ejabberd-2.1.11/0000775000000000000000000000000012240452476010230 5ustar ejabberd-2.1.11/debian/0000775000000000000000000000000012327447745011463 5ustar ejabberd-2.1.11/debian/dirs0000664000000000000000000000004212240230175012320 0ustar var/lib/ejabberd var/log/ejabberd ejabberd-2.1.11/debian/ejabberd.80000664000000000000000000001777612240230175013311 0ustar .TH ejabberd 8 "08 June 2008" "Version 2.0.1" "ejabberd manual page" .SH NAME ejabberd \(em a distributed fault-tolerant Jabber/XMPP server .SH SYNOPSIS .PP \fBejabberd\fR \fI[options] [\-\-] [erlang_options]\fP .SH DESCRIPTION .PP \fBejabberd\fR is a distributed fault-tolerant Jabber/XMPP server written in Erlang. Its main features are: .PD 0 .TP \(em XMPP-compliant .TP \(em Distributed: \fBejabberd\fR can run on a cluster of machines .TP \(em Fault-tolerant: All the information can be stored on more than one node, nodes can be added or replaced `on the fly' .TP \(em Built-in Multi-User Chat service .TP \(em Built-in IRC transport .TP \(em Built-in Publish-Subscribe service .TP \(em Built-in Jabber User Directory service based on users vCards .TP \(em SSL support .TP \(em Support for internationalized user messages .SH OPTIONS .TP .BI \-\-node " node" Specifies Erlang \fInode\fP at which ejabberd server will be run. Default node is \fBejabberd\fP. If the node name does not contain symbol \fI@\fR then actual node name becomes \fBnode@hostname\fP where hostname is short host name (usually it coincides with \fI\(gahostname \-s\(ga\fP). If the node name contain symbol \fI@\fR and its hostname part is a FQDN then \fBejabberd\fR will use so-called long names (see \fBerl\fR(1) manual page and look for options \fI\-name\fP and \fI\-sname\fP for details). Examples of \fI\-\-node\fP option: .BI ejabberd Locally run ejabberd server at node \fIejabberd@\(gahostname \-s\(ga\fP. .BI ejabberd@otherhost Pretend that ejabberd server runs at otherhost at node \fIejabberd@otherhost\fP. (Note that noone can remotely connect to this node if otherhost is resoved to other computer IP.) .BI ejabberd@localhost Locally run ejabberd server at node \fIejabberd@localhost\fP. Only nodes running at the same host can connect to this node. .BI ejabberd@hostname.domainname Using \fI\-name\fP Erlang option, run ejabberd server at long-name node \fIejabberd@hostname.domainname\fP. To be able to control this server instance \fIhostname.domainname\fP must resolve (either by DNS or via /etc/hosts) to the server's IP. .PP The default node can be overridden by defining ERLANG_NODE environment variable in /etc/default/ejabberd, see below. .TP .BI \-\-config " config\-file" Specifies an alternate \fIconfig\-file\fP to be parsed at startup, rather than the default (\fB/etc/ejabberd/ejabberd.cfg\fP). .TP .BI \-\-spool " spool\-dir" Specifies an alternate \fIspool\-dir\fP to store user database instead of the default (\fB/var/lib/ejabberd\fP). .TP .BI \-\-log " log\-file" Log Jabber events to specified \fIlog\-file\fP rather than to the default (\fB/var/log/ejabberd/ejabberd.log\fP). .TP .BI \-\-erlang\-log " sasl\-log\-file" Log SASL (System Application Support Libraries) events to specified \fIsasl\-log\-file\fP rather than to the default (\fB/var/log/ejabberd/erlang.log\fP). .TP .I erlang_options Other options (and all options following \fB\-\-\fR) are passed directly to \fBErlang\fR interpreter. See \fBErlang\fR documentation for more details on interpreter options. Some useful options are: .br .sp .BI \-detached Starts the Erlang system detached from the system console. .br .BI \-heart Starts heart beat monitoring of the Erlang system. .br .BI \-noinput Ensures that the Erlang system never tries to read any input. .SH CONFIGURATION FILE .PP The file \fB/etc/ejabberd/ejabberd.cfg\fR contains the main configuration. It is initially loaded the first time \fBejabberd\fR is executed, then it is parsed and stored in a database. Subsiquently the configuration is loaded from the database and any commands in the configuration file are appended to the entries in the database. The configuration file consists of a sequence of Erlang terms. Parts of lines after `%' sign are ignored. Each term is a tuple, where the first element is the name of an option, and the others are option values. E. g. if this file does not contain a "host" definition, then the value stored in the database will be used. To override old values stored in the database the following lines can be added in config: .br override_global. .br override_local. .br override_acls. A complete explanation of each configuration value can be found in the official \fBejabberd\fR documentation. See "\fBSEE ALSO\fR" part of this manual page for more information about the documentation. .SH OPTIONS FILE .PP The file \fB/etc/default/ejabberd\fR contains specific options. .PD 0 .TP .I POLL If set to true this variable enables kernel polling which can reduce CPU load on a system with a high number of users. This option requires support in the kernel and in Erlang emulator. .TP .I SMP Enables or disables SMP support in Erlang emulator. Valid values are disable (default), auto, and enable. .br .sp Explanation in Erlang/OTP documentation: .BI enable: Starts the Erlang runtime system with SMP support enabled. This may fail if no runtime system with SMP support is available. .br .BI auto: Starts the Erlang runtime system with SMP support enabled if it is available and more than one logical processor are detected. .br .BI disable: Starts a runtime system without SMP support. .TP .I ERL_MAX_PORTS To use more than 1024 connections (default value), \fIERL_MAX_PORTS\fP should be set to the number of connections needed. .TP .I PROCESSES Specifies the maximum number of Erlang processes to use. Default value is 250000. Maximum value is 268435456. Ejabberd uses up to three processes per user or server connection. .TP .I ERL_MAX_ETS_TABLES Sets the maximum number of ETS and Mnesia tables. Default value is 1400 which should be sufficient for a sever without many custom modules. If a message ** Too many db tables ** appears in ejabberd log files then increase this number. .TP .I ERL_OPTIONS With this option, parameters can be passed to \fBErlang\fR interpretor. See \fBErlang\fR documentation for more details on interpreter options. .TP .I ERL_FULLSWEEP_AFTER To reduce memory usage when allowing a large number of connections, \fIERL_FULLSWEEP_AFTER\fP may be set to 0 in the options file, but in this case \fBejabberd\fR may start to work slower. .TP .I ERLANG_NODE Use specified string as erlang node. It overrides default \fBejabberd\fP node name. The string may take one of the following forms: \fBnodename\fP, \fBnodename@hostname\fP or \fBnodename@hostname.domainname\fP .SH FILES .PD 0 .TP .I /etc/ejabberd/ejabberd.cfg default configuration file .TP .I /etc/default/ejabberd default variables .SH BUGS .PP Ejabberd uses distributed Erlang mode to work properly. This means that on start it connects to \fBepmd\fP (Erlang port mapping daemon) which is listening at port 4369 and tries to register ejabberd node name. If the connection fails (known failure reasons are unavailability of a loopback interface or firewall issues) Erlang emulator fails to start with not very clear error message. If there's already started Erlang node with the same name (\fIejabberd\fP by default) then ejabberd will also fail with a cryptic error message (in which one can find words \fI{error,duplicate_name}\fP). Another possible case when ejabberd cannot start is incorrect permissions of \fI/var/lib/ejabberd\fP directory (it must be writable by user ejabberd). .SH SEE ALSO .PP \fBerl\fR(1), \fBsasl\fR(6), \fBejabberdctl\fR(8), \fBepmd\fR. .PP The program documentation is available at \fIhttp://www.process\-one.net/en/projects/ejabberd/\fP. A copy of the documentation can be found at /usr/share/doc/ejabberd/guide.html. .SH AUTHORS .PP This manual page was adapted by Christophe Romain and Sergei Golovan for the \fBDebian\fP system (but may be used by others) from the \fBejabberd\fP documentation written by Alexey Shchepin . Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. .PP On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common\-licenses/GPL. ejabberd-2.1.11/debian/prerm0000664000000000000000000000256012240230175012513 0ustar #! /bin/sh # prerm script for ejabberd # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `remove' # * `upgrade' # * `failed-upgrade' # * `remove' `in-favour' # * `deconfigure' `in-favour' # `removing' # # for details, see /usr/doc/packaging-manual/ ctl() { local cmd='/usr/sbin/ejabberdctl' for arg in "$@"; do cmd="$cmd '$arg'" done su ejabberd -c "$cmd" } case "$1" in remove|upgrade) if ctl status >/dev/null ; then # Use timestamp to make database restoring easier TIME=$(date +%Y-%m-%dT%H:%M:%S) BACKUPDIR=$(mktemp -d -p /var/backups/ ejabberd-$TIME.XXXXXX) chown ejabberd:ejabberd $BACKUPDIR BACKUP=$BACKUPDIR/ejabberd-database ctl backup $BACKUP # Change ownership to root:root because ejabberd user might be # removed on package removal. chown -R root:root $BACKUPDIR chmod 700 $BACKUPDIR echo echo The ejabberd database has been backed up to $BACKUP. echo fi ;; deconfigure) ;; failed-upgrade) ;; *) echo "prerm called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 ejabberd-2.1.11/debian/control0000664000000000000000000000301612276225336013057 0ustar Source: ejabberd Section: net Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Konstantin Khomoutov Uploaders: Gerfried Fuchs Build-Depends: debhelper (>= 7.3~), quilt, erlang-base, erlang-asn1, erlang-parsetools, erlang-dev (>= 1:15.b), libexpat1-dev, libssl-dev, zlib1g-dev, libpam0g-dev, po-debconf, autotools-dev Standards-Version: 3.9.2 Homepage: http://www.process-one.net/en/projects/ejabberd/ Vcs-Git: git://git.deb.at/pkg/ejabberd.git Vcs-Browser: http://git.deb.at/w/pkg/ejabberd.git Package: ejabberd Architecture: any Depends: adduser, ${erlang:Depends}, ${erlang-abi:Depends}, openssl, ucf, ${misc:Depends}, ${shlibs:Depends} Suggests: libunix-syslog-perl, imagemagick | graphicsmagick-imagemagick-compat Conflicts: ejabberd-mod-shared-roster-ldap Description: distributed, fault-tolerant Jabber/XMPP server written in Erlang ejabberd is a distributed, fault-tolerant Jabber/XMPP server written in Erlang. Its features contain: - XMPP-compliant - Web based administration - Load balancing: can run in a cluster of machines - Fault-tolerance: database can be replicated and stored on multiple nodes (nodes can be added or replaced 'on the fly') - Virtual hosting: several virtual domains can be served using single ejabberd instance - SSL/TLS support - Multi-User Chat (MUC/conference) - IRC transport - Jabber Users Directory, based on users vCards - Service Discovery - Shared roster ejabberd-2.1.11/debian/NEWS0000664000000000000000000000731512240230175012145 0ustar ejabberd (2.1.11-1) unstable; urgency=low This release adds support for the SCRAM-SHA-1 authentication mecnahism. If the fully-qualified hostname of the server differs from the name of the XMPP domain it serves, in order for this mechanism to work with compliant clients, a modification should be made to the ejabberd's configuration file. Please consult the section "Using SCRAM-SHA-1 authentication mechanism" in the README.Debian file for detailed information. -- Konstantin Khomoutov Thu, 16 May 2013 13:27:56 +0000 ejabberd (2.1.8-1) unstable; urgency=low This release drops support for the @recent@ shared roster group (implemented as part of the OLPC project), and now only the @online@ shared roster group is supported. -- Konstantin Khomoutov Sun, 07 Aug 2011 20:40:02 +0400 ejabberd (2.1.4-1) unstable; urgency=low umask is now forcibly set to 027 before ejabberd's main process is started. This means all the files created by ejabberd now have permissions set to 0640 (0750 for directories). This does not have any impact on the routine operation of ejabberd but this affects all the commands which export data, such as `ejabberdctl export2odbc` -- the files they generate now cannot be read by users other than root, ejabberd and those included in the "ejabberd" group. The directory containing ejabberd logs (/var/log/ejabberd) is now owned by the "adm" group and have the group sticky bit set on it so that the log files are also owned by this group. In addition, due to the change described above they are now not world-readable. This is a change in behaviour; if you don't like it, use dpkg-statoverride on the /var/log/ejabberd directory to force other owner/permissions. -- Konstantin Khomoutov Mon, 12 Jul 2010 03:28:32 +0400 ejabberd (2.1.2-2) unstable; urgency=high This release fixes CVE-2010-0305 by allowing a server administrator to limit the lengths of "message queues" for outgoing connections. Roughly speaking, each message in such queues represents one XML stanza queued to be sent into its relevant outgoing stream. Note that the limiting is *NOT* enabled by default; if you want to enable it, use the {max_fsm_queue, Size} option which can either be specified globally (at the top level of the configuration file) and/or specifically for ejabberd_service and ejabberd_c2s_in listeners. Local options specified for the said listeners override the global one. The global option, if present, also affects outgoing server-to-server connections. The argument to this option can be either an atom 'undefined' -- the default value -- or an integer number, specifying the maximum number of queued messages. Refer to /usr/share/doc/ejabberd/guide.html for more details. -- Konstantin Khomoutov Tue, 09 Feb 2010 01:46:55 +0300 ejabberd (2.1.0-1) unstable; urgency=low Calling convention of the ejabberdctl program was changed. Also some of its commands were renamed or removed, or their calling convention was changed due to switching to another ejabberd module providing a set of additional commands. "sasl.log" was renamed to "erlang.log", and ejabberd command-line option to change its location was renamed accordingly as well. ejabberdctl no more generates unique node names for the erl process it spawns by default, it only does so if the "--concurrent" option is specified. The method used to generate unique node names was also changed. See the "Upgrading from 2.0.x series" section in README.Debian for details. -- Konstantin Khomoutov Tue, 17 Nov 2009 16:56:08 +0300 ejabberd-2.1.11/debian/bzr-builddeb.conf0000664000000000000000000000003112240230175014646 0ustar [BUILDDEB] native = True ejabberd-2.1.11/debian/README.source0000664000000000000000000000017012240230175013615 0ustar This package uses quilt for its patch management, see /usr/share/doc/quilt/README.source if you are unfamiliar with it. ejabberd-2.1.11/debian/copyright0000664000000000000000000000174212240230175013377 0ustar This package was first debianized by Sergei Golovan on Sun, 25 Apr 2004 16:39:22 +0400. It was maintained since then by Torsten Werner , Gerfried Fuchs and Konstantin Khomoutov . Original source has been downloaded from http://www.process-one.net/en/projects/ejabberd/download.html Upstream Author: Alexey Shchepin This software is Copyright (c) 2002-2005 Alexey Shchepin You are free to distribute this software under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. On Debian systems, the complete text of the GNU General Public License version 2 can be found in `/usr/share/common-licenses/GPL-2', later versions can be found in there too. As a special exception, the author gives permission to link this program with the OpenSSL library and distribute the resulting binary. ejabberd-2.1.11/debian/scripts/0000775000000000000000000000000012240452476013141 5ustar ejabberd-2.1.11/debian/scripts/ejabberdctl0000664000000000000000000000237112240230175015316 0ustar #!/bin/sh ERLANG_NODE=ejabberd if [ -f /etc/default/ejabberd ] ; then . /etc/default/ejabberd fi if [ "$FIREWALL_WINDOW" = "" ] ; then KERNEL_OPTS="" else KERNEL_OPTS="-kernel \ inet_dist_listen_min ${FIREWALL_WINDOW%-*} \ inet_dist_listen_max ${FIREWALL_WINDOW#*-}" fi if [ -r /var/lib/ejabberd/.erlang.cookie ] ; then HOME=/var/lib/ejabberd export HOME fi ERL_CRASH_DUMP=/var/log/ejabberd/erl_crash.dump export ERL_CRASH_DUMP ERL=/usr/bin/erl EBIN_DIR=/usr/lib/ejabberd/ebin SUFFIX='' if [ $# -ne 0 ] ; then case $1 in --) shift; break ;; --node) shift ; ERLANG_NODE=$1 ; shift ;; --concurrent) shift; SUFFIX=$$ ;; esac fi if [ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] ; then SNAME=-sname else SNAME=-name fi case $1 in debug) shift if [ "$ERLANG_NODE" = "${ERLANG_NODE%@*}" ] ; then ERLANG_NODE=$ERLANG_NODE@$(hostname -s) fi echo "Attaching Erlang shell to node $ERLANG_NODE." echo "To detach it, press: Ctrl+G, q, Return" echo "" exec $ERL $SNAME ejabberddebug$SUFFIX \ -remsh $ERLANG_NODE \ $KERNEL_OPTS \ "$@" ;; *) exec $ERL $SNAME ejabberdctl$SUFFIX \ -pa $EBIN_DIR \ -s ejabberd_ctl \ -noinput \ $KERNEL_OPTS \ -extra $ERLANG_NODE "$@" ;; esac ejabberd-2.1.11/debian/scripts/ejabberd0000664000000000000000000000343412240230175014614 0ustar #!/bin/sh # define default configuration POLL=false SMP=disable PROCESSES=250000 ERL_MAX_PORTS=32000 ERL_MAX_ETS_TABLES=1400 ERLANG_NODE=ejabberd # Location of the guide.html, for the web administration interface: EJABBERD_DOC_PATH=/usr/share/doc/ejabberd export EJABBERD_DOC_PATH if [ -f /etc/default/ejabberd ] ; then . /etc/default/ejabberd fi if [ "$FIREWALL_WINDOW" = "" ] ; then KERNEL_OPTS="" else KERNEL_OPTS="-kernel \ inet_dist_listen_min ${FIREWALL_WINDOW%-*} \ inet_dist_listen_max ${FIREWALL_WINDOW#*-}" fi ERLANG_OPTS="+K $POLL -smp $SMP +P $PROCESSES $KERNEL_OPTS" if [ -r /var/lib/ejabberd/.erlang.cookie ] ; then HOME=/var/lib/ejabberd export HOME fi ERL=/usr/bin/erl EBIN_DIR=/usr/lib/ejabberd/ebin CONFIG=/etc/ejabberd/ejabberd.cfg INETRC=/etc/ejabberd/inetrc LOG=/var/log/ejabberd/ejabberd.log ERLANG_LOG=/var/log/ejabberd/erlang.log SPOOL=/var/lib/ejabberd ERL_CRASH_DUMP=/var/log/ejabberd/erl_crash.dump EJABBERD_PID_PATH=/var/run/ejabberd/ejabberd.pid export ERL_CRASH_DUMP export ERL_MAX_PORTS export ERL_MAX_ETS_TABLES export ERL_FULLSWEEP_AFTER export EJABBERD_PID_PATH ARGS= while [ $# -ne 0 ] ; do PARAM=$1 shift case $PARAM in --) break ;; --node) ERLANG_NODE=$1; shift ;; --config) CONFIG=$1 ; shift ;; --log) LOG=$1 ; shift ;; --erlang-log) ERLANG_LOG=$1 ; shift ;; --spool) SPOOL=$1 ; shift ;; *) ARGS="$ARGS $PARAM" ;; esac done if [ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] ; then SNAME=-sname else SNAME=-name fi umask 027 exec $ERL $SNAME $ERLANG_NODE \ -pa $EBIN_DIR \ -s ejabberd \ -kernel inetrc \"$INETRC\" \ -ejabberd config \"$CONFIG\" log_path \"$LOG\" \ erlang_log_path \"$ERLANG_LOG\" \ -sasl sasl_error_logger false \ -mnesia dir \"$SPOOL\" \ $ERLANG_OPTS $ERL_OPTIONS $ARGS "$@" ejabberd-2.1.11/debian/ejabberd.cfg0000664000000000000000000004113712240230175013665 0ustar %%% %%% Debian ejabberd configuration file %%% This config must be in UTF-8 encoding %%% %%% The parameters used in this configuration file are explained in more detail %%% in the ejabberd Installation and Operation Guide. %%% Please consult the Guide in case of doubts, it is available at %%% /usr/share/doc/ejabberd/guide.html %%% This configuration file contains Erlang terms. %%% In case you want to understand the syntax, here are the concepts: %%% %%% - The character to comment a line is % %%% %%% - Each term ends in a dot, for example: %%% override_global. %%% %%% - A tuple has a fixed definition, its elements are %%% enclosed in {}, and separated with commas: %%% {loglevel, 4}. %%% %%% - A list can have as many elements as you want, %%% and is enclosed in [], for example: %%% [http_poll, web_admin, tls] %%% %%% - A keyword of ejabberd is a word in lowercase. %%% The strings are enclosed in "" and can have spaces, dots... %%% {language, "en"}. %%% {ldap_rootdn, "dc=example,dc=com"}. %%% %%% - This term includes a tuple, a keyword, a list and two strings: %%% {hosts, ["jabber.example.net", "im.example.com"]}. %%% %%% =================================== %%% OVERRIDE OPTIONS STORED IN DATABASE %% %% Override global options (shared by all ejabberd nodes in a cluster). %% %%override_global. %% %% Override local options (specific for this particular ejabberd node). %% %%override_local. %% %% Remove the Access Control Lists before new ones are added. %% %%override_acls. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Options which are set by Debconf and managed by ucf %% Admin user {acl, admin, {user, "__USER__", "__HOSTNAME__"}}. %% Hostname {hosts, ["__HOSTNAME__"]}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% ========= %%% DEBUGGING %% %% loglevel: Verbosity of log files generated by ejabberd. %% 0: No ejabberd log at all (not recommended) %% 1: Critical %% 2: Error %% 3: Warning %% 4: Info %% 5: Debug %% {loglevel, 4}. %% %% watchdog_admins: If an ejabberd process consumes too much memory, %% send live notifications to those Jabber accounts. %% %%{watchdog_admins, ["bob@example.com"]}. %%% ================ %%% SERVED HOSTNAMES %% %% hosts: Domains served by ejabberd. %% You can define one or several, for example: %% {hosts, ["example.net", "example.com", "example.org"]}. %% %% (This option is defined by debconf earlier) %% {hosts, ["localhost"]}. %% %% route_subdomains: Delegate subdomains to other Jabber server. %% For example, if this ejabberd serves example.org and you want %% to allow communication with a Jabber server called im.example.org. %% %%{route_subdomains, s2s}. %%% =============== %%% LISTENING PORTS %% %% listen: Which ports will ejabberd listen, which service handles it %% and what options to start it with. %% {listen, [ {5222, ejabberd_c2s, [ {access, c2s}, {shaper, c2s_shaper}, {max_stanza_size, 65536}, %%zlib, starttls, {certfile, "/etc/ejabberd/ejabberd.pem"} ]}, %% %% To enable the old SSL connection method (deprecated) in port 5223: %% %%{5223, ejabberd_c2s, [ %% {access, c2s}, %% {shaper, c2s_shaper}, %% {max_stanza_size, 65536}, %% zlib, %% tls, {certfile, "/etc/ejabberd/ejabberd.pem"} %% ]}, {5269, ejabberd_s2s_in, [ {shaper, s2s_shaper}, {max_stanza_size, 131072} ]}, %% External MUC jabber-muc %%{5554, ejabberd_service, [ %% {ip, {127, 0, 0, 1}}, %% {access, all}, %% {shaper_rule, fast}, %% {host, "muc.localhost", [{password, "secret"}]} %% ]}, %% Jabber ICQ Transport %%{5555, ejabberd_service, [ %% {ip, {127, 0, 0, 1}}, %% {access, all}, %% {shaper_rule, fast}, %% {hosts, ["icq.localhost", "sms.localhost"], %% [{password, "secret"}]} %% ]}, %% AIM Transport %%{5556, ejabberd_service, [ %% {ip, {127, 0, 0, 1}}, %% {access, all}, %% {shaper_rule, fast}, %% {host, "aim.localhost", [{password, "secret"}]} %% ]}, %% MSN Transport %%{5557, ejabberd_service, [ %% {ip, {127, 0, 0, 1}}, %% {access, all}, %% {shaper_rule, fast}, %% {host, "msn.localhost", [{password, "secret"}]} %% ]}, %% Yahoo! Transport %%{5558, ejabberd_service, [ %% {ip, {127, 0, 0, 1}}, %% {access, all}, %% {shaper_rule, fast}, %% {host, "yahoo.localhost", [{password, "secret"}]} %% ]}, %% External JUD (internal is more powerful, %% but doesn't allow to register users from other servers) %%{5559, ejabberd_service, [ %% {ip, {127, 0, 0, 1}}, %% {access, all}, %% {shaper_rule, fast}, %% {host, "jud.localhost", [{password, "secret"}]} %% ]}, {5280, ejabberd_http, [ %%{request_handlers, %% [ %% {["pub", "archive"], mod_http_fileserver} %% ]}, %%captcha, http_bind, http_poll, web_admin ]} ]}. %% %% max_fsm_queue: Enable limiting of lengths of "message queues" %% for outgoing connections. Roughly speaking, each message in such %% queues represents one XML stanza queued to be sent into %% an output stream it is serving. %% The default value is an atom 'undefined' which specifies no limiting. %% %% When specified globally, this option limits the message queue lengths %% for all ejabberd_c2s_in and ejabberd_service listeners, %% as well as for outgoing s2s connections. %% %% This option can also be specified as an option for ejabberd_c2s_in %% and ejabberd_service listeners, in wich case it will override %% the value of the global option. %% {max_fsm_queue, 1000}. %% %% s2s_use_starttls: Enable STARTTLS + Dialback for S2S connections. %% Allowed values are: true or false. %% You must specify a certificate file. %% {s2s_use_starttls, true}. %% %% s2s_certfile: Specify a certificate file. %% {s2s_certfile, "/etc/ejabberd/ejabberd.pem"}. %% %% domain_certfile: Specify a different certificate for each served hostname. %% %%{domain_certfile, "example.org", "/path/to/example_org.pem"}. %%{domain_certfile, "example.com", "/path/to/example_com.pem"}. %% %% S2S whitelist or blacklist %% %% Default s2s policy for undefined hosts. %% %%{s2s_default_policy, allow}. %% %% Allow or deny communication with specific servers. %% %%{{s2s_host, "goodhost.org"}, allow}. %%{{s2s_host, "badhost.org"}, deny}. %% %% The maximum allowed delay for retry to connect %% after a failed connection attempt to a remote server, in seconds. %% The default value is 300 seconds (5 minutes). %% %% The reconnection algorythm works like this: if connection fails, %% ejabberd makes an initial random delay between 1 and 15 seconds, %% then retries, and if this attempt fails, makes another delay, %% twice as long as previous. These attempts are performed either %% until a successful connection is made or until the next calculated %% delay is greated or equal than the value of s2s_max_retry_delay. %% %%{s2s_max_retry_delay, 300}. %% %% Outgoing S2S options %% %% Preferred address families (which to try first) and connect timeout %% in milliseconds. %% %%{outgoing_s2s_options, [ipv4, ipv6], 10000}. %%% ============== %%% AUTHENTICATION %% %% auth_method: Method used to authenticate the users. %% The default method is the internal. %% If you want to use a different method, %% comment this line and enable the correct ones. %% {auth_method, internal}. %% %% Authentication using external script %% Make sure the script is executable by ejabberd. %% %%{auth_method, external}. %%{extauth_program, "/path/to/authentication/script"}. %% %% Authentication using ODBC %% Remember to setup a database in the next section. %% %%{auth_method, odbc}. %% %% Authentication using PAM %% %%{auth_method, pam}. %%{pam_service, "pamservicename"}. %% %% Authentication using LDAP %% %%{auth_method, ldap}. %% %% List of LDAP servers: %%{ldap_servers, ["localhost"]}. %% %% Encryption of connection to LDAP servers (LDAPS): %%{ldap_encrypt, none}. %%{ldap_encrypt, tls}. %% %% Port connect to LDAP server: %%{ldap_port, 389}. %%{ldap_port, 636}. %% %% LDAP manager: %%{ldap_rootdn, "dc=example,dc=com"}. %% %% Password to LDAP manager: %%{ldap_password, "******"}. %% %% Search base of LDAP directory: %%{ldap_base, "dc=example,dc=com"}. %% %% LDAP attribute that holds user ID: %%{ldap_uids, [{"mail", "%u@mail.example.org"}]}. %% %% LDAP filter: %%{ldap_filter, "(objectClass=shadowAccount)"}. %% %% Anonymous login support: %% auth_method: anonymous %% anonymous_protocol: sasl_anon | login_anon | both %% allow_multiple_connections: true | false %% %%{host_config, "public.example.org", [{auth_method, anonymous}, %% {allow_multiple_connections, false}, %% {anonymous_protocol, sasl_anon}]}. %% %% To use both anonymous and internal authentication: %% %%{host_config, "public.example.org", [{auth_method, [internal, anonymous]}]}. %%% ============== %%% DATABASE SETUP %% ejabberd uses by default the internal Mnesia database, %% so you can avoid this section. %% This section provides configuration examples in case %% you want to use other database backends. %% Please consult the ejabberd Guide for details about database creation. %% NOTE that ejabberd in Debian supports "out of the box" %% only mnesia (default) and ODBC storage backends. %% Working with MySQL and PostgreSQL DB backends requires %% building and installation of the corresponding Erlang modules, %% not distributed as a part of ejabberd. %% Refer to /usr/share/doc/ejabberd/README.Debian for details. %% %% MySQL server: %% %%{odbc_server, {mysql, "server", "database", "username", "password"}}. %% %% If you want to specify the port: %%{odbc_server, {mysql, "server", 1234, "database", "username", "password"}}. %% %% PostgreSQL server: %% %%{odbc_server, {pgsql, "server", "database", "username", "password"}}. %% %% If you want to specify the port: %%{odbc_server, {pgsql, "server", 1234, "database", "username", "password"}}. %% %% If you use PostgreSQL, have a large database, and need a %% faster but inexact replacement for "select count(*) from users" %% %%{pgsql_users_number_estimate, true}. %% %% ODBC compatible or MSSQL server: %% %%{odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}. %% %% Number of connections to open to the database for each virtual host %% %%{odbc_pool_size, 10}. %% %% Interval to make a dummy SQL request to keep alive the connections %% to the database. Specify in seconds: for example 28800 means 8 hours %% %%{odbc_keepalive_interval, undefined}. %%% =============== %%% TRAFFIC SHAPERS %% %% The "normal" shaper limits traffic speed to 1.000 B/s %% {shaper, normal, {maxrate, 1000}}. %% %% The "fast" shaper limits traffic speed to 50.000 B/s %% {shaper, fast, {maxrate, 50000}}. %%% ==================== %%% ACCESS CONTROL LISTS %% %% The 'admin' ACL grants administrative privileges to Jabber accounts. %% You can put as many accounts as you want. %% %%{acl, admin, {user, "aleksey", "localhost"}}. %%{acl, admin, {user, "ermine", "example.org"}}. %% %% Blocked users %% %%{acl, blocked, {user, "baduser", "example.org"}}. %%{acl, blocked, {user, "test"}}. %% %% Local users: don't modify this line. %% {acl, local, {user_regexp, ""}}. %% %% More examples of ACLs %% %%{acl, jabberorg, {server, "jabber.org"}}. %%{acl, aleksey, {user, "aleksey", "jabber.ru"}}. %%{acl, test, {user_regexp, "^test"}}. %%{acl, test, {user_glob, "test*"}}. %% %% Define specific ACLs in a virtual host. %% %%{host_config, "localhost", %% [ %% {acl, admin, {user, "bob-local", "localhost"}} %% ] %%}. %%% ============ %%% ACCESS RULES %% Define the maximum number of time a single user is allowed to connect: {access, max_user_sessions, [{10, all}]}. %% Maximum number of offline messages that users can have: {access, max_user_offline_messages, [{5000, admin}, {100, all}]}. %% This rule allows access only for local users: {access, local, [{allow, local}]}. %% Only non-blocked users can use c2s connections: {access, c2s, [{deny, blocked}, {allow, all}]}. %% For all users except admins used "normal" shaper {access, c2s_shaper, [{none, admin}, {normal, all}]}. %% For all S2S connections used "fast" shaper {access, s2s_shaper, [{fast, all}]}. %% Only admins can send announcement messages: {access, announce, [{allow, admin}]}. %% Only admins can use configuration interface: {access, configure, [{allow, admin}]}. %% Admins of this server are also admins of MUC service: {access, muc_admin, [{allow, admin}]}. %% All users are allowed to use MUC service: {access, muc, [{allow, all}]}. %% No username can be registered via in-band registration: %% To enable in-band registration, replace 'deny' with 'allow' % (note that if you remove mod_register from modules list then users will not % be able to change their password as well as register). % This setting is default because it's more safe. {access, register, [{deny, all}]}. %% By default frequency of account registrations from the same IP %% is limited to 1 account every 10 minutes. To disable put: infinity %%{registration_timeout, 600}. %% Everybody can create pubsub nodes {access, pubsub_createnode, [{allow, all}]}. %% %% Define specific Access rules in a virtual host. %% %%{host_config, "localhost", %% [ %% {access, c2s, [{allow, admin}, {deny, all}]}, %% {access, register, [{deny, all}]} %% ] %%}. %%% ================ %%% DEFAULT LANGUAGE %% %% language: Default language used for server messages. %% {language, "en"}. %% %% Set a different default language in a virtual host. %% %%{host_config, "localhost", %% [{language, "ru"}] %%}. %%% ======= %%% CAPTCHA %% %% Full path to a script that generates the image. %% Note that this script must be made executable %% for the user ejabberd:ejabberd. %% %%{captcha_cmd, "/usr/lib/ejabberd/priv/bin/captcha.sh"}. %% %% Host part of the URL sent to the user. %% The port specified must be configured as the "ejabberd_http" %% listener which must have the "captcha" directive included %% in its configuration (see the "LISTENING PORTS" section above). %% %%{captcha_host, "localhost:5280"}. %%% ======= %%% MODULES %% %% Modules enabled in all ejabberd virtual hosts. %% {modules, [ {mod_adhoc, []}, {mod_announce, [{access, announce}]}, % requires mod_adhoc {mod_caps, []}, {mod_configure,[]}, % requires mod_adhoc {mod_admin_extra, []}, {mod_disco, []}, %%{mod_echo, [{host, "echo.localhost"}]}, {mod_irc, []}, %% NOTE that mod_http_fileserver must also be enabled in the %% "request_handlers" clause of the "ejabberd_http" listener %% configuration (see the "LISTENING PORTS" section above). %%{mod_http_fileserver, [ %% {docroot, "/var/www"}, %% {accesslog, "/var/log/ejabberd/access.log"} %% ]}, {mod_last, []}, {mod_muc, [ %%{host, "conference.@HOST@"}, {access, muc}, {access_create, muc}, {access_persistent, muc}, {access_admin, muc_admin}, {max_users, 500} ]}, %%{mod_muc_log,[]}, {mod_offline, [{access_max_user_messages, max_user_offline_messages}]}, {mod_privacy, []}, {mod_private, []}, {mod_proxy65, [ {access, local}, {shaper, c2s_shaper} ]}, {mod_pubsub, [ % requires mod_caps {access_createnode, pubsub_createnode}, {pep_sendlast_offline, false}, {last_item_cache, false}, %%{plugins, ["default", "pep"]} {plugins, ["flat", "hometree", "pep"]} % pep requires mod_caps ]}, {mod_register, [ %% %% After successful registration, the user receives %% a message with this subject and body. %% {welcome_message, {"Welcome!", "Welcome to a Jabber service powered by Debian. " "For information about Jabber visit " "http://www.jabber.org"}}, %% Replace it with 'none' if you don't want to send such message: %%{welcome_message, none}, %% %% When a user registers, send a notification to %% these Jabber accounts. %% %%{registration_watchers, ["admin1@example.org"]}, {access, register} ]}, {mod_roster, []}, %%{mod_service_log,[]}, %%{mod_shared_roster,[]}, {mod_stats, []}, {mod_time, []}, {mod_vcard, []}, {mod_version, []} ]}. %% %% Enable modules with custom options in a specific virtual host %% %%{host_config, "localhost", %% [{{add, modules}, %% [ %% {mod_echo, [{host, "mirror.localhost"}]} %% ] %% } %% ]}. %%% $Id: ejabberd.cfg.example 2497 2009-08-17 20:27:28Z cromain $ %%% Local Variables: %%% mode: erlang %%% End: %%% vim: set filetype=erlang tabstop=8: ejabberd-2.1.11/debian/postrm0000664000000000000000000000156612240230175012717 0ustar #! /bin/sh # postrm script for ejabberd # # see: dh_installdeb(1) set -e CONFIG_TARGET=/etc/ejabberd/ejabberd.cfg if [ -f /usr/share/debconf/confmodule ]; then . /usr/share/debconf/confmodule fi case "$1" in remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) ;; purge) if which ucf >/dev/null ; then ucf --purge $CONFIG_TARGET fi rm -f $CONFIG_TARGET rm -f /etc/ejabberd/ejabberd.pem rm -Rf /var/log/ejabberd /var/lib/ejabberd rm -Rf /var/run/ejabberd || true rm -f /etc/default/ejabberd if which deluser >/dev/null ; then deluser ejabberd 2>/dev/null || true delgroup ejabberd 2>/dev/null || true fi ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# ejabberd-2.1.11/debian/po/0000775000000000000000000000000012240452476012070 5ustar ejabberd-2.1.11/debian/po/es.po0000664000000000000000000000744412240230175013036 0ustar # translation of ejabberd-debian-es.po to Spanish # # Translators, if you are not familiar with the PO format, gettext # documentation is worth reading, especially sections dedicated to # this format, e.g. by running: # info -n '(gettext)PO Files' # info -n '(gettext)Header Entry' # Some information specific to po-debconf are available at # /usr/share/doc/po-debconf/README-trans # or http://www.debian.org/intl/l10n/po-debconf/README-trans# # Developers do not need to manually edit POT or PO files. # # Badlop , 2006. # msgid "" msgstr "" "Project-Id-Version: 2.0.1-2\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2008-07-14 13:57+0200\n" "Last-Translator: Badlop \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Nombre del servidor Jabber que ejabberd servirá:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Por favor indica el nombre de tu servidor Jabber." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "Cuenta de administrador en ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Por favor indica el nombre deseado para una cuenta de administrador en el " "servidor ejabberd. Después de la instalación de ejabberd podrás usar esta " "cuenta con un cliente Jabber y hacer tareas de administración, o entrar en " "la web de administración http://${hostname}:5280/admin/ Al poner los datos " "de administrador en esa web, recuerda introducir tu Jabber ID completo, por " "ejemplo '${user}@${hostname}'" #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Dejar vacío si no deseas que se cree automáticamente una cuenta de " "administrador." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "La contraseña de la cuenta del administrador:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Por favor introduce la contraseña para la cuenta de administrador." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "" "Introduce de nuevo la contraseña para la cuenta de administrador para " "verificación:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "" "Por favor introduce de nuevo la contraseña de la cuenta de administrador " "para verificación." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "¡Las contraseñas no coinciden!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "" "Las contraseñas que has tecleado no coinciden. Por favor inténtalo de nuevo." ejabberd-2.1.11/debian/po/templates.pot0000664000000000000000000000452312240230175014604 0ustar # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "" #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "" #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "" #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "" ejabberd-2.1.11/debian/po/eu.po0000664000000000000000000000662612240230175013041 0ustar # translation of eu.po to Euskara # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Aitor Ibañez , 2008. msgid "" msgstr "" "Project-Id-Version: ejabberd\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2008-07-22 01:19+0200\n" "Last-Translator: Aitor Ibañez \n" "Language-Team: Euskara \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Ejabberd-ek zerbitzatuko duen ostalariaren izena:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Jabber zerbitzariaren ostalari izena sartu (letra xehez)." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "Ejabberd-en administrazio konturako erabiltzaile-izena:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Kontu-izen bat eman, haren bidez ejabberd zerbitzaria administratzeko. " "Ejabberd instalatu ostean, kontu hau erabil dezakezu edozein Jabber " "bezerotan edo http://${ostalari-izena}:5280/admin/ helbideko administrazio-" "interfazean saioa hasi eta administrazio lanak egiteko. Hemen erabiltzaile-" "izena soilik sartu (adib. ${erabiltzailea}), baina Jabber ID osoa erabili (e." "g. ${erabiltzailea}@${ostalari-izena}) ejabberd-en web interfazean sartzeko, " "bestela huts egingo du." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Bete gabe utzi administrazio kontua automatikoki sortzea nahi ez baduzu." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "Pasahitza administrazio konturako:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Administratzaile erabiltzailearen pasahitza sartu." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "Berriz sartu administrazio kontuko pasahitza, egiaztatzeko:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "" "Berriz sartu administratzaile erabiltzailearen pasahitza, egiaztatzeko." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Pasahitzak ez datoz bat!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "Sartutako pasahitzak ez datoz bat. Mesedez, berriro saiatu." ejabberd-2.1.11/debian/po/gl.po0000664000000000000000000000670412240230175013027 0ustar # Galician translation of ejabberd's debconf templates # This file is distributed under the same license as the ejabberd package. # Jacobo Tarrio , 2008. # msgid "" msgstr "" "Project-Id-Version: ejabberd\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2008-07-14 20:27+0100\n" "Last-Translator: Jacobo Tarrio \n" "Language-Team: Galician \n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "O nome do servidor de ejabberd:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Introduza o nome do servidor Jabber (en minúsculas)." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "O usuario dunha conta administrativa para ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Introduza o nome dunha conta para administrar o servidor ejabberd. Trala " "instalación de ejabberd pode empregar esta conta para se conectar con " "calquera cliente Jabber para realizar tarefas administrativas ou pode " "conectarse a http://${hostname}:5280/admin/ e identifíquese con esta conta " "para entrar na interface de administración. Introduza aquí a parte do nome " "de usuario (por exemplo, ${user}), pero empregue o ID de Jabber completo " "(por exemplo, ${user}@${hostname}) para se identificar na interface web de " "ejabberd; se non o fai así, a identificación ha fallar." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Déixeo en branco se non quere crear unha conta de administrador " "automaticamente." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "O contrasinal para a conta do administrador:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Introduza o contrasinal do usuario administrativo." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "O contrasinal do administrador outra vez para verificalo:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "" "Volva introducir o contrasinal do usuario administrativo para verificalo." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Os contrasinais non coinciden" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "Os contrasinais que introduciu non son iguais. Volva tentalo." ejabberd-2.1.11/debian/po/da.po0000664000000000000000000000675212240230175013014 0ustar # Danish translation ejabberd. # Copyright (C) 2010 ejabberd & nedenstående oversættere. # This file is distributed under the same license as the ejabberd package. # Joe Hansen (joedalton2@yahoo.dk), 2010. # msgid "" msgstr "" "Project-Id-Version: ejabberd\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2010-08-08 17:30+01:00\n" "Last-Translator: Joe Hansen \n" "Language-Team: Danish \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Navnet på værten som ejabberd vil betjene:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Indtast venligst værtsnavnet på din Jabberserver (med små bogstaver)." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "Brugernavnet på en adminkonto for ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Angiv venligst navnet på en konto til administration af ejabberdserveren. " "Efter installationen af ejabberd kan du bruge denne konto til at logge ind " "med enhver Jabberklient og udføre administrative opgaver eller gå til http://" "${hostname}:5280/admin/ og logge ind med denne konto for at tilgå " "administrationsgrænsefladen. Indtast brugernavnsdelen her (f.eks. ${user}), " "men brug den fulde Jabber-id (f.eks. ${user}@${hostname}) for at logge ind " "på ejabberds internetgrænseflade; ellers vil den fejle." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Efterlad blank hvis du ikke automatisk ønsker at oprette en " "administrationskonto." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "Adgangskoden for administrationskontoen:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Indtast venligst adgangskoden for den administrative bruger." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "Adgangskoden for administrationskontoen endnu en gang for bekræftelse:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "" "Genindtast venligst adgangskoden for den administrative bruger for " "bekræftelse." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Adgangskoderne er ikke ens!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "Adgangskoderne, du har indtastet, er ikke ens. Forsøg venligst igen." ejabberd-2.1.11/debian/po/sv.po0000664000000000000000000000664612240230175013062 0ustar # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2008-07-13 18:03+0100\n" "Last-Translator: Martin Bagge \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Värdnamnet som ejabberd ska arbeta för:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Ange värdnamnet på din jabber-server (endast gemener)." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "Användarnamnet för administratörskontot för ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Ange användarnamnet för ett administratörskonto för ejabberd-servern. Efter " "att installationen är klar kan du använda detta kontot för att logga in med " "en Jabber-klient för att utföra administrativa uppgifter, alternativt så kan " "du besöka http://${hostname}:5280/admin/ och logga in med kontot där för att " "komma åt administrationsgränssnittet. Ange användanamnet här (t.ex. " "${user}), men kom ihåg att använda det fullständiga Jabber ID:t (t.ex. " "${user}@${hostname}) för att logga in i ejabberd:s webbgränssnitt." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Lämna fältet tomt om du inte vill skapa ett administrationskonto automatiskt." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "Lösenord för administrationskontot:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Ange lösenordet för administratörskontot." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "Upprepa lösenordet för administratörskontot:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "" "För att kontrollera att du angivit rätt lösenord ska du upprepa det här." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Lösenorden var inte likadana!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "Lösenorden du angav är inte likadana. Vänligen försök igen." ejabberd-2.1.11/debian/po/vi.po0000664000000000000000000000740412240230175013041 0ustar # Vietnamese translation for eJabberD. # Copyright © 2008 Free Software Foundation, Inc. # Clytie Siddall , 2008. # msgid "" msgstr "" "Project-Id-Version: ejabberd\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2008-07-16 17:20+0930\n" "Last-Translator: Clytie Siddall \n" "Language-Team: Vietnamese \n" "Language: vi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: LocFactoryEditor 1.7b3\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Tên máy của máy phục vụ Jabber:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Hãy nhập (bằng chữ thường) tên của máy sẽ được ejabberd phục vụ. " #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "Tên đăng nhập của tài khoản quản trị cho ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Hãy cung cấp tên của một tài khoản sẽ quản trị máy phục vụ ejabberd. Sau khi " "cài đặt trình nền ejabberd, bạn có thể sử dụng tài khoản này để đăng nhập " "với bất cứ ứng dụng khách Jabber nào, để làm các công việc quản trị, hoặc " "thăm địa chỉ « http://${hostname}:5280/admin/ » và đăng nhập với tài khoản " "này để vào giao diện quản trị. Ở đây thì nhập chỉ phần tên người dùng (v.d. " "« ${user} »), nhưng hãy sử dụng Jabber ID hoàn toàn (v.d. « ${user}@" "${hostname} ») để đăng nhập vào giao diện Web của ejabberd; không thì không " "đăng nhập được." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Bỏ trống trường này nếu bạn không muốn tự động tạo một tài khoản quản trị." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "Mật khẩu cho tài khoản quản trị:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Hãy nhập mật khẩu của người dùng quản trị." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "Nhập lại mật khẩu quản trị, để xác nhận:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "" "Hãy nhập lần nữa mật khẩu của người dùng quản trị, để xác nhận đây là mật " "khẩu đúng." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Hai mật khẩu không trùng nhau." #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "Bạn đã gõ hai mật khẩu khác nhau. Hãy thử lại." ejabberd-2.1.11/debian/po/fr.po0000664000000000000000000000714712240230175013036 0ustar # Translation of ejabberd debconf templates to French # Copyright (C) 2008 Florentin Duneau # This file is distributed under the same license as the ejabberd package. # # # Florentin Duneau , 2006. # Florentin Duneau , 2008. msgid "" msgstr "" "Project-Id-Version: ejabberd\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2008-03-01 13:47+0100\n" "Last-Translator: Florentin Duneau \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Nom d'hôte du serveur ejabberd :" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Veuillez indiquer le nom d'hôte (en minuscule) du serveur Jabber." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "Identifiant du compte administrateur d'ejabberd :" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Veuillez indiquer un identifiant afin d'administrer le serveur ejabberd. " "Après l'installation, vous pourrez utilisez cette identité pour vous " "connecter avec tout client Jabber ou l'interface d'administration sur http://" "${hostname}:5280/admin/ pour réaliser des tâches administratives. Veuillez " "seulement entrer ici l'identifiant (par exemple, « ${user} »), cependant " "vous devrez utiliser une identité Jabber complète (par exemple, « ${user}@" "${hostname} ») pour vous connecter à l'interface web." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Veuillez laisser cette entrée vide si vous ne souhaitez pas créer de compte " "administrateur automatiquement." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "Mot de passe du compte administrateur :" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Veuillez entrer le mot de passe de l'utilisateur administrateur." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "Mot de passe du compte administrateur :" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "" "Veuillez indiquer de nouveau le mot de passe de l'utilisateur administrateur " "pour vérification." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Mots de passe différents" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "Les mots de passe saisis ne correspondent pas. Veuillez recommencer." ejabberd-2.1.11/debian/po/sk.po0000664000000000000000000000727312240230175013044 0ustar # Slovak translations for ejabberd package # Slovenské preklady pre balík ejabberd. # Copyright (C) 2011 THE ejabberd'S COPYRIGHT HOLDER # This file is distributed under the same license as the ejabberd package. # Automatically generated, 2011. # Slavko , 2011. # msgid "" msgstr "" "Project-Id-Version: ejabberd 2.1.9-1\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2011-10-30 15:15+0100\n" "Last-Translator: Slavko \n" "Language-Team: slovenčina \n" "Language: sk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" "X-POFile-SpellExtra: admin hostname Jabber ejabberd administračného\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Meno hostiteľa, ktoré bude ejabberd poskytovať:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Prosím, zadajte meno hostiteľa servera Jabber (malými písmenami)." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "Meno používateľa účtu administrátora pre ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Prosím, zadajte meno účtu administrátora servera ejabberd. Po inštalácii " "ejabberd môžete tento účet použiť na prihlásenie sa pomocou ktoréhokoľvek " "klienta Jabber a vykonávanie administratívnych úloh alebo použiť http://" "${hostname}:5280/admin/ a prihlásiť sa pomocou tohoto účtu do " "administračného rozhrania. Tu zadajte len časť s používateľským menom (napr. " "${user}), ale na prihlásenie do webového rozhrania ejabberd použite úplný " "identifikátor Jabber (napr. ${user}@${hostname}); inak prihlásenie zlyhá." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Nechajte prázdne, ak nechcete aby bol účet administrátora vytvorený " "automaticky." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "Heslo účtu administrátora:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Prosím, zadajte heslo administračného používateľa." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "Heslo administrátora znova, kvôli overeniu:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "Prosím, zdajte znova heslo administrátora, kvôli overeniu." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Heslá sa nezhodujú!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "Heslá, ktoré ste zadali sa nezhodujú. Prosím, skúste znova." ejabberd-2.1.11/debian/po/de.po0000664000000000000000000000676612240230175013025 0ustar # translation of po-debconf template to German # Copyright (C) 2006, Matthias Julius # Copyright (C) 2008 Helge Kreutzmann # This file is distributed under the same license as the ejabberd package. # msgid "" msgstr "" "Project-Id-Version: ejabberd 2.0.0-6\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2008-04-28 21:21+0200\n" "Last-Translator: Torsten Werner \n" "Language-Team: de \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Der Name Ihres Ejabberd-Servers:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Geben Sie bitte (in Kleinbuchstaben) den Namen Ihres Jabberservers an." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "Der Benutzername eines administrativen Kontos für Ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Geben Sie bitte den Namen für ein Konto an, dass den Ejabberd-Server " "verwalten kann. Nach der Installation können Sie mit Hilfe dieses Kontos und " "eines beliebigen Jabber-Clients Verwaltungsaufgaben durchführen oder sich " "unter http://{hostname}:5280/admin/ an der Administratorschnittstelle " "anmelden. Geben Sie hier den Benutzernamen-Anteil ein (z.B. ${user}), " "verwenden Sie aber die komplette Jabber-ID (z.B. ${user}@${hostname}) um " "sich an der Ejabberd-Webschnittstelle anzumelden, da ansonsten die Anmeldung " "nicht funktionieren wird." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "Lassen Sie das Feld leer, um kein privilegiertes Konto anzulegen." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "Das Kennwort für das Administratorkonto:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Geben Sie das Kennwort für den Administrator an." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "Wiederholen Sie das Passwort zur Vermeidung von Fehleingaben:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "Bitte geben Sie noch einmal das Passwort ein." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Die Kennwörter waren nicht identisch!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "" "Die Kennwörter waren nicht identisch, bitte versuchen Sie es noch einmal." ejabberd-2.1.11/debian/po/it.po0000664000000000000000000000721312240230175013035 0ustar # Italian translation of ejabberd debconf messages. # Copyright (C) 2012, ejabberd package copyright holder. # This file is distributed under the same license as the ejabberd package. # Beatrice Torracca , 2012. msgid "" msgstr "" "Project-Id-Version: ejabberd\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2012-07-22 13:11+0200\n" "Last-Translator: Beatrice Torracca \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Virtaal 0.7.1\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Il nome dell'host per cui ejabberd farà da server:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Inserire il nome host del server Jabber (in lettere minuscole)." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "Il nome utente di un account di amministrazione per ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Inserire il nome di un account per amministrare il server ejabberd. Dopo " "l'installazione di ejabberd sarà possibile usare questo account per fare il " "login con qualsiasi client Jabber per svolgere compiti di amministrazione " "oppure si potrà andare all'indirizzo http://${hostname}:5280/admin/ e fare " "il login con questo account per entrare nell'interfaccia di amministrazione. " "Inserire qui la parte del nome utente (ad esempio ${user}), ma usare l'ID " "Jabber completo (ad esempio ${user}@${hostname}) per fare il login " "nell'interfaccia web, altrimenti non riuscirà." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Lasciare vuoto se non si desidera creare automaticamente un account di " "amministrazione." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "La password per l'account di amministrazione:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Inserire la password dell'utente amministratore." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "" "Inserire nuovamente la password per l'account di amministrazione per " "verifica:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "Reinserire la password per l'utente amministratore per verifica." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Le password non corrispondono." #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "Le password inserite non corrispondono. Riprovare." ejabberd-2.1.11/debian/po/pt_BR.po0000664000000000000000000000725112240230175013431 0ustar # ejabberd Brazilian Portuguese translation # Copyright (C) 2007 ejabberd's PACKAGE COPYRIGHT HOLDER # This file is distributed under the same license as the ejabberd package. # Alex de Oliveira Silva , 2007. # Felipe Augusto van de Wiel (faw) \n" "Language-Team: Brazilian Portuguese \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "pt_BR utf-8\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "O nome da máquina na qual o ejabberd será servidor:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "" "Por favor, informe o nome da máquina do seu servidor Jabber (em letras " "minúsculas)." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "O nome de usuário de uma conta administrativa para o ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Por favor, forneça o nome de uma conta para administrar o servidor ejabberd. " "Depois da instalação do ejabberd você pode usar esta conta para logar em " "qualquer cliente Jabber para realizar tarefas administrativas ou acesse " "http://${hostname}:5280/admin/ e efetue o login com esta conta para entrar " "na interface administrativa. Informe aqui a parte do nome de usuário (e.g. " "${user}), mas use um ID Jabber completo (e.g. ${user}@${hostname}) para " "efetuar login na interface web do ejabberd; caso contrário não funcionará." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Deixe vazio se você não quer criar automaticamente uma conta administrativa." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "A senha para a conta administrativa:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Por favor, informe a senha para o usuário administrativo." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "A senha para a conta administrativa, novamente, para verificação:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "" "Por favor, informe novamente a senha do usuário administrativo para " "verificação." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "As senhas não conferem!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "As senhas que você digitou não conferem. Por favor, tente novamente." ejabberd-2.1.11/debian/po/ja.po0000664000000000000000000000731012240230175013011 0ustar # Copyright (C) 2009 Torsten Werner # This file is distributed under the same license as ejabberd package. # Hideki Yamane (Debian-JP) , 2009. # msgid "" msgstr "" "Project-Id-Version: ejabberd 2.0.5-1.1\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2009-11-07 14:26+0900\n" "Last-Translator: Hideki Yamane (Debian-JP) \n" "Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "ejabberd が動作するホスト名:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Jabber サーバのホスト名を入力してください (小文字)。" #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "ejabberd 管理者アカウントのユーザ名:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "ejabberd サーバを管理するアカウントの名前を入力してください。ejabberd のイン" "ストール後は、どの Jabber クライアントからでも、このアカウントを使って管理作" "業を実施することができますし、http://${hostname}:5280/admin/ からこのアカウン" "トでログインして管理画面に入れます。ここでユーザ名の部分 (例: ${user}) を入力" "するわけですが、ejabberd のウェブインターフェイスでは、ログインするのに完全" "な Jabber ID (例: ${user}@${hostname}) を使ってください。それ以外はログインに" "失敗します。" #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "自動的に管理者アカウントを作りたくない場合は空のままにしておいてください。" #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "管理者アカウントのパスワード:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "管理者権限ユーザのパスワードを入力してください。" #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "確認のため、管理者アカウントのパスワードの再入力:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "管理者権限ユーザのパスワードを確認のため再入力してください。" #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "パスワードが一致しません!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "入力されたパスワードが一致しません。再入力してください。" ejabberd-2.1.11/debian/po/POTFILES.in0000664000000000000000000000004412240230175013631 0ustar [type: gettext/rfc822deb] templates ejabberd-2.1.11/debian/po/cs.po0000664000000000000000000000704012240230175013024 0ustar # Czech translation of ejabberd debconf messages # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the ejabberd package. # Miroslav Kure , 2006, 2008. # msgid "" msgstr "" "Project-Id-Version: ejabberd\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2008-07-26 18:50+0200\n" "Last-Translator: Miroslav Kure \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Jméno počítače, na kterém bude ejabberd sloužit:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "" "Zadejte prosím jméno počítače vašeho jabberového serveru (malými písmeny)." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "Jméno administrátorského účtu pro ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Zadejte prosím jméno účtu, který bude spravovat ejabberd server. Po " "instalaci serveru ejabberd se můžete pomocí tohoto účtu přihlásit z " "libovolného jabberového klienta a vzdáleně tak provádět správcovské úkony. " "Jinou možností je webové rozhraní na http://${hostname}:5280/admin/, kde se " "s tímto účtem (např. „${user}@${hostname}“) taktéž můžete přihlásit do " "správcovského rozhraní. (Zde zadejte pouze uživatelskou část (např. " "${user}), ale pro přihlášení do webového rozhraní používejte kompletní ID " "včetně jména serveru.)" #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Jestliže nechcete automaticky vytvořit správcovský účet, ponechte prázdné." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "Heslo správcovského účtu:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Zadejte prosím heslo uživatele se správcovskými oprávněními." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "Ověření hesla správcovského účtu:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "" "Pro ověření prosím zopakujte heslo uživatele se správcovskými oprávněními." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Hesla nesouhlasí!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "Zadaná hesla nesouhlasí. Zkuste to prosím znovu." ejabberd-2.1.11/debian/po/pt.po0000664000000000000000000000663712240230175013055 0ustar # Portuguese translation of ejabberd's debconf messages. # Copyright (C) 2007 # This file is distributed under the same license as the ejabberd package. # Luísa Lourenço , 2007. # msgid "" msgstr "" "Project-Id-Version: ejabberd 1.1.2-6\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2007-03-28 13:03+0100\n" "Last-Translator: Luísa Lourenço \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "O nome da máquina que o ejabberd irá servir:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "" "Por favor insira o nome da máquina do seu servidor de Jabber (em minúsculas)." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "O nome de uma conta de admin para o ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Por favor forneça o nome de uma conta para administrar o servidor ejabberd. " "Depois da instalação do ejabberd pode usar esta conta para se ligar a " "qualquer cliente Jabber para efectuar tarefas administrativas ou ir a http://" "${hostname}:5280/admin/ e ligar com esta conta para entrar na interface de " "admin. Certifique-se que insere o Jabber ID completo (p.e. '${user}@" "${hostname}') para se ligar; caso contrário irá falhar." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "Deixe em branco caso não queira criar uma conta admin automaticamente." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "A palavra chave para a conta de admin:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Por favor insira a palavra chave para o utilizador administrativo." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "De novo a palavra chave para a conta de admin para verificação:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "" "Por favor re-insira a palavra chave para o utilizador administrativo para " "verificaçao." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "As palavras chave não coincidem!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "As palavras chave que inseriu não coincidem. Por favor tente de novo." ejabberd-2.1.11/debian/po/fi.po0000664000000000000000000000623312240230175013020 0ustar msgid "" msgstr "" "Project-Id-Version: ejabberd\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2008-07-21 08:41+0200\n" "Last-Translator: Esko Arajärvi \n" "Language-Team: Finnish \n" "Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Finnish\n" "X-Poedit-Country: FINLAND\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Palvelin, jolla ejabberdia ajetaan:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Anna Jabber-palvelimen verkkonimi (pienellä kirjoitettuna)." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "ejabberdin ylläpitotunnus:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Anna tunnus, jota käytetään ejabberd-palvelimen ylläpitoon. Asennuksen " "jälkeen tällä tunnuksella voidaan tehdä ylläpitoon liittyviä tehtäviä " "käyttäen mitä tahansa Jabber-asiakasta. Sen avulla voidaan myös kirjautua " "osoitteessa http://${hostname}:5280/admin/ olevaan ylläpitokäyttöliittymään. " "Anna tässä vain käyttäjätunnus (esim. ${user}), mutta käytä ejabberdin " "verkkokäyttöliittymässä Jabber ID:tä kokonaisuudessaan (esim. ${user}@" "${hostname}). " #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Jätä kenttä tyhjäksi, jos ylläpitotunnusta ei haluta luoda automaattisesti." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "Ylläpitotunnuksen salasana:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Anna salasana ylläpitotunnukselle." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "Ylläpitotunnuksen salasana uudelleen:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "Anna ylläpitotunnuksen salasana uudelleen varmennuksena." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Salasanat eivät täsmää!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "Annetut salasanat eivät täsmää. Yritä uudelleen." ejabberd-2.1.11/debian/po/tr.po0000664000000000000000000000703312240230175013046 0ustar # Turkish translation of ejabberd debconf template. # Copyright (C) 2008 # This file is distributed under the same license as the ejabberd package. # Mert Dirik , 2008. # msgid "" msgstr "" "Project-Id-Version: ejabberd\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2008-07-20 00:41+0200\n" "Last-Translator: Mert Dirik \n" "Language-Team: Debian L10n Turkish \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Poedit-Language: Turkish\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "ejabberd hizmeti verecek olan makinenin adı:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Lütfen Jabber sunucunuzun makine adını girin (küçük harflerle)." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "ejabberd yönetici hesabının kullanıcı adı:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Lütfen ejabberd sunucusunu yönetecek olan hesabın adını girin. Kurulum " "bittikten sonra yönetimsel görevleri yerine getirmek için herhangi bir " "Jabber istemcisini kullanarak bu hesapla oturum açabilir ya da http://" "${hostname}:5280/admin/ adresine gidip bu hesapla oturum açarak yönetim " "arayüzüne girebilirsiniz. Buraya kullanıcı adı kısmını girin (ör. ${user}), " "ama ejabberd web arayüzüne erişmek için tam Jabber kimliğini (ör. ${user}@" "${hostname}) kullanın, aksi takdirde oturum açamazsınız." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Yönetici hesabını otomatik olarak oluşturmak istemiyorsanız bu alanı boş " "bırakın." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "Yönetici hesabının parolası:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Lütfen yönetimsel kullanıcı için bir parola girin." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "Yönetici hesabının parolası, doğrulama için tekrardan:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "Lütfen yönetimsel kullanıcının parolasını doğrulama için tekrar girin." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Parolalar eşleşmedi!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "Girdiğiniz parolalar eşleşmedi. Lütfen tekrar deneyin." ejabberd-2.1.11/debian/po/ru.po0000664000000000000000000001112712240230175013046 0ustar # # Translators, if you are not familiar with the PO format, gettext # documentation is worth reading, especially sections dedicated to # this format, e.g. by running: # info -n '(gettext)PO Files' # info -n '(gettext)Header Entry' # # Some information specific to po-debconf are available at # /usr/share/doc/po-debconf/README-trans # or http://www.debian.org/intl/l10n/po-debconf/README-trans # # Developers do not need to manually edit POT or PO files. # Sergei Golovan , 2007. # Sergey Alyoshin , 2008. # msgid "" msgstr "" "Project-Id-Version: 2.0.1-2\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2008-07-19 14:36+0400\n" "Last-Translator: Sergey Alyoshin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Имя хоста, которое будет обслуживать ejabberd:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Введите имя вашего Jabber-сервера (строчными буквами)." #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "Имя учётной записи администратора ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Пожалуйста, введите имя учётной записи администратора сервера ejabberd. " "После установки ejabberd вы сможете подключаться к нему с помощью Jabber-" "клиента, используя эту учетную запись, и администрировать сервер. Также вы " "сможете использовать интерфейс администратора по адресу http://" "${hostname}:5280/admin/. Сейчас введите только имя (например, ${user}), а " "для последующего подключения используйте полный Jabber ID (например, '${user}" "@${hostname}'), иначе подключиться к интерфейсу администратора не удастся." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Оставьте поле пустым, если не хотите создавать учётную запись администратора " "автоматически." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "Пароль учётной записи администратора:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Введите пароль администратора." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "Повторный ввод пароля администратора для проверки:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "Введите пароль администратора ещё раз для проверки." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "Пароли не совпадают!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "Введённые пароли не совпадают. Попробуйте ещё раз." ejabberd-2.1.11/debian/po/nl.po0000664000000000000000000000654612240230175013042 0ustar # Dutch translation of ejabberd debconf templates. # Copyright (C) 2006-2012 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the ejabberd package. # Sander Devrieze , 2006. # Jeroen Schot , 2012. # msgid "" msgstr "" "Project-Id-Version: ejabberd 2.1.9-1\n" "Report-Msgid-Bugs-To: twerner@debian.org\n" "POT-Creation-Date: 2008-02-15 10:37+0300\n" "PO-Revision-Date: 2012-01-27 10:54+0100\n" "Last-Translator: Jeroen Schot \n" "Language-Team: \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../templates:1001 msgid "The name of the host ejabberd will serve:" msgstr "Naam van de computer die ejabberd moet aanbieden:" #. Type: string #. Description #: ../templates:1001 msgid "Please enter the hostname of your Jabber server (in lowercase)." msgstr "Wat is de computernaam van uw Jabber-server (in kleine letters)?" #. Type: string #. Description #: ../templates:2001 msgid "The username of an admin account for ejabberd:" msgstr "Naam van een beheerdersaccount voor ejabberd:" #. Type: string #. Description #: ../templates:2001 msgid "" "Please provide the name of an account to administrate the ejabberd server. " "After the installation of ejabberd you can use this account to log in with " "any Jabber client to do administrative tasks or go to http://" "${hostname}:5280/admin/ and log in with this account to enter the admin " "interface. Enter the username part here (e.g. ${user}), but use the full " "Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; " "otherwise it will fail." msgstr "" "Geef de naam op van een account om ejabberd te beheren. Na de installatie " "van ejabberd kunt u met deze account in elke Jabber-client of op http://" "${hostname}:5280/admin/ beheerderstaken uitvoeren. Geeft hier alleen het " "gebruiksnaam-deel op (bv. ${user}), maar gebruik het volledige Jabber-ID " "(bv. ${user}@${hostname) om in te loggen op de webinterface van ejabberd, " "anders zal dit mislukken." #. Type: string #. Description #: ../templates:2001 msgid "Leave empty if you don't want to create an admin account automatically." msgstr "" "Voer niets in als u niet automatisch een beheerdersaccount wilt aanmaken." #. Type: password #. Description #: ../templates:3001 msgid "The password for the admin account:" msgstr "Wachtwoord voor de beheerdersaccount:" #. Type: password #. Description #: ../templates:3001 msgid "Please enter the password for the administrative user." msgstr "Voer het wachtwoord in voor de beheerder." #. Type: password #. Description #: ../templates:4001 msgid "The password for the admin account again for verification:" msgstr "Nogmaals het wachtwoord voor de beheerdersaccount ter controle:" #. Type: password #. Description #: ../templates:4001 msgid "" "Please reenter the password for the administrative user for verification." msgstr "Voer het wachtwoord voor de beheerder nogmaals in ter controle." #. Type: error #. Description #: ../templates:5001 msgid "The passwords do not match!" msgstr "De wachtwoorden komen niet overeen!" #. Type: error #. Description #: ../templates:5001 msgid "The passwords you have typed do not match. Please try again." msgstr "De ingevoerde wachtwoorden komen niet overeen. Probeer opnieuw." ejabberd-2.1.11/debian/docs0000664000000000000000000000004012240230175012305 0ustar doc/*.html doc/*.png doc/*.txt ejabberd-2.1.11/debian/manpages0000664000000000000000000000005012240230175013151 0ustar debian/ejabberd.8 debian/ejabberdctl.8 ejabberd-2.1.11/debian/doc-base0000664000000000000000000000042512240230175013041 0ustar Document: ejabberd Title: Debian ejabberd Manual Author: Alexey Shchepin Abstract: User manual for ejabberd - Erlang Jabber server. Section: Network/Communication Format: HTML Index: /usr/share/doc/ejabberd/guide.html Files: /usr/share/doc/ejabberd/*.html ejabberd-2.1.11/debian/templates0000664000000000000000000000242512240230175013364 0ustar Template: ejabberd/hostname Type: string Default: localhost _Description: The name of the host ejabberd will serve: Please enter the hostname of your Jabber server (in lowercase). Template: ejabberd/user Type: string _Description: The username of an admin account for ejabberd: Please provide the name of an account to administrate the ejabberd server. After the installation of ejabberd you can use this account to log in with any Jabber client to do administrative tasks or go to http://${hostname}:5280/admin/ and log in with this account to enter the admin interface. Enter the username part here (e.g. ${user}), but use the full Jabber ID (e.g. ${user}@${hostname}) to log into ejabberd web interface; otherwise it will fail. . Leave empty if you don't want to create an admin account automatically. Template: ejabberd/password Type: password _Description: The password for the admin account: Please enter the password for the administrative user. Template: ejabberd/verify Type: password _Description: The password for the admin account again for verification: Please reenter the password for the administrative user for verification. Template: ejabberd/nomatch Type: error _Description: The passwords do not match! The passwords you have typed do not match. Please try again. ejabberd-2.1.11/debian/compat0000664000000000000000000000000212240230175012636 0ustar 7 ejabberd-2.1.11/debian/config0000664000000000000000000000156312240230175012635 0ustar #!/bin/sh set -e get_passwd() { db_input medium ejabberd/password || true db_input medium ejabberd/verify || true db_go || true db_get ejabberd/password PASSWORD="$RET" db_get ejabberd/verify VERIFY="$RET" if [ "$PASSWORD" != "$VERIFY" ]; then db_input medium ejabberd/nomatch || true db_go || true get_passwd fi } get_credentials() { db_get ejabberd/user USER=${RET:-admin} db_subst ejabberd/user user "$USER" db_get ejabberd/hostname HOST=${RET:-hostname} db_subst ejabberd/user hostname "$HOST" db_input medium ejabberd/user || true db_go || true db_get ejabberd/user if [ -n "$RET" ]; then get_passwd fi } # Source debconf library. . /usr/share/debconf/confmodule db_input medium ejabberd/hostname || true db_go || true FLAG="/var/lib/ejabberd/.admin_registered" if [ ! -f $FLAG ]; then get_credentials fi exit 0 ejabberd-2.1.11/debian/watch0000664000000000000000000000017312240230175012472 0ustar version=3 http://www.process-one.net/en/ejabberd/archive/ \ /downloads/ejabberd/[\d.]+/ejabberd-([\d.]+)[_\d]*.tar.gz ejabberd-2.1.11/debian/rules0000775000000000000000000000471112276225425012536 0ustar #!/usr/bin/make -f # -*- makefile -*- # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 include /usr/share/quilt/quilt.make DEB_CONFIGURE_EXTRA_FLAGS := --enable-odbc --enable-pam # Not sure if we should enable workaround for gateway subscription # Adding it breaks XMPP compatibility # Not adding breaks roster import for some gateways (specifically JIT) #DEB_CONFIGURE_EXTRA_FLAGS := --enable-odbc --enable-roster-gateway-workaround AUTO_OPTS = --sourcedirectory=src DESTDIR=$(CURDIR)/debian/ejabberd ifndef HOME export HOME="$(CURDIR)" endif configure: configure-stamp configure-stamp: $(QUILT_STAMPFN) dh_testdir dh_autotools-dev_updateconfig dh_auto_configure $(AUTO_OPTS) -- $(DEB_CONFIGURE_EXTRA_FLAGS) \ $(shell dpkg-buildflags --export=configure) touch configure-stamp build: build-arch build-indep build-arch: build-stamp build-indep: build-stamp build-stamp: configure-stamp dh_testdir dh_auto_build $(AUTO_OPTS) touch $@ clean: unpatch dh_testdir dh_testroot rm -f build-stamp configure-stamp dh_auto_clean $(AUTO_OPTS) dh_autotools-dev_restoreconfig dh_clean install: build dh_testdir dh_testroot dh_prep dh_installdirs dh_auto_install $(AUTO_OPTS) # Remove unused upstream config files: rm $(DESTDIR)/etc/ejabberd/ejabberd.cfg rm $(DESTDIR)/etc/ejabberd/ejabberdctl.cfg # Remove unused upstream directories: rm -rf $(DESTDIR)/var/lock # Remove upstream license file: rm $(DESTDIR)/usr/share/doc/ejabberd/COPYING # Remove autogenerated init-script: rm $(CURDIR)/src/ejabberd.init # Build architecture-independent files here. binary-indep: install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: install dh_testdir dh_testroot dh_installchangelogs dh_installdocs dh_installexamples dh_install # dh_installmenu dh_installdebconf dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python dh_installinit # dh_installcron # dh_installinfo dh_installman dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs erlang-depends dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb get-orig-source: dh_testdir wget -O ../ejabberd_$(DEB_UPSTREAM_VERSION).orig.tar.gz \ http://www.process-one.net/en/projects/ejabberd/download/$(DEB_UPSTREAM_VERSION)/ejabberd-$(DEB_UPSTREAM_VERSION).tar.gz binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure get-orig-source ejabberd-2.1.11/debian/patches/0000775000000000000000000000000012327434417013102 5ustar ejabberd-2.1.11/debian/patches/series0000664000000000000000000000047112327434436014322 0ustar use_dpkg_buildflags.patch ejabberd_regexp.patch mod_admin_extra.patch captcha.patch fix_examples.patch digest-uri-virtual-hosts.patch reopen-log.patch fix-ldap-vcard-jpeg-photos.patch scram-optional-parameter-parsing-bugfix.patch disable-ssl2.patch disable-insecure-ssl-cyphers.patch fix-erlang-r16b-compat.patch ejabberd-2.1.11/debian/patches/reopen-log.patch0000664000000000000000000001322212240230175016157 0ustar This patch fixes several problems pinpointed when dealing with Debian bug #580951: * erlang.log (SASL log file) for some reason only gets reopened each second call to `ejabberdctl reopen-log`; * After reopening the same files (that is, when the files were not renamed (by logrotate, for instance) before reopening), erlang.log gets truncated, and ejabberd.log gets renamed to "ejabberd-old.log"; both behaviours break the "reopening of log files" contract common in Unix. The patch fixes these problems in the following way: * The SASL application is started with its built-in file logger disabled. After this a custom module is inserted to handle SASL messages; this module does not truncate its log file when reopening it. * Built-in ejabberd's "log rotation" (renaming original log files by appending the "-old" suffix to their base names) is disabled. * Both ejabberd's logging module and the custom SASL logging module now respond to a custom event which instructs them to reload their respective log files; this event is synchronously sent to these modules when `ejabberdctl reopen-log` is being run. This problem is being tracked upstream as https://support.process-one.net/browse/EJAB-1243 --- a/src/ejabberd_logger_h.erl +++ b/src/ejabberd_logger_h.erl @@ -58,6 +58,20 @@ %% {swap_handler, Args1, State1, Mod2, Args2} | %% remove_handler %%---------------------------------------------------------------------- +handle_event({ejabberd, reopen}, State) -> + Fd = State#state.fd, + File = State#state.file, + case file:close(Fd) of + ok -> + case file:open(File, [append, raw]) of + {ok, NewFd} -> + {ok, #state{fd = NewFd, file = File}}; + Error -> + Error + end; + Error -> + Error + end; handle_event(Event, State) -> write_event(State#state.fd, {erlang:localtime(), Event}), {ok, State}. @@ -82,7 +96,6 @@ remove_handler; handle_info({emulator, _GL, reopen}, State) -> file:close(State#state.fd), - rotate_log(State#state.file), case file:open(State#state.file, [append, raw]) of {ok, Fd} -> {ok, State#state{fd = Fd}}; --- a/src/ejabberd_admin.erl +++ b/src/ejabberd_admin.erl @@ -223,28 +223,9 @@ reopen_log() -> ejabberd_hooks:run(reopen_log_hook, []), - %% TODO: Use the Reopen log API for logger_h ? - ejabberd_logger_h:reopen_log(), - case application:get_env(sasl,sasl_error_logger) of - {ok, {file, SASLfile}} -> - error_logger:delete_report_handler(sasl_report_file_h), - ejabberd_logger_h:rotate_log(SASLfile), - error_logger:add_report_handler(sasl_report_file_h, - {SASLfile, get_sasl_error_logger_type()}); - _ -> false - end, + gen_event:sync_notify(error_logger, {ejabberd, reopen}), ok. -%% Function copied from Erlang/OTP lib/sasl/src/sasl.erl which doesn't export it -get_sasl_error_logger_type () -> - case application:get_env (sasl, errlog_type) of - {ok, error} -> error; - {ok, progress} -> progress; - {ok, all} -> all; - {ok, Bad} -> exit ({bad_config, {sasl, {errlog_type, Bad}}}); - _ -> all - end. - %%% %%% Stop Kindly %%% --- /dev/null +++ b/src/sasl_report_append_file_h.erl @@ -0,0 +1,59 @@ +%% +%% SASL report logging to a file in append mode. +%% Inspired by Erlang's sasl_report_file_h module. +%% +-module(sasl_report_append_file_h). + +%%% +%%% A handler that can be connected to the error_logger +%%% event handler. +%%% Writes all sasl_* events formatted to file +%%% + +-export([init/1, + handle_event/2, handle_call/2, handle_info/2, + terminate/2]). + +init({File, Type}) -> + process_flag(trap_exit, true), + case file:open(File, [append]) of + {ok,Fd} -> + {ok, {Fd, File, Type}}; + What -> + What + end. + +handle_event({ejabberd, reopen}, {Fd, File, Type}) -> + case file:close(Fd) of + ok -> + case file:open(File, [append]) of + {ok, NewFd} -> + {ok, {NewFd, File, Type}}; + Error -> + Error + end; + Error -> + Error + end; +handle_event({_Type, GL, _Msg}, State) when node(GL) /= node() -> + {ok, State}; +handle_event(Event, {Fd, File, Type}) -> + sasl_report:write_report(Fd, Type, tag_event(Event)), + {ok, {Fd, File, Type}}; +handle_event(_, State) -> + {ok, State}. + +handle_info({'EXIT', Fd, _Reason}, {Fd, _File, _Type}) -> + remove_handler; +handle_info(_, State) -> + {ok, State}. + +handle_call(_Query, _State) -> {error, bad_query}. + +terminate(_, {Fd, _File, _Type}) -> + file:close(Fd), + []. + +tag_event(Event) -> + {calendar:local_time(), Event}. + --- a/src/ejabberd_app.erl +++ b/src/ejabberd_app.erl @@ -103,6 +103,13 @@ register(ejabberd, self()), %erlang:system_flag(fullsweep_after, 0), %error_logger:logfile({open, ?LOG_PATH}), + case get_sasl_logger() of + {File, Type} -> + error_logger:add_report_handler(sasl_report_append_file_h, + {File, Type}); + _ -> + ok + end, LogPath = get_log_path(), error_logger:add_report_handler(ejabberd_logger_h, LogPath), erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv), @@ -113,6 +120,23 @@ Port = open_port({spawn, "expat_erl"}, [binary]), loop(Port). +get_sasl_logger() -> + case application:get_env(ejabberd, erlang_log_path) of + {ok, File} -> + {File, get_sasl_error_logger_type()}; + _ -> + false + end. + +%% Function copied from Erlang/OTP lib/sasl/src/sasl.erl which doesn't export it +get_sasl_error_logger_type () -> + case application:get_env (sasl, errlog_type) of + {ok, error} -> error; + {ok, progress} -> progress; + {ok, all} -> all; + {ok, Bad} -> exit ({bad_config, {sasl, {errlog_type, Bad}}}); + _ -> all + end. loop(Port) -> receive ejabberd-2.1.11/debian/patches/captcha.patch0000664000000000000000000000106112240230175015511 0ustar Makes the captcha script explicitly request bash as it uses its special variable "RANDOM" which is not defined by POSIX. The issue is tracked upstream at https://support.process-one.net/browse/EJAB-1105 While it will be sensible to incorporate the upstream fix (which will make the script work in POSIX-compliant shells also), until bash is required in Debian, this patch is OK. diff --git a/tools/captcha.sh b/tools/captcha.sh index 4d40567..d68edfa 100755 --- a/tools/captcha.sh +++ b/tools/captcha.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash INPUT=$1 ejabberd-2.1.11/debian/patches/fix_examples.patch0000664000000000000000000000153312240230175016576 0ustar Author: Gerfried Fuchs vim:ft=diff: Description: Fix syntax problems with the example scripts Index: VCS/examples/mtr/ejabberd =================================================================== --- VCS.orig/examples/mtr/ejabberd +++ VCS/examples/mtr/ejabberd @@ -44,9 +44,8 @@ force*) ;; esac -if checkyesno ${rcvar} +if ! checkyesno ${rcvar} then -else exit 0 fi Index: VCS/examples/mtr/ejabberd-netbsd.sh =================================================================== --- VCS.orig/examples/mtr/ejabberd-netbsd.sh +++ VCS/examples/mtr/ejabberd-netbsd.sh @@ -8,8 +8,7 @@ if [ ! pkg_info erlang 1>/dev/null 2>&1 make make install fi -if pkg_info erlang | grep -q erlang-9.1nb1; then -else +if ! pkg_info erlang | grep -q erlang-9.1nb1; then echo "erlang-9.1nb1 not installed" 1>&2 exit 1 fi ejabberd-2.1.11/debian/patches/fix-ldap-vcard-jpeg-photos.patch0000664000000000000000000000117212240230175021147 0ustar Description: Fix fetching JPEG vCard photos via LDAP Origin: upstream, https://github.com/processone/ejabberd/commit/be33ab890e35ae5c41285dd5ed422db910534040 Bug-ProcessOne: https://support.process-one.net/browse/EJAB-1526 Applied-Upstream: 2.1.11 Last-Update: 2013-02-17 diff --git a/src/eldap/eldap_filter.erl b/src/eldap/eldap_filter.erl index f8f20be..e78ee7e 100644 --- a/src/eldap/eldap_filter.erl +++ b/src/eldap/eldap_filter.erl @@ -181,5 +181,6 @@ do_sub(S, {RegExp, New, Times}, Iter) -> replace_amps(String) -> lists:flatmap( fun($&) -> "\\&"; + ($\\) -> "\\\\"; (Chr) -> [Chr] end, String). ejabberd-2.1.11/debian/patches/disable-ssl2.patch0000664000000000000000000000267512240230175016406 0ustar Description: Disable SSLv2 in the TLS driver SSL 2.0 is not used anywhere as it has security problems. Disable it unconditionally both in server and client mode. This does not disable support for SSL 2.0 compatible client hello which still will be accepted in the server mode. . This patch is a backport of changes introduced by the commit e06c1c49c14c3f56cf4ddae080514f7802669335 in the upstream Git repository to the ejabberd code base as of version 2.1.12. Author: Janusz Dziemidowicz Forwarded: not-needed Last-Update: 2013-09-29 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/src/tls/tls_drv.c +++ b/src/tls/tls_drv.c @@ -354,6 +354,8 @@ static ErlDrvSSizeT tls_drv_control(ErlDrvData handle, res = SSL_CTX_check_private_key(ctx); die_unless(res > 0, "SSL_CTX_check_private_key failed"); + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET); + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); SSL_CTX_set_default_verify_paths(ctx); #ifdef SSL_MODE_RELEASE_BUFFERS @@ -386,10 +388,8 @@ static ErlDrvSSizeT tls_drv_control(ErlDrvData handle, SSL_set_bio(d->ssl, d->bio_read, d->bio_write); if (command == SET_CERTIFICATE_FILE_ACCEPT) { - SSL_set_options(d->ssl, SSL_OP_NO_TICKET); SSL_set_accept_state(d->ssl); } else { - SSL_set_options(d->ssl, SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET); SSL_set_connect_state(d->ssl); } break; ejabberd-2.1.11/debian/patches/use_dpkg_buildflags.patch0000664000000000000000000000546712240230175020121 0ustar Description: Use CPPFLAGS from environment (dpkg-buildflags). Necessary for hardening flags. Author: Simon Ruderich Last-Update: 2012-03-15 Index: ejabberd-2.1.10/src/configure =================================================================== --- ejabberd-2.1.10.orig/src/configure 2012-03-15 00:20:28.288591657 +0100 +++ ejabberd-2.1.10/src/configure 2012-03-15 00:22:09.780595520 +0100 @@ -4479,7 +4479,7 @@ fi zlib_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $ZLIB_CFLAGS" - zlib_save_CPPFLAGS="$CFLAGS" + zlib_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" for ac_header in zlib.h do : Index: ejabberd-2.1.10/src/acinclude.m4 =================================================================== --- ejabberd-2.1.10.orig/src/acinclude.m4 2012-03-15 00:20:28.288591657 +0100 +++ ejabberd-2.1.10/src/acinclude.m4 2012-03-15 00:22:09.784595520 +0100 @@ -54,7 +54,7 @@ fi zlib_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $ZLIB_CFLAGS" - zlib_save_CPPFLAGS="$CFLAGS" + zlib_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" AC_CHECK_HEADERS(zlib.h, , zlib_found=no) if test $zlib_found = no; then Index: ejabberd-2.1.10/src/Makefile.in =================================================================== --- ejabberd-2.1.10.orig/src/Makefile.in 2012-03-15 00:20:28.288591657 +0100 +++ ejabberd-2.1.10/src/Makefile.in 2012-03-15 00:22:09.784595520 +0100 @@ -168,7 +168,7 @@ @ERLC@ -W $(EFLAGS) $*.erl $(ERLSHLIBS): %.so: %.c - $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) \ + $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LIBS) \ $(subst ../,,$(subst .so,.c,$@)) \ $(EXPAT_LIBS) \ $(EXPAT_CFLAGS) \ Index: ejabberd-2.1.10/src/mod_irc/Makefile.in =================================================================== --- ejabberd-2.1.10.orig/src/mod_irc/Makefile.in 2012-03-15 00:20:28.288591657 +0100 +++ ejabberd-2.1.10/src/mod_irc/Makefile.in 2012-03-15 00:22:09.784595520 +0100 @@ -41,7 +41,7 @@ # erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt $(ERLSHLIBS): ../%.so: %.c - $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) \ + $(CC) $(INCLUDES) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) \ $(subst ../,,$(subst .so,.c,$@)) \ $(LIBS) \ $(ERLANG_CFLAGS) \ Index: ejabberd-2.1.10/src/stringprep/Makefile.in =================================================================== --- ejabberd-2.1.10.orig/src/stringprep/Makefile.in 2012-03-15 00:22:43.904596819 +0100 +++ ejabberd-2.1.10/src/stringprep/Makefile.in 2012-03-15 00:22:58.844597386 +0100 @@ -42,7 +42,7 @@ # erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt $(ERLSHLIBS): ../%.so: %.c uni_data.c uni_norm.c - $(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDES) \ + $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(INCLUDES) \ $(subst ../,,$(subst .so,.c,$@)) $(LIBS) \ $(ERLANG_LIBS) \ $(ERLANG_CFLAGS) \ ejabberd-2.1.11/debian/patches/disable-insecure-ssl-cyphers.patch0000664000000000000000000000230712240230175021602 0ustar Description: Disable old and insecure cyphers in TLS driver Disabled: * Export ciphers - broken by design, 40 and 56 bit encryption. * Low encryption ciphers - 56 and 64 bit encryption. * SSLv2 ciphers - some ciphers using MD5 MAC. . This patch is a backport of changes introduced by the commit d2d51381ec3fea97d0bd968cd7ffed2364b644c6 in the upstream Git repository to the ejabberd code base as of version 2.1.12. Author: Janusz Dziemidowicz Forwarded: not-needed Last-Update: 2013-09-29 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/src/tls/tls_drv.c +++ b/src/tls/tls_drv.c @@ -44,6 +44,8 @@ typedef unsigned __int32 uint32_t; #define SSL_OP_NO_TICKET 0 #endif +#define CIPHERS "DEFAULT:!EXPORT:!LOW:!SSLv2" + /* * R15B changed several driver callbacks to use ErlDrvSizeT and * ErlDrvSSizeT typedefs instead of int. @@ -356,6 +358,8 @@ static ErlDrvSSizeT tls_drv_control(ErlDrvData handle, SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET); + SSL_CTX_set_cipher_list(ctx, CIPHERS); + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); SSL_CTX_set_default_verify_paths(ctx); #ifdef SSL_MODE_RELEASE_BUFFERS ejabberd-2.1.11/debian/patches/ejabberd_regexp.patch0000664000000000000000000000601312240230175017220 0ustar Description: Provide custom replacement for xmerl_regexp:sh_to_awk/1 Erlang R15 dropped support for its old regular expressions library (implemented as the "regexp" module) and replaced it with a new, PCRE-based, implementation (implemented as the "re" module). This transition lost the regexp:sh_to_awk/1 function which, given a "glob-style expression" commonly used in POSIX shells to match filenames, would produce a regular expression specification with the equivalent semantics. The ejabberd upstream tried to combat this situation [1] by using xmerl_regexp:sh_to_awk/1. This introduced an implicit dependency on the erlang-xmerl library which has been the cause for a Debian bug #670307. Depending on erlang-xmerl has two problems: 1) It's a 1.5M library otherwise not used by ejabberd code while the function itself is rather straightforward to implement. 2) The implementation of xmerl_regexp:sh_to_awk/1 has certain flaws (incorrect parsing of bracketed expressions, not escaping match repetition counts). As a result, a custom implementation of sh_to_awk/1 is provided, which works almost like xmerl_regexp:sh_to_awk/1 but fixes its flaws. 1. https://support.process-one.net/browse/EJAB-921 Author: Konstantin Khomoutov Forwarded: no Last-Update: 2012-06-04 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/src/ejabberd_regexp.erl +++ b/src/ejabberd_regexp.erl @@ -26,6 +26,7 @@ -module(ejabberd_regexp). -compile([export_all]). +-import(lists, [reverse/1, member/2]). exec(ReM, ReF, ReA, RgM, RgF, RgA) -> try apply(ReM, ReF, ReA) @@ -66,7 +67,56 @@ A -> A end. -sh_to_awk(ShRegExp) -> - case exec(xmerl_regexp, sh_to_awk, [ShRegExp], regexp, sh_to_awk, [ShRegExp]) of - A -> A +sh_to_awk(Pattern) when is_list(Pattern) -> + fnmatch_char(Pattern, [$(,$^]). + +fnmatch_char([], Acc) -> + lists:reverse([$$,$)|Acc]); +fnmatch_char([Ch|Tail], Acc) -> + case Ch of + $\\ -> + fnmatch_char(Tail, [$\\,$\\|Acc]); + $[ -> + fnmatch_bexp_first(Tail, [Ch|Acc]); + $? -> + fnmatch_char(Tail, [$.|Acc]); + $* -> + fnmatch_char(Tail, [$*,$.|Acc]); + _ -> + case lists:member(Ch, "^.+{}()$|\\") of + true -> + fnmatch_char(Tail, [Ch,$\\|Acc]); + false -> + fnmatch_char(Tail, [Ch|Acc]) + end + end. + +fnmatch_bexp_first([], _) -> + {error, unclosed_be}; +fnmatch_bexp_first([Ch|Tail], Acc) -> + case Ch of + $] -> + {error, empty_be}; + $! -> + fnmatch_bexp_next(Tail, false, [$^|Acc]); + $\\ -> + fnmatch_bexp_next(Tail, true, Acc); + _ -> + fnmatch_bexp_next(Tail, false, [Ch|Acc]) + end. + +fnmatch_bexp_next([], _, _) -> + {error, unclosed_be}; +fnmatch_bexp_next([Ch|Tail], true, Acc) -> + fnmatch_bexp_next(Tail, false, [Ch,$\\|Acc]); +fnmatch_bexp_next([Ch|Tail], false, Acc) -> + case Ch of + $] -> + fnmatch_char(Tail, [Ch|Acc]); + $\\ -> + fnmatch_bexp_next(Tail, true, Acc); + _ -> + fnmatch_bexp_next(Tail, false, [Ch|Acc]) end. + +%% vim:ts=8:sw=4:sts=4:noet ejabberd-2.1.11/debian/patches/scram-optional-parameter-parsing-bugfix.patch0000664000000000000000000001035512240230175023745 0ustar Description: Fix parsing SCRAM optional parameters The server gave an authentication error, if optional parameters were present in the GS2 Header. Specifically, the "a=" parameter, that can be used by admins to login as a different user. . This patch is a backport of changes introduced by the commit 9e9b0eae802ee0508db6780426954efd048e7976 in the upstream Git repository to the ejabberd code base as of version 2.1.10. Author: Stephen Röttger Forwarded: not-needed Bug: https://support.process-one.net/browse/EJAB-1632 Last-Update: 2013-03-25 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/src/cyrsasl_scram.erl +++ b/src/cyrsasl_scram.erl @@ -34,6 +34,8 @@ -include("ejabberd.hrl"). +-include("jlib.hrl"). + -behaviour(cyrsasl). -record(state, {step, stored_key, server_key, username, get_password, check_password, @@ -52,8 +54,12 @@ {ok, #state{step = 2, get_password = GetPassword}}. mech_step(#state{step = 2} = State, ClientIn) -> - case string:tokens(ClientIn, ",") of - [CBind, UserNameAttribute, ClientNonceAttribute] when (CBind == "y") or (CBind == "n") -> + case re:split(ClientIn, ",", [{return, list}]) of + [_CBind, _AuthorizationIdentity, _UserNameAttribute, _ClientNonceAttribute, ExtensionAttribute | _] + when ExtensionAttribute /= [] -> + {error, <<"protocol-error-extension-not-supported">>}; + [CBind, _AuthorizationIdentity, UserNameAttribute, ClientNonceAttribute | _] + when (CBind == "y") or (CBind == "n") -> case parse_attribute(UserNameAttribute) of {error, Reason} -> {error, Reason}; @@ -100,32 +106,36 @@ case string:tokens(ClientIn, ",") of [GS2ChannelBindingAttribute, NonceAttribute, ClientProofAttribute] -> case parse_attribute(GS2ChannelBindingAttribute) of - {$c, CVal} when (CVal == "biws") or (CVal == "eSws") -> - %% biws is base64 for n,, => channelbinding not supported - %% eSws is base64 for y,, => channelbinding supported by client only - Nonce = State#state.client_nonce ++ State#state.server_nonce, - case parse_attribute(NonceAttribute) of - {$r, CompareNonce} when CompareNonce == Nonce -> - case parse_attribute(ClientProofAttribute) of - {$p, ClientProofB64} -> - ClientProof = base64:decode(ClientProofB64), - AuthMessage = State#state.auth_message ++ "," ++ string:substr(ClientIn, 1, string:str(ClientIn, ",p=")-1), - ClientSignature = scram:client_signature(State#state.stored_key, AuthMessage), - ClientKey = scram:client_key(ClientProof, ClientSignature), - CompareStoredKey = scram:stored_key(ClientKey), - if CompareStoredKey == State#state.stored_key -> - ServerSignature = scram:server_signature(State#state.server_key, AuthMessage), - {ok, [{username, State#state.username}], "v=" ++ base64:encode_to_string(ServerSignature)}; - true -> - {error, "bad-auth"} + {$c, CVal} -> + ChannelBindingSupport = string:left(jlib:decode_base64(CVal), 1), + if (ChannelBindingSupport == "n") + or (ChannelBindingSupport == "y") -> + Nonce = State#state.client_nonce ++ State#state.server_nonce, + case parse_attribute(NonceAttribute) of + {$r, CompareNonce} when CompareNonce == Nonce -> + case parse_attribute(ClientProofAttribute) of + {$p, ClientProofB64} -> + ClientProof = base64:decode(ClientProofB64), + AuthMessage = State#state.auth_message ++ "," ++ string:substr(ClientIn, 1, string:str(ClientIn, ",p=")-1), + ClientSignature = scram:client_signature(State#state.stored_key, AuthMessage), + ClientKey = scram:client_key(ClientProof, ClientSignature), + CompareStoredKey = scram:stored_key(ClientKey), + if CompareStoredKey == State#state.stored_key -> + ServerSignature = scram:server_signature(State#state.server_key, AuthMessage), + {ok, [{username, State#state.username}], "v=" ++ base64:encode_to_string(ServerSignature)}; + true -> + {error, "bad-auth"} + end; + _Else -> + {error, "bad-protocol"} end; + {$r, _} -> + {error, "bad-nonce"}; _Else -> {error, "bad-protocol"} end; - {$r, _} -> - {error, "bad-nonce"}; - _Else -> - {error, "bad-protocol"} + true -> + {error, "bad-channel-binding"} end; _Else -> {error, "bad-protocol"} ejabberd-2.1.11/debian/patches/digest-uri-virtual-hosts.patch0000664000000000000000000000416012240230407021005 0ustar From f4345017c347d039013a33af9718e8c2c16ee84f Mon Sep 17 00:00:00 2001 From: Badlop Date: Thu, 21 Jun 2012 13:56:25 +0200 Subject: [PATCH] Allow multiple fqdn values in configuration (EJAB-1578) --- doc/guide.tex | 2 +- src/cyrsasl_digest.erl | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/doc/guide.tex b/doc/guide.tex index ca60f37..552b83a 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -1241,7 +1241,7 @@ The option \option{fqdn} allows you to define the Fully Qualified Domain Name of the machine, in case it isn't detected automatically. The FQDN is used to authenticate some clients that use the DIGEST-MD5 SASL mechanism. The option syntax is: -\esyntax{\{fqdn, undefined|FqdnString\}.} +\esyntax{\{fqdn, undefined|FqdnString|[FqdnString]\}.} \makesubsubsection{internalauth}{Internal} \ind{internal authentication}\ind{Mnesia} diff --git a/src/cyrsasl_digest.erl b/src/cyrsasl_digest.erl index 134a86d..056df33 100644 --- a/src/cyrsasl_digest.erl +++ b/src/cyrsasl_digest.erl @@ -165,14 +165,25 @@ parse4([], Key, Val, Ts) -> is_digesturi_valid(DigestURICase, JabberDomain, JabberFQDN) -> DigestURI = stringprep:tolower(DigestURICase), case catch string:tokens(DigestURI, "/") of - ["xmpp", Host] when (Host == JabberDomain) or (Host == JabberFQDN) -> - true; - ["xmpp", Host, ServName] when (ServName == JabberDomain) and (Host == JabberFQDN) -> - true; + ["xmpp", Host] -> + IsHostFqdn = is_host_fqdn(Host, JabberFQDN), + (Host == JabberDomain) or IsHostFqdn; + ["xmpp", Host, ServName] -> + IsHostFqdn = is_host_fqdn(Host, JabberFQDN), + (ServName == JabberDomain) and IsHostFqdn; _ -> false end. +is_host_fqdn(Host, [Letter | _Tail] = Fqdn) when not is_list(Letter) -> + Host == Fqdn; +is_host_fqdn(_Host, []) -> + false; +is_host_fqdn(Host, [Fqdn | _FqdnTail]) when Host == Fqdn -> + true; +is_host_fqdn(Host, [Fqdn | FqdnTail]) when Host /= Fqdn -> + is_host_fqdn(Host, FqdnTail). + get_local_fqdn() -> case (catch get_local_fqdn2()) of Str when is_list(Str) -> Str; -- 1.7.9.5 ejabberd-2.1.11/debian/patches/mod_admin_extra.patch0000664000000000000000000015214012240230175017245 0ustar Adds the mod_admin_extra module to ejabberd. This module extends the functionality provided by ejabberdctl by adding several new commands. The code is taken from the ProcessOne repository: https://forge.process-one.net/browse/ejabberd-modules/mod_admin_extra (trunk, revision 1126). --- a/src/ejabberd.app +++ b/src/ejabberd.app @@ -105,6 +105,7 @@ mod_vcard_ldap, mod_vcard_odbc, mod_version, + mod_admin_extra, node_buddy, node_club, node_default, --- /dev/null +++ b/src/mod_admin_extra.erl @@ -0,0 +1,1568 @@ +%%%------------------------------------------------------------------- +%%% File : mod_admin_extra.erl +%%% Author : Badlop +%%% Purpose : Contributed administrative functions and commands +%%% Created : 10 Aug 2008 by Badlop +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2008 ProcessOne +%%% +%%% 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., 59 Temple Place, Suite 330, Boston, MA +%%% 02111-1307 USA +%%% +%%%------------------------------------------------------------------- + +-module(mod_admin_extra). +-author('badlop@process-one.net'). + +-behaviour(gen_mod). + +-export([start/2, stop/1, + %% Node + compile/1, + load_config/1, + get_cookie/0, + remove_node/1, + export2odbc/2, + %% Accounts + set_password/3, + check_password_hash/4, + delete_old_users/1, + delete_old_users_vhost/2, + ban_account/3, + num_active_users/2, + %% Sessions + num_resources/2, + resource_num/3, + kick_session/4, + status_num/2, status_num/1, + status_list/2, status_list/1, + connected_users_info/0, + connected_users_vhost/1, + set_presence/7, + user_sessions_info/2, + %% Vcard + set_nickname/3, + get_vcard/3, + get_vcard/4, + get_vcard_multi/4, + set_vcard/4, + set_vcard/5, + %% Roster + add_rosteritem/7, + delete_rosteritem/4, + process_rosteritems/5, + get_roster/2, + push_roster/3, + push_roster_all/1, + push_alltoall/2, + %% mod_last + set_last/4, + %% mod_private + private_get/4, + private_set/3, + %% mod_shared_roster + srg_create/5, + srg_delete/2, + srg_list/1, + srg_get_info/2, + srg_get_members/2, + srg_user_add/4, + srg_user_del/4, + %% Stanza + send_message_headline/4, + send_message_chat/3, + send_stanza_c2s/4, + privacy_set/3, + %% Stats + stats/1, stats/2 + ]). + +-include("ejabberd.hrl"). +-include("ejabberd_commands.hrl"). +-include("mod_roster.hrl"). +-include("jlib.hrl"). + +%% Copied from ejabberd_sm.erl +-record(session, {sid, usr, us, priority, info}). + + +%%% +%%% gen_mod +%%% + +start(_Host, _Opts) -> + ejabberd_commands:register_commands(commands()). + +stop(_Host) -> + ejabberd_commands:unregister_commands(commands()). + + +%%% +%%% Register commands +%%% + +commands() -> + Vcard1FieldsString = "Some vcard field names in get/set_vcard are:\n" + " FN - Full Name\n" + " NICKNAME - Nickname\n" + " BDAY - Birthday\n" + " TITLE - Work: Position\n" + " ROLE - Work: Role", + + Vcard2FieldsString = "Some vcard field names and subnames in get/set_vcard2 are:\n" + " N FAMILY - Family name\n" + " N GIVEN - Given name\n" + " N MIDDLE - Middle name\n" + " ADR CTRY - Address: Country\n" + " ADR LOCALITY - Address: City\n" + " EMAIL USERID - E-Mail Address\n" + " ORG ORGNAME - Work: Company\n" + " ORG ORGUNIT - Work: Department", + + VcardXEP = "For a full list of vCard fields check XEP-0054: vcard-temp at " + "http://www.xmpp.org/extensions/xep-0054.html", + + [ + #ejabberd_commands{name = compile, tags = [erlang], + desc = "Recompile and reload Erlang source code file", + module = ?MODULE, function = compile, + args = [{file, string}], + result = {res, rescode}}, + #ejabberd_commands{name = load_config, tags = [server], + desc = "Load ejabberd configuration file", + module = ?MODULE, function = load_config, + args = [{file, string}], + result = {res, rescode}}, + #ejabberd_commands{name = get_cookie, tags = [erlang], + desc = "Get the Erlang cookie of this node", + module = ?MODULE, function = get_cookie, + args = [], + result = {cookie, string}}, + #ejabberd_commands{name = remove_node, tags = [erlang], + desc = "Remove an ejabberd node from Mnesia clustering config", + module = ?MODULE, function = remove_node, + args = [{node, string}], + result = {res, rescode}}, + #ejabberd_commands{name = export2odbc, tags = [mnesia], + desc = "Export Mnesia tables to files in directory", + module = ?MODULE, function = export2odbc, + args = [{host, string}, {path, string}], + result = {res, rescode}}, + + #ejabberd_commands{name = num_active_users, tags = [accounts, stats], + desc = "Get number of users active in the last days", + module = ?MODULE, function = num_active_users, + args = [{host, string}, {days, integer}], + result = {users, integer}}, + #ejabberd_commands{name = delete_old_users, tags = [accounts, purge], + desc = "Delete users that didn't log in last days, or that never logged", + module = ?MODULE, function = delete_old_users, + args = [{days, integer}], + result = {res, restuple}}, + #ejabberd_commands{name = delete_old_users_vhost, tags = [accounts, purge], + desc = "Delete users that didn't log in last days in vhost, or that never logged", + module = ?MODULE, function = delete_old_users_vhost, + args = [{host, string}, {days, integer}], + result = {res, restuple}}, + + #ejabberd_commands{name = check_account, tags = [accounts], + desc = "Check if an account exists or not", + module = ejabberd_auth, function = is_user_exists, + args = [{user, string}, {host, string}], + result = {res, rescode}}, + #ejabberd_commands{name = check_password, tags = [accounts], + desc = "Check if a password is correct", + module = ejabberd_auth, function = check_password, + args = [{user, string}, {host, string}, {password, string}], + result = {res, rescode}}, + #ejabberd_commands{name = check_password_hash, tags = [accounts], + desc = "Check if the password hash is correct", + longdesc = "Allowed hash methods: md5, sha.", + module = ?MODULE, function = check_password_hash, + args = [{user, string}, {host, string}, {passwordhash, string}, {hashmethod, string}], + result = {res, rescode}}, + #ejabberd_commands{name = change_password, tags = [accounts], + desc = "Change the password of an account", + module = ?MODULE, function = set_password, + args = [{user, string}, {host, string}, {newpass, string}], + result = {res, rescode}}, + #ejabberd_commands{name = ban_account, tags = [accounts], + desc = "Ban an account: kick sessions and set random password", + module = ?MODULE, function = ban_account, + args = [{user, string}, {host, string}, {reason, string}], + result = {res, rescode}}, + + #ejabberd_commands{name = num_resources, tags = [session], + desc = "Get the number of resources of a user", + module = ?MODULE, function = num_resources, + args = [{user, string}, {host, string}], + result = {resources, integer}}, + #ejabberd_commands{name = resource_num, tags = [session], + desc = "Resource string of a session number", + module = ?MODULE, function = resource_num, + args = [{user, string}, {host, string}, {num, integer}], + result = {resource, string}}, + #ejabberd_commands{name = kick_session, tags = [session], + desc = "Kick a user session", + module = ?MODULE, function = kick_session, + args = [{user, string}, {host, string}, {resource, string}, {reason, string}], + result = {res, rescode}}, + #ejabberd_commands{name = status_num_host, tags = [session, stats], + desc = "Number of logged users with this status in host", + module = ?MODULE, function = status_num, + args = [{host, string}, {status, string}], + result = {users, integer}}, + #ejabberd_commands{name = status_num, tags = [session, stats], + desc = "Number of logged users with this status", + module = ?MODULE, function = status_num, + args = [{status, string}], + result = {users, integer}}, + #ejabberd_commands{name = status_list_host, tags = [session], + desc = "List of users logged in host with their statuses", + module = ?MODULE, function = status_list, + args = [{host, string}, {status, string}], + result = {users, {list, + {userstatus, {tuple, [ + {user, string}, + {host, string}, + {resource, string}, + {priority, integer}, + {status, string} + ]}} + }}}, + #ejabberd_commands{name = status_list, tags = [session], + desc = "List of logged users with this status", + module = ?MODULE, function = status_list, + args = [{status, string}], + result = {users, {list, + {userstatus, {tuple, [ + {user, string}, + {host, string}, + {resource, string}, + {priority, integer}, + {status, string} + ]}} + }}}, + #ejabberd_commands{name = connected_users_info, + tags = [session], + desc = "List all established sessions and their information", + module = ?MODULE, function = connected_users_info, + args = [], + result = {connected_users_info, + {list, + {sessions, {tuple, + [{jid, string}, + {connection, string}, + {ip, string}, + {port, integer}, + {priority, integer}, + {node, string}, + {uptime, integer} + ]}} + }}}, + #ejabberd_commands{name = connected_users_vhost, + tags = [session], + desc = "Get the list of established sessions in a vhost", + module = ?MODULE, function = connected_users_vhost, + args = [{host, string}], + result = {connected_users_vhost, {list, {sessions, string}}}}, + #ejabberd_commands{name = user_sessions_info, + tags = [session], + desc = "Get information about all sessions of a user", + module = ?MODULE, function = user_sessions_info, + args = [{user, string}, {host, string}], + result = {sessions_info, + {list, + {session, {tuple, + [{connection, string}, + {ip, string}, + {port, integer}, + {priority, integer}, + {node, string}, + {uptime, integer}, + {status, string}, + {resource, string}, + {statustext, string} + ]}} + }}}, + + #ejabberd_commands{name = set_presence, + tags = [session], + desc = "Set presence of a session", + module = ?MODULE, function = set_presence, + args = [{user, string}, {host, string}, + {resource, string}, {type, string}, + {show, string}, {status, string}, + {priority, string}], + result = {res, rescode}}, + + #ejabberd_commands{name = set_nickname, tags = [vcard], + desc = "Set nickname in a user's vCard", + module = ?MODULE, function = set_nickname, + args = [{user, string}, {host, string}, {nickname, string}], + result = {res, rescode}}, + + #ejabberd_commands{name = get_vcard, tags = [vcard], + desc = "Get content from a vCard field", + longdesc = Vcard1FieldsString ++ "\n" ++ Vcard2FieldsString ++ "\n\n" ++ VcardXEP, + module = ?MODULE, function = get_vcard, + args = [{user, string}, {host, string}, {name, string}], + result = {content, string}}, + #ejabberd_commands{name = get_vcard2, tags = [vcard], + desc = "Get content from a vCard field", + longdesc = Vcard2FieldsString ++ "\n\n" ++ Vcard1FieldsString ++ "\n" ++ VcardXEP, + module = ?MODULE, function = get_vcard, + args = [{user, string}, {host, string}, {name, string}, {subname, string}], + result = {content, string}}, + #ejabberd_commands{name = get_vcard2_multi, tags = [vcard], + desc = "Get multiple contents from a vCard field (requires exmpp installed)", + longdesc = Vcard2FieldsString ++ "\n\n" ++ Vcard1FieldsString ++ "\n" ++ VcardXEP, + module = ?MODULE, function = get_vcard_multi, + args = [{user, string}, {host, string}, {name, string}, {subname, string}], + result = {contents, {list, string}}}, + + #ejabberd_commands{name = set_vcard, tags = [vcard], + desc = "Set content in a vCard field", + longdesc = Vcard1FieldsString ++ "\n" ++ Vcard2FieldsString ++ "\n\n" ++ VcardXEP, + module = ?MODULE, function = set_vcard, + args = [{user, string}, {host, string}, {name, string}, {content, string}], + result = {res, rescode}}, + #ejabberd_commands{name = set_vcard2, tags = [vcard], + desc = "Set content in a vCard subfield", + longdesc = Vcard2FieldsString ++ "\n\n" ++ Vcard1FieldsString ++ "\n" ++ VcardXEP, + module = ?MODULE, function = set_vcard, + args = [{user, string}, {host, string}, {name, string}, {subname, string}, {content, string}], + result = {res, rescode}}, + #ejabberd_commands{name = set_vcard2_multi, tags = [vcard], + desc = "Set multiple contents in a vCard subfield", + longdesc = Vcard2FieldsString ++ "\n\n" ++ Vcard1FieldsString ++ "\n" ++ VcardXEP, + module = ?MODULE, function = set_vcard, + args = [{user, string}, {host, string}, {name, string}, {subname, string}, {contents, {list, string}}], + result = {res, rescode}}, + + #ejabberd_commands{name = add_rosteritem, tags = [roster], + desc = "Add an item to a user's roster (supports ODBC)", + module = ?MODULE, function = add_rosteritem, + args = [{localuser, string}, {localserver, string}, + {user, string}, {server, string}, + {nick, string}, {group, string}, + {subs, string}], + result = {res, rescode}}, + %%{"", "subs= none, from, to or both"}, + %%{"", "example: add-roster peter localhost mike server.com MiKe Employees both"}, + %%{"", "will add mike@server.com to peter@localhost roster"}, + #ejabberd_commands{name = delete_rosteritem, tags = [roster], + desc = "Delete an item from a user's roster (supports ODBC)", + module = ?MODULE, function = delete_rosteritem, + args = [{localuser, string}, {localserver, string}, + {user, string}, {server, string}], + result = {res, rescode}}, + #ejabberd_commands{name = process_rosteritems, tags = [roster], + desc = "List or delete rosteritems that match filtering options", + longdesc = "Explanation of each argument:\n" + " - action: what to do with each rosteritem that " + "matches all the filtering options\n" + " - subs: subscription type\n" + " - asks: pending subscription\n" + " - users: the JIDs of the local user\n" + " - contacts: the JIDs of the contact in the roster\n" + "\n" + "Allowed values in the arguments:\n" + " ACTION = list | delete\n" + " SUBS = SUB[:SUB]* | any\n" + " SUB = none | from | to | both\n" + " ASKS = ASK[:ASK]* | any\n" + " ASK = none | out | in\n" + " USERS = JID[:JID]* | any\n" + " CONTACTS = JID[:JID]* | any\n" + " JID = characters valid in a JID, and can use the " + "globs: *, ?, ! and [...]\n" + "\n" + "This example will list roster items with subscription " + "'none', 'from' or 'to' that have any ask property, of " + "local users which JID is in the virtual host " + "'example.org' and that the contact JID is either a " + "bare server name (without user part) or that has a " + "user part and the server part contains the word 'icq'" + ":\n list none:from:to any *@example.org *:*@*icq*", + module = ?MODULE, function = process_rosteritems, + args = [{action, string}, {subs, string}, + {asks, string}, {users, string}, + {contacts, string}], + result = {res, rescode}}, + #ejabberd_commands{name = get_roster, tags = [roster], + desc = "Get roster of a local user", + module = ?MODULE, function = get_roster, + args = [{user, string}, {host, string}], + result = {contacts, {list, {contact, {tuple, [ + {jid, string}, + {nick, string}, + {subscription, string}, + {ask, string}, + {group, string} + ]}}}}}, + #ejabberd_commands{name = push_roster, tags = [roster], + desc = "Push template roster from file to a user", + module = ?MODULE, function = push_roster, + args = [{file, string}, {user, string}, {host, string}], + result = {res, rescode}}, + #ejabberd_commands{name = push_roster_all, tags = [roster], + desc = "Push template roster from file to all those users", + module = ?MODULE, function = push_roster_all, + args = [{file, string}], + result = {res, rescode}}, + #ejabberd_commands{name = push_alltoall, tags = [roster], + desc = "Add all the users to all the users of Host in Group", + module = ?MODULE, function = push_alltoall, + args = [{host, string}, {group, string}], + result = {res, rescode}}, + + #ejabberd_commands{name = set_last, tags = [last], + desc = "Set last activity information", + longdesc = "Timestamp is the seconds since" + "1970-01-01 00:00:00 UTC, for example: date +%s", + module = ?MODULE, function = set_last, + args = [{user, string}, {host, string}, {timestamp, integer}, {status, string}], + result = {res, rescode}}, + + #ejabberd_commands{name = private_get, tags = [private], + desc = "Get some information from a user private storage", + module = ?MODULE, function = private_get, + args = [{user, string}, {host, string}, {element, string}, {ns, string}], + result = {res, string}}, + #ejabberd_commands{name = private_set, tags = [private], + desc = "Set to the user private storage", + module = ?MODULE, function = private_set, + args = [{user, string}, {host, string}, {element, string}], + result = {res, rescode}}, + + #ejabberd_commands{name = srg_create, tags = [shared_roster_group], + desc = "Create a Shared Roster Group", + longdesc = "If you want to specify several group " + "identifiers in the Display argument,\n" + "put \\ \" around the argument and\nseparate the " + "identifiers with \\ \\ n\n" + "For example:\n" + " ejabberdctl srg_create group3 localhost " + "name desc \\\"group1\\\\ngroup2\\\"", + module = ?MODULE, function = srg_create, + args = [{group, string}, {host, string}, + {name, string}, {description, string}, {display, string}], + result = {res, rescode}}, + #ejabberd_commands{name = srg_delete, tags = [shared_roster_group], + desc = "Delete a Shared Roster Group", + module = ?MODULE, function = srg_delete, + args = [{group, string}, {host, string}], + result = {res, rescode}}, + #ejabberd_commands{name = srg_list, tags = [shared_roster_group], + desc = "List the Shared Roster Groups in Host", + module = ?MODULE, function = srg_list, + args = [{host, string}], + result = {groups, {list, {id, string}}}}, + #ejabberd_commands{name = srg_get_info, tags = [shared_roster_group], + desc = "Get info of a Shared Roster Group", + module = ?MODULE, function = srg_get_info, + args = [{group, string}, {host, string}], + result = {informations, {list, {information, {tuple, [{key, string}, {value, string}]}}}}}, + #ejabberd_commands{name = srg_get_members, tags = [shared_roster_group], + desc = "Get members of a Shared Roster Group", + module = ?MODULE, function = srg_get_members, + args = [{group, string}, {host, string}], + result = {members, {list, {member, string}}}}, + #ejabberd_commands{name = srg_user_add, tags = [shared_roster_group], + desc = "Add the JID user@host to the Shared Roster Group", + module = ?MODULE, function = srg_user_add, + args = [{user, string}, {host, string}, {group, string}, {grouphost, string}], + result = {res, rescode}}, + #ejabberd_commands{name = srg_user_del, tags = [shared_roster_group], + desc = "Delete this JID user@host from the Shared Roster Group", + module = ?MODULE, function = srg_user_del, + args = [{user, string}, {host, string}, {group, string}, {grouphost, string}], + result = {res, rescode}}, + + #ejabberd_commands{name = send_message_chat, tags = [stanza], + desc = "Send a chat message to a local or remote bare of full JID", + module = ?MODULE, function = send_message_chat, + args = [{from, string}, {to, string}, {body, string}], + result = {res, rescode}}, + #ejabberd_commands{name = send_message_headline, tags = [stanza], + desc = "Send a headline message to a local or remote bare of full JID", + module = ?MODULE, function = send_message_headline, + args = [{from, string}, {to, string}, + {subject, string}, {body, string}], + result = {res, rescode}}, + #ejabberd_commands{name = send_stanza_c2s, tags = [stanza], + desc = "Send a stanza as if sent from a c2s session", + module = ?MODULE, function = send_stanza_c2s, + args = [{user, string}, {host, string}, {resource, string}, {stanza, string}], + result = {res, rescode}}, + #ejabberd_commands{name = privacy_set, tags = [stanza], + desc = "Send a IQ set privacy stanza for a local account", + module = ?MODULE, function = privacy_set, + args = [{user, string}, {host, string}, {xmlquery, string}], + result = {res, rescode}}, + + #ejabberd_commands{name = stats, tags = [stats], + desc = "Get statistical value: registeredusers onlineusers onlineusersnode uptimeseconds", + module = ?MODULE, function = stats, + args = [{name, string}], + result = {stat, integer}}, + #ejabberd_commands{name = stats_host, tags = [stats], + desc = "Get statistical value for this host: registeredusers onlineusers", + module = ?MODULE, function = stats, + args = [{name, string}, {host, string}], + result = {stat, integer}} + ]. + + +%%% +%%% Node +%%% + +compile(File) -> + case compile:file(File) of + ok -> ok; + _ -> error + end. + +load_config(Path) -> + ok = ejabberd_config:load_file(Path). + +get_cookie() -> + atom_to_list(erlang:get_cookie()). + +remove_node(Node) -> + mnesia:del_table_copy(schema, list_to_atom(Node)), + ok. + +export2odbc(Host, Directory) -> + Tables = [ + {export_last, last}, + {export_offline, offline}, + {export_passwd, passwd}, + {export_private_storage, private_storage}, + {export_roster, roster}, + {export_vcard, vcard}, + {export_vcard_search, vcard_search}], + Export = fun({TableFun, Table}) -> + Filename = filename:join([Directory, atom_to_list(Table)++".txt"]), + io:format("Trying to export Mnesia table '~p' on Host '~s' to file '~s'~n", [Table, Host, Filename]), + Res = (catch ejd2odbc:TableFun(Host, Filename)), + io:format(" Result: ~p~n", [Res]) + end, + lists:foreach(Export, Tables), + ok. + + +%%% +%%% Accounts +%%% + +set_password(User, Host, Password) -> + case ejabberd_auth:set_password(User, Host, Password) of + ok -> + ok; + _ -> + error + end. + +%% Copied some code from ejabberd_commands.erl +check_password_hash(User, Host, PasswordHash, HashMethod) -> + AccountPass = ejabberd_auth:get_password_s(User, Host), + AccountPassHash = case HashMethod of + "md5" -> get_md5(AccountPass); + "sha" -> get_sha(AccountPass); + _ -> undefined + end, + case AccountPassHash of + undefined -> error; + PasswordHash -> ok; + _ -> error + end. +get_md5(AccountPass) -> + lists:flatten([io_lib:format("~.16B", [X]) + || X <- binary_to_list(crypto:md5(AccountPass))]). +get_sha(AccountPass) -> + lists:flatten([io_lib:format("~.16B", [X]) + || X <- binary_to_list(crypto:sha(AccountPass))]). + +num_active_users(Host, Days) -> + list_last_activity(Host, true, Days). + +%% Code based on ejabberd/src/web/ejabberd_web_admin.erl +list_last_activity(Host, Integral, Days) -> + {MegaSecs, Secs, _MicroSecs} = now(), + TimeStamp = MegaSecs * 1000000 + Secs, + TS = TimeStamp - Days * 86400, + case catch mnesia:dirty_select( + last_activity, [{{last_activity, {'_', Host}, '$1', '_'}, + [{'>', '$1', TS}], + [{'trunc', {'/', + {'-', TimeStamp, '$1'}, + 86400}}]}]) of + {'EXIT', _Reason} -> + []; + Vals -> + Hist = histogram(Vals, Integral), + if + Hist == [] -> + 0; + true -> + Left = Days - length(Hist), + Tail = if + Integral -> + lists:duplicate(Left, lists:last(Hist)); + true -> + lists:duplicate(Left, 0) + end, + lists:nth(Days, Hist ++ Tail) + end + end. +histogram(Values, Integral) -> + histogram(lists:sort(Values), Integral, 0, 0, []). +histogram([H | T], Integral, Current, Count, Hist) when Current == H -> + histogram(T, Integral, Current, Count + 1, Hist); +histogram([H | _] = Values, Integral, Current, Count, Hist) when Current < H -> + if + Integral -> + histogram(Values, Integral, Current + 1, Count, [Count | Hist]); + true -> + histogram(Values, Integral, Current + 1, 0, [Count | Hist]) + end; +histogram([], _Integral, _Current, Count, Hist) -> + if + Count > 0 -> + lists:reverse([Count | Hist]); + true -> + lists:reverse(Hist) + end. + + +delete_old_users(Days) -> + %% Get the list of registered users + Users = ejabberd_auth:dirty_get_registered_users(), + + {removed, N, UR} = delete_old_users(Days, Users), + {ok, io_lib:format("Deleted ~p users: ~p", [N, UR])}. + +delete_old_users_vhost(Host, Days) -> + %% Get the list of registered users + Users = ejabberd_auth:get_vh_registered_users(Host), + + {removed, N, UR} = delete_old_users(Days, Users), + {ok, io_lib:format("Deleted ~p users: ~p", [N, UR])}. + +delete_old_users(Days, Users) -> + %% Convert older time + SecOlder = Days*24*60*60, + + %% Get current time + {MegaSecs, Secs, _MicroSecs} = now(), + TimeStamp_now = MegaSecs * 1000000 + Secs, + + %% For a user, remove if required and answer true + F = fun({LUser, LServer}) -> + %% Check if the user is logged + case ejabberd_sm:get_user_resources(LUser, LServer) of + %% If it isnt + [] -> + %% Look for his last_activity + case (get_lastactivity_module(LServer)):get_last_info(LUser, LServer) of + %% If it is + %% existent: + {ok, TimeStamp, _Status} -> + %% get his age + Sec = TimeStamp_now - TimeStamp, + %% If he is + if + %% younger than SecOlder: + Sec < SecOlder -> + %% do nothing + false; + %% older: + true -> + %% remove the user + ejabberd_auth:remove_user(LUser, LServer), + true + end; + %% nonexistent: + not_found -> + %% remove the user + ejabberd_auth:remove_user(LUser, LServer), + true + end; + %% Else + _ -> + %% do nothing + false + end + end, + %% Apply the function to every user in the list + Users_removed = lists:filter(F, Users), + {removed, length(Users_removed), Users_removed}. + +get_lastactivity_module(Server) -> + case lists:member(mod_last, gen_mod:loaded_modules(Server)) of + true -> mod_last; + _ -> mod_last_odbc + end. + + +%% +%% Ban account + +ban_account(User, Host, ReasonText) -> + Reason = prepare_reason(ReasonText), + kick_sessions(User, Host, Reason), + set_random_password(User, Host, Reason), + ok. + +kick_sessions(User, Server, Reason) -> + lists:map( + fun(Resource) -> + kick_this_session(User, Server, Resource, Reason) + end, + get_resources(User, Server)). + +get_resources(User, Server) -> + lists:map( + fun(Session) -> + element(3, Session#session.usr) + end, + get_sessions(User, Server)). + +get_sessions(User, Server) -> + LUser = jlib:nodeprep(User), + LServer = jlib:nameprep(Server), + Sessions = mnesia:dirty_index_read(session, {LUser, LServer}, #session.us), + true = is_list(Sessions), + Sessions. + +set_random_password(User, Server, Reason) -> + NewPass = build_random_password(Reason), + set_password_auth(User, Server, NewPass). + +build_random_password(Reason) -> + Date = jlib:timestamp_to_iso(calendar:universal_time()), + RandomString = randoms:get_string(), + "BANNED_ACCOUNT--" ++ Date ++ "--" ++ RandomString ++ "--" ++ Reason. + +set_password_auth(User, Server, Password) -> + ok = ejabberd_auth:set_password(User, Server, Password). + +prepare_reason([]) -> + "Kicked by administrator"; +prepare_reason([Reason]) -> + Reason; +prepare_reason(Reason) when is_list(Reason) -> + Reason; +prepare_reason(StringList) -> + string:join(StringList, "_"). + + +%%% +%%% Sessions +%%% + +num_resources(User, Host) -> + length(ejabberd_sm:get_user_resources(User, Host)). + +resource_num(User, Host, Num) -> + Resources = ejabberd_sm:get_user_resources(User, Host), + case (0 + lists:nth(Num, Resources); + false -> + lists:flatten(io_lib:format("Error: Wrong resource number: ~p", [Num])) + end. + +kick_session(User, Server, Resource, ReasonText) -> + kick_this_session(User, Server, Resource, prepare_reason(ReasonText)), + ok. + +kick_this_session(User, Server, Resource, Reason) -> + ejabberd_router:route( + jlib:make_jid("", "", ""), + jlib:make_jid(User, Server, Resource), + {xmlelement, "broadcast", [], [{exit, Reason}]}). + + +status_num(Host, Status) -> + length(get_status_list(Host, Status)). +status_num(Status) -> + status_num("all", Status). +status_list(Host, Status) -> + Res = get_status_list(Host, Status), + [{U, S, R, P, St} || {U, S, R, P, St} <- Res]. +status_list(Status) -> + status_list("all", Status). + + +get_status_list(Host, Status_required) -> + %% Get list of all logged users + Sessions = ejabberd_sm:dirty_get_my_sessions_list(), + %% Reformat the list + Sessions2 = [ {Session#session.usr, Session#session.sid, Session#session.priority} || Session <- Sessions], + Fhost = case Host of + "all" -> + %% All hosts are requested, so dont filter at all + fun(_, _) -> true end; + _ -> + %% Filter the list, only Host is interesting + fun(A, B) -> A == B end + end, + Sessions3 = [ {Pid, Server, Priority} || {{_User, Server, _Resource}, {_, Pid}, Priority} <- Sessions2, apply(Fhost, [Server, Host])], + %% For each Pid, get its presence + Sessions4 = [ {ejabberd_c2s:get_presence(Pid), Server, Priority} || {Pid, Server, Priority} <- Sessions3], + %% Filter by status + Fstatus = case Status_required of + "all" -> + fun(_, _) -> true end; + _ -> + fun(A, B) -> A == B end + end, + [{User, Server, Resource, Priority, stringize(Status_text)} + || {{User, Resource, Status, Status_text}, Server, Priority} <- Sessions4, + apply(Fstatus, [Status, Status_required])]. + +connected_users_info() -> + USRIs = dirty_get_sessions_list2(), + CurrentSec = calendar:datetime_to_gregorian_seconds({date(), time()}), + lists:map( + fun([{U, S, R}, {Now, Pid}, Priority, Info]) -> + Conn = proplists:get_value(conn, Info), + {Ip, Port} = proplists:get_value(ip, Info), + IPS = inet_parse:ntoa(Ip), + NodeS = atom_to_list(node(Pid)), + Uptime = CurrentSec - calendar:datetime_to_gregorian_seconds( + calendar:now_to_local_time(Now)), + {[U, $@, S, $/, R], atom_to_list(Conn), IPS, Port, Priority, NodeS, Uptime} + end, + USRIs). + +connected_users_vhost(Host) -> + USRs = ejabberd_sm:get_vh_session_list(Host), + [ [U, $@, S, $/, R] || {U, S, R} <- USRs]. + +%% Code copied from ejabberd_sm.erl and customized +dirty_get_sessions_list2() -> + mnesia:dirty_select( + session, + [{#session{usr = '$1', sid = '$2', priority = '$3', info = '$4', _ = '_'}, + [], + [['$1', '$2', '$3', '$4']]}]). + +%% Make string more print-friendly +stringize(String) -> + %% Replace newline characters with other code + ejabberd_regexp:greplace(String, "\n", "\\n"). + +set_presence(User, Host, Resource, Type, Show, Status, Priority) -> + Pid = ejabberd_sm:get_session_pid(User, Host, Resource), + USR = User ++ "@" ++ Host ++ "/" ++ Resource, + US = User ++ "@" ++ Host, + Message = {route_xmlstreamelement, + {xmlelement, "presence", + [{"from", USR}, {"to", US}, {"type", Type}], + [{xmlelement, "show", [], [{xmlcdata, Show}]}, + {xmlelement, "status", [], [{xmlcdata, Status}]}, + {xmlelement, "priority", [], [{xmlcdata, Priority}]}]}}, + Pid ! Message. + +user_sessions_info(User, Host) -> + CurrentSec = calendar:datetime_to_gregorian_seconds({date(), time()}), + US = {User, Host}, + Sessions = case catch mnesia:dirty_index_read(session, US, #session.us) of + {'EXIT', _Reason} -> + []; + Ss -> + Ss + end, + lists:map( + fun(Session) -> + {_U, _S, Resource} = Session#session.usr, + {Now, Pid} = Session#session.sid, + {_U, _Resource, Status, StatusText} = ejabberd_c2s:get_presence(Pid), + Info = Session#session.info, + Priority = Session#session.priority, + Conn = proplists:get_value(conn, Info), + {Ip, Port} = proplists:get_value(ip, Info), + IPS = inet_parse:ntoa(Ip), + NodeS = atom_to_list(node(Pid)), + Uptime = CurrentSec - calendar:datetime_to_gregorian_seconds( + calendar:now_to_local_time(Now)), + {atom_to_list(Conn), IPS, Port, Priority, NodeS, Uptime, Status, Resource, StatusText} + end, + Sessions). + + +%%% +%%% Vcard +%%% + +set_nickname(User, Host, Nickname) -> + R = mod_vcard:process_sm_iq( + {jid, User, Host, "", User, Host, ""}, + {jid, User, Host, "", User, Host, ""}, + {iq, "", set, "", "en", + {xmlelement, "vCard", + [{"xmlns", "vcard-temp"}], [ + {xmlelement, "NICKNAME", [], [{xmlcdata, Nickname}]} + ] + }}), + case R of + {iq, [], result, [], _L, []} -> + ok; + _ -> + error + end. + +get_vcard(User, Host, Name) -> + [Res | _] = get_vcard_content(User, Host, [Name]), + Res. + +get_vcard(User, Host, Name, Subname) -> + [Res | _] = get_vcard_content(User, Host, [Name, Subname]), + Res. + +get_vcard_multi(User, Host, Name, Subname) -> + get_vcard_content(User, Host, [Name, Subname]). + +set_vcard(User, Host, Name, SomeContent) -> + set_vcard_content(User, Host, [Name], SomeContent). + +set_vcard(User, Host, Name, Subname, SomeContent) -> + set_vcard_content(User, Host, [Name, Subname], SomeContent). + + +%% +%% Internal vcard + +get_module_resource(Server) -> + case gen_mod:get_module_opt(Server, ?MODULE, module_resource, none) of + none -> atom_to_list(?MODULE); + R when is_list(R) -> R + end. + +get_vcard_content(User, Server, Data) -> + [{_, Module, Function, _Opts}] = ets:lookup(sm_iqtable, {?NS_VCARD, Server}), + JID = jlib:make_jid(User, Server, get_module_resource(Server)), + IQ = #iq{type = get, xmlns = ?NS_VCARD}, + IQr = Module:Function(JID, JID, IQ), + case IQr#iq.sub_el of + [A1] -> + case get_vcard(Data, A1) of + [] -> throw(error_no_value_found_in_vcard); + ElemList -> [xml:get_tag_cdata(Elem) || Elem <- ElemList] + end; + [] -> + throw(error_no_vcard_found) + end. + +get_vcard([Data1, Data2], A1) -> + case get_subtag(A1, Data1) of + false -> false; + A2List -> lists:flatten([get_vcard([Data2], A2) || A2 <- A2List]) + end; + +get_vcard([Data], A1) -> + get_subtag(A1, Data). + +get_subtag(Xmlelement, Name) -> + case code:ensure_loaded(exmpp_xml) of + {error, _} -> + [get_subtag_xml(Xmlelement, Name)]; + {module, exmpp_xml} -> + get_subtag_exmpp(Xmlelement, Name) + end. + +get_subtag_xml(Xmlelement, Name) -> + xml:get_subtag(Xmlelement, Name). + +get_subtag_exmpp(Xmlelement, Name) -> + Xmlel = exmpp_xml:xmlelement_to_xmlel(Xmlelement), + XmlelList = exmpp_xml:get_elements(Xmlel, Name), + [exmpp_xml:xmlel_to_xmlelement(Xmlel2) || Xmlel2 <- XmlelList]. + +set_vcard_content(User, Server, Data, SomeContent) -> + ContentList = case SomeContent of + [Char | _] when not is_list(Char) -> [SomeContent]; + [Char | _] when is_list(Char) -> SomeContent + end, + [{_, Module, Function, _Opts}] = ets:lookup(sm_iqtable, {?NS_VCARD, Server}), + JID = jlib:make_jid(User, Server, get_module_resource(Server)), + IQ = #iq{type = get, xmlns = ?NS_VCARD}, + IQr = Module:Function(JID, JID, IQ), + + %% Get old vcard + A4 = case IQr#iq.sub_el of + [A1] -> + {_, _, _, A2} = A1, + update_vcard_els(Data, ContentList, A2); + [] -> + update_vcard_els(Data, ContentList, []) + end, + + %% Build new vcard + SubEl = {xmlelement, "vCard", [{"xmlns","vcard-temp"}], A4}, + IQ2 = #iq{type=set, sub_el = SubEl}, + + Module:Function(JID, JID, IQ2), + ok. + +update_vcard_els(Data, ContentList, Els1) -> + Els2 = lists:keysort(2, Els1), + [Data1 | Data2] = Data, + NewEls = case Data2 of + [] -> + [{xmlelement, Data1, [], [{xmlcdata,Content}]} || Content <- ContentList]; + [D2] -> + OldEl = case lists:keysearch(Data1, 2, Els2) of + {value, A} -> A; + false -> {xmlelement, Data1, [], []} + end, + {xmlelement, _, _, ContentOld1} = OldEl, + Content2 = [{xmlelement, D2, [], [{xmlcdata,Content}]} || Content <- ContentList], + ContentOld2 = [A || {_, X, _, _} = A <- ContentOld1, X/=D2], + ContentOld3 = lists:keysort(2, ContentOld2), + ContentNew = lists:keymerge(2, Content2, ContentOld3), + [{xmlelement, Data1, [], ContentNew}] + end, + Els3 = lists:keydelete(Data1, 2, Els2), + lists:keymerge(2, NewEls, Els3). + + +%%% +%%% Roster +%%% + +add_rosteritem(LocalUser, LocalServer, User, Server, Nick, Group, Subs) -> + case add_rosteritem(LocalUser, LocalServer, User, Server, Nick, Group, list_to_atom(Subs), []) of + {atomic, ok} -> + push_roster_item(LocalUser, LocalServer, User, Server, {add, Nick, Subs, Group}), + ok; + _ -> + error + end. + +add_rosteritem(LU, LS, User, Server, Nick, Group, Subscription, Xattrs) -> + subscribe(LU, LS, User, Server, Nick, Group, Subscription, Xattrs). + +subscribe(LU, LS, User, Server, Nick, Group, Subscription, _Xattrs) -> + SubscriptionS = case is_atom(Subscription) of + true -> atom_to_list(Subscription); + false -> Subscription + end, + ItemEl = build_roster_item(User, Server, {add, Nick, SubscriptionS, Group}), + {ok, M} = loaded_module(LS,[mod_roster_odbc,mod_roster]), + M:set_items( + LU, LS, + {xmlelement,"query", + [{"xmlns","jabber:iq:roster"}], + [ItemEl]}). + +delete_rosteritem(LocalUser, LocalServer, User, Server) -> + case unsubscribe(LocalUser, LocalServer, User, Server) of + {atomic, ok} -> + push_roster_item(LocalUser, LocalServer, User, Server, remove), + ok; + _ -> + error + end. + +unsubscribe(LU, LS, User, Server) -> + ItemEl = build_roster_item(User, Server, remove), + {ok, M} = loaded_module(LS,[mod_roster_odbc,mod_roster]), + M:set_items( + LU, LS, + {xmlelement,"query", + [{"xmlns","jabber:iq:roster"}], + [ItemEl]}). + +loaded_module(Domain,Options) -> + LoadedModules = gen_mod:loaded_modules(Domain), + case lists:filter(fun(Module) -> + lists:member(Module, LoadedModules) + end, Options) of + [M|_] -> {ok, M}; + [] -> {error,not_found} + end. + +%% ----------------------------- +%% Get Roster +%% ----------------------------- + +get_roster(User, Server) -> + Items = ejabberd_hooks:run_fold(roster_get, Server, [], [{User, Server}]), + make_roster_xmlrpc(Items). + +%% Note: if a contact is in several groups, the contact is returned +%% several times, each one in a different group. +make_roster_xmlrpc(Roster) -> + lists:foldl( + fun(Item, Res) -> + JIDS = jlib:jid_to_string(Item#roster.jid), + Nick = Item#roster.name, + Subs = atom_to_list(Item#roster.subscription), + Ask = atom_to_list(Item#roster.ask), + Groups = case Item#roster.groups of + [] -> [""]; + Gs -> Gs + end, + ItemsX = [{JIDS, Nick, Subs, Ask, Group} + || Group <- Groups], + ItemsX ++ Res + end, + [], + Roster). + + +%%----------------------------- +%% Push Roster from file +%%----------------------------- + +push_roster(File, User, Server) -> + {ok, [Roster]} = file:consult(File), + subscribe_roster({User, Server, "", User}, Roster). + +push_roster_all(File) -> + {ok, [Roster]} = file:consult(File), + subscribe_all(Roster). + +subscribe_all(Roster) -> + subscribe_all(Roster, Roster). +subscribe_all([], _) -> + ok; +subscribe_all([User1 | Users], Roster) -> + subscribe_roster(User1, Roster), + subscribe_all(Users, Roster). + +subscribe_roster(_, []) -> + ok; +%% Do not subscribe a user to itself +subscribe_roster({Name, Server, Group, Nick}, [{Name, Server, _, _} | Roster]) -> + subscribe_roster({Name, Server, Group, Nick}, Roster); +%% Subscribe Name2 to Name1 +subscribe_roster({Name1, Server1, Group1, Nick1}, [{Name2, Server2, Group2, Nick2} | Roster]) -> + subscribe(Name1, Server1, Name2, Server2, Nick2, Group2, both, []), + subscribe_roster({Name1, Server1, Group1, Nick1}, Roster). + +push_alltoall(S, G) -> + Users = ejabberd_auth:get_vh_registered_users(S), + Users2 = build_list_users(G, Users, []), + subscribe_all(Users2), + ok. + +build_list_users(_Group, [], Res) -> + Res; +build_list_users(Group, [{User, Server}|Users], Res) -> + build_list_users(Group, Users, [{User, Server, Group, User}|Res]). + +%% @spec(LU, LS, U, S, Action) -> ok +%% Action = {add, Nick, Subs, Group} | remove +%% @doc Push to the roster of account LU@LS the contact U@S. +%% The specific action to perform is defined in Action. +push_roster_item(LU, LS, U, S, Action) -> + lists:foreach(fun(R) -> + push_roster_item(LU, LS, R, U, S, Action) + end, ejabberd_sm:get_user_resources(LU, LS)). + +push_roster_item(LU, LS, R, U, S, Action) -> + LJID = jlib:make_jid(LU, LS, R), + BroadcastEl = build_broadcast(U, S, Action), + ejabberd_router:route(LJID, LJID, BroadcastEl), + Item = build_roster_item(U, S, Action), + ResIQ = build_iq_roster_push(Item), + ejabberd_router:route(LJID, LJID, ResIQ). + +build_roster_item(U, S, {add, Nick, Subs, Group}) -> + {xmlelement, "item", + [{"jid", jlib:jid_to_string(jlib:make_jid(U, S, ""))}, + {"name", Nick}, + {"subscription", Subs}], + [{xmlelement, "group", [], [{xmlcdata, Group}]}] + }; +build_roster_item(U, S, remove) -> + {xmlelement, "item", + [{"jid", jlib:jid_to_string(jlib:make_jid(U, S, ""))}, + {"subscription", "remove"}], + [] + }. + +build_iq_roster_push(Item) -> + {xmlelement, "iq", + [{"type", "set"}, {"id", "push"}], + [{xmlelement, "query", + [{"xmlns", ?NS_ROSTER}], + [Item] + } + ] + }. + +build_broadcast(U, S, {add, _Nick, Subs, _Group}) -> + build_broadcast(U, S, list_to_atom(Subs)); +build_broadcast(U, S, remove) -> + build_broadcast(U, S, none); +%% @spec (U::string(), S::string(), Subs::atom()) -> any() +%% Subs = both | from | to | none +build_broadcast(U, S, SubsAtom) when is_atom(SubsAtom) -> + {xmlelement, "broadcast", [], + [{item, {U, S, ""}, SubsAtom}] + }. + +%%% +%%% Last Activity +%%% + +set_last(User, Server, Timestamp, Status) -> + Mod = get_lastactivity_module(Server), + Mod:store_last_info(User, Server, Timestamp, Status). + +%%% +%%% Private Storage +%%% + +%% Example usage: +%% $ ejabberdctl private_set badlop localhost "\Cluth\" +%% $ ejabberdctl private_get badlop localhost aa bb +%% Cluth + +private_get(Username, Host, Element, Ns) -> + From = jlib:make_jid(Username, Host, ""), + To = jlib:make_jid(Username, Host, ""), + IQ = {iq, "", get, ?NS_PRIVATE, "", + {xmlelement,"query", + [{"xmlns",?NS_PRIVATE}], + [{xmlelement, Element, [{"xmlns", Ns}], []}]}}, + ResIq = mod_private:process_sm_iq(From, To, IQ), + [{xmlelement,"query", + [{"xmlns","jabber:iq:private"}], + [SubEl]}] = ResIq#iq.sub_el, + xml:element_to_string(SubEl). + +private_set(Username, Host, ElementString) -> + case xml_stream:parse_element(ElementString) of + {error, Error} -> + io:format("Error found parsing the element:~n ~p~nError: ~p~n", + [ElementString, Error]), + error; + Xml -> + private_set2(Username, Host, Xml) + end. + +private_set2(Username, Host, Xml) -> + From = jlib:make_jid(Username, Host, ""), + To = jlib:make_jid(Username, Host, ""), + IQ = {iq, "", set, ?NS_PRIVATE, "", + {xmlelement,"query", + [{"xmlns",?NS_PRIVATE}], + [Xml]}}, + mod_private:process_sm_iq(From, To, IQ), + ok. + +%%% +%%% Shared Roster Groups +%%% + +srg_create(Group, Host, Name, Description, Display) -> + DisplayList = case Display of + [] -> []; + _ -> ejabberd_regexp:split(Display, "\\\\n") + end, + Opts = [{name, Name}, + {displayed_groups, DisplayList}, + {description, Description}], + {atomic, ok} = mod_shared_roster:create_group(Host, Group, Opts), + ok. + +srg_delete(Group, Host) -> + {atomic, ok} = mod_shared_roster:delete_group(Host, Group), + ok. + +srg_list(Host) -> + lists:sort(mod_shared_roster:list_groups(Host)). + +srg_get_info(Group, Host) -> + Opts = mod_shared_roster:get_group_opts(Host,Group), + [{io_lib:format("~p", [Title]), + io_lib:format("~p", [Value])} || {Title, Value} <- Opts]. + +srg_get_members(Group, Host) -> + Members = mod_shared_roster:get_group_explicit_users(Host,Group), + [jlib:jid_to_string(jlib:make_jid(MUser, MServer, "")) + || {MUser, MServer} <- Members]. + +srg_user_add(User, Host, Group, GroupHost) -> + {atomic, ok} = mod_shared_roster:add_user_to_group(GroupHost, {User, Host}, Group), + ok. + +srg_user_del(User, Host, Group, GroupHost) -> + {atomic, ok} = mod_shared_roster:remove_user_from_group(GroupHost, {User, Host}, Group), + ok. + + +%%% +%%% Stanza +%%% + +%% @doc Send a chat message to a Jabber account. +%% @spec (From::string(), To::string(), Body::string()) -> ok +send_message_chat(From, To, Body) -> + Packet = build_packet(message_chat, [Body]), + send_packet_all_resources(From, To, Packet). + +%% @doc Send a headline message to a Jabber account. +%% @spec (From::string(), To::string(), Subject::string(), Body::string()) -> ok +send_message_headline(From, To, Subject, Body) -> + Packet = build_packet(message_headline, [Subject, Body]), + send_packet_all_resources(From, To, Packet). + +%% @doc Send a packet to a Jabber account. +%% If a resource was specified in the JID, +%% the packet is sent only to that specific resource. +%% If no resource was specified in the JID, +%% and the user is remote or local but offline, +%% the packet is sent to the bare JID. +%% If the user is local and is online in several resources, +%% the packet is sent to all its resources. +send_packet_all_resources(FromJIDString, ToJIDString, Packet) -> + FromJID = jlib:string_to_jid(FromJIDString), + ToJID = jlib:string_to_jid(ToJIDString), + ToUser = ToJID#jid.user, + ToServer = ToJID#jid.server, + case ToJID#jid.resource of + "" -> + send_packet_all_resources(FromJID, ToUser, ToServer, Packet); + Res -> + send_packet_all_resources(FromJID, ToUser, ToServer, Res, Packet) + end. + +send_packet_all_resources(FromJID, ToUser, ToServer, Packet) -> + case ejabberd_sm:get_user_resources(ToUser, ToServer) of + [] -> + send_packet_all_resources(FromJID, ToUser, ToServer, "", Packet); + ToResources -> + lists:foreach( + fun(ToResource) -> + send_packet_all_resources(FromJID, ToUser, ToServer, + ToResource, Packet) + end, + ToResources) + end. + +send_packet_all_resources(FromJID, ToU, ToS, ToR, Packet) -> + ToJID = jlib:make_jid(ToU, ToS, ToR), + ejabberd_router:route(FromJID, ToJID, Packet). + + +build_packet(message_chat, [Body]) -> + {xmlelement, "message", + [{"type", "chat"}, {"id", randoms:get_string()}], + [{xmlelement, "body", [], [{xmlcdata, Body}]}] + }; +build_packet(message_headline, [Subject, Body]) -> + {xmlelement, "message", + [{"type", "headline"}, {"id", randoms:get_string()}], + [{xmlelement, "subject", [], [{xmlcdata, Subject}]}, + {xmlelement, "body", [], [{xmlcdata, Body}]} + ] + }. + +send_stanza_c2s(Username, Host, Resource, Stanza) -> + C2sPid = ejabberd_sm:get_session_pid(Username, Host, Resource), + XmlEl = xml_stream:parse_element(Stanza), + p1_fsm:send_event(C2sPid, {xmlstreamelement, XmlEl}). + +privacy_set(Username, Host, QueryS) -> + From = jlib:string_to_jid(Username ++ "@" ++ Host), + To = jlib:string_to_jid(Host), + QueryEl = xml_stream:parse_element(QueryS), + StanzaEl = {xmlelement, "iq", [{"type", "set"}], [QueryEl]}, + IQ = jlib:iq_query_info(StanzaEl), + ejabberd_hooks:run_fold( + privacy_iq_set, + Host, + {error, ?ERR_FEATURE_NOT_IMPLEMENTED}, + [From, To, IQ] + ), + ok. + +%%% +%%% Stats +%%% + +stats(Name) -> + case Name of + "uptimeseconds" -> trunc(element(1, erlang:statistics(wall_clock))/1000); + "registeredusers" -> length(ejabberd_auth:dirty_get_registered_users()); + "onlineusersnode" -> length(ejabberd_sm:dirty_get_my_sessions_list()); + "onlineusers" -> length(ejabberd_sm:dirty_get_sessions_list()) + end. + +stats(Name, Host) -> + case Name of + "registeredusers" -> length(ejabberd_auth:get_vh_registered_users(Host)); + "onlineusers" -> length(ejabberd_sm:get_vh_session_list(Host)) + end. + + + +%%----------------------------- +%% Purge roster items +%%----------------------------- + +process_rosteritems(ActionS, SubsS, AsksS, UsersS, ContactsS) -> + Action = case ActionS of + "list" -> list; + "delete" -> delete + end, + + Subs = lists:foldl( + fun(any, _) -> [none, from, to, both]; + (Sub, Subs) -> [Sub | Subs] + end, + [], + [list_to_atom(S) || S <- string:tokens(SubsS, ":")] + ), + + Asks = lists:foldl( + fun(any, _) -> [none, out, in]; + (Ask, Asks) -> [Ask | Asks] + end, + [], + [list_to_atom(S) || S <- string:tokens(AsksS, ":")] + ), + + Users = lists:foldl( + fun("any", _) -> ["*", "*@*"]; + (U, Us) -> [U | Us] + end, + [], + [S || S <- string:tokens(UsersS, ":")] + ), + + Contacts = lists:foldl( + fun("any", _) -> ["*", "*@*"]; + (U, Us) -> [U | Us] + end, + [], + [S || S <- string:tokens(ContactsS, ":")] + ), + + case rosteritem_purge({Action, Subs, Asks, Users, Contacts}) of + {atomic, ok} -> + ok; + {error, Reason} -> + io:format("Error purging rosteritems: ~p~n", [Reason]), + error; + {badrpc, Reason} -> + io:format("BadRPC purging rosteritems: ~p~n", [Reason]), + error + end. + +%% @spec ({Action::atom(), Subs::[atom()], Asks::[atom()], User::string(), Contact::string()}) -> {atomic, ok} +rosteritem_purge(Options) -> + Num_rosteritems = mnesia:table_info(roster, size), + io:format("There are ~p roster items in total.~n", [Num_rosteritems]), + Key = mnesia:dirty_first(roster), + ok = rip(Key, Options, {0, Num_rosteritems, 0, 0}), + {atomic, ok}. + +rip('$end_of_table', _Options, Counters) -> + print_progress_line(Counters), + ok; +rip(Key, Options, {Pr, NT, NV, ND}) -> + Key_next = mnesia:dirty_next(roster, Key), + {Action, _, _, _, _} = Options, + ND2 = case decide_rip(Key, Options) of + true -> + apply_action(Action, Key), + ND+1; + false -> + ND + end, + NV2 = NV+1, + Pr2 = print_progress_line({Pr, NT, NV2, ND2}), + rip(Key_next, Options, {Pr2, NT, NV2, ND2}). + +apply_action(list, Key) -> + {User, Server, JID} = Key, + {RUser, RServer, _} = JID, + io:format("Matches: ~s@~s ~s@~s~n", [User, Server, RUser, RServer]); +apply_action(delete, Key) -> + apply_action(list, Key), + mnesia:dirty_delete(roster, Key). + +print_progress_line({Pr, NT, NV, ND}) -> + Pr2 = trunc((NV/NT)*100), + case Pr == Pr2 of + true -> + ok; + false -> + io:format("Progress ~p% - visited ~p - deleted ~p~n", [Pr2, NV, ND]) + end, + Pr2. + +decide_rip(Key, {_Action, Subs, Asks, User, Contact}) -> + case catch mnesia:dirty_read(roster, Key) of + [RI] -> + lists:member(RI#roster.subscription, Subs) + andalso lists:member(RI#roster.ask, Asks) + andalso decide_rip_jid(RI#roster.us, User) + andalso decide_rip_jid(RI#roster.jid, Contact); + _ -> + false + end. + +%% Returns true if the server of the JID is included in the servers +decide_rip_jid({UName, UServer, _UResource}, Match_list) -> + decide_rip_jid({UName, UServer}, Match_list); +decide_rip_jid({UName, UServer}, Match_list) -> + lists:any( + fun(Match_string) -> + MJID = jlib:string_to_jid(Match_string), + MName = MJID#jid.luser, + MServer = MJID#jid.lserver, + Is_server = is_glob_match(UServer, MServer), + case MName of + [] when UName == [] -> + Is_server; + [] -> + false; + _ -> + Is_server + andalso is_glob_match(UName, MName) + end + end, + Match_list). + +%% Copied from ejabberd-2.0.0/src/acl.erl +is_regexp_match(String, RegExp) -> + case ejabberd_regexp:run(String, RegExp) of + nomatch -> + false; + match -> + true; + {error, ErrDesc} -> + io:format( + "Wrong regexp ~p in ACL: ~p", + [RegExp, ErrDesc]), + false + end. +is_glob_match(String, [$! | Glob]) -> + not is_regexp_match(String, ejabberd_regexp:sh_to_awk(Glob)); +is_glob_match(String, Glob) -> + is_regexp_match(String, ejabberd_regexp:sh_to_awk(Glob)). ejabberd-2.1.11/debian/patches/fix-erlang-r16b-compat.patch0000600000000000000000000000271112261540704020171 0ustar Description: Fix compatibility of LDAP support with Erlang R16 The asn1rt_ber_bin has been removed from Erlang/OTP R16A, so this patch removes calls to these functions since they are only used to do sanity checks which appear to be redundant. Author: Badlop Bug: https://support.process-one.net/browse/EJAB-1612 Forwarded: not-needed Applied-Upstream: 2.1.12, 2704378d43035474c5f3d8a656b81c7bc28b5ff9 Last-Update: 2013-10-24 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/src/eldap/eldap.erl +++ b/src/eldap/eldap.erl @@ -760,7 +760,6 @@ %% {'EXIT', Reason} - Broke %%----------------------------------------------------------------------- recvd_packet(Pkt, S) -> - check_tag(Pkt), case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of {ok,Msg} -> Op = Msg#'LDAPMessage'.protocolOp, @@ -873,7 +872,6 @@ %% {'EXIT', Reason} - Broken packet %%----------------------------------------------------------------------- recvd_wait_bind_response(Pkt, S) -> - check_tag(Pkt), case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of {ok,Msg} -> ?DEBUG("~p", [Msg]), @@ -906,12 +904,6 @@ end. -%%% Sanity check of received packet -check_tag(Data) -> - {_Tag, Data1, _Rb} = asn1rt_ber_bin:decode_tag(Data), - {{_Len,_Data2}, _Rb2} = asn1rt_ber_bin:decode_length(Data1), - ok. - close_and_retry(S, Timeout) -> catch (S#eldap.sockmod):close(S#eldap.fd), Queue = dict:fold( ejabberd-2.1.11/debian/install0000664000000000000000000000016012240230175013026 0ustar debian/scripts/ejabberd usr/sbin/ debian/scripts/ejabberdctl usr/sbin/ debian/ejabberd.cfg usr/share/ejabberd/ ejabberd-2.1.11/debian/changelog0000664000000000000000000012251112327424317013325 0ustar ejabberd (2.1.11-1ubuntu2.1) trusty; urgency=low * Fix LDAP authentication (LP: #1241632) - debian/patches/fix-erlang-r16b-compat.patch: backport upstream fix for Erlang 16b compatibility. - upstream reference: https://support.process-one.net/browse/EJAB-1612 -- Lionel Porcheron Mon, 28 Apr 2014 12:09:12 +0200 ejabberd (2.1.11-1ubuntu2) trusty; urgency=low * Use autotools-dev for arm64. -- Daniel T Chen Mon, 10 Feb 2014 14:41:57 -0500 ejabberd (2.1.11-1ubuntu1) trusty; urgency=low * Add digest-uri-virtual-hosts.patch from upstream commit f434501 - Fixes a problem with Pidgin not being able to log in on a server with multiple virtual hosts and SRV records (LP: #1097366) -- a7x Tue, 08 Jan 2013 12:52:21 -0500 ejabberd (2.1.11-1) unstable; urgency=low [ Konstantin Khomoutov ] * New upstream release (closes: #654853). * Update mod_admin_extra module to revision 1126. * Provide custom implementation of xmerl_regexp:sh_to_awk/1 (closes: #670307). * Refresh reopen-log.patch * Add use_dpkg_buildflags.patch (thanks to Simon Ruderich, closes: #664034). * Explain the "fqdn" configuration file option which has to be used in certain setups for the SCRAM-SHA-1 to work with complying clients. Mention this fact in the NEWS file. (Closes: #706590) * Add upstream patch fixing incorrect escaping of a single quote character in SQL queries generated by the ODBC storage backend (closes: #708151, thanks to Vladislav Chugunov). [ Gerfried Fuchs ] * Add upstream patches disabling SSLv2 and weak cyphers in TLS driver (closes: #722105). * New upstream release made these patches obsolete: relax-digest-uri-handling.patch, fix-parsing-split-https-requests.patch, fix-odbc-escaping.patch -- Gerfried Fuchs Thu, 17 Oct 2013 12:57:47 +0200 ejabberd (2.1.10-5) unstable; urgency=low [ Konstantin Khomoutov ] * Add patch fixing parsing of optional parameters in SCRAM SHA-1 headers (closes: #705613, thanks to Stephen Röttger for both writing the original patch and backporting it to 2.1.10). -- Konstantin Khomoutov Thu, 25 Apr 2013 15:31:59 +0000 ejabberd (2.1.10-4) unstable; urgency=low [ Konstantin Khomoutov ] * Do not run ejabberdctl as root in prerm and logrotate scripts (closes: #691125, thanks to Michael Stapelberg and Felix Geyer). * Add upstream patch fixing receiving JPEG vCard photos via LDAP (closes: #660186). * Add upstream patch fixing parsing HTTPS requests split into multiple packets (closes: #698309). -- Konstantin Khomoutov Sat, 16 Feb 2013 16:59:21 +0000 ejabberd (2.1.10-3) unstable; urgency=low [ Konstantin Khomoutov ] * Provide custom implementation of xmerl_regexp:sh_to_awk/1 (closes: #670307). * Add use_dpkg_buildflags.patch (thanks to Simon Ruderich, closes: #664034). * Add relax-digest-uri-handling.patch (closes: #654853). * Add Slovak translation (thanks to Slavko, closes: #647115). * Add Italian translation (thanks to Beatrice Torracca, closes: #682987). -- Konstantin Khomoutov Sun, 20 May 2012 14:51:12 +0400 ejabberd (2.1.10-2) unstable; urgency=low [ Gerfried Fuchs ] * Upload to unstable (closes: #657759). * Remove code for #368414 from postinst, 1.1.1-3 is ancient history (closes: #656826) [ Konstantin Khomoutov ] * Update Dutch translation (thanks to Jeroen Schot, closes: #657590). * Enable hardened building of C drivers by using dpkg-buildflags (thanks to Moritz Muehlenhoff, closes: #657525). -- Konstantin Khomoutov Wed, 01 Feb 2012 01:50:40 +0400 ejabberd (2.1.10-1) experimental; urgency=low [ Konstantin Khomoutov ] * New upstream release. * Update mod_admin_extra to revision 1123. [ Gerfried Fuchs ] * Bump erlang-dev Build-Depends version to >= 1:15.b. -- Gerfried Fuchs Sun, 08 Jan 2012 11:45:38 +0100 ejabberd (2.1.9-1) unstable; urgency=low [ Konstantin Khomoutov ] * New upstream release. * Remove obsoleted version.patch. -- Konstantin Khomoutov Mon, 03 Oct 2011 20:27:12 +0400 ejabberd (2.1.8-1) unstable; urgency=low [ Konstantin Khomoutov ] * New upstream release. * Remove patch fixing DSA-2248-1 (CVE-2011-1753) as the fix is now integrated upstream. * Drop patches from OLPC project implementing @recent@ and @online@ shared roster groups; support for @online@ is now intergated upstream. * Add patch fixing version string where applicable (EJAB-1484). * Bump standards version to 3.9.2 [ Gerfried Fuchs ] * Add recommended targets build-arch and build-indep to debian/rules. * Fix spelling error in manpage noticed by lintian. -- Gerfried Fuchs Sun, 11 Sep 2011 16:16:55 +0200 ejabberd (2.1.6-2.1) unstable; urgency=high * Non-maintainer upload by the Security Team. * Disable entity expansion completely to prevent against billion laugs DoS attack (CVE-2011-1753). -- Nico Golde Mon, 30 May 2011 23:53:46 +0200 ejabberd (2.1.6-2) unstable; urgency=low * Artifically set HOME environment variable in debian/rules if it is not set--this is required for the erlexec binary to be able to run successfully (closes: #620683). -- Konstantin Khomoutov Wed, 06 Apr 2011 01:32:42 +0400 ejabberd (2.1.6-1) unstable; urgency=low * New upstream release. * Remove obsolete patches. * Update mod_admin_extra to revision 1106. * Conflict with ejabberd-mod-shared-roster-ldap which is now included. -- Konstantin Khomoutov Tue, 14 Dec 2010 17:45:08 +0300 ejabberd (2.1.5-3) unstable; urgency=low [ Konstantin Khomoutov ] * Add patch http-poll-binary-parse.patch fixing EJAB-1325 (closes: #601094). -- Konstantin Khomoutov Sat, 23 Oct 2010 17:05:48 +0400 ejabberd (2.1.5-2) unstable; urgency=low [ Gerfried Fuchs ] * New debconf translation: - Danish by Joe Hansen (closes: #592271) * Run debconf-updatepo on all other translations. [ Konstantin Khomoutov ] * Remove /var/run/ejabberd on package purge (LP: #615473). * Add mod-vcard-ldap-photo.patch fixing EJAB-1258 (LP: #613854). * Bump standards version to 3.9.1. -- Gerfried Fuchs Wed, 15 Sep 2010 21:03:06 +0200 ejabberd (2.1.5-1) unstable; urgency=low [ Konstantin Khomoutov ] * New upstream release. * Remove obsolete erlang-otp-r14-ssl.patch * Refresh patches: reopen-log.patch, shared_roster_online.patch shared_roster_recent.patch * Bump standards version to 3.9.0. * Remove COPYING file installed by upstream Makefile * Remove autogenerated src/ejabberd.init * Add upstream patch fixing EJAB-1284 (closes: #591431). -- Konstantin Khomoutov Tue, 03 Aug 2010 19:55:25 +0400 ejabberd (2.1.4-1) unstable; urgency=low [ Konstantin Khomoutov ] * Do not prevent ejabberd_debug from being installed and used as this was implemented upstream as the default behavior. * Add build dependency on erlang-parsetools. * Add 'sharedscripts' option to logrotate config. * Update VCS references in control file to point to git.deb.at. * Add group sticky bit to permissions on the log directory -- this should make log files owned by the group "adm". * Explicitly set umask to 027 before starting erl. * Add patch with fix for EJAB-953 (closes: #590389). * Fix call to setup_ejabberd in postinst. * Fix owner/permissions for log files when upgrading. * Minor fixes and clarifications in ejabberdctl.8 manual page. * Refresh reopen-log.patch -- Konstantin Khomoutov Mon, 26 Jul 2010 20:36:14 +0400 ejabberd (2.1.3-2) unstable; urgency=low [ Gerfried Fuchs ] * New patch fix_examples fixing two example scripts. * Call set -e explicitly in debian/config instead of on the hashbang line. [ Konstantin Khomoutov ] * Add reopen-log.patch which fixes reopening of ejabberd log files by `ejabberdctl reopen-log` (closes: #580951). * Replace ${erlang-nox:Depends} with ${erlang:Depends} in debian/control to generate a minimal list of Erlang packages ejabberd depends on (closes: #581909). * Reduce the set of Erlang packages required to build ejabberd. * Disable ejabberd_debug module and exclude it from packaging. -- Gerfried Fuchs Thu, 20 May 2010 21:20:27 +0200 ejabberd (2.1.3-1) unstable; urgency=low [ Konstantin Khomoutov ] * New upstream release. * Remove obsolete c2s-p1-fsm.patch * Remove obsolete ejabberdctl-help-dashes.patch * Update mod_admin_extra to revision 1078 * Refresh shared_roster_recent.patch * Refresh shared_roster_online.patch * Clarify how to do mixed IPv4/IPv6 setup of ejabberd listeners as suggested by Marc Dequènes in the discussion of #573801. [ Gerfried Fuchs ] * Remove Torsten Werner from maintainer field on his own wish - thanks for your work so far! (closes: #578722) * Promote Konstantin to Maintainer to best fit reality. Enjoy. :) -- Konstantin Khomoutov Tue, 06 Apr 2010 13:00:03 +0400 ejabberd (2.1.2-3) unstable; urgency=low [ Konstantin Khomoutov ] * Tighten dependency on debhelper to >= 7.3~ (closes: #569152). * Add global option max_fsm_queue set to 1000 to the configuration file (amendment to the fix for #568383). * Use $remote_fs facility in init-script as ejabberd uses files under /urs (fixes lintian error). * Set place for Erlang crash dumps in ejabberdctl. [ Gerfried Fuchs ] * Bump Standards-Version to 3.8.4. -- Konstantin Khomoutov Sun, 28 Feb 2010 22:11:26 +0300 ejabberd (2.1.2-2) unstable; urgency=high * Integrate upstream patches for EJAB-1173, fixing CVE-2010-0305 (closes: #568383). -- Konstantin Khomoutov Thu, 04 Feb 2010 03:38:02 +0300 ejabberd (2.1.2-1) unstable; urgency=low [ Gerfried Fuchs ] * New upstream release. * Improve debian/copyright file. [ Konstantin Khomoutov ] * Refresh shared_roster_online.patch and shared_roster_recent.patch * Add ejabberdctl-help-dashes.patch which allows to spell commands passed to `ejabberdctl help` using "-" as a word separator. * Document connected-users-info and stop-kindly ejabberdctl commands. * Document --concurrent option of ejabberdctl. * Shorten Vcs-Browser string in debian/control -- Gerfried Fuchs Wed, 20 Jan 2010 20:56:15 +0100 ejabberd (2.1.1-1) unstable; urgency=low [ Konstantin Khomoutov ] * New upstream release. This also fixes a bug in ejabberdctl (closes: #560824). * Update mod_admin_extra to upstream revision 1049. * Remove obsolete patches (those backported from 2.1.1). * Suggest imagemagick instead of recommending it (closes: #560889). [ Gerfried Fuchs ] * Switch Vcs-* fields to point to new git repository. All the conversion work was actually done by Konstantin. * Call debconf-updatepo. -- Gerfried Fuchs Thu, 14 Jan 2010 20:40:53 +0100 ejabberd (2.1.0-2) unstable; urgency=low [ Konstantin Khomoutov ] * Set EJABBERD_DOC_PATH in the ejabberd script * Pull the following patches from upstream: - routing-speedup.patch: Speeds up routing of messages (EJAB-1114) - mod-pubsub-odbc.patch: Fixes service discovery browsing with PEP-capable clients (EJAB-1115) - req-starttls-zlib-clash.patch: Fix failure of the c2s listener (EJAB-1118, closes: 559727) - http-tls-leaks.patch: Fix memory and port leaks in web administration interface (EJAB-1119, closes: #547306) - multiple-pep-last-items.patch: Do not send PEP last items multiple times (EJAB-1116) -- Gerfried Fuchs Thu, 10 Dec 2009 23:45:09 +0100 ejabberd (2.1.0-1) unstable; urgency=low [ Konstantin Khomoutov ] * New upstream release (Closes: #519858). This also adds support for LDAPS upstream (Closes: #526145). * Do not depend on cdbs anymore, port debian/rules to dh+quilt, remove build dependency on patchutils, use erlang-depends. * Bump debhelper version to 7, standards base to 3.8.3 * Depend on erlang R13B. * Recommend imagemagick (for captcha support). * Remove deprecated patches (ssl.patch patch, dynamic_compile_loglevel.patch, ldaps.patch, update.patch, proxy.patch, caps.patch, convert.patch, s2s.patch). * Replace mod_ctlextra with mod_admin_extra. * Use upstream inetrc file. * Bring debian/ejabberd.cfg and ejabberdctl in sync with upstream. * Update ejabberdctl manual page. * Provide NEWS file. * Rework README.Debian: * Group all information into sections. * Describe issues with epam binary (Closes: #502791). * Discuss how to use DBMS backends (Closes: #540915, #507144). * Discuss upgrading from 2.0.x series. * Implement PID file management (Closes: #519858). * Make logrotate process all files matching "*.log". * Improve init script: * Make init script LSB-compliant. * Implement "live" target which allows to run ejabberd in foreground. * Make captcha.sh use bash explicitly. * Rework node-generation for ejabberdctl to fix ejabberd's atom table overflows while preserving the possibility to run several versions of ejabberdctl concurrently as before. * Add webadmin patch restoring compatibility with Erlang/OTP <= R12B-4. * Integrate upstream patch for EJAB-1106. * Add upstream patch for EJAB-1098. * Add upstream patch for EJAB-1045. * Add Konstantin Khomoutov to uploaders. * Add Japanese debconf translation (thanks to Hideki Yamane) (Closes: #558071). [ Gerfried Fuchs ] * Build-Depend on po-debconf so po2debconf can be called. -- Gerfried Fuchs Fri, 04 Dec 2009 18:22:49 +0100 ejabberd (2.0.5-2) unstable; urgency=low * Added myself to Uploaders. * Added debian/README.source about quilt. * Updated Standards-Version to 3.8.2. * Lintian hints: + Remove +ssh from Vcs-Svn. + Remove path from ejabberdctl in postinst. * Rewrote Description a little bit. -- Gerfried Fuchs Fri, 07 Aug 2009 14:37:42 +0200 ejabberd (2.0.5-1.1) unstable; urgency=low * Non-maintainer upload to fix compatibility with Erlang/OTP R13B (dynamic_compile_loglevel.patch added). * Raise requirement for the erlang-dev package version to >= 1:13.b to simplify transition of Debian to Erlang/OTP R13B. -- Konstantin Khomoutov Sun, 10 May 2009 01:32:38 +0400 ejabberd (2.0.5-1) unstable; urgency=high * new upstream release - Fixes 'CVE-2009-0934: Cross-site scripting (XSS) vulnerability in ejabberd' (Closes: #520852) - Fixes 'starttls hangs' (Closes: #516528, #518079) * Disable patch ldaps.patch because it does not apply any more. * Refresh all other patches. -- Torsten Werner Sun, 05 Apr 2009 22:53:46 +0200 ejabberd (2.0.3-2) unstable; urgency=low * Remove Sergei from Uploaders field as requested by himself. -- Torsten Werner Sun, 15 Feb 2009 21:47:35 +0100 ejabberd (2.0.3-1) experimental; urgency=low * New upstream release. -- Sergei Golovan Thu, 15 Jan 2009 19:44:58 +0300 ejabberd (2.0.2-3) experimental; urgency=low * Merge changes from version 2.0.1-5 from unstable. * Document ERL_OPTIONS in /etc/default/ejabberd and README.Debian. (Closes: #503012) -- Torsten Werner Sun, 11 Jan 2009 17:19:28 +0100 ejabberd (2.0.2-2) experimental; urgency=low * Added option {keepalive, true} to ssl socket in LDAPS support patch. This helps not to loose long-term connections to LDAPS server (thanks to Alex Mauer for a suggestion). -- Sergei Golovan Fri, 12 Sep 2008 19:14:17 +0400 ejabberd (2.0.2-1) experimental; urgency=low * New upstream release. * Protected hostname -s and hostname -d calls in postinst script to prevent its failure in case when hostname is incorrectly configured. It's harmless to replace hostname by "localhost" because it's used only for generating a reference SSL certificate which is to be replaced by a proper one. -- Sergei Golovan Fri, 29 Aug 2008 21:15:26 +0400 ejabberd (2.0.1-6) unstable; urgency=high * Add backported patch pubsub_upgrade_tables.patch that fixes the broken upgrade of ejabberd from Etch. (Closes: #507615) -- Torsten Werner Sat, 07 Feb 2009 20:02:20 +0100 ejabberd (2.0.1-5) unstable; urgency=low * Added Brazilian Portuguese debconf templates translation (closes: #501751). * Protected hostname -s and hostname -d calls in postinst script to prevent its failure in case when hostname is incorrectly configured. It's harmless to replace hostname by "localhost" because it's used only for generating a reference SSL certificate which is to be replaced by a proper one. * Added option {keepalive, true} to ssl socket in LDAPS support patch. This helps not to loose long-term connections to LDAPS server (thanks to Alex Mauer for a suggestion). -- Sergei Golovan Fri, 10 Oct 2008 09:48:34 +0400 ejabberd (2.0.1-4) unstable; urgency=low * Added Basque debconf templates translation (closes: #492129). * Removed unneeded package grep-dctrl from build-dependencies (a call to erlang-depends has replaced it long time ago). * Updated Czech debconf templates translation (closes: #492495). * Added a unique suffix to ejabberdctl nodes to allow several commands to run in parallel. * Fixed a bug in building mod_http_fileserver, which made it completely unusable. * Added missing description of reopen-weblog ejabberdctl command to ejabberdctl.8 manpage. -- Sergei Golovan Mon, 04 Aug 2008 14:10:00 +0400 ejabberd (2.0.1-3) unstable; urgency=low [ Sergei Golovan ] * Synced mod_ctlextra module with upstream (closes: #488991). * Updated Portuguese debconf templates translation (closes: #487822). * Switched off autoupdating debian/control by cdbs to make build-dependencies consistent. * Added Swedish debconf templates translation (closes: #490681). * Updated Russian debconf templates translation (closes: #491424). * Updated Spanish debconf templates translation. * Added Galician debconf templates translation (closes: #490855). * Added Vietnamese debconf templates translation (closes: #491056). * Cleaned up LDAPS patch and fixed a bug with leaking SSL sockets (closes: #490059). * Don't return from init script until at least Erlang VM is started to make subsequent checks for running ejabberd simpler. * Added an additional check for starting Erlang VM and don't try to register admin user if ejabberd isn't started. This allows to shorten waiting interval during upgrade if it isn't desirable to start ejabberd automatically (closes: #462357). * Added Turkish debconf templates translation (closes: #491493). * Added Finnish debconf templates translation (closes: #491652). * Install SQL database schemas to examples directory. * Fixed crash in checking relational DB modules (closes: #491664). [ Torsten Werner ] * Updated German debconf templates translation. -- Sergei Golovan Wed, 23 Jul 2008 16:32:03 +0400 ejabberd (2.0.1-2) unstable; urgency=low * Improved a patch which removes message rejecting intervals for server-to-server recipients. * Bumped standards version to 3.8.0. -- Sergei Golovan Fri, 20 Jun 2008 10:07:29 +0400 ejabberd (2.0.1-1) unstable; urgency=low * New upstream bugfix release. * Refreshed patches, removed those which were included into upstream. * Added _2 suffix to get-orig-source target in debian/rules (temporarily). * Fixed debian/watch to cover current release version (with _2 suffix). * Fixed mod_ctlextra to work with ejabberd 2.0.1 (changed session record definition). * Added new ejabberdctl commands (both new in 2.0.1 and in mod_ctlextra) to ejabberdctl manual page. * Changed restart branch in init.d script to perform full Erlang VM stop and start again (this allows to apply changes in /etc/default/ejabberd if any during ejabberd restart). * Clarified -sname and -name Erlang option usage by ejabberd and ejabberdctl in their manual pages (closes: #482904). * Added BUGS section to ejabberd manual page with a short description of the most common cases of ejabberd start failures (closes: #481819). -- Sergei Golovan Sun, 08 Jun 2008 16:32:18 +0400 ejabberd (2.0.0-7) unstable; urgency=low [ Sergei Golovan ] * Installed eldap.hrl header. It is necessary to build some external modules for ejabberd. * Moved headers which are in subdirectories of src directory to corresponding subdirectory of /usr/lib/ejabberd/include/ as they are usually included with subdirectory prepended. * Included a patch which adds LDAPS support and added {ldap_encrypt} and {ldap_port} example options to ejabberd config file (closes: #477918). * Added an additional info on how to use ejabberd headers to README.Debian. * Changed section in doc-base registration file to Network/Communication. * Don't use HOSTNAME variable in postinstall and debconf config scripts to prevent confusion with the same bash standard environment variable. * Removed empty preinstall maintainer script. * Fixed minus signs in ejabberd and ejabberdctl manual pages. * Updated Russian debconf templates translation. [ Torsten Werner ] * Updated German debconf templates translation. * Update Vcs headers in debian/control. -- Sergei Golovan Sat, 17 May 2008 23:30:17 +0400 ejabberd (2.0.0-6) unstable; urgency=low * Replaced a patch for proxy65 module with nicer one (thanks to Evgeniy Khramtsov). * Added a patch for S2S module to make STARTTLS working with Erlang R12B. * Added a patch by upstream fixes crash when browsing the Update page in Erlang R12B. * Fixed ODBC patch to work with Erlang R11B also. -- Sergei Golovan Tue, 11 Mar 2008 15:10:42 +0300 ejabberd (2.0.0-5) experimental; urgency=low * Turned unnecessary error messages in mod_caps module into debug messages. * Added a few patches to shared roster module and also added mod_ctlextra (a module which offers many more or less useful commands to ejabberdctl) following the discussion in the following thread: http://lists.debian.org/debian-edu/2008/03/msg00017.html -- Sergei Golovan Fri, 07 Mar 2008 20:30:07 +0300 ejabberd (2.0.0-4) experimental; urgency=low * Updated French debconf templates translation (closes: #468788). * Disabled epoll by default in /etc/default/ejabberd. * Increased default maximum number of conference room occupants to 500. Given increasing popularity of XMPP old default value 200 is too low. * Disabled SMP support in ejabberd by default. It isn't necessary in most cases but can be less reliable. * Enabled PAM authentication support (yet needs to be refined). -- Sergei Golovan Mon, 03 Mar 2008 22:54:48 +0300 ejabberd (2.0.0-3) experimental; urgency=low * Increased S2S timeouts. Defaults seems to be too short. * Removed a 5-minute delay between a remote server connect failure and the next connection attempt. It causes more harm than good. * Changed ownership of ejabberd config directory and SSL certificate to root:ejabberd and mode to to make sure they aren't overwritten by running ejabberd. * Remove an SSL certificate on package purge. It is assumed that it's a generated certificate, so the removal is unconditional. -- Sergei Golovan Sun, 24 Feb 2008 10:40:03 +0300 ejabberd (2.0.0-2) experimental; urgency=low * Saved a little bit of resources by not starting ssl module which isn't used by ejabberd anymore. * Added several new variables to ejabberd script and default settings following upstream. * Added 'debug' option to ejabberdctl script which attaches Erlang shell to already running ejabberd server. * Removed useless README and /etc/ejabberd/ejabberdctl.cfg files from the binary package (/etc/ejabberd/ejabberdctl.cfg content is moved to /etc/default/ejabberd). * Added a patch which makes proxy65 module working with Erlang R12B. * Fixed position of override section in ejabberd.cfg and uncommented proxy65 module (with adding restrictive options). -- Sergei Golovan Fri, 22 Feb 2008 13:51:14 +0300 ejabberd (2.0.0-1) experimental; urgency=low * New upstream release. -- Sergei Golovan Thu, 21 Feb 2008 18:36:46 +0300 ejabberd (1.1.4-6) unstable; urgency=low * Loosened build dependencies to make backporting to etch easier. * Added a requirement for $remote_fs into init.d script because ejabberd needs mounted /usr to run. * Added a patch which allows ODBC to work with Erlang R12B. * Clarified debconf messages (closes: #390206). * Added a notice about hostname change to README.Debian and included erlang node conversion utility to the binary package (closes: #457097). * Added a patch which allows to use certificate chain files for encrypted connections (closes: #466676). -- Sergei Golovan Thu, 21 Feb 2008 18:21:32 +0300 ejabberd (1.1.4-5) unstable; urgency=low * Do not remove /etc/ejabberd on package purge to preserve user files if any (closes: #460459). * Bumped standards version to 3.7.3. * Added homepage header to debian control file. * Fixed unnecessary space in doc-base. * Changed default setting for nicknames which can be registered to 'none' (which effectively forbids registration) as this setting is more safe (closes: #458627). * Fixed name section of ejabberd and ejabberdctl manual pages. -- Sergei Golovan Sun, 13 Jan 2008 01:37:19 +0300 ejabberd (1.1.4-4) unstable; urgency=low * Added a patch which fixes access rule check in mod_irc. * Added a patch which fixes ejabberd build using erlang R12B-0. * Increased number of erlang ports in /etc/ejabberd/default. The default value of 1024 allows too few simultaneous connections (from 300 to 500 for both clients and servers depending of whether they use SSL or traffic compression). * Fixed shell backquotes in ejabberd and ejabberdctl manual pages. Also bumped their versions to 1.1.4. * Added a note about binding to privileged ports to README.Debian. * Fixed a race condition between starting log handler and port listener. Otherwise, error reports about port binding can't get into log file (closes: #458518). -- Sergei Golovan Tue, 01 Jan 2008 17:09:57 +0300 ejabberd (1.1.4-3) unstable; urgency=low * Applied a patch by upstream which fixes usage of relational databases in ejabberd modules while using internal or LDAP-based authentication (closes: #446848). The patch was adopted from ejabberd SVN by Andreas Oberritter. -- Sergei Golovan Tue, 16 Oct 2007 10:34:07 +0400 ejabberd (1.1.4-2) unstable; urgency=low * Moved ejabberd application directory from /usr/lib/erlang/lib/ejabberd-1.1.4 to /usr/lib/ejabberd to avoid conflicts of modules names (specifically, eldap module conflicts with shiiped in Yxa SIP server). -- Sergei Golovan Fri, 12 Oct 2007 10:07:19 +0400 ejabberd (1.1.4-1) unstable; urgency=low * New upstream release. * Fixed debian/watch file. * Removed ejabberd_sm.diff patch. This makes ejabberd using recommended error condition instead of . There was sufficient time to fix broken clients. * Removed perl-path.diff, shaper.diff, ejabberd_http_poll.diff, eldap.diff, sql_escape.diff patches since they are included into upstream release. * Redefined HOME environment variable to fix Erlang compiler warnings in case when HOME points to an existent inaccessible directory. * Bumped debhelper compatibility level to 5. -- Sergei Golovan Sun, 09 Sep 2007 14:25:16 +0400 ejabberd (1.1.2-10) unstable; urgency=low [ Sergei Golovan ] * Added Sergei Golovan to uploaders list. * Included a fix for IE bug (it sends zero length queries which cause error 404) from http://www.jabber.ru/bugzilla/attachment.cgi?id=205 (closes: #428864). * Included experimental Personal Eventing via Pubsub (XEP-0163) support using patch from https://svn.process-one.net/ejabberd-modules/pep/. -- Sergei Golovan Mon, 27 Aug 2007 20:19:43 +0400 ejabberd (1.1.2-9) unstable; urgency=low [ Sergei Golovan ] * Added binary package dependency on erlang-abi-* virtual package to prevent installation of ejabberd which uses incompatible erlang ABI. * Included ejabberd headers to binary package to make building external modules for ejabberd possible (closes: #428081). -- Torsten Werner Sun, 10 Jun 2007 19:19:20 +0400 ejabberd (1.1.2-8) unstable; urgency=high [ Torsten Werner ] * Remove redundant Build-Depends. * Use erlang-depends for calculating Depends now. * Change email address of Christophe Romain in man page as requested by himself. * Add XS-X-Vcs-Svn header to debian/control. [ Sergei Golovan ] * Security fix, mentioned in 1.1.2-5 was backported from SVN and not from 1.1.3, where it is incomplete (the bug affects ejabberd only if users' rosters are stored in relational database, and not in Mnesia, which is default). * Moved patches to debian directory. This fixes cleaning up after build process. (Closes: #424193) * Moved creating user ejabberd from preinst to postinst because preinst cannot rely on existence of adduser package. * Added a comment to ejabberd.cfg concerning UTF-8 encoding. * Unfuzzied one string in russian debconf translation (closes: #408410). * Removed annoying message about existing SSL certificate. * Fixed references to ejabberd installation and operation guide in manual pages (closes: #416050). * Backup ejabberd database on package removal or upgrade to a subdirectory of /var/backups instead of /var/tmp (closes: #409916). * Do not change /etc/ejabberd, /var/lib/ejabberd and /var/log/ejabberd ownership and permissions if they are overridden using dpkg-statoverride (closes: #416178). * Conditionally source /usr/share/debconf/confmodule in postrm script as debconf isn't an essential package (closes: #416743). * Included Portuguese translation of debconf messages (closes: #416779). -- Torsten Werner Fri, 18 May 2007 13:44:53 +0200 ejabberd (1.1.2-7) unstable; urgency=low * Rebuild the package with newer erlang. -- Torsten Werner Fri, 13 Apr 2007 20:14:12 +0200 ejabberd (1.1.2-6) unstable; urgency=high [ Sergei Golovan ] * Fixed users database and logs directoriy permissions (closes: #412583). -- Torsten Werner Tue, 27 Feb 2007 08:28:31 +0300 ejabberd (1.1.2-5) unstable; urgency=high * apply security fix backported from version 1.1.3 (http://ejabberd.jabber.ru/ejabberd-1.1.3); thanks to Sergei -- Torsten Werner Sat, 3 Feb 2007 23:08:08 +0100 ejabberd (1.1.2-4) unstable; urgency=medium [ Sergei Golovan ] * Fixed bug with LDAP support, thanks to Evgeniy Khramtsov. (Closes: #399659) * Documented quilt patches in patches/ directory. -- Torsten Werner Wed, 22 Nov 2006 13:44:13 +0300 ejabberd (1.1.2-3) unstable; urgency=low * Add patch http_bind.diff, thanks to Matthew Harrell. (Closes: #399560) * Updated debian/control from debian/control.in. -- Torsten Werner Mon, 20 Nov 2006 20:11:08 +0100 ejabberd (1.1.2-2) unstable; urgency=medium [ Sergei Golovan ] * backported bugfix for HTTP-polling from the ejabberd author [ Torsten Werner ] * Set urgency to medium. -- Torsten Werner Sun, 8 Oct 2006 11:32:25 +0200 ejabberd (1.1.2-1) unstable; urgency=low [ Sergei Golovan ] * new upstream release * added spanish translation * removed no longer needed mod_muc_log patch * added variable ERLANG_NODE, which allows to override default ejabberd node, to /etc/default/ejabberd file * changed erlang node selection by ejabberdctl (in some cases `hostname -s` and erlang's view of hostname are different, so let ejabberd_ctl module find hostname), closes: #389635 * documented ERLANG_NODE variable in ejabberd and ejabberdctl manual pages * explicitly specify hostname in admin ACL * improved admin user registering in debian/postinst. installation is not interrupted if the user can't be registered, so, closes: #385020 * only call ucf and deluser on purge when they are available, closes: #389756 * added check for running ejabberd before backup in debian/prerm, closes: #389757 * added workaround for centericq users (replaced fetaure-not-implemented error for service-unavailable in session management) * backported bugfix for shapers from ejabberd SVN -- Torsten Werner Wed, 04 Oct 2006 08:00:46 +0400 ejabberd (1.1.1-9) unstable; urgency=low [ Miroslav Kure ] * updated czech translation [ Sergei Golovan ] * replaced 'note' type in debconf template ejabberd/nomatch by 'error' since it is more approppriate, closes: #388890 -- Torsten Werner Sat, 23 Sep 2006 10:42:03 +0400 ejabberd (1.1.1-8) unstable; urgency=medium [ Sergei Golovan ] * security fix! fixed vulnerability in mod_muc_log where users were able to insert an HTML code to MUC weblogs (fix is backported from ejabberd SVN) * added LSB keyword section to init.d script [ Torsten Werner ] * setting urgency to medium because of a securetty issue -- Torsten Werner Thu, 14 Sep 2006 07:20:39 +0200 ejabberd (1.1.1-7) unstable; urgency=low * updated french translation, closes: #385811 * bugfix in postrm -- Torsten Werner Sun, 10 Sep 2006 02:27:19 +0200 ejabberd (1.1.1-6) unstable; urgency=low * add french translation, closes: #381900 * add czech translation, closes: #380525 * add dutch translation, closes: #381131 * updated debconf question ejabberd/user * fix in debian/config * make a backup of the database when removing or updating the package * remove the actual database when purging -- Torsten Werner Wed, 2 Aug 2006 15:20:14 +0200 ejabberd (1.1.1-5) unstable; urgency=low [ Torsten Werner ] * add target get-orig-source in debian/rules * updated Standards-Version to 3.7.2, no changes needed * use ucf for handling conffiles * remove old cruft not needed any more * use debconf to setup an admin account, partially fixes: #286110 * make bashism explicit * minor cleanups in debian/rules * renamed some files in debian/ * add german translation of the debconf template [ Sergei Golovan ] * use debconf to setup a served hostname * added russian translation of the debconf template -- Torsten Werner Sun, 23 Jul 2006 12:12:12 +0400 ejabberd (1.1.1-4) unstable; urgency=low * updated Build-Depends for erlang 10.b.10 * switched to quilt for managing upstream patches -- Torsten Werner Sat, 24 Jun 2006 21:06:59 +0200 ejabberd (1.1.1-3) unstable; urgency=low [ Sergei Golovan ] * moved ejabberd SSL certificate from /etc/ssl/certs to /etc/ejabberd, closes: #368414 [ Torsten Werner ] * upload to unstable -- Torsten Werner Sat, 10 Jun 2006 18:13:34 +0200 ejabberd (1.1.1-2) experimental; urgency=low [ Sergei Golovan ] * changed Build-Depends from erlang-base-hipe to erlang-base * fix for lintian complaint about incorrect usage of chown [ Torsten Werner ] * making Build-Depends and erlang:Depends more strict: they are working now only with the latest versions of erlang -- Torsten Werner Tue, 2 May 2006 21:00:47 +0200 ejabberd (1.1.1-1) experimental; urgency=low * New upstream release * applied changes from Sergei Golovan * removed src/Makefile.in from Debians SVN because the changes have been included upstream -- Torsten Werner Mon, 1 May 2006 19:36:19 +0200 ejabberd (1.0.0-2) unstable; urgency=low * downgraded erlang-Depends to erlang-runtime, closes: #361739 -- Torsten Werner Mon, 10 Apr 2006 20:52:45 +0200 ejabberd (1.0.0-1) unstable; urgency=low * new upstream release, closes: #344330, #353989 - Server-to-server Encryption for Enhanced Security: STARTTLS + SASL_EXTERNAL and STARTTLS + Dialback. - Different certificates can be defined for each virtual host. - Shared Roster groups support has been enhanced. New is the ability to add all registered users to a Shared Roster group. - Improved ODBC support. - Support for vCard storage in ODBC has been added. - New tool to convert an Mnesia-based installation to an ODBC compatible relational database. - Native PostgreSQL support. - More XHTML 1.0 Transitional compliancy work is included. - Documentation has been extended to cover more topics. -- Torsten Werner Sun, 5 Mar 2006 10:20:50 +0100 ejabberd (0.9.8-1) unstable; urgency=low * new upstream version * added debian/watch * merged some documentation and configuration fixes from Sergei Golovan -- Torsten Werner Sat, 6 Aug 2005 19:39:59 +0200 ejabberd (0.9.1-2) unstable; urgency=low * some fixes to the german translation, thanks to Patrick Dreker for pointing that out, closes: #317955 -- Torsten Werner Wed, 13 Jul 2005 21:53:16 +0200 ejabberd (0.9.1-1) unstable; urgency=low * New upstream release, closes: #309526 * added --enable-odbc to configure * small fix to init script * thanks to Sergei Golovan for helping -- Torsten Werner Wed, 25 May 2005 23:55:28 +0200 ejabberd (0.9-2) unstable; urgency=low * smoothed the upgrade procedure from 0.7.5 * added custom inetrc file (erlang R10 doesn't load /etc/resolv.conf when running in -sname mode, making resolving of SRV record impossible), thanks to Sergej Golovan, closes: #299533 * updated homepage -- Torsten Werner Wed, 18 May 2005 00:16:22 +0200 ejabberd (0.9-1) unstable; urgency=low * new upstream version, closes: #307652 -- Torsten Werner Tue, 10 May 2005 22:04:03 +0200 ejabberd (0.7.5-7) unstable; urgency=low * can build now with various erlang versions because of buggy erlang on arm -- Torsten Werner Sat, 8 Jan 2005 23:34:27 +0100 ejabberd (0.7.5-6) unstable; urgency=low * changed to versioned (Build-)Depends: erlang (>= 1:10), closes: #282836 * fixed error in init script, closes: #283205 * scripts ejabberd and ejabberdctl export $HOME environment variable now * usage message for ejabberdctl updated to reflect the different call syntax thanks to Sergei Golovan (both changes) * updated the Description proposed by Andreas van Cranenburgh -- Torsten Werner Tue, 30 Nov 2004 22:05:28 +0100 ejabberd (0.7.5-5) unstable; urgency=low * renamed debian/control to debian/control.in and changed Build-Depends: @cdbs@ -- Torsten Werner Fri, 19 Nov 2004 23:58:01 +0100 ejabberd (0.7.5-4) unstable; urgency=low * switched to cdbs * fixed perl script and added Suggests: libunix-syslog-perl -- Torsten Werner Thu, 18 Nov 2004 15:48:36 +0100 ejabberd (0.7.5-3) unstable; urgency=low * changed maintainer to myself -- Torsten Werner Wed, 17 Nov 2004 19:23:08 +0100 ejabberd (0.7.5-2) unstable; urgency=low * fixed doc-base file * initial upload based on Sergei's work -- Torsten Werner Wed, 3 Nov 2004 21:43:58 +0100 ejabberd (0.7.5-1) unstable; urgency=low * new upstream release (highlights: new tls module, starttls, improvements in admiin web interface, bugfixes) * improved init.d script -- Sergei Golovan Sun, 10 Oct 2004 21:44:25 +0400 ejabberd (0.7-2) unstable; urgency=low * workaround for mnesia issue in mod_last -- Sergei Golovan Wed, 14 Jul 2004 01:43:13 +0400 ejabberd (0.7-1) unstable; urgency=low * new upstream release -- Sergei Golovan Tue, 13 Jul 2004 20:35:29 +0400 ejabberd (0.6-alpha-20040522-4) unstable; urgency=low * fixed icq.localhost entry in config file * added example options to config file -- Sergei Golovan Thu, 17 Jun 2004 00:23:32 +0400 ejabberd (0.6-alpha-20040522-3) unstable; urgency=low * fixed comments in config file -- Sergei Golovan Wed, 16 Jun 2004 21:10:13 +0400 ejabberd (0.6-alpha-20040522-2) unstable; urgency=low * added comments to config file -- Sergei Golovan Sun, 13 Jun 2004 13:24:58 +0400 ejabberd (0.6-alpha-20040522-1) unstable; urgency=low * new upstream CVS snapshot * updated manual pade for ejabberdctl -- Sergei Golovan Sun, 30 May 2004 09:36:59 +0400 ejabberd (0.6-alpha-20040417-1) unstable; urgency=low * initial prerelease from upstream CVS snapshot -- Sergei Golovan Sun, 25 Apr 2004 16:39:22 +0400 ejabberd-2.1.11/debian/TODO0000664000000000000000000001041012240230175012124 0ustar * Ponder reimplementing the logic of allowing several instances of ejabberdctl to run in parallel while not overflowing the server's atom table. The idea is to modify the solution offered by Martin Langhoff at http://lists.jabber.ru/pipermail/ejabberd/2009-December/005627.html which is clever (uses the flock program, which is essential in Debian and so can be relied upon) but weak in that any "extra" instance will still fail. The current plan is to go this route: - Hardcode some limit on the number of parallel instances into ejabberdctl but allow to override it using a command-line argument (say, via --concurrent N). - Upon startup, lock a well-known file under /var/lock/ejabberd in a "blocking forever" mode, that is, if a file is already locked, wait for unlock. - After acquiring the lock, iterate over a sequence 1..N trying to lock specific ("instance") lock files. - Upon successful locking of any of these files, release the "master" lock and continue working. - At exit, unlock the "instance" file and remove it. This way, no instance will ever (soft-) fail: they'll be queued for execution while waiting on the "master lock". And the server's atom table will be safe from overflowing as there will ever see at most N unique node names of connecting Erlang nodes running ejabberdctl instances. * Fix lintian warnings where possible. * In debconf code, check if the user name contains the "@" character and if it is, does the part of the username to the right of it equals to the provided hostname. If both conditions hold, extract the real username and proceed, otherwise complain. At the current state it's possible to enter an invalid username and several users tripped over this issue. * Implement processing of standard Debian build options to allow parallel builds (has to be tested) and builds with gcc code optimizations turned off. * Better parsing of FIREWALL_WINDOW: a) make it robust against invalid input. b) allow open ranges like 123- and -234. * Add comments (and commented out examples) to the clauses in the "LISTENING PORTS" config file section explaining how to enable IPv6 on a port. * Seems like git-orig-source doesn't catch RC releases. Might be it would be cool to train it to find them. ejabberdctl.8 tasks =================== * It seems (from the stop-kindly command) that ejabberdctl assumes all strings it is passed are encoded in UTF-8 no matter what locale settings it and the server see. This is now documented for stop-kindly, but some testing should be done to support or disprove this hypothesis; if it is true, we should document this behaviour exactly once in the man page. * get-cookie Verify the claim made about its functionality. * push-roster recheck, manpage entries for mod_ctlextra mentioned other format. * push-roster-all all users on all vhosts? * push-alltoall does each user get the entry for theirselves? * process-rosteritems need more info * srg-create what format of "display"? * srg-get-info " group host" what format? * srg-get-members " group host" what format? Low priority ============ * Think of implementing /usr/share/ejabberd/common which would be sourced by both ejabberdctl and ejabberd and processed/constructed certain options. Also it seems that the upstream's approach with having just one file both for startup and control isn't that bad, as current packaging leads to some code duplication in scripts. Do we need the separate ejabberd script at all? For reference ============= * Use upstream ejabberdctl.cfg as /etc/default/ejabberd. Requires patching, see the master branch. Also ensure that the config is safe w.r.t. proxy65 etc, def. log level match etc (compate to the current one). * Re-check whether the upstream startup files would do better than current. The current have some nice ideas but they a) deviate from upstream b) artifically constructing node names for ejabberdctl provokes the atom list overflow of the ejabberd host in certain scenarious; no robust workaround is known yet. On the other hand, upstream scripts: a) more cumbersome; b) kill epmd; c) don't draw dots while waiting for ejabberd to start/stop; d) Show nag screens on debug and live targets. ejabberd-2.1.11/debian/default0000664000000000000000000001024212240230175013006 0ustar # # In this file you can configure options that are passed # to the erlang runtime system when starting ejabberd # # POLL: Kernel polling ([true|false]) # # The kernel polling option requires support in the kernel. # Additionaly, you need to enable this feature while compiling Erlang. # # Default: false # #POLL=false # SMP: SMP support ([enable|auto|disable]) # # Explanation in Erlang/OTP documentation: # enable: starts the Erlang runtime system with SMP support enabled. # This may fail if no runtime system with SMP support is available. # auto: starts the Erlang runtime system with SMP support enabled if it # is available and more than one logical processor are detected. # disable: starts a runtime system without SMP support. # # Default: disable # #SMP=disable # ERL_MAX_PORTS: Maximum number of simultaneously open Erlang ports # # ejabberd consumes two or three ports for every connection, either # from a client or from another Jabber server. So take this into # account when setting this limit. # # Default: 32000 # Maximum: 268435456 # #ERL_MAX_PORTS=32000 # FIREWALL_WINDOW: Range of allowed ports to pass through a firewall # # If Ejabberd is configured to run in cluster, and a firewall is blocking ports, # it's possible to make Erlang use a defined range of port (instead of dynamic # ports) for node communication. # # Default: empty # Example: 4200-4210 # #FIREWALL_WINDOW= # PROCESSES: Maximum number of Erlang processes # # Erlang consumes a lot of lightweight processes. If there is a lot of activity # on ejabberd so that the maximum number of proccesses is reached, people will # experiment greater latency times. As these processes are implemented in # Erlang, and therefore not related to the operating system processes, you do # not have to worry about allowing a huge number of them. # # Default: 250000 # Maximum: 268435456 # #PROCESSES=250000 # ERL_MAX_ETS_TABLES: Maximum number of ETS and Mnesia tables # # The number of concurrent ETS and Mnesia tables is limited. When the limit is # reached, errors will appear in the logs: # ** Too many db tables ** # You can safely increase this limit when starting ejabberd. It impacts memory # consumption but the difference will be quite small. # # Default: 1400 # #ERL_MAX_ETS_TABLES=1400 # ERL_OPTIONS: Additional Erlang options # # The next variable allows to specify additional options passed to erlang while # starting ejabberd. Some useful options are -noshell, -detached, -heart. When # ejabberd is started from an init.d script options -noshell and -detached are # added implicitly. See erl(1) for more info. # # It might be useful to add "-pa /usr/local/lib/ejabberd/ebin" if you # want to add local modules in this path. # # Default: empty # #ERL_OPTIONS="" # ERL_FULLSWEEP_AFTER: The maximum number of generational collections before # forcing a fullsweep # # The Erlang runtime system uses a generational garbage collection scheme, # using an "old heap" for data that has survived at least one garbage # collection. When there is no more room on the old heap, a fullsweep garbage # collection will be done. # # The fullsweep_after option makes it possible to specify the maximum number # of generational collections before forcing a fullsweep even if there is # still room on the old heap. Setting the number to zero effectively disables # the general collection algorithm, meaning that all live data is copied at # every garbage collection. # # To reduce memory usage, you can set environment variable ERL_FULLSWEEP_AFTER # to zero. But in this case ejabberd may work slower. # # Default: 65535 # #ERL_FULLSWEEP_AFTER=65535 # ERLANG_NODE: Erlang node for ejabberd server # # The next variable allows to explicitly specify erlang node for ejabberd # It can be given in different formats: # ERLANG_NODE=ejabberd # Lets erlang add hostname to the node (ejabberd uses short name in this case) # ERLANG_NODE=ejabberd@hostname # Erlang uses node name as is (so make sure that hostname is a real # machine hostname or you'll not be able to control ejabberd) # ERLANG_NODE=ejabberd@hostname.domainname # The same as previous, but erlang will use long hostname # (see erl (1) manual for details) # # Default: ejabberd # #ERLANG_NODE=ejabberd ejabberd-2.1.11/debian/README.Debian0000664000000000000000000004077712240230175013520 0ustar Table of contents ================= 1. Running. 1.1. Using privileged TCP ports 1.2. Custom options for Erlang emulator 1.3. Backups 1.4. Using IPv6 1.5. Using captcha 2. Hostname issues 3. PAM authentication 4. Using DBMS for data storage 5. External modules 6. Upgrading from 2.0.x series 6.1 Changes in ejabberdctl program 6.2 Changes in logging 7. Using SCRAM-SHA-1 authentication mechanism 1. Running ========== 1.1. Using privileged TCP ports ------------------------------- The ejabberd daemon which is run in init.d script is owned by user ejabberd, so it cannot bind to privileged ports (below 1024). The error message in /var/log/ejabberd/ejabberd.log looks similar to the following: E(<0.242.0>:ejabberd_listener:80): Failed to open socket for {443, ejabberd_c2s, [{access,c2s}, {max_stanza_size, 65536}, starttls, {certfile, "/etc/ejabberd/ejabberd.pem"}, {shaper, c2s_shaper}]}: eacces If you want ejabberd to listen for example port 443 you could redirect it to port 5222 (the default XMPP port) by a firewall rule. For example: iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 5222 1.2. Custom options for Erlang emulator --------------------------------------- You can add extra options to the erl command line like -pa /usr/local/lib/ejabberd/ebin by adding them to ERL_OPTIONS in /etc/default/ejabberd. 1.3. Backups ------------ The package always makes a backup of the ejabberd database if it's running when it is upgraded or removed. The backup files are stored in /var/backups/ejabberd-.* directory. 1.4. Using IPv6 --------------- IPv6 is not enabled by default for any network activity in ejabberd. This is because with the current state of ejabberd code it's impossible to fall back to IPv4 if IPv6 is unavailable, and hence enabling IPv6 by default would immediately break things for users with IPv6 disabled (see http://bugs.debian.org/503313 for more details). The actions to be carried out to enable IPv6 depend on whether IPv6-only or mixed setup is needed. To make ejabberd use IPv6 only, proceed with one of these methods: * Add the "inet6" atom to the configuration clauses describing c2s and s2s listeners. * Specify and IPv6 address for the "ip" option in the configuration of a listener, like {ip, "::"} -- ejabberd is able to deduce the protocol family from an IP address it parses and enable the appropriate mode on the socket such an IP address is configured for. * Specify the address to bind to along with the listener port; the notes above about the IP address formatting also apply here. To support both IPv6 and IPv4, you have to duplicate the sections for appropriate listeners hinting ejabberd about the protocol to use for each one. One way to do this looks like this (for the c2s listener): {listen, {{5222, "0.0.0.0"}, ejabberd_c2s, [...]}, {{5222, "::"}, ejabberd_c2s, [...]}, ... } This way, two (supposedly identical, though not required) c2s listeners are configured: the first one for IPv4 and the second one for IPv6; ejabberd figures the necessary protocol family out by looking at how the IP address to bind to is specified. Refer to the "Listening Ports" section of the Installation and Operation Guide for more info, specifically, to its "Port Number, IP Address and Transport Protocol" and "Examples" parts. 1.5. Using captcha ------------------ Captcha generation script uses the "convert" program from the "imagemagick" package. As it depends on a lot of packages related to graphics and X Window System, it is listed as suggested. Therefore, if you intend to enable captcha support for your multi-user conferences be sure to install imagemagick besides enabling captcha in the ejabberd configuration file. Also the "graphicsmagick-imagemagick-compat" package can be installed instead of "imagemagick" -- it provides the "convert" program compatible with that of imagemagick. 2. Hostname issues =================== The ejabberd daemon uses Erlang database Mnesia. Even if it's configured for using ODBC it uses Mnesia for some data (privacy lists et.) and runtime tasks (keeping routing table etc.). Mnesia is a multi-master database, and it tightly bounds to a hostname where it's working. Therefore, if you change computer hostname then ejabberd will stop working. If you don't have a current database backup then run ejabberd (attached to the terminal, otherwise you'll not be able to backup database and quit) by /usr/sbin/ejabberd --node ejabberd@oldhostname and in the Erlang shell prompt call (ejabberd@oldhostname)1> mnesia:backup("/tmp/ejabberd_at_oldhostname.backup"). (note the trailing fullstop). Then stop ejabberd by typing (ejabberd@oldhostname)1> q(). Now you have the latest Mnesia database backup. After that run a new Erlang shell by erl -pa /usr/lib/ejabberd/ebin and convert the backup file to a new hostname: 1> mnesia_convert:change_node_name('ejabberd@oldhostname', 'ejabberd@newhostname', "/tmp/ejabberd_at_oldhostname.backup", "/tmp/ejabberd_at_newhostname.backup"). 2> q(). Then use file /tmp/ejabberd_at_newhostname.backup to restore ejabberd database as it is described in ejabberdctl manual page. 3. PAM authentication ======================= Ejabberd uses "/usr/lib/ejabberd/priv/bin/epam" binary as a helper program to perform PAM authentication. Depending on the PAM plugins used, the process accessing these plugins might have to be run with elevated privileges. The official ejabberd Installation and Operation Guide simplemindedly suggests to make epam setuid root which would make it work for any possible case. Debian's ejabberd package, on the other hand, ships the epam program with the setuid and setgid bits cleared, and here is why: * Setuid and setgid programs present a serious potential security risk and are a target for exploitation attempts (especially programs which are made setuid root). * Different PAM plugins have different requirements for the privileges of the user working with them, for instance, to use the shadow passwords database for authentication, it is sufficient for the accessing process to be in the group "shadow"; to use LDAP backend, no elevation of privileges is needed at all. Taking into account the fact that ejabberd uses internal authentication by default (using its own private database), the decision of what special access rights to set for the epam program is left to the system administrator. To maintain non-standard access rights for the epam binary, it is advised to use dpkg-statoverride, as suggested by the Debian policy (section 10.9 "Permissions and owners") -- ejabberd package configuration scripts honor this setting so it survives upgrades. As an example, to make epam setgid shadow, you can use: dpkg-statoverride --add root shadow 02755 /usr/lib/ejabberd/priv/bin/epam and to make epam setuid root you can do: dpkg-statoverride --add root ejabberd 04754 /usr/lib/ejabberd/priv/bin/epam (Note that we set o-x there so that only users in the ejabberd group are able to elevate their privileges by executing this program.) 4. Using DBMS for data storage =============================== The ejabberd Installation and Operation Guide mentions that ejabberd is able to use various DBMS engines to manage most of ejabberd's data, such as user accounts, rosters, offline messages, pubsub storage etc. This is confusing, as the only database driver ejabberd supports "out of the box" is ODBC; working with any listed DBMS directly requires installation of a special database driver for Erlang, which are third-party code and are not distributed along with ejabberd. Debian's ejabberd package does not ship these database drivers, and hence it is not possible to work natively with MySQL, PostgreSQL and other DBMSes listed as supported by the Guide. This issue is discussed in the Debian BTS (see bugs #507144 and #540915). Therefore, as no one yet stepped forward to create and maintain packages which would enable native access to the supported DBMSes, you have two options to use them: * Get, build and install the required Erlang database driver then configure ejabberd to locate the compiled code and use it. Drivers for MySQL and PostgreSQL can be obtained from https://forge.process-one.net/browse/ejabberd-modules Refer to the section "External modules" of this file for details on managing external ejabberd modules. * Use ODBC backend with a proper ODBC driver. On the ejabberd side, this only requires making corresponding changes in the configuration file. Gerfried Fuchs presented a sample configuration for using PostgreSQL via ODBC in http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=540915#10 Note that it appears that currently the only way to use Microsoft SQL Server as a database backend is via ODBC (and the FreeTDS ODBC driver). 5. External modules =================== The package installs ejabberd Erlang headers into /usr/lib/ejabberd/include directory. To build a module using these headers, as usual include them using -include_lib("ejabberd/include/headername.hrl"). and compile the module using -pa option to add ejabberd path to a search list erlc -pa /usr/lib/ejabberd/ebin module.erl Alternatively, include headers as -include("headername.hrl"). and add option -I /usr/lib/ejabberd/include to erlc command line. This is possibly the preferred way to build third-party ejabberd modules. To install a module, copy the resulting beam file(s) to a directory in which the Erlang emulator running ejabberd looks for compiled files. One of such directories is "/usr/lib/ejabberd/ebin", but you are strongly advised not to place any files there unless they come from a Debian package. Hence, the best way to handle external modules is to maintain a special directory for them under "/usr/local" -- for instance, the "/usr/local/lib/ejabberd/ebin". To make Erlang emulator know about this directory, add an appropriate option to the ERL_OPTIONS variable in the "/etc/default/ejabberd" file. For the location proposed, you will probably want to add -pa /usr/local/lib/ejabberd/ebin to that variable. See the erl(1) manual page for more info on the "-pa" Erlang emnulator command line option. 6. Upgrading from 2.0.x series ============================== Certain changes were made in version 2.1.0 which are incompatible with 2.0.x series packaged in Debian. While upgrading of the database should occur fully automatically, there are changes in the infrastructure, which you might need to take into account, 6.1 Changes in ejabberdctl program ---------------------------------- 1) The calling format of the ejabberdctl program was changed: a special prefix "vhost HOSTNAME" which selected operation on the specified virtual host was dropped; now previously vhost-specific commands gained one extra argument specifying a virtual host (such as "ban-users") or come in pairs, such as "delete-old-users" with "delete-old-users-vhost". 2) Some ejabberdctl commands were renamed (see below). 3) ejabberd in Debian was shipped with the mod_ctlextra module which provided several advanced commands for the ejabberdctl program. mod_ctlextra is not supported since 2.1.0 anymore and so it was replaced my its successor, mod_admin_extra. This resulted in renaming of several commands previously provided by mod_ctlextra. Note that for mod_admin_extra module to be loaded, it must be mentioned in the appropriate section of the ejabberd configuration file. As this file is not upgraded automatically, make sure you have replaced the request to load mod_ctlextra with the request to load mod_admin_extra. Refer to the ejabberdctl(8) manual page for more details. The summary of changes in ejabberdctl commands is given below. Renamed: "set-password" to "change-password"; "delete-older-messages" to "delete-old-messages"; "delete-older-users" to "delete-old-users"; "rem-rosteritem" to "delete-rosteritem"; "killsession" to "kick-session"; Renamed and calling convention changed: "vcard-get" to "get-vcard" and "get-vcard2"; "vcard-set" to "set-vcard" and "set-vcard2"; Deleted: "rosteritem-purge" Virtual-host specific commands which now accept a virtual host to operate on as their extra argument: "ban-account" "num-active-users" "registered-users" 4) The ejabberdctl program was changed not to generate unique node names by default for the Erlang process it starts; to enable generation of unique node names you now has to pass the "--concurrent" command-line option to the ejabberdctl program. This was made to prevent overflows of atom table in the ejabberd process which may occur if ejabberdctl is started many times during the ejabberd process lifetime, which is not uncommon on some high-profile sites. Now, ejabberdctl assumes you take care of ensuring all invocations of ejabberdctl are done in a sequence and uses constant names for the nodes of the Erlang processes it starts. If you can not (or don't want to) guarantee sequential invocations, pass the "--concurrent" command-line option to the ejabberdctl program. In this case, it will append the PID of the shell process executing the ejabberdctl code to the node name of the Erlang process ejabberdctl starts. This will inevitably grow the ejabberd process's atom table but the maximum theoretical number of the entries added will be no more than twice the maximum number of unique PIDs configured for the system (kernel.pid_max sysctl variable). See http://lists.jabber.ru/pipermail/ejabberd/2009-September/005337.html and http://lists.jabber.ru/pipermail/ejabberd/2009-November/005456.html threads for more info on this issue. 6.2 Changes in logging ---------------------- Erlang emulator log was renamed from "sasl.log" to "erlang.log" to remove confusion (some people interpreted "sasl" as standing for "Simple Authentication and Security Layer" instead of Erlang runtime's logging mechanism). The "--sasl-log" command-line option of the ejabberd program was renamed to "--erlang-log" to match the change above. 7. Using SCRAM-SHA-1 authentication mechanism ============================================= Since version 2.1.9 ejabberd supports the SCRAM-SHA-1 authentication mechanism (which, among other things, allows to not store passwords of XMPP accounts in clear text if the internal database backend is used for storage). This authentication process implemented by this mechanism includes the client sending a so-called "digest URI" which includes the server's identity as perceived by the connecting client. The SCRAM-SHA-1 RFC document requires this identity to be the fully-qualified host name of the server. This hostname is typically obtained by the client by looking up a server-specific DNS record of type SRV for the XMPP domain the client wants to register in. Unfortunately, the current implementation of SCRAM-SHA-1 in ejabberd is not able to perform the same kind of DNS query as used by the clients to know its "canonical" fully-qualified host name. Consequently, if the actual hostname of the server differs from the name of the XMPP domain it serves, a special option should be included in the configuration file to let the server know its hostname as seen by its clients. This configuration option is called "fqdn" and it expects a single argument -- the fully-qualified hostname of the server, as recorded in the appropriate DNS SRV record for the server. An example of its usage: {fqdn, "foo.example.com"}. It worth repeating that if the server's hostname is not different from the name of XMPP domain it servers (for instance, the XMPP domain is "example.com" and the server's hostname is also "example.com") the usage of this configuration option is not necessary as ejabberd will just use the domain name in the indicated case. It should be noted that while certain clients faithfully implement the SCRAM-SHA-1 specification, some other clients diverge and use the XMPP domain instead of the fully-qualified hostname of the server in the digest URI strings they send. Ejabberd implements relaxed rules for interpreting digest URIs to be interoperable with broken client implementations. Authors ======= Torsten Werner Sergei Golovan Konstantin Khomoutov Sun, 15 Nov 2009 03:52:33 +0300 ejabberd-2.1.11/debian/ejabberdctl.80000664000000000000000000007063712240230175014007 0ustar .TH ejabberdctl 8 "04 October 2009" "Version 2.1.0 RC1" "ejabberdctl manual page" .SH NAME ejabberdctl \(em a control interface of ejabberd Jabber/XMPP server .SH SYNOPSIS .PP \fBejabberdctl\fR \fI[\-\-node nodename] [\-\-auth user host password] [command [options]]\fP .SH DESCRIPTION .PP \fBejabberdctl\fR is a front end to the ejabberd Jabber/XMPP server. It is designed to help the administrator control the functioning of the running \fBejabberd\fR daemon. .PP This command must be run either by a superuser or by the user \fBejabberd\fP, otherwise it will fail to start or to connect to the ejabberd instance. .SH OPTIONS .TP .BI \-\-node " nodename" Specifies remote Erlang node to connect to. Default value is \fIejabberd\fP. If the node name does not contain a symbol \fI@\fP then the actual node name becomes \fInode@host\fP where \fIhost\fP is short hostname (usually it coincides with \fI\(gahostname \-s\(ga\fP). If the node name contains a symbol \fI@\fR and its hostname part is a FQDN then \fBejabberd\fR will use so-called long names (see \fBerl\fR(1) manual page and look for options \fI\-name\fP and \fI\-sname\fP for details). Examples of \fI\-\-node\fP option: .BI ejabberd Connect to locally run ejabberd server at node \fIejabberd@\(gahostname \-s\(ga\fP. .BI ejabberd@otherhost Connect to remotely run ejabberd server at node \fIejabberd@otherhost\fP. .BI ejabberd@localhost Connect to locally run ejabberd server at node \fIejabberd@localhost\fP. ejabberdctl honors \fBERLANG_NODE\fR environment variable from /etc/default/ejabberd, see below. .TP .BI \-\-auth " user host password" If restriction of access to \fBejabberdctl\fR commands is configured (see the "Restrict Execution with AccessCommands" section in the Installation and Operation Guide), this option must be used to authenticate the entity requesting execution of the command. \fIuser\fP and \fIhost\fP are the respective parts of the entity JID and \fIpassword\fP is either a plain text password to authenticate that JID or the MD5 hash of that password. .TP .BI \-\-concurrent Due to the way \fBejabberdctl\fR is implemented, it is normally not possible to run two instances of it in parallel\(enthe second one will fail. This is OK in a common case when \fBejabberdctl\fR is only run manually from time to time by a server administrator; if, conversely, there is a chance for several instances of \fBejabberdctl\fR to be active at the same time (say, automated registration of new users on an actively used site), you can pass the \fI\-\-concurrent\fP option to \fBejabberdctl\fR which will ensure no clash will ever occur. .IP Usage of the \fI\-\-concurrent\fP option creates additional pressure on the server resources, and that is why the behaviour it implements is not the default. This issue is described in more detail in /usr/share/doc/ejabberd/README.Debian .IP Note that the semantics of this option can be changed in a future release. .SH COMMANDS .PP Some commands to \fBejabberdctl\fR are single words, like \fBstatus\fR, and some are multi-word, like \fBreopen-log\fR; to join the adjacent words of the multi-word commands you can use either the underline ("_") symbol or the minus sign ("-") or a mixture of them, so all the following forms are valid: \fBstatus_list_host\fR, \fBstatus-list-host\fR, \fBstatus_list-host\fR. .PP When run without any \fIcommand\fP specified, \fBejabberdctl\fR prints the list of available commands and their short descriptions. .PP The following commands can be used: .TP .BI help " [\-\-tags [tag] | PATTERN]" The \fBhelp\fR command without any options does the same thing as running \fBejabberdctl\fR without any command specified \(em it prints the list of available commands along with their short descriptions. .IP The \fI\-\-tags\fP option specified alone makes the \fBhelp\fR command print the list of supported "help tags" which group \fBejabberdctl\fR commands on the basis of their purpose (such as debugging commands, backup commands etc). .IP The \fI\-\-tags\fP option specified with a tag \fItag\fP makes the \fBhelp\fR command print the list of commands associated wih the help tag \fItag\fP along with their short descriptions. .IP If the \fBhelp\fR command is followed by a word other than "\-\-tags", this word is interpreted as a pattern specifying a set of commands to print the help on. In this pattern, a "*" character matches any number of characters, including zero, and a "?" character matches any single character. Note that when running \fBejabberdctl\fR with this form of the \fBhelp\fR command from the shell, you have to protect the characters in the pattern from being interpreted by the shell. .TP .BI debug Attache an interactive Erlang shell to a running ejabberd server. To detach it press Ctrl+G, then input a character "q" and hit . .TP .BI status Request status of the Erlang virtual machine where ejabberd server is running. .TP .BI stop Stop the ejabberd server and its Erlang virtual machine. .TP .BI stop-kindly " delay announcement" Broadcast an announcement \fIannouncement\fP to all connected users, wait \fIdelay\fP seconds and then stop the ejabberd server and its Erlang virtual machine. .IP This command is interactive: it dumps the progress of the shutdown sequence to stdout (including waiting for the grace period to pass). .IP The \fIannouncement\fP string is unconditionally interpreted as a sequence of UTF-8 characters no matter what locale settings the server and ejabberdctl processes see. .TP .BI restart Restarts the ejabberd server inside Erlang virtual machine. Note that if you want to change VM options (enable/disable kernel poll or SMP, increase number of ports or database tables) you have to stop ejabberd completely and then start it again. .TP .BI reopen\-log Force the ejabberd server to reopen its log files (\fI/var/log/ejabberd/ejabberd.log\fP and \fI/var/log/erlang.log\fP by default). If module mod_http_fileserver is loaded then force the ejabberd server to reopen its weblog file. .TP .BI register " user server password" Register user \fIuser\fP with password \fIpassword\fP at ejabberd virtual host \fIserver\fP. .TP .BI unregister " user server" Unregister user \fIuser\fP at ejabberd virtual host \fIserver\fP. .TP .BI backup " filepath" Backup user database of the ejabberd server to file \fIfilepath\fP. .IP The directory in which \fIfilepath\fP is located must be writable by the user "ejabberd". .TP .BI restore " filepath" Restore user database of the ejabberd server from backup file \fIfilepath\fP. .IP The file \fIfilepath\fP must be readable by the user "ejabberd". .TP .BI install\-fallback " filepath" Install a backup to \fIfilepath\fP as fallback. The fallback will be used to restore the database at the next start-up. .IP The directory in which \fIfilepath\fP is located must be writable by the user "ejabberd". .TP .BI dump " filepath" Dump user database of the ejabberd server to text file \fIfilepath\fP. .IP The directory in which \fIfilepath\fP is located must be writable by the user "ejabberd". .TP .BI load " filepath" Restore user database of the ejabberd server from text file \fIfilepath\fP. .IP The file \fIfilepath\fP must be readable by the user "ejabberd". .TP .BI dump\-table " file table" Dump the specified database \fItable\fR to the specified text \fIfile\fR. .IP The directory in which \fIfile\fP is located must be writable by the user "ejabberd". .TP .BI import\-file " filepath" Import user data from jabberd 1.4 spool file \fIfilepath\fP. For example, if \fIfilepath\fP is \fI.../example.org/user.xml\fP then imported username will be \fIuser\fP and it will be imported to virtual server \fIexample.org\fP. .IP The file \fIfilepath\fP must be readable by the user "ejabberd". .TP .BI import\-dir " directorypath" Import user data from jabberd 1.4 spool directory \fIdirectorypath\fP. Directory name should be the name of virtual server to import users. .IP The directory \fIdirectorypath\fP and the files in it must be readable by the user "ejabberd". .TP .BI mnesia\-change\-nodename " oldnodename newnodename oldbackup newbackup" Reads the backup file \fIoldbackup\fR (which should have been created using the \fBejabberdctl backup\fR command) and writes its contents to the file \fInewbackup\fR while replacing in it all occurences of the Erlang node name \fIoldnodename\fR with the \fInewnodename\fR. .IP This should be used to "migrate" the ejabberd database to the new hostname of the machine on which ejabberd runs in case this hostname is about to change. This is because ejabberd is actually served by an Erlang node which is bound to the name of the physical host to provide for clustering. .TP .BI rename\-default\-nodeplugin Since release 2.0.0 and up to release 2.1.0, the implementation of publish-subscribe (pubsub) in ejabberd used a plugin named "node_default" as the default node plugin. Starting from release 2.1.0 this functionality is provided by the new plugin named "hometree". In the case of upgrading from an older version of ejabberd, its pubsub database might retain references to the old name of this plugin, "node_default", and this command can be used to upgrade the pubsub database, changing all these references to the new name \- "hometree". .IP Note that ejabberd automatically runs this command if you update from an ejabberd release 2.0.5 or older. .IP Running this command on already updated database does nothing. .TP .BI delete\-expired\-messages Delete expired offline messages from ejabberd database. .TP .BI delete\-old\-messages " n" Delete offline messages older than \fIn\fP days from ejabberd database. .TP .BI mnesia " info" Show some information about the Mnesia system (see \fBmnesia\fP(3), function \fIinfo\fP). .TP .BI mnesia Show all information about the Mnesia system, such as transaction statistics, database nodes, and configuration parameters (see \fBmnesia\fP(3), function system_info). .TP .BI mnesia " key" Show information about the Mnesia system according to \fIkey\fP specified (see \fBmnesia\fP(3), function system_info for valid \fIkey\fP values). .TP .BI incoming\-s2s\-number Print number of incoming server-to-server connections to the node. .TP .BI outgoing\-s2s\-number Print number of outgoing server-to-server connections from the node. .TP .BI user\-resources " user server" List all connected resources of user \fIuser@server\fP. .TP .BI connected\-users\-number Report number of established users' sessions. .TP .BI connected\-users Print full JIDs of all established sessions, one on a line. .TP .BI connected\-users\-info Print detailed information of all established sessions, one session on a line, with each session described as a list of whitespace-separated values: full JID, connection string (such as "c2s", "c2s_tls" etc), client IP address, client port number, resource priority, name of an Erlang node serving the session, session duration (in seconds). .TP .BI connected\-users\-vhost " server" Print full JIDs of all users registered at the virtual host \fIserver\fP which are currently connected to the ejabberd server, one on a line. .TP .BI registered\-users " server" List all the users registered on the ejabberd server at the virtual host \fIserver\fP. .TP .BI get\-loglevel Print the log level (an integer number) ejabberd is operating on. .SS EXPORTING DATA TO PIEFXIS (XEP-0227) FORMAT .PP The commands described in this section require availability of the \fBexmpp\fR library which is not shipped with ejabberd. Your can download its source code from \fIhttp://exmpp.org\fP. .TP .BI export\-piefxis " dir" Export data of all users registered on all virtual hosts of the server to a set of PIEFXIS files which will be stored in the directory \fIdir\fR. .IP The directory \fIdir\fR must be writable by the user "ejabberd". .TP .BI export\-piefxis\-host " dir host" Export data of all the users registered on the specified virtual host \fIhost\fR to a set of PIEFXIS files which will be stored in the directory \fIdir\fR. .IP The directory \fIdir\fR and the files in it must be readable by the user "ejabberd". .TP .BI import\-piefxis " file" Import users' data from a PIEFXIS file \fIfile\fR. .IP The file \fIfile\fR must be readable by the user "ejabberd". .SH EXTRA OPTIONS .PP An optional module \fBmod_admin_extra\fP adds a number of other commands. .PP While it is enabled by default, you might want to check it is actually enabled in the configuration file (especially if you're upgrading from pre-2.1 series of ejabberd). .PP To enable these additional commands add mod_admin_extra to the \fB{modules}\fP section of ejabberd config file and make it looking as the following: .sp .nf {modules, [ ... {mod_admin_extra, []}, ... ]}. .fi .PP Most of additional commands possess extended descriptions which can be printed using \fBejabberdctl help\fR \fIcommand\fP .PP The new commands are: .TP .BI add\-rosteritem " localuser localserver user server nick group subscription" Add to the roster of the user \fIlocaluser\fP registered on the virtual host \fIlocalserver\fP a new entry for the user \fIuser\fP on the server \fIserver\fP, assign the nickname \fInick\fP to it, place this entry to the group \fIgroup\fP and set its subscription type to \fIsubscription\fP which is one of "none", "from", "to" or "both". .TP .BI delete\-rosteritem " localuser localserver user server" Delete from the roster of the user \fIlocaluser\fP on the server \fIlocalserver\fP an entry for the JID \fIuser\fP@\fIserver\fP. .TP .BI ban\-account " user host reason" Ban the user \fIuser\fP registered on the virtual host \fIhost\fP. This is done by kicking their active sessions with the reason \fIreason\fP and replacing their password with a randomly generated one. .TP .BI kick\-session " user host resource reason" Kick the session opened by the user \fIuser\fP registered on the virtual host \fIhost\fP and having the resource \fIresource\fP bound to it providing the reason \fIreason\fP. .TP .BI change\-password " user host newpass" Change password of the user \fIuser\fP registered on the virtual host \fIhost\fP to \fInewpass\fP. .TP .BI check\-account " user host" Exit with code 0 if the user \fIuser\fP is registered on the virtual host \fIhost\fP, exit with code 1 otherwise. .TP .BI check\-password " user host password" Exit with code 0 the user \fIuser\fP registered on the virtual host \fIhost\fP has password \fIpassword\fP, exit with code 1 otherwise. .TP .BI check\-password\-hash " user host passwordhash hashmethod" Exit with code 0 if the user \fIuser\fP registered on the virtual host \fIhost\fP has a password, the hash of which, calculated using the \fIhashmethod\fP is equal to the hash \fIpasswordhash\fP; exit with code 1 otherwise. .IP Allowed hashing methods are "md5" and "sha" (for SHA-1). .TP .BI compile " file" Compile and reload the Erlang source code file \fIfile\fP. .IP The file \fIfile\fR must be readable by the user "ejabberd". .TP .BI load\-config " file" Load ejabberd configuration from the file \fIfile\fP. .IP The file \fIfile\fR must be readable by the user "ejabberd". .IP Note that loading config to a database does not mean reloading the server \(em for example it's impossible to add/remove virtual hosts without server restart. In fact, only ACLs, access rules and a few global options are applied upon reloading. .TP .BI delete\-old\-users " days" Delete accounts and all related data of users who did not log on the server for \fIdays\fP days. .TP .BI delete\-old\-users\-vhost " host days" Delete accounts and all related data of users registered on the virtual host \fIhost\fP who did not log on the server for \fIdays\fP days. .TP .BI export2odbc " host path" Export Mnesia database tables keeping the data for the virtual host \fIhost\fP to a set of text files created under the specified directory \fIpath\fP, which must exist and must be writable by the user "ejabberd". .TP .BI get\-cookie Print the cookie used by the Erlang node which runs ejabberd instance \fBejabberdctl\fR controls. .TP .BI get\-roster " user host" Print the roster of the user \fIuser\fP registered on the virtual host \fIhost\fP. .IP The information printed is a series of lines each representing one roster entry; each line consist of four fields separated by tab characters representing, in this order: the JID of an entry, its nickname, subscription type and group. .TP .BI push\-roster " file user host" Push items from the file \fIfile\fP to the roster of the user \fIuser\fP registered on the virtual host \fIhost\fP. .IP The format of file containing roster items is the same as used for output by the \fBget\-roster\fR command. .TP .BI push\-roster\-all " file" .IP The format of file containing roster items is the same as used for output by the \fBget\-roster\fR command. .TP .BI push\-alltoall " host group" All entries for all the users registered on the virtual host \fIhost\fP to the rosters of all the users registered on this virtual host. The created entries are assigned to the roster group \fIgroup\fP. .TP .BI process\-rosteritems " action subs asks users contacts" \fBFIXME\fP no information available. Do not use. .TP .BI get\-vcard " user host name" Print the contents of the field \fIname\fP of a vCard belonging to the user \fIuser\fP registered on the virtual host \fIhost\fP. If this field is not set of the user did not create their vCard, and empty string is printed (that is, containing only the line break). .IP For example \fIname\fP can be "FN" or "NICKNAME" For retrieving email address use "EMAIL USERID". Names and descriptions of other supported fields can be obtained from the XEP-0054 document (http://www.xmpp.org/extensions/xep\-0054.html). .TP .BI get\-vcard2 " user host name subname" Print the contents of the subfield \fIsubname\fP of the field \fIname\fP of a vCard belonging to the user \fIuser\fP registered on the virtual host \fIhost\fP. If this field is not set of the user did not create their vCard, and empty string is printed (that is, containing only the line break). .TP .BI set\-vcard " user host name content" Set the field \fIname\fP to the string \fIcontent\fP in the vCard of the user \fIuser\fP registered on the virtual host \fIhost\fP. .TP .BI set\-vcard2 " user host name subname content" Set the subfield \fIsubname\fP of the field \fIname\fP to the string \fIcontent\fP in the vCard of the user \fIuser\fP registered on the virtual host \fIhost\fP. .TP .BI set\-nickname " user host nickname" Set the "nickname" field in the vCard of the user \fIuser\fP registered on the virtual host \fIhost\fP to \fInickname\fP. .TP .BI num\-active\-users " host days" Print number of users registered on the virtual host \fIhost\fP who logged on the server at least once during the last \fIdays\fP days. .TP .BI num\-resources " user host" Print the number of resources (that is, active sessions) the user \fIuser\fP registered on the virtual host \fIhost\fP currently has. If the specified user has no active sessions, print the string "0". .TP .BI resource\-num " user host num" Print the resource of a session number \fInum\fP the user \fIuser\fP registered on the virtual host \fIhost\fP has currently open. \fInum\fP must be a positive integer, greater than or equal to 1. .IP If the session number specified is less than 1 or greater than the number of sessions opened by the user, an error message is printed. .TP .BI remove\-node " node" Remove the Erlang node \fInode\fP from the Mnesia database cluster. .TP .BI send\-message\-chat " from to body" Send a message of type "chat" from the JID \fIfrom\fP to the (local or remote) JID \fIto\fP containing the body \fIbody\fP. Both bare and full JIDs are supported. .TP .BI send\-message\-headline " from to subject body" Send a message of type "headline" from the JID \fIfrom\fP to the (local or remote) JID \fIto\fP containing the body \fIbody\fP and subject \fIsubject\fP. Both bare and full JIDs are supported. .TP .BI send\-stanza\-c2s " user server resource stanza" Send XML string \fIstanza\fP to the stream to which the session \fIuser@server/resource\fP is bound. The stanza must be well-formed (according to RFC 3920) and the session must be active. .IP For example: .nf ejabberdctl send-stanza-c2s john_doe example.com Bahamas \\ 'How goes?' .fi .TP .BI srg\-create " group host name description display" Create a new shared roster group \fIgroup\fP on the virtual host \fIhost\fP with displayed name \fIname\fP, description \fIdescription\fP and displayed groups \fIdisplay\fP. .TP .BI srg\-delete " group host" Delete the shared roster group \fIgroup\fP from the virtual host \fIhost\fP. .TP .BI srg\-user\-add " user server group host" Add an entry for the JID \fIuser\fP@\fIserver\fP to the group \fIgroup\fP on the virtual host \fIhost\fP. .TP .BI srg\-user\-del " user server group host" Delete an entry for the JID \fIuser\fP@\fIserver\fP from the group \fIgroup\fP on the virtual host \fIhost\fP. .TP .BI srg\-list " host" List the shared roster groups on the virtual host \fIhost\fP. .TP .BI srg\-get\-info " group host" Print info on the shared roster group \fIgroup\fP on the virtual host \fIhost\fP. .TP .BI srg\-get\-members " group host" Print members of the shared roster group \fIgroup\fP on the virtual host \fIhost\fP. .TP .BI private\-get " user server element namespace" Prints an XML stanza which would be sent by the server it it received an IQ-request of type "get" with the .nf <\fIelement\fP xmlns="\fInamespace\fP"/> .fi payload from \fIuser@server\fP. .IP For example: .nf ejabberdctl private-get john_doe example.com \\ storage storage:bookmarks .fi would return user's bookmarks, managed according to XEP-0048. .TP .BI private\-set " user server element" Allows one to simulate \fIuser@server\fP sending an IQ-request of type "set" containing \fIelement\fP as its payload; the payload is processed by the code managing users' private storage (XEP-0049 "Private XML Storage"). .IP The string \fIelement\fP must be a well-formed XML obeying the rules defined for IQ-request payloads in RFC 3920. .TP .BI privacy\-set " user server element" Allows one to simulate \fIuser@server\fP sending an IQ-request of type "set" containing \fIelement\fP as its payload; this payload is processed by the code managing privacy lists (XEP-0016 "Privacy lists"). .IP The string \fIelement\fP must be a well-formed XML obeying the rules defined for IQ-request payloads in RFC 3920. .TP .BI stats " topic" Print statistics on the topic \fItopic\fP. The valid topics and their meaning are: .IP .BI registeredusers Print the number of users registered on the server. .IP .BI onlineusers Print the number of users currently logged into the server. .IP .BI onlineusersnode Print the number of users logged into the server which are served by the current ejabberd Erlang node. .IP .BI uptimeseconds Print the uptime of the current ejabberd Erlang node, in seconds. .TP .BI stats\-host " host topic" Print statistics on the topic \fItopic\fP for the virtual host \fIhost\fP. The valid topics and their meaning are: .IP .BI registeredusers Print the number of users registered on the host \fIhost\fP. .IP .BI onlineusers Print the number of users currently logged into the server, which are registered on the host \fIhost\fP. .TP .BI status\-list " status" Print the users currently logged into the server and having the presence status \fIstatus\fP. The entries are printed one per line; each entry consists of the four fields separated by tab characters, in this order: the node part of the user's JID, the host part of the user's JID, the user's session resource, the priority of the user's session and the user's status description. .IP The \fIstatus\fP parameter can take the following values: "available", "away", "xa", "dnd" and "chat". .TP .BI status\-list\-host " host status" Print the users currently logged into the server which are registered on the virtual host \fIhost\fP and have the presence status \fIstatus\fP. .IP The available values for the \fIstatus\fP parameter and the format of the output data are the same as of the \fBstatus\-list\fR subcommand. .TP .BI status\-num " status" Print the number of users currently logged into the server and having the presence status \fIstatus\fP. .IP The available values for the \fIstatus\fP parameter are the same as of the \fBstatus\-list\fR subcommand. .TP .BI status\-num\-host " host status" Print the number of users currently logged into the server which are registered on the virtual host \fIhost\fP and have the presence status \fIstatus\fP. .IP The available values for the \fIstatus\fP parameter are the same as of the \fBstatus\-list\fR subcommand. .TP .BI user\-sessions\-info " user server" Print detailed information on all sessions currently established by \fIuser@server\fP. For each session, one line of output is generated, containing the following fields separated by tab characters: connection string (such as "c2s", "c2s_tls" etc), remote IP address, remote port number, priority of the resource bound to this session, name of an Erlang node serving the session, session uptime (in seconds), resource string. \" .TP \" .BI muc\-purge " days" \" Destroy MUC rooms with zero activity (no messages in history) in the last \" \fIdays\fP days. \" .TP \" .BI muc\-online\-rooms \" Print the list of existing MUC rooms. \" entries related to mod_ctlextra (2.0.x series): \".TP \".BI pushroster " file user server" \"Push template roster in file \fIfile\fP to \fIuser@server\fP. The file contents \"must use the following format: \".sp \".nf \"[{"bob", "example.org", "Bob's group", "Bob's nickname"}, \" {"mart", "example.org", "workers", "Mart"}, \" {"Rich", "example.org", "bosses", "Rich"}]. \".fi \".TP \".BI pushroster\-all " file" \"Push template roster in file to all users listed in the file \fIfile\fP itself. \"The file contents must be in the same format as for \fBpushroster\fP command. .SH NOTES .PP \fBejabberdctl\fR starts distributed Erlang node \fIejabberddebug\fP (if run with \fBdebug\fP option) or \fIejabberdctl\fP (if run with any other options). If the ejabberd server's node name to connect to includes FDQN as a hostname Erlang option \fI\-name\fP is used. Otherwise \fBejabberdctl\fR uses short names (\fI\-sname\fP option). .PP Note that \fBejabberdctl\fR does not append hostname to its own node name leaving this to Erlang emulator. It usually follows \fI\(gahostname \-f\(ga\fP to find a hostname if long names are used or \fI\(gahostname \-s\(ga\fP in case of short names, but may fail in case of unusual networking settings. A known case of failure is using long names when \fI\(gahostname \-f\(ga\fP doesn't return FDQN. If \fRejabberdctl\fR cannot create Erlang node then it cannot control ejabberd server. .PP \fBejabberdctl\fR does not do anything by itself except for connecting to the running ejabberd instance and telling it about the action requested by the user. Hence all the \fBejabberdctl\fR's operations involving writing or reading files or directories are actually performed by the server process which runs with the uid and gid of the user and group "ejabberd", respectively. This must be taken into account when requesting such operations to be done. .SH OPTIONS FILE .PP The file \fB/etc/default/ejabberd\fR contains specific options. Two of them are used by \fBejabberdctl\fP. .TP .BI ERLANG_NODE Use specified string as Erlang node of \fBejabberd\fP server to connect. It overrides default \fBejabberd\fP node name. The string may take one of the following forms: \fBnodename\fP, \fBnodename@hostname\fP or \fBnodename@hostname.domainname\fP. .TP .BI FIREWALL_WINDOW Use the specified range of ports to communicate with the other Erlang nodes (namely, with the target Erlang node running ejabberd). This can be useful when the system running the target node has restricted firewall setup allowing only a certain range of ports to be used by the Erlang nodes for communication; in this case, you should specify that range of ports in the \fBFIREWALL_WINDOW\fR setting. .SH FILES .PD 0 .I /etc/default/ejabberd default variables .SH SEE ALSO .PP \fBerl\fR(1), \fBejabberd\fR(8), \fBmnesia\fR(3). .PP The program documentation is available at \fIhttp://www.process\-one.net/en/projects/ejabberd/\fP. A copy of the documentation can be found at /usr/share/doc/ejabberd/guide.html. .SH AUTHORS .PP This manual page was adapted by Sergei Golovan for the \fBDebian\fP system (but may be used by others) from the \fBejabberd\fP documentation written by Alexey Shchepin . Updated by Konstantin Khomoutov . Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. .PP On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common\-licenses/GPL. ejabberd-2.1.11/debian/logrotate0000664000000000000000000000034412240230175013364 0ustar /var/log/ejabberd/*.log { weekly missingok rotate 12 size 1M compress delaycompress ifempty create 640 ejabberd adm sharedscripts postrotate su ejabberd -c '/usr/sbin/ejabberdctl reopen-log' > /dev/null endscript } ejabberd-2.1.11/debian/postinst0000664000000000000000000000745412240230175013260 0ustar #! /bin/sh # postinst script for ejabberd # # see: dh_installdeb(1) set -e CONFIG_SOURCE=/usr/share/ejabberd/ejabberd.cfg CONFIG_TARGET=/etc/ejabberd/ejabberd.cfg TEMPFILE=$(mktemp) . /usr/share/debconf/confmodule setup_ejabberd() { # Ejabberd config dir may contain sensitive data, so making it unreadable by # the world. if ! dpkg-statoverride --list /etc/ejabberd >/dev/null; then chown root:ejabberd /etc/ejabberd chmod 750 /etc/ejabberd fi # The users database dir /var/lib/ejabberd must be writable by user ejabberd. install -d /var/lib/ejabberd if ! dpkg-statoverride --list /var/lib/ejabberd >/dev/null; then chown -R ejabberd:ejabberd /var/lib/ejabberd chmod 700 /var/lib/ejabberd fi # Ejabberd logs should be readable by users in adm group (see also logrotate script). install -d /var/log/ejabberd if ! dpkg-statoverride --list /var/log/ejabberd >/dev/null; then chown ejabberd:adm /var/log/ejabberd chmod 2750 /var/log/ejabberd if dpkg --compare-versions "$2" lt '2.1.4'; then find /var/log/ejabberd -type f -name '*.log*' \ | while read f; do chown ejabberd:adm "$f" chmod 0640 "$f" done fi fi # Making /etc/ejabberd/ejabberd.pem if it does not exist. ( cd /etc/ejabberd if [ ! -f ejabberd.pem ] then echo "Generating SSL certificate /etc/ejabberd/ejabberd.pem..." EHOSTNAME=$(hostname -s 2>/dev/null || echo localhost) EDOMAINNAME=$(hostname -d 2>/dev/null || echo localdomain) openssl req -new -x509 -days 365 -nodes -out ejabberd.pem \ -keyout ejabberd.pem > /dev/null 2>&1 <<+++ . . . $EDOMAINNAME $EHOSTNAME ejabberd root@$EHOSTNAME.$EDOMAINNAME +++ fi if ! dpkg-statoverride --list /etc/ejabberd/ejabberd.pem >/dev/null; then chown root:ejabberd /etc/ejabberd/ejabberd.pem chmod 640 /etc/ejabberd/ejabberd.pem fi ) db_get ejabberd/hostname HOST="$RET" db_get ejabberd/user USER="$RET" db_get ejabberd/password PASSWD="$RET" sed -e "s/__USER__/$USER/g ; s/__HOSTNAME__/$HOST/g" $CONFIG_SOURCE >$TEMPFILE ucf --three-way --debconf-ok $TEMPFILE $CONFIG_TARGET db_stop # Making ejabberd config readable only by ejabberd user. chown ejabberd:ejabberd $CONFIG_TARGET chmod 600 $CONFIG_TARGET } register_admin() { if [ -n "$USER" -a -n "$PASSWD" ]; then echo -n "Waiting for ejabberd to register admin user" if ejabberdctl status >/dev/null || test $? = 1 ; then # Ejabberd is starting ($? = 1) or running ($? = 0) already. cnt=0 flag=1 while ! ejabberdctl status >/dev/null ; do echo -n "." cnt=`expr $cnt + 1` if [ $cnt -ge 60 ] ; then echo echo "Can't register admin user \"$USER@$HOST\"." echo -n "Ejabberd is starting too long." flag=0 break fi sleep 1 done echo if [ $flag -eq 1 ] ; then if ! status=$(ejabberdctl register "$USER" "$HOST" "$PASSWD") ; then if echo $status | grep -q "already registered" ; then echo "Admin user \"$USER@$HOST\" is already registered. Password IS NOT changed." else echo "Can't register admin user \"$USER@$HOST\"." fi else echo "Admin user \"$USER@$HOST\" is registered successfully." fi fi else echo echo "Can't register admin user \"$USER@$HOST\"." echo "Ejabberd server is not started." fi fi } case "$1" in configure|reconfigure) adduser --quiet --system --shell /bin/sh --group --home /var/lib/ejabberd ejabberd setup_ejabberd "$@" ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 0 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# case "$1" in configure|reconfigure) register_admin ;; esac exit 0 ejabberd-2.1.11/debian/examples0000664000000000000000000000006312240230175013200 0ustar src/ejabberd.cfg.example examples/* src/odbc/*.sql ejabberd-2.1.11/debian/init.d0000664000000000000000000000521012240230175012546 0ustar #! /bin/sh # # ejabberd Start/stop ejabberd server # ### BEGIN INIT INFO # Provides: ejabberd # Required-Start: $remote_fs $network $named $time # Required-Stop: $remote_fs $network $named $time # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Starts ejabberd jabber server # Description: Starts ejabberd jabber server, an XMPP # compliant server written in Erlang. ### END INIT INFO PATH=/sbin:/bin:/usr/sbin:/usr/bin EJABBERD=/usr/sbin/ejabberd EJABBERDCTL=/usr/sbin/ejabberdctl EJABBERDRUN=/var/run/ejabberd EJABBERDUSER=ejabberd NAME=ejabberd test -f $EJABBERD || exit 0 test -f $EJABBERDCTL || exit 0 # Include ejabberd defaults if available if [ -f /etc/default/ejabberd ] ; then . /etc/default/ejabberd fi ctl() { action="$1" su $EJABBERDUSER -c "$EJABBERDCTL $action" >/dev/null } mkrundir() { if [ ! -d $EJABBERDRUN ]; then mkdir -p $EJABBERDRUN if [ $? -ne 0 ]; then echo -n " failed" return fi chmod 0755 $EJABBERDRUN chown ejabberd:ejabberd $EJABBERDRUN fi } start() { mkrundir cd /var/lib/ejabberd su $EJABBERDUSER -c "$EJABBERD -noshell -detached" cnt=0 while ! (ctl status || test $? = 1) ; do echo -n . cnt=`expr $cnt + 1` if [ $cnt -ge 60 ] ; then echo -n " failed" break fi sleep 1 done } stop() { if ctl stop ; then cnt=0 sleep 1 while ctl status || test $? = 1 ; do echo -n . cnt=`expr $cnt + 1` if [ $cnt -ge 60 ] ; then echo -n " failed" break fi sleep 1 done else echo -n " failed" fi } live() { mkrundir echo '*******************************************************' echo '* To quit, press Ctrl-g then enter q and press Return *' echo '*******************************************************' echo cd /var/lib/ejabberd exec su $EJABBERDUSER -c "$EJABBERD" } case "$1" in start) echo -n "Starting jabber server: $NAME" if ctl status ; then echo -n " already running" else start fi ;; stop) echo -n "Stopping jabber server: $NAME" if ctl status ; then stop else echo -n " already stopped" fi ;; restart|force-reload) echo -n "Restarting jabber server: $NAME" if ctl status ; then stop start else echo -n " is not running. Starting $NAME" start fi ;; live) if ctl status ; then echo -n "ejabberd is already running" else live fi ;; *) echo "Usage: $0 {start|stop|restart|force-reload|live}" >&2 exit 1 ;; esac if [ $? -eq 0 ]; then echo . else echo " failed." fi exit 0 ejabberd-2.1.11/.git/0000775000000000000000000000000012240452476011071 5ustar ejabberd-2.1.11/.git/hooks/0000775000000000000000000000000012240452476012214 5ustar ejabberd-2.1.11/.git/hooks/applypatch-msg.sample0000775000000000000000000000070412240230175016342 0ustar #!/bin/sh # # An example hook script to check the commit log message taken by # applypatch from an e-mail message. # # The hook should exit with non-zero status after issuing an # appropriate message if it wants to stop the commit. The hook is # allowed to edit the commit message file. # # To enable this hook, rename this file to "applypatch-msg". . git-sh-setup test -x "$GIT_DIR/hooks/commit-msg" && exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} : ejabberd-2.1.11/.git/hooks/update.sample0000775000000000000000000000703312240230175014675 0ustar #!/bin/sh # # An example hook script to blocks unannotated tags from entering. # Called by "git receive-pack" with arguments: refname sha1-old sha1-new # # To enable this hook, rename this file to "update". # # Config # ------ # hooks.allowunannotated # This boolean sets whether unannotated tags will be allowed into the # repository. By default they won't be. # hooks.allowdeletetag # This boolean sets whether deleting tags will be allowed in the # repository. By default they won't be. # hooks.allowmodifytag # This boolean sets whether a tag may be modified after creation. By default # it won't be. # hooks.allowdeletebranch # This boolean sets whether deleting branches will be allowed in the # repository. By default they won't be. # hooks.denycreatebranch # This boolean sets whether remotely creating branches will be denied # in the repository. By default this is allowed. # # --- Command line refname="$1" oldrev="$2" newrev="$3" # --- Safety check if [ -z "$GIT_DIR" ]; then echo "Don't run this script from the command line." >&2 echo " (if you want, you could supply GIT_DIR then run" >&2 echo " $0 )" >&2 exit 1 fi if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then echo "Usage: $0 " >&2 exit 1 fi # --- Config allowunannotated=$(git config --bool hooks.allowunannotated) allowdeletebranch=$(git config --bool hooks.allowdeletebranch) denycreatebranch=$(git config --bool hooks.denycreatebranch) allowdeletetag=$(git config --bool hooks.allowdeletetag) allowmodifytag=$(git config --bool hooks.allowmodifytag) # check for no description projectdesc=$(sed -e '1q' "$GIT_DIR/description") case "$projectdesc" in "Unnamed repository"* | "") echo "*** Project description file hasn't been set" >&2 exit 1 ;; esac # --- Check types # if $newrev is 0000...0000, it's a commit to delete a ref. zero="0000000000000000000000000000000000000000" if [ "$newrev" = "$zero" ]; then newrev_type=delete else newrev_type=$(git cat-file -t $newrev) fi case "$refname","$newrev_type" in refs/tags/*,commit) # un-annotated tag short_refname=${refname##refs/tags/} if [ "$allowunannotated" != "true" ]; then echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 exit 1 fi ;; refs/tags/*,delete) # delete tag if [ "$allowdeletetag" != "true" ]; then echo "*** Deleting a tag is not allowed in this repository" >&2 exit 1 fi ;; refs/tags/*,tag) # annotated tag if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 then echo "*** Tag '$refname' already exists." >&2 echo "*** Modifying a tag is not allowed in this repository." >&2 exit 1 fi ;; refs/heads/*,commit) # branch if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then echo "*** Creating a branch is not allowed in this repository" >&2 exit 1 fi ;; refs/heads/*,delete) # delete branch if [ "$allowdeletebranch" != "true" ]; then echo "*** Deleting a branch is not allowed in this repository" >&2 exit 1 fi ;; refs/remotes/*,commit) # tracking branch ;; refs/remotes/*,delete) # delete tracking branch if [ "$allowdeletebranch" != "true" ]; then echo "*** Deleting a tracking branch is not allowed in this repository" >&2 exit 1 fi ;; *) # Anything else (is there anything else?) echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 exit 1 ;; esac # --- Finished exit 0 ejabberd-2.1.11/.git/hooks/prepare-commit-msg.sample0000775000000000000000000000232712240230175017124 0ustar #!/bin/sh # # An example hook script to prepare the commit log message. # Called by "git commit" with the name of the file that has the # commit message, followed by the description of the commit # message's source. The hook's purpose is to edit the commit # message file. If the hook fails with a non-zero status, # the commit is aborted. # # To enable this hook, rename this file to "prepare-commit-msg". # This hook includes three examples. The first comments out the # "Conflicts:" part of a merge commit. # # The second includes the output of "git diff --name-status -r" # into the message, just before the "git status" output. It is # commented because it doesn't cope with --amend or with squashed # commits. # # The third example adds a Signed-off-by line to the message, that can # still be edited. This is rarely a good idea. case "$2,$3" in merge,) /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; # ,|template,) # /usr/bin/perl -i.bak -pe ' # print "\n" . `git diff --cached --name-status -r` # if /^#/ && $first++ == 0' "$1" ;; *) ;; esac # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" ejabberd-2.1.11/.git/hooks/pre-applypatch.sample0000775000000000000000000000061612240230175016344 0ustar #!/bin/sh # # An example hook script to verify what is about to be committed # by applypatch from an e-mail message. # # The hook should exit with non-zero status after issuing an # appropriate message if it wants to stop the commit. # # To enable this hook, rename this file to "pre-applypatch". . git-sh-setup test -x "$GIT_DIR/hooks/pre-commit" && exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} : ejabberd-2.1.11/.git/hooks/pre-commit.sample0000775000000000000000000000325012240230175015464 0ustar #!/bin/sh # # An example hook script to verify what is about to be committed. # Called by "git commit" with no arguments. The hook should # exit with non-zero status after issuing an appropriate message if # it wants to stop the commit. # # To enable this hook, rename this file to "pre-commit". if git rev-parse --verify HEAD >/dev/null 2>&1 then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi # If you want to allow non-ascii filenames set this variable to true. allownonascii=$(git config hooks.allownonascii) # Redirect output to stderr. exec 1>&2 # Cross platform projects tend to avoid non-ascii filenames; prevent # them from being added to the repository. We exploit the fact that the # printable range starts at the space character and ends with tilde. if [ "$allownonascii" != "true" ] && # Note that the use of brackets around a tr range is ok here, (it's # even required, for portability to Solaris 10's /usr/bin/tr), since # the square bracket bytes happen to fall in the designated range. test $(git diff --cached --name-only --diff-filter=A -z $against | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 then echo "Error: Attempt to add a non-ascii file name." echo echo "This can cause problems if you want to work" echo "with people on other platforms." echo echo "To be portable it is advisable to rename the file ..." echo echo "If you know what you are doing you can disable this" echo "check using:" echo echo " git config hooks.allownonascii true" echo exit 1 fi # If there are whitespace errors, print the offending file names and fail. exec git diff-index --check --cached $against -- ejabberd-2.1.11/.git/hooks/post-update.sample0000775000000000000000000000027512240230175015661 0ustar #!/bin/sh # # An example hook script to prepare a packed repository for use over # dumb transports. # # To enable this hook, rename this file to "post-update". exec git update-server-info ejabberd-2.1.11/.git/hooks/pre-rebase.sample0000775000000000000000000001144212240230175015437 0ustar #!/bin/sh # # Copyright (c) 2006, 2008 Junio C Hamano # # The "pre-rebase" hook is run just before "git rebase" starts doing # its job, and can prevent the command from running by exiting with # non-zero status. # # The hook is called with the following parameters: # # $1 -- the upstream the series was forked from. # $2 -- the branch being rebased (or empty when rebasing the current branch). # # This sample shows how to prevent topic branches that are already # merged to 'next' branch from getting rebased, because allowing it # would result in rebasing already published history. publish=next basebranch="$1" if test "$#" = 2 then topic="refs/heads/$2" else topic=`git symbolic-ref HEAD` || exit 0 ;# we do not interrupt rebasing detached HEAD fi case "$topic" in refs/heads/??/*) ;; *) exit 0 ;# we do not interrupt others. ;; esac # Now we are dealing with a topic branch being rebased # on top of master. Is it OK to rebase it? # Does the topic really exist? git show-ref -q "$topic" || { echo >&2 "No such branch $topic" exit 1 } # Is topic fully merged to master? not_in_master=`git rev-list --pretty=oneline ^master "$topic"` if test -z "$not_in_master" then echo >&2 "$topic is fully merged to master; better remove it." exit 1 ;# we could allow it, but there is no point. fi # Is topic ever merged to next? If so you should not be rebasing it. only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` only_next_2=`git rev-list ^master ${publish} | sort` if test "$only_next_1" = "$only_next_2" then not_in_topic=`git rev-list "^$topic" master` if test -z "$not_in_topic" then echo >&2 "$topic is already up-to-date with master" exit 1 ;# we could allow it, but there is no point. else exit 0 fi else not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` /usr/bin/perl -e ' my $topic = $ARGV[0]; my $msg = "* $topic has commits already merged to public branch:\n"; my (%not_in_next) = map { /^([0-9a-f]+) /; ($1 => 1); } split(/\n/, $ARGV[1]); for my $elem (map { /^([0-9a-f]+) (.*)$/; [$1 => $2]; } split(/\n/, $ARGV[2])) { if (!exists $not_in_next{$elem->[0]}) { if ($msg) { print STDERR $msg; undef $msg; } print STDERR " $elem->[1]\n"; } } ' "$topic" "$not_in_next" "$not_in_master" exit 1 fi <<\DOC_END This sample hook safeguards topic branches that have been published from being rewound. The workflow assumed here is: * Once a topic branch forks from "master", "master" is never merged into it again (either directly or indirectly). * Once a topic branch is fully cooked and merged into "master", it is deleted. If you need to build on top of it to correct earlier mistakes, a new topic branch is created by forking at the tip of the "master". This is not strictly necessary, but it makes it easier to keep your history simple. * Whenever you need to test or publish your changes to topic branches, merge them into "next" branch. The script, being an example, hardcodes the publish branch name to be "next", but it is trivial to make it configurable via $GIT_DIR/config mechanism. With this workflow, you would want to know: (1) ... if a topic branch has ever been merged to "next". Young topic branches can have stupid mistakes you would rather clean up before publishing, and things that have not been merged into other branches can be easily rebased without affecting other people. But once it is published, you would not want to rewind it. (2) ... if a topic branch has been fully merged to "master". Then you can delete it. More importantly, you should not build on top of it -- other people may already want to change things related to the topic as patches against your "master", so if you need further changes, it is better to fork the topic (perhaps with the same name) afresh from the tip of "master". Let's look at this example: o---o---o---o---o---o---o---o---o---o "next" / / / / / a---a---b A / / / / / / / / c---c---c---c B / / / / \ / / / / b---b C \ / / / / / \ / ---o---o---o---o---o---o---o---o---o---o---o "master" A, B and C are topic branches. * A has one fix since it was merged up to "next". * B has finished. It has been fully merged up to "master" and "next", and is ready to be deleted. * C has not merged to "next" at all. We would want to allow C to be rebased, refuse A, and encourage B to be deleted. To compute (1): git rev-list ^master ^topic next git rev-list ^master next if these match, topic has not merged in next at all. To compute (2): git rev-list master..topic if this is empty, it is fully merged to "master". DOC_END ejabberd-2.1.11/.git/hooks/commit-msg.sample0000775000000000000000000000160012240230175015461 0ustar #!/bin/sh # # An example hook script to check the commit log message. # Called by "git commit" with one argument, the name of the file # that has the commit message. The hook should exit with non-zero # status after issuing an appropriate message if it wants to stop the # commit. The hook is allowed to edit the commit message file. # # To enable this hook, rename this file to "commit-msg". # Uncomment the below to add a Signed-off-by line to the message. # Doing this in a hook is a bad idea in general, but the prepare-commit-msg # hook is more suited to it. # # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" # This example catches duplicate Signed-off-by lines. test "" = "$(grep '^Signed-off-by: ' "$1" | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { echo >&2 Duplicate Signed-off-by lines. exit 1 } ejabberd-2.1.11/.git/config0000664000000000000000000000057512240230175012256 0ustar [user] email = rhonda@debian.org signingkey = DD079461 [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = ssh://git@git.deb.at/pkg/ejabberd.git [branch "master"] remote = origin merge = refs/heads/master [branch "wheezy"] remote = origin merge = refs/heads/wheezy ejabberd-2.1.11/.git/logs/0000775000000000000000000000000012240452476012035 5ustar ejabberd-2.1.11/.git/logs/HEAD0000664000000000000000000000225312240230175012451 0ustar 0ea99c66cdaba71358752a3a211d27137df52bdf dbe8f65123c4c5166405a3d24dd84f7c96c99c37 Gerfried Fuchs 1363518391 +0100 pull: Fast-forward dbe8f65123c4c5166405a3d24dd84f7c96c99c37 305e14c0ec9f2391b1b7149e5629c535d066368b Gerfried Fuchs 1382461430 +0200 pull: Fast-forward 305e14c0ec9f2391b1b7149e5629c535d066368b 8d11f756c70cd512eb2c73669fc514a1fb1418fc Gerfried Fuchs 1382461430 +0200 checkout: moving from wheezy to master 8d11f756c70cd512eb2c73669fc514a1fb1418fc fb32527514b30464c23cfafb7758fb3da49dd9a1 Gerfried Fuchs 1382461463 +0200 merge origin/master: Fast-forward fb32527514b30464c23cfafb7758fb3da49dd9a1 bfe1faa3c8bb67642331925df54606f94b3e6f07 Gerfried Fuchs 1382475370 +0200 commit: relax-digest-uri-handling patch obsolete bfe1faa3c8bb67642331925df54606f94b3e6f07 119ba312536cc93221324a38ef9da3309dab73d8 Gerfried Fuchs 1382475494 +0200 commit: fix-parsing-split-https-requests patch obsolete 119ba312536cc93221324a38ef9da3309dab73d8 979a86afb341caf60007e1afebc99cf20f0929f1 Gerfried Fuchs 1382475633 +0200 commit: fix-odbc-escaping patch obsolete ejabberd-2.1.11/.git/logs/refs/0000775000000000000000000000000012240452476012774 5ustar ejabberd-2.1.11/.git/logs/refs/heads/0000775000000000000000000000000012240452476014060 5ustar ejabberd-2.1.11/.git/logs/refs/heads/wheezy0000664000000000000000000000046212240230175015306 0ustar 0ea99c66cdaba71358752a3a211d27137df52bdf dbe8f65123c4c5166405a3d24dd84f7c96c99c37 Gerfried Fuchs 1363518391 +0100 pull: Fast-forward dbe8f65123c4c5166405a3d24dd84f7c96c99c37 305e14c0ec9f2391b1b7149e5629c535d066368b Gerfried Fuchs 1382461430 +0200 pull: Fast-forward ejabberd-2.1.11/.git/logs/refs/heads/master0000664000000000000000000000131412240230175015263 0ustar 8d11f756c70cd512eb2c73669fc514a1fb1418fc fb32527514b30464c23cfafb7758fb3da49dd9a1 Gerfried Fuchs 1382461463 +0200 merge origin/master: Fast-forward fb32527514b30464c23cfafb7758fb3da49dd9a1 bfe1faa3c8bb67642331925df54606f94b3e6f07 Gerfried Fuchs 1382475370 +0200 commit: relax-digest-uri-handling patch obsolete bfe1faa3c8bb67642331925df54606f94b3e6f07 119ba312536cc93221324a38ef9da3309dab73d8 Gerfried Fuchs 1382475494 +0200 commit: fix-parsing-split-https-requests patch obsolete 119ba312536cc93221324a38ef9da3309dab73d8 979a86afb341caf60007e1afebc99cf20f0929f1 Gerfried Fuchs 1382475633 +0200 commit: fix-odbc-escaping patch obsolete ejabberd-2.1.11/.git/logs/refs/remotes/0000775000000000000000000000000012240452476014452 5ustar ejabberd-2.1.11/.git/logs/refs/remotes/origin/0000775000000000000000000000000012240452476015741 5ustar ejabberd-2.1.11/.git/logs/refs/remotes/origin/wheezy0000664000000000000000000000046212240230175017167 0ustar 0ea99c66cdaba71358752a3a211d27137df52bdf dbe8f65123c4c5166405a3d24dd84f7c96c99c37 Gerfried Fuchs 1363518391 +0100 pull: fast-forward dbe8f65123c4c5166405a3d24dd84f7c96c99c37 305e14c0ec9f2391b1b7149e5629c535d066368b Gerfried Fuchs 1382461430 +0200 pull: fast-forward ejabberd-2.1.11/.git/logs/refs/remotes/origin/experimental0000664000000000000000000000023112240230175020343 0ustar c352294f1784ba02dc2822a388c5c7cb7e78231d 29f186ef161665c52bac88191f73bad5aef02a1d Gerfried Fuchs 1382461430 +0200 pull: fast-forward ejabberd-2.1.11/.git/logs/refs/remotes/origin/squeeze0000664000000000000000000000023112240230175017327 0ustar d133f4af9a0461b4d6b38a8617cd73d1b1e4cde9 6716aa6b176e4e79158e5e43f3e6e487eaf1ee15 Gerfried Fuchs 1382461430 +0200 pull: fast-forward ejabberd-2.1.11/.git/logs/refs/remotes/origin/HEAD0000664000000000000000000000000012240230175016341 0ustar ejabberd-2.1.11/.git/logs/refs/remotes/origin/master0000664000000000000000000000045612240230175017152 0ustar 8d11f756c70cd512eb2c73669fc514a1fb1418fc fb32527514b30464c23cfafb7758fb3da49dd9a1 Gerfried Fuchs 1382461430 +0200 pull: fast-forward fb32527514b30464c23cfafb7758fb3da49dd9a1 979a86afb341caf60007e1afebc99cf20f0929f1 Gerfried Fuchs 1382478984 +0200 update by push ejabberd-2.1.11/.git/ORIG_HEAD0000664000000000000000000000005112240230175012317 0ustar 8d11f756c70cd512eb2c73669fc514a1fb1418fc ejabberd-2.1.11/.git/index0000664000000000000000000011425012240230175012114 0ustar DIRCOVOVND ST0*_8aUnG. .gitignoreOVOVOFЋ2_S x #|PCOPYINGRfRfPTIL%/E^6;READMEOVOVԡ~7^&XE contrib/ejabberd-modules.repoOVOVxeԙY%d =#contrib/extract_translations/READMERfRfĐQucfD75contrib/extract_translations/extract_translations.erlOVOV#-Tiv|)=pP3contrib/extract_translations/prepare-translation.shRfRfͤ<ӺZ#L89)"|S debian/NEWSRfRfArЕA'E@ 5debian/README.DebianOVOVx5VMi%pmӺB&}q'Vdebian/README.sourceOVOV yޔuUK7pV H debian/TODORf\Rf\e'}p1t1:%debian/changelogOVOV=`C۝,( debian/compatOVOVs}tl,./N debian/configOVOV"]2lWGHўvu2debian/controlOVOVjZ4rq{Jek+w5debian/copyrightOVOVٿj>J_@h9ldebian/defaultOVOV"/3՗z debian/dirsOVOVX4:M,ul+>װ#6bTdebian/doc-baseOVOV RF!O*+ debian/docsOVOV5]wIh3˜debian/ejabberd.8OVOVB_ ] LD2fdebian/ejabberd.cfgOVOVqއ֓"9debian/ejabberdctl.8OVOV3sc=OR%debian/examplesOVOV y!JT(&*P\ debian/init.dOVOVpPs 3y*!/kA{ɞ)debian/installRfRfR\I-kp#nN6debian/logrotateOVOV(rc/+DnPN8bdebian/manpagesOVOV1}Φh5|]SW\debian/patches/captcha.patchRfRfSOIqfy/4@ڽ/>1debian/patches/disable-insecure-ssl-cyphers.patchRfRfTAu/$1M5 6Zx!debian/patches/disable-ssl2.patchOVOV DQO6]\s$debian/patches/ejabberd_regexp.patchRfRfUz8 5T/debian/patches/fix-ldap-vcard-jpeg-photos.patchOVOV['[K,p&z|qo!debian/patches/fix_examples.patchRfRf `E%l? H\$debian/patches/mod_admin_extra.patchRfRf&Q]05!debian/patches/reopen-log.patchRfRfYL/k ¤/{Ldebian/po/cs.poOVOV }nTN!A0s F ү&_debian/po/templates.potOVOVTe2y28R5debian/po/tr.poOVOVX΂^#]XOS-debian/po/vi.poOVOV,+10KėNѐ'debian/postinstOVOVvKA&*{0{F3B debian/postrmRfRfpXұ9$ߎ?> debian/prermOVOV Wvm8 vp debian/rulesOVOV є,:~cwPdebian/scripts/ejabberdOVOVU5ՇLRuκWdebian/scripts/ejabberdctlOVOV վ%EV<odebian/templatesOVOV{u<p. 8d}$, debian/watchOVOVUJy0ht8@=ݚH doc/MakefileOVOV5n 1~3zWLkdoc/api/MakefileRfRfF 6ખܤBLdoc/api/overview.edocOVOV\q1#ؠ&8qp!doc/api/process-one.cssRfRfG[LR, Y  - doc/dev.htmlOVOV5Nc\B7%2Idoc/release_notes_2.1.1.txtOVOV"[vqdoc/release_notes_2.1.10.txtRfRfD_ $ޝf~sѷT doc/release_notes_2.1.11.txtOVOV$VX6N>8sdoc/release_notes_2.1.2.txtOVOV% ,&7҈L]өhdoc/release_notes_2.1.3.txtOVOV& KKɫ'&QyWrrdoc/release_notes_2.1.4.txtOVOV' u;E-jq:sH.doc/release_notes_2.1.5.txtOVOV( d*;˥I]aXdoc/release_notes_2.1.6.txtOVOV)T?L"Kyfzc\`Ўtdoc/release_notes_2.1.7.txtOVOV*>H*d+3:ua,Pdoc/release_notes_2.1.8.txtOVOV+Gw̚7ps|z?doc/release_notes_2.1.9.txtRfRfL:YNԇ:xDW doc/version.texOVOV-"(ֆZDﺜ[Udoc/webadmmain.pngOVOV.3?J1I8|1$Ҙ2hdoc/webadmmainru.pngOVOV/tۈ@=Hp=ݞdoc/yozhikheader.pngOVOV2y #tW-o]I FP#examples/extauth/check_pass_null.plRfRf4lC(ixnՠ'QW!lexamples/mtr/ejabberdRfRf5QɼOM~\^ s examples/mtr/ejabberd-netbsd.shOVOV6oOK(BJ}SXTPexamples/mtr/ejabberd.cfgOVOV9ALij~݌NP`~Us4examples/transport-configs/configs/aim-transport.xmlOVOV:Ye {C{QJt*examples/transport-configs/configs/ile.xmlOVOV;9L-^(H(5z:examples/transport-configs/configs/jabber-gg-transport.xmlOVOV<'׌@#?o]*examples/transport-configs/configs/jit.xmlOVOV=9BhMttn4g4examples/transport-configs/configs/msn-transport.xmlOVOV> -zI au׉8examples/transport-configs/configs/yahoo-transport-2.xmlOVOV@=erкz56J"5examples/transport-configs/init-scripts/aim-transportOVOVAr,W:#pq+examples/transport-configs/init-scripts/ileOVOVB&ޕ $Do;examples/transport-configs/init-scripts/jabber-gg-transportOVOVCU{we Nz}+examples/transport-configs/init-scripts/jitOVOVD|U[} ݴc%)s5examples/transport-configs/init-scripts/msn-transportOVOVE犑:0zTsY;9examples/transport-configs/init-scripts/yahoo-transport-2RfRfGB[/$~ky/LV(src/Makefile.inRfRf!]T WÁsrc/Makefile.win32OVOVIP _yYVeausrc/XmppAddr.asn1RfRfJ(b ͐O src/acinclude.m4RfRf6|DmѴ>(j*Mk src/acl.erlRfRfE^[~cI K| src/adhoc.erlRfRfEL֐YLͼ src/adhoc.hrlRfRfDv@bT1u\>_src/cache_tab.erlRfRfqj#v Ҩu$2src/cache_tab_sup.erlOVOVP,j}=(,Rco,}src/config.guessOVOVQ^hyxsrc/config.subRfRfw*_lפˏ3ޥ src/configureOVOVSz%݇BOQozsrc/configure.acOVOVT/F=u_$wpNzsrc/configure.batRfRf Uܵ `ၕ,src/configure.erlRfRf#r?;͗M 5Msrc/cyrsasl.erlRfRf%lNsxwT>src/cyrsasl_anonymous.erlRf¦Rf¦J{t&;]7vsrc/cyrsasl_digest.erlRfRf (Oխ?VټP2hsrc/cyrsasl_plain.erlRfRft{<w"|ä(src/cyrsasl_scram.erlOVOV[6&ܪMߜdjy>F src/dynamic_compile.erlRfRf /`I|2nsrc/ejabberd.appRf¦Rf¦9hwOB2mbsrc/ejabberd.cfg.exampleRfRfNyꤟX*Vsrc/ejabberd.erlRfRf }UFpG}צ\7src/ejabberd.hrlOVOV`QiK0{]N k*@src/ejabberd.init.templateRfRfP]ؚ|US_src/ejabberd_admin.erlRfRfF|Cehۊ)src/ejabberd_app.erlRfRf.sȾLjuF:-d src/ejabberd_auth.erlRfRfW7F87UJ=[6<src/ejabberd_auth_anonymous.erlRfRf'qUH 7a"@src/ejabberd_auth_external.erlRfRf6](: S(:,ήxsrc/ejabberd_auth_internal.erlRfRf6 }ƊLT;#1Xtsrc/ejabberd_auth_ldap.erlRfRfeƁܚlJAGC˾src/ejabberd_auth_odbc.erlRfRf ‘3>2U,I_7uňsrc/ejabberd_auth_pam.erlRfRf U*۷>8<6R|hAsrc/ejabberd_c2s.erlRfRf $Bf[" O.#src/ejabberd_c2s_config.erlRfRfJ5/y&src/ejabberd_captcha.erlRfRf$R5Mzau3>khisrc/ejabberd_check.erlRfRf9!ZmvBd`.#0;src/ejabberd_commands.erlRfRfW2ҕl5Wasrc/ejabberd_commands.hrlRf¦Rf¦LP57oYv9ot=؇[1src/ejabberd_config.erlRfRfiLmQR3cksrc/ejabberd_config.hrlRfRfc,δMppTv͋*Mb|src/ejabberd_ctl.erlRfRfFk 4RRXsAsrc/ejabberd_ctl.hrlRfRf,* |բsIG%ћ src/ejabberd_frontend_socket.erlRfRf,^p?ʰBBX߶Եsrc/ejabberd_hooks.erlRfRf=%|#wR:ւp!F1esrc/ejabberd_listener.erlRfRf/=FFvyB*W{hsrc/ejabberd_local.erlRfRf O@jU,:,VcH`e FYHsrc/ejabberd_logger_h.erlRfRfy%Q1 <src/ejabberd_loglevel.erlRfRfk}7;0fL5Xsrc/ejabberd_node_groups.erlRfRfY:SZ>[src/ejabberd_piefxis.erlRfRf &vp0Ԛ=6src/ejabberd_rdbms.erlRfRf0,XQBB*#bxUsrc/ejabberd_receiver.erlRfRf 0|a4H&src/ejabberd_regexp.erlRfRf/b8ۢ5>{src/ejabberd_router.erlRfRfHՒؾ;RBHoJYsrc/ejabberd_s2s.erlRfRfg q5KS9<src/ejabberd_s2s_in.erlRfRfeq@ T?OIsrc/ejabberd_s2s_out.erlRfRf4t $˷4^-ohsrc/ejabberd_service.erlRfRf cҖ1*JN!;Frsrc/ejabberd_sm.erlRfRf %GQ4ẖ]osrc/ejabberd_socket.erlRfRf ><AwnBN'O~src/ejabberd_sup.erlRfRf .rSY2f+BoUsrc/ejabberd_system_monitor.erlRfRf]5jnd>"O7src/ejabberd_tmp_sup.erlRfRfpurLɋWi_َIsrc/ejabberd_update.erlOVOVe[&j L>&[src/ejabberd_zlib/Makefile.inRfRfA߃ ?Pv惬"# src/ejabberd_zlib/Makefile.win32RfRf JE5O.5T#src/ejabberd_zlib/ejabberd_zlib.erlRfRf&rvA {4EV0%src/ejabberd_zlib/ejabberd_zlib_drv.cOVOVh X69ƫHFؒsrc/ejabberdctl.cfg.exampleOVOV' `E[4Jsrc/ejabberdctl.templateRfRfO337g] !<%F(src/ejd2odbc.erlOVOV)5̀Ct(gC+"src/eldap/ELDAPv3.asnOVOVZ vh;RB}Csrc/eldap/Makefile.inOVOVT9@U0[=M src/eldap/Makefile.win32RfRf&XEYLS/@`?6src/eldap/eldap.erlRfRfH͗8aUV~g9src/eldap/eldap.hrlRfRf  LeIL {1NKsrc/eldap/eldap_filter.erlOVOV Ψ fNtZsrc/eldap/eldap_filter_yecc.yrlRfRf# wȺ5S+src/eldap/eldap_pool.erlRfRf$!4Vr&o^#'.src/eldap/eldap_utils.erlRfRf%+}ҹ. C/.bsrc/expat_erl.cRfRf&+:C*Dcsrc/extauth.erlRfRf'Z_b٦y osrc/gen_iq_handler.erlRfRf(NILNK̚/5Bsrc/gen_mod.erlRfRf)Kܩbyl$= src/idna.erlOVOVos@+hžjJy src/inetrcOVOV5_g#eJ67src/install-shRfRf*pyOFa.(X!u0src/jd2ejd.erlRfRf-TU)cpy7!; src/jlib.erlRfRf/8ˮXbcu^SĦz src/jlib.hrlRfRf0"M$`LbEX=q src/mod_adhoc.erlRfRf1zӘ³f{6*j9pd=Xsrc/mod_announce.erlRfRft)dwǿTsrc/mod_announce_odbc.erlRfRf2&)^*`"`i(=u֓Æsrc/mod_blocking.erlRfRf7nyEj"qS3src/mod_blocking_odbc.erlRfRf4GNu\ossrc/mod_caps.erlRfRf5)'lCU=DO7src/mod_configure.erlRfRf6?Dۧ}ns,M src/mod_configure2.erlRfRf7>Xz9Ɂ骰%src/mod_disco.erlRfRf8 S|Eٗsrc/mod_echo.erlRfRf9Dب*!^3sޱj{src/mod_ip_blacklist.erlRfRfU힞pAȡ|src/mod_irc/Makefile.inRfRf<p}iqS+ W\Wsrc/mod_irc/Makefile.win32RfRf> 4?gG[:f^u*p x]src/mod_irc/iconv.erlRfRf?T.DU U'2gO!_src/mod_irc/iconv_erl.cRfRfA/ځ#u=_src/mod_irc/mod_irc.erlRfRfB)|bO-QTK"src/mod_irc/mod_irc_connection.erlRfRfOݫD> 6PARnN)src/mod_irc/mod_irc_odbc.erlRfRfC1mG 8BK efe/[src/mod_last.erlRfRfDdDfGg>s%[>src/mod_last_odbc.erlOVOVA1ZҐ2[={Isrc/mod_muc/Makefile.inRfRfE0'%Gz: src/mod_muc/Makefile.win32RfRfFtVW=41M!Q֛src/mod_muc/mod_muc.erlRfRfG`5p[VJkƛsrc/mod_muc/mod_muc_log.erlRfRfPtGLvCն[D+src/mod_muc/mod_muc_odbc.erlRfRfH}Qu^\P#Pͧ4src/mod_muc/mod_muc_room.erlRfRfI ,CYÍ@src/mod_muc/mod_muc_room.hrlRfRfJNT Lċsrc/mod_private.erlRfRfSNE/kZpȰmsrc/mod_private_odbc.erlOVOV8:.ײN'Ca8src/mod_proxy65/Makefile.inOVOVv };,</~FDELsrc/mod_proxy65/Makefile.win32RfRfT zIRnj~src/mod_proxy65/mod_proxy65.erlRfRfUP#Tǡjsrc/mod_proxy65/mod_proxy65.hrlRfRfV ,ZׇI=ly#src/mod_proxy65/mod_proxy65_lib.erlRfRfWBE9{W£$)'src/mod_proxy65/mod_proxy65_service.erlRfRfX)}8ٸCO,Aj"src/mod_proxy65/mod_proxy65_sm.erlRfRfY#} A|G.'qǁ&&src/mod_proxy65/mod_proxy65_stream.erlOVOV{b_^l T}src/mod_pubsub/Makefile.inOVOV wBDks,src/mod_pubsub/Makefile.win32RfRf\ [ 4޽ozs ]1"src/mod_pubsub/gen_pubsub_node.erlRfRf]R&aQ/r-Czɧ&src/mod_pubsub/gen_pubsub_nodetree.erlRfRf^BޖV>*7uu<src/mod_pubsub/mod_pubsub.erlRfRf_.0mnHN(P_"src/mod_pubsub/mod_pubsub_odbc.erlRfRf`(Q:>ګY͉src/mod_pubsub/node.templateRfRfa_9N'QWćsrc/mod_pubsub/node_buddy.erlRfRff}-vBrָ},^src/mod_pubsub/node_club.erlOVOViF3pG2ϗFƘhRsrc/mod_pubsub/node_dag.erlRfRfi X}sU/z4 (Csrc/mod_pubsub/node_flat.erlRfRfls 7sksqOem!src/mod_pubsub/node_flat_odbc.erlRfRfq2ʪq"=*(U src/mod_pubsub/node_hometree.erlRfRf}"* + %src/mod_pubsub/node_hometree_odbc.erlRfRf<)`-ߚW H"dEsrc/mod_pubsub/node_mb.erlRfRf$-ZE;יf@PexD!ksrc/mod_pubsub/node_pep.erlRfRf+h[3wTA*oNu+ src/mod_pubsub/node_pep_odbc.erlRfRf՘G xJEH{FP<src/mod_pubsub/node_private.erlRfRfÆG)ksrc/mod_pubsub/node_public.erlOVOVHptʼJaUfbo&(jkqWsrc/mod_pubsub/nodetree_dag.erlRfRf"fWk! A'vu src/mod_pubsub/nodetree_tree.erlRfRf-*;yʼnBQz%src/mod_pubsub/nodetree_tree_odbc.erlRfRfw%-!YTy!sI#src/mod_pubsub/nodetree_virtual.erlRfRfAo\npVrsrc/mod_pubsub/pubsub.hrlRfRf6p,݀Sg+P!src/mod_pubsub/pubsub_db_odbc.erlRfRf U*mh4oRsrc/mod_pubsub/pubsub_index.erlRfRf (ɱ'c src/mod_pubsub/pubsub_odbc.patchRfRf#.FYESуthXL&src/mod_pubsub/pubsub_subscription.erlRfRf,*&MFԎ}6+src/mod_pubsub/pubsub_subscription_odbc.erlRfRfHJn፾+wř%JV`src/mod_register.erlRfRfK3?nq%zsrc/mod_roster.erlRfRfLd~ʯ fst6src/mod_roster.hrlRfRfM, QoϪ:@src/mod_roster_odbc.erlRfRfN 5F6DRHt.src/mod_service_log.erlRfRfOݗ~8W^f`;src/mod_shared_roster.erlRfRfRZyKcnNI d src/mod_shared_roster_ldap.erlRfRfQ#WP~gH@Uxz-2*src/mod_shared_roster_odbc.erlRfRfU nݘz2g!;psrc/mod_sic.erlRfRfV(d 9AԎsrc/mod_stats.erlRfRfW ^.~rQ $>uE;src/mod_time.erlRfRfXhԷ7_Q4sP4_ޒͳsrc/mod_vcard.erlRfRfYc&m35d7Wsrc/mod_vcard_ldap.erlRfRfZTrܷ[>/>src/mod_vcard_odbc.erlOVOVC8P)6Gsrc/msgs/id.msgRfRfp7mY_ߑ>\src/msgs/id.poRfRfqpWyaH(1VWsrc/msgs/it.msgRfRfr,Zغ'^p3src/msgs/it.poRfRfsx0Zb W˕0Zsrc/msgs/ja.msgRfRftx\# P7\eUasrc/msgs/ja.poRfRfumLp9w?dsM8src/msgs/nl.msgRfRfvۈQ5؛Ϯ{5^src/msgs/nl.poRfRfwh^x|A/8S\qsrc/msgs/no.msgRfRfxйH4HX[Z5~src/msgs/no.poRfRfylyK0bN+FOUVsrc/msgs/pl.msgRfRfzԭyct5LNsrc/msgs/pl.poRfRf{ic5;qŖTf Rsrc/msgs/pt-br.msgRfRf|۹gM& dbC6Lsrc/msgs/pt-br.poOVOV%|?g8DUqsrc/msgs/pt.msgRfRf}KVFGHsrc/msgs/pt.poRfRf~4Gx$rJ븕@src/msgs/ru.msgRfRf' lHgVu)>-}src/msgs/ru.poRfRfZ z<y3ke˸src/msgs/sk.msgRfRf*]ρ|LaTnnsrc/msgs/sk.poRfRfR3[7>^`c+src/msgs/sv.msgRfRfj]@04s΍RS~src/msgs/sv.poOVOV-i/䋷^w^ ,nsrc/msgs/th.msgRfRfH %ϚC)b3?!src/msgs/th.poRfRfn3޴s2ҥΆsrc/msgs/tr.msgRfRf!SЌf@}*]߰src/msgs/tr.poRfRfn! P~ePsrc/msgs/uk.msgRfRf&8aP;Q*7src/msgs/uk.poOVOV3J1 H R B: src/msgs/vi.msgRfRfL4q-)4z<[ňsrc/msgs/vi.poOVOV5In/LuT &d2 src/msgs/wa.msgRfRfF+"DVdBdқ/Msrc/msgs/wa.poRfRfa6Orx;gBV}d=src/msgs/zh.msgRfRfϷѧj.*!b Ǎ7.src/msgs/zh.poOVOV:D9S)&YOzsrc/odbc/Makefile.inOVOV;'uFq . tsrc/odbc/Makefile.win32RfRfJjAKj%*K"9 Psrc/odbc/ejabberd_odbc.erlRfRf 2wRo/NƏsrc/odbc/ejabberd_odbc_sup.erlRfRfaP.z&8" L@src/odbc/mssql2000.sqlRfRf%C㞂8P6ϗsrc/odbc/mssql2005.sqlRfRf#a &z78Y,jV src/odbc/mysql.sqlRfRfs!>ñZVn;[src/odbc/odbc_queries.erlRfRf؍=|3g|esrc/odbc/pg.sqlRfRfpB<Y-r*src/p1_fsm.erlRfRf.%R|%KIUyKsrc/p1_mnesia.erlRfRf$ &qԫǩdY7src/p1_prof.erlOVOVGt7=@XTQ-Esrc/pam/Makefile.inRfRfJ/l2T,pVŻsrc/pam/epam.cRfRf7*V(VG+׷msrc/pam/epam.erlOVOVJ)=uRM3eݦEKVsrc/pg2_backport.erlRfRf:vcFWnHsrc/randoms.erlRfRf ׈{c!+=iN src/scram.erlRfRf l28u66G src/sha.erlRfRf ,Xa<0ꕘKsrc/shaper.erlRfRfP+x6,mDg52@-rZzsrc/stringprep/Makefile.inRfRfDӧ~%eaJ2>src/stringprep/Makefile.win32RfRf x- ^+ke Rr-src/stringprep/stringprep.erlRfRf)Ƒt*tgQQsrc/stringprep/stringprep_drv.cRfRf o?dz?R곫qw4!src/stringprep/stringprep_sup.erlOVOVV3vʽrp87uJB,src/stringprep/uni_data.cOVOVWBQuu@QmJ4;oˁ' Bsrc/stringprep/uni_norm.cOVOVX'1 Ħg|Lssrc/stringprep/uni_parse.tclOVOVYC˒Rd*sLBZb+src/stringprep/uni_parse2.tclOVOV[g⍕=mq*$ksrc/stun/Makefile.inOVOV\X )zeqV@src/stun/Makefile.win32RfRf/u-2~_Dsrc/stun/ejabberd_stun.erlRfRf ^*NLP bXc͵src/stun/stun.hrlRfRf(5m{̀7r㌮>src/stun/stun_codec.erlOVOVhU@>OgYTI&src/tls/Makefile.inRfRf۠[EGHJ&src/tls/Makefile.win32RfRf͹9Ŗi#~hHG src/tls/sha_drv.cOVOVk2:cŒk5,[GgBsrc/tls/stdint.hRfRf-&F 'qz!2fcvy ksrc/tls/tls.erlRfRf7(m̾s?ֱn iQsrc/tls/tls_drv.cRfRfǤ*EdWY{6LOsrc/translate.erlRfRf"[?$ilۀрx src/treap.erlOVOVqHwA M:="ũOsrc/web/Makefile.inOVOVrAWΈHԦA9!=src/web/Makefile.win32RfsRfs?&}X<ͦ>~(src/web/ejabberd_http.erlRfRf}|GlD?*src/web/ejabberd_http.hrlRfRf-8\+!}˛~/Nsrc/web/ejabberd_http_bind.erlRfRf90ɦatYvsrc/web/ejabberd_http_poll.erlRfRf -BAm.×?gsrc/web/ejabberd_web.erlRfRfIXDy&aj]:bܘwۚsrc/web/ejabberd_web_admin.erlRfRf s"o7A'('src/web/ejabberd_web_admin.hrlRfRfC7AeI*ye!:qsrc/web/http_bind.hrlRfRf"@Phs+|ЭFbusrc/web/mod_http_bind.erlRfRfEK%6{?o5"wsrc/web/mod_http_fileserver.erlRfRfQ@UIb4ʬJsrc/web/mod_register_web.erlOVOV5_ٝdP>pHusrc/win32/CheckReqs.iniOVOV[v㮾Bm%kcssrc/win32/CheckReqs1.iniOVOV`6f@lksrc/win32/CheckReqs1H.iniOVOV6vH2F?ܡW L]<src/win32/CheckService.iniOVOV#3R֝*Mr)h!qsrc/win32/CheckUser.iniOVOV^t*^06fUNsrc/win32/CheckUserH.iniOVOV{9Z0ysrc/win32/ejabberd.cfgOVOV W-AΨLY"Ensrc/win32/ejabberd.icoOVOVA&aٿ\>ķ Nsrc/win32/ejabberd.nsiOVOV (!8:src/win32/ejabberd_header.bmpOVOVg~{7x  Gz_L src/win32/ejabberd_intro.bmpOVOVI.zicZsrc/win32/inetrcRfRfՊٓJ֠Ӈ/ src/win32_dns.erlOVOVcLx C/4P src/xml.cRfRfjOjv3,+rĘ src/xml.erlRfRf.G"ʣS4 3src/xml_stream.erlRfRf]V iRL`)z tools/captcha.shOVOV/jN wdkGyBtools/jhbtest.plTb,͡.;;rY|ejabberd-2.1.11/.git/HEAD0000664000000000000000000000002712240230175011502 0ustar ref: refs/heads/master ejabberd-2.1.11/.git/COMMIT_EDITMSG0000664000000000000000000000004112240230175013141 0ustar fix-odbc-escaping patch obsolete ejabberd-2.1.11/.git/refs/0000775000000000000000000000000012240452476012030 5ustar ejabberd-2.1.11/.git/refs/tags/0000775000000000000000000000000012240452476012766 5ustar ejabberd-2.1.11/.git/refs/tags/debian/0000775000000000000000000000000012240452476014210 5ustar ejabberd-2.1.11/.git/refs/tags/debian/2.1.5-3+squeeze20000664000000000000000000000005112240230175016457 0ustar 7781c1a6ef4d70a96ecc818c78f439c9456a02a5 ejabberd-2.1.11/.git/refs/tags/debian/2.1.10-4+deb7u10000664000000000000000000000005112240230175016060 0ustar daab52b0d0cc3d5b535eac10dcbf73483c2d7652 ejabberd-2.1.11/.git/refs/tags/debian/2.1.10-40000664000000000000000000000005112240230175014775 0ustar eda805df3b81bbf8b53b4694106c444fed44484c ejabberd-2.1.11/.git/refs/tags/debian/2.1.10-50000664000000000000000000000005112240230175014776 0ustar f6a0e318c8372d001fcb79a96d0fce2fa42266ab ejabberd-2.1.11/.git/refs/heads/0000775000000000000000000000000012240452476013114 5ustar ejabberd-2.1.11/.git/refs/heads/wheezy0000664000000000000000000000005112240230175014334 0ustar 305e14c0ec9f2391b1b7149e5629c535d066368b ejabberd-2.1.11/.git/refs/heads/master0000664000000000000000000000005112240230175014314 0ustar 979a86afb341caf60007e1afebc99cf20f0929f1 ejabberd-2.1.11/.git/refs/remotes/0000775000000000000000000000000012240452476013506 5ustar ejabberd-2.1.11/.git/refs/remotes/origin/0000775000000000000000000000000012240452476014775 5ustar ejabberd-2.1.11/.git/refs/remotes/origin/wheezy0000664000000000000000000000005112240230175016215 0ustar 305e14c0ec9f2391b1b7149e5629c535d066368b ejabberd-2.1.11/.git/refs/remotes/origin/experimental0000664000000000000000000000005112240230175017377 0ustar 29f186ef161665c52bac88191f73bad5aef02a1d ejabberd-2.1.11/.git/refs/remotes/origin/squeeze0000664000000000000000000000005112240230175016363 0ustar 6716aa6b176e4e79158e5e43f3e6e487eaf1ee15 ejabberd-2.1.11/.git/refs/remotes/origin/HEAD0000664000000000000000000000004012240230175015401 0ustar ref: refs/remotes/origin/master ejabberd-2.1.11/.git/refs/remotes/origin/master0000664000000000000000000000005112240230175016175 0ustar 979a86afb341caf60007e1afebc99cf20f0929f1 ejabberd-2.1.11/.git/packed-refs0000664000000000000000000002057112240230175013173 0ustar # pack-refs with: peeled 8d11f756c70cd512eb2c73669fc514a1fb1418fc refs/heads/master 0ea99c66cdaba71358752a3a211d27137df52bdf refs/heads/wheezy 11b9b259b92d538b5a59cdccf259f656c69fec62 refs/remotes/origin/debconf-perl c352294f1784ba02dc2822a388c5c7cb7e78231d refs/remotes/origin/experimental cbe90ebb05573f7c3f27f32fa9aef1fa06fc3902 refs/remotes/origin/fnmatch 383e2687748fd21c0bc288b3b2f93c5f15c473df refs/remotes/origin/lenny 8704f4ee40845e61b162b1a2779a546a8348c991 refs/remotes/origin/lenny-backports 5eae550cd084389afb4a8534dd574ca3f235f811 refs/remotes/origin/lucid 8d11f756c70cd512eb2c73669fc514a1fb1418fc refs/remotes/origin/master 2b1be0fc9c6da13b9b6ca295b7c202525b9361bd refs/remotes/origin/precise be547edb9efa59653c7abb08e5d9a49898aee5a5 refs/remotes/origin/pristine-tar d133f4af9a0461b4d6b38a8617cd73d1b1e4cde9 refs/remotes/origin/squeeze 7c6629c5619bdb039a87af6bb89c6b47ca72926a refs/remotes/origin/upstream 0ea99c66cdaba71358752a3a211d27137df52bdf refs/remotes/origin/wheezy 2f15f9fd0f5f9925e524dfc31645844a32ebb0c1 refs/tags/debian/1.0.0-2 d8b7809515a902c25d0f743ca2f0ec8110e607e4 refs/tags/debian/1.1.1-1 55235538210388605f4a7a7efc8d6f512ee35b05 refs/tags/debian/1.1.1-2 c17535e1352de6070b768810c588e336b12998c7 refs/tags/debian/1.1.1-3 751e1c30dfcd01f9098bf2f993340826fde9873f refs/tags/debian/1.1.1-4 ffccca32bf6ddb4b49af50931d39dfc66e0af7b7 refs/tags/debian/1.1.1-5 8de40fb22edcebe58c67f6c5a983425f592cfca4 refs/tags/debian/1.1.1-6 4e98eeada4486a94ae6adec5c18235a6febf967a refs/tags/debian/1.1.1-7 9a390b0c7d3000dc7e9421d89792718ec119bc57 refs/tags/debian/1.1.1-8 73dc1f8ee9f9b330b59c3d15f023c2b09f9b9b41 refs/tags/debian/1.1.1-9 c3c8f9fd5722f22cc8e4fa63eec0d04ba19da82c refs/tags/debian/1.1.2-1 747b00eb0ee4a424ae8cc477548bd0626ac58244 refs/tags/debian/1.1.2-10 f4f2d3d76afa7257c06b61c667b8ad58556abd57 refs/tags/debian/1.1.2-2 202e941d2c561a0902b7bab872f0dbfe321ab35e refs/tags/debian/1.1.2-3 062575f49c900530085aea00daec13d77bb3e5a7 refs/tags/debian/1.1.2-4 d437b8d4dd377442b16a5511aa5a8469b3a1e0d8 refs/tags/debian/1.1.2-5 ed61e0abcfe955105ad4ae909152226efc6b1564 refs/tags/debian/1.1.2-6 a608028575802c6bf007aca188ca66a2fd3752f8 refs/tags/debian/1.1.2-7 66fdfe6e4d17007e1ada6817d5868d4fcf2cd771 refs/tags/debian/1.1.2-8 f8b1088d2287effbcb4ea9df9b94beace2541204 refs/tags/debian/1.1.2-9 acfeb1d41313f7437a5ceba3cf5d8d11daf8feca refs/tags/debian/1.1.4-1 acacbd748c8ab861f98530a4c934c3014985016b refs/tags/debian/1.1.4-2 e0dd8127b9307f70795084d98931c50b86b2d01e refs/tags/debian/1.1.4-3 24fe08d31026449affed57531c5546d036a54b43 refs/tags/debian/1.1.4-4 a09d0ea2465c089a03130b56d480b52672abc16f refs/tags/debian/1.1.4-5 f00e1b9d3ae423b686def64fcef3a1e8dadbdd6c refs/tags/debian/1.1.4-6 b2a9c548cd5a5c799f106f1fca961c5e7ccea14c refs/tags/debian/1.1.4-7 2e539f3a0bded5e43ee96838e8e93e3a641e7c79 refs/tags/debian/2.0.0-1 8f8bb8317580e87d76754f6933a6f69738538460 refs/tags/debian/2.0.0-2 3611642f5b4e7fe51fae165a0e2a060d481ded19 refs/tags/debian/2.0.0-3 93299f29ec992955cb01fa751eb680b536b426f6 refs/tags/debian/2.0.0-4 a449f71764ebfb29dbcd79876ea918e51aa8d150 refs/tags/debian/2.0.0-5 3442fb972813b05eac11a7c799142aec98cc5c83 refs/tags/debian/2.0.0-6 49e1d980d2398bfa91d30f1caca9a70bc48ed794 refs/tags/debian/2.0.0-7 726d40c4eeb68cfdb1e6bfb895a2bb692ba61352 refs/tags/debian/2.0.1-1 7c82e86d1c65a4639cb998b104e596c4a7a12d8c refs/tags/debian/2.0.1-2 43f1b4aab532d684f0b3a097b3d7711e62309b68 refs/tags/debian/2.0.1-3 999fd1804f479d513f29bcff90e47c7cddc89a3d refs/tags/debian/2.0.1-4 717477142901192fa25d7916b80369c4f20d862d refs/tags/debian/2.0.1-5 142a59ee7a8df8ca3bd111fe6f24ee69ca788292 refs/tags/debian/2.0.1-6 34e1c538dbc240b694a0f9b64def89fb27b2f4ec refs/tags/debian/2.0.1-6+lenny1 892f73dec04b272d4c7fbc4c42dc91c7380262d9 refs/tags/debian/2.0.2-1 72ed7070c81f7ea52046cd5c95e3c58465af802d refs/tags/debian/2.0.2-2 bb13c3f7af9b95c46e8a4bd0192677ea63cecbda refs/tags/debian/2.0.2-3 2c81f5ff5061784676beadf224485504968ee491 refs/tags/debian/2.0.3-1 2898b5cc3618d15278522eb05f4266484619b0c5 refs/tags/debian/2.0.3-2 42bf12c0d413a4ace59ee9383eb2411951f288a4 refs/tags/debian/2.0.5-1 f4828b4140dc6dc909857790c57c1bfe6eeb1994 refs/tags/debian/2.0.5-1.1 2e93ea40ba3ce5ad891ddb8410e22ba477fbc9cc refs/tags/debian/2.0.5-1_bpo50+1 7c6d622ccde29796cdc18f012666e65b032e3f48 refs/tags/debian/2.1.0-2 20d532d5af21e53af5864f2af2689be895e7d3a9 refs/tags/debian/2.1.1-1 dd0ce4d725c16ce8b6ed558a5314da3ded6206f1 refs/tags/debian/2.1.10-1 ^c352294f1784ba02dc2822a388c5c7cb7e78231d b12a995bffa88658a867e681deb2f937d985f6cd refs/tags/debian/2.1.10-2 ^6073d6b63fef7497722c7f97a5d5325490e8b7d0 98a24504d09646aa544d23324b87ac907a51c888 refs/tags/debian/2.1.10-3 ^0ea99c66cdaba71358752a3a211d27137df52bdf 3673e7ae5fc9a232b42820ddac5f3866c02204a2 refs/tags/debian/2.1.2-1 e5c0ff266d074e2ec4a30241d650bbe8f00bf5fe refs/tags/debian/2.1.2-2 ddb509dbdfc4b07c3f5d3cf725faae778aa066c6 refs/tags/debian/2.1.2-3 6233e5c4f1b591c7bb97462b4cf5e2f36225c589 refs/tags/debian/2.1.3-1 ^cd0bec699b118959650034f9b4c71eee787146b0 b6c7385bec8453eeafe10317eb4dadfd3f085ac3 refs/tags/debian/2.1.3-2 ^52cd0f7f22d9438303489ec27090a58e95477200 e8316e28851fd56b5f8c612f6e681a92d13a9c7f refs/tags/debian/2.1.4-1 ^4d6d2fefa0e329d7cf28b61b099e7a06799f0894 bcffd2ca1d25f58854fab273871f01e59e2e49c5 refs/tags/debian/2.1.5-1 ^7f8a17352b97a2a16da4e2d8f84cbbc097200b1f 47315c293f36a2c2eaec8b063723eacf22f3906f refs/tags/debian/2.1.5-2 ^49467d2d00731957915c9d6cf5cc852ec3c31b6e adbe97a769f0270e89593710363c48a5cdc147f7 refs/tags/debian/2.1.5-3 ^e81e802052910b1dfe0a4117c666dbb6d4b0ad6e 2d54bad22f84fe790eb676e6bd23f03273bdd745 refs/tags/debian/2.1.5-3+squeeze1 ^d133f4af9a0461b4d6b38a8617cd73d1b1e4cde9 9a35411a56795e1b389c7dabcca548023a5047be refs/tags/debian/2.1.5-3+squeeze1_bpo50+1 ^8704f4ee40845e61b162b1a2779a546a8348c991 44f26e7c815c54f341dbc00cff9178dfb443ac29 refs/tags/debian/2.1.6-1 ^c8388c124037a24db131de341e929f7237bb5ee1 312d9640e5ac919fe631dfadeff76e19342f8bad refs/tags/debian/2.1.6-2.1 9323d95b64a3edb3d40b01cf52e3ea6afccba82d refs/tags/debian/2.1.8-1 ^6f5fab8556fe986057126068f5b988fb65b39018 6ca86c18faf4d877afa1c9eff2721b8b2c45d1e4 refs/tags/debian/2.1.9-1 ^0f3b2d547e358aed0767f59690d8ce9791ddba2b 0ce6287ed5f80ccd9ca458de6fd04527cfcbe7c9 refs/tags/ubuntu/2.1.10-2ubuntu1 ^2b1be0fc9c6da13b9b6ca295b7c202525b9361bd e65f9821ccf1d3aa310ce39f3dd47a740ae2932e refs/tags/upstream/1.0.0 ^9c9e5d65ef6b47dc252a17d23a71951a2c108e7a 4e909270cb140056c96425778a4553baf894e078 refs/tags/upstream/1.1.1 ^a7bae6d3f4a2c02f48c9d3738060161521a93e68 da9e5b178aea985e91ba78eba6b36ed01f3c3adf refs/tags/upstream/1.1.2 ^7fb54104aac9db81ef3ad5db09574f777459c9e7 de904e17421fc90eb940b5c27f15303ac77858a0 refs/tags/upstream/1.1.4 ^b3a4375b911f3cf3d4c3c1c7d1535dc084340288 abf2dd98fdd35af4071df8578bfa83eabc911666 refs/tags/upstream/2.0.0 ^808d37de52c3a06dc59427736c2f50d3852cb00a c03b7a4f7b2c0e0df08683b64d7ffd9931727116 refs/tags/upstream/2.0.1 ^2a6409c2b43debf2abb82048deb60e60948aa5f1 ec6c7d152a17118874b16efcc7980f1a3ed98752 refs/tags/upstream/2.0.2 ^d4507bbcaef1e429990476d32317c0a9b9bed04c 23e0d38d60d23111fcab38c212846d918aed64b6 refs/tags/upstream/2.0.3 ^20db5691ae04a3b07ac38f965581c6b5ef8be3ba 666f620084fd6040b3eb457bd557396627498324 refs/tags/upstream/2.0.5 ^2d328f8f5f6f81b767b3d35c742f79ed9f47d2d6 b362e4e02e7df2e97c93ae4a23a6f242e9045970 refs/tags/upstream/2.1.0 ^96472ed382dca18ffa33ba057a0eb6e86f10c044 599f9e56288e7e2e2b2bce46fd0408fb4ec9e846 refs/tags/upstream/2.1.0rc1 ^3fdaa89ed7477a546db9022360714296b92f2dcb 2b6ebb237a0ce67e0848653f974786837c953644 refs/tags/upstream/2.1.1 ^e0267f7704df7c64a2a801b31581cf82c13585d6 20ec34de6481821da182a074f69216d911f3c944 refs/tags/upstream/2.1.10 ^d8ad8ab301acb7f7bf34f75fdaaec33f221cde55 8f999055e1d19944b787c14c960a62546a616826 refs/tags/upstream/2.1.2 ^5a2ad5ab3cf7c264ed94a713e8e775765b43ed45 f71218fc975e48ffa05cf7ec72214d1792bcd416 refs/tags/upstream/2.1.3 ^af124ba8c90b923fceba51d3c4d4bd7be578ff3d 07fa519b1b826724c4aae0909a17c65548028b93 refs/tags/upstream/2.1.4 ^bbb939b2b01e5e95185975821c40f6304bfe4181 e0c8a7a618a996ead6f409337973a77a136764a5 refs/tags/upstream/2.1.5 ^0fa6975e87ecb185197f4ae5b2dd0b44444c79f5 fc0a5e08dbd169002aa391d25535342e029e2d62 refs/tags/upstream/2.1.6 ^a7492727f476e373ab6b5423c3566dd7385953ef f885a6fe97320a43546e186f74857e2902b6ab60 refs/tags/upstream/2.1.7 ^df055e1577fff2f9f745a79d17a5eebeb4dd033a e226ee32ee2fb039f2b639ac617d595e0237a81e refs/tags/upstream/2.1.8 ^edbaef2110e4e0ed989ffe82274a65193ec28224 c937501d33af41f065e065509746932611e41926 refs/tags/upstream/2.1.9 ^7e53c3ed3f78377b3356d3d7e0e0384794620604 ejabberd-2.1.11/.git/description0000664000000000000000000000003612240230175013324 0ustar ejabberd packaging for Debian ejabberd-2.1.11/.git/FETCH_HEAD0000664000000000000000000000311212240230175012411 0ustar 305e14c0ec9f2391b1b7149e5629c535d066368b branch 'wheezy' of ssh://git.deb.at/pkg/ejabberd 11b9b259b92d538b5a59cdccf259f656c69fec62 not-for-merge branch 'debconf-perl' of ssh://git.deb.at/pkg/ejabberd 29f186ef161665c52bac88191f73bad5aef02a1d not-for-merge branch 'experimental' of ssh://git.deb.at/pkg/ejabberd cbe90ebb05573f7c3f27f32fa9aef1fa06fc3902 not-for-merge branch 'fnmatch' of ssh://git.deb.at/pkg/ejabberd 383e2687748fd21c0bc288b3b2f93c5f15c473df not-for-merge branch 'lenny' of ssh://git.deb.at/pkg/ejabberd 8704f4ee40845e61b162b1a2779a546a8348c991 not-for-merge branch 'lenny-backports' of ssh://git.deb.at/pkg/ejabberd 5eae550cd084389afb4a8534dd574ca3f235f811 not-for-merge branch 'lucid' of ssh://git.deb.at/pkg/ejabberd fb32527514b30464c23cfafb7758fb3da49dd9a1 not-for-merge branch 'master' of ssh://git.deb.at/pkg/ejabberd 2b1be0fc9c6da13b9b6ca295b7c202525b9361bd not-for-merge branch 'precise' of ssh://git.deb.at/pkg/ejabberd be547edb9efa59653c7abb08e5d9a49898aee5a5 not-for-merge branch 'pristine-tar' of ssh://git.deb.at/pkg/ejabberd 6716aa6b176e4e79158e5e43f3e6e487eaf1ee15 not-for-merge branch 'squeeze' of ssh://git.deb.at/pkg/ejabberd 7c6629c5619bdb039a87af6bb89c6b47ca72926a not-for-merge branch 'upstream' of ssh://git.deb.at/pkg/ejabberd daab52b0d0cc3d5b535eac10dcbf73483c2d7652 not-for-merge tag 'debian/2.1.10-4+deb7u1' of ssh://git.deb.at/pkg/ejabberd 7781c1a6ef4d70a96ecc818c78f439c9456a02a5 not-for-merge tag 'debian/2.1.5-3+squeeze2' of ssh://git.deb.at/pkg/ejabberd f6a0e318c8372d001fcb79a96d0fce2fa42266ab not-for-merge tag 'debian/2.1.10-5' of ssh://git.deb.at/pkg/ejabberd ejabberd-2.1.11/.git/branches/0000775000000000000000000000000012240452476012656 5ustar ejabberd-2.1.11/.git/objects/0000775000000000000000000000000012240452476012522 5ustar ejabberd-2.1.11/.git/objects/84/0000775000000000000000000000000012240452476012755 5ustar ejabberd-2.1.11/.git/objects/84/4175cc122ff924b1314dad350cba365a78e1140000664000000000000000000000146412240230175017774 0ustar xT]4奫6甶ˎ) f4JY}1Ƒtu DZ}9Jp2F+DH~W Q{4Q4exu<h堠ƢhrG&+6Mi*+<'/#d͢! JHkӂ3r Z':깤&e&1?x*RrɅo^q28(94l߾3T r/rR-T* wg{rƽ)ޓϘ\Z* bBM% A%zm]S[XP(6ҳsu`W cyKYmw=}?F/uq⼲}Fp%E% Y36<8QTX՚:1E[(%5-4odٵxw*[N=LIfQ1 O}5:`ɺIũ &V:۾/A,iRBM1Î/w)N_&CSRR,~o<|-|g<=]UrZ:؇ 9o^Ybt_)mchKrv~?|}֢k/(LLaEbnANj1(kqWVY۟~IL Ǥ&3/D/R+dvn5 3{bdae$0 (hQ0Rdv>9Os'`(/I,Ie73FDS7@9Ϭu>ļtkW]"q o}uI&@L7@[{97+x G,|we c^0ӡV@{D6G8ACHjry .pTۭU}Yx"j7+N0E@#>_`9ib*T`njPT C&ZlnUu|{Ylq#2 JZqKyUMt~.6Q `3p1麺<װƣl^CaR) {ޜVXR٣#@ƣ ejabberd-2.1.11/.git/objects/03/0000775000000000000000000000000012240452476012744 5ustar ejabberd-2.1.11/.git/objects/03/a804a2c62dc738083aef6f4c6cd01233022fae0000664000000000000000000000057012240230175020122 0ustar x+)JMU016e040031QHN,(IH+HR zN{e5B1PYIIE)EP .;6d?l`ؘb ݜݲĢݬt݂b^ &/2mXb]oBXgZ[ SOHZdNڎn=XUSRo<׊~1* PXZ\[ZuYޘ )KOOUfք+py902ޤ2gSAe3m }@*H(_~N*JSS J3sRraލ,/=ml Yejabberd-2.1.11/.git/objects/64/0000775000000000000000000000000012240452476012753 5ustar ejabberd-2.1.11/.git/objects/64/b86e5f8713b03f904dc3dc6dfd3cd3b6b6f4010000664000000000000000000000027212240230175020314 0ustar xEAn! E)zwe Āc ㇑fio/\_#}DG wq]mr*nxnDtKL1WRI @)r0,$O+ܕ#V{]@D[9s`jOflqVmiGqejabberd-2.1.11/.git/objects/pack/0000775000000000000000000000000012240452476013440 5ustar ejabberd-2.1.11/.git/objects/pack/pack-3597b394a439b3587c942076c18d8b958eb0f5ef.pack0000664000000000000000003663542512240230175022511 0ustar PACK+xj0ὟbBɪiR+?3&O rFKH9fFey$%=WJs%Q+J /x6 ܶzs'\Ҏ㷶zvj}lRmZ WR)%^bl 8Zj"api[-:/^{S/3=c.K0>/Yx-J1{I/,E/I:Np&Nx-&hgq[F 1d2mSJ.z~Z8 Cˠ2kiErZzHKP~*﷣Ճ+v\oIZP=qL^6ZK[$tğ16V1»vV@K;s-J=V, pʌ! \$[ĵrUddkxͽn >#N&)L^`%FǏzisf&Eɍ ^$Pn 8;5$QJX{om@TZ.\2<h|-n~쏣R]x\zcz;Oi=FީĒ( pVvVåk+^ B+sem) Ι2wu?h8`@xAj0 {^a豰(8zW(1lŖ>Rؼ(- DHv1"),($:AdaaM붏3L\ZMK3*zj7tWy}i={.M{M,Z|)lon8_BX+ <8|h(-kq*I';{ 3?`xJ0}a=Ȗ$MD\{ 66MJ2U]\A^LF7'e: ( %vֶ؊V T f H^ :':ҒJ5-Vj{3•aba"4#{Z(5Sw mDFBTCLs 4p{JzBQ6ewY ēԒC<0R x)spIx G8&|~76pXN8CnjL֥p&O7P/DϏxMj0 @}N}abJ [1Mb+3ogUM>'ׁ&BD22ʥY4bx1n WlHS.>%Fg^'OA)F:L dB0ؠilG,4yT_ة h.~BGM_ti.9Q)+wq;w>R6yP?Ϟp\X*WW8OP [ұC}8@ Dp1%$B*W nlx=N0@ާ)izKر(ٓI -gnrƙ4Gņ`T)*1/l2,m2~5jj#NRF?jgTxXLWs%mK=~\* }_Ah: xN0D'GB܀;j۝LbGNؿ__RWRs!FckSh=iDhQNbBA^ZH1r5+F!xigLu,/ȕM-T3 ~k@sƥ7_ Tʟ-3ՕWQM~2~hi{2NUNal_y'xMo Ҫ vUU9W k/Nr7$ޏgfj&Eiqdq(gl-FPFtf$SJ-#Ĭ0f0ѤeuIS,c^k^(SI{6R)R=4(.'cI!Z qG`Z?5e{tvڰxOR1T^|/KM|V m+X}Isvu!дշ$@yVsMg|}yLw7[_f!t5mG34I೏f1E t@Rhj_QpmY Y0^97/dIQ܊v>qCP&EQ:xIj0D:Ň,Fe}].6NedUUZA/ Q: Jc.yab:zaW07!dh69Bv*p\p tEzK*0Qp@(ej5,uxsPpR=/fvV0mG1|`H:1ueILBLMoʜxN0EQY"EN:4+{|>nqt 6JYyGMh^z^î`"g(PONcoz)堄9e)*D1)-ɯs^v5Ţe.!=C/4 #ѻJB!FS7{1}{xS^Ue<'\&ҐX CK @o.:gS 4_Hs|xc9wZ)Cx @ P!atϿ&uK,r3%}Gj}H`UoYÑԺY)^q\a=x6#m_hxAn! ;^)k`Ys^D 8of2Оb -@+ՈFLћ jKs9G*nXw;`5`л {>>ޥɡk-]c#sqSg=[@LiY_Lo)6lNfVAxj E~MLT(nf0:)Uׅ<@JaU墝q#\l%⤥¤sCPs1Xoӈ# ְD`oѵξp*tjzGmhVn qvPJzZJ֜3POjΝNO{*7btBoӹP +t+~O__)qFY~N/|ߑXS-K p~?E|IxPN sԘl(-1zѓ>m-;L&sof(!z#gq3*R( NrN@/01hNQ~6s 2HVQdcd5PY:Ǵ?)r,iF ׺R l Ot~CWVkaA'TEa*~[*pƜm@TFVܲ) O-P y>:m0]`& OxIN1~Eߑ%By=n3#ROD:[[%7I\[ʴڤBJМN}?C\Z ML 3{P}BTJLJ})s9j/q^+X=P^nt__rlA@>N<c]J;M#iRCS* B$ unj Kd,+DT}^ܟYPjzm!S>/һu4dU;uo F}`U-4o?7j?P;ʅjZ|x1nC! НSxb{I" 7Rv)։'="d]h/`~@)rwjHTC[[3)dE2>r]'X O@S%xʾUBͻ<C [=4\xMN0 F9w,dҴ{v 3-Us{R\ ޳>)D0SԱw[hKFa,M@c\kǞ9{llQ8W,kop(\^S\IX]p;)"Oh͏P=SD8WV*ϻV5yR/ZML e^^q . r`3:f(DRPڡ';8xpR_FOxj0D`Id(=V*v kI웝.DըM1IBGFVE+CW,43t&&>9サJ$-9#MA$p!82EOAz죶m2gW@zRn1FQI}4ђ28PbV;/f;$C`|r]S)&8NiH+1ыpBnTkB;Lx[q4ot3;h$J#iWfj/ TX:`sY4\CĿvy xA8Jº=5ayp-xˎ0Ey?؏X@V.wLvTz b2ɭsԪVUKi.zYu?P77S'6 LHکH$qTzzġm,Q`N]LqxsY>د9RE9H>p@4cMuû-K!&%o@ O3S\1.SqG+A\|RXt3g#oAgI.̴-wV5̴=0G[ObO(5Q%<門\x!\m ه׭ x&J{Ğ,4Tw9k[m3ĽLpr[=LZBxKj0нN}H $b<;XSq{?fƹKrRCp@j́]oxȼ8^O Xy%)>]nO9R WqNt5WOzR3$DZBsoNۮeaBVxMj0F:Őmc %-5A9~;tx.NިFeA) fE\4:a44` 5ިre9eotPckR9>[RJxTV2 JYcJxu OǑ߄+=Qc)@n7W?_f=c#\ 8 ֶQpUH !X^%؉?xxбR0 ORm`S(X=[ireafӠ_L]i21]33aDߴ\@l}L:c$` YPFJQ(Bu1&*5q~"eOƍZL<`8]j9o@gf~vxkn7jWx; ОSG0 "RF).^rѥ\|dUxWP=gl83ﵽ[ZxMjC!йp^x? t;>@o  ɸקRs&TJrZ) L6"4З:S{} \M& Qбn<\׽ˍ_\~xcbm1 *+!Eo)% v_ o4~Abz] Wt`Ǿ_'-]8,xAk@ +tLڲ^7-z ٱ:3ڎ4l{AzI2"`]uv3llvmu{[mp[7)%'x)R:!X9S cS\%P]USUQ^'/0b+1CVxM 䬭0d B(0 X`'H,אKP! #ΞÅzz+ 1 x8ozP!O6hA[l=Kx}2"p}H`A{A1Pނl5+,|b#|eGf[F=-u!X !F)]ҌT,l?oLxMj0@N1BП=Үs YنXQBo_xak_~#!`xAn "{4 FZE#1bX D#>vU iL9Ŝct@Gņɩ'2Unr](M%ve,!m.^hv*GG;%[߶/ՉL[L%y8[/0 '}DUuAA=pMk5 }`\xN0 z@ ~XB{őصm$bWΦ>?:3/eɄ9ytaLAuMt4K+Wsj %xdx!(毇K9D #͐\rrC{M}~(_}loc~̵ OU[!XOf6FmPCj>]&;Y{RowxAj0 @}N}!Xv(ee=b˝@m[^s߾o](~#L|A.>"=omktrfW~v*%3K x)K_wmøЪۯz1z[&Et ܔLm8}SIsX|Cg?]Lx;n0 ݧ^EHj9`圿w0Uh"G5*zK@Iļ`fŦ}@BJML\DbȨK!jvx^umg~ieC >pFy=x}M &FJxIj0zECA`y$Aj'ߏ{QP%lTKJl6XpZס!ܩ D=To Z>39mʈXa@/*_q!ɗ<#/c+-Wz40v޵ZU>]MԃVނG nl-^^xMn =} Ur1 D$RO_Bߣ)'2Fq(7⊙R7Z[=C&rh^;ڞtV#Q`gpT*μq|cX9oP.-; :$tg1E)mҿwy%8ccZ|񶇄 _/ϖ@;1k5a3 O}mzÛ2_%ښx9j1s3\GN:Z3"N *)(iD08GC8%sqyL1[NUŎg)28K0dM9Z"bV"BTį{W+Q(וv^_:?Znkagx1 WGX ^,E+Krtf#X.Ovlq ֥xBk"e<#𨽰0^͌|%]guNzI>xdlsDql AN14%]:}׾㝗n}i{ς~mNlMpg[hZm(‡6zc1/LߟxK! =@)$ƸxR:DoFWP20yXF!@U͇GfG)X"$ I!UX[oZ~K_^Vl[_Ns!$BGӳՑ.>j=nr'nCIippM/ým8 z}C#y7޸OzZ%пmA!q!A:(@h[g7ͰLH625i.8 5#Qr *jsTxɽv 6ٛ/_~|w>ޮ4gxy#H^y<9@8v Tρг 낂z>pY˻3X0͌l?|axj0E{}eBiRR/cikk4pR }Duob+5!tTpm ~+ 7k%V+c n!z~CtG`>`5G#IxIj1zn>&!nԊ $ߏUQ2uȅ#;Y xӃ me7DZܗ}r󋗍]5.'9pu 'ߥ~|2WpRI6j`xAn {^Rd0D^=H0HGl}D0DGT.Wx닥D10sSCpGX("ц0zZ`?KMh*Ӽ5yw.ҿynƢkhLzW=+gs?vN3, .RB*VNǮ TcxAn ;^i "U8iVj DcCSq[+SB΄[-H,[-IVi9V0",9H[9@DA:ڧqgCOLyz&/u(Ě[H!4 ݧC_l?V<xIj0E>EC*!$>Hnr{_ 3̳A6Q#Nl理@ShN_8+YGCD!Lcpa}֦5U <%WY UT^9^RrmD,f/]g>p@lǦl~R. /EQCRw?cx= @SGc~(>]n0!gi^=!=Z5h(Ά%%t)(#FpxChޯ]R:YeSƇxo`h7yߨtkyR?>AGX?qj7g6R"S;3~m(XDIi WyΛN|\xAj0@ѽO]wfFJ&P[AP כ[\&(*0̬HlJr@ᑛnݑEEb$$D@b$+ &?kuAcAiP@!Vmy]ouGOwܿj[ߎ]>hZm:n_G%Etg\޻8Ot;741ofx1n0 @ݧ^%Y"Zd(j T!Ctژ3&Gl'.-ɐ 59j\xK"lx[.9Z;{ .W{ԇ4KJU 9UH_ٹV~y7@sb>7fX]m8|C?GTy]* m\QxA J@@w`$H D.va3 Ƭ(5~^\!;di"VgfzusH!3&.S -نUoߛe_?p՜,^lwМE(l,?9.u‘6zQ_@c=RFxN0 y8m%6H|Ǒff*9^mH(--XC阰k)RɼV)ZkA 5\}18>~|5*yC]t/]GO !O]=>v"`;!v]tޡ[<CRpxIj0zECZbrseՃNG:WA KΆ5 Vڛ\j%R4 а~-9]D1f\)W锍ܹ<:7[{&c:N8 ֪?D߂U-u7~rL8-;]xKn! =RIUUsc{>J?wۿ9T!,jі5 l|%%Ƅb4MX"eM)ňc ]3ބ~EA;,C ek SM%~'NmgW5eI0x;n0D{ ˟ HT9ĒǤCQEr0r ޛMDED$S{ dPrtÝ Y5'Qp]FB Pg@-iw}9 CehԻ-m˗U=K-L,i2v~Q`'ꨍCһ>E=F>FwRzUR)Qk i`cx]J1 {"GEVڙ6Eq{ڦ;Vj||s6?_2:3,AL(:Mc a2c&,Q}S:]% :M+&Q.ʤ[QbkùV_B Y~~/cp+ 'qsZMO+tq(z.Bw;74/xx|?Mژn~TKxN0 <%Nbbpjȥ OIf(EDP hqZHOiw(9F'ŜEQG5 o#胧0/yIyff-5/kmnmi)z]Ul_#)ews\?5[kgNw) 8c< ׯJ[xj0E{}EF!Ilg kFߏ?"ˑF9; 8y6>%};rhٺڄ),eڢSaȝ\t E;<=r;ѩKm~RHX3ypQk8v75;ȍk }M(xKa@xKN!=I71휂Ħ&PWޓA{ q7C$gwř(xU{R< n7Ρ; bu)%m U^r7Sr/',<5imO:hM5 :DUNP}SͣNx;fx_ZxMN0>ؙ!D%'Ϥx,{r|g`Oz\%hH ʁ>;{4c }>+fKކ4V)t!{1Ny7+>u6|ְcF_ZIi]gf7$8qMLY61aEKYÂB|wM̥=w]JR)bk.Tz4>>/mOVtxJ0FsOwۊHUDPAY MJ T* x902^jVeOC'M\UԺ)ԲQiL)k]F؅JH! <xh.]2\dZÞ|(]8 b(F}O/sqRGa3U1i+iY5BЅ*s/sQ8yCw%ȸ{((↢xMj0 @}N}ic(S( $V)}=Fj jS1F3zrJ*sCQzAgdk #Z/6r@Z($75vippk>#:>wZ&\i|DcJRS|ANR X7:dZWfAiߣ^xAn @=} 0#UU*Udמ`[ i,z^ SfJF`O1O* &8qBʐ%JIj쥋*{k3$ 5R9T^+\*t05P+cǶw;-b6cW@J;E)ERVf'8H/,tGX gxVB|Lpl;7 9ݩΝܨϕ0uPiIxKj0нN}/# B>(#{RSCtxD:4Z1 K`kROdS)Pȶ\[FZ(BB C}]1qx[F};nqDmBkO֪il*B'E䚾Vg.fUT-ax=N0>pRslKѯ8ċ3fW"y Pf5KJ(590!Bs!* `HA%gg)%ۯb hl)R ċ7!3Cnkp{U[ې^'w8Џhg?0Wȫ2p*ԓ&.wue<fAhZxN E v0RcOL"eBMܜ{FϒM ."3VM6rL)bzp65T4:>lp~jRx;4I(5U )$8 2819$,%99$xblī &\\E%) @sR3 ,|xKj0нO}_ }QFq0ׇ@7tiW{C *XKF,O ,U%Hũ֢vɢGtUPK3v}y8xĭ} ?4lV]hM4E#ޔSj)c7fpy6/ $*0 ꧑ZF9h[ tb$xAn @ѽO1J Xn{Ra,'׏A[!D$(+PǀN[[RhC?ة o0Z}չ *wnCʧ>ʋ{:1>{Fr,D[CYĵ"o܅2C:a%wneoZ[xJ0E)KiAD Q?u0ɐ7ۊ="zgO0d4ŢPG#GBf3M)(昷?vv%oUJj ˒Y$5xDc7i8Z/%R:KRB ؙ?*\%xy~H m[ mKu_n8Nkp̕x1n0 ])*蔾ڃ-CQ־=7*ҚOy Ĝb"-ݣr]2TW$1Z,f%`D\)ga'?6ֱ[K'|M]E sLͣNqsڿۏ %~_z7{z#Ix0@ M@Ģzpaq,-hdӃox,dbhc"2;D];~1XqyUekzV1E2s0:(J2|Jy?X>[0IJcnh(=C)Xu@=7 Tp>]wx_ ?Nȹ=q+e+_]?n/' ~iOxαj0Oq{!dK.]:t ',+Nm/7'=Z?zxp^Y;a`m?!yyVF AOMr.vd.yB;\rq#%ʥjneˍO; (m@n)"o`w~7:Dkٸ/J7#vxnIa3xAn =}$38T=OH}AP?*{qsʢ*ʋ^5")O {yQ,@g2 ĉE&!+xgyґdZ붕l'>b=ZY;r`^JxM 0@}N(NAĕc2҂mJL^&}t.QbF i6,)U5ٻ!٩pDKl]ƀ "`$FE/駴Rc׶ԽнH^iPi Mɀ1붭_Xc~+|G.GLJXxmMN0 @}O=R4IJ#4 9k;J$Aq{{@meKn+Y2k` Qv9ѩ u3Fv#kC8G&5S^ .(ʲgϠUÓJMTR:{ [ 2zK|Uj&ͭJK˜4ff`7xNs&" .6uo=R/r>. X<Dohxj!O9A{ {k V۝ N%oI #6ƚ U#*b;UA+S\U"RLZY)kZLU~Q兟:CjP&_ՌH8vz2Vޫmhۏ:NriR'n\'(^kM~/POx;k0޿bdq#\]^C^?"[M1RBP^چ!DLj`Y$!NCqZ,Tж:ipQ[g>eɅr9Q q2ޙMyC^3}_Ej!dM\Oɿt6+q(G{ 6A*ع_}"6,?'xU[k1FW[ӖxJ -!!/҇Yi(HE'u/z9F)zC^H9uzo"طX'6QHIQwBM[N4v3hNn+&xx|f9nH!֑shjOinڦߌ~ Nf ƕ hVૉ8YR@3[ i6A( }^Xߌ|v XdLMf,eKb!ܛ#b;?sL:-fF0 kbgחr$ňᴔ:*YEr*;-EȚEq}.c5a~s@ꜹ`iI_x$x%n0 Dw$۲ E:uر( JHtϯnyBjR7cofvfwa /sT+=nTu?y~$zHA~-QTi?*^̙x%On!G^``ȩRLxvpVFs+)\(SN;5héR+r7SZcfJ '^ۅ2-2 |`Y1{$8֩WLTJx}aKNb5ﹷSLe?N50Q3%l@əz#p$oZ,?w,qGE޼Gn3%ߘV}=-' Ή`Ax%1o ݿCU:dXuS\tu7{zM͐ 8j3kCIى݃Pi`㌨\'M1LwDZ9cJƏPXTqG/jO58s- ^yk| ɲJRʛ ͼ茶>+H^NH}vpɕ 9_۽6_Dax5MO0 >!~lY*!4npD]m\96=`Y<~f]"+]72+"*Yj,BلB>-`E%Vo: jB鎊 س'ɞi)2?AY(H<.Fر}tv=c7`<9<,-u4U]US04>i"qc wp֒ cñwK&ӟZv=]ULGYg̛;%E>.[6_| WY.b%ցn px5PN0+ jصH 8ibo8)={l-0[Tzs cϵ6KEoĀcsss=T'0>j/eE]?H<0hиNT gxv^sƵ-tR(UG(V,pV2QqqN%ڮ#L%:˄ wtcaqGh!y 1 Ym匡e+.G2@Ư0cF^1fr%1q%m€(x%n0D{yHAZEۥX)M(5 b#z(Ӝ)Fg$ /Xֳ *۹)[ᅺA xX@uzZTة;6#*βHWlnΞNnui6%}AKI鲆=d w:-7G9'T%C}imSmV_a>|$"nẑiEz_0[,x%QK0/&MkeANGIoܤM$uLy8|DB9ֶXWAҀZ$D jIҴ$oY8gѴӠF7uhR5Vun(pCbbb❢(|+}q]6Lӑ97'FG/60ÏXⴚT0GK.[Tz3(heU>y:_>˛.r8/4 be|Ct+.tA^2cx-IK@ut tVq@0 xT' ݕQE={D۵ucE)KFMUVeYdmY&@X<â i c%#ތQ] `94[PSlwƃrKnOxRkTbP11l4u0x%1o _q{% CU:dkǪÁωE]U lLv#Ń8:LQ=ro<2%6QL y;+ZM*|po `G%y+\N/.7ɲv4?KqmC&e ?[spT|N_ꝳl<gi~RxN0f`rJcL!:Hέ!$;pQg !i̐ʛ1ېR@)!-b4b,\q2V4X|ؾaDZTt/G=K~׳S6Ɒ`L7 LbRWٚ9Pk8?PCx-j0~^Z ƒ-E.r-X$k%Z5}? DŽcPqprУU]'jn2,ad0JA`78mU^i)酔 D(3FxCH9xtm#]ߏF}WҺ.uL1D8iM'5z()90T{+{pv:o=lrqe;]0ϖ!,_Ep)aC(RZ}nTB5߾txMj0~n^mB .B }I_8hҐw8͢Z јU* uo4CU3tFŐ:0MuТTm,L62bDlS\(3WF.-{teUOҶ1bGDž6J.p;9Qc)M1V]J=>iqn Ob2ˆƒ bО]ɋ:beהLڏrFܵ[/Y _!0;`g K|zzzN.hsYt;xT?Kl =È; EtFoL*p 1Kx%͹N0>Oq%)!(D^n&cĩ;5#$N녞̨ь@/1Uzːi!df(es{)+3.B+]\C91a\p3p#5;ڶVpTKuIpi7̥/>aVɑ7P6{=BveFΐ %#l \ {R#7F/6bxMj0D{ 1%R2eHV>[k$#20o$"=zm:5h* IYeTvP:98z Z[iG AQL 7p;Gm:^Abҽ箪qmK)1epGŠi;Rn3Q:F*bT҈ |7ZK5O=yؖ8Ҳ#pDS|]y++<~aPRNPn]x%νn0 ]O?!cǢ%щX $WE9r߱"褲K8!y^F-DV\iw~NΙPWPZi5^d?y֨smۚro.yTPy/3C:&k;@%}rox_%Ux%Mk0 @:o4q%PFew;ȎVO]}=ᒈxȾ#N-in&3N 2w Z1Q, Rk5jxA۱$3`* )ocS9R|ۘW%r/\8悱ow8M7,wNeJμ%GTo šxV,n%& (gI+9q\-h ҡɲc 珘 =G( kUWC|˚x%N1 E!< REY;"gU)OxaY7DF$TۊJFxmtoP 1uo %g&h!ؠy;p3tr& 9#c+"=?=2̏+YtU w,Wi\J`K>&=Ds I_ zbi-ecZ*"OJa0_-lҏh Nb{ȏ# ]ŕbmor9%^d;{jo4ALB*?MKZ+MӤfk' X(70.z4R&k%uN{3cʓQ^` >voTZ7~`s]%S R m"r s[3\oyeJ+%}f@SNw J^oJt!0/\_Wr3xeA0s 8J$e)[J)e{Kcid+Kf4Nqczߛ7#a"ؙq߻`66[kuc?ՄLIok ]C6ұn<5o6mqݦ+e =c>aҿ'*_`c]Ӛ;^+1CNE0IH01ϒOp#9x?R<%զJ$ n[nC9@P!s'*9.<B0U]@XquC)t"pBEH~Sa9D3E9>ǘϋ<av$![xeD@爊+Ũ F%g9<5ҷAuj]avڜ|&+/%E,_1r/2R@2μ >AZvTFݫwڠ Ӽ) `)d@]Z\=iN['(y) x*`NޅeUړx%N0{ E~sNDCq%%ȱ#{ci*8l .\.z< -/aV\Akm k/pS;^ASJ9\-a{-|T֭TO.Omf\LiU%FpcCێ">>{J!D TLؾ7CnnUh@T,)U@ ^6rW u O'~7KTڼނVG%q<ϱVȩTL5&xy܄ |ʥ-fGŦMT;i+ZKh>aYHn ֥L8i 'X  8@&p-$0hٯ0hc:Y&A|?|tD#YFw^0BwZx',*ڐyo!yپ\H_e/owx5Mk1 @+=mܙJI{%CuY۟_,zz ƺ7MmO490c]G %;LCX:o[-v֌f*p= &)^|#RoPUXjvpk)A^9&Ũ!*aZP,52*&mHuS*sV%Wx< DV 6D pp ˑEϗlXnty5pKz&E/ągcK' KHJx=9$;vmBbm7gptnKYx=;k1{8$K\%˔!ŞϜF'??gB2 LD5Ոe }P^*ͤ 3 Aˁ#9镵H*{5aսz ϴo|ruDRv.8ƵVpT*&8]8r|Cذ~qV(pˎ3]N٫;!>B 'x]CHPՕp` "??Hbxn |Ş[lc*\+ 륱^;iF* gyɠa 6.&WGTF S`Xb!)`XɣK*6sP_*\וCp 3|>H߸lnw޹ ?Q^\k;ɭ"tu ;)Q䒿ڱF6Rx%N0E|H4 HYaǻZ`%%;(`st'"QJu4 A5=3vRaIU%P&%;(!8'A œfD)N(!CHv-nYJu)QbBٯ>' '`|X9Ru9h2hjG[1`IUFg<@#<& rS+SaAcP=œq߶}e=z^k=;ޕ^|xRu ނxj0{} Ip ^˫$y#;58QKo!u گ:x-Se6qFLkFܒAfdL>Wp\wK_o:<ʉHyVOG۽6%?8FO狖J<ڭR*9& ØEM (Pڕxνj0^Ouf-YqYņX:V#2A1{.lCљRIg LU-I_? hu\袣[R0U8ek P/J 7#SCa݂Exq"clKWxnh_ Wqv>vr2,*3?єz7P. 6Z#Rxj!~=NrnD N%;3kHHXr 7Z#;hKf.zMhOF͐c0q3 9 y[?^<8T?ߴ_̜CdVO*GG+mHEl\6z<[T\xYgpRc~5N(UOLxj0D{}#Ylq\m J^ g)V1L5 o0m4S 0NLt۲:fN4/od6yk_lGMsAa0|B31/y(1ݣb9Cϒ`#s/giR~(W*qji)u Go6~]؛RLoJpC`]kT4x5=k!E{:Mb˔!>dž!:.BZ٬R8C R9_F+^zUIuQKKo-qe QyTtNTҟA#^቏0DZF.9R\nȽw.ǹW*u͔ 3By1N{*ჽ@;l Bn~K> ]x%Mk0D{GH!Pz˵FZ5[JD`ƠD8tX54+N{q63@!:m}iCk4&ε ZAnptXv\?_@kUx]Hߟ4"+opH ʍzնk@hWHptF)m ; |my 1^QreHTb{P迉 rA.9d>ߔf3x5;k0{>ɖ-8¥JqeHR8kAT0|39(g:[wjIeUy(H!:&3T荒~j85ki3]? ,yk Jݠ(xUo9S1-mK'\$I\L(W`;t>Ӳh-E-< S,gx<ĒR!G 7׭zrc&߈_?ex̻0^O~$b!}ֲ4b2o^?bOOQǸlC3R]J񦮋5736)Xg#~sŹ9|ʓX?` Y_Ds&/Sc;.IBّ۰pj(?G)Q}Jx̻j1^O1u.m  YɌf<~DN \.]Ns5jcc5彋2LL۶f"*eʠ5C XH'?:g !_q0-a )xsؙxop{R:s e iҐ'RUNpo{aB>OfxAk!ỿb-,ꮮB(ZY1YZtlȿ9}wꈀ^$.MUn!HWIhOX }E )kٽ6q9nMoDh>[WpPqZU{x|"RN"o G+mRKl\>fO¥"1*2do0X䪦P9 DL!hgivN_p1Q^*x%O=o \pخ*[Q+N~z}L$ :@5.0mT8 Z1SR9ۓ vΎ!Rb3oAQFyU~L\uIT|K8MZyZ)+R15;7O(KWȞ".Qm6Z`SB|O{I9|@nL3m<{JflU x]N0 } A3J[BH,Xr%W,ĝF(q3\$DVD""ئ6}骲UYEWuYpceG|7뼶)\Q{3Ul1t]lLUfW8I#a[.Ž!XsyvMAgOt*젘qd<otfʙeP,7߭#B܀L /a\o [&&43ȗfʸ/x;k1~ '0ƽ@j=VOktGTS #\vnE6XP%WuFԪUWDJE\'iKL˝|q;*|S,rPgn?PzМVđ)o"czHUy. _A-Q͕d7֞84}@>8d&ユ?>PQx=Mk0 :oõk(etlgőM'!=Rf"ho4:w++kZlQ{j 2 VkWDMk7ҭh2!2|FN|b8ۣ9ԍWkwJpqǜ?Ő2<8 qky>8)ȋ@YnX",L7Xp0qYzp+%gFxS04MȏA=NIp:;J(+PMk/(/, ٙxn0 w?%'"{:LYt _Bn:> d֡d}mĒKaXPUHS"_bilG&yv2Ù"v>X6 $.z<͵P^,_o`>DxuQmMRvw??z7xƢ6 6{g,PP7,Uڃ=s&)gw*Y)xm˒@E|E/"t m*J2/tMRy4q>LeXug]UY ^Ǥ$mlHW욓,hBHQ{C~&}Dllw-䝎ۿ򳮯Hv1bY['Ƭ*gBXutpѷ,y Ҷ;*E)!{k/Un0(xNƢ9_NiH똮kQSs&/j^T8u4F??hrns {]U865$&q-ͥ`,-"7O7,p:T٭COZEVژ-E1W^J ~z5}|~yw,Tfaէl Mn.6N|dyZHo2YW%AzfAK-ӧͭt)4)xmK@+#M;84ٚ˵,ѱ_xlf *=5&#p% ץD dn:߈:ic u|U gF*Q e]}eO6pig^ `a<#kY91ĿEwLˢB ;Ak3XwyY/mrˎmv__3~"Z\nZ޽e@tkD+x\7f5'gSN-a-U^AbdjSɹI+ BAx2uH.ql+7cb2f$NK]Mf9Z7{X!G99X42~n+* ¢d/RxgyAQQeVe3QA(2dYf E4 +(Q^gxܒuBݥQ LZT=U-._e6A<31YgPY~Cgtں|m-W;ơ3/Fn),9|x13LiZ,=p*Eqq)u1ta8"J6"&n{? ƲC1ENYI܁:둝o>MʹOm4 eȈa;'óDX^TZ8ۗDL!׻xbz>Uv8akwoS?Zt˞ nҸ]6蔠):MieUո뎚vŢYuSUoM/3wZz^Wxo$^qufќsy^a_S&3Qzp7!=)xmr@D|, aIũX!07!.>ח&#d|8!X)ҜI$a! I9 5[ Rr#5pR͚]1 y_ SzL,U^/"ܰ3,5 aSOQ4tkh{_NJF3?7vLw*ZȲeC9X/~24u'":䝓ڭ9?l+n4\:/FIG+'Y1m4G wGfK1?~ HMτW;.eIҠs.bJR})i YHw88'8}]㠍Cu;Go΅ oCg]YMnfR{;ܩ /lu]-:!-mcOF?%cMw+xwflo8$VsHKqzeޔ2D>艨1HN;.,͙FsT_*ioG]2ǩahÊgwth]UԌ}LLeYt#6س|ɉۖմV̦)xmI@>&E 2/ zAiDg&c͏@TŹ\eB Ɗ9aGGs=0CVurhg DCIgm2ϲH?fD4,xaY :dyCO r"{N%/gIi89`3qy nY;k 뚦k?8EӨo"eKCGƣU})uPcBGV&fa;fOP!]_hI9NaewGyqN݊ cۤ02S.UC7ٺzj4y ذuv|!#a}%Ln;О%xV"yDTaKҍ i2%Z t[$MP+u(#߭jV+QK:z5>"7PD9e5&GBc7lUBpS!N7iۨg )]g\-э rx2$7ߗ\)xmQ˒@sLZaRTx]3 (  >v(22?ũ<$ O:dKФep oOqw%FS~v'Ҡx_Ney&CCzy I/ PIz'4v= tmOEgKv3lmpay"nU6;Ôijkb=+GU4Yds)ή.Jbwާzt 1c'-mK@]ȅ2IHYk>{kcYۏO(Bs0P2Pý2umq\eDB3r٩^Y$ D'k1h\\{WtXd%V}E(̣w&SSz($78|Rn+6͵cHou8zn;s:΍+fo*хUQSVJKs][%Hc=g+4=_ˈ+xmɲ@E|E/̦REA _R{!IS LỶ2LD$'2TR&)35)J8'e|8kzG ?m֖O|o rGׄ(D$r<1̿0 JbD ;u8ےGtv\wخ{Oqە ~g ޿2L险i\l[n#ÚFP%6C/)_L,5L_YG\FP#љQ# #*i+cz|6=}N8+Ky K$+ZA誸@_Ru#NVCñdG9Պ_bɅGcpJ ƭcf:qGՂM֗\͙A+opl%6)gw1>kSB԰?yO,ǚc@6CRN V~IܝhUuژh2-%+=E3"6M_kh9+xmr@D|,fSV!˰b }ȷǎsJ]ߥLsR"K%$%2QN1KGAu52c\&Up-LC3Eh[Zk_MX/ھD+< y&.mkc .i^8}~e<ۖK3U|Vs,pG q dT53T[#U Q5B,uޜE$]JlxWNW>e6 vh>`IY+73H4\_)xmr@D|,52  b3X$8Uw_ jz %YDZ)MlZ$֐NVUJB:3rײM[r\-N:Fn0lcS*/(DQCdP9.y9Ѳ3wZV{i;kN89whD8-t.'†GvvmblZ;-;`L={ 5ynfPg*yU41/I{/6oC=#cud"3lw2jLU_¢hs+ ` El$z6Xf'z):*3nnjxaK"w4[4Uq2%Ϫ݃xK|} i]| f˶:߈- ?ώ/,y,Zm>H(oC1Uf7YK*M}_6m?C1&)xmr@D|,Ty $ˀ 0qc/g\@*5YV*k /VɹiUR=ifdƬ%ΛąОOTc LL+Ni?te  $`y&HV;#S7Y\;5]pX<>˙ӡ!`vkwa!-|3n}gC4>w6d^,MfҐ;'x^v Q3QIAO!SەơW:J!ԛ$mhΧ/׃m=H2;byr0GUOpw ۝1݉xn9Y'qDyպFͮk3;Z{5(2t?+~I}ShtYh.DBiTзeto\IHZN˜2<վQ[xj]dXW;F4 .vAE>mSG湻&et* "؂0荥T6E~}f29z]&H2:b6xH8AHJ5Ft*&AĤi15< Hۭ!AJ2WY:鲮$)ƤϮh4U^6] 0!Ӑ i߯M~cQ|%gdU7u 7 :^_?4 g]kTgQcYڄhG?6 ;ET1bԋB6jή2Itb:FBZ/լJ#sرL[=" crd8ٙJA 'q6kWJҡZ}T.|J*xmK@9&E0IeS% >~fT}ڬˆ.f ")O!RN3q,'rbr<; P{" ؐfp7{`Kٟ&O8+f_ʩ(*f!RԮ43t=F倩O ul_voNq?m`3a!f;fY6;EtM M ܋մֵ̅"E OI CvvRӆԪ#N:ZYzl#c{2񒠿Qʴizx~RZ0QEB>ҝvllGX( :B x-0E|M(41=k?1CکƿsigpLznBM; #j4} S+W([.eL0P"*LO8/JR2\g*Li:"A*M Uu +E|9 x-A E=M*E$1}Pki`jt>;zfrG0JAk=( _+nPmV͘aT&^7T68'xsi 1PMgݡB*m`'>i:la7: x-A E=M k@Pki`jt>w vFn<*4=ԨN݄7ȶ~b\a7C] g^ %>@K$n2mp ORE}<{B ~/o9 x- 0} qA{>@Lb%T|{+zcۃ@7F;c9tיAo m%qTb'(KD6Bj,6as"i|Zyq )e$G#T$9C[Xw} ;RU]vX~/9 x- 0y 5?5T޳Z1ْl+|0px `ѷ8кh1ۊ(y4a´nT\L;'^W8'ʋK,Jm*/ee&Xv9-)uag|: x-A E=MZIqߵ:540x{kt>d}p8hV8h.Hg8H~/ba7A] gtq&S* ;EL+ǧxsj8RP$ ꨥNnin:0S:m x-A0b&PZ!1;g-bl ߫$3N^ūfh,agÃѺoqBH9[k!, ֥H&m2$sƑW a9Bԅ)pN$'hZ6CXU0s : x-A0b&Bbw>-bl ߫$3C'BLhCWLQX|[kE(ƅ+v3lk.|ьJ]%pHp/[\D-O((jjٙ8H-eU]u?B ~7L:t x- 0 1V޳Z1ْl*^f;zm;CpƌN:'q۠mkE Z8{-_4cRaxI0(ReEcorh}4m]`LZNwÂRKgݨF?@-bl ߫$3㝼mТص=v\]!J^ gM.E2תQ&0p* G^78'x^ S ~7b49 x-A }M(41{>Ru3CZTֹCtz7Ep2!Ⱦ6RZc@*騅,0R3%jL;JJ,(2T8 iGX)Bb; x-A E=M(*Mqߵt540x{kt~ၞaJI4(qlZOkLS37&K.P~ 3 sN* t`.P EBj>mk`'Msú 3%U>: x-A0b&Bbw>%uNG gۢbc&,iֶM ym#{J!n%Rh=$.,i~8yr(&8Ǒf @rKkttuQ\u?~7Q 9xKJ0yVqP / dIxK 1 }O sM t{d.p(Y|oD&K >q 'o ;r^JZF*bLJiSHNb3x2&:|i_l/Uh޹~~uEiXq҉Hz6q;8v\S 8%K{~*&D0Ec?vЛ `ֶ\|6jg7i S[޸%܂ L0MكJTKc[8xZV)fo/GCjV+Z?C/22-.mK߀;^(1B@lyt~CJXS0W֧J+\exEU!Iԁb7)2^mN!3n@r$;I=4&a{_؟!i=')ڙ[k[(37L6za$Yz⦰xAn ;{d 0fE9䶏0 k"Y8~r-\!Hcś9$ɠE#ba@"oNZd0mU:99*ܩ4sJ;L?6'hX[` P|aخK-3 kv][@*kۢ qCnP\3^qsƕxKN0 9ӾH"k nO~f cE#Oɧ0Fvy&Jc 6T̝\~ JdoYSL0bM,M&JCsӭ}]Nox?~ pX?]r>E /[k4_D@<|%o&LFAK'ЫֹLoQ)B/jIŏD)KY`x;n0 ]^ 7螭7)DoO'3Kt{-V)H|M5- C2O<|긴lcL{?JVltੇLXCnt9U^?2x˒s7|CZxZC]-4_ +^v#ZxKn нO*#UU9D5ส!Ɖׇ <ZU̅ `mzL]TZ"@䝉ŢhjMѐC0/xm>l]]oczo?(1BmJ|(փz1`Rƾo"orm (Ns&_N[m'bxKj0>v8_KrF ?d fё)iW[ :rAI1[2bAI.+9Â%g,.?K&l;cC 6-rC]{ۅlM]oCzY$_}Էc{?k<7WM2V=^&&կW].>YxQ[cg6ݧ_nxIN0@}NQ{c*P-5P#aWdWwߗA-&1X,.sƔ5J[NSX8 vu"dJQ1TK<}Jrt?%G{&NFNrmRKNB>)b1]?FZ5P*uS&~!g;{<. L'(#^/V5Mfʑ"pp-|_N[c&3 g xAn @}N}Fv=0`&"N޾9Du0CJCK QɄ5֛L˭!0}ஐD֥b/6:_c5ps':uwRG&*֞?2q̇pYc‹LENB٨ Wn3.[,x[J0?tHgaGCgyL mR[E"qD!̅p"g@M4&έqJ&f#F?h t׹n zm{>:~hsm7<'Ni+Fxs-Do 3>u]~d)poqyc$L@Z;+ |R_n xAj0E:KH%B*9x6M +ܾ.,H򘘅X[[5F Ƒ$v$mLr>uѳ.UU'CNy1Rw JUK3H=sba!s:!ȑ!`~JSľ0I"<Pu[;oռhuU17>ݟy=3h$sgځemM ZOj~,s]V*01`6|V>|dxK =:c\sLa($-5H7^(hyIˈF ^ʠb֤/$tef#J+{n-#R]iᗣqn .RK)u 6aXGxMj0 }N}!'b(t;ho A|ژRĮ c2> e[ݡefzPP,q tnx+6Ch]ܤvG]N*OxݿHss >yo`=bLEP]c6j[RAf;[xAn E}`V]f!NdCzz t6zԣ'' %!zbB3.F?BьN)7E~̆&\9ʐy[n5߹lR]ͭ\KoRI;7ja0 B޶+3P| 8,rx(x\ds͕[&v ^_kBKa+}{R [5N'#~ay{xAn =}6zi . U/~Dd>iOv$ eV !83!:"1 љi;ϥ¹ƘypZ:<+7mJR3 88RSF)ʺ.O/(h-7y*kϒ.=%Oa`Dyip>;5ykOR>{Rv3wIVxA @=BIqata&%`(׷gp0ȨM &!Y"m]'NaꃍK/3?L6K8M#H:xu4pKm&-sNԒ8f,gW0v>NON/^;-ptT@oX7\5Kx[j0uoR0JiZ$"B3fDsM:OF!e$ԤGQ&֥B3O&l ޴mwYnܖ>V#0 f ሿlڻ+޵}(<>O4ўk|iߧ~~[ӓxj @ j4*R~Ũd!:C=x҉S2D19eCIYW&fT5,/D.MiU5eAeJS%x&+_(yP?ƃ~IWhT4NGo*5d)B\_; Aް _3 ^xMN!@=ĥqO5$8F7 PtLC !ܿq# QFR4'A%TR08|CBkK&;gғ9 ?x tsV:~symZ?:ZTJBJitV£D)E߆#s#9lo.+||^ޞrp:Ӓ}e09F?exMn! @})N3RUu]nI*2!zIOȤ[Ale9Pbs9 6*gWojjs1rKzZ i>Νh?I,$s|Hru~8E=B:k½orΏ IJL)r&>v]l`BxJ1@}E텡@Dp!2ˤSq;ɐTF{p} ɰ$A!^95K!SWڙB(puIh>:1:%Dc 8XKg_x+p<\ ܦwm~tjh+>P@HV)qZk38S׷GHN]}ƹs#5OVbxAn b RUURa#X'CsD`QJ\/!9mvpCTk=EmC3 ^{pf'7u \ɑxQj!OaQW7 %?@PgNC D#j(QB2$Z@(!WE_m-Ʋ%B`>r !ʇ4}JxCWO7827.媭&?7FUHgӳ1x XRE`xKj0N}k4n>y JV.'lf6T)^*q`gY,l6) PuxOn4y蠓O~G82+_\:T:@ph'?LDZ3㿁lX~;.ȹ7^ƗxAn F=`_ z~H1c8~;tvߓ */1bY1'CdQb [9mQGhYMTL.|\ѻ`] *q7nCRGӷw>_ZI@*;v&7Q jth'ߧ# m [2xIj0zECLk y^іX r{B~?"ׂ*()h*q@Zkol-I}&9>۬M.9Yu-E)[pjhpO/X$?}_㘎~K+OI< *}"oAuFmg_Zp `&=wEZx1 {^AEקa#ւuGDbD:x ,syge&SHJE) ^`nh8GDaPxU?4"g>?v?lT[  7Qs~׆2Hx'!MuXkm`xMJ0}O&DܿC$UlL<=OHmT(A h[hSؼu]oھP~$z N]a ,e.B.г >1gaA7}.axAN0}N]HaT!cZĕ3So?}:D٧%aE B@ P1f0C654YU,ͥm"AD ?4aK6K)]yshX4030tZxAN0{^#v$u+g~f|Ș"Gp#D iv1!Lp.U/!LG)C1eԵusmPUs]NmYn~G;;Ki}~hyځ۾oosϤbTż)#^_\xAn ;^5H61682NF.9Ǚr5H%94ͣk5 cť+F(5ňVFBkjҝ޹n;|)[{ K*5Mr.}ssq!Fn!d?Vcզ%'׏Y>(z]\ {4S@ ޡ @ xhSeh3)|Nކ@\x?ECjXZ)]~̽lEϳɩEtr0J̛Y;;pެR u7Y̥Tken??axMn @=e[),EUWxI ?ozn{ډqAq363-6YOgH;NyqD[vvq -1QޙIޥUԴ4ޥʡ H%89:Kѹ477y /[kPj-oy/ߠ?OpFIP e ax9n0{biR<T$Ϗ~&D(hRB芓*wB1٨1oU,vU(C^`=$&oи6xn7=Ocq}R酷s^ 'MB,Ge .׬6pIPO-?aҜxN0|H';~T'PPouً5>H# C:+g"EuhCo􍍪@'ykJy1rxCvnpn;?(h2.bj<)ԔC-8QOXҎu0 ;`]G9N`AxRn0 +xan`;Y0 ۩zh[-?JNa$Q{dUi+4ZU}lө9tª%*iZ54)Q(plhԻ]s;`\΁|7{E,/Pէ9ey,rhb(~\(EG o dJ%:t@~'<]\p \ eY6 Ybo?Vxah" % Ю ;H{RG\n #ihh5W`xÅGB~q=^L/*8+w31$7$R0ATwp](Xsܴj%`>Yz Ob6'8 ^TvZ,' !uL;+[$ 4F{:SXF9PL [gvq#ӆ7Э8i91;n=u'mo [?j6[.#Hͼ`⩛0(&jݒ.fUC˜':}~pS~Ӗ&;gYoHl?xj0{=G%8B46XZ#wuT7+pJIQ{y2xrQE%'T:`]SS@B4F8g߸KXz*p8crgچg 4oܤ""pΩw7HB\0BL;5xnT<֊K*[jpeBeC@q'.@XtЃ ~xxPN0UIƮ@5J|}q:2d"ja{A~ =!`$ɓy;CН3p7m 9ÑSL&B5ֶINwչ GYk+Iਅ4\=+Rۊ xj|\bUUF9$>%r+ظ8Ug&xAn0;m`Ur6:D/#:1&2٘q 0AFJw8ã;rQ #&Bx`rŎN]TU}]Nosl\䬑'X9 F.ʾT}~ެL/V1\7*^ֶ k &_ÑxMN0=ހqCa DTp6OX5iV;?N00AH#~btݝ K6, R >H=~>vb\G1ϝ/nϤ?,{$u)l47<`gbuoaȐl=݋}p'ݴ{MJ "|lMbxj0 E -[;OJ)t9l+`+St݅su$Sk!P#nh{cjfж1Sp׺-Nz s\8c]hvnlCpT G>o:m(_Q(=MgzC?‹nVc\E߄"ik@oqbo#b (o'lK)[E`A3ޡ,|lfzN:zG+ MJ˚ xN0Eϐ8A#D#A?Gcr4?0йWīN4XZw4SFwPaLG{h=x.ux=9};G==*Sd&'JYLi 3zW2r2vOX%[hèw~Nkh]Bu6#nsBoza\oc`Z6D^_!\0z&{?[3O9iHTֈ?:U70"oAʑIf{cٷkiTmW&?7/dZcΒxKN0D>Ef8 !Xϖ?퉑s}ؖ^=UqE)=9z5*cڸ^/b4b ┊F*yFtT.rdcP؃WpN+mt0}K̖Tam]zTWP'3/OrRxڶČ&!|M; Ή 0A{%tcM )gҎpO9CEڱ<ԣ4Q?әmnb: HPxj {bFWR =qit}!zO?|҉`Q^a&6C цLXO;vj.iSQ\Ak!XlJ֡bhCm6Y\! }=S~|6]|0QJMmN{A!AJ'.ay=gW ea xAj0E:hc4dPJ teO K`k4Nkz=T"0֌qaNdl?G?n&0=T*Zk&Y3%I)ˍ+\4 Eo ?=A\ϽQm]F\޻x=zZE޶EMS;\tl$kS{)ﰳo$(D ?c~[hxKj0D:EFdˆrO3ԃԊLJA t=AIy '%1 6VO28kp38+YE98D/ET.a(\ (Wv 5_x]'*Uj%Be.#0QO^RJigςp+O:w3B|;e82AΝ7K*v d:!RFOhd/~`'xN0{Z`oH$(Ch]_rJb8s/όUGIڱmH0kh*[1P ސC7dF| ZѦR\ SY Bإ^$zn A[U*:&TorZ`+ S^+(?XqzR}w?y .]8x`ài4cC>!vµtxMN0F>Ũ[D4IlK;Dʙ}OOIgDuJι1:ޏUٖB0֨+ubq)9/;i]YmJXL4ȉ-4qxKN0D>Ekȟb?;=4#3\T^q'*$kLɥlEkeLb*1,DG-}Ԕ;R%+KpiupV,mk;[ַcPhGOTZT_AiowZx"m[ ;ݩ3>x=gu$DzK 2!&F9G.{k6NǡrxMJ1}"Ym*]H%gNZox'YJ5\v lYg@"7Q%TɄE{@-.;D2'm8A)x]Ӟ*{fIPަ&CzIߎc#s lAkz}"og~]u9Sٮfj:hkxKN0 }O="J*9rSD!?=a"`1y_D兲qY!C*iLMTD\m.S)Qu%DjGgum6ٛ?OVP~: z3Ffo̬^5f8vpz>^YTW)г wAb7xm  f(WKR`-X_ڿfd){\vuHf BR2a9qPXr)ڭfJMٲ+.u+ ^nܧ`ۃ_O^P~ykҘkdr5 C@j3knKΙ/癈 g ŏ]cAаTG٦j}# l`CqD#x*Bb쪝ܵQ7& 0MP[qחxm0@;=]c rUpJ$@4>>wDnƒ4j1VWhrC( Xcч@9A eVz>xJ]> &+t1}G~|^]=cԐ?63R"qloxl?r[[ H'NtFΫK/`RxAn EbM-jYc+`ܦ/C?'l2FG789`[7'iBY@kh"Lhq ,:siA7M;qY ;'>wo.TjW,"Ls8OsJP}7_Gh9@w>BBZ'M*HAh"U~.'ԃ}E%|!=F K~x}xMj0O1R_4BFqy^v/|҉Il%j,ɭ^e XS&US*BlPE;(5!wq;$5y4m~$1{k!BNRTS:3Iަ?Zxj!л_1vtu\!B!q @=oU,6gJ99RY8PC~U Vs}J+"YU'Ks;|騣iC;vEs EDzms꿲}NxUПޤZg{miMxKj0:E3l!!h-0N-d]q'V":y+cjtt:OTБ٤d~ LIoV`X&^vQI SLZFp hgJ}k~"^ޯA}GzNJJTËRJ9M;ē Ap{}~رCyoTxQj b Ɖ(KPFMJ?ޘ!mZw3'-^Dkhf3R-fyq8t^Ѫ1`I6Do.T^)A)vh·P"›B(^7THEk?8/#nT R? b6#xn0 z ڢV衷\s/$Z+ECۗ6 &P3֍f474^:cƋnZ:lk Fw6nei|CNٝ*L3x2+3krco)`#% 38 +Bx&MƐ#LtrĢ̄RCJXVcCFk4dT,uk`L! ZO$DZN&E=ǶKT4诟>Xe~ axMN ]mb1njO`2 i ~0g NdT΍}8^l+Jmڰ =z g.^zM.)ʱΑ.״=G^KSҞBHRgvt'¥ukſ }^cC"^R myBGkxOz\0*.Qǿ&j"}Dxck}#{ڒx1n E{bt+clVQEU1d3+g(wHޗBJ)Qachh`'լLf e4 #E F87;Kek&vvrpQ|jo6P_u r'Bĵ-,OdOxMN0F>ŨCI!Ģ,PpSĮI;p3i(#n e#腰Zն3Fc)љN|ºoazCʰO"iI+qMrq˜hcL .Y'Ss/o:W/Hʇ.kCA`*P}o6nj/RV}G m_StcixA @=`_5 }wsJLL?z/Kýwu RCLƣ8NٛEFg*rS/5k>O2]JL+BҞE^ϱ#NWl:U[!xcTu]DkA?go6'=H?]/x͎0~$"Ni=n '۩8vc&3"]cklִRJv=*ӫq݄V1fSNJccnuZ+׏.y&G)}Ǚ*6gKI鐨AG|C0(d'0,>go-BxDdO*b$'q듞Xt L~¬ 1CtOߡ>vkDsXA <#2|z"!aБ/otM/qk <?E ӭA;X ~Cen>`J01ikt/E߆Q|NvA7W1HhJS'Sa׾%ݎ0u_Lu67V32qRAS1x*nŦm]Nox/Cy܏!g\/|i`C &9x31C}oUPjíViRuePC^-wd͘xIj1@ѽNQ<@0YŻ\!J =.c?r,/*uOd-'W'Gc{h`+uMLjL.ĠTO0sX»,>7xr\[:p\t9DxVkE׬> -󓟸|ؾ@;4! S/xAj0@ѽN1B4RdA g5F!_3dk Ę9@a)gW4+GOnnL.:S;#kNȆN]eC&7|鏌~&6XklS 4_{%e(+_n?jZx1n0 ]^ ,K2-C2M6b1Dg iFĜ*H&,ϼ$ɴlY;7 0I .k0RJ&HT8z]jV_zi_QW~2Ģ/͇Lcٿ Hc7 sq}Wxm bѝ (7*/ZK)`f4҉`ޘ6X_(oJZR]N}鈝@XCQ%` YG~Q!R. vlmHl7xl\Dyr>Ϟp{# ┹]M8}գEr>, ^FpBA)d'xKn =}KQEv9 "ޡxO3A&Ү&ZɓFW(:Wt@QsI=qp@m'SjB֙U[Ú_ަ`cG?VP8>c^g?G'_;_x^kq"oc'caL ~]x=N1 @>pvߙ͞"8l$&^(_=DPK[͘|ra mTbf1%"%(m \s)c {q)԰>列z 7ehp'<_P? xx;0^~!z` [l"4J &HKxNv .h#osAxs]r >H@5.=v)NT-zW4"JܸÉېdmpƻ=ɋ0x*+&M0o*"P]% uV xAJ1D9˜ND bc1FËWE&/4ָ9ظ(-0i'iI ;@(7.6z'c[a0uZKcɍ\Ḗt*RްC+z!#=FRY-W3_=j߰/ r!34~aK0c[ckꪇ26OhEZ*ڹfZ8?ttdxN0E|gP*I!֕zoHخ^Z2 >ޫ+PzV{atpdl?=< $Q. νXm0,F6n6~ p m䢎9P5c$_Ar%n;[s9c /3쭵Szк9Uؼ}Y'(**b' qM'|J!uiW<5S.; nm4*)_z\z%A{! ^.xAj0E: A+*tk1Fiu 9Awn2&3(6j?)t F[;aHbVuSv&8)A%m]F7jB3T.U^n4ʴɷ |6[?vZ[LNJ.^(4υ9sP|- L)@K $l^x=_V)vб?z= V]we4x̱n НRt|TUݳU3>jK1Dpn~?$t) 3I ̃Tf)3 ې-ȥeqSPWnhx/wg9hgRZK;䂇7&UB%;g[Csoޫn^Vax1n!WG8`"+E:n, 2 $J8/.b]uPIMJBANh=ZMc@@NKPtȭ}m 5ٚO^$>cُrO嬍,j?B낵B($W}ߦ_mWxIj0~ECLK !d --{Ԟ!APEw"(YELFXXtHxo0}N!-F:]w%i09GB 4a 'oý}kG;=__>Ξ\?AHZ+P!Nǃ!W4O8rV\FPr.Na q_ГxN0 E /AH3IڤTB=Bb~Ii6Cb94"1 \iDҝ% U!u)9휷|r]Gp^?0v> nx1j0^P04XGf"7HkcD#Dĕ1BqUmfR.`7//P[7T4z2˩m"C77;v~BqhAC@MQˊ$Vbx;n0 ݧ^Ġ>T, (g hHtzv : R׊ |P=a07QR5,GE(dJq+)s 6AkIoOy;)ˣ΍Oᗺgo4:*/Z;ɻ ,7pK"X'5~4IB*y9ζQ[ƜxKN0 @=Ev@*N4pb6ԅS qc]aE‚±bRL) 겙c. . 5搔Hr`@YB*?d,(#iԚ0ׇ{OQajb%.+1 ]й(ܧ`/'?(<5ie5 `4ReF?!X< NE_3J.DsPځh 䑵X%t.0i ޣ{om-*uG*''q> :kM޷m]MSDraZ>_,MGx;N1@=(;TblJ[B0%Pub۠'x;N1sҳg$7fvn@ 0X`0&=9Xg4~ ꘊ@4F%fBtGgCaޖ府+é&H.p:׽v_.N+ϽCt($O0y2UEBO^ ^R% *J >{fЇ88iel/qD=p <\b|wP wfxKj0O1B#+PB!&`y\i>iDTH*g)d} ƠYl h@mp䍉H)b*<8!wnpKΕ>[Z?u-QCڸE)7/>єև-8} };7cL%UAjxJA7bxN1 <{2dBҏad1d qcO.x=v0$ͬ8i1ΖkZhFlD@/롟Bvj}.O :7̲m͌wncM\/~ˡ3/~gQ~Wop[VI@3CYDZ?Ɍ+?9CZ.wIIAcxN <K) cB]jSz:moOo5naZZcWb &FY!gHGeP|wVx&~)+N) sSZRN/ƽǏZ VRƔw"%R)g=IH2#? ;XH#.{Z3'lyB#m[ ) [ޜm* $Z*4 lP/nn=2H718K2\,y0,vOA92 FX!!:I8b.ۘ#9 =OR~ IxAN0 E=4iVBAbÜI4%.p|H^='%4) ޏ. OXgC"qȩc,j8a4srz'q1j=hCV.p\l+|S|r_J*%P)5l)=YJEvyz^vMnF:P!8 || /M,,YK6tvJj7o|%CHNs8A>X?ɸ`MZDZB,I@˞GR[^`nh]"xN0EQ(ŏ* Ķ@cX=ȞP 9G"X- &4*ΓI[?,I|!)jdeDAkvKkqw­PήrpZJ<[wZ[DJVnR*%3GsAtD] TE=׾w3CP"F//0 7 Y"tx1n!WG8(E:n},؋4~?0:`c6c"&HԹQ Dkq M@e3]cCZڶKӟˍ03/_PY۶"荁BsҷuzVxIn!@=`bF,);2E3!_z2fS} ƜźjjfTwE/h .-B3bZ+%L@˕O~7'>9*O:w7m]i1:b1 ]m>gN]v/șFAoPbxKn =}%3HU}C 㡡q޾=D fQ\Fdw&]J`yC&$OThupDjeiu9E Oަ`vG?kQ}o1A\ॱ\bM.dE["oz`^TR_-jV|@Ej R.1Y @q->'o%rn.{W;7ŸZ$_<<0sdTo8wȳZM97KvrFP{Gӟs{b/xQn N4Mz 0f8' {x:Q!qL)beIfG'_ͥFx^ c(䑣oS2&up&#Ky95*0$];tVB:ﱂ,e_trC7Sg]_92 KHmVق_*%2ǓM(~&GaN8NgN9^ExAn @ѽOTUg Db)f"7׏ gHbVk<:A)q"oCӨjklw~(No]kxAN =(?t#mb?{`s)s,KԌ7&- =ud+JI|Y sx=s'F}ܶ^6hA!X͉e_Н~9G-x1n0 {B%8*D*vaA>r\HQYuFuf,) iwTF(8 FLeI@.;c@ v}Hhl)QܧVSqm9vw>Js"rHL~rlڻ+}pd{яp~hWGx;n0{}` H#؟,d׍O!sޏ*^k>,!EI !/5s޶*&4DzHUX kK.Lj̇BP8;5>4|KsYx]j wO1vFן@)}_zc"$NQ^{^ovf/tYXx"[,/A3) 6w&PN!:9G$⑝Fk!mfmk#_5ې'.75@cњhUs빩 2j@ XAIg^kloimC6_jx=n0 @ݧ^ M?@QtϘ02Bzo5Uu{YE#\B#CHci1$3a#9IJDx[Dt{ZbQڭ~k{ֶCq9joAcmI/E h=g3'?p0Ȼ$=IlP#4]jrImP7ax=j0@^P0Dz$!vȰ,8{!R'Q'3b)s\Ǎlvx$ڒ.Z3vlSr)R]A-exJo܆&{ӷQ^܏s`g$85/=/0`|~:Gʽ;pzFU`~xm T? FN/ ְbPD t"B̰ZGuwpA}]9 ;5Ѯ0%6IXh^R;!ɗ~/(ϏkP'*ܿhi$7mauGQQ)B&TT:GcyLS %UD]xAn @=}%!1RU5bCǩz=!1rdŹPlJb#ubyHS(OT(q4WCj)I@ç}CڟQ?}_!㘎~,E& _)@fZooE=y^^M ]xMn @=`_g08 %IaJ=} ѩO·jvd]P։gl,>I &0=::</qu6:^Զѱ2j8WOB.7emenBISEFl5~c}kr}bxMn @=`_08 X0Nߨg-QR\\3Q)$\lͺhoGXzHw(W2тK1Ĭ1 $Oި;}J'K~gvct%iT*%2պ3㿁+PRDFyDU7eyLY|YaxAn E} 3@UUgbKIa\?V{sCVǨQ4: hxstY͸:ghXY %F X`:}(+5y9TުThg:W~~Q+׽cC%8To98;Y@)P`%NdiG m43c7d:cАx;n ОSGk3(o 0ĖƂǏ3~(}I.(BJ4jKՇ e]vń5%3Ekh 8y!'CFNKyNst7.Cju _UJdjmg 6PR@FyM;>oFoC'_r4GfO7LƙGstN(5oS".)iX lGl\՝K*u8%P yr_WCmCF$? S3.nM9"a(IwC@j܆?^weܛx=n!@SG^񻬭(r.7`Z2 rHzQsI`NgWBf\6nhG#X:eutvk2I+9$Q䝺Q Mv4<_uc4{B%Yu_m+;3(%Adp/R>3OcZfbx=n0 @ݧ^P?;(zꠖhHtr=Coxژ͉=i MR}1$=5 wt_pM>)Ґ]MjTQJC yKVG.G#Ҿxp`e1Sh:>CptPUOh;cGLO^/+hd)pl`l,<6v'x?g痏[ m^D{K QKYlm.vYw}FK7q aqgbN`_scxAN0 E=Ev@*ةH6ԅS q:4^aJTZ%T',K #uIˆ9Yf%C xRETN SF@!C:ֺm}s[[a˽d߭oǮ}v7WwMBBɓCnz7 z.ci}F ?vgxm (WKR`-X_ڿfdj\NqKvJyF,`,J1:8ڽ D[2X+$[@MS謝[u>]~ˣ}^\'_#SMk'Pz A%sk[|PQs l'ʮf5 \x%ͻN0>_q{DߎB+QPlI(%ȏT)δB1z>r2VB{v FXk~\0*C.ݱW.>.RU856*%te߮\+0fR(O<ְrm.=mz\kTkX\w7s6@WFJ3@1Xs:oU{G/as9AiYmxEj0{?!oJ+Sڧ`K$;y‘afj&=g|/PW=7\ph;fM^z/;Q)NR['zK)/-s3\)ɬm RKb!営ti^~B%Jsj3}ڀ\ 7ӀB(JіOx ?a80kZG0>;-ڟdzx5;O0hx\;qN ŕ ]7wA7=5LL D`TIJZQRm-VJRF ł|M2](at'56M%LR)i'v|Fxu;O =Rz* س }e@Bat^, *m͙"<2zx\JpgkCISBl`S>.N ~*ENq_'Q'{ҔWy)oָ((0>i_a+ܚ@ ;] Щe 5 _"Ձs3Ow xlp.\W?C^̚tIi pw 96[SN5]tVސ)M'likK\Sx%n0 Ew}%A2v,:A% ,)WE9] uT W!y7jGfy肩Z*6VV|l[@%[.>T霰Nt+ Cl1.9զS .sou%{R{83%lݲnlB1 ,,!"z&a 9Aq0[Yx%1o0_q{UdlU:Dұp/ҟ_G}ӛ'rcɪvvC)ȡ~jꎉ@vR73vTNMMp|RRw^|oHNhߙET#o[Y0JpYx]Ӽ<8m=Su=4s#tO)`E7J+)>G1G#RW)wZx%ϱn _}ˀ#R&eLb'Cz" h ^U c0.FX?X%0:'1 "y3 A+Fi3Uxz ;èVOCKi]33VP.33pJoX~FLf%q5P5/3ܱ'fd* G~[N$xm=o0]~(YTE.,{*:ɓZ"ǿKZNs/#B j]̈UZeN$:2*& Q U%eQ(V UU,Co4:}:=?˳2Y^1/vum੷=};`8[7>̞O3pyfu&?7 AN}DN#8J?6#p엫:;a {8L^Ѫy 8Ѓ2VZC.h#QXp ޞާ/R7l7ɸ; MGm[k7`w,_W'pɀpoR @q#%klW_V&oûכx%=o0 _*HꖪmXu0\I'O_K ҖjTum[SE96]6[1h*MuG[3I7p|R8 = z=&v p+w"GނәܓFU}B#|gOA낖@XQI5njp W:Eץ8)M(m xOf|~eh$6tS?z6TcPw`T) iCߑ|vɡdsvFUn3SSW^p .]mu_@7CJE(Í&.ILpy]˴899}9eN$`6Gl X}ЗL?q-G otQ pFbcZÛx%1k0w7ȶ$J.K>%.d?*9g윖OKI~7f޷5\n`3O!R+2SUG%+-mSsDnxc7HzUbN!b.65B:Jo<>ՙ&Mi3c(>m//kG%:\6ch/GYɞ-x};o0w@֓H.XdRbKye7IxBDUF kk*fU]6;򀎠ThnW"/{hY-뫪fC_g|x0wۣØUQ5C_dϳ!E⎌~!m9}!/AI;eC'`/ͅ2/OM J .aH z{ixZaG[h!zm:hM(G.;Z@ZzyU"xeAk0s 49XJ֚e4%BI̮Em|?qĦdzmִ 68;;3`;nޘ6ck*̺d|3FOcTK~5]qjmUx p?Q/,cN$NŦ mh +'8_xZ0/-<)SpD*r!~۹ WW|'HYJPQ3E|c Sh ?spB3)oE!$Zr邥֛rsTrF/+$|r,}ux%ϻN0>_q{DGBQDC(g $+I|j3RԨ ބF5VBH-L .!fRh ډaآр60uD{[=O鎙^yElv괿TBwRIғ(<38n9}Cj;+Mu|a@@r-􆓎b)39Ou 1Zx%j0{= 1_82`kiuG![ |Hεѽi:m~nlƏEEBe-e0SQwKtXrHW_IC[놞rjD! ,ߝ|s<9!*q3<*@5m7mO݅?w(3#.a]%QD4(S*Rdx%ϽN0>O="r' ]Gq %X!'1bmDUp"H&h$:,y`T뜕QV5hG)Q0*i-))+/|`voD[z!؉'Qx]c)i+JLpy`99}yuMT@-{UI[AY惾9~Z脣~6CZ\xMN0F9w] ?[B}!&1ؕ=)'qe)y? bv'L) %Ý5@%#-%ϫ$f\אg,4Ю̹TZRk}|#m{߻>㰶O蛙,:0A4OnUU-8|oל{&F8kj<B|mx-Kj0D>E lK a!Y) ciK#BգGUAwqf!Zgp8`Z0ƄPz2zr1eM]ChueO 3|pKq +h3{?e6RC}jERwnFPX{;QM^ 3ԅcom{;X2p/@Bw?jDXx%j0 BA$v(?kc[kAOD49|C; =Jr7)ZJ`"R=m^Mvavff%JD[*ʒ7{6zяZJo\p\^H9U2b׼Q~. v5oa]'آ(%ll po[ |,(_Kʢ3oSybܵdjZ8 ZB3əbQTBّ2l^}}^o&jU>>3v:E\즠-A{]mOWLXOvj7y`¡tS{F7!뀴xAN0}N1{hN[ k0"#{קT܀[OɠbHŏlFIh`&BٹȦ씜 HvH8b}ѣ>tyʛ^78y͇/8]\֧J]GrCM8A y]?yvXp_ t7QchxM0@ừ%؉b8V1kO6c|rW" 7..d Nz"+%:vr6xG uuw&xE`-Wy˩1&ޓm9K>w7mlWOkm6(+QJL ,\5{9h(T;SlcA >)^W(G| `G Yj[xAN =`oMqL\ic w ǍH*{  $e=>Fz ))SIبyvSFaW F4 "n4g )m|PF)뾯Ѐw3?P\R 1ևr\x/LIGF˼;'>.̣|gxAN0}O1{PJc&.  j<,}Rl{4g?d,wlhb 'EM!1.f8RЮ {. ̹-*!ɒ6-?1Arٞʥ58r6<vLgh(o" /Ti͙6?26:{zK'8*qKUR jx;N0ާ%DZ!=Dv䌁7xFsP69gyH.$aYVrކ8|0OJY-بVdTF] zVj9 ܶkOjx4g@j'3?B[P#g_0&{a7'7>"QfxN E|{3 J!ąW<1mbޓs.UD>C76("J14[뀝P1V .zn ^5tǘ(RFit*_>K=^zڦVz J}լʟr;#jTAvaqi'bt<@x?U^zb\}gSx1N0@ާ: QѬ8='{eO`=)82 Й~f!0{7ō+g he."őȜb^QCRVr%ee//wѸR2 z4ԛWT=A4OT3+>/E1 G Cu;ws{=5&?[jbzp/V\lޟx̻m0ОS\G" 7)`yO x2!Tg-rBkѤm]9GDM/.92Q=&4Q6y*(;k4r.M)M[! ȫ, o"08C6/T*u}~uAXx-MN0@}N1{Ȏ?Be X1q!v |FYhilA-# Vtzz`:@V|SJX:LF).ӄظkIYwj+q& m?A.;Obe jpQ*6 ~=:>w>ZJ4JZ D'8kѰ*\_Tx=n0ާ>?XZEl3K02C6)rtO=}M}&DLa(cS> huc2@p:٠s:\u8)b*r;!W[ْ<>[mP@!Ko^e*GV6Jr3N5k^-G(ԨҩjەxAn0 @=j" IT}Y=oUXD&Mcdi0֢PJ&6lFB`LQpt4{Ϥ8p$ Y-pT|ۖᾖ<-=B.u8G^NY;sa /Ȉ],-d=}輅א}Wo/t]xKN1 D9 Ш !`Ć837{=!RUlID`;ׄ}ESwuێ8Uc5k0QФǺ!ۏ2fu5Ψ5n&,c#,x>[QΜÞ)C=rt$P7ra'q%PhQu۾FZʾEU#GL)D85Yɯp23swp#JQJ6QBh)UيB*w.GKeZWEZTmUeWge2< $- Mn!}7Jڜ>[x*ꪬӜ]% n ?xY<WK{Iȣ`==8O ƚZF ۃ$Լ_G@ܿaMȁ]:5av_v_<!kwŃ%,L&G IƐxN0~UO PdBP+^7Fu=iKy33PB+2 뱵M/Fb8pMçvdJI$*ٵD۾6TV4Lcm T `;G #؃SLdLʱ$6=VDݎC?%LG?F!ه_R<"&LfwiwZʒ)򏌽!wLp ЌA8n}4h|!jE.zYq%VƫJ.p]gjjߐ\^ۍKg8+/"xP=O0+ncFI؍H, BH̎}nL;/-?'jQDt5\Jڎs!EJ ʒM*' 5֝< vkeja|"ya 3A9qNS5XxM++Qp[d:# 拤h+~doG"xiADq=D+g^-8+c2 ~L}?"7b L` 5. &HbNcf')!ק(t\jٔ.Ns]r&ֶս%&>gޏ8 pg1]뺨`q#?{.iƛֶ n[33O۽~1dSxN <ō[3 Zhb٘償KHKt^FΕsKBJҲAضz3mܠ4#d 0J]1{1Hpyo !cؑ=a۳'{ `0`V.IETD/E4uNTY7et6VkC^&,8k`Uq[.n֏kPhWOTZ P68qEj)ԎccNw8}'籊(|=}K?/ ])xMn =`_#UQW?Cmf"'=~t-O/7D ZA.>@!*gӢt!S(\^Z6*-S5b"QWCFL^?g֧NgKX}T/Re]70"qК#_+jX}}֨[48mڰax=n0 @]^Ԡ,[V-CMdHts@O{ZD ܵ B`n@{&p]9HRc,c=1:]hh%T K Fe?|)Y$C^!A/I>lkUcnRQ(9nst`:z%I kߓxKn 9*6TUGv<.6F0(d Tw x*lyBLcK~ۜ>|͞xKj0нN1B%(eN1G-!O=AwoBSSMzKu^A&cӄ:Z|& nBu )dkp[ч_x;ʽ1Nrj/4+WsÛZҏc9$cB#oC<7L[x1N0>)c^KQН5|`co@E> XuLјd)đm, m55i2T;#5S&ԛ4ѕܤʩru'Vέ]Ζyvq6&3duS W3]_иR6,J}DP%u!ax=n1@ާp ^)B)QЄx=cX {-8ūqG*4A93TpR({yX"jQX/^NN+`CRW=&HyK Ihy]x;n!ОSGX(}[2;׷dm*o1dBAJlBN ١!V2!c}̮Pђ O}q }KGɃ6ky~hуq8Ux߯"axe!Zߘ+RO ^uxMj0O1#i?dSHѸ6#7xߓFiGlQϙR* )aO~*m ޟ]6NNs笓s!p;.ZƇ 3h}XI>AR!zPm[EC]cۡP^蹿{ra8JjCN0 bxj0P0e6{?61XZ#_0s)Dv0Λ@7Mzt71tƷjBY8`mpjZz3aī뼋]gv^.7.p\,7N 4(.}TjSy/&.35 L^ZNi5 g1-BO)l(€۶V¼J}R;EK'ط*0=1mM2ôƒ^ Af(GT~gx1n!@ўSG"+E:n0 fENO_"d+50E-yLVcُAŧrְ0zc(AϳT !VfxKj1:E㭉_mSHr+I\? ~UIL1Q6g3&tMƇ[hF>|(CZ[*FG(sL&;?{ock߹ཬ}ҘEFJ;pFJ{ 3? _P|m{./:ǃf8$ml,~Ze_?xKN0}N1ȟ'U}!8H<=Âz҉0.BBI)JdB ԪqNM3Eb0zlU/.TtySm6|)|s?A}̃^r_in$oWﭹ«JMc;ٹuiR[[2Gcx=k0w#kc#C!)C:t>'[Ŗ$rB^}xRtZp"^4JՕCnF(FE-]ۂkZCGM%J'lhpg//k VH;?Rn)>(궒2>qiH'~lP? -}*tZz٭'<ꤚy8]^ϷrT_a]͟xAj0z[lJi 9^ }ZZ.u<3Ra&'k N)o{"&4Ɏ: lyVw<'k蜶ŀFaC2YKkM(˖ẖR%H~JߎƵu5p*u.y${N;xVkʾo"`8LI>.;QV#4 R)nyy-mf+<k r/;#kxJA}WAQ>@NYpglo|}PTWōrI*zͨ0=!k-hkJCrykh(lR++U.n.| ŇKinKi탺BJ`.4RNL:_J5#;PqLiq^ : /hxMj0:%GRBcijHǯS t50y{É(;9vSRSגS8gph{b0uFn~P%yVmO蚆Z"c&t(5&8Ɛk\b WLsɔrcI.T'5tu-l\L7Ax_2OjcLS\Lu[m ЊX)->_6 ƗlQ`!d Twv3tJĈxj0D,ٖ\{ki]X k~Acތ"4Fۑh\HnZ&ku e5Nt#ә`=:ۓs!Џ6 wYs̲f8-x뼡ܸRM|QIޠ5ht/jm['T1B5\Hi;}4QM\ +UP+n#O~8HƚtLAV;ܙo {iFxMj0 >$(ٕ^@0dœ;'>8A[=@#N~ތNX( 9uhݢg;L ng|rfLq~SpxAj0E: f$YJ>@Fv jTWI~wN̤'T[xMNC!0y11`401ÃH)(:& )5펃 (K ^xN璥qze3f*?*':"؟.: HH`̆}Ko˵׾s@ꣾIcN{#~R9- :'[ޘ߆=ӺOYr DixIN0y"yLGH?KJUL"7-BNU1N-C:S.yyacR]rՆ`B;t.~tC㣉-n ~ !GhiGِ߄6E<߂˓1#@OXWaJv:v9.faxi0л=`B5y g5D#7oHDPr윶b(3M,L)ElY_3HAY >n4ō4NSĿ4p}5 6߸7*hxFʭP3[}&csO4.n[xMK0@sIQӂ+(x4l%ֿo/wzO 3tnDtQ{K68O[3u}8}Vݨ*&bVk8h}fhLvP&S.pkZ%p7;LU.TVF|ieym\`zwh՘%]iTo%)0חwifao3 [ A&TEBhAx1N0E{bzv"!fn άr}Rp^󤯕fwaqL4F)q!Δ6w)<2ifr1ΒMq2@Ѻ&β5M 7)<9?R޸S&R|X_On|i,`l:Ő iI107£lc7V/3]x1n!^}$k)һXlG%~\G#bT>ys9`3TZ^_b9hp@޳ >ٕd0n:XWBS}Sɳkҿ$?}ԏy8/g#qΗr ƫ zO6_|(F9ڤ ]x=n0 @ݧ^ kE=s@Yd’ j =AׇO*#DRɤbjr& Py5`B,*64 NynMM)[G'r96>ti$Wd]zVe>E`C.GA!E_3ɮ*:N/7r\}xAn ;^)b1, UU9kX' Xxi~`:Ȗ̐C$d@:hpm炩lh Fk(o9GvKV4އv 5y4}ڧ$>N˵u8:lV.Fzqms|,*5V&j>+%HꔚMM SQk\~ _[xMN0 @}O=QO~*!Ăݜq]hHwOϺc)P*]*|uiXP| r\P!IR&:] f[sכz~N}=qztU؋3X=y~bL&2?pz}NU'Ta#]%xPj1W}LA0! |@I*M+&KS \H5:̫ Zs*օ䈋^x%Pz` 4iץg\*56Cy 5I_py;~l~ S dh35x4o6NY Ah#1NS+!K6Wr}.!][iTf+jyl>O  m і0[OvQe25:X6#umuzP_`i7GDY{ެ3"(`SxKN0D>E/A0$%BYsݞX$  8WDC>tpMg|ڴF&DjJE7h>d ѓ mJǨ2q MH.px]OiF亼^%W:gh;;c\M/Kn51:$/uޯ(`[is>BZ)܎|,d"9 q 7}ǘx;j0{ F?BRo,}qf^avObtXπ\ !MBMM_}Sɳ{<\|iX3hà1*}Co!;T?G!aͿ Vi r) EgTZ`xAn OR41`Ϯ 1a"]vi7g>h{ĭӡhC ƨܶm-Dw|<:DzUXEx;j1^>`=BH&F`iV\?{?s0CEĨb*YFh=V&C\)[ZٹXf,m 5fW ZE|Ȁ}R[CS^^4ec_v9UƝ/y !F*msL T!0ܾnOFQy\xMn =RCTUms L# 3KеVD`^ի5q1̆C\H$T$5@vƍ7DAŹig2 \rR\n93qV)u,^B.WwqV>Ǹ&̈́YqAUtSzorN >\'yx罶"B_.DaP!+U s0wՙx=j1@^P"`;;һ(^JF%Ϟ!`JazO2Dpϑs(Q/D.͹]ٰX<pLIђGj7}{/?Z$}k\KcA`8v?npd^S6~n#?Y|v[x;N0ާi ! -Θ \'bK /b cqmII=.$Oxږ`SMcHؒ^C<}JuyC^#/4e1*5t$o`G^4j*&B31DgP}=,<)VBxKn =`_)x0RTU2`h,Iߜo4-XOAKyM2db=d3zr24>"!Zc,F6e2مMZI>u|]Z:[\ۏ\/m7b=} H8rߡ}vIC!Y%xKj!ṫ ߥB=Ժv赳-d~CY㡴sF֩yCX :VQ&x ٠"嚸d¤GpkuPtV=Zi >56{ B-+nkYjD*]o,0:o[wX_PX5_ #_xj0D%_ 4!n,z\%.uj U(,B .eKY7*}SuF[cdF1w*]tFcm\*Z03)bf;H3܇8gLyiN"eSj[YK)cόhU[ Zb=n?_cLFvkX DSB)sB3d8V. 't}8 >"$`",G=3\<^bG1cXZt-Jʈx;n1ާpvOBQt4a%Fl>!F| K(Y1DJ}I׈QTk%bΖ T\q{xm|[߹S}D~}<ξLe3`Em+3?uPBq}$/?X'7@V۔x=j0@ާ>hcYBrY[cц>>C|AmX$ eG[&b٬i 1LWlTuAkŬ֓]pHh8dO]bs㓇 9:TjX.覘(Ώ[ԫ7n-'+]uTLF[@((cXPwJwEt_+֔xAN0нO1)q#Ał]w ؞ ؕS7UUBBJ(N\"6u.96شtX$FUm@X-GqZK8/u{wxնm޲ε}POMz]La 4z7-hZz{t^ 8x<\6h fLDB33Ku,^,Qd0\oxKJ1EYţBD7N +$U pιшsR^9iHFZBY4&/jN,=8F3)LސPa%稍Lc>B[ZzzSUrtj">ZhWSpEOR۶Uh#T9C!V1xj O1BhB)]36ĹI}WpL)E(']lepstECG>gf kXcIK>g/+uQ;84 n+t2]R?~L=aSC~5/zqZIO2ANwBh7Č ;Oic%V#w_;>W!F3&vpԖIMrPy:xKj1:!d].`ieFjs!W<(YtJɻPK(&I%v:19<蚽 XSV++ y~puy[#I}r92Vxv V)ƌ: y0SP|cerϼ/(/KaxKj0нO1tz2MmH>>Cw"h9K/ׄΡ.(JrmB ))7ة2^8MHcH&AS4Qu:+nK>ˆl}>1vL͕ ڄ୅a-}_;/+~p | 59/ v%X8䍰n `ѐxKj0нOjH$Ǐ U7DQpb!$#"ڇF:39ذ2xX0؇Rk*/!y4/ިjXTmt yC:>wڊB FۢeZ8 3J8)&(SKnK- !PKce(!^ȅ'oxKj0нOϒ !>[mvBn!ZT Iuu!9Ld0?G_\wX#4re0(LR zLeqIan6q‹7jp+?+6:bײ#P;ޯ[sȢf~gc4H+83;O6{>{q'r܀ <_{:*h5({ 76z#twĂr:r$λ]ڒxm0 лཀ!E{n@8@,23 dеV3'4m9bTfS{tĘqnB!]hS]RTܸ<:V~{{f}c:;Mz뵃7mV!B=WWhAgxr_q'Ta;Yʪ]xm ;UpdD æ8-diHyLl}5bj7uÕu!Ѕ ØJ 4>C\SvmS?35Or*;-SusGߌ7Fen!B 75~W܉ =#J/7^Вx=n0ОS<)ox6gH'P@5G"S!G7!lkf;p&*%Pr!Pn%psv& 钕zp;%5y5XyK>}x *'R49c>z(/?dPy XmI9I:A_vxm л20|VV- 0 %`,F;{/ gcq*ergAg;O8:Rdd9c:"]+^] xKj09 g~&LZz H$jvJ..eHԪa@9ZjkuA5_%qɷ7#_wTo477@e2Sh Q D> [=zFǶ&ax9n0 @^P Z(Xtr ~L"ݫ@HU u\ri57[j ^y ]L-G<0dg /y!Џ'| y4kV<7Zɇw!7Qc7nP}m}d_rM_:'X7\o3MKX o3Tq+T֭xN]xKj0нO}}mC(gQc5EuI#Rf[3X[ÊY,G&%MبZ}&u.¦)``֭'r禮\`Ou)nyD͕Ci {Po SEaz vghpORVJ;w4~{~^x;n0^:R Hܦ7YF$AL73"䨬tnSUAOfʠ:쥇UnEG]oѕң[>N 7KcNN'\#/<,:b'DmuM9Jc"0XCW}'c_ i@r^i c_#xAj0~n9\ieJPJصVMn@zƺŗ2CBY ξ2p㮛B)ǐh(;)9J4:>œxH= 2J emۍ7n|ik;qqoG_` u OKqۭ+0%?iexMN0 @}O="O&C 'q:E49.H[}zˆ mu}rbѸƒOmzc50ٺ6\J^ bVȡsvvSN}tٻ?S[~\o;ʛ.x+xcBDZ '  ?!gՆ/JUcxxj0%ْ %Zr*Yߏ?ׁF+ڔbh)Qm_`L\I Gl 8J yZM >$Wܒl)lX6C ܹuMW>IQ_,(}|JFbűXL.|Ln̵o,~2wn`G3N^&x1j0{BgV!GUKF^'y~B~jFa`}(1< <eOs&%Sty& <l{a,9-O$GѲ̘sP"9l䤄$xSﭛ[rյ۽mi<Ξ.c}1v"ޡ `mVU&i~rvyaċY6#smCx%ϽN0>O="r' ]Gq %؛!l'1bєDרQ'R9CFNJ;{<0Q,`%y+pC7[B#7n4top eW>0%5RnTVKOqmJp "x/|e^)6\gHUgTUiA)lF'0TP/Zx%ϽN0>O="O鄮8QG=NLjFS|4z5 vX)fc&/%Vk?˔*j] WVqA$Z= eT:ׅ3|PR7^p NΉJWJ  ^S؁iPiSdxMj0O1,}!FҨ1Ԓi_C 6#3hr9b*jSP6\Jpb3QN^;qgxNflN1&gR!rF::[݅,Cnعގcey9huw>OurltE8 ,U6DkxUN0y9"ĉBe{%Ԟ,׻ !| e*j;ĮPjآ*V10RjBVvJueފa|=ea6(/cfqM( ߁n *ҲxfH! rǜ wkߘxMN0O1{DNc#۞?R)8\o>t"bZ| #-ɆyҺ.2:5 řYC3119jjTaȃ;ܸW|[_kΣ'ZH>E?i LTZ\ QPK+5lgN.܀Wvt0;LIRvkxAN0 E= it v#X ęU 咉@H+\Ԡ5@ҶWw.h/F'jV̔ p& 4eqҡG^ni+JLp{Ìov=; &*/ ^jm1(j5%BJȩ U6q#{P1]k ORٶ&.BF6bw ||!-ޘ)5 kmx|_!QxAn0=}cjQl3A$Kз? Q%V2kBDC2Ck6_8W0q cDCO^wF{Y %dϲQ %e8v.{Q"');hh[wKH؟`sG8Ak[l~gcxAj0O1cɱ4lEK>(#rW[|O &u:j2k*rJӞ:Xu[ͶP5`jQYmȨ^ѵшՕ]eg΋,1yWdez_*n8 \e7jQmi"p]o=,)Lc?lsLtI<$QVX>ga.|௷1Ey=l^>ձy%xEN0E|{IvDEvI$bG΄}4L5stb |gʶzUN:iUpVkpT; Ck- o,sqJ|!D9B&G-lcH(SkC2O2#9 m9󔖴c!mr7[={u Zh*auy{_Ȅ7ǭq>9x5e y*׃JHV.`xUAo0#qh8뤪P.Q\xcؑ=\ʜo g" ugsP=Hm'zފfLJ&5h{SNYYgF7S)?)GpϗW`xmOp0ՠAi,S,}9-i . _R^B%my"WYF;hZ8.)j7_Rq/N)R3A_g-h||+~1 ܞB*T]/JffpE Bzg_y!X\KO6`SĀ K7r $3_T/, ˜xMJ1@}"YmRI* D"ĭY\肇 j`+9k_?:20 D5d|*?(mK 38'BJ輴(YU ;TуReQZhfڶČn+)mv.#IeK+eƅL@I;<Oӄ%~;pZ L8?p&^ Sw"xMAk0 B(1;GI<+W﫴'YHJBvukar8kҺR(3Xꛪ'عm'o\:X$Wx$3+0}ߣHkWx޶3 DS u@,^jIfx%ͻj0_q,YXv)Ҥ )Z{ l~24sD`~:J$B1Ǽ9Had  a2ImE)YRb : |` oefc_O\Ŭz@۶nksn m7:T^Ա^&7c*v=xg+ehsm8Uܜx%1O0ݿf"IXnuD g%ʾMoޓLP{.l9Z fJ 4ZGcvC:hgIĦ8DLBJ3wLp(vJT6Mx]gpT  oi+KUxˁ"3U"y;׷wp}OuY# z,%Lba\o LA8VK,`x%;O0=΀"?$* Uuʱ+?Zq3}DF )*n$ZEΤǃըv7L G'äA.f4ۑɁALZkbJ+9x>11(|a YK}wPs `(.y{%h=GLfJϱll3}OT']QkJx7Mt]Ѻ:o\Xa沕rXwJ/ܲhn &P3jO} 8jx%νn0 OAKCm*"]!cǢ-QX $9}:v}w533{b*)Ef v*cBRT!8T}!v8XC8RoF8)ZI2|q> r%ؕ'.m^@mA^ԽeYZ9ARpE*7 _~-K[d͞l3mz-a;}qo>4q? 3>rrd.P3Y<.9m{6la˕x5?O0 ~ UMӦtBp##bp+Jcȟ;>>,\j_',\݌D`9=u_(''m GɮRcڎ갖+'xApF8叿)>")Ъ[)1epε N>`s5S},yn2}r- ({O4{ٵLP] r~fKȎ1n0a;6jf=Q_7m˗x%͹N0>Oq%)' Ŕ! /ד qN͈XdVI3<{鹖>7ڌ ^K7Eo8r  xڛvr;L1q7Zf K pQh<}m[j 'JT6jnp?c+K_e>a+9vxa_#>Z^ ve,PMeυ gK3Ƒ5bBn]jYx-ͽn Oe~t1St]2J(j7%uJf:+%8 ZX5~~n6L hYiqR+7i֪`HIr<-ʁ_;Gm_@BQixj뺔B .sX+iX9=Sm=Y޴/0 l>Pr wrHj~'%`%h`1(\)JdbjU] ʲǶXv+xMM1 8%UZ$X ni$NZǙKNyNLnjFՕW8XkpvTv7'd t]mTijwcŪj t _c $[oԦoӍ=ml\1 Cq93L3K6 l%f4EJ7fh(Q;Mݏ +zr,0AlHAcvBivy9q|O Jπ fBIg  %>EX y/+샀.C:Wī!sJQtUR18pvtE t ~zR8o<Nj/a+EUe.t`tTZЕH<~R2zE =ox%;O0=J,<8F*, {ݦj|픿Ywj&A9L89?P%Z!х豻LB$3)qqJ5A8V.l>(iw-$ؕ'*}^M ! <JJ . '^y|]yor oyOTAKg >2~uHo|oH)B`*PsHՅ.Tx%_a#x%ͻn ឧ>e.6 Rl-֎lqSwZ!AFgӣET!H$%tè'I; Pe(*vO&`&o\jP~Tc\NA |Opf]9A*9j?'"oq s[2fhKZlףR]DJ|txzh/OP ->)3MNng Tkx%1o ݿJ!RUG4*߯-{0Cd & cdA %c] }iIʙ@DR.LkK.7M zo̵/+/Hwe[ɵ ,6RZԾZ3?p"4 `vf>Tßx%j0нb>e;*E(xYƖI?*ՅA3F+9UD&ۆAiCejS]ka ¶]cj1YR LTNcqr:8u/@m9Tx"e*uN I4;8N~9+͇#XGCߗ3\V_9Wrh opzaSIO;!pz}S,^| wBȇ!zh'x%j0ໞb-K$BHiPȱV5I_oJ"4Q4XmB;g+Gq)6L xVdF"VǸvck8ҍfxo)7@*i:)[m#\ %pc#\&^1,X~9)&sM7MwA`~p)o a$u+lXԈ?Uxαn0 _!ɊbACej Td@W-拓bm5Fk}B,'gl*`r~nz$ARcUYΦ5`aeeۜ)zgwHB(pD3+Xg^̸)skߘ&ҝvƇ\w'KϝX3a2Qb7zf*;<3uZx%λn0 _AK!ɶEPSdNDb WA9K.dM4&(夕yJLQ *!gT4Z1Lc@tkw~r>B7aWie{V4^D.PJ+38P3'J1`\aE8 0kñk+ex X_atRLGaҞx=O0E'!Ev1P:tbB Kؑ픿.[h5t8ƹ뭑cWVh.͊B'I|DzoyaZ^7KLpt qW 矶۴=bui\\Jp! e p%n%^a7X>cZ[hu TJp êPTaFh-%걐-~d] #Z %aȵN1ӊaʗ W[7Lnz) x%ͽn0 O?:ұ@Yt6 I_ 醻5F猍 ;;D9ѣqR8:iL¨l4b2DVlWԃp g|&&*}_A* xm28 n oW>2?^(''hOP7o rw:hT֥Vcx%=o ݿJ]!Y`*ҩCƌU̽pK3sJ"aN9#N"J F`Tu O x1=*;kǁuBN.4~/3'8S_G8#6 ;;#M5m)8cY"fx/|ôL)hzF*ࠤʉ 6tH WD$p3 [)CI> Gx+g|i_}bxU=1 ~~%>ĐIu :9Gs{@C*G7%<YBFyc6S ZO݁rrh uE5Y[ ZGxEPuXΔ/3o ou~aNK'IXrp9QfLnQڏNy(*>OLA+cp3%>?;tކ80.. g|&&*m_Am3j۶P"dMp[x]D99o׽P.m=G޴VUA[8/x:[90TUpUx=j0@ާP0Y2~!4;4Fmr!Ҿ' Q:]hG+QKL[%MglXENټ~`иk-bZ2)ٹ+.QuC[y[;}\Q^3nZ=iC ;`cV{b;c3Ԩtԣ~FIV9?zj^+x]Mo0+FR@nbTB=T* {1rȞtIK>k'"0@W(-(:jU{0Q`W}uВ-ԾV-gb'JGr}|wx4V)c 1 81zSL)msdhxm}#Zx_ G2HI0㭁8DI#{o9N WQ7< }<ɟA¼vzgyw̜HKאoN#nK8G Zv^r F 3zpy}̔?TѼ?# ^-r¿pr<B`rKAW0̰Lk,.j9J%sF/xMn {v@!R5u40 [?զq<%!0݊NqՈF9F^q#QkzL M[nZKge(No*=!&xtDqg`>`3&;t:Krѡ!Nq. ;7riSsAM,`abCtc+Z4ekIJ"f2G1g$41Y,:|躾Re˟B=`YIaGji;Oͦz=x=N0y=#Bb *T.p#BhmF㶈=fp"tNYIVmV~ cTMT"ԑmECxmp)&x48:P~[5j)S,cȌ}r<ǘݚ):5rԁ e;tBv( o,A՟Ȃ%1<C4kL4fe=O% m}!X[H3?LJk.`,J?ôΥy ɼ{͝x==k0ݿrd B!СKYz+RGܟ_t{<>0fe0aarR4"|^ ViYΙ9:وg.U"#^%<;y6gb=cXAA]Fms9#9y [(9hWSIMD #q軮jgC@ةRPbEP lDZ`覲^j{ԟh_^hG9bj|l|pxAN0 E=Ev@*p6ԅS q￯CĔc I5)#G?=xȦFm)&BY s&ȶL)T0;rH"ovCo}kvM_}~}1>>dD_@vqv `*}]o]Ni~rgx%ͱn0О>`V:Eץ8)M(^.7 ~eiMI@ [uvzP`ıAV.'7Yyd;ih/$t)EFm_AJuA4^m-$Bnl92?96˞K ՚ TE2f_v\G؈?ʻgxUMk0 ^-8$2YXPZz*"LJb[ =Wz$z0U;(Ph:猲lzЎj}1ghl-i[!u5R nkWu)pSHpOH#SxF|rkPRFZe%aGfJp>3z=Na g KH~ɔrÒ, AƔxZuGzBc(?_'xMۊ0 뉆drZBKb[з2@ml%}oK<`yZTuMi4X"K,O"*[*2ѓ괫L[mTY3+M^%i$p=ȟyE|;=: _>AK"i"]tb< <"C?\OK g,Tf ~l[wޒ2Xј'<xĎ#8" i܊e#iWޘ ϰg`_@*M@hvzZF<;+/P-*x vBr<{#WO?_GX[l5O)3oCEvzn}KP.V Dl0ɭֳ;f&^:Mw ]ӛrx%n ໟb\)rϵ?ƍ"n^f>Te研K^c'B50&L\K3,qCVi2F?w|ȭTz+udDͨt_$s_יQj7:G/]˶"-yβfV)tZ,R˱^4 }ӠjX@q85XrW͙x%j1 EZ< $P"]fYm9[NmJGD錕C8i y;r[QJY1Q`@T?NVjB#B)n$1^Zo'`9&8R:^%^16n.PnSy+O Vc㲜)!0%W wLˮdJͱ$K>3m  U6Pr Ogr"۹U;B.5!o_c!xUn0 E [/y""2B Y4Hi' JsxnjeTOMkN ۥNzlb׌!Z3zSo;RjiNMWݲ:ŕ~#Otqz(%дTMן{0m.Fdx QQtx%ޞ K)BYSW͠Ff yF7x9ޣVVN A7srނІXA{&qY AyK 3+A!iDb3 1 MJ•wsV.,V⊷Cw%I9 >?Xw ,% Nxͽn0 OAْA=keHtU醻҈1K9gk!{CBvh`Loq:cNΑ]cTиLgmQ[b*pKvsmwP PxqS"ų g-U[Z{=[<,m\8} %xP+a|3cXA>^y~1[Ux%N0{?H;N:%I{Z;fofA6`͔FCJCDmdFr#; kンɅ9{Ovc^)<o$ m7~`SY9Sxc`}YxM*osG ~> I )q2_w&P'3C9[^ *w;ɶ{xY0ǵS?[QxAj0 yo{(eGȶ]Q7PFT"/轄LN!1%G5X"/ӃljxV`tm*[NʶVf_ "d32iu6gOP0"ć0׾ʛ7s_~~ގ]>Yj2of<LvWNrJ5nv.hx%j0E{,a&Œ&)Ccid;5Aw?Zr rNID $@"ބthtb'5z%71MVhk < )ʹ o|(Sih$AF' vڑuG Ro[סUMޗqR8(2'o[o\zM7 2swJWZW|s\nZN ԔTmYl%ejv>2\g>e$Ѻ"">N%U<rirm{QSI6 Gw+gpboxeMK19+l7ɦqHCJ&Rd3%mfxޗ"g;tV)( :y6Ψ^R;6ad؊kdEkdӶX69EPٕ'Ji)FoGuZ@Ri MӲ̘@1[F#謲eUr JnV5+j=?3˰&z SoQI:oL ^)ouXAeM? _ 'G*wNlzy^2ֶ_A5fJqt;3x\f3F:dz,ߨ/gRJgqHdڌ|NQ{6B\-FP τ`LJ`KR8o.VX[] A.?(;a 3ݑ0n/X pD{ug;e?="^V^н_ПQjT"osH_S΢x5j0DZ0[6CP(XzXIŖJWtO '"FKƉAw:3uN(b; D~ta#z{-̤dD/1ҙfxKb}>Cܦ ^IJxuf2c9X8^a䟘CɔrcI|3m i)BU'}1W/sFm11ԍ y, VY펮1suX̔)!X*>6nrMx%ͱn _}$ 0`#R&e/ٗ3?DjyS3Gk~v S@k3R=LTARYyFO78:QFJ44";ׅ3|P o'&*}_A*Et۶JnJ n oW>^(">Q G'=&**O8 ǮG}bxm ;Upd`,EQўX0޴)"'H )nDr%{֪NE;S"}2f!՘'TxɃq]on| ?{A>Ic.|h77Q[;DBNBE)TXjI>6zV۲G4f&ؘvIz &o~|ߝηk 5EkUC~Y㴖Oj-r?σ-(tg? %nVVu:v5/p5axMj0 @}N}!(c[Pnˬ{(@m[^s36=l%c\(3vn nSʑJDh+f5#%J\)^wiCcӣ!U.'?Q׏kpgޥXo` xC8ePN\9Vx! g3\xAN0 @}N="r4Ib?@Nvh2r\8==z*̖S1(q=2 3i ů1' W%csPR1rHC$C ˂~&C>{]^юvj~vz;dcWYac2ǮBUIBJ-R,:p웻?axAj!EFmVCa9@e!ZVO>Dv{_Vn +K0u- KVml ѨumrŔ.\5y]@U'xp]'7>_^P~ysҘsdD6eA[]1K4)[ku׬ u )bH@P/L ]\v˦:,6\1tʃܸOI]7>^h1TyI>@"Zm5E*skۡjcʠy;w0 .Zѷ["xJ0F}ً%!dL{+L >ۜ0CJ`LCT0pJ9ٖ&vxq2\}eHC C >-.g{T:t;vo{}IdNs<%&++ Bx2}S g%JJugnGd[. IahxAn Eb*ʺ04 c8~8DwO?iD`7358RvQG {ˮШ &,C7٤%K",8{%np%T9*\~g VNO)s@ϫA#| C-M(٥Q(σ+NKT[1xO0#)8I4hO+ BZ=nL;N;n{"ȉ2ޛ@FTT׬~jnQw2XצZJS%ج+iMTiɪ6z\w.i~Pؓ/~GtpӍX3ThX> ɦD ]?%#\ɇfb6e#D6 (~{ Wzɑ~M39MNYmd0"?Ve~`W(Fswj'xt굟*v|L'5>eۮRoy4gU㒇Lq 5ywUY`Iv) kgSfzZk[BUΈ;rƼlx38RY^6Rg+x%N0EwśAl'B^뤨CSc;ݚÄqbG6"9.E',3R%3A{c81;;)>&ޑWUD9tx&{;kY ~.JTo.rTy)޹HGA.]#Di.6u )/^"z7P _ʈhi]N.]MxMMK1 +rsv MDLV:vF!7ϛ4"^MVFUj7f-s1c 5ӨLjUs=F5f0JIcK:H7 {(NVp')av[r\W -dScBL$YO )24S|BUVUQ\d>p)yvVc@:I2e7fa측O<{JU6qk@' QSq&m9o 38-i9? Wȷ.Ax=N0E{ Eqki-)؞lXB0S3auQ\X(ͤ!'nQRy-'vL¼3(~R Hp'}39Izv //s NʐpnJ1}2S,c"״V K~jrJjђv8r-x+&y8ͼ `pX[[d9ה7WdSe`VENQ<ˌ~",nKH)WLR :oV&J ;Ϟvp;s(g_&`rY+n$pwm7ܗ/l|x%λn0 ]_!!@PdKǢ%SX,$*(Rvq)YG̽ B?_LPϋ&l{;x=ͨ;iW~cY9;m>0%5RnRyjmy:o"1 F"V޹p ~-Rn2Tz$OvO3IOF(-_N'qa1vV̐x%j0D=`d˱c%B(XzX+G^_i;ofު:2])t?}ըlcW%t#vOUVg&+pI E20q|#S,ey޷u*_aA5Ăͱzhk(>'C^c HLH}y /іR++&u,R|?9jweWr$+PL,:iRiAl %xWaʁΧ!L$!f$m +]G-Z),;yxIiޘ? #q}w\( .]B? *+x%ͻj1^O>+Y`Sp2eƻƫ ҬǏ pg *88\y\f2щؠ\R1kTdHNRV%(+5|=c~ץB*v>X%_Ԙȴ34y9Vުg|D_OiLxJio %J6nwtQx5N0E{H4Iン5" X=.Oׂm+(5Zj4>iVfp8^ t%?Tް^#fꙡ wFJ5Յ,X GT ΕyTx%j0Fw=ŝ[0- BI;Rtc$9Wo890CeKlv*N'B23)Z;Bq©K" H;[i(݁FQ7MR-; Ou( (ͨtp,D۶9Ն K#W.uy/3Cօz2R*kTv⃿1.) ne?\cZWp2}%`x%n D{bDr6StUR\2JrdC.fWidS3qF>rPHޱo[(5RψIJ?v25 \3ghk.AJ6^霨x!gg\TM-&yGw8ͶG.TPQoD G5q.O؉OYD*<[!0ͭF5UxAn ~ޫ"RUGT :ju"ufF92<%q@qqx; UhG9L]Z}r8s(/ˀޚծXupߨ&ILd%SI^&76^Ɠ}Sw9WEp@_Iol9 bcxAj0 E9w(-G C8hQ7PzuUKP%QN0$ sk5GH .fe$J S3FJ}R >Ŵ 0F袥ګa4H۶[pxst]w9u۳gx=n @SL#E9CR`,o=D|O`lvӶ+6~Zu&yW'&g9W.B.HA%p>n| ?hפ1Ty|In`Vim_2vп g;y: ϗH>Δwyq_{xv J8Ɲ1NtMn J&:iRxu;O@{-y(~(Bi" !{#tDVSܬ{4]ӼU܈-61gj(h# B510(8 B=ռ)+L-&~b(}Bӈ M<ƈdC6g)EZ`3L2~w)e5cJ1ٺf- ̪(S*|wd Ten!$749 1JxzJ~;#'8f, ^J`% Iʭ[91R 1XUa1oj&& CWq9x5AO! ꖅMc/bb=Ӽ.f`?_;M^&̔H;F–VA1l9ǮײWYrP#vr˹% -hnea8+:MZi*ƤB;V,LC.8%%^PcZkƔd,ȕ`UZT`U| &YW3a>穔繱޹{z3TǼO^Nׇ?'8x3Aq㎾_, Zox]MK0En&m'n;ťL-L}ߢ;p5Fs.(oV+& }k1`[);Xm錱8x ^9e"%8 cjF)/$O`)i7o8i9nR.3oQ]TF]XZ)mzT=(nQdK?p 2b /(21%.fΔ{c.z[= y{p8JB_WN,~s:x5AK0tf4" xXx/Ki%IWqN0|ÔD=7Zqt"ꥐpQg7Z MJZ#PW{;i,c'2&xQkJ(f⵵޹{*S>Z7T*6AiZKTup[Ҟ^p w(˩#Sڂj}/G[=*aaCc<@ ƙ4?IYx=;o0 w -bH~2Iر@I֖ Yv_}p)GE[a{+d[I}sRVF#mX0O 55wuѠ39k:^@^vp\uq{%kc<<Rׄ>91aKa0]COJq-װEM65BUQ'*E|p6 (1`A!ojV`2vuI93SJCu.(~|@Hc>zR!DV \BZe@J!<㉈|[kTι6ۖiqJT%RssΠQIӄoK6_B;/w4C <ɠBtX x%j1E{}!B] R )kv5F: թᎆN$P\|r([Q23ǬdаVƪ"6g' >Z>nx©_\󶿁SJ+eEcm\X*\n> Cm;[Б!TN !ݬA}=Ĉ-G2H.z`쏕BZITx]NKK1Wݲ&GwKтOa>$Yl)s1)u#Yʆdfmol:et%;tb@>դZ֕Q%5Ȫnq b+pM#x0qEGO(Uwuնrw20&ipy5t0H!`\SxJ9p۔R-s`FB|jM~ KzBp̩1m?a+|& #5,( OxEn& &Do@-LQ+{ʊۛge$xɡvT܌fD?aD?gx]Mk1 +=$i`׳3B r)Xrm$3b)qCuBHW%zmҶw3) =)Nh>*7 L;cT@i;tPF9":hs#k9q7^ O$\>X7L U.-P'NR0%Ӊ7v^W,;fjL{`7#xb~' =9B# `~0˺l۵~c6;_<<>o |9XLlo"xMn ~ziv(R9X0& FydcȑF״Z9%gP`k # P7j{{cEL{9ʼn<<' pKu( Z[)5|/HQY^W3Ex2<μwz'xF.crZ !u TU_pѾ|0DÉ Z,(/ط)# i7G[ƣ9CLy^7jNnK#Ao쌡L'xQMK0WݥiYDA((DI2V̒7*":x3A5>I5ꪒXJUh5mБ P-$uYn *!R5m#e^ ]BdmK=-po?SK>u dYՖUG"Ny[І3/' /œi9ڤBBE[<3*E<%ԈP:83 \]\nnn/`nD5Qzz]0聾MDS3};@=0{r-X6ȩ\-2ot7̋L}oU<~$ͼ:ߘ8z)< F4yՐx%N0E{HQ%bKJD1N&Aʞ,XVH%5،&$&&ь.5%sc"0vS 'ClFA?r T/NP: >5o"T̥  !u?ju{f($]hG&ۅ/̙ - wUO xE?k0wl, B;O`KA~ JM?j&!&FդE'b(f)VJ.0954I#viec{  t`sYyεPJj5u.m[2\S,c ~v җgG>>RmbqQ}<[;<t>(o~/Ra^x]OJ1+^&̫)n\T)UӼD0EoÌApԚb43%')*O9&(4 z5xȃ3|Q .OD;tu9=t۶P"dIp{Ƈ yE]BhiIj+YWa'N|Ru s LK0\mX]lxj0 ~ [:1,eǽBr,oN}MB88ΎhIkd8Zq` j?K葼A-NKv yIV.ɥ6E%Sk{[ a<@)kIë wεan[ʉ?p;'t;+:T>Bh:P[#xn;`j_X >%p`cB' XTifPx-Oj0=-G.ő* )akI~3LDУsJV Fvv 3 nG#hJ6 kVШu gZ7~`s%QJ X /AxVpT*&.Qa_Bt)rV#i M7&᧽~r~PhZ1>N<_0ʹ|{JaYxn!E{>ʊYtn#^;X0CrS\pCQŜ1Yh2j])}y. % k0ZkJ269eU9 8V3F䉟pθn@SmwlET}cK@^Tѱף%,Å!DO8Hlw+՟| .~Q-x-̽j0^OuB~,G"ݵ WgW$ǯհ|& di:NѤ,)'3i'iF'g1 |R1|Sa*pm_E+J9+V«'B޿g G\ӆeJj>J-Z3R*7$ |U*I+ѹs> [;xνj1^OuB; &s|VGd)Jk f08Fi3%/gӦU hf`Bܴ#zHURƔj '~s$<R.V ^qDr;_Jn2.rts,8FM( L<ٌglj _tAs"|>N9IZU=x5n EwMU!cթa;yTNgܚAYu@ilcR(.FNiG 1x=oPqZ(TQ掺P3Nz25a Bh+h/MmkFTFG'\(KWFj7]ڄ 3&lޝ7 WN;Ngx ݥ,PKWJwZ\A>*eexMn =`_gp>W5D8zr=L21Vx0@5`xaciK!Jhm\r1Zv&Wg5$ {G?%oqF?)cj&ī|s܏cgœ10, g. RB*FeU}S3Pۯ3a?xMj0F:vYܑFXJϨ VR xIgfdplB?;|̀)D+G켉&,ԅ9Ԑ!_b ~pH5ygŘCI኱r\%"wZ׶ 7}ҞR?|F{O˫6vF)3K嶮wzԿ]}C:Lf' hx1n {> EyZ香H'R:ެ5 1-&a:S- ,!lWђ܆`+OYP^9y47 vkPpє]-8}׃PV?ǐNX2wnJz6egZĝxj1EXƸwH^4F?":p/!K!Bet:i"\YKSY^cc$nwVM쮊Ѩ\lVƤ%_co ;\mZi)fDs684>ܟTdK ^o>AgOX ׆=nY6 XFa,`,gxņer{٘2beޗ8AMPUޱUlOLG o58-Ԍtߨv*o:i0v^G֗NeܧKERlBGgc/Nxj1E{}j% \10Jnu7Uք8KƆnakk\IJygn} Ck:H'?`ԁ_pOa݂1C͉DZ3O}pwy{'㯼gq=XT,xfnU38I' ILx51O0ݿv`'SW*, eپ$ƮK ě=.D@V鎌b#I5a3v %[VYkqrR;o%M`<g*ExΗ|:cڔ;{k%-eTSeL +V*y-Ƽ4x[IքxtJx\tS&1 r~O<ǜ1Mt^B#~yd7x%n {>NWF ,#=~,efzE> NޥaR z%{@y.gM6*\FmFBGQz+Pv+؆zq)Gqq";V~:~_hӓ_~;64:jLf(Ϡr4 @X7KV(q2F>tLgUx%j!D~E*,a{ ܶmv`ՠ=ߏ$uzPţ3EYG:{c[Z5%:7vhsd#R1-RNeJ'f*<:|>+|r"?&;֥w0f[8U(j"skuV+C\zXF;:q.^*'ٜIJ|VSMNUxϽj0O. F?eG@ꕴ gmֹ׏TS T"1Y'' hdWs!){2TЯkW)%9kc,c\)m3)Wڄ |Q-T*rw,#9mM c;&Xd/pSj5- IlnRm^s_HH:syF/vѡO}W1xϽj0O. Fpj76CZ^?"SM1|0RYy]KpqF1J69+e)^8 ?'` ^鲢#+;\皃痷w7Uu8Xb&% 9mjouxu;O1{-A/AJ(RR"o/gO~L~[1q3 Α6\!e͠vrghyof`+& dqКc?@RH֘TR'1+9x>1>~CI ZxqY\)C. pkgOgLˡfJycMj6JJ8oTހmb>J;8 ]ɭ%w=ckκ/ JMFjNq]j_9V?L~7XTb8]A.֯քQd}Iҟx]MO0 3I&8يָrӡ{2@ڄOc}-gFtFԮ5XZj:[QZ̖1el3H' 2xC[f+58a|$7B':.ϠT(isF=%۔#Mf:6l"v낼T 1R"XrZYK&;~ZÇF3Nsedf %q^D ࿕t* ^Xx 0H/32WTcP,zJn7otx1o _qs[Y g[Y+us$bHM z]g yfGի+ zti2RDCf]8謷'r\p_. ~wi Z4OS[>]/9UqI[>rS;yr[R[8v&Dm vR5o_٥4Px%j0Fw= HB![KJJ\b]+78p@8)ёQKkOa65. ;fJhl0Fjə" l>(h7~.ʐ+Hid-}󶭵R+R15O8_ۥe(ܲfHT{P8؃tr܊!a|+xot5c*a4?U|^^x%n j:S/jDIJJ9댱jw9'z]'?j錅^up[A~vG֗^G)OB" ;{tޙh8`'swZ͎CGUv(h~Pڣ}qr= K.Jg~}5Ҹb:2_@vkB޶Ykے\9?<=_lzP9NG%$,:%b(%T%@QM F C#E6sM3.%I(}beVEpTxn D{bDtRcXb'X璿Tj!RF <ghT=\B|Xy|V(rn-*̝ou 6nTY 1 |s"{-\T\O_pgmvvl}lpTpYpc/'z~'Sx;k1^B}cܻ t 5{L51<1TEC>x&ܢ3,Kv`ۀ5JmQR19|q0vyq uŲ8C͈J1A;L~2hq,b.y[&8$7tJx-Ak0llrBh %9h`ki49 y gD&Nsf]U1jkFYӇOq?2&]Q!8 ]0h'5ah\3e8R. ^1'pRKtZ~w%xڶY(vOgڨ2m\Sk\B5{6! 3Rz7(4g4WP/18HDp9/[(vא٥HA TA"A.RˊE2n@kkd\2~qĂ\/ vSM| z^ܺ~@\bodV?d͖x%N1 Eji3Bwq:ġ|>)xuGJa"ͤt@2!Fz cu)euX8 L:=iɹ5ѡGj2ڸs\pw. i+h=Uf'oHO9U$K9ICrYr[!ś҅fgVՅ= #``ݰ tɕ 5 an%2t&>T _\2;N ##q\ru}>r],6>8kjؚ1@)A:u@ ڄ];,\/&D!V=xMk0D{nӶ s ,ɫkj~ 3<0o~!-ڥM8m7*1iYzqA>ڤ1Fo;7N$B*ܩ6X V# rV{핁O9"<7*Cm:/\3y k0NylV9 =!C2Rxνj0^OuF,Ɇ#\m ~V!ֆ:yL51ˆ0B:͋f z[Z6cmQߑ 8wX1\Cͫ]rzٸ`Qމ` 7y{t6n1YW=2!2j]bc.կ(O~u>u8cN e[8R/Kyj[QBx%ͽn :l~lStR/ؖpu.L5DH4N(΋QIe爆+eB&l^{0)XKg'oG)'L.+H~<8-c=m+G9|%ݑ׳QmC+g EC&dj{ oaüҽNR%xn E{bDƖVzi [#{3ޡs{Q0VQk͡C`qlfq 8!E)WE87nrcqؤg zYu*}DLE"<״S/ɕ8 ҔtsmqYjVk`%>\'?)ҲΣHfᠷVZZxj0лb-5ZKB(ZY6n~s̓ E&rfD3& 9SP9 D$gqcI^hut޳1ӂw n vxmNN0+,qQPoz8xAXZf-JҲf)atdgܸ`=oyo9PPUY+ѭl7Aq\] }4D_qƋttPd/6m,S)c.6) \ ^~m´ )7aPj עH:9Hp[$7L~y3 I_]nmC*B+ ^%7>3}H&O60c^Ւ͜xMJ1}f!+? ~ ؝!mo o}άLq &4n>XJfbF&[ȱXo8N-Д[ڎ!tP[۔^'w:k,Jgb `m"oQze>tYg.hןxMN!@=`o$5 1 ZOo{_ lsM1/5mf)m`RD@,Xj"-UK5'蓡>q/{vN8`ȯ`SaqI;EDZ3 ŃyMdyq3R}7A. sacxMN0 @}N=R4BlѬ98L%W;\9z`=\L>!\C}0`ݶjNRNeEKEБnХwp>nwir#Ǥ>aa99*qHzX` 6DZ߆KtNT/z8s&PZQxA {_wBBbWӳ\laX>`F*1zmNGhhM&h7b|+,\"[e]Kz{pͷި6ոHT!YO9q&B {޹ =73?qBٝNx340031QK,L/Je8*4`V yzU~ F"'e8߶}SasGTI+Oy'oVwݿ/l PH+)LbPkŒON"}HIMLc0P¶;u+6?Uv Uz5/? weԊ܂bj+v;YϏbBmj]d.~aͿu{Sb}M5!%9 ݒR[јraz1Tsިx340031QrutueTqW WTLV"(1$H$d0L&pjiei.-&8ncnjPPZXG8anoemWh)X(Zq8Bx340031Qs fm!WF)9o!D>U%5)31ACq붊CVo >=Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?!qW:ܙ)..,{܂~F Ηݞ# 8u'tklXrT<Κm!T0(~7z+?N+5+),L(aȚjԉ-PE)i9% %ˮkMìWraJ2Vg~J\W=OMJ,Ne0xiv fIBjv|~#MqSh0A*Zg{ksx8l9誒xO>\yKMiCS\4[{]|AIdIK]` +s rRDXKbj?&P5y%z) ^!;5vIh #{ $1'o@qGq"~cy;J)($$!!6UV% UWtMQ|\$nQ?&9"\m]w.|*߰d!TE>Cƻٲx1totX(/.9҉mL_wq82\ਸ਼[En"W`*R D?l䎘#z[w:mm*075U(*er-6*^@8đE% Z|wȼ&:?@(I 0t]wEukXQq[6/A0ņ@o܉ +,Rjośۛ^c SPRJ)"gf*H)H߸7_yW)GMr*,)POk7~uߤ8%kAdac :K?\~dTA؊6 [~Q//}Uorsj~={C=ZpNA 5y{溜Ws!P5Eڨ5#Ĕ픅{N̟QVUP R oXאGo{X SPRs8pڊO8[yTAIjnANb 8J85N>qnp8x340031QMNMIeg߰XG'd_dB䗥e륦'3|c6iw|q6>@'%3\.|Ⱥpj__*.a2Nx31ԊҒ ŗ[l:&`%E #<ߓi / -)J+./*MKL/f},t_+]l/?x340075UHHMΎ/H,.++a8RAdIkXOn{Bpx340031QHJLJJ-JapؐY45)[cF7/$8E8aƴ{}'=xD`89bN4zi N^ɉDl/mx31brI gf~vF\\̼̂brb??6!n #bx340031QH-)J+./*ѫaplɼ/n_K@B]hsř9`%3?z^t wsO.Ĥ"t4S-o1]n=U`Z2!J\qXqWw U[f޲d)r:TqebF~>BX.{̜ Y֕N^ph x340075UH-)J+./*axhZ]U&mgʸK!DafN*E뜸~,ǿBRtӑLSz½˸K 0% u].OenzS T:8ɜE.弻exәdUbČ|R]#ϻ&ZM1zC}bHk aTxuy T]Ei%i씭R]^eraf25dCRRY^($Ke)"RRIL3s=<mmC}M(,⚗J섖áI>邨҉sGywPC1W{Jd']K@VOQ^ѡQX8}UWJS?\ph0@@Bo|wT4SX0OH,KdK{'zu~LHD TK[Cp$!Aaԉ&1yScM?x.<9 ZLkxYMWv㰾(? A#y'5}S'tD2 4!CKBTSV`c:CpbF4 2_3=w3z/ P8h@taE3+.8H$Uٹaiji4{|}d.vнOYƂs’5Cd!@lgj&R%V8 P,KDV\7ډ4xݒ0jPǃb(?HbvgOahQK|,s_]uE|'@1,LJ=1hZ>H%FZ^z#(X(q<3#\iq`&"ß2`nV,P P<%泞jR|_nZ,-}@0Ge>dRJg|q 3wl/<1~~¾kt7i_=$, ^յ-:6՗`qGE% xuDwCdȓ?|Ql/9sI сͽ =ðuG }ViкR3Cl4 T gK5=>8L<./!o/ȿ.WLl(qdgtŝ/ ˴tշtK'"rH|[$"y.aE,SR 4k k]m㌇ay=+%86ux nkg a2 }Bg_"]]):vcN5&VM5k׊1BzzQ+G?q3U VSirH cU{l1wXXA-p"o/LsT`Iǐ?aPl$Ux\8beS=g?k@Ak385'YlJھϪæi߯Z6 I yj/xB]ӓ6;\j/+u瑙PY1߹Q]\_&~JN'%A'+fi%ʕ..0B3} }y  .a~:A2*%*,Άh+kۥpY<c`gl|q|eo!a(]n(%/n18U   ܞkH{uiv/SEw ;?`hhT}MYl!U2^S]fp^1?LRE^|6jT~ck _!{'hu /ڌC_}iq害4;b82OU0H߅Guy6$Xr[)%j6иB&h`pJ7:=mC Jʌܝ.XSQ(?cx- Ir"G'ɍv'F?UnE_{~]lMFŰ.KzQ}2z}YM,Qqyz1Fp ~P{baήu\WkvaKv)K-Px>@ξ|kЕ2^` 3g9ݵw "[o󌈆rF҉XJ>j jy9MȲxhX*ԩkΝC_^;{ݺ_jѣg8/=6E9DVOǺ헨Wv[r'~F5|N|֦uzH^#2vÐRI#̶:5A)[n+YQP8E}}i[V&tm" By2{oXbrYrWmQza]lZKShzF'Ԍ# pIYMs7MMTAVfh·\Ls T]{ AvwE1X?Su{|Y9]꠭>ԌdK}W7]!~Z! "d7N;V^ v-&Ocl;WP@^*/רxH\[{V@U;]LvI?]~ Ioin^aQGu n=hХ(i~"f]}4txDe!].D?"RA/KwHYZ&?$/9):"7:3^WXd5.UlOSLs!#}Ylxoϖc?=\8<iT~(<d8hyVoOc<Ed7t9@c v zn<*<a#<7N'v!N2gV}G".6$.[4bhYӚKlLrH w2]L:ڞ<"'4IK6Kq9{^nǸ!e{? Q=YFa&~yIqRvrkt{*9HuǯZj@%Cp]A CpR@k:OW(q^G5$Xm-5ʥ?wU.O/gYz*ߺZݻ_Ι ,%>V %ٵt<Һ 1Áf'>vma<3؈~w Rl3=k^ UZ_ZðwnL?ܵlS?]j׋a Dx340031Qpqq (3K,ccz cOQ2(MNMIc-kba".4ZigteyF Wk09ږ/,3*SsR Rr"\_rDoh~/X! EQPQ=C=3r,x%E`|~as>Ն~˰LMN֫jX}:2}i_V4yCدQћ\+?k{X]^=_{Ғ̜by&e {ZT]-=NYY Qx340031QMNMIcx*?iy 'šWMh3 f]KXp92Ԣt-V/ŕjpnCE,x"d[zsXDt }F(_1,7?%>(l7S.o xy%y`j֬JZ)Ð _OIC;vǠ<5,Gpx340031QMNMIcp44ײѶ=xWC4eyF ;$U߹omQe?[@U&04JI61{򓄯f*O+e)iAc0/lc:4?% byʜn-=ze-.m ,='.&gȿ¦6vS:7w:D>?;Yxlx340031QMNMIcI~-^6DSVglPYk=]u Yun.>P)EfzE9 ?VyZ|7o)u(*pCɭf1׿[ջSi|NfփwGMl.nۜXe&qrϲY->\꽗5k-njYdaS]RQYŚ9R/<ި_sMSx340031QMNMIc[0)).gnگS)+36bh䴦Ź;]ՁLO͋/(M*.MOIK-a2qo?Vs ƞ4Į(%HH?tO<^\5$-)P-`ߛml;0;-󛥥6;cOIJ+ϕw)z4.$~&T9ؽ%9% _ZٱvZl'_0>4%ld.|Ki_sd9P9]^tm7{jun3YaJb:XvL7~Ft;6##E]fqAbIrX1˹E-f3|mȊӀ+\kWuiLRtp{9S1!SsUg"bԪ)_](TcѲxgVlƯQl֎=Vo}sH[q\Hi~r\R\ ++H-rn>sz7R+(f C-X^n kxU{TgqȉZZribfj-xA,/KԘeTBr^ uE-Skir{^^z{-xH8&{0Ač S5_EB{@"JM%K+:)[^ٶE"40Mhd>6T>\l(N q/ U[1޿-LВKFxZoÔ!EzcA_JP;wNyk{qrK0 (tѭWϤ3`ob&:f,T:xתif C=e[GKNrUl- x_Ha: &N[V7HJP 1SgֈVon9+lh58+j U] Ojؚ~ D!V\/T8=E`$ Wd-';u웗nZ;q9yL/[)ՐK Ҳڨb! DYXM䬠Dn)/-jDSĹ+NJ$T{.jʭ0H.I)`K<|wWwZ$iHW-Rl\k!.ڧByL<1@mD4SYOHNF2&sc 8&}ZvqGȵ&B~8Ҏ Y3d͐@ 9L`&s#>uD_ػqq? albg 9k|B6^ƽyZnSi,D5'Pd6 -Ѥۆ\A E; uׯQ>7p2ziB?X oM.!r쁭E#ŀgHe&Fsm*jsX _<{I~6>|7u v\,+?rs0 _CVJ:Fv"߶S+1c{!g~URUj6R,ls:u@Q}c֔#|M_4cx340031QMNMIc*b{Jmj#mMYyfz[waCx='kzfɗ@Uf%&%$%0du^Luҳ\)/.-k1zY7_I|ZC5i]zOx~A-h M ?>t~2, 1W/Ky9FB}_p+ndE9 ZT9ǝC+Ȥx340031QMNMIcЮ3LG8K#EQUh36,d|˺ժR|dUY\R^PZZðe;[.W}Wݩy=PRT0q%{f/K$='S!LťSݮC~Ыͫ //7.ˌOI,I)SQl4S{_XrAR_ TUZ!peӍx';!*H,*N+Ia`3ܶKA|y#˄ӟ<)FWhV9a‚i'h16DSVglk|E75߳ T]Zx/aTejVbRRjQJ|qIi^jQ REu}|?ޥT1XMPR-9> I#n&"ִ&di.2ϭ>`Q4=Q+x340031QMNMIcxȐǏznu厚!|y ]GyjXdݦ.;9a)y`.jKeJ3ωgsIVj?cQP:3/9]2UqU߿ seÔ5άw]1(JSRZTeͪ̔>Ң˧}@RY\Z?7~q8GS{ɩ5|^ rx:lsd*.*ڑ.χ(yx[ıc0\y' ,}J۳ JxF ։lHRֹIQx7V E Mrr'gG&Y2 l9x[ºqs8#ux340031QK,L/Je8*4`V yzU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1,|lרu{ C'3̉th-Xvm:36CdS+s rRNرd>?f ն*zu!Jn/dpr}-)fڊD 9Fjsx340031QHJLJJ-JO)I-+J-ge:1s j'"ubb %E%@28'$3?ԉ#etvͿ)zj(Tx340031QrutueTqW WTLV"(1$H$d0x4Jfi[ܪ̥#鮮@=榦 EEHz3놬VvAퟂ5 8D=x9x?f dHKY[4NJyҰbΒQ4 \d ɂ(x340031QMNMIeg߰XG'd_dB䗥e륦'3t60%l_&WI9{3TaAQ~rjqn~^^rq1C‡ 7(XfQUm-xuy T]A%DJ"5R%Q*Kwfa4 e"yE Pf+,eɒf4sϹ<9WG[P__a z &BX{h)2$6p1U$|DF>OT g?sMB@]8}&, ?RwM Aʞ"SVi!ԥ k]ץbgFh45 2dzK|$Ք"t U#?z}=]tt okUA%x2>~oGY %RF̵)L!Q6:֠֩k^qiu5DvC{kirVbUΤ5G<;5I#Ɏ}#2x kjv/Q<'\O6f:*@ߙ?mOYA}ڊS\ @$A$ѩ32[iLk]?r ߓC*Oq`XJуYE> /Y{K q&Ll JYS-h S8v`j\j0v3\v1  H4HfhykNj >[vG9P  NwuhvVR Uovho&qhMw]KU;e^i]p ҩ!___ jv vP1PMvPS@n4M!vўC#e"ٕy\HCdϱ} ۞Ώdx ꌝI ޝ,^~rWpz9WW~`iJpBk9I qE[w h UX!Zs{%#tQ F![IN9I;*SLrܫ.A d=)!%sAw.v ry憋~vVH}V#lœB?\K!epz,cEIo9GhǞRFҟvr[aoT ,'{7fo u낒K>i_9ItuʦS' "v\d;=9lPz-*R=>JZ>aX>-Z=*!N"7`Z3fhR+{5Zv+2/yvrKي9̙/LÅ>ϮH(9ҎYR1ƼnW^.wMZx_ú5uhT[,HfoŵTt؆9x+E8U*/Fܓq<}k' bo:e 4}m*9$j}ycE1 _<Ao:gZ4 cVt`x] sA}Lc)BX^]/=P18CcT4 Ω.ͤuE|~q{XbD`bE:YAf6K9̜:`g/[4V,Cf8sꖙ@uZM[Y"GݒF?CafkTlr'c9CO?cc :zS%шEd aFi 9#y{k{(T䁧S#z >{NwoԸ#tʕ(Qƹz٫˪%NVtUҡso\<$gi|7v?yfE"rag_m(%'FBzw+ѕ~FJK:gge $m+ǜy|ӄ7ۛjr&~j)뜽q/9 s-cbĎ*Hٟ%{>+:V׊qU 1g${đp~83 ɒ? x340031QMNMIcu<-Z%>vma<3؈qdz8_*rN?~cԬĤԢ$ԢThUJZ_Du5')O)*Kfss_B*%O} wE¤x340031Qpqq (3K,ccz cOQ2(MNMIc-kba".4ZigteyF Wk09ږ/,3*SsR RrL6M>7]w2 "-3ss})2תAg x%E`~"BĴiGaQ_W ԰t/eҾh`_ɣ( 9`]M2q=(*KK2sJYSf^YJЖU֦x340031QMNMIcx*?iy 'šWMh3(}~Ig/駹gL+K-a XgAsԲ%3"ZdZyprmV@g%M{&\e6ȓ:{߾xַo/xy%y`nݾn;CVe}`hx340031QMNMIcp44ײѶ=xWC4eyF 扚u0u{-s!dԢ[חUH>"fF܉c?*O+97y}S f<ESZ V{Qkb;'~lj3j7>b*/s["6gux340031QMNMIcI~-^6DSVglPYk=]u Yun.>P)EfzE9 YfLc~]}]å/-cQTzqƆe5wJ;_2.=4>'3 lgSWM[^D,ʋS2SZf/`3ݪZ?ͯĦ%6X)}tUfXw)aS]RqJ޶}'zl :)"-Sx340031QMNMIc[0)).gnگS)+36bh䴦Ź;]ՁLO͋/(M*.MOIK-aPRR5.?E7TmS߷q,?[(0IWR%7?Re5n}&DXʽCe|~JR2XD[#=yYEBs*$5 '$CṲ'%N wUʎ3rҔJsmʎmsɕ6* L΁:5;ϓ~tBi”t팙n,ƿ ܍zOvlFFĒ Ȭ|]nJjqEV XG;da]!"& {-~^:{>(nEFBBybcS0^~aף߫tyׯOL\HP]Ě7ttS_f`de`u*WECMtξIMn2[vQ>нKiTEeV>:Bt Q?K;O EmiRN&Xmz0-(\h ы~$`b/ỎBӒ4 CL)9ZKcޖXi'M1‡&_?Zȸ7iQP]e:2JJs2k[d}4-T=4eU|va?vso*>)ͶVlM5 (۷Uuf^JjXGD'udڏ,zU-XpgSk o,EU E%y`ZduBpkAw |Xx4vw ^x340031QMNMIc8U!t>2, 1W/-3wF!U]Uj<8o!H-az|MnS=) W-J'x340031QMNMIcЮ3LG8K#EQUh3l;ts'kW~yc*K2 R RrzYX/3 ̿`O)*Kfxװlg}; RoLťPk_b%gl:يyĠK2SKfʔk8WEgtTU~t\eb&tF%i ^ x340031QMNMIcwm@_•T>6DSVglk|E75߳ T]Zx/aTejVbRRjQJ|qIi^jQCC6kږ3kVrb %\Ep4,jSr3:J/kjn,'޷=onkRGg]!*~Pnvs{_=$L~*Gf72S CAQZZTZֲ[eS&>xB_sow i)JM,.I-Nۅ9=Yt> 4 :>Hxrdl%]6TZpPfx[ıcb{E{4]8Soϗ+'ԭ !xIJ|(Y'폜xYx[ıc#۲Xy~w [0m]zYEyv x"‘1l/K˱8B58a-x[˴i,J5?תL5҉ x[ıcbg*gv+Q& xA4-F+'s hcx8"7hC=ar;̱gG&Y2xx[˴i, .~;ӶC"htquUx8"7hC=ar;̱gf k. ǖbB:/2o:x[epƕZ,Gx[˴i,v ٗc9>q]=  x9.-g?s"_cT'JKy*Fô :Jf R}x4H]w-FU+V֍gT tx\u㜦f[gb93+x[ıcHS)7˳)1J n x340031QK,L/JeZ&ýU٩i9 &ýU٩i9 JNX"%n5TIx EZ6^b7w o xΌ,_Lv?ibP4E S()c'C DqSMo 0h)\? ohg06ReԳ>IB%~e'OꁷPt8o?R`H[Ne*[ L~q[N+Y!=/YGP4{Fp/ll8g3Cww)sܟ^z WhJx E& uJZ7u]Oxo>L#LcJ-B BQ5*KU!~4mn+YS<YF Sg9$^+P4t_[e`\Y뷲籃ýKdJ=weƩ8M i/c+nյq$ G%4 _fX|=~$Ǖz:i|lYP% ߱i,5`'m$ 25nݵ=x7KMqsˆ%61}4W呉  UOASh{S-3D ((GtתR Ac8?KQ**ID>k&=-}afobA3ЋAwZ|A=u%u>AB~wqhiRzlkt+cAe:|x!6|a="+:sؾe)$7gFB(^v..Va=mtD͙$bp7qɩL=-MdO' ZH\b"Ie QcO*M85ܩ+>0x EfY< ' F5DēZIo_]D}x Emz8iJC24Ñ Zx340031QHN,(IH+HR zN{e5B1i9POF{yXփEPչ))y@=%E0?n2_ʹI}nB5&B]c/rg=#%s&Br~^IQfCᜫK5֞ng~"%?aN#GCm|gjo"Z[ZpZ}Ŏ}'1[LMU[ QR\p{׭'ÍncwlI~~N1Gu߿V4&\`^o95Y;x340031QK,L/Je8*4`V yzU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lb8`c(fyIY{`coDEJjRfbSg;>I/h"]TA~2Q5{-(~IDu,Pw+SL7uʻ%P܂bj+v;YϏbBmj]2Ir.i1GQ&<d\L:`d7&CdKs>%1zcΩ>xƎxu{8TyG-ZkRn i0 P\Cda13Vdg[.ZKF4Qlke%֨dJOad9~>}bh@I7'涤(bM~/h*TaN1I gLdNeEk}4-e EQx:ew0IG7LwHBNUwPL BL6D1<]$ցfFր 3Z;3_ B]8]VdQ eڹ"nG쇜A4. s wwt3Q&[LKm{^c8IʋU21PtF4KLQa[r;0EWޣdmuwZE9aխH&$)3%#ҽ?ve "V b3)2Dc2P2VՐshN,螲DoJ8,Hg0^Km hnFL<Ȧ[QhXrجE۳I!M'Br`N>|9ԓ.fx Rً˶ݛ{7>|[d$r4z+yU'J "D2FQx%A<9կKGLS fwi*r)ppϺյ̓,`q#9n0(_UT='D,CD~E&ɔ؂=f?yu/TWac/:-^2CF7f\G>k=n`労D§[qJ/NQ]!b#WOs}gX :JfQU&VR#& K4oF:1VQ\9"hm6PJN{edݑĿ12NVQoX>Zzds-x/{,VX/`;U`(ƿf^2\b+ERϑBȦ4 "0 nJf~޹(Pu>kf (?V2]r>i7 ]*j-dUyGWfJ"{o^xV< w`=ƆUumpO(na[.Nx31T-kxUy8yq$WM4dIjgmu%ScfsJiښ# #wiTR2(YĘ;X+dgr~35107xy} l~Ȉ~#SCOjL`VJUȃ[t#qf . ͧyOVΩ!W%~yxHo^jL`um ;5& ª/ ˡԅ~S ?ȯCu^+9´.? *Wha[IK%Ga 7)񄱗5G^WeÛ,ostR3$dcOJ[g*P'1c a҆ Rvqbw[9 M (KEH'/3':*JB[ffwX`rغ21i=sԉ0Viiphns,&G"@"+uaNT2uFxW܅edb2qg=JPpj&զ I@l7bhNv nE$wѳY}ň5O8!{WVSK [""@`!/3I;8Ukeo9S'DF}gD6qWK scA \À9h]Tm?8P:1rDRil~U 4#Uޡ\=Rv7_Pdt&WtAt &-Qy*^_v~X~_GHHE=DQu iP'!CK&]̘%t 0J~#Qi&Ŗ坳+fsKF/Y'V:6z.M$$WJ5nj[/3?1^0]1^T!=wFêu"@b*\T\}ka e[±` YU8Cٓ$DD)M)`6m#E vMҬ. S T~]{)՚5BF }yz@OьO/@czhq {i3@D*N|И|u]hlsA8֦uww5' HZbG Z|㶊H  x340031Q-..1200 Wsv^eBH~&CT`[34.q94z)/V}Zcj% yU&/YːIB?So^j?aEV,j+S*>d/+"1 'hoU5 z:@ ?'G7)3/R 8o{kEкX_ /7?E,9(E҂|+Khֱ2>˃+>1%73’"X8L6ƞOڊ:͇j(J/HO8"soMW練inU[ZZ fZZOp΂%w'>H,JM//.I-̃y56ޝW>J'wL$V]Eɩy%P]Zmu˷ƪY x31ԊҒ nrRǪ)=7+U1L ~Oӧ7t溷g'D(1 D79?/-3!u{%~%*|kwu!0Sx340075UHHMΎ/H,.++aR`yr_ȼ (Kx340031QMNMIcx*?iy 'šWMh3(}~Ig/駹gL+K-ap7g?D[rKі3皑%3 Ng?ư~Αً*O,JƸL}MRa>*@U9/5$3?C.Jq}!Q 5uTr` x340031QMNMIcp44ײѶ=xWC4eyF 扚u0u{-s!dԢ}. s}do}vGP䧃^xݶۏ P)EfzE9 ϕO4*V7kw/@,o\:ysWY|FSi|Nfd- rnegKܭq`2X,ʋS2SZ6ͳu8;3k+[ڊ imd}tᢂT&Bt|ܶN%UiU;,e4lSx340031QMNMIc[0)).gnگS)+36bh䴦Ź;]ՁLO͋/(M*.MOIK-aؠ0q2 žM^Qd]yIQ*Dˇɞrz~ALYTKn~ +5n٫ɕOo{*SM9]:TxO|eP`$2 = :ŋD(ڀ0>4%la9W34ܲ8$u'$¼£r3Zɛ̃!O-”t팙n,ƿ ܍zOvlFFĒ ?j{<,q$.}3ȊӀ+> BzÔe]'ݞ7^EWE/71zWYPYuF~n*4`Ml>ʑy/Hlx7 ]GYfQIibؗ+;y%rֲOS!yY/)6vf(My\cj(SnP:%Wˬg׳:3/%lνwνlݰ{HJj8q QGߝX'ed;7j zւ9'Vp)ckgxUy8wq45RG&i(ZGGyVKٲJUG="qD1qEuҒT5a%~glddj1R\ܮgUS >U+mwZZG% \hdl\&/s8a)<[ Qct $:d@(:D,FeιO@HLk-vfb!u󌇪Ru@H$(JhT9<;lvr*WDGҺ/]bw c 14Ax_`k=}/MwYmV b>Uƨ>kLg8qnqP_x!ف&GTf{EI:;90峧vN~ nL8 WֲWi6 ❭MԂb2ZѠ$Df#u&x_G0#@BEx9B+F (^c f7×,'j*jOtͲWUL{ /i@;8ɋR+Cu@-72|*/;aM2qVCHh ]Y,F 41u qʠդx340031QMNMIc*b{Jmj#mMYyfz[waCx='kzfɗ@Uf%&%$%0x4Y<-u{eO`æ8戛?ym\(jqS#= 2瞯cnC ls:n*i*[R?jrf=0@=!tOUNvv3vB_XZZ vb{ӻ]nx<W /2AMrZy>r"ƭx340031QMNMIc8U!t>2, 1W/E.2E7*Rr$E~* */*N+~QN);x340031QMNMIcpL(r:θ9 ִ̖7DSVglİRNAă-ʩD98#1>L/AZ󲰝L[T$%3D/1֕N6ՉvOwTSZ0g煾Ej2^?K$B .ywlb1i";V"x340031QMNMIc(jo[%+;g|4DSVgl(~+6qddVLJLJJ-J())K-aWe,a˩ǽo\ =XgwLRX[:}2V1۞cS6^ ]Ol? m;V99`ܷi ?,Jٷy ?DtI`"|1'K ?ץ6.Ĕ< i;n~ϛܿi:@~М-S[_Pm.Nzm>P B RSWujWΟeHhU qDLi#ӗ.oMk ]1(SRN_'}r6x340031QHN,(IH+HR zN{e5B1i9POF{yXփEPչ))y@=%E0㯜{Nĭe~ɾk2w 8P_5\s\W߾(~7TVԢbV]{(dztĢԔԢ̼T9YP߾WP>쎂3O혜JDrȚ2E ^u~"ޚ0 ]}>K%r= ƛ JnAt|DddtJ0ƅS3;*&LoH%QOKy1l_uE0!eWmGVkAH@(֏tx\|vb~@:3%k:+0A &8#w"Ry#Se$P4C8>e AO%p3rˉq1_^|HTyҿZáFCbij%)ٸi3<plS 3,mݰT (JXWŶ2zT?Μ 8j8&Jz+.rrd5`-bbc_^NBHXlQZ})Avf'b$>8-T qá=[ $`g<2a7!5,K`m΢ tH}iC NE=g9A+d{'oT}Z5M!$/.si3Gsn `@4߫2Ukl QP_oGoaZ槜/@'3_~ϚqŒE{tS+s rRn1D7K\\vTΓ().Jfȱst;\@dKs6i^0iPGNe ~Dtרx340031QrutueTqW WTLV"(1$H$d0vU&̉޿`eD'PBAQjAbQ. Ӊ“' +JfZ 7rx[ıCD5#gHso/9!TmbPE"Ta뢞^?;znYFiPlpx TajVbRRjQJrInFjNnJbqFj1T#3)6o?!QSatKuR r*u2+$?DOxGD^OOL̋O(){_Kq\AMDԢb#_'<Ug%50E)E%Ey9yPssN^/W=';4vumURSJpn$x340031Qqq c8ʄ~!E7JB%3aٗ-Eԝr|{U R`Wdw)&W7XO~ U 6t̓?JZt?ƒSP R4U٤,GNt*TAZ&H/7Λb=WΞcXXW)SPRСnlOFGk*kNXnPUR du!ܖbXD~f5k A >d:O+iU6u?[`!ӻCk\/&ګk6;W:9;\uB=Ko}g6,VExK?DϜ# Vw$'?*(.)8aɔJ 6B$c_Sy&ui300~brhTSy =fs͇*(z1+/.?:ϱM x340031QHJLJJ-JaP)镹,%R^5Y8CT5%9 6^MXm\)a٬x31ԊҒ @GK?< ?שlb&`%E #<ߓi / -)J+./*MKL/f},t_+]l9n-x340031QHHMΎ/H,.++aR`yr_ȼ H x340031QMNMIc. vnÓ<"G^C4eyF 5?RiݔvCUf%&%Wd&09Q٣mhq{ƿ}k/Ŧ8>L/n9=Y=76W|lwZ5Bax340031Qpqq (3K,cuW(xDZB&fee1\O *7kwÆӻz++36bhX}wH9Kj?@U$00m?Nߛ}u^U+S>8(?{?7릾gV!+:$lEʥv(W\*2:(j s*.~̨#9ϻ/,-)+e3DzT>~55ڸwx340031QMNMIcf+'3}H:i<3؈!}#?ޟg3)t0=Z563* O]]6;b8/A,اjޚcpp, qGg][ĻF}foAUآ烙+>֎kif?hS\\1Cb t? `dD*(^Ow|LqG[(B܅ȖZ[!&&Ͼ ,IyX@a~\o^b( Y@߁X>fkHԷOJcGOdݱE;[kmf3T7`l(x"l?Bcٚ9rg΄r]㦦j\f WeI81k`(hw[$3QaʖC≻E,.Dzy|5U k/k#$,Gwurhy} ZX8YV~c 3 'FYĘU)B) 2EV ly1 @DW!0we+K~~4nlPM8UTgk&K a|IeUx!?ș+8g%$hTi鳝VW֟:l%*/(tN{myX~FL 8U$9urgt˙ü3]X{YWڟ6ҫ, ֋J x340031QMNMIcwm@_•T>6DSVglk|E75߳ T]Zx/aTejVbRRjQJ|qIi^jQå5G$ d3*N&`bGnm~FRpl$5)`ޮ]@3goʪv:)T'= jZIN^jQìw!2 =oy"ħ%3pm`NRu[Hͤx340031QpHMJ-,d0mo9h̀G {L.wM!Xeَ 3(:sSjvr*=J.ڜ +DwIK!+ N-*LNa6iwsYmhqjXqеZۊjNPtRtK.Ҋ3`k4뿘6-t$TejVbRRjQ^rZ:ÂG/l\m7ϜOl2u.8‡eV%#51衤>?'wGYLЕgUWob~ӽ*~>BUg楖%3xn)QO$uøx340075UHN,(IH+`bʘ$hOU'>T-1JJLJJ-JI.ahQ_}MҊ˫.pn UTZ\Wsʼ T.wj]X.Tx340031QK,L/Je8*4`V yzU~ F"'e8߶}SasGTI+M2 =/[؛~($e&11{^=Ͽ7"%5)31auR{LB$2-Z5C'3d׮rϽ~WX!9 "M\rO%uu.;*IC%3̘Rc;ku!%9 4/4(t#sx340031QHJLJJ-Jaϳey[rsjKr>jzݧ_'!Ox340031QMNMIcp44ײѶ=xWC4eyF 扚u0u{-s!dԢBK6Z}ekusJ?[2o 5MR-_)-Y58\0=v >dPrZt򤽉Qex340031QK,L/Je8*4`V yzU~ F"'e8߶}SasGTI+pQںu*?Fء⪉($e&11{^=Ͽ7"%5)31AdKsLz5-ǜd }"!WOs MH-I-fҟ7KK) =/@%3D5;'{\W޵=YْbnL}hSق_bRzxuy T'*DZ(B!SIk23f35GT<-$!K$[*D,)JB!;4w||9--ݝ;w֥~믥Ŝ^}!hz_~2?/Gl6'vPd8@!Iپm_9v\ϥճAdwa2?FV*zIppNσ~LhT8Ph"*րි'G'X~B3qQ8"wMlI$bn4B^5QѠ!Ěr lPbjة'>M_Rdo2(]!m42K[^6;whl* b@p [-Q6brY\*tAY lwS#Bfp =) +L}Et.>d @`a] [҃5/>C"OQXV7J8>y}UZ沽[SsxP7BejS9vpnb$! O)FoV |D x3g+nxo3bH^( HF fN7ȀYoTu 吮npp ,$ҏM*=7uMyc@ǍyLUJ">(҇ .䧆kL#uo*cVyR>+vr s/\v@ha)=@8d8 PA#~YMG-zy6*@suz*:`r>Db~*(o+5 ,WҨh5|ypF38H ̓Jrݯ KX/fzSA2QaoO>t贘pep:E0.X&Iэ/U¡(.U'=lt6ҢD TӌPJG>I+]7_TYK);l}фȇ9ī';xйsѯͶywц,2N1#%"V;vcOS'H4r'SF@ķC4όᜣI| "Yqڕ@䍪xVnmXS`C]F\#;jv-{)*C5_a/0\}(Z2‡Ӡ=&b[Kϕ, c|Oq|#<~P_7{jY&ڰΪW'!(l3ViITQ\xy ֬Xm&C 5?H\ޯ`㓟/8 lBHXDlaZ$8q-M*~h#>.IP6ED懇^-g?t'|[S{ 쎕el&ǀ#VOl5,Z8`&TD>-i`=qߎ-1*s<`HZ۞x;6QpSR5~VF??zE(ҏ>S MNt-Qhi|0((#Cx՝qz:`@* ̘%I-X-߶_yBp4\Aȳu ),JB#wZ>k|$ia?8b?7cm<,fw?]p~J57t(T;HׄtI^__P$4+j*l4܇ 'pH]aӳmZ&`_L[7?ͱFͅ$jlu5)R?3oTa ,:pVL>̢p( IdGu=ZdkMB{r  quqU~xmu{M0$ @3 KojM *-G$tFͷAYό+ {pB/ ϕ%14*FD OvwKl7rjC,5  f 4LiHءS?Ld꼰}q%0(䝷qn2KuՃ%GJŮO$.!@CJxpGq(x뿼\92@(vK8~ 9>KFA,.*,MeT4^Al?mZUP'n(1)[2vg&`n.[=l-n_UMTnxciu&joa] >`b+ǚRU#@Y\ͅLps})ܷUs&n̹ =7R.]8;uᓎbdQq.7K'T8K545{7WUYs^H:?Ɍn~2~\HD+;w3Q{w933f?(ɲ!iʵlA[>tTh fqLB$ $+yCbKࡣb"d4Li9C`;L%엇;C9Mg~ ;~!:&!l+>e}ѕ~D/vZi9WӡnZ,){m@sڹ۶YV9G]s6\Eift*m\!#@짌_g&D^"׎x340031QK,L/Je8*4`V yzU~ F"'e8߶}SasGTI+pQںu*?Fء⪉($e&11{^=Ͽ7"%5)31Jӌ$MSj{{{N*Ofv|j+l_=yy/D6"1 'aBOJ,/+ۧ6\lQR\$pes_5nz;fAdKs6i^0iPGNe ~y.x340031QHJLJJ-JafS$SSW3WT!)Ϸ^mttsĄx340031QK,L/Je8*4`V yzU~ F"'e8߶}SasGTI+M2 =/[؛~($e&11{^=Ͽ7"%5)31f~έ1pd,"7_vw+D6"1 'CġK|cɿĵeGzzkDJ:&7'e3?s)Y;LQ;ngnx340031QHJLJJ-JaP)镹,%R^5Y8CT5%9 SBo5ӿ/pv x340031QH6*-0M++H,I`/x>#gHso/9!TmbPE"Ta뢞^?;znYFiPlpx TajVbRRjQJrInFjNnJbqFj1T#3)6o?!QSsSSr3S+J`69{yI7+I4PZZ9jJKms;_4/LEFbQjJ|Q~qIjQ|~^Nf^*!9J+ދT:*SV]Eɩy%P]m8$zSK*] 93Ԧx340031Qpsg68)r ? !J\]|]\oRiyIL @!9?(3ဍ-'eq}9) ;p4 ȩl/Zͭx340031QK,L/Je8*4`V yzU~ F"'e8߶}SasGTI+C0 oGѵ%?YLoB($e&1t% >2Ukl QVB̴gNq/:VӮWP Gꗆ߳hu\id_f^']Ԋ܂b[ &.'׺:!JropeꜪ=]`o(W5ْbnL}hSق_b@vx340031Qpsg68)r ? J2S}*)S?fz.?tA:28<|C1sIo>xŘBr~^IQfsO}!}bA)Iy _)qlo}!sTA~2k"T,|fV-3D6"1 'CġK|cɿĵeG8n@x340031QrutusIMLcP48BfwHܭ2(LHKOOgu3xR5lwLQ~nAb CݵMhU؟eZ[aL@()apRu=}z͎bݏD/3a=dPNF庹pUE% BsMy/^6mMUAPE)i9% 5dX^1 ?(LIfQ1 O}5:`ɺIũ &V:۾/A,iRBM1Î/w)N_&CSRR,ٟ~К['rpYJNKg_=י yYF<-yM]rII~ߎ0j|d+|d{}09 |][em%15̼ԒdW_Ǽ myfn~&\Ef^ *_yĕӲ+;U$0ro;*yn)0e$2luKԷᴨ"|ڠPEy@%믺ΧE@L @3*Ml>7ke5CU3hxl㛿 o¸ \طS Nm֕yi$5E fx*ׂɲ1(J*u;b>;m贵T%oڼޏUB ,N.,()fx'wB؂}‰"_+.~ԎT`qN}WT繆5e= JYl ̝"1|+֫x340031QHJLJJ-Ja|ݳN9sW׶ϸUMrIC-.`WCD~%L?x340031QMNMIeq|fJk=7<*0B䗥e륦'3t60%l_&WI9{3TaAQ~rjqn~^^rq1Cma")bʪ1 ,xuy TZڬT YM![&!KFc ufɾlK%"ѥH%ZDhR*~c`}}]hPv7A B2?~u7e7kV McbmQ`mjQa} xXp|V׌#ӳ!T~k>^\{у9 @R]%TWN ӿa@2K0h쀌ո riYŃ946Bls<_oO3lVԪh*$ٸq,Gp qjP yT)S0mb#C^kB> J<݈{n&٤߼~;oBUنI]Ou u3֋ ~GU=zb)q$ΨƏh u<9/hRNaJKʛ$ɴ32l|){0GH޲XoUTe|bgL?45HƥsM\7}0_4 C0DuRP stӎS"&cהj2]J5"@@}ý*&JWܑzĒgVLK`tˢT=-nsGuXX͙M.v'ոC)gA;D/oR2h*r@_'f벖OsMeR(&X7Q şL;^1߾?`YA\2+aֵ[^db槦G tdbwIel(5kobv65_&Ɏ~Sl>ok=` k)q !ǁaw#jv/$ y<)o1WAw{::$_D#[MC߲q[m7lX~D{ 5d|`}:n9G 9l"Ąu^ TRGx3%"ij|}C*-o s'!Zg<L ɷLGUWi )פ? G= u EL( :ڽL{(T$=.i2u6L9:a"?d/b1s=1F+l5n8ACɒև>~HYbf jC6,ax!xdK2YjlIܜK(&]-h1;OdNKo_`1}s a,@6,y`]$W"'|9U/Vyb;ʍg+$lիSESu.aQ3m5rٓ+ Ƃ()!uܽf*'˅n7Z d ٚbFʛ98~࡟`wOłp?KcZ+DR:41jE#s7qX 5M}t!m ]smS4,9a /Y8kbgj[2Э-ē%_ C8r9N޳ۧ_6tGVD3&Esv0,+FQY.MD+#dڀ$ =1ג/ע&[¢K%1@ikgHEO`yeElu$W:T^x66'_)SmC_ 'Tljl}Tw[. >NI%}V%sQSrt8EWlL5?]M)d|D5{ lsT'wyT楍qc}t!5#@%ך|ewj,T S||e{<ҠNK1i w`C%_FMY:E a?AK؊:9q:NzJ㶔ycr!pW"JKqrRt|VTMMzfɅAk/CZ4~(돏✋yy/7 f6x qsOqPp-9ݎsZrY{ Ib-7)bxrA:L*8^Q"-zU r }NˢVwUy><4v _{'MK$$(˞hUΨvU[. u)D.I͹3!F#P璇m?fOgoQEWfܨ,48kUߴ"bvL!m 9ps.kB+UϽͨ;P"TvU)5Kfق"!0dYvU$5 >>[7Ge+at]$af(5TgV41ӛ(|g>p^OR,l?.ZH3>' pkŰImSw7}JpP9y9ɶ˿: +xw?0sbBA}JzZtщ4`6?>%Ԥ~} !:4:)վ:MҰb'~hBeSbuQ>{aqVp}~~w^[s~?@j,`<Zźs` vUJZˌƚT਎n#o='.UO~%4yam4VղNlil8u"c x340031QMNMIc Ѥ.jƗZ3 xMYyfA_͏gqTZ7岝:PYIIE)U9IzE9 ootK)O)*KfdWe\^k:|BD4x340031QMNMIcvqIu}w[#8S# єg1Qb/0ό_^?OsNUWZs+{fGxȊ⁊Nks^}ެOOs~~TYn~J|fQ2ش/;f]YR)ĭ"~Y(*\~Z}SQv/:Ne1x340031QHN-Ngp{gڰG*~mmBUU0t{j~9س[(ofBUU\m_Q^OP`to>p"AT@li;oRYLaqTUVVwjʥs<س]5TEzXڋJX_/ͱw7MXv" O9N=8rBZ$Yئ&>nxZo<-+m>f_PW))j[^Lķb݋_2z߇yP3Uηuq>(0%"LEnfc(J<13|Nku\\X* I/*5t袪vʝ>Fxiom +7TEq6Xũ???8)]k|LEXCWik_07[P%`<+miUs3T@6+]BcU7- UQ qv+*Slg[@UeU,ºhgU% UQ<_NZVpѴߟzKCUTA\zh0gu˱e.8AV>;x340031QMNMIc-8{ޑf*qJ͚fbQZ`roF'/oZYEjQCjG\f7b9{X6m*[x340075UHJLJJ-JI.a8C(ni߮oR x340031Qpsg68)r ? J2S}4W}cV 0k}TQ+ y+=[@J2˾l~q'UZb*HIMLcU5SuEl8e{ ?*u~/?iOԊ܂b[ &.'׺:!Js'omni8gS >jJF1 l?fjIAx׫-w%p|tXd䒜ԊDjw鳊*cUnA &Gq {(gG(Lfް/9hUҤҤ҂ĔĤTg]Mxϙ!Bٲֿu~XY טie3h-+0ani浺=`*2RSKRr2`ߘrnYq3PŪ(5955?zȧ1Y j0]9PEAS 9-ݛK UTZXsB=y7]?lZ/Zf4${vT0Uk%+x340031QMNMIeH<34@w݊89E3T'4B䗥e륦'3~EC= NC'%3TV-Zpm-.xuy T[,OYKP~YR隹WYE /,%i#d-QI^³>Zw>s={ܫ#oA8<,dTy*٧.l*Y7\@1z= ~% &9" &߷91M"z4숶ImN4/ ;& <'P4}2Tm^Z?#= 7{Eچl\1 bP!2 "y"<#uv|-UǨ+F`с*}oi ǂ TՄq+?c=e^QAz!\CF^I=FL0\$ 8#R{G愁ܣR<0dzS["C]H8羂E#{;w,AxlvJ)t_Rٌ]Gcۚg<$GRx հK$˙ [|1ګ>jcéZ}5Yǽم+مvލ^xa!b@>^mDf*X4rJU2?$Z8_"'c7Ƭ@JS"pS(N 2+a*:'Xd%ʩfʓ^: }S6*Ω!?I" wn֪I&:&'bBz?F1v\#<2z wLBh2FB{֠m⣜F4eE߆vhsǐ^D;ラr^q-͢#_'x4ptS?̹Y\!T<D́o*C7: ?qS{>`2ywSz+X4.6k h&ȝ\=39 977"~ȠD߭Jx8 rJ[m}z%gQ#aSnWV]T#Kډ.gZiwZo{pRώ̞mappkN d0M 8*a9M#eZ“s- 3èR7'>/t5Kˍs{ RwF=GCqp̛i m:߲㼀j>~#Lf㺑*a8xfJa7gEvEݕgةQڎB<0%*r(d:/KpԒj/mo9~%r?wgYJ-`U8Xdv==wa@* j1Kwb">u+(۩ *Jhs-UTxP1G%6`4 X<{i(>TBY޼g0k\ǣf-`LSh")ti ]ASCd \\2폼ϑ%N|~\aND5g ?оC$"` -ahHZhotjΌ{kв":)w|ZC;-|M1CJ`SS@B®4ydVJuB˄CA ^X~NqT[@񦖍B{S*ܿx340031Qpqq (3K,cuW(xDZB&fee1[1cʽ#o*7nJDWVglİu~O{ bɫP9)zE9 O'mP\[{^ïKC.?܁(_U߂\/;x%E`'JU1_4ak:>](j s*?7`o#ϓX||%9`n7/_?K.ӷ+e0x340031QMNMIcvqIu}w[#8S# єg1h}yzXb)U.1BUf&0 xHW`ֵ ]{&@VT`C7unG\z[$n"UY 6[گyfڶ#Te@CRK2:ѤÓ |I/x\a x340031QMNMIc6wJ{Krn<3؈Xce̟<]O-MK-aܻ[Ny}Os]UY|N~:X韗LM^z[xer2ũEeɩ`-]:pdAMOml-fcӒ V)_79GI:MuIQj"DǙ Q_WR}ae9W}u0+x340031QMNMIcx/  h~C4eyF ߚK\nuzoϼ.-[%U{AU&&姤0I^Bvte)+ `W^R rE눅a:GlVmJ:ՒVt`ϖy gx>T%%9% \onYp֡G3'TOOJ+.XlcUQ V!-ѣSdw"%bw[+s2VI֮UVU`9f]bs0[xmџkK/UVV(z\{!O{NtH5Q{0kE̜ˠ_.!P%`,^ ?er_V_A,Hx vľfꭩuE"bKm >Y[Љȃо%-d,rTEČ F9S6(2g?| D7 af؎uv_1mpE`84&ܫנyuR ]M+ܟ_סzl곮t./LEX -7]{"~P%`<+miUs3T@rqCU Gݚs.YUQ qS oY.}K9 UQ V 뚣 ~-VPw.TE9$V2h4]x}yNTXσ?~$~Ek8x340031QMNMIcX`gE+REz^x߽MYyfVMV~RP6ڡ*SRRSRrV<>gzGY3`){)/.-k0~_ֲvp}Ր[\\ GDZlLs1{`ҔM>0E0Eg]U+:ȵ|Ig?lcaijQfj1}?kgui-6A`TmA:شBm|ֈ뽅ldlx340031QMNMIc-8{ޑf*qJ͚fbQZp{O;*5:f@VZp_3{^]gw.) x340031QMNMIcb!Ѯ}\sU,r K єg1' =b >z9!de嬂P%9zE9 wxRw"?Ϙv]0: ̼Oh=[mns}}2Nƪ ?'CV~5oƵ. Wo<5 UoI6}[W?Ĕ<Ws,?Qou\c~U+ZcyԆG6Ĉy_4}SũEeE`-~?8P4a4_[X:CDx340075UHJLJJ-JI.ak_}u}Cw{_Ym4 ǡ#x340031QH6*-0M++H,I`>+s_9jUXP U%[UZW[p@*?,[Bs {ޫ#!ݠ S*s3s 2sRssRRs:5_. &UtjMUP9)Nh~Yۭ'z'X.U\ZQRUܺ[ŕ~[V_ꂢJ2/}oTL.\sWTYf&^oߵnn'`R2S4M9}d("0E)E%Ey9yPsu⮽6X4{KW*UWQjrj,_gy[(Dsg?t´棃}Y>^d uPE)%0'ܓgzӥQsΦ5eoMb@x340031Qpsg68)r ? !J\]|]\x;=-1=b҅M @!9?(3+Qѕ:X8]|eed#KYs:X/c.T6"1 'CġK|cɿĵeG8n)+36b8h,ΗJ\<_25+1))(%*'3I/(le+Mu Y&6)Eez ?rn8E/!KJZEx340031Qpqq (3K,cuW(xDZB&fee1w0v}q=_ޘ{x5o@?Wyl<3؈z\\}*sS +*LRrf߻b\COՏzYOXfVk|}g}-7|vvQT6Y%]SVLӎZ'Ͱ(/N-*LNkV-@MfA啥cӒ V=iՔ Lkms꒢D{sIR9|b#:Fx340031QMNMIcA{Sʘ _zqB$%38͑=}*-Ve~[45U06qtoev#雳?po>U( x340031QMNMIc(h75\u_׊,=Mъ- K2 єg1W{*y/ètD  PBqIJf^^b+[['m5$X/(zaʵȗyby}2B2dF;9XD͡,x340031QHN,(IH+HR zN{e5B1YIIE)I)yP=3uOh>p*DzP=%%99@MP=3DRg%^fyzUd=%9ź9P/pavyo,>B&&$%C5K%\yU?GjJYq|jEI|q /ȯ.ݸ?0 9%99%%0Msn|9Bj5/_gs j0E)E@dSa.o _r/Xu&$䶐]WwGĢ]uʁgHj0 95wʋQ WSxuy 'wE!T)4gV("dv|fwʈ\U3WJHRI9ӓԞo>kA>X<! vYɕ55vIv K42=@Rh=QT% $5M"(D_:n@ ą2Z;DPDnLpr(_2m= A@%CŽÁ_R8KkD(4DUz Aݯg ^K$?i/xi~q@ƎT@n; $`}4Bf-Y>z}r2$snfb_}KL yG @2?ʹ0I5w-HIuQńDne^ųgR7v$_(R*dgEl5QZ\i2\d%-j7_Fb( S7y2+_*r+5@_18FagZe!kDll%wX_Bee_d% (GbvĜwڦ(@, ;arvZ־ 5Yvu.f,  $VͲ"T68Y˝ҷNsq@"2 nXzTMm [$ȡ||?@1*+}̸uI Ɋy}͈*K}_qAUvGI38샄*{;}tJT(`GPkheڸ D 8MভxSX-t`K> $;gPZr:zi3"Ҩ6,x8ߺH&4k` l9sdBGQ?w"xT|A1 .ge3;4wcHP# Ja|R$WCFE^/L}DZP Fp2b c믆 J:/(X&Ռ*e(I:#9v({j/eFOv-F53j !bߏzQCMQSD,)=j*7b= q"B"A18fR/YU4P~l nxLJʱtpAADs"(ZՈ.ӄ|_%z aWF& }P%r|N{n" ک*e%T찴˽ J'⳾65n-+ʩ9J2nЧ,W"<:sq!7s6|ľJc?5PY41wW+zW=CX,89[r`!R&peqT+l}UKqA9 qR_utIil[C:i<4nY7{(ז+3p" K!eQ|_lG7}}230(7h<覽>ԫBp/pl?z|U9rQ!HlrLDp_2H#qW.X{Eg}⁰ʸeHX~D`0m닱}<$phÉ *bǷ]!D(KPcYWi~w 4bEvb(oXN8&r.A o)+ X8wV„nv U>S5 ە'sQwF"d:ٷ%)~|8$fkʄx,_s0}to6yh=!O_jx~2_jpBq&oX}#G~'}Y/25O@V9ywX-gmP11AՂbT NQ|u;=KcDb 4ٹ|eu(8Xf3g{̦,, {-w E1qd5d]~> W'k"[s_4p550ϣ Zg}Պcu q]f-KHۇ`:\/+6bO? A3GQª;Vim;-﬽NP!W{fC]Qt6_c풬z<@%rֿG@4[&5\Җu]\ &rk3/@sj7;%P( 11 idn "7Q0ȚjсAVySKІQͥ(3\dWl::ǣߟS+ŗnotͣgֶIӉqL\K 1*uӭe3O".r@&+y:  m`rSun*n'[ͧNXк'Je3DmZ(ºDU䇳ZGj:z^lȦ6D0Gr6h,K{_6Ztb >@a8`t}u|RX՗C\8, #P~-֛vIv%RO:. 6*+]Xf9y52X!Sהiysx>xWrteƪ[;T;28|Nn)wTXf 4dpDz o}cVs!Y\#Gm]yI|Y.y]]5ԉVHXqb_)dplYk[͐iBXIadeսˢ:7ޠ`R>~l"O/z2bcպd>YTy bDID@d5i`d`ch?3ۼ%o OEP9竛"wW=nM4c>H85 u ŭk6x5ި(vϲM.#Ÿ"?{tָZ eEB5=&ꪴ۵UнYD|w@n? )Xv#Q@؋ f6_4=$^z[4_ $ о4lVU6247s%IP'lM'p >Ωw :M4Zr_IެcR"@rv3J+EOؕ^B%3g zDk=BYin9 ҡA[A4ϛMS 7EoZg{kԼB̈́q2CUE,3 1.SNls.E%g4#m`p;ъ%[$g NUR6]s6Yޠ/46EcI3ݜ_V" *MtaeuqǜMKuMFxWsgqvQ 3ptOzSw#[Lx340031QMNMIckYv5v979?ǐMYyfC FyfLݞAw=s27?%>4Y/(#q-/Wޚ7U\UY|N~:X) :%}??C4E`[sھ?uѝfV^¦6r5XP|Wլ;_dSx340031QMNMIcz%YU,kGDcF2h39>9fsyq@bEu*S JKSRRrRܼOQV]vêf+/)Jhi9ߟ:骷焕2%oGA@m'-s=\31T$%OynOݪ:jX-I-I,Iexprܟ3-f}q)ҔJ'T林=)[4Qgi|g*sJ +,'oMDpܦf S3f.p7=?}۱A(2 K3oHx3˷|)%4'#+N/H'"svEW'U \=vܻp{_#MVEnm'zzM1xYc_\pJm7:r!!d[텃Dde`Ez^H1&S!~cÂxi /1\v!EqQf0  iMIB{G',CQ[ IYqj7gn56[̖WCR xX %9qYhZRFVva8Zxʩ~JŁy9VoĦ\,J˕WteE%9`_v<~b|oη?=2๙[FWv+=ee%e>] EU|J rE}- m|KIۯ&_cIh˿U-8=ky*6zvqZQ ̂)ctREm|bJnfXGɋzZ&V j[SҮ]Z09qVf@uC0sp6Kz]1(BSR.2K}[ϼ/l w> f;x340075UHN,(IH+`u+^y\'zq*5+1))(%$F~5J+N,7Xùi3TYVFRIjq^AC)&v_(PܩuC6/x31Ԋx WXW\T9«爞VUh]3x340031QHJLJJ-Jahr9FXq9V*k&$!`ySٟgei94"lx31ԊҒ u"b̩&YSo˫4yܒ"}\Ȗ%&e3dNqPzoįDŕoN6,rx340031QHHMΎ/H,.++a(E_+`(+_yp x340031QMNMIcK|O o~'8NMYyfã ܻt U ïn- 25+1))(%*'3I/(ץOYWZ-< bSRT̰+x]R-V&|vݼBOx340031QMNMIc?Wv=raI+ jo)+36b8/k-O:UWZm lLi֎y9Ȋ⁊vE)uΣ2Pe)E`nrYZ߳-s#7 *\ֱfŞ=͇ӳ3ZV`x340031QH.-NgxyelsܾeM !*RR*^sW13TE*Č#w[MX[G>O UVV`Au|:o8|P?TE^X1G+E)Ė,iW_UQQQ/jp$%Oʎ(MX4z"{›SlΔ(+p~L.߆|dF>ԇ(*P`>9}0Q.ڟZCUgU?|t=oU[]}+_LEXk%%{>N +0f"TE)Č'[Wy:#de x340031QMNMIcЛ%)Eez %o>+f20:kx=Zx340075UHJLJJ-JI.aY7!jNh=̽Wx340031Qpsg68)r ? J2S}L>~!ѝ, 1(şaeoUd`3A'3zWݼq^5ZwBljEbnANj1>i>_DIAbIrPś斫NnmEcDEqQ2Cea볦D){!lI~~N1˫8X]hYbK)x340031QHJLJJ-JO)I-+J-gbr'_R+JKd^qNbIf~^1CҌ/G/1( x340031QH+K-*+H,I`p6Oo&b]aTCd*OI>Q["wF_n.J^RHz9!de嬂P%9zE9 Zs$_?9V_}$>L/ˢ#{4]htc{ :Vx340075UHJLJJ-JI.amiltoWfx340031QHN,(+H,I`u>%sEWW1}4+K-**t6Oo&b]aT䒜ԊD{ʼnnYCh3SοN!b{|]{ᅲ>o? UUP_Q U;ޜ%Q["wF_n.ԢbO6z[B+s/~x340031QHJLJJ-Jart?eӛ+j?vlڷUMrIÂPqSh&<_/Xx340031Qpsg68)r ? J2S}\ͧ)̪߬oPEA. O0}uz,nlZ?J2n.d[mlSKݗCT&e&1MJ?γr7̈́*Ofh %|hK,bԊ܂b[ &.'׺:!Je<>O)5}٦-)f߿(ȼ_7ɸ?^s+wx340031QHN-*MHKLKcP%5).x\4? iZt&l&T]JR|qI~Qbz*D2FEﳬt\x45+1))(%>$X {+o1~:۷P%%Iy)' <%s[dV/UZQg[){0/SBg%CUtt㊺ƊSfuC$A=:ާ{׾ia۲Mzd**H-9rpRwT rTMqjQfj1CP/YE.Ua˃(ö9x1_i<3؈a{闤n~f~{v 2Ԣ3^67s?+9fsyq@bEu*S JKSRRr̓,q ^7w i+w0aW^R 5lJc-7Wu?ՒVy=d=KNZjREhdmB>[Ǥotݴ'C[[XyOQ[S_=n0>4%ldPxN宾Ub_uH.29E2p/=,YaJb:XݧގEJnjnZ 0BQY\XVnCwLtfO.4o Y<'q[&_~6BD8L0g֪siڑbU7 EĖƜ"b6ydlƟk%Z}CT,MƷבuBBl{9W??y[ R ]XȲLes :Am_~o9v'(2ˀ)vɞM~;y,ݭ/PԖ&dB=9_ʦ_&ƋX Y/ࡖwb6MT39q59 bSRcFgE5P{!̢zc3D{.tg T=4eUTm5p2<݂NDQl?刋ji{[ڙ*_55GUZV&_cIh˿U-Xpg0[qי~/{Y\EFU E%y`E%߿B1|:,]­r2bi~Gxz  cxUy8w4b!B>NIԱ=Vs3#UB5qmF)1UGyd-1kf&bb/RI )GZT}TQ;AN{7يtfD 4fWP4[h)oɻEg; !$c驹niYZwb~ͮ 8/O󱪚2F; ^*zS7 ހB>/4%q&Y^ O%,&k ^Ŝ{:HKU6<#ީuK;L`q3?A8*N/:0:G .`Ȝp0dȐ7qۤZA I.r iVߋ wۢ!qHNr?}xm9[oaRbRpwJ_v}Ue;ܰI ʰ KOG_A%F3ds4iC ""Ҡ&'*^Z3B#]! p 9)b{|gNrzHo߫^[9%H kn#?yS0q;%4<1oEu-t \s  $S νLvsok eYȃn8ǔHL$8`w _]Zn3XD Q..OGI~n &t:3[Y*;!Az<񪴝?h5Tϝ0JnsEZʋ6?i+b(Fh% K)$o2L RjVMK%Hj,w i: s`wF3(1˘v  'h'.~j#QNRZ; vSl.닯Q&_bWUH_X6 znHmz BHeJC0[qc98 s3Gnb#4!$0G56ť` m6.ӎ/ {ًGAr s 4C,EΛ<Ĕ_rqŵcfVio |eVHrNt׶%WakOH SJs^g/)W~NGi;̫=sU_xIE}թi(ʒ1 x340031QMNMIcx^U˚>o@?Wyl<3؈9׮njgz6^ԬĤԢ<Ԣϊ?>*5+1))(%$F~5J+N,7Xùi3TYVFRIjq^AC)&v_(PܩuC9(0b>~GsM @!9?(3+Qѕ:X8]|eeԤӻxct񕭗!*RR2gX 4yMbOug*OfPiM`ZUn["Ԋ܂b[ &.'׺:!J.UU׍Ԕg,[!%9 o#J ٣dy0s'g} Bx340031QrutusIMLcP48BfwHܭ2DQX_Z`o|w9A&g$楧3Elݵ;ַc? <)-H,a^ G} WΰTbZ3§L{x+L%E9 3?}Zysgd*cGo&OnpXUTeg09k7zط?7UB%0t8xIbyl/0%E +3??%.ES'&%2DXlr4GeI!5 ;r8ZgWo OJLJJ-Jѳ`xfAko=d~<_*9-A|^g2&Le,Qf4u%9@&~;¨H V$3w%oԠL?j2RK^~6 噝2Ukl Q̠Қ>fE2!9 "M\rO%uu.;*IC%3\tPK﫮)zYTBdKsF,>GWaJ=wgOc.x340031Qpsg68)r ? J2S}峈]ꗰYS͜\]|]ݹ$EzbL @!9?(3,YhñwoH\qDEJjRfbîcy lkՆ[+ 3_[%Uʭ "Z[Zp!%w_ZW粣r4DIqQ2>z߻X:"[S̰fn%ٍʲ.}-\tx340031QHJLJJ-JO)I-+J-gxu讕/5q9ĸR+JKd^qNbIf~^1CҌ/G/1J(۫x340031QHN,(+H,I`` %ߞܙ'7+K-**<;ftYc{)P9)~KnēEe,π*OO.I()J^;?M6㬳 _U]P_Q Uvau<՜nɞ֭/fx^r4Q ((3~~ǒ[ *Zwp2~"#(5%($(>?/'3/j֟3kIRXu&?-:׉x?oߕv}LWqT֗k\uL1Hc?f҂Z3ҨUgӚ}2ӷ[x340031Qpqq (3K,cuW(xDZB&fee1O:E3R"jȡ++36bn?KnjŒX@U$0/:+%WepQMx%E`xSf,jv&הe(j s*s^>=tuAPTd>:h/xs?sT܌e |5 x340031QMNMIc6wJ{Krn<3؈!}#3Ip;ڜ"+'ɒI)(PC)w>빿t#teE%98_\cyAkr|lHw6xcIeńex340031QMNMIcX`gE+REz^x߽MYyfz[waCx='kzfɗ@Uf%&%$%0t:ԽqR{ؓQB>8bS_\ZT6w?7?<r s2k/ߜZ=0E0Eg1$_4ſV\*XXZZ U*qbuF~qkX_Ps_4 lw[%ʲL/fŮ 7JIt< ,Dx340031QMNMIcx{O"*%3c_1DSVgl(~+6qddVLJLJJ-J())K-apʙZ_e/mђĪ88!_SOymzVr%̼^" Z4V99`ۛfz ;KG7V}GQV(;_ܙOcQ1aK,V.1\8Y♹}nBwnF=:rѽ+ _@%p_Ŧ o+TqjQYjX O+^`pOO3Mx340031QHN,(+H,I`6g*ۛuR*^;*tIaUWZTU_Kإ):3 R=U0Pߕ\*ߏ{2^3ËӠrSKrR+J'=^B/{W|}紦e"TuAQ~E%TQ+"?*~ ;_5w2b#vK?Uz m<`R2S{,ٽ5@E'a*2RSKRr2Rv?rEKYm|l V]EɩyL߼pN/>i{f>UUdI\mEb=5q҂Z3ҨUgӚ}2ӷE߬x340031Qpsg68)r ? J2S}SІY7loσ* rutue!b9ox{g:Br~^IQf`ٗM/ĸJKsݾС_)Iy &d n=JAܽ*'TA~2|n멽b~|͕(ljEbnANj1-Ck]ˎy%E kXߗYۻ.z/fBdKsV̭d^"]Y֥=]jxxuy q'B*&Eȵ㝙sc 2js )9a9ʑ+GVr\`vϿ>񎡁#}x%B.םu`S4YC>%lIJc]}s5C LB)PJ4py%X7p;~ -\PX{r}hG +P1$ w Wkzx BxSI!yj}߿pka:0,$)+}ɿnLE"`}w|Bcۀ nePU],~5M!&BZ= Hv (pq 0rI C}SOKATά^?gu vL2@$i(4E2(p--T[^π(VĩhoEi2AhOI?w%s1  ducݺZ2ň:~A!/ {09z۷xQ?`Xjt={W[ŕva/;G8Xu:B/Bd o#EŃ򀸼E@l>Qeix9Fq0l\~]Eo&3V ^?d[ 1k^޲)KN瞤{@ o[^נem%FaJf_3{ԆDVF?^5 83pS |TUc٬eU\վ6iPt: BF;`Bќ_2L .жs쐛\ h19oVc8ls@ZOF]!c߽߅Hj$5z2_JgQJL&k HOZb&,לnyjuNKHoMUo=$ڶ]̛UYE6k' w[ U D4JB@q`$˩= K~pϦaH$g%{d6*-JYcF@ ;Cz91HǮ}c~C `Q43U#j2 8JXssQ=B`CcsV  'J48bu [?IhK!ɜA~$nF{^\SᏡ7;u1TQ 6;E׬TϸfeHt-Sn~\I@䎧+W5'NWޔi:m >wnԷ[h).X:/IǝF #jH)XF4Os,+)S"9'BwvtJnocT\DTb.yaI=;a}NgBcmE6] ,UDHy)5C:;*f5 bhr34ӯȳ>-Ak:p:Wx37A!⇄`moD X+:EBa'BO~ 2&87 /{FOؼ HwOx?o١-y,8*I-(Ky JEAu(m(fe^Ǣt2-߭ډ]^V;䢚 X ]"\}C#N˝JMK}f fXg#;+ŬD"NnMфR OF;a?9mO({.:rf˩LuRvʡ^oGp\Zߘ֦'l~a6bGf[2 nq^3zPjFc(~=Veb/m|AЩonw衝q0ÒH<-WlЇ<ϖl5Yh_/hqY ݫpȼakOF<͔)ս]j*8pSs+#i**vaRd+(~+_%HJ)ڝH3,O:UdK_d5yu.:{{B4vP9fxP6Bd)Ǔ)`S~55()E0U+!wLDW%\4NPOY ]Bo<~9÷iN/sr7g+hߑ?Jjbn`힆/w%I+K&0Hп$jQhbI@G%5<ґ/d1*?*V^i ?NZ[VrL'^KZ:Ĕؗs4sfMP.jf,&U%`repNiI9'uGx8b^|qwkޞ#RP)Xcp].Exhsfh:ܰt%ʭY H8K+ /J`d Hjit?ĐXHzgᩐ=?hZxu6!T2,=>yy2e3UB[ӦOO9f2>s <Xq+El3ڴI8{KQŧ& m"|?tY{h>Z'.lBXNKgwt2zƭ x340031QMNMIc Ѥ.jƗZ3 xMYyf9s"Uc ȫvuCPYIIE)U9IzE9 W<%6)Eez ]tˍ$;:ѥmѭ3\Dƣx340031Qpqq (3K,cuW(xDZB&fee1O:E3R"jȡ++36bغwGǧ=OnViԜԢz6(.ح=/WĎ!@QTtGwݬ|.Tx%E`]i4q!*GQ[VyV=zԌYsyf9;Ғ̜bR\\C{w\ex340031QMNMIcvqIu}w[#8S# єg1h}yzXb)U.1BUf&0|vWVԝ}+N*k_YQU<(w7#crS3mcbv~ڥ <8Te@CRK2:Tn3ڮf;W?3^ү x340031QMNMIc6wJ{Krn<3؈Xce̟<]O-MK-ah}Yo?9}UY|N~:XiYo.(-zuԅ̕m4)-}Y[vL7,xu'͗oYZ!x340031QMNMIcx/  h~C4eyF s=<<ľi͆O/(ʯ43K-aH9s٪!=/u, RC]?NVݽNq*b*L<ߪ/cN<86ӷbQ^ZT bK+qͲ"=^[fىMK.X5ƏUwwo;w2cw8lKR!::aiϷ AY|'Md!+x340031QMNMIcγzuбIpl)+36b\zr{{-wi+ 2=5/44)>/?%U/(k~ޭ ߫ȾYT]~Z?3rFM͑N5MUn<㚟dnWh/P`$2QvY'soWÕDj$BRTR 6Җm잨yƸij|rYern'81 %攀2-1QCiEtDQY\XV|vkυ'04Ɑ>b ΰӤHV} 'Ԝ::<}52j]/2>g>`J.gǗqT-ML+5RaCwڔ?}\&8 I)(Pxw%/ C תy<;=̢u8$cT&7?JJP U *k[s;e'Dx340031QMNMIcX`gE+REz^x߽MYyfVMV~RP6ڡ*SRRSRr"7cߐҥ )/.-k8~+t})ORC51IC{jU.}U|)J"ĔMw:}Ώw$}u6em-T*&AQ >aESj MwK{ghܘ/  =x340031QMNMIc-8{ޑf*qJ͚fbQZPe ޱ,~"H-a3Vʖ>s:f0U(x340031QMNMIc`X{}dmvpp(>Yf!%$hTi鳝VW֟:l%*/(tN{myX~FL 8U$9urgt˙ü3]X{YWڟ6ҫ, Ho x340031QMNMIcb!Ѯ}\sU,r K єg1' =b >z9!de嬂P%9zE9 2/LU"r}e%)Eez vWxb78\ow7x340031QMNMIcx{O"*%3c_1DSVgl`?{˖lꂪLJLJJ-J())K-an9V^ o868U`˩)OKߵ=|O_]\Y9:oڙyeY:Sjrl䶞s{,^kOLXX("9z*4rs^N*u(HVݴ:rѽuDie겔D~1 QA1UZTZ:aJG>xS7]Ŧ"x340031QHN,(+H,I`!`bB;/O?/'3/j6;w?g@.= J3jvۜ[vS*j*JMN̓ĩWoT{o9E{:cgyWԸ.[UTZXsw=y7]?lZ/Zf4KBx340031QrutusIMLc鞒6aZpIZbMk ! 3Ss6.`v)fnM )-H,a^ G} WɮvuY{&>a/BEIQ~hZ“q,gD/3`PڣqL޹h۳./,L(arXטo{Bon r*JIMK,)awv_M'#oCs׌U+),*fX!>)q/Wz_5L>?Y7)8ZgfOD= G)f 7ũO:zq|jVbRRjQCό7D $>թhtUi Q,_V,, 8nW4u%9@-7X_2',/x szjEbnANj1CYW1m/v`3Sj2RK^~6 噝{mkļt{W]"q o}uI&@L@"ٞ05컟$6܄gNC=눸IԫVP+ K@ezS x=\3$X {+o1~:۷P%%Iy)gj-Jt/$Vʜ"?ߵH90~x_Xv]M&H3!EmwlqEScE)3:ǡS^kʴm&w[2@@ 9cqN?^ 8(3nUzûw~$e=?grĢԔԢ7Emi8sGM\+ w~;}ZCAg{{vBdK Jt2Ӌ2{_'~(7]WʷvW',خx340031QHHMΎ/H,.++a~6[/xmy YRDd#F2qMJݐ"Yfg\`1#j#Rt,r;$GU#ɑ(a`|{~{ LMX?:'Sh1J.~0ݼ(XPop:/qp]wA¯a/'Nf^e/g>Ѩ4A(BLNƌh}o5Ŋ vĮۚBH  bڠ+rRmi1EdvD]g{"?_[D7X&öuHNJF~ 4:HeM~44B-z27qC;{ )I4Z#], K(!:45\l>,U%Et*YBJa2ge܊ŵ+ޫ%ƿJjc`  R}Lуf4{N#ݻn ; @Mj/?^FM ۔Ns+) $e_nn灖 i>=S4CFVy8̯$'iY~A'ɠ|T*R$/l|BܮxcK" p8zGu>li>t[z),/bv"O?i% A^m"^ƚfVTQ0Y ~Q5Y%8_+{@AuY2x<@Y{+ϊh][D1SīUPEyV bmZb{ VXqg>rb\Q3Z3!`);W@Ԉjzlnɝ'? [[tso)W/`إkrO k"Lg@d 8=9ʋ)ol]H@t`Kq?,RQC4O^;sZ/eVW_)89-@_OR7.RrRBP a&jӓbMXt%} &u/-_da֓ߋ+yO}Layr)Y |q/#ryaU5"Xޡt:$ $v9H$OU2Nllꡥh(P&);]|1@Ʈw 2+l$o:\ieϜǎ: {&2x~V(UXvU~SCߢ$ 6rK{%Rnd4ﲂ 1/tjkr>>U{#>~,TVNkĦqꙭF㰨 Ó3 Pcg %ԇX8!έY]A]f$d_\{UjE1ٹ^)-IU0Ugo-寖2F| Ϡ]_#o64f NFMU||c75,NT+NRf7z9lǓQ[l])hΌfNT%tͼfo_B75gў?I:=k!La*-T>КMnS&`Q[JW̼6:>[qNmmRؘw4u=t2--f q0K@/7xxؑl7: @Kfq9ӼJcƫ9Ӱ@l<ȮE?DX3+0?JeKg?{bGZ'I4!x+b.+{\TmȩiIL,s^hyycrŠܓl(^^DK!;U츅ZS=D=tNP0TbK0Dwƈ0{u{+7_6^ Z$*Cgbwn2B06V`<rxM\g<) 9|S`H򓠥,Ȓ_ڠ" #s tz@Mk)b}}/ DD.f N0t٭4J d&XCz"uu]Eݍ-ROuҠ"C۪u k S| ;h5MƽC2`olW~y uZ+M4jJ Z% U*\Sѩvͺ+ OJum-˭kLf|>o/$t.,35^8XPC4:L]yѿ$a+̾.i~tUjVR/Unyn2`vYB$ 㹭?s:SH7NePw8kWI_w$qKvȩge $-3 %K ]7SWѮaOi% (Cg`2J^\B##e c@kq@Sb@bilKK5;?0]5Ӊ.{>Q9qOoN^&o TD{pku~ /Vhy55sg>GӰHdwP} dLnU" y h]1_6weؔNx340031Qpqq (3K,cuW(xDZB&fee1\x}cGˬXbMrSЕg1ײ./h¶-:߳v9UXZðvyʼn'W|VԎ(豔Lycw+3wx%E`WjoOypGtkKMa\̯ x340031QMNMIc<{:b}Xy!x{]׭& _2UY|N~:XqKp{r^պ*hJsj"+[yOYmz/S5 Ux340031QMNMIch#7>{xAC4eyF gߧ"˫3C^BUf%&%$%0z~;u{'͸06ť` 922^Ȯ]e~[ TCnqqa3x$qgœ[&yh~8 ST St];/Z=.g U4(3lk3wǷlbCRզp TmA:4Ow9|Q59[^ ؤx340031QMNMIc IumoX=Gv)+36b`nrl]T{-=w~t⒢̼Ԣݳ=/zE2S)PRT̐}{Ԇ>Ι,\RɏwO Oiq<AUeƧ$$d_?x:'6:T,:憤*/(*w߹) .2_qa1it$UEũz%9 _+?Ko[δ՞ *ݯT΢I^eIIx340031QMNMIcXU;y8&f)+36b(l멟vb;}$d쁪LJLJJ-J())K-ag.Υ|؎]o!۱**DE7>j ܜnwJk]xYbtI`kNnpt3o5m#X'fuYy2Glﮰnyx340031QHN-*MHKLKcP%5).x\4? iZt&l&T]JR|qI~Qbz*D2FEﳬt\x45+1))(%>$X {+o1~:۷P%%Iy)' <%s[dV/UZQg[){0/SBg%CUtt㊺ƊSfuC$A=:ާ{׾ia۲Mzd**H-9rpRwT rTMqjQfj1ϱo6$xsN{0CL?kR'-6ÔCjs6_|w"x340031QHJLJJ-JaxK< V%Md&$xA!f)L=b oV)Kx340031Qpsg68)r ? J2S}峈]ꗰYS͜\]|]ݹ$EzbL @!9?(3,YhñwoH\qDEJ~2z&kJUMPl4%1XljEbnANj1-Ck]ˎy%E 2'\KݔyyW>lӁȖ3ipd/^d\ j=x340031Qqq c8ʄ~!E7JB%3p>Я}{ݎM~CL sn%u6 U 6὘s wk͎*H+)0H:6چ=^ @į fS7g˦GB]o9ìĘ JA /}/_g[?YUP[Xvk -.R?[3}}7z=x340031QHJLJJ-Ja7Ɵκ'÷5njKrV M78^S/myux340031QHJLJJ-JO.KLKcR\`1qCCIagC, g@M ؽA_gy7m=GR Q`iu{͋Ț*ڜ*IU{, cvcၫKŠv'e@TZ=-:43~ʂTiw(L/t>.u)p5E9%U ?IwߌcZw9~a,N-L-f^%]+xcѸW\3>\S4b/fvt KSVZ T Qza~f㞍eiq^g-Tx340031Qpsg68)r ? J2S}Ll8<߆#j~Eϭ.@3Mjs } &Br~^IQf#6{=C1W) ld}>ͷjӲfV[CdS+s rR4..Ys>LrJ().Jf`.\l_j<"[S̠}@*G'ob74k{x340031QHJLJJ-JO.KLKc-K/ѳz/MqFIIA|A~TǧռOwt=T7w/t-ŹJ# ڤl%T-Ԥ̼s+.6 |`%yW^_p#TeAjQnAbID5N9o!68TeqjQfj1mVϿhyVĶeZ10@ U]+wEsv̯x340031QHJLJJ-JO.KLKcR\`1qCCIagC, g@M ؽA_gy7m=GR Q+fjYK]>~yn6LmNJbD$ͪ=e^XRڥbPU`2R *ܮs/-1 qh~鰧W* Rrt K2 *~:|$nsUYZZ̠->!#S]JoӝE`*2A <2\A} q"x340031Qqq c8ʄ~!E7JB%3p>Я}{ݎM~CdTDjahxH䎧蔄UP`\Kի_/JWp⫦PiE ޿pP=Z QLǠ r@ >8'prݾqPE twn CS\ڬ UP[XvJ dwd&q9f[r/jx340031QHJLJJ-JO.KLKcr在5gz$B$d@T^|gh[i!OTeӏ8*S2S~N̮.|t;|k, 3x340031QHJLJJ-JaxzSa޳ 潋-.k&$a㛣;-lzge!E[t*! x340031QHJLJJ-JO.KLKcؗwGX)S/]̿87?%>49>'?vc"G7ffμڂԢ݂Ē ʟ܋/m+-j,_{TeqjQfj1 )\=rҵqg]CvC9@x340031QrutusIMLcQ[RCΗ9gB&g$楧3;tFR+A|* S[X°#)翆g\׵ Ue3Dk]]o|mtxoc؋PQRpt]ͅ/x7Ow$ET%zy ?i?㋮z\} \UAeQfzF CEE% םsmev0%0y)q/Wz_5L>?Y7)8AP6zsvSIsw s6.މPS̰+AnSuF{ PԬĤԢ= 9OOT1"|;֢JNKgNQJÒ:K.h U0<; a +s rRZ:ǏiYUZRP~W-τに,Ka}ye_BonU$0ro;*ynULYE%% nc8-E(65TQnb^Ab:нEis8>E$ P(gH3"{wW\ȟP_\r {;NyvF(.\u_IMQ.C Ir7~~?a݌ە`*R8:nXKFeyhms~#)vmg&Rz E=|_T`njPT S&^i!aJi {ROK\ 8(AxUjff ̙ԎT`CAC}W);vWMc_UTX 's}sL+^2bx31Ԋx WXWvYOpNh?mZ^ x340031QrutueTqW WTLV"(1$H$d%&2Z@2g}mGw9OSjQC# #AzMsSSԂĢT]$=z ){gr\Y׊l?f NZx340031QHJLJJ-Ja*x~wZljKr*}Mig¢} x340031QMNMIcXu%<_}|ӲQ h3]ޥcW~uomPYIIE)U9IzE9 .}jκ2lYH2d^몗hy\=2䫴Cۢ x340031Qpqq (3K,cuW(xDZB&fee1eL*uS ѕg1]fz@'}Ҧ톪LII,K-auȳB4pֿg (*z,e2SFJ +J3 x340031QMNMIc<{:b}Xy!MrEw.S/{C4eyF ]g9Iԭ.=7*sS JKRr/ww9)s 1󰪬c['^#}UQT V s c,&}\ ["TEqXk%%{>N +0f"TEi6XE[I^Fg2ex\x340031QMNMIc8pcfz; 5Dz3 єg1kaTrE;*SRRSRr\өTsD{ؓ/r`S_\ZPSk*#UV{[@5V1Coǘ/[?0UnՉfx)1ٕIE_A x340031QMNMIcsd:&ewk)+36bpakˏ͙Vvm!TeIN^jQ˲"m2Vw'$>L/yLXmƹjKuP:Hx340031QHJLJJ-Ja*x~wZljKr,g4:]|ݤڗSNx340031Qqq c8ʄ~!E7JB%3̼] c U R0?U>2r9s_"UVRpWgŬ5R?-r /`R:kʸƲ]oHA}HH3T+XDm{q+ JRs rKRAn-a1kC]K={z%7x\x340031Qqq c8ʄ~!E7JB$0ؗo¶-x340031Qqq c8ʄ~!E7JB$0<:}Hpqڏ+5܎&R}x340031Qqq c8ʄ~!E7JB$0la7{1焮档7F6ܽ#=~Gx340031QrutusIMLcX49@McC4ViGٓ3B&g$楧3_Ϻ g~6?m%LQ~nAb ÎIr]3+\ WкEݳO 7]W4ص5Dh?BEIQ~u5dL|ltu)i9% y-.\49dYn1f3`LQO{Ca~nRbq*m즒m\b__rST3ګ7LGWZ[ZPt}=~LX̺$třy%z) Jzje([y o&FL%99 [䎊|xx[&ĒT nV1آTd^]unb^Ab:Eis8>E$t% 0Z<4{XZoq*4aS\Ή;o;XOWw0utݰz"cV¢hэ.;w=m͉{'L.&D6OU{>QUZRP~W-τ11||\jV?_ڛnnjPT HJ+3=:\ůA;*mR7sLzcS~N*(I-I,I9AfyӲ7o})SXj*|?VPx340031Qpsg68)r ? J2S}ʳ,<7ZQ3B3Mjs } &Br~^IQfCص'~:w )Iy {8p=[3g۶aP Ucx*sԊ܂bM鹋?z;K֜!!J~1-(^y,K!%9 o/xtbvI.fy/MxAx340031QrutusIMLcX49@McC4ViGٓ3B&g$楧3]Wk/lOKas Kv$LV~뺶YZqVrR2G6}6Uq?<CXkvE\A59pUE% e(._w Om*JJLJJ-Jѳ`tIչC*̗h-t'frUOWjOjBRRKsJ)q/Wz_5dݤTA9M%e-'(ϝ۸x' ;r8ZgWo 0"1 '^z6;ؙuI32KRx7lTPvLJKsr6hW{,;7wMQ~IbI*Æ[D}+NjlQ*2g z:71 1dUH[wݢS*vOy'> TyUyjĦ(as&@Sn vokN5;MerI0!H9w*(b߳1ώB̼ԒdW_Ǽ myfn~&PBQ)(.oe_= ?? P(N.,()fĬ=/NNsʄuPKK3$bYon=uEq\x340031QHJLJJ-Ja-/Oڲ6|CT5%9 |}Xr!rﮎ x340031QHJLJJ-J53’"*ԜD3-۽Ovxǭ#Gt0Ɯsy57tTjx+cB-5$?cn4_xRުx340031Qpsg68)r ? J2S}^Lw۶k {r* wg• i~WDY&@WR֚ͻ/0~zo׍|{uDEJjRfbCYPTW{}&K5^)UNn׼8|{YyljEbnANj1[ݝp%k·IN%E +79ximAdKs^^B\&^|¯x31Ԋx WXW`~t Ve{>wr:˔Tx340031QrutueTqW WTLV"(1$H$d0f[\qb`@ x340031QMNMIcؑzВqqDW]~hj5DSVglĐ? 9]u:e]*sSsKRr">L,?cso+MZUY|Q~~.XmLQ dcY=y=x340031QHI-NgWseſKoP ߴCb ؠ2#Ok "Tbh<)eUVq뿌}{/|GHJ?* *V({YT&A,byu6v۩uW'ipQ^1@&m}^!PbǞr>ǨL'UQ\VqEIɞ $¥UQ VQX">sYsX\g'# x340031QMNMIc8pcfz; 5Dz3 єg1kaTrE;*SRRSRr{i[39 )/.-kP;[k"gDчj(H+.ax-xǥuw;|] Oȫx340031QMNMIc7!V~ŝ=:!qyJ$F x ;N@PH#рb?]A)Ƴ3ȒM-" s'ҽmV!{1Yؠ,!YE+NS- YtJ)EE3@&i>)i}qxPV~uu3gx)5N#v8rxehyqVpѴTpN~_=vhBx+.I--El_x\[s6~^(]Q2ĩTɶ<֮Gr$y&~[J,f(RKߟe[$F_}Smf6_f[gezmt벲9{1zkMf-=uBdVoJ75xk^WiiU6ojïT6yzNOE>h0ǫᵦ FӁ{TLD)~vWeZ__/cme5-bŢxͿgf͍~ӅIɈ~>WǾ߿w?|w}/ڕD8յYA "gafJxg SX٘N4xe;-JRb|M_ |@`zJ<EYqN tRm+ڟN8Sft/iZC+:} Gَ}N̪؞H ^hk~" [Y.GXzIaφlVCRZ18Mh#}NʧƅPE ]WR/(_úkZL|,YOktYJa"^G%N-EV'f̳"e{3M6@8T~G%Rp+VO.d6Ok^|a:ͳ<3燰pTh9oe2+nK'fXNZO>C -48IpZdTÁ_i|ijOSgdUԋHh>DîI%蝍W*A( [V)/ذ9%ZB+ɴ6[>wqId뤖ܩI^1<07d]LX´wX~Lu?!¤7X@l^)fQښ>ANv%lHAa3.& (-lADꕃtXH !GB!FPhp,e28@X\sC Zţ7¶9ˆqKx=zMB7E)]pq8Kz̖ޱSHƙ C!bdDrΎD6 x,Іtsqh.C0dj`I4I'.$fV&]EnRG!Ho0RTө7{x/e`l T kbM iݗu%ڶ4*z`q}= ghoi8t6^=q|3^ }1ԑM'ZV_g2$Y5[iW(EvebӝBo,U'l?{=b\9,DgH'(Tw8MG` Kf/$1/^Eo?MgL wۜ:wV۲b5`0(G@!pXew!6/;p~6,;#H`E,Nؐ"oޱE@ ҺDžgg@rg@g;P_ VsH-Bpp).QYSیM"(U%\)XG:f8ƫ%7PnOTp{B؍f5GD}h|Nnl Jcqls> AɪpkYN84 Ĥ?zycc9+B6bd|MXM\v'þt~SC0FpDoҜqXi!>_/la|f}AzqQdnMA 0ltYGGҼ$R{D$Wcծw#wz-5Iέ:Xn<W{̚xE9Uu\atMg7!+N\,=&#t^ %Sww*KR cDIDq'ŅMic%q>[f,Tװl>d~ϑZ"r'o`@X61YKmɧcW XUοp=kw JQm]Rp3B[cV-*PSH~9Cz +ƕjR*E"?Ol +$U!z/ т S:''D]'_A(ТOEQ6]PtAQss`Z_~8+:mklfq ¨sd/yJ6l'd+_s2 x :AR%(:,OĉuҞCzGjFѹjOlB_S\&Tرƀ-Y'+TRn! `r(;+rxprO9VejIOWi)$jRa:>q00 Tm&]&V ޥ&)9qhFΤ6F~QUVrT3|:eB:@jI'gO>?K~Y9c } $rSR +zm]VX9ޞOou6Yr?|azL=yUGMIzfDv$wL{("g))iZ_PLiwXWIM,[s)MBgj7ĚqXNx ZܤUFP[$D4vI,L";ԉ#p,͉B1m+ QxJJ}1cCZN|Gp KAjTĄn 86!r%4\?#zICLTw-}?.=m Wڬ2֖R(YeE&VY}U2 eNư+IY-<} {(G֡R7=IcW?wƓE )Z#ۑqmjT'R7Qlc@PÞ9Gѻ4LwkQE;F;ۜh 2 rj*WuN\l:5b-ZPD-rj-е"wÕv.e7g HS9+B8ƿrkt7-tj2؋DEZ`Ȋ9w/8PEȏ ~S_8Q?2!Ş$n[F@x[pO<[LzldFEpeUܶ ɒg.+ smɤK7LϔM.@NfDuU(Mؽ呂ȸ#w!'124\eIaa .ۇ(dTA#|B*91 Y QqpWZBᢦAAumr iI1IWQFyzy SYh6xy.GJ_{nR;%mS;Rs#4.>Obm*P'UݹI w-o^v7_." }Mϕ[vcm$WUՇ' [.ɃaZd9a$G=cZ&hW܃tIfr9 O#:^R8yel)%Qmhw˲,),yG] rx 9"e$K87"8u1&YM<B <9ajI?z_MyFhPN*8-BWZVn,"^Ca=].% q?]ssh8pDF3Ӻi:s JTqu%Bb!ͩE*5K`H,;DsJ_`ty<2`c'aNS~2/woEj~KV9ٟI  s8["|NmVغ/3YBGB]T,g/GE6)"@2vAT:4h6sS>7jΊw q@gpԪ gIq3m<*vBOTYV^AQ a d0Rz?Anzcw2dt~5 '< '7Bױ=P-=bfLAB?2vsN%_(7FfǃPda]@cs ,T~҂2ٺv 42K߷Eӹ7#+2# Kr0.Oşh?'hWtgw0?O`Ƿ?0Hd70#-@oohٌVzZu?o׃|71<$z>>p6}1;~`Ӻ~OfT7CD<ݍgx?zn=B&)_ÏDG7<|E+3蜍5]:C뫏 o4_ %&om}Ox<oBZ>NSc?,Dܥ5>G,=AiA羿 ʿF vp=~"қ{:cOt04d1#=`H|GZ2x㴓t#5HH6'X?`S"3Lnw<"zL@D7in<ӇBIH_!E[DI8Љ 6]y{O)65SL`Dbs__?Nȴ jdl Elɍ'泾':F;Xu-+"a[IOwIߑ(ZGQd ӡحG1WdL٨TXgOp#;.YhK yP;GosSz.X>[+AL$s7R&F!G9e:*hhKuS 0GR p*d2q O\pYTn s=+vؘGxa\Ha`8ýjWے3 I>>h#M݈NLrC?:Tr0QZSZ?cځ@g;n[^ޗvcGʂ~a2AY.5?(r!6Re5_>rL4j/ǂ :ElqS9^}+:Ati]YXzb *C6_:n*ݴa WOyx(,ݜ2m!U]u4oV0 s6#UyF/oi 1ջg5Q SUJ>r:|@)/nzR+icp'{H׃V[W@%bxU⡯]Bi3#4&myи43KB*8VH䎏/i-rDQt2He.^QPUͳX$mr*z/yF azzTÜe }\seʴGwJYRz2G+*)X9.[:bsQ?9s gɭU[~fxC{QhIh.t{(C/u2}Šl>(],e2W=r<Ձqn1jZܶuD},b)3Bn3sM%$V>slUdͧy i㈰xY{OX;W:jYw;Z3Sh!8G[ }Wp("~퍾OooOVqa]^=wGL4ak7 fuH5eAY{F?:ϜHK_R $VwsoJY̧N 7eqs?$z$^ ȹ w:w "KJGyE~obtGIl A:zd$EI.Ԧ ""Sov?Tx酹-̹Ll"-xV2:jo=m: 2O}KF[y2m(ruT=Y&(9{L'Z6AIN[uP "G'7c]àO x&Cnn0x%ٖS 3ք6M9zQ^"g<9Y1Õcyo#WvT& V)'dGɞ+ Ia4F.䐪jBz M|eFS}9*1S5K:Kw/d$vJ~-yظ<08GcAZ,xKV9&G·lk' (툋4ɤPYj}Em^u?nxm1iUR50/I\%FϷ'o6)m+#0&fhi, fd VΎX@;|5D՘OzxTSOBdMG #N:dwD'PȞfb(=Q8*I; 2%%ΔUwอ/f cg%0ȍ7t6~*)| 20/^c>c9J;!A^E2v'*y ߒVg>O؈Y0-,EZ'#, sGUd0r[CiTzUm <:55={M?"??ۓy"p8(O͙lc7 vi~y +$hO$:45}v4ϹnZAmmJǜtÇ娂1~@bG 7`G"gd1*;ojx3ށ};~BktVteheWer+~VkFRmu JY" "/|b>"7Tovʕ8$OT,ɟ3o#x{`z># 5e8 @x{`BqeBRbJN~ '2lĨ0Y}'sqe(OԝĹd` '?r=9 Lvev̙̳ns=8M7|e@0Ax[b}zi@[ԬĤԢԊԂT RLL4u(BHsNݙVi}e&{L kVx{WqyBbNjEj o3o6y {\3]Lx۫Gq.*ZZXlNd1\6 xZSVlYɅ}| tpRl;SFX,i%$o߹/=lH;a t=_o7aܽЛ, hd$~onD6I|,2?(_I{"^(IyɚLB,S %NbȏoW8–gO )-ۼkҤP_:_'EBϓϿ&j =蓮HL|A*h?GLgagC?.D&(i1#ٽzE,vjt<=9:n]t~\Ӏ])4: ,O)TlǼǞ/ej0J~<7ܘNXTg( m%ü8NkVQ~ĒP JH%FgXI) \WqH +Kޜ z,:v3$4e^gup&\ @_k3C9,!Un["=jWwyX Z/NKI Kq:q*!_("w0 JaG ^HpZv/hMgԽ}[ĀpCk~kS$)LxŬ<ʬZg+gS2 REGOhW֕g~eQ5 pTo4?3:ѦvD~LɊH9O ϧ t_4U+l Ʉ)}X qOerm"Y"mLOjIn?Bnݗe -Y8'?d.K b;J2kh1 %8dˆ⚟*K9p:t2d\EGB! zdZ _:Y o'yLW<Ul.?>|VkӫST6Ra ݢ ^˗o\ Cokf9jS#"3 *$W;d*Ibs| ,: lYauIьP*yK]?ON./#qP0!~N;OaJ[ sc0{ W2čIlS~>Ej&~28S@+5z3)]``Lg6_q~~Szv Kq`[h%?G njAΚdp33$585I7J5'@#BAQPQ *f-MyCFN#ǀY%iJw\z 7V)AuVUj;ylWH͡63a-3.xaz<EYЌ$lC㫌bJfe]7M@fSFj1mXkT5bI4K~-F+>yp!ľ͠ xóN$ڦ雞](#wP;4ͳdi&Fkb pUc !8nE,2?(׃ rjd"A`s hbaStrd7/(y hGQMD7(%TD:&g*WQa} s9:RmOHPT!^YM00mKyL(,Wݙa-Ye0ӡev<=~T6נZV-OACf:^]iYn[D;JGa}@kJRfV&25Y;iP:n 4owOuw>:(Uͪ&  !UT:ߙX"SG" JGt%Dž`O{շkp8/w^=V< Q1VkOm 0sRh]7 cbuIf ˜ZʠbaOje;j}xQR♈eXzW3;}E}B"PY:lQU4]ZMji ;j^oe-xډ~oBL5M?0#\= =-2<9\ߕG{jb!T~Yu>ϸ*~@Ϡ:k(+H9Dɹ'uy|#A%WS*T"a#YEZ}nY9֕yIYU'((( K\G>.?E3?%\£ gk0t8INv+㡑'4IH#Hxia9e^w?F>3\xl_A#ލJ0r k U;*-ͥ>]5t}X~Хb.cJ;ة&sT@p^ȧ5:rju_ gWw*lSyDRxZ- :p0Mlk& i"Î{lU辰R *kHBfBo첒W( јQmO`Ef6M8}ar9-oF *.S3loj${rF!F^ y"tŷ'V"Ap\Bzo,?쏮ݰJ8!PG_buim*"!KWc^ ,?O%_>U"U_nanZUVdyob|1x[>}RNK9ϋg('e&*&'Vo^Υ,T9 nx[㾡K4=D!%8(3)UAW71Qu"嵃2AVM̨EǛzg;}m K\N  Y^Ei7.@RkQeRT nP0x`0TO?u6לt/3-XS6U xX`u!܊=߇gdYs =D!m ;ajFw}FQ C!\.`RzvwMcUB EDE;7ي~-ʳӫ}U^$0VK`m`زBG^#0e0MԼ45Z+(1JoM<6)'3TRҌPua:F4pz^0m! ,kr1ڲ~TF),zhH"psI(| @~ P\|1|kB;">+Ăё[\ b{EbTw,>wac ؉3;hk\ǢIVYO|ǍLwO>e\cb-w/ur6dՌm3=ϩ~jgW./1/?忞^Fct@ dC ;0\~a<촌n.EzpxHez֤z).vSu-KwF 4LfS]YYT.r?Sqؓ3A& D w1E&h`U] !eksSBo'<Dkؠ7jhxDPLX/ ")Ί9lW 4u-`NyN}.,{_=ٯ&t(7W?y+#'DfΐW1*n&xmjA[9tBw 9LfNoB,⢐*003?y}. n6JG˼YVB5iO07αXJB.%rR @p[]M؈p:ny7O`[~0oTFTeRIվN>itx#vo3K; ixŷm3kx[veRML+x;2Y(5+1))(EAHPϠ(p#?/#Bpj䫌 %: & ~e F VFfVF \Ax[ksF|+rIlln[N\ۺrTC`Hbb.=@ѯu6YzzqtV %Hʨϻ8ﺪʫe?y*ϯESx89INucbQ-$QeWHSx4?k3/)~?1JFkM%K%r;#|-dgVW^iWBCRS5+^.!+.[V}OݮTPTe]*OW0hȫ$i7>7VoEקEn`骪U&L=ԋu*8>:9;H+ж0oe\t!6e| Z p Pq2c*Iջ^߾zY#栰<Zb#Zb/P!4cd-' 4P-[ZeLJ,*Ax^g?`jo ]+#gЧ A(l}ܑe225woR!6YAҮmQc 2 Ӆ`Δ5M^69V5|Ȅ^ɮk6i9fa7ayY"Ǡ@VI^iTҴUWrF&Z)28K+d$s@psG S(=jZvǬ)V@.R Bk1,ޜHU])x*u/o%\#XHo u|ٵ̌DZS5%J00f,dh:ܛFb_NelbEփp+)x7S_\Qa'4q:DBl`.P [K:BHF3ԑ A@RIZ[EKӎ0vcC[P J!YaeyI _.Ji ,Ƞ ,.zo=(Q[$0zCd N@OL؂Ze0kَW[7[aw6E8yh{, ֵR EQGaN=9"X՛h'd!jҜZx'$皘|—Wp(,J`[P#/Ld^-_ #$[9q2hy$ܶn1_YFR>Ē|duo~XƾOa yzG$¹&|!0`'l z.bW|f kS8SOƱV~%9u$4rҞ\|$tRƣ-#@n 5;a DGl5c+u6XaH2#X +BL?)1G֧2@kVqxfh%e gϘ@}3ǍcÁ`95>"8X߾9mk.鈀Lٵقk%Kv)8Ȋ#qGլHF)2u`/S3rsЦa`RٓUoewRM]c-D5^HTJv(=E8%JU]0~5@jij. u 0sJ(8fM X^XhW'2$;1L,7/O]7ʁ ֮`ȹޙ,tҪ0B<@3Fjib')P8Ռ\IeG V|l Ny{gm ,(zx\ } `V K\D?"|4'~ު0ϭC$I u9!G+BfC3C_=4_hT[)s8oVa hXKX{K"I,ٿ$$d߱M82㲗Pfi5eeܥ8iⷦFw:-8]K]`Bޝ6ÓOrsޔ.-|*~MoE .u'ŶO7y\2Feܡz9V7CP11\¬ `UZtOnr-oɛJE-a$]|ۙ)g8 ;j:a&cY'$nlr Ӱ)o>G'ŜW773RnxZnWf" tg3{Q)kV52aع1=l>֊!q2/nϢ(]=F|ofLpvN{F䚘%DPQ `*4(dCK@RDJeZ>lIDfrξw'i1g@g|4~st炧vOʈpbk -?7dTr%Yl8\d{y\k縮DZ_v.猔qeWPNQk Gn2?H[UX+1!j9|(?K'@'qr4 ù WhM&{6Z+B.y(2zżNQxn9B]JN #|:0^+\]j:bVQ\ i%4RJu4e?Pĕvvb4}s*vh1Sulؐp:2AkeqpgRKy?%!.δXZHlӒ+>G̣㹬đ69S eؒQ$ݣfnL#qC seKKNG|xjW ݕqvi,T&@z-֬o=Pl40J90 emy{)Ky/@lӦ&ȥ( E7T;!L=x6Z[Ύ+4q݇ᕓ[IK#5IVgteN|S&@:&ub+ 2O3?2|ʻ/OV3;ʍ*GO>GQ♨}O rx #^a6^sfY~?Kǵ\Siu!pBuη$`$ZHoP]恦/n:r]n]{t-Fyc0u(㆛eO0g)+])DI)*qeARNϜ5 &b:2ڽ"ef&cU4yvLwv;%7m0ؽ&mwOEߴ}?*RdeJB<=:Yo^ ʬZ%+i<>7>v6ץ,5XK]ߤ%L;{ķG3ahT0B XNC:'u}Nuq9:eݸ~ܪ6|Nsw퉎VA鑥7/Gwd9CF!n}M&B߳R{9T V`6OG.U.~A/O˪.kҵa{?q%NtݵJ覫fTQo|8gxX${$jd~BFbYBIyBnjIF~JB~Bj^bRNf^g@}i'i(lCx[;s<5)oYx[}%m´+rn~sPF[xLr-ݛ.2n^hʲy7ɚl&o1Rfԙ|HUM ܊2u MR , L- Xloxv)z,2L)qkkx[&9AbB<< x[&-i6͋sL6LV- !x[&9oHyFjBfBfBiAzQbJj x-e"҂bԬĤԢ]-̢J;S7c HU)IM<̾/0 M~lXlt3b:' seY!zN~lR```d```hne`lebm`l`bBu;xq¼kT <5E4]AHR58D [u txwe܊2u K  M  L < qx{qBr^bnj~Yb~In~jVbRRjQnJbIbRbqپ0x5b foF :w*Lx-b foFM̒qZ쌌ӴM&+n< oyx}§ތJu79SxS[>%... IN ) P %J7P!P;!-t<x 1 ES/Mj@b\ X!=[U O3 e(sE>y4Y%t9tَ )TP]H._B*ҾxW]۸|_ҋW.}|9bWvU>C 'ʯOJe˵^`gؼ ЉϦ`2I6U:kЙ.l9MsCDu}+䝘6l]eBclۆ#&9H1Χl}%7HܚL㛫hTvv.xHlNWykvo?_[rZWqXY׮'O :ldfkstmkR5-g CX4P`!^##g*I;'{l^.+-x-CbjĻe뼨 ɞY.'W@ ѡ_]}8zӀLfPή6Ym4!2q3H 0@ZbkɶQl}(5jv4*l2NB6I~Yazvs@wd:}VRhrl}NGA-+RVP5B1`Fo_ll#EǒL".$;8x@go"pKEuDmuEyZs騾q(6ⳑЇ\QΛZ68ǑN FYS8Dbfa%R^pu UZo-r;~6ֶiP*6;M+sטM;:R;-c[/ZŪrJXX)8-W`3`I4w n_"ۺ!cҗQt}*U]Jk)PI7ka`i3wVK]*v `'pVfX v?`gӨo0q՛|׻w۹^u7-8E>^`0:lKn?/Z "D*%ri~IZnٷw>~w?Ȗm$RJM>#ܕ^"^"1WD.S"D0\`?&!L+{(ÀLnXEAg|S㊴t8檤W?C^>?JLw*9*N9Kkݞ^8/.S6Rec70̦gzȑF!Vy2a$\M襀 Lry ^_Mzgz 6.Q+ԳȓK/H@{e259P6mdgUb@G]`CI ʶV2wd߿%N!0ZԗݐnCIn[ƂQTl<'PcCV fft>Z1.@7D6v!e2Ty5P֪VR4:rR7b "Y>:JHКu)n86>SRfZkO_;l1;;,thNg[et(||It}Y)Z\&uV G\t@ڛqQͥ`j5PIdg^G#[W;hMb;=1mv ocV TJL ^TƢ?Gz[!g6V6NPUAX%BIgW|(*fz,2GoTn r_%kWUʬ%WZ;1Q8,  X:sn~T΀OC cDXw\U^1g?'xe5G$-G F>;\ ,ˬL:=2)^ 0^ʅ6r.܄8NZn=T Ŕ-Oc^ϓxi05[vCS ;l6|KEsLNRnLa*`ih@Uz$:/J{s5gAYѲS:r- ih8QxJQ1a[ֱWR*Z/e&hfxۧԡьCGnyxۧUd4g̛s0I -xM @E[? Xn|All>dg>֟Dcgy95z P2wh{E: Hy5cD` m?ɢA%d!fLLF $8m˲.JmT$9q:6H?L!ɞ[Ul^,*!><3;=x*Gd\Fg|T|̜ݔԂԼ<| ')9?/M!aP\Z\Rly&.xMRA=,xy/ފ=i$ EqWsMwLꡫ'1'~ YɊiWz]<-݀k)pYIExAW 8R8y Љc=&6iR6-˦W':Ĵ3L)ih]i?sI(a&P|A汥R-4[h6sKt1fGE\淀%%L9UBޕU!(d*RE? pz2xM[*bNr]R&y&<wn.YJ*ߊdKVfU\sJ|"-Z~Mm/=2rwV Yn`|'3'׃]\-6Rԥ]ޯou.Wi. qVm}%[Xz)d j>rw{ʔWow "/8Md\2xEXXc2ƽ&0=Vy^2\ LV1 U|ț_~lGy{YD.wbS*ni(#w9,S)C/d. DR8[$8b']JG]Up,~E.31[l>_gM\,eT FK5s,;81VĿ"3: 3_ER&^rlVywp=4r{AHl_U" pٳz5l,tu$e)8 8<:}UllsPKˉ;?x0c Oz[‘<WucW9/oσLA=0okU%jgvpm7Cl$> EUr]H= ~U;[O޼y.vEw 6&g [.KmI& KmU$ .rϢwHeoU(b8d}, ο&Ge,N).X|gx-aخ%;xBi:Qg07q7?QsЁ&Yo>c3gB_8,Yh&5hᘤ$#S. n; (^hM Lz]|&⪊L:Y<UkSd306d3F4ل/d,KY޼=%EHhpΒH* 8^C!$)bA.Y,3k<=Wf Ycn?ĺ ]RUj'hffN0ml^>qX82ށ(E uh vs4S A6Usvy:*..-Ⱥ/#I`}"Мo,m؍ḟIO9 I 8\]NI&qg -~̥>l3;gN3=Scr,r΄ye/b#^ͅ+|oSMB,S!ު=B[[f!5qҺ%?s##JS6f?YpVY, ,[^xSI}ZHO7L_O煫젆z[LP\^"/ ~0B.* wI^4G >G/hi<\ɮ*|W)+ -*d2^??f`CU1rV:}fVz|mR"Kf%,A,B,ГgȀ)7y S8+|>\9'96.Į?:HbvA9`t,Nũn0q p|ZE,I4;#ޫ$g`E$&Zȑy*q*?ݎ??֩һ4ZhO1JJO K;f2lJfM\n B4G!.Q69DLm9߬ucwy&ZK%Yad?3I@bd &ed1 *’0؛MToY2xff0;@+V*ƌ ?E焃44 Bwڎ0H?bsV:8ag#ӝAѸ&u@ !iC9087w%g `;dRȲ^T_ܓ_3Ed!rQ.š *" cA+HJdJ`hm*س#T4!=^Xſ٢0|\=9m#n| ܑ&@\g?oPc@r?ݳ{7H6*QCM~ GÉwN9!R[_kY*<֮b Ob sQlC=:8&U.-$H:l]! %+pZC -e]U |qpL3&lpQЊ%=[X{A ǃHuv?@'c~mop/tlȲY7 8̻ LxE Tn\`wLe|D5 )-E_ \ %[r];Ĩ&aQҞUI>Az3rБ9IyUs'=^FgǁuQ/J}X&Dq~^γ6{ X ,"L&Ep~@' V9bA `j+4c?*x,[)ݗWOof@ u9"^#5pi4;FKp|ӊO/G9:Xz ϑ rdVgZ+gH(XS)ծ֦&-T|{dqT@1xӰל$Љ40 RZد-Ȟ*uy8>s/U@U ٗ%H" fw٠9pIc6̔;#Dr`E-{Qj$_ՔE) q\'0C7R8WҍV.Ե{e`}%fL1Lh>Y tvDAo{ e=Tatjp˝8$yJׁ}4*Ƴ_fsqW:\1=iVwy#@0h=P3V.Og<1Z&0\r/7 FUSb :1{"7Rl"Uq#G[g>HXQYT&IN^x#.ڛir9tP6}M \O5;`*4 QoŗyG ' 'ЂCxN<:/oܼ{ 5饬)PBhBi{ɧYM~oG(J ^F x:$-V`'WWv5 {l`X-AcաS*H` NhPd5&@:=?wyr;`QR?SQl{#åK/m5@oJu9^&,Sم ZE^`A 0Xl$^TOP][ U S@G| z/c 1O@Cudb1 jv+|r-R yv c'SQ-y'zzsm&5^SV)}]DT0?SH :MU"u%*LgruFp[,N VބK>xIӂKږşICxn4T<ИQM1ʒEbLaPv 2,5 WysU]dpUI*bJځV=?BE^6Hճj1{Ϩ6]aÒ2E<x=i#Yd]MP5̩t]J;NWGvMHPA6#=_q"Tx%,ffij8q_,["*;v!(_ΰcn̬Q*pcD"O ` R mBF698E%JI Q?-qd ֏sq2řZlqg@O}sܙqpq/ M*Y쬊C!%\(ax';mOr'. N8im2$QY7J|Z͸MRWi^~ꭼ= kgv:r;X&z~0f3hW:8IqݗXYзZɸ Ns/!k}O_Pʲ꣕~oo 4]$ RS! pV En!M@Ba#M됸2XT-Pt|Z:xMw*p(l=nԶFr 1"H?z=%$䞞VՁ 甬^U߁⚪ zmjԘC^{>E} i|{=wg&⠋uՂ)[U ׼}|Bo)Q҄=zf|@XňuڶA\%)t4Er)~gIS"E tD,Nڛ@9f8WYm:̜_ڼ)ꃕ O.A#)0!#d! \7_kB3`[JT8weI o@ U&$fgN` ۤKU2TjK9T٥Tnb ЛD\SPJ':+n3e23J.7J@qU^H2w9c:M?eujE?COP$`4CӢm+,f@j;}R{FĿk R(J5해yC7ҫ|īw֕ eN^h-r' :9 Z߫EtbdlE.-?|."lRq[T'xngdtk㽡79Mn rTrfRq l*ыIgSeZAhX!6[яq$;X0~:c5(KRU.ؑ/М@3 EP; zfiI(-+iM|<~\Q"?7#Ꭷxx?|trAniپ= cdXJ6->8^"HI'iz(J^fqB(Dʵӂ3zR2) ДK3΄,;oŒM^z X{qGָޏ;,d g#|%'j!r?K:Bie8a$\ JM;hcT+kfx[VcO0DT;Veou~ љN*mToBmցT8::ZC&\oQSfcS}{ZJ̕؉dPKBc%aO XVcp=僺B4OnV]g\M#L xo=fYa; &{Ļ hny,,M`r^{pǫ[7q]ȶu#?2./n^vZ)bYU4k>Pm8ld8P)A!]7j3_ VݞMC Oq+G: -Hl3jCM>ɰ yFSC|i/1 EQ*B 9 3edܚ$^,o(HqJ`<<9vJʭ? '0}Uτ Uyu-TP mxrRȏ$Ѵ/S琁:^ΤrJ0"|k ؕځ>:a2jA S{[)?)b89^xDMbOIDbK4y] aB:Bl oFսAJ57W|5U=ukc2R%mjMoX ^CoBohd}QBa gBCoLN]5CS+ao}%{yahN)-#\\oTTôhƘ=O_ry@\Fh5P]@K] hĀuZbƭou^ڼbC7Zx<;cs;;2%kU#CIy.T6ުq< s fdp&[qӵ|z \zRf:In`WB>B ytt❹w]7V)^bs*&kS!-Zdq" )\h&)2ӼI)m@j;pPs xPߜj "u7-H.+R0gE{hދBWWl}[/jvp=֯W$N9' yéߓPFZ9F?–l78W|< ]x uZy^?P["}7]Ao-S+zc/gқŞ;\;q0~Dū[ȷ s vD~=/cL!0.0^C4ډS%+8Yu&9$6rn`!qn{W=~<$+ef2MmbZdJ!Vu1!ͅT&kLũ0$gyyR(>9XLMÀJѻ?q<)qpB跢T-ҩz'y?hE`̱jr rLBB !0{x:I-Mi-|Ǯy*83N8'%k;h>v!lf!lz/tC'NwߩׁlN7XY9鑑2Шē{6u\T]oI?lpszFA`S_ @rW-o]{Mx7zɜXa퍝`߼)1'iYD_x[i ٌpLalɔ>h]x[&ԬĤԢ #=C=C]ɅWNa /JIMLO-.--HKK+H,IΘ'9p&(|xi ӄ&볈om X(A xi&&ԬĤԢ #=C=C]ҤҼRCMɆ5"|AeE% IyXuJ2RR2T/I!33um9-qzv ): nI FF VV&F 0/jx[|ffT0x[i6{0v1[Nvl/Ǻ4ϩ ]x[z&{0b`le8QOtk&iI  x[:&{0bR|{" `-x[ca=uu6eiGPx[iZtu6eaksx[|!S x[i&On6TpIMV0204T04262X!YEj*Bl Bx[jR&7Iۊ(+&+*XXLf,"1 k~x[i*,*S)x[q `jVbRRjQL6'kJH++($+:Mnv12RpIMV0204T002124ElTo(T}xݔn@"h,hJSJ(RΌc+^UD$`|9I0O-!X 0*BE+ON7Gf[rF/%5Zd`~ւ&Ni&ԬĤԢ #='&6F24UGX4]@trFN>p hx5= @aFA; * XW %YI6aRlr +ItAjvo<"'ȼC2'N xaZxQ65+1))(EAH@HXS!/1eCYa?BkFVVFJm%isjw>>hxarq9N 8bxa:rqn%Ͷ+m &/dAesjw 9xa{Q65+1))(EAH@PLS!/1eCYa?BkF % F FVFVJm> kxapqndRk0xa}qsFx5û(T6.-+R1 Jul 2008 13:12-X xa͸YK!ROM-\`dU , ,L '?IW2R/x4iR6XY714i VRxti&R6XY714iQuxʹi`)˘b\Ex;4iBlV1&6Ebx;ŴiBf^&f:jxticC3ox;ti}&36-x;ƴi}&3'˰Im>XuI i bx{t?5+1))(EAHPx|"Vz\ Z Ae I9% FźiŹz%M,-HIjOOL̋O()JT(W(J-,S0403YzSf&? )MQ00Sp,(R0204P0420!>Ye@`6͂sqpHx[{q] B 9ũV ʦu7v- |jwx[{%yCxq]FԬĤԢ #=C= ]%Kt M , L &籉m<;k^x8&|Y9 2sx8&|eCJSu L|+ , ,  6?fR3=xyy{ltHDYxy9,,#9;;mtxyu %.k xyq5J !xy5区.~A>. %%VIz)IyzE険Iy Ԃ==gkbnfbjy!,k}xyqe̓2kxy n) gx[xQFԬĤԢ #==#] YM,M' m>kJk"x[x"I8x[xq!FԬĤԢ #==C]ӉѓYLK , -L'Ioܝ.kGx[qcff8\x[qqƍ'_a002224'YW,Ѻ Ex[q~ƍ}t$JSu,Js ,dF>z̿blCx[qq?^]rړ-XJs , '+nb J |}x[qq>Ɖ&+ (x(X(ZYM߬+% 2x[qq^FԬĤԢ #==C]ѓp[dF>z̿b} px۷^ 9/skOe002521,!ٍG, Vxxb^A:R6KGgGyxغq |z%Xu&cT*Q020P042425&U< 铕'2OVeQPWҭ(SGX7RBx楬`x۲r}'Ԟ\ &lX`d```hnel`el6YKbRV`+g?x۲qrFԬĤԢ #==]ѓ'( Z(&V*X(ZXNܼ?-kx۲q2SYlx۲RSY+&+p'e(+($祕gq)((ln0 Ax`ejabberd (2.0.0-7) UNRELEASED-(CH! Updated germ}"f 10:56:08 +04 mNN nxq 7&7HM6fn<ߎUT7RBlr̓)*x7,3],%>28 Apr 2008 23:19:05 +02N)px1С,3. 17 Apr 2008 17:05:0N0x!xɍ:R&o֞/&dXP`d```ddedleR?nxu>W? WW`WHא :ғ&o֚`&nX`d```hdebdejm`2?DPSxkxo&LFLo:joxk8g.Ɨsxkxm2LUu$Kt | , ̭L&'Hlvso@xk5q{̛o:O[xk8}:`jVbRRjQDAى΢S5%}t| , ̀hr"K,k+xk8a.XjVbRRjQY]jIr~r70oɲ BHcxkϸa6`jVbRRjQDAɢ D ,| , , ''Hl^ʤĴ&/?6xkz`jVbRRjQDAى΢S5%݊2u| , &'Hl^ʤĴ&//5k xkxq3yk#xkqg/9xkϸq$A<"FFVY$6{:hxkxQ05+1))(EAH@@hDg)WYZYNN`c w+xkϸqRI:%: F nI F VFVY$6+pg Qhxk(ZaggkYAKzL:R)yE)@Ҋs>233l+k1x5qs37{Qx7ejabberd (2.0.0-4[20:08:54cGx{=D,,ɛ'vHex{;Ɖy[C%KtR ,LnW? /x[=qU?e&J(*&)X([YL̴ox[=qA/ljVbRRjQB_cDɏE D | ,,L'qHlnfZ jUx[˸q ix[q⋼G%Kt | , ̬'y$x[xqBcBkdG'IB 8xYn&F6ɌL"VƓY%61z nbx۟*\M1zx۟9oɉrySSt LS   M ̬'|  ix;Sh%'ix;Swzs)u[)*x;Srs)# +},): Ff . F fVFVm>dukx;SwvAVrXx70^u x;Sf +},B" ^y F V&&VƖmnf>'LnӒOMQ06PMT0200VV&wx;Sא<%|.z“e?N~,5Yoo~YBJfQjrI~QzAbIrFjBf^I>DJjRfbsN~qjFUɂAK0(&)+YXMv(rZ P-"i[x{Q9ts+>ox{Qb<ɇY D \R K++#L3 x{QylB,ړ+ Y('(+X[XM+-9 S3i xkHy)m-wxkH2ٕ]u.~:uL:xkH8y)F㌓٥63űleaxrc]ejabberd (1.1.2-5 "/$JoW\ Backported security fix from SVNG y permissions h(h'dhYx;dk-}hXx$hMn_kx:dBBIX7mPFx;#z)}#K"#sC+#3+x6DZeit b|x;{8rM| LML 'plN`l k8x;{+btF nI F VFFV Ɠ8D6'ehA erx;$|"de} c<#sCK+#3+c3m"242 +x;7lClFf ^y F VV Ɠ8D6'ehq 7ix;9t Z%:  . Ff &VVFF Ɠ8D6'eh7(x;#dC)EYE \R L &pHlN`O bx;0xN|R'7h'()&+)ZZZX)hOٜc!(x;{/hȈ ZX \R  ̭ L&{sHnN`ar 6i;xk 2UiNxg+5iaxowtuhtx#` $xtg+&< '0M6И*b`\`d```haehieb8O@l7 U dMx5`3< 70i`N^nxtk fQE S   - -& HlḤ@ [&x4`3< '0FM *ld_`d`````e`jec:6Ycxs ̓ 9$݊2u,S   -Lͭ ' HlḤ9 x*hB)Z ZZZnנ lcxcC'L)yx9cCd[!Lf'0fNM.-,THˬPTpͮǥ87&8>lrKxqm:\Z؄S  ͬ 'dzHlc7{ x,Za&HMϥ%R`dZ`d````iel:?f;+ }BiOxqUicx~s:jy.wxqnr:d}n:ײ|KcrBpjxͪloem=xqq<% $UxqD=QƠKS&Ҟ/&lZ`d```dde`neb9e<{ixnwj,'/fb7262,* c4. 4xirU ڛYJOSxiB65+1))(EAPu4B\}\]]&+r OK(5Qpr=fSiLxfqbBCZy:  ^9 Ff FFVVFX%6~jP 8x;m|v-P WW`Wn^[x;mlv-P WW`W1N~ĢmdU`d``6f_|[nx;mbB,:o32x;mbG,Zy: F& ^9 Ff@b -< ix{ka9C4"x{kl25,R?3&Z[M~*E Nx{k6lC ɟX ,'g\G yx{ktC#[jN%ɟe݊2u Js  M ̬  L6'2H?x{ktFԜɊ""F ^9 Ff VFV&&Jl.e!h`W|x{kj:zbJ"Z X*x()YN^.M!4x{kxJ"ZX؄MJs  L &?d\CK4 iox{k6Oo?8+ix{k`5Ax{kvpr*Sd%-I<C#<#3#C+Sc+SY%6{3+IZ5 $Sx{ki ZaƓX&1GOVѐ .Q00Q*S0200S022420W60$9O2i'x{k֢%k( i;x{kRc3 {pix۱ 'o\Wx۱f 7kO> )P`d```dhelbe`8y"LN& 8x;u3!ɇŴ'70 r[YM^&y=d؄ mx[r RSOO+ 6x[< RS6gg߬ûu9a{rZ Okdx[bq' Hk{x[iBX&Nkx[$w:!!8(x[i$wN.֐t+Q00Sp,MW0204P042522|_b6/Kkfx[iҼ"k|x[U BYM!]Bkx[SE!H(xeJP(Bqp&MV:Fir+3}gM$Eq:9w+ y#F#Gs\tsހ.(Vު,/`.r)&Pg9zr82S#l"g'[m EF-~$caw"1Y?Kn ~n bFyrf˫lX;)uޔ^ ?1O2-uS ql_6Wj*; 'G_͵h CxMJ1aƕ+BXKgHRMR3oLI,¹/#,wuQ9}D6Ke&BS^ 2DcN{ZX,S)ж*UBTLDAkt W"o͆m߰ mTGt0l;NjޚR9w(9Wsu'G;Oz=NxvqmFԬĤԢ #==Ɂb8slt(l m6xi 62/Oxif &oa'ö;c n= Rmqx& 7oe\912x3zB7xRN@W Kz(@bQӢC씮[E .- xdv޼y3o-/ HhƴgdIx4rH<dQ{*SV+0*&u$;S/ _u:?'%M]m1u* K+0 JkP.q'Xp$(>/^jj ʇGMB ix;< i~{]4~s;8,ƽ˙̹xEj6Vi"%d'atr3|ʅ ]_:5j5-=LOQ2elN>⸛|[]WlƠgOYi^j=85u)xE̥w9\-Ϣ%;v'H,wXⴭrLrv\1> ~I#3Z]7sFk`ПU:ɷ~ԡ9}b<1{YU.?xHb;=qby(4Qc=|>4ŋ|rX*?JVLL6FpRs ?on@Iev|H7ɹk0 W.2t ҁi6䙳"n̦OB,#z4.EǔY>9SU (t Bh2|#Ǝ8;}J:H4FL!{KH+)Yz8ɒ89zJä!C3qAgϞw&- c&$x}3Rrc&"&exɇ׉vy+@p9`:M>ֻ u-jBci #asTCʿ6]_\E甗uT7!v xǽ{cf=㺉5&00Ldtw,RH@R/%5)31O/(OILM+/NMJLJJ-Jr%:Y)d`b_`׌LS633m9 x=7˩43'E% 5/J!9%XAV@DXPPSG!%5)#5 ,e )j+Q(H,I(-́i23Ic9^d>F3=X36odcs?&8|l)x={ !@xǽ{%&Լb+T LΞ|In<&= Zx[ǽ{~EX&%($&9Eũ%9p2 ;[C+CQ̖zFs8K 'fq!\y&Lr2KRRRtsSt3RStKRtsR 6 0c49l|x[={~: &%($&nUȸ9ɞZYx[ͽ{7#dF͙N,9yx[ͽ{Ēs'00ndtbsnFx[ͽ{C#LF'#>x[k% Ԣļtݔ2 ;[C+C܌,@L62el{x[k#ͼs#x[kC*# *ͼsNk!xkC*# Fq5D$x=s^~Dž,@&{fvlGx={wF?f @x̽{ĢԒ⍏7bs jn9x=s^~X+;1jxk5!qcW"nxuksfcoX/<)xʽ{cf=㺉[M&g2l y &%x[ǽ{Z70:>yAx[=vbDG^7cj]x[ǽ{ӍNJrx[ǽ{ӉZ70:? }l(x[={ Pp?x[k Y92:]x[k &s8wzx[ȽqscWL6x[}kB# 7bWdZ7x[=7˩43'E% 5/J!9%XAV@DXPPSG!%5)#5 ,e )j+Q(H,I(-́i23Ic9uF F͙_1fF& ,x[={BN}pjQzj{~N~YbMq:吒_nTZRlTag`ggdkgԐSZ2($$gd4A!15ԜZAP/I(^Z\R3trLFk!b<+<'bťXRZZyKFjGmJx~5a͆Ma+ccx~5aHJjRFjNAjCJ3oNcTa"q _jNx{uk¶禰8xk‚&ܬ˘IRVx}kC#JF[ֈ`}620mxk‚6-x={C#JF)P6xG 4.2.0X4-44` 7.2 XS-X-LQ..adduser . z<l6x;͵kC Ymx;εsBĉIũ 5 E9y nFfAĿU}'f4,d fl(x;ukFӍ'X"%?x;εkFӉ'3sMf\8kJcx;5!q FƓUlg`]*/jx;5kBƉXT`x;usBĉQz: E9yIũ 50Ҽ\\m^~`qQ2\p*$WpIb^JbQJnXjQqf~CqXR rI-HK)EsL^!dL6a_\SYY WWjDx͹sڍ;X*jYx9sµߎ2>ox͹sډ;2Nd ټQgx͹sډ;$%glŨ YA2x͹sډ;KY K3sJ&0*1Nd ټQ@ _x9aEɓY= '2l^(  x[9aâlEy%1%o jCx[9aϙlQxkZϹqd\fhxkZ͹qdFg/FLxys4V#=Mq=yۘ` >xmAo@+F+;E@P+Z)7ޱfqͯg(@zͷ}Z=c cw?0t=rvTzXIy\m)DUhjcZ m*%lk|Fu*l{e!f4~ Ke]vP*Yv>ڞu1ߨLN v>W5ȍf}yP55Kk zԎ;REfҼ"U?AoHf@ g6cչ8MwOS J# SikAq3d*%#N8JcUm!ww7%#1mw+`AZ̜BsݎvJJw@uOv2Ai2OLtJղm~ђ-㨿 QZ羄T =<][x{&YPPXĘD#W?r*|5HKxB(w5)*)r~`]:kj' afD#* czkϟV^'o$;u8|yut6>Z,IΥQ@Udr7,=C%C7Ybu"P rN 'J #j5h6aCٖ8-$چNS'kX{ma)':JOoFEI$RPȣ!pl[5vqQ 2m䮢U0]߃ 6dt>=Yr LjdHpP/Z梁0NO2?@ ^!5P#4|? Aԓ3;&-.*%ۤ܀|@2Qÿ"2a)P ;/de@XxSmH,;S nSK"+%_5w&aXٙ޵|{) 90U'* =j-k ./ U%ޭ5'q!ZEqcd).@o7`)Dz,Kar?e5"sP`D"%mj`P,nQ [ ryk#Pk l! rb䲅e!!<Dvib%m^U[0-~_(`aIְ99yu7׽Npxn:;̐}U8?b_TgVz`o>ҋezU^>.xyz-3X!7>@ ƻl{y4N -V (@P@ ~ D0uKI),-4J?AAiC,TyXbP ꝱZtG-灝Ұm#Y=9X_N ö:,Mt-Qr jlpx+Zvgͩ?X)]x+TvW&Ғ|.e.`[{37 ͩ?X z,x{*Xv@IQi*2r-َq9/ Sx{*YYqvzĢ̼tԬĤԢ=.eTԢ cM"T̼|TJjZbiNB~AIf~^BbNQjbJBAbqqjBbQPn^~qFjNnJjIbrFj 2rjEA~QkO@?_nF* J\\}]&Od.b1402UBIcD|PH-H?3вR1sxXx{}.|TT<C#bR̜}#BS+ J\| 6/f<$/ox~yŒd',(=ٔN. D5'-'85 -5ր R?x;|KY1%%$3?o#!F?x+K,LOJLJJ-J* #H :xuN1{H{+BD&|Klw9. TR|}0fk"K"/ rdV>щΰ >WdX 䎩ޙ~(UOB y._5!a=igkvJ(i$6f%q ?6/G:9-(^vH]9ULT7o.7rvaCx4a!cAA_jmL \Rg!xb`i2xbjfp$IܰxKO(J3 ҡ.. xYmoFba)'Ms=(زlL>+r)mCrU.iEw~.)RVRZ3 MfJr;y]|s|=|{PerTs'D oNǢq_RԸ2֩TGuZw~N3NXDE]U)dJWwO GOL؄MH?UhVX/N<ڿJK pe0N">3!ԻF[WB|?kI[ޖxqO@@ixё-Y7ʮl@Z KL¥~MɏQ]-,פ&OesnkJW2aq]?#aO&bl: 6U*j  jKIRðwӛ˧峩lYhgUA樵ơܮ~ǣB*!GٞTj MYEp{r݇( sCQ=RS}IͮWs_RU+*tbP2B5s٨W45-Y `!W 8>8ȸm&i<\T|H )Zuŧ(.+-3D [r| $c =,!T7]BfsDNjtyT"AG12`! Y"(K*f_S4L.Tf$zϷD" ʚ*eIĿRı9v*[x|? 5RBx,lid$e'iۙʣefW/VUP)S0#'4"jrA6eYfdv& p<ķز!4~׬fx1=le% P= tN{Y5QKHɏ +ɑ &p&|7ose`г "gx&TPS6ܗWj2.)uw{6qܣپ2ESx^P:kH|1E:۷_w(mאf+am%BK?{ hGVs7Dϼ #-U@G*~&=^0@zPشaWTdL|R7p*1̮%O)0 hhv%BCBy*r( A컉Y9,w美Ix<}:Q L.tASʆ EăPU5LLw9%&Q?>--Pw {(fM@pCq/% VdlQ:eY4UAg\h}Dض\upz)A)S1+0 cJNDTơ} /]? ' SM^W]Oo;_,%C述TZ?K"#D*CmKy(˱B2eA-Q))dT!J˃(% ַ_@{ۊ.{ cM@s,A&(C)22z훀L%}fځX^QKmk"ŸţP"N@YLBVVtɩ1 ѹcPAxofG.&.:0W;,dRP!hRcôD׏%NK?X]Z N@H$h!NlEcOHb3(!A>Q'3@[.7q<'4i>ԼmXX7sGRQ |Ȏjd4ZVQ(ʏGqTj$l9o6+75uMS N5zI-ds>p{נl5++JՒ=[TH8w e⻤[*^z}Kg(O U2o,`o6C-}OsIeH#S]#kPvAH. O_ =ۍb&[jמ DI3ǣ{7R d"'&ѥӇ}!'RP 9.JouA.Y"}m)=1a SDE 1([r:lxg^G/C!5+1))(EBAB4/UBIA),83?OH@p9y^ -x}Q=SAe QDm6pyو۸#Ƨq" ݷ;LD.QVV-B"󣱰9p̜{Ώ/X3]Il癐 nlЂ0śCaD:R(YN޲{CjwJk z`ǣ6e03&NZG[P-m'hN8i,tB#濒ݿ47t8# Ny}nKZ1ԁ1B$l j( )w.N@5F }aH(?̽(0 P1 3tRܭ 󏕔чtk6XBiT:فHÅ (~f 6VqR!Htu5#ZZOK^{}cԧ,n+:?_imxοJAq+Xi(B?a# $;,ށ`!ւ􂝥ll}]?zy!y1K aUN!Ml(l2*v92U|C!XcMPW:]OG< g@RP.[_Mn盲rYIܗggrDwpIVfpxe~2.Ԣļɫ@Wm Ux[@B"dVFݍ/qx[?KP/C!5+1))(EBA\!8$5(`d``ZT`gg4e2+Ɖ7k2}cM/.KMU-NljLj&̶%$7ghS%yx߭VTT&(ߡ"-173R/(ݎk"Q FɧDmbҜRRRb653lBx?Uf]\&&`x_⡐Z`ddXP`d``ZT` 33)LfєpP(HJL.)MQOIUKMU|B ԈIL/.tb&>Ÿ&IaT, ZX.x[uUEW/C!5+1))(EBAX4DTIA),83?O@Rb) 'M|Kr*''2O4qs!>>;nx<Wg#1:<:gpx50!PO[I,BQJآKh!@4WhpS^ʝX!qkIx&YҸdoe7T9!]0A8-SLqTP,P2IT V"b`h*d.T$4pAAZu}rG@HZa2FLUXSP้8ӍYnb A `J]7, XƟ<;K/x)+?K$&$=. 5/H}x#$ X M4!Xנ>.mGe >?jp"1rtNn)Ljb2p lQV,G4_t˩Ղz0+ )!kdڛ''uƦ&;SS6 !h,;CIl>a揞&PBw\A^=Ϧ^7&gڿBD' ˤ3=9]mWц.Aާ =4FHʦDz?}>K 8>*eaPxW0nH:Ύ$Xͫp4Ua6墚l@?|V^&"|Lϊ@1dTu@"wxj)5)ѩ`߃Q4Q]k0b@Q^ȁ*E@.42Z4GG EI&dx"B=`y#|1tV=S9CȢBQP_Hie(Kzx;7&8쫋R̹Ls-6)^q)IU+0G.*!jXQl7)A, γ;8`G٘q UQN*ւJrPWf5RiǓvm#вH^GIX |>+6PP (QS]7qΉ T{Pq]K)P<*k.xROK \pͺ/|~=TqmӨ#/%`HD\×h-:[99? OmK/O dg=0%<;GE\.1- \ -|j+^/PLj{-nn b zw4{mC..BPJ%!a. 2#!lORc`[Eo"KLJ :Mdl0Íc 48EUH?- d@{^}?ɫP89&,Q53h?wrc & O"0v:!TcΚwOv=@s^:w oڗOݮ=>T#Vkk|L3{.OV/fɍpZtq1:+@p\h)XQ\d(bi¶,PX,ޥXYoX2u6zcNc_Ǔĭ?rڱ#Ҙrb[uv~u׹i(\ǔFFtP#@)]d 3,Ac& [0 NЂ p_!0WʊnjT^Y ,Z;9U8!:ttX>NRcUԛvO?uy4<<=[. iklyy`.x旌i8zҝFJ/w*3%^nw7wSo1e+e+Zkh+ثBZ̡`<c"sj"2t!lm}ӿhw-1 =28W=Wt™tGgapSX3B^q| ahxҤOҲ {\UuFrPv<_Ǧgf Pp=Ħ=M8?{޻wJI׺4!m6N-~&br08)n̺>%Z %Q抃>z6akGҒR,I wkC;nBσH]]PBMJo¼%*jdd8yޥR?ͺߖm&>*ZZ%3٨j&`Uv*Q-w\`>sq/PL:XϮEymG{ DFUmB l\k3w)#p|ZTj<W'q{۵̶Kʺ[]@㲡U4,Blt0:apX#mik56jq!/q_QIktlW+L`a{gqdJ}di$==ߎbNY[ gSpInJ ۴Z8ܽ >"; ۘBk)RMsc\a?Z"0Dm{e];< }*[0ާGz~>vY[뛜Pd|7VJDz9!^. ;,6|vMx(n1gb dco^@zc@AZ0@:D*?Á)Ln#bcq >yyw++̔%12˿X$\ wolw~Kp'<O}oww޽şo{-je3Q)r~ AdNHGEo|@As^W : 52x߄eV RRU 1 . (but internal mod_muc is better :)) %%{5554,18 7 {&q./;4P5c68ctl9h[;<ѓ==A 1178 2008-02-08 18:28:36Z badlopB[CvQ,xx;kCB12웯42mb b>e3'dCރz I% y%Ey9 ) I%@A+MM.UjSSSZ77n:2̓-77+,a\V^s/~<}՟]X]}"_D/-5O>??Y]i@cXda4/_U8_`tEk't>z'MHU~$4ǵɸ% bQ~:s6~qhQS)$Q !D !R4Z= PYeY AXHܲ TY2&Ȍ^642)N$B_$4Fmk[ʬhnqňIO額S(@" Xmbj,aL{D:бQnJZ:~1MasNmbcZap$3pwApC.w.7Ld (ekKU`9k5#%QNEYЦ4&*S*!AE"&Cަ<-4 ==v+"0Y|G yҌz[x S{9O8MShPk.PiT&. b)b$7aUI$#D.0sSUdT | eߤܠwn>yB2_w[ǭW+ ?w]5Ez-d#gf,5p̨ mr‰t"AR8g!8-_ȅvG|գMחVV>kUhfqY]dFc #З2b:c]@~&(?y.c_|nx&'ʴyeEJ(J8G0e /C-A, lا>/_5xET"YIMm$I8߮jyrg8̓,r*CQR={+u&m";pgK%dsCt-$*) IaIc60: WԄ7|;*|QCtxn -BٰƯY߯]PORH02 ހt9, =(x798Nw)<4<U=̐v$R>OLgfI8*O1(,בx fdޓۋɧ~tvat#ڬko ]L ļ94ܠj@4!^ٗTvBD26P+<1IIX֑J[3X߿wxopѡEtUo<  [[ɶHqsV@V܍E&*mRV@Y"]ZSHMйy89TUJ2R'/,hlF Fxۘ*eC Rѓۥ&J8($&d)%U`J$X!751XA P$_ DL!1/KUU8U!' z@꜔ĂxZ=.li7qש4JxWoYW[Kg7iI6v'vMvk(mEuvRRs=smO;3w:w&iFFHHT ≕ x!_+ HH̹wfb{+!9| f J[$v#ti6ihV[3~>L3 CǦ b\P}0 Z98|i!:d=bY"@նu|S`ZM\m;~H+!X3`q]hRRЊ]wBv8PAFdžU4Q.9[PYQ&ѧ#PcqS0B>CBOK֤3L">1Ŀ׹;' 5`GlIJ(/M1& osҙć~BMuq߆&w*Zwh#15wڬ_}IP҄~Sc"]sNR)wm]eĢ27hS5KPv@윖cYH`Κ^G\ |=6ķ'uM8qixc޽G;$P!P> uquxNQHZQ$+%.]GIbw s|]cbMfCd1GiӨl,[aT(#"~Zz$j_~p'nZ.sO.),m !8UJ8a-ӆIRrz;]&A#"O?Vʪd$Bt|LrJ?S3>3UIRG|0ηYQ#p;%KR0[MVQGX0N޾[W9I%h gM !ًϝs93A|?kH C9y".!_o$ߎbj =_TZ0Ss2-y<~˵+id?& TtX[Il&Ba%o\G6db}p.{^Jj/.۱]қtK^R>> X `JWCI3˫˩ L* tVWWͽ԰V <H5Gx2r+kkבc%/ʼnoo"eꓦ^k# ]|b'cv€Y{#yG+#_?htdJr\# לx8ZJe~>:)e~;JǖĭS7`#$>YںWyg4Q9C|4J7ƎfRK^eKᛕ _FxzK}xocv+Xs#XbZpf ZH}zW|\Ԟ<ȈҔ:zk OeɍݐMئ͆ҺfҗxFF$8&rEƉ*euUJ8 ŀzc2ZV!=hGZ`2/ Xjn b_NR{RZ#o3@Ta*{!1;XEL3l$Y[BA4zWi@}ۡ:;xۈ9uw@k2akA1?OrqH'</}p m[,.. Ifq|%8paG$B6AXdo*RMVD_ =GVrKV/p="!e4QLMQ%tk'6nX!E/^"*1,0_ `ō;1q0YL#~C9RF/ZFű͛p+{W2lSeXOvqJqru|YQA ߲&6j[UɖI ̭XsIK6dEZuU8./dhkE#i=d$`WWnCLb28u du)Zte>T+d[l*swHK݁g*(.c^A~ _vp]tb[!S~zOD^:3QX~C1oTߥ: c{ [[[]:ekÁw9KBDtjOLꡘN=Wਫ਼O#!QX" ԦPcۓ+oljS=6+>LfkD,z{1qV DFg?v7JjCcɆJ̹f:@S8!R δ`CF޻F]Ůɽk-b[s֍2g?&e1uJf?s\EE> HCMt/Vz]&C8!һ={r%M(k'%&!v_ǻ6A7{^!Ndy_|>:33 Ú k$~92?]hv#oLi|'%H9 *VraW$lex{csfC|L(|x{c3z!d#,XnΗz Kn&xc}jF]2%d[.j>xcb@vl Rxc}jDyLmD oxcg>ANK5,(3%5>19XkrɌLblEyt7a=ٞ_be9ɩE%œoB6<&f%&%L/2y6H%w0O(5x#:709$&d  2x54h1Ԣ̼ԍ?L˷ǽ t[x52wM^L|ݼ;ux3{s6#|ׁXf Yb'?UBqR2;$'O|]Rx}osFSx9ϳxs-9ƶ|((Y~ @RU=U*3==9L\M&O~oOmEW'O\UiسOZ"-WiaKg;2qVe[Wճtl5 ۿNOmWKo܌醹z{{e9ep?Yڹ]Qov^5-4Ui 3cl 槟.g2ӋƴyCjB:ꥭl;w26-\_bϥ"/Ӷpg*//@,dU?#REUHŊ08KYSjjMW0u|:2gEagi^MwtvyIʩ qO4f؆K%|,w ٣H enkl,]IAlGݙl,YEU˄N[LK/eb-x{v∬8ŗ`+z 4ͼ[ Ϊ;PqZ4'^ zs;Wihz7~}f1yђ0{x '6ޔ#,*КoN?Qw˝+Έt!12{xD n9Bh9s)], "q77v@Ka> Ք ʜMM[X /x%;c #>bˆ&t"v^Uxutߟa]yZ I fߵLҾkd1WT@!Z,X 5֎dY΂ Ni$U)XX,Z.'gڗ=+wZOR/k!v"kv51ɂ$ #"Ӵ8q_@.#٣2a^*FZYBG_9*STvY@rSGz8 zw;OvO&ak݆#r,`#Y-I̚e49 ˈV`L B@d,&"T3AE%7NS0MI[bUwP*00m󅠇OQbg#0'iHj'6t4X5Euph k}CB"1;Mz74V Œ8JPF+-:Dܥv̹MނQUvWp:|:ʆ$ͤ`*US,S>P.oi/\UBJ#s@WUMd*b%TyzS fςE4 0u>qM좪#iWMig4wGC7Ӓ1~_d舳hJ lr%#ݸjn GlwΫdF YҐ 5Ld*kV~6#" B#Cm+~r5~F'!:3B%[eFvC^W']֊J#Za+2{.tGF["V1\eCm0Nd-"oF=\M> rZ}NJ/Q 5όYCoX SCQR("F{Ry +yL$Uc?GgJ;-#ql#wi{xu;D0o?2lN NHtC3byQ8$@|% I'Q ūZ-7z3IܯaIBbh'vd&:]Q2RVsa1&ii:6`z:m>$8:eKRX=H'мPh8iB/Ӗx܁P= mF nq)b[ c@nפb R91xZ @^}q޶ˏEV| ӆ(D 0.D;HU| 0g 5s&)96QuZAt;ugyM"h7iq#?u|lPxHt$U 1L}Q{p4U.f0R]ވdYGI1,G&h,P}oOuKDxﭖSSeC>8Od4/䲇QMx t%8kًVb.;_@Bɋ>مOǿ'HhK*:Ir:u+x_jC?- 6]?;ol):B<Vpo9MrU?YT|G6`Z"j||~kݕ#9~Vvt,5R?h]Zr>Ωn`Lx?f9TK02%c1qӔ!3h~b ??ˠt]. `5)f׬&g;t~h{"x\@D|TXQ_!n)~ G0 hDZ ȎŇ. 2)қµsL1Zea8#OZ7Zձ;F#>&nt|RoќFLHbG`t&:v>0#9(&ƭdy"GFT!wS/t̐ITsqAit4:Y2NV/=slNi1[9>dmܙe*=la hגUoǁFh٥97d,LK D{0nn},4$鳆 >>Ep4G#||=ԉ\b ƻQj PEjdv^쐲}DXSXoJ݄bx" FX_3k%CqQ, xqX,ޅ@!𻡯\ݸBY5ɚ+ZR2=K)\pn~8=98~=<8'v燣ӽ'Ϟ]E^x_+R>3ץܧŒ]")ylDFG3ϗK a_( V`)N,PնI:L}RlȐ MNe;'~DʢdAIa7'k:y}K)u$ؓ O&v{abZxzj9|P՞uYfBMOa> jL͸Yq93둱?k1_FO^\Jh6 KdXW2t!%l?*@u2.cG=%AE&b1ډImq«̉UFc pbsK/>)xRg(k"V!%Og./B5<>2ill( >ۑA@LF2bˊdM¶wKJ|3Xͮ/0RV dB:e7W .ӧYI@ s7/&NT,/ȭʶW6UZnӇ%TX^ĻU3Tֹx{ Z @Ur1J.rjAʕNt<'R44;=ݍ \-]FľPTszF#(;`5yIA`~{m@&E !kf4B.!6Jg]җWGFwePv@ iod"x*jZk:#媨&ԟyI\ȩ]+?}hqU@zQ7!ypS+r2B\UzQ>}/]`?~@az5n Ϫl2J[b 6 sK=3,ӊRpCiGs -bW# ' !`<臕pq\T .3) :y7t3V ͞`l>ڸKoNDӒaGkș]ahvY![=4{gS\xsY"<܈] h\54ݶ滋S 4<Lۡ\+6` #S^(W$)*{B HxO@i+œf_qDboz^X*<@h1R2;PR>H wR /avtw5̂7a[,ۻ"ދn"l|pkB]^k}TacKɛtx{G%F;8~k?y8(["B]Mvpn~Ot1۱šOnyɏ"xLP.\9GNl_y9wF*ZRcfᗫ ogu7$c,W Dd=݇YXOtzS a@(!}AIxjf|D& VpA!|:!,<==@zv}]SZ[f:ۣ; #PA̡cv)gAYni=iO@]W7a*;2a9Oh#Ha$hti#s ۵A00 nE+섭N 5!||73wiJÉ$7{?n^)h|ԟ *)M޽4>SV.eߏ_8[ Ň^W{a^J޼ӳ''XaQZZs.6yJ ռU?1&̾J還奱 ӄ߼}]uk*}b_+h X4,c LvY,RbZ|Iձz(ie(_@ǹ8 )Vzxl悯 `*!dz:a}At9>#Tٖ}F6} xF_ W& m75}Fox{ l ;I_ߤyvBCEXe.D_ g3H=Mֵ:|s:uE$!a6aEQ6NT 0Ht92L[+}H*)E-XT{AIU]/a 5 ZD[pW 1$?nf۬$* XS똳&#ǸOT6\)q]Jiːv&Һ3E(ɩ?$:;SLuaPMܝz?FRIf>b:Ezy PDOV|q="׆3b+jʱWl;~qjL>ZUbIGwӼ(768x'rFzu8AѢTWO-3& )"Nf2vAjsCJY|BWl&_._OyB_4;Cc=Ip|]ُ[Z,~}VF2å*߷'OvpkGh*1686D[dG e% P;MNlƒvmyh{f(kC/:x o:47o3͆}A%oaE9\&3l]M/ʅ4sc;krīV[E^ӠJv}bJr4zeĴ@ ;.:R* dz%jDK W`'$}gdt_鱡 dze¥8#G7)7kVT˄U3Ԋ`f_&?#T]t ~&$% _F? V5;C ׆o0 ldAjCf,b8}%ʹWoU98ӡ׫ g`v|D'zg3Wᆔys=+nUcwN?4O_/ Bߢ3<[v Uk>D X4[r`d~mxmge Ŵi5SM,_mWa?vGT؍+ww)*u(5x!HCJz04 M4q݄ҦǮwCHҟQ1a*V9Hǂea9g&S󻓴NG~6[Z׫qۏ;~x7G۫%y?MVp^,Vp%(!CcȦኻQ׈T1q rWu%VH%KNÁCS "6RgnahWKR!*vj9i I$3hTx~-S> {3=\2F .{M[ "u``w}BݸPL^%o jlGGސ53?:lwpe9"cOD\IUij`HNܧk(}hS5Depk(?šQ ϱLߝ{4 ҢcŒҥ:q玘)VEuC#hK"ɸ^}óot#,&;3 }4 Ńs8h>c}r n@o惞EXՂWuc_Ȍ!`8pĕ̩x}~Kd"C:ceLUF<--B!0[ {m>u%Jx_!\^Oj9{^[H7&XY2#:H3=rQFԌXMa7m=}KÛre xqc ]Ck7 %[5-x# &_S,.e5qѰ[R m)xUj`xe"l3GKinfo%$.Ɠ!/R/] R:X:>*j"y x# TY27T es fxv@FJCH x&UQ.QwSj\iuserP\R9eUxVMlE҆?П9Mz[!iMib%J۴^1;k` D(B#BPD/8RN'-P! xov8V\vw޼{o>ȧ"gQ.1,Ww/on]Dȋ߅_3i,n"-6 Ykk=/2` e|ڲ\ah֨j}>#w\^?J߷'!뺼r`$gAy[%*,kxfM?4|fp27/VK*!=scf&fs<;W%~S ^gyZtF=?do#g叇4ib ]58rO, \<g0jGy zUlO0VɄ01|:!.c)r5AE[=uo4}kIyq |ƿo?l7fW&bSC^;'&#16ˊ"I)#VL|٣s-<ƣ+[ߕ'n[RE^)2js8l<`N&ebp{ȩ5m 쇋cnכ{6oɑK<1B]^,,46!w.6%i $7qx>Դ]eסP>0p o?o٘is R %A|1dછ%,XIneM'@-}bZJ7 FxP``S"h?,%m4VEx`Cl`EI"dlB(I\\$yKp1mԲ!$Ca$WL #Hp^fTD`IįwRRŢO3HrPg0P]z_4*C +6oRXχYd6`#ŰA "ZALrv׌+]%Mws] q9osv؝/L GuUGKJ(/ؠR_s ~8J!lBtcH͔rؤ b%Eq$@tVah6Ŵv#{wvl"ӊ]SCd07 B+%(k-DqKt&v剎Z* M_lrgc91* y[iAȠ0$m'l; czƵKI4xx(wꛗi(nv~:x/8͏b5y)nbx82ㆳ/5nHx}> <;3`x}> <;1O $ Ea͹\AE%śk4Zn;x. |1wSxv ^ l.PyoXXN4xVoE!)C8%UWMKԨ%)R%6]{z&ٵkP8 qq'N+*q?C Ně8$*.~{oGstQ422M*\GO/ulWJ\ Pq \v |7:iXJ;%k![X2$(Q؇/bw)S,pڄkb,BdcIK^Kr]lcOX2}9ޥ0.PS}odD?5(jS{a4Y5#WWɐ 8Fx]|۝pkXA.et|^z_ oETItRH~KpOvr9*܆f`jbcPvϯqb\QwRm )8*0nO徶8u{?5aDKn\v&^љPvU/(]ߩau9ֿzu%Mq#$bZY* YVx{J#(f>MTLhtfptGK"_蘓K\&IFxD@WC!hXtLe44ڪ=`@!0{OeAo\`mSة8-`ځ4Nթ5wҬ9hhnDu\Oۛʖ#cKz^;DAcXl뾟ӳ`=F3>p0))-)Nd!-! ۸nJk1zl4Q] v:-\zkwG\.zпz{C74R`D}9\+MYSAJlͷDZhG}%%ꛭx*#ϭJ6AP0l뷏VvK{>Qo:W5L<9!v4cѬs /]Yx]TMlER4JF.%7(U1i!gA;:N.aJ'*T"q A/EBBJ.! 8iͼ}h;;6:' BzJ_Ht596m62&MKFx@zܶEMAd@@ QtMÁxÇi@ ï\&R^B#t jMn` k԰uMFlAznv " =P{~KĤ.ik iH ^j1b"K rSSQ]m W5}Dغ'H#u#茶GCzoSFԮè ;n;#b 5d`l:R;7mi53G1KmQS%dcD/IBMII$A*-#m[4pR8>ϳ9 E3WkN(6/>aQڴ)~t6}(ܨ=>J ?fNDN?@s/K8mh>> lܿMggrF d.F"f:YPDeDlR<3CP\DKTJUBBWB9_Z$Bе %uw9vDGN-P%/33 j7s-ٗuV[FjffDt3<S￴ Pʰzx^U/0/Q#%VUQO&SZka]"%sAиm􅻱0}j\ݸ8~B:yni@{_=_:W_; XRdD֪l=)If;Q9 `eFBWcCIzZp/hi #\]J6vB xMSMlG#) U!l#?TzO莆Gۛ?f9oQ?Oȹ̍#l3yyyU(#t9cCDGb׏ 8a넁&!xa?)~- HPe$}&8傃,DaG07;X3 pКLcӈ#8|B33|RX 1ls%3ۖd&SDrk_~9 vj׌8 \G1 `⦕]sD@6(T'bDKL'XXY2>+@wmU;M.*HgۭenHMI,0 %TQ*_* 9_63se^^X)|nXnut wq*o1eBQ|-OkZh؞B&'NS+Fq>mZFer|o_v%hm֗엿õ!mNߗro^ڄ.ԀmFUJAV:I4G3 r} 'hj_I޶TQofcυo 75҉.y36>}p>k 5Th;mCOTZ>ucy:N%ONO:%pZJY͠eJLxRN0U& b@ 82ӮTjA"$'FlҩVl BjKi`;{~w߭7oD-348P<%)נ;yAR"׬LD+ zTwfi9|C,v:a [ $ɰ1ѣ<:@(#ìq$ѣH?րYX+W-Rohdb7V(.J r}Nt\:k c!^pF9~{s`(wwP`3]t })%) ;.j?Q{kuvvۧQ]c!xi~jѤޫ.p 8YIlx4qyU* xt/X/C!5+1))(%$GBAL%595(`d``ZT`ggQ*n;DB<rKct JSR+&Nqbz\(r2Rcts&.eTl*"Z\XRPY\ZRZ tJg)K Bd!a2ړom6ҔHI<Hx|+X_/C!5+1))(%$GBAB4/UBIA),83?OH@pjM x|sgF_4bҜRRRKrbs2\|]\R2rSJ2rRu323RSK2&y@rͺL6gdY-*K-ɮ1]o$I{<B2R+R&?VdL!w@'QR-ZEJx;T}&5oɿg9xq''-ɋU-name\fP and \fI#(-Ng -log ForceQ a  -expired N c-usersz G \ -licenses/GPL. /Wlx>CmC?fN*3xޤ6!qbBr~^IQ~Bf^IjQZbr9Y7sw M2xkR:AD\!8$57)HLIA),83?OPPh&ބⒼTN̞hBX xX2Jrs60eRlZx]ua'L*pxzE~cAQfRXjQqf~n48EQaf4τⒼT℘,8'_/*qHaTؼZ =, UxZ@/C!5+1))(%$GBAX4DTIA),83?O@RpIij!,ɓ3&1y*姤N>9E&$+$#U!&39?771/%&-@!91O!)U!1R!?/U!?M&-?''<3/]!hGe '(e&(dkM>_ƨ0M Qaj@&AftxiBQw(eriDkNVP>ƣsMVT[9Ipy*)fFxk8u+㆏|I ťEũEsEo px[qn '[M7SH,Q(N-*K-RI/.I P(,PH,.ILMQKMJh}Γ4@FH(b7yci1DD;@Ԁ,(WH//-I AlNћlhDåP\ (Q]Nj% yi y %طy[v= Nx۳z 3 u&4mƹԴ5-35'eZ3,'X Is wI R(H,QHJ,NU+UH,WHO-V,Q(JI,IU(I%O>jy'S J/M,HISX!1'G8X!?)/.),j\F2x" "NfT+-N-RIONqbԢjB0%=jת0MN4R/VP*.M*V㜑PZ:@MlI-,u3K2RKJRS2R3 3rRS' i"U49P; hFv0yrNIlVם4@AbIBniqBjEfqRXp}_Xb?',5ĹAPPX `hup_-NMUH,PHO-/Koi9'-nmxqg;ͺK.xMP?K@'HC,up*NbP$UwIҫM/p(.~?CG)={/d5'KBd$d#TEƇ9)7;F@?zaӨV=wώޕ;H4)"HT?\Zdu\md[ުhz?*8Uy$H*QF\zkocYƄӘ]~rk8/gb|Qn=NvqȩdAD0Nb쏷Sq!gJm*xxqcV4 ̒T̂[}g\bxE?K@iT5nTpv&o]n 798 4~7WA&8{~{߷!4fS̆$a2J WRZ:΁=r& HFJ K(X9x+^3SVlU.B!`q1fbZ+V31%e-^p &J[ ~3CBx[\}j(dYQ΀Ҥ aə9 9y\y) J)i9%J % y zz7&9+dN,hAЙVLF44k]1=F<-lJx[\t;wŏ-bx6{k .TP .BI reopen\-weblog 5/K ?%x+.JOJLJJ-JKNKKH-IZ\@5)IZzŅ9\۸xUmo6llMWYvtoHo˰zbE&v2;R%%R >sG y*"b]؏ ÕyeҨȝu]8r6%}~r+M#% o6$tOOZ{'JuMz&]c3JEψ:d{8lˌ0!!J*UTQ!D(~piX+|w~N-#1&ђT3*! k X_Sy[]O >ad$&AêlT@}/2;S[ 2*?pD_cṗb0p]OM^ahx䊄Œnv"Τ )Ѷ\ǑlcPW$uJc?]GSXPڮ%›ANvsuHs:XX"zC(-SL|l(=:~lTuP+N ΞѾףsF^Cnvpa_~x^O1 W55* 0tЅ3wkQtq3s/.R2gNxa, m_xalc͜Z<1E\ xEK0 D)r0 Ēp41U ?iQAܝV{3|hB7u,~ƒ'TCAJ9TU!Ԣ[4v!G\FTΛِ#gNBmhbDx;xQX,H?'?]?5+1))(E_kF 'x;xqB-oqFbQjJqrQfAIjOp xKIMLOJLJJ-JѳJAI. r'H #xmQn1+x7+%-BBJQ9Ԧ"z(m<$&z<޼| wY},ȓ'(gDhH`ddC=]!o7  :)baʊ"u!a0A\sO=*mhqLP~"̒ wP2C FoCW謤7 ]v+߃ ft1 ݤHݗݑ)δ&(Y=wVtO[~rJ;Ipj* ]/5zfw䧽~4\P^\r~&`)hv G4^lHE3?ˌ9n/$Ϣ$I2h#h-%qӳdo}7 t~ϣY{K-FQӁt${xzQ$Mֺ'fd}@2WtIhޒ:rɅ{ ,om ?Fשڐ ΢d,n|;xa|0#ʃQIk%+k8=.3wUѼx`0"j3~yDw##O::USuL߲;[˝vsÙ ĭu(N׍ :aY+L1 ||Dc) (/'~t,(|h~e o {?lKec:nU/d~uZ5[w|~mCGaS'OFCg_8φbT]/Ꮋ5xK0ǟ_qh֎[D,⃤͵kdCm ܏]>w\@e8թ8IJAl'\q@.DZV(\`Ҳ s¦`S,Y^dM!Jr,91V{x5'\EEqb6:FTgtGv6@"Tp/ĩFj6P 6X bQĈJIVZy5aNj~ FHΘLzW\f]@HcYmԬ?~?]<g@K?1|cx.tH-gi/Xe8͓"n[b66.*^stb"KoxCƘE6oId55mYXGOD@J6ҌA3[LqF3aKx}t^#ǓASo^<E‡1&<+TPR!8LU MX ?Sk6[5v0WɈpN@5Zo@]jǗA@qσޞ_?wNNv~ya`A.$ ǃ`}Y4^2˃7g %ΎOOի'jG잿9Q'oOו:ck3 àÀAue`/ Fv~w2hEe3\p(&K yjzFo,D= xt^y%w6ֵU;#|"G}zҮb(uwx8YQoEMt7`h(*2A&4w{2}olRBqᖶq9vN|/r84o<$vzǃ߅ɐHp =%]Dn d)(0AxS" }\Okז Bp GqP.Sapń \$`z_) i'\uP1Kx;7t@74nF_0tΐdx;DL8U(Ok4LFpRH1p ?$$w%@3Z HD9JR+)&UGKP L` ΨOE4vc*ub[ɴFBdU)(1?Wt+u)F,(wzu^ꮎN>:hpDF鬗{;`IV\[~vpf3f[7W{-:y8I19$m/H䢚m#j/He4L%H>i2_'y{{oIwvNN?-v٭[Tb0vuÝ7ACtQ]k_: JA3Sd/ƣ"`W)FyG߇]67XL777:7hGOKxLuׯ"іKY ԄUm 誃me=$$r4 U%O%k lLxAU:s\_"6 ~" \!.#-;S 2ghVG1UiXfb[B!q_B3q->*EiNKDՕ/p=w&{z&E3p*fRdP9J́s%DSu_1R1qB5N2/C.0|gA(Iwh7"9d;Ydq77WHgt\j|VtwP|-[``oi O♆!$Bެ*wNW4#M/ӟݯI)Ylf2HDUE׹&OE2me:\ TQ0di29b{Gm6ĥF:=`b)- eEf֙Q*@"K)L9X=5險ɝ9t93Ù9̞)E;(z;{ۥ^c Cq;..NoQt1v}rFC%Y!Vs>A]%Ň#O7(E<*+rό˦ O'OTݨVs/{(.7lǫ9o$[v.pYLЯTZ+Y$Tn 0A qOoUx SgгBx4ְ BC6,.KvqDqET9U B~Q"{mӰbĹŮtR >eZjX#7\Ȟ4Siq]+?FxXcnq\KFa>VLzcjtRNmxa>[scQ"zP)7ǎ/i>s8ŦLHUNE\FE]ı/_ǃh EP85ATq]Y5JG-uaXS S / EGCp*^P½C_-uHԢ`\L0H h1&T5?Sh5 sjgp,s/O!ic(du h|DmG[W$HЈ pwAK-ۣ3iN)HU=7H8y&_ȄI]CW{SJ;.["J 1X$O ʫȂզZEnZ-Ut/,Y:34fvLA 61C(AS7(#rD.YFdC~/43z7uۚ&_ h0F~2Oe5*ua+f(rljly¡E=n=~*>^DHW<_LG R (Braݩ9w2ɞg̢n̗-j.)jb <1rTv=Š 3]rUPR ;,zQ[u/# }9h-4Ӗdp;\}yq]&  0c8&נn@qiWŶyO]%,!pL:hUz[67[:?mmwszb~6ƅ9'<;ےX)CسCgavi]-tm~99t2hLǙEylq( s!&ڸכ4CGa#ᔊMpO޸D#b^>{Cڡޗ2AQ&*^p5;QǠHwԻdbo'Q[GQw!5aSv3 p xX4ݻڂ_Fs*wf&6D@2s2CK[TZs%.ì6pYK+DpXVJEJu,% #GvTPRxolv76oܽo]dAHN=4 _ACf',?te8hE~AX/e%:JxxQ|h%X]&ݗ2 10l=FE=)y# _Ei{i6vשdHmBd%8HHWY9 L\ƽf8OE9`?rӮo=! kAw줞%q=Dxq8mgk<.TtXC~wF8J)H;c{йߡk,}'o,J>u>-X^f<ݕ}NvcHKaDm^:4Lc8Ǖ=Sg?,ðX 5aGŵ HS;T@؀'NH"DC܂\Չ&RGjm}MK!=!бhj ƣαt yN'bxbIĿi3K^GE ([U@oTABEm+ 3+Y|K9.kʜCg27/g4ۆMƓ'cQ4VxTexč!q]Ul^=_Ձ^wXTi*u yG}%-MlݯبFdn,|w0Hy]~uf90ǒ/rCkV` VlHB3Q(x^E܃Jt~!2 c Sx1sSam]ȤmۺSL͒)+ ė )f,9Cq#LL5#˥y }L(b 3_K?ӸF?}R?E2[3{H[a; Xś? D c%! p!ՇCR:C$Im- -~_]0[pwetĵA[tustvshK@=+@.w~lVڌ'jC]nz)%`fuyZj=2jӢŽ^R&|ѓ02Yݗ޿4l ij,SԒvf;ǛP̏v%VMnD=M}9c\ p1]"o W.y_H>].Ӯu{]wz@FjYP$ɏyMP$lD5?g͜%۴Aq\E듋c4o(\ͽa)9@2Fa% E>~';TW>'+|TD();BO|J\btVWB-6Z@(M}mi:ZF\ifͤx [vN>s+5 8CÊC-+z$ٲEH58TvђvE1j7>UM=楄g6P6FT'ܝg"`},Fz҉f L8F_/-*rcF*a4kVQVxa@3iDCT7.5(0iy Y\O? ]:uزŘu"u;A؀r{# hKBEXVBm>Zu[lѕ(f 4v],3{ŭZYʯdcV 9}5N/hVnՖc{ ]@AP ;hլӎyF6oJcF`Uga@񭪙e sH"Aad'h{ΔWB,3mbxgōXZo5[zZmXu$i6 Pa E\Ldn@ž":}D!.:E"sc2ƉT[6\VPިŵ5?.q+rrbTVICiy-/MS4O.YA]6uy]-:u8nwhW0Nc{R7!ML2oe{ι .]Y AV&  ,$0mv$H8+`s q}Nf \r*L0^$u)teָ'šΖPrYӼ7ުtzمҬتDf A7CM0Ɂ 0ca%-Y`CwNwr| &^)RU~O>s[%'ݖeUlO5݇{!VFe@ nQR yI<IwXvB;kXAZɅ@nR$я7+oo2RRJ-`#!8 Y Cj1/hL=~nfZ0UkHv+]вq4Ժ=u5plpG" 1ēFH <5$wTcY:xѧiOI4q+wPV͒6='.v~[L m?܎n$hxc<.qUaيg.#z]PYօ-kj\JYK۾{zJ#0x&p;N:oDgwSm3V'9 $ /S4srjk'%AncP\ 9ڴcñ"UsmM5a)w`M(TA`$dCJB^H{+S6`qn@*G\3JLaˀ oG-Q-3NtFx+ѪCWXB:.z3lt./<'&O#34&{0'֙C©^wb$ ޿iݝ= bvUj N~(|7Id@: ]QZ4t4!x^Ѳo?Q _+}|Kƴ|\u񇁲'TY| A(&9޶ O!)tݲ.m1M~3#4+L|ecgy ڀcҔL:<Ƅ9Ci@gƋSу̍ OFD#­2ة~jk Qfz?zʼn/zZpDc cߠiC/}S`b@2Q055A>8)sf(7~JAr , >Gg\~ԽZ `/Ū f,]سzFR){̨߹q\I. 6jkP RKNT0ԥ@0 Pt\D1|n@A7&oK^(N0cu 3It4[?9P^xL/Cc(~͡ 8Rګh nkΦm#%p]ǫzWiv K;h3:,ʰLMumhP_ yG j;f 5QĪ2%Jk׋yp>x!5lV6u/Aa9ZwԘi `ƽ:5aNkw̛ pW rbe{˒_r|Fa%MAAH1KցI{S=x5c?sSz?([@P(niW9pwzc;W`ծ:k<;QMzg4C"땍[ UDFSgU-)]iYDqOp T}Zg[fmn3p*-x.|bB*D!"}Nm29.~>ø~J%FͧUѠ#϶LJrϷ.j0D讘C[):ƃ Pwrh ='Z΁) L?H= VhcO Xe[pP2nRbKlߏz="$*e3'5~m.fzQZPJpү8UrC-ΟUu>.Y5qr(^_`|nB'IdLS)YtdY9A1~c,ZWFʠzsͩ8]gS';k_:~B&:}}J>+Nxzb66Bh%չ*#K}L[XFz f2B|(c Z==?"џ=pbce{\٬Vޭ.ENϬWV\T>oע$maqGC'Wwvpt'xG60za2;&DEa̾ލ:Ls])Ȑb^C>)Ǘ4xcyAn-J{ykD]DA:v_x]㳺V/.ޭ~wһ6 = FJYU@k=x)gߜ?; ҭiK5ȸÑ O;gsΘcœNi亃ِ爛|gA֯3PgҮ1o5V[K`;RRȰCGʄ=cmZ_Uצͨտ>*p[䆪}A%#:&G''e)K)>)(HQPAݣ5+-uńuyDrh.%s 9ܠ^VqܗoU"x:5;~Ōm/)D`RS:5zf\hB eO#v&~J"ey3=<3[4/}WýyDv5`[FGeФ&1NjD_M:a GXw\AB+TUI8` %EէgZˡYDMj2y UϒC  &%qe4 13UP(9^'\L(3'oZٵ1eQY~LzJO8"8ע01}'WX6Ccm0Tkr~~pʏ,~vd٧W^לͣ<3Jn\[ؚ&/,5,~$'L(`Dg}&{< k2C B񟉔l%ҳ"Z_p) kcY`Sx]ƒ3Q*RC:Ev(=@VYiɖ[g(1:Y;Z3}KRfh .MӪo/vgW72Bi8嗐:ëFN Y}ۖ,\t/|8~VPIO`&f!ǕuB7Þ%e,X1aVETiDǥ 1Re^xZ s).os l;Z]w7 9ŮWs.HЙLۇ*[Kh5  ~ʿϰM*ɟV5D ~5 5v?ɂT`T8!@/MtF+Kf j%)G`b.K[r}sv~=z{=8<~t7ۮգg? +kzŕ&LeLzug[yEnƵE s3JPsbBp2uaFj}afƑ)_9*2x/%:aPWNwN,KwOsGy?(5r@ێ(ja#gRߊQsѭf`~Bs,C3uP}ߦdut; Hǣ.\j xB-E),"4wjܵM} ЯkQd?~X\ #֩Vfe|WTbL̰XX iny㌭ȵ?n ozG6R%ʋ٥lM)>ƁmKG"wQ?oe?9|g-<}fOa~9#,ItBY=)u[;ǕG8RBq9I.y/ ]ZAQ!{r,%i ֙AA[^c|k2`<_J%Pf31wG]pP_%ʷS"= =A\e͔2=czx s(\w,B1 22DNnIso[VnRù~ɠ8eW?{e_r SeslIqMQ~ʜtX{ۦwb߲r)8 SF"w$DCXgK_01BU?{0! C$xΠCJE7Q1:9l׏~8:k<Uڋ8qaxN,Yeupaױ 2k>$y"쬉7{P#!S.;k1rA(K{8/1܈F}J:Vd!6DZ4Y%Eyn$XNZK΂A^a;*zݛo5sB(fJ;quiJ7 tӶTd{;iXe_=u1W\`s)ݫAzbsuCe">8C>l猓Z`3Sދk^ cqc,ǡj{W/&=eAwѳA'q0Ԍ%ec`^mP7 ):pр57$9cߋyEE.ɓ]JwY|2e{IF #x{2 b%-8Lt L6G2wJ%*)(Y)Ǘ%攦*M!,X49Mbsj%d^zLY74$nS&N `K-w͉ݼymҜZyrs2K69[+f<^8UxRMkAfi1 Eq)k=I-E+$@XM]vg'-B\ {x)({»G yyvok?>>oni4JWeoV5%Ʉq)Gz{+WD97ֲڋ \)~t`"P +A1޼*y ZrHF@e^G|7mD<\~*>՗ҹ pOM FD G(np&$p¼_ޝ I K{>H+iHbTu.=@E "abvLe '6V/C8F}geg?#_;flQ7Q[zIX/!%u)53ņk#~jGV)ڼ[Y)i\Q([7N|Qazob; P8gGLőQWϷ_H!x2 :f چ#.ex9BxPKkQ&Tڪ)( 3ܙ@eJSFj%XJE/LK"s~:}.6[stN0QV =ct^ܑ2fԕ|ZC9d/C~ P9bNjn2I!-m@oEl L$x| Xc"lD0r,J {{{,&)puCkGV{_ڊycd)](ҧ ӐQ6PFtb@ҚїU`ni= +Fx9qF&ɒ u  LL, `@Ax9FmffF +T\ :@d>͂,1lr3N}iUғtT7o&Y{QY7XYrfۆׂ***yFũE: EeE &IOV.ǥͥj$qNҜb:\ @1hfrbqBNfqIUnjnRjFn~ TTB~6'BIQi V kK5cu]Yiͥ-ԘS 7eaT=DK|~JR2( B՜hVC̪N-*JTK, t"tRRrRSjᐚdØ0ցt打X8'+ ͂,lyIE4 'wN~ 8A &+ o363a-λȾvC[ӻa?.bqi 2śPAkUowҧ8[yݼ!P=y(޵ݺ'U"ϼ M* u)m{Az 9Gt+I'FQ.l PC'F+ha!X~=@;9! SH]t#35{b.ȲY3Wn QwJgh_U I@BP#4Aj 1C3ʹsr;")nc|rK O5jdyZ4ĭQz6i H1cI5]AB^ ~wiЩ0 0 .sIU5%:[Zл <,jWd52eOq ׂw'_NNtlJ>i4IH7' R- ܅25 -9$sǪ-J$v:W=SXP|^ghxM:=죊M'/5AEZ~'l^Vt*7D>& h&K+ |9:({Fo5x&;x\߫7#E-} )KOW >W= x}kAi*{( f7&FPG)dm;?즶'o;a݋=y'MӺmB2/wgp8i;"Z %++n:t=!)h`ZC]w j`FŲMӦpUU3<0gG}u\<ݟ+=UMnԓۖ.)߬&:h2mUyoQ>Cv2aHH7 >awvh'$Ȗ^#v}Dy HRrE ݑnv0X u3eF1f"S&t=T߀#<""zftqt1jFWW򻮛EYN1@5YҘK%a1dL9^V_z\jXZEQH@ (-[*jck!y3=CAp!D: QhCُnWn7Nρ,=7s~1snv/ד+/f_ͷJۧrF<ʀP|iNDV!zj L: <[ko2tj!z ]N*M =BQEF8*5tO,tCZY۰XGђ KB.=X'uq8kUF^)|n.۳ׯ}ŖoVn%x;iE _0/5OxXoH9+j Mچ(MIwkn՞TE0yf_hl3o>T(șMa,xR 9L ,"<Ŕgpl-|(X~8zHY6r/@"-q(8S20Z 'p)>Y#%͆C^$#:qBƚ.FzA1tC^z4}'ԨF.f&b)Ͳ?xkO['lr<vkt1R ? 9/ `9יqU]X1]Wd[&;w97,\Ud]K3=dy LJYf@`JùHuv(i 5㚤 r Fs f27 SZj25g\)6*;DbԸ&l]Je +f:oc[pAA`9xXۧ탚 ֘:ZW0PQPȢKC]ʕD"dIer9 :* 9X-'6m9<,q>pr嶆"5\U&yx0' fb`|h:g3`ʛjAy. AB#d\w\(=ه?|y e@]UElqO;yavG(!D/hGQoLa\?86=G7~{ppk,,8+&Lf],LR|f"/mLr & ~ڻ?(쌓= o#Zt=Rq"i{X[">Y ૝[8 |q7w8`D`'멉p:!4. tF2 D%k;fLХF`iA*qbV.o}!HFN;:LKcѶ#Ƌi- #6z>١{̉T9|qV5{t7A s-6[Jy})ϟv_ή>bWNl A3g@AHb4*sF FBmc).׆ )GrU=RގXwj/$;*5 K{x+X?8VT1CTqucgkjʀ(E4N-\b/J:@0.|}v)@QAtdJDz|IEIjq뤼4fKGE?~W>ڹ%12`lF V~rxϐY2 kX5!b'Cʋέn8eOyL+#! MJ>Fb6$kTJ*Re}nZn-r8f^/@)7r "&5m3 ׆SC7nui۱&9ـGv2YPWXXONa21\cƴy#6v x=A  ebqk2 zZ͌3TPq׋?3AǖFTMbq}ܜk&api +sz9ejxX1ex(ෳxՖo@sNEE6k]e1!ފwf/Zƴ.丗>]z,"¨!cs6 gspFFP7Se4 .`8\cJ$uhƸC2g9f.\<#Ƨ量Fw#lj*ZM.Z1澢# iIȽ K㛤(nq42_9Di֚ZրTV[j5L֬t5UiA1FSݖ0!رZjP;KP޿X--jnP:ҖSU[0z x 4F3 |VϮG\x~vPj𚱴;k;cOy 2ȫ*SEYEĒ D8فPyd|vo`l;Xhusꖀ r/y(AH˵Ax.<VkeIJTmY9~w3\Hfޓc#B'|7 <ԮE]u8WKb1-;3KrIrmٝ}ofϟ9Omif0Jg7z$TjNBnldڒn~EM;,SK#fzabRѮPR4ⴵL2(IҧLF,QC6H ӆؾ[>mI6B'bqT䥴XXDf J}8Rӵ>$ת#,ej3kHM#Dl'X'jLײ6jEmWuk8Wt1ݰV!WUSԒzވ3)wdR#+6i6{q|h-uKJԎHJr2ʼnd&}crgG/AL'k :wѼ:wSotz3"!_VbZʼ-ٕ:zc+ 6ާ+N o/X? Vnɝ8Op㏂RKo IM[=ђޖn,:gFg&$|Bz/n\G'*5h3o߅(u8Lj/fgޥYYԔڻF1K۱qJzZ$g(,$J9[_Lnz@cxOV)RĂ%աt9B,~ޔY.'|fd BXk (h\մs2C-u*I0g ?/PC+2GXv2R8b˟ů(?~qo!|?7)2IH?Y?ET_Ԗ m#h,-y 3C@]_?nޖ\z?v(Rs>Mŝ!X@*R^1 boTiOmo,uډJqky5XI!kWdif0aci>z#FQXA k"k$Jbd3PX_3-ᅕKA*@1jƴd]2a*WMIrwІg=?_Z)JjаUR9+Q4㙴ܦ lKލgM3'S W7X8<޹"Zo V97o[hє]~Xv[CCYq]l,6}'.* 1mϊ{ꁥn~zqN?3u<7!)#,fT (nس+!vokc7_ l٢:bî2al˕2c(=p\,Sz.CK$~J9c&Z``;>)cGO [͐=zϳK)0̰eOJ/#zF>\lCpXD6aP40iOıN9=hfXwo uEc={N'x vES/|_H'㟞u\\^UHbV&•v.0ɵC*oh)g1`T;fĻocq-'#=Vob|59|mcD'dZY,f6FkT> 2@CǹUhzU/\)lxxToEV(R.-n$NQۈVPqBh;̺8p7N9r#8!Y$1R97lpyrP,4y+S³d$ %=T:'Eɾ<yڽGf]_d"~ sȨD+Ix&&r?2\B~$ɉTXj'I,y@ DǒzZǂn#pS/ErBZxqކ'7^߯IhlZ4# pѫ<2`=!ѓ"- olVS7<,5ŏ?LV(mߢkwW.n7>Zکz!5Q.n V Tjgd 9/ OrҎTheU$e<*$}\2.kR{ h:wQx{,;=D0Npڇ/8RLWq+/uarNi`*3S;WUd W:&6wxKͩt*M 4Cԏ-cb(xOpcؤ{^U=L"3>:o!orC\.2tp$dK:Ÿ0 6H[ Ret8@OUЉ(ǎg4fnq[+y28{ѨBWE կLY$߯\XwdՄZ^*8bffkp^"26vipޏZ扢i 8ЇC@zGӓL\_WӑNn4 u]e潑HS3dAgn!`JX$w/KLչn.;gQࣿ"*[-URoV$ׂJP- +zSnCz·Z3HBN:X:D7c ]5hDҷV.>Eڍde-P `LjoUTqh͠Z ([TOͽF}*h>rINI&˴m};-/~Aw(ŜPꫣS    a]ZLxwz.+\l:4n&xĢ7Nt#Μ'b4{rJB0`_Ol݇0$'RKD!u򀂘c2.Pq7tun1͗0%)j@P syvb xTMkGE f$!8J;JN[F!bl0JwfL?_shr%"' >}/H", ðv{^_.xsG "Y2u" pK ,ZN멤cܶI\ilmȷE0b)D<)'^fٝ2vgBwegǩKOq.ߨuϙhݎh'k j)AceC\Ds[5DVM6a^ngfM~ n? BlAU[l0@Ov˙s]|w!Z2.lKuԯKА\k*$2-~S7i}S<揗3Oo 5,qmm!m_Ӑ6І/.E jȥUh9Dhh͊eEUKPR!26ƈBj D) mID% >aI *{ %*%|_;ƨC84&HgG3֬Y9_%lH~N^-Hb"XJq\spd4?OW_6eX<|{̧'82r(9e\x>˜+TUK;bP}ΈxO8f_73lBt좛 _AcydzH}FI O2ݦog?MQ>cHT u )tiNʼnյcxߪv梋4$ҩ;|o}ҴJ^+tt.?e\!ɣDi;g\hxSMoEVB$"8@+P E4D4ACJ@-Ytwf"84$| .ROu zQxy׮w֯.CA7`Pfл\@g` ~noQǰ%N$On*Ksv_o7V?sWߺ3w] 8le+˖)/w_TEdc2X`_xI2Œ֗zdonByo[CnZ3.??oCB@*b iBD%p:O>%P^iWڷG 3u3*d1D8G$S W ֊t(Rm$dĕl5i_LD?\F]\JiYRe uQц@ٟoZWk|Ѩ iC;HTB)#^lήզΪI;$&tD-v ŏb*d<~%\/+}Nvxb<%V{r{+Z[W=LͨC86HB\TxSkVn(0ztmi)KLHӑ, ͺóV{=iXCatc:am3uu:E>w|nzDͣJˌJISYđt}籭`v 7va;k[k7n;w77Qsk}Bz$⓭ZnJjs(8~Z]BRH58J5pΛ9GJSod ôVp@ۤբAwT=V.n~EۊB%=!BH8"LOER?~x)s$[6?V/gH ڗn~>mpM;S o42v:t&;> EHԄ\;Мå"1܉e?g}f%lq^i˞;&Qi8iPx<7p. s(W&cP.4JMN9\m:\DB(ҦmilEdcup{ԫ՛Ol!'>/YUjL F^(YNЏ/pIq<]y֫҃?DV9|π}FADA C=ET"X I)Wx%vNFֳ(&4|O{a {6*mAR7En} π d l|Me(-KXrRO-OBPv0H1 kPr:DXEd F$2|W{Ue+%q{4u1(JP ֺ'jMV҄b'^{ty/t'{E2OJWz ZEfOzD ^Ջ[ZxSMOY$I 0NU (1LЕvխ'U5G 1Q7.ĸ`l{0c)MUս{yg_ߛ-k;2V4Z$!Z9R%s(l'g`]ukX__f,0ߙ0Vi%A!R[̊:A(6]ATN+X;$-vSU^'CF܈UjըyfRO#?XŨ4KI#IM46>Bo^8+`枬]e7FmGϩ o=]'$®#P B߂!zٟkr;L9)N Z30aJ(kRWgEC!D[ q!oj :}8j!Ғ/* +5Z5|*` ߩ0K  A{4]!-oprJRr^Ί+{01QR ْ1gd 뤭KX`X/F:l@ѭ-*S5VfviG+<[8:QΉjj?5vݿ{s#X%8ͩ`, I} ֎ΪHGo&5/z:أ~cœZ8+ C@1qzd#͖4ᣩZ; fBJa VtLEF}\UC `[9O|` xkFiܺ؉s4zmCIC ۺ -Hzz4ZfFivC0Sog>rڛ֗蛑C^y}Ӿ^[UL:ԉ0IȺO !D?d }K `?"kywi'" ]JH(s!2D&B"EH(@~gZ}ĢWIRnϡ}K% Kn8Ywux|ejC)2mǷʁЦթ͵蓐pY<;l%|2alG빯o~+K0ÐL@^m7#Yܘ*~h/Z"hc$J x|PNL%|A2o7%JXIyRNb&,?fd B-|W+!v1 j o>8nYκhM\I1L*I5&+_)|ʦ ȐJO Yq>)Kcm4 MV1sě O Dp@@(7 +lVvjRUx|0('r:50l7 ;Tc^7|܆Fb}ÁSqy%Ntti1 MG6KA3ryi#|>s%7@Ě3#b~;B*U]3*]?ytījgP'*-ch-?=6.Rm[>9t9EQv!э?wTзnSSC8ne{q_jx;2_e9e&KsOryNȥfs;Lp;N f;a!xkGǩ#"L{HSHHJZ[l&b"-6)ħv'Έ-`dJ9>zjV/(YɊzeV_{7PᝏІ-3d|;L5"ECCP.I >)־ѠMb{oW,'1lF!A9ᖝ<(½칬73g`5x,_ZL]JKd-e!5\ B[Wsw6 hQUD xIȡ0%} zL鿦r˭]wC& :0qz1 # iWJ>-?/xz$qM7Ҏ2/L[S Nd3$HY-s1.Ƥ!U7Cq(r6$*fi}J3L "ۄ%QZT,|oNjRUFs-Ŵ8wKŊNf v᣹| pXouӋf:{*}cX0\؞ۊǃY yc,xu=MEp|>ߝa-3T 0)v3Bص`׋$zA#Ju*xy.5Ļ+xt ,u -L6ObȡVZUU9ٟ9p2; lw1k0MbaYlĢ_ZTZZ]QT](QR_\Z>ٌhp,. x{.WrC0d猓&`nIxKK,6٩ ťE % y%E % i99 ^II@F^JuiqjQJuF~qI^bnj&HoN~Bflgr,x+Jrd F9. ]#C+# J\ V{M&3Ld唜<(6˒KYG!rb&DԬĤԢTܣK-IU+u7Ď 3Kr2sWPR͝+3/aM/O,ILN.*\ +96jjIj쒓߲]hhr>d_ k &#\+@ 3Fcd)(']x[%BrC7K^~IdF.ɪ<Os"  9x[%yZb #@FkFCɽLɉRg1σ0Xf%ZY+q)Mnc5+I-JKLNl .V^ 1ԛ`: =ٗ,AɌ\ ̦@->j<-~75VUxTMOAE~$V#]$,mg{u21'?3F=Lwի^޷__{0F 4BIP{@Q`ԣGC#:/ZƖq;uج-V귶aXo5f[ஏ9j( `..xm('\VfnwrJW@Kޟq=sQ! dOFs+$Ig@RRq&}a]tH>Ĥ]A U@"fjo>ys164EY5Mc9(wo;%`-, |%Mi0sW/*_;\h( J).QMkW,@Ȕ;edR4ѧ8Cjq')Zt!t(AKe/2̃M F(L&ԫ%@0Uj=YlJ?^ 6~w-PŹ2*c0ݹ-?#zet =<` fYHBdb񯸰1Qm~k[l[̢Q%f71 ~VIypK/r/%?JZWxuN@Syث"i-埴rM5 Es{C ]_֕&/XoL1aRo($~J+N~2?`cxT;kQ wM!6&w5h"ݙ3+3ba `AB;AasgZ,{}mمj}Z0Pݡ0}F΍‘fs#I p dNA~<_텙k:`., U{q6oVsm;ծ)y/GN?l5̴i*&tČT륯SXp&Q){x KgY#hy7е2>FCoNU_Lg[g^GˣcQA J#( jF8Zyvzcp5qBj8P= G̸Ňσ7v` ɣJTPgչІE4b zjHUdtP )-KT}Cb>#NA\ !Ūa. ڪ۶VeKɒHY^]/WP{ju NdHȁ{'AmCK"Oc4b"pЕ\pf#Y<]qLao24 BxXi/ɡLZz@k:D\PTLl2d&&i<%.%ļTݐ\+G?PGwWɭ &dzL^˲CYG!rr<V_9'bU,ftg;lfce]y-o&zU1833 ov^lta…*9GUQxTkA&Mk HQzGmP*Va;mά3` ^Jţыo7iLB#xɰ;m~_,+F+8MۤZ:h|]UK|g%@&|F²w-|~2wljXd43/s6x:-]+ Uxf-s/~Bqvr* + JBH4wWST]GHiu)Ȥ~ZMR_;M!蠟Be>2{~1\EE8GO;]QăO$U8n,X V1"JFlW;}` EQ!a[ƕ8Gz8P#6HJTH Sd ZFP/r_ՄҜxuT"`n04IIH${=k)veV%"2g ?h G$NtZɨho[Rh5w5FEC {ZGr<95jQ3{:iVQ#B'ҎCz5ߓ%d,vPV]SBln滜0kzK%{W?:k;2V4Z$)Z b%Sl&a]uiX]Fc9<;jrp2! C`0'DLrYlx9 - l)IO}EȢX?1W} -DO+4Xp/k-mǚ껄Ë'[%y$PvYz3=k}b B?9pB"8UztOhؒo! iF(r̈́'/ ȿߍL \Y ?0Ʌ\??Weqə*-Z^/ +jP`U!~ ,f?2f A{v X3>8`RQRRΊV _Oa9W& -;"Blt\U0ۍ({g spFAFrZA1R:XDo67H/J-~Qc5X,'4%ւ=y FgU爙E'~oj^+w*ɻ?aEH{t;Tڕu xQAD[JA\Hs*`=u)OS=d@U 9`DEB߯Bj[<\#MɈVx{Ԭ+ /+\t¾ [.lPPRV o#TlDž=)\q~=M6\lسyY6}2(,x{tBi dm ]3]C#c+cm2N^>9Wpr/˾y쓣Ywi)~ͺlfj /x[#wHva&3]C]C+#m͗1N.▘|En:nY'd,3yk3-˵٘M171;U(U$_!5$H$#U!4'G+1) tQHKSPW.-N-uPRR/.KMUOW̳Vݑ2 )x;$Of4+d ,t  ML7_`cd4,2HnaYh99uϬיĔs RrRK&@)Ĥ$Br~nANjIPmd}N9MqNleh4YOtrW3}l"P@lnɒ<y8̸r3S&o 59ׅY|V 0r_#KW?BEKxSkAf7IfQs0Lk&$VD 9I&`N R7/^C=(x^?!Փ (+=>>= miƴ 9 ]1H3n#.g]N\sf6 .U]ar3 Y@*kP?)=S3fT9!픅[9: ;R"'`zS/2!Vc}kf'ПZR<>ՙ Hc&'dm'֡M4A{p>&r9H!pmx_eb-mCvaFn{sGd'"C} O(\:~=1ݻx~~,4֓ ]R8bQRujg:scx` $ޤ aH*~v; SxkVZL@D@ &OK)_7(,83?O%$J(ck`kd`hhebm`y=^'s Nelk8YmG|,! Y2&f**+敤)%Jsr|OTt=uԢZCT3KsSk5Azs26?e:Nx[8Sq|&s]C]#S#c+3m'bu r Mx[Ua&Yn ]#C+# L&2 x$'blĺr[,@j -#&yy0M~/C|rn. tՋd7IMٮǾv{N. *[&;pdj~c o(ykԨEU X)iG QѰdll_!!NN$ [)7HDV!+Xrnc}#C2щtj%Wt)g-oZ93ӏ>Ӎ148dR?&lXNdtYbxEQt^ZLjrkÍ 2YAEmKGJaM)X+Ol4;rVܷ5Zk@ 0'f [ṚӂGkh=Z`N7HFN 1Hb:Cu2*Ȥ!lW(HE`PCJI{Px*UЎ-u# &?ȷt X޻jRcxQ 'i7 bx}z k;%նtz܏>\dG!yki)lYn`s\ƽŻ!73f~fdU G$w,FYY҃EBe9j\V@l> IR0Rb珱y-XV>YbpZTm)֮:"+5Z1H m|oVFفp*;\juUlK֊`onw I}Dil:= E}oy Urfa//l:^_2]'31BoEF<+e/HՄ3b(婬umitNn&Ykxm7+K^0-*L knTmG6[Y#2޽yG35E'w}[Հ,S-%'cY/?`]Yd s AT,6TZO(NpR-a%\~6*GN^(cb( 9sy`?xTMoURT V-(=K 1&i[$!]C%e%Qxtf)%ӷ{Wѥ񜊟Q۔A[- o^4)"rExVMoGWT0X56rm^{Sn|̬pgw_zzwUm Yrsj6c L;;8lmtaMɄ ћY9).Z2m`RCT)PM㷱~x:_K!b09ݺ%)O^yuL :_y|L^תeO[{hH/s[r8s3]nlDN3B>qެD˭to wVM.+,)?oKrW1Lv3>JV0-*n,:hiXyk,8,m.>(rWwJr?вB.rU6:VRbż E2&"4:Pk[ ix4H h̻v*.3i@C bu rA-.MC4nPTxN1=3ͧd>QM隶Ws9g'NJnWvv i^aՖt|4~2ӫ!|c3Z3y$X ͔Ε)v:wv4./ UJpir#j  HZ+ƻu/qsݮ5CVCkZX-,jRU ˍ^멾Qd$+ծ3!`}`NN75u{$VT̃ Gh e sV'U9zC.{UiTUtK)?ۜL.p?jו$^e۬Q+©꼷q t/ba*ۡ츺1Į\g/X575vN7IIڵz›bg?4w .m_)gl7<'[vlV8j{{pMoB"a⇁a@ vjY2czY& Y/hMJm?oܒ^k7!Fy96plgx;"YzUq&[xToEWGKtAA`a,d&qL R n;9ff}:!( ("@AIśW3~=mpFUIM0Q@c@p)næed;\^Ԇ¹\ J%K +nЬ1k G!,! Ԙ_ RqGK~^^܉;b[^ai5.kҦ{X+5@JaC'>"PהŬW_Z\aucXcQ -l?I&9@cտ3nÄ=t$U())uo2j2[SꇫV\^^HwՙEZHb{,06HK39GdVܹqΝ·U]1 6q(-@ŝpX.8>E,$UHn0ވ%ILHiC HSC?˝icrѬòşVSx^e=1ÒF~4 MIy[d>xgDp%vspݼDq 3ϵs K~x}JA*hV&h7 G (xʹNtEd  {- r+r)5=GeտUS~@j+gZHTʕPO@(Z&uJE4 I LE?fW )u THf VAxkAI1A>PIf|($Wb Nͦu{3-xWo =Y3٬2կ}A[ZBøbyș9LRMP#ńRaB.!;֔0W8_:sg`zգnC >lS FQJǖ6}{,Z[}{otc8] AX i}I%t)ack Wo\(ϐpRH mbPĒ:=H b䋆be$tER'aBLN$$53#sll]*3[u5rfx̥Uΰ,i/#:iꗱ#!)~rj4lE Nqk|^ O 3R;`0Z IjV^Rt>Darde ˸9ccj~z>i;$GCʒN>C\ ں 6=\Cݙ/{k <h6%(E$,nYIl<gqx:SwE"w`sUPA+l…Twl#H ZX{(z=4q戹|[,p{ҮDI^vK%FK0KFm*ˣ:v@s ^|K';:f94'H4>MMN 8}ˉdž/RV2Ud:ڲ= J(d("6 +U`3'UU%Zsl#$^J ÷]V{䰴gx1[ Bx)' ~(>ԩL!.Gy<>oQ7JYw 2Qхٓp5ٕ7y,gx'嬦px+]58{劁41/ˏ+[lf?uƀB4u38Ӿ6l'9(klHծxK)xl[[/`e'w%tR.wCUPcI,}krl2&'gH0"29+Wi |Uʒ;ifۯTZ44lpSڿJ<x|!a[dJEY%)aEřyV YIIE)1yJDYt#ĝ@╓P+BHd'Fy*@%)%>y饉V nyy`TxxB* @Ge楃\R2 JN~( 4H1钢)SrF&} 1KRs rKR y'G3 ĬH!\(g+,IL~b0Ysrb~IFjQyfqBfByfNBZbf"&d7OMg\R_\ZD_88rVX\\_9@aC"'+pKiX)dD>=\ǩkC6 =Ck $kT\u vcaxHAngeR0=n [=<@ҋǞ0 |x.LfɚLz@k:9DL\HThS&~G?PGwWN̥%i0kM|CYG!r.|zCY}.~o…6۰I2+;&&g)(q)g($+Y@FRjBjfVlIy%Us03)qmaғ&Sɧ=2Dx{&GzC1f%&'MR9xVmOWn$ GklMٶi/gg6wB7dgw!Uj"6U {gvwv ̹}"x#‰qc  A<\ l-1h!d:vr&8-`Ep',@\X¿:WV/uJ=Vݭqv [r8ʺށue_muZ`NE/`X= ߂&j6;nDC.0ȣꈣH2[k'u :#án\0\"T]TrXS+^J+S1y1|*~lQlPUUY݇GO?`,Y T`c!Աt@c#ߠQs@ۊ}I'=US~R>Qe&TXxE {*d3يSD== NME§LSF;C0xˈk ڔ%}-w LLXY][pKy,ux(ŸV:̂8eauRwI )z%4(buqzZ/Qu4X7ylzVsttmP]:O_ʋ'xŵ]6>Mks 5I1Oޮ͎+L)zS䖾2vmYȧ"I:Is9nFO~a8.G6ǖ]}]bywNK,/V6},wMIuMoQ^%%ȚxE{d= aԙ6 Ob^zibzBVbLd&L:CTLB* @S2A|̂<.e+==܂Ēb+Cɛ&?e'S6Va1bmGnxM7Yor%]ޓ|&6).DN>ƖiJ\JMSy[|Bۓs@كD7N~ܸqӢM7-*U.-N-Tx4iҧ]A2 ~>n1qM #W?]uHr@%M74)t9~٤4&rN^ɥ3)%''pM5[mhM瑜LND~ڗb1(PИdF>}4gN^_9;68x(]v>Q^%%ȚxE{d= aԙ6d&L:CTLB* Rz2A|̂<.e+==܂Ēb+Cɛ&?e'S6Va1bmGnx M7Yor%]ޓ|&6).DN>ƖiJ\JMSy[|Bۓs@كD7N~ܸqӢM7-*U.-N-Tx4iҧ]A2 ~>n1qM #W?]uHr@%M74)t9~٤4&rN^ɥ3)%''pM5[mhM瑜LND~ڗb1(PИdF>}4gN^5xVMSF+eC #2›TRˬ4$ͨfF‹?DWzFj869HYxĠ%*! /$cQBF ̬ \'$葤/\ PAans::[<8h.>,Cd\rR :HJ!a @}6kb7I! (` ŵ"2a< WůꐙT Xz|(1 :P-z7# }9(+|'T"ᮐ|xu6%;[GUx+uw;QsD &c=:r[yFoNw$m G.%}}8d':Q3 Jܦv><) 3 ^߻;j;tҧc%%I!Sj}y s|}ݛ>WK)/C.L:;BmFd$LH(͍7Ʊ"a2̺Pg-2̬ik|TƶDߚTnʝ$EeAƞ 4" 8<Fn>xPSŒf1E.,YDټǡRE$$ǚBdͥp Ba,II,Mѝc1|G 9׭8y& L%sԁM9!h-Cy]HZ gj^.`+;Ӯ"FA!₞~ԑFp,U0Zń-(,D ׁ0֙?y?veih?\Vi+03$.lok3"5D'ͫ 83z)~ÆF-m7&7l<HL. LW',qϚ;wG>P`͛sT<3Uk@iCP䤺1NBc?T3sT ѣX\_46Ycq=a,xy^8"|DX.DS?_2AN/d44ψ2ۃ/˚%1[BGPE 4 s_$s}|cuk:RExT[kA+DIx%4RR ؗݓ13av6AE @7( Y6ZE_l|3k-LL$Cc1l@ǘ5XVG':4 Mظ~ n/-\Zb3.5o Li^( %G2T:ü?bfRՍ=V ^4օgFltˍݏҭFʤ` zȲ}_[ ŦljN68Xk1I " Cw`Lc-eI;{'qrUFrC"Dh4_%=rrmR!HTHP)Ao ^;qv],4J֘Cq&ܺ P.%x\w24vS3m}ͬ" H>?\ڵkX OU@ʩ}u>S'C]~bDz>=)(Ӱ]X↊8b8.qܓTF . rO1$$NC.)&#Xp12OmSv.19Fe+-_F8\ew{,J͈Cv`*Ńˣg hM~84So;5P7_zW? x6պ8*2HEW]!T3tQ?i7Qn.ϭqf5j| 8fJHM`\\3S|凷 c6H~p'4;tvT# =A;G1B2Q0ЧD OdΗsq}WW(q.[݌0A1 H t9L$ Qߪͯ E*2;$wC}mR.NֆݯFߚubx1Qm  EY@4F Y6 $g46lx%Zj?f9&nU x[-uPrC>zә&a-NLQP HU2e@TҢT|Լ"ҜĤ$ EA#U/]OA]8AKI:#$/17V]7'?]!3ZaTil.D x;(//&OK)?D׹(5drFwFFǙ&|Ne-1f<.JuiqjQЀme8"'p2M6%63\dd6.d'Ff\) ra4*|;̚-"x͒_:y"'q! L (x땜#a#橌8uJ*7׳1qd%Nf1yLJ\9@6k| Mx#E|C#\FFCɛ&AsY@̳!'1+q)Mn`5+I-JKLN. KTHIU+.II,LU=d !쑓ײ8՜Z8Rɗ9@s\) ݸ3pq7 \R69xVnGS\>$5P%JV*]{`w:à@#_gf) %3sMVIe.cm\9*29#ͅZݸM{z23r4vN[&ݽw'_ ѫ$R&s&MuFS*UʆܘɊ) ++lxpq ݜ?Pt)K#O=ff3ݓ?\NvQuٿKi-gwR>E6ɔnul[N\tFhˠa?Ox.F=Fh؀g||4 6G z[Q{{脧ҞCWºhXkxRèQGC`SWIQh<ɡkD`]Ľyz>|}ll?ʱB! p\H0OEX_t&:PN hTΣeU΍1Uޗjg9|?8t\P ¥;WgK۞<' _`#R b})/ENz+Sw=9 Hi.htie8jhM*5 m=N66$UXQU6k\PX*UH5&e.?nӡiMDR9Ӧ+:|.%0@lbLn]fh6jJ7t7[,u"k6%.r[uFGHkأ 5[䒫Tw{aYB{G 67f{!qXڴP?D146zCGc6 ţ|_}^ \2uLYaV]~7zEw} ך3>#l$NLҁ ϿfbV Z֐^ςBPyWFEiNu2&:P1?-<' \Ì'?(> F9f)BC*)d,\oI^g7 {'1,>޿P#F%*ͥ*x2<c̤2ΙcsJ:pʙp+d:fЃN8x/t;M3%׻/!tNw%ZEvlW ~U8##$- ?W_ys ,ժ:ڡ {[,z3q ┛rkg'nsڒCP4jNn"au5Pij*f.,:^,ʱad' ϲ[$O%RO_RW姨ɑ~2|P*mFi`EcE=j-1tQ@ظ)|-.j4*}gv2r\5mU3m o!}wfdZGT =FaH Z5:ZMA\mDeq'-XvkQ*w[/v{̘WRE?p7G ޚAՏFQv xx3ȭ1Z\d_fٯ1 ,_D;2>#ؼMgBT?jF>ڋ0J& Z=c$7u\KȢyEATtP)~FKU {7kIf_,eݽFadnP¨ʅj$FJ͸?Yɖ  ) `J:Jp7'x$LzaQ^%%ȚxSc2d cԙh: *Ob^zibzBLnXjQqf~Pt2#d=&S..e=by KjqrQfA P~IjnANbIj&ԭ1IXD'd6Lb.D0M^ ,`څL7z铬`ZS Hdg*d(g(%f!7@l`Z=L@=Y8+q~<lg9ƂBk ܿ\ZLVJpm.\fJ͘[hdGnK"#^no ZT_Dզ WM^7y/NNb66x$=]zaQ^%%ȚxSc2d cԙh: nXjQqf~ALdF&zL*\\z !V @s2A|̂.e+==܂Ēb+C=LF3[cr)!ݓ'Nl>Yř(\pŇYKiOo0j Y=IVO0-K2R3S2K3sr3skr [ XY60-sv,^`ڏÕ8?FH3IcAbqqy~Q 5_.-&+86BYrr n.3%fL^- y#%ʑi/7yLLI-*/"jSx&᛼G\\'z1rvU[9xkADZiFsГ3zh1&jҪ[w3vgQW%PP?@O &V6ɼ3oԗ@G(P]) ֒87P[_e"? &yty[ޙUiO.>U25|A<ҷg{j>Ht*6 )Ѫ_@F;0^&CyѼٵT1ops|,/pi̗l̒;x6fF{XZ(iҊ'axf`a3z;Lpye $By$` bT:PU(o1-sߊ$k4>3uy^2iKi]*2\vr Ju_)_cY3XVyvOD>7LTP T| r&!)(eRӖ>$E7<S*Gڒ)T'VPK ZɧZ@\*)O3S Ci`JZ.Je &8ms]u9T$T(:>0NBEo腀I7ƛqׅ&Ǫ5duMpCUfP%c4iC뙔!J*ƼdՕN(C/` `nhd4IP:_Xb#,d]6^02s[Gy)&ؠ" vh9$$603"_w$U sX?9- vM$M wp o7m+WXh . **LpKjA+]³]= gJ@TW1 wgqފ8iDO'' 9I[;×Z"_*6lD _rszx ̼}]=u) 3)Hj,?0RWatПOЁgcJfw&C)ߌ8XD dPѡƨ1fbN^c15Fdׯ `>5Sڰ,SzjȤUt=h j|@XEc= s@p#i %TDz*BU>󺔃op(ouGu8~!t3F!6atpϒߥ& QD:,^%8VR0*$u6XJVR&x򽱨v@G'o=hq}T#"h^Rc-mqCl?3~U@fL)hj5 'q]4buNݸ8;<je:F4sP=\wۚMabBx|v{,E=>NoEzAv ";Q/Tt 4yqb 3)|j i\:^-$ 8:M8xOQӖ#*11aP-nh6$$Fv}[ Ww78x#MoEKK͛wWֽP̭kҊj!/e65(eJY-$yA5Vkns j"V!.A:Mi=e+4^%stxMjXUZYv 3aa5[ >w E-jΉpN0E P<2d=:8;ݓh$yCP:h DsOh U ZѬB #(={=eK~7`"66a!"2Bsҋԙ_ \2ѡt |)η$N@? d}la"@9zvtZu`~Ӻe4Ek-Ӷl)s[ ܴ9ȒwLz(rxb 18ݡb'8#`Oס߳ɇǯ?iA"H[MRWqA]m훬rĜ12Vd F{FF($ 5*tR/3m#,c"vhscK]\˜.Q CCڌ'c^Y r~ x.Vj#@_$&0MR9;8=3EA)$#UaK,6٩ ťE % y%E %@i99 ^II@F^JuiqjQJuF~qI^bnj&HoN~Bf&6Qv."x[+5[jvLRsQjbIf~KbI@;3rfxMJ@IZPZ3b^B1:(.V .\·/ y.>)}XۚV5:xD}p샋g=c#OkV5`AlPd>I}6tPa8ۃtL8˟M#1B,OM`%4I9cct(xGC!  3i a)$ fmv;@ԝ4<3&YͭbjuV(rf c7ltx-5SjcnɍL 9x9R _xVnF}WLJp ZLF I /+rHmBKJR%n`9g\#k3RcdL!i cs^p` zTsf!GcOSGIeRQf5,# YE~ KL8+hL,HC)Ol⣟0]a qO@Z#[$9 FYcrkiz'5 ɂRz)N)2g [0^iAwf*3E=;=c}9#̌) X.>9Ty)-R Y"+@g&̙䰡M,-ȷ!|YuS8<7({wx'K, :x}<WFXR Vڛ+.OK5nz3݁'a6=Y.b7z.*v>۶lp bx^=Oep&ĦST)MgQXl2@а4t =;S!}v[LK&;ar|&RO%+`MMp"q~mP(kBzP ڮքBWUQȜ֋1jLN 5&ݓw.-`PM;O;g (t{ۚP>X> g]"܃fZm n=JyojZ>IՒ\g`##Y5ߵT:.(l2~ BR2HMdS&h쟧1n꾉DE;urOoζŸ3ᆦ;\A_ocM-~N7+ݣam _H#_xUPQkP6l]HAA֭%]\! I iNmR[2_E~D|&OwwsDǍ-pquǴ=gzCҮnޥ,84&o@ngy4`` /bAx9q)!S aahVW04|3q=^xˁCrþfq'EƘIպmy-=EY TQKkutv,~K(7b$}D3lMZ[.4 YuO&g J.\Vz ]s1єC)Basiy('ᏩK}% M%7EG :f[>)ؕrwׇ,oϥN!ҽ 9?_.|FPS}m?jі0+'<(c`ٞ홙D؅JVEcY"à33V+N!)j7])U- ë@ڶ϶Q>0s&oА|]D.n(E6J6tiW񓫗gBn-Ae×dư*ޛ/MN9ƻY9 qd9lNבAW /l#8sI/@||4xdTZy`u] Y ؃k9U9#^xANٝc(+x ɀR)|SA.Xcp ުȍL_0IOzGzk)@PO~JU9?CEmʊhKsb|:]xk*aۅKRs rKR 'T) \Zt9#K3./X^1Nʖ<ٚ=ub\OJOИő> d5#4+e<ܵ@c^ť˜r6r+M+x rcA0$Kfa/: !CםRwᡵ],JPgjYLʒI!gckۄat: D΂^S'XipsR؇ ,i`sw\^W-3/m$)Lc`a6̄#~ۋ0< 1r.y_jܡ#h#Ag#L2!SG2ei0V aMab,sUcuۗ+* 5x**Jܗ < =ʜ*tE %N{Q,όJʩU!(uy`D<`Z&)w^Ъ1 t0;.>kÕj=<50;"zӚ.竴-taӓe" fK D2ю/r4a{]ofᵿU.oXqM%Yː0sSJǖnZW)ɄDM&=~|8Z,ȧ z&XQbDS"3cNVh6h)Dvd)}K<ԼDJ^ڛ=<{8H,mg=LLiq9Ec'L5Ag'P>SSm/R 0 ճSnEt&)øC@s@U4o@"j1H]t7N:@? dy/-"_}"G؁W\U4gl!J!ɨ=ƉcvkWZiy`cֶZ2d,Am<1jˠH& :f*N+uKcX2 fM&)dS*"o̽XdYZΈU ] |>nUE\HqV@fˤa-LWb~ յ2$Bs(I5bp˴:FLgl)}=ma0t|_'=W 0^p 3"`ūCl\}Q*^ʿLWt_1aGY0ͯZ G[{p&06d@a!% 9W51.%d)2i@x1 <]TvNj}>TlxFnj&Lx4Oqcי6gY@07x4Sqcי6g?gYxMqfsS"g$6gyƥ_Z\_?y6,T`eF$eL?08Nxۦ8Cq]rYk6wq;2n sxۦCa;<2=8;Bx=J1AaJbg((r;Hm "QAw"t~hLJ+ok3N |6ok{Q}svSq=Q )yr| eiL( ~kt}{4W%ƝBTpэqcp` pˌR(s:в'A|X Wb'pڃ3䔐.:-o!!W ia ,4)\X+ eFax$El7~Yb~Nf~jVbRRjQ^bJnf^|QjzfqIjQjd)D+(*)t*&NTPS.2#/gI~irDD!Vx$%1ag|qjIiA|jVbRRjQ&W5d)D+V(觖$ge'(Z+dg%($en|6q&ZK#$/17?8ulv6ǔ̼\`f@bqq}, %9X:`3>(5=$(5% %[ĜT%*0LfON <188EhE1+JJS:$v^3xp jxEJAB&LEx, aQ]qff{q\x%=>ycҧ.z~㼦cw2^?FSq( /_Q/ng\UDIOeom)3\ӕYi7L:VЃV1\q{HMQ,`J@m-yi4Nt QbZ㴴/Ob=sŇ!8Ry5AZ`rhh)=.~l% qW*͖\1e|R0rSRjAG݃>2c) 7}AxmLp YEB{U7H &߇|\ey۽ΡLJ*wFl8^Ǚ؋Qx"OlC;2+9ss2K6<m @x&Apk'`T,;yBRi Br~jI~qq~rjQI1d[(<,Le>f61%X`Ls$sK _Z&PBnbvf^dFv9a =YIIE) k$mc5fR2Of@D3rS `z RsZRsS:=C}]mU42KsSt5.~)0ɺlsٴ'bsb=09Q}2?dEvufM. r]ݼ^on^E>Rc[JS{)Oce?k4 h-ebL0:\CɕF G^X4 9~q ^%_M}D IpErIm]YvdL6j'3)𷧳>æCl >׶Ey}³|Ktn](j ~N]JثH7a~7}4O|"`4gMNsԢ ]P#مlglExvmCLŌ$ylx¶md[3".xvmdF4ԒdԬĤԢ2 o)x;6QobƓL,Bx;uB)'c&+2 (PF\4g?7O w.<+X_XZ]Z91r2d &5IL25EM&lxzu-|NF!Ndxu/~Yb~In~jVbRRjQnJbIbRbq\nFCyμPx}To0<Gue RUb[M0isKbؑt sN4|hRw0*Ci`c#K6?xlLE\ȾKesbΘE2O_3LV, "WXwYtO ӹZ*SLsEcV-=R(ϨX$ffnI [](y)cAiePz},tAR((]jad[ۛ'$5q}`U󐱘[d1o{9;I5buU(p*ᔦ1<(i(Ap# YVinnCb!~ E0v9]8$@@PB&ag6x/il?`iSN!;8h~\f\&ɺ%Fk?tNb^Q[:'@!cF3ZnϏu=%Y?9 ACֳ- $+U]N/z; 0+laH'Gg;"$ԬĤԢ}҂ KBk\x;>}W̋!hkqx;~u)dy漘xVo6  ޥ^Xڦmk6mbK$7QH)$DGR?R}K@H?;/f=~I 62Ty҂MZ:P!WX_ -?m,oWƄ 2BL5"1v?gr|_/ۇ/ Gy(y U9}Ik^Ȳ&@I(45ff:`[,1W/H#( rdnn\|CH9E"~}4#h^QVjA>$U\&)3te|%z\w:b ˺[bClzE9juMXu-r^;]Nz4:Xs n2vI3mRK1o P;wt^,t oj8+=_䞎`p$涞jGj:r=Hzjm1~?( )SOIH>J~̩s"]g Aiu:e|PKͺ%i Û1/gr9flx#Ls#G*x^ LC-7"Fx*i9SLCJSSrSJsR8rtT4\\C\<4Ks2SRRS2ԤtwY3`"ix*8K`C.Vrә1; x*xO`FbX37 !x*J` \LQ )) E y) % 9y  i%E % I9) Eɩzqh+.I*HLNLO%RR2SRR8U4|]5&`T|Yarf9ʬ;e 9x'EpFzNeT҂⒢\ԼT̜T+.΢\  M"ĢTdԬĤԢ}gHO?w..y%yE%) y%E%03C\DAf!L)ܼe=3O6x"Np#bcY34 Nx[%pJp &,3NcTVJ/KU(+-NMQ(-(.)JMUHKLWHI-,UPpq q O-IOJLJJ-J3҉R\Vŵe 3!2JqxuUmo0\ҍv&BMhLN&J 6im !/=gﹻgShJ~Ⱥ!ʜלԬ*QBPGƣ=O޵U#fsiK0R5(v{<*8D,zږx4%\<J}>}p۸}WO=/ԋZ !w~/XAea`As*-pc^X_)T֙2F'5ժ2: 1/ь`^®]xJK#ZC{*g=a&2$EYU͘Do9͌$peX$K-A-%pqAMA#XZ a6EIԴ<fAOFG84(JȬ YN'Mq߶Mv_AD)W9:βWhm6٦krU2Or>dlHx7os͟X!o_x7o;V&Xu-11xȷm26̜T% G?xټ dxk”2t'2}c v ,RX39wi,@9 5YC'/cNIՉQR(N>Iofx{uk%KbiIFV0nx{uk>oIQi*WombiIFVpuc"x{ϡ_jZ6B} 7a*b VPq rVPRqP7x{g4h%7 pGpO?p%[%%Xk<. v s URJ)NN-KQK-O,.yy *ը6jbWX<\YKVi5#+8%f%&%$Oe5prtrr rb<$P^AfL$Ԋ O1 PS |Asncx>vLm/0V}x>׎LbE9IYIIE)IyMo/xxƥ_5Q>kb+mjVbRRjQW&/atqXjEjknq^bn HdS[Xx{vm[ 61V12Lc2O-IOJLJJ-JK-)Ji%:x;6moN^ʸ#5+1))(er,s xga&`` Xs6?cZbk*@dXD7eIadq'"Bx{ϳg>ͷ26[ OxSao0-`l_"Jh(T)rd΄TC{` ELM[:A<"$YO` 4O}Ho职PO"LJ=w1Lx:- p0,]oN1 ˸F0_0~$ ̗3+.mko8)$8Newap7w Nnq+ں weCNE܍͖:L8v.>M!hsT5d48f,>HHaY-q=85zEe Hz. 3#G ,J~ j/U?|:P<`A^HGi覈rhkڍ6}o~3! y*zh`g` aPj3 3(6 Uq=f_Fm;9;; 5zp|=sX7"iRfb73l ez1(_Aa%lڱp'9w_mQ[dhl?xɹsC ӌz#x9s&{'1eyFتh$*hin^&[ 5x͹}BfUuL3WO.cQJpx>}i'` Ĝ VP?x>}d]y2 0N<99j1g$x>e|n~jI~JjZbiN~jVbRRjQBDoɉ{'1N,/ *N~.A 1\yy% tfYF.mhxy鉯Lh0x2׏Ks2SRRS2&_gt˵QxS0+/PR(Bzh顇܋bmduyJJ!ؚOx$,]֓28b-{Mh[J0}TGʚN-B$Q]Ch]EDp ЕL;dB{Ʈo>eM7(W$RiΟQr*\AŒqh5 K7= gʥ~:`]u_zp>eKiγ}r!}W\=U d#)EA!RUfv#ބf/}%Wa6?ZfiW~>{xus’zbOLӋ171;U(U$_!5$H$#U!4'G+1) tQHKSPW.-N-uP/.KMUOW̳Vj.*,NU,|ɖ )~x;yceFY+}ⒼT+S# Ĕ<}ɟ 2JRS7Oe:Ȓ_:9% ,bLx;ysC$ K^~I8,3hx;cFV.ļ *K2KsS'?g4R(HUHLS+I-JKLN<#K^~I8,UxMO=J@Fd;itaXX$/8oƐ3H ֞N"Nv}?"58?PQѪj}:x k Ry&zaj5E2d)mfؐ l4:E@3U= f {o1r$\;+mߒAGphhǐ9PKI$?J j%i5tհ]߇秸s6&O OuKk_pvx[quE^ԴҜ+2'0` mh+xϺer &3xEA @ @}N1j1Yt'$фD2=B]?j|,=QwYrLU lięz!b:8~ c%9'`)}nox.éWX^'x#R>~:rxY`U9} 5}%^9x~`y2~<KPjO100644 guide.texˉ̋]oYb| a{QTx%7\fM*m:6SOsBJj^Ij*inZ9Yh3 4<"9V!+eT&?巸k7؛YtnZx>1aިRFLW*Fj%Ay꜊tE'Գs!.(x%By:綅z woٲo LLRRJR+WIpRp{.o֦޲SL&d01RִĒҢb4=['? duSSn*c\\l{dUƸ80&_MXHb Ԁ̔TIu|F~<_/eeĚF]2(@N}y6C7S_66+7?dcQ(K-*Z-vk5ћ^۳%V&tI?xk;Td!Bg^Nz[ 6+{4\ s>=oT LLRKJR R[X0o&N I&2^]&|Wgi_j^ my1J7o E% d-TPtm*?61E,83?HΥOxWiohf kx[gBpGϕ.YEo;l$gr(W2xھC3ĒҢb4{&^Nd5#v+OVeym[Q'?XPj@zifJ*X uz-2i>/ >MUa'7f6ϰ"sڜ=2fV(K-*ScWG_p8>Y xbygx{dzgqmMs4M @! ANw17nsbCvC32ײ\ܷ1okyԔV0.hr^ |:GnCLdrф#i3čvLPzd&ԀĒҢb4V{U?t;_ՁlNjd9lt}&2)M67č6 O}&A H/LIfMrko x(Yqza_W"NcZx- '?dx|΂n_%?ˤQRR6cb|_:NgYwHYj\qZfNjqjQYjXSG3GLX,`!PEqf~XGkdl>n[߰6'!)x{dzgBH;ZBٜևN?LL:"ym?W qD!-5(X %!:_Cr_-7w*c\\vѩ|ŬΕfOh饙)`WNտpo u؃$ ?N>qQYpZ懌;R3im~{+ZSoX`dx{3Xse&SQUz"Osj;{+ IgX'v&ؘuޖB%Pa9CAηf&& i%Ez)i Pセi}OkIɪqq3yoQi?Q ɡ9fu+NaۜaT^_EQIjC:Sr|~i}懌 eEřy`Uy?v>+??/Hg+6 kos@(x( 3V#AYXUx׼40000 api,Tjx28VwdM{o100644 dev.htmlyev!хᕞʂ`Iwe/x!i%^9CZl^Ҍ100644 guide.texݸX O!!r Rdf(Â7 =k%=TTdXhQ^x`$z]u=:㍬6 version.tex ^>G##gql>gy_xʳkqLfP畝o>P5x($d2dU1<\#f&& )ez%9 k,UkO^ة/WΐUhb՞c`7Op>]؊{S.qaW㕋V<5Y1.nNRFm5b<%6f12V(H̖^&/v>E% v7y;!o_oW|ΟQBdҷ%oR|ٗq|o"k'2ي6z\#)L'f 09I^"AeR2zܻfLL^eEřy` waјv0֙Xà*OMJLMڀߔ^PoI|sՕwY%D-j;Ӳ:d"9tL x38se&SQU) PH,dᵽ5oo^)cY/dh``fbZQp3-V~ybgM_ok? o[۫t 7-5(X %ArҕYvƻv_:y_~~*c\\kWU^:PVyчUPK3SRO`Ф^CQTZ`ZGf=rF'&?dLqcg^qKn wd^&3~3MjggWRQ iKFD.dWf}jSYjQqf~خ;_ӟS~ol ˦ wxL 3__(7[@hG.ݭ/qGȲ1`6zkPq!ՂJV%^9U`1L> sk.100644 guide.tex 8#d4YMCrfxdL version.tex\J^JΉ=sya=)VkPZx̵D71;5-3'ܬ5B9W !jRR2JrsT4Y$lCRSZ`͞b(I%V67),N+Kg՚xf՚Y3dPXڴĒҢb_|e^%rP+xA4 rd݀LwTfGH (u%|ޫYX"a^9<t9?f SO100644 guide.texMZnq=UnmH͓xc_1.1.2.txt⛲CK)wZS_Q *ro>k.nIK/NMxk8nh``fbpWlbv#H71>=ت5njPi%EF`CN:3$vkLd4?|7~g_XV 5!43%[4&ik{/tcsz""dEϟ)o_߭Ͽ0#,5Q9y-g_&񘨽g}*3(?4$3?luGm:^8T|3y d&Ľ֛='Ta^չY6uPRaiٷ8DFzbSSsx;;D71;5-3'1Uiҩ.>%UZQàND{cСVnwT#)I`P󬒔V11ӱ]<),N+Kg՚;Ͽ>pV~3# "P饙)`3Osv㜶LUXOzr-?8u{Z35?sM>u&3Ŕ-OH}0/&k'sbc 6xk>5T]w H־xP_&xbg;&+3o5٘P k=>f^X*&ih``fb^WZx2?~?oLSۜXroի=k[;,83?l|\ՠsVx-7'CȋIMYeNhxSO0G։DNҐL>-SqKؙPs$ j߽ۧ{ީ1v >@<*s3vtq~% C׷9J-FsՈE~yߐb$ZՌr}ϜϜq2TBf;*g@fI'1^ -B%2]Y0 Y \CxZȴ#0lpAi9t4p!C!խGyGjRv Օ +Uc4^š4_|LPD)V*Cj!3Zԩ#moRE-@n6$ 7z[|RT5zA.ȅnدayRNɔThȫ"q,eIfɊ07S=I?:Ha'}>^U7mw#z㚜խivZ'i2Ztt^NN^f~UrNh6^y~ś[OE7%fpy9H+YL6-(ƍ] |,G/~#P‹Һ{`ٴjݏȉ(Biq$Uc?Y_Awv8W) {"M.f6&L+ xųA=5(osFQf_f9Fܜ,Y5Y! >x=Qy:~@ټʓM3'lcb 4ox=ϳA=5(osFQf_f9Fܜ,Y5YUY3'AY vP3Ĝ6xƳ!)7grܒbUqD82&% _kLxea?p& lxaadh41})nAxS0++ v㨿˪Ì]Ъ^IBžf355:b90&MK#g_тhEzqVɋÔFs$~YB*R:áN'Ұz hh,톅=7rv̺%(ZU-gVU5]G“2V"}%9 ;dGNV[ym~@]ĴNړj*7Vt%/'l"ps8XMjwy>Kё2A;qMIBZtI渾6xm13nNjZajvfkT? x\iwF_a΋7\8ZbhE:IPD  j緿{p%*G$]]]{WUEkNUӓ*VjZ/^VU/rK0pZ}^,$k^5keY'vحaphOw>jn4T՝ζj7N(V?μ[8遅YP\>n0H nQ b%5"c'}6ON {X}޾l..sQD_O* {/q'޿'{ݻ/ f7rUЍ7%]||E8/5a@.Ͼ'8z<0L0qϤDdߠj$?:};! `[9E3?݉rfI`n&CGo} ^p]!r]lZ'w=64Zz A+D#KJV`Iq#..O ur -CG,<u|y~<9kTټ^0v#2)c~)t.՞Ӌ?߽ͯFCr_ #e";wFC7LTP}gL>2Dȼ]u΂aeaT\v8ijJsge z7C/νB }g؝:4*x uHM ;&q=ʐ #w 9J:Fthp#{ uaQ dkYn>8*f,%ۊ4vN++4ŬxS]RkdD`l[|1l2-(K-HUp#?tmH7M?tmR|mMp}qaNW^-)@6Xgij=Ek翹hJmv>{2qU^\WY^Pn2Te jFJEiVXTA蠡gmlzxtPk!O:F3 k R@3! 'g?eau\U㴗AG~C5pC"rB.\HNpn'_vw tol݉˪9"w$F!WS( rP;.3(f*G&EZiﶛq|{qI3 yK OOw c<)`}B]'ADj2y0ţ<-?^h/mxDF R%@Vvz`71pjc@hn]7iUΜdNX/vWI|]<ؘAiE4_8XxB`;RݞgI/ӱa<=~ҝBDǫdN3up# %/-_jCcq\A@L qny}aYqr ۇʁh+F`!iěk@"s@>Ȣp𩢃HhXrϼC!5~xeu;va<"{1 4$X(8!Ltudӝh*Kyʃ]i;0V ?z\-u ,zq9'Au1>͂X4 Jypwzw1Jg4~:d#SZկLB+ =Ȳf3HPWFс|u@*FLCvj2*[U3ܑNJ"P*6ϲɽEEPe fC5Y d%qUư[7 Rȉ.lgfQ!yXҠpA-d4]U`=K @>cZˆ]gPb(wk|$vyJװ G)" 6迠jNl*ObhG S8ZB`$ c,IwJ-DL\"HDpCgU))m,HUၠy:yIlvmb .(0 QmBꪀ)5-]Y3H-\V#c^cΜ_ތu6g1i܏ >d2#Nxf>͐#&$ 5tD75tВd Tȍph*c2=FF .:"nHԵ#< UC(0hVUo]">u}TV#zWd(JqIvUf8k1 oo.(d$!a4owIyCb'V",&͋ysc< cȦ@9_vf!p~>p@`zYeRM᫢Y8k5mS&5 qtc_w" $3#H?# $άgrBKyX8gk#'U 2mAЉ6q:x0#m(. e8k".eh;FTi׸N:Mĩe]):, @ gCcA]cݓ2AHaw LŒXLJg=g"2Nj?iF%'Ohi В0Cxj)+uu Qh=c=::m5:"ܹEu5l:N/tC]mJ`(%3Y,ܚ]v5 5cV"1J#x vN+ۣxK#_i.@}xz.>++ۨ"dL,Ͷ_~k=1ȫG8gc2҆QPan| [)$Li2^6ޫmά&q;SAlq7quv^uAH B+\rSI7A9t#lw-SfT@D6Lvmkwٙz7Uzs}% 2U~g'Msc3 ~(-fG]VF h>.ʬD#kv4߉8u1AΤD58oYL#?.egFe';<չzCtҍG5'>3@-#h.,M b@NP`B9ɝ5S9+ftu( j3!}̼^a 4`,;ؚ^RsS[眬欸Lz,@,8 Dit%|V%e f8 W/$i4v"A0AD2h2oletx^SfJy(2Xbh,``b99yHjsaQnd3|k6K ɐ)>S:q=+^a裲f^O^hٵ]qOuZy+#$gl*)*B0n"o.SHY@e #.6k堬4kAŪN9\+7t5‹!["sp:h/Usmin2"3 rdc uzEAU)TYBbir.B\ >#8E KfUmk.NN&Ðwkd_$U%Gy`m;2q5o8!!%.0+5A؜* "ːxZ9q%E5v>ެF)n׻ w8H86oRh$w{er!nP@zAaP[P c׎"G1 ee2ڪnhW$Š[-sn!Vp'8P2nmY7pJV xW`߅(;QFVwhg)+Q--U3v\`+\j"eM(Լ@2- d;[hj+.l[ڇnOG_^kS 4B  L*y1\Ei.w/`:K  *> *Ũԗ!A^|s_gv1%[$q-X}5#C_ysJj>lF&@qd"^|so'wYxmJLהo\P`UXa!;OrtA^Go|\gM9 _ K~@8&[uigWJH&bC!a=M*{>(7Gd>xm`EN,𹘄Ų wU*yN7XKU{3K|0da@S.Ӗ9K a I?Wgy dQgW"aVz_ gy{O[=oj-ksw1yjE3TbAMVmjV7F.ŅyG N.懔ok,}] iRnnBh뾰 #A9Z>@ǖb^uUpDAOڟ Sk^dvh 2/2~~ւLҰ.YDCO\M q~Yu6RNF>'j7nÏ` sϭǺ֟`'#q$MKG ʤ̈3#߳WW.QSU%yOFV} h(! m~Y‘R~% zsc($ؾt@(4:%SD*RJ$ cbSX%yz̹C܏md=_؇݀5ZցN޲Zhp$]. +O?]m,_>H:yAzp ~k#85?~_ K7٩ymԑwFU@_DP+nY۞Bn0(BΤ0_'8^ht,m |1S͕ca rFaop.û Ϸ d8γ3kZFP&H9 jj|g׃WVӲ {]\@tmW:]+fxITXrM4wEw`ata|'Vt;Hn@‚N0_Aq1, >ႍT$xWj#p]( q} w?ԴmneͳZe#i,+EY)$)$ <å9W󹈛0qGL']ߨiP,t-zպ]z&dz %1F+\7j=m!%X8hCAׁh?#\J1̏? -s~`.m3CK) lG$9$6G2X2M(ӹ=r1WM/c0Rh:y9?y4 в*{elY&?W- h/T.<4ٔV8 *rD ,)z\C晀͵RuE{}g)w6ivnݠA4M%(ÝhcvSg`"NUƥBfCjNo}X,>iF4_E)6H02H뭅SY~O -+9$ZM9Ћvg% ĕ‰;fYrn<ib^ sn +˫Uvt ط: rhcIˢ0wQJh9ߪ s2  WgTW+ev*P*7BZ׌2bna~Xڥ˸Yf\XC) b9ɲ9d . SR`AZ2Ȧ`~Bs,?=_Y-`A)AUE9-D[`M:tvoE4U["&+,a/m}߹h{AqMù JN![$-YԀH_Th.O$D81TtJXOב/9VƗa[xQ3a2 gAߥZOث0eˢfpTLq?=`H[/yo8V8Ð㋋hW WK{C^[~ß>t+nVIFNNпv_?*>U'?PYUGzFo$N<8菱r=EboӓeNF_ ,2jsIxv  7^hىsWokxv 37^hىsWo  xv 3M7^hىL9%5es~ 8xv 36^hىL9%5es~ cxv 3M6^hىL9%5es~ #xv 3-7ZhفsWo mMxoWeQ'"* Q9q/a;&Nlؕ[x{JJ'ğDuP6h;37w޴>/@ 3@^:~Ӯ?6 Jw%΀J@K9rG]ǔE.(2d)XWc?%=>sÄ j8F% *ܨ7.ɢ-Vnk_g(wy7 韦.n6-_-_3R[ZY}[6dĥ0 b4f [& ,T6J`i<6nK!4(.4vv˄ y8RzU幦)eN3(/in/Ba+J_!F%ȡɥzxAT"33{-%S=2ˍosJd-ѬG3i jyF0F3a IgAI+CF?_lKqAqJfлo#ԸQُX3א`rjFZlnŘL=%ӪqmV R j0ߥI'trj%ai,|׆YZa{qO[M&f"9;jҎ[vȬ$SoO% 1BIfG0kn;Ξ7t gahv 5ntPώCjۚB->3? #xV 37ZhفsO\*Y +xV ә 6`,Ο$فs.[9M6Oȵ]+1))h^i0v$V̹͟T^";x9`,FÍ_r0nn|'_[x1`LF_p0on|'_6{x1`LFӍ_p0nn|'_x1`LF_p0mn|'_$;x1`LF㍳_p0on|'^[x1`LF_p0ln|'_ x1`LFˍ^p0Znn|'_"=xV ә 6㘼9C?$FnrfV)gImZ4f+^{+&I- xV 3M'Ίs 0354Kr:.2s3nvIS(HUH˩T|@Xvj|}TU87WggT\o4Q*$xV 3 7㘼p;@ );x011E /OTPpFL%5t7zxV 37㘼x;'fՕ O%xV 3+6㘼b;'fՕl HPxmTOLiϔi)eZJ-|3`+b-l uJQ,E0Δ 6l{Y уLDMxф |3`~ߛݟąNW~s$2FK@bl9N8MSVK IRJƼƱEGqR*ٞ<\`f@L,g o "w4|"23 k\3* A7GHTʨxa+Da zxaa,9E*=ҢxOڂ =hp;mtvd J$3; Ŝ,jǷ_HYT$ˀy x6w%~^rp ~hM`fj_bk:KB{aiȐ$A``)qI x#FC*AbU<-6;CGR*_قfKiaN "NvN$?Stjrx{V 3 7Zhفsu lox{V 3 6Zhفsu l]m"xoWe'jJ#rb11qbFw~a=l~PP".zV= 7p륧^{u~tSqgf33o;?=;U&2BwHniX*(J;C*.Qrq` S|'z^L|qܽ.6*++4Tjp}\z$K:oG&^*0[z^Mˇ'lR9c]o4*4=Xmho.e_).^.'G^,h߼5ԗ;2R1kڂ-_Ig pY*L%4podM%i޻NAIC g;p ;W ypvx^xeeo2g6TV6.}Dx@!F%ȑɥxy(] ~zL&WRe4ʋsutnO+ jt=Ѭ3i jyF0F3a IAI+CF_lKqAqtWfлo#Թ>Q9X3הt0=SV?[)ź3?ԓiչ6+av3멄U5R [lj'ai,|צYZa{q/gO~L%(E4sGwZҎvɬ$S1|wgG#?Ĕ %BҲ8{ۗ5E3d֙&A=?h~t 5 jWϾ|G$#6x1`LFÍ^p0nn|'^Vx1`LF^p0ln|'^xVMlEUMib;'MS{];-; 4ۛ7-$HI*$Q*!P% TET@ T f׮׶ x߼~mЭ?bX83 ڗJGiY7!QᄐWH&ײK{qf¬;wngԡDȧVMNʮLrV3OEYO@A,kAbht<2J&( Ngl&JEϹX|A…' ϹpK(dX nBWnbW.@~Dxa f@Yy.@SW5#MbSkp.jR6\t2|F(Ȃ!0c7!UBmz/1RDLD@W)|f ._6wx`hq5qN$­64b= Lts- ZՓ!?5՚/xH2]H+YWmcgkX{lj6C[˔lzi͈~RKތ(CZnt")S% 'pc/LfXȶUO3DU$ۼͲ5-ȒhPIJS|$=_%Yn5;p suY<4u;bu ;NkNW#:9S+ @2g_ZwS7`2.&xˇ3߂ӜMX h&sY_6w*?6`oj19~˖ t] u!vE- l_rjTR&QT3MbUo%ӊ~Ǹغ+mE8A%<ٿÐ(/ۇJR,t )F|RP\%V/QrX=pqEsi>un0#0&Neͺ*J ©=5 YeֻmϺ{.#Ւjm'9IXJ xN;1ƪX"d( 1FNcPo^n)~MAϽC66M΅#PF̯32\poe=X  pc^\;>v@2+i ՖVYbc|_zop8LOv *;1sA]ne8UG]솞)6|58UՔ^>5@/ 8w wP-Wl%jNG8fZ,@՞F3).5ki!!*$ťb[{j좾+:ڑqC8ojm 8D_5X&"z&L lP)RIQ {:ޣ$||@?x9&&.y")dzKC03alߢ͡>`4`uMʜ8.aVO⦔x;?^r -Hx,KgxB ٵӴ+[XN+r>Ɋ%)xus b#xUoE+ i(ɖ1U6NmXq:i;'ݝff**B8T qBB8 $.̬EjqiO^{7m'~XGmEp:u8嬖VcOt ܙ"h(9~8 -7Xk5ߎec '7L@!ʨ0̅5+ Vb_x;ʧ f\dXfaWH" 3P\ Ir2]_iz6g=Ooѣ'埏ۇlɒ+FrzWdժ͐ T)P ]1(9AWMKE[)Xp䷢LA6RϰLf@t4?j>7{\a3[̬~j덊 vs;v[f_8aBU8 Y![ (E jy#g4(FWҜx8'h }q}nxp'#p (pJ!vug GcH@LDD< P.7C{1CM@i+R"ЖC5ăSr,NH>4ژd!fZ&/U\7ȋ\zb91"+H #>X hjPVxV (_M}u\},J-1B"4U϶KH4pxV3ZT}~ ܰc̬Nߧ [IiL?+=Ϟ4ڴDiD >+i?}okYzsDEֵs:BYdSͩۉS=pm0 d+[*ڤAWc,P) .`!# /j@{nETFcS?M?n<VŐ7n4L:)ߛwɨ0eCo{'1NX&nxUoEUIk( )U(qKEl^4ݬA"`twIȩ2'*8"NV>#BQS@N;~~~_|s,G;Fy>qd'-Z=e# H–`4A[f<$+gǬ3}T`#ػGè-L=N.׍b-W'Y^d ilOP?_Z~uCEqw`v;?I |A?}fʬ5R}>~kWorj\M>v"0.|:₎[3jh3IA,6mwN@ m {ЅH^;@n]DJYКEW|Nab'ŹQ SӏԛUə5F1JܪmT?宾qʹQ O ڇ ,NQB9Nd7(dY\w[[[zCJ?TdMmBM) f5!8$lC'R_ObSsZプ^Վty)uY}vv27޽ab|+A,-x}WKlmWqhKQ-KvOJX|,DQ[S"eQ&EEkn #r.;kY(Z9hP) 4@})KEԢ-maܒKQ$貘߯7շ~2Ȥr-2r\f_~/"7r~-3TVP>Je-K1/xr;[+ 5[yµo"9A/<;,m1H hJTNDy@qgmůU#Ыh9BrruT J5TC)kQX3Pά@@Dc} r2?당}*} PŽ !;TJ/KAas)/)q݋3ݔ\ʯ/ΔB+v"0mzj,aR #kS~9}!Yp垈%s\8toח,dLx2/P7*F $xPꐳVHg*!2Acհv AW_(7^?7|$ ^ghDPXqӦP1AGz{z,LG.f7Ok/o Y0)ZՠfX%G2djtBǃ3/yA1UּD_- D e7P&rv0;cūcWyvb<,TICa.Ə'ўLCiĩc_Mȝ ( G*uUYqZKVIߡX́e7Z3`y@.b1Uq:TYTvWY |ՉQo"9̖!_ y%56#.VFs@nhPunKZpW[I%DG:^>؛ ʵY~nmQ1=`/fNMO]>F;3&FV*Y񟬑$\i..G7&703>5_<#ߍs0rN0*t_? ~vrs[hsρ>gsٴi`jn}zkï~x> k1]MB~;VZECWL,+rs]$i$md_C{QnH^wvhMzSz zG^v1#{_c_:Nw^mq=D}DmnG7GZ}nsISe^Y0Aw3>~q .{`wy-iuX煔ӡo:/ه#L<1=+KH[hElf\?) {2|M `}B#էɈDNֹ*&4}տpw?eP)Y$tZx Om b'nk߹. &)aƕ9bĔU XV K%L6~,ɟk@?)^Eq9h4;01͏7kBj5AKbMLizUr4<p*O=osȪf%ub$\((WA"}h]VѩpwLL&۔,V<1Z!pIl> lHq٠ -1Lun\o(J,beQ4ʛ5͌7'O{ěhB*A*=~Wp?'Y2H{3Ho1/$qVD\IT>6x.`LFÍB8&hp +Zx2PP1V1  /OTP.

- MZ]¬Ye˖6*Q΀⬆3cĥ~O7y%-'ڲDbF/hN0%|">e~+YHАh+-*_|tgB]b`ɻ(_.1j3$ۤyDo?N$N¥U@W_: b|j?4[AL3! ^9 t'y勫M ӫhfKۻFy,ݑ tKo?s$_eڊcHg-Qol&ULM9Ңn7os_Oζ8:\J:'Ii)Xav=xq%Sc iR̓q“m^-Ád>z{H2Bbx(NtIeDVy- %]@BBLQ/_n]Ơ4$s0Zt0ɮazGq#8MIiq(7ShL@I ya ?DNPr&rr+լ.+ʀ"r4:__U1@BZp~6/kAytϯ˗vzP*`ʣ+vh +>>unV;9ݴ9aTW[ W֡TTuQ~=} L['/QQ4QṚ'T[S UA)\;Z,Ʃ\f~cc>o/l0&`'%}j JV[]|@k)(jy,dəѢ^Dq;DGx0_f]ȗOqb)[1O_Agy~E~ǡc-cf} ḱ+l--AFWQ3ґ/5:6+O$| , 3Ԁ&:\@9E=8LOP<{UG Um( מ ^qJx]H ;T@ۑŶ+e.rPxη^m8sR2JN䴅ה7~yLvi u;v<Tڽ[ pHRz3/!dtkhZiTi落KYꝲlO$0= ‘xG@$ [f1>C;hXHu} b"z)߫$aMrmK"c/iH.򚰁F/np7as+&RѸ?K1ZӺzp޴};\B֯9yRdJ .tg!c&32&. ja"l*ζ k65C(::ͭHo%<9|j-PkDN8|툋2<^%S?D-?OE֩.%lߊf e.}SNZ-Hs8THrXw;4I57@KQ Wy)nqpKy8b+Y$AܙtZu3}o7ѯe6 ^(O gVO.~~kγ/)n┮_4._\%Ӧ?.;Լ9ݛ&Uyǔ9J|njT* +BƉ*qdEti.ʧ4yB&uNf=ǫ`_EɸG0kqީA8SH_uK] ichrBƷbb0˧J#/.b?Ah o#<-Ca%`6QW$Hk)C咠˖tltSKU< [}ѫs %-%m.pńv 3hR5r Z7xްߒ|AZr&q/`:RJfzM:N/*vQ} a`ۇ\m8 eu38d+Y U>`8Io 㽷ғO;uE~Kn jْBbx!Y{:G=uz8* emyp74MC47{!wq8X'̏Ϭ>O_rqr:ƹ9i~Bl^,s zr[Q]|!7 FGCf"nЇٟjbVJ_cGmmIhmjIuG#5k$_  (f(MK)"z㈃+i{t_w[2s%Ɵ?O?|7W[ _Vk&D0/PZ{`p4;? k hqK)p8B- ~FlQ7UVt j4?,3ZШ4Ob]74;!W۰',˶U9GU ޾ΖgC5?U8.fHk_429! qb`GFӵbсHrZ>Fr`uJp觳_8>@#P@e26a9+!i_6ՠF^hyΰ8X/ޓp(q/\u P#kؑރQ²S֎+&>|l T7^nNx53kcfJ,slgxu c%k%d*A~x6cTz9ټR6c9X`lc,J 6x[1%rWNƬ8RR &ksIEiц1%Nam$.%d-\ I2j^ 3;U3}jl'J-ԍ uk\z 'j J6 xrYVRD(*0,tw r \ejabberd{} mNk \label{sec:genmod}  TBD O)EE' x}UMlGb! %A@$4ȡRBʼn[xwlYffㄍeT  *R[[+zhk=ͮ847o>ΰis+p,H2jHbCkƳ+j}z3Gw]١r[2Zh*^t]Mh7^v8jqʁ;7:.ixVE{xp">JLG_ItzU;;Վ=m'vGO8 ɸWџ~ޔTY f)$.xJp;?j"uB40mI2@S< Vܡx 9Jb 8>2K4t`JaKlpW0BKD9KN-os$~CT WEmRAEq!sy] D~ŕfa2E])e,MI@Of<88Tqz 91daxT1 ICXgA5{ܦBRɄ+fTvDVׇ^l#d^ag6*S$_W1IZb [*:D{xl^В5>*` *85$sCqLuLZ~;(\j- ;nkiRO+Z t>(J '/q^].6cnYdcn:j*-GbS ;D w EY( ڦZoi_軇ڋ9 :>1lk65pR=IPl~).p^pN5fYYWIpd7>Vdri 0\]{oao^yqmj, o=Z=<nΌ^:>!.nɫ]TTM5~?[*%[HDFSɳЊ[h~ o^r^ytlk5a #'jcfxH~zst{pzggj#;t<xFKOʹי$*So -\N^Q@N{]tp#s&LhmQXsEd|hd$l߱WҍYHEy2ҭ>=59uvWT3x}zwX]~, HGM**UP@ P#P!J/" tBI(RD@H~?~{\{v33GZio:b,YD`.zhA~gT _P:zcTTWZOz|]7~~Urp1ӵ&[7F`Tq?!P;"|wݹzB_B[@.䳄>Py T(R^ <=Ff^9B6.P:|L{msڴk'tC2DLؙgifT|yۄRK50OAft8p ?1{<kiʘ~sUo96k)!w0MO_1j֙eGf=WF۳QmQi CG8s˞1Lp2(?>A$q'ȣu9P=1#f~P.oه  S%J{L=W yYD8w38!X)r(@vcxPJq7C)p/GZ,|E \{G$a`[pWR+UI${?Qt.OG`'$KU˥=ʺ2jm(q S~4][-n+.Q$"V!9mv` -PrG3 ra{-c<f9 WT7b؉]G ӤFmN6rۆz4 l"1{1l5FR'?Od>^iXU-&LKBn\YLR :8O=|^w- TR|~e[il[eN ~fTWt:VFyxt%w\ac?(azOP5%t~">NI~5LNRUj;:ƗI+5x < (xx3M"|u?*dh_( k=ޜ%/w0rsS')d )F3WKq{+$4hSK9L-g:SZF@Q&0@ДiJ%Jʔ~ưɩC<ån [ȼüsYNxum $V8c3O *S 7=(ȑ{3f$hj3Uqn;SȲiYESY ૛4ڢrMz: :+9cIeeGm ߁!VњCΞ!YYR&ԫޜkfVaZ9q筀ဃ0̔q=T;[P߇sc+4J@ԕZt;EYQ8 ̫'cGNOE]`Stt􉇔~(2` uk|XAUB +Wk=9Z696eS7"w' 4izcW)hb"Y,Ǝߴq7xEɺ{D3&~78pm0DR:΂ar=p49Q*aGZngxxBXo~ʳ砦B43yȫYt~°Vv>R(̓< Pe2ožn?,fl阩M <R8JxOMWo!VV_|?@@t HmcP uu\})FYԻm9 ۘie˭Eo\򔦒XۿCq d +& "T! =iBc!6V`wÍ,e/*Q:ˍt(}=(-jβg1˕ƜW;^~Pν2?zHZ%{I~iSQk--mITyvߕos1Gv^߃I햃 d=@=ܣMNoeL;&Ҥ#Q~(>fdAj!,xc`My[ARI3Us9{\7Me;wiV w$HMZxÂ_d@}-tԆ+-PQWخf[+wa4k7Uտ]3vഎ[4k\%۹rU3OB˚rO `q~ѷזCh&Cf\Hkyi7#ü`v _TH9D})Tm8 ʯ.CD-ˌS͐P3z2@M|o*Ycu2$/ זtqT2e/d9㔭4pdW'|R•neaй ~HMʿQ3̱e$ [|I> !;ɚWVjJOu$ j#XNLH|vqݟC /u&Pʞ&}f,Z~ 3!cjl`Yt7xqRѽNlUe]B׸c;ƮyFXeUdzꞮk\. a#4`K>g%+?}wnIZ҂彋os. E]zp` >ܐT`m\D>jV`S2 V-=,Wh1i%q%'o ,_޻]w^RF>3U(+NJ> Dyc;R+l`رNIoqj:2M\ <2b?aF 4xk%ℵ9]{*F3ڑIT/$8 +ZoY[Dxwj6.l2k~ }gH3Fcb׋t*ٞy?-.PYY]F9SxWzW\%{mA,+Bɝ-䟀&NrȄg"CF2l5 B2>jJǞ%oޛ YcK_E6AT? %W}Yqh" gyRq똗0AO\t{gx/3?K֨ VQ3ovz2\6[ݹ)=nw:z/U qz>IPt䅽]H)gD(flL"\yp݁\y^-TَD# "k9( =ʃl81')ҳ+FBEDss|ixσ=Afue?>Q S=ލ9DY^ӄثt؄ e)+*bֵ$+3cݤTp%JNZ1T.4b]\uư\bIH2ՙx'Y0BJ(ğ:*p~燼dNրQ)C(qIi_o ? j>]c Z$V/I=@_^)Zg(ſjCBĸ:bRabɽho^Qh cIakUcZg`hP!j+mm罄l2d1- xGF:G~"yׯ2".Q Ta$!q6-tr lS~aSok/&2 "݆% "YbmWE.;N= y`zǹ=!UU3pgM~c)}o$ _jIGؑ?KT3oX+}F4c/Vvk]=)+UӅJ.X>kaˁ{R}ɟDd LL/)9ЄW>k7ΰת 9^M>m螻@B$+tkCմy?Nqn_;?Wp') :A,GJVJdA8Mͳ*uxH2$?**bўty8p -4ŀ5s]F񾪹B羷"*w=»h ;0]XOLM2~ م|w "ҿcwdKyIKL-B9*F`XVRFu `-d'~&qU|wDw2/Tceʵ ynѭlj8PiPzӠ{b{gN,]\+e0ۅ;(pqvQ2sFaEDp:V-ꖲ6ٗ2RgdM/,DD,Edó0ee ;0}X¡tX-pþCs[ OJOLqU'Y1 MV;7@zh`E"/kG˶4kn- &o|@߄J lD|SUv)#Ǯfɶ|C1:X7{'| ݮ_a'Œv2bUlxy,QVzPQJ/[(t?>][ZW?IbcDk< \Y4`pƱgC{3㿕n!=EdYP̑#s8٤D)77ɲ(ю#6ZwoKhQ2Y(iEȼ,Ds=}LumUZ9'\S%u3v,BѰ}b(;kzFB8OɮKPoJljc*7nBQ* ն-s| {k7Dq=a?Mf:zL 6p Ͻ me0zL0堣B^h+U [Տ~J1PPz|kpA0Ǡ|r`c?ʑH9ERqRz+ 1 ZTǹPtAٝSX) V^Gwq8@n];[)ԧ\Ae0FewM[fNn`~Eby^}>Xيˇ[ǡ9t%r enlقg ח;lyCU?[nlVKv콑c(: yŧ }#:7bljP@InK%jO% ᙤ`#Ӥ9ftyԃwhyi#ƞ"4qduQYt{CoX9k?A`dP|?mq=ev(/Y`W A)Ϗ;ce ._^=߸$^nȭ%F嗓FjaͩYmnn``W~QF+?*,߼H;%13~J趽߇J?+^ցƆ~=bL4gz`|ڧ˙n˪-F-f?bD|9<<)qts;3AޟA~y>ߡn=irP.Qÿ!՘<cG? (aI\fAO> N Ԇzw3E2-8*?e 1]aR>+wAs`ܻ֋&t=,P^!Ւ5TP !>-lwg*]9m0[N^LfѢ WY2,KU;<,<>{ߥ 5P?1j.:4Wn"xS&`X[c%֣;y-GpFY2-Cx,Z;ZAl$ bm?"cQ7̹#@}u|x] ls^ Oy|5%Bnk6+TM n[9 C?*QL:NH.8N|dʻ^ա8_nBTjML+Ϩ.7؎0(ynNB2E9/,g\ÍȉJ9M:x¶'_n$ >!wɏF >"U`L ='ʠa.H+(֕]xU Ea/»Uã^Ժ\~`S\idE|Dpl/N7xeO{fgUFfW7 r,fVI;<#:DtKnz|RmpUf3u]CZuHKRaR3A>u  t)JH{KHD Uϡ0T 'uݷ f6X-\lNJFnvhEZPJo "D5K ߅>pc+.| RZYXNOmI/B 4uJl[kzCĦ{lh؅G */:5a}( ^eSW@7{=Q(ܼU.]?R0F?2:THspj ^R h5 0EX)6̑ĶN@k^4=y&mSOn;ݸ1!"y9[n#3O9v B׺c\`֨/.Dž\߭r>ԟ6 !W>}U3FiZ:s/$=OfN\xšH@ryz/w_gƸM751/o\wxXj嶔[bQYsTؼŻ \2O=9Mьú4Uyn2X;/7+3dD|țP3^dոB -c\"l!HA%ox {a^ߞVpm6u}#< g:sGR o&Cod*CZ)Dwzm g 5vL՝_>o|fKnYpNu5#.MSrHkȤtj OfO9&lI9H:df?:R>l7Bd^f-xXms۸\ =I22#Je+u.qҸ͌ I@ GD)D3I`BQsn-?x%0U8]/DiDeRXﬥWYwWWj&YԊarsY>a]X%bXܭ^Z iJǤ{> D~ nk-")Ak)}[+"{KѲZ*].-GbwiGOQGl&%A3R ͇?Jf3F~ Mf *2VE&mxDsesxTjM;9 בvUB# Q0EMY,6{WDbmNAu](:z7u}\#wlu8ѥvgwxõT5Ro\XdHu%"&3j$(ZtmXEpgxi-l] UYdT=*$HgdO}sJZ[DMWlpmg]CV!]rpڡCӡڝND%a,""mUX;G9di=WD^#a\$ZY'c|wR_2A=9H^DFY9(R0yhZ$-k7DM._˰R{Et}C/1ƪ.qYlnCJr*yaI|u\24 v ÷\4Yf(:z\q;Wr,)2CWHa,ikx XFh4d2 gx4|-)~6Zj3,ڰ  Y)GF(J8ڕaDTMza =ax8FE@}'QQx9Mfm5{r\TT/dJ EҢ.ôIݶ \ew4Lp R^7brawXDկo3od\ycWDVZ5um):x8`."sOP2-о_)ǻ$-z4rQ.lDgTYgӪ+~{uUgpOծo08qow',tP74Me,yκF> unatp> QHN'S=c>ӳ} -DBSMM/6SΣtczqg\&uɖ9=ouOw~iz?z>Z{OX;t:'0h8jPu!P71P"[AnAgn3i-ʮ?nE0Ɠ8ܛev[$\a[Q۳,OV5i~ ]Ti&LhR1C<}*p}75n1% +4QS6e\CsC7rOºs ,cf6vƩ;(9n~kkng' Nw-.vAL[r6 'IHRtݯnQדBfS}Bn } dCZ%lH;o웏W9ڪ Þ`0LYA\9:U;oS[L͐-jwnn*\p<G rw,ݾ.h9\>PgPNC?g҂}1!3vp<\l xЃ 1e.jpFr{q3mCRKM36d 45'qDJ+'jgF^ C>Cg'㰩' %8ϑp#G"b %v^) ROt%ݺ TЕ+F[ro{W(WJC? Q'!603'7\GaTjQ Yv]C O{`%:h8= 2Ub#E^V_VGJ-t?  Nef4 N75YMhx1ӌLdV*&gc(e0%qr!~b &kNk.8!O~]V/zjꯏKyӿGwUA8«}}~?lDAj X͉r(] v7_dn|͑@p^k_``oW[`+rKױG̍u`.;nfZ{0ޜ?v'v6Wmx7M2 j2l@ܑM> ǷV&ed`ăQn?58 Gp3j_uicOt5>zmdǝ]Y>cs۵|gS*f=zzDh%^6)pLF Ͻmtȡӎ;}ꗑ!(+DwAs:|[ǿ,EWn;u`jܫ%{i'`aV'7PkoO >h_O: 4utu1QJѣZݬ%qK4UK&Og5R:);zD?5Pm'537#~͇O! $6En^ێZxtm玙J m7A+ r/Le^#sZ7/GݦEo FoN^}WRu"\yZun|+ {_W߽|C#4j{}+o'}ƍG?/):~iUݛg:}&[{e!ŵJԺҢ߿H/{6;}FK2dp@"ndgвsbi6P"6^󍃽~)޽sʴGwX<09xu7߯<+~yNAJ X8Ʒћ9%:W] PhgiY iEߝyaAna ty@_G;v8{̜Ǧ 1[K0 2G *߽q=>Or4Q+xɃ|!f hdR {N>4R 7̀~ovņ s"8 P0O12Zf* p^r0^7ˌ*Q>uJ{Fir7%ن[{#8jF~wr[-cSM *&[dBqc0L,F)Vf'p!r_9V­,=n&z28L9bo8:73J 7Bg2 $:Dz@+ ?00aesGG AK/ 'g{oep>sR<Nqh\@#^ѻ&`$8J0- 7a#60EfGd:OiJ)wnu,>ɩlp`Q#/3PQN ;_ruBC!ne&%oG0FR0w`_|@dq$;MV=DՔPS,ϛ>~ g SyAk J(D=r7bܺ.?Vp<]zB2[Y.A81J, T!,wcwFk*ʲ~7^@.@p#&W('C:tr6Ȱv7N҃mdt(Ue mdx~sKlюґ;҃9mdԤ̠P5j(M頃/;ۥWjdќpO.JiQܘzq2zUQo5,$,(RKvljB"evhkd{%lDYHdϻ,^mlmkhtc;FdDxPi1 ,ϭ樴\1,$0r2*$1d؆'4\ƶ i j_DxF yd]Di'K*(m<i>*dO.\w ԉѳcx` 13L`ԅ| ؼׁF^(@9lGnY .ĻeuZKܚHD\ N) @9W\p0A9Ws]WC@93hEo8a~eL& XbԚ yDjB4<ngq b 7+C@AY =0tF2`BjZ614"-0vш%ks<*s H=$VX*DԴ=鷃`<0jv lAU%Z-Kı2`]+ fR0T~:n7=`44߰hb}MH0꘥ gy 9X zj^僲8|ÅG'Oq&f@;>"Odv?\QZPgY0 ½Q=˂CVG6a,?6ǭ6U0L 8";vU}8u]C&ɆJdȏ:ɗ )'q<ƏTV_~ɻ_{ )X˫"D_N&g5 8C~Q&nEm'G[((C8fV>BNoBm7UC`p$dĤ/S`>P$k$W!N8d2dzlh0I `Ql2 6=OH!eL;d5R¯ry0 Ip2ncu8D!F d2 [s@rP1I;Y`Y#;`7#G א+3U>yc6q~\\x %.ɋsa7N{[DkŤ$ 0"ِyU"dT>(aJ5V"A-Q^?-Oa@^H xd1爫^ѷ[M`U0eqF[`p pm,WIʝj{\*"Ǘ1d2| Q biZ(G% Vd{@*S7~] 59^WH7?ތբy<;sȻY8a u]d0i СAC/X+O(A/P'ݷ pƋNLLEM !i7CO U]DЊFq#yXJUOMċUwpA3t۵0"'d#XʡT vD+3!LØ:ѮH-KQ G5zmepXCvcV _/']lhK$`X] ~#2fZ_wGUh!pKE0vZF-ŘJeFo,?7IСi /C+)C* !;=txt'<9$1}'~x_wcI%,ApvN?2Y/\} &bL9K>vtSp%۝Z is@lfԂ@i֢Ǘ/']RyG,+^_q芜SQXhdgD:ȁ,6P@I/ ,S09V9+xZ#)ZT`G͎ast壀PjGdʾ L@. R3ʾ{7$NLmS =RvFVL*fS k`lZDATaa+8D@g9WZ/wxiQ^)< ADtƵ Kn, ݚ\ '}8V^a_E'uU7k*K󝪇Rgq@zBL+KNAP]Cal.2D Xo SAƷ 4)p!#\छ}B+g+EG5,[B ʡ-"wqt݄[pU d*Urx)uWN 8#NiBx1sh{@a.陇QH8 8,"ݟj 0Mڠhb@ rr;ѳ\ bB %XxN }w0O\ABܨR2NdpptVe!ֺrԀ?F aZY(.ʬ ux[H8%pNi\[kAxm屲b/kD@j"5I#4E ᠔BAy|*Uzp"F5ID,,ζQ{r,ǥ. 8H:4~"O aW+cO~x-< *`%Wt#$0Om<]_ [v8β[YI*$n;jl @DuXUbg'yBe^[yžϨu B7ܷyC99CQ{^!8P"F)#}1=p4H]@jb!.ĂZ{J|qE B]ab8b0\[Jn 3*vh.l3"65*4a^"ZD'y9EsF?il8X 梤4[K*'5B6Q+`h+S\z'U%$'8a<eKn1VIHl(| d\Ekty #H0T hаS "HmොS ӛ07wCfYO8햟!M>z{Sƾϕdv0\xbGySN3Mem?tS<7^<6># eNG믫/J`p^j…O7^?U/Ӎu_YyH2NKZWOu{Utm `ƣނx7^{Q{ UX+Yd< gV3kBxP/aYtkԼ'IԄmwZTo*»ּxœIr<u?GF024Y`hIzWsd,(_%ZE!clN(9]Gr<ȳ/Ѱm"/3i GɧΕLI9:a4ZD|(v]chZ*h\-OQ=fPtkӐ :ܱ27$!noO)XMDӣ15F(H2hmq-,8/-iy*|n~Aũo25v?v*ƙ/U! @\FY;J'>ZL/tV꩑¢*ӧ%χ-2)mpQą~4R2/tzZs-{qp(-`hqoO+v G o  諃$5p"S|4SeSjslzl!\/ePlzAd1{OMq z4>.Fs݀k2LЩ 0&k4MbeJVy`A)w鹊;˻TP2Bt:A [l}ߚ>= h }YhU;@Z$|$2`Kv,@6k!Jx ajcur|-xl}[ x0fWYgp}\^0{3~+qC#.6;8Y\lSu9;*dV@}iPBw?(xZ:DU4_@ld B3C0}V޼)kQ &\,3|iY\xd28H:ۓHzLwVssЅXSMp0J:7iN^!b@.3A-MԒpx&LGr`GjWxr)ߞ2S `>4U2 :cq"~2"^Sѭ)] Ӧ7nr^+bR憢Un,48+d`N}[xIƾ4 6_]vhQ i@Z ,bZCQ~q|HT:z$H`#~Q̼%& *kuF dz3YkI ;*5kM_gǞ  Z/q)zl.sr 52:$?Z&@ y1u0O6ғu-' tY|b nSldۇK/jYLX -x3;}DuR*anmo5ՠq,4-U]YEr20jg\Qj$b?-Eux)d1P3w[ս'f[R*ֈj)CJt3&$7(,y94'pw-B&ZȔW @vs Y:D>B f /d:_AkOzq%Rf«c4&3QIQ9u`]/píG;rC7#f.ݽ&2 v5!}<s0£R}4$%mw.ט&/xe}-(61/2Iir'lro~<DzqvvLz)1,yZPK_U'u#dAj3Lߦ|&]${X~}(٦ ؙ-dM[e2N6[ebkH}+mӂ2ѫl0*jxhiW>RQgد:S ЖE?{L$jaY ".UwgUsAH1:Ƒ ٱlDџkP}EÞTZܻ˶;-ABraR*|J].M~$;׏ȧ#GSpiY(P?蛂biڂdpDSrQvplq{xN E Y.]# ;wjҊ 1?K 8].Xzq[dtgX*tmx=?﴿Gx\Ve~Gu΁$,K4rUz1L!By-wʋ5SD(a s,_h]屚WM`S%]@?'qciz2ZYf#KG^MЖ>S/b2_?u(K9T{)wOMp>pe`@.Bt[ɫa' ̻a5kn,W[^_)m 6{^?ݚFCB0._F[Knٳ")x~ӣPޓh|;u7OU94Ž |PN[Xwp=&iq'`"?Х:)R jluSfQ" 3 1b.R+d4jEA!M ~<<>>s5t/~j0[(UPؚfy4^KR/w44[;~חNL?`{'(lX(?wGMu`:%U%mKuzPwP[ا}8#ϋ046!K/#1 =p񄐭=-Eq@D& wâgx?i=_2A`RHÄ)p虞25 W `)!:: YГ"f?WSK+-eaW׉n0K7 jP^j\ZF_"xJ޵_JWBT[QwjÊZ@~_zTF5JQv셅d.Xm)ng͎l'ꃳqK$Qj|7?O(qv?^2w$6rN0@Fdtbt̨Eb& $4Ɇ[bRܝA*̲OMIiGPw$înIȫ*Mg9iԴ X[梫1{8yi"c8?˄J2P|(* |_N:KaeC^@߆)m7U]Z&n}DC5MF"9;INLoЃVVDblObIx?o%\x<69D 5vh!p1au[V|I99s/$@N^@w 徘3 $%j ջV즬Qv=+LH͖&HIJD[kR)8#gפ:EM_:2ONWޏ΅m mU:Q 4.T"~b YRpy\+֐ЉUJxm^kZQo1 D,?$Cp"ȁPrߖtA"]\WI~i"}vSV6.47fܯŞ2yn1w2o)Fp}uo)K2FYn=K&n(ŝ\"dT0B$CG>/!iG=C+AОxZLSTR&0SK )ٹ~\}S` Vقz7-WdZv`TjTm0`2\K 󲻚[6taU`{b5BWJԸمsZ1w,@bh/Ovna(׳. yt 桐e n~@k)1GE,Mp36HZRBGjaY U U:#3QB@~íiWo8 :Z#)YS /^kObYpGͣ^z͙nr_x@GsmA htE.'#l70*m$>V-ٝEĬ.hjw4D҈%86Mi+.qaf..y)EӬyԈ m@[P JSކaR3| M5sVH]; QH |L[s0 tkIA.$hV'2K9@<%3"<lslhhD#a M%#NԎ2Rsc>nVVa7OIg47FH8'xGΈi%k8ml(I6c"K ) Ÿ Ur ||wzadî4Hs孪@;iK\`Zm]jE`?*@sfx!" !Bs[p`3]JB`9U7 seʈqRa6jP 1Rڔ/F+CWrb?UZoՔрOpt"mqd:25=KS=Cws헰E^jƊ#"h]©wWjOɋ> {{iUn`6|Qn}/3q,5V1aC$gg-[^ʝr]C™Q4\;ӺEOƅ?SG)~Rk 'ma>e7wj/'?)@?7a"sl`zZ!#KofVZrNl8jʡ؅]@;p-3g=-tY ,\+DdJOQ"T֥^Ĭ_^G0U]^ U?)Ү/A-? j_/Vq8`P4Gd"jF]^}1ӵQ%;ZjD:32 mo'twdF35mSÂ% j:B 20nWn 4Y? *w4#5=am TUq*;CfH1Q-xg>HG ό:ϡZU7N%r{$_u gMU)cw>0@G."3U/.gD=Csț 8(̘h0MJ7véˉ3?)DuxO-? tKMtnsOՑXC}-9tEYҷ3fZ[Or r%1 LnWu6Ty^;vӢ"N [ޑ+r g3o[#GQ/.qMm4^Y!{ 0S%E9}93ywLGy|Q)V48a< ZWu>1uQ$&:99tN4'9:zEw(,/KI NV>1T"yr;Xsee#p >"<VvKKWI63jk99C xWad̗)R2۶r7_{AXŖ e뜲pJfb7P'llyiGc0UsT,1 :H D Sdž0>`=Dkf"]$ GaQtQ}Nd@7am+~h+J4C4Ke'++*£XT bB/}VFH[)8F#'}j B+MUwdLq9)\pg5w|4FdÜ3KHۈfw-1ݦE4:H>ef^ҹ4eVAJyp" DI{,cfm{ 'ųgwwRvBT'] ,9{^@0 -v٠򾃧礹{/ Eut`p6nMTʒj376,yy@W~ahks[-kosew=o^ͧ[ó2XyW}^[(϶nL?צM^=n I['WQ JbEU{1U "͜XtQx~z>sh}# A;4jMr@A^^;h6K}屙^ʈ^c yxʚ,*k^e;G.>:?G^Mq d" ȣ~3t"9&Y$_єzl&ַ!unS` ʯ\=7텖~Ƞꔬs1^ Zb8_[yuȶ@  7#8TߓwyΫv*M=–-qL?a4<zԻS˟n]n5>G$ e4!xn|ƽH K`׮ǽ貵9o"D.Cѥ7,IO@oN P(8̒]xd|6WG?fa=G!#xu0!e7Y7k"Yc1 D 9ݯՒ7EK#taM{s}'Դhھ0][ŭNS*p"ʁair?C:m9nncHh gpU(-  *!;O؀ Guq ,FrΨ`b+{?W0G.KΏ3âo*; *d/sC 6TޝjUmX2>!!7*3A`ņ6F y|.ıwoqo*߰d;hrnp+@?La'0 };Dv.!8)6⨢.X}@;3FAmp:TR A kc3 s%C!̸kI\Q sݚ8ӆ_dG) :"u*"glSV"~@*K&iXk%%LAye:w]4;\BE$ $5tJL$%IXm]!!n2] 7DtGB&d -|1b_Bї&rE.g¨DV6@+ DuVf;IU`IfKÐ nt  .]mBkHݠ5 ŧW(8+Mn^*$v~L_ e5 L8xhr QO "A᥈ͩ`Q8,MɓPJ ?u/q_IPFS4dq{=f,Iz \XL)k.:t V9B0ʶ@t t2T1SwcU[ȥJSj4m;u@1&_!n;~Bǿ4$h0 : EX10/6>3]SQdQj| oT -St7㔍QVkԅs-|8bZ})|CU0aLr_WaA-ü;~0TBc C_|'LEd"b18jq&^)4 qiAeFxDv :p\ $ 8oZcRo 'E70yEUi tfѢ< ߝO\"AȂU''`iHhĦcXEF¤{s ~=oАf>Ϛ΅P;Y bpHO/7: 4eA[uT'C6z s;0eGH!yަ-Ċ* ᗷP, DQEsxo"y6w"]ğЈP=ğdyʚѪb p64rOZTk2;)UzǕ4g]ʂq.dK8?“_gT!]n=I 2CI{(G+8y;u HKlLԣ:Ykumj!<8VCƬBah+&> dP/k7j'(.>q!obh"F$^8zly& "\aLbcK/z">9O.+Yb5:OL2vzw^_D6GtEKýc")0LPkA48=pnldIweTJ`32XJK?7hY(Rۄ Q8'>zUdPSȃ͋@nO[j.Lar|N~`^ab1^*/+F +@QvO.Gٰ],A@4V]ӸD+/KF^$7z]O2$HhԬwECooX଴87.}M6U##;؜O8 XM+S[chm@脴! |vټg{r'D{۪pJ*)8@$!`:, BΉ4NN+svMpw)s:Bx"7L.ʣ*R[O‰N{`9Bgm)(`>1ͰrbJ$wUNS$Idy> MÅ %:½Z 6O]Qk:b bN-:F( :њ-itX]4#eLqcIsѾWGby!5{^-ǻCmOIQC ?ҜZzjR%(% U5Sסef)gjmC;; Q2D I)}kN:욭-7'Q[?ڢX> \LA[~pM3aߧwAV$#. p^fĽ3T3j*%V>]8MsY?ZoY>Mۼ FU\u~Mfŷv ̆uիtS+~h'Uݕ 3D,@Zf?z-˦Pͤ<ᑢ--diZfNBD- z`\Di4Vq_qG\-Vs$S{*/(A2Z3)%iFڬA<^((ovQ $t&ËB4>8I2Ǟ۰%݇ 'wXw G&iߋ%3>3 i"(U?X_ۛP0QfӘtTHz.5a,Y3̾Vʞ`mK\,gsj3S>JChxo0kKEYa3!q~ڕ%ǻ T"͜^Yc7F+Bh &=-xy4NY#\ T;TT-JQ64PY;/I*7Vvpld;%wU6y,B S~'s)}IV'l2kj(!]:]FN,7s9Խr*^v^Py YIb9ܔx9D3TW rĝLES9?5\QgͨP9IӳGcp{=Bw]wA<m=Z{# KlHOTVz褽' "zC;Uhhתt`]EWxT;~MmnBc-e`v4эB,%*4C9b دz=X)Y /U';괿7+J ~G鳖Oo~C|noF&e-^ k5 !jb~+ uW(0 ZD005 .hbXcSNA "K/ι4n(q= /FqAic}d@\f?1 NJk^.h XRV-@uOs8`I.'%󄊃]7LSW.V;nK%Oi[.h+U34#H'^VGy KݤT+xzWa޿Nȧ#2"` A%4_[b[hy 3eEt_VkB7`,⤙t g+.z UK1A"Hv8׵!Gb6\ Qn`Dϴ1e|g%uGe?#>fZ1fxHlzVي޽jnbU(3oWͺpM}K :؛ =TXs͑khL ՞Fл؄}GQ4F'Y8;p eT12,Q2e$ןit?k{DPmy X_hfbR/,s<?|,tn</"˾*+uB|JHQ ےw K4eS+<`")vJ!Z9`9E2vX KB@xDa5D_֨thCjIs}G{ϗuwnD@]acYp'A Q7$nSZ<7U Z( bԃ A!#s zbIU!lAUڕ"z/љuz%~x,ɇ?4ΪF3%vmcx[BאT uZL\ bNK.y,-@* RjsZʱUw -bp!׏q %HE%Qz$4w\Ui,M&y.ݍ;dC%'EyJ ЁFș-KE;S㱚`34ߛťpnܥ#!FPDw_?PBOyS'c]qRAwR *Ӆ9H0bLlοJ[_3+vey@DT1b,6*_^iIV$pzMM%ZNmFxy'̍/gsp!xͣ(h] *ٰJ9td\8S3=]32}D+bZ͈}vw*XZv{ʠwp9y^ 2EΤ#:%߅% \w;wI-杩),%}`,) F 3ɺ ǝ-w*sJO rҋ׆1-WX*d\ex ?zvF Eّ:Ʊ]T }JS~+FXn6{9E-Pמ W6h՝0)o9ڹ{=RҢh4Z:}X gXN>أgj?H~FFF/iv"# TMm,U_ -qk"ڑlU Oи؞pbK ,sXu5#Y۽1+-*v@ ^ /G1 єsl2"i@" ML?΅5Λ.6X)͍Jh<>qTRfC:zr{!T 4ȵ({rS*l"^%s6N6l-X?Sݡh}g:SgnT-,ܒy"}6*=.Y<$C`N/b  hENDճ?Wx.:z(E!hG x֯HH7+=竼Gtѯ[S-FͨcY=˻9@9cѳqu@ kSx\oч|& )-i&2'n6^oZq?:.;Ua {Ik3Є~.Bk?rf.4Inڃ# ۵wkL4w{{E\0L]qT[?ɗT):0Jsڝ0g)lM DI# a5ݘn X,GIp!^Pq>Zn#] G2prQ^s"_~'k -C-\ Z\bEO''\j{\ .D\wjAkLs~1 gnZBp縘Zza>kB2a&g8Ek[ &vO^11k C:IAR.{y'GJ#'$tutq&DBqy0hRb$'PNj:AN&+fT_~P95tdT%~~MPIW0Q7q7Wڭg,'{ )ٽ t=ѨC 7עBLy%0EڀT^T?{9Hp!3$]+3(+A%id /=NF#0\*D0$&ryдmӼh\?Fo`n I~?94[F1z"w - ӘoIBZA5.T`g7DʤhN݋il0ϤW*ԫufoR]1jXɫ_m-dԚP;hQKOoȉ6+r+8z4\|&g!fT}YA-$LȈdw-Zs2j:D} $Q`y5Nn*0gE«0uR00́4]<0ΗjTsP3D1̠Kzt +8$ ! y('T=I; @]3G%bCy0O Յ}8rp98aZZ2L%Bn7`z2@09m3@kK,5W׆54(q=q5@X) rnI`| c9$w^pB.,^tvaĮ1TBw [Z9 5b oInNS3 1]qM:Jh(15fSgYo !8]hcҺ`϶}~ ,H8.+x ]}h3&cR^.l|{K!=Cp!pCk8L/o\$,`~O3Ճ- nE4ɗB$e2*I&6X℄E.ӛ.!>:ES+ct!dKtذWB9fc]Ċu|JKJ]> Y s-v0;@@4'U)} <='tI*fmAmΘ*"GbՍں8{7ׇ\44 HBe( "Mgkə Bgj8+E"+D7f)|"q_Xx<@T0ME@(Wbrw8^:= WTC"ֺtFI0&785IHxȦ(N@]詂K 2'6X&.፿tJ֍:. I<`]<7AE˥A JI_W1/CƢxn2dnr$!O OH\`&Iy 8HZ%ͭI@n!"e;.P^&u[2j.:EQe(S6 Re4-?S3.pV3e!ҠKS{GLKZfۜFv{|Yn  P œæj/KG L&Zt>GLID\+A Id&^>-0;-8OraD"n3u.8¢A/q鵹tr؟ 3 /ѬcJain!"r胙U}~3nT0 ?;SQJ#xsq`m:D'r{жs>wvs+د.:=;498]Lm9 ·5@KۢdnX97{? 9V6[WsOctͅ=r~T"-OKRåN2rtеE)jQֵ@'hZPn<CH!%-O5% `fA{aſD3iTȋH "ev}:bO}-įE#}ĪVʏ?W_beӥ>8ҘBD3fATҸ3(lc *%N$A/`Wؖʂ ]+>[v܏ s"g.RWmǃr;wN(K i]%GBH'4 3ԒQ }:PMtMe䶪nW/_R_@8O+.ca-3Z Ϥ#s`9uǓqpϋϨtQj&>ǵft Li3kc$RXpڱ MXMEjG VmykYI9#WKx ou'k%-#тhs ၰ|kiNE{ Z@3eQT4q_115y:U:者 |~j>|cE M{"d$-zgNe1ǠYIs$F \{])/Dh:T)۬3T~#23gfܐ^HDmb>pijBSޣ>#O) 2__OICM.ZrYrq&+VÐi'r…- dTe͵E$ B*R8 =>Og<@a%g ЏNzk|`x &a ٻ 8|{Pjc*o$ ZL]P"% ~?D$$ ڋj,/J sl ɘ3҂5Pz *)) Fy(.!VWQKyVRX+zЙ86NJO@ndgʛvMg"J29{}Ù(M(F8NX(ni:RD/0y:VlIa~ *q~(L2f4(g-w"5-jx$H"K8D-%8W(_ 8뻹n֭t^Ә(L)l&Z6h4X.9`rzاUU_U-ϵ(` y%`_ܓ$R"`%LVIib@b6JԐGSAfgdiV= s{9!roG闣KS HKnq 2KQ0CgE-fzSw[StY!GEf!6;aC_i_Mf45?ƿ$$% 0k[y&8hj'fsh(9G( ]Δ a@ ` O򃝩R] 8-q3|4uU5J>e\mŐB^(Mrt0j)+Cf+ Ǫ-%i6^fK;jqNqԤmtǸ@ޖjKw,jyp_|ՎV6%!W wUذl ' =>8JGN0`4-q a͍5qb#z|'wznm<7w^@O8j<燮R5A4YiyA%1vV*NP'޽8E]rrcƤ< =MTPx0?f3x2n"W︳JYmZz9$k̷Ia Ony:x)xpGܥx&ݲpYUɅ\H?T>C2@;+Mz~V0D)k}8~B1(Vt {)ObádvS:hD nYmvYk@[LůL wFlo=fNEI:RI S~PbZ{h"QT0@ iG]kyPxplv=?@!y&'n%% ˅:6l ACd9o~?8sDq`>ѱ%#`8A{>!ik{Xv./o /LtdO^Qy_!]ZWw-XbZH.yny A*s7)̃9I iH䵎Тg^FN]i} wNf,m3*g@s4Wk]0f-`~BaI:P VjCڅ%.Pj 0 D'U {0}ʼv F2rj_`TJ-c]܍ 'U<24`^:d\YeI.tYvĒ8#>39Dְd@gnttddw ury Juu|)޻u]yUԞ&v)q cp3}:}m QqZ{}#qvNKse"zِJuY.)!p( [؄"^  MD-t%` f>h STHcW_Jx]:=.99NlVIFg|mRXǰ4q.b{[2ŘhejhJV#J Cɔmv Y+mɾ4̕ FUc"ӆRчC&&b"nm20X-_6=+aPﷰ&VAKPNqUPk3<`Jb٫J=ɀ]|_m2yrX*)F,Bف*j\&u7~At?. >y)5ɣ2nNɎW7ܹumԗb9D5inMGY۹KL.-k*uoСh27 Rw m/cw ?>wƟLMG fBVxF\2:&F{<:zsFy_V=OuwYx㫛ǵ`xjz;9tbrpG+p|m,.< zƇ|R}ZU^{=bD/oXƅ~,<΀wNhۿo'%_T9EtQ.0SyQ&n7&*Ln!Bhfy0)Tx::JGS-M7|KG}AT1 4)$HfDh| #7Gy 7p %CMdr }PY Ti2Oͨ3>ZAwE-]ᠠ"6BPd5|?RNdwVn`: &ҧ۪UD?3' 11JKƳnF):cbS&1V{r~=Ŝ*b,LE~|LAN3~L[C PRuW<ᡟf7f^p4U1b9nn&aL=mr?4,|H'qG߂ɪE\?@mn8©B̛fI«"ߌ_îzǩj,"3KU'qm:ȝh' ^͠jFPݫNvi0<=R/[ to[L]  ֨K !2䙖 Q_ C?l=n=Ï(veʄ_J M4v!ȗ&(2:l+֎~6͛7).d4|G.pY--3`UwT1y@B8^k6Vތ8|{1&^dϔ#A)K'Q#2BI:1J1H vn6ޱppgGpUCșN" pܼ%wi k|zSl\tZ3aj>^خQeԧ|e,uի.,: NRK]l|?@:~I+WO]u>і K\v}<ay`W;n֓U-}սiLue>cjM ** 5=I}bðm=86jt?u!t;e$&ުdSP-+M-\҃EЗ#)l{ɓd3_G"Z[^8AYVMe%DK%a!@!q=qn!sS~a)Z4Kx1VZ7U>OYTdzD0+S@$!ZrRނ'r-2G;= |R_og@Z‡ hNk9^}B*=h*szPW,sǮtpY3Xxiڍ:߅4 e SziaRBMc_h.cSD5Kn&PRRJx²@Fv7Aubl\Lvz>"p6JUVG˷>$DQBnm9gЋ-/YTvյ1iE_n49g 4L'Шգ<p*8r=Q7AsIYnTWi-װ*QGoodT72(]Q,3 X)#ˆ},y=#R] @kIPTeä/,5N5O29M\;bQ6CCp%B$(Esu<#~*@DrO]̬6-h YW=HAӓ3ZZ6B"9d 44''E ]~HНT|!fX*5cffQXQ=%muqRcQ݊ g>.sZqQa}q"ed?f]*噳w'ap!ͧ!x8bJҢ2LX6\3ȖS ef3}(V'&eT\ZSǎ?wMȳp"Y !puz^1P7_p6NGRN]*!a*Ϲ2V|?A -IsbwG¢odM 4NzN4҅UJ`=WA5i9S1WNᮊ0A]R d^m?ˆ+M٤Gd /:RH1.C"I[(PӮ|){ڒd'dǕė :(8q b431w%pß_1 &O_T/s-s<Ǿy̯.76-Dl5]1j\H[`+H֘_m ]H+$]ɍ SlVoߠf;VTԴe|3[}鑃GJKfttjij";Q\rS92 F̓F44m' g$ 9l[>-#KleUV K10m<.'b`-ѹ>Nr&] $SBa7ղm(t\bWB]}Yv$l1\{7k ýp:u]:Tg<r^|*ɵ9:S|1S wJugPWRЇ*TVZPiY*E̠SBUNk(N~}y ec%lq{KXLxf$RYt¤7FT#'=MyAkEҘ>ƴi"'o)IܕdpK(.}?yLKyfi-:2I1ȭgC8TcZ:A?Y`Kd\(ZXP >);+\*0N?;!;h<@npNsK] 53܅ ,3>䤕.|iSP;)*U{N:5 ~º[蚍>z%%/}C 됃P A%ES ~)+ZFȣ(Q k- O7V7I[E$M/$}H?O8L1Ȁ)%珉IqhLLghYŮnqVؘ*iTXf>d+>^=#J Jy?BXAn$a&vb߬!GŖ̊-eIǢd0!z&2dqhWeu_aM邛ٕJ%/R_Čqc[I}$Oc$K򓙭6 8S/e_:ghToFC/q|_;/P>bf"8Ru|ӆڼ1>Of S]xБԜNܮss SoMֆ8Ob#_'dk bh4Zih1O3>$,ic(hĂ~0YlJ*er59w~RC5 SdƋɦ0N}G {v:Fxs~\WgKe__&[D[X0ѯhˢQND ڙ!)d"3D993d 0MQOs6Q Q*CT*5^`*/!*O$L:>ъ+96+ݤ҈[@*b[;BZ Ej9ؿߤL"\_)@%*c9#Pn RJ/cSa[J[o֔Z?L tBR"rJ;*`vRl1|+vЋTDŌVWw־,/QJT t˸:aSKFQ:n b+@gI-J*F7+*l@fW?rhGS⣣cp;9U4D1rD_dѽE[?/}wrArsD֯fVN?)Ӳpwv%m dz+ߥW$7†i8q+hb v^:ZLlᒑ`}\<]<]. cPR6gwgYY kgwծ#o8Q^0*3y UEj:=Z0w D15Lבi_`$qbJiV}MPJ;(r T]e{6U?AOs2`Tbsh-吣j<5f uw,h[82v M'2P':jxŻoSIT{~\8R)͍xW\NKfuv:kݾC*Ƽ[8?.^Axap|~숙fc_hPх ީcMa>Qm7d%+"pS= ^*n)1AC9vU}][8}G:A PGV%0dž&}i&kW'i˝ 贪tOBn Y 38+iS kpEeɴz`uw~$uz>![':F1' E7HGN[(Xlc;L=7P7[uc)1_P)EA BTCE Pŗ+b! Dkb?*oii:z@/T6%/$zMEFmSVe|كy],?GU8N39|UL45TU^|vD[KK{R$1@]ӡWjKBS q&ސ$ˇFtPq4ר_f(xP=lc yHk4gjSR57 (e?DgZ=v)]39V`/K_[:J:"wvv/^'wFT?W4G3ntP;Nt#kި᭗3^ۧ[`n1i@W(KS 4p0 41_Nid v^)<AdBt.  $$U5; $@9fn CyG%o( S=~)' Zf&2cOqyXC7nl/ݿ."c;Z Xlto%@300Pu.F))5BfX .+0RvMHy{^vNl6,6Cwkz2fŅyFO%DyV&42/nT ͤ:.X kSVf%ؔp~OX&-.b12KLzNIt(nBI/tA_}i \TcP9:غ8jF_t_t]H1 s6V(<5 XM/|Z:o(Wma,h0qwQpd8llF(Sݶd}W0q(=QD%DrR3:n.&{(@jAI{9 X |)"ɜ;1ʗEbr @or[GYaU!m AJC"9±*b:≩䟍KB]wh*jk~u%\tⲥdȬvN7MS2r]b@YOJ X/V(@Pޗ(V"eϙI^Ú=ך8զH'gIAPJbB$*6g4T3CKkkO(HL@㙠4gKiuHǁȠǥO7Fa&lWzMTGpp^ݖ-`a,HSl<c|.}C 9`,0x} xѻR^˓OxQ."S?c7æ ^1k e3bcozhAz?>5ᱨ&Qu pѣ"lȮoy0t6= HV@CCGY,EѮܖ[bJ?4ǵ$ 3@Qzo$N a8 w*'8dt qTݗgDLI&Gj9ɼYUgx+8Ix LN9/#!A _5d,{g7tD~rB,E͇21#y9y{=' +]@\Jeې6 culG .fk37ܮ!T)ѱ^qPevۓO9Kq D1b(c[F0kirKWpװz鮑o3ykn*Ag/77=-8=ɓrЫ? 'y4E+7r1BnX{ln$p;՟xq[`鶞l֠>֤rQ 4d o1R0 0~nU>ϼM~u?lYl]xj[' OnxWh>x]I /7[*Wyz2ų3 gޝ|euP#4q}e-a,<1]D ✾5a2m: b}^{+:mb@kOVO&N5?1EIGS;ظ"Kr$HC EFg)hCϤ>?&4! ~mM,QLp!Z-V)\1DBUya0$cJ+4:.`ԟRQۤKsuH0iױ {x( ?ZrGA^2z9Ra3\əͯ3UFNTF=>s%@Dkc뗻Y޷[O(8ݷ=Wk_,uwOBWyhٓ㗯zxٳͧ/~p>molm]w_.o^<<9xݫ Ǐ~NYvf? YA$0ܮ^e ,zBBk[ߎ dٕON'OKRxɭ{k+ΎkO& ' 'h.l՜mZ|SY=CH;!@"ll}, OEΜqd1};>8_.OH zf{<蝸2OHŠ;׸{MyاB8dkpf5g/;nDOϻmv~漛(:W)ujs/֍Ḱ'v~]VWPeq钽=-P꿟ooKooTJj}fO_9[ }<Cb9D! K"15qx[|C-mۂgҫzpJt[fqO_m EfYySIaWբͪIL5(`{v{$z|\Wnz_1ks9!{\Ƣkp|^95dnJ^x] qכV=}"ˬ eDݵE1բ6~2cIE֬}`^?S5E`Dw{2XKy?BKZ^|f[DPO{ d!KƬxUqP5`0UM4,p@k,Lf;7':˳i%fnϺ;mr[zkw?kc7)uE|Ѣl$"t˺4)?w_>E0.@>坒2$jt Kc'`Jp-}۞o=땥ǡ/Y /ÙrV/n+P =քڮ?唀RmVT":y.o\н^m,~驦6wmUɅo&= tGt)*6J$= 0]@9+N`_nRh4>Pį"*WEsPƃVFw P^q ȵ뿬|\\#Tl۠Î<{0s7vA>~ ʥ_/)h9D Xj\>~]Ye-[,{wk2̽u[ujѥhF OdJJ?1a 2Fӌ[># N!n5{56[-0"8!T=>־(WaVQ"<CHE;ki+U!)g^̍GҒ#{j;|@^a˃H.9uXaid=D'H (`~Q,H5=UxW*!<2AV(ubPj#z}b5R,dy٫* YF鑌2z*<4gO+<eSg=m9:ЇѪ4XѬskXdmQiytqQ"1;U8 -,5O-*NI5D)Rn0Cv6Kӄ oLP^}bb)-a*vonڪșmV.͟4 "6\uxW^9*YoBMF?h~da9 P8 _&`FKVP& B$̌I!z"R3Aii wS.O~7dbӻy7ӃaR:€-#n,GPVtQ]Lurъ7*] kuƫCP8ٍ#}+(E": vMʯ'E죄5Ԯ`<uLjyǪ >]6rmCo ʹ}2!_pΓ1عÊg<8=ś v4ntxjTj.|[Kf%p\2H!~E;ua=~0xy M׷^K>nG9UohAfB`{_%_mW#0SK4hmպb)'HHRC@S"Nh~2](GI4/w 6*iTq+lu b$f]~\7*NPar77xZ]X9R* 7A劓;WoȭAZ|+寭t x60KN&NMŠk€W-:$m6!E"y5_OhŮZYR n~h_ZxجYS Sy#cemGZ & s5aܪ1EE_)E&ƉtB R-@0wDD(muڱqcdQD Szr1b7Dk鐒X ʨE};X&U(ёɔHx|N?nGn%ʤ$ Ʀ)RݛW$]Z<?w>럶4~OFqqJԡ#.w/]d7N0\:0cnq$6LyG_ 6{D4MBYdkT59Ȥأ65.YL5-*jZkTɚt2VH'־@&x)oQ@ǫiCS,M' TPl |_:-:~ֱ@^\-te'9~ɔtp B߮Yu|l}J~5yuz׆+x`2rJ>%XM,zkGjzаN.V6*,Rb7Rbzl|bOqI켕ݡ̭K,ؒl.IG[< nZ N[4H ؗ"+7K(ukBǥGj#h-7.qԮKn _V Kn͌pσZJ,[-3N!VNtH*NLrmy~^ - k3x &pa7 ~v0Cm?Rs}#V8'V rYIY~Ɩri'c;e<հ)08Kv`^jDKaTzu?[$MpZbqA [=c7O]ݗx Da۲yh: JJ/: L>*;#|[6_tH5!K[ySbѺp&'tP+GyKFUj6gv:iNe2>,2-̀6]bU]M/;#l.}=?QTV,B7łWT3`~^!KmM '_C㺟昩Œ^WI4,W)!8v}=rOz4~.5]v3t@2.5$#‰U) TTΈ{-.aM4—=IbКŌ)Y-Dc} rqQjnL!'Aüx#bsCt;d5r` 2Pf!~t>ABsޥo]^\%Q¨ ֣׸w[鬙wX[m/1ά`bf9Eb7dBǏBS+{N#80=flh=Z5J)*x%+Y 2&Ŷد·|uhp/ ܠ"&[HfEc>n㒌ie+ui1Ǐ_aw `$)`F0f|ڶncuϰ3w]?U[j Y]dJap3'fhz2]Ob]Uk@):Ri{'&rE:)}AdUۼ%²U}v}ȯNT28V[5F9٦>y"eZoaᄚG2U+sXJx) DF7 dIQΔBj(F7,`3B+] 0:m''T3Ɔsk{3"Oj=Y1mU-tmp|~ FP.z IvB;kՏ߀aqDX[^}q.J= ͔PUn#sy{sjJYJ Ed{M0!ߌ9JyWr,G2`(gOJ GjbK@B؜l|iѶd~]*37/)0swt5]рt cups*[%pfhwnZ STaaddl,u9-9!7R=Aҩ64؛s6ޒ]qj*Oڊ̠e1y\XQ|1y!`9vhKt;{1@З}w XGzb,ʖ=piVM}ew㟌bxE#{]ڤ=9 rAQ ߤ{]ўb注^y /W8) xrr̸&4@ !ȵGV:A[(77fEZZ|~KY;{Xŋbbk܅%rɃrȜ])рDyGu9#{ny9   *lUyl̻M0.uB/oPª[(LMǥM Q&_Iy/w.jzt ͩp)r.n0 &rϖӺ*z[/qi &z燃Ѫ>ZrW j1 >,:-m&uKg$Tp͞iy`vQW! F̽adlp4h iVdaĚl< !ySli䨅85@KW6Su%nj]LEwhDM5 $dZEab>$ۤ=f< ?U C\F͋d _=x{::?W{{e-I9j Ա@).nHAͤ-)MeIp*=\mÁ' 0vOVxD6űE_=j9,{E 2y$Uu0=&PJ,8T$CW`Y2eIm$c3ת'JC$h9i%{¦I:jz7 ͏r7(l)7Qi^*+/h[O^>LcMzLOlg79pBߪ u4~- }7O_tJZ/,?zw9qEXYh^1dFnt{ʫᒞ{Y`}b]ICN/#Hczbq1Ш ΪAυ| >y SF s,O#6Nnnz|6VW>AMFcXJ`5vR<`<2,ztɖO-` UZKpxWu{3<+g/;,cIP*fu4)CNz9c}~ nAnU5 ؐUn y 4b}_VLPA,/P n78S>E,aLe.`F{έF2WSlˉO̹* n>,#dH1LMTRKYx K,e j=U[vH5_rg`2k9\XƇ+TADm\B|@AU#$\L8r| I94cWIq)=hܙ*ZyG =5N{o 0!VGaHeC Cc%2ۜNQW+ * /j(q5r σ (ithrXN_ ԁWc毼KP+Tj_VNyU0ͫi.{b ;7c*E40RU)Ȃ8 C%\#O"Fqz@eUQ i<~D;{L r+% Ua?(WT7dBa_|@O-gbđ V1VRʹS ^˫|{4B IH8P@)\`ؚ(ΆRV{DhLMNJܑ;}"ctHl PhT*Mu­ewWAITb"QQ )B9$5)_q T-oϳ33\oIăhMDU(<`,w !1])m"WcFI1n_] bU]GbN&! 'H@B@#%Aqp >Tv(89M*̺ .L.Hw?4.#v/xL.vk5q(P;BK I2xIl aEʽ ½lMe7d-]ɪvS_L"RNڅzVrMFuiFTAikwwrt}B;=fqC&QUnv2/+sIYɹ%ҹCϽw\͋]~@TLX,vGѝc 1g݇E.$§wR̸&}9q*0G-tH6I 6Q蚟~8<`Lɳ(f<;%Z]$ḫ$g- #{;2rLw!uZ%albtI lf'/! TadܒSX;&=sdMTnCհ;"5Cnp?O3 4B f-p:y':m`@V6FOXK/7 Zi^w"!c>0Vh!)1,rHo_=c๽bO7e{C(Y𛝘9,U͹+'Td=GzpqBP=~sut3~X*0_lsXŤ `Hгո-< Ð+bd^ JG 3e_A2( _5tgO\ci}< ; 3iJ-v\sBX9ˢpi%ǥq4UC&?ĸDrju&_yDv nq1'!.5Y2ttsLf25VOI˰(Tp+>I`b}'͆$I]p6E@j7"/̊,K'" x[B˺ky^6"d@tIg_=ac يG(ajs|T83hm#-r[b+Q+~>_?]|z4OU'h}:`K *^NH)V11! rPBZZVE-YDPhSsvj%Q1ZC/N%] #LmJ+ȋz. ,kW*#__Ǔh QV|Jm81bv~ME-)~w&:72:c8~G'hHdR3ya+[k,nD)%}Yv.iwKjwIxK. ]YbHdi07\qݔ9Sr+.㭒i(E%X͡oYH[K᳤܍k)|)!++$lV_rC49j.6qLҦ\ &ʳ~>wG )jP kV{&mUՙ+jͮb\KR0D\mPAH1]H4 tCYx ͫDTwtˢFf{/@s1 )'.]nA0r/gQ_I$I"OQR3\9%Fqq.!9unl>pZeK ðʭIp5EFn̋zқ|N}&WL0U@! rxio"B j %>f{2O(m;-%:ClFבfjQISS& dVKxG/݅Ge]on&iUcwqo;>95*;d(nKAg9 ]ļd+n8:Gă SQN_(8%P z ) &DajGMƕ@z<39@83L-Y>͉f`Q. `]_ ə5nxtN]-Iܞxܻ3@xj5^f/nؓMW?5hNy,, bÍҐ|_2>c&q Q̫HPiHz2Py@#=/7JYt]4 3 n(bgUYaGb,~ح 6yG EeQCvonp==y!dPlFHB7ֆ)eZ\ K*bWHm,>`/niX(}(J$l~L;IN=u`1~ k#bd*ˮ ݋T.!GY]) יa!Kl#fH-?clx"_{l~']S<'UXSJ g ,DX=dgL>i?X0)g3hC@tҥ^Py}jd$·T؀y\: 9q #p.1iW7tԠnNCl|; M CиwO}בS>o|XcBy@ui~!vعZ./FQRq Ye}ϑ>-ZZGYx쪒NRܼgT2u|H'ff&n %-"qHs}2=1*6jLOK :XRԘZ-$&NC)FҾ^)-;yzwӷ[vW[i(x _B(G&,DFSʤD<}GSl CŏKr>}6_V?OG0Vcۡ,7%Gֽ1S Әj- r)gMSf5]$V7鲘U"kvfiH:ҵFNtcߎò+'M.۳w_qsTͺ^xXe%A١,4a_Ʋ,;N[y&+tiC Dp.(]236kBƁc-sұ55;8We^4-  pܨAȯJ)P1Ϫgc"tVu:#Ԅ/}=μ'Sp"N3`bjenV֚El“&Jʚ{6.#sA>~ED4 Ԣwfhzeo֟'oMC`%tdAMmĄfl t}鮹dʺ;e b:;렚^ڛ龎0MKMpqfY[%Г@HԻо &JIE6qY,$p.OuR3SmJTAm˰3pK/ZWcT֝lf7M`'Nʝ̐/Wy6=dS:nhv!pxPˎln-:\+P%Oj\uCPuW3|t7m<\b/=Be1RQR[gɶ_ KYsB+ox= pD3n w? Z\GXT'ո\&TY)[xۏjՈԓ啷Wޙ+cM(mdKXd+be YA~uA~mn ?ꂔ籬%#fP 2Wiz(c96&#EJ$RsV ٺʨRpfB͢5"y*+}e/y ڤ =ӤFFMyp)0cz-XMͤ)\09$1St 4Մ|"\]1!|T'jk<ι "`J)Iktఀ[2Qh6 q̺AR` OjLAu p21ߞckuzv $:}\55h$Kmdy@=!PRt|=y~'<;Grx DȈ e[蟱H w֫m hdw}耾,jΚKM װL~ݠ˄Iͯw7e5[ش_ gN\dy72>AeEC`8Iscd%-Q%>*4&y&ڪVO[N^%JN,t=X,I'њF{NU.Veӥp&abPPyÜYA)pE"'LC a7߮bM E)"Trjq'u*==< ۽S+ag杆r[¥LE!z5pV@=:qmO@PpxPUݼ1( a&bɹ"29u( 3#& 7)CV2utluW^4s#G T3s(=Ha[yT]pk4{s/[>mv*fzE[De+~9+/cpі%wn=ӆg LPr{((Q&wɁ;iHzAaʔ8RFqoyFs> 8PCYg\w0ji7~v~Hhz_5}@B VR .`%U)!\Wuǃ7mrAR a.I> pc_A{,J,$}#ֱ[ɘ@y+ʿkE9~;so=M*S/lc `MtҽB`h'+t]Xyv^f3fWsjfK ;_6kFEwoBF+⣤^+掟,Z/0 e[{\߂qҵ~vK W<$w]N|78s>'5̾'kWrmI#>C.O[[3ѐRz,fCGƒxw-~ƙ$8fE oUa3`(wWz^hcR,fx<ۍ;ዳ@[AG,6bVE|Wuk< ^bܞr+b$X x4z;}cڮ|H3NS3/l)֒<~b፿㗗_WG&Qxww ŕhǰ DK9I]^n˴2sO,;jGG/[s[kn\lHU[<}ү}%AI*Z"S(e$D x ΓHei|~/N׊yBBnx1QZJb2KA2G5 ]~2q̦/[d"F_(qL`'sjWk`{ d,tBCI ŐZe^P̓I62{m*?ߡZ]-8a5EzLs_ E:4kV:bmTGq'',wžTjͥglªy՞x##v>,FA*[Z}'}nm.HkDCMp)@Ӓv\atE̞҉$4) bί@]\9*{D(57x.|eqIVj 㬛54mcV UDؔ/3*$deM\٠8ˆ u{M΅t~Kd_QUqQ^U6k>\pAjbɾ]mΨpQXZD GZV86r08USwTfE\AzmU1@Y^+W?43˺+V''yݷ^Z P? mbfX ,65/4MbL|.IS;Ӥ= WnvNMAREJnWRLprlp'g>P¨ p0Pl7h'!\>LF-ѧMYР:b]LG9}]bYKcGΝ|]ȄI.n ^;qrKyX6+<2n2/# d;4Wc~~Is;yil-Ǟ l!{߶Rjze3h3Fs $,}t?Y K`=weB.0mQЗqK `Ehv&4 X w*!lurtY=qUU*;؟%pG܀D]A8W!Kc cO",: 0b9z]Ƽi2?써eߒ3!AuZV:UI ٹBܖΌttό8 yY<+5D:> $/*גV$ٻLW'+_yRk򜊲?ECO jR?I``=(m"z@ W#88);RJtILSW}`T*I@"짪4[I9~x3K-`%~1 Buғj1*^~NBW 妦>8yi02y5ӜfcmaJG"bnfɋ.B>&TǺmMDr4fF[ͲWZ[~K[U tR^Y#Axpp _8:-%e@; Zf޴x(M\|-:Uk;)z|UNh@l?7tu :~0Pt>0Q  U'5_֜-3Re`C ,'!& /|dh1s&#Nrΰm/~iL"8>d"ޑr[_βIhXZzT Vhb)@~:fp}5A Rtp_+@MDlVc:aQjm aPd"ϣ2Q =>@m;!)e͖7B~dhvkpRy-y),GwS>ݎp+ȹ[n Йl/'l[ͦEM㙊l<-hTuՂ@ 0j <?l=`LS0(RM$(2.xq7"n@ǒ &`rL'B𓋅 oU 3ϒmf߁2.& t4#P"!W,vZdt+%9ryޱ2+|"JYZ? 3Z|ퟻ2g7˄^^,P#;Si%#rYz"ȲBuRKNBG@xUWϺV>)N}Ї\uq1<&hZ4 #5( A7 )-ҬT~b^zSxAFZ# P-Y.v K!rX!+t#Е]8aN3Z`Xj/H,c *5n<'A[d{rH!Q HJgGilKFv p`rpK&r*$zqwPse\*-FHp(eGn$fЈND={0i19(- +ε˸q+L:ƞ"2~cz8RH[$ʛ]%by YWMTL=r6?QE 6?}ƫ':f'y ˓X ≓f\Lf v L>%}!ѭes!MDej.0yO50.XH~"v|$`oe? r(o>=\.yy1rpWX쭀GXi%WկuZK-t؍w0NYbBJybkEU׿c^yw,x@☒=tv쳫KWNo5Q o̬kan?3[Op1i8~@Mlj 6mUxl6wkPnBCS,T8,@A^ԵVͮ~ϵnX2e}eMLd XݩO0OF9:Q@yu7b >$_hd Uvkܙ:p2aTrJ>3;8 „@5Wr€51J ,ɚIUD0ṁ~$G- #j=G?eQ|>13Ք 1TTXF|E%K LKV y)EoT L^ ,4?1ܸ1F U5 E+.6DAz#F7(Nn^k hR~{EjG՞L_SXc~<Ӵb & r,ݼTg4k"f*2=}"q±3ltpkj:Tɹ0ol9sђ[K6n2`1DɧҚۛM73G+?_L⠩q JXܒ1Ej ;~;a*M/;ju!;ӎ/7)PnM=e\8d@oM⺮שOqB:-aA2Y$Hŝv**P YQr_k}*$W6Uu^{C g[(f^qZia5;m>U|ЖB #]ZI)S>QzVP-DGO?㓴BFMhһO`t4(rAtf1bjif+5DL?\}gNlLJxG]Xv?k0b6A;nQo/D՗T5S:H nmؘ6s*jGy.xuK(e4 u$N_\-i&wRXZDRUic] 2q᧫WZm#&_©VbYZ_Ǟ@7t*Qڠx/naSn6OiJq︚!Txv=LMߗa0I*㨤Q>DoU}  Lڈ=3f0(cROIA`"8!t-hG=Bupisl!; L1HA?%-{`kȺU3Q8(.6"c;F5ѿHHJ1;ӱ%C%lvfoWYցյE)_D6:4gkϖ羾jg֗ 6Lݕ'Փ;˕Ս/߶O/W) Vln|bstQa{eh17ю5vKN(,1'7ӭLnx ;vwBSh75TP4;Dl 'yk ju$:½U5’T3 $Z2^$1okUtm@Kst!3 '1b2wCa0s[#жOjOk iA`k=EmO?6V)'V2y_H0,BSFtZ23 ͕%_b/|"C^O.2h۱e\ { |Ѽ;X-wd: v{HB,(9)rL mhJhY|nkJ xjW7Kg oҒRש0i˒lr= i[DR1fDHX|?16;e9S,jB6*gf~2Qy϶Jl{N0n8y1WeXHIʇř՚2b])-,ӻG-r&b= ]#)f3uPZB2<=Lţ5`yD;J0t|Ul5ȍBCl#Z}}>{SQX>HǚH$1Rރ+/8pn=ǑbhZp^PI=<X :;NH@zD.Fgs\yĆ;s+}m)N+Vm{ֿ$CNU E +;M/6^ B0WͶQm-> Mu,GÀ %b/`U]rGUgH c@TeMUrCIq]2<{#Km%RRTۘSYE]߼3*8(<'mXU;6/Ú/vdI*U:Fq/ G3Eϐba9ư=C~:DҡȅK-R{O@;LNխvmug3 T$pմq? W[6ABfըntslo=&y 2ŹiPoFtO˿}Iz;b>zVgf?A"N:vD4aX1kBڸVf cd͔i|ﯺ_ܺypʿo%S>T)P5:VK]0/*& ^|re nx`ohL`K70y}]r*'zcu 3l/]l/57W2aoeq2er*rQ785_Kd?N F'GDSq- `Xnݣ ͊'!O_y`;U {)DZq]k9z[VZ^$a&'#i;k6b1J!kE`^"]l"Oa[\LixcN&C:Bͨ؜*Q÷"0fCqvK[PR>c>&XMK!"(JK]ֈ3 UjI1)a ;CkEe,*1%l:"vؘ (\tyX+(nrEwhWtK{ӇguhVɲb]|}eL`b! 5}=,Ph:}6ժ# ]}vH)`dnC7ϕm-߹w;p}y.8YV1Sol|lpsܺ5WMP(W+ >Qi*hUPedyQlǧ+RJT+ ^G"jĦ牖 ܒox>Rx嶗Ԣ時TE$m{#ݳ;c,*If>m P3:]~ڎ!^\MO(I!i;۝Ks[n@!d:}#'SI9`.+jЂqLAbrW)i~.@!7 l1^ըև PlG8e0ig~gC_.ҝo>2? > &;bF[YI]\piī\긬a0ũ2;-9}6C+^g$F+Xj֪_!U1R24;xw-ifZOS=)]YV0O- 4ƀoxNmW@+TkUOS!5q2Z Ҥ %\[7OӒ&þ4fI} ,ruhxs%\_^En5Я8n@cHrƴNdJ⦓]ȐpmNnɓRG 6wSJW0$Ճ'P+F=A图V>?qk֫/o}6CL^&~nhX6:coe<י1dO[1lZ'!Hc4/IϿ`m\9R Kkj0`lZ:}+`cʡT`{FuRYpʔ~NMuj;UTpGK8:c5U![wM޺v. ,vckw4V VتQ-:I[a[LgvZ0{wn?pwmxlwAeHSE4CKw%Qi}N6ʴ.3 $:pdeYwiO$jg3ȿEJT;՚&7np֮v1%l0/#V:VW+b7!f-tPNgu&,Y~"R*c@2@DŎTWP1jީ9ڭz=IWJyq$ ;E^-{S+}WH ήfUhJ9v4#)`5Cn/Vw-5Ožw\k7WO9 n+@IƋ73E]NF@X<7E # )ސp$ !^ý:EqbˮǠx,W/twnoU} ~$5Lԭ@#0%&we1Va2n !Rf[u;qFē@nqX]@9W#rJ{ ;syF;.ԿRXyX{ˡu70ԟ\ ~+|&Mh-0)8۸vwHvѨa}>o<[B퉃G+B>y,-a6Z`6^]@F:ncHJ-u)W{Ә{ t-p0,S}[x6.2AP j"F vx5mPu0".}Ϣ;J# ݋\s`ӮG/+DECQ|Oc8ګsFQK9ΉZ YtD s{(vMw_!"'0Ɗp.:=c=vZSj-WjF MS}Q+G$ّ\=7:>T:?{ݝ`y*cYP){SDsKK]}&i hŨlQMmx}<9@qʩh5M_^aJuO |X% AQ[%Lj0X*)kF0 *>0r"p)f2WRHVgwGgj/S8$Yo2sKB>$g_D 6(Ywh]ʠ_c6)A\MX㩥drlNU,scቈM#ԅBg^.,?4n hUz>,O,>D{gM#D#\)V&`V7Csw)1v:g򍟩S|O+T;cm~Iaڴ`J>̅)MH<?=M=>saћ! /_.[WE=moAXjt2-\j8ׁ6?nb[Iejl1lr5vyƱsZfC"qEL!ŊO0U7O8 3 .V"p\bO#ZZ(t|i ]kӒR6dg/N.r;R%Q=_e2ї{ #9WroъT[ T¹;&iPq[RK^KjGsk?sU_R{X(GH 1騯%(X,]Zb]"q"{&N6~J+f%K1I=0͇1XX-GJg+x2 m5%fAg1YSNGS ܬ"ߍ{EgOpBd +P5ݨ;"];?V!&<^$m"v{Iծd,rCw彈( @]d <CeB஥ 1gUČ-;%@W =߾f\pWhy )YM[*rǁi[kR윟᪻o~qBӇ?=~0=vE2'G}<>_/g bT< R+DZyqt imnOҷ5P#QZ*dN3֮f2{dK ۻA2B!rSu雖%~BcPgeyd.)77&kzвeؚ~ N2^ j 둩MˋMvҜ*O/19;^=[1l3bha1(  T![듾;8ۮgT~⽔.!VT+Bަ4qcBX Z7<%){qz:,VmSgȀ(u؜U =iLkAL=RRx P;#A{iU^W2.p[ab%lKݿa`GD#(G!R! %6@g\|:썬Ea$4O6aMJ6ŖF")dv0s6Ȣ0..y$|N(k1tk.0 HA,}] ,X^IO%̤MQ@l}s44a.Бy]:?:wKZm?]ŗfHJ1ɧX ]w>,?{@H Sߦ}*꽸x]vWC#1 e&,%<{S #m(fW#EG3~zuq~!O$ u8x֧F\[*M&;&0UH)Vy.!eeR㤒mGP)B;:y -wvu Qy-n  a2tUꖏv?-qh-d l4s'?-=䶀򺟵%%NMCDժ>V<_D$jĬZ7>UAy%&no]a IKlÂ,fXU43HX[aZx[$=/LP@ҍ3󮅹sΒ~%3}}'TC>ϩZ6ȘMz$2;zD $~rWloe yOgЂ:7+}D%ɢUk%PW& ?~{'eaqL?8}W}segx:^nb!󍵵MG~z`k$WF9q2bE{I-;NnÁݝEy{K.C"lw&.6!:f^[Y-PyFλmi+c?Y[)a=x^jsqz.D'=Vʿu^|C$]9hSZC͑}f+!y%ƙqam~Btbh]7 ޺S'RCd8Q`H}5(!dhyEY@OiB##13)1GS['+p_b8qTpVmӕ׏PFY3J*jPfhD= yvjXpi9+UA>Jq;>ϻx3q_O+dǿ=x{*"t̿|">2*ǹrCjғy. _5R?Q*m^D/^hH̅F>}]H.# ;`OZ՟?˭pP퐖wXG_Y 5ʵ SɃ%V64Ee>6nl1y _.@Km /L*}:۸k28G/d#IwG\Ov$)9c\,b3K<8FֶX@Nr\OYdK3φM2DJy'Q!ijL$j,yٲC[} S"dC>|+|XhRΙmEkZÒ<HrֹjTߏ6g>ʹJw럋-^{3ZG"`NgapZҳV#LeĊۺoD/8Î!ˤ%BS pirN-L :'66@-, ]R~8g#T8ti%U|-SE:Q6X zrbкr?F !cfaa'ͱQ"! L8dXA ]\!}yD  bӥ"m$9o?RT}5 } РŒ3H C,ͥj˔}gnΩg};:|O}Tc!z\D$87FRhPˆX^!t.dfӌWOR J]Mjd+X+N[?[n ׇzGB4k_!`j mRlcB(>%^\:!2 Hb{ĈMXXrĶ\0bX\1-_R3REIֽGB +B,kD&źnBjK=IV_gc Aǜq]dFx /cp ߧq܊7MBJ%P\/*qGfH= {5e1pu޳?;y)UJkN3Q>?SBJ'rČWl(Dz{].dzfK.*3]NT@ 2L_u ? V+5 R,;25KR.NUT CA(͑MF?rh ye_qHp2xԁ UL ;g G/lE7KǶK( (0RePxQųz}+8d!O[ tLVGHS/>{;֬)\%!)pvf:")/0 SϢe yKkN%Se"Q}Llm :Yl=532+Fc*t1nWI9E9>Ely|/_RKskc,'nVkǟ9 슛>:A7ypq7(vks]KB!82$4ws xx\J@jt.v|tf.n#ܠ_ x`ȰIGO .{,gqXcU rHD^?W8S:^}{dUoL.<8gŠ[֧&c^?q(­DjŝmC 4=m_lxzTba*a5Bz3mGV"Fv3)mӃ_UsjXF,G9 Sr -L%  ͹W/(Ϡyq]9,+TOZ{d _4RR& Ijs1: K3h/C>y*jŝbra&P:Y@S ?+ۯ|Oܾ7__}}o;[.SdqQѝq"4$ďsŮ,cl+G9p9H.'O1W`YǏƵ|xj2쫏)ks;}nӜmB@Ɓ'Aߪbay41H.!= r[}sJz!L;ynu "w_wk-4Qz$"mƒUTn>OP,(t1Ũ%\tŨ#sI竛եݗV$ :7-\R 2l\=CT=sJqީ r㩨QF7څUg]Z5pD1`G'w)DOn(/Is"̜I|iհ塐6nHk o=]Ni,Tq/Ǖ'OַV^<~3âiozQ _)<~S#t 1נΔͭI%}z!L< >k[qY{f4l}U/7>eUf^(a>y^޳~j̶%9a%WI5Nv!{T@h,(*T} xL.v,zuԛ[[^ykR#Q\1#72L'tviQ/m̰,sv"ۜ}YFBe;s`ݧr /wWgY0;~Z+pssB_LmP\Z *= 1ͥޝT\>x7~lSt $kI;{0&jky1b;Fjd栗ՁIrGJwjHNds.OHP`y7aRzw~]tK&A.K"5LLhL<`LMkiڂ uqYNTh#BǂݓD?ȝĜRryBLjAdƆK9]ɱ*8Hlq};Îw8񋹥RĒ h,r}/YuFFry15tsKm*'y& #Ve,I_,H  ~DMjcuW;?=hMLmoOͪ R{wdRu@=4'Xc}W[pa1/1*r";LdXOʳN߬S=77tDV)L Di~ݜ% K(5領̰VZDvy-$KĴ/;[$2Co1w84m-F  g5M^:<uhz {} o_{bd,k.PuOX`ֱfu|geg"8ǹ3V+\8s~]mv;ڣĖxW+O%8EQ~6:a?U??̀rwީ'\Gcϔ5;_amç/n8"% %4D1sl/.z3vZ ltfB lǬn .f(XLTT,"I-Y"7!'sDJ0U I6RkmCQ8@R {8C#8LN(TbliVQU(9z@C[mf Sp) 3JeV#W!A]mF#M -tB0&Kb d[jo+0ed G#,v68XmSCJSn>ɥ(W?W吱WPr2N@Byyn^LY) A8v[C t-  ϱH\!{b}a"(F(WXZ&䯄0Vaܰ.F%,_ ܇\C]K~XGE*_7#}cj. ߞnZIPؙ]cs&M{[ǤhGõ3/[_ݤIK ݮ/Y+Tv񃽤ʈo!yQ?tWl7uĕ53|/ M'+n'8$!=bcWtr]tHx~!:@O]M^>QJg*Ɩf,HhBݨx7/l"aFx%Y`X~bLJvuyz2Ö4 1<sT;Q@jѴBʴ^Ix6Ɍ^ %N@d|ֶr"#V*\WO&$N ]| i˘Q\vyf 3ld*m夨ŘFJ#d5^ rz5j?KG ##aqk7a]O4r&Xe=_9I"ו@oyj I{Pd*^xmN5,;q{ ðYeDގ9p pTulR_+ULU7œ?i5%]S2@$eZj0ٜsNG%R>[O:C?pzv4ݵdkXc&Ec[,o]VSaER 3t˜ re7dMC*iiS6Ү=lj½\n;maja+h%ZQ{ naQeҕ)x0ẖwQt꟥l>} ̾v3'dAG#sktWe>PIm%GGzhK%8iTqZzgBp×-{Ce5VHq4Q,["hd)g_v6 񇷔sU{u,`4m |FI }gL8E; G]SMH,vO.z~;#gFg!.:{H!=}dzucUeQ% ͽ$J hGSG,hUʼ%tk# 2.HjB%;1YkՂ9,P*śؠAuH_ :dhZVC n>K^0rJl\t6eoj"u N[rC[od|P)5?IR9Rҩ;v3;<'_!aW_L~HKS· 5mL}']3hcEU㠬ʛpxH=1Qve_BbTRx'i)%tDljAMf4Y.r3DXTtse1]$ H\8,u?twFu~%`h,,"5GvS]qNNO~HƗM\\:zO2*r/|\^W2Ak@1dFţN((s-Ϩll~Ͱ>Pϗ$O O ln"r͊c$48=N0[>T|l:C:\)@/!*:NX ̧&&ke-憪NJRp=Vzٗ47X- jņj=W` z޳ʆgI싕ݐrvRjͥU0.B}ڭa`̜ i VʐJLn/8A8~u# YZ(՗+7Ex캕D9wOU[Vl]w-jNeayS5I-kS9]\gr څd$N\Z0 13T#@&_ W+6j7;ۥ?8A!g7Z\.yfn8]6Vk\}+a +nDz4g7t)=X{SG[@"! hi 4P1o=B6R[<í;Md8UY{dBsP8^Ldhl{ Y]rZQXdBs$dLI'apB.wa#D\*3 2 D#R@[Ao{sEdZBi8[zkF~KBC!;_~w4g:4sq}$Mr[}жa=3P'GJLbAQ_ɘ2؋I>FPѬB]#~G|{ubYS|VHƵm}2ezMɷ~یz_9\"_LA5 lrDrf{&[,wdDj݄`UsJO66P2(*La/*z!+G7G FK 3EƠgg)X7nS!!K|B1 \l=鈵̧g:G<$HD$OE)b~1#ZA=򩵺E]ǎ8 .aʩpռ*qgMc,ViPGW}j{**9RDjLբЛy%FHY݌s5ᙌkVÏֽF@Në|a0f1P\q(BҔf.XN.OLJ9E DGN$Ophl?Jhia$3w+śSv sܧ;l5z1 Oc/ dl<0iG>uSꒌQk(/2RJC#xTD/GbҩJXN-1x|񻋩oQGd-H*Ya0ujϤvcW8Q~O/$Cr۫q z,JL`I&"IM*QI\"­ u!4[%˪zLsqw?}O<^}\&l],I[Q$KtRf e?8GRԆήn"Gm&b*&DNpC;j0_K=wwzܽTv,ټ[ Rmlhfx};~zbv )bEA \0/-p5PS3kvh1e4L2yU}, }zuՕ^xU9yJR0[4<9. $Y] SBt0B)[4m]4` >Ce&WըJ$ݿՃd ÅjiN\cDc>^ .,0@vvw8l,GlEo.ϹP%'hͱUkp]я9&%U4&J Logȫ /f ٖ eJ"~yNCJzT+I#0x#e OM#gRF?t1!krd[zK#[3tkٳ_l&J헽Ѹ[[Q AIuǝ&Bƥ!lB r늘XP,dT O]4(RBݣuaDo%iΛDwq5I(M.H)wĵĿECSIɥ ikfūiTEp!dJa bJU 14zir^*c߁Jz!(D)9st$ڻ&K5$.pgsY,MRr>=80h*00x+O=A6.Of !$`56J:.RQJqFh^J`q*RZ^(GG8I8]SB@@ U%?D M25[{ajÈm"fx3#x㘄$qFIAOf5&X-T9:s>-v? ӵS:b)DeJDTw{j}ZCmUqN! @#&5A,+`~ t'HvC9XSG\R>mU^^qM*mR,ડ"_ܜme}?-lgQ 9ASϭxhTJk6MF@g@e°5;Fġƺ 0Ycq>6yB!X> K?BOx=Q O ɾ]RbOer=6l@ =Xva&>D%4r1>X*#3R"Е#2#zZEOIc7$Ɍh?}RjGpSz,ը#`Xus%´>A.~)v4Z\-WTOor,@#rvtֈBңI?AM)nhr!|ˍx)f4\Gt(У˱ZRy#;pU -Xi(jM5TMӵX)F.Ž9%ۋRMd_*aLzP$ž^ =wQn϶w:&)=邧elTq'K4aJMXfI(K9# /[C'Ue{ @4ɵ"d$jЂ =JhW*m$3sVTEh]bz|ڴIbǛi G4Kl+fI>)">(7gLJ26o6jٴzo۟>}&Tclu*Lj=558nS5AJ¸,zT }Ic? AJڎH.-}`z- 猘5p J:# 'eh4Jg\-Ġ1db xT#uj k`pi] IPk D@t?,l w>Gq.Z,rЄ' kB{}M8ySʺR>D〟5 rő%tx&TG=!oyz9;ׅ"uS&A-h B/:B>a>;BMv4vHקIL|SpW ~'sgQ1_ )X8&@qn#m4|B<7ꊂ/Ϯ;|CHܗxC^;vqi!$լR͈d/`Xg6NМ#'z,)D $S;%תWK|h|z)_=ofZ!sͱwMzɾ>gJȃa]BNޠM"U+4 ktI\z1=A+^UGacC_CY o*Vb/v?"K163+y ~^>~ADo/,Ec6_B1*I(a"T;-ߤ\^sSv,-  7C=D1W( {T8ޅ7 Xi7os"2聆j>`"ˊz2Һ0^bN~BHll4T눂Fq熷هLCm0+!e睳cq̉ۻDԐ$ yJtffwav[imiP*pfRn`D?W=%Yv0E(a`5y)RsmB^޺M$7 t/`G}q>JjN,"顜)e)ŀnekZ FAN}A`:ˆNjO0g#cN|F\r#rNGcRkM{I94i–˜8\B B(F'pmCG`p:VJH[;-U.*\hS[;frl2˞qk&OPw߿I븅'mJ})S1W3.ЊFOⲒ~ t. ۸H;_E+/ܸm.K#ɉ#g!h g}z1PS6U'WGDN`tgk\xilzWU? Bai =gttvhgغهFRŵ'2ޙ~ݔL+#Bj6kkpx٦Q˥S/..9ʺ#ҋzeL$ŕ FDJ /=J&(8@4{8"∓\8r>'_ ~P7,3[vX%*J[:g}X[\D(4| lMLprngB4=9%[֚!V3/҅ȹ9/g mC[at󼄛uo1r|3{;c8:OK2]&5afb ~ߝ ɖYQL4 f݃:]UDrh#gZp^'06K7񰳏4rңe"XK͛9>k4Pnڂ70+a'ZFLZ3䰕EHd0QC~~P#+P5"sJ H N iT )_n΋ loRM"7WX-Gc$WM׺*.N=jlM9SC48vzӎkIZOHCu?!mM#{^?B˵qD)ܛ rBxJ["D> )5!J (hs*?֜Oҵ3^8:2ȉ$Sp[ײP_:u%a([o-7ۭe*E&Sޞٕp&V͵4Jj_Aэ4Hw)(5'odwҔs~p!l 0o (l$繥1:*Ha836UǟtlEgގ9UnA+6niEMk;1.q$1W<0\?1NU+ԃN+tKYxݓ%)cs~ )Pe^h@~C7n[ u܏/ޓi)Zԯ·?(?$j}޷/F)8`uuy!`I~z%Nۆɤ0uYwkYI}UwGtN(s(BHVpsqBp('=>z%J_ 누%kRhITy‹7A]F[*EȄ?.FC-ŦuHtB]!gSJ|Ȫj!D<N8:jiO06MVdѸwwaL}1h_3|L$!ܶX8`9k Gם7w&\IOug4#!~[7/|rɶQ,C-> ǜ1ߙEj;%ǁ>yz{~0Wg[r}hOuk2%`MKηOHӲ:Tkƭ:;_vVZFךXƋ<}_jqM9k+Ċ~VVzS)dW=f=H{NdlA/ϼ(S@".b;ހ44)>TCӥ~=2T*48-S2Tb3 ́iuOO%p>irx|/2b%K譍`3+|>= XSA+{Y<#{6yx1l ?PK}Vrd&1TB[xΧadnQ ;smSf *w)̚x Nj:9~#'[7%>n~}kأPݕFBVB]HUܛ95v0_<.xpâ/z7 _|4is7/oGoUw;V_N7}j;\5g^t+Op.z7;sJ$kZ 3ɋ=Lj/sd6srh3.q7=lŊO.lr'.SHuYE֢AMDAF}+݇u}][,07NͧA{;0s_4XSbN9WQrն?VsזȅlOO4`wM k̯h9YVjoKt6 qƚWQXB8oz.`[RJaYH':B:CPn<;Hvi=XoDG}6`u opS0v] ^SZbک2iŠu :CX&ym f>O?w>|0? t%bZd?ibk Ƿ1"zN9;Oo/w#a_ t;o5zx(tf)g{ CzgsدcpSPW:i'ݽ9?G^ fh YohD1LZ5ʉ_w$~Sξe!"m8>g쿌XIw{ ڿbL9۟ e%Ty>LGݘsįCFh^}V3igAJA61Hŗ׃w)b] 6e} -6G'ۏxͣBԺOwnW/Co"Azn$ѹQ.ƖõTݗ[-U7ڸ#QK Um:DQ~j8>5i(Wopt𷧚}'fS>UQB6NMIU1QMTgY=[3,z{s`R˜DboWʋT?lo#)BO[U+A#ŧo>'nX٩ypzjsezj":9ZajJ8P8{]5ͶCtr|WK#a#%C!¤Xd0w |NE[15̩3AP0QON+w^sΊoV5>n}g7nmGTae͆U]"Bl֟{odtf_u16NgabAaCT~jQţs|&}/ŧ[/vJ5}!/Gϟ_S’ LS ~z $ >nvY|xuT[hUfNtmb.kLmLAJ*^`K*(L ̙3{ɮ?Vу8ȓ7Ėw.GCBOy=W ]X1rOS={d(xgoJns>Tyuux>u$NW˽!$Kc<5Y+Mx`QKjY]@V(1{k{%&% 5 Bk3-2ᔤ a0,6i~cT|.-0&t;ϣ@ՑX^ybܢbxiKŒbZ^1KJ8VԜ F Krd:}S0"3 K:SehW)׏ezFI0)k:|t659rM:󒡚z,h \k7o|ϲj,BTh/tVcgՔG#Qx.\`symQ&>vLZ%nZՌCՇg5*de~c)""Gk/j u ZI WIL5ԩ-٭w֓jz,p)L=.Ft?dAUJ"_5{Uyp ,xS4 d(jy,^I+{z/g0GB3A?G}sD[?8:ƒBenǠaǙzwpO6:;wOJ@A-C&{6R|0Nߺ7:pjt%)_3B'}-z!>x2\޵pv-ph-MxpƓxbftcz0e[BkY>ub(:/}G0)xuKLQsb) ^S0 3---TAFp" tlkSЀ qALDoفƝ B\Q0!lZ%$,tuog:h 􃚞T=@8TQM<R5=̔UJԦUǒ,Cz[-ȧr[1g2Z2[I6fK+bÖt ne̴뜉LQb36GmH>9*0icᝄV/dCyکB,ғAWY(*ri.`$V39,Aæ"Oä-R؏ @G<!Ӷ]+SE5<>i/b> xëVاA拊QOÊGuh49eSސu[iQ5"+Bv>* Hh \QUk4ĀU#'m|P4T *Aw+>2QNؾżP}}B]=7H@ULZ.^)?l8Jx\6'fJǐ2hSngkSMoP֑BCޠ {aR3? Jq_ \ӛV>M:4W.*xVmEg7nMhd.l5qLVݰ ͎55:]58Q\sF Aqw  EAOoUl& Y]<ß<|)c뱧V[ۙNޮ&AT Α`Hy4!` %M/,lUIqoG>XGy}ƉX ̑Brq71ġAY$i^j<8?K]ee s䁽 MG3tY#qIeQ-HHF]AY|!܀PUڐ:T8RF$T0O !k!,99O/2D i 'YJXҿ `8Հ&t#Z'gG*Q`VY+7O]iařp&6l}wvLʾMKd{sGس50C!|Dp Ks7*2" L0*Ƽ81p!#b)&I%!VMghUTbK84j>8< {J@ejC G=@qOU+YS;qm/T 8Y8@2¿{ZJ\ 1ͩ.JR5٬x@uJuY',\N~}InJAxƠ>T4Of<Vadj64Mi+;go_(yUX:¸p(:Lck+`3uV6#Gn`8ƈ KH߲.m7.:ƹRf6 ,9򍻌AyNc9_4{/,OW\;[;v P9JB݈D.S(!$tA /}8!)) sV̜D5]?ilRx$<9A<*a#<ݏy:āuj8Qs+vZM:PꤓyI뭬~0'}Ƨ"v:@ Nie]ȧul$yDJ|h"8Ysf|5d\%3y` &ʛN]* Gzc\UcIS>ATѵ ( N4m,o@NmNp換@DzU_` E3W4Cy߬1#1WuytRN>V2/ffkO9' OwL mu+jTS3\bi vĪkWݚu{ޏQm|u*ϙ/|aɻ>[^P\|}aǶ{n a|ߚduȳk5:lɔ 1*3KSWMLR\$}pߣ+i]_Z [V%0WWhn\IcHyٛ;=7Cpn>x]UkpS}H!?ئ$_˲%۲,ٖd9`hlֵ-W$9I306e4` :lh'iB7 !qgi鏤i43;www{wVMN![u}񞎮bI&+yJy+-|7+^6_=d9d b\%MylѴ}l*I΢VV]`d *֘]lzĻl`nvl-8pMGulƼFX֎3W2oy)v{V;LN6iY;rD覬JqEZQ%eUnvϢa]~emBŭV{{l8PҎ,XR'3%%m\rӥ}mCU͸=5uem~Lh}}Dʛ|czvG=s8YS87;?s\dU_lzej {BKaY.@XCRKWw;a9:E] /iQ%Du(dgT8c;jL}c'hK$L`[XB ȶmmᄔQ]|a)N4"PN9]ITN$5Hx>p#|~jGpwA8_ߏ.[gѿ ^&wB5x+t^k`CN1 h+ux 3B!%]%_0B/KH<{xwz Y"1$V'ޟ&El׀#B[-6Cb&I_6Bm$'a Vn2-M>@:{ $ >WqvB(?@Z1LuGʶR TH1ml4t="x"HP@,}@$lxJW/$g_ĖJ6@p@%h[L| GpwRBU69 El6AmCFQە~R;H ]*&'Ր'>1HN 0(A |%2"Rt4!G'M;`DҩJ J@LHk `p]IK&Te<0'.lcDgT$a+Gj_ WcD'ZqRXx|*ퟓ@N%|FV^%1*49"&5QFtdQ҇dG"~lO91f[P *~y@ӂؙoKt4KRN~h%O ɳ Kכ Nx{}ROyZ d\O[~ w5USƥh,2 /}\_Wӗ) LCOBZhLF:t,Ʃ~JUGWj#jAgoYS2dm%V-6j^]OY5wiݲmߵ^W0,{x ;i>RZҬr+KzOe* QJ:’h-:I>hƪ>^ Ukh@]4g]k  GW=Rvngh@=|<R]jܔ)Z46;7f?;.,:+*d|@sy$'GI9#j_t&igX>9o\r%jm>EW)"SSW4vDR'L21Œ@,T;[դ*=2Q uOrnu0:}xo4sĚ0ax>"VX∛14J ůiq٣Z6׳'/\+ѶjF NÃu_V/Z9 ӝ}+~{ni;:ߝL02?et?)'!8 zbaĮO0?#&qQg/FP.@ b4 ٝy4h4W "x"4L 4 T6a2 Optional, highly recommenda *bioVr/]and/2 "3[$3龷RH-`+? w can’tY<\previous registration. Td=$==HrS.^lxTmlSUιu+u1>F<[k׮]ad:p0Y*m1 *Fp"#&c5`P!&|`5h h<ny<>'؞wy{u` RL%mCo.ջN2PCOwHͷlg'lU].zdpӛ%Jk wYK^o])6Avu e eR${ʟfA/u v[+fˢlVTtkBþ^(WЏ2g_! 4V>%W[fD <ٱv;̩1YG9kYXQmO&q5㠚+}D$DNSo1g*L+( )⸶rz_$d?D 5J1Oj}rt!oǛYK?@m׬]1&5aMWczB`5i% H /5X `%fdJ9kEâȯp$,9=$XM@Ph[s]ZnÜ< Ci"&L}R6:#M)|GOv~7b$eLg]c}Zƾ_՘1=btģ9NDiXDD k12P%8ۍxI83 sa/;wИJ`%Aͣ{f%CE%FүDN<1%(8Y,|CeWVKY#!sL02x ȮsfC_BI ripJ} n4۰?61+X[eOR6(?ErpAh?!~wCPcAX….<\> ga'baʣ_2ro͕)u2CW r_*\wffUe و\ah1G ϹCtRSfڻls3e߇],B@A\?h7iB?W dٝnG"|`C⍪eT#ӮfGٲחމEb@@1 3]0DA]U ;TzOFD'!p)7ؤNj&" }k`N} _6<5T&zy$YuxU{l[9';m8uNu8Iic]V]3*&vplvDmQ@['q4t`CrA7t nUؤA+4 N4 ;wkk}H9ylЂP83M NFQ5鸚̝tPd#"tgs%\7ŸVAp ?j`cΊeDm%)oU 1u*Em VyaaX`?oF!i؊`w&?ްMl%hq1-;r > ڍ(}X0;v ;K!wasXp,8G/ z;aae\svJ@HXw [ygwʟmsb.u=:ňS z7 ll/]ByI)!@mp,G:D] U\m}T?VgvS\إC"!][z#lϴ!?LHQtmc!_ },BpY Qsd&Mc44rIuF\f*`$Qy82yCM~F`24Q(d|bGBn:} d'Ϣ:myIʋ[]zYgwxH}? l@s QZ}kotK#1uރT2BFl:sX!.yG4/7O4YILWGҹHn?^ P5 R)Z bk9G(,qu<2*xˮg9*uwG֎ݏw,M26"#̡V`S;Ύ =łP)9xn:fFDal^~Fv(qAUm;Z׉ǬCsjM=}_pÉVJ8̴4tqK/tykn"[Xvo@Oh.gUU2Oz͢)4ad! um5݇UUG;r|hdž>lR`\-,3S0o '*;_7+T'|~?؀71bzpuV6ӽWVyx+~u m- 껬JD(P{ +bF৭~B楆v:h錫Zp+-] ,&MF6tK(YVt5 eW! t.UH߭7T BKJޏȦJqJb&XFޭ;&H;U AAkPYRv~ q7ב666F/vSvf.mQ7?%0KDE?"Lfljފ*fa;Uf^JWL,rS 1x%UFgɏ*dL$R/+|[1B0zx-OHTQƹ*m\<#c6B0(Exޙ׽mx]dE!-\W"ڜ9™-<$ݭ)߼lpoӅ͕g<)}#nK&Cf|`#^NO B (,5yhOfS6}ǎgggP.ShGյG JDFB>Pc3JM5ݿ>"K*-J LhѲ6,R9ΐ]Z-Z5m:+6pab&}Ap'YLAu1,n ԥyck!Vة!b!ugbrzswgZG?ȢsuwU%&xz0L 0 S|0Specify a mapping of extensions to content types&p6*u򒗰i(]>5@}. x]V PطagY uhr!lQb9pV9[&ӏؼ88ftPmCcT[hpΊVc Ŷrgo%UO67W3X-Ke6R캠FZ{iUPՏ4ƚGX~"P>?!_[P1Zlu8&aWR'jj~ZC{b '_Xٌ-)e/,\~)$:z%Y_+Ƶ$11Lq"Ǧfa絧p؞jNa=gc.b=8ac{1|taQW*Fx 8{W_b+a Yo)7b~^R`K[twv܍s5ytfJ;Cp/{L큎0-ewaXaI+A5j<ŨyE|/L!DQK/7tN$feN:h%;nhxUj.6 R_5}ΐBzp}~n\HeN<~+^)Utf$+馷P ]vDLLE(!FjOEվf#E ů{Cu]Qюu/H{Iq]r4ޘC6lхHHiL[zRQuޝAp~Cwa24.wh~Uvk>sImkUpKu)ͫ=Sּnގblj@h~({\ߓ]ѣѷ68Ly!w*8vz<7543^DS'xɝn:Ølre-cz&s%WiQKQf J !nzTߙRקæi"p'?yFJbUU]K :$9<ͣ˞mHcmtzt٧^ofs_{eoFUƵe}㯦: [zhk4WMW>|M[Ate69$.b;l\ o.d?vDGގӂ}9;fv 4u8~ +fC&7-*AzEF"Į` ȩrKhVv- nCUܲο+NNPW=f|²4:4.W]MMu)AQՕJ[pˊa.ك&9y=z1 &Laevƹ†Wgq0\ 5貳K!N 8povťrCmN=a}eva}Y`kQNë W|v^) pZ-d\,6CzeΥ>P)m*E j|.ߟ"s>G_<G'q ` g2bgg*vP\-Jg'JHe5yۗ MWX* n }ZE.Z `[p"nm6E_?tQ*;B}=(ݼfoi vU3ڧw*]j@|Z/_org>`Al]$h$jCy ekQe8&Ɍ`p,e'#ġ8p?ώD6T!̛^RGEvxE)nStQ7Ưl^a,h=:ܔB=ō˧@2'F ( KL V E$`,NTsz&FAY8Fk^SuA p #rP ъxR\f\L)m+e *)+^=Nݲٝ\@9G& ͥy0dQ'oFg@U-I8:;<(9ȲvӚs'ڽÃw9PMx]kud ŝ2Hy"7PW, |_dxC88+8~4…i| ΗQluWoGZM2G%i&= KH"x}&VZy],"; f{ãxeڮ=xtV^SkgutCV,EcF=0>=Gbn)GK 6IqďVZmuzO'P\NIFr+$riOa.nEwbt)|.r&p_H̵1 8zB[d4X|) ؔ8ȅ s/ 73/9CjÁCz_ho Y|C .%a_Tܰ6hFcҰ{`|&C C2F:CgueSKY 8%d://f0^spfXNa % 2~zv`9sA.~ :7eS]rk#J!r$Sǯ5fŕf]Ê( 03&ҊZ%cRTu  kfEXˊcp0x+o6_&"= |81=N]Vݩ[7JPTj?A~#n0-c'3q,uhx0QqcLyu \Xih9xӢ4+o+;,Ղg>H)[e !m(ά2Y(ʭĊHn \Xg|/\҉O/|x1͑O~];E% $3 V?f`kVSfMx?,ՅgfS@֭8ܿ ǠdN8cFh1 3S$Cőctd4ax-1Ew&D(MAލᚻsPN+迎 3nޅGم 8Qo M$ܻ#d~/U@a;o@1:sӃd_`oK5A`L) y QRLw0 ߑ.]gkxfEf28^itʼnL#ݞHf FC(Sj~1ehޥ1u3}㧊m(Xi~~$""tY %R>o,!% R*+i)F6+=_8)2w$cLFrf(y۬ j CB;Oz1r^KYR׭s HHK9⮡TMNcO1<6,BۣERB8|bo+GrxW7DZ=Xb!1VY;;aiL*Cʴ3x:JU9#fEuy< qgC9a 6ٚ"Qz)(S \'FX"PmjVpCF,iͬ5d|'(%vX av=I$U dpI GQy$!xqPzW@y ȮNVNi|ẘ)eQ1~I =)$ eTy 5ŒJw^aNmQXS.-nHj,ZU%c/|M]X-&8KIƙ qҀ)H%Ny4YY}F&L7Υ50*Zp_:sEsɂ lX&PUjQ32yEy܃ s:Szʞ2RI,% dj* cqlBzzҁ/tg਍D)L4AynIH7|+ao Y1|.%7]Hdc*Wp_hi9i@Q>?{{>|hT#*^!ZH#[_,J m l}Հ68ˬXIF $bd#V}-3=%]hHVnבXJdՆk?~ iޭisYzpn!ŰIE`2y!FA<.)B1T*E (*PWW2H\5wJ(^v[<N^Og=W'W@=>mmKpaT@պTK%|qr9*6>NŬz%_v[̲x`eU1I'?AS* "ȊA` uN["ZL(oHXūk%5D&8lNsPa)qdXil&D6Bf Vf2o#Yetrs6aA˟WqߤxYEŕ^@Rn~_3A%欻In+6~.[vM$^,~,͸{qicKb1^>[@!fo%rsȥ~at[Wk"kQ8Q۬.]9JCo0 $1WrK?6DIGdfDU%ђuѰ" Mч2T⊅Zy@:#U#q~xwJBU z DZub hl䦘ٖk^w4^<{٭ :E>r&7paB N&)[L0}2(DuO-wX{|dOXa$Cy?1.L]# |HpU9IJ c%M-fp /&ybX=$Yts\#M鈨ͭIn|J"6f&/bf^_|vX< qbOq,Q +IF*Js_$z[ "#o|KnLK@6 f)q_3ּ,W=?S¼9h2 wb) GT3UEw$Q]T{:|#RzEUX8B۟2N-&{Dקtݼ速FK)X·1ROwR1~5FnPk\0ܭD|scli҇\4U\4.}$e`9iLi)=,پ;[*wxm ɚ xR.,EyR'8)>/ep˒O'H aVYO 5 :AT'J7GPZ lI@WUUzBisRpH5Ufq5զL*G#٫\y|zr醍]9[Lj}U|>|)-:`@DW1†k[uؚBNh6h(VIQUkj^#0N^5i3,.m mR"NΘxVp{]#>%H@"I{{&{ݽ@Dip<t¨F?`@ PZ3"}{{!|?ݏ]زmʅ˾49e4p{n۝KRjIhUvhiH@v,bْiGmĉ$$X;tƺsӂNIoy,EjJݍ3S>KjRdS3keɧ/S)KWw1K̫] &NCGٿH1y2xmVъFY6-pd0TK0tWaJDS4)tc5"VRlv7AjX$t&y$AXJNZNaOD{]**@"7Wftto%Ǜ3`*mVW\ Uva$-c9 p%˾-q҂ռh]R,)M_9iF/A =}z]7|o,l< xӟA +Y IBz֕( ~b植У*,b{pe.+0|Z];#2X 8 0s0QM৆;qf.T;Pzal(g#G@Mv;$V= 'O&{ .<a(3EWd~9==[v8T7j؅Fa:5y(\E+f\3'VEu \ᖡ"GPdQ+]Bv_oyP~alaa{b#ŒbT;Aj~~ЧAiUխB\3dtX|p-]U r+X51t'OX i۰_ݍ~?9-u^*TtY*9 qŴTVt+AyI I>4:lDy Y);!?oѡ\"؆@-H`@!mA?U1N+Ν.Fm;^SUilĪb!ٲH9 jC8 *鰅J9vw4vfOwѳNb]>1yceP#:a5ϡ4zs f1_?>t.8hNnKԡx2ühϟD-]n%YXU)Dv,:t&"ch?F/BYz) 0{57n4oü7|x4 L`/Axtvlu<utkH(гEV6p[G&Mw_HLg TF7+4p)Ů4K~>mw|6W_܁or59|~fO&^j|<ng:EvP0/A6476Kj>وׅ}e|"} Lnt^+7jBjxwڮM'KVSkNՎ GS@Ss:th9v =1KUzo}|;]+ #t&,;K{J! }Kd t"W#9 $kYO-XcΙ3FB_ݸ-2NQ|3/dpb(qAIHΫ$qAcJMxVilTֽg<[3W\S;`E1& g{fI ؀KfIfRݘXPMJFi.&&D)AVgw;p,v?)!%/c^IoUn!K]+X٬2{)n*hOkVeU٭)앩uէ{Tcf2mr0bZ*e{fo%y)Nn^pBt"EDe5u3m?߱Gd7WKxH*U?S uX_qQVIk3kkrR*Q(e. ٝ_FSvdp͆Ȓy3&8$KA~U݆\(Š4sZcC6Kf_ڝmV8R~ŝ[IF$^Zuӳ,Y*Qo)I MnVn?l%dN.Ő[F7MuտP %>qbM7n͇ I8мOzp͌Xo3a}I"!0lh*k0_T*?"N#,a/&12?|F"w""EC*YP#H}GW䟄[xjb^|TQd_^X_NjT FVɑc&r'8TxNI/ӄkH|xŅ-)0 p'>"NRKBW]¯tX~u5yVtw>1S2bC$V$wCbkd\xw2,zvq_&ѡ(ip2ˢۙs{+h,% [sh(T:; [IXŏ%kڌ+4j:S gtHT{;i |$A|\GB߷hA+Kw{hIvZh J? "|i 5gHXX]E?úOUz2ַɖq[$1VKO_x|'4W#tI P2?Id?ck!zamz`lm0:^iX7_Ny)o)ǭ]=Nn\5c >NG3K_O {qbQ=m0Sx=)or@7;i[5C1T٣!K٨ s[{!Z.n#kqu8 /]{oFzʁ|:d5_vt/7(єfΜcp(PKUi_:~ܤvS;ne9[&@) a9LFufblp $Y+ˬHIe^d1)Ћp,T8Kp}34Gh7gB 2a.µL(Chˀ|VZɂ[}PlU)Iio9-+e=ڪ O&| fɅɀNSwq[ 3d>V1 י?qqo;!`!_խ{o{.Uvl C(wÎ畷{+CK~0eIʆ։Zf,զ4bJC5d57>BX,|0 }Ʒ ^_ei#)nTLhpn)YGVi*]rh#7ڈ *l*$a5dAk(gc1OyPx+y6\A|"*Ccð%+_;)?+4GGdut;.Ίe ,!(6ME\>9%? GW<vVp8QƤxJKX+9]'5 .ɗ[8[bJ`ĴbHf7Hl-)a ŖŸdƵ8o@\YDȗHt͓i1_#O=/_/)[ O &5RIU|Zҗ o$F$H{'98&dHj f ׇɋ(*%2ȅt\K `2]3jSq44ޭ)3\\B*RR#NRE&C Ҟ&З^3lyLBQGO<㈜G 9 !3 Or&T4BGBwhHTZi&Cxn73b0t V .Ţ3}:W bWW5/{Ej.R]&5x;aH &AmfG7 Fox&~҇l8L'gLMȾo#"qYb) _ f^ƉޝM"vJȆ r(u?EHaO:Wt+G|A#A0 "+gG/5w,3x+W_Tg $;:&S/D8Lֻ`41 N3ٿ<ϡvҙny /U*:#gp4 ә:yVL&K:~m~:![EDEa$b MB$a0?2ykUIdrqM,fB[$I%ï ^|^d͡YѬ՛6+`dq|KS^@!5D]\jQRkk4 #taC'P}7 {.4w_R9+^ڋ(žtgB-|"l]< hzhy`+}5:; EfW6?c'L|r,sJ8<=3>o3[ 0P9UpGU$YZT["P.5KI6O^[#5dzr4ou6-㍯؛z+PXGdYI4C¼ɀ{&0OΟA]< o4b6 @M_ĻW? p)Pj3g YdSrB/χ``H&ȋ1b4{̹ڋ̯SHM–= D^h|}m=. 8J%GV-sJwT}Z9iajZ7HO*{ǽ":B"0V)!3* ͠>( fv(Q(<%8c!̡piUA.$,z& #%- BQ\_8~F`UO]r 2,)u qkQQ P)vLOUඞV1{46P%Mú-a &,LBV6Ih5Wcz= ^/Gc3yɉH2{=w/dAT/f'McG s6 MD-P'2ԛXq&0e.b*V5cY(:-M4}-E<]q ]-Ere"P3 /Z{t}ŕ[w yhG/0>FC8sa >\[;֡2e5fH(zջxҰ!4.%le%b\QQܫ32:͖n1u3%t]dEÈ(bU4T5*)*0) }R>yїq(O{'%5WB9 =%sNL ,M&˼Dz|' CXCrl;tV AWmF /q5snFO<N;YYYS,: U0Y 7Ӝq1܆ 5N9[f[ R-WwEx18^dڳE~pA,:]p&p=t!B;Pmf4yk߇vQϝG7~' %ѕ;$N [NACv ȔV 0-݅vFu؀W,`lfB&'['Wtn*cϖC“<S=CUZ4UO#HC(~S2=(YLhN{@큶LtEt^;^e[1vC€-m(hAVV=8[ke,g+H_&.4'YRa Ĺ}Y* $e9'#ɷ1JݫϊK8p#=v1{!T C(۵.0<!tͫQ$I/;PF-ҋo': ЊqtP tBM5㝍3fL/s^_a dv5{ӹϣzaPQ ןG!l MSꕧ vz>=aG+Fc!wFITyc+ & ]u2@`=:> v́LPǏf$$ԷSg1ƧQ"I_~#Ḛ~2h~ 6!z, z?2_sWܮGtsF_uflln@ E;t6A鵱T+øY8G 楃EioU8PdwXCS(`IWEiF I|1f x ฦPȂqUpz"` mo.4Xl.BOHx#T@uc8DB\aܵL?I~y7HgHXC7E~'~D*oW)VcbhǷ5JN"4 'b0 R:wŭ (AD?>|7tr7=ߠ"<:gAFw1 wG *_A"O%H;Zpp,+5ySa 1bbe􎫨V[߯{nM(~=Jw} ssBGgwhTme^^~Bu|*!sT?JF3)r~<+G\, e B]c0+ Sy5J?":3`)fV3Va%[5.+ԉttC8T65T9U8~, j\:俢P)Xhcp뚅kf[䭐I sYCg;lA\[X7m̙ų=|%9SM_ǡ9Y|5xfV^Z!ϰfv,,C.@#){An %c/;Ч3 3`~+47&!}=Y\K"qBFEߏ_B:|NA<Zx]gdڠԀX\XY9SB ; #4,^f;a Vh?-h/ϧt \̠Gp,]QACVFy9= iq}`j?ePdVI L4Gaj8q/0Ա2ψj~nŐ>lqf%8ԄUqx|xle޼ Ey !Qz7t)Eqz{ySoQ 4 GO* z46z"t~񨊡`UM{'MěޕadnL{: m`<2ƴ,.Ȕ|oSuӞX:= xix8'Hmx@p32q8dv&~|$]<wAqddHMVq0~dkl-C/0[XKl|Ŭi@]N\6AQY9^a/aۿSocfTW=w؋.(Qp?uQ8|k_>&WI練JA,RvX]l (U zy8p~Lf"rGbչ]YoaLoQU4{qm(zǓU't|X`0i>bVΤ;@@m`8kntn{ҔvbKqو{LA:VTݦջ8}[W8URU&'76` )ɦuz$H+S org{'\Ay֝6vc^\dz%r rҰ Lb6W a% ReZFEMD*8ʸ2ۑrkwcX3s2<٭',84~ .eϩq9}`9Σ//rP88KsW`-ԗ[ٝ#2I}/>pA)_)mv<Gy܆;4_(Tbxqt_Tq7.[uo%,vYָ@O@"t#o>Ñ7Iv| .Orq ^bx>I V]/;na KÛGp[7[起T(|#N-lQ 3Zq7r koR>īn­ch+~U#|̎Q=i'3?l.97q! xB #xwetq [n7࿊g^UtXn>?7doMEs'7,tvQ.HX$ ;MPt2mA} GD&eu>h-FBwwM14838 ~?yLj n5T.(.a4Lho-ޏ4\iH~nm?ar9H!#σm2<|mB x#!T2=@oE"]q`{N."sV!^0-:ew <0:+[ޚH6h gO`,:L2OC=2R MÖ9WB\XJ\ݡ4$-5hdL9BHo[r;yk?U\ÉQhM^?wyp!Jr,R<7#^-y.@vr\%53o HMjʂ;\5pc=f=Ҝtu/G*ϱV˵K_:DnHs"HHD$r 'L~0TNéOҒ%IL.fߙT",aҖ-%=8~H8fܗP,8i (1+/l^ 9xՊ>[).iğ),ZJ٠QRu-W͋ s^|mbnFi좽:e;*JN:CLI.d)1G}D(ǡuKxe| !D&o3NMK*%,"En}R9q/D7eAy`q] 4Ώ0ǟnƩ&%Zۛ05?rTEl^$NT:S6Vߨ3(VWjBZmMZ7b 184\lmbF#ե#YҲfr>iVA.+ݦ-*y6OMc5:v/vVkZ8/9qIM**QK\q)Ӝ{.W#%80#Je:;/'>8V ǐ8fpAS^w%:G;:\ &5Gȣf:ePiM1s"U<M r"f0Q @p9'['=kS2 쎤G=xט\Ur.e$3W%HCnɘ㌡ǖsɗ yCd)Zqb|M~>abr`s6,51'21ҟ<6y쿬YEpm`x<^ >rk%ֽ\-.)k HVK ?:K7iұu-؃f ϖ\0F=pazdk} xmU}lE̵]Z+ )chKZZBb[s:{Tlh4F QLsQ$F(H&Fc֨фDn ?3o޼7s|uupe9YԬ"#Բ 0A}y;|ȅG|N@M:m͏DΌ̉At ' .61G<&JR$g+w0_P}yS`lj08DYp/}+ {v͌Twz{g! N~Zk9өЁ (ۻuHg]J/8'eanxU2ₖ`:m ytN$^JNtM!z΍]VȐS+RiY(]sb-v+]<)EZsGD‰d 7Fxl"dzlb^wڨIZ$L7!8یL=-$:N"Ov$TfƝv-&-E !Wϫ| O`y ZPy+^y26CxAxusLg"OuڳvmeTzv$,3Kf.e"[dӨN[`htDmP" qʨ}tGrl/J%:X~YwN,Et*<7xbOcC"Sh19n 0}FG$b)(W-!@iYk Z-2qDߠ>5xWϞBHw;DJMi5Aq;R0>PI=^O#-ܦhMK :5KYy6^dӕ]7c˵ 9ҌoMNh}-t89@r%UNjQk m F}2 f>hܴM>p5?&꘢zAn{L֤vf Uֆ U (gr$͚N/8plC>UB P*6^6WB/r*WF<^*Uz(U2ȏLx!6!NC7YA6R]-SϲVqr0Y45-)1W&3P͖_VϯOWӷA>[{`/;uf uWR^=h:3`j/u'xnhݥBٕ#YTc  +EӗZڝUSukPێ g.P4~Xֆ&n͙0)2xF,~2:HۡH^BkONuWۂ1z/גG2<5An5XI>2O)z%Rkzε Dx| xT3src /p\B dsO$x)(9=I= *XZk.ZZ[mmRoZEEkߙ9g/I6=y {;3}ޙN9t{bT~ԍC%R_<)rf:=6Yp C"9vȥnC)5wxܤw3hh^,x~o̔idMrٟ\\Xmsk~Tx>%wy>7eZnب>05r\WfnQz6;Jj>ͯSBeD~m k$e~MNUׯ8䍴yAedp*Vk94jbaEḦ+>U[+͍k =*u8K&)|^\hh[r۶dDk-kUEzޜMo #'y#cQ^EK3̘__Q0x:ceHl_FreXF)K`ԑ-]fJUd_U4QV?c$\rtfY5*VCO;EeXjE >O0NTF/ǧ¹66!3jse9/|)Vxfe(5Re%Q\pj,bQcJea 7@U0E}~U(͝tfpU|cݪ(RU)CDIT5U0jrGeU5׿`V^u b7D1hwh6rg~yAUhS1̀Ga/mqbu9kVA˩KobIȩ&/IՖj^!*Uװoz]d"W'VWZ6M̦SڠIkmfhNqR GZJ2ɇk¤lV6]Џ %TFk:sJ7@WN_TѶr=8C4[?'㬔oexdUjFXyW5 ur ><,u\Q DOSqmnSnna R=>&jaQfpGH I]Iѫʵ4r #U_bSJ֨7h.07Jmp>ϐj_Rƚ7.)-aJm;X"M/*7[pml?zFӒ%m|NhJ&MV6W-_/PP ;h[n2{ksI]w9_U" nF`+ ,>1,SB{CLZ;:ܪP`G ݛ_[ڌ2yj Yd}Es')W,o FKo"JJ{io_MjOi2w9͍k[K6rnjc]+C]\7kD. 8=0ϴ,t4YVJ|{Υd7cVo\g摑LlS;94I~<%uס2ɸi$+o$jH!-:="N2duKVq|A"]( '\wfdNFUNi5 'K&3̍c_.Lޓ<.љmiYJ}Ki thBË tITy+lh'.Ɉ*CVKd/U,<ȫm^[19r8Z!`nGsAA[1mUƵw;PCgV81=`$Y'0ͩlz.(fHYonKBw.b<0wDVwK)&$v&A*80 UV4PnQAr!r_XX.QjZ6 ec .SЎFvjcv smG  2֠*C Yt;3[u@^b0/^b1T>n׫&sxY bqnשz6NbԛBeSEKt l`jףलMdHqΈ\&5yErUu<>%dE9ǰ%,S;I/ܡ-77YqInUb$isb6pdˍ m(G׻%ld/e'1.:ؘ9+57Q3CLfkqulU=Z,dFtڼJeXiɥnťm˥Z7q^ " dعT~x m/Uph!I@`@uAcʐ %Dِ>YSmy6Vp |`WD33myNļ#MӲï>يnXZjs0I2I5|dXM!! p)#!$[Ǿfd|RG-[5ڀ'V!f}&Z7ohlk]4l6 lQMVVSY1CC3r"TKu1 ^x.prz`c5*GjBaʺ+7w]ڹyewYFjLåa_˜!av̗2rqyŴǷ]րU=yg׬]Ȃ1 0&Hҳo"kߎDOoz_׾"CFkn(G3Jd~:YM&ܘLd@=?Čb`Go5ױQނ:f;je47^">d.BX7M C"7vrpO[F4r춄ЙHylMPfQhp~nbn>A㌍"%[DtP6##pfl4kct([%&"wd;̣w9Kdbց|(\hEt9L7{UyS7d: Yt ;PTloNMG9?!*e~4+~$<3Xy! F >pAG/m`\RD_4)3Qw|ZL(DO|ЂBh;pу}eFy,BHw$:2w|muljBf#&xs)l(@OٴuGQ<UMABĮ^| v)i.:8d$s% Ԯkp2[8gmu2\[rQe*w19,TLEah--9OPIӷ[x8ak9=;4ZoΣþ55zɬ-+tT'@ɞ>>#W)650FcG xџY̵lTVCiCItLTf)nd7={TDOAkܚ4h(W}Jhj윋* hZ-׬X^QG&5DnB+FSUF=&6XxNG=1IYmZ g+P[R;CL*Hp>'`FIϨh]ٍ6G?8D ̪TeM}l }S'&i$㍃zז[ S̡OmA#nA`P%PY_Sxd\wVJlfqpNvGQ&yxp13[:o,3!b2;z5, |S9"A >ۏ~]Ro(N 1K2؂2/'u{x#Ƿ3s-^ᙰđh @#_rA|4zh f2Y=!+?"˭}5^jdnN: Q?:ȍ$DiS`Mx;Ўxn+FjH'FВ4L.)*&wo%pkB/0xUh>L39ۅht RГ(o//ӈXf5qFpw!yh5~cM͆y&,dchxUt;h)5 0+q*KQê=PQК;~s5Sy?%ˀN C6g.1Q~G[h~0߼Gsx]q͡gtF@O_9.Ac8fE1SQ2Ϳʾs*? ͥ 7C_}3p,7+`-0]ʦoFE<78!`@ޟ=B;`FRvHeGoEYu݊\as(mBMv@ 0GyџhIt5H%Eh֑Q؋QVHI0Z0}4add~pm(Ħ`(>}C7{]_CM. '= vTFK)X-MG` 8 L xs<<P-b0"=-d67d6D1֢gm:#l0҂1iE5>FP:z ߮l^Ђo1fRU51+QG5ыP3vX 8__0⵵!oZh4+Ǣ~k}4cX^:k=ު2A w!=ѩ>D '@Ds"IykCh݊@,;Vg7ɗNӀ"|-e #=ɹ `<(q%]M'Ec?D̓ Fx0 BnELGsc~DV@n+SfLVl"ߘⰩ z@RZfEFSĪ{aT('=BAˋd=B xaqdLDRj=%OJf֜*;\m l!a7;9_ :E*L Gyj`qנ,BܺlZOky@Rx4y 0 no! ޼Ъl8)@+n7X,[})f#Tm3>C;O%&imN; ;,rM qPyXS}wTSTI)Psit0>Af.~3t}BϣgOVj)2VezKK2C>u,` zW(Vvu}H~ .8M] i 5'mxaeX/Lj0ϗ}M0=O醗"ԋssBLgvIc_2}[u1_pMtO!eCɴv^\,.^>~3{ eP۳B)sET+>c4\\$}|o Ό 7へZawL6^@1hR/O[: waᦴQ=7{k s )s#Em8KoNkz%/,;ƵkUqãR13qV8lN\ECe0nvrݫBIMFLيWW'EW 7U|O kf{/'n 1GjOx!~e_7c@E7"*[KUv#IU"&䐵]1X~#MJ?Hũڀ^gKmx,E\I>q7!<0 ' S% G5 gGOYS:VFDQP 8a)Kbq#[nش'ؚ"8wh_N{C _[2u3$[9v%I:7?ޯ_^ eSy|.y3mw{nZ.6@k{2GD{'˶z<"|džY%Q GEQebV@{}S=x}stڿݔ\R.ފف]\Y0<-+_4baJpƖ"i3 9H?(z/|m(=a\82qBKl*m> o~ҏi 27R>Z|ՃE;@e0MLT Ŷm_y6{ fG4o^`Υ(&xc2Ցo$ PW!snH >g1YG i5w`Ù ^J7ߢLJr&<ۏTSȖmx`*)?qdg,_ka?TcF(ܯXap<95/]p/_5A7MZf<@2٦}Mݰ PW58`ꮡsQőaxx+=8#-S~$fvVe܁`:xN _t` kv]p=6 i?&;0]ۃo4[qu*#y(gySg$;ա)DZ9m8NFh .1#hV$zΧ^& \#6:|>.Ɂ2 fTZ[s0&=o·O@"?>}|LͤGsW]Һ .HX~yqFn?,TZ#ԯ@ygQW7]𠊾T>+o׿k/FdO]Q&2nix7qQ4EU>A8^aD&EdGЎOp41ޗwUv0jdr! a\w"cOLieBnRkNehm'a`<`#3g@h&yr9='9!gMUPPyrD%Es [Q`-GPh(Ks@#ΈobW ;,djFiqa:ѧC~OĐYvWѪAhY"C!',ȫ_{Fx7,o]3[Lsx )tUJ&ܻuz4. rI}2N%ۀtuy,?j;C1u^Lxv[To~VL"-&"i{VGa5BcBC@WD|:ᛙzeq+-ѶÉR6}ad;@j8mWSFO6<{?ͳ-F4M#<.";16>M薛Ls(ϡR) k8⦢ףiv:y\X?S^;] eۑL39R/vw妲OZ#~wzm2mbɱƓ( AQQxP~eAPP%q:="c =a肎!!y='Qѫض#w5M ?`wxRQfش2MvNZIlb]}kL{YW4^ʤEvmQ2θV ̴[ 6u 5 DvϣJ $J˛ͱ :Z[}wqqX4K7/ڥh/tuRZ\/PD7܂s R[/}i7{$/ɪ>p~A|"|7*/Z)T`?}Ը2 3{M<T^+cni(1W'I-ڱQ:J_/%gߞ)YWԱcvvqN .1vIo*`=bqḌwzj@ MJ3[e,SsuV? х]LGAҸ D,R!Hx t\ŕ0|굍}lIW˲eIe$Yd0[^l ,؝mH&pa& a|̗$@L woU%9>ǭnUݺuֽnzSKj pop:GzGz:z)ccj+׺kut8{wT4VjdTӢHD_#SJxh{q9Y)Htk_Y8maV6߇MVUu8KzspgKnsh^ :W]F-rDD}\+g)tlpE2 G:7]}͋C#msxXR|W*"۫"| >FNzX'=jБ}*``6Eԃ;B޶WKD^TFIc HSy5C=r7:epoVyxkC 7b`gPWwOIyqi 8v% G'`lb?-U@rJ xeU'x0,JD0>XH^3U"A_@E'+X829 0N`'}0սk۫7:{#=|Gvtc DrvYUY}w#85հQ&0 g%g?ן EU1A#]%P]g-%wQ'R{W,p:{3r<=Ҏҙ1_X.`sS fx讀p߷_-!5 Erd:UL46CH^[CH܎1 giwgi0]㍨6`5W7}~I:l 8&@Yնdmv #Qy@2ەшP~;+PRքoldA_׳_kC3<\- ʎS/l8[9BWKY\RZWp6=5b~ CE&' a흅## UCOBuHvwvy:u06t+Qe $֗%@}H&n*'xy]3eu-L0v^*ɪkEX[ Rڜr6k9ș [gz9 =Vu70Yk gD&|عx؆{G.ET;GiؼD[ċxy}+ӓW!\Xecc3}ݝYiC{Y -WY=;\U ֆZae*Pa?~!Azh EPR@)Xhv'T40({]x}qp[9p]"$]ĄL,b.Ix>[Zk&:A3FlYY1.ȘC= XOs*`ڡ6Qf@OjV[nӍyRޅF65>RT֦U52z&}j$N$a@0z -1Uah5lo4؅&FZiT (]k[5\Q6q>oMJ7uMkR(ao"jR1pMm;+m㿮Ў{^*~; P0l^ #aˎ_Tc}0 ШPS0uniOs1i G5Wz\4ߘe066!Gaib'̥F6 C U(lƇ6J{ޗ`14 ($ zVڲk]sEW P׺ZQmD"6HSIάc6ZY#4xxnc|@Ͷn~f *ĥ-@vZTըju5!~F!RBֺk5&d+B6YC ZM3<#h]ª e,}֦ht[^_kԐd7 1C؎td4AnAlrEaiW5${?@kmuGvjluE͞dVR>ە! }xd[W}3e2;#U鉖1J@~:=.@t g]}Gr ʫR#=5Ih0lqtVIתDjjG :}J )UQBo*TA#8EOBFZgC K]N5_@J`"B&hQR(h;!_MCfsՍk6ñj x!臚AM{#r$ Ql' -?io5畤k2֒#f"` [&Zg.Hk08zaVV/FVL~DkIO.]_ԈOqs=5g6T95*m_ߍ[Ѵ*{!uai"kigiWmH_(9K~Tַ'S~W Ԭp6_{sCVќTAM}ixG 0ZVj(entw|MUW%7*@3xd7\ACǣ Dvf4ShOU>"]7g5EXq+6Di跕&׺6̂UX=]F(m$dVW/RNTE=h*u:t jw= Jذk:W4Yu`hsUvI|oL=RS6ʰ&L&&0o,Ik>GiwWHT.l50t'WTV<6-UO i'vʲ#p~MAGe1`t8G&U0p 4~?RXJ^=հ^V 0=dhhC{y.U"QO"={Pe~`Yk2TpU8P0"T@'ڧm/,9T1TOr1o,/TY`j@UAwHiyME"jу%`SJ |-[QSʴh"gcKsilF\e<ᤔ/t)3>q(ge˔YZWE_Əj8 E/``p6fj/ g"']=C}{;w1hdX7T`:pH;G oS2[j ⏩|NSJþ)P0Ӳov"PB7ê71J"ʄj2u,o]}} 23d^{ nE$dN_ 5y&9qu9 #0#԰ +10`0Ȇypwul-%h rQ>dv(QgN-ÎeO_Eʴ^06\43]5Lj|uH>ۮlY%+)]}\GE& tP:qzU/Cj! [ޖ!3gWx͌BQG\TXdޟa`o3A#x\ ),m50Xis2@ e 5J5^?Eܬs|h ȍ,މfA3uKnpgЖ\Xӡ7]6@Űt.ϹS7׮8v>0||89ZىLn@8~Q#Uhce1{n>o Ħm͕Kn]IZP6rD z8  !P6V}ۨCAJMg{ۖ s[ ]=8 _kݵ] fo^HJ'0JY;/D UC 2"uM69Y%mTۏ(gкHw03'j!TV廒]BR0#Ƞ0og1N;7Ysaw#:D %X2})8d4jNОz)~:\6~W s%Y} 6zmw[3dQW-`tkG`g$CCj6to3|K{B)";.Do|Xk$?nEm2Ȣ?|Z*=4Zuz_;XP7ﯴ,Ҡ?V]6xW >{[u&%}˫ZJþ/1j/s5%_GJ"zު pK,Ko7SqP$9˞,iKd~R@Ooi ;&(znAg\[ &/y:FL0uғǤ­3աi7z< /5lgh%,7 "@fL$3I٢H@l~/|wlZ ʿ\$j/<0z5T=ˊ\|zCgb#c2mv Myu1.:p@+|Ӫ~<]\|$qM꼐d2 ۦ5@%O Eݯ(1 oO}ڳףOQi;9^ȏy^- L{%|VgŮ / N0l5N~b\ efqtei? M *eЄxJgkg{Ph@TX.Wx˙!% LOcq&/K c}{Z,cz!Υuߜ|<푦*mȊ@oN:~6w6L?]Nt[i-7Wg3]mB.]ٴSRo'Wo/I16#^+g`ʎmsȟ/bvǗ?:[yB BȸP[QxkkYNRsIfնm4F1 O.qsYLCԼoŋ.@iH@/z>j҆?pi5~ue7Lb}(mY,J*Bt!EX>DHG-NI2])E*D!rhnqtJ4~3ۏ&J^k_YMy 0U]Q XD>NQS3E[Wb'6Jp&;Q@) IQBF7J%m-"c"RNoa(vvޙ/4vẐ"4z[1_V80+fʺ4g%Az`%j呕d6ťG&.;0P$Na hJ+!,fE%G 5UJ ;֙8NF$$54&gѡUEN|bFl& e&I[MI|XyTڋGGm@I/jEs|RkTeJJPF%Zm glmݖw#ٳmp>B3RD_Y WM߭$!RS }7:MUeDGu9QT@Cd+Edqk7OHbdBbǺ0z/ғ#,ĩ7(:&h^0Cd䐄DPqqzj8R x4>ռ7seLS&^LvO$<׼19o"g:o"&]0Qyt=!~TX0;Y?GY DrNIK6> ngq[z}{ -x>v`э+Gό^[Iwve;m7l)"qf c7)]kD7,s:i ҝ[Ia4meU(酰f^} z􄊹]?C9:K\ g_lגب?%g`?~Ȃ1Yh) FXx kM G{'tkՃdwT&."38pXqr'sl}JKZэ%I+_wyxhxJI F8jB. dYLFfYa߄qmT%O\O =NsГŤR "r]s6b;W23#n31|#+^r =}Ծ8: JB2oEJmò}&<}:s1O \M gkWy3k~; &AMiP +S*=,Ov)>Ky^{KVwVvfqR*"qP].<4LSȣN%|SF߸QZ}N-QdO*_dТ<QS'ɾDҧ zYI?$Lt(\1X2># [ U"Nڻf.$"ExTL^#-N)$~8EVg!< uN9OcȆLQ"1wH+i}=@ I:ڋoi Hڀ1HVgLN}_ß!alON}{rm ,@x"kTGHYNg-;yyx&:/M-kJ2},_w$둃HAiB&#ޘ+B@1Jz5}0ߘ"&p ݠN&_wJ5t%l c/n)QaZTn])L RrϗWSC& Ti$W x@C]8)͕eiW:鲣G=JVҳz8z1yDZE_= ae2RA`tnO_['wJ4rnr\×{8ӧՇu\AJ~xԠHuz RIWk .z嗤=G$q+fNѰzÕye~D)a1$@/$q楟"ہ6E4Ӯh̽i)t0豕OSϰ*t=3d3wT,I,akTۧXtkgɚ<3tL bӃb(S2ៈ+E=O䴅p/D&ue_Ke04x38XvИٯv n<-mn&$uƆS/ ^ QcS̞7ݎ{+eȤngXj6r24)QS#^.'96ݷb<GqJ>hOwj[:M'\]b4]>I}w37kn'F+FT.1[g8-[:"t%eC_v5gLR6>@2jueoMa⌀ng$zs _# <#n*}_T⢹Q1tWH+،Jk2ۻA1C69<-A`;x&d ]Sa9"b}UTW&d+=B0uȕ!G:ިgX} 4{ N6ՆVcC[AW>\d'vK >%0rBrA[B7\OyqB= L6>I@쟛T=EO <R(qahcE|6arEk#zn0/H痋vJw ~(HK2@wG4dܴ.wKTK|I|6 nw,_ydw8π=k ie+?dsh*‚ϐ,ߟ%?!tDAʓ|8?Gw~qG rRbwCqVQօWR@o(-Gą6NcE:a-rBќr@afzܯګEw( \ ʃ_Ǹ0?&Dr3?S~SlYVV:Ŗ=Ҝ&86&.14-ƢHQx,mb 0 n|u`BrlCK!{=X;S\;7M&'L0Nm4$3G< {N  c&69_~e2d z'_!9e`,d-ktQ_.;X+z%Bjc=EGmb~qY]FwK(LsBkT<͖ӤӤhg`wyrHD`LeeGY *q; |&,ΫʂVhbd"O皳M%)˴.)i/pAړd~I} ͸-0g;#/|u5R(Y"iT~I![ݏN D\9*ָSXZ0x&Y!<_gKěiRƯ`io5>ؕUS)K x(V٦=`{]#3HE 37I^*ģo(X0-/I1fv٨D^2dUy&xLk'˂D kkjBcx h mK&!o΢G!,<}Rʾ,y.8}=ꇗSH'# f^x~]/-XhImd#[t?Ivɢ`1"G*v_|+$H2A8t08%'=iRB'"IK>5 /=l(ğ~|?U{KgiøSZ/r腋j(}"i;sJE Σ[$˝ٴfT@FeR6 _Lj91 })JfZ}4}G+ӤL[eRztѿ.^{(yK*ԖJhlа4 eB&!Y:$ץIƑ H\mA:'\tS+0fQI-oWz Rm<O˜|6@T(aSB*oz ӝ`ڿ0nzyRLT ">yLʣ"L oIX %V,s犥fhrL H24.6-k-+؈DWH; )*ӆR#̓+%7闥ţzB BSnO$RV-d8S%'e!rK3xJXHDK*gh]yqI8qEFUĬV1l.03BykH.zC%Ll: ޸~eŲReRi8˥~zz TLjo.g \BݴBj0tTK迭vɔKIvh4^'7|\*WUJe8*>s>8QS%ݕ[̒R,i6N6j)7/&FZXbU էXf OnJ:Ec}uذw6giI3" GK_i KmtdF[qwJQBcQg3sQږ.5J7-9z#c&iC4Ifgx8KEfi]$ҧkR{E}NV1;m)s<%^p7GU<&U$_xzúy6\Ba4cѶv/}Ѳ^A_,oK"gLg^BHl R7D|=ys06bj*}c~9ZW=!pİPٯ[SPہJaͫ6m|gei@K)Tz5rd:Ux,O'(ay+1V~$4ǂSJxC/We]r%wʼnjk}HkMɞ8W:9z" '3%RВ/-;_&*o_(aZqC6"WE|hg.ZΞ:g[Iw6 hHļf `EKͣ9cb( yb32~Wa_V$lH%[B,۟%lqy,A5udML\w]W*FW̛!);Ϝ*!N ՞mBFiP& d_yqbXN7э:0<]+*fk݋>#;9+hemBr=H9l֊_.^:%eU[6INbf)iK))Cz9󬀴J<_jtQͧOMKiurWO_`gww 5I`iA^MRq6}=V@!}<(ڣbkCR>;1 .}#Ę `~o`%\&U>Q 判[*ՃU ul76H=1iNk-|F uz5!e>|H 鋇B^])}^u)M?, ,^"Ǥ3b:6b>؁,/U?\,}DY/OQǬVL[aD=vQ%޵"w"auF|Bⷘ.5|?!Dt%R?w~ivRi%gU"q쿏qQQpn ݝ$#&}riV_.jWWHK[{`mfi%_![&~4lV7eq%᯹\E >ncWJSDl1_߿WJ+a[V"A?̘Lu:SiM)s}]J+vb$iV 6pre~Z\2vOK_^T}14 *zc9Oim <WKݨq"Ւ}0g@]#ak5:fF⧼Pz S#uײ]knkB%oJ *mfNڒEQu cKϲzfՅOBBom+j쏡ţ|NrcRY?=tUC]3 DiӯIY)4z~0 \+Oa'e0ĖA+@GY 祊NtuXrп"I"I>vl!jF<1F/(=e,csE;#lbSoZ~өpTUnhiV#Tʜ)?ߝ<¥JYD9ҶX/+oUFraw`ox!Y½ogۙR{6 AQ}\*_ Gɪ;$ LTчŘ陻 ig]_{C^|74L|݃BB V^E֣h%^icߋߓh_p>Y В|QJzRsKgoy+LۗE2SeHLAGQ F ޘOo*0K%1MZkJcHxGI "JrV6K%~eV.1}Wvw-?|4떣wWϰhX]xk֤PhR: Ei~#遘X8}ץCQL=ۅF3S0 m`iJcsscfצ`e91rT$Æb305@oa.C-vT`SDDyU9OcxĪ˫iXF7D_ƃVYCZߑU΀c;uyYʊCAw饎"#i.h0%r[Y$e06;W˖ML!߹ݑ-Ry#gq[Hn|n5wE}6}[y;CJ}*iaA = 񬽯w7ZՑG{S]%1٠|? "@ŨbO>[ ul@v=6G& O[ 3l+v? R7z6u$_+/JOr-5+mY\UQ򓎖2}t)mKT 05XOP&jfNjկ==6 V?kCƹ@^`s"4ױۯf~OB,H@^#у ,@ kpky@jsGj[J7ny+N?J?a|Gh*)x%}R 3C,z:(..cޗ6.SA%i%PgHIk(#x8;Dx+RZʚ^FSҊw?H;%u7_f{Y궳8 3s1"S|J*w qɌwgÔ`2sl%fQhh_:%[l M>-9 ;pU88=@ZI=Կg7}r T?7w\JKGCN| ym_;/8B 9?[CHxx_VdR-M"7M\dkV^ZPhDYnvjG6u^Zc2ʔ>"܅Q%kRNKY/:h;o/Pf^ZC07˰4]rh8ind'Uֲ ,!Y%0]T,2-;eKyUxla0,Z)6%`7#UCVbBZƦ;oY~Y",G1O)^7ck5Qnٵ I_8vgZ) ei׈MGj~5VC>R#8,"W6.F1]&)2mp9Ka)ng8fd3D=C4KVP餄IOJy3|# Y1+ֲCOJ%z$d+OJRvxJOʒ~)IO˥ l])?% Liy71i8׼)FM&\3o(o:oE )b[n-)s\mC/* 7/m&47#) K93EOA8ccDxurCUq{vat$5Cit{V*lej_v` +َbAܲJ [;7$i[#ݓWfGn:>:ΓRvjY\G_sKdYG)}({n68Q0#32 w`: ,ρak |re/;ZEEoxԚ uM)`}Q ӱМZZ\l96CmK_[puZy3j&:~:Guvqʷ_$ڿ;*}h|$lpdcedIrt&} } 0su31S2riqUX+or4$PWOG_Um##x%0Um2IR'6;$uH1n6 3 |`0 {:fjjܭ:Vmꋵ ĩ)yqCj5?)@e.) 8&k@=d[+t$xڸZ~BCx# :fwcEOy*Rau\ 39ɳ17BmsD֖m<ӎd4Xk=,5fNL aJ,f^<ur N*ۖtx=KCO \Rwv8ܣ; `sW!$>wJBE ݃Mc~/eL\<^#OtYu|$Y5c"\'Cq s:!5Qx 9bScE '%O)cCkLca^A QwQ -D[F5\.v 0K8_60ȅ3s+y\WHU詳,SX/xpKиD1*f(Bژ8Xգ9|'0U(#:gbYK{;@Rְ f~{+A%w,Ir $Y^uΠl/iTo11Ճ3VU&b3^vaM(bXv}87x*e,eVi@Z;ϑ׫}2K#plUQdL~7X8@S̷7(o#a {w_g;,κfm֝ $ݠu2' m3QpBgk$GWZ}a# o/z XiLvdP9VzVţIWO`i܂y_[Uc` {* x2!%`>z8޵4[ǁ!OLA3UC'Wq¢Ȃ`2u2ΓeȪi$*Є/\d%Fs-F9W#q>RCE VT陬Ec_}ZfX}qIHOiM4VմT|H7;Y@A /}H<ТbJq!)(2>G`ZUIKe[c_Q'D4&^a&қX롹:91ѨjwQ p:6C8n浥 P؟ cgܙf}H!njQ6%FhtJc'ܣ351bw8倍G,-cUAo] 6qaZ%e IEP' kEi1B > 0("z8~l%2w0b_ vUʧhH*z R7UgI% GjHʆomtߤ u޶%6zzm/g!TAĘa އ)s5U{1-ۆ©#CQ߸/Rk1EzLeaMFƲ az7#U1N^ha&>37%vF8EO v `NaBdsZ:zxIάqSA` X͋08`V/ iUGpgfh7Oǖ^.q6F~S߯ƉgSX7$E0Ȝx6Lv[5?ɉ}!lзxU$u2 3 N41i[ 呥:aP (yV2SК̛>?}ҪZX&,q}ȻANNj\X[f0Qϭ⶙Pe/Y{`dZ#2O?ܑ#wՇ[J=mSwaeax<E&*UBxgצ s**F!oB3.u'xMj_ʫHVWͥ7ʭC*ON~jB9+ &bA%kLx(2b yY]|QX~E,1%Ml驙b]8ڪhʺ4SuY{[\~}Q"4J"fd6 w:g99Zfs͑'{Y̑+?mAe&$uǡ^+;SDqG0XK{̗G? '5Ac{}&@֊^IaPڵMel>rv˺f1[ia6Klf3EX^(-Kf7dfsZ1mrB]Q:z0E*yrp|shd1gH@g[Lٙ#!, l{]`MtY)[i\X]MLR3呺Hcx-[ [`` sŮ1SR :@ >E)dRwy|hfycqO׶Bn8^TQBIJwD+Gaa ⰹ5Nz ~XQ"-Е6Ӵ>314}l9 ;Ţ soPj' MFz(q4/xf\IQgUry2RDBxG`37 ê]sx.+ /B&Hm0 -"En;7z^ݑ"mQ,cϢ+{o6@W- :Wіg&y4W~-3kc(BU#1x5#?+5X;(p Tn mȰmKWQԞd,ň>B (=J~&ظ9`-F*YhpNf'ꯔUqB-dOުŔ>9ə J32(SۓUu),gQv4)+M{S<;wWv.Ie-lpo!esHo91B,W4FpVyMm |VmV[uj4lv() BS2Rޝ?SܗĮv&=cWgca(Uk*fj9Ȩ&\c.9VC@Bh8(*הL 3Uݒ(oo}1O`7hZer +Q'G-:_ĐpR!<`ET( ސt4p:}0#?fTf]bJX51u/uPpgqS?1| _N/i:F^ݑTB{L M"\n C:]ypst;`MQp|O1ȱY f-~淎&֑҇gIs!dyeTvA7Thΐ0 q6~aX$3h^DέI(ΊiKtHT۹p h3! iaƮ uW0$4!s C$~ :ECERюdC PNӥrZN9}Ѭ=*;ki tb˒N4yf`Q߸hIXT6&rmdC$ Jyk!`nNq1Zѵ/_CC,ǩ+i&}bo*SSY<#}`]msD.?ȅ.o!dAkN߸<p#^AY#5*ilː)#rLguUjrr7UM\AQU=(W΄6,v&6j/VŶ|q6uUE \ӭvuq.r* 8gic;ZϺX»5B/W 6ȮYVCd9\l7{x_xhNC~JQG}`m}^jOV`ZW*J7sl?33|7{G'o 9#?@|Jf<;9»~4|a{u\NyISMM>y[G*c>vtfB*1<'9UY3;͎zk[݁$6O{ ~'Պ |rB^RےMh^:/1Ok㧓άZ 征\qAk"븍ķXȳ[Hq<0:򪍜|ece^ac'w7LN;2Z93>|9Kzfsb@T9V?: /=%gBen)$Uh>eSvϷ@H}.jxS;ZZ *5/ηTdKjPżV18%R))smp/x8bvF*?SA߲df0,!elv(v>pl;i Ϙ`T_^ew<;7Wdߐ6~wu 1j+Rߠ< 0\DIpvis-Ә u9Y[&a0! > 2M+A5hl˿[Dig;Ӌtܒo >tPr32BUq4[ЁtP%5 ~W/ӀLsd$ k?=z )E9V3ݐ5()0{9섍8ɅQϛXLSQhM/ -+;:vxm6Q]܀ǒcy," O)nl.΍񵱂IIS斅_.|* &^HG~ e/x')g"ȃ¸µ;m7\=Aեx_(pD$f5^cC#iBB)^:u޶X-z ?'1} {:=abchhDu!`xߵj`B4Ǡ~<6#~?!'ID7N}Q@b  !צ8٘43F$`1@>za#+-I\P!& %<(C5 c#!+ s }L" ]sk+j֬&X!75r@ ?XDnP6>ᵛNdDt挭(aMepxهs@^P"IK70&b|ά$9%";C$6;*zBlנnf-QS"οC@g&xܢ\zgۅuJH)c°8 i<6D@Թ/ h? \7Gw(`,}IfIA8>5L;AMǂaPS+k*yUvمypP @|&n5hVUA6PE%|pɭZVy{."6$w{eezG~RvyKАBG\Ȏ'*|gB3,|_͈v޽\f+DUWsÂCL:s`'{{iyJ;"osYV"1*}ʢ# |ٝ)FHA3w=]FŐ|jDP׻r(>/5jk\.'jZ19ʭ/aUsbiX.Z%U#WqqEnT=&^WN *Z3#;eH+ijCZxBZ*i ͌+CZ%xoQ*E>Gɬx ~Fō!#"rvQWn)kcL$aZ[(cPX*h^L,1J ?v2+Ѓ JS`oYe߬%Y܉(mvsFGs.M`_i&h %SѲ׹ɣ[xHF|!JCh%g0P1ܳ4FbK( J5+(F Rp Y= 2RUy/QGVq=\ths[5;i#雥F)sEgTd2tVs(m9!\5K-eUSp*4qϜQ-'P`%ě4 >FR߉G2dE7Ѭ`o 'cq/,6ب d<R6 !+1nj!}scqQ J%3[Ѭ ca;i?SocGKn:YPfMhXfS EQG*P9Acr\qUO7 SdI}!MCy(,xiF]ż9lҖR*"Qw¿fۑל( m_͢3.A&iWQ`=v!ZJ#TP9P96fWXP/F/ =رC&vŋr̸(;BC=8ZO_Fvވ^0OQeGD/%lV(x]B#J6N<Ǒ#rz|}[uJ##2r$7"f9Aⷠg dT~j$߂Qz*,;,|C_\ߵhK.h`zўb{Ovm 9E\u6.`BodзEnAkSZSJΏ\\P98 kJ4i1EdE}‘ס;QVDUL.heE ݀p(;"|5N̹|O̜3{Js#E?x-U_-_mɾ`֨*BYV|4V@=ҐD3uZ7[g1~%ȒOi$$W)e䱰FN,c?6#oD$e;A@CiV0%ѪD'|]˸V4Zvz~#4]6!9s#}jJ~eWoܘGCgTA~LѐOf l C\u)~( E8f (Rʧ؃[9rBG8)iraXz[:Y.n"Ӭbd2xʡ(n1ݐ.Xt;ShE};(jEdBGq闫LXa_]B>XV3hdhgr+og#Z 8eH:(DcJMKTNCrѺIBB_!ݓ[RIf&J o13޺GA|R9j t(UQ`]`a @&[p& "9*"ZmI(27x]N#B呻D{ ɀ)%9Z/Xp]IE#E5k,"rs#)_#rn=وq[Z٭?k!SMk#Oq)GU>n GoⓂ)ۘ}:I#s81GAS'a吽OqoFǸyn9_@xukPTuξYdY"nF|]?]?3(LJO| «EVjZ5/jA?gkp98 *H ra#< N~%k uaklR 2qĀǚm`g0H3X {hnB<.&‘5bX.ehWU/4.#ӲqGM%V)C8pnc2) >†83 J'7g@&x=$`͋o]d{RᝃI{ ! rxsH8=iZÑ\ K@IS%uB[4Wȭq`їF `On !)`Sj21}UQ/-dzrZH}<n /Tj^oqg0L_iT'AyVr%Lr>3"i:TBignnMƁ=.\~gg3 D޾a2-(aFO$-?bbtrJI >oW3ad~8?7 <8¼<&I-O:Ix'.8 EVf^GН ci(8{ _LK;=nhczfjsYcwZuVʹPrlI N0 ]ژ%xBnZ'|rդR8<8  G6 ~w0>Z9q}7G{o!p-R 4jyCm_T"j-Мz_wAJRW c{ #d|"o#:<Ν1Dq N[R/@.J]tɂb8A#=?V1T 7$c3(M/FqU~~8=I)Г%uPLZX%c >p/IBJ>H'k|}IX?ҌwҺ̢6)WWi+'n t*.R۔qfۖp\ wI A:xߔH@%/9t Ĥ,Yqi D z&JKZ|6hbmXx)]#N'ցS0 j=[bs$=Yn,u Pw{$}<p bv ff_jp[)aoQ*/IwBx0\R9tn+r81EddhɁ`Drm`UfƟ Q$7A !etQ#.;;t$7ރ}t߇&&_ƫcؚ0WG$?[1+VuWfe߁ oqHUG,4yx[qsWU%7$(R/t8V[E:N+Q@$߿\}׫#ٝN秃?fzӵ;gɛesf;:8Mzewv2OO?zGwkh2 ofkar8X;U~G;8Lټ7xy89'/`6{>oћ\Lggc;fFO Fj] UN&oY<.ɴy0] dP LJw 3fixN&7_NY}<_ {L\w)18Q1ntmrz |0=M,_mOb Z->,>\.K 6cIXzoܺtr0'i?p?zM#OϠ~o6X;×͡>k>bQq;3<qs͊Á{8+c: ʹfDkc >`fќ]oqk\eT*VNˢh,wi.6{[5̸y1|8~M&@m,6aǛ)lL GGɩ=~4%g=φi@ofPe,`p</]M}Ek?: ޤGc!Q$:v\So:7&~0'hVhatzK7?l=hpW+l@1̿vL2n*53F SIkN5mjcI4s$/^,w`v19NEY:tiqU_9<"0trjz'>3 sS1:ĸϞ7OW8AUm|~QKhx|>mW9Fl-B<$x!6"[^~8m\7zG-'nzX\OZptIi|^ھR=Zlʦ* fuz^b+ziٜMg&+^2|pH#MޭΈg_kǔ&a T ({q)LS4ǫ#Wo қzm$xYMKg$0VNlPycbju\wv&- aƓv޼l-&iۣՖ?{&;gmt~eA+{sXW7i|^|Rc9|[RL:8cfDJ#ұLDFXB?05WWHI] }F,7əX\Lα?|9zWH2!Ǐ pbh65](sz*U }i7JŸx3 }YHE7Y gldy(_nߛ;Ǘ1{6u/~Ixm #C+#k vX^]9W\ɑtz!pֲp4*@T&w R1~{cO<n`~&h1Q6JOŜ-=WHi^:SXx8ߚk׋zߝLD#&qia#Y Ӳ?y_{и&T<|nw">QN ßh[<FD7óo&p6:w ?m;fu|1'.&rIZ \6Y*5T\N}=`}LJ 6_w\֗u;ox'SOGK:L)4dI&MVO<:`ƒM z$J)hdKvh)QE_zyMPOޢnfȒGR|+~k\?vy֎Y\NSO%,ҷ4mo8_<65]9}KE)9PPPg)Z7B]a!W6aS}%WPA%;^f3p(@D)OD+(3iΣ:Q0E#wOz{?o{ӱV4Iw' X]L "YL *gU)19E׳,(0:kp>fy>Vb`|&\"I'MLw"`kG"%_} !)\ , ~x*KTUhTb̒œ>ЄEQfrt;{-aG5;otL?(g*Eސ5ėÙ qĖ޾}ۅڕ]*FBF @ 2kgra4 %4GXZTfqO}p8eEq0dzQ=c&H5M0#mč˨"̐^Xx ƔDEd7>+w|! _n P!<#E?孯"kis4M$/Q Z?^5HynDjv ظnB[KQbշ (/@7wY?uGǬ1W6rDma?9 hzH#u<.$3SDy±7|{s28`NrK͍|JaLٻ#dKVrTYo8ˊ^_6mgy$\ D6kym&|9[ݭ~+/5c2v#8y2&G? Wdiá΅YAVA|kr oJ9wQ3 D; &VewΝMUAlwn< ?Lhp&߃غs^bġ&g#]DVVtG[(4 EWĭ=[rSӴs~C\ $B¦ѷTTrZ%CvDsE[U 0tŒ_֖E rlѧIJa߸Z.Xd(cg 'J~UBfroZC"^X1F0սŜ ŋ,~yl;w6~ .^^&}Mʼ,O/v 8 sLqXgeAaAAkFC uv|P/D~xufbt~|lz>[c2i_ugVeeYI|PM{/WVW';~+bׯ?[;HLXa4o`%l..`ރwЧ$u$ŷ @yF_14G+CdBrY4谙\Ud-v&Uw:/6cuT- wrP&RXKf)хʚ]SMr owXN}WLrN27qxAO{EuKzȆ.Jb/8xLN ,b} qo/%t)X0FGuIzmhTvsͼLAG!'RC瀡M䷘F i#sC`ϝC䋃g+u-C xq#˨@фn hZŽy摪o"k}]o7߸i r_]b9|2"޼!z)(&e/]9`,V.v (vV$XGYg˛hPN_oV*u~}u٥ג 3J-v8VoDEa_ԳrLΊs(cN|Z0j]p5;$T\&_O%G GϽ)}@ٳa-c7l%"}*ܷe >'JJY_9<0P(x >iXł,wLzΙ|BTc"[$Ec &= GDqNÝY $2粀\.(CfI6}9cf3yQd#Bޏpf dejȣ\A>SېB0cuR93"7c%=OM3νH!\'+ʎdXS/=*%C[,d!>U[x@d"D%[3b1 3h!8+%l6Vzmb+~Xj6@: vzrܦ(cHѝ[T)dc &rt#&OXQA y9Bp(NZ2Y|'KBR۝&%TN4mԇYˬ4DoGWuRq$JWhKs4*>m43L&M4{O*-?s!d:ux<@(e#di;NkV'O[&2$}O Lj[lb@nOgBmLez[g-ml"(%TNKJ՘Cu҆\~F\[OɹѧʐpM-jĎUG݇nwY<{_R2YvNH@9yRUj :Qlg u s@084LRwYӪ󐆷]UǼŮr;b_Wnc'C5ʗ$Cs75Hr;#o(JRmjchjע-q#DXԀh|5j26Bp^SO@^"G⥒x"Qd(/|MڹInV'fGD%J[BvVVj"+_3"r,a]7o27L]ތ+ϯmas0#>G+~ҵD̏+ v#_gYQIA!(M]x 7}rm6ZǷXpR(CK De|jpP\.wDؒ,8MĬت2| Bf{l`-[xs ߗ)ZqVv;O1k'Hna١mSfut9^l}h >#-\DkcѐA;\<&I:-Cq~TwcUTvJ."ҷ^ /+#+c^M|[M{И@S{(o:ȑq~ʽ$p+nڑ_J&u`ClsvNٜ{D|ݼ?F=-5t3-E9'فBՐ]vevdl(Q`)ndpw+]D;zX lJ[ƅӹcǢ7A] ߙthwzd+LH?fTtRPF} NA7爛̆ϤtRmC?ē3ǫ&礥mdGh Ԓ=vY N9K]Jiims{枌Pi~idiqe @+u&_f`OzdFAL7I|1={5GXw'*oq [<*[瑫k0>7Z|S}O64K|[6&ּ 1G:o<$0ço'[dj| i\n?J*F#A_pu`<WU?z!7,x{57[zh9"M|e) .E'}j%rS 8[zZnkI!W'|˕SJz6ߢGP<ŸmeΛ85X+:dNB٩(5c iuZ\"r:7?|m d%U:"b2L$ E:fLk&D.dSD^DXR$E;o=dn:\X 5~hy*3v2O 464Jr[6 O2b *SL4VDTcmq?Vg&>ZZSԬ>hqV_]9$Wy_N\Ӕ$:ux~_K2-Pb%( L mʤWzh;|Z [qʹjr-plsnGXY+rs7|oSeo,Y|+ȹNkū%D/DŽh E it_F8Wg@haqX9WFZ/IQ*BXM1H!8}(Qk->#Py}mKlWudYzD&`(0;h5s] @PԪح#ǵnJI7$4ޛͷE7t%LfGdàceCfY,ɱ|X6%8K^A_V/) ކ~iS !rU}J\P 7ByI$ᩅKG%Td wKW<'96\!rj/V_C2P}Z gu߹>OAWX@uiPa&Sb>{ĂNi|x ne7V:;eJCt!no ZQ$[KO䕍ƈd*?!)QQB9lٿy mRuGf= r{&j'eX'Z.+q7JaO5/UbR"Ǖ"@ iFz^5$ۘgM\@9騅p(g}#hTL7zeES&" ˺!M+=1?W.BUk9RPX;zTC `b]Jx)QVZ1ZSz^T54 rtӅV6mc)xp6rTvoL0QPO@DA0oS݌̼4$83_!)E5m2.WgǰQ| pmI!?/?yQ2']rLhWIBEyݢXSP 1nqW|~,XD=bm8AP"rş|P P)j+gG15ܘFv.\5o2ࢦ͖R(S]j elů2}Ҥu2urh|<5t}?`EK9ՌLd68~8=[:S@p΋ @N0Y'Yn$FZed(NYzk䲦I]ٱʷVjvöxu# KR)?H Yomd_ 5N>\ _fP_OFC_DiY!2)2q;z48/G홹iIb.Z9χgaˋ_ x7K*:,,ly,\JR6ôի 206i8hRXlK#1.8UVа>!fjXdxN(fbh<3 d<2E/^M•yYU],Uu!OR)'tJ-X*R fv>5߫}_TU ٭X:MsRaf$Sk>òA¦Tsd/R+XpCfB±Fz%eyyw>}v.j_6v?1N1JWcmY 9dv%8La.O G%(r'OW/8 =8ۚ} x-Cq|GiFx-J*(o>`r>ICZ[a9LΤk'I$tWTl9U]&9Z!H`#~U=OIV4%%<)&US{G#?b; LN0]㥤$~0+#ғVqcv+N)Z5qӚsP8 D_}SJcgĮ ?an= ÁmHm.U ՊC.,[SNv-)Sbd  /OjQQ6EBERTm,Va}VkIsQH e=:O|a?>k?|yopT~Ѿ{`g_l}hi#]g %44a&Zà(l)2l[>Iƭpmq.2T^KawIO}w67?lēJ9 W,3T)4@Eо M܁lƨM˪׵¸yU?8W&Z C &_BP_$iyz Z1ʣ޻Gyc~GZ3W$TkY<9ivXyiMkC*Rӽ8 ^^r>`jWB2Fe<WXE8n)%Nh"A ѡpwM`6?'; L\Mر([8J,R5P{wg:*jAY|$8̏ӣ_}ӥț*\By Keܘ)n-3̩ƾ D(?oG1_i|GRx!GIt0Rw|IhԘՌ>r|gD +JE* S|U*C>Ss[㾾`'9F6^HkKQ.4sK} ޽ T8;֊&G5CM=oxz~ZMsV!ŘԗZRGD[f$#K*DWDe:C)wnF6C)kŮѦTÊ;GIcZ_Z r9ےIʑlRXu?BpO !-J!j *vW9u;tl7˂T=QbFR~g&HlefǷڪȹξuDn( Б^^mDXx:P[G5eeh2)yz Q3T ʬʰՔ&K<pBS'݃7_ʭΩ%&zoц]X:ZxoY-3Q 2ڣ?22%*;[CRGd 7U)mN=07s_0p Լ$yDQ |Nrd_{bZWNOoi$w%U2;$z2qĞk*_ߒ9'H>qx2o{Cbx[rD{Ӕp0-I!MMQ8xeʴ~{Hwߪ|sj1mڋ{g^(ů{e 5m*&3,NgC Y*)Is71lBSjf0b 6jWupWi3!C\{Եk*2 c,/)7r̆l7@][52/~:n!(\/͇HsvYkI ;ˮg@ aVQ/4"_bِ>o#bM&̌ I{2R<}3XkW{C"RǞF!*1d YGhJQ<@faL}#3(j=z.t04iQЈu lv}Uؚ^qxgYK74ud^댡$OW+ =t BDLj}`Tqy2IY6hV % TL! DbEe6fé ,Gl$E}FvmCs8ھ~zH[! `%L#γg*&牽F]tUVp*D~xn3WYvGcն8:UL'x ߑ KmD^>\ۥ-W~ 8(?:Cah+ Pވ%AN):~Q;X$z탛{P%*M&/=]_rXWBBƶdw7|eMNB.Pc{U.۶K9XƧߩH`&.h]`s#†ڀ~XǐL '= 'v$d@U5n6 ~K0 Bs{:ɟd$gwjds!SKauǶrLDB|rJM8p'-nqo /sy hU;[vjva@ U 1Dy^*mS# ZCXw-tꠏQUp܂kd&o90/#f;ge*M:(dRgc#tOU9t~^"IRGM4)_!T)֕t>,{kC)p)}&R/<5S3gi| A0o;+ *ؓP1u{Ʊ|"yDщT dҧir)U*sObsEalO, ]ˉAJ% %Td5Pb8W>5MOHE\S|]הӷ>el)5~_nF}W^,)):h Ĭ4w~iUVh6Q fE2 C˪M2YtL_oݱ*}j -Ng^GC{apʚ 8o։s5#h*Skm0#MAi eZp6\ZErhƪ0ūg(}ekl9nH\ơavQuYyO>x&N*m.oS8؋pv}UT"6٪LNܫeO o TyalCa7r ? MgߢkG 'VB ؆ qidzɄ2f/CK^E&Ew#8Se">Q_rjZ&>F}Dnò F/L7%Ft,+7q%7g Yc+t ɓ *}5'g6P;xt`E.xwTSAf}^u6avj,>@jGИ|Տ<@QW$ $`F b.K/Z$Mrg9SA-5ɁD& >$Y%jˇV(l"]TBh؉,Q͑#SDG y~u9ۼ~$Ʀ LM[V@MpS0`|N>66Vx'M.>i* /ZhD)2%pAE!w,q8bB&Sjboj"C"Lm:Jv 񥝢%8{wݵtHYиt~hRcF:1\>z'>׭"+8Y`uf o , h5*C& L1)$D&}/E2 gn^&T4ϚZ7@ x"WΥğbkWA6$LaO[܋U—heo2Lus;G{x4eݭ&$]8S:%:`8[*0Ω%tTB׻-{?j9,Px60d9n]*C%Ql~"Kb7 GllܫyRZ!ТX9ce{"Vr2]iC5t)8O2 .q6bAkHTI5|cnjw4ik_7d;#A'{B M;?X__~UƎ%E{[_ݩ}SuzS\ w)RE> ,}yUgͽhBZJ.ng6*}\sɧ҂jƞ.30g:5X`jte6+%*+V+jUd!%o*%V(/4 t[Å(5{;w䷵.7Ap~_lӯ*%]-;Dma"&/&IoLL p^E +]+K9.2^˷$ sř<7X&`a[(ګ@\;Nc?mwni|QO~bkOQS6c"szr)2k"buu/7C~mxfc7ѸYr)zѯXeݚVE/z˴aMKqn01_9QܖCA5 FB62^,ͯWTJ4ɥ2*!qߥ;AJJıbNPzlIf:CaGhjڅ{TB m=] Ċh7nS/G.ǭ~"k1BUi FrUcʤ E/۹^lCXu2Β&rGI0 }eCOLב6&ִz@-еKhaVOu42_r&ȴ>>Ŕ cADR1pȊhh49yK9ΑҖK'c^P4@=iؙDdVj5yA)Ӏƞ_O NʅZƤ@3Ov?%0#dsC1g)EF]Hmj:++/w ^8>Y3ʰ-gt+wYsr&Wo 0gqC7VQeByjyBi}>L䀈_gM9~{Kׁ0?^.ԺŰ\Xom?l4DR*2ʸ]_?>.'L|7'=͗i$9>n<~j):AzxNfIvؿ^!~|m`EJ S+zmz[8/^8C?B`erx:ѭΛƴbginQx O+Qpf7"΁ ä>yptVoobzP 5Jp3]и6LIE\DU1_DNt+ͅT4rak/`*.Ӆi"U}3?I!{t>O6.˪]q{kE~6iZJl'G6iN ^9ْ*`w9!Lrj27+jVxlGu )KSoTiN| [٤p,~U-|0Wٶʋ\_i٬A,{2HWrn1{[w(4Ϥ@ʨn׮M ֬1jJ0w% j_}L*]9qVt+ǭ+X7hҭ#"!}ܐ|\rEq^9+JUeˑfI^v̪E.SǐT+.\\lsm{YvK\bzL6Z&kU4sahE_ڳ Jd?Q9K~|> n#iEAu؃oO~ŋ4wvPGf|eQ06xW<9u^)fJUSAQ_Yqç~@C/#.czn,0, ^R1uk۳t;` ^S9WMi'hN&?ə3/gL44lؽY'5J5LS]b75zct_mvO겇{q:9;FIZ 5;;qѷ  k-H"j@UܦD-v$JHJU_%b[W롥,}4LYOo'cNP; HS'%kp[]x#JR nSnu_Koyrvdd[2Yu֝2ݭ.I%:! ̎Χ{.)syIGw=#hwgIjy/9v{7#~r:9˨Pvbɽd"RO҉ms.Ι^6 uÎ*EN t*XIR8Θʽ^AS84bOo0ll ;,=B~֟NɚK{bFK皋 ci~5m歍z&/^im}hr[P M8\6SB1go.pBz S}Jv\,\rB\ 2TF ,NvxT\~(&YǬ ̴gc<~v֟>'fYyw7ق6r`Nu:k1uqLLMqkm&elvo/g!:հa/v"t427]pfXZp_sNo^fqafVbq;'GLFY:]:&/kګP8vrvg,d@ʮ:@3v}}ָ@UM^XE-S .吡|%?kثZ]3wݢF~")f\w)Y4M@({<7S<Ѐz^f& \ lԁ+K*RUY2{Q%l$gА y٤yos~)|<('qZNљm#_zaZyZ֭U4J_Ҝ,OHjs\ ηr!ѩb͊?p*q4aqXU\ZPPpWL,1ء vNEc>#Z uNýɮ-sThE]FQ\0ioޑOEЙDYժrG9.h%^:@d}NBVU)3*Z%l֠~=A"# Lr꽳,n}0|pa/v;yg+'Y: l"&  1sC)$bwaĶ&5A(O]afL9țX F>Kԍ*ZBb]]+ߞSӾuW҄kItm)uMAqۃg:FlZm0K#q:+NHN+­3pР҇JtKy7~8FY̵KQ%i5߲w+p%:5*ti)m&RT ŵ6o<`M:[ wnݭ; ^Ws.\*gX֒)Znt [0 > Tܘa`sBJde7Һc/USR>F1?ϙ4[YIEk.8~jI)JZAvg|$nZjuKRWV4!iՀrmhXCB[&\WIiM7flH >togkHA3[Dlƭɱ$9̴`:ǯr6l852E;\5vde4JyH0u诬F30 ?{O#)gl:yӻ;^d2Մ99n:!te2x3ք0T҉F"mV#3m){<|GVҼrb4 Y̨i[&IӪsA%R Dj?2g_x*2턿 jY:Q|;6mbQ%2V#g0;NвPb~FQ/!csGgvsc@7rrsS;AvF1`j]׳ӱ 2Է/~ z)ovtd|uLvFR)=}Mkm]+ ݘ b(}ɷM޼'4z,;$WǞmi'p|[[vopd4 Z\# SuyC="2M> ؙ(jy]ߎM$-AjM ,qfgQ(jILf&n8vq!oۏZxWyEi+E:46B>:&0ŵ;NBڃJFܽL`5>xpTq9D4DZ ,j?a! !E$v\D~deƳ 0N%NJZF$J[ҡ'dQ]{y[\:^"W#͝Oo±]0ʁݩb x(J3ʃ'X8&ɯϽ&m}x31(*U4'XU݌>,:\5yWih \B#8[OUw'ßRw}xiϸeigGx 3SiTCK,%h)U*Rfe]e!`^0I;.#ғqn'4J{LΞrϡq1mɸë:{5 k=iH-@Wj(_hyA60.@>o!/,P4V.qp kw\!ep2}vqr sÕwrA9%DUe hwkp!s8Y e,\,~-ּ8 jUq.#_wGlmrpsL8ѡm.U1a+3.ODrx*,(BRRGeh=WWwֿmIoCie+9,>'/'tNJZ螕e_ZIRW-sUք+!NC`n+CaNW擳RhtNԾQDNP^ 9@,Jž~.Y/M2oNEgCunLwB`49@7ʗ CF>KHti_Dic(F5v ]-`(D=bU'965Fhg09R Djiue5$O91Y\Ԉ|Z0C)#|ѹ٥xXn|wJICWZU LN=sM O(A%r5%М-0…_o!~Fu5sEWU/_>eG.zۑh,L+ԞXQ6b)؏L ?RpuCgk<RarXup =_O8N֤f M>X{,L}NG]G..ƥ`l?a n{\yu$g*9E!K)V݋B#,0xɮ*qNE{n ꎋ`5Ksө|曞!9?')[ry?;HNq8Y쀠Y|qJscZ-sgm Y yNbJH.F 6(T?>o.ٚ+r`BQn+Z̋K6žj9=#%n*5TOU0u[\jW[B:U' u1vۇEOWq tdFy+'&_{W"VAΉP|T^O7@݆$l<])): X&Dja:Oȥ}f4:Li p[l 6T_ Zq;\E{uI.Q. pVn1-CDq.= ZH= X v^XsʕAʧ>#?2+1 K-Pe)|ҪЃqK.0SjZ};p]l\BČ_N2e0Ye7N6uO6D^$yrb esvҦ={êU)xĎǯ}{T;ugjs&fB : ;\A?{EJcMjظ H)w꟟J=IքóI0 ! >OY&׏x-olCnTKMI7S軟 D]l+~y _%]$Vabj^Gj}'}a $> dyr9n2iYNS@~SW/"1MFq\#E>⛄іe߲/WuQ{ /t.P3eq}7bۉ챏h?뾶߃^K!5<" %E ')\htícgquR *2 0NtBH2ާPMQƎ~B[[):{vP"Uy+\\ifª5GVt2i\gEZt cMݭp)ǦR~0ȬWZ=<%ˉl\*TdFp|Uz:elň.Q[)3NBA҉i}Up!|Ǿ-Mjj9^b ڍRS2 , *Z}nӤU4 P!$H4<:#zR2#U|G6* r!q/ގ>a!zy1Ѷ Txjz91:_[g zn y3*oN v$Oz)qvXUn8cdLآ/IdOY>3ݚ[sD&rT;ҺUshDAk[T6i-Ok3f-SuW֦gXϚxy,xZe.6Ȕb\8I\?E`*м2$-4GNU>erE;.W-H6Cfnť]]nX _D`[hNL\[l ?>zy}6^/}o~WUK_VPR9/_~527Zn~LȹNH}zhVI~{n`/4CqhSnkRFZ7 БSe8<+tنՙ\K"bJCVKWDz~]W 5-DTõ8Iwܴ}z:;ҵóo60yg)g 9UŎP"@y1r&~R9z1,H:_^"/&ح @V'+t鋲.$ Ou oS9p)$QJdS1$NnExe}RjR7uy11)@?7+nV0R\TD]3ӖoyQROHܴҊ]-8k"Й$<3&q |2Z.b03 g0FS9n(_wz|&#,JlV/Ă :)m g7J_z-  +3jV^^cV^B?,һW_׽un('N"vfV(B2V|=~_!a?-oc?~2i\nxU3! fܥ婊]RTehT7" 1TG8VĶ)A{kBDz{NPd'aH7)󌈢ZID(?_I!(qk o2V\6o}z-ְLj2NKv_ ܪ<y/'Wƅ*ҢJdL[,ēyD[ߤu\c8Y>D@ESJEKHiJl7 M~lnjlRu%E&푈g,)4IT H- @mϟ||wߑ^H8>9I栦x'q1ic*"IPV3Ɋ' pSKYc=U=<7Uur ꧶M'LY4)KK nԂO[A^9$5:,K#V55n-4P!KBHݐ9ޛjYHGz<*-\\k"^bw0`ge!P,+&)6 Z'iʐXܲ\ʅky:g]RvbE]5ƎA˓?bM82eI2C2"c$>vq 9H㰀/0+ .}%C6%+L *A[$ʨQ"N?Ht73 K]<|7h6?)MnA㓈CE]cM`(H-q ;2?nꢾ5%<{Aj>l K(2+wqw? 'W2v=gNMjқ+B<'5 ;^-2ׁi#Pvmے߹v_pR15K`#r,n_yT}rx~zza.HW}754TAr<*s[Yj(~J\3TPe7Y};ĖܵIҺtvMm}._q\hq (ic-I ;8-&zr޽ErrSD*/@^Q9Py/]f2mkݦfOf֤U؅kAvAq&'eW|hdOYr!n^Ό^yZ۽\4f+zVP_h5Bf9G3DJr/1%\ɻ ?hkLWR|S*du _ޙu\w-L$~@pb&Hʢ-.CV4IX،D1 (K&r"֭:u*jv"J } ˇڡ ڃȠ  |\ .A lj'܉bʦqgrrk(ޙ@<\YQ~ݕaOՙD4 Rܐh!l[ h릾2Ί HLwC:F#/i9:̈́Nt %=xr/?r\¤ޏ?hM!QJ8[WEF9Llzd!ŋ,T88'm {x @JIwR*w@o)fcdiαdmoRҍb.Nd L% ztN-FD6*5 `;߬-wc)'ռ9@b7-Jn˄^rTfܖx(py9?IĩR*jfK&>/;k]0y{|;+MeiLBJk+:!]E$FRPt39;m-i:l+`I`m DA\\Bf7u8#Kr#[{kJ@ tLrPmO Xts3 *2iDaScwN-R?-ol!u^8P%9WDeX$R.#TY:uFF Vuxē݉rCi:kRQigyߺst*c jA;kXc>m69ZU>\e9jvXix8leLfr?TeFwǻˉqgor4)pH6KY6F>n-mOAS^v$S뷁g·Rf־nkA>[Ww)YCS#/qǖ70 aNߩ;v喤l9 v[ ;R괽M*+&*mF8-ǚvؒl*{!Ԃ} @:ILX7'!,*@~Z.3esPb9C^zxk0" vtnIczc cII1 9%(b?}Hf\:Bd<:ZKZN1{g4m^vEuF,-F^ Mt/alK൚ru^Unl9&r(-RN-;cnn_Xk5?[q PWL-mHEyt҉uCW(tz6h9*w kșnPWi~Kmߩ`Fq]۩*0IǟIH&sNՊUh4R3S*"d=+Y]i O4{}Xc$~bRy=CPm6K|?^@h>Lx;Zo@8A╹%5.ubr/'?urRr[eQso齤Wzz7KmߩKl:95 Vӝlh02 \J7ǻ:rQƖ* 6W%},ZuG~8d6G+[wetj\ lՒnTϾA1/z2#_ډԄN>^FY'Mn4Pb.i^ 0*"} ̀gzdMyiq TR`fžl).'GgwVt wZ y!buWE؁W'ۄ$8ơLBrݷ빬ީ앗Zle,vvt(kc܅\o<.efDy7 3yׅKYcGe1W(oKQ+;5u;?i2cOO( L8eY؀ lγ=>w lp2KC_,gCq`:G0u` 7T}2T: aH/ErDucK%ij[M6Y|Dm4 6b`avc'PqϾ7ӛ 0 Cu/u%k&Bu01[p^N_18n|"Ӡn~HT_Zh`(E o:ǽ7O^d?bhv*?[\~5`aҫ3%E9Z5 uvO@5hpDx seIP|aV$Jr9A&i"i4V8K{m>=CMbPfpvR&⥈5:;yLzUN]N<ve!} & ØIb;=8öM(8==1lta6s&Hi97"7eN^\@eHoٌ Lx'[F94Cڔ"x%בG"N =8;iļ}Fq ,@hꈣ8ۄh5rۧϮLqp ݳ}4mqx[NHBEȋ2'Ɲmra0-6CgS:8\Ee{-#R0yw sB P8H(f 3uO+a-l}eaUw m J,H(DIMO&Zk O3"%oKb-g:%Xucn\WDdyӿeR>'o!n&XtAy@;E7, @GR.LH#e˅B |==RysD2L|fG27%B vez:Lk7ɝ'8UljOsYKXl"ԒJ}C4[ifw?kU߸Rp# _h "\Q@1eH\|G=~L'}vǫ{ҙ $HZѹnۣSM] 8KBļ[靴#IG[8Rzsi:'8ZXLȿtύ *H 1ȿkџL|,lj h?˦ØT+gTK;Ixs;x=)zעQB%BEuNE +\2wi%vkZ1&^ߟ!q{n{ -|Ha #)gC$ e}H"S|{!ڑt_cПsg DCg 'fdTӅɡ5Yv ]zj . Ύe@C&4C#NРZXW(ᢐ'I+x%3{vR^:?p}J膵;ULM,჻-;E2. ",wBsV-sa8$x>ߦZdY-ZP4CȵslpkEwD~,38' *.=~xϏ>z ^`¦z,Ȭt:p;[?mbM.*_@R 3m§wיHM!%?_*kyïj" t#ljm,P>RFIu;;o~r{sb}򁭙G!ee}}B/aBb:O$ >?.<øp.5| Y+<|-]v[v:lWquH\7T#pjZ?GQX,bb$v-BN]tݖx锼kssK F]jHI¹k`jkFuD7j~l,:j_ka1`y"a|1r&鬅Q?\7>!0dgg-{w~ X[Ak:=3ك?>|3z3z8O?a;'y;VR曯OA<@GyXΰd==|ӂ;HJW?N0L@$$R4yb|h<-pn;q^ͨ=߃0~QWХ]e,4?/+s9(:/ɟB \dƏHMo2⥖qh7??RK~L4pG+G?y8"u@}'VTayC 7p?9t|xKhN6Mܳ# ֶ2ȚA}u_j,5efeY=HCn>@9aTRfN97@3^6/LcVB^"o+S. s/uī>gHy02=;sM;\?.;2i6 мAVrL*Qb9JYפ-¤|뗅2Vu*a6ȅ805FN>(MaGOjk Mկ%4{ۯc]gvҽp/2/)KGr (֜)͟0[ G׾:=0n$,op7>qvݙw@w )ѽI 8כx=+,~?![暥D2Lo5!ͪoZsR=zoMg6$HGn.ZX^pp00CXm5 fhx-Pl8DOpX-af7h QuD#=HJЦ_pK-xYüht 7[w ]7-?|/&qhYB57n޺@rsF _s-*Ďg[ɐn1f͟8_0W%;gŹ|}#B|[yscgSRnֵbBxߐ<`R [&/#%/YYK>y#bd]ư P?i$8H 37'sg؁d.:m8Ͷw=_`:h7>́]so/?qK<}=O+8$(pUo]L\ļwdfg6,O/o~¶'C[F5b9Љ.M'k_hgKLr D <'|3 6_Kn*tH1"Ũt|f+ i&޲.3C9ֹ38CO(r~;8Եq(&\*_m~Y1cBŗf>+I9o, ]{ł'kg'4NhkRzj*nL| *d٘ IՉo||2}^rMou}nݸX2wOg2k}LwO.h{gxi퐅`9xcS6 x߇mBMMlEu0@WD Vz-ds>:5U@ ~eQ9G.xq$5z]#V#o'.WdL~͏ r3wx>^R;TjʱdÐб˯cm O-,@11yJY/)S1An;ZUzೳT9}!lzŠcqqp dL&|8"w-I(G8u edPR;Ѐ}?,@] (TM( /WɑioD;bx.3,zRIH`L^wI5mQ:W_`y+'JHK [ʃjo7^jO*J˞|I>Fa3HAEٗ>3uh~: 1e,hve{wݟ[1!e0 wnҰTΟ6Hn~5m 6K /iBi8:Ihm΁w}qM]MV+E|N!=h(h-#\uZ)62 ŝ zu& Η45WprAfP;YDHU#(yZ= Xw`E .w~KrWmD<^cELۆdgMo2|g?{:*=@HV/`_wfNN -wr[.iV`4ޅ Ec҇g4OI\R +t9Pǔ"ՍWj;ۧQJYyc^[*!fiAX3/ZK^`9 wB.N.n >.s @k`89%cNU5SnBwyS!t[p鼍no" RʋC#]GUBJa;ʧH*W_;ڑ' PګqLSݥժ<a"0;eIeL֐x6'/y]qxm}!i~BCynlB!2ݝ&xy XVN{ 739}s:Hxî*R*B'4zrXߺΈ 2t'9ף `( ^J% '?4 kl}88Ȗ\ PNXTAz+|cQ!f;oqdWO?_kI\Z0tStmwVG2J^[";̬ˋ8􉠢f@=IP4\ahRtoM?{/<['ť2|!|uFmUa)q8~YF8gJEq/L՝T_;^֢`>0bQvs"& '[v$NI˕@>i%Јg#X!u뚎-5PuȒQC)%eIp:Xs ﯎4^z@ڎ! J (Ϲ:nٜApYcMjy.LeR Yj:5T6$Izq[!5L݊b‘*:C 4 MyDny//Иg*EZ&bqXQFm8;XggSS&^h ۔ky<\"Jʛa؏%NQƠAtJWHXcYCoqH>:\˝EV!s[":LEc1&OۂRɢ K@CaW=_ԄJy`v. y*nn>f n \9+x<s꺸bD)-Zi_M)(?=xٷ4&;RޅAVI#8(%l'J~PyW$G5o-:&gRC6^j|ȫKx7;lP1H0,??xz )oeȆ{ܿ8:x3U.On}H Bco~cOgo9*`?'\ݮڹMnçNipV_`o 3g6X:6\<"ZĂu)g>a'`Tf9ߓuAU% PG4d,GVϬv<Ălm^Q-B6Soe4:_Jw|+X؟*SR z.캽|Y̺i.yP4}&/HZ^3Z8@`JaiG-/P5NC)qȺB5,fmB*jRoF;o#Eq-\eœMh η!v)ێ]Sx^Hd`,WtQ@@cErYf:WLL-Si2oAoZ o_=mYjLojTȇ-;9\UR^v(8d##$@hE^܆TrrWE0F-4ܫt~nG]F -յZ-%s-X})V0Osdz GCg?}wVܯVeZڛw*_] M|n꟱VĦr`p UƉMh~GS<ꣽT-$jzN).IttAIZ㟞߷xC?p# @qslEo{m9 ,QQWDr.%66|\=~d,2F~#qD wَwru/ >N˰>-I2Hkn΅.} aoDˡ~:1Q|XegM؄&֩jƴ9)ժ7o}JF֯޺p~(J&[H`ػܶzefxutpr(_;p]s,>&Դ"9vA;XM+%]Ycn4֠ FF-ByH:A_cX2Y&r3JC(k0,$uu6#((9ca!WT`h̄XƇVɗJ oX1L4Zk^G5B1$dx&ǑsT%;7DF@&{‰zk8䝷=/IsE﷞U=C>.s9Mz2~LJi~[VΟ8 JHG@+QڝB0ܕ\$l(% EJgUnfXl,D_]-qE/A3 vkFֿb5>, lbZV чOY-wzmu5ׂ/d*CHnL&y 4y0+#ڠ1[>9l-":ev ^ڙwM#eZ$/A$^WL&^a:^Fq-X]uS Tѝh "<Lb'gmn@y{Dn>t΄§KˢQpZ-kl١'q!/Tn-f>et:5S.`v?=&C&/Q`a93N;|ƌ>ʨxqHlLԹ̍!a0ƒv'o=/9(~R5?|NV^ %_N)OQf5eЧ-3ˀ"9ы=&96XkHFb[ֿnDz'hIK nRݬ)$U알w [Z@/C9/̓D3b ޠų3eaIWv'T xLNꄺyy7NB^>흿֚, s#5pxJoF.l /Vm [PgDF2itmfG}u֡fq4JÅLu^/n:z8:m)Ò(v3%.e#Phݪ/]AOԑI8h=Fa^ dy@{σ@+$bp͑C-x2X.kSZO2E._G*m+kF冑0p%gVF|=jl%W 8߽oE~1E++mˋq`ft=2GNd3wo\<]a0ӏjr- )(ִq43@I0OuQ'i@OvW[K0Ysh|_Mb -(a(~w"χc΋P=eUooi9> i?BJ/f86ɲs|gWٵ-@z] c YhSȴ2W2LOf0ɯk9/ԟX : z:=Ӓ_Nz6ݝ__ {I˭nw{4؇0c%93؟^)lVZ:azh܊9`޵s1ukij]gm&dm)4Զd%HҷD)A!jQW$>"`p RiUOAWNRkԃvыfK:P"1q EAg>ŏ_p/ t02_U50T%9qvQld$@B+>@DDPNJO/UTu*;5!xXrZJ? Q G_/C;{X h~FI( l3%:ۼFVVy]*QX+G:vPԳ gUZ->jBc|&zx9 3DdVYRL%vN8B K9,Rٿp&@t)2@Âw.{# YTɦP@&lAK.-C_Ab%%)LRc[׈Z0XFoaX, 'ņ@Jp `ǖ) FUzg@{ٽmmšh2I"z H=$W_f Uyb=\Z(+d.yޖ(f5ZTxX2~<2yqZlLe@n-0 4 ۿDvەUa 0{,P5]vg|`K6v ZU7No/ջ;RgwBGsx!Z(qżwbwYpMShz}JH !K^] Ԇa x#B|%dˠЩqܬ&{ڇ)0!o=SWNi9:Ju,3Etoz1& sWn=&I bAaWԢΝAf2]c_pvK>t `1xJ X7 Ajl"V ch;;Y],K5'UXUiuLkh|{_]ӥrAil* m;?ӫXؑ/Lt,ʢ>"9v;xQȫUV8jGLq9?AYW6^l !7qu&SV{-^2F^+?}5HC뉚ĈP+Lb2qD$C;(Y@,yr{;CQ3l`~w57 O+fQ6S$=M>L|T>6BdkP%M)md 窚;tJ\Q&)?͇GGSKPoewRX0- AFg-zhe٥-B uO%b״ڕ0G&&>oЬ*דPX$?da*ƳIZ FkDôw൶95*lFU5o&Z{Є\@3gn Vv@>ABK j@o}|?Z~Æi@ `D!D3-lZV5?[D4L_k'90+WԤ[7| bOg"(M,-~nec˶Q?=L>_a# /v6>( Y^ݗuqb*Wd?tw<*] ]i 6i( ufGL*3 [VkwMC?#pM0F:02j&{~7gy#ZH@uq)_(yaΞv㞘% zkđ^Vw5Ʋ9}+>2H}~ Z9cM=pN)W*CoںM\F7q,o#ۤzM-"}%l(?-޼Hhq|L1I+JI'*?u]UրQ-1SS_ ]^M߀YG3w&C}ln܊Eڇ݀u 0c%A&"=fɫxI%MG/ *@\e*)\vyw! _eNTtoOZnn砨X'pZ6v7BZcOţ(.bCf4*K}yo[Yń{?Q0hR#`᳇ w (/870[P=E!&yϧ+W h˯ Ƙi>φd-fH}I l/ ˭%XSou6s1\aRY1"g \siDI$_'C=3M"4s2+uWY͟/cf֎g!u pЅ{kk sK-PN|ޡ:J²9ٛw^CCԐ^@0B1lfHZ.efںALl=&ÂB3s@-OG­%_IUF5֎A8ˍ%o!󔼉K\P2 7^0 ";0SOAft@-n#;f 0 G"nZ )*e3Bu:P` -ðhvKԒlkk6d߁SYKgnΗ@Öeb(L?BŷLk0fGOj\y|߮6M*ۦQP_,r>mK%ivUDUrfg}# dF vuYlziw]Kd9)lZg"9T:@.V';K7| L <qRZLɛ:&q"."|^m"j d ɴ34nDyu;a;q0R*ۑ)+M:esRn{$g t(Gi$DAZ +$JñEQa0x*P^/2\4yWYnG\ͱ̜'h eIFqNs)Ow%H9Qm$)U^;*-љ:V4 Qճ X`XkLQ OxnTcrbѴ'AZ dwԓzuLrvڅbm!Ͽ஼fv- ]$&pIK.UICMWw'a"vŃc >AVEĂ T('"wҰ%,f(պRG4%Sfop陗;Ͽ֯?_W6.iTt4Ur=_h 453'@kěkXكz>yD#LG+̖tqt])-E/aZ[nɳPCv?a}%xyIf76ͅB'_fi=c@±қBl)V%(Ҍ+D{]etf30拘w;a1PPY-hUOi,@az>EŇwxU~Rpʔ+ Bgj4, Z7vOVArZɹ8M VrM׋\7?P~,)YI&U~Vg*tܒK2sU*-Ks,Q^HҥY0+zu^YU^ΥXC|VӫqʅB(ۡ j'ˑ5w K={CY8H&S,:Wx=KZ"5umB1$={+Z{L5V(wֻ^T,"+~;h[Rq]i:Wr {NNP\,\oP0TxI+XCP;w7~av=-@6]ete<b[˰d#w͈yHT:rɌy isD9榵9|j cjI>"+lZHZDޚ{:'_2 ح366ޫ줽s]aj"7×Li=EI )$"huu"P"ɤx"&%g\ !E5BJ 45PsHsI1xrf fK0ٻj>aHÏo1>D[ST' @Ih8V_sXdr|tNBm.~SA\6sڇJ6C&:4m-%n'*uK͈T;z R}EqV,-+[v8Bk['[ p PyQBȁЭң bXu!2{1]Q\DmEy9 !,Bʍͱ''-2qCұKUDk1,oU6lG֙c2\g '"^Yz&uآ q{miK\O`D}(mw S^[;*)I|r_.ЅSrx7,Qio!>s¤"JS.Jf01I+ @uhAK'ZNzvU w-N6cl}/ŪR;i:K&Vnٛ~趡%L1,lW?=fbd^/`4|uWq~\B lypOO.+c|?8z<>,|)9~-nQ't7~SVnbj*)o.NzGh̲k5pyC ``־Bm{FO9N%V\ɏrWﳩOpe(Չ4IXGG^$!zgOB٣wyEψꓬuyguj@U1}Mm.Yr6o#0Ք,:ޚ+b)\(kwߞ?U ;$Iє́2k0^#ж7^*5d> ?^Ĵs6?1Bri`OveX  RJs~yM&c{m x<]I7i^>FW=oq{ȸ7Tnˁh䍣'8]r P\*8,< ̓I͚y! ٸ;+z4{G EbYF |.''<,E'_sڌ;m:[[T%냽Y0sx::$> OE ^rr ^~MkkOyS{cSɽ7[,ǶSA!ZT$)/g[8OvEíH>yXt2vWj̷^p3C,Tdmݐk9RE%q<& }^ ɒ'"P#5 ߕKU{#C[]n)W!34Mx u\RMrM[iޫCvrD9<1!`i1e ޟ!Up@Eݱ-;ʹk[W)OxH ?G'N3nNF%wsyxXlȭ ՚xdxU$B:DCg?Vu|K܍e+#FpD! S~dYpvU6)b?`V8#x&.d!pZjNoB=_-6K ֡gADFrUiv 6hYoS2"X3vQ|QE&w;ZIOQ}qg쭤+j5˛m`mVTM&,lz!Pv7]\r\ef7Z^3 VӪX877n2f.{'?K+^Q,`:Sdf7:nD8agM(^ IFRńtO< [T9iŰ ,!󚽾ӞIVε@Qod-pVjd90hxwOp?ƍ郧,jX;j͏;B6{тo~1V,z@jMbVKro:qDAw[ST'6Y#*6@`{s ,r2T;IM`*B%EG\_6EܸiV_6Q^Xzݦk P#)tKfzpѽ˗P:4t޽kkre7[Yϼب}_Ȝ0,Ct<>寣djHBଭmZG,R1pTHS S\P &ĊbWatD۝;Xz@dH]*ַxܹARxP+ctyY̖e~.ܝ/IbB9لeYrX Af5 S+;/\qp\츂6(FJ뫎*77 /7d8{|@-hۓޚ=^G.ΩLMw.]ED "FP/e<g-%Ku=w71?ܞ5^=!Gx*O*;-fqCZVrsf͑)._ght8=\ND?𫸅;4zݴZU%%ց"Wh= Ut[Nj֤1ӣ#2Z{ZECU9ԃtUs!~I99$: quܗNh F~i*t:i7 Pv}czDslMv ʞ%vLI+i^L1=&bANr#,0M1I.LIǤY{pŃi-INt[I6'`(,M*韧C6[6mf :35G'@5PG tqJl~+]AӉ>. 2ⱘow'ʋ~P_Ȟdߤ&J QḻZfw}էa̜'R,6PP\1$4]tkPs D k^HQ}haI.m:\~e'F^E`h$&(ѿ:~0Gml)B,)4 <8dOPjUR s[+@<:x#k5ҸC- FOJ\ B޵ . 5= s͇v0=*޹g ipA>O`Ћ; ᷐Cq;@ zC"&R~g(TJ=SqWqͼ'Ǒ\F%p̐؂j2~ :|;g̏=x/1UvA_\ii j6LcMkJkNe);ggW l*4DmoyLQ|@8|1ܵNN0#q+l93{gd)U Jl1h'P˅<` x}r&m}w\,}r 9cqf2 pe+pDwcFw:-lx#,ȸAQ1R0sdjMy̤8L,Vh*%Q I'C)=NQ2$ Z%,}[2> tDQ]E=[8bVΧKuvxirz ]XB[̭P/%hM;l8{D)rHcHMfLosttva+ro$ǝ(Rqb(uХ)喖͠t~l+& 맹VLxC^1-k)p3](孄*I7q L(Qf|}So7.C~ F~mrJwQ|k@ӹcTG؂6*1r7B*O[L{VwWGf-)}9 +_(eꟚ"ޅc|xLq6}႗^WWU5`Q*·JP0`ex...nwNM~78aUEKdn013#bɞ?w1ױey* gJ<l1mˍYRiLu 1Gym^`9pګfwk{ȏ~|!5ҧ?*i=Zզҍ/N(Bo8Cg sҁ:Mr?(uqh9Az3<_/#{Kj&(I:) H)ؓFkmcaΎbWE2]Q⒟(lUW~n|!1Bj?Z.,]pJݤ+cj7ch4ۻbq >L'YҗR|R1:129h qw7WjGȑyľErDxz蚮NE@<]) s @4}(1os&ěM]0Rőv=kK3IdG^tҶ¶jcwE+GfQQTPKիg;A%[Ccѱ20{aQd♼NQ~Q{ԁ#3Ӽ Mvv:GA65 N 4凿1٣&Zi^xNF밳*KAsw?1.&f#/qSm6O@}q`c0Y|nˊ=}ʢ,|*(De; ?LɮeN/R*35$ Bj QbelBEQ(bjWd-(JHeS!'TX}0ՓM3wxf<ن20&Cr<=(V. nOOMRCwĐl`yЩK@My%i% :}O  _IJV:#Zg<;?;*IQY∐~׽dg\PɡP /B D+߸FE|*މ^8TpLH\uB@ Ouavlm5\|Ft!99(Rdmrxzߍ#ȫkgT;R:KQg^Mvx:5qp?ȃPٺskvt>ק 4TӚĶUjPΊIlQ;~%H+d͏w>Y;hٛSLsa2ܮsiҴ/s1 ";e5q'ۗ(}9"5^W=c1acf -OH#Sd8Smne#w9"\mjm1F7Ɋ} Q*;g z?olC)Ƒqv>$Zgӌlmh6xbK`ˋ֣w{qv'DX)P"E'SM6Rkz=;h]MmIewζvݧѰf ڧo1ll }pOd.kC)+?Qbd=`T[W~I+  :|D?; v>7Mݿ>zcRb|\c+X]>`#  'u'Oj%Ʀj XHA2{f6۝50#U>m.6JGGÙz "km7ǰ8cJuwXtALQuAp3m\b]w][aœ;x]|{թ5 D{cr=!XfPȄ~)g*3۰ > ym-8{("d\ӥLߔy8 ` n&8mG3 &uP޹{R#._%9"A\/˂ HEh#1좭İ_x3ohnlFlo:g2IQE;;j#,NG_Ej|eH)aܜm(ʗeeZG49kE>A5\lBNxEtQe4;;)**;j.&*Qx԰Ǹ]nvV @jrF^M-B2oNiIbҘ*M|Hhڔrhdu9Vމ(m`nH멭:g:eIBE-Ǡ7^Π5+<"PI^r_=N+*_Xf" MU‰ᄗҧ4~m@7>_8S\9?jLrTgB=;ԯ:hjȀ D9 9O:-vWeiO܏>ٶpUw$߁6Իgˮ|ը?S C滰iN;ZE)Ui'N# ķgwr6B-0 ;hG:36֟l}}ݪEI}`Vy0EuxyÓ;O-)kv;##hpa79b)UKn̑5}/OVX@_FX~ PXqnEv9.8B?>t5#a5ȹ9z†5H`ʀ ?>0ujv(v:/e$gfZg1H>3Hq, j|ORy>.H2:!A䒋Hp6ٌZB8SEMH[^E9Z*^(P,eQ 0X[>L1mk\ JdEׇkjP cqEiUI)4l宪j-E-b2R: 0?!oUw)WSRTQ6t$8B{$"SoTF^_pv35lVQN'YxHlwrJz(: Mp$ 2=և7F2U]~(Btw6zuɁĒ5]${Q12kE2-EjePR#YCS %MYHhYlM+^z?5`m.YgygiOV8(Xzl4yր=ᡖ "Sœ`[aݤ3MxkJrGgu=[\d,%) R"jbhL5Jt6g"?Wv=Uba ,+*ߵۆ l19H7Pgy,#.~^qDP防C` a.v9=uV>yLG9svgC1>n$OKMbD "nVVJiᨛ([<5]:IJRV`XIcC6#XrѰ^JJ4!L1 FvfMagFgl<@ y=Qī>ȗ!̫\\`-r qk[B*ַk@>5`A2'(L ,K^2HxTt W>}442Ff(bpZ bdlH `yz4D_3.xjpH:OzzTt,4ҽwaCz({קg7WW<NDW%u_-;b^Yzѝ&jgxVx#yQP:L>vw׫[#J?şN(>s&xsnCo~\ϝ(X:lF9 $vQ:^˂f]nB%g`_|`"/6V?Z-WKD Q {Ӡ|*h(b8}YQJ8GE~k0;GZr̢>ί Wrsc…}rtlLR6l87 td SpRC$]XGV+-15%tfk"NkwsJ3lxY)1 dA&~9mXe6"8AO vO4h/quP>L3Wo60£ RX7ujB됌gذVGˍp1o5RruXۺ+78%砎ۜΛT3R77Ȏ?=`Pʬ銢T+y#i8z>"yE(;Ǫ"7lJ;kͿNp$&qH&6ú4I%05}ϳVծ9g漘޻.V1S&$Uߒ[wǡzV-D`I@SulBO6{ #Iݔ= [ISQoKal1X1ޫcyx_&Ev I\Al%`(Faɰr_ybwUT͘k0Q~X !Xb^/rASԈ/Zװ|LC'Wx~#5H∢pH%"<=,LM/Ki@8F&Q)"lUhPw%PR]!1KHP#rjv°{!6/z蟥1|,@2(i.mLA{W6S&7@ ʉZ7'"w6aX 祍U%E%.W&NQV-#7ף<;:()س}u&pR ~ B^Je+\p3me\[#|noW9;AK |S TdQa|\t"}LR1GzEPPUA,]}jg* Ca'-`'^pmsJL?sLL6:6bR\~4@1}"DHR=.Ruq'Tu,ju@~nKLG2IbkU0=|9ICgUz ~c {77؜'"+&q2.К~60?y$qBWI*+ T.gFt)7_q62ŜuiRKGݫdRUz7gؘ)YBcuaK\qN&sC们I|3p5s)9ZZ"%f扔,ڄm)wζӥ~;ԈD+u( U[y_~ [hK^]H9%;]#Tz{s^~jwvrt;7XDP=- K s߉O6lߍ>^؛ޑ斮|A712<` zЩ9|2DSt;&[˹3:Еe:yqVױGyMfnuP.O&=4׌,knAR/v/"BDZ( }ŷMunܺ{H#ni~xv>KFH0wgYߕ"&חW. X wuSz-u5%iPps~@\p{!u3$а:Bћ5n-!gNRD{lV 8i1I`fh;nu7Bd,% hA;MCK@A`5!3{5`Ja9c&<|DFT3;K@ <G\2#77p)omFR:H7ϧ=R{؟|8eѻd*t%ŋprՕ+)vذ詢쏜Yrב6:³/=Q_mج'K2% 0o{"E (߲k|JPYzsѵ Բ MS"O6 |oj;)Hm ]ϕ@wOvIm@JrJ NRJ,X-r[c Qűʜg)n۴S;^̿C$,*/g (ln>F5t#|^P$^jt֣d` 8o?o)0o_ Dz1_=>.P,pY3v7/5g8kBOiR[~\ngYrf.M^۬ۏVKDɁ\Ңh(Y!T%C|ѯ|B# r\F#f4GU( dU؜gdz77I z|TʠnXԔdT蕸;V۝X:bm՜;q =Fqdz@!$r pRAhx2ϑ\x8o@ͣ?#%iT:yZOSTO{ iE䈋Hu [\F77 8w$ 75BI I >ʲԛ:@eV\閫+Q]ZH1٧"adw)\wqv'p$FUqT/;REJpJp=ta7s&4:dTR cjZ˃oY)rҠ r}kk*y)8H6 _LY:`L W:=Q$͂sVDz)bowZJflˍ)-ͭk6ʽn^@C-/Y53(SDV>WSD'͝&ٱMvYnυSdtL_D]I<:ǝ.ߢBȡ4|zj>=\aNtd79F/?Vi!!/%4$0=1~6[X'cy:__̚r> 8py[;W)d"{Oo"V1DI}I"6m9d?n? f¦ G Pթl!p]ް %AX#DD}7Ʋ6/swܙ]+uYί쟦Hd-ͭ`Ⴭ_G{H9-/<.)ޘ4=~N<9+ֶ6ެh[lskc} NQecOZ@p;bnړ{&PS SM>lK>2fN⦲qZB#[\t #sGeʳV[rë{;'c<啧,F#ՅJƽ)pX@ԟ 3i0E7)b04=AU,H̚02>R T[Q$.ra(~jyR ܫYy {3+1/;u-%D"t; Έ0[Xk'G=,rrlpsioR݌`ž)WUS{ɰ.::c}ֱ%6z>-!n[K gR^$L͟'ԕ\na4͙iTjk1+ Z}Ku!EU֟(%H̨XiO T-EF۴˯Q.MĶs@4صŤ@t1REϸ<-lZ/l+T:yOyP]JAl6PJ"PLρ^#ȖOhmQIRrFdv[ཨx8m)2jclBq$mQ1#҈#?!WO:QS{FE,*Ûz@G>YZN`ffdg33ZW[>/CfMJ?o2~Jm|+,<{az?K]Dp i1ߔYbMJmxDMXfA ۷? ($2ŧSK~do;>CR'j3ZJ yhϾ WaU.5],P22A2#CMLuˉXHB(='S =(}Vɣb(t|uǴ@sp2頳`hG8] ]VA wPi"`-QvH -T1L.Ak.dȍ,(I`mK=գ&d?u75sgoas?V&h-#F;.*'ni^a4*]f!*5k۽:P+s0+1jHO^&9Vwtu oc1q'5'Wښν0FRFe#ʏጦo-Rm]S&N %׼3^lFPSydĂzߌh#AӫehmǨnhZ3Cp{S7 :+/(1W{nS6ADąB^ v#?z.tOmq|qs52š4$4F?8}U0ebUfUdJbwl=f8dޔf+q03ͥsS;bCwv=)]aNSlQkAzgD)BVCm'(|x 0r%!Kq:KKt NAOAI Ϯ"BϟnyK4no$sWU|Qv4-3"t<>wb*"l"eW}2GՂ>N+j(ebqɄq7qU嬑!L0Ji%~m8+2QсD": Dp&V(^Iۿ,{yKikjz]S;UyLq{DIOjE\/PdV^58(Rh@TLAKMz+ ТHao?q¢Cլ3D/QlNQ){N(V]\!~$Wn4).rӅ5Ve!PI\@0Nla]B*jKy+8]`=~ø TX̪ځ? kpШ7GIB&ހWtoH{Z19E4?(/v{pMMҼM`FCrSx'uݮcpƵ kc LphRHӥJ}vGP#QByFJPb?R8R[ [S>Ȓց$(U#+CLjYX;\2x7H*'w-wHbh6e$@/"m7n_kX]gk_bӐ}$9d"Q-_r_i q쌧rC劝/۾}:Chs?o5s%-\3v{ >}霃S5y) W~} |:;`s>C biIOB+hqnp : 7nfa-P_)7{71H)D]0(X%ʓ-PaY#Q8UU]gAC JFcMNiR"])ӏ0:5FC.P"bԲ@wHgB1jN\ɿuiQh0<`K냠yѳ:L+}O\*7Za9>;adؿ,Ckw 5FB* zƽkO[\ ~A˜ s "hfG_o.S$:𣗜rf{˒Jjd.j,BrmVp]}̐z=[> b$뀲垩6Cý3ٝ jFZ),-~a,&xAV<8><>Cz oh WL=Zx-(wkŃl;NP0;R89%<)U6,HqfONA r"gj m(GbT]PI3Xth,h,Qɬ|L\{gZG>ƃKolzj_(+6߳? [w1/i7jbr@nޏ^Z`"g9@7֮WNVWC\HB$KW eAoq_l/Bo/t-Ǖ[~9ܾk9fDlз}ad+ gϦ.)*˫ {O|*`0Z›-kchKSc Ӎ_ʑZ'PN YE u W(ZA9(a6+ F0$A^# i)\-XLoɡpzFo 8vcn2c:ݙa濶m N^(ϵ[ʘi[h xv4}3jc0;?l*GTͳcai>wjhvrma'r wÇ;H7~H _Brsylx"?E0'xd|W|[oޘ )P :TW~ +%|UJ>xF/c$ Z65x gpeB2;T-hpN !80Twuܯ\IH! XLulp^oy\swP| fNw 3 Xf#.Vsxq핟 .-V)}J%x2Z4rDSNK<Ǵ"2I{ Vzdxq #5bVq;m$֨vy)q" J-TSj\04Ђ"4erIل=Xe2rIBr@'YZ` ݄®B} !#2kWTr/-NBr.2F3@.p'G QN*`@fBu&Ak!Dň z9m$Ob覹tcgٵop=}vޭ+v*wV}Ffnғ$VSPdCD[+`9.%!*8Co;e %$)Ckŝ(WwE:uIM?HElȑI+2I:?u'h㢮,}݉R/v_2<) %Q#>eAiY&|{}avؚ/ c_#\`!oG aq &K֏c|d`$Rl$ rɃb E4wg_2ggWCrVPr:]Q=r\+B eO#bW Oc#ڢ_̗AdyL2t+| ЯzI]n͈Did Xe&1Pj=820U컑oCo!a/.Z4|2eي#A 9vl=4ʤbSEys-+RXEm"er~6m٢M #XٕrjBn`qX`@]zoF|#hIa8U\9|v.C=ܲpɹKP%&_VAZE6O ˎTD=QUl2{jv!ı#gRpP)d"I66qUy]dImLZϡp`POD'za蓇5DҥO#.ʙ C~~<F$_C)\ يjގCGق辩l.eXV>%5֭Eop&nśJ+neGO1bzIQ;7B*\YBՋl-tj3Xuy̴O-Z!@+p^?z}Zſ sby=殳:uN+Sіa$?IBOC?U˟gbtϱ׫dx U؛&|rp%bt"r7 4SZk./V'7̍:h%"DDzgP2l._ȇK))6.bV,icܵ6͌|wټ|5^$vV;rAy/u e(- 6դ.'ubpjtjjub$Jk}]T: ~֕TΧiUsD"͔GJa;O(:{a3%@ K,yDسG~?`=i{ |=?u hYs(d3-"f#7\@w$;!1/Q[5ΨO<\bY=F=f3?d]ڧ_ׯwͯ߷tՁsGtU+U|U-RL hbWTZV\J6)eCyɇ TÛ>G7XeS m:UK!_;>j-dme˭JKˀЩ|ƖuXm4X,pRƫg-roiZa)w(p{H.[1U;4X,7?&+^Yȕ# >I@dmڥ6DʳXфe܂J  t1r'r3w<X6Np9En}ď_^pC *u3`#0}ڑ$ZpnСU+ n@[! r{R [&G̲tybMP{\hpE{@8)S*,w>\ /;1m-=8 "#puQsum )>]j%"k.'2r>Xfë.S'zƦMyz?g)02C)Wd_jP&TaBtIJ Ei3?g] ( jUHp#VʐJ+n渦ëe,`:vZV] K׭C@^x딵j24]~,Z\}9wAr}'Pw$N7+%w1FƬpdOƳj2I:ȧZ@u6&e"HAGsY1@ozާl*Q+P!e!O)2Y"ʁ(A,ǵøJ Uf`kѼX Zu I Mk H R!}|uSe'M6U͆%j簓#_X{a"e[O|'VxBncR\N[Z"bwnFv%z(B]S2K dZ)OQ`2@'.QET|h]TZ2h NIAi™`4Lܲy5:atų"#>]VfZ\J5mAMtA(t}OB\u_yex$q) rT7HmBj`cnՉph+5*oU6.9! K7koX|SlVa #bEޥQkFx !åY@hFR\Y9B4Z>A?UYtJs泘^!S@O;yqu_4z1u;8 =ɳ iDrn*۾hc%C<"tP5)w?e(4ieA9Nh%+jȽzq2'=Ε˶}1s01Pglh53b*5@I499N4#$O({6%` 4|3s6@Y:U{fڟH?=%uN5C’/'z.S761Dh i!HNPQ[xvg4RRL= I<^g|w/WNW&M;g'ʅ:n䡬^/#a|,LUn0b1i lpgN_jBAȥ~",0K~CKpUV7 0RpgAK9|-j&awpf_/z囕K?z+tΡC!mćJIMܙ %5|/zݶyEx +*)ʿI=ؒ:L9TG;ՏXTj5{CsC >0"lS*dPL[)hXse܎#i( &|6𷦣q$kp}cƐ\bFխՇzZAn{I %JH5w!髳S#}S/s -JAޣ_Ђ\2{QhsGQK_ ~2'Tdiׂu\ d *vE1$u/*R֒ & fшt% W׊Ǎȋ/*M+®F8~;7=m=܌dKM(^ѩ6]踵4Kظ߳UȎy!%$sy{ώR^xAyNΓ0_97|{)s7hNFƉnߺuuӝ]6aĆ"2m^쯫"Zϸ]>n1!rAQbqH6;omβ}QžmS`kXʔf4r~"YBMmt@g"=7~84o %a=5)Th4C͓  H jB ciGTb^s/9> 3t ֍9*/QCE&DT*8A")[j9.N[j^gȽe16RՈɹX3^-rnbt vͼȡ┱I3w4ӝ*=x90uȆfIa`6FlyDZUnD^l4C9Z6.8QkgX!uQJѿ6zԣ=".OXu'&|PkpGf2p_%K_B!teA)BwJ.`s@^X#QI4J퍛߽G'*Kvl VCVQzKd-I\ boW9"RY @ɯK=[Q#U,@KW'JKwKKac2qDb3I΄{ !ΰ:P($7rS]J@2KΣ딩.ʄT!;D^ϓw"EׂZhJ砀~y bZ%ޅ@'۴ 7K\}(䮬ށH%FҸ264m4]9hM= i(:1~kahs\kt"aZ?lC6%6]w`.t4X`IЗ7Ɠ^E,5Jy\N4Odjg Hg'ycj0IsΨ@HIםc#%9ɬ 7; EAwJD͋o@ߢD/ySO~1VfN̬6U,t9c0Г9eJuhbK5hHxT(!>s$S0#5 =)h8:Cic 6yC멗WERuyX-,Ұ"m{+:S*`+ȒLj@v'AV,d}XJ9U:{R -/P%rT&r o~푊I-+TR_e$:\~ Ha#_sanX\\WOz_b1ả3PBcS2dhh56NbO9hEW`(mgy!l-יW&a!w\ct#ѥLɒy?PvnF} xۨ` |t@ /8ZFeAUNd | >KK{( 0biL(=Bg_^; c[C;3erWGZK=j1.`GS9fCHHthcڿ5< e9Qy^Bz2@&,/lb`eQFhlK陿]lJvt-A )In$ԖR cp@ 9P8!<(JUk!7\ r@y(؜1i&v\FP&: ˓ɉd(g8ݲ991NGT{cB9OGpFK-'44~bh`4+e*[4=Pġ, (!-zG6i% T(O'֎kKTޟp|yGs$<[SB}TJKOփkzQ+zHF5\98Te EF?, WG&~|y_Im3Ɩ/5sK^)J2QZ8?)\4f2{P&f$RCBY ytlHg}AI!}h*X';w6^j97WR@/sN~3}T; *폎R&Be[ Cf8a=Y3(q]G˺#ڧ?8`tDD1sf6 $ח{6'ip@枺sJ S9QHfm&$#c_/)O2@C~\EՄ+jU]¦.DrlGVj50_D ySs5461i>==ƅD<|6E@Y\<%E GJqYL.p)f##9tꛀoO}[jᙶ$\⃺]4Xc 5 F<kQ9^]i*겕dwqbpB, `ػ.r̹2N{{wI?SY>Vp5:Ol$P5`ZK7 jg'u(j(xJ&I>pCr#SQoFOVܦۑnٞ9D`F)iĩ,inĤ F .ŜV@?2T+qEx3W96}Riܚ6>g K-!"d=J]C26~~Tt%JpUړzpgrIO׶ T-OdaX0䙖bdi(tE"5_v&JhƧH UjFt ^$ ~֙TB:ͱ S^>G գST@%4sM_ntMG kriC֠GSݟ:NJ^6_:goջnCE4Z%Z~q-@$;me{J hY¤ 퀘!mY J<Tt]Dyo5Eah(\-Y ԩnC>2V3$zvehG!{Plb`8nAv*IN-D˳+<4(ZZc:]ƜWZ7yIUTdmRCe@vݭ".[|g\b?eF!%B.yyf>GBL3hdb% _;9[_Q}MB91HGđ7X q]Du B ǒ0dSWױwe%HP,>P YI[; ע$l1EMoE{>6g`9H!!J}( oϏD#9_Q|MY\E$UaR<U$kzclyZ[L*鉉O'\4zhc v}`@nesTΑyM:l ܕTg|K j\r&Ca ofxJgK往0Y~{pV+7~?M37J [5GOwk GWQ( 0$7 C64 ў8$4^TrD^4,E)&@&P8ӎ vBK R2 %yZ߁#'ɋŀ6a}^f>| MK`VfW^MhP٢ G>x>@t!o_ԹOmQYTX}v3Ց4dn[@w‘Mx ޸KaQwMFo^ &ۭ БgowN 97q3׿o?tYoy=Z$-s߄wB/<& :|^]WmӼ&SeWu7ܚ<]R#\yHdgYÎc( ž. }RR;^d9=.8BρVUĸ>%Yꖣ!9v/ã x_4Ժo;]|X o3oZFMQPqwAl51).JWPSoZG^ޡOG4ײH刈nƋpll~=F`9qgܞlFϦxp]+szt 4D.Pb{4)㽃e5%D\Á(iitr$i68j]Fqi2Á.6*5;|ѻ(oPޫ}P^z픬*YɊP %c!8eIYe( V`/F n 4g(M}Fg~}uRpkuKI?fp+rN~LX͢cmԁAg٫3ޙV`NjPg١2qvJ").Eb  IZC'']G%[KPBO?G-GKU "ގ qiEz0MF=^^巴86,E^w/O<~h=9p')v(M tTwG?9GB R'ECﮘ;ʎ#1gV<sĻ>,xcյ3|IL " !_IR[s(/h:VU?VG7Fת3HFtCEaӬAQ#c@y'S*]8pν;yKˣ3ub^)LSyb|.䥘 }v VFkCjDsS?Gw.FRYF)b=xVgՊ.bv:2y%om?P8L'}'%NCI(pjf^^z;.X?|ya#)_^cϲ/]wC~?~y5{fB\N'{ߛ7WW4 %$ YeE]P1w9@ Gӌ NN,Z 1|w]@'h.$TM7PeJ>ZmU]/=)^]gGƽ)2[~~KPA9 ffT']! tEB@6N>vTQ ]V6LaSJ5hmJN+XsUJBuOC "d(UOPA[5kYo lo6z:zU)Af}~;~7+$tfy`h?qGp,/+N5M=y;ws_2Kz ӽK#Rw(HNI KJee\!^k T.D5EM0&X27Onɳ]X}?Rt?8TDyh}c_ჭkl=e餸:|`ՍgOluvp98z 4K'΍ R)U&#Ln {q7ptpo U-_޾9$Y57J9k?~A<V6!~Sprt}hux͛7n~vU>tITt.[tADȍKP"U켼~qu~Xb; ~ :I'SQum)7WҊujQXTg:wc7֖(fpyh?^H[I1 ;CYg/kkٻEY!LWKg8:D0xLyJ̼)|zGC tA,i*?p-R.y1z\_kd0I•nCxȔEP|o/gYVuu?ۑu"™ܻOߏNyY!jxF02d4>O,u U\VN}uBaJSq~,]K̀ P$ 8N*`ћgCa =` xmT_LEQ*q0T 4K  >TZJVc{M۝P<6e ӳhpZƮWͅcdm}{&L4+q寣X-`3O2kCmT'8ҏ 7ߟ;xǛ=\X֪ ^xtvgI3ijdrVpe ߨjQo85NҁLJσI>bW@[ irёS=_“CgM,̵)OJ~0>Pk!$mѐ %ܺt~cuc2jS.-WPa >]F1/ѐQ_A :ybw.jR?b]Յ6}ܡiW?b/tѱ{J:jkRt_},::U@n\[8о'DODׁ]mV5%Թ/|+L[^sZjO<&v>*2jms=M >{mLRU˽UiV4exT"LS$AnYՃjv 1:*nN8r5_yZ?m/!^|]&LhƋ;.eoL1 |BYR$ ϱW\nJ7")[]I9?x4o 4&7{obX<@ܘ/Y*rrɍ?`Tl|Wqr=G1L? (<9&k{2Ӄ8K1mzY+ctWO&ڬeɕ۟of\X<&cnj^g<H4dޟ1nCFFLn22zl_$ vhф /b>H }ȃgv(6ݝ~Z[Vq=ATyN%AH2$|ʉ'D W|,q #A8ÐĎ$gN%,"{mHx C$$Ҙd-#e*U+PO*{/vkOj}XYR#7_D ;뱸RO&'EC |@bRCpR,uDOc1u4"ZB8UbyFP 􁅾GSfBBH+s qU 8iѐJ͆O4#;nQ͝רsVΡAw &h~8?ԎNNM}(Z;Vẘ[%ygh|gxU .`zzl|Z9+ٖsG!A(%T /2[euݱcbK6BnM{sgXy}wVt94^Dp&ӢjځT̄pZ*N6jb 1$e :T\׷B,H4LLS|UW HWQmԨǢ2gPmncCC6/2L gPK9Kvd I68hp7ߦMNrFg&GDgzߓcӏ AEe^Cፙ !C "o݌V&ZL[%"@BuI M6F4jw賂0`0WOGVJ>_g1 &X8sb[գ*ƀ\|/q !jnG[/{^fL@ 'ծ;Vm6nvZ/prΆ6omYWj+e(`:Ʒ[Eęz04NMD$s hlD!Ĝ~$'*m)32ѪJc_;nmX X}wyOia/ШhHKΡy8y5oH8/m,=&7{?O+iw47!4 Q8ʡ($s$Ub8fu= AT`olgx5bB8s29 &hMӇ@N Pk{5E{o:HZ;-8066 ,pW"liQ̽T=rN0pw'|eV3uK}w{lh} yzwzFvz\E`g{,79fиTYL#b ̯COR͎n{f}{BӛNdCql\fkyG<NcOsӝf9&^~PKHTInd@+e$3^J &l˕nǍEM]l[=2kh'%*@sGҜy^+uȺAfC͓guegGT_tXɣ8@`xUS]hUl]bB= nϺmiMiCShL0Rirwՙ{׹wݦl!`^ԇZ+Z!//*>XafΜss}m{iҿc'yTz{;Y ).BffY-I sx, BLBlatKFgu|50;)^XY"@nBd:b0qPLhв)VgXC9%uMdiۻcd*)ֈ OYU:~6D#4Lnہɗܖ?"3FcS[j)>!lI|N5[E\Q:ǻ[ߐ7{ݪ}w2`d['fcpvxŽ,f*!eJhM#9'+yk i@z>؉Ҥ (>B<<FLEwu課e {:0 4Fl¼ U%Th:| I,Tg(noWEUZ B&XL+v1pb7xnm>&Qq} r?/URTZS:Jɂ t3RK2RJJSCBB|RK27,7fdO)3HQ< DNT'67 mK^?^C j+Ra-dtDJK{;8z yC)F*ZrdPQ,Ot j.ڦkxS5$F*,iR$|;2U"\0$|5.{^w6FG:ukx(yePB0u$ ux3q2o 1%Eyy/3FI:2KRsJRJbK* Rf7PƠ(TV3tBb1 UO3*#KGAOOOaz)FMF]9>7Gcs5  y i 0 % Pm/=yƷW1I^~Ty!C҉HKxUS[hAefشMԾ( BU~6JlKҊ+q6;ik6f7b(V?b|EX?D "VVZDQRP?CmϞsϝsgͺz]JtgcڈsdKz\Bml; ] `><8C;[78}1;Di5gdwg`[z&sʒhFr:X 0޳HYk˨\{;u Xi''VυPJ=繝LIXx6bCs eʈIUlhik ոI3U.b~53|}k)_s]m4}nݰEgAVs P@rQh>ܲbB4FF =dc,BJ!H nmU/ӊT4B+-?\ֹfp5q9\)~ǕYgl'%)pQdu{H51[jv1cɎN2QsĴJCQFb(:{UbDɑ1m@ ]4m"TRX;mfib#2,ǣ &0EL!IENHB>@DR*~L DR ͦhGbs󆶠9aJr&^c\'1]~Rtt c|,Hڷ"n7f:u͍Y4sZ#Wr/*qDY(xZ xTյ$ vH"(y@rfLr̜3 q< -VwD;`EEQU?]{I~Oa~^;Gzٽwfnb0%jG?գ)h|1CJ+9^9b}߯i,Ea-kQ #+5RTِ>Y2UG*KWV#`VTB..W3~GrĔuMO?D|9LJ*g~"#9 "C\kj0%$82!w⹦3w+eD`fW%v)[O/K7ږSe^V=⠟cǹsrr|b ayJDE*EzmsGgFuϢmҳITzt)li kEVRP%S1HTo1/,jKW/Or{bz9d^UXQ\]{/vyI'}颚k(QJ%cwL-"2 jaIx]?A QTLhjP։OBe= 1$W{H^ GU٫=5T:Z F_{R4=2ע&'P͍"!"& Z?pSZO—G!84/˪vK&X# $%)>$5&& Da (IRIq)(X!D{IH{FeÐ qQM77n7~dL,N:\y`|U?Mӌ+ٜiyäǢfcC%gM&^J/4>f==>7Mo +Ù4g>E @8ۭ'mh`iؿEB2Gk貒RzOf_d3J_9&ae1Θjiu&EZJ{lnf\2b>tI٣qËAع!n&XFd#~U1zC%$!E7Lbv X0;5%J0-)ץ Ry;{`ͱ%1U>O_£cH Ȝ5AJ/Y&ݒQ_-g7yHYkYW_t_C2{=dDRjNlqW6Y[o5d@~$ E"Ɛڂm%\zs&r$C TSZPd!~M9Ĉ%4@܏ϱ1SZS FH 6mL9gn[U gQ 鳘=,˰*7\j /mVkc%Jĉ;~*qч*h=4e%dE{d4Veڽ{ uQj4KsnStRٹh6ҹmʕ;Er  :rD堗~/}E7t3_qGh2w5".qw-iΠk Tyhg% a?}We¾G[nMݏv],5Kְuk/1l~%C^IǍ8(q Ši,[֬By-aՂ"$MDXL_=h̿fB'OVlevS>'ړDV>r:{s .cf9{CTv)+ܒc%!I5[hu{K0X48D=>x<,e8We",'Ⴏq": xP"ɱ!Y^A?FVf*kdT H13, BMf8mDdJ PqsBz^mWkǕ_iͭ:+NijxٛVv?ެ5zz+?GbQo=R:acꪜԤЍony}esCQc'Koߩ03aLTL9G}dzw"ޤD{+G>>^y1LQƌpSUIgJ~':Ռ3/6hGMgʈiW<'(P@VsstD,ۺ l€qDIm9 #d{_zG}x9,a0b~&}Ҳ> CTjNx asb0o>X "4p=[O4GSg^uwb䙍(}şa5awf'"~L4D ^) *W:8wg&eWBmgC_(h{e j?[0^& Qe)bt`WՊik8m|v {(5(E eנRuq^_8kK %e9f{1s Vzr8 P LVٙplcIVP]`9.K"Fń$<[U'cJ52Z7a{1\IL )uPke,&1F:TorPfw#2r_R7)V㳀=qk&kPv ~aCQ,KAt$:SΝ5Ol'+d!/K"yk!¶M-!ikz=0 V|ł_+I~LAɭx}".Љ|j 2دZu=mrڀ3f7Xc?GK'[^fvL-ڼjZKv| 2=zqvh!΃Q|]N`݇X *g_݇\mox~gF g/βO=LV[tǺdYz@bs[FQY0% Hд~݁Yܞz \^<v]؁pu_Q;+ٺ!4|翎O#, >ֳ>E২SElgh; Q}sD0>cN+2M']9U<2uUۑ묀apOTͭ>Օ> gf B6ndGa]sp9.41?q~iICRI=:פi{Hj>߽dirr?&^v~Si Od[{ 2 Wڬ.r %=X%"n^c"Z#n}j>E3 (͔}^D:]dC_Wdz9) _HYWD'pɔCU HЧhG,%5t0|pH1!C2`u){R\0IÈ41Ҝ*|:Ţp1J}/u9/1GBY[$ka C4 =" o0$|{eXDإ rdV})^bwQ.Pbr5MF  HzŤr\ w xZ86:j\_*qBbsHUPEoY 2Є珙RE3 x~QJ` u/YP 7i\o&|9]`)y%݄kgLWG80beq ۺ W^.gۄxSIo3 d4݄+6Cddoe ^46E*i>6=-ub%I7]ULgoƭ3j<$1t@nO{?ŝF/7.Ͱ݁+p.(9 +>?Zɺr96>[~@nv]x<߅'"]߇{')*" ~aMzc"TCG?D:{S؍QKr^4yfc=;gqu(LtZ\`DTI.`۟ŋsQQǾxf/ߋ:8OPH_ (TH<($ީ7wៈۄYx Tj^;trBo#p;A|87g<}d&[(r'}y9=^JkֳP4/ATsUMC߁O"ciǮ"&ͱh(E9'H`zHgdi:W$#B#\[9p q펁ij0i~2d?iR5{S<ѽFV9$H֧S| : [G6t%8aF3٣";!^K;Y^:\# x+:M\78))@H^j* ^uY A". HjOb4S 6;B{wŹݘ.T̔ZLB( Rsu/|zeԻrkc 2x{u nE?OwLN/+QH.JM,S,V˩T(.-(/*IMQHT+I-KQHKQOIJVM-O)Qls3>"Ԋ܂TɟN}'&mdۼ9}2 eڊIm#S$cGO yiEgf$)$s)ݤtCnuZfQqIv@ڙv0ym`jRQ[O%xU}PTsEveZ0D H(6D !۷ae["Um16_'NJΛLVjtGK|6Lk2I'v13{ݏ߹;SgӁ`l22sN*VA0 V `?W )RZS KbYX[Fc|Gl!ee`G? Ӱ~| W-Ԩ=P[j_ԟeYrﮄ]^A.M%hC/:>yt>cSǘ/ L kEf_-cB0<2Ma>%X ) *& !IeNF?:4#H'1Rd$ JhJ:ܭ+D%xkGnX]I˭/{!Q孉[gm"sO &eD32^8ݦo_hRp:ҕoe!W]'27AGra>q }v޵4PlyD7)z6Z4g۠ oމvh%x$vNg>Λ㰌vBm7:aC/5wKig}g̯ <'`9:'5zaa4 QUSB{SipDcSm)<ON¬p0TrE1%3!dWNAyf *Hyð}/Uspqƍp{/ 4j4tXn&Ӑ*o(@xOC7:/ jL,LZ/c`cDBB9`y{߃*B%ʭgyK\n$$Od'`da/#+qb:\\'kU9m5٨eQՒGMQFM$TԒ0"Y&FB*qIIBCvHbT]a cһ,uhM TihJ zD*aWX% CP|caJDXڠJEceAHVV"2+H42ga |BҍjOrDIL5$qMK0 kOx75ďb]T^]CKC=\um>=}-mcG걓F/#r޼ WSj@j@K6.7 ARhDKokmtn4bӃ5cek`-] jty{KrI=Ju3P'X؏!׏4~OK JUU'p/?!H e>T%Y %7##4qpy̹ׅzm}xΧ`/ay/Țf;Tҏ9M(/qx{ xTյv O!HBy?H&B pI̜aBGZRXZ,P_(zzo[[+([OZ̛$Y{Z{~}-'oTK xlW@6fdO@~ |A 66 alc8!қ͢;hяd_3Y-64jC.) 俘UY%:&<&\gۤ-.`bɊGьǩ\=6E_\JlFd\ T#UmA ..)Xa@/$ԠŖ@pw)"8pTRn775Yq,:WvŨD}bӦI[D/} }GSSקlUi\+Dlje&GS!f–飯i[`zJE4<[Ir`MNatPܝڧows(cUǻW|Z-ő5VRvڱ":&.}B[)nadIGlFݎL~3+$ԉkYEFuPR gܡ_tDRst$S;’QZY;92& .C+\6s,Gjdӄ1|seMnԗ(=aPl"l_{|&G0EZ)oo{e_m΅.g~RO:Krn4oG 7k,z))hXu0I3l˪w@jՊ/S].9B+|Ý!OR5@19t@wr'wL(]*d/\ DhxoQ"%O>DEMvhu[ڨdO0Ywv %1U4|o3SY^HtdQJ/Щ!e͉Ca6zvN cC#k׮EtU+ f#V#2@Xv&2 Y^IpȌ?mfG\1A5S%s?J)Ѿ4Ar$J|}'M(An| kM~*qMţ0nvUze?&}_Obo صD7,%qf<}ځ)Y1s[1ب>PwRLc(bsc g>p@Qz .dtlZL{@ֿDgS9fT4MT cVݡRvESBWGĤ#Px#Ԙ\4WiFG4mG<< 7l?c?пz0=)_=>q|J,TQ->#~0Xݱ`@ziGV{Nfeн͇l=SP ֿyi| 4'9X?y"?eSu{_/bϾbBKBE؊4|/U&jMd?4`<_YDCp%>?~_짻 StOO+ZMc׼1/2NͲp CY9*?l^ߜZ,Yۭ0kTYUu[~#w-a~_.iy|K9ZJ}Af3{A8T (_Hߥn3b ׿|{N36<-Yo<[2!Xh ROEk)iLFEmimNȤ7xbتaGdUעNT=nѫ8d{ʅ \|}3*; QGV!FM\XZtAn.ecLr SԓŽ)Vq>/k𬖹^?a-<>G/E`B(T1yۡ՘ L3A(u;[I8R v47së{]" ~uI^qE!9{y x*dWh5Nn OΥ<3od5چm&m=*'vN|+FɱDncHj냒:~@"D q2N`$&Ӫm <̪ ##JH!;-4Lf-Arx"`f`-"lEfWCllF/\-zщm(0-`M/L"oFr/Z-"mh Kr*j b Vv:$Q$u˳ N`Q#̋;"gNs5_ 51:+! %,I[^[& F.ɖb<*wU׳Ņ|QN~|Aɏ &DP;^vLNՊ-kJI؆#:n9?r˺O}bs-0Wڇۗ! )VEy m+!mɓ1*r=l/;L`a&T?_ץJ4< ʉt qIIJW\Sbc.DƚGKEk.-B]#j|C߀$yG=nT60dMɛ9lxQ=̥Pqrig,;nterf(hWśx::]BnQM[o\~~:S5=& ni̾fggȬGӰn%̞r \^-(}e%}Ro 4Zqlȏ0[*]"o2y2krz4~}ܻEӧZbspb:{U>{TWQU]QD/4l)]5l%fpv;ܝ`FNxcƶᅴ$CPVvI}Xș4E_a2y&I 8Ut(1{a*<.!)P:eTbSr#9 ,Q>: 6 :|0P|փ;# 27I[qA(4;Rs,+A)3V&9W!<҇Lg#C.5Lb0+erb0Fũ\G.=(\fRb[SiKRL`[Xs9r)hRCFC ri]2H۷Pypd75_"L{&sь' SGc˴:?SQnf?Nh2WOPs ɣ'?U 8h=El5*AqiLbeq 8'Yz)W̗/ a)ǜn|s,$aQJ5*(3>c'$=kfgE\+ 4ynGэx0X"T KIPhq%d{Pd,[ڊ˛5g0& ,gqu)#SPˆ)X-&<ɜ0: 0t3u&^"}OɆשȐI:w%G_0"`23&p-?6|fP7y}<ỵI=G7@߆=g|(]@gZƋUVmeM1<Sb3a+~&iUgeiJ痱z㈌œcrᏠ5$bYkdD N1kM|\"xNpn.x# [єavY5̮ ZeV7@Ĝ}𚶑v*.8d #۳ aƸa14$&d'fX3$>Vsd$)-xO41]7'kɛW\1gn&1,9w~~96w}90Sh$f&rq5Oc&e"Lr8%$&oΧ `G3Ȣ6kS.oEE쀸<( 0ɟJSџ`0C"͠[ǍAV3P6;ϫ w*~by2gL:3e q5Bt4%[5"Ϩ;zrP[ kօvpAݫ:; d6U/+/-Deߤ g.B^hM_JE ooR$gEX9͇iuj?] ű*T@6Vz:bTS__QU(僵-.Ƅ?ĈPL#jTd, Tv! ѱB [)a AO4yFp&@r2w {x`5Nb7"ZC+c~/؞]&4֋}.-iH?AFzɎ;Xj}~#cGY>gVgrQy]2VnG[a.rQ4FLoF3.Sh5%vE.@֩G q mAdAlgjK#H|@r#8k^T+{.|mSPNڨ^ݨ Ŝfl55X c| Y2U5/7Y&^n _vjnA)3c"݊]$БMcDŽ$QA䓹'/.;QI5]rG)+4z(k"lBo"4=j+^g;qv?E,oyf{_3$` 1qMB{lr4PpKzk0 7*n@tS%r­Ke߸FtnuӮ'}w] a~} ]ZE;IBV)H.]`P'qGtIO24֑'u}.@`q8駲ș;Q=U+zDxKQU7D_YÀzQ{xQxmUklUΝm;i @{`P*#*τPgg\l-kCc0'DH4/LЄ?"F%?FhH`3mFw=||g/&_1y__,*A9ER]U=WkqK}J6K£ݶbMLh fED`s|[^ޕ)u劺bT4,*b}S UH^n`Q--˽(Y}Qml?n2eVmucտkC4lrԠ@HSlKbl9'8UmӤF5nk2@HRzj{׹{UetבoZmFzrPDu|Q̢P`E@+R GUDNCF=i4,  WAq)7GMʠ$1Wbxةpʰpat.A j`g22=szn{/_[\!x4 dFGO(Ʃo)؏M#@J?ɛai힍cyH8XUPP 1shb\lE8Z`鯨{֩*Dĕdgɣڳ"0  Z •,De V HK]L7 $u`h3:BZ ]/I+]x{kxŕW-ɲۖe!?ed'?dY۲%[yxl3ӒZw H@67 |!6dCaLݐ H$K$Bqv=U33#c:NwӞ+!J,[10q$3hcz߰Uz%T6 .:3KqY%έAM' !Xu[| ĖL!!>+l*o(dGr&ڣj~g"ykJ{ (6]~"f^iÆUyRb`_]?]𶀡u l:9_Hoy踼.o] 5F/lB tm|w={jZRnj%#ɟ M=ԆV4BhY0L %'ᆪE~|hK>y2bVs ws V07.E{ƝM^ұf.nvr㢖lhLL; lż ^pq4G冓e5E]O A_GesCM#(P|- 'ߘ : I6qP,?ċm׭K"&ג68.VMLL;c?LCdTt aFȵ{{h$8qtH9.`XÌ05и,w Ƣh4.gQayp^Q̡IaNO=VY05 H8.&SGy(6gƱM T/HHMOϗϗzz!آnU!؂$Qi hO1Cx[ڽ`BS&x:KZD-u!2Φl41g+g š#j@b3]AiYN]4ENcM.GXgӲs-'p{_9d'iK-}UY 2 p?I?`7Ւphu{,łif?c(M>HW| H%=K7[+.,f=W!U!X*-aGͥKǭ-mu!Ö5dDT[ȡ><4 kLBYtqMoϞ}G-R"]Vm---l G(TO½0z%NØk|M;7l@7S FQ aE6u_ww]][v[pm%}K\ovθT"@/alQedO-Y 8Gz)dն{i*.O!54sw̨n\0 n!AU̜ⱫY%Z$:ぢvT 0_`i2< WE yK,i 97;TI"}fgƐxX!Jచ9$ l8TS)tp!$pV0ʕ0x{ϣfxײB&.^9п,bT|zCg! ol 7Wߓ_[ȲyІ iVNk '3[i*&;ߦTtUvd2O L?Ӂ{P/ +HRrDÉXlW¿%?ԫrIR##Mo\11>8D.+`xغwё7ud'7C^r"!Emܸ%|Ŕ]G K ǭb89BZw~|ԭͅ c&JQDBSk )ºlzhO=Oߍ_M+2uzͥܓZ q9 8"\#`˦*Lp4)>]( `YX T#!`]WqbA'LzzL֖8yDI>$:]؅E>9>TX@~\c'mM7o\JR\7^7'w\}.Z5>-${:|Ya+h/Aoc2u['P, I~TYd"Kv|*Yt"3,{{wf&WUGuB^@3 ^xl!^XH~}?Ħ׽]7_8]4a ϯzl仅̙I<֔E+zqd~Z=ėh1n\0I}=) SнhY**$tov +s6bfgDž fT-gq**J&JKzR)6EцYht@ Gg+p`?Xi9Bch*_m t>]['PE+\ktlS6o)'r!Zs0"UNqmg:c_.>bW RtM 2[R)MYn`eh3Z, ΔmŽkh`,F+&Tͣ^xU'+ߛJZm WyU[*鏫 *jnFU_ W=\<4!I/$i>%V\ Uкi! נ+50.Qҟ_/+zJl:\f_}f3"w"\R"բXwhCAcf D戦I]*Yb'yh h |WZCBnj(f/֡I2ڸ JUHDtj mAzr5Z"ےOFW N0׈P,Fxrz ѻђuK[P먲ɩe%=ԈV/Ž&?4kp&E Ge/ƛ 5Q LoA' |mwŏ uϑ6 ~hCgJV v:s0,5tdzj^q}F d@#pb?&zMd`ܵε'=&;Sc.|yC H/h(vc6v+ 6U y&J+;P %h&Y) l-~gj:j4cDA~=ݬRxR?-^X \+B$|vg*.=*d0)K lWͬ( q#gS$flB;"ƽ1j.}s] ɮ}܋d]'c M✛VEhAn4 gD?"Bmh;mAs=\L^Aϱ^T ^tЛ6"\N3mM}=4(;[sڄ5mgFfhMYB4h@dR4^BKot-Lgs PGE:eHXδ\Œ:,Kx#WYAڋנ҆kB*}*a'pA5Wccn1Ez%n4Q8v@>%A1c]TNcQ*ɍ5NhxH[LX),ąLoKT"(J`K>ЏJZu8E,OHHamw$KǏiG6 : y4DV]x/xÑ}۸~\p "<{ ?hZZCGI0gC31Ѻ4_IS?KXF8-UO%aK0Xųa\ .Q+{ANjj ~f }4WВn4i9O<{+Rg$;џ hJ' 0{//W~g206M>Q0?zj0 +/还_H)~/ [[H4"w^NoJZD q~¬nm3OfDh[ߖD@e{Ae}QtQ/51TWmfFw 1dɓ:2 8iyσx =Z6{FwKgwQ,ςOQuU\򽟢9sɹ?C*H;S23 #bJG{E0E'_D$0-zT[ ;=MB3mq˨2s5_FKm#%t#Z_A`Iϼ d%zvJk6_ A9VN~ }(ϡ"IkmXL K".Z4;ք{UU:(/߰R> .ϼaLxy3`iLEM<0B`IϟPlVJ.ju1B釋bzv1N^x]V\t]hhckYn~R cu)o:%S\^$͐vu쪢I 1@N꜕x;xN㝏azcvTiDޝ Ҕ NV!ʣ{f x`],؆[,-nd*储z+7$]̨(؊L/+"GaiQ v4%WM{ -ϊMDpoձ0ЃP;Yz~!CF:y.~ `:9!C V@Ro;7?(1?6\3F:;i㦷ڱcD3,2LUG;%Z[ 7{"j6Gf!cXlYp^`yJNTNJ#n4idɊ#*!w}.EP@fCrՎ9nICXSzIbW߳peaֆ⼪-% 뺓{sԼyߖJ}3Be9挾4yPyJ@Z(N \RFwlʸ{ߋyM~(XE 8X [FX1N?SB[VGf/q N80Oe3$2`L1cr >V؞5)i쩯ڹ,k  vUFgdVūo~ =|$͝]>)ZCDi8GI!?Wo¯G#|>XÜ 񽁒)=v$h-/՛ cidkpvIf M0N/}^#s0YAaj8%=|br0߱k )h¼f8/if.>+LxCԠr*~ ͛`RCzԱƆUC Bb;גR&nqJ=/gy5kjxMsX?*g'_/<Jg&J^*!Ԟg`3V cyW~<axZ{tU?_ !o $@ $@<0 "c#]]NhtuY]ux|gPўuFg}2#՝zfY߽U鄸98t=}U|NJO6o^_ #=;lEKEꚚLc+qHq2)N~oU? UbqC ߯hZGA=q ha=}ڽ4i!ە%!jɊjfV@Ig~|ѝE_Ǩ;fZ]cV7,az 4F5du צ%o&_GR.M9خ*%zHE4-TE 5\Jj˅rbnݵ.Ȣ`U+M҅ N[G/=%7"L.&ʗ2 )2T73,~iTT5厥7ͷXuɜZmLتwHb;eZ_϶~P6tpZCrBHEr"#afEEOr(&J`RTkf{,CL7)ϙo_tyW0HM 'Y/&Ձ7Dd eҥ Oxdi PÎ)^5eё8TSd>St#&XEoOﮇe ;+ =8N٘go@iT/cm#g̿O;$٣=KC"o#ò#_sPt+jv4oM(zCiLqk7e;giE&%eP9Fx-,wjA#8Tb/F&ۈ%Lz]I!q>>aJ!;-w? KE sQ1QFzk'1uhhDX ~J\_&2P\1c҃2lc6=φGWG׹-nw*fH1DNCc,^4A$u7N,\W9&τ&0nBs('1 BhhE6ƂmD 6#{I'(A^!>blRMS$c&c-}B;Iw䢃*g.Tq@Q0:eCQWLGF%ګbqxbƫɖ3D eAq N)%SLq:Z%mJchV߃'}H ǑŬ*]-!M2olRG,n``L.AD1݊{wS6U>.']3!NL w_L *ϟA"g3yPD\7>2U??S?ƞP"u 3wC SLx9%ne7چ;c\XR+sZ;3z1[_Twchr2^X K7QT>.7nXhIaCuJ~)0TvYӲ_lc2i)kυcƝf)ACw1 ]'o % TF2WnZ)bLz_- SVۈl ݱ$F ='Ju2M = J ΍ruyj$%mNV 3'z2E2 bTR3E3e;;:Ϝ:Ө1dD1y@BUEG5JgF&z ډ"YX]P d&'uM Ғ{Sbb#-0q[AkpM#݄!{$3lйEc&6eo!]KҬ2՞aM6 3$n8jfC k+.(L>QǨ.z_lta 8-e{gOu @`7v&ͅp>|m',hWGak; n#N{K8@DEΚ7#s}MqZַ>-ӘqiZih*&OCsf8SΜW<xrTcau-&76 _H3kf~ԭ&0 l,ߎcn9Oo<0g0A ?03dMؕugA2s9X=aq?`yV/m rAoF 0=a(;gW!'yt#,q0Hh v28߲x>ɋ"bt/ D38{``+#AIK`^R/c\'^^%aL>4|(XBlxj}ܦbиr.7D͈ 59GG5ǟ71q쿼v_sؐ<b= &k ] /o4T؂E^#G` EmduKM!B* 2u9/fQ >ȹ\_MYxž6.ݭd$}#-aš=j|.2қ7u9깺[ژc+ b ? 3%Qa7QV-vհUo/u!=WVj_ 1ޮξV;{n=21$ޭg߽yry7R\,U8orl@yIB TO. SϏVh0÷<|V`*KKa!T"A"xGvJb+e4z]ۺG-`6?ohJp|j+[Q=NA>,= 2L@Z6ػ+asQdOTB*V**xؾylGx&KAGKa]T KZjşU'2ggO^ EMST3I8tl_ b5Eс~d?K|4#܊OT1qj^jwFUq% ZM2{Q7bXs&*3k hiѱP.Le+a=B5Lu}R Y|0b3')sPDϊet KT}=mx? Xeu;w }+91j^ PhPMr̠"iVxr`,箆9 {VN_ئwd'r}`ܙý 夝cD܎dž_zj^k `r<eGE " _~hl0)#Lev0xU=:m b•/ (˾h>pe_g"gpÜso;g^ij*u,hcg)X18* E&vM>9ۿG;گpo!C=CRK^6U7MHfK zN-[o|zJ+xSiIjqT  Px_hEǙ$ǭijzsl>1MFmCZW\nuo;rTAy*HV ZAUDAJ$EZ?ݥog7sņO ` FCEh .OIm[mP9||,},r\ȭrcQdd\q>ü)F-GOMȀ?!`i V899/p*_EjrOV/щ;:E` ,?tٵ'>w{{},ej)RA4tX ҧ4UXU41u2StJ1ge}$ʼn)c‹>j݉OZ^'1'mw%R1^3"AGn怦)O`鴡SroERfSMd෋&O#ZyT(%:jH_ &GEG}Ȳɠ} 'c&lbvC81#m($g?x8@B$}QXk24[`wbj_s#UOlsn*Wܕևғ-`ΰԛfc!vZ78#FTҡm'̖0zc|15|^ kjFKiNk?l=I s K?6W^zX |<;2aJo啝*$ҽ!q{R+L^#*\ %A@|ӎP}~c+:y#-DףڇQX) H?ټxY]s۶}@zgƢLIvșh&IHBL,ZVU{vARr&ٳgѱWY,/Mp6Gs0.d%>j|h6h3]^/"8ra B\̥Sf"]U1aD!ʹSq;2B#D orgt)&N)qȵIipDE[('M㷼jW^9RbvO rd9 :=>牊X7=nѸ&ydRH,ݑ|iK{ٲ*4Lg22.S(j٬iv_)|X'|)|~G1Xz{}& ^%X(!8U**n+i+ H5$R!AЉT8I 㥁Edz܍õ3NV3 ZEt<-O] [Е8^haT2ՓUёL?#myXɗjg=B*'wÛU2H?S*$U?qdK('D0p%e3vn(`s.o+$ٓ'Obt2[y;뉸&+\zl3*'J^3:$USm6wnl(;'\ kFE7m2[dO7xheʼn8\V/L^ Ud҈4XHN~qsƥ|(*F$0C|u냱Q ;XwH71ީd5[wX}[1pPT R J|':4)H8iwYK:T{#_܍b!J\hӱHn?0'5+V-9=FB TOkנg]it F[[jY:s F?SDt9ԕ6ÑxjtoT?7X  8~`A"<Ů(e6FES(_{ʘ6_Q+3miLV2acу2ޘ7L T"И:cqeJ8rK;pt6VK$_Wu(bkQQ2Y6҅~˃o6#켈d\! vRTV( :3~ ' PR5L ^%Q6O#RFi!KCdRzhƁ\] XbQ!9*WVrlMLӧ]{ļ̄eoL^,RJk]nUww7򔙲SQgTnA#.h2OpA J,թTzu1:Wi"/UZwuĪq_H+PEWQpN|#oC$kxm2jmdP>g-sդ<]ɘ)7$-pA<}}mSke/p_Ϥ3fts ͼ3yNk\ɖYd@wl4c7#Wn8d[yw+Hrteɷy*Û~9o& [fu5ngj 2P(ܖ@+g虹-z *klJ߽vEZdž2ߠpp0樒 >B@ aA)buB۵؊B ·)!QFdQ YA4qMZ2n #Y[lu0HGg;il@9BDC; <;bYWW*mgަfgؗpFL؁.$k؁ʓ뗊¥}2-d RTƩj|.1wKnVKìN'3SY͉-~WtXl݉cH}'¦qg*-:;]K o!+|^ 6n): =417f՚%5kLԊ$bݯZ IFt$y]HwSx#^(Hn)YՖm $•yOXKzwT^֮vjYm:U fwd5"ߘXOAer|Pcgt6b GgooFLh]iݺ2~e.֭&ptwx)Q Ĝܩcw㢕 ~?n$ !N I6I YdgۻWDz_+wyA(^WT\iLUCvb?Yltw6TǾ8&E#jZ&^TZpOyU\Fٞ;>T*徇% U9O EgםQv촄{}0ҿ#Zڈ*mA:*_ʨiQAH+IMS٨.JG-ӸDOV8t?7KJHdQ)?mGSO00B%>E x_7aR31d{jV|{](1pޟp&C`2[$\O)FV!u8xUoES--A Ώ&U*[7n__JЦč[[$Hivwٝ13qz(Lj#o xk'M 7f폷w~t4ub_3}f_&{wE)(6%:TR ]@3 _@Ci;\i~ ηAy(d `9<*` ZR <ѡ%34"A PTQ ]ɴsÚ qy8_ ʝ薐Q d^|iPC]"KiV( =f mmFIIX,({b 4vV+~fD.o?4r77ecӭ&'?^8իy/W-+ JC2%WN(zZۦ ieCi`jLѓOB+G.;'w#Ջ u'bm`:d%aDN9-~:&$VE۬]!w+C2]hz)@{IyB6U)ߐIX:-{3~ΐY9Mή1_mzHaj!""T}nlyF {O_wu*`w̧WgT@N,N5-VY*y͏L7_{GpQIee%:Ci8*FÞ!sjxT]sr$*- T=MÖ0\}s4ajjz\-ƽZ:{+.֨Yg?Y`wEF*r=}89cWRsC_t')%Me>}7yʻܠ$?TlZ[ŎQ/h_q02,RүQro,c>wl~33S%_J;,fae?U:37kiN|P~@Zħ塚 8il?a;gX7<4sE5x[jlCLIFBqbnBWbRRjQuBJ~nbfF v#ɳ'j+QMLVVQHKQK/Gf ťE%z1yՓĕ&N^- ya@CS3"|zKRs3K2<T 'آVbG-WLfIjg^IjQZbrb : ΁`[}&JM.4ZJWbCN~z:j=$MV6U JRnz0ӃJ!C)--ndx{FoC^1zl}x{BoC P&qQ$jx{RoC P7›tEtK4xSjAe"I G2pDQPAHH$.\L9UcUuN[)\?p^8jsϗ^$r-ɗO!c^)^5,PRwFeTX"rP"!J!AH&((+.r!lJaDB&Q%myIʴCϗ aCh$lQ\GHi$I9 IfKչLrӗ$D<"SU[*Rm_ FoDӰe~a,A(FꆢjM:RcU׼jLA}ąٯ(2["Z%lG^Եu!Q5S 4"OHmNdf~Nu.Wح:--b kV`UknnwG/zC%ާGulW.hG7SU(xdeT[8LP ]3 ) C HJw7CJt %ZA)PQ~^k_{_ U=D]MI zꙞ}\L|10(01 i7ԵW Ip3I110J Aәv?M֝F;1D` ء ez{hvp䱃 b%*މdJinF;~dԯ!{ o"U4NLGݟo zS/<䟎Ys=z2ZDvwX- W:XBab8LZ߰UUa)9HYPSN\7eSbkud&\B_:T#= 4;,7?S!ܶZ6:xԄ߀+/7yf I˅~%UGVL`A(UXx:E[ XTw* nギfBo\P؄Al@'Y^BR\Ooh*so6Y Xtw) kGd&g-V̎ u ZRY"CS%vrpi(|86F㬟[c~ 4%XCJcϋ)FYI[T9ksZ#~]l"e} mմ8˸#VE䙱7t] I@w_2Ji Ǔe bcr lsMseɀIR`d{p|uvZQڻbgհY;}9D;xi6(~)v$ZKb*D j#܃Q2V |I;:~Wz_ UMXڱ%à5ݗI;˩t^ERޓ):!*e U8ۧ39d3N0I+ceĠm^ސG-hPy`η, =h>EUXwF:uy/zF`U,b~l#7 Ì8:=9v+;FɆ`#?P1Cȉ X &͚oꃋ:*J&)"?A'7|XR`6ŝ%-lk#g!t "͜mF\P Oykݮ3E"9B> p̞jbϋ& jݧ"taHlvURvN')͏Cl9́y*< eGCR+*ࡇ;fpc`XS| |2{=~2+Zkg[5(Jfgjq=o :/<&4Uf=⟺|SV&(CŒƙ)Y?+]3"lWqW\piW$P9'8raP-w|$o:բhZÆ*/kUjP'q~uTO:NT`ȃܱ.ah0ˢ/Klq٧>&ױg6A)G kg(|K|Ub l^Wbl`9&qũ0P#tϕdlR6pD'|=џBӫ3\ AGc::Nue\̧3?tߵ[I#=J$%%F) !&z)wskw?6 /kT7G@/6OZ&Ȫ+AA6D#^vH FMbq?u5T5``?U%b)L\g|3]ɧWb$1j ۘYSk)8R 6N4o@eJzOZ$qwRaqe%?PΠI !@9՞~+ȡU&>3OדܯG%TYLU@w&v\Q\b2W@pmĞ SlL(۰ 5 ꭵfM dXxܒ>EE)H3ֽcX/فi m[kt5A/̓c O[#ۻ16~ygo6;hR@G||zF\v^8@}Eꅐf;,cgU1帥ɰ I?(x<&?gq>UbA_C] ^֤|-H)Et(p9L.z*0G="+4BnI!!xƐN*cJQHp_IJr &a]D)"gz >Q{=ĸT"O{lTz`-4Amj+&bmgr®hzHpuYЋV\zh-Ҹ:,2 z )̨jMy*cW>T!҉eU R)sePRލAT"~a7ىy.(T ONGP2xhk1{Z'!ma4=,#TʹZ'`vp6g^uC"%xG/S<@{1W'' agGS Ђ&qY;mPBib!sI_A&7߁az0dGp&Q+QP8is%޸ڍ #;^-O1Cb7.FNi7'~rHqȔQSNG+=7/&e> -crKNJ75̌e9Nr]\(p-\29ufָڏEH${.BGsL;aV& c`z4lʩ~t\ 'K? ^(zRquXD)1nY:]DLiEć\_\Y ZD&CЌ42eDLNDeD M\?EP7SDn(ɰ#(q#(8|γٗ?pb[ÛG`5|@_)Ė8׉ "PT+.4X{@'1o6[X.\r+FA*K~ЉǏ ?_b}p6n Ғr!-Uv-;ϖuޡwH=466#VM_pAu",oo{!S̙ U͌.B̧DAFޔ~452#)zn_W97]{brH9Δk[٘U0z;4S<'՘{\=gtE8nuÕ@u1`YW,dڞs{Ue bɢܐ86T,&)2=QNRMk@ZM/L wTr/}ʝ/"`J.IkTҟ?b~5d'! 6d{[ mK'NFFb˝~]Okf9@R*1ӗQ ,-]ޏ5 }ʯ$t+?NY\as1zz|=(a]1/#t( Hآ?]ZqyL϶/D44QN-I9rK DUB BvN%g6 >* g9 g~- F`lutM4c )q%x XeXsB%]&wx0kŤʠ- X'nƮV0Λ4)#^5'ref+Lȇ46Vr[vrvUV65:EMGU]gǸKV rT!5 g**ee-,e|Sф\^gj@) ,V':D1ۜLzu%]E==۰~7>];,mB=)Om ~xF|#(B:cʚJchb'4zj.4eSs7T{qkmT6Ɍ'*S`v5"O(Wq!>IdIP;SG|)GNI%ReP ')&zhLCg?P unJ$c7VV|ѢJ ,dۑyc35{9kVk^:6SJ5dqwz'1A ];<28: p%n #Ǚ\N[ ?pt/oӪ'!9_3 EМQDe(mw{P^y OG=/IqSe%zH.Eٍ$Ig Aaf>5-k6}SʣϜ 4Qbl_rA5 y7rgX?:LuR(/C^m<Wz Ekw(}bkVD WAv]ߖD/!'Fgam/lyHw_,_@6-H=9Ovނ#f'uiI[Yج^" B.# &UZgƏ[#U=v{ 21ƹ9HYc +`MI]+U ߠ6yh‹?Xm;TNOX/#<նr:3<'[oKN(i^~=+nMY>p kQʚ%!QA$9Nke5BS|ʇ{]%SK-HϽ]Ĥ 8xVwYYi ggCTyJ yhKX ֓"0!WN`@1Ib Iw-˄OuzZjG8@o,{KR(+}4}HX#B[hPp$\՞5H |#Kfus'z(牶R<ץC/wƞ|$قQ⼧ 9a>m.G۫m '7Ҏ E-Sv&dGĄU h[1/'Xšv,] Z$b20kh)T|43{NmA8Hl;0nyV"D{Q#hrETEq:Lo-',bTuZ,@$к\Ê?/܈Ey=h8b/0HGz;g1Ưi#ۛQ)oޏ}Vk\G:yPS>Hl$BOXxҕHO{aJ <$HsCuCڃBA {0L>$q_2\o.Nއq9Wl~Չt$*fAX#:t_qid5Gi[Fpw/-AUCxv8ΞW CX49Z,pmT7V?@AT2D92IW)_L~ٞN%5ĕs//Z* 08+Az#) KP~$il$5e[-ݱЀ8Aw*w*%lC=?"+udn-% nd7ŲHS㾵&Ž#q21Y$ꁃ)Օ"#G8O1i}nn= cnVI{+",x}ZD U-ᣋ}n[r4y'CL \U"}Nn |@iͱHGK|G75 jr0&!E|C>a) s̈s: gm'1'JO֡eJ2nf\˄`I ~Qr+e%.?Q~%Ӊ _~0b)1`_@](@_7ify74Qt/ $OߝHέ+Oz/I_S7t'[X-2fwPIʮ+SƳE_Q"1\7uPLզ$!N_͞2O`w X%bкzSnEK;y~ǿ_8]uՏߦbҁD _޲W4(*b۲O䍞S!,[X:"~3İ\l{߱[7cZ:]cKjNzN$}^k49V},K"Rug H߮д H2KjSN\27o#h'UrZG1_c(x >)> tN2unCs7B*]7G$2N”jZ1nr!}.Gʭr7BSV_y?u=߰sm2^4& %T )'i22[9&K^ouHd)Y9actQh7 a?r3j7SSPؖ&""3`]b[ K% aZ>RyO'5\wCyA}]tխEsL؛~'1ڷ>E=PYjiUNsQRyihĒ:[>Opw6r&,V-G Xt )xMb=]oVӹ*.p@ | FLeB:Ha*vK(Tő=/g'aƚv8h'D eMc;%_mgRR|ݤ(Z'n\]_lя}A9 C)K^E ax&l8%kΑ {!gH>r6,?4s3ΣD."ʼnTt>\W7$D2tJf"ګ)x~矹L5w`Ъ/<4Ê*"\2Kk< [!I&d•ƗϵA2.c6 Aa+&D`4uތ핳XgFM)̹B,H.j~WGKZ2 4+ُ ~VHn]CDb82eY>924/Mr{6yǾ&ũ-0jMu"3>3wk40^QЌ8OF 55G_4}#(, \|"FH<$TtzZ;Li3  Zt6RIk=]Ηs0󢗞Bthjw* C},++CHp]f3 sv7|S3MUuѪBrS'7/\BXюOm=5P+®ap_iGn t386y ?8ݯ?'7q!AںӇq!Po\|55;9N b|SIt=uVl'q=FNuߴ!*"V&1;8*u%-Xc|Fplm|OZR.R؂O~<3>Tryv<# LT΂t@ӆ3yPSN%i&O8/tbdGBހdQwqG3. \N jh|=Ţ6D vŜlhQOh{% zf(r^^!jKp7*wR} :_ d:e4('JWZL*Ɖ,5’߭\q_ԍ+u*@E?/4xKƞcl& aRBZvM=y?vESL>>%qœ@I3K"WjmsKcУ_wU0k#$>v6V1R4Hur&5Yĉޣ=Pe=>DaIxLD(y}cڹ-:i{"z#K&c[G}s 6nP-v4w:\xԖ:xWoȍ&7Vkw85lJ2*1 SeNP >+}xNVZf(FO>b%4Fn_02> &9!߳~.T;Rѻ/99 Y].S DjK,!w nX$ᴒx&` e\{R,ɧ,̌8=yM٩/cAd Iձ{F!IVsA+,-OoO'=o?6t4P;,ap"` F/oݵ88)}yJA#auxɀ5ܻ~2u:ezXiؙh"|voI<cva۾o`(Hs7DHT6Q&|:4^tWUP>o~J$C"AtW[7ė#/JOzL7{%y|'MK;= ٻL)Qq%gCbɢl{oK*Wgp|d?ft޺Nߣ,koQOE78wzzJ M③XmM"]iJcg`Y21 4珎>,b{[t'3(R9OBݾrhZ?= E+g5~CVmz '<,ꡡoMa5GZcTY,щ[9D ft9cΉfY0,V'wUgV3)s־Ĕ?gMW]6bP @ O-S:?'~ӧA]+IP^ wFL.AwtD$b[HcZyi6IVӋ;=[xT{6$;0;? 5qZ$ =|¢F>su3oDI/.L%7? ;X0}/,v$3 : {yىzw 1^BgQ7I2HjuHj*Xs7:F>2r_s&Lʣ=G$,/+/ e\1v W}dVXI=( w]!ɏHsDPr#͡B.8=i,O:Q(U-mu:l:ۦN O+wşJ'/Z*w _jMT$߰2<1ڕ3z_b\i@w+r!z+ 3hѲ[kTͦ]kx]vDef7#Q邝mVVZzۮc׶c<DÇAg+>=,mL!ګp %,T@*݇::KxȔT?0]~}E7c#IBs l *C\ > &@T n+(,bq'7iSY3m{bI{^=T+oEe@Ga8;v|v{f섇8 m3,rqSOt]jutxnuf;=G咞 ,P.U҇Jy;yI[! zEiM)m /q^.C2v/q^Y_5RϋOIu):n':cV,e[(JXy `tY^h]up9PȺ+Sѝ&Bւ#6UߧШڝdSo Eل x-J^pFZa{ۧb;jJ#-I ?9 r"if;&$nmD2IuA 7ub%$R:GIBo]OUhL&y!ak>*rb<,YTta1\VyZ(PX9´ĭs4&:4P٢ܳR'k|&&wrWc܈6ްJz!/ f!A/FH g{n:-¬G_ZXEU4O`gL2]i^Щ&|8ɽԳYO)p?'Kd0-e-C8"h m■ަ\%2: ~PYN/+(d.46FU ڎ[GG5aQn =PxYӈonIVƐ,K{PVki f jQmyY)&]k(d/ZR=JuE1L޼v`dB2!JRX>0zY\Sޏ'UFam ) 4.bE?u%BH}k$m/ZrWj8dW<"^r/hńHv0BVӖ#"o^:Y_W+Ԕ+OƦ_/oPBR* \)4qa!"K*^:S eiՔ()m.LNV]; ͳ: )wثU/G&DqVAf! -uY <ݢPfy2ۋ1h!P:d}\N̨xT$'d}oyy~p Ǘ'ʨZΪL6#a߳p'alU6K%sҫҰޠ-[PRG [9&hFi*d ^孪|T3DC fVa;\r/_SX@[N2hHӏr<`|=33*lհrSѝux%Yʝ**)wq\<9:.ON\vW]}s y5Oҟe O:-x}aܡZx{W^b oͮH!遡.1rAWW8t ?,-=h,[Jrty}I,W>[$`,g&IDu"[)Hj~0,ryB^Wy#Ÿ`j@q֟22>0&RA8ih,eX,9^ ?gC!V< a72,vg$Wd~⼪vD7x{ EZAGLČY!u' Y8y_*/΀аSVОX5oW$5D]/rPd*B ϭr RUxuQTP1DloYn.y @q]M9S3Zje%8-)Ε0 ^T 9܉"PVdg \!YX S8ab0"t`:j GB"xi$V[#AC72pEQIG0NݔT41= 5T||2Zl8Y譼7{;X?I#}E0xp$j?kQ [UG:˨uQg'j1?{Zq* 'Dl_M(~txjS ٬֞ 9,7^ VvMueAegK'۫-b{ ^=h'"UwECqLUz-Q2zBN}2V%gP8W>'\"u$j@ɯ;̭[8UvЮC>~ ^_q;:8j y \kqCBu X[û>)H?gyAˑ,l R[@1߼ph ~$($J"v;Bh,ᴐq:[{F-P 4&gWIV|!aA)ܞQ39gp[iQ.bj[阱>`U|$j|> BInrBh ! }H#TB7g W@W)GweCmPW3TB A"6pN|F!Pdi:PGPs'le ɊNBj&ypBTj-[7H^\{8CUDSج4P.Q3|Ÿ1bHo58s Mbsg\j5䘹C3`6H#j5/)W, @FJq} }G$kEH *V#03_Pa?Z"VpZ"q|v8W BhB 3',Id'tϰese:0 PmσઈܥPaT:Ca::N#\x7+E)Vp"xmJ$z>gxp$AȐAjou.>%Գ"Ѯ7?§Uΰo8KnMlHTn:BY!W^T7{/OH""g. {$yD—S̀4jfb)DymRz-6CL*bbsED7D ǡ0&xofkǝY W vN(| 4AB<êZ+ ]@ۮօP#[TOClk2Pҟ(]q,PE\zP"{A@ҬF½"rl0nc4@ _`Ah=~ʳL_4Ud|CDQtm+Q_1~+M=JV,M`Վ10 ̣[X@^ɉ"I@.A-)N XegZ j3Fݔ+ˆ/xUN_ێ%%"4rJdF#H4`ݟf:F'E]Cȕdz `0h@Xl w~g-t-w|Ca.0u=jznOU>EL@k1$mq nh {d5:DA9N>Aue&\7 o  *^%8h:n|iwu+%uV7FGnFF?U6'^IHH hFg\mWdAog-/LQRnIV|V| .`Y"^e HFE6R3q})&!m˜I?׼Q TO{i!Lת-Q*ҺG2H'4NiSDm>B؊p)LaVD {~zj76' B҅:HmcPvaĿ u@`Yij AQ+EuX٧i 05YFrSŜlN62ۜ"N5 ;ǖ e8TqsL?liXxN*]" E1dT]Ҝ4TTsh=^VK-SP9NBHΫb&G>7٣!$Vj.Mi> HT9NcʹY04 @SH@ vP_;-vS)]b,DHB;}S+D Km3Dxi]8af8XIrs6FfV9T^UaUODit*vqTNw6~|V_ , ؏@"1a~ o&"xPI.KP lR:Qzjn}G@{ BlHlF\C)$͔DFz4n1ںl)56Cmˑ@ SOxv(<(nD.elm®O]J"wɛU)_sHyobGǮEr`*g`IЪp%$?w6prFZtncUI JJBQCe&Cx֋{r^I㐐5Y!D6T7$tܥ0HXuux#P$sqHv; <,r:O $CW:[6 E ĦtE-S{QyZ~]pސNW 1#px  ΐrQ0H-Dge7] !pCBLIhHmHԉnN+VTsF,jQH4-hHdBdڐ\R#n0TEÕ|=oCEc㨎 X)>C8I+L5 h(E/a{w`ReˡT41jk0!!JLрmνҷ ,):HBg&U턂eNe{XS7~_@Ys!RQ$ZI'B Q/+rvNa?ˑp+vP|+HkH H` F]'$suMkFm-+=r2o"Z}m$!5 lbV<噳nc&!ZWw74:<U(炍Ӏ`!^baph/0wViQ$=! 6ʘE"AZZ(ӵj(um?$~R_u#Kkn; 9-7aQ ,qM; :E0@6:BG/d!$'('W;$ u!VQ9d2we&\:@'@n!!egPPCXάFCTBU< m 1+$,`j }BT!B蔐J^˩ V: ,;UE_!eS˄!l QZiR02"u?_=VGYFFV1YL0Ӓl 6,ċ \P $g^g\xX*Xn6 e)bD o4ܞL>s(x@>TFnmht*WVU(!WH"d@ʹлTQ0C_Uڬ_|?UCB"Bޚ396^*'Fڰ`P}T[Vd9kh"iV@E-yѷ؊hetΙZL+焂Cޮ .)+F|( sL*G!):貛Oj160e+Ewv3&qP U;3DzOA "R+}q"6݊.Snի qD-*-J zEb ޥʥGأH߃r`(p8c jBN;39St+帕HAXiZn>G*P}2 m:>k<+~])Jvwn:P}d$K:vn^p+t):œdu%:Zu8Ħ_T78#ںgBO,y̬)TΨ: l- 1ZD·˩e9-Lҝq~a9TCbzgvt91 hUiwtܠ 4H#RjiAۮժU@Paf[ l槥|D4xm4t$uӫ̐hHRhANe6'eOӧ j(BFN)Sb,"Ɨ:gY̷Fpm]/o- ˉaChX Il0`"U1JC>:kJY|K;gb&?g.'d5xl}rsuЃZiNoio7tlA![u-"h۶}{nػ}gZV]-`{ -nL0je!MO96Μ:$7ԙwo#D:7sFM3LIw=EDCe& >B_#{B XmvjoVH`=.A_v qP|C-0P?UE{{{nۿ{ppm aCP yC>szUQHQ;4zD֣Q{W.%h.uA-JBuճ{=]5IQBU41ָBԼN eV wu GAq/Yyiu9' 3'W^h^ܘ`lsCFxhN2{Hz0G4#&9jRUvy֛o]_.ԮYP6 !R6t6ݾwz}抪j=ꇩO4 8(ʭm7HՔ-5LpP#' hXRv( O1$ԕZB?q`K"#xMotvtw`lcaRߘ7S>jʬ֔jsXcf*H(7vXA}6Noow8`4u"C\hqe*rm'$B Z=qΫ{wH B !h!Dhׯ?v4ˢT=㾴I2UA=ز CPԟ\:!jXlFTZ@=s6jQD?6 ID!($\ӻ| pFP'a8]0%iyO婳Uoϰ ɲO^Q؄YǬzA #΢ZkLC0<͢6 O}|wخV;woػqsO{I#qsϟ8~|L{'W.mw b;@C]) P#(kBw^Ǫ Mq5p29 TJ@'o>m狇>TF Soݦ޳du7o?K?X,e/ĶY@S[=E9ujq7v\\.i|i[o/ɓ[2G R󜫋`WkD[--`m"hZ=Lw&I hvuʵkW߿n-Z 'wp…Nm7%jbRܹcN;7oܼӶ !,sc o={ 5 8sf'y(GX9)A]D mk.\}lk-X2? GSe F^7 qdpPohj e+H"4{Nex?Ӿ}ҷTgާ¡!Dǂa`K?Zm"DSf,xISdj9Vp[|XޏQE4j ?!mjssϽWvX ݕ⑇O_|乳; _Xmm_͞md)Qhٝco,?-ԮΞ],a$:Bdti"<kAgC6'8Q*.Z!;%zKFm.ψnsIE, lu8ɜCB-EZ $1[bc*+cHLWrb3$vm0)DյQCtMYThL1XYe۷/i݉!X,⅓sj}r⩝> BW+]?wo-+C;{w ݭcǚE5݊Nue7I-u` 65r\ݕZ91SJ;bL6{MZh(? YTp׃#~в A ~wa4{-s]5R=Py0I9Wv\ƤۆžU2JW0u17~1tz-NT۷[ff-sl|v VsRhE9[jWo{|qիw@.;:{Z.o߆wwvw?\i4h lZ9/mӍ iHzx!Mel+'oXs7д2gs*ocgViIu Ďp[!5'NnܾsWT簋"n\=ybg{rjQHѨAhD\T6N,G8!D4Ԧ mzicQљ%fQ,M8휴4HLd'HɨMGr!n:/9}ٳ[[] =|ίg|A"Z.7߼>xJ4o:9dB\wƏeh[~-+p44U+c?~'PiءtI-a?^ MC;;,?mՋ{; yIŭh%|h 6AMy _xһ=Pꊭ[H^jd%RMUE<l̺' Xnj:$ĩVbɻKW':DJl>y7)MpctLqjCN2 ims_8oROskZSkeM~h TtF_ǰtzz㏟_x…SV>ȃͿy;8X3ϼ/}WVG>/~ N~S//W>@̦/ϒYG:g-#}g-go].; N>ą3g>jg@m&.͔*:eAZȂ$֎-yy lZS)` "VJ)G2eض"jj@e㝂S΃R5ncHP0K|j2`#r:#Jyk\pJxP'3o{x;}عs/|{_ҷ> ?O_<{vWi]So/^KopN{~gG_,Ip0(r6DOObʞD-я[߾tppwk Jw^<oPg8[@5IM w,+1Թ别Grg{!A Dvݶ9Dm#j:-:'"rt=Rv>@谧zE8Y_ns\{{`Pƌj"EPKg8ySekCa֘k16mg^;7wW^}*"=??#g!{駯3\t~/^}wWpίgSO{KWܹ_G?y NaѣɎ3ե`5@xo}b!gD/^8sŅ[ۘ%*j(+xc$BۮղYSLz]yP9,˭-; A$I[(!Rvö}|wI   ^rl+Ϲ J@hǪ:c3w$ 3ERQuEGkZT;B[-wԟtO|?<_s?zݝOǷo~կ}텽8ɝ;?O]|ѳ޻ E?󙇚!4}"l'5޶>/7g\,b{ӟSvV!-i]hC(T$<@\۶m[3A'TECT_`Fh? (YWBnT''mvSϩ~Y/s[>ƈ(X*jඳ>:`ͦL^)/MmddPUE5?1ˡr!NM6kKk7o#kw.q޻ϟ>;ݛ7WGwxwoKW+o3gͿ3gv+:{Y}\#fMߴd4?eoA$:O~sB u֒.n v-]DRR+aU4*A# ZEH*k;AP>%|o]*u 2 /]"t%=RWNeҥqf󕙱 1lox.S! cȠQo{_+Wmut{{\vM|H}ӧwk__gz5S}/W~=~l]B)AOu~=WowږTc?ϟD\h ~rxke2R$+J%(z'GVɭ(v "rdj2oRRgboͰixnTS* AWuaJ=,qnM*=gO_~;_{_ܣ[毞{+Wn&(WWpnvwږri4|iPc7OGf4L${`M]qK}Bz[<{r6 O\|D+:#-n G__;#5MV!PڨiW|٤QA_CnGSbב:VzNIz5}r^~e:^nF"#Y1Ƈx܈8`4tw=/T;t(hg&Ԁ{{?yUzO?OɓهoWמ~ʕ+7<'N<Й>#Ξ=Zw?{?|O;]3*GQwo_rT$@GG?߭eHU}AmeZ;Wb ۻѧT HE͵D *IC_\wftW~Cksp TZ)݃ Vcу'Ad0##R9V:(߆.bUSP71X>Ċض[W޸_~ЇΉc??3{K'8ujO\xsϟ;w Es@Gɇ>}1heL+S/ ;-?:g}m[xBZAF RI`z7D_s!5MW]k [A@Ftxd!N[=U#@RnʤCB*·2_Up< Q]FTxJ)&dOٽouqq|̙x'я>zs/:s؉ۍ={\Q={voO'|>35zut  4B /J8hm3|-i^}rGӯ`r!}+Z'duÝbCUdǨLߘ@7~2lx]a:b[uWtҵv^6ݭǷΟ?V۷_ҷ>iL:9k+%h9$N} }Kɝ/^z.5\GnW򗟹v[wO>VW ~/8L+N|+Yc{ HtJz62 q˃;5cmm+O m n8K u0s A]yhV4wn@"ĿƘi5Vb[4:ʀ|lIVHlz4*$?/}hkk!^3s{+m[moo<+b[zOe+ Ԕ~gxի7:yrSO\قqjXsSKՌâֿX4vR 6imBT7tB4 z%2?3(K=قwK9,R;wF`5jӺQ)IH-~OZ?#8ꩧ^ׯ߶}=v@T+_|Ν~O}Xg3(QsLBj-V[ݴ8eֶAjiihK,ka^<~#mQ,KoI V1HvDQGccȝӎՑJS'Uk_iQ Lښ<=n;w~»_{r1M=t~35m[z+B+x>?פ.vWZum}O}BWO opEw9x5Xc7`MMoy B  $P-܄@i 0liqkzG]_4S G? ï{M?G9?Xw?_? Mzw7)sggqp"-;߹?nt"' y{|ի׮,'?yagg1R ] =T j4_7\4iM(LQSi޻yQJ/9y_ap7 5wcká=wm9un7y;?zßc{ OdؠF8WPKb2)0 &pb5ԳhZ$I$IIP[dQ$텳^ޯ8닗Fjt>zN-AVj9yrĴ!ttwʕrO~2p媾jzi5[߳@ati컴>I`nY%dTÅ`,hשVnS A!H#`(YIȄO’uC=HL|@Kȑ5A#i"esbNo\Ê"A"P)F:a oѻpJwsG?:1;+@-o1n祗Nmz{cuv=ȭK8çNw% aٳ8Bxv5ݨ>I MO7xҵ#l(bLÜ+/L<h\݆'ޑ`&nYAA K@ӒWD5l M?.d7I;ޘZx;~bi˖e߿q[.ˊz;yNeddرҒ5ܩ;C׮M;~vۚ 朤 Pak##.\/ p׮-޽2"/ѠmM8,#q  0PCy0PfL܌YjPXp1e)g$14BBu'wbd-EZ9T;D|wSӻU>N[Fm}v򓁅b.۷Cڸe˲l6} w\:֊ݻnu?˃&B]`oC0y}r^Z[s;v3=!SCd"zMdڙF voQrʀ 1sF(@(47w9Hׇ7~#IՔHr")UA-KAzħwI Cz3>^xyX \A>͞ryɰ^COixx'=*1:%ԤPz kŋ7.Q"FϫuWT AFHD\jGp,UA7V՘V&:rmUU:>i ڧ xU%jm^G  y,%3>>xc|lN4>>wT9:H- ]Wlٲ{s47gpll?<񳟝CdT'9HK7Ti{{n%MMTPOi̊Dվ$/EY =LUu N_9R0Pqn@>JMtI@(N"F NH4"Vc͌&E[Iާ=Qªp|T5wMRn;$?y~+צxkWL7 *<"ݻ%ͷͲ|dKSSǏNN*tD??6SUɔUQ2 'jkWo DިXkn*#OQ$j'òe# 1 B`D 3*c: XߍLNZň+xLrK0 `:4Yg&-f|OX7jfUQgV)pr3#hF .֢uz?[lY#{?mmz듓bPggmf}h㗾o.j=;[OO=q {{L&Iw;<<15m޴5yphR]\ycF:'1LR EwD `;p 8:S#\QM-길+"{,;"~@ z~FGg~S?qnni~ kcX*DΏBN{{m]u󥡡eZ۷9ot_<_(=i\x+{2FFfϟ# p, Ȝb2^d7f Kw.F)ٌ(D"0sPd/qFR&Z d L KY,"II.BJv_nj(<(3z ,(m~Bگ.|{GΜ+MM[u]nڶ<הH 6?Ӆyﺫ?FSS߸1ɰ{W?ЮK[ ^"> pξ?;=;AzZ,b _ͳlh9 *$F/eulٺL_gWFLKy !# =F lWHy!d(@2"U~rt $b )$C Ɋlc$Lz/ k E<@e|.2 0n4hATQS~5U#WwӼá}6 "G"02^*$(]U=Ia'=!D>  *E"#XH.fs1W_Cit1qIIυQ ]b-x{qUijERNUԣ:;_~~KSSd?)mz097.~SO{/tPօ r`vm;UNyǎ]J)bEIFUgBT^}7-]CGWrY ̈́wLq @4{zLgQ{ rI0@#|ĈBS@ó`Y$ƛXQPJxv0k=q[j>Zl\a5ۣe7(eXI:~QOz\U-š,$&PU]zZ(kCjХK7x:2hn,Y#~c[A~I!iDH@`w0n5qx(/ E,"JpZbY-k!EE? v_Hr㮍Rsb7az]{L%='H5;Kh_>3@޴kW&ҍ Mh ,׮Mڵ];w953S+Yq] |y>dr SW_P.SmKȬ lܸtnV:}@3Tz3 P Y^"zH9 :I$a hj[4N^ a & "*!3JQh!aaMYlKX/y'6)E*3 +ET菪7]qkk]O[[w{K#zLaP(_2qZZ6,z{VK>?}Ϋzuǎ<̩RaS?r?K[wSpf Xphj>:\ښLqP52D'1LB# H!čHC 1 `(᧚ m* JlDg֎5=9Iި B9WOaN݈F']\:(>:jS_3p=b/׵{G^VCTsG5HdD87I@X_lOjJbQPw&MGGzǡH}}\Yve>M_6,qO-F; MaB| tk `6,] Ey $ߎnDCrQկ0&VNh8|HN@`1!S!$a: !&@^p. Y`xZ`%=<9.&*&T&.}yz u$@Lj[J~$8H*7T65^wO.] w?)DRU쟅 47gsnZ逸N>|9 nZOl.Ը{W|[o $O?=P.뷶vu|?+r78QGg+3[D|zl2f maƍLdnf&Eyq*$i$#!"#羢qǩpXo3УRJ^EAd%I At]ߍJ#7kJ;i"!S#&!E>qs[[â~ZR o[\=׊'/ҹ'86pr$ 2v-+[oݷeϗæt h@&YreK[fMWR{۲e}꩓_4LJg=P'4Cʳ$NSFfۡHG$6NCm&P}PHz )1=r" 0 \T_ID]t-Mij,P8մd }u5഻:ݠĭ &6F(H׏; 6V=V:4E4%zapâ,!0 @g')K[` $a0u}/꥗_:?;Wdmm;{?neEWwU_UV & (=aV(lL!Z0-Cn~ssy\3*YFSQN_(E9|kp/8Dҏi &sv0D=@$F"THr =]CޕI#@*FD/,RJD 9H1EH:6An>ט@H@g<Θ#*L TQ;3BH`\!=8!Ix5EW25=ٿV*ierx_^FΦ[o]gw۷Zp LV2j 岙 ELe29Co\c:?+Wv<9e.^855]&AQ^9J**ٛdž쮻׵7Y-7"@b0J %97o# ĀB}DrBR]H!>r0^?E"^"Dpg"0CS1 F |{ᘐyI.-df/lP! *35aB'p.,o}F/ `ÉZxGR|;5xzo($U{XbbW#Foit+_^҉#/9|Ӳw襁5ȧe⫽x45 KDE Yt^5%Hx}~xOS57}#gΌ@*SS'G eWܺu9j_i,R%'0+qwm˖ӆIsX۬ { ;FJ \ PCi+7>iЮ9e9]!r&J]Cj9 N1 'U%{g6jZ*Ud3iğW7y\/^;zu =7]T.+W EK;?%Bi۰gJTnommgg~Oٳ?>m׮>9 H'i[p:~)hmڹpNXy]>LJߊReJ]Zz"Đ4!Aȉ]Đ#Γ!2cʲ _ɤ)BrFڡ`8-jܭLavҫ)JKF28;1ɽX/qO@SLœi 6띌{NHr^W-nQJ7@e /'_}T ͏fz:?00z}"|}3 EdBGdr81c`llyĒ8dM7-җn}#G\@W'xX7KGOON㍷reMK3fIVOAHׇİ9P!Iלy.n'!(]BBJ`(j Inbvٺ9;TDZTNі1 V%.Y nu:BPz}aynM5ϢOs"]O6ct^EBBէuxImh}l#Kwzt{ܶ90_zLggsWwsGGczXggS\hė.Mq/aU3~}l>=Ƅc-'تU--YS|y| rBu^tc``@Ksvξeڵ6bvR;rX2#c VI\wGPoPn BSf#J^ C,TA{B1@i$EB465$e"ArHwi^t2>Xa3񄈧xXڌ2 @_@M.;0:v qVy_C[*Tu-_jK;*2Oe.!tamn|{K2 pn_c{ξ7-%r IP@<AN<7mttx @DG\/~Vf?LNOgf Bt2J9i cdžggK,izS/Kc%9¬lrhR< E  EB@ / ! ĸPRyCV2"YvHUvf`c`P0!Tjl!Cӓauڴ=O+rT5Lt0G*$tj Eϭjg б9`5~;9 )'5?j!+X=|_I&=jjQe); N=?<~赅twǷo1i)6C<AAV> T 4D\X(=5kK'jn|c[zz~𔺷P('e MMC'OiҞ58FNhQL5$`M(b( IDATe@!AB "'f%s Y!^_7l#HƳT#`[)rJv_5l@ bW)4cd˽?;"8\rENj.==Gi}ĪT)yClp'!A}i47pkVF|7I"y䶭[RaSS 99r/[{;911zu "%~ZZw{ylZ抿ř/ˡ3f43SQQ$v&S*h)*P&}txD֜2s g1U:"#MD ؀j !FT2iRI Iv8Qk"g3舱7sէ8e.MdU"IjxR&l54O=ɰ֙Q\L^w7=7cEΟ9;7q2u9CXԖyϞU!\6ww`||.&|f3v?g%A 1Dp~vIC?r䪺馛-[&;YqÉtR~T+>`-K> Y 0u#a Qr'YNG̑sK ̐t#d[X1@< T1#BbU "1U}2hZLB%7ċ!Lp 9V8IᎶԜ)YޒEտ*. ՛Ш̞:H:j".Hy$lټ+Om_o/IVxˉqcA0#].qAڵ>x֭CuNwqkxEJʕ_]{ 3?vvh:koLza~DDKd&㢆hrC<V]OLTԙt RY0InABbD58@7b T#1B@O05=@t̶xw:@EJLS11' Kc+I}ԊȳKDb׀=Ҫ\1c#T,+Ҽ/d."nV&NMq֞ヘ߱bE;v?};miBS12鿨ܶmgT*\CcQMuLsŨ =$C^ CdaT 8sʪRj3%$WGx]uSmC(բUj$ĔvJׇx-߿0 Jkmf 9E"/vkT9rʷu+c"`Ѭn,^ҜFF۹sEKKjC izDfR'*Ff %XOR+-ĕ1 q(h@[@EIJq&1I5 4 $MTL:@j8fhEgRCԽ䶡m_M2Y$˃U@ȕ!HftһffU71Y˗ӚϗGo=љ0$6_|sswܱvξ֖k{{+-J"Ƞ=y*[u=q%gZ.Ǐ XѾvmƍKڻsAssΜݿLQE]+::$?X߿D8rdX'1`sHzāDذdNuS}QAe9G"H8VKruFk( uoHKLi֯:SNÂtȉftJ,iQVW=2{KWI̔kL'^/nPCiUŘWr *>8Tg2wNr4D>۾; s0 ܲ11X A1nmMkkTYpꜼ0<$7 gؒoHO!}YdOrC2Kɜ%pu:Doaf. $.5dʼcI $6(cz8*01I5MjR-fuy|cVJզHHV 6JšpuZCu|a&P3|9 kߴiiee (, |WDpءCN=wnB؃%uw7wyڍ{ ~_xܹqQ5޽ZD Q_3CAˈ⤆ " e' AIEĥq%7FF&4.3)D") z d`LEnn2MC2DF&]VfjLR[\F8Hhk IYI";$zYCHK@u<5\@Cjb"I zF{q#ͫaHpk2~vEi.Ka@&Ô#;΋@09 g^|SR9';'r, YMM\.hjb{.ڻ;:rͭT.W r;zzZ!{S@jCI%xi|`D!(@Ε AM jgnsXPS<[3K$2e>!8f4%ZlE+PbMf*Q5'ʫRP}K5a=`DIe>k%Tp#{ 7]=| S5z?dϗ%.1 G=|BJlutV\kݺ+:ڲx&6Qi,F` |X)Bti1n쭷fCS6m'0?]R%@' zPQ9gʤQ[=rو:J100Nl%ROh$ݎHT {W= ds%G0x qn4M5d2dnwWrǫxRcFŵocJb9شTSS3UiL@DK tܴ7aX ·dWP)}o~ 5ݴ-zuǎ}Mx`VnȹK=I'G/]RdիӡmUlܮqq$Q I=M}~'Cגͯ B(A rdH0\5HjO6U3x{]I'kZt$Ł"TrDl9^i.Y:j'r`lW]қ*$ɬ61IXCtp+@n*A8<y$WK ,iY)~*B) C (%21rԷIYܲewKۤs"- fYH)SMnkÊMo5ϗM7vt4KR{h1YaOuPz꩓׮ͨ[|߸P(75gҾZR1,|,sCTM0?yrȑ+}/K[ 7'P"gCcIM7޸4?_K|7/JXP$p*G&H76C I&S ` T#_kYkR* +.(zZ'KM"mdtO!镐sOAHY 6CspʰX9;=C q&Z\YALbE5wVdTq^NSȤǕj'\GŠ ߬9_aaCrXo{^LLETƬ RBId2, I@b nc?}VELc. N#kddKJiL&aY\Wb̋tP2&`#r1D(ȅ#~*`tސ TU# %C}=ȔRU$`^0H6>Vi  <騬t$uQb61+@ۮ$C2RtU(C|^. a\l" zۨn[ҙR*xVlz|ԄCj&ХL5kצ5w]OGmM O6x#T &\ Ζ2իCC7x M˖9S5Nsәdo場!"mڴl.c3ɛi7 ViHf1h8&@3 Ce3 Yi UJcQBͧL769N mX@ză 7f2:ȫQ2ǁw K$&(]5ׄ57+mt!S.35)#dRnS." lkKnO}j?uo|cXѱc{o&,vkH~.R1,<ۛO|d yM@5^HQRD=@ Ir*=A!!c^#U O\v(TH&thR[(b@jucXURAjv]fN=1"UnZ!ߴy󒶶܆ =MM×_xlDktm[kHKaQ!lnX/G JX"p[6PRqۼƥ/Y~jBR<;0ۑL@c Iҍ@*`_,62!z omuT )1ց"F FA"0nBTT;&`LH(W com&e٦*գ4`0SgU3%⛳Jf䠈E޻GFf~c&3w0Sgljr8Ƣ`ii9>*|j(sD@d߿9690 ":%m9yx.衫 %#mը#dI:&h'k&8U4~4~+=莚Fkc)x'ub ԙ[V0Bsg~`RggӇ? =o2qf-uNrl6(Ñ7qE`5\pSr~[{+hutT~3) 4OFF'Syğb*{ߕp0 )n@v^w$OoHH K!2D&l$L <_G.wi@P<|$0* :*[ "8>`<l^`I Cd( 7p+!a_xHLROP[IýqWՏH@Uɹ/'b)4tsU9ts.!b>qɒ"\Hbb>{{y.~ff'OLMA[ v~ WC;9X3<梯}eP9[o&rV IDATEMa["〓I_߄hYS}BD>Ktd qW|u̎T=4W}02z(ը`UQ5ϸ\P-ԌC,q u צ@~p7l ?əﱉ + ) 9(qMaCϞ=ʕrOqhxx [,fgsHNPVorf,k5NdrGtF&|c9CO@i&`?(`l-g!&.ϙx^j6!SCm6ޝNأWM1Vb,ZJ 䀸XJ3d0>:aO+$!WUjn4+my'q(X\BSDW;밪=H{g~v*Yr800rh]%XwDaYВܑ;*0x`;clvpթ B.["reʕi뗬^4jr En@pcZD9DK| %*XQTKP3Ţp\%āV棘d;L2$4UAr 6'vx){<|XAL%}|؟/{[[ lܜ!:>q1s>oٙ~֭uDp YiD9.ƭ}֖ۺuYGG9$1|l\uVO0Tɖؼ"G4k-K9zW)4PE QM Z `*.5]#MT*F.Tu 2O㷢;&بv`tB295.bL*zS €N%C#%, @j]l@HI͊vA5F4NJKbkab׮ݳꑯяmiif3-7I{%a;, >*Jt[Z[s33^*ÄRmrW3* %[,3S]ׯ+Bi3C6M(RiDA)+:A BZLfO HfG4FQ1΂7;U8@;&Iʧڕ&r1 `t?Z,5]0x~聚xW= MG*&CILUIJT5ld!1ۅd麺[''7\޸q>-4Q⿐Oh`}Æ;W+t8R^T<9~bllNdժU:}Q, EN? K {1U~0 'FJ" *qHfE,a@0&ǂ^kBIAAJc)NAfR"YCPkhMW6N)%P?%.|jEdxH˥*L d(aIXMOV},q(27X)*{{ot?xڵlݱn]OR0$STᰎr{pll7E]fcÞUQ6教L`K^H,,m6idjq͟ @*T.hnd)Zu5 S|r栋CA'ۈҔmCP@h2C"Ϥ;ZʬfOhqWwb #;x&W 8b_I脍U*5ɦ7DoOֆ)>0jK;0{;`(wǯ!z#?2%*-.ScB-+r^'%${cVK|XRW<9 ޳J UQ0m4KȾ+:3g:,NEovbK;wuP y"˛`CFjKLit. @ a.7ͣ:gC#h r*C,]"B2B=mrk |ScyT @q4PK'l%2DP =ͪ^2Dz%L9j(W35ԉCPQЇT4!80T.jK1 L_%p|z"~mC7P"UooG__2L鿢<|#bҡCWtB>?"?\1][ f}`%7R#{ *"Ɯ0<_Z f0)#-d6]D7nؾ]?1f#wB'%Eg$6&  ٪=X߅GXZre!s2^ APeiŧ~g6 HbF\  ?酅z987FƐI.jєn{gF\{{]\P,O_6㪓|ybIEռqR3GN$!2Đn$ AI܅HrI2MC=YUF*-81O cQI̊ A',p9Ud)^ϵG5NSP#cEz 9XGx űrQ TtgmHZMH%zaE*$*yl\rS.Ѽvm(%^`N&dL )g<9" 7! ݨX׍vư%$SFoXP;ټyiKK6D&+2*9k_Ehs70g$ˉj?1?2s%`f%n70|Anyr"E f Q2wHgwfhqnC҂@JPz;a=%jP6n8L*u)z`;;ӣ@hi;ػuA=F21i;߹-/YP̣" ).eA&Hݹv" 86tv6ύ]pW0fd)sҿ.H̃;G@e܅`2YfhFq+b)=1w[GMt0ȑ^4Y)%č %EPCT(ʁ :ێ"E/g!)RPL@88Lsy&cCEcB2Ơb1AKq}EpM0p 5f | L]?ό_|粹2a]|GI0aL#" C>d/wG[}Ѝb[[.:UHA;|\\1\O&! @Sk=2OMXB`“o)(U2|Zt 9 Wcd'5 f_{YD=~xb ~n#GMIt8FmVaqš* Wb& J@JdQb kպ1%q8jzU9%6*{yͯ[5i>g9ub|`&d2 I~jgT+c}{/@CC''x/CC7\R]-Ui?M 5KJCDgEf\ f2w0JLULiP~%5.fS1T2)] J,--4_ώ*A2Lm>ͼfSzzB^GuEJ]!ږ%LqIcB1/i-z]QsPCӰV~% KB婿^yBXOܔ$]f7\sgcT nLL̯Y D &-93>7WT/8;7ngDh;;G))7N|t늅( G` zd1[m ފr2pnVYL'&@3;!;3XQIe p"bU-%$$xqd(wbƝ%){T ˡ@>( ?.0!oERhj: ŲclDr)aXJ7/==|o8%f)ыܱcc3tt4%ԱcX9fxU N핑(y|E @w@'VO_ˠWU*cUa~[$V*mnLXn 1}v@bu9ky!!T*0PTwWPu{WCnQ!{{I2ɀʃ {{[Z2T<^Cf刐BE%h}F;Jsg__FRE;\244t)/YҺjUW?* ّۖ(dmjFX +F2(׹(eL`| qq@myEi(G(IH&E<GS3„#-/866/wIhG[7|gn-،j&$!6&TOj<CfB̓VFbqbE:z7J%2-͙ 6ƦWLe |xLL-俟:5&+@!bIAmmM-/"67F{*C͙w̻ˢRN hM3s ,@c1AE fTC=U4E MBlO2Ec=~׃z)Ī^Q,2XMe(> 9/a\lcգLC;hO(Dՠzluލ".om.5{£zuک0uu5ww7ǘ*ɅS%~2Y UBHEwHmfb<<<3<:H{g;V'b3Aވ }(8QU%@"AQ%A=d:=inrPt_[zbT[(ƣÙBg=sK\#@djn9JP1~m>MC^uX1Z6lX2U_wĸ[,O~>|%5['ͻP(¹'F$I"Gm3W3ّqz戔X Vaמ`imR1[H8 U%0Om?yph&Ep{Z$ EUt=D/:%'$fhתP¥p:V[meV(pRU)U5pZQ"%IJ?b9rرk}/c6 fgis ג`Қ4XN*yU =9~nBUH%W9T u HАQC 6j:ߥ+DU5&`zj7.e>ىg=3?_jiɮY-¶!ܨwH7bDhmr,LJ#e"x׿Rt῔3Ϝt醱/1i:M4R,g`50*R8m=wgB~l*l3 ֙NdIJI;%y 3"|767]`NK%C*a\l ?bLyd2rDU[tH;@̝wyWoF w>-h'Ej?5؉ ?D`@Hf߾cKY[.`-7߼6<ok(sNm`3=dg E iFd9 HUt d`~N#`ix0d,Qe+@؞HÞh+]E.y4Ԅ)yiC)iwym 5 J5Hm[(.o4^>xJWw=xƍK+CFLpGw\p“O{ٙ\P(:=TF`ΟQ EXlUolh$˝3¨fHk\~c%|rJpl@(1JZKLh 2= BQowQ+daJVH `-˩S֍"wmAb1\nɪ՝b b D@5sLul0Csg &GiS)P[`-Kwߦ\S2%R4ޙ#Jƌ;=A<"=}KJMbˬEHXz{]EA\[+NLJK`%XqSUBdWT&CX] @[ X<9(1jI]. T@000Ҟnuͻ{Z\ l>r H7{eCF8{vɑ|56#E@Qss~e].B\2dN9h= Wj'[g0U#k]0Z1@ IBzhČZl&POr%+XːLRU鰆(Ίġ  PIf3TK?JC.:tޏ}| nP"&dL}(aܳo IDATփ1dS\"'QTyiOPGM0GA6~SKz l9GAH4!Z;BqU}/Vp:T#2"// UV$+EmgvdD;(PdQ"c#*A~}0T[tr!sAK}lSCKhP2# NHV*z"Cn _E瘨NU* Cg+ޥDt N?>L!1lг\a[o]mdVw*ҝm@:r5!Fm߶ĉɹ]tbI} ɲ͛sY̽P\X( ͔a}ի;2eGL)59e#=AF h&J0#G3&m=Ҩp?.j%Ww8SB}(#56Jw`URR0>jw5g!8TIIeP" 9HTXgg !Qww=o)ZӽM|MVwNB},iA&dx-mwy`vcG~ ݷϓni0 @X~O>y< Pqү|{i 6rk?QȉA&^(I֊4dBN6XM7r|ApKӨp)iPzI]T;*P|it&НRWpT5"Ib L5}Wpɶ8JzT-%u@d, ou͟=-͙}lC uɟܵvmġޛq]gfVf־ލN HNIEْ,ۚEPDh"y31e~,HJHepI$@@յzYU˽7ofU7@TWef+9W]!FxNj[*)_ľ}'Ο_C[nes2)øŭ[,I/>zѰ B!]c@'N&L\p4tE#ZiBrH;'ֺR4P5 pHL M 袭!VwQ!DlJB܈9"BXOJ^0N!Zn&gh9}:6)#Eab/C~:hԵ:G?{.;9Lxc0sp@(j߳ukap0u\ J<&}ç`E94f;N+wu׍]|D Q@sȶu~g,fr#OէQVN[`I؊pm~Ah7NXҁ2ğCܠrޟX`VDzS9<8ORO.oy5<.{PPrS;9сr6 PB˚,Apx!A@yORHл}w6۹ܰUUNoS*i V~i2~۳'>x~\/9=6Bp4jS5Fy\eo~f $]h[W&qƅI#cD g0Det\MYem8]XAvF0g0o?}NLd?:jOg ;|/g&HP* >-RI\*E"}@g_X'S)AUT9::P{%s}z䏍D׉1g 0B OέU UEμN?A/U!apAr0V1(㱳PZM/s'N,ɟܵ{0+FL@yiȉQ'}F*%ybCÉ :֭EpiMrpVVBM Ux ''sCN&Lo{s,-)tv @I I;L$=|bB)95;[ajBط{8elv,5oVA9@lh7z QNș p;[/>w"PfʊH|9ُ( YشVN\QӐ"@J<`%/' ȫ&EEO8(oq6 qc͓ML/XMQ7z~qC!kG+qު@a23q UQ V|_ ˡN`f޸:i`=)CS5w=i{|p2)W\ަ|䔲iX8PgcHQ$;/$bg Ed ۶J ϠU"O慎Fr L}<ջ.czBDc" B'XDUe,T0Xs3Eb30457G7]Q%񁯼`Y7?zm&pqu7d4[s$p7(bhv9 ڷ;tRJ#&~B#"a5o8CcOVok( Cfhi:?7gGjE%p=ۢZZ3*=]%2 #,;&ؼ9ķuknu3ȇg*" --GkD\|`j5"1&ؾøS8`QH ZH O||LZR5pSm!RJ@OE3Yŭ !4oz(̇-`Ih/8525\.Ts(u{sU [T[ 7ܰ)& DR9[LO_*fQd(Vr0Z.'q9/#\%MƔ“Dy9Q(zJhr,Di7bFG%!qfP Cr& 2Hnun8=:o f$!`j'͵} (s4T3.&O(5^xc1!|f~,['K<8hXM\ak'@lU70[!o^H1,̲V/pxڜU4]WvO` 660avĔN+bۙĘBtKCΡidDaXA1IlQsjB=-UGBƬ WD@@AP[_c坼PB,,rS E4(bz9O(V{pHhk^ h1 i ΁$RPT!CkPf1DEaN^.&^E}9 Ӡ!R*wY1m'Y`J?T"V%"~$ϝD (8L}X!y8C@V"~`BP[ = . = psBD$JEէOΜY ||p % b qE,i+\W^.eY1c~ Eh5@=xSmDe/ADpx!쨈39k'2z0գK{ӆ *X )|DVE'S `(!]LIR)E^4@Ӭ٪[, 7H,[jNe|9!`r*EnٯL-E yPl2mǦSeBAVD:s0{xg"Za=k!Lv ۜ܌Y*nb b)Nrn; TC>BԲi5+_yy)!ߘ >fji?EJd:Bna cQc1uzCCЀ<3 X=gѳ.>NaqL͒ndv>G Sp4=i'BUZ3AZ⎃j4]@9qTx7@E I.EPz8{lY:ur[z-g`f0:-{4 \0M~V} DQz9*x9l0m3FM#PXh!1i? דheX0q=iDAME@Kgg dm HCSS+l ]7_ĝ7DЬMvzX{B\%*_[o-9[j6u A;s+k0躩i&H V$9'KJ :Su۝t"<9:XPНJ2D HڜۼߢbOCJJPrpm@I/BQ~]=k1 {o5K-E1 Pd趁79u g#땃O5N/M}0DTe;Ѥ ȵ{hrʦWf&f+B,~eTV=41to5-UΘ\U#"9I'`־ah}r9ډ8#1B"IӢq[u̲+(- O`b1i剀" - @,&V|}lDZ"#O$~Q)r4m0H(W mVXF 8 =J8#́;#P!RJGwx\Hp~33U#<7W#x9P\rGEam(IUn5z\PLd#FH'!8hmS)f;?GmӕB &g+ܼ8ZA&Uqy3sjUkY䥔DRx #K"M@fjC( lL(TŏDlkeAHH]d+cȪʆzY7(B hk ȸ92/;azkJ-pr Ei5-mQ2Yig!aqQjl6[ѵ~zxl&P4 dDŽnl{,؁b#IQgh8p qh;(Tn< PZ4nn6׾vॗηQ@i^wD. W :ͦnL&N8!Lh4t ˱-wˑ@+߄_K{a"H re8|N.>pUH c Zp=! ١JJt{!F! t9xGE]Bȗ1L,i?= &#) }f$ }#ukU^_CZE?(mh!ɔ,K"s>M}iaZ9%es9ң+ג(G\kk'\P@@ʺohi $]khzR"sqjj'B> _[+6 a{Wi '`T, pSDBD F?T7ְz H!@HBPH83rz[-٪RB'U֝/< o{nuR#z≣[ xDBr| v4qm Umq1Ys$p9#O+8 $ev ,o$(sVch EZIbAP[+p  !Iz0ݕ6RY>9,tp(](.©0kp0o/|sr׮!G!? {ek A >"0߰{f.!L ߠ@-r5t&w9"U)Y&pf0m$rR4ٌe%c|E!Nѧ",eP3 >u!HrTpw&!S`^,&]n8cO>xt!P($Ym>?Ui6 @stѺh7 G0{u2 &$Zo1(:+|(P] B~՞Lw gFNf5BnBUwB0&0r> z=;Ν9y ioS>G0Ʈ #b!>Uj8vt>T@hb"˘Mq!UJǏhD)YzWr\6ۜۘPݸ*vUedpR? k n D4~^8X%gF"rt ![co>d?$¶^bۥަFo~" +HF(c\WXS(b(9]MNp|`ǏNkF0(H?Z"@-R\!h=A( ^7O|x\bRf 4Ywy2 f3{ IDAT˪Bc1a"Y}N z|-+(4!Vj78)Tұq`yߌ0)8\`".(a0 nFKݲ"jm8 G?43x˲]ܲ6.jwMw:ԪmdbJ{ oVkq4K W-\7'q-@q (L&^Rc)0c-)͸fkoBUVpr4 *;܁ 1{٥:ӟGoV|{vQ-ئ;_-(l/fX5<8UW!IJQ`7; \z9PT,X 'X OX18( !mln6:3e={FvP9l9! qJDixl!@, W\ FA:J$[VBMڅX#A B@ɭ*@SUk!~.^e!gB7s}sW5eT[]׵ݝVܵxqwR|ǁHZkk=u^δ>]ǓM/}@GcPviWz~r0m Gmu>w2Ņ,;9,jۦãT+Ì3b Ojbjqk s4¦"c Iܒ-ɯ~ƋLCp>k v (l\Gh;{3|W9~r< Ҵ0Oڌ|Wx wasHf;gZw^NKC1vfv9+/< }nL55Q4L9WVk)j/k=L\ΣzS.0v;@DpQPr_2ycjOڴo6;w ( Y[^g"AUzl!X %}P06yN )@ ?mMC2OrDcPbHR)W1I\!*Ԃjî%De"wϳbE#%]PВ= HX,2GSl5*zܰ7S~TVItZg˾xK'ä.A$Lyh+CK2?2qGi+np? X+fKX  6_s^FeEPfYɚ dIFB0A061!tCBeD7@8Xdqh'pY,]^޼ٕsqAi,&3o=-m$79 0oF#TO+>F(Kdd-{rUݽweDKwg>V,cpu45eB9 :A nsgn : ˳Qb9q>C Pf.2 Pȏldk|S$IBS #ԦTڃnAA*)"7&U )Xζ2&AFxR#uZxz`*z䇡x\c~xgU%v`)J #8թ<}]7Ê/[%aet#_E4qo8`/ v4╆vvµf !Txc̀±Ba68 aXqs=21o+fxK`h_%aUXTnǵfI& cV)8B+N 8A۪+ؤsuXΝJ_at=`ҢSDhH~-jjx%?8$!܁^a4"CX 2Ge\X .qVJLѥD) \$Qj0ÂڧH!xLM6KbnkC*$;NF(|||F~B#ߊu%[[F҄j2!3`",+LO ${6'ڥu+[5.Aߎ4xmTB?"׸s׫L$:p3 8ݧECkkbhů-wa#w6pQV>HO{=y[N& '!"MY8h;[.uL5ȑXe} ڝÈ ’/H,놏$؝3x4f݁Y8_vJ1dqQIZJ_Ul&[QhU3v-r ?YHuhtiQt7@EQ!q+vΫwX>*/8D`[2I{%eǐ*@-#9x;%ܗ1 1MpIku1SSUS8χNp6ɬGljBN0$m6@b0(sJ_H)a!`) d9 k+c,_ Kr/àrk!ѫS7b!BCYgK{~R@w0y]m7Xj߭ut:o@ &-9EpȾZ[}CݑhNIBpn \<~JI/`>EuξoѽHE5  "aJ=nà^$Y5r>.ԈC%  -8QRWT G΀y"3WE"v&,B˔]׫:s7GN3;!Y0ˮړE9OdscVKgY5wř .;]~xÊ.uh"t?NjYyYq[=kCװ1DG S2'dL >a?ў.5OM5&kGp_`)8+o4\ oD9 xeQjo1…} ,v1um DqaTDOo?ϥTr|!Ky`oW#D(sdEݞL$ 8]}(ePbs4arW$t"Hn60ЇoS>k0k/ Ʌ ,>pzHo]75` 0^>QiL.̵am0]|UBݹӎݮJ&/&! cpɚ|Zq|e 6nU' wσFn夥Q#i~̬< emh*UwY&#hj>np0B]ҍ9sϔ90j'3NevN4i'daaIr3N@ KwB n+Xa#w&Vt?Z?ɄPOl}/]S3)\uM~i&5Z8ϡ@!ZV5E,=z%q*fMUfuiZsS8Ef6pѸfh:X2zрMd@c`)Rj63FpK^ENr{=M7-qtfWLJN`#9ՍڈIY$?=(hT:ExAHm#R$%A9)")կ0wAm/;& iZ]bLY٘Zv5T_Kc@-ElQC96լBh"]!vR!W"mx;(  φѐG͐c=@ gǞ#BW*miӕq yVÿ7e\ݚYs g-$Z/7+Sqe7%xpeY*лR9*ӜzLNj*_ǥHM(q={%??S׹X -˹_r;c xkhwi=df@9VzCb4Q?z:_$v\':NéF͓ *1ڃ?CXc҇4MHd@oTdlUӪ>0;;7zZi'dKs؎鹭lBer 1CAzSEJ%F'I%PJ 5Q"V'Hg gCg5VO UjվB<\1RoLĐNXOGoVm3Eo<!δ?ث G2%;]`n㱉$^RH 3xj[t="MN'쪼IXȫ ,We>\ 禗e7ZM&Oek{*)Fk)@NDJ$LMPgPP8겷8,Vv CֱAhe3AYD *KW}\=͊PDλ'7gǭtf21* 7P<˧AH׃,~'E|. kUUrY{nfs/lXf -HR[L~/|UJ46䧃_Hm5+zP;:P9J];4' 6x''cw.gYSUoo,qSEk$J \1ZuF9Eمn%?y"rЄg{}H ׇfE:9ۉg*Lt=CˇT.!d՛V/lX=%#&^GlʂW߽S9Y3D0*iU=jD~_o_tʚrD~6@P{o%otR]%t!eX.4g WX%Gr bP=CEh@k/ܨ kREzo TeNW?{ᎫAQ 9of{eJÂĒtWMᤥL|ߩF̅y ~.|S6u -\FV?oG+X񐡴Yk SdlÞVnU^B'jR=^ZdW)aLQ4ڨ@=QUZuIG<[vFWHhgV|_q^wa\ѿTu?#d[))~>?Q[+ &}o} &y۟ 65V )BX M{_EPc+C܀uV1Ә6&fjsllU(b~dUn^ !4 9I&] ÉD7/Nv_$|X V< T}I]G9s*+VPP>4@Te7r灶`_<6vt ̉pqߺܶ{@^ j~k܄`'9oI^O>"t"FiavێGK.D\zDI&_eԹ4,SifTe*!g lQH"Kϊ(Ľ|=(B 9kQ`8{տѼ!5Q*p'l6lp@hFa@t,qXo84`͛wLll|&J5gw D!ʟ!Kd%pi4)*;aă(JҨ=] (* #M[|@ ˉ[9gBp׀[5i/wYލXeYVR*";q)p~$#G=VDpM(l-Τ|\<7ŴR Ml^G 1*eֱeقeACqAGJ*D"2G,R")g^"#X o%l$:] 9S@pba]*+\VXo|Q\?w狼RU~Eׯ5bjj]fӌ}z- (n0fo!>NJr'& zNQ/-DZ0ľ2s 2lڄyfmEfeZ4jV 8g1NlkJ{п)x5xWD̒wAV$dP & }%xC7oaHY-5} HtsJ8t>7%F}߃2|WZF{25y^D.39e2y̻L9x yxJI&DjV[UkT]QUisHTR T8e>+2 i~ BJoI2N`,e^W9+͎?e͛*0,KdLs\'΂K#' ˍ:shԙ.ڟ; žY4vuUhq/؂  4l ^ JPN{W>`+?X#ȧQqJ5/W(l^z\#{e ? 8gQQ!!e*`^lCFda|t*cVA3rTT RQrUF$,߿)Ns935mEFy'XU~Wpj,6B+@s|3E{'KhN$'/c2<kp5BBV?ja-wY']~eۋᅜlK-@ u}? &`}BY\ﭫԲ).,b_Z23vגuE‹ %IQ6ČQS8I~ % @Y3Ộ̔p92IJEϤ<punsK|r C$p&dDntךY"o+=LȜ/?1gП[K""YqP1$9-)}`g(X E((޴8oӫA(QUT̍SRDG~k -I")}oREJgTJL&z/YMaWicReTk !h.G>5ȮqB< 1S/~n}[ryNnHPgl15.Cg5-3|SGQKRKuШ69hWYZYpV7v%fLԘ%#&I*ZrE*R"WQq$Y{/{Qz%D׭0a;f~lo=P TXQe^-FYbΎ$U{a[\ b(UQS-*L: *yytQhySUW9V:7/?I/߿5?iBAP ![g6 ul,a,GK UWghm̼^]~ɪ8c=l\lC㱳}͕dR+$@g)bMn|*+$  t}k͐m5CVXUܪ4C~\pmÐMeڨ6P> QE 2$v ќDv,"d$2XXe*_jOh<(kŴJ忉+LI*b*ȯqeIwU]?sIpC2h=JW&H,3|  eQCBmb!_lNCml|JRXx22*3J"*,c ,jy鋕P(;QS͂ J?msƇ5lQpkI͉ F|y_@_قIH`깁.h_`d?%!~u[|33ܾ (4$3=Lw˩6t6 V='~lfc.,K}hȖVWQl~jDnFnld"O"dh6tm2V1$(⅛AL5c Vhyp5KAd4 \"ݬ̪̭\bG/Ϫ\6"b'YZgl=OZ'EGFdSe۽^0emmYKKjYDgE}ð!88˘5qTTV]p+mTةՆ=͍#\HoUD倭Vm. V<y7ts?E '!Bt>`-5HF2)G/ޠ9T> $&;uҖ@ 7(Hq4YU}3{_w.yyMu!N&)h+wdltW$FM(EKFMG ;mD/z.2^}.EcB@"c8pyͫ>GfH [蒕%A5+?|D*+'!d3& HٲE2)39RXKՖba$4Qę#;ҙ!$?#DȀDكSHdYRR8;.,]`װ t-Klf3YħㅃLJبRTs*e3Eӷj[ )-:229)-+f(B"x([Zć?$4 břtjn@dB5Äf@\r30^#IkxՆ)JW-\stmdyx ~M(I=?kxt xjAde7wE҄F@ėK-D1`'褈Ȃ۟d)[/w|Z,0: &`YKY˙GIKh~~8S x /L;*-]\z&oƍ} |H³)m>ǭz_D\ n9_ךyA0o޻1صnQEr&z%rO-=zcf rS6\ a,ZL6P4| Ǭ']Sbq&'Ӳ$%2%TgN x{\>ɇw a VH<$v?CO-,.Y˭&"K"ts4{22p (4LtpO+PgS zHDD&Ad 1 Q5=1:u@I+=#)B0>ӱuf MG]ʦVe7̓LҊr9cLEV:l%ѕ~zpNOE[FD͇ ; Ӯ)hv 77 x>~zSà z:,0Q;}rA>(15 歙9UHŖ_Cʇfޞo:]춺LjaCCxW!F=cH/D'IINpj8F; ɈVr;3 0FO6mο;"hZs2`83.ڟl HV{ s-/פʩ: $L1^LM`1E_z=ʁ۟^jJ45ɹGv+omˍn!ʆ>}<ŝ"pI 6ȶBmjm]f !HlHAAثە8 |{*rn ƽ9)uk,maG J1rK}#Oaru!$@WSLWSW5p=ym LhxE|K1IgX+ΪMcZmTH ~i,$2ш~FbE *;jTػt"!Xq uep_NrQnD߬IYWֺZ}<1'$ta2k Vm #8 :@)Ip0DM_%lk]Y2p$yk'm|lhY~m5X/]svxoZtߊaF˯x/wrB:{NNi9jr $ЗϮyϷt]ˍT]v +>/}ɉCo;T}-wvʗ%iuM 9:E{ߧVh( YQjyX^[0:>X]1eFpU`u}faݍ ʱ )4C%E$YktѩΈb*hY1yj=;Q8?ws}˔R gp`S VfN7o ?j`-I"$)a}dD=;t(7tWh(eB_N-y9%Xc/fE]/tY~$O \&LGvi%ɪzEKbnWzbzkFb.`Q)肅Ba,"ubۅy!|iA.[Ԩ<d?ҮX yz~V$ڳ"StRQ s{pu\4KM&.lkKN/k>5;/VTے=ES7T);W3g)DUzZ'2Wr4Nt*0u\m"}"gvKui6Rr~_e۵ j?̮#ǺJۛ&1N+3a@H%.H]KVm}4Ky}]-#BYFJ{-A)"e〰J7훮+a GCvt` $@j78#%c/WԴ(X·z zraԒޗ仯ҵdb BDqXQ%*R؃]FDƃJz,!vdQ>mqWÐ hXH-x;U}l $.?86{l{9ە jo~~w;E5 I=Zǻ}?mHmۯڡ9~;%fHUio?+\ny_!bVoboJ t-\siSJo/}kӞWM c=Xu KξJ{))KNОM(AF[Qz"kR 2-'/\D42M[iLqMM}}*{XM% 8 ]Jltp}yn;Z~jqH%2]SӬXRٗ3H[8zY+ 񡐧O/ Myr^" ~ ĆpyeMlg:e|fݸy"6m.evШS}=<󠊚+% 1-l˕2 LhK$,K ˳riL7p{z|Y ${?3l tGͷu5},) .T_ X 1P%'W|mwK^žb<H9 wݔe-۶Cc#cVW]Kf&c?o|CWqf(Li.ʳKOrN|u59O2 i p` ^-OmN*W/b~p=}jfό;gn5u7s݁M I@xM6Wfgɩ{%_[+`P>>??ݷpy]h{o`cD`ge%OQ`F"N눝?r"UBEx ]?ܦWu-#G䷴$rW'镻̕LKnjR͜D$LnGk9W#Ԃ酝~08h 1VOlgkק}Ybr`̉s669Um0&ށrWmJDSX?dM*smE|Z4&ޕYk ]j-xPuhGܳf;JZkZJOOR(QyD1b2Wѝ-Tlee_?ke_Q!91:G܋\kӆ> qzEb\;$۹@:bXjU&y~B+V}_LQZy0w[},ʤ sE\ŧfZ?ƈ3K_td %ƨ~nuvc^da_2/+Q+kά\מ ~i 3,?`5ڸ*\%Mw1Gv'C N.&aq}ğw)Q7jE ks"()W!q:v6'+,~T3^ firQKXJ|1s9F"~iAuOmwjTl[Ǯ͍WߜsΊYo-d4m3{5Ĵ,r}ŶM1 &sS 5:!5E I+X(Sr-DG5ݰ/Ö0;tYT_ PaŰceT^3i%(W< ns=Ѽ =.3R!j;m G/(gЉyY1aIf$+ImzH{CNڊl.l=ӗ71N](!\lӚq?@Ճb|+ӽ8&ڀ&l&\ƙf1G= <y]E_SNtVn's:0,iv:Jɑwa]\J/^n;Tee[2gݒ.`4w6u 6l@l~*;3j6r-r0`t"_ hu*;.7[1/(Ţ+A>_3EN#̀RA+2\C %ԇ}G.x.tI$ 0GOOPA˳Xy:X>%?eFoe@}agf/o 5YYpdͩBjQӧlj{oZ^>*k(͉u &*m?P^o!zL} Ue b3ccvuk~g ߡhhH 5`KBs*W^ec#R")qvϭ}) \tuF'⒗Hrx1 FOGوp†quCZ^u\DRF7aZ@ÿs$a@%4U—/ܹ -}o#`֖ 05)Q \#ݕwsbڻw޿Q8pNu !)S4HaډSҕ߉&/M<%E=3u "ī uB4&Y[/jڞl쉽R$p VNLI.vu՜^~H0;ڑ>5 $P^Sږ::T$,sF?wD.YUň&ܾWd㮖(uFA>,%Ii")уPoOesm4r(qM)&վZA>lR8-yf>HK@"+mʄ^+{: ?"yyqUcupvvv`_b5U J犿./SﭤZܑK߹\V2nґkTD)ybB׏m)1E0ϼ eW52]zl$ 'Ξz5ۈ{06>n{ [١cgb*6m>Nf)bXL1߬F^Q&474@Ń5a0ESsyQL-f.$ϝ?<9s$O#2k҂fB 3:&KH"LDV  CwZn zhhՄE]ׂQS y;/,0(C!gpMXS\',ݤ#5/ؔp2Kkkk>Æ3BP CAt^[ HG)i@7hUCOμbuu> m[[m!wB(ςv x~fė DL! )y_dpL%%zP4Yl#ZxC >5ӡٞn HY\/d[֮Fdgg5!2Et7ϒ:cv}huqWn  E"19sͬKA epQ1._ep64T7Ù +M۰Rx!Pn [LF+} &@+zm$_6BaaTO:mh?H8䢅MpW@(!Ƞd?2<,Q {F,Ԯ((ܙ)0Da@U9lO_AbM;taʮn3bY 0 d*sʦ +=(8;P :FQJ̇scVkB+1]jf'~(BPVahD =kNۯ| k}PA6?w칝&WO2+,鵪ϐ R\(/Fl4_m:Q/mMެ~lbf(m+)ih>q]«kr X&Zjr]gjVO7Hx >*\1YVOEEeNg@}Ϟ 2'7w/! yeATUi"XO?p:ʂ{J 2es7*褁G\¶N>Z8y>dD@; DKm{IVPvB1pH^^F fanEpY&+_$ )Dp44\2 "nTsfj {ڮxܝCyC 2)(o-јgHkѣ .+)lND<8;zC(p!GˤO-y&ʍ\Ⱐ/c4?_RR]'R, ?V36+3}9(γP:su>pH=ʘ(\XX͟1p<:II.8.utYK4>N/P3Ziu߽v )YT^Z0\.h474^ۋP)1Mfl.8 7drXS:ŢnT1NAL/(ԵAO,}%Hҟa[[& |G2OȀhBc}ojGBp ݝA11quL@A=5VY Qs v̥kd߮Ow$Cvqi9rctyO~ZIC#?!RXsccI |З** D f/ບv%頍zzLlJEeQgm !M޿ӱm-!zFa D(s%vS0B<׭qF(=jD>q:$^7qY 0,78ò>TZh؟ /a9Q#jB=k_|C}&$0ە]Uo3&I4<tV7ì([~[m=7q^Qɟ" Z.GȨ3!1 ں: tp%uPXA6jM)u,py`h]B"b5>MkRY D@6ƈaq,RJrQ(O]tʘU^,C6JPd;w7'ĸ)!C@8 =)nD/zZ;O"lll-ѽo@YQ]_)ijQk?*itsmkvAM_{aS4,'Sޏj"2}#h{10"•}9(/*L?9͐մ*o55{ BGmNf8Do0N t|͵N%I [+"6_A|N ɿ̟!~S̈́oР쭏 T tU5Mf5MA8{dɆ_ r>sCv| 24 M5F6}}7GfTW_kOfVWo~bu*f~BF:6|7Ɵyd)iV Wؔ7<=<^CĨЬJ(ӈjBlq'q%_l f/'<44$F\],ā9MMvR FCtK:nˏ66\7j:8҉Ux>Mr3=ZzmΚV {4ȿ7488sb3E\p@,0t-ƗZPurOq/m8C-*OƟO1TyXD^o YYlwBzJPϑi(NgUh0M+SڼglP|hOkastׯKMBt\2ڎ0‹lP7Z>Q*;C;)͔DqmnQq`hcp%y)`BzۨMm|eCPa15а:J87$JHLAG|_EQJǏ:q/hҜRRJ\@^Ŷ_{{,Du€`qJ6quRĞoMEٞ|4ѯ0@=q'YUC#i} "T38oPn,Y 7mǤ`++!{S;#;#9tS2]+A͕-1ѓKoB)Qw 2%KIIXbAR#YD}ogƛR]@ "3ÉsXEҴB#u`59["~BwWĤDl>u>uɆ^u:}yj$/c;̂6~O {=<k"sGTHHɯ6'- N![ɖ`Jы\>`+h-emXzC'4hqHaQZܿâ$_FƮw`HSuV r0h JUkk ݢ]Y&ZqLҷ餯|L{л΃ϼ@ bM 'UuA(kK16>~}+C3W;Tb98*W#`=A8I܋|Gz9`<ޏ@r%ӃHU4Q\7SSbԕМ=wbuO@Ϊ( VGKN+ك#?w#TlrBPQBN]G1d݇rQ (_5c'uowxR?_TޛW d[I?%=3>%5Cѣxȭެߦ*Rd+%7Fm{#bhnhh=x?b,Q(E/!R37O;EI)..*ŅqGL&׹MD7%(ǁdм5 d7HV\Ѻ4;Ͱ+8hMӏΠ>x b@X7ƌĮ[1n 2o5eX\ i! ,'E{no(w;WU +5cM/;zUpayBz9tr]dٶ.BCB!+SllGm@FÑך( r# iQh%ϊhB)ܗޕ)pw x/wmX@g{F, 4 8/+Hw~p2:jΏ[V}E52՚ â\ۓo6WWyxKXXJ{Aeo,!"k}6Gib;e7qwgC" BjSˬGGԲhl-&bNcHJ몚h#}BrQcs}J~GVyU?6m Ƀs'CGجes^xyumepv;`P|m: _߼TuL\ B\(g俺Qg8!u<1f-v rFTgFgc E7nX!ȱawEX7hMYV`/hMKˌ04OOI:RTwТ ;=NvXe1jhHUX|˗L?*5w!G kӛkkJnƆ,oJ⩙9C)*i43!VHEO(Q9dW *ȁY>[i;r0c]4:sl8L@᧿٬ Pm1 ʠΜyZ#C&Tty_Ad85-IvvvpL|`_lOwؼtbGByllGMAUf6@n򙴠gٜ454+,+J^Ϊ)ވ{;)iqKNcf@I"#GSwv+YDXYB[tdbچ꣏=7QTTtw(w+@sG05n]ׄFhUɩ dH頍²RVm#^by߿ߛO/j1t~!R/SuZEXK`\n lMLh +j lrH݆u'%.nZyzv(uyN9lѧ9XSz*7:d#4ڿ*iln\汚,Ci *G*$T:,G6`MV*A+`-wIV:ewuΓS@`v` <8Q6UՍl: *Bsm d sVOg3Z!oH(HT6)FKOm7+89ٜ_7pKG)jC2Rl5C <*~dp*oK@|H#O,riYOGG?\@,n%2Żʋ¬.մCڅ퐤PY ^=V[ю!&HoG}{*n &Y3 -J%662βXdH_P*Y YGޢ<9+eB6vt8䓁.~aDOfMS6`_ܰ7!o$9gL u!B"PwyTJm;aTQǴi:Jb[YHC=&UG8~X^ǫoΕ[᳁Y;D"/~Z ǷcU" \JKrz:x8Ni9gp 4B *IEw28K:wTQ!ͦ@cdS Db"GX5Mmʨv/Q8BM-:'Fd\׫l ?>I_bsbÚgn+J;kd͹g\ \* {sCG)<(G>{O{ɣ܉,#CT5SWἥeKFV6L|ԉٻ6uؤP^^^->?Yش}.8"^Շn0Tɯ}J$(:\¡{J[[;,w(ŋ%$$}\/ZC~kmU'b8tKwe' E 2YdaaQLm??22bAT!C@@"1 -& tuyQ-{ugj+f)?6CU1i~L5ӟi>?xsvJM(t£ʀp!!,ǔEl:7mPa iO/~q=ڼ6.3ܠH5w+;h@-;RD|Ywp;-c4.Oۡas=0g5 5&SIL``| % ҢKsL jiIIIȓ\c]@@P~=ɽ9m[MTl1R_wFZ!R}BGFR҉rr`"u/! ᙝN6%7ӝr 7ǃB===ko<4[lk,GSRR0c  <FF,/)fHRvpp͗IUKH\>41aIf?cEoO>(.:Ws }17gfg dVhyK<_bH'~_l$3^ߎHy!;5`,##o}Fj.131cO$5g>וmx͛SXzBQ&-Q9dze'hxu{y;uDܒ9|_XThaڸ8GDf]2Nf}eٓ'Of]PUSRZԨnx"-r8FAA1_Jr;EvviVwCSS=w ]_sᷓiowsߡ o}&rKiLDcX>;vv߿ ל?rIM{c|My111ԧNgzjń))c]_,h8|HBsÇނ•AO#Y~epڵ,IF ~ >H8ԜUܻwOEy2{̙'#GG-5KJJBG6θCۚw^BX %oiGd!'WVut"ttX'9{9h&xT׫kaپD3<ˉ"|+6Aj:zV]gUT'VXpe/y~ه1&&9&|(k{ D9W5 PSܳӟ:;շsiii~Ttz`K),' 2N%с r+'gܼ6AĨ'iyz'߁t9u]̽{o߿vWT\<5zitAAuBCURXtgf}OY dd޾a\`5*4/@I voU[pt\\b[Cm,|v:$44\+Y1ߒz iQ st%M+o]cC'>=#2z>Z_/ @f)A ݙ]X> ~ .hy | ׍jhh2-q -:k,@a\_%D_Wq~^ x1j(7"6vs} ǃ18EMq)^Bdd999P>l3VDg1Ů?oXF*g"{X厯x~}y3(Jسm_?YG]==u Gsw] @Z7x&xPs?(ͤ|+$OOIW2=.6ןk/V=vBnÔ3H^ң?ژSQq@16PH2﹯v^{xՠ(s7ÇAOF%nc? k$Tmӏ8޼Im߄PʞʋU%"I!9/ռ {î?F<:t5B/66kFM$yFb*L+zp5ҩg9 =# h:߳ϟv#"sdǽ0b2';cxrUQ 'pA42 j]JHSbwd{{Q? C!Ʒj9"y3Q. u|nʋ t8X>?whggUx^P.]+oLLMɓ""K.Dq U,C0T U(ǁ/=!6tB#Soo{e`˗,MlJ⬕^Ѿe**P> .o݇+Mc}|||gufܰ~KJRa+}2ॏb|FGϟ?RSS gi6'kQ<0z\pU'yݭBxLcs6F :mIRTՇ ~ fatԉӧ+'V]Ğ Y N)1UU褧UqHz&꼈=`0oCB@|! ZSxZOGc?w 9UOR3EOT2ddjϠ' HLSZq(0x ut08fè")R۷OXE4P/A`cq쌈u/(Ii$`oh@_TXYm>$DsLV(?E4NsYEmU Yށ:CP@f#m_Fi8.W>ʋYN*u0 4ևǙEZi9ruyw:&>xeHĊT{[[gg՞BW8O3_d_b/F]W__huC@` qZ\ֺ֝k|Y<>$c``T#8˫>31!IM:.]#ˊXW.c`w68O&Z큰2)9-5`vFZ** 8L\{ElNΑK<<:`OֿnǓqppky#++[*%:v!0/?}U\YnjjcrrrwHjB;ܗdFVq.NiAOl\.PYܫO{Wkۆjg~뉽{BS1%:e! >Ҡ㲏U'.wiX?/@' 70 ލuNuuu /ȁA| 2D_`{(ii}++ۧ; QOw sWG85p]#O>%Pt]!A8s),>Ʈ1BBd{g5o :a K`OiVzt4XҒb4uY2/3 <؄߉!Fm/15Od>\?흼Q17vV*vHd !gj꫒Q50 //hN I|D]N?]hmTVy-.Nu͕#d"[]]= i\\\Uϧy&?6Wwvn&VxJ ((8(jbb'".3@,s"o&@:^2i?Pdx;DC@l --/q]+@_PNď͇GFBeav>)-{YU #1*30kf2W>LDT/5`dcapͧ AA.=ldÝo:+4l`k:sz࡚"x=д ߤx/Sn[S:Vպl,% gygl =έuk>5&8vis=Rf0hyd!Dӕgz&AB:oSb"kÿ~50&>:ʺk[lXX8kjiiϩ)JE%&8(z^Fm+z'jK9Ж̊Ȼ1_ܔm.'Mxq?r  4~sJ4JT#|2YL &)æk#Y)0eq'7%#am9R7^ MiȬLJu햨(>а0.S1;$ݽu*MUE,]S4@ט0y R!7bž%g\#ܣ=P/X7,>Rj?>LyI ?KdLv>LBB ;99bffM]v -޸sz/^,𷺛g_%?#lOity6;;;j,8N~F C>}DփoY55"D^UhwT1[^Ee?|1DIDo޼Qt_F=V#{ ?~g&EIQl_x[r(\WJXfpV|DZ ^Dhi-|,G &bz·?+8sMt4btEmF船;3Uń-,,^fr32:M]!Nvvv9$닓^l2 ĀD(5e@0ϝ;$0l…S ^SR= gCHpa:ksI#?OFy& ֥PFgY^D BtUƉF C3&ki-K:^ᘈiJs0">me ;pw:L@|)+86EsUMiwn"ɻv+E„ (р57p?݀@L;X(!D$EcR%KX%3LLLս%M@fztAa:I迺<ԘadIW>}$F-$Wtp(}?u48kK8s;:V~yЩQw)w! $2]9ծOM 辰%i vSR1P5uP2),iE+|/_~6.㶳(ӆ*63/m d<nX_I rS3JfA^1@To^GFFF}4JIIk0Pѡ @ۻ/{D@"8b?YV\ 1 ղՍ=g+=###s̴y yz T0 "!! ^+8v,e{S;Ksٲ*h $QlIG/@K>!OzLUF.5o]zg?|<R50wall q&Clğ[W3nxdV-ndx.#yJs\nWKm'C+ٳ8+..ɕM^hm]֦ O4}UIa~F.@%ϥxA wivay રclB*F׀^0Q5Vr]R͍nt[+`mn=T. ~tE/ߦ\+pZtPAb i uz5ip/థþEI l~bXĐHvd"j᫛(#z8 xR15X7ȭC]]T^|!_G v5ͅ7hAIw6Dž`#BDGYo! )MwXc5 yByG3rĖVVU_.O9)XJSԴW*!^zZS='tv|NҚYߙzr?ǐStFG f'PA) ,Q>[Am{ki`65dۍ41\Kd= =^u3A$N_rHJv/OwgS_5^W; t8ң[BBBB/p6Ff~_\ً_7Rm @x=xʋ^TMG~JAv+;[sn#aQOړR*;.Q 60+-+C# KJjzS23qSoaRfo;ܗcM-o6e g ܣj$V ðm%ztLJױG2[0`pۤ@/Փƛkhq /zڿRǗ.ͯݘ RRVFBbn%(<pӻ( Dr}]1wRX4ʓm*)+*tk'244t't[_ @4gÍ VâFGQ#%=C##{P9+/<#ƒ uYl"bk%|Y19<@GLl?}RMw<(GM?.,,oI5Se9 ]Dge#7+ ]mNy'RϋU?#iꙗ qQFJ71lqJg[u/Hs &&VwNAļf3F&G S7|D__5ۚ :dHW2f/য়џܸdۭtԌ'_HW! rbpBJJ p UUx*%<{}*)|SSSW%ee_ qcm} զ"e;=PNqF(b;oGMk~.S;I.NvAǔQlxrR]/KS,7:br??$)]X~%a 8"v[N$ꭶyoW]T4-vBOgdo:Y}=1!'ǻ!< [ /j%TJVO# Aw>}b zK^v_q JJJwJ%~Y\\9IG4"9g|Zv)%?ysNz(yڥFʍ;ܖR`UH߿0c:K`F]t33 FRG5&?5FmA&XX7k<'?>܅  _P!t5d]VfƨrڌI ===_ÉДQΌgy/ VM;']c,<+Xʳ/ԑ'[d vXiӰ?:a~fX11 K?%ӯ>JFScuwv~"/ /ن=nsk[%vG mAxy!)kCao`sBӄMvlw jrro9꽀tJ%>{+SB\bG3=3II-n ~iǚ:W֗" r8NBBDRuPԗ]'#4хt8! 5>}Zr8IcOi )U龾_ `9ss$ Fv_wd Byy!E6>bqW{n>FFNNs `}AcKQP MNKO8A&H/x&);i;T{]"E 3vg[6r}JD}bxx她gb;v;ҴJC\C CQp(SFUr?HȪQ LG7t7׀S4=ֽ/^"V ПI &e5"!C/p~|wE{%@ƣF8|L Ib9W ()8p8D89"_A^ H4%vlw&6GjȄۓ-v?hy,j`(ST}{53dRoت BR=ǣ"ϡݵ 64 Cxa5_%z~ X{&ȼCRI?{K_UU} 4n .@wyLSX3,cЧ]"U^vM8bbP]K ;RUI_Ti>Sҟ jJ/kݽ[SW6,mE3E1  &}ucmfW,Ri/j_s,T9_`vԏsjeV!Ͻ/\*>AĠ>/EF?K)ϳT[N>)zi qT߭yhw9ÁhTb^ˬ;[Wg4VP]:Lwosb ~HvI "{\am MP[N#?{xAwԲ Q3RE8 {ĖHL͜ ?{}kՙKCdnIPqԄ?>HvyNӈ=u4muډ3-Fiu?-[̌ 8jhITӋ`e+*Lҡp[ls n>xÃnZtc'Igd$]t/ٳEKD>}dmZdagD"hJDf"9SKc}*`Svu yhӧOeHɹ cy|s@tY ړk[J\^oa[ }?2I4)P^&A_ىDs%,㵔a?Sr Q7Ҩxrhf&=D'[\Ak!(;MWfCG`E\ll,!v9stlcaa0!!!\8U5P`A,k FYc+^PYW` ^}-fV&`ξZeN.?EPf0Fjz'$?jNB )8 0[9UkwPDNSMx'hAO,)@ՆR1h83lԡ9> ;S[_~H^^{=%%WZKP=0 Y[s؛?mb,8*bUWD1~t[pp 0k&ȁ,skZ#Eyڥ^6crn a9Vyu|\ش3[Vk W1T~N)'t8f͛Q IAҿHgp٫z_o qEb/O_|YT\\ bCLigegq!Olvƪ3[O\M]=mg;n䟻9?. ZUE,ruBI6`ɵ-ѶD}ԆVd X1]`nkk3, ^0^WM0lPS G֊j48D즽ly˯NNNR_<> 2+4,Դ[,75L-׃u70)-= X QEPeN&Trye86{݃Κ?B6i?vqăUmmzlB*AxjЕB K77cbq] {.|XS[\TDRea^C߱qpa1w93a$#fi7_Hfrq{c3)xχ6xf5`sO>0|9r6Wn~[ j$^lU¹[\tSơэ_wˉmllPʜzXU?@ySS<j|57:18P-XEt֢3>j=À4Hckeee ,PRkj)T}&3Wsn ll;vr~8 4c2jV'pu+di*÷:8X1O$E Ǐ^&nA=(S Ɨ^fz1O˜t}k Q}mFDF1bwDm]Pd[nyZULB!QApɊ?: "!T3  9u?Vβr>ȷ'Z`i;owˆq@"$6]k_](xxT=)0ߑ51Sz (%kJ2wɪ?cW<i|y b0)V^WH4[(_%$~B۫gaM5? 0xȥ'2Vr?+^U?Q&DFpH,0Jʣ-~Nc`eekbq& rO}۷Sii 0 jc7/.-{l:2qǵPRj?3pUL9̑uisOsw)Պg,,,P DsSҎkNj̝`~j[AUh/[vd~Rap 53zueDZ^9to3||4/_ _1BzD>>-G׀GA¿33Ku;t7 mdyw0B|aG Ҫ<"zq(ϩW_C͗=wRAMT̊ .+e8^G?SG11dX\ %E62Jf?b1SmgL&>-) @^w ,K`)ž qĊl&yW]2^#WE NadTPR:{EBaTfd?`@{ b ƯL7BIvzPjSqJ*Z&V2 xku^Lf=Tf{lz pvYJ1p./_`P~g \@~9:rԹődEyL0W0Lq蕩fu?KИ,̶KZBfw| ބRRȫ"`r4D~)z^kl&e=$,evv~nlrodeggJJJe3y5}z] J1'_A50##z^Q>=0Ioy&r-~Ҙvh4n;YbC]&HќG ρ0|jVsUW.GoǶ:BԓMl///6cǭ6 -n`m+S34T5~\J5mAjЦ[Ê .0_C^PNGocNNu 1Eb!z7 qV[+|{^6V/jo?k"v;7~*CuC:“'OqaѴLA$yBaJ.w4~@L],oSWQab//Ou[I)Hisoʍh?Tj]Moݺ5<9ɢ#BYuKKÇ߿.>K5QE̻ r:ۿ 3Х|GIOZ/MWlevi%+2=ơɟdw°W:.k)M, "(0tݞI"8Mρ3|N@x6+iOmƴx]-}cy]M9/c֧`|uv-' `4h,S2D "ƊTTFSSU_oc)5g8 j:)A-6<:vLע~(*>>>h:CBa͂]ZA~Z`zں؄9vw 1IHᡵuq Bv3ZyBCjS_LΗ~t]VV`{zyy_ط&'zp]]]s<@wQBKco.~COP㚝 ҳMu4=wމσzN<5yhU4|N#w`H91&o)e|KOLL:a?-!+{_㪍!=O.#8{ܹsNĈuu"nLeZ~KbѴد_[XS3~g&H-Y`1 (nc6D ;w^X5~Xߎ~Ԯ^-VjBB4$( D Og{dCwiPL qqq$d9.wqptk@:nv-%r/pt)sx.W^гN;ؔgUKMe+ڤWIExBN@7[ޘC&$f> !rcb q\VQ.3]7O 8@*(౿&_'NqCWOVDsX^3u, u PJ֥X0~?1QaMU5Ch0qwh;rMssf4 PJʾ݌='w_% &[wɘdA@N ҃.=@BRkU:l>H1 V#ظơ *X?h(,oOX. 2(×ص7q$ _Gd,cЙaQUUQ[ ֗FɉE5Hħ>#K\Pz3Y7Dp4QuPI:9F(:,pծu!uuujNQ16f0B=e55>;E o:vMמ O@L^H`*r"=H 翎1YyrM.bMaѷ]6lzKGꚚ"]w5Y~'<ϝ'++;v(%4@-6.Յʠ ?@Jz-Zt~ܘ[%@z ~cqDO?w9t}u#+'ClJ8YoP21pج,3/Q.zPB}د_9{legggiytet*xz_ <}ss9)x+?V#-W~Go!GfЍzı~**"0}(B^1"gccJLjPJo7BV| ] E(qsub~,9?T[M>$& 2T2gJ4U3jLmXk?N_u@ jO h$lf7@inN4KA]f-NqWh$΃տ8P0C~~222Ϯ_/1`0 3~|ux L@:nm%D14\hfm0Ĉ8Ùa~=,->-#3D?Px$@4-+T1~vZe v5N15-9/E&#  DUllPknp 22 q1*殊ch&賢&44n~m=*{r9"JkB;`^f:\ʛ.\8zS] o)ۂﰳ7t"|YӜ(ftuX'¯ ӡ 0ab[,Ϡp4} ]a.~mw)yC7aUbԿ".BG, >DXqd Ԋϩ<|됐dBe+bse x𨉖-@1Ƿ%$`E=]F}CQݯWL>0H+kk.K9eZ|!c?(3@?S,L"={D ؋7sTÊ٩Yh:sFhZt 024 ':t͍|sTBaŋɔhPD{ۋjzA.|:p^TƋXB >QijjB#MQ [CއjؤL d)NPeHsn/h_ v@"pmdxx U;q{۩NTMW48q39d1 e c(Pc/qggg^">5`%\Rg Yú ' a}} KKPMfzq,pa7u٦20wfo=EQ>;?,f3 T0p^@ϑ\7^Jff0NǿT?'.*&Omm >ItI\Y]]/58^u38(]S#wQ ^xקfb-o!y1?ڿ^FDJ``]ohfsGsh e~E9:RbPj;s售qF'dCIGSQJ~-~smu0Oҫ'EXYY!,LSQMӝ \4 .8gqQc@ÁTTTxL;NѐoDiY#UU(TeЫKsGX[3D=ƄkvSZAuGxmR͍T/(†:KHx+lG`'*<`k0Pl&$jJ<K*[IraH_4ڳOH<2nBYTZz:ka]u:1bRR( SA/@sG77EvLg[: &٢m1YF4ZuNzޔ#s_"\ȏyv{ch}vI߸F8zk9zٮ}EFʭ)ƕx{ݯ[k[n2⵾;+ As.3?zy40i1g>E2Syxxttlʾ:ة1_GS)ʈ}+"4- ;}ƃ )/ymJZRz*SO7'nKIՠL^%c ^[_'Ĭmld|c#"Nbº5yS=~R%݃R@c9*2Ru `? U>be^u d?qL֕~.j 3q.S>.J׳xE [KUΤM5|{L3ѻ{JQRz]hbif ЭT7aS%/m E-*w0\¹^@ma?shx37\}Eل$t쿖2y:dd.ktra6Vf/O1i%)8Er]9'7Y\AdN =nI22㇑˓03: bS˪zuia54_WC{Ʋѷ֣Qw55DD{+67ys۷{Z4nMo!¤E1.vGE%aBOADzݶQ$v$z$ӽpI) Dے[+d CCE聳?_a:1GMIyM_&&;%3,/Xcr{r&ff(jC״N(qJK4VԦ_\s{gu8sfX JwVZdvQɶs6be:aҢ+zj,959P>^t> v~+^)cvG >Q o4$$$MDExC'> xl/zOH(̜hkEע@18LV X A;LB޼iå02Br{*,'_zٔk=R%v2т?m)!C(VnF/o!X/((H9o :e AXT:~"yZD\X_LJnsxN:0sh HHHNM'=HIxh'q ÷ހMiaxsA<)`]рnPohÄ))~g>V|xܞeqQ7h~_>M@@pԔ4ړε!=ID=:jhhHLBhGD{W9˿V Rl2fڕn!<01 C5lD$hwTu\%111C%idvqZH܎R}[[bwϟpi?AVsV=Hι?Ώ0iRUҿrCȆ!| YVNyhBe߯')iT^> /cln&S4=s-.%Kͺg/26Ttt ;\kjCƲF,C_g_rMd֝ҭ {Ȯ k a䂃h{5NI\ {MIy'}΄O Reπ+coϞÎp>֥)888P}η5U4+ĹֶVF&'gfʍ }Zp|&:׍C؛sn?&.1jmdf>2y觶Mf&~(#}aˋ #(_AsiawT8ʼnw=]l.& "D64TS -1@i[@%ZoʡM;*IiE϶F 걭59 ̘~(> ar 4Fo;bfaaƦ&E1 qn`!g',fA2g^8\?Wm}}liIԆtskxM}}}i8p+t{ z R3BE!O1*( _40s鮤ۃ'":s쇪п^I Hꞹ`Q%"9p)N9w77׬pVqPnhLE #h\ivEm3QhmY~c5To'DhkrX9d9Q䭎 yy< B7E/)=ŕ#q[Tߋ\ vT$ R(IHE*c"!2Fd IJLy*Q33guw?gk8ϵckB:&V:&M[Ou=7͡+/AȄz ;XX~~2\L@IŌ{CdT)3Amg%ǨɯGDhdl&Pk8WBB6Pݳzuzxwȑ#oj ZV YT*|s335nj*X֯.Y=ʙd7jCw;:VT頣D<<<ˣܱ:|߿ΙGEFEnP)6W5 ᘖlJ?U (ZOq{VQ0q%u( #->}Jx {q e v\3} 6˟)Q7" 9\qbEV<^([{XR" s;S`C=}ph)9Z|ps9StLhÆĮ̗u`vP "HX[8816Zb]?Ibt^uޫD PW~ Ua [s[[/`_fޮ{ Ppz(eZ51J7_o;]{| <FsdV2Yݟ:Z 6x"k}mT80WAxǠd3Ǐuxcj~y*?/k\Ҫ,?~I]]VghwmٲSGʑ#D.͖-;D54EGqC+l;XYy)6RhhhLfՅ\1 %5Ҫ΢:yXyw, kwfv,1M\ߩs9O-+^n_i.)z?4-99ؠk!((xMۘ~;B3OQ` 3#UJ! hb=Y;Cr}]p`Jj*Aǡ]3(%e;M6A%)#?vI'Atzi"sCpV=9Opfν{%|EUVХLDe쉓̀X0 խyyUyAM|u~~~lkF" OX^gw2<>Ŵo޿/ Amh9>n/]ǿ"biv?b*[i0UX8 {;I'+OU.j֒SN}9'_MK#llb$$ż's)IBWsg-{V/:2i2HB B7|e$l223326_CmQ@߼#:Xg(*,cz:%qT V]- v("r;ImWTV>%˗ 0 Qk jTcMufWt"V#ޞlTCU}3N~`wlsReiXdDvvvHfa\NpyS"3&:gŷod]"dbܻ |1mIETZXY1c⦉hsa͛7a3c_1i[<#N o.u:\DsxV/ (Ν=CVo25Wԇ[{p8K+ɍeVoeK dEWl:9>H!-}&].&&jD G=9uM@}g9w"kr &n zլ a,Cs 6dy=mULu?.2Jd. kinn(%iϨz˗nF#cƲHjjͻ9ɷwNX+j9\A$2]2 G4]x.@IIY@m̧߯8R|B9 ;wnǎ]3>~ 5x-z$&ggԒ&:5h ,EێHQTZtYMkÞ{#y삂jBɺ:I!k5T\1jSiX˲-2,ݹlotede<ῶ ߇. ?g.H4YYYA|/ ػo6~i6l"Qgxh_۶%N18s}+^WF>7NJ(vXeddDU*&ak. [ޗZwK˟g'<`KGnR?p q X5ϝƯ5}ccnxO1JQFy،`}S) ѓ-ͭWVV4^ +YZZ:TPPX9y;gcGG42Y7::z/Ѿo/P^^քx,6D+ajR@|}즯\,}/O^N,LWuA(\_ƑyjƓkl; f-ᐙ`zZ܈Iw}*IV#۳.sve-E%f>hvVTtvfm bz~$|yXׯ_[G+8vyw2V `fjj }WX?e?ÇXf" ɇ);6URnC 4ʁx}:!3=GPG_Pe' PԩSoMTA^"dؖSgbbb[sὡF}2L>Lm?~.r̬#'mGIjq##8AYנKR>}{ld?#{ TXprB?h0%CliuҔ8q@E66KHRI:Lұm`i(ޟۥ޽648$\%g "JTu2fW }UhjPiJR+CH--ަb\lBll}JrP'uXU@J p^ROzc3*B^R[n  @k*7y:FN#HYZә[3ƞ?A4[&ě4eNX"(ںpر+梗uIOêtA$]}Έh!Hܦf*y< O@7%w~|l%O i#<ek gF#[\\7l8>6  ;YuQitr85i!VE X^ *Wz[zӐz!5NJ NWΰ'zYq/<ܷZl8f?cxb t 5sFĉNwWgSiDž8h~Dy ?k݃[ٮi``{ [0Y[E9 E͓K:ViWUR?ľ#G* 0@O:/tw`LQ=Kl=BZ r*E/:U tBJҾ%BaV" I(ֳg5db/Vy<Ƃ#IyyLp|XH-KY|K'%;EZ}#@QHJL1MPv 铈6=}&YX{  hܨu-9Q;Qhܹ[fB(8jwҚaeYRHNYmS">kM7~rd||߲ҷj*񧔣6N[{3,Y8x5ÔЛ̷/++#g/.~u~}N^=((8]Aތ2 BlJLLH-ۑc\\ϛHv0Ν߯2%н_~S5.^8~SNnHA6JĴwޟ=(7`nǎk+ͰV:r3.N T a]͟4P_UfffqG2W";⍤s/"ޜ{\RSV§N]Ae]9w]>yDyaKiZbە>701 2 \eʀ,3:z(m:pg<'| \i^"g)ZZXX젡yI_ p ٌt&WVM~ i1lv[ ;2f`9?9i8.@ ILF&cǟ5t\lKy@kW9C^ȋt, pv&80 l'_x ^"%']D0$s)9R Ttnٌ9 '(hvxޓ+`b(H۞t() uAEI)KY]Gs΍YGnŖr0pL?\Tj|^OR]N(ݻtc5=|( ޼)L3;ڪCI 9iIF`"}cIs'{P_4'W݃Oc$~xM~̹wټCPSR8f{eݾV⑴0!$f"y(S Km w+*Q)=\j cWXg&{#r#Z ```q" 1AN/in?"[Ӯf["+Z\~">qeAyn4#9/!m m {۩y}.TS~fubI$o>v{_)<<<9=ߎyBcttNyW$nO2Vc_9 67h+{!פrcE12ȣm qqq!?" rp{d.{ Ֆ-_z";8q8чV\307r?D.[*MF/I޸hJv a)v.狧ac<.-=hڀ6PRUSej3{}V@ԁRSmlhhhaq0nC0 jxMЊ<94tm<1*VPOrIBN DgCQ飼]Dď$B0AsW.],=dZ\[^tc4z[14VWM#~ylys]L163`(rzYqL5ThdE."`Y>4N@yDh5]R oSEwnnnEyJ޹!}F-zNݼ;q5rYv~~EHGz{~|c!zڥC555=[ &z[TVV-nݺm:):3--kW_ֺ$$$~n5LAͲE8X:ML$.^vbhM&۷R&m10Mob?i#cbuZC2AfTe%H7{JJEuF[>_6PLȘfYufZy]"z.ry{.6Unbr7| b70FSST9mҺ~m>܌vc6E "**PG9))@܈}iD( ;B=Nu@tfB!rBD{#ey|LtttmpVVVa3 C=kh"%i:=b0`a=j޼mF) Q/d8,"qV@o޼1bƞ0~kjC$ݢ3bV t0a}Q_U 7ݱ2 mnoތ\:iv ,|jy`` }! +nEW(Տ㍄<(O34ے}7qrZ7b=@ʪV\"듦kyQ)OCM $JJ6W^EJ52L&''Kv@d##+gHvVӼGȱ2Vjnn&^2[.7jIZ'Yj(&׏k,- F V؀^jְ4x̀jab2`snmF%SHH)Wh/t*l`%o(Mg1؉G+\Q!+YMHhÇu [#u~eyta]<pul8^7ne۲-0*yFpPu`@h^XZb;s V.xt61#΢v&:"4? (̿A8GEEUOW~ :I%Pql%!rxyxCu|v*tzUrV4O*ՠ~E7n%'0uW`Uee0w|.1NMMQgxfXQ ;EBu( HRmhq`m)((PߞW{fRͽ{OK]aNQ jQFŘX+/A$u놪ϟ)~9,!D6A13`doG+[v~keHVU:bOݹa̝~[o9E.A|CM`Op(-pXXʷFQ$V%: -AӧO b ='@TE[+\̮<%3T BՄAybevHdNUHOMIL .c^^^4;>>^rB6Lg~R0dڻw'OR"?~ѣG ^x @LKӗ+k317$|ґkE/߿x+R<a%, =oͺ qK  -OP6Fxat@҃WIKAFz/"!»P ٚpQ-3q S5T%*;"q))oVJpO&*Ё)?)7ԃ(\֍}#4ƳoB54UH7` w( 4f甖@`9FXc_Cj2:@4m7z^ѡHҷIAܫDZ7*)+WZJQaW%4e.=ċ]؏4("R,KrY^  A(S:r]Uo{gAN87b/<xCE}ը5{'MXZg&6tP!@xnIW\ىsݮ{;tTf.&%q MތxQ"yoB *s]gND+#r&Sw`J{CQ0[r!&RRPd"lZ\kill\"YYL25 PͻRNQVUIJIm}wSK zDPSSD\D_nEMMAwf\ƹsd(o޲%ʹTv"xHKy l hggǠ"X<ƭT7E݅IfϜ9<((*+<<#IC&? ڵkRbh_'M4")u(ȼ;R岕 Glq%]] w 9Ӳ4*o2 v/xĵ|J#}3</ڳ# `s5H\]G+WhpDCAvaaL#Tx6= `1̏=<"{i1ƪpbBs??ԧ*'Ў(O rPquZ"\AX.vvJlo^1%3gU~)~F M #R';C{yoLIIɤ#Gedζ_k [FF[XR'{с Qm\AI̩TsJƺC=In˙Y(|͐js JaȻ"j}p(O>MJ0>[tsʽhIN,-4&GӳKóLuuuq~屛[CN̍wsp3AIIsK#W}z1%wčpJA@ |G{kҬRzh3zy0 gv3#bwzK2𔔔Ǐ[vƿOfIH7VCoںn]O@D'pҢ}}sȼ,2xӠbQVn ,n亍9P!O 5`:yTP;~- =}5pU BT9w<(hAVun}{BG;tkQOZ8A]r Pwi^sCaOIYܜ5@~ vӉuFR]llq,PæR+JM{O7y%hs-:gy7oFU,Ʃ% i=G w%]9n~v d m?p!"v;Е/V%#.T7?́`O1%+WFF=k)z`'/ɓaZFd%n8:#ݏ"9vSZ(zfZ[[p-Ʈݍ貲oDJ/,lt" w|ƴLahdwűOD^j>$÷hO'"t#lܓ>,}}zT}<Ĵ6TtWBgxkzuk+b = ׇsrbin6|KBne𬬮djݍi阘j{n+' aldFAȢh ECJS\R:U},.@ŊO'㦓>**|5ј꒑Q)TR 3VFOq~P޽oprR :G!C}_Pz5zss' 03Yi[ vd]4WUs,gc2SS^hc WU/FN-ZL2 ϢPTg<2/v>Ğ{$s|)>=6*ަ,T ޤ52G4sE ?c=vpjrZIY[g%.]"4W:X_T v LYX뷸.zKQTR6/|ݒau#N O7pf )`6I[{$l"!QR]-hi0: y ،C"\`]FF <똊ʝ{^Z,=iN=:uEV$:zcn'''4066v® Yayt>,YgsUBySIYYEϒs)cK Al XX@.=x'ntiBm 9>Ȓz_gaB{@tX 7xaW!J7՛_뭉^ l\2Rw`b5]EeѸq؉r̙HĈ1/F0,ܶMAARi-66/Odqq0KY#<<_o$돎8^lx nnn}]Mϋ k??N~ԇYc| >=6A!III|04ؿRs= qxrBVemRRYDbbbP|y|jjjk\"ⶑ Pу36\ei&IP1BvH>=3]ZG*Yk,!V$   ѮYѧ@vmqR䦣g* `2b.@}'&#n*>4YJ nMNaP!Ψuh]o= ܥx8.zz@.%ި$(Ԝs-R7rݥ"%\M H_ 8(qީsA|i.qʨj]˖[5iN|&bǏW^ g/H8p!ȇ(*gam =##c7B/+tah.2]7fg;GBVnn ]Җ Hh8)aA &vqpJyY3t:xOEDEvK7fݴ;մ B ñY󲬨ojϾ xC@2чii-,-w)/oΎ.vɑ/ɡJ? " q46pLjsKӧOQXJJ*F#6Nj/j JslF7!/ Xbgo z _a$i.MEYק Ipu>ݰ&ⓣbfjnk>"3џL*,ԃcOuζ~B.R9=Į'Qp8ċF!$6mhБcU^~~[Mkʙ8 _ocBDzjjXHKyVp嵦MJӠT;wVO@0꼢T['^Q7m?goW=z႒hЊ֣fd^9[X^F&6~+pߖԵXl3<F3ү6׳[:z4u-W+Ds[[9ظp Gz;v,0b}+j".PcQ:f=z?E`߿dC_ܺ::A-gnI H36cJq<ζKO>\p4?9VFOUTo:4S ~-֛A_>\%.myI@ٹP6tY[e>GiiNQxE.XXX~5 z*DM@Ɖ۵˰,.F_x7\cx奨;BT<u렷\w[1({oS6zUP- Y {@D=7ݕr2 ,ʼV 6W$Yiq;p|;6V1\fY%Ȉ/ʟyyyXD_U?~^\|y#\8>k#S`;^xJÛnIS4Snkcē?/g1C8=8²U-܎- \p(sPQAcPɠVo sh0idT];ɥmVZP>kAHnr*+"=52~OOc8; gĝ+uObA̫tؿ !uZRe =|ݻv?[gZ`?̂?x/BB\udm1[,f~){H#OON[["]~, "0ɴ58ni뉗Coc7Y޽; xLB #-8<%5/;s*l3uoqwlۋ1.Mc <{T=(%WHztU f{8;LB`m~zJ=<\-ΝGm̐Y0@w!Z=Ga"z;B MD A73j𢁹׏ y1VK33;N( M,ޝ ,@G]trqq]i|). ρ,nH$%c{[WVGlAz}By͒7/P z5|?;t4x68?it9qipԣG8[BϟCjߎ!GCtE;SDHcgLؽwoJiə:sOaw9%=UXmYV%.$ fACBm ByGGD=FS÷&ivt۳#jnfjxh vtg]Ct㯝sT j-v ;5" gev<'{ H_|'fN<% YuH5Yqc7m\\\ZYY[^މ^0{ Q^bT cUUUE}nq~ȴ4Z Wn{\\E&u"oz,Ǹ8 *l34`؝>?ç"%ߍ#.H((bz͐@ 0tL '|Mr]^Emh(Q&* )+{DJv2UIFF"WvVHvv22Gs=.9?y1GWP(InwwWYw~08_xgGGΛ~0E։1pkMM)$%%BCKGbggq̽803z,g %j05*-9fp)qzqAwCk_r4XY7L e7+i4dLFz9@~of~qUs^ٌl 'Ǧ7KDZ-.d8M&KUvW8R?l,Hhrr*|z d&,X߮WBUUIJ:D|YJ.d*P|e|0^tǵr̵|t 4_>lpE^K|Oc6EÌ04(DLw99"P]?e/< (%{-s??3$GS%qt26 ?e䋓e1pc?Yhff嘹gVV^^-V '>b~i.qL>?nHDߩbk@)ED ()`ydxS<椾fN3ZcD(>i{~GZyK:qq!ۏuOy ׉.Ի‹%cO_}LʚuOF'u'd–d[gvi+U ٳgO:72fpl ccՅsNCɘ^VWSceg+tWFK^}o|:2@n92&!)$Y;V@@6-Oו$cƩete1a:Mj1 ^xjWa^G‡lvAjj?8[q=>h{u҆- )y=9~XB 锉bʺ Lp=M < FSO^r~ }zr|b""Egd_#{޳Cn}-??88xkAVkDDDȘIb֭"{9*@&3)*(4);3Ez[{-5hTh,]Ò'+`H8fte*u-kO7! Q$φ-)aH<8rDR~?\kSp5ٰ2{ىjďok(;bln»ªGIAC^ϫs(1MC~lt"-;ZX]Ogl\J[8;[qcoڧ #:>V [Aմ3Ǽp{@Eim]fi&ᡟL$E-waPCV .A056xei>y^qŀy︷h:3"8M9i/y(nh؉D!\YF-n> c;n c}}}ϥ6ug>|]N4^`u{cn+мj[qk+|bś,/eiPD 89ӸEd~:Z?qZ?C͉*[iً@܀}6Op(2{KD;\zwǭ4`LZXLOy%5e!kXmlBov*&Krnqj-+1#FN /h`ʃ\!Y48S2#il"vZړ?~?{f0:V X/[`!oIjN4sϚM@$)/QJ_{{lo5Px?Uf:xWUo_$sK/ʽ_v73;\YcaJ[~KsYLra~]ܸ{k7>iƿ)-Ƿm2Rg^țGyrgّZZ6lxv@XOj4v\L(瘅aHE׾|<-B>Aܕv_ڎwaU6nۙ} XC΁3n<7O9PC #H![cT닎cCaڵjٹ/{XqNʘBK'N`e2ͼ@䪂dRPq\֮wl奥cf-n>g`x}-)*v!lsOc\q ~j̰΄(p6oV67^q e8 qʣAĔّI/؉] `cܖג^'ik/yR Mi5ˡ=]6qcmD{ΝgL-Tx젾=(zp_[e^"|UiD Q6cH7oH rr2׮=íW\Q3QB055uDHO} /ccfq;.A!:>w{k!&zlwj?L:ӧw +7pp*s;*R|Jǽ(3ðX>@Q㬝iF,ݹ2색0X2;K({bXϙޞ GR'LV3gJMC=Qn9٦b*bis^&U}o/_޺7*بtDAQ <_2 &%msrr"\0uZU0Vٙ4FX$YYYoddD{g&&3>L'GO;$4/8>ɹIMp 9f<5򈓚KJMFd||*c[[[)~*ga;\J1 `8)a=TRpxh8Kqw="MIwwO:v8OUr2(uH sa0X3_f V C ez3ivRQe1JU0mHv6=EҤ*?ON3uƄAWNenil|;0b<;vpZ:#[DFFA݁J L8 Wd[4e('ǩ}%(>g+F_3-CO_a*4_cjHnafiqZ֌|.@]t۟=cX['OD?Ή;RH^aff~[s=۴*[.VAF]P'((| T ,WCYDTqCáHe-&[8+|լ0KHN'|>IBV]wyb"[9k2ԽyoTϲpU0㧅Y CSNd:-R@~cm!N/Mt& e*>~~08FႀCeVj~, H#=Z*"&h,lߞ"9ݙt+`Γ,\Q0c(۱c8j8,% 0W-"~/ԠݲБ!*YΜ\!p"xJP~{"2jj^<ξ J'gggu:^[ag]婠}1<'.Vx+P㏰x B+}[l42FJj[}CC8㎟nUfYkj5v*.]Z';.mݲ7MB%+ˬ'O^cb5ITc9{4TуP܀3/Cw=9(W-`aTmwTܛ=6lx$i׮]8.iht;ℲIjsC㖔x,|%n1|\J&,K7K$!{xӇpڸ7\]%:lSSKnT+/eU-z_Bt= 'hSDW'Dx3ѳ%$&29}^ K1 G`ӕFG*{70 ]=t)`MgNVnrcK ]hk xxx(u=9E[慭>pI-EWCh06gWUU}{@ƲwF"M-\N\B½kӼm[)@kz+QZ5my;rfWUU)N*.'3ΰtJ%f5Bc}?c3bJ*A|i]$Ьsӧ=1l#"1'WiܻEq2b5*Cgkµpnp3C!˨ BfF1gƏq`jSԚ!OD'&B^^tP/?-Otγcj w wfvv#qh,>s,Y~r3;^̽grZή3 ^=Dy "< ݃7\~+)GI p H;|ewz9˕R4h v?xoYZ3SobPȾt~oAiW;~ls8'1=la\-86Gof灀XcȀqJg̭9SllbbRTT@Wh ŗ$IK}d#~X`^b19/9O/aP̌|b_lܭ*3_n{/_y#`SC*B\vhܫ+"3E&TTg&"ҁ_xѝx<^ďv8dY~zwV9 Ǖxwfz"o,NY N#55mu F]AIɹ9Br1R2ύRB~fTl߲};-\\27b+EF[:,Ai\Rh!,omv~$o׵DoNp2p$Y1y芩I`gf0Ȩ~(.&Ls3UzO`V{]pˡxX"x­*NOp'w?meÇMwVD6po~67~$9=$0[upxT-ge&{+YO; #7"k(RM69 UNrkϥS< uFteHT x"V_v-\MaOj)TB3lT?Hj͈N@N։.΍%2d[\#co KS~jaWH6Eq*Z?3suPJnnCsNaxʉbIg'+YWWᒐp Kky0R>I_KN 㪜SD}{u#yrռ'iDiCY{p`덼AB4iJaEH@ | Aꚝ IM+um~͠R2j:a3%mmL0Ok_`vM{=jû#TcyCxnqDJJEE!۸E2Pidg 'ۍj :g+<09D:[Υ*eh2+:%YuQd<^K7WgK&خSr/ x D<^jaݜky{`qG}7W%F_~|74%4LmKU#jOqp߹cA`YG\^i;odhӀ݌<-]^`X ͛/UNn-DnTYVVvt5q5EnČaz45A( 8ȴ%̄!qڅqSm5qP:Y3a#pOϯoPCq+59+֦H%2܁Y.IY1>6VqpR{7 u)ŝCQߍr)@)֍yq>-(7<@|{tF*,z5gϵ\j(v+h mE):m++BA!WP`H %x uށa[dMgƤrhPClIw>bAFțҞn > q`.G~iǏ X|aii)z/nQ}e|AVz.8& 9TDOz-po՜Y&c)򭯯'o9[lOz:3j*`n?s8jEa.-~qqPZU 5Қ-FY`[WrK|ٮ۰ܽ ] t$ >|sJJ !m~c:;2 ,>CBΎxb[B?[~RX?J:WD{t 'O@G`K3`d{K=v^[J'#tǠʘ^$)%h@ga{⹚+"U2j9DX5.a0p8xwi5x]9]L!*b`U ~RQfxJ˨CNJ v6:}\ž'dlOZ4,wAffQIIR/^cJW7cV~()oD|ݩO(/??iftgfxN-c=|"I#ǿf3]XZJ ")N;ĝm6w$+0x/$0UFǐOQ+W(jͶhON K98_|w=oEynxR;|ӵ*5᯦ז/022x,`3zQarn RsWk۳MFZR?) =/HyT@_>؎ݢ\jkk_8vo8z%R uX 1e& 7zUS@KYNncC}/o#V|uļp6P-ߦδ~\K"'T Hmǻ[lQݨD FYv z>*&Puxyig]ɏIMN Y\W\yxYg!r)l0VBn70f޼-;MU>N@ppz2$$ݗ&s E?z90ziHybq$p=-M II}8uvU]IPHĤq3 #l[~mr $o҆ ypyήwJ22=U,ύOv/ǜ]X̍*c2Va(34].eGZna2+/#sS[]%Jk;PHv1U@~@ǔ4nf%"XH?'C9S y἟8k'6MLܼ6΍S Xpw t-u:fH9^K/=U@#\zzIS_:CΗHH:Ilb=k&{n{cw&pHz2'Νؤʺܿ5X^ja?߲|AgS.h)Zɿ<8 p/6A@z"BCau1j׻ 4^gmC:QMԡq<>L0|dӼ8FybΚ[2߽;8}xԲ') ZPCްaCNţ.F"dpS)+8,rv7B}6uuC65*K :ɸb,T3Î#.JJc`T} v(N޼eY N,\[#o۶ۑhu9E1CCCG887kK1R4$)Y)mݏ?Vf[Pgx,*@TӭsMRb OVI`?5zp~۔v=?]I?F. &.a,Э\Y ʽI&$guryv9c&?4}y_Phbp R<\[IıgcնlDeOا #C^'"Dx@qoUCMLȀjpwJ4%Dd] ܽt߿9} 鼒%k3w֎+mY~',,,):]R4"CV8nBUq7f x `e|"0ۤȉ`v鍲_;"߿d8椸یSvv2M+iNVQV6ln.J,򐋕~Yt-qKaV X x LTzz7~ >c9đHMG綰Esv3U A$ U)m lR4f 0ذi6c\' -|ZR? 6KIm B󶥍? DׯENgdv ?8J Ϛ|f[mlѱ4:&Yq9)qiUQs MkөquCUk}^]SZd6}0eǞ=dA3n0/8v)Rl&,oJ%QAgӋi:nnN,#'b.:&@\`Ps2t.#?**wBD⌡PFl:ӼC҈MIٮygr5زKV|୍m3t";V4T1DZ/6'-UzDdTT6}\OX Ty9=^Y+̩79f7mm/J`nԑ3˄fkGAuTEUս8Mܲ Ϳ"eMp4pX;9K`nKsG/(,adJ}:/[dϋMxݢLbFa]w^ç>4!dXiS›vYE&gk,wwtHohۖiNT 2)I{֦m&kV 8^QR1j6Iw]}_]7dxΆRS`OQ9‹NUc:uagK455 (srG8APɘWN1cޖ8iXϚ1[ʿ _{rݥFrI30 c$َAVV1@gS4l6-âj-fz#OnwwY-(N=f)EypGG<>1aۥ 4 J?ΖӧwoejNg68\vQo2K]"\܏pEH7B2H3Jȣ3Ύ9sk IL)O"UNyܶ۾W %N.}N8-O^Ul#~Rdspx,,|҉@HJ_่G0r/K2yBvjxzL{86$Zn*oM)oyc>:k&vx-LP~372ϙۅJ:E.I,ۼhjlT%&VQ_Z BZ'/*ƨYt2C #,~8(AXNw`UD#ՠV7 5qi쌽# Ĵoj=0P;++pƯ*,qӤޔ<bKɪۚc""LI?;]jmfyM>8mFU[_tpn5 @m$x݅}ekX7 ";\X͝Vlt: F:\}28i  | yxLUHF+򿝮wo>ݴTLc6#ϟ?2p:6<9?2b1.FB1,-;i7RW+i2Qgެ`=#0PZQ>Ndu!*cO- C+˺oRvoB7TT[ _*JJ5k1ꍻΒQT7}ȾԢU~lzuN&)7.M=i}49<>>>ǿ`"c.Ylŋz\OM[cbI{ ߒ 4,us9yyo ʂq3s/z?kDW8㐐/==wv>KCu%I5}eh#4--f{t$9P.e:SmMd(=iV!DM6h7*iidfd-G?s1ܪ?b ^[DgwBDeyGTߕce[' 56>6\yO3^H|Z!3 - H7TXsEiGw~"cv^(%Vx a̷6 1w鑿 #pulFWC*ώ6H\ڄ Օ%- |f KK,dkd{pS 3Pф HSzxS)|f1PNRPf8&^}؊&zmK]p5u:b^<->}4ϚnT,@"z o+ͮ]^0QB;.U?> vDYtljW .mT[#^Í[Ն2"!\K]44s;_ K::E嵱g'P@JϦŽB#^a'vY75ѯMk-ࡁο:q97>%偛&``̬;_uf`qK <$жp2Ź1o{:ǒN0f؈59=U' 0t;1iYp^_-W*$ ;NY,x ۆݫJԇ[ QZ'\bV vѭ'=̇.oPp$=t%$\,}۔ok:OR.:kBϧsӺ%D ,_l1x|`|S/Α~߀Sa\lefn{NqK4$33/cbT۳9-`A9eh+eE㟺f} >/GxBAVƴ9g.NKQ``2=V%;Q^A_bZ*&PPwCUbagy# WDf35󡂹Eb3|h{?¥T,qɬ=)K=$ :E$/`ڴ쓙0gäʮP6zgI7fn \ᾀc='קu=q"F.5q5o񉅽{'G8 ",,jLםp#ۃ/J4b5v'OaDl 7jR/cox`j +]^^*P0şwK_*_`!t6mBpOMFRU}.Qhkw zrP_P l 5m4U-i٦PKW{yƁE엝*O-ϿIMEbhpxͻp!I>ݗcXlQu/_Z.Oz);_:^_/1h6qX,0 M$񨻴ybB}XՒW9;{ao]zxCRdoYl9Rs6EÇ7aA MZp6((vwI%v:0L'~ՆţܒwiavQtYT,Ź.Xstm/f `r1R8?40?`F3 +OƊl\c$?%yӧߎ )O#EEY$0O0tEk+(H܏g^ɒ\\\Q>4'2ʺ/d}x[ Pdm{(%,XL l٤>F\5rMӹSͿ`M@3&4ERoذXNwy0<+VV%{HvUE!yH0J]1JJ<j,Qe}CPr+ jD]̥q#XOopF-Į}8oEv_GQVpzpk?Y!V">)Y=jxb!--[)`mc#GOç_&`ͽ1(w+NT"v=(Y86fLu~>ԁC?UB@-ɵ5We i#M  O#@Dy'Юy (gu7]B5&6P q4za/kbjg. 2JJ>]E|gqVoqW7tqu]/?y_![^27w/j駚NSS~՘_f:؞s$Gj[${m?Uk=#LJĤqɪ:@ܽFnnU#CCBW?ȴ%EG9g~If.jv뇱<|VP022->`e >e!-'+ʥnGIKnɜ #vMi>հoזޏ߻ {8e_4[.oJը9^ɪфT2 }D՝;w2XY]eޱc Ds73uo*.Zc}TTfYܼ###b2pFܿ?]:;%LmfP\3x8lD!NHdS YO$-;+ >p2؋ ŋ[脵#[$]|u@NUV6,͍ե9"-)qE̙Kt s 9ޚ:_p{1->-rdM#?$lS]QA?{I+ѻ3==uIA.Iؘ̖g[ @IAᨷ7Ԝј¯WyBIq4zlVNw#a9BAFA`+^ۓXLv PjGBQ @jjDyeee蘘+:"aP}N/X\ xl5zz [l:]|NNN&^(D6u:bJj⚹͍$uI͵(+S\䳊 q1ZD$$Iqr{&P 7dA7ʣrn +$yQ3l.ylQ#W|1QvnSA=EW?o'([YqQ064|1!m{a.6Ӣ"܇}f fK5K:N`y<"n ,H^Irl wF]`V Us]V/&R),5x3Ŵ,lY4elWZxnmL*߲'69DKQW vpx5 28.؊^aaa!TgxI\sdMG篏^IIޒ.][@%W9XϢl +vWĉIF 9 |  Sw 5O݊A1)\FYppqUJSr ] B Yׯ?oAíJ&3^?ff`/7){c\_~?V\g,,]H֖]` (V.u&~{'[,OPSmX9 cy1118ەX\g$?4]U?< ?|--3z~zxO{ 'ڟ]=ǯ+NӅ]A[`DM<t֢9HII%4s #!;R&._xulYZޠx;Kd]yGA\ؑ]}|2NڠyfyQ8lL*e{T$ögT5:?mZY[ʿ)l7PTeQ7nqxnK$+gRN4]%bpλ%opiPv=aBpk ۫No.H=uYa2geNոz*aU(!ʪ|(nF{'o_oWF0L@O榦k N"99ٌF+Ǵw嫰 5A6@i=%)'+3ҾTs!xofY8=;{#=Y^v1fd_8g٭pȁKl~ߟ1c]ݧO.]4qzfF)=YA;XpM'zQIg`c}Qoې׿"ñcOi5un H|@vq _``***ąVgVVnc.l6[HIVc3-IDQp6G, Pn=Ր$$4\RQdt@hhr,\UW{X,;ukI&׼}۳tݢGeee LLҚ!'gpZ^S<S`aqGk8G"yC6䏎έ. ynJO:KO(.yزf0F zK*>}sYd\rrlYr_w YlkyΝ?07EE},|θpd}cc 6|tB|\FQѱټ[eJ~Ѣ9/y)UDK+zl¤s){RuԊKJ*::4+q3!gjmeqy}$F !uGR*_5,R)׀ l߱Ǧ́8 hp(?RoFw4dUgnj!\c-dr:a=kU,^aAE0)?hqTo؍FCJDM-OxRQ&_z^kgfSE-ƍjx '+b6|%Do9n̕ĨM{ M۷Izxi3 g@G]yWyM^o!E̦ϧLVb"W ŖQ&0y{ϯ ! !b7-O<8W44fQKG+x-G0ȉǡiϣ ͐G[n{iE!3 o߽DTSP y4R{I \ЁZ|@89Au}< zg..}OsXAm?4WK'96ʽ1>G`&.=!v&2tnƒ'?pKyZf$&QzɦYW`cUTd2+NxKa4Rlȵa1ѪWsONrŁlC枟OYti1"'. d2+]=W(;o;r b⯑4 c4FcMb%v߱$iO.f9/@s?8"jyUA|,--r0.(?6ޞE(nݺGfj`W݈]^+ 6W)Z?)!"q{}pJJJcll FVቨ> 4^z]H0WX7fBTpXoӧY#Aa-yy_pVm6HGqqq8SC&E Xl=|Z%b8_D=x%ꉑFAy7(x^244L㦣#~o ʁ.N  UO_yue)AUNSgwh>ߌ UIwS{ٍ|H.̵y@SW8NP3JԇT\KCe iE { ~X8r[)u<yȆkk;$))}/8 x5;k5 f 6Uzib+oc [ah,j62 r%˩t:p|J^\|)?b忥ZZx*3V%z9ݭ;1bLB4mאJ;D2F؛$LC d?-: ό{'mITt*mMIL16EZt[i):1!;GO".<>EP_p̤\ěK~dka/P..ǖDǏ[GHI ~ݾZFɳ)OF\!qUs@xعa8}"^/(1tmW%?}z4߲GT;3J^˳zTvJ',,:5 Y7-Zf羴j|c$Fˤ/\bQ*l5*ēWvA=G5265wdAjs< TG6KHfgf6vXsE}^" nPk{Ca|iN TF} ʚ} f3!%-}i-.z)8D_BwGx[6e![@Fѹpb":b'g^r7  u%$r:pxc$-:9`k|QQe۶m8A^`BѳSے[_*[&ȽTQv  Om%,suxcTcg'y¤VHp0 ,vAMUUѠy⤞ŶLHh핺P$֪v}oooہ]Fw, a17Vi7)zzhi-wUҡ? =ɍŶM _ YY]oaov7d-Q11G wwlVVV8v000bbX<u8ã*Yf;(yMa!~ K{~=sr鲕L[`9cKMM &M]A' :!E?~Pֵ4;yxk?=}?}zŦ(?2}:jj^^welnjn/-qٳf%+++yz^:/tQTԩ! 8)5QXsxS}~C<'F<:8=`^EEE3.gS/RJ9keKqYC>ccc;&V'">;iS$K5Nw[]~"J#P44N $dz6̪4 7zzX uʒ0uw6ou(U#K%=zH/uNoyu&-'5y ͗^ɯ \Sfy)1'?[ ׻W[v#aGHD38r-f< 4dϟ]Z_;nh .G]r;? /~\2֝07; g=3b6ҹpw3KbC=8nY H;6٢6ya^}Ɔu8ahog6#]`i?$-M 6Ca?OyiV~~P{+3󝰰lz*3=80xYj2/NПPH@dۦبc fgβvFT2ƿ`9^64b@nj>~ )48jׯϟh&Trrb-P)t3? ehT s`9@%y^عՙiod'8'##ٲ*6b V_M"2`Iё6hO붇YV}Bh/ҴerrP: Xlb ̒9Zik[ޚV<*„*nL`R gE`ĵSOSG1UAL2YW՗/Z0?C4FitHS:L%ω!N9E_L&VX7Nc'QrDL S}EeJ\S! \{Xaa[miZ( aIX4#3,R"4Crd7V%͍Uꁝs===!{z6֪ cUCCԩ2jj;\Vv_%3]̜\nF`V9 &v SzUڪ uz":qꔌ6eWCs'eksM`tڜMB4b瑥^ױ0MG6cѥ?9]ELȄˑ'pgFtE 8TͪY|Ǘ/F։Y's}mWiPPP+m&ܨ#//],e-[˓?;Qȼ=Vog; //8f5}:瞓Ƶ/_)LceV{vWCӟ)X)8YYT$Hef:O~\+8U a`Fb%[>?*o=WCwx䩚٤pg1x?ع82ELx{%4y%kK8-mT' [.KK,| K*`Z|ѕ$`>iS %= '$T?=FLv36sQG0 hEYA0I3NA7.s3;*T=JWҬ)!䒈jOxx pqƟa]RRX1vIݒi,Ak`xz::볷tRH ~o&9AUz/ 8S^93uPRL-Tʬ absձ%wLiIHe{}OqrrIٳ#t ݼP.99Y׮0MIX!$Påϟ8q21=)߄5%(ܞ[ק?A"2?WmCfRWDTz󿈙'd)d1֔ZUm `V2+}{{zw-u˖DGɭ|| r+Pꫫ_ܓ;'%/^[ͦªפ*J/iX~qKVSl%n 5z3Ɋ-4x Qq^tNk 7X\@ea44^-\$Xg"$VTZ6'JV#eB2gY~)8=Ǐȑlm9OzRs}Ϲ1aa)rJJ?.߾];]gstY=2?;GcF1$*Ɣw3q1w y%`AnSy9t|N8ҟ08bb x2dF~nqh([7!~3z0뜘v=.qZD&&SfA'+1j.Oh@}~vܤ$+ v%eS5t<E|r[`WIo-!T5,=wh 9Bm݋b;MM 6dxuDJȬ/MJm9 -ֶzKި}#vGG@0%ԱqyごyOff GTia1^}j7Q%Uu\C&37Ag{/u`![4!".y۩-TIZVӣ[&d(Gkaf7RE0'&3S֐ 87ދo ,I;#bm-UQ$x^i\o-뻞a}/ʈ1^v# 4 .͍c=P;QGF0? 㕕LGd؏^\nniY);w:H#tƻgwxw˗j[J^S7ZS%į޾=CodO 'BKi*(Uy\nN_+9]^Um暜?.6+KILl> YYyBÔ6{5Ko~8M%S2Wvfy`W!*uR%J|=Ҝֲ_`4eb'lj^|գAA|x?Bh z@: #I=C9N]5;N"_C"bI&lN1zCܺLma]'*AJEdA-ZkNWnw8իgj`s{d$VL$Jyʾ$Sk9תL@>^^;`)o*SצKxWVGGd m6y)WwU=걲,Nt'0қ6۾KJuw ߿ۗžAJJ)ji]wSEDvy~¨җRII)0!쫼a,0|Uiob>nimabUYk>!T6 1lhY s+.8VHNVj#?Y. j<ܡ[<E_,|{:۳ˣXï%mi3D=? FJVcpacǹԛGÜl,ć=)(bhdbf.%=|:o*zpքGd$va}kw@i;pCl>Jl{[Dbkk+ɓX5{Fy3 xJYt 4 ѭOn/9fğbO޼ys `LLwϒ3՚tO3 &)]sYQW']h?JߕosXC vyL<[GD'uyI' Hi:Nx{{c^>rMj] WFGঀ՞z!y:IiOF .KHCIAAY^SLq܂k}`<,x2333WwͨoS}3*(p _܅,m8ۖn;~sT,XѿU(%P 9e5q7; QcwF% m䙷ОR_/㟋0ի.Ȕf͏ܔ&uAIl\b1x%:=2dlLyjp0<X#c|/&\Jh/=pfrj7%NL~^TqO{r ?>pǷpj6ՕxYG/_TӓMx)Z"">`k!{@7 b(Yw۽~ȧ)ڋ/`صsN1i$ t&d9pG<BIJׂ\Tj R_ O^,(.)ASY[P{mnnNLFVGM .ev#{V~26Ȅ{zhPmZe6A-.WvNJL6&_+|lR]4UgЖ7dUuia!xsYQ>Q۟W72!p wHaUC^k~ .LEC<^B+c-hTp ^DGiPVa-<Ϗ޽ =DEŲ/pDF<>IFI,4b\J.fcb18|]]^ɔIm;j/0473T ,EXj`0'893ky)SǛT[M}ky"uQMt9Y2Ie%96<ޞ#U;?[C3uM]]xNL&©C};gFb-?5]FZeϓbO 90'U}k*YpPX Q]츸턑Cǟ| W vQwjf$n,UU%)uR'.[̛ڙXDPlj58<0:QwD{3grΦ~;42š+嬏椈j-ܫu" ]]&szx x̧zD =znh-K/[P6zIo۶mF,efʯz}e#FEN7'_Flb7Wkm6Ͻv= <*S҆sg׶a؞VYr3pJ%Sr֙8u*i(7\,H&2W6-[_+qkQ'&\JcatHW>rk&LV-r|(z5hVwoŰӳ[<9Lʍ0筽-e9WVF+Vew[y-/;ҾF:Ϣ{:/I::d_-S= شu9O`;#Jl NB!mOroz̆7క$WNϫpٽKj,Jn!<w3N ;ckzTSԘP*{җRj \[`i[;'K8I4Tʊ'\ '5|b2ߜnTɯç *}ygbȶg5b,LP=Bir++swHi$ ֏/!vpKZF3p(۷O00?zǗL.TɵR#QkcKhƚ7oĺ w9sd 7h$%%e馴>e1flY)6CLkz7aS9z02f-=={ȶSmEREpssC9u YRjɶo?oQ26lnQ|$jgC鴷DNmS05FVz0d"}i`hrͥQ^+3ujvv%Yf.\1RXpLEc"df.%gD٬Zooͧq#D)'i ;zoK eU>ؘ&ylBJZ# 4T)yo)j-OΗ1긷eoU]]EMkf{Vp'G+ 4]h+3\۵^,*s|F/ϻYd8 Gˆi1o77=SF+|Ԗ<;ckR`P9M۞6c;5x% !ݔ ?KNKK |E^zٮtҦE3"|}PN] "ea:veIIű(,GU]]?.cj,:6.U*lB=ϯDuQ5'nc~sWjSJ>~ܐNLVe'_*1kNLl@iie91R5(`UʺWE^(ɉ]VZcpBL!6TIʕp[6r^M#i/+_ڵkq]ԧւG{pj?ܺ!{0xt-<,qCjږ$e :ؒlfƎR"͞kD5i!R0RJGkLJKL˻)pT=V|։ w+gőH85k޸Gv\a)))X?1gɦT˜-m| ǐ3 !l0ۈ!> w;rZNownxIdoy}eXL%\{qq!n SZk ~fRs0Ӄr_=@q%T*<ۑO4ɱL JxxF׷l䇓q}sD,K5|-pz?zkA}l?ɝRb)j7od~ԴUD3q);l"RZ>5z7e5[DJ-!x7'?!R_Q&(0*HII1p85lI݉}VftqbH9aߎ:.sc`7els%+:Rq{G>>A5SM m;5&rEi.M<}}(SC(+11>jE(BA3u^Ѫߴ˛ve2Xs^#&^^EdL L\]I̾PUmT  IERA)键Cw+ ( *"(Já窗sk5s98_#&!xX /z!_)9F8Oa?T暄q2m T{9 hde a-%l WYϳWJC=!!!()`O;@Aw.}lz RjSYU&dc# Y\/mMc,SD\#5MB>H=̠^XD,&g I$†XyV rrU>/w l"A٥`>0[3MsB)]u|rbO3\@ѣ Hg}p). ̤n7,4,LiLQV#8KKKކZѳtϑ sJ"@/e춮$fåQ nG I{\Z:낂ںGq tvJ;VlY5utgf2#BaI_@&*-\䗜Hŋ/.^pEYY9(<hֆ?Vn]k0XdޭVd͌z"!xI ADji4af)/_Rخ>t>NUt|~>^{[FziYX\n@|U shÁB}aTPG$EQg9Y=7{ ZHD Fak)򄤈p x7o6&H4)@D+T<\x +k5B؅)0拼c4 0@=.nP\gfeU668`nab\4FƜrZD]z 㧶u4(bB(m⥫91CI^ߨ\l^vH)| }ӥ ܑQPUlmfdv<24@gkT0 55 bkzu쪃`ω+)EMɯ)JubtBOvm4*7t}.-Yڸw=#&e,SΊqK NS "&;ۆpOGqs1X`~/k\x=1,wgi'PB"5.5RQ-DnxsJCKV4APh蚁C5!TQ!/[x yejVW kӇyo9Q4ɣy msE~q) e~}X' S!HIOl,Hh9aŞU$.7ٌưjjWceז_NW /M̙R7}==1&Y^O.Pv| [܂ٙH~(, Uz0X=C͉Ɨ mvᤴMQ1ٵOyphGd&-=}r1F̎*lk]WÆo/-n; 8B:]۞4!xގZʷn Xu|e)AhU\Eo PYls?RXs7g7Ȝ pƢdFxZ U'Vyp1c1wM#?~>8@dw ב1gcjʤq0Csu{r ˭˜?eGESpg@mv' 1Czp+ax~_A"o/YMO1Pd.;F#ו<[|صr } >(euTM:xg^H(=ئQuu8Q/#q7f{M=֮ \b&}0rʡ0xv}ib/ QWhFp] Pbs`6ni:^i+"~?ĸ0YcW-<pyR|0Էٞ 8 |8 _F蝃*(@m$((x8u~ -:"A?k 9 k84kscaiv[_Ҹo? BA\ 2sY!^4zo?[Y]Z[% ௵˿ Lw/v rvXDڍמ̥뽧/3 Wa3 ߛ҈ *ڞ"g D"YRs3L-<|Sq4॰LJ<-77%bGùUJ%@LC]K~8ѣGwqct&[fBo:JgP V4554 2AZU׾*1/nm37>>yxUTT|6P Rhk1ұNg|{gu;~~$@qOտ4Z#=~<(]~J`E葏`"7O>:'8"8Q]əSu(x7Η؏Һ ˪@kTШU`}Ψ<##`spgd`EX)+C9?g H8Ȳ|PK;bR0{#\8byŸЍŠ ~GW?IVCĄa\$wV#KސAĔ:~A Ly''Բ{^dk.kGi{`onKPh%6:DziLBcmy'NÇI. Tep Y\\UI~Y#Z44Z6^QTJ+kEͯ{^06Jm 2"Jc`ÁSZ˜eUT 3NiVCr+ ۷wC]4ݦũ٣Wg{Fg  v (8ߞE@Pgr!l4nMqi'$%Kt +5^bze7B3pBs_T7jEZM&*6 `8}-@r;t:`i<1(&`Ҳ O#BUVV),E |ɭBtc(ֆSN›pqqp *ݸ,!/# |OѧT 6ƾ>+{{㪩^2$$ n!ILJ^ag5<"v\(0  Gb#oCB|w8WzѨ[GEG3M]XWpOV6?~Xww~鉗$ЅPwѱV=y܀"ZeZV119ٴ6wɓMs9U,WaE@2{뢧q7ALzH?dj]7^4Ρ+8Nˁj"ATs&?O,pyOטS|g{Cw8^d)3kƓ3{pokʌR\e|I% K^ ^{egJQ9>i'4PI~?cyNz 8w~I#I.  XA%x)x2~ِⲲdhTAW~pV™y*5'D ,0 cc;,vUIe_ojF1F޹syUY;Ov:UÑ:} #CL( ƼiȠ)T#4֎ ٖx[[[Gg=T'***rSD5EJ>Ӏ,`bjz#w+qmR+Y=^xx|8%eA H IIFe>ZoH:nZ}'pYVoܷ.ɬ7m{ӪGK>v%#!\*KЯX!pë깼@c}Cz\\\u[6W6Y52>s%DuBH2J53`.̍?>hO&=^Q8s}ep;mw>Wsa^('E_?H>WkgFq<0tg0\A6Zf.ōʔ s\hPI纐@r!q$z NՑ>`KoŤ%ɳq >5LpYspWu߮=RfxuҎdN8a8~Ǻ2-|*f|MIa 睰1_%Kٕ2q!t YܑH+;LE>KJK8_oDvN}q?41 ?;*W8Z n3 (/P}6FQ({$gE6݌mM{IUwZk8J|ӛvBdx,Z껰 kK$o?$Gnsp,Y/~iDA7vqW*P踞OevNN(PdԏU7YY$HEg תx_hm A cٝ퉽Y^fqB. lxSd6|Tڟ!|!T=Rrus3=#oXX !bff,Pb~,»:SG,0ݭzp="6G04a jEU{}t ج`m1_| v+.͕7O_zV'6Yb Ry1x3Eϰ/*in.۷oO^o~7KT[G'פNM"6~gU?K:P(떁҄II$JJM= j@,)EPd"uv72|%cxaMkH (fh_IXwzw7//8AƎ]`APc|̙3v}6hעOb.R5961 "X'pU k^e-sZc<׮_FSS7D:Uy;rymvs<&|rg75k Wy{5c~_(%>*-j/k] r LmJ恱o(2o8 fXNI:\O>JTwi9QC,=-IWp0%k>0|gw22 |G5K) 3grK_%y>z6[M\U`/4y=(I T%`q"V/YӑPc&XF gx Lqٳ^hNKOKp"_渢 fE֊BxLE׌ҀUぅ3O?{օClЉ_m{,o'aBn.:΁IΑ c/D}5C08;քJNp~qki'|L#J*y`=k{Hz]o7Ka511Qkmǰ72%%%bF{ E* wl'Ƣ%^MQM/|㞳ߍ Vx퍫oxK=< E$`F 6vlLYA(>+Nȋ}GHxɱM5}f?R!JPbL =i:YI_ѠzŪ\´ľ_p{w? :'ŢV\94gi:.ݛ^;Ϗ 6;G@XKlWKO2ڪ|!ӥ ƛ".Ofoo}W [["Ʌw*q{e9^"8^oug9Ij}r潦ʈ:9,N9Jrчk :_-g`شtt`_zub2666Iw455j8:3Nh1!0ǶLݺk*4T72/ӻ$wވK ax.conm=Oɿ@8bZ"? n`R+$ (P\!]UETP`:(&rym-tlLr!ѓx`BXJ3WVU [[[tv1EdDxҳg^^J唕T͞]6iMMY__%??ZdxR۹證o)}D[qhk}ѩYTdt@}W)sz1-l÷l554ד/e-js3.$QKjkd&h'g6Eʎ gD v e欽~- daIAw_ћq-68R M#/$djjz r$ jg<;,Al뙁Msuă *GlZ`D䈰 5_[lw'PVԈE5w>mG]Z/lF>q A>N܉겥Jt6+׺j[qN:o,,ئ7ouz<ӧᜅv~D2#@,l$9á3ljZZWQ, +ͻkB_/>TlQ}7W LKm HeN뢧4>@i g-rvVzi8ue|j46psW").3\bg@#lƭYԗ"C|R_UX{c[{#޽{/\+Cŝb^<sN%|nn$`>6dxx6;?{L6wvFFFgynCt68K 4ݒK3Qprrw$`1V*9l~>a\-$Und '\77n%Nנ)WkUR繚lr R+J_R+[X-- Zo8Q-LC@xa&TE<SoV?Z" N5oh3pՌMrtfaS ,H>}Jlz䮺zJ7)yR'efcB\\zy"g5c@t:{aW\eL"2^:lp}jև >Tg8ŖBv6;l,W{`%7#7>a#zᎱo_D4̼2ևШb@ 8L!A9 "ᢼ&G}wnݺ+! 5/ ]]~:|<~y*AM/|z:ŏ׋a6JKpr^QUQA=C9ݭUiė.]af>(¼ [?J ./h]F< 4LTO/1f_kt0tŗ8 4抻D7O .3)b"XS?GU*BI̛eD$#o͹pY Z;,W .]}y'UPRt%졎wd8 M; Pfh4+)ˮGZP@ZBv _Sͼ|q$3r%&Ȥa?wnY,k,7H͛Zw" >E!6:U  +H27P$Hɉ2S;^_{1*f_u)]rnHOgp;۠c((4;d<|R1[Mܷ>^ A.=֦mo'|9==mVTLplkbzzz~zxrr5YݺմK@4€qH}=׵mu LL}KFAѲin`Z.B9}xҥXW{?(+)*|"eý֖^鬭".I[׵nN/^7pǨqދ^̺Ξ;'^*Lg~97݂{>(3)=<| .?t?)>Xq X I ;6Sϋ#K\\a?~lmm/ UtezB:1 [>ag:ΟLKˇoWL4p;ƅ*:/aL\l@؃uKl/||` b,ͪ7o;tʚAGq,y_9I ԉ]ܠ5\.Aٛ=rcj6úfh֒Efgn={RS'O.SO_6~᭐]j:nZkQmy{~}[4CHp,&ٴ*G1XL"Z*ڞK ]8FUY JOJ:ɨy;Ji 8~^QzlRXYҟ!qH';Gݓ2k2 -E1"猪q P`6Ǖ 75} QTmʲmwmz媹U8 8Ϡc1h븒F;W=WwkpJ~~X"Ks6=Y2cۢ+r,5fԱ-ѵgw9z(VC ꖨe p"&.>]NPu%?o4>bZA춴i za?xL#* vFk1fƜPEϸk9gzofxoOc ?L[__vvJ@R *}MN9zGE+sDDEK4Ɓ y6}|GE#?m_~m@EKku oYMʧa?w\*x,!SF7T"kw_fg!tڼjΟ_?8Z G9N `˗ oCB.MLLme֎8z \CY!ӀWkM46vtR]h֕"CuWV jA)19eif):̩kמ>[Eȱ\wY9hQl}9+Na#QR} z..-uIqc9N)HR۷DJJ~yX6[U srK^sb^ČL꥗4ziiIY"A++V[6I@nP뙤pl$^[Cn; m!!]/c_=j}3G ӆnħt^9[{Z?^#G>[bYҪa]˞ E:~~`z)io()pM/ f0OƩ ]v[mtE~ :-Jk \C  ;U?̌hוZ qX1IݢQjEU8' P{=,`{OPGį`. W^-Ƽ\ck}ktׯP}LCNsY Ȯm(SCcO26t}-C32}u桭-'T~HxDu8AUX!= \sC.+p-c]1SqP`#+\zQ)0KD/C^+.ӟwa"uksaa^w|5^e|EȰƆBs$ddX(BQMݠE4'$ K Q/ElBW`z6yM5:ADFs nSvn:::At&4e":3pu/foWԹaYUs2g&LX01 .n1iDw3:ϯ:?FHhAT\f>V3EGQxy-?dj0!p`:6,'=~t|Viݍu6h('`a] %@eLKϏ+@Z>s+ `M |C3& .}ʖ*)H|mK3x$˛uNCK=-`/c5ꢏm2T>hŠM lgd@r?6$pb<ۂ9N8*{A6Fa_z[[uaa)KXn]!5 ޠV&eSݾ n rp9.tp_BB"&-)9=M##yK Ѿ>}0--seŋs oue= +2;k[M0uJaaa[E3bbv!{110Њ_*5ͷG{s3`iĩΜ9#)#3 B}q1OrRo7QP0) R66fvl8w u(B \X2IM[J3 B֋r A!4^3>Im4Uq< _N VLn=wqg)6DU)6B:R "ccIqqFy9Ɯe7ǚo@٘I.i^IiiUrk*-Z[\RⰬ%N qzN c$w̟1$~̈Ϗg<_.6x.}_d'PXdl>QmSvzJ{7K8_NViVV 'Q mBS.Dq11!J2A o7GC;KE~eE ~}`q0+y+1+QZM} e6L 8!רk?t3.BЯ0jMZ77ꍢmX(4h*gxso6Mk//-6/`ʌO5܀\Yjx73wC\we(*sbA˂'yf|m;8Tgk:^P oTYI'fe1,uv4gP3۝Ua0 2K*++߮ @a'++T뱄Xc8.>iḅePmgmCBXtJNfadn=c1 ]x2L]o)mE[ g{lP㓱U/TLEWYX3νYJ̥ w3 o^:CK z ݸD\a%Uůƾٛ l Y0VEu!n!80ӌy];[HN9J "j pH]xZ7>wVap|+;pslj`%OB{P t" d lz͗͊B 8U9M٭NwpQ+?y8|"˸at 79+XN"mf)1E$IX-e΍m8K3{dHAA"hz9P m|߀O0T{rX,rygfw3wMSA6UQ6󍈲0rre*y7deo7wMLAQ l啌ԣSz'-$4&Q[;: ΧHF~KL\{ DYey:x[_oblfFB1-a\6'O^k Xs7o~6282 /ppz3ӵ%$m%dzE]]5^>qo{q[#U+Lr)vV [yd@,`ZwΤy*@qwIΥp`òL'a0$2"lc؞&#=}soc$u+'Uhpza@v,$2 Sa~pc57mba̪?V6 I}]%6\ߴ5wvjwk>{V sY%?)roh_b[$"S(2sh/]֨3Dd>>ڪqu:vp#p'>Ǧ f (PE|J3.GSSZlDDDzL(F HM v|Ͻ^)ZȸfIaM_{oPfNaxyo3RU`,< Y__@zNδkEIvx멨CZ'UV>T ukDtf y9'L`xzOeըzPښKHhmXNѢv" QvgRR*.yL$[[=1&FF_)@37dj.C L~erݶ1;or|ŶHܪ @`_࿎W[W=PQK!ZKz|LiE-.#PM|Ϸ%K6_wN ,F&vbN}k4WE~bSt:٨~-'b,+-v2VVW ih6.TRS[ߜI?la+$%F#=@#@V烽e{[MfF`wΘD6Q$9>Fht?JSK*z@!kR)[,B3.>?x_1p+H.'u]5^xh}Dpǩ<|.0_HKT^2R1|0_G 4lz@^<:H5L Ŵ/Ӯ *se _'?MC-`øKɉ=}}p0h[nyk%ƾE/_n1+r{6μ𰼽ueJ@k6d%g&˃佸?>IIŹ;&''G5G?D\Km7#t |@ggDžvzy rW74}|<4 ܻVbA%`eB@\#Nu6{. 53h!ʗUёUCpjbwYaQ+~ȵ6 ,(={hsBAUS)]Dx!n&]sk5bjjlL+.+!_ HoXM>s]I5? Q4Q}j4Iyp #Dz껎)NAA FZbsWxv_;VbǮSӔ1QQ gn "8Tk.mU첏twO~1ਝs])2((wss =@r=r/j6@pzwVD@ZP$/Os">j5X>DN.\"E[_qOTGW<ۃ,`"qd6#pœw 37ǧ+!G~qQ+NQ=l)LBc-N˱džG 9SSI[B֟(?B+MeF # "ߵ~t\%RbkmU1/5m4b. OT}{h͑!Οā?Ѭ _~E7}% -Qɝ #2. Ls4(.!#1s1w:W#4ݶ&ΞJPlZ(a 9./4-G c6+ )lZY XTk>q \&+(!~a wE$\o׏Jsڒ~,f"?}w\Sٺؐ( PŊ"*"+$ F(M@:$PD);AHBPZP@BFsf̹߽'Gk}ge5~aNUX| Ե3O@.=op=ʑ_Qe2N|A:3cc[qļu:Vs#&Y'fO :??haÅ@(D,_xN}Rxkpl[ X5(_4w+vX㌟ g9Rb\(u3TCd ._KB2ǫA<|SxyC ƛ1Qy0?9TaF*DlL!Jr2gxl,xS%8[QС-˜oҵ%iCukB!670$RA#\ ‹BX+Y׹E-9]pBy`oiH );ڐ>𞽧7%QzW$m{{YB ֻޝFXbb[c)KM٣pzzz0DP }'9 %;Nvvu)ڴ _fa`cmeU /ꁹX&xKuuur͝Z8<1gRpK؆zu""m c "+3󳣺qϞĥ?sXV\<ĩj!&\ΕߋNo2gT .2e 0Y8) }>]ZkHrA -?[3~!֍4%Ճk=YׯmMEW{B ̪ xa||ۗgtG3u8 ^IsU6+p#QVͭriiikm'@Iu"ث49'3syN ޽pƈP@n*BbJd={,]p $K^KK$&M}g Dm󁖓Rp$DsB7IyJ8ǤB("h;Mr݃~WNj?E遪D^^˗. UC&_4|O5X{gv8O ]PoeD7!&HTPb`k<sV4<E#Z<2i& /Մ|iڊ?wwPRtK02 KOT:֣eXﭙB8rT^(J8΃~w;,%0o .#o\yBsVw`#=yףVڶbJ 26-q9HJ')r RzRLvR)HR&񨎇͸e|קsYpەU:RELs3fΣZX^ҩ&pu:9[O`ڒG|h dv.x4#\vd(8~}Ry?ĘQB9nO'r5ta&) 벲>`ՃŚXU X=|PWHhWOہEJ>w#J%10bjv <իc9@V|0ܰĜW<_ 7,\h8I+ CJa6[XN)kYY̷!r0i“Kʯ'p@TU ܾp,jX aogΞyCen;قWb ۪)p=|4Fwv^#Ly9}jcRA.Fq #czMmѢK98^5N /ifp[%$ηV 1e2RSbU|*{ipWφxt&K+4bc S֕75m4C:8Q yyEs{Ӷp5m58Mf S1yg-SׂNM)^QvneTj4-IlFCIE:&= o sAN6 ^AOUZ)p%f;hk?*t\ȳ8po x'n*.*%0"-Y(w.NShd4=[-BjqGso;=Hsӕ@Wzo呹dx@p>cܤcŕv8ީq^o_:8IR[ÌwQu#-p]ɗQԜS5Q*q_. P#FJu'Iaζ"GX L?bˈUeJŞ,Z?E[ qBpS$@ϫTӿ>f0|*{GSѣGpKɪo3mΟg$ShtvהM%8g>q9YiPo/|9>E.ӣ@LpbvTe pwȂ~Xt֭L,7>:ه7Νnioo)Ƀ.%M>цp9Y߱tށ$9XnȒw}׍;S'OzY/7rB7Z2p]4wڵ@jYkBKQ6]#zo( /۴ui*'F*xGuC02_r+I|QZ 3>!OD7Yghm[UMe'kj'$& Υi=;!"(ZcrskE]]]]p."nBwL7yʓ(s~mu%{ٷw/ϰ_Uvh#E4P{Tʦ-Y9oou I w@nB " KTI*oGiYkr;i kc '7P麼,HD:ɛ9C&&T414^D ׽+-Up/|S>B8X[:+;w:;IsAswmvsK!"xJ!95ԂW?>$4tx C}}o*߆I?<4/]ldg|y," SwW ;XR g#o9->Qx.b{M0}hljjo>Q遺-]b[Z0NjC`+A11PDlbf;^yiMp9)IYj "qQ1ƅvtۄ oj \,ʂrmur/ wx{feVCHe["#yv~rYHÁ Fܜŝ  U3* HY~>>r$zy Uƍ9^p\?9[>3*>SMIX`7%N-:Is8:}SB$!WIߨCBYezp0{pFt§yѻr ޾:.9Q<P}҅[9!p˦ڃvr iDRE+x:.ƽA$LJndIWvS *ԖGa{ Y]644j27Ca\Sf|$ x8ESCG?Z,]dlۿ4Ϛ+gU5K7H%f_gޤDs_4őNմۉyߋq1X~D/9[ iPI=mrc&6X p?u4=]c7ް6H&혁sͼ(F1RA55jZdVf"Q&eHcOo9.W[#~dA򜺺;O S%7wG[[[Ms]||O '؁XaWƐB< Ae9)g&I6rংg*V×:z,;~ߦcYieeel)),@RmRܳR~7p$kF<놃@J<)\_<% ]߶%-`'G6j@4 6G秤#?ZTF=%w5Lj{b& 5/-44o]J6cW/ֿKpj~%^?HT_M@8IPh4j\tpVa󗸢zFznv:'ruzdЎ49MHn߾;9Т!7^JҪajpnқ$Inbloҧݗ>)\`?=H;OesMq Sl`ucc2":Eg9F WFsd7lX0?X|.u(f4ޕڞ*TQDk0_ w¯o5+eX+k'KH {$ӋO!;w ;ùU`l$I *4?a_t<];ܻ|fBX&%]TFجA3ߖN'LcU5"c*sW-ZXx XnC3o ҵAGpz^GQIv`,l3g`\zsL|)`U%E{rVU撘란 3iQ6I~{`l֜&=s:Ea3F=!+}"Vze3};C鑧u9wڋLMD =3ԨwO)Vtms$aXA^AalaB_s[|3D^f|y jy˟‷742J8D;J?u=QQQg|QUҷRܮ<b푩454"nn+LLrcM]^736ҊF4eWפͫہ*iNjI9wTµu6opqttTVδ|$ ʡ/TxFM{5eFs|i)`N9zQ7zH 5jbd`qp?UƑd$_X3|/)G U}o8 TF } ad iMM|>CکQrF}KDc }mm kYd6OO\7)QT\\Nغu+Bj BR)ʼz/ZsI`!!dFo϶MeYPo6XK+$eVPJI$\`2%dd:Tg& 2ӌzD;.V'q4>>'7,E{yUIBǝi73tp`&8IϿ[zZZ3u|v;- CWt+T9~oċ˓Dy/ׯL!ed,sݲMD,0 (곷 \YOM7FJ(Ip08oUX{ѝVM._U?Q8$[))*2{0mN7tIbWvpxxk+eZ˫wIx!~%6,SL\pi ~c0ϙ֯Tm[ ̚7ٳiiiK\ G+*=&,qj1n @Z؛eh X{ص]SE͕fN}w}jI>d^.k$*cYsIyAz&Vٯ_2A_?|D cdH^ ύ6a|.>ahk;~[5pG;0Tf=ȣ""ǾfѴqqQVR9e:ſpb1]Xo}hMүAY2&zZ`L8gt\}~y}X2Wj¢ΊٌKbw[4Y41[4j;NJi9>4yk@K\Q$mos]87-xbk?7.27`v7i㹈33_|?7,p̠/ys9g,?fϺ&xTV.Q).iDKnEARQ.s9>ֺ=5kιuaH(BЕG*xt:-f+!m .JW$ceǸNj'm,6]eW#AJ7K QH QY7{Uj:6\/> g/} u,׼d8%p'tǹ:"Wz-$rq|^[ 3A(ԁ^}RRdtttAԞ0w$|^ <&x9DhXD WFFԲ [zna+sZj5> 2@{{{BmGǻs֛uúgO^qCts&H0l8v],iܕ?|VҒM? sY#b| ˮXo4؛,दʸc#UVVFسƜr"x= +@w,CxZߦ% ;,l;ݛAZZZЈ`jQt#`Xut QpD%((Xd܋첿ƮiɄd<[G'LLן-eTH 󹺹^7ujj'(Ç:y>O?dV&T:ną899XQ:l r{kIbި &-Uux#@ē2dԟ>OVK=ok/L6Pfj^ETaҌ,xA #!ݧOJ>.uzrerMf៳Vɸ񜜜~~^iicfF{^c=.tN"intXj#ߏMx͡t,SvvlG8mHX9DNE%ne5Us}ڬgyY9tt :UTλK)36r'EPp(\GOە;*c寍 K-޻'EV ޸#ɾ%Ԁ6CN֛5c83[_qZMj9u[x44쌠i>U8?ԿH m0,$p49?5S4!ݿ4]l^"DKļ6h/m}.9ݤd3swy,zQV6$E*!+tYVs ֕r^G"Y{QPPi~v:o}P\\/B<_NuEw1Q;::xrf."HHH<{O-~~mX͔2oX䂇 dxqaaa#V9+u,U>˜a7ӂaO1ŵ=d!R2{HJ' )Zy`EpR? a7=<#5Vo"dHJIe5Y8k&\"HQJ&TMN+χ8Z/cc2j^ˢca kDk euO8сl-,DQouj GqVJzz#%wQ?UF|9CcLt vͿAԠ Z;F蕶{ X|qcD!+̛? (dhXJ,{ t8~Erbӷ q:'<N5՗qZo!=6:_Qw?:aѧqA,vO^uq Lw֧!& &&& Y8Ѐ('S9:p/Q/N2 b/HbAwJݏ4q1f9YebW胅Pu;dHxx4XSc܎Jfޜ! O d d܃#I]+乢/_D8PCG\1U'stXImfy:ylm8UN\_%@ $~QĕouhQ[*'j?3QW,VhPTPг{DR鰮oO0n +f/ etQ}L/L~nvq#XSg醏`(ǩDDrJJ+?*׀>Qs͒բ#&!|c 2 ´2<#;ҥ70!;_ :'+\P] `$~k`)LZp"Uk3 %U\]`P^͔rk+pj he C)Ku1W7,?W0C~q:5W5b,U &|7#=?VҡC&>!2͌tU\`$:!L~Hj_g.t9cCܿH@ YLdr?v<8<80`.4E|O@ʨҼLa,E fĀ۷_gDZZlpEůMn| "z^g5VjA3v'. ts34[z,[NyR) Wh$ Yh__ߑR+bh[JB?#?PV얤I-$. z6&ȟ.|GJHH履:=hDN 6136;ooƿ6\ &v=o ~A p!!It7xh\ܺ8qo"UVj^q?v6\]lWv$e! <a PKK"u^֒jd:a쎍ƛ7oFj=j3s,kVX xl՞gCuh{I 7ώx"@PJJvPp4NQ} "~HY0Pzhk14~Tʿ-vzpG#8:Ay4qV ӏ()2ЄZF! %wsTiIIaّЛ&/egzO4@vTL3ABloÙݚ*' q 4{R9h>R.! 8\¢VE ,os8;zX:!3`ǩkG!"@ )**/nE WNϗ!48̃+_<>YiǺ>oJXkҐhj苰ffKzLqI_|Y rھYu) :g00RsKuhbbdDD^qڿ98;ЇM㼳"m,H;;PY qdmct;DgO8eDD &],O6! |"9֤"#==,ɲ@ŘF9*(Mj:`M*xƓUܹ:붪o7y7L39gʋ@ڤ$31H|ás*7~_jծ< / #㩼|sIOWA)%E[***!=1 ȍ5zS]o-Ќ n#&)u= @=j]K[7E jbJdP2F%%obN4WV;( R CfIXN!A`ʘUO\C&͞M<Nj2޾Eg E#|V*MZeϟEfy3#fp àud.tj0TmwV4/Ç׍\|0+e+s%4_/&#AS՜iBB]{8] LkZL#SE%qeJ$bԑ/"$. ql6]YƂ^;߅^m|̷?34g>λcVհMV95fXN+1FFgeBpmc4D 65hgdggKn<4xH>OٕJNNNQ "&ֵ8!f6#w@2qtzd tϪ`B"LYz;'kgbpwwޚcqPCAt9$!~#B6d!B""(H^0i/6؛Vkyz ҧ! #_MݻwULJDB"E&P 8/T%١cD0m؄؀_|Vگ5$W@T:}@P)wmۭMp/gٮMFMqՐDFH!$*{8#d9~~~ =EzaI;s̳gh8v=b~Gz9Sy===.5+^J\<º'얓Uú@~_mjq;38$`cٹue!dh $Jꓘ) HR/4ip6RQ$ږ ~!$\Pk H?nlog1$ ADy^P{8{#]j@rJʬ\Ë~͞lkk""%*N ?漙[HPD K,\xIGG͛M 9&}yfTJJ*ɽadR  uIĮ¥)׮ P 塜Vbfiэ_CCQ;e-JHȬŰ;*-2k""B@xղ3-(`*n9~.tt7*$jM Z_`\ܟ]D[(((422t f#*-vP݁]yQ] ZB##M#C<-0ҫ_I+`k'{Ζ6.9-=AtQ OVɥ$]GखQGpױ IEaAYYY0ܯD#H⢯AgC..޲Pr2тM5΁7p^- P)O K4C΂-ҰjL0ۜn^kU[TTTq-'z bHRPPq1CS.QλW-O_4-E+!{%9_}{ 6%8*q"!'"4OV6L (ozt\"5fL W 0I\\͝~ }iejl aaw"#V;d}D\ɩ7R͂v #p;p?Rߚh1a+GEINa]ho>'dBZM9ă+Øφ\Ng^ 0 V8& \ |lyⓅIH3Y|7fе31TъHFݖ͙_>`T{:{e\S W LN۷ouuB+Sf?\RLp_|F\\&=n.) j}/k[c}դS5 '7M (zɇcMq9qze'l";&Pj>Ԉ͙V$hzz 0JO YXnmyH$Ѣ"M/6k̇} _ZhTJRXO/'@@pvi=;041.>^AC4egEM~AA>;N+Y#k>j>lG+kk~{Ҥ=;.yaeW,dPijz_+PTړAds*Q!0:\Ⲟ2.WC+u;@ݥAi[do.=q411q7E֮3G0(0v_X04q0) '}"[B@Z iqG(%+1hczSˆ8ן_&@lf7 &F<'AHZ_Tao ?/t?rp0LtE6wgB&.#A;k?*{OlNшAp7=Ѵ2=<<2TV*xoi%СCeλ4pa0ni K[x7r2 ӮrFA s:kHx;Yxrs8OW֖ݻ/kR > 5iKXD|jF ?K:z+ '!藜ahwzZ 3c%!##}ʸ+U1nOչRSJi=ӂ-gmmm5v֎ׯ֓I֧ʆ4(>X FVmu„y'J5!<*VhtG &!ȴ/[M[To`\%mp1'I%棤\.:ux^AC21(N!KK\žPK5Zg^35b.yq{krnܞB]L*rjw6?XmH3ڻE iqt]6]KQ-<cXXvyʒ1)wZ;ӧOU[O eczAۂG뵺C%~G1ꦡ%m2;rNOSwvtzvtu.-M Fi5QyS+{(MuL' {RrUOxMDARDh8h\\oă-#Yx).q0^PxQ*ܟLer"[Fjv9$7Lk0H:QBne<ч֠?n)9_;`Rd-P QO_ Qc[pn^Ąu,,,j::TY|P'ʵ_@"T%`I˳qtnatr{0xvHve {1HXaM%2ܦw-B)ިfL݌{WWWV'c##c$D?δuʵ6e+?8 sb^߇ }Q\~T:ȹrFY63þK,F \+4cƽIJz2mmd119x[KJdF>U\6ɹu%zNT gku=6wwӮPM"7EŻ33W=W& =!؋NƷkϪ;O6rpv?~z۷ [l1eY'kE"4QNK[irOCa 8-ԨIc藺|Kt C$Ǐ#su@ozm|3 :A߿Y=[xbi (\qj?M *" mlox UJnV GDB*Dzz| > _$ {ŲSu!knΛըq5oXBd0lBu] `, QY^٨'e%n}IK{yۏ \ R+$ծ4, xV@08F@cf-h\C!-$!(a՟(,ket߼$𷡌v/%K"}i*pkqF7ǁ8D(EElxlbתrT0WB |JIoRIh+W]aҔ㫌nk/C9Ǧ"4 [EW'.pplEDgg`S0>P '{{@uY*{}V-U8;~nGi@:YQb"t.cx2 f@[q&),a\I]8](2V@؛,[ގn``^xxF=MADJ /6 سEPT0I,­* x{@,(- dq(&nI=lQ,e\; oh Ez 0IWAA"V.TDhưc5fc+pǗ@,<88 Y"m6eeGۆ.0 Gˡ>pOJ@:`]ə Hwb\Y<䝏W*'Vx ny{]8<(f}Sq/v{޽wO}5.8pze5@~r̆sxBjT\3RRS5ݴf[q<ұW EDE_ˡiD@T5·#B$zzz`C^Z7p"n_PMe+tRzH'*b뙚5Vj)lp4f`"~T4,"YYLIsEN0/V ӢJ]Ҥ4-@3$E_! 7 %%g?[DK##jk= еx!}B>ڎe_uPVF#'O6bHreXĘP6sg\X0N6:ki݄:@$*`P >< {@k@'Vn܀ყѠ {G^IMM)9{AnNYNDYgf5I䝰dä#KaΫhPf)&</̠oDu<^'''@T4@٘xIO |} wœ&R$houD3~HEv~Ik N 0#&aIcYNLa> vIEEwʭu /sB#(\Ob{>dId $turH~HJh(c^T'+ak&đ $.pF&SWcGBR[{&\ZE5ݻVlzler³U RA>]\jp|J96s8Y'+Eiqi.#&VJِSrC}vqWNϕ!NxںG׵uƥe{Sih@^Ra01.J10>>~hl;y[@. m4ttMVpK$#0 xMTBD$%h|E q))`lB#, ٸk Y>o5 !;?Vdpo7i r] }iIO&U1}_x3 )Նpoh:7iWc`6÷q>[+~m.9E9O@@xD[+)%l1GPϟ?'0`^g\;T'A'`C/C)+w~9*t#4G+Ϋ lu, ^o i? |$R\ELrmx\+j^eZp{S$Oplw6RwH #d{t__!,*xԽ &MNG21p9n8,|4t&>,>܀Lt}.H)J1{AKٗwTo>Ujc}( edtN/~ZHWx%r&g))/~&IܖUyxo}ɕa޵{~Ե;κۥ`xѸk萄A{blL8 & W߿<5$$dcx|>NXCnD#v p A`IF8H}ݥy:կ@qxG 16;* |⼻HaD~߄@fynf{&Mgy<HF%@``~K]K FaFq?'zz&41>#=S!=jd|vɭҩeej4[CV)¦ammzz**>42z @,d"bJ㓽q?R! "N- `*\ @$wgMhlcTBr~+흝wxyy}?|~t;|ճ%p}n$+kųxBRqkp7'6&F#lbKc `qT$} ܷh-ީ}xЊ1{8>8X{L /Og<"nwutw_ijmݭfwm,'vJ^znYw؉e^][#iW]$MlyjrG !oC:J-קD 3u KKKu)mC$|I/@ENN {%%z%\K{D˫I /7MϏ GO9T.:j诨:lysE%f4X^"l'&9LzN^(Z],>U54hHIKr[i^sT[7N)<>ǯcywbcc`h ]UTUN0܊lr[7RqrrzaeŘ,s &s3' .~& bݖ B!Ჿ”]wPE$B֠c˕>X+rusˢDusn܋>\aC(c¡,{8wZt >O#!tSrGEV15iU,Y2Oͤ""N3VzVVA0/FAqt*W\*fP!Fx!<#`lJr ̰AgMVYyg1Q/d16,B2@:ڼ+G&ͪSn8/&Z8TbY\3Э-Lq|oO12:CZPP ?Sc -[Y@&Z ݭ[X@b ElhF\W,6r(nf9 dތo1Tۥ?Q[98\فZ#~gZ;?LKxEk뻫2̲noj8rK$.]Z字W>4`!ӵզ555'Cz[kkZZZZt~1 1:Jko<J x" -WƃSȓ %%} ݫuVOG fĆ4Y$Td@ Vч*RR' z%R% Ϟ=7mN:#0=Ӝj 7V+ީVSg]RK<pީfG\Ddd' Ieegg[K .]_HںӒSL@?mXBJ[@# \\\6ww; x(r@v^\!HtgNC$SH-/_T7 xN ͆s3j_S~(LNM-A >[M](:2XOY4 ò؅eS> ۸ v)-++C-]JRRj`q3OYzpC_~fi n9mf8<+%ͮznHɓi7~5.tYN;[-Z"0r;T>oQ׌F3 'U쌦b8e~yr ARRFq}__߀{9k( r+O5A R@6vRumbv p[ksf ^uǛ-#WN9ө={N'CW*U(3Ȁ&;d'eK^I6^|w5^w3t$f"O} q%RQJ7mKPzEBEǂOr_.YZ ЎHDy%c^ϟL| zs~yz5ehjⓘ*qsv8u3_pa쌠DOѣGQY awa?/fan]+SI|<-ʇjg/"X5NC9zLe- yl4 !p3ūrۚIxۣ]r9:aϻ5b⣢ e^*<}G_~KhkPP_:+vg aVC]k6HHI܅6jb Dx<,cIERDYYlX۷o2 (T5F_B2zhnݻAiyyy_wq5$GF3ps,&优*J-,/9SGο|9ˆ/%y6t55@X3c9l ha1ly>BHBn5$[RRҷUIII܇zj$ڵU ޙlMAi,c'U|5{N%VҐ1}-?ޜ226deee܆GQa=(Yc%)ArxM% I444(WvsߐGp_QQU3-G/@~-[ ƫ++- ]WPP8v4˪E>~qv?)kP/fofR͓XN:re~5mއ> ,]1!(ޫ2Wh]Kxz:8hyrRmXK${ f@hrVlr:шw`LIg;rO_azTtgHmAr6%"z_Cg=hM$4uߏ5Dh-󡒭jDR1yGoMwOIIg1JQiIx;.}t Mo[\ndҁK.aWA:\3[F.D۾K; 9}gh=(jǓLS3WGFF:q Q3.D1/x,}" w)V\w,/vݻHE rBU* ?|I%;s&v *FCCBsaa+3yu7+}$*f晟Zeua2Ѽ-%.Ryn9^,upwEM!8,r^s{8arl|rrx`e| 1~ Nz 0҄K2<(U{쬐;{F{x 2JHJ׼RNo)@&%lҲ2~z%JZ%/DJyR7o"ءqppHm|XBS;47\"ՀRj{B Y9r{nTx?|?~|! o>&B i_$$=5LxǏWVWXx~L[î ǹ2E>e°N>w*Y}k9mV(;AJ㽁O;2 QH7[@ <<'^;{@eC//mkmA/T56`ҨC"n nHK_SV&Trsreb:t>_ i{TK(OX{ ^}4 (Z<Bͨݗ2J=;m#I+쒯%h{ӟG._wPDMYj(̺SbI-à%@֣iA 8sjk6u/x渨:#"1@T&S WN)WWl/sO!k(w6cG,o)뭿@q=WݸqeΏtŋPrMsꧯE(}ʥEeЭR0~S["0.zi_5Qt[B?sю3\g>y48@M.>4e7ƪ6a ٽ^܍Iʆ|1UMOΣK f0>WnD1/PBYXY0t#L>lQ3{Z*OP%>`}%n 7nbccî$2je~щ|U!?>{~`#9vLE31d*#+RkE-JDXx=@<CTĄ䴴Qؖoܾm^z"6 |) TG"7_%Ç;0HzBjӹ#cc)4(Ѹ/)ߛ~w^u9ƴF6/'O`HNHޕCQodd$J_pn(~Ry:|ph;gA:O_?k+{^9sjLus_$$RY ϝd]7dP |\^<%L*(\`#:0޳KOlFh! xl$@6:#`'a`*D޽#̶_"Me߀H>!W-CP(.|£΢ Dɫty=k>6pɂ!:nOQT'1a/Ԁ g{)wJ߾JĽdl4Zqǁ?(~*Vٴ_=CCCwvܦUd:\8=88Mo'ޞ5GNA"&9/lWLPg =qvbV2RҢzee硡={QP ؙWd&&,7nݺ5<\ШjjS|*";:_~kuuGz:C 65@>JXO`4*/Mbx>'Q*Δ ^9w풂^t!4ןy`S|Y], 6'>q(أM@C:TAGd22q&t__,dsЈ{%A&ZSP}bBmmm %srSOpdpT aV:ծx-EUH^If=E󳵾 &ۑlBTdwNϵcgΜVhp 52 mW(ܔ`kkoVd}Ua&|_QQ1ۼq*5шþH0( ejb44&&MBtᗢ<:tηs,AENt̏yϝ9A=AQ.TnRR !x|siDIW-fo aRS(W1غ+網zz..D\ΜwmInjLLOt>}*!ػ~WRB]p =jYcЅ3Ǧ+;{Y_B--J%)|``9x:  ~yyٜyc^^ύYύr' V45CE#wZ¾ `Œ9gSKJQ]=E ]Y^E&镵:aIB*xzzr񝢥5,u߃n؝o5 w| .pe+ٮw2^Ϻ" s*|≇;;2vm0Ef7o8HS}}fQ]Ko2kck2ߣ7Xf >sռCFZX]^^X/^.z<733sʛ)E*3L0;kBy,ܶGĦnNf7 %}rXUGGW~e Ĥs.(ژPۇ_cc\c KKP!}KmXU˺*Nw9;d6vkZ-RǬy(Xz½Mjjjb8!MTspekR-[бg);;AHH1 *ގQk"$.{aXCCvS }WruM+qj+z̐ĜFV 1 F:ko#*pǎxC !'w#hgm0Uy\.X  J $%'WӏyJUk0YtA\AE?7 P?KS"Yۃ_1yCˡ'V5ǰwo> HBRԤ:iW_b:/˭_H|nkSb,ٱ:ӪI/6 X=_=[h$ s3f[^] ''GE=Pu"ʳ B l]97w!##ANϹl va9ܩ!9zׂ8BfoJŢd*8KZII==EvtXEO=+Do+f>LBfd|\}AF^><Ս -Ty۱oބ)? {`ţ UjB// ,*k?q,X!!tϩ8QM@2PSC!L?!Dgq&MA^hD02g])sxb"깺?)gNKK0?PR>)֛.bҰ`?'J r|U Kg觱 [|gff V rU/Dq®.\@qd(izlmٖ,(,asdP! zVVVޥ@FFF϶!ʙ{1[l(z7_2_n7{sycdqt>ʆ>ac+&M9ّ9kLzCg\:|DM~U!DK泥+Czf-+u=]9[]ҋ('t|RPSP/+/УW}UH[ݶKǭbw &PIYY]@CMbb6ho$jii2iU5'(hrr]q*~/%;AvZУonT6$#DtCXg\Wf*Qa*/DHcx-B w,٨3|y 42G;,LMM;Q&w(wJl_]03޳ؾ8M+KK9R*Nn)Ć>}zpowdO^Z .Ý-DNI1sȜAQjj?n,,,d8_n+@^D/jJY?'%}r?s?QK3H>!Lk ))6 "4˟Evcvw\ܾ"NַmRjjZ+`7 ygc4楚Ge#91lc:61F3*}}PjAy7eŽ]]$J{OfQ:5\̄0r?[-gCPA@O_ Ii801Unޕy L} : .]\Jĝ F~3VD1gwϯ\y˒Z?.9cNTQNt~$i iaF!4 fH _ŋC[hgDd4K'%Q##;t+AA@GNUUc_u+U.~x#:JtGpL~_e}FDMFF*/az&*8ʁjiiis+;l`W>(V&W&?Wf3.4tv RdƸ \]]88HsɨP40ȅJDgf0d lڠ~7v+$OMud!$rv/z4ذ"G2Ā]G7|A98/Gy܇@x\up(P"q/tԨvSY|9 I*);3U_="of8] Z7\?wȑ#xnAL[뫟% +.[.p92n46cO>+J$ cw w'$`s>1ajNXCJ/G׈11QȐo]pR1_Ĉ(\$%Vn4.(a]|O@1TU/z?GTcCs"yyEDDPt F,??e}]FQ7h~P!3G<==A~IQq<`a)ykׇpQQ긡 ^SA4/nZH@Fb\~jˡ LaTQ̌* Z\l('˶5Rm͖Vtpo*_u'o$!w_Nm \aB+Db ϝ; JKW̻e0$OOIjɹ-ElMK+]&'*z|{㿠^cʦyN6A$kqֶ6z5De;999(昰C)w+й T&|8..){oom?L(@[::[PvWMMY]&'s[*@'o~&ѾƼSbωT¤k?b|a%e?FY P<*jL J&x~>8]3a0<Yq#seCu4EZߖ;d 8(1, |_-I *z?0AuԊh?o_P;{mmͪkaٽˎP?/1Į[ G.Pk GJ}iЋʶ62"%`OtB`iD!K)Q~Z8rE2ӕ,{=+=@W"v?QpF.'z#Ho%PDD\_N }$@ CWl9]]]Gxh:A@)ng[RPKdDN4.5)ޡ]}bαU$ѭ= qʼnm/NŇ/i> ;[<4 "ս;`x!ΫhPYBnnRtݲNXWM-q³Dgx$T؎S5\:^ZZ__c쑰INMczU2`M'"gL( ;zNmkFO!N4|zs lMpu^@ؐprtLVVV7*p+* gG /~ԒҊA)PRvq⥊olo^|rbi aU(5..>lov#^lX H { Kew>"A1=&5zۮj0gB tb**QkC𰎎/l ?TC]Qj'&%T4IZ|y]@-9J' "GuMtC KWVT"WAv #77w(WM"5|5| 4:II JXpӺG2qGc =1FD#7Yt[}  뢜B2jlvbLa&GIQBu꠱atvndn+e!,vT(jF \FQF Z;(T׹VeCmf8m.2ҋ0~!*^}5wNՆlj|,wGdJbo23{>lqzڗ?v<41׵MvI;ݛ|o]I1@| }wn|j4 n[M/zם"TzG>LeeeeWdXz9ߋ < O5&֜ƬV8^e?3o?;Z^ % "bƶקs+bvvy%顢$5de_i_y9m^rlB2KL~GBA )- Kڅn^1)Qv l$'??(mN@cΧ.R /Jz? "-㶍~cZlH뽉BQl!zN+LyҵbPD?Ʒ,5V06Wk&B0^ `UXVfURWV/f9`8xŨ% ̮dpWN  6բV̖x#UB2fE.?h&[8 SUS^g.uG![(**W5t{`kwb҂.K,xBɼLing_3?s%n+C z~j"p8AތV̀`-aN҃/.t2ܲ~Xj+ΥײԹO%}3t*8XjWAYϫ'rz[Қ Jv&#w E,y C>D_ϥ4&ћ,5'e~kq|L PX2l!n.K=iD]waB8YK8uou^.uԌ,(nqK:M6y'jߌء.^|u=C E7<Rb;v4{'>+b9\}FCCX[{yK u xÇr22 ˮby=^ff6798{TygKϳsb#cR.KgCq8κ([8f$a3E;N[rDVZl$f<i9„2'6羢>fMG|٘6VNH)^NoOSa+5A<6R|ޕ>FIJ*x@[=<懬#CC?xAQ\Th \un8cev{nB#=Ԕ ѓ'OK6DPf(|17PajI /ny%ʴ:RdYe&|@H|iq u<==JTGyW: p{|Px%5љ9# "&.\8`Z(8BlȯZi ^^`iQ 5ǩNYjEpF"6zCq5WZ5{NٟkvԈ2^x+W)7,PaSLN5Ե̓ r,Ng-¨V-P:7fdיw^^|tiץGֲ>; bUs.gϒ5G֓u*Rqdsl{pS/MEVPpi^B %|L| d>ZIm:#0Ṭ\'c0|||6Fv0tUUU` ՄUn0q6`5'u]Dt~QDMkM'FE~Bj2M4{e AY G1y)9YсHwgދ IxC [|P!ܴ8ѭaFr=ؐ6ey{}KnCJJ۷'k8 ނRN>2!QX: &,N3 P:o+v{rOOMQ]6 IdRxuLϐP#g X)PSFn8 )׉Q/EWGK^=7EEEeJ19)ùi>3}4sa``eĵXaN "EEE<7@׏1ZzEXdLCx󜜜3W%CwB",VQ8odb²"<- VTTTd3ѥs%Q5sNeVzٰTn0z Un-Y~שtif IShmN l0fEޘ| ͽƵjk뒓;);M[2W|2M=.M0ݓ'z.xsK"ӧP$Eo+Kvjr$dG+[ѭ;գˮW~5K|r3bGenY~rJש:-RL!>bx|btN|yF#9py6Eςs:Iy8nl-̦ġG&5]ɫ''Dr1[t\9Wk~z :q(+: ޤ.EYAxh9{ֽҞ_çH106,um #g2MW՚O~^.sCoc7z_dJptBiOqpB(*^C̗`P<5KK{ޥ2'xrLtffTGVOkJ▭ȕw]feF~~p.o!f1D瞥%{Ty۱G/:FY7X%@5t/P0(LZZӪcxb)F5AC7-tRS4MfĈihbQzfYɹh%~T$G֭vv$o8_O.&J%VRR株zrJCمVToJfP%G:W24y+nm›Q-#PC_Mڣ LB]7OV,~ I-IhZA arbBWPv^}`3:>UkUNܾGa/RP O$DHXeX&_(AHHe/G A5:UsOC}o4ѕK+ zg=~5;y:LAk`|TGcMjnKYZ|%&̶pw(TQ ^%C|rSSftKg&Ц/ {-ڐH2=ZlD xYp 0֫/_4߻"ztDd(>R$g3=yHXFb]C<(NnENN޼+'fAFwƾa闻p@vfk{/)-^av2:Orkqݳx"?x6xF~}â DjhT"&E;+Xľa/TvmIlǃܚVNqcQ3'ڡwQǖ!!R?8RQLү_ã_AJ/wj(dYƦ8aZgS~PFo+o`t֛7YYYM)SEUܺZ"k?f:,ULMMr"ir~,) jeѺh|e #bнNCw}]|j CԄ+F%ra_c@d65CAHR₶?PRH Kr9,,m-SchƚA$c?"v=_o<";3wwUs=; sٽ/GN$xN6өPؐwhݶgZ $ <c3zY9c[[ɷ1;f.UUUeoۮ}93Zo*4~egr_ƻG؛8 3S?Zy(0,{p=z2R?F x`!7K;;3]I՟9W^y9tOZ :ANB'ל*ǹJVN@Hi{'`#s))(LV ^%67_S !.t[w|KL΁ Pr9yyCCs=Lꂃ 6 =Q<Nc矕^AVZ<ԣҲ446(wߘAZ]u^ulcf)nЯA#[sHπ#yqkC?+r:u(LTVV2jJnhzfg:N8(P;%9>Wq6EQtT\\-$YtUce˗aVVVϞhZTQV #"W gGjr3͢1c'OUo !qɑon2120DWzl }{5.6004z<])E|uM^Zʖʟ?|ڎS3a_87oe8hSinڷ;cy|/x K3@;G8 y7vB-\5_KШ !Qsy zkũ6RZs:gg~- xllL!&ODz: Xls` j%UFj8 QUكіHkb%%\h6oxu"8{II|(tiPЗ0fTn^C;*qE!#+}־mlA5 j3ďMsm ]o*zi@~5B >yfZ59XAGTmhfs=O\Crn`ee%56s_/6=w\7<* 5^///?ުݘL(QRi[* pK?i_mm>"|@_^6@ _Uk93!!)YYU_ d8b籱AοJyA-5e#Cact=] Kp> "jU,sO7'|uxٙ{߆}{4ߎhskKIYΜo}%{Vل*ia J:wJaZff pGGҢ~S[KamQ>\\SQ2~l.j7c筸ݲ*jEVEO]й*&dyRCu|Zl' ;ٗ#OD+7/50`XǰfOVH }>ݐ|;s*dM?C=y 7q"">fff<GZ\.]:/]>ϡ`,uaaj \ j"첄CPdZ89ZI!n@x(>vi$2fTCx uWfh vKS35;\" *|DW,u5h!'=T?{C y~p[QCj}o HuY=7* SbGFoe2>1Ѻv[C"6Ѽ,+?IIW-D"Qٚ'| 3;k`d~!iZ0qYeEy Tta8oXsX.4YeSS+Uvc_ҥҊLO*;Ό⛺qe('p4: lMS`bbbdbz`D+\ _s?!ԵC~O)}Cr(ABo'0uZ|C1 xn+#G .FWrQVQymw7ILSei!(~^/`y7{zoZU+JEt.Z>͢ ,j_mǡz`1q444E=Wd0Ƙ%2w+s}-@'"7?$=}-ؑ#J1){f\VѥהgM`(`G)$}3220}e\޵ѾkXI˚٢U US(yKѫ[w 8<{OD8xЗrSi5UbTx\WAgP[p #|9X"fHpQNIL 5O*n߈E6=w! }ƙz.yEB#EW0_K~*ť?(⌊fz=re?hS~eB8!x8dkC2!:E/CvkhU^fƧwsx*W߮&Lc?-!6q, ͅOCkW,89 Y썙fٞ+.q'xl|f9OS+lfgkH\X.uy٪p%O~QyVOf"Z<0_Ni}M Zk/gRdX)Nw/C a|F`Pz ӄy!CCC/y4ZqH*  >?!m<)BtgG: U D 3}Pzyo +>Pco8-(W2дk^"j={IN #Nklǖ3_\[xT))DSwP ^inErW\d\?AXۤweY u1 C_e%tԞp}[~M &4_]ib߾c g7;Ǘl/xWփ&H Y\5O8qVЎ3?X&; s`?mZړnqʆv˙9P{G@CczYȰ֭w|9sبDU咣=/b=T,B.#CHMkw\hަY{UjByX T:?{IIkZ|11+e{k GD#)yװ5oBJZ)C##B\RptB[2ss+k Е7Z}lѢg&bW3 ^_tqqy{wʥD)(d k 5lX̅*Y>n&+ϟJ*_ 8v+"-ee/p@.Z[[n9ŨoFv(fE8%CO>Rh t 4 "Nh|"``qssi($i%܇}b?`)bt~eTNeKj::FIhlo>Rk@ygG˷?K񏒲hywO5u]a-,Gh񹥤4q--@Sgd;jH7Px[Vmc~_n'Ϟ21eh>&~Y};z2@'ջ;.h!y_x:Q>`/-L, 1Seˁ*Gc'?#%j3z}>ŤxTojOq&CRш?- Wq]>fV?: Dsҵ)SB5x3{KߛPֈ 2އZa]^#Av ";⼼V,TheoZ~v xpy?:: 5gVРAͭSVbGWN{OyU8zn7=4BHVDU3">  ,Q;2ṚU'VQ]:JԲVhKhx1["5w[wvaǜXWdq޷pxzzWqi fQ< [ӓV?1Uo^':nٱb,ʺԟKP]KQ @YWWW,W@Dg7LB!Y[sEgƾj߿3c#Aw@\k_x'/>-mN,DG!h4 !0~~~11o.  Nvvk_:!5hޣ{mw@ IU!}U,~%fnZiNp@-ϳ܆ {ljKdsk+5E߾%[m])2gh Aٝ\.\LE ޝ484Gt*rdk~)wk?XDR}}L^kzrrgK -GDy|555z'LE!...** h8/1-5[M(aO4Ap \bZbVn1ӓ};i{I# hWzN 9ۓs3rsYZ6 /2kjnK6W*/,+3SfNF;)V  #w8x*;?flME_hp]#xO%y3I5NW p AJN~O{s^}̒{:6bT ŀ/i o]X+ꡫ,~ =Wו@v`W%{l&koo 1 L܋ZU.!A%҉ڧGQﺒzTaN 򵵵vhOSa-==v-I+4*3a [^7sh+*.@t}ta:jGxOc`1L>^8\r/gffbRRyElR8[dIi@z7q7>j~!|3P]ϭo>THi ܁ZN۸ O,rRVYY[;kkO?Hxgs1E&"җZ8WKy>y3gTԗW'l-?_DݏJvrUoW, B**(J09;̕jhh6@Q}}}t ?j9i_ 9 BOPeeɧ%{{psq%z(iڃ r8Gz7rmһy?o8&{&'"#陝B[/\cYS/yi1vRRp4lZ蔕є`t &<&c\GC>@"shx؂ׯ@Pc<&Žac_,r\)10}cꉢË݂0KYP7Gvg#. {2 [؉k)nVϙ8<9uCmB:Վ719I*ݰ|p:T+a $41BBP/BCCl#;9{Ņ(޷rɐY="fWo>*(Ȱ:X*A;EEEÙ(=}Na{˭^fA?h@Yf״ifC6q,ϏV ~j_7w| RQc[+=zR!a 9/z/@r* T}7hmqm2vw~ nCdBq̐ӧ0???73?~`8 ??Á̋kN `21,%%šcde-4 qtG>xK#]\ƷFJF!aar7b]W L$%SfC,-ߞѽTߨSyNQS #`; *UtY 1XCtLƽ,[ZA9sb.zhy`kh{Y@m;#.JMgəg陘)#aJUfwVI{lwq_/ČMN>JQҪy~="1ӗ0|4`YCڈl?1A18/s8w=b&d!Jr-{秖/{~F(!n'͌OL<?ۛH}{C@AnA7ȯ2^Rd`R RG+؋hڨ+ss. F-g&z S):X=M!Tc/n>!oR"xxxw.!]>cF\ peD§y.*\5^&A`FиM˪(n}~8F'6F )&\AiGPg>~yxyaf?!?%/SIֱJ"L^ZnRTehƺm.A)d%opIOi_L7;>ؘefyÀԃb-meK{U+?~|2 ᷤۿFI9>Bco /\' SrO$AػzfP4:"z24,$S?xWjJrT\8x+qIM.trb0**JzkOt JY &CXǏ9f?bW:&mt 0~ ɭ0\^Q$;Qc?Ku` $DL+<~wZr =v |,ړ1$|虜|2-u^TISR+(ZVgqgwD #3*H1|ZW'5E_f7q4aYAF)ܿ"@jibwRh^/9ə"DV(\]j/M>kQ*0Õ"Y,[.\ژIбy0'?Rr|PIjb'2"5'֡!J$(H}IEb@4Ra$w^=mMpxɦ1³m< nmy&_qa6JՙϭhE C8 CHGN0I1ecH 7"],T#*ޟ@0\J $d@Ha&y1OLEN337m^55C7r{1%ee]Zot:@HSѹ);<-]pXXp}K׎.y[/o=OKp MILJLLLã"&F|V.~|q6c:o܁):p[W$(krǴչ{FF Ôn:OKGJMM\FW7wusuWqR;M_AA7u}} bbtcbbmUщe^Z"tQqT{W5Xd.!ﴙgbccA7NPYodvul&J?t]HF*8F-*=ɂԄz3qRDT#ēéFIp~DD?pO9PKAd}?;;;*項@1&Z^Nbi/^DzrUua! }nӴ/lCW9v4#b˞/fFgɊ̦vU\*4#.*+0&e1˅D/Z9xK( 7ؾ Nޫ?XƤi5\u()KbllF7>|]]ԓRCOh(؆Jqrr" WmT#??h~dYYqX~2Г.9䔖>.q=·gyao)<9-51\dd|0T {] c;z\? l'a0͟[ue#?}~ܴ:&ih;[}b)J!]L!cgW=} #ZZ.SΟ={ Y_l~8SnDLIDyyT )xwV|÷d@$KG 2 "Nmw0*d_j(5B-UI㹸le\سVcu6 z.@L|uYPg7",y]G0E9{KNٛ7o6aClJ&P^ho: kݧ``Qk `^{^h7೧'muj)qO}#'&'2e T|decS??{0Λu&"" b~N"$f< FƧd}uXةP0bot5f^R]j еV 1=x,B )|슔grH1"UYᇿF'$ 7Þ ]B|pi,os4~÷wԛbbg e-N'[&oKKԁq< 5p8WQaϣco؇! '/BB{zb%ݞiC'N!R,qi_j-]9|ę5Bqo ]6Ϯ% r^M1GAAQѡ PPE}1|0 ju|\om11vjV@cssl'++pfؕb>H:%|r?Afg xY;8>;EDO$03 O >|pz~i!Ð]ۗOD"rfWwS\(>eGv p0T)$Ptbʥ7,kxs^ dx?p@()=5_G~dQKOLN.V tOnsխlk{C'jh-O~f[݃R2h/3ҨgF34Zsa 3~J#&|Jh֝8! ꠛx441=7)p4͢Z/&{ 'vTD{exP7yՕs5۫cH9,~Л2\EȁprYpݻ3_qKN@BΚ)~/6.u¡mR*wY{ UcbZ1rtMSJNȚ%$Y`bs+>77g~,NCO/[QDFuʈK,GyLŕ(uD7߈fvKSR`VͅNL+v&zInݭl(>c*.9#Di3P1c ϥ 3֯&̘ >=dP/&s8r$5SSf<r,Wpt:@Tti9== 'Ty$r*ù+kBPaAwӼU#'UOﭞV `2Ghvt| .a 7AGn_>Pz9tg8sf3X.Z[~%VNщr|6,&F; dg_߮!͟8xzvԻ> 4R{! fqJ^K_$&!KD:gUe!!kNُ=`"&:~RjjgΜA 稷%K?sT00Naa$wjJk!}& A5.T`i5#r~M%0wd:<x?Xjfsv2,?pP7+f!:~~M_bO@ϹKcbwuf)!/UԢoBU #k`;xIÛK-,˯?o7 "sY{ګIZQf&L1HjiLtY۹p!QQL$~jb>|g=ZZzc9z%8W0)qqs*"&[`Ǿo ]u,+h>ˌ!qS%׬kMS 6FUmb!p5lOv^ٜ?{{l ( s'~_+H{5N-#6<:uі"\)xojtG >`$^j3")MMMLo Z›SSQMѕ> nXK?)wEd0 \7rSTTrKH!B!Iԡj7:/-9Yٴ o [Vlޗd.>]_LDH!64SZ^kUxї٬^%BlЅj">ɡ-Qᐃ!qĔRt Sx tl}5AzǹM/CIk5nSzܽgQ$"᝹ٰvVH0b22Kfݬ( ohl>-ʍwb@iO\G~Ϧ?g|4D?)y#. Wvb}i"Mf|N_.`JQXE!K8L2Tf+g9$[Tԡ(GwpeFWO>teD'HTJv_9jYQ1 bASP%͎BmAYuúAp9:Acߏ)0q.γm>L3? X:=WMQ=_ P):VU9i,wdΫw7d[` ...I7p>.aG9"@C/l>` R7',o[-@ ߥp`X  '+{ >(pq#ߏ"zFc˿O~xCtcXB՗ 'HD#Y+%`vzK,Pa 𔹔͗E5sFzTgE>B(xn{/5N˩.׮Iaʩ-50;@‹,*[Kl-J5l]\b}yeƃ?Z뚚,ucPW釠~ }kxd9eGF+'J_c/êHB(C=RAE>v/W3 +0VwY~{8`םDLIiacꨯ2I B%Mh#?@8ӆGp}}N5z-+1>>}<aZ$|`5k;{K?Q>Ņ zNWV5 cz\a$ӣ>@0Y}\)$d[= qf&&N!}???0111BjV4aF< {86A= eO- 9x [~UhI٨eސi ڣ>YYYEZH< _IC)x19ypeY;՜T%ͨݹ)ZS 턯bOcqy1 U`痷(+5Mz&)8։2K5>iLGi08tl jĤ(#>٬JWO~8>DItCmԚ xoJl7~kN[pogBK]Y.іLYxR8lyNN"vvv^xhaQr?8gdlJ3jcD/ip'D}}!Qj[{,YG^K^b#a/R*px4D7inpi`QnoQ<Vui ;Ҝ?h'He@7^?{qA"I}_E<% :.ed3ޓ<0_ʞ]PpAPܞOҖrS%"f>\ye-~uu'UTC'>H>?Ϲh5xL$ĨS>K#TY=< ߿?tpۄ铤᧣l< ??Gw8x႐/6*lOkJX {׎PmJI7{8mm-oΙ˧A~paD[! F+kccS60?&sR"-x)F8%ݠZh֛op?dYMjf6i݇鹭&6 [Ƕ[ #[dv4o!b'kӎ鶉l(ag[SK4«l8[6tAB%joA );V`M`yK-}ljvG .. XNbfϐ~ ~]ڷ]1HbĞORjݰQ]?&ؾH]/> Mݚ&ocjm%Db999{l˘294vd X {IίntI^Ն[UlMp =ڤY뛛ڵkd\"1KS0O<33Kx@m0l}}]mEUI)v!ۆԊ3v4 `S(RPد`-|_Daޙr6,^^HY5۫EK f{'C6r;&(y0Wh4_PH^7IQu'ə <;;!R;FPw~VwM NoۉC5Ch4\4o즕BoܸzazD%6q c HP`t5xunx ǫo6u՟Ž PdGmwo1ڴxxv++~Llz&Q RC+AweYm[ joo'Zjt瘺z1@ܺ03ϮyD 4oЂ̖E^_ 8=m&;}nW9o n:FA $~~""^Qx؊?)[vTQ 6IYv*|C}o`@k B|G.]6!6/;V, }y1ֶ(guVC= +KM d/qQӳr U?d7p79(zhH:g=wl).Zq\!^?7oL p.^tv{L^6?"Gw)EcmH1bFU431g+4p\hzz LEgń-8EOg}_,6R'Mk};Dn5%V ,_{t-*<sn4,r=Վ4 ݋{P_1zHѝ`2!V9tOUP#ف$2Iq5ٶ]! r5wj8{P38ќMk"CCDr'̴/0@;Q 0&C7.{sk AtI >{.Czh0 NoWrl+E<bVf)ieD71!~2n>쨪PE{cEڤ~{BE&bbbtE1=>p4lyhhp8!֍6S-@"ѵ>=jJ@_y_F`4c{@%}ຽ;7&%nR^{Yb8f{ `)H=}(χ/߅Z|$ݻaV0w:M.|_`րFmƝt%H)V&-#?hv'Ojk%vTSEY>9\GlgŠOGjl\Eu70,s29~ ^|nكb|}NܨE<2ĿsKὤ pOZO)D>uY[kpmBH?ﴰc8<{It. U`wrs4 ij̽ WK^x7Ջ`#o~I[@ ?E>Ȗ'Uo!6[}= cL{ɕ5WE${bi>>lj{|odwJ+;YkpĉB*B[S~ZZzXi nfD̲r Pfx jͮt5^h$ejqep=h=Z@` XGK&k|xqMYH~Q[jϹ|>3+Χ,]ON23kmMXZٺ emm-'QP-b02f O{ӓa]B< <rw-YDTj0G9oOW+47Sv2Ӡq[`)Muub Ou!~baŲothnmoy%Ǐ۬/'=ݿPuyJx}]o tC/ʄ?CùYmjg{uuIgab _5U?bD15unA؈J_:uWPPQOi{TYbbFsXXYOdQʛ`*g&ͽ ڄVM1M2Q[=}^󤶆7z5oXUT^ޮP$54"RRaa =7\d$w&Y-'|^'?z8}â7%7l3uqҊmm G/%NBϹPqŊ5~3W`c/޼dPDx7 vSwl-0&zU0.f *l몬咔5uBy|fb =oޮru8ך%| K9ە}:7[;skkL]H'C Cj˻w`ph(9㊊`FfLZJ'N`8v'8"{\`[\ph(Gp>U 8ޕoi5ފtxvw=NbNʣ ͍olvϜDPl1p@MLJ_oe}"ʎ2R(eDB-2TH7gFB){S{dߛ7};}]w|Ŏ b+Θؔ#,wfzǧI1, 5[36s/Ȉ)|H//dK kLJ2Q'Lr9?UYDŽCII_wlust\Vr?tuXK9 }O*%== XlDw0*5RT e6PF owY/aڧӆhG jiz6Bp-RTxL~3MptbΆpj{C,< dLX?wZr ܿ}P?]dFDdd^_o/:㇘XLCG8a{QD nn9~z/6ԦClB0vԩ:jM[@ Fl`XӮkhWQg lˆI(kMj OA)Ct^P{EԌEtX ֐Ŋ{S{]\6wT'iw0|cfJJf`*CtM#`hOݝֿ;Mꡪ>'\J(&0þC8SRuE7!BVu<5L ޫY38p^* ft / ZvP>>$kl 5u;BN)]Y#p344Dwqȅ_>Hr$`@E;&Iaz!  ƚGX:FEF쬸ߘqwnT &Y,Ʊ_>|x%vwi ߞ%Q~1>~ܦ1)E" ͇ vD}La!999K,N2 ػ88vaT9C)**j%ڳc6鼣|ьw Bк0DŽG/-F %O/uhՎ$WcalYLi*)%VXXfR֙|$tOOOsn_#TZtvs9$=Wk@[?r(3fqNHdEj-4}VWߌm1@sՎ&Ħrće8QPO׵{[f`^S)0$B4%!))*"a-T@ 5 ?xvPl0|ANΚ;-4{rC&ff^@"aeCZ}/={5X+ 2li|O@hKٳycE⯎d}WG]g/EoE_{D {`3}=<.nU.5^ʭJ6--+&E ދdFy 7mY:$ƽO֑#;D,IE=@/o+xĎG:>sɄ"ɹU\&K1}بr cIFyU3Cnd5$[G4ifsK,p8ÃOhp5*ugZ% x,_TԐ`++:NX昊5 9^Qߟ>%"`FユKa>+} \q[!כL @̜fthinڷw^{ wa$$$J@ϝ;RtUpl|n}gOO۷u6oEvк7pYWv$%we(s $\^g e¤RgC9:e ?PZXǝno(ӠW ̎Ͱ!NF"mzRz2k?%Q%a3F?sb#9Uӟ ŷ85@w8'wӊ]LijJ@׬.8Tq5Z"m=ۖ1 .&f}].^ u s馳 Un}UT-Ε)Ю7)EJúK `?lrmw/ yrtͲܒǦԽT`h(˲ᙕJP~RTvalb|&nb"+C>ѱ HΏ>U}=f@UUg8?NCOyY~DF\v-ً.5%2d:tжwRTFe˚ؘISiv)u\..Oss|55CN^;Z옡Uiaaqo.]oDđ"DG.RWd9z.?~*J9HK+ R'gM 65IZ[㑜<_ӽGDGG'9/m6B\?umEE5o**{GGcA6ۙ`"t ++nGoGDD((+ b"ĭ ߇ 1T=&w\4 xE}}=!zCe%@u43WUAy,z>6AA@$pKţ,2!w8Eah Hd׳cUb7!ypr9h(X\/H``Rg qE uU _9|. C6ԞE @$VQ=n‡mf$wy j}г3a܃oR}rƚJگ]RYZ_E1PNڅu -_'IHI6\FKZ%& go$E+wdgS(0#=jPaO8ٯf#U=S0+tqB |Gz9qǹ.gK7B,0^g6eZM4  |.xR7`0e(em ac^AAjzz0sr|٢++RǏ#E$rV3;;;͚YwɵrS*`oZwtJxKփ& ηj)iI[薧\Qvj(|BCiNN}/{ 2@m`.Ωg1 }(6h6k4 @`0;fQd۲VTEw<$Pk!}*`'1ov ',F2۠yWy cHYCڪ'Cvr-z&7Fnߗ=~'ydž@)׽MN7ڎFD+%舷ت!+_se20U:Lu[ME=fy"0}3:N]+@԰<==޹Q+)/_`LJ]5|jB@ IIpعGRj8g18XEAk"h;UꝜ ~œ'6'z_Y}BsdvxXA""o ̷Z. ٱΓD]vİR%-! 011"nWJKH{ ]S79J+zRYI ֹ?+_Cq98H:22*%<\?zZ_;@ST3t>CQGjV96 TD'%Pk+^EEE_W!SqQ7w44(ihWUɼx{yC9{~wa>UhLWOw;';/)5w ;)Frpr-5]_L:g3֒^RZ7.lAzkW|m *2(Ο9fBΩdu}XҏMT#e w5144ŵ]ԏ$$e$j)>U-O*iOƍ >څJAMh9hË݆9ٵ\xs^n#!.`J0WG*MzTfr RTR滍2ހ)'KOQ*\ (( FYrpK} \yzҜzIKo|-h\ ["s}4 ^F0PCudQpin}YiiE[_B]By`o+&qT* y%GisĐOG'ENj."V|UGѷT8} d~eAPXNtu4;. BǶy&kS|P1;E^MMM1Mz"8+JC{x%?3;1kc}=R^r=u ;Dbp8Dy&Ŕ6*zzN*\T/^8q OOk0dk9}_F+Κp!B' s_wmX|Eh'HP( ݨeH T0=.{{pNjgEq IʨSbj3n, w'} rfPͮ=#ܱMcƁOMfo ɠz_{mXvAsUd!:0m7n]\`{ػa:re.b}/&;2tےoJiHHsY :zAn0?F+&wkݣJ(S@Rgf*<'geA ڹ֛}FS9nS:yүׯ_!S&bm}\pw~tr3Vŵ4MJ %=43OAP޻̷^z6j;֚D XqԙxwQ>?=YO٧O/t֚VG.ZZP8+kihhYN4dž +z exoo㌨F-Wco(]au61/Lq ư=SD? bEGLIyǭ ڬ,lo6_5]EWc=n݋鴔;@'`xx'PSONN /I)iixqSlc(jRo oG$꺇eTEc=S5]ls|'RiWxѩ2! |S 'X}<<<$$$2'WM^>C}_B9/r$j5w оT{X=v\ky@ɮC3w]?0ny/HNrx;`IJZmmܵFGQa]$*5ZpҤj'`rJQcPI7斖:kliᬄܺrppSEy`z4Y_|NnmX 03i *s9(`8p!8QMu[tc{}":OWk;I>֞ /IaX&VVϢTRoQB$C ii9d/;\2< S6 1JK7EF).?K4ږ74v#^oҝ[vd^MT23 `GgmOC):?v9\sZq~Ж|("2rMx]t6 +?=2E縦 /̛4SoßHVG5[ē2,^T(^[跟.k͹ A確8V돛;ll>HiI9\4gI8Qgۜ/e͍Cf-0@䂊V2 $y|Q,Tu#]c)@yL P<2.޺ ̠ؓU2~xTֆ-%Rl=́áDpgeBV'p8(l_0JԁpqX0_χzV6_Yͷ8QQS(5>BFҏd47oqk}wκaǰ:֨m]Yd(zNNמs ZQ]#ޗ/h |`SE&8IɍUIRMivkW*=yCYl SRRaU]a5e)jT9_ 5ެQ֚III"ιvr#?2s/ސR4 2ǘ/h{-oVQӿ{`\uK}ZFy:x><&LY2L@^ŝ;G+T[Ai#O9_.bugQ?lnoC5PVQr4J4jW?>8*RmhPv$婮}$$29D߉f57? 50NC;- ]PW DR68--yi~7؝-8t\/)rRXX5>zs'(yx$l5#$6Ɐa͢E孨/6r4^ ,^b/^Xfd $Q%UjS`";>v gOmm&x`b/Ϳ;Td!!% c/@;vbqx#mon'``Q;!O_g[11\⾔η[ax51ԭ%)|N>墺-K) 鰱}td}rAu?1qquq<ӣRԼlўֺ#RڶF~w1foHԨP*O*Srd/M]cPyY93I&K>^`&zô0UjafRJ#ʜ&'RxX;C=r6k "fFjXR lgΏ`=>/- ibf `oZ}rjEka¤2xOP3:xtQD /$ΞosD OzTjNőr`NEPW L%Ϗ= 媚J«JW$9y%An$!˰K Y?;Re p0q-"C_ʢϑ^T^a`/ڑł|blP%N;L˕ٛlMq4f2{Z 6})@Rݏ{'vT=Ƴ'~ 7o*$'\9q*dzڪ<+.y vZWz bXp\T㵶\e̢fR<=pH0t84aUDQGqvq,j-zY[QZ* sB@nݩodC-tDŷ׌?c=x®薽p–(Yg|Yc׸xeєʈSݛ&@B#?GSe.S[^ڥS'h v[m:tsb1wX]b֟J3 ]t\! ܁Wd.!^YDhM{̊<'X8 a—Hd'NWX1[P3ES{̌ 5}_Zwn6{bsKSpQR0&23d1|cGCEqؕg=?yG3&e[{4yӼz*.d;)s$NIJ3 !8ZKrP+3bؖ/x?,"ז:+l74};IppH̅[y'R@Or@W]CǶZix#ӹ-}i}(jw qglŗv?AߖVg8@cZVƚ܋ԲOZJ#9c"cwih32Z2ĦtW6^`e] Gu~X nd1$Yi˯Zళcr,=jHhm;0?=٪i"p p|s]a.%(.elgQi<{|W<ajwxiFw_nody&^k4_Уx|<(!>!bϻީ;}o[˚C9#IR)yڻUQW%m|gvv1'`%xy{G?8/ev!J> 'G ЖWl }~T4\<ц}DMR_Y_F"%{ku5xv~Y_(rt˝)߅q9t'lL7rUէD׷̵>& 5 *]n^yA]xS^2X~hވk"^6!uѻ>r#5Sʇ$X>:C?ِ[p|zECfѸ*Uo^FW@=p5 zC|3~p2S%I6T8MJ-)e4<vۄ Y05 _?4 p+*{hdRQ ǭ(:쭞q_WQMZ@p @uKdij$5oMweyvsTگIٝ*xYF9n?`2Kezuv4fyF5MӀm-1=DɸWKaa&,{ U{}d* Ց ɍR𧁔o͋#SzKS?UNJZ=V/;F4 .5r#3l' 06ώLީ)|H⪍վrJ&OkB}h _x թ79ܢPn\jED:|088SD]˂KO쑼eY/Nhl ,84b7^mqKK]c[yzvys4g(I)J5 })RZҳqT=0]1з=\w 0/2|WFk 4+JjDJi HII3<+h<:RZlmj1Ic@ 2DxPӊ :8m྿˄qy\tFzTx/6s fmt,hQqRY51Chv(RTv\MU&N)0{>~j ,lxZ45P_wFpM]E喔 u8UϜpg|5v9 t3[KjTuap< B$ިKKؑ /1c?`,Y9[zfk-8a7?YSOwXKF'ca@{yr&PrNy)ǧr`^5ԑkdU~Nj_zˎ.9'xԎ D8GmzQqVBCs! B^jmz=zOyY"S֨n#[ǂ%S`snAoU=1WDϦp~[$%x({g6nSTce]sor+.Mr O'ZG;ՍNș)FkD#[^Fߟ6'Akk>7/OznsGkxL|`F? m ɯYDge];C2ppTi]WCCCջ:Q^O:9 PnٷKxy} 5,v6xJgLOOXyw{=cO[t@ϯ{ 7;OOL+UUEpvL#IP=d2 _wI5^? E  ܧ8$Emߗzom EMэآcFOejxIx66w^6\ h8ʭFĜ#뺺Xέ&q΄S:F.fjh #=<ޝX-auf[FHU+i)%7l\k26GH7c`܀ =Lϳ?42&++jG8*T3>. JzV ,z#鵡`iCAWq|B! ׂwQQu7x#꺕FY zMeq5e);f,m]1nѮkڱL: g*#Y蝅Jb̢ Z),&^_`Fgja'^[VO5PXqP=%|ʥi'~j x^6}{8$fz5 QJy>MJ*~~~NAAA`^CIAy~.B%6}#jZհϞQYTOt.5`QA`<:bb \Wekv/%q0`O*`]eA6uAT lx V%R^f g?FhsGYn:rJ絳\gd8sp>M*ҫ~bEQWy?zJDžf^8$z \C];i30 Vjt" ҈TyE٦טeRO0ҳcs`H8AAgof٘AxyI!vvfm2ЀIus̝\m~,wu-ͤYB[+! >Q{$ jŮ#npќn x^^^ip26>GYcMۍӮCG:ƐXrqr5:c|2a Ͼ?ZA@Hx#PIt;iSt^h*kF;=ǃkFo7 qqI?cb~Ctg17tf}{Li3e`fF :\TvrNJQUqX*|ebm٨0ϫIɕ6QGGʆޞ n"\`~[[h)c$KUNG' I:x73Pǥb9m wm2m.7IMe"f$u'Cѩ?ᏦLA*kډj8l1UQQQ6ާ!t+../#|#t}Oc/;LQ+ Bm*ԾB:UPQȕ؎v1Ό/o9.Իm^~?7qi_k!P_9zbŬ `(Y S= $\g`NX.k 4'{ I Rh`i7~-n$Lo%jXz:p1Lϡa`ni:ADHh{,YZNV""bRq1M_Z&6 1-,&@TK2] m~ԤS40GP՞b ]-l(תa-6ۗחoyvɑZ)-,,9Դp b`'۟.c)O%UxF):WM%tkjgŗƸ!J&BFz IY 6+_hiJX᭔Sy%ѩ-011|8Wj:T^r[4Gp8d3SuV?^Ey~U؏Bx >{{{4%r'`W*J1R,oAUor*&C|f:Tn{S&+uTjuL7]5Q6d+=Ά7ثv&78:&-m޺rkz&z.V\2hB+4nJcxKZFsq&|QQ=X0-rmr_Rv$kgC## ర! Hݺ%9keE|ܪ^&4,DފXB;Z bQFٳ{0ʪX 6v|VVwUzYx_( +|'yW_r55q}ঢ়] 8F,>!]6%G.//Slm}nSe\d$ώ_|UW hB=ª&,9/}[J&r.POhiEG; ==~Yhi7mOf|чu4RA;'8<053o-a #JI]`bOsɇus!b0' W 3XYQׄ }h;\YeƋnK;/c͗0IZ Ju^!4Nj6vH50,?p|)1GS&C'a$e s>" քS=MݨIQ5#ׯaqqhk9W)|웟ބ񰔭-Qs[NcRd6\b?d$r-v<+63iJ$KD.AL mSc kʫ ^V޻KaSFMWָ7Ic\TRV=o go#0a*㲸VMW$%. QJ6Ւ1/ei`5crl%>~q OBCGpu>j{}\d<$s) YY$9>4S㌌4O )* vflnJ?BؕNΆeYE (ߓX7(a/bm5!]pL[OvaC^LÍ/o*59og8>.nmBtBD()VLC 3#3|+*V4,*Nnnnf&@P𯞇G*EoZ!ye-ѶG {ʻw``$_X#z)IzMQSzXYWb^z|m!Gn(rddͼ3fZX:2fZR⤢gjRAH؏w/OG* 0 vECwb(_B'"?\Ent`"PɦjԂE,88NགlZ0[’ˑқe_4|3*glؤ/; $]KD"31'FV\zjXe5pB;b=0iB @;N8@';ђf"N撲SƠ~}WaXd !Rqζ5f ziGcVZfeavw)sPPh# a6:;fJk&2{7&&jxW蜻WvӕfooӸP+㝁}ԿccF3ן^_ xݽYdSΦIaZGNckc md qyE`$&'*s>$]"SG'gUlXrj[)~ ӴGrqO@/ݥIoj 8J*} >Kf) *5oB;%W Fri(m-GwG0¬\G|K"2ϼ Km8aq.mLorqg';*UYSpt{jR몙 -!!A;C'dwL,bہc `lb&xjy顁eO fH_PĹ֓Z(9r,G#ZqRQ QX6S3|6mŪ1=á52(:!$g g,l/i1ؠWYZw: mqq;im"ᵼQ.)WzMZH(~zu 0%-J -Ӆ4bGi='^gs-Q8yS>Oajّbu1%:˓gg~Wd$O;kRΜlxmm풲3'Y}{p/M !QmК'3c6x#pWu /Iː5{=Mw=Wqlyct &K׉moF/O&*GNc O/OX/_(qXUCcFlT I~ QKRjJiVPi8aH<ۇ1r|Í}6]eu#o')l W08oh1)T'ml@%3H(kRm``4l3S=4$7uʀ\a|os`|GlFJɥ5LIcWZ.%z6B#%_ %%=%3Tì\cb!a}@':̷9C++ic觧g9 JSSCiczo2n[[[n.,g~#oqasB x[,Y1O,osS5DF/*,A3_ y* :55OA^`p!ۛe ,חaMQqSGuL|=1mX>wȡ\XD&R=988,%|r?єe?,YODN<;;g1r6V||[nd؍*T岡 x=]H?Lv'e~r%7fO7h2֬\Zn\hSӡ>y=/MKOAq%tϖf ;ӭnsPZ8hQM|rIܛΘ#%,oטĩKN5#C$$vqgj;wci=H˓l(f89@@XOXqxNq.lae||<orUڽp4E seGi#W %QN񡗫CO_nb-ƇZmWI^ںTq=Woqfj̷oo{{قTxH-\[aKGL=G/NW҃Ƴ'6 |[ h !>h͆QTZV3^stb5>xf\hߘ )8 h0xpXR#~xzu"nl/W3H/.VTԐ#$ S+W׈PtP S;f\>H.T3bf2xteF :LN 9[B>Kg3 kOQRԻB\~Lx?lZa3a)(Ba7ݗ>BӤ߼KwnB) )PȠ}&.g kjj^[{<<-G7{SP0EccWRWW[od vz[K/Fɺq[ykEbgY !vo6֟1|Dj*KY B|*I6)lOp.9&k6 gi#7ႣV?!Ɉ) ~t=ƥqՅHn{"ZDnDbg]jŸ$z&vvtۗCsF\ԲW5Ho/0>RwVB 4,KSuRvx*9}i]ZZébD3ަAP>d}N;dLFj;(e psu[7OJekGq:bH䍌ǷvvWkAܑHFv&***˥uCtbϷv[zw(BⲢPj"qj#gj鬲Sk"TIl{aLPfue 3E_aԥ'OtZ鐃QIC_g˵&v%a`Z_# y>860Gj%NodSԿWٷ<O}Oiݟ,>Sn~k{]O\NK=@3{v6#]E7M<_Xv/X l6Azkc%J34Fly 3p β> 3QvO?b3O-as}CW<#ńn.yUKjGG@RED J?_SϮCD=x3 ŤJ}pßĹ bN9A%~i~3hl!ڛW.^޼O -/Ok\ *mS@dz[W ?f.껿R#6|V߾KwY6$)hiDU5Vu1cH} BkߓVU1njUgm&tt)R(BNo|LWg\cP-55,7`Xv-SvȄ֗KEXzN,3)uk~Gt4A)EeI,vQ<2w֏,-NB0=_}3*ZK)AǗa IȂ|`%Q2LvwT3+ٿDDE@``lBd{ rPx?Nt*rpJzk͌3ZwB~`qvzkVLL̦}clxP#mmxe(Aݰqʕ^HX%gzwfB@`G*GGƵn,nܳ76uUy{H3Stp,  Y!WJ|lj nmN//9^ II oƯI5ջsb4h('CT 쇙F;>9^JX F^rYOK`:g?pH\7dޣm0wIAEYcrb &x|!ɱTMN|S\Uzȋei?SގJ(|pV$&_ 0b>{)x/6 )nLيϰ!*zKxahH*`?)4Bh9ڞn+qɚah㺂`­(% %*BtHQ AA"E:Bt!{U:Bowܙ}3[f9]e#HC~JKc v;?W|9IEE{ne[ PxUX c@=OKԽ;D$ysx zIg]NR$ȇR%'ϖ5 +w9fg m"cV],u4zɵ$aWKT^q0&~v x9gHòF>-k_sNvXq?;@I3 9a[9`xhifSޥLMMc`jgCw@P!n ٣'~_pm=rr l[k]ȸn:|T)Rfe,UGBI;yхR_e>~+.Ψ<^6i3'M‘]b6w9~jG8{Ph~ :XtK-E!rٹkƨɉ.:l,kKjblSʸɿ7mx`(Qk?yM>6 AP/ٝ.XGP%$64Qy^Ŋ)42>گ_Wn |t2" `\\@kb c"s_ÏO b+MEۃt֚oFQja0U@Y U!LLdXG3¼x'y5Ş1} cz783EA߯ݛ˼?—oT8l !>U_99"=%heU@DSUFMf<9xdMɝᑟ^ 1LbbNsSkj'|Ϋ~'&J $A}2 FnjX_+Č%q}lt9!gGx|Aꛥ۱eۊ$/Lx1F!Uv:Fc S^=EY]nBw" &xUwA,DcP+WtJk-`??YpteŸxpsU#feqRoW=+ck V<0#:JE@T٩Aԑdኬ ?F8쏳w[_0D > %U6a 4GaCjNxq-4\eNϚ{8h̫R[/tI *9o$IT`qD\BNi~R2&OP2 -t|_eIf8dTJŕL NB`%"ls~IE.fj{M_,l=Qy@n/ OWTVNc1@x3).e-}2U:FWux{]{0rko3EmWVl&}ȃ938q 0#]5M룦qeFVy&+yxҪN uHe+ {ݦ?ֿL~0K)PƩL(??s%uX:$ߔ%#lҒU=9=R^b])uQ[]X8#ۭB!b{I{0ݍipuE+ SV闣SpC"lZ%:‚?bQl40–_ָ-U![k K ϽܝJY2M%S~f̡cqAN>zƁäZZ @!C?[6r2`rMg-޸d-M,N]@zk[u[}tރpB(–=,2>o=7`g6$ eЁ}ѿ;;ŋN0. P z'#v {\M-\ۑV9:[,H}1*&l,lKTΪd53]m"Y&IԒѽ7%sxXf)~O7;l9kI6wgy'=6dy}>'$c @4*"^{~ULrx-|4Mn,]R]uWYqDHqbT:TY1Qጲ!xY^KWkwrtyss9.{Sy\z ӣVawݺY.p.}=IeDy~>>ݙrdAPc4Zu}u&M2H?L2>Iف894xM_#}g;0co)~;JQbe05@҆ׯlzl6g[(;DLf 54b(o,V,*FtUx|4 .rWb_u#C_spqݛgK%ct- MF{-2`Ժ@a9!%]4Q|w\sw Qi#oe`օHN`տLGR릔*::jjҲKb}Vso"OjD5͕%~hgj]E\a]FMjn~4s|ng^0 KܨFbNXÝ9pMƩ*{0񽶃r&aT?J,aʙ Ifΐ+MaM$W|^.û@v"es}b{ϬEyY穽!9o{jޑ<{s1QTIs0XZڟyx+0F6F 80wP޳ܬd*{<2)r_aG͉3'^(fUhqvM~R1r'ja {Lj#jsFO{ً5Xj] 5K\Uem,?iҋWwKڔGE1,\nnU&e{?`px9,.;"i}zX{71Kp>GL*,bBuۍB7Y11kQi[W]/S2 fk$dfsbF*} A[W0_GmE<;gBD)ZJL(}Æ6~j^\]ShD=l[u[=m<,eˉ=GȤ}1(_W^M ]7\#gӿ١HF_j )`Ż E~3ccZ?X% .Y񞐛8'`] 8]STl2c7bcs=P?_3 ]S )ڜِ~MJ :沁ԱpMڅ!}S >xf>YD^5"\"oW**E X[MK{۞ɶU1`q@Dsc]{13Wlpx'.͖goa_B+fkۭdӑ.N 9iҜuR(*@f1N .Plo;,$Q eXT0`AN£8iF޸:z\G%ҢpN@@.Ic!H$T]Qß n={6.нj?.7,t]So}^G .,5|'Ud.)o+/վѐ>bۓ$G>9_ ECN[mv=3u&{U7}Me%R^w!1t%ҵvdN1;-{ۗ{ADүJ,AGߡԽؑn- W^ہޥlDo_?| V*o==* AYqP(ۺ_^iW%ԫ+IW%*~59"B\\)4жu5}! S~Tgyob u'{}{?MA;)62CHgL]1onȧh vY rWV5 R<#""b+>DN;-ڜih5/Fam"NQy**z R2L^H#IgvH[Z| OQ NfꢨٓO0Й*;ho+B+RKr+jk&21"+=^(GrͨeAR׵{dvEMu_>gia«O.l$5k7AHD̋>|VSzC] x̺P\AKB$hpw'wwwwws߹}9Vݩ{^ݻZ_ ^9Glk18Q1{\|׃`7pdS9 x;# LD%}eī sT--   u MLED%e}0 !D(,;k((?eRAvO|EZEVk5l5VI䩒,Y*Uab(>@QABJEP Io e3Ser!Hמ?s$CSb~?XnVP0k:[.ZNt_3_o5,UifCP` Sd{,^/FK1^K{}ꔂ5' V0yu56ҡ=q1\Hrgwϭ4Z޳m'AL O/2?[8];-6ZFI'sF9 $=8Lcr5M;2.yR4 ?ڎƕgHO ?Y BE%8Ǡp1Ǿs 5xf tiFwn"J)C5A1BXzI)k8#hp3"J 5^F!tu-7y%wK!r]ydTy1sC@e0RU6_"٭0a|z n۠YoO&l}c̕M}͜ cWlWnnRl RtV^Zf|p |]*#{l'׊ȭؘ鐖 %˝:]ܻBv*aVhc't?.D"#F("՟a=ǵ_ vn%Qʟ6sf5I6cMUl 2ymvDߊb[~;lYR[2-B-R^uҚc,dw9o9$A&56bs0mf8馜M,5u$W@ܠVU "5\(чKf5T9>^v &IH`dUj`0%v ŚQҵe@t5@+*ĐzT\`S v,ia_rfbAZK=*IO4_qW[zWM#cJY ;2q~Q6"56{$q"[H[#,p8"(mM q0lCyOflᮿoxCU6UZ3~2RH_ [ ,5Nm]2luDҪv8zQ #f|k{}DՒ :~~+@!}KGbn10~rM@HRv|q&5{+l;??vug-Or.Uh1w?C}uQIqYO|(LdJd& 9mE%"+E 6'<ԉˮ; Xq\S!9V˟:jAx~d-EnѳJlac$Yb rA'Pّݹ{ӡK9Maaz28Hܩ`a գ8}s9傐?km ] LKsR ЈlDҥpuF0TK'A~X |\,eyrxn %QQ-{.?ccVU]ޱ-kэfZ@˴.ÏZ83Pt&?e53/Q;ao.uU&U5hfo5ۗ-3܄MرXEf^Ӣ|F0@nsfr`xRx߽ !ME#Ww[ڱn^M Ru{oO V$ϩp81ȂpUnwe} sTMqi2vXe5 ٴ}Rj?}`/އ*9k)hF>{ V9Gf%nhJ fyyc WaQp2C'>D4Gj+2ݠ}x'߶tԱ{BsQ57nhb~r4;9 JʲJ7Apw`1L0ݣiw:'ڸ$ [ruw ǂ樎 Y?Xoٌ"F̑C+ߊMuGJ4X duKo]6`OFcIp;ƒCDo6; TΒ`jr;HOhWMِuY1T7[q_NX ՟!a6ܞ/@w%$)ҁ,W}\+4rrFGBF^Ҽ/77w甯 ŕGwUWr͑j!7 zPZ^ĞP$9jj }i-=|dD,}bUYvKԼN{0F%2haHz-¤Rd!.\tuxdԝˁ~|WMǫ>d,=|f-sQvo6ڵ&XSv%!b+*ZxNW` *Fי?mh9˧{ޱ]^CAиe4ss +_zqx?6eDUz˪ yM3xڅ{1W^1^/*1nUS;_I|V,!G9 }?8S3z]Zo̡`]]RzXն]H6 -{ReNba̹9fwϙX^鸣N[t"XuVCf=~7鸷蒿v~~{^nj-#u^28m;Ocl/#XF2N𺟷wNX^ɼDXS^xN07iW_5{/V4\ Cc u)wcW\Y*on;G֚O;MVC1[{jG[mg3T-6omWgQUgh3ssٓ&EEE&NiAЅC1`~Ch~F;k}pU4q^32 g8s[ZYIu>GвTu>_FV*=;x-~B64pi֟9`:zq3O,r_Osol^rN:@Y{3rv//F\I{cJJ}SZGr.a֪WO\RU*1)(}=D\\8aᤢ*s⇬/V<"[[핕lDDek?5W=^.KQe J+~644OHd`V?m,{&THB֠"$^5.!9lE\ ΃ynz֛f_}Puv3z˝%e䱍jOLҕvLZcyJ3*߭SVgMV>Y`ڬA}]RR 98R`1.Gن9gM&29g3 EjΨ5OูrLlg8!!Y~,7 rЛ;Lxy҄Y"n)xx$zo=_4i4~how"{yYD[Q%Ё9~d)mV ^^dیX=km?YG6*& 7d5^G| ßgsVkԿAAOP PZkda4|ftws\~:$[!njJ54FRQZmk7Dшrphvafs4"f; ![Κ!۴J= HMXQ^nkɅ.\@YɭKg;RuiR3 ҥE "\MhFRok0>>\aNk%v@b@`GަUo|vj9KJyPz?2|A5()}wYbƎ@z١`g~HEI3?af~VIDΦZoYlT7E wj]В ;_Sgj;U2x0l$Ōz_'\0֬}. _9hpg5^ZRHa+tˇV!шmp"jl\ 0gWJ/#5ċ:q[;CLzL6aԇJ f\Ialp. &n\JBﹸJi\2|-ex1R2kStv3yr@RR`qS`=3e4>3YcO @z.Hݘ#D-^ȩ*Y>8k) -Rʖeh 7 /]5*T ]/d/Dp1"VpxB';;cF&R% CCnȁTB{V\DDDZ9YΤCu汑Rjp=^PѫN-No p{D3<ЯR5P!e-F@E(ANd2БreiP/0088<]u^ e̜ 880a=SNy_jOQ-,`F8i󪙋$+v%Sr*r/J7;&.*\/" WsJ ]5w2QZgb+iM=B p ÿ٭6RML|?Ǎ! NCé/Jd($UqCV(-.Nc& Tb{ԝ$gʤ+־if11)xZ"[I}T4:ޯr Q?eG6p-TmA|M;JvoaM;b6EGBy<*.*A'+#yFO.i(O^iI#!<]k>ڧ7u*<;旍}Ҏ\ʤQixVu:ўsbEWfø"A]Ё;'#Dˆtm֖%TJ<9v#;۷ 례E>CR&My>a2rr=fUv͍ܸQ|Nl;M~xxzhqR\^rR[񅽈ҷCJߟ$!Mxqzoqv|s볽8vlago?y9q2A#)]dvvc~Dv7 sr+++HD3;pSŠwxNl&g=LJf `ǐoҦ*Y[, gPb\];J8g>~MjYC|yup]9~z#[g~ar/K" :˗_\\ᷯ_@CC?;:uB¤eGBoâEo-J_Ϲ(ȳ|ƿ{_ηmlle96կS‹pl}_l%1uTX2⋠#T/1& @R$H6g2;:?@74lfX?% ]bt%@.[g,m) Kك-o֬J W&aFVm5jƲsXm3v |U Ej@4xT]9bI7v@1Lp^:||J=Bo5 q邛NzĐ4K\wq{{eG HYWaxNWNkEk'b|'9y ^:\4.G:{&\>ES_o:ޗkk ::5,Fǃr ;L)#?o -^ **/#Ѿ r`6Nf°Xȵ ,Sn5$Ǐ<&T>U`&a?U!ZN?R#Oƺ83 Sc*:UyOK5NB.˒]zRo%ӷIPÀ4O{\2iggI()Wջ +T49}x5e7Ùk'-#Bq%37(_sg -G]O5-!(o-*A_lDF12οЍ :NѩqAX8dmu)'סyKfҬnsyAomY/Z|?f\VV6SG%~$k O55RI xԭ"yZ:I\Gt)B\Ljܯ-A1ok|K"]Kt%ӃeΫ*$u |v3KK#A{o0߯|kT/KN–<ĺ=,uFɪJ媼i0(㼡+Rc,iL(*S;SKkP4,.%EֳHYKefƬxSɉY}LvxӨmYrJIKHjN{]OFn3с MKF(**z`8OI"k*`#K-M4М\m{ +Ups cNAǗrڊh1QHSPAjM"G1 pn%U3űU;eZSy䵯ZFJ=+p޽7d`~(OG*=&.H a[OMgZ㠰ķDfc*ON5pI' ,E2Ytv(yLJ,Hɴ9DEEp}i>=Jgb)-m_Bf->5(VRr@꣒'3fr9/fA+H? wZhax9|YԼy aȦ3pہ2mVv87v`!:ՕU<2ȕ3g c5 0cM &$ *_sJ ~~.. ØTzu zzX謉3'h?Ilw忿k9$NǍ/~pҲ4|*8WOTA'?G p...nr\qcndL|"C^!Wa)1Y6IEܱ?M ? =Es5x-J҈Ng`Anm777yVPrrseKgcI"c3h蝮M4lRCXHUNDAav6#q v45DLuѻ ]twyH׏HLZz鞵Q6^duz&ٓy,)")i.YA!2/ea8_X +grfyuc+F+Hh9D n*kWLQO6,."45hXF,`ٯ\opNrUX.ȷzXit߭ql-B'>y8Nd,O31aƦ8)Сϒ,f>ťKZY}|3b#-_.dg{wC3! 뇇CFQYnCʌm:SĆa6;ϯ KʲaP;dYi< x-bВϢ@vߤhÿG -&3I7Rj<}&[RJ 5Z6I,#*%Ke~3=$!, EzpguKVxVa4ˇO&;5aBtDoo踸2Rmfpi:opJa¹F5d4l9kǻ6D 3ĨO];pP]_)BBa HrVLf2 7ukpdPhw}x(֥Hie* ɂZJG ``1=^b*~+t3PqǴ9Qʋjk~z;2s+33Lg,yLgD5CˏxFjQP$mK1:s9t&A뭥׻A>P7ҁ흽}$&K*/iQ@X_:opZX4߰=Ql ւ -@:oXJrִ[<(KJuy>Z:/YecDPVVtek"S#s .XZ lo+izRL|ڊscQvy} ߿ ӛ=uazpu{ed D ,Xq- | %I,fX o '׆iie)-$((|@pV!$[O桍-{&*sr|#BR uv钃Zآcl Ђߦu7gЏ8U#7ɭ ek,AƪR[,kG%ek:#ʍ*VIyfoty?y#WM;QoI"o}ڂ \oi.t{BTZbKq.N`xUqyyM*WY`o׫)(xށMzAYQgfÄ"GlV:/}y'?Im'.5kgmWDMa2[;j>|~'CT< ֗Z<<5.h'֘.@, #?QWgst&XLԊ%~|)*3:vϑL6=2qa6&^13X\O%:;߮l[xjfcg'&{6}ᨮje"z>ݨ6vS-_HIO(28hyK/ 8Mlll++<ӽ)T]LFj$e:Ϯeqq( .-,YEb5rM,iU,/.~^Y]Uz9yi'm"rJL "$A("`o֩E lް[N")GO^lSǓ?f N0Ocd2h5B'eAE*QC}1[*xc"[pp`Äy24xւ ;"C7;EnȖ;~tRA_<5p`8!-KVdqD_" .O(弼}V́  hwpt)L?BوJL dԖx+LH n.SGzh )jH!%yWlayqqnK$%A}3n^bؔd1Uۂ^ȊI9mBGʾBmu;&xy5zn… "t~ޯAc~)fXsS ]^쬮lա_=}x3}=B`܉aYIwjj@Ɇ{|vQk{L gts1w: DTNH;ul PZ_X枊:`A dYӏϒ~#Qs溒,Yq'&ə8hѝ'^ZyAIIh-8\Y]`UHOBZX~-54C?<./]3pnZV*/mUIU O0`Dp28)k*h:U`I_}[9bPG! [ޓ -a,7C[ `gY>|`sJm qzD^yEɖf=z\JeO(& JJ;~βJS0}:ue |@dlr]M5_`xH .l%Ͽp-mE5,{_/C) OVd{NfSQ!fi= tY>Od#ÇzG0,V둒!AP xwțo^\ ~?88hXDZO e\qZi N:.DEWP$'*.U/q>W9 VTv=Q~J>>(3䟥êdZ7 [T]]ʖ*;mY5ȆGAA(Ꝗ$gsbwOgg竁cM-G?s/d.Fd,u#vP[u^z\&ă!ڡQ? ex5 &ct_P,x#AB_LYdPPѰ d;P;Y<^9y1?Xc P̄; 2V\mz@#7Iyw$s㻜|oؤ(JcJu MI;77i:{ [ 9To+`lq)g+bEeE7IR4=}*Tj>Y{39w>Cl7QmhFB'C^phkUذa`-^|#A85c߽7>2zI%]NwPYk/sZ{ێ;(<ΉLhK 6?EI% CCu4M{o.`ۗ-j11Xa'׺8Dw.ҍ-f [zvj]\ah b*9L1lB֬xR9_}HH$:ڌ[MͲnI'kf[͟ICB TMƧɨh rGw࣬-ʪ^l]Xd K.G״K濢tkV%Œ#,&p>u{W04CܧMF>}AINl+T > (d{S: ~bѕ = /xË+t}*2՞J7A׼躎Ր}Ve;.dYIؕ$xZp(-P?d{oM*Yt-`}|WǣUg%wa,%K5q `K?`M.[I'>sfsa)k.< ϩr8}c;w|}{W^ Y֛oCv^K<_kyO#FMh3Xj(t?4Zg)Uk^AyPO9|E-,,d?0q&졨'f%PU퉪t{̝;]!wۉat˞K8BڑԎ_]ȪUC_:SSq:,xi>֯鐒G2!O{l*[K+;o;b/aW۰DGWjѼgѼ.tMPXٳkL d%Yȿ>NvPlC4gDQ';(60YBq_D5in$$tC >+բj~b5UxٿyTUUz^|n]Yz5ǚ$'#{|k7 ~}+&uZg)ɉTTV,Iߖt[e Z }|ezγ EQW蔇AW=ꕉOڏsNF|3* ͇CDB7EiI -wOiȢdmrG{CĢE,}NhjenY[s:Ec{MYE!sB2jNY*dYfv2Yysf>sty'[~%咒Rڵ YVd&H()v߂1}i1{ 2~,NJ+mHFu.x0rݟMv>EY /22e^ʪWyZFoqzBnWwZ;ܞP5ŧ{QT2 q8|8}2,sK~5YN}Xn='=d{DEEѻw`>׋nS\R/vyXg^zŋ 0e=6u ?gytԑGż tk5'>jqFڌTS7xtI7ZKyf+fLYQx7^كȊ(X{2q֎l̥V0}Ԑۦ=(K3x<&y/%/9i;~49-1x:x Y֏8̮̚31G]-w*{O09t*d2L;dsTTMcࠡq٩y;jȭn.'[_|SJL&c=1>7n&+3du߯O!+>ݼg8##S)]g葌=ɺO .( ~O{"5.d6 |U}5lYq:D ɌZW^!Xc):ܝ7͉-ͱ^qx3>Y}alC95Fj%!:g߭@w2je[:&Nfo9wD&%X,<0n"y}í)82czd w00R蓜AYE!w/1sYmv߽@+z/v*C0?K@ 4xج C}8 s]8TX\2dSprNL&!Ed *'g3ks\uL&SV`һ\g/^mm:NA3 k5{m[K& ^jkUoG{ϽS_jQы[pЯ_,ڪŋ!,ns\DQa>f3'Ooe6CnSU5K>F|CGddˈ>%Egdo\pSZZDJ!jD-ThpUjm4x<${ÿbsFfY|kg㺵|o(.bUa曛LJ20i -˗6&nf␎aGXɈQc||\LU-)97U! q,ftOwں:^o7JHX,v;1D8+=@tL{·Xp!';%^Ь@ >(z ZB DQD:cDk7(g*x_/Ϸ n@|7/~eU$@ O6[d4OpϟbfVcι1d@Z 1dH.IENDB`s#ax]TN1<_G PHύY3q?Xٝ!{Xiru~Yx&cN9?I:f8o'iر $NU)LPVg;z::~2`0VOpk,KVz:9^^XGu F2uʚ} ; v$t2*fڽ:1]a$-nOHumљI+<٤T]iB9im6ن~@:BQ2D ;=jX k x{q<ܝ.n.~' #IG Qs.ի2jv@նH+^Rz6~- 8:`{&I1JdTf?4١_~+|X#f@hb,pZ`qRxMejakE-oa0^g3a >L P,-# dsƬD^"F(17 'h.uO0 m8RsÃʏNbǹY%!7xy.Zi6+؉7'zw05Ë>]3]#:,פ¤ShRG-0 q_dŶ0x9]5#`m$iI_bNebd~[^mP+g\5$ݰQSzQ"S] [hj`=e-vY}]QG]+xmX1hؑ>mL`.4#cn٤E6QxVrF=_1\HPrrtӖ\^X `l`5( ![I\AfsrrsG@ʺHaqnWx9*b reFUQ(RP%kcUj`>5Y]@>gi~{U;/1@WmKkM*Q$Rw'1FRK[%UJ a,\6H|q8_w]1Ka=!yxM?"^GTCSͱcN,LElHhc-$;*b]o,K`|LS FntMa W͡v3e sPV|&\ \to % 55ú'T9={OB Ѿb+a8Y J'lhJ)UK(cw 𩣰T)pZ7 T!/WB*B" c-Vj]j#24H=O0KI}6i}bBM:'Q4]eXy_o6w;6VdG608 ʺL}@_&eۅ̕`UTϳ\]*sE zX.).>ho2`zbϱB`A*[Uԡ~{{3ͱ Cl \VUtbWɳpHxC^ѣ!;H(ΏO Mqe`SKidnv$IљCp_ȲuZn|엊brHX\7axw|3P{p [ ~LKp݄4i^[StN5ک_U ~)Bkq&?r. 5Xo4Qov_(X 5)V> rTH_` 1~90*o)tR[?)ZDV H&2g 8Tɶ&ԙsCmfN#)4 I\AFqR҈\" $(Q/ٕK֢NmLv0Y"5/m ȜwZ g8'Z1V.pX=$ww6..r:_>cVޏ 2(c pԖ0~f 0WkTY2'A'xGYvozN5+rNn Kqcɑ.XMay 5r{5i=WtU,{\lcȱ ]³?'1{ (WRT\ŎIv ˔֔- HUM%,yOdB&%T&n g=aR:$xoe-vypzv7;Taaʺ6\a` [Cᯔ^_z+AB_ }*MٚG"SsL(8hHGXT8s}!+MNpǘ_ZaESq-֝8!=ڐ hߠ'?mSl'A=Jq5Z6.+O֎3Г^\ x~YHUl Vu;-hȪ/I-B+1B>P..z[I#=F ׫0P{S)ukeb,Q}#ߍW.1HFc@?mpl1b>HA|<o%y=&ԴAJmQhǖgE6韈[d?;]% tɽ5rmva20!db'% ^fCUE0!v}\C3EGbYb5[(3~vMfvv|.f˻h9;:VG֋/~-7G^nf4'h[$T̠%P떉[̋xEphgɖѻ)j-J4Kv>|> Ew !m)iD<Ыڻ{rnzj6饳Lp #~B!BfW8 zn`[ +B}x7BШm哂ҊL\k0n k} 2™@kF(b p] 5̜$JZ,_FBu-W{,S>qd7 ^nIHTBʽ#O˵S2.Tc^Y1Vw)8eo Н<9||=:2P̈́+!?NXh顬 2$Y(DY:|O6OW9 CM94V5J|<3f! {9""8&:`>ܹ$@$ޒrj3̆Gȩ(Ęʰ5etK;ԡh;zm])7*"D &֢79!Mi5xTFKc!f=;M+ڰZ! < M@9t?6@)zؕ˄kPC  O 'T8nRYJTPpnvJ<AS:sR+ҽm>$S6Mx:Z߁i4@IϜ<5 1K CC/i]&TY3O.i@qƀ+Gf,y-7G݄-rvI mW % ژIBQ.fd$JOKJ zuz\XSrڛubH&2k@ڐ qq"͓Ư»Q|kym0|x7p:*B-jHZ22GH ɲ6␻RlR$D$- AJ$0" Uɀ`+>)p)zP7@i%qRcoxL7hLK t4-i/*ϏuW&dі4E7?0ӟ%UerEs٘Ї*Џ\~{iiwUQ!։pr1]\!8daruw1}8̷CY 8jRt!.{XC/i?x,Nf2'Ld4Xvy3//oanfx,Yncff&^"YxWn7}SXmi7[NZVXN>R.bY!n_$2sxGGGGIzl ?}ZF$ObN@-6+Emؒ &_9 /ŠD+J%hW|:ڵ^>;)Y+ħbA+lt6 'f+ÃG=94̖F]^:YfFBWX gCM-*ۮĝJ[-,עqMgV?Ć^໫fGF˜K_ ~ܹ'0 p20yc=($y@g[wk~h٬Tb6|yO$*ˏVՇ|*Sɉ7ozAp/s(sq>0Gr/Ü =Uнr&nzPL <=F&pjKEI1^-*~{x՚zf޺e} NYE MeAH|O*m=[Z d!aVؖ=~"'\JWn9]JE U؞kte)W0Y)YVMEX ;&'tiK x>CVDtB`P}*)<¢^4QN@E-\$gq.\6A?ޢT碗٦Qr>Uqw}59_6 dj8\!(4 T6:@*/'A_I[[I|'謤Ϫ5<}2mE.ҽ;I q*n!EJ1ɱ킾CvL|JҟnY `y:I ܶ9leuUp|"d)b[MwcgbߣނclΧIovȃ*u ]Ǧ3 QNzLƊ i vU 8'X7sM.yVD\6]dU(z$<p(ot)* oIv qZy| R:~\hXrf6RC<e#DnC96Cme2͋/|V&QR0]R7.Z1rZ$xФB̓ǹFy,7<@̣d)Ѫ03XĔ1X.̭vO.OQ;P Jhi #"W Nhs8ca]P]S[p uMݓsS|dɥx?m݇ߑLx]AN0u|,²H}ؓUƎLnD7 }@&Μ(j ja_{z52q^߃0d'iF we1Viz{4vb-aF K1.C}')C٧U]c@kM@CpeC+|۬FQ-@x:\>O4]+JOp4xmRMs0 =n9-cmS&CPjl2,l&i91{{l60hQ3j>.K }iy}N a{ rhjzP>=C3m?gP!~ء5#%k0v `E2+ )@c_yB&|a0O-I*\Y+?9uо jiUs<=|QURl.P((\!fp} ~< q95v;`K< s o,;?j p{ 7jjL4 yq39FitV dw0yNY*]]аLHn>aΧqI/K1p~}\ݟxv#,\Ƶ1nHw_7c\1œ|)ΡSn4/%,ɢ?Q)KSfl byZ, WQM*vt*h"qm ۈѷ`~:պPcЋ-'DB@ CN|xfB"Hi;Gίd"عMG l!+؀uk̤`J(v9Yo E q^PE0 /Q[Cu0뵳&:gP8`sxM`h@C^8("Sh fiutt|~ӌ@KȬG pADQI?OG!&?t:-O:r~FNot7ݻOSJ9\;X xO[ DM%5ˆG62$BE,*(쎬qJ'vK"@"--:X`6%C޿ڒ|6qtxb1M.p=|Vzlu)2z<~i O12;Y@9iG Nʧd6uF ^X!\!䀤`w-`.KvCd~V8up\i?0! BEJo'G6G(@`Lǔ,< Jd1 X[#`NI_OQ~U[, =K{H :QYBFd_)딓d<ب+#\xǺ2U^}a壜뾐IM'\>2Y 1NdLi4He';< {Yr|{b(i]E0i#N-}37GEGDql3UT6ܞ8=EL(]j?Rm;Ĺ:DikaʹkĘl\{F>Z#Ŭo[d_]?&l" jzNT'd vi̮3TT%hC]ñ8Sr@cekbއk72Ä:Rh8A )]I@kCeق'$:SÄԌiIaYt2Ǜ-(&4bNs}KV^aج,m8 ;UƢ`ύ) Yb쒣}_0+_-SnW 6:6FJݧ\%Fƺ_jiɭR֐HAFϵAvqFxi܃i҈h: u%'MтTHbi$q]Aw@.ʯsIC/{d6 MBFiP-ޠs )Gnb^]jĵL`~ s "9xkBGf)ϧ>I"e++wA]C9O"g{ň+mOl5 I6;6.u5<\*@RНnaXmA7tu` |d)oIl']MT} aodF uOF!m(:ۅߡ`GigʰТ3&u:̔E yʥNk#5֮{a=mWPjSa>'HX0o߄t"N߈OsY"NKi[c{3T(."raA JI͎ XyT=dV~R斦A(9!y;+ֆ#UHy!Z.ߎR0aj<\\𡍩3S|178kL=rh lPgΨˠ%d..&bBfZYfRuw%[G2&oD^tv]F؀l'-=I8]^4ss%qBbb~e6کҖqwL imH)OY3x^!A/wI횆8G!S`4Tj=gnm}JT)j؇YDTJ2н;d*X<{u9YnGVݥ&X@*Oo mk,[2K < `IFg+Nw{yʣzjȉȐPތ,˲'ڴ=I$[9Y`ְsh,:ޖ%GXwaa/,"Sni+d6(deW e"˳C^b)'b.FuqV|OE[{qZ{Mก|Yq!޽`6c228UT 1kT1Lp-DLcDEFPjn}K",y!ƈ75iY|H/9diTʵD4OgceQ=AĴ3g)`?3%șK QyP}t h&ilfx̹sB9 k Hx}SKs0W8i`2P2I;-"k=*i=+)v,~СKk |r[|RlnQ^+Guj6¸̆;-%"0(7ɁlpCϱS@Э4iFY@@]u`2lP ȳZӃ,g֛ q@1 ٲ^-rү\Lj#InX:El/SNuoR[S.m0Oq;)On$VY(>V:ɊNGwEP.D]hlzS ," ɑs*Yt# d,e5:ZdYjD(?) 96k^C y=Uc<׎Œgtxk^pJ?^.W{~o1jIVtbLw[R 91xc@} ]2Jƻ+owg;U uoqp/{-@A\%{RUmJR;?mS)>{aPP-a|Xm$HU.AZr/{pEJS|8u9ɓzvڸਆ`GNѠLg XC4x45`-| v2,lrl`&%z]B-}4PTÖ\Vl9h&B$DQ@bϕ P?ɟjo}վ{缈Zj)a8h yk; \֋_eƬhih$0JZ1#P5J~Tq$f/~0 膑R124j_VT"tlF8i<Ƣ=T p[TSbz 14pd'sۤl;jb6'Z0jZh{_P4ml'"uj@40I[?"JuWinBBN%%UKd:L}kia?Qd'{"==/͢^nK\yH;x}S=s0 +0^]4ɵ^: أH#;,EI= ~'L7Q(Uool[b z~.뤇6;w^]xZ}1y '-4&Z(5Z=2%AN+b* ŽBq^4"va $~W&0Ҋk|Dz}olpSdpT ȊPM)6G?Rna7A )"kˀ -vUiZ):wf|Yҗr*v@F X,ywO|ba]j YiD91 a8Q@/khs9 0 t&Ĭ#*OYUݕ́\ARU_`x9]>jlG9y աl pw6:7Oɼr,/nVD9yx[sF+TI%0O$ǚlQg $l@Iel^64Yϝe]Yu/_$dQֱq+DEZ8{X׸-Vڴh6nuZ  ]ULݲʿ(b|=BX'," \,=tˡi>dgrXnt Bj735LújZtnohߴ G]ŝw7 ܽdUQ1~͊c$~K70l,sNN-|8g:[ɦ%UqSZ\L4@"7mSnU8edB~'7E!eٴr=?fXŤ "x>+u :q*KM+O׍k 8'YHaoVhH)QW5n[lɣqZ68)V3DS7NMmݵL̈́7r3g/m ̬hVXhU9+曐:z:6rY.+"CW^fˢT.Oٗו݊__,_Ƙ12XB (hWג E \dy"2IE^]?]??q7o.nK=}sB]@uk?>r_>.T(8#d&/ D}ٙyXuxSu!89IⵯdvvGlÁ*eu*ȴ~br}UQɲ4pCLטƛyn:]%Y]V@%TYqo-X+z3VBasEeszFM* |6!6"Ȗ¿5op֮ ocV@"h l+Nq[s!dRV-WoC0ۄ@d 2ta(AvV&$Y(޴DE~աnFv/S:Hc# E6ӛ[VR[r 6'erC+U7LA.a#  +܏-&?b+s pÑu,r/ XRww_IN"*\籈H9]D.}SdnQibn* Li3XE0Y3iZ`ɡb|e}kY1$PoI{y~ =ч}8f6}M@pM,iw\pAx?WU7Y2OޚzR 9;mjE>mѱرYLaGH9I~DZ lJ^+sߎ?4嬢" Wg-*3+Q֋yi9LFWSɆp:9Սgsv\찕XaRNFe8Jbׁ۪GΎ/j¨CTA/;`Z=\0vNzt-WXp4V*O~詺[ņ ˖nk"4hDi\ 㠣`l(h[Di& 1Y#dRaѫʸVNr|3!kk ᝟2[@:C^&1fʝ2?/y7 PC›tzr<֭h˪X#!#S!$gys /jysJ"@}7 ߆P`n󚩗&  m{J:1Rm4H%rV*#+%R5N0 pja[ 'H&gOL `8 %l#^/LlzVI|s̒1M&"2OCPxT|hrpJI@DqN,iJTbmue2ђbS$ uUp8`~jv_ A@\5Q Զ57 tl d~AoE¢d$vjƍq&Dd- *;ÙS2.ab?-謧)?iP ouhahf!rDLM Fa1@);pOY4]D*,DySxm 8; tO 1l}}΅a{뗁ķ=~;+_ɐfzT"shڝoޝƽuኝ& j#~{5pQpgCw+RkkO-'])=3N:9:q$/]̷v89E*D;'f ,kͪgi%ڢwym R:ߠ֝ zOO5gyh 7 !Ttaz\~۔Ȫ0Df!ֵ]-&uuo]6b^{͈C&t#Hs+ZuE;$a|>>(Iu3q󗑐U_k>!@Dl@2MZa%R}~ (0T=x&ԙ:J&AX9/Luص/$]4l0U-xJo O_oga_SӸzIu7Goz%bSɛKbWS;c)oy4]%G ۽Yq`{>1]zht@`o uHRJ'SbY,U>}'(-bt5LVش*Y`̘Wf\n<5$NFIe <;T#>ǰYgD3Dz!u8~x7[IзH!?g5)B:݄v>~6X)hF|ŋu s_731Unè!^rfnK|e 0[d_CӤ]4,W}7\i{ALVl Fʉ) aÌ@`NsHq WO/U!j}'>&ץ$#.@AqcO^ijMtKB_#ǒjF?q&PR#z]6&0l=0=S3+yCozFiY9iD9sf3"7CB-jC)VmpVyc\pIfRWjD<"cuQтdpD҇7CQ"-&M]um?i*{Ni,4ewr(˗sK_w׎P%Ԥ]\~t;t/$JľWſ hȆ7+|fN5p& -epN_/h/>00JoW^7zbΗ%H=xUSjA%( .2.DI$w&3JSuazdҫY ,?\{{d7t{oR+S@n,'he*QoҙE^BN-.W8 1AyȌΫbFɄe&h #XcjBK8 <lq)+ hB#R:zKhffsxN0]Qtsu6zʗ&xpKti D NhT(**2fz}h=?ZtQ8 (J @Eʩǔ +]V]К`,3=BhƥMțpi+ a^]^ S{MH8Gyc25O( 6pҲ`S+^&{SuQAQߌh7:_LzAq?1Hz׊!5K{ˊ;ke驭1{gB'^| x%(qc:7,$ڗH+T aD"75m>$F:RܚofDQ lmU|@>1 ,hM`w#C[_0cih^W?o3,OM̯o>U_Z9*/,I@)H.{{l+=脎M.4Yҩ[@l8~=rANF Vv[\׾oj ,E'DcU 9IL算 &CȨmE CM Uy.j_G|Uvdk2oK:R6#YZp i9<4) &1ʚڢ'8!L0=4`sG~REJ)nʓ$X{<^be {NSVpvϿ0/i X'z#Fd"Μfi Qx}S]o0 | u@>v֤]a]GYcdQn<;yТb> '2p2N7G`M k6y.S[F U'2V2%.иUPanh(<aU ^#p_8Z$|Cuoݡ(BZGO0MpCVFKiW*XM]{ %7\r2mT|09N<˚JU@@xJ)_ @1 UuD>>-vɺd *ZLנ!8ՊaJtVqT<|_]. [IH"7JJz|eܦj`^͒6_M1B'2T(vt<~.R;VVڵ& . L>\xS״JoS6ndn~. ҒO x QKOh+2۩ZA.d2E / ]$c(S7>ӱl2n2%? ^rb5GX8BץP,r K|S;U綔kõU[{iEyڛD~ḡGGWQ.A] ʫKn|Z910Ȋ0 [{,{ͻ7/: fxUrF+(UDr"$.9EٴʉZ]x$OςR@ܙFO숎ݳa>at4d_t2DV&HQ*Ӫ[jk]ݚ;1J=:jJ.E-S*BE&ggkOSqcgr<۳5\0]2}ƻ_ol6og#Ah;</t~+4Z78.r8sH *Rt*V-EG^U$p8hX4a(mI=Y!gczIT@T{y!x8D *ILԽaWsw={I~RCKP\ߌ'~h G,Ͻ{CFYB6Wub`tD*E7Ʈ]䝹:ՖjG_\ITg%5GT]mdu|^'x{B6yA)#bGEâ͆S $$![فThաш=WpJGp3Ey tݺH} -n74]/8c`U%q{KɊbH`_&mr/$M8?](5tTn ]/{"RD,#[?Ea;GՑ Z38ab0'A+6:Ɔ[2.jy\:'rU `(->dh8W\ }6N hԬ,PjVZ4.}H_yƭHR]nd0p r^ybMnɻ6@1iƒFNm0w" f8xt5l.HY"|aU. f<u6ua _ 0SH6h56HvEl*d\tV7o46u$=fE@rj .3hz}}D#ZLχZXZG4 j+| ,YT[^v\yzZ&ǛLA;p2=#w,9Cl8 r/0m(jK[FH J6)MtK*K.,le ,aK9u[Tb)snL(-/Q?]ԏJ"k}*G?" I-TZ%axrt:|Nx֜ZO]F(jzNvvybgׯ2gxuVg xl6'2ZxP!5k0}GƏĒF|OR*MlxO<iYᵃ'y\ w+ J='yzN5 ^S=;)B"xVMo7W C’%;Nj$[ @U[.ړ]r%6\rKr_7ܕ'E}0p͛7Cv(ݹB秦eK: z;WH+E}\o=knK6_ T P c(b-wkU*C>(!t^TQh1W.qPafc5<;Jj߃\uVg{\CFc= H$K'U4DS>P],fѽ=D8 Y!+o4mEv4F!W;E١:0&]ZWO׃G!qdH%B8ԣlЙQKWr>oϏwjC.a##E&,b )܇8?O1fg*Q.8 m w舋<[Q*r>}a>HJږ(Dm"jf3l5RX>m[+Pʌ[ST.k% C{[PhFuX{pDA᭶K2d8 G9Q _Սʄ,]5v $!khyu5iU-|<굎&E# eHI*j3ǁ- k jʥ3Ow Raj&q?2w*U)cA}*[}^;kp|y);WcA~1l>zkg;^B] t*(S`&b XQy pxΧWM0~t{m1o't4x~4s:y̓w<^_3/Kx^|K:䩃9}1tyz 7D4tK5 Dzc%1o%.tR sx}VrF+;ERd2]9Sr)9hC/,ʲ`+'Q*jg#~ gSZq>Ra(^7|V5b49:;|k׈~ b}Hih%gFy }xml]] C28h кe~p>-\>k67ޢ-|]HTeF{^]ڡ:#g+ (nB*7T 9+gVQ ud zjV4zԺ%P#p#*/nt%g*jGO$&fF{ P !wc˥ u^O: }6_/s2VKE5h"طTZ>RtT\-ClCaO?fl HG]ƭ%۫ y P3sFsP+dxߟd(]A`sLE&N,xLo$䙅_cD dc˶9(v9(u}7:LN$y2+oR%e2@h>94ƫr2[)E(Уo2w:IwPF ˚+ tU89IQlnL5TepXpmonQWO]&'0EosݥdJ[eDo="a?}R!Owx`Af Z"dܲ*KNz(t Ne++ʧ/9ZH^!#LheeV="Ԍeg~Lۃ7>eiLD{Riଢ]WGY0lyUIk,FgKg$> Y°KhXf#^jZE]UDfq9LA:Q[? $_5XՈ-$=[{i;ҽ~;~ݒc .ΈGEZ( ?v T0q5ڹʧtn[Y:|t;<B|x}VV8}Wn@B\7t˞RRBvrd{ؖ+ )6ҝ;w<_~d>n˭M)ۜxx:\!ȯ~+DUu:yUxmΎƓYRK$+jYsŵwCy*X%!rRuRV7r8;whjG}Vr̦. C M]ΫdhiMSfE }n*U'te=H+l(1_?'7$kScVgfeޡ]L'o^^RG}RU6Ԍe\3F916_(448k-Jh69}`d g6=gVoV=VrZl8xXmK>F:A68~7~#=?ԿyTjʵ 1! RKVT*|ə^?iA8k@W`_7%Zǔa eπV!{c7aF+LN H4{mKhpt :ե[ ޏǓP& Mx@y0hrM8LOџ0M`!u,!rp|1[T 0"P5E<)$j[k]7M,sm"HS$Q趣5]Gn iU.J)VYny(1N[e@%G,b[e!q0Q#ݎJ]@1zZvkm0mM[8_ƣ B7Jutt̼83̜oaK4gl^ P;x{_y[pGt #>{=\w)CN!yҳste֦MGR5MV)cyNGR Y|o"Lv@L o*؂\xΒƵ!<VʭBw8ڼ"JwWKA[']FsfKb#I,\eDnn>\} mb DjQnc P$[%դq`e(yXNZ6s.\!WRcZeۨTOi-̬:VzGDQޗG/ ;^BR( C4Y 4O L- !?1m"z=+fwȪR,%[Id/Nx}Wr8}W͓-$bmmUdY3/ZI}RdSDL Z|HIvɓC}=}'~oF%IGxr_o2Ifbp?>~ _ *|!lkYDbNC:id"iVz/sU[Jid&*cId*q,1B.*= ÓKǰsGFӱ&Eu֬ui`m9&MFm˲$DnMzѼz8^Ұyw$ƥ*XQ\X ١>JP) VETrEK=K0WM99]ya[jX"G8wt2^&Jg|kce r!t_ ᡡPq7*Òv(E8/ U߈mLt1}2 nuS(>TΓ&{ȿkjJ5ޤfy3D0nW.'6+\?s2iAp8\]Z\: "-JSWD~_g<m@NtֺO/wݑ!WMVuImY$*ˆB һY"CMǡCdau)=>'`ҫ߮U 'XU HW R;aE5!6T{X+S3ʕ N)Mw=J Uf sXG 4dRG܆K橅yR}?hCY^xLj`^ǖ?uT;DVcgIzCj \<`+98ƬL^X`V©UH$`/yiܘ-h'ϘT5ITv*XlHsHdw,!иC+fpï*PbMEԫL90%h[뀤ۛqE 9B)a|j^e|4s=N'.j(ܘ̉Q:5cekpi$|  vubV.|4t2=˚[:k.W%S_4p#ت1 zkYvE-7ac[3;q_2sS7%^ ,Pxms _*Ɨ81"SfNl2QŝfdJjW+RSN0 нx27i<ʱż]? {1î#n{(}5a ?P +zR1Z[?j &ׄ,i1>Ovz&p|wVhفUdLod>a^!<y7gl1'MnN)p uP *όEȕu9`og5VAyhZchP5/xGtHԢoڪ\W Af\ٟÝ`\G뾘Ǧ7n_]О88PJYl ΂::AiXֆpq8GR*èd/oE@XpR4p){A!;+{snGax$ t?cεY CqVx|8y,bNY(lG3( odT˸QM6P:S̱C1*#N( 9YX^[UZQjXȬRXS҉A*m^ 0 oQq"5#|˪.^%PD% $g؍MP2]V{ e#)w:s)47Pݞ0n ?wW-T`QTiQ)j-lKq-`YS 5BMG `DֹnTنTKύ| "% v $.?.o. SM+? ig۔ö3m-txUnG+ ! LIԖ7IZFӠSt=y5 eYvw*軟G"ӽOG5jšӣt4LT1TG6rzʕx6IVy6Or#ukv)IGV%>00[ԺRnGfm/UJ8pihq9NCUC?ss#Ċ>Θ"_%voûCDU*l4nl49ТvL9 \T\jOYd3תR%QX{kbB!NvOfD?ǓӟtPı6eV}SIsAy%di?lg(Ofmt7KbsvHvq6T=gaZa[!H 6R`T{V/*a~}ɾɧIjeTD\نSnhfkc5^^-oiyxu7^~5ʘ}$ۭY6r2vv@k ښä^^PYy#Qn_>cj@ ӽ VE$KeY",ѿJf 3x;yBBjVbRRjQBfBIFB^f23ɀҤ$< 9@V\\ n@fqiPTKAQjYj^If^BAiRNfrb H{~BfIjn&kl0ټxSUHJLJJ-JQ(K-*SH,-M,LNɩTHOK-J,IMK-OMK63343hQxlX -hcxl^ 1huxlZ /hxlV 0hxlT ,h-xl\ -h@xlR .hpxlY 2hKxlX *h]xlP )jxjg\hhxlZ .h&xlX *h8xlP )hJx\Q qxWy<_cb H"Dl1ٗ}!{dȮc'ʾ{Y&DB%k<_|>3=}skk*QS2Q@ je @$BPRR;w3/{A` @"QR]Q]@t*  ;" y ]QqɻO@HeWE%5euM5nz<|$Я% [řܶKB?r(tH}dm)T|I7JJsGj#>osQ1 Ia;;Z _Rdw!C b_ThdĨRXTLzxup齗J2Q@!O2zr؋L9?aAtz̀bFsB@p>t7تcF r%fƉ.q I> olr$)#6ɽOicŖzVq) s9 n}' j/!Ƴ(cWɫ̴͘[05¯rljosmng)₳L&\7kyǹ $LXb?ǧtE5D/QmKkz_[}VtVݙ{Πc}%~IqrOYa\yv_FO*[79U|vůgtSiޮgau/U#gygce}{3Sc?Wf~N[=maqdmj_{K[+[뛿77woN ggOB9%)).(F ~%3*䣤W+.6OAn66O{w;p_RQ_pvbnny#BOe?\y-9AY兡k!M)>-|Z aS)NF }O9x+Hp|XzS0~I~dU*ao'LMJJJXci[iMpv[ι؟h-^[@⃾yXr"&0+V4yPun69r2NT6 5Dd6 W>{Qe'2X)!2%:mrcr7%_[FeE/TZypR"1/sf{4]s/uqw<(>R:wWv.WQkW& 0"7_v/V~@Oy'g[Ԥ[ .2aGG706;|k}}>| $#*&[%u$`/c2p<*kKSl.MDqJY&o&5ԑK">e GUܱٔ{ė*Ȱ!fx&'%y ).LsGՋ6ȶyMnQ4mo/0y%.0oX\ϟko a5XlfES4ȡ]J9iqB睽iV~WP/#XqΫoرg]Y{}Š\ʔ>XGT`Œp8\ɦx5:\74GߌgE{q*C=勢F_ʇϬ [fVrr?wnRTX\s?<,{+JbwY_aJX::8-Jvsy3g;1UZC5 6\Jx}:kC6IGiZh+եoTU% .pEm4^[f{*#_45=4[H.R:Jʯ$w5%2ަHwGGŧ;%'<9dѠh*+ `R{M{'/kk]97i F֧ 6.4w&KiA&@Il9 %H'>>VK0Ý͒V!+7+w A01q'[1Wves\5[Q8ݡ&IV'o5.+Vuf!s҇nFavyDxl1 Xk=+KG L.9DMh}9J hO/%4Ә6e=+-#N+@]n m1!6%@{nVyzN?4£b$Eܺ !a֨0\ { XdfO >V }qnAr(@,CPګL K7y}oj'w.^|g`bA9v1-|UT3MMܓݫUPb4Wj!Giқ mSO/&dOee<9?N3χCe,Fe$mki\WhmRO= ٫CEM EΦ ξu̟I|kj9P}zV|f3 ל)Upo&_uMm_*_Wy\5y!8I0E芎3ĸD+֨:ҀpD/y|_TUaplAe| 6Β pKh) +Wpf6wGHjI<ﯪ5N1'MfW(LVDc7`LEd3-X7Kg-Po+× g@!tů $Yoy5ۮ[g1*G5omB5EW?? +Sug3$j958}ً;Bt0PCRkItm%%0- jϠEίm2S U^c5uYNjOwM(YA 0KD~T]-rF#R!BK_K_15Crjߔl=ϺZLof?q50X;Oo?",oPIwӳ/~vA& yS$oYa#W |8Tn0Nhbv ~}>pgu Xʡaɗ6*J`B{a -'l$ Cdl9FTخBj̴6—<1U{ N"е>ƽ?^j(KKM=@<ꭘo˥+Y^SO}knp3{{?uDUv1Gsu;)2RU DQI4"~y4DYtLj߽eWYRlW4k-)V%h 9&*f7ƭD OeqUD =8A#c+Ћ @-e萜x{TUϐco#[e(<4<5eۍ H[ TF$ay_HV v,eե|Xnl#$Q+!GŖi*S4:`қ9ʘJסWPNJ$;= cD̸!yIPo^$l=Z$R})tIʌ氄ɞf*#&XEY 8|WT?F;Mc6zo5b/bEaUJgq)}98:MpǖpL`Unj좞6A-i=Q:0Lk'B$DDok ¯J75֜36 jː.=GQpWB׎R/zH j EXx0" N E I=޵t#''KE+j|bIn!}x3eAyŇ#UJˌ!`D=D _p /h/kYj(`RXr{r^Cf3P;TuQ7$Uek^#C?^~0|dV(gM{>dW\a[!IdA=h/ouoHv1-p,F$&~ ~3q}7\S_\8MgD }v{ـ4M~~%2 oUΒ?ѻx)xw'%X#t0ѕޮ O^r"ͫUN'֧Et? T[Vvyn' ?&$ͤ? ev&g -I xIϛ,^QUWdX?YUەӸ2X[Rc4LNQz+Z_n %7nn|-/7nWL ;i&&UL ٘iG1$XŒKHr3q}:%;vIw-nr)x8U`Is5Jo8BD[S+PDŽazׁ@ϖbtꚡTsЦbm:7RM*( *FZyhl;89[*%;v^Mz#񫞫kA㜕rҲ=L{liciiƄmbh ) sŹ[A @UבM4FЛ%7Czkg(?|]OƧ\d*:fɗ [:gZ*1%*)}۴(f.`doMOlV¶{ 3Z|$5T~SVb^ <{Arʧ!ץ^EL^TbP`R=6ߕݨ=.нQmT/@&H+q)B/G* 6, m;#DZ:EF&i|Y{mruWF\Ǽ!6y"v3e8"ozQး;\#M4;wIrܮcmo2 {ɝK]陵}i+V,rhB߰¾uA#.YNy$ 9d~5 4x lT8eDrazeLnnJ0hT~z}g~Wھm۸3 (/+_ P)促)l'Q?&gkZԥǦZN]3vauQ<[_'4[i+0!yu1 2+%T"mwx] kc5Ob1dcf%8ZļR'ߦqB@D=[ﻰ^/3>JG {Nzc5gHԞú+50cUzġu`2Pd2OHU1i oN]w<-X~ } hly4^K5όy9ld+N>ޝHb$LcHqj¶G|*ԏeAAP53 hH+#4wG`(}>Qns _{ߝYap C2ňXed2"2-}4.Qs=a36rz/Яn)L)1fWp$LDw۾ԓ>8?_xq6 ~m#ΫmxõFP2M IKbBVlS4,qS#e/ \pWԚl^ 6)aa+U\&~ caeĚʐda`xxNZoƒc_J쿳 ]-pA.zC͏ ddr1+*E:IFhnnڐ|/f8qMq>[j4nI<yš!U|x?aM5ᴯGLW8Ua`łW6pZe޻@lp$yşv]zrH#,μ=="q51\I,]QHPB)QXU'h"̯R]ȑ1+Uv*ny1x|a$AEq|ɘ@{YvH@QXe@, ȴꣴCbY @C@%#d9HOgmWvۑVWi?z@X(ljJ%YTڳPc ' /!;3T]鬀r5[q/>Ӟqp oٿAv?87. $ _.+>X>!ԅ#or(iB LjHwę6SO/n].X chܘnH01~؇v҇ Y1D bxdA,x{HeG U?0QdGK'K\6&;q37*ՙ RU0 ^ Y}$,l%4pMp಼@Gfj |8 s|OOg dHY֙Vu.sT9 1B |뫥k )`EԪq.?4 F$NAq,̗6|a#a-/Y sB_a;xQ ([vȰ ^<,@ E'a ȿJtt*YA%PmcrX+GAs@kxɢIz"gg4)m{C&B$$F$Bj n[Z[S't_&#3w~ܸUׇWnn=Sm?;]jS>q,V)c'!A^erK*;JH)ľ AK>=U@jD5qv0gQD שbui %8 ^m8th˹:{V.5^5q7_Ss+7mQ]u9` ";l+ڴ p֖|IX3/PLu+[2t7sV>Dus_U*lA{:EٟܞS&9رܵ8 }r_:b^yzir1 4NPR_bm`YiUcیK Iket(Tq{H|̗PEm:hlX-p,miILh_liQ>!{x45kkH^ּw1}r91@fDW)u}3uƆHqzFa,<E]Uʸ+1viȗK_Ӯ&-΍[twpglw%"14:)s2˩1otE*g*9eB`{/intj=by~9c+O$rW묉SuH&JE=ϧ]@$&!g*l=5zy!0m'A3@Cm`Pױtqͪ03R: [x2{O*x6\CLp/0s$2!޽Soc|]ЫA9U= qѓr,x0>@ꐴi,9] =>gZi<ҙP>cnUj^?N:@l cbw:/;ƵL% %KWxszS>@F.#Y;W,NjZb PJ@%"U%tdzfY?6ҶSxoCx(7[C[»V."xǶ8:19/!=dpUNqaOLx{["x: l98A}\1|{X=1nܠA低9(1 Z `R1,ȊS{Ew'o" `&nS1ѯY7mm|kz1tD4 Xi/#`{R$!09Sas U@*ȿ⿲Jz}ƅ,WCl.Ɍs~fGcerf%:u(+#tOG14AɸNO/Y~'~*9!F6U'HVSK~Ξ))b]4:o8uId@E{mF]Wi?0ekITi f)LOIJB}EHs+# Uuب2DjXhn ;:ix@P ]OjYMbNǺnw3ƈt]dd3+7p՗ޣY,*i?kruy`Ji`-L! Mj ]lHT:jC3Mpbʋ5R8H?m!1?ڻm ^LS;KN p [7g m7;8#wfDT+\yC4٣cl`װN ""- [C UGfʍ)NƱj{ Z,~]HC;oʹ9-!_5 c?4jk.&IKjݥގ]9h5[I o?S,N$;Lm\"P3[k1/IS('NBKm<"GKa%} bAUp_f"[g'BܼOb$GB~=P0Gny‚ [ U,G uƄC|#I'#2weB~pKeiĞ61 K@.KF{<;!LXI5>x@bV\q~6'4OKVK z1 X2dqڂ_H>BuUD3&d(ItVd90˫zϬ g+IWJ 'MLiaFb%C6|2gxrxQesb}骝 ,^ ~JjQiz8'tMغ礚\T DPFfmP͕ĦMsr(wRh 6#=">j1b(DdBbTcc!F%3npSb1F]|+[ GHda a+߿A!mAo@)6Yw/&9GqD?E="ܬ(*f,^E7ϻK_޾Eb%BЧڻ.`>z@bxV(N'=ڸQHzX|w\.XӄNxN_M]%hs /6DhysL*O_8%A pxϸ$a:NÖg|"CrP ]EHDpF QӰQ56ByG_̖5"w WDL?)ۨZqԧ|?{#}fuknaIgQ%z[¯!!t!A7|ɕX9Ij۠ߐ&s&q?[1/C(^̎&C.=Zen~wVD1dDDcS!{2`Hʜ>ե7k<7Qm S U_φY'8h2G鶁gBWP|^9b"sZ]zʷP^= x,n4ӯ6B<~$F!Q$ӡ$WSav-H}v=I'e$)c MF$!a.~Fc7wͤn*!QeL|k3ŲSuꪶtx),7D"2QifkL'fRGl'R&ѳ4ȂZuKN[fd4֯xQҮv- ]HKIEI5Y7X?U+ȅ֩v4^8׶,5M1;,25/#mrwf N*m9:mQGݡ ŤCB KG+&]A>9p䐧x.rIZVM]t<6> Pp=ah$\a/WO|A™6S.ᵪHLZTTVn#Y^ 2^?t$ZV+.@+_ XK 8((*NVB"̋z#i]uxsX<]I''qHGb.u4 ~TKnDm !u lƚ%u}>oZlepao-Ĺ'#=BVw q +NGsKYKܐsي$LؕDeTMvi^M` 'Ȋ\]LL}v[[w1NZqE3Dˁ808$lInSUGBHGȾ2o jiZ`x;H%hXdm\ɝ诧A@&:Aty{ZTm{ܒ8x]"񟫀JI͘mx(4r\db;+)iú Mq!Th ;>+މ3~ƞ5pҨuJ/B͋Xc\6vrh*ݟm, ".nɄT^hY;*STV+Q3/NE#G*lHq4dIO]y]Sii} pƉztPpRC$ז*sַu&KlD w5)ޝS`ppY`n|  ^ڙS$fA׶V̢ٕ+d[rv"n.(%X,gz~ٺv1XRf{rq.Q)Sr`>kb^6FjV;`{$k۶ToD =֚GZX7g|)EVj5$2NrRZ F+%6t/*zrozF@ ;s0P-Aw_0Wu6::=e.ضJ Yz;c,K‚<)91+#j{zTG/MmJ'~޵gtE.g1A U TYjS1dGOpW#A(p:3u~ݢK5S.Z` 062c檵wpa܄*p߸M;c9NxAd9A:3"*$)M]fvJ( jƊ|SNx^sN6myMĐ6m&|%DOS6kMͩyLvs76Io y=okW{O*Foݴg1k:5ے'k៼jX)Y;C 񚍏; :}HM`HKiNw\uSYa ~8Ld6͓|( V )m33xϺ]]FV<\͛ڱoJN_^/.3/i 1_{yχRGgk-=Th~ȿ*|"S%jⅮwg=+cklrxz_`}a4wG{Y5#XĿ ٮ߻6 #$21U5[7CsBLAWr ,(duG t]{Ww6~i5P]TB BITQs2>2/ة&Di)wbVU3=6w% j@B/~$0?Sכh yibsw~\Sd*~TWXpV*_:hnU(s4}=ܨk!ݏ?bJ-I_R^Ez^҉˙L!TߋKmlq\RXvnLZexyx1^>^uf98z֍ʒߕuBĺR=䚿ଁ%q^ pg:7}\V^2%c d&~m%Sae*4譵3O͈tMX|ZZLlyGGJUSxxϣɖq 'Bam]tB%Hbv0Q('oOCBcdֽOe(jA7V6k# %RccԙƯtVKM$QC55yBb4<S lS ==db* 5$u9tִ]0np;PvO2deq4_K0΋J=kūu \aI}Lbx_7ڻ%0 ,Q:؃^M*h3D$BVP/!5!zϔ'Щ `Y[ZG:ˊs/# Ok$RA yؔQm 78y  WW8UY DE~ڳC2Q 6F}@&rU%FiV{?` ۵Z>Y(),] SY,$Pi:b54J?H8p(o!~GEqoW/EyK4b{t}II5o:VlOf-KTF'!L"r$(`$Qhl9q5@}݅2{:|(zT9B˧CQ}m婍ae0)ū[.,Jmhs{Oq/lVd%^ ڵV%! z@wZza9F vg"<1Wpn[hȣMJeFֳk$qXo[pr=~fu(sH'VJE>asx\4c]G AEښ^*9_Mu!=N*Zyo#ǷXLޟh0/qIh ɍA5{7%d^>' d EJ=_IdM~jٹt4_͈au,p ş#!η0_0m&3# 2VtciA糟VE2 86o!W0P9H޵fcy35Fߗ:daa} z̷4^YT`zFbj[3mPɥZ OAT򳁿PլM?0w&Ĭw,z᫘OG"ˑ&_q@NvO+8\ #% kEgsT+-baQ;^:Ić.G^YucjSҕT5Tr@%PwsRcLn[V mS){F+{KkK5UWUc&&' ޼ˠi㼤AC`@2̭`i8~[Wˈ/|gfKfH.R\e=^sUX6c M|\֥jӵ6Ix!j~;ᝪUv -"ZMڋ9sExS&+,6 &xg뵮\n]q|h:bDo&3TՈ |*1l~$M~!qKvaYP%dҬ}e1%:6? ?lM^ e 2j=;ݫ[("ӽ`Y ʅވ|=Q¹0T֓xz4/ZHVBD†QIժ|`t {TKZګ"Y$H B X=pg}:FAz~Eiuu]MBA@|,ؐ MOƥ5$y}&g*35iIt(_ iƼ'deNW*8>&n"y:$IJ' 5j=ixj +.]5Ҋ~ۘQݡA{!ZKx,[9䑨7/շ܉(tUMRI4Zrn)g| uEhffwFERY9V kT3/NfIYEg wvt2  |%1k [ƛ]<"+"f)(3UO,?inTXLϖJ%'bP:iٺj[P;"'DT7yfk\e9ҟ JP| qM Lml1zX.^ B[P }w nXž8m *hr`#3]d8 a]',!hؿ=`.kRu5Eg SxPaշ.CkuGeN51!$uL,YOYס* Wyq#_Lw|CBNPPQy:{r#E),>)A7'Qe02!(Gm[|a\ߵWei̚!ߣiu8twnNViRn-;[]F|oօ;L KYaZNp;\cy>it;mAQ=Q#EH^B0Cs>\"%jfv#ObDβ>5z;I!l"]㪢x $<[%QF[J"1Si73bDΎn Zl㿽,]<*k&aΖU aCcyg=cjtRzaH?4@'ƀwawF/ P/so56I-كĽ2JW]+=;] 3\KKUyXNչcT<ȬTrWm2$!3QqT*Hwឋsx"P:Ӱ ="/7^BT0fhG4ź#CjW([WOm @1Y&6TncJƋ8dɒRŧkuA~$2R'7C^ƋflV1|+#Ɩ ԭB@v#p$$hQ32= t|@Zv.JBayZ2G֜HgfӴM1N*"nh=@)$HoWI#B^<\:>[|L+ٿRDjv~VlqelRMj+t>;Uav/_ݳekd劀LJE+Mg4ВqŪܙ  T.޸pb U!^hGpWaTNcۻM6#قo/u|s+&K;8TSR]/k gw$׭_5&SjsꁇrlMjk Ćd5M惪PzW`׾Շ ȃ]9<+@K8BO%},'(StΘMNvv"vw{簹MՏ`CMeFjj~./j.CTGIo`˪=4G-wWPxzQ;CHSw@4e<VtK:./ dQLOvPxV^QsScZ"4fdwCu[j2zE aN* S 5*>XKf.70'?t*0T9k\A(2/җv&%Y;"Io & Qh/ETKWOxbbFy7k|Usȍl{<;5e}k_4y lٻSJ#>*s(~fK 2⪎㺚>YWJw-'9" D!Gͤ~ 9MWgBHj[z$h\p΄ܚ&ApUVn&1N;iotÙ/)UyXE)=?}v.$ݼ&SC\TSLaD䀳rB͟ tl%^OqhVg྅GZBB)cGo530kpԒMwZT`keݨE)_Ś߯S֞X0f]b%ش+ճBQؑ ̧FF9V_ ohAH#2~]l#1! /H${' v8]_2}b}-0#j\Vwo4Yuƈ8r4C[""|rR)iCUbɬ3ԃo bOZKz7pY%r=C2#s_c=E}@B*.cAqˁS'HS0h6-H,.(1{[܂ڢY(؃fk"'k-V]ʣBVVCGdu*c*wjqgM D"E~>X3؎sB=]͓lp 20~avM>"EbJgi{ɛ\ZC͋|Xv4"w*J$0KA5%`Z? g!AX Ahϼѷs\~X{)P֮䋕hl'F;5'0 )wPy`EWڣ0ƽAaƻY-NyvC%ITPtϓq.wXcj C6MYM͐dhpջ?4wqTI΄x#!'Vk(]&6U&t1CZ߬VFoWk邹@ӣYR"f!A6c8C^uwTP&spx\i~Hv !1nA>A-e9{ _:. W'`ӟY owa95]t͜`$O~1{瀛ygŜT&)& h_|$3eܶ+A熕@^0mNioJ? 01گ&bz3ᢙk Ne]->C,Q;tPk($H05ZW\ }9Z!wͭa,nưF7_{+HƚӖgi*;[\ \zd\/hʿNٺ r ձB##'x WVqy))Hi [ ܟa/@e0S>Q/)la ֎(և~ htT2] 28ZsFaǹ.,ϙˣذ &,?1Yc .P9 UܯVv"jYM8"ήεd{~A7iYi.ğT8g܈:!a*A1nauBfBILLʇڴ2i]l"9VL [EH=%p-BN("$kĄ&狓G\^K7uSNy6ߔ7Y,~ßꁵ|eGX%0Nd-6 b5%_*0V ~5S'W=>瑚TE<~!fܦ;a pjFM!䐙,2s-<1 fL)/OAW +^%L{3_m~rQs;#H+ cvB *y/[d ]DQT 4v3)QW9\_?!pV:5B6aMBEKϫ2;2 4ce>QʽBrAXNGxyrpAA H3q[XDk~MP*}\1> u}? NnR͊C4D Ȅxb؞}qȷI: qOSF  t.3[m:{=9fEbсs[h,) ŧ5lW\T|ҔZB%Tق]{N:P2Tn\Q .SkFrCʅ&oHQӊsRXƋĹF&&HUw$ Z!t],nwxw'q*tp򅀜T2B ydԜw7--uQe}уT_y o3'X.,p4zmORU*gCo 8C9!6S \!6dרv+i.  C m1T> š~۞^>% g )* ^-7e$3ѫ# <_`u3)rmEfhrx?j޸*ٺka:jUdFזt%Ujt&Vy>U ξMI:}R?[8<.*-XP$p|_Ox hP [hc&r=D026l2Vssxf=vr푝h=ȟf]4&_O?afCk;L&f WZ(JdV*ցzRiDx l>M@1iz2bF7|vw{7,Eܱ2ݞVMiM"OK)o2+a‘(`QwSCشIJb\5nL) Imu4s_u3u@ë}#ma6 u)y\} LFM\g*=|-{QV\foOor%>6 smi~' P5i{I!֧n#Ѿ(PR=bue/q~ }Ë_{Bε˼>']g3qĻ iB15eH"MQ8$ kPbmUdxZ'ȸɤ|nC?S- xF xN_rtWG8w|bY$%&HSMЬcqə{Hz\4_sVUп;ͩx֨92iad52ɂ1/nS˲gˏ;8qJ?c+AN$|>7y pQ}8!̣Mq)s۸QAQw#cMIY$O7@蕣gZA^f6#>yR{7 r9Vm8fE9xzܴ3_YOY :/H:֥T?9/yw;Π4q6kCjzd^R|lٯ !g g2ɞ. k],mA$_bMbܭTz6FE{عѸ& *+yARIB}*VB"0WTokm ".9z] ?J˟!NF8P!ll>cZ'ڼH 0;jgiT\xu|JLxm_cO/ef-}bǚ³OlwwD+:zEiԪWl &+eeKY$xɈl&ȯ;i ~P.~}nvqWlU$mF`D 6wtM"Rգ>MaO&beL[ҫ?۝Eg9\f# +SšjM`wXwHO) =z.?4 57т=-\jP\1ToØ902uQ*hg&x=3]Uo -E+1xbm9[/bvg?N!<JVk4(HFgR,'>|^5X(isU-;i=ۇ '쉖ͫ#_(tZkCr&/ \h}]s2}מֳFL^H{9|+!qwBquC^YL1?M&u..q4'ץ; Te_;>,H} F@JyUעܟṪ@;eI8(F,{4H_ZQjucJPHb'îe0STgu\٭)nOXAy@oVn;VSR&鶂r9[ ܚZ{θUbm]50mNP`c\)װn||?%dziȲig_B}e^^[uA[Oـz@]ylJN.8Q6*zQ'F+ ^=]O*WfmJvⱩaͷ]L2l;N,lV&jOԚ]xJk9LБ`+Ͳ򽗹GionLp]գTNR̟224^οw u~[uw:bo_~/0zS4!':XS;Ux3nt?wS,^c4:ȒG1)Qȵ687e.)mcuüni`ձ׶ItŬɰNLjA&JS4bBuX,m-yhUojl1?Φ=97Yc2hiߗGX]H+O){$ Hqd#7K_9k>JƁ.q:}]dދh\R ߋ+[5%3z#|ގR1R@pBUoҪ!hÕvx3@Y}wޠiCi ?<_c87LO2Z3c\k.˦,"$Pܑc| L LoLvkN9]hI{bje;Sqz#>TgYR$,bSҚ :}:%Y&HJ%=L`(-YM7ᗐ#h^[~1508?t~B@΀)uK^ƥ`ft\2{$/5Whv25ZZ.~:J/盉h3j"{]vej lW,MyN<a9`JFrKo] vH}:Cf{!t?rFo~3ږ{`hg;Hv|~)H}ϟ:ܸm۷:67~ٟ@L+T.s÷[`A~䁑/q旰pۛ5$ }K$=U8La>${mRVݶeoz,-Z}_ݜE5gns(HơM~ wu~~ XZ $2 O='"]67w3|g82)9rCz05Ǵdfm+KwVA#ߣ"?QSM6J)*V?ᷘ}x:Yg:7=Ts cLַwV~*Pi{"apR'֏~{LO2PR3<\sOsQ7?T% 5~v~7]>#"H>pdKvMݢa@3~77~QbI霠{`9x1j-tLA>niXg[ոrnʠͦyH{<+qK0QF<"P-;EC,75Y/X 8vPZicH#ɰ^NJxq'L,fɻѹb9]Ƨ+!|.vhJ XyȊqJ?BDw M<0L.祐Zcؽs$[sPz9&αcc]iVoU%ч|fOmҁm~tBx4#ꉫeB7Lq3QV0hDK?+MQ}v!EX%PT@1i&Hmcć 7|=P h EwPL*gQ{/j:=.=? R>/nPAUZQ({Gs ]Jt4f\g(II4$*6JLDzx4pCuQIo a),S-}7x~t.s9 -JG\A~ͣjf|I|,p!e74 :\uOT«Xo\ ;!ҝm#sVg.aJ!x=rVWݎ4IK^RxX?[vę1px 8K6kS *OУr,t ^+a0{K,kǔB3iVpkxI.n]J!aM`7s]e*o+$ʾ'|/}@P^d+ W $jvz.5i55&H5ĭMI[sIVv(kC.MvQzT+*t]Hss c# 5ko=Zع- 2ǰg"(aPƮ2,X ˤ;NF0 <]5q1G\ #/,E46NaxVbAg*:DA yBɽJT5c]Hp?_z|ퟮqs8;aDw0 "h㯩b/< ݓr[9 HlH=)=5 P6{1L?g~n&ea{%O֪WRQT+rbuԽ1ȌCYggm*'؈{"7<Gs5[uS. .z|oadm2~nhHސMr¾Ά9Vw .p̿lLA<.w]* 2 p9@aP[]  Pjky֫cƖ3jT~" +f o:sCev/G^{\ŒG.<;؀l;SZ "}s|×OaF R`!lLxόt2_es"0ʈ'wGjZ" 9X2oBI֓HYzy ܭ)UK&tSo]E+8|&7=2 9K#9:`bR j/ne9ۅmhtn}@vYٚ^ sϽhT= \1/FM>bsy:_hz:hJWAO|ժpY-l,WObdo/4`mQRғj5pz/#Rxi%OZʫO,g_ "ҷeճHkB\gݚa=}4@szbؘNBwZ[n ވ[*v)zkhgp 13ˮV_~PƨE/́p#2Nho%uFuVW>"#-oK+5 V|ZW-cwheɰuЫgA5j4i3 9iA㺕(?o9"}au0w[eڝFu$K6,Zd|wwʱK6.e7׆9 އ}veovfn D*"8q1?|UJԖ9SxrWp.i?RTG+X7* <(r~S(+˶NAڳH0ˁf*Ua,݊JVʰ%`M ?PWu3lΉ_04R3@z6zn>$8.VMA4^2.igmS(]T끉je7wځu' —|gW`cek#Siw&_$y}3ڻ-+* 3evqe.n{S/}hs5 @Emo&ÿ/I aT; qŴjq/y0 ܌/[&g"l*˜%'Jf\huoˍIqw]8k@0}y9Xԧ7O#_章ˈeZqޗuTA)a\!c"ɢ'wۊr I~W; x%pep А8!KVcx/ 3 洰> ~IvopM5/V͐a#}#V(ZX7jy_KݞCA:ZEql^5As9 pI2a"* 5g G‹è"ֱ* ψ7d{ ^l2/#]ݵL!>s%MJ`ȧ=bLg$c V]4 煱,mmYU>WJHboR:ZqfFK]WO.=? d@y7C+;xڷ@ӢR@vbj\v 0=)2!8iB~oBqr(SB>S<̵tJ !n7a =Mr0VAoװpN zie~vf\IqEb`DjI6뉋W[_$MAIG Sٻ:sdL%R9W-Xv eK1A~u/oS'[KIPZ|Г9ڷ~S`8zVR̦Q~?k HN\&oTKلf֝Qk\<( sDz^4As]q^%= o峵Bf,A[9eCk^:nlm mna͢K+)Ŕ>lorxL73?H@fRؽ.d۾ϕY?2ۄ]cXJFIԴ~M{y6 \W'$%}$u؅˰sd|N!F"q ^k7pZܰߵЦI5{(T|94"Kl;S'F})_7o)h}I,͜#l Mh?Z R KW8h Guuosiu$EY[riA+oZ!~2d`н)t^Mk&xub|5 Ox ۡmI+m$4.^߆V :P ; h?fJZWŽV g_CT͌w_5L:6\`](;,Hڒ =ᰞb|U۪# '7w,_P΀jvdc~0.V n:=xݎ'4[/x݋/GSKhy7<#"^5_{0^Ę@ kq QP.GZzͱ) s&4K{Eg뙫 ^l㰪{ZEgK|# f1<#( 1I-()ATpmL1ᓎu?olskn38>~$}@+y3齠a!yXMpAcn ,jG:{5, f0;c3kGtG;8"PMh:bQtHk[ӿG#7h ywp젆i ?xǍZV3r}t @l288֢狜l ͙A)imu?8!0W?;({P|=!μ q6AN/̇/]f6MULKsjN`\sUg+ FF6Ҝgؙ5f({aqQHtqjHG؍A 0.ԁǑINfElNIL[JPgGGXxx|wj*qoIGN`A$rUIĻkPw.g´53fxG(wWՎ )i:%fo`}yb?h.GOiÁδS/]%e2id͇ "g&+d&[ N p=ncD HI_W5\E:ڸ =J$Y[eUSZ;k`&]K?t /*V:r-#n c}ngy57Yq jk8g-uo`bl8ˊj0tl#Ǚ8,87G% .3b^vPC NUy˭m'[U.22Ѱ>YJס^֠_gN.j ֗.5S$C^ [Å]%]Ŭ9Jn脬qg.&.|5[-[ܫ4. $W6k<2ۉ\[@elz"U#Z[Z@3{S7-+V`3'.0B )|%( 綌SG'+DWzftiD?˝p-l6@ ][ o+\YjbwYuv<=KpO b _ٖEAs,mwSZ7Kԋ>U GM2)ޗ0F4LۇP!4'ʼy-ċfqoM޹G⦳^/"g2w50}h8];lW!ƒ{l3{hao71یD~Gl[tUej ,񕞅~QFӐcjڭ i09(ۑwvO[m{u5ƣIGcPVh f$q ]PV:v qħo.j5`B!rGiE'Vija5~LA=U .W}=(wID\H,He3&x̵Fv:M <2{?lda#j`'jTU4  <$O @^vg '?)GcRYK}(zk k0[-Wc28U0^s0ɣ~#h#/ Vxv՘E&M9Je}݋pvO )z<3p4+R)R^ %m?)ǯ^\ RyppFQTL +lj6O`xRh/ b!|?{?9uw{eNa.PW%HJ-l=]q0U\nC(1'?ugW?VZJ#r8.;2kQBKڢd^.vȫQPŭXyq# W0I7Ag[Sܤ-[H_\abL+IH90`XBXûǭb}Yv5K,9ĵܷ ,ȗC6.m:#P[2F!j _o!v07A[W+ݬuAĊ- 4GfE11m&έσCаԡ(R`p_`{btjQ|94q)Q3_`:-ڲqwAnE^z9uR h(H2^k]x&#w #!<Q|H"N݌  &#LiXLŵhEz7O]lf&$+Sil8j[7hQ̚<2zC*7U*}jGgw~oeͩIO;Ix+v+9`sQ zG aɆ SDn,P`GL|B^fp*Gʎ>!xY]m +޶Wtھ?<=d.,5{%LR{ʢ]/Ћ6 ~/vMȎr<ݔLR4Ț܉ ?LPcskZ@x75P 9 fv-N+l>*k9Ũz6>!<:GB-Gȸ\n*C{k?ǴqBsPD[MO #,HFKT4 k[k^޹-jGA|Pfx:Cfs"TYe uiQtOl#߼9\3KI _b) LTgGv,[L o'>}YD)e *ِ̌J (QXH~m;m$^]جzB N>i ­}cg]866e Pӿ}"Yeo i9¾KSvi(Ѝ[{Fߜ1!< wd:9CCny=c-Lwȕ~Qj?xgg6Ҝ-&,gղxIV5ㄹRhagW iYυ=q" p?h?mpW=jVy]m H?tb?8yFt:ޣ$y6eV>i9&:ݧAbsj9X$/ޢ.RîH+T¹~o~ ~I-*&lDFFG;_T…y٫X]R.UQ ?ZcuшR i}6=_ˍf.;?$dKPo߾҂~G.l)юUDxZ9gnp/!5-U$#)ư"UIZKmRZXH3{zhx {Aϩ2r@< D6 t:켷6_ȼ8 "+ V/UB[} ng‹>.ݾSy_a2B1UPzڷ9$ m ˟>Yq/*첊fWc37SR5b6 {A9+/͒ˤ:ϟfx9woaSmmqccu>GUbό$v{j6eFltajcl5ox7tbE}NUE@f;|sgӘ\cOFʼnuFdX~w+9Y)F~tݮ gcRu]6T/Gd_y} ٥RܡuR=:Xu~PҒ$b}Ew*_w_p;_ᶾn{Q/2(R8jv*ț\5\[R[ڨzrim@H[YzPfURz=zм0-m,B gwc̃[xfVu)7Q"5l%XIf(sH6q䕇 IpP:6y[3s.?,f|D"&?P TW =LF̋ͼbKEL=xqnۋqXR}LךQe'h{ DL:tCBS1wCFUa 1, k&gf &l;'$^>^{N!^V2ӠӜ9Iزv㳠4뵉_/zOQ8R|6%D3>X@̟'uJ, "y\zr[bBrq7}D oLG|0yܔ!V)ݤ'S6!kf|xϵ[[cN0I!0wT]x&~7@'+R7ҍ2:-!c꿬njJ4;N:07()oy1zvKx}J'# 4]>NMv4^ #2ܼ_`D;cp.ƯT nXQ\AͩmM) e$K<(i\!ga㫆$xBSMCVĎ<+z#9߾}4ˁ{1Me9qXo{ yQ(|ْW)+]sJu6;5z6H;$eI!wp첛zcxݲCbWwv~tDBS ֘'/ Q@]FwpB֛ 7urj'& rKe} >HfN5oJݶ<ֻS9xF$a"lyZض*DܻHr#d7G&cE#%J. ^WXW9޺guqհ=FzSuw,k>Vc][Pm#!I rEfx8,k,1p~kD0}rT/ x7VDh$Ƥ?/F~E:XX\4Kxu@DKQ1K(I>ϓ >W}U@m}Z`^调[<"vmN͇^kZ0M 9`^6.s߸J%%:l9Z5b%uxz,3&LBg9\?`#_Vg[;Z ptA̛ݠWS<r _,#K?&8#6ȝb[]e3>3DaS5-rZ%u@PDŽ5&"n˜S뽓i~#c}c_{l:Y~ŋwrd1#a/H>#B뉒?%{9-/b:)], 1[+qIF\BN/u]stG7P%U ɠ7X}nx1)];o{WJi׃cX x.Q916 w>|7zō}JuL|W~I#Iʛ(e>lH0+ҧQ6H{ 4D^ -Re 玣Qx*78tcO"]nZ+${yj12;H/b<^mz1yzk\y:2Ix!'mSlM>8,]* Bgo)^S ]^ʗȡ?OG+쩍St.Y$r9"7j~w7D.H w01hh@X~2{I!CvDsSUG._=b_18e@*WT<_ #l";93ћ7\"8TJ~qаlKBZΚFAKq %  Y UK3|e)3w#4BsZ+}z^7}2uj-&_Rt@`۪}ȴ-ly*۶+Gm6/ȯgTSg P όH֫?w`QTuZDɢVғ|CIJ8aeb$- K% 766{Hύ9Or545`&!A%a=xv۹UQ}ԎTS'JHp5GzRE JLR@y^g0Rn|=dzlĔv$CB &k=ݐ ǃjh=_He͹Xlflhc۶mm4Mڤm'>'gٙ{e]2-t{Wk?!.R?}%~p *voRBȟ.|U(c&7ԏj|yQ0(DJ+Ha'eMG5 [ yVgJ۽o!rmQ#}gS+ѦYLN3Fs@4Fx+I[($F#kbsָ`EWOwO-y-x) ) EJ<ڗ!rڅRAmlZx crzv`z#/7^cfZ Q+޳)b:qNTvd|7'_x(Ryo!?'eO\OY^pmsך=Oa_![mPu+nV Mwx p}1<6QQ]^V5Ls6kHg*J\S.>>`OO`EpqԴJ6T8 Cg6c5<ڵ Bw4\؁:+epćř5>J:#-B)#Yk'獄%,}jb{jy6j2L4' ;tZ&9 _9l!{JtЧz$'̄K_!G*||0+P[cV<Q9ڳ &i<7wCf1A6rEb=^kЋR7aZ;>5 3)\@sb.ޅ?73U{ F-ŧ6rir5Dj(-[V6D<^C? $HmrH#|8CK9EedAUIuyɣglFCc4xeVSIER׭bBb~0vit9x+ dv2id@))Mv2{ѯSPsEM<ӯG `ݏ=ob下R;Gׄ|2l VP~ EVEn ccˇY]-OVlQO$4%bMXIqP X+8ՙ?5-bIw*a'1裓Rs_dJRR-f~%*H¶7B|Ǫ|NCZ/8)v,Z X'Xc]cҔWkUbkZۃ S-4k(#$W-W+Shar퓢FDZᰕ\X*J,v QBօX4QY'mVT\1 G&~Ytm ~H]Q);k8βTe1'[FXM"^Fa˥E(D*uc>9o_ͺG.8a`JXǎY8љ?9z(Ns1->ˈC#i;V^I:讂 B7'(c5Nȿ&5r$q5Um3WmvXޞ/Kę>5kL k j\4KgU]ݹ,Wii鏞*@,aO<%6@R׊92{Sdypk&kۥKȉUDZ4$&6¹q=ZE㧉@ h_":*%ƀ-vLhJPXB>ZB8Ͱ!:k*/E 3Ւ<' o2=( {FT䴌t?䲳yscbtњ(5$vVٳkզ G'7~yx7l.5pNß> 6- Ij)Zs{ue v(+=\d6D7 pu:!kÛZ)J3D)vr&+Ō = Oo5uߡl o⇌;)XDD+)fvTóamjmŧ*3^jAX yR2plJc~&::PEC"A^|jNK#E{:8nCBD NYF4_{hc^\L{R4^~*t}U:a;ga-~E?⵺A _b#MAeh;MQ=LD%2"M7\\!cs8̶Z0sv2YpONjQFa%;  ]ˢ JvL(KP x$ \,L["xb#[ܕYj#RخJΤe=g3¼Y#@6q/߫ƆMVA·`v~;sa +%k!TwBfDɀ#:ԯUi#qJSDEݨ +t˦+)UM884Oq]])b(j9Z!Ha-r<_k@6hW)8q*ndB£B?=Y۲g͏<wp QmVݑZ(4ۥ3c7G[&Or ]_'OT'Ikp^ύ@WFKiK,GH^s3`[M^^Ep DׄSiYbD^ ] -g A8b{S\+cd f< BtL;f{˯a '6-V)z;a 7 bu@WV} gF"\ɀ`L xF1DL@]z6P2.w'~ v%x̰QO)^4Rbn&0ܤ:zźFRW.x q_2Gu F1CF_%ZKȸi$5H 6ќ D&ۡDifg"\ݵu&s!JAjū %l?yL8LcLH|Yh_cUeÉ6A]8:+% Ϻky iCj ҆mw~;؛cDb\7m[vO/zo;MGO5aĿs"W|X$uj({f2MlA]Ks7Ze+{csPLþqB Ժhl/Cp|ն KW)-kTi|]ɿ"FChΞV|EQ 1\vg?ρBƘܘz mL/@HP'lj#U9 Ϧ5aT~Ea:(ķI, -JS$a÷\ n a4"N)YZDvc_cV ڭ+MKO+i7wz~Gk;D?sq;߯x;\PAzecʾLu%X=<}B?NϚ %׿_!%GKwpd)p,jRkZ=T^/î3HGz, O0 Vbk ZP kŻ .C λM;"j5cHti`)rV8(AӊJ3 GCrHPJrͼܔn*A*ZuVG-H{a&~?`+{eqtAEe)[>1Ew"N $n5u;p';{zz:$ ^8E0;ᐓȓb`n+.H,l NEhLX,D]Gf e SoT7fQgPpt Lu׻Vhx3LGJP=1%6Y 5,J}4S3C&WolxQ'7$eù'J\"S'<_^*û z!ʲwcE޺r3BI7`2p$IUБՌ7ij.ltU4k*|LYxڭ%n ,y%=|Gw|Dq|w4]qȥfڱɗ|:5_ZG#$^X @s`/K25tpǗ'զ~o7UeP'|9!vz`49_)mE謫7P)T%@>i٬2ce)`m;!/+⏲Y:TĦJ5 olc^fۥߚ.-zIk|Vad22Cϳ12덆nCZ+)(P$)ZmV#(2Orj.I%nP-(-wUĨ>\cW}ű]0k!澐,-J gם ??I0_jiz u[ MzG> ŴѪ9q'B({?ݥ{..JKl|\?Zivמ;-GщVɑyb4{Շf̩{)&eʾcVk#TWÊaZפ]x jՈBڳ-N5.lB-1K"2ѱq***3 5+#9IG'nӫZdY9T>/OH<RҽXj\o4F!4`KPnyCBB.cAOCfюRL(8'%a,Z+t ZwT^v(%쐏 1nݠ5o8x6Y\lqhb !D'ۚD+F]kJYmp؇m*WyDYl֨Llp| XnZUh*X\iiFgP]n `۞뤭F Xe30(pyPzfASzueָRy22^cblez`gc}P0(o*LvՆuOdAzNJNB l[돿9?3&0~J OUn<X$'̊G߅ v (I0vb/֕P 믨s %vJN"jn%MH y]S*9kSDze!)#9ePt 3$'n.&Kw[Ol CdJcEi5 xh4o.07i'lWa>d>B]h! Vg1$CyCAk_@l\TIG@%irɸњNYN .Bh<gM. ֩kKYjf\nq!ob(N|ch A߽ݏcÑ@Ltws^0)59v !/^_\/9^g7p#t]/N}gs-oye]@-:"^ ?O bFb|$v" V8Aľ\ זom/4/[7 2k%ܑz &Wy|%ײeզ>@A㈳XԯxEs̻s:8ѻDTB6Wgi-I]#6-娾>n-SuJJ ʼcT{yFۮNa)SxLB4=ZH&^$?2y}PR!nXq(s0st9k|h!J֤=-Izd3V|TE)?`2⸜ A@pD>EW,n8&"#Ncaѡ<AJ-mκ=۲k;>fӜ*,qg+ͽz\#]RfDimJ7AmuDPt6"58zJƳ0e.h#2.nͺOge&24o}hm:]c3#lkE\0x`h>^dzXo}Uhs`D#p07;3ӂ>wQ4}X/"k‚(h孨\]oz>m/YS:vpO^\D*m6= ~( <2=Fo:n8P[X"~Ŀ [ 0? [>$C^]- v aIj{;jiTVkeǍwקvZɵ vhX&k[V)XyZG\hy] E$hg;Ujםg 8ѝ|<;w=}\wV ]ϊˈVcmws;[XiGV\o_4/m@_6Kc/јվKi}>O-=?$Os|ShFQ'fIe}8HQ)q(A@締2AuELZۦ΃Q2~=qD]~8KxiqL΁{{}tB!zEA]kF]e/7tX% 3gC]+.c>wf_P?pˠȔx__ôp&fR~pņ7{T**R*6>ou\ϟY!.OG_9Iw*>;.BcokA&j{纂N/uT">,- jTJEe0L.+Q̪A,6=$ o2f@Cf`@ ,ӗ'gjEx-L {DsAD9@YW=xaS"7l:RzYFf `Y غO,+}fg4E@;;0a"to`Ƥn4qvwa"J15 ̵,%CpߵM0(~4 l Nsf$pbc1ЭAx&0cr#P8N{2/~)<\˹ 2X}q8ok5氷̿yܟC FJqcgvAiY9&=1WPimn;_)8%⼟keX~}ج=G8Y7~,* U2U-{ġљS>O?jq*-b8a􀷕Aa X9E_o{U2)ᄉsN!A>K叾eyĒQKɦ#IcBMcO?NA?[q x?0 lV<=6]#Y`IT~ɷEl,"'OⰏ*$~r? SGo˛`(C5[ %6%l&Rph"p6r&{9!em1a$6wڧKftј|x:<26bHnX#d':D, CfU|{+ ߁r) ObbD/k-16% 6 c^I񁍛 &ӣ6~ wkrʦ 4??f{pӾ2wtqⰋ-<0?B'cLKiO%Qx"bEb4 /s 5,*4aP 267*J#ZQs-Sfʽ-fl9OZ>O߳-T8|Ik5ARkyEh઱6Ljdʪ /m.z0T;g4R&>ʼG/U&+q+yjB',򫅶ɣOB&.-|.3$zK2M;1A0lrv BOފ8D:T_d\nʜ+ō%ŶN6ιOzIܰ?h 炡ʞ͘S%2UGwldT"QG1V=\VetQ]dwm%2;MznZ_u8ҨNR@m^ĵjj\;[ubڭ>sҺD94qid >mFŷ?^>lɃuܶ0l$B<3mC~ngWi~q$— %*J|Gã986FGlZ[߃Nq];?mdZYBv@eX5bw"qhv/.z9 3a=D-C򁕞+6^hW"ҰVOՠ¶ADZM>ǯA!KpC~Sdz㫡nԳ.\3,O`"9e;.=78|@o[ >;,-rRXw}x}[fnO+- m˟C2 x.~I; f'B 8MtCcd5BMJ!iOi8m}_qQwH|^z.}c]v{ nnjjee$(U\VPC1ϘmlWDJv+0Rt*wGxa5(y> ,gwDLgvNXͼAmػF RUWW;@S Kb+`1Yg$_`^l.I1%TcPW$n ?Sj2et}5V>[Ӕ8?fjG+s >Kg~=oZP"+l(_LhZCc~}j7w]dѴMN4JQs^/`t!Xnm'7I]&A#S!@p_'VV|,NPMb1bjw9zCw=?EuIj l2E`XHK0Iɐgּ6z:4ș4Ѡ^/j.,7&xK!o8"+d&!w:Nkw;V? Փ&&?2<<^D~iMhwFu2~9tt >䃽_+ }N.5d+B8C%+w e8瞯 jgMoY2Do,K|^#J1g%9pkEBeK ε]S}zKg΍RؾB>*в/Jyt²@n1nw_iJleXv`,MXYSli0io` oA`9qLo{ MXE]Jve%a ")lUIxpr$۾iL$뷮(H?,VY4w\߂;]twj)?ȸj~3jyPԴӊa ?H  {ޭ~&cQY<sgԘ;-័n6 2ؼ>|~ +!m;!:wq'-bB7@ Gɛ{hѕAs0חo1WX݀`V|٨VJ*Jx=>7gι#Y $q~}MV7/0\O S =V޺%<6Q2 *s5_ f4챾)AP%K\I+<.cSf{m26[/;;8 G/;%tE|&HD8yRt ;4oŪ;d/{+Bs,!_bVS;:["Ϭ>vg}d`׍"ߎl-}׌oo8G06r m^t 23)2f9RtZZlvc8\^0v K+ XQ"D8>̯ =^u)&ًvYZF[uZvXosѹ;;2!!jgz^zorXI`de7q`؀ю\/ >\bLG 6?n7_,Spa3?^;̂08woZ)u]f*nn=5#PcYEj+#>sz+%AVg[sc( z>n;AY|4C|Ptjf&Uч x pzQ#2j7")zge;"E5;tB*gXxg|sF s8C]#YBy<: Qks;Arc>2'E6Nzd[dIHI3N_YsZ,];F>l/"]MZbތ!DZ8|C9B~S%1M} J[a%^ @raKI }'pF8lkb%uZ*tL(O O} hwYR?[x{[S|53h^~(߃[)[mt?gSC̢&5p!tdD 60\ϼhxhB%!{ZnfQy ʀ)oPrTcdƺ2e9 uij #18Hy>F)|8aN'qXj7Y#),yz)/5`V=ˬE4]GZF!I5]CA`>f68/χ5!r _-b\Lb<(N܈cvd0{ꬕT/[)řZ[RRwlZp{:u֚.3\h5ءurFՖ- F{^C@ #voh5kU}{x?W4" Wk~/ĐzK8j ٺ6~;^XFQ{z12]!mQqI;yPNx(tzNM˥C[Y5p`d -cBVO*A y dBFM+Ma? sDH%6-&j 3Cb 5Lxt 3XMI' C0B},rTҊE^qعŎ%fOcpm ƚ)272>җ٬9$hԞoHڙ6`D>Z:Li/m?>Izjp)e )bTwMA+YAIwV2׼uΈHģ ;}=qœ;y8\rn~m/ qD/rG]1>Da1V<" ?m_OJsQ͓޲7ӟRL 0 L[x\A迚;_p&N9俏ZZV kfN`XPJ>L~C5a" ]j=F-"/yLXUmTf7Z6}WN@]6M,oi:Qv|)Ct^A䡮@LpB9<*8A폤tԢKGҘk  NOLɓ[=Y$.C#({lt=н@U@9…[X'Fun<^u(}%'}X Chn-L?kB Ww!}'aO 'O3آ41BYwrc?*OyQ Ϯ' _be.\ +$Wt[uEbk{c=_78Q,b|lU?NiJs[ moռaRHƔĮsRi"r1J /#R'5ڥ66!xcVN-+mfa3A/+=ͷ{7Ƞ#nx$Ne7U @s|P,Imiظ-p 6~j7 ZrbHaҸUKFoU>GDU߉6zQ'0_/];~1А#6w,e[sw>CC8xl -c~a賒qMC~Y P|Wy~)Ֆ~?Ms~ MpKŇiA2,[* Qj S齻<+eqn 7f%\TqHC쾪fZjJ1g}`dR4nuX XmJ/RĚe3b^A;&E;Ju]5ZXD'<,Aʤ/_Mqzީ%+ݻ`7H"PVx*Khsbg|h^++dQq֫*a>COn]m{ڦ7iw(;dzC`u @{1nl|Ɓ7r3 dKnC"KC}n$1kdGԾnhM՗;b^Ftᕙ~XY~$0xlSVfvɹJ~V7$r7ѡ3v>WDmL}WQPzQ2߂쾳  1I0%7L5]<ۆQUծS`w*KVFߖ]ҘVEE9r̎l;i̩Z<pF?pY}t czKB#cC1)kx(H(?id%l;# =Nf?N?Nʽʟ?w?.UJ9KBe+o1nr[YElFGkCe'"89*m<%*Y?U|Ef]!snV!GA%u-Ҫ^0Ү&A.F{]*cX\L R X֭l>&SC}!k̊̄m\^~o&kCM45}%p4;" 5]P)(|pBuDXCG҇~qU7aCF$WVsx QY 1ݓYYZZXR79#zΩiޙOXA[T#GNim&+mu[=g,C2AB0@"氫`Ĕ8,sP~|[n^UnNjsDSJRI {8fݟ9]M-z<{֝`%"QV`'uFOZB뵈 &OTuNųD`{ܠAY&W`k0m͘dNN }( 9UC例ŪQr: VfF jtGuZ^B_>6pSxdB q3^WG<'yhפ/z?s`]4>#|jG06c}yY7;8a{['{yf9M^n?S܍f߹UX "!SHp* U{2վL̓ul|UO{H!þzB|.J` !NysYAZƦG sRmCb@3arӼR̵Oi*9L_Qml6vfu $,r;c?)@AZXveݎ-H)xU]_< G5XaŁwW/MXdpF~'}4Id<2~ V&8lM80l"9yn^e]z(3.2yjTڏr*͔3PȎv~q,(`2%lL9}T?\҉2Z[pFi9$Uv/aW;9BxIYF)9!HGeWxMd606HbUFgVؗXypp(1碰G%ʈUTۼf"mCX>&l,+s(zm8ym ٟ7 ¯ !ds7 <%\ӊBG;qpҸd'IU~X>ocaW:B& 4BC +g.ӷ!6 @^$/T#[?BLl7 h^?@o]ȥ7.J۴ V<% Z/g&a؛S8:싈my9 _?JKFeِ\jMi= V_|8b4 ù{N8L1mS҃ieⱎE%Uƀr>pZ8$1t(=7cExNtO#_yY`ɱ ^>$4[9ۿaOp:({+?g:?ÐppŲEV -6 WBUI >>f K(|Fс̙WFK]C-QF؛ T{T~;tو}@:QdoQԦ}K?jS* [vS[V/ o |;_;FY9eKDd7J> : G<7c>*`[ 5mtWF|j8 J =MNKg 3M |MP_ո )'c=ٲuC >8sP+-M69V+gN`ѳ/%Fcg ~Od>4,q!5gV[MB(b RA!:S51eR *\  FC $Bm#ɩ3uڶ/m4gQM44S-UZE!!w>#9ԯt˔#kVNgKKhWpR^͙ʐܔf}nQF$~֝aRM8הc^yS`*2dOsjUc(blחͤ٫/M#z{~MT+Ts~G4&4s$A(O7n$Bq$~Y.8!d&}R)8d%VFZC x=ruF,QEX Z/D#*^ kI$[.@Ύ{ x̧Rom ЍfVr*;",$`k1M?nk?)iT:2cag%/q{ZՖ$B¯:lhm$c&S|eNxqY~ ]VWΗGCX) jPv[c*fW}j|8PrB X"`0mRPbve<7p#mTkVo䘎]vwtNAm:8I:Ojk)GQʈuJ(TMJ#.C3>BX-kRg%joȬُiy6ٓsJV=,Ex~l3ˮs&#Ǟ״,Ֆ]6Eб߿DZVD_J?7 h{ݾ+ ?ʕU.\|9p{uHA TMLnڅGYfDpzd-Ӽb%A\p /]D RRD.CO!RhAsͳ}^t*"`tn%P ;eQ9@,SehU2;l 0v<+p&qJ1Z(Bx^Ŷ;#)ƀ.̏ef,R7A-6͏LXVnc`u*/ N?%v8h>:V9~W dv􋯗e# 5dLXMW15SWCNW KEMTU]ԠMv ͗1?:T~)23PYnR v 0lRF!7U}龜4U}3BU"–0>$[ai5b;;@f\qhz܌k20 bŭ`22-k.Ϊ)s&"-qvϹEKhEWӶAbD *מ,MIР_;_>9K<,S iP3 黫`ΊQ-mb4PϪ[|lrz;_s%aDmH`8)rD"́f8:L-Ռ'ľ;\Rv4;9r`?uB+IuX{cjds S4q5?S/ܟŶPFF#_ P$FT¥Z#Tr HIbbY+OP@ ŪJB넏To&ȰXk{`Qж26ݨfX_et$<€?inc)Dkϓ[i> A1WQw+-UA3<5IoZ]ݯf2Ys]#(@~ 7[> &ӌĚBPz i>Zpl_K.SpGzL҉-~8_)pujy@NTqaa4$ixAO`pBRtnF 4*"4dx2HrA%^Nx$ r(ljDR((ufK9l/46]>BC韴D sj{!5oO;g*RyZJ,?ԚEH)-Ʌ9,Hn؈ S4)U€{{.m\UΉA]j~p|q);ȘYc1دƟlh4N867K)@j:8KhZlNŘ4 ߌ;rPrI|P+zAޏ~薿l7qW1-5ѼԲD:Sc{n{6=K@B.P2_ÒfLsbr9Kf F95 .&Qedv vDn.H7- %V 2|s$Oz SO`]h-^d,u:uʫ;|մX4AkeOXO;ܧ{"p/gR?~P,%}[dyhsaYXZ+wu1kcyHa<7/_fS?&m܃f^M+ kpV)flS^8yh~/w ܀dҹ:7IhbElTUW(HQcbGWa?>{\ko7HnqD痬RW56%5韃W’66Wε3$ań(Z+ѲqHC*Y} tDf(ZJ8DoO?o)lABUb+Bw?ë)}Oxj~}.s~_&,JZ*r|&m%]ܷ!nPKdQw=1Ӿ9"K^QkpӅ˝mO஖۱Z^ w~ ɨ?R͙_WrƟx++Ή/z(}T\#mS"I)/b;;[>>fh }Y д3ŵ|;pK6)HxC}wn5^f$z{?U`Ѿj2xfl]"F 7.;ީ\ |ba9TaG6|t@Aɀ*GIMV Z'0ip4Nb'L%`^Q߽y!{4& -qcc=v,躁rZ'X%ANgëhV;FNMolPFsygbvi]oO(w"FT|tN *Z͂@pܭ0mFw{z%hR:-;R_:,8^P\h( $jH0dBqYUn~\}NAiYoXU];ӯ 3fiըwI^ 3uZcIoޫo9zhUvhH ?bKprS&oFHR~ n VLO wOq Jg* (2PձCt(=ȟ2?aksIT߯<6\4/Iz )&_[xBኍ*PY'ƙX`>=;J<**;U9V&? ;[_e83t1Skj9816jL]U!WY;e{qdβ%H|{ F{}pXL-?^&b{T޺1hhnؠ4jbjR/_]Ї (vхxb[lJ_W[Xgb{(.`\7Fb5+`U qTSo6),6w+d٠ (V>׍:IWᡄ!ϕB_\&H/p}{ }ye[ z>a>oBt߿c?>z~(-e!'4q8>`Hc+LUPdJ#Y=r  & 7p R#^3@E1>tփLݺ(Q gIE_jV,C[*oX^YjY{f"bKs^VM'Y2;.QSGKjU`˜JPz[c ЩWj5~|#2̧deu_tCf&F;-Qec!0P#G-'q{Ia7H;:u4cb} N<5=M(J+X-ID֥e.uoȠbiaE)Gu@GJzevf4SvL4'ިzsUpƏ:P7)i(*tr^hXyѩC\2y=yWׯTnáR|;}1)oROсQ'0|ae$~~,;9ؠzXmסvbqo8 _, k&;kCd{d5ԁ$R@=À®oD V0ROY:{aGmY{-pgعV _Ke^nKj ۉS,zE+rYklEg5 r/=4;MF9Dg O,J'YЁU:>cU}𲢷c0\V1z@YDƠ!VfDBsN[YkHCWf.kρnd Sq 7|&b6`ԉB) T=o9'(OA}/jٓ&f4lz.^XAAppySQt?s7T9N/*_SH/4Whkj?$&RXHs1I93[ ~C,He%,ɟ}OVQk3X}]"F1KB[s5'T!"HiX]_wйFn2$=Vm/j{\ rwx RPHW_tS֕4)KLP}SQQc0:ɾ"Vc}muX9< },咃"mXtPΠ*j'$>Gt'F]c!<0) fP-ۣSS}%T"ȣ'GE&hy^wtΎ~33|ҏ/6ied\XENXN>33 vo7p(wGד1?ݑJW.I%V\ wZ=o)|gg;LR%@&XkRsV 8a,B'CÈ)>h<+..1SR\2gҙG8;;B~C r a3(Aŧ^]CGxH|ݼy0ǽ Ȏ{ ךɚPЩ 7}C˄K#P?4x9m]b,R2mnV!?=OEs I;}as.Hscڬ5z\v G7r _^װa;nWbE).mnM.ZS}"_d*{޴ڳD slRoj,~ q01v޻#M8J-n0.bf<$Q)䖔(wz>l1U&%$kE]S1"wbr劄iupOZ`0I4or+CK6r"JL{ Te0%K(ͽmK4zbeXz*urrԉ=&, -?Xn%mua"-̀əpzE(11^>#.uPn.NCh{WeR!ws3n&$Jol9OZ:PI;jS(Ǘe~Zw8lޱZ^C4}:lan]-P_?*DYvf`~[}NjN*oam\6ﱰS4~\n` *<WM5ؑ_C6Ei 9V;PF2|W}hc7 Zle'Q=Ҷ;òEhR60A\K6 [#'Lӝh6ZT}`sZbNb+z0gv^Iփә?wM&Y!i5~GY ^Hxu3\g@+"lPoWkȴf[sܶz=ֵ=;KǥZw۴y.@C甽$n 9u22956gOM/J>4P[YmzkYlzH "QBű$''a}rGaEmƦ@a"]Nl+U*8W ./V$P5d^X=+AX@iKT^EJ爞˛t8Uu)@*FEJ*+~?X`DFx?:I'K93jdCLIKԕ[@a4q]6BX}k'~s I`Mr)/2Sj-o,csy:>ؓv+Sm8:C!q; ^+- i8_ Q_^2/!"ۄ`+(!LgtjPIә50q?b$P{{qɃ֫#[y%!+2*z:g *z=?XF>vHIt9}pӍOABA3[1z U6]5LQ]>H>\F;|,~9M1]N'd }Z5 KW+Y4dQo$ϚWSڍ4G z/k\%bdM@$:oVl!&8jx:AmnݧRqK8y^AH%e 1 "-ۻ%z7/0{xhs`g86:rm*Ԝ zW{9Y^{=]RV}]kCO)~lh^D!HC m ayX-ZNs\lYބ%s yՕ]ok]md7H':u3T86f0 HZRFɂwwmL޳%!JR{״Zh|X܏ݙGJCSzCuB{G[!Pdؠ# R"&DF^m6A{.nW9>גUwu;/Q8 PNGKDs%8'waf©EVh (0۩:=>R)IE[ߡ;4kd rڼ?2Xd_QsO ?Ɵkj:eGC6TWuԍBnmpD{;UM"[(XN]P(C:"ino:_3l-D'8\{BRB }R+ dGa)G iTL=X;j7~MRDsYr h5J5I:UJ d{!.+OJۜT/{Qj?^Y.qE9j{jCO!Ӆ榇>LchI^#&iV7wq7 y /}E -1Pyu QNgW++5~S=̘NlZaӤ[eFlܻ~g;pT +oY>YĆ0324.Pv2=+ĩZ^_|Q?ˆH^7VrkŹd/D@aʼnԚDTA)4j]\9S9jR'HHm(޾J0s>9 .;ҶNV$_7hX@q,`lð~_ HJI՟ 69*aG0fx.s`t!8 {1Nr?j{۱wGc* ׷`ZXVnz)t Ͷm'B {. {17=>H{jb[r}qC #HOdL>a#&3QCx'WY0L*`itňVKt/ 8ᴿ__oY۹ A-jTȭއؠ GU.CXM[[)Q Jn}ytobxwx;A$tDl8gNMg{Άp觠ZTs!?=0cԚZB *_y5iR@Sa'b:׳P5WFBEӋtښ%.ynR_[W1j26ٞIQudThƛ w  ψ6P O}kZK!Ï.YUkLE͸M>L4C,n꼜9bkM!{B%Jjſ tV1 rNCt+`9 щ9͚#X"T 4Z.3NYز1Y2t7q׌xDqzOşocx+#嚓G]eܴ򽌎uޅ^.;/ǿۅ;RU[W $RG9TuÝQ13|l׫۩Qx"}ǮyRFM%线u@ǝ!p(':f{ZJ:&u^5Q](^H -&;qs^Mh'գ6oVómT2Hs]q `չ!#׋J_fn([GUgFw;/΂OGRi.&Rwd Y<JecOzuO?#W,CMsTt:AL<Ѣ偻֎&Fmx!;= wF֝́@72W<K=Յv8O"rJ>2Rxx*Y\vW7."IHAmF_:Ɲ݁E*L1:)+^ȋ[t4!f.D7& m\ #Oܡf%E(?"7.I!TSh ܋P"`ُg҄3LMeaX- }"e&,mfNNOFQ3&0͂4Rh`]y=On_ %(.6<=}% fLaǰv_m66;s s\ CIڤcTM(e $zn$R!;M%}waGq{D̽HjdTdƔ<)Tem_eJ=Z$GBJZsJdO6,{#]iOeGv⺣5-HWf;0i{j.߬>w?=!˲ ێíHOyĻ]ػ"d~QQF=y&骇CKyV-T5ޙ"I~:Y8O ^V$#^>%EO+H+{3 wȭjD,^hHԅbrTJ '~B)¹YCh!mfTڇ`+MEZJMI}#2c h'aQST~"_Խz+rgyZ y3z0. eѨq0<(2xyMpYqW t1D_(s_U/'~<I>ZoL)(Y*524 dÍW旄@U]|Сah7OMBD&L9Sfk҆s̲"}Q98siS9 : &4i.h^W/ܕ$_5!J[czivNϔH*e{`.bϺĿDMf˜tYc+FQc'd?}.ߎ[_9ҹ]ul+D+/lquOw1y'늕㒌Kh=tlL5KIa_BX"BPS OO܇-ݓYE$vGBƎQ#+RI!pQ# )^^MoIm l#5kfM׮f]5n :n P)(Vm Gc/TVL#˭}}V#bSqo V=-|=+w_!z `뫧11Ḧ́f}x%z_c h'e#f ټX}1.axl*X4B5ב07dUCax&Qo-[)obqQ[pOWbxT$.u5GR-m7\(B̠ LjHxR+۸b2%9vة=nf:vu?@bk%j/4 c&&B5VۡKT~'9K;O͡uj;4gD#vs5I|}\JSڼ}vὥގ=55 _Ye{. nc}fl QVP:ޱbĒE,/7Z1ǃh ߿hw1/丶J]mxl"8cǵZ(]+8@c{` f/~|uz|~՘ضWVm?ߪ 0ڭ7zYd;pc-.787H"7g ͊*-vy.uVY&E(y~CjVG@'c*Mʈ~O2dlK}K^U?ѳyPaLqK`6V‚oE,*< Y51' 1xm.&3ԇѭWR^ DWDT5"g)fyxoNu"ŷl|ru;88y4. "t9X"";˷0=6:8 uN1 ^yRn򟈵I0S'rB[ӌh^9Gi1$ )󪥋s\(x7^76 $_Gʽ>c~VA {uTLꅇex Mjllo~R+_3T>KwnB%_äOP 2a&Wb|)j*Z*B+j{p #hZ-Q[+3<F,q˯A %`NHzX>U2tUM<|nVm(6e@UN$՛1 0<.䆦 !"8 U!W$ܖOL9<-Pb(V\Fi&3oLq0/D 6oGƝ;JG0#㹄TjG.fCH[K'y\edr#:-c<؀~^&Mc}RַIuXBd(8P $]c*3$kdzl:Clщ3Y57Bepp8#o7t$ ]n0aD2mtlkpgH^WIS!q:zԾ<ݢbtr_/TtY4>ҐG替ޛaQKAAL ӹrNmup=`){E<{ǡ_G32 PLnr6\IA '0 VP&&7U#""-TG\;Jּe4ΏdVT(`pxƝA\;2sDz>&'- zDź|S`k=ƥeT0jL#TM`HMyc 2!U`!F"B 4x|_8L"GS/IΔ ËP17~殶h !g#Fgw7ann5h ݌ F ñkanDN?@70$qa* E~#t<ޡMHIvMxIskAW锗<۞WqnxBv\nf(W(doi:2V6v6[S2`p5lt άhF6X=Q6=Ś#["n^!tM>E:08M%nm!>!O.⏭#vqrSUwobf60GnF@lmp׎LJj bů+=GjǷ& 0Rx>gD D,?^q:CQEe4#;^!bWx˧L\9 yiiz ~.ppebACs:ED'_媚b-İ(cN±OGcle!s(;_P:`E>l1o_e.[6PCۡ6}P$×^5yІFWEPE tF7e_k;gy߃g"_C,/_!oc\!=m9[ MRu-G9/8BY,ǒ{7[#)9 {$:E>yUT25 +h u/Mn/cz(Ht{2\mɻNUfϠP )g:LȄvp;Zz d؀}-,u.cBp+ce*`G!:V5L7} # pueȐb>aJd 1` Ɓ%{P.@حnou Qf8ۂypsx;9)}E׽ htuG,вK㻂q(QIdဃ6UwVn>_O_x%@ˆyH58iX7USuv'q6۫tk`"%z12ԗzGʪWHV doE|~8m&h"H 7u~pəjp`<ݧ(X1bD̘9yA76xWeL`llHaK+f8]-EHou3h*y=uSLWWŰ/Tcl| cj3Zt?F zwQ"ED.=K#0 12Hq&p-^8I9$ z3">#T S(jX & FnV G xm1=1dzx폣NBg= : yu}7zqV8X^ )()_"rkݿY%zsH*Dw?Rc3-Pܠ>>."Aԯf${:*PRfV8`2%%;C3~h|>)Yޝ2tkAv{u2ʶ+wz4>komrje#\@;|*8zM &d^4F%EܓR6ղG "ǟ,yzE d-֮OD~>\xdjT@1q%#+ܱAS,q6Ee gP(xlNFCH>N,IoX9P&٦MGhݓvM欲˫۝ <O;2G=z l|Ulp"%ŇTz:={$Qb'}ʎy_M)r pbLdX$Y"@u)ß9${,yG7Lͺ߂k[n\юP=O*9\t&Гy\be-}OA)9ZRBEyND>MBug֮S &іEeS. hHwr}MR0Ǔp3 z\˚ZEAIX:UXmvz 71 2AN߯90 :rb|,6SAQ/Ⱦ-H[M9hlퟀ 6^aj PrM4 $M4\f Fç"pҘct(?mQt.o59sNUUdh50 6?s|1>Haԕ{D>'Jshn:+ʔ{{L![\NdEn\iR\W G_)XB^N=mB-~$s@f)c9Hm\>:BU ֋}x+\z[;AđnJ&j d M]o`Y΂}^Мlv\3" чfTk~k97gRFb}|Gi7ͣXMP{$F-ÐlP1q-Lx(‹"F*V`kPBtѹ@+!*aW1/PaÙr}T2O`pFXL_Z_FnlG/jKx`mA) f$?.l }J'5{LS=\2 ߘH~@ B;dX8#difl-ѣ3%$Eb0&;U|Dv U] ڀ@~Vr1[xDn^96\#OipVAqpMƝ`'[p4www}3K0ssE\P[z0_}elG;mdHK 0c_tCPb, ʓ7ZcŪy)q¹IP}ޠiͦƸ cDnuLO;7BDsdz)?:)^وs}."6PkV+UDw:0dELY4Y>Do dEdybi^ ջ:`02 ` \+\Q"MX=V# n`mqP]DQ|U"biLp\=$^4amNwYgCntpYC@!Di ׬Fh}*>77wJap.,Wߟ<Ly:*y?Ђ[7II )ASE!7g|Fzp 9h$n ]>`wt KгN jWGPı1 2p^A'@hɁxGDnS>{JO)rț*8M܉R$ rHRx]`I,teZ )M^k:jcAӟw0'5UvL Lg-}|qtʌ s*qudW@_H]tϣ\G,~:o}2tX^pq?y a&. ~ݩ.Gb/_zc{@zacۼ-XO|=#0)cSr O]Aj6 $0R4"<,]Q20̜"[/Xt2nwnQ/"BSġݿE迲񧲏~LiPbxj 희 ed\Le&Md䧰T2Xlm4Ed)T˹Zi@! ]ëEilMEA#+1[đ~ӘIw]t t@C8ϑ:f9I?zJn Z@~)kOMALh*?g!X:; qbgSԣ+>Ep ,b6O]/t*f@k&Z>wݙo J("}w<%OeWZ =t{,rR*cvo_oAF_,$(|f}qqO t4&lѮā[u5: <)t-ڌDR؊6X1 *fbY<<]O2qxiz6LDV@]ma#y@ZD8 W mW/ ўhEY^nYE ~n?۱;3z磴3?+uN.i: Z{ bFz%0geV7\<˙!rDn3}x9{)_XgOx ~1T1rSR"*e%̝g, @Plw }!B OB .Oe1zSt;~XTRH,ri3o}2s`ߖL;ӀFIHqFTy5]!Le4]cM6fKm8A>POR_ 霢GEzS,0sGʴc+d.HaD?|sF]kZ _YlKF dwqoߺbv~`Hiiށ*CɰnSyM{5|)[bDy-Χdd^{; O)iIͷYcщIݦ-dJK "]'YP3iNa);\q`g s-Rp9CYZny'ç3~A$'̟{K[J}93w -{2~qE}0 bmq<>XF\8Xj7!I:h{P#K4sNA#1/oǂ{X d2)-5H߹;B˕6e6őN,80ʇF3(SY1UMlKPZ?"ZoAa"< mօ焥ij$a͒ȍ+ @?P#:}SN]չU$4MFT'ǁ%3;h?WN,i+Oxb~w{?"ͬ~R$L EN9roUUHd|WP/0i:#dgǑĦHPLz,܉!j-,r"^H"4Vq%& 5b'd `ёәC )VCP᮪=SRp73HsbV㰌u0 \05;We>5DV@B/7LXQEl 4p4ho ~*|:{ W*BGS?Œ=; 2(ؿ_ b?JfqLCHǃp{H҃l+  Ѝ(DefOߔA }|Fߵ 93|ҟ|?[2TX}  \Bۯ|ہtӨzh$YE_lF2'_Ȑ5o C Wt\J GGE y }ź$)Y"^0x0Hn1|<$oڗJTid $!5r4-oz:!WӤ>_ix,=BBnmv6h,Ԯ|z1řz O-_Qf?37ޛFKȦ-+Z>Ií}`:K-j&k,86d+nGd%6y^"$_lߥb\݋O56IEPf`%DQ'YpmY餎 {RnN_Z (TɬPڭ˻Usz._+; r3&=4 #Kؾ2<^DlS¡ )V:ȑGw|?Ȏ |Yզe7V~Hߋ:Pl'Ny-톍SW/Q)צB.mKtvqln z!SGzܰE:1L|!KTZg]7[ V&CR\|cYp= "3;F p?Z,4I`sDb;2Wbb2&0D<:nGh~U].m.|Վ/wO'PEx+063*;"pnMI !!";yW-:5GIq>АhSӨ]< "Ox2CA˷#*gt U m6*İp? /Y"w8ןYskTh,QoI1/q NDWO[XZ-Fd޾p,4(vJqdX?.\N*˨ wU$b um OmZΠUܳMN1@Pz)MIK¼b?/CzH-c(%'|G9>@JMxļ`lYsU&P$@.Q"B)'^CV4FVZjlI1dnBK()iuF%*"<˜jMOة--9*?]>c19{u4mqϐr Yolnrn?6psXmk5`)yGeOUmwրD2%8ЀkXҜZmjRMg}G?׎Z-cٹmJJI '3c:I=^PWi})6B46؝ϵfyNՏΤ9J"+І5 edqqp֫x 7zJkO 'Re^JOabT_ e_(->yv(RT)cd1 Oռ|߹mC~Đ^93k)L& wU`ne@Лdq|v7- X˲!UI-=ΎsKPFIEnwϧp47#/U:nҡOg&־ c.Y?VEr $R=eR0X훓 i"X-c b9 4]mH ġ`7 avD+~cW dWaMf9ctFWG@՘p 4hkX=WJ8nGuֳ@|r+ʻw@~DRiI P(R:1{!v\5:.o?$JCBw]+) 1QHlNz"a-xH]mynndQF40Hdo^z T 3D:ʵM8-S nD,7y|)8a1^np'K󃑈f%0E^(%=%7ՈlUYZ{V~mK4msV;.p?5EnkP~Sܝ0 jػ\c ۪9VcUx:g?!ӸTp"4(W :jhaDV9IpbL\ J'=貛\]Q#GD9fn'X1r9(I(*󶵲S=eHM0:-y6Lz4^X8Y۲E#Cw)y|g@*s.mtMVj㭗&X `䌽i{ =4H Ji2#)9;rҙ,EHr۳g: rԅ"`qC8Btͬf$a6\A cTtEJ=1 7ġW$}2k I6_6O1LK]K}'Wrc{ܹq:_v5D5K(jנ\ >J,`FoJ/s3eeD?A:vO3{21~=\>g$ `lɇ6ܬh$kt +t=5d/KӨLIO0D8J3cevC:=N}|%x7B}vtx3]bI͉=[hN%#Ϋ W`s+2P6q ezT%cvZI&qVpY cE#vwR4w(NWC QdMW_]quYJEq41P„N/\ sl;3^=nkE?3>@pߋ݃ 5<%J]3˙Pv8a~ Ac˪y@*]?a!V獊/'TT6Fjp$/-4,ӢS()׽"x8Lʋ>^ /09Fmԁ/XXG* V4O ly &w49.<ت< f J]8E' '_8KaHH qniPr  -Zݱh)(BrfmsxaC8: Q,MY~jؕC5|Svu嬺m.8H zV_b&Q7)ɻH;y0rL Ҟ_#GefXv8II,4>eA94i2ZIiD )z#'˙ ?~a ϮxۂGetN6 B@ҶNtڕ=%btj:* M%5}0<=/zEbQ~^&30\C]K#<ҭ4 `17`˴eBuDxbUJ%^nwM3FeY_Lb[ό8 K$V5ubPcaH ]<ݯ#Ee=8L]?S*4`*\2;=_fϜ HTO"a*X! _슿x*iq3E9NSHE.jff˛jWesVC⚞>~} mq QUP&@V΂vZ ӰaƑع'/~\wQfc"5F2p+m$mjy6#-Wxxjc5b~udm<87٣r M|5tb{kɪLSoDBI x ]Iw;N{42o7E[7ufGbȑfJ+z?Sl:2(<|iKL ;*W=rT(R'N):ir# ZVb!QJ0,ttZP>o g^yyoEh.w"HChrz-^[C*% TIbFhm}-LԼ1c%4T ~muE8 mUA?*+X 4 NzS*hKe]nѻ7MdNc!2}vON?p'tc~H^ @WG?K$Q`f?kz]_2j.A!Fʒ݅x>-*Q1} ~zߪOH+5@|[ 5/{xn[3+c^яx.Vn ndSgWƌ"QM$qz_?¢O?-f1uk ^4Iբ"6o(©Z y`Sc 4%!ԤZoitՎXP{)"}}-G}RVEDMBE*s!0m;h6謦S t?(,;Uil20iv p;lѸ>h<0x*o_$'^>&[tGm7WjĖ~IEN 1߉~z㝯 wXAd`c 0ՈI[b b6>6 $ 4ȅ}@н-pKZD\ۯv5PP5s 4rBSDw XlU]7e_d..6z5_9鵧ZfaO5EpZ6PQc۷ IKF]O}.`?KpZ?%z 9kEe/F9fȓ%]4畓`҄B.E VH2S~5v%ݚ2&csNɹ1{rs@Yr>u8{a4}ƳR ??%FjTK"nOg:'(O1".,pTXlo83!X hzC :@ ZwACȾA} Q ._t.ҪM1|x@7> I!pqpZ8gZ{#bdVK9н_9?WX8Ğ0U Vs{.Jtũn"V&Q0T='lgi*lCLy΀Sgt`X5M}h%>:n4hi"Oa3j<ɩ?h-H5"2J&7'B/dP~xMQ4 aH.ͮ-W%?[Zmxq|^S1@kBѪ- HѼWp1^ɗCėS`*E@ʯ7\Ǭ$wgUuEE΅|<%dV/!d']ءܐ2{b_ܡ!Q6zGwZQ5fǛ{ G2,ZueihvkdU+Ժ 'ƿ;@IIB?4" c3Yz@\kHcc\75UoCJu%Av|ul{ ʜu`ƳSQ:կ/for<`1CО%WNXm}SFEFIx3A~;% Pƪ"mJ?[m?)nWƉ2CXHe3_7熼" u"0ڱ@@"BC16aIJYF4M(;.e߿C@h:*Y[j8_^go/ď37Az`qx4ty|e1KNv=mhr1$^(үS}h׈PY?$}I傚IZ0_ ,Q1/fgfWMڳU^轧0c>AWϱ{w2ϷZB!"G [soQ:xS7\A]8.̼J xjylN~L,/|11Pܺ`7I Œܹe]}H i˥ju;+C:Z֭ 9f.D@)~[:9h}`z8OΟF2pe CE$춍eo QEm3 "M&CZP+ۈd%{xPlb+7W}/A"[;EiiDpЇ4744%3/3LN/W4퉭0W<͡ʍ 1.{+[XG&.ZIt{zd$ 4'U-u?|aGWF@B:6YVK];Q@a4*d#ht옸A*mvtV U a&wCeq?.mS_._ Ժ,Q`U $mO-uoz0 tyO,\sM-69|%-3 P*/BͷjĔgwɘ*7e+*X!=ndk 08Iqu>ab^R9WVkIB['!*&R9޹=Q~Zi'^ԵoeqR_N*c͝w4xCT(ɻ!_ۺqJh&J]KCKs,oUJg nGEMs "yNyLR"Eɭ DA2ݠ@lD![:QG kcg,rdR-I @-PwԃSZV( }-d834$ϢӜ,.w.݊MK{5 Tg)jp&^á ƏZ(Q:iM`@:) ] eX(MrbyZl dfxlEu*Zhj^&]bV;WNEUK+**ІvH nydF.F۸G"Fy1FTN`A*e/Fh'g8/ e_+'R8 n,!ޏ@=d]+}MGU%?6NwKrWRFּ̈ 6Kc).d}=lAeO [ Dۚ6x>[Bа# oO=jǺE Y{.6 }P,/á(((`0YF:@a)7jvOEaCg005C旳4.x%<5esgv?x _N|I0EnR~ U-@-Pgf44aY=JV5]tWI\hf&W!(U} [6=06y)t~LŚ^.ljOŀ}+882q gEKn1:=ndLeoX5h4ܥ%-*`=LU W q_kJ4V'o:4?GmN\ X0#/)| TzH,-~kZ^5 W`lƬw*I!e,um`z䮌U%‚#>xчZ BJ"`e m$2TZ_ڛKpeX⳽<ʱB@*vu|5l0 @)q}&?+9+S uPX{cTv-P,;'kJz-I $U5Jhєw)?O]4(dsp`RzlMO[Q=nfe!߬/FLEDE͍*>eq|b@ miyq{_#lh 3S,? /ɩqИ$Y4bU^SiZ__YP$lݟ,Hm 2};y7=ON4 ?gM]!VQU9OZk_1D#L~Gl2S$̽rۗ<1er+-W ">݅B@y:?&qB2pJڰ7SD9aqcR5xi_6ۖʍ^ؿ>%pޥLJyY 3tls9⽭Ki ~Fd%J. g"|A=$m ntUz-5 AhQ$LOe2: tbnBba!rDkU.k)qk2NmIY /UM\JJ<1s"ƯX_qӦJ{_3.yU&UiX~krlir24JoS? tUl5>}"]גYV\T]nrT{%V5ţp2$~i MMnT [9b?p['[0Fq>]7~8^:i e|k!EZet9Y5F;V"xn`GQ7'gID|Tif֤"O[n)Fo,OobmhJ]!9ŀ:c@oE{(%pXOwV.rOV[} CVג_hvMSs|dh?5Hݪ9;]Ђa\٠T'k.lŢ|mח\>#!@Kr}?saN(/7)=)oeV=z ]~qN"f6,]i<':\kaľ%J}#qb ڦk89kO͢Zahy銫=ߠ,*-δu.9K[nĚtA}iNWd,up_@aq+2fb}'EW|gtάC?,]JmE(`]B fl:gtrWf+k|}m @(?MLB;l;稄^7vy'SFմC_hJDcNSH&ZZ[8n{>O(f&n(6Yf1nӐu#Q` QjbNHHA9.kwJ685 uMݟkrK) bPlp0dN8;/܂]JL-v=,nTYK/BAuObɤw9 .1 ~]P`pn{y+Q‚VS܊1Ik멺AK 1 +_ɆG9G={bol;۶m۶mlmkƶm;֯j濩w~>}K+)CR !~=t {zՀ WՃ}9F420vWubyBȸ&C׀>4;DF@8(==BuNfS_>f DW hxS jrK˸'_Jf"U nsZl$|„#":sN#Augub bz0(-At;HK+f&-c QH .DD ߿ F\#8 4jS_Gz_d2EUD&mtSy:p=׃7j_ְX\ad캙>U^~ir*v]3\Tr}CdgV2i|n^IBCBgȡJX W7Րt{ ʟGP*[X(1ۆ@&I)ծG,G3W[2rjE] \klv?|coOСF63 s@(`GO5/+Y|M#Wui.FSi2+  };QX̴zg{d,{ _?~4q̈́ZZKq@i `Xp\.l[@Va5FStN.4{޶|r߅bGY^ ]KMGB* V#wRІ: UjidW=ƙVPTH^]qL7`Y N| ܸvm6HfKJ*/+^'~em%XGۈGQJ)yP"*9JTvvX3ΰQ|֕ao=|/X| \:ZUpB^jb^:5BRƧ^v)J8vO֜*Wӫ)O@J EپR8DdNZȃ38m2Ts23&&a7)/TT"=Yl>0c^̶ǣiBiC b:A6DY]],T7\+kҭ="a^Cp.(jpdk"1ϔNFAx^% k_:۽^w$ -ScM_S =:4:A*x[k)u Zd˟ *Og 5}%U4y. {BT@`I*q *kjász%2# d݁MyNX!M%:*~LIe+#cFŐAEJ{,aaxupP$UՊnS=b%E=KCϝu6+÷E䚦Ub$Цqv-F3ӛ' $(sqޭMl_eFJ6Y<mza  $ux jv;]bdzv.f֣"!gӟMM=Zùc3@<{^EسqJmUJNv]su<u/ ҫ0QpuM+`5ppxHP7Id"w"97P,K)u_z񿻈@{v+4E9xz!ACeSAd515&?,M=e%@l)0iZe# 㜍@q/0r끯˭H<ʋE)hݔLuSKO]H mb|a'jUrf(d$ Dhp쁽=ts[r[Kcg~x֦ 'FFVCq!jGdzsbsAܢZsk֑?8gmc=:wJ } Auޛ 9wt<X_,po5 E6vo9+ O)N`ﴱǸ}_ɘaU' h 24u>X]cJ&V0Cc^Eҧq}=sڠP暟#X)9j6^\]'ӟc=nj#_D$$k"PU,&4Bƴ07㚽Mϛd$HtBIEB6"Q`)J 94t{c勪L Aֶ /lvbz&`Ez|30Op}),vVP|ڸytn57֞W ?bJ2510 M8C3+iٺKBv[#V,AyHGJM$!i+@{&M6T@P%eu1Hums$4i&#XJ-S8s>3]*1QCG,.|ߖ6| {"fJp4Zpe3'r.yR*dքꧽi#I!VsewCjoV#&FԚUv}XtTdzj-ڙty_iyaw;!٪^jvO˯ z>┬V >Ԏ^*ʨ÷Ƣo & $ @0x>9p_ﲇ/HJF<)[ JV'F3 < >Nc\ Ã;LSaT0S:9Ȧso&ˏ^#ǒm?RKx'IUMY~p̤js^,:Ӥczc!f•1"ɂԚ`'PYNRWT:}RaHHf16ace|7k66I~=:qF,9 -#xGY ^PSi|Fw@GaOy~XNmyOPQWr nny}UQli5F8 qhJ3-lXE,A)zQtŮRT~[Gn Li7<79cijzu36/uC pd~AuPA7 mݨ. hre@(,-4<2Qq&!Z/-+_^)v|m: 2ՓM k#:PimZ> Fۂ޸ʇ"q55TCyF ?2Yt"Ip@ vY3I> ܝcEJF 2Om+.[Ss8L{;:|>.@G/16a, %+Zä$`Y ~<$ ҧW{*ھȡ#Ǡt/vM{A:./ ^ ?W\/b)h?b*OuH 4˨/ekJ =>AE3(+$.Y $fc.?BCbA͉)xt)AE5&vUowZ,@eaeX˂/ԿI/YtY4VC7`T{2VXZQ+ˢ˂O sBWvP6qMfUl[*^ʉTZ+yc+M*?\1=m`-s :ڹk}K)6q'îb|Z hXC{`-`[sri}sTc3 H:%(0iEN'= d`^:Sn>9PO8zr᥎I<_ݍ|:jTLe2ӄh0J3fĥ<etIF' O?kx[^N䃶* J~=;8Bop '-#Lwtw\D{Ix5r6Pe!NA RA _.n)Pc/i2R"<}\M}BXx;H-p"r62 kmjD)d&S:ghGqDDPP>!]5gzu_f59AZO i&ړֶ.Y͓㵈6wxLѰ[# (㟙z%8o, \+/0WtHn(VeVr:Nؙa^xF:љ33T6{>߱؟ b,cK3D ~b4 +*Jjk>J 4E+ŕ#8ޱnhϬN~9Wl$`/L5o!$ mn7]Y'=QYAf$ Ń#>^+bj=ϐ9f uOU/GⒷj&m㝣P ߮( ٟȤsV;l.ڦs sr)iAZy<jYv/Yػ3[^2wa/G wK淔cpIׯ;\ÃEOzgsl daM 6)EX1튽8Co_Ixg |Ѕs*^&"~'":U~*,>]a+6;eUޫV[rC2Vs>˿nak %%!$Š66h_HLst˙u510 ?Y5^,Vd)[\Dz-K{vn99jnVvY]rO& ՃSז6L!(1}Gj8kk{FAάqMT1no)7KK%W[:yl/.@h"W eM,D98qϳ$߃}BG*:Ü*g>?q6}LiF dʟcoH9_YěS'5S[A Į~Roɰ')X]m5XiY*7<2hYs*;(η)wV=Q|olyE;oqu785Zo~oQUd69>W颐QdVK[_i.w6N\8 JUBtŔ(e_gL״KUx\e?|vw3\~B!4 '4s8oKQO\tNu"gٮW[-w|p;aco*d%I,ǩ#c+-j]>kXk]T\tXi^5hf_cBEKq9|{ 53 zQ)1^UH!,f3P~x`jSqzRr S|rdV x7cV͝)"4xF2q 6d24|56U ޞ:}a?l8tzq)spwrȫL5|~}x筳/lߛLn6Zc\i?C4ߌ;V1 /UQ"k7+aNSԧj;(QNM[&U ><] YP-P%N*ͬXҧoӢ? ALH+x=6Kobx,> ZRzlo'"-Ȫ/|tUFy~Jot -J(a֋Q$DpWs=Q¾[Ǥ/V;! [tѱ &Z{ V'>N ,L7 rjdl'1|v?3UaR_^TQ0 l_=;b֤ЪP1b(LOSTQ+Y<ø l^A8mCs1` ߢ/vx?gXxC VD-.jjtL9L+!Qp&w5QHv ć# c##lӖ[! wa#fHDL4:@^ ?i;_bCfBvA]ʋKwVD(K2v7oU['ٿP]J%a>H NǵQ:es@̱\)"i+_gtAv k6kŪ.Qܬs~ٹfC@q èLu#̍)',,o#řwmVd]>|g4̣߭q,[zi0` #iӂ:eloЛ^v| 8WA!{Xa#⇢p[q c{STFZ|Fx(To~Tg.*ł6&517!TT*()"aP/j_Qx㿥|e!zt|mA2=q7Hbt̘!2- O$YcjNGlEXIĵ됣4jg%,⫗\֧;DsxQzǡ]{QdY !Y*w밖ɚ Iݷp3鏓DĖ`fk0r.&J*;5SnTc'!aou\~cKzE3fDςBe5Ҙ7p=mG+HV)_?lqˣׯyy(`5 8ݍu3BQݽH>ߨ~tZ>C2ᣟKb>rhםibFQH%kiEfkZ%_IUէ*DH4Oo/!n, e}Y8EJ0&Cstr Ϙ~"aS3Dr0.Ӹ|Y>V]*oGo᰸If.vgvF8?[b$lIZ cP]ZԨz9iws+H,9)P0pG-(Is/s{ |[ DNB&|l|]ОO"斛?:{V\zPtwFw~%cv*J| .mudxi>ppkVvȟ6/Ol[P^`|r{!KH)?Iz7\^vZrw&Fr  0EZŶ]H.6fXY|Q֘F*9XjJY"Ha:GBNHZ:jذ/r%RMWҜfƦvUjAGwVMWT?YQOmůZXQJd__ Sl_\W/{+a)\mm! u˷wCWq}m7V1|Oqb+aAǎ=+ke!l?7e{}͕0!1oX bк5̘dD V!(mP';&17Ak1PNC2qp#;O1dl k#)' Md5k֎a84OCd~ڞ|g8^۴Yg&s1npҶ+1Rv>qBTFP=MOׇ D7>m\uzaEhx^G//ۯ7j^K[7 ~B=a3Gm',̭B<_?܉ 59U&N1yȲI뷵K1,N\."mV;׌IJx߁RB@Sl/?=@McC0U/@kԙPYg~@NVTvF$.'l1vyp&XؚO-ij=lM(GPB6HT庲ꊫ$Iia_a"&YL%Q-zURXK3*BW5ʶcfzs4*vHڪ;PRgFӄvmzG*msCu@q pJ*0QWfe8ˌN0~)KzJgYf>Mlu/3$nw5 Fl,=%T2GΎtT0 evNܸ"vCZVmMI!׭09tqhs+]Ѓan@,Zۤ=@K z#XJQm%/,->.}WɇHs226E. U)-bƜwVALw-SL&O9{BE AK۟GcK!M>Z:N[M(YP)VLLur㎑ ^ =ҩfB]y߬'[-1Χum"cҠ`)#TOqalSCgܘ^p?͏)W}5cc$K=Ĝv eteDgT̨ücnstּBzN“ז6_3 )u/AF4#'ǵYsxy 6#`&N$:`'لfvxɊ6b~rE,LVXs5ҎmԝJ]$c3GoE_|عq,b6 Q}䭻oޫ[ELvGbO6&vN 0f}/|ǔ#g/%\ۻڥ:dTR[a^ߵnq `W^kuCL4#Z3:T#&jY)nRJ܉3,DG\;= M# v Ԭl a9TF| .J'!'Ne|:(wυ5~-a7g_O# ]a?@B_6w5z=L9EVKIPགྷ#ߋToߖhkocǙv&_/Sv+~jJ|% _?Ew @..Q&f5e1=k (u۫H|G^t9{):asmaq=:n3WE\|  θ语DAyl@[=RSZKsxݒA _M]DqL;⣵9riDيkU_[uSSU.XʳV ׻4"w ;+L9٭%L&-i2QGoa"Se4ft`O1n.W˃K㌖pKF,bޠ/^'>JJ9E-%{Wdۄ 0RM 4NAx=.be&5 Ya={}`W=^xEɠ3|NQ5N6l-(JђFV)LI6:Z6+Ik\Å޷zǥ>X\fr*?i Y>O_΀n8CDU*]3h&iPJ0:G,^ |mtj=aBPMw`FxpAcymRO%ܥ%PfmPWQR6n D 2/,ٜO 2&0L:_ ZB. +:ˑ=Ggy +UTCݍ lP6L/I9-CCRɞgix:کu'X>Ē_ Or +ˊU2,DAKȕSp̐J-Ýen-:i;zQz!tfVON{OOɪ)(02PAu`|Lrq`AϴMb4|'$-DCI*'ݜͲyabG_H<bfX=b^߁=P lVIMk7f a|j;[C֕OsqP~;`,+o~'^םb I{e_wK32 LNs1zg:=*<9U.2.G|H:-y\x,y>&W:lU"KNvBW;@L{eCå6AuFIc)69 d1=MZIDD͌\U9*.*hR_ 4," ̷Pز ܻa[8f@|2,<,* YLyˮsbh,¸W4 V;}hW{҂ 4Ҍ Ǭyx 1lz) ZK_>>E?BAL%ӪCI;^H2jw$Xs<r{ts+d ?_~ĕ'H 3s.rSP|ͱj~xz{ahłҀaJCHF 9}&4ĝb{NDKZ"Ю\6~/oSGAR_33fP+G4il9z#ck0ql`bQ.A㪌(8OYC vdyҚoFbE&+vāu%()@ƍ[~?`Msba[ݬ/W#^~y>()+]EB2<=ЗZ\f2V:V eUH4rz%gۗ6cgXCCJr{ o#D 3:_ZRl~ \:i &C_Ehh4`u~ZzxLcT(HAeAA𴚪wqɕ)_3vӯXIo!T8>L&dH;17%F硓f2I~E>76n  #Ct {|d8&zd7xz?&*6EK6 ]/T<ĉc PnRC^AHv;O[[R?u1[zT"?s4DE_wv*D;|s1}VzFBoAuRB5 ]#W{|~nF{<;vFnS>|兺Ůt4ZܶQ][ľ3 0|@TW6h6ܻ}_hi ^[5|(fwJ͂r L^ה܃ |윉OrXQ ړЦ4saTe5X6HswHd pBsN;~I~.F/c-˩kqtuUL=NTt0!J94/X+Mǰ'#̃j q ,q=rjBIkp-X*Y[oE (*|m|Vù<ݼ1Y:@P̡+Vswx㲒5O5Rx|J:mriçL&c^!~|kDŜZDUxEwjgSo`H X (08IXKL:r$zfe:{n;w!hMDԻތPMR2q j'nY vK-EE*@ %/g \#"XNt edC~BH($&Z鱋"h(L+ې L1vo}aN'8?ڕ:' 8&ע ~&xu^/&Ȳ@fp/thi\f R=`0@PMw>g}Ak>*%4ռ6LWgJ@3knf̪3+3 N7Xf b| W9=cx+zbLCLW&*|A>`3"O#"Xt+=Xyy7<4O7Y=dFƯNǁ'q9{b㸫yEIJ[*T/NZ4`81O;gJrGG>>sRǴHX|k-bv͠(SݬПu E8݇VقjH УK5wk+ AuzW^H֔dMa']IY][3U]y ɡ^I"op3B&/Ss{M} 1I&z'Yhp;;GWu](R)K^ENp)w܋~a$Lrk~oSk 8IC#qN0w+QKgV:2wHJu]\eW-m?!S4=+f+tء U:]OFq.1\0\劀;,MLvH:L:npȿ5w 9YXF1xC8(`ҭm>J6/HɈ "pugM'0p)(hY멙oD༎w:.xbV9 F|eo9Ƞ/E0.٭ UDw 'ϑ=S<*E8IV~yLkV !<͓̓ zp~~ *TW |'SM2$l_= s pg8oNQ؝&d(G׉a--f ҈.^ve) 08/Ϸ͊xY]i 뚥UT{FhIͳybӽ N쏖%U>Z>6 F=ful``mW3֙U3iUT-ZOJ+H2+(S#CdzC$;XU {^0ۯy{ZXnEYvaeC⒭ K ]g\M?CPsd<;mv~+猗?.g+j7Ϧ"50~J :Ow_BoLq/|> &"޳3ڷ>Vk8GS[6αB\KwNV`H 8%7àJIU=2,+b"%;]]4̈0ɘ^7﨨8=A1wOd%YlM {w*r:8؇S0}ltyGP^ή3yz )Xg2vqwdiBVA¸q-\Ẅ́P\|% J~ɔg DP*m^cf߭*Ў v6}Fߨ|wm. A"6Q.;l?,v?qPCx4: dc(s'pScrPUT  YTD%&g[bI[j}K9W̴J7E2~|6?`1ĩ]ϊ xf*K1Nt.Y _eYBU`fD!udl?YU~M5*mt]yț $Y4%P(}i`;=2zSI/'2z◼40z&~JlBӬin:!AD; [Q8QykpscD~]U+ Qs$u3y E̽dˇkua0إ,Ut{NSa6=3aFeo[o_H9RٲC^;G}!mrb4Xz~H$ ,~&Y> (׈_ -? |Bnj-3D`fIhEA4n'1I܎H#Q}{lj/P>$gyPQԝ{fXoMқċyqu *Cqb9+tp֟[g$Usq Dӣ- \ug r<!h4,Nt~:_iY__{h_s|/6#'<~"KږU'XH]C Zi}HAz-Dy|i<:ڷx$V w+̏LO;Kf(MD$Y؇/6gc9O n$|VJ۸$ޗnvE5"$&( Xx~$`K1ayT v.j Szzœo2Hj hJ~~y( #58JD4 ;(AWN7ϘZRgJIȴkX`C8oCE;ԓyP:`@/k_urLͲLN[>Hv]]@ i!<ʪ?ުlirU%,Wp*ZҪbYn7G &o6:4]sηoU i YMeFzzY|] z슜ؠ̮}߇:t=23kB9,r Ɠ7GB=(?'7sD*l^ ŁmY B>ƂC֯m&Dg,!]Y"w; 6l~EN=[JtKCOWR}H39pN#y?$ ZVS5s?h“$oߝ?rs^3ZBV>lbu#,s5?覩6@f05b:3:7`Ƕ"͵n*yԎ/2}ݾ)\#;j4t`x?7]8U21P ۪y˕@U=~U GIqS)%}ڝ#8ag>A|rVF'QY&ZEOSAsEg96pAѭGBvIF q4GbP}N_DOrqxEdh̾h֫ 脧(Fe[)DӔ u^AXĐ"WA#'smzV =T#B@im? (g|ܿC9S h%s#3ov}/z!ߦaqw#8U'>ψv9j}c+%䳜_ˠI{'/"^f ru\̗+9}s3N(W\ %* 6tFg-D|̜-t8lJ9h-~^OzcTF.ƨe^Ck{:)J"zԦ6XglRl 4À Uzy7wkN <+oMa]Tʹ>zԽplM|>M8ȶ{ jSLAws?5r~/, cQ:%zIEQNN*j)_`/yU‹/H[yj=FpK7o4;pDDŎ˹ Z`=?%>Z,o+|ߨ[#tMmA `Uulbi ق_`=NM0d|UUUI,V7􆐄>D*rxLZ& *%NCB:H[βCaÓ ] B=AI:==8 J=hl-2TҐ;m6Z ؝eV syB/jG?V  1H5{SS vi}V-s90"54P tu\5zM_Mi#qWnV۽`vv(S ? -o`CRq́,m}'m|Ghp[]O+6OKF%6C"UyN!i~SO/jF emDQm%jp֡]xB z7tǓ%ص߮~@bh3o}:އ 餸.6j@'IԔϴ`Zwj!`CRfG%+Z4qzϓ !d0٘ÞDDFe|jSwzDͻ?I:o#b,kީ~07LG225"0*0!jFU{p_6y{Cߕy^WwiKe潾2iM1i?5}y?I;?ӲÄb,u A'dYDğA+N/h^Rb2N3D{OF]ّXfTI=m?Rp FUތ+*#-z`"[U0|X(9ҁ~ pT U_Wْ=c F}>|3B%WnG\ArCy*!U5 ,}qj.;! (~`fsf_IX/Ϊ9(7SO.",Ie" :@8׾Ufb9cGܰڼ";+frs-DYFx_j7kڔxN_{K6I>!5Ѕ'> |p"@KVykQ C^aih'ʩpRZn@:Td)R C0<4m'?>$"mŇV(i=Y_Q漒w~$"N#s)mZ:Qhޥ3J'6ΧKjA(G,&k2tTáJM1,#2iKmPn<>//Z-Q1jZ*S{,/MC9e,ᙙk+n֖ X/-,,XaJU`bcz@wzdi܃4Y8M.P5!PeHWD0H{*ǗͱVi&qFLG{T5<2~sxZǧGםb$[B߭'Vһ|+۽ \@}@HԊ,v )g75&b+ J`ݮYuiL'7IûֿnB4Ǣvl0qBbG5^XdЙ I+4o̸4=ND4Amш'%c)Mε +>Vx4ci@*{C+so]zX(t.:O)T]ͅbm0g( iQ_+E^׎$z0K$ii$ :NnE2 %,Y%G1oӘ~rrr&3ZD[%QP~ Wk)o9ozC%.Ȧ: $mNzZӃ,0֪R=4[C9a!:l履-c۵ MRex!n2G%#RMT[@ >/>{4 {i}og Hʇ7ۢ woI`+q\Bx:ȩ;O `Јݘvf4J4Fst+`Z|>c>'c^ڏyS_n$&D <x!v9,?w\rJXݙFc'p]C]h[&;*ڰڇ[2'KȐgz jSu>4st~*jE4e<nBt́(g)6lN ̓3n-"{)"ȌYOfJn5pɀ|jy=Z:h5˘PTڠLbby}G 򌮥߾I|j4lin)u>b(.v34*tYȍY? HkYZ\ mFwad\cM"}ЊBبy8=dnLCM;UroN9w|V_#v00MzC-\msh ^CrGJ彼R{g^E1Z=U$~yjG7щzjkj M}i2vYZ 2*> ?LRSq'&Q8]}" w9#Lˬq9@0nȔ:η^5x]9FX\\Z L_LFiIhY:dO9 s%ǯE N3|S8t}oWCUHn'aal?g a3  1Ä>]b2dEpKwi B6K/ Vroqj)? }( ҐEO_dS5bQ/~_dx1O:F>۪~w]ՉRgrTbM QMҳ0˺^<uLk"sDžZJG |B}Ĭy:잉a9mO7rz2+1voȝ49|w;uY6;s %@ vv%*:X "VN -$I!oE$Ja` ;Jo*f@ZVV/Ŋ\g3_^[;|$~^m]V8"H"k;P3~UGy5ȡ$F*rPmΗ_M=Cek6h?nttyu/~td'H($9yAl./a҅{ޚn 2ҩuZKqEĊ-6 |C,yȿhhֱNo+\?NrHNh8Lo6:hۻՠ #O*|CG _WpT6,DMwG*\)hS͹35}^=簌$?HT 繠ߢ s4(UHGv5' <>` JYmiL}h<^ ?S k+!&|"SڑH'XQ4 5ex8!C*Zw!S*]qEʬ#.jh8ʊ)+}ٚ@nœ=uZ$Ig=ngżp9s 1'msK?Syrt[: $[[PKE%miiho@En&@D9DĚD"qHÒO[vy-[@ @ XЋؕ2Ԏ 3ɢgpSʴQ}6ɐNëm(v`09+x_ ._wwuVqR߷< [lS>[J; 6..ofq4D;!o&+a-4%L6~lZRiIRNmJ#7ۑ#?|NfuI:^^ ~@ s$'?jh{u8`^,MzDIg,۠4,oA]8xreH4"UgbzzՕv}}L ffn-_.a?9h: %-~Ƃpph]PҒ11tܶ2_tqZAb hJI3ӓgHPw~fVWd6n|[2BZ,%).ϥ[`jBmt+/uKfGkx8᳁l%颬6+,5[@V?1OhQT|׺_ú'wN8vEougC+KX!8xW(! %-ae>j[A! I`h,ypHn(X2w*˴,qy$? ZbΤwԁ,#R(vyNb>|]wr$ >Vk r7\ȪSB?tgWˆj0B|Bkz#JdOJ<>!|~x? (L9ކiZhC-Fﱁ;ϰ6 m}+tMb.1K\-V%. >-6yɪ7֭dGo`ޠ$&Ҧ[bΏjw߃,x:/Eώ+Z/> S؊CO,dȯ,ہ I"3/ oU귮oW8)Sޖ'ONv610r+!c{6}N/{bER5>XJ~C2JSfTgL5vXS/ǰET'Q 9'ع<~_ }y1PlVr.4育>n].O8 :'Ca(bn\VTޟH2.ew` "%U$' {]_;ldf/괠k) oUXJYJO6/vQokN]AE^¸*6 \U9w Er0oI@}SqN~rBp2 1[o ʇu nwe?0om֮sYϛvū3/= C iubmw9tw7Hmʶ!v:1/eb'|ܣ¼Xu6$bWI~TtX|/1oq|IՊ[nrsɘg,,]w? %HMg k~lrYkշfߞM p<}|y}Y 6y}tB 0OdvQ-p֧#fR%+5ӹC…S POA-x'YwiY߿e0g#o8T<<>EN 4l?73fui9j #;<[gcPOq|vfN:E6RRF"%BV(p=|>DoD}pjnIOW'$Mv+"(タBĖ<f5y侵 ^G[A:;XqOx_ȉhz 'R"tɉeD--"s2nF":91iIQWR}|7~2hwΣ(M2\fF)1t$=|v#Xڂ%*{<=2 ٢|> GUygšp&"`$Z<^C#JKb~](qXTbO0w"`sCiP -`7D}O?*^[@kn),7VC*~הӞ+iR +~^!G$oS8y̎,MP"\`u53c%Ru lɧTxp;{E=<ڍ1Oq>xZqQi*TcD9@-̚Vot`pil ZR a@א} myU|mGJ̱ c(ysʞWNe! b lvB/zZuvV+_5Jk/-{fʕƄ)СT i?|∼Gd>Fj&+8Q:B0I ٷ+ءRo^3YkUwL2hElm/ ŝ s_aK*AwټlQXfWȆ%Z5U9R{n`$hǒǣZ9*P}]> TX2N:=!mg]g u/] p:+OlC &WĬjl(ӛZ>f2>v:)qUt7NwwO XxVwyLFm[T&ʼnE[A,K6,X{p;\7~}8(HyZ$"4E4~x'dg9հZ_o w_eW<iESNjKq;hhz6[oV Gܱlİ!phI%p7(_K~~Tno}c!`NNn aJQe#V^r9Za7[ų̤L:db/EJݶBx 7͕͐EPR[]>N-{CCǂ,9P٬aQpQ=b_y6bbo}<ޗIH#vJW:U]?mojP㮞؝"65M i+#z9Po0[665Aݭ,B{pkiIʱihPcƳ~LF4dmRwpU_K; 5_~){C-Ïi:@󺮖u\D'"a\4[&<':A>r8k=5d07NQ1틽>?FQnuOLzH8jU0d9 ?Qit"d&;~p<xH(7&)&E8rlb~͌6q6D77ݖua[e&=݁ PG _!g\BuDWs2>4SQq80ׂ66 TB gHr?RD8&RP_2Tj?-teZ3ǠLPx@ittZ6چ}Wm81"@QI j~ ߓr0q;"cZ)JQ}TX4~ta-0T-xo$GW=2Wc~#K1K3ER)ٰm!`T/P Hʹ,(opf˓F9A\Zde#GiɭhOWtvV9C]:p{3"b3f ;^@k1ttftSEx=KǙ#48dL(7Swq/YstuE-ff,93v!FYopan/Q-E2 ~)Phg)TJ?DΘƚ@`t@8kPW#4))Y8¶9\ތU !"> hwbT\~e%D!n16=ޘZX U wBkn^[+F*mUhiIslq`0"E<{s,)>_g`H wlCoȝg+ \ һMG0[ՏF5X?W/ b7̒'*G\7dl8߅.ֲ0FG|V·4JJd.Νh1K/hHgrjLZ>愲@1vԋ%Y[~˜@0K4|҄=%Vohw?UbHe]Kh 䊜9v[wR+jYGCl|P {6bɝM3)w;cO@%ULlm\+wSUccMey醊RB Ɓv%+˛abBy;9)q/48`v0-}/?CUSWcKϯTGT*ycb |}xR" +MQ@;Yb{uh5H#3wk^U56JFOL sF@|Xk#b"F7Lda Q8 )Ua)z}[zd {Ҹ>M:1VoL-RX@$T"!F$vl*E7[ts9 ~bշ034䳄FJ!wB Gesa/bcc?psQ$3;dJF=׆MQ~8,Swt$e nUv\^FI88q @ Y>v= {˻МA. -HŶ{5 jѿ2]_#7@ߍ7g}:upY#C/fig'4zۅx4U x먨Q;SfT$`膡a y{׺>{̹3-^bDĎ~2V(ȶ̞y\t{4`_ Eb[%_2m Z) -jZoл!NM7o{F9T L85n#J"/W='Il4JV5{v<6~Wlx™cW#As[nKT@q:fL/1NXPZt/Kqk&گHHvfB8YS%K gnfV4c7|!"jE\N9rUk4Ry2n@bLћUaIw#꧌ovU6Q i}$9u:]go$hz)h/!^LyZ$ \!vtCJU>#^ Dl2\!gy@J)W$[xMM-@`0TI\NVEdo7 ?=L5dvh߸+ݺŋ>(Ψ._A=] ؐbc+gvkJ?'pi9:Cm?M9ҙMZp|QP]zrĜ", %oN'f(jWǾ2/mZ,qPM}>k˹O(R:osR[('t^Rog@ƚհho/G[ݙRf\V@9M{Z5mmn._%a,\9/mYǷNcWB9OWc:w/E2lPwWNib!5}0"=5xzt&nUnem[k_M?8(7SgVK`iqw# @kṻO}E3 %7nJ=As ΟWYk R,62;S[]N_eu85\zؔc7l~c$*k 4.L@I!L31 Bxގ'Th.Ta)ys nqhG\EGvYі}>-E=f~Sy:]ӱձxп থq7H$`E&Pfρu]Fl\[R8XXBLj(H-:%Lw?m}aqnut;%s T~ݧ 2^ǟrkkɫ%juT=C׽M#?~0")U^$_Bݯl It)jIt|s<2K (Gu]hFtdOЌѽ,幝ObF Yie',Qzno1֔, #X[Lw6(z67( `?1mTHX X>HZA"7n}lmjjTQc̿s՝6rY G|4b!c줁@#R"REi`ڧ> oȿ?JͮfZ8vus*HPvQlNJFWUş/ybd ܠv~[J]CTaaG}E7m])v]Ϸ9!ZFt8MB*ldlZYsÿ]q~e+N Rnq2,L{-?%-z ,o-QlGr}ԿPePUJ*!`O9<ʝ}t8Fq-ӓRaʀS0pV]!ao4db\EACϦN -WP̄K<'3]yB޹ ` y}x'S|XrKؠx'jUEU$hߤYpoQU7k3UD:BS>GknM b,m&{$IɔM1Sb[}氤ǖ)M9[WYќ(?ξ`8wNHd_acƏQbzƎmé [\轥dIRbw]rP~o2 BȭCND ,aA,fA:(U꺲78ϰ%~´ OGEаd'e*U ctOCn7_$SbZ/WJmyl=/L8ꒉEӼ+d^^k-[qt [;S*?*^d{A?@ucOtyV>3@MQ)#UÏli|Z#m9j7.O S%0Li|]܋hFcb tq1y6'\#e, KsG[AEI1+骯sTaȏ?|׼-O|<5U x^7{kaԫI}Z?s<i5X@|dJW_pq#;DقH@וIx %+롧uHF4Jy~9s,AWSxvU _ᇭwW7a_K1D̄4vǴ<݊ 1Y^n#=:SF~i_g7.b:H #h(vNb_$"L\) B =nXoliNlg̫I9))uauDw*m53QC_,n^W!wiKt{ǽ+fP:ٴ5gr1}t1"P|)5( 58}EwM*C[?XQrAX)mkݽ`lxB J8F)I.Z{O@QDŽo :.9 YB!A/3r3۔O# m6{v ̢W$ڊaDjfYw3%8֟ _U-1zx8}j6U˘╝+Uы;k6/H9c N(~l狘Ge厃8 n{X'!J6c73fgz;Xv-Xû :Z5mIlGr j4lll2. 35XnԘ(#l(x"9)DX ]5qo?tLh!z/JJpTcO6[=n\(TyqOIr1 :rY15x ' jTI4&@Kf:|##E 2m-_z&8$CT&hucц8ND2!Iqè/HSGTFzkJtXz:[vFEkQ<;>5ߣ+Bakٚՙ_>;4Q F+> G'+d876KIpCi]g"˩1!<ސ'-P<e|J`{; RDEҥa]b;K3idd^u. 9@KڵNaQƤW ]eǧ cWE"X8sHqKrhj&Ɇm"?LnfK#x]mDȸʈa:O%MSݟVV NQ2'OM}s餂lmN$?pcMFQRGrŏ@fĿ?QUQ ry53XJyZ^-+}OTҝm*sfa3 -:g@`ִ۪3_GrF hsvNqőLU/(?>|`H`]Wb78'CcGuZߚB 0v;3䳩YaVy]Jڹ#ݍ󰜩] g+B8;bǯP=FHC]j32Vi.mi+*xLtor73Rv%"j?$]t[eڬ`oOsTrߐ9ʲgW 6.oQ޳1pwcL1JGV 2̡W1R\cH$'0Q 7VZt,ff%!5?I E_d쎠 8`@{1J^"JÑ潫cx؁t 7KTm?4jFޜ'Td\f[Jt}j$lzz%!S)XJ[>(Oڸof8m\?K"?UbZTc!u428jaگf\q¹[ JaZU K0vwq%Sc`v:66q Yss8,G:?ɏW~LLpťo_Yf7X$[x@upv{vX>6 iA{wC ː:"75_p\օ$ C/NVcNU-d==eNwutrnI7t%Z.F̌;3pc3tVmG\сT4u:i}طCx{[}MkL6Ș\vc]DxFz+p_R@&(!qh;V!ZRDς,{8Tϟ=lB)0}J*eKdql:gk&o ;~FCIaПФ3ۓeXk Y i#>)B / bnx7Gjz[65xx`Oa?UpߞQӽV7y=@, GrSVnZY3< ^'uO[zR \g1*DjsQxvÎޑ+yۜgy,#mf!Q!5meo5`% )*FP оvv^~_5/5,X6R1 \p{S&8- vWv~U{.sGߪm?Em45Th[W<zaɬ[PN|Sn G/)+`o'4Hb'g6ؿ(+T6BݣS@?4WD^sɡ:ȖÐzHSݏFYd%3-`_Go%&n]UϦm<'Y{ `{br*QH Nj&9pURb݃7)AP;D\UD[1 jQp!'âTgl}mtT/.9hQvihѾ5ɂױyX7z%zou 6 ^`ј]JlW:TSiG k CKYm_2>۩򅋁Zyx[_|4n^hz5s j*X?X޲@Ú2l~/Tp`>sneYwU*y1z;Y^iU+V)u`ּ֖7 J B|'~PK81~J񰟕4T b* Y̭1SJ|ԲDܘ1va v_¢&˪qM󕞐6п7Q`x|q7#.ˑ,5RfRy8ښ٪W_ 1]dIkLV5)Q1ӂ74:d kZ!$n ^X qځLOL45)~^TB9;2z]qV{'S5N&M"P~2ߡ$eєZ#ֻTgo8Y= :53„nk$Ƣ\SVje,3jX\PVZC]ͬ&MfpO-Yr;(Cxd?KO*xd񅁉^"@G [imL6^[f1uPj֦(NS;ͮ* 2ށLXqrWY-6 ?r.n\?1٨rJsY躔,ub妮-M &U;WC{kw^s Z*HKG|)Y\`mJڏ5b&>T{:}j)Z}&yt=E ϻrF˿pYh-LXbh̓Q uj%I~ugd_'SR?ZƗJYZjt4P$M'aKMnr5rM#zAc}t-I;D HGfX?`N_TZڣ}cO/ʈ ؖ A B)܃yQ26qiRdWը!8hh-^|Y< Gm"֢ WgJg57 NNwG 3{'ތ}NC^_}J@%߻>\?[}A'\&9dndOsg}0CFj>i*b&gx% y%J ]L3]"j}%yEbT}ߤ/0#*{~k&LExf+z=f7Z!ҁTz>՚ycm)1%4 ; @ڵ&F,=6kXo;Ƌ]. Z;lDj$i_5Cit>Ɇ*Y!x_Mun8E^4G_W]{GB{<"Z*5$(#%4I+3OyES.=֏_mS|zAr]Q_2ҶQY(=`֔|t)ہRߨr$WؿS9V < b (+X0ޟҏChsov`9 3۵:բå bm6EbN  &LgK\y#$BDZ`r:+a={gWdK߯ X_JҀ'v|LBrL*Qұ',5vVEv 2n/0V٣@P;pE\YDST3"᎑%I#Wu,W_mp0TscMȧEfO=:;1) U c:׽e?}H7_AFY,L2<|RDZR (10iA]x_K,T\~Ǹra/| F0eGO,rA2u~~5C T3TSA&ʲZ}Ѵio񼚨$ۅoҍM7bD gBI@,BEMwkCAy<~SxeÊZ:_`H؟ؤ؍ֳ]DP؞yhroAPmU2E͍KEMo]SX]I.=F/_7"ukb_q/  6MEFLj)ɇ;5<QmܛPILc_yXԓ>)`Y 8r+s=uH9Xq?<ΉΘ Ud< _C@+a%7 ar0 JM;BP!Of} 5dx3TE +/2++ALm F =B7|-3QCWi~ʲ)nĪ.@rO2Թ^S8=h0hFx"ڔEgO) v,s⻈m5k)(@5/?hFe6!äk lv$&uu%̢,KU6Crt;gK~ӫ'Xowni{-Ui&E{JanJ{;hW"v9M 1qݖM"\̖^{i_j{㺧gW3 Vē Gge %k<*,( oP0il;. &[YpY<5k;5C l7O M^Lw# (C)!2Y~.D; jqsȚIomN@?s鯟A~K%L}TH8zl8'H#S_3Ugҡ ?ƣz[Ի`K-Ng;zb?,/="=mnyS% M !C^$c ޤk$gM$XR3.i!VKķN| xiL54xÖ+,ۡ۵lh1A8|/_ڄKGN7)#ATK8<1U`/݀E?_=yM m$C.f_i4_ksiщ#O«ņ.c!UYaB-SkZ4b\~PJ;^7=$ (ZNW $z r1 vЪ,$h07~T&;}lnULL6MݞH /z&[Dbv^=E0)e@Ђ {ҡHRV lwh˥mF@qoqkY??xVy~*|<q&jW~7}Eɖ7O=psW({ymW[W/}۱Z] 5Nmc/hP 6?'Bo}_'q0WivyQd5,fVVy<6vū9m,S]Ī*hR4m! DҼW_εfy6^ݑ[vܶԟpѽyz=Z*OE02=qVt#^W 2{9[[#wi tE!8 ., vJyv^xkЏzy]i d RT M哢rd>~K50PeA?GSC}7¬Ή$G} U/&)FcjIGwyyX͖ HsԘ}Mz3AVY{s{!UhX>y250e =;{ ѾZDUY99'{jIj+J?8ɱW\{( ˀ4ZYMhaFVKQ}miF1c½Vj4o/ HR/'n)$UyD*ZXW82'5WezM+YՎ>zV13UfXDS4-ZAwd[x2Xe1jgJ tJFsG%AIP]:^:9kTtSx9V-dN$Lf0R| T!Yqnp1^#[Ȥ< >ς㼭 7n[mfېV7p*EVמP!UMtaͽTSϙ"A9ݵUvT!FS^g_i9/yՀp~V\#>kuLJ30m}}yN~j=zG:̜)Rj4͚Q pqɽKo*~Pp7x:&]M7Lhq=۪t.{ C}-2K5Ղ 7kzWɈdШnbɽ,%)O#HųSZ?ƞE8EqvUɜLb:n{Su`P vαtYhDUGaYRF PkjBM]MyNZ~, (,`,?q>kdȧ$qǼ˒vi[,DB )t a*'3|,6R Mku ̼yڽc8w~/fRUQd>$鴸h1[EjUGP']hב`b%f,9kehqYZטEyKk;{,)jHAAD)xyǻ:kz@2vSL{U6DYZAN)nYA5Wtn8.E:fAͥ2S 4ê 7oZMK>QQ$Z%Fd+[r |1T;!,Kyگ<P7s_3q2O7Zb#[뵧og&Sy־u3e4pb2-#]_VOŴU^Pc|1b* ee"3eRv|Ax2᫂uϐqԇ8YdO-kХh|iAԂn\Vt3OjW8L2 T+X͑5^X@|s&\'jtT0 _VCٴlH|ASf29&Ga8%;@_o^G&]yd2B{3َN`*9z.wa/o w>Y)p]v%iwmY 'UNS#޼yu8±6%N? 6fK7VJ,Hg>l XQRj"| W&9N/Lhi_@F2/v^*G̱ N,ywn s[ɣ{Mf:Cs[ro> p9OAKEwr؊PXvF^%Fz2j>N؟ǚ*ي7w5mf-"K{WFMKџ-*.{D3,e9Hx3:\'UBt2?ZEPra~0z1K ̗hY?@SpLNeq^z gvfH%GxLI5P K+rU Ъ sohp&}&ݵ^UeDA ʭVP(.2JN{}/{vmtзd(QliՔp'y?f>h$mgڮKcɷ6/qס_v s>Нurڈ<w7ٱzw p BHfI67Q<1GCt=avRSͼ Y( qԻg,\>4n~+qGu OUgw1 AZtDo %wYL- {>וI-x1'䩒nxFiנ3{Y}_15k\Kģ={4xh[߸Q-gp&dzL8iq@$칳ITUʲ~$0bG9u*k҃#/ܺ2E"^h@j}0u+Ŗqfڗ>rM|Ȫؔ=EP|ό\9,eq>2VMZ靴>0_ mKVC6wM0xnQc7B\F&WCA ;8Vh[Wssؑ to#ݏ5m&=a{YCqIY!La`:xP"WƆcR3R;Z9}q|pϟ_'tʝ}M_^r;эx(<%b{yY9medu﹈Zw)ܬ0"UZ.{L?{IS a4GfޅLTbly9tlqd>pǗ1u3$EYSLԆhMlI{}3b7\2B+x*9"7LKi,~V%Pkm*kqkoKV<&~6BT8r_5tɿt8 onB{ ?<2K+ՁS 6V6\84;_擮A6\); \hSHv,ro:[}۔a4R !eWޚaQ`} ܪPbtٻeel`&'piŲA%wDo2S0QL!2:1{/Оh{:GOyNO  WT'b<)֊8ٝ!WoZKʟde[eIn~2e7 f8,ƾB$xT+:07pdz>gXw o;u0ݮj K"Iho_R*ɛ))0fx1S* R[!3D[9`3Wȩ=9켁!,@ǻsp(cE/rR<]~4MJ[XX= \?_T84"Ukh؈ >i4k j x/KhqוM7 }?eſDlDYHS)/䢾DFA!g직F5<MK5p(Ɇ(@ t$넜'Ş~&:% {s֛o4okVWKLp4Z\ :-:=%%#LLbh(W6&P:WFRom\j܏}^N';/-IQ{&c6/%-~+AwV"u/?_/oBkl↖W3SWw}Q+ *0MLBA 06'6Lr_"S47=(Ο8p6bhgu~ݲ4ٺP23VxTDu[R`\8xB@3|S6f:.[E:`OA]]U(2hjP/ݫ?0my/7gP{~Fíͼd1Oo%s*;N])|萤As< J  '$?ݥ*Gcwg|mS#{`3;w\qqrg̯ 5"R1QWۣ (i J>_Y16**|#1 56-_܍ho( F%OTIdqoÝ;9r|AYy.BZ)!67_v~ԧJ ;JX1΅RMQfm뼒tx+^񲛣;;AP qo]`j~d#~9ڌܧQ-Y+|Yr漢8 E9Nַy\*E|~(ipc'pAa]36<|f=uD:H.ihRYv '* gJ8O `i`6>X[k0 @z2p! 3+ I J_xo5R |p^˺xaߴmm"69篸%A!PLFDGS?DpA+{1"a6:B ?93灔QJO@ug/z=r4v3Ϳ32-GxPOz/W)^X8˭x[ճeۓէ?DJZBqc<%>SbFz.γZ[@BpDM>NNQ*=ka2M$[ެg4؛o6o),|,5nh( 9y*QI `ҢsmsCc^r 痾=/(ṃG7t+kSRw:;λO%3 _5_dhC]$Gg*p@8XaS#8Y!>FpLD|!i{(0#%h Fom @֘ÛޟG%H5( Դ&?\fXKiږsJ" ;t;3 gFQwgIɘsG/EKB-R珛?`3 .=޴[3(ǶO47z:[@x0! k޶QVc70rV,ؓe@0k.c 0'A ڶm1 s|פ6}2KWms=v =w@ꌊ@ Z_kMI%%2iSZSؔCϓ||χ(ѝvM 6!EQ;qx]$%ahƞ^Isnt;y!>RT[|'چҮ'N'@4HVƀ@GW=eW5x^L$sX'Sz#%lvY߶Lv zM[t+FX[/CxTQ@~P =x^bA)e 3&4dggEͅ(^]OX%li.Jrs hRBHAç1RcJܮDA/xtj_D+k!𝗩HNonn{l#AHi퉃 eeEik^B!ԑǢs`gotxst _};fF%,(qfzN OGϫe AW)xx (m* 3XYsD$pL4 Ri=IWzj7MTZfJaIS n܄,;>F?Y?eZ sf/[;MHs5-lio,Gs H[9\P5.JE“:RD^8qAn\ul tC= ?!@pǍ `V>Ro4v$DG!p8-.y銮 9\T [- ~ʒ{ 'J,B+xͱ{=f).(P/PH-TP/),JM,.ά2y8ɮ3epȕOdV XyxͱGYQH?'?91g#wY 3o&xͱMYQh#> $DfxTmo0_q Q)QZ%2Z[:hU!q kV$}vBI({qRK,Q5v<~9t@~OOϕm|+¹(Wh<Xr~SE_F׎mł[煕axhv@^֌K0"mS p"[w1xH. EP<ݚHG6~6LgcA/M]*mᜈ4" ! sRPF-U,/^Je-#g{j~Z/*܉Nz{}wsܓ;ιzE$k\Լb \&*`D9"^O؂z^\;SĢ5ӽ.N1 V[8w'+C*Wf(!c<8JH لnBo DcAuݤT-#݅rqTp2NP(Kk Xk1\A\?4JcQ<ٻ+X6ˁ'(tG;A{Rsu55GؼޞsY."-ZA.gwݒ~˺5L*, krbP9[Ar2Xl=Sg\*!P旘O^ű`M)uMeDz)F95S0UdݖE&Bd?rf3u2-|0w&3MС!/q{;yMo,ϙQU]?pv(G5I= `jrFXH=*]p;S$/R(Vm;fw}HU^N͓Ci+/Vo5`^FCҷ"n]~\y_S# 8aQ y5 m897VNg +f/I_xxTK0+ɦJ{o=6I18__(dtgQ` g*lEWMc$Wi|m,4NXI]/k])( ix%B ~wm@.h~ Gw6̎]!48EaԾ{u/L852]@_⮘[1Hq%بdnt э1ɬ`!%i 5cH@\ߖ` ?ڭ,<x Rŭ#ήgJ [uY ?}8دa[삻EysCuUn Sp\8rwZ p/ 燦D?@) DUb/@ xWko6_t(6.qMٰa Ze62Kgm8$ǹłZ8ÕqdEYtϟfJ9x3Qq3\ mV 1+VZq+p;ȲdOI(1x~yCy{yy\ȥIzn>[x\Quu.uM'1vy>2(:*ܪ|ĐY`ɷ  V]W%zQWq) R S , %rjSVMf0Ž x,IJdUCId`G; WMVx ,$(%=_hc+zji~O كtv5$A\ |a3Y(B*|" NڗiC@vh]HMA]l:-h fSjkb GJuu/Yz6$*ߋ3C.#:ⱒ$sqX@ŷ_B_Axlh {Wa#mU6؊0-Bgl{a %iD!<ŽPڶ t>+ìS΢g19E;;3遶-eGP~1 ע!=Qr]ru7+k`6j| 9 7N#ݟPG7 #hZ{h44fyt]a*\A̢(V|jܲ!g/dxF2gVO^˜"Nyi|)R7u@y?26 >4/hOK#OvkE-\/fEc?hZ'nX'[wS;vi Cv;Vv^M17_`hw´k]};HR"sZg/S髗?Jbٽ#,O.]-/n8f }J ⸳Au )^=_Ȋ+ex[+?FQWW!13w"GC@d ƹ z FvFb̜T ]XTZkgW+:P^kPklȢK*rsm!&Y%e[d:z˜R`< W9p(2U_Tg쌤cr<Xh]FII>aSY-M3SK Lla|a.CE^Mg _NH?'?91G?'3I?v]|]3g&Nhb))Nb{m׾5$3$g7C2ߝ UPggI?3z9G8K|M?iZXOc+Yd<߱Dx}V2Jymox) єyWUŻ oJ*/LHɋ\?ayAe!sJI%~[3޾J/ĥYR x2L?+~hf-֦RF ĂBf*^z''jZ fiVb -j栺'jj+*\TQo V̬)ylwEڳ1kbsdr)VLXo/vмbz.ha"q!r&/4OŴ<H4iEgBNz$ӧe:? Fd,o/Ӆyp8F׹2=cI?1D.FIK4MRڤ0WЌ~6Hr C ˽"~ x~>bMf ~f,({T*/ZjحTX^dj~P7oliqip\߈))kktX5Ӄ&q1ŦQOB^>ǧ64kP,-( ݂(Иi]¡[Q8dmϠԒP5躡woWtwm|kl٨#ݡČ:Ko;S BLQSeKq/R_WfDY~bv ^yqK&SsC^ZYIjYR `zaGW?Q.v@wqԵkZP94$PӐt$ |@Y\(?EQlj;}p٥97Hh56HBPtYgA(ƯS 2vCMi6]v0~c ȥ:џ<Zi5R/z#>2mbP T]޿ *V4 NYb;(^/γLqG.a߈l̔ѨbO!'1 npL.=Ejēqωk˺Vq| IOHvXf_/,lrYM%{ayXj[!UGx3{Yc`S]߱=B-O a]]-=< N@l! Ί$.Qk!l`$mDiP<t)Le0|Z)gh5-MCq Lng %ؾ@hIumlC;9& .h"; dv ckB~DK dmtB+qK30x<[=P&^)y " +Z?g#d5X|BV!ְ% VV'^#̃ ږ @>70r˭o-﬽*&m)6\>r;JUPc?,:Ҽ$#NEEQNYfuuSA&˞ UV"nj,$\7 Ax+}1s}Op<(#ZZEOKS">d2ڞ>Z/ -;hKMP໗?6R۠,_ hʰX#:2S2`bAӈ2܆s+WX/ |1V9c~t;.G>"a*+jT=t 'ަDxpG3@Eهs[+^Y'+.+@gj0kȩ ~C~W@B=N% nm㠤d"i;$q 8BA$r lۭ.K'MI;SOxX[SH~_ѫLPTA&'-e[na;}dcOwK3gll~*3yRݿ&`aRd0=̈́1* `0!.0bR> zrpO~xNNߞ|_5"Nחw4<4jkQ VX^%[ʼ,/M]I-l4̖K1t/հK"qJL\fZGcۦe] fjIrO$|oeJ#f+֖`jNt`Ls%|CZ3:OKXddt*VJVf_0,9vBBH7N57fS3&FptX;V? 'UzM@C2Qf(-IlϬĊ`G8'0 6#P3n[.i"sΗ%,G-+Jmk&J kW ;Ő: ?BȜ"]uR!`%3q8|һ,,R wS0j`㉬zPp+V|wOA % f;V !s"Kf{υ&FlD{ҒpSǧSNAUwNem);zZ 6%OÊCE.ñ_NHǁS>ցquOpu=A?q}{|quuw=R~qw3YX[jdljtA]8ΰ`˾J9*w\2b{"Q4pa,9׀UW3kTe5@(;ܙ%~{HwR!8-+WLpSmT]=|!oč* Ch|5&6n :@[ׂ%0KIluDQ#J }K*K<)"hV":>筌9 @ cdc%M""!F ƩH2f X;kVhe#z0Z+C֣>bŵs>Tyc zZgS^eG1xq&T+DwòZ˵= pt3AH>C##;3 TB/Kk7:n^Z嚓] [K#/+>/ ХIG.UuUza,~Fby[ʧҔtR[9!'E'jkєy&[A4RÚ&a?98fJtXMB#M9&p]+kݐb)~س5p5֣FV$8A!nŀ H YP{ᄣ=JTQt[c94P2Wnڡ P hkuMAj tE,*B\ 3h=knsݻd?F4~(`=?Ic,Z Y\<- 68!~ni3JJ1/TB?:~$Y16okl0yh՟Nccꟻk谻?USÃ0ԱAK-RC W,CNywW3w_tcۭ]V-jeHow_~qꉢ77*Bޔ`ƽA7QXVQg$e43sCjoGI`#Fߟ4a$ Aت Fo=/'iss 0jl zBZpwALk&*{ym#{i)8YyVܵn_J0w޾ Hf/x'Žueti3!n.叟;7r"^g3>ER#{o=T+xW[S7~W2I,;M I>ydl+I{sM)7kW~s!a8/ҍ6 Q- [uJ Z L`Y(gFn-TV 1Q ZZ Rֻ3B/(iڱ):SqfcAb |-d5ҤGx(l?lX$75c`_ on&fZbuylB~ws3f!}Ki1[;W^&ԃG!U#mVIE>I2vnKmݮP7i]bYlp6 ̩,[^Hl}DM%sHN,p+=vq7A[_ئձ %At㇑m/Feף04{aJ7Ԉ6:evvf43 BَLQvqGtlz:y2o T~C%Lk6x}Vmo6 ~-Pdm\c]CۭBD;[$9iH/I%DRÇӣ^ʘRX?>O^ݻ_9'd4 dA_+,rP{ +jhKhHH& j-lTYBa.#U~w2ڤq^t_k c+鳓b໓8qhOZ1Ub& W1ZklB"Q)o#E.tK5kU u8kKK1fÉ3@FҌJDkZA6<Ahdsqu.KQy;=n`R*zΊlqԟF/rҝ)]$RiE)#7BSؓx:^XeV~ApeId|@ ]?Δkse$@-4Fj[ϜRAG ͼTvڄ4~%ßӇzccWF'`AV 4{b#xJEeA1WUuxeXK XuV*HxмήG.ue<ڻTAlyfL* c򾞈UD o ec",svTim3.{\[xn9sm =R9Omm\Гx@=.2TME' .N/NSy$l2g'*Y'`o[:twe ,/J*=3}`XR #E[s_ w8;8S9"*ǟ*ang!!]=tjU o_G$VDb?XGxRMO0=׿b0RRQ倠K[iBI#a6N"Įu.|X*Jf6𫇸ٚ2RBɴ,Xr//s|HXm4*?OSy\. Ccx?6o#hy(DZJ D"76 m2%Ɍ̶E eEEy(LRkkE7q0xQK0~^[V k7|sahuADX޶hڔ$ʼn7iD|| WޓѩEW\ L&skF6LKBws2?^$UGV9v^X .IW& 2T͡d'Όs񶗬 ht(<"|a@ebɐBw ѨH5Eq# Ȗ3VeFWv]`dSi+ceфW; J (e 2-W[.d O~|gGBY@^L? S9i ɊqSdb U֚TZ趧\Q|l&n8xRj0}6_qeVۤ2nœc LkMiZ&%MW'0\{9'''ڒΥ fx *xC.A,g0h2[}P'dȄtǂ3W 0=[tw 2& tЕPZN|*+uel>PPxBń í" H#\*0BafJY)x{>d B2ݎ0(rT}68eeiy ښZI QZؔ2£#)8&dpÚ 17Ks^r;תd=4=!xB0!v,a,Njnb 7uCCkFlXUde4,eMԯ9#=x]K0_q0!w^ x"i{F$)*nO޴{='Ʃ(cSq ռ4Җc`2-* V\[.tv'qmt,Uel|g?DcQ@,vNcNA`m찺 BaӭqpX*tV:w *?I殇ԪWdDp4^D1qҙz8Ȭ $8+/wރ{4El3;~pOfou Oq﷛L܎F/7#׹N'm.o43=طx8O( EKD)4/5oO;vT ~8wҩ,\~ FL78ۂ5&japFZ `c9Yi$𞂨>\6ueKaܦdv 4&KsNW6J𹋸o2`Awb~ބ ܅aث6 JD.Txl+~ ."'w&4gX:j% hLRq 7xxca.5dZVՠ{CJ".INk!ȴ\AYa ޡ.I%egG LSf;m(ϐh֠$PB?WWY@ЎX{hq$v{owޝ7lx9J!3B@.K5<'jqM`y07@q{(F:΁mMgwGi BRL?\ij?Û %mSmUnkNBw̙" lb3G`B* ҩ|zh{$}kBmq17 GlxZkWWnm6\?UE@Gfn+(v,@ PZ_R9Z*Jh{o <j ,A'ܽ)}VgϤ8 "u<(Pӛ( c!uGhTbZHC;e#rW#Ti3cK^|%սgDցb7}?xfoa0grFn~F\gEn@xfaiL&!?X$C]xfjC.nALNYIIE))IzE9\i)i \ n>ڶ.RmON`Eq37]BRɛӘM'Uhx[eleb`dab`d``khkd`hieh`ej_ dAfQL *@%E%@kcXf#6yɜ\e((F9 ]pjnzQ~inRnJbB $%D.. %&f&U%dLL,por1=†7,x[eurGɂlT42sJRtKK 'WǰFl?xkn9ADBR  ,L-L7j?d,Zӽ 2xk:e9ADPRBD|Ck 58xRKlQ ̔*`G{0SZ %[>2hbBn]pܤ.4&nL\ԥn1ݘƅq9{ry [hšؐڲ"-]rQB,e&A0,8L}O$ T9_>F)1EӲDSZ>:q|/?6i䊩t:WˢL\o+>8?&T+'HVkPj_Ȫ(](hr_ZfMqg|nVnKwoJD/fMK>D4)} w >%+5'Z)?N^Z5u CDF 4۱FMrThڡ$n^CQ$|G_9[t`%ª.\xDǔg}ۧ<>7Dq jk ۜo^g&lmGyh٢3/^jw WMKOL$mv܉;|%8k$K^AiF %!/Qa NJ4s{'ZLx[NnABrQ~nbfFcG[ 'Wǰ`M <3'%9(EAK/(gsͬ/7bc=c2;y275aY!! yx['7CvyBRbJN~FL6o`b.(JMˬp/K,%qrD;L"Vp/4CRqX3{FTpZ >Hw|alVCM.x atL~rf53 ~P*|崊r`ljrb9%"AKXj3v;ʍ#؀+scpd I4WV&[(w#&Tld js/6%qgD ZȲ᳤吆^ɪ/كS֗5PzG9Q?Ȋ-+~3 oo}j*%Gl؂L;cF>Dk-\n:KxP|Y-<.s҂gkф)2&4B 8HTdqA1$((^ BZ߲AeLx'IOvu!Ty8'Uj9R@N3FSx m@p߇;d, yFj' go+Ki&J '&|  xPK> ɽe!Ee-;hn[%cqR*Eh0E<~e Yô5RH~IW!|R̖?5r!e X֙'Dt8 uʐŸ:cPkBxkǗR8gk/R4O oZޝ=wbz^\}uU*;l#,ē,rmϖ ?v F]Ib$RӒ c҂wF41_TRcH.IF3c-D!4Վ^h 1){q;i/&$~gC*RY3:aLbDDTi6ro$YrDQV.&sW' |wi _^mxۥPe3A_XA .[ xۥҮ}dD͊ܫ7cfQɼB: \\˔ ".xkWAm,;?lB1ofW s*x8Mv#'Oa4ٗ+3('YAKHM٘'q)LǜxMk1ίcr VfeJabRdK6wC?8igxjOm-:a|\G=ڊ. Dn8mvVm=ă^r׋Z)4ZUDs2h Ԃ45=Aʔ6zI] ɯ0?5SGE Jg mȴxZmSF~D8T]ݙ5u^c*^0$QZ!\f==ov43===-=:?􇿝[΄~콘<([?,G7irPӳo-6|?9xY\8- Ixtټl:+`?F񔕼(ك۠3|q˾뱇]Vxll> 4Lw G6P_`;X?Sl> /x>yPrBJbh8v" Ր?i{kif-NYIa`=fF?<;;9&lDX.4N#;d[D*)nD#4Brؐ6 (*W0E^F(NOvE=Pjmaax6ZUk}睙uE"8 Z_{6WvvX[v'hU$眒tO5cH^Đ8X+76i qYBĬا~eayaOgZZMz&aҎaG2nRлeY΢>T(LvY۵emւ/uow[,^13lճ tlquBo%Ÿf N`ɸ5嵑a90̃W` K;H@g֍ k g<bȩjɺBЏ[0qբ ] b[|Lj'r, d|u5?zUjƎZ&z{Et@0'iWuFQK1r}%4y></;<ϓ ~%A9ceư%"t]NU ùT[KUԮ=ؾ.ZA!0|1 Î \}r{V Ʈ 5JJp! ཽ0Kt}O}E{zqe(]vR^naաkPd"_./iZ[ox7Cg'.!ۼ&kmlxcfbŹH?NKOMOԞQ|E{(te}J8f /]XӣjtEpZQep mx$؍YlJgARzBx Ko+$cn{<wp Kj!)D,"O|Xa g#,gWA#d}g!/,w$ ny>feJEoig+zqNȲ>Nzbg虹E}be 9ٴ,9 \y^w솧(jmL7/ZLGM7-_^wNV>"On<nIÄDJ+iST{Sǡ !5q&5ArjKH򉤍h6Mu,ɂ0Ce#)4p--6|n\4`E}M`H*ZWfZ)[o8m)8x* Fxh*lRvo~l%!gFzP@"2%i;O<ϳ9BmCs^6"Jx!"w#XKR zxMtŠv{LH_=BSsŸHf4OXzvQ"W o?Jmu7H^e:b׊ѾFaHEI}IdQB)>\PFHDBw-;cxOi)f- Ey|̶YTɽ GRа&y7TW(#vf{N5'HqU1#D( ,\]%|Qb4Z ]} [᯺5%#Nea E/} FJU1)Rt h% E|$ deHV%cR$Vϋ7 }NUéZ[/ҕ pȊ|dlLdR g] Wu4MZIW+OPT 4=_6 8V]=VwlaL-Գv-d)=(qvđ PUE&$R&At,/';{j'NFCobԗбIM 9Z+D ȒKnB Bu9zV)瑂%0iq&}7L¢fkeeLɪ] eTWU(7+'cܨj}+,҂ 犎5qס;ѣ4",eR,BCU謣r4(C E0g$ ZI.C+ٜߔ{}syGŸ8|*Zhb=AN_Av$v(pKR$0rKѭ1'[7tuMZ̾dN WoV}+wDv8Y}Bճ)V2~x;=P9-O#7>3#5"1$vX73\,)vZf>^Xoc쏙Z|c7oȸy/ c}qqNJjHFrbIrBjQNb^UqeqIjn|f^ZF~IA|QjNjbqHGf'HR$%]`<%kdY#$YcK50()*MAy)2N "9^D95hr40X|]]|\c7e{?hC3J?X^ x;2pCI,9)i v \ ! ɉ% E9yVŕ%yi%E9ũ: i\ ]v JA&J t]}L b򔬑ed- #4,JK/)u"ҌaAkD=4 8x;xo[F撌͌L"LX|<$ .J,dcSE'fOaĨ__ y H \*UK@Flȝ%_W\S2%)U!-4/EO3$1'G0H!%81)'U!$X]!7?Յ5&7j8MRBx;wwnyfInjEAbm@gō̢p٪$ X 0قԴ ԢTG_b̼ĜԔ́2F;rҡ: |DBb^ 5#C\DASrRuU "HIMK,)RP1|Id>b4F72t!΄{ib۸F! pjEEFYadqxioF΍M'70lϬȹ9Eq)ɓ\&qENNRP p R),ɈO-IKG'eM^%NX&\@cѹܞpߟ|Gr o23/'HEX\`:AL\12_Lon\!@w];bY"Uty!n˲SK/_vC6c#rb9n5oe0ɻms+y=;m%CG;SL+^ !j$\Z_"ͦ $.&#XhUg贒@J ‡J tAod 1_Te%,ǰ(YF XZa=`8YP};JNj5 evZ)S] _ 6rR4ߞ@TK97瘞%ZN/G/i/zDA&,|N9 l@`qJwuOY}\~K$宇އ=lmu4Ոnj(<k`6G-m"Oyw'-w} z{O[vYҵ[ksll_tH$g/6Ɉ7٧mȦr"GHc",2NX@Ϡgp5V;VWŃ;-1N]M 7IgOȸy3 2*xUo2#B@Q~rjqnf}F&I\`9s;&ZV 3xwGmBjYr~ĉ^^^jgX)xX)$&(ZX*Z(YYZG)(pM\"0P]SK8OC]%(,83? l%,'y} RkS&+)N^ƙ,ٸl>1M:=WnlxwEo#fFU1(TRx6MuyBbNjEj ɥv@1ۜ)xWmOHQ*TGuUwGJ{. jIx5}huR/3.;;;_i(Ha 2I'ԆgOCz791\wJ kMT-1?6Fgqz6u8CWAxvr}u96U6^^c1cH¤^Y 3rGM0p^,^0NMP{]6$H^$)ŷo'hgi0XC WDA=p̥Қ1oZop="^6z M/Lkԩ6 .4[FmՊMEZ(H"twYikd%iIJz|3j:b+KRKN\|C S4: y\`@>R!傮@eةf*p@R##8LJ2A62 >E Vuhj~t?bRݔvj65nGu(xDSBE!QJҫTN{d;`"zo x /L4+=xD_9Ch~ƺLB=* SтK9]>dX%ctgtrvͽݶZF_5oJHx|jEֺۧNRK֭fxNjJB<,ߪF~?<:auw0\Ys\G>>Xx"}7(7\#6T65K-Clc1Y&i{Kݴ'||D8\73=5gZgMEҗN0 VtvrplgnFc!sxsWEx8d9ڞ=#+n,'c# a@ӌL1A7a EA+g2x;Eyv5^Sfsr!Qʡط.Eq5"*\00/N ɘ*(cu#8&|: -?=$|j"Yjf*ն廂+}>T/HD%DLx%brg'YºQ.-c9{~>kFF'`m؜yRAY9E6סZ6QlNam2575^ex,QPO=zZqB9Q|f0mVycҬ }Mx;!B~ƈW+y S70r0mel_ZT`XXřqq)8[sqÄ&ln7x;!N~?#B@Q~rjqF͵<@ ,ax;!VrgX)xX)$d'(X)Z*Y[F)$VV*pM𚼈T\8OC]%(,83? SEae\nNx;!\~C#>)nx[!B~?#>$h,n3x[!B~?#>$\*Lx[!B~FW 60FG_xTk@_1B{$V!GzVj$r&GܕͪlVr_P̘7j\ZV~u@GvZ,2Kh5-h6`UEKw’'=a6{X~`IQ2[#oS{78OGNoKyLHߐ=X!r{cq^Y?ni'ٵw_tJ5+=F˝?n˻?0;Ÿ]\O*w!~լ &I 5DUzUh Ns*S'eU$JRq6 f;*gc]jqu1-U~?>|Vu8Ug4dRd3*-'t@?}ÅrL}tB}EI10C0Q\yRJuwөZԱJ2fh D!mRyidžbԗw ~yְ+Zh%Y@Vh"0'WN{jOzsT"ALe@mZu'iYK XMS=W,Ya46w*RY^umt sQhOj*x;?' olw_ʳ:;nwf?>Q?/7`TG.7_$ǃaARKnq֭ wvrC:ˋ*:/il[Gevk9JuۛJf>zyF*dW9*S F_MIQ ]g& f@&T\iP۾0<2ݔIBœOPaJ$|jG=Zoa7l:Zض9)5/4/W2_W`u6SEEO5[&QM[ }ƿA"NIS(|J0ZR1I)ḛ1AG֜`HG6>F?xVи!sa@+l`sWu@x?iy1\o*- _ ugV;RDaeG|]mo^\"an:ܣw!Y,M_ -8rݨ=MD>ZB Ƴ>鸆!!:9o:jxi>L; {(t6U Am5 u8h8I.6!Ū8-DCEBd; "_D(3E (PvC+\`Y H02605SZRw񾆙U: 騿껎ww+p1}_,5K9B7?I?ƁG[c ~``c@eV X3K³SK~z̳Z ťt PMءDO4qoIb&] zIQƤ(!y6W a_810DSf':jKh ZM?ar_y:J褂'hlR*{֡g굪;o&Qg,o. fE>_PQhLx?qpAym\2ŵjC&-7Oڐ,nyiĽRCeE[+ lWh5l̑8U6R~f}CH<~p;IF lk,ٞ!CO)zrvZ7F~b 2 >2T 3x兢0-LIU M4ls^GLUjv֩ BCO;L?&?f2TYGOw2V~* W p5@ɜQ^!bN@+>~P@maCf~6tpj3kս#zBRYM*@^ 0%w=>AdC ~5 h"0q[ǍTiTFA%v8P9.,HpOV Y;5s~ab]E^āQ(W6tnrneޞlS'jzq&b}huZjr(}yp؇3 -Qs>$I@2z/h46x2 &rCՋ5,f#)IO;U;ބEK\k$M1gZ>z.r %WMbY&0'T`ߋ'%A+J> j)e"EƊaf5k'ؖq&$lRKUd2?.":JͥpX2׫;!b {s("U2t86˙;7Pe kP3쇷v!O#M2oNi:DCnVE\3V>t|# y &0a\p қX#U f}KG6w'4IKiB(yJTxf:Pɽd}h^VI9ĚE_帏Qm[%6 ʁʭu2a1d}@4:ygGܵg5i84Xw5phժ&@()G-pۢ#x:4@(!X"{t(G۪>h?jC^Xj|rkLEݞdO 酱~mK>\6D1|ʶqcܕUV+/?ڈs|Rb ,h&x*pM-2h nbVL.`vԓ;ܱ 0/.3k@ _oNyDT[ n@X* F 'n/IY<8<քzK߳5 B}=7D> ϐ |z!@OKwH4 VzdT%nFg nQOBjl+N3RuށyO-?Gti\ŠҨ^)_#xӓlBeUzFSB3yli~Ҡtݿ[3rް/!hi{ہB4i[-2@\sFGTV^?@E^$&[`v΄73 7QG{vvzӞ;]t@p<Ww!\_aYhEL TCa="bpB;Bϲ!I۝!?}`/=OX/\WmZ~ %/U4 ,YG%=ؔ ohJ&K hn:ͶYXG7xdw ڍ5F!E kChyGO>@Ń4\3ȍn㤢AoMb,3Z$ҋ[$^폂DhK SHDQKi-k@;,'{I{B>,Įgt!)LRG8q6HkZ]Wdbjz?^  ^)Sx[q#fwF! > i\ PP_kCk8ׯ4](l\&!Rx[q#fw{N2SxXmo8R-B Tm‰jL0N-m_}8M$xX)lYvTzl+!),&,Ve78  ũ){@}B\IoϢ Kbl\RQ2\:ZXZr=ȃ~b(cR0="܃unw;Ns \Kh5-\iL3"54?>FkN a@'BDY18ǝofDihBsS~5s:<{rf[Yna_X"x$:>@XG9W!b9]x6[ԕAҴ/[y+{DV(d7w&WS~JIӌ]]zX* CUb9嵯& EK{U]\rG|Vf3'׭rų5"U^INy/׊ Gew)ζ. {OnJOXO+fzr8c^";W25Sv>DQfe'߻fO Q>Vc*]jNk_YgCU>,2x|S`/^_9&?{g~nW9yٻs?ϠJ]?{1Ve/?^*Aճ: 893%6 nYfd9Ë;ݷglXUSn#xۧOm#fsFv!%in̂<+g^ޜb҂Ԣ".UUUVp.JM,IM46Pp,MW0204PHTo;F&b\)9pWEhc'njEA~QFtqIbQI|Nf^A p')$'$%&g#tdeꦤej(B걊\*%BDcSzkQxΠOj` t:?[G:?/5>-(HւU[/ry3$(/1n:}xۧ6Ou 5kXxۧ6Ou)#fs &0Ngn%xo#foF6+n>xo#foF6+ WxPi#B@Q~rjqnf'F&I\`shNee7 \( f@x{t\i#B@Q~rjqfgF)yA ix{4_rBTqjYr~^^jB@iQA~qfA貞) ``bZ_\ZZ`bi`d``k`kd``belaelZZ5kr'*`uM=.ݲ< uԲ<+9* tOb.)K(J-P.s \.N$l6\fv׹LY\Z[[-VlnGx{@i##fgF9)mwx/9Kb?qBnQjn~^d=)@E20ng㘼kAx/yB|?IBInbNNbQd=)@U2lncg{x}{C㶳SY@.q^mn~C8qqlvtwIH{."kFx4F~`[˩+Cs,t 3Cw\2t2Gelfu7:y&}n}nkܡ7Q6N l&}n6}|C}d}w>޻SglchBhM 'n a*JV* ȲMM мe3wf9зn!T &͠@±Bӟї>P7-Z&aI06v8`@2ӂ>{0lB`83CuzC|'8xCf9xz01 !?ZnM6 `P=xr~ǟ٧P7Ӑ&dM<0&_wt:=}ݳNޟ6OϺS;?;c}Ӕsh;n'x`k5L v;!ԍIY#{-`6 i`[u;6BU{kۮo=7QzRo498;4,deg; ( !Exp,|YwS÷@nQ!6kOCkmЌ0gÞi2DBD"T\Ì TT' ,Gzу9c3_op'٦CclHğ+;g/Ȍ "%G#d tz߬N̟: f3E}f*0VoJel?DkN ,@X GQ} [8 Ҟ,r[W Hл89],F%b)Vuli!AR]v*jpibH0Esx' u G-gB`xY.Rp9/~<= , λHEDžDuE;vCSuRHF-4$\4`CXZpzl4Eh %HgiY\P7Ƥn MXimWP0F:IW#h+=`7*1J Ǔ`ߑW@FE=ulh` I%}8j' Ō( $"&0Áa `hQ-[kJy[OXe>B3_CLm-'4>Xg?9WDQ!GHl95!,_Ύz*|"{6=~ݙ#sTK)`m5d(K޲oWj+  Y],/-"]W&+4}DUK0/j ?JD+5 D$%W0N&][7/nq4?\oOo/(|XsdiXe(j,Oo?,jmaZa;gaƛ7|Za8V VLu30O8@+$ub,`Qo)A.{R&P:@ElЈ zHzVgzXzIJ w@ *7I=Z 0P|9kwcoW54AfUj;:.Tk|"XUF7k}]ϖ!>$i:?nuG Ce_dͩs️?v}ޟ/k&g9[ՂjW$H% xqշT˭c3>i[N+[sn: A1Gҋu8\Aer}'V[*)ʕr1C@iڣ]Jdąeߣs@4t8=Cc'IH=RI]s!b yDM?|$݊ n AK)FO0}իZ+W?kM} iw>8Tg秝oa9mu?5ŗ)P*яA8ÂL?*hEEo/nm7ӪKzG.<@Q_etVNüw~Qbg컶5|.+/E dEgy&E)JRt |wz7&*IuAɸKkP@ac{ J?9j I(G?:?Kǧkz+TԛXuJbb5b"Ҿ*RcHeKۢ*~<ja+ m B9P`g^?uZk,WmRcɸSh;{nAn' >p{/ۿp/{`Uf$`.ŴLRF,lh'ThN,8T"SOg+,Qr$a.0Ifhh]>6ֵ* +_E_Df\qQV]]^šJ_/?w[ch֟q ><>&CY2>òc08>PRQ5A%蝥uP'ј"rtbR@eI{ Z-H c|ҽDT+| 8v!Z21mfCSs* gU@cx7C%yUk5>- VNN/Ώn.ZZf3 6ӚU[F4W'U?~#dpM]!N曚jU )&ߕMC]8RaA0?L\3fM4!GP'}~[uVo\X[a=)ы'T«,*7hIIB)I+'Ojnz!,N Ɯ((Ǟ׵ze {4$^YF=ңn?Wd1^4}5GOjHX6[>w5־7ɆiTaGś*wCsWv~{= #oPy+7ΈfAU*G]%vF" Oͷm|'1ӤbvyڞƧ:NFi=+"eg&Ruiu!xp*=S'ɇyl,C. So0u6?hh4DYm0}蹶Y2@떭m,-Cٓ۝8sη"N.C<8E7hɞ1YܑYqhCop[ "O`p v3ۺ7iika8E]>].Y|[m?RfOĮM=܊"—^Y#'CdYzY=# +Z:#OI﬿(1WB&~3O;Pȟ FZm)gu(c=,nXEϨ8+$ĸ GơnLD "Uz]kur8\Alc\x>Y.Lg4+~ IVoJʺaqO?!$}Vs>0vU.^m{xawoMrYJ}q-J'J}9HRMD L9hPnz; txftqJo7s@t̖ aAWWJ0JY=lVEi)LE`Lq˙2!) 38WQ$wZt^Cͣπl蘭G[ LzƻZh}-+!E ^57aa{%w$"jycvU?/9>kWFɽCJZm߱W|yQD2U?\6''hoÛdfL>I1I[yy0 |<4rɞƇ?[zD"a=DAm. z<z$sѰMt՜,#D)\b4yX5D{&=/1aVL\ J)F+AbN[T՘:T"e,Y%v| <^kI%qB3i+ޭ9`#l$l94[t/W#"39![ Quq9z |`Nu2c]G3M FY#ЧvY-<;0l9s-0eMK335hҙ&lT,Dϓ MT(q$plҒ_,ί9B I(TL'Mt%κC"Hoff@c$PF rQJ<1fs0! 9Q%HlɴI%Cz]k4)s^1&#aO?u.Keðd cvuNEeI~|';mY۪yܮ4(J";lODY.q+$0g0w~nMCEap3}uLw3DNП[!"߻DfZsی A~¦1z*bnVfGhD5{0f\'mO-']Jár )b'甄Wan^n΃}KJQ X~tCu׎8) P\FRIKX'ess0;@@3:n??UzS&^p.85Y#5`]VK)AW_O Y,jsaEmjku(śPkVt:^5c;'}75;Iܯ_ѿ'cto_x/<$&7kWu _GgЋ ɿ>)gD sؓnh7GYO@3`[e4 i%.|o\YUP}SKDIx.yyU(&dQ$˭v`3LnM$.9XKL`JSɣRX(\90><ӄE;0f':AQ %֞Mg [n+?=#sgyXE|{x G+s&{%˹{l62>F$Va8:G iir^{e2P8_n]5qw_vt1'ļ] 7щTmou2pGtc"{=n[Yrϼ!$"1)-Ƹ(J(mSv2@.c,@GzH2C7,mː xYih;b9L?-Nۀ(^ P )|ff,?% x6R4^C׽%id?P)JIJtc7s*^uY$*nKiUqs^UQUS/ks3T%oҊ%TtI t< g x{ t a%&VKK?NxzameplyСw5)ə{0=$|:h5+` D1|%w <9CKwP&ļxUe)*)ĭ#qb'$ON0Eo}7Cv?hc@=tnlbx^:^ pL=7q t6Xąate0 yDÐNV5+WYN)YHVRiwOqUȀvJt$ug݋n&XaI:06L }¹HL(=\:6hdRpY@AyopmEȊQe5 +ќx%d\*DfʋR'Ga4>tS%`Nzكib" &ʠɅ\@•71soiV& x{Y§֦mj5^N1]x7PxBm+_b5Bb4tt#,DŽ|.G`51wƣa<c=ڈΏtՐD^ђstI/ y#, 3ӒnШWuy֯4)ul줷T Bru)^5G0\2w iTJY3^g7<6[hCe)3[`$ϻtZoމh=N\x6zܫ-Q%ˢΖ>.\y03? fL"j9x'(^kOx{~>fb֢tJNKi8qvy$k ěb#)Vfky}/Oux%Eo:)7dX]t26*z jb#&͢i|GN'UePZ+SG^فʻx( /ZɃvjS<|0$JQJ"%?pY}t|HOfMss38W #ZYZ >zFg"DTF s 2Aїx>c>2^[=\^E.dty S'F'ftakkia(2c\3nMW4:3|7*dE VVOyfz%xnO;IZ;5E$rBCa ]JA1"':̂TX@+&8g`r1/F9{iU<(cgы^TRrܡ:'JwBDT)gN B~E iK~qK'=RTy 7zUQzBc*}0ǣsZxU(0GU^ 8~>0'P;tt_ Hlm7gE#SOΛkzvի}4M5Mt 50M~d)::nfW>NdFw2S}cQ31dSwFCC-MU`$E8{>_spfF^{Bid0,ęP%eDSAu_Q*X Rvұ,EFÞn'_>!ӲzÑz*tȍ4wDK=RGXdk=gO=3%G2a!řG>$Kx`> $ ڞ v69ڻ˰]gA5Ƣ&e5 m"Q-}y!1¤VfV9.uЯ5E)WRY6;o"(EqbN OYaV oJ7A9#.z%{0y\«-35`鉃Mf\;E1 ɧ1EV!YҴW{MWDxAw. ֨ a/T˒1;HuJ=|TOv.|$YY>CtpH5-l僜KȐj dl#g[eTm|$`X+k19.d%yMz$ܺ[#@]8ْP ,JI<ʸٟӎ?\ m.f}T+_;v nGuӌ(K}posX>[)1J$*E0'x8V3Ƴ~;g+Ȼ’bSӐ ǾW٠y,U(>'X Eg[E RC-n774!G0kLސC.'q!L O# cؑdD#^+n%HXH'Lu_I ?I|Ex%ukYW:;(%5A)&1+Iؼm>ٹ0i|Z泎*XW5է[v^q0ͦQ/5̼n&+SV^77_,wAa8۩eb$p>'pt6I%W='(nxI UYxI~y+a=׶ uW7 ÚL]g |]uV6yWt=t=a9Xo6y8=)W!#?E)y@F9gq06F}NPbd+%u3/}an>62+\3!tZ _׶+Q(Q ÷pxn`&xDxt(`֏:F ]>96$?CgV0탵2SȰ< - bvi uC# XDal74qS#ϼkUՄF*<@ <,)dnp$Li'RKSI |߈aD'96˳TFsW<+UA #1ATآ>xr ad{H%mAQ %8rbhfT/UE]j H rS/ De thx2LSd((8"ޣ#h_?O/=Ë/>}E9]ˌYe$P7=~<8y¾Ny^o/O{<>{ջ_c7/6ׯz)tʻ\PD 3"=+éS_"y$?@ƒC|XtEa#>Pa!S^29XcBNmӽj$ڥJ+,[P A[DXfQ߾i )RﯨRP?>o1TSLCkPȊ>h-b%ƏyS~mC C^coGWޠzic Fӧf.۵Tdz&-LM4``8.\iը g4 7/D1#j"$Yr!Z!ա% =S~<|96!Ҡ~BrF4LHԢ@YyJpFӰy^K񰖄Iʤ{!Ȁz䏨vIjh*\?ǨW Oj]f8LA5§̠$`|@9v @G4\0~{ 7G֢x8EAIPmMۨB2R>{ůTCt8Nyrry}~>2kSs?{b۽b,"Q<40^؆/@ }PnPjoRQn@]Ne!k0)?\ĠL|PI2i Be2d8jr5$WUcxψis6y߿5CSPt>z剴K$Js(\Rb$F؃B U/p0nbc̿z<^ ,A-" ' 'w`,Eݞ+>g?6@~/pC=/P恨GGPG>D~vl$E@G!!@ z ^-hx59 pr؉Q(-f_+dZ< &W_-"Kϸ0"e\2::y-p ?㯂s<:A;1Z\TpŘ?1,d> 8z/>;^@;o3<<~U,q}Nou8TщWͦO6.qP肁k >fl>6Hq5x܏i`Xsp#1iD~UTG3ӽE>$E<%#n\T_MF؝sP L#g r˯]~ *utIp U9")$Dŏ Y:җc5;M8q"uWΝbX() \oIXΰM!w '=oi NJ}8 eP]C@>\9  Or>&ÄxfR@:wjpdBF̾QSlo:b8j頒2JrI*qT%b<FЅwh{* X 8+PpBAU:ֳK;Yy XG޻",q"A[TۚD9d>*"Uᗓ̢4k9'< 4iW5Cj߯3F73;`2}SՐUQA6 Ոh̆A(p6*6K̵k78QEӁQ\գpݨQ*AZra:d<iapK`;j٥Bev-ۀBez`[@Fl.<jg&T{[ڈֈQ'k JI+%e8 LlP+4j N wT EVM.t69pÃhEKuj^˵Ehl"ȪLf KMvVhƴp/(ʷ*Vk^σ8HCamB(*N#AV_ $ {MKoL4O`i#_KPB^#?tCeb4r C9 ދ؉U ~n#;y - pB6D/ lN8;ZW.RFDYt*("H( YE@{Q "5@)D P(Ass"3!>MFÂM#McPF\85V8jo6acSE im'>s4:k1hLAca7&x؁&5QwZLM;W|e>3?y0"O ;!Q>u15z¯x=-xz\ y`-7ΖFֶ\a?[t,%2rvYḤb *e p}4~\"!$Q, ue  $Hd۟;+|aܥMiYdPA<)* THcCVyة$m?ZRC@*=~.]_ѤvJx$R^2KG*I RyHFF߱*c,IZgs=l1RVhИQ] :mKqD~HՑ\/%\!G"Hj4N](~۴|7ۏ ^}W[ wE&f:YpEU0[. V])h&ҹL` 2ÿVwU;gfw:4,@Mt,.!|| Y*Zf Gceb.ϖ~hvq]@LVn+{o En4܉Hgp73!vINʑ4`ku*b{$Q߫'0#U4=Ʈ(]yw{&^|ufP6zba4a3 Cb@X2sOigȹcԙ"q D:NgdY>. Ul%xMwcD.*h+ېtU{-3-t?:C2ٵ{W #0S5mkx,{9tZ٥K{:v hҭL1ZWS&(;edukS 2wDڱY Ew{HuC?S.:O tS5uLՕ暑R=ʕc&r>ak 6pVW?'MEW3_O-81U'ǹ I;w֩1Cim !{꒼*QN!ߝ{} BEeOEv1H4+;3+!ˎ^sD^_Jݮ$Y!ٴ9\G5I(]5-x=wfy5{.0*sW$(k@F"f/(t~ahXY~j|\:^6B02e@u$箓 il6n 7q c ѽ+}aVDdeA :sgG'Cp! %<*ۂ.G  M7701y]ԑ:g9&#,eG:6u5 H ,ͨI^c\CsԸ+ij!Y)]:Sbż;KgRN,;-z t%C&OoəI4;P-`QlԵ>ݸ9Fw Cp7DiiJ]Sy]f{|Qpa_V Yl tv~;c;x܏rQԅo;%0OgђfSA_ߥJBdeJ"u#CW2r>lLMl !ˌj3ZKwޱ ײe&Qޙato=wɐx0ߣRjP\:]x|ֺu7Ot2nNۅogxd{)Js,cnUm |ڢNa!s[A"]_tDB϶euxN@Pά; ^9^`Ǹh ewލM}76<99'myU=^^=mo5hߝ7LB8gJŞ _*! göޛO7oz=ghh\ P킵T;6g^l<X4ץ/vЉ~S&Iay5EMRJC6P00 qԷ 90'EIx51CRYJZ:7E ZBLΖ J:i^?5*\Mx:\kUɮAnODnVԍsj3RUrɩ.SX:2Z fkn,* X3Td[up̌Nv$ԸEf,-!aLwhcFRzo;Ƴm5XهGЇխHQָ']yEҨ15R7kE;B :0թ#u:(~_G2mMT&3+u+vBr{|7r Nȃ8݋or#͊g3;%`|Wxql 0 q"ڂpAvШAebDnbQUdL*|&D"⮁aG?-] T>N 3,#-3.__j=|7e|5=e[t%wYQtub= vd'u]Ujlݪx;0wdw|t?xzh $:5%'Q{[Jұކa-eXgىa[6I>C^.ah;hؘ W]AUW xu0{MuNK PH.,p/eM6}_PZʙX9tm"hMb&IzH u M2uC 7rk y^"*o,G|^;'1vcpozJH)WJ†=+"M`El,sdBGRu}t fx |_?36-sfyQ3#y7_S7MYn?ޑ+"y6_Gb![ag  /H/00r"H5Qa[9NzIvP1bYf~<)uߒ+Cv; cOi%]$4zZv:)*U;Q~^p-Ҡ{IN^*v03GOB5置4-$?ٴ1{ԇ&+R#i6<;(> vIT U"u%m.nKŒI^ˡGf9#Suלpm/ qiLg}u);4qTlZ:aG dL" [VzQ e=ׂoA|/+pNyeknD.~HWOT-Gcm|ʍrnZQ#6{xUI#kdu^QIunyY11Q<1G@>0NiVAoӌ6QG:7Ym`fE}Yj_]Ge }hCC2jWAYް22r6|?Mv^4jo$MC՜1IkYQ-Uv:ӱS+ ^YK堙%[hg Wtbʴ/.VlYv+~9.U^SAxe}:#h{^ZMG6]C.F:!n*wx[i?j2SG~- *-kH?+k+~HuƑ"H+ax{@j7Z;AV&9bz-0w97F]u-be~-^6 QIkiyxWU.XP<>c ¿^a] 7vIR--i)_EG̮bkcw[_{P1Ӽ8=*.(ɏl+==G)Oޓ`YNn n׽)@z'ի8Y0>-ʟc'u~@Q? 8{k_x}{_Sƭ/Hs u{q!9!56ػͥi;I+/&yh4F3_ƹ7ܪx6qH\: M4v;r!-$;~WtByYG7K=w_Ei,ֿ~o#'*6z}=G;4t]qWN芧:c/b`;O.H`rDd$Kn;{?vzC/ Q?C|B ׻*jY*6zcxPu!ӦF=vh`.b80l'/v[-^p,TX!c؍Ƣ|n?QrtQ?6eß bo o~N8|y U?5[A ®Fo<Tޭ?_W^C'A\C_$r.!B#p@HaPDE ,oRgA'9wq"W e𰣕Qyו,>V΍N.roUn<v#sۗ<ðw őqb9Q"f9t^`h<(NN`Ě;OZO=^˟yj`Y^Ck}? Pس@pM: HkzbC [G'G޾j"bc\"W^sPQȻX?Zɝ 0#%oEz~+6΅,n!III "Zhɪ8hnN|+))L*ҋݽwk[2~ş f€P&Uĭc{Fݧqbӄ+1|m"w n&M`/8H0O!%.%n!`H,jx>fw΃ɘAuȬK=>nBhg0]y l-Z( &.2^bPJR`ir*w8W/#If1WAr3/1O=@P0^EDb%~MALnsT k>=m2kBpHȹtؠ*rBmJu@ r\:uFaMeQ [wshhnHTcM`*\P( an4ć;/^l?)#̞y8( |溠MqmN} W8QF3S6A u9iK.vHց.G ]dlw"Z/o l=oԻI?s&^/FUI azkgbG҅(Κb8\<ʇbA!,HoF 3fz~{;'OZßJ9!vOvl8v/Z/Z/ ?*zq:>/_/ZG;<>l)0's(@/Z<{b isVr_(4wDQ;˗Ebv sBp>  8yTF*1xZrN /(;HkX^9-u(vDS37P\ RU{@ڭPoU#o֫5U_Y> z#k3;tvg ֝G.矹쐀`qZzk _9-7*8hkER^&F,F'GZl `Wz 6\578;?__a۱h2nf֨9-{ L=S(r&9}ga$.ͼ%p} L(yFpi~@NpB2 Vt͹MM/Je0o>-ss*K4tp-$J9{7]gvu#'D%f\ 6t>\M;}]-nb]nq[8j,tߦ&@-5Qnm{@Yhu ur9͋"#nQZbI% d#iAh-?JLn(A{yZoXf4W>-NiG8󒡋ai^dr"6HmG`5SErme"Gc&c@ |Q)gr//P-57UZ\pEd?ϧ2l]Ff]e3ay^&>UMIn߂Ġ4.uXAx$DdiG)&[O\k3'^\z\$OYU"9˱+rТPq; ?ٲOB"U+jz,$%ޫf4@p ̻!WnSه0G!B1 lv.gl1evdv5kɻ=-K!|G6 O JS^ٕou(ÁbZ4F @'8U:rБ&:d7varV.Chq 5~v]l3+٤&OEߖE*EuUH1:R_}RBudL*.e5f&;w{EPjSņ.VsԂÈ$At57Ӻu΁+,qh̄:J7qKW_y("#sG's;ߞB[-"tqyk9=v`=pdŬ0]G@Q j[Y̩8lيEt<%[yg4J[g`b(<{ RV H܎  쐉u-99H)3;C'q]>Zu¹"ֿeqwHrrϧa'VUjD o <)b"3O7g`]fWzKOINQm;ŋ+ŭUhăǚPFو"C@Cj +> M8䬂xuU4_cYT֛Q÷xHkDAkh(~LT=E-2ۣZ;k෣fJz5ufPa|~0$j,|ǰ<θVWمq J~lœ?;<?ڷ ,|-Ȩ (9W!vuEv}I3┧ L׮ۃt1:#Q4 F[O52YrP7 Ƙ%Ai@9 áM,f#h15F]9ڣIP u]bBע1mau(3UܛQ1(W~Z!joFхu`Lc<<2BIz^`P+|*er+d3K""Z%NW~JyskR&|om<ꝠN2q15o` B29W  !A4+v`Ҳ۝Ѩgtuz+mSyu~1ۖ(Up9E5fՉyE7k⇘¾ K*g\L/K(T/o"Q:a}*<r]ȼ΃>n,8wA2Ә tڪYIW{']˶vuwTz@IK]Um@mϻn] ؞mҠo7iþ<8M^>>xcB؁Q_ e_<~y^l%yVJI cąyWl?kTSl%8>9?~uxp O\.o9lu7QA%I5z\N pA8o"&ޟn3[hŏՃ жQUޛ1GM^ISɓԜ6K0ߊ2 $5Gq0HowuF{.ASh< WŁIVȾQ6r/T R oR0@IWMOXm9=o{ťaھrw5'x2G&L &w$Z2B. 80oKjm5Ȁdg#l zd$)g^/+،ZB}Z DB4HjU x:[N9։uĔOǃM4O6$ZH|۟&Pli5:T"!cTM(ٚ:&^\bnI8C Zit TyU8CپKQj (]&q8c̸BV~q!YB6FU0g^1;:V}ŃA_,1=k3]sksv^'>/C3Œ:65%kjzD4xyYve:[4d~]ܴoh ǘF8 $W0+WK$#,|q2?p7!Jy 4yshN&F(_."CvDT1rK4>WEy\LXU!#PUfDUxʡpW/Z{qyK.&&QaugdLB`VF U:U- >qUK&IƵC bRҊ2!K$FcۼZtV3,FM.+SX%\2;Uc|(Î_]vxowl 6ኩ;%a:0Mʊ6}j`qFGA*"I`az_e˗Jfur.m;d?mj0،Ϣ Gi2Xx+}ILSP2⹵pS5>a('d݄ o}\>Go;C6 "xV>`& `df*I :7u~i,$ 6 ǂ͂hp6X,g (acTo;CO:7,#·YXmuǒ Rp쳫 %6N'C휜|uKY2Ȧ 0=XA0PWRhF[vF#& |?wzum2W]Zzj9'g2rN*$dfʄD?dAAi+ ɧ-Zɦ̆@6.IU &Sb0 ; ) 2XC{z D|eKBڢF*c~`l}GPt:W΀ /#rHiѨh-<`u#"c4 [̛%%y1/vgLe _C3<9H(:e#*ر-+'dFWЀp>=Mc<"l5L^YDè+mzMc,!@K)BlPA3Ԑ-Xc;ٙ-pbV }ᜦE\lJtr▊yU$`.%S6h4do\$.Mz~s^%7|s{Fsb2/jע='_oC)Jڪ_yqT=Rz8Kmױ "rFME+q$Ո퓗G-Z=J,u,^՗y]_7)8!ϗޘe?*$כM헓冓r;4(b%S:edo0&YcB"UbBA".r3`YK`ML׈S;"DwP;lU+:2@N͉Fk(c08_sX ,<@ F-5FJO/< zcq{ a;B,3,"),tظV8p @GJJ!iJ¬]F}^)${zqx~)̽;j&hugČPђF\_WT ^*Il3Yf֍Mgpi8Ô@7S3p$w D)SmUN)Y%dvbo/ @A\*wp?>޳ܪ7pВq|D#p'8nW02N4JB%U =~TH Q$1 GʥqaU">yqesTC?p,R;4h2;`DovPbQ:nZLP&c$6iG#˪i `j"b5 S[@J9#N>96ӡvC]ᑚ.l7 ?Y2a>2Yt"mW%:O3cl>"| tJe(7@f48iPt|<\, HÖ5Vk qMTP:Ttm*E^BZL]|?+?SM+:%Mj^ B֮uW Y&/(+5FlS?7?f֦Qix߹U9WHϽ7%aKND y"(M_Jom\&1.YƟ#l$Ď@emle5|#W3kefKa.;I &삉K&_܊UCu}j^h{y܈s[fV,eST0V]+ZadMDƍ3N^g#4:'>UkH'c_3]'j8XAڧ3ɻ,Dc%w}7熰`oSo:^]nBҶ+oTC-}DW]o#x8mK$VŮߩ2N9=d9v9 T?vuO[:/8Α%,BǺ7dnZL1A\(oA?*^XuiNw"}*9 5P_J^׼tS=Cd1<U\*`m9]K?%Epam_Z#G?Ƚ˩ du'VW0΢sRSΙLRA'O|]&4˄2be.2s/#*{?b_Fc[ ptT7f /6n纉@K%Cj JO%e40{Pd4No_ Kw 2'k>4ifl %\ Ѷ*R*JexlPpƩnV+bS,{ o x׏LUW~4tNMr/H@p(%X hw2xe!XAXs3NqI4nt}zZNNeSWI]vL>ȰFmbYJtBwqG "ՀiҸ>v;5W,63D>0$Je1VZ ՈEYi1@oKmu, !WJ+SD%~#(j`x d)6I2̈́ㇶ- EdUI Egq+x hY:>Jk^be ZM+ž(+(15̕2PܱёNT3h(dS9 >Ú'ߥSIޫ`iKN-$2[կϬ~}gTNO-3BnUZkPmYŋ1:+E|%9=Vs%i Jj@='gT1 x+& Czߎ'QV<\dpZӴl ]t,u^aY +̋9XEΧWq*}|D|[_iLezg? (ex^c7RȄ rwLA?>xL, 8Tךctn K׃v>P(!×<70„P^HdрRKj=+-bک]_ վoӛzx0ٖZΧL%^%aEm^ב2#dES~k8=1a 1Qn!llWXgt IPkYLHgN!̡4ю5j2q(Y֨BXPrA>/iq@On8=]o2 6W ݾD[_iS/!ʷjv=u~_ik)aXdE*eȡ8CѴG4E&FM`^';)^I]2C}<8{޼ oE/q;eh#o𼾏jmUp(K|CTL|2!D8 Z?J2,hZ.gp.c<69}H_OAФ^w\|;0Pa*WʅN~4V0=wx(hq8J tn@1w `q'X[NC=i)KPc=+x|'Qu=z#(oO =@}2P]_dk9}{2^tB#9ˌ %4‘**cq;X)ꕱᤞd@Cy)#g 60c&0|q*8N?&"hL彞 $C ^w[|-S4J*D=#f0=OD&[]K Ȉ(KS `㹬|;*{ۛҜIb ,VnFQOX pqN%?a:]dzss4b"֣G1̦swGڮwŤVyEUD{b>J`} {+5;ϝsʈ@YJHչƮBEMvXӆZ'y誛tM ceۋj$pg=ܐO$v}Uީt:E`AXbL)=1q(Ƶx/P0"T&۽X<ښ ݐg/|[Mb^9u&aTDdfeSeYêM_ AmO0y`.TycF ,֚RsEVT݉Vi8f}7[yq]7N0k >,ۼ\OFɧgG8zBVASWb$5.Г/Iq#44z[-mCÎX)AࣦV0\)gZ6LÅz$h;gT/E&=1LKon@ t.b4zLY R^kISJvl.ţHru0#gZר2 ˆLueMQ}Ӟ DZ;z(`.px#l!TY۠Q+)vE>3#p;,8Nj;F#/(UD[`*ޒXZ&C2~`=\1gv),Xl$`LEiPP0R}sd&n$"h3}IGo>g7NmIYle-6)XMia@,ٱwDj'e<𜽦8; ߘ0̎dYH8D<{2Z2gĴ96G.6+'*wF婜 6=Vwt lMְ(wu`ic,FwBxl(=Ps.AbTyKGZim( (=Ee}eY=->^OCp|I`j/D?˪{[dOlu[*).%޻HTn2=܍,'_z!aK`0{VMgWy(^(SXњ[hӿO*qc8<ii|AUɥJ.ZbB%n.one]s#F9O"rσ+lH XwTs+'奂*S3]ԏ~D<-mm3ņ-鉜w_0k]XHTHzA>Tg6PEw?A-WA" ]wCV%B@NhSyQ<68b>9<"xԿ|'9 |wy{HwD{֢47WPglo>vʜ](0 tA9*y8 ĵ!9GH[`u5-UN{2}3>womZ깕ʌ"M([=`óTj:L2޺lM68~% Y%Y*Lv` #J1OZa/[ARQ B6,z*)26RӘ T|V WT$`vv_o":bIġs# .>]sl&uF(;zؽ;bs ,w}kG"ӑ|Z!|OUozw#QӏOCgD oe+϶vT[>nT>~@~bk{:cgXx+q!CtsEwyg9'v^-ERñJgCI GQiZCXLZ,W.pQ*\ejf԰9.1ĴNnH)N*%C^6Q a;#\+roJ=V%B,О*wQ#]#{hN;qJlT AHAEPN8ɋAب) Tq=MdںgҲl.[^dx&ukQ!;mEx ه񟿥-N,[^+-qj/hח7R>͢0wqwhkv,'kK[ q֣KhBTIlogu/^_YXYifs9L]aMbg`8{g|#I 2ҿ`-mlޖou,l#c2y;Z*/S9,c QWz4^`wdAD9<p". ~$R/X|&sM4 --/~Xz>$vpn9]| 4 @JA"}^Z;B⯢`fYE"yW O 'KׁLnh_/kGg\Tkセ13lF։ׅd5~`qе4̚B-]r_M$lgyYD>#LԻfR;"֨ݬwq֌fX72Ŏ"kw:\]қ)ɛD+׬F]d S8Y+SB!I^?$YHzSD3E`zhKE!f`?i-Q0blL~?=·]u=ldG)?LVU &]WNد_hyA"&joFnFPՋD-_ز"q>=αxTG1Q>nl]4'8zx{Q(~Y|pA_ ~y+J#H*WI'X{ˣ\-=Q_VZ@eQVsjR~euTƘOm4f ),X.ˆaOAzLoApT*-׶wTsFғE$&>+ApiX}4O?/ ZhHcq0&oR'K<@Iȉw'"jpS%UԀ'WF HQĢ+g! pq;tL')9tQ~gV R4DtE C NXDGYvA7k-4*N]P# ʑdzC HA &IMQ[:E*}BXr!sy0=|+48ơ W<.єM82)d 8KA麌#FmtmN6yKhVv&0OuK^9q,s9^"*'jU0_)U U;[9 >.40CUQ-ïdDԍzehAXƑin {ڶ#jO_j}R: >eϧʭٛaREf2MisʶHteQѥфQ=;Ԕ0/|ck->_'M_Xg~f~k&'Xb3=%N*-R}PO2"%ON߳<Kqޔ旌`L|ɘYM"E#b|B|oI>%Sg? jט^26ÕV"xÌGYYiPph܈i0NnI%"KEg_{ Ӧ"j5^e^H7`x| 2w]SRY~a}ǀNu78rJmzNG<S?_es,# ?؜GA06k ᛪIçDhd/L !XC')ɦ Awnje AHKE[C Vuڏ"_{r|{h`i4.5@kiyqyQ ;VtM@Lq0 P.s'n<s<IRn;l e&90 nTE=5U߂]W_Ÿ}8Td1"JE|-QƝ>V:q4MFJVɏ:ya2qh!/B.F2(﻾z}8@<@!j2"q5Ge*#5od;|{4uz@]d="kVc3CΉ@*I_z-WPu*1& 2ţ}o=m\ Ab4.o#dSٴ4L褒wR/o Hihic\SR=4"6ie)rL[,Ptu쎩a]WvBӎwQv[F L}ˎȵPin/qUQ2k13Ju<=:GѪxJwI4n5,JOq*_X?.df}<. Sh aVQӺd5r9 +JqƢCd7B+XfXŃ^RT" %RY)*<]@5%Qs\n",h ,l(m)y7luq+ĕ ԇ 9JkdZz +ڳ0誄!U R2YbN R&PQySCܕ6e)>HlJ+m^pLv.FY\=( [+_[j R[ ` y3!LP,.|rǖ|Q}r:bOg;^|d3:*xSk6Qt@ʋ1)+#!F,_-ĖllJ6KAű8͚L敗|:u\p%OVZJ,?`M{$ =) KRbuIlgh!i8s^|Fdk1, "KQjH7sWK߬ŢVEK2T*ن?'pnt jfZHKۛqwG60WP owR),kk6 u[ic֕19fJʑm|3[O^jNgۍMiv]6KFf@hC63EY7Ay3]-6{6J)H2QWU I,2Rfw:ޑ8}hLK%0 "J!o b'( U!(:5Et]4%Ŗi_\ꤊV@tIa0_X^!2U 6AmNF.7عfņ<6_NrGM(3s%_F:BF6$=`Je&.T3D(>2ٟ[v"oЏjcrʀ"d0j괏&:X wO)'Tu!]hp&X2ш`@:}Aۇ\~@Nd^Nd]4頴ǙEsroKB96ķ']'݂8#Ū9>zb.`sBl%G» 5)Xmz'/cb/FN.7O0$,*@<yU=>-fK%aSYHzm|D+Vdb@ͨ@ VU0@*Ҟ'f]1SqO(;'ot|vd`9O¿B]]تNZNVQmNl:@٤U lmxB̸"޵>>ƀ#R.`3Pl2% 㡼^ ;V$`aǦ,P!Slq>xV?@ƣ:R tz"9*.j׃r^BT_Iu:׵5+GsU)}uaj@lJGhͥ6lHS4'u9kƯkeȈ 0arE>>fH2z{o ؊IeaU\++gJوU2 ܂ˢr}s;&agy^.&=AN6WEi--*66ڽ KqoҚ{;Ij٢eև kLiu+qXA[fۗ+$j8wsZpM[ Lόr'^[""-e,1ɘv g;ΒZ k:KkGqAy|\-BhGnm~DYoz}P4+7򙌼WkRc}+,A‚x8P(Ao]1t24j[ sEgy$2$EҷhӞ+n1D;bV5>!RÆ{7ytP8 ڷ0Xy;;h7ݦGb.{PCf%a;isXé[/0%|X^{Chc[/R,JEvnMa`_?F2Q'Q.&5b!YS7+M+,䓽T-+[M"ݠ Xv?V/^sxi_*TW^11QNE oK֔<-vyރeI-A-#C\UÏrnmшSjj,% A 랄$fHH'(l|eA%aiHGi$ܼ% J][׀+? |{~N?z' d=YD6k;g]Li?om?i:#2*k"X A^s<ϖv0 k&񹫊BB)u"AN \#y9jTO-,t9u.w7J/pN9~ fJ7쟂(v`I'BaϜcBd`]5 [»UW},'V,)tLy'vWZHK2.[k_#L5yN)f: 7|[pD@d+EƢ3b@qʙʦ$"6geuՋ!= ]gLwlڜiFمNѾn'!݃U2oNEy!Y~z(}#;o4Љz <|MxAoɐ2ϡ׿:t !7& o+Hj7doc⪯*c/g4$ޣF 5.EOh|66f\\[ë>]Ōz?L2/汷طNڬmRY%feX} ?[r|_0f?Ы@ڛD]u/A0"Kȯ[I`<8VS@'m4LQGiDΖe60}fnseͻ$imH:1*4&FDι773G!@X|zed)H-!٦z edMI;ecIN4ގ q췡?&4, |7TO4 #qg%c#b+OBsy$D' |i3 ssXB'~)X`3TvlX֘؊L1|5ӭ=@dJ7,L.f>A±eDsݚLGws'~3"BycF?-[¼S#ץQݞdt4bvS烹3V#%4(1 cWȡ6{,8W U":vRf7.yxeJ(!4cO1L]o[?I<[8(Й>L^f6fOJ9"0Dz&vh##^x9 ^4:Q}i S 5l {̛Ӌ.tW'#{`\Ow_hm]\HD~DyLuy'8P/лbRG#йvhnd;~9Bha$i06WϨ3tTZ2u$֎8[z0Lb`S몸zEi t,\n[5nĎXC5:wLl_2W < =Ow`پz|_]xޫcUuZagA>+zy{_$ke/_@- dTgaU*e:Jc\rToV!!E* vearSQٸ-[ ]9h€aTG#F>ݰDnyD| ]m<}aj }sz =xQv{ Bak"KjAR W|Qiʑ_u"Iz_~e[>0N R X\B:KqȒ%!Mq}*di^jV8pЍvKp[i$X* ,KeRTX* |RLh,y򛥲RY`,TX* ,KeOTb,p،'G ,!'f]fۜNP49feO-I_?D+t6i&-#򪫝ǿ_ smWܯ/Ҡէbj]M>o2=kj۰̷E NZty܄ $k},̫@4ʲPN s"6ܾ@#%3G06pio74潼Y^^^^111'}4d;ݶvߺm5wL=ɮf3KdV^]6kKIu!0W;m; rp:nL!)_HVl**m S-,jƗMnI P֤ed)@$) G 4)`Qkc^~)1d6u_| seoIԭICO2-HDH|RQ9瑋Xd#%#!$dddM<$#BHTtDnOFTl*|!"*!$RDU188Aē鴣sƤHR ߒ`-hߊLl , 5=$8,jx _DxxLPs%xpn1ΘVÌf2Xp19CLYxs2+&p9*O2\$Zgx{)N~RWVa~(m4\+>|hsk*0h,{$Luc/,L"2nUG1G%8Quٔ7Ɏʓtce1(v[?#:N'NtHbb` Cd׋Ȳ%&IDfMfZK?4-ǐpMg>?vzvzvzvzjK;=w4ӳӳӓ7K;=K;=K;=K;=K;=K;=K;=K;=N;I&}q+ y'] %OON<Z\Ը-,-+ t*F,Oפ O@NSk:[WsqjX Uk̒pbft&4z L 35ef 5E!Yte(0m LKj&#" 3`Q]/iJ RCL9S,KՆjGUmotHe`eL< rupZ!Mi<褏\Dru$rbFql-X!3 M+UkѰhXj4,5 KF'Ƅ 'Yj4,5 KFRaѰhO% ѐ:GM*4ijt5?>n88:L Su.<<9[7*Z4, WI!eq=FɘKNWlcD܌ 9GRdA4FwsӾ ·NHbL-PM-?oLaW?-ibB0~̱kY5iy vwM;[w}7:;Tq1JtlޘC4k;oy"*;o 3 %'kv0Q{v=5rchcmt\ >oU/rt} E4l|B~!mb2beLzM@#Q%+h~ \?Se,UDeuDU'>d{e||@IRA PG$+s#]#y׸,Ec T43:0z7rSpKt%–=7*aq`yk!iJb]I3֘42ڠތA{]0+քs Nb{eDq/ eK%ʿSRQTJ3Rr@Q( 'ʾI?T'Y)Nْj֪ojE&DZ ̆ϵ]u'>\VM@bʷT[-U|KU*'Ƅ|'Y-U|KU*RoʷTO%|wVNke=+ϔcŌBu&̠U +~~+Up]Jzt Q n"}M/1m:bW,#ʴLdOF+"Px5`pKO|:$IQ=GQ$85=M(':0I(0ar&T4Pe*ܪQx L`;' ysŠ.UT*;K5N\c;I⫫pGOVQ $x7 {&+$$2s_qZk¯фp]yd0H 9UD`EY0|d תGNKql{]qDb_FX_G}\#8Q:N\l0J2EG*qeƒ]KVIWqV+j5.DʴDCX*8(c81va"Wť:O4V4v4]XДU0;4O_ـ *1]Zoʯ_ڧX|>]kյe!a[^5i;|Z+i' pl(}<ڢQГap9>x}8saCaw_4/ @ J[}-ޒuP^?IUZqiϢ=XE%(F _ue@;& Pȇ"IX(| dz48Y:OLcCReY=NޔBVg{RH?uᒅ5>wpOvy-XZDjm4S?ieD6!3 39T=ut}CKhAu[ Yfesx%z <2r`B*?Ԭ4ow 8.o?~:)״6l6Fݩ@c5A 0XzIJԠ/0"\@*gy.d*lRɨ]R;rTԀGii %(C+\DIO-(dvgxZU {x<=l1@;(,XEu"vpEb l|t3&jwgt[ S|0"sC[,Kd{E1lɮ(Q)RK{:K5A˘1ʼΠG=gzu?Ĩ%| aGE_E!釐oӵe8GO)]ZUH6“d Ø ګi⻕O]݇8` AmrAW^ 1?zO.'H *xd}|WI| _Z0%gH'x4_hi+p _ҏݨcUB@WjZ|_# cݪ>mDeϯ[ՠ!YM$IPÜi6J4Bd{ZXS,B4A:}cAzb xg8u2N UY]rA7]zWAM]tC-XANғ|@0H|6(F5:=oɞqvduQ ' / ^YfFCY*:uB!+0(y,S%Ul"fHlqvk,˼;ՒmiQ272rs.=^t6{8AL }覟"tNrvRhK<,1ܕ̄s„+Y2\SnkqpG_C9ݽCqAa` כ{[͝kX,L#cNSH/WvGZazY!d`vFW"m_(㙟Ѡ?% lƗ§&lhrm9Xh$*b0_@U7|$:8l;|n~nݺ aw+8/aK @fó.F d휜5[p|vi6)?[{{'rG98}ycjl6_;~l6+?<9<;6 -Lmk4';{;GPB;{beMdH[2CI2B:$.ayj`a20Z C>UF*G1BMհUMZb?o B?Cy vP@⇜^ ~9ir.nt)ZR;(R̢! P(X+unFiAtȯ &F$Fj1 w0 n-5Ȯ0izNO'x؎EaKлA A]};?rLV( LӁC7raurZeDke=j/,\1`>zt;[ON),3"_fM$3@0y-DqxFщ&0>Js1= V˅xB,LbZ(/L#$a=ԒJ)} |>2,]4T2)Y~W)'uE0ևO D*ձzZdRG(6aa&/Ա喭.9ӣ0$p> !؋NUwK(W]c< UJQgDS|[1^d^ JE2G'~>g[srLnf"!mF=R TSJMC%%.i]%9Z՝;]~w |i4 Y;\[߮դ  YA4u*2X,21H DyItN ZL"pDMzjdG  ڊ4 X^iFrEn(vCT8> rn۱dsmeА_Ho-mw%Z!K%&ʿiu}-µIOzɲ Z AIJοZY'IiyI6 ǑD.{lZYsUbm /cwzӆO˛6;#?MoNJz}D]>q N&Q1o`$zDT4a8BƐBѰQb{kmF4 %nNzk͗_F'-,(?}0jЊ%lʬa},t$ pA)Y2M*ԋݽ&*閣'le ^"SM u7HݳՁޅ-|y:wV@*2G.\\D0"aԗA܆i!$+ Dش tQ[|y e^&鄸&]N}KVƇWf#l{P扂䡯Q<^OޓjBkux}6>'}:Y+>"&c6)&w{k8xoPD(8rok';G(9=ƚ.İNy ଊc&&$x $*:˳xZMWE%&9 3Z|!e0({*'dZl] v8H K e N6DdEw ftKJ;y}[bEO}x2nIMEBql*eYs:R o8#MQpqE~> V]~xW@C8`i`#NzϤ\ݕ-t-C%Wm |A4mJ=Ȫ([7XH$_F: RYkU0 1ŷ1nhA;(Pc 8OHɫ/Weq#-L3|ϴ%:^A/jah˝Egt4)_1cjܶޙt4)_?K E(F*bz')_=v=l8!#E=df6f z\(/U+C;NӑItg$ RjA(/4)_\h,iuC;[4Y7-ěx]' Wl3K%&<*͓fq9pzI,fgNЉ ֩9gN]+Xeaf泛RaɝQ3wp*:;6Oc&l 6aSg}޹)x絳-k)=ԦmO0_aԃ'Ag5,0У|Dl>}!YOjP .B[HGߧi>?|6|2"E=yi} ո0;[If})A[M iӞ2cyvaNGsPg"$9T0d8~yyhu0 ):ㄏ W" FHK(h[?PY̏ą)XF,[;6`G9fL(O sjc.1,̽3+ibWl#44= D_昬 İWmtMnNTK0whp>_19 qs6ՍWU};<9V =y;gWkzd(q}h̑]&&IwD/[O֛RMRv~ Hh,l !K?d8"4F,V&z}#$ X#kIPCT^^rYIDnAWCkZb :j΢sb4!Dt98c{:E_rPlHQV-J$YyJKDTJχjՆz6Rxy/~RrMҢhv8̵u MeY}UE)#o7p^, RW u k0Yt:W4J]}3,uʢ|U|rQ^?v~\nfe7?l7rD"7?gSo ]b? ]9#ml%R,sI<{Dw8o+ߝ4`=QFSLQJr(CJγ7q`A\̽-;e*|(*q Cak}9YacW-tr5{yb*-,s fdܽ ًoܝ0Gnmfc . J7'4c\C%#H$x@[$҄OjI(;cYb)ƋXՑivu1ڽ~Z~תR rpQ2QNrinel}GAZCԞ9|'>o(?zykb?p(]|og)k^ntbe 8Hȣ=!yFԒ7o4 ᑸ_wꇚ FEؓЭ_L}^vŀA" ̭uXmc}x ܂w}z%r;v{' GTe)^ߩi#{z*Tѵ±|Zv_,m,ݨ\nEqC{&Ƶ hQ Y0҃sZT`tzfL[Ycm5]=&u*'(ߗ_)jEb5N;> +p tьS3l+cB^M㹢MlpW2RzE (_Zh5ӊm-rᛝDF"{%sGS թ mkmD *("֞ꉔŷagGGބ&W-?P2VX蹆_׹h$thl}:Vs|%o&h}4l"g:G" OSuRP6"SUeSRwR`:_ujxeĖX] io% h(RiC{1}4dDAs#˧Ia׉|Ë'-0:'ul1`3dhv> t.K|ocY#@-ht~pA"34d=qT. HJP(WϑCDѐ4IFmL@Z^PRw'm˓|Y:Kى^.~T@_GEx};|"Rknvuv]=˵;;)kX'x7i%Bi50wyV['1VNzkT%˼)?V# _$ED$I5Lݒ[Rxh[O&ƓC,)Q|f"갢BLDSAw//~V.~g\*Q 唚fDH&liLI2e,d8P&2RIsj#@eh<;߈ yJ$:f{:,070ٵoXGoCkxYƍg0oyÊf-1͖ ,d!%ɓY ۠N_GV%Ձ)X@sZ.:̛xXL9O r[ʲJ>cV8iв+ ey1ڲ2g- C!O1d[, [4*СR\F;=RYduv@2` A(}MNL`E2RsiВHr}Ј FrF =2`U,%b昡!.[B/->7$Wc:Ļ-lXuHi90HBb8Ҍ<f2G"_(t=l7I.uwm_-Ӿ瓌*+V3A]rFҀ1ϠlI$ 1 _ eaM,d`8Z i+Zn{Ϻa-wҍ$=:E+`Ռr}.QbA^𞅾:;r<$\49e #D.(d/fqY MŔ`u R!3y6hs< 4kV. 45jWR8k5RzV֮[h9 9C`h,M>4# 614,OēJ2VGs_oLV/ATRPQ\ `uAzV{yp|RFMn~w+-3UhHԇ U"#vgrl KlDg;k⯘Y|+/Kv%ڙz %N8F2x4dgvkRw*ɲ Lބ3\z(ABf&f$"Y%= 6+CH.9_ lM\Œ%ް;L#.&r1.1a5cG#TZZ 4~PekWK4uHA$Mh$L :L&$} Ϋ&8bQ#)̔Jwuwwuvwپގpwd(gɑGwA.e77Оg>2Gcyu&"teY|\GBP@\`h=+q]m˹.#Xe9i;rv]u!=h9LMA1chҮtղ\Qzt^t`:913> 4ken(2 + Xl#hfiPl>4 6W ok;~*zt񀡙QɄ<-aLpr[RJ@W(B9Ǵ@ m|>ej= SSG $ bEI+45؃74H  x;GHbT<&|@ggѯ浴ͤll z"#T4f8ȱ!Wt#\x!qe *(  lUg~ m5H6V;Nsuu sR&'8vir?E:aFx-٥97k4yƯ djSQvPi|o}# n8Uڳf#Vo$^,+ ^ۮĮ,?jvK%blߡ]JnLpK=mWi=v#X&ɰtn _H;yh_+ΰ(*ݽG y0Yk_/>tjwݽ@վm_4”j>Ke̷h:g_xK}GۮꐠGDl*_dPC$ ؊gQ7Q"I{:$D R?'A ?ّƓ)9:aR("z@qo0L1*+(T*kF?SǗ$ИcƳJS;FabM($\ uG#ލ\UMKNU2 jW5@|4VhJPtЁ8t:a,JyImWH۫AO/mB0mGd'3;NEtnh N3i=-Z'$#t2S,(*8(j}GLJ׶F dvQC55D+K\**lƬ0?2{'̬ڋWn] Ai .`i̙DݣFk OPbjKʛy\'éL|42CQz>YcѭOx|'a_VWf$شCd%e)P#UkrWY*ndnOj=#6k?Sԁp,>wXz 4X"`9Ak9@G0@\6Ój|3C.Ka%mO1To~.bR0Z$Ƽ1'is ء3DP1֥4ּ.%yzH;7ذD|0F4_27=ft`Q !*rs.k+ ~&Bu[)ȩSzU<_}xy]ˤdʢAZl-`[5HnAg_KOL]lfQԊceTkKP˶|5:-<{p7'j7$ 8j728pǀOBg~J2>-Z";n[^>mg=}9yjKX9@x~[Kr!֟82;kQO<(%|n"Go[l9I/~߭]q.ms󵿹qz}E{,j޲ ~{3o)bXK0߸q=/u~_Ǒ[b1r@h'37y6H[s: x0Q^{ۍڌ=-\M+ZBŇ覞)rcs2+ gDP0557VjELkglR ZV& lׇCJF;uE8'8q"ޜ'ObfHQ \DY8)le6YYJkD\fuQh29F|!XjsHZSKCY#XJ)a`8h='#)yꫦ`w @-{ݨt{2HU/ s{t]v}<#*e{f|5:1̋|"ڒ8n[\=3_8hFĎ sx=: `H|,{1'e| ,+I 1HOb<&k  qCJ(0Of ŭZ1jĀ2zs| -؆:z1*;tXF:]$ ! '^I.HB\1 Μ֯o{='ϒ򡶌|@nGx\z)謁avOM{mD0~"1%I%2J ѶGuj:4po@jdžl(~Zd%JwȲs @{e/%8A%%Q#h*V`bUe{jXfTƷ G\śFSe8+"lXN2(ciivX:̘GG953Q(Ya+|Lhu 'io)48U}l]ye{MZ+wnjMռC hl"V!O Kt0٬7] UJsZ1Lڑ$YqۧA*5l4[RctlEjzlG0]bl'#s\'F+jK2b8=+ P}GNae~Ԑf|@.7AMm!/^$E]Eb@"Pb@t]/@nu@]$#_g }6-p#7H{qN֊11=o8oOπdҙB+Pn+b$Ҟl.q>WR9uAV:MQOe \]~*ׅ@ KI FR5; lJ]BE +a~H"6~ׯIKv7"Z+r!<rťXff- ah KᷳkSݵηҞ2{V)5ʴ?\T&9 W@O2m}+G_$,~d >ϿLM~-N*L>"G|nX1~vC[c`%glu0quƙlm!gB?%vx4v\{gX=yv>D,D[AkS2;jo'QW֣E}>P߃X}ҍKvXض2hO^M#Ilـ*|oB xPd?.jmރ H!ND04&(Zt08g|~{f3/42fO?™%vUfsХ=jkmtg^HED=u\YbkF[KÑhܜOgK[\ZW4 CnK%3d⬝~Q赈M-%7&6ul9q\RvUjmKCp}&s`_OSFrx_Gd!ɨXbRofȆQcb擪07 FѠا:ƅgI*e_! b, XUtjvA|| [լۇ YHrHPP:Ik>fŁZ/k NQTUq_QQn `nhҶ}fi4#G j2qZ4{ Ŵ?SU]Zڠ}3|OT{_;D@{xwa3K|nBC[vwY8b ~h3%=/TZ@0ؽPtKܭ W8=}uo( J.q -w+g t qx^o:dlןD_y]5Ao,v'v MŴ׿@,{oЏpp LnkOnBֺj~jvh?^yv\Px]ͦOClP†{Ix^o2[\cvө3te> b`2M' I>̨`DtWt&@nZAR8QE}qri`q]5zB~kt;gd_Dv ,iUT<&kmoa%Cٿ[Qmgs_5h:rgqk3lxmmU%Ok:L( ,@+oKox1`W~TVj_]zYi0ve!oW{}71J:dO.f ;1¿\^W1zi]цL@\x7C':ήV?XlB<*{Z%3`8%s`3MT_JVnlzlvӋ~y6h6~,ngfInۈy5>ynCz# ~~@?Ju/ g}EfgjMN\1b_zf a߾4?_,[M;5pTxqnvGuk(o͑G/p6vBNr \WL1|iE]Ydg2rj6OfKr|;ݳɊ-!*t޹d]\ %sdWG+D 7:O" ly:he.F_EUj"h;ȆSۢPżϗȸ{Ɩ_#RJeOTAHbu jvt.#M2YXM̷W5^Nvr?}D_Q9$V-cA]?!&k}3-i"W"!kuy=+D߭' z⪰_v}LvW>gdt16(1\=*Zɡ迩% BMh•"q.rk pgMֿz~M.Pu«spQ= p+}Hv!z\ =HV&+En%~M6n ip2#HaRW~\Y!zS9Mg(?-} H}AAI}/lL>,~a#ӱY[F.[6j;߶^q+qo\l\we .P}C Y}avwp Y0pQ^j'Iz-GqnBj-uZ fr OQI&&ڬR{Kf ##ͥٮOrd~=֡_$'$ h?:MDEV9+r#(d0?ԿrY^eא!Io $'W&|dCE7%#zN!'h5P~w&K%~aR0DO`XG@; c)$ d]?m{`q182d٦ThO0WnH l 9Q߉d[|T\ lJpF1T>[V:/*=%QwGiͳQO42zUYiMdlՍ,`_7Oΐh|z2<xғ!#< r0W%?z3)];LNmO:3 h[_yK[y[{zc7Y;|aҍ UH>q|)мi۶_ENo%7AqOd߽(|Hbŷ"skTtK_^R1FX?.Ǧ.f[l.d Pȡy/ٺ\_Rfb_LV;PQ%Kua77%kU%üoMg0pF&m2d rDPz'y)K">#JЁ6L~ݤ`C{aZVn(Ӑ ,O\j߼\Q1ǟR?s ٘/Gj6}W%~\Y3R}`l SLTg??@t{fZ;?@"fc"IO.V$ig$1Ⱥ}Jdd L13R;t#J5#{bY]dnY!L5 Ipj iLwJsTh 'Na'^y,*[pyEEw1N;ky*E_㟒&#J%uџhK.ٚآ>r4 %||tIaմ Bl\mI pA?Y@1|]طV[<@Jom.}dr =z{}At>H_We*>PEOQ , V\shl|nP$*//[*fFS%=ބ&?s*'ȚE,V!ttq̸m7΢󋚵_lϭxirlֲluF++sTԾΡU4Y_t 5GZZi(T\plK32W)&dsv}{*yr{V &hUqfje_[3VF@!..Q+Qo-K; _jk]JotQO+ [k, مVs=`+l7:5z":޳>^!Tv$tLho0dʝX>c[=AkJ*-曗Z;oYNWSn1Ku˩:żsYC MJkF e͓I S&rno]}yttg^ZQX\,MGFJ>Ls1볱k᫐-%աZ9?D?]{v(@˄+mt @C^sܿܓmnӫ$%9%Wmt ,.!Fe9CqP\A LgfUJ1,a3K]Jaw~5ݠ_<:w5J,Zy=BxH(~T%GgGRjZhanXǗV=NߏaM8N+ kV Z6\Ckf荾uHL '.]aՊ{KmYy?]2 w~V4/'VXUM̽ʎ"H acCmS 2eDe\Ttt }BuxQ*5]7LΖ(P8(z%j6N\`|+Ef`x90Td$o^ΙQRH0wKB^qܚ7Uz2&`AC}GںD3 I_ӌIKY5OMvXLrFd shJ1|clv$7Gl#hYkϜ7>l/nD Xb ^ $ 4ÎBFF?9 #?_ļƁ%+ijښ<fuC_]37_T3 _-(>(_XD#IҌp jK˭YvdE|+>9}CfT5PY_KEs#JXrI5렔X#^ghl^I!NX&2H\on6}q~KI4 )OTΤ#*lD\kd RLڊM5ʌ5uK0bC;|ͩBkUR_H=W',5$jQi ^i% /,(C5Z ܛd@g~ݟomň ⬦צfkPjQ80[p#^xLNvlV+li,]zPTH+j|063FmXm2<5T;CטǀsZ3r8,b2^_{/*R*̶J3<̇m2,b9~u xy/e=Q\!t0 T65邿 h8/NˍV?i}dɔa1N#`a=7h{H>K<ë3<`J6hwPkx7(1"BS" ?gA>wf]U y4q[ԃ1tY/=c/IGtk9>qhOwoj;Rg/z$I ށԸ0ch<hHUG}ww12T2 !A7?lB9OafߛKZ2帥Y'0peT`bv״XO=KqĨ J‹GR1֠gdl$UFWQQt&f)ٌYT۶WqG޻ qMܮߟ}:}'|sv s+ZK|{8FܻWMs CcV1;-!xQںNC7_2i{ANJ)c=>ɫM( qMp$SN$FS St #v<m|R_Ub*6(~ -#CB. `"dt'?)7H \tl!?H냔-Q; 6iw=ӡ︝^V|ZjCS"x\ч1@DĀ~y*{qݧ/9]*OS5[=t;;)kX'x7qaf50wyA mE@)?ZDdZ0|$A6[?ؓC,)QDPY_**95 4IPݡq[UdJ3.`D(`CG)5?,|biLY%Y)pb9}90kF#j0NHL" ϹB%޾݇\/,5udtx?o^gZߏ6||=ZSc -[,I|Y ۠N_GV%Ձ)nSy&qREսIY^ac-<ے[' ȠOj%ew (,붋22g- C!O1d[Ctc"ohsbvrŨ 2ɎDpqG W3dͦ(3]"+S:b #@^>$8b&Mm 6(ލg\[݅\6Ŗ5ׂ^`wAKAb~L$͚dTwd-QYGYdaB"}oj~zm| tY6F#Lk8P0g%RV݆P_s CHBta7< g@HL G7D^`)Htb7 d1xH.)##S,2= o(,j^FI3L)7Fe|5\$'.FM8+d$~I'kvP\ŭ MeҤ|޳-!tٮ}K}_!"LW^ E*2Gn^a'Eql|y,Yez + #C.6t+F$ JIPx7<4ꇾL,bFc\=J!Wg@$MM2Dw魏Rה_9іYd%L}=}\Ro v{1(:s([p܎ɇ.u߆9b[nw|@3"WK1b s!1c\5ozgF,)ݨPkۆJKw?A]+١f%4$ *: z(Q}~1ކ>}Z"+cJ PS`}(`JƓz3(.,x t~(3hx %C٨N%)>2&hӋS{ n z|/:`R 27.WG4@$zW0c劑w> CLȍC? C9JP2}`#GB4qvݛYpvjڡq{DJeXwۋ@]WdSvK4]B(y8̍Xa%cѭݯ'.. R/V}W9p\ߦE[5m3W!3`MZ48 /}YWB˗|vh2# 4,k}'d?h0ɠ_JKCp'R t5!eџO@[z&]!ԒLp:_L`ِPC3yROs maE.$?) 0^iKQ|i)6٬7 "5}kD30c~S4C4Nl#!e$F` %Y(cG31dKH)IESq:z)eM> UO'y\,A.OğgMSᕹj:aj#KF/ #KOw(;\3mߤٕ&hxihnljPϟ49`»,[ 1AǿfɲQF y#`6mj/tG',XIbYI2"l"z^J)E$M,~?PE v0-0gEޑ'b(C-8=LWrWDHn(Y| B#0t83!ğwh,5~n *a&zw Ud="J `B]%ۿ=-eH|:#>>vm[QbqpA yo~MOі˝smvOʋPePN2GA(8 )!_Њ=M7MLc&FS)# ia#3Tƒ΢{okow:;_0mASsaLHx2C{IXiYAOKѻ_u3>Pzho]*UѕaU|D>]aY{ԗ8$vlL:^Ufe#IIH FɫMԳ<)xu[LcL  5ɷߘzJ ôߺ}1D6O1Ą̏UtO k1~M OhtVY.3pJenIx^ _;_d0:Cd/ ?x*G~Fz)Z3)NZ?{ [a~1_PyĮ""5*! tl*mlh6BN~Iג)cvF숁AyI|+ïLt+: J}& ЯYw^o`6i6OYnJ5_SϪBgs eqt<63'su%< u-9DZ; e^Z< ԣvqW~C^$vTZ"gy|i'- ]ܫŏ]2^V.]KZV2 pħ?].38/ x} x\Uw[ڜ>hIӦkt1IImmJڦI[*LfN.9gΙLI]>9g?^{^k}7ndS ([IDQ% Ǣniu(X"z}IFMD,$* 7ְ5x^Ƕ&uzSP kXk4(QnQ74v]]{i)kPg_R֞PjW ܒ,.OPL[|;ɰecUX2G5W%xV")($e2rT@s D FYl@hB@=4uK\M酌4VY+'^;+ۛnfj?F'9o#@K%[Np\-5ƩbYAa. 'G?q:ljda6ik)cik߻(Cr=틢Z? #P`&`XE%'~4 *w`a6Yc.kګfl3WOOGHPt%I zɝJ߀Mґ ?Ч`M9++,KGB>FAl/*wۻ-T_Y8? %(H- J5$ !$@Ԁ2͉q1Klנ}tŎ殦6_1#wi׶}MZ,z y &+63Ö\ ҉ ābOl*(1Vk_:u`6KX2 |hjɯvϿt]>i?j7N+_}f~Imj-d1*ʑt8|2F=}g.vDwx]$`0#JeK‘tBSț-) m,,bŋdt0_;rP2W " yʼҙg8 g8-eK朽CzN{B9zOF::f\i J4ɍ\ֺeqJlX@}sNiBz 8j'_[vD: i +Pw^,G.YVwfI'˪ĭy1s1d)ĵwP(8d1%@rBB9QmeI1!0곗TBaB4uZd&5hM/y+TeY7M9 '< "Azꑹ}s2X9 ƨUN0Q}X'BݻnYdR*Bbe.e0G5V(.pY 3eTF91BK[2f夹!7_Q~nR֢B J+thd-)VYR0^hS4L,BJlհd %=xdGàR2ҩD >.}0^5i:i|.ovV?d u  r-+q MGKQPxXrns-LHE9]aMLu4eahX*^Ts h ԟ./sSt##KVc,<й` F` !נˬ-.)'2Lƀӣt8pVWW3 c^VJx}t*E{7E^иD!!)IE=f{#MPŮ9< b!er11Y,l8 1hl0ZI-Mvq<Bds[k][ww4ض{ >I7h|m.l۹ɕt4K}MdѭrS\Еc,斬*]g'$9=}Jh󸽆x.$۴wtmw"H=Wc { T,Pt|tkNe,@8_-n2҂聉ɇ@F9 LuбNF!V`PcEauasx31)a CW( A u1`*8V8A&QkDD1Y@턝!_o]{GxS^9Z"]HxΗ!2S=@h2$Yzx 2׶($HU;/ҁ c CJo8 `H8!@hAJD >H Yv*| e >k_"6€AGPH]HpLR H:J=yh | #'3<cF7Bw}GӠg5D5m#8pa\ w=$tJBYTpxJ!Ynv98kK 0; }nZP 'YL#z"]Nෝ9 d!H$HiaR =D |A )@\0*gP~avd,ıWtÇUJg#gGV&(Zvۘ1HlKGvP8bm[A E;RSsu$0i2kZ{'2T[!`3Xw,& 1(| +J&De&]O!`"~f؍5,J^n1X:SStUslLjf:tϲָcl1L8a>ʎz8þwGNn>m:JA4YlCca`TGdԛ2%f O։!k3QZ6b~&vϛe 5|*d^`C6t,/.ʾ=X6o8ƒn/cAmSJ1a!3-WjR;D=^!cOVh+ݜΡcM s1Ҽ}wW:yʅZ‡k+赦l6!>hYJg+ߧWt縲AP:v8 -Q0]us䁡sF6|frA&UNWRU YmV&,V9vH"ΑOT_LHpM ^/ѧ>O;ȵwӺ8ڛ/mҵcWSfs:vs[oΖڼ{3zs6)P oֺyR. utHm][ۚuG()g"jfi.0 I7`$>`$w9InE?zn#?^%IJB=AJ$K/Od*[ͬDlUW 5 " jho+zZގǹ]@Q[<|RgޮMH\ˁJ ]TWs3B-m:9@$HJk!YǠم?ҖȘ(]pēoB0Oj ho'ǂDn+"|@Qd?̎!ߏ%qs@TMb)eH ${IG}<&goxH2]E ԊR+fgpJѴw7:N$OgfD]?4-/1Ր M=řW-?zm-)0G?Z;in>x$uueoNvH绣DjffuUԡZfrݪڠ~Tة-eX-}&mW? ϽEu]Azy!9tȷWRKY^ӕFHԠ~\yf id%",r3EtBf K@0b[vo8l^e(m0WFZ6M%pC(r4Lhx0pl9p+81jV:ߵSO2ưkH\usEVYnt `<^X7 Иur+f?D9gK3 k3VAMz)!%5%)a{KӖ uWs۾--=9&aHҭN5/|T|9HDO܌؊f_? ѾL @ {/ +r,;]1!w(9Vhs K ja@Q/s~ni#m,V ZJ7-0Y'|f2X G©ctZ ;{ä-Vxաk`-.ظRZfzGIwi<YY6~mw-:@=G/=dVw9 /mC?e%#d/!;TƧQj<ղq7dP+hKӵZt X^0Ӌ%rwIdS X'+xX]Աu6(=ϐRR+iE(HZ)w>1ȁIմzs@ARi\fR|m a󄖟RmԒ{z[^`-X>yWL'_wFƥv g%c$~sNsMtk>?j[޶8,S\H+4xVmϵYvY' PBT*K - ~D_` X]120K)k\'RM992^0d^ l̃g# L`3WxJYb:ANDأw"2;|v6m<f4[sAw2  KO|rzp: X簭{ߢmmēRј C+CV=cӅ.DD)+e_O߳ж#a,k.rG[)iG[q{'~H I]D_;_Sw,3g>qyW>^Zϓqlwv`PfZ)e_4#"YSMƟ;whnq%'w}TqK'Us{|ӥ{I Fc+ӴX.[K| j9k6ƌP΂se)8A}ǁ΅i1P,0ug #ԡ:u/e$zR`,kwKVzAf4?WhS~h >(rR;әe,%hPjx hO qKE7**]>qzj7/US2c+ckRQ]9[HE\ `E - }bnR|aUI~6R; ){^lL@=,TG.-;)>_}g/p.:If6_}wEsтf8!V{gGF=]?J꟞G]Ƚ? 2 ْ3mALF5XT~qPؼ#pf;A-|sa2k┼ Zo~8zBᘻyLzkk[ н-@ɃQ2\`$T[9⦕O=wsm._~`< 01񮛝V_%fn]Nə|]/ 4$ah0xo-lq.خdIupz2vVBū.idwu@`1mf("k 5T1v}Y3L~XD h3$r9Q 'dI8',. O[27*d|ja>iK e@La5.FEGV<1E`x܏' t &sGwڋM` 6<#*ǵV@Ot5\Nr:^/'zd{wds|>%671]E7KhPv_-KZ쿏!a(|byAk?^OA= -=xutiN'iK?&v!d; 4w6^ CqyA.}路p7𦯇=OĦ~$Ѧ)vY%7xj:'LH8ק$7L Y+ElC5gčM,2'{шܙdԕ uYnE_b[_r5kim":jx~ !!M;=ęit4}jr% HIlZfu~?~0 |~)z$ #[_#'fž#$`:N\G-H/NA^7/ClQc>gNLvaPf c-]\QdNo\ lA; 5->= ݄ړO-1 ﰕ¡c$r ?'M"ף9}#YoGR)¬7{mݤr</״҉-<\?*!rY=)m0d~Od(je87ڙ\`/߲nݞ}?X,'3Y`;+%{-x%rӂܿY(r|ZI~mt-?~m ,+~7}@?* RZUL v$:#%E-|NIt+2w mZ2Z LK z&t)ToSh&k_D ΖhW\D 5R4(kRh77*Ltt_4yn]jůZ6ZDrQ$}61/k'l l^6`Dk XғEVnA?k |r]bE3h;|@j݂t,VIwX8@E+mEi^MeM,3zNWuZv.[ \ ;PBK}J*keV*<̣_ͣ|R}~mBqPvxt9Ckm9]ywP(4~7L`\ *}[cC[C~pgxrs!; |w HtzqZ=AǗKoXWlwA4PgĜf': #<^(q;6JWҼuﻺަ6(tGNϟؙ3?fJunziN졎9x+m+No5׏>•9eImeҿ7^ n[7 §/_LZ2y/tɑ- _NYs: QxU$7pAV \ -ycnZ1RT{r I -ߨsCUG̘(~]M8V= wwY.^.7cR ϒ̠wya2L^#@%q&ǘܩmZ~ 0hYYgv>FAl/*wۻҍ'%,ljm$5LH- 7cfG"D * 5O/eb^O;ښL53xښvm״Œ+ ~nIoRb3+ ?*tt`}voں}<\85G9Aˁܬ8EB]p P2P?,0(|  KO *B~ԨD?F˵7@չmqIG;4Vd:, 9͗sj\np4DFdD f)N"(tٻzi'JFdȫ1 #-PtFx-mgKY1[^3v٢˂n qA0Q*S@h@Ud~L7XJX $;,R䲠IXIYŨwC/c,f t$ ?̛u'%W,̶uԶrGMBraϑ6rAȌG 0 qBG:*^ʿtTV\4C>(qR|l+Je!j\'~gDńTLAoH}fG,}t\> G1Zz6:8OV*: sJHm_O{e/]据U>&@'ܛjd9>Gp8Kb!z$oƧbb)Q먥DltL8 e0jE!}^ʖ%x|QL ,W0N~IhK1 'AмaoK$C̾:vpwݻ΃PPkkXV0}txMBє>rmЫE|x-;ۚ_Jvߡ엨k{>@.~dq0bZ՗i][q$eCtY^zZ{22hR<=1̇8T X!~xl01x4?Sħ+ǸqDbk7c"ZڬQ5ŧ/}J5XdC'3 թ=mMb}QnW ,NM:u@ȉm[PR>u|T{=ӂ8t)Nxs2kAW]İrܮN=JrJe@${Qiݤ5>Jg1~ ,{6-/c#V-M6ꆣ1n >mz$Lf?bZU hU:|:]1\ O* w@tR'n}>ј0N̠[1.s 6!Aa`h{U16 GS5,CHƃpr@L꽠{;v.&)%ow cYBAGp`-Zw%"rBdqlpײ\hcϱՓ=f\ lm: l SPG6Ȏ@ܓL$n(-äl~]EZpcnaY,֯ψQER$ejZgT;*0?D k3 20凪=:R$3lIv:?<< 5D#?]~/]BAy OzG(daQG4֐R^KrոՏ{fLޒgB` gTEB*!\}gBœPeÆ\g;}rV)0dEE|]yX9suv:I@1UTE0($0YaQ"!:ֳ1sKH |()0q_;C?lF)9;"xVZ|,,TVB_K-e)hkӞuymC,!Bxʱ_{ݟ?}qڍ7ŧNd]\W^%N`Wwc#oNYh 0Ň)Zs˜t3ĸ b*Y[ X*vkj^vj}(x3y76Ƽ 4v)T(|\w@f'O(WiwA7$}d9,+U*ke_Ō̯QBm< 1VAO0NR|qvg\ &ۡ/WÑ<]Ij1@ CMИv%8T|4'F{J2=VaCj3,+nRtIɰS5qÞipR^W.i |NI~^h)?^/^~*(n7$r3dvw4[GO)?K R@}g_;ר\1)集cDcX]QŻpOK¡kZ<]L2 YIÑQ&rGL\UJ.kri:}pkmGs?S?? mҟGuld>ZpLw:-N|>'|dz 9ұ/`Tt+-m֟ݓ2eٍg5hP9 ?.!8X蹒[LWFK8 }Fƣл&.,xOq=YM&KHQbZcY,k3(vCÃn)ڃQAv^ڢCЩCQ̚vx[šsf&磱͐H¦ș <( |ޖ|W\ ,`v^蒡nsL^a-s4{uDKVVH֎j[ՐG›_s+5V $X' Ip`5e^WLzgw/0Ğ4a "`~(;~Xh81XQ$ TVt1# ԰ĭ:ޓnz`p8GM9 ncǶ6x c|X#? of>BX/ a VxMج:+f`?sMS%/ʪ* llRj$T TȨ|ZŔ~aSNOë5Bʐ6om86 s s-p >4]KOZ@fYɡ" I5xkׄF =.e.e6uLZ7WZ3VLֳgoSRft 3VL7dߜSVdivyہ@Z)a$}xW PSWs ("OT+"`!bIpjէnWTfǢc]uz-jmGvNmUj:u{v3ݻ쿊+֛Sj3-0TVU\&IӬQD("8VQ!D!Txo'05R;7YyEEJ!&$W.#Ix]l:5vf7l*N~:RxVA2_7C,Y^$%79J¿q0BU0.Oɨh5YY%cn$ {{{e ,{0A|`) Z %hm%3mfm@` wW,Pr*owU%W?+a~_37vգh[0lLBkoίs1\VHa띯9v)Ul2[,CW\6EEq5m& %'{V UDsC]~ g~ZzHu lUJ&gj4qJ~RjU8MLD~ߔ/@'=R|hsYY:Yf;zH}z;OTNF+9;|x LG`Q% y0p,?[!YgwlXH%3[P)LcE l(9c1"nͷn_Mp"n {C#n~ͯ;~cɭ 9Ep7YjSL)DjXP8RdJ.цEץƃSe4X^NT.05#0,K\2"@C*%]!$ B`/m.h*F|W2,LsŰCDze|.}.w$awWC΃/$2kyeEn{q3 7[U'B0h !"MNE!WHcc(ϔQs vXD54hs;`G:`8!P1V䩆5]Iɐ~C8[% d_Om0h%nbŬ/+{9,gn/?:Oa4\ru *ҜwV.[rԞ,0LVqܐ@aT;{3GAΨ3~< tOO1?|*Yq IWJ|]ᰇlGf84yEELY؛O/<4ݜt Ew݅un$C8RBGߋ{3%XK%h2Wθ2|ٵ<Ѯ/,ʖEUo,u~akf)3o̕hP0rC1qgsfc.V3԰nerUG+p+T65&3#POn`h%N4UZMWd[u-M$8 ShI7YP[W5ሧ;I_''0+%CTxElKꕭ@DJ7\FF@L}7O vu-JH5}Q$e?7(u'N9¦?nӋ UBng3Kο2 #<e}2XsxcrkL|!&Ib"[M+~^/K_T☑9rR Y{Ufcj)t_6{ ځe@g'-_#ޫIpIXƮ}a[Ds UChօ\B܀G(B7`hF&HلHݛO>ڌl~݌6Sj!J`.· G3mJ[Ď"p݉ UN]ت%fuXUkP'f$h"m6ELTb+窳\!K*:m;߁]8?LJºQI~nrՑDKw%ýFb`w{]=%@orfߙQGc\:1MQKyIdEu--ՃW4hYx{k' Z1Ng4\`]f {A/n 5{z0)5Lr]Wc4gsحV1,~]Zv_V V(@Gx}Ske$mEqcCRf]6,IYժӂT\s.]LGՁ/ *'{(A/qM^J7;_~?o>wW7^1"ie4tZcs饏"}f(ʎqC7BwTRFU׽ lVqRz%w6r^%;pަ #O?ok܉nE-^;T>LML2jOzc-Z1 UZF5HԖV9Up/rj.-_y<{gGs{;>ݲֲ[ T$ k$=vWU5.k]Mz Rj<˧vw5ۊC98(M&~ VAi4L$T𵿠2ЃuOv\sMƉ~@vwO0Xm+W4]3fzRbd1+:˜䲄 ACS3TV uh(.}wG<4܍<9\>ϱ p,O( h' }p)Y8> `EPjtm'jzjHvr@JCZdjO\+M*? %8Lɇ$Lu(j*϶jE^ҋS dx=DI!"OC$!f&{0*Sl/N< UK#;UfNZӜ5+͏jө) c|Arc(YGo#x[ pǙsx dբ>"z H,j 3zVpMr&nCq6Llbcn ǝB'`8\w.gsW]gW ɎsWT%i|wמ7|/Q@VQ}ۚ5Φ;֡u-׹5cEVuҐ.[uMͭΪ準d TQ5O+.up\7 %kOHBuޖU>5m\M]VN%ȴyQMuwJ"kRu9?%_l͵\G^^ib8nS-~I%O9'M,@Rď䨎zXbutXӑnGڭ#vE5D4UٯcB؁DOtPX7Œאlԃbe?FnZ׏uA&þ.vJ!Iw >QG+}r$`[U-uBBdH OQo% Jȑ܌VBle!By^cM 8a *0ryǾ]Hy[y`;-vagD Ox쉋[ߖb 98±>WMfY)gSDړxO|6`@4v[3 JK(Ji| KNqTbc>JL 7+Kk`7v_Tָ-Xk:R%?W7 7(EB*v%=V_Ɍj6MኜmMNnYW,zf ތ1sgw[Kz_>ؕjzCY[heR&Y@dksѥpc5iWXx`IE>fqh0`~ՠ `Fb1Y%X'3svx).zň"^@æ=2qu\QPdnLj}AfNv1NRvy.*"(vnĐ&921ag)Jci.$2b; |>VWQDկUtUbG"ˣ"bT_u68$8#r/bWجa3.#! 40bi1wAJ΀tlc"ų0k4tI4gKb,{E*qZ%xjc;(S 00n.aq bdnP5~$X0@1ai㉭IC ~=麒9L4melYNUSb7˵%,KēB""4͋O1q B0|܈}HX<-OX@I`M+, Vx(%?\B@ [YD_+V4rȗ> (9Z7w| Fotl!$ӕ 5ghb)B68=vf h6cOI蛐3iG3~v&G Ї3.)Ц',cmfIU)9U^n> ҍT3@׃);mQ.4Nv!?Z úlp?nS.b*^=mg~qXlڊVQWlʢo/aK 2:Qihh- o"U Aav?YD"aK36]&;ݶ5y;;<1fdR.3yߴl4c qO.7ޡ&zri<|8u H*o6NT2s;X6 W`- `=`ͤ{ȝHA Lv`5H0r7q̤>u} i'x$sXb*c_?]#}gҩpȧ(^wno\^v%@HbGȣ{vz</ޔRp sb|ol-&۟펍~ilenY),p]}ׇϒqI6??”U%gwiؗ<(ܣ?3 | ȩ?B|z4ԋ wUNƥ7yE ]p${a}qc_Ǒ_Al' R䎿f@wU5[|2AvL5~v\g׹\^^yz2a1@4O|AQE%% ,.N+$AE a49ƑtxLY\:0 yb k<8 m'Qq!g,],fOj2ײB3xA ܲ#26Wv𸧑Ӂ%$u܈7w =GuXg4ʀvp0%0Vfl _ {1u e.h$~s|z_u,hQǽM%E[osP5`b,i0j"䋆I4̂7}:V]:ܧ":m{{p,DZBjIwF/1]omRv:x]U%Ѣ^i?kvklXOJ,&ҸA*)2}T(Eȸ(!Q*]4?%`#jf!fZ@-&kfyz/[cdvuu-nBgd)ٰ{dո";r;ʘ}dM2>~+/+ .D'_s8_`K].Qmh8RIZ$#5359#B*(ip ?O?wEt)PKJLJJ-JQ(QHJUH-̩Od($+dd+g)KK JRSR2E@sSR)委&L)N-bxWZ&x}y|\ő[Ʒ-zk$yؒǖ,G%ccFO'yhf+:/g._Դ|LTr5=Bio7) fA.ƯEz5_I*/W٣wC]Tɷ}n"t-5^2x{JWѾe1_ 3kaX}83mEG"H+ʎ`,rɮX$V"QbH#(j,i:djzmUmC¥Uu54CSɴėG굃;f57ek#H$]HGɋ+ErЅ @G#PHe-7XH!e}A Dʙژh ҍ csw+*р/ @E@JmdL#2P6-\Vc6Uf:X>D``$j} F M۷B^4Kj;Y0!- 1pP%'JVi6,Nh$ Y8: }ZLYnZ!:^%lA?!-zmȤyVIMh8W1A^dA@"BNRxniN0J(U+lT1g<n7K"mt ҷecOTabNմ莜@2켵uƟ"-r!KQD>cf#M6`r0l[WǑNUW j( kiXjY/v؈KbqAvh:뙔`nCF\p~&Ùm@H60㒻¾u&CbEjhb ݹxO-]'Rt8lKĢ޾{D;.hjiGzwxue{zwldGܴs{^fmXUu.ڛ{&6KLjK3VEB25loFϛҬȆ΍=493AY::Xƭz "б}@'qٹu~z:{/d;v R6Aqk71~urbH: ^EL^  (@az@ ij~MOL\D;\p1Ԭmͤ|J d"],psXOVYn 1|/X0jTz8#ٜ6Li6ۓ[d2Hef{^Ȩc0rI,MFX@OΒK)qA:& h-1!huSE,GE1)ZRMjN-)%[dRtu 568ĪiHɿO~v 1ܥQsd43&\ہrѣh`!f wnaS{3t58-@L1Z]q[GTve@2eԭ"E{dB(Y_k]_0>}e+`&66j4puR;]z@RK3!AP;AiVHѰ-Uv@n+8&q>>L-uԬ/,eߨnN1r,)t7]]0.QQ~St牌C„ d[  ^pe[h{4$"c2|3MI7>Nuxʱ""?]1aQCcxzea+,H긑gC)nw$u`o#`P`A<9]6f z\! ` fђӖT%Ph:zf[YƐ$Mpב%Y}MMˍjŒkn<^͚P+J.TfȇkںFMoGoo;UG\/$r{nN<)G x6]5A;;ŎZckbkcbJ,gw'-.Hlz2=BN^x*&رՃ Bb/3۰ 7A遠?u!ѵ @㣥/&_7LcWE VyņrZY&u}E}\Ď<~Dx*Rcr#g~^}帥#Wjc?^x6x쟇eMTiϬ)w"vO1O8[T/Vk\jt׍2GOt=- Z1SFHi~y5G߰eE0,,ܧXF2! ~kٌu)A]MeD|ȦL73 u?g 6YJ0 XG N%M^G:giz~ Qzl64ۤ4i'EM>w %,$} 9PW3(QBoiA%Vn46@\ZN'()lT9xg*KB=#!(f3lڹ575ԔrvN) F( $,!y];::+A(wvxRvܢ!¼c(l% W졃I~=$0ACÙ?Tz[!=]MG3 \ ||b>Ǻ%BLI#ˏщ3,,ʨk'e)q]K5MF\:@(DC 3v*48^LZ" /ގ)k\Vb3& ucȋ\$),0Mػ8idK<;zǀ&f\&-HS_)k@l`y*ýf !3XgELrT,  ` &X;})%s{/X@݁$nx9Dd9f'` ,D.sM;o nޘ;n~ J_l&71v, *ܶTǃ+IS(8L߹ 8d cejlb3ǩ57.ɮyfI#Wn$ m&{\&6ς^)/]>*{OvľVE;%Zia9T8߼jud}/&Cx{4+]&_Kl$a\im?ѥbr }1'dR\WfC/*Cjt\#s'OkK7"?\V~jU.n5Ou4ebW5@sm50>K3o>G|A\I&$~'P|2g?OWSn~/ LF9W:~X2//R:pq"qSCFvQe`,Ѕ$7wΥA^OI69H{f~I2g.kǗj7dN齻`VNLgsX#O%/6A@ni佤q{bQ󼹙.#,Kz!X />rh_Gv}trPW@DWIF4 gJ =k_dplM_!;9i_!U_%"|IR4aۗBe?oWKy_ôj/x;_#k?I9rr$)?4N2 'L>Y^F6:5e OSRͷWTOsi6^6;{wgDg绤4ivvߑ :/b2Ǟ% سiDW#cg9tM i ,&Q(96o|MP^5bE-~Dw`97}sQ]]AOҶd\OAq$p]aXkaͨ7Χy)_oZkz'CL#Eحi9FpN 8pG*,Ԝ"C2➆zob K|EVMvfi"7ƔBv@²1\h ].(߷_T%ZO4G5c-IP · 7JZeH D,]H":,yZEs hlYpȗ׺q|-6x#beu{XdуN`<=Hy:sBlfxh,i0tyi }쬗^FNe_y!S"3_9w#O~Y#g׽xa/T]fRc+sqX7Ɂ%9/nb2Cb3=Iq @oflkfhgo(d^`Z> |{}|уΛW>Ä $#*Ed7!`LcOwgGcwwZ4v zLFkewgز: R2 OJ$ƻǍWUtmRZʫoKx } '[ɼx+=6z$ŷщLTqEwN$ċ$ #^ q~`&- dSD2/7ܐg7}'*z֍{;K&))^( 2BaDžX*P!S5wp-7Cԝt_=/7VWG-v w҅s7wob< a66_~]2^[]4$]t9M'iB|Xo_O wJg|\~%ym@f'uVa{>C$? t; 7ͤ=tlW%*SѺ&Ḧ;7DjwC"..bচYcRT,vL7,n5{Y 7~L_jmHj|+~G&/CIk/Ӻ~s/O/^??bG/ >ϔxhIr )G |ՃTr_wcp۸ekg#tRˁ 3Eg28c8ː|,'ĕkUXMe=y [z$ik[PP1l!援@2=<D72$6Nt4ɴ!%23 j[jGHafM,&+=&D[P̍V^WWˉcr 6[ ՄBTr!J)x- 3\a ډc賫 -P2`u;A|D'b$htI1f Xncp.p 'Ӊy7469 x.2i !Bvtc 2വEc;NElǑ 8;:0QA~l*EoBZ^ց;:ˍ0pnfbLfN@t)`1EKnn+$9vlM7s~doFydSs3ۻ6vy<ˍA특;B!֔ CAl-͇露&+0 pqLMYVCD5 Lv5"er,g*4%}d@_;夡amv0F!̈f宗W[p7!҆'^UR8=mꛐ5McY2*#SEY0Xt7TZ2w>g6*J98;s 1+=1,/ޯq,t?G4rc^0S<6Dl+)mw ֮o8޳G Zgqt'q?/E,dZqRf>m1[%->N}bA'&x2v)k!:v_ҲZ9N-FD57EYޗi?  bce&sƛe6)P ir+h XWVe.|6ǯ湧ӹ~h3v8Mug]_@X(xD<,X*ZhpJktrX<:2y;N׺M4-ib-P4ZڗqRgl pd;!O~vrwY|g={[6^Ku'<~˓t}|묮'OЭ  Ւ4r -]\EQk[XƢMxmwcf"S`G}g[b @ UC>HmDZT&#/07<6=4-H(EKdS91 thHa/uآ)gtӇζhe =\KVod`}Bū w;QĵnH(AEx:xieq: zY'/VgАd 0- gE˜[oTʓz%І>3$tAʼUMPo:~q:,~[UއWf^IAH1#-8v:gNH g'22ى;n.؞SɌ¼'6P!6Z[;TX(fo{$׺- 0t7 RX}dxYH6YBlYh}g/Ӆge=xk 78ybRKzOQrs^^f"%"3j47 ȸ9i 59׉@'!ŧ+2n?̘ܾ]r^FM{wbk:s,3fw: %Vlٶ{0f*+bCf-;L9QXQ㿜oiow1q!I,pe|/\clB05oo(/(qq)pMQx錬۷12}aEsQNelprg4?IL:<۳0nO-dR.ƴe6&s[G2mŴ zmx-L4÷xXsH}2U)I]9孓lSa2Hh-F4cn8E_ӏuO{=[Dn(f#Da}VpVQ%.$ϓCFJ60Z_uGM<Ah L~?JA6cʥo밑SAִF : W\qPvqճN pi}h@j[NX)D s#΀fgܲ.LGc8't^U\]A9v寰)pJʴ“R{!^tBc|=I$,O|dzOIݽkaF1t[km{^0$vPi!L*6#]FOq܏mkx[-6>QM {OO|.H=Xq  | x3f$˹GýT:T,C@@bBјB.("*jmͯF`}Ek<*ܦ'&mqMC*|h ]-P^6cYtBǁݳq?Z9;߬^?tv"=RŢP-9!Š\C߽+o2GG.T[9XUޠnв psWVǶ4 AO##qQzht X2*,X KgIbj8y1:>$f܋'zQ۴aLb+$l.3:~8/&O0ٍ̯ZDpK7FҔ}R8Trchީ|).1tĎS"A_$xۮKc7A[WgxWG Լ#  e[RT a%jr9::h47tggxۮ^ub^ԢԢsLV|s* <*o3x[EaChH@h/x@v )ԬĤԢbTԒ7'pmfrt  s4)^xRkA&6mFJZu UO n%iM7?^̔vfҪ{2o{/^=zMЃiSBA{{oO]?PDC o 1}E xӀN}=mWtɘ'z/  wW(Wo{\󜦽pn`qaFJkZ5حHҥ V3B1ZXύ%NgSDƻㄓbM{Rřa1>d?AO%vjy8:stql.=9x8غz?J'l[mRvmo7/ 0;;vYo`.2#p@cƨ.8"#ޫ^x.BR΀wFd\A хgѰ#0!~,EC@?0Io"x[ ;OvDe$sK2}}=C<'1KO1ٓYjkfN1Gx_xW?G'W$%&a2 #gLx둻%/ 7^xa.FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS77vw /A8k,  zhpx {T*J2՛9?4$ 4 K )+xkC2Ơ_lf^4:^ xuPI 0  p1vr@ohF3nD4'ubr"hc8gm TP' Ϡo"]xжudFg1&luv~PJPN"mP7£21=[9) v3ԺX{eq/K`y]c(xVmo9\~]EJN#w$nEqBf׀[c^Z*ۭxfI|0NR,*SMw{~fR=t:^Ӕ 8禍1պ%m j^:$SaNV}ns7@?ł 2)ZŸ,`,hL.Rri>E/a'314EbP`HK62a˝Uf" ̚jA.p;[*"S,!L(RkB6aR\e`KFGS6kcW S l`; ~2&eZ#)2Mo:Aj|?ztꏢKf]9ۤ!5MavxGqן^B bD~`<&4 &8BJ,;'2Dd&Ƶ;=<yk1e[ Hw_/c!\KZ| l B&|R {/ êMDn?CD1&X0 &\ImyC,wz%j-lSz Z;;{&Je?!+Hė.f_oGiUV79M'b;mfRzhQGE,C)ڊ# %>\#9&Rh☎vI'|>8gbt⫯c(Oothz-"~_]79[J Zvݩ@㔊0?BXUhzqӊ֤Hi:Ct_4o_^Z+݆ /3^M׌k ^T}C/$xQiu!{)7g|Ý>(L f@c=Uc(aP2QkHb+)uAb:jBNF||cZПJ}W)<_9ԛc~Icrqrv=d A4y95$2&hɍpP!KCT#}t"o.}/?IcS~\eC9tzvfl0VHJs}p,\c}#LˉZU8Y=8bB~,ܢloZwM|M/bɶ귩[['10˟,H `{æp-ԤT\{]{sikzÐ(cT|3eh쬢g4uufBugkvfÃV8_9WMA{3Np3ay40a 3*:r|_\aEa D\$|\@͌շE(]d H*SM W A\q¢h)ݼZV hz"vW 5߸$"*N?9*R18 (y',͊;w>.q. m5kDW%!|M1׆y#z"c['ؼ.Qߩe+'5?yTk?{.nJ Ay`RcbU_gcLldF@VCB/Ը-|T[b]K/kWjkR3Xf4TqO+7O+/ ۭ{׻W3@$aQgi4}[xt\uh`/bU2ܫaEX;)(0a$'~ Ȝc= "޺eHwSu=')p5O;?J&t4X_cđe8,Vf,",1aws.&7٤%g gپu$Ǵ-Al$ΒOR'rCkms]\֓lJ0MYJ6VO6yXROl"x+xށفTrHvlIe`H\8NSQ)͜Kv?#%K+yύu#s}ue D]7I" 8߆Clg)Rdl#-Ua0J\`I-L-CE -Rѓ|ؽk]|(+\/!@ߙUY ט9.jܻ{7,1D7alJwe#$}vljUitUSwB"o+RVRx엽@|ۇ^$6 F v&ٍA8l뒵 hРlwڏw^|[n x`hل1\ 9x`>P=f,yb>jj\8B,)@)-/ X"TWU; vS-L$ j

q`{ۍ|iy ,Z:UNuxy6&zjx;e4Io8lebYE3?%)94(3*1%% ??'0G#8(/17UG!Gsr6 v%:pfܼ+"98UEmzjI|b^J|JjԆ Ԣ"Wm0hDрPsRnx;ethqBbNjEj ͌jpqrr*xYJIy J: E: J %JqLiUjUPP N-*K-s`<Ɂ B~QJjBRBqj!\^PR5]AI&NS!?3 %$5EG4/%5-3/5h1eMZT>B}Ll@3QPxYko8 "EPe!U.l&NALQl1YtH)i`$]xX"^[[[͵|[[[TĜsȦ2 f"*6C,HECv#߷0HN3SI1fRv-e]eaWBFbn9(8VêyaJ+&g$ Y; 5b"1M QMq>8fC2YH 3ty5`/V׺|9l[]b:bEU8o?As|(N;vN/{źޠs|uU{o0G(eȲL6u,q&=R8p1XM #&,tRi/gd㳿eTq֍HÛ7{> u*~s?U߼k!f³{9Al4u ^crQH$ͯ\fHFqqo3߾;oD1-mH׿{t=墁f$\n63~fDoFr>m] ~Llƚo-62 }dRt.:?dG24uw>ե(4;UJX$>O}3ĻNeTpt4bU 秄D"}H `Ry@6vTu qD2$5dɭIw60y@&H9h*mb[JyHU0`wlss eq"9ރ+BnllbAfA8"VD&|y0®5|r8mmAٻF FYY7(*AAI?<:koT\ Êy,-TϜϾFd0Tgɚ<:((43X0KflY) i5A5t&&_k 'lr(QS≭B hP rN۵BuZ*DđZJrhLk];ܑjU*^E<)q[@z٣ܡ^HxM]$f3V=W*uNI˪fU:_Vtp`i:*iwA5D>Ep,78_"qw{kbrK0*^M}f95_6U(CMPfq̓q"*#Cz2Nj^hgjSR0|X 7G)y,$akZڝvd/\ E'}4An@5 eSI[ޞ[|sƧӶ3m\?aԸiw2TN6@@d$n="ju#Nޚ1j)}P"RJ.7;{JŪ'J ] v zTC]=˅Y:}v>t $Tn2Ш?TG 5.ݵI;xZd φ혈0Nt㕮}NgOb<@.b4Ő/zA4@&c)j~jzi5굃A9۸=^-(v!j{s}*2E\ҮI̻{eKxAyvf/)ʯ^CuM+ :ܥw̡~Z]!m:Q{l$W"1'tW"B)],ˉ @ Qс1XՇ4+VxYP,%*fc Wˎ Gu "pRYa(PܕW^ ӧ,.{CHjs.1κ>1StLY}ʢOn_&x׵%pLlN?/hn x0a9#f ƻr%tl$x~n.u;x~9#f x7ww O Rdx~#f x7ww xWmoFl +X'j"HAQ96riG0~ )ZrK>T yggFݿpp@&cV6 e*z22:2X8UT0\aK`=376yfmJyǹҙ  t|?qsv|Jk[Q85wfVy&)WxZ6Y'DYJQ)A'}6l\SKSn}HΠu`wO5i'~7MP18&Xx(mm@~_t3#9[w2?d3hƺ`yz_ |[c_{xW},98eUIVt6tYn+t"Y<Cj\Opv`2Xohg%?7|!Eׅ/}!himy:ڎ:$U%|~~{sNr P[uk 3pM޶# "$zS2uH.msgW!M- UBw%=>n5M(irQ^G#l|㰜l@:pt`0Aǯ 4՘w1S]ŧMDەUQY5[:ydm޳d$G[pkMaoj%Hgz}X{QiU9hF0-<qcC.")7$×°G)Q[:Ě!Œi|nԬx([1JH?5a74s{47ǫ%'C +GhCK8챁R9\.6uefp%SrHV u۵FkPrlۅ0nE)k$:nyM)GȀ8《 l4NJmB/Y[aV%F4|3ȗ>W%b4y#ˍ#n`oru[~߰ޝʀtP x aB;TǐZTqUmAnZxhY/ x\moH, 28ss3-#ə ͉D*$匡SU&EIޝY]U]]ӧOӧOq4 }5IF4ÎNp%)== 4Ci u=ObGv>KI1Z}Ze4Is{0#jWየ&Ʀب$Ӈ4U6!{rw<vb Lai8QIVYr SZ=$35 cQit=˵rƣIʄ!nNU~UIE: |v=$" 3F1dcoP 0yįLoy$Y9tyx Vsj#k`W LanB̓tDMҺx{ʐ:枕Kp$p4@kV<_۳^> '4( %kY̾ѭF\z ^RW-Cjt% C #CזlbNy{k5.ANHƹC+F7c;_;^ 6dv+P5 ʊ9Y'1W@OlNuxD[:e hKTUȜ  7g^ug`Iq']u .3P(ItǵO^/8=''gw%kmu8FCa(ReyN0GIp>3'VcnjK5k&:F0/g#`aFCǰm*WK+S26 y5hbJxT0lQ f)6Dd ZIj*||.kFPUf>< z.:Bf<)l58=oEfk0̇wQ˹m5/ FB?<{:̒x4W{:NO~ `g h!m|_fCss1$cXoLv( cjEs)"f"!g}>=u kzS6*R8(N'Hge*bDvf.}Ke(I𓪇!WADKkyqm^rڒ S` (DiyЪ{?$1FK>73p^]㽺7kp]6JUr.nLnVɹS=lьOO:wh@c?<確Ѱ%5XR);- @scĘcdak{ա,K0{=a Wtq;#6pye:bx (ٳfRuFO_wքzw6[~}4QpQpSGG([u2uRә?и$({z'N+qnSXi[X~k/Jmwam)CY0Ͱ:@ibKsW؈'n]å<"m/K$LR~ *Q} tT Ύ^SnDN\V=tf a)4N'"d5+s D-2;_RVNSIR{KThI12:VXpvZ&k!_}ָ ^5e3moV&</m掄rm XWgi˳"vxݥxf(DA ۲kbdxHs#Dڻ4k[ =k+#:p]GDq.d~KS ˱[^;tDedٵA*Ւ7K\4[;L9?'j,-Hjni6@ٍ `I-Q#kRR wF&rd5 a4!AɋdPsLq-,z t J"wU5ykI)! %A ofб-32hQq2N< ۸߆PxjrpN cܙc?Nta]6F%97g@zO2W#3QװdxAVne:ԍ+#:3em?V\4gO^R`~a" uqN%g7 7><=" 综,Kp}DBbb3&ZN!T4GwV.6qɯm0!}g# }D(Ϣt6NX[a*jD)L}?~$KY̧-BJ JE54rM&>尧m.!7Ύ:m̡; -zы5UjX>)1aLo4]1l#Vƕ%C#F\@'5.%Af!=>(N.^Dwpm5H응!)7TFattbX{ڃC7=$HT1|`*9e.K,}&$gJBr8>27EZ -Oe;1.A,qlq!SA{ psZA<8Դ sEֶ&fl~ Z<4 %F788h4TYIzӬ1ИlweıYAԻKǁ38)rRt_if\Xh2,Mq̬ta0l=V1U{`aE $5eA'5kjBK[Z8WЌ}&i_\56cc,${W,nFks~P,ITY8,ȏ˒+3 sFSXLЏA87:JLGc{o0BDț0sp7 xH .c]C|Z$|^kiA2݃5X2=:+lE[oI`0Ȉ[ U*/y]>A.BFsuv)FBG-lLx+?<F˕``t z(g}.OX8_K~nk9X!PUm$*)g^F51H|0xIo1eh-r{z|jIbz0X73#U9CP=X2FN3fo;;| ͘~ A>,<6?@rQkV+sw 1<L,=7"krQ(_YmYNX+?ɂJi?0eVAT+0BTK|ゔCƎqķ:m,ܤ$y^#"3 :sQ`IfRwh* BzQ³?^\Moifzov{vVQ*N_,=i%.y#w (6x1q%#f+F?/.x8qKFFV'T=Y\2yZJdͲ!:Oxx|KFFV7Zg RVx8q$ L5#3x8qD JY'_Ӕܧ*i5#Op~QIjOfqdm\sC&OB1~2$IԼT.NN HK&ϵ0M-.NLOQ̫Uе*tQULL//O-p+jZA35+1))(%>#??ت4/>-?'EhД6"lVD"Ԣ2 )lAk@&2y5[Y88tl΃p(9yFsm~i  ɧc:յ" #ܗtAJ-lGx8 ״r2KRRS56ig [*x;?e/KF~ bL2J*}3ne}δCiG/fw9-pHPxuSn@UKK`bQ 4yi">hEľmLHf(Š/yO.nNIPff9{/~;u]ͱ>}֞D $2$$]rt͌.zy`&X+bq3W,VzQ.^jk葴_cߤ˙r[YNסkpña4=RQ- 7ǁšhjj(֩ zi$ [3=l*)= 1\B-f^Ke~k~u(hӕ,{-pJ=%vl0ayQ ,v{m!]jz@Tsq xf3uJMNa7:Sa H`*f@5)1#E(P\;uN8h~0߾t hǸd *ƞzͪ9M(+G˺nsHR(_%Ω$$uGC:9IO{yH* 9vXQf >0,٭Z;<>lisHoEEIB,>ىRYv46БG3=2% JTxn BCtƻ&?%XI7你x0#'_ Jjשdp4zq6߼ ʛ?[=yx{q #^d&͉eKxxqd9Lo1f)L*[;}J7*Oٍx;>$ y=4QxTj@|Nb^ ȮPb81$d)%uESN"߻8q&K6ݝ;N]N~@zM& 0Uc&w8c脬jEϸ8#Jkf`u]# RiPm$(x; {ex5PAA!(?9c=L9L: y))I i9ũ z\p $xcBB@Q~rjqz 2uS+usJSk5tRR4rs (*.I,I+*Dpqrf#R2SRsSu̐s吤sa NVE4x5cBB@Q~rjqz SR2R5CCBC]u 4tQ\tbʅ;0]@9'xsBB@Q~rjqz p Cx̹s}r~^ZfBuvjBYbNijnQjr~QFN~rbN<E%%@b[X.NΌb$^~YjQQfJj<@pZbNqTzN~TbrN1Ld3/?D>xcqԴ̼TǐPgg`M=.]T9נ CL`GwWKP3P(!xUA 0DSdYA x "!M46)"G$V/ϛxgj+u4z#o w8Y&W0}ODcP"8X}ifEK|A UiB |?;!Ė`O>&Gcڴ\Eruv. r D Q5TWx(Lx:+ud21W*cf Jk"3g~:µvV֧l+lg[[цp ߎCp V5Itox5RAA!(?9c=L9L: y))I i9ũ z\?G BxcBB@Q~rjqz KRtKt89JTVf KMUUPRK2 J2yy`ldnzQ~iA1P$:& 61=!V7-JM/Jр&,hU ŜPZ;`xMMM @&W)! EhShЗ#湪 +D R {9j69Ev$D2(ZyIO,OyY HR qOyrf,_د6<{{<~ `E?q+E!Aś׿/=p0>>ItqPMVkQ_\ڈsW,N`:yR֯XZ=6'=?ؘ8; hu4G ^_,G7}r{kkkcbg9X<❢n7r+97.95[\,@G9 _lhbn1^r/Vh |ԇŔA&Y0@ǖ&8UhϦ b.'|;*7iuχ(,Z2Rma7PY gye?ل1)NxKp"a5ܿ9hɿIN0vZ4z[-&~fvt+H lZ85qft4Uf[]uVRׅjka=:HcCka@ 6뵣ie1?9~TNz&3Xm)Lys^kwm2[ePX]W@\mt\m͵lomɵjnhmCs2i`8A{5_D o6ϣtв!c%" ?"e LwE\ Hby]Pl8z6a14[Q:T8 l c>Tkݓ. t5:5݊5K[1_PQaY [-a~'IJ):&Z*F}]T&´ I!2,91"5jMo= q LD-RZdg3 UN/O$.hjUytՄ.ؔTy2Z,b܅!CR3<S`A%oxCS6;\ɻ j&xqXɏ;8flX LV{oEzYყckS;#w>#"- p 5b >8ݒ7oK;ܚn Oi.նLBt4>BWJ&~74ܕ-)i~K]k.Vl,QXjɖL%OaP;`+|ر'(1Ȃ[ 4@?"u+x$iȳd+O8EPՂ< '={>{>kyqya/8W)-< &JA3rD-"f'qiV5flr<_N#?TxVn/$8NԮNف6 ^.V,V**JCPT pȵ/Ĺ +;Db"[c/clJJ>4=┅SbOA]Wdr2PRfަ$ !a[Zx°+wμEznKv)# +˕E/É(T(2'_1Ol|~~ۖ]2i{6F ܵ;%l ]4 +Z;?ښ3S[Fbԭ+ܠO 72 :*F&z2L1U9G[ sGnr[fV5GܽML';cw!e>}%L/OJ iߡm~ŸD |r %*ɔwYDH@$^~xU?UwmTaT-b$ZbYʟ``顺i~4G:zM3O骳N֐SrI…fuk?MCN̙fK;[L32tމW-jT/&!xq"VUf  ԵGv~\/tWI4K,KfӀfm<GVWj&ak,̀Zw-Pf53N_&p,?NL |||IA[Vˈ0r(9e{+1Po^vP4Xf؇? UWezw"nUu5{S& UĚ,MbvU5!kmIVoCF*M Ivnr_ʜR6S['UI#&taڿ@Voik,K|]keѩ ]_Z*դJU <i"g\1ݽ=`ˊuQ@97Z*քc/ښ!|ONKy) )ZcY :PJދEvf5HH yjƢ,GzU 7*'r b sԜ!EHBOOeWNY*bBֵ<64KŠڵDԀ43ZbVw6MmPe ЮuM'rֽYpX2u nVT‘7P:ubSj$,&Y'Ia2 U;ڤ Jor*7^CJ›4F\{*BRF*[.7X{EOW/$~򷺟zɖM œ3x6M?r@7 oEl[ޮƼj 1xQ5%8O5j| 085h@r=ǜ\f&eTjWyQCIv7UwrUua5C(ĻAg rcLFu/cl̸KZ&܎NsO 0BO+N1"L O/G{8[NrףK=]~}ί45÷Q#f4:n5@@t9IגM"J9|u9TZI.ƪXLz&锶g Ie{圵Ԅ^ɬ4QqyJ_ޣ0Vc_p 957ϱů5F';s9&Yf22)1ך-u<įm]Ͽ=u4jϿڛKYQnѸqq<჎a4b=tu(/pǠFCoRKR+Ogeh9"z f)(T%84TpZUCxVoESZIIe&J&K!DBLm Izlqfׁ(,PQ!zCJ"z.PoofwDx{ؿz\ =J#eJ!VLv yMb?vT_A/O^dK}bjg…iKl?zEXgvpю~b'Tk_[ eKZaנ6Fchu/aD a8˚S rh'&%06 ic_FnhǓѶ􍮖Tٹ+h"0 (K|KCÝt " {UL0 J UIrcAaj똟%ַT};"#u-{Vq`le0QA%ԻK({e?.5wYҌU*GbCէ$GuzFyvps<[SVQzpF:?8fܯ^LlbGQXQ>P7cC{Z1 .OFG(@l{aO8*p k&lwmSJ6%J8PD`(w߁+R& ]G|*^蠈m[aUOnl~ߠV zA`P*`KoFE^LoȾNœFrۦ%]Lႄ65>uؿHTµ @{X6WXF@ng{$`]lX<l.G?E8PEsؓTO˹WiCSZ:֜i(YFm}XFYV .vߟ-2 ת5Mm,Cn pw[KZnc'ٟӡ+̾T2>Ͻ*eL l'ا;7fEJTh5T}--he,y'դp{Z6!#}b^.tx}\=y=Ŧj+w 4{/+ھbNϳ@NE^lvp)gٽ$Eo-t%ipYd/6 }1Gɀ5̀Ní7gV oTxSoQJ+Ic&Ԕ/;ќ~C ]Lht ͸9x?{GM}??}?z;^ 1!AeZ1Q9>Id zc6 /Bi%dc/dfu*xeᶺ6~d|&fXKX[H,gQm$ 4uegΩ E5A SrHl57ٖGXhdL ܛ;EO`hgN77eb:M:3#$0U8oz?m76$/sU1 ߋi *yN@\xֱ"`5OX`D7TlGO3F t0ȊaS0h*Q.Tb@]˹Dczu؊/f$m bDP9 @zuS?.w=xtAT! ϻ_ך .<;o; nK獄%"on:,W kB/Qh)G-ω[ww` ]ŸqQxq> r2KRRS56sx {8xۿqv vFX` $57$?(\P .䃄A qN҂ĒԔ}XM=..UU"̼d.ԊœĔ̲Jf#q00C /HE?5B%yQEPUML/A5M2Qũ%hڜ0%T3DESAnra\@Bo2[ExۿF viL^v'd34m6ELT((J-NKNTԼ.kryunjqqbzBf^TBVNfUVfJ|I~N~yj[Q~&P ɉũ ~).I i@[VUfF"Ԣ2 2:V:AN0q2f@ՙ>#Pfv,tށ0g桺ͥ%D85$F;T\p[b-]D6_s̼ek|obIrcNB~Qjy%J:\ @ÙXAK&xCE}!Id9Z U,,4`l`c"LDiR& X/.)KK)MWl t%P+xF Z(IdhLys"Kɵꁛ5֧f%&%$%['h&$g8hp)`Og rTz`ʐu%z}rQZKA ˗i9xmQjAfA ZPZhl~S%`FdlNL:3*!oo{A+>/ lMй:;;||uٞtss6"@DH{C! $atه}h ` @)U ☥TB.:o.ua# M)PWEuA8Iu2t9eOe)Obn1σ;0X˰FIn)kv"椋@J,Xp0@Ι^380=3|f4biA;z 4jixBDEsk$/9&,( Iad4Z}థmdnn#T77۵sPktǤJ3j\GVFZ[ 9wTDo66ԯfB%PN}C=Xbسigs(8rU?W+KvC!9(I'lQ?^]8wk% +4x;qF ZWc,.̩}TvD O xv vY6&3mPbk% j5x{qv ,y$72eT61Ww QQJM,ϛƫ;9Ac.^sj'/\ ,h"o!"- L\(#Q;O4m7,0}yd6PZ* 9y Y?5jt89AR.-N-,.8ཙ:'X*5/esyb%J:\ AĒ Tɖn 6_w3`+QV()*M6Y[][]]脷9f^[\\\xWmsڸ BC{&˦вC 5d[rd9-,󖤻뙦X::zs^}rrRG PF<( %in+ .nd oA"bHpq>v (Bh1Q,sТׂp.tCfS"|]h)|!u]SJ?`FA~n1s?gN>߰ Wh6A|KA A%¡ʅR-&O $AL|ߡ$$3gʨz#!Єc"RՑB14(Pf,)/1ssVc(T:XKĀl(S}+@ U P v~)AILf F_Ojї+H]DR]4`\ ZM۹gZv{ѽ! B-gԽt{BCB2#L0 8)<{} Й@ x>p<ݫ`ù&7<_!:C!6&(ĔO4wװO? ewFr1igf޼872CE\O (ױ.VpVA\B|Zs@dXXb!OrI贩~=nB- 'BVAC%>*YAh,(XWFj^· ~ה(8m=`k%!Y^ "P 4;d BYK!%C>&$!5[ BS|"J<w1KxVm (q!:eA9DB_\irKBwJթeEANzyFm@RiUmU!c{\diQ_2g޷Gmö{qamXK]Q`2Xp C01t=+Rmz/SLd)o3jw 6M? *nlU=+P Jez:!fV^+aaj8}:~HB9vs{R枏CCsB*kEErsDGC.lAԀI,su\hGkw|iS!.ԡCSL ϲ%;o(T\g;Wp8,w2gtVԥA"A"-jQôѓ 489VqL Nyh.Ի=U6BDž۪YMɜ~W߾Ntaj#EV:o!W.\Z%xAw ; ԰=eqPg]e3 b?@TU`zo;fѪ\Ȑ>v.@n6J4̰aiYOˊ.`&Lüoݴ"<0&&< 8 t//OFS-͗>߱;φV_+T =Z5_B,x*xk~PAA!(?9?/u?Ʒh [xk~RAA!(?9?/u?Ʒ  xkn쟗:ٟIrs C9 +xknS'UZZbǥPZT_`0YgX)xX)e%(X+XX*YZE)(pMϢ0X]SK8OC]%(,83? l,$2xUn@VR"G,)mlJT-MsI6nJN HyB\"رO!wgfǟNM=Vfjk-V5$ 8i`:je MQTo!͔AfdҶiJu|]uVes Qz3OA#3 ASȽWuޡ x@<`mk"ۀ;Ybi֓z# hy<@rNӓfZ{5X,*/jŭF$1q\VL%*fqan5QˈIW&^oRj2~/P"_޴XdD 4a0w)# 7,@>qЛc{P=Ǘ;dT#m/[2ޯk(b6;s6STҞ Zn*RM3,5ũN1yKLϹ;vqD<94uC9Fi?gf_Gwg/Rی"lي[B=aw4p{,5O7Cfv"E)+{ +'B;rȢ.e:R.lXoK3勛KFX?@hu@; #i"Oݳ'ak_ajwcpw_Y!Ӑ:b=Y1y^*l{ª~f&O b"c <9H/<`0OpxeuJSgX$8l:@krZ}Hݒcj31iBXiTX Xsn9 QA )n(Bęz uqHnUx{Zk #f[F=*|mxkSQ@TL@8J!1'"r.df͇rJq*[)*g&Z&L.O,.)J/JMLTPH+ӨQQUUNTе%3 4h**i*$(hS@B =󨄀մF,)*M φȤpAiSsrS+5 2KRKS57`JoxrsB sIfĤ0F;=@`+'?91'>Pxj,1Kt̮nřTg[$+SKs K35$Ye-&39]T4RIlBtREnN^±@ԜuF#jnSZVCCʏ\؊8B`]"5q?`ON3(.;^{8˾G-Qhp !L BVv0=yj&l( T=_@!, N{h֒:hJIj]z2cS_ݿαK$t59x4_1Hs]95K8N4G]zSتvEzRJ5AA՛DM`+EvW`^\ T.-;\,'DYַoS_ɽm8_],K\* @8HqY(`A3~itf/ۅ_; J77#_o-ToVaEK쫌J^+ZwUaJ`u .s$@&`{Ea̛|ӓ)R@ TMN˲.v [5I}a!Tڬ'׾.ԡT(!čYцmn\L=lJf?D(XCߐ)*^e]3_ب%)nEW4L / /t)$)hګN[beNo̕b}e7VCxpNa #f[F-.ԜԼ̼ĢJ לYWn8x;pNa #f[FA~&nPx;pNa #f[FA~& 0xK @_q-t1j!YYZЃ6@rRƊ7)Y9sal@(&Cjص& !s,`Zd`["nxS\oݎi~mzFZ> hb[KmMф2ZQ^/OD -ل2_\,rzU(ՐVr%7gC| 1,Q^gxkb:60?45XVAE<3'%9(EAK/(G"RPYdxih@5[%&jjn8Yl"xVao8\~|A@{vXnѕhUU2;ZwlB][7o'-_)e1}.`)Iy Uv[YHew;9 -+7NQTJFՊkjnhф~hYȇL֊v5zA Q6Zp T㜔})DrfKXB&@aĵQ|nT*w0gkA g1|E0H1ᆇ(EbW\-ʪ2p%.% }+T~C3;d>P<)N1҉==+š`d f!>Z\o6jdDJUJx7 *RA;hT"Y)~ -X,f}FN]8SD*kÔ9m@%' RpEqMpk}8xL^#tl'- Ft2w#@I=Rϻj*q$hv$9]:^2CVsd7kS`CvZw{6޶.6B{|BÑ8%^$#u?ehays )OMiąlO?_vɯXLj݋o e=x!2Qd #B@Q~rjqnfF&I\`7>vɯXLj݋n@x(2Ad>#fC!GnxTk8~G.Ti^c+IvJ84M`bfF/y.Fй7d~.Kj<)һd2O' :G[ %_U+*;PWb9DeW!%Zv8t5WЯ9\~<9<򎫲tX6PTJm!6ƪ׼Ά l^@|[4~tQ .ސW 7& )!C>8Xj rU|MK櫡qln^ HB)SX4kEq%XȧƐ T1Xg RBY!4M2 C䨲E+DkPqx`-Ȱa]n9bJawImڲݫ#ubxSG줿6cv;0RqHdA8 u/;"b'Su+5/ٽB]k|i$qq4  ]/*;rz?"HΞ '"J́ c4p=?HCLqRD> ܻVv~Li_,0CL"߁Y1w|c{mqeyѬ8=vlxvJXYq)n垇*Oi>%a1'ASY0' ag^cܶhdؗlF<3 |a,,ҀûC/",,Oӄ2̍fU(7=}6kE9GvLpQ B&1nT-gߋŸ0q{_KDBTK&# H YSʯ>D5z.iÁa)y y]9GQز[q)uߊscRxXg#B@Q~rjqfFͱ̌LKX6V0&fNҒTе*Vs 7Quvv xmCx-zTd#fF%%bKX+YrS'Gqii*q)A}kP_}pkp\Ɠnnx[#Fd>#f?#j|n0x[#Fd>#f?#^zxYs;d"¯L{qi*cQk6ȰB"+r}zA~ٳg={L4<^\>S`>R1D;^Tp3Kٮ!,x,ɂl8 o`שR$4+y"VRH(9 `CpLRGX`8/hqMLT*OH"#Pa0p Xj2`7џL qqt"d}%J,3!&j SR^xAuh!<]?ԉ"Vh/` La ŵDNŲ;| y+~}3|{@ؕwR 0tťo}^÷dŹ;88-zvGv_F^w 1e2sySpJL LJ" 4 'bIz,;12Qd~G7l+)SDSũ%>ƬF|%ho-ci8xqh8I65^ F^寂Z _܁Zg0obsl. &E* 8`axo_*5QY=% i|p\Y  IߠDHv8'ύQC/!~zU/92R@_P*/_ ψF)BbL&ZȆ"p/GuJ= sk ECSm=sk&e 8&|m8 d 5 `Eegvr޵жZ/SơlPouW86+ ! O6ieMpbjpj3\_u00 #=4[^{2-nq=!]|t2qŇ}y o4O+L-}?t.W$5epR~ ~Ӷg(Ϻ|T{wckR0 וc e+' Ouuqv }.R=hhvVXMp|Fe= X5x={tgCɌ?Y *[YaOgb0 6r+SWxngp ?uΜCމV[4YŮvу~'_'Vr?qU]C,[Og^bf.{&ȘDE9pϠ]N7 FL(AyXiE*xhy &fS",ukϷ[bU`srs ѳO(tf╺hqݿp(84N/_<Đ$YL_pLtN .W$3d.Y>҃]P7Zy3%yI\i^Sx,{vJzb7C\fR=y^]TzQ,cs]tG㵻MsGS5-_휗mSwݴSLʌ5ީ}#GĚQt"a ~8.!9[ /F^'Bs`]~Ա}zbCyZmIc٥CDnA͵Aj%Gzl`;pwsT6kK% 睯0]23mU I.D k@2]6秝l&c(}}VR3/s7{g봱ΝJPҾwyl9eq;(GIJAHQsƨ(ί?F}1gΠ(‰r/Vz4i#3P*177&;r%L.L%?nN˲5Փ<)B0wGzl4tskWg#(r?faٌmt;^taR/ByDS/k@eu>MZ(pv|c0i&[R15ƌ@m 77<й@O0_Ry Gx_~4t|O?ӃCβNuNx;m=zTpIgBf^jI|AbQqU^I~gl& 3xd=z;#^d&)z2G xhb #f[Fa͙"Y$"Aqyy v %\ R\@ʪu|+=KsSkl2RK@J3by@1 Meĸ&-+Ț10xh}j #f[Fa͙"Y$"Aq,t~xWmO"LAѻo+;̎JfbL.֦[]8T̒vy?yzooU>tD?'0Sq8qwa:krXL& b O5T=ϏdM*zR Fs6Ka$95ciud{-_"|dj?~x6p*R\'h߱R56槰T cpXbŅ3`D>vuq5K"DDQD\baXjMi5b0qRP, (̌P} \ Gk&6gנXLj` 5(SAHT1)> J I^QjA;oW _$ߤzk0q@h8a560r.IF,F5\i )A+j'<r* up'A#)${T(5^.V\j6a"|u̅;Ydzi }m}{ #%%* D94dTy݂{mvMP%艘B/26ng0f Յ8aSġ،‡(|,${EPpu8ԂWPXD=U_<8d^~xMe@xh4+}Wvˮ+znEX`<azDƿTI*QX\7ʷ-[*I v#84l\ 9<'wk6~lWd' 8ȺOb\+wY['yXn8vb>SdlO:k\D ~co{6]^A>P(V ~`;aG62p5s˅r3b6 yKY״oJ 9Jv.n+}Y<œ\\>a'"Y #MG4O³֫zekJ=]@a~TVdnW՜B1o[H\ uiMm<;ZI_?e^fwgV+_gq,Ԡi)W !i7O 1oWʐH^yvˣ/>q%+Sf!wy_͉* &L]ǽY[nEdy6 Rėj&" sͿ^ \k_Vo1V^΀rߚr:WSj@"<Fbw6hǔ[|b +[s^H/zty?:zT {awĞɓ9x/M+[b\_( sޟGbqyAb<0mOծ֫_^7]z*~M{.I3?"Mg`bKC^Ne ymSٛ"fio=/~;/ b_[N oY6ܠrtnƟ^^5weaEzͱTWR奈}Xqɸ 4*x۪5[k#B@Q~rjq^d;&o7G2 /\x۪5[k6#B@Q~rjq^d;&o7G2ױ  x۪Ek#^d;&Inx5[k6#f#}|nx5[k6#f#qzxZmsHl~\\e#6N@\*h-$N/9H`a' F==Oʻʧ+΂P |b2V?v,@&!ov4[beut\} CS}[U\3a~ĽFa$ɦ %a Y"HYv&X\xn$<3)L' f+Z#_&"Kdx? .; ( O| <A%n,ΡܙHBfA y"ndhCj r3> Jвe꠼/KjmR<<#>S|qw0| xepF W`{t?g7XtŨ;O.>vbt1 '!& Zf.[4=EH B<& 0ܽ0' Hzފ iJH`&8m:Y®ٗKۢyxJJQz8zudqő-λL|j6WG^?%.7@xJqL;h B ™ ZEѿYaxzװƾ[If}isAvشm? C_UVUҲJ Y%p iRܺA6ӢS]p})6V]/ nultJq&-,aR /:a]3:!RػHD^zQ1< _@%"O>uSg?m>{6m #H(ίoxT+P$",fS'#Jϳ`! s&yf6MwZ>&HA"kGm=j&6"gqe>|`Z|K+ 4."Izi(S7s ɻ i[w>4*`9WPN.K*li4 \:Ė}p_C뿫HxY^8evda;藌#U1ɡ %:F@b,E'٢0=*k|8SU`/.P Ij?9xr;~s><ثUNƪ=Y^Y0ґwn%ԷSwCK( FvoMq_L 6ZT6|Vs\2$o*iIȯ'%:a֭7A)ڳEL}"W ,dٗ{)R{_HCK4%=yd3[`d‹  qF,湊=i02FVEHEKz7LڳtS*&eð^D@o,y+LtS`QYYt:P? TGeEΆQ ׼ sp-LCulAP`=$-!(Y(C"h"[#MШonQ+sDaFa: UWE|()Z '‘w'`5i=[$9 \qM`G/V5q-#y ]@>.:v?mewDWsž֖=56c}m]UbqdK*M&R"r@6D,Ǝc%91ؙRn7ւ5BKOy-;E1SJ|ZE@P5^h \: )S">;)a1*Y#-t>cW7ZRIei{P{1}tńdKAFqj.9tzTMiU V(2JR܇y&a:T|?:شZeHica`b\hKl^Q" ~;:Tu:: 37PR[!]F\poH|ӏ CD)wޛn ow83qm¯MLv,^M׊+B-52#D}CFImE?kjʾ̫PSu^Ч(7r&x ہ gU{rY$śx ϻSg0:h8NtM-4ikrJ,XEiLAUkIY?&HCWOU1F% kA9Zf5U&T=0h+7SNكZGFԝמ nPĢC;"?`p 4뺵h0}y-*>BuTsC][6 ԷG372AUL[kpY RpËK}J xiUij6揬Ly˹{7ѱF5jС.ۈ[lt!9CNv8ec/"{8j+S!c1o5^G gcV%耞zD%?<>޶l޿ӗc;?rǵti,-LI-F ,1*lQ^Z0^nUfn8KEeS޺M K0Yw4>XvŘ^C/\Uv-On`qv.aJ c QjF(B:gs oX9r1̧%5|WCiWZL 5L%~G8XhK_`GݪjP#5`d#.eBe Us2W7 MVxTjqPcQ3)W#c 0ו² Sū>Y+ܻvTPjy {R>$zwU7뇬5 ETtESV3il>w?iJΒoN*_mϯBw%9_Me<74iB=$3m*}}ZJjrx,\)|jWɓa^N*vN]P罳$/bx S\g5>Uwh18㸕hcU$"hOP:8siFBAbLP8ڂPZ82xk\g)60?45XVAE<3'%9(EAK/(G"RPYdxih@5[%&jjnvg d͒8Y  xUmo6\Cq6tC36$Y@V"cx;,>l^t|| W9&ϟ'9WҢl. LE4/-XE_u #%#࣍=,U %[Tj,± G᪬ $GX .2A#G1 ݠZq^% P~L4jjtSG-a3 i@h@a.P/DF0f!E^XY/,& d\Z[«e}; :Rx`pqRfx_4L#n͇D#`|4, rH S pϦB.TRWޚfjZ KYNd(el p .[15;=?SpO+As?ʢ.i<-FpU'24٬I- ,/qT+aMtUֺ#Ce1s_CߏY'bfI̻p%m_f ]t' m%Rf娘~.ka]dt[h18w86 $,$\W2Iq?Ze3Txx&}%$N;mݬ'V%yٝ/lbF:\ P]PZ`<)\RNfqF|fIjd/vF Fͺ.ɮ8َoZv b8$EtLf$L!VpCs0?( ŊbC9b~9!x;/t^h3dif ͬhy&6Vhs%x;/Zh&&wA#3ReQ:@j"fM8D&spgӽx}SGB! ,y |= qϻP#df}Hb#,ʯ~q3YVVe\_^M˼u9A vi/t]?YSbՍb_^D|Z{iΆgDm3+g8S,8e.\ F.'8Yv1]<}z}}]u`!;AI|xjR427%q6<^8y[Ó|{t{pͷ_mfŇhMVd;;.tR\#iv*;ϋhj F^MiyYfM`U9+iN+ & Vdoe JbM=oBA֍ "'No6š/[_W_|fFܝN#hK䉼:!; d{ ^)_".@ VA˼gchG/[5(Pod,{Ww ImuݾbwwV^wڨ&g)Y=3r9+.Y~ ayZ@@T׍ v5c73pLjFpWg. I 8t"g|:BQy!8Xe=O j 49W;Q^ 'XmЃ6I=i+ZS{BКS"!t_ˉAA|kfWe3ЕJZ6NDc6Y0y VRx޼9 x!gOh4"-'zbZVͻhyb@b!_=biߠM1DZ Kl[_;+A<~~YSnghl_C>b,_X*EpZ@byqϊbrߓzΔJG[ctQ_b7)G[OTOVYI1XW2l_4u-/!09xrG[,moyV"}H+]0JXfHHWJȞ ݆9@fXuxKJF?=Bv [캲~K6llwQ7QYՃN,xxdKF/!f'8q؀=h-GGk#H-~&Z(B,ϫ6AڐSw-_' E?;EsnB d& i+*Hm;c}n4:=ڧja֪@iR}Tt^}? .b ߼p3sȬ'B32|uVòȧK֗oC%6ywm3 iS_)S/@b #oePb;#&>jarD4(G'ǠoܒddDq4yެ3=ħD.%~KeRM n^Vw<<}  `_#&% Xv,.3՛ݽ?}+^W4Fp$Fn}/[pM&\e0ƒ0 $"oI{ 2X~I[wdҡqV=ia&toσK3ph@HTP,0>Nށ?>&/^ɦNA*v?#fXfI%%z M]jt WL`7Y 1=#AgSbBıg5m"lͧ~gϦ%+h (-eIJZE$~#4c͂hO /i_Qc<>uDX-ㆨq5Qœ$A-~:twdnJBq)|QVj!c#qhb=<#I0/\ʇs,6E49F)fe t p Gt)@0G7zY?`1=u|pݐЂ5*%W'Oa__!0}֎RuK =}HHf}ׁxYbRewz NautlH9YXģ@-_z?oq=lUe2OU`k!wcBu$-'MR٫Q]hT璚̈́qT]*@}Dҭ ) ?8=ke`#&9NqEq SZ7'GaM E_Zam#!QW]FکX`AϸHgh))8XVZAjQ)ᙡaޠ+\S=3SĿVr.H,955 :c: aK\F/{٦ZT]gRY]i2;.,;vci]@)qMkl~,=oȒ}@mBj vC1p wy;50Kq+|;)c0"M/9u$"釻C#DD[oZ9 ᕵhC<)cnU dD?De zc #sh'{{H'[d9قqAƱna#5_EawiPr߾9poof4#Fd((>BJ~Aq%1uʃ]JpC<zs(lՆ"!?'n1 ߜbg, a4?WF3<_;ARIjf((R([*ɫG> C`^F ŧH VW 8p%x5jqF"c$n\}#R g zD{xGY{ۺ9-'ڭ沞a>)]1aUl j%e;d<քQ(@Me M8AslG5<(ZWeW 8:P2h /YZwA0%m+iV1B`2_>1\F0-t8=Т!} ڠcs;FXHUPx#yS$(d`x?U9BR R&|3#df&BNdN(£iQ.JZ'_uqv`Us^r3NҒp**~"Z\% 36,/SŴVs(zZ` dxLYqA2jwcWj(|81'l4.{ eH]\1޲Le:Q;#Im{/‘Bs&RIQ}Ϛ˕Q\)H ҹ+CL'BN̔*;{WCo[hSqe1>-0u!8}Cέ'%}^IYϖ%ǹB)ToVdK[M9K0k5'3baΌxh|l~v,Pp j%gK1]k^DopsV ;OʺjeO\~6Siw1b ܺ@ɄC(ഠA24 dY+r+`&dsf|_/8ΫfI 'cpehqDG" ;Ҽs|@,ռ۠(iZLT-sof~,UQ}XDO~zF@clKNr~Us@X(4N D$pY.}t2X"ךHK}q ʂIf bӻ׏S@aFnR }`rDばrBXt[KD+3Te67=\*3ӫdE$ 2(Nfm~^t x`~] .&­6ދH :&ceP==<'LB$e@RfRftnt`baZGp͑#iڑX(CqqAaR @U\U0՝:#pEHJ9Ԧ @ij4׉^фހTXLמ]|#(W7-r;+K[R֥,(ç(UeC%tQ |?Tb+q"rıoErD:B-]=4MlP6 -|{mS^ye͐kt[(1;%4]ޘ:ɇWq3܂$ G2y*bX)gu4"4[`PCZlɨ*˛nv*OL)b5š0Ep'2qǥعc=NTEdhqtdz#Rv:KMDϑK7CxQyPϯI| Zn.xX^o.յ3(XK unV7h/b3;lw!ᔨwgt.68J D{e~7m\#a23w^itx(%3rk*O5(dxN;A*D/ur"Np#+DHx^%~|Ca)8ܩn3y (֍f.>$RwL]X Rέt/=ܭ@QkaP|E0;RAFytHM|-whndB|Vuʭr/w&7* ՟bW/n֌ |٬A2xD"B̧A2v&nB =vݛ8cMr`G Dotdz>TPKτ SB6ՋQZPB'7''ثFL+wOp5Cs|!39Ɗp2ۤ1KaK-bQE>C7ս[tK$8}R&zƕ@237S 5Cp>t^FdN uFw.]<%-q9@^G6Nrjݳ؊|I`n%#zwkҽ8&jX-_{_wΓQOmnՅsp/\:%P(<75lV9] .!9&Y}tfV'ا֠֐NGj%=]KuIToz)K5<@\)k&#f0s-HDd9  Fm3R I YW&]=4 7;-Q?U3#~O?4 ƲRi`U}hR+P윂T[aO4e*;Ny^!<6+p5٤98h܅zV .wS/6"*a 'XZ!Wf-LXH Q͞K9,)P0|-3dF  QM/5xEx@ՖE?&ȭ\ c}WG>h5]%װ$[;[$%gwp\ pOf\I:l,*l f,V¨C]>{/)6z>X6i3Ų\4W>ܚHSʚų? T;B.qx{l $8-Q>]b'“ĀiH tesTpۍ!f˞־αdm{=_?# I\bٯQ6/M(*넳kQh#_>/r/fqٖQKx)В9Gє+d % _DP| s{ʯXV#|Ey[>.|ߎ.)ĔwD'mieoāTh.Y W7m&.lз u>jk=Cs{)'69D=Z,DСM `MB93m2^Ғ/VW D# x}!-s('D)+K-d> 1D+ak{EaU5A݅/jH[xA/b*j^ǥˉkVIt]>5k$ܛh!ZdO!qqw$ kBxj9")w.e2SCUbzg1*٥8{4&9WrxN,^F%(vb8ʒ!-ۍK$Jn p'a _ X9&튪aAo|ZT+FDd@oEHA:JP\Ȑ ɹmV5tP4:IaDEs$K u_)ȷku 'ƒ#-ݲ!6RqD`y+QKlX / \Sޜnoow~5f݁aΟm%~U?}ەc0t'*qKv98𪗝jQ 1~mZ Jqpg^<ٰ; F yx( vKR\esg~4E[ M[73_F۰[WuUa:CԆb!s"o؝N咓-3: %4׽g1\`y.&\HD=;.i:h0.Gg'ͨWH>1bpŇ2(a:WݵbUP[\.oے)`+ޱu_g% 6+\g; w;XwJcWHDro|z{ =p:[0Q2P譳7JC ׮j<85w? oU jFwYݿ۰$FD ;@pX@:a!hQȃ<.*Ic6lwb4mnm.iFK7tI^\e,!7$d/}5b/>C _J.3)SˤߠKEia{##a{!BQg^ 4JJ@5|t|^﮲I=s(rj@)bo?ꘚZeGܷ#ۊB Y2ƃ_%1Zs5|`F‚y#DP0 r(͈MV mfԽ - Ͼ&Ǚ%_Q'?N27xuj1iMK/=a1&&ISڛ1V;Y^KBLk7ȩKy V^5E|hF_>bsEgߝob+b0zp r*[Q#\̀<BYڂqpNVLX5swp1#Α.1@[j.LR e&w+:<=(,EnK 䩴Yꭽsx'2t]8|?WƢ?9!FT˸߇>]h ;==0 f s}Zwq_VU>7jӦ,NNho kjɸ[fǁ]t]ǒ(bj`i&ũP\T\YPPPZPX7h`FF0bs-&XM1L/ƧT\Xk7ٰ[xHXsruRA)*@tu' 2pMp2^XV6dDɵjrrqA5fh JWX }x԰i".v.XM=.›p=fgSH,S0|Xas:2BۥEuTB]JRRR'_KN=:&c޼,f)72PGx{W\G/7{!3=\,?d 鑀Y\VڈjUtUa.ӟ~~ݞvKxeddÇσyYGr4bv>gaY&e1:ky:+fc(ɰ7z[] ūi9d:'O֋?^k_w]ƳjZ&NY1 p\:50||5罟bR~.R4"Zc`o1l(ψz1QqP&l2(O~]n>~R1}!X_ILjxW~9IGWPx>;(VIo:>/gxlX/J roSc$-^3L),ގ*'5=kFb8z3LTP"!nAoX K & V:1(MƧ@xwT*D)N'e;N|)܊/}0^#>}LgɫC3Q -'xIv]jv>?`Ǘ 7OOãy؞1>Չ*?@p Qrx>>){` 87Lyv5:>IfAD^^@mO"C<+'%U Dx+Մ../EzG/6go~ړ_7*x є.8!&b:+|yYR~4rBCNCK(/r.ҮA* cgb (yHI-TDᛮ=}?0UWRz:\r*UW34Sp?/_ E䯧ųLoCGUl AHnZ1 u5`J AmiK~!Cra/h㑐7m[%`d tf*Ԯſo >{褄&+ xVNWZwrRN">ǧTʳu(Gl0*;/֋٤,W$}7g֞,/L+ Pt>>x:G4T1]I_v.$I1&|_&OG](Iw|vVZ^<_8wް fǿq!ʋixzk`4 $T >ۨ?T;xu\) ]4ö˓pGW@\}>!]YF{&5= sND_qDe0}rf W[v;=/dYos#ⵁL:D^D=h?HBZ9!.%H9i; \OS!>Kؓo{gQzWTߕnX[n9'J3UEم`_]/"m8NS9^./9c>w BM]Y!D"U7teAeUo}í|[>w}>8Q/4#z=?nB'xt֊GAs-,WXgp8 ]{@у?ٔH>(gK*&ITA>ho]R֥QT S]Zbo^AbO2蟎9F2ȫ<`̱fVVp֋'_|]9ߑV+Ć}~;Ay:s|)7zSud9(ffPc͸'1/lV@Ho\g!bp3K2&b."WJ p{/-9:vo~/qVVc%h, u?~j0CCJkK7oml&-J ^4nÁxNut:B`x r 5 J2:tsT,)Ao^/ɿ N{Z/HC8kuXn@k 1 .Ft۴ 1"9V7rXg fSs@ܳqGxVv4O( IAJ.mQ÷;ݽ7>li_W`7 ,|@au׋LL>pURٹؔg[~5A~MeM\/ϲH*h>7N ,K&i,tiQ^CHLn3yi~ﴨoAmtYZxtY^}l \DN Blo\CvXKb"Pxt}1"bmEtm8vi`͝oCL/V}q])qXEqJ-ʾYm"][ 6|''BAM[/!_g#XY&~M+O8pc[*sϠN ~Y:AvBzl =L' S)B'](aV$ ]ytf]5blFHED߹ɥ698 ؍[`Pk}41ЬIZkUf |F $Fʆ~g1A"el 7寃4ã#>^ZW2:Gt_vj[DQ9}K/9R <7I􅵖8Z-h*# ү;U4gcQow^v_`Gpִ)ԅ 6x Gb7Gv+R!, **g)(2`$Eb^l1ƝW0oGG' -Ⳳ"pሾ_ ^z\h{zͯFFXɮ^=^v6{e,&$dο}B@|%,ovΙ0̥/_W_GI?GЄn 3͙F#V=up:i$H5) d=;BF7Ӊ7x:`e +lSe_I ELj@_mcxlu,FS^m<5Fl`Kn Ț^֛Ng1̱҆1#C2\|Lt9d]2fAIj oR8YZE%,no -|1!Ý/)TcNϔcKs[6@)>/9'*y*'Cyw,RLa|&X\ݷϺ'uC3pn\ Ebq @H.@r4ք[;{+)u)yId.r@bUE(n53C| [ʲ% 3Ju@CO"Jpɰp~$:u)DΚH6\/@'{ }E5BiGG&^s7HQrYĆs Ba2?F*q<]VIOeU(cF} w r1]_ǡ@2 "jSD\@Ĝ3` B"Q#TAcآI[8 |e+iګ;y/1E @2Шb.ME&%{ bPuvIrf?̀ZXU '4*KS m#CSF]us0PR̈{@/^^ᐛ]]LvbLn\"(MS xxB@(2$qԳӏ>l.3oT"G읒&)5 k3p~s~fI" Mw$kc-yfюBgYsA:VPwH LgZށ0B܃!k̈́_Eݦr[;Z<5DjLwv 8-Iр}źxQ[P\s%p?^8w^>f/dvzDs ef}H)- hO銠 Lpɪɏ82f~ZqK%]6`.ۺoӇ e)؏6 DEf:v[~MR}sk=~^A ]1n2E&wjGXf\X!eRsYcUl|캫q!q$\Ry/Rc0lYq+nL4KX=i^[-)ϩSi' NNxEDb4< )PI{! yN Wѥ'DRDg:}4\<2g1|bP~AW4Q:Mj|8+B<fб25`.5?b `SѩYAc?N Ȏj@p2!zZ8U.Bun+HϥqH.!FӐv?͚(Tb(:oJH%G-4-KJ `=[#vPI=ub. %`[^XETS#;S7 jL>[jJ\QVOT+M +-O;l!,) 4KQ}P2Lw1`Gca %4) BBupX&J ;{tLMIT y"Ў۾4]ȺCA¶Mq 7zf_5j`VN8|Mh){D>$v AGQ!tdiB:H$_DPBx /=Er SǾ2rJ}9>)1]L'iaIkۡS6#!.zYrFWI"_tO]YyPƃAD"-@0{Ec 'aABx25L 0Mh32ɺ,6w1xeTr~e2XN*{XH~fOE4$֚z 2JD(y͎QB^wuH[Z#=2JTHB!U)*YljyVcօ~I=x\ɑ8"6%^ :辖QU`#tJ-{Ӑo?fGtctuTYJ Y_Npq jl&_zSMVM*x[۹g¥ \Hs\СN;)ɂ@XHaGni9<$"'2ͧh}x>F^A97 t(̄5\^[ )gݰ *Us4yQbЄyRdH?f.${ $/Z`;"aR9 EFVTl@u̎V": aRhDcjPA1eRKH Mh2*H(oIR1flwVdÙjF#govb`̱Rm/e8_3cs∰1Mۈh[GӓC<_3U@(7WًҥȴNKHrW۠s]h)-(3NhN[3g\=#Y u(:K$=%Bz%ϣVҡ3ML.rЄ- KчGk#B Є.c)4zS 4wrxLȑ+ /<5bBe?0!"K+do"L*õJuǿZ@G,QD`r@qI@֟|-2_*R3nH9, v9RIp@ڔR~i Jȉ!(>KDHڦ-*rh0F6)6t.% ɮ*4!3-][7qB6]%O[Z:]5ԲB> :C!u?AZ#L{XBں]ˊYe+Eä')ԈySB׹j.lT}16LDz5ns ŎHKMKP-GHLT,`Y9E+..)a >F)UXp-zZe'&Z 6g9Ieh]:Jmb6waU^g' .腻+ө体v*-)\(_-߈xUÎBœNՁIϲܛ Cs81+U[<34}iΦxo-i$>T?sB=qNfJ2u4kQр![CB}v?c2gfVO]of,$:J~wƚ"ťՙQ姺wS^եʒ. =0pnV%yBg&4/dZD6c$). q6Z-HM- ~A4[ 56w,̮yI!Va̰4&zqjNm)897v22نd˜;4R$w>e>сEk]~7{;,݌rDo} PC32/AFBy8O1+-=nތ䪠 -{` \2e_qK\PÄ ,jh-*pX ?)Ft1~1ds `,dZ"X!Q ]b2p/oD^E[A$*=L&C3d%eD#7)NZ[A22i48xnLP^rSob}x1P`p"%ӎ<'[`dL9Ije}xz435Hr__K*w-G{#]:7p7@=Rc1t GR_HP0p%gtE$E'^&TxBAHVeX_P[l>l;3Bv\܆DdHx"'.p-UJiz%Y ʔ=:EcB#m6PЕ5T@5#'=7ZNjJX85 n*M:$Tә]n/δhWrx&R>5~u~UnL'>Rs0A8[leMqR>jI7FFakQז\TX<gH l'trr>=])qB O(O ‘(VACs{;תLr69R!;vO:/P^7Ag+U-J:u8Hp^Zn&>-"'K\~ԟ$ m(ƭEG^{0DJ8 wEK3c^JVLz-Hޝ? =o:B ,q+\/w9EPXZY g OFJUxH"M CFpi¥.Ie`?+<ŝgw@36iS'A}zJ/wa _Q ~=}LmXX*lw!+#W^ؖlo|}lM?FA2BTv =(gYUDl4ҥ`mTYm3MDscڢw=s xYے^-o"Byy _DT]3V0('\<&Z:T{4k2Pn7΃@4cLO[&3Pc =ʵұ&ݍqo1bNy 8a@@!Iqtҫˍ/Rɲha%Ǽ^j>k'4&w2߻etN`E"n *zaGdey5z&=m %•?>Le٢/Zd0p  ߵޞPYE- Z6DnkElQokXzL-UGlQ&bz0atFjA~-tYΛl%OO3i/<7o2xM<κdAW¼wڮqsA}]8؁ mly81'дpR\M>yc%{7q}{[vv?OQ\X\?Dm? Y'r֨߇#X⼾U@:VE.m#=SܻOGЭ Ơ^/Z|Xl0#"

\ ǎ1~.<) 1G\׮\@26[e¸~=k}#v(N oIOJG/ (ٛMOmeDD\LQ*ʆ޿*#bJ6a"-B@#+D,.-*Nt0}LMW2A棦>-m֓3pgż7a>R=`d` GfHto;b {(RLܻׯ8hV j/xv[,PbڅIr%2`c`fc CQ<_e6b4rawޫ[;[RL1е<\Ha*)Su|+iEu*i-e^ v(iꐛVvJ~# ` ,u(-m&{aBoʏ/ale$  <@z@L&'F_w! *VAn(%ϓqjFmx•/w(?[f ȗF,T%A8 UI~)|[\Pe20w([j#l(c$_cVҡKthҴ8Yߎ3W$hg@,Z*;>I㕕m_t;x u$AyDVOX $%z tTptXFNXgGR"zAHl"3{Ġ|ݪX!H beJAKa{[s枇ФaFDuh#s2@shȮpTG{boar*r9#,XZNQql[@CJ/B - #ƺ5 ,/'ǻ7Ye )#^-xQ~hWlIz$z2鍦=LzZA#te5Xmr atP;Rhw(ē~3.XAA hlU:;x_VCZvptYo,o╉ERDUXHN>"Nodc\ dHf~dK462{udmYJ@M.٦ZL}XfOm"ӧ\ohqɣsr%[R z;W]:SD:VX0;ID.Lz<9$A3Źd<KwY" -K7dDya$600:'ĂPYg;)$ʧ֎eJ p~E= tDIxIa[0e͕3UѓNڲVÜC6B5ewY@y\bk,g𡵫Vϩ)TDK7mԈØDH@) I4c2h[rOAq8wJ%@VW4j.f|5s|w59n.#q td Y{o23jpV1vC&PJD(]\MJ|lZVM)Ջ7S0նh sѯpF%ջ,tsaL I}TGuAΈ^+.Uleո+2}kB덈O(5R>W9 5/oʜin|\,o;ӋFի i%H4ZTrWr/%pq,;1YCJ_JcWRH($UGEJk٘\PG펼ϓm#Hf6+"Bo_5vϾ~kEv[[ϵNxC%ۇ`'E'`sP/'糢sV|/T=q7y٬;$ݱ.e0>t$)L=7ςC>Qǟ[^JZaJ_Q#`q ѡenN~2N>^]Ng/ͦzR6I1IK8.r8M2,wy j]6FC4w c#KL1/` Gg=Ƈ1l3C-fǪA`pU_0_+kLB&?RKW"-;⥶B D9lV BKzKk-"kѴ*-Gg[C *_4J^Q[(UTԹH0wWM+˫[d4ݓK6+J1{YEjbەwTQ (!;!)*EےP'*w'kCJ^||UR']HÇ ۯZG&^C]+Z>K.\{^n5[׼vG6 Bt%Jw5%%I~MmE%\+X<7 .>o"($iO_~t$mJ%HbM5:+u~H]CQY+<^-?(8gH⃤ᝬ"yK>#ft*Whϛ\(Mteا(2_qrI=nUWWT R*i 2H6,TЄԚY_z:'zFSK3*R}PfAwf\C_ȀY 9 (A#XHN0-_U}up\y2!V\2Ș ʜ@ѰsfiŲMg}8/X*%d`لdC$v#_F SOuXjquyt5[. 8Tv>gadJagqHU(ؠ{QFzz֣7^O!f? (Dq7N0J|Iѽ"MDZt ߂dBϾ.\J ;^}VVN`d";+ ^Kfn rZGe [u"^jH/^l툢,$>]EyZEE7"# ۘʡk-3D}?1s(@c*(R Jn#C@24-V5 ,=q&7O<=YB8'̓ny\TrhCuu⥰ ЮTF4ҺOw9j1 弄9V&\&цJW0mt} DzY1{7/019VgX-FG |u;*?[rފUb"XTd( 5ΊeDtrf垱 tufcK-Jbt [9cay{Jz2)Oa1a^yv ! EsdJԷ#Ujhc⩛u4DzʧVnlj t*NInKp(ܰobFeJ[VVZ@Dy1vT6J,g~8 81]1>fm \X BO#{ @aϫq( +Z;|-oPJ+?@j?ۗ+ډI'H%8.[l?*9K79-ʥ:B i3)q"!%Vۋ$q)FbE!<qm96Dv6AՑl?E4BZVgE4_327 /'츖r-r+IxnOi^,-E3%e/"ǽiX f3 MrT[[^"1AD֗K `OuCY4ȴU'BSanrejodwi& =. @aZ!*pV}&>V״gl(o"+\І$Pj(yTzС~̐1^`Wk{ B-pv[ GDxm{ʸ{3[fB$.TFJ83q V;[Ha? Na1 sć-(4Į/zהp{$s2Y z٦3O4K`z#KX5L9f὆@fXB%aBO5S-q#BTfKq"'(ߝuݬ12ˍ'O Zţ©xTDn>γW݃?owNg=f <~WY/y/-̱~T,g߿BlG )&L?7s͞NWCǸơe41bL.Vp1};o*9;^0=! cxO]DH |@B8Vp^lxHB- 9 f#r_*4*n N) \+86Z{s$yi#֫v\c"ş{@Ͻ!Wvlg,J(}\= {i}KEqg+dn)m1}0oժƍܘbwxe1֫_WQIn T?| xG#T)*~s6EqdtX{l7 c<tpF.!-gJe9P z`, jTSJVx}pC&Uۣ5&D~rUv*?weXmf9ۺk|6+1\j>'TtFs|$Uw!uc:J8OP͆dlZ*mn?w)mssd?uo2nM][犰 gb$؀e=6¤vc]G>D@a1"rlpZg\ + R=ߝ ܴ"DTIUMBMjJ2Ģ"85^燘xlw47`City}_pM tK[*qx]qh\0Eľ&㼇۩W8s:ͳӶqE_NW^/GkcaY$I ͓UM&SAa ]@^5c;j6ٚ5g(>c;R+b›Mk'iwTЭ $'?,vHGa,liQY@;x.LpJ >,7Enʄ!T@0Vw}-uhIdhc(>1_ё_%-" RUy&z|hPZL^zp) O0@QrEQӭS%6Ez[Ef}~KgI0ț]f>]e 0 j~M`@e/yҘ ݸ"Gwj"` nb rj 2%, RPA f&($QTH̝\ Sp v]k)`F06ӐM'{Kz]r*<#cTOCB}mC tuFH^R@$.WpލWVEykYS~B9,b /u(D؂csnv4s_X=óLF^ؗb[1M7YGH8L-+2n & ڷ2^}:4s!Au;P&YGem"ÝDc⑹D|smرP;݂ԒziPoft8b`|U: O_?us.|7a>Cz)1F(ͬ m@ R͔n9':Ln| L ( AksڊVՈbWrUǛ`Δ!GastmEYz Gv0RvGM6݂ԬOep1ףS܈2]oll\qNd? [ULDEA%/-5l%%x!?5ã,^@!g19NF΃`a" P\z`NyGtBL0,'AIbncD#2uS'XP I5HЛP@5LroLR0e6e'Yzt sK&4䞐<$M4NlU#d=FmKv- q¾OADsѥ5y;@M(pY9{GΈ/> ~a$-@Ÿ4"\%x$s S"Q A$3 44%~lolTܡ=#'q-RfE>FՇCUcG OvP7?Ll W(}X".0 k1VYt4K<Ųܵ:vN]q+N]q THtߢ^bŧ#$F@TԜwKl3S`{2oU[@,k~bt`*O 6G5۝i*5ZaIr@`pMW'r8DJ+';a.yxTI)ߧ,cV!9W˾{*G{, -U'pl$ٟ0( &.)F}A)ԁ=IO*%p- dOBr'dYRC!oyYfm>+imhR2( /lLE\q/ay39cTᚊm~LCl%zZyVf *ôQ*[)7n=،SjӋ \jTzE*I-4EUż-ڍ@ wJYY9sXBSQَq[?D nj6v*O\c ZEQ/ο#õ#D}hC6MY虮-HtBq60r}a6:Sjֆ-mEnِ75H螋'@_ V1InFzWz ^wxl ڹ6?DQU5;A̾腚E l.ndnv搋OӐ;y@D$*2:@vZ+a0zmie)|i6.l2ZU W.uo 1KH9TØ#)ZL]`+i S0}[MncPPh$u: Z 4Cw9-rɢS19dVYD\Y~ 7 -hD@J`J&\gIi(YPzcq'BĽ&-74-PݹutBU6Ư7f,y85BSȎC=*dnsvjcjڻ41v$FLEXAnLXB`s&ʮ:9m)\yh(N)i#UasqUh##LwRC td$'OPb׉4G]k|Q>&eb.ChC$q%i)]Cڻ<~]^ 25W<;JcT.B*\~2&ePN}υw0ɰ5#FXf"e +_xmdFADkZH# = sPv-XY[(ˇ;O%Uxi$cm $SdMԝ4ܫeb(HG‘jFM͡ii!iVŭeͿU_N)' BI Q>Dc LŪ֒˅O aK0V}F1c:W0 9f>hqκ(K6*jD֫'pX x3; ߉)#"|#HIQRwEj4tzpW}az#IvUT3IRGYXSDZ. y:Y @7n b_u̹bwjmmx޺‹~:{Ҝ|?}T|!>5D^9MC |7OqT@n2 hTpOVN:X{3 ?A0w/}Z 6r o@%: *?i2r'Xy<+U_*1[,G7#r=ZIxK4馳)Էd8%'ҹƭ5tKz DXAv^fl<~t2x(:w}]| ǕvodŵXԺ|ƭ2UG#qT2M鈖O7Ԭs?T;G)P⧺3Po4,[qr; >O>?l!SV 6tSTTȸ6B%p+Q}-%s*dtc*@G s^Xݝ,̷}彧Rvd1 ^ƜYJ4E@X6D Y4"+9V>'[#n=T㟸XƗS0!0YKV&b=0 Kn ME{j9l]1;494VVLJVZ# j R\Ht+*=nd"bFVe35 c4|8ފmv<{l<a_0#Ne EιCh4c^2ޯϜ'.,:ͨRsRN K >*'G,i,DŽ YKڎ[`_ّZXk\DDfGzї! AEJ13YJRBތ`Dk$4?3o(:ATRA޿bv7ܦd0}t{G8yCFSO@0Fխn(TVW@ '+kmúΔyH1HVD(n?UNULz Ь%ON.LJep/_+ؙuA4xgˆxE.@Z`SD_p Qn-jk߇BZ);|jPxH8`8g7I"&ɪ=pmPxBGN̕)HJ̭;nAx):34m5&0IL?/@u,d*#7? 2o*rhƓrG0 ]]c= _|E" T&<.edGC:P y@7h>l@lܸrBhy:YZ&\6zYJ| 31o<3 dn ͑2,|DU|*Y2Q4 EEPa_8O:Ehp֏ۇwחl=. :M􆸻|%=QWIkYx$;g-J%{ KԮ<jw!'%U3d88CbۀDcLr:Eh<˫w֖-4᦮NuVrL}L X._Eɛs'2͎y^0;听Մ`,UFoو2&?7zVCQGr +cjQxUB>aNлlKCn専%פL޸YYknF59)jUч!M+%?ˢCꑾ"6,fg``RIvsN"d<[$Q ߇? MTLfZ9!18!ʯ!"͛q0;n6Gi(ʏOuZ5KQ;mmtqT 0gn 'Nd]I`e&sv?SM j b颍%tjM '`v;& vܠX'IzVǃ- NjTQi\у>;4(N 6-⋭Y(bis"B搥=T=zs8wyݸ^Hr5^eu4k׽EJё#z ceHf6T3!h b?!6=f7ֵ\7 ~|/8tʤzvλ'ymXctZ?K =~9 <̂ 3.(%'L\O竟#ʉۃvJoXKw^i#/NL->N,U{s80$I`$]7 <LT\劏Bܘ"ݙ6xGya!6i --)Q &OQGǹ73c(.YK(m"t*];YAΝA4t郸H?ߗ!< YҜy7Y&}MU[{?Cu?묱y23xLrr8{{aE5cR-sJ0Ճ;CM+Yc"gWZWFw`nj?O t4MQS`_>h˵a j33 XO N"ZrMEՂ9n{"\;ݢ[5b_TL㯵8X@[xK T +[kf ⪪T,@֐:.*("cLeF W0=ud6)sQ%kȅ+;hgbwfb (7AxbBn4I~kS|m.AXI@NZͺ_tnfK>L7!768LLf,SS􃦓>LrBi^Q>r;EesA.n Yָt9!@3s9Fyӗ0otd68|e=$]ߊDL(ļ K-J7 Y]C⟎`%2E'i1]|t4;|Sr!RTFaݵhPպԴ쉇"r:_n Uwp݈.('mC piwC|A_u,i^KJN7bF&& 2kv?WRg0G&3Ǟȕƨ I W&Bgf[U!eQ#rqtF*hJ_4lx8 ;2L kiJY<,bl?75g$r9kebgp̈W \J/N $ĬKYD ͐p78 ~ù5k;+#3q'JqM|WF?w!\6RL|j^h"{ ;O yE4t(1RT_?_%al^xsk}aLI7ֻ+%O܊Cjh>n`8[@*h_/$;tsr52 MQؘ!dSFJ~Ct#2j^Ὼd_pi:ӐdRƁ3:" y3뉼=7>䭜qayK 1\T>= <UYYdY>LٙL~3I`S䑜N~'۶͙ū.3vf<܋u,cX=G>iYSVIE* pFbZkk c)h Z}fh/SK( M&'@zxL'}^嚄 #-m絁KC)kI{/4f\])-@oJEK8-!NGЏJJgAV`o}T2}ˬY u*m/fP~T_z%{O7_駲ԏ詓qk2]2v\5aRd?HA@ O[(~YR tH*ĭp2 >^Bk 20 w8o/尲iS'roGl,FrқQ ʩ٭V%ƬF(R~Y đf8:4ZB`nd']8Cw YP̝ e`%l`PX@j:ʗcQx-  6'+x#gOU9Lj}W^O}^pzcV( 4*/p(kwhVЗ HlR .666І`$vRWZPTr DR%6J^T;Xԑ5=I ]`ZM+Еe$ИgqLj K:Fx_t e?sT-X `Dgp`{c0}bu?"$AY@e@8ohNam憂wI(&)R~! SxecVVޯ۷p?r=HF7'kNr B_0ĝw_E۞#MIg0N֊%1ݶtmQW{?C˞u!: Q2k5ε}w9/0nyd猻&d]WXNhV}VT ŷ1Qbps(CU(*YELB &{AM#'X;g^jE=ļ+Z8*mSЙ%I ^Y`G5ҍO׋/4}@DĺO_5mӂ~>e :G,sQΰE[I%=%?Gb_ }Ahlk.f5iӊM )}lBX}c׵A9.A80Yo [\dUǛ?,G*y~*\\q(&?;Ĺgr>A lHC?t՘1jo!Z8!h@5(n(x~*CF!vjAx Υ${=s?ueh.?x 6^wh;pec.I ׺|? Y4aYi5Դ5^d UE;B3ܙʍ BJقNlFx cjFHZ1 -3qXR0cR3,:jNx f%aߑZ  8<~{Q%`$&" Y{w:k%8VHڴR{יF-]!R [hnkL^Rs^JS2t1ɍU I))R!'&NqTF[/eȆ!DAux/-q"wUKiɻXoP޴Υʈ=ЙFjI9Մc JZUX]+2% ay@u*ݢC!9,S #"&,R(:A {<.4;RrtP`rOMf_v3,uo󯇂JάR㕰.P9ClY$P붾2ފ_ZW(|S1Rgւ>J%Q3j ’'SRQY}:T 9g=[4"[Rz%&e܂L G7<+]ԾDNO[D@Se?`r+k_<;|vLL*"s%4C>VUz Boj#IOѡ DcÆe# E0|{e֯xv ̬`Ud+QH ?*?SH9?`a b/Yy@ZXf[#586NU7X5p4 ۮh1BڎKx/[&N)'I_/.GgJ-y9 ͛7-hQ&aa!];EfQh1m5@&'9U<ۓFpzMqB6i%w8B++I(za(RbKX썱 &dȤ:Kd`¤tZ@7!h0A>Z;P0i#qL6ar-=r7%\]~YNF.rfCrvG Q5) Zn`_>pVjr2#AAx/.UdU\nnJ֎ c$eO5{Θr Om#W9{B8VYwr2:CMu@n{rݚѤ1(b0ݩkqb&tOsF5% CS6]f˖&^eZ|2CQ ZZ݃olyZ~Upc  S'j;.38i5 y3y}d[.@e $uؼT)iaSr+\sL0`u)y:!4&E ϑ‹ot>`Y τ1'8NrAj/>yng{'XÜ]38vIHZ!*<9Lm]$.N?@)|AΞ3KylY:Kv|Yz(ZM~9}\eRRiьNyUp}#K:?XPFD֋D$pZ/n>VF;{k#N4׿l{?o>QPݲsMV{5@,n:X|tX`”lNpч6z;hVlJdZR%όT.%J-NBp Z-xz_/!?Fzi >Piqnl*2w8(ι4:>)J( dد~sI;1@^1p;}$)T98o@jpx0pRw W1z0BGPΔFJCn+w6`M6f?2|pfMgUyg,6˶Y$`Oo}4blm@qgLMjOqD Z0F/H{6 ap\#vNe4*kLT 'ls3hesHA@][MD6!Nyy[6 !(~1XMc+wʡunf/3۷" vF{

ْZ4}uڃ5&?u`Wj -5M,K")0^mkIg4@ cʧ!Zk]:PHL}OZGvM^tam( h}}#6}ؓ >ahj%CV!"a^_jsǧ״JZ}7ƖZ?U&?;5VI7" Л„ m$I@%R)fq,D`nΟq"%. v8-!WhV@[c"qJƢ2J㪓 s<]VVp w_/m]fb Vbp gTc#)6<i*Td qJ8ue0zA"|cE(h{*,?͵sVJ=o)Ӳ$6(~9V6/2:LХ?2&td4CoQbVx 5-tY-cswmEb/ (*̱tK*.tgW4˝lоAjnv76cBpi #܃+DxDA1y1Lm'̂?C`ݰ-5SB nZ4V*r't !5@xʡ=q8 tXB¶V$m901Un79V,Ffl[ѹVm&l 6K=b(7oüCX$kf$xaB}ɌZXS*Z0)pzqt^naug%'8U{ei4v( QULyЗfg$&y^ .ZQTU[69?}4eU8 Ԑbxy9̱0&RĄMf>aG_=Xje)[H袀,-~%n-kPn6@ ~tدU#|khT7BG\bv{#dc( <&ٓgOynaaf֥P0~m|tNdTɪG =vz.`Z[ h*-2}^J.:Q /8bB< ݑLF,rhҬl)60`-fyړ/̥Uzݛ>0w ܣ'|m%AeT<#{pwKzekj`jMڮB BwJ_\7P׹!D跡ҟ{>"Ky,BjЖJ76Xۈ 3"-SI=HcL_ b3v+/\d_D!؍3f6DS;VtxS@\竌ҐkOOyu/F2(^.:f`@QF?# if*6GZUFf¦J3 ,iQ%RY\WI p5xQw7x#񱖾.i.091:&$,Pܙ h^NSZ<#2>p u-E7RI"bLs}^'щY9hY,tԴtrNq8ömJk~%}wXൗdk8x,{7,7aEק- OfYU@ǫx ^иJQbm[|dK`!!sg2C FDy&ƀ05 :j7֙p'+t>L||` Ē-f9 Eˆ405L-: ++*D*0φ 3YrþΒ @s+Go'ߐG] @?`.Pk..y0{o[g ? ÜٿQERF A0.r"n*߹8>/2^wtHDuP(9M^'i'eÊ&AHL='S@ |ɸve1ݖ>*R=$']MCHOb\coeUp;m_|([D[ HHa`. 3Gg1GC}2>Cp o ~ctN@ 5Y1YF% h4y͗;ۛ 6vD.΍ˤה\b8xlZuAp[.>eʼn<ߏNq>f8:EglZ$[jF;hpr019Zs҄U y2#,`8\32EaYܯSA! j,1^([/pMc >23t]߬{%x9Gi~ b3$P+/fxO_oI8q̭s u1ܟuDҽ*fqHty,#\3)T k+xb|g? Ghoۼ# \]cڲhvS5>TS"%ʔ>"In g8aJn+lxjBTO?0z2wbWZsajXGxV Rg2]\gL%[R-[4+I:RR'~Fh+jfQZEЗ㾮z[gmNؤF-˭DPe`gICUM:#n6 =BQqmg/?qRPV @@-Bd27<e@w7t@l:\wle2q`UQfv0[?>JL ][`mmPts)Hgq bŪ@*z/dŹ=L.h&I.>3M_VyiYd^ (/BΊ~ #\`gkzcɇ6Mp>+h_ cB1qx^9DV!W W 6/! en IA#.Q.i"Mah؍=+)wgYe|#GI+bI2{3\&?o#k6F{A;;h" wi8r O'ڽT&ұm4y=WCX6<=U}X^Ȍzomv:Jeu[!. r%LMW:%tJyxC(_z^SӮb!#a+Dnt!K N]]xfQ p1تixs?x\ q;VߛwʓH83 ;vѱNiDP"!1%(.kVQ:֨sH A2m[-\Ĉ={hOWt+'ibZЍf[|~6w, S%dE1u.vy?n 2]LXƌso~shſSHO:(S4tJa1.bz~@8In|-exvsr~:X}cf< ˴FRUo zTHk#xiٽ}D;"- !=NhϖYQ@'EgyǢݳ +Y/FYX?O:FeOGHFJ'n-3߯Ab\&cIQfdO~P# FܧA#ͦr>40-)TdK I&$F8onCIkv\ ^BsiYZ&F3 b/"Fk+]7)EJ*FTj3. *cSe-H抯eZ2'H9u?S;dd)}Q5}HװTG(+DG #e1 `}03.2W EĿGg;X"%ӱWK l|]V ;Cn:hRR&#H '`v1eH% u3k4}!U8y C<#ם##3&˃;^wo3*|4zv,R,:'uЅZ#ۖMiě 3z6Tnt}ۙ/yfQ\a  \=fQ F9T.Gۇ]o%w)ExoLb5(uoT#j1]+}KPWV*%OAce\ ̪/%X?Ԛ JZwN&!x!qCӋ03R|Ak 1xL+)fF@2YhT{+TZyy6inE3̙/H`\䙂*d$ɩy ~)) ee1N=7o|#FH#Xgd+z\\SY1fRxG Je7/S9 +d?khNޓ9}#d@! ~o> t~wFZ,2۽Y;3(TpPjqiNB|Pjn~YjJ-(Ms`LHIMK(2Q$ ] ȵ]tU}FbbIE)ɉ%@+s\kJ| @ bM_h9Fe`Z!ڦ4d>q7 gE0oɄt\խ\Ksީ #AaMi3}쥿PQ{0E$PL^n}lKu@MWT#{wXi`IDz*PHL5; qEoPjp_]hqM<3ha/h# ]d7G@]fmAF劘De8$jo.g 'A9ZǞQS/`.t} zxъvWA_aq / o=8lIx:O vb}P؆,ͯ}vm6;f}&Hw* 4AdT1WDҽCw١XZf8 ݙR9]% zGFcaM5e*̯4Yj)i޸||=02F_bz^uX (xi8SN\fe K, UU=Uۢ 4@dIѝ>.T(q[rt`)Z1M$ Ot.u 0ҲjU SƑt[֔1uȨ:&r$BLEvXʸÅ:Ц8a :A(v(OexMI3(" MFfK7;{Z3%VJRilJrLz by[!,G[W:@`)뜊KBrBˠe/-TZr] 98RMUY;EqʟYO r=Jih%F {6prsou.7`wX3ٷE߉ QɆQ-6VCHTKB1t^xcI'D9Kؓ!c<dsA @8 fvd4bx6#M">-8H pE"EsF9Un4OL UƗ u`CA;ki@pӂ䢭wNO7Q㽐*,ͪՓPzXiz|VGiN^]1|]e =|~F$,x0jpORv^QܐZUPDOl)\-# y~S# nNVv6>_TCbR$/h\N8Rֺ=rS x3:v o?pi?)fQxkv5LډaM.C Bo Tw!#T\*_ѧt9T\[ S>ymDލBCeP<Ğ2NJXmXN!ү"q"ݑ(Qe6nu^6B7͝=~y{䮦{bAzڷIUƪd Cv&gK&M\j<t*r週]0}*ѐ>ҽ.h{2>A5ToͥLCU%H!/SSA9RQtBlOH&sV}K2i ^6g`a.O!E.Un\ iʸ v.~byGg,c+Av,h# \kq6ٌPR&7,8g o`w3?D:bB%yyK~.Ĕ&rr]pInSX^X lBi9\_'jh:5TF5-}QI4NbC8ZzԴ ~Q[ivH@Hq*ȆБqL JH$x{Q$w;XYNG, 󵷆O(όh[¼LrroJ]hOMn׀}9ԑ+y[I^Tk{K\QrɝFZ4TҕH6rw;U 5nRsk?i'җ$2rvo"-'>\5yWU5~[ =n&}gREAI\jT곗AۨW^Z368~ESXI8TRCS<#%nJG#l' AXG< ݖe:lgY-rVI[W_ 6&M񐰸 ? ܄޾ ?A/6LkTjsoW>v^VVHuVPJ2ƞپN9<Y)c_[8hEL]`[[4JܭFg_oS=q]Kc<̼YN_y}H E]>r M 98Gɝfk0L͜D }I&n&p1.Z:nyǢn;:xr7@77;pԓ{VG8@w=B]/^|_N4>Ey5mz05\xU]lSUia-kmН1z Hl0v54kٽ6D$L䣌 &d$j0 1A41 "sm7>؇sʞg=ݮgfw?2{[<`KijAU:)^IŰada]4WG.ҁ{kɖ5FFj6gv88Aޚ[C9hd| ٯ/q,E`ڊeM#,+ 07Itj,%IZ $U?-v3y_}¡ݲBG9N1h|Փ jJN n&IOP'Gu-Uã VLI{j] W t`bȨ":OV=zhA^rB[/j&bIJ0{w)J#T!QȠFL BuDMc5zȓ 1 fsqRHi [;&1Ebsz'Oފ7,)vy)U0{Z#<BVf~Vr$חdO@1/2k "ݣEɒB7ewC }:Z!z>9*è )vL 0ex:Si2=qd#2ZAQ;䟔{mδl'J͓+陆+Dx`?DṢHY~+9lO9q*ը:)”pn% ^tX7]s@;!Evͥw]Y.JaFcFpu FB񑖠ÐCZcUެa<@$DX,/}Pʷ2Ni;I1}$B.)A{Vf9y=6@w(|<5 H}ӸuE~xNI^tp =Ҭ?:ե'zonjucPHgj/21qV,ygwjiݍ̥\Ҍ$ުo5$s_vHN .f>bͳ'اdQ[VeN~q;, -vq84c4$h)+ˮt 6)5ؓhJ_A;;m`'϶wOzgkO[V颕[סwXR-'`lRE)vk*3~I( Bc9򁕛a~%@Ij jtY3MGtv}z?s$X'ٞx `lO|`}i F0uO.V2 C%ƦkZ:amk f 4yw!֞x ~r3~"֐l:|[mK4fzJZ$ { qؖ>#sﲚƉús!yP0⇯OO<YwaX(V*G'ƗRoz6'Y ѵH%>Hn3U(xnhec,c0kD;X5kw m7um:MR ?^*L^iKy'C%|~^|.02ՃuC[u XUx Ovt "5Ɩc/u]quX_4,trgMb% g݆ ٩`-_cgoaDa{p܁Mc㰟3;S\v6ߠ2GW?_!?0%礬)/e s?xz xTյNNL2y( Ʒ#수\6Y{$oxev J~Yr}v! x{MsQ!oG~k7Je{^_8x$(ts Mj[ۗm! Դjc5 NI}m4w]ҹvI7ZzzdpY-dYy׆KAۖM;g K/ûn/3:ä65x:PЅGӰ<.y▝^&u&:bl;L,o9*^;O-¸t-Uִ/mzdn$6vj O&W@ˆ_nZV6-}eegǐ+X~6]_qkº  |QZA 2x=C%PCBpǓd=xj{rtPO;ռF daHҬY.=ە'SPKƖ:!=B8xuhFd;YnrJ 2eC=(Wk@sGt9e}9t emNAЯs~s<L6}i=/pw!lǻ} Qi{ L۲mB"ZPF;ѾIvE3Q;'BC\(}4o;-xC-䴆-M kϷd7Md18Y4D4H ;ƴMvw(Gy:pMdAv(.[IDu=#a%ODb]g="j_3/b|>BNnU\v3uTԃC1,SVygSf,e72v٬c\nMgQytbd)))<+Z!Ca)e(6i;_To 1_.Ś }ŲdzٍGqxj㠎8 XRmBgSPe!J`U@ZO3zؖHaf`4$a ]6\Aq!a!;buF6Zo'⩯t䵰(JN K%db;Nheg"} 1%d]m.0cD&JcHBTђ-hҿ`r찑'='|Æ$8y2 0(d[Z(5VH v[M-`WP|Jb,QU'r-4UCVd3TC!NUSd PiYwR構i싯8Pg^FPuEGA=;80vaH/Gd ;kT 1Tgۯ&)H#p'? T(\2oHA&HjlnRK&jί ]HeM+I=N BN JҳT#K9TXNWrKCEZC=X|:c%1JَtHSV}QIM:,&G%֒-bVJU+߷7%3┓"(T$Mr|!ҀH`/Q ZMHGkH񻦕=rQf/X)J"x?Az)!%~Ks"!H 0rïPG0p@6@M¹4V Rgg< ic}OKNsҪMqK£Odt4$e1JMH :Q5M[Иiq&FkxwdP l*I3In2a2&= C]5}z\.lq'߁EVH5D$ T{^bƨiecXN3 i;wBr)Ywd;MI @P"DIHTv!<=" nUxٷ,}PǶ$SgҜ-;+Gu̼E_hbP.Ԗm̅G\N􎳎PDIċoY9=nGϨ?vPV=(>Sh^*bV0ݎ`dn3w߭ Qd5mA2a?&VF4dz[7C)I IQL̔ELX-{6,9߂iy[!F&5c"Qg\# a`U;u0 /!RV Rf]J^iy S = j{ĀHCƍ,yj%&bhseuiNU%2,o\񷟧 33ԈМb@p&}rfX}xb΀dAԽP_Kk٭BgJSJxSC*UT}][pX 1ȋj7\S[Df#Jۻb?_y5>ؑʯi ҈A}\('(5L.(UpH^~#,nY؈%^ -N;yS~$NoV_Gh߆kdfo>B%q(V~>y9FL5 }X!g`C!O\v\u ؗO@*do!ʹ? ЧJR'pLa< Yi5;y2/)J<#]d ai!X](l듐+zx=ٓpM;ExLE!b9QcT!}* J>ÕZ<N<ƶpgǠY400ղ'z>>T9P/#qFvHN. {ǀB>VsQT('xCܗaT{^C1Û~w fo Qn/T$9' pM ¹#ps)h݄a-i.uEex5eP&v@Twos{sP<${^LW]_FX!d>1SwH~8ہVC^KP4\:"gRt<4 Nw +)9ޅp⯠X-I 6TI#J/})lek^ȝI,y\M N${(eI0Nڙ{c1S+[DA.,(phdG *!D6GҀ0ѱ4Ā2;D+{#ǜ=)ry޺2g>0uõ\!=\)&i4 V)S8 ;d g{~6;/BHL~ ,Ë;y9>Lњ]Ƽ4> Cy|)H^]-[]nRӣ$-hT7.ۨ-+Ć]a&?Bx{ |TUdʾ$/T% %Hd(*U/P$UB: :A+토%St0.hc6{RN~_佻{W{> p"³&6.z$|VhAxAk0Ư#GQpzqDq 8;])h]v v.z\Nr\.NQ'*%%%u N1QmVgWBm+]nZ0Z.wyD\? ؒV/XZSYS]Q]'cR"eL tE3[Zg2 -WGWlݤ*#V7u7RVZ9}bj{u~s\`k>'%~gm}faWt5O?ù cȋۣn6oWL^ȯRq[n5g2Gc#o"Hs^I(K4QZnyvk$TLÈ^cè4 0u&iY`k7.Y~nm[<} uvm5Ӱ\4.i5g4ޟ~9[LRZ_d Sio2fV9(^A)"NL 3`L2bu,xTbNK:5s524cN)`i0?WX6pep--+: l1lvwWA|o!LmdovA_H>)j&:D*h+tRDacT8]=4R2I=frhͣFSH^uj j9!rLI69.#ژU7+pmypky~FDY*;v_vi2#(uD6gӎvAB.vsR`5jJ^o؅ƧX9x$_S[]BhT8ZMek8RJi/Z ݌l͛I!MjԲAȒ?+r蟏+*9P;p ,L(bo}69t68ϡ7MN퐊[+u؛r^e`^Xݝ+E0ӫŪ00@iՕfsWӁ}}+ZgxjCCtҞI"jҀ^V2HCe3 `L9u lrGOK%3^& !VQkcђ8h+n`,W%LjR$OYk@>ԑw]1h[҂5]NiL4Ym (' ==)2mf\6ρ^eǯoMEɜT\^rxWG w ӗfReEei 65RLS}+RqwFuH͝ `d`+7Jiۦ; U{GEO?wluH\gc%Tzϸ =8=RlP+nK#YQ>;`&u6P''_=qh[dcdN+N:I>ؚc]Icݒ1evr&m4F|n.TxtAG%«'yʊa!H!Qn[h#?Yפ" u$ϐ>¨3 :r[勽v8sO Cn033fXR@tiBZ,bĴ}AfCg10bkA.5h H\#5퐎ۚL9[a[1]-ZT$TǙY.1@sZD9QBREcjQqtr?lU e1)6##&f92~U^uM ֝{ݫOLLsf2sp;J{,s.x-}yD$ 30ۗd`@^ch*>:ci}^?Js̙'UhWOjJ*s&} ;O)Yŀn$(,Ļi{Rk~q \w*ȩpؖ߃uWGP=aaݤ4o\F>r Xے^ _@ܜ{n [A#Z4|/on pBh)ՂGH*F Wnn[*>7Xo99X~55 з|lmDԙ*ks UY=`SW47ѽU1};wm} `궽Grh L͹},j%YOrȆcmeuCC W* =+Y2H́Z.{!dUTgfR[ S,ّkH<|OiqIV\3,XeG1vLV\y #C|*?~ j"9o'*JOƐmP t!^rѲMN*~@7cw<)N םcEI ,9' ӄD4MNZ'X:%>NmxPi:=``YX'LU'Nlh Ηz# ONC "t5##K<3\gjTj3JR6䐂`ŻpwKqƋCnz~vF0u"(C)(?3̴Yh%u,ɚx'Xʇ=ics@7Oçˑ* ?fm53x5l?d1xyLt} EmXj^YOSqRg o^0w7 GbY8BHhlm4qѰ ٔd)7G^42ޤCJyu3<!@)=7u_ZЪҤzWxO1Xpl~v&yrhQ{ o2,gxr1T@ pvTupv\MW'n?9\UI-'ҩ4F !G+C>r+D {"-I.y!XI|E!KqW) [ˎX]0>uf4<JJ2Q ^-9 sPP$gʿY\J͐w%ǓQmUI%"MfLWA ?d]IPN/g|X" Ƴ)L9Jrdt*DE0LOzD 4W${E~YevԪOVu)^#~<*͖SyHm [ ?0&w~fl{6V 1F0o%-()CXL TC9j_k -FVL<aGjMh ޸N!gitИu@5$yLS[Sq!R ݜCT吁8/k\fBH3UH2p U9Y5l==geyeRvIlL\EE.F r=זCCQ; &Hb&}%9LȐdP>wMl=n  )$8|$I Hl)UY$(3"$@&5LZH-;`̐ p,vT*+3I&7QM MtWCj~ H O +|۩X+@-Py,R6|% \4<8 BdRi"=QvO+"iE i2\񂳎Yɑ1P:FO.k&l ,xir諬y335PNe%i; i T=I+p{ͼP^*n](%yn6Iq=LJuA_Cf.5J>4l.b5|*H0^>hԸ='>,"w;K;(vxNpwQyBP>I>gz;Dv#󿇜@ha!RЕW%d[^*NinTn**ΦKNSx^=5jgXv ?%.0l\>%X/;4A{Q}H"}.h' 0[+)u]/V%TdwXHa'pK&QX:658Mg|NS[3&iǨz5++`/-qRAgid0Ï&iTxfS/`,wUB͝ "/,DtgI IoBJ8E O[}~27`h~%( HOQ@ƕ\+Ijit{5_Iu%5u{/9dg)9;{ǣg2(fɢ+Ym|p3{ucPT a?= /R6q^X%ݐQ0$Fmt<'>形p3PZb  #.l$C(N?z-TE$wg\%zt@::2ȓ#zs[Rayj,t)_:\H ?^ɛ1jZuMlD@7@nl}C.YdcPӐܠidTE'yK7fL;Tw[^%yBo{ԗRϺ#x![{udM*$DN`5CbGoX&5B,TlTtKNL#KohYAe߱ ?TnQ"n{RIqaV*C\9`֞u!B6UYR.·n&1Sȴ@9G\8͂ /f{Ī,ڋd)5I6%mB\J\`r6{rt;NtKCdgn] kd&M.uP2V)rT1 e(=MH jB˪pdžL*?O*L M*oRtH 4!rf)yJ.yH,z3q oD#xҨsv s\*g5mz[t#A[S+yg!P?GA} Л?F˜^lo&:HDZ]}p!շҰ?WqUu xwoQ:2~c:>@)FvrPY@J(^n~dպM&lɂMd1aCڻ*)%ktͮxtI*5;{g5 V,Fb܂ 6CDPE>\Z$hCQa1%T^C45J2@cjҴ_(f2h Lˤ3:_ԺoMEq@w@,~rӝ܁޺y߶Aިl<0#R-pM ؠxbN7`.< DZǡ9)`z!M֪n}yFݘXɽy> 5@˳Y #5/x hpz?6W*z*v$#P*3*" #"^/OJ:5k2.gwt,;[Mvm5 }Wm~ų ~^; ב-*N0aF!ph?q/lk(Cqj:ߏt5[oY5}7n@mأW?@p Sȧ!y`Jw6_?%BtC%O;V>RtQ ?J} %ɂT=D?"ẠКP"5e^gA?.ȣGak$ zC  [R{qȋwfKK gK)ʚUtʤ$ov;{D9E斅f)h oiIdpw+x"#H\20 7J'!U4ñ!}l]!rK(AN=L ]sӥ_WkY˟+*ھprSdVoL6QGxmTMlG9H\bF4#\\v&8qYf]$U\Խ¡ RiUzďB TPFg7{9~$G>b=v㟑 0R?\,8VKb~x6¡#^N?qd,iZ[Em r1b?jYhi&A|-#iiP**X*W^Ts*9*Pˤ`bbaz*4rrvar G'<9#KU^~ŗ ^D=xYSӃTmZ`3'=ݭr 8]??N7ӭ/];ؽ>FȞoHw|cl8o vZKl nƨEBD'/8%O]xibN,[h@5M˼5Q+U >-=0MݳПVݱ^/B&-*QZ"6\KN2qo2!W>Rce1 dh۬ItIӃVP[ƎFL&B&?]3d=Bcr Sʪ%D 7{YIofMs&]tQ{n {dWm̲Lh'|%Mm[LŚϒmZuq>xY t\y>zCzyJJ-ze Y%y}{eڻ޻Jי> !&B@zBLJ>&@z&Rtfcw-LLz8Gw?ޛzpSI ߩ$'Mm@Ô06 ~Nq^KʅR[^u"$ӂ_59 Mo%oܰ1zh@M_%EE\qvXH!,̘&fvyXuUް8-0%3~&OH~ߡa jyuXiDi\Y4~|(g(}R7‡`a]8esl@ 1i>O /{q5J{rײI}qo3֠KǙ)ʠ-1<_V~UQy/(/< ߧmb•s(5<,a,M./Zcv30$]I[Js*LݗW1ABH }^oz]qőRHVԙ ØER18 2(K}ƹ@9+> u֐P6|\hjEEa]> pQ 턅 ;lmn åqo 6+OMQ^lT ՝w[PztLWcF#<8P>ԷCff /08,4!,Jqpf"lR9)r_;m;}!(I1}q(L?mTW Ϸl8o"T<9@ًٰ b(bKLԓ=̝hp$rP$CbVq @6[Cfr@F_,ON*+Qc͈ SǺrW^> Djdq! J| IrX =!xUl?n(О۱2A!&̸ Ʃ5lήz6\x0,6׮}~x>r8 up朮+&qLgΕqs3}4)sM5ԩFpeoЕ8!JQ07 OW(#J}kǜWboχ`GoKT4=B"y1B`9'6@@w|oz >,$7OQ\OGzM|xϞw[9p~_*HB^3MS`]u+ood/ݵ.ܵը@Ș+Tۣ iVt@pv= I3 Rz-=Z UžG4UrGcUx'qS!xf B4J=BEx4ƍX[ӎ_OI,ɹYaN#mto>4h`Kf!#ZOQ*0&E(zyO7E|m~4DWk?92T򠒀 F_?>v:]WkLJK'=:3'ӍLWe^Q2ɶ1xjO\΍F߉҈rd'=tXA7#uX^-*QnCA ك: $\>~]x:y9%;r)U/&MM.dڋf{d@9×t}_yge]+L@}<`‡J3x~=dr;ib utH}xe^Ԅ[沐,:xat4oqu4*ݗԋdO!;*P.dU]~92F,FTNƣ_ 6rň&'ITN{=TǣsAj| ΄YOx!B^\ Hf]kYK>I&=ԓ &W:Hn1\q:l!Y(L#,rY+}T;ru@Ky_Zt*DW? HzT8dC!fCwWaSXiP+({gף\yH: ܁򭼮hIa-:u&֢g9?֫-QA,qeq _߇ LZ*y'RIhCpTΣ‰0p5`0s,]o@掸)!L}aw9*/Q)aRKIa5҈FmTê\2Bq`[KWƵn^."KÐZzJEhU[]YJ"AۅxHI*QZ#Uh my@ &9[ yD+:4:_dtZt~$+78@raɏȕ ,#$;c8 &CuT,#  {?Y gT.Q9HB3]7F ܶ&I5I=(9S/č B{1D]if.?5YzGoUQ-t΃J[Z1+bWyMqÑUhaU&ɡ-n rیc~֢,[FkCuzscoΆfhPqY"}rSr[֘?͘f-r*י\Ond] ,"!_^57yi+z vo(tYa"V;ej5$u޶<*OFԢÔǗ:K<7 LoAձr]mC.QTVs4r(Q2cAEo7;;lc7?U <#S+ĐjAqco+*[tLcӈ%"us~0OH3}zog^m/~|@PcPX4#-`T)ѽujB[y Gx Zp,~0¤m7qrJMm&;PY,D[=h3\_v39riDhgYOO-]Qw[GGh[{WF?"4^" ҥ B_lB B`X%'$d\DyΥ[DIV¸8YxmRAOA-춀(۠,&"AJ(@AXZ#Zmwղ ]!/O DƘz ^=/=Ƀ1q.}y{ɁkO S먅oN=o7BЫfGb_F"0xf~m-ހѓGPT>hދ.46^JOc7B4xz4Yn!"xf8-Lo/̠2Z3B ʊQ4a"T h: M %2" tDӃ͛ieexE,!a.297?9U5 TB'x00Host0Node=13Id33E]ղExmWG.RsybE @3ڋ@IfK f~}'"2F{U񞑑/{Ӳ8 p:)FoiRʢ7.i1EYlbh?.^\I4,=^-:x/|Y\.e1MIR~8.ϧE((ǣA7<.:u0ktt18)N{?Ÿ<.?'E38ї8Т7aӜLckmOް82(r:~Ocy?<*zt:=_k6}Q?{Iqҟ.'8]ӽbsoYpzdۯ=}ӭ,բp>.'Xq'B˓bIqi|'q {{[oG?aߞ4zÓb?O{S,DCE2}ޠxF,?ěg#`S1ai vFcuSvt|#|%؊/>O7صr\{@I8xZ~eo{S >:2vGgxrsf?,_8HHɣC HLwOjq u>*'dW̓q>\@T<e\?yOYRWcH<Xp j08\N s <QN9-{-I#H@wr::}AX=|t\]Nw[ yƎ>/[,<5/$hnr=P%StAkG߯[dkT.? 0޼zqyEWa]wTXǣ`ttAizl :?-&Y#v m}+Vq00 `Z`NKKtނ/LK5(Z=,pb^"ct0An?zb,nwb{{cO΋W?lnuwv7| ))I(kZ4O=6t)񕩄)RwLO(dzDW!|vtx?_']Z"ăkx7t`)rƛo^>}ro9σ`b|Lpxܿ'5$"H=`)C .FVw'υ-~nKzGت;{~$ y<,&%`Bs.>XoQ%/WҠiW/aU*?}f(A~~Ŧ9:, M433ӿMCcʊqGLW)T@\Jc`gDڳbK%~bj b4l5׉:wܚ`&l߽>ju-ȂNKS':܋oS)Y(\]3AMLs Nym|CP9ͿIgU ~Ԕ*2 Qw2 hTW5 jM|j : 4{o:SX{Oo^>`":py;'DwH!=eh I1HQ;t\"RA'#f) #fL mSYNٿF&*rR̦Ę&;rGɤO"iGbPDGrDz"ÄAB̕BOy/0;1Q+֠]X*323?;m`\Bg禢IM,%,/&ͯ8q\צxZC&44ÃƄ0@M GR$i{ I"Wph"mF#jStGjd>vr HH7?D=H>XF~&GYO{Bɥ)?Sgq^pY =)o7qxNF`KpR}\ 7 v~"7bAMچ @cvk\SϭH 83AY $6A疢,?B8b2f-K/Oخ#u/s]6#'ovעc(2bTEk0>{SRL.`Bc ~-aH1&SP0 kُ4mF6-:܇\ Dk\dc[].YR ~e@`3`9:LpN,_ Ġ|Gzl"<'a :I>,D(_$< 26d6Dhr]< xx*[q{֡ d!\E2g ^l8~"DVH7FF 9Ҩ&5>2 Lr)WρbPA8#ИБ÷ '0>x4AOq3 = KXc0GbH&f2\q?24钬 g>!%V4'.(.ӫe"3Qnht^$u<4}mG+˺q$;T4 LJwQi6L^^%qV\nJ}xo,!+`_ʡTCQlׇ^Tx:Ā8|lI@턍/ё1Knz++C܎:Df1[J(VPG50h:lA$Whu+28Big!(ߢ Lq}C'+-yL \arc`0H!AJ|ހ߲TIFka!;9us-N.׫@1}n,z/@tZuȬc=†PW@AUCZ~az 0I:,&ţ y$Bx?餙y iG­GV+ϲg,"c ܫ}[~p.?ZV NM3atgHЎ9r 0jt,h'^y>1t~ߦ'L56KwGl8_hW ײk޾Vfg nY/Ǥt 1;wyL9Ըl =n@ȜZw)`$@#4eKM'UCoE09ٟUcS$\1; {.CĖ2-.s;#:m"6=YcL@[q@iddJe2W-k`cTNi[E P*s_0y؅3gP&nwߩiMU6iL$dLXĮU\7#Q() a ^FaFЛ I̋M5I]q'6!9/@O=!(P{J 9 x]/m.2x#lmnO7'UHx%SΎsRl}u#W}}zj<[ ƗRrܫ RO-W;.nx~M>RiÀ<}]'x^Yָ[aUϾ: n#L`s⥪Oi2HhH kt 9I _bרΫ3l5+~}f*9 w9f 0^Ed&Ɖ^< $^_ C]Y#* _w0 LU:-u! &w H!GZw0bKR,B PL%cBxFZpf^meEyS!i5H`Β?LCv<<[ mkG[~V6+"\uQ:v26gT=IIGºe;wzqJ'+ u2BDPQ}ӐqZNbho&ЬVb\3֦Ѝs0;),[;b y .+~bKWYn85N:kZg1S鑶,Å`]&]to;R=o 5VB( g/_>zM5S%޸|D}jd[ d\Xq\h)>Ao;~Up1 ~ݍ~w΋[1f#е|R sV}7n:20Uj!2}黐niR%H=sP)f 0Qe,&"z뙈SQ2_ =}˫}痥I:̤XؒEp| קzc/иdk†$@7&lϓQjk*^&~Ֆ#;Z!PI=xVMg7" ]S56X'x|P(÷x wU9; ̡=bД mR`Y%Q>ZR?u?`5@"d&Q &ϡx<&biTx2 :UbY]턣!9HLfiު g^yfߗ_®U b9|4[VZhp|#pf޶>(\&"̣8 2T{:쎐Xs hT B{BP06ciá:B7[\ijSgm8žh1[7+W׈g HI%QMC`^@ߢ; qp v{קwqMðC|CXҧl4"0L, 8Z]o0ȯWt)Ϛ`5a1WTQ^uczl˸l |P-]?%ヷm&eDmoĽ! آȅO w D)dJTfj ɓz2 oXA2 -0hM$ >|8\@sN>2&LJ6$q۪VB8*IFC ^QI@FOZVLKr؁= 18;- PVۚIpsK0QjG܂F"% TVV̲`;UcԂ۱jKs6a((.EÄ%60thmdSG=KrQ()g jh>p&{ЯjEn0 Rf9 `mD$t @Lmr]5c!IݮCĈd'y+פ))ޮ._8b5IcV#ng pK GYR-x019MIyZ'+9^m)#]@ + ;2oI,!U:_|@خ6sk]\˥ͬ:f©.fZœM0P QQH%7(R1mQT2%B.*gB)"O%Y Ax0ҙ=ּĖG<T\H"1.*,YoG(6ܬs~9C:=4BE^hƟ~Ͷ7Y[wb]or,fB> ڻk>_oOEž?<ǟĂ*o߽>4nrb3ӡ`@h!Wzֺiy$-qg?  2!jGe5ٔ&"lH]L ݍ272P1Lig?3izE.HL, soDƕv^eZ*Qh$DJ9VA3+.LJz$DaNKG&;ߩټ{ y}ll>*MX:=Ͽ@Pg`%VUPzcG"%3ذ!V w>NЏbtXZ&7[a&s% S֧ĝ'ۺe<?,V q, V7muo eD}ك!$b3E&!HT! z'L(M^,Q'.a {-Î%ƭ͸E0.nNH[ދ~E]j|a#ձ hY/3'L<\ts >6;806Ay乡MhqAS%JpEY2pna 1<)}kF^)|;#T8{]+Bo$Ĥ/ȝ}nCO#d;q&8Mjy@ ȧ,tBy1*enb-WZW\$j<KRB Lۓqk*q7ЎRړG_K EɾU˘lE V!e -WIx\~(/eZsF]S*JK63O1UQ6_nojNF&v1Afe*p؋b3L] h?Y!#jDݏ+WTR}0Wa/ $08&P8oa&&G $(13.p)?Q]@iȫ3XA.#'[lG]bE+ÚaIvW<8ޮTpt72<е} Lu’`)fV΄̊Ilbk-ЎiWd_dkd©|]Kr>¯~xŖ {EP&Q G A' &1+32yɸ(>0:/nU.,^볛v+,m .'U0 sȘ[װqdDP W| y"=[hU"+#JMPI¹ Ĝ\=4Ē[Es=9z)xp1'& R^/cl b4' ɼ3%]S!e8n9FcG,%}C̒ 3\@xZUẁiS.j /% Y@sS2rAQ,ˋj`K\?cDtL`8LxSĿa=siZ1Ai}m.}!K+c.̨B/B8Nl_Ľ 7ٞ>yx}c1I'p\9yKsܛ 26f Jse&3:s6 &?"9Ъ(Du~3&F1Fh9=1>7S_~"p&um9db_ŸL:)fkc n1j6ASr{  A ,&J>:khATS8WhkOn['Z~uz9APȐ &\H슎ݶb~n+]'=fEGԤk,[٫spdI=n-IMR`h>ؓ>>fλAI{{i(ȍUNřW{0u~g$A;޼DFV㵨:HA~*(]#Jfmj!XԶ Z{.##C}4: 6woδ3^ X:(U&G(~!#d OIoĉ5gs GwHIXտ5#BшpX֚ҥ=j.jnx‡v6ȅo3TOd^i KtLQm'R4 LŠfifD#.|u@-]nbL +[Os1ՏfV`i{*9 z4of>e{Gd;J"f%iK^7 #[e7%W)xfY!j׭N re;:ɕJYLVMМ iq9EiI׮탅(vdG8S9~L9L:D A?3D?2shSi.N(ߠ4#P'9 Pܠb^kaZjq+H@෵Oa/حY+m[,VH\7Ն옍(f[tO˥p,=V,QwNEO *yEkz`$&s\G"eC,2=j48sm}A88 @IT%ԲH:\%syb瘯"ңh/un =JKՊwLc+m5buRtxy"$<cǪu3JqIIUpaވPGڴ\D8"-N{N2"c8Dre}2'3û/PQ-\az> +fp]IԺoEIy0STBDotĨ XsКH5֐ 35B%/F\GZ_2նp_~EQʭgkm[ym~S(Z\W?5^K\HQl!jk3T χvY7 ͍;Ff/3Y-0Sjs[O[6Zwf]Y`}+cwb2Ô?N(>}㯖CIq@ ptO=8dϗ'Hw~o%@!32/akgiYP2vhW"a.Zd'Yץu=FDUYQ}]S"sЮ1Jz?P5\*/=T)MG REu ~K1Te iQ"? ﲬXv6: ;OZ!dDNտu*h?`S^<;EޞO:+TGf{jU0ROU ,㦥9vWri\2˵g-wmE c8qa-+L$Ь=W`E=!%5Bqi ]ѮqgI\hvޛzx0G(@4ב0;!/MT4!àE<|FE8;t:69۫"8/[fQ>#$TH'jaRG5bo9zѿ%2'|D 0\IRx"IIaW[a3S@%.Ơޝ◖yyYT2 L٢Os  -/m*rX#?sQgH/f)pg|vZ&3AR pTD$ 3l#],O[@6V(QLI2p|`4ŰAP$KO ,ea*g7Ch  whRE`F[E>:Nc\UWB" N1\W ;JNf pHT_ˑ7&N I*X f2@y6SЦ ` FE͞1ZVVJ$Yg7U9 _&vDr0d]Ď$q#Zv2"6!WkFL&- *#L56P"(Ug3 =m@އǿ5D{XH6}IޛBfU6Y]LÇ='Pʦuر98Uٵ^QjUk?u# m2?L j/hG&f_3LA5#UVܪQ-Fk"Ƃ"h`U1Em|ź $|f5Mk3cu/8h'"2 (X. )}d,퀊Lc/t뀃UƓ=48N''G٣?]pP`\a8 \]tj9A1S7X`pvи?!"?8^hSkᴧ0=g2eTE nE}4wG*b+?XŹv]]V4s}T:PE׽h7 iIy@ܶlcijF,һWQG馏3%ˏNB-+W<ݩ,`hte%#v!NF2m<O!ƒlۧ!-#a/sKoL|&ό_RCZ&Oz147qH螒Eۂbwq8x⨚]_JJ71Aޕ ú vJ,O~=<2ݒչ@1 J+Ɩ,E^X~٫gt-/ 2qZH+9;Ag$WNo2wU; Tc&,μ*TsQIX0Yr~)15O LdyѿsJ+Ryfr=zآHcR*db,po\]`\ttA7}wIv?  pHC; 'Їqg6=1qB[ۙMbl7֩Xaڠ"5PmSk82R{d(UM$ᐧo1'uwيۆwQ$Slȩt>qg=걛uֻ(fW{y\Oӯd(b)&y?4mDlurJȲs:1ؓ;u(FŠ0PV"q#!n t;#AoV߇HGyY6`C~k2..COAPxcVG4_yODIF hjb> ͚_(l'O%@KzS'@#8ȅFέX0=4& L2^P8U!Q)V𷠂gF֫B(fDz#WK!-eǃ\1l"bVNV8$Rqit-1$/_#HH2+ b maA7جc.y(;Y‚s%_cK[)rIUc>%Ox:D"bWCfzLエOgلQ7@$G.⢵(ʔt4㏶2$؂͌M@}$E] P!w*dqߐFS$$-kiaa#/^^h\WBt. ~ Q͛ɀh:'M'‹U<\0cbs_ mpfn.#Gqfc,anZ]D¤DlLI_N̿@Zi0!㙘&RҚ`SuRI>,DF[3I!8($<9Kec|lt,Ow|@>_olC[4,$RTI7l s.g?Txm|:ŷ)`Iݸ˭60Zi3&ws e릯:L pTpݸ-&qW3O}sJ}-oiD Ak3 XOnhг3۫ 1 gڱh6 }5LRF`C陸T)[uiJrAމXwJm#@I'w28: צa Me)rۆ\V(Z|lDNIhkTh" l@E>#kӋˍڶWeEaP!9mxqy1H`(eOf[{`0Kتd,)ࠋMp.oQHbjVZ埸L_c2!u Ps^Gɭ_3ʉi4hŒxʻ{/7^]M O3./s=!yDUHDM{STa+z lW6o 7{TpDl^Rq::T[22-c̀6c X q *[HzJA k1 O:@eK˛aMн5őb7 .#"sr(yx.̋ډj^a/7Z ì!Dtv!9GNъRBą'++B:_lX` [$MR'&B+˶(޾+D&L?XʂMh!wwM!Jn!нB Vm3u TBdE%mE~Hc_|U;9G&fYtHR0E㺦.hQ$;iDg-\Y5ඝX$'7ڐvgcAAuf_8\HV*Ob<9뢼 v@WXꕅ ]*>*vuuCܼ*vA_kY;!I E_A! T/=x?56B:7GvHߎvdcuiKzӔZD 1I.CxI[Ό9 d"üal"[, #±K:>au[X#fh刊#tu@$X(6ıCiy~Wf<&?*G\9{ւo6q O9Գ6;^RҡZl3CR~fJ‹g7CW}ǞLmܶO:C$>%^&l.9tHOoFr۫] f?#hHr].qmL"F >lx1S3HG ;Xc|P)k@A\G"^E{5L .tt+-pg8 %Cn^c$Ʋ|RW}̮iJ Dz }[[h2ύK@IlW gmc_AGJ4z'OpY/a$Œ] 'or`)ΥEoL$*3oҹ & 5c!h@%uMV T51֫>Z1D@.ǘ\tr3P@TJce&fu1Aӣ"4尓@y3m܋Dk?U+D . z4DIe9,^0 |ƫY9?SaE{0lv$TNFH= rKnRPL(: iF6_7{th᷿d(/APN5#e?{D] 6N:F$* Pҽl|XA6sh_z$!ecAUDgzD"GWqy#[oUn \FJqsJiWd#@ İ Zsy31E` >^/Y,$,QVخ93v%֡iRd꣄b|B/ă(O".<§onRXl ^-dy d_AŅlg06J8uH|ONIK*su3 JrY1۷9|ѠD&?JJѼކ?$CuBX BL ~_o 5?Jdȗi51I"t-btO)l.l+< p85T4d+tFQ6_x(w< YDȢOhĭq6FzZrTe6_j&[!Y9o.9l1!>,rhVy<*M9IXс\X!ࡂSċH6k)(7B"ؙ">VCJ+WVX$ Ų8PṊ~'\eo$+![ , mt=VjU4>Er ('{D n_ﭟ.S1ϾomIW-NjIiy> Y /$1;!6kӹm 癶 ZVg97 PRM{ W-mA֯Sr&^Zq,瓂w$A ^{3JdHNCNG7T!%:{s~ď`{pAd]Uq*1E^lر<4'7ujQioUV~qW D3v}*'>kόf۫N:#cWB ţѠ ^4*"ǜYZ JDN")"pxupe`-a=%r8mUxvZT𬽪QqvGwV00|Q&c~xSks~/A5 E~Q jBppPqa6G7Ni-J-:<\}X޴~qI%D! #>0ﴳtLs%#m%1 ŸHFE&_#KiHV0d0f#91nA?tp[(bWMF@qVyR<>bp?W|d>b|Fs:Z^`}p8zY) wĻɃUJZTWMA t!P# $wNU|[490쾎բ1Í/>$φ[?QEWOuGG匝 CiAހ. "P ބNe\`|*a/{& bX 1ĽXP-qBG`j2ΉT4(x(k}5(Q!JFyCPsW"x=mnؾ ݍsF굓! ~\1ENoEd{=4q+p)yj0ƌh IZ҅1x@w(S͘5>k}VJ?KܻWp,P̓@5'ބ olsS; x:b$V"\G!4-;n/D}ρB,{jr}:AjO_G͝(xB4@EA/UJz-\b,*@c|6Љ3S@jZŪ +~ctF1*ܱg gR93ج:IV.CԄu6[ 9gnslRETTY pYmA&\$jXVm/Y`5O]@_F 7 ͐bvI`PN_N&~ABF5bh(YHM[#TLlQy.ph QGoI9`w&6fg *82xA#Wwʅ_><=҆l15aQTz*| L?*PFW:nӜ2 :3p &9HOaNv:,1|e'dD*Hcz< $lKAZi88dl QYWx絢ys=$.ޔ  ^jotm9t$#g cDH)C}?S&Yj̇[ !֠OYZx:)c}@:9d +S-)03`CBIJ|fuV (S (׽ߍGsUqN!&+~;vتУGGڱ6x1*2gzA63MCԽ+`^N aT͸S}$g~Io(x02(':~ܙ@!EDDt.%4OgBkeT[3LI AƲl4.#ߺ#StNء0ARx$k6}Sأ.pA@s} 1+ILoIb(Y8 GKc F~d탏~w!G5dl_A [Mg잿x'3;A!FV9}LF{vZW1y[䨦ى:46qbq{+j Hw?gCrgFW|a/vpvvc`A0D럹 [A-9AEl-$R֤Jk7 L щgUd;;ddLhHG:ffzs)QedD|&6բ>Yr?bq2W5o!nH%ABqV9Ds؁gVNض" -@}tZhW?8H) b~3 4+v?~т˅b/׷v9Qh{<>y:-hB+E o㝋$-%fbD+"Rt:}\lWM" v O]hrfejAN{r6ԨuHEY-y?n=1fYjoPmV4FTg6% hR+> j+8 1.GVsΛe"߽ou.leu}5>c'r]YQ+w#:,u B5V? xe1'$ f4$ ȐnJM-|.N5:Bt-EH 5W=ЂBr ܑi]8oUǜ5CbT^w}?@-Df]9GC!(qUkcğݼ*L[';n)zgd~u;,C `ׇPjg(o4Wqon *SIU*xH ̷KU=ڀkuDF,y#rzq>P09鈊4Q]x$x50*Rȹ:Hq  |#v`O2s{4n'3VgN#DiV7!i؜|}÷2Ν'0KEؐVyy|[3NV¶͒1VOS,~z| k凮./[=9p`O'xgKԒNY% V +#>'+P$O.(i6CG=pdy1ċ VsBk>)rD?- >k N2: "YId$Vf>M#ԙŻ`g[e#vdDlc|."|Pc%.]Ha+ϗ%+%n+op]Iƕ^&V/+`#M+à2 8,}aGO͛-4 +T/qw^d~(~n֯aP("?9z5'}#儧Iߟ^UO7=^>Xn͠?pfZߞNq?XWB1z|͎}>GPuZp䀣"mz/O}G0 ߩukmHҟ_1`nad'wX;^Ţ^N焀E"L )%괿ᐢN؍93UՅ9Pe˵Yg̘o1xw6,RLH<q }Ⱦ!=Mcyfw 3eA[qTwr`tHǬbtbv)IGG lZsKD"ĬCX-kUfv<ᄆjpb/JRYsFgJVd 2O> (S1zG4;ԁ %smqvHtmt_ax9^G q9lj].{zı6yfZEΊo`#"KIq@t@VG}?UQ@0Ln*'p> hz=E%69)ȿ9U?cH on|LUJ*-Lo׶J7: dIG ʾ B͘ :]H`YKh$kvT:dq*GaASiSf{P=}jwecY;aE d+t+2>}psgwCxrj٪7 cI[C(#y4Rr ؜G  023ıX 38E^t7*Ң+&dUQL&8 5ƗzFJ#Zae!gр꼮9J *d}ꋙB7Gb8$ey'F(';'=xnwm,QBIKQ9J5z}=1ظ{:lL%w)@s$GjxzyZ]5xO:mޫ>#!əNP})Ўӓ0M$%:dU&A?Ÿ?pRM@>.D1#^jQ5>U{?FeۻN+,4@=p,;Le@gRG2r' Bĉ~<>DƂ;yja`X$Tshmj3ugv-ot)Nra?8nZnwA7{}H|cXI@ pdcxqx>sS:kB:ċ>/!e!j pPv8p-kWE ^<D=(~:)_Y]ƞiPOȮ(0^MkIk]W ti2 AU&iFGu,f{ JK<2 Q BuRNj^O͹z4|8ARA; Y<3_1^;Fyɋ!{.ɕ! rtl|܀,ҪT-$=Ma;z&Z]$I@%S)fq3d$ػ|gyid,ΆY"3mO@]^zMxT.i,R4. ,8 Xee5PxJh,ߺc:63J%I@)`Sw"c!+5̷3vls(j= @:^+ T}YvH`*R+ׂ7BE3X4> e @|~qX:a$jM3̼nd1d c9:])viJRaG$Fц-|WSdz@ObJ&%ʨncyd',o:3PԚ] :nUS!DwҝX9{ YlcjfV-nlhf1)*f[ňwCT$lX?ۄ_.۟g\dſ7On1 Q%ڱi^22]W==ag@42#NoEC L4o,CZ@ -(^-*#_%N6eTqͨF,=K p5x) ߽Z:DB㓂@ypD@qx@vbf;q("^2iX$w Pٴ#-.XNl1@rJGh_OM'S地DU{^/ ^zaNU9|iv.X)n զ/uW,'4SjrиJQbm۾dKh%} ZtiJd!w/5 7}t0}Ղ3 # ǣpFWܢC0"{N PRY b>'n0t7g~4pDꁫ"@ai[-t4hlvR6Hyihr>A7fRHszمwpOHǟ5aW "eUZfpYq[о,ikwgʇ" P}EN01xtC{4'S Ȱ7vJwsT]fԨsy1^K2/yl#ut)@Jz)%fϫ6 1%~X岸\QX/Sp0A$2!;Vyid1A=nw~s-jprCaCתsBUYgqOf+P2(P!Q\/pMc4>23tc߬{%x&>Gi~ b $P#/fxOoK8q̭K u1ܟuDҽ*FfHc_!WEpli H X!a]KgP[,p%9f7Zml᮱\mE4H\D{{O)Dʔ>}"Inp姇ax 7ĕ؉5*K+0>^S.E~'{Қf:³Q=ڦ3l,nK [[jaWƥiNቬmE,Jmilpn t36LlRVT"(3b?K>AUM"ڧpI# կCO&#Uj H!`,_'/k(82nbaaD] ǁVE&;D>~|Ra{b]am8q^v8 U!V Kl>! a,ydJ}}H3<^6~l'1YylT#ߐTՃmU}ौJRFOww2Xd?#&gR:hwlJfett:?/O!YCC#*a"WV(${ LQiZ䮿X)Ľ'VHƍz"=r-lo#Q){k>B>M%εE3.j֩[(eW(֫zywv]q|7d $T9FX?Lt;³M#<3j;#=OlJZ6̈́jX72w52wΙp @ݝb;{mY_;goea/;xvbdp<;<$7+q¬[gژ23IYd~8!4⏍Fq˅2bŕCrb5 NؚW_0\FT.]Ubo̙T?v%WŒ`Ve;5cKs$ykVg>o=T.^}Yya3V5$tƅ,{`!Ie92YSi=篆1X`cxW&fUh@ ްơk fP#dɃd8(ȡ:*Ѽ0"quذGM2Ј lĆyhٛ&1_I( &#^dpDbR΀oZn|zI ־ _dkoR@ mppQ*6/chdZm</k)ޭVq: *Zx3d%Jݿr R!ݞ߀5B `D crՏ( !Na{s;.vp~nΐ('4e6qleu/0nZaǛfdu)Jv[! ί)f"W_>\~D{kR>j&>8kt |=nyOIڷ1D:J,Ɵ`+qe`tv$.y36䯜e1BuF>fUg{;x#:Ӎ4@ Z -mcH.wҒo!xbʧ}:W`M1mVLڭ3V,I6-k`%$SlH(AZGTy6M66! :p7]lnlNG*K{Lʍez MAt__qwL~'' &9XP6Ap` ֘xm`/u W^mZ ɢN!RUo@WO%pol/~hG$@;HR>hw.,+@  [ l.{vut;X0k ՛xcT!l3w>y|v |2Yrk*~2 /3 5f Lf.hKI$pKR̐\{ͮ[8P':M FX d3r~Xil N2oڪ[9ӫ! R/ hY`j5!fuP3i)ELx ;1`?dl4^SۗՍ0?ӒBEEmN})Uj#䖰R5;6qP8i`i!0 ¤q^jb*=-z;S͸Hຏ_7`昦_˴dvqy_K4|洩oHytrc1a{ϗTb%=S,=$e1 ` {#{*[ i?jsu}TKztۡğl|]V}Ai9| JI)< Ĺ/r#ay?0?{X]|7#`I\inpK<7pݩ+)wF8_'x4bm kWaB.@Ƕ@2 x_ɞl~.랒6/yixeBܛOwqR,E&0֠T?Y/0l+kFE]Ba'`ieiD S 4'XCAw@?a]BT@B)պݓM(NQzD[#Y} %11!|#0t܇K|L=r2a>!kæ$hoPϾwTW;ZOMmC2>6  #$wcpvְ{_G q)lH|*0`kY¡ `{^`ZͺVfH˗0wƢFX`V 2K,ŮB%Z,`߲b zS-:*>Y2 V׸֛AWf*n R0sHyxsz2~A $:Y(N>TE]\k>CgMy#g:v%sK) =5̦eÊi5s^gg9Oly4#Ƴ C(OQVh mC:[,EF ~c$]IpY +oocz-GD[%9B9T1>'?KġBHJ|u`%aQʊQkfؑ=x0 N *1J?JP0`,YǦXԚ JL~6z t#^j뼂E#O=_t܃s$xT]LUvVVPȆmvĤ fgwݙq~Z nb}x\7ê1lLIL ʃFnMʆɹs{߯{ԣb" G}IY7%[Wd^N=@o>+f-#.m&1Ch%hy1 ~jN戬8a[X%D! 44hڢe iIjj=pU͙)0覫B o&e`Kf%qVZtɸs{yةK C3 ؉1R5P?q8*`Wı+ YvK0pc~8& j*9HDsE15HXs" Dl8/*xqٽ7ME&ZUp'Me|e؄^c짟Gt~ 78F:F}=Mm]n'L;!% HӆzYx5yft;8c. 5l|0Zx^-!vZw^\yg:LirߘhNs;ptv'3&&=?IWoDzF(U "F@2,ȶ@w.<՛}-䇜[!qls\.v<;N.<6Jt"/;Z;*LGE@8ՎzPHJaK9MVJ~ԃ86GfbEVye?ٳ*PB+%x]ybt Wh_FMt>סXzr!w?k )˲diR"_qv9,u9B!s$(?>]uKybrOt>.á0LI6*8JQ㚇pzVޜ# ył /^>):k' 1xDUt5ʮK/4* ڼU2xVmhSWVk{;v椵,Ԯ6iL-8B^-&-6K-cWUŁlL+d쇸?8 m{sk9=8ﹷT>S[-+s,+Q\ix :W10QC!Pqtx Nw_mG5kUD>(Sds]h{7/hJONe6΍)"jFhi-z6Rj&Sɸؘ}19ya}E97ǁc35YQK X+MG L̉+9s x {C1Ԋ0DR+ed84U F0E/ZFN(n:k6vѰMKgT΍+0X/PQCRv)]O?YlL(oZ[|"ALj8exZKKLWyYU(q&`( {q߶HNJi͒ EԒ8 Et ]&,kjQ;rRKk]I'@zw6Ub uX)mUj1&@l7ujXsK"T<( =T>JpKՠ㌯BSYFŴ$P2XIbi(Ҫ"#go{ێvnԁ}-V 6\L))ѻ4l4 / m"eAO1[%H)s™`"J\H n)C~LD }]"Lׅb08[ʘuE r\w{[rq<^︫?Zn=B^^0MNHvs7NJ7y %!G6UP9}+^YIAde _Tz淫%ްrkV|F<"1w>9u@m.;Yxzrc,}&񓵞hNm9}$#sOB7h31rm}u*=F7^lښqw%: Z\S?Y'< ԴDx" *|sUcTSеSHOLOQj8pqX-Ob~{ NE@]ɉ%H2znז`?_Q{FqJ@mx9&OھGqYex{p)-BIjdde&'dk*qqrr*ځÅ91JIE)ɉ%@ 9@5HUBJ<@Fj^DkF0rEu !l'9P34%í6YŒYo5f4HJ:Z)/?%UIG/ȪQaڊ 9%%IyEPe)((L`i_$}>nx}S]HQlZ;ߪ^%T,ZAv6;keRKuC<APPDjO%Q/atUS.{{眑'g1s(w%­JX~>m-}lQO827br%R܉(njĿG~:-S)&"o?sYKkR A c:ӋS\|O+[L\9:R (>{!?G+$,Ǘ!:KPUa5E2tdVrE4iJPHө3(*q6WVB 9$\4*FcPmJ}:;.Az"bptv@ q^u^T0V%=./Ơb"'b$iߚ["-i‡8ѤuLKU!'' pdDIzc UÚ#6∱`=dC  ]pH;e dǡ99 )%:#FQ"2^OWCL* 0eV[amR?k7cV$AEh6I/L?ItxVklW]?X?{ 88B!n ¸x}zwƝqcBiT܈+MRMHP(E@/B$ ν3N?ws=߹g>|wiI24g-b sZ~\F۷Жvދ؟0< "8cڔup }M_Ƹ,q%ݰ)}>"KRG!xw8M uBưmTKTɂxn(U'(i $Q\} mf\q,>F&`!?-n12_tx$bAr]HbK}ni_mvw,̗]͎K`,I)^:Q[qi3&J(>D5ӞzB[4t'.քu\D F.n\=WM/J=[03OOs tq]mg }Blջ>V١ $ӗ21s^8v2.J =wcoѳR_[ٛ5uxL7]L+ 48\U<ʴAT>!D x^۳S:o#4;Io&oш1FFT:usͩ-CGS&?" 8PRCn-}Vn:^lTSXӋHSyz˚`X.nΝẕR֖*qcIEE'P==ۿj4LjiCSw f;7e ] !:b@: 뉴P8bOj{eCnO/pN&M-a,޸ )ߺ9A<Qw~o#fmQSCl z]jCʣvZv>p k2VrcemP Q[ӟbF:7YB{f^AAܐlK]AgwCM#U)u+,R\[_FqަNiZxVklE\i{{ 6ϋ;N/AG&ɴ|<]W?`Vgs`yfzkC/P y8Zz ai8 Fu9%BHeE"&0GZ 1:qU3v*36s f= ~?V+Ǘjl vvW'@IpOh(I ?T3'.WDU$21?`Sl+C~W?--v)*bO'?%F@(3bpҫ W7㟁JrY |)6V5@5/;B(1b#EWgKfJos6d".zMpGzov.A;W+v3G@f\; 6;2`_p \Z=m=M0i %" C0FD1AeEZN*= ?v"Hi4;vկĬ : 7{ THzjߪnaNueX*A&кS!IASdE }%"PܘW~Ӊ8 Ҹ 8j xɋ ǫr0^Z}tYmŅn#3Ynpubr3Iз9%U2}ԑς;x;:- r)akQiQUb)h{E"y>+QXl3guyؼS̺l/>!V 3V=égLcF:XPh- A!y"XGMPb;y&'l苗w9<3U{|} g4I4K4ۇAA.e5DM Z} %h}N? J2rTQSHXVH4dKpwȐGИ31s7 *IV`Oy 'hAzB1\Ib8Gch ?녃l 6Phxı4[YW9'(N5{n<bWy=+VPT./-IQ~КQq|\ @2`揻| 7cj_4e^jʄ!X5cy=y d݊s-a^7c>JKQK{*&&))(*(d嗥*d$()$*dlor2xWkp% cVB#9 R?,eKZ]c I( Izin8m2PiMgZ<ch;@Z#IL Ci{d;6MTٽ{;{~ 0fK\dآ烠"B@d A 1v$ ʤOHgHtu]L\'_ &1qs tbj|~P:%!CSx|ހ@jd*Q|ggыY;bhقlJn ޻[~r[:-kS.J$$l.9H:,ʖ1]zS1芲oGr B 5+ކKz=/Z,c.-og^[ݶ^s|^IpU1zz;cmET3Ӊz۲Y9ȡm/1/Shi{~H3x>KɤV@BUJ&zҞK϶m%rdڦF:zXB&}gPs(iKbwlN7+͙M0$`u݂\NtKO :G8< YO6#wnZÛh23%H=9IQ>?04 q=۝5 +hS<2~6+)NIyF dr拋AqH:da1_ tĢ֨a4%5ZVHKӜ=v|"$&0%=de4c&A@xȤ+1Р`P (O%1@X·`ҪDA#DrE܉+ x垈_^ bD"+dfzѝ16K @c'ҸWz.ڑI,_m=.Y-9 F '֌Tv^uҒrlo;tG^esLWh\3Jw;]Yi=F V+wвZpCNmlp`U =L#gfQ fwnV=fI2UO#Gϗ)"J GS>8'AӐRkimuZ:,FK#?է+36noJ/`;+rsMھqh-]bsy6Ռșg^b?j7')mJxұ­]ae׿:Į;f$秕LS9X7! Z Uyhwץ oi7-6252Wh00Mr0]1aZ1 )77{΢_(M%a"kBW1|-=v\!-xRN: %kہy?)$'grZH `3sJDZ?$bc @Gx `:ٵT^gtMmf[8H% C2V*S6ɂ_R_#-CZyxE^Ⓦm _Q܆/vdǘ6KP^U &`4[iN)e_Qg2g%F>^fMj*f3ܚ a7Bΰ`.T._ױ h7Y_w:HkYQ;<17 7Ɛef

gV>{dz-u[,̜ZÑϳ+ܰl~G\ 6vo2*Ni3(a.?#w:'W(;G{]`Em s vaIxM-ٛao6^,I6Nߧ#1#=hxWa۸|A@\q-u6]A%UZqHɒ%ə733Go@?|eєlJ$B.Ȑɰ!HDr^HZOYhl,5?>+i+fJ-Q}$sC*e(i$ĭz deFI*d$՝I|ﲗs4QI=0P+Z@P$RZ:BBIN eS1K6/n7$+ g>JnYi,fut`y g /Z~x[ivs3}KWhv><H4YxB 銲G) wHpxKd*U!ҘUFT(T%:I#1n0IWU)v^f`_YR PTHa [6ܚ/q=xNp$tZ8Ǽukjmx{>ـܗ ȶB^?P}*]:&.݇;~ Y >3if|?Y\&rW_.Wˋ0|2]GcFI0/ЕɦH֩^%Q`rh-)>.3# c* rle&H Nj 4D~<֔gZ%$yK63* 'fm,{ M%<<T{ddPUTL t>[~+eA+UomlXHl@dT2g3m *^B: ;7 CQ0wYl1FNo(y\OZa`K>c/[*0:{%4ϬE^kàmt k6eY72ryp^`Bn!r7`;&m>+܄)Kn2߭-Nn5V,v#=}\dWh/;^Z @Cʼ}صiGt_dW:+VGTl7 lC~4.߅}ʍ~Bhv8ĺ3pQ: ώ">DKpVZcDlfٴlJT ib:'q܊{wb_ۋ7:Y5K !G&[z8,T.2!+8wk 5_bm'+47RĶ)/Lly0` sH=BmC&xZ^A6f%лx#C{c+zS?hG`RL`j:YipӘqCejlqr0񬞿xvzGuߺ+H B,oQOO|ko\1KxuejTG69Fs{au@MèZ`\c`QݧzFo k_xݽ-xN=$>YzjΎ9ȻЫ)OX}=X^@u}e1}yӶA!$GsO֟kӛ#ߵ|eO5G}<豽=?aR˺4ڰ'P/O<~0]M~TvM̱֫ Բ卅sLZG"Wk@˼߆?b|EtOO_b/4VƖğT*|oݨ/rGRH  miMru}[xe2C |x[a`3dif ͬhy*de3!x[a`3dif ͬhy*de9-l%x[am'f1.!>!9x66 d`9YDe3kSDs$x6xAM!%LhW3\_Mn"xTopRƏp@ J3DXbYR |MZf1W^Lzك٘xmKqy{aKtPWX~N9vP)H:/hx;=7>zTǗDd=%h:g)J=ITAוeK_"h .[r{$ 'xk|ВQA2_;&ySd #2u)/ ȀqwM}%q <ׄjmިU%GO,>s9hC>|7gmŞLSUFy\J JmD4Szc: Hɪ$TH[@f/ DI$w(Vz2'4_qj)MHiiQ %9­&]V NO.Ihh?NwDv&YNL毅 B*44E:B:M0<C*m~?okf^/W ./d,H12Bڢxk? [[uv+TB7h ƔBcKҽ*ev*DBaH4K+O30ү,B—WYaPTH- ӚO&7zѷǏx,I-KY`+'ggfnN[ɋ=n Q ~)YBl+TJEľ- R`iWdf}2L"cV[46?n|?Y\%rbeؖ;:`qgU%U,GüZBf&"2Gx)1*Z 9ʴ$LͪJ#nJqe)/ċy¬B/z?gJʳTK(!ziқi‹H@ bhm,L3 N%f/ϗ=J`PSxn, ݄l+$ 3p>E& BFL`ĵFK!,vgW&c &t~q0LQ@+o1o,q6B gΚEe"4sȫbMMARݻMv~c=qbPiyaL Nؕ( kCJCyZ2R㭵/;/\>S^1گ-/~m*dJU7IJ:χaI+-i}ҿԙ'yQ)LVZ : s7n+^z>8}!C}C;8# 7L8uQɕA`jRǩH{a{""҂VJ!HmX.n:[qgw5k~':k V4Bd_@$qޭuUyBಝz[@͐iz Óz#1m8wGsX„Kf_\Ξ{[d .Mޮ޾fƹkߢ1j-lt*;~ڽ>`Rf;l3V,4%=n7nc;N,H:Ź_m[1b0B5ʡ+sobRm_ 93mg7ʟO|;g0t>c0AF8Gd{`Ym17,-C/2 ^.nm ?XP=z2W걢QYOkj RYIғg"w#`7# ҵelje?dlZOMn1_\! BOSCKG+ h_oBr_d mޝX4]̷\?@>u h\߱;PGGnFOMpOڮ^e7smͬYX=;oHkX,r#>{90(s4ā|j='U޵ 38濓gEBMj톈e9<HspSb;}8{>6pQA}!x;kxp3dif ͬhy&(l^)Fx;kxp3dif ͬhy&(l#l%x;kpfO>!#^x`p$3dif?ͬ6dzw8;xQn0K|⊸TU$"ۅEXTpVjfvJKO'|mUŁ{o^n?߾۽ >*H+8ze;_R* i+׳9P`goӷ˯P 3 FQiiPT$d0B7EM<%ژTѫr6^TIG&q nfo^?vN$_j(.jc| `@i -$$ l˸.Ru]&$(^ [jEc\Sa)K-9VލVk=k8J}wRR{; #m ry|.hңIO* yCk FcC-k.3 )qn⍝h;\=͈b`n>WsOgymخ Gϋ^̓oY?\Z^[ }xx`[5Ϳ8R2&Gslf/ n)xT]kPf"M6#m:jgCFa]~"Z isEKR.DAx@awyke`5I9y܄6)54L۴0䟹=ɓSm n;>l TwG,N"~ |;6l0,)fUv?ޥn]*DSlGOsN$eG}^N-T;GN҅.MCܞ6Ȉ( 7߉63x6s=ĥð4µl5O8s3=bE-Ċ!7B!;o\"g_!(˯ D4[ӷ?Bq`kE$}MU˯zGgq ̼|c;("\fGxt_Ɋ"`vÄ  [ٷe-CHlwx;wNo3dif ͬhy&Vam%x;wP{&&wA#3ReQ:@j",8`f,IL<{/h1rbō%xXmoF\ @IqZg!IjX|傀]+i{IK˾ ]HZT&8ݙgfy٥e +6&(i$iu0z rUIL[q#T72&;48G%d#2[=œ|ͮ4E"E).d 7J_Y{?"iud:iؙdf:1^_KgbUnUiUi,ftw`~ gK/g%JU^o٫t#^_毞$Am^,H12Rڠ85RZC\Fjrz+nd*U!ҘSZh4.݋5`J$ &YLIJ4}QdLXd1CQ!kȘ|Gߎ?:Gp$+,eTN5y] <k#][t[ YBl'TJE~ib.rK8?+Do O]ܔ]`=jﭐLcxU"G)FIz8mvXPhW+LɶH H_W-mdZ3٫LKBӬ4ʡX_6a{1Z,> +O*s<+K 䡅h5P3;y6fB$0 ^ %SYZf9V^4zk}w}#(&xl.LCQ$9:.J7aaXȨ2 tֈx9ȳR żI :z OHb~r8|EYnw(5ڷ,36l7;tmgϢ2Z9KUq ʦ0Q_YJ;XMX6TZ5nH!wyՅ0r%FgwX\TvYy2VcʗŮ绣MV&BF10ԍ!S9:e}eJK#cWﬡ/5u{e޼~ SiC\K8B|[n觬q^\in'4j y7Pm.Dc\|_Z߅=#ަ-؞M`mduR 6, Nڬͯ\zg]eز&">CL(dOC2 6EVe eЛStpKTdZ0w9|Js|^w<%1gr^D; P+K5w7.kCrWQFi HsCWC5I9S*CHccP +f}On;wrkTy̺+f8-rh>~?roNę)c߻>bmWG`|ݿ y,p8N,=$rc=ՍhGP|):retSh:f05{a{Udkcsmb=^@w7K4U̷ STǁ;}0)- ?ݬ^bOr>:>2:5aEo?mj/ǟ{' dkfƒdސ֐ryЏhgG 7&.{*ONzW(1'>0@O2k";lQ@}p۾'e_wh#e?W=[xcp3dif ͬhy&(h@xcp3dif ͬhy&(hl%xc8p6f>*xo8p$3dif?ͬ6dfwD%xoJU?9R2&GqnfJ l(xTMP .(-4;4`h4pqNX?\ܟ`\50nL\p0n\}@3xs_Ǎ0Ge:4`3-24GCd y4#n&Shvކ0U.vXV t"5%pL5/a2de0Pb㑄u_?+^vNO` @TM{ǑR #ō} :rЏ5a7swt=gU-/&H{i =w!B*|]i 2;c{&d}Ӑ2kBD,3Dg=t2~U~Nzp;OfYxoIv,ټutVl`\lnSA<YvHN蹡)XH27%R:d TLCgyy(A&sLP\p>Fw3kgI~;R|vADXͶZ[@X@ {ysky0ƒ5E29}3qxeN@U_xDr$^ DJz*E^΂?(}$^xz㐄ofg-}:z~|Zz==QXN (l0F ^NV oG ƩmEBYْqqA*m\+pX@H1@Z{) U #yhK7ګx('Q4%L\ۼμw.P&mÓΈ˸߇ v;0+zu ⽮8¸Ua3_OӶ,V^hD]XTKݵ8]'GBzqh4Z8 ܂!8=%DjLMb~g>{Iw-ܗS>V`7O-f?Ra^G )x;wRo3dif ͬhy&al]x[o:%u ku8SKKSRF%&GxZx[o&&wA#$B@Q~rjq1P@UY߼y~6~bZ.NԒҤTd{vIFɑ!!x;wo3dif ͬhy&jfeHix;w@{&&wA#3ReQ:@j"3,k9`f,ILϽsd)1b=MxWmo6l :lCvɖtA+BT4dﻣ(Y%/)H=~<˯ӧBN ^f2@ !Ii @sHLz&w܁.wygHC`I zkAeHz+FIQ7 =7 L{48"I4+2B$).HI?а:> VUwdle/BGU6H29a8Hd ?<>|k8>O@m0p*O0&(̈IQD9#̣T$o)9_PfЇ@.X[}$R _~K~^{G)uS_#c& ?ry i-#? F>۽Lݓ>v;q:/Tab:n7EN;x\`TsCq&Cɮl(Z+p@Zʐ0i :0CS,Ӂhٍ'aG~8P| 3EyƜaGi~b4>OԸ̤YpaH.)\J #9jwQY6e I(G]ue!zVȨnTSZR h x}NK272f,5.1wYZU!Wn(8x}%ƨ̲Q}j=݋hI}`!yڀl^w {саHy5:4вEA@UCg b5u3_eǹTta,ڭ{w QQ-lj%UU]R6qBV*)9lbۢ/)ٚq=3-p:f N 2ڶ,CҘ*A/Vj=E YB.q;@ O  OCL fJ&w s8Cn'ͅ "7], ( ilwN U8A:!2<{P^@$o>q ؙFR% w]09p8k5{B} `]GWQ  YB0*j@yl$q=6h]Os|3kUs34Qǂ֝qvbRcx55W3Vfas>̅4',B{!i%*+9sൊ ,N%ϠrWз?Zkt/|:lR79h- 5jd ίGvpp숆TҔ7 Ѩ4j箬eTO x[uP{B^~Jj|I~|AbI!Hd c5&Glva'ąAș)! ҆lFR*! R Q0xX6`@W?n$m}d޵ Piʒ Q ߛ!EKZiCb3ofg<|P|<o]oԨԔ"[ եXD Y(QVUdɰċ"F,U#RG*-UHQETO1"[>Ve;fFTjDQʍ)D.OL#%l97)Yb+o(T􍊅D^1DL2dQfeN|MBT,JLEђsguJH#O~?Q$+6 g-]pJcU4Hi&pqVe ~_|kjQ^~nBBh"TT(GXÀ\Ez-FMvTBoh ";m6ҽ*e_vje"$ˑ7)Ve`/,B—0"*$Vw ngrMR:y'{_قg; vRȿW%`T8o1`x_ܔ@kN}F*_]Wؽ0/ > ƶG;`(b5 B3ɐ`+YU6* OH)ufܬ4Zk,ex1Dg:z+O*tsyVz-$݂ZNys!0OxI袀50T*U3@td}i|%~kXQMwu~kžl)x EF;NE&$腊*LbȍA+H!ɥ*1żI%_¨b6j$<Y;}5&7@PY:fQb(xzNyUl3A۔DսlogV Q;́ 6)[SH+Q7ʄ8 GhSE滵R㭵/;/\>.҇hזDi )@9PC a@2/VH'˔|VSʝL3& sin+ZaPӍ~JKRMHC}C;8#= w%qRU]Zo032)-چY@H K^': a1~R8@WK[dDxR oW`@Ȫ p^Łx[@yJ{Dނ`hrU2 %xK?P by-1a"AC,RxzF!s 56{֨հCcr:bhwKN1f)d n!j6`Hzvxj;*Y #̸V(Rc_Hq}χc[:%Ƅn oK+i'7R}g5'i ?3٧[4ءNt/c$vBZiT|FG+y;'CMGKO2_ ߐ|tO@Hצ}d8^'>rZOM1]\$4B3.UCKG+ h_Kpred mޝX4]̷|?@>yKh\1B;P֧ȟ܌~0xڮSm,/,gV.:\==Q9?~"1߻AFʞʓ*^GZ 8⿓EB K l}ۦQ5F!"ofk%sY޷#}_8޷L@8xjxp3dif ͬhy&(mA]xjxp3dif ͬhy&(m;U%xTMkA&hSZMc]HaX<(%V5fKzٝdnv٦RJś  yOOx͇!{y?y?f-~Y3 "G-7m6e(6F9)&] ÐփFPC4lp\Q +-8AAu- FMib.j;!v\b/l2LAex5fR!G,ZA1}HXR=h*QNV8-BQ6q( S('>ſG8 īb"xZQf6ejOQD $2}ĵ8IM\Q56.ޯe@,Y*7ga*7=GyX1Mj<:_hj0xW>$A!G 0b*JBOSORa89,~^YlNt=,CX,&+wFBuu7`RH&PA^B493[e(ağLyH&:吲׌ݒHJ@(f jTd_aCΝ}H ݚR*Tr\ wFky͕Uw[Q;cspvzYBn-F7q62牗|>K׹|t%empFϴ!#״GExqJNfNC`?Ilxjpfo.>!xx{D3dif ͬhy&pi3x{D3dif ͬhy&pacaxap$3dif?ͬ6d|V%xTkAF4ISZbX tAJ$@4A)fw]Yff50XzɣYl~J7޼wRod ?E~~ M,GQ͔MҌS2:1<Sj;Ő6ʦWA,5Lp$lQzb&6t1-6jY!ݴlb'Nl1LaKs*LV8nB XA#bw]a~Ovzd'UA$4E hϢ܃jdN1>&AbG<| p o`W|ϸye3J"5˂Q4oW/5:uN?DfpH lH7nbT.Xu:l%FǮi`bw\n%8w)\͢)%@+bN>􄫲Y gf>N,]ilJDs+p8,ܒ ٻc|-I dlttJUZa\evN-Ofφ77ˆ̱ԧnEj˹uP,C YIzQH?/.MΨ?''"@ץP!Umirx62'>V!ѯcbj$ w/cIU( &rjB"RnG1qKB&>ƦWGi7 *1*xal?l )e FcZ7qz .x;\$3dif?ͬ6d&x;?IoR'9R2&kq5l> V(xץa BJjNjIj|^~JH(7|MS"YYo>Y]d56XOzjI|bZZfNfbIf~>b4As-}K2 P5Ֆ$γe4!j;ng5>)i9%qxzF _ǗT(d$$gp)xrfb <5xm=KttR4t:f'&BCYer.)_]7RAuO^+ aƃM*yr>!49?.$KiLFV .NNNI`a0x9g%Ql|"R^.lQE!v>%& P.(ZA%% N~/d4$rRӈG苐@F삃 {l'c&"#n>V( y`( z_UH}Vaa : ɩžߋ3f'r *ftOg Ȧ R$}n1i JǺDx h1YHf32Zl\(_%xipI7]&e TAT)ڼy.d?Y3KRsu3S6sCDdmEIm0xT͎PFT CGH hIf@Q3'b23cdvX \ SH[F'C[W Ԅqڍ.`bb|m/m--h9?=/?P@j}aHC<ʆq1+}\p4m$ iҀۡbrĚ>| 0*דICRQ}QmH# G*u,6@MԐ:K>,dXZuFۥ1mX3J⹑"x3~W3'(` ܞ.?Ąu$*)cbe?4{߂=cYKp+8}is[R;#Yf_8mGz:>;Vn }PeNx5s#,Lx{Ro3dif ͬhy&asT%x{wC{&&wA#3ReQ:@j",F93KRsu3S6O>99XLdd3qcxXkol FdNdjXnSȑ8!ȡesgâ6,9sc.~1~&̔gdULD!edhlHzW"Ӹ**Y)/YJgt? ]=yM+]B(ӆRnp ̢DzJd2ea e4DK*d$սI@|夗g$R =0,,fF3- e(MJ!M$sWʲ/U 䔄Ę|0X.}i|зR_τbUnZUY,Ml;hҵ8SQ2F7?^~^_?|hcm@F| YŸ)64N)v7)@e.#5KٽK{Yd *.t2 ƺl(*`MW464V6zw^!8VaҵZ+/^ح:XxV.{r.KQ}ak*DRKSTCL-ۍ!9I#tee k=Q d~q.t\s,9u^n/@9UYVuj O0T5өD+]Bw&d "6(3Ѧ)ӻ2X ڌ :GsZ\2cŚE Uq9XHK<8c*۲be|kf*Y;rZ&2ryp`I @BҕP siBTneVj+ND޴nڲƪ/ww9xٽ l/[ )GX˵%j|v{F+}6Z6j_  3֐F0w8 ;c.L&\p Un:CX^Hy~}ڂw|÷6R-b4ST)#B 35GΈ|eۨ`-X/z6KU&wO"v.ăj@0݇I#)K%%@\z 8 ]e(T/e]Ccԟ6R;ЬrOY&K_xm8]C["T5 3Ξ8/1*5jGnJPyBơ?p:Fvb_J$ Z((; <k; BZ̔|NA#&xŠSd!(Y1x|twRg~(qƘ2>,h] tYHqg7N\`(Y3?gn7 g<k:FG<`zD+ Ws6D/vYKāzB4"R 0X0B;צvzwmTܘ=6%n%du@"}==Զg8W-_Eʻ@}JCו[zxq p]oha!pWNU`ò.&--Hz(#9x3 ZxKNz67bFn=!7v_ @wmP"WlWoG7-Me=tIS}Ƶ WCyݶ_3M׃XjM8[3-ڲvc¿[`.hچ{*6NHSJۖq|+w}7a$0RjcnY;ϗOq*yk>S|C.$xMdF 5/pó(_p鱏D%?bl_s%sGUqq8*vZwuݓZZ9wϊ%W>E˜o[] *x;ep`3dif ͬhy*Vli+x;ep`3dif ͬhy*Vl!l%x;e`I8R';mx[k`$3dif?ͬ6Oe!z%x[kp_gC1;g2w2)d)MѰy'+/ rxYmol#2@KqZ\ ZHr=X^Sȕȥe(J ɝy}vvO'᧵~L$E:323 D4Q$K*2 >Ȧ4,ǩ裊dV"[u0qۯR4Kʴ5)6sC*(S%HB 0] "eS"n$2F$`|鴗g$R =0,,`fV- e(J.M$KQ9/T 䘄ĘqX,zikF^Ūܸ4+Xu Ih0j[(TЯ˟uI/..?O~|z,o,Ϝ;T]Igƻ& b.#5AH9Jg 4Aj,T͔a.J} A)S=b6$TeXyI>u3 :b(ʥ`5ry7xk`?M! #W%*XN<޺_f,|qjt\!r$&8:ɝWO ԭCEiN{^fIz%UX.Tf Y C'ˉY%\ޟ22! Z{6z J ǂK8"cg`~Zs(Lw2g+޿+Ӕ?;N" 3'̓$3Te(oM.,]8&DVf Zr%TE%,/:bw5&c5D{ _lA8`9ѣZ@&xVFyZe<mY{+qu-ƮmH 31똱W6LFsaN/^9[ҝuj=-wMq@??+3`R=nblU @髬S!\9#sCtl^eE䥬;2Ĥ2QSx EEmzՓI2h-ׇhq&n]Y?gJYc nHor!:L NX?u9/Bz!〮+ < <lƺ8"f*ۻ8,А*ڪtݲl[zƅb&yА*U lGsbgYnw-̿F~Z:v)x,P1|bG1bmU;HK9xd:i.%J"%G^7vo0.8g 53|tBeQ1z'Pޱ .0 qR,3Ik5v[ݷM7h ?Xb tpbQz<&JœGzsr^8hN;dSJYaujhv35 U;vS+_rƹ(U;j#1*^gF3G~V]xR; umzW=`Re0mIAU3=?] >?8C4iViS,[wO\8\Yd'-ڼZ$װ{)7dnr?qk[50~[&2z0Ф3P6cP/ r6*`#3Rb'G޵;gE+9 $7zt"BZ)m?%erpT\K#vCMhu?ذڽJ˕qU? |/VD\Q g^YomHm+ QҠLȪfGB!(7ܭ#s,.EJVAD4!+哀l[v.TPߦB<|tP9$]P,XBiXm8ԣ̻ۮ'#ʩ,m%' Vht9Yc-!Gr I}M–n#Rsq*eY4[Id70)OVO}AAtܣֆ^&O|/u'!4v!<` a`&0?+tઉ#SĻoTk:$Q:i!Y 2A֛Pٚ!H?@S7nz25(4sq^RQSS&3c #K_;9m?!>v!y'o]ҵLg+C>~{GDQEk;f|iFmfhOLLATdF'P Z?#.t 3`f$>G6 R,)ZErit;&Ԙ*|+^+CW/p0:{4w܋g>ƺ0eEGU7 Qh)XcCZOaAf? , bgvW cG48T5u%94 SwzU$n@@neky ;KoQU#: S_,`g>^}epclh "a/m7p)].V1=cɶ:&mJʱ-cL寍Xo t`Zd_,ٗP}X9 򽗆UP񦓡$xaM]8!mج8<7%FE6pڥPZO"%oX, <gC~HF}ӔKKv q8tYv3}do?XOvdW'6Ŀ8 OЗUg>Hf۳Σ>23dWE9pewY0p'R6}Ioyj`DdK#uC=:O}u7蟸B%X܇୅]M,0L4|b("עdluԀΊPJE%w+C4+m6V6X6JM%=*ա´:^f# 2I@fPb3v;TK|rĬO~: Gz DRNQ-`렙u0p=pF0I> jp^ O"FʃmOeY8LclxlvllN!%D~xx{"l3dif ͬhy&yuyVx{v/lCj嬓l~t1 ?x{v/l3dif ͬhy&]RY'WKX `xfvl$3dif?ͬ6Oe>(aq&xKoTW$6(N"rj#%ʒGvB]\rvC %5@ Dz[r!| ]JIk8)zhI~rb/~67qbrcb{Iv9s;?ra =In-..-eyңȧdYH΂.O ! nnFmQ 4vI\*)tK+km!ڐi>Xn ɧݦܭ_ՓNK;^@ݧOhpVvN2\j,qX?m/ k4)?a\N>;c{, Q# jwL"yD $&,E!\xBZ}a&Vik*T^+-ڡ4&pؤ ̿YWH < K}]X『Kʩ $x\2:' vP X$[q`KBR "{7.$x7W;Trۑc=߭P=k:.,Rܙ`'ד?TO&ek Hsr~v8<~7 ޠNT}cK%$u2JpR-;?]7*T@Jdy49쯵4A.|~V4=|)/[C9㸯^)+= =gGS<b ,b{X7oWrM7I$,%~t=uI'?}'oF>Z MW+Qع/})r VVTF<'nx%FWCj53`dkSӛm^М/AkWH{gD娑>2oMAMj@P-C77 -az!hR"Q=T;X?J8@AS}pq&9%4qY !<3[#ȕ1hd9(!%UMTE VĤ:)+ە$̋_>h^ͫ#S1Xe <1qz$ܫ/yCK1l6DF |+d?3ʌ#26aT %4Lv̆183f|' {{V4\Y s>OaRN΅uW3# WUYud)-:txff_͌l )e Fk96+r- swx;v0l$3dif?ͬ6d^&x;a+WR2&j}AfleL Yx}mW#Gg+r4SZP~ӻWمZH KJJUFdD**V6ʌqEē'OOҤ?Χi>-E2ʊ"Io&״?McHɰ_&aO^e4/Ҷ@[:)q|E;iq7׿NnƳdԻI4iK^O,(z~˦WҩL~j<oi2Ii[:Hz>8Mz1Fo1b|1}in& dӤ˓s2I,ee=˻_ztzٻw6SxrlSF!sl$f K00q4qSh'?uN~8xs}tKr}Kn;I4N_O$6T'EJ 4:g );]tg@$kA2Fٴ7 ,il'ϦYo5& &x3&1ɸ䩂8O?I{DMFXs$%_~6 0^ G=&G:H' ӧ|C O/5ͦW@_!GQ/˓}hs"^^+6@N^4`Jgg:Io"m'`fV@zŚTΦ(Ρ2L:Sh>*`N73 0w\̨!%4#MEo6BNl\Rt(}%`6LAc2I/A鐄R̮> zv=i2md %3vbZNRG8cc[_8Y&X@:.?["x&Л]O͟e7.꥛FiI3b%ݛ^u〝px7ϾXkp9ik6o~=,C1 o~/@6FduҺVl^a\=!4ѿz MkMИ4y+:1 Z܍DٟATc#и݊IS̹g\ɳo,2#]r:ǂxmv3KYzK$sLvqӅ{]bY &.yIׇʈb+jn{ |q9LROaH؁(YDϾw |PҸ!t ckC5]JޠkHq89{ qs˳ȧ-E~eRlmL^RFϝ@\$>%`Q]NƳ C{NN<лH0A.]vrSPwyu==v99 .#+b)EIG>Z#4==9*Em!YklaѴޛp)|&"fĿPޫ@b06.ϲ6_>|FД$CmfO|;/9ML N߈k|W6 Q WK>e/wOۋO rR"1CZS]N_x[B8|<~$Ï]"(uQ垆2и Lr[H~Gv< ݝ%cوm&> Rn(;I6I1K.…F`}Bm= 'a Wa!%#~ޤuCapENJaGP \&tp5xQ0nFEoځ-pR$bS1t{E&;9zJ흟!4+$WƆs,~j!v;_!(Bq@Mqv9 Ð8qFр5&F;^bEGϠ7DWqKE5a-,@Hm1Q*[O` "K B#5n>zG6ˍo#S1Bm܂R[};YPA^9gk Ť%/G /A}5H.j)V;b1o6ᶓf6?&V xNT܂~y׻aPF p{֨7_u'5Bի*m] # S!8Dd&Cm';] t)CR+8S*OFy⥠ULڋ%Ax(OFҀ# ׷\SzD!U*ׁA+ལX5O<X@%A X12:fx +o6mӃsa5lI XZ&7iKIqڄ Nv, hB~:#ISA%MQE "fk{%[˯)>]p:FwہK"Rٸ+Z̫+p XwĹrdbw^}a0(;S$|m{5Xl뛮H~eCwr{v#Lv{]kP&E+F[5ǀ&kR 3_c-aWU&5w?3s(p1  TU1mNR 6;GFXbZLel(탺Y1Ddc.: %r x*ptX |fiF#o170 b<ȧK7""'W Sqw@¤D$q1~z}qhIFe ԻuAI];c%x\Ӛ%:ӳ&u@Uh/ޠxuXkң8ϰ DXF@%n4Zu8(KS2kzb  #) 4(a3kЌo{?wHM ,,&4oa( , Hm*`D<:{^`65tFx'7H=B>FӠPNҐkZ˨9wZkȖN1ZA%QFq{&~L5] !,UseLC'HLN.I=bVR !P꧂x0@З34ٍfsX +Qի1V6)L(dJ.N¡Z_sO֣ &$ _t [DGdrպ{,~y،1E)F,?;~=;V#Dkls(o]A:f  ov> L{,CMhѡ|"y:{c#H":a9q[4D/)SFgZ?-ԪqJ&UmWLQlliY]J01MgF]ĞW6)4=[|B6/<AP2 W9ֽAI<[j>:$A3@ù!Wt=9wwg{gCcQbV80bv-&tSw:_@\dVsGlȪtl-6]|׳;ќ*?;oS + @~=aDKM'6u4c:n_kR ("B"_]H<V 1 Q;_"CQ܃`gGH;FL3#I0} E(#8SF,aCKw8*orzUp_2իA}@o4G.FӺcׇl Ex5drA߀>rPn^(eQD"ؚFo$6 5|QPd€:} {'/qWڮLڅ']-IC2rDs!$-B- Lؑ,:YxsoHIӘ%V4:Ks@bδC3p RL Sn/ yVI}䙻ܧ\cr}"[B4P`-xfy=03l.Dև& ¬%&VM:w' I#®bņ*(72QkNmpӖ^lp= ӁtY$7|oa/a!P\a9Zob~(Oo8u?s$WDnHt -+*qܦP[&Xj2cWVoeptKpavd葏mvb™Rk%HX4?բb˻c,_ig9}174pZJ û UX ױ/̰?paQKKC[ms ZL@[8@]fJ: A^ krg j_ 爵tn)p%{ (B5P 4 qNͬd"YPDBM&[WV ǃ t'7!}0؟n`̻(,7%m_d8RyQ,OhZGH&T`u'RFf{f$11BR)B- Гp=sx,M(KbDweӚaZи_2bGdVERm@w!94+Zr#cxW ׿E {dfznfcyA葅8e@܏) fe4qy 櫮3x6w+ MZŸ_,Hs0-B3q%[@'Ӗ5Ĺ ^,>iu I[2%qBuJ9%6,D*+n}y%fF,rteƯÚѣ x'b W PS{vʼn%}. G- hb%Ud[VJR!K+lb0z@L~FsRC3f.+!s<"vr`qeF',:][r+HqB 0CmҌbNsL$CZ%rn [C??>R`gEHo'+4l JVqYѠ;P?X2M%LZYv;68SЊiۉixaO52ͨS;Yt ZVM}c!^@JOy'D9XN~j; )KyɥD}D ' ѼWfl,{<7{#ɗn1"sU,&hEGLAoKwavB:nw:'@^Kzkp9(Ԃ;%6 ARvEf3`jka\n:\VnpCRs\"4ܑ"ay;BM%z\SqPk%)){O '$ޑ l'BO;QCt5Jg>b``>N!`h,\0J/C>x" Lݸ/wb]e׻P&(nMu2Aٝ7.Hy~9u@UVJ~:8oZ8> nVorZL_m2yI9l)Lp&61r0te揨&yɛݔmUs79tWοYϩ{[}4~I-r" `@m)ZP72O=[/^9 lʡ&ӵ3j[0#ZC|s(J˄d#3"Q8ᑜ (?F̃h]R8񻃒 dKfDנt}+D=ctoB I:/=(R$L3A# PFX`DԡMxs$Tˬ% 40^’RS 4d"|Le EJƤϕAW. *LB1d-0CUpU{JiQi`l$gZVOĴ*[,W .'48S_e?!F :ED=C"8{8VOG(9Y ZAbl'8hXO`Yoq<籨_,s;130B7g5 ;Y&Gfehs%/BQ_ɗ8E꺥@8g21O.q%%T=t 3;EB1syFdy*,rMo@c@.12CT_ԜIJҧϢocV<B3OrFS`gWįߥáx F@0Z7"vwd\媜j{ʈNsyB^CbZcK<K?2< gE=i@8hE-`Fq\i(םfЏVv'GH6>ȱtP:#7Dp@>Nʼny(~[dJb4cnÊ_!+ b{*aήW{F/;%)O GVa%klD[2eU ThLNֹC eQMŜ`EFC(tWM[RsgZ7"ՎFD9~t־-aL徻.n@(+@JvV*HBǞc}@9+B J᪞תE\Y0JˉW$$r-!bd%^ӅS$ǑUXm+HR+BHPI rB5u[aw gpÙe<JZNyJGxXbn+.hP\aհՇ&}i7kXw+?Pf DAy,:" dK+5YpN?&dxU},W;E\2{^Z%i{s3h?PPDtQPzP ižz=K|JRd!KIዝ?+IFIAPSppVmѵϋPbivQ˓ $<V:' 87Ypo>k8].q$g[DΝqߐ=o6IpxEPBޞn7޹]_"lvdu&|7l/:() E& [hfk.J}4kݫt^1A}&3D0אDD ŕhVzh|aЄۡ }EwIYc#'Q H-^Zp'lC8hcq*MNtĉg |6J^vU rYz$_$04yodsCa]qm! $hA{N*`%mglXjKNp*j3p 8}#/ ]Ԏ5N2u@PZEh$-;p$j 7&y-nZϪ7wøm+c8[i'zm+ CBH#3lFe$gZt;"*E7ӫwΉqVچcr8sYb<6sw,>9yf/ \'rv5Pݕ]U5(ߊҠ00Hv]g;ׇ] ^]pqнN=eå5۝ *ʶ'R5EQCnh^i]MY9Dx(uY7eD4y2o^U!w fnuN*BIb:bgVKQZI- , ^)%yP]n#)=]|/r /WJCxno>F|arS Qie~w &w m$c}1ٚ꩗[70o\f<;˯]$/X@a}, xQKձm_jJ(:YPUm-{D{[r=e7.Cq;łRO ?4 m8s!=ExziMo6믉sS`z4x<7}%*aڳFygGȞ$9|u<ŗi2Jkn9 n?o "捣el8:xm>@"cԌQDBtӨ6]o0W) w,"25Md}VZT H%s `Rx=)bR,h&}# ED.Zk:T shv^lXX2aTgق\Hi'2YrFq>*F3!kU~CVg,KQ#&>3~/5GWV4p/5NcP{]Gy?wAyk5lMȋw=8*_jBXA[;C;ކyQ! aH]ےC& g w[[8ŪmR!0i#z^ްl `;أ'7:d.^Q2F~#=q UB)ZP!)P*FW(Qi՗J QR؈3gt~ Нb7._2~-> Gw|g:JKW[]9TA2Tb?sWq.Crqk=Ǵ^8 b{v}mUx/^`b޿]g|]-ٗk1j~Fr>-}!1.ښ̛ɿ&wxJf^&~56vINH2eu|`2s\ǃϵq=N_H ܴ;:ݲc)n[6(di:\gb" dJf({j:c)gZ*"h/vS֊ wdѓղ(p~i k&b{H^#uEt~`%U i OQ/gChNZc`ewD;2O5Ӫ94_65H0>Na{;6(BՏncYk~θ,e )Y ;PwMM;^%Ob֛ Qm ڴ\ⰩEv&D<갌Y K /n5Hm$;sPF0hhirt.`.fF|b jE"~#{0lIHU+;Ț;S.&uk'LvS'pgjFL~ U\?TG+S} '.ZKW^͇{䎃ʭx]>&P59@/MGP?:-f0Dc(k~=P7NI޽H@3lhzfp_!W;W-p0i R㈡^Z݆]e'J*h᪟xİy0wx@ZҵѻV*WhsgSX4mvO+)K?]I ,u)֛?J*rH4,oP# ʁNMH!DgWaFSK,.>[qiD|, F_RVtg/83ވ=YJW?uR0=.&Ed~DG>Z!lPL Wƿ^kI>3تI9>]2+)*=G3 =0QF7+rkP[NXvৄ.2婸AcF>)BKB5J9/Nn_W+ FAO6'HݾO6m"@tnU;J/O6'oxi+KhH=St0g9~Ycsf,. zq zcĊl`~3GXRb P\Y_BZևh[e P,~~ */P[=heIV1MD Ll;A+=OøSF)OLlYP3lMؐqu,N1K` yW}e蔧&:pwefVwi,~Ģ`lifei\ YZȡnt% ܱMF֎!Q91n|Ul(\cu"]LH~kڍ(DHt9ڲ7Gm+͇1vms dy7fre0囹&թ}.-`uSd]q{|JM8ο'?s/AfƖds˘[^$&/dop[\ o%1'G(4ˌ\K@.wb!-XQ⑛!Uuwbm(97ܰ%5&5y?e7|=DSA;ފlζ$:a/}x>B~݁H@`e/l ݐ?HJw{pb2_v! ۖF(q8I Co'`o,PIeS '\CShѽ6$u#~۾Z#*nŏ GYsa|LaQXL76 t G{<&Xy[Bƶ σZM(u/nUP7c;FL\l. 2;@Te6R+I;Ulin@Z8)WLAP gIhTfRo@sD-ljj;$h*3>Bŋ bvp{дGqY'" i22#6D<+b"<=:ը$} ; qn[LT;e%>QiciW,;^q=XUK\Mo,*ZsQ-CtaGzr¥;SN3_'-[F[ȵs:iEм@~CP)+<5ٛ콵&L D$~{ _@ f)L|KW2#v}9/nGDZ(?L p ~FQx{0T ŘFd6.xx{0T Řd6.X'x{0T o6g2D6?= &x4yTBD7 -AUx:d L@T6܏R2& 5l,t/?%ui+WK)*[)+$*Nz" &Mu q Vi=ٷOb8M39c6 ?rbWj͗|`$f#YFbxXmoF\ @Iq+4g!IKb]"ҶIp}A=DZT&|pݙgfy%? 5~.*%2 7Be$j&nps0IZ!zW^; d><cQ ,?a0oJ(C;:ht'UU,GC `Le:dfT5RU^*tB0^F&kb(.|vG``]C,9$ nQ;@aQz,nW^Ԧ)+GxLBV{@0_O;%ߤ5s?.Kw~8Űp5qNiY0˲ ϋ1CAMǺqw Cn~ CMo=0rCuFŘ:t۠$tן7o>~}Rn\PPǃ;~01-fY;68 cko|b2ujNj޽rM9w[PKfn,oO-i{R:]=lA9?@>ƿĞ Gxm+?_d pYXXf'm(yGxz%5%_mŹTBd6;DT)>kn6tʼnœ'=[n}A8ov >xݗ"+/K<P/{*X%]x77 h4YHf32m\& `x77 h0YHf32l\& `O%xeRMoU8$·;MVj&| I2g53ͤTXBj.`!b]VlqDl̻3;_Ə'smܖ|6`3ZBI>pS""q8]=XFc(S̃>i@%΢^{ ֹqDcCH=܀`;u.AڣQC[60p r"Q EԢ3W L)'BxN,4 0p<5q$$b> ) #‚ON$#ScZf28QOfʣa7VJ^~aֹ}±l@]IU,F*A'.H47=RІF=FMu]klյmwUv: I$7%oy`*ḃ?M~ HB:I]ǿg. ݉/ RI(Q#ޮ;]IK39eeϬk\(* ?Y+{ᬎ›/nMy X{N*2kƘron?Lfg^{_[}9wGQuܟ[W>‡Y%{OvzEGN&D.MzVX]Kg ~xKV45~W~Crѯe6O*K_v3eI&$'i-˯رem˃R<Ǚ7lvx7dAkQ>!ghxip3dif ͬhy&(hN xip3dif ͬhy&(haxdp$3dif?ͬ6d=R%xmRk#UM6Ӥ&4k9 $۠+B kuoKMr;%*(|PO *>znЗ9s}gy˅ |*Gف}|{11 L8E Syq4d'mE}4LsE|8Xz,'8]!@S"slw+ zd/@V$RITᔎ2Nj_ gT$D"m$f!?ڏ 6ܶ2tPL-,iƲȳsĉ$H'V;Qt]+Ԝa޵\6U,r4LUAH#xf72V:6Z[-aEr==桥P.HtqwK֮ 7 grs zXkrDsuAZ: >BtH}WPEJwZPrxy BNLp(kX-TVSmn-EVقV_+TszMc^?WjjOM=xV޽u}x%51Z' t4Ӭj|O7߯4$UMT˺quo&)o9uy:~s9f =4l~an_ W#grcԩE6_''z~>ڱ+Ǝ`yP\xd`uͿ9R2&p5l* 5xc8p$3dif?ͬ6dfvY;&xcD{œ7Kq DL2okxTnPU*?Z7i@B"LܦA))*ABB7R^BbR|lAB\;}8N̜sܙ}<店F@~-XGMrSGrFwt 4 xME}VV4ԒsP, srPJES:mPVm,nCjzJw^IّU4ʙ1ZeOбQH<ϰX0fYL ҜY)O̚^eY{EҠk-]8< g^6OUć*^Q/%4CnPe$Gt~'y:wؽ>[ #;'5m7\j}掋E97dܗ>.>+' Cdп#W*{plk'%-H/9|Nq b>pp.&Zgy:/+̶dc()ze牙.qܳ*,K$g$ (}+oMY :634^:CI ,Vf>cE|YOlY܈}=xkFXdJ9s1Q kS?N6F!9; 0~K*vr Llx7}=uΠfmTX釱uo$іL&Hgje3ynlߞyS8G# 8,bx>WU־@d \gI xQܨ+Nb⠿]! } `MakQ=;x }daF`VPshDI*sѴmZԐ]Zsή}vнoSU%ɕakvUFf㶱"P+`8i1m%eCI;"~7":jq Yf|E\5-x슜v]-إ.+ݳ׼{3q*s@愗2LOޛ0@z2a*I/Jt)j<90 3̓Igkޅ~uzv\8r>{78^rݢ:[%ͼŸZVs;h;[[GXȦƒpc魶xOCY\'4|cЈGxяϤoN{GG /MAңC2MؚC+m"kkU[DbjWĵ"B,CCPtJKXgZbsh_^զe#FC4~uφ1qoxK>M1$AT\4{VYoA>Z~اݵZӯDZ)֘KuG1KZ[U*i+ұ~ȥ!L8V-4[m8b M0z1:њؠ &+k3\Z5kp.W<' \UuwO[\-^$Rz#9`Y3E(_T9Z59ߐK\oж CɰpF%SSRE%2c4z=GC#=C7;R|'K4Y:Y\q&?AԳjeR>*XaDAԛf`HUk@}4b-S{'Kx\pkȲ%'l]rHSѸݪf*|"+WV-]?ec [\$1,k:iUWyn֙X^*l@  ]6 / >q(\l 8ƺk:<[A ߒx2"_C/īE_'Gs^yJF8v c%C@iI+z!g*F]g$ht\RƜ93|i6 o<y'7c<̌3\L! -#w*I?y--RM +Cpka2OD٠')[ e?e&,H|NN/#\MBWن ľ!sԋ;7[i^)WfedkۊFl3M0)7T׉_@MEǼQcmYbDiUfwn+D k@k|΍#dM_+A|R^ݟ [555щtZ_7$"b$5 g1w/kW׀%y^dx Cl  ܄TD!~-.RzvtfW%[3 }xd>VgCZn~`|4% y0MSBpzR!0'fꙕZ~x2|QQbf^n%~~5z\,_(ͷ9'H+Ix[c3dif ͬhy&k9;x;qc$3dif?ͬ6dު%x;1}f?l )e FqlƵPlJťL" {-x}UOANAnAD"B)DؚRA4(xјqiPě;ɓNċŋ7ggͶ=lf7͍Oim^ϭ@zu )"#BqG۰ xLuV򊾉lN| WdCQ T''?tkΚՔ[4W7UC6nrc*  LP_,b\:p;yc}P !{~f- I,EK w^| \=\F×a-~ČyۙMU7$LYs鸓+ٶT N[alOH.E Yʬ8\Wl |ŸQ¿\"mMcj(.'R#N Í 8q1sÉ?B3cQ~ˎukҘs<34oۀ8/EZշȶJ#5ǻ|65jL]yZ |ɞRRE6ٕʁh{y fdW8$TbOXGYDWʶU@KܢP,!LQ@_ϕY D!s@ 9ksI#:/!XCޖ&:Reu? DlUd"UVE. |]P|UBwTbiB:3fDTZL/.,U|}|%MxD%?'k Xq/*v,z+-ݥjlhCw˵l=Q{`)xiHtG+w l9{XZ /DBq NrS)ֹ75sT 3Ԉ C;]kz.y=YK-~ gqugh4F]Ld*l!4_?Q ,xm=r3dif ͬhy&G~q_~JyV**dd&Yee日ҢT 6Mrb h@ڼ_D=$$UvQũ% Qt5!z 973 HxmfnL L2Rf yqͬLFmnĕYR[##DG!~x" 199XSA׎KTUB]r+S3RR<]% `Eť9@KJSk&7o d//ۼ_3eTIL;mxmwOqS.ꛯf9H, W4ljtdxwRNٽ^%Y20C1fS4RRBOt')vS#r`>wxB42{Pf6*r+@u'PczW"geafCz@O./O'щ~9]|,U™RTA#c]/mZ^éZI* ڟ&A)+NX)7n۝־z9\Zl0?vkrN*̏Ls?d*wyt[>ɺIUOYf+936Yv9.۵A-&Z_X@E| a?#k7|w_#3IDkW}F#P)ڝ#h3o[#\"nU5#[([jꞞ\\=|8)R3&\\:+l.&>Sҡw(]^W/$Qi}H2ٕJYwgm"|*г[ai;S/\UIz?)gmr(=~lcKj_KGQ1]ѣ['(*h䜧a,6RQ tx85ox#½`{ֿv%q4@q'`l(t63Ur WdhJ XӒTzU he"a!Z2% 4G͑ Z!r щ5? .I%YvDx׈Ar0h۰ R T/( U.5/4e+ s))-$:"%@Zaf5Q5m{qk|byŪF&Y4dԨDݪ؀Pd5 V*1SX=['q}T,!ԂT1fgըf/6]U;an}q}満O,-i'f|Ձ$ъD=j Rp&,X28vm[C)L;Ғu:V=ouS&?k(U"E0F{G;.R7G4 }B# -6Dnŕb/ЩhVhKf2+c[nXbrgWc }ne7t'= bNĶamlP4o~Rgmj:7ς š(Ԡך'*mBSpASW~iE΋iWgo*ݵ<.Q9vvꠅ&5(0Wf-^>p2Z~ joзy(}|$H$@-r8C[-sÊwAWfx7 .mE~ )lQMkYQ-=eO- Ojנ'l^kEr揝}dRt]Fp%s>L2Z %Pw.ߢV̥ /{AʰϭZ۬r y*Ց9& .| *XE|fՖRvrq<_vO||!1ᅮoHRVV8P$$җpQOog~=W*7_@y]L=ETxG\.k6JcWqh@).L ,DO?n# S$xaufC* 4f9tRJ&l*$89uG&姤gix(YOn,Pģ(2y06q;qɲB O ̂M,Hj&)Vlvs6Kq2/LxYas6, o2f}vc{^NveR$d!H -]);-`X}^x!OD0MrZcOcKdRbISLHqAr+.QB^2Ѳ͚~Vi"^u^G;v~F,BLH\ZVvB%%LXI(\Ԫ鈏P'iGbKP{'-l5Tq bS|cvDoLE$bdd2ϔU UHl۝mV?Wv) u""dV=9Uxv\Zwõd08_Q?m A|eR#PPuĕ4X1賞PR oJq,QpWn'FD"VS9¬٤Gj{US0Ng0&3oSxG_$ҨL3F aEE!g/{ıR 5L }EE+y͏"o'"A: T"r8`/.B +K'NNVm<~j*WFH&xiTFi((4*7hylV];B%ErqNqUo}I)fq4̎z`M,u-$'u=X`)/G 8ʙLπFBV+"@ Dk*f6Gw3 Xi`8ДAtq;q+N^fc*-FIreHvs`byjɆF&妠u<VK.C4kX\NiA#B(PФ! PpBMiGXhw2p O6 R<4LxϦ.{* "~Fގ#ڱ8Lx* nWǣ5eX!xD v!rMl쾦i>h+t>/+?$&Z `Kr6fLe=7dHE01G28̥xlܐGnTR4xLGxR{E/ZbHwmΐ[^έ?̺2@v{-Z+QqLll~ AE)w`` ěr48INd:H]: 4.>" |rҟ,P&Rň CUD;:Xݮ#"$T>d#U͎"!6K.xMC8@1uMQ*5wwNGSԶ*}ʱsV= $oӹ`TŘ6:Igy MRQ݇sM#AJoZF` N9F~VI} ncdzGD,iq H7B&Tl=-H0Lv|(@}XeszkN35 *ˋ fJDA b-W75 )H3X,KQHiBJ~R84&Dî!z+v> 7:[-BʥYf/`g{l`ûc9LA*-mR .Zڋ}_sκ}w Öc09 '.3d_:4XLLX7b#fQh7d=|gŇ B "?\WaZpi¶[edJ[nG} [Q)\U|j/IQ9eUt#3?'%_QFX4.>G7L~zs5,ۊ hWLO՝;(9 Khmleq`XjVV]< ĸhuH΁J u صDDFOhrM_Kq2]ކ߹fVJDvZV&u ڤCc2._ J%!VA9O %ؑ4-+O_ 򔻢m')L ް/|zQ&O|t7\Nbe@PŸ}q*VtWC,`q Kk:z,ϳ?d&*Z'f"m06ebJF2 M-xVoR[I{ +*hp7?uɯ$ESkN0;?j ᓗ`CW 1 GBض4b'1Ȋc'ahm4p}KcYa'z6`iR4lyVHjT;J|  by:1{ o<H{['ŐxޙۋVdɶ† gE If-$W664PUmIWJHv3ecg/M4Q(~mDvstGxVμr S<JLi7ܙch\wf^MJ{t^F7z#.|' _4D$KCeO4-&JfAN$AyRżX;\`+؜pchf4&Szw ė0B |riS8XJfFMFeJ#ES44BL /H&ԵP,a 9<'r_%0\ʥh !٭_lNqR_vS3OXfbU|G@~.$AkK>0˖Ͻt ':]'Oӳt~sNSސ15Uo/{oWVik"k n'V-Ty~|Q#\+v[Ce&=@2'_|<#/lG1 cWV?VoH_MN;=oOE%x{e3dif ͬhy&Y9v #;JxSKo@SU@^x/C9WC ѭVYJ%D׊z`g yzDKEn{.饿s[ mưH]leb5Pu|rLxU0ۚԕ$b ~8o+dPs3/dgX*f"{Yxk׆xQDm[/ckP&چ)YOM&Ձ  LqQG!1tϲ1=(4ߔ)2i*>؞@ ʪY1Y>$z&d1F5ss7o^ӌ ?t "?P%>!dԾecHZ-bS p|ADK],jSqY)(`bI ?d*ra6̀S: 9w3 &*x{e3dif ͬhy&Y9uixq$3dif?ͬ6dwh$&xaC R3^>TM];.U SB9Vg;Qq!d''grbqdq4ļ [[M4Th?XkTZbN1X( LK @ZG!:VG44)>"bWα۬Y\RlUPYruf-VlN㓞'%6WP.ĢԼUk_KWW4Y)RЀ:h2uoNj^zI4 ! rsBl M LYRDy7Z,"f>[U^@z̒i~c`JT+ߋD:OCM;܄r6 (/W<_5kW{}MTf`7)r+@)S'&!G\ ;geaS?.ޞP?FGËu4Y}7X\:=SBuWZE1*USlp y JFqu Ły{9̜Hlq^(Y@0v0N41:&q4!iY6OG ,k4욯arMxϞ*>,Q?ҙNaO][ ȅrJ^}^Ϡ׳OP({a^P?Å(`7b]ޥH;qoxS[<8_72H|EF'Ax FtZ!咓zQNq^Lo0}jQoÿ\ 2B 6\GE|'qr(VXJ˖f) ~CʩT&E /`Z_%&˱OA{NEFD_Fa|tk p,Lj{t62\e7 _Rrl#( $ufМ_Z_"諷-HӞ2x/X2/›PB D}ui )МvLM&M p(+X7 &~ޕqv>+;nv:,:Ħ;ޅ3v{9+ -Ż ݳɛO=!a]-Yr{Ȝq {RN@\⦆ɂan}tα]oo LxɬⳀ39DSdW3;vF(,E:ҹeCw扙-e =Uԑ4r!,M2dsBT>.v_NHͩg+jNC Fp?$C!" 7!(.f.(^ZR5̐x9,itr$f(B%+ $0K줒 pbr/V1,ҥ$a #=rฅSl!^ a&jPD0?sOSDg\ PjFx&"9ѭLSj\em'$qv1XA?̈́AT4I1St󝓟;cruoNF#w08 ޹'NF.NGkw8^oNlj$ew O7`E[nNV[tO_Q N=uˬ4js0u6Pƪr+bM *aL! 2[C380|"h YT?dso a; 㛑-S59}ȏ(_VamcVf$ ^% L*duUl"҉F,&1 шBRf"9fUرU% w-JJ9:ȑxdeA!lyoѺ'n#T*?T\*5Q*!A~wq8^=C^/)NDF6"ت#uo\\h~=Ngmqz q@?\IhO6~WK N=΃ݵVt?sS.2INocjmyTc$_||Yr9hkۤ&j鲝ӲǩkRH2.ZSzF(rQίVo"KGB]]Ix8UB׼QDUQs"d9C+4+=tgՂDbmR nhi(,ԩ%QPy7a\GDi/)ZXfsiPeR4"TH<+-gq2;chŭjhzbd4hw=Go!p7fCLnFcOcIR%&AGް'y+$RAuVجhזvElj&|dLsD;:Әց U\Jh`]w_)\E#v HQ ԅhVx4t$:Vfx6p-Z K]TMYc܁V']dͻ jաO\ʤƫݡI|K]˺7OVz>|BLShCK٫Tl395Oa4J9>ޥv{"`oN&2 G#Z$|U{xsݻRϑQm5 )<ȃ`k )juG6,yxAQ+VeOEM+&mR_ó!ؙ/k>һ?PH#=x4qӧ~2peL_/׭HKd^9 ZJRo|Oy`"K c%3L(SWVO~WY%zE!pߌ+=%nkRwɃ(S3p.b|% ]RJ^-"݅9RfD0N( f~Q6RAI 5ʣO1o3]f3N'm{ye$4 &$;!lL7pQaAI/־}vMX|B.W@sdbƇAݴ菀ր~rvVS8A oFQsVΕo&fHD$V_7!) uA_Udt#@$ao^\Xeϗ_OO/n?Otzz~~LAb4"Tf )- ϶Z J,%-4BZ Qdr!֛ȋ۷P{^(DN\0L%;gWF0Aŕ6J#y{˗?~ kxO󜮃JT&/^[y]{z@çr+ley]" z-TA'i4-C5"PHΟBtׁ"n`v SkB?߁7LI^[ܨwiX؟L. qSQgH3RRW@*E J͸ `9B/0 8)}E ,#M=-e1cE|e P2ɤ !Fږ, u 6dS@ =(%VB+8IgHb1lZ93 &Zdf#]9p_TEoʥ˒E!f )H}q o!Yۣdp9z$_@zp429ǒɇYy\7q;M"BPj|t?A NN^#D3yV:?-y5O=ItM)y3X8c;Hq#H+#\:^}hvzu)S6~]놙̈́/Kg0(Zfv+b S|̜U!5X~e}i$tZla]Y.{ߠ6"_~֯}:]L,] ^Ƭ]Cd$jS/Zdh}O4F1]u;ЊN߃ zG4&3WLXB<)S HCY{jFOޑ`/ǂ}CZ'YC$6?Dm磸pK|)R_.I&lW,Dcx. |L_TS"*,ѹw"B>M4IWx]o3dif ͬhy&=auT|x]o3dif ͬhy&=au !x]o$3dif?ͬ6d' S&xDozvF_k*)gO(f}1Fz &0xeJA)$lk("J pՊ04d0ݸǸe3̪4}y')t&Xu.f;g̓ETyafgpjDV2Aca\q B?{rr-=f-۸p %&SFdh}|!_uu@ QPy~~1?~՗T1TXoj _J5ԛ$4.Tj2j&o|O+S\(59iO^"%4E4Դ(b:B)f&C)xX9i(z/nff/f6-8P4vRmY×X-Kc}GOI4rhNQGWBQAܸ!H#m̩O@$aG;%r*>?|ҧ]znQ3Կ H#hVgȧ sSCJLlxrz 545_Mc҈x*G315O E5 (.a .mo'mMr4 c|#yX TB_r:#ttq~)Ger=jZ;zO e|E,ILӣi[k(SP?aظP5|9TCn=>>[c3n1nrAk.~$ ڤ w$/\,} جC DaH'z3^xэu43s}Tem׭l9[Tۦ{\:޽ XuB\py'޵3ar~Fk"pNsu"ߍpN2/nq "H9 [\H9.¤(вna$Ͱ?׃`ؽ;bƑ i+<%o O+ޥ-cn?0èw=lSͯ{Rlq(^mbCkwGU]H|&S0zt]vq$ &pĀ &!EdUNOyd|,]Hʽ) L_.$sd2Z;Jxun.-vE lLr,{UUI%V4IhP)eF $nꅟT:Je;|(P^+AV;5nfj+WF7ݡI<؏"pexS= 4>@H)ҲБ<ƸS!Q 3mp HqБ|flX5zB6{0I[[@2)27J1ţj|kywJ(jg2c={=r\{nn5xKaQ`š -QZVzV k Or xO,#Gg~qa8l/zCLp-rt燜I>\m,Ź[,[$96dz9(3st)w IvY.`8;t. ^o̰6){TW|d$a$8OIB014wƙqv%mHj|d¥}bgRYL&p.t!$f`*p5иn" "|S&od5ꊱˉǝ&5ުLm}QI[SnH.7;)˗אj*fU]Qxz&)xgiuN¼ Ϛ%0`RDVx;P3dif ͬhyi{xuUnHV) O[hkR*?ݕZZ7PSgcf pH[W<>"Ό3M#sw|k`;F4b*"zQZ3LDuP; ̐թ\H\OIsMBy\msOٺÏx2Fv'1قZw"#3Rk&dҴj$Qj-0KJjGt0<*4"ύ_'AYRY+{-=FJ=Hl~E=˵Pɶ6QI>vR(r$x;P3dif ͬhyi;gNx{\m0 `x{\m$3dif?ͬ 6`~&x[vCuLY¸=C\}u 46{ #(xP/A;}C.n(Y"rffv6r\t*+Ѩ%Z(Th3ɼ޼Gؼz4LӬo2KEP|{G ?[SNJrCJM;dcRQŅ牗xJ82n$>cdH:&-{R {T# C(iռ=v.FaRmipyO#㇌=hYQMVD\w#, n і[vzQ ZT8纟(}oھxPDjĊd!)aA~3+u+k? 86H/ů"$fY[z23pWRAe=^/b"^q}亮 xQmWp=&eNTĢT1@1 f Yɬy9S>]M8xkW=Ar4?fv/,L(Q0200g2gcLa,`dټW1g{~ɷ#shxXmoHȧF"nғCzmwEWAH{QTqzP!%iŊ흝}fyfy.`*)q&̐S6U*$RI&}AFƀVxBW(RWlXOdj?in9_B4 uFU@&z ,IsMnLu4wRHu'C Ys(H}a=ӧ5HeFTf\X}B#M,9}b>f(,~(.CV# w04c{{=ygpC_sC;I $LIq>eS_1qeʌl1*DD4VV&S0C!Ej2Bڋ>c)Qt\^b\j_:n,ҩ]T hQļD-4zy|ޏwE+) ?nu<"oWbi tb9g?)ϒ"#b!V$˳;<  Ua$tGK< GCqx]:G*<0ni`j݊0¿ Rp^4*^އ2ܝ#y tSL5:!$;2dԠJPp 1W.JQ2h$Ӑ~ ?z'//XPSJYa/HM:=%|w?!o8_˰A{O+ k_Ót- {qxEm*`%_] Et&oǼm(rl 4kW+2)S p"/uQdW{S{5tM FW $$_w|!dbO$ynW,ܼG~(pA-0]'xA_&wѿ_Wv3\%{"A^oW쭮̸s;2❽[Ъh&'dԢ/c05Y@ߐ y+D5޽. VuZb3 cmk[U#tZƿ 6Xl}΍7^7ƏVVNvD3ftH꣛mQPZؤ␌LتPIf\,c8hB(m!f{S |:R Ma\kAY`n qbh^Z2(8k>Nx>1KsiV ȔǮ 9R=ʳ`X~ پ9HF%H nmY. Ow~y:rq]T x6Om3dIfF͙[=+x6Om3dIfF͙[=iKx6Om83dIf? 9y+?G xTao6l 2&qC ŁsM&x}Fq D߽t|,2+gI/-,a/9 L!]WBfXYҟlԊ wv)=V⑔vTYndᇌKGRLB 1[;nb*rZ{&{I@AX*Q0dZpkL(]xj1IGP4Q ;#g"pYkkI8Z:W:N]? ,xri7*i#iI\)w\XicN> ?Mhtq5{ջJ4$'4Z/RZ ے3@I}y+qt( [5ʩ+Cm `S%.A,4RaRIH6:Z26lĄּD7:>:z;>qQĖ J| ^OD'?[˥Au CFz%_oK Kem@OmB4m^Hf:ۜ[isñ-\bpo %x>Y1i<(a% |i^t^7Lb:IW;_nʊ*S$KStlDCk1Ikan{#}>|2lmJ?3 N@x h4YHf32m\Zex h0YHf32l\Z=x}kSIgWa_Lj@H0acPQy2Z.Ͼ]gVViuu5;v|ԯ֚U̚k[O\[tk'fCx~ݿ?xzYgQGqo8-NF ;E^dEP[][XÓ5h4>[]b/y\{+O$V;٨Wgp1E:5=MAs}uMqɏ56%'n^_{wl_R)^n~woo7(+}_;ʫ=u_ɠ+#I/qvpk۳(/I Nְ_DT-+ƣ}{v> G[bZ6 $v.`/{`g Tt.M zDB{;]#6;ǝDmKd Һpx 鴷7 Tq>궧i}mÒGOo-V?n{o2HgͪqjŷOOȌTY  1)q4磭Qb E3E6>u!j91\ZP\\FfqvM2hdǗl`l<%ƼYg v'A[^o3v*f md@; TY'?!H39h=]o F{Zڳetwo_md^!&ΊeYLATuIKg\J\N6<]ܔB0]qv2`dC܀ރ {|@>gK++)0˷P&m|wZOi“qj,zNb;Y.Lu:Î@bLZ;9hc7k_r}QCY[G=^CO/eVN#SwDt뀦VgRAEz Ѳi¹ 5q~^4a 8e'_g45gZ˘0y@.,Oaɞj/iqEy6:Dxk#kv!48WI24>^Kiϔ9ipaKĻXX8DЅ"I9B,{andEN%BtOO@)L,)F"g4jQtpa)y ՞IQ /9;:@N;> ܀$>HB * 9M%ӽ/(-*Y:#s\=hA|'A0YsyX.;m,&PW%pćsaRŗt|jlgLZ>7  n]р}l%k^y/.qN#H t!*ro߀YZvV%G6f Ӈ|)<2}xl0mEIg<<`],r8>xŗgk$6#W!v t9t{IdxG.Bk J`aO{y. Η3cE_džTG. %>KH.cr]1]%2c 4j3_t3x?meXleIs5Gfa8v߼='!*mԌ[ 8L0`N%Z0(?!je&o7|A`A!04r@-,3)Q"jzfebhN4Wz0hMȟRYidɉy|E){]g*Y)P{T|)f+l[533D bzYANcf_ j5}Mw$ɱ-jPKhIXTVTqS bċEZZ&ow|"8_y9pa%fR87F(ۜKټwʍ2:~;<\2* !jt`G[<eoC%NS*rq} &_h&6]ZR/f";_,ol :) nUR 6ўk>bJv7*Ʃ3>g mO9O(9a|٨t Phn4|Yo$1aЃ=E$b6wrэϸgas%V 7i@v{!l/nu6g~mD#fZG1,/-v0a3b.,^>b0<\ $`NE(P (m**L#G}1FF>k8[LMBV9\e;Xa-S\-@2LʑUt5B襼5 bR<*_h[.go65_ ܨ^PõNސvOv_$2!Qa3`I&j;2%>+0]"@ $Z0> + !>{dZ .ᅢv-,WG`WWy8Xa@bfɫ!29;Ba>=q:XsS %?Fl_+"eYPt` J !)H  bA+-#Nqc&E#C7/~ GW˥Ps)Y=<2 6V%dû@ʕjX, ]_7mNyd.hP2o{ʒ.{Z?P`nb54T65܄l4&7RY^>KЊ6wMW2b!O3LQ0.w98ƚ g$-#[4FIv̅6m ={h $#CJn53ATTrtBBD[oPlD%MhQk+,\a|F6TуPKq8xwE3sȓ%HC~8̊/w,ѹ3^]aN&sƲqR9ϭR䋻;t? SXVƗk, RS,6kXn';|TqCaCK#2Fy$ mAFaӯE5xT-ϻ_^飕?5o Gs/6? PyԧOboWE)L̴mBAe;4*LIs)B\^ _4/@o+5b|EY^jPe$Qn$ϙMb!>#!M+&x"a? N x·Kv f!;'Xpg,ڋB ?q[cHXks\V6[uU);7KE#"|w-o1}/pK5m¹g8b :zdvNXg ~mťhCkGjLd-aj Q=XX&_KQ Ęh^. = K¤IxDIM/ö>v~vGU|UXT!B>ݭc r.r8. };8%H:L h::"Z' 7נ7qZ`y3 h`2Ф]rO;#|(6(=!p޹P;O`- 0;|&"lW56sX{io|` 5]9aL$!b(NDy*:n2*T: RU>~hhD M"ModW-tn/߾y|;}d-F #>$- |&RUg|!Կwh}}12|%- K>3VX~.K!z0W$DGx&02N?6uӠ&"2 ځ#_5g0 C>Jϸ~]ZJ4g5sZO$gtdNl3^ȧ1I:P&Ip0Jeq]{o{c|PihPNO#3{'o8"wFfXۨ5]%weda@7 ߀VP-숥MR+\C9,f2O"$Q_Mݎ/ڀp [Nz۾Sg'R+/ U"i[-x9[%tq D`\ > "Bfp2&386zlnn1](J<58g>PcG9LiBСf=L(KũWrdt4z5#trUB0}a[t*N$"$:Wb?tWMl诣oH ֘(?(~AfYR &o:2}U :[rr`*$@}%s0QQL2AqX"H0~휥sIU(N_on2l6C >fmQ9x ȑi\rv5l2S8ϭH2R!GQ)aag_C? {m|j+Ъei.FsŵlTS*+psL` R*;vPDqH]Lr 7oZUЩ68gƯ=U8GJ-Q F!quH:!QR{IVc$cp.5aPpAJ"\t]z)ίvކĴ"L1䚸`b ˼x8r3@ڍ|HܷʭcܤlEs-p g~1(zfic]~i1Ⱥi*\k*/p oN] lAƒz|v;@4=؂}MH F+nɔW`J!zgNp df]lB{\:췏b>@Sbe%.&& $9BcC+DFDՌyr.ʪhkPSJvy" >+9CTiFI4b}.u2GMxCT}|p& 鴔Myʢ dcX_`[/>My4>5Yn7.吉+puP$Sq*P `z#)n1z[i>iQJ)ӽM L7 j/bZc\L2s/ UޙvC0[=WLWSjsju1݀0\)9:V}qpǸ [_7$?}1ږxvA'9nC.t<ΏT.yS\R&Uv<~4CԾsLO؜2XQ3 R&lL!G罂ÅH\"SíQ"-Xkm}lhO3$4ԜQYyiqaQ#ɳ*8C{X»N~Eymzp&.|Q=X1~n2{p q&fF%PʸVF?v5˧eΙėk/;- +ca7>.˫8{|6x,lE9*hmxkygP9.~gAn ߅k7 eCR_0`"8,Bl~K +hB4[~jDq[0x ?QjbP/nP?mEϸ0v):۴>:N~g4,Ht"}:ޟu!:,( 82As`!99`gu\S 4H\Rw1뵞ZkH PD*nxQ;<1xɯXdg<3 6[hy3r}/=_{lIMf~(Hq>דZH7N-<7@} PTt41DbtSӽnԩ8Z 0]K}|[Ij5&Q`\X|T}^4Lb2ƸeޡXT^MNm 5C`WŠZ~ "VO6 ib ;3`82o+`$9IU3=Lڧ:._0[7G1(az˕ -j XpˆJe "]<㶚() GBOS1Ec.1;Ҙ@Z=ॗ!dz§ҫH~P*/P.?eA딲`eC ISD#f#$X2.qU iQ_1k-UU6Eit< Z%YF! F't_Eev"̖١cߊ ݀=`zQܞNyJ.,c#Zl\+2e,(XK&Ť߻[uҤB }ˏRo&#,*O'qw L#)M"B B \+hT_{t$)*!Q.X \8B0 MtA)teXAp~f8F_&`  #l⋞k%8_23KՔ>ZJW+Z,h^a0M< 5.)Gn.tVv+nK.ĩ<x(ΨΑ`wӴ $ (\#F&.W6Qb% Jsǹ4sӵ<Fa/*"-y斕NB8l*-!ީ^,"Sr%'|ͯpO_n1  2[-J0 @Kg#w5HIG,d7&)פ5tUD.i[+QDA#ŝ8\F8qn/7ylS{WμbvmPM"`ǔj*,C>!i. ERzǧ)Y YTJR${jQ$'c{ȉsX廔Chw?y"И^';Q^ 'zϯ_Lz˽?|;{ˮ:D)@!GIMS&n:z}a%9::~$\_w&u2c]eCd.haE&hV5ڝwjlu{pHR'[ÔܟiD{!ᖔ l%8_ܓ^bi(+ Y"C` |DCyOo̍8unal#eTLPxa/ډZ, @{Y!-ƝjV0(7u[?[Efv&_W2kA20x˧kO Z3!febFTjQ<mt_tg9?F 1ZѴ ײkcsVt^M_RVR7FĩaCc-nZ~p C)F1%t`xP~P&hJWЭx&e-W5ͺX'##Cytyڄo@}m?Ŧ]ōG`}= "?tԈaehR`v}yb 1aWL%0Pİ#.̛jk޼?Lݺ |Grt#_%|˅bz#T҅@+܁h>Ulܛ*쎆z(|xlԋ"8нBзr0}A`1p½kR`m|zQ 308 bM*|!rK$v=F,[U1{ <GxUJAM@`Xx8;7{U* (hJK)|_ƽbcf2x^MRmaL4x!@Y'ng0*Ge-ZE 꿛Vc+w:X2m0^ 5V '>ڪ59*2yE4gE[?xgh E]$l{fheO3@ܿZ 򖟮jCMC4FLE'JPRqޢY9bpʦn VU6lxUKTQǹofj< hڋh ^10 TԔ͓̤QҦm ڴhgѦ?!WAAZAu sGmLh!a=PTtٴ?7Z}gzLc DJ%,SE#j"KTaxYD,jݻV3yT#Iwhͦb,F> KKz>65c /I%8XG%14ubdZ 659pWo3j!_X"PL _axЗ#xNуCȗ-4Y <ʢǡ.Ϡ ]ЎsgI84^j3nD)W)fp[Q4qBliy G2fw36Ȅp~J򍟨-H/ɩ2XY:8n ۫7y qާxVoEA H P);]oBPEiZ:1%YIe]C>j'w= $č#VH=_@ĩ.$`.3}{}O>lU"y͜GƜ2\@VTE)ʲ :kmpTN~]VT dTLh"(^9U|$hHյsk84<%X @5go%Aٳ=v._H 0.@^¾̭>?  ٘rG#1s4TPCS+l9>}~> 7#8 Š׍i ;r24LM1:v-D#B0;Q$ų@=ᖦ<'VTai TT4:n)tՃ_ lҼ ./MVUVVg`y2G<%_9sqc֤z`~OUaAFm:%n^]3")[NloӎL%znc:l.wpcB$  N`m̷"L! (uPh6@QR#.3H<#wڟ O/Mve7(Y;O=38bJ?hJ sރ\_x ws2%3; HT9-=lN|L>I퀥-7`E!#v %\ۈ[IԚ@Z0B0W!Jͅ\H du0>!q }:gfHp_2tneIpPeX/rɪSM1SY*HVPҏo%CN4KIضr%CS@GV:|kԻVkfz,_ҵJh?z kH?OLUUZsXz[ W4!0{?_)&wahjzjt Uwľ>8vs1&xU;hTAx؈X,dotΙq jDYMJ 4AQ7aG>J-J&"SM aV7&{|p`Z¶;D5v%TKon*-QF!\ ßk92BAl&҆jXnC1dЋr*JZ9b\v=-AFGtV:Y]@ɩO,>(,%Ҙ͸%)<빕)3TD^9Er fN< ;qk*@ONd dP0n|42z(:3ˡ?,=8;EA׹׬[&PqpT4y %` (G_&B : 02^AXz{iV`b^Ys\ ZE_g/8U 8MrnVඈv)VW-=¸B="=-^a-[{412n-A}4Mj7>}֗ZFhȸnP;lW0v5W4xTMlEl]@TCaRnR94r{]:^4nKCO^@\q@Í3*! TH0Q#!qaf7ɫS^SH fiʰWn65ɑKKIʒ?m%JM}z$,=`X>"\+peߧL Il 櫇l. p.paՔ7c9Xf/)9,IQȯ,BiTRaZ-kxP? a/m;Zr"|qۭ~^ 0؊Ox7Aa[vǰQ؇3,, fl6{hb}0@[0:%۶|Es~FQo.<\sʩiFz7`WMVגjq2ՉKuup|@W[AJ75LՅπC\\=]< /S zd̔0SSy~2]_\%3䏷덝Ahn$+,4~Ut"^\u[8@0]vo76j"XA 0r)^Eޠ4x5wf܎z\Ýs: ?g2[q\=޾83ɜGr@J< 9ttsuBuPp%"D79kxRTzwbX7-ZńJROkarV4qJS:[v1xA3,}l VVT*TH>փiPIvE=8ac89TeB  i3pL70X03arm館';u|ҹ:ܣZ/kL?=oPnt?,]5#xUMHQǹ3Goye)S_FFY/ygHҸ-ڶlghU.*hDh23C;sqDk, #"'D#~,&]w+/K) rOqh8tM}cώw y)yk!,b -pX ٷV)*ޝʤEi=eJD#xøp2AP k7M x7$aֱQ*lxĺZwNٶgNgȥ9Q zgKJ9jee7T//˷L$;%TRAPIbfI4Ō%䄾ZCR><iI/zVȵ]ֳ+)|][7b l=ӸOҵ@~Uj3{k!MU_>ޭkS3Tk^^Y6̶qLdT@u,'*D9#C8,\ΒBirh2`GY U\£6˥LFWd^_nZ >a%2L֏ ?!J+E˕*L @CfZ(xeT]LU̢23[ 6m.Rv3xpɶERԊݟ,2 &j|$>h|}g&&&&&ꃩ1MLj|1@%1;S$asw9>-l-DwARP+5ZU)J }Gv &X$;~  @TciU1dزPZ^|T0g6$~&ȃh#oVACM,~TjAՋRz\px:צoSl`a߅s|jWp6b'd IƱRϏﺞ&k}Lj6ӽu6y$^Yd[NYF%gz##:6,jgCA ˠ(mqҝMAF0]--#:7!7=xDŮ f.WPl.x0C{5Q6ׄ+}[Y-xz= GVײCJǀ$`[?ˎ05( B.yWD&od{\Do ӓK͈*'4y͜"\7qOYac8SŽH)8iR7mLQ6& x؀ 0-}YWtM!Sgh:yQL!Sl^z$Xn6OgY:ӘP?yZuc?|g8ɦqe4P L55-,t?إ %V=\(7\j+jK`o^E)xuSMlEi]P*A#a]ӝݙYGmJBM uYh*U**.8; T%n qjrls@BDj7{I\\b2f_+?Q6T͝GP\i4"n~ko4ը[*,y!zQF^9Ɛ2`쩼`λ@`iֆEKtXE_t[wO!X7 d9Gd zdE؅ŀVCcޘ:+dCˤ:A֋EuY%rnH| ?NZٗ!NS\Ml&2ϸG;mXzm|._qu#;/GSgjoIZ-"]=E 1j w|yQS|Й#sgW¥[Vl`BQŕb MZB+JhxȚ. CLm<_$[qNGݥY LQ/zUϐD'uh+ n~жQF#lOxcЃ4)! NrBo9b\j*M R NBjmh *yܔB6CT Au$ *t" D ~jRnӖj~o37I*6rOm%yZ7JAS8]*&0`8],S(͊44-h6 !h"gC#9^y hD>PnTNx t`uFx芀Gvۇw6g8"I% >BU*RĶx_.PT.|>+ hjs,e_$@>_ _T-ٶ@ن͘F\\ 1"KɎ@~)*Ou8US "Iq2 2ZA3`s#gC iH],xZsF;dSL 1Mg<@FH$=ޮ{;}o779xBx.4 Sf"DT K&i*R j8QS&͔>8QQ(:Gm$`ǜ;W.Zw'(DZ\T.SB2@yTJԐ/ ̣Uw#E,RH_x`yLVP7f5Dk 4V8(eYG1Dxg#:(~!)XsC**UVN@N\ 3X|u/bNt_oa-$lv"{J#Υ։ C;Ȇ3 o.յLҽ?>_6FrgJӻ_aX@'{}njlI1:?~|쟷P և7^I 7lp:ipӻe%^t]IseImq|KH(*k .ꪩbQ */Jcjmz?Eg'&]_ZlQ*.q!e }uNJN1rQIDŏCX-DZLt_ PD'(ZP$ȀTgN$ Ba[raYWȩTs5# ))u);(}۾vf,J1.w/>UQeJGH/(HXZzwAqZx[iy_HwXC F!Urg)jXpa^*|A 2=:\PmE*v?wbls$]{(w#y {n-g@f/C=yx*Y*^hx2f.{uk#Q跏EVho#DLp5K,6ؙד\i 4a9Gow8Ip:4Qn}s:az2YtON0 T 1 ovQfP_LT$xk}qcnr S^Q)"^&wԅӻ&7JmU:WT)Zio=_i-d_JҳNOq`|mm46eWA%fRKR:(_w .p9Qy5@.SɻҌmŬ]~jG]yMU;% V́af!@|HPa2nnfR-Z[-.7 >3X7^λx|s)5*DD؀O1{Z3͡#IηW{a "ԌMs,Tx65.)(W^^y"2YiŒ-Gx4U4F̷Ԫ!CӧF| 9+~U5FYPǗ]J}1-r!j%RNKNƳZ?859u܌(:*ʒYk%æ6'/g:Ȝw~z[JA誥 B|Ë*=Xe:v*Df'"m.6!H]?y+U"^f{ 92';1D /y}+*P  PNw7Y)QN:;X9ŭ k rWti&uD @me\m1F" 6psb[WpjĂ~^VVY_bY׃׼#]G JOn&뤣]"Y yXm%bXM#ƣQBP8CͽCw)p.K A,IDw(ݖKo:kAbeXR Xdw@ʱlSr?.^W9A 6~D?G@:V@A\aޘjKCTa2gbCQna[ggX1^htߞmNJqhl^g:(s;~C _UΏ4^3@Qy y}i9`,aOso иC_PUj{KSf7ܨu7͚V5 IOc*:Q<&9nXf̭4ؚBEޜ6 "=xfzC s-.|27k7.;uLJmtہapdE@ Ajh]C"[;-ICsڳ:&q؄7h8[436. %#n&mLJsji R;LH=*++7}Fm5Mʸ͇Fqΰ埰SurC\ULXށP [B3VBtJBZK[bVSwTJNj.WjLKFU҉!Y\|MFna-.!+ꂻFwb%PZY1nJxVU+C:2|3K zø+&gqC<ڬ1e` Z'!O:=#Jō69ύћR½ V^psZ YM gթv `mkQ 4K;O$v=Ilvp:zenp/bD<2F/_{_N#3fSp&GÓppDfhOQ b-f풥eGQfoa}{׎;3ϧ€xaZPGgV+YO7l"&UXZ%U牦vrzRLr)1(׈m S.׋N熽ObH |a/ZoIxE0 *zP@-<Ƭg wM>/^<ːgF#U-~oR9 ;=T uVZPe$ r$M^jw>U4~t^G 4ízpKNU2x~"2ٰPTٸ ͖S[M&n>" Rn4 RNNFQu(ŖM0BCkVgZvnFϝiyXb7V*nʑ9]Άu-|מqll5D\\yģӳ1ɁXa!9vACf#?V(o8,hb{xx]` ډ8>̓E{s>/=UbJ 6!6ïGɠw2{̛d{A/m-eߗ+ T8 %6)_ h;hL{I\9,)D恒ԡt9L @3J ^lcRKz-P)oT)@Ս4 ('G1I=F4?b= I@񞞩-|Lt͈i0NM$xElٛ)WsnI`ky!<8;Xl"Lg-( Bmj|H1oMh,(BAaI+>n9qqNJu>AgaN(܍Nfd-Hѡ 0_8hq{DZ@ӅߔA:腼lbZE 3B' E=U]]; N*ZK(-r,f J . #be(vVЪ5ІGd&qj pvPv6 ߗڬ N77|ޠ@a?Z$9FqTv:@57tbA1Oj]pnzյH>7z.%d%l\9]R;AtRѮBS@L;9bB[SIoe(BP8CͽC?eRF,3~F%ڦ;hЏ8YwAzF,p1 ,cئB'B NG@!6) |p ġ"ǪaPUGyμ5bF6g)BNOONH{s#1V%8|/ײGf)ʬWtUp|Sy_Ot5֪E'5*5uUvpٷ\頎=Eע>pAq6E%zkLYQS=SP#;= I #j:z=vf~& G mm;hiDz S8V|p'h4ƋJyUyujP+3Ɋ0Tfe8f/Edk76"-&$\D[բ!&T!1tɃ^~m2X$e\H*;F.@sq^0M¤5 a1W:2h[aBz`Q%}bcb?F;b0biaSu&4f&,c,o_d\hƊ)^RF҂Q,e5ZDw Ni #b(f\ 8 u#λJeCa3`*PM9,Ob5EۥQ d%\pw٨IjvU*fY EH~v(vI T[Z|;`ԾPqt߃/Q+#aXJI%;On Fx't3dIfF͙̓Qfx't3dIfF͙̓Qx't83dIf? 9y:^r x\{SH|.oV5ȼ.Yffmv6EQ*a7 K$p=9ԭ`Kŋ? u'Zᳫ(M\:y¯6u;o$N#~I uQldLu#O;擬ИMtpqb:dy#szujgkkG]=|>J磖&y|s[`nlmo3!4n6.ɣ\kUd}!aWRT`e3b/~tsUj9 ]_N/:yUQ<) bBO[CoP ^+}> y$ @m),[D| ~?vs7WʠbuDm6W >$QWZM }=MZQuTOo_c4o-$+$Giq+uoӞjvo??jyTI2CY!k@gV#]FqRTܿ0RuEjM*2(T*Z*ʖcN1`8͖?@CTZ%PTJ^jҖ:n䭝W[߫>?X[ۀO^b}sm#bu7+m\i47: Nk|_p\;$æ)aiwj74'0KFd:A!fuO?wMف̕uxƒb prpZ `*D]B,ef ß(,ܣ3ΚOYrVi6= NNQ븳QvCd7j'#Ss->UەFu OP HYO*i[,jHeQG[ݘ,MPIUv+APpDCDjk<˭0+YNTa'}tt[(EAXGOBtIǪxf'QNGag#"seoxxQ|U⫋7@@!d"z b-x^{~E篾k3Ό8ey)]ͯ; jjI\;3NR$`;h/ɍyM 3]Lo nXK3CEVSpe%R(M!yW$jPS/䢍Cq<ɲvmH986R8f)4Pq\4f]0g<}N:[P|츕"i4{$FV@Wy(V85ĞYfB,L XBVj#J^m7zzrԘ*"Wh?R#1*jA{9V/=uޠԃpNЄy3@>x~X7vkqNӄszJƌ~ҧJsY?Y^,hI$2>ERY fahU7Kc )~|N٤mҡrtHI]0#0OHdQZЮƮơx@ѻ&uS-}<%rGdB}%RMZ HרYe, |%|%<0>ګiD/lxGmI`sp~k{̯5=M 7L&Mf$=a2R_0ur4Z.`:f1vD5Ha8Jn&y:в%6_RݙظkzӶѦsimп0z j)ԥu>vM'&)VF!S}^݀ӑ?855KG -V6v~WUЯyD Ia!bo{.גO9N PO{p?Q%+ٱX©D{6.fy,ssatzPc1VF --jPh&ᅾSE=U7?f}#8b,:(fa{֯\[`pb{^e=TS"}Kg]@è )%autG| c0~ '::\I^Mu/ͻPu:@:ٵe"'{⥾=[wIR3g0B3;\#ؠgA(aMWE({#3r&)(ykip-}xhH{S$@VN6<Kꚝ^+F 90 _x+i}`-ԫ6Z}28M6R@{ 5nt`#5uVpΰ̴>4M/1q2A*>xFMWPu Is^tێ`Gq*w9X—<"Kac.={I; S7~+GTMƶ`)4Cw) BˋzQF<b"_[6yM Pڑ*YqkG笫bv3CNÎcApnËo_!U#͚# )t!HWH4YL%L <-ϬR%M;%{hnZ{:bRe񀩐 *ͣɋn ,0劶q=E|ĉ8J' Ɔ6 |Mg@p + AeNԧ{YT&&kK|)St39Ke$#`,SMsҝFkz}o$X@@$s'Aeׅ9cgU%Km'3J7J׭bݬnb"' ++'~iVIRVv¯׼ij_Q^JGܗwl͖qs/@zsHᒅJ,v:k`]|9%qry$iLUG>IѾڢzspjK&@ >2fώ)L{: w)7l4Xͳho`5Kh4841hxip >[vwZ1tl-3h;2<tp0ituH̅<4+&8?TDζ%(΂j\5B+,7 = X Ft,`5DΣ=giDoLN -HιJv޾%K@nێ˥{nUE΢+䞟JO{q/2ƃ:"]OiՈ HQM w%a?|N3)'ps WB8 /Tn2ŊP̳ɇ$c]q:agDɅd6,G8$SdIs*G:7ȓ;5%?lwMt)ɋ"=nBk]w3DY^ݴ"Z Ldou4ƅ2"tڄYHiGΙ. 3 Ӕ/ݹˡ$n,t9)7a_lu[_[q4CƧ͝-Gɯ_m)UH~ŷ _$\z8jdKKS8\tϦ&dmР{9rsu< &c'_&gpyq N=ӂ: 9F 6t?#6cC jkҩ!jiy?nyt3u#\}~ĈHo++j:Op^!, [Way'"tzS޶ԖN-APNǸǨG:ŽS9N)s6}d4z\s>ZUS P'AvpK{d*uAu6]rJXLrs8Ozd6@.嵵eejZKη'E"ۄd׃$W0.ʑT"iЖ0׶rp!Vu,Ğb&"܇%|b<;Wƛ,{σP`!חXdy֝'RR6Aܶ_Wk*1 VA)dF8QFK<}2-;o>\KqY̩4< b0[jy㺂Dj}&Vj|O{,,/Kȇ8cjؒc 38gZ?az䰵4Ӄw1ֽC@,yIȝXI,\ 4D{4I {{_*eyz&XVԗ4XkTCg]#rSp r1:EmZ03؊4#!?W{q4V*Eo, KA*A818d\Ȝ*h\X]cVs{ =T񁘽=ǘ{E`[] H:DmqT+ .`2@.PHeg'+7?\l^H¾*Г+,dmyE|S}0u j7Nu B-=^Fnꁡz:5"zY= ?as 5h6x=q 6Fmy2$Sx5QKhQ%gINɯ/LϫEhSQPKW%1AfLc q p\(BuQ\V1kuBu#.[f͹syv׋>^ɗ?d@F7G| q_:+#m?J%d 8/1LNJan "3'q CU"@E|*mUT8g4kf4;aSY*`V-RyeRQͳDzZ44yxe m)WXK6R . WBh}heZ{4ﮃ`vy̬{YMǻ$w 2-JfGoUl{˴j&8s2>gdϿ it* %FoNa7eZ <ļEDA;4ۅEĊ1<@rʦqJYw=[9<)N3}yϺzEu͸Tf\H$J4&,v~PQf/=6>ޛ0oDx3Ր<0= )/=j 6 erro )3x[9fR7IX22EN+9Q -x@\Y1 h W*ok -> _0* i $ n{xs&f_FXl9K`mxy'r5#f[F;dx7wJtrxy"l5#f[Fa&I\`seͦnbN晚Z]lUTQZZ_Y\ZZTZ PC`r:d7ddIK,.l*g49ObxHFDbubĒfu:?_q/Q=ʦ8|;^e7h*_N4UsO=z.>ݫbl/݋loO5_n O=~0FY;ÿto~dǗI}\;r?ȧluGt .?l&nz9p&wKSM6&ݡ{;zn.(n4/@=9csw:l>=Nam9ٝr7%F ]˃Ծ9-Ra0r6lI`ۣ{q=<ZC{6{)pZIw4śo냓I?j]v}rn۽=m=:veRK`O2Ϧ0/"1a]wgu/MZ-E;VPgnpFi} :ӱ 62nQo$2ve-w<#O0 '?~飿cywx)=?-ke0 L{*hYx2uO{o+ fxWծ+4|pApͫl<>Rrͳ|ڝL>iۇ[tǽ0<ʦ8(泋7kMsEwQ6%K|41Iv3~x2C`tx3T2?d G!G$L8j)G}6dډ 1~ì>9x Զ'2\,>-$uMо#vo|ZvodpAs!\Q9FYY6˶Zv#c'@gJ4#9;,oѸ5 X̻S x=l38WE>j$֣Ru Fb:&ص>"}wr">pDśWZb"=#,Yc=k /[u=ŖkƮDP}'u{-\Y=-ew4}lru6ZDQœ oN* ,),zz/B Nζ)Mik`fat_;ט ?,91q}t|Vy"#'$@b@+5'glystoR| <ƽ(gXHVas U}Ե]“/ZZnbvjL˽b hRfBm{Z!*90󡢿 :Q<>0 (!<^ z[Ӧ -rxD8,6/g#ƩVdbT:ia-(%-8T&]?4ѩI<4tϘ?<[/vyGj=!{EUDb| )e$D=Sa! 8h &-E2<^+нOc9" ] 2p9J{u~|{gJ3YwgO{E/6lpI'(= ]X6:;ۈٷ|s^Y^3v2 45ejd " Gb'VLZ~ް &\Ir0n;=JRnFw5RDDDoRR0WEbdusPil.lC[6\ a5s/nR] mJF~~`([7:pnq[#eM7@_`&BP$VupWI8v7Bg ʠ{"V<[9M X{^ `ZYmbJVՙ9wh THJsT~Ux#7TR(%S{|w})`)ؚFnaq >itRq!ߥuR1eeС\Gzh9bc#º~w-hoH 3c il9*9U`s4;xEO$H=]xN4O%8QMxG d lNaOF@!!HߊV@;gcaeŸ> 1le\n&׊ rؐHAfYl9:平p%sD2a޴€7*t⠉ ~6,UbBrRC[SH!= $ANRCkg! pCol|$gSi*[敹7͂SeIl-uix_a]9́NzJ '~R%rnih.Ȫk {-v7$:LP[^@):1vؔ1Hcyl >TL)ke b L2-1mJ FW9~sYoMR)bE-@lw{dds"'vo(Ώ}rBTײɨ,0N1" ȖA`~DU)2+T "X#_@:YW/^}}M+;%ȵ;߷1xӧϊr(8ay МXaa[ٜa5.z,<!G%/*0H(! ːYtLɲ)X,UUUrorkFq'&=2>{>E"CS 7 D W8G-=~4k&3]ED7jU'0YIBHUASxB=٤d{1+ LY@7~S7j xq1$y!YC=/ᙌwڵ$˲T%,Vvr VL\RI~.F5gZJ_*)cYn隵4xnH4 i:h`}$ ]m\LPܧ`ٜ@D->=fj%o N}tXՃ4=J*YpUY2m}}߾e"/ ,t +P)w#ʗю"xd}#*2r3'-!} %]-'Œ,e+s;jf$?Ʌ04AC#5h_":M-Cђ.r&f Bf^1kC&y, IBMU嗓s~!\ `V_#*e s|{Yה|O8_^b6׾_9Βrbmhes csl-0 lcQƃq78s&~At~`x@ #,XC7SyhozҎ@ix`( ]T1綴 CBwXӄ5w>Z-؀|i,  I @~zd77ALlu!-ZL4l}? sW*4* R=1&,PV1[h<*OxK+_`6YshY{zY6eUG3T,NK;pk(E NJɉovF Ŏ`΢Fe%*[(*?2jGS5B.ti-XqQFDXQ&˃>[Eք}9&%Fl\r%( %%C(q+ղ0(ųlR582%I8O~/ҩKY`cٓU!'7 XRxSskCDDZKC:.r.O %@=V~\UYА]Dbh`YW3'2@af58 Ω#Y*2S[(y1n-ZDbpI!0$ >vF3Ġd+[1kex#~mo!=<&ә̗lяDdgg>0]>t! !nhfT^# %>n+=?!D%@Re'`c?*"5N7rkR|c|0I\pc0nFt8cZ'[y,dX1 E!DTP6鲼m +2AA.7SZ}2?X$s) \Ռ)E7AIR݉J1߃q`t\4zt aopha]׸D0ܲB (P0=XuվTF`qxq޻'Ʒ(篩ga%^<3e6»bvsf Ždp\yѭm:3`Ob!W{rsoVPQWDQI@{Uq2.`0 ^*n5?B3^Zj#5T^ԛ\mȄBYaSSb;R3 q-R 4<#s;iDSrumOir\>=2cVDX,mSc\g U C-;u壷qT57rEhv d꼟$ˆ=C;V*X[썦\13h =GjZ,R|RT8ZFkz  ؿ?r \_ ۾|vKC|EsPfd?2:O0Q`=J =Ñ9 7/TqS63̏C$B^8G7Ǽ"`+B%+x<%(ejkpHeҚ`g=B #\Y/h?DP ka[0\c2p/gh.=?}M"*`A'o u7D9=|K{8нms0eWր\Tb) ~_\̹>)>5P2SRZU!xAВ;"S@+M wH:SoWO>i$әK3SQ-k\`¤^Ӣ_+8*}ì;IloUIrs5d Tl%mOR T@ӭJwcN?+|7!7 >׻WX⫽2_w.y}D u8QjLHX" F>>hfC!I5m睫1ZRn y(d<&^Ii E%&9?#1 *#({P}lwĸDu2*9_uak, \Y_4cX=9UMI.s÷NAkO-山DI|PB}{o7[s&$ߛwIqPcY Y%O{͆qof Oyk; ;x7ll/wcU꽝zsFbη%b-D剢u q 0 тPҮs`GmM=!B0Dh fQW&@|KAp i Շްsx"y .t@ZD B1%p!Ɩ 6&j2mҳ^FxRtcU-ISEߞn@u~L7ϔޅr,F75p@B8Imj% iF4#8Fq&s" _v$#SwVUC9~;mk d\.?ExnjվvA BjaW7K[cڍ5{o-]6]|\Feh̠1GyV 7iPo[W+Y-*LB'FH` *kQoqai"*?*!*w٧s0\@]h7NCH.<Qem5|~#^7[%q#S=}|Qh)ʕY?*er cO5rbH@ ;]ߦ{ 3q7mP'KJ$Nd_%^Np_f;&2~K9*aؑ3-lf+"DJ `zS!0\qZ㉈toC+v9KDMilAbZ\.LVHs&NjB<9S4*Q2V^̗_R23a_Pr'|׼-&-55D5GWyT7"phJY%Dzz4%=*{,QWp,3.|ј&ޔ Ԁ~կH3*iZZn skKų$Pͽ,!c}$p<1HF,:i9c/~ݿC 3%4duV.V8x7i#fC e'?r,e"ʯ__59Xgr@V%:+*$'*g)qqMjRRtPuƂMK3R=f+gVTũ%LkpqrrN>`29.| ]1ّ[lsO4Jx7 _'/g%0mrB |D؀&n `  xgg`hِ1 . ^x;7 L e:"x;7 Y,'+m8yf)?LyY&⪛碣PRTťT]B؃R=l' 3pqNo2u+Q\@dY__֤ UɵAl9ũz q1y)i`+"9dlɉ% em'+sFx+*L>/' T,.,HJ攀0DmFEnZ ,&VP|Va=fMVU&M>kl?0NL4Vbj3Ӥi2d^ s!_A Xf]FNABbS-6pn>ģbdJ+u'n>wr}JQf+ Ҥ̒%MXkStASrK &y#Ux  Eɩźm9$p.;=ClSsR&+HLe\# U[kPRTjʼn%DSRt <݊sO/@5S! M TK2^еO-Wcr8Jϒ\"M& ㋹J* RtJK2Rjcu[iͅ@ p+$RrfupM%4&O6rpuR? x LJJS,YJ{=xq < Eɩm961) jx ֌mE@M+ gx lũegDBXzy%v\ ) ``b__\ZZ`ja`d``k`k``hbe`ae`[5kr3*\uM=.ݲ< uԲ<+A* wp2N~My2WdN~2ܓ&iO2ɯY[y(j;&;XpO.V`!bC,Yx;* 2J& FF V&VƆQ 9 *\&w22N8qr L'|inNͬTKJlgIjrQ~qIj^E"Hx%m;Y@WDyAt68&3 Ɍr*PEt5HBXbNBDgl''LS Ͼy8d-?5'hhqqM<_Ky&ڌ̓W-ܬ/3N|;k![@('qcJ';47vp "U& Wz UG!)1dd^ 3#L9'ύ1Fb@9j7Ciy v@弑& yřVi9)9@рHɛęyEjJBm+y:TZMܜ y)+&e5u3kDֶZ;?u;ǟkyI8܁ (ܼ,棶 ƸO||z~v?w:G'?@mhkx{7Vpx>AA՟ÓIśÓn׽9}~sr~ǽ??iWXE\ģiOz3iF|PM3Go=j<_ ; y #F%TGG#pO`PO{Iy`kfW1"C L| c~CEy7yj*R݀fm}[Tt7ByB4@ C7^'^ 2B;q4q`HSA}A-<+֒G[_WQeEgqHktY=yimb"w@b#bQ̘BVd̗aeFϧ> c,tad8ČY@w]TkR+SN+Z97WlN E# s}M>[4Qo\6a!sJf#=j3߁;tBQ-Qߜ0\).gL ҦGcDd8 t_L3|#O>kE6ryj?OD]2!S6. y㖪:Oo!mKoY$̛q$(}o,ġeP~:a</\$dnPHOn$G R%RW;V=`(D c0Mb Yf̽ـC#d I~ӡpڡ+(ȶ3i%M^ݴcb.m0.Ig7Fq 0s]p82&!JG m2{TW(t6w!ɤ h{?iP1׽l6m阠*G> .{ůY= > gULLcj* NTgqwBzf ?vX!Z;{!@ Q3.aqu7_Hi#_a܎Jܫ+'UOS@Ž]^&=|go|A.,dϼVD}&u*+T|l\c޺x S z!cqe0S6Z|6 1_ hTF cW60dSRG#DUaN.yfϏkM0q>=KcW1zo`lp(b+JsKpeHk(1GoӣwA&ǝl^/s/f:ZaG(ZdOuj8BJ3e9,Ȑ/?p|#OUJZP!#ͮ ^}8]טA}btafM2?ҕ|Nyj䅼eб&"/?o 4?nT )fRs):"{ KY/J3 dfzLj$r:U:Bazzow6//SPDT4SL#*Y (~ ё\c`1ev1Sʼ LĠ&Y%JeNY;&,IksͦP͉>o='h\ u؟ \oyUT1#o$DQ{&Ng-1%Ykf EZ+`<P뤠t&> "^[-2# X3Bd2 MsdNУA].\;"۠Є_2|][#`d ]Z̒#uh&wڱ2lGl1ۑ5УI] vHMB(_CFHF. tFU+r[j#M B~scU.wȘާS+}x^2$8\d00h;,I螼W-|\軕  {^0ʼn`YYbe%o5]#R.'ÕE#Z}5qnH2$W=`$G)@@'g^ XN.$aRDr\T& uAGKzZEg |g_+!Po8+3b&ٔX7?ZO ErJFb$-FZ;ur@BgޱCɐC,-}2?#S{Q3|'q,z:3K!jTS3듮lN ڋ `vEio\M5 slcXڑVX?ꄃ>]#V/פBnaT|姗^m[ZڶnƯV2XO*4 -fr]{cZd"Ʋ^Mlkn8)U"'5$HKǦ?qݻC0Q/ ۍa=S ' 1ͨEAߝm5uߞ_ܱuFxS jH=pzdv9I]قQ csYAtNg!xYE,L&d @ߴlUc_ 3f7"d"VB5!K==02W"q;3@q  GFO)%%CU5y"J'dnR7#sM{@MΪqUVMI;PF'">a,r'ǯl;~<f"d^)yP|(GO eDnjC6 VHM6 6 &2Knh=_,"*2? +[1Ua-*i~RıfBfgksߋҬPMa w`rNz\9>0;f%{g,Ć,;w-ciS)JNmy6tաj6ke岍3t;&mqay:C*_[7+ERZ=]DF0(}Xbnɠ@p'͌˦VA U +`QDQ98oZ߈xȨs[I ĪW&ջ"[O]IJ:y˦GX2Id݁)J pԤSa/{ 9D4-xR˴t{fߖ@(Ć;vOz(4ƙqyC$lu6TKܷ/ RHȓbMdh۽`dp]a5q-2Tlש4W:A~ӕ|!I42NX6viY|H*l.y-4bL@"7j!XV>lZ`UЪhRIH~w L&k@KŠ)LI1`kyklӼCM%P~=EsƝ 9B6'NX$\]f\CoĶDVi%T Zj:AmP3I6xI±!(+<.#B^ z[2W❑F2򞙰;KEoSޣᢧAqtOcut,h1Rax-A  be\t?06_l8 $_0A0 hhLdkm EAi[ Ruq5|սH:>.x^A7Pŵ}b`*4qQK (Us]Kү@f2lV]q=V$Y!A U`VtY M M2m+(n L SФB> T)\%'^f%ж2ڪ-m4 /B-#+̭+ I4^ҶU|4gjWV|R_ Ӹ&|F[ Tp+cZJp?FVljDKmtΛW Rj*yKmYaD>0dv ԸVkio ӷLg- k⠕x&"-,Y+YWeHa dFdM:Z\%LQAUDuD>VɬoRC̃[ѷlPbӄ3&D>K MՈԓZ&Z[cıM䁀*K0[ѥ0+tmpMJ lFVYD ՐW yA7uߏIT+4`ov;Ojy +`i/C`}5&pj=VzjI `oL4-~nLy䀏@?s^Zv8faˬ[%HBFnP~@碎l"_YV@e߹1$VCm[̄;7r($T51rewaK)õx/lfAϴd%M~衬/.ْ坭T-1H"ZVX4~on!Is ݷՐK!\v'qI3^I{\8|`wkhs*,$D+ %}%K'ŒN[QDЬe)m|G`1&~/\ c|Kw ,qrnzܫC:lT%Ň!_f(gy!Qo_-,Jƾn;mfKl}ߊFflr?X-N)MןSf5~փMܹC~7FW{AHm_~ٺCʬ.;\Ai#q/gv7Ӝg(:c7T}:-AN$_6D9|o3h4~ӓنÝ`@d^W1K9'S9bzGFLJWbW"EIRu-tRð=$*瞇vil^=2Sop^] 't*XM6!9=ٔwؖ5! ߖێ2TEquW&29ڧec g[ 2rv5 3& iEْ[uD9wd-ŏV>UNfX3 O)u2UWa)*A ݥ;+n(k&>L[ek)pŭWd6_`מW8(ړpڒ^8G}ؐ(YlPZLeY{JewYǠQįHQ#@spJ9Kww ͐S*݅>愈8όܩR:F}K)d>*JtI~ [O}V'lZǺ4%&jy"ųIVF 0bIxDbu,^ClyDePF8uϽ-E){ XZIvW$#:TwMԛ&:Ma}B-"AmZL2o&U#*_βi%9s5)UםrvjmAxI}ÃL|K*q)4Yzl^ɨ^G"p+4Rj5:(p_qK& 4W-39#2'N32HDjX| ,aƌ؃MKŃƑ_`4}]? n=^le/~B+BvۓSy5ٳ|hcr`RPʆX4U)-Me5$23xaJQ)Xbs{$+2ruC+ gm<Bnࡢ qjWY//d=USp Ҡa9 #U+u@I/CH# QܢFJX#:Q d]7bYL4솪Dوn7#F?7A>ivH<%P%~e,ǘ[).ɓȌ >MwH ዏñ/=LJe_^Ggӿ:Fkϼ[]hbVd~Rb2P>X:pϾutS,ۻ'#l}  0u7<a4|0{\|^rr?\;D>oX"}x`Eo\^cɜQUOz!.wX,r/ :~A~t(~?/go > x{B\ z%*=]h/Т ]tؾ 5_ddV&a\aJ?-x BxJi[oRE;]_Q5V^+*E=5Zu5=g/_Ga]&>Hŭg/zj#d;+)x|Hj x& Wͺz{\>#?r,Q`@[#5,w/۽oQB%DuJ eR[v&1GwNmE5x>t߯汒'!AO^zi٠  ^L+8 i Qdzk4Tvǔ(FIXm  ꤙ{P2Ħ9*j;L=_nXzPA^?=݀!nRǢz \pUFg!JPn= blU ڂ@ 56Qp:pHl 5$6t5dc OЖh>D(Ayp byw 91Nj<68: !k+Sv+ҐF@9 d#zZ?ۮc-77|&i'= Y[V_JlbuѼ-f7qw迚|]3fBo̳9.>Bk/}6,WO+3A}6j% aBWan0!bZe%ev<ن.ziW 2YSxc|.[iMJęl w} ӥr 8rB |6K~,\Hl_ M+t9s,–I$ɪ,B.Ў/> l%fo27n'z)&yC!4a)\NQ ߕac@B]a u6ajA&T.396^W7 ;5w2]+4 Q͙TLULnFȗJ63A04EKM9B,A Ԕm&ъv{RFyjf7S>.J_VQD~$ұm={~k=ӄu{ l)# `f/Wf-7Z{.mΠ sks*&م̞Ym@P{~ϣ/*yQ"P("Qm9~tKLL/'iPb Ⲛf 2: }lO #ĀA4b D{B6iD@IjxF FN?S0xi wrħl>$!3yzbĒ .N0PPH+ӨQpT(HSVUtQе*vxMTXlj^P{Q~iAXbs*N-+3*-(7DC)%5'($Jbt'tgԙlh(2yfW6abGm~M~+-nH)_xۺj lnЛ6mP"Bـ|g N| {s2+Vj|'xUkU3.Jl 8nֆfC`Ijv kLfovWfg6Τ-e]>I|DE$6[p^=g}3O{'=o=c !jA 6 \YY{kcje_؋[iHSSxh[^yU/ߒ[JRNMmѸDŗvIͼ.ޙ_U/ oNpG4L]mLm.{z yԧ uyka9 ۀ׵Ϻٽ%~Y Bv${P0+!y# >-DT.- <ᥣu :Q9"*'s*Шwe|VܢY#gFy&21 `vIЁT?F<(; B3ˍJ: O}GC?`(cqy؈f&Q% ڧZ9bf*R3P)͓bW'['m(PN٬Pt$Ín `R>MS 7 [xxa/HDo_6U;er3k.tVPhH`InԖM*V: qJYT VwvOaɉPX>1NJ)=ʒ"ry\O3g:2q1&XtHp9{8. |2ēo.LՀo~tkQisl>7x4RGĘh̠5<:asF_MtL^MU=:/nEFt({Au|8 |ւ렶y^Q#T+|K`gur?&܀عkks!f\9D;vdv_:^Evxۺi &LO<5xj N>&7;xRkAg۴5-Im&[&IҚ(ڏ`(v3iVtg)j*yY*= ACMEh rv5W#lr7z>󸠨88NhJi.Cc$v8  $$p@1@ ޳b'>$Ir[m2^Ms ݨ388_Q4DQA$%QV3((DPhj$d(xy^C 2#ǫ99' Q]/gw䄤\Ji)WTȻj=mZ̛VX#`sWT KYT>O,ai-|Q,b VyVPIƒ0Vr rKw!KWQH}Z$$)+T\2eeˡ$;.yn @\6G݉%XD,Ibh2`m3qe3AtKIgp]~LWӅсtz%Hѥȳvfׁ\ ڇNq?Q7J sz,j-HXKRsI~P䇟z2Jl&leb׌uX[{D|!!C!RG G0t(GBa*ՇvIJ鿠5w| aGqbd dW,9U¶;rEX~6 LGrvl;mPpv(5EkWʠ}*/a .2"ZP\>'+r4+JO/%!@xZ\nxQFΘ܃GJt^*Zͮ3صB=.`l }e\vĖ_nϑ7(@qM2Lƒ>fb3[܎oK̡ ~daޙ~H7|zɬoNM \ڨSjPszcCuraSjsl[|o .v2->f@tgw= n1Dv{usv{f |w/\ط: ѩRk<ȋU/|<}zAt: ua}dS WC0y_hhJ@5Drqg]&9 %ghC8_`ae"RThO-741$XQs8CNCf^%tfbcpgwP de dH&v`xUoDIKkEIբQT[rH4lHQD)h-e=]䵝oJ]m\FJA8/p#y3O_N?αDmǑH̅@p</;'[T'GqԷA1W<.%]9ZZ-1g=5ի\|bsʃV3ߘ]yO6{ّik}(909'ObP×.*[U_[ xΑʅUzoĘ42Ԩ&E@_n {*+!u 9zgg)ۘR~jT\Bw{UĐ BH*NBjeYkΔ>+>Yps&]ٙP&_OLBE2rX1Nآ(FxE"1͠f;Cl] P٘>ݒq{u$hk82b5xrPrN6@QR3ASg_78 ~SpS_p^@&:ఞROr[]e[ZlBi <`s];/)a|iDfΐ>1/VBHz!p‡nDx)D0<ŷŤs4900Nߧ~&MYھվ538K-Hx´i)#f3FaȈXrK6Hpqrre+N.ۼ` -$Txrq$Բ܉s ,;.UUU0RPLRO//.I-OIJK-Q07P020050"C+S +(< ^Yl8k^FɩI 2MN2.NQج q cr5g'5@6 G4JSt<] 2S2ҢZeY5&_4Tk~V2r @ >@:\ RRlxs/B^@O~=,I%e&pN>o͒ SI>iP Pxl^fƠ猤6/e<bLMNZ4QdoraGcJ%+(G A`+(<&nVM:?y]fTFGx]a;#^d&)"R+xVoEnMJC$&Y'im'!iJ"[P]8quv(XQE: Bi .= F%*#}#Ç_ φ" BȄ$ABt*6heaķB{"OϧMdyM.!-6e\N㌑/y]ÓaNZwN_l2&t@CnޭJmdDܐJ+3g^3GY]MdW")ED^Vp0V6 '+$yŅ|+7 \Gxh/,%\y^ РNB(%#\ypa㈐XYl?g Z||g )|5)Z\aDۧ%ޡk~GGa9<5t;M([`T 1̜;9(*3"3Pa' =C[-@<6T3gIG p]&a6<;mQC~58u 5& .\M0,:h)rWI'Ȝ|LghgMP$NsיMfmoR qw  "us N&Uhk*F=ppV D"_8ӷki҄jّo"o6TT@/Z\]a~:E~_8yA/P$_G!tS0ǯHS"`ЎQHߥd}k[zCM\L<s/ǟ5t>>B2V:NG\qrmdڸ{Kƿ/^K&G=՞*#a !rC J%d*,S{5,&XU RѢRlʚ?v`W[*XsINs&wj̋ @E"vSw؜vJ4[*ArvQE**"dFtX`TSĶY+A:U:FOcN rbֵnrg=KQ*+MpH$T-U,Vp @/< ^65cf'ڄzX-N̐>vقmO:Xg~O3&ΈQ9,Z&X[D_r7ࠣ YgEBq#X]cEo{3u|W{(Y=>JoKf92F7glGM^ö"b7x\UWa3ԛ s:P-/aǚ0&O\c3!)Y ^L'~B8~"CA?Γ4DxmQKLQk!CP@(ajg|TT[* 8J;` ބ..FMdhXueLܸPLAmn97{Z@ @wq\wyy'C?e 㕅$ϸeIQŗZg܏N) JV ()gspN eS^eEȪ{aq* >ʺǏ`i1E <+,3"5! VAOw'LP ֣neU!Rԅܼ6!k;7h:L{ )~71Lmq#O{) =-M۪`(;:rX# U1fˏmb)d72n$mp#^6xp4Vkh%'XK6@cYs q'(׹Pwzn?l`Pٚ{hb{BF{û+QsvtE"k,͚i %œuB0޵IbgVD9vV>Š&OkaN=+.Z7SX[bV2 =Eb5[neɁT]\e q4)A p _0C4<3!#v])AKf1)$df̎9+E:eS@+ulPk$ַWG 6T*%PyDž*Wwd _4`x _8dMEx_4qS,3k OƽS > eÓc`Aoza4.&'- FeG9-%a\h=nj)u@nz F~K3mgy 2[8QcsȤNq)/Fv[|Y? Da$XL垬,QۇORky8vyx `StT+޳Ѫ6;Fw;26gHrQoYD nsMAǯV(Glp4GOr8<*A9Z5vZfyEnt6Q*$9D9o\cR)ӳiTv!h;ёcF I,v1yv'aKBanY" /j~)H%f4dKb'B?m#R(g@ё^6ꮒއoW" ww'Z͇"Uz)PjMC@^* ] q۶ UxV\^u yp_RώWղ-ݽ/&4x;/Ud;#B@Q~rjq^h&o71d fx;/Ud#B@Q~rjq^h&o71dY tx;/ro$Բ܉sB ,;.UUU0RPLRO/N-*LNOK-Q050W02005054U002425RHIHTPRbE:Vƹ$ x;/rNdC0#^h&9Mnxx*Ud#fO7%ynx*Ud#fO7%mGx·o ļTļҼTb@  FfF VVƛ0Mc񟼕BQSA׎Ky6bwT_-9Oٵ띏γP<磬(lw-U_En=ΆgE6[Hglh r'_4! I6wܳz>9;_}x@{, 'gy"?]|Cʍ3L|rrdᆳ|.}k>[gL(\~*_^=r/Y6Nd^OF OsԳ b3,܋I>{ l^{hqY{ s_0vS;]ɃԱy~ t~L$sWEvz5`۫wvZC6)tZp AݫׯN*^:|{n߽zvzu߿:!,PVp.yb8% `8 eoFФۥ(Lh6J=rS7i>,rA6/eqfݎ? pu\~};gf_:gwԓG|wWӬ];w"w4پ{(c, Ff//ÎIt^ ŔϷܧd8F6-\±ڜesn aquR1mQ~i~lmNm?'6RO=L3 \γ"2d:nsEʣs \-8zC$fdZ]WdmQq=w}edg\PuKxipU;7Pĭ-.,8b">d1ywnwV(o0.dxv  gR ,ygr:! T"^P`NɛwϏ^Dm;7K)X^VtUXVz< `;yWD#]uvR(>vXujNVr㔍7~j$!@%dnıJu<E~U .b QwQ# %c &-jDRC 4uzK^jkJ6vw)S^]!kƛ jUUN)*ud sKL3;)U2m j*)6\mnM ʚ4^́7)4m3:/rz䶷+v~ԣ^}#xoc<ӄKMX_i^G;{|R1DĈ$$tIZIn{K{tw:"(+(^KL'<r"DIy VH,-EΞZ>:s_7+P%/Ëe*F6KI.- P+kWŏ*ʣ2%r'9:Y"1P y MqYg c v/;|FfD鐨6Ye (%Ô f &^#JSHRAQ)7CbPy cIE,ʹh7b#Djwm <]1K>zI#[o5M%|t5Q_XJ IRg j*9Lڑ7le:[9 60Xmo(`^q?8cAs7t=Ȝ>QxxslVY?3|[GBS!UBFI塽ᇌsv&$KqxXN~Xiޅ\\Y6z4T/[x:+(qsSy9  iQq1&I ᳘_7ʣA~5i ;Ȧ;2h{9n]w:O%l 9 (Vn)X i,RC`5uLEb\]dR٧.)_ 6T۫nJf0j}i_Uz䄧4П$͇p B< ,|Nuet>+`0{\V G [m:]xn%K mƼmЫ`'݈}P QOϜTXoOC#NHu%73;V#$>vOwÃ.TZWyˡ;[PPF30 ݏ ._#fX^QPw/F=c[d;iVM0qOi+W)1Ѻ 1ITK=JF<2¾nXct3D{u!T._)${Ra'(&kD[#,0 ƝʌM ^XF[m:yjɦry aTc<Cz>:}9O:Ab h ,r49aT'H tֲ%>C?'6*DwOO(A:u4 [o0KŠ#_U+͈Uedq^d85ߨP:JBrc酔z[ ܨf_hB3σfd` Tg~ +(ڈOw:A0;_y*}AKz&u9t+KNh2x44$q1cÒC@ ^]ع_켓B|qn4,HR|8¶K4 |_“]fTd@cRm |e^#8mmeE!A|7X*X- j KժH\HQ ,oQ).k^ 2D* e ʞ B2EJ$ፆr,9&wl҃ qt.+U{kf?_ƞGU$M/M]FCuw31lOM-,/K-"t)LPqdU*"򚲬,Hzg3ER=(|𮭧cAJ*"t]L g// ؚ=c|/HWqM@vqg,錌;hKa{#]Ispw?u\6+T ) )y뽽PQPн"mj*1s2VVBc3 .ʟu pM@ Y œ~ˏ"B YQ ji/ K ށԾ|6 :`2PAk|F*z}R38ލX6$jB37˦ŦO- s.өJ1NV&]jbƩY8 _"[D̅?9)J)< ITv_J쵚߁MH<ߝ5 00P>9\IgP~(pSD!ψR+6 _?0θl~("ҏ ˫]y-uRmIi8y5Bp$3 dh p&oAXFOaO=Um|z/[ :$$OTD#RTqFFdZ!bc%Qż/&몣醖XeLYV [O^ŕ!&<8VF0dq5ݚ^3!`wA8_:xB]pO &Պ_z@UZ!L8/Qi&77KTnhpR0<"`{yVnG&! 1nbL}`lkk][($ c%D8Im1!/}qaXIp6+<`UP8.k7N&ͭ0+ѼkMF6ّDP" -93E{g'Pћx*7k24X!0m>Ye86BiY q!hU{=g6xa "{z98v@$ A/Sxjb/&X ?l.±I[`]pUFL-̳0`o/o.Owy*pO$ɤOI2},tuQK=ҒXNQ,!oԅH+K amqՔo/:'bEUިùT#<{lMR/4%ջxsS]⮄ =#rRK1\up ok aDn5"!FVˉbL\ 5XûW /S%Bj*Gd/$%ށ NZ2k`/*/9PikVyU} HQ11-&BiJ1>t)#0L+"8S5W*QZ2_V5@i?> Syjq?{;qaQLt+-_5d@d35^Q,zP䱫: = Tq53;Qއ4|^h¦ |1j  $l/rbi5]5^5:Z9fsH@>9bW()-fw9fBy7(Vw5bYc6Ö&bW3=0) -k6شjgrW-4bMK,^D39 ¤K,enmI{71&.I5kFbs1&NK4'3JL%|R'$D}L3iyfߠqhvk7a+UnKPz]L} "B/#5IWaP_UK Jc(5ҌW>1cƛ|J[/+ ??RLYt\V72T݁0B z݃mgQmz|SJ[$JdjnШuyo L|)NJZ6s [emL XYvoč,Κ!׌hi ?G":ǮݓeAY㑅*Ht^@B0^E{cSpo||Uf^ԉsC7FJJ`X4q CھL/1~P!@phf+Xd8%5lA KvYv 1'9EUloa>:=)v2ǕG]-xG wZ+̓1|\mE4Ɓ1#k+g|r6<dqhxˡ8h< w[LB.:Nx.kRI^-_$;?M;t]J =u qqfLoҁO(E49pp܏%&fs߇i[N`z)M#Hs!hSy85F zJyW ޕF7W zt~R[ 3-8)K^ g' X%-mӠ up^ė7dVVǙnsGse :"uaYw}'uӄ}}Gmw5Jy.3A)s8Fz_M[PjxG>'3UfIK޻:9Z$CH㍘vrhY.cA؀ĤEQd40ՊX?cIÐerkp:g,U[Dg hB1 ۨ2 gOi9%2-P^"3χ V*nwG.ES:i!v~BÁlv8o|vujoe1dڸmaC e{끘}_ 6񾸻MfHXxG=&f87,H;N6_) u˧!]F3G{)yU3dzkrs #y#=dNT"nz]M;e'5[jU˿=rVzǝ3VcK¦YDz`Wu}H|ϐ~s;1Ou{Cu?|06n T6\Iq =:-{&l)}C(z{ ϙe<5xʼnbpOQH$a< ,;7hFji<53SaV)e [?yfp=l<.{"h ΧV f؁ Ezqې0uү>۲D8;28(UOE/6?!SG"\\J;]R!h!FVuYQHp+etzushϬбt_QnѮ_hcDieP tʤLfA,c߄3똼"VA`4uO[81m}ʐ4Ƕbc.n4ܭQ3T!ʖHѠG o` mM~wµxb T (ZtP pm6+zwvy5,c+,yjCG71W1"MHvt\`M} Mx1id /X64l.8ye*u&98uAoyt܋K 4t&U\`0y8 p+QKZ򳭹&HlJIM+0QZP\YZ\YPf;>h x;i /XD` $57$?"7gOnxϛodzǒ7(urq7-2\Jy9yJS['@THnb9yCAl՛LJ.xr>0?O. R? Q/+C>@)?_User, ?@C+CdDBCUZIfVZ/V Z] @n 0y Yz[ փE|("8xqG "{D򘔔&ˋޜ&a=fЅ KxqO B&lP_| Nx,=09?5: :6false:7@6y:x jHO+.Z^_Zin+q(+9x;K .S]='w~o M='OpMxd]7:' g&Z椖'e&hirq{L,?yW^֓S;r+APjqiNoއĸ#52 t&KbҌ̘,'\YR`00YX$_XKܼ#ًmKdDɓ6G8 .I(I,JM] d)'ed)pqi JE 529`#X $X!jb'ܤԢb wj99@9" (bMILMqp9I2"@+I6 x] %999ct8'gJm]49X(>yn"[Q~B~PbyEN0HK)NjSO//.I-JlWhfټJEmigtM."{%2'yxzj v Eɩźy$72e'ªmKSR3KRRS&a]9-C†S ]lO&3‹FLI`я,/17NI E4iiwE Jgc!W#$x@c@JJ: @Egym+¼6h @_ ]xqI`,-9[p;nf=.UI⛗`I.JM$S1)1gcL&7hN0&XqQ|iqjB{Q~iG~qIdEe1^4.N(P' UWZPS`Tkũ v@] ѱ\"Oe;YQ[wryR]˙7gl>^)xj y$71Nliox[ŸԲ܉ ,;.UUU0RPLRO/H,JM//.I-K-Q02Q02005054Q002426RHIHTP5y".Ԛ'Y7k.b,>qr =<\86r3˭allǵy+HDunoO3O <_]kdSo Y+C XxDOA-vsn('$Revision: 24 $ zin_subscription/5psLs3 m  Xdict:append(User, !( 1 iC&n'({ }(A5&ѓ_&Mn'2@ x\sFY+-uNw+m)&SX9S~=3x!:qVf3ǏwߣǏxb m:7QfG, &hgt̊4cǮ&thw/^eJwԿQ6sGɝVtp&ϛ,-~fnؽ:,qιQRbn$6)\o 4/=\ݙbLfxcH,9٨m]_uC/v_<{8W'6 srA8 !2w @ q^dլ&.LL ;>%#67XnN͉MlMjYk7 i6o;2ًϟ>/ߓG|]hlb[ޣGWlj-xAn3&:秏v/4+Zye`'hӋt7 [LǼ'qyKF;`/+yA5N)nm tsmi׶@3u0泫@A^s<T-߭n0?+&q2F]M6&C ţNv2<}ݑljmt?Nm?{@]SwhCXdۼd!-v&# 8A\=נj(Y7g6m^E.L6F-O;:-yxz3%I>PG)G-Q|^U oǃhGY:8FFTzjo# ,[ Yyy]^Fv1L8p?XQ>RFqqW"_~OLWXTvp^28n o|%hi}O]1Ecv*e`^Îj_x ٍՆCW`ϑEmㆴe9܉˰M<T̝((PYޫ)L WSπf݀|<D]G 6+2_;aUƌ+H qt }"n}Z-9Gp{n>'vHb6)uc3E`KTWH$rD<',`:If%D˂6YXdtɈOhAI}(z$w<܊L㍊ו1@qm {8aʌ (d?2I+ ֠oA3.& ֒!]ϯʨyx]́ תhUfϕ'OLPWceʂDwv$ \7i>̐t4Q8aT2 ^֊yaVwC70 8! Q ~kUa|\Sl{]?u7[.v5U֡ݼ!cp DUnN6kXN \Ge/AbO9AвII~@JaP.̵BSΧ Ցf 6S erU Q\hu(MZF4 jڭ||!fA# UH\?J &[aBRt[cVE(yÇJBrki9PsA#K|68*dͬV6 Cf&T+b@\٪.X&`ݖ[_̪gj%~V/ͪ//Z32 7CFyŭ'Km$ɟ XϺ}7~@<>x B^+Q5<K?  h$(h P /KVl\!2r/dq,5\>-)Yqώ+9VtzA,i:T=拿0hn(X'k7f=˪f+%~g8 ]̊+G-QL V_;ǪerA CBv mQ]#^D 5$dCXo N0@qL(\>؜~ E9?}#o .uk9_Lta|M}EfΛMGjՐUNUY=0M7^U \;Af0ʾkk~2!G.:9ȢRK[TER}=k' OPG@"41<$P?*~,KEw,BvՐx*u$buG $ r^c\Wf\cs +i%ZW Œ9DMzMRV|ĭ+k=-?:mЅ@ZG}M2uiETr<70N*tx 8p vj/T츨&#d(4LϱX}ϙwkQ ߻/>n>drL6K2[2=}5lR6وUQ;ظN8kG+,vԴ{rJ9N%:e N P5xF7v\G C! "ld d'ţ5Řn #P.GZΟ46u2%'t`rת2+6a֒MK7U _DeGvTKxdvW3 .jkrN9:492!ek* Keڪ_=QjMUxHBu)oe8,͑ߔ804Nf-U:r(/~jk3 [#^Ův l5v)踎t;S(hkCA8fGk'M!N_ZcJ_dųC\x4Fn|yuӼuδdD]ZY^wzPwR0XLJYr\+KH/aҶ! yg-/\q*!  ۠upKCB?eswAwKKYDYq71sK*B`e.\ic0т-,>u7J!}fڼu'͹[呵ȁRp@iD 6HJ!9ۏ!jOF Up1¸~EMi,NKKLV()4e>GEEELT?dPCO8Kx @O`#o- #~{F2 -t%tlN2M?0kBAE|exc1R4e]\.:X%k@@B)"Jt u a5-`ul°KmjrK\3NLDnI*k-]Gk>ӕ ,iK6U`39wu<(&;uWk#k(1r>bB߼Rdl3BFd~%Ca?ڻjDÃK7ra F4G s4pH=b9 bֶv9`er@aV,3Ǹs<Ʊ (g r=%ޗ3Pg5@p4PYw/e7h0g,c90375YqWcZ(]4wcHF&@FA^LЬFO:l#%A-r;R8θrfVU{uve |.GXeN = @d!o d{E ]_N G")QD t=eMx%@D'o$Ueʧ.t@#ˏԐ,w5C?J!0jzrKP~ʬE.EY7勒a1l,+U%ꕧK!E|gIQ2W j} ,@o ;ZY Q!ͽP{&"KiCyTxo9^9? ƃ,y PðY؃Čo4Y_kyW|xVq/'XQ ;Tېj@ .U NA(>'f{݋JjfoZP!}l ҂Kո[0LP7nP5H!o4*+2fdk3Vb\ f{lx'0Hejn8o'L~(V'gX2gsbTT3JssĒe"yŴ>)טA Zi~I)pK~:dvےfׅs+ߞ M9oGm蘆}H#2͟7b(bg{m)=._b-(xmc/ XWV>`1 [F{X^ }Xʪ k4e͵R9WEU )'LIO:/L7M ls -i S-(0zX#k[5t)(t 3|--*"g2BIac&唞f<~]HyO?Cvbrnpxq{DU4᛿-Ȅ=nF"NU(Cx|Z ϭ*M[)n*΋]g"6)O:zox{U75DJU[gRxV&_Vu |:TGpU uk6t:KK$rTwr3qoC¬%]ODUJ䄻h%WU˧>sjcӰ/'B+ շ7gw"?WR!'%IxU}ݦ-Goɮ$ >8Pg0j|rX0vG onK<~]iJg;"JE;=VSdI.k&EU6nF9v=Hnc<'(}HKi G8%UQM77AoRR.RY֐U$ eu?} |)<*qě)~{K3yyEj6H␚t7Eny[ Zn,J=u<ujkdKlyԷ_<[kg~/9Xiq:neu<L+6UV;7Dk됂殄ztw="_hH>Эn6xi Σ'mJmr{iTatȹ~Frk&,VǿΘX61kɏ nPCF.ý;5J@N)`8zVOD Hv.`G4V^yQ$2Y'5{i4y/\~LBxq k=Ə?yGbpFvO$|5d':z^ nٹ`Q3L <~y1[ލ `hI//Xus-1Hg"0]]$$eip:Dbs{l?$.w - {HE4\/!Qp/XğQXxLЄ&q3sa1XR]QHa af> S&6@!Ng_%B=z҈]_! iä F LH`Y'\/ DIp,m69sN@oPW2Y?1+/Hp$H*D^ >+fQǚ7F}mt6>tvg|C!6RK@>7Ou"I&j$ Ior 9 v' c~T'>y>*C5Z -Q:7X៭Ri t Y9#0ʵ{l5\ϟ0 2,VZLzȜŴcnwdo<-{lLmH)}Kl1)t8PSU;DlMU2v'\`ITH_ꮨ P.tIa@ϥ$:r;KX|_8+OmieHf@L >Fo،z,+MP#9TQ;8 WOܺ Q ?żK&A6yXtc_+nf0NnNih%}K|,}fI`q׾ߖs[hm2*djddqڑX )`>;z{ L,}54~}f43zN>51DeBV#NH$!@S;)O $M( &{mӝ 5q.R?hPXX;Niy|bI/ :hzx=nl>0c/oqY3嬡 B#K&U8s6u~ NNGAcX YND1e3N7F/[VQ[`x$6DA I])>i*r*P[(WuvDDnp~G!3/W\VsWH)puop|`mr+5/F/~oW9468Qη;ڌ6\XHlIѮ# %U ?*d|]vu֯{ jSLĒ ib%.83d;:+OT}v12+ʅEAvzzKː{ЮBY#~噸єT3z!P*SV t!LD5bkIHj0U0Eh):mnӣZn= Tg=_ʪIv* YLH5M(=U8͒;&6'a͡]@S7R/gwq_ jζBX'ƹXs] 7_$K!3p72 Oamm4Rz1Zv<)A;CBA;xz~ɽU'}8>S'g%(& ?kJ4?O7-[cpe0Ke~Y/ } NF41O)yJkPiӔ-I7IfԢ[c7WZI["RZHmNuh{HEckeuVU$,9o j(0iyf]ɧ`_j~=) ىB[Ce{e+|y="pqúAGu~Yc WjN>->[0gUlOK%i57뷱5惸MELf徚(F[BVhs6peɃ2ZQb}\`q4#!CQ+1ۡ<@d8&s.hIl4U|815D! G9@#j )mIji}թjˡƑ\"2,D$ώA_JjR6u&;6qZAI~߉KiSɍƌpk{)RJ؍$4.90ߣ? ?3\KItjI'0+^KPҟ2˵o./&@ ғ;jīY`d!ϙCӾ7yQ\.M aHgH_"1vʼn| ;J> U'pj3a}vZL?4MM8RTc;E'cd[U\V˻LRy(N~cHw`8æ]pMƅ29&S?/y;5fA <|XT&slo7ZYE_HsmLH詮%pYvcixQV`Uo!UbRtIj*x$`?Y*8A=˚{WM#O5sH 27^ctH}jǽWQF.qTlxt5=s]O}Jrlϰ`wᴹ{K[!|ÉUUU[ǚEwFR襒TUaFU5_Ì 8zG?Фãg'mdʤ\6%Wh`M5 N[hrSFZ`7V>jEg%ZU$G:աx>m0 9|a Rü&I1-L Y8x׹>}h2GyTLT(Gs52FvK<zf~`23`fxjIHgi2t/koZBGo?8>u⡩jy3}ήj[v BM$fxȸvsi=t']<)ij^Ϗ%fW@ņxtLw` fw}!I7@qߢ@Q*݈pwKTm_-,{dXjv&H&|PwlF_+=pDH[^V R"[c\tr;U& %U)E,Kp0%=nd֕2Rg|z`,ʝ yb:(Ν#qNJh%;6f06RaR3>ʆ\l$)Atxb {ӧT qkqQdQu:W_vT6t,0|c썵YݵjJ]2{-3Rt~ܟUXüЖ*!VAFXQs&nJ1%{t B1&S'XM֡wpyۋo#G[w~Yz/P|Y7,s]g3=]S]#&)nrǐڂ7_5U8y7>-MIv 5}h~ܦ0+\N?=n8s9=[wN-U?yǽBx!GJw aA#qdZ;dS@p{ilt)5M JG D*{{;j]455+_$A7vۖ: &:L%wwpbN{q+*+WeFcN kmOԍayǗޕz3~ܒ?;:cW5cux=ׅ~͘#<+FbD}h)fTOx I ]o Ò10{IyPT c. "=${~mRyHx֋Zөlp43ڥzv~ɛNxB/ q6A"c,% pyo|O^+ ]=OC9@1H&*ff1mZFˡ7ª e^ wM2#[:Y<|t_קK q~];nng_N NVw+VeDŒ;p)g S?z=$U^SnQxIS-ڍmdkBJR79AĦ"ީef?E})3%%Ơӌuu( Ʊh62ޮB^<ԫEuԟfG9zMp$7bG밠^e WxDqL5/[[M4aHx#_ĚSjkG616v6 L{47Qe N\gFAGN:&yeI ka7lOA7>9Xv*<Q952E^uh o[:|Ϗ8?ff(2&>Iڏ<{)F!d{)0J{8t}B˯Zh<ś Dv #tVGzBQwQ;L~rlzdы1?҄+76lmy@ z_ 5ES񊐐0ӞPmggG MjC{fȨX,&^kFu-$w/=pti0?(Di2ԪP]xį<8Jd>'s [ 㔰a=晸1e-Ƽ ~eo_ <+CZHGb}G|G /zw(-zu*[!̅zsak :3xیr韩2O(O=A(3bl?uDa+G)c̉%Œ Ac@ǂ<3E~i^AWx.Q !BJlkOrpj<&&i #RL=}w8f >4ðj&kYrʕ,SJ8{i dq :~k5l7C ^׀C 'LH5㩺Ja]#:F~MI_ R_\ }KC.7Sha>A< B,F_PZ4q}oww_ þ2?E*S/St2Q9Uf~ViS!ʩK#aGRJ3w뛋U| +fS1|nnA}z a_84ɊM{\pGn0<7)Ɇ t~ۺw Nj;1j,r3g l]|$*X.VuE0u׳7ݺy׾:ATRW*TƿILj [vc}g>'iXJ 7vP3bs ywzLdž|y*KE5( 7 |.ȡ)VPsjZ'Quu_/\r^k5NS#?RS&q,]"/j"n$&;׭L1AwEc \'qr ..qw׮9AИ"b{f|vu)MNBgj(G-3ri`2&ƪzqIZu,,doo C+|\EPivqI?% ^rah+ns_ۤ֯m |!_+(Gf ٞ PLQRվ:qy3^p`-5g(gu9`47krw5+xS lA-voվxb2Xb_ZW/N` S:Z?+ .>2,Oų'Ș!zA!UB5 [ո&~s1E.B=K*$OqŐPrV[W>M0Wp-XIyS7qI(N0&<_Xžr8!yl•Z'da)ָ X'q`ƹ@Etb:?wZlC$r-@VxFIDmմ;'uxq_"X) Ŷe!fR2[!z`_M.6TEM,!`F*ԣQls6!ϞMQXΣn&:/0r%'#!?ToDb\:7/ҥLcKsh%1A<И0M~ڕTRsy=@7N52=/hy!Yfj{&=<0_!/}ºb $pϱB򜿄˙ }& ޯNj<w(fsfjBؼq[X`ķ T/4P-q); *ޟ xNg6wᬬ|Z~mHlVǍ /z=n /Υa*>MDu7߳qU6l^bZ,Z ʖW`}kwnH:8_aRѻV(mo(wRk&qZy$tݱQx{NIp>sq?xt|] 9LLgn.x[aj>#f&Gx[arC[Rܓ S&\Xx+'D sx[a5jB@Q~rjqn~^dG&ao%p̗9&(l6qe|K{r[Abqqyق7 _g|^}$i#x]J@Ѐ0 ڴ+ E"ЋB)16Ӱ*%@S2f lXBn0.oD P2yBi4M& 5F078u*롻Tfui2n{SqZ[%!AH+)̅֕GL#1K`8diU=k0BnDv8 sV_>d+LgWBPדnfxor>#f.Pnqxkm`hٖхwn xkm`hٖхuxnr>#B@Q~rjqfFͱ̗96ps3L'徹Q|+_n@xn5j#f%xfr>#fFa1̻$Bxk9dBTqjYr~^^jB@iQA~q=f貞) ``b_\XRZ`ln`d``k`kd``lehaehZZ5kr*TuM=.ݲ< uԲ<+9* t2(((gVg(*x(T!@J*l:kMV`d n~}rX~^M' N( b'o:Sx& zr br.Pgr48T*yt8#o xVmoF|:3Um{)Mȅ*iY xO.]PzJBb<3/vP(OP(9ZjV=Π N[mdZ@љS5ݞ( + دT?{SyoQjÉ%u_گTDD @hG*]"h94H1d 1AS8`(O 3T.0Æ3*0 A5 sQ8>g1\)ibbWuBZ{kfQtW(L0)+CWAW(7^d,xrb xlOj:ʩ J)2ΡjwI[j+ZtjNS.O8#99'FpeY5fۅVjЮuIցvnue.)eJX*qaE)ք R##|TI/gх#ǕlJ4>L1ҁɯ؇>|TmC7*>.‡˚3WR n.QPJT)Go=\)r{x#RIOF5PdV~"񮵉soLj56B.㈇wCi:8 )b?RrX=k#n\T&b˯D9QnfFCtMuƗL8nj=g1--OT[/>; Ekfq{Cy'Α}EOB#CG=RG4=I[:t=s8FAR+/Ky:OHZ_lرOMLGXt$kYܸ״|єSʆSo-1XtOOOwOwÏ=]~v=z$Ry84 ~'\Y7YNu$ݪ&ũ (4O{g<؏NM4QZ(<AE4FC\}ӧ/탺#L-%q[d<)T`>{S{F&+: <<W|8hmYklFV%ළ_71Mt0 8?I"GES39~ bS$,1Vp8C`w{ghGpNwg~gޟޟJ )\f,+8=iGja?`0SE'$i,raK H>m=͈^bVSӃq̌̉P;wP:]MȔפ#^"31Yq4GYAlv/i  N'YkGejr7#7U[ߥڮKadVp< H2K&Ú?A1 ң=(ރX#0aixe/!f-Uv.5&!Q KZ)_IOEQ"ZDZǿ7ڒ('"?[D&I9?tʑV]`3Yl>ݾ'^*Xcp W+ + [e7(f[5?ۦWeY ޶U)ɣk8ԑu x&7ƨ#YHsڲrBLo+\ߡ08 m0 amLX $fK8v_4GgBf lPM%fNQ-dއQqoQbtƙgBr|q,i? Y*o 8k5:k䒘 ¹(뙫WٸH02X%#G:/H=CH5;cYGNFS[D>CVOZ!gKPL09́aw!¹ 0+g31O8#& 8njئP5Y-6fR#t,}>GMcV,2#`uaMc6`p֢s+w5BOG8]1P࿸r7땲a5G'BX~,,nyK%2y0H0XA,`8Xu2>s=0z?v-%ǜz0a[GomAa?)Io[flkla;gܧ4(p) t(% =fNx>z?!sDi~}$r:xӇ?͜W#:MOzgG !36M3#fӭ\/Icku-㵢dKJ=hˋ=Z,$Ķs{:_Ӗk ZOkJi)jM[SkZuZXӚjMKOjZRiMMKSkZ˄ ״ZԓΚkl$1բ1{I+^<1y5ڙSjJJJ5R᦯RfRaؿCq}BsVl2q_S4f8ҵ/]޿kO_J~>Թ}|R} gAt:``τ}S.U&8j8k 7eYNo$%]&,x}W fwb/Af]9f )8~qߕ3%e RP}W YiAPV*v ©vbndOL]9d?J 5^]Y% $"[^|kS>5E!.w(lzaK"~x%h<ؚ7(kH;`D#H !@XnS"A?7N"Ip98^pByN iQ4 fߨF828 )&J YNs|9hY)m E\$HM֔8٩9 љLbva95%8S)4P2d`!')%԰՟ zn)<*Q2*Jw!1lYD_9:d67ɖMbmq+-04p bnloZ̭/x#&MWIEOJ0|om7@{#NDS{ܛ#Pfo1`K9lg,3&cMx/㭬-wqrM83@RrI4ؘc61kpBLZ;Ruvdmf}ڦ}2Ayf*LV1-TXWX gix5י54Ҥķ_Z;zvVVE⥖L&bj+q'и~e}p2c#>jx=1%AjΙ+>CpK͚/.T%N x=Aw٠.A>PgNjҁWK JJ>q ];<@yלcz *HQ98x+H;Y hQU*k-cSeIϲsE񬝶6DiYX&:";dܮK%ryk"g7ޑ-b %6d6Lm\VSSR)_ 唝-!tH\B|S\wwˏ[XȂ!;&ح-˜x;%ʊ"\W.`#%[!&SaIRܧ@Dn9Vdl'Q8I [.PAIl `06xVZg^XPtz9[>Tc<-8(EU8KߨNV8rACjnq˿!K tY_پV$z<&!![/{qNHSs;`]_^~k\!e. !'Z͇MZVLh.ɮX: r*jcL"El+%Ъ@ Oq ˂!{yf]/?;̅\X'z#LǓ}Tb5gJ|}6cf&h?\}a-J0æ='E@&S&vqqhTjma}sym\"ވ^֥NA O^k& LYE]}?}?ܘ{xj6➋i+(1BM钍q-˱iͽBL gMVOt2(w V|&ǿ!.ȸ\2 uwgO?FP u,/_\ACP6^ԉN!×+hereݣ!(y]IUR KŮpPrg]l(@<ݩP Ijp`%)?Aز>_2:vdqH/#{v6̪7\\wT0nއlhuzTt뇧 dƑoջHmtGi+Oڙ@M%yOG04 R.689?},9.S 4Zc'I Ef'e饃,kaiٔs4H,Zi}P 1.B=F-ݫA14j:DknZR6 xuyzRR3Fo$lᅙ1zaXU~2Nz,%g`=NX'Q#yG(eWMyD"d^7*T/]ܝ̌'ݹɺf`&SGg|a`O橎g!rA8 E6^͑Ҙj8Cm6:5[Jy;X*[J%_vJlܶbc댙i3̬“7~[l0\ h7 Bحu~<ڒweєPB.Jy"nOiBl}]J[n[">Y.idzm8ccXSapD E_Mѫ|eÒ'09uX Q3={ELKJ pAO'゗JpJ%&i zآѷRwL ]PP[/0%[a.SL=yM.H,XZnbm@}06pb"}(XfZ0# ~jC茞x`i١4-7x]֯

x;pE -5TCE jVm fx;p JD7SrZ`x;p L-5At^FɌa)I*(*T嗖(((n jVmZx}E F-5TAvF2@WFHɨy`qu  $%eA,H$[ЈYK2ҍrS4M];. HN,NU(((J-*GUV> < ,5\mjQQ~Hh0 oQ򢊙/sVЧAg`Ox}y =zo`bɁ-0J Ex}qy  Eɩź]9&3JL`7y毂LE4&a̡8yA;'Lmټ0bY^+-x} S4&ՔؼA=` g3x[Բ\;.UUUҢT+Ge=SJA3J!7?%,9(E/(GBLHB,J!1'"RAeK*HuM=.ݲ< uԲ<+!* b/.Q/()QP**MSRV /^î  J%%VYII@@Ҕ|t9²/ )A(((9Teg(h$kn r#ĵyJse6 gM8+[ZbnfN%&09N]urjeV*sBhqjBpjbQrUOXtӕ&1)2[q8{e&v7OWZpv䗘 ]ה4N)>dTSL$hRL΃ʃs,*HIKX8Ok) wYKGlWuE~40¢idG h$AM3;LGY.PE]Mftkbx[qy Όy$7'0eg:x=yq'dƙ@{3n.<&ĘBtrh&Ҝb4Ģ ̼wM7[17b( \ x\sF,SLR~ndJf%Q!). # 10h[~ dA$ӯiɓ''Oa< {6GQ6'hTgК7iFZYߩFOD}qÏ,e1DHr6wtt' zS[</^x?ـOۻDUt{7be|\3|!ۻ\!N\g][ml UL.l֮LZ%8xJU@4䅌c'8su8kkʋ(3k82 ׺ lwQ$*a c[16e6CLe8'_-*q2:hX&4ye)gUBN8iwp:4.l.AP^@m7:u{ga<\GF&o6寴TLP7kFy +Y<bn)5aT/']!x,k Ќ4=CdUM( 6*`sݳ V=hqh'݃Mx2{yrjk@N'Itn@{'ێ?+>G,A(&0!wvz3y0h\QEZܛ6qa!´j]~nϧ)/NzmE49QvӇa".&eYG*=e c20 @:q:ǭ?u[>s.㬸iGw߫@ zx7-I97y>ק7iAgAv;G O5`Yt H܀RLqYTNN?{G+~&Ӧz"w(XP??GpB2fkNwM<fιE7ǽ.}0z1"@;cϟ݃E h&)8O=="$gя"F&-]=rN 7<̜k;8g Zb(q`Ih|b~G{߀=~;3p"## WVddޜ BoWp{v=a@M䲭DG1*l I0|߃!$ 7:tmKŐˎim1$C6Wx XqrﷶMn/[1 >ɜaUaPNkEh[% ZWkVИ0!45\c_/3i&noI_٬:]u`19ɽ(~!}Cn "B(3 R.2ks%ȉl$STXK4Ɂ|_C# cvbfۮ+uĂMC#'~]Õ8. !KQRI/UU ,B;!|lR?Y3]sì RZLͫ UJ-7]8'kڷ!;$JrPUrbX1y#~ݐ-%Eғ8d:y1'yH''n-TG1MOs*O ,L$ؙ*٥bHQ'!u 'JAPZs=ӹ^5ȾG))8GzG"\'h̨Cj.'2_8N"0c@[&{S VA7oLs*R0ZBF|Rɬ[zn=1JuHKp9 ;|ܰl_Dt=r1Kt |j=/"XrvwաxرNqk$"{ c{qdXut7.֟{{mKRpZO'|5G0vbof2t_}n@DTy:|aS^elƗs=oٵE_'ƶm]i&V‘/ ü;rMn)wTZe+_AH*#e5_] <[fLomSU}w^?tpl+YIQ[F>T*F( TT;[|g3.%vj>FT@eӥj. %/6Bo4 x'وtjw5V *^M4&F(6)T)`]gpk-95P={|iʪa7laù #)*c &7Vҭ IFT-*>HLdjٓH8%\Tn(%/Ve\{v+B.vsa_]Sߡ&)!/LqL>>%6|l7bf5/p'MHMTHQoڔ)mހ3( $l խ[qpgHWó[ߵ:t3eQA|/o ҨEtˢ"K=% Br5r+7K K UnD*ߵq;t;9tq[&+-՞ ZTng[3ba2p3#jz.E݆[$0gk+N>8wlb|6 eB* "!@!ʰ<ПA@IPI]T8itm5TlkU*7XU94nH&fb5zFBc5Qq%doC,3_hV80#t n: ҥy+Vtc;̵UYwGWe7EԔO{7t07}-.!<1%6t㙉Jfz[A5"*X.zu$" ]V`k* Tu)%UrKf!\K!NR0=~ 8cE'RxղRbNTM Yc9 ĥN{ ZKjȉrC_MΗlnWz)_}K h pEaIb4_8:/8̚R Q.߸ƅ-g#&TNS"*usfc6+-Th!IE9_ܲ6QX&E1Qނu&3)SUzA x%1$IiHW%Lz3T2Ъ)+,Vo-Un-BXMi {c+6Sr[EKʵ^ɣr-ϲy`O-NIHR.o\<>HYG7nɫ{X_.86CCOO#:vg&AUxXl)c35ʪD7A5Rc̘јXf9H^8!eZse(Qe9|t,?2ɞ졔7ųn]զlԈpN)NNI*"I`rê\~ֶarC8Rb RIM:E!ܒ a{gk\j#́ޥAgv:GΣ1xmyUf۳b3JVRG-6oLϨHSf4ů0) n5 MGA^''pS>yN ";ͅLKAM&zEkE$jN똒"P+,sJvlr/֕]Y \$Dzɒ /ȓ]`[TwG\‡leձvj@րw)YqTj_nT&qG, dnlt0݋k%_( WR0 zyIڛ=Պ p/oe J '%ɜ5~lЇ-; 4N\Lͽ{*2섹53yv fL'hR6)i4\~y.>7X3T*OqBqFeA#'ƴ +<^DF!/a Bj<*8o4 Rs,5(޹p}la*$ à3zHiWኽw#H{ycZ|Ip=I,{:C502B蚯p$Ma ٷx ~k+2eUC^TK(;2`*=z/&'ѭuUk2€ʪhuMb[dAl \T,K&(E*:Kf;+ѵL:3W}rL/šO70A @| /)3X^)<%sc6VI/8}Qt\Yj;|>*[ J"׽ KoapNtRy! ~lt5CԵxpQ Y5HƟ`^N;ucq@p(|([Ԁ~'ewSVss4 qqS3"rvp'!. -GKD]|>14 WkYˁ5 M~_)l־TU~>hqW`y? y|3&-miq%c(n<Ab ~ep9=zZP1ֻ-R--N?Ս%-$+VKpr!#Kfs0EMp8Z*[`_+R&j9ppݯeRr$I$ ɰ@4My%ODig]" J8f\euFByn3iZOH 3= C|Z%d_aT*>0{aՐOMi/Ro&cAT@33vɢ[x,y$zIoQYJH0_w̯ :B*pzyU\]W*pԪK(|MƔ`}l˜#v!{$iN4 ¢!~>%bDCڈY HXnYg{_z`WMVM˵i3FP]Z=v}elT+Ȼ$.iՈg7ă'XӆdVDZ0,:ĺb1`Z8qEG+pRoEM#/MCF2ܔ^t㔄Z\i %[chHZV;;͈$# 7JL>\x(2'Ϫz&Vۓ(OZD;Fs<[VN{A/3#v~W"梷zGϽpop-+}ReݸTOd|(Vͅ*|?\}S ^7&&-Zo?"wQ< @OLĪΊpw2uF@-S<|s[FOE 3J4YY\=CѬOX' E?,r!UΫrllJĄG}Fcʑ/-tW\Ębȶsq;9wߟ"bŊJ$XFjr,{2 H~d$|_ћ8zv#R^:{q4 X65ВTFټ,#:g4DX[ҒH5v3e .݆pɮP zW[Je''C̎$ID.i d$K|v=HIpliYuq_h!VIjUw 5>m؆'s{*%l9j&OI`7[.s\Ì=#T[n [ŭ-dȊ[X4[; Svd[kd<3^"~A ]&DH#yS'sTFYzm5gᆜ//_1Oh:|C="-ӃXQ,%C^m3,uV6sN?OR;as+Yg XGz'e mPE2 ܞWW ֟D  2LJ<;}m=q;6,H!˄V{gFU2Uv9fKhNFK%PM! P99j–ӷO5˟HUhΔ%,h&jPAu!g35OkW3)۝;ž#Lަv݅QRYO .:ekx[wF>KbL 2n.ce|A"RHiحA+xъ@i@JaVoEE+.!Ԇ03vC^A!v/}$;'3Iv7*9ws7>q * Kh~_GAi,v`0@*!B^%~<%|r9$$FDۂFg!!=#(\hG5 Yq֧B#:AFREṲԯVL8|U7ᾞOЛ AkV+Y[>jf{&$A;gu 6-y`[WihzTIbH< 0[÷wlmY^~ 5bB{-k&Q7*,% my\q)-w`|GS `E_LUEp 329(=D Ha*;g,V]lN RrOw#|>I'&&%KhVO+\Z8 1өi'/n}m"VjC Nx[q& y$70nb%Fx)p_`#B@Q~rjqfgF)̢ px)pkԲ܉!,;.UUU0RPLRH,*N,Ή/IK-Q052W02005050W00222RHIHTP5ESanYqJPjYfqf~Yn2N^f2]3)1E7$Ci>#46-x)pZ`,6kL6W2YUnu7{0K 96uh4 _?Z=5=g%6Pn\ X0UYKj־vBߔUb.ǬX2MzSLY'nHhSiCRds/'mPL1O4J*ϡ){з{8p " Q p() VTŠՄ{7` Yk:ܔw&=QEhmw T$Ԙe-0e]V:L0)IëTMH pݹ?xU6ꊴbFqD9h&~=4hԔMw!T jC{FF*.MYS$h2T,7Fm6I6 #IoM^m> 1CprR6c_C)H>qvc!M ?KPQͩsaB ?'u#UfC`U"ȥ9\iV]rBǰCZCe?0>*qyWCXdn3 B1ǿ;eWV3e9iTIR(Ot4iLGޱRАJUD5jRMVџ:,/W6(^!_e4g}&I,9 <&<>d`ru2ʆH\Dz@Rvom9paw.pQϥ#c - vӶ.[n] Uڙ\n ?CpT;l#MA\w`:i;rt\x[c/vsx;Qwndmy@gM7 2nn62+)&%g(dMtQQPLh(>#P>|" xJ)Oӧq#Bh*N99W8M1' ޏ؋_53ſɬ͎m,3苧?` 7Rd8O8gi<Ͼ n5B> , gAh,Np-b:eלec#J @m3g<0ѳU~٧pƮ:0 tgSб%*~G b@>bEqfߓt*˂橅fhf?'s!gB ˗(N3<O^>wv1(?{ Ϯ> I>W y@JeIE0Ȟl3A{<ҥ7Nxg,MxaWJg׸#m1(8n+uhTS?Ab Eq{͆OH#oz;u 3$70*6=ֲqm`d5'|Ŗ/ V4!6*=Tcw*X`8#?f:sPXhj "Xe 58wnpS斨d m)jr=-AaErTX%;ȕUHp2V8++J)(2ʙAɕQ׶ 㧲F]#ITV1`0reey~V#k(J R<.CӞgO$}<8]Wlx+S~<띃08v-sB$+7Ş?5*Cދ]5gIž:8jk8'\oDoD!rp_A$2 hGtaG`} {3T1əҹzf =%SW$77i%Y)2O^{r&aC2Fе%最J6ۙ_PUDe6$½?1ƖcFF)68d CC#!F[5hVh*$1QmVВrV ɮa"g"J|9s; klI9Nuް71Ln-Gk,Hx 2Wj K Dq3Ewǁ#JjƸ %55%[TKgs/]m;]TŅ| R@@ɷZ9"lCBmhul{V;FBwﭖhgITIAݦ(J"p찯j5sbF폎ϽyΉ촶cX.Jaԍ2-ʳ K%K~()X _rfBl%ފ Gz!`whbQ/,uBB's4D>_qtKٿJ5OZ mq-jes1?W}{ja, }+GJsxS<@Kfo wֿ[(!CEBxT\"|!ĕ:~\%,)_# `]!,S9` M2MU ˪{a>ug^'˒T^K5sb$ˉAU«@UhM_EBuP/umJsv}BGq|JʣbzG%"kvS&ܐZN)-N ;/';QA!]|VT {^6v6}m8U[[p*vTlpm)qmض N :&+w!& )yen D2^yW2Jۇ^y JK:X6mʴ\;s؆'hDLsɣ+rMLJ?#%}$D0Hs3>\jAJ1c=}D%fM3N.}̂F dhp60Θ=ezFe .mk}eeNm}f-GV"9QIx1ZqLiN7R(( ;arXFXVH2{@>iixL|:%vh( mIqx,F8exI_oD`u3>IykG\gC ( ODe]:l?폙.]!N4Yc'Ð/V>#ڗUR[.)zqvdǎ*ρYnyi| u5pB%QA;[<^N!6Jj$k4Te4iDl'頔܍W!U: a-4d6L[ֲ;EM 0ѫIroS1!~4ϦnW(!VC6Q(r${NͲX'r$*5w7b˨nj:Oo;aQ^$ſQH']G7#Gr0vWv -Ö[*BJ"4(uHDDl&"ͨ1l BACp,@lsl B_OĊK6IGyj"vRODڞX"7ŸDȫQ$B3A`BTh,&Pt0NX,L84kXz>~_ L&CQWS5h] _ 7Uu+|W-Z4i=y;Ofzt6Z{ -zwJ?9;m6'.A 3 ~b1~ܵN۲9^C,P B}4AA1& G$*H5W(>j Q|lAheF>}I;Y枕\MxT< [.-O'wN; Нy|<kN))OjB0k5k󚵙yԼfmn^69Y׬Mk5kz8g*5.XF< C>W1L[ʛH; .r6 9VASE4VF[(iCvb+ B-*@xb+B ֟SW͔k4\l.rkUoR"Bx`5ZP}9IMFu$kr#Bx`5\PɅb+GF]#&!BhFo A1h5! /]Gѐ0Yg%̊6GqDh4DF d'BubFMY#++8D s]3g+ބ}Ck[)L dM*tx{o%cF^Cb͎LqlQcf24Ϥ_XZZlZ_XZTZZZIȟ1~u<(15t(;$V)琠H ꛘ @s3s@j3RTX\DBpX\D'BO~rbNf X73%%l 1C2K@Ln:`# :`z&9; PS B!5+1))(%>#??ت4Ot@,}& l~S`Eg|Z~NrLryMA(Fw qQPRXMBb@[ wFmmC6_5e,f1df]>&PbkAz`/M&+O1b6h?@lj69+xP7BM6a4'Hx{ &< Eɩ96'1ˣhߟI#?%)94(3*=$,9(E'8,HG!8(/17u?#cdAAxQ4cjQvrIR!A@713G v%fԸgi&bfz>FNJĜofJJ%>~`W!A be0pup3F@tU!Lsv rA w*?C ,syԾXU"9WHV jj~]]o$I{(0qO&6E@mTcfr"8r~e"`ӅM} TouS 4}c5*yMJ4Kxd_hJ1-=E~tpk!L>ll2bsN"LLd c C?MSlkM-TY;jrn+r(f%#STL}p2Ys%.!Z8rrSQ`]h6g_Ev K芯0Pt=UePTXJ)kM[#b{![Mg_DAiLnΝzqΝ.?ť>raxK8Q ?-/tR12Qw ~YP 0 ~_L(7NC3" @;;ۘ l':*Tk.W*}@B;k'X9"k`i:l~C^nN?/,qQUڲcQjx[9V9y%%IyEaΎA.Jo}EAn!x[x| }2k Px &MMTRb*%aLP0K(CP$TPk&)U5&|KNk,4x &MMT*1aV xJ &FMMTRF@BBH&JN0{:+ $Y$A$H$LNR h Rv⒢̼t"`0GSA׎KS'+Ӹ8}@*3R2s2K4B ] `5gjQQ~HbUI~< =.6eZA|Dqxz &M6'2+-@j Qvx * FfF VfVf16ah6yeF/L穰s+MgKLJJ-Ro!;fv#l=s2S5s 5T6gzZ!dP>X8&wpZ+jqqqB{txWmo8 Hvum]/hJYNbwCmy3vlG 裹§2 OiPͺLFfPHce? L-_=+wT&B1 D!U!1J$S,1XH)SGᇳaoG I2$@+;<yoMdO@5;N1# 31| 4<S{Jx}sJ$w 46#rGnDG֭c?J[+<&n(,WF+f|!\ETY,=p)vӢ/."7V꼷c8FDSX-w݁/|⋄3d Йv{%Zr/!x*(*wV' Vضi`H.6|W7wg.zapw7nCo]H,%ĵ1^ϿS瑷xSc=bo |GPEb HD"B'hgȔy̰({S_ӟ1M )-Qܒ$(v#\Q񖝎KoRlZ:`Fpy*/3 nP,6P(Ha yix77^>6XI6 VbSpi|=J{8r;]BڇldWEqv&Լ?:Un_پj'Iglo |Ci:6QrKE^ƌrbX9e<4V\j8S\g뵖Q(jLvR̾r8`S`T:y\ߩG ߃;Ag&)[/Q>_{n|p? CY ْLog(BmMaTns7d[uw&1و[qU_2bx\Vu2BSnCOS8)Tt! !_ĚXѳ]{}ߙ` >~{l吕yA,w5㝩`65ЪD)^d*)a/dR6S+e~ޠǐň+bڍKo05\K_R ֌Xl |#`$pѵxWo8 +Z#һ=\w+$d7YayJGbόg<34^z@A<]4Tx9=㶙`?Q>Z>ⅺ>?xs~2D\2{s@>> " &Y2#0' ).ã_Й`~G7`sxr^ȞЪ$df$t$'OYD@PBri:&-sH*cQHャqs*wplk(F2uplZA䆉ǰžRak"`k5 |9Sl PKe#r+DO [OtIt]\A]":c"tݭL4Δ[>ԚUj*w 2$MR:{Dd7V-1j%"#+܇{gQi B*k,bPC$uU#\}٢/HߓsרAYx1$?WDZY%$`5^+u1Gf bA_|; ]ylD˯( :̝l#+me8\ͻ&[339Z?JD}=򿺶nڥis/BH%ã"Fa r~Q`R&3&НQryhI=!K$u+\7ڂHϷCb>y/YxY.7Tz`MHU5QrY+\-[t2)FM_,QY T9w/STL:3#SizAbP6IJبv" ]A,/8jnj%@.m`@5x,5Z%U P 3L< oқ'\xL.ɛ戬x9O4զXjVT8뎏N)M.l'ɠp2CFwtat> n @,Uv(?PzNh$1c4 ]xAD]İ`H3!% "ס0!+'y?||4>)N3e䷍7>Ҩo`!Hd<^c'6h3QoVoۗRm̐$4!U_JeKm2~Trw>8!= F"ѫG@sDXt9xa4wUާc#x 6ohOD7mÛ 3.zpA@fqꕴr>ysw*.g~R f[= g&SyR/VPl|qFEa@(fݠ#.vo^}pD{ai3s.aߩN΄]c$$ L0%53=|PsBמtp=xr+ѱȣzrz SEzaxL+|&{'EЕʕc1 &4?RR^)PYŊ6u]D$42JǺ^ۭ1xd1ieO6l.]I>㩽IXr.Wl ݞ`Zqy֦VŒW~QT. 8,h%O-lUA bPVNOB|L07&]x[.'PAA!(?9?/u/$Ʒ333l6g/`4 x[.+RAA!(?9?/u/$Ʒ3\ UFx[.:oBTqjYr~^^jB@iQA~qf貞) ``b_ZTZ`ln`d``k`kd``lehaehZZ5kr/*\uM=.ݲ< uԲLQV`sT6fY(VYX`0MyR8d'ᐚ,ʩ5َSS8-173RA׎sr*<'y):@>N[89s2KrKJR428U&srA\R6 PA"P3CT'a;9C)xr#pml-H X=...Jgmx[.Lt+#^d_&IE4nFx`hٚ1l_x ˾Y>evx`hٚf9f: x͜Mo$Ǒ+ k?V")yIe,E4URu߿'lcYUaAîʌx#2|?U}_E}u6>ȿg|TϺkӺ_@U,邖e1ں=͂ݪ~2\Uo^5u5/o^׳XzvMuYUif]4ud͢ '%gyfʙ֡ <9#Z){~Svi(kj^j:Ǻ@}h'_h^\ݘSe;/-p`_)\# o:+籼lUW D)Qg}|ZY^ln7{<ۦ1}Z=[MsZ˷m˸|{*i)"NfyS|Д5Y{׷wg< h&ȃ+ xh~jVj&;[V|mo]5:KYU{`]CjJB>^ae94faK=]7Wy8*W}- 'x$״qrf@ 6RRԛl咅_hX;pՙY6]Ȭi׬]vZX[3Tu/]zGIYMxRl ]7C;f.\x5kC,X6u`en_gҀgrex=K3>ќl̴(,iKYs5XD7[l$ȁ5hh1MCۛɑrSgȘc֮+ -Z >RE*>v3VEh粳.rU LpWmG :(PD) tnѼ^]oYfDg0T,CɁ|:CK<{j~9'zt<3W 3`m;}qӟѵrݶ[^37煽j?mkmOB{Ȓ꼰okm=Zd(4U;Z_ n.yM@S @2|Ng񨙁K_C ጐ[졧Jj^Ǩ~(N[cL2~YT$lL|a_K .Xӗ4mȄ4 &RWܴ &~ ̦4In؞XH0zLtU ϵx2E&l7"#:vzw]cۿ% 7FYDweX:^v&vڼ6>P1%9dcFd-ҖLf3@9Suim$)1Oe\P ҽ猲"5D; ւP~h \[D} NLbU~1XL $Af!fS)1}eDhg u4Ӓ\$$k"&Vn%/tѴo|G꺓~HüÝ)J롹 ^3Qj?{-7nv ro)w4ah>]us]JC>,gnxyTCU[  =+BcaA!ں||Q] /M~ lf}PTNclogYi+?9ONd8:~? {STX"2w5l":&Si>xo8wqA=Ey^bO\>;$12V#We72CH 4)^"IOA`s1M'1{iFNjjՒhc}(USd Xw0,Ȋ^,vO bn4*(#j G- qgYX0X_abў[2M .FAYMs/Lw˪k3I-W%GoE{RP,[?R*k hM%4vɃXwt~ 5I/XP;< ^qOQ}O.&0_U}aY?Nz\/BόjN CĒ˅4Rvs{ͻT?{h]kD4$>y@\EF0"_`Di_`dOkS*+㑷LD'́g *fDZP c! K |~;!} . 6#٦1H8 ,Ø?Y8XITB{)ԂE+OLJj 8;R~4[@h@JDzn2gGEB5H>lɋ]g~ˌ|z 6,1~/xgm!%½eP8"sJZ/ k>րh\^c96c>~br-Uf:q2n93Y 1[[cQU])e) %fwӖtS`Ri)"V#"|' ˻ ~M12,02Ai{[O7N$nn|cuYaVa5#a] {i#%jxM q-*vAIOTp8T %'FǟŴƔX` [zN1TBz.['^ ~ES;R1V$U "jk(fHhpp IwjF+FYv-f" c$:`: )1LdA#.NHPHxϫT2tIm vCb-j-Guxd\f[!3k^nlI)fH+ŏq\ f5w8 1vu<+~Qz[Ya(Yo?+˘kUzw((e_C-,8P+-?+$?;03Tq`H?4 @8M)*Hbɭ<*7._SaeI|^d%R:X9ȰL5ȹPG\+ E? ]pMi*]GT#e.4Ӽ[~< v!ometsag,˃L"3puj!r4 w9Ҷ9.3T23^bcX2TA7z1 KTCy-ɧI㱇QؐnZQѠx%'?J7&bVT1 / %.˦mx;˼٘?{l֗DE|B mlڶ'VC힎~w*t6"4{CRo|ύ,Bcyo I|LGJG9@NMZ@v0Փ*̮35Lݼ8/O+ZGrV\1g,RUᝳ 3ΦW:"!z#aHgA&Jpp |$2@. JEv%"XS6&8q4饷jTNp-<mguofb@7AF':'j`k^ 5vmYUQh*CK=9I&cfp BM?ҼD]JnЪs( Le^osNm*Cov3GSY >6DT(C_Ҳ/u"'%R8Y_&0<!K~A$81عY4ȦH%9GC&,& $ntpcS<fpώ!ejq{R/Py qcHV>}R\ͯ5&e<'鲐 %vCΞOt9ʲ Ԉ* ۇFsX_\ |d_V^X.K ]0A\*P%lPuV 0׺z]YuM hy8%&Ct`V\ƔzhrR|cC+ɰڟE=`ZQ(28ҘX$] =H9 Eɿ%02ÿYn@c8)]U>2'({NĝE\큷CYڿHq S )R@6 "m[! O;* q8sn;haYGpBQي/[}1ϴ|dJNxTg)!/IO4;>(ݽ3fA8O6M#9IW΅I}9EΘ] c,E|#VbnJ+ZҹU5{eDâ;qFf6ԎY sE[ztB},")UAR$0R^n+ A*Li#= X(Qd&"|J2atCaw"2E}]lr%8ay HRR0R+J4 сbkDVH]$#Ꮴv# ܙ &Jz8d 7=F\i]*>H /eGcw}?/%5:/:Bj=u:q;8T̀Msm,}XˡDQ@bV{֛*QF+ٺD0YW*:UV2=< S몑B 1G_q.!z;;P W=6-6vd=0l op'oLoMA`Ǎta8M꾷}OLApSSS]LĹՆ}Z&~{&|A6 oc_R apPډ  7~&m0.˖"=RKAh3Sr03ҵahdyjQd[.q9J]e'R]4:pꊀbv".}*XzP3{gPZ- HJ.ʉ4bt-E9**m)c̟Eq9#oć@J\ RƑ₃&>=ǷCxKĚwrnC *! [2IAg9ނƏ[׬vY1NG ee}X":F; l=KI5K =#R(܈yȾ55%}w+ ?}5Y|ik`Ymn-wR^6hQq\/k&zx|Fn%yt>:kZ8N[gV(eRzF6;sQkyVҾ%IU s\6< k[/yW/u(9#7.w>qH$'T~lմ*Kuv =8*,MVuDĖ"࿈zda^zѤ(WIW#DMh &dCA5gɥn]#:.nN*6jKA_v|l).ɛRN "' )3=[pV`%b A?=Fq압,#$6JShE)" L%5L.]H_S݌^Dc5_%lYϼT.QB&UҀ9K[`ߥo#Pe-v.L3$8|6q*C =Yy 4L%Nb c^oaF!mG{QeŻÇui՜clt3?*=Cօ˦O$w@U}. b/ݝlRTqtb;^  pU2שT"介~W?e\GT u?2!d' ]etΦeɭri(AnqVj; |Nf[LT'SR}ӢOq9Nd6W>'_n1!TOc޹>c醪p ^\! BG/F8Cҫ|Xgj)tO}qn9/ 1yQZ9Cpx2vX>tPh2&YWc6?ҧGݣE}d71dH"bx;q6 W 6&(x+(iLhf̛CJ@nx;6 g#7D077x;q }997߱ϳA1 \xYklu߯ˇ.C(%J[|eՒ2;3\;%Ech#1jVˆnpK$ 6"F㴵M'h#9.esϽsy~(l-T?б#lxpDhI64̒)f*)VL֩`nFseG؊ˢn[iyM-DGFNvx 0[w,k[놦k^_2vMU#~YW]u|q MW]ehe3=ͧu#X?.Ӻn#{x"md SSl3aj:a8\i}TTV‹IW7 -)a:r|  1W)欔a5鍆x>ħ_3|T?/'WLMHmM:^Bd|D]>ш{ =0pK??PD(%l9.1m,1EPCТ(W̒\"u'u5g;ͅmѺajrG$:69YJUC~ne-}mj hwq^ι S]u-۸3؅ߗ;w9Lml&m| {~ ǵ~LW'ro>U9ZFs`:f(Xd U\dzČ8Z2E˂ŭy&lzx;3)9bŁI~-b2n)&>n&Nh SKh: 18-WNVFu3MLKώ%|G3ie0f@@-l Aۯ؁/PR(~i>G\"Bk TX&q_ }yζUý6<|yXilVIzʠH OCU"a8 , 0/SL֥9QbTOO˷x3uz7]j;g`br MFUŷ@|'/"|_8?MЊv: ByiC0my9S蟦4d λybVgX0}oHBiwa_b#,\S1kkh0p|o{- Dٍ+{F)A'J;ahV`;6K{( }:O;i 6N;'[֙n,YE3$tnostG9z6>t_={*\CA?~tW st㗠dQϝ_S'bm>mFJ_h>1(m: 4HpP3!+ s7;('lkDJ &i*5s~3p7 bbܔh ;``~m[@Xl9S :ѧgP3:B>o#VO]M_WܖaH~b9UQqJgOL!vRO}^bIl?/-=(ͫ$ $`3R=9aQ7a^TN`hr:_]n!ޖ8@XyK[2c<.-. [$P/5x١*(r G,O@2 $^ٶz& G׏ 'O0‹lkԣq0 ׂ7(=]$& [1^( =aQ:Y) =95l.*(^yկ(E pwIUn*@mgiqu8{|+ bYr*bzy0@ nIld;(Lx/E[^'w)a1%sKC(ICT;9 U+"Rٔ2}|SB %xރWT4~6dYbWU7ߩY*kY xM|mEk1-۝-0Euuïuc NBXrLH`u]ܘ7CI9X%{V^y_})+Շ~Y˜,RR ӧl+Bia$EZxvDZXI)?5mV&:'BMR9bl\D\ӕon"0f P˪H.Yɻ-n<؆pLeNDFr2]ޭIgCN͞X0xdo0@BmcKR~Cp $ ~&5W M-zIs_\kXnJν4\V6τEo]mase=HaZd)Y,m23ྼٵtRtye5VW[3Gk/ɋ;g}]ݾgJh5S?Fhs}G  gKfZD?)b]#pf5Eg?/Ң骅5(q(fkȐyL c@]wO>g Z9Y%B'COF^RYb&BKڗ_G)"/FÐߞ)%z>>O3ߍv٪TKǼ?Gl}]l"fUA*r8fet`r_Q4?6A CQōl 9rUdHHss˦ -Qxݕx[v>tQ78ÊFWH:jD1Ghn]qlQ7|t;;N2'ˉ\s#g|# >CP3dE{.BezyKK :+:2@|C^k-^㵹X>qd+o(௢Y!CX uֽ9^_A$oKQ'ׂ4l.o3J:/^l צNL_>)po!xqSau20> RI|kcOen889j{NP&0RnJ>\`3{eLk5N{|J+^4Pq^ɆOJjOx <>[m񑁼5G|#(X"ӗesyv>[*T;s3r*f 'LF&wA1UH>ZgxXm\Wf&Y6MaCٌm&66[C8sc=wzνH?~{Ԉ$\VA %_=ޙsg;L(?;11P0edžtuՔO։'/%Ħ2d $pHŚ6xO->||:k^>ݻڔ%_lIߟd-'}u3LµR7[\s/0ŌA.E_wamCa"^doD7R31E(ѰјH j V`R*]}B3#tG8@2?Qphp6qjnAd1WDEO#֙cJ4:a^ K%:YSJ49eXON\׳?N²_M?TV .ҕb=a1(S3ӂ/Q3eҍ"N 4Wo?j)<8W pCH'|>4Gv}KF8PpiπX`idlwz IJTHuYz~9(+ōe~J=ґʋ^̳_or-](gE3䟂E([&r}j~;Q?ȗE(o׵@DA*B8V oPc++~2` OauAp7ԅEKFmma.qe 0i dfkK%Y9i<Ns'L 뱜`$-G@-@5a"43x]2'Y 7sq8C!8WˆN,Ɖm}b\ͧʤϕsYc Z G?r@6Ў#:^_ H\ Y| |ĕ)`Q # p#Y@Rd :Ց+o'"k1nwMy2J 6Ie Xª*DzigW>njsMpyΉ8:泷+(7Sh oHwt 5<`X'h&K7cDn_knD<,M `WM2fKﺉ 1*zۆ{Pb%olao3uzWFJm:> p&2k/,뉍nPv& 1]4\a!N@5XC$x0f-~Rv I2YC>RzUAEI-xAqK-NI?orpaS )[h}L~x|[SGD6 Hb0C_jY̡ Op˴O-6ywzmB^on/  a.>q P |..#"^ygk60Wg[$ +[5bu g?Z8m }*2. ~`$/] 5H^olqӎ~]5Nqc;*b[Bf+9|< "Zo9KϱOx"X\yXg^NE^^NSW\  m3ͮ3QڶB #@rhk' 6,Z54{Z+3ln?Og]by/k_)]P{2M!i;y+`ҷڑLu" /ߵo.ھXZ9) nCE>f#uTQe ji nvi@#9!كtDorJm;DI,U'MI ,-Eݎ4qi nq`oK90]s;9y+yaDX*R`)GIE}pD6b3kgoXMv ? 1@(6"K4z\]y߶A }'99x6-ԫ?3U1rl>E^98 ԝsBjIam|<[ nwDUC"N.f$M5(BS1˨hlԍBHNԁ;vIfWTUQe"҆ۚ+|Y$Zʠc8G#>ƛNA?#ajjcr/XcCGhNc g{HxgBU&BM"{HPZW+|p*+Rr,-jfr#L .|~ 0:6MMj:yQMdEu^ѱWd%\//H".u欐m涷B5$PVY)#`Y8ڗĈȃP74s#qދ5_t6pg^ obgy4tA坎#:E$5uC=%7djޠ%9yDz7,ot% 7[vK?f M-[a\PebIh?78]se iCiEPEDw pϻٟ(!1f~w"#FM MDmm)f T>]7XQ,x&@"MȦЛb96{z&{s)/ӔYh 'mUB Y޽I|oЅ ;ʴ.Z=Q@rh~]pd$KX&̂w\"gw%R` <MhܥvD)aCQ ŋ6b6F6)E}=U axp!nCP3~x?lSҦqtpH0 u:gREx#@Y$+˻+ `ݛp?j9%Ni\6E2mK#5-( -IXZ'EvI2ݐM[ (K>@fISՂ%+1q7h2⦿o${jq\2 %Q`Ƨ} '>: i.W(.28x- |:ߌ0 L&:l0J:-7YmN^WXrn`HyxmO4Y=–7c~XؽEW:Zod8fNPT sL窆pkAZcp-kmf[//BCϽsgģF?ҼRdYdߎ`>rTϤE6T:?;gӫX[fX`yWGqIX{8p@^%_z,5*+&/炝C Y%ZgJxOr̺֯~z! B\?s~1·0ѱ[S, pi*+%`ݛÍ~[7rH)=™6Xo;y\Zͧ||'5y6/vbd2-e/k?&2CPʜL: +i-rh!^ \y>+ .db{˽nuq?\&ۅ^Hֳ pkw|wt⹍,W7q#Er8]MB'/ꑦ鹹ܰnZ2P7AGrl?hv>鴳<9DI#@ߟSyx :3Mgz> k7Dhq;b]n#t4?E4ekLFO,@p&*Qrota0mbECy8<Ȃɘ' 6xR]͎bu0{]5Cago/&0Z,%u*=!Wf`RIyHj<yY<ӘNS)Cܱ&2$jW`HCSچf ^c8~dۂU􂾹a>WHIU",bvF55%"Y DbW)*ruϫǓQOw]A;jj'?sg"e:^R>%5s'-Űwɀ%&kl9VT^ g,Tc瘾>*kְx(=Hgu5#ո#z^o :>'{|gxCq4[h3SAߨ^oI^|V?Ǡu]W{j]NiXoSUxLŲgs}`I6%Ddn欫T`ׯq. hkYTGšu;/5kRf)z_!Ul61gz^nm ?Kyjuv3 %xPN ت9^ T*5#|8\F̵ggEnn )0K*vb8 gtس;ptx6IGk) x%O$XW`Ǭ_ +wqvZ>Y@&0(O bpʇ}QeZIBviA5TI6+2߻6MԟF2 s oV raUIn'ݖ7= 8(RbiJ. ч5r A╉µ[l`XV~JI[,Wh Il+{e!b0y fwG Z}:)!k!38 ZJύDKqYOY3;x CbP#iXNCl &ѧf^8%%9Xi\[/BK6iHeeި夻I:?%/r]m 'ǚ-D&n~y0JX ۹0)Uf߳`uyflZ mrxv|3Eklrk*' ьf\X8}[X-9]~n۬m>z}97}FG32h5ѧ;= dtl_c?F)Խ$ɝ[5 m5V//ujdh;__-G ;[V̧mEy@^ CanpBPgw fv?Q&Ƣ4:4`r.眸w-I^Mooڪda׮~gL31PoNhH{E4 n)w/P2BcsZ6apT?%)UC9]i0 Qs" ;hi Xd@eEJޭ^`xo{H8Qܩ1K =Up |^svjYˣGMaP}R>gd=6ѥM.&#Iy>:ė)l=e6DpFQ8u(Z. ]ށnhpё"b=**\Y k2`fvTѴlm/M0S@De"d $RJdD$ !X(rovq s !9B&$zvGjbMD9Mӄt&FlhZ2ixW4{$Rs''&bRiT`MtIh L .5}:->izՒje̵=Y ݮBWd gf;fDoA > D$/IO3jzX8}(/I,RDT)ߪP8+i\&48z<LB#1) ^*RzܾJ! O +SJwqր{3dUMo׼;!%?\c,2's4ǶEBAԃ;N M9Z,chҶ/hqPR᧎he4Nu3><ϒKsX|o^c .nOMfAfOGZ{#.t\tGli6i%$H,îDͩ A "~ۤ @#ЈʰPMб"cCrNlѮ=7)űy)yq c ǿ]&HŃ|*0UX^ot1W "5nڕG<&ZtUKQ*E(-`G( HyQP =0WttxȪͧfaiaJLف BYkij3|Ǟٕ;Ҥ^ÛC-zք uD@  Pc.Qtrc}1 BC'P9)-C?m0 o\)#NsVbNTS kbqLJW1=']b? y:}1M5 )bU$ʦxvZ~Z&1:rxK9T1Z[w,_5̆~;\']1,ar5% RZ@7`RH<m_ѭVç: ko]v87ӳ/R5["j7 rڰuMɬR{rA(]m F G*`;q?h;cqHzDR: pQ?UQK3L7h7(}F'͔ŐY}Y9MaW$'h/KB0ʊxgL#]@jr *hB %P@sd& ZE.<mҗDsw`Vjg"Uj<aiFF"|JP>{w+Oya(iNqQ, HMk/:l#o1I(?֔vۄYX')ᤱou)Qkmn>u/ (ͳ3*g)20l.*%ݡ̴)IW! ɇRBu5~@H>DHU$pK9N%`껣7gGۣ`r#0 `ӿXX ~Uɂ֐ Vsv#P!00TNĻR挧a\WދH\hdڍ(ϹL5Q)==/AknHV5 n2ݖP uAg,2x^7Z#m X3U 󳈕k~RLe/9ʳ-_6NDV`5%kV>!c𪑵3oI&!\">4ݨբN=j7B6nv<\jFFJ{k3K]ib(\h5 AosW{mM_վIChjk̚Dw3rLrٍ@Dfi&^ßvǮ oӏKU'[uiŞlX&+.~QE$Nsp]0RuA ܚjY؃ܤ p?e/~s6BG2l܉Gdc92瘸|jn-_.T:ِ͈}bSIglkC@%J'T$u&Z;M`̳S" R#)-p'H?D%Q^Հ?o9itr'qhob#NU. pOw !=C.p:fH!u\aE.pM=:q\mzhJүO;;wl68o`Ձ]В(s_tЬ+oJlJ:X4gfBj-{}zwB"nud"^ Epl,QŠs/"nhaq=aESr iMK-&/zg3؃wghԐC˙a%`{ t3.W!;M+Ķ"g; bg^eT`s!`>LBs)KZBu|q|VYu{Bx:d.#ʱr$b9t?RYd(4KٴE|貳^^E`>T%sUgj1|Hunz|`ASZ\ P=;`c DvD6a8D-Dum/X׀Q#Ɠw~L'ˉFe'S<ԕFǰ: FgFzycWL+1bM?4@f2>DuX!v ^4êC'1$f"oZ8Q:|Fvjy'7nis37pDŀLqLA&.#bs]h ndnB2e_v"ok3 Rū>![!)**Id@k' l&V"Z% %yiV*v+D >/Gr  =)b+$h1_'F7 x2(ni04ag>1#?Ma&b:pwx!.l+5(J+B5&rD}L:3&o BVR|t-l')/dUKbh~ߊODbw]KTbwWq:h|Η O|*Lf%)aњ)4!He k'ҏ_N"j$MP[;582ryrI Nv#$'L,/LFxw 3>y" "b:5q\9KTcO愳AD=OU:ȑ]9|UZL8ejAt6ЙSE`މ'hh6׽;$~^?bEA 黶'Ƙ 0B$D &BNxa(!xI]/a)FSc8P)&$"C2>1wk &vD]DnzXAd?Us93O6.Ǝ ;?%Aj?a>Fښ>a|'0hfDr˩s8D{><"EOoܒpP'~Am%ɒu+`C|M#S:G9¹i)>^1eqUm}bmNȑ؆-"QWld7 (VI+&DΝS喃2SdӇy4>[`U$I,QIv O?em]ޠ ˌ%߈pJ?JF%a*97]oXYkT\:B҂wN+hAZ7mT>MG6üM`$ yW$LgTMMl>v9 bV0)qzTvKr.TʗdQ(?{RSv}_hΑG#K³02(bvf h8vѡ~'xHY7;H^ԕeV6 =4{d AeKĠ_ڟ2\چҖ xC*m젽Rk +{C*F3lt|qDjQI pЗ׃ZA Y,<E]C*Ts"@0ۏg#Q"k6&&؆Vۣ)dqh2NeKVfY%B+)1* rP0rT1T_fa=cjίLDOS8SPk]8{ThHgc!-vpFB.TZ`GQΜC="5nj cYn5[GMn&5hʚE24Cj`NeoS1m"/VÒsBQ .MZK"=sn.ǃԟ>\vSB<|.bXN͵%q#0u ;x%FG3VJc(Lj@3հgb=c\dr  H_i}_ `VbY(Y $)r]k&pz;WL1fr1: P/W74/`(oֳb94wg g GȈ+u*NiO|+ڰ] gMTMT^K[=-fo~10d A^tNkRb9RHw qNh/wbsߞaw'RLg 5"k'$ÑZsHi9# -;ҳ<} E`y&o)Qb^BZ$ytڱtNp?}TP~x]"kb\QX|0]o$|I ~D!&,En=fF p+R/ &B.ˆ@rYLVjXs %@*)oJvs\ڭ@Jmٮw!͢gOŊV=+y i~웎7d%Be'љx qxkڒ;͆y0 ʥHƨט!JD"Ye]y"\ 0^1nK+5@k{ۄ<i8~m\beg.I7ٖ^Fj%];ZcI("S {Yz0nP8>A@AǪ]/K`c!gI|Hu D2N)FC@WwĎmB$sUtMTlAHwR^iWNRlNS8z&Az#\chn጖ `ku&,~hb^_P]&rej^^f_] Z;0lU+Ʀ'u qoy5Џukp66E_s'W`,r=|ҟ A; Yp_@8( BЧWWtH*߷}N؝z\CrIz43ʕeĪ(Ո:h'Qcpβet!q)G+N007MѺj0Qg2pXneJѾxՠ΢5ڌ"l"="sMsW#΁sa\J.". E^IiDiG,T"0os36s[>x"VeF_ע Pʼ߶KBiV+̆[dSoЭFj][nprJV7܇YGӋrAJ\Q>}pfrSvVܖ+&=cxPZb }"F@)#Ι,[r h1+R?u 7\Y(C ON*''ldaf9 b:?Hd35#$G= }XKŇ|TB9%|!4/r08%8J,% Q1l D|* F"'/`}/cQO$GUIeQG50KyPO6'tq.+;RbPklx d>Y L W t2`~jBOj06M7gL*:塀Pd #Bls(/@,@U6FIDyOQ0]k~}kTS!ytIDUހpYdvt4TSd ҉*U"с%o V8pH}-Zh4i'D L5fďE"#WX%J;rDk2)_2h ]/3-$TryHZ]BG/K8(`e_G!Ģ`ip"<;kD"B~q/}^r޾AJvx:qݷv}ZμLj'^_xPg%dh/qӞ#䪫dpt5ivr9W G F=Og%QtB|"X<%SMƙP2N<RM!`I,ovm{pTO:a bfm+ idg#EqҏcY%lPg RNܸ(#|>T=t;x#"UՍM5lK+z/3UjΌjXKMq9#5_49\c"V$xH2>9[wDT/r MVDMrLtL oʺ^hc*E5fQi ȞidULn-ϑCTS^a`r]H>Ų6CehF "/8!N X絑s҆n [/l30Bdf&&ͧ/wMz 1V%[s Gђ3 Ұ)`lX锟=^ 1gS&vhGS2ۜcQ4P@ڍoGgB(E^X; 5h1%M2" IpF s{$gO4_+(OJݖػ'%i#f(.PYc͉8F8FxYpQ3Jl{ TVI`dYQ_{;Az#AgP[KkgdS Q8p!h4t(#+]] ֩nJD-墍+ЪDn/Dܬi،&9<%C^W$VV+B&$Jf[Q@OBH K2EdE}{,J1%9f>v D_M +XlIE #QÁ25"PwdV–]B32*Ax]tpGaY:_H0?,?<=y*U P=IةlaQO9٩a\k"h!ɊɌ0"2Vy*M鴤{]&Q<3!tK2 ??,, ͝^DRy@z\EuX2jl8f+wS2l5x|ƾlQʽ;Wfؼ=lcg<(3b)NY:j(1X4>Xl}?URX{Y.;2:o˖3 ,Y16Xcc+e3=rU骜UTx\U.B줸se8 Fږ22q*F>#Fƛ χQ K62rYaqƪDH]V:42B$t%QD ͽ3{!!)hE<= TpII`=}m")@1 #9` @/pm*>źИ/h쿂x-3}c-#I^ ,vܤHUTQ0P:RhI̪ʋp!r+V7F<-3>B , BƁ W2ۚ@gpm|l'D @:<7292d5Fm,a:AwW?aZʨ:L]80.[qT|[nxRËWÐ'"œ8AQt5B ¶WyZᅃ`QNjDcƮY<1tWcJ 00]Wzٿ`x LH@[ /=_Fľ6ЁD#xF_IcpMG̱Y91s\?Xw|?hbKTҬ i˅?h|nM=1^zbYv`~b.ʓa85},*oKBlJ1'}\NC|D E @! $!)N"=ǻlT>^< =yj?yFm9]ԠgϸѴgS=t?l,$[?;"Ȣ8Fg~r 5| ͈Bq1+.(HN}Հ+_; RdDー4T\pR!$] >4trd2~y ɌGb j6vx=ViPUW{fD{<,kƉz/!XHB&,>m;FbP㸌K0XN Q)e1TFT*q>}sz)ȺJLJNNK"Lˊt bTQ%8 Pa o^ TmM%Y^%ق}'(ǃA$Xh;NYkG  0Vg"LrUN* +   tkDT}EuYiZ2UMËUѺi]B" kG@ћfZ%c %(q/Y'f3s C5G0w{{P9j"h\C }&ID=:q2~0qRQ4X5$*1nΤ*ҒɩDDnψ}0 Jc1Vsl3o楥gr2R$e%м?jk vZR6ATBT$ ;rVV\kI3k視pl`j`>\:=7GT5˓6յ E d%dj% R$ }%uQCD &nΩ'Ꜿ"fN@"3\=><h:TPfHUUw :.# Q[T=C> L?E7㝪ma7R.P?yӪp"JJT2}G"> k#М1 H;rEm 2ݝ'qSmjT9+S?[OeCmܝЎ&wv7f w`ޟ>޾8b։C.H>3 6Ú(=ɉwϧ|"}SwM,].ehB&`r82$CNr2"%MIN: ćiD| '!Q9 %_<0 ;p8-T/)Ÿk;]{By"~<ؾ#-e~ Su~1ƵB][V0) 4OB 1USb'a,hE5L͓6G4K=ЦgCND^J_ {i rRՙjT8WJ.ƽ[N}ƴ% N(26o[^qUS`yӯWKv7 cq}Y/i#,Ym5'+'bb쥒㮨y݉XoXf5q魉igvZk}#:zg>Mi]ʫՃ W7u[[L{HZۑ;:f]FjQ}s /k©{kPo|gɕisgLv~TtARWe+X' u 40]٩9t៽|4oRh*\4Zm o.0š|?C3 qx|kx\Wu'ɱeْFey!,[,pFsF:3V,!(R_JqzR0GPAKKqӖ~_>,?k^{^{_[| U 7TҊzpXvVl 'Y|T1f^;Jd۫ks^z8_<fbEgJʌRL@w/FAάZ^9f5N&>/)2:_zȲ!fW-۰q^ٸLsuehslPTcuةaZNlhtRfZTUcC$ԇLF5NG~$#I~ْ>u695815utF , iŪMGTMWلjŒ12uFͨ:U5X7U C,Ւ`&f]UE !˩hrSѲ,VĔiK;yC;L_`yʹجbkjY*3%K4LfZi,|9 p^جj} E jCT]b#Y#b$fӔ,qD6;\lH66:{fwbAM4_iHC9Y~fMnÐ3rua7mL ׌9l_j"O[pPs9˳S05O{[fЊkzVA3Q?!p[6Ck޲LU8zZT ٸ/zL)EgeU"5UQ}ݭ})M#pW 8n N8 dm 1 nf=8gPC g+ϳ> /ziwwqǼ͕P/ܳke;qiW];AvZCݎ ds*цE#૛w%`!_669kmC\i dIf޵%T{ j@#h|yߖ9dT&O_kEl(a!uy~kƢ `3HwnZwEoM"LCNǽxUYM_,B mGkN[Psێ7=IZsQIHCWLsfJ($ĖƷ!mA<[<$?5MtX ͡Yi>;q6e0C(͔{F<33ɖxu4/}*ѲLiFsE2|,8w҈\k*&L/!yj^Um[\Ph졹-;wDnХ4A.DS"fuqT`;UqcP"G%8%Վʲ;Y3O8Q{dDA>v4OYҪν;&`8/kv62 ?Yt~$BE)R=@e0lr^%: $Sr(VWz˱TӚ_ReW'tl%MB[6hqo& l߾eT!w5K2+k؎0ò}Gbu='xGI q4?6LRޅTO]A +/==-GUP~tnHw:S`c;z;}057F,T*dZR*&+H4UWg]o@ 4^upOx =G#~/x'+(4}{9(R kD),;V,osx3@/.]kYC^W( jPx GIuump:njY 4_wirevhWc~1c*ڥ( =g5P+ɸ$y8.kBhԏzM}'Xlz_lҌtu91ן':o;< 7 mMN-X'{f <2XYk+Z}7]?xRhj[eyfޘ>bg TŤC"X?!6qxb?+jw >H ~TS5t1TMu?>P AJXeC͘JAڒ-\?4opI*+EvZoky+hAn!'+Q9'=S"ίӾTO޲E fXj1:;KWDD =Sx8p) E}Lv[k +ǘ+K J@((yـН gNta}(ՒUlaszZVKHEl@  =:F۫QdօpԿ\h[7,-J?[xH-(Q!+ K) 41fpA)Á1Ǯ|hl> TĈ3p?,xW\P(ZQ- c˦i^<40f ud[;h] _z/Nn_jL,CMׇPhDRӂt@ͨm,{^&/HAɀ-AoNvmܶ^apyLɛ71uOu4şk[ ؝Y@2`OloA 4He`GY`1>~rw5Vj1`pq۾FdQggͩBȆӧ6;,5pupTnp%Z<ݺaR)8/@$ )zI1'e5cؿ?[F.M58ohy`=~\*ۯ[#3D\wMVӡU~M8[먈O贻κR&ԬE6/T " D:7JdR+ ݘD*!Zjgd1;[΢PFF|@N`^H&cC]p,4$gU|~oE"Pw?'4+"BdE[ 4e05PŽm9LI $R8[TCG<>vaw=B'/btRQ1B`e11<jzh_ʹs>VdLC Z{}#PA/C#B1xgg 4iAMo&kl! vSk.!r`h_=vf4!10_{z#wwsc7= ߂вܺc'u1PnV }ܱ{5?"H«^/mG&hֳ|72C adT k&+ <M帄)-2AV~OsNf{EFFnk<EmYyx:_ʪnd91&a_?ۑV%=F{܊r(@ XDѷ+r9 z$9x #\<<'cs8Ef•<kJ͏E:MXs]Xcө$c1TWO]i^'ZkR(VO~:?iuymXz~U0IhU.UvՄ!^OW':-Jڽo%F>dCIGw>Y_=(̓4+s[ߏ}J8H(NEt*{QŠGսty3"멮6SNՐ> .cR LUa.,zYtVn=Q GF{`'3 ]d)`Bǭ ?t&NQLٵy1#:4ܢ:/<Y$j̉`@vHa0f$VȻk#Q%HFw{c%RƄIMhaykY7 Tx$3$%-k&A؎'B/SaQ10??F{~wg Xm`)%Ǚy|m`M^PZ`k]Q>{M)X@̧j:6AwRz$ްjseܫ ٍ x|oC-.:a6Y$E堧>ܩ1uX$&pX#qs8_ЉjATe N<^$U1G}L+8L@VO|?聼6GbR9i4,G)-wDPyC1p<>4tQgFicqB;w\bS1piaheI1q9fRr)Ex Cf \٬EX=m_r%>B ,DtF'![g>>{R)_TuVsk  vuBfOyڦ 9E˫tl`4CI y^@0]ULY llԞ ؠl0_Yn` D_蠰oBwk&H[~av `?SW[6%г' :az\qu\(̆\~ef?^a]D+ dy˛=&=X[dg^|0$CE$"ʍ 7߆w@x?NօSr H8r% C>|cY#AO4ߪj3ԞxuI%e?oHiw^l\QDb]?ٌMHO7FuMǢMk0<zkooW%-*,Jc"D[|)+[h4Tuwo<_cO]6s{J(EI{юnǤPF`/q&H;?T{L-d )~pj~* NM $?x67!aҵ 0$WA]64yO&Wj_6cGh xѾͤ+u<뷃a+fUV*@c?[ Z/]w%}Gw?3 %+XoП\(٢SsMIz {qs/MC;#r;wʒ~BZM0+0bL[T-;oBx+緞5G]@Nuf^EC۳W;Պ|U.X'o33Lqӓf, cȠ==5b}ǟڽID+Igbn*z0S=duA$?\O6Q1f`uRŋgkY;Ҽĸpl1*J'BcK.^z:%tZ| [GMNPU?hIB\r[g#j3iBYpO9RjTy:_ 7{y+.&/b[3fX%!5W׻|ۛd5#OXvL0- "`PzkB8zӎeƇ삪x<n}Kx+jt}Blo<5TI Z;+Aj˜6[jyd#z`Gz_mSnj {_e?՗A\_7SG,_ Ox꥙gs }SOmںBEcޯuu͞z7(6׿v &=/Ƽ0+?#avcV{#DS_(k,NF# u{oM28 :8oU`=w% bˏIcGIղa6qa0LnLE$\8lxrg8In%>P*/W(Lb[ ef"IL=?gUNEHT[%795'QoTÓ'E@7'u<.|HDē?g&K9omSɗEj0y;%6oɓî$nF, XXOg$q0(D`(r&,yC: ;򐪈DLŋYa^ Q骩)AghMY|dž }+ƒ8~ԏhU ~G&|/]6Ty !E\AioWد.S*U!@mo 9R>veIKbwORܹr,|*HT7Y*@-ls,撃isWLw<; `i?L풔-ZyE`~ԽVqxTu`G><)_}<=2 =%"RQNn t&z>>\\lXMl4yUp"iPőAp(MU.CTjI,5Т p65KuB7v֚*># eR.h+&]~P | Hd9`ٿ!dW^k1: fЕˢie~ sȤ4kHj$z: NX7T M,ɦ6 `ueFfv6/kĽ2=x;*{(.=H88\0s^+yŽc=''j,6'CgK``*2vX\\P>PGkHdmL*SZqh{qV?a:,Ž:_hua覭_7թ5z>ǘ .UEW<: :+;P䒉Q+Wicܠ+*B8 <T\g&p~>LZX{j.KxȋGc:(`M|t4JNXIMu|KYWIJO st*pt]#1LrDMJ˛2;%_~km&=|U EC[`om@룑TkjV4!wDs,r4O3*Y1 ^'][+3*mf(~Oɻi %d'.hҦ1 } L(V l. zP4zH,ӵf;&H\)ՠh!ؗDn)Ec#لMkëSl]j Yw)sЊok7RRZZ_3hs'j)MƤ`P:S;5=>Z4 jy5 T#z7SA v,MF. ckgL fdz>HEpc TZ32n9Jٚ#3vURT͠S QLިguiQga׋ut#2,j 5lDh ӧ%ްyL\+dt?AV OaqPeݸ~ :P.4橦PEWYU,o6\?@bhh[7{rRpVP\ǟi]~24l(&_[ZV(FһnXzjtN][=!mm]3R2Cل@ȡ;_nm]2;c}_",ĞN;r/>6q'vTrljN4/slJ>xaŰJXC:#w{­Afʤb)m؍& ܯ=Q 5; ̬`#{c l:lf0,.۸gSㆱҢamZr\@}YUvbvt/1կulmTaaW;rx30Q[ؿv1!naC:{(]>$\/v-i,{S]{0SWПin8@I$:Qtyg[Hԝٺ"J'}%"`F>(UEԳ>PE,@!}->B?f&!|_-rVZ]_FUImy׊.m聈e\z|&E#NNV=|'51db57:hKl)}ެzm*ռC`G΀cXU۬-xq.P*f l$i}{`$m+З7(FZV;A#e"$Üֆi` 'sOD7G!h> [fQGQm.5Ob7=Nh~ٔb:iR҅@cv3 A jD?m EG/J'Y2vPs&Iv{oQZ"i]7-x` /iq}`먙:j͐P (&ݭ WDBD0ĉZG$o[xR8;鰔zpӚ4񖊸q"v}A`9/P%u:{2{SC/*d(dw;@ Н5&0OgNx/< 3ediN\~J]K<0^ Nflf%., '#;~q~c=֎i<^ [fIǝaf2`Ñm/+제 @Z|F7`Hq`sv?wTFb0]Pr@!q;\Pl lh= yl 1pN@=jrd%WWb|#u}hr៝*x'Mi= $SʴƦ@͔,m&4P"8)9gt\ZO,[~Qrs8=淓gxM:#w,8Zz% cFarc<oP()Zgȭ)Rx'Y-@QIdQbn nIbj|~Pf@V>@\oadPX`qT*բ9T,ʥexaTe&LI<-R۝4SfUR:a8` 9k쓐A9)Am,} !~Z^=b\O"'qSő@+K|!8N6̧&4hGy\+hiCgFɃiQOiШ+Vqáe"/zxiO 3h*Ӷɋ]Ξ#;7 i%$;_8sITV jy՜V~~lplH+y0+Rk ˁm^RJSe+(urt4gL#=!؟頌%.VAVac7Vɉv~\5t6%At5G`̇9Q;fQ kۓGXT\uEP"$#@tl,굢v"/nnX:;I_U<~y}<i鰒t<ްjA.?޴t\4$e#(?7^w@ɘ7ni\W _n0ߠk RjDpZ䀙#%Zon` SmM+՜a4ߺHYO4.?~- hZ>VC Gdo^%qu󓁆@e |䝻Ga!R("X"A;+I ᚺct~EceMLYW(x.L'mδj: Sv^ZOBAC\#l,Is!#ܧ= }D g:5s$'uG{my _JaKEM/79%em򂅗` 0 #.3H)5W!$F,G !#FнMg18+uuqX\divL7Y"Тxh56Xn2j&g([2baB {;ٵf׼]kgƴP|ä2:2/Q U1o H=Ȥ9>e؊//, xv \Vh@-i/dB\Wm20"dzۻ.r[KVf[s=cN~,7s{Kzwi󅃡2,v"Y72UG>{ $AXݱSqqM+I NmZ3G S<#Q@QĀa$ݨ{wmmE#\ M JJJhF|B-:J4u/i>]7 ;BOq,z|lTH$Hط\"pԢՀ wNoJXkC3RVl|M6, Q A;p_MwY$nqh}CC )5TBpu!XyS/݆z;9g`=wSfBu$YgSyP#1a)jg`u7? `fj$5`8=;!Udixoa ļ?X]zv+t4}js&0`C3y}!N@h`ZoO=P/>x0le-`Cu œFLj~vMy}`UހT ?hkE_~qєFv췏n[Jz:>XզO=qϗ{-U@ӺZhVb03m-U;dXgW1U`L\'F)Hua4^8#}|곁6qim^+ ^Ѹh'6☜ Fqsb@BBEA F\|ɁWaǢ%1$">}HԴVň/G}~[#K {jGb{i>8(!W_瀐r[NȐ =#:5)x`ABa5MI%ec2S$ۿW_2Us0a|v7^BD͒[@AD^Mm/dfx_ R.`KLXMŖ}a/Ϛey3Iǐ~k5׎T# Ͼָ̪Fz3^Z=ysy. ec aJ-_}!7@vSkoC.b[e COeT(}M+(̎^HOEjj\uöm|3[֏)g_]nEx:v%g#LU TfOhU`Z=ސm#2F&Pί~Qb<9 mo1T68E>~/^nZ)^;L)L^n_5YUqnߩSoլbH\%:j%J:O 0R uⵧʇ N %m~qpEtlۆtgE(a?{dzζs -]xs7|m]U<۾ 30w]Yn2ڬp,'fmk]m]Ϸ0W_>U{g|ms{\w>zb r廙>_5x5N2 =@,7ʪA| ,\/^?rUCXnEaǵcxH(NdƼA^(P?`P]K=$!1 Z@.ՠ STԤuAh̆pOH<}y?կ:`koC[1Y2=$5EVXEcL,ر^( Ax Seu2Doz=)|ӫ#-534$`@`y>{lY .|rn>D4'wϽUIѽ8r~:hWDU@ڏM@uk) rɓ>Td+EF="ٽ9Ȓa: glqj#RybH'_hsVHF[ qAH&Aѷp+ac/{lS4^@zm[$UO?Ӡť gB!~o5Q1!2wDF*{4\.&cTmõft ?ɖqQ9lA7HVDAx g-_);^r]&Iѡ={{F{#wx$u 5n;e+.9) 6Jhaw#XK<YA7 Ibf:[dar.`S%?۝{f[soν1 1cs߀/]~7+js?}ͽ8. o}A^Ksh@ PL_lS-T{{,xO?ͫ/{~?xRZvnv.C`͆b =&}ϻ!w q/E:z xJCz[@& |v,x9saPceC*8cdHICA$+CӋ$A.((za8V٧dd'ßH5/f,-OꊅfQj]P94γ|րH: [h`nx 1'~0iҴ@{ 1v;t-k)l8wmީwEdhY0v l݌U]2SYϫ! }Kc K7K2Rasrм*:bN|$evVUq!m4RտNx<(R//!zЌ9P!zX?qMI_KŸaJ*=#R-` J]cB Seg1|7;R ǙTJovZXFS*0wBDyU6e`f!N/)jܐ00Y*|~C gc;ZUB]QJI:P5iV)^+nѓVDOiSc"T"n*}3*,k}JiI(kG"h[b nϮQbJs= / ^,'Uc`?u|I#J|vtD@(*]d3oNtE'8h]+aD)S* -^SxȒx=w,5IS'vk WI]mcWO|O$wy@+_(c`RšN&f{ i5#["=.*9k Jjd.g{?)W/= v`n$qP~SG[mkUQ P,DsMvڵ%i0f2 cH uguݎ;E4rx6SӺt`+*!p ođTS*^L?HJ܃TR#gT o)^"D.-Z4}0lFxq F) yqN$ ϖ{;" _0LRAՄhA>6<< BM3UL#ƨVij*dgNQjKג۴3;W>F@"D> Ң< fbeW|*(n 8;2s+p**0 }KzL6̹Hw@WDRv p*aJ ;u~ !(a1!' .}Ou="ebnvT1+7r܋,[?Л.;#6e=;[~Y6[²D7!{v^]oչ 7s0ͽ7&== ^ Qx} TTW2$;1A[ `UI`7/&Ĕp1Ձ**4&*GEDQD/ݙNtw Xefzzk59޺ֹ>9/T|۶q2P/|{S;A[`qv/Wtz]P`02zk+kP(c݌1UnN{n2o=LtpeMqvU?;߱j1h@3 5-@{ x,` \G `Șn@0p4^ 돆:< EjdJK6_+Mrzl!S=O81t4s}дd0`MM0pm'cta!xmd3 e3{<XM˙ݮj2#{dQɆ%1Jvysss,h^u=BO8t؝P 09/,q_FV!kN6_doҞ5܅"H۫bu3Un >S:1)}*Hd35u`>}"t?4t"&:Ȕbau&gCOLC,Ks+t~?'$-89 t&8s RGO* <ʲ M:[X[h ֜D졆˦tZR0W/UbݡۄpgO&^$`)g NoN 6|s&"<. o(J~wh' s" sCM͏m3 5=YBE~&Yt o\j DRHޚdI֜k.x#n~?N:mBтnGyO0& ]eG*2&dfGKdI y?IodW\L R0j2ƃ_ iQiO } R=/4.њb*OcȀ֠~]W9@j&;|2poM+I}ĵj&c¾ mNfƺE2Q.Lݢ?LMŜ @"̙k]䝙sr ~nTw̚ȉХzލY*e6n{5CO`n-P +{;.n ȣ#oѽ|Gj́X\55hms2Plݼf+8˜9 `xXa$sgsMĐ11lX@5uXDe%M(ʌ>hki-j\0F##qj?izT?Y_Vcװ[׋OJWV7rn&1Hߡc2rˤ@@l :OlajL_ՉM:AS1("sKcf jWYg@OخqV8RV>/~ < A{Y"u]keQO&HӒ5aalF!ՃiK-Cu>@:tX=:#[LJZ&s;uI&J3?e)) [vuKZ0ָsEi)Z:/'ۄ،X@c>70oAq)B&K5HbV,3lBNA|/e5p3ӓt^v`͓.?|ЭSVL-bƢzW$' ?st<16gS(es[Mן~vR/T{($P}J}TLGN%wh1==vv.E9K]evc\n/nU{$v t|n}a&pej^ ̼dzEV!О&0=U2.&θ m^z4E3S =Ny^&17v> pbtv6pdG:BbS~Lpȹ > GͳbJnJv3miɌgq*RveBD@-@+ #NEpT8dl@bܑa2; (W)Q% % _\}{ۛ,|.S?t> D.qUVUp^.2_f%Ĵ¾؞'*>?cن? qA '4K6/|g5^ț-'mo`qfnlb`?t.& 1>|6|L"iQm?@M3Ƈސtl:%-/g9,iY3gJ˙0=`ЊW2^I ?FթLieEhy8لw7g< ے? e#z5%73&-y C =m׼Y(u,sTyQvE0[#Mn'gx~W@Uc<4ɉHUA&)ʷ8FݒbVPH'q-Ҡoj'l!'L\w4{;'J,o| Pg/ h]UGc 6{" s϶WlLl}[x3*BXQN6ؐ:Ɍt4%)_ Na,xc.A)2*#/,^ŭ}!pƩNſg%(\GRۼ]M\{ vz[i Ψ3浪:7B "t)T\mv NGVv5A9F>i1d/csؘBeom(o ʦ֖G-(!ty2z]YAeqIL:rH;[*xB&fo7YNӳxnxr=,b\gxHT$Kdf*D`,hNܹ 7$`e6hjaZI18l4HG6\Lݹ[,"ss;9=UJBýpXQ㱳$&"t0;rfDc:B'vhTzvXnf;/cB.ʠ͊qf]Zm_PxF?A4.YJ,4JDǢk2UOb\a7؞Cک^>VtX Vsr*qW[]6٨G?9[k.>bsXrU2^BV >n06ߖ1eV.:nu%|b2/vsWo$^ v;q>G;E}II}bǂPwc["7)AK&2|ͳJ/ G!&)ӳ( fFΝ!:2+ȑ%#Mz<(2/>~*If+|/Gq0Aף?(aUSgD̛W6%{bZP>]KBMޠkp0x=_ֲG)VBfaqND,ʵR3LWĄ??j Z-TВBv6~`EʧekE,D/ ?gbuFVoVTq0nPQHe**8vY *IcRlox#Ѿ{A-7pQgt4З6feLj\FXx/K#t00<2S i\3fK vFOC'f$еo`:,b^5E<Pbp* _'w[BuO@6#Ɋ&0cǂh]z2DfOXQL_?]eeY\9~z_l4? |@IңL,nOm_%kұ:Nf'>+ɂgNBm?KkHRƋmG ) z!}"ٰkt[ܛ1ƟIrlV3;ɤ^4ϰĂOEpĤ-v?yMO+Œ|]9gE7fS1Keгv`DM;,9m뫷1wA(>!1zp4;fFo_Xs_*W \8㨄`ÉS8 -F[^,dZhYXe㑂rekVzxjeV+:L"mm)#EJ)ʨ,>`s0F575#N#$ !9ĢM' 51E FiqVZKGp\(Iw[@XF!'g$iiXŢHL;("ho>h=Ss d צdx?>)y"ԇwI0v\|E SaE/kK)G?yu.F#Ɉyߤ* X/| aAA:9 sz~gW|\a硋TPޣsJ6Х|(%i~}J <͝Iw(%_mIM6<~(Iʲ^|H5j5T?FuC2_umm#C}on^ GbקUqS2بqY횞9xpCbѰaZ\6\b*d3L裶lw(No2+=V{QF cϚ$=&B>(ZXIOڣ A!^qވ i J:}{͇+R ˚n~a*t 5u@o~nj zR+!xX 1bjT͖֗Rs'{IeaxĘ|\ 3oV6>fk&3ZG+8aS٭b/::׭=5~_h9K{ 4k)ƏMG_=Vh37S;A)ͦgJ84rH:"m =1CehdǪm1l{LЄRI_kT70rofl157 (̤ߪULٴHI"|N[Pр>3 !! [Ś&숵Az n0"kΤZO[yZJq'TgЯ2=^IͰ!fI'9#=RHCȸƈJ _Λ їdg';G&V&0 $Pkӣg%J贚#1X^`hPT~>5(I@|<p0w֒`0k'l'Ϙar-&Tǐ|6kp@riֺHo1c0XkO(m1X {gYMgDIL{L8 @T6=WY cꄠ WKm*"s57qQ,uXfIb+qqي|>m|J> :ԌdzK?nCL[W 5vΗ u͊253{;ZN5:=ޝc=EF ס& ZEx"`+1#^v1-&~fPYz?fNF.dM0^f8Ll+,=d\ 5ƼG YS_P^dw<:kWFquS$czArQY䭥vr0ʹgcCd@4HFfAnI:a]esYeA[u'V; o[]@̄zWE 'i<'wjs>ɹ'5Tv zzm~g-ùb1&^sV'GKyXoo63y//-)ЁJke*25|]gwFTEnk#s7lU=_MU_|wUbP|fE\cxOBĎrA>%%5Y= >Ija&Yzl|.=UXTxs#%!! MesKJ62佡I:3Ɉ[ї+i<‚Z$Ad :u~NޢX׳!D.`Sm0Q|q ߡTv"CԞdDh ʇNLiBFjYɫ5 :7{Glȇ-9HNB_9QS{~S- >vy] EAH7 j|W_O*ɂ;h328IKX+׊& a>S$ѵk.(خ~*D"^fxKK9b7S`[>FQ$g%ῡCgc=o1=[p'hw}Rm,=c2 J"):ߘVFLrW8.ф1ͧ̚j L1bhA[E|iwnWRPRߍY}|(ZQEɨ<Vl@ SwOuƕ4dQfH N:Ắ]1I];چZ 66q>@'tY9TF9`s~-+*\|\4Pꪬƕ#jUƸ` o0`K:kKAOxiuGۣo %)TY/cV8_zř!["/mA5{?*]n;>2r;!p`ΗreS62˝J^uUp\ݴ ԅddJn*l;-<ͅJǽA?}#wRbMu|Ҵdb 1pR8{)嵓%}Q<  '%Iv%1l1y0C IA%\^c 6wG5 n'S&⸦Ak18؎7HhuG w@`"hT; eDwU3Zp/֌D9Vcc0JFEB= Y>[9Z_@G & B  r,!v7n@^N@bƭGBEU{c:ΫCqW;I" x|}pug ( $HOP @R)S8rf `Il_d}ZH9H+f$1T,d[bYSvXWuuJ\]+u9{{fg@0ݯ_~3eqPMҰb*ie\9驊#JХM'ez1=VRS IIetT5AK5S`.޿WLʘVIUJjHHZdE`S]|I{~#JfYFr$קUKj8-픆&r"L1*8=!19*mkIw5%%ak1I%1-4bIIUԤd~1%Y(]eJ\iui8H1zi`k3R i'NhiM&y*Ӡ$ՄVj;\CpƤi#+% }-YJ 푴2J'TS֖fS: #WI@(r9X_&{e^k=ZL]J఑2fIK4LۆƔjiղĚR$YŊZvqY(sLpɡ]]t`d\*)cH ~URtCUN)а=P+\n5iL,PXlÒR%eg,nGhIJ2܂+7/ݘ+w7Ǖ[B۪>uLӵ&]RmQyWs3EVg6_k*.@òZ{u3t5-D%芭-Ǯ=/nqmb+ m(lS ,ŵ@? l>)m$)QVYc-Sճ+aJb"kdiʝ45;wձu놔z,|n]wp,KD# k(O4Ɉx<SK*Mz`Ő*hi9%T覡 *h뺞DQ(f\x0=c.e4v1t+ P0?sK]}xn~()) -߰Gqߪ=hfڬ{wҾ^t8NNK1dǯLN3s'OKiB ` n@Z K0Omo`pn{W.9dkf( %~޻1VjEDܥ$I)iCgNLiҴt7av =/c%I]ޮxp=Nr'Xt&ŝ t qa 9K,'$S0Ǟ1Gb 蘯E8._CպVmjͲgAZxvUe߳}=uYF,o 宝({h-T_9X*Gw%7H=4*_6KKQHi$}HǞr@+Ma[>`MA=잇anqUΤbrmIC:!.Φ}{i&B [mM:}~M4 C'l vjskS0ғ4hTڡv6j픠iONU5 lcKd | !9^RbЕnj/mm77!@^7hDO<θzȃ@^+!zjjnsM̔Ft;[=0 ~:133w f)ϐknYIp%t{20EM)`.aJb Q`Tiύ>5 f!aZMji!}封IR8zG1u_f9tmY5z#zgUYZ?}g2@( bTx\2{hCڸG1_qI|_w:=wiR45'ՄnbzlceO}D[=7ʺ l'.)KlL i"{6M8*PO/'F^!|hLZ cuS8{rLc5v|p)vMMNV$)EdTif % O v=_9W`)1cX&%‘^}v404F›-D{p-}NoM4J"Yu+{1Ѷ8Z8"QRs8"~Fn2ے&VySd_ K_HH]s t H]h4?xy HB6bqGe;v-Lq jcoܴ giRш߱n=?$X<ޛPFmAD?|Q(ja ;wRR+-5g"fQ~~%V9\\4v@p ^]Csނ@H0"9s*WV_F4նd:[{ $sji!f$(3}q)ů#k7ERLg=7SYUU H8fN t~T[:>,٩zvԔZRnFY&菱ߘwӉsVG+,>OItM+h 0CZD1$X/ˢdjw8`G7,5؇bE1h4DR4Mni_xNzp4))_g~ #-LyByBѺe1]UT> I;y8wY8ޚjdva6[sh@DdGSZ075m[xc~^a͢7]K1 .`xGc셙uaҼ Gp4Dd‘qGOv6#AٕyM.^ 0;9*M"WGN8_8H ^G qH7In#&ױBGr:c?tm`h&B {ٙ XeHv6ˮӉTxx~̄8ɩ*lgz?gVȚz\?k>L\"mRGFʃ8W@~P<(*mCuS°OAz5# -\sLfOB źe? n(2^`T ¿6}Jl=(,/az34!P>\e<\ Ybۖ?5>A#58{ʄWf2g.VEXE؃4{pR*o!k(>{&v??l  `(i e'pb?Z+R4ߪY2ClqSt7K7[VXTJl itrnj Kr>1̞ε c0H{qVc.8 W0U׳Nm\ ̰*q*1 bĆw'40]]*<>8>Pxssc|?m1缎*"yDfGڰ+-oZhI,xF F| 3Ca'b>߲LV B| i /'r)π/n \q5 /mktA0ar^y Km8|bnYH4 P7 (C䑧HZFM!0 `Nllq=7݃~!QKrv` OڂY\0]Ù|\!#z9 W%_AWQz9$jg]. [ufG ^ 5ECZ;LL{(n;nG- ]-$fw~f@xqV 0x{~LR,Gt9](T#ER0{kK-3zd96Ef;&-oG! +b; P# Т1u6^쓧*kF p;UJIoҔL9 >V&'Ii&UQS@2~\(1ڧ[4- b!)7-M` d7o0 |ͫz IU=SrЇ"ʣP(MGSbπhˆ6&o+rGJ*w61Dwk9d82 /BmCMe9^,UҲ` g}ᆁ)Ex[>qzW]x_:es M:~w{뛃7&c(m˲rv[ӳCAt-DxOnLWͮ>e ڔ$$ -|nF肾N$ bVm̈́7}ݖ1$JEkݛy .t7h}p:viH' 9"7Z%=@1!j;<Ds|,+Kk{T|x6@;=~iU13t_=vVUŃHj4c`޸&2v6\Tͱ/Xu)oQP ҫm‚{yYj[p୚kJЈrVwXvވϮ}H1߰!ww@GJ)$Q܇Mc 誥AԊ3w٦JI31n4nq/i]5@ogo'kK벬>؏Hxʕ!wY /Lj:zBYl0a}?aYcQ/c4G$=t2nLQzl_wLQO? o.eD 30 @p][eS 6¼,BzC?^OfcyI hz]! a,W~A:L:lWM*駱>~~]Nן)lߝ@셿;f^A{K&R9>xm]uqaǂ?y ֆ'ه Kޫ>HpV sC?~QISz9#7!m -Y{54\uD2{v_Cq!o …_*0y=]4Pvɂ{K(|CrK02bDoX$U`i"ZE#l*"  uwEKv|5uyM`僚|Tvk#Nh}~u Rtzφa[J$^ʅ1 ggHD bdLX80k,JM#Hv~+7[ &FBjoYN]i8|jLҜ%|EE廫8[>iЯ\ôPq!{'wuz^]D^ =B!"5)ghăjdtyB̙@W̕ Y$ˋz;ts )p!OaFŸ(”N8?#-.>DܳRUg1:)-Q?R.[Bs||a3R #=%Irp56l3]c2a JZ]y[c\Y #KC|ީ!1noL|~] E#$0u1بjx6%+Xh`Wn.aPL%t5AMv//x0)g2bS&=G?ed\sӣFr܄&saЅz+j<ܱ^G'Js Y ^",=xMRds{J #t 58ƧM[GCgД`{af REEzD09tJ LjdD F|P]>ݳ6ډ UFof}&Ȝf\Ak|?V|E9䏸ȍ5-J8*ryy;㹠% ?/ݯNkcΣb%Z8¦\*e045z}?l]+`PZ;'>pg[?"8NTL=g |W~xWkluH"|;w8ʧwk(S%MqѩT,"Fk )os&dJ^ȗGn$hj+cS-:n-KS͡ 4u;tj[0۩DpjfV'BUwO$ ^NBE$=5%i |̥fkZ-5ZN;t[M pݬF;qwS)rV^-$^~7"JV'C$>޿ķޡXS}${ʼ&:xO!\+U9N qO|" pn7> |}3 pD$U_߯D"*AmPI8ʼj`aD`jfr"`Q=oǢɡƙi2[PjXSnhLge%4WEweYn.&!VU&(Qh>9 ov`ŴѰ=nDTᑝ3B ,r|Av{#ua</{7_q2qVN^LEpCN"" 4W?8n^CKs2Q7sQݹyWr1͗vpcc A<&! 7jSSg}d8ﳐAR(\}mWH$& (Cr7QÁ, ˒Ɂ_Qa 4ႚ[@}!JnAs(7>%Qf`$ԪY=BA9说!I vQŜ7 }1M ;zJNx6LIT!Oǟ <֞x%1'L$'_GIIpNZv(7R`nNyB7Fm#i5װLLg.531蠠 g W~q7pvAnvZK3/3Oq+P"L<;N2JҸkkX }Iu۶@ؐyQfydk?ŗS}"%GoBkwalO"ٞw$T>~>޼ G6Kzr_}NbƷїJWp.?J! $V^,DkE[O,JӾOsm1۵z I5JYYFp>ffH-;Ӡojh^S5R)ڦl&-;T70ofYJ|ZYk&&6gCL2q˶;R .Wk@JP`41lЭ&v+{n]y,y+PI]Du?&FZMw; wuU0Jx`#98kAwh6~ CM 'bL7]K>tϫr>-3$ m\ !,4Jwf@a aus0DSHcҔƺ/!dFz|j3(k:C ;_[ {Pb 6Πebgd(~ߣPhIde}CM󳶁adV'Liq=0?B m2 pXuZƵlL ^q 447rJ_2אK`XA"dДAN 2|T(0 KS Fx=k$"3K|>V Sjߌ) mDŒ*4W3 KJcAE/2M-g"Du"ft,34zCנ&V3h5L[*%u,Gѡ iptjKEx”SdQQ,X ɽ MZP+mmŠȁLq`QQTZLfK-=ӭIt;LfЩЅTۍV'14jQ'b[ꢙПWmq7uѢw;)Y20$%b фYT1nzGfc GN["}d hE fQCTe@'60:i&%Nmb_-#1vZ]~kg_ֹ~k&[4<( W4maB]g/]&R}H =![;0q<&+.>5PټJ&4Ź.i6CI9L6 G-) _ _@I r@ZґGO),ؙzXg(YJSAY& Ge[_"*xj5RVAS>\z_f϶BO1d1iU鲑VX3)9էiL1UT kD2U*n~`\k@MgN=^MJ$$&T-݂ul7ʋWW&<1j_(Y2s D[( G֡{SO>߹Xeh"ߧxvmaO`Dz)1=PDF[(mMtɈuֵ޵ sEܗa\Tt's~ZWZ,: .=4kT9D(#+m F!+{ ׻y)\>N☎I86'pB2]Tfwl9j0%A@#Cn#AoLz̯qHuy-pZ[cROFxOCWtBƂ| Θ,n(t!-tkp,)DCҨ4ђ4%S&T:|Y!f2j.N<Sb6yZ~ "oS Sc'r87aW fGʩX5⇊N='3E.vUyPLŦo'pvܑCl`Cj7Tʪ湃Esvttg+9oWUe}!^"Zʌ('rR:1)ڠ􃧱cћٻՃ>Zmz}4b 4wA{}Cdo  I" ?4!%>tQ}0w"fֻTih'xZs$Ha{:n Y>Hel^c>I0l j:6;4 pl*g< XItXQOh>PٚZ@=RM;D?h2x-ol)d x,獑@>% G)3)x:>'{pƟ !Դ'=:RQ'BV ʳTO#)t :+R}řm>Љ8&-g|=0Ǥgs%phy%*=+oY ԧOGσq,n1|)РK.>?wyq{=ڟ)Vɓ¾kϮߤW}\{z/AbL^Ӽsc<KK8:n5B *=XDd vg*ZVyIܩFk/KDחњ]E+Qz! seh=%H>x}Xype΢ LL3A#"NL23I "B bFk%n\#eպ[U[ZZʾs_}{W?f~\к sJZG eGMUV@11+J 3T7Ku49ƺLk"OMNX'y2"ʸbLl.*ulE.K"Uȥ3-c'Sѱq36f%DNHJ:8(9zgLxMpIٳlcM#)U.-K:LiT?chM/7' D.N~6-ddvQ1Rl}\YOrq353D85#;!d`d%*fƣŸuf!3ˊr+Rg&qCiuTV;6c>DI}jD=_jN={̩đPSq<5Ig\|%.+GyvƉF[J)KuM<% GBZS+q[˧U9\Utdi=N5u_oq*՝pSgƉ\$(4&gab4:ʔ2̘$5Es Z1gN\-?Ycx8s +q$d:J<ߑEtJs≨xl?)# W?אH,"q@24o*U=o*b$w,/?OgY"E-[EQк4tٰ"lU0lϪ3J) ff3<&2pM4#!֍l6B3-5l騨 3Qȴ5BFV\ +C[}|s$uUwZnZah)[կ30Ұe6lgQ,3ݪH jKUl OkׇMFݰ,oټpE!ư>p%x"bU7bx9ei#oFNVF 6`f$N7* XEĢYqY,p`,1%h9dM^UI8şJ%-"J H _>>U4K*|Vv>}Zُj.6mü84Re:h<(^gYt=R2c}F?2%ar`P!vՂ`xMV1!FRDx‡jL6`콣NJިbT^(M9A+4*DqpA,D iƌQAO1. *S`eлy7ofZ9]F ZVif  )dlZ]4 5|Z8,V>|3iC6+[E`Va %lꆁ#&a xSn/.{F4l=HԬ׬m$B=CoQ&J*j3X Vlq8P=/aC=ת Th.F1%F%. ZcPκrFĦ]4`h8wzdڪqǬ.<C X9)6H >,)ԑ rux4܇ y%З_2~_ɩ֛p0;0abWBXO@.Qؑ_ԣ). .vx']><ͼ`펁NPv'?^]lw!^MX&@{({' NF*pjN*QFk^Ⲣ{(ft, qaJS^lRxz[]`E1J_8HT6;oZC.*x{Z%4be!} ki !ٔWJGLkYmkg6ބVloіMǴ-!ZJm$NlB(ZC.6C'k\.do)mcpGDxbO/I;p;:>R]O$H=`q8&Ilw ٕMѲΨwn ]r&{e<{n 9t>}n5/>y6.H<|{%=˱ؼg}E)%(B+e .4Mro2tLKcxס_1?v,cgL?KeKҎF٘hjKkvI`(;Y p/Ctׯ \KH ̞pNNui)pO'7m)L:R{\IzAw MD&܋Cw6^=Go;!Ξ N%aK|x`$1qbNwMpP{@; `$VTpw=NK2|ەH:q;U]I$&ǜVbCG/{AykTXNN!h\n4<8=“kI3?EK.V:YJuV)wӯ#trApO\qg!]~&6dA3 >3 ,?Ӟ9gC,Z᧳Qv12sysNXo@8 \8?_@٘Aͅ|ԐQ{8zG'7}JxMVkPDIڄ$ͅ]%`1 ^4Q ,r] 1jEF3"x@"D1팍&1Sm1Ig:v:m2}e{{9<9߿Y׹}Bj_U52%8N6L63 }rE6iOYnSa1QQu#Si|r αi9cw1Ť2,Jx6czZm*;qɚn;?{7ɜ^ӷ0t GQ̯R3&X_IgMդn[8M]r>Nf̗IOP*aU NEAzڨ (eLsL֩Ӫcc2]Ҕ0oR] nmW3͠K.x$oNY$6ssR0٠S D'o+q r"W7Ֆj=M ĈDza=k|~1:=Bϛڣ_Z)?<fL.Yt*H X0i\Q>B 'Enr0\۴*7(Hi43y64ޝ3ws\WnlƊl(j m[Zֆ^k UrBZM kl k25M-mp2nUKz45kia_AxlṴ̈̀ 4-:N[ݻiXP<'p3, lq xDE֨MfO>bҞdŖ=o.f60YXm0[Ho{LPPZ9!at3Ө`oK$I(rw&j¡D߶lj6@g/L yZ++QXe*k3Lw*m^=? :/c9wپ|%N, P n)[|:7/oܑ8:"Lr\:M#'GmSF>g%$la|uH'4#˽X.7xmr0=(r"<9hc!=L$<n N4Napgy\JtzoY^y 8'Tp33xI@l db+h3[Ka`r,^ C|KguG޶< LR$7Pz`GP #v]%8|]uv0Y=w3\|(N xX{pTʀ?Le D" w~{{HbPSVN[ֱ368c?JNgj+|}[g`6sk#rI="RL+ZO\p4";~`]x\>!ZVVMcYIJ :)+DS-d4scz\lY/6IWWk@ΤDh EZ$R6AbijaEݦfёzgxUHh\( Z.(Ȑi!iCM,J=iF5/g;5i7T-Nh^T׉BQ2-&ջIZ*TUKYL;&(/Ieˤ\L'eX_e 7&2 OQϑko6g763,Dw7wKZ(^$B|alp"1cpM%!_Ex a<ދk7ƪHMtsx|l]{8AzṞ(8I|nh*ՙ1 ,P0L"zҲ- esM{۶Pݱ<}St?w/=dԿ*׷,Kw5up4ۮ/~(-ͷsXw} I|"FyX(dÅq(-@q߷9!Wr?80U9(rBZ=(V98ahI~~]tHd;ԟCݗ*+ϡG`by{(=Nq o/H]"(F`S(e)N8$6(;*rrI=}x,t\K95L&CNܽ>nyv gLL|n\~ k'WD1nQ1DiGa\:r7޼};OOdBY}@;w?q|.tO-8\fYaW$ᤐO̽a⺅X%cZyXlgdyjǍdt|4#002yx O}K0R]!~5er vZ=:xz3\OE<%ps pI1X(-.)?%u_>?%=,o|auCfXQ#\nW`5W`~bWB'U2X}Sc|Fjp~jFUd[5tredU*nUy*5Y dI洳3)DX& 0Б ,޼ :66Oq UcW gU!*엥s/am&F!d(Bʓo ͝/QLh4RhowYU:y~Չ.El BohQ!R1r.KZ[baksmDcMVqn6]rX3M7&!R{xMoD4c`L0|y[B2ۃ7[QFLؔd 3CozT4*[8S9)IcoTv8(k I;̴U?b{4٢N`Yht Z;z _Hh82eԢv) DcayXBvj[Q[CU-쐴c*nm.*5,0aV]d<ߠ'g6A.W\G3҈s.-}_!yYIQ;5hUAYX_:_:e޾4oةW +)5u E{d91VlռZV:VtsQJdSV"aE=}x QC;E5i"ɲ|~0Sh_kca$Vfz"tHOw{I=Wuh֎:@{h* ]y=%JG,r Zl5M0Չ&38+T4v, bcU"è]g"6 Va%F9z% ;p6dY1.iԱum(F `ه2X|c舸yQ3gpk^Ե̼ϐwS*a$0:z`wPؾ r]jH&:n;uY<dܬ~\g4ojlA70a7ldF*- &+40XPNXfd6lToڟw. kzR 5'[yũ> VL,/[H/u',P)[cc݂hU"h%T֟׹KVqJQEvD }ᩔOv@dOAijOEmg Zdo뛰X5"&+QN_lswQSPɺ;sjV;:|vX CA_僰uܵ6thx%UJ78trE+cB*Cc{V&xUW{P~$ WeW\vD|GZA1nx "ˆ4 JLA$ ڴ4$c҄&}tؚWiL2.&sν)o2YvZ;h m۝ !ԌIQ[W 7 9pC"C hJ$mgFM+pU(L-Lfyd`/ɅyHwE%94-(XI$ i`0q5QDXH @3cMGqJL"U9lu^__ʪ\%hceM?ϬUHn2 OM^"s0LTY}0f:deN?̪b%MwYIT֢ëIM3è臕"77 sH:$$V' 1EYUfI"Zv*jIK +*t&z_Myj簺TB8H cV7&kM%I|[ u V+4P6H`jDaK2|KpPe/U\]ePz]+»RF4VȲS%} 5l  db{oV2 +\ .plIh+6EZ2.O! w-(~'}Eq,dc{)2w'Dhe](5*H/o^jgBi][c+"xTrγHE<*ڈP*T6ctUfx٪G)yWت|QuO&hTʪS*jZ?7U͎EWj)ۼI0놿zio>h`buֻi=U߂>& r34 kx5BV~+F+|o4΄&hiJ5zɦ8Ê 5:[7Pҁ@698&7>te{sK1kCA$0ZN"K1b\^~JH^4k,JA>ћugaS`/}h  3)+J$CxQ$ᵬT6މ5* y~ (&kpch"vQY밴)瑍/PDwκiŘ{hGÊ=Ol'SiOD%&(:5Hkg Q<4lS|y+~+cO ݔ@LTT[z.d0DD/-2mQ[[ކq-kklSu9*,=3t ّ|" Qih׍7-m+A}G`l/NJ^nmFSBŎ)WcXr]Fx8EG#}2}+ƽhi"hpV_ /|QE<'Vg I\䝝2ĘDjS1 o Dwƈ& _Bi} \5,B݊ۤU_쾭? #E f1(ǵgx8[NC.4m F9l [۠?>8ԛ!@5ׅr30i24RIbt%{۱~7 e[ܴυ= 7jdsZ5EC}e58\U[~eF쬪P~Ls""g:JQq"#KaoSup=XB* %u|,x6dqj+(z{hrx xRTPtC8iZ16UC#E=ޚo3Ch3as49aKn:+${nql=EAb /NϣCρ''V^6 "t2qNї}CkO$ޞ*unKkJ(lO*=]@S7fz:RקWb#we|D@I#g÷Xg04gHg;%s_rʐY/}JCn~֗wmg{1gϾF3{l <{8ued^w9Ο!H#4p$C\|OA( tth%EJ)9]4QdRMžPc#{pM9 k(uqh\ZKkK:ME#SO.1!U.$JEWNxX{PTM@LuQ]BQQFX4>+,"Eqa/]F*xh(6Yi&iӚIjڤtҴItN2I킊ao{9ۻ=~ Ei l6R# ť #Xɬ0UzE]Y5WzsEM'i4Kq%VgF p;5~Hga9(ΘBj:QEfb5W+ݣqy f-޺Anbؠd6;ݤ}vI&Zf9q2 >͡&iDWg/G\$$WvTX1GB s&~7467muLrW{!&v$ȳaA>Py`̨MI9Kj|KPҢŇH2\E6@(PX ,TxP5E,"bpč&`Tf$D UvZx 񙼐RXT {ΤYjVY.*VYpAa58ƊZM3YE 'BCM 5\ʝo(E 5XgѺoo  ;  |2zȐ!Al O9etRV_>!" n+r,dJ9wQxS+U_AaLˡ$kX:+N:3;3F8e,N4!b[X痗Q 'fK)+& Qõ  xLFWwl 3Ձ bk=^ԑҙw{5_of* z( zfa9enu{BJf<~&\ W=L,Z@8-ᠫ*Fk\p惭\QEGkq S|-b}>O. ?߮e~҄Y#~V8V%,/dV$&*6$ {Wy=~3Ziܨ*ëYBP~r*Y;m͒$׃?/zUѺ~_L|5tFBXq@=@KOsYo3X3`r8Z)̥6rO~ndc` (#AgUG ֆ&$hih mHp;Ԍ ބQBoǠ)EcYFpKV7eO5L]T-9##Jiu&Xt֮LJ``i['heZmuD)vn!o!XiϹ)9Fu~-FpqQ.Fj(J&ύ4om#l+"2QZ蛂뉽1T|Cfh;)7|b"Hg!q'Pwao*JPc7j #mދK?CP0xJ 24\gw9vo@83ր(RtH!,x˚LTg5#ڍ/5bإ-(6ՒU!>ud{q߽㴇*s@:})#)_*FIb԰ 2LXS~odxoɲ&*[7ui0!Fd+g4yHq#q |͑+7?R<ܑ$={4 u'BAptߊ})(Q(5Ѽ&3NL%qFJR5S=m999?w>d z!Rx־)ڤzd)vNpsWQ _=ee g/ɘuKT؞llyMܼThd2Axyu1qcxN O'2 {nM˞5M/nHb@T85 ߅`j]q}G$C҈HFFAt%ANj*,jZmф>* #V_adK"ҜZmIQIԨTo\֎GpLCޤwQ)@A!*e醷)bhb(j o]RQA͘qD*N{V8xx& G@pF%DHZD5k> ?&尿L>MݑRTLHQP1FWQؓk",_k԰%"ƏϦ' Gqt.a+ǢG!O98ǵ|6Q>J a`guM'VoxcEOf-. ⷟Pp h B1jCH 44h0t <Ӏ Wc_bXzƠئBd6POּT*$ b!)L^68y A Aü/4QIԌu!xӠؒ6V1ΎaTUt!uS84 ub%3CIPaB~(x2J!x~x);4EiAƬ\V7fٌ!oB<2;0tH%;BPȘcR7w]:oi*= tXץ6B!6Qhv9bg2qlrҌDc6*":0'g<11Ad^ Qg9D3\$90Q9x3XxvN%$" Әq!ϝRqgd8.gx]s!Σ<\( bdDeM A~ y7/1 o碂@lk˧vHJĭo):Vފđn@sEQE2j5[ E6ׂ# Xe+nͳKiZd|FWӎΦ(묻y|>9[ RvG.{pԔqVIUie'kF-Nsn%XWmk~=|NznpZ'/G7l%]vas ^d bv1Ԭab.'wU>n㯼sai"Aw}̶Rc1ͷwP+D¦ S se1#zB<2#w!`\_95fWIe䞘5DTۣiE##|5Q_&72Pk0(Txn#ؗΟn"ߵ{Ӣa+Z1Ź1i^3l]M-ܭA0QAwuFVW:t-Q J eI6az͵ ->#ߒGl' 05{P/3N}W]"ۗ[a}hSw".3.LFw,ꑏu^qXNm֯ʍO~]]D*v& eAe$dHsa`ڶ2<˘8+M49(37΂ #LaBoh6Ҙ'A$X]8AҼ- I\FUg+߼GAۃ8[ۓ򷯢RtoI&5 v ޞD) d|w\F\|g~p2J'f}VXgECq'an nw1Q&0I`(=o \H 2YrdT&#wL*qI,5K=ɴNZ!`cDDU'Cah^V`1MPT=/ ϛ>?|>KLa0D/+D\hx$X_t\H*XNo,&jo#b xzݞ|ۏ j}E!<:A o膏j͈ oQα?O~&E"P_N`h0~=6Ձ}yzoդ?Px S}8?u_Ƥp<wjZ$sn.zsU.!t7,P{/~M?߻ =x}X{PWP2 bg% (Q㋞M$DP"FE5>j+X[[wov2ۂuo٭{oUwzܭ99}go2'2Msql>RZٲ\˴تa.it@0/KAhc!gVƛQO{/Z;!b F^S[(zz/{LEUA4gNU]^x,J0P1 _9=vS?!ӛF́);GWOSN3LSө~Ho^y?b_v 8|K>h ~ςuNiNl2CNѼ ZgS<Aΰpb^C{J=[7"vh5"M7!+g23Xlm:#!k<_DE@}dLQܴV ]y!@܀,!kz7{FYohV昽>6BwFD3o W4դZMA~6\2[qIFJGf*HE31`ԏp(/-)BvH_S 9W տj;:r^t&Ok iއg^/}-J0zteMږh687pȵvqs);z94BG|4LM {Se$;Βv| ;!=AOsz؞fFh+ ҷF121k -6D-,j  T R!^POf3֛`n2"莤d5A_RST7q _s fsIy* wYp/0X$OL~MaC:dcdcTx|ɅKd;(רXzj6 Zɰfi^a&m훶)A1 (n&XW̍97ⷼdOu[4 qH\C2ZBoUó"-IpUtlfgb֙PeK]o&햱\"ߺatFёQ1M10h3. zK5HBWCf`˒q`CMٺqLh2ǓL`-_:0\?Q'%CG[0 ;mWSY?3 PG{˫Z`+Ɔ- Õp[evxFYE=JW;^^9'B8 tͶ~y Q J R4^= XNu,l# Դ0Q=ٮmHޞiʶmFYiEWPZ/aP1;vhh8ͤA þhJBk.b]ւdbiokh,yd <s_C-'INn\R`fW ||CHa}c~0fhђٞhҸb9fi&PZf1<µҿܗa 9>JZ';.c 2N܅=z45+%dKgˮ+ fL((&K /H{HGc^'Z$Em ,T#fbEtmq#˂޽NXz0}ptoC6ܳPpXz YP]ÛYW66 EdbLkX1`g5%^xJIH+."!;'8ըMh@8| StٌAoiFqM:A%Q ԅ[ah|ma$Ud'U&Z+3Fh Y=IFҖG!HLM\|Vl=ѥkZ !vE4 ʂ8Q~a)$PӨؿ]HDKOXAU;ܭf.Fb@/Ph{¥{ih[I'r?z? 'Ԡ=؊>{?+C|FD`f!㾇:Lr?oH~T^p41511ΑY$TqFMO2&'OOpTUXJ5K#jË  |x|ity <8Wcp%q )ABJj4zG= @YD$;eɌ"DzlRc˺B)*$#8zy9ݗYgf0$ꫯ Պ/zœ;nUXUqAx#â)*;YsRWOf2)kj(CrZRM.IܰJIL5ԇœtF}1 P,#e6 F9QgS33ǧC}E$(l)) Nոl4US$pEYJ9E\hr9I"TUZWBY>.ĪƂwkyӦ(q9]^˜"&wZ4R3OKuO STω~c:'?(o.)#!o,N*eI gJKy[Lj-rK =;f,ȎA|oZZӠр"gefUMoMF>3%n1 ~xtPϸƝ@ဵEIh:e*y5-ÌsK$i߳[B\J]ʼnH卼[rkz@f8?pݩTӦhVǘu~gaMɜdRjۧg0.uidI-ZAZp)4ElOHͼhRu5`zHrG##9%%I9U#o)ue&rNi4Fi$?+ ]EQpݽ+{Tꛙ¾+sR HhYܿ(47scifIZ )4)x/v5rn҃%j_ڞѬt-#px`)ՓSl|E}zjO-FD͉8\ۙd:jvf~ h{r^is&s 㬦g"Bs@3aq`$=]_: Y0v;Ut ?!x#j}FG&HOB},e}:NA3 k/{{ty^NۻV8Lh{7zJ֞>YkƥEIwW+Xc&TEV=y蜚G)ڂҏ'e@ݠc/W%@ȍNOu+3p}$8:nbŁ8dQ )ȔA!AMnlqkN>^&3vJ V 4e5% w4 ~tj~"]̝zcHH}\B.U.Ig)ҥO%w~D.q',O p\.hIOJ*HQ[6.' 3w>ׇ/vr"TIHMԒD3d&+ -0J >[N 9)DG'#v4/`PtuXQxiUTQ0Z@ogx#Y} SO&KB& :7:2!!.%Zk̊Gc1䶡ЄŀSt \2N+3 'tc5OY@dδa֚`%ǘcW7x 1r6VNB{q#@ly2psvG ~lyMDyN4+L9Nm!RaY,^[%nje5o%1 aX8%3CTڕt 6qyfeIz ZLXuǴ0m+}J;)r$ePᘫ0O+ qvXBko?Px7y\דMZq Eġd<M~xhkSaaB=4>R.D+ ahQ`:]X#`qx_7%tYR,+ ex1mJ.h^hed-i3o2Ѽu\[tAևV 4(Ɏjp@sh]Z:=m _i%_ 2`^NDO>poOzJZ;őIRFb Z┟1 H xojq2CVt]1\5&|;tw 6yt̨%3mx`J^tĚvA4x~=r&x{Ɔ\I*yELK &ȟ1r[0RQwsMXgCgtuBb`Qf,^oNr)7;k]ՅpOw9@ F@,geӖ9D!dɛKqDeAT'&/u܄Wj y:x+ON),UQ+H!K* MOHSҘNc?m;>]/c(DUHcM%R޸֋T7 mq],wSAjU{@,$%vל,\d'cѐ@.S(lVr-#|4)QWs/g4$[(EH$LM}qNCf-Oj_[0bgs1`+@]%+!4$#G  ̔\eӄ@|'Wv*ABh:ɆpP kM18[2={N;gELgE8$/f;4XA:xVHrOTty `v==sRoӺ2,JN4W@ 8T!' osEk}B"ͷ6VxC=ג- bիs` >` ^I1 MME1{.[EOw5E%9덃'@iZ1-g!]>%r_$Xs,އi Zenu 8Îzfj y@#Avg#3ݝE.șc!y普b[$ax`'g0VRxO/Y ȫݓ,-@;/k(k/ OdItvMz8Hj` 䯕Pbu< ,$1 (zT願 #{ԁY|Z~eeh/u6Xfo12BzNo͋;by#bA01 SJ-<5pSײ9R u&ΡGfne*-G[|D\9PKԸ:ބRăM0o8=LJGZOݰ#+דkߟ,6 m~o롅.q0HӠv@|R!W3ǯ9n?Uu Уյ >$^j 6Ke,L.rXBk9OoH{=8Xu>$9v= aN{y$AZ*B6Ӧ.~rN @~X_>";o$D r|½K? {>PBƄ"c/ A!*\GIR{ 3s#==8po^)?24?.w8z-O-[rr{󯝯#gq8׽YMfx^ SSUM橳G05U~C}-1/m-ESBsD3K YoS"ܴK CG\x!H#x͍ "粕ɇ O~63vɣ;@<sⲢ;G3CkH;G @;*F΋{}oe{ʀvz憁2wfLxP^[fr,%rm24-4X `#|ƸD{^Y`c4H oy@$ ieB *5'GkfUz7dz ?1dE G1f=3|s$ut 8~SZR Qhۇ渧&JmX9FVa>J#w2/.:!f"T@3YkY{:|@EH<-/0! VD5cEv%}ܾ.PD!!>3vzݢrߔܢ{ KWsdv=$O7UԴ_l>޴I-s%u*pT|M Q~A:15;+B>~7*,9W4a#UDux[]7 > s!>GbG>z:c6m 2|=swBkk!Ve`l[߻ak [0ba&b 4v1],vp5Bhly5B=]4Ց?co; "&tŦ!?R$ۨmȕ[( 7g fBsmgK%e \e+I'jHS<@5&ܞqPȡf!釸 :hi<2 q=cL 0Pl51@=ѐ*%gq{5jSam3sj/$7[9ީ€D`XF<|;6axnrUIU)&+6yLpt7UNT,.uىX,N ·>"%s}m\5G=%1䅗sEl0`ύoV4k?ߜ6--h4 _~S ўsk瘃fgU;_ N|HEO%F_ĩ'Xm#O7Nvpâe<׾ FGxGÔdw sW p X~b:fUL ?0e4[RN bq\{m@^lS+c;NPbqPKܮ6M!6Mg=Dhs吕<{y +6W;b !RE]Wgc>#ZuEQr0`NS.B%>NG/tX#2vLpZf+(1D>zv̋{^جD) $"] ,ĒD^1Dg)bca~޶X3"(37g0JE%RW]!ȨjJ Pi 9]e$1-f ]4+xpj?2 w8j G}1ȳ寱{u#Yjh5 R:|,_ל+pNQW:j.>d%,8|Y34NzYإ'ʓg4|Ocd@h`%AĄ>Fwct & q~a6OrsGqHԫl\1Or n'gֺn4SFES 60'{_kf_11~qD@6+LE"#_i+vU%[^'iZ&q6ZZRn{y8FjvkJGbQZ6繞5&X+sδ1lɏkM7eyjraKɖ׻Zf^:}? #u|<8g% eؓuN׾(F_mMY):~cPLӗ 7fT!m{NB 7K=T*o"o޺pǢUI\^aoeD98M,A6{{6ZL`b0V_ 0ocu5ق1zr϶7wLa)lsz ;aݕ7VdH13_ m@tC׉9SdB/oa8H|wU9 (g`=/^x u i\׌L7zoztaWN$_}=~TDOp} P\ qQ_h]So|k=#*oI7b|.)H>^E7'6 7t&|fc)5ږ (Ֆ1#6W{K˻wﳐ$^VA 4p Oβ䝽 mhU$9+$b05uE%P~:[S8ðXȆ Gl,bw{fs"I(Ȫ'$kvR仝ealt0BV[4MKOg:9t3gEbd= WS-sf(F" u8.lRL Dk}{m+5lft JZo2aa#v,ɲڵo!ޯ_^粂qпb%p<}Z>We-e<mdV/8EÿׂUwk(E䯔?CYw+7 +IʍayS!8ӢPr;+(cSq#*X+%1*/ X g#G0b?)Ѣo>6F_fUM DUB3HW<8QQXxd}Z1ޞ˒Ý]h2< ;dT$Xa c$~"mR$#NŔqcB9oFs*5 sS7$ke=&M; I5dWC$4jتIoaۮ11sQ2|IPL&Rf,wWq ^^'ft~#FptDkD[?esgԱ Y)&PL q3d+7@rC2sEqpgulLfa" ܨj{k٘>e-׏i !l`$D)E{X0=EoˊG[1h.vwe`"qqe0XxΈ–ru=*'w7|ؑPx.mo}rVvijFH[hiR#TIuc8j'[ȳVGP-ެԞ֔ |,R+hero o4:x|7[$K3 uу.j8 pb7Ѵ2?8bjdHtW c(t`ɢsA߸K-.6e '>gWN^{M#j:m FW ;_%ִre) |ρ /xGDP ([MZlh cVXYxt&"f6?uŽ%Va/@|L6tOW h}A;E7,NjaGՖ>x][un}*n5np_s, vUvNm]qhz.Vp_}r2sE$z_ -DU%ȹ1q*?}kA9_ҿE93kG3b X*n!(\nrWQmEPJJZ`` 10J[S (UntXU +_˗X<횏l;f[YڍپJûu VmG'o#XgPZC XĠvi7XC@c46gVHj.J߅*v':- bfMɃ4`)@@~ (9HiJe;2&_k7vF0rjB:LMjw[6y(kP=%&{k]-ڀDAYJNP,x T >ދ3͉ўĻ%@=>zxb.ܦFx(b\;Uʛ7r䭫MClR#q֏ @)'qIFz2*85Y@Cho~hnstZж2EͷMXnd!\RiiHԵ %1Uڤq؉DhF +EKBQ",AmޯUBc9v5Oş˨!2;Vwl%,Ѽ+oex\ԏn@o*@;к?n]zX9pr=3v}efAӑrgY0:teYt9zeh:;e;weec5j&5W=>,|UG5, t->?|:!5tdXyNٜ&xM.@$JYmTRT㤑 _85W=8"M#GaFefZn wrMIq͠15hפIAkpR.PrMfx\8vbز!ʀPiX39li)U䒀J4_"^I+tӀp1YYjaٜl)\6Zn. 35Tkԡ/ʓZ;{.fS~1 }WQ# Fbږ+M؀a<'V"L ><'A^&Ӕ\+µЬ@KG͓Ţ/ p< 6Ox.:y1#'zp3B{{i"cQxOH"y.;` -Ze,*)5`]ڤk7LHؗ8}/ݬ UisLz5CWO^>#]Z6qX?9=O5ŒӶaMQYz$d.T1ڨr.*[LeĂǃ A_~SćJ 1γ/1}ɮ2>8'~6MCSF=e5BgU18E Xpٕh5y`5HĐE --h-2Je8:il!zr?6ӾLav!δ}\HV-4{B@"v`-F0(HA-ā#jN U3Ɩק\~Xi=Z] }8V25>ΪJ#N2L>0d`jȴśf-xwq8}Dj 䩔s:tJ= Z4JMite'y7Qn39jBXa 'OEq5%`L2h/It2p*r3bR[29LB:Ɵy Sq6}oST}%]2ibi;g:F!bw)_R(?̮6 55 OL5>nxaS.8_Wc882 sejxyvu!z%S$K '詻irPĞrdEW5~[g,_I/ub?zxMWyPW F9TĠdTE1h4"$d7ƪI%WlId*[IvCgtz{l~UKaǗ/))--/[PmY^_ۭRk,tU Sҕ/ JBC%P"ɶǢYvtPs.6=K}~$Z۷eml _kHw{ *ޙ[7}/`M8.  ve% y u$C%Ւ)h`ݴ<.#tHiPЀ"֨n@p`@dwMgC:KJ:XO>6h1ٙ/2/B-7 ٢ nQ]DX&EbYgzr/ Ƽ(8{!nt" #;,T2%6BTPfh DRš1t.l&.-Y~"N.fH^9˙UٙB4F`x,cEFCmSud&t9qiʂu%.tlP±±2FMI ^ {QkmInˠ-ѩ!RcV ˦>!݋[;x&6ˡ̸\t2\h&BJB%{ҏ%؞P$ .:j<EC$HEG' F6mxOP&وȼ٦Bd?M"DT4M8@ރLΎ4jb:dg:QTY/R$9K}€F`(ED;K P);rHk AS\2}*9&4OfU-M(x ]))OfI*1}\$FË- oS YB44"gP(4%gPiAxrFd XM) i$bf# &;2L*\FQӬH[iW|M[,gz2qGz [UÄ!SI.eDұV_2ӱ0CQ' FE̍0?*_ #-YȱW+3V w;~vy$ҳӘKС}DN(-AKJ26q)CsN:s +w,5+7-7'/ C°hԔG&G1~9Y_1 Q@n4uۡSVՔS{i#Ʉ]QL&ڦykhz}X"j!ݜxCvdd"EVr@Op#A`*4?+~NԱ&J8'th\8my8fzV=GW0#7Dԡճ ^߅v G{95~4iJ$ǛVnĤӣޚ`eGkm㡳{lvd<v: էQV4_GP{ д^*uWꅦRPӆ}B3z-QףMQTQ(mtpڣReA6sݦjWˆMM`J;Fg9:{:upJiQٹ7iAݞիsEIQԚݯbצ')͍; `T3Ӎ;Êq'To2 @a9z;N?7tP$Nߦeo,ƷQ"ؘ7(:wͅ܈Quߝe`\>q,||I`,OZ.rޮ37yq̦tjν64uW{})x ]^.^7 {w}vktڰMA]zA.LK5 %~lFmnJmg$h;ڛH7=r$ϗrn=xR!*`~8Xsxw#?NALD,?s04L!j*<#:6n6jM| mnu[-7rz<>:P`g։<(qNf~d@=Yƅ0o_I*oq,x;3w۳^du;g=FQY'rHnlg1mxx2< N4y-(ϧEg{G, //ج(b&^LS~,|~qw\+,\DǓaH5gȿe E%tHA{$S[&[?;²'&̾ ?_=MP󻗅.{%8]{ק8=z}nLp `QB uYu~s>[KAn:| hh|{1]O'nC6U*>'id`4 Ec`rl3=M霄h;w.uۿBxZ{peI͒$2A ~tw @ <i&-3ݡ{&| *Ɂu]QVWpD>K]w몷ZX{nn|3y@2uIw9wɉ=v3ܫ蕄cX:琴j*qЫ+qlԽ9榪VK*F805<ƦmPxUVTf "a)Rz$DԪ6UՐ@L5%:jV-ViW6H݈5D7^շros4a*ѪzÌY5D?Zn.q^k+tRVKؙsm몖j:5۔֣Z;]7ܲ߹"naU(.DQB*4.%ŕ8QBq|'t\W#8!%JL$x"|P8 >?l}1Y8!Of'\.1yz$#\X{LpLbfu(/gJwP>ț g]sq{|elsQ?:>?|4{tW.+\<CU-8jtpZ2W9tK24+!o$8;6~{ϱC!B^%ɏʋ%G%$烥sJI|~ v9\@&&&\AW“R2<99na#lʊ3l${Ug AmDA@CD6-2pN,Di4kج$߈XIK_J2TfhVfr K'\%Bkgh۬X 3i n [1^oEF^ySlZAwwdV$:J*~}2;HTb6pr^j:JV'G@CJ ],ޥ)=?FdةƵ6QEALkf$(HX`T M'n!Cߪ*!UT+٠bm֨FPqr) J&i갺mҀ]EP+7ڍ1{/&[M#Fv sQi*xd^@EO4,mQ!|Z&=zq8rԑ-hZs4IZZlSc%A͗=>|-g<>,Y7Z{|N}V1qm s/x0mI(5CK,_f7McZ$Ƃjl9xdv)BW= Bݺٚ<,*ԭ;/>>j"LUvkzpc=pƜ7g0ӻʆ@Q#fgeҭdwꀩFQM;&9ۇ%`󺦇 TCq8u#B^lhpib5x{܂ oW<"-Y}ώ)wě%%[&#e 4jK117w?F#,-f<*67[TJGpCAd4̈6d`IٟpI8v}hst<*j勇",6zF.P/@`Ӷ-p'²xR !,KO.(5PTU7awV+51VJ̠-ufXI:ɥS `F,c!5(E¡S֒ۦy(D5ע?sa tV5%$P ]tRpL?{gxDJ[-RTE@Ùrxth=0- [<)v ùfexq6I~Bvx ]^=u>Uܧ(]3'\]^z78_>jG*#KW;rc`I|w'M36|i: 3=O*wlp35h;ԃ<<e~:#Ћ>젩^䇫bwbh0թ 30a&T%5=gqÇz=*zvRmA;~xvn*~8f<#÷}0AA_2۪DJF|(M|v<\VH B,0*GF6SzHY/b}XN^<fNo{.ۅbQ}S}vD VB|[C 7F1~.?ȽKxR/7O-/7yj~|Wj;;+.-{ԍM T?10 1pEdWC~E' $nG!C06>v4n2t>n4n2YtIwlI ?ЯgR4S೾lh^PKI'c=ičH>r42~ Jj>Z@C(57[w]ؿV֍x2/>S&L[9 r,\z^;<6|8|v8KOWCV7} ^s0uXXs2<|RT:Oq/?}I܎:Ls|5$_ NɅKh7_ c!W#. "Ȑ # )' %켓+dQ nm.ۇbg^Y uc) ?ȩ3Vg!~fs:au8{f+OD<;Of sU ^JZ`f0)q2;NʩԄrrS)B}^<{ 5>Y 깇QsFoAS(,|5]peكx@9Ȫz;s~`XV oՀ< }q.,CWo/fî8ף>3.YgZr6|{ɏcUkpr=e%۶a3V^6ƶ>R8=F5ft_iT jL-QyB2ӡh9榼]7t؉޴QAD@Ǣ41աCF4:cZXMQ?yO#yӋ=cZpdd 此]<ʵMcxLW߁AvbM& 焢&44mW>^Tx'/d=t{RsV^4$)h`X!uQW5{ der(s nQ#@ a q\UZT[Eu)# Lxˉot1 2:cyS&Q;]@CUntF=L*162EU8LD3Yhb? >G{bm%=j XIl0=MLĬ;}y [Wpp!U'%<򊡇|}>`L! ^F7x(½c=59W# TVAF)i.n?8ыfh[kpΑBmS'' D6$Xm+Ej*G̣ aQ?^h YɽɴZaVKѼۉ9m <3# EE_L~D@JGXM&?^ǩ'.~:鯉O 'dD6{ {&GR{ ! Jhb\n.^BGu8J$<Z !҃bd669|eŁ8~N5|I̶ĺ_Yჱ(}m{%7$>oNLDMq53K fTD7Sy5L(z?)&B\3{MfyRFn,ʔ j4s]t;O%tqK}n/d77p'x۰5 ~.:T=sтcjzMף9ͥLfP/Ǩc=R;RӬ =zm;d%'n$&(|M'8L$*tg"5l zwtQsX2cDGMBK"fK\^***lʘċWc7-IapXdN+Q]%ĖT+ߜ& Y~o!&+< 3==p 蜾~LD,G 8p&+v-IazIsz }?A%ĖkFfVAjB#p9n)8]Kg1TjN Xv )['˾#fr%0`&FCxLK96DG~>|=?N {Rܜ^]c> rb9Q&筍 3NxJp`+ _A`[LWGGPX+7ѱ+ԁO.)I)~Q Q xB'\LU?D( a׾$J"w&c'd>/Å Y & pAy~i?:kP !!mDeL-D5EO^_oI%ҬpAcnQיf|Øi\k찐fQ8 `Uܹ go<{8D Cv[r-;ܦfe[IVUj0Hlf:iŰa{CZ'lsZ U!7~{ VPEi&WVFgv?j=4J7=*.spuҨvnDhP܆s ' s613i$p6n>RMoi.;ftaQL m+A*f8L*$(,os]Q}8)n}_dK"o!;p34rC\dMr}ODt_&g;9dK-ۋό' -XR} 3!o)S<,=Yƙ^Ym6fQfE6Jr"0?a!h^ J5juzݠΔX?X\c>c+7TE%c=\(żr 9ema]ѻKf 2aѸ ێ9Q&cf1=!l8 (tfD'蠓fb>y\ r׊=,$8JJzDFb_ʲ,EȼАU׼j.<_oXX<1GW%6'oP&7 7v;\݌)6eMLӈm\nƉ9zՔ)ZmZJ^}!ތ49xuWyPU)A }QyȢ, Q܍r4}T(jӦMcejL$ҤqfDC4M}ϴ4s|;Wѝ6چʪ5ꊧj/k*ezfyOkx>>i(I6)ɎIz%3mkSd>)Fzg`'|ܧyd{V'4c(䉩Xa,MEw+XػVD2F1}n_u}ЕQj˴_0MoG#$2(%l05V*L>'JE5JtH"7H%:}ؿO4/%JIŤ;#}!۴,bV;DBoC34`С͔j%[.^Ӂm0TCP17r3NKe-C$&J69`ΡxʮA6h7PM mzp=35Iu"NFdݍɅtnӴ9x()!Dq[cKnфQ8v&Aqd:YqK!MZ( M21iBR40Lh'LB +҈2?X- z/y xS!M#%DZ鵤4oXm=-9ǿ|U֨"Ңϓ/m>I(9n-J?'T; _>& /UŠp~\>A#,I1k   EoHpM5I/ ޣSFH~06PGS҅bjJp)dxdk B5$8::ORH3F1=WJ9"\ )ô|H&b]{ O=E5Ah( Z- G,+;Ƹx3>m/{L^V;ԟ&HPǃ==1B7hߏYXA$LJ(7c/8юߔ s͜gN<"eN6wdPEV1gPxNe>ripN3ޙS $؏X!Fw'9frs3uk C1y$ORK% <⋼ aʤBM,Tz!f⻛Ш,/w.ҡs-ebe5]P(2}U P_ pŪbT}X_%B3ju)G!f S[{:ƸvRZ]zv_[;uxݫ҅_X!U4.ZT^?G]tZߐ';IKkʛ7Ֆ7TUjiaqx*Va8aSti[dvĺ 5@92(dls+ pi3 H >P6jI!9='&dZ&3O6RcﻣMqf=ÈmѸH>#"PוhPIN- CIeYس'ɀE`0%)ڴhų i=c;Aݡ+H5(*}Zzt:R-#tu@AXΖBӃْD̚zd@u( # [r""Eƒhm3~M_4XFRX[)C~(FޡVqZ׏ y֍zmhfq7lXf}9hȿrwV޲y4z59n(V))ßJz@u[vo)[Ci<#jۑ<&7(G}GgqYvwGRԱsfьc=z}X:s9ܔk49iA{Dqr&W$~r"&d5CSŐ6#`gZȰss֝ QdRæL|iFΫ]y~&ك/$.En^tRCh?Tzʀ.C }]ba}MMC/.-M:p-R km}=7 U)/{)Kܿܕ=*DӐInk'svIaW Rjj 'W+&Y&:mV iлfSվd<E^^t*\iѾ6M@"lީ7&Eod%(?V5r$x}itTB "!aL^Uo_IHCl@[`2 LfLL@D+ / GGmOk{N{ʑjvIy}~wo0]'sP‡AkrPsy%K bQ*[sqx&XsU;g~O=*Gٗ9(MI66z'5EPS-Adx6ȦpQuݜM"UqEuz}!{+J#"M:xT1*2L VttEwjz|}b3ʍF<3 m-Dπ/F^茮~:<?&KQJp=ṸcDRM:c)![`u-Nc)}ĨGĨ͠>6V՟Ȳz sA!:M/KeA_OWA=>9cE 12֍#4AţdnIkl3 /y}0vbJQeTUtU;gwx]GV +JMa"&%a_ӈ|D]"Dd^fӣ s >6Md r [X`7e' LR8,M4ufI!Vɵ & (evՌB4g,Z2)GfM.CzU zJA:nbIeItcN%2^FL))f€_>S>M.DD٢獄h/M(d,'s) 4G HTl'j=L`ev)'Q7"D`#j<93~0 +\0?@ciIX^1I!<ǗYUvn9GLID>gEiΈ3%Įr`Ҷ␍•U$i0qu3#a#ߵڏv@Uy2\5Tmg l8+XT3*/¦5KcDNP=VvMCc[kȂLShc9BdAku+.o;p>yYC:Y `g36М*dž0,?]E o2kxAVVM;~%x&V' ?5ijkk=n>4x}>W`$%ϵkq֫*ivw*|Xw9mM9G& Sag݌ẑFÏbaaN4 NBȫC"9)G-:]1t[ɈX3o/0 ._O9bzD8qXg pz^yX]qs%1PG-zk39IO*`>o`zpTf0KJft.To@/޽ tYr{"A;2X.jmy y)+;Qф{u~|ywn>cٝCccStI矶0Gv? `=i -y& qӓt7E${g@t o#Ԡ;gH s'F0)yȽ7BBM{Tn &w3v3 fdp/Qߞ!}u߿Ho!I9o߻nd735ҒA\ }epmO"2AO[{Qz,rsߡU<ɒz{)P­CK2 ZCɏ ,pvxM߰#/92>GW] !~a\XՐ_Xc*'/%Mvvd:~*NъOv畖yhbp dFAɥ7'spk©|*T#T©e( ^mJ?&>|x=V{P~K4b}Yͣ&5w&D|A]$>P|U jP<ڂ$ 31I;vL536Ii3ɤM{swK5]j@2W@.0 -eMV*ۄR)]V}ȄYCC\/ UԹyZR"FeIN%-Ҝp% (HȖaS`cb e0<鎤>#M[!.ZRaUz$#ɂ)_2!hH#ǛKb$hOg ~B/F0IjddBr SCs,TOq&S||GFzU76ᅙZdyվU 7XnxXO?s0xqL(fO3FUcLd 9?43f1f:ýT֤L1 dυ6g܀>2+#HeP Xn ",ICT0si R]\HfV)Eov038B_yl!?W̋8UWȢ7&QS|F?US-}nsQ|X-T.NaI6fYq+) EoJ`*^b43}&["sKaʟTVOQ!k$W1UEL^4l/VT1_"܆ _ dCo!*˷(\[m& xMU5k|Y0_680 * +3a; CE^:,'`9`y5jqhI4[q`+WNԖ2ń+2?+ ^:1uղfW_3J|pUxoHN!۶Ac C)+ Rwd$8YUn.UݩȺC'өy Y(S]#sLס4G$obnygQ=/‰Plc+!XV0|vb6v cByzaga*[NNUճp|2aBep&TEϚ벊ui- #I&DK*Jo}֭gʺgi݋v;jW(N"1dnC$b7$FQE*DZ =nsDNC=Ha&4YJtA<*6"RcHڂ--:!LzC.Öڴm l#dxMMESeCv%7+NwAh=;Jk>vd`Qٴ.\5j$Ҡ#EH"IюIQJ!$6nP=x89nY`- M2]\QDrWD(xk6 #E{o(rcS_H vbwPX` /HE:I#khQ&Cg^"^_{<3n _L|g.=m~c BLρܲUh}]X]B__a66J=S1͆-WKpW8s O;z7MBYBØwhjUt3nL_%{ߝzᓏ 1IF%Lp ?ɤsDxWklMhdC^ . \3RC 0`1㝻wg636S-P!JREj?VUhZ)JZ!UU+EU[VQsgfcwF~yUV);c 1L^+s3m19O &*PIG{]RIKDa4Z#FH3iã&-f|Q)-;E$Ga3Z/&XO *lHƢp~A="v%i)Pӱ7ǘoίuP+kM3˳(9iqmeee֙EKmUquA0L:n[/m_ nOR=]VǥR/2~Om' XLi{PMm=hp2h,қF _$ {||Qdx#ITI ,;WxHj3|-&2y n!sܼG϶Fޠy#y-M Uq"CR3Y ESKz~NNǏO$VEdcW§7wolYb2Xl)t& x?'Sk@N&N:ZۿOIAEOc3O#3gd D +3(?e' tُ6g?H+]+n_DFH/DY$ѣH=^ƾtP @PíBD@ޛla:sUMVhĹT ŭ0~9Rp5"^>&,Րxw%;A0<S]R;3H!KRBRZH RHECʅq4'_AJG-RDTtZI+a-{mҰ2̄\v>,ŗ%n洙rw7|8:C =E/WV7s"n/dW1C:Q{Ȝxbr:Iq1 i,x|{|ZpU()\!`t\| "w.\/6’K)ܥ/[ݽ⟗#:{Cxvzxu ܀m_zbڪ+XX0 $q{u6YFWDe_!pH8D(+$LH.3l{w껪hV<|M:n Ϸ>C+mk_O,/?kcB"iN߂"'/[8||~uQ;UxG!W>QE^\jU=TOY ^;˫ըxvk޹b~dqzmZφ dQ:Zv\sqL])u?#[騕!,&7F (nYfx3r}\eq]ȇ,h+cz xwgiHR,挈0wm8=9\VRE?_'e6~[gO!OL0Y.~'jwjit ?Q/]P%]rt=Ӌt߼"Y?{شlƉZ5Hof a!,ѱfZv(>4yK"ϝJv?$UL8bxUWypUݰ%ll_K xwHH^1 % !$BHd1$$EE b@vqZGvkj+Upb#v\U5j댺U(W,Z*N#AvP${z7.\ dp!{ RYAY.~9hKSygLg4x1rۓ"$!I9t%naװlTv4l&x- tL?ҋaj!Aqe\X1BN'FTJ^SӠ#+judNK^K9j u:5ޥoPP4mtʎLN@ӭ^I^٢nt;!\@\ ]\C#mSҘKP(j1~IeJ PI{7&EJ-akUF u 7Kh,,Hcͱ.7IנYRpIFdEJ[w~k;Fͦ1Qi8A7ݠ2܈$ˤۣ#wn8}3>2||yo7$RPL=| Zx{gj[ LsS+4B_lJjf)a ceB$u16^y ܳNM>[!8q$?,& a.NL̇]C:@+H/0tR)%R$[(F$r CY>p:7&)abRsHdNFR"GwGǹdzrPL'yUMqV4z>޻[.O%Ŵ?SJ$/S0`(2ȳ/F%ip7RCŴTΘ(o+Tޜ^,4ȖjXRw<_K6u\Gܝ߼$Z?GF>IN' l1k ^3:9h"AkSc{ڊ-n'ixԭЦ`džMhx˗UͦkHj%S/҇Gtuǩ4=fg^P˟OvGt6o(X_#\p ?)d{ƃ5.t8~4fʢkbSh:WM(U<;ɐu*].@iJ8Y,d"J ŦƲv [ϧV4]dT0S]v~(ݦA j]p~a)3kH^ʉzfJ|#;9(S鷏0j/.\-^.P.%po+++_ij5^(2WpzvVB gjrrX4v%PLi umBҌHRHɨEKlhRbl;Co/Rm%\XJ%] LCVa#$ X3`? _|)GտϠ;${5<)I$q ط/Nr4p1t P(s"i*ވB>95a4IM4u8&/7P(Hf7Hs)[Rne& k t:6E;u 0&lnQS`T}G`3tхe `\qHqGR UkW MPQOuy}>[[hE7,cT~䯼.Fcc 7~GjS#,7oKOl)P Ji3 EUm9 b2&#@ѵ.jdTn/@$s tˌ ΩQwxčxMs`z׶rmxάayZ\'ej:CѴH@]h]Oe )<6MZ߻U[o;Α;Ch˓ $M7`wlT)gwf39]8Ҧ=fý`\sȃq )*a~W05I-sr ӄ=M&Uw0g%DOө+ &3¥;֌[T[jU7[ps`BaV& ӻ{Ty3_8b0zBTl<]3yJ[O>?pEԺ?R ̻g#7'8A8$a9:[%Nw6ThpdD;-WspUZnPіi͡TfKjrkru/n_.QLE[|)XdR)f_GNcg.8\­ËR>;lϖ?LGDх#YGyh $Myh &|H;ϥYQ߷ A "Fz*N7J=!`!*tx*J#rD3/:. Rld̠<0iY<@ p2 S  ~V6L`xJdkHGTLɊCKRՑ0Il$}@jJ!훰M;r Ѭ;uЙL ޖJQe\Odfs^MT)Xԡ9}2eڨ:SL5EXd…̫T 6I {2I7f*q<2Dgf&LCvS3T`TrO&K 9N\顊 {OP3C@53p~| ]ꔳ ]a(u: Sy(e8׀RЃ7PPzh A0AT0`~Al?| B҂&*j1SH̊#NxݺV}D`:3Y׬u(t5!n ˰Hba!T`NjH1Q9J!Vz2Mޔ"*jl31N>DIafi3rŴFKgʔ[sʀ \\NaHeM0M9wfUQIaRW -/w@bRCQ UGU GՠJ:E6t*Vr+&g΃q.Kl O*\sCzR!jx[:?NOlҁω`[m ظÕae&*sR${Y"܋d)8v?$ n\)\E+1͆T¬̒jo~IODic՛+by5%E_Klҷ&X$"erYECsN1-YR̻+E#ڷJ}1&uWV+L<8>Zܜ4\ =̨MMEv `WUTKO/Bw jv U3Vk6Dg;1yZHZ)DS.x}Z^mwm9\mgN;O:5%NwK,vĺw2Ժ: eZT?ćRHk&EDE"l9p,WC`n§(3gq D# ¥)쒳>Iq2B44업9+HFD0BP!p7 [6*lIs˅x"7@Fsl0yxY0A}-ڗ5?]fE8 \(Do\3!1˱72} $3Nj 0|nV"T>PIs`sQwLvlnم,CwN  _~|}JXr) 8[N PX|UPv5("s2 ٘ &ܱ1+ZzfcI!H2kAњ\Q#Zȏvl?ȩlv YTEs0jA<>ֱޖBcsܱ-P-`tw-cf1r@z(4/vP-pT lUC3=s&ež;BzC }|SGOM, W{+>罢h>neؒ-fA39 4or7h0Ȯ@9_`Jq,|< EV;(­5T4pi&2sf+!@Y@^ ՗ oXKd$=!Z67n\1*^I6 6e"$yG"I?ěRG2d2!H-JԵՙ~ .dn0Ї3g1&4 `ayYo;ɳzdK%e=w3tXHqfcTk(X `š(}` ?a;8 `>4n&09W";h b+D I Öp̑Q C3xEHLA#Yy+#ׁ!Yc{a xJd4>E,6ՠ@itZ=ۖA$WQe'q3!q)<IKY}陑[  h KtУllgad8R^Piq ^y,4'q{DHlnpJc \v:*2Iwj `ʗbK-&,# ue=Y>O}5P{ sa%v r^P}b\ 5 fN+O)R}]xd@T/ؙǛ#?.]˧*rQ=8\TxhR+[2D}#stJ("5cp85*Oj({;-1fdtĊJIK*̜Jȧ}p"n6rנ(+~t@ ѭhQ/֫~ %#gP"{%BL x? ˱ᒫNG`ܑs%۱HX>M7'+Mļn]˩+y q{OvYL. ƇH Ѐ x;}Zh  $u }Dco`%ApOfQ@T 3p[f\h>L3D!OXonJ6dj; E4rL9l^g2MoY#1~_Dߏ/\FRUYȆ7(짢WS7^^q~b4!$Q#ٜ; ~=}֥ٙߛ%@ cV鈗KvMG$%Q BCf<s:؈۷l݆lx"G̤0C{@%Yu:|q rV>!Oe7X )θk=AɅod;vak^+a!TSMZ{8१sY>3d+bSs͗^L -KMSJ:-Fq(T[kCD(gԦ'B]uA= b>:UJX`Qgq(D OVG1X }Mw3+X( 1EmjZ6cag솊Aק QI i*.(Q]A_cG;~)-$9cᨔҢqfadzX*!%Щn$ Lf]Ş<-JƝnF1I%Y9}̪j]8eUe9]N /GO-m\=OSpBue3? +JD=Wnj0nM{ZI ]_J#^ \R NSljMsW}tT#@r}z<`ftoWӂuSb' ІkjxuGtfģ߮~]2&0碙= V ׸[A\ [K<ɰ~ZR;rey`"f`ۧM׼67x ouד|u͕;|2!D^[isBcV2*qT\\:fFUc>ZdW'! - WYܚف2BL#}CO8ttv,@ !^ B=`:=?ί;iEo㣱X9ߪ/Iar4G"3X%,_]P7W/!;o*}͕΅¤]sK(L9iؚAa]U&ZK|֊yvکO6ѯdD_^uq]U4'ܰAu\"m&Wq4gޖV`-űYsoݾ]yơzX8 B1ë)1WѴ·@A2ם;u7 Qm@FU΁Qg1mw5[觛=zYZF 9Nܺ4:EJ.Wq(@/;w|| f>_J{>k@B|8#8b[(xU$M.N tGO(%r䧩c pa~V!)|(dMJ9XoKy^\XW_ wwcXPX@ߣAoalUC?wwvb_#F!MKtM5 cBu( a-߀1Iypw/ Re¼hBcL2CEHYc;I槧3'KcD8RMD;Ncl9C0Lߊ$1fu/"@ЖBad+4○RRb74~xp ejfl/ږ U4,ȭ?bB&Jً(嚮qR9KHk! rQF4wjw\P sW}-8YsYܪgW0WG! #1yQI~ I`V)ae2^`hg)P9`ib]gO i)aQ'K{Gv›p?@Q/?PO|GExw=q({DVd$[ZTwbSIRiE {g"?u%a_nh6>ɴmvCX箄be_=kK$ȠxuPr;3>X_ wF {tYtZ[j&E+~q5`%'b)җQ3A#mz:zKekyfq8?Ci7s ZHhW [}=ܿ= Hi@ozxx fX>_NHO0ldVA@ܢj! =F m8FLY_fTf S+cۃ!;2m^y{8^؞bpܹ.[[')=|aui'jN}C?CDWy{U˾t\6=:Yb99DT~Rbt";lװ1%%!R@[Aέ֡ꏈls?q'wAlܛ..zWzs/8s҅Ovdq'ܥP|@lpٶjʔhy{%@;%+& O՗aу劣 =ݰ/kY{ڱ g9^b&V]\?-fA6ax] Xن1Ɍ2Z ۃx.)aGv\\/JP9 LoAhs՜xUc( 2_0=u&``}czA'mҺ~$ j F(H$$aKTrGfq#0cLBghD]><<u7FE'Rf")p6©A ^3c-NB#Q wnҸ^E|8gn 뚊l-f?FıքM({Ӽ(#"[UlJ-̛,7C2tu+h~og5o6Y<ؑ.$KxAE5;y )/ݳ4^pBoetD5ڻyZ:C([%y4on:_iro4syU,>}lu"|xf .KCRSW8ފC=m_P8"+3'XS #- JDͺ =4W7+G5%8^ͅg?|]_b44r|fTpo߁Q @[ ~t*׷ ~QF/xUL bY<: + '/q ~Z OG|il,rzʥ`vf&ىNx}!kkRAU%b`c.\uK| /:eЏ2s6i?_uj!Sm:x[m!)}pJ:b8RN(trjt]G-pV D#!;QY{nf}%ۤ29 ?wˌ& ]ǃ,3"L"z55_<æyۀoMVzpf>2h7G&ryx>xPI$kûd]ˣz>l_REթTћj y|Prq~g.lZF蔮06u~n7ӕy|gvc=3?$Fg#2Cz -qͧse5oxe5Lq"yA~?{xMUYLWΜs VkS^&̙93W*".z1.,)˯DmM5U^Zח|si d>; U%j* $2ɂ%)v(J8w^*sZB`Kvw1e{nxlY0[$Þ:7KK_ ϲTvbвG1?47ދքh-SLtSKАRt@=iٳW}"l?XhQunrKRaIIw2M3TC+ur$D.+/M-@bZdZ">oJ~J֌!Iмar23:FC5m^j%Aw3[wfWQRŜ *[:r"íUsjX0['.mci$RUJ9%K^VNUCX~:a:0_A4qU Y\&zZ[VEh [TMMK B!Jpm [%:x}"&LSD_be{E6!'D3/4`E. n9}h G%0^( TC$1K1 H}"UB ǻHTwA[ZAΞayF)RTwU)PPs8t-XZρxDu&Ր@Io :L?głf3YSXg1}D*UECf1!|o *a & %P}j׾ d@~?BZ2A-.C m10ʰ-yPNU`so]B PZ= C=bhB'Bi%ҫ áCy Iq&A[S$±zShB:QPFߛ!!Žap<9C-EG_ ztd1 ֘@ 4ㇴx6TO Uzr'Dv ΝnNq 2;S׈|fMz2Vg6bڋΞy߶"bENpؑEgbvgT|"Ä9~}iPvKp,=Od/}&ʚ=xMtQ^\7.ㄡLΡd1 '֪@`9NTˀ3f .엎$Ԍ=F'fnA:^)dΎ?ȏl2i%}cQ@3tF +)W+d:@\x5ILTYsMQ;2HU9tXH<`D{A5^ji!1ґ)բqNs+7*.4hWm^w?罜/R͇p-j[uݤr&>8yB8E Ի;$rH1n:a9KW.cd݋f o}̢E| dQi.D\m{&Q iAn(,S3 ]+tϾIg"jn Gh- E?qEwo\N+]CR(DwIRW+wBWl`?NtsUb Wee xЇ縪zSm\'&2{)F<@ f"px;YtՕGe˻lYRjIn-VI-Բe[rk \2YBX yY L ,` #F0% g 399ںݖ9{ngEᕻx۝x^%kK? ڧerׁH2)"Rפ˚s).s,2(%*ZI㔸$"etQ+xPT 6 q%E-b\MqAH%~A^҂ed`x.Ȳ0/.p-_G/ +#e]UAӅy ͆,7JLg4.%j ]inAA$qIC{L%R$E͉c^(y-Ĥhf倒$jD(>iBͨeQIL2"&_'e%{Kv.hZ&Y6bGy$>pENʜ $nwP匜ܸԵ4B?5}zis"8YӸUpv6u{젢 5PyNTz 7p~W)p|o@gDz~!s"'+&D*fTLE`s dr6/+;# =ó6-^;9j'/ʙ,V{ꢋ.(L滪kfVY2O޵6+&9 8 .tsm/Q b&D2#U1^,m'.ͤm;@I@H,<2B"JБWGӊSŘyj}=kS[g'E!*DcO AܟF;qiUdFUC{X7eW1V3:MȟK +q]b״5 Ϋ3O/AU4',t1wUO6QrrḦ`l-&8 @Apxs.! ,<`_3H $ Paw$Xxͭ%$ʔ1^P?^¹#"w'˦ld,3 k'sEi`Rd9~\FWA7 56Up3h:&0Knl\ɦӼj. B^SG.l1 mlv$VдeĶi'nrj#)`nɠ`~ z[n>R;/7' {;!HBn:o1ARzMJrxmsx\>TFk0暈ܘ,Z֭fJZ73Rtv4 ('3qZxޱ s0(ލX3“{Qd) r%Ե]:+|voV6i& z< mΦ* 3dz/}M#9|(>axgܰsSӢ!Otz8C 6%)~v8I_7"!kc{ptkoyE߆rVAgWK< eД5C$5?zE"]0X09|"!h d[V;W((v-RPeǡ[U&T`sݢww:"Wj \:8NRfEm\?Ctؐ%t^ny>$2p_ƲC,\н.N5τNׁqTEr揃-eQH@ On@ĕz;00tdaH"-AT:Ր®4 D]xr*@>a C} p1gd.!hT2|_>͘0o(R9L{P#aQ~ egz]%$ E2J±.١F>1zgq: a#O<* ;2/Jwx|_[3`QdE=?޺ H̩ }FP14'yzn6Kc ޓ1MŤg%?A).Hxڵ MlvN i7?]#K\U f@`47RvLܑ&,8{ȱm 'ێ/ӽ[#M?*HgU %@G8dl~S*&LJƨf:: kK2;VL8v( VcnC$0Cs 1isQKݹ5<1 ohP&=k= `)B6y8ea/1NЮݻ?OC.B-]GĥSû=N:fi jW*Y)=ZH|d;9>r^wԁ{+q1 .(= ^.<(ԃ)*=J+Xf$t۶>#r#S$2@nqRGgF2@DIŚBtضՃ [cvp5a ,;c3|:H&gNQӘxY290OOmɃ <#@-%`)mER/g oh^I/'JNO^ ܼQ.&k +j;Ń-!cS%!%>W.LZ2β5Kv%Vڒ!_d/D;PY ,]0x@Uɮ$* 傚%YEcQ/_6!Tt`ڥ{z^saݲQe``1@]u6mE`wD>ÕUv+LȳZ6 v&oltjDi@QMh PLhui|8?2B4䴸`)FQF`jl+1p tXbjUInho8澐FIVpE9 tv}'0Lp٩̂˴kVU2A|8K. ;Ґ[RAa:ɰ[>$3R =}x,o?7ơEHα(X!sV%&'"\Ԏnp,dۘ*'BC >E33{љ*CWyd& j/ndxoƶ'ÑBq؃rA߳Un=J\wQoz5C O^>4=UGEL3 @MMkl΍7EpPeC"W)p# } y2tDVs8Yq@do]$GIq缼 &J? 22ZfPl,R;SrZspM+YtcXIN ؜n[ow]z_Wڬ>B0:Cgl _p iW u<#YQp5vG`vymx8x5sZ_R*ΣfkfX2M~/itӾ5{2.LS堀/>Cڪhni ̻w< '`x:v{.9g&c6ffQ\mR Ŕ3J@VM&p{X8@>8>F/<RupR;h.ų鼲 @ 'Б̕-9®]&>38^⺪5WNlo\k:prhyy9}$K^hQ,&m(f]KGB£<#=bF"3C&RHkZ&%8`C"\mYV#J>b[κ~#|J,6Z{]W&5J7h9NXb\.s;W:[tG*?VfWkB\䛟.t*r;lu phtsÕQ>;xUff$QqEAu<[: FF N}cpn+5b;I0HLFOwtTR˼"{Y0i~QWaOLn-ŀIɝ;* pz{ `\_9e2ΨZ93s8Qpg`"'->&ägtÒ'5P5;na6UB8s{]MXCf.,d8>GR_-%_i2j NkKތϨORy#7{#i`r,:32aFk'0c$es2D>Z2yɬ2x!w{Mɴl4D |NPzQ&UT#8XaV| KlEOC`lFG}JH }V5)<;Ԁ]欚I3V[? |vz?I~˕=2BLnN!|LeF?+t=dŽ$imdEl1֢W"2oc/4l<-řX!XĿV$a]8WFfr$Vɾc <.VKê&J#R;@n֎-θ+;*@P0aO>v?\T 75M3dF~6 ۻ9q5@e p}i 쎶Pg<X=m em)abdy&>RG>zzlP Շ-V^$Fō4Yp=hTI{9o#qRݺVjw[W(칀^K:PrGoXXSG/h˳f+,"T%b#{c<%/J&7=+PfAɇ=&FTQ7/RQ:X{ރ[ 'ハ桋<1mDtBU#'ƉR2b5:n䉩 4FcVEe f5pzɩ)ٌr!>|E$MOՔ jwdz:r%FC$DCOV6Nq@VK77;iH !d$pRYO6L9y]APb'F\-O^q~xQ3X rmE?\_g1 {RZԚWvڇ=sY h _[sN;'?iƢf{"ka +S^!)ֲ39 ҙ C}R+yag2Ʀj}6Sec żMΆQY;GAQ=aʛ3^#wܴl505B~\vN+H %g/@ǾF-ߏ=='ի_+VoX1اtO)ĥz \6,e(re1σ .Iaѻl ٩4+GTgBn[8d5x#FA .w8:ͮR p$cSGIԬMbn3Oavɞ+-JCvR)|`BHџz&jDUox}d7z&p}P{zɱ_UmHӋ׀ .9ff0MO!|2+nBdfea0/< سߌZ'u1_;OB;@GA&u"X Ŏ}c.}#xk-y[Vm+=䪷[*,ǁ&s0vKe%7qCX;ܟܑ4t!@$!8d=4v=2&Яʫh.oX7k-" $2R)P2o Ko},E<`o|^, .&+ᣌ2tuT(ݠ V ZK`7E\`f(Iٿ1ĥ$cXitӅ!r7Ũ*8PTc81%YS]= s_4ֆ^{(MOtyQ,@вdӃ7#PYjŵG%x< TTG%(߅lҼn@t h\P#\b̘5LIEYQPQ6iPpc3?$3g239r[~ u֭W?w>ca6),j0`cNqNh`MWƻ.,SN5JB}XmǎG3Ȩ ֣EI5a|5cMYs kǚαfĚYSkjAX}>bo샶cԲ^|~͚+Xet1beM:5WX 2̙1iw.DƧ_&`g=. {V~Vub:J4sQ#cb0+kZ,yw5Fa.BY4~ylg7fY h<"(f*0`u_PnZX0ڛ+mUwx.3߾ `3K%2omU+dJ.+B8MnA‘ cClsokbWɌn2YsN@13ٮއk(3^gxh9mdՁi+'dmk\'6t}Fv;7cFZfT JO2$e bQߋ^1J`,qz N~J0$9(S9WT<`ܟ( `,-a%-g!jX%2 b߼m> 4lf{%89O$zM',H 40F N&Et"8].l.$)m'eSռ3I4,܌ 5BA0i~VkI8<^+o qp2吂bUҥ.x4$t,Ȏe԰J1 8WB >4kzbmu{a{h vef_}FDԉLH1=;*0dC57Đ}NO@_EdDIaj# R2Te/|!DO,!zQ73QyIZ%1F[}cq'0$ZᓂtѳThTN ;H:g3DWEy FI4&;, s/ђ}W('7PJa0nj"xQޑGpV^ChS, ݶb3h5āM75Z )>iTo&:acb2NB1V#GȈm7/e$n`Wb0{G@\H?)qqެ#]PܒXni-ZE<ۉj[{5 ,l8!v O!IǨtN5 I$/)`]N OXҽK:٩-,CUjOr6)f!cUI8/R.Y>j:_LN%6zP⩦.KR=©2+}~wLSS"' Z4a* ݢ ϖi!DA/(bp2܋I\ǻj֛BGmW@y昏ƮSfmzBi= FC ^RfP(/p?:Ţ=W1;r6r6\7/ʖa:L 7Mxǎ(x~^H1r1OLNP$Y2U2{ըfmU\@ã ]%!T`@;!$[F¾A=Q.M$!0haM`L؝Z,1, j;ǵ. X/Zu*B3^|6 Dq&y8 [x^QPJ83Y sIgEqFՋ7WGI!őZ,л~㦣`k08 4B ./tOhL|Ӂ{BO?27-p'BpX_mi$$yٳ!>r7A=^#6R_!COGzOc?m!3v|lC?\E iA}=j S}j~VN6*>^&L j3OO³CR0ƙh+]OfO>!YrP Ep:dܧǏwlq#ȡ OOr@A-hUFY+ C{)%4 ^f*z;Vd0@T͔{Ra[N}}HR>hb闂#'Ѳ#3w{+](!M' r{ίCTŤzdԓK2&)PK `wacГT9Ԧc`= J/G>ޟoj=`o' #m3mz! (Gl04rO8N<;?ʦ[%^L1mt)٪?)PT-L{nj%|CN>w 9@+÷xvg< H5D,$7>[th*&ez Q}RS((}(r)oAi>(Jr9x[k\s,rCh*~L&$N5]y~[z%4D?c4^V.Mn1K] dO0Ө13LqXQ9Ԉo Q$MV胉 DQ@ xgc@%\;eC-5!~C+ >#^Z%pؽ0HAAϻ#^kӠ5bB\Ӥ҄rz̠ Ȅ 5~O*n3{3C "8xTٛgkGޣTѴTä&"$$P1aU*lMfr=2ӧUl`#y'odVVtEoCK(x86߲s`g 1r|ի@[KfD4(_.C+$grc|܁ֿ2ٷ {!#$\ƒQ/?7>|4rg~ Do@7EbˀUݳyS5@ ܝRf!=0&@ʐo[΋롔H0!zxI A0^u nw$MIx$!uwlէmׯ{滑o-' ;EfϻdC|<>OhB֒œCD(Է*԰$;ԾI[F4zӊ2'xK#!_{#)H,s pPXj1J+j7EU>H~"UC,IT j fܯCͣ$֝f㓹_ؽrg)OcQ_8/F76PE!s]QhgYGA0^4&A9=cih+5#o@R!#3vrٟHG.}9ij?QQџM>Lh`Hb&# +q,wFІ~돶vam!H? ۈXw_-`Ǧ,~t@n @H_̌]E7w&FnwޒRfﳆωt*۩A):T3xk:E,C,:$U"1cEvK>hb G*vwF-MN 3mŢWTht nAyQE+>T "4{:EL'/ 9d?Y×-ZK;^/kX,6 Ox;ipՙ%/lKcZ#ɖ,Kh436˒%[I6!fZv[3Cw` !&#/gaHlKH61[,H 9j6,n-ja'_R]|d;̿gY8SAQĽ(-TEh?1UU(잼9ykV>{TJqQ, uzI7u$&GObY/Ď*ۡ$Au]MFTI?6.ͫk@Q"BB@EMIEu%D~oKHB 1"丬)9}Fe2XCsKJTҙ4wS'.T  >*F$%]7 p~9;1o$9ZإB0ZyzȈɅuCDEU`Gb" ; 4_햔:AL`Q0T]IrMt*o5FH(_x(31EݝҨ3l 4#qVɉiEىMnfҚE>8H6lv18=A}i{v}%?,vFl)g-]ҙPC&x>Yh-{ qDD#f@ysgVl`|B\&c\}aNJN 4sֶ[6d"éKMHJOO4H'$wwAXLH7 ;6TF&H z,A0m+eaGa2`ȊS49**ͷ/ KuYRr&n.E$N)u| %e<\2PRpR9P*rѤ&ψ:>2W8ݲhH$@PkP@P ǫnOsa7Tl[न(p:_>誛6^B%ݚ*`N]M4*UN@MDY^uOTp9l7W].fjj.\R !h ]vtH騟be0uY׏K;̣M>SX0eM2 =ۂ:RCm_~82"iQNpV {sZZPǭ.w:!ZBRLq>U0=}J#I-jИMn LKt]+TH.$+LX r ξ& 3aMLeo(IO;Uh暆R 2^^:sY0b˄ r\ݹjUj#vjUG_NҎGԽ0tZZ g_w !^, L붦T7 `76vw\D6 IBi-^mY9D еESx[FcOnȰ%kb3Sn7ev6҇x 5_LD.!{F!d5}DTd{g`S9l ]l0:%DxoJ/p 2/~ƬWiZ(TVeԺ] 5f mJ V%;2XW!B>˜?τ;4V"fb j^Ũ *qLq01>pxWyA R3쪜Kq fr\LwW*):mwWR}c[]]>W>.tN\狽l.HWIP񀚄Adw,WOˮZOl險1kةkVwN4vmya(JI1t9}ƥC廓kAj`gK ɨWS pӴp^û!K' O;,޷)+r[6{c9,q]k=h=lv I+%X"$ͺnRsbD$Y.`VrB̔f> S 5 l ̵8T^}yYg-;-3q)/؂'d"b;!a-q!O{e@whNI8!߁"mYǘ>)r܌ȑL ?Bv^h'dubƷuIo:%(V-$qcsO+l*T2YQՄ1]_4x!/mU5i :irNyo gi/9:8~!t 셙ao6dehvN EJ辨,m`=]5"Jq7ղI2gx"Jn_-znJ5!@} wR] HLP74sL/k,8Tt ~X6g-q1q5 ȓUU3 {|OEz&zFgg8|P gsXI\q%e'Si0 g'DQ~~7xVNɴ}_t@o6Ca6B~Pu MCAdN@_g ݇=UA? &z-~ qzl 73K9]4黝@ώ^>LLhKv z_*;ōKMjJz`z۶t!qjx)SkpU{J?Ӹ<6`nϴ t^fhX#ˎUʾyØA mNnE閁^𪖂d"&+D^Y 1A?= bLj\TGGc] '`  BKGO>xg4 n Q־EmL?r[Unj)᳥weʻJeUyw_$NXH//~ `p Ow ή~a8XD1g]oOG|@ PW%e~"I\Bz;|m[k򖦩H9\o[ 햩h@Z Dka{fSTۃœ$)؝b7:9w*gpαOoe|93Ҹ;&z-"#7'|DFE9?a ȗ<>\ ;]Rtoq yԺ%Dtg6K- [2Bxe_X+ Y]@$կ1X rJON6ɶd}AvKz)8%Яt^ {8>QU1;.bGh$ K91~6FK9Ú+>d[kgEl2N )bH|}~U]tR6GӼ&.49d7۸"H|}AV|N0~g+ub:TPgҝ7UFoBP- $MJ- *LT0D29]¾wXޑ)T{۽VUq4a){\(NT\"W)i+x.n4&}wvd{Y!* p_';؍O C9dŃ}9ʹE| GQƄbVx6<_9@Ǫ؇nX7KV{:3vH2Bl5̀o(|K8aW>#7,7\ؗGoF?}< H/Ǔ᳷+4̌O[e=nyw%31cRL&-&;NlfZTϼ-qak5;T%ߨHZ Z*3b眉rֿO%u{>~v.1/icffh&[~WXHƠs)!u..<ܕf8왎9fevu,{Db|>ٕӁeO)h:xڻ*Fmz}H'*X8qTkX Q"&^h}(x1?]{ 0 zyyٸW%>,8f FeB.#T/6.f@sul%LTdP4[/6I. Ȓ!mgڙC4,zd'ij 3!8h֩4?zj]N BI%M_d92}%Ncyڢm(#aɃr_h1QMٵI5ԅ~@բEm lÏKQ}L :XA)| NP! ğJf?K@~ݜ `a[gŎ>} 94x9ՑyAOkjC ѻn"l(9p,qLS5'8^Cާ&#!(`a } 4՞9WμjV NmԹOڸsG9Y|HqnC=jU4tBZf,&ŮS!& )\nٚJksy}"66J齚 fraX-ܮ攽S}%;7w%:q!ym(Ev&qɭ!mUt8"+t^{s5X u{xM~()g~(&2Q Kh^{6vH3:FDs8a%LO-Ycb33b7W4x?# ^`lS)ݠGf<!y Zrig9 rm$8W~|6Fٝo3B,'vU`ryKom`~*v%Z~og7]_gx~a vê}v3ox=~qɇ83Ԑ# شgyw^V?bv+3T~URP4nC`VfSB\Y5*A`w[#=F:w !DX'T_e;~UUU`+|_X[m޾;xAߦP{སYH(c2Tf~82x'E!gj4P' %f# w~{Xo2o5.vV]5p'Cx@:__!eh{/-0sN_xK }0%hj n^q tw5 &n')xmVkpU(3M$$0${.!QP1vf:df#d*_X DŽtYXbDWGrWK,-˭_gf;{=93?~KD/%C< "=Jg pJU40K0faW z[d'̒v,>w_KAOՋ;e9Y?PaP'lC5ֻK_1v|!6ӵtUa {aj WƬUd߁TVO hFDa1‹I#_<+ƒ-%I")I wodׁ#Tj"-z5`)?l% 彖@k mV<k(9҅?υ),u_Z ;wELϭlׇ+0\z~3zԍ4w F0<,]XEpVtx3ucvȮs8_?4<8Y0s;xŞFrn Mǻ m00qmHUæY04YI| Cttc摭~bTjH4EǑr &D52L,'$, k,#2N`N  iN"e]/Me4Awth1|4]{±^>v NR?^t(Ve9>UiWs|?nyً׉&Uti>rqY~> '6Dٓ NT1sZp^,O-^ 'T-J܉%@ZoO/w*343-A>!žnN;3= 30Y94,ƪL3df _0Y13L5e݂uE] HP w#R`nEK (Ix\YU]slpn"zb6ot,zG0^QKB4m0֨ ]֐LmM&MYC;cF@5ea SWVzp_x66[CxM[lUs.&[ؔn}\̙c$ ܲ.4RM[#6`V>C..;emQ_&o胉$!?1ef~ߜ|\˯wjDp (G }y #uѮ1u5d*,Ӥ_wjw#:^Mz)}IqAXqS"].2*03LPD,B(G:Ņ壅S/?[Fu'V Hsc_|kʼ-Q&W2YnkN?4t7N Xj5XS׾e͜bs ({fܥU?:/i v cx0`v~Cv#iogp?)q'یKB8U+)p)h)m/>==aŕQ?R$҅ݴ-dÓ^OU6;j1I*v)mSIݔgP&CN?No̙$S1y΄{mw q o Ԁlopv _f6SAEx5S[LeM8$`B ?Q@Ƕ!\4@9P:R,1L,C'^wc<%.Bghbny=V<]wtt ]5!d'$^zDsQ/SQ}d=_~c?ߩna؏J\a+q ? 3$Q3-__ bK:oQ4LTԓ!JA T5\ܐH :|+pa9{ ɨ \6Pn?eӡL")p#Pqg+ Hv`=XLՁ*A[44it+NiA@よ=\ adlJ)(U5Tko'\4Urׅ`-~ j={>a ^1B,Z[u"2f)|30=_KR,@^xfO99+.n{f߅S_VHœ.r@:FuG0ԄLt/eⅸF@% zoU3n_~S#uS}d&C]˩v RmHZ ]Aӄ8,uvn%`_2W[kxzHRoBx>M86DZ1Xݵz%ZXR_o!{F xl4M,gh훍4drjٸe?ʊ<%ΪE)('V\v,j^4HyȊ4'͟kT5LV"M[6&'4%40MqH%$p/y6ɜ(yY^x /Y bs^OK`u|&crƘZԇgiq8|gy|^7?MBCMAEYTɪj(֫ ʛ?t1H[ ӹ>#[Y$/o0?~VP傿$CldKB]6DIWӶʋΑp,Qf?.n.op9M;Z5[qgO@S0H@*3w#n&rb#ߑ,# hokR;%z,E0QT˃%ccuާEY͟FUҺ~SV,i%BlGTe9ı6ɨIe2mXlVoL͓:n2jEiSKwŧ_1믏rR1I@ٛ^Tu- ))V ʪ6BY#4Ҕ;8*V!j[lJMY,ՔY+$8_̲7O>EHV`arZVdNYf6 gʆ!y&0 ˯3l'YRLPd3/eP'"o_r:eI;e䰓AQid߳`qMΓ"8Dox?r{ͧC'oI3G%?NMTM`A>69giҏviQM&Yd[I9%Irq1pF8۷k}ݥpf;6QVI*yGrYVy@#љtTuQ$%}vȧ!,g&zCcX$O"ӀEk[&)&Ǫlf^LLvQY|!ž`[)|@ؠmM0m nQjUJq?#hs|mRmb>S-Wɿ{y5ܝ4nͿ|wo\߿/~'u;$t&t$;zu_o?BcѯKa{pui'_ *;4߉L~;SrgIUHT@:''Gsi?@`Q15q DmŎTԴ12g?Uu?oizȦ&TMjN.^yFݿ ,=~Ϥ1|BA+$կ7^Cj4ӚO$QkTq0MgƧ >h!sb!N}> ˆM1W7?qVK7ZuYyHPDO(!f(&S4/N_rmoIŐX&DyVbj :AC)D:7|[-*cGxu u&:EdׅpW˄[r_>VQ>GŘqp :+ ȉ&y?}@tl0( 3UxLAYl6 /Tng:jŋEx ER?qs5Q6*hQ>REݻ]#iZm0x6Y/Udx%%D?.$҅ZT&6ɲ#  +Xoazs[ɐd+R^~5DH'ON %̹tϧ#8iI"{fmq3"wfK=uA֣^E' ;'g0?X\1gLNv5ыt`HҎ/pqPK_Q%5\y`FV^[{?k9 4f0;"nZ D pLeXeMŻWceG]0J}^I/K$v"ϡ̠\=yD|HH~=1ּ$,W=`s]dA:bV0O8ALe}11;H6n=Vi (Fhx 1,;cϘZւeTso4 #: |d@Fsm[^+^Sɝ|ܻJsص 4K>¯ψZQ0!;{ ?Tr%!٫T'ܜ?9:?82\E6I>^i^aZhRJeLFlQR?w6U~͒P"鈼$8O R*vw;Ir6$] SDbZ6 >0O(pXK[ ĖʍcF?AgUl|:i(K;~wTIL$$0\֘"6'b| >[5 bEn E7y]muۢO7R{%['FtTC{zg"}ݣ|G{~ۆz# bi:xQ Io "J"=¦qiO`́##Qk2:l8}5aK?ҜA|@Dm`>h&PlfuI-S_of9TgisO+qQzfUj#\нk$yOaezʳj\ٯ5J/Śd"זTGXvI%—nB1i,.v9o6j_܆NqLo#y z#2EMH*,cr\Hk2 9zl-micTa/8iTEc 阀H&,>( tF`Ţ&ș{g^;"kUA麓P`3[B@po2Œg(c k-l{L~Cg'WW4mRՋ MLnq6OZҋHz=FWkBfYkEm;vOA)^WвIJ(n S dbs HRl?6N($yxuVBdgHki񝄀㛊d}liL@C=6&O1\ZvWVz XJQQ>^O@>A9ZP'R3eBIuRzx+CӒM:8+ZC9#*gJd H86(~P7ZxrS] &!ᶌ Naz.~^e>%a#p1j6$H>۔%&Q}&Zak`~JϬ?r-6£ezX>pvS'wYsc"iћR$D:RM`߭!;7=tOl+ҴKzUn7*:#?RhQ+*bΪ9 T=7[˻>D=IXa!v itM}d;! @٭x|C]1E ,( Dz[Z],0L\''y4g]wħ%Gk< y0{W*騤.+,wi[zH!Mpk;EtU$ ʉzH! ]er\~ONk]`e4fȠL]|`O × ,&C[7u1݁2 BQuvm·rMZXCapȈ!B*Gz3aat"OaHϝ'b4DWgex83še9&5c`^1/CLmSRII:WzhA;:Ft0Q)5S-Is;;jUL}yB1VWQ;φmhG T[F@M!xSl3NC.P 0!r>_ݽCuu -&4 ƿ:>#u? yE6xR+-4kA%m4CiQCAwuq5 1A:䔨`y}l */)wiEx>xuݱtl:K!ZK<;Y.ۖb9VQ9_'>=ŻSRtgЌB/ R l@Z%(oS~NwBjB83OZF6IdɄ\uﰴ,f 8\'Ax'Ziv0:#`\ʸߑ!tS':,uPc /6ֳؔ*hW %͍Pe@Cqw+ ے " jNuz  v4C[]9Z-bHNhpPj3n^8d #ZaZ2 b3%= سGxm xᙝh7s zaz_:hZb-:(M=M0hT+pa41vX#0Xjٲ)i2t>J89#V#e[+;o'}JbKt8Z<3gLh(4#Z~S|J"y)p1]Q5mouP\[8:֨k/;r>.u(7Y趟14Q_ijo5qm4-,`:p0 Iy,,r8P fsAEbs{'ixeL&4%h~Vǃ2diĮ TB ` 6RFA/U &s_og6NEkO?t4-Lb1҇R5,P\[?9"A8N)Tߘҁ[N ;լøxAHJ{5V;̄F #1!:ֵjK >)a\SrMhmb˔c9oyVm NB ꜄OmnbpEIC}kT>y ޮF:$͟~BZ])adm>,gm)%q\vm!ѮDž--w= p?pP?[]4R1dvnA~׈i-PK#^Fq$_ Bli /Nq C6=hk-~G3[5hGnd?(tRѿ4 $I20`4…e1zY!7jUVTrk{è..O#Nd!V # D f/IxDة}|eov\ñ9چYgDwص-v:7PY9+2Ϩ,b=LI,%TN9嬻RPC\ǵ ɒS)ЭEhN3+.g⼥~0#EJGW?WpCD@ aRl{TV,fGYt\b)>v3bCN^s>Y=<QO(g?b[2=r|tFNc ῡ"Tf㑚pKz)1 y:Z/(["쒴U&;orl+FG Tc(lv$Mu-83[;);FbT[Ri7_d)%"] %W;"J\ 6IxB: | ('Xig QfpbKK7?c{ ^+ wW}Y ,&, nV|RDx.\}H+!3jj w7R(=KQ~r$b%鉺iSd?vXm<)!;ܪypAxT 3ag2$% _#>ss\9o%?^gs*Wظcŵ,JQӒ,v{Z XATu(׿/ u4tV d~/7;%e1tsnDP&̾4j،P=3>V=$ zJ&ϵ7/6 Ͻ[=f%_L%ֺpd->[(W LzKxaW3kXS,q_V|jы keq"db"Ϭ YkeJтHQq{&w[e:"Ϛ v,ТWf^nSm (~0>U6+y1kOLn v90NSL5Ob=ƃX;k<]h/_~{2X?n QʶCzVommq-TS s/xْ0ft661eñ@q;D7fI/ O!'tD>pVK>x6蓤DoŗaW:Mp;7-forƮ:W=NI pU(zWD= r^7 *[HЃ{+䥂kL:`1l^ȹt55Em}=7N.M-Ӟe GԢ.?}#WQu3Sd| w% <IH1&{ibMЅN[΂8'B pCwBU) KX*Q$jBT\ NE*Bdgeg֫w[HZ8d(`y.֞ W|Yp9VM[W&\=#&2!lʒxᖰ21 uT4V6-"jh ;`3?An>s_bj/WרE- ^`BZa3)X9̴L"5`(jQvf#1=roHW"̕԰Sk/|XsE>ÂGiF_vp\j.n?^9X*|' ?Cg{qnQbz9Y/icǯP5 ^N.kVrZa.:t*JbxuTOHagUH,{/ &z*`-g7 !V8kR|tRqGHt"iuGlM|v7tMB9=(:XmbvR7.e mg^М807_ە0`m}uR\z z8衲rV5[4Wد N}(Y;AcBJ/J,MR~WGhWb['[]Gh_aǓd*d cregister nickname","K;cidPef~EYBfxVM$cP2hKq6Rqnjh3=2ouEefDɭ*FE3B dt+n?YYأʈƹ~>a3[WϞ?#v#RCשcj,\f8[}lZdd&2.myALWbe4hOĉOg"8[$qnPdFH=pQAZd=2LV.3L뿾!;‘-ȶ8*2I.4p+PA\l6I Xj%['wO/[ ij) TW-2 V(tmH<QEbQK>o 7 筍&_/ LM;5hh$ETCZwS+vB6TXJ`#FXqK3Pؖg&wR`|%Et!d+S T"w =O}0&!MZX'-r ѡaJA)XK :[C]}T8AO)ٚh [s<͂;֭Dlbmr _1^zź:3'7_Ӹ¼LYw[ߑngW[ -#{x#n̜\|ĉ]_gq{r?'+M V3'tρG9%s)(t Ót/ʨϬDO]qC6T.Bùĵ[*%}< vgk(`?WBN.ך H?J'JSڳf)rt90^y%k_fXvZxwjIӭ\F @A@u=w(l-%3G^t1s)n0=1L{զHFrЀJxkJk 0\PWf6FıAg}ƵMw~ebN0o>ʘ!ظ˚9*HCUAm:|gAI$xA:?ydʌ.( 9 c˰ ˨*ԗYF]\~R*ӬFDyT@x~3޿jׅs…s<]EY`j*dYw݄؊BXYbNA!_] ނLq&@}-"k8aн=`G|Y\G?+:9:/R%.I~`!xMָ a1__2BXBi^ͯPgwѮ\Z͍ki1P{c8ż>oޚ|virˏ7//oǗy9UFGRҗۋ ͙&^e3h0F=r%;Q,ZߎRx/!^LCY>jB=IL0Bkߟij,aZ^6^J%$XjW}y Yx;qF -96۸l~  ~x;qF -9'Ix]@?fo,ssMw&_VTT!9ƅgCA2+OxZylyuX%ޔx+cMJ-R%Z# Ýα2MI l+q v6$m R.=vSEIݢڠqyݥ,oѷT k Z؜o8҆`[J8wUvmU:ptԱ#`sN4͖ -};#V\*x<=^ؔB!rޞW5bd)QȄsc}0'ecF\#$[~] MM #Vi߂L23i$TY} {%c|-lc*~@1y6I]2°`M ILV{܏MV̼8,ʅTt1ږ=-AۈyCv4bh^cxkqDzU6RॲI gk1)u6ؔ)ބKGZy1i%KHWεP>lE!>Vt@`\8V %M="եAf Cc|G*MM2²jHi+,XâL؂kj&8H(#xh[/{x:\Qk9l>i#zU0ߨSuղM WkʒU[R$ Եe%f$j)|E&Qٽ&$[Owf, 5̕=8609d\7pgG8Y c̟]R (.Iu0aku!:СÍ4 ueT7Z%O:^k?mık໵d|\m{9_i^ѭcn7АMⶽd7,G;S]Wø ߫o1ssE4,X|KB9T9ӌ #xK|o)5Nng|Lf]Mcߋa\%]vrQT]!=P9?i޵m5լ%oW Y2ywNQ݋2Uf1T0Ғ٨Wd`PER5yK=WSʖ.Œ:/gM͍($›yDPz(ܺX子0B '{b!' gFg=0/t niEagοi>5f>= u _ d ^MeC%KQZSL0pxSt",2mZkϷ Gxx<wQSd)׷Y#1@ zUOk eAѱ]qK O=,\" Ӊ|d))bRȊۛ1zj8]LL=1մ#2wwOjBX ilN8n8mJ^Qb;73ê;6s-\470nq7[Hoo) L#f,y *l'wnj]s½wkhk௫ch^E>EYJ?YuCcQ=`2ۉ$Iq#ah'Mӷ6:-E[M/hũ(kV_@*W-uZ@3$gP8ij6e[EKW50bni!iO/5BEp[+Yxl=|=g2tBs3yF? +s<⭩y)0ZV0 h,7ԡյY+ l0=1 k 4; BFdAEL1L9j9MLՙҮ荗O&?v*gA?ϔՈF N Dcsm>|WY^'ӎp2 Pm#双0$,![78;3Os;Ѡu%I6. A_N}5ߧH5;&bpQLnX)Ԓp MǼh2$/Izy$JwWZbNjp::ԘjC~ LwW]E)[~vzMGpq6/&.^OQz/BC5lUCa_3烩3T{LLw uMWVX5]* gC&ωpaGx~^"K&mCI[0tW3NNkc8T+mHx)i:NI=s)xx+Qxѕ=X /4V?cD! NU pG+llqk.tU)G If~&O}Zg?<7Sw&U}>O8Cv8p#YbC+=Ko!<"_'3 <9I/.JZ~wl~-Y.6̿Mr0Ckj,EZXlO}+,uВ-" g!u|-zFSm|anQQ\Iܶ,QQ*HpA@]ԋ)Pu+b/"s^F QpZ87@ zFV%1ag8Ǭ;`~FPٕRBfv ]=Sw`w"qSd}?PF;E9Φ8lY O~ԒVt/:~fqO>mN-}/{o-T[}KrDbmGe)=vx8< }hVozj'"MFlb> od| \$ok Mux'h/wvK롯>^*F!,$Q5T ; ؁T h`ysyB:8XFe⪲kN\j 3Qq{߫~~}Y3LpygVƍ䩡ޜ5K|/SIpu[F&*?+ P %%}'uzj,d\ ș@xx_8o  &N&nyf%\ 2xV]l,T8!8!YrcvB߸Iz#x@ݙxgnD$pph/ݖ ,Zվ m*U<%U@j (=wf׬Qs=ss~AzGRFPM+ gǢSGʆ\G}!S"~&Db'S p)~;#v df6?NfY)f-Ov֜k یhIiNr"g|{~plϯ&X92[L(tdWXY:ߢvÊHUK0oh!% 5vmb0fv[}(TMܹ?dGݳu ֭ߺ9c*@dG-x)h>.ᦾ R v#\(K][*zMOu%_ e+Jf>Zq.xys~(nhB ?DI}X_n<떦{!th:V갥9M5B%<MbAw:N}=]i {jr=[Ix/u-nFhN+26:+szI0,8špCO͈p)YԦz&i B0=g\>Uro[/h; }$֭;Tj10^0|36 IM8`>4nxUHJM ; }+zɨOSC_Rcl/ǚx!-J:Snv~cE1C$l1Aq8А݅'_[SKu', =mfOG䃞O25U,12e2YNGevli",Qݻ$.w{.鵼V8+dGLrC0^w2f,W *c]bSvk $D$| ;WRJPWU[o+,e\Whl] [kP*t60XiD 9yN*?3UIC0 O iZTC?[Z 5n{ViSXRI? CLxȴ|ve8>Uqʲ1׃AK+B)I\rqKe4 48?~~1ϔQ|#8{q*f+1",dx|ou#™~gbǏt0?u}a^LSǦ@<X& #}Jgoa:w''r/.&93 6Ai>SE~-2ux)f\l/: :n;xq *5T,Ox}kyw %$pR4VHQ==4mf}S vLV•5_R% q =h~N{~Gƨ{9Xj4hoqe9X,#d6=776F;~qzXohVDFCbqi>.vGDtx:`g>[.fWMFWKhDtqXLF_܎7;Y,/:W΄stOq82~iϢhO6>f}g}ൃ:6nggk1[q?]l'6}}7:xXm6^Y__-X c8ގGZ4M`0Є{X_E73PUƃƕv{M#P3ZDAiGsP_L t W~!D k88(7"[/N#A/ۯ"|%~u *R%Ap$e``aOm|8 t ((Up D0S1>k:>Ǎpʒ#6Mf/^, rF8ڊxxti/nXD77&P @YɥןLwW= _%  Ƀ_ d:U>?v]elؒȟ:yҩ>Mh'$kV/QǾϳM/wI`D=ix+0"tޱZ*fAzcpz /cC*M\"__@9Փ d){ pQ7J~le>t}j7n+\`_ S :^6_?(X^Lpȸ0Kԏj:݆Gx{q7^ƑeO#h{t/I~Kff_# S MC"S?#a5r#qfG>88`FkT:Iu`ƣ^j> 8@`K?B~NjWJ9fm%I9^A^pN/1dW2TT fyb} ykz۟RG(jGN5ykz;Fs $h?)8(g 4׽XwȰ; i0X#ঐ IѲ ᭢`cCtVSAQlxZFgצ9'JaΒGf%=S*n+-ِb$ +$NvAɁr]e SIjß%on{̓d"14"!w)w^-tY aͣn+&G6J$>9bqm6i,AB4ޥHvyRpj0c#9L.]l^ V&{I1i_1L`-cad}'|hc7E\.B)7EDRd2H $r"rx9-AϮ:_{1!n쌢u| &2OC)` EHX&/-b㫗yݖWoyt!$XQ.:λa@ڕA1at l7z k2nW2$\"h)h— Q$Y/-gCo2{ڛ\L5á%Uaa[<s)<*}\3Yl5u4 r=>VBB-ۋl b%3C] 2ӎW.[S[ K _/u|o>MK%9~9饃 DF[.$o}j7GIn1lFY_Jr8u`#Y`gi|\$>6cn_N,ƌ_G5̾򍱸suEY>.OH6wKn`cP֣%o?v7Ct;2 #:,Ƥˆ*hSa4W \ȏu>)ueFLY%p )yL]8XqzSC$U0HcߝgDw?ӬO(L"P {48 #6w6c>BDH&KUa)S攘 U5+QhCےkt9xLuIu@BR-/_C^bša~D k Vh}J邽A*`y wc!eC6 Y|]Eq"8% =HN'_"SP+)*G"`k&QH1 `-d Oך?@1ET$؍bEU gٞp@=$~mxdĺ y)fG|);m}]hd9!.Uh; C 4;^>ڳ vW|M`GjHzi6v#4[hV+Wյ_WuN8}nʦoPs>Pm$|xnJbm|l{˔ʂ%%fGmN\H>yaw{oL^cF2OKDttอF^9nQ^d`É{>ٞ;sEOۂp#*=&Y|NP82iMI˓qP"Sƨ`1`&BCT*YpsPȄ#0n>(r2bw<1<_M$R߇ - "7{A=ԥg ^BKB(sHănpȼWn-/PhR1J*ƒWX !F h{P ;{!2fأI!-UZ S!I)A ^4=[u_aK\*bк>)X,.#X Ewߒo]oݞA7`xh Ƽ]zRs&٬z Q TC>o$vV8(lw2֦%*hWҨKtB_BFhzRQi; J^<IC*k#(0Ă@BC+&VX7e]t(벣S ]Eh}^Gb6NbEs bࠀ=} U4B% YӐ*P:HH41kObBwp'p(;@Srɞ7MM29J C@ ׌$Eh ( ۝yi(-XWV \>UD:XRK 3x$]J  6 r0MM5岰0N/_Q@KM }OwANxi_~*e=EPΆ~oeQq@2$#q30|P}:P{c9wkUdΜHdia\^=J-UAϓz{xBCr_@ $S5$jOM.Љ{5Q;_AI@dEݢ %K$qe,?X`!g*Tb01ȠH6լ̦:6AʇY&\o5#+~w}1o"b+PUL9) Q4/29JTiSPBe?(<_()¤VGWJJ<8 U]`kHjh{tĴ4B1t1!aWo"hkkK }NL Xå̄Zfs3kp=S+ewK?"m_,&"ZFѶ(y]﫛>/L`M=m..VtaC_pq a~Fu"kK1FoI'WqyåE(QU/5 t◀ uSTp*Tq6́!{J\b@|glOWPJ?C‡)nXچ2@Y..t2~cnįa&7{l- HdBGHcK >klkm#YWȜ5zEILxz Cfk85 rç&"-g']`&H>d ɵM O:}xLw 7uxS0E!e6Ĭn02//<! x&aF/U!LxFz (Q8nmb2 ݌5wԁ1 1%>KrΔ,6QHv.փMbfd$B3U>z,ĒX/ c}C LỬ$ķg Ĉ9'S]‘A†l/}4# G]f}㄰(;'UguM)^wCvc# УݝELMФNۊ)J^?A3=# Cb@/B{$tS*s wR{#Ȣ!0 A+ZV`{Xj_5I!yD% aSEu4+s bl[l\uɀwe!_xCߒKqrDFrhmD ta8D<3ttv-zd1z|jbA3TD(LzD"DHxL&d-,m.%+_g';!\19wO|*Xb܆jhE%v6yF8_L5|(zзi%l| &bPc>4Ś^dS7vp4'>c/!͓\ IVkAm=Mt*.ei|0j:DK)hV- $y2dfyT-WB`,}Gb>oJaMQB%Lk`.߸j:MW#=_߯q BV yj8PrTcHU@;s;$BA%|T1f|[l3T#Ts#?}zPy yK @a8HtrC2+Yz 􁡰7*<$VAEUuz7#Pҧqz;jܫM/2XMDP :qU:?&L rE2ʀ0Dpz1Mf`aGĘsB+h1gqG= T1/ۜ>(l k#f662|@&e5±T W =ZLGeTy'"^4:ËާA9ܦLmE $#?`- 0btx 7k١E ʤ6 R{c)iyw턁[z>7 >eݻS\qK Tr^+/Hp?ueQرuxbҩ}'D"[ ^ts}#irRNv숧܃ЮVPm^JVkTO"i ݼ-J_}6bgR'E:2Yӧ 'yJHK?P 1+!F8aX+?Yô!F#&OQ.St U IjJJȴ9H("iJj5v 0*hWPQcB@h{3621ǚ.LRWMA`+$PRlp%)wGɂƆ+A>\e,Jnnkjt~-$qȋTEЭfx[bHE30bB >r{x{JIۓfmh櫶QUaekgzKsSt=_C [%iqVgQ$VDFh5"xBIzu^.u+óqY#mUD5B\3ú8r# zn@̓rБqQ{4OwT*?39v&tm /Zb啥c*=!~F݃}5əJk,p:^ǫl:RAU kF23 `:-qIh4{>TM `$3`D׆8M8xU.cW`r2KYWG$bea*I346iGaARs-$}Zْ3V|,qYDrmGW]bժGDw xGm4OxQzR$!T|j5|3, 0`D\1ʣW?1YsC V;s~pJfSK=oԷƌo4 1*x9;𸜕2uv"5"PN]%H8vD̜$4oʁ? r"wYNT?'LTRlr=RAFzz<@gz]:7z > JO l*ȩ |YCeW[GF̝y&NaCEPAݓlŒ+Gh{ HcV(@^2P:Xecs&{==cE~b1+p H[ 9*Q$b0@A|iPSsݔ0|'Ĝ' wm%le Ӷ o'p,QsJdc/`[9iKYg Nʰ""'p (ŝ27l6xNM:cұ}އ`zw8>m _"{,u)VP%Gz+ 6\2 <(S}'R$U!e>G.=f6XynKNiҙΊ2n(3 -߯G\P]zOPj8y^σ KOOp&6nl )|v'3!1fFP]5uWFr!h%թ3tOT`Ch_ :y#~9F|D 'G"%5R?u3ge?Geã%R B#( B7""2NR2C/uX j <-ݘDn尼 [._{R=ga"nȐ9#U̐cX{11֏S"@gDĄ|cJASPCtnT&B \ 4CdB0kHѐ} ̠Z`caAPIvb\3c輁ztMx`!gR$$A%_hnL_$%y,itC :lG'phr;CfKGfJg. <\5fbWOxs^+_J:j2R~F]4^KBޥtVăL>;PtBMv2?@ RlD6,^[׿=tq$u "yRN⼀at"Xͮ.b!ZWKP; dM<F 4UN }!\&:p>%N$paZ_8sdE񪎑>]f . vK{]k;$k4ulv1N[PO*[3ݱMǜCSo6#NW\`svg|yK)"4ń0e»vVt%1,J>A9Xb߃~,T"ҧVWX%:Q"dq. DZQ{p%(B #H%@pu%@ہs0vbsˣ}-:{vI0`?GDwOUZ2$q+~l#6y  7^36[bG3_'K>{.a:$bJ $YeeZNR h8WiG O 2qH|fAWl (%%cF3c`sOG9۝f%[R`#뻳&XxH F|E#~*omZJGoiRƅl66 Q{ь䞑f a qqӌ:PvP.~_ ht/<p'.]̡ܙ+e됞%B0Q!t? 2`)6i!,MLD׌#cg$2"wkPjx彗\yy8x(%Y}-t :&uѵ5*㭷]EA5},;GA.o{ɉGE?u;6OY Abm+6T,?o= d8IF9SG?`Op `0urs 55jc(?; }A(LQgt.E ђ<JL_+hsJKrVSU8o$y"L1 |TJw1Ŕ` zҐiB4%mǮCBE4sAixN(ɯ~cb@'y'5j+At 9+z"B/F XL V YC 3H[6zj5G`m+9Uv̆^\<+L0Kf}R, Q LHH&)AjwsƁKjі{b-f_b[hCL8#mhBW BtIbA6GlCЇNVŸ*4%0hRt`h%\V;߮c0k(du!>aIT#L9sĶ-.ňlzb#Hqd@"agd.55(%Zq]n8WG])N'<"Sq]#x"鑱WIov !CW%m?'_-!5<_20΂%" лc_PT *~iia49,Ybh*T aeAh'GM >AvHWÝTF΀=gh!%Ԧ0Ń7<ȥfcXMQV{(rfi o, |3f%Xٔ2Ȝ *2-?ωsXNL .Q:{xy6HQzM][>DREYӡJ*_-\kđa[j:=Yo :b7DJ3pWEvpQ UZy2T bG1%#D_pn5{PL-4c0>s0ш͐<3Ũ'M6S>LN ~NȈzr2_$~*JX6mEX1 0F?LN@a_$ΦzᅕSp-1iҩk/B)!n6!=OpUp'+< Iŕ^*F%#ۛXl>D`UVJ\9Tu/B1vx_Ϧj}2&x87E}Fк0N!QٶT[e|)Pd~~e4Լ P~vOhDM$Ʀ'4nAOoG?9+x6SܶB(FW\A!"5pG> x(oIioWGU!]RZѽ.>vw{oA XSh#uz\dZc 5%4q A;TtFYS 'WAULQ O :VVu HuJ>8uiVnyy" ~S" `z~)B>~xz卯^: }%(ż:I[&_@XujyH^B+}ANKyj1 xoվ'$JA&v5wcŚrW酰R^܊KJ.jUԋ&u`H u^d,=O3``%Q,䴣j[g6}j>52xTtgTba ۰E_ ygkb-^Gb2sƦoIxB{OKɲ@ז~5b]gv=j597[]>rD2uʵrbmF.An%.3=1}?XaC2 [[ 6lQ<+ ?Nr w|XJX \J,bzok5]"LOtNFJ؄c#g/$6rt3_Č(%!fPB~(qZE5DH|ǰ:XwBawJPI>Çm2z K;7n& Q63OftRрϧIl6.%F丶B0D#iDJ/6˱E<qNl[-et%\EWb ߜ-BrMr]^E&Pi >acݩCZ"uwQ9v ◒DPzFѯ؃|<#N؟vp|XʥpheӸc!אnH8}n!j*i*D: aqY/vQX# bFsB2#2!qCezIeL*Jz5Jּ!)ɋ ;3ʩ Eͨ@M9KÐ3tA>:%x|`Jq6ez ;~Y˰m52@.Wkg'v>oWK슘#Į4ObSBh[J>tMA VK.ꃥ!gzV8K¬R3Hճ"ęX]U2qr+{逎pDFE!iUnPO2%[$1G)x!/A#;b:w2[O T6+.K}qS.³Euo>uiy26hl aw ayaAX(lUg{7xFͼ*)s^MvҊ!#s͟+uGb%8z4VsP4smumĸP'ܨUM(*Up@O^0!(#Qt9D%G7Bђ]׷?R3;!aU,tLsX f-ouHaF]Wҝtf)!Fm0s@+Sh\h@h"/C-49)<w!KE">7H`\F xk)#ⱑ-wrA|rZ5 od %SWBCp=pZ5.áYBjB^ #r@xb GXjC_)*;aE;؏IV`-B5`ET#B)Y5dXDiPP'_M`ȳos5ɶ0g;ãQ>rFxumX8bRR$Ep1s.i``rh1)7βձ 78YAre?6)cL',a\Yudg`0h~%DhTBQ@&`,xq_b1ڶȊƟ̫ƒ҂)\UYah-A =Gv B 0[} Unz6bC:VW(_ØГs~U1k}[/c%C #r~=x9dyŪ!XBMYjͻ$N&K(ײ$9)T'3"O^lhݍdHEGdy >&̐ M &DBB$QYT|FQVUnݞI{֭[꫺;nmܾY9~tYΠ1d!x1VegNO0[2~WbY>1ku0U&XСk !*񹊜^[b\% IסoB9ƺ̩PJk"T wXլ)eqܯ#2;A$ \jq8dDorQC̢0`x,*Lk:l蓧/+ Q]E"'`SSs#\G7@Q@n "M}%V dUՐuU3bE:Xvd/{z:7a.:`98;~epM+^`sE~%VVX8Ne0ax8@8r0A#+]twyóX@>Ǻ5~GhQCQ3Ո.#\zVNJrQtTz[33XetD %>+0׹Bl, ]g` J-d~p#{=8ݹ!2-Eb@fÏ}ȞfvSr;f0"e֪1(%nu9\=l.l8M{ELtPY7as%noR\Ouj#݃sn]4&WmMj\pIiKKq$v1p&`P0 罭ptàŷY1O^_=T𐋶慁o*Ǯ|(*:?LǮT2# _U}32o$M4Jiعt|e쉡ZfM,'C팦 gd段Ѵ`ͺE؍ CVG^xo:kM%poGP{棓h.GKѢTaR1Z%R3 rms |ss ֭Enbйu(sQB0ЪfA=lLFf4xy'Eq3SLQaM1+5#(D; OCE(z_SSSGѢ'U{>uz>F>’7(T܋?}LO g'%hgѧpi%J">]h ?sXY݉;6| ?O>kq /&E<3`Mp뺍1vv sT/bAxEVyPVw/FYj æqBo_A@!Z(QA|  ADcDg2MP2D$&3]Le&)Qs;羖o9Zmyn[H#A&36eS6/f_R5b*+"̠ɔ74Ȥ[`t_bH+ xO%((6IEI1ۦox fn@d "j ډCbh+TDDPfGOi8PŠ9 VGd<4'9 qD/A37_sbAM`* o>R d~g8 k0tTETÜZ!J]*T:"~dH!"eD !&h أmp)*8Bwtg+#YP2V  h% )!^+8{y,:D3g3J3Kg֘mSsQzI2D ;$ Rp&j'?tf ֣ɕ[PO%Ms)*\,% Ra<'T K2/@D* PFxjA߭,[ʞV"a/ 'YMPSX%;p` ?LTUi+[p{g1(vF5 t ?b@Fp 7vc z˶>YI`gE<\O+ʩ*;)zn+|_䦧r#&4  o{sCj/."QBi&l{l^r^8oct RQw(Q;&baNR]`ɮy: KeTǺW8YU`@Mv/A /"8QTctA>cJhuhc捎(L:[its1K=d'd+.7l3 &0vr;I~<Bgd箲3df PÎ8ҕR`iv;|r 2^b(5۞= y*`&=ǯzN&%ȞD@K&з:ѷw^(êMǞ$|n_R 5tX5PvUm6Þ sWBt|wM<4V0RBfG/'ŀyDG0?Jd{?v>^[1u`$Zf# x0 K>?8';,2s _CTTZT5et}/%8Yo덄M>leT7c֙ igɬs`Q1e mߜDZG|c ̀[t9aG` BSp]*ywV2\:~~wKݍmʽ+@&7,V|K 2Nt`<B)_ǽ/^%W%48|?6#<A<=x2?V sx| p\u`ÛD}5fp@IuP>f>_giK%ܾl+U,XKͮdKX+%[ڍ&zY{9PTD>{=y틞Ϗo?QH(䰩-iC7/+iMI0hsU[QeԴJfZ: YTZF9U`l{,ѽ۶z2HrCryc$wU? l|zv 1ZJf4+U݁I5+ 1a`:eY$Tʌk AzXRHuh0-KiI(DI%dJIkC4ɫ9XԒ浴 p=_s$kSR),f C7|H$6DTbTvJ 9@ޓ'9UeO͎J .$ ūn` - #tzCϞ4l $K I>!y(zRoCc7L=7LƉ yA53 Ii-yrس#}&pwh6o>J @ѷ6Ewf(1K(!\< ڄ¥E zfvlkoo ~Kk\_`/hk(QHk$JZȫz~zU&m7Fn5]I(V mLZ.k4DU#=cWFQKu8ĢuHzuCW P/_;;{]l놇vBTHukG@TJŚ;*ye^5kK\l2FXs&3n*3W_DIȲĝc#f*h lV赬YS%PB1}fwdAmq_&j|9֟svZSbw9\Ҁ΂ű9[[ֲ$nga(=rq]~{\]ߩp@d[3$]J.lɲ ɈהuQCnIrds!2GbM[n9`M'ˉi;Bbk` k9^h3Fs:(Ѫϴ{%;ԣ 鍏cS3-a{/O,fZM\h6u(VH#}*J?AK,NrfFzulOm#vx?{A xx6bg{G]]ǘeH. KKUT{k-CD7PuH#&,%>PZ8PJGf w"4KSsYHt>Ѵ!A c饎 ~t6;Bf)<YR"0F@t^o)9/."vPo+1:k1%Wit/:x?0>f UHt|<=?#{r2hgRi-ý,*]]5؂?½N V @d[k [NfFo>2&"l6{fF";{Z@q3.L{Wl -쮅.dE2p3}=긘Z\ 7kŔ<7*hC'=?H*N:TOIu,?0@"1QH5 Fm kׁtmX4]_m4ڷ)2>A?J'PMa!ÞP@ԴeJx<6_Z5 2jΔQ<[ ԗq?b,k ϼ! /$Ӈ N:k-kQ-N(Ua-ۮ㎝?)r;3f@%&ՐoW90sgMg,}T>n|0D[`\ɪIȣ=` p"ޭzs"[aYi O(W T4YD@ %U$M1f`րp$ Yĭ&i!.Z~HL0Ȉ>~>mHu##n`Cw!RpV[Q%4$XGϊ1TBfzĻ 5ܶ}AfZaH FҐ˪ k߁,*;}6mt|Mw 4 ~1ˉgwHR]P xpYBœA2, `\!ȴ فy@+yg6p5 L5oD/zvkEua?е-$,)t*@;< &iLxvw2Pt%w,!Bcޜ@| b㐂aC-f%|~8FUGt|x#:o{+%T}۫:umHyqG@)^]U!;"%$ f* x!3v/w㒚dA͙mVʔ N7#`p !3XVsxHrMXio+S }¼ccڪ_z!B+JR|lGM(XGnZs[vQ19VED .xE7D#h{~@9*6kZ_/>VO-b |D&HoUw4)񍨫(i,uOJ3}K0@ :۞'lo=1W⭯̴w&+d/qoj{5PE=Nq}z3:Se lwLN S.&XuYĚGNN,!LJJFY伩18|PxuR`2s)]R@g8_5tdKh^o*P=s}u0J3-.z&~XB() PyCEu=E,7gϳJ|މ' 4>N暶L k6Nn;ݼf, -d5ryӌ2Kdo2 PaxQUHoHW>޼:?oZ @y影aSappcݦ otT+tl:Q7Sf 7h?l:MMOy$, ]ܲeTKX m7TJW7j1C_GʭGO`T@0d[ -IHhYyk!ncy⥧Ȣ‹yf,?< Rn^? .(]a3;!}Bサj٢  &;mRԣ3DIpr@3|}υ>Ocԓgjd  J[u A:A_H0+] aHޚ?8VFO%]@h[e m̧ޒ!d ;g˖ mp 0Hr/UX֏SR)X, TZ:oǡNz֍#sA1ҖY{$mtbojQlm=1 >5 L%i%!B}9մA Ac,2.~Rڥn ҍr@BQU+'0|*#K;G1dYNjIL bDPb3=rL_¿ZF z`Xm]}T ˡ 50HFLw:ZB2eYǯ7zaS;bpXt"CGi왴E]<)QT6'W}U؊Az Rb΅`-02gh[@VAz*^پ8ִ&ܴ }6Uӟd;!/f;= lתjt(T!1=ٽ-%Ge}wҲ{T/m N)U0ҳaT|xfw4EmQ@P`{.ƀ~l%j@^~۷/RT -lV F6Ƕ>HVpH 5 /jMoi^ݲ|& &IV|~=XA@J`YgpljݕH#9`tZՋ!ʐ>q7.b=$mx//4Zd^]Zg5JGuOuksnc4W&]ٸب!7'{J./6\ֻ!Zwғ4zz=MU{s'X[([fvawqêrYX2Dݗ{ZkHb 6AJ^% Ǣmazcaz rCt|6xÂ~ER-Ϫ%x |;lǛezoU H^~:(߇S/vd9SIq12ֽISaozy8kFJNed#/}&XaA~g$`+E4~9BeWӪPED&:ak o9Q$tA-y[fN >Jι쳟7J5L Ǵep8xʃ? `H`*ϙEz I`@ o.:0`*}ձ5>H'?w4<3B3<afx E<X/9KpFLW`{W@t6SRqͳ .x?xZ.G jGmw?f_Ըz!_r1ϻCu | k~o͂'F/ZxMP雿7~hRb.2cSS,V,~ix@t=#<01o>/}ol`,ѷ XKUf~.YCܙW\Ah 17`͍a_ӜO a`\+_G.If~b΀TB[޴| ^8ׁƪ<\ a/5mj{p'mL]|iӎeݶ Js_>gG, uUeKeKX/8`+NjI%AٚՁA̕"sy W#ۗŭJRYaFѷPؾV9;eA&pzp 4waXI4V ɶ ,3x=XP kqlܰ'q(Tȯ\c9>P&fA4/UK+{.f#A R &N<{-o{B[Cxzp4i &|:%ԛR%禸lAUN]It =A]ᣇ+\B<0GF]zJVKrcu੦ ?Uh,A!)Zk b@~ XO>ڼe a<ڴDGZfE|_X=D|cM[#P݉kZhq؀( /Beq1/{/b $Yc]XtwouDܤqp-1$W|M iܗj&=]嫢UO’Y [ ot{_Ij$+D : m0ƽ~Iuz|f|`R$HŰhm;\) A{B*s V`-~·G,2.,ڣQȺF6 8#_TGyG5dX̚:6/o6l֞.~󟶍lZUtcF H?Exv+/,@6Y|yWw/*J|d-=7S;]zL.>g6miD>NRHXx뷛6iUpInڙ@۩r] >+'6:1KifStV2U׆/R_,H7<&j)[{O#reWeDI2 _$ן4`LyGN,llxbXhV7Pu9<9@b+n K?ʫ_a*vw:+1,5;Ku?y8\`? `*:Qѝrx'F`vuHR#џdL]5)V nN)`?rVH JkmcQzVke W M۩_R"~֣뒲^#6_t"Y)M%,Xj\=*5> vLje-&*+(3 ɣL! TZŀp 8.8Gam3Hdy1p9-!iʹ3ή4Ē],0]$9N dN&%1ّ VXsM(؁[ |\:F!O@'^5sPW*8 kckg!I.c-/<(A p(a<8wnBm1~nH`k[n9KT| *^R iU[ 94*jUn gP@9\5`Ys<)qAco|: 4ug NYP?:xx~h Dcv =Xdͦ/hɭ^2Duמor( g0pww' UJ:R,y k#e"oP?:wi*1c"{C斋skX VNZrWڥ=| W*m–v/Aytk 2 1mAn~"_7C & Exdl,lɲeݑ4;ٕl@4)M!7&` !E*лcTϛFpZRJV p-j4qydހZ|'3i@1^Iq6yRU:$ey[PM[,-O.0ԼQk/E].#12f;yaBk./m^&TW׻6k_v݅t*ޮEM1)uq[,ABMۗr>|/<}Cmzu-ƾ .f+fTJ3tG߳a(\+ }N/S |mc }[)qTR0.|.]b7e~%uG!uMA1#|.)(O)yIM_W^y$*.U)ZMYyҗ_>gj-5{o_:+*Ns3jzJ5ahvA4_ ՆITc %,ݢJAZ<iB2M7R33S=WZy-K%8S"^f̓]Bn m [|2| h@I;@Ǯ#$C2R-^l[DǸ`"%ֱqR7. XK;CZ fh{&Nz.Q=*]C&Lwo6 թ@׺{WBRzr%8%L9k Ż34XRɂ7*C8̫aI=;;Mj Y'Wq͗yZ+1FutϪPcNvn%Bݱްr`̼f"W,d3 q?L IrglXQmSws/zCՄŰ QVfՌb+ɩYfa5g*xЊUN:,0V t55 F!f |kz-5 Ή<ݽo]kzvvd[$XD𱞞Ҳ0n-|j@t%ܺP˵l8?o69.wl?0J^?U;]<\ه;*v:9eTH3oݟy) vVэU|~GtW5Uѣng@BzhpB\e0ϲn^} WJri ͕6A=` Jji&VnEc.ko=jPVet AY?̷T{\ϋ޳VIezл}&AiI4@õ~g, q 0YHJ+yȤ\[mQ8B){L:T~(˱'Kg7gY֍,@H]ZcCC LLۉHAsRdf <[^m6yMyhA9&:NgrSsӻ7R ΩVNMQՉO[s00@K ]œ:-EdtL~q3x3dH˒0o"ypg]+L޾|MnG y V38I#*-QsDѠ*>vM!CYG<363|+y:w8/1~KYCK!ƻOGg'}b>[1NSSs@FP!^NC8WS=+ra#3̈́#iϿiϾҧ^+{:|"ǯk?>Ϲs6ohq)s6Q}Lfo./|!vcQn$߿I'G gIf[ NcOisN*QomvS< MSFHv]0B;mFm3ZiYJcԗm[C6TuJG@Hn(9 䕛DBN}-rceft,bB&_я#7'ƩmB VY_A<:С%̱4_iVJU`sb("䝅nkaɺG- nBڂU6O޺e^؂X0*±_\e0o? T3 z: ) :F(zqb;vG\b/<ӕ[hVC%18m:ui/ӵ׆ k0{ohn.4;>*UUo_cڀTAOvHLg4qQHA%*f|agpl.'Dҧh1V_-<`͆IW];/ܷ$SF_QZ#`f4L{8I hERD$X"F\#tB\xÄqXD6[Nvɥ @_'1";R HQr !)AuI̾ 3\?URf.Mfrۚ2&Q1KYuˠ C4[좚q:J0֮>cnUڅc >f'L#Ϋ1i IMaKq(B?y~IeXŦutO~azp7gz2)Xൠ{W(zЎP+Q3lGrpʽvwO[O;&lfR/CTfy~|~%VB1u9h+pç126==0p1E-`(x_xxg y}͗,w \LBf9::e2Ɓef@ؚrͩJ%4|%)۴$@"B~vz$ϷЅϫXqe@Ƞ  ,v#}wK@>u,|fV~r@;q͊?^y!%wl&r@"J|e CXN$Ϛ.ʑ@v7H@w,C1Bd9&?AkbXaE0NoZ3@_5SD_kD|P ;\h:D5V@ CU-V0,  Tč=FƞKA%J\p6{ٟݲa| %*[2VhpT_5CԋQ&k}_BF+cXS ?"_"،x\B@,:>Y N<8$#?Bߢ2=ڲO|/ԑ+1pAꊕ04O?uhݰ۵N(ZI? G K%!F!y!C^(ŧ$'M=XHZewt7gҚ I MOiT&0̹J<S|AO`q3 giWg33a+:g*~=;4SNTPly.ոry`z[IT <fR(sLY, [ex1TtNE/CѻxOu[y˗DR*i.E~g ,vhK+LȮǂ_|D~@tt\jS\ }T\-V*֙aҙ}Ҥ5s4&- v{E[%1\dHTl.~ibURnIdYվңC\zwbȨEn(iz[1U[ )jd9r@`LںxࢫgF=gNChw(}s +^e$^JjV/НLm4I.1%5+ ycIM]<ղ?K.V,c"CW*5Ʈ=,d)Y#}W]Tu wyx2Ed3,e:Zڂv5RFOL0Ys+t6`[iX Ṕ(@C%?zjP@-eN>y-@L lF 9,Bg[p\aՙ%S/Y( 0{/Y{i}nr3Ğ%Xy@VQpe/Ag׏|hX+&ELsb+%Lhx%zXVU5b }tC-^5o{ʌמyX ػP׵wRYv |L74p֢Knu0c t +~'gZ*r*Kc̓EH,8`` 09z}*y%vXV}!cΗ=T'6{k!E=:adwGp%#GpwzoCUI#l•"t;p iG!Ńi&=w=4̂Lgʹ۝N t{s( 1mu:Ȑgnn/(WBhkITupdZ]Aڼ)m9tׯ0UOopf+$הmt{_t^]J׬^Z_u,LFLu{7MBg/BݴMqB$" `՜Kfԓ)njiz?G['wTɇxIXЄ3 EjM[dLyf[9Xb}f+??װW#ERµZ Kx| t\ŕ66,RK$`[dȲeK $={mZ+<23!$L3 q80݅99s=;gwfgUdgrUݺuWUjYZv{314Qѓ! Qt89)iCIPxFKf2j/Re퉩)h/Ϲܣx{FtN:L= R/F}~ހ`=nҥj+OlS3=.{Ri%mh_ܛuCՌTmZQ$#|/䱻NOZۍ%-{N``wvIqʆI)I|=>_{m~&{$-+ư?L(;6>~h$2ɤ,\H-\ Ӓ&%r\֖@Ւr9 0Rb||>!JGKL&&J lK yCd\^ Q$^ҧ8n1fȧ$Sb,KdF"KqbHDS3LU3NtCTf" xKuk61mfD>cпDG8BSi{P]Z]RrfIJ2L2y0ז>:Q61}F[/\PD fLK$ОU22 RHe"1I:LBf嬨I8ey,>"YJAtIbL7:@S zd4IБϣVZ,|Ȳ7Ljk[8/ka٤cU7 VUUmsWa1Zc|#d A"R Xu5U%JHL.3Y68]S80mZ_E[۴!ز3ofoʽ$Xf/ްGG=db".nX"1N,5᣻̺j:ucM)@n86xY]kޢK+qIccEG1nBqhW!giWn,.q{ގkG~izm(, ~?9R"з6xɆ8g=#7@&~2Mu.0 GW_%2iG5Kqnof߆! odԳ"S \ - ֛-%&} \'[v< ϢiZ5]qrLҐq)Z޲bl=,z3b-/'9vD ZU@2 ~Z#3J5m[3Rno׆J>ZƲHOIw /UMe޷PÐ h}E!nGe41Vk{9:>UTP#JRV$& .,Y5n4H ]C2 DߎO, ƦV2a3ys_70 ?T/46VqU$S|K>z ^gk7t5-57wm<0HP cii%8XKYQm|f `߹u܀jiSeȸ8Ti໗^謦w>;v&.UtĐ( 8(n2&ƥD 5C_/js͖c}# Os01+@jZZHԒNbm)Ea5}XgkA$!xHC,@уۻп7DaG7Mn 4~c&>QG:<+k*s',Towu,Bֲ τ`z267c dMJ)Z-]6YI1#) .ዡEqʰLZ:"vTϤt/d6e6Ka .V5*۝%l( #n:iAN!k1"Z>n$EC >uqFNIYcIX*&g%QYA3EK8txj=+BJ.LfdgIJfW VBUT2pXtpt9&& #p'vGNhzЉ/=)Rvw>&e OK!LISXC CJN[`=UN)И e@XS{M2G`Ι@{` i&rXnh&fS(J9(Dn#zwp̼pKvזô~؞198fVq;KC~:߰* Ԗ QonIN1kvJ)KedҶpڈqn RbL.2ͺ*D8I,)K !J3iq. X>[q/lw$G{h@6ȯls8{szΛ-M]àU[!}z~ )ye#@7Ғkie YL^La:4گjәLygA0 (pe$􂾍~xx`HΣ ;:@On@Y4l`/ H\w[L#7X J bA͑Fz@'H9F(HVjSst" HR-ԝ&NKBGL/3*(:[ǚ]t!,ľұ[K7ֵv@ޮ~[ycvus px[^pp<4^q.8衉u⬨wߜY=^}ljshԤȚ:n]7*AXv{}~XzGj6|:fs'_v2>ꎪU#0}xZ}X(}MYf[wn[{@5^3.RYEWз0 N[3(7>_9^j0tv0~[]uk4\yjr%U뻚`mcvr@#Sr@ *Ix=Ϙӣ;B#6mgk #HGm:I3b  gjҽ[& iQ, 4l5y V^{Vѫ;KhM L:("׹"D%O,rn\  ]_ X7@_?Q5hf4*:'fsfهywrO',̮tfُ;~ P2eY22[1|=*L@ @QX3j|G[l,x_5;f 1''0ol\N Q݁"S6Ȳ&J>حrw} #޼=r0Q }աœ2m[ꎚ"/kj UO%3[t2)7]B2^C#c̐293U ln ޵K *%}sMQ/V>iǮoʂ :s-r![j_$55-9}OrSçP>$2Y- 2\ U0 X-e.}l5ؒ_n\m9:8j_~4^K|4g&/D'ue@JϾJJ?Y Do'xLYt#%_Y+6GQz.`$2` )p|J)lv菾PE5WUx>N?\N1\6~TOÇk`UyM6 ѾG6ILXn}~RXf#7Vl䈙P8ήf, :{C#C䗛 P7g؝{$HV( ?@?=f43 ~w4yR"n̫|l29^b1m #dЭf:r}V1jKiϔμzqlQ98lu977Xe;&Gd̲Xy5^pZMepKx?lObU1q%Vw4 5n]T}=Gjݜ9gwsD`^Sbךqʷhw{?XMx,9LG^rG"K蕹(,8V:[rR &YE"S>oF AU,ANC֐_ b6EI1hbW|K9 vZ70bKOVtͽCLI,J,@eYwX[*8&>>l61o A{ޕ,\q@'ŬaƠg@N5"F`og}EꁣQ7:R$3xA) A bF~w Sf+%1(dm[$uoJw!xJl.JT\(H NmPB(H'90?e.,"DskEw0ӹ]i0::MX|2P ۜ_-u&d|EV(HE]?jqX#lJNKb™\p/- O -XCV7*!HcD]Y0|%xyٟ+Dd^Y$04}#+"_?I֚Ɛ7XS7A2 Տ0}驚Cl0?p,az4267_ 's+xȴEX4a+ !`^!mTA_4  0٧1.yYeqY8h.wMQ$< TD·joʧ<[KbQ`ۿ}(O*t}тl0- BBS~X:'< l(yvv~k6E kYBHl!#2MuGO0nU!^aˤx`y+K#x˺ )nM[T5:ٵ͔Oo;eRk|e WH&$Ncߧ׎YC||syX^YPD oVmJ}툴% fY)@BN<&5it7ct MOSk#D>11μXjk8q0+F]ؖӉaLZ ~Td^H+^ C2ρl9JϽ> +r{|V|~> cɠ/ܿS=g~B|$hۻIrʹ93y0m̈́"fUg~8~7O~zG&;1W^obW8W Va;i#;6]~@I|nߩtnκJ T!ˈIr@ͫu-2qI zW/}3hfR_^rqoZ6ӄ@!kr+R g_o, g^)I jjFqDou Ra7yF" nk07 %e"e >`}r (k Cn"ھ[Jaoo/9f_ iE/߮ny'3{jq5+8pyo/ƪa_*6E!lDؗGLj$@_AdT&@;UrO"=Y. "Tߴ0l۸1Cu>4_)"2PU9Rqltɝ@+{؃/1jm*xwd9=X|eaho<~vA }6[Z ӳ Ukq ?Ĵm@;LO-6!?ys1+w|V zd2@*\žyCW$Avsd]ń}ocG-B?.[b9?{/ !$[`ZJ k Vn|cK&az>@T],[H Ii#1 oe+@hS̔B]B;i?voűvv+o.b-+b=߲oK;}m Y.`6l6}/:rgŁ*t{y{L?y&ĖA~}ߞgW Eh`dQM5ԄdI^>F?TgbmA'2_bfg A 1\50<`8nsy¾t}fáv%Zph2a.e>W]At>Q~ÿ )KRb ;dJ'n#b;De.uuoFKN!{՜9G/7}Bǘ.#wE͹h ]B?~ˀ R۲dJvRgؚSw#,Βd@ [9kUc4"2:][!늛:-ZQֶxf# SS b `C1J(9= 6hRSuȡ3s0ψb|8ӐDj0$BWfK'Ř's -=3y8YGYCMaN/Ϧc*lbUd<܈"Q *Qk]. (sK6Xx|oy9WhwvKƉEɽ+`҇׃pn"Yڹ.]~Ї|X僝}ak0-@OYxYkl%rZBp1!@b;>v <;vg];`L`M xlZj(Jf(REFj#RsgvYH νsswι~OܥI9y,]b1"ZLN(A6U!BbSRZVrRQȱ ِ4;JnG#F¨/z0˞X.'4=HVk;hU!B%Y-+-[Mrbnj QlhTK k`8^:;HJE=֏>Gw^^7\9Cr ~4f4D¤-94)$GP ALHlF0I4*Dג@zF b$dU,C9FB'ep՛ٟ9 dڭAkƇLɼG$ӖiF23WX`μ`aX}(lJ`n鳆3!f]qm֐5smh#(R>(r<j{L\Og hIԹ b( CciͺjH$E])' 6۬l'qCzb V/:huq`XozK}t,wqHn@+~ϭ wcNLô{%@vUvx:)ʉU3s㧁X;tX^V9O8l<]|xc<>ʾ]{aѮ&X{ӳ%b1 $ T٥o@ojb2 qD%+y$JuC<8ҤpUiSbEO5-}ִG[ѿΠt#4g(i> csܳD{UN?K*mDؿ%^ݿtم_8!@{ms = y~ӮL)ϑ.NYш[S;In.Pe%Xz!ٱDP'!@=9/a v9@?ıG:K{^C'ΏfqD>W=%_3B̌tqGnk]^bvAtpOvt X2h}6z` O /_r{xHpԗuaˉ?PNv1:yNT ky?=St3BI#D͒I*a̝P #~:U?//U#sY N̋yB, YK瞞82Du^Kr:]DLW.iy<3pN[b+;$>pD`|..M[=м邨U읊ٖ=?:^L\Nrq,-2oW}RɀPp``J=T[=n0EUX0rO4Ts|+:- 밵6Ѩ֌![$DφPsTjߕs&kA刢'͑hlWNV!IPtU) Gʺ"*rd]CDT0L2>TGfHu%paѰ1A>$^g_ wގc4 ؙ4ҕ$K@`f` X^X봻Cl7d~ |z nDb lb ·uwP{ q -]0,S[_ \HQILmWD1@]CKp5eZgh:/ R1c}0(3QwsiՍn;bM~ۺnZ9ZY(r& j ;p~%QoT| FSYHl{*J( ,;0l-JuG8Q3(;rJy9 "a`jE5PC↘# +]^Ea-G.ޢdpeDevE2Isۍ\-f2B3SHk@iž>Oߙ7մso\GU¾asdP/xFc r.k't0wQQ37N^b#rʬIVਧv<47#qy\gІZ'U)“j9]6U$eo,PfڲE/βoB ɾ_p9OGՈ'!@eN]%KF7c!xUW{TUe_;h^^"p/"* U TA D$4rkf+5AK˱|rfi֬ƚƩ5}թw>c{osW78td.t͝?'p(kx\KIv?oEle-訡P('L!)P=.yfhB.2TP^82QNBpome྆.@|^18塜kO 3DxӋW4 C,^[Q~rͶBo e&$LS  WBPݞ=Mgj[z1N/q0EQ\Ьם *4xªqԠ&z MX{q_~3aS $ ofo/c0L'i;f3t^{_ !ț *M7D~L"հ}7 _h5ž1|ߎ='C"N#R7'eM 1.&_/g^Bw2( NJ-,-IpKN^ܒ A1$VD'tz'AJ{ٞ4<!XI!HHM ڙ:*u,4|Kp,+)625V=-L6RmP7-iD6a JFĸ/m4Kʞ>y8XHfLzB2?3P-H`4iɝ:i{F |4Y9GS#wQM9K =MW2\4-+Y:ܜ>.MRa(By5ND^~r PaFdѴaLlANU< A'&Uͧ}WM2.(quۄKRMLܒ -G $FCM#S51EKol (YM?o C_wZ#~C7C55aY[}aޖUTB*tzr˒4rk>b [H+p[4B[$qKoc?bDD'f#ǘ0@ :fP$dMFSO:_ E2N q!t8]([d>[e&fˑg9? %Ǽ=D|d,j>;hґ.#Q6e9< G2Yp :KCyfr?PQr[a`|~fU#}aX?a&aZ@ˣ4k9)1 =M1 D:ZRS0wiz7k6,fjJ6,{x wa/?2NcY .ɏNdu>g^6t +2{>CQ'ÿ&1sV|\ %sLr`?_䶈f{'4\@\|a9Kl=RThC3gH][0A8Llk-v7pv7k"N7뙑FB!_.UvdR!0m2+[܇ KeDx":qqÌU>WrN*$*%ۜqbiV[\onz(_jJRCnYE+B\aW3ֹ:e8zv*Io5_!䍡N8ZIfjEJ?m&yd4Qe!Ӽ[g=j=I,=C${[H{ܠgm3tFGup2ah,)Lb;=Z Lb0& M1a=hZS۸t2BMM&}_cs~3}Xz|8Q>dP!a;N,;nuv_a8JI@D<{Sೱy,patvI71/Ua#E>nPjMv *'(P|O͠ cjy|-`!?(4U4rrWJrWl,*`D \3ޢ4èYBAudU Q $G-x|;~4<zļqLJzĭ=p8ܹGm1,e󐺦|G<>/PÒ%8T,(nR^4g4M0 *|pn=K8$^BQ-,V'p+Id ϖÿs)o+ʢ&>z2QY),q!SeO>.{,$TgٸIH{8Kh8XB˰`f]VI>sJ@tfUV.yg9 3hPd$fc ΪY)(S LDuU63\MXjKhw2\5SfDQ̪<m31xD) fƮ ,—JR%<^/dyFm;v>i [),J[BFX}Y`/j8sZ#m)|7גOJs o9?FKZ;Lqމ8v5ĺpĎFj=$rtu6C.# &VHP~h0CГm+&#N.3lmbRGIbj䅺:ZJJw~`e^EY GSwh`]%>tt_Y$?-]`Bϑ8˾ ʑPt%|>$r& phe5I+/ ѝ'Ԭ|N|!'9*Q]OWu1W 7Ww,õ` K;x_DH<4?,*Pvw6JtAha]+KQ/mg}`M$FY`^Y,G;9"ޖ#bO3Z |(N`vdhG@OYQ@Xh h q shg.C0K=KPZo __Vw6o+?p,xjp~-ň-s!ш3Pc1ZT4.>beDq謟6>WcnI(#rpnC!x6Š2wJeGN_N ٲh|Wi1m s[laX"Lż50zRZI21+`N1)C9EM)0B!JrDzg6,Gr ؘ4[Z  nR  {Bѧ҄W z1TQ2$P癱6N8X ?D[Zk0c-NӌgdM2`vqaђNAzt\E 0e3%&Fsv^J/&`ޫ]>Zkf0X^odU%uf>RjذT'h sl 6g4Q o^עW%?S _l9̨*tm TAAc|ͽ<ed8ߍ "M]{h> l߀ѷMfгe$2FƜ>fL0l۹9]QʜǼ Wvh\& {ф9vf41sݽkn;QxK_iPҌztjuZӁL-;xDMoA=fvPo=gqcM+"[> چ" ]bˍ]M9}D}&njd;zӪb  VSwc|vBl?W#X2w O6RzO61hu1X+JH=t\1)0`vjϗ%,33>!,WF^EũF"d ڻNcD>JZ kq+m"Dd KfKaڱ\П{}?q8+EQg\x.ަCAձ#Mrq 2X>:^E>u> b'ѳzdO'Æ#;~t?ٌAx262t51Sc@|a. ]t/4Dl8//6ÙG갂ԼW_zM^~=*t-B8~Wy+5^?-̅8?48DzMCWì%ϯ$JFغϮA\ߜ#=7%ƜŽ>K|uUB.bF\G]rX:Kȓj4F/BC@Py$ pYhۯbIt O<*|CdyyTrţi/FQoFo> ~ dRR>sT|X#ȉzn]Eo!u(psy1/+0PԠW*顼^{g(.w1;sh _W]Faű8N[ E'-q"&b]#UZI)%+]"KˠZc^I\+~R[ a?%*r'UU[B+nӜ҅[MHO wkj1FI~ՁeuRk' aj 0ަZN~۲dC˽U3ucctP,W/iuIP@?5E^79 g )6NX$-;ls1;ɭQf:vaW{鑙ݣ:Ԁo;Kp7^ ?tz}*o=گ/hG6 fr]^,.JN$6K&A۲W6qPÔUMj{0N GyW'OB j8Nv۲p@0O]5{ ._0FWsxL8̐u+: =Gd];!?*u A?k+*,%ָh+Jqo 6v Y@;)sEFv\rb0Nwjczh*ACq;h7KO2{NzȌ?WÈnIuv (dH{3I=—'AG^o%|4|T<|6Cō)8~a qڰӹǗd r#!/q#iQ=,]w7 :?zhC ogr*{xUVkPTW{$V$F1 T, /3CB "tMx1AЭ$UM%?S?ʦ2ym>w_;uy.0+DU/-*j+UJי],"%"<A'"peQ6Y w ܒXF2Җ^08YMz+DTX]֊ 5;ҍ/p3ˈH$4﷌-'CӚ e^5BkF6UUT!}].uV9O # i{ m50 baM.C2HIdZhϚZMD/Z+تg7N!*d$eNM/ cɅ6#ƾuA_4R0n>'"xv[xY /2gD`EızOmzFze&Wѐ5ODR Sm+8'=D`.'|x0H&zXakٗ9!Wk|%R |Q̊j }DyD ?BUtLj𡻜p#ثEjJu]X*ѤDtMttDz:Ct`I]x5.Ƴ 啀muVVs,0=]v˸qJ$~|E~=Hİo*|Կ^K?eu?fwGr9ЩB wձ3D TxG$+`ЦVl.BX:\"ܬ` 'H'5$'8<Գ:a IBU?͏2ȟby]1PM9r)A$/ᡈzM^yf./}#)} @JdLhL!g,iu,kmQ2ֲ)FaGVXDɒeYeQ7vlnn+*?\NѦv8U* }{7/k|I2r)ղRJ |˙l3!ڗ(\;}i']3WI]kn=! MLcz2*dEy\Z,dOuu{?9_tGh'pT$BRMO >LJGU]M|d-eC'OO&;T s1q6 P K-LTHuF(%aPХHy4 I$&>.U182F4]  p4]%avR$9\hz_Y(@TefnnRپG+ VB죟M&/D_G8D/$*l;'%tW& @TZI!NOyR#C}9%Py&(p:kN܄c6Z/.eAk¸1<=CaM[u&E OP!џq_# >hSqzv-.DӒ,^Yc&-b_hTFh"\bBZΔniϘtYl&F@:XyhޅgA伽yp9,ź{nB{lM=]j"I UHH=hU|U,_]=5p*(I#wКQlfckOVBG'8nuDxFt4h5T3WPjЏל^nѵT7f=^ TSK w}ݷ䚑|V[ạި&&}3{CJ(:?$ly/֟j8R䙫*c!g7djGLnR KvK5^kU0*Y%ɴ/ Ԟ4F=Ϻ4YD:%)#=֠6\'x68wӁ)sE|cS7nuG#~.Da oRu7;ЩNbw]S'o8L+~vXkb*'QY*BZM))zoB>BCKoUCFk#Spg[0I/8)iS\8a76,C{ ?i`:8P{IEL/AS# &M<.D>Kc *.6:gh&4\( 3뎱S{OzutM-Wؽfk֌@ $ @Z:6TtlZzZ.E2P|HX8Z@j vؖM>%gUȈkȡme[\~l͛P!G@;xqzq PyIc4bNKm|~T1mS R˖^x-l WE3>lT"g 6-sxrFF{rX:۠U4h+y@G1S RdH7wh]:Cg4t iv gcAJnnk/ou-{_7ͯv5#[~G{TOOtڈy<aT6YpHдK,)`蛝 tg`4 fjR *kw8a9E-{8Vb0H xЈ(|fxh=}%Bʥ Ќo%MCq֚bR+<OݴŨ#D5'-P$D_MGCo_ڪ".M!}ZCgӳOLnuRVt!#!R9)jfz͖ϟ 1ssQN(II ^rΓ5-}dy;s'5@'DdDz%"tWu3BM I:|O/SlD˧!O툦+FHr{c;yJ+.O98/5Kf1 _MH^45-Nt0xz9^H$wlA twI9r]"\/eі['E`/j.ʰ p+2 GEO37aBzvrzj  ,@{`6T< FX2b%75NHz|hR U[\7?~M*ս342hݙEb*+&bǴl!+!lqf"K=CzNj+6*ʌK0_ ܘj;wF&>HL}q3(VeAYJ)jS 2-6 ˡMX6>+_Ne%[v@T_t-֫\pfW @m=DlZ%qcPUŠ5n9ah,GT1mJEwCL=iY4Dc)0X'X-CJcB Kh+Rp[iþ.(c>9J3(gN\lQi.;|ށ{\4(e zwmsGrӒ+S7+G5gV/`\ '#2yCYƨツ?;2BܼfzSqNȈ9 \C?ndùk?aC[jl!-C@u=rl,ڲ9 ַpÊ!ENLӇ~󇛖 (&aB39SH!4`‘%:< }"wiZGek{6=[H u S s (TIi]]GQ*SbҜm2&?}rg˜pqVb1K! PPIԺzrX$|Z0"3 x 1[jdRG\!c$]+V0a;#C96uп^ '1m)8bXm1Ktg,,;'' t64F?Fij Xxr"m@8hƯlY!</W y R;*b<A#g9Ȑ jXv:bLx@ _ܟVb^*lSk6W0L3_MRw픿S#Xa]A>{C+em^ßɴOp!DcE~ff/ܙ5 P4X} `ҙg%Zz*P̶:a5LC;Ģ~Zt(ף .G*-h U{+gE(|aHc@_jA/=y*@} Y7֪Ҹ_AuK>Ʋu$Mn`lMuZu:7DMX4L}myQ#l_>n}`Vn15r黪@Qmw5:yyaQyۆP8@9j% ]Z6whn@Wo3=DAU*AvŢz8Be/>=Hy{JGF^V`!o>\ǺX5|HAKJp&-,tSdvF`OxA_&r\_]wd* *X 1@+*Ob@ksW#KA0U%8J/u88g;'KlK`Q Pk>O*;.a2II-gj [AZPJ a GC T8KeV HA +̗>ծ ,9nP):~X e Z̒גM4(!\@#9L[X۵ >l MW4gXkP}bk㙜8.噣d#uL ǟ uMTY.-2b_pVLHcxȈ뀯lZZֹaM뛚1;) <1 5( Vg3~NуtǕf1Z2#q5BJdd޾o-M"jmbހSCgBb1̵wT8&hc_u T.Гߠΰ4 AkG؎k9']RdvC|L`%ba_2Ƹ< VxqC$[ rvnڴJu_~R H!_<תPpIckkXUDWpC".pxB6&S\MD;qw6g_yV%QH_Q/,UI|wH?9*ϐ:ucRD'SoUSOmš }ͼ*;j}ђUwFRMOCfXo*O5yFL ]uL͵faq헛sU/ėV1/73/ʓG+AtdZНGOcsKc-HR^[n+n/68M h DYg.?ِ_i\[8myBǴN"h!kye#XB5.߱r b|pöm쑊lDdBL0W$Jw>Ӳu̶8!f`ߚc3fr[g7*qRD*||6]C_me [ p55B߮=`wP92zxmwo{;Mz7}KG z'䕒96_{02=gnԤ %& J0Ezu @ATHi\B?H/^?r?O_~j;=thŁ .o+yoLR3yiz0J{\E_ /Nc@+_㘽}x3>?~x.A-v Zt\]_^~cvdjApH$qЈuX}T#^@^q߇qj nnQ/D᪂9hk5փ!qQv{ EƠP:R{^YJp:xvD2}'5G3@  yIŇ'fU¹``Z;!jX\>T MIbﶷ{KgHI~yi] H=1EÞ*) "[֍XZwƗ:H!w >(L /u6ڃRJ&u\ViVW }pd'^nZ.Bkz| de'>/7,0Tk/Tك25}\mXS`պ~á3FHh+_ֱ,іnWC0d#kʇۘ8oq; yEByD'.SC D<*b6jg݁ӗ[Svj뚊w/Vg?o?)Z#OJQ$̾M  JwcPf os@մz$RBGn}XR>}'/){ Vu+;Pq#UJS(ӷW@"3'dQ>¯Ij`3Z6`@sʄDO!њᵗ}&.V).:(zB O̠i ^;*K~>A=O~Zc0%dpD1̿t(D\h1"4e cjoI]`]tۤt@vףًg {͋q\eߎ7j7v^FfsēS%?~ؽc*0H‰ṚKGin_mﭮq%I􅀬oy: ~QZMoWc4X"v#{akB pR}>;e)b4):wbx3?]2Xx9Hʺ8UՀo1&B<,jY9nֳd  b I&"ZAזSǙEq}1^g+B)I}i-M`{qW$H ,0h)^gdu!dEg c ֏<r/Fr*ukSeaX}ռ Y&`C|*zOR*Zd*PA^%q"1'@WM3-HG&cY  FcDQV<*N~0Ev8^N2aFA `Ē8k'Єd*g]dE-10:NP|Tm@2P!R֔8O乫yOڬX)[ [25^?qO5V*X8;RԛNynFЬ Ţs붻: ^䀒[lKFvsg9qbI.F9Q/·?8}VD> |u2BV Z̺hĻ9ho$g fx|ip\ǙXa$%P E$07@IHP(Q"9 )8 IRHHp;dsV~`Zm+&ق< L+rvְTNUMɺ?_/vϰR4"$)᪮AS)̜HbjPdx(N/TlXHi,"T RdLMMNOZ_4jK!d{f%g b*i"IwM*J6p.$ 9q~1WeY5C::ꜜ>O4Â(dHBLWY<)"V^/ȁNcM9]`p2 DjFp2ȔYLiԈ4p|'9LA+"FR4'O|JZSdǐW dN/%s.X$|ZL.ZUX)H qD, @1p 9oHзDƖC{ 5 "EN)"0ѳJ 6x4@‰&s(ALӡskΪpy|P".rXLd #I˹|HJ+* Z7C~<pDCH4ѿ_1>V3\ކ}بX`s`[6tv/a[LQ _a! =_?0ѰWa_-B<oU:fTl[fܦcfGZl`6O7# ʫis^| e50Ypy&S`ݾΥz^t?ѿi\BO(ً64P:[[/w\1J`PEKnֿDR#H,Llh߰84.48h ltLʬy~y0:,?qĆ2(x*_bD_hjZc ~eӶni޷5 5@%gpjB88ZT~4҆][F(Pʫh6|ݞf["y,YiEC[yhk:Q4@Cthp5| zֵmZGo{hSuq}[Qɜ`pFgSMF{.SH+n<1=rWv{fb(ni,vS良W,C& aq޳Q*XF޽q9Jn 8dj [[m(6rN=HzOK~>$Y#s[ld V([Ce:kus?{8$oGۊضue'Ί$3D?V0R,xR蚪+%#F/Dm'dZׅru7Ihc><|n8|iwBĆz7'uP0Q1rO fsvDh<0k%&7Y'v?sӍ;6pÅԍNe1}BHt  35@V.-_H4>xbx\?TĈ\68y{i,tmїf(k1 ~,6}ZŎ0-`X;ƙ.ƫ^DOL³jq,w1Ra$X/tg|S)xְ/8x,2 ?1_Ƿb!:Vu&oX4kHU"p\ˈ#/hpS)ic4i*UhW Rf#k1*̪!&{"2v%C!zpu!m>8V1b!j(wa1E { 0,s̶ ׀B VDŽ>^ pjnN;[hl>%E0`fQ q8OTV燬:Jvݵ(,6ɟ*d[ĎXG vxNŗ9#脯≶ սHz^ O<ГjJl 8 .rB yFvDREwʓ!#,){,p\._8Aw߽c S8gGwo8T5-c,$ꦄ:$ȯy.W:3jgэVifM~@KUVLͫO9gh9z;IB_mZju[͕]G3 0l䔩qc|?]iN={+dzU˫uC-F:_jԍ9>":Z_&ݴclxt!'c=D'VՇC9%C#`**yp_3&E~GbuTJP&s:q HSexҎɵ{qc)*KV_O<3HNc\;*V_(I+sz^zHCs젚4exyp^7N'+.6 /d=#"c[u _[a ۨID0JxCNΗC ikE`f)H;\ x7˩Up^]2~ƨxr/ 6KG/)OtS,Ӕ('?LC aLVl.X{{ˉl2?}6쩥v|Y nJ 'D0y_4A?m;I+6 Igq* \GVH): zDO yu0jV ӟ?xX@yeD)wӆA~޹53wݒ= R)Ţzx0Wcxݸb͞1yngR2L= -\K"v4P0A_}hG2@*1p,L[kx>:gf?p'N;p9F< ӎq8kʓ'| }Df>#)jv v^%^1ʋj´gz3ɶ͜&Z^t/@"2Izd/ɕ|3U4#U3AEAWg+$[EfQe;v0'OZSxt"}/NwrO5s 6YˏH0,0#k5XT :j ix邬1`z}*T3 Q:`%Szi .b"ʎCoH=IV2zzte8 .|WL,ВaXA\55ZrUC K6Xɹ(b+Р?yQsIZ6Qtoǁ h~s"L?wvS@ICTxZvNMd/dMTشnF¶xKkl:Nl9f·hvlN0մ(GLȺbN>֗ RyF呍;W/?L]yc{fE()1Hp֩uzT@4I!U-}t1[R!vV3N"Ud@puA@&B=6U$h6m.ZlϲMwȓxU xnN&D5F?-<  KbOJ/Q~[f~/+CpN|"L%T N^`4a?Q5{_3 \]%6?}mikg{ y@"D'n'1왾 tf >;D$~Sjt. 7]YߠV,7Չh&\p%AڧJ!x7s`ҦR,[pkbDmH[3Z wNA~{Xxdò.|Ʉ$L #}0P$ c"(#^p}KRXJk<ڌ>Fo4t_nԿyӥHQDȧ+!==8[-,g)ٞ#1Y)X?"Ŝ CR˳;&9TTޏAN| -*2K*px.0#`-Y\>J ?/lA^u'\"Kz [,2,\gH? @J(d]epm"BR 7v }bɚ6b ^qx!nss[qndۏwXqY%# hK??s낦h:fׁs6\^LF!{ oOOw# E a>폄﹛Y;syJw#&ϱXHl,*RG)CDS^_$̘;/o*ܼka@:w -Y.ŷs`f8{s7d#*i>/2@Qea_FrYKS=_ݻCSsdf; :W4y=Q0$N驆dQ`; 鞧7#{cm`%f :K4 = +dzpi~{Wȗ*U9R-RjE_~u٬bלe jQP>j<QqyML|`!!ѸNΣ"DUo -xb% Ep1{9`CT t g- 1aYbWS ?OIJh]]2 pXL.uMΩT^]&/b I {ê>[ &eh"SؠT{J? !}6lTЫZ1ZjQ¾u}5l!q n+%Ȓ!NlèϞn'#a&Yt i&F=ɣY_8ʣ[)?-kd-DRh׻jD#fX>a3*O Q7Z}Qg끽yf: ^cVSp,ɉ9=T% L[WrV -j|}ݷ&j˜-X1Q%1)5 9{m$L[R-&⋄z+omgbr$QOlX0z&|>XfvK/8 =bj> 3O=\Ut{* \=w?&|*VV\饯|k|PN45wϝg ¤ ZƉ m)Qw=>#vM셆|`A $^LKS hP ?>G/'z^A sVYiu֮csz;4˶wx;=^v M@oOՉBp`fyXu0&&g0Hw8c̩07 +6J7WOCfm}T@\.KĘ`A?n;"))::X Ǜm=Jgzk'峞Dwi{vOM",XLRa(yjb0}108hMECtؽ j˙b6bwE?  ֶ[r@?7@|H΃WrW'& f$!2Ȱ$Y_C13|*bldw[q'^쬐hK-#8^j‡y}'RursH,D m \G5 H|W;H_n/X4|E,57.շ:&)&>.);~@{b=:)auD قYE)ᓼ8IG2ᄴ,pD{Ӛ;J vW%Ȃ"0*7.2.JXdCEB݁=x 6cwu._0B?&+ge:=h_].`)L$DGhdK(q^nO>WO]~2%?j~[Hkl;f*o:rS*ܵz':G-CWdx9~lw7wvy㝍=+uOYyth[} %=vsHKɋ9{M*>"#&Xp~)n>.!*k>ݱѮSK_wjR kY~B q~ϸ q?QSo) Ӧ6ʦs3#Z6%B6rzZm{[kўQ4dEꜢS{cw]L㤶P$!/s`"N:!Lç.ڢQt̀x wDhy(3"f2Єd/աKFBncq Q,60#f vyJFBQMvŠn8+Rl}ޓƟrFaQzbnn|R(P\v, v_a]TJ(;t~c9+..V ȝ rJgKSVs¢îVbXqai9BzlYce..% /{lŎ&,MWz9T=2I -{I\U2"e+8222L* / \fͥ +K N^eM3bq]KO?H9%=n^F) Ā}䬪i$_RXpbg3{l,qM0M- W=,Q3S蓘iˣN|NMTu\7!SC؝_B_ +w{"=6Kf9=(Bu~E!lċ3C^[*DlT;G-{nVrO!A"nb'薊+5H /M)S؂EۘmJO0Y2!ƒ+Ōdj픍 ;q\^\e|<Ⱥ("!E}߄W -wv8Q y(b9X\inc?f?|Pa}>ed3`wnkrcF!(?E|ǥS+]Ψ oyBZnȎ$FDc,ƎwH:v&\au߮Xxwr2J)-ہ(e]?o hY^pET3 -D?f цԒgӲ8Ѻ`~X^_ņ^!ZXyߔY)pkKXX2R,|{8JXO@ΚJTZ'䴒_CQϳpNPHF%+!<`6@ʏˬF͗Z* KG4؂ΨZȈnԱw+ڼ+;t!vR嚆S2e'w.{=mvoygG)UK9&ݫ;\\G Y8 BWsV.+mu'tcҡ /z2s[h 6BsyY$*C x|kp\ՙ`[~ R_daI۷l˒2 s}$]}o۲oa򀘳a(Cxd,8ڝc&If6aT1 }WZ2w;|?DaTNdS!$95X;;AyD6)]VljzpRIi,/銹$ܢy lVV2})-{Y;El_6uim:QSsB ,گ;t0&4^Q%ugaby)ih;|FQSD5 %%i_/ 4SaH81ŊdEHarj`bjjdR )(*!b@>Wz3?U!W#IOl.#v9YpI&C2 )^5f< p9(9]S k s4%҂ 5؈:+h3S1ÔE/p Sg4Sa˯rљb ,vI-/ a(lG?5U }_g#8$M"\a^Yy~1$&)3!dV!pWe 9.旗>a 3П^^bDI^z- (&y Jb3‚Қa !<cS9^"Y!0G_%|o>߁R8j.3  ՘#1){И5 mbԒBqc3Ss2y9 XljԨ;3zF>CAd^@W7G60@L7Ln5##1~Nص . )J>i 4 0 Zg-$6w2=qк2YFb}T_ObH# =lsxGG@Js+EiZF8=A a+ǺChop.e-#VwђJdk~I謷%-¯^kIHVQQ8Yvu|#:[3Xv,p3Nt<l@炡1[1lĝuam:~umBg'VkRԻƩxl@j[ kU1ioq@TO޴ Q~wp޼H;~K?_OG;CyC1,E|kGX.8%MOz5jL>ӈq7֊T^Kz#ƥ>д1y"4}<"ҏk76,`<^ x[6yv@=]7Ep2%c`tg ૎nHchtcmOnn>?tLt2ymiod'A0@ۼi%q[~aNff:ġz0&{7axbV;8u<ibh TFyn Ha 8w|t(B}WR>)>pkCtly:\8(SDeHt ,rn3Hĥ'd8LO7o%BO)L`LJƺY؀i* w9I"Ȯ՝,-tFKب`ED8?j[{ ` 8XZ = ,byLѬd2ejP;$ln2TŹw`+isNv4aiSl%U%u*g=f%HpTT`:Pka Q}a F!w[c]zˈ8qS6o=Zh-M67yH~'It&ud68r&q *p>sd0ȓ&EZ9p@rEz8=@@c;zzx=/ m8V3b21c-4{ȎyYo* m0 ГGFr9"?:vP 8Cw ) P`: 4Ci Q)S>Y^ Daq,0Y1b-óJ/ku0frD|=|[O̷pfR/ }NgbI>;@ر{{nl-?TC 軫Dx'F>\ txד[:M'PGpse9?Z??ܸQjjQ7MN<ODӦy=s`x3# 5QWy";j7`$& |G/gҿi#FZ]#ԶhۮST>'txn8iGw=p8(-H@_48>TQd ӻRrLɷ{=֎{`'{k 話ۇ3:94zvz8TOO/^=#,?b** ]P\Sm;pVdZ*b^z3[⩺~kx88oL:8o-.iSnk2[+B3c~]P.wӿ|o" EPe^0<rJ;G?"0/1DB/f% ³->17j>^x $PoYYOTHTԄ0?*ZI-C,p9=WMTI+."Q|xE"Lm'1֮Io!K,0[r(B~k͟~KZgfT79S)?vl8ir W%cu};0IhՈ5v hl&Z0ИO)]FlZcO@g3DXY"]f/hT0 .lp|_mEIL gu8 EYyZ4t]oc]ZiFz>XAHt՚ap4;*sh.AdKBcEԼWYP5ӹ@(&ǽ3 29elzWU(:oeh*E ZѬs+sъ^avYZE)Kw"0˟mkB)=Ff b!?IKsEsD>ʼ"gVՈT4zQLYt~pbDzv?h**Wq]3+B|Jd\Î۠E'mI,X^j6p".vu؋n6D Cbř;%FjO*BesLb6)Z_$za(2@wōo=Qؿ92w2b4UaudD;>7 Ɍe C#!q<V=\{/DNǷ N >QOeˈ,̗Vؓ1kl[!#A%$ #ֺYп~Fh`lZEܗ!XF,Jscg"K*ûj5 i}WzIħm[xF0d/ A_b`[qV˗}Qk0Rg6ggdP$9R,Ʊń֟a3'X`NY$~>O[~`mˁQv7ہDҰ Na@30YcQAI^~b(ׯmƸ{:@cmnAGb0cZ̹Nz3`؏w?[0ؔQ؏: Io,x\{5yn|NRs"gRZjai.Q^<:0tAPYUXUna0x5vEg4|f+ ?::G}Zv.kڷĿ{RپVzhdq0[Q_فFPD;kSu}yU{i{6A\>u?}lgL'c]^V:A|\QIԎYcٰq (ǟuۛ߀@1c,t{`|&߯y<䥿{%qOg&ށe[+Qb ;樞7m>"ě^ "0.,93nq?y/v < "?uPW19;n_[ʞUMiovxLZ_?HZujv?۴ur–I: D ܫn_<؎ŏn7;jTМ>+Їct%Cxl%ǟ VZ e\;Jݠ_>TI@~R~OrnH,LʳG[$RElg6J|SxcE/  - ;/76|;'|O7_B~ӿ`Ez5/kYRf)x?³N|^)\*׷.F¯0@M]9R ag!&LbEa"u kPB4(ݢ!xIi6R0,| */BO}t$DxU"\×U>((kIB hhU vch2&mtX 2y[ O.F!Da0Of ; ]Ii@'V $ kc ^܎)(hR+jf}BCtB_?ѻKJ&#L+0Ueܰv!d|'jyZ3ҪZ4NhYWY2oql珷ڕ5 GP<5lܸa8p=bCXc̫VOtEg׬}[YBf8hb х* Zzm{n+,uK#OEc]֢e,Ƃ ]HfeDuL߹uF2b֕ΞM=CVEE̎r4rLT}̻B=D=Բ?mn/?@SS jXa>VAn,<~{42ER(;j&̳y&iP|L\?Pl tYmE9`4frm?cO-̢ lg)iL`nlG&i·bL(j*K9TqړnZh@}"]wuQ;c2:=."r9~"pgNi'!%,UETMSJآuMïSD`CTԫC㻈$SK-D QcȎ5h*W(LVuIi9aL,d.u4pi%ɰRgu \bt៣!0"_ϠI' XGQFjp)5 ֎oGPwdiꀏ%>,7I"\.P99Gl>&쒐`'Xv 1ҙrĐkHkpqĈհNط2/npaT8~­ k5W?X m˩)5O#Zu]b׿4Ԕ*VC_,`f`N4SfVd̞^][c:VD+߹ o}T?ccp}8.k{+ƥu"0pb%]`[cJ]a]Ϣť`n-rL/M~Ǿ6N*}+6;,,଀.sCxa `8< !p]~=p؅0 \ZM·./.iSuH5"ޘ/Z6UFTEMXLJ㍫J\sx* #EyĠK&r$Mz U[;( jA{,i:y05N޺)bMK{_Ԛk~uImэ.ctFSQGhO%{9U,VԛIk& wMXV.6a+.sN!X#f;Zכw1~ٛ{{K{/ljn>3m\N0C+i#-V6BWfx=pb:i`)i3Sd[+fۄVh)iz Pv0\2D@b*t=%t]IiT_UXMW<,'%1G _oq1 Elyk6_ ]mg=fzVdO7(?w_?Ilt H0w BBl^ޤzXmѫ3`h$HĈL&\krC`Ny[)S%Aup$W/I:dћ[jB@fK}Ԫwم9m^SǎLD^efE2a#q,vX\f‹9-H8FYTA9- AC߃U8\[I}^^XK6M[c 4:=,i~(Q3欐\M`4ӑQk+9I+ؐ8*ѕӛPxUWipUUwnTxYl/}H KBlv! H@"HXdƚ-erQ˚EG?{N>___ 7v.mPh\>4U4ͦ=Z51sL\)q1at+7>Jc[x4lr v[>3z,qfV+8Ѷ,ZOmhs>ZNڝ+a;\; MoH2* !00>Tπsa.G_M?xȢExIQcs)Ssta*tx_ϊUJ)R]bmڏ.3]y\Iҹh6L8?;7Jo䠼gL _3I|+`\ WJJ԰9@̡lՔit-_6w{)ĕiЁ-|7gцڳoҗZfœLW\LYey/ׄл nŝAu=.̵*="'^&@s  T{O;3o,`hE]LIjś@,oe'6r]{M7rhI:۶biW@~ ,ty::d֯uIBBhbC  %N/Bgd!%5B31-o⩲E=ߴ>hҫMS}2MI慸BDK"8=eC-uk҂0ձå8jR4e,˗tE˖)}ygbng7[eQqPJ/Y0M};f`*tj31]rPC 26XSC!z2X Sl7 ba vi zdGv$!yϬ7\= #hJR]CŖb^rlMJĮt [K` <[*J}ږ0EQc,m\X2c~uh3a1Hȥ0Mt`Mԡ:wi])MWbma4f eSϺ !:rCί1dpuN6r;3h\Ct&"c^K6gӘ:'?2leSo[AQǐ:z ֫NCEp ;n<40B28pGX.r㨫8'?㱢uɣ5-}E 7!X‰,+ '\tQF)|^UOfM1O˱MM&eQg'vYxw'vWa0 6eM$"J2 dBk<^HQJ))xdF4wiJL;0 :}a$RᥙnJ§(1 3)/U> ǧ7Τ$ˇf@l!iE4Qpu44gEHQܺdLN˨*Q8>.X2OG];U?WCPXmm/_Μ(_?oFWCI_E =TQ;w'ag*@ΪipX|8 )( P0gq,U$_]M ~;Hǽ\ Tsx"k  klzt0.ٍEIH_yUzHA(,Rm0rpC-X,M V nmwBZ4w;uNKa1?#zCGK68^ HpzA5E?.XdElaCQHVԉ{mqвh-B/ GƇ2l_\iQ) ,%[-CKq"aޭ/J5q) Cx(8L&[Ku[[Ss)$cQۂ沣nGŴ .F}'!5V=F:?V (ng5z.Q&-[k8< ͖un` ety4:ذqxoPGLİ>?ys8Ak%#a(m`+DIu~@\ɋJ=&t{p&ORJ[V AmfoNht+x KF rxND;~3Ȯyd|l߾so*+M; FkÃm]hj2,bÎm*dl>J l&집nirc4Y!C[Kc 31lbhNnn)c4-lݖOk*3Ϸ G &]K M & ?(Xatɨlc-%6Di1% wTᄄDݱ$f&؀dy9hE*65 fFC g+#``/ݵpnK$Dsy)CƧT y[{iϳ,h`Qܳ>.)Eh٘VLisY0xJ˷] 0}2>g dߖP@qf/Ϗ:T1=!hBłaQ9i\H&5.OҾa2]{6}"d*GGM@g> /yr^+tXzwP2g#HbKY1"Q9Fiی35UNFij#?oQ'~tc,Me8@*ƒR"cMk|ÃAшVqt.}SRq ;JkZɃ0GU#e.M)s]?A<M XKcc\jkçQߡ4Y6<3~߀;ʘJ?d8[sخ+ ;D], P3 EAҢ7 Ѩ#{Vh"שY}QAi MftLg`M@MqI6^ O"8ė_<Ƞ7umT'i5n"|CrJBI],|TbS(@s¥q2+D= ohOIp} ) zDOZ)$ϟEK28™11"Pb օ1bwR"fwxi~w4Ffo> /cjDYasDJz8tӥRӋVH_J2jZ2F#Tc p;[)YMg>T:c_'YbdLY-M=2<:zӼidȡ(`4t%nSljxXh`LRVVu^HhV8+K]_SҡYxχ*t,,Կ&|~?4SScxtNvN;&RۙN:BYƮTT=5UU5@eҲ� DMWP.JI+V/0Eva3qXTT9X4Ar>KX$?3N4'ۣqL10â)j`)ڦBF=d;gg'K2^PiVU<)X'AH'd/ ٍt7'c꒳iέ-`rObMKaTY rSL0SZ==a,&%&bD^3*m4nRY tzܪcAjt3nu |Qi&t1'oL6hrDٷXa\Jkh ׄ<Ơfp3ҍ`DV*m]>47qKw\q&+NS~ѷh'DP)џ&ZǶ_{;n UGU_ƘlRc(T S+1Nz:i'+Oe_g-琚Nϔv0àHifuPY#SeJc#p]f6QʫhfjiDMݠ[LScj9YPWBm[$ӈSU٦O3ɢEZ&t̃DU\WU=Ru,nl< )nQi !ѹ@#7TAjvræ`m Z3X{;PWS[,VW Knh0x}["! m/eWILKJMA#f4G¸w=sijTJܜmlҘdciLh鹢&٪s [t3DD.Q$tj^G цT^txWESA<>}{x8Ed^͢#;7#ߝ, CpޖdItт [|l`6ZZMB3Dk3GO԰7u033h$jLgJ7΋*!O ݻzP<}vw s Z[? ؊Y.^ۼ /oI1 cc?h ގ#?B> {Bdg/+9 X[R `u r " DAܷdu Q<1c7*XK8DQXnt7Zz̹I p14')Px3іTqY:sKqOcM El\q'2L0b%i0O{!ΆdzySPտSOΧ !<{ó9jxFν |!,:pw ,,җ߿%y_PW f>l7҆ ke / =.._lItbS, U?ş Cy(m_Z?tR.&>weۛiT|/>D'nïN74  ;T@}2;03ew25>4.?Pw].$pm~;F4d zIEJF` +:!H>ď'o>p<]=r]bM;F)4p{''Snp QXU߽4[on܂o6RMGa#kfS(-5Z֏cE@Rn-Rr3=~+D֊hoQNn WfjS,CGQ!xYklWΚF Ii۴USŸ;}IҤIp8'Mrw=s7Xgiƥ%UZ"H,XTJ(BU%"3;R%wϽsswΝ_L'>H "E[?IᬔegctJf' ²!vb/L7tl5רT*j4M`2 l깆5h~r\l:qm %°P%V rWin2j&ENyV|ۼ@FYaW\mވ p2˾(Kc; F=S9^l:r`ێ(q&MQp 7X$yTW#騮gj+.A4o7g ̿Ḓ.GU4%{f(mх(,rJj:ZCe8, &jl[wC"2MCy!b/8ڙH76~,M$[ +r@Eb rmL?$dTJB"fҷ;2BFbe2ƻK vĮ涀Ybc"6fTI؀4 C,JڮN 6KM} It.xxsV7>AR rZɰmhl~*4w1Ş?AJ1e^ٵfO_4k5(JCHlDu$HvȳcN ;?vcӀTPR:RB. $ϻ>z2eG+M+r|\ʮ>IMeZ{*v|9y sN㠾s 7uI#a8 t\x2 [ndV7pl氫m-Ȏ_/yv\c ه~vPqONA!~LAzyb2׍E0\ wOmlTQeۭ=c볷&sb -|ajOGI>rfU?J9hR[[>1%)l)OP3,o&5} xO UuP A%P2-cB9K/ׄ\[5Hf=Wȩ] ՗5" VeL>*b\.ON ԥ骠]U=W;/.x @f[Ju2Kμ2KV|]"2] gY4gAvSObăb\%Q04 O&;Ը:7rPbw|v↛( ȞckR1q;$uۥ.uAhEXiC1qyy גr:3I(5B`چ}#ܘfjajny\ xs~s`OMoI;ʷ7pMצhL]&wA+ܸ%Lb60$w]h$4J9KL]ؗ)f2zP iq i֐f=>z5g!f_Ν'n븇5DNƟfPV)/0= Ē& BĶ^'A>1F 1 e.g!JHf5CT>.:1Kqf@%|)T&ɢm5 f%!;3.}FvŠ]Xs3עˢ%:'#+r,js:'+#E݅Zmm+nP5+XTŞT}Ha4[]+1P{0`.ߠSqjxi[mo~QGشv!¦I'y[ku6 -Cl5PH*;C[Z۹C}/4L '/Aj-\&["5#& \1 k1,R`bԨmmmL݉U$(ك/c -Ͽ:(.brxnWTjc:W^.OoPU PNy藛-X67i^) SkuI_[jsF@{:.οyH[6\"` wo=Ai<(<9 kyN3Ձ{r7 |nXyZIL*1u\UL0yE*i_vnP a1=cas\ [T Wn)F91s' vvۄV-O`=+lzٰ&@mA-]]FI! V G1CbnAhʏVʶ=1##䢅L7 i۴|qb`:Cvj*L5HRp/nb*PP]v8l@k\A=% @~qTt dAfJ.y@R >n8%@`<$BI ؤF$s hPU)7gbVx\V1]̿\.9-DZToLх\ ]ZgQ_bhˡl;?/LY?MdQU\xUWit>JX$BHH%`}! IHBd'!5 X6Ia aQA K@SmmSOԞg}wwg+8W 3eUյkj*Mծia*m,M Ke1N2FA#BiEvLGHaҍ!BVAif>T/<}_?MCXƇW f1"T&N tz&lc/–c%P>z>$ 1aشQjˤ tӤΡ%nF(eaԨrX0u<N [GK0|3,1$X$ 5ؒĈJI݇{cQ!۔P6),KAAaq(vd80:XRF{;#%ݑՈQM26j7d'*Uowaԩ,d[El8NnlzmW免w߇L7-Ѧ7C:$]ZX&y3pLUgן}.;Fg߁#9U/tl1dF%0 =|F^ oFՠ`5)nlxpl?Y.E U#f!!2B# ]V C à`ybiN.Lˡ蕒@xBɁc0Z !3CH_Lс48j8#|0!K3-&36 Šs.OO'ѝpp& ne1BB%U5YG/ %$D <ۦx9O ZNI kݣ4ŷQ&^UqdkO$N`rJ) (E S XBKZ hD?Q#36 NbυҵX.M[ TʦMՍ)smZW|}N ܡxdžd_78" @ S9);ڂAcLFj ݠxWgMj0a8،#K܋ߚqђ8s IL ^Rq%<,)|Ct!KJi)fJк&⁳LMdɴJNI.m3'3RGd$i(F]fF"sݨLHf&ԓiѯ14hxF 2늳,aV";;Slv24΄/Y3C)+oZ\;ќuPV/=L]w=,AИ b)10,ډg8UpE2e>\:K12戀j-|A(E /;f׋&;b`GE,$@gP d:KZcfس 3!/ZB5H/,ա5UHȦO ~+[)ܢBzyd T$-uɮIϡ\[TZ(jfMUe7 kLu@.^.4~[]tjM][\x]Rn*765f[[[*eI8ݮ~޺d+ݬr^[7?@ulNӰWKK$]()>=ދt F=j,eKnW QS^aZ™|I#595h&!yrw .^gc409 6X`ն\.c["5Y.Ö3}(0vW[GSmE\јrti?qCC@QtzwUjvO\N`}l|zplMH@d(C=M%XX|yO)Hֶ2Ft:Ѻ&:= әMeBQB36=s'#M1(2nh /aN_mc *޴3OgMMaفE-YqjxRo6&2#®`biOغڹy4}^rk sofܞҢpC\3(>ߑO@|//\eAG"QAv?tCH 7hKM\h@ Sp,C0t,nXC[\3v|+v$4hw27A[ûAW|}=$s/CuftԹ(O% _*H[Z-覷/6}תBWYM{*ZHh.2*$gw0SqxL~0}>P2;uɡrnVVzCÅ+2TL,G)B\卢wqѫ,tNҦ{Ҹj;Zhk8[thds4n6"cJ{] 4 8DuiȱHBqW/b>^8șҕCD+l{"  D+tq2?擝|!_/kdXnFis㭸VȪ? < A'#TlvEkγ7DSa4T)"kO}-E&n).nhK Uo^z+gxC!} *[sv69g n|y6+})\)ιŜA&~>Sw  *PѤ_Ѣk0ҟ'i@1Z4Ѧ‹iݜ\?8=< [qiznj/%s'8#xXipTU^X%lt^l o_B$@P $ KKҡ_ A bAEư *  bY35#5j8rs;$u|w%kLkdؒܢiD|V0؈.-0nIr?Pnt_{ђ7P}GwY}Q XuF0h=:[3C~hm9ɺ̩tJ1p+C5 'LK* t]I* S VJS=ٺ#Ȁ鐙ʉ( 51ۘ^N[Tu\ς_J]'CD\ρAO%,` yF)8v651$C 6F66OcҠ}ܷ 5t6J6gT 82Q9RRO:c_qF2f˺0n_*RIZ[2hI{a8E%6Gck#i-Jk H'^)XO %#gJ`7o;xbyf5Y #`RYnqe#`mKprr=2VcA{fFPy`b+a;.W[ᛚqOgao,wXp/gYQйn Zws  +-@zϠEY3h [NH~Dž۾q}CIn |A_>1CxHLY &7<Wua#(D|_UZajA!HimY ղaҽ 3xSgo} Y' ՛}PŌ?#J985kא$Jl_ v}A$F^X KJ|(ѧP;t|';v}ؔm;kE=zYfwڌ3e${K^%acxjo3+kAݑnYE;wuܽgfYp;x{#>a 422`PXǒ"xS^T`l27w2uz1BT;dh:AB[ʶ;?9H fgj| s4^ w|$G=T AJme )xk[~Y)$-~yFp9R$ [0šFB#c :2*e VkR )pa0m}b*{@ .{вϻz)<֍8p !3H/dvǁ/yXuL>=\;8 = 9rIoH.xSqRbߑlB9GF" R۶X \X~qL<46Ied9>-]dʗg|y8w Br8-lm_ N(%Oda:=Niz)xrŸN/#n9L/κ,hHʳ?NE≤́"~}nW~q7^YE,cRp>/B狺iI  (z« ,_I\B1CcqPwIrw]`ş(:/m$a$Yp7 4]`0p;뗷bF=~v]!TT++Qtu J?{u9Zk Q}: &Qҍo[oiǛ\?z3_ξr=N_p.st̅w;&)cnjAb7)=Q8>P&BxEV{PT{2#&Zl3@tﻂ,(/@P ,dy"$$[4;ZSɴ3mi y߹;^u- "u*ɂ?Gml l_#i[穨*FoR5" zH|$1$WQE/T ^oQFsyuqx'WNۈANw:̭1!"֑prͯ8t:WBJb[)Ga^I@b;Gc-IEB5" j+6iN5E0{7DT8 By̹֘qx@EZ©kj9_h%RJD-D0HPF5Q).qBе(Ԝsr?x)%*,%z:5Pt?h}Q[ 38#28UtҊט2EhNnK}EQ snpbmI{AվX\$YΏP;w'}/2$@bq,a҃\ J^UC]rHzYhili1Q5Oua5X(8@Qy+/ieYyd()쀆@G$U#Zc%j""pP >e˪:Hnٻ[ǴfY?xH(f Etܨ|\]6ajZG! ai>?$y/t ԭu Z1`/¦Bt_ @vC%Fn/+EG}cUY*C&*'6E#\N8ivB|h.tdUXX= +C/*4dzM$(e WЇyZe CI`%fv13+yjP hեw&ڨ!cK#'/*^G[y}LmMGEeL$K_tbOKNN[m͈4g; t hmm##S!&:htp0v;:‰#Gt4KAw^AD#IxH%ǏU3:NA=_brRIk]HQN@!9Ny["E|.$DOf=; (z:]H\CI x9'hdD6SMMȦ KKS)6*rʃ<:Uu(˱䳤3*ZeEۗBw%nAQ_$ .aB!1#8(Pj8=#?ޫK`LK·ׁx{Sg@zs#lAL&Kgl!m$ #y$=eF l7wMY?X>&U`\ { Grc{x6<Jcy+fl09k>&q9:Љ vvweםfgnbYJ'x1/T>HZq9>[^OqNŽLUvNNcww-H5b2f18,uЩ-B1_ampߘkzskimF}%ލi)i8>K?8gNyjy"䟃iLW}tz./]kߎ)w=i'p=|F/\+¡OqY3F PufAB}!^`$#UaP7(yz%?;Ʋ>B*D3~הK/<:qHe)n?es9iD~"c%kS&' ~ń`#'K +89 l#8P|& .hrIp?6mfy"EFrWSO fN~!PNt,E{2]u ZfZcoXb|2.|2DjEA! ا@^pyE5djlYb`).::R[#D#^')1ծIX)LUK GX-QriA i;1r4+S+m cXh#-S ] ie*DECbh ]<;pӕ-I\/1CA^%+IH=O7._([S%W"3ߪa(Aܺ1NjDUcm4X12DOxPS=Âi[g'GNU߰3sXm ?|% 흨́|B5dѡ fYF|2R&8| ˨y셃 DUeL(Z!ǝ{%/t~j5F ꖺFF2x {7aǪQǂą܆c!pepp fTP2| |<#QB1wߚ=(#(tn*e6Z0V ɤРGsn*3'{켉λ@Lu ui*hђc$Ō /=R ,xUWiTV>{Qew/*"BXDDEAP[5Fq$h4jMƦǚ6'm&ǐ.i>s?ϝλ͝y晹}%=[vl+[Q4 vW/^QUPmTbYit˵@hŊRѻ{eP\U ۤ-42@ |%EVi`ˢauة Of<[:x3q>A3\t{.l^I_ n|asuB!i/g-ChtKeSj(I}1\aj@2a%ãRO\dyL;cZ@eai1R#ؒ14ѯTcG~Un9I#&DIlѴP{.8rƖwlԨZma5-rGϨnd`tLIeRW@*j]cbRi~r4 R Ł5|na42+=aʔ[I!,>|<硱s -t]P2vW-B+B\:߆>%A=~0*7n}&Aad& t: Z3}ay0/%Ҭ-_*ގxF*=EydU /khl!2fG $p$mF ӠU3z55>tK!A }@c9H%BQ)s\P-/4:3.N(5/ᔺ3~}=Ώ$@JL*tT'G9KLUJ'Ld[Y1OI co vt-fr>CSz:p,MM ^-Xm/c$PBNjW뉋Q` $hO\$X?& s!5j8R{ U:bxCog3et & r y`J;S%yx*L|elj[I-0BRgtO?8v{ LmA(pat.yΰSR3RG |T98+5M <;-;Mӂ( âO 2aQ鬩,L_ TS-- Gws5ڗJrrJ<eϡܳ >;V5&`Jj|hT?iԶ IХ)E]!ts)TWxJh|]X .%yʊW p߽vT ٠_b̯cxw~ GT:&å͜  ՠ 5&P=MAeU`]_V d4ܣ}j:[MTj-χ+uME~|[>ϡŠV,)=˅k!DzirWqFUӇUB3):z XL>55B7hEM+E\JA_ohdq q"j@8皇.iT%( 8pi-NL% q/y!ph]5RuhMk];C[#NrJΥb%p6ũG#,s#^rNRe)'| :^n 95Ȱ# OkE<쀆`LDU$SS51 746i|V=MMgd^IP~˽*_FQr"ӧaޫ*pй)P*WI F P1Q C4;J~ yc?&T5@cb:BQTRY53cә㲸-k NNtt<#/gq F|C/>wS% Wa۾hR=J ^)^)|*_˻?|r*q РkڃTz{~ 3%?}(P̏%s/8LS_Å ;NG oH&v1PwGr!@7i4hQn"Qgry˭X/-;?%J8%W1?Ss잿ߦ^M#vG8;8Nw8-$bNjJ^Hw^+HN$y8N׽wb*O]~ oH᧖CL+bN:JFDٛ~#}F^<z>ȢNo QXuf53{4mZp҇;{6IƧl{3jίdNw79 氕~_-[u}EQh+w{F  iQy]##c`tpmvF_ #k9$XiKǰ/ĻX0(AhERσʼnPE, *Zu%v-/簉*X[+H g%WUu~uߪ 4RnW17cJR7cjJXQlgx 5+ k636ex8>u{261 F*tYVƨs DNPB|EMQ" +Ds:Xƃ])KFqS(#/ʓ<*? ]dU<~^>ZPS76C}M*ˏU9W#)߯KuϢvֵ2>e|NhӆH הy_"S#cb654wh@ILYq6 7ѻ:4z $Z|8?qϕp$:T4T _ax&1 7Y/("0ov_ '< 8cmNJ[g>L"6S7PD^83a"@֕R/nDq1>#5#?\hyGdFN/<;fhXB!Y (#ՌoAG3ËHܰ+mp8Ќiy"j-(^%y+`s[q saJo7=2aښFcOzyWO5JtO?C\SGvoH<2L$-H&/,!6#Ň) lx%þjR|BTZX+fș-\[ [cΖP$vExoۓDqb&9L*(  ؚӢDgNӤ߾i'6oZN](1p-֔vΣhYr 3}4E琊|vb'vvZ1(VSE?yXE $_}X2LCQ[gSadx}B 0uw#`{ڳ{QIa՜jZ;BS#hV0Kx`O5+[㈽"ݗ=Yߑߝ=z&Z0?M),lN~1iJ3:s_ :6QX3q{q1[[H|(k!%eטּ{at&E)N>D aVPɓ(ׁUo;̜/"䩎>x~et›ٿ;c H3:qXAd |x,X|pp0qL?%鲓[w^5TP|2w1bUx) ,+~?fd9@  QsWT6\ݯFm0iLVT8Pr4 ~.%њ(Xm&X^:`̱l?%١By'._KH'k"7#~74Z.d%?gn]AmNH8JGoGmd]ƑI=1 DAvD̓(|\9T"!z {g1zRSBRFNLTK+. 5:HDU~&%B{_ԙwPC|w{jΰvvQyn9j--C!qKU{>J`PAr@} Q"y/!b҇/KkR J=vKr4lw<{Y@AGdjp#މlHŘQ$o>N+vIm'G!wmpxmViPTWw1d"1 j¢"(@- `w#dQSc% $T%h%dH&JMũIes_ktn~7>' |QjGY[QR.ޚ$EU T,.Rr &p cDFAKH)֐qVe#uWΈ0%2tcDP!w &4Q1 HI76DGVplC'4I5 b}`x|[\m#j/` gUE%'2gF4l|=èi 7)_tE7&Xї: qOدRwM!E' ]z8LZAdrR"t|Ip;H lJ"2c*y! ӟͅSzLxRS7#mƩJwjgzUzMq1l- U3H1평CV dxy12djf㐳z&*Bx~4aLcYo課L^Z=nl-<!,*X A&׍w(_#TFbu\Y6#"΢XLNnigAз<.yRv=>wn" _6&F^VULD.+'/'b =UjnLSp<\Ѭ!9ǙMx Jz¶Ftbd[ ^zn TzA58Zk5D4悫*FRC{#auu10sCl(4!5ԐЈ :Cn75thŜ\CSDԥau(c?+)2tp"!{F Vw]EJ,^]BP;"]Qx$IjBViXh!O/,ǖD r,Tᆍ"Ten^eICZٹcEo:dK'E4g9n#]:ob#9{7Q%6V@F |J{O6b5UzO+Q4b""aE-FBo6Y䋇h:O8#xkoEQu3EB=l@hF$QB]dT?![$ZX7ˎ>z:F6#Q^~ͅ>dP,3])#|kC~i_jwz;gH Ӣn^}WCst{jt64s"cP3 쓃8Qh E svE3C*cx 2S 40F򁎄xCI'f:E RnPx:b`z226y;DZ6<*w2i'+\:AbP wY ;>C.[AlX1[C56g^-•Ye<n\Eqvs91nd"LdIDV'Y?)\9]tF:uBPaj6})!Ӏߎi4"< ޥm:O;g@|llK&ҁ tun?RWZAPdaY~9كBJr#=- nxLͬ' MS7y0w3sl7LΜ-v AA!1Ba;i~Ǭ;^vVGK Y3{ $9k<# 9N&܏Q#{zq7O︐M2](l&zyi`7%zF P4I1 /wrU!dϡWl_ \Dw~ ]Ȋ^~ Y)<%d'D']!qra<:N=W၊O7wOW~Or( >WH3>$VRX{%\“/u'sJ]2Q`mGI$y͔ՂMgo'f *tږ!5t5LQƞ. ĮOgo}p%&yȮg ~$( T{ϵuNMgor"RTфYF14Og dEG9FtW׶J𔸜TA<&~maS< &jϹXu+Š"JdeVi 2깧O@,Z8+]3tWMc#٫)lf虘V.mөD8wT?J:`Kv@3P f29~ n;ϊ8Mhԑ%Q$s3 fFF!wb`IljEbEf]^/AR4s 1u@{8epPk>"m0ڋZCs a/kfn4*uX QEĴ%ӆ]s-[wjNǞ%Ib,:M+[9XQQw@n9@'(2(g6($ʴUXa[׊e;u ]QGEA̠4YaX{|b5ޅ@c:z<\B@ R$].ss6HDLG((2x*WdKA)湺;%HPE.u[-`rW"hAK`eG:`&(huh-aۥP #"J uvulנ d/D SqwK B`Ґ C\v=;ooMt̘!gEeB2gM4{Adl7tK"Q+ L~Ze̿e C'ςRsmuV106]FHG[Tn%Q[ٖ_map\ bU4"@zF] ^5ź5 0Bc -okQV҆AwB%|\ujF6(uȁ(`~;*TIK@:'g8Z"[K:DlK^6(zkϩk M}u4;Y[c]c4JR.M|h'P=n'9o~ҽ$rZr?2%x}WiP~DA }-F\]A .\CԨĪp$kKDi64$mf:N&iI2>ę4sw;9yι_'}- ׮Sjk|Sk|[.ک jp~tPFYKυKm#e`${j+l4]EtPH@F52AA߱pp@h6>ӨeHQ!9Й:Z_ą!qa)1= )tC:{54"25Z8fZ2tàwN ɒez);r04 ҵa48j5*ݨ:%aeuޥ6:G o4hx[ObPqk-0 j3*#*![!ٶ؈-B(tybP5Sm^فQpL+b qKA#!id+F ݤ-[SWqn:3N&5>S*S[s_ ,nbuwy }iBר)!ZKȖtL2$ D&hСGIwL:g^gC)?7̥at#%O* N/BwRBWifZO-p~t$K_Mĵ# ۢwᥤQ[$۴Ȩt<-#ibF4vQ!1~!T?f:,=a4blPT -FAKQ(^jIqK(q\4oIhd $G$9bb09$*0@{3MHpt{5W5%IUxdE~(+<1CRLޙZRI!4꘴ƱMsDDdv(ٰ^RQ#Sfc/S2S.I"IdL󻼽]Jªg:s0oY<Ƭ\^$jF5dOf#ޕ94=$b˺Ӥ,KV T&צY}N6{g-L4ښSgN;:$s"HxlʚGM/S@ytw^: VglGWT1)p330;g6uO,9«Ѡ\ :e`Q36% M̜0*~Ow+f>oʟjȟx3?C ?cMs,XV|VP*I,, 2忼b],χz-+hJ~vV[7-JadAٱkbJat`qvP,:d:3% gB){%Բb4 ̷0ë F~kVfVz\ +cYnY8Eoip(nTmHͭX,d#ܮ}ҏ;vh*BF]ݶk1ڭWF E&˗-O7}[&z4t]u;Zޟ ,wņ]:d9n}Uj:}Lxs_1Y|s!ݼ@8`WC`QN,(Nf; 4ST`t3pBl<׼uRRo}\'r?S RR ǜs's$p1]eTwf>DJI(LE;E0Vdzj1-~ddKjO85'DЗs% %g`3,gWb|ή<\bsOK/ː,MJ:n.Eg?g*jS hLl\#|l!mwGg&+,ZՓ\3ea._@!Rz(M=).Eq?x)@9dhEOEͺst~iJEon{K2t4}B8uXh?쭔Xzi/-AG_ZdK ̺c?{Q1䪟y5x dkݫxNc`cזb4Cg4iZK% &7,ߘv5Lx!ϰ}њs}|[|1N=䝛 2b+x}X{PT{/>@1~EDD . `|5TQƷƬͣMMNmM4Ӧ$64Mg鴿e;9_n>^Ianose E_H\nyHVҨ6 Sl xj~_ xVM4ۦ}3uɤ]iR{0OA"Œnae9y},C)k+oYLbһ}~M'eSvv,Uvd32*d2ԘufPݱ]VMylUGSIɔ85ۚLbNb6 iH2cI$TkbîŜJԑB=p>ҾaS`d&~C RljQU MAT5>QTۢ S\VlMiτJ[D7,{" x4ˈ#fҕ⸣[sqX$Npœu2)51`D{82U*s0u:RH'<ˌ+1I]Λ+iijnBJ}8$:se8Ǵ% xI`K6b>IK#'4YM/yq-M6ƵjA~eDFKoZYA4ߏ#|$Zq%Lo:һe1-rwA]]W xihzP=.%z;o4Nãh;JESŵdi] KɕgeҦE9xdjjg\Uߙj_Axr^iҼ|NyPo'РBC,RičSܟMUU%)swkA-nXk􊫼bEw>Rwc&U5LK_ z׵zC-!эm_Ƚ}~e 1}%k@d5أYt77"W{,7>b [Ar5g4sAI}Qtيuf_Q6Aל&Mɩu8*)^B/" !} N w-}>MRaU+kUՂcHj@Lu>#Zx? uk@ clG*MTy/׎m;ݍfo0SQ"ظBOZ4ў.ؘ$n̖#OM0Bs* %:6'HkI[ϱaԄ$ QdiQߖך@5L{0ug/>xCkk1(rkGШZLK:X+cKIpdpPZYq( 4:,-%B40TΊC=}ǿBKgP60!Qe!&B*UK#s%BY:}ZLGH+P(nژpÆ"u[قWWǫeF3Ld nˊE,w0d9@Ar>3ĭTzFR֡E08RkC&/E w=G4Y]3ɷz$}D;LotFR̓5<si1`Il";VJ d?BxKl\O0I:1Oxa_f<4 Rw=*d8%:Ys@F1- xNS^؊JĩGhgK/wN3O3p33ыDèl|lP3s .*?_l}> +aB#]N YLX/DICsѥ4 O/ge ŗIK]΃e':sOÕd+ u57x=VyP~DJXdyqR/Y,(iCNT5$.Q8>t5 Gd(dn=Y3 W~Ir[!4s 7uw U]U8^ ٙTHASwSkfZia"wz EY_d@"J똨‡R  9r.Seȑ3]d'B^4X.c"K&t:᩺ kW[D j0b=g,5mlkoY^3?˰"ƒD|B׶doLewًyCA, ||H?tOH[[N3&HN/$Bm&K[8vҊzin& 'õ/^iTm/>k J,¥q{۫CH‹wtRJ KQ8e]e Lՠ ɲ-LH-?a|0EqYM8\QDc'BE=vz!aŮ]dxIZrC2pe6- cf\hމ̪EqfUmiuU-LvHT+;Qp: A!BZm&gbffܯk+ pjn&8U$6adn=ց^ߌ~R?yhx-Jr5WZ'v< Lz 0b)Tm7q:D uSCPWcփ,3I/Hytqږ$EIB~_,766ݐg0m.@FlES$L.݊sK [tQMyv inE?͛x d dA͍hjڒ#-UdN -v2}kZPdD-z5Ef̑Ds"(WH ˾|;VH m[Z $Wm WDO۽ :ځZ 9wC CoC j< G~LXrWJa OX}yITKj]햆uawn=آe쯴[g&]'&-`@Ml~s)$ g#:GlM4Tls%o䦛 AIQ 'h:^j{ u,"(~'7U;hHTqx2џ4z57!DuWE‰D@)䪛:NlVSp(揆V1 ;y=Μ μϘal ^Qr.?'܁8x6 umiر؀!z &=N쏄Sk@@CZks7D4aH$Y1T@8!|:I\YUS.-HS'_{>>_=_F/kaׅaGMar)N ;8; @5=^P?|{&\:$J/7ߗw+(uN$!{fZDx6IbF6Ѩ;oB5x 7|_k;PL 0Ra,I&xO[o-= j Bw>[.ҎLe(4 496y k}ҟ]+M'ЫL_]e:Z؍_͍7CGCbHȩJЊ n˦i'<;7*nzxzL,8ftO~f KogD)ܦ1V;-N;#F&|ٍ6jv u-ˋI0>3sk| ?/e>xWkl%P^օ$`E\z*lZ-VYԃ[rݩW=;.vוK$,MIQ\& ͅ-$<m"p| u]D:dܷi/gT19{F\Oia]D^B^<8w@3ANkLfµ:f/om8+;J0J6KlۂX"IXMGek)uaèkncLEumG8=<Ɔ룏<@:[>7j 6f[ןhJ``Z1^CϟŘ9à\8\H' feq,@WU=R0Zk ƃh<t&2| /glFGzbxxN7鏄fJӘmiu|ӜT鐸tMPP-v*MT."ݱ :3Y<\>7? 5s5n;2WX"@ .3S: j a?S_n~nZ{+#\*|,PsCOuQx.-Sl|*s1?a9Y|SudlJUӴF"{aU6eN 'nZG88p01:m&eM1)䨏Z`_C-&S]\4a d M``qES?oG)9WbK-۫D姍'LNY0-M$"_7L"j͌LKh/bVB('QFTKP;0r5ՠ"+u \%UxRuA2͓t\D!@ E?Xm(fg%cP2bɧXP=O*H7Wcq5;Xv`Z(ib]Cū"j/IL`7=l ǎEkU߳ hij6h*_\YhYx+d8Vmo)jC ?o.XϜ/]&eܵDzD'%B]vQ%HKltgW3fx]Wypw&=yy/l} $e! @ Dh-EDT ("bgDUkg3[kk[űV[;.uGg?߽{=YkJ5@Hkk6u݌MS$OlZi~[x UQdI6$ Ǥq|tt2 ǤxJaU:ƣё6ή#aZ4W lL]褯l !2)PS \Y`JVkA}9PTJ>$Pi4祑-SOͿN$6(1͔l(>eiÝi$c7aeϤ/(ݛQB/%O2ʄRBf,\ t)^de5 |05f 8f%"BnFpl](9CO717)J%9 % zrN#M񏦴@Dt) EZF `k 0_(=ȁ6.;%ŌHv!.zݥTz#) O2U9:Z Dp; :^à;} x]D](+![HYq + 떯h eQfK*,V1a̤O*eK}'pd *)4:πJ*bh0|8o8\@)SjKS M+d3{4c4٫*f_9H+џ*{bSsɔuz?l>_Co ?$̿$`-{^~03N1`۽5gQrm]TnTɮu 9ۜ\s6z})PT/)ʔ,9Te"?~-zrFTdJ*Et,tS8[܌y qWR,d E 3|CX}рdH_I%iH _c3Т9U~7.m Ҏ>wM ls0tגAzK5T:ٲ0ښt|ie"E: FPH&pm}L4`>+:2i_*xĥofPBdAdͦL$P_@8M&UK@{r mϑ3ǭo&ʹ  qˊ>,\"w-5|՘*6IC^٘MoepSk9Q N3y}w%o$RI׀Vdɤ+[-+Na.B1ڦ̮NK{P5ȸU.Q@UYU&(2Q}JN F&Fwf5FNд+3Q~twviO.88]B3blzfuЄ55. u|M(И:F^D>bFIzjrV =vc:n0\Ǻ05J*qbL{"({ӟC#7;6xɆ3ȜUQxJ__G/bg%E²% >ħ72u6lqfTn# D#/zLDBe+w9Ɩм_rb-5G\00֛{n8tc`x3n`m39&GS`{{^J8v+T};nWۋIDU!c!+ZwӚ(c+#ƃMԂs}t΁T=X?d ;uQ\q}g2=+]2]1|cl.@gE&]S>;p[K #}VԢ^ ڰwT.Cڄ)Ӊ}wqm_(vK7ⷐ˿LҁrTJ2nx@.Bs#u8KА" ˇ9ؼNALA8Hx|x5gw+4#mZ~T]:E2hd!49֍ ))>zhd#OL_--r[\8M ~oVپn,{v7E@~!}[8+xJ"%טaӜ!L,k4zʹNoI1}r3O 6ktXjF6e)ռf\Lg>^@{aeS īޛÜx~.Bg^3D% xP˔sf4?D+q<G_Ƨqh/?͙~XCp i*VO-MTYݝy>s(<6?^E=^Ѧۆf1iPF mPFuWҙBm %eB sPjō 1>xY{te?]D@W^hMB=+A$$E TwWn{@ " "fEQ#ap왁?̜zgvt]qwv1{Kf{~#󙘥QC2G1d[JIÕH2f-+gxU/mZ fm3=zWWTcZMPz+8*N>zq R$E,B ݰrU,LXmbGc'/pdKAҍM60)JE_syV j.ԠJ5ѭ"$>-)>謙GM`g"w9L(xyY,qjL^"֗xy%$O 7r b_R \K6D\2>+Z&RYcSgWZڞ$NBე,RT+)$/g,1d1?ܖME-?Ue =ʚlJ*fDxl񆬒|^Y%O]2+4QGJX]paIMvɹ,"fSKBE3Mprl$O-75!CKh&,aIS'gaP]s!P M&E{ -s,^80m xz_?_Faj sd.Y&{1],4JsX)ɲ\ҊOr\XZP8&0vΌH` &bįVơoU)% VNLT#8g{cԯDaV[>8W"qvkgg(q+8% }Q ǘֈŨ̞v_%PlcLm;4iqtY.k!dk 63ւH?YTҠ>Gʈ2Uğv="ffikXq&d#PC* (bר44<{5ZͅZq;jU'bF{w Ƭ[i"a&[Vdj 8bSMؐ5TM_7&5&njX Kuh ⎸`&Iha4 A4~)LG#CMn31GS ?L Knz6,},_nJb&DO75SXVȐyv})rc ^| C>8|VVmx|@+þ~"oXP7a-#[r͇(dbZ[/yyD)ȓV T۷um5s=Ӫ&.9_6 :srϩ0F,;yۋxO`/n)Y_mo>NUii nmP>Ph֫%N-;7,s;lͪ;a?#/Sc8 B^D|7C!=Y`~a!/ \/" _MGJ6i4c xցO[ᗭ?y'S]W6#e :YN vЭ͈?L SLHG581%>?A؋}V%zXظM <8^;ۈAL h!z8e s"ʃ d>@!L mA - s02ЋEH7g֩~?ڕe$QVd@:0 |n<= pu9B1sXiΎ#ym2;Vv=V9fTRqQyii G1Cfl$̭ ~]w XF(uthV4b.]B0 Xb =̄ D8O%UKnEf v_XivO"$ h0ގ7s8 eFNY<ӼWN]B 2ɤŔ}A&xnu#7 7 !!xwjc3yt+'ȇOb4q?n*η=)ɗB׏{ ~a3}%醺Ǻqef|drVG(sPd'L/ljdG"f?t$:vc`^ ֹ׃_[;p_Iv#8#D#U932tkf ;k0dBn?w +֢.&wf6w'ΜOI4n^~ٌ36Z$*DIHll3[c0}ӿ|_(vɜ( !C\4zfW=sLp/^Z{V$1]+5BK\A-u;/>g(,6'lxgcD쳏SD?Y\"X!W2iqX;.=DG,s$"sYMʪ!- kv1b-^ w`UYNyxGjE> 3T;P|d4ttҼ/ ^IU^Kh}I:gLh :y&.9x 2"#|0*⦌"! Œ1ճ$yu\T{\S ji\8qB"džy?ώ7~2,:YϏ?rY=TA DZN6p{U 2$OmǼ h/ѧN5Fs9xDL{Ab]+aȾt$ӛ-}/Ek3ӳaՙ5$O,'\'Cs$ ?}m\udtⵝUO a+}u9ۄ<9[zc5L,\x%8;Hb[DOlHJ)_A'NEƝp91< ߝÿ9 yf-N~ ICk/G펞uR;Nu)shwV3髇J!vn`*q+Kjc\ !'WjlhQ3pJM`͠^i{e)[!tfȿ^ &`lA6, ¥.#<$8s1(eSMp$_E'u32Z8VzPM k \5ZKD剠ѶӯdQǥҵ?upm%G-̐Gf<ߌr2|\Ngc7Sb<o"bU2zRUȝ sI! v -"?BZ8h]5CTޢjGJffK|EZ0vv*}Ԭ6ePԘB1Yi̧5ͧ`mO]w4CD?Ąg+}hdV؟3nXAwۯ퓻FGtyEb(ljĢ:P5P7Prtr$9Uҥ(})ahC7pbhJ}Qt~gϠڎ1Q@p?P#<[{>s8J؍^oDHq!9JJ24tVɠɥ/%5-@h:-ݿ[3> 荛jQflH(YFo]KC-1@H?j,2,\Gc™l )X$VtS:6[<04v Idjs o:nAۤw bF;7toiz5UýhHg 3t=c=L>wi΃N2D}ߗNv2fÓ4-Wx5VkPUϥTE.ht}GQrUy)>riM|hh<0@"8i:IÏNɌucӄv:vs/gַo_ϱ I$vb(n_U/ |՛tC0V$ ,W,f<,BV0YbÅhCe!nZXT[.&bDS75+dx@5h2Tti$2 +kqŕj1v>+0۱Zɲ[=Y4[sD2XrFk71dV<0݂V&VH9Yk0i43Y LSc1C93LiF":R-iؼI:|90uN؇u%prOʆF_& X΍`*fjP/Kz¸lS} 2w>uU`.+%x]o_vG*EMKCqsy3LỼDͳ~h" ҚrDnq[(jjAǺ5.b5JX?U,'$ØwnUP$aGEEqxcՈ /ArjQsC6l\|"D/} niq@l9Hr[] z$cJAÈ GNHRN2-L#Sc4co]$,pUѤFUR](sP 9lG8$J;i3:_ތm"4%9fGg2?dȽ9r0!Q)h9DHAbksQ́`{%sDBH\]yj9|vol*vWH4O5Dx,?^Jmc_ڛ} T$Oc G3cF09Leyt?py`d eB&Cݹ!~5WR!$r"'~i\0ل\

)@CcX?%P񭤩?/ z0b(H\I185Iҍ6"8荂 OJh³N|Ce|rxjafX`:lSLdnn{Fn뺑NFS鸫u* >o.o I ~o:$;{>[EL2sTB!7gk1N*!Nb:l cq}G`xXklW5 q mM8%4u;;%ubnM'ggٝƓ8)i: 6U* m)ڊJm%@@jO@*?8wff7,͞{=G/8ZL!y=ͧUI62O2bPLLu)T7|kѢkM4[Ot̶I1F][v:Y$-zn=]\维 )`uń}$<cp(KUt)QӱXwGSc.L',C$"25(*JUjU@ukθ,HmHтc,n27 $˰"-mX V^x^%`pByN;=D/"#1ܯ$x=1L0+{,A$5 /0>JT&I KZΥދ ~"IॷsQ?LYO҇nWĪsaՖ5-w i433]sfxO:5ytkXt\ߣSiSu;3h61`m ]SV_n#7R5BFDw$߇ū_5Fj+O>O\+&|{Й DJ5/'BZWK;hxΉ' 1QYěpF'/ţb2*?ԅSшD9A0ߜefhRǙD+SE4m .3ODKT?xډ|cDt) T3y pJP &JT'JV?<}IS/!+R zM0Z[Ԭny6uoHߤ"%:]t6d=t]Gru gan% /س~;ડ+*aޠn,hڰ4W=oqMw,A+ꮓiID*Uq̇nGg9{'V~X w{)!uka՝sYoۂ7z𑠢5M.]Tne~Pglyj CqZJԛSK1εv'XQZ]Wjr#)-fiPQ+m8/EuTSA:E S͘ft*: m$,]]>3ɫo%TPˎezh[v Pځ ;!s7I+%:n!MKx V3g/\,1?d[Mr+[PY(u8%.Bc#|bi"n Z(yN3#o3lraX9F_7 M79h{Lc/Azv^z$EKh@!j,_KFfne,`zG | BDt17> fG,XvTcG(K,c54j"J M{ѦԸAփQ^h-֌).NXEG@CQY%<ؘcV4Ceu,@="6S9 "+u -]v͕~,KS hN6"ca \r#%dt ?P;TpHåMb -Û&$BRC6&`xUWyPw?j@v彸,hDVAp(%JDkhj[4Icv3M&I;4&LSy=s~gPWa'-[^[9_]1n$TOT ͢z1[xE2Ͽjqi}HHMj`p!t96OQd6 eD#>1…?nl,n.kq龓*H0W|B`x>[ՠ! !;W!B}ts[2d2ΑtKBCAZi۔M-Å(jfRIeJ [ׅK.ӛa`pTF3Wux2T12R"aעb*;نIGR0t릗 Z4Pc+AuM ӦcW&}=υxɰ"zlMf<{I1O)A$ɲjIo,?'Md~ϝ, fion2׾{4tZ*M i06yI(7 4FTԭ4NӦ| "#z x@Tczhz#c4 !#q~;1M}Yۭ~k\*mYJ]3ɿsxw%ɔu$Ufz dŦJ_( ߳7 ]*+ ss^/*E~Ҡ+jZVwUs+[Tʸ{PDüo[&P!򥜙ʫKM W**!>.ڷ*0I "w)rR:6VoDBiFkj Ek1i~E M!6U 53kfҵZAl]HQHXQ}`#\\^C_dgYֆQʢUŻwMxRpڴt_m>ю Y֭sBG[8Nܛ,<?RжYz[5mwljQ[q?p*>p>p~p`4~HO SH}g=*oo;mS2FBx'mUF$w#'qH@缎TG:fCMsɾ2ʗA2jG~>dʂG;:xw>@voCwv&k;(yv=j:]L&i#^ vLKr*bޮ4pBJ'R $cQnڝ Q UTVܯ#>W4gɹ 7 4 [/Ep}̅Rʙy [݄Vz\GF:5WXpʹ$VbѺs˱?1R<:Gn?%T>iͅ %xM \u|+B5JWqo ҳ͜:ͽ(&}ݛ%14j!V6^Wg`ľeX-:W(iþL^YX-Zqiɵ4quN-i0z} d_N x͝rɑiCw\lG2 `Mİ欦ecYUYlTedV ԧ}5Ӆ'b#2# &=c6fXȈ˃٬hI]-ʋɷe]=8x".>$M^l^4OV+FՃମ 6PUѓ_zg UY̳uͻrVdzUήɳ[\4]5%EnrܮJFVٻ*ʋَjU jW?C;@>J _nyM>Bgt߇ώeYt=zV\@|o7>_d_5$YȄ|Gz~ ն.tlӔjlzUS@"O"=[4l|uU.0N*[4o ՙаU>\|Xh*2oߧ+@l[gm7mgM9-5oM  rZ!t˘7:UUw(f.jO^]ו}q&o۫a)|ba"U}vCYvW9imXa+!n|.V }?|vmx ժa\ D4 NV";Ba˲I b,t`OOYOfZ8Ks𦺸B`qG_Ll\b5^N'G篟(*v%~z[Lۂ:>b'O,E#;A*J +\?b4aP?^G \3`Xdz^.PZ2GtñpQ8A[/fMӱU p4X zj@QmY1foi!q3BVvC3lzRx5^o |P?4M:qQ\- @,9l4ρF5F]ap@sӨIݚ_P81 #a@=u^!vq( l /my t*zF_mR4ʲ0d0FG*d? Yk\VXXl{UL)^T{CRe`Gޠtà^nq[bd du鞜9Dl,@.Ӽ39ͫK[2@HWubq WwGZ>Āfō4:[PrVnrW0K5ϛ9YE]bVWtS+٘~拝7W'Vj0[8%63' &{c@8gݧd/;<i1hͥطV EB(Vv*MYcCܟ :i%_\" &^uѷfO3ֵ.8!X&ϝdL?.2\D>.d͘qY-6|5q'Z'# 5n:Ibwלؑ2PL|pdJ@t I)Uɳ-ugK%WNΖ^:1=yܭ7`XGG]{5?Tn$}J Y߃A}w?='s70&}OJrF)7x={DJCSb~f_o}MY,'xw;}B||Ok|A;&zg};Y %/Wp?j('iͰ~YQ 4혃^oWN' s)!6 ՟**"9+][#x} KvaHxS[% 'V< BBoc#']/*>m ~qbPE&Cbk\smrq,ىn>Qaø`2Pb|!~Up[l1w<6oQrDz[ `ׇci{{@'3F|w6a= "E x#tSlZ'`?k_e᪛]^?w\~{}i |dZz1{s?\aT?7΂2MC@qu/BiXKzK㴊tΟ^xJ@C/h Z-SIQfSb_|IBfVj^݃9 Ȯ7BbڹlODh 259;a )߯ETl(.f &@Ӂ,'BosO!$*KB/o8cHY)Mh=pw)G~X!N^'-uJk63&G5r7Nua I %˂9UߜJϪX1PF)m9", j#Lռdby@CЕ9F&X2&K3FwaŽi?Lg{c`w 鄃wPcz9(3<}ҕEs B3h`G{C=AWT>/qp`\䜸09Uʾte\ -JdM2L%D^Q&)cRG$O&#{+8&w$6{ij7W2tRr%C'D,FG!6*.e )jb`#-A E +ABH&mN";r=vO:כì_Spsq:d|0+ LEz0xlcr P&qBIՌ0*~0]J*.8 7~5NNғCMZt=s$~<'"n ddh5i;Qз]}H)Zߕ2o:3 xwVMWD 5n/ W8F؞X6պeߥ 6گ Z2lӪ H9W3ݷ0q6ՆF$)*:Ȑ?Y]d?aW%X*xqM!#(c Y[;b89G$JU;`ep*f'>MwA ^ oA9>>Dr/o? o$[c8|oJ:_,Ȕr(:޾on" (DlZӜ{2DRd:[$,kREAVvs4eƀXmnS,28+7)3EC'>[  :,ˍ$v,0*ŀo-ַ=YlE̝,2ckZFr~(j 89ϐ?}x=AGIee,b+ݶ}eU~a]RԌJwu)E)϶l B*!?~]эc Y|!UE98T'NoIbPʇX7 l3 ИNJ>|kyLOhn94`d' 2WwabŸ`DքPlTe<| ek ߼{H_?JP}GU#jD3TY-q׼ҒaA8ZֱqdAP(34nta`+tOaȞ8%ň3k<@&e OIڿ+Lj aoDҺVYxT-[hiZz=ngߒz#*4h][lU׷U6q.n f.c!v0L[.Ay=Y}o49luI,LSFGUбGPyJw1+?t~^MlF[Ztbem{yT}B? g1`zgǒU;Q6RD X. g.&ˡe[]|s ݔ7痳Ch; ,-v3 ;[UBjʀlelO˼7eF VИh pp'⽥Oօ0h8,Q`vl BƩ2a+&e '43u ME rPws>@tA nk#L" *%% ER#dO֛?%|y8yd2($<3QoQP/؀ϝUi-X??WB ]@ 6Yx$(HsT}+J/АH/ɢCJr= 3 дIza9y1 `NJ9ۿEuNIHg'#aLaE&-m{y5?#A4ܻ< [1h<=YƞئW(f@?oZÅak'^lD1Sa[(Q-J"^̆F}?>rynt\S&e찑YkK.v M=!%2.,mIE3 ^]vj8Dȗ 4}yzV}cX;V6r] 6<²>(d.mYEUѾ}? h9$XsJ b~6c]鏲Ò-aE9桬:)a;jL/b[ =>Ps-4^͈gѮ!!x s6wCqk?3wm8^Zkg_M# ^"F(ixT?pP LU/?ȺeZ KxpH@kVzpX/anPxӔXYS4N- 3d0~Xʛ`sڒL2Ru@>UkLk%U=zoD!vilGvM 0sI}a""d bI*-wVhRRc <>E{\mLoUI ׺Wpp?xK&5 ;4I b%Oc:? g"scȲ8CK%bEZGMQ!񌸇GW4Q+L/o^`Sn|eqL>pYd䒗]bM=A jۥ$<.yEK[+m|o}'d+ƝRXPU}jq<.F0+|m%Cz۪Z'iq@sJc%.aiCJQT؂1@! d&7"WkJnD*.sƪ#8!9C"58O\gd B0e"eejğ;$8kdcW40h+]U]=20Ecs-CŢ𸪬7 FU!@C#MltK{.8x"Esꋘ]az(j @RH?U-F@nNC#Kż`T(G"JV2VܕRJBjŪ͚Nߋ ݝt@WS GU 1/yV`pԥm|O, (y ܒ۱`/WUx}TKhAe6_ %Pc MQDgvlݳk"xa  "g<x6]UޫWgy T}Tvo>/ٱcGTauDLJR@Q3t8łH r,=SJwK?\<@Px-Am4͊bFrXU,{y+k~x#P+E%KRAAC8Ms :B;(W}lHcD_uc2 afv 2׭]$D8^{i 9% 0=}fX1<4$א'7~y/$ "RŔv/1"ԣIN&d T$-].$Σit|@f X`.M_5`eΦ[w-T _/4AqxG'$"4"N@o*XfʭH(x~KTqIAIҿVcX6{w WUrt*]9><#Zlm/$PHo즋~( 4V^F\|KrnCTd !l#9&Mj.,#_ '6/YOn6x[xv s'eOñy_vW52JJs2KtRRR99  0dTm^)|Qws302o^ɶ9Cßm3A䛆:`yy IŌ!L4RL\`8YXlrƫ66ye D͜N,6_= 5mM`6%T>yЄ7"&FoyWL;?XonUd|(qridD'$O"YqsLj`QjzfqIjBԹ'p{f)@:Lސ$X\*U>-//5ou3M4`xV[dWqz`.AdېTfXLzm'si#u6ujr}D|HayI<BN2E "?Sto[]Wň:b(\ݜ|IKQJedX3'df#8dRw;vW~\d '8rkG˄G,>jztHZ V2@ftKL QVЊR4gnpM!'ִ1yxn[۪on1O|[R>Ké葡8TV9.'yt3vjX,dM!sюr(g [o,V<EYأnHHeXl2qǏxPǴ؁Ȍ8[i!ka*#+ Z⪮8a,WDXt#n(C= \%E$gLE=N0Qϐ<4> `葄n R!-#ؼ϶u IluSPSu bAqnZY{ѦQ}(43kz%Tx-_o]|x=TuaJW7;ջOmi|G[ﻜC܅/5\W|#3?eq8xs*&H:Eg-y2ok3Y OSjG鹿 zBy.A|WT/7{?^ٔC(_Fȣ*\j7UN4z^hB/59pɥqڋ_ I]JFyb%eB.nP>|Yv7P^Ff$;e۳sַ/NpR|8v,Q/wo=50?i=ZLa<\9)idgb2sWʖTMS O=Ou$qE!RxmS{ͣ2b jSNb=dY2̔k<ƴ,-P&Ameo>}O p_}Nm~IYAV ?lWTMuj@ɤ2F0]( ՉE]rjda#z-F*ޚ[qG-HÚc1[45!Jܭޭı1?o኿w)'Ѫ)+9氼>,*W]-,+.ZI`+kGgF0>0ށQPAf-.l4z%~u"n4^&k&<')g`5 `yO4B !:dijC(CvR9LM.u xL8PFGVF^_^v*H(»d?y_PU>|𬡨-'~$W0,Sb͵p*t~Pe6MSf:؁Yn9 [|cGm2@aw g{qۇw)b2vdN9DF4,{f-a-D] ؜kac!(-79*51/O'&T,qyŰ3R2`/ -/4r?1Hxf ʫ*UL]g)kXEo.cV=TԑLhbʤfIŒ7ķJf[<"|J'4v8SY؊(qݛ?%{=VogD+rnWS5py iUY>;V=Hy{ h݀k:mS|bK?;+~ᣉ^~KTfQ DYmVFWVBy-*<[=3=jlT_ T 9T~z n4bő3n 'rHUeXC 6c3= V+wմ(zN95 l37[;b6sfapsꤍ-L&sΊn> o{=vWҎ |i|n2[Xp ON3z8Z c~} wxSL@5_=@l\-9`aTu5eB&:C)dkc(L/I+Fku-[l(㜢A_>]юsbZ\AS8˭fI 0KY]]8`wK]xuLtk.qk(]=dY!\]oc|yʋ&̔rV.+⮤/iXXcPlJRT\lmT+uz/[Y ksQ7-/=δm;GHwo?ɬ!qf[=ۚIJRj&E`isc:Q; BDH /{Idh1䵲ZLr dC{(b}gY(iY;0>PҼb'UMjН"c؄m矝lbyIḩ}J^y]םL IT뤡4AIϲhM[\~>]Q1,t 5Z y0:]tI[_MPACo(gnm*G#7Uj [BKK]ꄩ{Ud,/j#W낉r#D!IM}05HEg\"x4Nڡ,5)ۙ$ ˳š)rB]/AJ=h.pQtM]wrN&s2@_=OUz_Vl}/,-L|aKHh9atq[naky ˸f&.`9wwI-STqCZ\=<>O:{$,Gd ^{flƊ.dӞhvi&(^-`p'"0Iſ8Ph:8Ilv(uGhRO_<_{$(_ |Nv\Ij<_z{@D>z4JKIʄJÂC<5`yMKU|ḱeHB.x" ɲ//zC)CQIIOSqNK/1 l¶-D!5I}Jd'sp{RrP0@Q?.O=gVMJ:Do9x.Zu! o_t\qZkvacZE0pb*x~r:OO$xTǗ;bƒA%n=\ s 4¯.SWq !:vM,TH;<3]Q%O$}FRg.FY_ƖVي?N[3M@FT +qbɑ0W΀gO)R%.ź|Ts^cQ9=8]:S| *x@+y!1PvMF2ʖIB8]U'H$6t;ң!۸!E3cLp8)/o(NtH9^_ρofQ]^$H7| T4{2iu7 $z꘦J$rb~-/#qM Q9y7ebM3jmh'r?ns@a|F`Ǝ+n b"ZnZW qL/-]햚; ,A3N]F`ϔ Y2#9%Tɐ0TRB/!Ac ʡpm#N,PCi@ԪLJ Z̹Y~DK+6e$o@"+S⭻5\8nl ੳI8g/rSw!9LՖ[pB40FlCc%[x@peW:[;gkgJkQɽ5{;Wۨ3uuJj{rq= /u *@IWN i$EhɚA1?D}P3v'^dm3 4K7ۘ0RcbqMmw<$pjZFoň;*d)"[Pi{,2L0okNSlkoӏ[noW۫) xrMX))[㪋,_D+/T9F,};I ; 8,o#g#t#Kn| KsVk3U0Ԭ_g^[ [x*fh+@%)뜳"5Ej˃ -v'(Qt"0`ŤORoxW˧͢&% $Id: de.msg 1253 2008-03-24 01:28:55&2qX&  w.Raum>FDBB?+fxW}l[W7Mi|4q[ql'q|4ǒ8IN]۴g~p{/i/&cB;ب6TݘZ !!ʤR bi@"Rw={~9ڞ}6D"$Bd-FzvHgGGc:wwt'2DHDNKb-$x]j0rhvPbPWS%jBDHn9j@UELPMOH}*KLA|=VQ7úo%N5bHPQ!oYI袪P/BJKrGN>UA*OO)Bs,%q&|!Χkq*d^䖕k˾l5xq|$FTEgdU'{B^Ck|e1ւXPC 8 :Ǵ ߨG6J6+*X|DVuXkBﳔͭ%"<ap9>FiĖ{o7X4"GWYjO+dp? 5"#J_ݣgX!xs}lH 5I4Xl+"'iP՟oU4>jz/Lx gsI# Ǘ;F"RQ .wCvYwof/yh#0~2/'גWfsu~4ٜ2{X7\ml[)ZZ(|TB 9%i *آLp#1`i!w&vf&̀:5\pTjÛU˲[}%] [rW/;fm9ʒ// DxcAP [G̀K\Sq 9[d\_ :-JjKQ` ^ mk"W=!}0G>D@u@ RDiݎ(%0+yp@#%gy2L,:0'ćQ ܶJ(M6 b2xn8-D%,ȁ:Z ]hkQGӞ!<2 ?N'Zz\X} KOva?E@DWgiA^F~ "N:Ȯ|nuaD|JXˁ?_"5G)bgHg`}*Z"BޓԕQlpK 0Sv!4jIiUƹuϯW[.4C 7;J N\ⱘAuhɞjq \KBb.ULo$^Nz<Wն-Bq29H6OY~v&;Vm;OmxUoA5=4jokq txQ`1$֐L'QzDmS %ֵ. 8 [th`쏃DcO¦wS^ `U͙&u?.yAL>s+Neqųq>Eٝs)c8:)þzS8LC5媫gS)1x]msȑ~b͕ _]i%9ƲI*N &  -+~O[]$zz{z/cYכzqY?.EG>^V>#_}zV"۔~$\&m2tsV]tKyDN"p :A7kֱlgs-3{5} ! >6"2 ^Q1N] /"ż $ZnhlمGtr.e=96mVlRc45|dF\"w*]$إSHכrn9 JXf_k =tZtװ}(:Tv.߼T {oLF|.&_h."#  vޡۋ҉hZÌJuW_%͵|:q#F\L#4:)[@󹀇Uye|8ő5e&].Ck.@Ӛf.HcקN h%%Y]?UCuu |<S^bbQ<PA+)>!u \{Ǧ㉽&P8Gn!ar#{@DgK ت%B MpN ݇zl

dlq}!]O'B6S~) MsTor)tA$ȃ_#qᰶFG֌ <3$]d HAd{e-٨y t,9x3l'att7[ʗ%gOh%7O&^>QL&p^#{v5OV&U$Zq[WCv;t־EIЂ玠5m66D[$;/_l?Ndm6rsߦp53RtGϟLHX-RMH %hޚP"xW= P˛@VxG%њ>~ ̈p?Z`t`"GU{y`%V58xҠ&qG 5#7cK 3CıS7عuCcC |q+4ǰ{pډ&+Ӂr~f <:˪u2R|^̳G^c #Is[S/#CхHYngm\J )+O+8j*!PP3`= pu<˃Ѥ;rN$]t'^1t rsUҔ !c.v|jNſ|Az)9BlIj1%"+xDz4$^kl jSxw2;%b<<ª&(VCyχ՗v'-* 2ԨM)(b /|n)*X#F^wEw}Y1Be-ϐ;$RUc{ 8zRv@pC>jpɲ4L+s꠲‘K2L$mvO0zb.#RR/@•?F&J2݋flG*Are%=ZΙB[=쵼*H{((N5ĘC_lXD]++@5 q[/jVtT2-8ݭ: eߠCMx*suL돕ԓ {$1B]Db7}jP(e~C추t: 3]XAe7 rPMIaTБ'>p~~*D9k* AI6K$lՑ,'U(3OU ݦҩ_6WH^rV!(C]6*z=uA gYv, 'fޡ% ?eOZB^A˜Bה?ex К-Q?!$5(o~U>/w{XL"drlX^ %y$jU{ (;ɥIN8s@jru!jT$R} c F@.YO"(Whj~*n=ioUָyVaZ |-Ͷ zzF]˖6sUmeEVEQ1Fr"@8{v寠96@6ĶRb | U}P]-:&i> ztMW䣐BN/.iB@>f5^>KqPȸD>6C_Z1gP$TJt 0ZnȲȫ X[τ=ˑ~Mnd!BQ lkƛ, y|-08z)o- G:Ywyv-knv[44O&xBDz-3,bv{^egKɝNP GKd,4RK )} kx3z? gf%~I6qSb'M¼ΡeKfjj TO5&| DJӱh؊~fmk TkBO-kF8HOOYE QadKt(V([ *aHyڍp7᣽sC}m[^#P~7CH*C¡svMҹ*WOr`挸ئ~3dG*1>󠁛hfw\qǕLTԃCpd]sd+jʳ04j5`Wajc:~gydZ;siq%&ehZH֍ջ*'&9,A+*C{E[qu!>G0NpF&V_}_@N¸v:dVŒ6׆v!6t=֑tDL]nj4Rq9V~z}e a=55wݐea] ҢG7Vl+Q-NVUP _QmAS$Ru=#:WfU% 5h o+"=|A %A{ܥ钕8MN߹5+2uz0b>rC#ug7DN6k= QK eLݼF$7rDaXEt?p1ǡ=c٬ \4Iz\xM6^C(k, 3i+ ]q2h;TQ*;g# ˊ3i gݝ9Gb ۠1Ͼfцռ?̢t]hlKy̾K>OƿtuG/I, Pwc@rS!/Z+>vcLSL6,40w )d ?Ri>hY6 #(N0TTn6KnZTl•2}`XSj'(ŀixr˜@'΀T08*qg ᝾az\ē{7{#S>%GDsz@8ia6/L{*isAj &Nj?ɽ)e9nCL:ɖj~E%6rS.}պLApB?1BPtv|ЩE3?s |~`qc4#.7`\梱5Ɠ7>CjksR~Ԏ'dN^xWuh/Á5_ڣ cN|suoS˼sdžIφVǂ\6[j Xvw yKcdjW./ɹTAF/w-~M18zB˧d\vSa稛NDVEE@(#sdF.SUV[IzٴYM:ܕm)ahPg_y2;w;ʇuyٱ}}pe. 9vg2*_{0Slc v>f~Tȱkxɡ` U PEUIݗc3mbV-;qn+m/Q=%:ȉDa@n6,؞NۚhW([ {.G# =,#puN7UtܹK!?@YjmA ̫cBmTTtQA j0>8C}X}fȓt@ =m[r1w=~9 ;+j4Dя;=4PC}eQYdL#լCO42{+U37\ ˾ןQ"jAxXcԐ[/ף(%&m]ti 4"qOϑO8(.8UM! !/ա;Ўoqy,?A;Hh fMhУ *i0 M/JјŰ@ʶ']w  r|7e .^׈)abΡ:hVz g.$,rBK{~ESJ"=/l>(EKY wAg_MU yhO7 ֎Gd?NX!$V1/:]8:I,`zC/ xT UEa7pN&zaǁ]^3>37I8:֓S//dح=0/wFəݘf 7{xiuWi9sE,pDLW_24it6Ru܋l$ȏ+}>.$:8G7jx&*u|[+b k"(HCu~JwS!F&ܪC_E$h&$̎\) {/6VJp ,-o'*hc],./W:σ9%(M+ )Eg-vWc{"}O_P lj*+hzpڋNћynqJ'xյZiz -8Hmh4qP-O'MRrOPD_ڕjM" \B x-zD1x79 IJ{ ïc[wD).%QtzkW y8;4]pюedL%y9R2n9tǒ>C>@~B˪9U~{@Iw(0c5r0נ]R=Bыp!ƈsypsr>,RуOC3`9;f{&#.gȔ>}٤(#UxX{lS׽7H; PB8C^vmiʣ` 1vRIZ ߦi}b]mjN[nڦjFJ+;{w~;u}GKOS³䉿R_{;omNFbh461B;{~p;H0/s|ZHdK àp.[+\F. :3*Xe::kLOa|F"1<_sjT//ܑB=3su/e1k3#UQbPZ͈?[V3Uj)BxcZnr"[. xU/x B.j8U*KP -5u4Nvh\.79ISUë*YM1Qs:ӻp0U ݌!`lEz]t,#4{ {.ҜYu5&d4peCtޮT *֍;@Z_3ia aYݲYB^]9iIZF9X\@1{{P:UDeKɎ$#~?nsUMyk8Xp5__̨ |r(<䶙BD~u vD]x\UO:$]^ ]P[ luWP2|P-«nW( So:v_0dwl7؝ 6aDCn6jc=7D׋t4{2qm(7Bl8&{ ▼hɩ%0MXc2I- x,>ݏ  c{dc ž`tr˜Oj+FF5Vz9"FA;ofd25b"m匌itt|gu >]eQgܩQ$e$g=`x. |/ kzR*m Y$A*puhMdtn+ ,P'8v}ѐnAuah1g$~_;Lg} ft Z!̨Y"'()"@Ɩ,` nl 7K+YpQ#/2kj#/|`DA5dd3S/ؖ.oicN5x Mz, -[K>eZ}@k;#<\k+Z]P梱,pѝKQ1x0TL"0XChd: eT*}4vKHbmhYIg[Rlov"gR$q״"6L<ŒDl"hZyPFk30DX1оݍOq awx{?<E, v wt63"   (Z!/6Nr7dU{*a0-OԇK^GW9#`#q.? j"jk#]ݍ݂O9”oMb?iP]bi%'UOF /*)B<ʻí4/ӰBѐJzON5S=+g4n {X(H8,!Q_[U}R&[ܥ58xOs_z_W1ìׯZg EnI0#]TrO?}p͑\ERC}~KHUH T9Pj@U. υ.`g޼<w58Vldx|#d鐣Vxm` 9gYAL"2kT <3Cಿl?uSjp)nx|p.p߉a nDQɡ3iCܐNT&K|Z)6xl g򟓔$&ʲQ/)c.s\o.Wzpbu0*c8# L<Cߡ|8l0rHly9<؍3?<܂NyQzr WJ `[a]Tګ!]PX?\ ɑԿ-*2vcqqx]`~!TpsG]Vmڝ! jGpi*u"W~D--Ř0#%BI|qJăXTj;>qxMViL\ֻ5 eq6ݷ֙ag1ްYf .HY .SHMpF6?pFVU5v[M6Ujwν,wμ#r[|A^.U`OK/;Zڥ>k&QEY( #qĔaIi!>駒D?&Gۅ,þ;|eN *%H543ӡ+5 2u 0I''L=vThH8雷BxDxӾ.x:q࠺*ս9o_ peKj=< 9W3!^,"LDXщ*DqN%>2"׹C6}nDv5T|mL"jp?nWӠ0߃I)sA &&Da(̌as g1IW`U2&Z=oUaAw~m0nIҳDVi?_V胾2U/Yɀ1j>i8oa*=h;S<#-n[N4>̐WEQ^C0)o[>5DZTx\ǚ$Vb2UөLр@U%a2VUqU7WP]oM(쩩x8[cHjjt\h"/dj|Xm=_Vu 2t.LZ_9a:}/\w}"S':0a}Qo_)aBkS* ^0,М":Z8,yS҈h®44^IL;1txp&Kw5{7FEZS`љ`\v*Jؖ 6|2"xI$ƦJq׻S-+541lpn,NR ouN1;0Y$Rss_ cdO7oLxf1c30Ź,L%M(E-MٓM\nZ~:WWK9&2ݻZV͗o企}4ޘWp,hŧiaw.ń e!%0Dž$x;: w : BwtFU>dlj.$aRxYG]1^+#_d j5lNXCGZI#%Ԋqb5SmlͱlTw|ؓnlJ=%UvRy8^ƒwyQ"/ ˓hoNpTha ]g9?zp5Bӗx%O`fbߎMa3R",)ފc6 `fT\Y8߆3~[mT!f ˘JLAgC[`P/kPP 1^ap*$|H(j k8& }G6K#m Q05"c/*#S*1:" GyQ*j$eDڗQɳ(96h*r~2vS}OƳSQ0=EwA1;>??9\odΤH&vc~=Kk\]*ҋ'yU;Ǽ鎀,ɐi˾\8˫O8ƫA'.y=W.MAI@ 4G٧J>ɽIfB(­y %O.\|Hm#cZɰLp3p3}bGĤZSt5Mvsa+ZL\'(A.񊂗yS5_mAYPw/9Βe e!Akj}"t;*}mg`eN4P۶lϞ jFA~嗦yp\5[ۛ^і~l5dY?}-Zt/ት݅fSO5j*nl`-7qM* 2'jmU2 dllCɭD:>)~Bs^;I?cАسhĘzL {0W{AwճRM>L|,PMIƲ QRFsTM*O5_TK3OfS0em7 s[MRUcNO} {Bِ^؄"ͱ" u= nu*j~DIAh),x[1ۆIOɽJXu|r_Bvi›w xi7@B}Mw6@,7~<(:9x5syJ/u/]0Ltik% + ]$"NlaGuR);{#hTpA0u܀:-W[b=HbCz,e" F޻/~ܮbr mbȗb,۸*{6 kxTDżӴ'aqu 75CE^^PZ~@ehඎ r6N}/z|0׍ K+ 2 ^]Xx4`jPj1i]:4xMWyp]eW$m{Ef}i^=)钶I4i7{ZrBt(B2Ul8@;RE߹e~-;w~_?$'q&ϳlS 'w`{_M[ɂ"T)S%46zʅN1uɣѕ4?I^EvLZU=vDy"+}6/Xbӥ%KVz,u ;o)$EkeG|?,biycX jin(t.*@{Vb깨Aat3*I2cuښ~`*rh4/tweIe녩aTk K|5y_F_j1T.F4bzL;[ ՠ6aȮdX|#>1 jM:I-:khPܲ6^t&.WHet}Y^e\JY^[ I1o:[0K )mAFRs%0G1nZIp0C63+FLz1At\ӄ*J]I]p D$Q2 #I쎤6LRGiũkLQ$6(ٯH6o7b4;Za;YTv2?~{X\X^Xl FrBU7Rhw5B4 ]ja(4Z*`xrKяӗ. plNʹX1*;} 6t:u!!! EpBQ KvF}af4YlfgיwHALgBVøQtIIlHLU0ln^E7TΏ'њ4LcٺhGZp30mM @/(Hu9GdTH*q!FR"7s w*۳x~ C2uF0!`7X&EBPXhLz?1^(\Ys&Vrpcy|LZ_ y87%.v&TF@B\ڞVw\J*͂*P؋Xa (iS;*W`W+lp!ɡJ u)wQJ;8zB)JAW R˰e23% k LSͷ3BC' ^*V=`25*aӉ1幌kT)_̂S]vU/>azটYIжY*dmL5u {YषP;p6-GmLyFCs醻P>nhdHnȤFU:lbO M%THSWupmIEIfUhncj볝ɒ00 YAɕ`~_k%Uۃ\3%]e[xK9(^6T1D33ʚW0Y8f `j1:-P{U^}OvN!ӡIm\IlytGߝJŪG:CP|w2[:ڵ<`ZOhFWw3ז)0{@"%6[Jgҡ %`.^!i\5= B2]B-f,RԾ $^]ǭHی3;gc| 681l nB.?2T6m",f& wSJÛ *70n3pi9`O7H,Fhm쏦7_ `-uؖ&J ]]]88օ ytxEuv@3Nzue*%  6PŠNm+,+|K Z,@4.-};-I&ss`1gAdL|T rin"7/p7zeHYН>WmZ='fUDӻo.52+Ho@[s=>79;|Wڽ+4ݡA9MqvuOikvژa9Jax e&CڑyK7ш}Ko:qq?Ka=1ܹcKcK I;SgƟ"p1=D 52ejaV@^4ѻZtc;FƢg SSE<:ӥ̵˸B|2]HRvQ޴*G#I2I͔1oǧ/DYKgfp55wW ﮍ )ADB,=toOrOy{t祭{ptaO{{K GƠ{Վٲ(Eg6^ij,W6WF?prmlj&!yғb6 rk'fbbtÏN;$;x/`:T/awᬘ rb Hā$soo 2wml>܍ ófi6cL̳GsG~/g×=H&IfH2n󷣡|>S2LIA<դp@L^3SaTI g-J ;oK*J!ZHRҭ0Y!R=QOLM&+"1H-<)qfGna>\uW ;*)\9I(~0'|x$=DFQ::RڈҀǥm"{<ʹV1ʧ β *["ZtՔ7 ?3U-.V ?HRC\ׇQ Tȫ#o2HMnʽmip{<(93Q U^*|TUR4ȩvu,-T%U;`W # 5DQPlj\D1 $X~Q5[DCn@-U =]S=̃!h>@bg$\mV1)Ut^]W(aHT֕K-[!%^r}Q8Dre7j,/%z Ȃ .quBKF/8<۟0ߝ^T]k[MeSmxw.n xx fBÄPS6CBKRe X`)SE) H_ĠI HBZҠeB<qEJ8}lm$L[t Yp!2vNla`m``"|ᰶ)ލݽ~p5^tŋxGr 3v@~^lj 2pc, CO뺶bO{aBϻSS#d/?1W:wS|Fe)}'ve;!Qd9nHb?XAtn?IhSyhL DtfӡJs,Ϣ ٰN!Ͱnt7\Aqp00b F נaĽ4g0Fˉ3}o@ZK':#o" 3KsY8Yr/Ǫ4N}TMOƚք-]s`jHe)`,Y$qe Ʒǝr#7S?g$o"D0ȉ3It:vf0IU}<% OAM,npҳX0}'y@KD6ʴ[ o\(~0qH qfJfմ2au6 ~c#fc2ooj\rVt,nM8Vh9_.Kٹ)aDjxMSKLQ{J!jT&ą yK"~X,Z@ E oA,*v\u,4B c4Vĕ!]hDFcM=S8߬H4+WV*Sn@7#̼FntͻW BD;bO#IGEK͖b"F8נ3Bu[$!6DK:9;23;9@)ɜs(>{b9ZNDGp')J:aiM .Gr܇5ȯ"+J R&lʤKp&Z@C6LF~Wšs D=-H"%YŊ6bGb-Y\%|U9O5U+*AAT"TMDŽH\OfU}紵#X|n$N)I[r U(] SFπ89oJ%c[ _m@c[0Qx ;n)֦FltjN@8킲ni+jz#J}J{R3hT猋nkh+"|B62HBS5g|Va< O_a x͝k\yߟO@N :}8/NE# .WLa{ e s5U)%l+)C^(.,@7JZkݽ{4#pN $tֳmol'h58?ߝߙ:zﭽ_+:ŏ?{/?c9v`2]1~5 ^{_§~:js{~n^uU' epp߬/W`_펶.J^ZDj[ ||:R(9Vވ__|p3ۢx61]ݟg8;e{G9*~?^_|lBNnnVOI!+??fӷWaW2) O/u=+HBRK?\lg0B"V,L5Ox"Sxpq?ߟTfqPV+ w3{ׁ/>-F~ƃpsr5-^Wf_$Aי+|VeN7MJg{i1-B9FGf0T>ul}1ٺa_*x+L?b[yTbtoxy44ai }ω-ABM&FcRZG φwZeHJצQȖU 1 ۥzvZ$i'xxʀzvӽ!#i.8;){9C0><%l/=[N h0ɨf#9ɒRg@3h[ F6r?S$n(PBK[ʮB^!*mW&=9٭nhzN,p+ܑ+6 D7qp㛃iuf<폧:#sK59XwVO)e'>)&3թ'Sק6v o|~fNq#k%V|rkϜ۵L^jJL3Amh/葳Yy_5Wo؄H)$2o<3QmΟ ϋ]ZEPj9X rdA`;<sjTew O&6`H s]Gvm *dz:ǝSO͊Gx w_5M geHdbQ)Eߣ7~ c.(āSUP/y U- >q PGZ$ڄfqTGbmUצ9+Dt74F2j!*YHI&# {W^2ɇe*D݄eή͖/ӂkpq5^2zeiZ7ʎGM&}F&M}Vs1J= &Fˊbq'@S)PcvCe">o(1U|I׃OvvIzҟNQ.j=lxD;9?$J< u+^ OJ3ʃTIN!_A&c>ȗ2 FZu5xy5I:e5_G48GɁ$9JWx:ɬC*%@ ~^"6._qGE(|RV7a|-S(F[7Ft0K*?>&kk98 $[lR~CƱ :Z=?'>eъGp7ޱV`2<zwc柌1!X.GfӭG~Ȭ?IҎR%06᧼ ' 0ɳP@b0QES:(ewO5)=RkG3|{w]ťVH&$֖[gĤJ ߁jķ^[REݔv R%ѕ۠y3 D~p/诏gH?Эom.=&a&xnE9m'Y(.%EnW&!)>%J 3!B4}hZ1"R9NӟkTwlnϼ{gc}w}|5+9[Xm Qib5<&/sHۚ(luZSD_fҌ= 켉=qp%RL&z9O*@?5X")'T#=N Oy%'Oqgghp^Zd{z(p{0׽ |TV,C%tQ@^l]s|85Jƨj$4mTSBRkLIC4;Ǯ>{%M|5K5m 5KЭ!Ke5aP@'L:6;tBOnAW_ e'SÙwB79Y%\<%~1_yy:Ԉ dIoaæ4#2mb,9@Tv+JO:$wٗojr2N50n.)eXfToEScR.jѐiMJnWĹK}BMߢ7m_`kvRgՂ1ZD ?*nFAOOtZ 2PbaEG#Mf7%tj˄$ vTѥr'byM lF |H Is%NJ';`2-SfI#8F@*SU_mpiѼS=^zr-E~C*'=/C0!c@Je^A%=乇.+ sjD"L=֒Dyr4%q?p07+ `h1a!%\kLޮ4 o5i5y,&KŽ#toІa%w(/;gKFuOD6J-TLHQ6fY<`lKSW/[Ɣu{σڳ5)PA~=~dbV@z" @@T -E@Hح̻LH &Z&mM2'gN4OHN|uNLtu ;2 I3;( "6݆.tĔ4c>W !ԝ>)Lpu&2&s1-z2JqiU!6眓-FG]":ʱ| sM; uSmб A[ Ȉ3e¶È:aS*<r9ӽ9 rBcZXC]$X#k'5j֝40M=JorF:z-qK:nZAdNYHo*r+N*Q9z:ђP") i_v؋obH -}Ԣ3mKSRH=`mtQ zt>@E6nb(dIWn2dHimӽ;fbccVڹ߃eBS PV/R7ug8Ϥ8LUBf5>SX إɮvJup5ݺ񵢂(-ؚJO:x` = z&M!; PfŶcĵs@_CZSntf C|Kc9TQUt,o`YɤrǪSlq!h.LԜ l::3ЇЄ׫z&z`j7ʚVho0t.ٺ%-[5TBZ 1 2"+FG$OQ.3p,Ǫ*F2jY<',ͩ@H,s$R%F548Nx쬍hswܧhp=VW%k8@_\2uPysӃM`8z]{eS<6ce2=eLCGclPZgF0mضԈ(99Ivjҏe,ȽR:dy"QrJV.fild^s1y #:/nȉ>=$-)R'WPŷK2?;j$$*K&fmTY ޏO>q1Kn<\]yb=h;[SزXԇ^cS)ɛ诱v%"ߞpj$5h5'XǛ)s )arfz1V@e1 xQ2:왼&XSTHhﴮnRGBlTld"le'΅Jp{S8qB؜Z}[3b7 Ĥ(6}\`HĊ A&E؟h係펃uϨ?_1c˺sSDM⧎YTOB+&Fm7P+n U {c:/>Toigt:8VTȩ($;8r9Tץ AwۤPR N!h85lvi;f}9V{1~F ʃ TE Tރ8W:)wcI>Tx@N(_D×q JN ̪h5!S%jÔPo$\N} 3uj[+|42'B{;ܟJJЄ{,* ^7q;ʹ@9>F1{P]J?ۆvQ!X<5b!)pkbol/mUKzqr~s^IA@xEuWa:ӗ ?ƥv:q:|v~{LF<{?59a_e׾VͳNz3+1]Xs5G!3ds!ꥡls:=O=7|&2M-4G[۞aOuu*Qu6\pyPLJbཽwlN6Cј@́π"Qe%KtFq&Ki4C8ucDyɄ8+I͔X3VIj+NvEOINCשpv!:)D\N R ,)@_P`!9C )&<ĸ{V&wG/vCYY_>[uzN䞶ui Cg{Sr} ?'>a"Ô,d}U5Ж<pk42xRcSqU],gvڻt|wM7[ ݌R1ns.ŕ7u)TPʇǨ.^4|IwV);?TpEzr'0o1{I'Yjޕ a#>oMIDɢոa*dsuo+#vdm \l|XkAJ]\vtFj$BZWlS~=T5 #K]jmzݕU|0>L gI!e8@q\(*jÑ[^ nۀ)@CE I3,7(1JhmY\Ԙk&t1=8rF`gɁI\Fi{Uޜ\l 0tb( JŤY[HD2z*į]0;OZPLilY_^W*TFVNqr:F07yAa2K݄Qօm7LNQI%B`J s-<q5npxu&ݰgWs+|-O> ]FA e #,f]aJFRl 'Yi*(V )w6T뗞|Px-M6&jn˦gNT'Nx/YeQeO3PR/*@5B*Z̀%wLڍfE&*6D`Uo0kbzK>mr_σ+zD]W8f,r^!. nƟF;x%ńKlE]>/CD1"cȓ}E+;v!f^>6@٨]Ơ#?ʿ+W}9|SbRK#&bt2t gTvNkj'l>?Ƿ{ɦhvO)wa֜WCd8X;9#F;f*5"^䦜l 0 =s qmvݮ +FrZ'̓!%NPb-}ӦX(7·xqt2qrMvj{dղ5\Sy~L6kwl[KBVF)RdV.)}1E#]s%XWh͵=yՃ{ɫu"l3{SAw9DrnʬK(=]KcRrq۫/a|_$ͯ+4%U5dWwbK} ~F}'ا%ڡ!:BC/Aeĝ*y)q] l(%ߥ qEج 9Z!2ʟODjg%wo@'tkA.<W@Yil\k,W'Wrԁ'_c1TM5XA;2f2F(rcaUω.s"ZTFw*ߦd _ S>rc Z`08:Gj/]X` /~Nh8Eu'VBjtH-|WK攁4*9vS ({"Za^0/aY*ĹRGʪdW@N[lvt<$-qFƉ%k JvLG_7'78c*Be9 ш NRcd67@rH+#CL_MC.qlNrg%yoCԵ)S(;8-lMfDg&&Q~ܱlSL2qwqW+/ys# W޼rN܂`j@~E{I K9W:sRSAw)\j\Sf0I#rF ".(y?-oyd7yO8WcBmAfD 'OU$/RhՊ\$0'q~BaY~xD #?W2Rdz#f/c\bVB$'Rޭ$wI_:I\ӀDFv' C0Wy3g&c= %宰m Q?,{),!gZ,YF۲%U9hC[%ج]v!Z$ ɥ1#+TpY ]lGz*[!~l5{+!u+6AKu`lrTO0ʪZ.z"F &V"N _čHEu/؇g{ ea~cP=h"vr?Zn! 8& C8:>"u&Z<͟IؖsKm/ƦͤٸcJ&|o2fZAꂒ4yK V5]X_Qb,Q[>j\ko KmC~yrpPQ`nl\ Yݣ7 /f~1#&H^Zt9wa6 )T}b ,ƅlH_+"{0i/#h:sy0'lEj|ƎlTkB_{ #B{ Q>J0!]y ueۡ0HId#vk>{\y%pfjdq<}xӨn:; XjN!*f 6s~36XAwvų1\eriёbƾӉW`0q!&FMhF*_[aL,{>2GϮ6w".VBc[oEHE4`DpLfEe_a9#ZOAz| >苼Je$A q!36 ͗Jw1S`Z .“K-&~u^7Br"yϐdjPQ1cX9 f#{vzLM|Tg R1;_Mb:`]˹@xAol&_uO4_(3rR*U*wFǎ"6C {(_Ļ4"3'.X])rfP YNP^Z5| h) eٮT/<)- (pPjՐrvaZmTy+]Ņ.e\CAـyɬ}AJyEez`u1H7d,c(Rglo0v5״^Y$1AeFWClia6^Vw,f܏ն|4OUΔ󸉠q9.H%t~Sz+m<ßJ`r7S#qS ae~*UlqfUZ|ibou7H Rl&qu3+U UfJ$yyy*3*[ hwFF_BQ.[8o"*a{Ns_ljYKUJ2NDS),V2# $0ġ\M=(8Oq@۩_/}1HonԼy;5[aEšTt RN2!Bja b@03Jm=:ƾ{j^x}TOAiAL0rQ3V4<4\WQ01H 1zڶݤ5@J O6CmJ`~l[)vٙ~~\/^P-*!n/؋e =i.w]SbСajZ%z1) O-QEx`ko8q"Sxʄu R(>BnT'=^נJg|CDJ8[&7bVWI$?4KJgI }vmJA%Z?ueND1DI \"*D 6^+ w""7,If(h&e(~tu;TaЌcJI-@! MBb?Dؕ})MѳAIy 6tW}ETM2H SZgFt $HΨlqlQ:޵|/ :0<@T͢H&>jR:bZU#&Zsz3QlH?3'Im,g>irH~ZG:܈>c?Ӱc:䘦RـrS>uθ݇O-B!ΝkM{LR6c!'tSSQŤ^2qRhr? hU'-D76-漐ST6mB`s`J7#`y9t8cAłOGVr_L.^Tvd@s9"QrGt\Eً*3T¨@90oX5/ M#p^!t2>jPO Y8ؕFPI<%ǽFIc#O.c={% x+̴  e virtual hbC ejabberd"}. {QP.} :j /FnH|OqCW ``|Sa nPn7sSzO{IЈ8ǎQ./ZregisterQOP εγγράGJiؓ^QcxW]lWVB[TI)D1nT( Tj]QDi]{53k)h^;&F C("PUOeĎ_ya OwνwvױCx6?|;eĹώy5)fNճt'Vn qڬKpG#t"#!+^񽴑Fz׳Zr;'_??ptq{#T"jpJ"&('i%di0 d:O* TP{m]B%(|5?UG@'$^͢騒~ʲ bܳUIJj{)PZW2=e?R1b4 6"7ˠ䁡=Hr_;ׅ4  $bVmeWdO-݉łHE;-%DRӄgpnrPI27mz_j_FyhCfaQbt-/C >:wR .|@1yÀ 5=i[03M mSAQOI^*曯n^bc铟\(BvQf ,B{Q|`0s3ke rКw #VTcK\cnֵYNKH ӍZLQ#488\yy_  ]JLP[Q%BZd~8w{dI!ejA !:>DZFw>z3:-!ӎz}z;mpf+lH _ujq7JLw!' )˃ٶZ.XQӟ<$t5@G9V^ LWA x\oe}%c]Me 4I Rn_m-iv hd\hdESS>35/<1;P?^}v}}pSϗ y WK41aVggnB$#CZ!`&őh%sx_tSqOl4x4i{9|UGoNʉS x}i\ՙwp$3pFH*lO4EV-Ur.Ä CVMӁ&惐B$Yi=K'Ƅ!+{wx:rWg#GG~XO^򣳛GNo99X"1n#ƑZ=5Gj|byds>.&l~,zi/Ӄgf`:'Eŋ|Zwt8G~jp1>v5/{3Ϝr[U럘M \&'pg0_Gz.ݎGNMxzX/;<<__?X^~~#~?=–. |rh6<̫8mGon߬xl}}?c{7^G�kڵY8ڛ.GBGWﰻo?Š~!?ڿRꛥ0E[Wi|9ΦS{;X1XߏGx@® 5-f' %nv|i0`-wh>[-q<rLu`-֟E ~{%p-FPDJDxm9ƫwG//÷^~":o?SWwH~b]G3$T.x_o7r> =l-d}SK#A(<r户 "$Z <7 9HH"Z΢`G[1mk2Fh5j/;yAKB߃S /@0>з: /(Ď4Q?.pv`'aT՛-ۂlܒ 'rw<!N<^IΗhx:ƳH֏@WdV_\"d`=бS {X~e[CZ (Y"`*ʏٗmɫ_ rzхhg6TՎ7;f;K'fЂe( !Z&hl`?N0wg=>ѩ䟛%~8tcvf|1& mj(+ mqK(h6(wf TP ABi]Mm%C3\eII̦4~C BQlJ'Z,^uYaYF\ugO:}<S6-_`_* wOۍwN^meDӌtL-aԪXgg [#;CƕxM+zoeݫ{# (ycNG?1sJ&Lr174(,BZ,@N68ly>W "q?[#a,ywH3jY Xix\?!$)x:Ozfe6CCZ}C'*)|{Yç/$|) M2l 0E"y vCЫ~r0_Fgf$-G℩8F6, TrMeo3ѩJi`j;JKY>^{lw/#^)\d7^  wbbDwS ߐ:Y<ݣ PҋMND\boK &=TG #:uӻ{3_'TfBBof`n P/v!R+&É j@z^kl/x`pD)&J ˴56vV4O/`i‹&E= 1xCFuКIz+j,7z4S Jdn2$`ѴS<lܐ۠qT3J 8m+LJx |,zn7ޭ3.mm+~E ?7X,.~w|>D>8x狍86n7,Af+΅:[xLhdYot-oE/.x @\h;& _b6S2y ji!Dh<[V-XnjrW"lF .rt "rb!ho#?77M`>!sd'q +Y!Tb3T"v_${KŢp@x>D/I&o1"YJc9굢]P+EkI|rYy7Yre#P'E(s*-k+AI66CJЅaB/h3f6RunuDyHu+L`#la`K4X"aY d(L&KT5~@=.3:SK,I\@KP_(Cp9DRPRW#Z*PdXN}/ _AϞĪ=e0({0 O>GXV糂6}ƻ3Dғ !HoKH2os]EXn%@fgݶF EѰi0c`IR6߄=+4 ]K}J+ߘw "]DKֵBDDI LRpgXֶo}tX!^r1âۧ fXN민(~]nڭou^kX8<[1=Uc: ]';!&K)\Je +کZfp~(EMR;ILb[^s5~(tRO e5<@t26Fy^dF0"G"|~Ei F%`wQn]F(tmgFA&hm4e8dٷ ցh3ZkECs8T Tw(Uo Ɣa'4 xm\%3sI l(9vK`v0~NW"4Y[f-U I"q4>p0ɷ[!yd4Sm/}Fe/IKtwgv- 6rv 7:YzusvWsl+{APSmfcݦMq~F&a݃X6zЅ5ʦBdt}yGbb7HAmPISrTkCl?]6W\`EmYbx%f|apA>ػpu`u.텷sf0IMJѲrtnXHh1~ ~ o.0''IƩ(qs`4B?"hR#u x-:}rO#q gVnk[xeUPsXg6:_s < 92{)X4i[@ 7^ڽFhBw^<_lTVb["HwUt!˽N k֜G ={ bm$=lH%6+*9Tj@#X%1l2&{Xu׈&/ڤ?@7ac nO؛R!'wЪY}qHjYP÷uOXQŦxUcTS9.5|h:5@>Ucъqh8ǪMÆ4~^L eY'"L7y`Y23 ,"j?)uUHylvdSZ*YYe+1ЪF  FeSPbݝ8 /=]^ĺ# !Y2!c&|UTPXl M@!CJy y~#' i≊rg:9~ S_3h1h/V?JXo%b]X҇*xj>{׭7{p60r8ws5A]gъ}Hږj#;1er9UTUjU0jkuqƢMl|XX26`H JڌE]ӑhQ_S+ CL*]/ߺ,{ѡ9sΨls.זJ{ػLzHb''_4He,?X zAK~؋ b5zX9S݈If3 2l JCw4¦tPCL0b@i9 u;Yy6m{Y82,+^ۅ 7 X,ZnB.H!|*48~0 /0f;!r#P4lTx8UE׎V.`B1 _7s}d-cEoErfg ]<ԍ63w!vaC8,J6@%[T$Jɀ;߀,;ɝhXQᐘF38i2ѺB!tnHMq NI m ٮoKҏ5h㻮Tl F՞ f@֤%𚎇BΠ.O$#h#x#=-&:>֔1!Ym9jp-e2 jTG <)WY/MVJj9JիD k.GUN$c:Or<`3q#icʏ^?z$|{z] aG/UȰj"}h9h{P܇ mzE0[ $>_@[`=kwWp1K8)/1];( Ed'mW=fh#u\X !M蹾>jA0|BS),-c9ѕQ0pb#5dǃ\iLu͸9A1!3six ~!5;A1jٳDP8,[HUnf"o$;)h|K|Y&J7Ȇ&96r+"Ef<^8 lqg-rq6AXE â*"ԖJ<E6{+E.z]!$FpKk.oJVlR:eSlݘ]#\pKua _ ?maSyweB\e@YAy!ΣTF t_g&AQ,nDz (r:RMBc g>6fa^xeٿ1R ni C S 5~1p*x#XaVR*l$]7BqI~c%s?{zP$ 戾V~Xz,z@>$׃~`(T5j{UEU@L' Q0$;t> 6B"=UDF 5m(2Xl)řc0O`FkpMD.|m&7M"ܴ_ģi)Vxl pn`AVx%pO7!芩AY!1XnAP +9/X% [{/ A0x?dL6 yq'<^||ήX cN~,UgL ῴ8%m% xi!wbm㫋<^$pֵڈ`H٬Qa[4PpLTW1˅s:fmn| xG/X9jtT.r%1Ehf,B֡^S922> _> !_|ƓU%c-(0iU@  RB=`uvZCVBjC[hhЙ/=$) QJw<`8K Z@T< dI(dZE~BԈPȅ2TFLMZoA`!ܖɼz7 ܔpt.K OK>^OYdLkx[15_dR`PݔTgҁN`R;= ̅,[Ґ_H; B)Be1;^ԁEd;q"cnDt6;[T.o !\P̉s=I;N㶡)qjjMJgNK:swlfLbo#ݰg9~u* Ls{ H:,ڙȮ4 o[(TfpJp{:c\ CxGq{_+&*' eՎdN, 75>c gN!W L ? Kr{ ;ۊ1F@C!Ff8tb AM8"!SuQU8HF.qu2B_Lx`'Q 6fdv d6YL 5+ QBnFIۤ\y&d V"Qij̓xlȃȃ Jr׷Ec?44Sg]&LJh6{VҨ2cڛ\A; F)m'<3x]lNڰ_>ߋ 0@'K%B߳r-&@:\jUI ;* G[ rqXR(,!B_ۧ>v7] u(%)P^;ȑ^&=f+aݺÚ34-.D|Z/ћgٻX f|'h=2OAm|d"L" %A1āu>V[)}H[Ż"ˮpD#S (jPoesG&HfU2$rUMD bP*  &]ꁨXNab*>d9bG~6{H"U:'QU䝟٪2~vl80yRГX@X*M BtbxH!81jL EQ37u",(zpC6eD"\d Se̶<2tY.8RXøq1#FvJмFvm hRVdž_GbQH0Q丙4mMFSd"_52K(UËamsJ RdVzf"d\BN}|5)c qh~a Dß9I"P;W (-53M6SxCVXR ҒtPH"t6 Jܔo$P $A$6|Q1W =?9+R0y 0Opԁ L܀15X z>WWH'"$7h>x2x;Y!t c" Q~_+0_AGjZuO q`w-^,9ڏn~Vϡ.)A3-u ;dd2$酬yIwi z"C PRYO1&OL_&B&YoC[Qy`;{,w.A-6dRjW.nbv @LB'g 0{`Ph.!=a/ѶM: %z@ʇ'Cv1&,뻄@1%ya8s`ͻ4A܊o!_'RĞ,b G& 59*NAf y6( |!EW@*ÈM8ޭHQ~G$YhQ`.mۉr%Pr lKh·_Am磯^l0D;Φ[͊t!#6U)2L/8#J$ )s/˝p* ~&|0(Yg@Ņw(CE uCL et^e.f-uvڝwjAg1]WZgP_쎑tkc_^_ZL3wH-u [J9~]*x&@0RiS+ &WJLvJ$*݀i2>BjM,/\(".Fbz|*'6;wF0^eT]'bX$x43Ǡ}+Oߡf'.D?s gخyi未#LVDZVz$a}D?<8ipT&H@NOZ-83pzpPD!RXzfZSouȜzv~q0,H&p& Am)i?M"կ; oeۆ nؼň B61Syp\z+Џ&DưB`Yj(zFnscFffnbk(tqK'#wG x&O(mWYചള3mAZrnu2֡\ck;/pg \U9E)x6Z*p԰ͅXP(lg 2LXv3 }Wan< w&¥ʳ,=I90J%@9v.е1gNh318it;ZO‰N}1ux+^?cNp21rM0 @2hѓF kAqGD+cҽ*a 2ƒ86\mH)K'Xș u$0އS C;1ᐭ/d=1S5:-bD,0t\WE{9Yn"SxLi 㹂(63L0m-<tΛGLE!)<ժ*%Tفɀ-D[Eq73C\e줣) 5P \KS\+N3 'Q)L]k\+:N5 sO6zƢyܑ\ON9 N7fәz{2KRPϚUސPD}%+T 9PƈY;[doMX%ۂý.iJ*z4pxhkH`~ Lwr`,Jp)mzMu׃-2?l6b$me ֍eB2#6H =+ȮZA ga4[h0~&xWeX8qՈ3}ZT!O8ܜ )gSw4O7I;T^9nV KúǷ⑿ j#KJ|'^C9T]k3r0'A0? j diW֩p IFHփE[σìopg6qhh@RݟF; * Gn,+]kC&wx~u!)G'ܑ\/#S%1,FO$ ` 4bB)Jܐ p=H3E[)ݰ@w!`vJ(wWOнK K!FIr_D̏iњ37v&-/dL4d&c<9k0 LR) ̔ wصuP , IlWJrA= lK?+2?GcѓZsBԂ6K`AjiEꊛPؙ@ppQIs:5 6DCJDPlyJQVۜg#/{"50Z@V>:)|$6NmҀے\c1i):w \+<OA+B&(זuF֮C[`r2n-4'ΥK0|VR``.L-Y1t: %OCeq8r8TiEgoP`0 %AH,.HO~*O"6Y}mjhuɀK*Nh="w2)vPȍb,o&;'iϩQPgȃdÿb4tz&6Ѭ_̟6b-[\F`k\a(0ɐpm<]QpKw-LH7 g5cFq؜5(MF[ JP2wXT@Qx4$CẆ=kzhU\}$l>ŏa!C(#Nd'sgXI]_Zg 2ɠ B *ou!`r_: l l1WΠE[lt4ZFe) csIQ*^}#9۳ʰ#1g'.ôfAȈfEz-Ā|ࠨ" Rh9TC{*9)_2&'P*F)|)dsBХÖ]1@cF>i (a⣯-峠gcIB혒h*vV@Q9+چ#(:cUN#J`;N"kPrۢIƾ?bdi.{|TQ9LVX;RkpY\B[VDF$GLNU6"Iō=W#̆0k"xKzظԪ=1<s ǨXtrLєwxꍣi6H!/(@Tha~vy#4h?4x C,NC@GmKa(a#S&E%Ė>!58sJiI" ]T{vAĭ%"Q[9=1)LUY4P xH$6ZX1%Hn;p?yP*WZJ,Mwso.U""'f*`ԍ1S}fypO~vj!F2ؕE)Ҥd]x{h9o32WO()}ڵpFD(۴-wh"i+|>Pd:'ҩتaEZk(tJ(Ar~Mqo^ߊtjEfX%nC)Iƿ80A;&Ox}Y TUe^Dp|pYYj@)4K½UWje&+ut ͪƙRԴf՚jV5SkV߿WO?A )'bi<1sp,’?[q?G BxX@I-6/EQ\ ߴD%VS"tT$0 Aǫ#`|3S%16F4Q gP(J9\8B=õ(BGmg\1I4\=Q*Ms"JVUtx3Q.oޝq+ЈD_E$~{$EIѓH_e'iE$Aѓ"xTڔ0*=VBs6t!_Dalp"*+ Fk]_ Y}QViXMHg./"q{cdNcoiAuVQ,a-i_c9ʜRk6紇ïxvU{]]*tN9YpnjvǕdΕN_IndW C@+Gp\he.}8nG)SZڃ8mG&ڈ h&'*6xp7 QR@o>֎Gp|Buْl<|׉eOKю4h 4%,*Nyjrb6XctT!*R7vSakJ6c46)b<޾f^nA69@El5sDA6Aqv5ֳdXYس܅e$"^{Njδ:Ʌ#`fQe [Fڅx\}iX<~s6(n+$x0`d rrF3 &e͌EF"]UMcbK2P0 dQp(/-Exi *-%8ZPc9XW s0TN<$l%f?YVUx{Ʋ2ϷFwdlL @NJCO {b`Һ^Sj*Txt#I ]I~Ms]?;:pcHC_: 5tT$ҒekE"'("G2="~)Eʵ)ց ȍ֭ Y 4({8@(oƁ(5dCcq sm,:FP+q.**+o}~5i3P_*~%hNC!:NW5j*5,n K<`Z*ƎtMnOQ+!NAbX_êG@:jbMƒ KjFCyVk8N' z쯹vj?$X|&t]EEH^%N/sj}C!Hm߸^yDūlpZ;Zjtc-8h0{!N'G0V&=pr-ȃ⃕:4׊ Z6QS A~Nx'G^P=eBM7<*6Þg_ˤ @%-BԆ"FĤLVa߆ܿQ1 8{(v}JLуMbJ 䇵+tXen‰}n٪)D6uJhffx-\DeV㮣CL=q8p4zk.邊ȬNN}}ٌVS%z: mY'|9=lՍ6-ME|)u)g_kRLJޫ;9Gza~&y&ъS?N,D7 m iƷDV Om Yl~*]#N8#/C34"/@*<䮩_i쭬)8ussu#ךbv婄{Vek%ÜqмsoC|fn;{k{ ׀g> 5^T`e5/1N7elNߚvh$Ζq֍Azړ14zrV \LX; @ nԅ6z&ްş7cg߸AݾiG{*bB`1dzd$+1T8g,-1^g:]1&-aVCbr2|ݪ+c?O=/CW#%<"e=?ݶidqbk"=Ƭ*:(HH''ӡЃVXDݛч<N^q1HZQ{d)-ɐ"L,ut.ʥH#)49h *3~:ZuNaJm ?s6rf'nyz(=yz?Q ?Lړ|N%Vg#< p$Mb47ruW vY!t}zm0>3~:PLKUFА&vU0I|L]vf6̒l9Q0Év䡶:2q{T7]tv"|;>~g>نwR$I l#dCJwI >|G?Ea:HjvID4|27vq?>hlWQ6B6|\O꜆2yqXx3ѤԱbd/E/eˑE(yˏNKߵ|2DB̕4\jĕ~u Xk1:U߫?$D\xMV{PU $$<|L ĜF8(C@TDh DID@T2&@Ԧi0w5'|K; YAyE"*#jtIԵIɩ)+Vy3Rs3"TMn-/+"#`hlyN@"*GyQRG> Gs5yN6N:<N󺪃T&_ldh0Km"k& k8^DP͜|A݃jN-W n:"$\D;i=K,9Cnᜥ]'ϩw2e :?PG""A<)PZTQ)L ƨDVDf\B ;ADr9P8 1gf<=/7u 5e%eBOoᛙ/{1{K{MGl>V qm. y;c0+M똆s4)8Y+jNM/YNO"5:zԿ ClŏY{ V:Faj5+P 6dV TĴaͫpe|:0DU e2:=9GN#tr)BeЪ85&RI5a(/?zK.n`m0]nߍ"-}|UKnN?rk?bJI '.EK%X-Bc(ܢSenT;rDh:}9"pPx>1i2* VuB}L t: ^?=1˨y`rA$tA2(d5ʰ."4QU_,r*sM\=WQ7T7d< 0p1)>yLJ#~|RȂT,)Mm%<T6s5&x4r/2W0嬀ur~yWb~8cYUk!f_/=.`Ζ<.O} IthnsNuC hǍ6 \{۷3ݾqjp]W3`E( ]Zjɽ@%SJ=KџSaV4 (쌷Sz0eb0Ǻ06w +>vxٵ(EDa͕ڛ مYhbewutpTkC;'ut˲{ZnOK8Ʃ".Jg3R>}1([4{M%h3QʗΗk pXk fM3N/!Yh&TBRӀ}~z;d_%͟ƿJW(8vKϢm5P1*Jٽ46xUN81C݈?n$Q"]l>Zkp̷x`,σyx O P-mM6nBI6PG@$tH jNviGک;ܻ ;C={|;w=[k"AD+ B*4iHݦlݪjR%>n!?\/΄9*egq}6G["q )XQE ZQ5P0CuJpPXH< עH(ƔpRUA։4TQQ\a>cKz@׌T6Æ&}t+hI06DFOYxt [м`WonF?L-K'd0k#{̰U8d[Mt},Y H#1UUqG7U^JTMDh0FGԭ0C`.p裞^pҸ^ M6RW@!l5o%aq MVveeK)'o~<6M$讪R7k46](?$Y$΍yd.s!ow 䁻ݥ9>mK-8 -YeYN1Ky.;%6 wNJdAp?%ü(S5w\\> =ۺ9Ik&(~Rr1=9[7JxN;?{9M>y$7|&]$ /{q,Ֆq!ڭ~ܣ!Ct_>:+܋_d NƗͻc|B~Gd2 #;lm06#Sza/ﱛO>{fc˩$s4x}!p7lvA0[NxK!Z)h9/w@iNC hyVhMYaQՂO#alJ0b ?SzI>HwO#)I#H }$Yd"‰*d9%oHQ; U!A2GSyKr" 56@⾹ӡ;;げ{gW's!X)ۯJr/^Jd#cYudsN={h)dX$FٞKAeSϺ#!!e$}v8ܺpn^2:?pa9@{q9K5 CfT%rv|9*ҍ$IOJy/a[{g4iD4(_^e^0mctP՟а䨥+Aj Ab%"Hs3B֊o_ DxhHbѕbj  `T֡w+y'KbP>7% 6x@&>`9dّ?ȨK53`UŷUQ T²RXVR!cF]!wbSD@ r0"t[qpn<߿`#J,8MtdYiFYބLHS4QXPެpt"u O s$WHiȶy~zRad1+حw1bUE 7o+) jfJ_ K# 8Mc5KV6[zG d$U(` 6o:3RP;xog'̓_zCNmfF'nH=GÃߢ(h( _!Nj[QE X*i3DV42Q%Bk%V)1Ȁ&Xݐ>W2N?4aFLqfGXTă &˺^>lMu喚͈]r)~ww"UX}K#;`uj}D ڸJBI RPR|=aUhMC=FU}0J0C".|rV>5G(Ѓ26pdptٿJJ8ΐ?z l>_0A=y4߾`M9ĉ\nQ8D d}줷4gSUr-%: aUH`e;$w!zrk;ƒ5SG dJ4߃,4 4daݕ0>W2]m>xUWyXVe{1LM \jilZ 0*.i ,+,rIQ)7rGK[ɭzifirw4sϹ{=ιGN߼-תޤ3g&(W<)IUS7#(,2S'f,Hn 3RLnSfύQǢ=w bZ/9B(*E/lh FGޝuH|-vVНawᨰ%Q[pmpmh< ev]p Jg;},To%ߛ@u>)Lpa+T-R6,>A#$ںɶϤ"aԽ4aTe0}T>Dj鴺kA5i|LH 옶ra*| dvC"Y4!A6, bjt:݊ZաpYSUlR km Q MUFbspmh|H1Z"a4?.f>K NGzO=n`|0Ѱw0Lb…ibXƞOx_bYC7*.Ll_$n>"[>֙a2 uJ2 b ~n}S-"+.v|Ȣ^vd:KQڣgyRV[R&sȽ˩O}TևseO8HdHӃ8{؁hЪC1;rY07o:.|J?9Mq_2hofa+R_VܸNu8a|f!#;CMմ6;"u\"yǯ_u-,~E dӗ9#rAfԾ;?!O0aꔖ1 K8I 7C+&/96V-XC֐=WΖ U?\:kU &RցoW b滫f R&I&|ۣ@oSIxBE(m]@]Z"SX!:@qu]rP@>]/GH T,pQDn?t<Ȧk %uÛ2pd[7h뙴YI2"R7ze<:ա!TWׁ?"X{j . e!`L ]$&GucJN_ j9n^LfRif B7*t3h){2Q@u_Vãm/>ٟR5-j$^^ *sWGNNG*7W3vD;Ʌ Pr#tbsg~dw! /+ȐM[N2TjPַ$՟ZG\|s9Mc qGCpaF.F6q';s[>dWxe`ظ@ge;*=Q9n(o̪.Fm(}x''2pٹUqHt۱h-HԐ#n9H 7b ڣ~p3X:cyzQ&ǏO:>y>Q#ةx' 'd `}~K{-S {;}1ʆ,sg~dN0d 2/{e՜S|}zMCΌ撻ߏg&>; )ۖP(HZi-:tS2٬!Gɦօ!?~ 舷#m0lòM<'਋#`Gܞ8_,/nxcr_wP3/'prq99hn.1! n(b&ݸ]9az\9+4[W$颇?$_|rB?WQ+Ti{?ub߄W1LgF?vپS E /Qiҗ7AZ~s7 :PH} iSK20oDty Zem)h݈z,{4y|x5UyPU\dBA\Qi.߾XSZI)M\FDeUYD݄c<>eUQ7trFkrsߣ=~sw~߳s,ýڕXd9ѝib0%9L,·Nn5=ΣtBy1dM!C¢PL,^,YG0?I><3g2T~'Xp]0rc쐀Iƣ>Gї^A—+bS' kV>t{Ѫ~űXnYMLzBg J/j~OTrvcSAQL,\vikJfIx}M- e (}u 2 lX<Da$DS+[:m {ȪWWᑜ:AS* k뙩Xn3oscihX[LJ7,o)Y 8'?Ke%ҺduL*8N텣pjeË^XSBqކ@hY/8'%Tj͒dzm,e7'Jqgi!ͭUa`Z*ØLY˶:dє$CGml Lu,+wP2Hdx}Vc~lгwU`?)` _%3` ز(,Yv\p!Y38@PUu`+DRz0~o)./߷6ߦg\*Q]0p mz3 *Sl2PH/-V \4D;P (vQe!{LEIdsU3ċcmCĤ3+R09~dHɌ;1 N=rb=(1߯*/:nj#j+=قLjyiM`5SSM2c]$ @x?޸{/DM`Ņ m}iȖ惤aps5ŪD[cj˧4rKWƴ.Mí\H~n&Rh Vߵ-/݉=@q16*͙L/-𻢆K9 /'pd/rE>2vBv{4vo~xcOO-gQtYMHtp ޹:#he*26} r=Z,?kq%uD/[͜ή|u И.ച=Qa/sݙ(NÂLç\·{8`D r`* @#6h Z_䘇1΁?/?redP  xrƱS )I$oRY"pE%)p$6DGu~@.eIZ3==3=|sbQmN˳ɻܽsnu,2TgoF^gʶўR)?Ph5 u,Xf'WY[4ȶ\\<ߖ]IL r50)5ގD _Eo#-IdOzYW葯=̫H;O7eŚ Y}1~N~āRúɶMyY͚}K3"k 63;)UNvڔE\_eU)SuEVOzS՛=kwߕYWz]|1x|w+.C5vXƬ?iMyR{Ibhٶh6E[Ɓ,_g]?R&16:c40ŢcCBpQe?|W/E+6@zL}\e5RYmщ2Kn-{ iB~1/A>+2֭͑]9-o)h˲-zvUXIHF4ـRg3tVLӵI]lQc~rcD]2,;_eEEEY%퀔PD"C[U=#nU`UW7J3ddۼm_3:8I$ 禮7Z6>;Phf$' "I;}Sַ?Sboy8ol^fUoe@L~uWI˩RiS(+T&{ 'i*~UIKMc}=s(|K|}Gs/kiNfj<ƚ~zameybmUiL,UaSUSpN|5MFS_MWFy=\#f-qNIF[iuݲ6(cXewBϺ_u[.(V)*[an{NRm$i, 2f6Zb Q;Ų59 uWBOAހ6-!4(c>/L3|mK6Cl+tqo`w˜\ qЍqsԛ k=y.4,S&˚E.+ް̪"+VoyaIbMKPF[ Cyn:f*(h~Ih:Yxly\_|92AAt4wga3LJeݖE߽eeM @JhGF48`0,uqa2{rPE3Oz9Ow7㫞ɭ9Y|;3A,Ӱ=yvMt׻)]>́7'q ٚxW,`?'z}N#Hw/ڽMnXGӴWIaf]kvCիzKyȼ9oOWxqdzcFdDaXm"zOPzvgmC8!t7&Mw??o6vFnoYM3&,<-"ݚ(Umѝɔ}ۓ]BAM{ls:;1\B5 pD⿳v[Y2${MЉ ,"n6Pm$w4*c3B[0v+B$`gDhƄH$Pń.SӏeH8 8yoJށGʞqq5g|g0~ܔa\jkQ>pO$l ˻6vN=L0j}?WkTY0gƨ9ƨ쳟$x&4T?Mf ^vXtO%3& ?؊ kG\+,%)?%vB.u7'8S2G!TroRL=j" lg $U/0 35<\3žvnCG97 ~%&x!ćޞ[5pWAENOc(-5[VX=P@ W{^O2lq Y,Eyy"[֯^wnYb3[o#d`aϥ+ &3;z]:Y/#[d1  !|nRS'p61@[(a"WcebQ^mO-9 )0c;(GxLqX&,B#,v&YWw"y!]CbA?=#%WwmAYȾf]%eŀ|%%4*BD6aKlnJ8OkWnL@vDf"8o" _4Z^JvGZa5|j[MS7 ଄,;NFQÇ6lSt|AH#NӆN1țf4b&ČV@&kG lb8Pqe4wf3w.cQLOlnVZdN1=T \*<&BЂ5tlphW8Sl~)c㇃ꏖœʻQ~ax#WIƨa/+m+p8WC-a`VB>% S]O Xg^R$|SlF \u@Oj`Hߺdw9!0.K;`:RrCXHؑs-0hHN*I|rɞC_ *u3A~rI8yK@s&~;3"uUr?|()fSӌ'y|+ 1 /|u&ErzF} ~O\@Q OWDUp+l5\R{daz,_И@NQ4U-V<a0QU匒BV[)y4bL7M2]̼ɣ2N*>1qsZvcmۖSo kyj_y gz{c].z?g}KV#pG t#uڜ7Xyl=iʀ ; qR(5V^y↮r e03Lym\|X4KԳAEj/*$[\zs@: ÜHUkܘSϮً^޵6AT )QH#0.[3*;ӃP`-g 0!~U*S㩢_Njy*"d.JLӳ09H'PoMm[y1.v0)%az>UcKEzpIMn_"g8 SkV ]c3ZE.0zSMEC;>G>Q`ӞOJv]r.VOn8S}퀈[}6[u].ӆ6\Q\ TB]ÍB`,jcfQNE 18r<9:0­XzQUu i/z8B@k-8o!,VqdO"߹hڸb޶cLUdKys֐f% #뭙Ƒݑ `˼աt8oTA8bJ#htkxK}v➊aW7.iK . Cۃ{4 9FVk`pb;t~݈ p9.h!Ő81 ٯp{m-Z=Y`5Sg5* Fn'eEQVT>UY7O}@2ŤZXV6'K= /'bɦ3l%e,Xa5y::O0l8YM1AR<ݥ{86C0e{ at]o"s_˛>K:T^r(N?`%1/X#1b9Fk`fN. b96GG <4:-b-!w]HĘlj3Oۄhqhu0{(8)Ç@KC˾jYpq_⅞@ѽ?lM*ZF95<h綛 JP+(9ܶ`X-YDEǦXm\j A>EX8@ixCbsQ#B(Cbrs4?d/qf#y $#[&;d8^`HP*!\!  Aa%Ss5E8'83!y(b.\Npy+p^虞y2YHo $)7,$v5حHR/7K$ƘImҀ! _(Rpؕ):_֏H|XBF0${ 'KOzލњ~4j6)]8KX4J`*VŤ3iWF`ۿl9Y벳{ %:,;F5 5ꖈOHu܉Y=Q>|BlCǃчFWL ThP'r{*yc=(ehD"q7ƶ `E-}خ&%K別#xa G93~m] I" k!&զ%Cq%ʷWswo(Ryƻ s7DVTEw+Fv@:ξeD첌I*%< ,pVsjRJxLKvq0=货Jwf^x6v[SKn@鷞->JƠCyq1T2|gr#|XnT )xns3k/4$Zn-`{ևIcjsLB==s{c'a@g02b@TU'/2^X!eK`>6NPj>tV|:tIվњdI`W-1_aX,ɴeT4ܢ\QD1! _Mç*Rڀk,JJ3I"h һ[O pmY_$UMJi&]34: 2~7Ti/eYty&*!Rz}0]`H͗cJ[bm"Hސ>~^p]?/<[_~4.1\IKFZF\XW[>~ _^s;7Xtِh Qyy%i9a,S!H"nx0%PLXx:XyTKҔ cmb4꠫uObn_0gRI wt?ݮ0 3[Zl$"#mVHj,3~.bAy-+S._oKD4FTe2)erg댟r(6M+=. d*<⾣͍7_;I$ wTSI-l6-A]W:n5Vsos@{ZsSĊo@F:u K ('H d 3nnT|o+Qs\I5iZxW._SkZ,䡘g:hl 'DxfaQV0ytl"+^GOXO@DOԻ"tHXi2τC3լHrYf$U@$E/gdCk6͍4tZ_@-o>439YW?V$V#BbRrM: &o*g{ŽꅥZvWg [I{9Pz {7N[],RB `6?W 0Glגp"aUz4C,le4b>SFA, 2燈FIt)t% :U}b2ޜ''P%'#/il~{FĜuGfA0u7?. < ! 6ąIy l/OQ+ DLC\TOy7䈫#Q{ (0Ss:_GpHa A:)7Y/uFwt`k"g9-Xy'II}Bcʑw-ˋ&*?p&)dW\q;ʑx4CN`蝠N)t%+(a)$*!{ d'2a4:,_o\l{-#@*Na R[eS(v jyU%}!ѹ^hsq\r*i}a-ZO3BaɀlZGrN$P~o*p 7r:I&O2cq cόz?/f5 wx[qj bMd<*hOܖrZY ;6x}Ykl\u)Z)>ER\GK.%eZR%Zq)Nm˳{G޽w}TfAl@j&q5ZHp6iHu~@ F a Fϙ;R6ܙ33c|b%[D;Easӵws-;fMad)fֳkPDllVڵܔ3.l]^0Ova녓}10m|!l1[8g+֦ -:m,Xe^<[В8e<b Y~ӊ>;C+q7P]L_.lκaK熋IrN#l9k$r&)ńH[i;xdxopn!l=/ iۛD]zΡ7v`~}fk.n{s5h8ڻ&v$mfGYhY;B.FowѸG5хmm5øZW`0]5m[y;ı&Φeytm˰Dg}-l]KM,re48 r\a3GIS3Ҍk(Ǒg.ZI%:`}{ 2rVQUԃpt':4™˞Mb]E§D9+θV-Yeek>d$p}(pc[-pn{yϖ;lC0o:B(~⪵ABt?L`륺8Ww[MFu]k,MkwS&<9?kjYmV_Ai>Bk,kh. jކR\̵؜ _?&Rf6an`U݀#=m8:Śg **;Yt f{Y/<~銖2D7Rq)zOY[:d)*5=7'?7kaGuoCqBŞhPCagli2!LvFϻ&ߠ[_M|&^iX6Y4Ө3?m[ =&z0]:oqT4A>S|-^=^u "d6ZkIp4Vco IZnKSMjfۚzy@.HK_s5jG2jt vnZΌj=dNlE 6L$Mf̑ jHj-/{;f(pFuMz@`;yהLг`XRJwC+v61{Mi_ `(^Dؖ?|kƋےResn`tֽ@)P>ӭih^7=DL = sdtulԔg*T[h4e YgP,gYi23Z&_Ao':(0EZ#7ԩia>:шDA+7[Aj=1b-Ez;]S׷.ϡvFBjJޑ*e.#pv[?~}oizo_'8ϡ08Lnz5z  ]T͑}v)eW'zgb<_r 7u!Uvgr6LVw3E:kh3hAt̖H0v<ʸGNO?>/Vwz֯JVxTu.yM`9>UD-5o02cCym(cj :Xy%%hpXtv4%t_\ƣoFߧ|QHgӪ6z j&s ~gaA[=/_8 l -.<4d+C#c>ps2 Ea:]_^8Co $_zi[Ix? ;TSg\i4ti<ʅ9cy"aTGDJǁ8Q;7p5lV!S0²~v#s8::As |48l;0+{ ilC$mz{]:Ux~~ݞD,ԫ{bpFWf5:YVsnW ME!?kt{/cQ&Zyh̄)r4耕s"w.!i I:*zyÙFiffu+\%f]A1Ww60xծ&~P9y R&QL!p)7J`jj[OÒlF-mֆ_ex\Kι(;Gֿ%F!GNnoOu)x?1]&ٻ2Q$ H#κ^ 0|rp-'XK 6qT-iF*iLe ^+<Wv H1$b.:ۘBscFAY > {'U1tŘ|(2m8"ۅ[%s`m2}^fqQo8:$; ^t9}~ڀܵ X;ƺzדNDT6uk (&)@R@0Qp5 GN'?þ伡{F܉;i*rJQ)G]c*0t@\i@W)\xyƟԅ*RpsH% u?kl(p;k?#gOdz)4->,_:)ҥS'K%칢8GW^Idgs:HG̡n}䋌-ÿ]~}q^Xhp[bo͕"Q{O/E"&%qrVc0QѮF%LacQ_n s@CFܺӇRa+k-4naYq+cm kapRJ/|mF̐ĮԴ\~fE C~Λn$s+s1;K0fS'5//x{\ |YnᚼDisW x}iבoH7}.cȃ-C7o&UoeuWk +$ˋ&B2%ǵ}? B PݫAAɓ's0:Eǎ|1ߎ]M'ΏN$ɩq~vb7xqŸ},,퉳E|*_۳d?XLgO'`OMZv96>9.gxw:ċ!;[qgHB8뵺VHs0h1^GY$tr<:mODE(wA[hE`p}@4|)9n"A:~ywq l bVP}3p:^<Ȏ_hЍ9g,W׷!r/<)Ż&kO.czNV_;yhJ8Ywfp' #;@ @QG) a(\v|jze=aFy{BJlh۠yGy4:5GK/oV&(a,GnbۿD`V3л8/.$1J8E ,rAv|D`m/pMD6Ԧ@0|̠Di99B" izڊ'#H~Ugz1G7†TPDÔM't8Qo $G@(o[Җ(NǓ1 Y %V\9*[T_fJpV3юkHgؐ= @x#1RŠ,!ⅻJ`Aܜ+F,gs0M:hgaTnÒƏs^rn%QC/Ƞ*d# DWGpH'H~ ? {PޣX1Ww^C wf ]~3Y3 p!6\ /pQ Hm\3c"3<%oֿjO䀳N~v}Qج~0R c7R|Tpl-Eta:ZŖZ} |>5zVyf! Dvˆ6ݫY9V֪@?CE?{h՘:O./V<6j;w\IEccRhzv/׼[.(}&>Fpq_oe<^D#Dg;Bp3@= Ϩ=[yٮ1SQNu)82 (nrZs0 H7gfD!ۅ?C CѠktiHr"4?/p_V&Y_qd$qyr>q!(mIɽ<ꍮiUdZhd {F9͝c##rCA'G&5zFg@Rb<FgH0 7 oy;f%XWt=/W^BI0;q>723λsT'~^&[uT\xqs/=Ȳr p1Au6ݏQ3Y%Ⱥ/0)"BڗHrL'ke#JU~~Ξrƾֹ+$Osww[!*R` JA 6ِvQ$(VToJçWdV|3 YUDvĝF 6}KV9^L_\.NǛ7=mW3'oE~s'2)b؛eW+b9Ajtp߄.p5".RB )$B`7=97۴^moeqխZߐ6~`{_Hz圹Xq}*5*"=7Da)$Q %20g> /ZNE'0}8u_u/\|#K4X *QY؋5%9xjz ZHL@ zMU%>(bj_5[dSIRӮ S χ@mɡvi?X4crL[jaܱ!dͨx})B̩5%c4} J6/giæLjUF :E Ld;x⼸ U*6+`5{Fa,HͣΈdPEc{Z-7UC/?Pk%{T h-JCm87ڥΡx3oHP7:3O| J/d; $AؔE(+**7b$=ĝV!*T4L›]\l`ų"v0IzR ⍣&/`^PUXz˄K. Q-/|zO iɍ3v=V gx(>ec7r$I+:؂`L:TONh*9lǮTY.Rht Trq +F+χ@>7a ɷ:R:],T24z "vkl$?'/me>kZ>@#iOΟ Wf>Ȑ7:yqz]ـr} i6g6l>m -bs(*UQ(ue4Lx.rpI cT"bLs"0#9{T !QHPtz塵vO,#~B|-Nl^.1WचmYLd!Q1G\rt"f^m^_ǿ2{ƁC@)?uy)Fh+ K@bPlwCVބ4igHzJL^˻,v]JwѴ̫$d5 |X=X61"q[" 3 s_^rJK:A{P.Ёd0̴dy!32Xi4K0)L?ɬU@,8A mv b^j5#@ 1*Cjס ,F0t}cui;0R)\),KG<[4F$B_ķ@BX+}a7o8wBtLx8㷿z&¯\C tnM_ϧ=)'\[σc1QMg {-?Nq3T-OEO *$Eg`>AéWJz4/ڋ)f" }ĝ`ZSHܥd+KCiR Zvx.)Q3䂾R것@g{6rokrUIq"DwQH [㳄(Yc ҺRo`QMڊg16z;wSZΜJ 0[Z׽gj=hY p=N=FֻD3:JS3_E HrĢj:F6"_`!g*"#SEj.dє+8H,Èu]IZLy H66.01|CVzO>#; '[aJ/e \8(Ȁ{P}ɚ>ѫ;j{K(;]b3Gj hFh$^rH(m8j 6 (8ζDW' jb ^ 4mtfF|{z^).td4D dFX#BL\Sx2|ˣ6h¡DGWSC2Ge#J&)D*X}O;;j|0Tn@@9$VXg=MvL(~R ᒀփwoo ?~˽\m15M"xnHꇐa`h<4n s\X]x2p23?%飩[^!Љ\gʩ7o ']} l`34T *߆0%aaN,dmxPhb vHxM,.č3䙑OFUpM&h"'&|BiVD&S 4&u.Z!눤Pr'K%hM!7v0'y-<  xGâO'ڤ2fh a"ES/Wů L v{M>X…֙{:"B!D:߅)9Qb%8cSW;VCQbBu^RČgT.R;&5ˊPNO {0Llb$I4aCQ9KnRнs80$Qb/ ӌuFM]w}cXy0P!x@MN;߸1r;qt*:o yNn <kn*> -4^^`m9EDBU/S:@}IeRgaD,1(`$ ^aCP;_K8<$}+XąHY%[NU J~Pzをj@SAJ3먛xH/j S xLr Y&$zf0`ΝZ5 %L o·LNr-<`%o4MkpUގ[R EnT̳sq\wpOq,2 Ux,JAPkBdV-bk"\հxh0Y \[͉R-A}YYrH{yQqPya0)tq3&تZ1V'UF"U }AZ`Oa|r8 s`2aGAmN/PP -❕AX:8^\ĕ:"^L&x~}8)pMfQ-zގ>Ӌm S7^f I(dm搔_npy@6$) Ydxk.3j|`#Xb>@t4 W1 Qpa @Chd#`2܏Jw8F(Ek}$1@bLtPo:s> lx bp~JB|HeNW/Yɇ f䁷1biylK|%D(nq͖ա6i=/a3a䍈9,H &..ψB̿Iڃ$8GamtuOutoA׷x" Cg :Jn .R7kFF3MMG ,8)%z>^<3vu2qҷȴw/JǮb!]w%F m ayNR8_-e(:BF7/1=9 ޝ]bܶ1YeXt #jRx#anCsOD xu(YrF-H/3?Sp? fT\'?=8ڗ2G9%%=Qjx7'|h~tuZ8ⴑIY&7˱$d¢ڤ˗-;*-z+L^_J0ݓ(vJ) %i*n*]SÝ_U %>]zT*.-ٻM?-Gt,ZvOIQ% ؘQI`wQ=J% 鶈uPQr/9)nc `M6 O%Ӝ .Msc)6E wD $EM2TL/U7>w=s #-'I%7 } sEۈI0 -đ4P-2jހ!?ӘSkQY1񷂈lط^n86Gm- Uӥ\x"F(LtsR+$o2ͮH$Gi}nD#Õ"4^Hj<: >"` Df>mD*397{3ꓚ;=~A{%Øʪ'^06{ZX@TB筰"[^pv5nL=lwΌ'UD"!\7>UpdsSR7ma[p8+jղ^4A78хrpȑ:-N!y&1/o'VlO7'[!#5I T_~NYAxOtDv Hcb n/sx[aYq.V{rAF-n6{^ȮHgc.Clam綏T]lKmYq[ j9hB6KBYc߫,<,r=3H0hnN%=vӫܼy(z4d .v|ZOQ#tLxʩFCG_0n@Ov@q|j^ )/,*a =xN^jq`CϢA` 3OpDC3s-j$q18_N `p) Z?*V4MT~%,q1'=T x1rS.EW`fdJ;,Ddu-+Ea8#\`QJч=Mgv !H*CTABʙ9r Q$.ތkLh3-fWD2*\DR]˦BM P+ pҶΘ'!D[gQjc7"S.$/h 6XWox`̏ ] O^=NɵXXdh@NuST-'@BE"m d!.o?A%K8&1f-emo SpPS}P(wO' @sUَZxrke 0' +fE3QTa~]54yF+bHXo-<(ޛEM@"4VF770? 9ژ'XiQFظMW |-`8ɧ 'FX fcmfYyjڬd?GTŠ#> ŠI:'2"&-/ "M7l; fBT8twJ gR`d? cPjR8|m3(?m  G~!l5po:,]Y",.C~y.M4&o:MPӎU7 n#ۆ7I/+!˛/1]6gKt*B\xk߮XfVo>Tg @/;HnȖLKQB*K._3]&PzL"\P Hؒ!qo-sPPc̹F: ka5E C}p BJ].M?4er1%ՠ[.0)JhMa3g$%( TH `rӖy/ٹ"yqv|3?jcL!t0͟& ֏d U3Y&]Es \{FwFB({~]1:J0N4f-\9oVqQ x(,DA!#))\ yoWA Q$ T2b9T!6Ĉ8RMܠB+2l^gH(JKXPDL_Ӝ!K Z9#v.,^6#L Vyv͈s{1#ϟe<̕@8uRf^f'BU)/R8IR7^$iC4Aǝ,‹Q ؿl2g nMvDG"8֑~~6%@UFĠ B WtZ2ӶGmrS;y0#n Y&ʨ!7%1a⛢\Rqv4\Bf#ܝ1N$Gg̹ ^Ty Q[)@z`cI 8L.vLM00MOjP5W I8{#K&CY/~BϟOpȻJ!sW O̪<7h<,ozXÑ RZ`- ):0{EB#rFȕ:+]2s5ٯs|0ߛ.L<2ǥ5݆7 D;̀:: ^Y&2RnX߲z4@SS8sJ6 2nC-H9d>9r=qx˩Nn|g0 B%VؠDw`w Cwf8"0g +sA.E cdVSS"øRTY")>̤.CF^ģ6XnTk}!2(%1Ѧ]! 5m4(a($@Kx Y +.3妊,Mt(hPJ%V7C>CІvM>T. 15m]$,`ƙ)Ra1y*tMN]Ŕ;Qmz1]6N#Bj?ZQ>,lC?"%!Js2TQ WHwKk~USZzJaЯ,fQDyJќ"TT__e͐ 9)Es"\ .a7êY>Crs_^lIOd 2/=[R)g= 5 6c_J͎ 0/Q=Ty!Q~^@T/|` ]U=G?Ĝ XzېUJzny 垳!$GݐO/f-+ ꕮ }YPKXp,PmUZkU +sUҫGja(R$uHA ;}xa2f$V{i}{5xKlzz|HގW>䓇<`AqpXz?ߒLb_V1R#>}Pl@-LM(@݋IF}\9BB,,N뛚P_wՃsd䊚2z3D59漒Fاpټ[}a<4w`DSMa1`)uX36k! gW/#E`DA< KU G)+uJa{+]*姏 _P-"NDْ.rۮ%Ϲ&,m%-M6uw=POkAk`۵3h#i yP&j.oO A xJۚ5`f4 !nyr<ɼۍԠTRo?fΨc2̗`5SI@R|}%f6r-VxUyJF5bt6e"i@h7h|7z.8M<4Ax.''3M!2v: Ӓh-Z g귄0Q]M8'^*^yM mwBv-Bt7Dec7%ǃ+qmg+\fbBEt-$Eًo* Zb? Rc xM #Xe2:-)Cncz$LFG 6stۘT/ K1w"ЅJx%yHF@^[6~^@~&%eul be0Zrw|M}i*K@YjhMU90 bwՂy7: ^/t,*MlۿΙ)pݣlp!VwJ5PD@rHd56"2:LrBs r0c?paeoZn ßx&"=@sy ?S"p#TxJxJg#F]F 1#qi=" pF-J*F5|XH&3QڴPݒd'Q i&ՖH֪H! _^Vר!Zu%S[jeUA3.E`(\s$cք5p/'Qg8 #QE'XB0g ȳCefRTkm%mvƄ#)]-bDO3&a| iu,ʔd"Lyy S2րӀ{)w ٽ8re9%0Y;xހMYSݚVAt~v~+ER]:Q9i;9D sO  nr _nڕyC+ZK钰<;s p;(;9"42؝=X>J.Ls3=6|Eǂ=@PޥPl'Fẟv ފ]I+;p1BoW@ c2 YXGc>a8K7. B1= +-/xL0 wƻ{4ةFK>5"wxi8,3Vb델/J tEÅ L ƉyFa#^,;\6?Q@{e aTHL2lCS *JD"mw}[@Rm03֗zv]}cdXaF㮚Be?),W;Wf `b2m\y<+fA]mkOmrh"^j'@ 툒{s0K-[Y]Uv(MtRVC-dCd^Ju02_ 12\0M[_ۃQFoK2 &MT: TgmƉ$67 O<)֧`:M Yѿ jg'jҤǰ}AԝD)8mVS, hK?$Dgp tln(b31]w<H*yذK-$͐h%zrxP5B-\ Mp`1DM}A-FWE 6KSpV X,R~WM,Q5C@3j|} } &%",o`h!}(+ޖą5l+Se8"1NG3(ѝ3=èK2feJ O>`*B1H \P; u>4=f:H&;=!I/1rMZk]x\ 1e%`^1vX{ `^0#ɟx WcIyǩD}j9>ww).E7{"tiX2K$k8 Jkp-aljO|+,s?|ű}2Cn AgrFuۼ XHMEj"tCJ`$n"Nb6(f=O  UFP<'ܣA ¢DB fr"i8cu 2)AUHDp0i ``o)7γM]?mPp<kNn b,ed jҨcc.1C  8uK+2h XWbp po1"aWC*C·ia*qzV6'\ 9$3Wb[3:L)i^̀Dց iqZvh"UKDa4¨+ A64NS%{T!(o4k?"44P[U7K t*ι,>/Y,TvDU\QPi+w{%Tߣvx#8l)$~5a3Cps?צL9h|+zm#087L|`KT<ux;kxTW-yHBd<ɓd <'(JK=9 g gmh/w}TK-־hXVPު^kVUzZ{3g-|kwv?>-h(r\5Ӑ5E >iL-E{3s1//fQcR 2krB&5.S4Ք 5n@k*!K؟.[Rٓ8"i,uM 't 0ukQ%aJQ]KHPq@f;TUq=$`\Rq\ D0otCQfI5Le?~YKuYk{d dJQ+ '.N77`Gz^\M~] SO6ە;--ٽæ44gKj u:+ V8}d{8gu0m–殩 N._~E $MN$1?w#@Qh8.*ݚ7X~?Nԥݚb͋?4+g^Ge3u("{$0$8CޅE(uŲ`M{d ,$-M<Jc[ލ|Ӧk^f#{ӌ7Ξ^b`4,)f4 Or'VZՃfDi 9Rel~%la=9CxΞ4Lܸpm?lSR4) qU1/ZY5 &"8g^^0C8fQ>-(bLЌR/g m?0{dJ;d9JtZ +2Z3;SV^tK{iRLO`|5@/Lb4e65It A.U Lt|Kh eѳ&De)謙IO)0N#0%yᅅ.@s%lk+du%ͪeveQraL.y]Rƽ"pmM-=(0Vw)r8NW!wnQ5 Sx5Y'TC Ɂb[Wx *lySÈE=]5ִU\z!$+ \_V]_N״VuG`9`ބ*DkTa/I-ڲ!_|\|KħB-̅+RW[d]p\ή! 5N/JRVװVi(~2nbp5l)Q02tB%^Ʈ2҄ҹI:ySω'b;VpID)MjsstLI&oy,ttlyKEiiSlқ#0oV`ۛBPqI˪]0~R1KV zؐq_%m%I×^,mLly`icلxciLO:{ e+T'DV4'ҸY+'21k9ܓc{;V5'տ#m*ܮwoymr!*xƪ)Gjx* ._]3H x_lŠVo⠰:vbM)G⪅T̜$<$xQ1ƹ^Z-L k_巕Xk^SD\ GT;lje9rx*^kTc8\Z:ob2k'Ua oҰ\(B MqG&T{0]ܹn 8h[:{ W^_|8SO/uȯ$A5JM81IdkIBn8epFAե#CKw3nfm-<,#nKM-/Irr3RB5% ǥܹ9Qׄ_صѝzFnXuu=shmǞY(Z$GܐCH>8"LIHsolE"Z@2ֱEB""ͱt0@7g+@Fx6$🺢2ןUo/e]c3HL!JBk%;!y@/lݰ H\m&S K֩ygn[òV“* *s,d ٞf l֬"YW/g=+hН|bϪza;D4X-~;hsG2Q<3A32;Ƃn2o>`VCux wUdĶX{M x+.kPM+6d>`2׆DrSGd)4>BU0=ÛVҕw|w=y%h!EBS}DXD謝![lcM'8BFE ve}!3Wf؛0 U XWnU5eȒ[\;|o2r@NaU.5Bp]Wfm5S6N~vUyf%`؀ʫ]8bAbÇ.+%LM#nEH];{r܌'8KweƝ#}'?6K+OG垓{< "h '^H{2"CAxd܄;ڟeJgrgh:/ \iX2N$;틂V1dch\3Ё~wN`ٯT8Kn~Qϧ)̵@;Ho=t>@a-](HJ3kQm(fOS蝫KW2Q64)bB8E ﵪaEEX9D\>2ԈsEAf<4GyszDPky ʤM_SÉ^tqtRۓ]xu7@f"a!6iByزa5@K@ )BdW#vNMҙʽfWSF-UX߃x [jR2ɐFV[J 8, 3v:y)KѪٽ:EX%X 9*}SgcB;/+Ek8If߆N&k4`ܙhNU$;?͆P#D#;zN'n9c9BۛE 0\;@6ԃ<ݕxbRsvG$6of#zxљ:b܂,++tG}YE \ ɧ5Zlm*$%.$mMuy+zcC Y R#즏E`b"T!Mڑ `8w5 4_t.ۙ} Vp,M >_'L%w$ɂu:6+?1P+jԌURJO; gDcpMfOXG+ixxXC.$qPY?f[z+--CNdrN'TqNnwVXbfEJ*-J|+w:Dg3َBWu0_z\i#ϲ4{ǫ|pUŹYFFl1pj-s>.a_lpg],vFq=%'{ RNܞɿp\[[gN{~Wr_qd۶,}$8i (엟{13Zľ5h+r|(w3M+wb `1[Ln4|u@;_|Ҡ*읇3y ps+x=\]g\1">rMhC8 Ô; 9vY"9ӏPRJfɯ. *Xc| jbZO) ɞ9}r< W+f0|3zH]֜!R˳&/٫_/ެoOZEJhPO%~DUWhYwCO @ޣaΩzvɾD K9ʤ/ŠO7eMunkVMQfG l䩕/B֩B~@Gii ѱ}+c{: YH^C4#x_vtj6x~9}_pu9 (%2ى YWel7L(tO{s__Z9cu^dsHLuNHr+Bx5YV'=ߨ/fF= mx(φ _g|,gDqHIXjߔOװNWQב͔KYW" ?̺5bhшo UK(x7v[`<[ _Ѕg=irem{8[ECi35'm* K{nsZV~f<7rv}{ɻa!ŋnIa(ǥM[8#0gK(7~vqCve~zv$ҁk;Q]~ <>G`Gx:󝽹X- l,Eu2/:aPk(J;ay/Tc{հfw?Lpp k2h~d%^d=4Fe#lJa;ԇxiCMTf:z5(Jch|k5Z [޾`}HkFAJrR|u3_X=I!z+AO; 웂C:g-+?js`͘d/ރ4/d99pMt~\V=[?\3eF$ 7v?w/N*uͻvg˕]p\:H)ҫiBl)+I_tNIJ,,KjlKhunI\[phb:]0^|"s`p $cFMD鉂oSɳ;2,|؉e㏽P[OC6seNO;Y`u/d'mYhɓH԰_HS0i/WtȠc pr*ժ|?vʠ}]Gs/f#.ljůY7{4csu6~'^Uz#~7~#L_e|%+xkS,,S )~kQm;fϻ)z*_!{ޖso|aF!,кr]cFjPrn@d)ul,odiv*V,unǦaٛvrǪ9$;l:G N:( aQr[I`'B0$_טB@bEux*AISGÚU$9v *BP)I+ג"_TR8l1k8闺p7tRbWh"v7;ɵ#mxmQMhQf7Ք6&ئl yzА^ =H)PKē  /)-H^lR.-yi@Fa!בQ+lwf9'2 w uqv#n ?P秿|-õb.+1%v1NJrWW6 \7%` b`/UUT*+K3oΡz$sAL~ 6,OxeX{XUU>@z/i|JBy( "&#h4k+2-5q}?A'Mkư!S43W8Ͼ>4_ܽ:gZ[k߯+l6KQ#A9E*)_2{vYm9aeU)nR[*If ]VI1BP^$k9Y AV4ߐ^vܿ١ТpI`4w E3QQA$Jtwäl2!UsLh\Amá׉eM{mJECu /s-fU'ׄݚ0/] !wF|-,)ȦHf$S)!j_tf4D`BY Y15IA3(èz}l*(B/ Z] ~yIi+AqUj(z]Hâ'вʒ=G2Y5j3z-FX)50d/k2 YbcT1FPMvA58wQ X߹TSɭ zb< Q1*= E-\b83s8E<G*}TNi~aтGS[|S z0᫧tAOHLFL| NW0xNS09? Sq cJlb0qT&˔t"J4x01U@NRǷX2pCV88rbI-M`:NjY*>!XC !XZ~().O#;$ӡa2O;sqڔ$BrIb8LDEÃV F EGE78]%y,,Ypq]Y 0g(Qq'UQFN$ƶHc.;Rq`w:`qyE'EJ"8dx vI!³T<L.QX wg:٬`TO*F"ln"qAnitlg$Y _eJԲrx Q_fqʹB;z9t_yQ<GW0&icP( A#W:Ҧ2]9@ 40Qֱc/ǎY;238> O>zoҚE|oJcH)-+e]Ѥٯ"Cj!.@'qDHzːRq`:}V?iB_wpwL( y ܹ T`e7/~{bCV3#`@fa%Ӄ`8тL3)H(0aC7 dM!1~l#l A^'9ޛfކ+fZœ}FI?4Swjʔ=i^r7Aѥr4/Uʾx^tUق)Jf;8J˱dU|ɹh|qDbU$`\yW_yU{R\F.8ʐUYt$gn,4gk*mBiˢf"jLvٝZP ]IM1(Z:~]/p* dFzloPlC3J5LD &>l><>1h혠@~O>PE")y*)E%MKAxOLZ&Ǟ'W4c齲EV^aL]57(y A1t::%yM^d\i)?\KNHKqF 2uo NoWQQj,^E7OQPvve/ϣk(ZؒL`K m9m-4e#ۀL[R9`eC1Ga;mp([S-oc7'^2(ːM=A}ܛc2H)J.tBtwo5D Osy61}ؤ? ܃c?'O|}݌"/k0y)ba!|[ޙs.Tc[0=> 3m=[9]N5ȆJ=|O4fv M,KԖڼo;$_c9LO ]ۡ{ƹ{| >ڈ(z7A7Ёӆ)帋ґ:E=cU|~eJ׈߽疃j7ҬyLp~2R!c4|H:Q̳YóoOݏrv&_h,;!}}}M,]3b% L'SlߨoӕoTRuk!Tu)Y_ nEu@OAC{fK')X//R0WJʧIGLEv}NjWhtLpZ&y޲E5O _[[f3OpYΔl3$.2g.I6&H YDE~QnȢwbb>gׁ+z3&KWBi.z!tf^  "6ܨw7^hЎO"N;r\Lx@a9(6}x]zI7dѮPdr}h)C-QǹxiTq!F.}<A?k_Z>AL~:GP@q>Ѥ-V6CZֹCUɄzzVh֧rH=cv/G=x}Y{te?]QBp I;"τ+HB+ҏpC3:Uu]d kW5/\Z[eN;"tsV{x-` vqBޔɫcV@4o53+&!+PaxT. HF,%U a;ňDDbګhFuRGu(#+^Z{5jLF}ޑhE E9Ku=|kt$~Jst:uzR}$IRqu nntD o3O}2ɑT_A;#.ygde <1kF]@stDe Ǻ髂9#*±~˟\zrޟG|8.NkJtIɯJ.wKżo[RQF"{'/uj%2RNӞ<4M~=Er^:S.OMIFWk#>ZI?~̟BuͲ(}0o9yhtɻ$'8+q79GjsI9HDz^^2_ ?-UzԜW%Q2V>dYanK%\׿<)uL_<5ݫW:;IɍjU. *$XL?7ݯS>7'똾< F^y!eM_N 6ӚV$BWYDE8lRc1"qԥt]B9s2Fc)oN";yM38x9\Ǧryx?M& UL+ETɥ&T8$\.%[ҵMbK+k~B|k$2tU4b4 +.tQmBfbd 13"Dۄj7@Œų8ΎءZfpA/PX 8%y ;&bF[ VDobycQZ.d;-L7@oVM- { q4ǣF{\Xl;XŲ7BD݌΁&Q@`XH jUf{B)bY! PlFNXcg s^jWD-yiLٜ"߸C^eS:?8_K2_5뒏[8.e82µzˋH?mBekųQU&џ>$FT #?ck'4G5q&$Q2j7.5X'pJ9hx yzAEW˃rs2'}()OμG6yo6 ۼQj'{_ټ H =(eK=h$&]F؃Nb<o3xRv3V>X&m>f_ߵ_%OJ}egNu)q'txbT >ݛ4#3b% 7 :x8Kpo%ij犱7x4ۆxknI3"뭈NϸErL|iF0 3H 6}Hv`p huLDv2Q:YL$=WF;8nvxhk3UVđgBvK3~0;,oUuԹ-Uwk/l;E[nLg8:l"2-+ev,[qL.A! *o>r`"G1SC+NoM 沜"7Ua6hٛ]BZYt1;2?{%pD"sY";-z7_\Nn72!Ձƶ< , 4pUչh \41tQ<]΁7gCe|cJZ.&硑ђ]&cUi2i>2Hc|^*B_x(Q7Eq-J7Jtt牒(ӻѧP} 7Dojпֺб+z+Y&;9@^kJNnzhYfe7= JN1q~6@=үC+;,NS#Nr83RHmg!t^\a9K `O_az%e3B_ 1ɩw2aFPw%d߁THfQ^0FUG"ll!-/Q!UQи=;,h^Ԇ}hʾL뱣 P8KtXLmwSx.EiDMW鋧cQ^}x91?<ġB-{agX}t%BGV'|N(CALXe4ﱗrH !E\ *c _ߌif\+5(nK瀸! :=NNKZ%>;Q ^j =Ł>@} tq<"nc9ٌ9ޣKg.rfܰn?Ӆga `|a;)1> ҫ/Vp~/.v"F&8LKy^ *<[u,!g\䒗p_+gLI& bZ%Ё'UO";_q/{?y=ah' oCbQo߿!]ooÒwks+slUq~)4z B %AԐ\ O'A]r#f}yԅFa>fP//,]‹:C쬊۾Ȍ6 8ʑSuRQ妚^w U3j u/@^`@ߔet)֏73Cc߼פ-Xv5_0"'ϱҼ KXiYiQs'=]dïTF="JqGG$ ۳%^p>N7Πff0Z`fgPe-0v,  #v^8##dv&6; S lt^RM)#mwU j+6ko&ޡ-ukb%XÈښVPoױSDg0{((0K15˵~&]4 `t.ҳojFWd``0 @FXk:^P!-.$pAM,\\ń0C2oVf!3cW*>v;wI&ؕ: l6kOrW=)4Q#ЧSD7Z'2!lp܃nlPk4J Z΅]=j##13hsN)c R:?>n}Of?^d2l/oﯸ 1/M- }s۹=ۇF}&opCW+ Iׯv?$+x}kpו`IMг[BGu'^``^65 [R?y`0\"9;8$BٍT*3;gfSIUjڝsν߫FLt{{9k[/7;mm҆!iޖhxD{]{`bOlo|"m&h.?٧'QzWwƦx[v{"piA6ikѶ죷ulc=,5X'yJB4XFJaqNUUN넙^OE`9rYWqMjzWg$v [CO}>nС>Abci@ˏa8_8 <]7Q3LO Cx xq8+Oq$bEosUko-^_xzk&ɻ}LZոyuRst(. d`7Ā_&S8}8~rZMD- l͗. qi#V|ELltKٗ݊/a{&޴ * X E"}ÓI \D K)>XE=_ ߗigHf_<{Md HȂ_Fr̄vԒr :kgnfyE`kLGݯ,`~ez<bnxxa'cU@ xfZ1 Ê˚5Q%Aę1,yeOe] 6{gNi0I0 鴸V#H2"̚7M95q㳑$>hH  ,fI'a2t/|~GOl-]oB@tv ZϾ PDFQ+Y /}ih# 1#[M"NxX=wZW(93= x4 apPɧBvrҲUu̞ hGtw=fYnxJ]Xڬp1YIQT3@QQlҘrk}X~0uZyxay~pC ӦQF`n/b08`hKDF TX`֟vvVcITZQ C!TOu\l2a%7luu=:?wIhpe<.BsJ G$N-DsHdwKt!CS/ř'?>oV~MɼO!| qPbB^NS<ؙ1}+tw{s8I\RgyvCF!z܃ 8樅;ZĞj۔VHm`#Ӓ{wCZ5.H$a1np/2S ?p!Fؖ"v`UCA Oh+̅%nRYF=T'y*oM O 0²bYۧrl0^@,rTX4%@:], /b`c`K".,\ J=G 4/Ya~a|8D\tXIҁcq4So]Zȶ(fRtd+;?"_(5ң,YZ&Kd̍ڲ&% plzvЄ[.~F&#*`>0/?=lO:u@(ɶ˼YI[lX#I"+!Oa⨮ht$b 5eR$v_H :;KYvl>C٪!<&paTpua|b"-M @s HN`W#2-X!_}6>So]5:܅qc6{CIo7oJyGnI^=6 |W/7})^oY ץ(s=\`FB{Wd|mo?O4ق%Iέ^T)EqQi_d: g32K+:1*ʉ0OmKD W<{AALq2qKy[%ʌ4YF;P>_\%6#h} J \؍Lkl|?g{jBNȍ(ί{%SbA?-&G{FZKAg1YQ5O_2I&ytm8ꌸ5?Kuܱ Z$}<ҜS/6b*@F#osd gʫWH:}FIQS@+ aH`QuqQ|?yrЯ]uLp )ybu[)LʓBt r(~͚I9;Ŕ=H`j1|D.)D~); (vWBv9pSQ"lT=׫UeT5^%vabLICf9?L6^tЉő$lztU3l>PDzmasPlAyNN=dK$G,1 HQAjQ&9AvMq!DŽ_%N!pew.ot zU9\Lсic хCa]޴"CEbF놕|5-4l2;$9Bl,P^ Y@RBX' gga!X^',O('ZphSB`8MWg7xfX p>&+sAX@eEG|(T{[g#}9lٝEa2̥0'r/-T:OyGGէB;[ive.N% CTNEVr*l)Z韣|3>r$.qRuf ;)E,%+HԴBq?ׄ~=cZ`6Ffҫm HY p3ϩ WPlZXVEZmȭ6Nvi' y%e$"aݕyQSC\82gh&"kLL^^\&gTW= /ZfGˍ>#qvr٢\0I@.ș_ 1/_>w.tVv G,=ME.9a'?P:1ҵxfKrGMEXDٜOb8IP[4%lt,v [0j,5ˆC@f\ahk^.QDHVu2xTq(8gB WT}pr4xYiUωah\/U8,нRb+W GAnRtWCB> v~&4U"xlŖ"7x̲]^W!CY -ٙ)pcP {ǽ&C `/kVQm~s3vRj|W(bn~[\kP4H]!r<`Zu_DuܬI[*^cd\eCbGAQAls{\Uރat:;Ùu@ Oy.> q#x,-" v^2݃Y}f/+ J~)~NfV"w;*WaZ^53 =6 +6 Ďzݱv \ b|jQ  c\)ẃKaqܦ'jR~q4c׿O,}ZO aA*1$E;:J*П՚ҕ$wH>'b;b =n]1:9:⦮#U^=deeF(e?eXA쯞hV,A\: o']n!Ye*$z8;7@+pUehJأW`ဧžܠUi氨)#qJ&܊zr!Z(gZ\w .WUSM5 EJ.ǖ?]RH:۽8g]JB}iov' |ZqWxqd=Lrܕ"Ӟ_NYAR $hU֭ R򫆧m{)n++MTg/^ٖpYBі@t$VIdiHa2x67hu E=d|7),|&)YKzt%[qM7ȖJ؎Np!:F{_b?OyG,1ǯm00-WC@_5\NUn#:;XW6 ؖXȪbiH`_Eh-k(ҶYܙ V`բmxƭA-rGM& "6yi*ȲR`סh;q8kڥmR{lO-04o5-H;b{:b;$f d~}KVPcB31X5󈀥E:\H`\ A6ұ8%MŠ!P$E;b5֊a{O 'U1 D|[;ÙqxBjj >YN^ MC` ZrxF-6mt)*%m+TA=lY n]T:YjHe?k̴ ,|>ܫBQ'ON=B1x6ZI_'Q95NPiQj}DZr_=pnrZ+gO?uɾ ,Iī9G1pYf@o~=}oٌTXA9&_)ͅS=On@fܹɺ,l F#n;.\كy"Uyk=3~NEi޷$~p-0+Gh3; %HϢsؒx'h?5`ŋkKvzg bUKSvHw.SWi9 r/Wż"^ݫZ B"ϧ}OvSLJIRpA5 #S(h0id"8S٭W<4XLoT] ^R#Q']kڄmp0jY4h,q ĜwߐM1*PYOYimowD*1gQ#:ֵC#<%!MiE\/p^gh \v]o]5t = g|Th">NR]SY86΍|Z !H/z3}CWjM&^ ,p^^TGJ@ dpy B\5Wۜ!&?/D$*:Y~Jm>31\W0:0ҙT# i7"ڐ4AHɒJ!' C&DŚÍ1@ETVo9 v42  /S/8s":%Iy\=dxLFѡEbk~58@7 o&u:΃)6BN_I+E9j!5eM 1Z=$VWhg*Q2dj8C@l9B&{H>"mYO=7sW祻1u:'X9hg|崿qQ7H+uc)﹞ מ\YAV nav i_>9fjҐkNyH3S/ *$}[dzgx _H=HUsC]23iraUUӨœ Hz[=6Uif^dXv}htڂ§`Hh<#'ycS5|ڏ僋go+55O&IMR_'T/rp?d-Z=.ZOdN$Z_O~e3mOU~3Hu3vʺN/wEV?:YC3'zo١x`Cؕer!`{!UIz:`⍨JVRpQ%W )`$v;ܘ aT)X\7E[c 6;y=S3ϯ,o y|*|NM?JOqj{dyDI}iwOg\`ڮ3m\p "C"anZ9Ȋ>9̺OK }#9 *d_<٩Y-8Ky=DLӫœ {"70hƅ഼%>sh%k;&@9r(t BR4ĆCwIasj6XV=c\'ț(6#s}g,,z))ӵ3ݝ".a}l,@1-k_'&Nj~?D3EFKσˎ-:cϾYZN9/V筂 >ӂ92Yw=d_SJҙ(xq3<;{cMO0%CÆGfX! X=U. MD%`gU9eSJ5Fx=iq/990^%#*- 㒡08_^7%ߡUH1`6R2l7?(X֟%z@؏^Q)>.cMwȾbszn/rZ~"qn}eO=ZڑB(9+eob1a=u۴Ua4畄rI5PξO\b<Қaz!|SfMky;Mus'C߬کoѡ_cÛ̹f\AP2Sp|X^ in á?PR<  UԽ5~a?k !鏋#xiO 6Q& ;L _,D`rbi&*+r 6&|S)@O0dğׁfD#pwcsəjf]J8~w4ļ z9l˥)PB|]`cw |+zr)V?{r|U<{wa:Kp Ύ v;7W5Hɰa[st=zaXLZ~}C_=b9٬_×r1O {,;ˀd YS!O[P66#~Vao1I!sbn+ͫ@|;U{қ Dt_L6m⪗/as>(-,h#$U 2m/ʑ=G] i'񄽭wZn)|Xbk?Lr'BzjC6Q"K)a^:> B:)up0b:ms-u=c Ӑ=1$,NBBFC.qX[}gGW\U]#Xކ֛V 4AYjN;([ bT ar@@y}tKs?? WW<'q OceЙnE˸ľ.n.!a6[SS=lÜ!xN)u،bْ?8WH:ƚ"B wNV |C-K;Ť1cO|yyɔwG]~Ѫ5v~FSV,=XК'occfٷ~|7Q 3"emim`m+AÍ;,䆙,+잏jkkZ.@zoI쓏m2pʝM,RAג岬ō~, 0[/sU؁f{lMZKiHdu.$%PUa Ta4OYY^]xIaU&>ٱZI)TLe査:GɌ& s ^ MW f B_ʜ HϯU(W-LKwmb]+=/ ֲyV-< XE'zSUa ;ⵃZ`02 ņ9j;pE%V8^S8+P*J]^87K ZdV:SA>(aմ^Ƹі0ސD*4 )!WH؍ ,Eا"v9W)u,$4&F`stdMZ N6AǑ-;Q'y!fq0 a [s X^CVŞ!Z(֦Z=\]jnuH>mH+;q\7\#,?~(%wJIcsuL jfjD]b_'t9E>ӌrw:{"aύ;WTD#:~67C G"'#Y8*YĽC rmIL<$_UW8B"VjceH@N?JO%=ٳUz6\Yb/*+EWu E[e`vr 6Vܟ%jMϊ/ƍLީO*[tvk(gxF9 =flxMVkPUQi3* jxyT">RA^ދ jd4.5>xDkh$mFI:}L̴NN&~r鯳Z{y9N,lpMeI ץIR*},Ǣ٬%|q4W.aX+_UpGK$-KcB_S-y̴l4 ]^ٱT=I'/rO eF)Ht(x9*_j$6fQhvl8vhv!{Nk66ǭmIh(mϭfCoGJܕ<&/80z-3-c34DfX4Ŭ`&vsM\ 2Qޱb8g0gܤN)řJڋφu `͚_$IL_ p3~1q-_5t6|l97M ͤyrf=Yk{i*mw|r%5l[SRa?ꘕH3ۘiR{8hl*ugQ_DQ&$_ZL *5E0fYYEȌp9*o|8Ȥჲ讣R8 lŰE:Na ZAiYC|"6)B?Td $sKi-ys|LQcbv{*nGj/Æc @j IAz[`6a@b6^/kۊrPClYǐEaSV<yJuY1tc[dSNiQWQ +{m9E;8ac<% }];Xys#&s(;3$~'g\ 4ntF90ߕ,s%JAE8nb҄wb/BUשi8({$)-$mTj|)C7IFChU-ʔm˦=]6Op7_V]mNM,2#h$f }$ oR8w;Fa%D_Q<욊NGF3ikZK/ҍy!=R4ZËF K W C[WGqlaJ=+)}]2{2Pu{6hz:͛hi>eQ-5% Ё#Pbb[r&ߛ#=;w4+fR//CпZL11/JHZ%b .;͍XdJБzf8|h%6D!*`X9֓‰'F,M?SA-+N-' SKDL<ȧfәgYsf ܾs&a=0S]y}%.\d`$Ggk[ĹQzE}'D*(5tH)a>*4Bt\u\;.0>;q*~YH eǍdyV)Ki# o#]DT`  9^m9f`1!iS96h0n OpƌMQYU]r(j(KeRtQuZ3jر{sۨ1`HlB0K,fk\,*JYjY@QY ?kZX?ɼ0V,Ù|'EHI4nK kS{D- HD]r@_;,?q$Ch2F9J4 ^tёHe"CY*,3>`6•$+̒Ӧv5!5pݲQF ;S' ǫ2K=ŏ^I"7qz CIY~ysaQBDΦ;ħvg&_\ g?f>Q]JJH"bQAR5'zSDYaC0 WoH6Q9 {^#* Yv2Ln)b$8W9   gPyqOr.iwQYat@-k#&CG*şF HNNHRKߝL*^Z24*ѵ՝bmñftU9lIL||*]N/D^m6C7t#%0Z_Z6 kqII\=#}6YЫ˪RJa׳(Nu='\RTV磈eaq˕/F޹JaN0ZX>U&aZ#LOp<|1ц)R'ۑף . O6K O]ĉ}LX7uN=ĉWV]L?=k?4鸦T$闡L$qscCc7lh j#cZ[(֡ Ĵ`8l:(a(|PbnsZ‰uD5,+q!DO?%k|X HA 5}V _VMe?CH?$.:SKkϲ$E8Fj #SW M?[y.lYܢNG.F-1T|8̋ru.ݜUP=YBZ4}s`:m'ne}MU#/Q՛@Æ~-TB*{x8gn߁O5|-;0Ps-${N__X1M1Sv@Gl䳑[JL9oqm>CKPZ#+l5U w EA|iC, ZOڂ4FI.IqV:Q} YA=z[,J_{.^>B' @aphL`Z<$C_N= 8uy-  @75ܢ۷:f ;n.VŽ˴ M[3BW%t~e3<\﨩Ce&"ƍ3H:gIN$^Ю|\~~2pՎqkǀrfF7-QF hh슻<z/2M30˛w5[6#ЖVh CsH2]ׁGHmŴ㰦 EV$a{ woH[=R'1E:&Nd|6 iWQWْ~p޽`fnh{w?:h2h.j!.HObSݱ*utƺ1͢8 D?.svBz tpw? '+/deӚ! S^^" +O!5Nw;Z rm#J?"N>v5b[qoJ]ZF b҆{UהJ z\:.z C@>_bh<`, J?Xx9Jm@VU63GfFz4ሃ3p.܊2|'O nB[^)^)Lwj lΐ?kU4rq;^l=H+7QF>WClM|Z[N!Q.ErT0y0j\⯥Qݩ9B--RW9PU~tBr]6sW.q!/iжgzZa;>_ z4P$q3H'E(5"{p<`R kzѽ]xT5lzlOV O4Q /+utd-=slS%"㒈 1NR~5X{Yvmm<&aWLKc|uy'VyگW՜'/Cn-n~@teta\$V[pK禟 Ԩ<:#5^Hl[@?ʹN)^xٜ=R%ė3p| "T HB6!!Zj: 7!H'TH:p}QORUWGxp ;u|M~iKN8c+4y6^^Gke7s0R̈_UwoC9p6<5-v_W9udweP1HJMlLNvTsزC .!TI5jG$C'hNDlWBmC}ꙗsT>[]~L5YKچ"$-+$_263$%Uzd|Eq.: 9}Q֊BZ421"ꓒӹTk#mn[$#^*8y{0z~E_L,є5ƿ3n Xm'fIz~bWꁪ'M.5-eVO >+}GS%Q\peԹ0&uh/2ߗAgM79:V~SHh#i^&;C><pRݝ rWiP1!}jN'Jة{c*"*#zB{Eb+%)O#}F^txؽuri1wLGb2 h4J3ɪ+9_ +nR:r[ FIB1_0FI@v>55PZ0i-@q P?5Q`opm=`$:ӧX[8"C\j|Qڍ0fL#6^~.0G;_u!z]WKSd''4vu],yi]lB16ϟ[>DzN6>~,.ɉC"ڥ4v\ڥ(ԠTrS)D< -+'݇<˞yBc|%o$LUa(()\:`HA-. /5'aʭ%Z76yM'~!i!sɔLg.qT|ŸOg]*td"sT(r/Wص8#KUКؼ_qs8YazՒFY4,ly²l ) `IS7W-Ằ:{8RhhMKA6[ܲr+V4(ƒ bcVufҠao=ojbqP㯃SRw,)J꜆~<8 xesVNA!bP74Wf屳{:{rb&d⛘ɴ'_}y䪌X'qh)\vbo 4g͛!IٲU/ZO5Tl:[`R>_t]&O-sXqKJ@gj&}&Ӝa}-5gPWww8xIU̠3 1 Lɬ1aUO2C:@M.:#c YE.Z7 $-[N.<,&t=5>p`Z2fVN^HBl5ej-3 2HFuW5kl&& =?51s"m'̵Eʪ>u'_2'T$v9YiԑS"3U}Wb!g @nMNJF廁ԁZsxf^Xm{'c+J>)p~kBθ!+|Ƹl%Dx,!x8XNÑ bI^̸1@k8LyX0qY!:.tè9'lC %B3 n2wLPC% ]ϗޯ9qYPi сŰ8ɭ%sFN׎ >_rX}^3b֕v;@v΂ Y壌nh2ŪD=-&jYz];#eX1(1ٓRgh'$zGC.˥KaO AgWGۅOr1 vKGs߆IXPp2`+Uy=묰5ˍunbgVՒbpa-Hs1='._4O#bQΏ1?K̪ypP;9VP8i x\6N sZȸQQ L$9ho8dLUTHjΙL90.4X򎇹w%;!-k*VbmAxE[I.F]ޔo&mo>gs|*fy%Yl;4m c/_[0Ψqe)^7?J(>V-DG8o H2JX<>`Px9Zx9[MfdWQL'[I;xn}#,(nIUܗ6H!bOfGr%ؓ'ꮆ9Z6@K}с{a,eoQ}lu SdI5r}R\8:`1;<)|+L=hbnU`-^,6kʯ_w"t]U&z-ֿ>h`sNal(b %,t\KԀoe-= ^$ͥlbXP(D[YM<B[6Y `C~p|cB[Bu3ڭ}[ Z˲ >:'og7_ 'X#xGj;믔,,5e(zS;K5< sKZnagrv_0>_=ӜkͳnR$  /r4K;KL$32bXػ2Iw32@-2iUiJF /(T14&cxy{pD D[o{倥4[_|eaDp5Pb{u󟔭y`W yz@ͅ}J٣l^k(M \6ōRU"H`K2nM|Ml!uw|xofUw]fʄ򿵴,CL:o5̳f>z2,v~qI*DJM0AP[`3vayA'ԨWQH^H~vY) Yg0뒵mkە;O&Q'el<"'zd0}bѝz 7mF7M<;YB^I$ 5 7S%cS;Q \Ѐp0 jGq_%4ՕWpM"asHxX.qu"d 75oM>r8)*?I:CnWi[֮^>%_6 i?yn|ԔS1YK]RS@w$AԘiva/ꬹT>)\WP]v E2eͲ(b)@'&xPAy&yVJ"< Ͻ󃆼]/41U9azij2O?hiڄm̏)'Lwڌ {tvV2bh,b mڂ'kMޖG2Lᶋx<-ptS_}ie>Zm)?gsWhTT /[}O~irؙJ&K;~+^J:?)0M&zux~(fG}Z :/\F2/u>]YyVnQ/*V|ě+&ӟ 3FY\qTE*?÷HLp I;Nt9y Vx~2A7.LGXf攲 /-`#  }.WVIb{R>O CEqSxAi@ozΝHZZZ"h :[Z؁ζcZK4/ h%,g2?G=R>oX+!h `4rg:⇂FdXP,H)'z*i 35LOiR `]M_ND.".Oz.mZ%B0 N<4B\M&9-G}$J!HR9ur!q;D<%*AaYگz}Gt]|q#*JwuRUY[bZL33|lpf$ 6I!t\`m (I1ܧ^7CWS;4\3̈́!53B8.e ;l7G@[[(&-OAC ވnj5.6%(l ;BBhM""FSնRin bA nEH-he ;[ZDlD&kk՚`Yu8e~zŒy#7*9]I-BVX\(=8%4,I| ^ιsDy~}tTѬjM\{*z=TI1*)1n=NgО?U>8Żq#M2v98iA6 c!F=в?q21ׇlXwUn$U`酿F7iqR_(rUrӛ-z4M2ebp*UJ k‘.;hyr5Dyr\c`j-9FG)p;y~p#0i=VM$   wD^.Y|!|df;J2ŰEL] W,)7ޭpZ[5,茡=ch^9ˋ&MB@TMȎ,=ѸT!6ю4d&4M2t2mδjsLw?yys= 755mu)m bR&i\LYynڂFacAh:[$ݲ8֨h;[͝# kGgfW(8Ps' Y։^I5:U τp4pjfMe&efpȦlg pMG~ RS T(sV>xiV#R]վ_Ϲ£ |Q(y`0:sh o桍/c];^<$ T(^Nj ŦsoJӐe3$١%78&6D>/,5/ ,oD1/ŷ ٣@^JHj 3.\xژYZ\/Toe_),աjeB6}Zᦝ0,POyKqK׷dZ-.?XǬ;E(2m0WR6j[!4XBh&FՆ5B7Ps[S϶U>TĐy\ [qmݩ[NZu(9&^:6EFIE.],FZIZ-;MuK66lu 0IX#!oT!a 툐,\p~w434NQTݡcp:ƻE,p$2#n,C9/['l:a@RFʤ⫺*ٴձ0'^5!M1FɊ |v2n5y4ǡkLšKg޶I:6]X P4$\ 6 $HN׶fIOqR@^M9mek4 YU֋Nbj@_g<|Ϯo 🳩}mc7tl\śX:׵qa@P5D k{5/glbq8JPK7lXOF0A[{ elO3}:]߼G:媯3aƎJnj~}tr8vgbC |6|^/PS2m v2cϯ,>MN%P z]߃ԧ|]=tNO'oWi@KxܑC7y8jD~tŧ,Jemi}w0;8+!nnoDIs3w>PtQw1`t-#,gRzxzp10+@qJP:FxGa\o%I"<n7P ]Xd2 =~inxh3QW \YabZXs_.`{r@%/Ÿ9^%j@MG>@D$C+'%NfjPe u K'Mah`AqT_%.'*2! Ϧrz6NYwOѴ3QyM_;Fߞ96 xv46">e= [!9 @Հs3>Qecyn?s|dT{~>ԛ#a |"/Сr _@r}8F^L \,9}q=Zn c{~s pp*GF^âlR:w9W9ݾr3B{tbݼz~{hyR{iߘ/Tޘxp#y>f53n2oNUF2ҭ foAkPEf0.آo/GkӒ9hKGk}6ZR:+9ƎgrYY2/Iu\>љLtǺw&cݽ@7lR[C[H%6FqSڐJs"/şOv<ۮ6œ]-p=SUϩcz'=P҃ IUǀILdPTGar0AhcgkΝ@PaSU`M3nI@JMsaVjhV/@;ahuLJ zGRo.KW'Hd"}ZƵ Qq==LW80 _G28kq>^#aI Iz$@zކƁS8>$2 Sӛ8({DEB|כ["_ Uw]zv/H\S)6RH.&SȾv[^$q|ϒs꿩^&q~JܚS @; gn; _ 4BAK(;r}D66U`9ݾHwG)/ܛJJ^*E(vp",?G~QQˆq {Gl}o'OD3 jhFfS(K)gn`WhC!5M(5RouG2os sD =O9R!Gq#F1hIAs|0}<7shAa#96l!vo)b82"".m,/f =tXrS[KTKWЈzp+B-2; ;}QiuP hS+=4r0DoV]^vbV*>$ˬf7@zA3C6h^T~Q]ΦUK( M2%h,FָF8~+ljVgdĈ| \[G,'T؆9GS8,8 []%OeR0TDp)"9O),X[^`)SN3ዲ0r EkI@Y!`Y)'B[DٗW=(,),?9Konx0yyf==fMj}A,cD#1en8>)FV~д)3#E}Shkv BЫWm̈@/ 4y(Jg7K̶LRD.I&6H3}אXq*N gUYPӂ-M)+io±)Q G9"qhP[X}lT^~h!h)WytF-TqO 2ʐ ؤrxY#l3cJx3fi65?-75riyu@TygC ǣ KW.-@ML=+eRB橪ڜݾh[YҜ0;RuOة~j1eeUUygWnŇŒڭJ ?=ysdhч`*Z,4w68~ZS9w:\ž̸ԬA"SO?.nz{_H$;̰&8"o.[VaO`䌶s La&9΂*&rG9 . 7dM; ¿PdɶtHRY6#ޔԕm0ӄ8-E?-v8))A@zYA4_ň!yt0|F|h A1ƺmD uRzo ʟ9<*.Q\)Rnp[ӣ˗˖eFɁ` 50 ȝ55)޿vR|B05`)v6T/af fp>mIn~D@'M>yrv&as=ʀF4Ԋ1~$̐Fҋ-T8(/#6nL]P%Mo2eY=XWfej4Y1)ݬ kg{נu18M:JC` Zǜ70`4h7{(}*~t~#\%( ɇ`qT49k$ȲYEPyꄶV;!vP2Nqǹ e #.o//k"wq3S6, ڸJ.oԛP#HSEJJL?e&ZaB8-ۮ4*sJ=+Rʚ*L&ę(nW7pڗZ# M`W5veI1T@ey] w_VN2&'mZۂQ@= !l@67BI^Y󍮛uĉoFa /ysYNfE\CNjM/ e x 8L4`.VWEڄ a4EdV0 !m㊯sA}h)5 Z$ $b9? dg0Pdz0dFޑ Hf,a1cՃu`Mזr\Qv"~92zg;Y.2ˊU2g"D1@Cq;e$ݕX 2o&e:l=7#Š 0af_mr?`b4o-q #kNEϾ-"Q5 ~9(7@,ͻ9Q TԒM#1_impd gQQbL,|*W{j#|BݦA۵q%`eyf& Q<7< Mښ&3m!^af[wLIiݠ#%#JTG_1&"QnYVjSNjHksW9K%CRgԞRqsDw+kGl##2hkIT,DB+):v$ςu-Kƈ,OR.vl(Zsvf܊'W4lLK+ӚEyd98/r,omeP|lN7emIAAlx<,^弋Q\*9NT*,y?_O%ĒLkPACag恂j?qI!}^$3'Ƚ5zAaYzd'iqy}Xwu;= n>9WmkO%?%'{]kO&IցB{#>T ,#iV; ]ZCokou  g 4F,R)KλRxce ˍEͭ9i8*7"sQj~h>jֺ[rmS_^aȗNd4#R>̰5E&;; V~(B;Dyht#{a/2 =pi?$F7%qyT33Y&^ ۼ_?,BfA{tn%h`)v?޼z96rhp(,V[Bqp?y kP"!ϏDhD+^|gY Gn,g~Ngf<)Dud/5*-A,ƓL&.yM غ$Ѩ:aJ0L ;=u;1mpТI,u%SqiIkdKyS#99gM?ӲPsdphKm%b|t{̬ރ +n{_٫vfSSl^ɱ 7| Pf(zi،Dl^{`.{ozൻ_]XgV [u4?9^H ' &zAܸ6^X aqF=tu`}{y%ԛR倶!l8 l>|3ja +̑z /kQ<btJJRl6" J̜eL6ux}~z6]5fA hgI+ZŘtTʋa </{=`VkP-eՔ>YsqoEp#O6>̔; 2; ALBF5Z@*Fܛ90ޗ1.9AXu2ZƢa? e&Z空akSe* Xc_+,yξ*$*VD~cpz 9'36_ f/-s :)p9}ыr9/5jE_[k0b|޲NhVIqxxtxA.@IË{<˲bV\~E޷%ǥXWԙ{@[JKxWp;%=m"+%A͛)aYDyn‚bdąirDţ|"B1zE. N3ӯM՚YDf9*Mrӕ>j+ g0Zl#[iBr}u$8ۺƥ D\V-kPx@QѪ=ȞD1._(/s( N&2,ukG 3xތ㗶g^ QEߦɸTJZ]=%K~?CΧ~&#)/D&i R5@4//`_}B/9_`eIdoZqj>|ԗfڽR>ynxwGg~&[.+ŕ:HܐLbf\W}F!㱮ΎX*nBӊWJj⢶a+/as#jSw4> X@ *QR@7"&7_V kPCڗHl+X%bY\6!>{ao D m TtKHx塥0`b \ + Tm:\_uxM kH$u.x]9J݊ߝ›ئtqN9]]҃#AzМzgc!>at+^W$Xr7t)AvLy)/hʺI]\f'^ns*|CzNF{aY=)p\+vh{T>}_ց+ &=ӔGd @~&o8ӛA2'*~]=|uRK=gC`|yN] ^V7/9>HGyyآ<^| z_":¡DwC:D`wh9OK@ [ǒ3!6ƹ#yskfQvQ>;UCN fu(bv$!d:ٯ\dbpi*^ j0oX`C)oKY{A]o>* #L~}+g{V/clH!o]S~2BfS*g~FJ |ﭪ{9*|q;؀LVEݼa$ ?A7쌯A ;rCsˍ1h[+Oo{Ja(pPa[.8 I3k*'6yz#PB'g"]˃++M޹bJ/UTͭ֨ܯwRwiꃖaE`)OƳx$r?|>KuABxΚ/@~фr8ǖxogIR JD: Y֗6(pJ{777/'xQCuԄr]\OK>./,eBâ:|R3Ilt닫s+Ֆcyn_J r|`chc2@%jʓwo~.3f1)z?v-*"k~C5B>߯`X6kt5~a4 @\d/HK^T[>i=Nkʕh PClLiFv)xLS[CHBk+yi< 5z̀ /C1}\~,xOgO(ѹ۔ 8n5JN[BAxՍ9% ~a~\X$UH=]n TAg9;4J>kr3vgY|dgJ^TRNԛ<P#V [ORxAkivy> Jo!EaO8Pa'D{+CŞxru{:̓b4Jk xQaج>н=ӜjAq-"_B"oSqx;YtՕGe-vڥRk_Z"Բ-YMՒ,%uI^.96cK`섄8CF ;̜93`0'$d}UusK{z$ wvo$1&_I~ŖiKsrt xHDCbLպ>QaNT)]= lV]ĩԦz8 eVg%$>1H@S֤A SS~mP$7&5&_|}C>aJ:*bLeft/'kw{oY49k@UUIN'ٛZهgYsT)>|%,t!*1 qbR0Jɕ)d1 xR bH 0 S!5ۄ1UbeAJ k:aͮ!Qcjp ]0P9œ:%I`QjTT/.U?՞9.EHvy2SxL$MfT fHbCqV}kŒѵyt}i3)8ǩ~MTTe.&U!tWOR:1@Qǁ~Z"NmD?g>YF$fxW&b{J̑|>g^۰ ` Q=g*J\E qŲ9"FEb<]B~RK%R(فdZ@iiU%侜}*X6tve-7?<'s;s|1Q ~= /C13a඼Τvr.8w'u-F|g8g4BT j.H aը,iLa0{/t%F򧂱:$mSܾa<P ҅I rP6׭kB ۣMG1T:K"btc͏$ Z<&Vh)sEK@H8'.Q;' cR*oe9xw*gD1y2RLF:m]ptV 6jRԆ 1pŪaMRPaQF0WAX*v &hJBc3_?edg_kd@Qēծ(=&s+⨤϶7{D ک_ .j3p<VMa& B[SW`0l-\6s %Um}>wC}ds6M9xl0}ƇQ.C27dԠ4*D N:I#'D'E@rY E1"vԀwz'q&;?OsJnZ!C3Q[-"#_ߘGBu!,/#E *4ܴvtb֊ o3&@nx6C# mX 2cb+BL ũGM|U!Uݩd@0$E`-Ԡ&lΒu4y&#&†jTߥ=uTESdޮZ+"KkMP51N5iƄݻugr[[{W3D5ҾZJ0WP)s{2hJZMQy RwȍqC)< HHC("XMF¢$p6*Wgᤦ:/}B7u' UB7z+@E;TJlǔѬ%XAXce%3d\"(xaG KTM4Ď Ɩc2RNw6\[ !IHݓJYa(r,%ؼV4!vn6vw.h08S= ~(#sxlQ<;pY]xN8+0jE_$o #yϟrI&yG = a[006(_o͗B+]35-ܔvš |dv>a_ Nb"M\0d_E6Mv/E_<.jV9Vv$a e۱fʥMlYN>!Z:}qJr&>g&.jҔf&Kւ<|E49>qb7*,B+B̂X9~qd cf Eپvݭu4$E1-a*:{]Kh}Co̅5iJ!Y fgaTԲKٔǪ++a*3L)(!xk0YƁ+}P6Y߷yeR n'cyAaW/]*5eI_faLͳ&Ņ6iEC<> qMvO5>/;9x J3i0\YwȽiC+!"Sj$8 NY$ pPWF2x PSP;OTzPcT5,"C!OY%{AQaHIdW=ܝ ߧ? o73%[\(:QlC>1o#j}97z\@+/OHG^PxcSŏZlIw^6a5S!Y L&:(#ai<55Ɵ`lSabq/{ko1ъeb ,]Q/j1aw v6V$P\ ޲\%2>̚k,^]!ݲcsA=&%;Z\zd ;z葶`/ÃeT6e 414'U2-m$E^gKGewizrᎶYZ)YMWt|`L߼Vp~HuJs*`uiG<)Z~yi^pb~gn(ިO%7U<ci0 o jJM2?x,&zK9}tW |b_,W”e+oqA8DrOBlKM m$R-9!VS#74k2z.n v&ǫSYMHȾ[kM qS/hnuw(L@ mȯ&|@A^)DЩpPFDĨ)ʇ#z1ĥ;WfKxXtoFn{_o.s:%ޒ셯wg[ɠiFnȰޟ|&|Ζa1z|44eD4NN][ I!U1vN&}~i,nE~@%f~4]\v-Ue=gjYID c 6 %64F&20trwۄQYaë4pzC.OwUA0ib&8yl/wK- 7iE>wk媆aB?$Rh^LS]xi<4|Tt>*}>$^7㽃0CoZ X̃II^oZ ~ĜlNbx)o?O733?ˁ5CE!&e#YvuR3@<#^%)>P̋LbQ(m(fןŷ]g^t侳#Ff||&frJ"|⹒#y`|yne'j?z~NJy*kW|xzN.c/0yxŋy̿Xd>֓|"f4H/&{IKeJ񅚔Ύ՗J%KOrɿT:(Ã+聋?j!~ žO'Fg8?%9H+řPDaz uAڽNr+%F $&w/UTڽH\ޯ8P0ڞ䝃L,3TWέ'=6b$4{π r5/BS5ƹPY54UKI%br׫Y6S^BHë?>:.E- A3u  nbυPG +D^*mkXCѾ0ڿm;wJ+JP<?}ƙMCqAj ˸t4k_5=/V&C|a: 4[2 Tp|頟N@_}*EoX N sv[Bڲ`wvM?3#j4!v*^on7 iz:{ahB*;%S?su6uǭ)m/5vjlkj`j77?yM"3с`#[8#%%qɶ7z&Ntx̍.`ސ$EonTyx3|%Oq>VmR'{Wb,{ 08- ȐJS32ŤRf{ߢ'SӧO,zOwo?5rp̽TYT3tweRweFG9-Dd{dz$ȢQuHG9+{S9{LDKDTPmӃ }b{LeKGgF*G gyCw{tllЫL΢jϺaU,"9 lACn(.]fUE70t5\}^=F-%dQyj BMOywNh̯[:gT" J#T6e0 ⷦhAMoU4^0?jWLMCjY:g/lLA,7*+k>}iQ5bsKiK-eN5Ue0al:(`F1wX3 h|'eesAx1*ɉJtCvǸKHk;7ҫ>Kਥ3͚D3Z/DŽ&,ē6+XVBbѩq}fG;>{W0 a@#j(.ܜ5"=;SUWAf/oψh),*ږ@$](l )ɣɫsRuqu (Kys7*Q2z}|R,2Ɖ镋Y*]aGJDR f63e$nLTgA5=YS;E#ڊS뺣FE;Je{sE:V*=E£n i:Z _.㫫 b]ˮ鱪ӚO-j) jpYq"8f&x MްQm.VʇkF3d@R͆!piFD l[bǡt yϦTӷy2v̻J r~*x_mGX(듋 yXS`2O5A!fbdxHV:;lOd':\ECn´emk`]nǨ_+ΆIhu Ev䲷mo)9Mf`IW %$v5t4JX*U9JjUO(2І"B؄9B7g aholɛ05q>$ !7@~5+jڴA[|߉ g`ijLRM<uz*1ofCaHލm"ASH译OԆWZp0 +Z;FL#`֎Xسx$".ws~45]<@8^9"1WyWW ]*2ƵD{ұvc!kߑ Q~^;wmQ Q8d,`o4}ۖQQ_#lmI-r~zk]N(pT1\,!o8rmp-T3'cA#tA5.N( c 4$p_pŠDGVmdN:ޣPv3mv=5f'"" W/Tުl )~h;d/]q#M}P1:sX5;S憰}[iɾ,O7 N)_o+AĦۅ#f8pN5ynE!&9 3{7|ˎ ;ĉT!BQvjXvsxI( xdU m6ˡ=j0e=9brS̴Q JwY|`φ#*20bXe>ut>æ?/Y3cDiKW}Kf䭉,_Rr]EA=*3@QmB5uyu #X /o]9-5|-c&acqCh F[- .ҌP%>XsD"wLt|o³\7sX( hD-ѦC,(9mVS@ɅT0>(bcO`,`@x/slch]70M$-3oLvqj=7ur8&mЮUӱ: '-SbvYu|%,ihpi(Zh a;+47bRg}ޝ^" $s|fդUu)~E vΎD- 0f.f=؈,D'  a?6>R;C f҂9 m*S; Z!Guv}k#jDƚ-+{jmNIO!qKv1xݜ7`K@&b5%kMj0qsl22O;*G&戌']<3dCv;C\1'O? TT j1 KXax.x!ió1^>Qu)tRH on.hk۰@K 7o]`&٩,2mN'&aw&wBDp>annZ46qvD6E^(Zzjѫ96qAlFBrXҪH\ղ%*>̙k*])ܖ+Tg* =4kwԎВNR|xeT.eK2hPnB'jVE4<(wl0";2~ʓ{緵V[q֗߸Ut(-1B}Uq d E'>tZr]pv/?7T^{[),,bӦ+$Щ#ࡢt$Ӧ :埤CXz":s{ \mzuڬO}4m o૔KSKhduoa9G'nH8A1UMf?LE v:)Kٜ~g\ЙeȋMw ZM`j}|#'XLO}PB 5'WH:j)Kg,Y!P$ 82 ((Qgg@9ځ lNtЍzd" K??]MU:Շl}~X%4;[HCY=jP د\,B߸Km]Q؝Щ/ܼ5ޫ%IuM _-9x n -wO F8]{v6 @D Y!XE2Ru($}pA<ѤPz/ZKԠ!óVX%pL|Ldc"ʿ쭉Y-oLi ݗo@g p}*N#*tN&l3AvXH%.ޣt!NSӂbK&4vMptWO`riML:*/[iX@7_9F?f ?7q*/x%|AOxtx9}|ma hKA Ҟ5@ ]a->rs֨ 5Υs0ڂ_d9{Ec bg_Ӛ8PMEj>وсNgRQA2bMA<3xC#tCA Gf qo>AMjxGϱT \<^^E&U7=~:]ۮV%}[zR7 wPb;CZSf'6=}Mڀi .<:׾EB˜43j[>S̰_wwKE<UPΘ2 <7]<碲Vp0/Vɐ3S~zQ+R>X*(X( Y>Љ4HM}7h?[=,ir?[GH{,O{k(Mqٍmy7myWnψT^8'Fnm{ws8m [Wn/47(ӾAg/߯]bWM&#CUg ~ϽXC/ސ %p`@-/̴_/ufȇ6}uE&ё09ؘXԓ sR]/WrY:^L닯T3T+B XJ~Q3EӈK1|t涟8z⳸/\Wފ L-y fѱx 錙NVhwcStLu0gbUkX:\ o| )QOa5cXF$eFV47o;(=M "QnL|#|'#{7O?u=@DvyΫ(tA?Y$k+/_S_͋躢vr^~c̿X~Ųڛ-_O POUkژ}kOޑq7zbz0'BSڔЪ[hS/;n)o崿vSi|}0tSI8Ͽ;$ wꋝuZޭ-3ϽRu-?C5י)Lҷ;" ㉟wƗd4 A;Ŵ?ߙ{6HCUإ:~>^)%|W6 F\ Fo(;ޜDJsׄ:Z7L$$ rb>~X*-KP# ōAZ?Q6&hݠ(=6tAD0"B彿2 8o\px[ pq- ~" |`q)K Rv@Ѳe[8R,HcђlY$$[KT9IUr9%J'8J{voGRS"ogzzzz_ _p_-mG L69Y YcZ ngݲk%T֪{pt?ng|R?3xc,`ĕ1OOL %&bSLh1M &0 9{#ꦘ#uCBBMay R0dUeS:bRYbHhл^MKf( Ѣ)F,cFUJ ViRX4Y6g-QL yM7UYZӹ}z4 M^+c lG, bÊjIqiY7øye6tѐ̡QT<3bPhVIߛ:a;(R(]ȆO/eլIP1Fi,T$**&8ݵoj7q$:Z4%9mNנkɬEsaY u.տ.`&I VcUkܒULMRZق^³)9pe LA,W>:&Y LG8]jTP lG41^mMo40e )aNE0AxЪ2'2; 羊ę}|6jK*GV8>LDVT A v}Q R8NmI70.jӅx#.uRaյ~^JCTeRX8"lC簖UP1=键욥c1hwַT _m kR-*G\^_EB䐀5A`"邱裎\{)t溶asPg44kl1`_ٴ!Xڼ%ԑ7bM |p[W8N35]KnqTlWt9 ׭-M' T@l*!-5v~uydPmz!3NlK3r c2ZyPϵpJ?o.ZR-Rq]Z ]İԮlB3^8ch q^Bp歵E=AAt'^QD|eŽtm]%n&Etn [!g~ѡF*SBvvg@ w87L@50{MipA .혚f/ !Q DpN= =1>ApZrr#d}g[aR;Or^G(a*f | XI0DcFdք vJ?;H[NYTnZ'0ؖ9Y&^Bt!L@JFGfi.B0w $>@=NtӺ;=sGfϙH4ltE;U#z}[bRSd(?0X4_91c͒XسVW<P) #Nu#̇X[Q IsE˒[Q%7.xkT3Y2q̘lȠ<ԠEv2*TPfܵsaLXmj3l={IMK 7D. c:E!i$a*v| 8ړgG\ӋUzToJ~ +ё #!!wq hi H]e0_}5iV0L9Y/ƫc0{=n_a-4y# JΟtvS@G ZW8QThdaC><= n#88tlr ,esHYHXg!#wDQf#d6¨HD?nM< eQe≓ Pm(Xh# 2;I:ğ/ˊWƵufęw5Wfm8_"&NYsppk&e/ȖK03Q|t"kVⲡ@?p4,[ bM% ELYe.cjml\ʳxΚq05-c2dp@B !5+;W^s.CbAp}<~NCa OVGTcmY@U"?2'#흨jZݢo(#X6UشG[N7-GQTG!@hdS&<-gS֢kCQtWKߋfR2޵%εQ dUg}FߐvJ#XAIXKŒΏev38WrMcYLR 4$ Dk*=h1]hO(2EwM*p6SG&r7q|??^9HHRǝyّtmSk첕gMcRba*;0(dq7|: "˄s,OD3mڹ 21J3X-$L''K%h iQPw:x#&C'-`Uƕt "(HEn,vB=ԟ.L ]iŲ"y&ʘxPg0U&wG P?R!M]W> ']25mHL)/ F񅓛9c wwunW]My`ɻFru|@0,`'+%~k;ݔ}+tCb8:^pե Ӝ&n[uOL$ƾww- Q*~{le-rw95 عL瞧d'%~jwNK6'f&}6{ c)̽-QYQy}=-Tj/wGtJR 픝 4Q^D 68P|u jml J^r_/$ N$^} Gs'ɴDS3BٸlPLt+j;dvϴ5xPjOgKhnqջ)%?rpڹ*3 W!tork;GW3M-jb" oI~usOǮ/:jc^ig?ٯ6,`:d ^+'6y^LФ&tί5O%?"ǿ֑몈jq1 bxRRveNu^=pj1 P+Y|?Br$ח棇XJ@_z}kiI6_eGo3f/S=O4Y|c*:P` )J߉|^J}~eWMhK kKL‘SܻȠy _ď8p&FqU"XH ?Â6Fd Ⱦ .yM2}nH,^/Mr b/p_y"s-*o1dG0`5:.'|u&SOݯC@ rOfsI>fcDtw+BN2* MD/ aYVσk Pbօ?ƺa}^5y }? ]516kZ:Ov9/?ٝ)w*v;9~W/x;ipՙeK>,֭Ȳe[ƒ-ٲdk$dx3Ӗz{hYll0eaw6p h \ $U즲.JmuHcC_~z Yw Z-GoLODԣ] YkMƶu\Wc>!5%q݂퉰f)wxrJ^!RCţV,g"w/[CcQf|cgX\ I jK Մjɐ 32r+Gjp))JɘMI @W^M5"Kj\M)QL(Q&%}0JۃHj>LEƕ&ݻ%@N3?6H!9ۯ$yxNl ?gllǤl&=:9uKGN^?gX3/,ddd'0KXR_[Я DEF쬌Ge궥Q%4=57D}h^?UJ02 &bJB& ?y8߽ե;0s #@C"6ciDV$Y> ;`fn½nOWU7^:N6 yH=Tv-Syv*gڛOKgK*鋎,أ&()"ۊ`60=[-PR\ ',*X2 ə(4UBeו i6˝g1N#93t BՔnXO,(ΌFb8Mo!PL3$]LEOKhet]䒲x‘ESg.*gciӬ1 TW/,(Ǥ -8pW~]ݨ%$Ű!MK(bpAQ}-=vS_U]0*T) :n6۰hplð.|X:]H5.ӎ*B5bw._Q\}Y/=:qmҡd("_~=~R'W[@kH.ʀa1 <{'XdMkEOy,R`{#%24+׭ÆMIx΢68]v5kE4v]CUR>9f)Xim0zZ) aG<F{VmGU ׺55}ڗu٧#pMۖ_Bnc$W; KKCWFϢ#cѬDz{I{%{3n@jq5,a%tQtW-T*7-BoK~L@(B$XK J (= PT۸!q$;KB lw`g<ŝIx1 Kh"\"8 6 7?~>XM?تIcet3tсW*"X*awTuVc2F QNᤛN PsԠG3ʔZ{V^w؇'Dþf x''Bj[*wq 7CN8stwT'\f:xVK0;C3[d RƑ͇}7K84f&Rn޼ Ķ~/אl~[ci3(T[\TvnC$MemX%; t„յ<5Do%:3xqޱo1mdK=ony h|fyFCJ4Ja_ɑ>zf 48G=V$!2?yn~Gr~T&{zVlN0^+yw#尅X,7 U>?%?mkA񲰕ҌK#_5:a+Uu,-!O]kCҴ%r6T 0 HEvJ ,pEʁ4xe{ye/)zfdh?KA5s|zzji^-@W74 {1/jʹZ~ /a*q>Pt)zQ6z-ap24Co.jb~2' &¨-%r7&v!μ/+;"H؉(^Qn=/8c6刣y|l\EA#ڦ[$ +V'Xv rBv(܂XSYbT$n6dJrb&kbTF\bw[NR[UP;%UIJw}Kr@MX-"r!4 Zky%C:%{BeU#N^3# p|{v*E8jmu#&m8<Ǽ"ں1mt2ѕqآ_\;:l6FB9N#[zMx1bUU{ vK8, /}=-V'a $0 p#30nT(KH6x* YkVk^$*_C|>*x4ș؈b "Hؗ{. x@B`Ri.(ajCF c&8YDWNMm{ZXSP%5w^ |)hJX  ݺBtƻTwۘRXANaV4e=T6H/lf,[}x IoI9%)YJ87BTRc0_ x6 URE Wj~+k*;e£f|G0p&pa'Y,_i iLޣԋSi* 1w|SN;ytpg--ֺn3Z( bMK⥧ޟ-W2$w_A0MkW 6pߞ1f`NO5̟;=tde`>`VɁ0/C9}?pUŨ,O,x+D&aw=X17J兏:;=ƺc[6b]*ipHч^)T*-?=hI[u@&?70P_SgtCWgJ:X 5|c9t+)9jUEQ;q豑=Ľ6'pJh_3J&@:? q`]O< R@;qM74^7Ϟ BJPC_QQC%חĪ2=agԕd:i*ĽFs>A&JYV;$?nLʱ3VCыt3SϮ_/DŽX ʪk\]a*bʔA<~-ne g5,3`; L7¥I! G"d|wBS4IZR4˜6Ă,Wj[++yg‚ DmEL ~f>Qɶ}|ò^Lyq/T 'HX5SRz8wEߒ|'Lzqyn-͙wz?Ki o7-UH-myՙ9ug*s4^gVt)R-/׺RRﴵ"?\Y؛Ñ[n9| Y-e@+NA GQIYsS+Ci(ځҐQ|dтhp۫yVn9ժy;]'Պy~rRk8}~ZAi?}c{[zESΦ*`Jf6ARfb o Di#)8,:q)igGwa : NәqS̔lOTâN+m7 FN`bx/5G7..4G jn o~3<6xLOLh4TFII)< ]{s[;̛r:sc P\RyvboG-njєf_z׽S=:;-n۹@_@: l:߂&k^Ż\? =wevsg٦~>^3ݝA,Iu;q療߸0ॣI~`$i(qNkQw`y)5ADvBPu[_3>:dӌcI^{rp2SbvE#tԕXV)4y rf>/ ``|55 )eӣmjsfR"E+D ~j`6 B!G[ }~u5PxA_T97:Wc Ax[kpTǕ.^ 1zF @ AB! I^wf.jw|13,`ʼn77f;ec;ba18[ݭd+Jy+Mmw^}ӧsѻnh$MvYrj@rZ?/{g*^顏˳z M }c\rˮ>)OqCۗTc+27D&d]@?\^/U7~WPzd( SS'h=~i\2 !^5O)}nmcSeRt+05"D m,OI?%n$ 710'e8{%JRfܒO%7 )G2lZd%4uGM ?|YԖ!g G !s? ιFב֓ndG3iˇe*Hq}z[ҸZee+!#{5ee48UUC^CsaYw}I˳UرA C@5.8Z@T8c%-k];iv-`zQD?jmXsQnl,ïiݲ%{,͸8 q ֖>cg_ l-q0ةpaKdڮj#+ݔ񩚞ܶl,95 k\?幰.i 7엝;7=y#Iy6Mq\_ߗ? ׻w ݚFm~]2e@DOl/8Imٳ24eD3@ 1zԍn[E{b>@I P)[k*ͨ!Wįb0NY 4RO2tJ2y/lb$eL:QHʤpQzd! L [{$vþ?.-۵hÖT*;ɑ ;G#)}H-LL{NuG>":t8k)Œ1#̆[o)W1gKv e[jV-%3>ځWo|d?b'5٥,<@bQ~;F,El#~l%݀A;6vCHle<by2XA?>T_ ih\Io%5 jE,~qHX3a9«Y !S ,zngB8wa"+ l $m܎ q^|^Hjz1ӇJ#5 $oN5 D[Cۺh87p*>ctF&-Jn:CYm`F!"YZ䘕<)995$ϕn3``X+俾gq/$ѻ$~^?Y͎E\G7oD6jHX!@ vpK0Vp5,A+;2. FR(!K`ϴkb]0niB MP ر- +e$M4Gcwr6;srAwK3HJ,أ1L$.'ڈ%6H0X}W,Ĝ-?8j1 0f):F3P{tL,s{ѷvshsC.+sFCЁ1Ⳗ)B FUUv=1a^oh؋LѓfԬؐ{HyP(BKpOHYEF v bX@/$ok蕝Xi^G;aCӊQ#|rҵ!y]zX)ޅNPDdGGg'\qwrV=Ҷ2&~׌]" K@`,Ɗ}c$MdO,stQRCaKhwԘV9T,D0tX!!E)}`etwJbfFg$wLcv5~v NW]p[S_|[fq5В.;Oi:d'Tq.=귊Fk!K -q4!InA"њyS!~镝tx)~ۃ3 ?mJ|I(I䫄DAh0 @vP5:9݄{pKq~Hsj_\Ib5dL Bx MGlwzh{kv 6Iin].Wcya_b{e/)wm?ܪJJ~U )݀{7` }7l\Xq S<˸6 >VAp[-|#2K(pt! Мw% |Q1>e?Z9n%D JL7. <#4èp ::zHܡa c8|| \\T@'XJVuAj9PSM4<ȷ">H(^\Z= $`>+*@t-gOe“˄}`D|,Un;1@P+ )7 &ደtYd/=P3s?wxγq-]O#&̯5mz,׍ԻOB7\`g$ c_Q}ᗖζNll򧞋F .J0I7'SGU4o”ۜF}`cq͘dqDyG"Kw)W7W;PX Uc8ܡt&5 7QS|Lg?N{7lkjv4m ٔW^#bwW9ɟId20hAA}nLe)i4:#W ?;S1XT gHlC嬮J?pw__H`—t('WLa ZzNTS<)Xsf@`7y]P bZڅMF>pE,☻AUD2y"ay yrC:Hppϣ\5 N -1 ==G}M U992^HkQR$i36.:Vassj'niG!]F{mqe2,qrH ljaũ”F5C4F~J~;͖hZ$,@M3ɂ Gԏmf->C{k`u4nKjmIrк4~h̯SH۫0,P$HлX!PSi{?-'YĆ\܇g~;P%%8Xkj \3GK@}WtM?M=(a2U5@"(de̛o1 >@}DMCpgdL@1N ӌYrL-`!G5tץL B-]s!).oi !\efpǁ~.6{V rMS?5u<[|\ p߄'q/7Y!JV:{$+6"eYW7s( wg礪sqT$iau 9ۻ$K`uw@{<Tڶ Yg&mB8eDƴf{q.əAƁPJT΋Ϡ#aЂ 94=(sV1> _K}X=:%# r=e,f?,>AFAM:|} eei"%ͷtX,Dr]<}uӇ]( ,9ϻ*lQ7?R왼쳼‚ȘFɤ턌/{ٗLbOd%-E('2օ~e_8gi7C KYGi-.05Iy&ũS^ܙVr> ߋV UojhPVl$LaU(h8h~ G9Y/@>[yps+ҒH_av M^~"s%R`WK, kś~U!2F9J~ϿVX]ª+͟.p{PoIFNe)"ƃD81)k@u ,ub0kaKD4Bb ]؀~0*sF;zh9fH١-)K9?yTRiBݡ`H0C%zK*p ~32cl\jKs5+.|5OԴ>(tVADq(Er,q pNMAq!k F%8'yT:xoil|@Cv d:St(~ڈ3x/g37nknZz9rqpLDiqFnu8ILxz*$V*e?u ctU a/Y"Ν_!u">@;#n%lVGgwhC^D<$vSvϲceZM+ɪV,@/ś6{z:76uWxևv|kmg]TMl$FGz˔>2.w^ʭ_"18Uqh7J?󄠐w sF#LV1Z2eH ޳I fYS'dחHx=Pl;# m\޲ % c^Kq|d#}ݴFIV؆ARg ЈfFYfelՂ6&@Fm7`ɪ\y|֖3+dr} g DAd, TKb[p`L[8>%s ((is9ޭQ1ȁ\np̀Y{ʶ`GeL.}'ܫ@DFV{J]vhs<讱] H4BI4ס|l ތď! J4Pf2Tcza^_oTUaog#u)x-E: xܹ/b:|j9''G )$3Ma}[Nj,^mȩpd3Q:\ !q7 6(28zI/w9ZI %: JXيS~kႍC4$+G9׶_(A݋F~gQ26UH4dBe4\ciIef2պz>J*15u$]:lSk#R4Z òZIX=?[Hd!b%0͌VDFU/I>Wb痤%UIU/e"q$^ &"MǗ8oȽIx`57Ih˖eN#!ŝeq%ٲa?|a9IsDs~>p`T״Ϙ~as1cG@X'ugen9dX< [$5s"^A##UyTuW~'vGHJbVEXLZWfvsxEd9PotUUUz,t)UhupL4/c0> 3“WL: 0SyVpGC `Mt$)l cZU+Џ:y>v pIIR ̴/v`x,FvšS' 9󲌱Ime| 8KNyn)ybAYE6av;a[<ࡹj)GlwfVn Le#,xL@Q esQkNN1^BebSg[49#0 DvQ|n]ĞoqWB{˹<|.?%eBgxXCx_x.{Umh 5 |Ruh6.ϳ` O"D U[/   ^ӎKS\K qS PKxtZ( _#4ggФ/?YnW#XX⧚+^asvXɳe9[k|z3ӺE(L5XfPǼ3>-QqErUK#z7uqkSf7!p\쓔lp'Owq .g@f?>>+v X )-󒌷IFYWKv[SYtD&.;C Յ,)ַgV{ǡEJk6ʈHWˬGҚ bv-;a۲'[jDƽ8n=UN?74N=5`ض'XֵDʼnl&`heҼ 콓`9$a~\1=OKTp7uV%.y^*OH1 \Vx~6Q\࣍}$/O`inժ~6!+F4(TwVky̜n* xP8Slvi)yq-@ü\U)^oj%aO2FQzkd4K>Si=Ҧ\c-RGHi:_Mv'8*EĪuaA|ʫY)x`AE< ]ߑbw,HiG ;򝱞:2Lz[ˆ8!W?{RGyQg]y`n.V؞/A0~v[%|?M~mZŜ~e;^ʹf&>Y'T,%m|mrakОw e{go^NOѭyW4X^c+_0,|i.e E>@h52\V.-T<hW\l W3b?2"mٓ5uOpef‾URe;}Ғ &R];TUQf_~#@a@1_hᄓ=>)0k|M‹{-o2۫FPYሙiCScGfjdRE˹>Ө1X,^=Gw^izYZ8"/x!_B-bM}\R>ͤLQIS݊y0/b5{ml/$ FqVR ARjyI/,*/#5wd)h"W?o6]y.(wH՚0#ǀ徕ONd&8#C?t:WW?P4{gW@VXH[ ÉgY5cžX"oP+XZcAYeq~GD\tFBPFge~/"P6&~} ޴a'9(5;z7rJ[1Mzr-Ќ>{[ڣ8yՊ%Kzai' HUԘe;xL͉w;wlf~zy@b)dVG x&V̾xwFSjlt/LgCɘ2i[vYJNF|6ۆҕq8T3#rQ >`>NWSfUПSMk[ zx@v 5.!.hP(UI4`,ic4NǤ |LfLw3}gt;}>3ttf1ުz{{>CzUunu~s7GŜennl*P]xhCRu~W~Hu}]O4xpE v9uXSo*^QSSTwⶦk'SpNYsgolVR{z63:6˿kp66.xPT_)`{U ڧnulSjAmWTm߾qۅ脘R}?jM}A7 n+`[,%h  (漣j? `z}t*k^D`D+< OH `^ 'FmQ=W]:FttzGa8t> 8,QԋtR@!sgzxx/yt<SB ~`?@(ĭ1v ءۆ+@|%쫘'gy_aZ *&5ܞ H`橀!h {?2Yܷ~z>daAsC=MyD4xVH'PDƐ'Blpz| >4G"zsJb "pE/BϠ_V7ib٠%X u nH`OOL10HkIKbf46fc壑-K6zC;`&食ܑjb2ڡ57yU7b c\ŵo}kb&ӛB֐T:/h=A}40̢gywp>c2Ŧ"^MY0 bEVǜA:`wJ72V]g4]64Y= $ hF, vyw?!6q~]SAZ.8ͩJ#Q4Jc՜YpxmG}_yhcn]뇶HlosWH]__:y;af Miy C1h rPaW- H)o_>5ڒm1~N`)η!]BGp\e(qeH -$bZ×4/bۤf„?o3*Hڊh7c4;|Z 9?-RK ѸGj A1JHO#9nl@S\#AFgcqXh@O'ڢJG)TP x *Ѷ#u4Uǎ(6eH b0MȦ5_)fE%Gr4;1ْ,3~ L^>ЮQJp%'ߏJ bgɩp/[JdOgQ4 l7܄^"]׆1(oij!\Hd&xb!a6v05y>ҭ^^MyAM{ PmS`o%iٶq 0ΧU#YNT< @sJZ\\8 0M|_z2w Mf;ݫL1<ƮÜRS""-0z4])I+B416!saBϤ|r Qr2|9ob+/B?3jQm}=;!T}l,V#KZ3Wu*X:)F+O 6 W4I [ɦ{@ʥTJͳz\,GDHbxg܋VS *_ɱBv434H|dT(@hgA,ԫ2**Pü F!~,Z^"@6cQav90Boob-îYK`̨"EȎ<AmTDѿ[Or6 %!Ei{lEʱ MxXuc㉣ 5{l/疐w=^tNOqic;ٸFz JIBNCiz+r!ۂ3/SX.8 Y3Y-,N-"Q~ aCᏐv+(>`L%G*%B ^&L?QxjeJɬ=ټXAo f}^?A;`#Z'NO`@:[K-S9][/l {̞q @ӇvnSoYZ+s "OPnЛMreGuX9 I-kt pErPPpwF>*۠s' ,7ݨ&[C&"BP']<Ak`+v%fSVmGFž]a9(w:46e1x!BIf񵹠MPS?EH_"Щ$U7X6^Z( N@Z"cPi0rK]&t,rT6,DEx޴Zx8k! _EL{BQeDl}<`E空Sh7l/Ss0dOSP+y+iqh )ƿ.OS?lH^uԾ:_zQsqX'=\KGgæY`0: m< Z8K3ƒίJvҗ_Zݼq8M-Ɗ (.eutdY¦]jnZ׬IK0WcdQ{kR*krIQz$]Dàxڍ4{dm΀,L݄ :M9zLk|yd tOt=|йrtnz( ~ֽe LqS>LwtSjVC<T5J ص*uT֙xA.(TSL;Nt%gau14uV(%*m:01DsBfqNFiv$Bx?6+fyyXL6 ۶3×.< @le϶o"BH&fз5- e÷NFSxt&v:VfDV/D:Lm3{2$dY5B#\WM (BdG7zdJnڄᩕAB0XI h,b# s"I#2Ô,3N>؃ jv9N|˟cCtƆYH+B.uڽ9Xm},Q,(icK& RE*lcEv>dz!*bSzOA8-9:%&?;`_:u=EPVd#Kq~(f5wj TeL'Jr.̕uJd[^oYe*JP/LtJLJI6/dLQJ`{"BnmAqݣJ؀-&όq8Ͳ̐;\eZ%wGH)z4E_ELSjJ-ᴳ ŋ1s)&iL#4;5;j3 wFБ.gK(OKE2!8oN;8<^[s`.e7#s-ƃ](VXxRŰǥŸr=%L#,)a/^m;^mQN1x˘gU+fxds-]a|hO`hc1' JȺ61T Z`gO5= +%VTM!䄼 }SDX5 *e+H!V \VU 'tO~}v/IXldG4]g,4Z2j4ce1Lb]^o/;dՇ2TR>s]./P!EbtnCpOQ^8~f|"W\PEU] (cbus{rG+^GK(u OEhK@}eNb^z<>'=Te%QzUwa<# U˥<߃e6u4{>ݟ2+ 1;4b7[}/_#-v9>>Lv;] OZR#g?0n]˶nӣz[_*BI 4E~okVPF\{B|_ےcCgn{:nWf5<ݞ ޓLdc'9 C4_ }%q){n>{YVlm4g2eƩi9nHRyX2%!J9!BM (?;.C}Kl6qv0*B۴ٹ3TG6ZGgg>,|o}( $v ɵZÁ۴hm.s|6~?.rV16RWejbqKq{}G"$Z2哽מݑ%Ą7&R*<X8Vun|+ ڶlvDH!~eCf<{m%B?[^PC;xTȇ/tD5@\l'm4ݎMߨHkmΖ~Z#˶hQɇ>lxo@-3/V;%˛^ӹ8r%f6;N ]RSa4bF ݮ2zjρ yaR=#΁ۍױ;`zO )Zhz%rt.W756_=|xU%E ?$#J%]I38XW#c&?)B~dw&y[{?۽ps\f+{;cj27ޞ 3-:. aO 4~+3&!?K<>M:v4 ްMsx._ZeIiPW*gצNõKY1^w))>+}.>o A`tYlgȳ9a>{GIxo3\TC1>dD9 ,joR8vQ\gGXyيeD!ܾ>ɂ3 9. VU+Շ+6n?F\~}7'W"]ߚ,CwaG4bKKs:\{Ibo#dNQߥQцBsg-OOs!4+ rqI=ĩꟓ[+,-]]裱&" x^ЯYt`=\T_XW]bQ GS݊xא< 0Ԭ#mĽ>qPOkDiY,ĝNeK"8ɇ&sT:i9|pR(+q}o![Ȼ.DCҀ9,h柿)9(~?(Z)uz!bcCS z1arnvm2䱃}  ßˠ4)@Qt2L .dBdMHɓlz>i;+{Ʒ b6$d9hzclFa{ӛ7mgt3|3g>uVZM۵`m4&{ViO?F,1\]47bHt_BpY6yd"yYIaUݿ <@`.];X?Ur>P؆_8jhr/вK٦84Y1v}|#!WkN}}f CtcNs:>壤yC)ap8{Jt4E*Uv_+j'Z;rƏs# U{84>8zИɩz8~w;2֢.~tx|FO19[Xl6Xt>c$wD|~IBp!3y;2O?Ģ!u'iE8Ί?MϲxL6tVb5Aqاhϧsi׾Wʟ̲|휀F9.]+,?‡=|9}u},a~M0bz$ x͝sבWTp'(혱̒ hSC0ڳ1(tU]$!MGtMXcf{Uh]~˗/?^ͷ/UmsQ_])UQa?׶kWŋ~Z + lE]1p9/oY5u,ίԋشzqNS7ely,7?l^|ݰDIur❇j4g95!US0eg]./+?Uӛ,u7y[GIf$y:f;sf9yLLPbiSQh0ԭְvoUuYEWejIӪh*hQ&ewv1bqU\]M ^1Du_bۚEZeWHX-l%gԶe~dsm~8]}^釽d87zZRueV1_їGbjo t8)^-撉Y03~U-wp8f\L#Hp)p+j~'egFIXbUL`~sP6[t sPAI$l2j ;[jQq dYg։5phe- E!sP}aB)Wm]5^{_|%x.E&H wN%ԒdgC?M#g '`K´+fUbފwC|>i/aӶd e93H.^uw_?:7}+wj4]gc~#j*%qC }pJg{~j />~_šݘ6"u`XA}x:>2]y O2Q=<#vt~1.R:8I.b:2ʔ&и   V(,}b|b Zh$a5V;x>&j #hƶ_LDkvU,f+Rg]  (}g ؊o5tOkO"ij;A 71Q([kɯUT9<'A ƊXOMN|?iWE]%SNŋ>ZP#Q'< )`Vzm>gE RݩqYRSRzWkIEP3'OBr# #޼FoyE ~^teI4&>k20VrwH]<*>>%#OTR% sm3ĎD^qtja,h\ YOO8 C$9 IS>? êQw]oי`A]h|[ribKa"fؗ$XӅْ8+f5ز@RΛT?r^ZCeН;leJJf5ldIT0=GƽP{gᚦfڰp_hBvj3p%@ *]V'~h ]E9Lɐ9tCJt{& Y퀿]Ze486-w|lI>h>ޓ! lA|嫘˨(#ͧNe3'1ꡇ?eh`+xgJϐS?O}p>Ԓ~1+)ԓz0.\'R)&"儞rH1ŎUxϏcV6kn-6[>eM(PL0F!R rXɳDoM_{"Pals֕ ɶ-4k3 qL8tT`XrAID6T|>/ Wh I;KU ).qW vc*-!"Qj!m9mG-;IY(HBGBňZ[rQ=e!Iuz2Ҫ32`uj%FVMWI?}||*{g<>bz2 wX֚khNecJcڑ>i)$i'> }2v|jN $!xyd ̫xuqa#^Ȗ+btտP8OVKL,0HI SLDIڦ'vi6B-i4 :Y~%RJ>U \<G\k9g=Xt9rJ|\8A9̖4xikX2.pɹt7k& 3HJfrV'!=_Ea Ll~fMPaXT<}"FoեLg[e41=gǐv9AwHbQ2107ArEvXl5K]j+2]E;@O!,&oy SXE/wYVE92dzMpr9#k$S+Qٞ<>&nt D/U Ni/K}Pr=AiœlM 'A džr1\bu} 5v &c%xb'96L )3J4V&_ "h&hali*-=4&k[9 "M31'ui|e5NY.zE2ê1(aSHAJnŅU+R!# i$M]6ݮP73PRGݵU& z \9GL3|TZEY,)-Y2ܙ/^ɴ]) U s 9 }(S1_ɔX=kgN0P М҆‡PpO) }%[R8qW8ϫߔO*4"x< -GKB՗S%AxI{=QJ>18Ђ9!]YI+1FiP9#ZJ q"uJNZdhXctoh4NfJAB{%/#LbA/ W$,_X|;D]C8A^J1R.OYݬd9XUܩS}bSU]8ԡWDL;O)DoI$^%V\t1TC`^QFKO:ݺ!)# GNx*lGOځ[0d`7IZaU+eMTeG\J¢W%b{ۖ1 &z\9`-9m=dQxE,Q/aNw..j5% z7`iêeXxd To@C+-0gk쩙Tkbݿ!Yo̅u3&3)כ+K,ʮPqI_̷=Mȟp"d#OzB]o0~f4,ݣ5Pe酖Ck̲^;}fʈޤŚ8;ZGf]&vc&m86@qF,u`'g*#"vjGo̥={{[=cӉ j';Vx):7xv\ >0"ʋk^D7c761" _Ƒ9S OI۔+09.L>'8# $mqWCq-eb6h Kq}8/S[y8򢓉EM,c!A5W EeoZJy2TzPbꓮ rWH:2/J 2S/| _FE˕G- JXq+FՕP@fD}!u?M:QM(UIC^ˇJ!g5BXDsy=hlbE[[h7.d'LC#`.WXM̓͑i.pDv7-ͯ}q:0bl'+ uv{VcR&\VJ}eGRsuqΧRr7G^(Pj =2fީj[doiN랢G48EHU1}]cK-8EC~z及|A59v@V/7a- q)1xU.꠨N7ĉDos}&i_p0}!|?) "8|+tө8g=*Άp˂hN蘃jU8*/~Q+nTE. U_. 50Þ MyHp>E4yDŽ[&OBLs]tVB/;kN`]/FH$]͏V3,;g $3;즾h;k1sd#E<мruKM\A Tu=mڴ0*<qly7J .eT{|1r9p eP %ջ ^3&z;2T(ڢ蜠eƆcXQ)<0QTBo8so A}O\2?!!69-{za2!OUnfcq)G`V ÷!KtwAػHÖR J!${DwƾioHBN{ Prdȝׇ)-F2ݯ䓇eftqu]P}"M>lc#ǀS?E~.B3:w^xFд'q q]SEDM[=-S.W9#@4`rCQ7#}B_@ҧ16iqҙ4;z? gUSxb }521HP/:w_,/.Sljx {(yaleS\||/SԤܩ餪>Jt7mɇI63Ψ11e7ڧ*Ϫ^%Fp4t,Df^xzLnO zX~sN>]laDF !#׬?ڎh5kŇmA3F_ri7|Ad=#:g ߆d@/nD[=^- &Hwͼh&~o{'H5.8 9K|01Mj@d~q8bҖ`E-ҵ˛&-hbW[x“qT z`yza( 2̨q<=R$k-ŵ߬U.JH[Š '|C=Iq (lL>6)R` W7^hŶd?hf$̄#̊CJ^Pxхf'3aW\?ר1; dJZ3No k3 "8hNs|.@I->X/v͹zv|S3Ս/2yFێGbxuSOkAg Aj>mQzEڢC[= lf즩h>^J=P_x#xӳm6img~w rcW`Up#v S9X>;RG]Hƚbd$PCd'n?*l4`UD4zFͻr[TCPk.BDf瓃[m/U Եje õB NYcRD@>[c5zת]Qڙ6 1c*PMAlZp8r~ ͠m K(Yao+JzSf fXI^&2E;Nܹ[c=!E+l4e,$\vGZM7eJw犩uo$UM]+<\x2~52L,޼wu㽀,tPX3(B;e|"&'}! 3:lpy#gS6!V 8"xA 8MiWanVKl&0\Y~NR~9p:h&D-T=j=~d|aI9 u1qKGɆ_XAɰe 0Aof/CДr x7%h  virtual hosts","Dominios de !L)!027V=XCZCgL ~OT}ZG"ZX^ ^`Bb9 bdg,g fregister nicknameg9Uf=gPhi\YOWxVϏE" jz1k"0 e!&k51551㠦/^P_}A\bۢ[B"UO[Dge/{3y[L=P]_K+2 H9Z҈",[Hj-ʤ!08̜U1jBKeh,(h E+-oMBruTDK|vQu9uj̀*rE<\*Tur#~LJϡP8!1QE*h8ћ,>?Wpln|+O}gvz:_;}{Km$s`ݳO =nT<:gZ5;2D 5*m 8uo-unYGppA%Ѡ ?4٨*,J#u"DiLt27qGhC<&r7Si 2W^Ng\Dž[N_򿝡'M9'Q|r5CcXH->:,n,=.0K/31vR`-Y(J̍! km^Zs:%V˜ʓٖ@HOiM?f)^"{" A,Z4Ǫd!"3gs{wKx۵qv 96Wp2lʳY[Lw7x۵qv 96Wp>g4 $7K:yL7;IRfImʳY[LsCx}9ilu.嵼ɏ[X%EQ%RqGڝo4%ڱA]n`AAMT"q hRG-#1ЦF[H"}ݥ?߼o{߻,xF'XTL3&`SÓcM\eI:;nl|S NێNsC"뤄ebLg <^ЌP+¸o6!ŢQ4qdmv)܎30g*Su[4V@,e,Ιe#O?I8(ÒPݴf30ɹFTTE [Σ$HTَ$f|WFNa5/lUYܘ. Țp솮4 Nu"IT|XE(Whwz`*g)MkFIiCa/ҫEUĎs'<{S(ͽ]?WTuDAa%mTqEl}$}!хfɣ4UΫ055./[CoiOiOr_za -dgAE{}A)R3 yH wGGB0[R\LVifmYũDu؜c#mҚ,rZXP$[46Fxj(J4#qnwl a46IV pqTO5uzkN>Vʗ,q)ze]ϐvҜLoı-eLa4T3owGFWG ]@di/=G I&m-fOJg|1θZ(񕎚$W"ȋZ09 #c?sZ޻buûyEBݵt:ZQ;ߔ{FүDiYkɖIrm.Dojj8t>|oVt e3@Ko:jO +h }9;5ٳ4Wn&|a#  E K8AFY휛1ɕ׵ h ٸwׇaxk 3h\!ߖ-U)}FiH?yE;l[Jj[K'AlLk+9]ׅT|.3\O>]WP0OiyO&Qs=Hm}7{8=Q{GqE]ycbYdΖ119<߬tUMk1<;Psgtl{Y3-cѳuI2ؘK\ p|8߽OQΞݺrbkafrdkyPn)Q }]>\N{u0 Y)oMSZ%~3q!mrEX|^>OF?660vEtP̆z)F }; ?+"6Z8.E(bd}^4%NJ0ȉ;I6;kRb$b'DKa_W{+[NOdB-A qr(xV0i\58J1)淊{n$R0_ry(aj~CTxp-e|hۣR8,1KnKz%x4kgrk%muxW!G!@*,VEA/qv߰tEZ_(JҁM<w[ǑnóNcQx(|J&neƅdu٥qDѵ1<&2§/_RW`tC4>shfѐ E1jͷۛS !xíssX0໧7E+4~h- uÏenCat>QŃSæoK<x :2w쾸䄢2ٝ#8>blBw[jūL.Ovu$"ë}҆?k],gtG&Bz>>iYEvIiYŢڈ0-k:QaGZ 0XQ>?l.Of;LᾝB7P)-0ΈFo컯[^BDjynѥ0^&5} 0:廦w%)'4 c/i2-0VgIu2;AWΦ%axD$ZPc%M5r}w,E{RAe y݇nf_`GbWYFn*2XsiWRMKZDahIZl }9Et = JrЬR$7 xLG)>Z"\:G q%|Ez&ClӔ,J%%SƣcCCgWs^z댯>'RlxX\:H3H݂=e5H7zȤe 2B8%,/( pEx?TCAzj{ Y}'%^zT1ں 3OpGKi7eӠ^LJ\E{.iI,2~>TSV>!9NRۡKU,m a臯y̪sJ_Ш_jRX7lY#cb1K +?Aߑ\O/ 2%h09d d`5DNp-} F4^Cohؓ{=m6Vgl}Jxy#:Pk;ㅔz ;KWK5)xsrwj'h=QtZf9{y&3]M3&vKA/gP^leQyd*=Mqך=uEeP@3$Ѱ΍J<])!uclXN^˙k= ~缹OKEy>-1oXkJ.X7Bdgt)rp,KFӿ5xs&t=H7Lo[]4gxಲE=$fmJ;^W;v6|[S'GqSS˪!D TD3 L`ޘOgP[&m:Wvf3EϮꥠDa)0vhxod gac_wz^bG\Uf}2e'K\^5,ѧ\ i(Fgfi6{4xiȪֲz?޸!K^.#cU`~tg2Vr@>60IQdSmUn?Ӣ[NPX3\ b#CF>+G|ȯv9"[_G,!C\ |t#%%l8jW aP-h~I~/=0χW&l>}Q_1ǐOO=7HVx| lͣڲ;Nb/s'WNŦUnJ7꣈IՔP2n~F@ Яm} q!0y_P͙Dv cIJa61XF3l~SͨNg鳋EGn?g h糫#q~{H|aփ_\i] |=|LrqNl?lk%!֣ a4NXzcτ冟) 檖=ql(o}sIe}>Mӈ@AxFqx8} SvۤERrc [z&L:󤃥،GƜTx^a)gBj^nqF5L~$^XT*,>yd e͜JM7hgxTMo Qδ ZۺiVT^șW0s83SJD,%N6X NXp%{yyμy_73@ {te:3jKuvAG7ݛ^<64'-0x&r de>bU)2>rۼ8ufx(dr267~HP:ٞ8  Z !j;r/?- ť9auQ@]SHQ'SAȀ4Mȣ0J*N2e#C\.7;q#5hc)jl-~ V}ws@Ϛw赿GT*14<Z1 VĹ}r; b0Z_83KG,g\*Fĕ>돖TDSJ1\)74?{7|VݢI͊3wt|1V>ܯn;t'=ꤜպ)sfa63_ mV3Ol=RpEwEV1'ф!4_bRFo}o fa,̱6H-FC%^eG ,1Z#QoQtlNM5o?'<냉VF"rln\5E[cL •\s:Vnpa"ԛgk9G&,!3~{D:&qSYIXHQ󠎦3ƉEcdVg^p3v_ )k]B@g\CGXʺ%fԲs7]t[vclWzuBpb?PBs ,c!tImr~Yt]G>u2D{'a^B7mwл~;ukek{O*JHYqPT* sdtβ XfBWlVYE]6vtСA;9(QS}}sWodlh Zv aW5y?:U,e/t3r.@ O_Ya/dE*C66rHC&yr"M0gQ1?ȶw1{h}Uv>܍vz圎[@J s; Ԟ?R<<=|~\* niťq8Kz禖;uZ'{'~W<= A%Lr|uzٗđLӹ x͝rIril fF}Ѣ (P Gkl-QYUYʬy_@75{wȏB{f3vMEdl|]Vg/~g|:yAu]ͳY?ֿhY]&{δZ9p>!8u>pV,bdMQ_"[UrzImnyqNoi*>HT7M[gv]2|]u kahg|uiEӋn˦_l]eM{LM{n]WuɂgYseN~^-|YvҞO1]4?ʗ b1&ܴp-ꛬ.t{RԋbYlX^W74y͓-]hlaDz=OͺJo-m2B=JNF_F\Mn7cYN?am6 2j7|2HyHk]͘錆JsA TJ_҇W53L2AF[pZ:-=~3(_TK-%,"[MEӀqZ]Tk )2;ustϵ˶1^no7cʎ% w %Y,nkHtp78dEelĨ\gd:zNfe\3^ 7eXvrY^dl{٧ռ~9ںt9ҨլVڋnA^⌶ᶨ3Z׈^ % on8^"Y$G 2x k }.:_"]k(Zlmӈ6DS'&uVxy n2qƯ=kXpojh~6QUantlKLSrf* EUԄ"]<Z5Yn2@d Yx2L9ʑZ26(Z-*̩ͪv{ |QØ`p`0?]QY|kin Y~%;{U&nH0er>O[-lIXڔqȬ2.Zgg6rQ7|l.nx厵0>doi1pNCZ`,zih(_P-X r X%Cu?s[2_Z"$IßE1ϊ O715? oc2I 3yk 7;)&4|tGY̋sRYn.*w~##nXk-wKPY`@dUnۤXiW(ne6 q͇ΪE^.5ozR,XG /s*OlOK?nSsfΊk14: 3ųWaNKRv}eQ~oU>k\n|[LxZV˝B7ѐifiL0+ghDkZOժ[ BYVw٬91]]+cq{b쟁j?;k `F1T6ؙ5r82Ѓre$Н,p]ɿ ƐyQq*ΨDKvc* 3&}`o20aJ02}-En]wV|[jVbR4R#Ypad4:c]jӯzl4%qW7gWXw[wr&oa778GhH hKv##Ϯ5mj1-xbnpa3ur诐cj)ͫry7$V Z~b//-ԟpnvK-&.qF Q l'4 W)F'̋ߚ iO ,A!Qzl[FP% O)YzA0Zg>$W9ﱹ:S2MTW Mj`|*ğs6xAYU?g4D@pH M}:O੘?E $Ai~j -Y2+(Lνv5 n|ۑ(Idy+QDfH;4yKEїbzs"+}jc#Hi}6tᬦ_O}nOޤˌ4cS̐Wf{UҘ2ݙX_O~ HxmzhEsXހ8@͠jʡœFiiPU}4~}tȅ5b>50(C͛y|2RǛ(X8F bX[X,v,`%̼@!9Sͪ7)5&'c 㱷Ǖ`X/~+ mg9|.~=eyL9QQ``VKxCY~Xb1cQ)G[W [?ל-Ft&21.K",oӒbZMF[F {((ös1 6\4!Ed#eb" L,`u Y”ZvΜYrSŸm! Kge Ua](ο *|7m`ThKV-:ܝuK}ro"j0BRⵃatmΝ\l @B>2R7ln: ˙^46WhoLrA#x> %1vDڤ&vL hפcxwĤ][<@zEl<:zSEhb(1K}8_:-ݯ+l 3!Nx JM9}!Dv.kk6/r2j5lVl3Plv I mEKɰ;}![_JDk0q0^p2XC2tT"2ybA^ZQoJX OH_M!y6ZxjR͐ìH9 ܶDr@H]_5nУ˞ں#?R2BQ 6'Kj3O{b \?عb)˲ TX: G .ߘQJA4N-~!/Za4jn-q,+_R5JXR8V&bɫG}a8ls3dXYaH% IIZ)3՛s@ SHm8waSo[o%cc ] ESC%}Uthf;U1}JI *>pwPCYT"R`Z!kePxg$9CW۪TQJrOiN%WJ `3 ߞ_WCȦ#X'a5*Ux'Y;OSfTAL /= ~d3h9|$IO԰ T Z>V-'kRHfɆm Nh@S2فB;nlZ]&ʆS)~ <Q~ Ԗv[ >VTC tI-Ѩ͘XR0SP4>Hxa&dBm`92O<5褐 8TvE)Z _&-'tP,۪eJkDٲÇ5㍏|+b}J;;̱0L:Ax=BnZt#Oa6r #N{t+7@W X%6ɠg1pVD츉">'Jc*V|,VìszSSʥ,MuT,%M6!GT.&C"6i(Sa6j 4ZS;|NY%wFfi|$hv Ns ̶ EQ 7;7TDxZe#E+h$pB.V@@Lmi[ZxD5I!*F4Ԡ\~v6y q{OkH%jwż aMs1I>pR|E }3O ?`3׻Sۋ ˏ;_ZazV,O2o9liK]q "F$Ar&mM^-. 7 ɫ]֛v Wt>זbH*[MYڰKQ{R$@&%!B _aF;00p1qCrls zg' k1LyƛHR?♙-!V?80Z 0^1#\G>n.M$NLp_|֢ o|Y{ĐmGu/6@z?9 쥩dZ?.D$Tƭ1|;thjZrخX,}MF S@tg٩uoj>olY`_s9<ℤ/%W^ aj|Gu7Siy)UVoxZY%aY6‘ apO*L ;7(ؕvӱ? ]jy$iGxU*t8bp "| i"N~5H=;߻|#0IB~ipd;DXK"W' -y"3꽖IYㅍ9yb"JCk@ݴ̱Qr'6f1Jo,`DO*NT"gE2 :=$Qyѷl[\W:UbB)FkE|"e傗eIrHb^yA:Aqhk=MQW:Hb#+C7ֹk" ȢxB۬W1`sNN}AV *#87{/8L@Gyfbjc|7f] F TT(/A!p M mG$>t,cknG+a5E t6`ےx,υo]7ЋYZa_O]> !g/(B𣋻10h!3:8ƔA|l'gRA6 57p,gbѤTUdzu=0Y_5#sIk,@H-Sj/HqS|&> ~lW<,_g'Qsr!8J^"j"AeJJ3#3"!mF) #M3h~GGWQP{e8piDvBw$tF-$բ^V8bEP7p[*hJt=6<|Mps`zzhfu[xd?}vOxlkLwRL SxU n&靾ܜ`Osg&ź ܾ!p@K=`wJ##pEyvKE$[x|2f\W"k䀄Y$ /  85]@#Iv#! i]քd-ەRjAg˜!1rTS}#&dՎ|78f),㟽.#]<%{|/:e4JK2 эy2$jW$X!Ѓ>ZVޣ,L4l) 'aρ* #W_9+l BI*)Kn"'B63BlZkC(L/}eԲnu :ci%nj!Z@ٽ ë,̙6A|<}C]:FME $$5+ĚXJݘ )y z:)J`G[]1qHRh/]'[>O Ž1DtcR;4[ke)y) pE1mq5?1coZČI!/==Z0pqA Re&'kL5'M0{)1p#5!+Wq`g%僟I u g9H-SP*%h~7xIl;#s+Z-l{d^Cˮz4Vt3d4jJv-"ZuIg,`]<#81z|j~*Ąiܖ#*l@R=sp4QˮG&@"S{4Ât2Uka䣥58Dgy6vcw!V7U蠈LQ-&d'Jvjs5#cjJXOZ&~ğX(BNANWXѲ-;G/)ba4nżǜDN' uTl.m9hos8~ʛFfu |Mud$ (%ʆd4&Xf9Ӆtv8+dݩ렣tJ lNT?YF~I ;_N_od=L${EZ!шÜv('n`f BK<+RTu-溛yX>ۯAGeiz* }n2N_6ˆSPGhIPछqX3BQak;TːdGX{CQ])vB#@8G}{"VR8oJ(~!R nvAy!w۶U4u~7 2i> ֓ϝ9D 'F.iӸDXDuO*APs/֪rsqL7qaE"p0Q#5N'米:)(t{/-{I[!36ŗ{;r^JqO3EԷbڅG}q6|?8\_G3\r&֒ȴ|_6IM*8R &̹F L&D!׽z]t~8);)6MI"gъ j4s Tb=Ym4G ?,=*+$6핔ߝh)S?;Fؖ48Ǫm. -*}_5n셊T ez:;llhb5h`QQ2r72i+TpA:m䱜*|q*xTMSF)fvN!gawx%oؗX86vnYBN͈~?ew/-ј#"2~ zrN]K8AD*'%% 8 >Q}(AާUA4`?9=EtYmnKX_+Yxz\дyR:'`IL8"5 (Qvj4*g 5sBzu"b{ bn-ᓆ7]xoP,O"aW}qIg㡠0nf3=+a[5Q9gʈsbJXX:NB ?`xPClhZqL|poӰPڜ#/,DѪ_;&fE(l9łJtri2:i_%^S\f 6sJ,/rXXv* xxt yI] meퟄ+7wl2 cJJ"p" @(+v@aX3C)4 +|7ܲOcE% xdWԩKbw,&gJ%'(g$(bFKY~y'GNpTsPwaPY\+%@`L²!$ fg:,oxOItL]xL?NWFwMQtؿ[C6 #Ft7h$CC+(L(FRGGĄM0]=gA.y3+hK4HwtY }5H5Ì:p ӞhZVmQ8+#Y|O:xyq- VzΎ!azbĜ=%%T˜yZ x'w+$virtual hosts","Serveurs virtuels d'#5!*S2H4P9Q?LEdEnSNJQV]@o\T]Ho\]dx]1^3` !a]cddWgǓojsiregisterh)j3i@j[qklXgxV=lEC- $9c\ EBq8rc+(?bnoev`^@" %ݳ|NDu7wL}7?LzuܢآH.̮X*?wOʑ̈́IQlQЄ9.sX zhf~.3焣($ɲ%BN+ : )mMB6:sVU&ПY$Ev"$bA AbHZ3$]pCQ8p3"] tδ_k8+%ch8ttuKc.o3o,*Ɖ˴QF-(&| rĩ)?7ަQDbŖ@A"& !bSVo5pUbH&,8>u+t$\ǧ1D eR7lsē鲎 bA\Hz;%V+V.8h|參G`r( yCSSZSzAWR#U%0Qϋ3G[J)o y""2rD 0bkt"$r\HLԩlW `@j*"}LjK߽ qq.w:RIŭbd^SO_M7]j1Tnq@{!wVz BuFцB# ۊP箯ܚ-n'=v鳂v񛡇>r& ҊWۻ'abЛ =W,#G٠R IW w:5A>d-f:̦2vR^@,IԠM"h,0aGQA.*sESWqCBCrMK""P&㪵.Hu?Hlg}dr*FIaS#Uxw; :L!Gwxo8V}X>!-8AEɞ}F8@6J $;Cx* EAV>춘S!5\UZ [arB ieLl8g'9O茥NZ榱|ݒ`JO",iew ~p1߼XDZE"x63a+kpU4{<ز{i0eܷƙe9N 8Hč ]vV~V;p匿M~L 5{&55QMFmH+hJjTǙt j wDsfjwj K8*h I'_E{y% c,;xmhk6l5U%]2.'Z*v8[S̿,ok\-9t42Yy87ٺ"43ÜQ߲: ,Ģ*a ;eU"D \u;1B?j)e]GM4wsƽl62f5҆ܳL] 5NktTG-%'ܵlhn9S?B+Bi<NR9jm$mjp y6BT)jزfg@izۙUւ ?18 Zpsl,mmXifA7k,8'0sku!4]'\O6[9\"|%pivrZW> ODH߼BEp8!iÔ"}e,N iX=yz J,ܩ.\#l:y`rX_w)1:9W jآ5/\i `<-h_w9Ԛ÷y\ \!z,!*^eo2Jv{{ OR_lԨwA!X9*Ec~r ii]˪眳h@lQ(0Zel! |=R/ME|gZgaNޓѡ[pN&o<9ٛ5qA0|GWe:E=ڴ2FzA&J{V0t0)_gڰݔ.gEH5MWt49v.]86*1BzW-4>!?0<8w|dT)+LF3uGh5-"_IŒ=Ӵ<Ԓ1Q^:|q:cUq/qMB;܅CմEX1CxáZ]헻Ӳ x җT,cVe\6UqM?:w{8g2vygﮖ$V+cWFjXk8o k.8+el'>ZhVF$̏62퍶BS,<& &!,Cbtpq4"sĂ4zB`m6ݥ>xEp MBj|E3|u<4hg>DA2Iӣ*16Z`Ž0Z~ԛsdI-!b!j|M["F@570^\e0GBvX-#N.u@F7nL4xf6zvRӫďXa. f90 Җ Xipє}CJsXsm#0pzx j`=_ǻxm1M8t-c"#+wuTQqӹynBʳ}" hql#73<4E2gQ3=͖k}| g9βj(ȉ& g١-T'XKlOI*J:o5T8Ϻ<={∦#ȶ?e's /ߞi{$"G̀NF=5x 0:ۭWLc+7jٍf&[[(A> ǪNa zMc8MBa;A({-IL L*2?XYAűZM=n>|-.Y#4e5HYL^i0zBf> ߻F>xz=R #-Ƒ (9D .a+w V#ZgO4-kҞi[#Msx HSm]{J{qbܴlXe1jg~+bA1T  \LI6C-YRrAM Y8=Q^)Ĵ_@ eK REl]Y{E+^!OJ?\!,/:\Os^~J|ob B($Aw}!oH٣S̤eS,ot`҇Ɗ1j!z_ 6sHA sGKV.p{CF4&FYxB8$&χN"> ዃ$? zk T Le+Kŕ'2ur1|x^/&| )X..&+aS<9gj <3:-['V<5$dj2L:_Jr|%U|dVC O~lp ZW^YV8:P^9Z 12c!h $&B +KC.>ԇ?_$Kʼn r[4եOR JW~b3E&a_xEmSnMuo. Z`T씪|2TOuZ-hbCDd. !i9ɧG]U IZ:`P[5ӡtQw*wy"ca>zk<" 'CEUR! sek5{~\&/zO{{c]Ӷ@"Ca0ĸeʴ@f4W:noGC5e0\wǟBlp߀_sd "4Qw61SsBx;pR [FX ˗:*TYEjU*,[}vNF|NQPQ,$;:ﯿNyN6Iq WIJT_.:f0csm"7TZOqJVwW/q62(Y jt^8T+eWD${WH&R\_^o,]˺F ּ4]c\L€4Q{E2fjYI UV FT/Y#m_ {+NC7G~ʫL~ QڒrV,'::کNrj^?J3W77EAnYfŲk Q~_VEq2ڑ6PUuhQˠ .s}ksL󟍊yD-\FďV0QgC *7װWP FE/~m2Vma:Ĝ"A.gdDrBZ\Rą5-xWhlA]/ks{H6L%u $+˶djaekar KY}J(mRQ,0IWY^mXzX0_HhL2]Q'g꯯¯VH?9Tq.vbecdJaP>U^D>~>^ze?`hvWUɎ6T0P6{-m'&Egc2oMR20>ȻN :{QQR 9mmx cWOhY01]M42Kwf ŮӿYn:35C5yLG'>m_!$ykM ^k|*$쇀I> Taz&1R#*Y|~| >(~̶=;~ۑD\UjUOdI m nF[Qk%Qe509S'ꎑ 3Ss;ɟnx{JF5U+"tC#C# ]#]CKCK+CS+#j6O ެ+Ͽ9__ e;xMhIIG3Ddt%2n3f~tKǪQ]Q,eaɹ[ð,aE,{Ad$`v7?^U1n5`;%`4Q؛H%#'ezԆ~}a_6+xXm>5]93` vxcWӎqG+!v@0F8/C?2PmFgu=UGƃp^T*AZdcˮDCe^F'r6DήPWՍ-aS#W yg}ѴW1r ;4t XV';6KVGf̆jO׳E^<͎M/3F|;*\;!WKT[.uYNEpQ؂FNSM%[КWԤg#BXnz##JQV[OceYxԗpG> YxЪWC1`R 9k =$.\Gݨsy|-R X1-ҬnKGLx @,0v|W{ƵOنBK=G˵ ݇S19=]$n[\,g#*[e-1ԁ@_Yyol#ksjjkˀZ m8h_ _f`<A(&g!琣y]PϱCBC}biNJ F\rY+,VXZf.28?TdvƬמvt9RFQ 䆩-Tx0FUU+"tScK#3]]#c +S3+D3RsSt|"oqjnfb^~^en~i"  bxV&)QxuVML\UΫ2ZKc a@P̔i`,  4jt7wW_}KZ z44&jКTc\htgbsa(Lg1yswmW.%IX@GI|p0x,I\b2Vhdx.CI_K%]}vՅգpGmvixD4|\_0.0cs4e<"u!JW5ִ wӽp˾ȤlrZLkco(tLOe|ԶY&|(a1*%#9FLJ8<ZE uCD" {mȆ'UV>ܫ%>hS<W:AN;4smp A co#)ĻkRzx#F6kxGrRL3LCP܊=n 6})YqE5~4tB^ =ܹ ȺvZKg膋#Јtup.Z^؁mZN jµU<+.BL"'67D8_Vamع*1?ıxD.ad_(;mDd!Y|h!{7)1!̰ DrӃXq[[-` 1!BWU꡶c/[/: ܆6͚8bPVi=r!9>H;\U>)/kYi DȖowPh+xMLrfAb=+r .4&ѲН@Ki DՕ+\$||c `{'zzJIڲٖ&6u3|~P)WRJ#f*Jl[z J8zhJp11swY x9e)T+EW1 j窘pYwU#ΐ-Ic94nhL06 oBq^Xȫm_Sˡ1 30'?m >6H^iH/ Ci玐w|W5{R>ภm:pV}Tzr*'kzF'no!ij:3/~3i x͜KsǑ): !+PL<emL{|Q/VVu`BF"YYY|Thg6+6ۭkuYW?JgU6/\ ߟ׃^^d/v!rkk,F~iףQgv-h}8~*y6ڢ,gE용uL]֋\~]XJ/8)Λ@x`h'YQۉI7er>ϾȧӢ^nR?OJAU_xf7XiIrDw͝ˢj+:Зe[SrFR95+yŬ@RcŨuǾWkEVsrk| Y!REBv|m]ht5<>ު;C4w*~qyu]W,_H>}[7lkd%AhzI)6͞e/AyæWZS8>۴Tv]+ 9(ٛnf8zUi lY0;+EKWL:֦vok4+<7Tlhov8 Ѥ~YlfW}1/h+mvk5˛ s"r7ha5̗m%irt, [% |usy7*// 6h;Hy?275W٢>?/sFw^H}Ъ:776@)v q"Zkcn?at\^ѴwVP([8>0{No3 X@׾2h: 1zQueoBOƌ.y8& \|5MПcgǤ .GqY6o/iDdy#DF;s`j$w豍`iˆC(j`ݵ5m!U<|͸)GnxB=6l0JD;CZ`p^AۧQAYz{^9 bE;S7W2֡m n/ a.[@ õ81AR 4XJI2k…o-Ji /2; k9=n)r1X6~^}cp',nU)Eh֥2Mv:q/B4s9!w,"[ث!n"ܿ%)e=]t7Ob7uF7 _?.+u8{m駿'T~ǡo7:h.ɧ `Q*3CVa* .ڪt$_?TN}?䷿KP|r<\t$);pe,Ee `=x<Ƒӆ+ ?">-r $ e}fR.>^9jiע^Kh9׌AŒĭ̛}CZ=E&L+뙑juſW[(.vZfb(Œ"s"5QGЗQ >W@OھƂ{%́2.jKؒ qxY+QUhSS hMP˭!ϓl2k/~+-J9nv~tl^'"Visr9s;bFi3ޜLNG,S3<.L+pT!i/UwU4ɉc^} ʳk@G18h#߽K:Bه(̒~Q̳`z!@Ty4fYW |7+]׉zI!Z-b9:V[ C_g؀[!~36VP|R0H@6= $#oΐ}6wՆ!7j4s)06! lVO G0w@y[̤y!֓f12jN1ʙ4$ᱸj˕Υwnyx y'|Ŵ\Գ+1v[@5ZG_iwpLowH%,6270A[V+e3x(UN5mѽ8\+nǾc1,@ȒT"h^W{4n^!GxU5$&$4 &q:8ᢃObM޷ѱVT&$h<)Ὂ7 B(WCx6Ị XȸŃGS$.Dzdx'?sz,PO+ȗ(Pi|g.hI?v(9n1||yWy;Z_ ɠ#hlI}Җ01ZbZ2Z!j0lF ǏnAHВ~u7߻* ~$cHǛQ}$ c BfKq089(8Mj `9XYJ~;b2NY'[.uZʲB5F"v@IbSgOm"|>N3 r0P1AS@ZQF uk42 tZh$슭$m֖ y@Se1ޏM9N a/k8n+:.^I 8ҴNwBSb/s[7*Ivρ-ƙPEroH$bRTD7V>Dj=k/:p_0ux0&((9Ϧ Baد ]ξ"~ >9Uz¤sMr9 jc d OXGrvI~qDw`md2ZPDMC"80Q0O(Wߖ\q N5>TE23tFG1Ą!~sGr:Rz0*4Qo{J}zJw քXo~t ;\)FzU2E Hݢc׌VN^򷵃KyC?t^qb0V@!lOl ߡT'QXH_`}S[LLUԩL?qn+P1}5*)2{Ӽ*}bQ K2h" Jc֝o[#ܡ[w䮺MEku)]7= YL&03y˹ʼװϸo#aQ1Pe˨TEi6< 8"'Xbkws}Xt!K؂+{rJua T7( GIn}[?!WAhUeգ[㭟g'vO͊J8:R暶 {٣&}~KlSٶުc;Ī>|XjlǗi0NX\+uj*LLiAyfi꜔]O) 'XC/EȰKLWcٴ0i^{f(d<Ĕd"0`V RtMfr r#@&br c!%J͵lVϪ FN]狈YȮS!3mZQt^ǻlnz@H#0$<~P/\Q;/Q/Q*Kփ-eM?7KqUh>E~B3ڧ/NF"pAqgD!Bxj#.6+=F0t]n6gA ZGv oH^q_I;KiŜ׉ul3_weX"0LFR4hΛxW#"؆UVm NVJMvҲY~^-{R':h3S#أXx`31l#qm^u C)ӨS`If$?iUwT_nDS:$fw PFM RñS#mp$4cMPۣw]L u}<^Fvr F̂"]qRd} nK*J 1?8%಩' L5P^U]ƞ-Ac<0P05.*fU9C#>G\qC=nɦAaT/71ySaޝgE"7Pbð+,|Ѽ"nt@S27G5AgnWZm/;peW<Ľp@BDu!3~wݽPu/9܇y٨TE/AR\hrA +&:̮rFSuhrBi챭*Mi~ɩv=&^>6w*JV솽-!q \R{3ùdJvc̥&e0Y?1t` 7ԲxRlLrX JЛeFUlk_mdcæz^TMDUazpB#Ju6g0Ip7 'ŸRRn#'\w7"td5[=cHa8T36x !4kYhW`+{skE_Y'HE^`l|e-<#+κSM||#aqB4M++ÒNZ}t'e &|s˞iR 6M;i&ޡ)+IR4PJ-X}B#eQ׬AJ%[ߒm;Jؗ5Ѯ y;C0#M"[_$c #6?AoH(XbMxRP nxq{EL%ibqv/x ٴsHFČ}TA sx__J<ҿFqWwU$#϶[X{LgB?nD!pWv;*sj Pw$J=*S"S*zMi-LaP! I(fĆ2q9 -sMQ(?"dhCi]&ssPIzMױ6Z;Gޓ{Kg=]1ۻY`;NH4l [-xc:eE׿#4DCL)mݧ5_ɉri}QqMNwNNO_N,NIE7|>\uRkv;szOxHuU.鍾`<[imp9|kƊsNmPSTr,J4wC"a.պpKz~AWS ?U2_H#}zx9%㝉0Ͼށ]PvJ>w'cSA0 ξ*sc- "̙3w\I-şP'+9[.Õp} l1#g\x賑ʮr| i$q\ [VW|}D7f8>@Fy{)*#6"sЇyNqP,yPU%W.֟5>X x;x۸qf 6 f8&(x+(iLhfdP3C7hb~n|x۸qf G41212x۸q 擯Iɩ0fu0 U1q x& Ύ! a4dbĜ=%%1vs}]sx}Y{p\Yۊ-Үei-i%ْ-˫ÒX=,; 9{t{G30Lh폁 Sd1 (Y:P iiaI i;S-wιUB9};v9=6Ό SCCcCGPbd,149Fζtv-pkF򬩙b^3kgSTi;G]^[ŢM\ٌ̳5zw S2L|V'ΥuD)W4W6Cb X54qm9 ~!mJ[ 5j@l*7ܓ!lQZun~bfϋn~Ω)8[im%[6 jP.X ,ݥUenxM$>^Unx)D4εVґ?k&1-$[?G'ѫp{ߧ 0 dcdw-oh2 YJγ;,@F'ra^ pSx kȭ8Y<>$O@ [_:HkJ~1~\yaogQo o'pU)ǘ˳V6D[YU‰gz2N\/!kVʚ-/T&'CΖՋ^ cYIz篝 vҏGpcRpĀgQ,cC䪓Z֮|GEu02'y#^܃r/lI'ߖCu G)[ wNmQd%K?:0sey<\E=̙u#>edpJ "]W#=5 C'D#8 | #%/v(fQ]w/!ᛗn`\). 9r>ҍh墑Cn;tb%$}KïgPp(J{x` FుF1d2yxD,{VvQAl[ŠB5)< ?0s `hC1wgEDEG^Z d1ѕ~aZγ 9"L|ԣa3PC!h[xDk48^ܺ(M5Ep82FZ09@WZ.-mChbϓ875rdfm^k}7mcbo4?j[YiY qRdKEvi| ~̸ E0o[d 6z7VBjpt8 }ž>h7IVS"&T);Ew U) QƊ=%ׂ=q62W KNW.E{Z_{/t{3雐k9A#4R̺-%6Tp \uNUwS6|Sf #1iꂙ9:ZX& rUCUzRH}TN-c70 V[Ζ[r&iv~H+= \[bHq,^.ˊ^N˥P@ vXQHe-AT8lN^ Y/&g򊖩`MT˲8|mC-|pQ XBMsb @I@wJeUaS%y<ѓ?[;ښ]VPsA6 g\)*_-Mݟ*GB{)vE!y1%mCޕzF0S:?:R_Fdo :i d)ʉYBVju{I:+0Vʘ*FȮ)ť+p+?GKHͣzq z̈́ŭE0Q٥mYfg̮%MY6]%"`Ef "6qrJrh" Tk+pK٬CݡPˎNuSB@Sqbe81>QV]w/5R)oi4)L.QK~">}q f߃dZ'ι2(d*}+:xhԧ/?i*ξb)}T7I-^JH$/3|`Q:Mvլ}AziEW{H͢V`151δ-CۦKu6oq™R@l+tEK?\*#fzSSX*u c907dU o‡N{2'k_X_- aI@Ib Q]4\Y ޠхsTKxϞ'Pi3Ge=RX eoMw ,'CAපLoc,&S!⋆2Dm)EP@aY,Vөҏ& 8UwWPoǀAf.%/OMJK27D\e Vgү5lme!ܝG.6Eq4NTq&8_XMF SX*# vէV).{8 }߬󂒷&pc5-[+~tP*xf+ѯrjĖ#v&?þpՇGϮCѤiA4غEu)'5~>>p6I9'k]XAw$,LUV'g7{T읙?[imur~Uk7 nrX>64m_Yi;R(?Ӄ"VWQաԉط,i_wW9!\T{mOb{-DOn㻭!m HEFv-Fw\/뉯l+eG@ԼFE4ߕoz&fgYc<߾xxmI~z݃΋h_㝷Q}qE|m:e6ğ T^8{qh C8}sz"mMRm6(Y/5<_Ld=O楚\%[~o.e2O&Z7?|R^~g˗`7&*JLevI/ҫ,!$Q^t[R]6&K]V@?llIwx}t;Z1:AjXmg|lw.RAn}uz}[麓# Twmr2ɷ6"^'b{,mlD-Dh):|ӊ6[/t䭔;0XR2ƀM=y˰o,]>E*eVLv>Nׂ<jreiWt!^Kǚ"TV]'[,`,nxGx=Zli2"yEqnelpLS?ؿf,[" χ*YaN6b.JmCFv, g^k4}!qQw??U!ZܦsL҃noɠ_~gV(][9URv"+׋?WL㯈}j)TDQӎ~",˄?]sjMla)`joխѸᆓqxC<b(ymī*v*'ñJql^g$pg poi'خFF#{=-H6,~ո[XNnZwR]FWN(sVt?9HUJb*R䒒 a'6uSvőMS|E^eAHUrd1qgG)=hBARoDEҨԎU(I>sLA|xVzc@Ӧq.O9Fꆢw@If&`UY~j!K̏9LB6䢡Ԏ4I <}}dra\";rR柄EؖC#A|nǝpӷsog'|7E^8ߍx#58vT"ۇ6WL m.J1ʈfPdPz2g8›8C-$-XW#_smoi8)JTR' rд:T>}NE E ok&B\_ 5u Sp"U1W`pg7ןxYUC\cXOZ )NA=zn8黑)$BU6f ܅'*DOdH= -M~vN&ڽYPv zҍ*N즤X`y!sbѲzW(U 5AlEOZaUNN[C :';!~**&Qހj =z׫=g%}oPew"W8zI*4LjR: >&Ƞ~|_PB0˿L37-ϞE0z@c;R:-Q=GuOhO`lQ@l-!(]Ђ V-cb y1A(a$]5*> CghL !*01OM,N ohtފPˀDOQ x0"ԟWzY %NfA`x8X[45FcZs&y: /gtE=Vs^lӳ{qO )KE颜+i~V‹cqu«^z簾A֓0JH)*+(bRpCE@$«=bАWTMI !ӊk::!d3f[tFyg2+3C`4;r=3, kF%O-:bNF41v=weM%9Y[_Ɓx*sr3ԗP%)\o'X~Vqiy- Jj Ծ=N*ӊ&D^xH tfIگYDنKl9< -KA3fjƑM.t5 9],FO58RsvnԯJA9ۉ1T,s zyccNDؑЮSx,'IX8*E@(5;GI?™_Uf!cLOh! 9 qg+YTdguX )R7;HDӘl8{N!x0#"3TQF*{ӕV+c.=' fTw>=Xkt^"FY 6Ǻn^%H'$--;=ݟ^ ѸB&אɾ@92kEbg=@X:b܌Kg[0 r]:Z. $.@<u@)x ٗ~H2Vxش0ӛ8iƬ;䒸g-!ѐvv+R.={B,9AB;d6 Ƈv8ɵ$o KX +'2Q|K nIG-q"ut6 NF3kA%ա5s2_۾aE!t95cߝ{FR#<WI ua` &rS'—1̴.=z s> W1"ǫN )d٦j ey~[戍g5 s f1(&75D3yc7^ƃ ϙo0r:,p &ƈmUL *1 ߆y54WБHiOGv?>=DgBbm!iF' vn,qק4x@z/34q-Z`|V#-yУn΢`fa-YٮIIK17 &k}cy_eE Xpq ezs󂋇@ɉJ?j4oXr֞n*/C k!Eˏ5&P@?`ɡݠNR27 AN:ƨ#ʸ `UٶiMk/qmIm¹% 9T%#y8EZ W6쬁9^(Pqʀө܄AlLNi-K9Qޞk>?Ȍ6|ۂPFB,Lʫ\MK)&ԍ]8//mx#aIbR3Ͱ>~AoN'xbzym* ˍBZq x`I8e "crH)eK89hɤd"{SCTQ5) CнNtx(`3辥ƚ6#JBsQNd㜡$T   p2ul"uL[l[Ba1q"2\ Q^86 sW3_֓B`+t m5A2K+UPw(>^!Z"%ؿ NqIH#j0Ve:[*֮]$@ĔM#Y p{Em!S6G&3Yu\F՜nbs[:2*u/T 탲}viIݛr7|E`WXѪ}oQiۆq n q~N.&udkԫٲi̼:5Nu\Ԛ=M}+Bdݒeg W 8d^m^kQ=.jrXǡi:5IT|SLŒCuX|VphΙvAi9u*Os& f l_Q* Sbd}YJi㸉S)"nӐcܽ, NTr_boc{mR zh%@1?4:4`{Rp~#Fd#NHO ,>&-kn &-Ұ"y^x-ם7 U:) &Uަ.ͪ\pa*?>yNt(!Jzײ=}ڭb6 sW?mN@[;tsU`j#裒Lp XYN@ -/Bh7..4KsNgةJ 976nkPAA:shbpVDJ z! 7(9xV>F4f$3hF]ձ-򞽆tPϱa0''g6!hr-Gw/C^9l :8楱81EWx1sa=bhEX$݃%b M(@8kQ"Q ; 4#VN-z`oPĆEmAs6v܏ y-/RbP pRm5U`wHzuÿ6Pt}a@@QL_!rE$mߑ'%"MaT^M52:8]Ab:O#WE{)&%m$tPA ?3:%g둴j0f6- [ԥG}[[F+:6~H͆ llP/\5]~F#3ϤAfc|I&؇#oEj5pS0?287"II0C0I'3㓐z\Hi#m@@b} #EtZ0QNgo1H~ʿՙݩ]B.Rqx~8Ml|#9|ie" fЙ.4 9:#8^Z6cvĠjz2YrX#$`a?|sLƤ_= fgG:\>-<܂Shp4O5 ,jkzNAv$~4|9+[g'* :@6&[nHĚwu}!rznCq{ω4QVV tq!řinEK}_T-tq:FUnFZFI^\H2 {bߛlG]?|V6۲X"ON$ìɪndr'jTiɆ2+-$\Hg~ױy0)hёA=Mpn-㞆1?SL+catA@Ѭ=[lD M|0 ++' sپA~n¦]' )ڔ!+ Ť=Rs Qf7V\ Qf7C%pZTksC\%tJ l!a%h-M+%)Dfb =-Phc)K&qeOBWFl kgD k\PR-PH;<͂B\I];iX+0zBC9j\_G %1R"UOb', WjcU2ҡOI $K7*[TOF&&֍LQYw9hrחա P>I]YciXBණ .)4]:M[`ESL> קJITf<$oArI"d›F Wj@t)};!':?qCI'o$1kIAТXow|ی z=} w>Y^fj˂y)Ό[Ei[Y{.HvNmoIFRZ9@3&w?͟z7>;=_b1C'fVfT_qi!Yw2 Eĭ6ΫGc*V;i5RpU:_EW'sɲY9'`0,0"! db]x' `vxmfXC2egϻ %u;F[1-ﱻ֦+itvDy#f%Üw΂Cf#s00+1$ɓ͋k~xqڭu=^A9.l}pk Xh'+2]󧍚G*1-Jh MM> b522kguEo?Aj )Cx_qwc7Ԗ4j݁QͯvT5&z(V1PԂ y!t8o$ECtIνo QUnВ8uɶ+s-`Z3Ņptn284Y,(2,A)A]\D&PVB5Ɋ}Ze=j:,87#@RJY R܆ݞJUgZk_O/*Sx:R~Yabb34c "B^6V=ednϋiPW3"A ;B,Ǣ4  h3g9(T0뜌°5kHk []eYhDܦWFcP)t.b:b$ !iO8)_ j y!d`A|Xcن?Z+A\;Bi#AbU"lR?@NaJI6ۛ eܡ_)>-5aK9M#Zbj3F@'~e) -npb+{;U[xxj5Daz /PM7? ]c:8J\ᱥNHRw 7@@VH[8G>n -B n*yҕ3E 0kkY{ڏ!@Y&mX{rm/c5,K0]Fnp؞#>j7@űT-Xys $,9 m w@{b^XPW$4@J(MhAPt@?uZ7Skf5بkL oxA>nhd8rr1q.] w-Qc#E` ?@_:x.)۩%G4 ^4t9*SA2[{ަuΏ!4(Z=Is7n}be]I͕cz$*kLڅ$i7?If Tz<[넭^*3BMXTr%dH@Aîٿ R+o| ۤV%V֙uwwaVWrV~88蚚¦݊6Zi2- ֌na]1.`ը4'\YB7hx*G\2 qs0B,= ʌD t|N[ XR|oF6`ZrMy5& h6dScDy+M(ē>YNٸD1p%5)(@ObO&~NE&,cU˨ ?u%0*ͅo!'18wd*чɬBas$k5ޜ&7G_*GIC 3h/jk0s~sd8l]Q$6I:'KS3$%}SaUD%P-rS-XBl}N] ]Dôq>3TV؛6O^L]c {Np9&c@kYbZU1Bbgc=e1PHE;zj@tBK›fch /A6M ]lFLtQ%&\d(GP2V||\Dy]uǀnƌVe g+q*|:tmTzS9r7LjW:p0/dsPLhC/*c-LJd;cE7/DІ at=/[ذ$=sJrI8^(b!ȳ:fys*I!/ .yXE+4v4HFWƿ饧$W3Xozsk"/>RAEy36zF~)*mYKbp P+(ZtL*r ]OڳԷ``uy.:)҉Kc>hAr)bD7d-?aWP1ǎIN|S(^೏d uSVZ3G\hSVatim^}뵄>u17;5mM@*gURޟrsy|uA@ Q*ZZXwjF ?>̋_[O#ݶB ˶?sAҙʻ= gOoF{=2}q{+Tn`@vZ*T93@6S.DhB)1R9g&Lu:_sPGϳ?7 0 9xX{LTWϽy3ZĪuQDc03(.[EQZhk{}4u֦f7inm4fwfxd|w;^~9Ϝu\&+&:*/8oQ.܎H #:+0**GsϒtkMCا'0&²D89k4DNZdQX])* wrB:G?z)z(#;. bRĐϔ@C]9ZeQ{ZmQG*K<9-ʒi3! ՖdNWqZh}%մNGQiPjz"ts$w4D"䵔mhRJ&g 73x8=,MARJi^,= :'e4Eܵ) Hw2QSF-E ;Ț6 pyRV 3Z+(`ތ3|L&~G MbEQ )H!1kgdBC$A3,zhS Ÿ9%&f|2˅ea+і0Q8d,b%Jy8& "@Ei{dZcv|ƨe=5V5So*55QuN[ڋ8nPV) Ƭ° &^VC9aϮyq!p# B1nNgX ]s *F.ҧFun$rK|^,i`HaӤm2#xUS!t Zyv܋XTZW_:Qc5.'Vw̗ \w ai|Qv d]l.V83Xq<5X6{] M&#K!F+G/Y;u*d]凜~95WTm .hƆF.~i>[ֱ-&2Y{}lwᙢ.qYq>{gv riJF浀QW,`dGxo\劘nILur^Ì"J}b?H *gtQw񫂰K*T1%[`W(Ƞbd^U! Yi%iL`wWt1,5XiI*Mex/a$,3! P9^U3Y**ofYB=\dT^Š] "9:B0T.&`WK>8Ov W|8dhDG-1ؒ~XXӜps v8sp.2ʐe¯ۍ :Rp,qǦgM-0P l88\$NjOsO 9[uBU 5nx*׬Eצ #vSiəp]S-|UThЋ1a'1^q3ZQ,߾`jSsepƵ:Į-bDt}xWD+eT4sݼ$,c/7]/k p@apc`T+WF` ?I( h3ڈuAnH` ލNѿgƻ0$ٕ:ߙs|yhQoз|>Lg1N/YoU;maI3.<&"+ ŚhCAek7KvSa[ 6O5cS{V2@n:4ZASvV[͕*ev [i4Htj9I2y GؠZՃotXZ્ZKxpF\a&C%YP(JʹF0F8 PFv4^]ߘ][ TiDVpT7;IagCcCVFVX): mJH*Ar&Z Y0~e p?wBµo[>#H / d++z0m|xoㇽ]h/, aZiKE!X9.˹N' xaf?GExDzsj8 Ol~$"Ε#DlC%BPey=n=N|ҽ0NOٕ3^]Avfל#d=]00ƠDbԳG4V1bW{oI.H=nawz {f?ӀHF)ÏL {1`aa*<j8`pG{{C{!I QdB5{7бo.3L` 1K!u48?,LN 7 )#,OX*΀e1[@E/.K؝==qh,7D` ¿cyD{\h?7AAg +D YztIiph"؎%)0j@0D1u"6( _<ڛ+_?@uH8ˁ%THM> yt$Kd*Ͻ 8 mSxOG`SI)K$r/ky`Q!t6WqRKQ%3uA,bE zfQ p oePw/o's6TyLJ޹{:fC 3_C _8_oΗ"}ޅ"-^Jb!#CF&ȉKѭK%~9f\.vy9,_^^ ΧdoBo.OfHwj*.ݿ:I6ͶkjsnN[u3'i9xUVkPUiSd*> U`| WԀ`t4( P4ꑇ0Ӕ6M:2NfZӚ;цIgL>&g}{[k܌$Mrx=^_L'x}BWˊ}\>/|ƕ@Cwco44Uz3TTߤWy^!#a`zGͷ940BD y]ա=4TNNGNA6̵ 1՜1DLgQ'D ̧'8NQ'4.W ݂`'g:8NwB/H0i41"!j>K

6) lɏ6!T4MWG cyC,n]wC>%)j%~Ȓ&" , -y"WqPNT0.8ʫ D!i_8xp7V}DՠsC8UT_Y-i“b/dt)"AJI%(l%j@':4J[O"-m"+}YVͬ^Nd~_V |[h(:,ߌ*L `@HA^gb*j|:pT2 #hC`KU XVqcDZKP^VaUkK1}-b%u?un_=[!RLNt IH6FW lKv̶ /#N"iX5ą,g$ؐNuLj)=,fcsyjP 8?ELPS=ىP1/1+Ęb^FhvA-7x d%=p PD94Hg"<{(:TKF`I%\}cx$KCIs!|u``:A~; 1:컸KE:R jG^ډ.mGl|t <}gbpoc=9=]'#vL;CQيƫZh{|$ǚGJh:lC?FSb4qe\w%Ʀ@fco+pKuFT؃9;{V]یZ.* ]ۉČ3mOaT,֊`&{"LqoYslSTh$l 0 vDr"Nwk` ы|?,}{9ybشCحFvk tM^Z2odzm ^[9< Iw;;>,yn*w̬n: 3P5jݟD@Otj\m~+]{^VY ~ȒxW[l֜upbTJplŊk溳`0f#uZItK9!2,ՎuE;0Q`wMDWx#]ǿH\NK0f% '7E^J&w[h*{.1qˣdb0IfhУUOmYMW:$-![>N > e{ޮ#bu 5`]';&C`sx7Q)50& ŭ+o= >,aq"aϑDMo -qy4ƸXHTԫ=a֕ua֓to!n.u]doe [ ׏w #]_}N6DD#y:,2Nt_9rMOC 6wM'}Ur[ #k[l;ُ48<:4W™untN)"Fyq~")ב9xdNβ =2W1 @撕!D2nrHOIٵ^'HS̐06t(&ASLUx^- c r=b$"LZ-,'jem:ʪV7<$LWD Yo篒D6 x>}/*N 8 iB?m! qFP*>Vٓ>1ʢ1@ \ /T1҈0đVB  GpUVrWV-ų*{/p1\_;3^R׆ ύkt2̞R -')Ѱo)[zMWdfwgO%/_Z R8q IsW-nOOTDc:5̙AP|b =9m8(9f 3;3`ZcsB3; sx>[x/ oypq3tX*^'__: Wy4Շ^܈,t_t% Ql[fb4I-ƚ5ċS.gLӥ=,W&K/Nf0%_ F,io釹SQk]WjB#.&'fhV^ql_Gustѐq"ӓ9# 0EXTnL܀\Ěgejf2^JRAV~80lkfٶbULG>3isI2!EG@db˴)aYwN0b)6%DDZ2[hE[޳c7 kyx3RvRE1p pK(MmlxkTC~↹O)4ތM_D|։Y!:¡ƴ5eLs93{R5f7ǫju3s!&DndN{KRLVxUWyPU]\ #;ps|wW\#C][QYRZZ|iR;b TWP-Z$LS¥U\*yC(/0DU h`ɣT34XxdˠLEcoS.š t~HPmna –ñp_L 8G (iKφw ;ekI1!f3ȥ7rDèQUn6FwF㸯d2{M}L, .nsKǢ 5`z4`'gSCXrTdfT5vŪظ̊8&&)i֎YOP~ B7 Bo4:c% C$(U),&L*DL l4MCݦ t6\v=Cai?uӅS͈ jn,ex/ UQdX:M4$ 4F6`4^dljm;~)J2|#RjR{td^h -)Lo,N- 7.p TY[¶La鮓lӦ7  q hBW/<&7|r4Ō/BO僎J.HJP,d',$?pQ)L!>x{Pd~/Ps$CF T2V'$NN{b$j>L(ӕ0#z"Κ93˙ Rif{:}fU43E]eE~Yɔ@9Y6mĸ7K1)K`r1bڛ6+gP,7+ͬ4@sv2G~v@x_àyfb!ײg^N#۽{B;sWAMn)~uwKk&Wy[z 2{}=&twxJsyg$ãUb,20pQAOszki[kk>Ѣ@ƵL(vOTM9Dڼ#4<2wwZ(UR=Z>xsum^+\EMܒþR ӝ˴fk1=tp0$O?320tY~"y֣t:Pm)oRI 3|%+ia#[e!L-~ّ4fΟ3IdnM3`í xn,c:MLN1\B=䫇ЈǡkРimS3k`MkvW h4dW #E>3;=I&ءҽ=PNC| 7{tUX7.@?nl6q!\.DyW~ FMS` ́\^Bh<=\F\MUן]w1Wz]ԅ0uN+?T͎$Ci̖^!қg1H#si2b.7@9nK͖<8Gq:z4r`[ȸ:6jnƷ8Yb8P=[G|HX@Djܑ!YV}G7`!g٤]y> <>X 3M c̶tb ҙe12f664/LcE'S0Mr(WO;%fH쿝0q|gtJB=:$@Etya[he {/i% w(de]åC~9W(sPĩ}nuep@Rؔ,k2Tq1X6mllMV~XJm1Myϟ:k}!ĐUeerqfaX+6zAv :34rP0S5e%94Qȫfa˷2̒QYP k04o, kƃdm(q7jAN^"ڊQU]nw9I~t1Mr“;BrKPP'i&Wt*35>&ؙH'; nfLYrh>ACOj*YGgYKNul|(~>,j'G92U7kgAnųDݖe^(:"[,a QT  *EŴRpB~Fł Q54fQR3qK]  "7g!ڋ2/KU4e3UGJq6=LS1dZM(dWh:FwUE{4O&&.-!, wYY?"k A[EʽZ~`c, eV&2"2{!4 )f:GH %тp"&C J#A "OW戲ftRwׇv]bxX ۨ?%jj*!i:bDO6ا 5^d{ ~HhkZq/ЦTvPReE(<>I">p`5A9u,m*#Mu4{h7A--;ô*\@Rڲ` 7-m``njuUy1'SFrSFiَVUv~j5 r41GH4|.E"PF|̔E Mx}x,8@r2Q;:דZwn|xFmJ{]|"˻1Msƺ? ": =ͻ=ӯ3pvu 흅SiF"*ONOcDN[#ijDYN6u W\9ӿ*92fm* 3;: &r0'oC&Nd$^ KQ3I8ZMh H Aqύ$0j쀄l~6&9gޠ| 9ypED2"lxtN?LŠ(Q[u!n)$ st3KIS_|^Hœˑb= /}˫g#/aVN)|<gt>wZd3<Oi_wN`\(K;x왤 |>h4|யxrT0e3]AwxeMlTUsSZHcRlH5%fx>.XZR`mSh5C[Ǵ]i1q!@v(ڷby{yk|xe2y- ӽe m x͝ݒq*ŰH7]| 0bhB ,,]ǐf-o?3ϩ`AEOȓ'O??NwiGe=m^ܽs4ox6m׋Entu*]-|j5VrQ[k^ʈX@zhToqUl֋z|ԻE5+ը~SU(vQun*k;KmՐ -0E s4צnMUO&ųr4c-r{Cջrvy۟`Yd' o~~_bZ~xz[lzQMmm&z^VʢbGI=jw >FlWŪ\V%mvX'#,eL8VhWv)EQw.W˶,we,w [7KݺhQ3֣J Oڑ z-{z: Z@Tr{*vڟ\BhNLM51iI"M`%c{̉Mx.NJoi+ivvzEQn&,P K$՛AvN)@Qwli RwWuld RoeL/WW{^rӦAVzˮvV8ȏzqy+ `Y6mkً]_?m$G3 O5 gjj x?-צQ%sŤ1T;ixC)bӇDgY̯kQm=٤y4ŋrVoӋGOwNh,"Z?-k);h/8cvAsRZM0s^m[kJw0e@B\OP&6\Jl`- L/;p&ƻj:q"ˤ4;MغU琅>i&E3ܜA{nn?ClLí d*֌֝&Dm[M1{ٻz75Z/l\gWtڍ%e 0#lҝG3#8H+)-vWʑ# H^ˍY7TfY.7,h47a410ĉvЬY*ҹ80D܏)ݲ?_>Z/i3.Vz)Hp5l=Y=6p5T;Y pXc|3Ax?8FTj߯ҳY[ y;z֙z.0 /+n*0I1tjJuq lDţ11r7*V*.L,BuGVMIuG|B׻6'*l AQUe9)JcȮȦ>V!]9>HF+ZRzi}g %O3f Af>B(bv `LU$2WRFzdT!7bQ?EJ(Y:1&KA bYj.'Oǚv # 0k%)7Kn0`޸Ct=6?f}];dxRpLKfnҰ;syd#IF]͠z RFl9 Yv=nm-0pKߧ x.7/?{0:a /A#3t.xv-\<[UõO >`ӽ'S3d^vDH`v5|֏"ǴS zM591^chvδXF3w,Ĥ/ĐS~ R0/vZ8r[Z`xĒlsM PmAhe Ʌ(آ\lli΋wܦg?辏^/0%Eo| 80]/DJutTn4: 0]x.1ug6ɧ aڝߋm!r[K<9Q/Ŵ b4Y{g;0e@XIs+%N /H4ZȂX=3Ϳ{O 4i0'NDByz_zCZi9M&/E  .=|c1-y_Hw3Czo0-/AgV8U'ʹ kiA󆇆8މ4Qy^답|8;<)2c3!vG%uy'ܮ#u8 kTb8?0r9|ei(Kl~mNm$Wzè (`i]#N>6|\[ͬMV (kQu,'&JNhb\果[&K*-JG<7FANg 乜{C pHNAmO,$9(|kë~xziob6Mz$+<KA|&nˣtK;Oi bwq9D=*|ZmXpM$w"H`=n.u^M,m_c/zTyd~GVrLxD$-PRvf2|$L$1ќhI cSaP`tOȜe!仍D߁CR\x1'U]x#N.e+6=ͧK=9o)!$;,*(Vd%NODW%Ys`7+\`&E?|E?R3NzIyʫ<D\]:v'A'|㝹_MBj#Cj%!9JB򑱠% )W] R4T(֓ T?x!+tZ>OJX<߫o0*ғ1Q7Nv`s. a8=6E̅LUb (u/N#Qo*)$潫M/,a HEM'`kXD3BI\(Q0K`.3$p8-1/MN_fQőx"EN\~m킳#:b({`J% (nDEtYN .|%t%jqo;eU|ɷ,/L+W*(\GC/|G q&C& :"OF͆``ckmYǨbc a. z-GݲL-'ObW -#-n ?1-:tBI[שY)ϽSQZ.%R={~ЌzE.7VK" '%5#[ϫ"yeWˎǫKKZ2SE }ߎqb,.ֈR&{m<})s a\8D!br`b-vڛۈ`-12!HƗ4I@t+\XmMh<JY c[H׺I-^2=+MUg/{بMNR^1?7)ai}2r(ZP.1F3ustM%yLS&J>ȧ0O%W)zxuҧ^h1s mb7cZarVu7PN>)萼m;TPLB"|nwK݂ ACmF*B@"EDTĬHJb@k@(9O8ek)ѨFPqjTEB~H.5~u0ߵrhŪC kȃ FϺr7t[n%ӌq\IK͔HTy;]Zf1%'g2qR"'QT Vp>qr)YLq+ʏYJϱTiguEM X?Atda]9OHT]*zmZVMm7e=8++@8)HABKjlAoU,lFdvA ꦶ/U 7< TiMX<@3`+ Np%yR a]L$HŐzyCD7tBkgq7q<.X(ޕv ġvO!d>P{E<~&nJQ2x0ᗄN'TS,w?)wJjKEA`K㤵>rw E? 6M3:m$o{. ǣc.^gpN^ M7VN |8oS4;O^sY4l |> Y㼷R2tp{TlIL| e%'r}aCeHO:{=4)[ N U 3z}^meoRu;;L8VV2g~K˞"ceutY7&AM\|mx!7[A2XQ-,^bZmZ˰lRcG U6I4R'7q4!'\./ 0:D \f9a۫ w-sW/9 ~xnyL62> VV9uwnnWBoKrFKBv 5IGqC3a>yξG T&zMj vp|ѥol^ |섑3;j\AZb5L=5; \J#Ư*=k2 p{9oc9re%Q{ I>Q{\ "@T9.6J\ib^IC#=7oGi)"m ;}7f%z&́zD I FJiGBcDm.Pv̙vũ3$a24q3}þbHjndR鎓/$e*܎Ґx_Wӿ#z q| DSu)&40s3P?_ 'q7^Y:0kO}[Α_Z&Ϭ:Gz|5Y~:r .{c>榝[倝ūSrqcoqP eX`IVXS,'A@051spm$5IbPbC}kw @}>Ri7Su2+YRGVJnoXEn)+wgVd-[Lt>5 Dw>2~LcmDǻIwP(+(.xΗbB3Gg/-V>ԫ?`u[AK! ڧ!)gvv~g|bT%+CDIh 5܉*j3FEv?=*\&%77V ]rDB1L?fL9k(zZm ÿC, Sprs4*Kc}>VǖM%RG1|;5:B!{ X'kg5&=⟓Kb-8B(‚%h~A:KEY,EỸRDUUy&5ƾY\Swߓ=t`=@ Siዚ\#Uz 1T=x>Y>eq᳊IJ*5D)1ZQCęE-5b=IT(- 3)Z;mcL₩,lݦaS&-sSBif?dp,@ɄV14J%w>̦C0V|ǘU"aԉQ6G6oEe{*R ΠN]K4܊aH]oѝ>}~o.gHTu5g" dj+?p M.8Nw\K@lxB.<$5[bQޚo0DmXRјZ)q@(IKPQhg8<,eJ~$ P5Cj/)峧 _T6!w[ujoDN̢|iϳV⾁SJ\3{Aʀ'0oG/2}M(MAsT( LG}Ҹү - S a%xrq9 Ύ!Eu`n/TcEx  xŜnؑ)ž|`sh${VV$9",nJbMryy߿!ݖI j:uw_fUꪾrS7]jxX__F6m(@b^fW<:8|Y@;9I`1IjUWUźYԳ;u4E\Wzrzvc4Yh~/*apV]7:uQ:zP>~]Ij|^|]^^Vmq|quڪWÛQ՛UܦU=9]}Y88M8BNGN;Xmh?u[͙ۖm]ysUiD⪭|qWeU\v yW+Y6XCz̺lqy֋Eu7":lݬ/z͓V`܎dcEY:bZ{!W8_tZhvSKS5lt ;Hڬ\^%,6f3lMe` k[ir|زyQ Θ"#7 ~wr/~]+8CWP+ t)0h5И:/#coډ30*ʍx>P\U2jZѠ%Vm2n77RYUyCDNy}ULєì njf LA#P҇͠qFܡ˥=3|jQcs.{(ooo(-dma%84M'.-jD%ޕ5<177. Eu ҬBØc(dG'$T[:9dPS " f0{ļ,bc>Z$ܭؔIJinp.M`zsSrn[3y ?]]KnL(%j7h#)*N18vel%V2_sR&MQc`[vm;ytұ$!\p;=cDd[[j<ܼAGݬV~\ܳk :;l<^w]d4t0h+֩Ay TRJ%**.%б%rb#d$}0N cКYp@(9m}Os_- I_l/*Xt{bL8`; 6!9A#xa9=Oy\`ؐxt3?_a$7 fR`ufMB D$@Qfi2k0FA-r,33xxn º[4s{?]@LFqsc{QraxMi"塤vbW=._YxPZurt|pc%5z),x`= T+!KKv‘]r"I68xcwtzBcM$_nݐ#wXCjIE3&F9|t?x ?1JYWy7| ';?z!ylrJ93wO 4'Z<|~$j~k [9=HT6+q;UixW\&$0$|dwD[je6'h8mۤ v 'B{)-^&V`c,L2 #EZ ?#lcW&Z45m7]1> !cf\EƋԌ {)Kxŧi)X-^T_7vd^=YUo<^7/?o_IW LaUu5"/oD ~IF7)_ȧB|V`_|_|ZAf+'[ _T g?>7+?O(66᫋e)s mZ̻TB*8FGQbzm~<EJ^K8>.۾?/2KrR_]US Ra¯ @ijZBHᶹrx}T?~ɨ;F?ju@Y}%7rpЍ(#s'YLV(f闬\$!N`3*J/`0o \o2*=lj0nX{a$|aۏWdca*C(RA_?r4FaS \2Q%) ,u-)@#W(2C8mǸ854Xx<{s7VbP3ui+ b;yDzrή"@J׊L"B,R\| sRp!ڍ0-'.Ӗ7k1 yL>FK#u܈Ex6=sEw˼?$bnVA ƸpCUrC1qgyЪBʟ*c#{4nּ6KuSu"b2/$̸>;|Zu' wuq|[>26R!]_-.:Ry@9hX4/> 9_m/=YpA$rW0*="sB&`/5ñ`٩)rƫս'*j!^kK7&槫%C>X*&I>hr̓kyaa1U1佰(L~2&i~r"tn[L8/Rv|Ę4r":|ͯU_UU np!{,b0qP4>n2 ƍ t2UvHVmvr\4$ >\ >cP_X>櫺'G hPGG}h6mH^F`Աn V @ Blar0V#bwxcn5ƴ~.H8Ž f/`O># ᬼ=40D+ѹ@, <%зzYP#mcT{n9I?l%j8IڋkТΔ%⁕ifv{i5ܶ2e-U>cRN. !f&d@*}60+YOC *ܬ?kw `v%4:ѱ)KO$T>_f1lGoeg2f>Uo(uU(xv|oI9QyVٝLq˂{)^MM@B u"E&|;fcP{bOn?G߈]Epz}%9'zO  ]H܋歼Fl|ZO<#U[r-N?8!'j`X`TgMbPt$#Gjlv?҆|V֘5Nv`!XMDm9rXg@s$Ejee^<<7H !Smf3i{{d|0p0JB֘]-5,$彬,R/'"Wrlih#i{߶P|1@,:ߔȳGj,V4N SddDo~\aPKL<[cu5B^ٳR4p"Q6Ϸ  -}I{3*DX YJ<eoNUV4攦HǜD6Iy/0|U/ed:i`yekZu+)W3q0grx{Gh,"n0˳ńN^*fng_u$̛˫+j&_ʪ#4^WT!`K ҆T4Ϋ [J'(^(s[0[|eICCF*=Ml1}9%]Eqe u^efP%Y1Qg[x+,> :M7dv{ҚvdZzY2i̽oj`:yn=[.3PbŪ"KtS.9]|A,Zo4mz O^ޤoapi<~ڙ u4ɻm sӱJZo U1NxX@8P&N_ X(/.Hǥʱ~qRwy%)*t.Sݥ?˾&=*N^TQ"kˣ/Sc **9.Z i{k<dt;Iŝrh/|7(L$Q^oÉ5lD;!A1юz6UjS$5vOmB4(LaJlAF`6}qګ>_TӢT*H|hrrNP q) tÉdc7MifӐ;$g ?&4]֘qCr呓f.]e iZ* F? 7/_ jX ׺)KP0?vt APFL#Pigw%93ZPv,\Zl*+@2)k~': չY\#F}DkNQMwF +uqzTg*YYDW6zQ~Ae|+\ J1" <%zƁՙt^=E`qGf‡иc E.BgD3͍ޣC85h&{k=AS'5:כ?[ MSP(O?dC*ӎ;!3t63XUo@؅zs@M_2ھ[,kM1/9id4jsL1\6@Qr\G.a=TyBEU%O\?ʚu%]G@9zuM+s(]ѐrCi^$/[*1W.쬒hu ]s`NSvT҇).`rFm= GUcN|}c߷ؑn|HZuV6/̩= $12@+Zـ?!Cz\ ׽L ݂=Ep;yᖠAw_Z^4ael`zlpvo"2y.1!tΙCwu ɪ|'C k aqvIbK`4 J.ric/ hY#*R`*]~fJjP=c 'S,j~lw[p"&ҹ$#e\&,FjWr`E)EhfO}kv|aV~{W!H0ѡS&̓qǹ9'g A*e tޫ@}#=z{H:Io M]"m:LMN=p'ɖu䳪}bG1FFTuÛ;~ \P7H6x5دE\t䲲5aBht?EMcp;SrNGT#ʿP*.qb~*5f ;fNQXIA“RBeTƇ2]eK=~\Zn 4?oDMQӢq%WM;[-@WAdǁ @f˸M4|JPI\ <1nwagahd9#bDdIk82*Z/ڎ#M/1Hݡ6U)sVB7}pF&`l}\A}V(}팜z8!@! VK^/.IDWs^Rǀ ;rўI8(&q]zwjJn7A j@ai N_!kJ'7c[4\ `.j|]:3rJE G#u@m>ٴ .gZf5w{ܫwZ#/( ist10. (%ւ1^uU_]\)W\Ђ-MA륗f=Ĝ|үiJ@EQAL{24z'YWΡNw$dh|Sw՜D{8㠎 ! MN927AA8 g%Ifkґk̝ `Rjf#=gNnŐ԰:O˵s䋜3%RsTJT͓옊՜4Zο.͌&jnBVƯ{2w5sas.>ڏ>§4fyE8K>Ǹd|c}O+H^\t &Y% Œ8<Omp < |̪ۇ`f%?:dVшuy)7ξ/+e/n烠b%Y>y< D6 VxqؼZS 9x[}7ㆯuݤJJs.͊> #xWMG֬xql)EQaDۂ5v4o61A553E&U3E@@ɡpK8`!EBBA.pA߫];t^}Ο<Eй̸eug}ztV^>S#x.wwej]4,d,qZП Fէc;toG|$5o.NOX:MθRf&Y A$^7NF,J=SXpnfl{mzb*4p?ͤ.Vkf^Ⴡ ; xcYe,/zδp5P/&V_ig~e ݖĚ`ƲT$Jjm.$l^83 z$x]fw|cCk&,#B_vtV֥F(G#2JzhSJ%|*î@^ F,me@ JE8RyqXS4EZ}{'>uM|,'F?K84j3֣_\*S'Bқ `ddSd6(j\P7zt[%QS&-k֐fo?'.$)dzbaPoOj:mkWsb򛄯@D#5# 6QE&d3lmqeJf!$L*<~*f=${ 6h|U|cSN2.D_~CK>uWo#,ݨf=zh4=6NzpWT*kG`蛍2<s 1!_р\%c&Z-CPQOXS'0lfmW}__عsWpyjOťd-ہ*(. _`L ˞sDK <'7Z5 LB%OeTk:Vdfޅ\*߰9Gqd,8whձyyvb֗㓫-:֐)Y`9,!u!L14r pi@=O I`^pF}WJ1i2cRP~y5 FЈ;9a3 I_D I epdmKJ L"SN; }m=A@$Ex;*=F@+&$E vW3lDZ9b"}Y6|@npLN`wh̕P~Imhh9=>adz~x4}@Y5[e8DMB/\b@ex2jlF$aIFw eugqQe7@{X 2|m\WZF(G%x [ -ˣ=*Uh]k(KwMP:>O)?>O UOn?]^\~ZΜ;D}<7?و-# }\p rh(Zჳv9=Tzm3\BD6EE.gQxŝbKd_8TƷ|"\-״ڃ[ZNT7,iPơpă|q ZuPQA^SO Z~ړ+0,"m- ]SQՒ7WHZ^Lx %0Wpel>TЂf/2Z=ykz?7MO'{LA(R,.t!k ?s<"gwCā\ŋ>XuViA#T (QWڽu|=s#64{m1{#=0xxFwn}A7x K%'/e17״ !:GR(d*hF3Pf.EJ2@J-qFx}9[luEJ$77\R|EJJ$|j).IqIQJ3Yʢ1 pi'q,G\4p;0~(h .40`)hi({ν3K9 p=y3s7`x {0e%ؙq6:<<10|z`  O^cQOiQ|-s= -B6O nF{0l9lȁFRܴGGF'x+yDDw$L4<+eetLaٶa긵 D27c-Sd}fٸ!h殈i~_|wWpSc",  5l1f ӒM.IP&2ۚ"O,aH 'As!fw?j#-aƉ `)CS²E"{}VjMrd oV2">X\K$Z"E$XL3-?͇P`$m}ox[6K Ao&m2iW wXbx ߛ1Hѽ!=.L'XhYYFƌ)%N?_ :tnhT3cZ+hLe-|3z[8>%.Yǿp[v ' U|S"2$Lfp~i~%Ղi]zqeB8p6REtZ{к\軵RY?X"9yȞr;Ҁ")&|#7aK@$ϐjwq3C*T3i!t- xȿ7|c)erFVxxTW9TÕBE<;`6 }{P gEn$0흸 >EtE%gnk\ f}`Ok3\{"K7&Ga d눌wg2q:JG@ 1 _c<\h}8Յ.xs~X  ?08 l\JQZ%קf"-B& ;/5R 6‰.\<YJN.៷()2 e}8zlF'p:j˿ ~> #m#Rx#0O:+ G7Dg=ZO%v`4F뱳R&][ii[--WaG2|ÖV kb& 0kM[XQy:&);3 #EB-n@̐'}[44+IZ8R-4s~](w%1AG?:Ru?l3ӿpTc"EifHɘ.nQ`aL/k:F{vtPL)\d{͡E+3T'hݪ`A.QÄO=L*ˑ'%dzM&{0L 3 v`3qZRQE5 BڔD+7w9-a3͎5uIӤ~i0r\е|4DPUuG?t4ޜun/K1$RӘWN߄Y>-i㡱HZmIfMЗ8Q dIC` CQcg?ʩa^i?Y˝E*$ڠn h&t= NE Vwmw|KdOAa`X5EXYFv*M&(=oO|ĠuC?W`J1 6m(溮-2'cu iIz*o10,F\'[SBg|Irjo먎l?qh4L.G)׬Yur|$nܾk?y<2bWZ;G{e`{ jJ.O) `I$VIB_)ǾR2/WTr|ޯ7AiA3ت T!8,0nQ#Mǝ0Dc0]:xQKRJTnj bzu9Vr=ver{L# 7kז*0#-LlQn[54klX6ojZb;8CpNۚT1mK;+mȵT7|&QÑ0;p3Fqeu4bTiw Rt>>ob[di f1]1PRzc(]A`tyo^CzyO 1#)A@Rb6y=N] 0Kg,`Dɉ@}#xigBf^nqD5Ģ#C#77 qoyʿ% y@IxSOA( 5!^D RZ,4F%BVB!z0k;fwfofMbHLH4xhwOntfb4M{7϶;6_t MXn 2S0NN34dfrZz1ba49T-M3YqDbCs"H6ZMlQΈ@?-/{hª+!&j{)8&VQm8xv42>vv+_:T]+}ؚ}T~©0k-lBѦl\Qjh.3e5?BQ!N .\di..eWE&]ogRq\ֱ/=:Rό1_‘ʹ*ux]mU" N 3]af7։j*CDfElA\1IUu}sy3+Q'v# ̛ssonSq^̴aR۰.~to'݇I[ŏ׽jz%nm:IV{һnN<)TIUTzBMcC(GJT8jQVJҥod *O:7iҹO^9>$MǓI|ҹs]FʩeJ\KIa=ܻΚO]2UkT mA9 YzJZh Y~*nh;#5UjXT>C/{= J5]iFeW~Nc.]$ϓSO0ݬDru>sQ0ZQP#TNʜI:IlRWwB^)VB?Z" I;,iZCŕ8UT\jV"C^7=% ;M{Q`X \K7nqꟺ-CglXA4STjɸS 1=NڑŻj܎A6ED=j='7xOmd!f}t% "PhW^{CX>yja{+qUϬ@RCM'ǬwLjdWXrX& %c(vEsu(e҅ k.Ku}HϽ`*6?LW,eVo+sQ)ѤrlR zttz˟| 5jɆjs2)G5ag F]6!c) HrpE{sӼir0l~a 2ƱU}BeWkS*bWC*L 8?O܂_ȜM'tl͖Cg^Ll4ko ESX.(},sߔV 4aR:]LyU45jVR!G9G.Qrtޅ@oٵR ERD˕i`mh-*,gC\jF؍k잁NGsWk2ï rW}3&[KX/Kբ`z1\,)f4AWiͪBUU@6pVRJlTW^$;G&3p=J:P'g!=ALַT }3dm~L64SE ;=R+2PuplkLh(b`=׺o6ی9 f}/!BFJ@1 ߁ <^]#@H:5\cGarrKK͠ssXDYx 8}YbdKZn-2;مvCyw 8+N ]b ٹ;eX =ܻ\Q\o7bQ N~6]|$;t5&P5Xvm8Ḳ\Ķ6O\.4% "  v9R"?Z+Ӊ4^` F/MjKfʤ*J#4,+Jw8LT |3쨊 Pv1l(؎`l=9: @p1aDԵL.|iW/B/5\좍UV=h/`I8ݱ |,Sqf anRI#ryUvC|,JN#T;=}tG'&%,)R!~)5w1-L+q֬. =Hw1@oKL "3}MS`Pq²s{PC+Kqun 8 ݃ SɁ5E .Iӌ.dM`T>M jsֵm9k5'A.*R Fu~ʸu`TAErL4덨٪5@ ]XxHGZl۹6=R̽ؾ4[|=kIG 5L;yw-˹ e+ۻ95ڗ'DQ}fk9~ew u.8ozO ]pk(gf*Yx:;X#l `6#`ʽ6DpDHu,, p)^$Ktγ'oDŽ$2.B!?2./`8SeSAGwߨe}05,E=am4Bz0%o0 S%kpfQ(k~č:Xrx Ԯ!2C{׶haM8tuӘH8-]u{-mnU<AQ,PDhA؎xJu;2@!30LԂiJTL#FVZxs}A&!ܘ8jcZI֟7sb\N@'t˧48ރ3&: 璶wU4c0Y{ҁ؏`_x1~or™؀(ESTsxR)f@gF!|{ w߬**xl&*f..48-3ozufic]3\!xsݞz$@;|WJ\_?fq rI5K'#(^Z!M" aLjFG];mmRB=_,xn{ >'*)1qf- ‚%8eZ,v(ݪ]y6~޽U熣x5jCSUUYe #[%yM#{,7  _KûC].4)cZoB,/~3PO&, WЫZ>$\s$YX-Rm? J@mLCUmj{.^rM]cSdoqba*JIitoZZ8oη7Fn)<#fAMEB!J3w As C h"` 'opx\϶[>cP>$ ŧA򁤋d-ss &$QraH`]e]e_<%` ivP풆ДցǽmB 33Ū2;kunmӂrBNK6U#ox!A1uM@ 7{&70r9+wXɮ"3<^Z/nD<ܦi[M.@oP .f%7C[h0xF,0l@:տ^.WZ ` ϛosV7ٹFk?`z (x4 eEx߱x|A>w#DNZDF~񀦐l,:bms G.X 1x[⏰MŘ4y?TmI huC ъa{gU1YbboLMRv030 WPB(cNUtG"Ns\,0M6\8 (dG{%-r!]Ԉ[Ծtb@!Ѷwor9mF+;Ǘ4נ+e^uUPa0Mީ, W0m#|+>2m7m}Z=ZT ֫lOW?#`d փYr :gO"6<5G[M۵L)dYîfX7iֵ?`xE(]K˕NCZ9kH܃?>?r @I`!|Ѧd n@k}.,q|i#5"zf4=N5Wd?źqk&|"oөCt>Rǻ"My>r$+eHIFh&^N$qAEvg{Ve=SuRۦa;}IJ5MBta̐r=t d7I2A\KDz}|$$ }g9K)O ȷJʪN گ79L̆'351LvT Sޑ'q8=m5C!n3}<pl{AE CVZbcrP18û]@#rwp^aQ yGOL8V?H&LC85dl3<džr? (ͥXC^"O͹`XVFD&/AWrn!!KL)CcOdtXX$PWa9ɝD6ds[kXW>cϚ [~1َ5?`3࿹Յ0 ?pRL\Y@;PxE5)\'%ylpȊCf]&aymKnh9;%] dJ'8Ndvym~g:[[*Tc {xd2tS[tr@a"9pl[ GwD$Pév`{-+a FiN?UA;^ܱ{cd{ո"WS{U'pgp$rD67B/}$؆E۱yRq6Vc$^/]s]$SC.]E=i 7\):ncp6KJOEn=;M';Jpmwۄw>y# !W:xq 0%Ckp0b!w#~znv7f#l4:;=s\zPDŽ\7ƻ8|)^\貝K|@< 2zӏS&-򲜝SDz'I6:H‡7 .bW?S*yى$qXC`%v00 CRu\NŦ5[*(&FaH I~c(T{ Ѳv+?*= F&PA(j)0mQ붶l'8wX[(fF7' BN`|(#.%4AyNj dX@ڳ8rWR3菫n>=18cFR8/wvs/WK~c1cNhx/S}AOҏxlȜ7]Kֈ=e 7OSy3'L֛ bD#q srvrSFQߌMө׀(yFDAg+ssQ%C\ԁK tm@_8oU w֬ԐˬY`DzٿE䠓ŝr /YuhB[݊"niucv3wXqJQOxp&6C$:];9/3|:)PWRM:A˜v{kNl6Ì[Axk@z =ص][B&Q FF |T?hY2dE7lWm55hӿtL5TfP 0 & =yq#g~szKvMIahX{[ԯ8wc~ ϟhE\uA 4N4~b]IY}"o'4LIK!=] $(r+İ&F7K%3׎[ޤ+<"—J`Ԇ:$|E B+ o.=,?pTpw*w+# k)HpLnܟ t$Qno D/w4Ad/݃Dn&Xr6}fM^-" $SiK(*0iX4\Cơ!WtJpr1;d=A ' w1P;Ӱm/sLF_ж3s@U 5(zp;`eoRsR#ft c4F,7)dO3go5iJ+e/r2t1nI%J_jp~ ˰/]K އBdJȍ@uFOfN IHﶕ̄5%v+ _ǵ8=?˝ KYLUPXbR&y3H8ю{XoCb?v6oCm&Qd9 yӖlL97Ds9<=X?oѪ΢*0A Cij{4#ۃxsSVڃ@e8p5R>^Ɲ )ʗ-STBE[+|< t67";o?(&uC\YTtߵ.mrJCH^;B2SQa#D7^۶%Xo^l,ĭaj",s0f6f@NaSY lLw"`Ky͊2HDAo;E>ypl -ݏ""7@cEO% ; Gh u.^#[vZ?or ن-4 j..yDdB9aon KtȠMOV{/SCY MܩsJjLKzEi; lg ҉qKVےVR_?owͶx2W2((osH01̣:ŋ8ſK|qz$s$RBf8z(!{xVsG䍛ȼ_("'!rr=Ԋq=4,xw͹cpo\S0~-pY; Z~#Sdt-2+J06 ]v䢘qϰX+A~v"FSej52PʫVTN+SY9%T#gw^qR YfXw "ks~1ţǀϣ\OqRu&^v >k(~{zG45"EDEl {pɚKSqye)H.+45GZY"99Jvf_5V[۰).T^XxoeKƢC-x)ݤ+Q]lJQGā8t=¢T锂x;$7z9L)=W0 #4;9Cz]6H\WɄKVC??6 uбu BPqe8ǒQaSn 0Ko eŤdLo=|f" B> fvEFͳcΌjy #>^6}Dl ~#"DA mEzC`t``DJ쌁}D',BE![3zdب=YkpG?3LuØ\ִ%5&}Ĩǻ,JlCluň!36Y-Ft~vY4i4JOpr :I",K\G\5q{-Za\ފ$/4YkF#^ӎm|QxETZ\`/Unh v*cJi[{+6#;kr❡'l>¤V-/aR)DlR(u|zT9_"~tA'!y ~K ~.sAPJUc)5gbF>;Kp1f/]G_3kA!.QГRֿ)n 뚢(T) lOa̐6b4Z\!f&NՆ&6fo3Qlxxq&T\N^v q''5*WCɜDc9yӠ;7mUY8KUMpl5FFØ(!;6ٞpP)\v6uM̊Oy7c+5fP% -]%+іo'nxUmX " ^jQ ؘ .lU`mvdbi gvJCNMVq\p*5>*4#,Loȴ϶ߋxϊY;DuŁʩ!%a8@BwxUBN-,h׫/{)n3"6%{N-q Sxx}OMʊK.GhهԷpazrHskBu[ÓJr=n=LL%| jMK4e7'{cjR|QKi\ *rw|[# P7 W.ڟ޺(#Qv+ExY<\-*cNp/.Q˝6q=Z[f-㬻8%GK'l1Ǵ;hD7?ԃ~IdH:vrvG[kp-{bry湡PJ%T(^pTMD:>t9#x͑(K]˔ZDHE`+DhO!/cBsץ{ _gpBTx~D:|gv֢F1aqERw!{x$D .a$8n?Kqu Ǿ/!ѸlILԬϖR^ 0TBfS=_Hl^G@2Ļwڨo`܃Q |x zeɤt*OsnP'!PO;x߹>( û5_ၩ5&f٢7!_z\1mC6xp ۢ[7xW]li:XJ^,*H-K6B!P"뙻kf֮xfĎd؎CĎmly2W>#UB̮Jk8ޙ:kJj|ι;_[Wr_O}']tVȽEQsx"]ު{L̴n؄f2FSSpͧjpq4DcMlɐn#k 2Lzwv7 Cnc횮YImi"mia&fW_8wpwz'Mp# %7nR>U w=ad?Ge=;%p&w'_"F1c@v@15Nl܌8a_Pxa07*^+Laޠ /,)?\޹p+ʠ /4~E1M^e\ (WϘṀ n ~njǟpwXea.S4P,udTb4 䐞F\f!pempv#5Lr4ZWH0[xXtcd :`B43a? |Qlz2#&I{{ܒ`M?B}kLcF)8ZL;ynFǹp|"rxePP7f[xz-zZqE .,w;7٧Zq1í3W-\]+Οݗ OBfTRIZ\ %L8'~gv/lW,Tw9F{t" mb#M,(F{G$MҌY`D@HR0 7aɀ ^ Gx([BLxOr,6u>`8߸U<= &H@-WR"MPYZZS6j42L,u$_1w_|=oAoUcvΎVF6?s0HVfH˴T UfYl8mToejsMmzB8M6 g&Jo7 3M9iz)K뫋B."GH&8f:?t g6Ƨkp|аV5b:4@H;UZ&-Ty77ĆӳrCR8A)9%mKw2G0온s-y,36ʌe'IțΡ WPgG4ZX2@kO,\!_%&fU@dx R`hO1L9O*,4,T%X {?ɨW\ 8C!Y26;,dlBsQ0Z_ظܻszhqJh yscaJV0vƲ)Lַd-F%KAS5#A}RRRo]I wljv[||qv /aB'j0G>C$yq4b0R0'TYY^\SXHO&I"ȴyTzL Nw᫄L#r?q9tG! >.xM48'>Ү8.KQ_ O$. =q>r%42>y-MIh~168§V/lh(*ȩ 2sr.877= ^^r1vv.|(f(cݢ:$9#@O t{BX8::'lzU۬dͥtЏMr^| oH/|f&kէ&"/Wϫ[~"‘<-,\cUTcoҴkZ2Q1e킌q-l1t40VkT嘹9:3PeMIMS%]~Yҡ8\Oїx^x<8 aA Y7|=t1Ix|s>Csu`^@.0dҽLsT5s5)af0SRg*.Yg!qS&M"q.' ݹ9y"U[-4,۟E ߹9^]q͘j'_;V:Ff,k,ĩzOMzUT 6/l͇sչ fuj?NO;Su:82ho'yIܾ8^ 8z9Iեxy71mDp:U l{uoPit~MKr >ό?Pry'P&Ե{`nXs*$GLoHZuGmqt:1ܣLGTq@i }[݁6B9e-<r bܓS<߱&.45 TnK*+a &wM21 q!U0X4[wTjhc$*M4B5 A3 ;YMej/c pV1=HE*LU ,yKQ/Nh64+1$4$튬X&OK0S##1EM^1cנ_ '"QUIC<;#Y|~UÅOEnV "~WUȹvhWu0] :J+Bb^AZ WF@\z & =>m瞰* t XD.D# WM(:Tnf`ƴX9'" 5ΓDV%;LCfIQ4UEu­vu/X`yK 4uF580(myTEQ[r/+I/՜ nvHXZO?sѝ{䡽XG0 S9ޓ_loݖ6Pi<%t<97z+&z߆Ҫx.ZLEncxؾ b7'xEU6 `ؖ mu]ɽ^*bv! "3b^cpx9mx"M)-b._PR+UAki~fzZ?a!RlÕ+էK*2RRYU :s~w]//+hY )h, =|I*wfe~f yPlhaWTV X|LJsW+l/57J % ܾҡ ̼%dywy:ˣG~uxn*^4ӃJǏE"e(;E27ļU"iv -x5砢׆ -N^] V(kM /(DHYVԴSЩs򖜆Hx*9z-u_Cñ%(GuNGL(6=ijO6+`K;eOrᥧZ''yߑľ3ij ͇v3S[.ܖBCp&8՚8[ֵkz0ZuIY^ܑhnhpF~^^vؘ6= h5oha Y'pC<4n3ߝq͢w^,E8^(j? ԙۏ_Ƙ"Z 0YE{#v\Q!W\J[0 ϹV1VN/~uU0Lk4Wd]zZβ==i[\_mUtСM(C>՞vJxFE6&ֹ\X1kvq .4 {f[ ؜>(Ug9G\YÇ?l8 ]w,b0c~ʇtHNԝړQoEͧ׉=6lw߭υٰ~W ]fߕ@oxq O$6IeܼHf6jZlwc/.I-RH//-(V(H,QMT(.M*N.LJULSHLNN-.VOIQ,V(kTQPzyϋUkѼq㪧zoiՏIQ$˖DF\ .!.6#/vw\JeWi t?;L+5zַn6լ\κz٭^Ϊ>Gm3/Vg^U,Je,ӜN7{iwpjYWTŪדV[\WUU=ӯiӴE.ΪyUOm.CUL9nLՈs4 afYYחrO3OP;"uY.bMWF__KW i&k8YjV66Ką4UՖ;/&U{S4mMybѠ3l 21Fǫ^"eВ&mm*Q]<ͿPO.wxUwِ\JBgMњ ބ[c6o}ݳ652@+c^Ք)ua_׌Hȅinֵd;˦gEĜ{QMolML1}hH\ʮnph}ڒB('ڦY3v)}I_Ϧh3`٣Kff!Y9_dž~1_8~X[](}X#P,J\v,`rm^أl܇MLeomyo8_u2.h=YWz|Oifu^&j4z?.=5BRƞ,;~<,NZ5=Bf[QI[͢PW],տ;Mmsg;3$]c٫ufGB&)3'mS:L悞$Mӡf) a:m53H7 Kl2lTsM<>V OL]?6fP'Rk@ dښfEזSoV`b]9b9ZurTwe۔5HnժmPv%n~:k38G~C9/d$:}V)LQX4Zm bm[LثuQgvyu!m %#ڏ 76޴xUuM߂+{ jf9Pׅi,uSj7zC@m).NEF{U8%^vrK1a9Ӭ*>Rz:hIrto jgz V8K?vQg]OUq0lN /[S͗x$7& 2k$9-gRf}1w/b[<4վ2uGaжyPH۝P-+vvdb ;Uwg0N}ƢĪ7s`HW$kK;t}ZeQh#6fr'vMXBIҮMnM.wAV_U`$,4ѶU,^= x)T|zUx蹭Hpܟa/Or0t;l:9z7jeP"7⽸&G23w{{W?f i8㡇lϴ/Jˏ1x)[̛vd7 PهAr9-g&;(~:xK9vˠ>h8/x&*یn* &$l /l9^O&hcᱵ_5"oU,j7 `K`Y}"0!1U)4פ0!Z;=DH1ݪ!=6JNnomih?N涉~M Vw$|We !Yn]mMD9i)hqibK #h$쓫izz˘(a#4g1p%l|'`jiGKxcVcYNrN@azfחR?ʠWԼrkDȢEjȴ] `0Iz0b#ٮ@gNI퍄q3{ɖ\ tK|1vNj,%NRxcE6vO> o?W~ry`Y+޻l[G={]S|p^_~7a*)׃K>wk3trFlF^,s(#\4^2WXvVV -vOD;0닿<>[FłT<"hAp? J1&YiWJ gǸzR.jKO-()+#DF,~֮OdXW!;Xk`^#-"oFuY#_k;yiDZ| K7к*%} 1Z2hb=3--qXyM6Q2h2DڣkwԁyI =Ѐ+&B2Ox*lXX"D^ܧ W*-IVCh<(ו~T^qRJ&$*2MD$Zr\7"(&yK(Sd`r* TIzvQVrqHF8֓8 mT,XRIdP"ࠨNQ []!`5)fp8 jF~pݓ5gܞЏ^*(~=ml ,0֔e•56r?vO}w+3dpy/Px&LKa/!L.B)17]PF- L1nxo14<;U5ok\;Da##ҲX6DrHCIU$laCK{{/6Qj}l8 X%+/X^{3VG(xսJNChNu@ZWB0`]CrKpM &H|`\@haޟ- X 9Em/v%Ƹ^‡l2;Z.<B<]ʕ:cڅȦ AD,<0mP}qԾBd} GݖTsequ0,wkpO5 Ǣe&[h$r'k)v-dݽؙ@hW%:$kț i|1V,#|~ߕ%l(b(uqQN ]%]gY͋/>37B2, xfz㵫Uyq<4:ť<΃HqŠ:Bw5|mqKJ(F2H{(s!.?6`G÷tTk `9Ւx*ڐ{#١{d`{p%Lv@m\<$eKsQ8$70L'nqQV/J~)iѮb*&I꺌R"6HbC@iiBIeƤT%d7Y 'j9b#h]j(vWƌz&%f:7%Ӫ9 P&$)V] Y) Z\eHx[=5B5ZPZxα^Kbɧ!hq љv?ZW1F1mJ:3Iz KHXgM:S_l0۬u*jN\Iq ~ (a>1uh/8Ϸ戄פ+%Yۑ7 QNdb̪_7j2 oO{%HzKcШ/6ÚJqfb ZF9eDr#/PϘ^g5q) y 6!fgU*/t&Lh](׋~1fL&}:OOoYC4¾ԗ:@NPޘᄣ+F&J^⌲{$h]M@3 qX _W82ª^Taz^Zz6vW2*[4LAGM?a81n ófݳǻz:%$i [ [Oښ&5ɕiI/x%SɯIz`xDZdl ^N8 1zd&oPMRʯȵHZŗH!/'NR4jAJhˡ3Ji<&rkr>Y&HW/dUlE/HU**Ԟbē6;Tp $Q1ڂ6`P+sF x6NepkAɇE)E(=?MNf$G^2`ރ*IA-q1#r=Vu~PiU5! 'Jk@5Wy 5;1mBd'=-?cfL]Ţ^J],5w-RV~ƺ_4d(ScTS[1eCRuN`:ҭƑdQj8f-[͙eߦ&Z9 p2K0o ,r}괐m Iq!C Y1Z7s15,hļ̋GKVf46 Je`?X)ho0At_V [aV6j`ILC_DF['7P@nhE~dBeaZSUvA`B}6뼂JT][Unp}lfV|#N16n8boL ,E%EYކ\6٫Rp[ޒ-tAT MF6I[Ml[YWvKUIm#*ˀM\l2K5dIQ$b40܎H-*ABP,}:3aƣeەrh"(# D\+>)gy9#}ꮑ{4 Xt*CKo Ohvx(GG yjE/<+nx yB#DCXGDn3>Oa w >aЖN '\n=WNlPjr3PՂI=lx,VԆ`hWPG}3[CށOsF%yP'y2np;Ip -48A5;mL}K':d5?h=#T;H<ƿ$oc zq;Pp ĺpxRʪdz!Ll4V*Mʤ.vb}VFq'xT0465ш!+`Jp7z%`l(ƶnބYJ]8k~"f- Pmx a%c \%NtlC uO[fl'H,ڌ-{X* _sa. )[`T9 28K':6B㐔ʺRGݿ&C#C,pL7p++RNSGh; B^ܴ5ܢ!Oz,Cz/O?\{'\"K2u*Q5I lOAPiJn#C{*cG >p=eGRZo8w8K^t_-f>Jp"t$K'o~C0"tC9=COgei"@f'CySN]9$r܉=*) AEJF3J)uRC|a[}ǭ!GgDT`C1RW2C"XILC,vVESyYhn[( eS: ~JNB vtdzxć05FΛ(v@p* 9)C)|lj7]%d-mLKosW3+T7WB  M۰°,_kBTi_q'1N-[y,ڲY,v37FEyU|`)Fqdw} WB`JK\B6;y1BgHW'}]M#6*R(8ՋǭT}Y׋dUH7ѷ^Df㴂mn↏J! @ KG*;C<,<6.}iY_uPt^:=}~bS:2T+&fFszo1;zRhjrBTPN.LY: D_^~ U ~RpkJ&@,0ίa~6pf>9feJ,[cG"/!dNC%9CP× Be< }ήqz]Nׯ͑6nJ$/rMCv6poT xflŸ$FY'@WhQѹ3VH1 ]#jH+#8O;=ׄ4N Dž>i1JPX5>$)R,2~ UoF.(TQoڎJ-=t.\&$]?jGlLV^&{-Nh:l, @âyˑE $FVqb|P?GEelf/d%Mh2SˎI>\_4>czP^V be,~`R'TOS/WupR NuNFA٢;QXȴE33lJ('VJZInY\ټrk6KK[eZY^Ǟ0,\ $W+Pf}P- )M)f %'vx۳q6 z'&(x+(e9  OC2og.n5x۳q6 "7F35ab Ox۳q ElE9Jz\J%J:J3nƱ1e&o?"xJ(! !bst[W*a96^Zf}sՁcSZCڧZ YXG :ELۢ_ 6 խinE3viܹ"zb&^ר&F:T 08 Hv]J%x?ON̄FQ3o/C'ȈNXM0H_7թ FGJMs@2}!w6qU/Ei}14-Jmm>~3T?$yI]oe`$MᘛxwZ\ǞPОE$39Z"@ÙPgjԠ"62r,xT&&lJgziw~gXH_`tDo`gڮev.~3T"!\<oŏ/>S KXp>p 7F(Cǣ3@[Vθ3)4%|HyExy-QmIPSRI"Y3SJJ١#`Ba\vI4c?M `gt: AlnN)`ܖmHmxpmXVn^R,THЎO Bhx}%?@3D-XIdӥ` |i $uT"ۮ4Q#ag>S1C-kcSK0SqI&#TƠ1j7^^R":֓ԬZ5D;G[2(RQHm!, ܟ2<%%zmL:9]0Bz4ÜŪP&FG '@(QBF I gvPT%![K{dw}b;zٺƨ}aβi[)3f,B:<ۂBy(K$h$VE0UO`)GoJ~[XK8ˏ;;u|<ҝeSLC0!~Þfȅ1/1px[q $4'o;!曋%vq9zv@Nv 9x}Yyl\yuQxHRx,IXu)\s)R)o w%[($ PIh Ң$H7 h\Mp}E6pf.mw/AٟNYu,QffNEF#x?EX$D>r=)OK(dMs;ӃIM[vM5h&5 NK893 ߱ ~W -kwZn׭x44KآH {;f-#dFWל9va2=?51xi1kymL-kYNu+ẑԴdX2t= ,kpHӲFNٓiśc-pqбU4Q\l୩cqq78_~ JΖ4@nQ 0j;"#,XVh4Br5=(HԔc[Y5fqA|ih8҆#=%rVAT NPiD$gN2mlm*e"|+YYm?.\>0aq$_큞:~0T > t^p߆ꕬ9$JbYy|:! O˵Z NVFBl:4]sC*s}R]A+UuZ%֋xP"w@|j_.<[in>#xo~0| b}׌Gj}* WwY⁦x^~Y`u Nfu%62isK\C?kl(Qik:E˩O/6boҞf]0s G4nkߙˁ͢ȉ g;2 [!rb>Q>_-pH"5H>sF@9H~/PS+6أolZ3^ wum-E17Py&(VlCgˑjj!qYBnZU @ 1Uר[0g'%iʶLSr$6OtMH&nI+oǗ x{>\av#?J.xi`HybO@6^DL|5ABpa+h6?/'I[a3Lsf[V]-0>+ 4kvICR| b4Z V'BT(3]m4!* |'%THVCRf{Q:0u@ٵx i-م9i6p\s(w1(Έ{ZS-jhK4 >"lʶ,hngrl2g˰Iyl)F)&.z-,d^FLz)O*9gR{BGV+Zk²Scme r{$xnU kdK{L}/]7q<5*:*1/38?@Nc} ^9މCO P`za^JPm% Xdт`S}QSLMpb:6sN;9oo1JR;ERYM⒟\{~y;`7SY4Chh|\: e~p7{ >5<&yU.w7G*:3^u^rgsz!Έ]{''bny(T}@wCð0ڃyf85zlcqO^O](ncb3qVF/fs/>ZJ*yZxS }KNi 0OOstY:{GE R`&-^ ^ 5Í}}3qf02$X掖1Č]!xl ,_ ,H61Z1De\ "'Hl)mecdTEu&2nj/^}]0C!3no>{!N(u|uHhweBL2-ƛ^b /_“#M& j)>0O.? 51:ӊJh]F?-((*y#Bda ChKB;\µe &H$X2FPCR`͓m|d|l;`Qw [.|wlauX_'Xt?L7k:& i18B#TDP%"ՄO,Qys6Y ۥatha?˰TEFd 1OW|3ܽF_܊Bp0pX2lp ^lChs-#* 5+Id~]391%;|ULhr*& j=^bSWK<) xYMVWsG83ͽs󨟓uD N_!r-O5  5zŴmj& +) 'ӘX]HSRꈙ+ x)XWpTD2a $YP'գQ!/5W`Dujþ'T6Z39.%*hlQQ<3 Sii/0f*جm[b`ƅG`g,$dTi팱Muzږf 41%*TpyuW(ƒKAxr>z4_Z_,Tb9|.~mQZw4-8BH|TR~S{[)1"`B߭qJj\_P<;i|ylZ"}͊ODM2P73hwPB .WE&wZm ?NߙWkK5nXIwE _^F#wΎo;4-ta+Ժf䍝\B莑b$?9PzAr0T`ralqąsY[X=,ME]}+ A*~"*5PmDK5xR':|mAW k|ТZt'nv\|?Ă}cqҺ*./Xeyo_dWf+=19YǸJ=94Joje̦$UOU&E+h#\oA`NK(y;xhcI TO>9(AlN|&Riż:[D}.[ p9a>1H+~R=ܓ6tܢm d%. /nCz+Itt]8O7x7Ԧ?*%R-UTiU)T?U9wf_@"{|߿;bJZnY_ tDX`o0㚸%6Yb\4VMOr#i)5D4S9_iȑqG}79%ffԷk la`vrE]Mт>ILU;LCdI3 &턋B7O7[RU 릖"O~ OIt7ۭ<ͰaَԃsG 5U5JVA 9bv/Uجj*w߾Q~Vy"!,"^xavpJl3Um—>U_*^?r31=OLԞ,f{-ԳD"I$6,Ns- +jYξ^xiEx"Z|XqܷT&AVx-%%4OZpfB/!V\rXFe9tw1;cQ)URDh\OO- bCK,xQ63k2z[ n옰+0R/ѳ[QD4&B3LEM3ᶖE}~xw{QYͱb._),LL_?\s #l Ȩ@Cլ9,͢E&>DL]"4Y$-VV]<*qi=NG/8cq:i,u-‚WMӂKm @qẊAƓ+ Dq5fd5Vxϕr͡-Y$ƂƹcKBV`n#fcp}#Tw/xkmCiV 0-]> JWޯ&vF$ՔD7Pia1 >J#܂OyUYQɓ!ѱDPWez)~ 9:1,1Q:qTtV,bP,7sQ!Y1ͬ,7-rCu'BWLF턚(V9,cjjr: aY^8&.4=geN%a9:\IIȱpF?džXmGL (WPL q~ċ ںS>.lR}WV>ܘi]xcKtѪ`Of3'ƒnX) zp{,<>hu+p3T9\DGiHqLd^.6Ӆ$$:4Hyy 0,mUΕ!: 'Gw;:xRa{nF0mH0ME7UOEme Gd~5"T 7>ocئY R ζ$Pey+xuTEZ!!թ'CbQxwp7Z }୎VÏT \uŪVr1;A[᫧;fQcv⤬bS z|/&Y+|4#޾0%Sx;@LqFD+c >N閤~uCnM{j0|q^w,RBZ.L&w0)}Q\3Ic:^w;4b5A9-;(&4 ;G|2?M ex}rr?E4"иkwmS($%=C` 9lcˬKV;ڤh={tf E SQ}A_$ 2=8 𕧟\}>~ulu+hשwlc<~%Q.e߅$g&af5z3ćP8OKhYnyox W}X7~830/CP~. E݂@'A,X2/?Q?MdzR&ڲџ̃ԱI5}R!GY,H2,^UP LZUdUlv  ǽa ^15TYOw 7N꿎|WoxK{7 z[ Z -\dؒ'fGrS v6YLA?v] S%3bq2¤4) 8c4zC+H~O=Z8T֬GRhZi{V^w?lC [0~3&21Dv;c}!VӨ_}o{㊬ԲUȋ?^K4(V!@Lb _KjeTn#iQ$R, F"HS S~$ChLK|w vP<*6-[RnLDUSU*L,*vppJhk8l˾ ; pMQdT*+d?*8H-%)d9!R?F~>x? WPkO1W1ȷ/+?XѶQo$n*|uX`{'{:ؒ¬x[SǕ5:{܌lbq,biVϪ{(+gUeނf?5Zv2Q/]I(ڥIэ}%Hyb#ϬC|B$'6_/|hb1,F/]#$ bCV^QA,A_5v#{#v<ΤFI4GV,'9e{U lԏ&Ц'367]Cd:k>p H3^J>F7>-ٌe3"w)>9>X~FݐpQ)5LΑcvc=DKE"iΧR<8F|&H/Cጀ wCa [0wO3;k͛?P3mOtAGvS@tq}Hˣ3m-i"|z@#nb"sD(?݀bQ;؃ћJ!8˫gc8 cZd/2B{̊v , pSƨ@s׳D$D蘳z5^U v~[= eS*#E/mg.NO)G5HWuQ]tc+|5 B^4YEs2p9QkwzM`I(%ר(DQF Ę蚙2V竝@;2j KՂOSqi&CD@8GH{VlwvX#LTI]5hu9>]Koqw' mT #tıs.`2 P$M.u>YT;~=YYrDkH599Qym sYvifͣ7mP%\ڼAy;AFBˍJ^ ; sd(QbUx)=ӺTJQh0'(} \1yUQ:D6*mްg•=6HM9GB  )>0nQ  u@URH L+lu713vv#?ϸ[i"rTL9a##1{@n?GTU*#7 |$,FR$BX m=LIOmlPKRYԝP\#3АkIE$,$0H (Y#iP5}o SU d)H bQ,bִoBWwSU_j.UHqlk.G78ATƼ %`Zgɵ:s爝F` p{3ɴ _<3+ `ƥf/^SQM#hBogE B2Ti `/2cZ (X E}}F)^cc@4Gc+p0bAEML{\)IkC01JKG4Zʙ/T˗ 7U:_=nL-]MxV5  K|Kȴ&QOALz=X0`*ƓߊK p"A/H 8YաymJhEq3@Z XGaer`ޘ#?`꾮yF50ZvŻ!>V¼3sVj!yyjtr#:^rAx?8Ŭc=ċﬞHEj' P ۧXU=&"s ΈN8*6vJ*z\Bv<zԇu-{):O$ @QجdVϵ.q@sP+{Gpv3'dXBՃ1?,/Y><0sD%]'u;hV¾z?~Y!܃矴N؆F#m/I'_g"HB0)QO[̫viYȖ"!ΤlBTﷹtBPjdiگR6I@(b&ad9/р+ GC4 zjƉ:O.08 HeBYLi"*!~9Y!$-, \7RLlrq0[8xaP -m-;. [߷VZzdQ(NbAH% M'W`Ya6VtLs|G%#:RJ%!unLfs[Bb/wѾ"ńXn];2oE؟pQC$ 4ª ]*B:{tG,q[+=c?)2<46C/UfE,C K,|d8Q08Qt<~P2+2jn k+JX{Òz.Č`a!U>BNB(|;n[!␅mީTw1<侮6B*9C~r.ƣ nȷՠĩ+(ލIM7x0`&Cs%kPUjQ9陕\ՈPpLeș Ui#sȒ,?z^-efk(b4*4g(i=p"P 08ΑRPpb[?+h0:Wr|~F9͔lг%CYɭPbhRzzt=zC3 Zd2PLp cH*TݱA&!G-3qnKqf6U / L5ی ;"0!YoJ6s;K+/yȦL~Pk2d*!C (&I5rduEYPCLW,[Pڹ.xAþ{lS"k1Z`@9? y-*klp[l:zE(g0q8{fqHp H.{ >H ua<Âٰ !o0O8{WB 񤕖vZ֦s? a^IJ]%1[KSin]-#x)7h6[FU-3dR<ݸHkn{ELl؇Q2yDt/':ږ?hFŇWo9UdK 1r\a"Y_F/Y{kYIe gЗg+4)6~l r@L3<2-)*2%r;.'%=zQghsWv J䦨Mo6 =18tA7n "wmܴnۭC9IvO`CfrMoO ~aQ8lDG{6ɺ:1!sK ׆tH>vy]͌  9!d[ Q-kTL$w S `\&8jB^_abꈌةPcGtu9rk(G h iC{,*)+W~`E6Qڜxl6N#)RƩ|l#G0s.98 rS 7_ KSGH/CjA62=x AbTjH$m9v^ø-EuQMN_,;^9!(XNDɻb޹98$PK2vFF puRPyi'cd" |9ՀPRp> & &m E?Z8V k];>p`H[{| 9Sޠnyi'afR?N~~ V*,&\z{'PȼirAx2î$d@̚Y q<3_>F LО:?jԆbugFx",zkע{Io)l5w4@ū1iV CIuG-aJ#ӥ- q$M 8 +$Ǻ s:ϛ0Et@rFK?.ER x\NsKjyc%qf9}j2L'AMѵBPT>wOJ ڍ"apㇺS+* jpjݽF>pܰXSx{TfXra դ!yզ:(c0*`|Zn/P3ARbp̆iU63vJ*pux#=L7&)mi%dGR( ;,0)5* {i'&m-vJJP:`Dd;um>}a%NA"EC#2 sr䄔Zc4F۶NvBfAn/eš#i?kÁ31ϕ@`iuV?C)F!AB2N Xsc21,uĪ@4 45ȼ16:l?HJؒdJ\#DT@A'h Eeg څ=1ykȌzc XW?=B1]DYHb1ChE9ŇҬTρEg$`V4qL:2A gqO詓@QNN;ubs6,YWrt_L#*UX^4d = 8;ac*>5k ݲ{> h"{M;IA NXY`RrXD68@~Aw=Bw(0Qw&u0Te("c9hJd6P]A+&;šCiK)vn}>uvzB(eݡI+`\V"/pݞ q+\ g=wtбwXڅ8bOa 7;ȩ .K*\. X SHܗʸ_&p3KD*;SI_"S(٭18S76l٤1;y۝9:d [75׺RTgY+HE ]A-%+٬kL&}B7Dx@!'Y-;2Kԗ pw=ᶁe/g=5W ]F(8(ÞΚb0.s ֢?B28Ĭ0ˣk'}WU 'RB@pk!I"SIrM:a?Ɂ K|m# #$BAcwzoF{tj~O|JFn_8:dlG_813籽8/ي7uFD\qV2|f4בWeQ:F(nt5#Ww:FRPp޾QU]{Z]u߮s>{+}sȎ%eðRV6DwX'ϰuᴬS:Bx-pj:>z+BIIr2.9Q*@( E:2Tʩf~oTJIдTVԾEB6zPR"Aް!ͳhD-9H>=Ʋ6\cg\݉2qo|s t }W(W)E;;mpu<>n]utCaJ%PPn]~ŇQluى6ǯ[6SƖV WS`yVtTU2aᱰW?(, TG1xTme ŖJ 8u7BJwB ( +6L2Lqʐ I e=uD=5FVPKߨj1=J@9j+WD" B*8ZlI2s\HR,ju<4rXBtt@c"u:Lפ!XcuwXVR=vԏE,wALz#Yŋ$^@@z/ephRNuշŁmʎ!&pmH!Vna)g#Afӆb@aR;oX'cX\V!ݱz2|9s0MwtBv}~РyZ7Q3@46aԷ//fZCΉq U( 6>8V5狟#kHUC=}e @W/~-֘/nÅs.θR7h6 mdVS`IJ8Bm'I8('I;XHAn>Dcf\92=KD<:7'#G4UDOFqWtA`/U%(-TI%֩`z>O|SoGsj! `Y3]kx*!Pe&>u3V עO^$U`U.`/pu-8)و-U10bfc=e1PD!ꕒ:P,2t.JM^kf;UG!Q&=EjˎnDT4$~?.T藍Wpm @ǧȥTM1j"(WS7K(,Q% ]K*I~l&݅C3T$S$צ#Rxk7U}(D pyIpa(%hFiu)DcǢݗR^|A_Pyu$ gsKg@i- @,XKGO6f&)Puf>ڍF}_qLA@=~a"݇Y'9՞X!F!K1!rj m:K_Kw踏(cb:Ry+zk +*ej*h$-zME@jMHQcWS!bew?"L)[[pE^zI sRň=|US-cM80w}q>{ Kn-iB9'P Æ@3I{0lg%?[U (7^b.|k ޕaB3 ( }WzJl~>ISAQBg"!?i|p6'V2]8kH &j]W xVdavWdxY{tU?]ABpDAJ@$Ix$`TJw%]d% * ~0 F'FƳǃsϺY=zfu߭*XҩpK{5WE>ʫu̩=ʑ7bT98$Mqi,⒜}BR탓9%:򐫼i/WaY*zWD\Ggѝl._ p4.XwTQ6o*6AWHB&эsdYq$Sx^`q\F%홽Xѕ٫I|FgT=EJ2ɤO'-itgUF gW.E*3HԤܝSʪ"O \jHHa 8Us&jfY3^e*׊ua&=Yڮ ꢗ^Җe]~h$ZQn( _5:#93^upeNm)7R p㋹'3R=$\8{yo22 Q ߛ$^a$8&X3ÙI{au.އo>Vh4 쉕8Ocς42*,46+'xūPu.{TaS{U*hj9tiMnX[D;o#cg.m];CXz5~mpN \кWJgiWoZ ^ds,Y(μ⡷wd˾!X +KRPcpm{х6hT k/^tËOݼ7S]<ޣ鱗1k0&-i7wUtݚ)x^r(uK7HܞKW% e.'Jn10P- A2Ziy:jx^34;&{0)۪"KRz+jE`z2$ )|f$&"/m'ϒgpn;6IC)qlya1ӦK0p gfƄuT)Ns;xY*/- U 2#"H7'PZd%Bۏ*VAw9Unvghbq ngl%Nc:hg8fDi[˻X܎Ѯ~< fj0uxmx#z΅kKyx*ض`$J5]h0/6E]9mnSb7$.\O(P)ti쑴\FO.JGd5,}9{)5 9Eחe.P}}ɡd/SwU߅n1y߶dѩΧv=]CSiVdbV̲leG#S`<ӑe˖#ӑ~x"pxŎ2wSH_ c2:VCJX B+I"%\Lk<~yS2RiC-ZFv "U=["NԥȮOOp)}3~ Ɵ? J@Xa70@a CY7bO?3?y!,9NK%ݙ_BroI%_3K@򳭠|0Zr~5o_nd;l|\8Y,}z*zu}J(~.\?}uZ3kk*>eu VT`Rܓ.* NOfgLDv Mxslt=FdBh:F:E+쪜}o.7$&:>zs<ZsWv1_A4-MP2a2bfB٘hejrx_á Ʈޞ3zs NOUig4VGHۂb1̨tx@`FV´eB/V(nACAeFhQÈ4@( LB v'+#jZ[@`q}3p،cXO{Q)sorN*d큰4mB5,:`A_ >ES=̂HfdB'aZ/ߩYR𻱻hڙ놄Z!q LpZM#mf%c>ps` JihXCNݓh{XAuЧ cowLYY#]Jv>)upLF꣏1;FBetgۄڌ[mZ8-V-xwc4ô*g]Y60b,I/xPtX#| F2aGq@28*kIByi @yT"! $9h^F%Yɀ@/(%c7G6sߟԷ;'0 )(b`B܇HFxMVyPU]=4}EIQ@ l$ RI&* p$4mi4f&ڙNlg!?:NJϹs}gs޷ǽ~/ӽ]WVX*կwUEhc\,ci`갓Af1IZ~CM^UK_`ysoph+^Ly' ?d ո8 +܉vLk2%|Vp253EžS| >qxUԭm8ߺLuU'[Org^<=\a sF Oڎ.JӬJ1Բ(˜D^$c*CQ pzD7:Tњ390 Gl&U|L03{u֑gA8bDPa6'`?1 (]OL5ioh2o ӀiV^ƷڞuVkz c?dI%)L0 2|RR^ZPv|^^VN[be S 8/T 8FB"dز >y`A2(]ƒ6"T[T/"V  0[IM2vua† -_>$ެz !p&ļ3UyES]]X{Kꚲº‡ݐ)AT{!W.+{(W*L`]Գ\x0o"DG:$s>EUߑ`^RkgkRЯ~i|> +!Al>Q.7Mv'odlhmuyfaC)R5(j@I5ڈסi;``Ya ]T"K C9۱3{ F1/zș15{ ;؅/45W"'s [lT fnںD$n-XmxcQgmn^6yuy. 9yư5À"OXE_َ.G'aۚ@:Gb$D p슣gD>v"nc~juw$3?=EL4zk==Wlc1BNJliڼ(d4V +V۩Q8"Tjd?r`(0 *١R3FF2zTׄ'=鼉$toȣNΰTН>MLh~7s!̛FPgkh+˜0\Z|ØaR ZZ޹tNŜϱSױ%nagݯq0>o\a_YBlP\嬀lzRGߌ묹yc`3thH&\H`.݃yv0ljP2M_2is(.r0z!_4t8pZGXDv1Դ]vq]Le_\4~mk0 1SDUX= vT5#Eǜ"g}1ذ/S;g0a۳;imڴETԪ7 }u s1 ,d_i)uH<|D+mLj&v{ĞZ>*#|E6" %cj7E%r6I\vud(I\Zk׵E$ ;,A,O>VSg8Yy| cPp\ߣI ;"`i.M <{ {luH:U:! +zCD&r> <8;zH*U5 &w?}5"¥cxu ^;%R]!J&jv8K'1"T 4x6}l*9 6͓g7O} !.[#-D׍oe1͹;Wsㄈ:4⍩ D x0Q ե|JQhiYǞIDƂc{Q:l,^9@ =QUT+. 7;HEdqH 9 GRLoRx{lNMlFff|r++DW+#8+3D!4vM*P~;8ȸlrg,_"V_ H+T, #S+ͩXC5}lv6 vAMvY5]h+[UeвklkS0z g.й£ JD ZKȠ޼1eYд_=˂X%6Ex 8Eq=8 -\vDWMn_Sm|#,yMpf{0G܇N8rfH}_~fOTn;_^hzy%X_c<1!4_kuZcYP}skT_**_][{KytW4Myb6;FMak$k@u7 >+ZtENo,;EJրCHGȧSZQꥃ˫Sn2Ke3+W Ag\2MqiS݊ Sԥ%D~ڭHZkof]+eH_93k; kc!؇cs;,X`4帹$-뼑+/Vte3,.4\˜?[LLq+WPY_(ґ%pB@ی'kQqM򚾇!&dy$ 3C=NN|wnwi sڛ1\cGBYP댲DCH 5L\ >K>Cry"xؠc>aaq0p_~ldTGݰ//:Ws"w7ڔr*Q^`-ԌeNPE @CQ)E|CK? gqBwrk/0qmlGvЀ dP]!k O`;פC8{;9\ xMkA@B/QYn*۬om͑$-Az͇/ꄺecPj[f-U5u%$YmHy-p*.=DK/W|V{e*c͐ kX*Bx]WyPUg]ܞ{MDDDP l@KB- vh@&`INwf&VTITL9d&;=?|roEk1o5lO_[^v=ly4Uuf$6 >E|Y+æ\Lqi+-rD)mҗӞ"%0ɵ0ƥ+\3Va32gb:*4gn,Y}P0:k Fg`x85{m,if(i Ғli –gFI%S'FMS)tdtuN05z0Z:DQ! ~;F5bՉJќj:F Z5^D0dTY-IwgF Ӡ^![mVp}KmB`hm7'>tgNP+F $ݖ*t?3%ӡTGP)) Fч_}>\%IX H>lVe*Klm 6\OB,Bw[ak;LD-.:dPzrN)a=O!bn8j asS~%!W>K3;Mɴ ,G+nRER6" mҪ)/x }>٘B\& 1.JC);oRJPQU,V y6 XMuO-pIv"<+lfA+=g.O+l^ZV!_Է=`DP]FPTQ(T+H ŠOsddSH: Fv/A(C&c$ҮCKqEKh"OFW‧dI gĠit* X_:E,,S2 W39ӵ;DDZLB,-Lsi!V>XU^m] "WJ)1~ш9(/?}.=qZހ[gC.f1WýX1Gh琛fe/M@RX4!9L1 eBG~<WVBGin<hN9t0 947`Xn&~Gy{hQ~*KKZ`5xŢ;R$`?zGn[=iO1ٵӓ0=U'$ʻ]SDں[Ʒ qZo{`Pzd 绣;lljfYڞ^P9s}&>wGuݗŒ$cnCʹpa1iw~sDf&u;:-LO09M-StZX?a&*5&-n +VluiJf>_/K(N7წJYeu2m~)t9WNmBאPRL'PTP1,yaˎO~OEUNlӕ!AϮtU@KWu:/Շ jZn\fаտm|0ME)vZқ5۝voƊoqٗ^!kmLs錩8酺"^tC~@Q`'pC?|<K# 0w!~X) 55&PΎZ:UEon5Smޏ%]9O~-bg!W?°RGWRjP?1z(NA17JP:a[ÃaǗV@Zy*G nM Sl'+^gJPe ^S^J0Ur q[ XBn}{&{$:LzvWÓ0cAc;J{8;]E#KUɿ#0z&Kḭ㲮9_tq @i 9` (A MEɠ9g=CɞIӞ6P5{€bz԰)zz@hFeQS_c)H}^p^⃤B1₤Jwdhҟxj&N_i{1xfsD_?U!H*,q -?ɹ2?v>wpﻂqS54 Nl XҁJ ab`Wv|w m (+23 Qrk1bSD8Gs8Z~)i#[~_Rc'qh8fѣ@lP@6Fy|ޒce26={q"K>lGoh%7ij͝g8;{|Bnzrp)x'y%n[24U*q?za NjjxB}1ko3ۮ8Rd\MË`Ⱦ4^:{8H<p"OFQ ŃG'lpsN4M]huޑt\ݙڭkʚd|>7o{,0ȾAu8⋭S/h8眢/xTS!Q7i`ƎӠ뎽4z :g[-sEa~=&/*L/wa] h4*>UƂm"co1*Eݠx* AYa S{ASn}Qh&ϕ Y.So\tRKoIEVI gJ=cZ V怤ǼL_%- 8WpoE:gН۠TKCeNF :°w=AYTkÀ*FzC}r;x0Q6;} sKKrDۢ85 |0dȊaݚ^ԂmCk M`]9Eh5Bo!s [x'd2IpWixM9͆2.o!uYbP4t6VOd漏4|Mtz/ =L kKMn2Gd&IL^7gL| 1f"N:)$2IB[*ßAW9h\zD wM; h3@0?ej R\gsƽ x(uU*++V0+Dz+bΡ~&z+t4U_uMwzf0fC_cߙtjٙlNe"-1t$k(/ǐs 8sI+s@m8LI*~{>߳O]ǃtкac D\ F$|1[hRmDS_cy&Lsxw(0wvp<CE|{8CVM;B-zZ^ yf޷EkZh7zhyly::8UX@E_i7L꺊ݥp? „qPZt^}cA{e~l$W@\2>N5s5Z 5ѵdwpsOᘼ6QU <1q? X'Rɭ4})dO&?H(g xпV_h'F ˞ahGʃ=\4 SAgX x͜rǕ) ;)I67)JlYĐ85 23ĸ>bAJrU*>}ݽ٬r}߻ˢ^v޽шmE? 5l֌+;Hؘ#fMmHhC#2/몜˛Еu5+öYWaPlwuP֡S%X\ n]bv &_|]Kݭdy, /2z(ڗɣMT5p4O #.m"PTK+ zXaVvo-瓱$m¢JHsbSgWey}.z]-龮[]sabֳz>ו}-8zݼ U }e7kR_{Ks,U0Pqe|8v+˰)Sav204`rSgۮloB,qTdM8cam?v8 cwpz U  L^oެͣ.TPSܯ:\UW:c*l%>MYv~Xپ3Wz]_{fhv}|׳u~d G<^!,t+?C0h]7;ؔȡi񢾁 .7k6\wö躷MQ 7M<ƌq4sq,Xn~\ StŦ/if/ DZfpa~;֧?XbmIQs_}x_ V^=f˅g~q\c Z5l)"'@nP쎦OK7RWBRܜn^D >. OtAg:7i}m Xoٱk f !s`xS!\*yvV׃}oаD8s.lå'fSUy\/C䥩uoLO&>Y7VҔWz[({|ergB-/.0R^!DwFU-wFjhs-©sQtIm&,.jX6vj͕WD֙r+m+Gx:PMԘz@Cm q8tA"y|3a#ebՊPE6i:.߈t v geZl/X-j8&~1 tBqj[aJNq˛R=ē.:ѰM…GrVctGr)9a|f'%J { *nݻ ~_ͪmg*'$R`rRi5L,#$levj? ;O26~[UyR1/c Bdb'H8 }<[u3D/hn%n):`)c[ܬb޹X;<9;jrG/C=yeW>*6:&U>kbg04zٮ 4Fmv[NHBΧ{dنAk_n랪zS~1SyՇӶ2[Wؗe88hƜyxv8 qݺ}tn݃>]^=8nJwt߆G7=z~@.dԾ?3inKZߑ%E^279h\wqxSezE:8NǵdcX7˥ Lr$Cj9~KaV89zC(GzLrkN9rlhߝ-p?ݱ~chjc=Mp[~r&fM `$im! nsդ$r?l .U4OFmHbtonap{;裼nDpZ*`tfuEd< "Dt@!1e?irėxD`~%i`xktMf G h[AZT zYEݜ_ÔeLYH pެVI]bK~n®򘧻z盇ᒵd}.O$}|-s|$3û">}o~_:bFw&ڸlJ_a)0 z<$Vl+7-HS\V ]Xkʾg:B}qKS:/AN>9޾NEFz8Ѻ̓ߙ?ALsx/,[>(` fg8>m@nW26(|4$qF{fiRj46EA/m>45^+|˒, uUMN3䊈5,g/1,,8j.t꛾[0txծ7o럳!"ʹk)]q4iE)$JG`7bo}}{/cs 7{WE#|2wgֶdw2̄Aڣ@s|\i=vO,r\RiiQ[Ghglc23"bXoc%!d> :GabfL֤zYXAJ𔍦ϫAt: ,hn#pC#93*3fRe'93gjXuOb_ c~ pIIca3ld0vLuou?EI"A^7q?a! WFux d32Ǩ#3b b/Q7zlyWmv3?R,;1-Bܠ?A&0gTq̅眹P\q5LAfP{ĔwVB{tޔ\WAFV[Elֲ$[X1ŠYO 8h7wamI9Xyؗ4!E_"icTQ-> TĦc_ 1T㵪Qy4y$|Zv"^a08ܠȮxIz Ը( g%il)awoRA!sΏdEj4 d Ky=p44NsQ6 >&WרYGG޺TfHP5n[K-x&S$.'#VOg#|d;eKe xBUtkP! '5хiM(K2/ZWبĐ8f|O6ׯ>XR(M ؂|SKbQ"CEgfPML2^BXS$9یE5C(E$S{A;= ~EP닚2_-‰+(NG%>8HvV|nl4\E~%R7G]*(5< )⚚aHtDZٓ×bn! {-%2#OsKkR$%(s=h͜#oyw q:؅Wo\K|TbJn4'm.U!E'9N} HFIC*ٱ~8eUtX2!IXxyjNCN莼cPJl[q?ġǽg8U Buw%@~ŃG0!3[Oi)[yBTSSA,w:")R?%3[޺|+,jravAq!zgmQ"HS[Uf@!Ta$z9O`MŨ[bO pelvJUSzE-|js5ev):вJѲ6`o N&hO HW$O]2aCU*?nC\aBm?c r!XKgFgMD\i^ҩJǼ;us!>8wN},WgLz5bepFn&%>q '`fm19(%K,1@r  p8,&<{c] ?ur梦V"q1R?Dz3 C}6A u=WlQЋ_?'1K`; vVȎ!xUr\Nt`9[1ݹeeBLf^;ɽ)*"#\vD8#tdjL93J34bE!-&ܱOL;ʝ3*3'N{l|إGnPPTމ`A#UY32|%E%P<ؘʙa'DPX^? +%JI_ (rAwծG($3-:FiBGԡiܔ5ϣ L$p ďU(Lj<@RwKE gsȋbGՉHkQ} Ђp?=a<& 0D?YP›⵿<0IZY7rU2J3'<3BLC~KVź'6r,06@tbnw9tQ{4"mUJ&6މ}0Rmkr^Le_#y"_]\8@w%Gɱ1 Mӟ#impVҪ*Z VVQƯlIusm3DZFϏPy^"1J9ƈX騖AһiM7*#Frh2 PHo1>#_%ikH~' UHFOںiI'[91ed~1m8 OkA*)] =`[]vZ 7oq嗖g[ d%9=B%:gLk 3 Ng $ G#4% NU#+=LuKi<{LwW1 7 T)R/9XJ7+og蒹cORC؆v\$|kBۊRfkK@" CK6ey특Wzi Y|4 )l~I7&JC"C&q]+i(=&".A,yEr9T5]KuX!).-R]͂\XMe}r.'#haԥ`;'; G̝mzFOfɨb$n=Q,3.KW׫QH1݇[+UOW`x[qZ g 9*&(x+(e99 ٙyE3o>}:nHx[qZ af23]bx[qj Or3iu{ }nxWMGYpp1AN&CIPz{$rHMwL'U3/ \P_@H,)BHpdC"?p{?ӽƑ]{^ݻcwW^f6+0+w+/{%{wħP>Lal3s c-d6ŝKW/ ڥ##}m0[0 [A (-V0+FY'Xl'G⌫ ]KLbv,#q{zB3#T^e8N% N.t@q5r[One?8%"j'O5J%\&-@)jn 12Yj wOtu ikð#VPa8M5O'|-(ӝT¡+ް+vmkpoe_C"`h|M0+pKutfޣ^~+[B&v, 4z6sAa%WB=եw1*SF %Ѣ˦HVl>lIz6w]6Ӫ=!fj/{|ϖRy[%Zʹ(rlr tO AmDNXBXb[mu3^E܈{51bx%wM4)x%_d'5 Hӏ:ȯJOhg LDܳݰ,ڿza;]Lz(*\XN1QdTELuɆb+ߜGe7 3PbR?X0H|1'`o>:gČ픝#۞[ \/.[F ًXyRtzk"9ql/=|"ٺB1}R n0P387C2cAPx0kg{T  !RN-A1uX wSZrSlm@Sm>7<.tHz}iy??:i2 Gʆ^Mpn d y5GV'(et#KSi ]v͍P4K><& $`7 [Y)M)vH74A|JJ?zHt96 Ut[ǭ[OE7щ!npC 9gwM4RaXRT$;v}Eãr npo^pN{$~Hu}سxT 4rOREFVUޛҚ/nv G^vd5",ff2R]6g LFbǩ%$>: x4M4lHXc"YnPaD J]! {jcV9q/ tm1P%SUWP2RdSH/ f8wׂ:zE\ؔiX9(:Zt2|+z]{!Wcp;RF/_ߌ.0Jg.luڼ}:p~0:NwQj΅3D~]JXosb);ߕ׾U%$ ŝԵ !ACn8cZN9Q4'?I6&{ߦۄT!qblwcH▨ڿhq7vT&¥+:e/˥BL2kҰ7IjRKuј.B5t;-(Gi8vP7Ab}&IqUN+M%}ŸNvb,Xg/ܞu\C ̾wۉ_E<(l ۃon >PԑOvnBK3{?|7_Wx[qj -b[$f?qw g9sN) ;2xuY l\WZq?'8cyM^?ei3xzfއSw7.TTnW"vh٭]](!UP]"XXsν3N!R<}R6d][̌exZ14 \a^~㞛K435ʦ4:[Z*mvzvz;l\7RY=e3MfslF҉ M#ٜTtFs 憐X4=e T[<)N\L2֥3SE1ְ9.[ 5[O4azt覾*s촜]A߮_׺_ai#汝\ /ȮahTp v-y}kyB06{ !Z"[tcă{í(iUiѶ0j3-3;kZo5}-Ҁ;-e%(5PĕjMo.er<~Nt^noFA;Σ]GA8)6@˛agJS2'uư+)]kv?ޝosnFS}o0vڞD)$[aب*ɬM+i9` T MS{XRue *r5ɍ]V-n J>m)[3lE@(5 >L烁(vvrˆŞS#lArt^L޸jK[{ԹR/8Z4j2Q3*+Yok('kψ)#/r!}PcײF#6chl C?<˗ T19DioSie#f 'ѝ˥U$AGےR xypѦe3sQ-ЉNrX)|V3kdkK '{:Ҷ.vCc?Er_/`kdB 䪆;іYw5 ˣ`5&3t_Cr(SdnCM0ypk"͊:ON87m錱03HT_7 52sgư3( |Vsm*H#]qpiQ\Q1l=OnK{bBo)Nj9-}k~t+atv }Ѧ6cg_?LOyp?ѫ&zDz4JvrI+wxA z"OSCaiyk! YDlr[+#`/}8'{E4Sc50~S DQju(ΐfXpm^`)Kq|?/֫G``SKC :'/NyRX<'^5Zo0ȴ% 1it+j+c!h!BFg;4hQMnFzYe55d"/1x)9" ?9nk=$ ϫtVۘhf9RB!.{Ǎg.+a]r.V68އ_>&K_m{wb VEp?_ha$UP;N^jIW_OW?m 7\m3Vd: 7$n5<ؖWD Fỗȸc#H_R] o];#UUN^"r9Wx„H;|tֱNwF;}b0)?{S± 7Li%Azʉ!ۘ 9B=9($VMSaC^T# x涖7ofvI85BccdP\pLO$ ml쌰 fҢr lLBK~4W%>}DxqhO(E{3]:CB#*#@PjR;@АK ?m(POsx?8,?pY8=Z5 Mm_sQmC}t|{ᩱ%hS) 䃦0U7Ob$s|i`]3H TʮZk$׺a6I4 >k?Hs0z9eHGLW9 ͟$axeGR.YS΄# F>SlEOL-5&yB1 Rf h62Ձ}Ü|*H92*2ABshDwϏWhajKbBUJ֮aʌ݄`s}ՋWDE\N: Jn]0 u =MOɎ˝5\4.Bra*f`Fr|~jc-GU_nK-f{ঈKḐB#gٷPڪ]2-vBu?RRts&c⹜:OA/kVr_2?i%Ì_^E(IDu_.wrQ07l0$O:[By&#BM*.E}Zbs3|pGhR',H4ʅM]h^‚_`(T56vbfYdORq%C-5~OV 0EqIc)z7q]ywOuA$TDKW,TD~V}P]_ZQVD Mpʷx^UOZE\rR&0/tj\dV0pFP`}RZ褢F< 5]jpk5xDgb eZwX`)^4TZLYwKZ5v0`YyCֳVŎ9PÛ^Ѥz6#3OzE4颷DS1>T㛲p*[}Cc'Jhe%;.zoyf0zy524^l ~]tSIrB`imWl`cƊQ}ni!Ҋ.{ffnsLHUa`ubK_@Dx\ 6n&kr8 x}rFy {6$M/=,ER6ǢeS9p`n@S7o ;_f]ƍ#v"{euRϞi<=J2qz}fQRv㛷AI8yR< bz0Vу^Ƈ?<OO8c{܇Tu _>H0_n޼yLVQ~fQ ^5KOp6> }?R6LW?.0ݾ F)! Ur7'77o* J:=lT l!jв.COh僽 )>i0(k`zpnU~R$XP< Ü ʣ&݂uc̆&8@!X>m>*# ߇*M9 (S59x) 9Ve>{j^Lg`1 RAea(.6@ZEq d`C/tγa]k ' mHs&Mznu/d\=DYc,C ʄp%XXl6aToT}c?P6 >#`_D &'*a>LC"-ݧVbG;kl;9޺K= yCT’`H֏]1X'KBcU|= LB&]N?I,%`WA &=Kȫ~!^ƷG4]>~o)Yz]8ܒn m0%x٬j6Y=Xze4놜;) Lwb[ f'1k돟K5(LdӞѠXs=h6Yb2t,E \x\G>`xEYVq,<}jX!]m 3Si'1\>{hpJѠ-{jn8n)wnGN_,` p TMX)ERwY->Wӗ#w\tksLa **xN_B#RJ;;@'#qL.h :=BiNe- R=lcyRR7n0Ҁ.Yhx̠hggLc"tB__?`m\YAniTvy2YXc"AZɾ {Zzد{u`& L<$?9 I3x|{IQCmwvI&ߐ&z+rt"*zw_ ֺ^?%pѰj'}%YmwmY%GU >U=٠ ^C9/yذDƍ(b5UCΒO1'1iqQwՆ|Jk$0bV l3ކ5ۅh*f?;Z[ Xz+ mcĮ,^[5ZJOX y cgsن_Ix?쏷ߴR%@W y:ҩ"QZ( JiVB-} CF^ rd8̣X߇۵kGg?)9L*t\,Գ([R(i7|w@J'6N %GhYOC(bN.IP3px `[k,%DrEab^͜2v=?W4,r (Uktӽͩow]Q jA{699 4?iGeOarI+"=ŶW+RZdFҔ0䂫*kGrrj,-s) * 램sM}rEH )awY6T6Nzxj7t+-QC b. h%(H"ս> #a*5ij9#C+[jezۀQp·)*'ށO,ukw|TG;DJxOQzo Ntg fBfBdJ7Nky! V\ҴB Ms[E^xi $d &ukڂzIe~Q'lw~P)b$)]B /h9 E+Y'SZ:N"q`tg>}X2~O Keb *j<UYU<N)j8SJS]ybяVW{#v 2HWh'O~ܮ=?5cc4rq-8ՠ;U9IU?E+g&\;,JLdǸ#ZGP.ע9x8=} ՌКKL"(ֻCJ"A2;/ۇb:>w[.(f2!Fz %Ysk<4-tJ=Q~]V25=88:$k)4eS2bƑױdvL,VSL.MgϲNȃMM,G\'m䨩g\`({b֫oaXr;F}l 勱MS%!Tw$ȡ%L'\qJiy[dEopJ:_r%{#P!j(:t5xdȍӉpQJA#0Es)ZZt|(%YFBYbJ?}SרcSDMnnӓ5~]QωŋSܔ̕[qHʢmB"p/eQ0**$* zIIRm5'XISU?;U*3nmA'~Cne'.#Q 7eKrП8UCHbY@4|0h:n17mƊvCS =9P`ƥm(8ЀNHlX+ s]2{=%<2TI7lE<avDh7gWOBv$MZIO$l 2џT>\Fw(p8 Y*zTаcHm"wSju;i%B]<4.=_T5-7H ZqAֻ}2V3B7+ȐX¤ꡂn,pN¶k/`V~;^Lm06M5&~It)ES `IiWιv[Il#[OL/ez6I4{6LHYDO(˻~~el6i߃^bԆ[O:w8U\M GGhQ8Q,<#OAh & mcΑ$ ;7X$[zK+"m ^,kRB_`sVwNϨ?{2zWw0)JK_בh*Ҝ 3Ղ IID3CU sG/kǞ:r K,瘾*ĪǤ%K?b6q| V6 i7>3ej%vfUwEVJ"RkTpBJP`8,a @O[5)f-õlURʴn͆ŊuD =!"|ҿysniQq+g[ā* L h;dRtetVC^Y2s~{CǠ"Mo,{8 $# 음!lHX{17%?\ObO Qq*Tt7Zda7C$!H޷G]&VX^jҖ,P81>Iv?Uu2RcؗZ%0FO!^ 1(4;On!d)EC,C"gk~rnރqfA GM.Xƣ6p+~Mh:% c ΅R߁CKyMZhxvl AZ+8WhV9_ǔ !b]X"x9"<Mu0 Sތ$`i,ulX#SEMs3VL!ns }k`HC!g đd&`~Yb3mvsFj5 ޒ[0Pu`}+:!҄K/| wA(=023ra 1r~D,SǛ!o;= ɠEM;j$YScRQ6## UsBM,8~a=փB;pR>`_zIAs=лH*۷c8 u֣ Aۦ~7~#`r@#V.[IpȣnA~H p;@pš#e"-D#?htx]/O e ͂~j`l,2eFRCiǏnvö99a wleBИ!G@ >)&z$tTAyRp8][ 0M0ښ~,m3u`)|Srq+@A.~Ѥk`N*l.E q Sr(Š\a12L(hca#9JG%?/!q9auM:bMp3i=(A(Z%ܮ‘3'FM Cصv_&H\Z~в 9s ʬDI }@'V0VC?[.@p8S: GY)AE z3_-0P^|ȦSbpzlOM ڵ!):/m]Y?9@Г*AQ!vL!,L^2!f鼣'5aW;@+ΆN3.:fܧMBbfJ7 WU<ΆH圓1儅kn۝w>3mO}u #~([v=r !Q>R%jp i">7q#U&$+`۔-G* CE(e,.E(l6O23:{J{1bk'p.٨c^6m/dn`.f&S%KSU-gd[Rz1Xx…7zďCX'4QڜD@V#]}2@SG{b:txJԛ$Q=*BjÄ7[6NkPч g&Qo ;ִ'+p9@>k%(z_j֐Ob 2r2)<*68MHw-, E_R ^AYyk>P:d&TDbv+{JT@V %jsX`>wI`?9*|1=F}*B' , PHX+XZCQt \5I<~ĺгzrp< q4\S)e,M%|K8$T@Lwڮ5eR7:v*H $(*q:gе.CDd .01X >zԳݏz9Z 3lE:_?E:e}P:DI?9sT^)MިvNr'-7t`GXK- {=N=/3)r*NvOE#=6ژܶ&Ϊ؟ EqD ;Nz59s}ɚ{j5sdaHI>#9dAp AmC'dP/kOCZnyRNR %\<,2PѹQne-K#;-Ai}AӠڅ_0v;bL!GkK '^j!+,)!|:lB2|!@>?@PW60-=`;p[ !5HVn/y#W{C)lnQ>aO={۰X :Ou.1\\8KD=dݛFkcHLSMg"InR!e;~,Gbvkѓfe?1b o&( u,Øp,J /xget /Iy&"R lckwȮK LTAB `c_J3bi; tn_)c oo0/-58j̽Sab{ļB_2]C.SH3 >hZ< 8@i&9u\=A W 't4|?~FCc.n.g9 \>Z?tjEg֎syo‚xl w+!#iU&5Lcpú1Gu=zÚ% Ǐ3Z?E7TGl`nGձKФJൕ* .#7&7adw̿4#l ;Ew`1|]Fڧ{Cݷ2D!?y~tz?z-kyE6Łn=_ʒsfuzZFW99TOO[2•vPa@5U S'-z&t AFԴ$rB$hS!Uzy]@I-n EV!n`}#jk!p Ķ6f!ƜbjtZ7+rQwD!u9S.޾GʋNb0 O?RW ͛mDn<0 #VB;-sw8X*"Iаt:R+׫ m̏D;VBaWW!nyN^tH@`}zd謶C0b3FB '1+鱩pk_,09Ħ]j-!]Y gJ9 W hԔ0:1_RZ.wO#slޞ~PFaZurD[:@,´RP t1]V``壬 ~Fh3N!Y5"Oj}a]Kt;[[n#f֎)n}^CEPS ) _P\S -q₵6'\wx)wx):q&R H2DRAIJx9gQ1p yp Kd֦' "1ióZomQ(Ħ5m`ȥF9H '%L#F+Ρ+ d=v"x&Ņ#Ef/Jv[˳2|ff4M]j,( =W|m!4P"(66@FTr ATä]KK. 9 GKhm:1A@[O@ 7k9V'e_Bi:}Ϻ`*2 2w^+`!Vö߃r/x#~ٜ l@ƣ؝ tmC,`Ϸw)u3_;FUrQ+KQDGC`ќW#1f\~eurIǣJAlc:p*[aN ~XO4YpjkިvNk 4Yh-)N7QC~ ֊%<3VcL4a3kb;{x46޵Lr ԀTy'q **̉?@h4.1z#%';\`gL~i so7 {d1tk Mx#Ԗ䀱;PKD2i8p0'hEyA}G N@w@T~ -q # #OBZWQ~+S>^!Xl{ѰRO"Fߡ ku!%a=S0kp]'7Id- bmm}|Ro1z2 \T\rFP̚J(rWGQգR6#10Hocks "E] -yǏ1h\Ь;oGzO%Y#f,^&i#M$nXp 5ΤPGm "T@+%PVwL=[g;wC+p+&K0qkdjD>Jfҽ&X~[폇#)?}Ԩ@9Ea2" mBnBV}[RkZځoWsHh02dL.E3\) E?d k{A HpOՐ@`~¥FBm_uIڗs.oOVvP}5y''`Кx7|21\`D.{ cOP [t㒆V&ң̓I#QK5vթ:s,90RqO|1apZr/t㿄_ 19`TGnuM:4z@s. <$Z/01T6qx_vUi:- b.G{d[MtE[ Dp &]b#NͯڄCvU<zE_o0H_f?]_ se p.m|]ЌfZGjm0 <u6΀q\+YSnc6X#7e@:lv4\OY\'֮QKj^i9'{fHy8v۴zYH6+nwnV줌zV#70>!>Ć;dW-urk ذ15U xצ l, a l`>RkvzГ] kqʸgJm1 .SG.W5O?GBȸe%(&?;YăJ%TP %oqtP- iHBҚ'&jwY1*إ/ACZQ/8o0?~%#A0P{;xt10`.$ENүw M*CȆer AT7X(JMVN>BNEfg;p@BxjnCb"L#9'ua1\"1az(c!]1 0-HbWcwODE5/O68NsTi,+%w1 r^;2 P/[w8jqz_q?v\ǒ4i;"n-qIfḾ 'XgnȂ32[ JXnfP?'+ӯ^*X:a$<{9S=1/~n.G`p,u-8وqT1n{ag7 ,p^)euό!c@#Sh[xz,drⶺܦpԴHmن:JLF߄XI|mNq "R~ӧ֓O|ϑh]$!^*.(ywqsksp0,+w|-b[G:/ZopuQ?1| o1iA qnyIpHt2dqrKg-B^RsGTr[4Ε4it1`^9a>z -A0Magp7Nqq#YVL<m&t_iG:BM+ȏGmmz|3^L[iCwWAe@6chP -wg鞰"5$-I8j1~Lv%1u𠼝^`*E5#, @bγ,H U\h@(:^#HDV?x.خVGNU8} AHvZk)0j tdٯBU{<ާ+{6vŔGLX_>F=Yԏœ]?-w"ZYWZx[|&KC;BgUE5|q%t>$k=̼\{Rk~8JxY{pTe7yIL@x$@HCMrۍqQrrV uQ23/vgΖ[3n[ֺL*}9~=5t]?wcLueukvI͋Ԭ6쾄g]ofVL.'ɠ3]Mg%M2XI#QLo8$G"'YvI6m${MfxL0' [MǍH8A,I\!K[:/]BBV4fMLh1Cĵ^ɚJU99,YaRNXRX<ðx1wá&Ӊ6Kdϐy/spmʔDxyZ&T4_ 7.̛ϱ"0|qWn oY6SOGQL~"޲JO.:篦'CU*;>~Ȣ?){vp%* ,qÕdTdEqJjR?_fb] fzBj[RW AC11Êٕi*=aa=N*2-ǧ7;ࡥq:0D V\]k1ynk 5%ՌJR«/V4g-o,¨JP#KkQYUaU-gu?O!H+3$J?iG5rm|IaAӺj}|񦷫"*t-&UXԐrmE57Ȕ.U.bbҖbFTFh(0CNVE5NKKR%JlPZ/'BR baⲮU)2Ub9sz*HEtx^VHҢ0E:ѷYyqzڐ0g+RDC8x@Q 2.[x$|3S1DhԴ "*-E `(cH|a5 nשy'kᢢ4 M5,)YO=Gj<|Ģ/JbaE]L (Yj=#0jB'v#޳a YpۚDQҋΨif#cX; {QjcCq$;a^{C6"SZ$M#H\/aIQR$j A 2j.,X%F\#5o'nbFAa5[Rwʰ?Ұ1"kbS)râ޼81#mA7O8ׯ1x҈CYnx8fƖ= 6/P- t_ں=qd^ͻ]B*]oY3 =.3Jlee^ˤ+,¤5,]%hgO>ʙ5C$61T#n\[]]"qX2t́(s")çsauI? 7|O ^'hA&jQ7C}ua{&A,d%< qxN4O}Y7tAVŭ?տCb4&zmSv2ö54XOa'j!|5m]KHwB7,c@gDs.s^& f$m(?|;hcu,OcSֿ|9{h:-ۏX0 Q@0?;4 ݵYp "=΄n`|M ""}5_ݏێT*ciB*j6jS7;pbwh^<Ӓrݝ(-=(z~`s jKg sy [dbSK !pϨr^DqNsz)J2Hvr%"{UKt"zN"¹D~p7`18@D2Z>.ĜO#p?EGhyzСE2(NCˋ>I^}h(yCWrU?%z|64p?=>+Wx L*\LTD18]POU+; E A>J&bdoLKi~j }-1@;3}W:;^>up ]/OGSN.&x1b8|`N`FQ@ˆB62<Ғ?+i>Z%!Vwp 6=EC$E85!g V!=4SSY jc$:wk wP3"TxXs:?8(><.N-*6{OQ_' s~=\ÛqZW 5-+Ĺ8Lɪr8xf9gv3asp }n RXv^n΀+gw bGka2蜆iQ}< ~eZFѡՁtH;/,ƙ\yy1#;FJar5:"<Ȣ 0sJpadOr%8w 4(bN^Phfiig>7?P,(_~*N-_1qxe.<}xa+jͻ>t.'K+0K!4K=8>t5uzm9MT;jKm(Sr:.W¦DtMϿlt{ z)]@ F=\ֲJ7Z0~Hpb'$ jGgzB-W5.#xN&9oV>F2=ִqj[{o|Mn9c;@=hWC'XxYvɺ{qC2^6XU|G.џYU9!(5lI:oR s8q[_ϼQݿ2H،ry4ZI]Yݹ$qɫ3}3p՛IȧlqB؞.5cs"D$AwĊã7>Oxj NJxV_?~o(_onL^|!q=zG\Ț{fk׈011zw8nMZ^f6r+\#ٗ-JZϾ9)d_|#L>;VtlLG[3p [HfЙ?f6m Rƾ:7NI(̆e^ƥN uo|4ΎAg 7-&o؛34L&@}3s2z{tne6f?7XIm3ۡʨ9h 76Rff ΖKo0wpqt܈1P8&f (Nw%ȹ eP>5rUNUYOiNZA1 vX Gډ_.fHhE[b`{[pixMV{PUlëj\ \hL*=*HA^ \r(rERM@yɣUtLhtR딴t24m'i{_g~v ?~梹XYzWu[[U#ov{5] \xa;Hf.a g t~d~؁pN>N8ъ[SaLamjohDlLl%hySPs;Ӫ} C ww1Eќ8gLlkUԭoqj2uPRKy4lUz&­&柠-L3!Y_ny :iV"&𾲏*ī>& pId ]he1M}Z/S4HTJ8pa2vIV&jiV`E3͛zuvl44q]m8Ӿ;LU &J -¬ʐ\&xֽaD^<-|zo_cߣ-0Y)QZ*yN3Y=#B/48 5A2E{yJ4;=X4Fzyѐ`]y=ǩJL<,?˺RW58dV09/RrȮw0AqYM8SY~[y2hUMfkOO#ai.OdaW1 ,PH \u i$4||TM `s`y$.;IQP@ @bx#"b2q܃/$xVDKG:YFDKT9F2p !IFD A>"" ='Άt hi7_NQǟy.~~$aa„&I"^MLGRo:!B.hvL~Mdl!+6ϑjLoIS餒jȮɮnLj޸ܑK'"H9-LrZmu$u,`3O>. KF4,:> /?C[˛ح oMTFpŪ( -rK]BDk!{#kQ`p1x埞b sv`3ņݍ_gP*14vH0TEuP6C{{a$rj8KIDG˹Q֕\4x蟮|ao#`ψQ9ؤHn0U-mhJ鰿:?T~9V$~0^z =jws'3IY>7ϓlxX[lW֞MHkRHՒ8G!-MBP8'rb;q.9;svwݙ̬oAЦV"- TB/HAR 塔@T*ٵ&z?r=ޥ}VϳL;ƈ.])UI ӱA"*p#6|FSrLvegsZrqOтz4\jp:v3t1kuur\ϡAY0!4!I8JN4x9 Rݬ,԰mu9ltnjYݲfSDRc &0]Tϥiyz6ux?jwқobiH Վ_zgkm?*"iPǫ<#DH:3" w$ۇc tKG`L6N6 U🡹]) ǿ&_#J NH"7O {p(Qxtx_LRB SR1OpR 蔎_ϝ674A t꙳}83G|Y7|׳93$xnd֭!T`~x\Ucc.יvņ`,c }y LctFw eo_% #|2 +cXz/fdmDF0ø/WIBDmpD /pPA /A\ϟX-I)b %Tb qL"$"j-dQF`,u#-a("1nU829Plژ {Iiuoyjk5ohlFIO&Go' h!pf2GE:y)BY!"Eӯ#"GM;$"S6","KH/"ZM?1<Ӷef̆AILYƢwy}恸~pku; ͘~ Ʈٰ ,)p_j[aG[j,hh#u ͏Jwg8R(|*G}g6Dkql65Q/}'εc?/\ <64~_;shIHN<70Qy5_]}qm_>;n P[J9]N-ja, <`~Ý$TJK.Q/]t˺]7[.pLܝmTd$d2 N(Ͽ4{r'+7xߛ@\k+-Km[.Uwj\T]4lGk=ø0 {ӬӴ-VOR*( _ְȴб?01mWcAeýƕDqxqS ;:*-Gts[[^>y蜋bU]>_}!m}4ѽXI"w\j^~n>~b;lAkߑZEd1R=X <\X#̚=>έpE g׊E-=ԑݐJߟ]aWbkFeڔGl,e}[7tX*w.Jb˗ma;JfǖstYK|xvm[&̙ CZ Օ L,]׊ ޳g[~ۘԕ yA ̥DTҢAlc}Ë,Goo[hy;j;.k.2׶>D!>Q4mِr5d43[q[.?^weEZOY8J-$l󿞥WxUWyPW}*(eAQ"n1b$'(ĵ&FI2f&4ii.Y&ˌvƘ~?{wsޗ0o}SuMM}{]U$Tigl)~Ϟ7Ǡ6 ٠)옔2ɦ$0JB,MLڋ-`jܭ- o=Bs[4^F7yYIvy[#fØ-p3œB^= uNQ$ ܇aqjEp&W]ɶ z)XMR!L6L) KjSVQhuZ#F?O8[ӪTHU zgZ0d͖LEӫ%4hӀW2d~^&tQ- )4.)C׌P|UVG U3%ݑ5L+nbpJ߾=Cw/ۄnѕS1V7lCnT6KrTFz `eܒEhm"duX ܡmiXD!/}!$.3"se q9B7JhFYQl娝3 ɴ Z7ӒlX{z&͈Cq6xusEnGѿge UzYpu=E*56Cb+KC=&}拠5q+f::B86]dz%rio3;J/[r*ZeI-o tcB$mqKG [bP2'g҇ !4m)C@9o&aBX \ďLĐ7q&TxGÉ)bȋ)`*p[S03@q*T>7 m:2DRAV!4*kǁ?3lXܺ;`BgȆ h5JVS,"&yZT`d?k=eǂ9{v躳O3﮻胤Fx.ya ;!GrPBwC[]:W4âU灶w7ҹd ph6&@1 bSĒSiaɌ(I5\H6E ڰq}7m}+L Eiu )=GH/"Cz =#.z5G3NPeFvoL^]ͮ\ʊUFҚ`U5Njv$ͦhv_ssvZJ[- %csYY}"SJ%]ӆVڥY|?KXqewuu#ӥwSH’?vϢHX DzRn842cD@еX1b^aHȱUF?Q6E4'1{Kx*\==@A?DH:.ԾHK# $n:ߒ ?J(}Jk8I Ō@t&4:Ա)3@@, ^j)4j-̲ ġ[s#mBRbзۻ7hG[Qɖpa}[H]q U6 D]{Y5'^EL Dv\._4n-=CȔ&c]}s E m pWv/cBZ`Z`[cMȡXA:t+0^D/hNf@ 4Ůr^Iż23ȏvw]۷L,4c#>`9Jg/F9"XĐ4:E1 NoQLzQk3@zg{@ e$y`;H,vmHwd #OoSC/NP AI!EVik\|j̴HZDf;>6;IEo{\Jo?v|P$cV[d?C(?I/vA-:\:x4٫K8R}YUT P;!DEc R)aELPrd]ar$Gv냹9%/qx2Q#<47-YhףyL?>c4ʣ\<t3K;V< <I/tc*SAT0TlhO1\Ѡ"6=7׆+9~,'4ZcF,9*P_<EfS‰E,='}$:YĢsrM t9")T2EN$[}~ş.]!EED߄@|*I2!w]&evr>k6qv^@ߣqOԲ>5S9z%=vX+g\B5b 4RI5s)u)>8.^ŜJw$/∍#hZ9R\[h.jkoҽ3OIGu{G<6wOt3EY~,xMUilTUλw2mM  lo_ K.3t BN;(r@W[ZD `$AIĪAc;?s|{ww]2y/#*\('\.g~.[=+Q%SjB6?l% ʢ*"0h/ys@"p:LYqyigjz؈A~dxôQET¢cה@ߣ 0ꐺ]"IK!0d 0#ȏ9D5]67N)ygSaeJI=- Nq#RڇHyw~Su# 7ܷp( j. ً+ʘ5 3$Ypm|8 eQ-;1<$RQU`&A[nEܺJA[0XPk}KUMyDdڮ ^ӹy-D" yn")p!+z"KV~w˨hPZPIuT-:QQۅ8ZnC`(%xPTQ’0(g=+  /7%Gx J%`++$ʶe.&5Y+UQO%M5W<n;|^uŧNv`o|SA JCQx3a:#/k(/f+,2JO1yn?dDMu,9 TV9 M1P=T!ߧǠm >75 !fWCbs+ºBCB0ٲ%a\u ~H[ ;vnGHC: @O I]B&J*$_Eb? Tk'wmvg[C䠽WYQ} GbBO:Ѫ_1T*"DC܋}v*`]G.O4շC'eYr*v&p$uFMx;7aJ; 䅮4|QN>Y6C psDUͱp? k8~;qϜp?feh0ZTd?I> Г,b?" A=q{ |~O"QxM*7;yN/nEIJfOvXD]l/iKScaGә0f YORX$+@ у/C Dk^V$`G֡HVdjJqe5GekX$c;~6fyjAJçnX'qHM`tWk# 2Z_5^2;ـ53{FAvclU3 `ZqcY60k,5ex ߁R6d&Ƭ<4rub#TȤTNfOf2LU3O0ǹ:QxHND7; U?,xfΝ#}3X@txES[LW9S[Y& 3/V馭ҖF11X$mc[]rۥI5i_>_|XojwîezTr3}C{fx ӽ;k1{Y 6FEv͛"em_p˦ J+kхQUѬ ?zUt~ql,O1iOi} t[P.wР}yvw<Peo(\Ynh/qn8Гjj[\P縩填i4YLTvnr(@:{:+I{;i7wʮKK} bkZqn*\M L&'[VdyŜƷRdE7=ЦH=D0LXկ0K˒dp!ptCw0s_җahmG#TLCk2wiHSF ߕ rď%Ls&f{bgڍ?"t !v$*őH.!UJ%%4w ;us]_XJ&):YEbw?XB/&yOXL*]Mb - 5Cc[u+wAiI1;f͙ X056{ z*kDRy;5'!o!@o ƟiLδOF閭ϲEԗZuV-0jXw.lh9 xrq: y:72 p%. Pi:== 1wOs8^03N{303+;2aԎgŜlAŏdm"aiynI5m;*YTb_uRU>ϝ5ֲxfd 9Q:ḃ >`8D"?1*W,@;EEEYٺ24y0,z<-}*LZI:_s}JT!Yu*+ۯL!C :=$ _IV백*E{/VsJ'"ϊqsԒ3o=ffsV^B0;RHRYu]==Q$ *૾F3%ID^%)WlzxZ ~} yxwclIxbk򰨖WԬNekrܓ~tXK& M<_b9pEqK>`C#䶖= M )4/I39qN~ݐQYrllt%Y9..h 2Ͷb!YwÍ.g n1W}Ę[>Yf$V{Gj&*gzž6Pް;`IUnfH,kTYH/1ҬX^ndm_! 1C;b"Iٴʵ;+曽k& Q[gH+h>2~XAr:XPz[>krY{r,ӑcH(lr3_|}fudX4 {sw $=PN"fzur$( GE Ӂr}y֙+a2n?.! +*ۭ RuF[D[)OQ府ρ`gy]6_;4Z LKvzsF*̡F,JT;VTؙe%v^1 }<9/ftAAFi- 0wɹHMDZmtไa|MWU3t0H!S0#"+rtwbulu:)&hᾃ0wTkrj 껅-Lkq/n%}+5_ $ m덀tB >8Z o#h$6ն@gVKxUY xs3Ɵ.k"Evt7%3۱"YU)pT qMHOQ:cpHr!w\OY}$tvXԋiJ~U6 $:--KĚ:6k&mg5>(g P@:_|m]BȴZ2k0 ;,ML " ĥtEVi^\'s4U?e,+MBq@!@ciqj .Au>q!iϴCq \.c,t=vSU ƁțTrp?߾STٽiMs/~I\ww+Mz"z/~_:'?7|5~._@?%~ NckU4]Szg+'3F &w1rL'{tO_=*!\+q0G+!qrDXOfkfcyzjR61D뛞s2iB+6Ɠϙ, | \nv&\Nn5N%X8T!5MG |?z*83" ƿpa)LdvL@ؚfؒ* @OtSpQX Dh]uUxdxZ$l+jdxY+ q#W_~2ȷVƼr|6#,F\0kw5#"k/|JqI DHi85L-^l DW0WA"F&@&[U>BD1N^x`1'mboj=AGw!̶%!Җy67h(6 =v[f=mAl{b:CC%5joaVt,.$y!oyڑjdִL\liť,sn^<xv0}E͈Z !lY7sU1V@'|-e[}yY0)ձzu<> I )T Xq;tQTR}B$9(hktۀLqGxܴa*gDa Z*.mQ}DSzT-%ڑtYHSa\ X‡Pa1HP g#": ,BS1g%, $ޅ$X/|-ctp! ~NB}B15r 0Z }j&vH;>o%X^V) 71QSʴj)f({Rl8=25R%%3՘Ō{?ߴƆ#}]ԜBآs=Κ{| LUz uNc)w6`X(wOX} "ObŅ%pZ{`q'OSz(KQ<#Żp+~J] jCZ4LhQBCW(󞾦xɊZ0NLs>o(XЕ&PZ}^eok[[hFKfRU25򒐴'ݞA[۹ۍ|4)@vqX1d+0:/蒾4Çr`A%1\?IIi`!;aɽ 'Ծ^C A@ޠC~s3xyfyIp23VD6 h ]?OU=3l\~%mW8@X|XMJ~SrSmtמt5_v ~&/㸌9s-BIqC ^gr6 9^CVTY :A-M(k_RËSy&;8|T)Mwp877Qݩbi9S~R^"oW|FQ&7 tt5ŔhNirN;yڧx*ۣX|2Sͱ(@֜ӳ}#28r9QUjW0zRMT[ըBX,,KBx©(Hw;p +a؜ ކļ=ۤjU>\YkpVL?T@tLJү Y`6ɲ)+egr!Wȗ2+u`"?7oëjlˋރPRg툒Jc7%@ -dWNXG8AemRT^P4ٹ/ߺzµR[@ 4́ e R#0&׎ALvgrclY;VӂxeRARjJ9t%M21 ;7#58C] SJHa'QQV-M A*Py1Zs˚Ka742eflG軧 #?f"|Ď'H4d_*IϤkqB{*wۢL}:}67C1c3,Ήؤ-WU+ Ӄ.?=g"u/*QXҞ .ř-ee=qWw8g]q2nLU?ADzbNug4N酝ZP{<sv?5Ԥ7(HG8vpFs"!Ψ)$Ϙt|ēy^>6@~f,S:2/`>ӱ=]Z'TfQ&O0CYR(t$UJP3b(;L^"+NVVA_ k;mAv`7C+pso{LL |}ovygjQ\KsېX9ϒ ɶ ʵ)Fe;kA q'KastwmLDue$,QBg.k}FӃ֓G{ i4W YLd/h*T$mQ:ׁup4HJ#كp ឰ4C_`KД!a8P6![԰"\86:ƝHuL%9Qmo+&櫌Lį;ĵ#3hB',nkP,X :&PN!ʖu# ;N%qIt,ڹ ?okn؆ ~kPAyM͠)C '^ II]%m#avИѶ- a8 "w̪^  {)OxԺŠm#~T3b$ol@A1\ Ӿ~h1u.uF_S:U er*gȟYCFX4T%os1?AM];CT;d?05s{8.KQ3^ :L)ƃP]f܇x@}@vL.HYaX?[" +Ą -QNuS :\2*{s`7_⮌kRZ'Bl^"jo;,*<ؽP ) ME#>xʀ ČTxF܁ Q4*6w'ނIJݔ+EKcqr1n?g_"M_5C/Uҍd43!2>xMu09Vynt;mGO%R^3s; 2%H2>l5Sz)qpfBG]&.[|²L baFlJX8#.VRvE @QUUz|m#=p.[:sڄ>-Q@wuem^A*b>oc(?6d^}x`k:u\9/ĩ'Pޘ*w0uxؐ:Lq`&~Y)x ;R2R~ (Վ]:{:w>`/4st[3sL#@qoٸv6;„q/`n4?v"4֜ a FK43E[P Fۢ+gH%ׂR8PP;3듨XQO$HY+fj] D(8&%͞E IZխn7 qLۅMEQ,Cf?e[}V?s*fez$6~UICe^̨. j,1Z7H -y+>G "¿ZÈdJw[J;K : J&#j*찧FKc0iݙi;k~=*Շp8,FcB.Oq)Ĭ9P?ú/wj]\U{1FhgL!II:/UBC\r2措|f|ı`oCF(WsƗȠvnsj{x]&>MXSD#4PSYB}NVq׆k}B< Lf{FgP;-_Յ,q.3~x92OzMJ{wՌ?⁎VCEzWh_ThJ|"2彇 @[֡:a A,{?*:mUkF-}GnvJEcEx\eq@:Ċ=O1$#4-\sЅq[*o fh(t e`qs8R8,99}?b'lm=[s@nP;7+3p#J{05R Z\qKRb:h K ,tצDl8uN}qv8l DPH%}9x킠v5}a-Zc,:ysn=l]xdvʑp#sMG.IotsaeYXu$jBS Ju?nÝ@q{b> s.[8Ttԇx A me%tX:I{ )c >&PFe#oDr!^l~DN<1S T5So+c^c]52fb[V7s pWi.ltmV"(7 qtkcZ ˿m/Qya~^3ʥGRC1T/YKk>Ζ]ODz yŽj!HxmSkA璍 ѠyUg- AC|"*ٝ/w۝9gfD`+ly[ Vvoϻ'v=ŧү/WgҧΦ~*}޿-;ҏN%=5OgfÂ!wƲXDCJ@.(%Τ@Qf?6}^=!GbKg*ɉK'1GYEZ<?de) dNޱypkmB˸-0MBΈ|Q̕w J# Ry,6%dܚt|rA~F"S'ۥMN읶t%Y hxVAG;(PBHKK#h+h7.fjLOըz;݀mABVn\!rN;sOHUwg1֪z}o޻g?|{/<[8?059k7o]9T-Ҟ&or)7fXZx!qN(+'B+JLh\^-/<(Lf˹Dx#.&)6CH:"-L&J+ %}‘="!"15H J8bl&ʜ6j@+m̨~RBQH^\ C)S>@:ޢ⛋\%r0}+z$9Y|(C<$eşŋ|ZL{GMh+ǸW"9hߕ^훃+U*HhEn'@oʘf5 *c,$eLǙ\2KAUh{HPTNԴLj4RN),qci}X>SEq(8nwqܘHlj,JW8O +*ɹiqk)7[»r[\C _K o{iɫ?^MG^οWDWMCz04дg/ϞɆ-Fg5~s=SMC*މr 9pBl& -^ H N}H P!0?jEWbCO\~sp%vk{ 3GJ"p! R6 FwǕڂ S+ Q?^@p^1*\:hGLr@ٯvN*ZB΁.Lj^Ǹ?"äK9ĆqK41.E1U2`j K<$z+1 s3%[qM2#, k1!҇Ajzoe;yZ n[{Ojq, R n*rzTQcc 35c`G+HCq09PUa0vd::oi9֔瘳C).7bKj6pC0\a ]-Z4k ǴUKi7+QL+ܧM!ԓP 5!HLBYj'h|06-Ȕ&Q ͒]`?xT(LC:eBWJ0iݙb??G_)3q A2Cdic5 _k{Rbrq_*`_ D5S{_Z^e.}hos --_I٩0KL` XW/Tl=䜍sUbv)fCfKk0B0ML I0Yip~8ݹl:5n/ܩx4WΫ|c^:DsP7\Z(Tu$:gJI kfaPԥ \UQ9u#+[R3?UF`$]`j}.(#8<8}鳣2{GSQpxf Y81Nh* nx}V]lc_pcc|f 6`bcwmͯCݹس3;w5?YfPA*UUs*5UEUڷRWQVmԊ6mRJчܙb {=|;_{5"Rҥ;MKo7@T*_kxHMkZ&ĥ1 ם[Eqfİ5fC[ HQD'#KpSVAqy{SMG%:)I1ӎjKy*0ŪUz $irJ <\`IJSTaqNa'p0VY]yn$8Y=_T!UpO|+Ģ1MöKV).gV.\-jx6b)dZi[Vr3Obg`š3+Ž1x\WrW\kW/mn,"1~usr ?,k N0I1d.0p,7f 35)N"[s߿km,,ζ+ղXX ~VsS <pzGkdV)b2k]`@a'V7#˫;f巿*O S;:-Ȍ o]2uFW~9("_ fR_ȲK r~2nFШ4L`$: a"tzʹ-,P[n=Tc.v55߿;Zvؠ*c쾰WUqY.n ign$-۳Vs9o1O7G\itQVRj|C>|b¥c@k誁odD9 5[ 'Z|U{R*1{vH >9Z=j{C5WdNB4 8ChZ Iཞ;(zWD5df %~ZvPŃ@&ؽ!דp:K3DX Rmf+8Ƕql+~ $Șyfd,ps;iweQ)j811%SvlƎ!=΁UehsjDLiqxxY7TAs;Bѣ.`#8h>8D -_SQ_pݠB; MXr%i'I(Í@a$RN4 t6ٵo`~vD~ /w?9|NЖa0$3bҕP6tڇCps(\Z.а#Wyd~p6gL>iRxmtd>WV[:[:w ,Z] ri,?< =\H5.E[adžcgD4h]:kf,.ރI ̄Sސ2e|=w) (5P'Sd__L(,bӅwO|7Ka]-mzAU@HTLQˉ)uadY+g矟̛U-^j f֬UF)Կ_W_<x}R]HTAfV,4-@M32b+J3%֠ٽݻ;ިpC?Nc?A<YACKQTTj(|ssP!̛e:nPl砂0-$煟QgNў6nBt8 >en +R8c [شҶ8$,Rxx?V.)$T}D>OOjqڸ,8p|2WvCuƪ /CPP{=#9yFDʵsFLXM΀xZCZk΃GuUS] Cc#fsb38 HBHR9&Sٌ$rf NOŸ@׷Kv+ql4Ϝ oJ7±+$$Hno"8:7M(މر*++++Cӛh=]7Yp> ~fyP*\ĮV[΂hj|$io/|2('/x-n(ZoD=gQz>_3 $"ҿ YU/oM8ZuMo/&6Sʹ'67}»`4 ɷV4Lf:VmZ]\>?|}Y< ތo g6v71K, >Xx,b x lvv?'jQ 8^, )!%>YV-5Mu6Ķ4h;? F㍂m 2QP%qtWQUOu|`ڬ`:X-#,~Y] ͻ8y}J,^$L*3g`2,)U1Ni6vtfG:UX} ($fxNXe Q2HϬcuLf̄GK?}qBT=w|鯏5<^^(}f;ẆIlE`=?EoG櫻I6Dɷ6k'ozN~9{%5;L5ut%fc9qE6"3@h Y2fphf1D{5'o_8*x:n :59^$Th"eF#-?7aQQ_#"&J6#rDB@bNt5Ʒ|%ew+V S}'DAxTx;N숇sh6*FX[N0asjvxpe p pWJ;RZAuLxǥ8_Tx !\)P5*ڜ?0Tԟ;uoE,rOWmvO#XM@P3PϞI)<`[=. #o=fIv%ǰx&JUN\Wo_t!=}A:C'=G g[Xx|:Q)M;0тMPn<(H=E `:o ; XJēlz$sb4[EFG4*^.X%[8w㷛l);uԾSxiG2(w.z 79,8vftݱE'&q6_$7h͒#rM37K]$[Ы2B4CI@$ } 8b y& ɆeP:EHOshH/}4hMVW'UAIl8zq1 aW0z뉦cĤ,{}:Uz+^@1(Cq η_˕XH"h10??VG bڢ Frh} FʒFUz^r"Em}$G8y5Na1ygAăQ&[?:B!g5ꭀ "GGW(FCt߆ <b4E\II -x^z+vä[Q><&}@ǨG@.NӐf2X҆Qyı.ES@ ])iF!( R6>34 M"Y=7`a5]V?ֿ81w#W*fJ6VU;n.`ؽkuR~9'm-7g]5^ɯǏ͌QTY-Cul!ނSbw -Zr Wj Wzy@Օ;ev?`QjEweRp)%28]"pC7gnm.s6Οd\琭Ԋ }h3w,'t/d uow5&y'X/ߚ-xLU[VW޶@8ŗ^bd7\#LtG" K'5Qޏd¿og`h_c7F㐾8Q:>MlClf[ h3ƿ#~Mxδ2'iӟy/t'-=wkW!7;ū0\GDȖZͶ@Ukq3Jܰ-1#8!+`Au;TSMޏvn(ѩDzA=}*WD["j\ߗ[ȋ[L`ajuo{OJy$Gl\݊+5}":SdZF:!0V9ػJwƣr N<9.Dpe,d ayLYtVd n!A9Ǡ ;WgI UdTd r"{Ja%}W9S "lQ"W뾆 x?oݖդM#Qd'9cZfV@qobH0 &_wI4|u~zԲ@{IM?0 wˆeW>h@q>ej^Nhipзy'z e<Fic{+'L ERw0xD |9G+Ol q4ǵ]@r=j+%ʓ,*i'H"wnB;K 5\4  *ܾojxw 9,~VD F[.S[`zBw%e8JCjOP*ZnC/S2#@{]`6J`p Td(jcDrPLce yy+I1V_(29?H#[(C՗Rͮ9.FJp%U (ubàdܡ͝[>f]Tw|FIqvjrzUm$޶Zf9ɈC>뗬FƮpx)tg-}猤c$63ϣCO]LV]Dsussw0/Yi}`_Lj&1 Z::R4*w/Xv形4)|^lMׂm+ZN5yk9-jXEX.crH?\9TRg+24:g)QXynp)uNxL qI]4~/ ,@Q<4.|Ҥz_ m?COZCA(X3%]>LEz4-5K]9#ϩ89`:I Pki"4-4([a(gB||}M_0EP}ߚ$P>JGBqQ hw BE1@@k^ _H~O*Fc5uOm Wz-4@u*fi5TZRpslVRr&yWG`P0۔zpإ{X^红@] B> #]DA?^ џzkh_mCxs$BQ3GoJ"sNǦD2mO ʔz]) Ɋah}uoMњƻS+8={d+ _wL؛{?%ޯ"-.4&Bɽ,Hl Bh]Wd3EJb8McoC>Wų%$ 4\[V\^=} 8L1#uPӃ +!WK|#Qug;ԥ:UձO{S’E|m 4<36 |;`YU.A"@*=Zp$-̃fIP;8PڝfAhĮC,P`FО pcj%li 4g,ҠWmf0УM}' wjE*-CI`jO7Hsx#JI(J7 x )CQe35fC܃Vse8vDrM8Uy^Z$V-#_PԢkbB>rD!u;aW/R&9zymY`zw$PGAȼFƝf:>F!BNZpS`y%QYgRXv[h}[օz+ 瀓+ cqN 6ȅJ<ՂEJo4筋5joÜv1 K؝bh}~GyFw٭p_v"$5M)m-I_j}6qB@qaEPHgx]Ge/ 3.qQarZZsy%_[ZxWnR5*~XoA[—WA'SNDa)fX)'2/ 6lnсbCIJ @F gEXD}ZmW0sOuax&r4yx᜞E&"3T,cl$Pi*~6͐`YVn  u1ģ?yYaՌ@4ަAv@#'}//zV>4p="oF)?Pc*9fS26ii/ppe柇mSuY1$}Iܤ"PdF#=5pCUSUZoas>']/kk a \%cJW:䞏'B @GKA =u@}' 0PH A1BAA[+U[H٠3z"%@89<&tqE<==|5殷 /*sg@>wZŀbO=P!rs5"ϕW0Rt;z4ۉZWO032];+9i8䘟pfCG5bͯz(܅Sù6kvg1"KHKALKi(wHK3(2s`~CM<*HhGdz@xnp) kOxIlPꡜ S1jEvXz-i<~@.Nha.wk1 &eW(,YhB\<m3?mz٭R8^{ 3TY4}ƦV- \K;  Fp )9@P Pܖ;!t`GcWiHs. ;.M]Ѯtb RUE_Qy{Zԃ|TUqW]G+4%PѦD[yy"ܨRX~1^jq+TԢ-:~?9h2&0?>A`p"XT]bчG= 1"B6->`^ 7xgm[U?;Pw0ܗN @"ScWHP/]vBwz/܈̫C!G[xҪi^G YJG _UiWW]".'PxūR5Bbc(iBm3܉Nndzp@y#ճU孮@oڢ!+:HQKj#-QDkiC QlEZy>C:'P Dv`b\%23?_xOV' 9"\xwtӏ^f/9`/6gk[$2gx([ # г7:qik,ꀃ)>0ʢV'x_97KTΚp3}13d3و-7T/xX WlբK"N !4yfSz(LcY[]jlփ;W[V?7W(AG!(R(hHkGWQY)=C񴣦Y^P7L;gFG(:pjTF}^@_p@r%3Syv?Nu@]Kt ސ,{n ZTOL_]P\S5h StF「p5N!sifaMnHY尸 bC ۱TT}lz4ӽIa=!v8_]^ W/ӫ z/Tٓf#k!zO#~nˌvzD"L&ۄ*=`g"b!/) h`#ߠ0X 2wVV[^ޖhye

y`1px){}QS7[d=ꗂi/Җ쭢+FP@tN7HluI㐛)OWЁ&kb7>7AZErsW)l,l:h㎳q[-"㩅jkIօb<ÿ(թ2CqW6q '_܄!c[7ە/u$٩׈\ݖP0).QᑨC萞öxAU(P\4aKlN˱Ux:ѽ:?S3؍Qt''0l\᭮䤨BkeнՕ tTJ+W!1+ݨ+a\^L։S L-tr{Rk\#i+oc35=*O!hAP3U%;D5|y^eS-ajx4҆\37 eɐ䠃؀JWjQcU*`V3b:ʠtN s -g Ppp)ԃb!"(bp[X,I>sh 跡aT˒t3 {D !䚾4 ]Wom0Es~} ?@-lNĩ;x2$6o6WA +ˇPGfz_I QnH):c@?UZk'WhCFMrGM>9_ (Gh 4 ڥ(l5&5-<hf &0$ĄwԯF:nIY ==/kF5[U4ǾP#sGMʃa1 z΂ꪃo=70`;lv0 h+BiuWJJ^FՒ0' @kZKK'8KS-na) C=Q?8 / *lӏ{vȂlĆm*2'y:ױCrwZo͘)9}iimmL[z`ib" $ ޼N~-е6)*R_0Q Ko,8^|`)ĩ^35!(=_'{E o/+/>>Nw ȴi)aoG^z൧D !Zw'Y&b<;=Q}05}m[}3y͛ڦ7TL[a&)Ѣ~+cK<)HT} ԈGsx}XipĮfq#1A`%@$cH]69p\lF?L,UىRI*Ĺ\8)QWRI7_~u=b ͖ݷf3nug}Oyf2ٸ {m6n}OYvDFdezZ0Xl[05%{F"ԸMNf3x, /T[TIUoؑlf?Gu K,2BϴbJσp>Eಱa5 |{lܩpYuF4gի*v,j"p)ѳN8e7a"-SSOP;ԗ0: \Ͼ\x dD0_QZxƪZZ!oZJ [conX R2[#GU](䷆-;o!s50m&`dCfgـeۖd@SP8"v(ŶX}YoSEŠ&`XK~3gvd{F?3HԈRȎ-%5cR`5!@+|Vh> &+?*f'E&%l).Yp|HYpeKfV6fGw5ڂv?pUhrė,B7 1<.)q6F{"/bƌ4v0z@Zy xӜF8jA_A]#q̯12%՗skdd)}*831 aLM5J:c<7oeH90`T$+NҡfQyl@W* # uAxPI>un{ 8aaw+>< Y75~[23L?#`vNI(J$ [8pbk-amM`wRԺ)0IPy~ Yښt؆k8&&%\9`7ؾ؀xX:mkzG=`` 2Lk9mh$xU&,%|fJ Q"Ҋ6q=iv:_hƀRXۇ=WWۊK ?GQʈHgxfFvF 2̀|Voy*B\f44A$>(.3P*nС1Nz[0e{f'ϿXĺeH8_վoeqwenBK23~+`"T)r4As"TwΚ*Cȃgu6K f`P^[B}I-d,s~t V?zk* * L$B=ͧ:PffL@:*{,Ȼn;c,tW݆IH dË%-i: S+5XJ$!M nGQ>/+0ގH;ѩ4vϿ4csHмFΊ.y.[G71Ӱ*~<)qQ6?nEdbeogav'\BcwH;Ezf.3O "LHk|f.&dx7v6Z ߮ݴADBkzf.K/:cѺ@Ӻ+pj>j`dvmKx27&A9ji-k?Gr\fjg!v:>f7%g{@clʟ[Au=ZOuVzG9BܞDL?=:XRU{.lk?v3w#^MhgcotR5Bt ,~0"ZTÛX9ؾD>;1pg佲wSuG=tt<Bu_ gJyv!V k=֓& Cjљϗتw_I0B;xExEjh@Ք C~ut@ݗ|nq_~ =|n<|vyO>zyǾS溯C;$w,VKg,G[W* w|*swW[8.y"jdVW쪀W+az j%!w6F^JO.aO_x=V{PT{ƀ2Dy-;cF( Y.,hTE5XGܼJ6cR_ _DR!VDPm3yIV5 s\phEsYzF$ryC3 ye4xY"Kߘ{ȁ֨X<hh|Q[';棕gno4 &=$';yUrj}Cup'Uj*&{̍B 0'hQ*'gJ |-w E%nɒbk*M\ ]Ů]cyMC/ DT!ɨ%'4żv@4jhpfU4)?㈪'krsmZ5D`tm9\n5ĸ0_egYqJԛDa4/& C봰Dex202D$Yi̙cUv^5s厷u0WD7$ 2Ur OBxZEd?w`}h\p.1EZ"pK./V1rh:4nEC?,R~I5&>(ie]@dnq9轎ez7 ,R,>UKዲl"ʰeD:sKE=b#Q neMhde.[Ue.42dN`-(4DCOHY=i`XE Xjrg-x TZ[PFa%"_7bdo}hMΆbX{{JoE`u*y"P(oV価 -lM1> ޣv;N"iYL:xQE嬝(2jzĘAѼ!Z Α$)v]%ha#GN^4}!8vPڶwxOY\*b=ux=W."Ȱ l6i0?'> GULu!Ѿ<L@9p1!ectr9v=>'i" UV:6N ؕFą ՞ hZZK58;]Ls⽕b_WJG^$2 ٵU{*oSuEOdW#{qz31 8áL,:q,|f#~;ZʆL:ge 8,>\Ldsrx|v F? F;ϹWs[Jq M$\0Y㛘h!&:?gYʝ`0B:.`tgK.&܆d0&|Evf"b~%&~x,JR*(D/q+ ' %0m UBL: CvHw09Xa5 {>T0s&N}V9sf {x9s;p! aaqv޾_ (hʦsv|zu3rq7df'D@m^c$˵?5#XN$٤I*CBIJcSL(v',V*:]KIe˲wWDׯ_~+__w_4Z)ULg}dPT'ݹꑤ3 J;W䴸~TѼSdPMIeHizU[ iJ/+ɾ/L{]]aE{_d?yԱ2%\~}17E;ӯ:q%I2J6ҺVM`OI!*SLQ׮*%@AJx;Ee gS8*DT'ӊ19dT9'$)g52)f 8&%*&/e>,jb zOVSv+BTpoq A7Κ3b\$RPUt&#܂WOɨřHtb$r9K`")I%2K7ȔNRwޗ{ZxyB yE'q%ݡ$>P?SLJMrrVX%idtm [@j"0AK!~o: 4RbbFMҷ+lB,i}$tMs% I\N1ȝ{VCVGV R<%iëb@Yo՘KKxVAVdPI+wsM)HZ$Y͉t}%c7lxǀp^9IU`U+k\Z'VI0Z*/Q۷2ReQ멈*[׼i'+O]sWJv> 5|ayгiȌ$ t(tq\PYiaC߅+mvP~ pSzF9fJ)XD;Ø]] ІVOI#줐}IFB>J27 az rk)9v}-[ϲ[KwgBwܹ T1D4fu197 X QRJLIu%K|;[I KPڌ/?AQk^q(s}>5Z`Bv߼h8<.As \ ~bFYnXnծcy-Nz[FavB sgfIz (I]& Vlʶn2 yGJQAVbLmRHV>˛Xt!:؍DxT@&/u(qpxpwt^[nl쮮wuհ1OwsO37ӪӍrn 7d̀)Ye\g2t-h;WxXzLuVe]m88jZǏiy $kpSA=9DL3>V˂Nq; ؾ^gbowg~F.Y2:1lE,+9ըuTP…zU420z`ވnc {+8!pTAss;\x&LR:gS jӜY~`vG9wz<,ǯ)7j] s3 E Ń(V,eq L_B?=7 nj\>4.C+^rfls˥8sGĴ!~Í+HհH#=qC8R$w]beG#x}p(h~n-|siՈѤцC ٰX% )hbfC3;ֱ:Xb7 ms[9fZҌ*%T.n@/)d =t˘k&H$tqW~2 aЩ(;KnVT]j b ,te[̚.c"yЂ/޲Pd3m?q"^ Ng.A$􌌵U)CW'N1LR1XIFB v2qҏ!87O >P.ʌ:*ߋ1>.K%;Ybؠ_.=wsZFv pluDhҔ4AB dPN['*7C,xڱp9%yͱc@@yK98KQBy-BGҷ<{; aa9NoILx X>'iי5=Uty.sE"8 }}: MT%qI>($3 ͱ@{H;K !(%N,Q1)4[ :ӾﺧX@P @ʮR,Ef]N@0@DoUTe,Ţq<t5+СݺTEq Q?zOF4xN}][]!?}H% >`s!H-%3=䂽=ڵef,0ѶF QvkF< Λ &[ȉk*x[0ǾB , )JqIdwÍ|Kڰx ôĆf:15[_MT[cue|韌?ƻa 'ڼh*ֺn!Q9RK2Hxg\+wAօG s9Lpn#GmR"2I9&k)`+hвܦ*18R [pȒp<2t`A[NX0 wl2h~>]~"cg?)<*E>t2ɒ551.%2J e__o[Bf D:ٳmAQ7"1XC{VbI=.9,8A( z'h "KէqA.ڰʝ8tN8.'ӽZK!ob2ajXcL7=Aɧ|c>_ŲG=LS ߔ*|t(qD`5DS&M1+:Iv,ײ3K$kiC"Bɞ`\J0@ V,OO?WLy^*^nOg#.!Jﶺar;5}#y\~/kr oQLj>Q&ŝu:|DUJ2,ұ 'uix_ipI/Ο=[WvG">XC; Q9ӺY˃E/g/2m˙dt/9k1\v)OvQ^lU9&@nȷ+"tPFt?/@o~:^&Sa2fSikX%zAIyZ]z(KyfK$Kt89+$flT\}-yvjTYpNv[$S!߆ۗǪ b?g&BwP%BGۏ|!!7./%

Ec_m:=`Oߤ,/85Ǔr qq= ,?)nxƸ C "\Ą=O tUA[t<AT>ӸDFYGŧ xx5p" /wgk[9Dg|%D?zFXa(5aW+r*_+EX@ү+lQ+ q0p;XFkf ]CkO;.p_n!?$zqE .Ĩng $ҏkrqGB]ܶS@2 9˜-#W2_{󹺵bpa \ͲA8?Mz>-k&_ukFy7ox|vq~WT[頪b_HXc/˚2 []ۼBԽ.ׯUӺb]qFR1|kʑe u׮[~T4kzGW+KR!^·ҵ_:2ya]zܳp+ 4.,X&/U{C,&6f9Zq6c{cVs'u[& z*wG_"mf@g൉Z?nbλИ3ľ㢹 3ֽנvc }GZD!gC?zqV; !W#c$\.:oklm_»~hA_-$QBg7=H)Og]I }ZPu#^izL׆%[:AMW+˭]JD[dLV5]LCJI5sOĸk[:AeΠ1h$Z孭p̶um.Xy{=Zӎ@ڤs6rVc8+jdC.4BUl^V15鷶/%owv xPRµL'/bͽj>g@<=F(z:bu2 !F %tB{pJ ՁτC[O:n:o.D`i"SK߭EAnw[6ΗZ -xmYA*-0QzI_مuʯ^Qq*nZ} o; %ATЋK G%6x*6O_j#DS35놝] âޝV5l^oJQO$'(D^_Y/d7Zp߳U1Akz6t\rQ|XKt -8AkdÐq\wFXR{/_#Z 'kv"u+OWv5g7=>JƦY^aIHNەd)Yo4B|ck݀N]9l[ox*W*FsULrCʠRԼC;@a;,E[*]ʨ5`u3Ƌ1HϦ(Φ  Xd G  UqV*Bi֫'' 3uȲo d1 w,eD,4^0h[2Aei|5^kx5s<27@s&$no${\]=>~׾hJ)|mܥZlZW0H}b0,0,suL^N^xm]GФȂ5^̛[!74X_7#;XDgZhlW |.(cφ]?=9^cwg+q~:QAXz"Е|X|<zˆ;6dw~/2~10i~MmA=-_lytE|{ӳᙐiXhFSS k۟SYP3w7P^ Ud 4j鑷{0fo׭O+N;G3qTл"Ja39`|S=č'a0YmA<=DBB)){A,m 2ƄiGCƋfpewwW?z&q)I6 3OR35VmQlkDb(i3WgjkfQudrzM¾K!ضLwc [ = S%{z0M KJt~XRC9!%ĻOp(C3CtVƟ#)16.i|3(a}9|Ga`1̒qPLN/QuPc,OgNI}a`c+PKDw5K`i6aBeM Tg`L/ӤIR͔TFEukD^MFyDII,|f8˜.|* 0Ma'X?iҬ8!}9Suxb,ʈ&`.L+Е\RIqނN^r83Y69p 0vy^()(]e uAb<K蚀74Osi0uښ>8l5XVVJƉ}.M?a;z\DKg _p_st[wbeVtҶԼ  NywdQᏯ9?Ah1G%Н'KK-~DSrz󔹈2ͥsmo JG]c "޸`{CJ Wf+KXz*/0HxXklκD5 h&`y "pI;Ape2)R{ *$UUF%6~ U*RQZ*;cJ399wT8b wRr 2.Oi3Hl33lP8TE)>uUҽUgQk1CP6f@Ḩ :rKs k"<r\lxq\Oi#\qu "0lԱkŗ5`cDI II4+$Od396oC:6!$w ! * 1pN  m&/gP}c e ŷ޵pKl07Rذ؆X۲8n;H*zohWpF͛wo>#lȢ*էl2 ;(Lz\]".LǢ&dD%H)#3oCP {W;m%_g>&{3l{6I4Q}H(7}3>l9\<>V+$HKF"aeÃm1@f;al{|||Ushd;N>VAʱ1q免ɬa`;kצ?nnܙY6bNʠ #rcW\:zV`clR;n/@ <ǒ6("; >.ܸ ~_&D=ͣ!'EoxdcVɭ_4Fp/ TaSDŽz\4H0tdJ4d=^E R㿀'%ڠ8>ֆti3S.>"ZJeOxz@i%gm BV/b$:l?z˩!(.6wjV;d2v뚟{o xݷ)x'eRw寽33鎇!#CdUJ5Ot%ʊiew8ТQҰ)xFfi6|W&UC< Bŀt[$T-Dlڑ:>eT-+ reaf,΢œC@q`AhwCJ_@$ksςwŀL Buo9^ӼuA|epX\C5ݎKNQ4m_3lb"vJ:(6<|J5Rz͙:B;QDafC-{i,vW su3"tXIAӲxībnV; vl32]n->Ҽ.#K^*hQʁi:oW-ʻJ)\BZClQ! k_M&b$D*R b1&\ ֹ$ $*0~ư[O X"5jDs[[@;PPA H5 ʎcHtQMKqY|mTu:U|YnwqFѨ`p$j @/<ap[p+n"\8a9pk"o+ZLkdq2 CƤ8+uP P tYjj#p+Ă˴1C򨊵qKTs@z4`m_HN8ccS%)f%``MqޭS [prqUQTT+ k*2hK:ȢnT2RK$ȷ@#r渹:5'wZes1{rj3iom]+R+l,쁵 P{A To bE-ZB,OVl"EAuH)[ V=ЁڥբUqv>AfZĜXr2sxO]~A ,Njosi5#7"'sR rA4p;k<,ȠJ.uBoe@ Vk (@R8ރ34c@:P1+Zup1 WE^jȝFlTN>NM@1 "W'y]@ҚV6zvÏl^Dx AQLeRW5`#{+oa-p<3^8카/05FV(Z4 b+>kj,gݸFb,98V ] LZr\u@Z7CDqVy;Lnp6TCRS19C;x%a!-kh9Q}r +w䖌3u44Fi-ܻYRmԗ-KaA4VUwZ[j&05A|҇1nR".~(k.2ro;ُz`x}WypwKBvȒo_’HJBv ! Y"{lSDlkk:R?Z\ޣgjysw{B7ڊuEJ]kci" ͦvQ$,q[x :߯ţ!B67,$@ [$8T sBVǦ7`yLtzty`8-yRhf)?dGObm;,dxB7J Bw0$B1f.(F`@遃i^20`Ve<8LM.ؖAFCʅӰa@d[&:FbiʰVɰ5:lF4U:*!DKjI]xLڼ5A2dz a@˅naqsR|3* }6$B%4J#ӡfu4*y=jV, amnY<<N :/X'ZhQeώB`nňY@,cs ^u9Fdz'r!F01/*߁Ϣr88zcoG# ݢGج&ZL۠Ѧd }Ic%Y>p8F@-;6WS(5KC)+nPUjxңT+dé*Bބ90;&DkBbB:A|pliг%ra 2G.Ñ.qezN5j)= 1JJ?Qx$6r A[F Š?`@~j6Սl> ʪ EC4,$ƕMշ̴ᒉ::f< G B_4d$I| 2U֠W?u֦J$Z2n)K wyn)l>s(d%M9Tڜ4F'c)4yqKGjd8@vmXțڔvJO `8(8G&\3)=LLZ?rqR[֥;Ͱs DjMK76uϏ ái`3%(HI2Z!2߻:$)EJ3C%SKxjrtbjM{i;2혰T+ȁLOT'3ìNg<;mdi9ӽ-Ms>ā0eJϝ(L6 p\e{ JRZF1nȳ9nWr^~7M t HΟG/({+" SȠ͝qTQAJp yqEܑT|A7G 弖nC{!NqgK&X LI A(6+NI6o ١s 8炀rgЅ{猢y ={Iɥm|ҵĖRv ͲzKSod 9B]PTѹ`S(o\]SX?+_ P*GЪMh2!\**٭UT94yPTYj8U湤ZѡU3&ݯ'dr"LI`æBS͚:Vh&58U\;V3mR"sQ0t{j[R*@weQC IE~+mmhbn}0eֲhQc}s]EKmu?T*\;etc Ѹ,Jkuzc %?!YE2&@@ޱ(]RrO2dW-8`KJ I26}ф8έWYP[fU6}Aڽn1'+"zs 2lm"$7T3}}agO41B\?TLEBۍp^[ ߴUnIuڸy`KBl8toyk"F񷭹6&ӧwM6 l˶ػûûᾬ9EIwkۗΝ!=.S#oondJ^A]3(7wH/c8M^3C-B-套SD{ ;Yǻݕ ݿJ}'VR>v'Jg˸[I{ v$^([]4yk޾Lqv>GX.6.94".2,^s&F __(3%׳? iѽ-k}TmEˁLru`) {r?A!`K6V^p͊7tP6r U\>OꪷiD* Ci@zHah j<0yd{8!h?tʑ#Cs,;T,\>VҠ"65ugr|`iEP@tOls#d Tѓ7 {d+yn@O0 }evs-+SMSNfF/^=9:}q2}Ϋ=Fk`MF. 2q @N (d TiuR1~IΆQ/ugۙ.s;sb?|.:zo7_wh98-.7;zDy;;c]a^_qb#SjnBIg$+hKA4Xzt# % D}wh}% #1btO(*DD}tnw\7^cUxX{PT{/jH ki/@шJ| e+ˮ#H)F'&M$&S&Lm$NG$$餝N h؝|};G} 4 ]GkrvS]~<nLT5nvݬ85OuHܜ*ٗ9Ks'Op`^{1Y)6 04*5eqXA< -MyJZtm#nnzz*P1@xE1W,jLGx%ؚzK2e_cJj0={yR=E38dJ.OIE؜@FNJ qgYD8bFxxiI 75g|kfPL4Hmx(OD^Wz|v&¶F*Q8g12[=;viv%L/CiUa_~ekKحy]E PW4EŲM1( }~{F)&%x.C$AsYnȦD@*`(*" GDA0E)HLT+6!B3צFDiӔD|37aָm=5NUZIMsTk_ !E2{($E"JBtނ\N9k2"X^|k~-|\H_15< G`,\ b!xiL \dD)E;G61Dәh<+ f7&& ZiYw " $謰aMŃ|M5eeaW$5 !"DME"YtS#bsk1ne/]R/k|!`( S[|N]2 9m5~e 2z)nȺV6qMknnPeVY?~x.:ݬ򵉰f [HN{X5~vEI1;%֭^Opѳuqj~  18 yͲΑ[-Asy#c}_(h}OEhY.!uΊ CEF%gÒ0F{G? =Ik!r9Vl8TQUV[գc~Sw4ƨ ljPǨ'n7KYZSW5I yS+#)"ot\ϐǹy鴤ZQyԮ9A>uE<'q[% ޗV )4s?1ʑ0L2/.2Ѡ`i}N*:2aؾ'jb,PV\RFPZWEH &<G|H*e %' XAէawt֦LXO=1  :75nON\ )8GM63hdQ1 "!%HlP Rٲoz{1ӹ}L i\VߎR }϶-dFal 1I3"a,}&jfT4%c0|Rގ*LrM l΋[kC2YCy2>(M!jcVzk#0|n5>z#sypԃ\7)" nuOgtzllׄQ㊛A; bitmi̜>x-Zǘ1M1kVPxĎ Cl #3ն_R#7|6#UԵeE"~5}߂͵'7Z[cAxP Z %>CZ-{&`{ڶ 9ԚCk:|֞ wB][spHHf/ Gx!mG3- ^܁GQ2>DҐE)գv=y yX@\M X;Q\a_%^Q]X.t/Ǻ՝Lu2H{I1<LEͬQkD#D,%Hן sɌz&޵(ѧOX߽;fE=1ˉh) /F,sҚd:[=,VW! vV$(;`7P^h&Aj_ΆB)|7 fJ~y"^x cX(@,s`Ly/I(8sB9?`-VfaʀES3&RF˞Z94wF:TYxPal !Q~sH'a.#8E8T"d40_Lx99ѷ+H#b.>Z}@iR* o\F(qS+T\dLUrd IpBZBK1Zm[y&Ư3KC(c%xklEateȭpl=CiE QSJa -#ČC#X>CV-(y&{<O(WSW`bay%QlazQѡ x&JdSuXb}w[4\ Af)ʡp8 v]Z^Z -!*Ļ/oĵ.W!Ϝ+R+_^Y+ͫ Z.wUŐekHW"fM-?q~D:xMVilU=פa+=;-RIl 3 L@cٚWjPT*(iJ@ԕ&HiH>;s朙93|qb4Nu,()ך3C,˶hT.FKeŵb e& N$4Q.0ldM7c"C%%$QCeɈs'Ah65MNˡB<յ5d@#?GiEr/7ÎLY7Rrݜ( MvϤVI2n;:ߛFNЇCc.I6P."ƇJX*K&hs\)$+m"^+(TXjiQh Ӆ+~gR! 9sƎ;0m*Κ-geYSjQƔe(VlӔLA#VU7GB7/WIK7'i}P 5A536?[JZcvhQ(N% \.#{Pmj~5IkԵyx4e,yQn,[Bjq ~ ۅeу*-ŤoꅮRŲ7yMh@qPX6[&F{7rVTb6KmӢJʄnPMIPz|r^jx9*V EYW]QbI#Pg)ӟK7sVm0?( 8h,a8]ym"Z]|YE6Kb b?XpiQe nQe}Yfի6r ChTr.`@HP\VYץ֚r0lSJk:=P[5ȆeѺ"򻺻(oW7&i %Ƃ7t (R,v'cs>lˎT; Sb~ǭ$`5ږKliaee{I4uf^k:]ڞ.?}FOZoZA8w% jgVlf jPN4ղq+Q+^ݫo9uTC3-|,"|Mr-'y>LG='bTA+T<4mc,>EYpg=>YZqNznWC&R^+^F0=b^h|5 |h&s ԟv &rPve{.=UMzI`9zu|rnK=?EN= o=)rLf:۵ 1zdD ƽO* -ixP j$[ʾB ͡@oG,,uӼfhܓX%Rɩ`9 J?ʹ <5˃] XATtiP^r&=Y3ӄҤA>YdĹ . s\z-ǵ)) !lxhx0=!?x e]lp 4Ş!atR=^V^4D8PѾe86Vǖ+BـJ1:nJ~+mWޏQuȱ ULʉƜo[%Q !F=d#4k>c3F=N?ux}3jp=~ȑ&##2 sIzb:'Tu#MG\K }޾kf6!۷Zd)GtV:3. RzgbIh2ϭ)_]"sFTdM^m|oxawL-[IL+XL_(a"<N:\Q5MͰ'h9F,vVծ2,wI^}+=Y"K'(bYok%nHM5ðd56sxf L`!wm4p+wJk:D5)?ݢ,!L?R{o5I;Wǔ*w}DDzHĺoKݮF&bp*ԩI>r)&¿F^ QH (}(I4O$ UOcyp혅B+zO}ͨz`e_7bgh*\s9={$]NYT8 o?Nc tpyj?8q qq2)Ȱ, r$R$@9Nz`5> 8n̅Kd ;ρ>v)w_7 H2^,`23&e6aCݳ;Cě7z0w3j=jguT[ts/Ue<ygQ\5N3q&ls˯#_'1iLUpcnji|aօ6,'ຉqBʻ[\^/߄EOTq,"mnD]aE-~fjTQ)߼rvi(6 oOL~͎PcFX QHjJPPy+VµjX=VP|׃=nY@92?_8ie^9jSŚRAQQLh*s2=fG؆=?M7lǥy\NԸ\F;8pHʣ|0pE+pjJV f QNYMkFB(qH0ByyXk'6<-6E2R.Βz1kQ_C"1KCOEקM0c̙g>{N4D4`RDao:7?Ho a=xUWiP~hܗ _T4KX$( 0шѺDuQdNL4ib&6ii:8i'NsKlw;9s>}('3=!SQUZVVX^B]; Ti\h6)' Xhђl(1}Cc3]"+to@ǦWa);ey,9 4*)̵Ay;0 aWu{;bA҃aB,}8(b/ {T[^I7Mx yBS=:5Qm?d05zfH0ur2ɰTRj"1kR< Q'iXd5[QalkjP <dzoxbRn8cՈbܞۢF,t%ǡ#(*T=FGb;KeǨgxRfLk4`:)tSpX^MdcYWީ*,2$[|(ʢ-!9請 Pd@ OyC31PYhしB0*~oa}ِDcӅnW;* al߱WƅiTnI6L9ހѤUؤ@ڮFdL.3bd:E7(/yRZT,} ^*m@|amwd9K1y(XhnFǦ`ߓ4(W!9C^t0ٱK%A9[E>R![:^BQ||G {{ly)nj (p*z80+dFFR14+ØO3961#&ΐqUSxPwit8b}NԦr$^x%(Njǁaڔ= +"N`B"> &QSIuK4^r,f@cBP-(adKivb轜`jWᶩZ}.O[MzL>rMHgLL{FRs8+C 1)<  y ΢uBp$'VP4g;zlI Zd+%3.|N)ꙡWcX4C׋VPȦDU\+rT44,fJV/uyF~MOV Y+eB[Ƭ,*>(jĊ._fU)k3C(эat PF͝WwVU֊4zu@noY]:6ꂤ+JZUytU^Jcկ~ru?aաEf3Tv/龜8_tj'Bb%"qLZ|װ͘M ml86VҀ+^ P4cZB.-7%3qlZif6,X')\>i&E:!jh빑z < ;-ymCr7r×L{Bw3]jLJZHOu3gU^ROC%4.!feƍ&[̸WX3}g:~Qͧ~Q'mR9Tu̮dn!<#mkCS:\-:a}{Gu:qކ"Gx~x4~H^H)u!IRޑhƣC]>zDRx.)^ FWb}i*@:,ۖ)6mH*M؞,ۑD^>]gB8 bl~/> W3+ mDwt=6Et)P-Heў.ORѮ 3ݏ!UNG` #iQ(n7m۝՟w=R.ɑrȘyߺH ].̈́|!7o x| t6h VW@{_"02y&Z'/͕|,&\0|y .T,,\?!V%49;C+H _<C\N<<78/ዌlLӑL|CYƑl밣؅g CA0v6apoo ?e$;=9ykߥǖyh׀\#WXExE'ѧ#X N~JՓ3aE<9_( gc2u*R!~(68kKKdа{fM??埝2>ΦpJpnȨY؍| rzXTI%< iϰ)AQxWtLX!oMo]N/ݦ?ŷ/r[^>_cPU1*j N;_ۓl.+4]C7+L@weIvo&>5u蝏ѠO{ Jg!W1$]˕4@tfcε hMB Qatz:\^OA;ᕫ#)vx%UiLTW;M76R߾HX%&8 3`]Ee1i-rL+@YikbCk6GMFܙ?s=,λf .L=UNpK=޽I&b9LspAPMʖ^ 5f0 K9[;[1qskf=IPBA1!C$20|]h&~.H\r:7?D \M8|d.MIC D?m0145hHUNBmNmQ.;J!=+I{'bwfsp*wOWbKU KdJ!t SDs,cya &PƫqaQ-"~S  [\K%.^M4G緮ȸ˚<^ӄ๩} XXVR(!hx,d坕T<(2F;t=길TtU|/oU,ZUltҪu'v)V hf`nAm/'`;or`}r|sD@Ա 7.:ݕ-R1uw-/eOlZwf~4PlH^4LWySqf7d "C$Q9Jmx.SޯFJ عOT^@yEUYo%M% d;-B.(k@r:Cd:Ӱz@-q f5##x$Y͠(wIXzG *"Q ~zvw1-VR * |vHm,K]bnEM)jMǙKn$e]ci~BǖNƦ#aBPQ :{"N*DbYiT0\ IP $P/.Z'#DĎ0^5 BVpcyvs:nO"b.HtOuA2b.S:OX Sk&PㅠiVOrBbo>&>k{>neãv4QABUj4z%l04m"XWjAUqiE@Ղ"0}|b2PP8{Nf")4E]L ˟Ɯ XNc`Cor #6^.La{7jX N]r33D l``"h r%]LQ3BMp7Jjv$F! F\>} .[O0FǬQ7EGt= *NJY5eX.37JSN6_5Gl{rb;F/ɓ@=ur2&XT!sS>l6JA1ܴ w7*4B7dg?4D+5|\xWypݵ-XJ6沌V+$08Ŭ%k*!i%MHI$6iIi'iLzđNgV{} o#w)͵E)*v IRƔ9=%="S6&O} nVFwDGwQ>ݘ7*K (e xfN-(IObc",s;m·R,2ռ)5J)QcJJ٤(+0w\¹D\NHW}EnzdyiS6xxU}bTU]>F.%38̚n/i9:}LoZ>ө7KRsxz9[tE5$27$ex7S9jXVT0鈘0mTAJRu9 i@eN3yv9mn8Ϳ*Ta=YyV9Fܰj_SI[CU=,s+GUwQwV@I쭀„F3X:u-|i񚧬WYOa]s,*5Ԣjdtu+F 1)AS~䖣W0aq9f5)]VȎXRs#օh\KzNLĸ2Ʈxcb }z\YPKВZn,%m3/.E{ geotdc |NonY5:*'䔦6Zc: .,h|>wD]~.f]7ªc"/;h `$7γR4 TިH:")?A1H4UissbWd~hiիmP=PXd̛]kGoVhkB̦aԯٍW k5? <.J&`q<Zo'kiyZ bRqBXRW .^FOb\:CzڪWKb-@ٻ~6U-⨤$I%W[2BĮQ/nTH1h[u;m+ "cjۛw-yr]!|w:Д%MJU%mNf67SpZ-RH"SB53<õP,k\hwf3 u{yAw;do7OT)Ɍ$f6נ}Nwhဘh"K^@$ճ0Е=nNmJ[N㯫<+OC޻:w zVY mELw)뫢> Qv+HӐy~;A 6%UQ Gsn?ȶd< l߶,Cͳlqyx<Ë w7xW}Pch/١87X6 %#)KmCKC1& LClX֩)YaCuheuc+d>hb?.ޜrggpOG x@. MJTR#2Ttu4 n_B=$Rv' @۹9Is~N4p7Ieïl+~f w=R̥ՠǦ,O9h_Uxn x&ǒ\:]p~9kt r1Uv`n7%73rilT$Gq9xЯ_H hK>*zEXmO hIme~N텷Rf%T: =B442j CBf\90yP0$TfEKj+BR^~!|&h& 'UX]Hmn{6}ffCuьp//? ZfE/gFܸn\{%%,Ъsb$gW8\arec-`4N-閈bv(ᆩ@֔ݾʛnD:>d6 QK1{x[K ˬ܈ڛIT[8h7bĀ{*cKBSFNhѡcس~B114fݙ6 lxm.{H?h s:.={\8X=8,+rb +wࣇo/S<k/G 2@Kkc5}}Sl)q߾ J:v-+4 CHyiGH >de dd4ݗxպmمoJ=3*(#,IGOKyRSiȤ(yĐ /| /_NkM'n=z 1&֓'2_< ݩ"fCmwu;帔b\x.x}bAڅWݚ Zf!6{^yM=ܬo>v ̮>I.v7V&5yO.&.l'8회XuM·w'7pn+\ʿ7-Uv?<_O:vQR(Y)RW3], ËȗGt 6Џ87E_u*V07e9oyR7߭iOk JDzM\?/J\&Lr41F(̓a*@P x͞!A 2ӾϵM'uy1q׮*c=~ oU΋Ó}a Ls*!ү~9g 5uvrܹCB/o}g7xriN\LIs{o/?~hf sYh1>45b=3)7nE{yP.{BvYQ>N лߜq?\Zc&14@$`39 y =R0JZ#ſ1EPv7|ЈM QL~N!Ma)q s2vR\m:x';tf<+$.J!_~ײlќA1 BS:bp`LcleF(ASgihk14ú=+_Uv亝mR\o2Mn{lԃ&&Ȁ225O\,F>j%rQW LGrl n] TX#Z{&&`!0viKE\^%j19'ҵDLIzĮ[ժUiOw'IĨ#@ذ(Kxɞܔ s qOeW`\OѰg~~=ŗb,;z?eÁvKE0巕=h D&8M>, kzuDNQ]/޳ _Q͞/W7ϛjţj_>_I_O Y\{}_}X{./oq(ȕzTcdG$b;=T,Sh•kt.sLpW46+/T_^?~O(3|#$Va|P}o4 ő-Dȃ]oqRaUO4nr|YwCi^KAWIF_ޛh¾*ٕT4d[eFJ \ڝ8="=#J7"*'{_Zވq=3f-|)(< _㥼&)CMJ|V_B%D5 P/;"!`o£|Y ? CTVfE&(\_a^57͢Fek79z 5d-}m'#t5EELW%U Ef,SSFVY`ÝHֳq/L(h.@~յķW@,eP$aϑl_XrHa(Y "EpTN$ OX{#cQ+ lt,XY<&'2#O~=BA9 Je*(Z`P#@ާhRs|0D?Wi]+ļ.}BLfkao={j~K8WzlEEJoR`X+4B*<SKUY_٣+|10!DLِ)L|FRu(Ɗ?Q_RJsͩň8 5P;WpBe]R T~dᜣ2 \ի{Jn-^-Vq% aqoC|ۣڝJNwJB:%<YbLcϋ&[1ِW2]Q jk ]y5ZxE^3n%^xϬ1T)cu2X[y]b3l<^}3FbU7^TɁۚc%F–b T囬Eo| ,| [o;Uѹq; ٲAꏯC˨6"0r-56&#w/*:\ {g4y[פ T#yVx3dydFj6u<M V362ש#pjMdXyD]RC,1!xV!%NxHp&8iAQd(PcҀ&;&\Bԑ - %dbR6O+xɛIOjgiJx`8gBox\^:xdF%LfM68-jeJC8T46a'GgXU rqeuTG`BQTeShJT by= c.X7'Nf&p\ 3 Bզ'_zYı\onp6 .R9S1[&Bvg1A̿u# $lwCe4,,5,c SӴH\>٥@>斵Wi\s+sԓ0FXFwI'&CHjLmcJ|V 7t咘eʻoboM?-c{,ct_S+0u?#2aw{k܇EukP7o F(F8MDlt̵J?p}vx}]Hufjo"ȪR&gˊ|8Jr"4)&?iFei>Dwj{hoSPQlo^eb Sʱo 9בbKS 'wF;e}N/ bdlS ݚ4GmܴhFLW)t\FÃW=ft'}?ZErE~i3=d J&"4~iv|聖U"\Tm;cY-yQwc) {W"H9)F>fΟcK)pup0 x Fvc}'{Gt1vka_֗RK 0d+_3RW̩ng@ N@ɯ, +{vńE~lK\}W\F3y(\_&9@mV)Ћ̈R'es&09l*CWBa\HꋺQb̌o!0Nc@Gz`E:?4}R镡|KqY =*r]/Q<8ʵglS@0HkEO9p{>TﴶGaugӊ ׶`?&LWlHMӝTtÃj41׹?L-%nUbaٻ(!;Ճl 4zE >!#(,[#CAN"bkzLd=d 8HdRw3\/d!h m6E\WCT %)JnPOIos;e)mg & 7)FqBNCg䯅K5 H+fp`8͈ھX5x/жLvNn,g ;gS#*i_HBRܘ.O| "wQIƋR4TGwQ%stB>x~?q uJisqW]v;B2AsTeX=A ;{{MhG&:[U5Wv?P.6nyߑ]w|re2$C <KW9 f[^GA: R>f{RYPrYVʟ\(JFW\nN *{ʔrٔ[ĄcBH R~!N1Z:q:j.jlqK\#)uAs>kڷ7MQ9L/o5ҧǻ>E(akenA,6ʝ )7{ϋz)l}P;ADL3 soDXrS (D)Ѳ+ѴZYMu,c[8C2t\+Q"L]9T7B>O~D8ڬJn%jR.+\m {6( j>|a&FDYf˙l޵wC_^ͷӅ3FLϷRΰKa.j1JYQr2--΅Dj\W]wB *K،FR$oNo5&dJ+߂M c?,Q{?KcЁv`Me[cq)&H%=Y fJBlq#sFG2=&D(l`D_|œ3},el  |1˜~K'9sX L^l4JgئԮ^3;>ChsrpEs,i`V}>VWfם}|y8[w迣O(O#;p~L|AqU̹4^IJKVa}e^Gv/S{uc <)&h}kaU8m/JO0f"z9ce/N\7FLHiqխL/=TFg'R?*G0Hۡޚi1OZoUܫڷ8Vl)Y W7\/ ٗPR Yl} VloS t >#ߣ4y(,,au21PNxHQ;4Y1LnGNN`se|,aM6ŁQ.Z3}#C[ [ ħkBԥ_>kw,XwG29E6e:&̟~_wA4|^=.C밤@_O2,o ģq|Rr9983Y(tjߩhL̒~@LƋ}c@>MW4!}\UhF: ZѽzT`=XxYΣ8َ%zM< (mPw#RRے 1v a=:Ѐ&ߵH 2ĦvWV _tePwWx:x&[>AͰOpuc(PL|e*XڭsVզ`Z4~LOLVǽi"*D .^IMs'O-Xv j߲ Rc>y@8Yl"nG$suT#\`T-G5>]CT)1Vd+#T"8OcGP7T v_Q_lxT<>ƺ|^eFyIZvbyhQ_z_D_o~xϬp]xrlhez[\9R K/ )y:nY%RAE"kXUFTFg8hAɿ@h;(O~xuSkA&i{GGBCTzR[ֶe ęMk!ɃUPZ ݃ z?@Mڈ|{7S?SYܭVj#( 6Z|-w=4n!,++"AYTM ,rW E0"W> y-ǣ,+̔V&&UaczJTiPVjW.A\jf0;3걦<=I2.s\8T1aG@T̑h΁ 3 Ldr0fpt?3PeA˞G#Oz\r EMzn Qv5 M4_(a8hljܥ Dd#I-\S6j#g?KUTJ.^)?FSs(+Mi˒҂G?6?h1Nf[TT!4Iҷhgrc`llc_Af05]REVMQtR!m k;=lPoT[,+{RX_i6rx}MHTQǹՌhc6fr-*9if#zuIBrQE(!!I (XElq۠; iy%4`fT!1ƘIL ' sT |g1XB tHڪ1qLdX8\Q~-\τ#člQT7Y&3Ta#!2&łzQ>QqCרx9Gbx W(x#D}PӠrECU'lcVg^2R ŴjHV8<ʁ@>Ixb1ƈ|/û,ͅQ~A9$x ~NDQ^;WUq7u,?<%fƱűBcÏT\O;gq/J.}#(SePaxnjVJi@Ufdoi%O OVe%#-xd[X6X(i+`eX]&Pܼsg6Ω-2Ի|dvoBO]3/uSzZ -wdyv'5LKi?3{mu.6d)Pʠzo*,-2T?8rSյxwM }.2Doa=ѓ2c g8CxiPoDM‰ujl&2dxef*To2RXbrUhGESi†XDȁ1ab0Oa@/[k8158Qᴪui\=mLKG(ytH`[ŝq*9'bxɲ~HkA,Q Y];0X\}[>74<-rU{3fXNE~|ؐI+VJLLaW;&*=<0u:b:VV}ZyS `1w6F؋s[*KݴġN MfTˏ=f+mpWɕ&(F&"{gR^s2k3?lDh_#H!j T=d8]ċA}'و@r:o+=R'v,a$$Y[EdlRvLJ[ svIkw>^n'O~(bnv*|LŲ|c *:LWI+!Ң" j{/dHƟ[r҇Ȅ34_UsZjCӪGZ L"ԡHMN AFe,EVli3oV ?K>g9C4zAݪ\x=ڈ4 :g`]nТ3۟foUV<=tNO{%Pq^ T xkxr zI;7/ u@o %x; $&WI0O/0oQ4c17״\Qn$AxZklu-Z-KQ/QiI˗$R4Grwr9z(hP4H;77m"JI<p s\) "isYp{|yղϽZo!GfNw͐!{xW?xP`HE wM4El3>sj& ۂ& [w,g;dD]g伯[M&|vk!WM#ݽ|opXY[֊كe乃x,<~omϔkeGTxB w _ 0G6 xn[-o];๶x6qX^cNO1i*F|/uh"?]q+4\ؖN4;= Oo'9)h- :$9`:ՙudAv@joql$`Veo$tV&'˺U^5MCU^S~Y*.5)}d7To7N3(aY\e{,Xj{Q3DXcN_E5F.V.G`ܿ=gfwo##8XG:-TVgOBz!Q}MUHc"] :~tݧ$si}1<~9+9lG&8&Z67>#})k_FfSҋCZ:p5H+țdB?"ؓNUP2q@$hAsk$'\;67R U$3ɯ4äiR.!3UǑ~E`DN~01d p"UߒkQpWwUp!@p[u1Wx%gh(˫yc kF>8H7>3R"d58P!se_eV]OfY^]pKiV0QMv&~V+Y . awV c;_>ʼn7n[H:`+g-v\ݧkz5F lk=kr3lǂnRB]UQQ YT<bK>`:|"]sm;#Nn?Q9 Ēs,g;ΓxYS5NV0zd I&H' 2 yi@14L,} FbKvE6G"i[rǺV +|[NQ((?y$U+?Qhy*Ve۱0`!-n}n&$@ 4?F!"ހ@3lQ8H@lx:[aF@06ihd)>ن& `s-C`$zh_hZ%ԛPw> 3p]kz F H8u"A=<@$l規yCI'hfXkJ{VK3s5WMћlw&(41mJD6 0L׉:RfF\۴u} cn^q8I@,-CɨJ_=#k[j@`y_jU&$nZcĊa.`վPCx~G1x;{N<_Rt; ]<A$zweJ 7NW<:?x]< 9q|yV y?CխU9Xv(~fBwO|P'dLT!Օ.c~$_XnA_'n"z@v GBweoGݮﭟ$aPAEpwxG. MvjuTC' 21ByuuԶyn`kx /6~6!F"A5Jdž*0cЅqvq"<'O''`P'̓1 ޺.ì.ǵ\?M$uѴpG0QR"}v/ǻUR&q xsK7A<}ɥ~ҁPM΢v\g鞀]W(#&Q70[bLgQ=*&qT!3Z$dQ q)H1I6A}Sn F..!'D({(p,r2 0HNGf'famzAW~zifRW6*# '3md99ZO'>qSt ߣi2D1J<׭l8$E-rv<$T&5lD="3d=Lo$Zg,* A{ᯍ_*,A^`.3D6.q)zua(6sHWiJ8љX[dKĮII`\ 디(xh;?19[M&a|kUus+a1I拖qdrI8&0!GJzG!l# ,̞#28 6R~bRTTzb0)l'T0dL1- `yUTXKCrLE9 Lp!AL{Rd6IRM]́ȍ.L *<-"k@9AfD7BnGŒMsK_>dppT^T^RE]"k ^AOxMɕS94x3Ok}SEU[SzZ5jCVزkfһ2#|$RwHrZIum3 W;ܲl8%Y2׉`9)lSsLv''YY>ӅlXB &aH47C{mu?{?v 7_/;0] (M=FVܕc# BgL T'&w۪l;*aiWIk&[ Q:۴9?k3c;E Y4o_!"5$*StOzHy$o1RR~m! ?д3!iZ,A?Yh/,T'7xn]dG^lEMΤ®`yHW7zr*PJ(׋ SmaܗڎMrL&8DCݼ)<=u znp>B6"Q+$`#l0uPjkKVy-)Mf)MFc| [ "oi45e Sp\kup6zxڼ,JS+S5xNe] \UU|VXOmiw<@yP1=FPvK/f3!%*bi'¨YVW|)Q#)N"_hY_] L9oE ?4K">-Xy,dO+<[UWyF $$H"&&jBIлO,1^od&Q1x~cڐko/*\5,/Mv$#U9:9qrhlёcx;>qx R~ bk`7Q=u6AI=ag$Ń}x?膐mrAh3Uz7"/rFh4DlDJ"_>f9#u<y,Dꝫ[l_y4,0Oǩ;[o/4Mč,Ui*MfEGd琒)f痁ȤV/hS=WQtyt=BV!*j@@dXsI$ĺT.n1dbgd3+.4CiY)yfb˅〶L?M8EHֳbŭי5TDp(;XvU^BW(O)񵡴'.(M\wxqAuOHC5`Y~sxfPߗ6s~M\n)H/{?ϼDno= :gߘTEe2/O*&dp¥rzH"m= P!^C,|z#1XGϿc&ևfdÐ7lo?p{ɐ,R膍w\ ӞӐb Ϊ1T# IUyW3*%,v1b?U'sJ][$p&w)2=Yr}Z3D$r$xK{84COB`*h0@;q,E$\׭U$1J!<$31 F@-̔k)yQ4#^ȓ*$!dgA,$m܋'^ic䷲(wťGV7+K,4M&Ȧ4`GoogR<^k9ЬE[w{ebY֥HbUUFk[+y]>`2D fs)0f1'wټIMm[!L.-,Ѐt9 X_d- jx{fvMeysx*3MIdܻfS۶f?K) i(ƸnA2d4rTJuKcd5q$0.@OuFrsvk$ PdkS܀ba26s:0d̖.JZø!ёC13?͐S;ӰYF/} :)a~ 5)B{<D#¤ m$k1O6v(ƃHo8OB 5Z!dKƚ>-XGY+JWI!-_6Ui8]@U2@yJ t>SɼyM&ayaSl] ;woZ.XѿE Vh&PHK$s%n}|c}sfCʕ`жVOi;W^#k۱|U1l}[}jŦuusko/k>?y8~ ?n50{4&f{f{o'/'M;dN|fJ?^=(Wd¤^ylT^6Rlv,U> +{on+NiYYӬ|g}YטBP++y\9Ӈt1MW>]%l1e}f 2UZOT?Lʎ4;edAfg{3I&2PrY=F[= 5? O9h.@NYVY~XM<&K$RfPγՊӷJUYr nfl"@3q2DrV}vXwYMs\nX7@ZX{P|lv?tq|S2]<<%y>>cCOymsw$PݾH@KQ{xx>пE"Y:}Xf:TAΒI^;Orz9adv ﹝m F`h0G&6qZm|n x0VMy\م䓏aX̺iG/e 'Eom:gL9搧 vn ׀qﱝQ)_D1ab(Pq@O}N@$YYb[ i-v#)=D¸MnjXф?;'_8|zq /T4h0'~ڠ }*:QJ^EH@@=]sUA=.ˬn)6:UP <~M曆z:YxГ?z:ͻ2JUx5pn:䠁~&.}XKv3DZ*Jevĸ} /P>te?p tXE̲ƹ1Ą|P!U085!' %~ϒo@b)ەT]:OYa%Mw`a6<:(0_-(06Uy?xJ ^W;iopиjeٝ+3|dL#e;|i*YgDD~Yh]\&D-QS?5Ӊ̰Ji"/!dx31ӿmtY V@jQprņԌFrx-ĐDXPVl{:j$ךC-*iȟS jTfgɿ/{?FS]K$Gn#$x䐕dA'hONLan3LMnYFܨhbHo0Lvےs$`2'4mw6]%1կҰ>84ppT[w=꽰8';ՂQo=ide]r+kP`aa#{~UpDܚPykӤncݶ*цtu8#㧊w$>7v=g)/-+5Wi#JLiݻ/e8Ky%̚qĕpg5\ {/pCkw7@ѰC̝?togztV0, 1(4THHA¦-m::guT-`ulΉI{c8E|E k3g'aeA _L4[ΑGIj§ۭ]2|ۯRCqU.׌S- Isz#+gIıl|rct8j㴘C }l.M@IӪ]QHkUoLakϹ.'ȝ~+'DEN&|3LHlh{;QG5Q7#6A֘ K,)TMM͟Z!r鼒u #Όtd`0WNNH^_f(%LI$+aF"<:Z,s҆@7v°@X> 5+Km2yL%SRgq݈xw ix5=,qSR`ugo.OPtX%dg)k ΌQLF1pt|"ӥl>T(XZ@L4(>s̓FРD!uBZsY ÉcezC8XD췚YeEwo( s-$c Q3rL)Ӳ@ K\inJm|>ʔU@N&R7EgVwlsSFVH^e|*zPjҮꋧHVz9ه VFQ]2$L0TQHb{áCZ nF_ee2[XGdЎpSTF!ŠǛ0:0I)H}^< HΓگ{ZR5OJd?lk' KX gU1V?%Vf{E8"{foXӧ`Kzۑ1+GWOe0VJSGϢ\z$Շ$1ћ[ OEgf9G$O>,zTjLCk9lHn"a7Z]Ӽƹ^ _#E"_yzÓqlb[C$ơ6,.kXM7GeI+ZHУ# O.r),lN}${I4ŖD%R=4 =r8M5!3RU,uP+sD:v)}',S0̴֜ÐF\EٻFߒl8 V=]〳eI:oGy6 %݈ Ċ ϯZ 5oϗ)0_)no-Jc= mZx`Se4mÙTʥg3TjG +˜WLe+CkʥTo'㟳 >ـV]x}OCږuA[ >OUi!Ts%%̻[E] m8(Z2:~TC5rm>?Io;K {K0u?_oby_zvbz|'m^sʖj7m#T.Y9 X-2 IC">s4}zOH@~h:*0ﵭ@9 bo5O+8b<`Oyőtڨ?Pb'w[ y~GJܾT!Z9 ;%keXU+m}QI$SMt¡:@[9n1⁣f20i;Okt-sH|ϩwxsJ)Taub9W%^@ܛTRGas=NĻJ&uRcig+zZP ߐЂ#Foxe*FasK@Ҩv6[r(+E'V/8WAEA|V^\@ HBXSۈ &hنaH6Y )f hA]}+9],& Dg]0k=mhyfvI|#a~:(tn*4*d&oqv'4$542}(S[iZUv_e4=ܟgbКX):`D6LJrwE7}ft!QC(dSal%KVCvZ7c()3\~]5hi!|He/ W4a?QL8aJ jv&$遒 @z4zT+ }S"jƱ:^eĵa S㻅f%6&Qx7е!l{" zWcIFS\)ҜҶ]t򮷐/ZTJgG$67tGTR~D˪8sz0mB2F9bΎ続JRx6J^`RNpD 0S,ހh[d`7(Yc(7fq(?wŪtfi9gPU7K'H40 - Urb=Gmӳ+!! S{t5ekWyocĿacڗ? R9ԆNrw;+u.iSm+}h|)w*g6CyqKknUE{uQtF on(A\vXBiǿ{[<&Y23E Յfol:naw<j&wdo{ }")1Tǯ•{&Z1BhjY~3?I(5O/eRlyHW PAViSk(8ϵVH-fN (\ Nd.Khi;k(nΓBGEW 귢4[ѤrMRg޷`x(gAd d11Im!-@FY3]h5Efť6Hw;f H}7U]&r؝[fmX"hJlctHf I.VT],:C@:9oSM? Fc-!Naʇl" ~gՊЋdWP]~dXxc.U-dWÊv/r+엮 @j/;9Q^?ʋT ±ϜeMyXlyI*Lj{%;c3ﴭ?$緷A=)dv"pk}MrM6&f6&` d JpM !R; 54B톒.uBc+O(R _gțoɖ_A-#j5nJNȈ,{;þB6>q];БVy%a$yc,Z"87*lN=vjT3@|nm4e* X((V>{-IתqL }?] 3 s5Ki@8N4lEIW:nn ONh;stQ qsu?u-}fwf0t;?hnJPd2vl,xEbGG\+\)J@`X3`IlGWCлiƭ={} ¸]BD4Fg01D] IIo_SwcΟoܽRڗD&ɓqpWcu@A(KĻV1񯝟# Mکx HpEw+opc]M+q/b&N!0Sx4r23^tJi~{ݠ# qkrɦt!{ȗp7/~'5Hت&X:V,Ej7 ;?uN8[@` 0zv̇JԎ"pdpQ[90`Hq#D﵇A=)!}oh ᇱ2Y.c5xu5I4%; 6/@{ DZ[w\" =`{X)mxT=nc7ie[Tzrx!M=Ft7G)s đ9k}k{],T ǁǟ۩6 mȻ+ $BCAZљ BqMz);:6a"Jο~@v׷ ;Pg.)GƽL) f4s+wrU.E\d}R$qzڊz P$Ƈ;3b؝K$F&aK/^4[~rz{bmd*y(7b{2TbbRi#4r+8tEp *J@ %?ؼsrbn0K APԂ_s~a3JD *>x#UVK-+TJ %q.ĕ9܃AjkJ0.1r~:GWWeUбgu!R@9gPN5œT8^Jŋ2}Ae͚+} c( G&_El6P~/n.î0ԦZYĦӥ͟9QkM;qq)fUn*1P(]Ŧ"rX-KQK%M[^g{puW._#G`3Pe%0pe1Z~(Dr#g) m  XXpcJKu\>038IX5քSG^V!DQ0 }Zjw-]͇\Eqd4Fnw>: vu+dN9PAPk'(ccWO'$N_\m7 KA %Z-\o-b}_j|svխ/j~ɶ:-6~'h y%eRBYT; a^ѥXӻq>pYxT۸; iw<{}MJވB զܑ kx?4xl:*Ӈ€wmŭA0ZgИƍq>` [+Z_ayqG_O.R_W̹F,ًRhW"YJGX/i/>$X?n[y௴hʸ4NrQP߯%ֺ?3yhp) p}vڳ)6La,qM}@cZ&1h @%9_}j~/>~AOY2p`V)_辨`X/]3,]fSTdTRA0|y 0 rhEaz/UqL}lM^.X[TYJZ&^qb[,o;lԜ{2pdsvCU,F: =뢊uy¤yđ6gA^\I<ĕsj lZP'0LX{ sݑc0Wij*jߢSW?]q_mT/tXclVn$ƕ2Aʮ"3>!?͑8~&-0'qW]&eۼEŸRRGʹp5|ȜH\)j'Q#6"#_^d9źo3ޞ8Fq2<܆SEw+t!Q[nug hgU$+җ٪,_ Bz+]LŹLT|a;GꌚFbH% M(:;^UjbrL @0`l5g hʢ LӂTn=m.>y!(1"ɦx,M.ޜ+i%_JtR^FD5喳CfZcN">,Fkq \ÌľRh$x" k2"X YVBhn"Xcnѯ/MH( ;8a)P)"n {0|,/h)G'SNJCgƭXmTL~4 W`^•> D>s֕Il9ugk=bRi<p-̴"w^PL*v;w;R>'wUv: <@$YHVĖŜs%Y_Z# IRD$K;nio6?zރl*"i'ZsJYB ?Ƃ:ޛ{nH j)AUh'nhӻ`%`^dFF?S}M݀++dj!hCa%-MdI?>Harյomļ>rq$,2 s="\m 2 ]Q7  Z:TQpn0ɹ5%8XA0ȩv?CP/"&7N4X=xI =F+¥Gwiu8zn@(mjo8cz@㚲LŪΫaXԳ iQ(t5!g/Th4ȱ6(C '/+p7B]`@Ltmi$:zZCC%qc PJ _riCRP y[nk<6>T[NS\EKN&QM!qa$-4EjHw|G)I,m`FF1R0VMT%}hqg-\JeIʘGfII!oNӮ 6nL6eƆ~A}a{TRQr/OF=笘_5E7u e?2ؙ ]*XO3 a:4M$ک "FDǙ\#>"/\LHV/9+UrSgI:J xoӇxNO{L|eƛ%[PՇ@g]GNFV(H^][YSI=ji!6FvIwI.ސ7QxrnHvQHѝ'761O74V-A,$KeJ,F#z=0*?Kwcrrql7)&^`,*pEf(Z~6{X4n#=JK"xӶ 2|/z8*9(o%73Ņ%M O&-\tu7 E* 'bp1'>na~I1CG1OFH_lk&&9x&FUв4NvIrh-&f̲vxb@ǿ8rAkv\t&dsA_`TUz+!1ϸmT߈hNfPwHX] 45:7KgSc Dx4kplH N!95lKty.HtьJ=tJpy"0^PK)g~2+9>쇴MMgSt(OX#R2?a@7^J 6JD~='Dgi@i/(anDGk!Kl`#mێY*J(+o ;sgA6G)DN _Sww?(cA_TI}m(}ǣ) M*@1w=lJJΪVƷZ̴ tO u)NͻWĪ'=2?&OaKJSW̅o^(.xx}Xip! pX4q#t!hw$1\m `Xn\*>br%e;v(;@$JJٕ%ay=ׯ{73E 6Dcz#Nflu0|6)<dN '%'zK^Tp" M+Շ[P?FoJrT6`V z;t$]Oz7 ˜ w d8M~aC \"0/ C=  xm M+ %t]t{j>daDlI]'Ĉyj;Pg[ԁ,#cq±)II)ְq(iWBָR>KK[w< >; Wd½IXQTX"1 >;$ksc[ӣ.Qנ?7'WK p7u` RhN{eq |Pauʦ1Bl,o!s ưؼ8i&[kdCfg٠m- wv*e8h1j4q !lX3d ln2ܹV(j?~tPƉ]XQ7}Y+&V1c &q†Dz`鴟z-0`7viXD{f͵aٹs:}bX@VC:F;jYkF5jkMSMf##`P~ɋ $kNGb]=>e8TWO Sf{ٰއoKT1l]yl aG`bauUЮ}:S6Lio $$W5ט{C1kB)jF ,̷"w.V/fֈՊ^c2|Q]o_l6 S*N;#Bf}HgFyDJU8F:Ƚl_e &3zC0CFjfBљn0jFIJQp72F}_@a 4#vJF3p:J6뷂&2$m?Hgetqve83:b4Tq,]QLYGq)0yhFjԣ;\:*5 sh>$pEJ/?NcW8#iͥ@ZL>?PҢ(܌T{(moc~KY_ѿ/=EGydގܡExA%ѴP[3Fexe FokϐV;p7kVHWׅH>í,&&s% aΣVgi='|Da.wSմ&>PtatwgOI] mZ~s>6L=>gObC<Z&cCon$cC~ 5ڲޏ`!q:<McY^#?7;f&9/_o}r7"!n59B?} 6>Si#dM5Fm~ʝb•ʧ؅Y1,#3v<9yI(#G<[BlYf˳ki1q |ʱb'o> nn_ȥEG_JcBV`<,L]ٸlwzX55 ׎ֲ 癁ؔY9ׂ bIh =x猴u᥅ݥkr\AͮY:4A_Z#XwONS= &,u F;rilZӼ ̃mYuϢLEzZ T˶A[ wIP ‚킒a=⻢T Z lKšB(˨h`汅}nvk7Sc4#!'[ǫpς'*poNH,/{O.r3J§f 1u VҘ0vkʾmhE궙ʑV+N/L%MX~&n.Igfgȿ< TxL!:\Jzxk>N Wb[k#fLFXE&fN,6.4hlsqٞsۖbb}y~==z]TvΌޔ3 n9#Q<7k)ͪnM#f)YޙS Y';iGȱO915$jgRb=ϮWW +Oâh,4Rҩ)Oݎc4Œ[S E\8s ћ2`;MC3$~漢vV0mnlpW$4h$ ++"Ėh2qEqvfIT5nSsy, r >H-RYؘIH0̿hR.+ ӸRܐ Ҟ,%o]V%\OZd 튐޾BX^D:{2 Ӊ%a`Q N1Ȟb:`^ pkwÝsnn2q%#IoE{5Z㵮X%HY8=;L`WmζO˛ qxӂ}/Ep/@o.|;ƙUb2-""4=S Dp֜ ٭ -$3? ݖGi{D>ޮ;PEhmM#ڑ[0Ctw>G:pTIxkdYJ»奪c%>Yl0ӯ;9r4)&Y9CNO=υɽDžL~n-d|>{qD) m}LȊY)舋7L! :5nT0g?/ŐCF4wH G_q G8J8$t| GpXLSSa:gpԷ\ꉙod(ݩ_0N֑`{s^{Q:Xx| lqfA}j{jaSk-z;-&=Jba9;q"; qTb:U0f'n'a)hTY`RLxgNuGa{]5/"(^yx&BQZԜ{Ja(?:+E&نjXİ`M![ XEb5}5UZgMyS8 9wFdgjƂp>?pz4e|obdhZ\[҅gtMR~u+/{O_j+ ҋrYVdv(FMH@}I6 2Λ˂fURe h2rf\̩='z-dXU&a.gツ|{e 7Cey6kJ`Z/%cB4t4|X8oϗ+EAJ_c BaT\`qwᛋ1i9^)X !<ㅋ  4T 55l 5=M8k,YѱBx&R#-WX̊xBC n*y:ʿcDx*aE%]eB=d*lzO6sHA `COr,8uo̵DӃ L f0pq2,HݘHz|tC#;X,ܓg|x{BM?hHU"yenj5sr^ < Ta/ X*_|T ӱ0+|.4x2$Cφ|ǩ!uG3 |+ 0-e/QgGM>2l~1yxUWipUUw. a  ! $Kx$hIXLZ *蠣VSSat(F pj\kvs>~%zDvb߂+Vר+]04UZhYb$n AKhGOI/)L&)8M& Bz,zFYр:3`NjItxlF7]oDhs@& L{hV8:hmd:DW-*,M JAMX*L7C%4)k~ťDO{t1$^]X}_F;#iDɔu$K U|*d^qF(6gx;r$}7sC^˥U;V-f ٠2S,e9Џ%]{wn@(‰xU[$ۢJ!~upz|OwΡϯp07סg!m޷Vb.]Q}rTQ˕],! w\=^h&:ܱv5s]{]DעZxLʀu4nqg} ׷qhxm(=x׿xV?ն^Tn4E#yis챥i:#U,x0w4H w7zCӘl  lkWߡѡ9*m2B.ԛ$dxaYT8|QC~(M2vhzI%`tDT剒e6Mcrv7q$1\ ^NJg z$+xbU&ZmU-:jdSVOnu# Yk9ؚ(p-1 \U׮W %Zmc&o -(ɰza=#4ÿȢMjSQgJWU1*=nm`칪A[msUbkfEX)hRu+_Y2PgA|%ta}֮iQ.}/kP=ξU9w{/w@iIK;'o=@ou*dJ]0PLQ:L=E.\wk'{j{ҸS{'I;/Zc? o}%~17>73Ġ<>bCj^WW'!w0^|Vli=](Ptm?(qqGqgBI; ne5@9I4Jw9c<ǣMxR@zHwDsc  zҢDzmDKᏄA Bͼz|MO}}|brǭ*UN*Ga['r뮎qgO`n)&G@;UhurۧNR v:ޏN x'msq Mry2 7j`ȁⲎ 7e^oe/&/?Wύ~<$PVȅ[LʅJ|_'>}c$Fe=_B=UN/q/?/pZ]*`{)/2߽cFt\]MT551@Vquh vH:J QB*#X5]6_MY0Wl+iMp"@yNI䤾[YGZZ>T;}=cx͙%o7`āDP 8/ceբ ($.k9+xΜbP7' M pQNjɹeaJ"ls*t^&oHD kEeb 2|?)h"m{ ~u[5+V:vk05^*]VoЯkZ\,ލVs.%D< 0[b9YDyi46JMe)_`+5xg:<ٞ7 4)ώDÓVO'mKKmg8`#(V" SM0Vep߅ k~爠Bێ50 noݎjFr񫅊 ak/\-WnD7jsy{P!"B إ݋Yw\ 2D!~ib>"QQD_pQBh%{۰ pw P'%?ԠcӔ:D6T0//QP͐?$Bb#Dо5PQ ZO n:2dmQNj$kQ:Nlp+;cJo@.!C Q0\=t:[(NQJ D^0J͟rH kёMdk|y =ݺy*Tm&8-?qf9kY6चg\otޛCTռt8<(96 g73)D@xzfsI\vETm%TptT ݩ.uo!:` zr}+z:(ѻ-8D9,w A-4pȆs"up2"_OP!S@YK4ԟY2[ 6UmL"(l_ (%܄7 v,l7X~ }%,ZfQ?s(LPTˇXU[V^b? {t)Dm 5p 6zx020n6u}z-x+SpBGEUd:\hO&#f#͛̆EQ# Eb޷x[$6 raG့f``<S|)L)-lc۲Y(\ o΋U%U5)am˃ҹ:xTac~Ŷ-<=M -iS 5D 1\xE*ֆcNǰoC$7(%\ 7*87*1zz %V pV(G.*&NDžQm+BTOpaV֣!7 ec\TGQn^jr:ΏrSTZFYAS1/uM&Tghkpq1nx;qejV7qW\Hz=IXO+^%f1A]~;G'{nyV[эJvhQdx7t<wOYuMı;aXZ`+ć&2g6puLf;Sa2kT4i]5$WmҋŁ")hUDU |B]ۆw'(k}a?M̋xvӿ,/ķfhXV+έeIY<[JejHHCө~ Ѻn2xz#u}</r&џ Q![#CnʻAj#P ,OBL,=X)jX FaYtbi?v\pG&yRxn BHKCڮRIVviϐdو }3uBr8l ks%O_Q5o^ͤ=_O{Xr uejի6$P|Nn2h2r7I*&%f%fW{eFTiɐ Ҡ'sW=jJi֗=A^]9csl]LXcrahąTЎGv>Jw5;zh7=-xz( (ͱcGx{r#e7BŶ;H҈W\b)+lDVhp.]1P,aAPKµh0tvSrH1 Wq .L"w_KQ&[Cr:2`7:|d p-<Ü {y85 =%)Kׂt>PV <#s84!_z2PVB۪4}*[E֚QۺnL֧ 7h3٣ڱ-dP.߇ZH7ʎ»G)uo\5$ J"f4% najg!$z.| ?wO^jfw9uƦ; N%ؓ8"%o^;q B]>sSlsz=[*TȮ e ^Z±@WnͺB͊fR@)_j8_}#9] *$|֜%$W g[kl#+ ą\, "WZBȄNA:+[쒛1İ 4bљ\e͸l]ct_nMnf0\carpoXn 2o*3d9&/eVgeL]\sTwRX4$PbO/ xP-f ;^~c4x蝉tɘ}GziB'Q.@Oщ|C6󨕇ђLꨨ1\ ۠ekqԃq&˦s>KCJ:$ TK/|'0=n\)&j_2]A$u|[R\?E$>54c< G+JL|do3 ' Sr`TxG-0z;aBʊpG:X0ghl\E2M.s Hcei[7":. 2ϡ~6QwEPKyZ! ӝ֠23JCa8E B k0|քͲtzJBۄ08-V)X$GWr`V@B5twJ芣#FGOٲKԀLɿۨGRu` ztw8+p+BfXgxf'!ohhB'R8ǫߒMtc^۶lN7w.bhPG,B_H|*#ϑ~KnFnlL6+1j?‚CcĴkc2 `1.tx Kǚȩօ՟t7B[̤1@R{d[xhHǜ.tVsk֚vdP:r)%"^0Q4v1N7=o>Jz|z1^~Z.(˄Fdĸڡʑi.3qGUMUi>_UF~Lr s|Pɍ>ѯ3zs ΐ# j$ʨ8Ƀo4lWlؚ =iBeФخűqXIo\$ ]dy廃e;/ub4BR&vR_Nj N&6N/<<`Zx[kxVm9?s#pF(f@eHa|5=(ɹm3yhU1dL pDAM/ʘuO؝8!q ʀ69*d-Ts'!d|#^Hwңc1;Qg.CofMK*YT&AJÆ1^9;tSФ\ggukk5TB/#KxISC =PGWd J^4cdBdJ]zH֩oTY;T !s}kU Ww D?#0^ׅˈ-\w5)B_\/ O Y X$YztƺB*)&XW$!K.]|k#܄gJc^yXΟ%ֳ㙘'g'aT0]Xƛ?M19x$[.d^"f }i >S!g`y,[GM!u S$uht5 33qZ,I- =G Ǹ ޷*H׾զAC83b{^(PNZv3VFKs2'q5ܜ-\`%G ͼM "c mi$߰6^%x)RZX̛498OE&XoE6)Rn ~솯J#~6dz|7(Gg.[[a=P"bԱ}Mku~:3Sl',hmKCl]>7Pg|C{%H4V gAH2<{M} !'`s&=!m؜yG2x@V ƒTQ]uSC4_neޯL\l`*kX5=`|Vh3dTo&{r1ߝ7ͩR"!#CT @ZR\Vxad!exX:*wa|zfkE>[HѼw~ nOgZf^.QF^7n9j*q z'kfQ]&Vrہ-/ ٷ7"qg#+bwYH!n=QkKq:XPBIp7~.QyQi9uՅm6x{u(#MUA3JD/8]PBHȷ222RHJL/PPRUIK/MLOR/*)M/M-NU(*q,-/RLNM*-;'d{>i%%ÛSJsʜRRRRRRj&/φqSBۅ<:#l#4ERX($(/H!Q81'Q!7?%(1%hf71%UlRMPSU(̵R(N-QHI-,HM-R$1$Š Dakxkmadsox͝m\uOqJy$㺱}&$")a'RQq?H]cQ₄}*!$__k}%ox4}k秽Ov{qqb8oMGI88tكٗg̯/n1۟_-f_>2jvOT昌d 1>?Bjٝٗ>}Q[;ز,;71Ȼ b}F^;wKTY;3ٗx C$?>QCh3Xoy Z{≂l3\Lgw tki@<@I8u("&zmlu{c#5Yي_]jy26/fԦr5a_M#wٽnZwlH<'̿}+^i/{[q1h64ׇy _^%1IQ7+^J b0i䟈؟_sK}b E;5xA%uɰOQ?]>#@?`w$7*]e4$o:`I-( ?M{30?u'0,B]0Κ_ux@ۺ^1dCѾ^GG5A_͂]v(HJb 5u+F}+m$jYXlޙLfogZC#m}<-Nw0P)>2W@AmS?LEI}P0::Q }bOĬʓ~&>7K^eIHڐvg+|gfF qt&6:h|!3$eN?{/.a-cI: .M7VeR'\ Ӿn:`E.!r1woD{1)3NtJo㘠r 5ȯosd1Np-bg|2W/V.A7ג56ppm:n7zxYý֡Wt3#qQayh:m[,ʔzјTpQ0?23auY!%S`ׯʹ6iYo^ՆG}YLF KR yتw*Cѵ^R%F" S>pKngo{|YN/\O\C)+n8ҞtJH7OɞRf7LC\7K]|Kw+=T|L #= 7Nw])^c2).w9.W &l29]Ín-0:9Yqܛ;#f 9 9ARxx`K0QRl,MH) Fer^s5r[Q; #(gR'3Iqv4&}DC{?tFq 9\R 7+/ ҧ :;]'~ZNugKyٍE?N1kgN_O[vp_mr';rlsZDo2Aft_!s,!%(W/GeAS=ŲʮrW@ziG$wȏ4G Z JRpwfwTF, 7}#/JzPf3X$9Z^t~p0Uٽp^\B&rh2.Gdr0]- Y0۟!UmJk\Kg>v? M]IuǢTt$ NJKi彣C<H;>\O =@:G7{x:Wo}[t 4!1뿚\ހ硓xhWĖʓbe1X*iMߚS=OϜ=oOYG=1J sm4v`+T AV6:?ZԶ*H``"7bE _mEhڱ\J<)vsQ1 ^gԽ`8ҽ 9oxJHn60pWE`;n.8b"{**I"8t؊hCB0 X^ۻq\m%~!"Xv&! jqalE[mŨQŸUU/4#)a?TTUY+.Pr=Pb+_ XυRnϐTcV8P#ƕJzL+Z;S;t7iO/;)_rJ%q{ d}$d+ȏTwC_:C#xu`wv'{zoC$*I"Fz(dCG6D>Yaư`>T9V e *le*STP1Ǜ0n*TP帅5(44Q-Eڍ[fcX&| FQNrI#B&W-qBtvߛ:yءd}[SOtȔJ?<\ٔ[Ԗ6 eμrUJ|ˆ~2%@Q ̊XUҮ iKEЃ>5ZC6>켓#!]Aۯ_K.> Ч f@$)]*YG)D1p<:3w Bz Jf)[ygW,"$c +jɣ 5QV},iu䚞"{5N>h`OUXD2xd DfsfO$!qPh40e{wW}ll(j>u G@c$Ne[a'-؝߱"E2}(.Hi_6e,n<,7CC\4sk_3 ?C#>'pQN+͡ʤj/jouU_< ύ$L8/9(WrKC[6;G 9c<[SZw<$'v^-HGVݯ`u& sFy܈h^YrS2"L"kp~T ʷK:F2V=U#1uX襮,hPn>ܓâZm0Ihgߍ@Oԃ8 ; jU::^ʓdnoznG,9 |Y^yS/!pRj+NhF1KhK#5%e FxejTI- 3} s8wҺF Ї4_99,sr=Zn0 Gɘ2))H6MeN]! ȐPzyNͧ׃ưrjQk+X)8##V=*Y//yweºJ31 ǫ)?S'$E4qlsPIJFgT$P.w1%fd/ vVn+!d0tyMM<2(yFԧXXI3N`:tL=\nf]%dwe8G]|?7wvw8 4ƾFdҤ,O <' *QV.H[2Βd-!!)rnn`[v,C{]%:5>I?aeJpӿ56Y ϳHz(d)\@EC= ՜5s[J9B(ߙT34wݾ2'T"09:@-;MX鄥WApr[hL&+tP^a5틗幔x|ɴbqO u-YЛ:c--g*ZçlwOJwX9$l~HX;tEBwhB¹3Wt:6Fɦ7X oV 7!} ZӽF +2b2qg-fkЌTIdH1h+L%u~ļ+ٜǺ5Digۯ"i+ymĢQRl1dv,(3濭1WZ]lkh׌nh{}Ba@Dc#4~[&5> >9qJז9lk%6U!dO G =K{NGtHm|S|hNj|LIa GVH)Q$iI/PTRa(٫YkAh J:^]޸X(07c'{č*iP|?*.zA)k!ଲ_ trB>÷ 8 ] R?+8\âII3KSO(ITC͉5" %R+}LN/fo0% *B,AÛxaX&}_j)UTDq'yI+'Y&!UH?k(V#»-2&s,?"l>ƽwp`Wp̶>BQإ6!OTK9>篥 bmպ,ɐR!+_@{7:J4)X"Q=K\J"㆘` QB?[5¦2͂C/-&n1{ T3@:M,c +Nj]Tp \X99V D;]"¡$SXV"|l5`GZ)!MK!*25՝<5ܴ-3L_'H؊VF3LAsm \vFX?4%9Mn"M̼baLT:y> y MF-8MlΠiP{NM\ |{ŇCVrV ah/obK*Ӯqˍ[n‡"pjXR-tn$Mkш{r= 5T@H̄owXr#RJoa;_Y $[Y#v#n5$/~!d-H{ZQ+l}tEL[0B[kI]_74;#=K1Fγ#B|!UE3WM@$$ߏHڑ\8:xfmnKb9З1=@%tq D,QŁZ8:lQ*߶1|g}E1iW,G^:MYm1(eijsYՏ.ȻdYsiܻ[B"/ELv_=+×dߊYit =hF4]B:週ih Xuɛvg* Á){̹K-Lv3\:o`M8roqؒjw@# dk7 7JvݏGmkMq_mRO:yJ xkĩ_O"f ȔE,c!Q_Ad+%u㖮z&x+-p׀Zj4;呋R鉜,UA9k$tŢ;R<`9_A/ F|#&onW玟37#@ۿ=H)|_={=ױKa5Vsr^98Aؓ!);hF]:{72{ fU*Pl:׋q{{XscQdH8 G\xv8Z:SC'd8b>H)۲FNB^Q{XrmYiއi>d6m: &IOKkjX˙ATl;2E!03m.Ζ#/8mu>=- j_ Hvu¨ez@E"[åC|&rXõՑ8n x,)wdɢnɎ~ఴ;9t;B5LkPdq`#iq2n:zu6 ݈n$柔zL W )EN\ViTrp[ t5R*itSIdsPmϠFRpM~^5.M9},I׼PiTAk3i>DRg#r$~NQTFZT*V|-~zn4ۃ@+I4#:$Ï& -`W܃99szCR$j[Li =秸nkDNM} "[WF QP<3"o-?~ ϭv#&m~ҫjkne&* utϵuO7:B1N }'!#eغ˕w+ 1caMA3 ܁{ҰV&U ChlsNe$7.kU7%y(:ZI- >IaTs)K&7VTtZqYOEa [0z0u)w=Ѝ%X5/m,4/[修z;89?q;awKqŘߞtQ%]oK˘7:T=$Cw>)Ң-ɪ%$W7ڦ~b?WWzD0znuzNw JdM pTg0C~ńƲ/˺=|&|#В"!']'eC].hRk'o';ϵ7Eg+U%-nUeƯӚypjp'5NO3:J Te8|t4rdBE^?36´H$MzR(pC?Qyk?{hxj$[cϰIL{tis,OngB;A9H20a2y ?+̕z0v|x&I)jh$DW5yC0ZgҴfU|3񝶹v L_>rk oU\dHoYHO]5p#9r_W`(I}i0-4m+rc`- 3˟8trLS_l5o~V9°x/GIf(<*./Sn,NBRa1*;H-tZ!.O{Y,|Rӽ\^$rD-,Tpϔ>TqctNX;FTh9Jk>aF!%֔d%|9xңb_T@tc*}N68_$fz8?BlPShS٭!)8?H*8w-N\UU=~c:y5CW(FUyΚ*x pF[;Ip ؇:,eqN'w`{RRUw=I eR4 zg^Uq?ݜ؜<MkJfkDҡtW9*4OضtfܬDuQ>G(\J+J#ݔ ]ݘ:.^9fQ6.e+EK 9O'%Т`ogCkXD',L([ JJѠ07ԓ2}$,S3;^=fM(F ;[q4Rg)ܷRW|@wmfNG-Hc}aF@ I9s߹;l{X}^;G?|Oȅ*H$j$o)6" (-MSiH"֘z^粎FBeQ ʎHGʦ@Phq]{9tƉך6lg:VNoM@r Kpm*I"KaGl9Fl\H!d ښ/n>ʂX&TT|f3\XSEV3\X5AQuՠ^j"&>YI׷z 4ՏKy'2o,wXq~r!!WH{Kʃ JWe4AY{xTMOQ@Z@*1" D 4Qb\1yIo̔B(?H@. ĥqaP)bNqލ7EA7ӾysW`.pšyٝ2\GuB%QeF#D7 YIcg^biv^cϳ. ,V`YVXi Fh Ú:C@@""Suش㈖BM)@,KY|y>C_}/&b`wUTU㌜-Бΐ*M0TMQ6[!e/qRpQSy:t\ޒ6)DIDـIA:+|,e:Dk`Zԣb q4aYL1y\l}ҼwOnmOkS!$йpC @3VQ5hֽO.7a歃'  $B&ʉ1jh|nT6η #3snR}|W+釦_ )xK؟ vM virtual h( ejabberd6+ 6 ACjuJQZZ f)kderv$s'yG*y .yiVtregisterʋ# ̮M.CxWOle"kEQ Y@`44J̷3efmmWGLofB<~sYibmvcE']"IP4*g,1y.E#kq e1nvsxKY'G°ةhe^D嶿c0M6`3f 9}b^`\/zlpnCS8Np1 &C @*FS~%82 䄬o~>j| )R6Loq|W?NQ n 3\ãIj g`nFV,G x*'tPwQY J0|۫kܧivKeǰ-t n`*֢j`nF#.8.vo]f;1< b^B{M ]}P_dA+i`yp~>EvfCɚP~#߰t Q>xa(t]Na1@58JY#,q=2 Xt6o#bw%8ڭbh2Fg`<&c2,߅5wq(sr^;B%audR*#G,1e[E?;W4n:o^‰='Wn7÷[ϯJ'z6>ބ8n;n@ \4۱epq : t|L8xr9 m#vB2׈o c-p0l(>\iQ|Mͮ=>F҇q@Cɷau@HB MSVc-Z3Ϸq2_JPBE[4]hsl G{ZҰ\a4D)nb 8tyAs |-Tv؋'lI}j]jwlSmnv`9ӹIIoQIN,ivbpx  :Ό{ Ԓ:F h 2`u"\dXYhg n%x[qO 2RD6lx[qO 5* Z|sbnfss:.t5B5<=x}Y pי. Y׌nt_ht!čnI 3CO06qc{_NeWـ-Z{wkcϬSԖw:v*ٔ{fz|1/}ο]biA/0Z۷歬l|ѫYer+(3AaFr` // ?z;zz9Y܌ lxV|z@YV]PtYuէ56#lU%WS-i┧54/LIv8GOhBS^ռW&Ԡ摘_SdQ71H(EJ*N !vHޫ|"4[KVfp\z_v'zrUkb(jPHz+cx_ ׎ݧ$7}?t+t;t`O P̭ tm/kp[{of'):SSR/H $O,MMy=GN|Eq4_M xrA9)!$qu8qv7B[V&:><G\l0 _,C%VSmc-r85Qiy&IȬ&V߅]?~m<Sxα냅Yfhΐd0U.X1ɧRdɉF蕲Ry"C]cp6'L=]:B w_lȥ{BBr_b~ Djw6=ӱe&C"+wl:GRpY#(kqݱ4]f}5*b0㫡dC˗/o!#JTޕ*xXʺі~Q֙KS˜J.[ƜtˁLDM'_=iEP2;>Y:.] I-K||ӀGǂa8_U_)_2դqV \n3Zzfbh% bU2 \ A6w9YAA& 7 *.6{M)]x?,f<&/"aCrPu. {0g\4,a*@W8`Y B G9eW2e?rYiA4!B6.^^2{:OEdqФ 8.G >ٻv/K躷44y紲L7MGY㏵2g$ Fox/Xh+ O* >Apϫ֛w3GrUj[Z?-,.M!'`/SG*qrdsp>`ޜ8Г< w| %.;zLQLAF'I1G;K+_eM%aO=,ru7|;JV3 i KQSF`0Gi'<ŕ1D7Q] T"Ll i |v ?>.2 sD5:7e7 z̿\Pޅ$цV! >\8b6A~:6i.9&a7䦓<8>83߂>4<]Aj .0yʌI5|;՝[,tMϐt݂lmެk3c&D D1%BMܬ&jջaJ=Tl>3)e4IφGR N@H@,oJœvu0YyUԑY!ܒ`(Fvfxi2c3-U0$y"(v$*9'jA-CD Œ[H+ekߴv zPr"T7SraHPƩK*bɭEVAz ;j~m-rH_Qwb,Dv,_sCAE'АLʡw!2 !u^hF_'uh_MRzQ#]5 BC]ߏ Łj䉮D|X{X3Y7ՖD){6o=hq s]еW>| K=f"lO ׾SONS|4 {ApaRw q-+u<-bMf3tY>/#c݁H7Y߾8kU09K̛p #x32m̓py4CE&QiI)_m%c/CWyW9ps{o[˞G s=w/.XSG~ " 3F%ڼ qEpwf jxk iٕO}{HcA_k1l'r;a݉_?s]fe?o/%?K$KQBK *UH25£M٠|S]3Į;+ X2'xe!mZAc X;ܴF_4&zMGE&O]d2ˇyZCEXz|L?ȇ; cgS~yelٳd"yڲY>nb Y-;c0F fgX/-N9Qʳ& hmf)6PZ2(;O5'8huMPQ(+/KMH< R~CS^-uKklwQyb\Z5rQ}*/Pp '4A PE̼nt cJ}?~bONYW-ѺƵl,_HX06x ,S0jDŽ:":+"t3R[Q$ Ep.9+9c}W%6<7(ɮ/6cј5v.gQ(S;ˊzDyOPcX|8'8i pZܟlNS(lșBk峡FL)׻I3( q #ҌRh  X{y\ׅukmL-1YVLSt<ŠkGtף>33QyQFKY%e(=a8Be%F32[Fu&4`44ji]bW^߈ˣ3%0}\Ӄ#/\y zy2`39T3৓mkVLNߘCfVn)U7&_}g6 kɌXR'^Fו"Tid.ڔ4S1j#ӽxίT V~@41lK_J` ^upL`ƸG:Jώnw &9dvOqfOF[s5oMJz<{iޯ3]0__N4ݻ䌬Uś=]3p9i4g4m:_@z?~B}`mBVVsZ#vvԫ-fujltJEb lcBh)Ir#2qݚ= ] uc5Ahەe)lFF{.}8ڸZFx"hr莱g^7M@+"e2Z7{ki<*/Y<!0 y|#j"npINS8)N=ThBhJ@3*ZBYv'MaŝO+s0TtiF$tw^0Ak/^Ed͞ Wk/AVaTFf (.YӃxTu)Z%âc:n+ SZmܡs9_kUeRdGil )b~E9dI?1QEeP0]p0,vms&7ga7x;qCF5U+RtC### ]#]#CS+ fFUns QjU"6^HexUoL[Uϣ@ D`K:b?( ZFBLv5. qAb271jD}0j\1&,1bss?EQz.Db5;Q`wG5)KJ"r~),b6yDm!N@ն)>L/MN,W [^7mg\v 7U's)BlKWKhظ)z/8\ !#'a=UFmלLGǚ(b/HYVM,lޠL N/́zq["fiu:zR)w[0V\1o-_Iv'x;q FeU+RtCKS# ]s]#KCC+#ÍV>}+ Xx{rqF]U+RtS#S#3]]C#C+c+S(ĜԊʍz3sSSS3SRR Z}SsSs3*sK'*K6\ d0k,_zARyxxuU_LSWŁ \mc-D^ ̀U {ϗe[M&Z8aӖ-[̶uɒ} naMzݧRFRםj'zE1I$F`9nI= *clvuɕtf<+wn.+7///$Ȯ P]t]ʶ#vL7HZr&LOZ"Ę4aس+r7=(\@ '^B>n'Xufde Z$B&;WIЌˈ>rEpӣus# OE/!pop̦륺)vr緜M+bG:e$L'" pو*B E W4%ZW'Z0!Fl DRL&K9sՈTaJBuUd EhǭH1'~p=s/N*Z.< ASJ2#6>Qc֐xGk"]ΞP|B@wkyrmÍFLJM( M+y+^txKAwydF6u99c`$as,T-d#;+yu:E-;Y傱(?h|f\&5 81t;SŎioUwv7u*gTFwsۣ#6jSu߱Wk V'ksQ3T"}4?vq!e -4V|\C%I*˄ND$c|:gM1z/W*g SM Oݝug8MMgMN *mwu~g!^>9WZzIEI`${y]Dtd~z`u.}2oMYoۛY?=";XЙU&&b01ӡvajc_B);L99nf}Q_hH< i`ʷ&Da3Iv I㗱K9 yd;7H2 k{kՀNU&͌ڣ\|;^- l.A|h% :O %"_5>\o/WOļ0)؅l 5jpk䓲#ñ}_{;E`^<H,{~pt2~yP"S>wdO܁U8By~ "1N4(,}K x͜su+R\@*H0A Tjvw vwf3?uYgQt9,}zfvPT3ݯ_~~8d,NӶJ,nݽ\4YTu.[Wir<{uێPܼ%%/EVl^'w=h, 5<4"#:&b"ȳI2Z%uV-q,Y>^ԡ&!u:ϳhۤH&]jj󤞵fWL E[.lsjK_ =XdW.f\Xټ^Mv]L&hUɣR>Ii,,;WֱqF>BEyP`=vHk()On\iYVH/_4*6 6oXFILarHN<+&rg 4,)Ifn.]3f6KqƋwY3]%)f+u/ߤ)*e^/xҎl_BAdӱ,M9oiӭXRNJN+v؎"~p!ϳqEʃ*ɜ]67;bf*)!Vn5):MεYR)kY#pt"[; egCrsQӛ jpo]lgfy3ʹTmZ,n2sPE>jWA}-ɖ(q76-޼]NogB@4-䳯}1q1a*dt53\e"9+E.ⶵa[YPQ-yLi9*I>-Ve!! N&YuXjBe'*9]9uK٣dR&hܺ)ʺɓs-w/W1{|2@Lӵon2)VQ6Ik4X譍]d=4l"p_փL@ . SNfTt9ҫwFfS0urTQģ F7P ˠr50H;uڼX9{\,HhQWIrmtZ0'csM5l*B4$ lw_YN6`:K'I *een̩SH]8ݔrsZ m'YL7^ffY]J*ۅ%[YL.biEB|PqlPZK@Pih\7p7aUU6 .zI@ Xh39I= v@GӝOk=iC`c-tCJG{.lp=ojCk`r2xצQĴ ή[oQb^pCۑg?:<5@cZRɬ<=͋SHLkos~׵O9a1.NGx2T& ^xs'#ܮt:E8UF d[%QLHO MNd/c:(v ˁ0)Z;3"]dU+JS&Iz.p.ZMD 9/T8LF8'5m2휂D Dptұ/[$*"n.i}?ɛҍ0aTPr:!&ΆZGZ {)&aaЖ:,$ZB§mQ|XJEYKPp އz{56/ C#&52֡&Fka˸9?%rh?"P7E^KS̑@#Yzu3-ۗβ! $f@S݅u9BcD?V ¢C޻Nwq]wn;y@|X{1>Ϩ"ttkGszx=;[>*ծ4~y+fxWd͗&_ޚ/>g?pvy ]>vQz$;{u_7O>$4  }9PmC&`Wl~6Ժt+>z?>:2R'wǟ?HXQ dB4d s,w$ 05H|H::oNUJeFTjdsR QS~65~=P~z3>n"$j1Ôqgח߸\teGJ*z%yq rkVOX5g#SUd2~lK Ҩ;`@:SdFlC.Jl?qO󴉡 `'3w`t-;qCC{ocj, jE3k(7hQ^~CD(6Xr8ئ̃Dx!7R'O0 ɓh>=3.FNpYϲ ."n !wb1D 00sr5:"$ے!O})2{dW{)2Q ~KN6u4+C~ͅor8mA Rn' Rvc zg nR2]n{dVFH@gm3)_)H _:ɞ(Zlkf03ic9 jL=Pի3!^B v,o7\h۳Zwc8 QO0Y0$!zm-űgWhdoFɖgP/q~X(= a HZZÜ.Y I56"MX@ʃP6ځ_VY|I 0ܟFƑ#:ԂZw iX,i$]+X@,;]'wa52mf `V$ֶNy##cw3>EA7u搀 Ո;}4נ2c(S)U3 (t>r C 3}>|4S68*yt 젰n𜁰(&b+pawŅFrWd-UՔ>fkj'!GFkEdlj'vcX<+s,dnAsJlUZẇ|;mO`3—ihtb24(<GcRDD?+CйO)YrgRATI^=~"'3U FME< Hv4 z#0w28J<'͢TQ8;:i{܂gAƔW("K#3)i%<xW275p7֩b,J[r$D;VN%j+`|Dt΅I1\?x0 qXς-퐏7ǸV1dka(YQbܭ7ȣG)ꋴpM:D]'B"&o@✶ђJ͛E9#®c, JN0`kΤָcLr$FׅZ\}ա{`PrG΅c#uNᜊA÷үy:gjQEo?H؂pEOpZ(~vXxI#ުl)bHCxrOPC#]qH|@3Rgc( /Ho^ wWɐN&#_T\=U,yN  Ҡ!OO35@qy#hp=S?$CI h!X66s(_-k<]v)ͷݗk1Щ L\_3F(q,,D1S$jTZh*45zxlFVYRU`RD4qy~)RD56&C #.=ʸ_%?ў&HF~4T #!TiQs ,1y:8cZ8u&'l1K$pty8wja#v qQ,_HnVT\2JkUT߈=ѻDu7)^Ifà7m 31Q &̌2ՑEEG![Vc5)4ibڪB^6v8ӲX?J(Zͧ υ]NzГ  O\U+tPrjPΆ? 78/ b\N1Dخ0';ɾ֡kN*sFQQ4ADE64{6x戹(7*gcDP$$tL2q-Q<^ h10+\3п1_~ӵհbn(OW^PRWd6]NUZ uHZyNabo(Eǡº>꣭ 6~'q0sİ,4сx$S)J?5PbPsFCVY>ԫVZyV-]jpv/r#i Bm) t`$? ~@)L)Oɉʇ-g?> =>nXo;ua0W gH wnD]-;k76Rrf^[5^2Hbe_!&UhՄDŽ<F"| i?7+0H+Z+ρV88f4 NQ^;rn2p@53dS7mt MDA@)׺Yݡ) rWd\_t,_}@ Ww[H B7ba?d -+∡i2.O&H/%oSt:$) eDžYLN1ՁL4AۜQ8M-A+״d|UڍԂý.͝}bþGqT{+&^Q7\[ޑ6KAeP¨0!Zp!UJKjNb7 8R./ؿU2Km ׮$Ԏ%$\BC/0Dl8$BBZiX3g.JB+l:08 F)spǭs8} @( (*FZx)%r*6QT<-TJ%әlkmT>xY%k9tFUN*9Oar'rD~'[8 :pQ n.30Bl2]â"xiJZ:pGհ <9e #T}ػUeQ! f4#HVGy8V?jX^7q2?6gl#o{TFƽ}V!1C} ~})wrh `̷Zjγ;Շޢ&dC! um÷x=<=O^Q._=s{ז]^#zzS)=%ȵL#ze `Xjpz"{WS/ *2+^PY8/ R.Bsj ޻ }c<.YDڴp;L\DVĥ&BeIO\5]> VU6^PkA'TgՋ݀ôP9|"bv;wQDdB&'|>D2yx[̮6j8:prZӶPYuUC鮭nq7Xⰺm7=$F=۩ER+ 5 "w(J"])\0W`P7`s|N0I@CO#[: 1#!mke~1衞ooȸM*F*["C6=O+g<8QyE!H"/e ƍ-Q@i>!u/FSG|w7|#.W!{T#[dx "Kp9?"'\p§ct~ w]ʕ]R1*)c l(G ٴxpg9RQxT3hf=A 80p7M(|g& kHd)~`h83I*T>. nloU@ɰ5v9=)k Lac k/#nr7Ggr\D:iNG^9fߝ"u?#k w}=4\ّ_ׄ!Vǃ ?Yj ^T"=P֔Q0OCr%敲H[i8_P*#/&=7 9G63ގBF/4 oB*kՅ[-D.}˼JZr?zUw_ؗO1y;)~FS}g)NA 0Ukc0j!̡>ej.9}e q0Vf/yZf̛â+nx;6 "7E38 x;f s86O 3\o[ͳ٫M %Ex;f s86O4g4()1 h9Q-W+޶gW %=xۼV =ZΎ!+KUn>Ŧ (d+%d)($^W7e󬠙  x͜rƕ)PʅrR-RlQd88΀C``(1*y|~t7ᐲ*8}'M}^.7mޗMმͪq?}To ևm=y`&zU4ñeϳ:LUoPx7e=0%S$\]7]!G,4By٪ˍNQ V`Bi4w}o8M*u4#a6K/aܬüL4--y{YE]6 gFx_16P&CA6=x$bn g AJV,I'7À@bѶm87Unnїrv|{/@}B Ǻ_Tl`T~+ًyvִ;[?(?@沆Z HN\3H_*qd5ڂU"⊫(G ͡\[]jE^L\Ptnm`Cq@qEw"#&\s8Xf->zǵYݥaܠ[W5꫶٬N}WvȖ-:?]j}:M1҂VL64\c$_㶁4XK)x L!YdN q#[Ї/wA-ţY2]WgŠha;8A[fGO6ko|Ł^cZt$o;[e_aql$NߑMkGRI8OYf~՘ȡJf_,M%~r)Û0MA%sQyXѳπ:4b ff3 w]Ig .t2DKph0ˑ]`ƙ.L6Hp]a}vl׈߱3M{kQ t %"cI%5!kWh uj10Eu놘Ȣ r W]MdvØWT.ʗ:g w 7+!=$6dq;?t΋AX2iҴJh9z s2zEeckb5(cr^tChklvn[<( &_/?|l珫q]?x})?~߫+z0cJuQ?>/·Qe|oѯ5} ?8&V; >_e)VEqfr"I#٣)*񳃧~6ò{}RE!t̢Yx2O#|lJ$J` rRJܱ{xJ,8PG8k7cp /Zabw]R27|Ɏ589 ˨a[!a>I ?q=BF*4j3"-rD sl*eYѿ4fc2s[u9=yamDCc$i۬Ddqcn֨XO7q8O}z+zۢ 9"DZ)5C(Yցa>I#`%H'x=z*ʞN~.<1̉n -y0!E.e|ӣOhSe$]!dH1x~grs+]pXH-F%yA_IfmH  b2x3`. ,(ytK&˺k"BD_.6y$ΈgKAOhqDܢl Kw>3< "9D\s6|waw3Avp( vhBMWU[xfnn`fӭż<Ƭ;Y,.!$dΘ0&Q2#BvE9O*MS48% X \GˉcD~\Cj_'e 1_-Yёdud.W ZN#1ViuJcY nF[ٰOJjNQ̚`t{ NkNn=#S}df8xۺf0C3d'#FDv#J QLL䚅Gxqnj۞ nGnhPK{)p!w.Ek*t8l$V8-~ t '@)J2EHm 76%Nv!T%a(_q,?kP7q: hz<;łx0n-[kK.ES%$ 2ɿKrLX AG4T"[-'1yp>Q:㒴g1Y-UU NV\Ii6pLk>P%EVgB)<t4fqͽGVlHCҋwGidXKB#%kr-'r&F.ftt'P~.AfF.0>N?X٨M_:32lr4(bMOA=ͨVCv5+u`a!)ޅv=  Mk b'wTqQC{C 襌1 8i+.Xt_W6k\;A߉ȯp1g LX6^2ϯQQsQA*$W)WT|s֛S!Tt*"7/;@T07I+*x2CJDW˺ļpkA!IɴN9Ćw2Y҇@sE%`"sE3 dR]+Hր5 U+1McwSɂ<\2vt(#eVmDNuaJbr1r1|FCxg[F\\n3 AgD(m?h$@xJ.,_ bmQH9ɦIw3`¯AzP "2j -"HuZm2դsRv|Gt⇑-P+e0Wj@/C\ =Wpg3j:b=T\M|L|^4>w0ԅ3"xk)8C$ZT3rN]5(\;-Q`\fK .p_x JjB6$.$!F4$7&y}t&(`:l.n ʭFBW"ΐ LLCz;;жs8VG}LlFB*Y,CSQˋqeR/3SqIfFL(!(8\-ۡ(z|oT]'#8T&R<'B:V߆/X[lbp3Bo^2u̯[>n{(W胀Y\(WK1S:tF>]PlM8!E偬Nj,`]J+xm !wĝ0(,}x~/{=;yN0x{?TS!3(( VpWRbidp,(U2vM{' F q`9a_W"5`9Tr.k轍8dM@_֦e&E2G~̺أ׃ ^NU]DfTd q 3 pҾFeyfR cFp&kr-y,0Izc]Qwhuqc(I1$}`Ih9t N>m?$%}N^HTp ϼf .BĒф%f`o iڨcx(JB|XfsAS3 SvgP0Is>nw̷#4KVbM5gcYi N{10|]}- M\XG4*GN[=U3o++{6;goL1D(,Cu\ /X>A l rA&òŖoϕ)^EJSgoFZ\1_+LWQNG[W۟|1ygx[M%;7R,ɍ KA% h`ﲞ*nC-qUgg  Sc3a т Ɓ.oއ-5#p; (2Yc`MaKm.U7GeF54] V@b_[-BIc mfgyD=0$ ^KR4?ePQoBZf& )ǦhZ$,ߐkK$X|$ҋBRcl2RYMwPGz7msIN»'Gգb&;@-PFXyǮ>7E?8NDlvwrz|fMC1N4XkN^*D qJCzH=I@Wa>*EVrǀoM£"L*UˇH;66xBs |v+U)4K܎M}'=̭aIm3'm#wpm#%Af`HR- Y.p k'p?URd>F9uAJNH5j|˞rEp6~\i-w'p/޷Oł\#1j'U 6Jo_H9t<A~Y f~H 4Jqb IOĢ4:%H*hUu/ _m'C?zAf9<;sOuzTdJáhJC :]r[#oP++ B0 sV"|&(%C@:%ZZ\ ?a~'n; I [ua?enGu?ffhaYٽC{lu=«sa'SǙ܏ؕ)G"9"Hl M.hX ¤gUהھ)Sz? ϤE xt.i܄*6 U ZqBx[} U\JJsࣃYx2B kBcekL3.o' m,|ivP^i suC,V:z,JxvTIZC5ld[v͙!~ADxfO:uݺ5HZϡn5C,󴗶H`"IC5r徦A/ 8X U%*g")1WTzl [9;w@qْm(3rA| fDbN-Ĝeq_Pu"eq Y;/3l+L{1$ѯ {5"oVKcLA*BZ$*:RXwh>ŋ¡ w-71[Yȁ<4%806q'ұAĈ26l9dpŁjj ,h&76_/_9']iѻ߸̴GmSOj /nK4G7dyY ˜ilZGUPYMZx'Eۘ{HLK2â+ ഝRQv~6 "=|\Fִ} WQKj"-Ef!! UR-zV^ZM~H넯U)holYȘ`1LF0&xrׁHiц(wK܁h|{m^FڧR)WPXA) w 2ͦ`جزMSunß"mTfPr' =<`vvL[0x#|*:-f᱙j[Pe'/xnZEE>噜Kf<3+k9=?rzLMh'Ǩ5`{n" zq&Ie#[HK\ɱ_ jIٔX|G^&H^-ziY4#6Tj%Js2^OD"- "_eiKBS5Rq],WDF W“ԉ:=$(C1:XK#sxfn*cd ⦢I)yBz-p_X< l|$xtSGV z /؁i;1[5e%1g0hO(9tDw"B5OMt_qJ1L%-_ eM۾RFUNW,-Gz&f;)/psK'QzI mU61ѺKbG5 ԅ+yvB(}&LP_A۔y7>{k]ttclwLV^,,iiLJcsҦ^ndj >5I^!BBiԇiԿhJlR\IJcȈ,zBp%LYB^Bxy/I3 0X rX+cń*͵Cm὞I%M#-z,&Ѯ-,x-]u8]У/WߪGKV]Xgm#ν!8wu3>rt =8BF쀶֓Gd]HߚrGΜ뿯YN5[eoH}eVG5zT{NƧLJB)FZ/6zVH8 >+?{zƶn yć9= yA{,%¿J3,(s)4b™IA)S-قU ۉvQvWj^3G #px _TGMrrtXH0 &lx #OQ#vV\+?ǮcHw9yyԍ*\=BR~dA2;gM޼Lտ_ݨR_j&(+S]ePN`\e a}}H@*E&CP |bBuof+먁$[t"F68dze _9s͹џ H"I"#WYub>ۡ*hLWy(Wv2Ta*sG8C}Iycj0CIU;{ZZDKB>_#ڢz|>: {Nʏ.5sC*;-&M]E8тMRx]><違5t_DRobk8vԯUpw ĨW6@YAPg,l>ou5.Vx!>ՃP0,mǛ=;SF>¤)@&mRvt2Ң 1QKR>y> !<݀c<=[cS>@qs|&xB.]sСuswSM΃lf./zbbw)KmԢ$ZUfehHѝW!F͉4]ť\".X)4;Dv|]k0p0TBpUOVT7Oe-IZoG"o@EÖ@GW7Q4MDzܢ\L"gNP${t*ALknn(WL Mѳjq7_YN+bPDA_c l.!0oAf63Ȃ9I"ZLj\:f5 ق\[*il)vͺ%~X+^ ",5ba"er F鹃7l)x7=_6o@~!G`ƫw(j_P`ln@Ƕˑ4=5QGT`xxyYQKndhjj[y U)*TkKW쭠&0㏔wNb2ʰ!(S-&@f8J9_)tp]k/7Ee]./K?i\.1TFəy̸O8 `t@>bG}`,W? T-Aj/E:V_6ۣ,4/#l8݂D<-`5T44KDK#=5Q}] |燁?;EA،9'Ģ*MQ,ܥ>Y@EeR6|OɐxP,N5սAPkOycsBYf.0JI-,HM-FBIbRqI~j鹺x}rFy |aFkcc%()lp`b7tSOf~_l(#vol@geeeemU ϋxpxpNhhq]ˣ7 Ox)+z68һednso3@,}m%KIS`J@pf^XE 4,4auWyvAt]}:?6PN}N]pj/48ȳz/sA:V݁?yUfcgQQb25>E˰[ $iP<|ł]^6Ni{vY+~ӌ6^>.`_ip 6IxQ *|\ʣe]D #4}6v.Z!|etlw[)JP+M:~Y+U#C1(QѩYXj#]a=QXO6+ Gv} uq;C;~۸>AOd(|άitnp!3baLM'28;:s1u\]Z5?rj"3\k9HA7XԳki7&0$?YFW>! xsZ Ms$ΔIFلe,]Baԛ;/ʦLGl<[o@oQ~χ VRVvQ֢fZ՚p=Y%24JaGiQ}Y?Ȩ,ilnvs=)#We$~#8G*'Y"_syYqҒ2ĨmuI,G`=A$Z񠎃(!NU0ɬΡ 6 %YBE/7/Xv&nᒂ~NVae|ݟf<;g2IC-R.A)xmX7Y;0ND2Ώ|hc#J`͸Sz&qR,u1(呂(-rܬmSvTҢ2^=cӟ3Jybo2x`(G\=:8,yq&)H/Kk˥լ^*LӐLZc+fKp?`|6jClBq}G|b7jr:+4ϳ-z0 p"C?quWO,H=UЗ Z4fjMjX$}IsRO:@ٮ(v7W![JC46q'CNPz{^zs7s6Kc^h+](kpMA-D@D!nӐI֫TSy*4V=MmZ n+vEj9۩ZR(+rD}JcVTᝉ"I3Wrj'[I?em̸v+ yC+V,J;s׺`ؘ]H~G"q, 38@si\8 #tL8f=[t8 |PBAؤ4~bɧcC5GE֊z4FUj!oStTz8`sJ{C6 "ʗp&O~^/-?c c8d: {u~XGMNX?YaP+&K8;-zHߴzDþst+k:Yi$`I![U@(4=3A/{Ў $F#GMatFdhWm 9h7<835nɯ$_ꔇ:ԓ\ A_ɿr;‘$KL:)6[' G?152_io5$1Yyxr2Lw ʬ1?FIQlPl9Y[GH G4b1%)XXHϘ*Hg%),G%= OTCgr|DLD`=*t2j ˩B:)!=L!;J)洓hLX O՗HVg]p6~yұ;-q[)CXƊ,1Svv-ɽ#n'L ֮@hHKB6MUHPXʉU85tkT`c0AHC>L9p41 vʲ''d6|Gtά(ex G|p 3Bj&uYI<s*OZ3II:gT땀8?mb8?K,_K>^-TC|[9%p#j Xl*Re( euGF)Ӂ|;f3-v8'JEq"YngV~m9Lj62od==Z5UTb3#@r> X 3 5.U؇)r(6p OZ?Xƌ!7 p}"/pgCP @q34;&SSؠpmHU YudD0Ki#]#Dd'De}< ~Pytt3uyw(IH\B25٭E7:&" n}}4EaBPzaX"ASͬ^P`Z#X3;Z?Ͳ N4Z.;^j4blҖuJ YDd Wt ]1QNq8STcp~ؑ&u xxس.& qBuML3k“\D,W8Gpam򹬣{k(iMAQ9$Dc v$ALC9O*koCi!@2+ٲ*m7VQ:\Lh< RK@J9a+/Jy胺ȼ!U k` f1B ,ΰEj-%{>,™^+J8Ͱ)uDUQZ\3Yp[2@8K@ "Qe`tרhݏs>n!"MQm¤nvPvѻ(8Kh4/UUjryf(#TT["C5vZ֊5BFRJ#)c/+#zPdOx{:}kT佢9-D8Z',LNa'}4BX@lFn3'Dnn626TG:%o4c'f|Un8` !qFUY)̲oVRd-5.W,&(Abڬ ŸQ5ݮu٣9fQ` &?dCfi8kxUp>jZ-2᷻ CW? م^Bq_r\ٙvTjPOƁDeMF(g1V5.ёo;/Zvv8D (; 15s7NUN;[%RQn;zڼ.Ht{#ԌP'5qY+_BR ləȥ Żd&_a%;JڀL7P]`JC@f'\/| ')huܑ5O[Cy&@*bYeV!*8r<$|np? ֙8=,+Joҡ@JovfA,M<\dƯkӣQg}ӧd-OqGh<!$Օ9 ~f;=+'l늈cr.q-3=Jt΢+UxeAgXk3ܶD DnޭU]i@*GFD~7#ĸ7g.3@C8ڬEn|%2/'}z ~MO\$~K%(5~ɣhcfJ‚jZf Pie_r.,1} ؗop>QW-vT,ʰlLq1v&0hԲAOeW0!'}xZ f܀}!豂S:κ΄HRJ=7tP#0 esY kUwt RmF;W$? 0~%rQE#3bP^c 7JӠ'=^}\Imna4PJTӒHTc9{B+RO* 5tDdydy'"8/ {GdZX5 LÁ*Fⱎzwϔ@ ?^✳m;eS& 9.F-X륵,s`vÖo"a/0d{\~E4g=@I'rb jݹѫI7ul]:oM?P 5;`~0=hJ 8M;d+k;EtϺ$H~nes=- c'InYEahb^1nt`Uy @yǖņ~<~:?S*xŰ1ljǩ)Cۍɣ;rr9 ;Q<ö#Е#-t[ +_3epַdh8{Jhi"f+(a7H,V2& BT xA-Vn`HE/S#GS P4h C̋Kp${ev9j kc{`D7A&v6c 6gs!r;QNfȥ&XA8 ZX9jPxU+->Ͼ5yǗfʴe)6@ ^V[s1D@PLаY^R}i`o P4vHl {t"TIs3 4D۱ˡ=S\;'eUخHRS\}ycUfqZ ]po\t:u~K$BYz"URg|-OgZ,FJ sTJJkhں0 +Nh;^mbE@P!ڱw9&lv© kҜGQEc`1EJx0G[V̠Sx=:LEAc\Y:yT{oH32ո`zcLץe0Q$K.QNlWTu%Nv//(JgcRB>9P@J'O&|sD=<{&ŹsfZ#溟U6nQ_@{ũX/T^lEKvU+ijXE>D> !}N[om9БMka' {riŅ{%l#P"ʮ\Pjk/NW92 WF@̹_ Xp _zOmȾ{kIM!kd!V?Y݇%iBSS0)ME_vyn(.Ci^m`\ױD* eMO25glJ8-[I . ^rЙ/TD@̼GYnq;#WtB;}M2XVpo`z̿@Ύ<~_ 4jNLmhuSi n|O<qrI]yi*S/hN#0{ɘXFvy53dQR>5R>[TW{V ~w} x>h'8vVhՔb Xk|p P]D^iV.A[ӆgS+/"ǚ.*xl :LCO!T#)&̇& ;(GPtvs|{h;'*F%N읍02=l|'芗-贑kПMPߋda8XZFu2.R}T 7;hF n09D6 RТ+YjT}w*:ط{hЬʹ#x\q)=} sjdLuf!*x o)w/fیGcq6Vix>c!H. 4WTiZ8؝Tu w+_EXPSTs3ƻJ̣o ]Z{QIipsQR0A=OA\onZ;%k&pCN@H6 h#a]2l,9wG](d|uGj-'K_̊wfF$zeci|ds` tl\SF;cd N>Og82 )JRDO^)Cq41@ŜI>[LttcO #a0l }1\N׆wEd4q.u—aΠ'W" ]sT0'׶,FV8W Y@sЅ$6!(Mm6'X2`jl0/JԕV*g!&Zqm$1WPMy2_D-saZH6!ڗTY"zA1~nu&BK}hK:pBCUFEɫ;mpWZw O)ؚ9 Z9xjW?,i{(W.ݺ@iPQ1XQ#$u>#/:vhXl:p<;Wp  퐣LV⋺0"Wͩò?DUCYȣ6: sv"l#u)v eB-T!2>/mKg,)+4u$铣3l~AΫ2vӗ8Iw+-cHoZ) AU+eUtbj=ڙ^z69#PH I x: +VKQMkl^e+,|i:-pyG\POCQ¸)U2Rc't7a[<5H"RicPZ m:9ӿjgr*+@:envo,f~ݘAm/{ ܰU=pW=%jԧ{g}hX.h] ?f6̆]٘*,R}SWJF:Reep;6Pk[x~,ĸ}~$t#PZVLTJL-&Cta2w}>.Rݘֳ.]} ٪$]ʄ{MurLco$kkw`J} mh'"]CB^1V„~Cn|uB،0nH  olEMꒂ%¿$]Rfh'/Y UR9?^zAULy h޿Wh)EE4o^h ^>z 9A<0MƺSLC4)ia/eцJ9 ԃ׫6LX8KŎ%9"#YW)Ϙ#0m9j$%Tytd``mShzHu|V,t#VT^@q$-زOK"lݞ?=Q'{O 9 ) l !$"4@Z@ X"j6a"?aՃ  >ܑ옡H?APM򐁞# sBk9@5FCv/-*]ЍނP9K=Mo*7ed).xXiPTW.,:DiLDQ߾Z\EhtQA+n(':I1KGLfJjRfjd&f*S5$fʚ$USs_wFz{9=ju\tɁ[qJW.ZcRkLeQYQcw=mz㨫exs$]Mc[-ruS74^Q2$ӧ\$f^1k&qK [:"V/h"9c#<m#?NXĈ{]`nw5 XHav'{XckO,[6x=.l7Űws;=^jw؍`^q%#ZXq,\SboF605^:u[a.2(w ؝HJ \X˺]f /-Xr0VdxͫkL,Ъ oG$Gh0Fkc ;iw3<^z F4W V>P^Uː镪="C^G FEMߧЊ:{c>n]( |n1;[ښ8˚ 2! 4mٯk]8pd{>d3^efCvו1…h ZifS__ oa&#68q,1VC@Mf::Ǔv$]ՒTi0,\8((zHO--eh- nܢT'v_QF E[t;]m.,(Bo4 ;}48e+*h$F,@+ƈ9JP\ɨx RU)|èov D^SgOѸOf @ 4֥D%^3<#5:]MOAeLv+u* Q0w]x]ޙ@cRZawn`w̠4AU\C;GHtpJp\5{ -p`on|wZxߗpXvybg|U2F`#_em} i5_6!вh,LŶ4e&AՆF&&ōYMXȌ xXxjS'W$(hA{ۧ҈u'T 6㮠V6o!g`pplK%H fbHmLV>F*P |v*ȪAeARni JKw[DFLOǰؙ8k:E˲yw #\5|2evVxڟvVшy{I|؈CY9& kB8Ƈs 8psLw46f &Q1q6iZ<!&̓1$S$N们;s@yv^D08nۅX, .=AG'\]KtyL] 5t,ƒ%A%⽫K5N1P!i_$8xh$EZC 9<Ȇ zF8={4a=dHFaÒMC=<ɺ;rD{őMCPE P_ɚÃI0||Jkp}=?Q3NTW- qU' }pҡN8ج4]͠1>;O= V N 30s(䣨g pqPzrQ{C(%0(t @N74yJ9os̤.LZ -x6B׾9*%B\5y?|~+M jdх< .nEC?X9pKQ/-&'tDˉr)*yrJ!yp3{_ J,~]i½/^)!|WrqFJL_-)ײӫX1OTwƆ"JuP3ľ~6z_?vʌ·Yx5VyPUGTxb$Ⱦ<ɾ@A-q((B%̴$M\ƙN'M8miglh{}Ͽ}~w>/ܸV UU{*嶭@cnsTT5,W,Xqk9kZoeLS@0|!aL:3^`o$ƭTz硕/3YŇ3T_SؿZN~YLp7'5S[UiQ~[jo{kJ#jn'L1 x9`GH֛}_UCL> ~S6u.<'uIpWI`c<%L7] _40,a,=)*hh:T0\) ,R^ (pIUnAeE!LEE) +r=c?*[(X}` U.B7=UdYիhxP"2t t㏄{J  eӢ=P[ ոY&PBBV'Â\&f̡n@"5AmqX྆HԲ"B4*&ɤd#w/&Η#@} hFsvz. $Ex#y<>.cظ1g#gt<^X0^d=FkJWHOm4 Qd(>'.' S&մlKN bHu{*$^IaX z/WZd1&1<&>p2׷N%_2 LPqoOfO \U)X4]sAR(AgG2:88H[ 2l>AsC*}f0F40sHI(F=s}/ B\7Eǹ2<?IߍOœq Z8]YD֝vږcڙx[;$7y1/"b|W :v#׬x|})OEyY^Jᕛzon%tSx[lU{IhR iswg #`83yxmBA=R#- m~#IU*HHIPUU=3mV4{Sro">u-\$ʆL9&1I! c2'rIx L KȢ>%&nis;TEL$|-\[m[xb f07Fћdh4~<1t^xEV ')\ȗ^[OY{8[4)zkxM$ Q$BPyx`%UED ފHe^`{Rp7HRJ2? _GD1-qʧ0>2kF[#X"*'UD+Q3"1 aRkx\ ڱ,fW[_6%VP?}GH@]-wO #ůRv _6#khgVWa‰NO5Z:?d7/65Ғe8:7¥p-`2P>]gӢ$8+""eb5 mG87<'[NqQNތc>9(Oo/ǰxLT'[+7g0;~x6'gwbyNn+ļ;ҭAn}s/x A4aQDZـf;ӼfkWyZ왷 ;z"X^֔yNFf+PiW Aƹ6{Tk"{K4d6:\cK-ۋ'uX)sfB#maS3$u,qB(gێqlr)Μc`+2" 1=: FtU0 W} δh f9$T>0&g%>?';rliiSRS˒RT)>aY1eF5a!,_Yb۾B$$d!f'!, HٔE $eXhRΠwϻ{]9IWǎnX^S[۰N]7amP*yL,B:IKo;`8zs"e%ٔ)-^֨A 9-yd> ttIJmޚ * ^"F'/t[[ԑx.Sm`UrJ?@諠` ⾎cnZ;% +K1jQ$?-CiIgC((8_١Y+4ZcTݠ)BgFXҔ apfeqټ)*lydXnKh (YxHd'XyYDO"RT_jGaRIdLudZ/tGϢ*b8j^bd Sv|%:DE 8w{d6tFɒlxb8-L&!txZ ,MBQg"Zi IBPTwf<,%Ÿy.S}TʏɑC09.BlXvdC}3\243A(7Ɓ:*fl4 AYY%ݬI$"f"4>.D(40zNd ѱih5jeY W46_ դ :"%Sչ>*/`gvs0 IDճb uwNGtd'cq)YnpBJ;/`&b 3ZgW\mA},Vzv`PeyhHLiX9kGBi*mn&VdQoR-X״pONu ɐQ٦K$ߑ=+4H_$lo{ $*7ArodCmiRF&hںKh!f72Mϵ5c4{5\:͍+q^Q6n¿̱4FEWkZ@BU,&<Fr>r^NIG6Hg; =;nhMrjds!Q#(+v5Gф3%.G(R ')ו̦vE8$vA ;Rﰙ?ڑɌ>wgs\PM9 b9Wuny'T 7`(fW~ wЉ r.oFhL*鹗!s|hX]>4nɽ'ĥ_;ԅ3#oi% Mo 'm6׍}2&*l mqH=9{ ;惽D3#[\Łl4'vp<՟ pD+}qP9s|i&31^Ǭ˰-D}wG]pR)B|{<4^Sv0`@tr07P.¨P9WsVKLI=s"Vs$rX}kG5G G6AdoMF ځhTzkPRgLZz&dر Ns2jK,8g`dHԼ| k!tmӑ\!fƨКpC&(~ٗ9~n3W!w*2m>K /&]#xsQ _q|q.?P JLB{0z7("w/1ErwP(Ѡ4uťq7b 2FEҳ#[aU= $#wzb7_%뒎I'E^L:F @U/Hu DR^HuKܔ8QtR!etIǩ'.dx5-MTr>=AdLrHUz('Ufnm@S5Rx.s5>LMRѤ͊MCgE.lNUϲ#h5pmNhZIUsjhe8չhɭIky y ?淂l`sAp /݊[|h&YHRT f*F.@cFH\.AWTx0!%eIYD1訥 3E\$U5.VUph>Q5S]v"l9N֤`Z;si#.vdH*޴ 1 t>P1p-ǬyaK}!Aف:.?B229RMPu[[́&n(V*cLQz^PÆ5MqsJU$ :@M%Me|~ΙEȃݢj*@ <.k=er49`rvR>(/z\po$K푂ԭ#)G*Olzp4kjfQGˁ1ɅwUݻL7>˕(2^Ord9.YOX1,I`o" z#Uٛx}A1/O񾝠3r]U HP/`N "TM/u{)*A$.uy)͗Js#CvHG\J\dz)ouUgW*5/?HI*^\LyZ$%:3lqΨI2I u!WQd9dyә°?Z# _C;N HH# 1\ǘ^Qs\]#A?Ԩ\X;'^CDBMDp6OFq2' x3VO'c6Lkxp}m/̓kQ\aS@{*GT< z~z83'a׷c]¦(en5:pءNFupdt6+ qx\ytǑ$N$}ҠI}#qHqĶXIXLdG `;q$u}ddMMݗ[o&fFf0ϚW'o'?U`cҖZ:;ڎ\;:ZXo;-oiklhln.m-m;ێyIvmێ4emnoP =jo2~srROyH0u~rαL*H [QbQwb'0 vIZ:{X%? z`uZ򈄿ˣ0htXj±0'z]QD$_z&P)Ot/`L=tmI H>PX\k ZE`$)2/,zc7DR;Cp<*(!V;k|zXf2 kiV?R643 $b 19v$! N~ |嫸r~Ⱦe[60F/xKF } U?.K~kX1@5Aj,Kf"q-HWQAq~h3ZM |5]!MlX4hAN^\\)N+M7 ESw&쎮xdo pc %L e=Eɒud|6]O˺MD\Mp7ilrd$]p_Pt_A1ݘ[~#L(M!9)) 80u9׀*hlðϻL~j FM_a#"s#'|.8j.O|Oi]Ћ^hŖ,/-^p\2TZ%ڝԣr8k }u}N"'Ɋ(iU&=}{Q<$Ly~Zq47C8ai5d1@_4_@ZfZlЉ^:OvV23=Jf mMhXE[,m5Ls4Ko0w-9_H!x mv=<$7N]?^r$-)7XC;܉*'tMm MN%-zdAl=UfTO9puTcR f̷y|lSf^A0cT3L}}8̳Ǚ15L-bYvs~Zhs9 tHh4v<&a^,y=`/`Y KdGd%ryI:iiƜ-ŖYb "{(ĽzC"!kc eiJ_w-*,ϫk;t cGgT*798 Q$İjX^&xJoL-np9-(w[\ie\#I<[X(v!x}!fЗ!>oZI#Y5mAH@t,V'vь=+d+#KMKli}3Ycc9:$߱ꦠƂ@jΙZAŪiw `J|;cY+&8A7@,{ٳF+@Tɾܷ$0BDܗz&tݪSRO˭"3%7㑱 K2盱H܃l/Ֆd-/d4TpGFKJs). rt.HHhZk7 4(>I*3t$Ԯ/"Rnd ʲf>7f\W.R2(X> 4=uZž ? tot4J~qƊv)yBAl|1mI,q꺮(>0Jd6wZڎO32w)z'8+#(dފUyJm}^'M`/R.-u5!&tsrF0vo,Th?8y TtZ +<6jq'+7êZɘa9Er\RD:3`_hh)5\o}.ݰnG5Ƭh Nؑ8L3p,JүvEFFAt-&k"oA:e$u3$X"7aņHT;Y@&`|~RT*NvoAaRDL-{ +h3 צ2IPFD +ƑI ߤ\AX)tp&Úʍ @ 8JsӢ%{)u'o>xs w!nMxۻ=S=[LJ#lrdOFgh h[ق= ]M ;&L \@QX}b^}hйӺ"ƣߜ𦼜.)U"Qi06' !Z[ mdI!y@m>%֏KC\@ڪD4<\۽Ī*#X7%-'MK |P'{zǏB_}.h`&{Avb[4xoS"9 /!aі%V)m1qQQ+'! 8|D+8oc'7a?=q7W9,Nۮ[Gq3AT(_Zy:op-穘3\g_DR*>⒓ΈC:e;֯c:oј $.RhTﯷBYqԦ%5m_S/j*I5YKDJwxdDEi.۰,E~IQ|T7dÆjsYF8וl΍Kx)qMoJX6A$H,: SI6e 7e??߹)#UP[7-Nj3ހ*G7//_x76gc at6;WԥR$ek ';7\[/LˮHcKw-#|5OZ=]s:jB"GL)9'(Z04x约.D(CHR? nr_7Z# bIA8 <*tw< /Ib&^90-@n+a6)rT!^^RB^Ԥ専yޘ+Ȕaˉo $L=H)=yZ:{oJ\B_zG֠SuJJ8N1S׽w%!Iv{mng*VA= ;WzLU8C?OE؃TSpng,RQ 5:i'Ĉ⛂aa|Q?|35j/zrIga}lj (*w0o:  @wj#yvbK5\& ;ϧY3ȤwtQ0q~e&fb6ZXX?A z!ƿ43%ಔN%^@_YM Mao)Eڜ~}G,p0.:YHlEv qYQ <:HO0QSAE4#a7;Uwɗ&ooPzPư#*J, N(ڰ('&T ,wڦk"p5TˁMr}}tW.Qe2(#d^j&D*ar9=N]ECrQ.H*$09-߳5-Ip;{J ?O7< tˁ[Q}t\^=jsm& ({Iz>/; W-'ZplGҞƨO*~lwNCx\s R'%bN5$f>{Oٴ#{r!v]qoA8$l]đ>If;'C=ЩNA ֌>EO&82% ֯̔A28On &1ʢ|F;@3 :*W谛V%u:6`sKsሟ"R :\N6mBDTK+!R Jۍh.n2cm!ݜlaY,󁒽TuDմ*7&[>PBYYӥ-qgAO;N"#+)D٦n$=4.em 6_! p$*W97 YK3}qz1{G*ɢ]04VDrY g_v/4y~A>zF&b9 oMi{ _{3ԑYoSڈ;~b664 IonݯCV1wApX ULa'Bډn)50ϤGq+>TX,_#66i;q]q4=bac>%rPFf|j ONǭƄr-U*@Ði!h%16#QX1x=Ajzm;~зm~9=b,gb=#%NZn@Jv9by 钝Kw0wced}~ZFpe~Xul8Ac8Pc/?zPQ7qҲ4UN,\mcc[oh0֧9ING9[mNik`yydUR8i:L9σq(@Tb 2VQu,r*Ly fBR.r>K!eN(ig\T+H#yu\V8p\a+:1'~`e~b[BVx!"JFS/ې5#'HAv*GEI9/KX Z8h* z?b[` Rm^,# (8YQ=֙&1ttG6RzM(;%4ӖӸ0@=ʞ{ٖ/yX7@T%qoFa |%e{`~72.# Tn¬kkͨu2Aӥ]. = aׯ沦I;rxȁ/!lڲu/Iohlkoi Z5ݷϏ=Rܳpd?{LC9IaOQ t?|~TL^q)uMMҝ: &z./o96< >M}jVak hGnky'N ҝ,9M*mOU`)Iל֞:Uc"S}O2n4M-V$S}%l"!y~:%U~oto {K'Yg 멾bvl}uIq|4.ȆB0(8ދD~0/Hտ@QU+1׈"w<L6p=Y4ܹ4%9O]J|\}>xih1fBNJ͕`(Չ+hӹ'nܦR]7wT%zoî=amIt9ww :5uAx/=~ctKvÅ2?j_ta߶XY7S4;\R [wqڻBpkK#}g IN4X/KxKRrh(Dn{|3RiLWs쑗,(A T iYzXUe}, +݃N6l^r0B`s,'pz(r. M3ϣ$;:L7w{D+FE"5ʡf&ɥq߯n쵲e_Vro-_ |F7)r>񵚆tq6Xǚ ?V\pm) c]X6$SX ܽrK6Jak$|sO TKQi+#R{|y\;b:| 57}e zz4]Tx[სS,uO^η)^ʱʴ7.}+t斐>=Eو; 7&-%jљw{ُ(-K?dF7i'"/oYCzAqRuqP So}ļ Kq[G@Eu55t$Ó ՞Ʒrra7A1%Dv>VA>t=i+4Ƥ#P7*]Oq O$ [<=Mj봐hCҾBܳ4,c|ͩijE.&&ԔUrlJUK\FڛQnGluh.U(ڤ9Q)R޹]0jі*pڄ:p,,-]]5h[&,B\4{.2;cedaEjiEIpqr^[f服 %nqq$%.mu dRBpRx萋5܋6# &RJ8F]>4h\\b Au?$+˗XwQ Xs {"r㡒Mܚ B(%\KkXZfI}'qUI _M [ i0K/|!UAS %WeMTP ɴ;P4w;=s;QZ:;tG pb Vx6Gף2 Y f0xܯuH+ЕE.g]Wv-unB$46v2n_̡n@$<6_]|ىX$VxaA=w^.UxC uك%T&$vVE#A^ 9@cb,3ĭ''c# 4_ZVD@T3u+#1RH:wUe-JZ Q]Qڀ2$2[JCFͥysi%1wgtq \tPFofH_.}'pQl2NAsIN$a{Ō$bVxO*PL*#L5#"n!BWY[ߡ0$ gq`2` =@,=J(Qâq@V؎UH2pP5?XKM5ΕCzh?dʙk̎b4P&'ii)FQ// A ZtA8C:w';bB+rfIOP$%ZKJ) ҾёanQ hv]û"d(޿޳"i0}.YK{AF F?;!W1˦D C7^ixxn77DfiZ&H` :0ze˗Er|lB4 m%g۷o;1oD}e3x6Xф]5C3<D4ޓ:.dDD[r~p{V`ߋ-A*/Y *(r^.mB Ҿ_!H3iό<胑)1% mƔ5m'GIM];f'=ct-j;m'^OZߍ{c-i_c(7>FT!Sn_@ 2vaQ1M4ݤ}on\:{]ltxhqԧ5![ [ J´c!UqFGќhߎ1Pơv|Mhmc9ٛ;A}D^wӪ춭%^jg5c]2 ݮtN妷ďwDѥÂX6-Ҩ7Y137{1߿ڏ!еA=/ -(~gt-Dةb*R3:/GM?x°~j{&ᩩo1-Іt'x_Qq1a5ym /a&8T6Aĵ!آS| *3)9) L]kZ8s&G) \xG?<͵Dt9-qENW\(̩ӽ*'NL\ yjL2n7GGM܌n&`(h0Bi \r  ?r!u 軩$zS=v / +eQܠByeuWRDފ\;m,lKR%l]q-4^#B{Z묆}X/gC=]yI[;9-% LƂCjO;Kp8 tf&?R]QUHR5-fKUօCǐ A?ښ餿a)Cek0}'m.JDVz,% {Pt [HI=1l=KGjt]=pGcG+( <'j4+.0uA qι FcҮrUs{B gV[G)=?KÈTe\%!}[ s,fJ6Ÿ4b1p\ek'*y 6>AQq;A>Q>1}<@ A|!ȵuY+}w :hҁz髝Qzݜ+ }&P@6~~WgTs}`zn!P'@{[Oi'pgE8̸k>-4ahBr>& Dj3wοw>?u{izY|oIÔx6ig]M$a] ]zWv蝿iG߁mP9y{tqC0J@:@ ЏFֻ+JֻDo]>B?dТ !HV"D>[G;CD }NR~p@, ^BGt6H*}>YWk@rpEԊ䇚dP| ŵԣՈ$l}/`_p{&o`Jb쏆m[5/g%ܗ׫G)I<*,4LԣՅ jКǼ6.|]cb[qy=z`m/]h  O 7qr#29 6PQk AFWA>n8O 05!&Q6hJ.tLM1=8_u6[hx,cLGm8In登[:9f'_6®DvԼ. k jݡ0{dJ}rw%'>SJ-Cѐ4sux KCf, oh!GcȒ!xCFG]ֽV^EcX6CXQB` yq"@IdL2 NqڑX&+y+CywɃ m!ńь¼ %oBLur@U|J믑h Vm3B ޶!WzSX6(I% n* C> _6(ph:{'gPg5>|9اox %r{HE x u|`^APt<4H@ (Eu?._jrz"0^&>|߁vp ]n`7Ws9 ҃ - ZgB| SW=&%醛ȦHfO^7BdORL1Fcqd{=O]`=WAPqL^VRM +bTW| "4Id0 VZB_VYJm7DKa#벊7("Y$fώdP3>$A7ti=L?Ɩ]=+aT1"q=V'+0N_ ˷DcJjLŪ+d5$꒎;wEzVRmPUIuiDR>I[2:SEqyMz*c Q1, ȨzؕDeQ/#CT1bس e⩌h d&O@;kh*ǁF+DS70)V*˜i}J4կ$ZRjFѴ$\V@t-cV\9+ ,oħ 8Y" "l,l)Go5{Ն"v[rNRg;}dKWq'(Q'w֣(!5yP}1D1t9)dLezEM=pWUx@. -?x 4eaB(5"sLeIFy1_YWsG2$4PơCM"AQ%`y/xeP 邆),{AǍG*^P9-HXt|\P~50(u&#'OPY tOB&JEN !/:c֙@0FfclQ5ժHLJkE]4Es `Df}'q~4{GɤV;ݴW|1rS/NST]9)I0lg✶(Pom<Ø658d AqMg֫[h&YH*ftdz&xG:.\:Á: \ڵ mx)LSՐQW>/ Q4,]=kܝ_6O[8ݱN'=|4:zzg%n]O%ٍO}\vnqPJ]YhczkPR@P?jQU9vfK\Kz6;|caQiW>ޞwQ?@רtRй71暺:\ӆ|1|~>$  MF<8›tArW8f.ᕱh>`d1a$v+ xHI(7Bj`:VIiPi`7Mh⻙nZ>Zx1u!nē8QX'?ΎrlB[V,B/vpݠ^T]넂;9>8wiG5qY˕ ڿկu3-@-߅d<.Z@t2^|Oik҄`1Fq$:]!n [bb'-Ib/|b L}!fc4A_‹R ,ٔJqv&L҇$)^"i3"7봃A&*A9QJN+/p-G2EͯZWT5~Z=XTbAW6+WQҊ7OS5ĭ^tN:F[^&I9ݎ ҇{kį 8Lr@^b[īI}: &mQzi`6_]TqSSw?1jJXx;ipW5I$ےlzF%\C>u!Kdq=3-MO{Fcb;\NHI 9`!cj%hP[K-,,=Z * !{{5lmz{~yU`EPĔ6%HFORRZq0 -)lے [SUJm|Ob8cҬl !1%1nO>Ӄ# vh'Mޚw+n&:IIL &Iݦ=>=1=%EUm=C<ؽCR%s= F%Ex=K?q11#J_0RGG!hQE&LY҆ 㓓{&.G`V $;1Ԁ GW$%x/  UQPҬ(p'*$]G4UMJ1E3%HiLZf%afv'ӆTC<.(6pRsT%D ᑕ#(%hRyÊ.i]S-ΩZBDsv$i9.du]FJ_w1 _PAw&P1i]Ch$D5]G-5"eq+CX2b,~#4ՃH/1t/ ]tC$ QMjJlauVFM8T{JCOs#NTh\KȪI- | d5m1Uڒ2Tîe[p'%=wř|^\6>^+FΡry_W,^q]BRBS51nC5¿^/|wyg7֢ŭ} %upH+p C?l.- b%*Rf. 9 ʵL>=OqFk%Z& SrZS3ܳbȡm;-+=p%$!rsjLϝjYX9w]˺el[UZ' ZT {X%Ul"7vKJ`o#i ɻ9"tؖYrJ*f݈AU׊QMATbLR-Q'{55Lh$fMSp@zMJ dD8 jt9 %.%Tֵ%nӊ)'M. ä2&WgUCrO]Z26} 2PQXDTwaw;HQT2Kn!\i*[7[K|_hk_.॒/Z˩L^-Eh7펅B)kёXH$Y wm1㳨ڀ}?%P> B?e4,Աtwom<2cm @+Vਅ揬lḻ썯5K]Lnaci}d0l{eԢh-6 F`*nk] .r |mc39AyE|~[C餘箛N.(P߾{)sCXZZnkFe puF_o+Byo-tt`\Ui: ̽B f8pbʧ yh l+!U1xBGhZ6& Tow^ZO*cS*`R eu^ܤN1;WDTl;ЅN[c>w-ºISe;̤e<Fo|:IB"ThwK|Nv2hbL*tJVSV>Tyi$%;;/ĸG9>6(/XI !ϊƤ`1 :Daw*K8Ίć8ckYvB#Kڌ+}F6+NvQ6=|\5pY3FJ`iz[K۷blzAbjWi.zRtHX^#Sl֏A+h2Η#Tq&= n·5!/x|룃2Z>j:3g\!?=--0ec}Z[=2ϱH qkh""g$ȊOqQY4E]' Z{5&=NGe 8뛽 fL$yƛ5 fzJ&lcH-|hL{bTXaU鼘 ׬>  n웠2C`3pt*b|KpAk ʝg -5N'( 5ͼGp!\"λ3D n t-8Nzx)[0[{?U? @{ߖa {P4r6ԮGP0 zaM"*~"wؽbNo6F wac1Rm.zr෇jгX_ٰi[3Ύ~ӶRdCζplssvN:$G2!o\GkH ┬Ȣy޼?(&m&zل Gv3m%I%q%(sa^m0$.hdXmx5Ҹօm-P'[ "V'`Ͷ?PlHI 6[Ri5B^mYJfm1X_PGmjt`wqx382Լj4N';}C R"`I)f)6?]02,NỲJfԅ6cs#|Y8Ǣ ):&a~7|Ѕ a5(ϲ Pq ^imU]ߣqE{ H X9jS Y43Nv?Zfхrjq0ϟ5UZwk|íb@ ‡-FesORsr1VowO ',|%+វbf.Q"xڝaOl>bn {FF}{q0Tl.z 3r1md0+׷79#={# E"l5igYEvP0UN6ҙģG㕷a2g33{ƺaj&[Ou{tVp,0CT1TaV̾mTļ+^ɔo=,6dŘf7sfdWP=DnoNx|<ƅ _V$X6qlG&Tf:tKƜޝfӶ˪ Z"q{rlٸ{0ӥj6{t$S=C 5NL U>@;ԞtNEVgguueor+_=B?K: y KlƸ&O, EuwR3*Z>J`x`]4}ZTYKVgkpÊ R]3:򣙳=O*;ibĸ%m]!_-MTgE=n{s 8Дu; [LXSt|N'wqqs8^ vɼaגvpæGΖ]L3{E8z~H3= e&8<޼s/m2 k\v!s}ƽ!KӼou\ivzֹ!`\UMq_$w*F&p o('cJo*)}xk+>Og~ES'kB3JD|Ze'齐0ZA=^9r'4 oG;S )aVmU^=ς )gAh)๐/KsT\ϹJ=| ~&bT0]L[oon pl§bFt,KaՇ/,np撑^ ٥7'ûBA [qif0$D۝ҫWZ~ k!J ƐN8nB3UKM(!9aEKŮ'b@ v@$#DJKּ! >RiESݘVW_>UVaH_,>xmYMKğ0~ ۱5E}nsFo4yz#c}R&No|rpa3I5Kdf{ZI]]uZZp43tJQ&d^o)T p:c=*ΨhtFDvV]oݯ$_S}y ,dž7_?p? $:}pgc;9!fq;4#T zED3,; 1dv7$fg[9h9%ygwfaft`yhWճe;싴\kJ?_Z &󒍠Bx#3ך<ϯ+t|L.؟AmRGܤIV_X7!{"|>W dDƲ+.}L*\MuF.eMMa绳 k:7>S+}rLw0Uy 欇3ZaՋ+6O^-۲I/A틮֥5Ag%Fl׏Q=_X5ls, sP[hctnb!K]p饍<;hV~)kMw!4_*S)EYxMR[hTW圛 DЪGj ts_c5ѴZ ѶĪBҌz3c#1dh# 1$֘L T? !H?(}`+^ud5"uCz",߳6.6f/xJٰf {+o LۑFf wLD38;\ E5-duLC4+w(KDZޥސ:!DBnksm!1U0IlD ֚Z2inX*UX.v#\_98{SJ r.|3]x& ɽtq2dOS{-W]/f+| qkh=i }z*g*L*%pͦX!k+tа{z3m-MI[d~8Ed?8ABk.ܫN\ {νOb+\lپx3[drCCẌRD;yFr,͂&G뱣?\xj?d;;Dx=S]lSeŤ5,HE#i 3o9j~,&uPCn܅ XZlNk׆16vJxsy'uQH].3&F"QH2y)21嚉 e͏725m8ǚ60J0mK&;/2LJc~nZhQP4(o+"L4Cs6vK`2؄(S$ZލInAV N3!T;9ކ=vF.ǣH۰#1A2C:QJ&HȀ?Y/Xa,6X\Tk$"RsMS2:R Z*x3iua6}i Ҷt3iZ̈́SLlY 6S\k+5'WՐ>3\ҝ'^d_0\Σ>4 ݱ}5!e=g*.dpF_=>x#bg0jH_qsTM6=5f>:MaN*DTݐM ]PCr9*Y~"h߹.9aXp3r3}$gj! 5&2:ۅf8?02E 0wQ8^w-t$ e s-\uѹ$lie^ |=|ۖD[0LϾg) $v_q*6^eO ۗ6"ۗ~"S#Y^\gе_~jVz'\9L4GLOIra*>(^]j߭zX';Ir{e/|k^{kk,E'Tsxu{MCqo)V^AWx;[pՕ%ɖ-!˖eu5eyI˲e,[[@pLjͣ3~ۀsp1$ؑM ~lVR, lR=#rs{^y܇@rz~x`r6JD 65x(2>wM ^m%NP'!&HIq~ZB3̩? e E {Gh5hT9"'DEpRXXEDNϮ`e]8r>KNe2XͣOl)i$QDCO4E{ޥal54,Ulk65Napط{>bZ>(=li=l>>l%"( rrScB ͊XH[HH+CḀgd3(;̷RS& U"bT 3Ix :WShpN0< ZlՂ}_Eo5[03p.n@}Pʒ]ȾUi.nei J@cTeEB 84ա&I1 ` L[n /9`}@-}WxE& L (eR5$43B`v,eSUC*N$ow lkC5l,P 3jhgﶅ`d.#Bg[glV *^468p]v̝ <Id_<2}qEŨaڼQ3!r%-=w(Ehu6{peGN-WH>5+Qގs'd-6pHe3|c:K%+E/ohՊ6^YXߍV/*>V(~ͫ+D>X95ߏG}1@GFt5@E>Ej#G?ȕՅmx8d~ƍ&ҭK3y!*0Ub +fF;u]-wcd"~8 I*QwȮ:& t2Ľ`45}jOǠuUeA5X:n̨LyDI$ppAv,cmS7 bipb&*%%v^;7!ȝM60O Z8FpuWfR EXMAI ˫ 7g.JݘZQş>֟)Q\_lڇ;F`^!ܙ*&ڦB"i^y4=Y9- 2 8!,!F_@p[سf:`eVEVVmF',oU1zT0v;f[.OPj(\ޱ|FS 1; sυ d*]H=u E42'5N /F4Zju9")Aq]TzJ%1ӠC 떂݄uHW֚3뗁 "]3㹂(}4~T4y_>d?!c|(5S iaEo8ֲy ͘~4v@BTfac78[=h̥!4.KJDpú('LQ:EܕU29`Wڲ(A6UNfC(v(65nA̟l[dخeN+-B ^#7ּp}Uџ~ oho͝[heC~.÷oG[ʀXՉo]4]yĒ,<::tb$dbAE%@l6O:akvТ hݛ8vfwi%~3;ߢ{Zh{ƪJ~:( 8'Tnl_%H=2Iَl;#>;޴{Ia YVR'r"AEw4*p}9A,Ȋ4/$%Q˳:i;zAN2 K ̃U4ΡkB%fҚ6Xf$m''NnR) &K5SYΐ>~E\T.m\v10s]:@%K\?V"2+ Kᦷ>lӧlIqHVR1phoMgI=V2+%40g:}@8.A1dN.ŋƹ$:I7;e-1ɬ]}r4&=/]R0>ifKdP!deW7s{zt 㲗e…՝8{ir%gV lǟ,[7#ϔ;tQzi'3t𔀉lj'?ZF:3ZX8|{fpƾWY ic-1 f ]ͫ RY B?v7_}s%oM#=FzǷJ. I#1)!aϿr_OΎmK^[$`^;nj2K} “%"11 u̙bVMmfv v/gڳ6˔bJ֐XQwoζIQUӝFrjGc)qd(?Ncu.hf@xj96t[_Oq@Ncp/VIDERw8^}@w=֖1Ѫo~aA.]/[/&z2hT?8 >M25 5|8-%9'\0׭D].dH_[foaݪ|f/rksMI.4Y`]pUZGsr;Z[##-12J b<vAn+]wl]wMW=7}^]coL9aU6ᢽ{&^!W6Cܘc)_Y79c4nH~uZn$HW^-M&yAr.ګe+<3l<#j{Q9g"d3]c-uB\kGjB[ U,"Wt)kDL8e&gl9Ih#+'];Ի{}l5S'%2|p"kQD͝nc"ܖr#!JQnTp-o5{ fEgY٬,Nq$Lůةܡ (훇BWh[%_A;Avh) S`[AC 3R?!M>`CUj2IWm?vl_dwnХ0;iϏkX:`w7VNs{eW+zY!>Ɩ\#dOMtLMB=ot_IkZDTXeK@{7g|Զ{9Nz&+7ev>Vu۬NoY֤}6BYS)>Qh!*8f}fObbuMݼal3ź`v4@"awЏnޔ?@eΖRT]7z<ө̻ػg8'AGt컖0+9^} ?]3JO4 F Dʁ [Mi] d9yB{XCБ͑;t{5 ۋء&pka0XG-i^J {g-g:# W5vw a3p ^UՔ .sZmi,y?k x;ixǕ$}fЉ$fFF a]h$liʹ{=mაcRI |NNl%#_KEn66^UuO! U{ջ=O{G%EvS֌EEU]fh.m8˒" (pE,tI=,G͊<'ZMQ.VRb9]tz$]p{ك8 Ç5!$ X@9,5]A'Z]R,PEAcyMWa/r:N2ehOq , @MhIQj eMS{F#) "ĥ'<'+8_Of G,aYHJzLbBLS5aNтA1.S.ا]G\%,ܾvTb4/ O I8F) iQ LZҿd}ᔬ-Kj 48d| #MR䈬qBHRL4YpqOðC PUECWҹ~'6C&iM@XȂ 5+Kɏl~W-uI (,AqI3'z/ Z%,c.o*2{sݛ9֐[vJl(L.rdJUZ!WLeq%Hl> "X;(߯:/G6YXɻGj_#]i.qξW ͒ ](:|ԛ&/.cEeU$SJ(2Sue2/Ⲫ-bDVcq]D%I-8K ^ck6b,&>/5O}e(:% 7A؞3",ԥ XCt~کiY$=)Cc 5mh=%F#[:2RVEIARI0Ǫb,v@CY5՛!12'|zwcePrI0hYS`g3^̈́OJ>] Z0P_V}H˨hv9 (>OD6 TlႶX]=Z9FGw46dixft`]1B"7G!V7!6PUe„b)ՇO'cM<yia׈%K|\![% ,;.*YtqbQMSr]~┉KE*[WCםnyKX? x9{lN_)\`;0O"ipxra^]5EeQXPC*\uf6RHD}?~\B!^V'V)Xײ6~}d^fd*(WZZפ[G'-TVA7ғպOOFLnR9bV0DP!ۆ:Ѱ[RzL@v=eUІCжw8;d԰lc]m昙oiH3eh2䐺6һ~)Ս8j碸Y$f.O4!u*=n$ZËX37-=u9ya@枞fG[!ɇ0:p*GNq?DΪ].ːF97M\Y]뫲`,k`\d{cdj꘻ilßԔ hT`h)^r%},Nѱ{|0C2uW-kpm.K5~Zoqu>[5\|*^|%ԒO3\ŅZuXJ!Uj`t ?_p^2j \l$x۫ Fhctů3 Nc0CjJȒI-^ʠ"5ҔE0ϛD eBm?|$Z_N dϾ$0Q&2XOrmܞ LE==d+!=XMh^>"<[ȩ;FE>^\=8@MǣhWSEjKIs"pn!,t_us'VnMG+mW)FU+c|Rⶐꩁd@Uѕ¸g38}SpatNH-7]eR,(2|rp-9q&aJbфcnjdOSX (HT`VFEiF1k0 Os-LsL, ,.ʜTvc#0k:u _0(8;[ GcZ0+KR@qܯ1@c8Ԋ9qa6YKGg‚1LCQr8ٺ'=8[_MRUQf6,*ofkW"?Dp ]E,OuEL\98ի'A&kNL״-HW=&1S,Sh+_Den Ոee8& L w|*86"uf\}7&M?.Y54N WH W>=u s%釣VjaE9LOǯok 9\G jJoޙ?os(|\ qH \3 }zk.!lI2h/\}(oS?եA 5A|q CeDԹ( ;Z2(vkEEۖ`2ƥ%@ =)ke\1-n5T4*D7[jր$gq Yɽ 0D႞SFc`E5^Q3KaF ] 7IKTFv!W[$pJ{b~fBPvӢiD\EMe'"] pdfm ,`zE SwTM)2w։ިx>XˢuEluOyacMŜSbH7U$z{90;F+s2 LxYVB#Z{<APc{GC.'XLsV%GN\;Hm6Xm 1#((o.ET^? ^燿v, 8ﳥ*⨣"q%2^@+wgZ}F@>+A`r@1XH,W󥻚 |.p^=-,UQ#lq~Ϲ8ERv!v d .i9_aXHV4M?? -VHX; +5AkF`O2{zvgu7jSS5հ Q_3_Rx%EӇaC훭ߨ\C<EK Z[>E\t6}O2g򺂁WxKI,q <8l[ ww78~Ӏˌ/$?BM'8n\h!yj[cVA.| q+{/R1 Z|O?g x=#ES*ކ~LJˏޖ%ރ<` i2pPNWvVeqpYY uqh??;g6#iLЂ0CȼG=4UNf>r:#izJqp;I%ܦ]6tAdȨ]-)=vt3trQ9|$ܽ/X?DIqWD(ϛR, G0L\n>0'j0!ĉE.CekU}S3R0fp_ H_&` ;݆0!H 6Jk,]WՓ+,,?PE%y|8և,wWB)~q!$Khߩ6򉷅;C3?jG9#7H9Db:40{RbrH6ɌQm|rĀLřWV,' arJ +_ݧ\NL`Rz6f[3;bHseu8/% "C3w ٌDy_g:KcsuRx Ngmk]A"daDá0?W6-Dwl1F/*}Y H &z:g5nAެL r`2P=Ay߫_HuxqAȣ߳N`fL,~M! ~l~KlVμ$ 'f N<P3e]Z,x@@s[ε) }*zoe)^y !!0;}JHKjXjiǒ FPk`#hƹ|_9tC]ipj'r"X]:E|}.^)}$k$7Tgx+fi7i2 ֌躦3_#hn>mtneLc+rerPLn=g'^.aQE#FN nyjL Ҳ2]}42~`sA?BG&z / k[^T-I x52?o[t/d{Wi[K bRT(奇J&wk.$@o^Eh|G(^{2.;HqW͒WV bs"!% on_"BI,p>YAcEZ{;*E M.wyDxaH_8??-ҵE ?"៖_С|ˮu^&{ 3~I-.eKZIVhphVRx;ipŕÒ[lVkdY<4`YdٖeĀ?|?f73##H'&! I0v K̵#I ɟ-6[%![Mjo.I6l2_r~qZ1=W"ZPg ^-b,dcQç,eA#c۴cy'[6O0 60j[r_M)x%ёֽQ- dZM֮VVJpuL4/MX.'ʤ:*mnqv٤mQ]‘p[85e@X,LF ;W )_4dYO#TT AD+xMjl?)5pE4M͜eWkS 2u6 H]nN)!9zJs VL /n)W)O]3!GS^Ο3A?>FKK6.ӟptTX7ApJpx@Lj?V:R̜G #TOJCC(ZIMg?-}Ҡ.dMȢ`#; 'TC]W\:5?+UvIrl'Õ޵;t晛j-Լa{%_j[2ިC`ࡓ:Cڳ|ET hՖ,'DNaE#/c s+|[̺{v@F;s Rq^`$} oԔi+}k* #Kj:RSA& |w3bk)A- aBeac9.Z[RV -c`nڲOmRK^oJI>+㴐W̪kfQ(XHB&XDomX3+h>s^Q¾08|Ս G f.SZ-r9F:Q\Bl_-¤'5)k6xM.'^V BB@lVI92It җƖR55HP&꧛:djkgaRtLLz e<$e"H-Ε!h)iun\!aNLWLkcm:RRsMݴcdnd@1 )MQp@kA|A/ jJ!]ր?10HWIefi"+Ou׬AV22 lΦtN6>>9ZԀk(UYb FS-C<A'=diaľn (H!ˍp辨cQa1A?/=:'5 pzG8YLA7t ;bif a.T3yݛAS~ 8oa磠j$M8%YWon=%< I)5bW#G{|`~>>4rKWC$k>V#i/ rhR,y( e"h= Yx="g9'P -@^訚nk ~4ճQdpRඌisQ*GP)a,~r'XP 4b]'b#Fqxf fh(_6Fb7 ʔ'Ln*G;}d(U=&|G ʲجqh|W$IġȢtxam^0ˇ *:kxRotq5€PvǶ> OF9AjB(-ł!_p QKHD^9X nRH^OA46 Y$qqhWs[x@I! gTNf(z[ZΆS¢2JAˣ@MEMLe7ixX8~U0*1#ebHOX0d HJsie/hh&'V1KQ#m[]9s# IUn&F\L˃w{": Ν_i(6Rg1O٫ʔbJFsW,rۤ?@ NH +4i`T50mc[1LGcED<*rGKdz*f+þaXI 0ױ%yÔ K+S!4oL Si|qt4 Uy14?}^Q;#*P؁^% x|@r0G BD/}Bs94&8;~5:!7|,3Qtta־n` 1:#J2\#t6QẂR.| v9amD]rSpPc>ȵptJ?N.$m<|=`P36_=2i!C ȵ>kXz"2B?>? csOڬ|I $TDf*L\j~pKqPqw/I8eOQl"D1ʤ0_}E$wn`mK2 ./ %949ai6wh}&Tw+@G2o?L᫗8zM»t P@4^C^9t2.E<#;!+`) +JW C#+M뎇S:qxӈ'L&,P-wV$W1hp:7eP/ EQο[!."/iņ2Qu!k2!3_ܸQQ NS(SW(\4l֡Tc]%HGe @ 3IP*/h@zmyd:mTWQ-܀!LaQX!hlg2 o_J)-,%6R[ǏH,Ol>OF.3\`ۻWy8L:[O6&X~VÚ٨waC u9.LI*#SrƟ8ֱurt \_f瘂ZNh;fũK9 2|*̘!|/ݱ˻cDx(__`w1*O9TR*TIϷ [HJ>[<Fw;vc#e2%8Y;qxtۏK_^;~`(bV/q4;_4fDp!ׅR+Ɔ7^&M%mgW;8ݷl;s+ت!W缺I{4%~9I""#Q/ lE(|Ă{Ϟ. ]h|r%6[Nٺ"o^/!wz2Ojs_OfUH [ܗ^8eO-N$;~X'nslկNXWPA/Yʏ|i[X ? $߅~4}aw'Rqymyx7ܴ& N/ljqU-39&gKrj7m(Lx9 8]|ym{ΒR~IJ Hxdx:V`7d?ͳ~;] 6CFuqWؓ70mc~j˟w6v둄9nGw l;Ý|OQh1Sy{}/1^%\NKuQ48dmzCKpߕj] Yzo/Wx|(~u|;+*/ɁXrN;K ;!L$S~iU3L'ž$^jwj8zvmf㏾[^8swf:Fv[6ܷ+`*zSVЋ~5TZX߫0s:R5b?}%=ʠx.#6ZcHk]/J ͫ.e|kVA&P NBB~ R/>:ml0u9_2~kjONc% ]x$.+JIW|Ṗ=q̨9)^" w+HܓhᓿX' ^Wmw&¡F ijnCNIi<`wXm@IeXe\EpxM]LUs UQڰl18wvf.45Y[ -"b²JRbl7,b(I45٤1JԔf ~ier{>7yء޾o&>g\Xcf2۞a([^4~z}SO0Nr@P,$Y2𨲩 e D%Ff $4tGd8(ɡ~ij(sC HչW`=~ _Zع0V.fuf/=??TdD| YE]=\[Ԓ1z ť 描rDŮǸ\i.K;…'Fh QYc\eY$ NƸn4-k;8FcA6&c~5@ԖH ~$Ώ i_9mҟ\C.xjfcbf7oPk6"&WA mFv/g_B_RH-6Q\+^)8M\1I!5ŵT )/*]{4|̰)֗QJ%s'U).в %U輪cS* 1皂SɅ R+wG)-alݙL Ys)y+*.5ԵT^?$ﲗh|]}b~}H/HU_Fe JW,DWz#~%JɜS]:G"F\y#x7߅cy/n?ƮSӹBB|L9+uŋ-z.6Q;Wq@Ux5S]hWލF8wfvg&%C kVğtW"mҞ6RfnOf߃ COsϹ߽|x/yӽ={h_s `bn1bcELu[ngaMKKqknNJ1nX jIy u~z q1D^b =<`9r1a N%L_BǘhC {cŨ݄mi%UbPw|kFxxF$!sl_M|Ga/PFOt001)fyhYx8EJS+}N8Z\paH(TEhZ`<;D1 ka*Ų\(99rȾ(Or]s7\D˒󔪠.@>vvSvRx[QSRŭԂBiﹰ R;P īR}t.u t=ǦʒBԃ%Ǫf O r:9ӊolf={}3IsjASx;pU^!$ɻyIHyὗb! ?n\|ǽEV֮QQ T-vUvNѮݶVtw{w?w||9;~;G*uI[Du dxg`79CFUQ⢮]RT06;Jpl4O3`ePd,3&<'Y`(]©ѻ LN }Qة}+{TIӕv+ QO*K}5.잝I(r $9d]-EE5L kLwE"!8iOR\FF{vL)4teim6;G$Lt $X:Yj\=ztJ,RliqBcL-jW'$5+㢠I:8`W?.2meo0bxzh)5E'X<}VëmH#"" 13iQz4Q: M%.9$Ɖl۬Iąb3t,Xe.cZ 墓TE5)>b¤B[xIJ ai)L~T[5e :J5F<ΌJoV/e&Q].O*ʪQyƱK@,kvLY#?* -k0&֔oni))hIE F< [ #ٌ)}Wt7q&y\nB+ͽS :eTDM?`c;B_v*+ 4 R2PC!fS# $(TP {v%m9VYEU% 0QA*aPaU E֝4Y+Ujgg,Jly@UM}ue[\%_\r2 c$ߙ$RU i$mi~Yh(4m7`m%$*TنŢcA ˑ: ilυIlxL#3gOj?c(ޚֆ k}RY ?ºږܺjj{$[һiԹ8bup2>ظquzMxR-gsR}eP5*R.]@6((G@^ &+[еjZC| i[ .tgH u #n6@5:ʅP202Q0l"pc)PY>l{́EL +{ !o1h48L4.QBJiɄ] -R*5X#Ϲd M!Qc%pztI7q`B(K4>iu AcCC• ='$+}MQڙDr1ibbY7Ք&ڦ}cGwChBIavm(& /@aD Yæ]$+ Q'd_87 &ߢI_1scv<: 1#YBfi6EBk>x)=ʜ<-ox3I^@ji$WKmuA3Zd,Q Ull&؉$kvȇzoTT[]c"Vw7-¹L0#a`KD彦 n񎿻ҭN9d5E,.iz\Iv4WP1'LJ;EI52T_L5pol&ud3gڌ?u \AuFǻ ]u(?wMaR!5ޱk@RT/<Ȫ'ѹgC9rRqy s5r७x{o!Q5FC2ݍBg\` ,sH0C77dz B1 }SzG=yTEM Ԏu\. rE0 Hsrرw?wMNB]1YF1*؆njrS[140 f~Ss!NܾPJ&Cg xz v8Zzoo51;s%8v#1S<7Eaa&zKkd1h~Q`.T\gF&9uDC# _Bdȣ34,L M #qDGr'.`JO pz,9߾mك;m?UH Q8</i1{"gvfZ_/8X3Pi\ Ɩqwf$O0P3k:~,[Q>XM`9X:Xx.OS>Ԣ*{Mh4)Hzo*sN>j 3!Q&7 K(~2ϧD=6IGE${g*s \BCe*}LUL9/BDXdJe=ISj, Gz'Hed*Ӊ|6hIMCԞ߹g#N~bXw̨aOuIFL闃0OsO8/V$CJG| vu2.^:u6c.Yؽk}]=&2Uv(EUv<2޺@5c%3}J󏦫N۪A3Դ/F^Fо,#ӭPĒS4ּtl\"rtν&?'Z?i3X햽!.[V1/3X>oYlq!f;L6hI ̘:"_/{;]k&Ɍ>Zg2ߘ `I96"AoW?۷nعGNdFϽ_U`D7e+KEP̨謹H`ȮPqmBsbn%^`M+GV(.mC#Pʎp3@mWl`w .W,mwm:8w5||{[Go GՀt@ ]w4N|O*rmwMRO}g[Vk`eA je" |nB]F*!)JW*+o=~؝#",ox?XuB9ō k"P]ѡ#~tGWC1T U$ r٥UL~VCN2ށ]Ʋ| kpvP:}57=p<yrڃae"QKhi?MlH?c]GrE;zQc9''#8zæ[l*T4B`#<:UW>Fi#S۷A^WZ5t)sR.)Rz^`˰pM.OhER9]?g̚1p0HufN᩻+tK A]ɏ<7e::p^CCU.\<02KhY |].ޓdzگ^;nV@b&>;GypM.ǒpszA]`Ąe8S .Hdj#UY`::Ck f?3N>7&'١PBՉޮv1ą6IkQU'F:— VmaG`!i'eI*E12s`G趶"]sG[nBbf l7V?CxiB=HC~UfL9/M6BTz t4sV@4bx0!dBP41!azIfVs n!)B tAA5nF0ڒ{#&pݿ/.kâQT2yi+fs/AƖ#4yfoiJLiN\y%_uB'_}.J!ylo(([e|s™y׏7*v3{k]!&]_hh6i#pFKm^4YNB^k-#^N''PRqLCb;BjP$۰-_m1]=7t3~ݓgp>_/ZK!f'kO7t 𜮆'NgoVS: EӻBOoU#K괤0u}Zwz̴dnH/>SZ_(‘Z3˶)֝FTp3upG*A" s$YZxrδ$SfauY"yZJ$.{*;!yJjsu+<>Wcvh~W-sxx~W#N}sgk_ݶ ³gka-h^{z |`>y>UUbaĘ; VI#_Yd_j3|CuNRoυCқM9:1bz,w!;B-,G\ݢtmP=b,tz"peG_~D/=MvFYwx]3{P;dIb0"LfoQ s^(۔'0koƝ֢yeMQ/IAo+us_ BR*+l1"F!Xya8lev8N/j=3f_$# C^Jy)\*vpL(K!i5á5x6]|=|az3ݵ.]AŢkNFb9%N^JU oum;0"41N^G~kpbPΠwx>J?JOhRV?ULLk=))"7sBlp.ōVKZOx^,y5-k5vee]곅\O!'i=X]J0GY"nv)uBpu_&ﱆ81MH A@+)/hAE}Y/}TC#}\fL!p-*wQUyͺl;^ϣ&]eÆ7H2F1OߤN-)f&)li0x쭥!o[VG/o~gjExEC.jiMάn^f퉐E7=OO7 &P5J79lZ۰[{m\kӀcq_tQ?5MXXB _gvחwνwG#1Phc-cb'kX#8% ␤_BIs$g(t=d`SBX{aSsdVV, }*]gtgDk!YURqZeIŝl.fjwHvlIbfHu4KP ;+Yx$w ]*닒;O߻L]BW SN]JrR0 G C%W(Ġ0Ì3BQt0Pt02p|Rf T5b Nʨhہ7ܲhR|S~7:&ˤc_>$ ]?B3g5Z}H2Z"^N>44~)7ѩ&QZMV\n J6^$?,># n@{wK}BۓQ8)[rCGuo:^S\5L7ȿ(1gf >""xN̞2BP<=K㧙"Ͻi ~ ͔|?|{/.Q뛅Co^l`=n7xz Sqf//2{3oa.G`.5qɏKM-A}ۨuw:VS?iXֺw'Ouٹ}+QRoW[2q;yBx-kh[e9鄬̩SӜ¹_,Uƌҁ0ҙŹ$9/0⊶it (a}>IcDK>y{lӝmZ/k ?zv"_ߟio)/}uhv=,HKJ DME ]Zc>\''86w>A+d':V+9R+y1HjܷEMCͅS@EAv qYE ]A-ߌߋ!6[EܣfQZHﰕZotx gJP=\Wj/EiA ^Ct|7K-pvx%;#YJ%5<,Zܕcc _:7ǥT溌E`hne'-Lj rQtGg0Rz8ڳQAӧFt@::2϶Q hͳZ#G^)/z~$"Ziy4cVpmѯ-l 49 @PT'}g5,58 fz"._I}w~n,}D4Oc ni7R~3#4'A՞ScT`Tmx?egC^„ſa[B9: ғL?8λٌv Icr1+Yw~\6z0V-b}O{Y !piq5be-: զ^y>xiK"MY* ۥ2ll = !eO<̜ cLl5BJkp׺-#)x+nBWtUMp~ʕ맞k +cҵu}lÆ򡵳ݍ Ybf˶`HxON e7^TD(s^Kx CړW C <,GHb#^l׎׎}P()mc7k :J9D{ z5uo,lnm #,T#S'NE& 1A<4:y|8B9rXPpͱ"\Z sɨ{}<ʒoP f4(mxgOT9^m/r-ޘ,iQwȟT64_ #%P|奸0ґvʆ^d[gTCތGz{GGUa2e6CXWR'z<"^Cc5>lBPg=J[^M;L+qBtB{za( p +9Ob2ZnLNC`ӖF l%f>ME]g%#9ljEa#Nl-n|Y5r)q:Y"P|Q$_ ҤYeHْRWcm$8QIV_X=IG\afO>`?Tl1,%Je=ݢ2x-8-x\WtBDwFBihO4ڳ/QXᨓ6:ڻR̳D Y,6>ښvy_^6=q/Du!UTNʉ6q%:gcҨ\q(~ٽJys)+4/f=ַE*K4պCŹӺZ]#roTγU=YrOl [ܿaf1QVdʪmZ{GxLW3q`+")_9KUpG&^Cyޙ`e-_ TPB`5+QT6ͽ.(z86 b]E׶8P1p{!֠>#di20 ~8Pܣ hM}ous׮m^/HaAgBA9މf}d C%LA.2b>8y=G(/4lRI42QM ".ﳄ}%cT 4\Z?1 s fڒl(& }TN^XC.qA53:~׵&7xhNH|js*ZW.PYOaf*U9{@φs/ۢ7p CAFTIxɞ{H/{jhփ系>~\ -{2 zɃZ3~a.5?K{QESC<]Ȁ(H 1! { W^&qmcA+Vz\Y=S.]6 Ym3SA)b7̅Zs_rr)׋Kq9φ2/ciC ˼m9q[rP^?u`hAk|‚~&** _Tpg:pmP渱ɇтzes;NX AzJ_}5;. NRRNe\_-B+D[\k뾟\Ǟîs|)G{GcA"T9sgW1h6nө7l<x6O FJA̝l2%DVߏ3wF&2Q$z|OK{iZƫkVq= Ҽ72U`/b:6'Nx|#10E~lv6!$Ba֦^_hsVL8c0P;-1 ]{ihyQpdR )7G#߃AyP7+Gx/WT`kʹ&?}S])I(D /`Q4wCKKgo* Tᥙ(#)ʣZv]ˠ4L&emmd.I5|ðx p؃G=kI[uUH-2qfI{m =Q'l)Ev+`Lǀg\iԍ >B.Ɂ7h쉔>AEԘeеkm[f t)c(`=Պ{x.P]~ m;4cwFt& =>"^7'GdUfF.s[Zj>+kG9}9j^(2uŕ"a]FeHiZ~Ѥܼy߆㙃'(g( 0yhP0?Z6ORKQ pm!{_OTG eKY#\9ͱ -C:ΚVlPwed [C>?h2.81en:W?X3l\-`(eBId8%nv9B{Փܕ}zсԫAG {CUGuƦSk`Gs*q&IdM 8ˡΤآoIm e@P83!Tt99&Q>JC{E^ Wb9򙭟z=49Y^`_qjqoUB .S1#֝낓=P`J\pIeǁ6尕w\Ƕ}MT9ʯsffH1'^I ,H4}>2QQGNTKgsA'uRdt0ᶔwΛ?!a/[ej)8زO9!]إ9h2^uVaylpL%0M3@hT: jlU(Gjbu9^3S%6t q!ً]:MG9Au jh)Bk7-H0nˀXB9"&ە ^H)&,| ' `mOt\.&\{~N$ }5^=|SV-y"ʲP'ts;^kk~/$m6Han /9}]aHIuՃy؈b3VFg s\UjI ޢDə-kCӝZP+5l6>n׻śAobTR r>[ZM,}p^U_KP 0nBP> %5Mft_{^ى\q\kh'iqݾ^7J^n99W(uo&1)ڭ S0Q|NbF6l ٦G/`[6{~鲰}8Q|4grl81J6\mo(ad0$>_ҵPgx9`˔@h/Lau swx 蜐m9o 6y@L=^z:eigߧD(6F];Մ zol( xCD5 <8%]7kfs/nf>Тw͟?v_s]_x7xK8(߇=e2㮀8HbeR]xtjG[&֟Y nq §lKlth¦)y\S]#*Rͥ闞xCE4&I^i1luzfhvuXN!Uk̤oRYαykǰtӵc?ykuTh׸Qi̴LN Mk &`$Vu#s;MB H.'a ;)1 zIs('P f>P!8v,`;Ҧ1V8E o8@IF<$]Z do!-~beZUP \yWC717dyW, J*_ mw[Nw|6FV/J@qȚ" u E5~DDRLajڎ&h\}W _e>x!P4;pe{.tJegq tC-N_8mV9~SeRۅF< ۸|;nr+{ZoJ0fWZ\CPePX)lm&C7 ^BE阿8 Qe 턿A5!R8x3Ya_Yvjms}eʕ=w_vL) X"A="ScAsc&HLXB?WΣ[-Ȧ|>jy?9N*K5)Ւli? rrwbwMFDcZR[u/J!z1K#(~CK]VS8AﺢjkH.)&2to嘱j?DSm O>`g7yg'2Z۞w#ו_052 Ӈ~hDw~E\O&Ha;̬w$#)>d7Lk_a՝7tׯ\ɢvknod/ 9)Fy9,|-~+a :XϺ/c<ѡdGHlڃ񠃱+| Ң?p'\#7:K7xXyPי/9\300 44@h>f-L= $bIF^Hd^e'>$G*Ǒ即jcnumk\?w}WᷫOzAIӄ^%:-.+Q_#vUux_綵VpvCħxx\O%kc]f :cEr{B!aXTad)XoL'co2j& +3B_2q&Lm|Vc>܈t #\ǎ9= uyNh|b)>#kĦո<$_trNj-|lЭȉC-uds?Dz~'UѠ:}%*L|7H{ܛLyK?t˓bX<\BbT<·%Mqu9jmLR_7eruEÒ \DSM9[Ő0-@fu3!=pZ.9kExuSYLW|r/Έ( .zb|礯wFQ4I(! Х0۰? µqF7k|ZaYѐ_ddjrd,ػf__G.qIS*9l;,d2]e;QD;#.qF:+}Y}{RFrx\KG6'%Ga-@ck?SKɍ6C7/ iBO{%r*I?CnMb $qm EȻbp-"AVޢeLX}%s-y1z#WWN%eY;}\&irDf{ֻvbKGbנZKPMh P☓C, t&IKG);IT19I=y\ .tJ4Ӽ o#jbٲ=F amQ#K ~a7%$ N5L8ZkPBm7!jj_|ok !,m e]8ׯq],F\ZvoŘT=,9 aӜ}F` 'wM8\"zٜ *H άRovPvt]_i }W8FAPKrm # 5 jgt@/:=Hvn>>W (CPyK\`-LghrY69Q˝TXf&S Mb0.n(K$r^뽰 o*2!xϨ@@PJV_&rS-(G}6[a U}~tr8>ؐ?.aYVBFVk=hvz^`Z* ΌL`&Wk@b%kW qx욐DOR|$,GOj咽|4N|/Tg ́72Sy07软2͂2/`G a51{!҅썮깇tDN`R?8|  h$NP޲1 qy/cƷt'exaKc/0|hbNݚ uȵۊ!IsA o1}fȄf>^bja%&,`45Z0hjhe1TmZSk'`Kmp1(A8۬Og п}/NиٱB(h xt`Psľ,2~5!LX2;;}WpB=PC TQ;H. 7Kh1}7\} ku&syRugIyqZ3oe`78N] ?ÛxUz?M9nCflY[ E ϗ#?Wz=sxKV?tC3"?{x Ni^}W&⵭sPu^cҬx+>ٷʉQ:y&SMZOx{~e G6f/*)MQ|]Lc3cr"f4nx{~ ㆤ+7q xŜMsqԁdH [ 咀9䵩p4f@kfګN ˞xYY= ڎXb2㭽8o*OΖEU޺w._YV_O˺/fycgU5gy]Ey\=A1<7Z;2na->veO*4yaQ͊ Fze15:,sE˳|6I6CF,l{1_n4{L{98zB~|* g6Φ!_0/O})t^oiKxk h" "W?,$V[:,M1&EO=*_Ny]A0uVy8<e5<W"YfeN:MVk6 xKgSj6BQ2,д'͸.Nr '6?Ca;p=qջU2 a??b F3ΦxKFȆIZ8:mH^_.zC3I?ۼ^EM$ۄ'% 4ڈjI< 9V΅d&{D>g$gK>2#+yʖy`MTLM?|(bYmAY=[̗qt hk{) ,eˎ_/Y(Ic4T09Mjs7Nj{JʗoI[s&tmtƲKeY1KS:+WUBpIXdMK!lyjN?Q5PxgEB|=v~FE>T{6:!{חQ9](3c_'UZI+~̮l)M_5+qkx8l"5 _z6iEgSLVvٝuIˤbj1 +$)'eI"1ģCZL1M"&]3 {7U[|?dח,[ٔ5gYG4u%}ymF)uk:WM><:zy{"ߘ2xB! V,*"RzJO6;-M$zXE#u$4kgˈBf,ł1X ~Ŗs9`gDzj'mH5}#쨩ԽY}6bg?gw87cQG$J~ $vG<Za7`4؜11{KI8'{mXplDWWpTw]mdly&AHxv4IpьYhZM0)GhxR4 (>vaZTO'q/Bof9 fqeT~/ ٦ 6rhΎXZ0u㬈Kq!a?5 O_>}r0S Fݫvu:'xG#=6=cxX.<7;h78Z;(twvYR;Tt pС{)uAAǃ yF( XKyɘfWߦ>cpQyfh& 8~V1u1|6gKv`E# ~htS7(@ݣɣ oQ= pO򥹓`*NA TIݧuEgrY2. ?a,*bQBi쏡mDqsJQ|Lİڄ&J"k`.t$fD[hhb *T +Jk {[oc023 gVQt[[ӪZW4[Z}~P_?E⁀oߥ] T/K]Yq1+~,O|Si1e&E/4+ ksҙ7I@+Kq)x_c^c? zR9EıCA AZ=dEdLk1n1%iChtfLIqqFj\.Lt 竢%q]DQ;w𸶨߳bNn&"d^~|M>Lu'W)mxbFBvsrK;$BZ wyM+|׾`ָ[}5{bQ<re>%iDTV7u-25ئl=4-9@ܢ4wyri)xOaJ,]|9S4Ya='/q=fqLZ˂ 4FhVyhz+E?ŧ&0YxaLZX/Y#xv?%3P@T eHmF {,[&E\?Dh?6?=]sE>.NWS-#xh !Sy/"Ib/ca7٬ńqJbx<܎@]D ]̏pB|@d+敌&jV"f~ rcR4:JsWL>D[ 7B8@{9:H85COH:<5W6zy+IlGhjҤ1.zƎO"c'K.rj3mfpP>1qpKc(YmHr=!'b: Ԏ#":`tN!jB>O/Ch#(hzp'a*ltV$ޛYh m1FyC)z'n zv 9H&Jhnځ& ;Dm |l (r7EEـwbXi]Z+ש ZN3Z؊а}LH7{n0i;O y8hyDS\bΞ\~%Q)IZ +[8d[!t3{}LP5ǑC /fHݰ}'3ðv!OE]k Cl3ee:%N\_@`h<ғsPG@GHY'ժ]IR)n[U'll قTI*.|,VL7ʞGW~&Oi^DJܔQ8Vk~AyS3`r,LbdHžtITA@4WNT7TpSJ5ZTq 9u-jTZtfż(\8X9.) ?pK[0EXOvL>v&ԍR*Tt텷€sXvύ:qy$ru+"'aIXְ/UKL5Qá&V TVeJ)i$_tGS*9:2پ -Vƒՠ-ՄvW8:6Q^H Q}Qec(?JWipmPUyI1ԝe;% IվlF<(.Uٺ|]m 'j,J+q $iZ)ΕscDW TѶ[](K;{T"5,)pq HQaWFkԖ4!.v#r>xV ʋNBRV7P.bcĘѼ(u_Ϋ;,)}b ~K/7G Q1 wD+]`rrR I[TBD5PT! >qfpaQglT1/f#_>[CMT`ܹU&f]oJudb_4:ulgk/Jg +@ԉyHUlpGazҽf[WP+͟5+4ߖHX$98U [8ѮոE(ꖗՔ?#7%ôJ4Eنþ%u8m4Sٞ੕vB`T8ڡ)wDfãYY@o rQ}>Nz.H /Zןk/3]J,k0ΥTP {*)55,ՂGV\[shŵM tWs |y ! NaI~a.|xˆiwجGF8H\*꠫=ҵj뺒Iӹ~Jz .s8?`?WC]kB@Y&Xm۩y3\-RucÞO*\28O 2㮀N-6@wTs98=za/@lg>$8hmOc ]/"1 X1w#S31% Oh@#cpl#Du| #/- ,D{R֜Yi׬QzQboZww2KvU`-kI27 Ѡt#nڢ| 0q{}FT"QŲa=_(z8(61];jGy5S)Ő@TOk){'D?I݋%OsTz Npfﰓ"Oľ8;H7IEI6n~5ɵ~?0:#d;%5~D^=Swԡ.ϫTU_y60V\۾ ^{bD5*߁w\QsᒪDQT؄^;LJ8|?D͵GkM+B&5デVyq0z's"Jɗ0:{y|eYgospN@vcf&c){;bx޸$y(xj[B~AS#I /:O ldox{a5u\ߪ 'R &-`.4[NFf/X][ۙ׸+wKPZUjqd.VK+LG .Dx/0 ?x33'df#j',ɘnkX&넢kILKƹ>R1j02Љ:}|P"4˂##֯a:$x*#D ƯJs~=B ٳmWf+,y$ 2٘%FO{7Ҁ ^˳?~c ~a7Ք3}SJ2\]uiI~ևD+t /_)Q*?!y,kŴ*%%K`F*% OOn8%# #UwYUD.V莩SD},$={:1~xq _lxOrd߱)N^ϧFKiru), Z=/R<x9WTI3z˜oJax;qV S6Ht/*)MQ/.)VQ NKJKsl#Tir ]̛G.bLn.x;qV <G.b2HHx;6 o' S‡|5@Es b%xXoGٸHU -+PU'T'H I4n۝ ;s잻>!$@OH"OHq Y*.'x1 ^;q/|}g[ޯS^ZYL Yc\6ZaӅ4ZzXZIH*_XʗE 7/]EKG'n';G̪^$eJG~ '8~#A(XJme7Se<>on[DLt0A|&x{O~wRGFv!z<';fCo7Ss׫(ts~l.y,d",ѱAgf\%m'+.ObD]JiPw7y- jc&s&;CQevɕj*bX2U"^Qj~u/K1F)ZCk!HL(o™ϱk/.~ bµ7,$q  U'#$SN{&X2yZ#E(.⽈޼Fa%A&0x }H" o4 aoP,}gJS$(}tVabBI*"! _'K}+OS!CtCm H+#vچT˓ю Gی#55" вRkWJ@k~p cD*(W}O<|i04?X^O)Y5(+fQ좳nf&_K"䏟4n2}ټuT3 :cV@Mx:ǀyݲD|A+pkʑA۵n 5/rjMU WM>dd(z;ĴTe9AcOF#PˮGΦjf]} DQҧހYzƿ"׮>)fkS"'ԑ`&QrՒ#dy 7EJؐ){[٢;EA[!"NhcYQ"*- rTD Cj PwvlB;6xbUvWÐ_`-!u2@Ƨzu1SceV1hlzB}id}m +G.S:H *AD2ZgB=v{ W>}U %=̬.}r!C|X9d:=k G1$ZG,Ņ X*CDS]M@hS3!Bo̶e@cr*aت6-Xw}ˈyxeιiK`)mBAapϼN_KiXVPKmH!“8gaޤSkeۘ"MbZ%@§&[,H)9@/SaX>}Eֽ8qfs+"@M#\$uyOүNg|OV5`D @> t9{7~טZ9{舏˅wfS^n`Xi9KhIo%u;I[O߸3ޮkFE7A]Q !;)Șs.& @L LKw8yOnX٫$Z|~PĖׅ!.|ڭe8?v=_]D48j0pT\8@{-P_Kc 8*>vvr6[پ˶)Mf,)qI%ɖd7 w6MGExT3rVN;ge3XUt! (r=gl| )Όv1.ʦw%I">3B_*7:޾e424N㘫ۍ,)VҧOc4aj67{ͬa'O$dSn hF(6AR/[cʺ+:[1T 6 ]S pC;Unl(Cqnzm2}!)2а}4OBr!>Mze&{dO^W,l)^@:\ YGfbq9H},0 Vu }!R~rnč(,8_-\p{KEʡ]3 1_tGSrLsorGCO0kr6L$/Fk7BSZX{& vfvna`Ѵӊ)*7޷1~q80?80v%9*\xS8j;-LA7?Q]Gjvȸ^3ޕ`Xpob@e;7_ͻMѦG"/)XL1,=>T6~!Z8tjpki^}I^=oе;]&RwIAb)xi .em Q {rhlI<''miq B-0$?s5@Ӆ i D;hn9Y ϏY&Aow|ZY~x ,7폁5A󵉓@Ed6d] ]}W:O"'a9Pu#?t^+)l*ul夣:!m. &JVLIal unDsB_td[s\WdIo7 b1qme'㚬%d?*ޮQG!"1g N;vᦘOXN7yњ^ZfL7)}2]I^Ɵvtt&btӎ*eMs=~Ϊ#^(ӫ`4^_vƳ*&o/%mßN00x[;5 J1ݡ@/q!]uX {6([Db*<^ yYIdN(;JF9pڇf(1\-DoA<;[Q"Yt KqJ4( O3X]S%^¸j\2? *D :s I<$Ud HidfC0sʕGS&g*%* }ryV ؛s6ϛ1n'ݥ:POm xm9'A>AlѨ)Aiǩ9̈́1j 'C$%ArWÉ0㖎zٓJ~?,p5dH8ي3d1$?4Mߛ jfXON-pk_ˍ(ʓ_>sGsg3m(Xi!KS[쪣[:(]2w;3P4+0"<=;l^n /xP# faipG98 ]!^i*,J)V1~]35pyJO;'pr\c|1w(Tyzj k2eE_"8x2Beu(iLT_R`'Vp6sh xQ Tkܖ;f*,͇E,]*.w\G9x7L ګpTvBhko ega"qY9d?3R{G{Kz/{`ho\"ZqFESC:BH& w \<8TH] %(D6Q\ix-* Y\¨G*c}Ģ5g 7.d3-[xb.M-1 G$ϮH0}mndD`SH|2&U1 Č:p̆_zvd ƉIXd6i-~|F|j)IJZ=P+Q(kEAhD@s<*-7Dq]N k@)sD9#'fFn$v+sa_\N]qY˘ntm_6ɵ+mqoo߱0xC.neM<㟤M-+jQ-tcL"gexo,hKau$9[nc<U ^UDžڢ_S1imj֋׻ӑ| 3W +T wö: D.VSBDk Z2x;TZOrʴ$E&?ٌX31[ YK&pUL3$a_߲{a[RT"X0Ƿp3[b>-LTh^X҅wb!Y {+xb!O̅'cǨdn%k#ÆOLnLkbVf&^ߎU߭"fbs<5<:Vl'K'paJU o]j{D}ڱX8k:)T'&9зx}ksu$@8)LD<*Lm5f@3@,LVE:\.P#kWO;cfў}c0Y(=s]n<7Wr2Ȣ"I{΍?O&2lNN&Oxw<<wxངx[>ݤ'8he}N`)<ѺtJ3ϒp:/IΗ5ɧk9 ˣ*q$%q0eXM/m|`=ځ  NDpkIA ûҿ\tJrwjHM>X[Y hF?E)|a^nxe&@ s:F'Ў~4~5- ZQo%]y"nC1 wp_ Hn/H8/qaR0K~ynR3 $& c466= <&"fXD行MI8>;mcdǓCv5%y7?^Һ0 vr0 iQ1?O iXu ?%Q7·w0^>V / }|*{MpO\o[}[QVFI^/rqϱ;:gDGۿPa-0<, rdnGyf q4"K.H 󾓭Cfr\ O G~cz5$>z4\i]=l r$^Ժ;Qpw2Sڇck[#P[w :~,DpCw|D>8+F~Ӎ edoĜ 1Y%YڎD$ LiW.߼ugz ŭF`8 6[oiP% ^iv JMbˀ"u쥅XB?V`ax)Pubd9aɡQ G6Tȸho<\V"/poMߵnIJaYhiVhG<3tM}JӻM==MsGH)݂{+ ~'*,Y|ÿ$bDYZT~ eϭ'ԓ>AP'~{T;cf0% PC 5ttAexяђ_H*K!z&%밒$.2~?Kbs U㭘UҠy`X#ave&y K#sؑxv'tHzhJ/X.zܵ{w9H^ Dn1$/;p9R lN;`0{H4߶ <8O jF6?!hQiTn!cr"0zsإ3Sl3)ߛͭ/6;x^DI$tF -ax %]iʇE #<hC!CA[bd]wWh)D~ #(2a*ɽuL#_>Rj܉@1ЦҬbnAڅksC`xB)Q^ނ]|0SF~Z*pP 8G|+jèt"`pך^sk@."LT7 HxPY6"# Nsfg>]ft)D&\?mjT-X`Dt\/~: d CnpȷHmD 昿A)OK宦(@%i1v0E"CX V%-Eчqn~s,0Ů'_Aoq 5`_}aY1|Wtہd`﷓~ Zc41mv\R9Փ>/u~:R'W/-Z12 _kmӥAo\ſ0m(Q7hM)^P)8 DF}@`N*49X Di-E|_Qc -\Hqy++IogRkx0ˑ7ZjZo|oͽ%Eݲ}ލ^\d3Tict^ n>[-? ox0D'ވ$JƂʡW۬ :fd _lc] ;>?‹onՙdYĪPiKe/ȓġ>ekɔkV2nBb~vL;Y_8 1xrؐłeeWcsBoq?G0u%.e1;mRa#:&ƠQ&yj>Y yƦˤ©/QGk/^q  ۇU36\ hlR΃<7Dbp޺XCY4}9ޙMB" ?HzP.̙~y`9#8jx}5-Ec:,UdEl,4cv-ZDx?ι$kw󽸸sn9w7M~r)G?1ǭ f@p{xJ'?pchBedeP,_ @y5&`f' ڱ~f9KF UPJld2}@bxP|K`-O6[D(6]o^{H 7~T>"BFÛMp(,tXYGd93n({,0:nGn>ϔu}/eMYxe2˔g<ΓQZ%JFEk5qWT ێ*;QnTh*KhlD 4 ":}fb.T80ZF]Ș[d⻞!O܃PH{ln )SËY"6ϓQlwO5>Ίܯ*I˷e\_$ {7z;Wɲ,HjsS2h 7~,{>ۡN <>҇SȾ[;h4;Y~u$GLQоW2~A m ĤU{/17}bf)}0FYE 3)#Ns͂ Ʒŭ(d)@'l دĨ?"+`iC|@#CϏ>ovM:(zGΰC頩`,o6}`Hv!gɦӇFlf|?"!b}!ջUs8: T? x|d! 86JjAg){'k$| Z! 2PE*9͡@b:Ụh0%l y|l  HJhd>9~J7L;Y&_ǜS=<Մg̱I^Oِ}- bu8œg!Sz`0/!A<j{0+qY_6"9w/sΌa{}l_l{;;,h|+:sӤ:?8 PQMaپ*DbO=NyD~6υ6pD}#}ž.$˘D[skMAg7nIQG-T50v`p4 Ѫ^J  soQX`ZzeԈԘϴDf@Vw_S@Zhxe/Ҳ33z¦0[FI|0k@N2<K;Ƨ]Oھ, UKM%"҂U>Hi^ߛ&jI[ z@J9c.0+Y/'p?xQ;VDExʢ^6gpm՚(6~ q Z7w? >,kRU7q0 Qd;VPO3+A}% NgqQ^L j鉡̂}Zd/g䖜!DVQ69bVMK3>B5cR ~e <̰?7`o 'g)1YR.{>yA#[립bUl|F1hPGYcR$FGkq"@B ~qnMvC$iGkP%ՄGݍANҪFY !QB(fxcD gWS5|9| O0~xIŋ<왓j.mY4:tT .~d%OC^!nS?a `0\K`}$h/(s0"yЄ|?CIw.N5Aߣt4f_y9K(&&O~#WYڐ̳D 96cqG#^'K>SWh5ϐlZZ#kƈR6jH!5[`[9g̬gppHG;Q+n/yZO0)@U4w۬GJыƀ&l)\N3.Iy@.R']cQ~&aCxJmWwx_7cLrP)se8y3,҇@b~٧{vWcȍ 9Dxq&^pr^P;ņ{'!E`\!ύľ2wŎҐ&;_J* TMGK(%LE?6S6|x.*u˗;_C(꧞RǜǑ#px(j<\pX4LHGu D}x ^}KVU<4)Z)?WWXMG媤laNu<#/9J(.%->|UM5t.I3`oٱ0gE]2V>f#WJ wk)`1{bG 2[Z;<@p!;NMq+ϐ8rYq#I}˱3ɈkCx͌@8mU:l qOQo ͥA1I:sBKŎM/rB* )C!S_&i:R~+{F󷚬{RN2]1³6ak6qz i+Ʀ[r@ 5)jaLJ\ȴAJ1ܡ0u"msL&W kѥ:3l PD` d~֍N;Kr )y?Vl=fV%Y,H (P_+65;KBҮ|R6zjkSU0 -%Nԝ2R 4(аw?w9SK%t;0GgpcSL3K$|<[U 0u (֭C>` 6x>=5J7գ%f"}fZIJK~ŲEE_0ԯELK Pv]RPw+)F?\pMw׬QO*I 7#Vɍ^ W EQn\>%1pUpRv,P|dC~zBir%إrFOK {iPNЭs+~Ea MXvڦ =^24o?椋SJ|ڊ㴚{@:r̾&؉bHȔ"Mf(;[. N\z/Γa¼;]viFL,RqgCrI%xS!ʖ`3e e1d$6=>9ywFE؏YvK#.v65߲)99[l{BnNz[FaC|$ag(4E'wj@碎S5zK TW(KD#`(-Vj#:EmIr9,Ч<==h|m*X:y bdDEMm:Z ΐ_ PDNdZS58n1 * ו=Ǯ:$..L[mdw~|E{)LJ$} E\Ǿ&* PqLKʙ~ujliFmW֊8Ic+]P6>6*S6Զ%Iy`8Q(V$t@"= iYv-ٚAS\u Cf|R7XK>ݼb[_ A5#Io롊j_ >A#:;v%̦^PoGbIΨ_v/jܺ[o) cȩp"ʤ< .zljipA$zt`uzU ~I6-Ͳ6ɚxZ?6 *@HMlV)ͅ]ʹ52﷯d@͇|J{=:e3uQiݫCpXԕʌ,#R[Fga,Qe1.v>~󕄗GpXh]-s5BLA<䱶&vk"^ɢWUdJozbc`puҪHOn)$S?@(H n^a:&H]WiaR׆N,WUN]{Z?ףd 5wu!\ kYJn7?9Ple\klI߰M +ܮD瓸%o)ΛB#={v 9-]bQ{ XBt/){%o ҫycc.n:pyz+Lݏ1fTJ2-4 Fc3.|EoAGWDg@J(4S, 0'YIAJ`1Kk/cO86秤M|%qࣷY{AXC)qg 'WX ?DZoS\NR,HlAt}ߺ-0odè| Vd(tΫŜj8s" '\99m_CqλiI^yn|g̨ KM$ Ece9?oMe+lԝS<6m $"El}~&>.J/=7?]Xdy)әzT#R䉞iQ> ^ɒ?UtOb2ay >eH{5}ʅ.vZaJJE7J5[B%˙ Xpzdkƙ&}.ࢉb Ƚ@=r~1ǸeXmN> 3+7;L Ȏ6uR漷8֣[V%8! }U>4YJ >7ʋ {PghM҃s(6 MXrК:|#ŧzȗіH_U`%wZ'u*[\Q#=bϥNI8`4_]}C>L-mK6.C˹N,Y60&>Aq¤#U"9x;6i\ vL6lt`pa}^l†Mvl^",,1Y^ _VzGq/+92JJs2&[4q*f%&%l✼Bwo6֋v)LPZ7yFT]s5qL,,za' /쿰bÅ\lu.ӆ$+%f&(xLΖPl֜ 3 wx[ N +~ 5@BjIPJYZo te*j6pmsq'Ow6}.~)оf-~7"WSZD  registerPÓNJc܍g:E3xW Uܛx>lV ," %xuYypuJ$KG@R")()/E-%$ -JGQ-Sϕ2mŎnRdV4ө;S&:J:Ʈ&cowAPI{~ۘỉ V>䲱e-mlCSS{CӦM85u6eQ|<٠0+Լ*H$Ȭ:|&t3|2>>ZA`66{n\w{Y)ڛ(AY"YQbGY$CT] ~zLḚɝL%UtY4{(ɖdH[;q۪NWqM .E*^<ˏ",CwCCˡ;cVܷK,߻WUXE}.x5˟e@:fy--tkxEnE/  &j2鱲4zOr#| {5[#Ms3OJC~Ts(Ez;KU(n^QhR ^Vn(d(_KSp3Bd 0OnuN|Fm.E 0?a I9Qj2ݩ3lP˓(Bb >LV 9E~Wfo ?9O SaBQo7r. rqäA1CSd6)y 0Q>)Hie%8./:NYR.ͦ7. ?9FF哾T\GC3Q ?)Z,p,%`'OnOgЙAK=hAGߘY m*5*ETf_I"wka;)tRƻGS-ft1t R -3r-rSLw24c4|Ք6.zԄ ;&ZM>6τOᬅ<<7Ş=$' IrFFܶ ^I$,K̃6m%P_nnP؀᪼b~fў 19Ӡ ssu$oi=Ofk ftڑ1k-PʹZ@h`i#Njd~uEG"}S;j4,aKP AAk* omj<)1~ *4iwIfW$Np#;ޟHM" ]GM.%UQnB}*h\RH R JLOdD4tVUQ`|?PD4[|K~#ݦ QPn-0D_j%,K{n/elڗuC}Hl,'cР u^pݮ ӄE\o٨5-TE.*iU{RŜ&xq+Ϙ03g_Λ/ɏs og{Si 0CZfCP2Ҍ+V$U\̀ Sa-l45%Bo:_7ǞFhFzXC2}% JVڠ2:>ɥ87 I!։2/pYǹa^[:fΠ~l<ޱCOo?.r^fV>Q=߄!Gۏ/Qىe@WZv2-u,0. 0&#/ 5L} |q^ ?hGm{vJ钿k7É KN 6bN;gׯ2[P+n1@[eY]oPn_J-#[jyQ ~Yp`X55# ) ? Ĺwoz` 3n>ME 5'/kH:fL0|eW^nW];S-xr*-]zEpY{v{ vB1\MW]| {rv`nINڝjӊ D&i"JaJ}A\zE>8I ?wzpSvOR6;HUi?ON󹧲eܘ[FZvxjTwno*q[;ԃ鶡 Μn9OjOu&Y+X=bstCH]>QNvD7g-Z3~+ 8n,W{)J.k24;8ܻ.PAK}ΨxSoH]'67 S+=b &1ڗy1FGf?5:z˃z'"ާw_kbf9StccAU 4Oz2]ܹ+Zߚ %jQv)^x.QZxtݔ~Jўbi[ dׅE %6 lfKlQE0͡=T6xDzez@<|.^wGS9Wmmo S#XkW8O1{3?q7j2js0#0v-a5#ca\O6x4lAgwНEoh\QS\#[7$Nh T/Gnf'~|JT#mhc"_v1@}Vv[ OxW y5t.LbdCɟ';+8`)Lޠ`h 7PNS~h:xl&% $Id: uk.msg 1201 2008-02-19 19:15:28&BhC^3%d>By<Make room moderaF&?=En-|"5xUOSWυnHƴb-H&٢8G[ޢ u> kXfilF"B%3Ŝ%b`{n)L}9Pzzx$Ie4~To$ntאwk]J$%cr^7}ҸPu5dWy??Γ42$"fw;;Rl`75G8\Q_$C@VMLzM;&r7a3l]gl,l4R8%!T Bp5-.pWt"2ZINT馤3Nո!zM ɮb$3||kJsY{BM!aI>PX%v>Ħ$? kq$+]rA/>JYs: =JG  i,P.v D=B{H{(lw 췭ZZ>  ڊЫZ\YݱUI6I2dGvp7T36]ʇPWR%'pd]=$C<'Q%؟2¦8~pl<;4R[ %4E5?8H/()[ZY2Ԟ`XQA0LA%*_Z]HH9M̞9s7|܇_ g/ dC BbC 6H|Mv7{74ZBEv\mL?w O*zKJhI1P"pƄZ'e Nۨ=2lK\ݼIHA'}=U8vyvxS|S_2K8V_jʗ˻#\ #+QMg^_f*Y V{ǧE(RAlfF$&!BK dEGGH|eԛ+| Z[7#ӸKuܘ7ysҘ,sISAQʃ~nm#[xJ8CǾo7i'δd3-MSҡysm&d]U*=^cp1Z,(Eu$Ks !_3n1e-6 JTpXXnoJ46bFB(egАU벽)5&2ۻc s8~pgDw(Yi\609>-QaT!ymwLTՈUx0i9f\GS|G[I PȜ"(v\,Lz?gǺa4O#Is 1P")2t+{CT n76ݥVɵr:y2ro#&Nlp}2BIb^ЎDEƏ^4{_7 h5#k+cmp-> }yppӋFN9%a ܊x % .) 4*)vf-s6I}DE ǴHftLcn0ǝni =}<~Ӝ4'0SpJk/Y]rӐ ZwdZGEEC8aG:̷Qe^ QEZŽ +457faN.qQS*ޙ:`[2{>X㥃UTYi_&=I̜bDx5K9 \Lg 4r\Hz<<+ ]sޱ&MȡAr^H5_,,,KL$#^! 7L⿚ x\ǵ|W .;+[vWkHI.oO ?`# Ƅx-D821=]IAqyΣ;עwfM`mWY0X_W`ܥJbqZϧ:aP<+Q4Ȣ jK*I`iEfõH])`Dqq.Lݭ_eY?kqLDA04VaRU8(3..#R,%jyǏ௽dq&*Y/gנqT]U-2U{)7U]EtQ3HeN4Z|il {Ƌ2fҷvn{~ 0ǿc˖"(}kyɯSν粔2H \EDE><[*ȒPMt tE>Q[+SDF1 2KRVԣjf?{trIGO,`CS$Y4, ~4ߢohꔨZ|ՙj=QxQqYUIJv=T.Aa+(wm7gb±MyF]g9{!$ބ!Xsc~Z__+zVNOErnE ʈhvT "n|F<> <@Ѩb%d)7:P𩮪8b^ "0AO=c|`t-LVe~绻[^0Ϫ QJpX q+ /yMQjǙt&֐ ;UAi`QR8!}ZU kmcr,`F{*VKuCbJO DԐ"1᥷"{1OcFU *ơs:iԢf> ieb.yeF? _: ,pth9TE|Sg5yfX͊|_Gs`ay^øBZߞ${tsZZ{,x\w.*8Xۍw1_y`/L?oYf"^l@Fdz[`uJ&hjՀ%ׇ?fEF"c) tȢ*g3r32Z_`ofM‚{-6_讧3TQ|R)M.^MԈ4x*vsQ) ;Q Xf$ܭY4dd]֨Mʈ߶nk԰C~SϫXcMρl_փf8գd69\"*L(82nixYB^lJHv-!iK'A60 Pu)Kfw344v%4NUw׹;&(x@[*0:,M0~/>;eoJv* 3)S,'n7808#F^SXԂNDuL[L0_P{%Ϳi,u $nb҂(mjfvy棁DM`XQU]Mr6%,&=h*v2G̊QbJZH?ҵ]~.Ețh7"8Y "CZSe~^>TsHјhnsN/}qߕ 6wS#D:s5>*o)y''@OB ne?aVg.NhUrs>}i ln 8gQ35ENLكgI 19HoTtf` Fw b轠 |æG |L%rCZvBB.ߠlwt۲4d*  ShMY;M[b̄ *h}0ȇ0_j X ϙ +WYؠ#.tj%kJηp#vw1$]C*5ܲH,+`jU2ow$O}R"ْ sn׼ZYt"(9tqq)O ]"h #"G :q_T/4jE4Ş9N( VbKߤ"ڄeŞ^|m`OлLF@Y4 f i捥zh4SګK@oRٕD۞ƋFNP"PIe,)(p:=JK O(݂~ljQAQ_G@ ߨk;R]0-+D٤6KTgMOzNqVfy+eGe[y*oW[]ܺJ,.*ݠߠX0 '&26jVmSwe=~_'SAɒg-;55Ԏl3|rȰ,H]|jAm>[]N'AvOpAW PcP@h́eTDf-j#PQ}nKѵ a- _bIw}BXi^EwD%Ae= -NqΑad+٣13.koĩ'O7O *9 v%`8eASuMb:z_gmtJ8wa"-5[`RR])pbH&Ȭ^ ѥ&DϽ;H$jWhVmx  قQĸǧu5HA `J8j*a[ 9VpO'ž׵r* ك`:?qik5nU8؄TO0qYRD ĭNSe t8pާ:wQ7\R\RQ)DRfpֹ=猽 |QOOhvpUt҂g7838 ^/E7c.+|_#kژM0, wA>X^G%ڂer ["8u2rAT?DŽr;j4 7HgA14&1}$-GLI<=qfU j7ȦDžH4/.hU-\h793WZuADz_#0SW)LDOV r9vŚR]?>`+mv7va`dKa^ ,#~VkU;yC| rș=]jB[6m2XCRՔ;j{ENʽIw F}_+x_qT C)(3 {S r.!^KyegJj"]k0ZwU/7M &5lҵ,Ǩ(⹥y?3yozn<6-pGR6( = &hyRl/칅 ?`ߓw`Z:'/US7i3|ۃ{s_d%us}]yb̢c|k1kjj@X2dynQ.襻\=g?,Hr`_Wl|5(BIDA5U[GB۴Ob໋ y:`e*Glw"dndV!˳4]ht n>5vfZWpE?ײ0/&jFߕe />RƔ:Y\Xi>UkqZ.QyGƨC+QB WIB*w;-cQպ ᕱ~Qg \M~wDG2[6 ,55&D!L5Y6Mf~]9x;*0As;?Mkν6f*fI)rbԊOr#4,YS`f7W`/1B+zyfMre .dغj>4i͘ 69ۇԽE3*Xof)+%#v l=BF".J ]Q-&IE*'cі ۣ**xUds.&daY'0$߿s #[SV!;H".ߜa0]c3Q8m$',-W}{>u]=)>?M~RGi>o͙u&69M;y/`v+gc'Vp2PTI<8 j2O,zHyV?$ Vz2 %ET\c;W4.2Hw&̐ߡ|a'(ZQ<rR, B ~=CFxC I%Tvew$>*|1FװnnuW>{kG!%K /!* Q)M#2p#͡%ݼ{^|`@M[=zcoO|e?II1,;hZSp Cr_3v#[GkdҒ$1N2/0銼ұgm?^uX[~"Yىmؼ;0ͥ_KQrOOkr7v~ xnGeAM2 練9KS (~b!=JEHY,h;,L FW;{ 8l4xMIzf/Z}d k{ofJ+3)UZː5GptT#m)!zQ6`-g%V - :w ޥn1M"{i{y!a.d3`h;Nt_l玆A/ quлN9)DHSeSB@+1 Zc|kb.DXLƥTylSė\H{D L":Zd^wW>` f06m@ژin}MyC`u.)vՀ}wG!:늪$l: ^{*WuЪZ}ڟȿ5 x7꿅? k$d5d:n("j8^o 4AocK8!!24"7uDSUȤtF,9w:W:>3^}mp _ iH oovGu`FzrgӚ#7qsW7He5Y\AKWXIJQ@Idoc\C_F:d " γpzЮr :|^qؠ}~ęn 4f-EFpI.ꆙ=:'q^x6RQ0_}oՋwp~teۋ7.ݏ4P_F'1=P?U`o/4rZ0Xvvݽ۫h~+bK@M¦89"ޖ;h~_| C;rjdx- 'V|/UgwSK{<? {R_},9𒟶2\\=I4e#ޗZ go|Oɋ LlHrze0_x޽yOVSu Ջa6ͩz#jCYƳI}U0xNUAī v"=SMe8vjn8;dkE _Mm'#dFW.y{Fc|\Kx[y¹OUqȘOPofICVss2!s&_UtN ׀M 4S,\+KڽO뵶shHwh3!6nHA ?}PX%eEӸ;R]MIߪ̝%>zҡ-6mq p\N ?MԖw>Y%eztuԘ+#9= =kvDꍦh/ āj{p^CNvY_7>yRpP&{;X,sC5y"c;KN7F5üehFei-n4.'m(AQF2%n mG NɽS(7C/7zprf^޵f>:)>& ZMDs7<-!Y' zI&g5:Yp1F^ݴw:`,jEj]Rh{"W.@a6-Z0 #u ݻ?] ?^+~mn^|5@cu2Zn> @u M:Ϧ3E-)Za'q/"[aH^ ^0P"mmۯK4 C)t &~`3AO *o[5;"=y5[w1/Սג]f *O Z*k2\~F%^xmgA9Q,DGEQ2?̓r,L"ǥuv1YԫxLN,!{sf68G_Nx34o9! ȋ-sݺyf\y#[Z{X=bk |p\yV|M>8ٞ߯1B8RDk03cL7- JG$Q MNZ8 9yN{_- d3nep^dDqHS&g#ao0Msńb,zy%$%.ZSTٌF tt+pYHĀ:zЏm8MDncCrKA/3LJNQJC2lp oxüs`@0=hT&!T |,=N߱1j<̂N^m51*4grDhOJBg8h e;ַ YzpS(1A٧}$wj@៿2s&+zD2֗m>rbɝ{ *9HSJdl"#y ͩjlmn|2 o |`._H6[=?eq+Oa!SiO6`ykyQ)Vt%gCc =(&0b$irm .k ~2n V<8&P`don`8D(Aj﫛9x4g{ӖI _C CNC]|ss S>$׹f'+MN(tdWi9~0DzUԻ>D4*f|&h]X3\H7% Ʒ^>M^ͻ@QA pS yY-ٻѤ¦ < cu@pօz[O?Eq"EP0C_FY0#P QbnaKDN0SuLI #$?O >FA%x| OlJ⿾llt:苘Bp\\g2% qFͩFsFSn6aObXVz$kN=\PY\Ηj@fB .Bx-0 i<5@RH8HHe\%g9= uض i]JhMd(1LQ(m1Rvnz0j 6Z`p#?G-I1sLX\%ҰGL!E6 >ZbX4 W~9}ot98˚9ӗ|vȳ~ԃ$+ygd{Asbm+[HJ}.dL]C;F_F2,Z1 O7{43iCpF#o.=춹N;{2j6P>յ(w YkANl2_&ʗ۾x;=s~v"ZR _[Nn_<( Vqq G>Lwe NҮ"`wq0nU*1#譫om o k`]Y v[ad;G)EͰc%uFT2d?Y˃265aVM EZBnofQY7QAi. 5 `n21/,7h$L'9Jh iB &HŀuzŲe5iUJ *@tns`٢c[Ɖ4Ʈ i* VfPȭ`3@n iyD &`$b++$lN^>J{ͬ#lMvv%,8I𣅟C Vn5395Y3׸a`[=b=@)<bS}(ɑ[G*L{+ "Η9f^9BCAhT-S&uG}*$^F0~w  *1*P aGF`&rDJaAKV6-2&;i.sAu.If!c~K%P2k_g[gFɱ_A>WүDʂYZffO  y[NE p:ዴ@NցؔMż)pfMIH(RT2IRC7'j!bАzIUwC`)?_;:jEW/-t4:^o:3C1\^0W/@Gq IEB`$mmKjekkSx?ҷ_v &:bAɑ9 \g3 F &_A+̖*@73Zr1O4s bQ,:^[TWQRP(Vǝ`g BWxu1EvVm! ]OIO* UQHaJFA `v{aʅDs6ރ&RJC"fR̙v'w *ȆD2~&˄ 0`qri p\fcHndk꠳FE8Nm!I^ Õ nWb@cbFi%\.f  "crod _SI qq gyާƱ6,$|͈*GE?@D2**!T#3 c,엷f'ͨ}"#8ي y kMY1B @k$dC8P(u CUOT2r#<|ۚt{㖂wC«NSM}[98]#ʐ8>2\FG gUWzThI"6V xz8WǷ-{ড়ۓ^&iٹT#ls(KP%R S26DgieC0)Mlܛr2 ҍk)@&mͱS.;< .څ< >-yi>VteONhrꩱ"SMA p6Y=6ʈhJSmd3:!є _0/;S$З D덥ԕͼ^*ɩ F gC2]75 Z2ЧXk_,PI;Z9!moKr?|3M͈DQIڝG8/)^˧| V BKpx2?RoEݥ١ZIqߴϜ쭿"5GܑB&i +@nVs࡟kzg_:DV{L91~W- KB_cLR)<R.k3$==]ʦ'Ü:.[.qxm#V(=.er GZfyy4:9h\y,0V'./>̉zī S oiKW"* {yB>p$P> M6O|՜y~Ek:yG)< 󜨞T&-lEa=89V <Ƒߝ䉄 Gil咍BA`x+)dh. ?$YN=ΓWA2&$9 5HYϤBqh-#Һ))ҝ"E CIerwƶ"Y+!΃2ptߓXߘwMfKA[2ipU}sSv%>m%|&a8!,v.`Jz(2RFnB!:7'1G|Je„ueB^ˀ␦/9A]x]ˣb^'o>%V;WY&es&[y>$TRM߂HMquB4v@<5ӒkԓI=]Pp}o൧?ċRR=J;3H}B @!@a hH ^C*Q#l&؛ffԽ>ZYUO9zgTg߷w2׎ (ɡŴZwjhSY=:*P*>|;~7)_a]UESw@ Qȴ#N,s#Ӯg!-X{$+g= b!CsoX~¦J|)}ڵ6[#lT#3:E8u(Llw >MnYG ĞQ Q ]@g9x͆l]F5mV瞁R\1]zf!JS1w)dƛ(ZhyM)䔞R,} #UDj5NHyLo-_yXn[C $ mڌ4GZnmBʫlFE+(f˼URwo+#hR?!K 8sx.f>6Q?&jωsBKWW$^ѧ)p{2 ^jAtpcC ";fL  p"S ;57J/X?}; oPJC`?޽Q ވ ŦvL/6ڦ@?7o ~ Icc?]ݿ pj.VVzqV[8SPx9ҕ#C1?r!g42s1E>mB*ajV8 n!K!=r&Tk\~?]tFpС>B4T"`;e:cz#V:|3|] TW0$)lj&JјsBdk}C*-ܤ Qa1T k,G`/2Gc-ƏHRihoUo !p-V5+C,"Ohwa6q&u &m5xq:&֨v`+pWCaTsS*HDXB;C^sdYFt KCD"φ z`ߥ,j/!r*2{094Ӛ`F3#>%2!pWj+ؠ~(ߌ${'^X-bhW;CPN5z=m>Wf{%{xxFCަJEreٮ,.7րDIIk_"pGR!zDrӷ`pM~j_=akt_v&o.胱LG782N%^W'V]M3k%8%2U|1f̒'zG-/^1B+AҾ~aq= E8Kx4@Yz뒭~5Jejz8[psD e_zE2 0<%n7|^P-2𺘊|^߽3)+MT>+87Fhös~4;ܰ@Zڃ0IsTQθǏ?¤K5əFLG"&ˊfg /:+c5Su#$MNc11^%>JR 6y,yGʂ.=!+O>],Q:>vQ%q}>KvR}_"BL$g'?ksF(ѕj*=M]gךbEm )7gkE̊k;~,U0V7y1x],輬(TOc~'=OUj,Jy&@F^Ak7+/R(!ڔgBSOm1A]z+0)S*?wE5> sRAsrRUelwE^EQjC"$~gi|W^ȸR mJ9K އp;3jqq\>η7nOXE"44^%?W-u^0M4K^c3bZ y%|oMdμŏlbl=jzW%_#d'? ͇(Z$Ȃ`g[+̐ZXxQb…'"_pd=sKt8{)uR@=K`M&xM UȵT,Ttz- $AT\QGܮjNC PYYF7_mΊ6AE[F=([ihAh0Dطw;B&YRcܵNGG}tJnt "oxPֿv6mX2-!=Z'|vcHyI)Z'LB$Yz{t@m߼7w%PL]<<sNTʟxq1Mf Fqۙ\p5oɮa83,N(*.ÃA䚑Qb^'nTC0.Rz:Y%i]VRq+Xhfo/M uG_n$ E%ɨtNi&s9޽B@ Uv >p[/hCk!RF䴖IfC]4@ͥ4 v(/X#ٔ}hz9Ҝ-`\ya6,Z@"Vtn#|R0*=pM_pK"c+ӝn;,xSf">Y4&*:r 8 "t-?/)z-cf8ZWMkuoU9 m;Ivŵ0@节2+-1rSZՕerHiJ#4y^D3L` VL$z5h!qg)y8 I`!{pɑDtr 6.z%o+W1 cҽiBpSKi6dwJ"6˺4N9+S}e\}׼2H'j“ܖXJNʜj 6RTtoj#qg,խ%GZߵtn:*u CwICbk yis`(S]ev ȝv[4:ˆZo)6eLspYȏox(mÔdnIE[ڙԝEDZgrewB ,ޡJ!QoZ_:o*ǿӗNhuæj|[X79(7/-Hv`M/W9^Wk!dUUcb/^S3f1cZQ7x#*y*냆$`apƜÐ U$Y:`L۞bc%ĐCD kɉ=x2[K=E #_F qIt쇧!YcLHTM2BB9>O iW#Z?S2@@?iMJc£֎dE2#` 8ONBEمV2mߧu񏀶A$@d+g \rBSrԈ:7I3ȤK8=,*V_vX4˴W`ʿeI~[Zc].|'.L:ģp}DzǨFUV(%ݦ)!y㞷|L$Q";d2@FKnYTqLf46T.N.'<)q};8-܊6zy]mZg3joݽ?;<vx}XiPTW.͢@Z"[Ćnnf5.1!.E 5$*I\CL258Y*ebT_Sg_.YghIӺ Ѵd6z=n^^Ѫyy[1TֺmV઴mYv3[uv̶T9ľ̩PTc|"*p<&Ӛ:6ߤp!-!* RoE!oHCaD>96~_  YP*sbShEjnК:b~ CIԐK"[cV[ŘuTO6sv|$t$td֌I` -(J&e29gg"k6yIPn}nsG% Zh$pX0!xʟ]p obu8md l~ H9BhɉߔsiS)L8$1RehsMB+LjXUA;yRaz+8f=;3h+kaΪsL:sRf) ijJR$xe L-P0 ,'ի c~kǭٚ)tHc 1wܙs4,BWEFk]bYyzr09o<CS^FH|134z9,[|q[򕰪j4EŮJax,P]y7LXWvk)05}y -]d$,z(ř _px[(Ն"Zo6Y>vZ٦jVqfg.UźMlQig{Ҍ,QRYZ樷V86b}Վz8rJDE$[`uڛ}^k]uײ-HN"u][iu l؃pX_.0kp}E#cA߶r#ci&7V^9tИfȶ޿p3!QD wER`F@9: \>T_r#G J W27J+4wJw.vhrN|G}S<(^ B۔P WfD'atW&URWP{Qt;_\TU'ݵ!ol#e:;*Tݕ& oRRWѕAe Ls+bbG2m8LJb9 2Xax&\j,Wev`E]7$[YƷMՕOq;n*|y\e_6z_¥8}{5|ӄÆy*HWu䂭Qh?L6k4Bgl,#dku8'H4U~ @}|R24_A6djWP=U_h,ؼzNXZ؝5tfΊIsh\O(|N| `>k:[[ilD{u=a8aju˅a8)pqN4HHLK͜Ƣ86P,Z)%y):׸^. VN`L&_/w o/QH_t:&-DPԳ?Jx8HUxP1°gC8=O@O\b4D,|MWoT w|M#wiQ1*S{E;ol R]2x[P O<6 @z(^%^qT#ٯNc.::$+ _@D :$a2e؎sK }|zU[2vE3eg.UWD,]+KaM x"vQSVv)Р[7pIyG_2CFCMX>Pq![F4XWWoJ-J@+!//ԑć}'shEx RBCR +): 99Q70߇&(*jB}Z! [tkeb[  1LH@saN'8Hja.P+MYZ\d nud$,#<ϢdLW0&k•:ck7ހն9(eׯ E;RΈLOG2VrO^`dΈZȄP0C7F5]^`WJ>I%dgVT0.K(iy1!Ÿ)9aaO"ei*1`\鱩l}0K'k lā^̜Ͷ$¬slHҪeK(N>URHh]R8#R 8yJC&˼ };QtقS9̊/un0zwM;GiSRH%%ociA/ pAVJ TˁMxXV$9~BkM=7ӕA22B]%42%X{օP{!=PAtfqHL ߌ HT|Mh _)s9ZЅFsBl!b:{.'|=?;-,^k8'kFk rʺn,g*8mbHqu7ЌN[ui=->nDw©k_zȢie)Ԭp離 p22i%+ZJ6 օʎㄺj. vU䬬mi'@`#:9!xxCI3th+)crҩQ n!ۺ1R"{|ui Ϭ݀)ˁ0CzHyaJ gWp%d0ӇgRT~wNYmZ< eFx"h`[A n;|m :23$(olJfS߱?Rd;0jY yrY:ܡցe(f!~D+6 H 4 ??X-<[My$OJ(~W,o/3mϬd8e.le)k♄zSsY+|`Ct)P:7^@\V+К!2okST BkPOrӂ }NC}^HdSk@ 5ŭ%0ɬ.{P[ |ΫA[T7ՠB4αv5k25hnT1aP ȯvGiцTFħISp-*:>|ICaIǠpG_z#9I:g4UPbZ0ǰ D_(`h.|E OLMS13d:y",5{|O¿d *tJn5P9}1*Dpd(9S]t8 9  u/Nml@p`wL&`"G8je#€w_8Mt/փ5\+֌e_gi i`$yju""\1y(Mu>>gl,cG鵡4L4!TYH $MҤ+ש2,NL>N7'C92, ]ۗ>ܡ4ϮuE<Nh?ޅaKtU)4 ]RZ 뗢hvjSґ%R$+ /)D{\\L5bp/,(H<F46JSh=( :njr^=MD?BP0ޢi"w3'"sȰE>Fi>|>Q'[iIRp4 PB!ջ~兄启]W= 'L=v8rjZèl q:ΉKnhN?(2''@`E܄VUgOzf*X.'+2|tl)yXHS*{C_\3 ]%z^n~P2׋AKʂ%t<.P&BB Ir0IHO.zB8X^tJ`Wp41A>}#ͽPwJ/*Ϟ'}+%>32EHF\^fr.b=*-Jb̀%Y1Ҝ@ƌ|e5=Ö2'=~|Dvz)D&4fꗐTMč9r[` ujzv!&7!f4t..ABQ6 E#M ¨Q|)Y1>HnVPK*rtrS`3c{*FAV$R?֧T+;Vy$ bE(yMn1Ԫ1 VHgR2\6tZ)gHX襤[3=YA{ ~Z_TWn5KaD9Lj谨6Q! 2R:kkq.?n֤Q3f pu7ceP~D_B7wkd_J5B]t.lHFgL4h C5@dcd*'yZwcUM'mQfyE`((nΰz AygwFy复,}/C'`xќWЃYlE9}+])r.]4s.h7Qs`*G4|G?ZΆwj :†_4giE~*G ߲J+ 60w$}>ǧu|d+|Z/]8~*Al= Hu DZ~phqмP3 L|̍ djF[x,W-hu*9… Rй# u:f:'{ɗeZrf62'.=&N47t{F5N |_-SWr_]JWZ|Àk4*zՏNamLRTGODf\Á1Phba)džW/P{< W4[Zv]wxkpiXY#?t}PZiYP=Is>J9 E/XRA|JN[8-?ghgtލ/zFw. P qyfK 9Pt9D?S3x-yu ,w+e ŀNRRu|9Adc5ҟ6Cښx-υEg5X=amX>5N FAZi|0zpw)#!N; >58ɆC|†i"ȆCO9WMWr ~s…/[)(04C~QaDsva~qSd<h߽꾱)M+/ԳǗ|MY!T Z ^G U#HLw4ӰtLrGRBě|m|2Ǥ粨t`fph7Urzs9!x0V/{i4=L-۽6mKrm2k[䶜 IIw,,x}G蕎:R=0J;ȐDvU)ݾ!vfy>HB6ݏ[GԒsd8H* Z.&7ՓCF=:dp;'BeGA&b0 =.{- /x ċ~h3^B^HmS!8-Az"eROSz_i`rv[ps(c ,l;Zb@>}7!++'orN.:%H}7V]+Oݠ"-8RdH{[#i;lfU&o)gm 714"2;9Y$sޘ99a懚E~)7G&RKNc$T/pZ Ht#:]GuҬ 5}zLnfD7a Ǧ }a߬/`=dZlӜ faN )SkRtF\^ Xs' Kr.px+ U&VI}']|"B L?جٗS*aE܇Oh4-nlJw:Dk3,5 Xr?xkh~" 4]yι~͚\4p*TB>AbAOfj Y;coFjf mA/ =hTK De=U}(y(lpPLP^ 7AI7@5e2я9a6Y$#띜$~ϓD/<βuO?ۍEUYN7pQW_\=o(8N} I?=t]T؇J, 6ŔC51a<-xMV{PT{.1HDy-b;EAQP ( @@v(JF u06 *GmL3Lf'm8L;I}Ф3M;v?y|8HسE-$(Ի׮TCnPUM3[,:xȢRU]vb(+Zp8&JՓf<09&02;U4u^N -5eːrW1AլuuO=; : ß mL5 'Dg25nW:,B'S K5 AM I@dI0݂9.T 5Z>~ jt L\kn2M͚]Q.d94ne3aɸCV%x1i fhp=Lp#cSu:bY"0̀cOlL.d-x/=[<`c!A/T#E)h%-W'g_`\ͽ" ((Yuh"Ջ*0#g^X23Z/ L l%VLaRQ׭Waz̸b˓BǪ]La\&X%8(W3áG5o3݀W*)Ým\w-r;E0Bvk똢kL [o`Wu ܭfM6-xzL(LgSAt>mkd5m4Rpt] |W )%Z][h0XM,m#އ DIbcpT F\")骨 SJ:NOSTВ[p;l ]A&2{_@wmNZSpobD[RX)[d#maC[_'ؚ&HP1o+Al7[EŔ >}S(!2v$8@ ëUP\0Wގߝ^$r\0Q3`q( 80*tnQ0Ѐ*Jz/ƌq& BjiPt! = gqF UlScx0*s!aC` `;6XD^*Bi`ż_7aoL( ].{WrjQk%~0PfX%|(jȎ`EF^K3IW2=r }%DLNΠ5̰6;lk]h d.uкc7mJl:ـ_$roQ[exɭ*\za3^J]+YX+$  R-PGݡ@-3yj{c:(piwd`Χ%5(m x:y\׵?D3EQ`P (.fa 6:2xQVe@PmնIk|˴k}믿w7@Ҽ`9{s=۽5V6wSRX'1Gϥ2:. Ä4ֽiLݥfd3!~Zi\<݁U YY99y'VH/ˏg^8 <s2yeҁ ̼fOl#rCh/ᖁ,OLLjZBJZTv څ{95'[K ͗\M72Uw]x$m}P]0RC[ trWxum)G]aEF,| [VE X/XFI^\ϷVexePzHOm Ls X`pg#oFg =7M]`f C[E܍V̮WjrVqouptQ*b l$_^O9:aй9A2%E@OjY{t1[7auaƣf|eA^R5tdj؄N?嫎RGg#ꄚRGm o'6r7Akl51WQ2n U$:A{B;Yi`Yjڟ>>7U;,P4oRP^W-)x1R0OfE F k>&Y>X`r~~2.8tN(|2)[>gOni#-PD}KtAqD0V×^>܂ZmZ5k\o{_ZFZ(*n uQ*vUaz/a GlQk jQf-| @_ᢽjGi5ĵVx59Ws#6] Qm"& |`:4-p `3D8^joJi=R=Ӱ:/0V*E $uRQBc]) RBp!G~V.UZ9^pput8B97({&/ ZIn]F2ba'/مˏ)\+"qB<ޗC|Q9&LsJ*x"P8%doSBB52/(Vvt *Y9$[XRzWIχxIhz'9F]xؚeL1^X跺QL:R; MJJWD!] >)ÈyzQnkM}%%C('_*YS5vӠ%Qsu'T4E4vrDmd-cƁ'Z Ցh&Lֱ78}}d&נp/)׈5&˄fMRx;}oE٢%0'4VJѪbGoq q~̚;}tyY/g24#"H`peZBӼA?XSp%O/6gV$ZYWM⪩:}> [{R%Z!+erXzun/ BeH+pUTW#ٹ$ȎK uSuaPAIx(8Lֽ@p`k^lGk4B}ǃ8l`\-gĕYbYH ]<Ÿ _ſi=l@쓕 \t9f"|"lݰe!dEe`8:j<ppZk#{;dڑPB=Y1<}W.feנw1;2I[q.ՍV苾ިEK7]jJz`r&6fD.Naa'|O$f2S0cZȰy4ܼ>d,F^Pp6 <3RPz" NX%0"|z_D!mrJ۸Ƥ+m4;(&Ѳe-*䳺Ľ8w6CڅC?]o"V-zr[ipUopDs &C"YóKl ~&U; p>@#)'GZvvl ,Jl-*j+!#}9n L6zxXGyARDKR8=e|gڵs%uaq HP#A zfF5Ǝe`8B; 0dF;!MGݙZ]0C2lmRR1hΞHLiW2p9`A`&{6k`"psW{=Au>{ @ mbo?~6K֔A>Gbc޽ zbݽgp *%EKgZ}rm\kXǠk%O)'}¶}>z~,Eƒ ;WRk.O JïR|[. `)ix0u)KTo,$ bi >iLe. 4* 7 *fZw_gD>\hhe( R5&u07YBP o,Ô(3|=/;+A0:у24(EGpA^HjC۝G`"B` $4bJ8E_Hm&jMv&m% m'ZQ %[5庘zͬ,T3V/.uROW{Q7׷ɔ{HTTs7 [Gzх|^ Δ`xIyh, x^jlƉ:=.CC9 4eGmthñ"T"nqiX[bi=*.:2ooγK'Эb/8c8/؎wpcjvm'(y4i7 c=/6A;s#5Y7_} תB ~ wZTZ2Ȇx75N]V8*oZP}*nfO\ Vjě Co>5|Xӹ,y:ڟ3ZSBDQ?#yeà8%QxšBXLT3Ʌ!¸/r]'X(ǚ &+()H' 숡8b8;axo(z?I|_4qg#k3?zF1ZRKLlds} ަjO kDEϮUH0 wvrHPUu\Y#Hj8u<^z?d䚻Bݾ`:,kДMIN 9 bzN=CM'hHk+Fk4"8H:-FJ/D.Ԕ76t%x i  AsEK{[ZC=S8%ehlጳuD0ʋm;b]KH_`DF#s1ZEf$}TEqM'KApUa@6$0td}Q J*ҩKExQ7c)]Q ˩{w2lPQ3[UsH/gS$LF pLwKyAt-A~la' b ?|RCf+1@pSZ ;u&DmIh}+Z06nvUWв O@9Wdb|Q'!|EN ۄLПrB)N_ `)^4b<|/Mƌl5%-`th*Aa/P[vO@f"&xz_0UDt]=.+_W?鲗ЉdO{UJg %=/!4jSt\cKrr6 [FY㐌u$7jB#SnQg"/YUTlysP|͓(8# 8I* .`231&7lzPƠu4bڡ0!]`p,[z7aW!dnmDE-5] Itċ =v2ְsM=ikPۍёhЙz; V"QW7PBюYo X*I _d;;W* Q5oPOJ[Y-ЏZ,HmkX<bGg?fB%`GM{{wH^hKтWU$!×ݱwbU;@cTk8o{F@ 75ʠ!C+Zy=m<]3PM;+d oxЙ{BUwjW=w*1JLQڷzES` mo ߊ%wF%hWg\%`WCn5~TC7`s3IŶհEKŶLaک&GS:%j|Υ ?)hV鷇+% 2J kG %k N ?9*)Rsjr[11N '|fR,SD8:rO&VL]^WS=_KL(,fj1:wKєF 4P6hԛK5:~'+jjit~k v {:Yb́N =F0E-*klMSIa}ȲSy-֫uߢS M\e}EA*d!WC]iLjx[?уuA;=}A ѳcw  񤧇k2㄂bUջ2*mT C+V\$  mT=wqZ[|5KcghqGk^,P;1$T-V`/jZIdW-|0(K% T9&IC$U&l*fsc :ty߇)^RR } GtD'jLx~wd䤯>N"q*Ivuǁ1kВ_M.qYf<4g'7 'E`77q7K޻utRjO#dKز>Q$52?"v7^*)1^zgm& WV7FA 8Z f.nNf"6hb߈B Ë?RKE{wRo xw{$~6I#&UkC#lDnǷrʜHU K%+ۈ5#9ёqqhOf.B9lP!^V>#.WG8_!Ncyb{/%73L(܃5h$]G+=S2W>ZA-0/܇1vCN5bG?^&'O-:> rE?y^#w'[%͸0/D o큳8k4@M4Gn!KUs,d ծ¼̼N []+d⤷n"SvZXwڔ(sQZ z& 4ƹfh@bE >,&HW\82'R2GfD U*鞈DJvh"Fb(g1*p!:bЧ?v\A)^(\G0җ%meBFH(&':!.4^Sfm~ea9 \c ;6Lo?pzX҄ okblF˾'p|CAl28v$9]x0{3PN^v2+;^Xsfhũe;X4LjJpdYW!Xv~8 XXҫ&>&CF\dHoq 6FJ7duMZ4+౭-3wt ,]#KdD(ҫmPx8`Bφ/'jB"Pv k8]\ofQ?f5eH\o,N(!=a }`o9NeBl.6R`)Gr OOb1qkЪ_<5PZ%6,#SZе /= 6=p0y1_쥑 OQSGәBY:MDriܫ-e`4}-$%l"k䗉 &-Y$K9Šgݼe\qx:iTٕՍвGQ" .-CJ#vwN )v‡R"TaXTd2I&IL̒ԷT&$gN&'=-W@w}ᄏ ?7'](({+~I%Uq:ΝXR^9zkqFޅʲ2.e%WjkO*--Z~"ʪr_y%gJ.k0:K>|^|6GʿZƽVRyد/ծy}+:㇋v/)H蓞`2?TLwk{B=/ O  #ٞIs7 #B^4x|`y7]0v^0gN0>Ɓt}w puaIHjWG%A3v}8f]Aiv04 bw'xlrM(.{"ؐ`M- ?8O|{Z\`~[&=e$(-A%HۦWpZʴAgHsm{~ ;}Qav:~Xô*htKt?k\3}`t8#2f 18[]P-z]ﲏ(喖\-e+oB =.^*=]~,G !i43CӈNFaMsPLS>IZcoK8!J`![R8fjiDq+gt썓n\wP-ܳA22Bs27%  {X TХ!zXk)b78H +W?F0>~·NN0rᦑ}7.@T^E B/srWis6m\sMHE>\#eT}0;eCiV{mftlwܸ==ϛ%?3}7;zf1O.'w-FhlO[7>$F\Q9q⽶),3m E \|0>J ?x3Fv)#W[zsMeLcBnAomY`m[c}kz,m$dd,Xu\r~FUWpZJKmӢےo|AQ+ogvQ`Bɛl.-(xV+n!0=Y:0aJ\@[KEec%C#?PѠ~p_<8!NrH]E  YǸ D d)8:cQ=q|wdh]8xSottLic 0&x؆@Ok`pCϡ8If+  `r9,L*5N;DY zfD(LWrjY2%e-kjw=]ȏ :{K/X k<G3"L@ &w|21g2 C {iT8pYoq ͞EUSt8 =*X3'7=# 8rMxCGT|3M PXƭF fݫ jjU\`r+(;mpX+rĢG4|:wKm`4k q;cw{dxN@yV[ehFd6h?9lB0 8TZ}(e3Aq{, \;h Haǎg@07(:k(Fd=Ћe3NFvh2"Gp %`' .Io\^fer|ykzDn 64wH @WW\0j Θ gᔀ-(9bw:Y"M|\0k9.T@vf&?Y %'{SGSe1=dl郿[óSg@)Ao\+w9C-G^2_8@+Z|rEd.n NHyE*ΉOlnHQrd_MAW8~>$k^P9)Yn@col,ɒTYx{1,fbfK\?JY5s }:3S8f /WUxdx꭭T׫)![WQrq 8TYci!C@/9̖r,*0Oё?>u6Ud @G& v״U>rZϦk`) FlG8-B43n;Vš(f '6=4$`Q xDz kR! Zy N{94ExNr:]=5}(Hs6g!e5MP Yv:LJkIVAy!:bCAC91JITS|h$<[o3 LvzT tQoe v4Cb1,E(#+y ?'U #R41Par7fRN˄*9_S\L\AwSH2E?ʬTY>hCW\RӇ~z5 m >3C MMsw;A|*]fnRfpDCr "Uj˫"\VR"Ps7l$ī  WOT \q)_K))з);y6qdKSšKߜ*YܝF>hyWVΙwpeEF~tc~mk-,EH+ Hd9IfL`9Svk5q`.G9Cie,Jk>8mv[K&ƷU ,,Y # _B& IK'ro4qt ۠lɦ =buɉZ8N;Jzq<Ayb35C!e?(LzચoSz!>H76 B;1w kF CYMhTĞ s(~V})YC+cVn-^|tvIҧUp+c$﷞ YkT ?`N.Iu6T*i];k(JQ`HFѨjV=͸_^^V񽭼|됊Sdx ]mWtT L`7}@9D EZp8ޭED0$z*Xƨ!RjXe0 'Ƿ_U|[bc;*R"ݫ'x3u,[%s**)kwY/Z>'Y'Vւ~]IO)=CԂe6Ezh'+8.{Ua-jn>D{B^M2 M nU)DЗ|X!p9 ׅ( ?ޏR)TcpZyJV(J(dZ6^&(98`90&qxj<jZ{2a 5݅#AT%<*<6"ƶ#k<"&xQ)Sp "cC]>n͏$9zZE[2+"c** {tA 8iw?$K _Э7xu*yyhĦ>H}x;[ǬdO 48̘eVoހmjL+CM+Z#xv#eU%,fOȣ{v{R8@J˵Qa-_?ƤQC%#A?zSwStd9?yx?zY#5-qzkr-*~, }˦f&Zތw˹6sP# G]l LCd モExroAjzf$3 fxgO^ۏo-u⹔(+9@v̯,pTgو>y%^K-~,ž`g$KOC{ [w vģbW*Q'tj|ɍ<1 kWdI5w+8!' ZYG~ }-:;opA|i79Bq ~ËG/X¡™xsGA`u~ -9Ш7mz yjShV;b φ~Y,y1IV+x}45ƣ7怐n$5xDW'}ڻxnUa16>"}N]'UxXklu (<  S8ٙ<841`axwzf׋v  TJ! YHڂPj%JUj>sgmV{s+C+κER(52%HX # [ $qf`Ӣ&INJ҆NƥMVaЄihtQɤ-:1\Z҆}h# uA1$>*\&_&DY*NF{ez[[vn}ZI8sY#<+S+Z$*JIVtӃ +4t].AOCe;Kn\ #an`idRR懔M$RW5J0i, 7]DaypXuz[ =BT ~D s 5@Mm$o&oo"XJd on%y?yry#e&Ġfb6̤RHH4В< \ iBRoNϧ͎7k5DA[Cʻ |> H0/:A= c4z|L^ % 0I<|wDR׈IH{x|xC:Me!ӡ#&@Gۢ`ыM)/ p{72d a$/emu%9mp-:~by̛r+PAfLj"5ebGbmp|9g{=ɪ!A< 3Q X )u1X&wt9759Ilx(W>-qF0ODZXy>Kv"^7[ƝmKX1Gf0!G1 ݥ\o,5A?% H"\\V# uٗ"yYPEYvZq)C{J:hF Z`A^NN4)K2Dhzyy |YK ^:^~n7 7(Q6 sSe7Jq{qf:_5!-I1l##M^Z0w,w#/2LmmCF[:NЌUe t^Zf y.h}drjUf&?'ID%ݷ媜yco:OeLy^,H PeFE8viCCmU#DAUeLæu !`/j{.*S?UMe~5IỂoEaLNnFY.Oɚɇ*M$TMk):?mޕ*D],1^=B9;K7#c\ÔĜi ^/`HBvPYa+aj$NbOPA-p/n{D u aUu M]MV"AY!hqAnH͹ fxl`FK2 `̙,}˘1.t\Tz^(rIڰ&Vo S>Җ(VL9l|*BqСs-v|n/$`j.>QIϢ&) I2)O.?;? .ƇO+& 1n':]hѤeQ:w@+$Ҧ h+ZMlڔ w91<}0d*oZ[JagDZXxc~ GgG%:>θF%Zv, P]*a76V"giXYzodNDp~ .I¯ ؐzN"ZvKR 3}ᬽ7֮țX"|<$ǵ=;JkLዬlcٱRrSIQt}Lc7V2OIF8UOqK;q7&xUWitU^܀!#! `dG D$!)JPTH,)I ʬֶa]uYZe֮:,P-}.}9s훤XO$VVW6T,RWlX64U)M'<һB1d: grߪzVh^Ѝ^׫mP7 +5O&X')SX6+t>>޾!/}Z) vI-S{P4+TU$&Y=io_ݣӀxɶ w05W!L.+ K8ِ̚:}Z2l/jrʍ +B?`0E,n(t۽PLkIlS@N vPw7Il4DQFa$ݑi[&H".jif-|R"[$ݲlU 'ҝ"LTQ\C MљV\'EiDI53}#2:HyS^<z3q4i08XGcn:U`7%6g$y5BFb,]#6P89>gq S~OMo$d UBڒ8E A*U `Bछé.K\U,%'Ӡ9C%r譡$@RrY]ES%BQjwG39d7Š9uKG&J42ՏD*NAB#"*⬈LQz*٠#xd62E(V0UM cE!?(sEs ЀQ$Й=@R3#4S;zG7ՌC%G0(8뻣4] =fd-;d@*}>RtHpl?y\P-j7Wh2}/I^yZ/O nN|x6epPW"&?;O*{|j#+ud!{O]QQfQYCˀaez) Āzb~,9̦CaϘ܉'Þ/+Ffh_Â;^0e>ln)9X4S%/ݜꧽS}G&Q[>H/e%,XQQ==4hiYmFqF@]1ENfScz&4Lӽt;Ӣ/!ϴ?$3S ?gx)ixZt,lz,de2m͚縓U;fĂ;* wriKH>|>i{/έ= {33;VMf?!os^̍ ј< ζtlIܹLYɆ| X cTQ V(Ƨuc-m q ␓[-b t?Adb) #; U;/'.|6la"Y] WTqxIX y~{d!bŃaAJ]@9{4F?o"9CG\Sājm8#nϔu>IB~vWj˜k$ 4__W)(M_i{h RzĆv>xmXX5h]P[PRLh#`}DQl4pc[w,_Kn$n]MThþ4{]Ou;6yQmcjdbN]Anӂ O*t?X]s'ۈ*<}ԜCM-Inɡ [Zq[f qk.SJ*rl5S2\lA:vrnS8uI_󹝴Kn?S&>PRlrwKx[ҏahHLb e{:SS8#^qhĎ8͇$L`.$}a[Hߥ>(&m_uPh[o6coǒ(|>E*F_x0ӿHH5^#h>ݟ(1"_O#nI+3׷%Q]A5튠0~6.u,(eΞԟbbpةzhP C߬H־lLn7cu]7xG >7yRz q\,{$_\X|q2U\#Ț৆vDӺ>P^z\PסL=aE+2t~x~,|{H!׵IO=Kbcart(ggx80x8n :-mg Z*<㥖PZv<<^ tpguAt#5\&_:1~Y0hfg st|>\Hr2H%˻'['p.?ȩ+KjRiN_^iP2HN]w"CڴZo]CZ iӔ|g͸ e7X:GHG,SɍIhݺz1 +x:iXTW`ʨeP"˫ddѨ &!.`GXQ4[GA- l*PEAL3o{zKugf:33͹Kzh29{޹^cgeϦ'OGJ踄 SscE'\w/:]XRȅ'GkyutR JOOF՟.9/->½tx닁0:Jn|z<}Eor/O[t}h-Z#,/mb0z 7wo. z{WKds>RpmL"v B׬P_GNP]t8T.UmR߰P{U^[*x0: T:J]R_t,U|cs4*CGa4xàpiX.|^T&oiq:``\vpJ8ARGU3 0k`IH/No^qXpT  jVd.{R|wq?0{kqj\%#VH.VEmv\O}& U `n5@ET*N)}j!_qu=l2l0ztWxЬEcKt*JCdAa>9Ψi`ihOམ;k킳@eVA9\cyS-KL3MYSji(*T'#H M6p!G~A.&hHGr/WG+S#"} #^C:7Yѯ=%xl'tLM2p|(3?۰ QAKN!% &(?ѴD^#D˼[0\%沤PhhcXRzwI<=,AM^y7LCǽR/ㄙ7cG~q ^+:{Iͱ'zw%B;$x&$Ơn;  8~ +JÉTɁ`o_M$OЮ)X;E, 8*!=ĹUS^({׺ }/OWt@⡓E2)ӽAr˦`_9`e_q>Y!SB YH ]8ù _%~`*OND+L*L-|84)N:.mQtx ! E+(f4µi=.>oS 7oA^)~+KJyN#WP֢{8#\.#=pBi[9bAj<$[-9 oFC9u:l$l?&1b~Nj !xS'mstG\6|r#Du NQ3kd9&:ID|Ц'Pµ%u"G|nYE29oU]*Ď86A:DaKq`@;(zgv$Gx%'SWRED&iXNh>9- "]% ҦxlXKWkv¬gG{py:'Oʾԕ+:f>k2DžީoZ2p;Tx0Oo@izoM]Ry D+;VXol)s;)lu vq23o⏞۩ Xy4y c8lڛ3W=Xm{2Q_-ԗ薝*9VRz*dGq6ތP9xGK`.'xF^X5f&|r#|I^* {4N@4RǏA.bzyV +F ŽN@{5*̌U({?-ua>_V;E0Ñ}k9zZ,F_ s/a2`F{T_WLR2(ӏ@\2w=Af`E@q).sgKK\L qW9ԑ4af+i$6T::pe[PG!C* P. P.&fiI~sT^< sv%+$/"̗ w v50 Hy9 9̀hB10"K/."/n@das"hNwHijd{od[bOnӐ+"YC'sA^FsJB%x >')&:͹"^ N&ukNϊQl z%w/eFɻe@WDzJeDR6Vx,db̈́PV8LC^/ꗣeeYXqEeQ]0:^Iyx%)EEf ty&lGl(Υ/)"YFV5]_(ErlKf_M,Ȑ_oEѯVeHl;{ ^ܛ]rJαlޑ8gLARZѢTJsiPSrQw~0z-?R<Ö˥ F{SJB\}vԟ\v4@66JcyUc)we114FpgMFn?9^CED+fz0m AQOOA'"bTؚP4\bSri7bM2KLtz;tAecՎbkK10'10WDr`+NXMdByD"LRj࢐խ ȕ@&M+nN8KF|2ҿ_CJy{lRxOdi ; ]6" ox&h(= b >ae>MkJz); <9lmB2e&8m&mVJynA-zR75t#A-FIOXOf B.q9yC R!vMBA+cM ¤A>L}ye/Jt0Q!KâsX=E9}cx9BS2]Ah BDa[F3}M;D+{PfZMe5Í2&tw`wV-FvFs ȵe.JgL. Y]Mb)>URs|,L\mP5,WɬEEkjý|~[nq@kPIsRe:ũrp T ~ /Uo3O<̫OP u{r>-*z/B/5ī[% I+]7ݤ;ލEjڋ@U%6.gj>j9#!ȺQ b/B?pKV!exxXr% D}( &|&7~EmѪ¥0a^5j=syO^".oj?d 0-K,5PO!mvP6ĕ| :8:00B#T7BPjX>!:q 0C6ڦC]*Tg֓QMEO-2HZɜ!a7^IeU}Qq|YYjDF݇|KiX؏aXmֈk$s=)JJnJF_ PdoZ0I; j Dw]a}i*D5sAXk㽕wQm]̥N>!?"|"ܵF!F}})pxufa)'.ZUR=@!e]ŀP GH0ᄁVQ!xSzWFUWAᱛMťܳN+P=BFSxġu*J?uⶖE~6ϺONо^wޡ`L |~[M+ 0p`dʚnG±<ٕ/欿$~j57Au* <|4y KGu޸ 7v]`Ti~"$}+d1\1i$sI ylc:  P^2c28Bqn{b.D.u㋰w•fX5ػ -|.,)sќv4wi΋Hl;42yYW0yԐ3w"|CUmB{t7m$K҈#|d+c&kr97}BX&cRq97jd iKHP ܽ ?졌Ƅ ;;+*&..1\Y,×*TJK +->+~'2c~=MsMߑGr>n3_5J&A?ئR?xF*)<1,Ran1բ؇ӗδ&8 jkz`4!N M=F[9a!(Pp"2)OD,ȉN~T'XMw)%pnXфq ?|c5EHGKȁOsQF߯yUUhu\ 'I2/pCSX_V4FG8vka Md+7SȊ\q[Z؛ "_`IS)#!R| ?ppuM0/,='}i77OeB/vtEBSDd%|E f}b##\-w#9~l\42Nպ=`q8اz{.*F؏o-HE48gOmn1t͛#ei3F ~CBcDwI:goG-A}鲍 O&/mJi!gjLLbk iUY4~r vR¾H39fZB2i>OVa[+a=ⓑ*(jŢ'.چ,2azarܰq×ۜ{,|_fA-[tccLz{]_thAn{E_7ܫ/nUҧ_v'B7a-?)x:kPW&m0mPg#|4 Q(IL"*B":&Fy6t  tdRS5qfwjj6[5;Nvg*_?s=߹y5~ EΟ/):YITqc^()?)8z򊲪2&anWWN9}RyeEcK*Η\żsx䖔T:A9\QVIb +%zUs5m):sرCE;u ӵ '/ q&۵u^Zwޡ躷 ,'q5#\75 x|)gz{NM5obU1;U[agHb@:akڼ0$`Bu+8GuL\{CXqFA%4Y6?΢:% PĪ@ 9I7_.PR GR95^q2h _iY,!"BAiNJTX Or1[+qYX3&ų],4$`*)u>|CY3-ֹlϛ9l~5s=V&BW6T/\s^:L[j5̊Q/dy-%>ҩma[غ>Y"26p#lOdM`\;3}ꛬ27_4LP ٪d-s5"6dٕk 3MhX{Tj9;e@y%6[c~T32`ܺ#~q=蘻-Xz' Y-b-uU~޷%^"L> 4=ή:c1E&y0 _ߟG#l7{D\ ipZنC=G1AW/ ײ ] B? RRyCn>j MpÃ1psHZƏu1UU ',~mjY.d?Iޮ-QUH~ڨ%pshF锭LǕjE24U]!b؊ p=CB(ֆ i*Aq\xcak%4?ڐS5ߧ48w}vN3uصj6`h:Lcxںbcaj‚iX/£p.pKt A~L-J¤H_ʤ BʃW)*y:ga/"q621ti w¥d[c M()\|# nFȦ˖$CD.Q /#d**I%0ZW'YiJ\m AsOb7f+%:1w)XPB/ 1;{a)#lHlDo,rG0ʀ6.%l].^OR@TLd JF{ÕL_i5*0;'O/dXۣ!̤0%ɰ6)F!`H?2+cDP9-ቑi kzFZ|H%j jT[||dc쀀/9v]h Ɖ>q%)rVu4'aesP1f.T W<@8\<~Z Nũ)*Ft5\'6ӬHKD?Ot£Vآ[!$Nүd\XHF,.{SG"HՖ3%zbޫĕA22 B\QtxI?~"j4X  Cb5eR^Gx},\i} LuFZ(pjqԈ6l۶ ] n^.PӉd㈶3Rm=Kx>x-Y + s-' QRz3Uz&C^4045}/45O+uXn|( )v6D wpi]oq Ʊʗ&dPu4+_*XQrLU.Rg&JS0̔ʋkn6QdD4>Nφ"NFOs?缌*C7;PxHlcꉢ53{۸]S.vluAP;F$a>Bu;x"T;lk+2M PECVe$W2".,hPj}EU99X(2D1 ߣ:l6ײuh|uik(VC%u,>.Ah fhSA%u.K<9GgRRyPg{"> `#;,;ΓҼx2+05ȗ` @'K&^WD ,H_uyPq8> ى:z B=Y p@ڧrAl:dKF1.aF+,owvpO2`$b 6 IxKXhѢ$(UՂbp5 717~JOqh=E~ XWpT_x<RA^K10"m[D G‡mЭ0iDq}0q޷]FHn+e=D-WozMn_-ǬؖTe{ lO췈;J\I+zALsVǬV,3e1(4YM!Pa>9` *M@]Al:?HVRg@ӌC?;PK7oC3q _ߜR:Zi{0L.Hm&x0/~MfnIGg\ul#dz0=@*F}KF|&5΢M:Rzd7Ͼ?Sk+E <'EK Rk!`璃rsh RդmE;o J\2rP3`~<8Q ӷ+&rM.c920`~lB`UO=wqJbuS8/V%B5yciE z >⺬i Z:5}ӊTk|,,UA]0S!$\7 r1 M5t{<Wc?% gWC(qZ媀˥EK źˑGѣkP |l@Gx;\ E#W^\dA_x{?XǗK.RfZ$nf}ƩPDkWzU+L "?;}mSsSG/İci>2IXB_r4Mќ-Oo*lҋ&@6ϙqg`}^ <١yH1AK I>X籑t0 虜x 1;*9=%Oj~&4g5Et:.27=vqx1W}D%&/Fs6qF{jc )~hp$ axL\S RշXoRgi1U54ڳXb%>¦ČTxSZ͋YTF#?[ ~AVhRPϠoQo6IPpa1O]? @mi zfOߢ4^>UCZR~g0h)[Aolѳc>LdхSq[dFU}lעۀ:>^3v*zʬ C[BbـD L'|[[BȷbflWQ:Ÿ}k3>Vж^|n%@>_2,3n~5ϐ |4;np֘w 3cC!Zʈwǂ3J4FRZ8`raGW|q\V#s)uۛJr{'K|MEC{*؂'_:w&LǚԿx)F"@GoKI҈ǫC(qwLBC6`iAu]S"2#Q5QrQ\)Z#=H$?-^yuG 0ؔd[{f'xٴO~&of.t{-R'O4!lx B9oGC-w4`Kqӝ0 ѰS! .uqFABf>%CշK!> >{؏7>'0?X!KD>ֹ9n Kǁ,؁%2.[2љG;6-h3#xoMGkrF_byd9͜pvE!jS)ּZ +o2S1:(tY>DKNDu +lXxȨTMQpwQSt/*f:Qطt->wqcfL":ECI1UWv# <]L3ۘihXQL󠼈V =)vE3-UIͻ &qUU>Ze1X變} .y *8N I jry $ţ@51.5p)nGV{\hbϜ&sfbɊ@򛚍>Bbdjx Lu kw2 %nf8Ia =ep,gKx}l%(9P/^#(;Pz //wPuMl?Xx*dᐗ^P#MtpAW͑w ntÊD|c:pH(Y7] @uꍦсX[KXp1x&FHCk ij}0sZ..|7)t9w` 'M"686PUTDkKKA햳 d!i(@ c2W d+x\H5t{pN gFI' + -iX7$tZH̘h:y?wuTܳ$4U304$9᎖W,$D=?'vD xj/peۍ>Ab#wñ}HlWYDdB@wDCi4I~d]`!HHC]c0t:_𥂨c׷`r -u]@OFzv&>>'r6Z.[%\J7~4^[(J."WJ)Fry.:o&V*@M^\D00xTzٵ $Ư< JvUeGx:kPٕδӾP  ( >PG''̈DaFDmЍ ( 4HfJf+MRlդ&[nͦRs믁q?s=߹y׿ïZ2\ȿx1#.Gy\cJD(klDٸY׺I,+_O]%XFu2KLhgCuk"eKY/ wk8V6]xOhj8aE)Zz^Ȁm|Yhrs~/N%|W |qZ4@.YQ;&y]KRej'زfi5 `l hYzTU@EWu[B}0vY$B[;]-~좿T7E(dՏ@7Cճ@ct7 #!F6ṗl(|VD O{20eL x7[,U X ~Yo Z o'Dk&!Ÿw){2TƺH8qWz^ = ؼno>B&ɚe4-Tmf Q .5v@,_d2Vu[ 'QkoB~ټ+ypT>C7Rw .br<`5B)9"ʛ>XSo˒8!Ȋ_7{N-5q 9x} "I g*Oc6.sP*ܳ+dL#eS9蒌~"\=^ez>)@HzdRAb'T B _ӐM`-#_6 .z(fk0I`srWQ'B'k\ϫImrđ>)I٥5m.B?OZ  T-:w Ѫ͛W{A Ec4,i;%)|yB2F?޼W^'M5M3BRG32w6)\{L؞J^$Sm7JSq8TEÆ ќ\]-s##(؇eb~$TX9Tn/\R|8raޥ|=_P_NML&[ViofNa1{xe]8ehL_nY|''1tr:q*4y+>UR~Gb_ě.g7VO{V9.T@=vyu?vQ?ګwn JVl['2 =  ѐU9ç-,0@egMҐXƶHэ<P^g2yRf=E2mN  G-e ho?t\/vv VApM١MXwkѹpV|' ۽] Pb|7xcw8!CVL|ꄥxsd0R8H)@ l %X51=;t08CK@+;dObvyPypf?y/d@=iÛ M킵A~W灌+ađF"Puc͒ÁGmF ׇ"iT1HQR'zJX^Hl TNXGȿd4qq _H*]):R.y10bmWD #۳ ЭSbkE+M}1q?t ͒8M^6nJ!s4]m dG\'wKN`)#|,g &T)q\}Ɣ㡯(`דSE:HFTPK{z܄1Qlp% Z3 *a۽Hw+rC)I{NX}tI<-+V$O'#9&ƬCWSO~Y3|Ī!FwSCiQwiҁ)+79om GWǘzYaVN-04i *5MRɲ-YYue֙@6{vXa37f]9񁷓Rm 0/N NTB ''I*`VF1Z19~-b%fTdr=U- EOG7~-5OO.{,M 0P^l003edujڀ1ͩ8hz=h(v߲ٙ9i:j~Jv$O] ~[sBskQl4*À:?l@n>!Ioj" :SVBOfz h=EPYSbml٫Bq6m{X"둒9 _$:3W4i8&zaOHA|r@ɞ\H ]jHTl+ط/ƑY@wuD%JB>|/>,Uʑ9"ByW>C>@)YM5?z77.jq3.nZjqMv@_xX5c٥(?4ycEay'[@zxVR(pt[nj7*8m.]'n! 1Sst5Na0 H#_ɦ繜@d?>๬1FZ }ދ@\}z4IQbS0RS8/L7r:W*K+JBg6Sdt7JeJ}-jV`9WOsʅA5s$]ӄby cG7$ہ e_ӓpb|Go|pJ`_=]|42N0IGy`jsmPS+^JC$G9v wbzJQeFAJt"-3^zx7;qe`/V7L\t=+1#ogخǂA#ȓNȎFe*Lh  H Zs27S"jh6!g9Φ-dJurRm+PYV4dSr_Dg!cAjCz/'0[hn---\zb"=cJiGV D _Nȿ|1-iRp{o zJ%5?jB.2l2d[YڸY#oͶT* ?cyT狌˲MCn@Mc44E U >ȒH kFIJ^z IQ$5O+,C 4T&~zq-g l=z[p\kYRʝ5ϗ}ѐw,nit5mFk e\d{FN:{D,h A]rp̣Ȏ;{PſN{zyA+XjACl '7["H_KW4qm(֝Zkm{ix_}&|z/dZxK-Bu;>`X5UABۢ!0^׶rDsُ%HHU`U7HBDb{a~t,N3'`jMBÐ 4sƦ*臋p{]9-MjE%zoҪo [$iEh} i:ғ{1;$Zu?D}urQ(H-VrFήȜccmw, ^o&Gݡ4IJV22`JA'͗(6~ Ÿ+Z6lI7U RoĒY8i+r F*-c]<\ 8?|Gl8QFG 7-M=&po-FEPa~qAȚyoӃ8||xdNϑ|Hi š~=++diP))-c{th?^1"1Կ {&|dO։}|S|08 8Z 6)w:3F>Mʧ 2Iq:EJklE@jZY 7̑Dp1'ȊOLJJU@E73}uz$*j@do -CB-W֓=7˫ԟt髤&ˍod(&p{z? _~уOVk}2uX@eԔGGᰅsa/Wn y%tb2nFҶ ?8 ޳U1 ? +*F_%iͮOqWF#<n d8n9}Lšp @Gd,D#A:X, I8S1Kv;C5Q 15U1 cXƆNT;|];| /1Z<3;O0?Z'ϜOcǸAmx=S[hW šidc%)̙93NVjjcP^F-cWqMVB ]ni'ݵZZJXP  >?k_f/y.$tb^gtaG^W3C=iexTTjDnqf!~ۮJBR߶yF(}L4UZ ݊UiD~1W> 0CX=-]G9=tU Ef<&ˣCTNPH4?Z@wbhMm:KI]QBQt+A`˔\ % q. 4p+KMxNq)+P!. a]/ wrYw]\Np׉r]i[Fyd h)t'ܲ!K樫 sDǼV#=~~$' Vԫ୸xZpZ}Ӓ <<WDk{J@;wѹ6}/,5Nډ-sGD'FRI\TC@xoNvM!i-ngv~=dw9h6Fo 6>:67LxzK6Սd(W3kFE%$ȴ*J]4*ișɪ7g2$ܭ8?d/ *΅Ae{L [bn\Wʷ HͽF?{۩P?;'$So>]Gi^J8paq?%GwRKS=m6.<lkuŝQ?iQoxLW7kUx:kPٕδӾP  ( @ j4̈DaFt&3AgC7^W#4H7țLRl%I*$}um1[{k`=swy{/uٗ\˾QnḈ Op_;yEy\sO_S]=~B‚+']ɽ^x-e'7\n!pFq|՗9<;r/yG@sjUeH?~lThh fdv>oWj+N?ji|=5=_CΏsBTt|`y {ÛjbUQHPlGFבtbCwS'86n$`! -s?1bW{`H*v脟+I+}a.=~|y;&KZܰ/ "k_=lxcjp9SR5n}M —64D W! XE |2hd 壌fs҂e9VI54sW us-=ir1V%)~Es죬y\rLrMZYn2VRsbU6HT/]w^09m եNP/eIX$,m[xlq?_ARyz|k.IVf;˜)B4Q%wlS:# of5ov.I@Wg.\vU82yq5ot7)j+jaWK[Bը0vEA6:'E{+Cdf7Go/d;ՍB3Yyp7 #!F6p‡&P{R#0{%<ثA05|_ Z{beՈM &? NUKRج.s)n[uAcUj ! WoWTaHeSnq,Z#h,q3! N&4$_lJ6`KZ5B :5ܻ]q3^aH2y]vW`ׄ. "l'=;SΉF隍4;Bc5TYRzXji/ jhktF/Gl# LIXZz$ aQ4xԇB?Nt%cRȭeLfr,\΃ *{oDblFA,<:wC쐴kz.! Q;.#^T#\< 7t#K|F0)Đ#lGd"+|%L(- T룒ceV +-RXkCȳ\1\W)/\ֆ- #9bCatoOѱ/01RQL vV ~?_֯SC#:Wĭ_:W Xⶩ ƇsK\ |=>/#-|At *%nBJHo"yw ) CoT&k6GSBISP?Q(9v@"O$܍'ҡVu['1s oB~빴pmT^;C7jwbr6j<`5B#Y%YG~tO}gsjrY'Y+&ҩ:}^;oz3U$0I~)|1L޺y0fyG%2H4YF0AAH+*.q޻.|'?h-PAtaE&9ڛ$~D䭽 u .1α*"+'|*W>y|8Iwؓ#){ԒM%C()Qˡ0ცQ.F#ZuZ/6vմyazM'72m$%O^\[k&wqZ(tng4ݽN [.co*mµ4䶎cF/c.H &묷JSq8XEÆ }]ќT s# ؆%b~(9t+n/\jѥ |(ZA<-]P_%&mkԷ10ƍ^׮sy 1SIh} EM^ O @16&х33mpwL]lOlv;BJ1eh͎C[(Lî~ɕ hȪέ3L| ڷ˪Ȣtr"}GhB G(sb³l4)#"LV\s#G Ŗiw79){Wz 8mЦG,{\K|[z'2 \ܻS:e8>r9p],=kKFQoq2Rڥ Kjb CYvi`"p VvM񾈥~A嵓 /Lr o'4 6~2aHGNi9JQ {i } ᡁa 0r6ghT e3r0Xy :p`  CpUa9_]D8~JQA^ %ոuRU)udNBPglQ0#4#q WML{9ylTB bq5v; -(_͌QP,xsj.b)zQcA@,=S>c}x#r3$=>|,~ta,FH;]k2%jٙu&VA2A-=re,s4)o2\yK io[%;+rZ>Kw@Jhׄ6L곦d }&O{iۚ4uB22T3mՃdeF}%7Ղ 4pr96GxEsMպXز[~Вk*tWޣI1> u^bSPՆO?fѩd"Hhky0PZW/hra 8u D% =LJA:@wKh̉=ܶVB6P?$"p:hun_ፂ ZxfU*(jUw\Cl!*|4 T? ],=1af|oI!۰]ӿM6LRxu#yE,ka{Hᱽ=Gq FkEZh/ORC$c6? 9axj@y* MȖqVՃa9$~p l#osftO_#ꯍe 4$ʋF~]R9̌7ȖDp1ȌOLJIU@EӁ3虾HRؒ?ý7xOIa0 eXӉ* $Yޙ@G◡@Ⱥ@f] ~h =_~U1*  _Jov%e|>pgP?8j\;ǵj 4qHCTR_ĽߴYGB&蝊I͉4B*1l846whThsD)[|Q$Wx28)fx:h?D) x\[s~^ 6)I)v.:SJѤU"J Iɵ\n F=e}Q^WIo~=7=3$V" wœ|.^կ߫|g?|ojR=yD} W{pv:©SRNM7w9&3n&@¨z?«ܪZv).*s̞w3D`7ʷTr3#ͳl̕U"{~a|jo\6+*Mya=x{oʴʻBXWuib_W1oՎn'tYU ⴅ:ryӭf 44R^yH2+}S!:0H#;>٢c )yXX@4繭<69f92P ,,Zw 2> AmPWvksJn뢮᠟aW֪יlt6:&jM]b-Ry1&h 6&|j[өHܼ|tj{S %0` E@}z"lz6)9暜8msBp'A҆qne{uશRd579^[v8q2AgApWY4?|r&Dѯ`#]!UlU m*rYO`PF\mqѴ?5!-u3P='|* Byמ;[+WeeDkŦ=yUTDҠ}]uFQ{|1v6ŁhiLHkج=FS zԝْzb 2׭s @3SD)vhقB("fYWQ O̹lr^s47iGR{^nEA-ZL&pnJSVq43Dc0^*9YoI%4!q~M/.LMr;ήÉnlu"h?ΎsWMi_~WOc0'-+% XM* <=?9;{z 0GSG͓f 4+U tC[`NKX#xv_㷃i-k_}3ɦRs {A<%W7']U|rn*Hw ez%"^NnKM(o {(IFCw7X9Drp>Mh0SdI%CWb#* =vjk݈gӛDEH@[yDSBẪ 5A" !iU*z,#ynVb^Z7a-0` .&xd)Xdy81:D6L)r]t5c4*7@LvyZ *-HK\yrlwNx D XnѓClP8ܘ˧̑Oc2(j (:p0RZeFP‚QצfZ}=7AK K 00W;ۚ@&6 ۄCQO54iʁ-҂hB}IVW+UjL-Ėu.ke4s^h-(o9.wSey@;pܮж1;U._z#xwT߷u [d7GOӁtiB&o9eZ+;FV.9(˥mkՖVΞlQ ;2- myN/4Ϫ6tMXģۦo^zޜ^q ^Q߯bNˋʒ[ƟXM,XsESz9skǠa~'O? f牁(BhZ,*zuN,q՟$1N2~}7} \p% SKu6,+NoR<Ӡ ƴ 04AW -H(!``BjAcI4hT-6`zB)v#U F C QQE! zx lewh%a c[GN/9sz6宺KiО {4@?e-s.Q z*M?q?w0N&95֖w)XyZp_C Ԁ "PmZ 7+Iȋ_ H!F` 0(쥻_Zo!)˜6ފ7Hs^tDc-b zERl1-b ETR2rC4%*nR$H$:Vkjp3zvIU4XJ'dn4vX0#uR-U8t=@ ˰=H=+,@2 ]@5@$(=PƆE)CPa᰸駊|/տkf:t%%٘%іdv58Li YsQby:IfjT$Ħ)]` 0{Т~TcjD/Z&L5a_(~i`jv3,, RW/)DCybIl`-ʹwCGW]e*{Fr)xv=-.sZw$s ƶ^m~ɤ}U0 伡* cR%5TET`'W:zdjf/g $4U{uAnyy!ƖTD4.0[^pMjeϯ w.!uXX6!f!/ Z&oH1+F=$5 ʲqyZ.`cnXuJ |C&J TRa,eжta+%w1d\(-"'RY ,Agد'jfZ{` x8+s)}uF-Ʋ9Bl[Ș 6o`ul RjeU.\WN3л#lWTzm՝,.Gkb3aG޴rA8T7l&J P*9؄v9L@v? Mt$ЂuKG}T[r ظp"g #hߜHa"Y'#4Ѷ*yuˤU/ۧ ]'6/dF.*8^AKn@g\Z٨q5Ч03.`IԅS?3Yjg&ő^d  N, P 2(6ꨂG"?\NԜ5JUXi.&S)t5>'P"7|Kh)' SV ZruT&.$*=Q9\Op*7v0FQ#I"1<#Sh)45y33eO0UD3(Ac"&KORK X2աmpYOwiox!tc0[]wuJ+$H|+LYAS"J}=E>4tm$Z)HK%aqmmN*#P ?Mp\L zWӶàDAW:^r43 =vG`qs/n2Ww( 6ѾC!zVN} k$x{:\GfC/3o-_$V;x<1ilu޶ d8OX0bҤcLAg4u<@6oh>G{a4K@Θd;yUxT<2x`\cཟ&d0hXA (''P JjWOB"BE)Ũr?ʻ&}S8̽G:D ,F'xq+}~DBrq|zԆbpV%X*  m@7-298p ^yes:Xt7t߿HO0ݧ Jd 67_ }g[UtpTS߈ɞ\hq.&[e*5 9v劄W|!f}/r;#x&I%xtDCǥ?,V^m yu'|uۻ{J} 8ě#|uu'r'gLN# lHE3^!x U_R< ~ 0p%cÌغtCe}CѲK bmj2-p o(hFffַ}٧xkhw#eRݠA 3_xf 43䡣^N'ë{&wdip;Wb}AZiA$6ק83$^brҖ0%,Qxt)X? _C>eX\_DV+$$`?s]X9[cyIެM͎[N5C* UK]j<~ȥ0c$ȤR( ~`c97 s9|/T~EZm7Ek!dIچۘuGdShLc||rƸ,4^Xy_/nAuiW3h80j]EBz92}WHȈM/6~L"/(uBdvxVQyNt n:64=B6 ;I28yDHN8n DoOZ6ex-܄ƍT [=EI=2m\Z9mIo?<|L6,? b,kG뷫z5@3 ·BT/. 6O:&-')f zqkkyL>Z<0ѽ`,9,>[d@d'4pNzs^E\ |",N3|eTUU,$I0âMr$`NDL`I͙F3xBɲ&tc0=V}Xӫ0* c+?^nQ:~A|z)ȹPX|ݬ0i"Ï z^mn]J&ϐgBA4_11^,.sG049 rkm^ *[&$s: ӭaf=#x~(Z|#l,B#0?dKc;xaǸTU|LԨ gSV$;^ N#l{*_ hOҰy:|Y$N8rpL[#[x HXȡ%(#Sꨲ6BԘ !{q ʖޓK X*JXu -oPJ^׈qO`Ş:@nrɆAiQ~S gD̴.o*}ՅKrO?N~Jj󃿜~>ǻIt7[ڌj]xKt¬2y'|Ng(q/?pg0 Gg+EϪa-\OxK+E<XT)l7BUK-"|@hR${ᭋsؓF+ wWLR r@9(\~htvqi"iPrOF-'+D O(, u0<ૂzG#u=L4)gGUIIR͢"VY/"-eM5x"Q^)0w2 /4yY , ɭJ?<=낗f}p'wpZ2vS|I#J$fiRuGi+v^ I;ƖrvдвXău~ZWzDi;S!8 6xTU9,$3Z?βsNӿq ֠%4tàIi4:4qqeV3ܒXq?y!flvhB)rsݥ9͡4\,@6:8vjEsXrES3vJMr]/uVL jU-f&Xz.Td2|s&Vs˞lN ӥD$(UHBTflP2k#r 'K n ;`;~|E=YH8&#dCFG{#LV $k*=Ŏ :9;偣SC0^tsar̰GRL|oqgKj a Fmx(Ĵ,MMӰu<1Z˂uF(I>qȮը[$[lՌ: xcTJB$mG! c jbxAX] ؅ 8lK1;D6|c*g#E -\49G1Ip͚49̈)q1nF$;ຨcV8Dj;8XB`dxS<̇:E!y,+-_:8͚Dt+ Q ؐ45^Cy/$`n   >u\dEa^~b#<h<1J ðVKⶄLHf0 ~,<Ai]~eܬoD8d bE@8#V9uP]T$T)ùI%,I(EdCT`3þր# 6UƳ,VlũiؼT\Rvba!V`P1|}B? \}l?ƍ̃ۗdfhDV䄽 w͘*`aX9Xαl.Ά[ hè`4y>*S*^U$Ԓdq2( }'n ?+['Q^~xsNڤ1N{N\-6j2lIIݴh[3@[-o^҄['TCarVXFbċ%q![u.x{ O@Y/^ 04 |vf)d]\emquÛlKona`X?k\Y>R)@6F~x/^h3YɷaY Q|[ߗx5[op;HD`8Je0a5d#řITtK2-٬$ta(ͭfMn9٫2YTFNie=[,8 pvR{FI0^{N?ᵸ=_1@&~j!rsPfMAXd"]cvInm~:PM%#gv"$؋ex֎ճ< `~AEBahXMay^ZFjOx?/x)<(nLMg7ao3T `?/n [v7GG+5>ڸ7+؍^׶53 B~:) VqveGefNַs:m0^ /73l/0w /%]T|5)Fa^܆5zq1_2~}7SdCVW2yÅNuXo+oy2razi%(Wcvjj6Kℚed`9}Go'ђ.jlXdeοIM??|.Űw߈l~pd4Mx,ZMPR l6䡥%_[Z:3;d񓪕Juv\;gzޠDX.n Z=0}8'(G(l,jVGRP|XIG`4l_EN&L*^"gVҤM9p+tIu~XnO,nD҆! aR=/o ~. #/-ɻpsN_]m8a_f,53W[4`ca/(/쌅Mp&@{O0&LV@f8U 1dug爏N?/ z]iJ!:ad85Z-O*~5i_&o'Fe^\Y_na`:iP P41RtF@:xԸʧ!p [7Hiuv(2rO7dmĔ`cәU*Al0\⠋4?-Gop釹ʙCiLyˀ.( ;Ġ'/{{Rո™X'm/ 7Cjߏ)0_U.m7~:)j^嚔d``WT,'5'gN^V@c [/]W׊wAWIVWwP̔.|&gDpB; s6Ց 6?>B:o`Sow;xmNpdiWS_JSBU؎KےQHZ֗'?buVJِP23^1p .ѶNVf.o(.oF:CUo.hAFN_ۻN Wk/IP6*؜m\)F3Eml>;ۇl%j)>-10ے) 8-G'/xc7d; P|e ]`a 3ps}}9_a,yT`cy/ᣋFpctaᕍ ضPqk& ˙w`=R0 h xS ^k/fgix9I);֕BfD6=Ic ]EFH8e5M58šI1k^ 9 G.#gGah[aZ41`8=G^W: V[tml]F8y8RݾY 7׎i0q姠x+A'É#Fu`z- vXs\ߋY8; bi)^nLyvK &^$KA"6+.aKJ瓗Ӹqٱ?ſ_ K< ,G8S0fWqٞ'~?31ՠW,yO@_eOAC05"k/K,W2h'*'/y9G 2\ghם˦\`S.v|_ ``x(h>m="Yq |r^qom&væ>EE5Q*KⲠ&Ç`5K1H w ͕&ˀ0d%M<7Pk셽h.kr$<΁u^^TЯ83_Dz{%A~̲TRa<\{QS^6>BRt8'Ai)XcH8-qiu@z:0ףƊ8ۡn&.8KxlWW$S: :awr*0`\XoW# ~BA%KBв@I*!!Ix2qFU@H۳ ()%6ojxH4uG[am㖤eDK) ]Q& )̓X KZwMEz߸p7Wņq@Ow_;eCcS?e03i"րfUgհ‡U#eX= (Fs,yv- f)HSq(GKcAa4 F:(4(5si'wk`)gԯW3e+cP@| +9lM؉/cf 6"n3cYڕy ¹lp:)˕ mObĩBOzoߙCi.){dkSRli4}+0/فufϘ_ٙ|Fɼ lpvç#2 r`ߢqv \`2` 4<*!mjư4W1wg.,^vLH%R/?U)>B$!AջsԘС'lVAdMTwX\ "M\:w:C'>5JD*U?NM!Qbπi)Am8xfiVH-IpMsUC94c5]+@pctr`T[69dk>|K.|@j]7JVflUB-@jhcKUm./UzM֨t7$/P~L=\ԜLQY]\U1Y:5Us0R2e(r=pv,m88B{`:yfEG}' \[JR$݂R#DByAՋChYQ; 74e1gܜD>D8#lj\7ԵE`jM@_"wp?\0-el bp7EnΞAZmk{a;wWޣ>w3,i1o=!ߟV`;b ol c~}[EXPET4e0=FpdT煝>1L<)aW6dwx5z9X]aŅA)ťP%R`+^pQv)WN!7L(9pȀBY-EP=ÓQx5*l&0c;㿶^߾ RvAdCO6G'rpbwB )LalԚÌ1Pr,Fa `z)XaAQOO%L{Hk9<%<,KDXk\fM݉r]SD 1vK&b$m=YUHU¢bHmE ?ۛw| 㾒?NLS}q36Cd!xU^ي9\B82RS g ~8"ĝ$#CQm Tc|*-QuQ)f[L,X˙կ{H=vtչaRN/fThWt@ | y ϖ#&-jH<>ܝ.tvfn:8kv&cl:jȎzz3zVz4ZM+y'BQEk^87߬c\&2jothDXT2&ʕդ[(j~Fu0:spx$d.{RGrhs.h)ܘ+KSFOsFLƷ'S8L:FirrX߽½.xF>XE8Hf\BΗ>^ow$7K;i,ŷA~ cVnm;QzOF*ĶW AyIޮJ&g8> Uc؍Y_J>SS}$f\D1y<' H6}:+tgzQwْi~4SM,$L.#ԅXM^ Ռ)ntS쥠?&o,`Z:zqo-1; TV5A)\2=7"|c~uOd"EZa'7ҝDb }lMw#&ިkGoTX`->ЀԀec~ hS<ƏEb,tY uZ[A̯Te"[w0^"Ce+RNM/7ϛzq`W4I͏ʌ|T]l3zy&!`w{<uGSt\e>2F~ʫz ~SH +]O+Y =?pT "8 fjHng1=x yD4Tn'QIɖJ"9E/ '芨e ^TUrMkI}J>*<%syb) ?X f'"a*yYrP~> v3gQ`: &Is!B丵/:+tb41E# %!d!vfi%(`VQaXKg;1d1뜌ϝ"Rr~ GRlKozlFLX06xy8=c&? D;gM} =.et5݋$Usd6ȉ1G LF-!?BDOxmSe3h1:iUF|׶cQH* Rp"jr-^@#"bxtY@ Ů9 r8[A鍯.C'x +Q.쯕L@j1zR/ 1%ҕ1U(sfϺy{^ ri̍󸉾H&DqF Gʫ5tS0GA'ҺoH 7E~ng)'|jy6ԔږS`ʼnOM̶r~JND'RN =@mMħF_\6[67+0fQ*;.Y1oB{zj |Vk&6VR[33bU* }JF$a(⻂Tv_8 `::_QLIxBiύ" Ue=nX"FP"~*ʭ(8b+io92:x3U6??;yh.WZیm%JϱJ Zr9zq?(DG;RhM6뢊"YuiӋ)apߝ0#]JQ{޽sMNN;+m jqw ӅQ ӸeUl]QvZm~l9)%eБ֫<`\Ri:BcҿyI^P!qNn6?|_*A fn%hKK=ΕQ:ZpwT{C&eq|Su6=>-]H[|O.9|U"Bd_ӑ/qfnFP7W96k8M[]Z? mL&Q8oIEfhYc6(|vopO}trPt+z9*]?nr߽u~@E{HF.Y?Ppz>0zh/،|`XleG1_}&2O-k!x.*^Ertual Hosts","虚拟主机Vjئ?^xk8i&B'nabTȼ9o_=%ʲU1=_lN'(=bEó1Jgٵ餞MOvٓRlgk}b}HYxm_HQřu P=ERDTW؝Y7?[庛Ni-EZkJumzg@AOA]3zý|;&ƱZn9h ˷WT+9e%g#gwjdUsvh!6 ЙO)>&^]ֹ.L=zN(UٰWZ\k$!%"P`VEHtĈ 7 ~. ^ MUdhD?>Z{<-χfDt~&TsH%>Oh}'=,cN>EtV8 uyv1 9e"3CfaᤕL3tY #6@eqdGv'(TiehE, cOM>=Mar/݇>Yqzm3RK `YC)ԔѰs}l.V.c|кޅ+ ?^PD)A2T# ^2nك ==bF-=[;7O09[-z۳{6L^!֊zE N}*M"*}i2%0ٱӁ*eO'-x(v[h4$=!HB3(XCm9k܈ݽy@jAמ󋗁Iϴ#An7SdEBk9P}ʕ;|."9}yA͛F"'v)%2o,xh#{72M;́FklB<(tDhփ'#:_*(o\7! ,6gxmJP"82Zus&x~mJ1AM+Z?A*BjLo&礙]Mg<}~*OB̠*mH3>qw< ґ+cF CUn! F%=i澲G`o*Rhʠ#&"B }U2T7"VS2u2 xW<80y/DNo\Xb䤖>|&4!i@)Βe%OnGS1K#~wWxʴ  xq Dd\%h,v.ssM+%'&360KHx}ZypTGz/s! $$F71- Yފ]^i!=33o`IM|~Mt\D?V>i X%#=NNIc.2ׇΨӽjO@T>Yi-GcǬpޜ/:}w >r0e1)ܸ+WՔVͰfym 2*g;ީn߽6 eKl\rl6kˌޙjD4AE=ATS)[ma&Dt\p P:v+g!ZZ=7{VܒMjo>e2W&^}WFw+Ai!wjD[pQlts]J:إ\qr]Ot|>}LOV.ZE;E[7,t@Vd\7c`J5~egpf,|<7s?> Y71!FD ˘tJ@gnA:&"h|1~1wUQ"7<Q&\#GdA s\!*7Hv a_|?߹FvsI'\xv_e2كQ=IVf2 Rr DG\`Xmm]iM]]E-pE}%mV,ZD»kcsj]ZeaV0Ԕ:xn# ;КQ=ߪO4Rz[|3Ig:eSoT풽U&(uK_"׸k]h ҄:ViphMwVn]QʅQ:vutm]=n|Xhoޤ& !B9LaЄ6 04YjEinB]j]!vwZaS!ӗh7 >8|SϨ7p*FtP`sa`FdXEmA1m^&AB[=d>nnx{lt7Z(0ҳ@rG~_d *<)ͺVLG.df:ff)]WA:U FM[zgF؆de#2وnSEίF x]_ShƮ{x'-,X|ѩMxf";V/_o);/os;'x4S&ϲ1_n߸J7Hſڞgepups9 visj؟׬"ʀpYIbȚ,%)K߇e!D,lt#hdb`j? tIH'r/ngYLюxDϿ5m PL};f¿I׏s%Knh-pz'g \ynC*|V]`WN$[3x6~&/wNM B?Ȯ=`l;= )DQXVTHq;fDb҆H!('Qrg3O?xLl*R8HK,p+C@Quc0tG!W9jHid؅bȁ_j|ڰz F2"%'/KvVDNYQ0DL'\򲕎ݱ$IwjZv nlNq)yD™KlsSFs20@ZH!+\\cLS)##8Y8^ZwƧ/+[HDb'p W_ y>?4xXW:FkE[le9lv|Xj WAec W.LX^ w$ixU0Pʎ_E6‰asxVv Ϩ GĸX~BR#8x2?O:ԟ?:D=ph>_[C) 5LxAޒh=)URt(/նIes]@MYYv̮ DR=ڊITq2N>.GAs8}s,`s>Q+C*)ڸ%~ ے߈ckWh _$E$M.6vl\LrhqR(D\8~q n} vq@9%{`ؠz}HډOe7ȆB'8Dq2hr /"ɩH&p\j5޹[p*f/ilȈ^Ci}QG}&p^'# EuNH'w)'Dt#>Xb9V=,ض'K%C\$?K!2,KV%|//+-Hb]XUҞfC23"R͟!W\R"#2ϡ}OoØzoda|4+va"؛e3_0%^_c"2^~oƕkg1'x=~ף }C Oi+-^sp ]9KYvL2q?ĥ%Tۃj5  '$$#"y|S8n\v=G'fՕ\p:`wF?=!{SMS1D~_вhk@ga?̌ LVp,,:2@nHC mazDX|f"#%1;WŬ* 0z<o@Qr7L#IW7iaݰ3$dczCJg &9<-}OkMT/XD QCy:S z$z!Mc0P*`jAXXANiSV1 ){.-WQk.CePܣ=NLMKӔbbAW;')lQܾIxז5kMfy;{0!2[rl" ZV}#|t@B)"oK[UZwʾ4~Q鵞2Q^?k'KpCM{_ZmAWa;Y[xJ=vS8\9sFXD,N'~'CODO ߛbZ m3IBc zIv hzzs$OKJ mrXE]qu\3gL:©l1!&6ӿIcnR=ORs ʋWMMo"ԧ MgiГ7Q3EP/Wc.s ]Ø*eV#\ܒ $Ep~u|wb$Rn[=rpֲHz_E&TlݎwbTܸ4S{es r4vPc  2!Uk$)ހpxq`]X`ݙcܑB nC~uFdn){TS4 $5hD_8ΑK1}z̨?l.\}^i73ujݬ]@}:Wa/C}YkA:El8 z1"Hߢ{B$ D,YG^un1I&G)zȱ aZ}5-vGiyXUkxZB2+Np9W+בw5ZFui> fzP>@$aƑWYB^FWmo~ǞXrQl`B9H\) ,5'R#䃫b֨\ vu;TH4fwj;c]a;')Sm?|LJAxN0ݧCyHHU$ R)E 8?r H<=n8R}ό_vPT;v?譐j O7ǗՓM7޹l<6 ^LU>a5c뛄Sx^0i/R)F8_ܦI5)~ ˚/y׀ERfC hq$\ 38i^.s|aVl7 ϱIyGt`}8b &YoQaxyBq~JR^Rjb^LjVbRRjQJ4oRo`4ԖyANȧ"5`<mn,AqԁEBP>"q#4iAeOw>~qA'Qi3AbG:qӾGg]/˓8잟]7Tf(K(=qJ1yFYq FqUSٗ'a'y J PIiV_^_qK8l)Axj%$Y-qϋ^nooo/qy(Fc>g$Fc=`+ULi0.N[b1H;z{zC'?McH9- Xn~ɬL~'MDjNʉD`kHt0(( waj,n6"$䛯/$}'q5JC|Iƹ" s2z8; :×X&X+m=t ᒍ4j=Ct1-1+&b0} "JYY8Od<Ꮃ<#XYk?ʦM 3 oB;o؍6pewvorN?=Y:EKl^;Ϻ=HO^>CbBn[[[/9@xք>?9WWLywb͋I'wL47oYt*pO=vIgt@LGuebmY<#Og"3+tM h5f%Os[Jze>,s歉{DP% :>Ʊ%&,+hce5Wq0T4ݚt-9=8%x"K!.7A %`Ҝ +P$Nc%}f `kEO`AhFUMDMC'=2p2xͼ %ugvSh2 a.Nځ飌 q7RC]FJB&C&)irXxʉ'$tv'ѝ1z&8HBJ<4׬i1&r5<  _K1KA1j @O`ofG`?rE_H 2ߧ~:"uc?wb]=? (GecB06TQ7Pf5o0 9TF)R%-0viEJ1W -*?Q ɵUR \=8YerBƼFW.%i˂y< q(F&fAd ;%H"J5^-eO&~A`#\ Wz8m*VkHϳ‹幨UηO¥s{mI`TjV9Dqkdb T%NI yșE-v(dp%/Uփ2cTX I=4($ġfsLJ L|6IжADM(NbījG)ЁR^%O0:a ZZWPB@@1]L0G"cbJ$(h=H Jxj8rzr3]O8C1gbpvPUԳ;r 3mENN-~0WEϴA[t)s Uݡפ ]qa$~/pkJ-6LQ*Jy_<[Dz rGyCǒLX=5fF av YB`E#$"V"7V~Rs9jn%;Un^'X! 0vK*3kUY3JAVd4Pi" R)7qw0SXMѭn- 8GdQа`%la0B',XVb6ABQ8,:pw@s@`HPG jOѢ ϠWɰCiA 83)N^t[=Cv ApNۈsQ:9;qT4':g`0V, .ٲF20gE_pd49kjQWP!pj'iR=ўh$+MAWחp>݌icU)j"$X@/Π\ h kď>R #Ĵ@|/s6Ӝ>&?Q]ZwV:քs S Qɣ '"kYk6:@eϫr8̡G/z| k?s EkGF Ĕ-_V @.R|:=- _>}Q(MTw%Y8cC#gy VnKkںC #>cv(#O:ڕ:@Q羅~99YS|J |eI?#BQ ӆ S"V Z} Xz=UWt)^,]ctjᔊ®a}j"-Vd 2<5RH^|ɦ}ʆîua =S" 2*Dp*a'aC(pp[…d K.Lx? (`XKVϕFaP˫/ž_'[wMUIf@S$ ;P/#Br[*1ґ ~苦;V-%O&%?4͒Q2?}sdF$EGP9e R8-4%71Wσ,Qǡ.^H4I$AC)RLözoA?eQnDà!(%jdS匰:FDzj#Ώ7E]MPŪ_I-4yɵjbJ.' GB?+0#HGOj(H%-kJl9YFtELdi&8<\=dء+Ύ;h>7:F7<MÛos ^zzmkw9\P^пH@5#^ 9EȢ~1o}ݸ:j5hS[ p#o>,fM(A{9'c7'2*NˋduX=XMdOA{YSء9l8q]׫IOŊ:s2_8c7E5/I2yiOoVfޗ<Z/;`@xk>q9#f FHKOI/I-7ႋ7װ #) v`ɉE9E%%EViE%`ʼ Ĥ⒢^MM=..$+4KVg(g(** Zg4$3/\A[[AIOISI$ĢT+0 u3@rJ &m+nY^xk"sFFIۥrV!Lxk2q9#f 3.G xkĸq9#f F[M , @}rM|L' fhVɉ+qL/U09JZ1ure2^,\! 4HlrdYu2`'+ZMNS|PAxcZĒTM]qz8UoRb@y:f? rrUxTq@ BxVoTWhi -kRg5iUlKҮ!*N,K;q8 7'7$.$N8ĎvEp6y{ߗO} ey ַ?w)8̪"UMǨD1.ȑECSbMw*uZf8‰5_A(9 L=7Gd%\C^Z] auem@LQ U^d> 'D? '5R(gMfio5c61 Frk:t2Ǫg%kzr:.*e*15l>ZL.DmE x̱;*7u BL7RX-HJjyQQN7) ]ዾp)<pӮbKVUËuGi=L\:+=iN: S!u6(I[>3&i]ztpdfVt̂/. >?pXu-\j\jɊPT%>89 U#XSA׎KSӸ8Tb J11J`~@%P~AE*b "0U?ƏqNWHKQ:FW!8Vkz˸uRjl'M$ ə_RY`P^\S[;9OIB~JRUr~^^jrFpOpjQYjH3'ĤҢb`N((j ȸZ.k'u;ѯ\/ (LfX4;$M eto T4Їi=\g}wvp1uG|Cljjh4ۡS %菇6ϔޥA*îlP [qa5 nhD6W-d1z{ڃD{U !{18_΂htL|v8O޳|\0< &O}xDO_`-6Xrކ4h܏[c]4;DP͑lK:?nRf'Eh|5x̆g6NiES)jT6ұgޥAT&jxར-h?mNXI4"<:6fѸܐV4RQ[WwYΨW:HUd.-J ouիЖJ~ -1Ua[wW->8na:B,}7Dkx\z.FL4-z*\V2މx'- qH|X hjK xYBlt*P=S-9c |SRQHˣp-%(4۸USCMH[\ei3<9/6|I"sc:LFl{Y)w* |7q⾅VaZGZ.]"?*g{HׄOYT}CK]W/].e_o?㠼YROpu_P-w)p%W.&>iڔ"m.gpY"*Ys|7FAf[]SQ$}ڀ}&.mTDZs 3 ֌m4n)U3jй-5y}v5Z6Σ[;ju PgW"(]$[ ^N~|x܆*on1l pZYģ9B<̒$T,)%-ztPJ)֋~wkۄ䪺('O᷿J7bjaH6Bx()pmVœ͚:,lZ: Ӹk$#_exMJ@QjK\b{/ڊēeN܅v7`P(}p7\y|~tG{;k՟m ,ת*̭PD Q? 4RYHYC1Ʊ_*ݠKu] (Cf9ST)!Uzcᨹ7>%b 3>C֫(?HIFj'w ٥&OaWή!b9 ,d&\I@/qL}* x sԲ܉S# ,;.UUU0RPLRHJLJJ-JOIJ/.-K-Q00U02005054V02024R-JKQP5y &xuM=.ݲ< uԲ<+A* ɷYR&'v *s``hY3##6nIx /!v" \Jx{s qBbNjEj  } 7`Ted4,|,Dx]s۶r'r&9^߱k˩Oײf2 -6O) $H(;9SMKb>xvW*wtsO{x8Mgu}ۯ}Rb:Yv>Q*]'zNH4U6}q2Wh0ff>U2SxdJFarHa շ bpTQ>U rU,*TCzt$MMY|;ODrv:S]^u}XJFi~blx rY:RGWgםKuq}yqk+ `c| Ih20EII߁K>8"5,fwrJnx2S e6aB=R{l`"?bZYB]an.gxOpxpCu~2lu_؇i>$7T?}|uqy~ѾzJt_eY) -"lcx> XB&u T7K-c}x!Iej7͉-kRuM<}=؜mQ fK\LKckJLnG'#kFk6&I!mi'=k^F4_ NۋUk{ j($M?ַ}Wj`Y0@,.ׯrBjgP.rۣwzgғ'CM<ѧCf'<|p ,2BS]8B*U#2zsSr!5{|Gۻ<:^A(~ka5B~jt;׽ed103wv)ZGȰuOڿ*4OO::!yw/o/9R|O/Ԣtҿz Sћ ܅ ɺx >^cOAt=̙..R0q1u#59Iwn=wY γ 캞*=RW_uz-WKS՛UVQxS0+'UMqX,R.s(IjKa;.d8Lɲ:uaFU`jfӪڦ6'kT;)6plz[S`ĝK|Ii`eWf ~S5N3wvURT 5Cdqq5,%d |.=$89_Kn": \8[%4|Ocr*TVEۄtFTCNİQߛǑӴ&c@Ś׍(¯yEkj  >H)1*KQ #! N2C󚂅E#Iێ$^c>~@ghz!|D ˷iHINj}=!||ÀoI_~Db:?H%5nQD3 >^yqrww19?n\myThVm۟Ƴt*T"HJ iE SqxS cjxD 604D57YGsDzd!=r?Vzd»$CZ^C0|zSzÄQxe@rPe-ro.`$ I"1%$ iY,ZGKH&8KC]^a7듕Yjӭ$DevulUYmX[G:KҮf&6aLOA.M0ukt25AmYG2*5L6Hv #,h+[ Ik-2%$ Ib1%$ IKՖ ^ϩiIKQJ^cbA^ЬlN%Ry8R*aD#ѩ^s(s+;] ;]4V-XMKگk\-A-LB.9~sEm/z>d_kyɩ3fnZK,ҹ\|"2uJlJ s@=;\y/}y2.]n|Wnar*""h$К> - NC:(w}IY]-\$t@rfP#u5*,ă [ &$u|pH"kYrGq~oP'#nͼ.e^a չrK NGϭ(r  ՅRPomal5feM0x挑R?u=[_fIYj,$(AE%Q)Oce/+&;ȷ2+k9[@&, ]YVvR -c <(+V@Sfx%Gm(NUT&ꖃ2xޞ]/kh¾!e!ۊ=DzٌmIzaSq $|KMmw+U \]x M(G h -D^CB PxQoRPDgsc42-܀3y>$K4j8 `*&@@yCHO]q l^R+.iBwyo;6;yv#cn9砟h@ ?m@EV( SUfuGtlȷ%-v-V[)NК2U),ÇM  &2Hd;>uJЬ7Gzm*Ց<%,ch$lQgPdìuIm$%XvQ-#%qPF2;ɛ8d2Ƒ=zM>t8X'RPTZղ_)n`N[]ÉK,L0tF^.Ă^i!I>2->Q*HNg$ ЯD a[[JSSVes k,RDXwLi/ly~ ~DrKLJZ*ٺ ܀5ZmB>/Obw%ųߴL 4O;"pZ^wr ^ZOj&vpZ%?,9+obS4z|:+:lT4" :Dpzd8T|ȗdWѡ^uw{M:6FHD;~QIp-_t[qZܽv6Aw:DCdd.l1RNi >A$GbZ1fnS.TvިdRaasqkfd+Y{1]nV62^;04w1T{(언 kNR%Zu -w+cpK1rNznQۛJ '@&^8-%tlY /9Օ芛] %j3VJX?Tm8SfM![겆*XC~nf7DLjJ k'}~_ȼ~sJw[6<4ZJLPqun#GhEW<I<:rol5aVsZ=@Q,eY/%K,:KAaH۵ 2.مf ([ZX}Z!(29/{ ~ڜ&fi2iI.45Dq|}>.0 $M#p9 AQԴq-"ʳyˬr| ;'&"9P_bnرLF$46,QT=ܒajH9zPZ}! -,SANp%*9 )ݫqʃ1J 6 x"&uaXyM Ly:$!ǟP"c$hYM:,휢r6si^m- [9[rZ_tȗټܪdtgD*;g*<Yv YŐv\9,؞ʈոn 麷] A$M ^i]v1]|2!컸`U}T̼Cv 073Gyyo ?Gpȯ eZLOLdOLl8jU#NjuȩV9jCA]7MtET!BLvCJW &X`ICPaȯT :}K.w$Z`# _DɊ#4+A\TEHwvӆ'T ﳑꬒv}=bIq#0Ip m__pkq 6n:8I#1ux B^+4ȒJ="{Qq|RPG|JTFnù,r/rIE:EZ@Uʿ!$c<5_Y aWȷ>lzJ;$Y%c)l0a(FoW;䵪w>X=em؋++mDo["7 3\cv+B [-T̀ɒ"I@̪"`@jR($)+/j$bgzDZ8=ǵbk{;u>|͊$ExWaքi뾺yTdX/lѴ5JZEݜ<_D>'`lPjE|>em̼/`da.)Y0ZT%ѶDi( -PXJ(y,}~aDJvy-)~zL\VF6ͻAں5*[,!3rA]@VrH;lBZ1ͅk섕Wqч1>hS~Q-Fx~᭺Ù1GZ&_B5.s%sA+,,Zy9v3*d:yWX؋q̜ce?Mp˜|^g& |{ZPGFya:-.CQ>ZŔ00,oXњ& o0)0,]l1#T֚=pڶˍ p<.0p!:A&X؇ `j$NpOA ˤ3'zj"<1\4e @7jQ~\,D (&YlX3@sX& h:/D^BZb uViaJ5TVjNsZ -PժM-_86ei_kv1qRFG~VasdjSЗZP6pI0}sb +XI5Gmm v4V ,5O^[0l55~Z N*dT`Ę:of,2-ZclGn*tQ {Ղ/fŒhy5~ւf֖Q0Fh- fW #h)fma-^-Ŧk11n۰z˗o Vahzucv%5\3z)k_kAWa"5Zy oԼq 1Hd'JN6yhSKkȀ*JYހ'a*}2Ƌىwײ Ʒg'{]7QYazUb,*WW)^$ gf'->CPv2 04ٞyB_t{Ohr&S\;TE]fNerx8ǃW@PL$%.*J^ @-9N2[2%D>ц3^YcW?hZz`ZQXWa0ť+H:$d$Y''s{gN/sy ;?RSc7A w%1=#,nlQŵħRjY|"Zswٮy q2㦿<|CvJ7&L nRx9syF'+ykx]%09 Process-o2| 59 7%0 ,+8 V:@{< @N@ Z@{*<}K0!lxmL[U&a0`06H!6#`RlBRJ؆@IWmSզUuJnLkm֭Mcj]vY6Mn=m1G\{s׹~5]&湴b!t(E"#Dd|]DB3Tp=.B@*+Q zsK4>B*NS^cEY_d&,Y̯New_b"w=[>{R0%Fߊ6O' %X9ugoAc$q7yF\Q簓" <k[GrMzZ# s80`Ȣ[2S>_oIk!cs>4t3VKABNhpQ2"ݪ1KfΖa6O% JKӤ, J'bKس1{B2r@zn{e[vK\nH)ߓY3HK/Ј㠑/鞊$nuhCIs tMvdx(4 4r;G=3(-1RLETمV'ϽlQFL.8l:c;DNó1jY(Xij'(D8qb!\\1Vu]"}NNQ>:#.-Oa_# D'@a|$q3z"5nP"=sW'֣. gnUi,()yhuҭV"k |ѥp`J 1i9"mNKrgA7@-/n%9V4_fDcˣ~$/N)t1CգP;hcHWfTEGf҉VqvOOGO光LvwZٰ ֘ē`T(Re7QQ_$=Or^WPa#cp5JVyLE޸A>r?e=^+KOOˁVI㷼~fsbA 3$w<}$>{b/m>c?J; >B69K'wP"|YHT BU[hT4.)\3};lb}\w/հlR:08"\||A[ |Kb9߂T@(a Q_4NJs ρfY(¦ I?iUq~+ڥz0& OATbp?@ucy[ac-RvbJ3{#`܉D1_ z|N11?OCe H*čS 0b[1&FJr3r"zt[މZZ1 Ww2^--Ce-vtw;&7Έ(+5zupfB⇽Q"rX3wV/+SfTc[>Z. `*8-WH-į1 /0 w폩=z^<+}`eBtOEǡqUTsQJu czkJffQ5pux[7ж8^njxIT ygz>!T ~ QMJ+o4W6؝҂y%ʶ\D />i.<,x[i  EɩL| SxYkP[apyI 12`p;c , l LIINLt2nƱͤLN㙶iΏG2MI~$uN2ݳ^^`sΞՍkY7/fh63/f5G^F!a^\!ŭK$ٴwH*!]'e5r},/e#kVdmlMVkw;(#ofCa 3ʾWP(dGZvQ,TTIT8UciGxk ܒSv"[#ivޔS%W㨨^щQeHT?/Cz\xѤgf?edN)v=k7v&nJpmTL$ ED|%}˳>r^alS22zZR1rFi"& 9FNŇ$<-c c/̯I`?:"b9/'-MT R `}1Ju~]E sY$QCܹEzRDVX3Vx22-urvQ,Ԓ??+_gW&_8xDeOxv&xxV<ɭx~wY[ڄ 7eci$npEWҳO` $\&]fKh8dsB0bE KKųK_4:?`91zE)A72N̏w{Xj&;$4CRoEF`>o(C=}ch6}îx:F!ex|ܵŊk nq7 $X=%o%Cwb\Dg=~%^O@8@;5"ϼwkFkB fķպ4R6p0H;yO͛^&gEPQr`  {#(D2:\i'm@[BN,jJ| #'E, c >^[/G>À:wk`Јv1ŠFZ=A<á`i-)_3ȗt['&tQ.uj3KTFvxzI&ԁW`Wjz>Y Ϳnp ~7֤'Ǧy Z&7kO|>~[u.A={=1:xR@#q2V_4q_P?7{H͏-Py`cǸ _k)a.=U2EGPS.l<,-_i$[MZ= 9NE -ZR6X>h',Uf=.0 %(Iα,{-,qL|C1b/6Cʺl?l7Xo-!je;#ëV a{n lBzgU:l-^t ]bq`[OK5FȒ<&$*Ig\iEÎqwZʍBCzIzFmZz NR{N!Hw/͐R;VB^]") Iᮎ6|ß7:3^l>\ ~k].#`m8(-"Mc Sv 1J%Ii*2O3  R0z;D/۵t`qna#)$ z+\:;.1h|smp"e*PZM\Mxo9!? b{p 8d1'A%-DWF[KR^;t'ۀ]ZZ𥮽5xDBf;xCv)-# rE{0~CG.О[ٖ] !Kv7t )qtdbpyW6lOE^9ՄLD{n2)Rُ ƤmMDݮ156XFbᓥ3u TفV<Ͻj6q%4M^}<`x.XjшExM8)Q\-$ԫ+60& 7KũwwP_: =GQCR Nk򄀏mG8Ԁ2t6~x̺X 4DŽLqV' ?q-=T[l<8w_la'u9. sX///O;u \LEbFΑqr5emq{A2 LYE(+CS A& qƙ< mCg-`;h0TkB_*}4*%iC]#(z].rb ^wuj;"B}.YEͦnϰXE|R&|c\'@"ot)>~!-^dj y p0iWJFnv%l /r+^LϔhHޑUC#{\rӻQH~~4.1 ൣŬ% xs:&[@힄_ MBdeۉU,,ۃ7$*߽\uT][$h'ECT/H/j?LA<YXUjex1z `CZ~k<*|ǫO;#?I#mo{Nc \ gI-/0$i~`>W _nl_o ,}@޷VR(~zaֲMm`ls3B:5æ%1Kgo']lPԜ,Բ_@g h4Hs '=4-|)zkfw%ge}vj/b +2L>8ҩ"vZ?N_YJ$HBB RMWIc4p})0Xvm6gM#\bG0 ٔq&ÀsUd!j)SC0lNuF)a"/>ߣz Fn?1kJ2(xc+ ө[@Sg)`^ r̂M+$4#BEtDq Y76 rtj ;?0`ύio~#72;xmԽ#*:&O~1#ղܺ"6 ƑP0'6o6RۮBAۊ[\TԞGj,DeKj)[ "F:J@H@+[ O# ڊf63f49]BxJ|̭SGm9{i^.?4l '|w~hF?{AN~>ơ $b%]OF&o?P qedU#|>7@7,dԂ.`gk'W|7 -K.rG=*b(~-AAհH yuUZ#8fE3gCdGNm:crDfq5vi1RJ#LW.*FH}TA 3},(|:mVphR_C1oRfUdjQ9PkHF&EH1kj*]xf9F"d v¨fe٨ϬMUkJ۫s*/uآ+oZ_خܗȇmi ,4khmTDu%-|ӆl.O#}8 ]|7en0x 3vlZ՜.G}V(m_jwf3ReWaDj$l f!ȡ9,jb2lDCtdET688!@'t;ox̴iFF,fxYKsFW- ;`g7d*X& j;L-ӱs2(2 H}XIoͤqׁttoN뱫%,M_cc-|~pǚIX]T&Bf,L[`hݚtjَcO:0ǚٝg_Ժy.SSR4Wq!xa#=׌)ԓB:PNʍ~gTw> c2R{\*6 <+ ]j@@9`d@E\JK} :] s]IB19t/U2Ӷd'VIcI=!\Q<[5Ox4~{nI%Y7k ֐Iݍlltg[-;F o >g#ne6@z__<\|mVoG7;'ׯZmI)>j=CuWuhnn2]%E.l릗]o3>(=.Xqc|b%L;k{ o(}B㋖ 9Fm5,.1g3uhJ.9m"Sy9țѨc㉋R w}/֝ N %+?k*|B}[|W1 :MРbW4^MM%~ -cnTK11N yI8C_|f= ՗#u)! {%ҕ2Xp'CT^jRa?եl8Fә7N+c(5JTFVV6j#ڸ=Yu!2lwH\-b/RC^eB~7i'\5PBWY #[uU\)hwKGt©b%;ysu١]S{vE]I2 =J/Bxk>Ahz&scBBqQ|zQ~i~9X J'_dr~^N"lإ2lbP1~ PA BzQi5B!3I;Fjrُ֛0[X_QZX:YE%#8;9kePB!49(??WAK&`/.C `sSAB=B\]AH4؝Y\Zu0v19~TyXWR|x~P xtIfQr|riq <1|!'7?%D؜_lԊ!;xkyrF#/ O^9F axkyr*F#/ O^9F {MxTMkQ66DMۤiZik&4_Ș-䚣$L4MIItO&v(r`*1S WP&/(JyYAemQ q` 8,W x6+y*yB,vŴNT }0ҙQ4e q zY# 䖑Ͷsܲ^AqLahTv;t+5gKgx)iI^!ŒQ:'QP$FEfxY?J`JEGAkoZd|k p͂Ϯ(|uyQ'lBfOtw?;6yxjBM_,<]p8&愫TDr5^m#twt^X-=%fi)C(,$qV-1RXԎKJ)\n7ldTi>kw`kMI &=K}%AhhR]CC`<[ЂA CH4G)R)c4d&!zcRoV~<Ί1o,Λ'RLEʪXZjt[,!7O뮪V$?s4]F0]a/l|qu/h 3]G[{?\!vWkx߽b| ?mZkh3x<.vns| B M EE edY J''2L6ʕ)hp)AVf PFdr3|f3 qPU@yQ ~ 0~ I%E @yMk. <\\#2LFUN|- %$u!KFbqȧ 8$P%49(??(% #0y u gDG,g7,8' rjLΆ[0z$%S 83KK@ED"/I"sEndV+x;mhFu,›731piZsM "9rl@>LrlN|^YKx[jtdC>lE%)% !! ~! ~>> .n>! y umXޒm2#le$2]LX7c"NO9h}mCx[jh*F!xnS}B@Q~rjqnF f}*z1c*-M (:$13hl 3&Ad{M&rI!ax۩]}B@Q~rjqFB ( _@xROh`k56q2e]::AEFlIY4Avq5Jl͋ϳGowDnz}_2uHy{-o,cOm5Y]U>nͲtz @AIW~y>Cηe$~DF{(}oa{k 2P b ǧ0b|b) *Y!*)IELMV j^.{ \qFxz(8~?N0YRnmӠT*ZmCӂLF:{F :xpco!dE#*hmeP|Yw=hma x~`E tg۵fBrՕ\z 0cqs** -=hx۩&.R[裐X1ٞYlrswHdg^^|bo3qi*` Mg|%f5T*V`萝U+4]1c2Bf\g>ntC&pM&@b{qjBk'psLހ|9>3[y6_"]'x۩C}B@Q~rjqF6a\lJx۩C}!F6aNYxۧ[uB@Q~rjqF 0Nf 2xۧWuB@Q~rjqFn!]:l)xۧWu!Fn!'X4`xk?)6QC٠$D! 1(R5RK R CB}|4'.Pe Mh9YQgr"F0ϸW KsrBQ~qIjQiqjQBhBRIQjH(/17UG!+3ef&ei<'gRWg Mkɦ(Κ,< \kzQ~i^(&HM"% Z\ꞓ,ఘʪh=ٗd/(p L^ɪ3٘MxVY')lJ`+glr`Z]n HvU0&®9Tds.ez=K= +.]] WW`PW?gWS A'5H!* ijBf^Ijzj.`$! .n>! y@ו%hث 6,469@m`0$5PdCnuu գX^l9xk!)_Ɯ!px;)-!qsuɍ’Ee %I9 )iy%ygr~l11@xm`dm=ٚYzr3{IfE0[c-7 >x]SI E. :0hխn<޿~$@Kwfe5=ZGAH._f2eD ;+~?E2'r#IPV',iVH ;~rOYHNe:1ٔn[vVD2@ƤM$RY!dzk1N~d  [Y4W`8[)1/9@8xsz+힜;;=Ne2҂1fdQn@&#q} PƟ_$Te$KxƱ E=q`2c`xGxğ[JJwI4=џ ϟ?퉗YQfiOOmooom?_MԼ%%+'[nEtg}K:{~%rPNwO{k% A{F+R=iP~H&޷wM\ӂ1iL4 zW3O\A J,Kؼ6C 2sR\a+\,]'ys<\lZԾͼKƬMtyKs)fcG3iXzLn"M9,PRq_&Vk *i1V[ynf [xf+X]IGD tw_z &#L֑>)aM#%ܺ"2bZ Z>g0Z'T D|#aDe1[CLB5LY߁q+@Ven QAqB눴|F3?nx5FCO(/6d~Ez8j`:tRE}<=R07 4}dVt L!(:>WG #Ae53ȴn?v8ȆQ2PC/ǔ(kuctr8VIZ3|}ฤL 7t)NH!?(r=.v%T[ؿ`Ɲ^H~x@H!j:ѯ*AyE9 -R6 +g8ѻ^ &̦x?fCgg'W-N]S lvU.k0`܆@_+D`/ݠb泴b}2/ykCq'8L(78,ECRO0k q:IWQiUR LC; <~$6̍81>S7@aRUMN91Im5̞R=N7 mdAVhr1E? 1G ;݁B\:8ju,Ymr} b6:x5B8w药dԒphscFGYoD$3_xĩ]3AtԶRDm+Q wH >r'ssludިVT'Zt1Z5k&6$y4'9.akW$GvOzoGZR,Z(pAux W-읞|G+ })?uC=Ќ8!v̡$tzhD#HDR:|ۑGqn .fsPdP-֠G6|y}Y0ʈ3* kҍ@p$Ė[R~'Ϙ#ЦDh SGrh9F1s'䗙Qt͇a%3 O<.˯g`n>5ZTӬ3~#|66 Ȃ/N4kqP̓㓑 1t]b3R`ϑe[:*%>:"PG_tت@%u) GjYd7Cn:j@Gu4’*s]3'Dg yfIe9v 40 sG`>wkQ1D &1h QmO=✿PьMtu ћ/zR⚏(Wi?3*0c%E2~d`Ϛ񡍕,ΟsN`\c?wpD!138JLw3#9o Y5#{+Zpn}.g"%UYw3-zY!B}+q/~P.iO|񘙉O(7ܣ.҄6 m^_qT ?Oѻi_lPNE>픶a+W)tCC=ޅvr"+z%[Ef[-F+^S2&]qfUe ,@]G9AtS"|µm,5[KZoMknl =׊ckLkrݣtIRߨ[ݑj] <)uVoOtcz$ݕ @#{Y5_;9=0Uپk4WEG+-$ir6䁄O`.~ݻv~Gعqtf\UWF#,`Ko(m{Fn=GUM^6_3IUvAzE| arl0_ -N&8KPZJ kvxMZn-Ů;oWؚ/=8n~}Qks(cb_>^=1ӳe~U6N юk iKZ 8btY̠EPIL_[ DUzEc2r˘wU>%Z9 xsb*7iv7YK\k_Vb85CĮf 1MoF{.."CXT]41D"-vc3dܬhvGKk&p^)M[n:#\TDPKܤVD{GJLݒ҈n&UY/~fً!vϋvDЂ%nOnpUu2: MaM] Q 4wIYd+Uw,هmcW!~o;\\G DL ,ukJʗw+4YZEu .ZuW > 9݆A' ”ɵ eomRno44C9jwE΄?h,}V}G8A(xn;l 5=41Ȣn"EつȵY+)H-ݽ7G"%.Z'PF/:Y΂qE$|~[! aP|*PXR=E2ÖRz[U&/Xߦu.iɇ̅pZUT& c 6h]J!}ܵ/XX!p>, S׀hY |Z5. BV\nM[g9?b@3d |#{axP[U퇂ʝTV\Zw#g(, tjսm,{W+p Np) ӽRf-;2 fxq |dRUU rsRT( 9) I %Ey y% yy %Eyʼn%y9@eE*Mvd|LHj)S,'3 M|O)VK RR4'M<]pg<p3x;% +gd(h'gk*MW59#xtZ;x;wq#f k;4$x;ǸzsFFvl9'gpn):e oz^5N.UU0ؼ(#c#kX.BRf^qjQBf^IBNbqF)PR d$j*(qqNSTI((+(@c5'Mpٜ&US،h"!FrN YVd-$&MṶ6*!yzlt&wM֕ẚ`WWYJAI,14XAϒܰ4'V(1x[=q NLE& M6!V. f_{aBx[=xJs~AeQfzB@Q~rjqn~^*P6$#X!7?4'U+IKIMQ(W(IN +$&'($d%($$&%+$f$eKLKK-JZ?E=39;15Go$'wF1''jqMn8ٍ#j&cEX' M6!V. d_R“'/4\6Y8fMiM]M$6˙`dS vϛ3OR<Ǻ,_^wCv!9tLHyVɐʶ `Tgl<4gԔ >CBqO f)&@bTc刈E& ͉)ӺR%yQbl欮{;;۩Pf(OwoG0ìY h| p @sTY_ǧOż}aϗoE&74- YL}*Xb{5MKe%9->eRevzHgNjoEg|/Βy⍋)J[@r 1e6*c:0ƨyG(e<3(ӄt;hړ3ǚ fo0" xxlt:iXMDz@Β fR A&: `, <$zz o8g0dj8b<.I7âI[H|X=ieV_٬n<&/$1۝4!b4b+ BScrUJZI),o.u A܌EAXL'f‘oڣ6 ðH+cP2S(܀׳b(Q` Ad:sӦք,j.&?%SraR'̂-VL˲(qqz:$б:h2LoI~@+ |= i_lkCѣQ',E1T$=?pSHDayBCǟ}A}S\Ne1RR~V"ovc,?--*U+AȺ.˶T|^k1编Y>*/#0 [nn~y /229=^n,#4M{_`@PɛWt6}0N;ͦ$$s~U"7! :L<5Cg!!V`Ftr6C̱ jxr  ILcBlD^.oʧ6xí#ij6ߤSaIۯV~EBCi_?Nhvl;B9݉g, у]cH,בކ~D /Epd hu蒯~dHCX|}K*hxx`'# Xtk]vA20,wַGM|!I<[K[=k%Mi<W$QG~V|"=&2G6bvi0GF±2#&7!Yþ$k6Tv:g]e;a{Av !b8_m$|̣zƣ9W.ڽn4X)u̩c3 I-LLbQ@&&iD&P 4`G>Z # cȼ$V+ۈ&6Y L%ʰ7quu.&KDqq%bt~8{|y# XIϣ0=!.?z屃m (,A/nvbzF $dιU:p0Sg9[ؾvn 7 `;EYcWX^pE4JHx9"pGodcncGMٔj{%R|i=!WvfNİo:pi$ Ns_o]MFΆ\AcˆPNyjSgrd'yE`ITHe=$/.$Z\z S;O@e,5/Ʌ5Ez0I.dv\)%+xBYKTWK+,2O CO!\[|VIۤ5M;B2^>s灵TƛV6n; ]ZȰEByqSo5?_Ln4؎` Rz(ON.ɢ9yXڏ-˿=-iK;?/d$0WOZ^t12 H=54H̞sZ[i okԠw,76mzF13Zݵ_gڲFM7xg3s&9K\! },{pǢvdk *Jk"o]Jx:"Oz".%TR S=+a/`Cna]z7>ls2n'݈ #&I"h겏(Jv~n#C_TZ+=yk΢={|^>LkT2J&E(.Z8Z~Rmnj}UiZ]-[kOwc=f})/i'p11:n0uJ "ZcƋD9L=-\=N`R#v3vF^mvio_zOOSj];8$6 lGA8bHtY5ui#]%c\: `xru tUWJnuɒm ײ8k2ETMt)q.EInnOt{h-z㖹K(P*e833:8U׀ԓ+:*om'S(-#h9Es&vn6xOg5@6nCfp~Gy\zϥų!%)u.!-rr+ SkTdFVdtyژU:^2y۠HO̍TWN9؏(S1Aךs!ǥB*ȁ`HJu\fʛUL~$=xX`lY4ȍ.Õypz3dU X-d8rLut#  UP}J̟pvFʦq a1"7PȌJPm#'Eҿ7|Mgkfa±\vq{ *}duaU{7+bGTYj)DK PdmhGYW~Bb)1]yCwjYTra\2Hw -O׌S뙠lN.`?_Tt+qO "b2 tZū^帖`v/w]]\{[:ōs[wdƒ:&F(:!wҡboʕ"BڋU,dAx Ԓ ,{p)<\JPSsM#<uHonU6C^DaY\X_Ą<H@>2'MDZP~~;h`7K,Hg`2b|o"!blס@+ym #泷?)Id쬺N~cuz/B$LqE ]vF;Ԉϊ`#e:FNQtns-\Э*U}gXc̟ H ^d5 $Zh G!YwV$.q=وw­s=6 rDYZȨA9sFGهvr|&P..K>FyaG ,`((=ZH2"]fe 7vإR6g0ኈnRa%YI"@{.4~Fh.^v`i6 yCW(Tӛmvxwe{[驉u#bU.~ rYTˋ@lmn4 DV`YYfhoRgSF} m{Lf;6ՙ%8;Q+ #TAe߈W-EδW;4qmՉ k!7YI#};Zwa#|Nmt&毣˟^xZ[)#c"6`a`= A'z }v'"f28)cg[>b)m m(MMvv`@/ 6@~O T=PU*RwXj׫{t7>dveO%1%l3E",i/ѰpJ<\Anl7XpO;02GUJ88cGeJ`tRօ蚬Y&ZVRmaV#}q`M>-᫱`N9 /'rB;'j$xh^:5l9׶^\k7i*p^~E0;(U]lw'jtT`k^I`*'ݬxݳlWӦXTWz2Psb&8>6 TU7@prfCї y)f)^hj?^Eb gC?zi.781rNAZ M]& TR7gyqzpR+0D&(N[\&rޠDLk[tl| b &a :`xkmM. XKPyNx~qC03旪43nVNu @x~8].>: Ey%ey%: *1m6r)SA cp1ȏ[ 䀸 u'_d1Y csS9fxq ̌CO;v x2`fF!G'3O.,<)cdKmOn{_UU!J-B!7u>Ɋ.p?؛[X'/𵘬ak𰙼ףtr3|S.09h\5|Lu\ qPs7^n3yZzd 2~,xkؼqbV C S#K]C]C#C+S#+SͻYoNUc" exkغq%n~^s~AeQfzF.Q(ON-.$ahhj 5054U042025߼uQX5&=&GxkؼqC03f& CKK# ]s]cCCC+C +ͻYoNUcn jxTkoFlQCJr>>TE6!5\CPJ#!F;w\@ۛݽ zvY2Z9VΒސ+a>sGNcTBmgw..O6VjEWUB{~>T=)[>IrnI@r]7*gj+cJJUA1Y s;,IT\zZhLi r( wRD&6pT:\_^mr̙jL,`w@`s4&dAyɄ6Kz#JGmv*!.ưE! %)-8 :Mp.70)b˴;6J)#%ZB*YK'kgf)館̫tȮ2tD3ET}ot#:{mb `E? 9E#3z17iPT;slPĴF.|Ńj]+R HxWj32Gp*~nN)v}FpOʭр*l"7*jU:(ૠ-Vu ǂAvë<kk.OhbiiO'Bѽ {g{2AYH1i֕.fttҝAGfGAAk[nSkJbjA52xx[wC;N&% IPG!(?9%kے #(x[wC;N&% IRG!(?9%k Wx[wC;N&% I%ksnx[ʻw&FG0)kknx[ʻw&FG0)_ixZOH9Т:mtݽ–;9HwUE(2$ֱ6~fv\Xjui̛넭?ڢ(V>-v NvegTT%ђ=<3 }H&j'Qr2#-(MMQ4OƤa&Va8&m`~ 0],u4e6 @qXsSMxhȤc-ӜF`Pqd2]癢(cZhE ٳL!/?uO*Q:_шNJ4cqAǬ̐}@*¾ +~4k` ̘yMX CٝuP:(fR̀r~☮FM%m:wK;4 FY\|Ga-!8;8|3W''w,I{tyIԡ^rsAˣKhiY< Sh0M);؀xLF#݀Fǭ(d8M"+)]ꀢ %iBhDp,f+K$opZt3/-z,MZt֑KY?>7y9;LƶHu $ȇ& utr[{ݭ 0^,n \{DQkP֞ab9#@~{Ųm$JT.[4(sd9wR& BoؽkwX;&M|h [- YBQ7K:ׇ(tܤag5>\eM6hޠ ѩTh>ye,R/в!l2C-tdhoLg6gJfnf<&M~I8enͱ%FiT&'.EoG1y("C`2|% %_Eeڡsb{ _+pe{<EOܔ[3vƩk&Mwdq+UBYgQVj7x0$@B}۔o0(hd9E)" h nܔ)ȵ;;;4ҹ2p80 d[tB\(5 W'a pp]Pf 81?UPr;󐃫QW !IĻ@YE7'Htfl55!`; ^tp@< C{(;˒FChwa,:vj"Aש]Iʳӊ<ݲ"AtPxfha+M<~q}spO$x>'t.0y\: :l۬ mgDÙ]eA﹧C7ph!We rzt$f鐙 N%|gCE,'Ol! *0R~ c8?|Ÿ.n%ڑ]p/ Tᜆqf,D^3OAѹ쥣Kސ[^;锞^#k5C?ٛlʗ+w!z%EM/[@(OOӂxI*.+껫`XC,ݤghs۝粃F_M.u@ }M`$]Və;ix_~F>c0Q8{އ8ΑF԰ւu;~-bgx5\*IFzXaزD3]3Y (lt2pbYkQTL(FQP.6ȝ׏kW"HrKI`С[\>{D%X2XXkR>YefYoW jcIbCָ/5\)rpr8^kC\HèxTE>|H<2z1pE ze8:7m~4]mr`Y2=1ŕP4>q_xQ,#] XZ1 Wlh5 \]vW.9ν\_2kt[> 5)?1 3o;t8Pj|4*W7a3۽h}{.[QE[IvavJqj@KBq/G~&/ӧHax5)Xo;\26z܃f SZhll&|/^Or)DkR,ϒF՚v?_`rcx4=0j2Tri-Ƽ,Y:G\"YMdk<%1p@ izs{XK4|O2KA࿽m46\:%}v:޵w2 OۢUCD= :.8\fO N߅-=!dL~+q!|7U<÷Ӳ0-ʡ>\bw]} }#!N KKnsx9sC # F;e%O xuC # "FG}7 NWКU / I|Cci0 j@1% b&F}}>^B+L,8#&p&S\=`%L2a: $X"%BO QcR0%Bb< Ay:f6- YfG#2%Xm}Bpqy1.nЇQ<.cƣ`X_iH"i xP[xn,5i|׫J ^(ⅎ !ʁɑHJ7%w"_a0{ Fc')qHI^Isv;٤ozc?L Sy"[iuZ\ 1E}1l.>4F4z9@>iw,q1f_zms ?Zب۽ sB-7x܆S:FdNW LˀJ>&ե?۟MϡS mfpjv(֣inԿre($kL}myla:jNkwc箔[wmx@(B:jji@hZzu ?ZoXED<]_kWFn,ޞNN$ ag XE@d%)XV^<d&jbV:ˏJes;$\hb9tp* F㛫oܛ3[Ե(9ᅡڒ&qKg/e)HWV;2 {XjaT--MvSC35? R( 8+<*-q9Z2spM-[c-)yrjE5*Lج#-|FOw,d^ާs3O{q!>Bss&0KtaSxX%‹2o .2ttGX/PK;JB߯ܝL 7p:_a7䁉r26&&LPJ>:jp&X,x\.ih/"OY_/_Ϟ:B/1[4pBZK·ݶ^H/Sդ%"Je f'X4X&Ks4ْ`EsU VV6^+L7rNiNBD▨wgM֭c/bf:?!=¤MK0kGړ+<Д_T=)S"kkbN`v&N16Ag{N|-BTB#Y :gj d/' C%xY^3$|?9BnNyI 'GiىMدSi۹=;;\EןL6W١\[utt_A}6 Bx2m0khPZ\/fO<E Z0xIi: 9%E6 r  x24cPZ\8\ V\0x2m0cPZ\/fO<E Z0xIi: 9%E6 rzx2`2ARAA!(?9_͞L l"x24`8\ lwxk0m0hQ=R lxk0m0hQ=R xWmoI~E %ڻ=>`w_Ejf4=c!S=/,G:#cUOt{{{ۣsIRi"7҅6<D? #7b:cߜ 3Km%+PI*HBA3L%sE"2S)RBwiId>˕QEJ^pGmQmJoPFρM93RճQyB+Q 22T65jT1kbي'$;Ė .oB&҈F*O* %X] UًQ#u IuCXQa>a<[xE2]v6ԐTZ%Zq>(YrvL/;v_N bª|94b3"IWA\~r8_G#:R5_n?u4nFH2Lπk$3Pus{ozB/WLWF[~[jz_m*L ~p^1V)Y)gJ'te+q[|ay| a+p9J씙oo=8sai1`YAхwV_KZ'9LB}>%00\(Wk0(%vBb0BJY|NG3{*\o:j2lZQC)N87CE'ws&?nZ۬EUW&j X7%w:T)X/M= 퇤cU ܓM|";=I$ϭ>۞e9{[s:}Y\fѪ 4]-Q(^>E|rwA=f܅36}0>ER2VuwpG<)SWvekř z.=z1cEG69c. ab/pSɃnw,k Vu/ՓXI$d,;#ȵ3^hD<+rޞՄK\kNC) p,&G> zۊppf׌zwa\ xο'R%x.ȀԱVeo= uvI>aiJ-Mn6)V!o$n}i=3x]e #B@Q~rjqf'FF ^x]e #B@Q~rjqf'F0  x]e)#B@Q~rjqf'F o3xrAe7SqfOnv/nMxrAe#f'F~A(^An3xۮ]e)#f3FFA$i̻xZo0ҲɂaK h$H/qF{#/ͧH$w=wttpt$& "zF2 YGq=yrv~6a(i[&e&r6{_/Q.#"_~*EV*cB\wa0?Se%%,sW8P>|'6q!FDq.LZS"4^'aGS)|Gj(C0e\3Kʩ @/(%Ra 5\И49! S?w $yHGaXy2:=J0N796L6!G 3yxq#^w~dx?_Z~'^=wǗg`I*3-b7'hމ9,`ɑ !"~/(cX22ar?83BC!hFxpgE(dĻ$N3)td&CWb=}r ̽\Ah ;˧a,`F[t-ҸHӳ,OB^G9-Pz8*tlG .y,ÚyM0(j8(ձ+@3؊-4N3na2##u\v?~~엟.7WLnI|>!ŚhӒȺЩN, ,Mw<-:D+KDH7$RDQ|G糹07Br7kūfUbmk + yj+$3d W\\c9 tUd_U>[rFMY_B,I VvR xR#s{%Dm]MQK's'yoSOrZl;3V*+l&RmJTWAAQ~*pU  ey SYY{(!(D]d~pT&TYnSkCjs銛J~nCr1  Զb@P ǂ0(xt94,{ Q=lh4-3x-FylF D 6Zl葱͈5(sG=fi-7>W9i _f%bhO9Zd(*E@NzOm!ɠc g}c!ĖRb찧4]cUrՆQ'zlTbeo7PC傖J NɩnKH-O,:y٫7cgosvɔ`3%hDDvW|9#RK JM#)~rhmKWuC^]sB ŕ MqW3(Nz~x Zѯ0ĸ|}#t |dMs8^Lೆ \Hm-Os1a% -A=ox3h6:[~*@'|AFNJ"wpy(Pp5y.d\ﱅ63.QCFʠ0d21}2h(cF`$L8`hp!7lUvi4g8QlhUkW9GNܵWWYGI Il.| Lp "q( Yؔщ͏ɤ ǏJ@D_E1rJ-PBL9ŭʌ(o?3r )RIŏr#`Q5˚K ԘÙws bX|-&(dbawmϴ"#3*qlR>\8q]T{CfjɵX= U*\@K# ٍD76fwA5~V>gTc 9 r*E`̭ qPIť'BFG_Z5 K)xM))+!%\naI*[$38uo|-2 W|}SyR9n1@bOPKf=fP[tNoJv?E1Pa+EJIl7>U-`*YXH=\T<CӖ?4b%CfZf {n #SVIf?Ue %l.v6-f~nS";[g=h8ō{ Jv}LjݬŶAllo ;=3?+{6syf 7tkF5)Iil;.;侗ݏ;oKfu|!rd4 G*ZQͩ3qwˆӕ51m,aN&/p*7z1xA^,d@JUh\Ѯ* \!npIEG˖:xjəAkh=UdI`]0F62M`^OVeL'UÔmkvG0P< @Y3V҂ǨQRN+-ok*TTcLЋ- }cLeE ѝ9n=cNO)@ȩOfR7lO??;;í8L5̀ xd~B8s9nQ OARC%} A>u%?`2J#WxNиH JimC}\ŝۨYYĨSNP<KPrb- 1!NQ2zѢhnjM $P'Q@H,34~V$Q]P5sKvF'" ;Yf}+ĻӢ1˦tQh?V|~TCIN4j2yneD^ Fx[7h5Fs̓]Y'bQÚ8y ەg/0&n8ۛ9=dr o<ѓ=xOެy++&;ݬ 1q],fT# TܤԢbͲƒXet&;:pp)AIQi-wY#6OTzQPS3PLv%X9&WR^M`/CNHõxU8{yQ%Xª]u)P d ;/aaK;l|3qll6aK.@g-ۨJզ$?@N[It;,\dlgrĵF KkAD0F? U@OV+|r1b%3VmTp \!ss^J֐1 s pLgRKn"'L`P-5ȹ[kX q=+yWj!L%>u6>^6N },B[a:G<]E16S ]e{&<9O\=d'tzlv8~ܷ7lN E@o)iz>l%Gsz(\飐֨4 V]ꋿyeǘ7.w0{2i,ذ"4㻖 ~Bw6%JHnB9-qÞv~ALo^FN`V8-TIp B>Gֱ»ƒq1f%{ Э5dv\n/x*:Ut-#f;pN ȼxVkoH~RIv"%iEK<]3f$=3*R!{o t&s&\ ik2mi+GS?K2JEoD8kjt֖b.ugf--S֫t n:HшMӱ΍EǥZWk5d]Tvd1!< 3Y=vpzFPd899&Ht_xS9ÙJِ˘%=/:WSw6eB2aJ fgEɂ4Z5%gcNeD w,r{[e 6zB" A9fdz<Q|PsM[^3nÂ| ,9F(7G w>gqtN}:Qޠ}|uQ׽Vg*_Tz 6L);!s-`{F'($CXkurH5IIiӃ٭Mcj4`cwF`Ԧh*3fX|GIbBoHߍn>QNЛ<dp7CqvF3t4|ƈE-;^JR1ԌGU]DOz@ȞfGLtZIE} `8mֲ_׏0A!0b>{2&߱ɍV٬5t)ΒJF?Ɏ^1{8ޱ(R×X*|>kz@y1ijWą:ž*:.jTb/<ؖo-4_dTh gVBb{4K43:|yD=[Fr΢YumAܹfly1;pd4Kmi6gSm:&dX^geWFҖx94iL&z6O>YO,#fcmOlvUX[ߥ :l4pbpV9rZ(BJ_BDt~fQ™eAy{w=wmU/gϾgˁJo/I})q"h_{1ЄSPgUˣ\#r>\NBh~Wm`VkuHp V=ky rjGPʶ?FmnS7c<'S|zо ,x;&Fh#B@Q~rjqFͅWY Wx;&Fh#B@Q~rjqFͅWYo x;&Fh3#B@Q~rjqFͅWY9 m,x;&Ah'ͼL\ViE%S5U7d qn[x;&tTh#o( nHx[#Fh3#f$ax tgB'[qjYr~)E^^jgX)xX)g$(X*X+XXZF)(pMQ}yX5wa{7P[*Jq>q!`0p< m|tnKAgp{NG$G̱,)6ͤYP6>M}(ZACB  0uc>&eODŽ6S "sþ o.G? b걯ס0%y>>O7"o hQ|&*>o0@!BOtП[ӪTfMZVVa?1HB?mg|\0$qD*)ӛ2ԓNϩƻ r/VʓPOOjv! JvV3;8IR2[ʈ0zKnr)ȪI}g˱7br(i{.iOΡJc.v6{Q]~vltonΥ5{JZߑ~w6^iZxg %;۲咥P7usUpwo+~\Mp6n(t=EI"ęP,&R{?2L)[9PtDiF*Jdݑ(߽ )ZcI>b|M4NHɻ7hkz+ w]"w[K;E>Чo,%qk*}|xCߎ cϥ7p ?{OWVJ跓co;?p21knK߃mg gaWtONOY?tOz!]\/GD#( 2{T<E8= ;JsnC.a"&8耼aҠϑIBatͬ[A'A?Lc%4hbNAaAκlZgN]xW*?x믦^ ߬ E^p>f"2 yT=GYn{|cI&>q B2C 8^tr|};9<t L򰼵)46HTᲀL}cŶQRjv^OWG[!iPxfKlfv* g v_= ~FHhG^f0ZX 28տ{4w#bqF;nX١*py (]AtY@&.m.x&߻NR2U=X!ǽ4|;|I.z)?4?vQDGbzF-5&GujYˌdiwWy# M!d7Ϟ*O |ѫז*2Χd^YaGBuO+Eի*_9tÆ^!s-;omBmkM^ɺ4pmhkmиt 5 ̀ULh )$f^Nה )Ȑ#35[}Z#F,30,Bjb~$&-8,? |\_wQS/#DoΜSFFyj,A*wd )jE P<=GƏ V͒X}u۴&6bnz$)νbro7e.bh2zCʮr%MVTa2$l}"E Vˍ"'GGKU8'lˎ!s//*4Λ\lp< EmBBb-,'HRey"}Uw pD`9QRuD1f"R yY\!e.dU T?a^VPTA1VA5/5[1Yؠu!eZ|C[kkVu״f%/ݺ*1[ykj;Z|NUqkY>8gIkiR$1 ڛyDd=I8I/]3͙vҝ9pGS5+rdY.(N^a׵Ãx.'SA: 8MTvPS2&K&r%جǹEiq`vjNOubLy FR WÁ(,[+ٝI=n]rcӪ_76ʇl{/ѭ)* :whO .ӹ(vOĹ-BEhYDW!EhuKJlU!3pƤ;j6d[OxدZ~ݣj3vWng"qD=BFy>dh ȓ|L#9 G|}83.'!pOR-:5t-+%vR'B$[M3+]Iふ_qb e4Njǜ@6QeAΐEiK?g)latfxY3.u/dk"Щ?" [ECMO'܋OfVay\xZY`ʪd+,OPw,V\=q u]t9ϕvPF$H!ħ3EEi% &R4}qmOJ*A=(n%t$I~-߯4rv)X%-GXخj \PѦ`X7WNR 3zZl YRN삔gl .f ^iJuCx vܷ=4<6 BU*zk:^wL#5.OO8qbo+ E Tԧw/!Zc7 lC#SP,; =[[7oj], Z>} nqd3ݦG:JC"VHGȸ!}%@TD|p_t=na}Wq~QRb] ¿S+;]>9Wv@-wp)`qL' 've ^Npnh^dQ,Wֱ> i..~ x/A lű6gIl|EhxKɸxy^}pbp  Tݵ[g4Zlix;|,xF"x;w*B@Q~rjqnF f}u_`+_M|Qgy [!'5O3Jtrbx77+o`fl89Lz#bqxw*B@Q~rjqF㿌=k6W(9G !xwB@Q~rjqFv5c&(DxwB@Q~rjqF㿌=k6W(9 tx{J_KA3J(3/( >L/Y@T -ḼsR+R+T63V|CxwB@Q~rjqF㿌= Uo lkxw!Fv5!lx[wF*5=xVn"9}^^ Z&n3rA\&(2xq=;߷iu\uN]\V?T*BRs+Z> 0?R!fF{f˟5 :W7`]bed:*rЌa;]mE1%+n6?H )4WVj#mV"lָܿ3/ knE:? g2$BT2k#HBƆ3ي &b6s`f!wWxP0(J&p!A[=3c/F[/gY0g-Kf+1l+ !@\vd_ǷE?FлB x8w&zm)X(?`s13!E/re$#U $uP&XXɛ2@@:g7ؗGI#__* FTYprҌq.`lZzg2 Km^) /[QvH|Iʱ5mxЯSn9/PR/D"dJ ?no)Τڨ;FEws~g. pqE` @m]Beam@\sz5Zklg6Ԟ$,U;_WiSrVt'97>n#a N]5JO: Q3~ Cs_8͞1=K]ylig.~{ߵh"_*Yri|WE]@ zMujF-OʨFn!x{/^d'#f/FUN)`n:x{/^d'#f/FUN)^&x]mFr, TErie.زRg]U*.2%H_< 43p\Zl g{zX~nbxyדϗ׋bڬw2zuXfWlloX#/\/w/j]jG0t?eo%0ٛՒ{]lw˗lw]&[odX]n ë⥸]gΟgn>7 :AHd}z}..wKZ7-{rˎ~zq Ыj]W|<~'6(Gsgn'EWv]loӧs?j.^CZ7M\whfb#E&:zj֎2oxϾzMvݮvlݒ2.8 vI-!h(`}wQo.ue"aH] xvqmQrq[loj,],{Bxz)L.Y2r v&cnOvkNbӷeiF/2"_dŋ|_dE6{!"1 *:JZjz C9'0(PΡ }a6 mj!{0 RJ($)'@ej@}'K!U6#9rtFRﶎ&}#߭G~o)8hQ\:ZGۯnnoVk1 lj%߽կw͸L5]!SEloWo^9>}fߍNo'8X雴|!m GFX{GZ뗌mRv_d7b,PEg{{tU'U4(xQ]`IhYfo= >mB@%bn6E`%MqfHyqY]S_8mxPw%ԪBɡJ066GMIE[6G+!m@{7POM@PCF4H~* H O|HzuzEd?0QiSOMF=ɢHw?C Ӵ4=²+o $,v6tBhP |%RԆV3+6&0mZҤVl4xhZ\B N#hʵC ]IN0|m#^D }`y=N;tt_ ,/1}AOtZg۰ol*?쁜"P2+tb2BӒ&"ރ8DФ%*wKxY$}5R_;ں/deod:z)>Bz;PaSkޭ^@׫YHtkG!p}iI5T͒q8ڈff 1r 4iZ, dP)Nؗ_Ec1=ʼn x6+-i*4#i-Im{e< t4tJa>'sHސ!O ԖcD֔&w$[WJOHN1kҚ0>FNpD>A*X;8Z$au#֞TW#I1QSeD3:1 񜐦: &`X#C_IT:6a2(OGE9fYݐ>V $+T;0—##Mݚv Hڃ^pGEAS/;󤊞xOutFz>'m}yjR#`3hGe 52TK8GcM&n"lA(0E:VZGgyj$L lit3:Q@DYko`Hj'DQVWS#ҢMӂ58B奨 TuA%Dr@Hʖn vҪ ЮiFJԍ>A('5 F =JS9j$;(BN1U~j$H:BqJGMKSզ `Qb^rPF!PBM9 j&:Q OAa3R.>*>Q<68u$B=#y5ku` I"1 0Ȣ~dz>ԪKwt3:Dz4#yd{ ::N$K?$,KDݭ}ȭE@F1**SBBv)O^NDE-z1eH^c+1C C>yjj5ptQI?f=r0MKs5~=B;LOhja ±S9CE5;_RP ED?Vi0GuU<3iJmŝV)K(|?2qX7/f2%brM1tɂ5h )] )AofЛAohgPCy9PCy9ЛCo=7AӍ8n7č`F0r#XQM;GffΑ# :.9#%LΠu\N8r!Ӟr'o"TAMk#ڌѾv 3ўp6e6sCqh7G) A t*/ْ|(3W0h@c>3#i+$mf%E%#mjɺi]!Kkz#'= љq OKB It1n6i2RZV[P~OjF<xHd:8Gir+b{\D3ru\=*@]=Zc{uVlNlNO 39=C}["ksz6ksz6ksz6kszVڜڜڜVN*|N9Aг,@aN ZxDN1Of{-7;k 6k:;I@Ċa}yB1%8Dn_ G?ƱBhѵ`[XeZ'<),fʓVD.':`j(H:ݼ>hܘx=:r5JP V1(KVkG3[#Y#)b@JL)-r!r!/g  r!iZlzKP@Eb>*Fې뽗SP|TbeJ64|JrH۾u2/!GCbs/oՌ|:}b: UA,"{$Y K(څ ΑBJ/2!څFFOp[O /}"&|Y1@ΑZ^wG[T' #E%G^WO)uaSTMJcZ]d{Qͮe`Jժ1$(eCr>+u9S::ќ !ۄCQr7^+T}7XlwZ*zX"BuJR;z|:OtZ9Ij$Z݇ʧz(,m&&G8ʧ4nV0nNRxtA}|:׍V`BiBx)wbqMxt-@ PaQN,KQ/1UI(:B3[N^TTOO>TnKWM/ +~Q$i@9c B?Z`9&~[Js0=G͓x%6yiQ4@QIh®(ښ&6DԻ3ۦ+˸]9:wf\ k}|R(1 h9)NxLП7@}X_lF0DVɐcSӟ=>ʾX_eol.w~-owlgj]loWo,{}4 [lr}X^d~"?{g/eONA|ez^WEvvj',++o'5ϛ1E<˘>y-.C0Ayɟr.wHn*:wV BX^|FGf-Y^"{WK=y$WW>\-!m`XgnuS[~ >~t_W462o9;EOG'1}\QAç97ô66kϫ gr6#9k}kor-]1=[KN9'>>^9@yFTYL-mYNJH{wŠguBݝ9WN33|#StVНtFxF1+\>JgP9TΑg' Mh߳r<$ 3Pl> nzծL N|Vi]DNc7br]O#ƅ,d&`s|p2ueĊьƶ甿ӰSvh:Ђ.*4灚4cWPtS4tLd|'1ЛC:N)|JL)x+ft XPc˘Hϵ*1z4T@t8؍)(qİqZbvgO^P9M91poe`np`Kj%uML7hAP`Ni wN}a?g) 5H U}F S2üc vqe1&cJ> 휱6χ3D8g!@2,Qd +W'gtZf*,cT j` 83ߛcgl-{rCNYޜc,)غr>Q>o ާ|9؈$(^ ik(s`5$g yt2iZZ'IH5w֔6uM[7q's*a)cdzqs\sT)n  oA}Ay)^jB!wV :RX2Ma/Kad3Nz]Nt1 Ki(Z !E4=19s)]EʋhTLN(& -J.5"aK7O3`1sE_sMUK¨:^V-ÕrK׌t}zsw_Bu^ҥiztp~my;5?W3Nǖ#YGtV5,hN   1sS` v:ip.%]G-pc_<9`zH\KS~A`B3db.LD0i 7dzý>V&tB'-t4`ҍϐ]Z,=PE0X c30v0Z3%03M0tfaN:Y. 4 d ^ ~y#=WR0\6 %Ŝ;FpX ~fmgSir\lPƧQ,6Ⱥ0'= = /grቚ;oD/M!r7:J< rMe4OBN" ]σ ,Mʛ,h1ivIU4oȆFɢktNz{)9+) G\RmB(h1>㓑ǯrjM 1%ܷt$+*oWqo檎˅pUC-*l^҅Wc]NއaNXvrb@*uiG@cDoy0-(k8Gx'8XeLfO]x9fkn3%!ӊ0Ur3c~Kuy"_dK4Yc{|2_l[* }e{% էX^ѧ^'˞FϟւWαDr+τ_A Ai||&|r|pwDYo7;-A~ܾQZu۴Z_n>eߖ~ɳ# E77+J,9_^Ku{ 5brKPcsk!-qeuycnȯٳgl4 !/yk#2"3bG2/f~ş}rg7޼w?g?S곯^~oݼy_|R?{ꛛoPcܼ^ͯ|_y2/-8?՛W\/y?g߼ۛ7oCwo?MW%|ϛ_߼o~OoneB?{o~vP/ny7A굘Sn^?/Wߘӿտ/?ׯT/7OOo|/n^n77/|}o^oHO~agyݼ+e~y{#ao>GBW_o~;ՍT◿ۿկW7go7߽y)_|{,}ȉw To~; W_~Tջ¯߽ZFL&zbsi￑Mٗ_ȞJ/%_yBvwܚ{w/61I^ܽ{;ITwso߈w$vzѻwSBToͿ}r/>}zfƉOo?}zT? VH[M#[|:LFx \XJ2htU8'?1=)r̶.Nt.!#+įt1]t%pUNW9]*>\{˵\{˵ /\}\ǽe/Q)ry(w?'8#΢*vƋoJ N,ȗnNZ8tDe]t.ɮp8:bD瑢GYWJWG(zkgvkg@O}GӸy7f34S:G]nI/87/1%M\ ui0FZS.EW{;)ЕJ^IJ: +xˌ`ufQet#?aJnߩ~It>C8-%[G2hJ¬zʢ 6G!Q}-e GDj2JdrxN;;9N̯TUY/V퟇–fuG?Cq =}~zU0ItT[nY<۱uTG?]$0ЉkqY2l5|ՅO,#ԟRf]iοS9&PG)j+PJG )zt}PC4W~Pe##TxR[ .3o')O; uuGI>D&4h^JX~;r~?=I$oGr?IrPOmC]r9-#x*2}<*Ŀּzf> wAi.QQ`f; %O9G >~w9vJ|oϓ/Wכ׿KϾO/򓟼~?ݼ/ӛN|o9ӛ'? ޞAO?O߿__կͯu:_y_-?̟?+vr7?/^zwR_Ͽ/?{w?op#I~WS^~mbooVw/wj |rv_F[x_oi鍞-:_DZ1>fkpkJsQX`U3juؑ/(_MasS&M<"~ny*GexF֏̚F 9F-+y\i-R>3>3>|~WyWy}㹔ϼ̫<3j/7~[蝾+Y+z=/̻|㵽/޽zoyo/_՛߾2z/߼{oܼ{W|JoV߾~>3yԢX^.ߖ寄VƏYF͆3ەCLJe7oJTܝ#*A *y",s-ṴԾI9o_j7{ŜÅjUVL6HBY⾴(#M/(R YN x8r3 ZάBȊ mMqmVmVm/»/{X _8U>jx']n/վ  )|W{ܻ{)ܕjP-UߐxV}he N,Ҩ/q'eC?^#zNjCKwɻ]iMJwŻ]ixWZC3hsCpT+Mޕ&JwCABŻ]i-4BejE(-(-oSV}ZRjN/m3檴A:骴Bsa)KꪴBXvj)TZ]VWUiuUZ]VWhu*mJ+9sXZ]VWZP-FWUitU]F'ץuis]\6ץuis]v]Z\]}ru8{@HZr5蘭+t*!^f /*p.9${sClT*,]c&Fb x]ni].]veklw+^=_2LМ ™m @$Ĉk[Iӓ;n7co9MqS){ء \H"`A/,ّNТ3yX%M S Ǧ)ojdߔؔؔ0a b56565lalalalalalqMl[^c[^cP0m9m)h[ ڢA -Mܖhӏ!հn2@o-+::[}#pF{C&t*iWBO '\ CȈe抰L JC:ն>j랣{{<4Px\%봟NUC=*xyn.(($)36R=w"mZvf,=wNxMD_pgmf+5TGFAzN%m`ͥuNڮ=[#cq7pPS4e=C&k5YGGA->!s$n=ozC2E2B!WS{v!g)v-@eMQ8&|Tqڣ%DSP?Vx;KhF:3OMy) ũacJAs88:\J= $Xiǵ>aȑ{y9B}=ד=Oj]ȱД>rWOnzrՓ3']={ VOnMImW x; Vݻzݮaw䶛K*+}k-shlpOxYN?F$|Gk6L$vหܮwcDaB :vlwcb#BޕwE} Sy,}2cO]>I{N xN{@h|NbB4h_ *s88ƽ+qUFҸ;{aGN,7zoֆ2]x.r ۷M-$XO}+fWBO+ l'O}$;(MQّj#i.BC6ۏNԙKqѼ+GOk6U7@CsrS}il+9B 65ymG'&?,acͣ̕#4]|a4o]s\0Epd]81wW9s:uެ;]ӡ7tN? A>YQ_p;r@.1s'<΅ hq\#ꕮUp\H0jB#!S~Щ t*9iWBxlB]s:J#z^C65 z|d|#]PZ#{Ć ~{]*t\ÙX^+s)d@@*s'PገEvE$/+^DPw*^3ԏf#`_ޡn_Nĩ*(MLC%7W鶐,7[^+b=t5MZ",ih^G3RnR_J9[+@t*X-؊Yۥ!/RH݇pwkzgMB &>%Gq3p"/wH^6Js?gB.ߕJw%} ނ;*NG3}IsJIEv~Kwhd|G3Kw%軲-=[3՜lgzaJoUY,~URq NJL34Nb/Uˑ'JR*,**{zzz\ЪzCefy@۫{Jk=CWXV[ ~_g[d/o)^M6Ѣw0ك\#1dzw38M}Y/(R:ĈD;.+ߗ}P%g B?E b ĽK{./.^qlpV. _cz}OeS%dX2;ʼnGH{ P7b8b^rj^.Q{R)6g$VTaCև Ls3)in歝ssSURƮI 75nj(` n1Et[^#6 %ے4*),ۼP{숋̀L;EŗDHख़Ҧ^H%>*"7::jtȅ^oF~Edzn3eQ! LsC4}W7ꚾx]\hF$eQ8̽BJ*w+H+X[;=֧]Y:qumT:z]ww_*@׸b:c/د^M3sxS<{, RwQDǽ|eRa2sd{zWwx )Q 1^R<}pWw|խ*dw[3 Gv*`Q N6PTgObo"Cp\.'"dr]ND־78Tnyc"݀Ls EL#iCH+ f`XD ÉuGnDW Cw*~l"RWC:fx̷ElڰxuAseu\MxVStu].1T e76`~z*i.m3Iu4둭 ?.D 8ìfVj%[ uo.e:BͯVX, @(W;Ru&qi\ <Գ TQQ2'ѫZqbҴ踂mdžktl|w56ib(B_y ,w3.'Gm<5Ǐd4 |^>I <%d.J>8#  7EE& LvxG1C}\#98a8H/tjAss jK&3|)w)-Z:"eGQ|1.\j6dy\9D*}&.΍4spr^etqՎZ [0AV)qUd ZdKv2˩+E49zO=j!C^gcDblz|7C `($`m*ycxm*yC 4М9YPi^b=IצG}7Gq9J ۵[`Ҽyλ`e@T1ރ` #E4{D%2 ZniD${Z%vţa}³V"ڬUqAF́}Ϟ`>SwC$D,jny8ZP˔ȄLb֔Tn^VS cRyAbOb #z /ļhUb!A3.KʡI)奝^72G6,xaՄGs`\#m$V{ʫ8YiYRcۤC4bBꪾ #WB9}p.]堋w:~G>ez5e=1R8`O.=?&)fv(ਗ਼3!yB&si=+KMxR@*R^ip噯b!.Qp[Ɋ>g0yvT:84_!+O W% @6 )o,{Xt()iRT,\<1i 3b!Hs9!B*O >+?H1/tXHb)QRHF(u` u) |AXGv*k:ڵOŮ!v R!kb%b pkIH 9*o+1/ WvRưmB*/+ѫ9L,bަoRv^H/DWvmJ]hlv~*־SʋbXC7*䄫X{vu8:b>9$XýTL_2'fY{|$͉T۽JD'k X+%ڽJvoIck:RS㎍Ts>>!4䯞H|³Ik#;g 2ێ+EG*n(P EHw22 ]3G $76r(xH$>:#ib׻ibW`Ӫ)S&@J=CU D!MjR&B5274PXF%)L:j^&,GD($:' 3Q:F q1Joy(S be[k{*B+mxϲك]\e2o=[wǨ!Rc?0R11 !xpH/5&f*{J91U}0F&sO^Yw35MR*q:ExR&,U R axnIL &Lj>j($"Ǿ o3'1 "6/"`A+BP߳}`ፎL!~N7jz`hS.Y2\,*nJ'*f֦',2ܢҫomBzXuq1 SL!,tu?!r<[Us(^-BeTdLe J VU*TyZBx Z}a\md&飚H 3*ƞr]nR#n %H}VS#2KT3I/#ca9-He?X,H~DӀ⨻DF+H,EIѺB1(=i_оmA '?:'PxA<>R}?L֘'PNj(&4>< (u4.GSL*E*@&~ZO*J-I *P@SUB8AKLJLQMʔP{.٠X@6L -_dJmMeJ W 2O L w!)o"12n0'Rzz9 sYZ%1\b 겒"2T.< J!2 +$b"iD^dEP,X)?+)03 /2 ח W˙q%E|qW\yd叐iQžOl!jRSg Eok@%m]ӲLv$LWM*sdB@< RiRfe~JL[2Ur{h<& iw<_Md<5$`\g.A| QB0}l^x0 :^$3lV[&.Quv/TUn#wB bHQ8PС3 "3@x B4P`BL0I*g刚2f mNѨ̘3a!q hx ý4՚כd1)e%ZH/iG_{x pĔ5^uBG`ҼV%t3tRVGgY{0LꔅiLdgJeX0[>d2A1,-qU ;hbxL%IwlQ͈ (.8V":^D"nذyi N|U A K&L*q^֔0:/Hg$7 MhN'd-+AVJ] WA82"bEBE:'a0?6B{mvI޳8TGԝ-??Zk0@9$J a@^I3LV80D@X'uG@â7*itbPLP 3dGR4·e@bՆgVKJ-Jұhrs Ź KpKAU/0OUu װMzf@Gm,#}x rf$$C.BrH! $W>TSq h10(%IhY-@< 4)+'Mʸbi'^  xK44H;$.%6J u-B O 2I< \yZ9-X0H-IY0`.`tpaJ4Т:PbhRSҝ~UshWzƤ:rQĊ}dD}Q6ܣ!S@U\Vь!D tY P峉q,/p: ED\ԒW%L2fJdA[m-+$Tb (jH En}7&U>A[ #$%j3vmEQ2⩁t'Y (惓Z0?.% [Ha-G=ys(xƃ{b3K#K$%՚)Oک&%!%V_DLHi !"`$l*1{乚RRj+R!%N( :d,J@RJQ'~B+ySz=J>CыKXâkJ+5zvkJ؊#)B /~R̠:5W. )gM" /=W,%b;1V@*2ݼBj@h'0*% V)kSS] =.hȈYL-`-5,VW_S, Tu|w]j3Ҵ :r).?.GjxnǑPOMVkj@tIϛR@CMVEyjH yn)H=oYNLA2>SBso Kd u@B{qIؠhs*NѭCtNxm~~EFp1Xԡ8nzp'I-x"6{[,r1:sŞjNH|Ȁ2V) Ԑ0 \W3HsXyeI/.ds'?& M%tBJhR6jB3| aOhcҗ-5II% ۾үJSe#cJ+BcV)eA佸&7fu=/*!D23X]]?9::?љ=efx%.5<6wKO49Cb"\I"E`}6ikTM -$ى*&yI=K;BJ;)b 93 J ̙-m L#*UjV ?07P4>Hg )դ>Hg40Vmiդ>Hg%v$NtC]MʻOEP]M~zŚԅ&-:WS.g:CK3?<ŊKYU*vvnYK?;xy߸z3\4 ko|Lg%9o@otʇiT\+߬UIgX˪ 5 cpu0N{TP\MMLg`.ZƳui| ,;(!RNKu4#J}cN],2P.WQY T&ѹ;E 4E'H EΡ|f[,:A"y>L\١gJ ŜJwsU8>%&<,>_rb e`?Ѥ "3|EJg)J^Ĩ&"a(M h9ú$KL)+K`pvt'|*s"*'=%Ưҩ|7yoMgv)e ]q6sQ^z] "=XH7nB%hѤҗ"t t*]ruߟ.AF"3yt1]`bUuX|#Q]./!EojR !a%TNɋ\4=Kzk-YK3A5^b16)V)H w;? A \`p/I֋?K̤q#қ#b!޴No>ܫ]-St s3,sA"T~oNdw}z 蛺K7bT? ճ8O)VN`%}iݟ>z?D,LYgҷsL#=_C& 5 W#tR!NX=T:G# b2h71J6sP՘*N}p(Ƶn6=a7ъ>Z! M0%'!( _|H9:RR=F9@#OM#^ ,ӫ2Ÿ'Ono_{_}w_}on޽߿z٫wB'{n^y_x7f3e8LD8_%N`|3~x9+xi*VD+tIHGFl^X't6t{U4D?D׆Z-/ҁ<υQ!$%o0eʹyu )[͈›;?GLΒo9j3p73Ni' j9>Ĕ.5e[Ku!dAxWOޱ䙾4/t͊"!?g%M,z\I@ƓIMkBHoڔ⹜V0n:*biyn&UKSdx5P&C~B&3QM1H d@ֻ{!J*IؘZ C/ce$P|?{* :@_81*;%;x1tBv1w4kTuX*L*^8W6ZDL'r'jJ!Sƕȧ:ڲ$Tˬ] %&ʴ&K"ĂRHԲ`BZ!Tay(yZ JpVyjX6aҋ@߳S|C:#! QLGXmaE%d,pTa:O7 {QL%&:_ {kcqgBLh*c2|[\/K/9΅v;:\܉(Iarn,+]+M7~݇vtrv37S'6ę~%Vn@e:FNtWl/NyZyB_|>o 0V[6g:0@3-3aa614^'A.2WGNnq:<%Zso:18SxJgrLJa{c4 [팇;-vgK1R4ʸS2xF-1Zajf*,B9)I^LX#qiv UxcYt C2ŝݵt(Ijm%)$ȸN{IQ5sA zmVj"h94$FOS7I9i9߷{.&CkjDo[#SzÄ.AZ#ig!Q(t\(u84_iƨ6}+L9lzR4PÎWܬf"Xue(aL;mzlP–]#:+S C Z2Ld.]&tgxa-HǕN_f kɅ1 ,.E! QShţ45yI+H֍n$77.B*';BNbO:mե>(Zf`WR \9}U^P\nAd[O0̀k!$HLIU24-obf?I4ef_,ɩL-)d:"rU$,T%B^ 3)em5i0ySیI m6N}:2^ #f&q7!(FMXЎ apM\9ipձ+%M\)f10)L$aUuR5sP3 ILdNۥbӀŗh@mv{`iLJvQԅWSF{1os Ɗ*ӧe>#Pv")JU|].{6j$qDt6T"m(i(&љC3; 0tJ:LEGؙaSa8q8i7! ;'?qF<M,iK'N[VሚaS$ '@8R)ʀ#j "n.hzw%NUάZPFjѕ9mZF@E̓?)rȤ %Iq\\yzFJ˖x,9 >uəya)s<Tx;oD c'&H[~NT78=Sbz̀8fԟFCwinK9Ɉ<9f>($z.r4e+O+H۬8!@!!Hr.QV[ [lX^(N^SM vpmpu RGGuqG×$]~Lc|:Nݞ"RB&2<68ї )f\γ"嗘t-:iǐr!+!h^/aO5z%pObtlG :::4t{<WJ•n̋|(Z1#`C({:j] -qKC@{4g0ӧdVX^ua[f—(6AFwUR`bB룰oT\ql5}'uѥm}NœDOr R2WCBa*:E bVKAJf4BFr־G-4LC6ԦsTtLBJ8'黔ּ٥ttړY]Q Q+ n.aR{߲6 )M ^.}<1_;t,'w1&׭BS!p%^%(-$E@-p`tq>ZLk_&3a  sa()7{kz X5Σ/`%f|+15HU%yP xZMbJ׬y*Mli`OK%.VVg窄8Jg`j5Xm"n 3|. DWH,cH\CIMؖyy15+Y?b.Z:L=@>-+Ȏ^lOBʱ5IY=#@_M?IKYjfЛ!lfai`yyX^Mj9Rdt4lJl7WK<&|0K8T31Zw xxw'u W5,?׵|1E<K:!5$\i3t`ECeHX_WzuNDEgt{.|Lzσz >WhAKT6HC1y_&1!nX kC7i J}pm`B+bo 5z,[6:G5}􋬤4wdUnք |x.izwZ(XNٯ])wUg3v6_}mPj'FFh@)-ە{JV $r0%7AT'Jl,ä$#fa1:I˴k{0-. UITbu?~ \msM(AcŲṗ2 O}稣8b%̐ -{z"Cp ܏leK)}UgLT yZqmcЉ>賣KA>L`Nr: 2*%HWIG[im (pQdӄXMVT_!RgeaeA'mYA+ `i|DɳӑA])޳y@<e(:YJAEa,9k | N~g!ۋUۣ8tY8b 4boBjgKLqF(AgaUuU!K#ž3H|G@44x!} Aǟh(cF^ó }X0W G /~S W1/5髗RmNpUvH$ 93LkB񃕟<Ї])XaotX独 Δ$%nGB؟ as,E B̋Fx_$-ik"fR/(!Z+ ΋Y϶Ùxew3 >_8%R?_ɵ1P 1 |"DMfp& g˽ u1fG=ENz^+ns'v5KЏU8x|r꾃>#67p,< q+1pᡚӼnBè$0By4Rib eͺPELYU(pp n~%*KGo^0s6+醔2&*ܧR6}qpؐD,CfkzsYG!8%ޚ mye5"1 hF[E]<5v6#KJҥh ў*8}A Q)M)%4ypJ9(bKJΖQ9 c,nN'%3x QsYtz@76&sp6gKJqVٜeC>!:F?2unfMkӺi½ )% )n4=hDG)ɥI+Y+q9dA))]=#9K alN҇ur6Y]NS"md[L;'giLa3ov/ÔtU F:>K`/^ 侢8xò/9!WN4*Wz%D.:LLsJY_^VƢ3NT*;m:ۼgt w-;[v<{S*CnEgV:`Sksٵ-h"伇6pQՅ:< u`J% x[Aiǐg 'e}2ŲqY,L'"ޚas]R*bv@s [_4tw뛎u_z(_I(EʦM[pDTG҃+Н[T^]Tg{(מ-pX4@,-詘Nt`~J,_ h\xDq2>ehvřy, u&DL r6͕qHCI6]:0G"{pݓy;N-bJIvѸz/_Ø!#u#ivert>&#/ׇ^ usaT]EKf\G zeȭvOS(< "#$iD_|2 7eJ f;G~t1CKLۏh[N,䄐N9AJ,M)h8l8 +oCi:DZbղ5R'.mp8-'ڧJf HO]s(1GX)JˣmT)S::Hka[R.Y)%Ż- /rK!/]M'oږt}FDsPG.Jل kXԅZ4YE\k pJ^9{4P磼ұ3; G?q,1sRWEgGI_z('mD#}ʈ DW=nFѫfMώh1:i|k^s6"y{oOs#b>zA= q78Tס& Mh Γ * Ñ>.|eqEƚPNzl(h5Ãt;7occ}uKKL09wBM&ު fvgGu0C. :A4%\GzvxCF"'dk%UO"|=@R=_9 I"LZM#;)䇝TՐ"'9Q182h`6<1db( -;kF5MpkNl?#gT-")@Ă#tygq:AO*%ΨDFt1$5|oNC0U g!cUĄGXA:Ú@h1BLU ⢪#_HleF I˜vPdr3%J lIQu)ᦚD3X[])V#gB&ݖvOж+YjXR¾6V ZqKol{㸭=ޟbU4vfWE&  @X+ɸ |.ݵ,iƐgpxÐ\.򋯾OoO>|2yӓ-Ȏwxq ~qUu~D[➭ Ϩ˫?^<}ή޼ 8z>{ssu{vru~I* hgo.M~1g/ί~ڭOkcvmq{ꢞc;9^~vLuf?ZQekOn4 '4FW8œ`v$O j|>t 8&INBXN4ӤOv|SkZZ" L`L`<&9fN6st L=#L=#L=#L=a}$INQ)Jb~Nr43q4yd3'9fN63fN6s͜l渝c'9fN6sUw/i(ɋbq^o]^]^}oGfy#y/n/8l ѿ֑>QP7w8f8ǑJ;N]G>}[EܗҿF\:̡C~A|cQҹg;ZK#t J]&j;n,̮Wwvgu.HC:8{u~)kAhDQ(&G(ۡr+Qv :ctYYha֙j;m~]vQEչhc#uCaL2BmTŪ&UT)pt}JtǷ)q#' ǩ"vgP w*+xʟR^]z =t1Jp/BJdm8fRCR4[c.f-TkT>: P VzCl%ISÇL\wu"M|"Dco'qoFb}_UcZdIt/|i,Zܽтq1)AP:Ͱ 14gbkLVU6Zy0@w/#zSM w~"kOZCeR5[@B`0[L7:ۏ+GxJl?cQ*ZntK"J;+^ IfmhS1L~݈{QN[akrYm[ Эxz7MdD/ i'WnǙܐ>Awڽrnsҝ[ -B9.MׂpziM`#1-F$,iṭ_! iuȣ Zi1=KV17Kb-7wzXC[ƨl}O{+2>:ujt{rdy;~c=.TS& Z2ɪ$xUFRPgAZ-Vj4--¦9]SNp{b&M2:=Mztq~'m "٨AjyXWLZ^E2B3Z2&2h)(VZov1/d"R&@8֥ˢ-feNddar 3! ;$l1VnJc#1lDU`>hpOK#4=c{Q-A+lb_G߉PwK91zO0fDݙYZn9 f8Wr\fTÖA(RsOڬZ1&2 ?wxŰfjt.&2%MXrW-=+?*TAt92Ft~V{c(Te9_Ĉ֜wE%++t*Zrd4(ׇu[0Km|zo<#@j %oN-F1m޿BFH*TYM K Ov?gxy'V$>#,lW6AF|~qmqבXqB֙vIf-LBШ*/＀;#*5[I f^k>!3nd$ 5mfcᣑZ[2RITg@:2^@ߐ!nj:gƶLۏ&,&vGZ%adX?Y'P'e>31گ6Kt^Q m`B3͒/HATW5IҦ$\H#-?ԿWTw \*SPu<dOǡtgO2z?ЯPSѬm#ٿ0Q4gܑS$1B U"7@dk-§4mDҀl7)iH&ꄃ(V<\UK|#kX65 Fsk9;)3,R `eJSLVC(w*41R,s*NaVBoq*j+J+=K7)42P  SIz5i~*p5ke&x8LC_ f!KL_/Q-~b_E2mdr&fdzi8aD9>pl85x ㌟A Y&TZ^7gnk|v%ܷT 9Ⱦfbt6'PU&OU>Kw523X6W&1¯ L2 @⌧ y+/A΢ByK^%Y. UY|HojO$>[^RyY춵_ gׯ^_^]^_^\̞<9vwqsmk\9~]^ B".KӣGeh^)o~ =|f?5o_sN*.P! rs}qe_~ĘI'&tm~9ءmzk}~VyuAC* xegYQT>Ez=R[=ufN'h ՚y'.)ݐ/!}vU38 g6 L]ʥ5m_\e[tJ8z]2m_-,ը 喙ń^)CuK|.E/J]N V6%B#(&c\.%dmC_'w^[,AYCt`FTZhKkMܸň胝 㬌k_MoMK lՕsYn܂zY;7~tfZn4g2=WtLGڻNyYPU "gTF!(5WBE`0> :V^GyD9, D"b?Xd7F7Yz16ޜ2A]A}msyZBm̚-O?Zh& ̀Uj`W,1oK\e+·&d`7gW+spiU}K{S˭[j*1Υ֭uin;lsnT-s|dY{O)ԫs:+K+8֧lbdgcp`u}76_4+ף/pq,;]<N2H[띌ZXm=Rn"gQˋFOIc;bw}%wګ[mBaUV _`4dO?ZCaKɤ gK4o$8$GM~Zk Ofh70ws <8.jwr4@ &Ĵ>fb;L ~xk4roj4Lgj,d-5sϒTi>M <ߢ}@*蚈vƂ]fNEmeEr ӄhug^y̪!)tJ' j^ŅI[93F| /ɘ + 0晔6T&Tu`?L;jPPAAmhaI?":-ITL'b$.^K'Z,Qή85W}J+RKv`H@Uȃ|=%\1~cL| ֎%Mt9u۱iۣ9ev19\4455?GǦ,WS(*ƼuL$ojJn$1p^ $a4ɗ(AB߮zُ#S/iجU F-(yTk|.me22!;\]\sEa;u]/%qT5I\WR;tURO+T;q*5YF7s~‹e&&& on˘W[.y>#@2qmlAgڄy_T9D\j.֡4z7M)=D>uGs WmPVHnh'"jSAY6ħyRt֔;LXaf-,Ǹ0xRwCSXd@ [rvR=&\ <'+HȚ3d VnML#"7ܒ79ՎL)Gמt5).'L^B~wRv>'e`P6[*Mh’gSKH4 yzTŒ$P"(X˒p"U>92.H5Zk#c'Jjk`L62[8iAT`\z1e]}7JcWScX)lJʈ$Teė(mdaIƒ'ƑԦ.^`҄^W49(BvᾠeɜvzJܔXЛ|WI${AfwkGh@x&|6aUH ;n94RCG6Su0"kq)/ϖj11jq)h>)s/4r!:SVK#6jf߁ш4Y&&#3$R#JuG.9MI jQp`p\) J5Y;aVh;GprX%š>,,&MGSb R@Il.'h҈csh4qzg!jQj.ol O5CGLQz509$LLսUųP=L(H4U7 fN" ^Q8(!pF2QTSbtñIg,cg+h$ýQ#mj9Rbc;+ZPtjp@/N+ lA!`]y˭K}$'qڝ{*kcӺG]ڻ݇/ܢI֡҄RKjK^[TMpcUED# v`,UL- #bhx%1>jm8Wr$LSȃbpV;V i($<(]<ıב"y|o@`,v&ىpIur]k5:Tbܰˁs1{م 2iڰӬ xkZe%M|vФc)r[2R0m19lJέe~6o[?lgx+d63eH)ϔmMl#p٫}`?#Q0A2ͰrɈQ)ro!m 2؉*RWuLI":980#B؁ :.笮*31~Euq9v&6 EHxUeDFw-jzk L*@ ȭGUbJ) :IJ Bȋ K-yٗ!oEα(6¨]H !(s~-)9VkI͝: p"!XzxL bƔX3[{(LYéNM9G!bIpN5pC.HYT<9ufrRw@.e5Z}|n"v@W]dC,c!J#-gX*Gø k Ռ|^$ .ܚ"+_eIsT>i5vn= Mz׿s[?#i<`hwn!ٕB{RHʳGb!.ڈ&D(1H5!hL }Yds\$pˋ<5>{gq&8ipbxaC"[eaYzD b.=O@فMy#i9rDAe3XuBsGuWG"'Ϣ2а*G]D.{BX8LEF[9Ws;Ήbjm ivvtƐ#XqMgSxgP]04{Z R\SiQђKxG=obG ~`FwS߱MX6q^n%R_i߲'eBT]z#R?jE/W8Ub؍pB%0?HTy@jIj)hcڄ3,,?=pyq@ grӄpt?H^5[{5AIJ@Ucܺ^ Ѱ1xɗ_|헟~o_Ͽ~tG;'[.WI><=` ܓ˫<$Cf~qaEfKdx{w'cs9c{9#3m/gdpd xwC.Z([[G)$VV61102FfNG-xZw+lJrㇴ#qyvʒ+$I~ff%lAk|ߙY*/,7E~{:rZf<$9DA~, IHs/L 2/$1 WQqAAXbNnB . a%ϣŸ&? :(Y *RPw8/UP6 FtyEzA4wA-(1)[8Jy$krO&`B1p,4#sO&0/ LN{{} 6::71#u𗛂hVOZ=JV pB錦Q(5%`sno:ڀme(֘^BA]AhGEDF B9~~hy/Y1?o 7n(-%"V};_,<(YX|%;PVAh+,Tͳt,Ъ&ekNQ{%ݱ~iRkiȏadF[%~G#5nYݾm)*~n_U M-kBEA>"`mB4tA AcС =p@@Px 8o'j,.؊?r|$4n36FҦ+3/]Ե>a*$II˥RBbE'")o99m 9JUN22VR4",9 d[8㖥"KGLBC&R,q-U+Iqm<^sٰ1*hZbJe=ȝK6W:fXkT7Ʉx`'8W#2Kx?zWYAgR|K]!PR֞_]TӬ- Q龂32ա%ЃhlJB˼x|tF8L~BOJaϹaIƾ[9#5G<(zfS`?ѵ(^t$sQ3J}Y F)[ŁUrl -Ҧhl̩+J\KwB*SKe5H C v!VemȺe>Lޗ)`@T+SY3 (r] Va sјW,. Dk쪥B\ q|xCo?Gj722k$6h8㠪qwqKH3nA $@2@>̜uF("V4!N< #ׁ5V(|B8`_gM-4ϧoR^@Kn5]DhfPf k3Gh(Ál;smOj}Kq(8<j";ZUHE`;Xs.N@M-|HN[l'{ѱB K@X ?g~zr (xp9ϕTO휼,IQ㪧Ѝ&~;ՍH St EΑ'-0"qdҲ:EYX6}J#Kښ>kD1!X7(º)"0{b'Qbx^&˨srh\;"[8]a=;Ol -ʌ)΃ &ȡ`DP NΔC#G!xy3=aMրA.P7&f6{`~:Pv ѓ0?=)5$.Tp'tzi2櫌EE'y,pgV0^98zi{nK ^ 8MHlx%BjS{JE3hU*A_Ѻtn'rije܁׽ւ{7[-蔡/l]Dy:@8mUs>G+/T\+ng ¶iaMv r4+oq4az~ݫ/ޜӛGem«]^ìОɴ(W7rV8 ͌.MuR3;&6M҄Yc%drIE seA)˩lq^dKe@d4iŬIBFZuS绐5$nn[vpNw|'%[";O᥮_@-n:?D R|7D;AsΗ!`eT速rmA>tĖ.IR2v۾ JKd^VnxI?ٞ1K ϔ\J㝯"S__#8sٵ{H&P86$X|IH4h}GY;_K@(*D^@F@2آx-/&@ҕމ?Pzp('p vMh[O"^'W|vneub}A˽mcY)u]6 G%>H$jP2"z6p+!LN.Bk-e#4NxXJ|sƙ4 N*.*ˠd wIAQD PS(3}fβ,rׂ_1Wp(#:0tZAZ#Nd*NB ёgQr,+.fizWz=.^=GM@ ^-Ѕ<[%^Ч?tD(ӓno:866U2a՟/Cm AKCGONP|KMjLE'm&;G(D0\;Cs.Cg}PT?q@::~Rm;Mil#xk !qsc#x[SGY+z`y'u\ 4ftgF1\~N!qeIt <<+&ozoQnVY:ςDt̢84A250 e 6O, ULd.$iܛ获Q0tš<"ȂIf9%"ag%ua{tO8ݧ{{{u!x4(M^^Ou/f#17+VGOsl!{i6rɏ߿z'd9NW7Y4_f{c]||a7lE"XRpa86'7=~ t"bf& 0u7^,U`)#_[;fjzO'ssώ> k` Є1!>L&q"rxRfAɗޖIKPcҙGEΟ"djA5=ۂ!b $H ]Ly@fT :hü0*D;Q- UyL}A Of:X B`%2 @Ϧc "1QnO*2OC(;>98@:pP&T:`Vh; P(1gzpU$D]NAzjb,UV+iN1D05r+V4O0S iM`Ni~81'ksœ,Ij^'uh^OS}lOO)6?zbg{87s:5ȜijΖgs @4lf@M~cFZ,B>7m n:藡EؼuETqN %֯+AUF*NKu,o iJd\q{r-ѢQ8NINݠ&hTCCI}8 -<,G.mTKcw֒b]]*(s낎 jΊaR1ޘ{8ܞ4Ñy5_Va62_}egP9'PASw&N7xӷh@@Apـ.z ;-;8 M%_LhQ!< 2ܒVP~ot3/B d"T𭇅wsdٵ] qReTI1dkP^S+e:K̠(p;} A|Gkmnյ.JPxAn%8L房{.8 !%w)-/jz\T2$ԖR6N[ &{=GErʅ~ +/tLW,,1Ա~o j SDW~]:=SW{YY9XezN !b*8atF܅h`TAS *zw3T畘)b|(ա dCo@?զc&?Gıi(\^_51튞pQBNF4q<1ET“➄rQYrKݗs_q:Um0Ns|ds/,t!5Uhp:4 g:.Ǻ_(Рvk<I|$?97h0(BBp9꧂:,A ̲@!K_Q<}#/K+d3I)g ־ O&h@9Y1ɎwtsRHPAsΩY(Hgy5pqFF>FwTЇL;ḥoz|?B5D~K!غ `SKXn܆Lͭ702(_Fb$r'EI,Q#O4.0&a oI/sYo>MTϫ Bu]a!.EQ!#[DX>?S}mSO:2PT쓩0xCE¢bc䱪WWVbJwO El& glH/H ޫѨLi4޵;sy̲ȦzZOɋS5 g5Лf"ʀ4e~dA aC^Rݵne%5tZ65yK;qV@!R]JahPS;}ܑ ZbH,L|G46CwƸL-z#IEC ]a;'W}+l_ao~u]` 7]_v N[w/j2E *'*KG?,,X#+6Nu{d7ʔC-1D<2 n/e =14-~/rj3!ʡؓ-Bm}Ƣδ jU'0!P&;&ln*@LzQ]Ǭf)':Xh_' $Tؖ{f:q Y-?_gUbe__0oa GkH33)*GD[**vKxЀ$Nj<6HC6j;a> KB57_y./a#cQ~`?hC=68GT9pٳ=D"$c@aaۣy3"=*t0TZծRX< CVKmO o'hF;]t%$yL<07xa|`XE!65Xdg Lz!`ur j1i'a ^^.g"Er{KݠE[]{{gG#==lMH~x..v1BO}s.hs >rOolaVm 5K:ņ s||o={WoΤ,E0z N{؆ǁ8`n4b=;BeoG@eJ/WiJ J[ ,s"hL-"h2b-w'뚔 r#؜ O$'y`qex5zi. 7dKqyeJuKZmW&^$ω {2:, ׷DF#?*ΖE/m~s܍ tKzXک(ҼR*Zƛb!ITW{d{QZ&KUbg“;o UꢈИԍIL3W BU<[0AFj vUj-QxqڧՖHu2-U@Ijgὃ:]X]ۓEQ*ہloonp1^bYebi&ynێ@(~ѱh`gbB^֜<-,#0~Evy̿EV7xeGEK]Ei5WS ti.֨)G2Nє c)x—ݐi* 3Ĵ-இDۻZ, (l5gypY÷KAތΌC<]Ot ʿFW&H $cߓ4_l`:2o?%hg6UR:X puWe ut%UJ',E(b2Ȑ@.? bD!{C;^`gsxE7PZ 0F=#2.!qfhHhkg=g0@WЕc n@f6 @yoRuP\N -YC 8-\pq~P j" j~-xh/}4}lMUP/?@+)}L8ַ''5 o$) ֏ˉǃ,oߠ3O԰׶$.FۀԺoZ9Wu4%g{cs*kZ +K4t($7Y[qJѥ 1{3L,4x8yjw@ A>ngw-r6w+ URfu$NED?Fu'TyN.ػRoh,|G\J~ʓ@PU _$4('v$0%8\=egI T9 S[ۇN>O@xtN~X?aK;nx[qA͟͝2DxYsH+|劸YjcpN6Jdi0:  {}1'YSȚGO?iou}}]\ĉ Fϋq!Uq17oe??*yv/B,,yC8KAsqr"9i$fROE8VV8x4T!#Δ 0cį>;[[OMHUeG UN qnEz"nJJg!P@FA\t "e1數*'CCZ/(y%2h?Z/̱Sfh D!C$FIJ?N|6#7{{ ;zᔘR"!+4es;Oo$EjtuqUgoquݹjwBt)RT> 3%E$ N`&e|“"$d73:q_YQ*3;g_?qU4p*^=I' Uݭ8"KΛvkۻ[]:{HFMecuv#i~>Q`TZQ{"PNuuE3 d#EshC/?R00In.Ӹܦmb"}bs 9q: 8EH0ܭ[d9! >In""}&7wL-NdIojqc59a7HTz? w*^s{kg!W{w7^󲁸--vJ3y,@ULrX#Aj.R}${$gd7>O}g=f}y+ 4VE{TQ;^|$}gjq{EUlH͔ٛt}~s)MSq^ID# zBDUyPUIH%A>pxzB2 e~[#M*No۬~Cg4r>V:2M< qNMg% 2@ f7\pESv-+1L&.A>.+XJxOv qz`qYlg BH،bB< u vZz /eJ"7Z8 IFi!$@= 5PCr B6%x 7d$^Ι.x%oSA2^ f&)VF#pfȿod\fJr`Bwi,7";P0v%5(ҥOESZR5) 6܉<> 1*TC6FysΧ}E 03̾0K%8{ey+M:P^ΨARv\!bJ(?۝fEj,Ka^ FS zo%5.2[Y!I=h #}-bCYζuV}V:^u^XJY"٪La{ΈʥI ^ߙ~[.EŚq6-Z֣}e cx ;?XyE}CmmX#`˓-1q$?e6J5&,eJev1MKp Q=b϶%2Y; աuOd?[Y "Weo\[}Ͷ9~fҼmK2̜LF+T MU]f522aqk(%EG];nzY9?rH ȟh8&nT"?)ӊ[ AJ}bTHNs Yiv(-:υqAn0xl7nC#F%v%h9yfwi9vN潼osxl7n*%h9yfwi9vN潼'n~xn7nC;#~Y(nxn7nC;#~Y(xV]oF}^~ŕ(F Ɇ4mcXk cFUom1'KTs_\\h4...'Y^5OYkŲ[a2V*O){VKTF[%x-R#:(I;E/׷;[)wQZzIc=o6) ›꠮7aqhmx0 /&y[ŌZơ7ilj2:2(Pj֛8kM2B YedS`ٜ_ELb6UPLAP{Eg) 9w Al9餣Jmz7~2m2{s 8ɫfe w6=ٕד,3Rs`׷1{ycon{ǴgfgwE ~fmGWWg]ܱkUU.Sog)j/Kˋ#ݒ,qߧclnys }{N#$.Jlo*G}2T Ieg =+dYԎ35"͊qwY[;J4u[IvcB޶VڬGH  RQuT&Y_=P;Rb砇Ɵ.>&W'J_:n(x'rOd!#f#FN&nAx'rOd!#f#FN&oZx'rOd#f#FN+9LxZ{SH;|lQ=۱N'Z0.lR*!6BI2ǒ~$ۃf߯a}}A(~"ž2 yӞg8Յ}Y_,=8Hf|(S/ fYG 0S̓D! {~!|7=)teA<[$4&ުo5[-9PDҠA*4:Ii<ɮDE<DA%<"Ȅ_~0Y;#rxٺa].BjWYM\'B'Xſ_&zרXTR Bד51fM|,jfVժo鈗h:{J(5V?fqYgZBFwj9Ƒ>j}Ӕ2҂V_?{E̫=NUՃ 羴^iTL'z})YNUL[;5q$v <^^{aXC/xuDn"Y)kT=s3o`'gXD]T(&eދx&[H$*MRʴ؏VFV](K`%l9F; UYoMS'蓂~.%cbɬJ":Aoi/0̙lu+/ݘO"=G0 ZO˭|9,ŭ|L+@klJMguеp#+ ,KHwqEҫ=D v?b0f|fG1O;ape, jb2|OKݱwpkFzw ،CTMqv-r7)`>>UhTN#˯lF(. TFݏ#"BL`ѥ4+'NKLP՟|"6WH~(Tyκ`EJE .ZC.T:LUSrpdF Fe`@ eT~/ҏJ=ZئN;U)LҡVXJ񻵅WJ + eBQ%>/I6y \W<7'_MBᆕsik#&&<5X`)J +0/12SOCC::%sx9Ԣ&f>t6`e3'u0ZYlaG'hNL}6EAQ}?)ۃAбPL@qkR_N`*9&5T\'KL(pbU6@2ghqut%flS@)GP]̚A*xa SotjwC䰻=W8;5i~BtmlrpK&t^!-3x6bCwsHEॽ<5)trd4Wfc)zC-ڷ' 7ժ,:VXȅk@f[LF#1DhJʛ ,ܓO3L^jw͑kuS 6a%hc%)3wI%J":VQIȝR; ]7gj5M2ꎰPeo8 wLjA kC5k@V )q/1jkߋU8{Uuz.0 :{s;UM =Eؔ#)JXջru)=5BۿZpٳg8 |S3ZpᾙG|FC 49@W2Zo~y;LmQ%qF1oeN7/= 5ӱ񿽅STwrpBT'ŖV;kF}U0F[{w6:Х$ yD.ӼBJorM)duNRs2jm[2F(޿8J$]Y+Zjp2[2Qm<8hVT#m*@-f5m'bbNt`,?5/_9 }-(d60uf~%tnnc\WQ#i<51F5EߪKFӝ ޴2A Tsj IQjyBS^PJB-RUٍR ;I떺< ~8uA[QgOr13-^㇌H]`eZE ͪ)UOphƙ~pEM# V"/-#q ]txe+ۛU$Z,\`uX"Z)RAo$3 d#FX 1K,^f|bF1o`U e:}wh[tP 0 ddi[ 񣘍*>w7LA/r;{`MLpYgYJ 0/F^y4,T<y<,!}4Ļ_zߌgu=l=qQ2@ &x·^Iӯ%zlJKzJX?lϣZ<@*]]s[ Fzf6_,:3ԩjDzM ᭯^> /M.4 3HaO!,sdNra6# ˙čye"%L;)@E9Q{p@;o1Py]hɵ>ŗnM/ߠ?3^O< Sσmţ7~d2za傧=.mMUD,5d s8"S剡H5oyWU n;\/Q43'֧ r4)ZICdZAhHy*Hc&tDib|!UszqiQ?-QWߡnP*cb9q#Wrnx5`#fsj*q4n1x5`#fsj*e2Jx9`#fs;lyɉ%x%`lK?\7 o,x9`)#fs?j.exW]oH}.⪕V![JN q͓5ChƦe=wli!A~{\5: ELRG˵Vg j_Z-"4ƌ VRZ,_gZJ2,*:) i)i53I*#DTEٚ$Lꅡtf\ B&R4V! T(#IC3MV1LJ t°TtH*״7KlP.2F)]^p ڨB~>ʈTb%"$b☦r#gy PB'wxC]sM'|wV{0#I漏H#$}8X9G6c⦙,3t?n{"j[AkurJ\$ \݅;KOExg8p tիW8 <*βRAřLWIƩJEB@VMv#m&"Q]S np5O=o =k)vA@;Xګ -R+2 }ETgćÄi:F{[ LLq0ŭgNC׻ite넆׃AVA2)X`)h,L-S{fbu LA.xyETɡX&Qhqy0O>+?'Ägy-N$ GO >eb{ S/1e$ctۮD1g*wdE;5(;̎{hrH{fsfOW`0= 8l|a(Tn違λG&oo|Z^ '.~#a#Ug9wc\# F:f&ET@a?1V _+Pg%xEI6 ^.nN [6gHҒ'q*=LOawrbsb+K墂JrD8Hdd~C{bx[.(>A`+r̙y%EXt$ZѢ/ X-v D2r?KRY ]vd*E[At%#"CE .}CkB.! ,S” InTq)-N[a2 X:e O<z8)~-"yv &ZC'`ĉ'a 5rnc(eg&55WJw#UH6lI݃=j&;(IDnfP;IW~}qM \~Ae^/t7@!H |QL5eBxKsSShsyjM.- L3\ 8zRX pf._RjU9ET17nj5t\1fSI)c$A MU&t*&u !r䐘D$7@"Sƍ"kWbn(0frr˖̈Bú4LʹL WP[MV0]*X2 c#*c|$8J24.67]nLm1U@p=s3 п.޸VЦKal\覐-̕vei"ihy; C[,!Ѐg.W⨒ NO㏐+rg {AIJ2g=:)w7>GA=h  h Ë! A4Ax"Qugܯl]m?桘[xe0es7n>FcЍ ~1M?D]&o;0wъa_K{eĔm%V*H-Ehb׽4+\"u1nuɳ*3TJ݇TRt}zVStKTݧRfV'wM갶bτ^/{K:ˬ+j/ (B}`?NԻjuZU!߲[zgRaK6n/mB K/tReVZPvO4Uٕ6;%^]iav lޔTЮl\49GER|lh*TU8VŽX>8.Zšya= ט&V7x&F3k$c~ւ\H3 j<[UfOWկօVx[ms۶l 4Hb޽q;M:FVfۻ,^Sx}@eV+W0l1nh]ã#!(KCD&(,͂LJ!xL" YY4]RDY72EG['3b!E!e.9aI q(I.E 9G"n4*⠈T3q/űAX4ΎH3 <`Q2!.g"JEŽ@=>Dq,Rs9_BɏO|{qo0r"Ŭ U\ fAR<}_އuvp՟ q5ƓŧX>G@ -"2ͤ"l x&C݃@G48Mnyѩ"Ix"K2lG#]L$$(B7kBprrҼH#㣣7G'nhuww0^Ϥx(=XW(,gvUǡ$.oY "̻J4AQw ~?(ç+8:<.Œ׭B<{2Y!VT4JLAV7QĹ NIrs"NK$nߓc>/x>x }OޤX}B]v"\- J)>q< »^pP"[P2QcZn97/ d5-4~d.QD Æ 0]ge .Kc?cgo|{a+b3Z1*Q@"Ay)rq)La,]ҮEz><<LYKA"4v _wSXfQ"6ʘn j`]6RjN>3Ѫs6&y4}NXQ+SdFvi^a֌'5;?US߈qș}K魚dFRI$$FȖ8i޵>~cLJڷNZT?biFhI]O3Fv1}fJl?_ߠ=A[` YkUNzefm liD97*'-mڊH@-+B+h/  6'~⋏-LEm8h(XllW%/,#Rk$rauˬ a;:;;;Ů h18jT(0DlHY6KPjr֖RM䃯b@4x1*Hp'Z-6^o1 bR؈ "Gd9Ҙ~Ud<,%cEĈߜ3g=o\p"-svlC"od>2hP3`вB@S wivM,83$ M!9r!çb meu\F:Z3*7FDWZX(X&--HtcѩmmeM 6q)iA5gUi0?XL:6ڲ]}"=9 1n iw2ڱr(ҫJdķ{&(l4{eHl)BN`X!`1#r[,J p Z&P Z(* hd :qO$[G"/׽9Oq5O zHݟ 0бrꮣsS5fRxb+Rlƪ$a&Wī8f JNcrܗ 7~29x7uh" qDjeՄV6 <+5LKf,:nw;`kTSTgY gIH VօSo?_+[ 2[Q)P{Hj_ar0F? sc (A $CQg;L A Yl3d|;=W)QRp ww+Z}R=t5Xtu$م;wVvpo񉿔6n(v+MV^Q]ʋaV܇haQw)7P!7%:*VMA'ݼ,iwTL<}\PD᝿RlPH,!Z蜓#*(Q1*^i ŏ?2]h\u JfT_KUƵ׻|_ZQU, |3.=I3K"$0p*?X%r7|OO`&m. B_'E/UNo?p QC9\M|! B)_N+`fuG7)Mm,fnc C烍`tHz;B`utxpZ#ƐTN}۶Ġr@paϊA Z3GP\ʴ $VeаC(AJ3$%%>v0Z5\a(W8fJ 4D7<&a9zćw'{p1LA/zuQ1LvuE4ӡ7]ᠤleI\X2&|iZ`{42Ŝѧ@@‹xPݻm~'^[>$~vJk^Jk_fI\ڣ:*W"C7VURd8!N>Z-ԭfohFHmmJFBOq.W*GFj%8VLV\wd-(@=j { m3ą"D 3F6 XqIĚ͘.]NdWj8jGcECkjk[^7z$)$&FPs |T:i="vQ+&ż)N:l&qE=CB[,Qooɫ 9 az( ;HDBt :D_*a/t(ZfjT‚YAD`o)) ~y< tb2zYIQYK=pUQ##cqSb4hg*,cyya[3A^άhg>cSlIpqNyP}41uic۷jbw"`p ydÁ=xVpfH16f.);m&z喟 lkw{ѻ`xnT&aR~j9y|{i3 %3"+lVj+j*-V|E$ s4΂EҤ`g =LXJbbdA}PH Qp ur#'-[#8'ב[d ͧyrTx;ݞa?S>̙y%dt$V(I͛|[Xq ٷ\RnQ \`I[0{O9 E@)'O]̒T.N YKCh mKPRMQH,OS젭%4JӚ l-H dk:<řU '7O/R9KsW#@I[xkO_a|rIQN|Aj^Jf^F]Rf~|yQfI5d}] ZϪK9u&QHҵ/LO,I-Q(άJUU0boVL'nPxkO_2A`z+:`Bdӕ> lxkOoOhQ=^/Jx[-yEj,9ũ/*imT Uox[ҟ2Ar:.Yidfe5Ԝ6G*_-4xVMOA>p1AJI"S &Bi*H!Fn2dȇ`2'xƓG/z2:m{N}ywNT1:>0 X'Z5YfHɝc i$e{t3yЮT "(KK:2vSa`v:Ky0݉V$C EdJҷ5(H`f駡{.ёh2_ݑH&IYK1:}p ߨL:@wZыdžu"Vyߦu6+HeRKŠUϘieStfgؓ|z֧.tv؋jN4%W.2t ITwcq 1!a:U1xO9b;ABAA!(?9X7Q+<>! Z%Y&d+*lVfLSHѵ +B5=>(5drfE3%2X&[6qq*&wʩdƗR>yr: Ii\+M% RW#/?y \Per'+(AmߩdU qũ%eEiP'pqrU(LVԵxE$>91'')19dB-C\_\ y07L~*QHKIMQltgrdfLNo8wvxVMOAx5A$cRZHZ#Yit[ln8_ţOMx3:m}w睧=OM|X>{rrkV3ĺNⲽ|:μh[*EE%]P%W@(Y̲4Y1dU#:e?Jxۓ36O^7#ٖ0bpGRU nYB6 LeuU/o*vg ayk"TU$Uuq+B(hU!>B0*jңpuQ# -I5ʜ*;' M+fC8~/Ř>:6, m;H#oG5ѷ+Q &@f藁.㑡!h!1ۑrȴ~eK" 'F5!'2eB?Fhqpr^}bn.bmu\SlT].5%Xi@Zk,Yƃ-7v$!gla1 2fVj/$q}56NPѼ`І]u }M䇢_-*=sIuON|$$ ӓž\4AgRim2=Ne؊DSLz"1QylkxOAiq}%Z!xOiI0e%f͓60mQs WqxM}B@Q~rjqF#gxY}ZO<[i!ޝ{Y¼ l>xM}!F#$Ax۬~QV_KA3J!5+1))(%*'3)>L/YLLPR0J!1'"RAe<%y*x;b{X_KA3J$8>L/YXLBD J!1'"RAeL/Y@TPXd}ɂUs)*jZoǮθٚskxWmoH dMFcHHvud3s dED\iFv;/{60/7J/மn4C'Q Ol,VVtۅIY֍~"\UoJJMiJ}#j<]LCoBGR62 -tҩ~A*}S~ؒXӟN) K~F{6@/]QFH`%,՚23*Շdr ZQf6"K*L/TdN|8:ѩiQH( Qľl,=p" :1, O^ù_83ՀP._Y>%bnS- Y-`y>DqLL88S!v?{lEU!W ' &Ύ;ퟎ8hD'CҠ;.! .qh8B,V ֖&4VEq %a<(u{ħ(~\Eqb%WD!E3J !@k$ح&a+Pi*rpp;YtvlJ#Yd<4&گFCUo* O?aKW&ufUjwzbif>Vvo@q>վW6wkĤߠ:-mN,D-tbm ›F ^ d:߻OFFAwk0AkfbϚ TwVit)en(<45i@U{+fߟaM]2#|2Q_$ o3女:Bk[7Y*^\[%h:;`XI$gsȩY6s"nuy#?9െ xb&YRl[ _kAk$- O D*%s$2Z.7@$`Soc>a+d| 1g^J^:d]b/o%/0S`S^,`׆=1P\TSp2Dy~Ď^/ oPc'0}t%hf\npU'(pTa.N{ TcdBT{D(Cj+c"Uȝ1rwpcDFISpZ1rf`T{}N>gL2@킧F~ *|jv,%qЩBc+}^Bq/UYsYHϢD6GQw<)'TP:> l[SE5ٵb[*6v=ӿiRIG}&k$GhUށٚCCh^]ǐ}Y`*wԾǍʃPq?ܳ_UL<$ȷgW)f[Ӫ6. rKR'(߀}WHl@]aY,"ٲA'/5G1l~2=ijP@r99S9&7 .%#+`'4Y xa;e7 zXSGoUtg'l{M+EMHPٶ7ߵ\pR\zԸAYlnsx۪Uq!#f#f~$:n x۪Uq!#f#f~$8o%x۪Uq#f#f~(qx۪8Sv!#B@Q~rjqnf[F&I\`+Bbqrff|I~N~yj''>vͮ'rKVdhL" pax)_f!#B@Q~rjqf;FVx x)&>G8,9?W//ĎKUUU! 8UJa>tY0RPLR()J+I,IK-Q027T0200556P02252RHI.NTP5E b-,O9(nx);Cv #f;h^"fxXmoH~|d$C\uwF&ȐB,WKZD73];ܵ.<3̳~_Q,^V"LB ,XD_cT*0jC4Dj>%l_؇d\0kc`A Lć6nfyn'"Z瑒R4iAүXO,uSONNb|#2ba $q)>H"W/FlH­.װŽ&/ȶ~}6M};AJ eBjOǺ0f91) -ַƌ8.h+Z<"Jgؿy{}Wxm.gBj֛`"=[x[ vk*^v)h;EyG±g#0{Bqd' ɒZp綛X&(׺P.A(8 sZ<#/oZ_Lw"t^IiCge^t#GAF!8ܶ%օ&:S3.bbgSŃf"? Ds䑶ݞ˷6y3MAl;QtT[l^yAFm."j2 o6%͖2qm5N3g}e9_V&|whE0WI,G0" `v&lD[Ζ&g?#fgB"jZx1Ku>#fƭ̛Y<^zx1Ku#fƭ̛YA^nqxW}>#fƳB-9xzPi>#B@Q~rjqn~^dG&a̛22pqNN`ܬ&RRTk ԢZnZT_ZZY\Ry/ < | lx;t@i>#B@Q~rjqfFViy~nx;t@i#fFV&+x}kWIgllMcltc+02y"2Jt{ΌL[Kd22222yY|y= szDv?IkA4ˤFi`<)q WQ6 2q`jk7 :Ilnl<17CbvM4OLyw@7W77UsH[? u. EA`,Dss^ngd7hpzfΨF2Eݰr "El3y34GA bҸ^zM, :N2GM0@}d>Qf"`,ԊhʝG& 01C]˃ԞHP?>ΫphNsgÊ Ƙwfah ]Am9PXpZ3Jn@xw>;?_Hzp0ssܬ?96G5֌iS\(s8}ha^t88Þw>u7|~Ӆ&}]2lg> &UfpfFaR1W|*㊩k{  ;ݠbQ1?q*tجVխO1aPv3LLjG@yx/ 0{Pt?Q/r+N:QYY\0=i /v7%Q8zU i'7`}VX~܋e4ln ֫-= ? 04X^P.9"ѰD"}GiqxQ Hnop/k[zI":WbgwѸ wl!0}n>@[M)b:991WO/̆Q ,!lv&A{8׺g2o<2q}[[ َ9 VU |c:bP: L+)դ6ft)IOkZ+Y{ ¤ N۝`-,,>' DŽiMZ%Wc?DNs8#;gYPQYg -a~疓`q FAdn=Qz-)յ^~vCiu}WWF2Mx3\_;P2Dׯ֮zx au>wϠ ~b LWS1IbV_.R!n0M6Aɦ!qJmXL27kZ?j@.E3p*|\? uvΓrǴ>j~x7Rf~_ԴrSVTw 1=x" ߰A$pn8 fYR=϶ p W'l'^F-a03Jʛ֧qfEUj| gAƲp(.|BFP@720TGAz8:: N2I(;J!SUR,s\J׀ZaE,SfBy+/|Wmv+s]WN@rvTb L CL^m8;ѯ @Z!_qg\)|DmL3S$Zʏ"c<UĈs62k8pV^ÉZͭ(!,'8?IN06} ,(Vp[G <j2L0&$51F53-VXlOaCw-xL΁jٷ#б;p$_Oyq-BlBU>)ܑ a ЇmQ"m ϸ tkiԲ9{9n Z%o+GYQi70Z߷  ӔUn 80} {+l5д]^~\bO,yUPj`WPYwXvP-CU/hڎf 5>当zs8] /:AsvȮw,-*|xb|1׼X[-ziY =Pv$hZ,,кkձQb) ÑP/88ON+l:&ۑqD^M]¨atׯA7'Ň^g'HcjA7 }tcyF7}}vVV*C $`íd$%-PAS|"linƹi ,u3`xAt}nsw>xxbS(r)ΜBZ?W/f60Ž_!YДmq[dȂgv샑THc`AI۬ihVv#[`C{C5=.plo$B&RL$q9H,9& mh6n @B)9rΔ Fꙗ/<,bʴFgH|a!|y*Ӗyqdrr]+ezur0s"W3ڌe@M[2ʗeE2!l0y+څi$[UP( eY+ x˘i\*r ~n3HRϦƒ벻W1FDR<vw;+x=?"e%L3x$'_̓49 sgl+˘69o8m߿:.6G<Ը=3X}4·4 :=D)|kI`he!k[QυKU0ĔشWŲh uPw l7aJ?/&.^@h#dvhMr˒tq#{w\';gj!wLgSKib! UnO_30T짩 *7%3KRڵiUM~@vImLb2&3I=6B r3_\N)kK}jBpYfC 酄g$uhӘYew|*&XANG5XBj+[l~#\Br*c[n'y Y-] y˖U+N=c.q )4P .ծEr96N3bM@̔=_Pg( $5@!M K5 \^hC0h[$MBtx[g!0[(' ~(/c+,ƉyJ3+S/l<'NU2ˣV܍)ӛ\7Ń-R!G1nEv7 XA )\Lk6<;LAm#agrAzkgȔ*ϱ%[*8c",U'adYwHTɸ8hQ hf,7u][ (1| d'gZK/*FudK￴ g9xp1JKKKOPw}]Znt3NRsl2%\HY TG/\G'?ɺm~J$KKe58.2%2x9mB Rry~ ] sP﵋Hq4 % j9^i.!GQ 3pd#rTtӹ«+)p ]>!q),TŅW<ŻV| o{3gL)NӐWq-kr }|<ܽ@9b/EM<7fv^) oWg| df-pD?pi`'"n5UGƕm9 qwF dy}x y7~̰7glK/5M)Nc9~rsd 爲kH \+Ruҁ gEߊ|hࡻ@L\0Y#`uL&c# .ñܟAGMմU@wymHD (|,8ֈo>S=M{LLu)C ZhqsOqs:1)zwㆋhymp8 tF؇P:jAɵqm_;Bt {vCP-><'9]F)@o.nUEeiR& C5HHVTia^ZljwЁ{Aɖ69 G̭&UW q]=qx=Fwqw;0"qa2૝^_<;ֆe[=sb;#9)jk%[.wp 6#A:?"omXN ѱ(2GIr6Ξ(ǰ#fB~+"ɆQWX堞!Y$lXA}a3~u3^,;"yJo5,6C nMxd_){m }>ƭH4U+7TjXªp[]dV2=P7ah:ѧBTlU$oNGxrYo9ɚUD4>c D l0GU+Ƚk\›H(BFKm\1㩛T:Weo)nNpXW1>CJŤ=ݰL\]{\g/;~\MY~3Oe3YLƔ[{ՃϞCl!9w;o@nrk7Ab%;2Kלc я1{ z(op*4zWbG#N˲^-+ !4H(CЪfze.kٹA&^aR nNwd^p7b;ۭM[}N*1QB6cOcnV[9q~$m˴NJ9 wj/&:u~cށIuۂAM-2^:V[DvD,OF!dln٫$v5d c8g9;[fɌ{8?ᅫ`K4B(ֽVݣym,NM8JSp CUl,ӔJ_=HB a]lGTfhE՟~d("{wgޖWvZwx]]a Q\_VL[A *8`<$lCpi' \N 0Yy^-SuH8;H2SpJ2p"x=qqĆ+-?,[]̂7 Ot}.NFmYbd2Q{Z*7r]1byyg5ƽ*;{Z%_].!pZnU jGÛ i92~c_6uD?$ 4(=|Rcd]U?eE &9fT88O:f*5dEw.p8"R]1+%,^OD)<0<[M f%<Աs'^[n`SQ&<$(dp<98sޚ/ۦaK@ fC <]k+à1#-R& (xZ,[*m0:l-OV;K{WdjKRR#a LY'4mk%AJKΣ{V6 p+Qu d$ 2` 8YaʹM2>,mq/\\}/neVd.(kg??t3 `9Vgbl;:9pj`z* P<${>b+x~D_ofγ `{S&^~{*,U0e%(ޣ~ƻ4%\I@6Co<`@vÓ@>/?`0Vjz<`Aͮۇr0z|?B4INP ygJ2{JNUA9~8c>dloo;(#uOwƴ=u@g]kǏu<OX'^FBܘ<5PsKL-C.W]QF WͯJؙ^ɼ^iLlcʳl;wA]H@O6N@@~5sNL묥xRtDY(5&_(*rCdZdaZ( З< r_ۭ/'CtЋaBe7S' 'N/FVW$(u2r>Pxf7jXKjtӨ5/MlyLǣ61cufi2;`/9 Nsg@ GAXuNXgGNQsתmIm Xa\&M*y!s`J6#ZH~wY%Q],}^@KjxWO#UB5 Ljb(S Xօ5 dJGʼ:RJw&^dċIoě1&m/&{o~t~Y|+_>o -Cڬc,,eưuPܟy"6CC9E1 j`! lIi]݀F\C3V1첋gG?ǿ ZՂ`M*@]]t"^㯆jZPAU%QK@0"%=&2%^N"2|&'l%)V bZD˙ |hBwN~> 5 )&\Pø)vXsNK w * rY!1#,Xw#vL2@R9/NlV11XCncײ؆*#Q^x 7QZS=˳wL5<ݩׂsG1Zw -G|OS{O"$(dR^/ǨΕ&^ygcwo̗&e1uyr~tWW5ﴋES0R꺅#myQMG}9`B1HHr7 dB&IQ#3Z&3Yrd hK+*-$b%^gR!}r/1ȅ "6jv2u>2 ,IgQ-,͍4`lخop]tXC"HB'OG6)[)zg$mjiJLϝOn`l&gs_5Ѵt#is,!M3꽛ҋOޤX/4Zj#꿎5 h eke  TC#U0{AZ.dB4(cTGX)&v0[=R$sA1i;Tty=U1Gp_h5Ir @#_r%7_-$cf'ilo~8vI lJu]6Nu#?B<)'(LG2IqwqλsT641(UJwsSyt1mO,ao>Nwu8{o>纓-O;x m (x[tiHAQ~rjqq|QjaijqFZbNf_mONIN *݄e2b6KVĒ2m3v.`¤ǵ P}V B*.xuOhA٤mMkhM">1m &RH/4;6KvvFL(xAyWSa// 7Dċz0ߛx?qO?rG89yhU0fB C?ܞĝ0vR#f0:C rG<Ьӊj\ƫ8 R?UVsPaHMuɉ/b%"LgtbTuBE:&pH%LD v0…6:jkMrXӀ SeP2Pb5Fj-U23sueU#TU Qm |$)I67`'Oa8K:zg|Z 2i2'wԏZT[°"fJYׅ\㲰JlT 0 -J3 +ydjU >Ƚ f:7x# 61+(Tg(x*rq&'*'g(qq*Azj^|Ir~E)X<נ!3[ts&ɷe7Ѹ #x>F&ͺ ՞: E%3nT::#5'L.|JllrbqBqIQf^UI~vj^ciIB~'gthqjB@bqqPD@xTi^JjZf^jdCm͟|V>6Gx1EFFJL}TExVMLGdMCB"/6`h dXXﺻkBj9kJNQS/Uf{"UBKC#UU:'Z!uy{7{̃j ͘TQ/ht57ܐ2u,h4 G"QyGu]?̖Id02Ԁ߻dCTY˄τIĂ(`Jye\^Vu{Ns)tɀӋE 3qɥ.-*ǃR] XwN7W%,嬱ҧ#.s--)\G'6Ѝ.tZ7%ϞgwҦd>&fNF@͆<=Zs"cN4֍+i+tR@̾4JXoU>L U&84q Ehj↜  @nXPT%Uanð.R'/:]v`I!M eM00˫fzVCD<U#eZ_u*Xz򢚃*n˔#QqKP^7B Tgt0;<@ŎdYwCIO\f.p\"ƢCTW 6bYhU`KsE?DnbKgy0_.81c6u3533_âA u;z,zghl\OVuM "kʎ Kg(a`! "4L[hGM^U![" LC)uR2v ~0b]&* u3,RI3Hix6 5 Q 3@q6 .x;ҭ0oQ -ft4ue7]M]MWASMW=/mj*[=mkPl=> "<9ŏrFaY?2 z?&Ď8W}?gN@nWGGg}J4l1DV2+~mÉu)pUm$$S)Dz;#~ŞGf8  'ud$tGߴ{!ĺDa!L ?P3Kf祐qH[(z?Yy]w[ñx3#p؇>wY[%V\lʙ3f0-9>e2M IÑ` T\ .G㿨?CFh^#xTAOANۈ( tE]@,(I@b4.ہnwpw5Wo&n&{!zaKRff|{o7];w=.49=<5ƞ8LčdsTvhOuΪD iؐ#lجbr5@')ʣHULȆ׃lVM-Y슚% {Ĵ`HTbshv b1L3DmBH'9=2aux~FM|+&dz>O[ɴמa=" C/E˷§'y!5խ)&P0/u/5h MM oa. fV+VxW,Ouu7aE{0MzN?M@bՏ}>~9ht/l2S/=koeɹje a~X$ "?Vî  f.$Ts[%mPk"Z>3曳/-k ׈hyk9v?o>"CFtlhCKhM5G$!EA dY+)s Ȑ 1Ɇ$vXC551%g&;~I$LA9YEc\:9pe.Z?~ Zxz^ & FfF VFVQ 9 2l>8{R \ތ>| v\ j"TSZY IUE K2tj7k1' x}sr_1a$)h=xI։ZK!`Q4Lgg ԑ=l؝GOOgѣG_oѣG0uv%߽LRhw:,t4Iϒ 0I)_$dh`86sx0_Ea:JI>98p'~'wlk}Gh]fuBZ!|{{9NIGϞ=;y(ol(a#F zI:t(;L?hw^ 2`mGf,7֟׷=OhĶʬtaY"4ȧyuϊ>Oq ]*OuXL񤋉rl0|oI]@6wIq?`/^dgVDAԟE7*u?W޻̒Q_~$Zgq>ݫqK 4#ߧc_~ZLQwSh[L@e#}cɕm &൨2@ aPj:yH:O' 8J)- } :i'2׃7xW OHץqo:n6\Iq߮u>ttM l_VnMʁ`ٕ;?1j;HH.ӛ=N75&d*+jY -*@xPs9?M)i^%BS! K'>&$axpR)n7WU2-y6<>\]p(O:!M. xSN4s2]ӜB0Jb1fJ|w~ڽt eGg*N<cp Das3/<Q2.T RE2 6W0OH.ѯn1U&  _tpXŏ?Տ^)b(>_&㤗ܞT ri*/Ag-j{GvӍ&ou_{{W{Dv[A8<|2To_ iq{sS盠Iˇ|Edý~~@sth:$YO #Ah!?7o^#nZxyx @.:u׃pEd"'&0 sAo q[+~&?[[?(]D3!J#ow_4h[LZ W@ũ3&o@ :SM=}h>3o"҄J5C\#9t'f/֨0i45qP%h/R 4nQhANf&E ^u_ akZ^Cb=bJv^O/:W~-VW4W`aԣ+׃4+ t2.:+kH6mW(-2vkn^zA F'Чl(r+0 ۈyҫ}C8vVZ,OXɸwѦ9b+H`OpJKkz+ʂ, UnVZz$ڽC҉a^!,P0. HX *mj<\wH}+D8I2^T Ou$_H)9N[]))cz_ V16e&>DB /@wN\;lNUuۜ[io}l=.1eU ϣnp|`oelXI1~c߁pCzcIt)t'9d|Ӟ!@ FS.nR.eThy3K+2K K*[ .Fb%FƝ $ə9 fpc%ֶF['.֣>2`O1L ~1{5 ޙlQSe/6m# q{'4coyPOLHO`"hLYEߝ&} 2m߯i!l--;rr({:TcŎ 50сA)#`(m9؍9ܭi*?ʺpdZx4{zG>H[^eU1UYIR[['| 6/;̶fUҋ#dw Xz!-.@,!,o#چ*>Z!d%AvRd\_Y9vn;+9,sFc&{JBd6s=g]T Cΰ19$L D-f>?6< ~<ڙWo],t5Ѝ<&tYc$&4**z׫*3Ӥd%-@U wKe[X(g*TuZ^6b$gW1A6?D":ʽkKCIM9jk @F.I#B{_ʶd B>s=&֬_q䕕4 %kKk`~i ZN})x]YNT=D*ܥ<=/ޖ`M&TۿT ޮPYgya8>H6,9D~b#m6"HFm!r,W옘BE!y)<[S-~D;˪X K<'GK0|ObRAU2bޛ)Z6Y7LH.C$$fѪ[aTL!ŭE\zДoRO|ic3?6G0(H FV^z}~s9aiU5PPlMÝXS%S!z@H#g5Oc JD",*XfH(5 Ȁ0 ̪|QylAu +]齏/Vݫ___bq&j{dKXሤ^hMi|lM0 $B`؜/w k372vm!h]9Ly,CkM<` R*gd 1FFElv޿B ¼tQ(,`݉+]DhPG v'iCY]*2A&N~6y{WkXUJ#z ZVcb.k>w$ꫵ?jkQ`$ˏ{`'^AF/:0@2*ÿuK?I N$?D=d>,ԯhtt5"|6f&`"Ppq`al/́a{IL[Wp5kG-g*&W(E%cDQsCQ=``_?A2BH|iXK6&6;E|p;$^wX wZHB I^wB:u !F1.xp@C~@AVbn Xaj.aXg^. 1nhSFbk9,ʿSTUer{ƪߐ y;-y)|s_ Ll{)KBuߝ|!ݘ;ᱯH/AYmHh4>,7Xӂlr&niw]֥7 Y'j`<,ڌ.-aqTt9fnlpj-M"X4ؑ-Z `zWmEFlgx9g+X+I H*|>A~oUɧ,6yyQ<3W, E|QKe< Ӭћn4BǞ C MUmc ,x= 驏 tRu")Su#3O jF)UjH*SrX4Z  *ׇZjͼq/h|%ni2A27గsX(ΊQE% ~A.)6`ʢ{x`>l]-H!CU8?a9_he`2Tt2E/C+.>3)( }[K}_}dZgcfsB6kc~LG{瀤E!HF Aˎa{RkD؝jDLh%#՘!f t~r=>QlQefRԋ< +]cs?5(!q[GB(B8Ql/1 3&́O:f2aN}9nҫ𒲃L#'0|t8)x}i"N/ 0z3He*JW I+k;O}k«_dH ε賳n0lۿMHv,6Cp87i<+&sVs#k7Mx%bK3JAW4GZ9dus,/^<ݿHpt"ŮjRcgLm?RlǶZ8"!h1ʝEh xu6}i{)D{YF#K*:|[L@ }8ǒez^W;ηa( br~v®OŻˀ; W -/"H9*(IMXY!wqDZ$ƫ`VeiMrl̀n oH&VhW*aw,V62$h΂}?sUlww{34Bg%oHtD*Bb`ؑ2C'D%`;vf0ϾkǑіţ&FKrT),K02A]T"^Rb kv<΋ : cް 28VE=\;|8L y A#6yntp}'ڇb2Bw3VVUqp}l$C'zĤ<gSp$+IMA#]@#1ՒRDm6!vI/'F3{{)[΂%BӔ&i4=7ykNZlTp+dRq_`_P㢍9Yb6}'L_҉*7!R8l6wڛ%<&@³l(Is{MVe{>C&o n5ib 7I $5d z0IMq#Zf)$iZK{ԟy+8t -ĂQ~Y2zCuIWEe>ZjS🵩f埪 'L 1 =m VjCe&c^p("U;p }pZb|ٯ`YK*7wtj]qf%Nn-Q CxxRKf 6sSD7tUӇ>̬? =%W6f+1LWk8խ9H,8`Z߳Њ,8FfS#f$y4aֱf5뺯,&7Tc/Vv1qmi6#9ˊ":V4*f8V-؟4@9r 7İ.UNr28 9LQĉ5:XMיl{f˸6qUٱ}2>I弽'OiVS<@cEAt#%17SGFi-Im ^Lܢ4UAbckZzÎ,GfpNz@!&HV/fP4hJr+yn\4+g^xpj<:c|ee+. :tbej\^;ECq^ ru)iaz<7YJubrD³}3"跾E4c7l2و.ijfī/3y.yԼ$N A@'E<]9~vzi֋r府L*ϛ\@*3+?R&⪦ZPžW͇֣3|aСփu\[_M{x.tuءҠpP B4R6ҵ8P$i 'O;Ēun!*띌%IJ)2E hnc8[d2_f,̧Jt>H]"bk!w+ 3wlj4'7=(o;M u($uC(zXCCGg$,r^AӠo3v[cf&PRuHr4Jԋ<,+︾eh[8[#-\P0aљR.p;>>| Mg.!xp=#.d8Sοû 9ɶ;NύtW܀si&m7bn`??\n#MΔj0o XPMyQgLp ko}m( 0FHÐ"d NKL|[ϯu_f sRj+8meN=qՁhHL[40ARE[bȄO(Ȼ\Bϲ yYPݞ<-'$6)Y]&YY+%k2,5|dfQjqt]DBWx@iH^T[un\XNnx-O!4LGTON \/ІWR1ȄofҢXo,d|cEFo+0(U5.4$.=Ôm*sKpbOßc7\vs h UXm6I܃LX3x6icƣZ*3<3m>|,"&71+`UI/`#^ M<*bT'Vnve#د [~nr7^Wskz0 w [tٳKuMp)[QE\E68c@q[TaS$ y`b { P,d bEQ)I8f{Me -'b+&!R$H3KlސfD0a^g)x@QY> Y|sŋ{̎f~K& o@0P0sh4P V5*}3;U4Ш6efؠNWp;0M"O~ϸYC}t P6|`|Qv nL,JKD`;B2KfMlf*DT]iĦnp ¶ bohҙEU̳}"m'Py@H\08*"BL+nRhdJXs_Uy aAᚼj]Jffo/ <g T-(HR|aa T:X|юHЙ]HʵJ55GtY?tN,!LZ~hCԤʦa C+t!q6$89 VߪFd6疠h Ss`8P|W&H_Tڞs(]]kgEVϥ;[LҢը 6q:'麒Qyos’ Kfj 8xDa&-۔x#-d[ &fb̍?<<f_'\ >{_~DPs\/wkRGH>Ǘ8-ɚ e |NpGGCܡ^crt t-ыȫ4!x+a憰v7H3ίVUؠ3eȇľ5Dže"S@G%+6e&=nl$!-3slAZקs5fWǻ iӔsWW5E*xY+!SOڲ'}V eX 6TfT/E] kp" )e`qxE C2)Tn&Ik9Td_n!d{iEe1,* I6!G"e疊E,k_֡k缇\!> pM58ZLMz)o!^c1ī%-!W$nX @V)")LOdj(t1 _DǷ yp.TLNJOʺ3\>H^?~4{IhK2^{$RprX 7aTe!c-J.¾(K/*I5`.]T>䮇7,`iH 1SO.Lx5Ŭw5<_EmVe Dّrq_jK "^ _cq\g%c W77 m4AG~ |tҰ]Q^HDqWcKaE/mYNy@L*HEK"n9;0ǐo鋅!@B8J>tҎ_x0*>$ ҙ7 ?+bV # G!--}C$Z PtEʉP{@Pٙk^ U%69.!W U#V~Z PqUW+c qDtREnN^&N{xx'O?X@RYS\91DxV_ͩs2h` x۴o ӆ#,/b|Pz ͋2nU\V\R59ʞ=Y7+Y6[}sn%.VZvn[sw撖bfvd 9V9y%%P=9  kn5 Ok15x}RMOQ - 2@@9ʈ&%B#5tA:2oTC(+\1c\5;w.HWlX 4&.s̽c`CmnN'Coy}Wa<=o9)ޒbZ^~;>۱g^WpQL,MEѫP<>6|5~&Iܚu 52ш6S6U WYjECj2sx7! VՒEXؚlE!$Տceyb 9>x0!v9ތ«(]|kymjamZ Mgj7|މo,$\\o;0( crPRϵ)'E|93F`8Wý\9! Z^ŧgX9m %5:]셃VߺWL͑_ϧK%B8"6 =ꬡX7)gf[l+o\yP*f?O7$W|j͍qGFt&{7U_$t.zKgP{pxmj qxk4g~Z,?XuSR2R5CtJRJtC* RtJR+J+rs3SKlKKt-j5`:=\]\tCb56+pp  _HVS0Pם{.2Y-!*nB*'34Wf(,'73|H.x: ,~n-KJ2JKR tA"űJn(|qshkjQQ~BqfUj|NfnfI614Qputq QP J-,M-.QWI,JOU/ 1YM6>(3EG!dBY%ת%8^ҵm%,_p. ZuӞQ2+Gcޔ 6^,t)ʷ.A9|䩶!JT6xi?;.$@ /+Q87BVZRqp|@qw,kBM5G ]PE i ]]>+`<0`CӄIYIa=5=qhnܓXus OFј̬tC`0D99Lr5d@qYJIG:)=l'Ÿlއك\@FSz:al 1ۦ!>|vYdMKȤI^ W\@NЄ2=h3ש| Ʊ g 3RJOVϺO4DҰ#fbQM[aqCh_d%Es\N]Nb3CԦ3(cQh21Dw&7:о2/7U1x<:=?rz/"zMͭk8L5 F}6F_YXR-lX_XC{q)))7 xl1m:`si5. 2Wa|n$xB:"Kg:/N%{=<:y)t4pv%attO{榕 d~t2 X"]hhpa֫]}!hGDD{:XmFչH 55Rt~=Wp**7_i;F=yކO4 NB2ЯiZh-8ۜDaJ[8sW3BPdYZWiuɉ-5J0իP%KYP5@k(RFY8,Z]jBTm5FpomfēLefm:_QkbQ>5T@GfbYB toϰ 7TZ`b '{<,0d, h[]h€`o^Q2)?cܝbbߜ4v x5n._x,@ah&eV#kNZ*qYֆ• ?BTe a".^dn>,sm&BPڥyGlL-T,*pa=?6u/Fܰ0cC^oK9kGwõ[+$P2Ѓ}5~x^ĨxsMɣXmd,#b9cV58}ypCoYo]fƼ@Zs-[MJQ C7ᙺb;"RI 7|x:ʄ/3 џ-\a8Cm ln^NCր['((H* (J9#CWT#aL^Lb B+`$h?ȶJ|FZ2HGZrOyP̀SjmrC8L-A0\i,ڀ7l: ;xJm\ݸ-(h UDM R ~# AJ:2n ,S1=݉sL \b%]ZmZYo<hvD?yjC)V=l;׬ݿxX)$4i;u vvzս]X9J_| 򗺷2Hk_,a[~E6Q %k0Sp㵋xV9 A|Any错ȵ*j_ie%q1I!^ُмSI|[ZQE 7ƌܡY}Vfm3dj^Q,{J51& Rm>r*4~ ۮ[Za^͚SvxV?5R9('<'F@ooK๕yqҜFq `LRxXbaۏ5tz!&'8w =s'8 _pNQp Έ NIp.`1R118X'~~5TD󄰚+m~BCl=Tޯ(fYs(Kti>s;;q6!kw[s8УM}Ŝ^Db,'FDHDIng",3)1(IYL(Qi iehJ_TIE d)E)̓ yP+Q,Z1u4q9:)|[g Y [s6. ȉD% 楤(3JKx9MJxRI"ͅr"JbdGx#fe}r\@bSڕ&gW*:J4 4)'iԱzxۻ}-ӆfVNX#*Rkq7s`= /@8xRMOQ L-b6RB)э(5Z>ckHکN:N1.&njܒrƥƸ/oWdͽ̹l~~ZPc=fGܞ! ~nΎ{4zu.v*&nr^f&ïD;l:j•hF|2EyK|,E qq Ob\'Sńa(*LNdc0 Y8*5D {er Vc-uxįIrOO]>\LL>*Q!!L~E}p ZE :+hcRݼb+^ueF x<޻>q@akh<{ѨŬ ;c-x>݊w L >I]"5K"H'FLYP(?YWS ZXI;P ;:lO1Zxs2YvD"(D)M];uk)ON-.:G%$qs;';ql{59>Grsl&F7KI1MΑ@bfd" E7 w c1qU3ͯt6`U2ifqo/q`S2J%Vqȯel6DI1maafZx[{sǑspTY&r9C (HOĚ]dw ß=} 3===Ƴg4={NH+|J :ScKcBdSM H ZdzZ7~ ޜwԏ^b6d o'-< qVP8 bs#07Xs7@8 ޝ\^ u~yQ" AeJOmZ (+N,΀a4VG:5$}m%t:+)D '*NLKݦ!D$lqKQhJ~tK].-:L!/k=zC4n4ڐEbh*߯ ǔF{A]؟d3.:<ƸDh*3Aj|h04;{mi;;#;&Gxywx I" 閆1%ZPua<c5sbvi$:7?Eh>n!I:oe8x ѻ֍? }føtZG'AطiAp(ȌoPJn g[ }Mg_zyR&]ho0Qäಥc=\\IqA>m M1t5IEf}zg']-|>0l%ĵslwfnTs05L9ׇ?WRQ܄ w|~݅^{M>ݏM`2!z-7ȒUXgamM0p)4mkj CÆ:ubVoωVa`F5o ~@E M'e^ OssGM |s ְ&»Rߤ % H_U8Ŀ+m> sGP #bm1{0c|i[+r<~)n:im y J`$fӠ=I!Llz-nYpCȱ,JF tfaXвд-2j8#JbW+5Y^!mg}.6д> [a~ƒ8=y2$VHϠ IZBuBˆN$mc;|B~fʣb<acF?mQr#" v(P8 WQ)GbT3]k:E/@d|aB'۲mmA!s"V Q%Ԅl?fn0Xkqc1Y x+eD7wMn&ה"bIg'*bogob"qaeuqpr0|5K|ۺ[ 'Ud ^4tÂxEG&`,4Pl8IڄҘ˫,?=nIQƔӀ,.b %hM$.e⌜IRݝN^};wD|b9Kg!fZQnUQ&GAܨp[8qU*cE>g;(n<:%V), 甼LGxHVd;wzɧNL9?p^*rW$\8=~D6ꡚ#!EGHMg8'QM>RsPzqhS3Q洄~_Jfl-CD,>ʥ e)ṒfL3\1np7P6*vmF4"!*C }%i%BBL+܇=u+KcB=4'd$.al@iQQ^ޝg{Mv~a_(X1mGtNCZ|$L3$4́c> \0΁tyUȇE.1,tyWm)pS!լ"FTA.U"* ǫp:w* P+nZF,57Wi V(S&a9qJE³&b.vbŞt`Cv$\Tau IJ^Y%7e:z\(1AO^lFC-͈Y\[lŲ$¹+ yml?>}禴RʽiOԮt1eUJc4*E,hZ`E+WH{˂z/01( vI ƯnFJgtZ,Bd4jXI2ؒ\v/ltK+HּD:R\ED^ {E:"N΂8г(n95٠n5ӂ.J` j/C̒e57dmz "&̦ҳ quku~ܣG* m#sN$MҲ*6(ש8D%X2spп6 Iٌz󨪇hr]KeŔ:!2$j?0v,o=;Y|nɱ<@;(JS[,7ܠ :'Ro9NB!{L Mzrs2q-lf?)b &ѵ1Ś;>t8>UF-orJ *#(hsԨ36/? %ڀJ0X(923+'2+ !Bӡ Pj@;$XLQr<MJ׎xԫEͥc'haB-u{~JgI]}' @g{/#])S8)$o:F!pU B[>]@eMD.zxũ!Lm,c<{}SYR*o4nVxk+j+hٝq9)> oxk+R`;w*U f5Hnxk+j+hٝq9)2 ,xk+R8Ռ͔'Sجz_} (xR9di3ɛ&bFs憛{9 {o)x9+#fw5f9Bx"s+#fwF~-&LJJ Mdw; '\,LR OC)*sD'*ZW2X>os*O!YZS T)6I}[Q~d-)̲">2AZ'&r>L)X;GUnz6M@ 3`2vNN/NM)NKS-M=Bx:`yBbNjvqj }*'cV\o".>QQRR_VV^_Zk5Y^]!/6 rrA$݊s'o|AsIϔ&IqT**TgO">ғoI2+((L^,Ez oPjrjfYjV{Tdur2KK2*5SK4k573˅rZKxv;m#fwFǎN7xWmSFl JR J)ƥ-hdl-_wNeˤs^u(?k41tԢ계OC3.Fn@~৘o ˜cԁ':"!-!Dܻp(Q1tqt7Fy):G2FK-&mR>jgqЙa`{,ֿ7H8VjX9}(XV_.~nTP1gn01yh>v2pIQzHK:'\%!>h*x暈W11J98a\F.ڤ'kⒾN@$`hjAbQUVQadٞ[ܞ ̬%v$a0&hdE;4X;]Ig :P^>1pNRBA)J7<^_I-$[1Mjax5$krnZ#qHz]>6o)?R_TqYX(efh6I3VBT)=q,"Ϋ+EO =Ti|nPCPᅌS.–mFALpdy/ 5JlT2˒~HWB%.x9 C/]-vU|G=΅5؍aL[XZϤ6roS!x}jGDZO|#JJ`X,!c ,iػmw+vȤ [D ϐ}ήiIڽ|;~|ͽ1j+ ӫ٭c@ܫT*"Tr4U*3sXzwA@g8/~5JoALLe 1+@ag(`E'C2^E L`Pd/x*&SFpc,41:K9ee$2. cTP_~qXfl &V)fֹ敖U UوʈJN!RB?9پn_6(d0'6uXaԃCuO(u_6[Q.4[f:nwT!v.gq_Ҙ5(i11 &7-$$ Y\n)|hx 4>L'Ŝ|hq͇O$BG,J|x!gM0 '0蹫ykk_7B~b{RR󻛿̈xqqS3[/f8fȜ3cFvA[k9`4dI W@JJrY CbR_ܚZ H]M ))֦"4+pb%Olκ4)Q&J7m;m$!7 S;*>7^Apmi&خL9eV姃 AJ,ůqQ>SUx}jAiG?Dſ:\$XZiӐڢz{aw/1 D%>C?|'g7J $df>7|_t%CzSf۳Ʌc)C+ /"v`Yb`crI?5g;p >S,+D26#cC2P6AXmIxپfl/2OiF0Od6wgDC@8rNiտm^'.4Eg+@F耹C1rzT6>%r*E3b#$$g\@>P 2pFv1FC~0sU$_}> 7j:ZW;~A/\[i#5 d.W8 ~mK&^\\`$L& #yj3&~s[:h(\<ȖC6%p5/%a1+.z X] T޿*</p.m{<b"dʳ?BzéJaՏ_>޴ëʖ+QtDʷ1[{?c}'o$e7 ~e=V!]`K# [J_Vkb+g[ΨD7# :x[(Gr?d59 9'+*O%1m:)FZM.NN HK2KRR26eDy(H5B1TKJCu)L",n$x۠hY5'n=x۠hY5'tx[&vCt#nf]5̛3n^̸y{3 /)x}{9W>!p,3kBar#&DZ;7|IzU%v`}bwKRTU*Iwܙ!w܉֚8§şjGGqQ=FY-)T O}EwZ?{Nuq?Dcj zw~팎ZzѬP6=>=="ZP(n}?:Ru0u.¸kC"ߏ=0Z:R/K tW~7[(FxԚ L![3J6>Vk5WP_ /u*/7?k[{{nTv*+h`wg{ou!@) T(S(} hn?l ab u=nZT']=lH_MR?GE&XgdS+1;ѳh?hF\;v;sfE*/./--/=X|#>! c6Aَ!dQ+.:Kǽ5Żj.d؁H_{pp{^Mnߊ *?(=L6;F֫ }Eׇ~mJKAYf7;֨ ~@OSWz:fN=/[;ݽEUkw*apHR,4;Ѱ`O|Dž!j9\ @S 2K )<~z QcЋQq6<-;'{1q/%nIÊT描sh؊GϣVFBJ(4 7!;[v7f}2ǹ6\hurVϙ/'݅^握1o^v֬w; fm ՅOWávGN"jT԰BNb'DWZDluD6Hn'dӄ7oST~}Z,ea>}Zyy,58njȸz֌l*.ʮ TzFaD.+iNZ#Ki5%ڻU?|超QBxV:( 7!k8$́vmX?-r"\)jE0(EEǣNHPS{=%* 5q1g_*͸3և1L>Uu"蹈;wUDUۼjDg< ./=8}ߟ* E½o::O77~O[{U,U{&>r"N~͂oA*̙ss\Q`x_ʈJ__NsQ\bҐΩ 0NKj*k[d͒1Ƅ~>߿_(o[5Lrf۷n m;go)8I S{LZ;hxP&DEY,^,!%p<s>:|9{gT':,oPPQ5ōjS iΟV`ths%k# 20h8E[;hNYQ))Ok DOL!M(}# bRiW򩚧Wrx,_>_v`x #GhYZK%a]H腒P%<-PV蜌-5UQfʟ͎Ro `% б{R4d, a3B|/%л۷kA fAWw/x0LVx٭$;qXX}SybueJuz R!؈ZTw5Z2Sث% Qr!JoK[42.q88V :u N9)u!許e5^A(*f$ b4֕/ 9;F8-鞳uG])gt 줼3B DD%u#zѷ C:Œ5Ԑ%V+) ijfN/-D+qְjj#TJL=)qYY2$SXF)ܿO rkmu@ hΪՠ("=k6*@~/DpY{0yQEiZ-XF`}w#8Md4<HQ((eCFH_7?FTbO5İ?PQrQ2Sv̑ 涔6NeRzB " Ǩ+TfC20mZC=*_= >f)r^h\w@&C0q3֊ .n+u*aP=] ۴)T 6 n·_"9OVFj*y f9nn'@}5u^ʌGD=fA3/nf!* B 6FGb=K^XM9.3_P`51n\cӊ4njvC̵}OC2N2'ݰm5رg!KI$9ERaU/&Te$H?c λlUh)yWv͑3YҌ:X"=qKe62[35'rB̹ΡE_Oš L4EhQSg` 628$,"<#gcdr9 ~ M!^;b:{9:j( T*H cȠ== :z ԃt8;-MgCCBXs"hUuXz:aXPTHe1Q.A G)zM p1qg@ρ+R|BRZzYI.h#tGQh&|axas'ȩwdJUn2L3+)P'hcjg5!mRD^^Sf-+{OX5yg ]vY>aHZfZ$LABĂ{Cj$$jpm\CB` ^48̜0'j lI˟RمНX5ˏV. SHfN6?߬:j?TZ^4[G] +0ؓB[B+WʴFVG`40qg6% iJ9Ui<,9c]HW'\kYwMu@k‹Z.N+1|(O$*IQ^ V? Q0MׇHh›1dS_|]ynp On޿3qj^Qq1^`EzzW`!F*Kpy2xY ia0K?ױCDns*ҕ9?/c!9Iv@X9ZǺsbNc;?敲KN>EZa;V,J3:Ӡo֏Nfn4g{7$ R;8K&?nB$Ԕ8݁$Ѡۂ$ .2Lԭ}h3I×Ӊeĕ#$~,aF!Y.@qbܶO%Sj!i(C;C0_[-B5Zy.Wf!`=yՆ0#桜LCh[J1{!Wbdoa/㧵Eql]w1Q"`70nŤ"b8yLB#jX'=%yrnzd)[1Mh9'IG-*mLsOgt?+ZF'ϖBF{(VSzŹy1ːΤjHfV=PMW}"Ecǿϔ嬋Jx|\ND.c VĉA~`]ވ]k2!cNL 0'O-~څBW{& c9R5"V`tPK!7803;P!k/Wz] lr)h@Y2LߡYOa w^ja *pJJXjRdx_<>^r`HojyacPVmͥEU3d"#tm$ŐhUyqZ\!.҉x>k7Pg$ޣ@U8NQ=@;L2Gbi03v\|5qFj3ѣOj?g3F6yOM!fxAø3̽7Bq/~6 ߚ8 buBo2f{VfIWЙS Ļ.6锄h(4r'qG]BZy*VfM)M!OTM:+)yc-B6q2:Stq?.bNB֤c8n$~8bm-}lQ++3L.bx2rhx4@1?%v,^- (3p#qaO ,W3M(B?vB' 2RV5Vk5'"AJX?d3s2Ziz /p{+E(n0GO L5f-:L_\Xee@֟'Џܢ̾ӟ.\רlcʵէh7nBtC۵+~akAbR8!V jrr t+cEm \|m5.T*jeE-GNfW|?9_G͝AjI}rE{èW~CQi闸[9_Tl@.+gO*gF[aq{K_pmm=8h4FO:d~lNjߍ֎|~zV:-x4lK_9:k56?m7_.=KgO;JO?m?>~y@>yxӘ / 7/^_ꬴ9y?X.h{ay~oJW;NjG_VJ'$EN5~n7ꃒjkm󶽲⥐>a3TQ| /D_6Oin(x$]vWJ݇ýRҗGd lvit꟝;SY])Zj+/VxUyR9=rO7o?zxZ=֣s͇Gոmvgҕ,neYeh-r=X&:c4K8TqƧG(;.We&i\XW_&t ItDŠzHBR,ߌdLy\?6׷0_>= Kf15A+όQ% r"ܮptm"s:+j3 3Hl4HBJj+9ɬO Z1fђ`4ˣ7x]eR"W|Br3\U'Ʒf~ft``}umxP R{H4Mt|Vu 7oMr'^ 8'i0?JG@Yᯩ|D/:f90(C]/ik5DXί(N9;U7N,N-dK 1<f$;WW6 eOV|^Yٰmh 2M*VrN,$l8p" U5x#n~(e[Ҵ?VF;%% E5vF>{fGV2Pț/.E1NU" c;]]w"WVJˏ10(Xrh^ΰ.0?ƟJ1"\4ZB'6 KX2~F[ԇsA#gY4Bo5h4򦒢O%lwRBKUA+B զfv'J<>޻B 5;eU#šęvK.,"wBʍhl䩝G2fQv y/IWKt Ï sٲD+S<,*tD ,xS5.h)Î#hG,zڼ$Pr;xn+`nMN&7W^Z2.`@6M>=YB_棐03B ޳dJ6?K#=Q*>vdt8+Qz A>Mu`7r*3{mz"D۞ޥcrE1ۆ6X  xNks̷fSpSd=\tT 7xX37iNjYDb[>鄄S/"c Oq#%; C8ƩvjHS`8(]p]J̉rG6E1K˱Aq4\!snEJ9q3&סѤTCGvHA@%8eO̱5H$Giipl:%GaDuK.qO85žж1`iFN|b9I7 EPt]_$U/DHx: "H탔CHQDC jڅz$";92@I ZZNPgKl#!zl bl$d'p&4rAB,Kױ4 9 `wxoS}hO*T"Duɼ 0B\xB*W9ZBϩMl 5=p{v9S6|A=}U(4|rf\ԈjS4@R\p0xNyL]_[xqh,7 e}0i׾D 6ϝ4Tpܪ qx1RQ7WG}0Pٍ8pNNn 5ָhdyAYҩ|3?[:,4?D:7%[rْJK ^j wBKO+Y3"LO4_ 枷nA8k" Sx ܫ!4$,֌[ x!nC {/gѳL)Ń\$頧T*`$ {NH"s>EWM\a/* -9yf7澿v0.ZMxnC26}$⺢H'jJӑ'ezݨq%讀nGyw"Ø^ƜЮnєD9 IֱmCsV M'޺jHpTv?J)7_b5.?\iOfsR&:hT4AĤ`!'r:b_YT S [j`ȸ5L -=Mʎ8$#Ξڒ-%v%)vhc4@jT; 8ĺ*T ֯Pw%FbrQyBc}*aa{-^.-{e B:œAGn¥ruJW;Q!_~C1ZoIb ahgHRd,$J(G_; oeP$&گz')| e)niKqȁۉCYg_0nǟ,eN>90nEz sԇ]sطK`9 )gw;p u*ū#!БSO VE+uSKxh{N[tz)~OlMdIN0.ߚmLﴲ!?4HҰH1:ә_f$,*U;EMSɉ9BLx/"k)2M Y&:J /Q1GH?oz{H3@S~DQV E""h۩鶕uhKmdWb$b$~}rG*зD#ߠ˖b)%=M vOjڡGֆaJɒoB'x)Zz˿ٍO7mP۰T:IT){IvMٵwszHR棛~ߨ5C&2mj M1{i eNnM( Bljt@:w$+hnxXLj/N*w-ISZ9H|x=NQt , Ql S49n%y99HL N"%OXTMgz8یP:kU&v/RIͨd:(+].{A ]P ȃMBؐb4gDWBb4ߒ1X| VմՂ*,Emgi_ \jCg)B2۔.JL9+ik$@w`б ;@s>)O{׽a &ʚHb3 ak Ew]ĞJvd1{FGb3jL5*xK-\ N#B]6׬1`ې!XοnOy ]0uW{pSZUElIy'YE&!7I9&dp YXHTVS(|oPb$j=UDZ.b6Qs|d[Xx#95 9U98CʤE2`N wc s4")AJȃ7&XJܭz q qm/ۿ́r2)طp4Udx.13U%~q'r㌦3jwvLO]Zb{&cZG5fajTN-~K7r hxe`ݠ\'1I[6o* ;!F;v$"Gzxb _|kG|79NvؐTLR"lxq A9z)'Nʞ0UVdYr: ;1@k 065P@?,cTf'05:i ̍t?;s_jUO.*)Lr 9J;N@x_ Q[}x3DEfT`e3hyʼ? Ir P[C{ n-‰W[41/C^z)wu0km}OwjE ii9:ZZ`j;OϨFRR`O%b`Crgحw k,?h}6Uɪ[*ޒB/"DwY/oE􏲝XU^Y +X\0O.P^DLԃݒ l+%4xiPr ;XBMZCP3*?f2whȑ,ȷUzt7Y Ge)yeduO" X:UA%8MJv6p ԗV18<φz50[Nnjͅo oX )2-prBoF7s*A89XuvO"/tk0 "gCȨ\`xLLlh4K.:7k,^hEjZ 4J= "<.F O*;%k"O1h3\E8uɮj)DtC16L\f*002^` 1u 32F=Z'%c%Yŭ@g|LDyAQ &!;t gUk'SU${nZźH›' (I(su0fJlfխ{rSEzd70^4K"۴Z#y-:j? )NS.C? ZOlqV0=Y&B%-g41 ٱjBIq`Bk9Q՗na® %gᅭkFٺvђs=7V7~`EYUBޙ-!R()!6$B;2]: b41])IуǏe-.K;KS*.9R&kE•vlgk><߭L$(Ld_uWavnx{ᝋE,rP~zRFOr_,PO'#lX$#&'YjYeLb&s1ÚlJlXKuga* (<1ZOr $y'|3¾DG<KFZ39{e٭&F=.MlAZ𺈜M>6k_A-[4͸b(Phr8[З8ۨ 5jڊ-w^L8Fs5">}gwL*yg~vpݪ70s9xڧ\w GFrF tiw#(+PRJ :-I)q>\, ^Ahich޼&p|Ca~AZ5|"E{:\dB1t^N#8g= ;FH4(7'TXuHk>%$jgZ .f.,gpA6[Гztc]=tg6o .%Zw,eHNt^/nƥsiUrJ"u_y:`i]Ĥ.A ~?Jԗ,ZqVd,Kn(SH8n-M$5&->%|BT^{&X/yJgBN?v>=t-TYk.[vocUMT@7Sd^K݊^p'aTsr !(̮Y aRQ̹4lZ0dVo'&Ƥl>LB?K30! Eԋr5y_Q{\2g 0Tš*=sAںA >jAIYBN>x/+KDQG *RܩGQOWU! ?0qOCVLx̆$D!09{fQs _وuFTɀ ٽ1y$A?&Yl K 0yE-Γ;Uv@x>Z/}]տ.'L02pc\vIQ$i 03NKYC"{^(uT*Z$ %&ԅQZ\8MM);+ G% C('"XѤ %lɢk@CA{>Ch!u{gSwh`w52)E="O"*3 Mmovz$ĊqQI=.x\Cii'<ڀĒ|t~֥1; IdH;FA8pҋqdFM² (]p%s伹kE2$J aL#RޔX;t'!cgrk$|=|F oZF 4-}lRNJ!(GI8ɵKIhxP ~[&s|@`\zbX:XnfF 9mxiƀu ƬVWdfsL@6|HZoq+>|9#8ت )\(v?Kbo  W9U,' %`~~bHZZA@@n(js h3:GdHHt 3d^C࡞0+Xmut 6Hj7qBl%8 #D`Uc$;a8m}m/ڹ]Iʉ;gU(QyfvXe:^p*;4XDϛ˨=``\b+L]) ۰f]^1d)? ܁ } +uMLJVG2NNό9]2{(6a h.lb42^,x@UMɍjt汦46\֚0㕔i |wZ02"U%ݞd;GMXH"G#BA9bB~]tGQύ/_p9}tN2n`Q4AŸ$"~uutw"wz:-d!uj$roREGz#Lxzs2EopE5Eyrcp-(m L"v3A0K笲KCH7-l4 3 GY!M*XeQݎqXz+[S7|vES#A!cITnxN)Ϩ؏ Rk-Xwɵ݄ Y8&DQ~^vj7)!WQvE~VFEomƓ\(gME;kdƎWw(k#PSUbSVoxiTק s# X3N,agEA!VutpR]D_D92*!:[Xc!7'c,<Ѱ?iff,ɔq-L.$#NG$COZX%io̬)}}ֶ*3wKɏb΄)ྋl )0ݖȭi\DBBʖ~<1B܌$"X(%rI)s6ZLP@UАo4reQ`8_qy½v+=@HܑA1O:oSS$*m8gl*Ҭ:1yab>UBx3 ҆i8IYٗvs8-rE弇޽Ccv9gQ`zG.4±NFɂ9Ƞ^B\jP/ЦI=&>pQIѬ0VW1/NQ`.K_Oi9oJY@!97AI@)nEɵ4#R.X~ٰ߯u)6q\ pe"nRkcEWy:\9`sCG!(kB螜|#VzB,,Ȓf.N{/K"f( , Z%+DnOL/  -L2Ġt`)%Z0f&sc 5.:%.MD#& %/@þ B*6 8`ȏ܅ZCi֝; )pY\Xk39hv7X]tM1~1aaxi5I8Uw#)` #?LT/1`c0^a31 )m@Zksz{b[ !F `9^H1.ِ`W*rjc kD], $h,mRت&% <"S=/9~ Kf]Bd1;ɱ2lFkJYrPNIy1ݹR<8i1G dWDU%w=ÏX\ շ :wZ(!ŕ+(b.I -|1C.BtL~|yz4JZ^lhrWN9㫄EmDJSEI}'hԣLA# Ko)+DI>@G'JdZb<_u]k3UBud ۫ LDɇ`4My긂Ž q<TvsQ㖒4Smbu9+'%ݘd3wqN0< `W4odQHۻ+w,ԔnJ"*|!IUHS<|f6N_=}fl̽gGhh:5bt8  k/>JI0׷nf]Z 41ffcnvd괺P5H\uu!KtSe=0dž %m: Jj6ȼL-x-W- x|&χ9ԐDk5EׄNa{!ӻ}gnN!Pj=B8!zLBgȷez>q@7`M[`,RD-RSꙗnJNN~%=޺Z618ؙ&m%:b\(okH^_}rfI"nz3!TNOV4 tح k.;H>O0l"Q{r]Ha9vzEz.zY lQ\~С!]'#~06p3B:m m0m47j IWQ|^>S #SaHSx$u, g$&&ކMn#|R/h K>[Eg8J޿ v㑪A+B'#)G9sh;I[W[O4վBdZA8՜ٖ,2\E#I ekQ :ꅌ鉛IOFXYӶΏY 8!I/1qDΌ&ġ|P#OGxlG*baX?ⵏn ȁqOܠ^)D=d߬s0\*cHK3E5?b)s. @@#g`5>}~5|0ȟFr*?} ;Nw/%$cqrOF|I~_'xhC ͬopaN)_Μha>U:d /8"gHkWN WևRpjHÕ ]b`]846S`xS~&QQIS+Y, v:jc] dhV]Nd`:RCjOd|< /& s=<V~ܥ1wxwCr=/f艰aDbE"zNe!%QNTps#/DJy !X xḞ($v2ď\E Q|] |{pgZVEP]]7U,BC:5OXVWLBjQX73& AC,Q="5[  "/$ՊnF}8.K#8P O8f~6z0&OZhcaTB)Ki"kN`& T,+\9jn<@|CK2 : sGH!)o LQk.eegnTKk.*섖=/˓~>&_)h+W57bhe%/jE mNwOi %2quSauIx˭j޶`=8*)$"ꄺ(gNIDtq  wU+<NN?>n~7.?;؆ LC1kla .W[P0T@'xUrd, 8-+C)oŚm4PքOmz?7-rEk?mݹ/KЗ`YꧻѿxW֫ǀA@ vKAV2 sI8HM*P<@J)7F>Mo#AUT !7Qxf"1GעB(7ZS%MK~s/2R\~6槒4"_m7ILuc*6\hhl kPZ6Z81҈-JW-{J}+Cͨf.:\\là7L-Ւ9d_U5pDT6xQǤgaNݺPY(@IWaZz׎0 L.G(%`_s]ׇI. !qL|; 0c-%HAeoer;j*TWc&sgot/TSSݏAT5Ij'0 sJ](c'N٤w+n@S4$G"|+ y ~yݸt]Éi[D́HKz0WJ3JB"EJQ%2deI)K fP\s 3'?+U`SM +| 蘶@NVkTəZN 87JG菶?>RWe[ZYj7o=e26["mmj}=L֮a%4h&(]"&q9{/i̓Tq*ˇ:Mi}^QFEؕbCb$L,W [ϴ,2,G DeG*Apd@Jh7 b߲-::LcT+F{9ڷ K#tƈI'[4S*v:3拏HCဏ sg2Id-K&(d\]yQ ^^J#wgtAKs.xg`XA>Z+MN) 25ʌYA }.*7̄$`w%ۤTRry< U Utuߜm9 Fy$&S׵8bl̼t̼TZ[ԊҤͲ:\ @P6X[fjNOfq HSAxt!\X%rR3JrR35 St3R7_[Zgl4Yfۖy$?H@x4$ XTU&|O~˫8/. 9%V iyաA: ~ v`|c!| iԼ0ó$5 j& pl>ß3_ bQZ~NJ=f *hCD&+L̖TZ9l杷,ϦAx4 Ό]3N)9ydUNg9k8b! v۸*"RRR2JJs26L玶pP0TQxGmyw&g$xx&ޏ @9!-()(N)f ,x{>urll v Փ 1N~f>y"0sbNdvY[ȮJO-OLΉ/*IՈVO+KW_ɮb+aUX$r(!pQ*1,8-0Ӹ8'Psl 겢mn*#64"“YRR*'S4aW~g eOpqcs &˼ܬYwE FS5i2Jz xz?'F&. 2)*楗dhg&ZdT&hT秥d(jN_>e!T<ͅK73Ӈc"aT7X$dZhYTR_QX\\YYR\  ;hX];H&8#3DV!5'575DXGUSg|+jRR rS52sRsSVVɹ)J *J: J1yJ@RKJtr2Kjc7odϪt+ Fx١QAmx[eo L7X5&ݔ|x&$kr-7o1o 6, Bx< T[וۀ`f[`#Y@[``@ &_ _l$mΤI4%]mF=I9u.i3,%I36ir3i:Ju|R޻ۻᄏG?nsrn#O|f&ɧ0'^kػw/_']v,r1ֳy=  O8@7mvm?ioll:Eb\(fZИs܅D˱? &!#LsK2 \46;8A;U37-`$܉%ryDnvN8;vPr30g4`BJ^ υhјv"2D VT5Uq* W兵 I=^-iѯJhzLcܒ(Xi4#@)Mf=oPg cTb <#r' K4 Qp CTHP P2>-~Q:җ& 4@@[Sz,D&nezU 9LƨQ;$ޘn8$dC`84~C>\ G"Y'jMC8m C<#A_j%Dq՝6+_PHpdV%h2iXiWp+hgda$̕eiX.PB6b8R@ xJc7_ ^T~Xb3猷{j 7mحj)tA<z? {WN=}Yx^v&H҂"vyN E[DMcbch$zp R|ظ'(Sھڽ!ǚ%€.Iw| CP믗u34wi`i6jIZ8d})]#8 4Ua<@gnAg|bp!(.+ݙ2Yk}[2x$!80|\!:B-̄Ll#3V9ZMwE=aAi'B0ܲ\[~j.;C ɱܴ@|f 7U6Oc':z3Fb>gCk d5"0̺jؖ.M/Y1I76{llqk7ZjHnvF@A{Im-f.HD BWrV #w]b{hwf1F`y?hYd l[h2?絴1Kdv,| fiZŰעY [V^ˬkYX"14hζ[BA4niM^KbP햦vJ<ǃsoީS~4t^G8N~r":'3ݎ@w䊯c~Nt gKS;9nSw:[{Zl6yx"BÊÜXX<pKs+-BdaDcd/1hYr.m O9XfAmb Tc#3+>#>)YYYif,CS\RB$v $&Cg4TBK:&3mM31yq#% w"3cm%msq? &ͷ&Zݾ 3ĩd|ö홌L'bͳ}dȁŦ6hGP!E@K$dw2jG'FOߴ83U=\vQbCtbcsO ;Lx|TP@dP [<:wxc3rr~# ѣ66FǑ 76Mq-sw;Fں>a;xr'N+KB.\Mݓ|Nuڝ+=qeamjy[Xj( UW/؈(qRe?^^KMpl|-ܼPZeCYQI}Ydr,Y$+tf ̀ڵ:i B oզ`~tcA6X 1 mQa줼-tURוm[薮(H~PݠK}|.?=Wg>f=J#<,2 ֪6 .\^6n9LWW7z4 r6}l|Cǜ9 L9xJGo)JmmeCrfWC.1_h۝T6PH T#Jy1&_Ρ*>n nruWqRuJ 8ն3o@~F<9Kˣ1N>J YV숋p7 {t׾ paXv0PpÕz фItof7>T>OM՜cυb{e4}irn/pz e4B 0%@KU)L@3ʑHɨ) 4=PJ -0: |pߣeI{%U )A__o6'-*WEG4P؁]d62<ɳUT g@W >ycB-"Q34AdUbAeb>ǖMw'Gzm!@Ce"DC 8Xy.E1x|bX*B&Pᛚ h,6[UҘ" Cg ^T} B,!0VlxJ4#5\c0c _|6@P<<3fЬEYiG\pc7lj*2YcReƬ݄tMh)D&' Md´2t1FdUd%8')ü\\^ZE2LS鷠rͤK,sujfѵ! >ތlVVl0~ּjlQ3O㳮4Ejw]Hh꼍ti"1,VjV5r1IF5'ƌD98rkG54"7.932X9y{5!. >Sp@ {>j0 7-Su/|fM>pLild 3I)8Wݎx)>r/#pm-&""1$hbs s7 pF#WłQt GÑ0aN(:^P=AG5aʎ\‹G:!a= b$`]#c-oN0za_BB#Z޵` `NyD@"Q7rUwwӠkՈ*E4 Q8,|2Kv |2 ޑ|JUE~T$IOĢIl(=it'F*n(UwӚNcBMK#.XfנA!Z&VT )5r^2ࣼK9Oj_1 ?>=JtdxSWV:*9(m5 30-i08e2r;òҬeisʒj /]3HFtP?PZ ^V)rp]+Y&ܦIG_2RPs=nHa6t*4e1%CWQaI R\?p2 Dxq82jtJ{΀ϕ[ Q^6~49+as=Ţ=PnFV/p(BmDVuں֔'Y*ZWXd1Ta.daV-U7[+驠 Ȫ@Nh!y.{Mp4u9Q]pT^|، A T:8]cδ:'lM %=@]Uiv%AndjUj3T͞s4ɗ+bmjȸ!u7`GhCD,]c_(O_`OdUp+*0Tyw{oy̩j6bSZsw1t4oT.`HJMIĐnR.@j̀=է '?ٜ> ,o ³ը%\ \~~b=Q.ROZ߫Derےܳ JjcET]Tw꒍Ꭴ}'eUvoXi\v&JcP/䂪\ o'XE+3#f՛jjmF*PM.|Q^laR)x茗@SBs;h/4K+OiPBxmDS!t_I76%TU7@/]qi ʫ7In /d( Y >"*?yS tyT 0垆&W60Jv*o+q@j]&i7ۃjIoGE= uύ6j.ݔ ^B43Ӧ}sb\3gN$e>3j+>%|1g'jsjʣ kwƒ^*_1g0p.GboQn_ :҉5zOv$FxyKF !V  r]!I!g)!pڋ, As faOHfPEw^hX2*M HjOJ\KDQ5T僾Hˢ><։ݢ0 6GIyit. Bua7%iQ(sK30=}䨊x(BJrk>\7>;μl_N; hVKh]d&4fT{O}ۜ1#?mr ۖUni֒9DR^XǍiJ-D gkj‘tZ tPڝ5ɓ&yL@95J(! rU*q N/' 6T+DjfKLkȜjZq_Z9 Q7bDfL" j)o$<xN ng:lt1`$" RQ>aaCpFyZ? _]Sv DG,`#|`c!YP  %ߠRf4E(a`rSάhȾjhTvm6.Pa/0M*K+ B)>)xRJê2$(r@ň(r~MM< vSLx9F)1B X"Pa gq&`*N<2G0HywbWhmmMU}-= UUz*g  70/O-u{hI Ôsgm-TX{vkQ%$rq޶= q&1A!C-ޙcpTVcnP _?שEn6Cޠ摝 4s؀ȅuXrAi܄ʽۉmxyOؚ:%tjV0xfBfFC=eWGZr;>xO-1 <#"af bӡ7YwfmFւXɞ jH&`wqQIMx12˥Nϳ#Lڌ?LFdधJBEVS΁x2vӰ5VEM%\>:޴nKo )[Z` Fa&y2k@ifLmSC>/OSm WD@kYQ&;YwAlab tp ׍lA"/o4|OS{L)ry=Y R۔i\`CW >ƻ#0>sk2^hWcN/"1̰xM@Z ShZ\΅(òE\nX+ddTux׭:mtT[|K>;'Yg]L A;̏O؞pw<=m1%%׉Lf:nbh3. Źa/t['#"G) B |*T/Hx\)8ÄnIbUCʞ4@T8ѤyYs~3 D_3 3=p<qg3pYJMΫ.$ԅv$3N}Nlйf0-A`–b%GLOU 2(xXTsA+ +HnmXRx DҒJhͳYT,LTے֌1\Yiz`+Ivw3 Zf6CP<;8=kbepL% +buli+ FnzuG MU°Wnm|RᡴQbȏ {@;'&蝚%rUĵ3OL=T"$g|[gF8ɷLIOml%+^-u^iٜtitOPhUFzj)n%.(|T']D>G j'yEect#E߮B)W Jk\vt[5髅HD4:"+ "G0F&R{ư"(E.}=AMbTVNT)jEXA66v G2?UM EmP)U@a˧ҹZT CSzf'݉ڤ%baH=PI2#]ߍSB^مQ~z+N/O̼ɷ xS&x*h_Z\_  %: )i9%0YBvjjA|IbRNjqmfϵg mKE_TxS]lUmnزVzYmٖV"Z:u~̬h`DZEB Ā!iH@x A#Fr+@bN/(AN E:YIjO5Z.=ecvE/|H7vעNSELpϦz$>j'cz$tM|Ye['&C Vg!'&{"X,h"b5 4}6'rW9YK&s5pc^/)Jz+5uԵTᏖZK(!uǭ; N^uB Dyx};D`-[ [ l{[bq8~$qlSevb'~;ق i~"\A)F)s期?͍FRbb`q ܂U!GW䲱+n8ZAU0ak5r gA\mA ˣ*(p4GVi<YNFj[Y5ܾfL6ݔ& c1ME<\}ei-ǭ¹y RgBAްzQ*n$A_qUnY^\ÒVi18qF$צ\[13wfCQfmQMZP_eNE-_jy\ mzN;rWMTMc޼yE,=!(>jӂ_2K ٙdf%Y޹^e ,A-9(s sD#1c[&c6b;KAyG%M6Xq ᙅRd)]csROQQkQ︞JS(ɲªڝ9 UjTاȷ K }໏%܏Fô 'a %L_~%1#C} yL %N@]Ьrhq+ivYymvie=Y;B&♣NFh Q[O%A/Eaf)*]]됲ʵfj=U7o=O~ճ_*K0xys ~LO;ʾ94 WxS ~L]r&/ۜ=srQ͹7{nxVaoF|VHFHTU|@% G1="Um$zmLC/HDn6?l6؟td2rncNWULCe `A3t-r%,]* Bdϔ\1 h]ޤ_bDL(&7+ss?=K&RFLfq:hL)m9l| mR br?a3d("aCwȏB'鿻hR&k $rEr<:*5dOk0L¶ ? CL \gpf*M\p^t;ljF"b+0g醵\8nlԥ\X<[}L R2;2[ `nV+Q6~w, ˚?N(fJ`i 0(I)Ld]pWLٳ79F-ؔ,φ{U;%nᕄ):"ӹ:!ϙbՅ!K+~+~RMsZRE[tsy'C^/Vdy8Gpw*r'lsUQW: ?$u>YDa,SlYg Ru=&l9>e]qP.tF􌰒տʳA#kG1 k/ODޓm٩2W95?}EIƪ:Y 1.xk79Ǘ~kePչ?Ζ=Ւ$4%H zL\3 }uh9~$U%GV+QH^3L)Xj8>%6< ۱ڈ6 VCs 53c)h] dal LZ-Kw9='y2 q=ֻ::N "n1hlzx-[tB.% lx-[tB.%  m(x-[tB!.)}Cgx-Bp V*)x-zHpBB@Q~rjqn:&I\`sH l,x;$xPpB-zg M~xXmoH(=7rs (npOgC8}mɍ!骧|rrRz ] > Jr 2=ތ+C>P||!3R뿜eFP~^2PLO'9/{=Oiuה/yra銏^YN!EĿwt!9 t/ Z^WkUx ͣlJurN 9eL6\#"='NE\?}(4n?>'yd n}0"觑 GsrVЕazH .LM LZ$D+ϔ6>$h,RW9XA P9G#NqDZW4?;ݐ_f߼~=4ȔK [|5 sq fs~^\u}jRv.n}{AL4.1Se/S>>^Zajun/?A{[\\i9؛Jt(0iđ"?sSP)DR/n>A Hj~|`Po{lzڰ7Ony}7Kp.c\PN$ ]}=,>q]N~%]W,ymqZ:oy,[YC~ bŔ#@Ӎn~Pd*fd>^[ws5PՌhBGuyǓ3tkFZx ml[>,oҥ?,!wz.˩.AE nR+52ozU'>$,,72L=ː/\7DƩfV)HV_5?a2393wZ%?Srj)iaS(w7^ѓx8'm}:LkT*٬<;+pRlD;8u%-jR'A2Ig], /óo+bM}ۯ&r3pBG%|4 ;<mV┒Ǽ3 3Mw{|4$Sx˔3RؤҝG|nz mӾJ(^HsK<,3;o~q?:ݻ>]4onZ͋o>5]Ԓn Ks:bϧ5Csā"Q/ZBM4@8fܿu>U(9:Mz 5VofѮq 6Tu=g)k|=,3|<ߗwi}aC-cwf{'ۯ"!I)UnjE1_q4[a&Wi{/N_:i'c 'ٹJXWG{z0h+&5wvK;* ̳P=pSG5lRz襏-҂GD+_Щ5J5`-i-] c=C vl1Abj&h;n|Z7: zb8 Ȍм>I:0$TlL_Ǵǜ:n91p$~fg<0~#EP&o @괃{h?uE҇axۧ1IcO͊lEɩ)9٥X6oÎ*>9W"5cxۧѢr)N͜Secu+rsRsRsSJt2 t\Os0g&găjhNWpR%xHm #fSƵ:)iyA~N: YIIE))%%Iy)ﱭeS\EVSA׎K t7qٳLƧP`2*=De4Ţdlf8y+6`dl Qw:xk*AQ@\HL0J!)1%'@Ae.ͳs2o6^˸9W fCl;x{ u_j7ffٻx\ysF[SZegȒhV#\Z"",@PG{fpM̫'; L=~I6` 0ohA/=+v{ýݞ8;B)\f,K8M5 c)\:-N@s+C݂>G !I_E jrz%´.bLli>8 ͺb PEJ?߮aA]2Nno}~D_E$|KBCl57+R?4@g)l6$XAk@DJh%= GMِQE:qک p j/5֎@(^j!KF&<~ln9*"hĘkznoS%ig$8ך /SWZ5~{WO+v#@-=E v nfkpq-5rL@e#2$uJ_頓Cll6p ص4b6#.!Dc7Z\\D&T|lj+SE.@b/6z~F,JFPع4>sIHȕ#?zMۂ/^ wxn׃ 5@H<U&]{z>`h;7W ]3SSH{dd^!M}ySAb7_._*/>f;~08z={xt`>ӀxT; S8.05"k}{{pRW\. +NAwh` N_s"!pʴ΄Uh^k2jO[qq{Gv̛8mm5q:/}tbڏέpy?FWd[zDq2(]((NKV#7-۳{}5>奲DDAW xTܣէEP@Oi $.{ ƍa8`,Jؘ ~5dzv4J-'+3D4Ж6yvL$R7|I ܘh<1{s|~ˆS_BݐLp'`%UIcb9STX3?H9Xٙ*#2W2 qcڍYgHr*!~Hvx  ~~R'uNx=Pg#s((FOcxf^kIZ'٘K};7.GǮrzTr$dmJ `rX B</w o̒B Q-_ӿ@lX>kEB/rm)G3?on8(Q^PZ5%OЪ(4난:',)u]փlNr=rw$f({dIQKll@8/uUb\.[m8Xr*V !".9tAR0#+ ei]_ ع|!Tőfʠ`j w y[Wz[\[l}=ݛÓ}grO!(+ɳgx߬,# Қ#{ymkׅ7H:ens2~wHK7 gȆPNgXBe&r;1ڌCEE>4g]سtH_OoDvژ, NUAr \rply{!.# Hr@$y"f$[S)!uF Gviґq q`+}n,GtqAh)KlP^ep~ &)L,f#N LmH?:ͨ}QK)SaCFs[՝DВm.l6ū@@coQ{dPwMK/8=GKe`tK4=E(A:-5hS@3Ym Jd tfQ\Q+/{TvYK =GrSDV*LeDIJtVrfmeD#`R2M_e4j)d>KThDb R !(uqDي3ΐd?9aeõ诩C*Uxnέ K_ sV)G>FUj ;;,0ֲ'3I!Wyoi1::Us &-{]U<PkapqH)̣ ""t9oiĶ&t+ W6cS dFh'4sQVr[, }dEQS 9Ezp|Di%sd;H&n֥ȶ&g+`{>IzZgLnTJҎgQrU(rTpBÛ;bOu껿$Fo(GD1ŋyxdZfDŽД; EK l5kڪB'eϑmgt:*$[=UCUU PLPwAQg:˚gx8ž-[ARe3ѮPNL{GrOޫiDkQe khzS$!zNH5*HᬹIs([52oϑA E/prţ F^r:|uwVNCj5g,E\Jr:iS+ ^+MK?xUG8řEm=ShNɮQ~.Fq[Oȼs`2ᴑE*f^BCÄ2z6W-2B:\01pFHXٷ4O={hϜ,gDQ4Wyw^14d$;+1n\0$9y6]刷bFyoJ?/l^qw 2\Fg%Q77 [9k`xVV8R0{8OUPEłXOɹEa]EZʵAmM1k%mn{(Պu DQ*oqPce"*D\USUĀт0o.6o*\ 2g;_.`Ņ<5[g#v},1le%}7I0A]@P;F(qȉ92OS!x ;_,`iBYIfk_h*(S˛ɐ!jln)3A bB1P{f64fB]Ph|g\wvBѮGZnw&fܔ;4 ڨݮ/5Q%n- !ȑ:tQ,*i*W-oe4 C_jGb?\SY]ryt.}T0F'o,<sJGņ"Ҋ hKsm,<yArCLlD ث\tAܯϝ#A* I:LJ?[:tn-˳fEĸQ0pTǕ5<\Dn W+uǥvEK3"Y6 \n jgmi0#Q|IZ5=&Q>CFYHY QC. D Ҭ0py` ' hۘ'7KMKZ k+Ӌy-^hqӡ;!مXUf^4 H)sWaГKXshp@u%r^8V89jP08iu:Fw^6iu-OΏ?g~)jiVٮ;9!; .14LMAc\uxװfM6"Lbr|]K&bI]A^ ˌ@ruvɉ:Vd w_ ?ϞB x%^IY@^A]W;X=7:_gk:Y0n2v;-dP&6b^_l#RϧDmߧ;"R^>%א~ ! {!SJoTiE)w9#%ǘl7ӪfVjNs=?8Q^<:*^sHDVJGP4pl(% X9%h$ٹ-G)規=^Ns\bDonTHZY:xcAҎ|Fe1`";}vwҎAy^f}DڭQ軾]weZ D{  hɇRQ+xi;57.r,?#Mc6o" Ham3+baJ"|^,\8 9]f@O T:UN<;mRӎ`r.j[Hdљk6@ExC=\mO@ó$hYrAv[lB Ty-xaʄpM8f Mv_'I0`Ux{WFQ>5{ yHs5Q!Z" !`ژ,SVFDx;xq)#f3FQ4v 1x;q7 'L޴هa&Sx;q)#f3F.N ǽi ')xɸq_6sQ|HP n#x[qG<_1_;x[q #f3\y[ "x{xqC!)""r\a [0%IJ]]]]*ٳgWyxR!׎嵟2nN](!o/e? ȕI>ƃ(숁s-E X8 T8JONrf,NCđ3;[[#:eV& D~v:{hFQ_RQm6{P?e6'[e7R$Q7sb+FPN=(;T 7ż0(wGtsz2i{q?QB,C;8v|W 0IDi;Lc!ށvQ+籸qbG/˜hUE45~$\[2Bh]@t&; l^_į?b4 OT WP8vt-0{:Dx:xxv&}qzj^|?''gu!@)"PP h(“IO89GJ9'=|D5,+wցPL/ЭŹ8 WlH?߲(IGIx盹`xQB8f͎0C# )W=G-Fa׏|Dɉ2$X ^lTH3} = '>>ۥ ZVAm˴ZMk>Z"[jP(/f+˱'!:ɗC8=?!6ij.m&d SMxz4^y%XZ^#3%HҔ WOq8 l 5AEs܈]*3Z'CQ`Lol1cNU6 $k$ī}F?^ureHkW. hf9{yՂ_8l1rXWclAEw+kq ` #ԐB C&Arci&~He61UY3;B [( B.~A#nY9kQY RWX{Ua>aoΏ9ɳD!Å[G.0anO7!W'&gQ3 |\D (2tr*ϽoiיCjفwb`ZO !V vKZf੍@ZHlW6pY(WUk6,#iqij =h11%[XG-vD b獝[s f/Cl2 C>4V/v'B|=czSn!z VN| [ uOR:!Vt0N':CH0 Lᥲ0k,~k)g8͔3گZo, ˱Ջe`DO{PlV:3d9 H̞LJy{o|oD\p`B@Ԯ(x| u@*i],O$֐ * |" +! v&<vE}I@Mև¸M k.Bs3P_)šص RKfLIAQz Ic(3"i}U͊YH\WA!N<8 n DB+\yAG$*;3mvF: XH.`!"F:R -|"?%*oMq]XFu zHzc\2AҠD#?oe\>?DvR Er2@^ަK& h~11 (>uTHb!8EDg]έ3GJ(^b"2؈j΋*,v I -9#}̢F.Z*`3Oʳw醲"ȱ6+Tq5[O.``huC% wߞg,UǦ@1h3Nu+?E}C ;ÙjP3AhBq%Q iLeÆP K%~/& /+m+" A6p-ZHOefS/llڃIםyEVpZ*J(f#L58JNDqV,Ie6A|  uQ T$PwVϦȟOg`L%1G+8ulCs' *ājF\] }T5lDP+59XxΚ_wYF.J4t OvPӋ7¿Z I("L<E-3=y0 ?ze'fb_Ts;8q"a9n j-ʾZĮ&B$d"WE*s BdZC0丄251[]_ׯG]tգU OQdojm|Է̇P:z"[@ǕOE*“Oʕ]g=z8V&{BeϬr.MggU '9"ãbx2 \+uJ'QyXlr]S䫍YY$i#ph ~TK\&2٤{crKU=FCvx*/"N=Gc Y9(0bt"+F"*+wFgu 9JVa-mOCǷN0m~ee.ɐ ɵi;.K)h'=,Y#ZȘ["Sopĥʸt8KԒ|C|$*AbT< D2IflID~3mwP>ZnVO)GsME7+r+oZ;>+^|puF]Ud1N)dbsyU C fgS"=A!xC=B#K% 9>p}]g#Nm<VNJ`%'wL-$fm|0~}PIVnR/İ&4TӞ4),% 2_]tkd9inL~sg󟾦$<ȠܡϲpO\ORRkZFL(4'<37\F(︆~tcaJMF@Q1hoA,څ'=mkJ DK.(JyzvrӥhO BO99's/B!jŀMZlb\YLcWzP&p{D>mKugrjC4kY8Z0kWNQlv4A̸A̖1&ȕ^XkQYS'sFT@A8L(Xљrɬ?U= (ĤH@Ztq*)23do E+*( c@'R%d:Ƣ6Rer)V"^)(S ͓BfbS TO/B f9"ٳ H?UҪOa%#x\Mj| w"m[!XPӅ';p[B,gsV)W &} _Jy3ǰטD"Zچ貾񐩌ȩA +%[n' 'eۏyb0_`e='̷MD{evieT&?9c^x16F|C+umW]RYe ع(M(N0[{gJ3UP@®ÖeJ}^d>S\GY5O;*.كLa4E؏Gb o&ՏBM3 ,},IbإrjE}܀fA>abm_my p@h]G;OmASYXGsxcF0FۚYНfLn0TȲDM-D!z=~ac<_ξ~)=I̤3uӦ͇)ڟI#2CaLφ_;ٯy;l~%Oȟ6wox۲qb vFK5 x۲qB n7o_Rp x[q| v+&sM~->9o3O"b %4&ӑInx(*%[ekhL.ԟ1d>2`O\|ļtǢbM GGj(d*(D;Vpqr;k()(i@@wj%X)"ũ;!z>sFr>vJx {9Z0y%x{xyC"HOSv|mt\ɥ3/xy DUf656~䏩x ,xyh `ߪ+KR:)D9#59;(P/3/_nwn]fI_+eJgYḘ8pg%o;o~XXAXS5H={u;&26>xOK@))Ta/ hisk{4duw'~{J< {-AF{9bwY!>Ԡ4*C#`.+X8KbZ&Hd匲%kr':]0oXЁs`m=+c` ]ޞRK 6ՉZGэµAџ*ctQ#{o8*ۛ Ry߸pTOFVWQ%b!e@"e~^nPמ/۝C{ZTY 񔽩CK&cy'Kd;LYGMsHd:0Ё`,AcS50]?})- (rQWnInXY"ёj lcRƄt n:%3e_NxZGS h+ؤq]͹QOow7+(-Q8{gVI`z,n':c?&S(*{a1fe/! d'p2'~xU1qvy`Z<ݔ/-+OLfx{rekƉRR\N%%\!%Ji etts2zJ\\1Dl+x{eB"cƤ"0l\xreB"cƤ"'!xmαn@ Oae/J"톶*SաD*`%&ܡ;B&K6kVߧJuˑ#xj*hT%<0e _aDⓒs_ZR§n/I#im/N9 .&򢘍dlp\zb~PQQ!6K.MYixuj0DKm?@Z(ߒdil뿯Zh{a`;rvsxf_L p>=CNd$J<^ܷХɴ <&@Gj6>pj8eHm&R=yjt}O#ǢVd{ʧ7P^ORkJBƎpak1L~)/iFEMRsq]zNؽnn>ЮgXx[ti(D1SFӉ=J\\n9) F\!I\>i%\A%\!\N%%fF\!%J+q$$xErb|!ܺxXmoFsB$, 6.;%NNTI;#VRbM2eCg/v>?3:_'$4$6ghvR~})SIa'EzoToEM[q)IeH$vBHS*r%BƋpZRBr!еn./ ZK5EqMFnrC2@hBNa~uL4zts?D- VE dcZں:Ӊ(Z (Tr`RGP1$DYҲ/zB}ـ C4 zvvm ?^&NM!Z.,%B#(*7u qD"Rdc: ΋0 !vUS0G2`~W%}1E YLRo yWBsXd/Ԭ2k5kEK Th?1Oؿ%2=O$hN l̴)3Z7u<|5Xtz'9wYp;^~P(ϸ(QM;jVJ(Gln[A!F %ʩ[I,VwBY8-yc0be~V;Q' ѿ\)m5*.;|; u tYJXB&hOeF,q  TT~v෕o:HpPDB@8iy(ȓDYQt03J0+z ߱I_6-ѺNtܑBG߸Njz tv;ܫMLRqZ D|UFo(մvZO WS/&:]'^ ~ NG޿>>~>잟ˈ}IͽnZyOe&BMRqJ<]) DJxSqmc,}Q Ȥsx!1 S-z}j0r+8uY^Fi_\1j\Mߝ-}+?[4cbCTcN'%P-k 痣UUɄ/}#ZC 4l.ӿl_4g{Jrρ8ZtmrT>] ģ+?GӤkLX+Qޠv۩vh(9' \9fDNFqp7o*h$+ ʙI)& ?.Ί> omָ>uvӐ}ذ3CX4{]]FW*E -K6n xۥޥΪ♲ѴU,xT90 \w2~dX22>ju|'0(]v`` )lY~ՁJ:~ߴ@94_A,o gj5ޏyz&w45hHț|oit=!7{xis6+;IZl';Hͭ;-AM$C6' 1G hJp0қj nnp@~H/ďBD汿M?Ֆ΃+NoSƂ1C-{#s֋ i GqA'vC{5J h K?hYR\VpQ~fc]r:8NΝuϳ;~x;.ND⥷ 3-ϠG8tnOktII)+$#ȻPNu vG1v-\討.5OڮsE_Ȩ9pB2dȭDfF][7$ r"[ JT96_'n\{fI{>/^OgOD܋ (ݸ%i-blhm8<څqSr }CVұ89?bn\]3?dQZ9zj4UTbHpEuWХ5pen7cPƮdm DeYf0UOg8čb|GCfP{wX62bP9P+Fx)^~4؃x .ٝ>U(P.rtt (&expcU"͠SZ[v |z=2[Dy+k çQwxZȣ,yۃ8{qz#w2iē֧!vB@P5вd M64|NnbϳE4/7Jg7dEgD~-dP2E!U1_6 `)Mc?(Z.>SAhD ډ~DP)ςhmq&?jqݲ$5~{:h ZS,i']B. ʤcJKlLEWG' 2Hg`+{ ͪDŽ F[Q8Cn7DxaD#q[ Y7qfM!`l(YGD4_GZ8S淔b-d<{2% x.4$xFQgF z \X͉ <[MPt?8Y=By凋螰'3,De=-`$aihG(aQ0QATej/$zyVso5r ?0TB & $L_dGIYI8Q@Ab#`y1&sJ45o'I|UB:[ia`^"2Yin=.pg9 Q3ABKN"uU'q޳{wiƯhR6qL>9Yg8L>"7gI5L4s=[6iFQWFW(^ ݮNf#hr-x Ѕ5{('ZWx,|m;EFX5V_iE)Mk$rS,QE'uZ`|p-CQ-ȳbh=5׺|:#kڅ;a16i{mg^=1MXz8[5jVY幋rlpY 93ʁFEĨd ctyQ)NtCK[%0&`21 &U09і!N697M5%q˨M$ =ݜqcP5v`e;P̮MHK 6y5b-֣U 0t>6;bI%N>\zQ曓º ,\#*""O ىMy" ZX4^ vu_Ca=u_ QVJCmYRWK`ȔzLzvR8vZ<;h3VVSd?J2 t 6 VHRgYcy6ݾbq#)Ǜ=Q>4TJzU4݄ƴ̍3p +; RTFֹ:'{ Iՠ;j`B38Cڢq` p/H^[ӗmUTk$u(4%Ey)j CnvIԁNМH>3Ji8!udDkLBsTTb{FPPu hǓq. )oR_-Z2gp@&k4품%q̜5kmCɏ#f/s&喙4$^ⓥ) ʱ({R'2%qj7y/w i0Kyv߆gu)Ws)<۳o3(3a2%ƃsdLi'Ma/vx[ǽtrE{cl@ ߈(4ơ?aVCQTK{zABOWꏷ_ZϮoUiN]Tm/'˩rM]T}I@i{}Ci4H6 r]Zib]5#w Ke$/F6:Z@!0nk}%)iX*_e=4XLϸ'3>(f .qYKe'P8B}QG\dM%EWVXR_{11D&} } 'SBDx&m?I@'̊*P4nL>З0R}/ܟk8_a}PNFcݶ-Ǎ\N9^2~(.]:u,;V 15dBa4cJF=&b_ZN-EW\ђFäs@ 1^@Ef~?N"Q"Z '"-//ACMK I`OWSJM$Zs/D7AJ]b oeK^Fqj蓦#:!7I F>1 (e O''{*BLKD98ܹC"#/&r~j$ di uCrER Ԛ$ô)mS( @LV]VHU^|X <Lb>5&zI=oVJ("!s!EcaHfʅDdxiWi,B(,$HD"%(XУ\ *2_=KidK-)-z[,áQp)OWNJf>b9Va%`y+ļ(\B24e|YiIxcOE}*}96A~hB[%55 JwJ#}"@ԆJOyo]y]jd)Al>j?@ĤD+ QȁP֡foZW6yO K ds z+TL!Ƶ3tLf2eS ^+Ū9HN7Hh9*RL~0:A5  63LwlӋ,L%XHx[̸qKqbqf+WX6/ 5%x@3.6.21H G T;  F inetrc\\\"1+x}[gn u=3{f2dE+(X bأEA ) H_{=}=gvrZ'^si1?_"'/.!?;O`!P8 Bar(8(L(u-ix$Pb Oҕ0C٪Pf kgAX?cTl ByPy>- zk ݶn_5;pepng,] p~O"\؛pp@XuWBݏ>s \>.YWn?okY[0 q{r@xfnvp0) eG~yܯ̆UT} b@|xtZ.B˥bh+e\W059hy7`4^[u~\W5&t65|t^܁Փx!n}o?۟@OSg9lo_uBk/Gk} o0am P[0bca*10q5UUQJ*Lj9*M*}Uʩ[0V(*تQ-h[5]P[`d8غ@u`:BlZBL.W1\mCL!0ur'MܽpubU ψcp8$UYW "RxrqU)puquVquAv=s\]{נjW..UU3FU7U3yъBlu[+>7/ b7Wo1zy 0РĖ++ UCSI[Wx0UxkWPxck!Άu_s|C$b+ *6͇M 9jK To[Uۗ@5bc+jv9,݉pV\duh:YW5_mb|%pu=[jbj74rn4|u!Y|%plU᫺2xz|D՝zh{:8J1Eb )ճf+Wݝ)++WXp\ |5VTr[W! S#_qyUl!g1VLt+WJ3Uz&%usx tC#xlF@%rbھv`dBpzW"Is{Rv4p .2lqΒPUWW7Na1yU(SJqxPqBfZ_=*yrW WϐZ%_W?\hjUWn_rpuͼ{W] U3v>|E߃^h}u{+>WS}rރ## U̿ wqE<q?+f:;. 1c.(KX)OVLҦ|i3H X1ŗ>+!=H-"VEê,B`X3w,  c4?-,V8(CΪ޿B  w z ~qu[ u/⺝JB{v1xp%uzt:Ld|/zu+9FH$U9WQtt88yaj d. Ss 3?US?IAR؇7,otaidt܇lGlG3, b'|#ng7s9O| Sĩ_CJxE Öaw,8" 7,$DU{B7!_CWFv޶}Q۟6I_TvW<+WW^]Wgr+U|򠃫|1sUF6bT0E37sdE!v _ |GD_ "O3_`70cn`nE|D~!DA#A9k_l8x̅p*%T!u:h wtAW=`+K WW^o W[ל<8ogxdW=}Av_Znyy#Jv&*}_8qUNX+W?Dȯakf:rՄ!v,rзy_#~> ?#~f~'?a&?,ج0c}o0;a)MRg1`£JQcq\iRug{0wv}nJeWMJ3U.` \޶8FuW킯h1|A3Pݞ'=Q^wf(B=q:5{B(ޟ~K&} I3a+~rڝ"W Wgg8@2 _ N_qZ.•[pIם i>{&]ם):l<jJAZW>ԛpHpEGd.6J[y P[q ^`9,~ K&\Ņs\|jpu՞ߞ-߃W|ԝoA ~۳-bzqU(uA:yπ~ۗ>>}_>o}Pn}+ MA[0'^=7V>?}WlOD0/x8#Ο;fpzs΃ WWblϐc|QWl8d_A>:nw|QPTJv?.aiՠg0yzRoԭ'8*J ^/_-=IDa+UauO"̓Aԝ@|@ꙟn'|E:\WdqW=zAR>g`o\x`A"D$;_ >\ 2K\P}2o>C!:QWg`}2,rlI\=hY2}~+Zl\qL)θCjvU?CO7g{C&P_Ԯ:NgJ[W'8|U6JjTg o?jo?/ g:X2\>h|Q3+& Z~;+W~@:NoWJ뫄_ޅ~ X 1\MS|5ӫYۿA`q&o7WiUMN>Ǟ:N/_\/jd}v+=7ǐȃJ'\|"|. qKʫۙ~ê&>~g~;VouPWw++=VW+%R4_AYU텇>Uԝs3sG_=!gN}PyRnzd^=Swfj;^3Ju}wԝW>}2VF{ 6F֯鈫(+]wyԝEU=S+s圗쓹H&lŕ=w/zWkW}}td}}o_A3t+:C4EރV 櫹 +틒~_u]k8$>̥>mTYZ_5d~Pם~OF& rWw8_jqۛ{vLK'ӥ }ȴkgno8]`>,\ʯ{*O_[~|+Zw.Q*+_^}@sgx;E= _ݛ{5ugW_~3Ho4_~?|5]W&~Zǡ3?| ЇqpS ~' hꙍ.27Ɉ~QQ1}}fnC&=Ȏ>y\%>B=[p5;X+鿢 nXyQ*|~dn;?gpqd?C /ۻUO_sK98Vת;VV)v5tg4W +S)yp5zLƿ;j^g~qI}EM8WOHgJgs&=Eyv}\HyD oU qL_~rR¿ &Y#9^/iF_>d6p%KUJgɜ߃W=Eקރs<nvEAq(BoO|&bqS|nb2Ie{wnB39//ʼ}¿:pȶۭ:Eo|D2˃•nWy'냝r^⪯W6,R=2\'3hWqAd)_qEs[ S_%}KD [O}I<}x(8b~{?䞢\:as_ D}g?Cs3|W;>קpe}2־]T}2Oy xYVG|yk\-CL%L̥.S񵋠p{{R0uglCVTAWMyW-\I\*+_Gv_?nsmڿby37'3$ F},\;+Lq<-}E֚ T_ yH$}q+U|^x=|5 &CƲp eCmyL}z5ʞd?[n C.}r f΋;ӽ~9/Hwf>7t~u_\j~QwWc|%p 넣ںhX<vDž^UT)dl>WWCd~QӇ[٫&yUwvtW-P{Ndߋ2ξp yE]U-ٞQU|Ѻ'w,UɃ9b9Avw~ҹTQls=3AK'#ίU|&}Qk3_יK{?nU+`l)B|@&{__9 9jM4Db*`䪊=,y.&ԝ{ ^5k_+{h8^\uH_=7E_Z߅b+䬏61U,VKZVD.!olȶ~+ nhW)jA:knK%u{~& 2joɨy.Zw[Ȑ z۝yg2 g[W̧`k{{"w%ApAÝ@ҿy3RoKcbJݫy)Ug/_uY{ 8"K}4H\N__:Ys^!~Wj; &2Relwە ,OCL;GsoϒyЭWL{6W=>z~ه읣nWͤި=EmW=h_z+jĩ;Sdͥs^=XD.J*\>Q$so"m &D&WkfCڹPMlQPal&{KGR}o݃:}o*_n(\ބɡs^E˼.@}sSS3R3_=@Wz~{y3Xs\*/:2޽n_TW 8SE+XL"vP*1V;9Ek"xS~<(@lK #*- ˠ2cT}nAxn;>rLvGyG_KWwE|8߹Qޡ&|Ro|=ڦAYws}f.uPM<8Ll޳M|8Ź*y{^ [NqwxT(N!oz#K%,ֲu(CLmMQPy>TlfwrT}노 g3y9nvs)jXKKV܏@yk]ڪ_|%![gng~P\td*ȜHyugol;9{?ZOԁ>gEA* u-/INJ)vp cL(eNbj=bj\(瘚oű;q[ 1Um!bJ܊;β;qQ5;OPxELC}=yg&=?轻ŕʃo/Ժ=ԺZJUwxBɪi'q+eR^vyj[Fwx3;R<O;"O1LWW=G۫3U*WMC~\g Կjis^j{S=E-ᡯ`vYw6gZy%AȾ>>dɃ>h /*mT V* ePSUx; \[}j}skp;#3l\Zi@W^,W^j+9dDrG7yg{?cr/qC88=tnuW|.Nug{~~~QpeWD)]K+ōgWn8ρꮳ.p5Ubʇv0Zb#_W{SmgqŏWG }2 O/q"y0yȾGgO뿢8mm?3}}Mp9z٭_޳z:[o[;d;޵R\j4w- }KVNJp@U+2yPÁ<2GopeEW{f}/5 >Xd_k鿢}2g"wo~sϿzm33~ڇL;&Oמ xKn6P5A z$^Fvad!^W/ ND%]=UR}mMaQ{z}_k<_kc6+[Z1Ϝ̰3([,kf5/kf.mWВmSa˴2Y6=MV&[=N4;9e83MLDRLb5swj˩Q14:)X5$W+ M*Syث]-S﬙kJ1֙*g%L dgүn%*L9\G9z)ߪp.e8mBө,y9ehWY:;y!rn9+fᬡe3 f&b/Z."o2ńʜ,Qż&.'D&*'T[%t(ՙ;I()IAkPD(K(ɜڈJ'ɜ mg^ډp֘:-<qPWIACu]'@纥&qw S>y @AfLG`JZo*ny8;GNH|'QlIM`+sguKVq3w*H3;w*FrZNr^%KzW;iQ9j+7( RO*vQQ :{5liI\WD=T>NT;;.g{e>ɍ(s_85 p2JU:`9d|Y:uP8Jk ɻ:[i))v#t;3% yȕ:m1|s:v;ovGv~Yg:Ξt;:?u)| g2;p1yDtΟ Ý)c3E sfy;Y?Y?Y>Y=Y5rVpngve1P>'q6I){ᤕn't;9*NVs LSPzf;e٩ar*ѩRڜJũTZZũfzީWiQ*&icjFiTjfiUNqJgJNSpzs*)g ɷYY2N>z199StO˜ϡԙǺi8~ŕ99tfn d>2ψ<vfN$\}N!sRЗ褠R&$=]$='9?)v_A{HDןvJ gcoάI>cL= 'gZ݈yegu8Ust9|s9LSݼ7v?x.JM,.)Q(36JxW]O}& h ]-,w0@F("c_勇vXy:Uu%.]D 9JA;BfΖRg!Ðz^ZR Qi%( 䳦/D3=%L8x,jz2ݨhap67 xiJ\(oEx m2̞=%Nh#{ )D:S:e%G pË$L&׷0:ʋi~#"_$FEʫz g`+Ft!";5VxE2-Xڳ>cνŠr5AK«%(AZpF_7c^pؽߟ@I]$r]*# d/_8=_E|}>͐4UwHft!)(-?@:TyQ+b 〖ޓ@}=>|d֋e0š*N( )K*Bd_sK7 @%h{pif GG.Iĥ/]sx}p/%^%5n4u,[N-J9\E9ܟaю?^ieYiĝޥt|WөL࿷VJ$YO&Hd\Ot:PɌ~i.ԏoDNn0 ̙n0Z)8ͫr@0aO^Τy !t! q ׉kdr/ 扮E;ٚ@75Rb@Fl>NKNQRf"H4]L.M^Xu;F eJc-rOj o)GئĢ|tiȈ1%q&``V`1dlhuG>K/Y8CȳPW#V,t)6?u:&r?i[ò˟1#<jgҥI]tB\pr/_74i)W^ x?~ZgˉiX+#)ylf;FU-e?;3EL{ltpei+Yx!yMx=i" _=F?IM%g9 #04_|z^U]Lց: n  GcG H-Rp1h\|~zM`CzA85gTj{Qο,K{54jŪ*O]#10W_h+(~RُU`0|<_dM}%,pUߪYXl8[,dAk>{Më_oCVhLx>Vt({SP+Xn~rWbm->ncc.bra2A[Zn弓> fQMUmzhmʙs*W$tRwlcߴIHn xn&xo?x#4x\aC ~NV|a}LwϢ`/Gwot^TF7c1I^'@ aej4";K7}e3 "ǠSSH)4S s}LNrY$ynUU ]K>"-$h5\h79py18q9gn6!K./dmWr * +`ft`\8R%/ƻ9-T.'Rfgpq'T$U5NdOd(!T"v-R-si.ǃsJzȘ?襾80j_i~ub碇m|bl:nɓu_ݭaq<[Ș1Jt}[ k@)Ѥpb*?~R峧9N:s<I}Jy4Ig̊<-0?cJu13|F'2 <{`2|)!HNVǓe` yo+`lHڃ5<7=HH(1%oi|jE@;9ZQciN=kM6s2 oaգ a.mR j()(]LD_|Ad,anlhOi[-^ &hxw*EV^,|7F(xU3K{Mph3w$Q#lBakemȴkeek2 ݞh+۫{["zK氠^Z0VF8;JAuGA+zc 7=gI3ilvp߬c,!pt> 2ռENo$eV-Mϳ^PxS&5Oj[WVf' ,^`ʀnR'mҟ( Kuz x}XdM|9>ʗ>MFOoaQ g_m+KA乳f|Ņ[Ӗ/1Os ks ڣ]nnx*khbzCH`DxS]@+-^"IȮw.XHKZW4DIM"e!7O|Q|56Vt_2{sq>ղJ%%{nݲwVi) \/ n{BAۙe2ƤbvΘvy"{+ ̓6r5N?vQ1,ה p֋DXIÿKSfw*yǧW bIUOEV%/z^C46Eve^&oCyXhѡ{_סH rIDN81 kf b4p<`2:W >hsXglt9(;eV\_qn]7C̐[N/@NߗV.,J71>\%knݘ]- } m7ۊĐܑ即^ܾaȲ_M KBxYmsl-#Ey:m%E)PfdCRu<GQ+/6PM w{{>yew|.@~Nq8RϢGہzTkܙZ!92E*IQCEQ +Zj?Hd+G+Gt=1׿I;kmg N8w~Lrx OmUO~f=$Sl!,Z ͣX'0h<(UsE p*g5NɟPiVH݈12t-_h*EqE%kxȢwQТm>:nZۣ?@xwF— ꇕ#,P{?_cIQk# #'6[V~k3Ɵ4wգSf2VA.1#SOLCq|s<}$13 +C8 =Lt/=$ډu󈷍Ղc)o_~KOժS r48_03k)b8ủp5k`/ .C溳6(%P3T4JßxjR׻ CU:^~wyu~D1LYJ ,c7ƅ0ds}yg擆$;$DaīVyMiׇ\a- ,lx iպ%wwNOlX3Z-:3y_tZyэ|p{}pYO_E#eo2w։{I]nݏp/IDJMBjމ̅e?l3R\<$۲+^w$ s?.TqŵuoU t.c> ڹrHdKz8~ wN /0Bit'K4Gg'|T> Ki. 3u"pp~0%F;8]H3#H:?a,{HCu:O!pp62fgZ@<~b2|}lb,`qF(+5MT3E5 "-Y.v5S$rՇYMũ=gYZfŘdh#*PCm,x2`,szf{ bl ׬ʌ 깻tΌwt T}UFt}nw|ce#S ޴SGITI vycAF}}4wΔB8YasO(+8\BC98*B5|^ fMM0VL5'zC<\"f5ٔK6JrpU0Q&f ҃ALD y|ǎ +mc)n {@ J"ll`*s ]&MܲteWzIV5*vr s߹VB,!x66zԋ33/?Hj5+' G4r\ˋW >؀ÐP#x=ab?-8(vp-s ';_fw4L7G  pL<149Ve_,~ޯ-\i,&SRMb̲k4[: MK_5`Bܒ+qlhKM_qZ27!ܺ\X ,5V_fZ/Njuz{%j5K ǽqE?q.ƌvzPM/@ɟj.WQ_of+ߛ3dPVsƫ0!ӡkXՐ:J_ *R6@w1dYn fQEҨp 4Ij wĎ&| ^|STþte$o;_JR.J^\I{9tz1lE: D1Y:g`T\{uxBPܹm*y[M)51_ۢR tP[Q7&^Y8b2:? cn[u]Ij]bpLW@BQahbfdӯ 6Wor 3^z,I{Nb`Ci:O| UhE(Js~ZjF>nIit>oLٰZ2#됖 هm0Rx~㘿YqMv R~3 ̛:2ИJ_<ZDhp?F^乴@#`.t@ ţAzӬH3g`S)d[ic,[d,6N/%O16OZ@qƍ7orb/'<#-$%>~!Y¹X.c ?5"s hK+([4BLQ=)YuHN8U,?В\t3vуV&)_ 5 N6 ynx{dv"#f%+l(x{dvxd&?x{dv"#f%|"#B@Q~rjqf=F xUkP0 @ߺCllmnb[ Z0:Fj!_kҺIqgчハ/"Ϟ{o&i)\s~9~ImTW$I `Wr+e6"8RtPZRyn&;Č4̗WBZr> ۶2˓D!9*xql68yDK.eMASP@RYkoA\^6\jP>"c${^]5봭|+#h eeq!3 #ov-yY$ɷTL7b$T%䎗'c5qҤ8 UKsx2{GRatQoLJzi]K(>ϣ5"!ts*<Ս.y9,%9'KC\#fvļXA< M9K ќ UT…Tas>J@;G*-%"!KRLV#9ԏȇn"]MÝC@ah\hOƝ]8=(C_g1ýs'3mn x[g|#f=)&s,x;Ps.(ZZZE)$fV*pM\h Ty3\͛7pg.ˤ4WKbIf9=Vэ7xWmoH bStFgҐԻpiR"%a^Eb/R쮍!&QR>3;3۫ʯQp?TI&\1Sc!{>o4J/7J4'\lݙ#[I|s~FrϛT<;[8<88YZ?Ѕe4+p-@+9_GMC9bu,3!RZDpN$ԘrϝK.Y (( b SMO,dgSDRṄ[.S|CDR]h9LĔ+hb<ߊ2h,wQÀ,YjH _/}htkktWuS~ˍh2#I9Ez/>kȋv<8A^ݼ9M%Fϰ|ƒ Tߗ)giN;tJ\6A d\C8"+iQpr7dd` #tr$5+daڮTTX#3/ PkV$xEÖø|S<ӡm%!Q<8%},; lBcɩrTnj'Fy)CnbJ(VL"ik=k)=&UE!e֊&6ʱyY`or~G!7:#Z␧T ρn fbj&CTX!ddZO'Ǣؼaw6;CQIȧݷ.ָWk(وugkq@e!FhzHD`Nb"V J;k:,7JE#K.P0fBnHJ}'<%[[R3 wxȨ,eloEfo컘6["5{r.U8%tc{hDtLn2/Mi%*araj4fj:YCp`cnZns)mQL0P]H?Toȩ{JX3t+bsL}*%'#5֯އ闲]7Z֟h}*RĎ>l mXXm\2g(0vHp8.<}_VKc!Lt4\bX{pZ#x-Ժi-21+ r>}*9OM[}]c7+%}(!Д=#P"Saf Ͷ,fz}$ ɼ栃J~Y)fK*rqc]eivf5τ#u paݠn ]T4|\H/ cyꜽESV%r6Wg`4Z*z,|/bI5]x8 WhN`yϚUGvnEa* ZfMjxըAPAA!(?9-#8fv%\+R+ KSr6dFx3:xWs>#B@Q~rjqf[Fq9%%Kq3 sxGs>#B@Q~rjqf[Fq; nx5Uk5#f[ƛ$EE7x}ROA*OJukdˏJMY&ZI0 ȏ%Yvfa;̬B6<5A'1)7 &ofp(a{|ߛΛ M~X~DCDf6E>ҟiA*"N!*Qqdd0Z, tJcN!YdY=!o.?d5Ou4T,^ˣQ%A6 @3P-%PrA2+zM&oNwJ-qpi G&6:Rϣ¤iT,e*3ݱ>'$\̩32yD۲#3}qՅ-)PVRȵƱ T@+uf5b0^W1br9 )ꠠ r 2Cuw"N~M0P9BY]63ɍtg죙evexN;4%3KmBhe w@X<=qNuS5.WǺEZ , k8JAX/%=K[s1vSqϽ]lk0cP>vLNnKxkj`hِ0 3nxWs#fC3-H#otxGs>#fC1Y2JxeRn@UkJE)0'TJI6 5uƭUF$rS6Hv>6|KlY03;瞙sT\\.U6{}תn4Z5$dUcPpc㶮[$yQfN Ȣs !Alj,Rc' {.f!_Y\/iE44_jL~.}Qk!d 3V[>H Nv_,?%=C "k9.Au@Mea&2:5+n=NIvACL9j[9U'=7J?|7V!!UfEפHw0F]&<SQ*O8 1țƳ뼑3Av=m97۪!\٦DEƭ"A6"_ cM&"_eVJ?(1 EPyy1Exd=&*nX+egPx+;1D qxaO@?Iܸ`x&~hc5xwMLhdAٞݥ,X < ;}?} fx2w ?#Μ{=2]L0ۋD؅nAgm@g_,OFޝ;ނt}‹AlIY#Yo&dDUv-B*jGC鶎Hj ZVm>.!ȁ_ H*zbHQh>u1 [f7{ [^Ҙ8x'=t/#~ 0 +%_0xچl }>q3ILbtĜ%͉i F^) 0|etvE(_"+O5jEUuYWI(dM1oDX >1UL!gϧ8C 3d`?C铲<>sڞT'e#=BNrq Zp՟)"m){tG#a ZwSgY@HS%2 %zGa~; v!. ϗ}Z;x_KP]D,*Q':1q07;.3.U" ͅV`y~s^>Vf\k%.ZYl08 wNyn5CvЛ( ^*k5f];աo˛wրSh0 ĜA"o6?c$hMݢӥ'B\+U\ qp @R]+ ҹR S1Ki ʗϔlֱ[ @]R޼OƖʒ^E%-:<  |po|Qs7K`lՉn_|Bs?:>sjaN]I[ls/(? YwL=Q_Z@xsgW\ kBbڗnדpI'Nƌݽ; !qՓhooowoEڞ!y.rJhYW꫍rAMƴR){%G)AIʚ0 = p.5a~iAtMhF"JoNS8(46C]~(1 > P싅Cшx؊<i@ƬOqD.r;HX ̞<;Zt  hO-cGQn#>O,H \@@`VzafDL#$橲t9B76C2coEosˆ-?VM[nOF yD:MTV:'ЄAȟY=ۨv*% 6WjdAkjNZ?FqpZ˵ؽzيI S.PyYܣ#dyeznscMD7 K@J@ o2x-'ͽʗ-ˆ]ߊ}yeij5P Zhy"MlN>Ô\f)-^L}p;F$Bڜ؞,hRľ׈}xW]\_\eAU + nvU[βj< ܖ`Ʃ|0W;PYnÍܣנ˒tx[EE=$q3"C6[jT*B O^U ] 1.% aʙ0Z' uӥc!г[Xfa0m|4Ǧoq>g/^fxMM El0DtYAS!ӵ=56}M7ȐPxiջ9xS5>\N pSq}(jHmuQpoYpּ?k12M'Kz^%.dJD=Y\3T )n:o:GnrgϳX@Esw)zX6 ex- w(So]; {:#v) E{تAG"BVk>i)+mh_exQO]h؏{'A&Gt=?җeDIǙa% {[Biy]ЯBrq5L}09 )IOF!̍Ʃeli20ݵ ~1R(@+TjOxÍţA̵ Brҕnӣp4L$yJ?+٣X_#n_8|fP fLun=k|sipW-%NۅæPsPJ_qvS'UdB:VR5F}ĿxXSHl}:,ؼsلB6~YR4H(uH~Iaw1I餰ʇYd& K\q3扁BhInH;T>MfX 0=H v.aZ"M!VHrE&AMfz S:^dE*;ʚNe4gͅVTfp9|JS& gdAfh0]_PP4/etl:ޅNPX-E ('dFF+qg vcq A49;h"zq4؟{SONE.+5, mN.mw՝ݷ? {#(Rbx]Y:~w]¢N D7VQwV&Xym%0+,?"vLDs;0(Ȳ,2( 9y ep֍H0*ChVdmwo/>p3a%&lgr׾iqSL;X7k{p[i ԹHzZ"mǫG]y.M"Q7zFtzGG7 hw 'r.&~Ѣ C*7XY<' .$BsLDsn<8  j;KTv܇AN;j_ִ kP%kJ`L >"O_}<_  lʓdox~% _d PY ~s-^_? ^{ mQqC:,mrpѳjn48(Ufad")puߊ oiIN o NEM2b\^ہ @ɇ_DjUhgʺRv@Xod+aE q[\!sNa*Wl22#Ku?`L m.k%9G@? jJ+@؛F`Cdj#E >3vs \hmIZ>o8h1JnkPz ܌1u\W=e+<#~g gv; ԋn9g"n&)# O1vpGYyh+NjL&l[zpaZvv!NQ G"CJ @Qta>5env* )7[NM7OX3sP Q$ ˫wL C\ ILkZ33)n`fcU%|z͂d8Y2Fm2 Bq5+VIz[jPGxw,H~+sْ&kBw!/72 |&vΠld/UMY`+5 6+.2ixb NM[XIqII_9f.ʈ]<_s't'VlZ3 WS8ǼTm}pؿ⽆CmgcK̫wI+.q|=y`ZJ1n /,Ďʆu֪05_Nz; mX7sQ7cT~=8ԥU]e14.O>e[sM7c_vDZdH[hwinXx]) rxYȸo9 hGWNݝeI.u^KA@f.ݨܡs rz;'^j/+8ެjGj<[ޠ7 :3)^SZ Q} 1ft念=ݼu5.ݥŢM>xɻwVs@5e9mp-f軚=I7 ~xi)MS[j59Q s %x$Vz#+5ZWǜ Tx[˴i,Bww5[GzZ=${z֌ -xкi>&ǵ[wodؑ#YxAܗ,;# ˟anŐ x[˴i,[s 2 u_M&0x[˴i,ҷ{kg{-(,RklǦ>j[x[qZĭzx"aBk Fx9'Fx*m )(3JA kN8a MJx9Acna9:68J^~&I|sn?KG³ h x9KU/6Lsg%;J/h K? {Yx9$kc2sι̍ZCJ8Amm$$5휿dLR !x[ıc#c̜\ETLٟf(3/# Ox8<nQWAGjhs葷Sp˴6cH9M尤mGx[ıcb{NvouɣJ؋Ы۳ XBx8i"Opnti|ݵr LediFhGx[ıcb9=4{A>Ǎ۳rx8aqʛ5ȀKpgAZPe R4# x29Fx8^Au7s󥱷9eqL ͘&ZoVFx$ rgDkEsx8cV1y "K>ؼSp˴6cH9M尤Fx9*1,+&tJkX,a/ɊL" Gx[ıc#+o }BJ R#q̼͢5 d-xm/ŔgP$lkrZx9^@xA#Jp`$+AK1x (!x9 2ɚi&R屷J^ԟ0DzS]~ 'Hx9γ-ƯB!߻tY*]ɛJ@E LTu0dų 5rx9lActMe_MM`v >T$2fwAx[ıc#ȦIEk_QZpIi̼͢O8.x 2ɚi&R屷k%#x8r:Ei]A? vpcT`[M৑<W04L%u͛إ;tD_ۓh`\/fyxjBWNΫl1DyStKGJ*Wͯ06B%׋`/%HRO_U *DIVp )b&Dhs,#qxD9SlI$4kG&x ?lBWXh=Ux %u͛إ;tD_ۓhe/x[ıcH\Ƽ9{8.$.;nf9Ffi -x!T&#MK y \x[ıc#!q9ze=ϟoEEy - x[ıc#촧}Wk?ZfQf^F |.x[ıcbggwEX:)`V q{63 Anx!;An|ઑ/  n0x[ıc.H/n0ue27Gw#CF ~]x[ıc.GWf\ʊZ,ofGB G x!-kt-پ6-^AY0x[ıCD5MkPK}hŪO:tO/C2%<`9s%u͛إ;tD_ۓh>U`Xͳ1޸B FNi* AT92֚Nwf4l6'] UFPE"5u40000 scripts޹TaGbՎ!SFb9x9:놰i!^o*-E>Γ޹TaGbՎ!SFǠx[ıCD53ٞ_O=XQ0q{O6M(Uxڌ28q!kN.x9-|?+Lxc@%u͛إ;tD_ۓhGx[ıcbeV{~{r W+x[ıcȜc9AX0IO~# 3 -xfRxh㗱k$-x[ıc#,7<e[ԡUf9Ff :-xQLJ6BؠJkJ@9hI=W uo/BdW%KF_( xLJ6BؠJkk- x[ıc#Hwh$N"oJ?ɤ:OY \x!8ش ?Tķ}a Y)/x[ıcb%ܛ8ݮ}̡y[xEY3+x9 U?$x~0J!cIVf*  Xrx[ıCD5-akYF̼͢H [x9~ :ًOgݯcoȉEH=7"; א=Gx75blzX+[IZ⒐2x1^&汷kɡEx!-1޸B FNi* A~/x[ıc#`4W͏rrg>.Ҫ, \xp~9 yޔuUK7pV H100644 changelog9JUs\QJS<D|OQT92֚Nwf4l'] UFPE"5uh(;xv~9 :ًOgݯc100644 changelog'M0EW!ϭJt 9Jc_lm+q*x%u͛إ;tD_ۓh4"x7΁i(069@--KS(vnюbU`!B`V9ųKx~ yޔuUK7pV HA.x9JUs\QJk |-x[ıc2fu5LW8B\2R_:ys m,x!q ? 8\$ L9[x[ıc#z#UuZOs^ff>Fl x[ıc##|yZ>`hFeWƋ̼͢ 5x[ıc#}N9Sc{̼͢ x[ıc f,οv +*ذmf7ס -x9l (R¨ߥS,OxtEfGx8ug//6N}IS/xh$G҆ŵWΧγ#Fx9jiʰEF 礥M%_Ό.<<Ҽa Gx85pHE)~K΀r#S 6<3P1M 8BFx[ıCD5rk6bxNѓO"3N.'k#x9DQd"jӻ sAJ>f5[Jӊ"!Nó $Hx[ıc#}N9Sc{̼͢ uxRfHWYG*X x@m}]zREC_}V(?" #T`x9QcG;~W&ٯٱJ+w 0hyh &wGx[ıcb%\j~/щOQ0Smq{63: +x[ıcHf5{|mwQmތuY@ Xx8~ǍW|X:ZEy|Ax[ıc#YO;%UON,ø ox[ıc#HoM귕67ud(3/#z x[ıc# G^3g}V`T|_=}EyzxkhذYd$KEGzlIAҲL0S -xkhI$FcNM)W'Mnqm $ZxkhIF韖koꦆ\}PlW&^FpxkhI$H5#aՏS6lؗ 5xkhIqb>55iׁLv-xkh$lvGY<ۮ͊L-xkhI$0)o_ / %ZxkhIox~sّ&gqLx!PԤt(}37򡣾] +7xkhI$cIu@]{RRErl ".xZ 100644 NEWSX0޵\ $ N:/} Pz-@虱I_À'~fj F=)hxkhIN" v[__x4-xkhJ$ -_frXXxL-+km Z-x!Ci:]  m\xkhIt=~;]Q~){sLe-xkhJ cf 2U5X +xkh$";^iFq"CF 0Xxkh$r|?5κ2, {-xkhID oktEb_x:-x6kEVkãñUZx7~k*x$?M>i16vKE  Kϥ5F(sR"Ex !3Tg82wzI:):rym(xL7ӱ%?m( {Nn磓=%eW7hNi100644 ejabberdctl.8zڹ{hdKah!2XpԔΎ QKp|"aؓg4Mx~("r2o}R듯2g\s 6c QIݵF]ښb*F+oix!LԾ\F),rOn5x{}[FAV^n@u͌L2 cx!)(~5FwTL׳ x!d)y<ǞL(Cx{}[F#W\y.5y54͌L< qx!>?U.7R(ĖC{vͳhQ!x{}[Fz7_qܓnTəw3#CF w Ox!ec)*!'x!N 2=\ķU y0x!<ڐ1;z' 4/xRc2UT÷~ZwI׃̳GA\+@b~ AM9FN$`x!Jh Xvli^  wwx85C@% NIsԏ-jM1ٚ@~ݲGx?.7F1i]kZ$x87M1O;d=S<D|OQCx4H]w-FU+V֍gT *xkgjgpQYFY؛T[S>_,wrO]*xkg8`b${ LӸl$W^[' @xxqBH_s?z ԓɷyg[;jExxqB ZK91Iύr‰~y =xKJM+.1xVRQNIM*MKˏMɾxEN0<_!P |@E=ăMMJ!P[V.ٙɳDR.k%R>q뤐aBkVWetJKdac8sPⲒz*S<E"M;vC'1G{I@2`ΕR^7s($|*)rIRxS]o0}_љ..K`ܲ7u0~,_[۽9siel4Ko:_mlqIh$_N)<0.)Td.&xE 9Jфjj#u(&QLnSŎz=Jo8}= t;^Izԋl<-)Z5t b3YLH!7 KKve!ʟNrV;=2914mk!k/kƝP]t VUcprC(ߝT&j͓̗EWz m4,x[˵kDC ܤ"}XM=.ԊY& ykkx[5k?ɂ2jUx[5kFۗ,QxTMo0'DI cmVUt[ϼ}`s+ iI&/f'Be龳2(&`uVk^On ǝF_\+KX*(49 wǦr$:è [ܦ~LlLxusD!/cxεsDpqrrV+*( Q[x;xq:eYthLK7 x¾â¦Ps]y +M ei,x;8qB2>?x!Rv81fք!Ѭk$e/xX5 '$x&rxkUTz?= 4x&2}GM&*xBLme [KxS]o0}_љ.K`ܲ7@x d@M[?|4 \9=v&+.PD=1ש,~M,S4W_Vr rlqxzO'g(F @!DI%!R[/* S.T Z.G i˙'ǯ0.QDcF׆(G]"2 Nl{zA# 4!_ Apl|]ve$u20-@2N'5IQFЦ2a%%M"k p5LT6_2TpY7|c)e*9m.iҝld#O1 [Hei8D4w:|7{qYς0{_xcB6#| \398U9C!?S%&FAMS%ʛøތR@[(Mg,)*M3 pr%# eTLKz\\IiE%ѱ: `c&'1I97jXujQQ~BjnAI%ЌZk"Eғ/0qs#(&</U9'[2+0aNl,VQ PQ~6\V3m|x{cB&w0-Hx{cB&29gl.acgx+*'޴9u2bN-:6s5 vx+*' %3M3s}if#| h7x+*'±}JΜn i_a _x+*'_,ވ?6P;ڲF GxMn0)\EBUZTqJ.I#c%jd {v 2os&e\௪JSwɱ2Ey"R$\c.FߩfP\W81fH}S{Gn>i^8)\YHF_~(vq< HrG56簑`;}D 5UK [#2Cr~Ճ<3"][fʹ!9dz5-?7K[b*:;^&\ tI{gNq[uŊZ2]x.te#,<;ɣMun {xݎYR(Ty!ʔazPp=l_|0`M xDZcd/FK&͌**5ɱ\%%: *115!9: @IM];.Ă5aR@@- թEEE: %EI9\hFE;g69Et*&.a=. @>nj<k)xmf/Ffl3x[DZcC,sL3\Jx[DZcBFMf䍛jY\-t~^-*FQ4ҬH<^V.Tl?$EV5 &A 14"vkGKJ+rrT٠U5o9Z{D\\bȚNʚBT!S1B,QTYbLMMSQ `PE<ȲF4V,=TaR1_4-=4Ԅ `b{,D#iDQ,ҡXCF)؈T:в=' !-`t@V]v-[ U4P TLShqS, L[:b@|k@Tq13m7ʆtNfh@&s FᠢAe~UoMƭ$ T42%F??hNCJ}@M^׵ L5 !kt ;250p[2Q,`Փ6(ecY1d-!tUՉnC A\ghD*7RĪ*0UárT $tՁXlXh 064AJ#'g/Ixb@J(BV**50L䅯X<*ދYxY([1^B) @!"[aJ3 P>*Fd*^q^VMeaQMn2X˶O8c5s~`9}z9cҙ%e'˺kOnCZ5mt"j MZvCQNw ~B4dnNy h컜"Eq=AP `j%ӱʺgn1PU18DNpƒO>^pE+_t{aՙB*kL6G{r:aȬP_c:kMǽ;D p Q :ZTMcz9Q#hq8=`T8/&‘$U^"Is|=Us%%ީyi@^Ϗ$M=~y%?2[YrCW;tkxױ>0aUӣOb$> aCh:Bt5Jҥ&P_Tq_I=k$^+3I|NJ.=uh_pu M U;?'NN;6Mk16k7 mᲿ, 'N.sQUHyg߮[׏~{,X,?s@!azJWbT_ɖRtT7 ;}@ֱEW;Ͽoh8_ 9UQMRH MB0q]?H˽k8kTqWU $loa%5֛֭lV} M8v5 !r:B"CJRXoP/ss?{ _"B ۗZ\O6V-YiLɧ҇ F ]-ICƩ ps7ͽed-jUՕ:ȆO:u8z-ZF6}v&9SjEvT(xx;=. Η[G/4uѥ>/sE u/=p\޸ht$u? OG[:`:-;G,Ԡ>g$ǻ՚cLycSwεϞ1P{o1OIzXzl_./1wc[966U-[S0L6WqjLw;6=B q f٣@˺)VP&ÿ=-Zk'ҸzhBݢ:zV'|p8{ 4l|q$5B+.]/n? QbGxBW_ie~%SBMy]xy8k_My m_`S*3SkmP{,=/n|}z;]7i ' Au MÌT5Ha h<|N~/di~f}{np`=́'~g[^v;cy4쩙;rj]:⩥2 dXiB Ʀ]x5/ 'AWjs58ۨO̭޲~ ģ}~ؙjޙoЏ;|trؼ{y\}D: l9wxyYtԟW Mx^/CgO :w-}Sh)lNmuYٛO6S>4mHQlQ+5}ҴpW }C]eJɣ0_Z7W~LעP4o~Ɇg m:Lx xq_kM!4`A+V/> ]7Fr D>tq/R}}e OhݵVؘ@M0xEo+ l!5v8dՃoDcZ2bXиJ}uow5 *OZg.?Ts]c9۽YHims hOɿ5<pbb uԎ%쒸/X\K'N _9* <ݞI"5GמJ;˨.znP65p񭟟{GVm x_/w}x}1 B]֡*VA@~&"-K֧gt ~U ޿F|K6$\lӚpٺ2`Wrf dho*gE%pZLZR ؑUЫ'Axw-`=>/l;`~7fX e,ƽ;^iH[k1'8NY$^|lW>?T؇竡{sopj9l_Pqgv^}lRI1^.ٶ*7ljjAguL^jw߭<،ٌ_0Jд\ / ϔVv"K] ;۸۵P6w񉕐O. P({ӌl~Єm /TkqWJR?k.]R7rZ#Ȳ폯B*ϭB7w-4NwU.^H9@T21^Y |oYnt*,60 3bSjPa>?ϏRIGlY_޸ / VC=8ju~{qi/ #(OMjN܈u06mFQE6 !$ !5Jv)*DcHTmk Lg^v3O1`H 1&F` bL4h|P"^jx=ޖtNssϝ|!vi+'y?"C0:sf p3٩P'?D+mJ ~-Y_-.!n aTl3BZ X@R]5-6eҮx#aZ@*7RVƜlhce˗Zˡ;(AWB(Yy 8:v5)>Wbد U})0tUZFr򏾣CWVɱ՝ m csU"cvGё_ ggmTJn>q,3,$t6TL7dmy߸Ym㪉n.!O *jY[""cIuTMFLvX(aK0BHL 5L>W}=Ag1e(2 S`>-Q%tu[_Y.sv4)~AAv5u8 FNkHI-aeаa,60&7!]f>P'9jDP36fILٽUnd2b^(ٙf9'9"@jaatݡ .T]PTi D /.;(aUӴʦ͘E JKnÍ ϭ A]13lE` lD'aFB`W`vY I@J)X8REӠ8m8.SU~Lpx aRdMdFnA 3G@U?Ʌ-JƤ5OA#a'ӄXƠ&̈́WvE]'wǼ)YR7>5ƁTxYmJ(*8"B2^T:\hI~8!'h2N<٩1o%nE Fﮛ5˥b'yg%DxglI;)H5{6 Du (m邝hۘB9,Îjș6DrV'3dk N^mϋis^x?[V.YĻo}:oˋw\8sח_/gS+&= kvmoϭ޴[߶'}=s51eO+wt._ZzeЁk]:Ox?9:weɁnlOWN_ܥGvӧ[߸ӹ/Ds񫯯]9)6qleG<5nD֕Y1, Ќ. .8ψ hGHL CÐe=cbaZ 2VoTHXΰʈjɰ =/R((Į́>Xj+XMAgMcI\'tbˢذa~}B-biQͨBܒ[IMרs4`x T(S GeTMOUFDYVEUYquMIO%`Eঀk +ʋ.klʴ*2(U ~We֝j&Hf]!fRT3'#C[8|w1**D+7qz,F/p0PQch&tnJySȄ˂9_$"#L} ^0&?(i[Q@*o IHQpd Sl\5v3\M?\1&It@É)!%AUYG}LebC`b6W2HxwJPUZwK>U%e43>w6,ʟdFX>#0|=حtgcʟ(* E*wܑ_ E~, eq>40MDJ9:/XX}L$ Ga|h:&ZFl[yetBO0O#:EeUvy\rH҄|ed 47+@:gY71wGq ZqTim$WÕLvxtY vYڵFKqyoHa}S)FZVZ ubc҂`epn&u##+Ԛֳ+6 D(2y$-[bcGOPvjK?X>e YQ /O)Ue>n5Gǎ3j4>NNQJS*ZuNa[ 9:&6]poBs}F@Me,sHsD3Mp%vOhލI18e w\mᙩQ :P6bdt縞'HM40k¬iw#DZG6 +)- U:6J6L{rٰ›38 ŪcJ*yG>=>yB5|> B3zyjZq[zkZבґ|H4jx¥U8u&T脌oQga0?sdeRWߨcCN͊^ZLUM@'r7Ox iv*:OMWQ㬒UzВSZ\^57RUUᤗiF}5 b\sӦ0qPeqEsn`5!4u39.cϪP͎cWUjBiҨcLWC%%HYqii KyX&cMx)1VHqqM䴑0ðd DZn[,u#b\7jS: u{u^U]0hIn79s2%4!#*e{op}ΐmAx-c{ aq6N*4 q I a2 &O{ ::vO_Ft; A}V.qQ_Ǒa~_6ц} @D -H7;H쪣ա2MK W-#uȾ!4cN_U2Q*rx|&y=/If* ) Ecֿc/I %}bj-P9n&wsN˛p{ `y Z W;_jl~whJ_wxt3; .QV",ͺ˽}X]ZkMoJV&GdhCY&q.nTh:WˋñPE4G!g8u=8"F•XzC9\E7ߞ3534zu-]1 Ekcpy%%T'*hDNK<8!n) gx ?Yaqި*R⼻,VW^z ڕ꺟-Ve!}tNLh2X\t]1 dz~pSTW ?-@Mx|FX>gAtJF=X9})j&S2Z$]kkK9U05ؐ ﺨ$] I\xyzQ 3֑9+xu\N}u\ayߊo_7O,jb$iM?I!3SAt!u ^Β `'I-es$)z$i.Otqx`HI^@k=!s$ȗ;>[G.u# `hwkqy|Pݦ+Z[/r]nP_pk?|8};y0+᳧,rGXh>lŖwù/Fv`mϻ3u#~ ]"=l>>l~dgAstWdz(Wl%U+)F)F=w'Gs_p}s/sxa(4>ܵ(4^bO4=求GvX푱__ c Żxl`aY{ tpJ^6al^_:G~t)Bە) 9ŗ,֟o}eك s8G֏k8CeN;Pax zb\.Mg1&{gU쏹{J|~9i04/[*#QƊv p9Ѽ;Wg@GStLJQ^ӅM/fg߯9w uoޟĩ>gC&Sy]+0Loioއ*ѢLjw5^vr`=f*X OsA|.=ڕS\$H>%Bzt^!uHAжre~Ff\jf|cA{ np]y-)Laq\t},m)U,2KEn°gP2-/-XȲŎ<4mkDq~4?GɅU. k>ѝHӝ [= 9%Ip[e®w[ȑ`_deAuJR?} tJ44j/yg0ioī4\d ]Y7- peHpEg{==e}Z_1y)\`G7.O\xsJ\[pOEI>а!-pgU8'Pf_W{;jo?,'jh.8'1Al/4o |hyaˆgwEK^EYVSKs}gQz}B87z MC@ȼQGկҬM_tw95KWO(|^)΄/^Y u'jj_ yF+GA8p}cçfsF&<]>Pz,y,*۾Y U>ϱ|6釡![ƓS>!aa♧:>銿?= !$/Wu. ND{ ᅳYLJ?i^-̂u+F{Yni DJVۣp?Y e]J'wGʟV™ab6xJx*9t^ $eҀ#/=o`K-o-{~WoahaVNaz#c,>ay$=` ;9W2-^Eß%L'>*zkrjS ?1.s?L 0ae#x 5$&o]4E֚_.Z dS?nj3s"V0&9KmL|g |AIg>#5Ky#z͂ka( ]ZIшB[[ TZ/ Jň>v罷{A ^M);y5"a8SPZOkC`}v3sGmxsw|3wNf 2veyW}|ڴcuznF A<0ZWP#99}oiۂ`_Cnj6ep89hϋge)!}۩ih~׷ݳՅߑu?6bG$0^z{ m _l]Sq .m˳pC#BWPrY~q`'+`a9}~^ْs~ wwQ~n'<@ >A"d,:3s8upͦ?jfC\eY~D A's裙BѶm9trsЩ9]"s,m?9zt)x0f?Bjpqp+as-:6͕CNɋ'A܃76I\.ƍ'|)2mEp^0Y^CWسB J"{4O|*ǒVM#]o*۠?X;"++ M 7nik:P<"ݫ㸑,Z'nStZ5L6,D.i'c88ULnQx]t-K"Ʊe6CZw`5,"'2)Q49A1 s,=y2[jRV'S2`FQ(8baOC⧬M p5ɸ=:bׅ*歓aa\'j&=N~Dz6$f&CLw:Ȅ4̖f(^/~$%=ώV*C 0nYIJɛIdD/c몇!f)! !<>9|1> 37S\- {\213ؖB 8yh.R0g}Pܵ0t7ruRl+ +4=ЂXM;m-D.;5@K |AK@bW$@l1 T@hU z?} y eg%4FGD34hu KOiMb};@4EI9aF-mXĞôݲ&n>P'C~DHP8sB%2]x49GxK ie^5n8!P4C-LPCkԕU5-;meȶ"m7 %VTm*_ yh04158dOj)Oؕ>"gLӵh4:.t&UK`KJqf[Nд(Xm‘8, r) DvצF+< ѓ8 i(~1ItEn& ?1q#!BXG(-'KZX }XJs_V .5mGw CG Y ^ԄMAfF@s@jU_f<ik"9`'KM '? oaJ0xKeg3f½YĊS$ A{"0yJ7P 3irTfFL%PIXʥ,F$\{ nxN% *("9Ǟ S0=\!n^;A+ KjX-v̋VVv@Ѓ/Fgѽ:AGռXnr,&΄fKn_| UA+ej(je1> Z (њEBs"^3dc¥@"0m ThH$+k^0H_0n(%. ͓Cj1&*;M&4V%OjŐMIܙѩ<6|Ǿ3~G_O{>ٰz翉o?~rPe]ER'TZ`iؤ2BLQu7° =`R "IH~"14G #+#J㹑 :D6(GFV">98F TU4%[ K!gntij{Y@H!MNEYCSD( )"F~!2\QtB0Q=`ǔ  'ZƂe##ù菣JdH$[: 硔ʔ6*m@EZ3\ @%􄧒 iZQhyH8&[Dz,bt UC$k 9[_å`,LMG⛋a#ۈaebdq lM5cgt˻$W?u GW~1)Ddc i؎&K%il"DȥX,mLAwwۃ8Æ\mu PXQA ۜVtwNhg >tw"oИ$l9*A/+PM{tݤvȬE^ojroHpIewwԨx.Fj}>ߋ~̽oqt B3U5shE YV.caJדO;az)⽻Ͽ!+K?r|SW/|kd繙Pu wA_'4T v5&|:[Or;[QY/x+pOqG]2 Up&ί7px:4oH+#K;̋[ѥ]YpEP;]RnM39a-> gypӔ]~-NmՃE³4,C*-s|AM6Z׬Y Umf#գ ڰFPSlG@hz_T=6vNu_6-ql&ޚœ%cSĬ+u~z\!!8uBH45ɶ?īr-mu}){~ihmΩ\kŋ?x֖*lb5\/A9dڹ>жµp3USTkNcs 5U1.oφKsqvx 4@tXۇy9O(+3_S5e/ Vu}{m g7|6tdN*cLթU]/תG.`S+=6FtXe O^qeW@@n|i"@#ct򿧥Y5;*84g2 lq7dXuvhۇa^t\̾lX4'g_)⚎ ][ڗAsӷoOyҊU,>_.#ى|X֣в xQ4/C=$ {޷9];kl⽙B,,CF:~eV:`*hojU=Vu7=ϱ'~Yg ]}=%'3-Dlͷ`nĢK{;{ɞ_YH5{\~<<~cSpu {6tæݰS r7܂{|3z3feU=hL#4x q.;ȞIn4i2|x6_'[7ϧq7[Cû8mi AY7H;yd03y]0XBphklCF" <g& zq XHO{0Tα}YBV-ۜ=( G YT6WEa!)$g\?>+LqKNĩ)AőZ9HȚ.z,l^kWj0bڑ} g)$h*;IK_AeekNwiS4ݱhRq(bI-f<> g"3*r9SH0 q#f4 Pm%mRy]hFL.b^dƶJW~Sy8(_OS8@ѨPc9Hpi44_% [9藈KD%ͨ$fn'b*P\ZôbŦ:zzZl2j1ZEb^Z$v3 r)08biKT$cMɥITpfڇD3#P%p@9^Wa ?$Z`w3n(2Ѩ/|qA6/!'p!5Tps/LBBˊ7/rKܯDA dnH^y>4?YZ "s6-0xwK*U{jEj wIH̑)J tձmAեv.هډ\+.pہ\,Z-(4 ɔ* ^䶓 H&P0Ѩd]1߉dQ"ȗX雉0i@1YYM bp0Pu#+dEl -z4N3<>q̋jýDu͇FxŹ8 xBsuJ0&PPWĘL huW+ԋ7Mt״w 76.0g.Ǎd;'&1jՋlM\f >,1eDC[CKj0K,}1Y<=`-f`mƑTEՖxZ#uv(N=J|B]mPi2?Tw1 AT8Tz5:8<%S5匜Wj9>shB]UޱfzcȒP^hXNGJmHP%eŐhXJ3T"T^\>.g,vvlk3ͧ-X\kzz34dȅ+}dʼnY[i*8atT&̮|`Έ` Jvpa|=s8 $^+U֎ 䀥aG*^X^U վ=/ouut=oww~%6՟:쾿}'K/_:qSO5^)t0gqp>l Ax!vkGK[}xUřX%-[o`̜>E @@q$WrcQYlDARA$\Ŋ#*jQi](h})vιܜəS?J3sfޏ{3&"??#Ÿ7¶xRΨ#-*xĢT0Zu?ML,FnkHg ?#ghYHFz>Nc8*L6r:B< D%-<)S u1/i9j kgCMŨeKTQ %w(ƨx 7¯1x k Ai-)6wBO3,1lXUU{He\gym}Pkk (B09?(I b9rWa^ql!OGBA4vcW Tl--l90V&]V/R Qw`j@nlJ7UӼ`Izm.=/=:=.>N6 9uӲx`N._ku㥭^e(vd3i; X|2msITdz{x~>mdҚ+v#,כ ;}Bj:HvBB{G4Qn!t<,V,NJ`eBhb8Bf~<-U]?M6y|I0/= Gx}e]ݟ5:{Brsr yoEUK; )]-mfYHsє %:BEIW.*ɓfF҆pܐjm~jυravfA>bo&pi~ޘ?Es5 ]]1DiD}4Д-ӊ2׊j{cB7Ah6[(0 $H' "D`% 2؟FE:~ÊҭH!4.^c)4lhd,xkq@ʭ5JږIgz˥g+6>|ro}  ^0lX? slLɜgRqSHW7^Oͷ=&ttJ?ᣥjcJYg ^STu9 MQIT11 ޹L&Q?/Eӛ$ɚUZ 9N=u6 5Y5z\0jȞ%G(G9ǧJyN.`²\*3WO(>"Z>*9dSJ'_k4T'U74KQ OkJ}CTf*#@}Yʱ%BgJl*M2O_^@x];)]B769!Z:9ESx͏WW}/5[Q+*KJ+&WΜ< vF$2F-Sʯ aK?*G%S[ v'FWrYUs8ĥ %2^^!duTkReO̤bdTxSgA!+k3x]C >_Vt1r\WgV$99Yi`a'~}g,*![#>[]]"A ӿHSOt,Lc"ڞJ6"w9f Rx&ijGm<O6̛OEY8n `~d4\TF֥ڤ#M5u" 4E=_͝x!}Mr>I4,w jIHm|O"MWJ|"--mwUDխ2HHdk큲Nzsۯܱ~F52յњX&6Wʾ~?;|nƪs=߳W_pX3ә[&Y=Dj#AgHșD}z%ioȅxYw2!`A%ؾ-Ξgn HK_sdɊMkoZRӁE'e/ |hgQ6j0eg]E/ngETO.x`xO4ޜY(ٷ}kPdAo |A]g>iKOG p)!K|GGn1*ã 쭦`TGpj4l7zs23a#V|/awMHq0MFɱ?lx/Gq;k{rlQvp9 ׏ %d=ȰûO u40`lq|D$RD:  1Z7lj9ۀcUu/D=bS_ e}/Lg'l~[[nm2&>:xhBfɮlgHo v/Z3"snrs_a>A~ٶb[`dr{sO6<(C}H[G& en$ȉ7_JZN|+1/w;Hdev4WfۂM ڪ H"Z # &~Ru; cկ~`X8Gz?s-8>1!0}OvM! Q]\DǛt7[?7jL ,4O.#'5<3\Yt4U ڬC'%%ti}6'&ok̾T$2}v` yx<80B̐dVhg hD 8&!!׆~֊Vh`U p[xw>V,ާ. #ZrSUη`nd]yk_lo۠ `6\h&jpm.C;Nl\|FDH۷UfK8cq:,oA2U`5y{xj>l޺ _ߟTBw_;j{`ٕ YSԓ{J{!|48.l]Q/v͡з-a GHһ&%hyѩ8Sqm.C~VY ;7텷ru^xgс޽ٿ~ގoAk_ovqZp=_ ]LLAˍfwS?Uwv8򸋍CȐ1`/j. `+^ 8^B$\ p=P яx+[w׈ӛB[r4r?jk=p璩aOH}h|`&Vo*b;7/\rx_/^i ns?oC/Líu%Opd?wB3;Dqp'{꽃p/,8jRJֵjvƳ 25778sH42#V ݱ*uޱdő~Ɏf7QU Q䨘#dK ]؉,HwȻw2H@P*kȈ5Gd2Yؑ d4FAe1Xr&bj֪Ur,5Rln8-E#S@Fe9$hn4(F `nJRJq+4Uld'A$O\IӑɒfsS$vQ9TⓄ lSMu^r^2r{<1^cj{d~pfiєiYIFzNM .؃CY fKNf:[c PC}CnhΌ/IA?{֛C^B3nBd'pՋ X$uviS)ޓSqE%e%R\ "j InSPhX7D].p )xp 2Vo8C+ +XjӪD-wuvm2~],.fta,Y1j{ QC]ZfoGPCKԸFsZn|yX>ˊam:Zs@#K/y-TN*mKz:EURE e\02Uv,Aj fq^QłzVj+9VFwsLrdɪ-Fф._Zrђ'o +66G-}.T)3sTǻl7]x iy1'0dTqm5gu[W24'&j[}dZ߶jշ=]eM ovы՛[t'u.3֜=T|s௃N߉7|phժKٝ%}w,twrp'Wt?|ˤew;~˷;/,Y?[_U7oskw_u-W^Ь/n $H A $H A $H A $H A $H A?nvx P #uf8. A0FVN]> x(;GK] Tř xQnU!@Dwasv;= :3vL@] ɠ7Qw_U9 N\ Lap&դ&DzP3׍VWu3q;3T5ƭ3kz({}&Ԙ%\[MudQA][W-Y2ԡ2p2Z5$Q ScV^70Ds,!!jLo)z5LFj+Ե$Qs |$356 :\j)!̕5,d" o՝g=eԴwu=b:.KC(y2+RS}nL;܂jb ϔx6ˌl8R:iVOtxJâÌ2ua@Y6[=`_jzaդҤį\fliGW1@56 oy_E܋¨7(~Z:y+l\}H78E4DcVF׃1f#s tAb!,fNH,ynz4l=I./vnSV%:e>eSXe\tZvI,a pxM;鉾֭-1ڬ LNN2}֍zژG}a@M~H'kS+X4 m(~ohfDr"\aFV4'YMݾHxq-|a χK!Bsp*tT=13Q'd`5R ђ3Y \A(cŸX$h)t$BFuq'gd'L@EnP֚Ԕn 4m1Ajq=6ͷV["uxX0 cMiN&Lv(+Yb]HWX&lf'Ċ  ,-`N9LvAV Ǹ!Mu~l~T]1).X, jJ]}m>:" 5|SpsD1ܲS{P›%)ʼnjOg5 g|YH)ZeW >hgȾ$Gzʶs`n0v¼m"DoPk"?qW3{s&o6+ Δ#L@X8TFmUdE'MTw̚2d̗42* F^Hzq,O,x8dQ0 q,QܭI32cLȖځkm\1b!ݷV(7I=V L5qC,֭ :UV;>o >å%\:f̔I 8,LnT1_ba7M99+o%)bnsmaxJ?a\kmε>kğwX價 sZ {xA{(4ˣA*[jۢ.`("գ)EZkt {d!BG1o(䳛rpE fkMl1tbEy4;?& 9 b2~18kċY/}ѢxJƎ-;qmq>kP[X(N6{2  k4Thbq=6NdMr}ʯgObnd*t-1ŀϔRD| Z^BVK[`"3ƅi"Y-MCqq=Jr5-(NTu3T,tws"tegC{ЙdY~U2tf^*OId~ DwPYa'm3t"=}e(;='71/bmM"Zgq1ـxOɹeYMĎ#НlM2]e%g6$On8ЙpV T@58ľQ 369G~Z_ht6NG;gMB/OBVøpj"Tkku\' @ZR*&Q=cPߺTjREE:lƲM㻻Y-$=7wMFAO?uW[ z *gcƌpwݫWM"}e;q~{$:sڑFN$7 R8P< # Ho<8pIE"cqA"E#hֶ>ZmEi,2UTۊگPQm/_\oE/P]pPcH74\dAP|M$nQ.b́Ay,Y^STl_o U1+c&ïOo~j;Lհ乫Tw՗] 7%'P5QoOJrSJeYQ<V5}U#g([m14lW=MU٘1}/5 n|bߨ4n1yĘ3J7x%l_h~p=X]@sc&`K㵿:V!`ǻKߨ |Pұϭc2:R~t&e7.[T;e\ rrcqw5* ؼ~z᳻vY(Vem5oUgJCQOӈH M]wj+Tp~%~ t~_Qb4=![^5 k~q\ olf ?,W&F8Ŷv[Bm}6Q2seYwM?[Oʿ0Q|hT]?b16oZ{1lƏn%:s>;a҅ ]w%ghav XMcw6xz.COB=J2w%amZuGCWU͐JW*>]V:9I9j A G<C10BC"@Egf23 ]+ cxbp(0e̴Z B hٝf*6kf6pqm߶ (tN7 >Ď Z] C̽<|qX[6ٸZ/Ң K p͢j\D*N<@5@n o_5y=~3^hHc75!ǰVy[W#WimH'>\[YCٞ&sHwHy5nӼ ʸ=OfCͯ͜r_8 /cfWxzW#p2d-KK` ̫\ `i[V jL^hxe%y ȣl ޏr;dOgU* [/ 8moT;x<\^Z{ Eruà9>Bb&V}㡱*cع|U TX8Eֿ3:\.fw==}z/O?dz*3FԾO}t~f6p6מ;L?N$w \[_<ϋf ]8ڲ(z 08 Y< #PlWϾ{|,] 㚻E81k`ݑc0\I[#vqб~n|7ЂOk+f?ёߒcDZAAá9q_]=$'BBcf)|7 A~pV@=jȉ>>HI+]Al>w]Yk4Ȇ:d{l[yr/8\g×p66a2}#]dn9@_-cyNq[OJa)`߹B+`Nz_r̿* 8 gNF5yH¹X'_١U,cK\wc4u'ǂp#,(9 H(E ߣ G y4^ť؄KW!|1hnoK6[qڊաN *Ah4rwn繰ҹ|$pӁ~% }؁:PYզBa \' ; ?r]wfׅ2: 5Oh⺐{H+O9Z'GBqhP;lKv\Ao$_Z 7Fzh? x˟I ba)`שA# ,*w!h$u /? )Λp\0)ǨƓث|!=%B^ _,%ԡD`_چ@L)b _!s+)|[܏ȝj֎/ A>n, 0ײ 3Hx%˄qqyRR7]rW_oH0v5,e?]t9c ZR,)cG+CzJK).]Ӣ*>E[!uUV;oS#l6{hTGU)9EWNz)V'}lWlQDL|>E.DW$5KfZ$r^Pji2deԝQkR)Il^HtI=*#RǽBeŮf l-n{:HSFx2 P2Bu{A DM]Ҭ) Tm\C9/4?PIaX~8~x>X 6j)vS]$ !T )OϔD;-:H4U/)Hw6)٦[ݢY]ڇUJn4.PK47[le0̀[Qdd DCBQv&R-: X_!9#+Ey5+#f*JT.YO_\ʁ6bb/x0sM΁6Ͼ ;jgaMHXxS=SLsZȥ-bIO0@-GD8*WS:@LVUâM#5m  #+Zhd@#+.H4rXvEC#/lh`,V;* 3%ݪ)q⑺^FC:ȐT+[t!eIf͞jOsr$$gqLus4C+f0)CzQUp)M$KNSAvWats5qE=ח&ɧhD_|FeYSY)[dW?3e׸($55PdAu>:7_Q"Q}Bm0[QJ# ey_IO=3Y,f"c$̿l[p|I͐\Vy5Ste(BbdK$Pܫ R)ȠxXUzDՕ6.q$Da1,84;)ɖI˄`$H8X  $a EC?Y >G!DNu61!/+q,ES'xM>(9 Usrh@7hJyA"˃tGA~g8Qp+E;0\Kb5ؙUHO15b@#}tiCr ͧ냵yv ܃ڥtŻ%g pOCF?jTɒUCêXOתctg`NԞ2JZJ<tQ:`27&3wjn*b>xFh&G6hA?dJF;F:xJ%g8dY_EoE^ۭ'^Pt:9JFLwL%Ϥs%1rЛؠmh$-d7C4̩i3a!1H,tgqZn:]&Cv_sTJVEq}*+BcڒFPHnr讀@13$Qv_9;4SDXO9ϕrݢ!_ӻKs3!2tr/@&/~͘)G!yתh D XY[q4G?$)c<B9FEx ;4gA4CC9`p l,9aN&(u8z9Mt,9ɝ$Db*ߍ}?Cu@sUe|'?!ik]tO2.EA2S(}?"|=9ǭd\ɏJJ«0iL\" rӼ?swolI5u_rOyHMmK{OݙNzcχ\ ?S4TzaZkk합vNqڒKS.e7 h5{ʳ۱ܲȘ~sㇻWn{ o.sov̿Г3AIzʴ+?Epà^~Hhvw˯ˏ[XXXXXXXXLtx0H16OI55J6N40KI6412776K6J35H1J$$ry x(*GK\{xTյj  +x*p5}>PocUs' Lf̄-Q_X*`bJPlOqVREkO g?H$:kا&τC/\a-+˴ YM,%GCa}53a%әuAkKg3&ǐ T4x2ңT]_&noJA{]M%Lc$G:F k1ȏ)N8ɴrlGF!x[ rGdYQ*Rřh2S`zu9 ˟—[ԋ J('G6QEtVFm Hp]WZxps*lt]W, {rblW]Ӡ@lj:> / mEu mYcGLl$ Ԡ`Z~ zypCLWgi=7vy G*Yz}1ZnŝtBW_L^x򊊀ubٞ7D熫UM$"._c18+زHP&W\|Ϛr+\2keA^.~ii( 5=.D0fRV:( L njc\jNnDD4%i^k\+oAtVsѩڱ,G+̥aA]\ )R6d%2O="xQZ\UʄpK֡@~ թ2|M.[&nFՌ1ռ0'`hPbB&y:2eN؟n4,QY_QwՁl+P*7Th|TԢZje ("ַ& 5˨ē"h@-TE&qx /j("_JPW!)Ü~}r- J*U "avɈpdmE{]T Ϗ%Rc{][c/.6z~Lr:es'0IĘ$ :Lilcjo3XK$&xHC~!S۫T@ПJROt6fDŽ$*֐\Qjb愖{~ʩvC^7Q\g+kS/o::*!6[SC@Ke%.b XUM81XՐ7h$u39k&:a@ wă᷼bzX*mΟ`=L)XC-d-$/aն1F|H0?Hz !qdZ |񇪤e/,Ng*a&IKX{T@TTqm~HFSVyוEס6StT3ږ=υyas%.BzaN"+iLc%X*PkʟyvlN!%6bH][!Uhs:ǫɫUB3pDq"WP֘~^ppӳtJkTy\Cڬ< h dMu(??/藣'8@L`p`ܶů9qK =7U\u0: T Q(CPPܟ8h<- l3(/hc;(m C bEʻm,ʎV^(k`"dg`;KgĖ>ZZlU[gdC 9ڇdMMgDVN`89budHy3 :>ƱkWihZ9>+F w7^f*6 k.ۥֳE-ej9l<^il;v}3kMPptɷgϪ#`VZSaΔB֑cpx}jE78йTL uӔ|,|jW ņON$dě&˱ɝE,r6*ū`uӔk™`Oɖ(/>%@YG (&J~_lX}h|.wsǧ *Sf/VܩY[o*$p8-%* vp8|YॡP?x{_C~QYG >z Hyܠ?U>/tP>W#%>vnΊiBش}C^`ZnkqP(.p'3;o$hyh WV19)_m-뷼 Dw*>>goX-͞}à痪U"L,::ګ޷a(ܾPο< á`ņ7Uܭe[)hnj+2 2q}4/Uk?t=)fPa` |r*R{W c,΅K/zt^=6(n ޿ ͸V^WWk8P\{vḑ ȏ't}%~]lݼFxo]X vj/txkF8n=뵛'׸i3p獗] AQn<{Z߻ `kS6'c_>Zρw_rW<۠x{^lũy wS:vV knl^0A "5g903~,SګV]|[5h?{z5ȹpW;'(Ѧ S |[K5?p/mFQ[Mǚ1_[֮VxC;"Jr490* d!cni?{\ퟚdb~ غ:n>@߃hIUuC:nv`ǡ>)+W7“AYᮎ[aF5% d@)5/u1M@BY(&tff7ݙs30fyatRVWPjz 5 pW0s~2^.#l/ |(:8א ;T@\R^)ȩI+/0 z*Bw`ss`'f/,MSEs!\Y텦Q_Z`utX1y?UKt.[DջÎ<󿜆8aўмo|U%% >Pػ`%,mc wVeoÊ l26m\հV¿F*Wd47B )C(BA0QFJ88?QtJ~oMkm_)bY?pcX'> ^' <w${nㆊƒ+%]ǎ#=Cס`PC m;^9<4G`V^u,2`; FcB9,_U/)+>?&l0^-0QU2|V ](Hycٞgx7@Ѹ5Jݎ\= m/F(aVl]$Tk6B{d&쳪D,GD7Zv0xOvDXt{$~dKfo؉5L=(/qO*|y<,rB?R vƓ=;L?j TwZgj`2 A* ]kjL5+wl Y}ihp A,.S-4lscZhY ka~ot77x͟=4 ͊U SDꠄ'[x=K+cp ݎmuGU$%phap(:T2uٳW7?wxٽ=H3,F7An+_.\=o׀Pm` C|NVCOZA?QϻhPZp@m-\EFB5C;dG=YVY ]'F>DEɒM>]i.ƬBc|@JG'miR6Eo९b3ƀzEHKJc_Y'ѩPMA5W0v| 2l}Zև,nqpQy 4sBX ƽX~WkW ru]뱹Y[ѯ-\Eo|L2Z> >C\faG+v`=J8KCQSZEԵՊ9Ǡbn@-;-[/C J9XOOG7ugeYN* @$d7OsT[DAS&[NC.Z[T}cYDU6اd)vwܞėpÕSɲIp:)=˒a%q=c9Kx\ r~|]%! huɚZs6MfFA3頔$bɰeoh -8;iX=]hNяvGRmQ-nMs)H.DEtTi"4kMtzz-01L$>AӣZԂ^x8{? đ+® Yly \ծ3,]p*<>O޻@MU<ŝ0%W!ݲa&;"HpeZ4x!=?c.M$Su}~O d9;<$tզHnW^T^(`T@ E3DhHCg"T7vzo)`LǮ|(f3!g*F%? /$i${$] $F'[R> p]> 'b M+m݊T(ئS'.tdC t",*}7pX$/*Z {3]D)#qaԖ_j 90>Q|nC,,&fN|ˌQ$p v=T."MzrUOWI5i|4E'\>(0+(W9 Ƒ(v3 ËyA՝QQR_193OPR4]^1{P$D*{ml]ӝ*㚎;zYJE'ϛA497n?"r Nae14KPXD)ewЉ!,ꄂ >.ZSnn-=`V'3BcUq:1m*ZdW)cc{gdfaV{4m.rŰ(&IlȕtsF@(X^#A.HtqV]𓧠01E!! /6ܸPtOp3c<gc{ckNcfptTcu@:S.V񹅀֦xDE;tkN?"3):vvL4hB:w-[>)LZ֢*}FU\c,Vtr1_2]n&>iF7CӨhuz|>KY6<2 œt@3ps9T[՜nV l} d!#08^Pn*Tc$wUVNdWE>Pw^ceRcTC|Z()t?I|bS85Vp y?y`R'Q@VIPdԩ&{ B*@(X.rݱ0oTG1Lw7(gz!.V]~ƗE,φQԕ7=`z1ׁe8́7tdm 9Q50X?u>0 o#Q5e]iZV1Qc-} aH'W;B"o$s;+$I?FyF$:hvڧ\cOYIn^|?b>,?m[6z/c| ޔqTT -W=/NIk޻dٰ3?]w=0{{Tg /]KVx}Oew˯*[2q^y߰ ;8hR|0cBʪ́ho!R?OEkXEUe/=fiJ8&F*E*kVO4 w"AEWMq:]W42?PKUR "gW9-€N'gT֞cE3"@AF=m.rreY8.8 kf@N9ɈQZmIg=3V6qBo[:&joI~6*1ld\*јt ExɄF1-$-~NGRhMHBz>Z_33Z}C̺EjC(1 ;\5č+{I=aB\$@qpu6|T挊)(^2Pj1PPy1<:n;zDKMjVQR5&c(;Jdd"'r)6?ŏW$_ο`Ȇbȋd&(ϖaHz V30_fz!{(˄--8!|] 7:(ѵk[ 88o1%LJ>O12Z_Ls9q(r,jAXY DȄ?߯VOq "Ob  RUk~:ݢesȡΦ0OGDJQSsNsJLjYS5@p5U/U1nlRHpfUZ]_oqdA%+\K/DCN4]V*aDL E-T?毚*H: 2-@@*ó]!JgVlb-ٸNTXօ(9l l}Q R^^rC~$`4 +2U]8 ȣWb!5)6i~X]`QU`-ӆ'q C&]q:PF۵AB2@YXpqugҵppCG0@b.mK)@u-33(Ӥ!}ft)< ,GN zl*3u \ho:j9l[<,eP̀[6af YdBPJ^ԁ$]j~Du SuP.¡ Uozgi :ADjF褠 z#:Sq~W_^RD~Oru,̇T=Kg0CUcF&|2I.pmu}xXK~LO}2ijP=` g/ 5C5)xb[dhŏEF݄'WecHBTP`3NqS>?MFLbd$eG1Lbn<1Ve~"Kr=-eiOJ5Y0 Zvʑ0 Kl0GbJkD=y\LM˶V w $'T3 ԝdV$h7)*kVG C³"BQ x%/&+?\og3tKٸM2%iGgFFOiLfgr8i3 x xDa)7RU; +]e}MXaW86]ْ?{֚K$7qY7nYwaBQHಯ=O9I\`0.o Ky޾i)8Nw湶ȀX.ެqkҞ;]cf?sCm'2,Mt}>:ܲqN'Hs$b:RZ\BJE"Â/H۠L$2>3TF僡c.dAZJF#"kJtյ%'Ȩv'HŲOn'y\R $-DMKHH>]$] DKIn,"&)-\ǰ."z491<_+k1|LjףI^Z[cseRy Yԣ șbYmR?1|4ykZ 4:M(%khW { ࿇&"O=8/tٺ%y/ѣce ?R9o{k6NW  ?+zZ֔s夔tK=M[ϗrꜞ)kslRԘLE[={+'[FH1y)tV'Ku_\﯒Uuz$j)~Qu_UL|GN_,yjEWè>1DwF^}z,9nպ">xNBcޏ>Zeꏥ hU5ۥgs\U6i}} Y0Fv^ΝOWˡH@|0'^F{kڤܵd6yy]D~,j&Tݞsuz,ON[9rbh)CDQd9|[׻s]<<9a{#[UN."e$Ywrecgu0#[$Oj6$դ{z)^D~/7CNnB`k6Joy`H)_ou#v2ܳi8W=ed2ۛZ=G]ܽpBE0;p#BI. G _KvaK7*WB^t9sx آw/a~e,Z=[ƛR:Jng,C7F̑ v-p7l?EE~c#OqcpiAӿd[ ,˃뷾 فB8sRgyi^[KI&a2-CRՙDOj>nr_=a("1aV>m?kOeS31S[1Js#Nl2rPf ȹ~O-6% ie]E|2߿d!Ua?7;Fw1y濋aDk~'T.[{ Ň- Bx"P( *0;ǑH0rw@φܫ,MeɟRtj=ܳcory6ϹO^sO:TZx=t +# ]mݿc]i$h3id3ks7AVׁ*^늏fv]t+芠t63LB+L0,AAF 11$G0 {&tuU@o>INU:uԩhl|8 Q<-t30 vVmm?OCg`ŕ{c1% ͷR7l>wFO-@g3Ha 5KHv/d1ʂsB'r1~B׼*u|3 ,f`Szl{alK}c0&VN^(~@}ٌ7 ~ Շqpnu. )@c{06@OsysT,IU( U; aB,N]G2}RU+7ņm~e(蓴Q>'|O~>tC"8Nq '(wZrz(8u,RDAC , Ge偟b#^ wܽE %F0"PJƖS71=8Csk˾7 2Hq^g;T_*O@rCr(XI{rd{h hBk>/C0}K¥ C|P.&:+*yQ Ëᅣm} M_6<KaG|%i7^,C֫&wPs`}JB>h옸Rn4yOc<;*$wkrN&be_)xs8q$1.fe'xT[?./}TV+C${$T]a+X+;8e v`j>SۇP_}Pʩ\;װ q5x`rKA٥ci˫GfA5_ Xϫ˨u,6_5U||KioBofVtw -PMkV鬫ciљzm>)vj]vˬ? z=;CWO G@ŽPCt~8SL=LWN ;'\lӦBοB-}[Am`Ksai̾Iuӆ,1ERu eAJ,E>T#f19N91y4l=셏^c?](dB5 J察m!XC=t|ʍVrPO'ӴhL_ um@#PȲTQ%V|HMsH*]y˫66:Tm,1nML1Gc K`EbAX,sP q}]of؉[P]H ,1mhhi` W|E/1j]:Vٙˣx9~;"7V;@~@+ <3Řˋ\X:C~iQ6eWZl0?`_1#Q2lZˇl7wͿK*/>@mR4(U2V3n=mޗ2pqYZnocZZM[& w@udlk V0){q:큪a!1IJ>[&K@@翹/ꯩrf5wcGǠ>W$ ;~oV*-)oQOX[uw1m"% '[(&]F£ZToK8Kϳ]wC^Aa)t<p;-N&:>]؇n*_T/A eh$ߪ  'a]1jOyt{ Y/N ݮ|w?22vg_RᎢo5?1ntG ?mTvG2vj|HꙬMH%,CAB~GЧ|JDM|#\|Bb|덬T ~.JNa:G qxC#z=&Ԟhs: ];)$Dt39mbcXwXz_9)W,^gDžI7Ͽ,ZqvY.O,R`$F +NBqA4N5~v.WRxvTk =rzbQHmmP_ 7P5&f!6Y+a4)ˢi{C$ߺϊD4 `dmX5zT9Kp,>ޡZڤ$qbsj:jNٹ&hFQHIe` L4hkyQ<šINh&Uv۴۴fmw%kͮ]yK,k34heI֮K A+Ī12+5‘Z#M~C1ĉWY%iŀY4\i.!D%$>c mBT\yW&U+E*q1 ̅Ly#1Q>h |ȪJ Li;A UJ15DP.Y2#*g fo58M,DiQsJ@QNrPO& ?p2fo:%3y% ~e0-@T5E % A?XqF( !*FӨڱ=\~E$HX+ w:ߏF)8@P;ULaGUP6DT[UA|6TKOG "QSvfoF$8EQ6*OMNK?N_x3qZ+?T]H32z?FDBhE|CˠIRd#Ұ7<=^קϊG7~|#ϷxB?tֿ ('+Vl[v0L-T>jObo~=u%{z>v_ %w&>9+dהvJuNvߨPyc歙W?ܹlSWsX4d۞+bӣeWz+KY}8u鯮ېwe|&=|{ggo۶sX]gup"HHHHHHHJbBgx ,2[`vdlm*^&sV (xS[% @m'۶͝mNlۮmvl۶' fݭ,8Yy_^7{6ƢG;`.zR #2<ӲEQۅ]!Z0<,վB B)b 4H207XaWk%kեg͔B+3TY{%.pkH^E'/d=e\j^Ş4 pj&&p\9=TΉz Uc գ$-苈ׅ7{ŀbfnjO |n9IgEXeP ضzkǠiɰ"Q0Ͷ,unZ)|dǩG7 7<1]j5ɮ6ǝya5xU¿1i?)trSAL‘ĩ3՜}e=%a a0oXi_vS29lxAz;]$Ўc'&^>"WNUU0vi4 $ʴMpP.C=(zXە.fFlɞVt4Y20?KIt*8&'^Bvi1h@(ѵ=iYcSS2wI=8< b*8%rʫb%V>+AhKphG}aN?@(e#]xtZ.mK[)xJnSIK=a2[${a#́{JBӄ3I2'=,:j?3  #p= W -P+R*yN҈@1Qf u+Lib*t@3F)N*6rѲg UaYs=;_w{usJnYFpžqrkby5-Dq0jdpjRP,3;WZ15*Bzij_Ew(MX)cm@ށ>6t, .D?o1,`T28KlY>LY5V& xV^U\ɼT•YsΘրjC-wR?F~>]jK$C&*1 )(SKnsLg(QE2>Qf83dRXyscqQu5d/`4)f&a ( OEq||A{w{#%@ )/ѥF+z>iU},J?",4'4'}2/C!pR\چ#yXOcIB7 xAl ˯7yu߂Iq?g)fSšc͊㔕Mk6Prq7R̋H|r7Lw IGb6`ɈW<8|Ip0FBJhv4 |6#Z1̖#f((6I ~Yq>?9ELUE K2fůFu-ׯuR6>dL UqRsbnn4W7w{Zo%7H_2>JTb" vQ=65~Ge8rYDu&v.O^ k8Vǰƺ LOz{lvNk:xW4tMD-˰YP5xy;Oxtt"@n@YuȺ${ <@Gc%rP˞Rs69jtS+LQ "ɷ΅%19]E~aL<{~Lo`)Cڬnf1.|5܂`*,)Oqg%mvoE91̅9kq=~c^>EqE*E*5 F~-POsGR6tϲ4<<-!'fLRkҳ Lm ?=Rನ*vI*v~_ݨVo+nph~DLsЧyU;(%6 nD Gqu/NVJꨪbC$p!Rb_d7H(!^KL=,x[dnJhcYR%p&&~F#JܩK!-ޔj+~bR<ά*6 O筼^Dcvm.fʪ.FضJ9oN[2( i1+vbчhr5.՛2n *8GG:?ڨBWH#9?b^KqNIfy.[T yZR5ouf p?/ M~/?Pa_rôC lfG@U$2[-"3))AqGTMؚd ?oz#gM4׍2Zy[C4fS4bqbuYծΩ);(\" Oާd5@u*qSlV=Tx٬=~M,i bU'7gm(~Bj75j)[uŴjl|jp1vm3 d[%|Ysp?~Bf3s88UNԔ,I{ɆGy7_~2>O &pK_ISPI| ž\/fRNŬVJ: fzke_|"Rq/qh!I 4|y1(iT e1x$t^O& ku':oOE& {rZ &b99>b[Vߦ XF@LP4 "PM)bDCg`-C'%=Z ڐT%pf~Bv|ƵBg/,+[#1$\2Ф2`i98) k]':()W J$QBA7D`JUk2# }B>/oUs,^ۀs<Ӛ&pq UGN7/sϾ.%nosH䈁} r^\f#jӻYSwJS hm(9@!g&CU/po}{y延monQ}XH&S+Sד޿sW; r.=O' ~[ڂP+p aGCRM2:e_zY#ߡ{m`gϷTw7NpSaڳg/A9¿ʖh gc\d[ld?.|0\KF]R$»|rM>r J}Jf֑7pNhӖ f3d7b+ksY-%YypLk{o2D0Ni%sbBv9\)<SJwMC)*]xݍg06}X $}h3'.||t!3Iz6@$?:c`hnٯNS]uۅZymڴI BAi<ĉ5Bs0.4l`>T *~4Ugfc&_MD%ޙ&eolmal[7kVCgfpQL0W%j4帣:>j\߷zTݠ!qD^s_ Bz= _8=vdQ)8PCSۈ 8FiHlXڹُJu&Bݖv1G=yΎVJU'MǼ5/?=q+.`4^. g3Oh*i,=o>;X?Mf"ܞ? ̲1 x}Wd*d g\* -L|X#D; n 5T_Z p7vŶ~P[{]z%pzN:y+iH",?lVj܄xs=nnd.J7.-k΀&.v+ZǓ22BuM`ll&)G&Fiz\dFn"]fM5ٗL 5hD-)F>~St2y@eakc`#cȂm-h-EdJ(or[^K@$c$EQгTIy_^{,9WQZͺRN^RƝ_͔Sk?9 0 Ք갷T{Oq@]vd‡a,KplJ)v1|f+^j<ƅ$cƄ̨+wھ,߹PP{yMr>91v:^$6 P!_*+x'@<ߜ;îFMJo-Lj}Zk7v~~ a^eN1kk. 2} (&Or}Ht%PV-{fj&ߵ>5i\Ԝ_:nEت', sD>3}?U.a ;- oO5ɲ,Z*An+)rwKI{e $ϵ?}>~Ϸ@U6Ͽ*)_Y[!τL~L%id}XLJ ˩%.#K[Rku 3'{b=I=:huOyu?aӱ$'&'k|Dsb[wIy"ύJ rY̬:a,`"?؉;A~s?qt ;Z&tg_aK27[AkIc˟O_Zb܄5zuOi6`k_9DZk ,ܸE+^j Y)%%oeyIi0KfsmĎynH"RdlO=v .T"CXuIo:{AQRק6m?iW&F>O;!&]GZvH*s9 dE˒' 2x=[^ܫL4v"ҷ|593,{pdnN/1]$JK~ ;PڏޢK"EfNV1~\W9Gz렿a=* ?d>[LP H$`(ol©A5]p$ݮ/ 6 c誖+TS?fZCpQPP.=v{ >.7P())`?oAB&[bNe4NzC!rUٕ>_GRyZBDx-mKzUd_Ah/M=;%ҨMѤ_,0Ջ=-!$ƐgYj说=77 Ŷ %"2_mؤS_ șPQcnb~`ۊX1 Y޳bеӤsnmHS^GRp=SsTNsFJgd3>zGj BO;jm2Z3iRcګ&7E.Hǣ%1 wz:yP.&IRqp0ۼ-Q'!j9n\ H+@M{/UM2+5O7lO6v9T+%K`(5='#ӯ2E^A;0f.%AUI\YB"<>v*1dx}!QN^Q KEy8m=~ Bxj÷4QYΜ̬1w3 IJkE6fUc:sF"/پa<(RA ˌ[%xj%cLd.crZlcIb揫isFBO?Lr SPue<U=zL`I6Mk 5Sň6j1 e9(U7ZH>/qrmV[(ÝĤS~!5Ī70(^5͈NbHJӭ;y?Rz _͸*+l>1˒_/ :KNԏ7óH< GfﲫHق(K3R5HRzZ`yծ g߫Ȋ nNjmI̧^|u9m>ۘWCIٞEw}jܿn@;]GmDS:]kVy8NnBm;{kCbE4ޚz5- ޏomhn.otZٜF |uoTk߿z(|Ămfo :yc|GxxOy \o,=y,u(cNOP18u<܊u2'>ozJc n!  iJx !xbM't'Lչ hA Vx' 'IK\}tUABY#RF1U*P8|,12LS@k'a9uF1LpPA#Y>U@EcU0+0stW^7 Iݛzww($!Wb0c2ga;Eئf&TӍ2 T8#d*d?Q4gʏ .|s6Ix7:tt~ce8QYκw;ğ:MNڗ#p{# n_5]f"#zxulMij W<_Mk͸k Gqk]K5u bNz"ZԂLpPSπ1<-`穣qC3x&Rlm9݅1Sumj3+T5uH+@P8(1R b5x "F l']bI}NɆz1G=Z{DOs [od 8`(2~0C1r 2 aTd`T n*YS&(ĉ-B2e,rT.`2U DÀpZhib;1%ATpUc 2c $JUSL^ʆN( 'rL.#-i 8JmF95 *t:Քcܦ)ֺ|IKVO#^2lf9OV(g'D@a*D*20\#,iD(^Uϰ#^\LyعZ¤|'i-a:ZSΕ8G ‘OL)'ʘ2,` J`Qd伽P $ Gj('bg'7:ÜԨbEg;e%u5xE‚IOYI,OoϤZ f:Psn~pŶH1* Xb/?0}VC> Kcfa̶(K;|GpCV|"c-A9b{{ tiQJiuEj]Clm)E B}8U91XC S`N1- %JER},ݑ1hW9x^p1#\^_1vȩ6+s?V@a PD^ϪW6 VjMت Q8Z 0Gu"pvU|feȧ_9 Mu oD,/zj~2c2|-6BѴ[h?Tt1^TaGcFE? ڪA4 d=Wt)Ւ~"~ sS `e9c,\_\:;J6H΂JL \/ЧxH"ZzDnA}«O<⡕εTon\B5spU/8 0cvRV̥>?"Z*K%ⱘ(Cmn `P%`MU➒FCwk021wcl4`ΨѰ.4pR. zs K9AkPZĝqKOzlOya ظ\m4Uu .MU_` ໡o,&$ s9֨qdc/QL=X=*lMCD$ZD ,Y8~ `~u`ML(8]fـh>[dz#[DG?>'4%O5b@F:pLq3T[zѺl^m;}o-#.g QV3lN}GQ* ARsA'4`D+gֆZi`Fz(EʗLQLdJQ4#.931u&:\m؄u[{1 A5MN6X=bu4-L$(GFM\?'"6ttb)8ԂRv轶GzjϏ7$R Kԓޢ G{R1&5^*sϐPb$( LGlaߑ{;l(AA1t( F%bm~3DRhx5"?xIcaL,1} 9"t>= GP.aD#.0⥻Tγ߶3A:UT$^b+p~grAyI h8DO14+77©x"iy ^mM?~{BSۛHhzQ=ȷx7jMl$\++UuMobkM~=j#BMJ hڀ̷Hɏ֫ Ik״I6熦k444-t$#:ᝪsɓdMmFΜ2Z:pd=ԢKG8z]{#W". )$(ڑOX+k+ٙIi]7l};m.w<4?H〷.i4 nQ&{[U+5t- '[. 8$99//ot \ qf D#OIײ1#3^\~:Nȥ=ؤsPZbw==_Z!!M+S//e`O]^Asٲg!Q7T=f$ǡQtǐcȻ^t*g^z54:6 ;RCB7ơRK<1ZRM^oFFY$/l'_ҝX6 5>pc;?1oLQz <9хrKl.w:N'[{pt/:Ƕ,>tRonx+,2,O~tR!pwW}*yގ߮]pM+/E+#8UYع=9GzCEW|sznԛ޼zm/~,<\qztū ]IYH-RҺ{}P> B/(i|MDv]} 97V?w[K:t]U(F:5v#5N4hY+oӫHRx{sXڲ,آ}n47K69k1= v,yxi*i &s6 '-ko bKmw_l'IݬO@Xwt[;夦2[>^2Oּ%rd`f#;ʿuOrFڟ dף>Hv.F?;(īȡg&o  ,T[$ILrl˔ ʩ$o~I~Zzwd?O!ڋ-G )yהr!/3Sefm>; !C=nEA'Wq6 ]O -?[-&dS{o'^幺+/*\{ɱ ''N[3ZI'm%)}gOm!2Q#b}]s+yig+Yt'`#L݄ӏwKZJsL-'iJL<4~&~%u;O&d2+1R?.᪟MY:_6KMI<^OcH1eDΙ0ұotRoi5/8J?<}B!<2&S[f6_UbflIw^r$hq}m,ʈ3&YX<=!]mypLӴ\Ȼ+<%<}+wU'GZ+,!iM Gᎂ߫<;95܇$zYBK]Z|}xt#ad݊_r扂YN ]*:3*N \M/μY|rdC XղJ -Wsdid+M?]NYGT,d {kbn=M_U$cl|+E?̜9^$\xΕn#DrQHk96>||~ A Tj#϶$̆JB0b"(*,,0"bH,(z̾{$~h9`7s9sϹ{g✂{ɔt_ ⦢-"t–%z7H 82Ei{[N~S.Ԗ*f6 4x{i9WCYPeDJ:v!ؚ慕V>pFLUtLތLuQ8j*a [k ăE8KE@ǚ<{'yqx $n~mp7%)\Q8epؼv,7MSI=z@-/lŃabx ~X8> zÎ,ģgdjˇPeF7et~2[E&u~RyvԭJp%kJ i~ spȉ)a)W2$xqeY3\H,y,h|l̍s ,R]pN}C+o7i,#C&Jjɣ撵 {7̊Qϵ#ړXz!h !aX .mDll xMp#% 8| Ts7ޚq+pB?س2 ;$2j,8#]s6pL6@nzh aiGsJÜ ߀l&%jtR<yb,-P1.W@TFUo&*nؿf#w:"tkb3lM*/lΊ}%Ap6zhPy_TG0a+Tr ݵ'h\\н[yM9@:E{45삞c[a%唼 ǂbԾ6T <\kz"/u$z}>\ ΆsqA>9^8$ H: ;1UU 2"a\}s;Lx#h՝43V.kuWV9G}ag"asxp-,Y*lƷRh{@49 ޻TO؈ѢKr Jl/ `APxhGp!kM@='AZcc0Nx6(lE^![w9[GA!_Z&9Mؼ\hc &j05X#?%byfۈ/)FҨ:(JWW/VcB+[h{BU•EMP|/T`Qy6IкtFh9a4FMsW ەP#.\'xyC,I+RR@#gBl0#'\m&G +刊z:~H{Iz'2Je$9xPe~*J_7ˊ*qSj2s<.%HϽqj1pNOa./@^[cH>{wK0댿j5/zЙKٵ%~'ZSu.i\yٙ/ssE= ԏGW;JVѮ&:EmlCMS 4z=;8&y:h&?yv6ngfÕ'3Ǒ/R۴*֙CWhm/- Kk ѺYIN#љ'c.Iq+i°-ecMQ~1"" ${^U1j3VQ2C̠5/צa{ƑR2& %9X%/ny3?`y(|\~Cfࣽ.`i{=vPD">Pcc/+rD8duxd G{#4:T8%SuΏsj]Hc0"f305RQ5 6ag oCZ]tjhEel3d^\mar*CWv\`'bˋ$RA^Q{{)[;vftc yrOQ@g3/t}0f>{vB5sdn l?͗" 5?R,\@5A6bvp<79|>KBLA;BĚS+ b^C{-cv^Ji+Otɡ] &P^Ebh=R31˸,nML2ԎFg*z6:Qh!s e&l<>A_m2'D.\ɐx*0]mW,wN#sѦ:y׎0h3q'8X.2]@?|`XVPŚe.1p33p3ّ7$\ _Mip d%|ЋIEFd. RRvvDɯicMһMV_i2 c|JZ\u^\ >5-ۏ"2ZkƧN-ሆ-KhIJbSoxVjB<!TQ?$0ShR.-R09 #A:36M$OtŋdQ ]]4=.OϼSs7LLaAMc7$;(i=d7sJŒ x5aϑ1۔8dg/8i rY1Q=h&4胛8r3UNTbh+>ٯwJn5Mq%<7-,qOk?SC?RJ?X~3&uOQߧNyڻ~rú='?ݶ}ެ³']InyK>ow>>{6_^=qU.wr=FLKfz_|lqS =z}3^u{ګNݸ>άi}h뒺GKwd=wݴe×|[Q-w}ׇ/?Lugl;T{JnܹO ^}@֝ }?(废NYdEYdEYdEYdEYdEYdEYdEYdEYdEYtfS<xA mdPGV*js&c+@cj "xr% m۶m۾q29m۶m; [u N@Be@~/y{dBIeUorC/`Jv\]S_c"qFDu |7 $"+.F|"/\MgK;F)Kg[dόxK}o?ͼ_R:RfZ.eF%TCp ջKa:%ǩ7? PnE\†can(:O'./~,&]u]zγI!r*썰x6zZl=춥(;NuW iW'Iъ _ϕ%Kɓ0UC&,GIqt04oqjCn#ރWƛW4#EF7QtpLTX__| '-gO .m$HՊ(5VrO#ȑ)Ƈi+ӝ PyߣLng}(3du(?sLS](Lpc(v hmOh f)']e aZm mK{H-m0 TQiUM,@:w= @<}]s"mL{|E*-<stbjISMV׮`KI6<N,41϶]n d&c,; mR6:P4eRCIc` _"3"dM/D Chn*7[rDË&솲cٙ'%~@0f3'IzyC)dh;t1L00&ÿTc|QㅘŤQNw nɬa Tk y}IX=vj#`㷵`?n N{D& H/(.^g9W^X_!ze h;ۮ<N"9-`X8@lbs/~ˆ^3?LS\P(5&buȝ!ӊ)۽ZkTMIPOԃL2IcRf^ ɧ{6<\rqr*J]jAn3hPFA" T+kN>͏. f< 7k\kYUl+$FN'*Ā\$ q`J!R@ɖ_ 6mj.v-E SEjDBfEOeɨ[Dώ7ks=%4 fV8!!*FUIrKV݋էMnrB!+Üd׏ëN[BrLu{8D-$2^pp旵_K5vEhSGM6]meG Qɛ.tճ/ED Z*C`(6 -{*KzRy z9{;uĊApՃQAICz>d0ۼעB/Up3\&_~:l Cz DRg^Z++Ǝ+uI2&%q_1xʙW(88 Z}^fH: r,JsM9RRX\g^lۄȪ^EkFQ`RjQ*n0jxg dLF'oK`/bcBw5K±#ӛ&zv`L˧HYDCtDz31ˁ)\īLK/!z\:`Dw~ngBI 4:s'a9blb˫M솄 `. ,>f;֊xF~lV. Qx&\Z̄W3V}Lo/M[ ])h8TD#5q:6]]o5FlC1IvC!UϷA-Dɤ t5!cعbTK<p'ucs}6QOuQqMy^a a/[]o<~I]c\oB9@"iɭiWR"Ac:FOԢM1c[wQ?ɉ1[nVL `@Eq,g^CO@mUK 1HRDڳt'(Qdv}},kF:P>`:(f *%bQ9HJ ^: =pBW0qYmIl̺Y/Y35Lq 3g5j6oƈbQLH{lA`e gBM!=ެJdE X&+^n9%YL(Me̤k̳dGOIV_0-jŌ䪗B%c8̓@ + k#K3/B4ʏy$:ڳ8:$XM.H.ӵmv{y*N@ުĩ-,R\6c2YenJcfEHOOG6b9>l3"fa"F6JAyȋMFMJw6~AkT^{ 0[RYRшB8yPe KE.F%QzVg1o*ND]R+-(?4I|ltjrlRjy'4ФO`Dx>c+y(J2L`Ž iD^~1,@E$S,:܀MɕYȉ[+Iڄi"~=,2A@&2 Mɢ&C cnIE;)Ż8W<~ޯQ,1/B`<[V͗?22= XVP=ZLf(DT@ 'fIT|g}1#b+4)yU'Z(&0ʝZS1-pNmN9CFҹUC[H@d>)Ş@M%FJ^f eYObmЎG M!Nn6|);=[SQ77_7~*pDXT==0dF( PzjJ6;0Ԏ],8,^`ҜR$Pzr:?/䫿kv~R]3{zN.!-6҂XN'P8&e3)M=A# 4rߦ H/@qk:r~f.G&c[eCj~.'S踦ZRD-†^8[ZLmx I Ľ\e5;H0 V Wz0H7jtsj[VV 5Kk1 ^ŋԍq`h=-gc݀f 8wHޡ)XcW+,l#ڃ1^Mv{uJfޏ۩$ *ŽUkNQ1vHTV Rff>e1Yb갱%Lm%+b>4@( [< =Cbk %8V)$JѬ,f&b Zo;Y^sJq`gq3*20_5]ͤi=rۚ" @иy$lX)кYtF IΠ--խ")cBdiF>HRqG#SyPpy jXw'񷧹ޤn*!4yc]!ҤtIۣgvnH[@‹vvexE`zjF|.D6 ۹۠^0 `z"/T䣾j4\ZPoj {6(iklѫræcgh^ul1-?su9Yx1?G| wyU{#ЃɠPXqVs.Ǡ ˆ#(z8W@`f Hs*kPkߎ@ :bnb [r"&Vלּ}O=3$2ֿsX>>-m~#`w"h:j2td[w+*K8R'k68j Z<^y[C]6;ԙCЬkRi ];9#njj2~zJImxo,ثuK[m?*Gp}8аb ~K!k 7rl?d`Q1dn=!lZL5hx`B7_yk4p{AwhXNh}a`[8VwoCFpv>@ >FHN #"xӝr|٣o{kNG{/z*E xFī[Afc?@%xؽ@"uw~^YLj9/u^q*c{z{"`;d2Oyә]@hSGG Ǣ0t=e=epi1zmlr!M^C$>m28=n h3Ў-`s!ant`06NwݝufGFenn;@}pmSˑCCcFG<~(KJR.U5"$-}9{\ze^?q['e[č>h2~9* .LZ`JdFj4hGp%~n6rG :۽$OQ^G%s.cO;ٮVshv3,!sLKjԙ鱊fǸ}udSs@(9A)eM<!r<䄲d-jd-q d[s˵g_.0$<|)w ;Ċk4!r5wg YZ)mb%CЄS|9{<|~#"ƣ%3b*2~y@twϠ=WP BuKD _v\nI;% KFE$i?}jxM#Qn؝.ͦ[h Ć@)jBG'D« Vct'<xOPn)%Q7eIȵNu$ve$%5X;m B ">ɴ^ }("\L G'@eఋ&x jLD͸#c:k^Q #uË&4:<" Q1hǦ)Y䈧?u* ]YHrdB/8 $c$R d|G=W7ꈄRm7؆w︎䘭Y[?5Ԡ?mu֌f^5=lM\:j0VdV vzlWjF,smupF嬽ǯgz~>L=[āXU qڀ^BBf{-|'FxDmk>0ߎ|e\6+O"a2KLxV"UŻ K!#-[~GAb;7Pjj(wIv5gYqQOa:oB)'n}dUԔ9B{W. b4eJnǿe⠪!Ͷl 2 "zp.1_A3A3M?g|^u(Ao}Zr҂3ZL. Ɨ_|وxo :Zۃ0m6 k+"g{*5ʀ- XBԺ}l2r8R )ʥ|E_hydj[gT&‡GC;Ff%tһB 0DŽ$7DQ'³}$oMVj04PqMh_e 4`ta̯kF\lHd-}FgB iSؗ2/&O?Cz>+0@Xէ,ebbWf1LŖ.5<^ZY7AhfǏf ;aÐ@ݚ%Bkjۂdx34qK/j/S$K> .~xƱ~AxI˝xkH[!kGyy \:Z\+ (€?3ܻL<Û/w-L_xl08zx*><[:ҥH )*:؅1uaG"iS0]ph䜽qV @UgX:V QuJXRPgӫ|"_~SNvqi:Hjjya{Bq;pTuqc UϩJ~vҎ^97KDRxMuCgɧࡢ' ?޾<9 w,U̵)DVy!a \TC)X0Ty-4wW30} l^_ lFY\fssFڏ\<" S͠}?(XwΒiixxCG5Ky,fy3XMH\vT֡mqȥs+S7;`W?6>F̾aqL+c0BO?v6K:*kh{3U\*IƩ$$>; @t q-/BVgq1+sJ0K|)KvKW8ZU/-jzG}<ģ;T`eջ1eBVPp!y0GB2o$i эj3pcqƌ VWpp0H^̺B!ZN]` +Z=gEn֤sX?%#rb0Z~'dSX]Abd@ b03 ^¼& euAix!W"?-[0:+uW⤢#o 'fJ,m1?G T$Uج ̟B1"d,)4:KS!KYborH158I&䷉N 4hkJޓk2ں4֮k%u-H)gʧ&#( HS I£^w1|?hRrFY>X4pԤYrC&s3L^/Vn<X9 my oc}*AMz1 f+@r5 v$ ݦ ʋWXoqn!XRDp<žMBm@ĨH|Csa B͘\nLJY>"0VǪaB{BHعTBxZm ,UKQ lܤSXs㭏I7ypo";ޯ*L +3愑/`bcpˉ[8v INC9i6E)\gN|լ[uXۖl\TF1ayU,[K˾IpEis,gݨg.$e*"SlmcGR{PLK⎖3gjtl.,+7-hȚ]e;ٕ1^PƮٹ{\ckK-JF'h@)\:_,/%8wرtt& DB@<~p 7J쀩ڮ0zȀZ ?ejL;bVu9]:Hi40,\k/M+=^Ǭb>@$otS+{,P6v Q<@[uIn=O>!\w!%6;dO:$G9#= VH{4R-|PyYv5uF=_fi)D Y砻a c-;8{a{_2r p^%N6yˆŋ/WddyD[P+(h 3ZWL4yK&I[ *\z_Ev^-ˀBd)BerN?]z ŭU=YcC]wg5igԏcm2*AJ 1'͔RCU,&|"$⊚J^MJ5WIy{vI"uݐW5@ O{J7.$d *o_Bg gsL1I,~j>P԰N,L(yJ罍M{IgORb^nC W}tg Oqwt|O]AKzSSOdҏyXB2>=q [:~u9Izjk~`K^e{֐WSRE7_lUR,rF7"Z{Ri[1ěqγߘJ2l)7o SGb%m^;OOݗWܬlV`4n{OwM;qƫ"3V.9\vD6Ş_擃X9:se`>n; WӢ ^}Q$T"8纵;II}80>0ñJ9Ĺ}u\/as)'8qUۂ tk'wPr'4|bmpEpD`mұRC=[x >[ I.W'muv<_p¤l%%v\AAK -5 QvGH5Qs@n++lWEvE Yu Rcb\A0~)A$Ms DrC)i@ڕ9hW`(롐&c J,% 똍v\byl[{+1~XdNqs6?c}9n]|*ъ@≄Hm~2c%|`%}+~Y,>KO0= WRKI:K7Zٔt.L:%Od҆sIȡjLuj >.}|WOGx]!9l.;hP!HҫИZlqCX&ՙ 9B1gmVXZp۲ɦRID0SPR?+3 SM#[ G-NS(^ B\)3m9Z1 yȴZ>I YqPikFLV"a"JHcUGoF!Aa31Z3yd"f_o"I% Mi ]4ZJf@Tq,u;`2jLyxB E0B!)"q!!%ՆJL dSt)@` MjIxXW.뀰4Z'P$gEɵOml'o`s 49HJ0a xIJT@`dPxl. J.Q6z$]a459m@j8!ndʜ6J'+[Q(8) -$hJ8Pd{ak<%f؋{fFR`S} gb%g~pn'RA)IQsڠn//tcLЌ9H7ǘ1!, RҟK=QRIJTS./xJiX纝m ;rz(`{ " |*Jin¯r!3\JܖtZ*Ix*t/a t@ TVtэq2TЭJָ3 ݂FLa|SU+nBJY6?C eJ'sg(;œ_5WM~<rv, n4i8P4NօT>9&nIraPMDqܡ*#ho [ĕL*zHS%/0?/Se HddBҰ_2G桤5x~/3Jī*G - WLͪ\S]' ֥t(#l"]D0У3pJg3b1U\ ׼I#3r> 64'吳纕 ȓ`WRdW Du)W0M3/:tqoQ.0u\Yv?x~à PGssGR=gLCL< ӕ{M qfWmJ1UGdNˁԑ>+BSQȒ;oyPb |t_w\F [8iauXE->Qć"څ6ϻtPtl2Jd3WS:BCr%}oUM,NH9'}%UF7y$2>z#ɖ\ŗ*-3&ǩRv6R;\)71[aYn|XvW/VPG*Q˛qS&Sq5((X^/o !sk sհIP]I=!lkPTy5t*8 ~DTF}'0G8%x®D*jZZU.ebs!Dž46-;3m0;#UtT[#]BmgAc+t]h\הBߵM_oYㅱNX|NX=JJ!ԍ\8sEzn6PZWHcUC҂Hc2FM[NdsS-ER_:fSŴO*09çV|%Ac1&zڞϴ?xm 7޽i0tĉx1jε q 1n-~񗌱#_M?mλg_r'{k1׎4B7}al'GldΉlSg {~:^x{lWN|k׿>u"Ᶎo!lQKvOUw=5j"wXgOVP~̯M1%+Il7-g;y]+[wC7q]kد_zQ|q=cWlWUe3\1.?| Xֽuּοϖ{54Kxwm bm|x ;gQlưz7m&ڟiً:vhwc/= ҿݸu_/Ƀت~0u~ռlpvCis!{ᢻ{; A[_X|8CgKS=g w۸aln |`X| XwQlg]xpg_<`8zLeKu]& dowC`D97׺_ }9>q]Egؐmxb~uÙ޹`sbwe}s6^e<ɫ{Nr5ư5^޽;C:..n^j*J*cõNwm&ϟ6 $^Zkakä_?]cTRNvz 3@;S#;)lϖ—o԰u=Fczگ]p ?~]v`ۗӞX4^qxfyQxw!( iazL.}hs܎:^:ؖ|oH>ze{1z o+,}yDknb}1^c#K~l(dM'#R0mm92t׋#oo|HdXr-l+oΏo 3k`bxa)~+{5*XiB䷄uE6vl|Ko[,x˲l#+gS#نc #\Lncl <GwEwS4l>{c%hrj|ԴO L6-[clf2$Ϯ!7D~3sLd]n+د9}vRv/cnYŶGXֿX>`V/&F_2ݸmu, H{d\?gGz7i:z uL{0~p=k'7e-[d!Q7uՕ䩃 FMDD8Qcgg&!D3ΌMv2f4-t%CDlGT!*<#B!m5l/m?/i.9NU_9 ,oqd7?ϡ,w#ޯն8fː'agF6Ԓr%/t"4 `ב,x5 $d'#r%g, ˩p6~U0u|BL,od|BM7Hi>/@m{>d-A/~&]q mk+Dut&Յ|3H(\ _:I* ڋ1Z #- "jJnsPtZ{5\Eij`±ί;Jwiҫn;UCwR5Σ]cp=_5pZE51$5~aq|bvgR:v;~l'A[?*l Y:e-wyMRK3dC#k:ATҮ^:L)B%Td838 {yPqId^Uݥ'8O–` }'!tףA߀}+로2@=dL=mīNB`=Tc_z  )jhP!Q :$5{<5OQ׎]þ P..jrx̹@|>+#:Bfk@CQ7 ؜A2[y>q5*aMExnhߑ킬7ip%]HLЄ ͐,9f jоϡtcݞ`ߖP^,iOA~o8'rVX/Vi$TB~g#3~$WֿP'o8m_*u? ofSZ5s'HyyHֶQ6s^rDy|ZL-$R6^wWI u!sT>6XNP;?-lG!QfyJKvd4> svʮ<%;ud ;ENg,}ԠĽЛMy^lòN2Kva,l ?|E*_@@kA*O˰ O*vHn#iq=/v /h .v=&\T"U=I^OuJ/Bw]St jNӸ}}yK+fkC@ʯ!W\MI&^=k7%QBiOd\U]_Cp,?7Q8lZn<$4/s:d]HkaeC0UG( `<C[y9`'Xvr`@\N|M!BrayT4a\G(";'6b=*N˷,m?5{uPE9·!} w(R|.(ܕm >7c8f1M`&2ܻtesy .5;n:V %*9[/! &kśKC򛝃n>(7qn*DwKɮe%x1/fہv[֋9\IbԛȈ4wB,e&<) rKY@Wnlr,Hd 0@0O@=́61_(pr(KV08ԐQ N oLwFώڀ6<|Cy X7$QsĚy<)Rx(qޘ3)/6VďS&}ֻ_t39}гz`ڃ@c>6W3m"wRҘ#s Y]6af+Lq8َ{QN\Gx6E>¦͚0e)hIfI =Ӡtn,w3w3!*b 2.fM}y.¬ \\\*,u)2[ `gþ- eR'x|v@1>"o#K7 S>0'9‘׏D+eH:x~AϮ qSjFV!VU}m'Pe9ަ8 n_fU#Jg7FP<=got mo:Epz)^yeb_a$_/oLo+ 7KelahEjLQ3U*nSK)k\o@em?+$Nُ!F?{TLGgÝC쩺S4j=pԨu8T$p&@l(+j֗x%ⱹkl*DhlL.yn>fJ* @?C%^z{Irs@3|Y^B)U 4&_s_6kOZ%aܹsf !|_)?7c-ԛn FmQ^1E5A٨TKb#jfwGWi<7f)nޙ?jZRySY={`VE+GI~2H3.O(LԱ#ɗSi0)PR Q"r{VjmJ@k- C]LLC~tf!LID'Ir"fJR64'89![H2Hq>j0?i$PrPQFrA#(мIs(D3"-Ea"БrՐnôAM'C G[h ?"Y1Eُ }B hG Z͂xCMVƍI]?F^S!}KP_&!/F]u^BBz"V~ά5 ҈7"hEYM&1.BgD *z: /(dMXzOg\)7Fӫ5h}FWGf7fhS36N椯,&Js]*ܜ9pɩr)VԑHSkaL5Ij*&.zY~``IeЏ3z?5f6l%5($LJch2~id!{w=-ygy Z|A{,^TJ0;qF&c&z1 cRWa}I(4ΗQ)5>g?\^&Z3G&]*E*YC ґVS(_2R4ܞGB̐F1Je4"CCT04]BHRUJı&uYHݔshʏe%;뙂'O5pZ)T#lY`g[> 5#8 bqJ)C3h3s)f5Њq&~2>X8o7Q4EZ e}5%w6| ddr [猚2Āنc hudoFMV*$QGޡD <2A|3MR!3AC35b9qE"=' C [!C "̿#FV~Y]5:F)R }IB+%70ѝb r9OUլa!biu±K#jp5a#$x*<٭*SҐVePxAE\.|p}fUEČ!l~r`lC?HUKrEd1Y]U(7/L際A_vl81y0R5a{k ZczmntJ e,5h!'99/~18Γxѻ銝Uvì̈́af #dreoYOM x-"Zu4S27v+G5v"Ù,MH8KJDJ(ԌҧlVh5rg}VfY46 :(EfZTBQFY)im٠Z_"MӬ G-{xK,KGP Ob!lY9̬SDBƚS0&'ab M WcRi0HcĺIvx^ʶ<ԮV"Sՠu5M> ; Mgπs̿?Ryޖ1h!?=7(R /2ư9q߿a@ޞF_|gU#}S>ݽ5C_~G{vSus?͝]/0Xmb?&oe:u;\=g>̜!RM.+ 띄~c_譂"竆aYjÜ т$ٙ]7c?oƶ}\ӂ΂8a!k"DNg͛g#_+InכO8@*䏍ZkğN.X'4?KFm ^b"/ubs;?=br|7a)GO1?_BD(dd8,쩤'n#n6W *,ԷI\{/AI2Izi1js=28h;.<\}g#_yK2(;p7|?Q>AKCN=~Sa8wz.+8M|e) idc1J9>Jkx&f4PT) dZ$P:P<_G&n= ~ޢSUP`ε9JyŦn/V,xi^! Ǜ7jآ”q4Yph;smjs7RѮڲugZE2L Y"C*ք2K"z[,T1 0="7~f&Hk\9HGT)MS6P֏pV2.FZ;4| y9^Waf͖<"Ss3G\2y|~Ϋ4qYz_[&QNxn1#,2zܨTAlSҽ_Qw0F)y}L0;EkaxM.DY1N熙 vT}MwfB(>X(ZE#Nuۜ:Ѡ"2uICQBRYHƤYy#S8C^ BBitFeraa7S5:,𠧜Өzwh2*T) 14=[qqVIf8%kdН]!My#G82fJI0#IBG'l$6&4y֫ljQwwL/o lߙ^.kC]a-x`>Q@; FBrr15\(.i x*}HR٣t@(񠷻F?Z@-1踉y%M}28J4|S+6o. zcFpK-TIq[]ux+0:ҡzu柜Z&/t7ie puب7^};}kQ^H[+ G&0!O]I> كZ>C o d$迬? WT/ 2v0iba}F3,bO0N24` Z9xW h▋Ԃ d>xy6X`}4GluE-X`DUuqQ))kW ˭%"Gk$S-P$D'EQګ,ow덖0dDxfHyL&q{ 9ܔx*Brf0紬|W9K`(zPwmD&@z(hѩ Bax+ | %鬏fDJ+h |}G٧hF֞Mf pOX x+FLGy,E-lgâ(@EaŊI9=agZn¯vs=vIXly!4VY˘AՀ4/| i2UpxXtV.7PEo4!TMiP[ 6rkEh7tOjVWu;d"\JJfȪv- GMJFV+ee:tI|CJp/SG2tun|F2Ģo.%y \SB[_&EW ,)(sVtu8 v23uPԾ&TS^hWVSǤ(t5*I'sN8ʨk*]YFRc؇fu{Mc]:^ն.4e%]aS;.,aZ' ms5bh92 [[L04ۧs5 E= >Q<fדI8P\=+%Ѥ0g*[Ea-mi 8k'L? Yh {1Z+üڻ[S*3(O!Պd q!11>G(7v*ɚng~'OD( \0d?duJ}|mW@B-wj=`L6u,k*^Ƌze^Uo^gW69mުN'sD5! d &EMDŐb1oݳt jɗ5OT)*nɗ d6~$D y.Tank1fN/ ]EQf'ߚs xKYͣ4_ҝPQڨm8IB"W)O`]^;mh/~H2kKIF,h8mG?B8*IEu=EJ/ZOa٫=J#7;Ǜ*!=M_EqƲCi&-*Vt`rikIBܡ*L`{8I3 $K#@5 ,?jסv 0c4Lcp`N [&xI^4+Wnmߴ?]ZXjEc]yd*8kbm6-BVLy}JiLx4.}Kds#=S`Ę #@IjղFg;`TIbsS͈D(bפ%A1K0?@Ն{a E}EBa8bL഑2&İL LkH: XͭHՙzh8ȚO#BUSKim^gHyBR1Ɔ>}4?e]12%` h[4f" Fh=R= {%%M_drlZɕבtihI3/૿YLR[z> \|RRd4<TP?c!99̟Qa4=&RFql# i*?o?UU Karm+MIAY7ʺe)*k{#U38RI|L<+ΰqLBN&' q(]\DfM*-#Jo{t0Z)MZlg[b74xp쪺9(ڎѯv&oEB~aΐ[E:"|[".*W )~2WZXJC͒Nw|Ɵtm !mvhUԿRs)P~mJw0ղg5Kۃ\.h2I&}Z+ |'@uh$9k=źʹ`P8RRGDP9mjK f|S8 5VԞb@c>e2.j%px\ϔWe _Hi28O̮PԾt.xT0axf<;}$H.a@5hTF4}(=ӷU!N)OYQS`1HQm췽$[}+/{AEX7]zR")CFϽnY4P:Tߊk'V Qs)ªΫsMVJ=;ڼY*\\8sTv W ~_pX[n4FKBWm :)( qA tV~ ({7thKD 6ÐQk\3mI7΂M/V\ BPC*RV hdW"hL= ilpV-kz :' mjؼzCf.CXS՛.› nEN``hrU0մ;+E9@btI_ 0}ԯ]n>Pytjr,0Tt־Iǡ~$B:[Eu,<<+hb=Thw*|y䯱^l vؾY,K͑2v}<XyhV^bXTl/իvGKW1Ss~9?p]l%\o% ɺ {11%ݹkNyq|$;&An_}L h@:0Bp=ivXv)VYa hY`A^tUy/ l!|u1ݬU;t~lU [ +|-jQz7'YŬ?O;gF_,n;_gZܐ n{G1ANg+ =:t.Ԅ>>H{w_.:3~ݏKCaϯdL8%~[ws]6FXk1W;mZŶ@DTz]9 OOA-2^O:p~FgOC$UЈw*ZAXaD$Lˡ$6m(㹼˔q>p=s^9K$k)nuIDzsʿ{u)10+>-2w*GS=Nh2G&,#EVxL?^#B^H[Jn󳾿;eUf+H:GKņoOUHq׺<Bq*nS7~طx^Wgb0==ʝ|-Խ{z&ue?mninq.ø:yZ M4KdCek0%A|} -Pc74nt(EF7- ](X>+/œ dpbʕ pR $ ~tٺhOrirBg80H2*.,qQh9OiuH Aq $(- ;B6~8g*Y\IrAxLUN|β2ʾXV޷:Eۇ8߻l|f[KK .nCe}m@KSf1._7 ^$,5iXŝBǙՂ[(yGN-h Ԉ^eE[_XPdHF p_V qF &]80 ee$ΘݓQĂ| ,^vIIIw8.Y$_7(Lb _jTaG0k9`E&4LFy_DpOJOC@p# r pc̮!ձ9Q?_voͱ>a\Ɉۉ{8LRR=yWuUBd]YyQU flؚM(=%zTӉnUfb;[pw: =3n5CNE-Dʦ;@RzJu= k_XC*`3УuTܤvpfE6DY0L#])E7̎T}N |-\) pj>n~Nƾyu#yMGX|]ʥI[{n &ʰAj9`ʡգEE$ȣR|ɹ!nz,灑j5VQfWhtra-Oc܎p4yщ0!'c!Ե4$:BKC..[4͠vL+ w8bDVt@D}]d?!m0z1#svPq$>RIZMep5 O0DW4T?%zn̶6.dĩ܁*.̸Աau\Q9pk&c0u,tb/\ˑ5ZUXPcE򒥂1B+K(_!ofR`ۼ =HS1;_nң}*ܺG{Dp SVaqR^PCn̴G3;4TUXPXأ1>̌005ThJߠn˘Q/91, \ۑ d ,~cF)Qp"qmej$9Q1U\Xydq'aVޕs6Y+~˼sjߩ 5C}d>O,~;;DɗazZ)9E5Nas]w3=ADހ$s &yn6_rfzSLP6lj:E4 =QeLy'[E]C%Vޮk7нz#7' %0=YzT{l~c i/jρTA{ʓP77mab;>MgD^{dɈ;͝ڛH.DHx5rlwz)x7ɹ待ͧf'-I&NިLVr +"b jUmrmkV,A{]k;~3 1n׭7W @뉸 !@,RU)jx*}8lg`"/<.)V>'.wԹz t̙mLc[C>)nzFUnIPf݇I(  >|~`4d9y;};K:jɣY' igX\G/#OH?3fuJSv3H?H8;/E ~EzYe>sHT*^fҡ\? òkq& x֎=ZMݸT"Xx \tu R=ur4 wq:vU ϘJpeY0PIrr8'B*'j-EH~-8`2)T!S[;bną{dN^شuc2urUn^fk nZ7NFI8r] N^m|1V- ! j00L!{7Q" bYf׊LG79[4LTpUSTL֔י6ܼWw&N?$\' ;y.iȈP}0'BѨ$|q|FKm5Da]]7ATPbǤt_x*6 iwI*='YGosARn`1$ Lt:.28<@GK3b>lr97Y+f&bb] ~#t&X6fbvn*KͿmA:q>jwZ!+a=Cs U/kkYqn`HpEԢ0zR dq\Hk&*-OFق.k*e 1  #k8I^tJ\v#~,ؤō̒z%ZLʡ~ЄwM4B-k3u%MTv۠VZ8ԂC iwewz 0C *<~h ?_ +XhȨ|G΃:ҤMӳUA饙 xV3kxzKCz-LVS8X1 rUrM&jǙ!eJK-ӂ-OL&Qpn2(Uʇxđ. s0 ummGz* /甴xWy0puV51ǀr!1F^ʟ,9 Nwo,x]lo-"ö[Yt7BYAT7T2޲7admKQZd cfe<5mh ]f5@~R+pIUUlo9Ǥl8%%Ǐ^7\( {?6Y$+(!=;mm6lWwػU0FXӗzD#By8Js]ŒreP1w%Hv/wUJ!ao^W0:wsU/&bzX2e]!J!cC Wxo,Oi \"ˣ[ ㅱYdžY=xEb9-v1^$Y+r&zے=AF?J!?~iojJ|vU^6p H$CrUH;~!F@Jp\dsE1];هkclaeP̢Er+$q`M )VbBh&6]\T%ź?٫-"d}``-yF7N[z^!vGY^9LR׊ V qu{ (:H# >y9"1!u3+ ^! (6De=աSDg(r^bő4LR7"O(C|p!cBhvx:k/ڈZA ;V9k Խi.ۃV>Yg:<lTsF GM9EHmr̍nOĎn himIf+@v8k+P+-ˆ 3+m&+3 бQe*;,ǃkHC#ֶ-NL^}pY{!^d}wn0gw={D]XA"_qK`wK'%حTLFM3nG9:r)S8uH '  ^:JUX($uo_PG墬A ~^vA-6}{֕ x-g`GfT֒Qäٙ! Re(eL{S%jfF-|Aʔqu~ͰIeuJIZK0}25AmmƯH{̝3Lm;6? [V]_?Rgij?$>j!xw}$ua[)HJ*cE*2ŠSbA? B ? w"xI i:?3$,:*{roJz lxT1.N=kqz Fp;b7q ^{gCrg(q9ڽ ?&!?,՜.Yr d Q]U]٦uySt(ޅwx%FYDcM"tXHiԓ(9:]QM坿uZm~-b!Wrp|mk6%*˦cSE[e`mqE7x_>}TĢg6)5סͪ umume׷E%᚜>[f[ªnʵ- '}ۥ]˵7[8?g݂`h[$?~39~ho0&foYx]|`>i4]jM= Ï 0v@Nmnx@eq][7~w| <\ 1? mOq&|zby?GM x5ۮ,nJivQe4~e:j8ov)SE}uy 1s~v +6ݎ=:/e7!+n9.k7qe/`k[!bf邢B'<,߯5yg F4(%.<_4޷aNnbC:ܼWiSAYe/hugţ<`fFy ʼN'1̛)F{P8ޥa=?=Ѐ#rUٛ }.h0'1Xt3xfh7hτCm8pf8d - k)(.Cm STyW:Ӓ$%sʴnmS*-\@t_;weIw;HY:E$,;4>ƒ˷L;2 ((=ANmswotE:6x{ t _\*']ޖلI GI 1k> p}Z4}MUqb]vm=2\ PiZ>jBAWC&{SLxG'ݤmq' :?lwy.ҮSoMЮdž.VrqԠ @x/aGOlh1.-iP7M&LE-yzQ}p2bfkSEq9F__bB?"ʺ~_0=s?L{n;z$!BQP,{[]7wk\Ckڰ?`!׮0\ҶO&Gc1٣9 .vhp`t僑C Bq]/gEL*:ݖ;€5̅ˮO{ƞ? )l Kã8*jK֟9ŏ㴜hw>`<mQw *\Cjs2h3Gn<7 D^fRiYYgޕM X`Ձ)viU]t'W ހ )Jpo`rDn\@B >Fm yP4+z8洮}pAq gtY;BNռ-<{p}QKp"3"Ϩ> tHtW8#2\_?x&QwS׳k>pߚ rś q.d Ń{dWV嶩˾aHH m h-5]S$\xNE6Y"hM@_WmFam8I`fS#N;˻ G)ᎉR"|~2k{}ھOewMq;v=^t4á\*h1u,^"!;B|rS5o9q45Kw@PgO?`63"̎Zˡlf3T]&h/N.I@n9ߋtW=صMVtuS[5.LZ]UpxIfginۜeEէ?"͓Xx=?DZz67Oj-_HZUմu75 4OZ)AXeDHk5Hl~VQB3~z?f rl'WQmDeČl<ҵäe5bkއk?)s8&ٴDp)Y>R``!5'Z}%e%EHop!ӶF+}QE~\Ro rTqfkMRkp~$$61`rAbQX 8$\DbҪ$ kpuwBHL Q섵F}%#$ @0xn^$s'( $Œ/Hƻw#fMke >X7G0.?REb_\ y-_D"X?G4]DdT:c/p2Df1EwdLneN 11\!ӓŒ 6 ʕ AѽyI؇1# N-7SDE&acpNeB6I ~$⁊{LFDdӴ@p+ ")H($o\V(u5z̨G"5IznD11.Ռr#l(0l Wyp=z@s?η5[iˁ2ô2qUؤXo_Cp \v i+@.``o' ")\jdig]:E('PdvCoIX LU+: (>Hj G=I CĖLn\; 5&5{]Lx{vr?/n}G47W|MbyNɵ8O2f*юcǹAF+Cʆ<}oW*NwA,{@*2φăD)!GEߗ׫o/KOMvG v'sPŰ:cq?5*1()-?a덮|œvmǑkG9!4ΗpRXK.T2: 8!g߉~\(m'8iabѐ'Mi@L"LЕ$/~G10C@?}YZGz*B 36 9KGx.pr#KN^/ p_̋`hЊ7)2w؜Gq_ ; ɂ]АFG|.2Ayc@CޛlI-pe VMR蔃eߘNAboL8 }vu]ohi 35:F^s(\'c,,(@`7! iD2>=v$zL3]\gnzS&068otpS*Kya}z9l 1z҄ bIj f\)#%]d &=u+w̽pJnw`)vpT@YW79%+ftmkӝfPr[㌑P@V#XϢ+w{[2ͪnq5g`K1W?1ƛ{W0YD0'ck Y6DYv8AM$Oѧ%>^Cw'm#a筝ƽ98#:7>c^ثb[,]o,כ~S5.kwV' HR[G\i-rKM.{H d*@EB]bסggU][.2k<#pA4P8[ BX*4{`&\ȵf.X"-.[ПR@{*TäRC;l E1]?K6A= Da3T3ri_e&m#)n&me *9_55fDkqE%<);=YvxC"}=҃3LB^ȬÌrlƹjn]&bMrQ{,d쪿Hv'ȨmhSԂ-GfG] uCOKN '&h#8Lw*xZ"4z4ڃL=<y_XwBÌ0=O {"13jͳgHVG(Ҕ;:3^}j^=$4gǼiNJw3^Ry®y;om=shSs%8R:ˤ7qڼ$4/xDLZuu 򼵭+ zWrl!i:3I&DvddnxW9zs gKI 4RtӲ2 VVm1\ˤZmSb,Le{h^;@tr2_{YO-oE*m%p(l񀏰Gs}1Ry@NH}`?̘C{5=Ryܵp" 8Υ476>~tXt*,;|\GImO_%UDX/ieR6+`:_*Q}oNp u) ;կa4H釐lPͼ $4Ob1^M(HIPFּ-(bvh_@؉Im@u;ET3ʶ z4loW$V=PXT55 o %1 '- jQ.}VOY Ms(%NN3p-N5NfL8H΢=#]Y$^HG,Jϋ) %8v<ĎJ5(E'B Mk, 1n*^ %KGCSƞ'9NG)yCQ3jlmףc1g@')M%vPPˠcpZJ2/%blq8+YEȓW#傍~|7Y$@w;BAJ|'NGrr"(  .DM aͿͥkEY],GpE<r_Ӝ+O j왩?i܃C)͐}( FܝP+ky/s q䆼f/h4ׅ#i1r=&ne zks_H#'H>3n>azWH&;:y*9xjZ9i:"FsA1O[zHS #1#ĞfaH2ZC/1)O(6ӋCF '/\̊L"L&MBbjE49'bbc`X$XQ2)po+مJ:[^%t%RǔJaϑgՔ-cl~7L9:i+9[trJUMiC'׊y~#si i'$?6J$BAd&X%X!rq.Ǖmf }lvJƙ$t='6?kz3]ׇK|]Y] ©hPڂ-t\ SΡ?7Sgvy!53"| Dl '48: 3]8sn>ŀcaM@Gas 9͂~ e0_0cN~eLC:SN9}i:$-~āw *> Ol?҈eTgҚ<3݈Ӹl4Mdbѹ%"{*ҪP,A`{wr3|b[AXI'ſ,썄9(OBQ_`sNaw[s=VE?g%S"gNv/:z54$Łfl&XK[[?'$UuqC3P%/.j-]hkcId x^zBѪ9( ,$7p@|sv@7<,n!l6 C|Pp2Wa7@mnPp77VdXsD1Fp&1`(" :5sW<]vb^G,j5ڮ+yqɄ9:R <©7J$Lag 4Ϝ^Ч>|0BS16y܍\D9PW6Dr`lJly{mo!TPV#(& $qk pˑ+JD$7b ӌAQ}OwBzwʦi?hI=wPA_s).%Իvw@VMrUnz fT$S,59BGB0+a"q6Fþ:6.tJJ66i$4' ]q8×V:"%˽eP#%XjU"J+Ua,NxocK#3c }a!Ò΢@ ?%,B^#蘝Ȕ,vlun:JoP3/%"D#Ɋ]ȀL!#ȗ{E2gq,2V?L-fs '8">DZEpLQARYύqz,6(V|ؾMj\ZE)CiRjs?mףl[MGob:ԔߊYR1"'97f|~cD5.6fc9 ^.6 QLE$bhf')XF$s8/DlmlYeF;}ScEV=o7͗ U ,8h`"&;@)I-Vʌ$I|I8&Q~ڜm;wrc4qV ^Qp&񽁞8vU+fı **z9XRƋR+YqwMUk0 Vn<"I0 wiuSJ,lR XWdFꄿ30|.T ٗ%ĺ;boYePĥ50>VBo '+(!O=鬖(]c̢h牝gscp;<2Ǩd L} ptrg"ߛ2Y]֑h(RsXT#o {IQs&Dc<l5k0QW"?\<UNn ۪рQҲx]Nz +z tVa\>7SeUOk,Xs^*vP>=÷o"lE"~1EpQͶK#*f\5+ TWoRMКf jQ|'쯨aTH\=ap fVQCn c$KIJk97Or>[#TjSy oD4lÓs2Mg<|}ڧ+-4e'$[&/4;E&D2lv\H^@ . *D ڂlK^X'LA+~ 2s%ͩ*Kk2=:J=OIkol߀8!U곭8*0DgnmhfnN3il2ʔf,.?3GdΦKS[p;({߻oDD#0h/z5(Lla1$syႱ}%"@ '}@Ù~!߶0o~maSCT^ –Tlasp!cs-,_Bfîkl86rh5uiQC+#.[)/nemZ҃շQQh{8^ЕzYOj-l,Okb{[;n9_o3rv0sTO`d39ҾU&"8CpM@]lPkgݧ.*8!I^1}wŭoLm0R,1N Ηk-lX"yg9,ֶS)句+>˥KDOȹwVmKdP R{/;k`u9AcCxpʂTZA7A Mwa 0?-Q0 F(`Q0 F(`Q0 F(`"xI0(vcKh2I]AW0ͨ*=~> Axh8xʸO]_Fr6 |e`gn6I|wJ$/q0f1YZys<y|}Tq,Y#93;쮮U]fUya+1UR)&Q&V)|NdjZ]{+ƞ?}WmRN_u5e]6vUK_wMw3Y+J/q4>鳗WrjW̷U/V]~q]*꜒/YkgU g LNPVOCUv. ;얔YT$U+7e,& 0L.@U5+۴zuLZ"<J?4ySwYYa#G%7<+ˬ~֮JD` 8u7 PZ=,z^;Eve^ +sbJWn*VA9|ͺuFRHFβɫ7nTaQG 0Z#7lUx :m;+;Y}U7S mQ" ^pt9Xm^7e^g$*e׌lM|Idu}Kj#!ܝˠ`VySNE"w ;ӺgLҺweRҺ`mhzZ=-fbK@(9ʥe+,4m.fBW8w?Y =n౿ 땟OnMo*/׷6#QA}e5.ّ[W'cׅusӗ/ &$饃̾1tt3pxUbQVnޓ̵{(rP(_#v0RY=a Tǫ<4X[61lQdnʖ ?ujOb\˺S Grk/mvi{zzQϳ-gFga{pZ9 ;YqYdbQzl9CAǫnrL᣻HKBqaj{yW ?~Pz%_s?s5o[kKbD'W#_GU}lk?#w6eŤ|>FƷ`c7|%# fǘz5"?}kѳ#kG[[328oanz+0XtWu{ʺ" neoQ' 70TͯGMhc9?ݡ눷DU.sޟT5"f?X\Fgݑ{US^󂰵^.p;]^(N98/U,= #P8'c q*ĪN:KA+Xqe]vT`A5s >jqV8<֙jXvv.Imo4>Zߐ]o3|Qٞ勵[݃ Y/#ƌG)WlH.ceUkqϋLҷQI1_8XW !),wl{ Iy)VU4G1#T;%L**ʝ}(=O92{Hzwޑl?g?F 76ϧ7.vP~UJK]p{MIro ~Ϯ"\veNؤk!BU/Tʪb\b@uog)#t6+A~ jAcZ@݆^@)]IbuY;ދVaDqH4#ma֕whj(XP ne"Yz0#nƵfjw n?-rY\i-!3WpX,~zFD{4e5 =r<(*kZhG[Uݸ֒Y>$BEerjvzPyH!JȰқOS{,lCğG͗.3%M}}Ğ8}[y1F 8mg Xdx*FvդQ;z? .o[s` *=: A{yW'c~m_]tO܆$Tlԟx=߇yycsw: B:)ۏioG2:|߽pD z%1(>❴sUODD:5 [;JARB$aK i!mn867DP[%ihm'DHXis'FEHs<;:VrZ4$v<2%M7qJ5 r1S=tȺѡPc 3dظ1RP3BXMvIabɚP @@vډm^Z; mRʅ&/c8R*8'=;kHc!&22s ntI*0TPbAS .I֞rPm8 ST'MG=#lH*+DI2*zH2&-0Q0͚a $dˆHA0O c*@J1UE}eoXz_s\y#ˑs%@: SJiJ"RԲ@eC| u2 ~8'ќP":Q,!rp+&UX.=p*hH0Lw20FeLG5鰶HL ڋUzxOϼ(H`8bL/a}p5TLoza.Bs [K`Qʱ# pæ}/١Kc% w-|wl A 0!eX] ŢOC;JN ۋQlPmb\\12¤DT#0ldr2lL&#x'R Ih{p$$8 N#a?@!h`\Z&;Qn`Ft O 16Lx%bGtZI3T#f4VC_ E$I(;Me|D):ilagϑ_a!QT+?Glrh{AK,P;Y=iz,ez`m˯ `⢿]~8=afD6 CF"qܐLB S*5L&j^p!c`1W/˅El՟9VF9`cQ4G4 )M*Apy z3*W )qNpL&de' 19 &0^F]mbMV 2؎U,̡+^27ub=nlK!%cjx_%h#/meǂ2&ل*cLK{{zʠZy ¥:LjPQɄnd5lt0FwctdjyLR0n2SF&@pZ$&Ʊ݇=Ln]_vUӹ|*LKx~Bsq|lj ]xIj'Nj')=< BR_?Gx6FlgY^߃,m[/<[ jrˋ>CSiIR,$4kbUdVd1X %}ި6nԬ !&IS ᘱ"1-Ed~, 8ib/ >ɖ(n BЁaWY,ǧޞSԬm[p(7(JXRU19p03p$dp!YiDrYXO;~l'sli^A<n{#fX8Oڧ4Riz GY `Xbv"!3ou[|T7zP(< p0ֿ' )]<%IYIGg٭)E5Q4TEpSO|Q毃Ou7e6&#Ib4T;bR;U_oRRݜHmnNjcxAGH&Y'_~:5bDo*)G>f =hvg+M/K4 ,zfKMn.Sf?G%<ݶ|kz3o$L D8E~8\Mpۻ>FIOsV֜)!1VcW; LB,L?;. ōDf6kƏf,S!b*@5ѣT P{ׂ_x7>7ww5ѽ}O^|/@q?'zBuɽg)SdH94eaUKu&nV1隤.о#9Z`sJvy*&.% Y($;ZĆ,NgEo3hn. %$@DzPSzbpQˉTar a{KA>L5!߹H#h>2.3Evc_: m::(_/_|za—0t@¯Dz͞nid \)A)(:L4Y*݂ L)Ҙ544'ٟ/2Ӕm>uĶkkL]켡6ذ}0D#҄Ly?e15P!Szu(US5XitFŴxǦ!XcVFضZ*vِ9T0aX[nd?5Qņ kG @ŭ1=Xě`VpO!P$qFl@Lߜ[7y?ҧ<[IԘnHYsgM9_]CNġtGT)7K$, ;q4a1!E l ػq7qeC>W]`> ݒiAy9Dس+JI KTڑ e):lIF^X+O^i "XZ*͖72۔H$=l݉)(Za|%ax$Y{(uHO,S-N!p}kX7+:*rDdUVĄXPV%G(*ʝvo<1vޙywyGf?6UL~ae3&(9|$q+~$8PH,gݗאQ" O(!fO?t} |r93;]=U_HϹO Dv[vh=3$d g7In^NB-˗PN3ٝ)|UM>e2{dF; n$Ƶ)5xa$>Smdv#ҕx\G*9\FUkcHmH3NPZ4E^~d2S}&4% 6)KGGzOnli ?ue/ Cf8IWT>[zdU tDŽ!ߠ,Gm@'[:kemPʞ>g,U?Wu0ɬ@|i8TǰIi3dѨYߋ(%Ȳ=P (4FHi"jv>ʏPTzL`j\)֤LUYTo}oϏZQGbN]; IF:ޚjŧemJOIk0JNtH.hN ݠ83hI*~WX⋇aHs~R].,hޟ_\g)ls$3̄'$M:'+Pl]˱JЗI#72@nɪ,uSн 2M:8*ҬF%tn~}_(mi@z?;8<* GPrz,ݺgTef,z kO07˾br慆MOlJcdg&Uj4x#aҤ]ӎ@^`' ǗzrxI `în8GG1>3U+` jSZԨ JGp "=}NwS&}_Hvoiz*)n]ܭC$|uy4K"}'ȤWQ?i~r$Emz UOb QKZ@K9.">_ X%G0݅KFܕ6$N" GH@w RON󡚷 IVl-c[KjNCʔ;^+Sκ`iIJl+<c h>e}Ų~w  XP \]A:Bp/΋x5_PLzh &gבPCby o0Xx{D ^G:>dVHFMFayHP2+X0Y!IHxWfz6撝6l.|ڽ-T(@o rYâO 僫ʬm&+Fp*nv5yNYO-ת In|UW9[UϬp `C!;oq]F:$s Ngꋋ3znc̏V2kEqKfsF- bꁉ^FImwUG$Kڛ9 6yZհb ow} J > ,'ύcj g̎ F]lP< 1~mi1dEɯUV4ǸÕK!1=PN "n MƗ %7PG X9=Ou q_բ/uOFF`l\!*)EaK-n# ut3v#!T8t3^B$t`7s=6  V=E\BjNL^ms&` 6&㲧,nm54yҎLN4, 8(fC#xCZ׀1hDew?bfI 9EY.ƁTd#p{9i*durQte8PekºFU h=Pn2AVq(7?."_P9܅\r#c5,3jp&Xa'mj3fS.z ֨!jΖ )c~Ge?SK1kGQ\M@+^?}nȸOLc7?0@~3?>blEX 2?1a /TX,H$^&$o%?C}]<:g C} ;ʦ#|,(H;HX˹L:`:G:^hMr Xz/yh2H< FvaPwv)Z,_7]щ e@ dJd=5pP[~;H VF#yVxSkc6<% y2vzLX`u dNM!Slx**Xj'26Gՠ7DmO׳^b2'`l7S6"mC,-70aC8.pv| nK30v퇫"6H,Hh-Ħ=$r0OecNȒ,DH F QhC6ȓ}6h/Ή?;|: sFv]d. h07G2ل/mDWLj0Y YAL&t#ʝ[ ?ӎ:->*W=N^'P䁳h ^={>l*c<e]+^7ʫً< ?5&o;ԕŠاy+ϦN8Ms 8pck JLP dU@Ԫx4Aoav_,{QH`xg&:c,Ta0U(=t=)pas`P- nǡT/4 58*Cf6IaZ[  p~a& Q\?nvM Pt,Uܸ[ ٨q]Ѣ=| yOy 3q[joQDe蜞'rQTEj Dfq8lCJ؊^S-Invm! %w1 Xs ru qWƕ$;AAܮҡv/_q7Ɠ96:zw,Vapdy7 wNHniN'1c;*)goى2Qn>hRP)$ ŷJ<]H-#?}S#9:1VkDg^p;=4 6v˲6ܭJ~Hہ܈k!ޖFc cSP+7Z<-t+q)f䥞p.}5=hԣm }mx&3;H\[r\.XL``=W6Eܾ)m@Y51Q]Iw>Sg2T}?2dhN7;jNԊ\%M/wgo&Őtl/ FPgK&rlcsaLT^e! ϝ^w* CUf7PB:wb{o0l[hz5yp/VR a=2~F"M aY\:'ޙC D3f6Qٹ,쌻EcD3SvjfoWu"߹&vyrS̅M ;X PK( NJnN< ;#rVcj$h}R!D^9P);-]--'Q<9t|{FAb'Vy PKf+0mU]vt4~eK&̮`3qp8wwij eH:=-i[,(+,&'Al +b^Vt .z} wыcA] if^[ca nRj\ujPS737 ]{Pc}2->bNqvS?XQԌckf2F[MD3v,>Yqh",""C¢(ܻܻX?֏۽ݩPdg*\kgޯן+iL'g Yf<.)hf ލsQ8_havD0ZXL]7C^qRQ,A+03[Ȿ\F^_ޘvk[a;E)smGohI^&}*m q\-ZMX$+si6ri<}~/p)dEVF+`EQEzMWo[LFpTV ߏ5N+~ŏX%q'F+QN]PtP;9C[T"-(U\Z [v #ݎh \?)H+j9vK 6+A#?CYԡ庉emZNaZ1e=ӡN=M*f)Ko.XD!;9o6YBمW {]P,ixρo p~i.TrBO<$d"os4mQXtTY|oZ:&Yp7*V1yk hQJw?әd;GFS]|b*b,)#ȁJ^v}`x͈?}Fo"dIMl<+G^ѱB2aGbwYl8{d*NOyB҇bqm>'y/KrwU>zco'}6!ASp:ENl(l{6spn}ճn٭co® ܊k#i#/j#yo5q:X<)uXhEH*@/tֽ-9lvgߘME'+%ۗ{+G9wI/Nh,,,4{8r!>n؏WPqߐa~.4lllljϝmsݹax0K.$˰JL,&{> xb2TK]}TՕ;(#𡢠y+`3{ A¢ͤ1v(Pee$UeUTH`UP&\0XEٰ~%cys=w>#_e\}Ox']wcv\ד~v~X_ҫP-+of8mKN}>Hx1&l>׺o'zw֞lN[$J9$h7$TkF'F}I@ w@C4HW{ q24v3'e;犉Pa>_ [!Jz9ZJ:¯dxU' @FgQ{[f.G~,剆 kΪ V]A0}"#=0hqj4TXAmLasj6%-@y-co8؈.)ukhPU-hWr)B\[*&4ViY۽!H |* >7SVH$m>Y+If j!.D"H*c%|`%+>CEF=<k0Kn$/=_.e)t#I!]@ab8A#wtsYO*MNFN0jW<"4Wm=8iGbt.)^ j1MX.'%_J0;a43>ډ$Hrv=ziK2R"oov8_a-~87fdRnxW*yxz8܋grZ=X`f9}MU;d0\s](ҥF)j)ix\2SUaȳR$gA/Iz("k1ڑ{Y1Do}4.`|O>S26vB[㒐ﱵMċ l'[SAʙqXLD0GTzb: 2ic(xH)+4SCPn(e#7~qQQE#pPwf;mpQ,h*–oj KY.?ʒ6j)(xӇ#cn9$KP}*ɖDCpcd?Q$3$K4 퓹*S8G-DZ7|Z}Acd5]7*c$ V풑£g5&[sAcI>!&5vO($:`IʍrW=qG{dqgVA2S,LJ 2uρEqMπě-MD^߂$A&e i,S±6@{-sdN'4$I W΀޵(n:TY4nɬb9AF ,0,j>hGL$ʼnio/ٝ03A֎”s ^~H2!Fisb8(uڠ'w9D=#)bG׳eƟG8.{Hfٜ}޶pkD|7jdiibM'b9UW>&d ͸Y|< Z檢?9 ZBfZIb@?$a')Ll}jfA 2^qwY >Cs}-Agg E]M>ZTpN%e*>AhN?ΌkA>n͙5c^0^/RQ })R"7ѕ\7}RPJF)q3X\D k-`0h%$b&FK]26!.kE>ĺ4h9@m"׸`g"s3NJbR Lm'*51<G ck&'a5"g/$twY4M4Ξ?g˚jH=e|c#䧒 |!NvfQ[܂'|j,4S-0MZ4Tƚבe u5oΌq J{' Š=IT5j{#nj%JUV'h23%Q$Ý EƉ gCJB1դ&NMS|A4rQdulU¦fLFMg۔[)|n9_6UR(IBPF6PGҕj&JvǪSeS/DXd{;\UUy8hds<5X&Z"9.zӬRXuj頒8n*U.<I/ma^&B.{+\kOkf2YcwBG4&ΛuTޭ{7jIݔ*PΰùȖGx~.)>6>kIѮ_Ey g 4Жgo6)}o=dRtZ:Z%Wc=zacr=z@PppGf߆ fA:+-Z%0DU\s}%\φ(B}|;g8'-vSWdPK.em)$Q8]V瘧g֧2y2\wpvqy,-l}jD6wP1-ΧZۊwu=γ}eOỄDൌG+CLbbGW֠u15エ;7n$jOŋ6˴g] bJWd !NYK=w7vz={7boNXLE]],6\ԍN*}?'E,qb R]cGb]*6fEgJ-~XZqꉢn|,6%xb+^fT,6Hcz$F@c^uZP6d\bf61l>Oxyvā/ƭXfD+GƜ#s皏g{[(|дsgOA{aО>y|sۼ{"poo%`l<]shoر% ̽m8CH8-su۽9s8o_6Blx3Ek{nelD=7 ( F!?)@c(ۓmO~͠``0f{`(N6_"t/RƟiMe_Mt>F%Yaڇ 4;Mt|RԉW[XdϏQbg7hp ݏwȳ{^2v-9W ϭ݃őocjƉn]Us8֒OW`IHOݻ;ǯb%lu.[^=E>-:9R>m|܌O b-?IG V :={"w/w:N_[%FB8tYӥ&Vܿ\|4)­ՇnZmkrQq8rB[.Jn_}-y5 veF@ߊ_6ĐCD緉z8[@f}l;_v&ϗB|*/| obWK B,Jq[_kwaGV9:CCXG߆L;nw܁k>,fXRlľ僧ĪKEx*]{XTG*;&F1ymFc3ټcfL&FwMwqogC|4` Ei%Jb@[#&Q=uou._:ԩS}+=׆Hp(jҝR1M| e CPT {TC5AW)K@<̔V%5<_B:pK}\%x]֑M= ۸ <: GDS Nmς4q[Ïh \p6R2iཱུp/ ? jB;lx{H",./k4q{ `5)vo{"c3̷Eݕ':f,ql_COY[b#^- oIKYbU Eu.Qɠ zz.y*yD?S_Rv%æ/  ^Ta9%!i L=b"yY~P7jIKc߆@$- qur`5s ]]__z~JխqJZ}+]8mӅT+S 9Z ؆ۯ;\cPC!8 9?R|=n"jcft VHbdC%CFrTUֽ꣣,. FE|2̓B!z֓*YΧh;:IqI/4 7q=O.;Մ! =Ԯn1ʑ v~#.B!$ !-,tTX~q)NOgHl<}NC_=ϻ Fk-r:Ue2؃~[Tɤ+wf%0 ·W}` Ug"+(r%\6 @AĀXXΟ bkE|D.9,ӯGoVH(Ϳ;E:6\b:ʢHP~I>l[7RAc\ _/Ua*SEBb=T"P Pc3llHO݇ެl>'uo1}%uP[dCH1{^36zl`Z(83 c{XD 4~`U;ׯS{,3t"Bm [ O=)[\ #Ku`Xsذ 5|CRvP_&T1<\54c|(ܤ.d>L^*Pe=hqV1kв1}Jju/b*"uBC]rb1'y23p$ߗ/@3|5б|/D2;a4^- 9ߍ-!wNWk U 7?q_F-q,(QuJ)< %yy58Ʋh;`vs:k62V)˧O(KY8$b p`=ƿWQt&麍\䥃j%*ѳ,<:wFIzQxy&Jt`~Z";;ilb.*Ai]t\ˮ^6lxFAG*\ZR?T.Q*Ϭ\˼oo|+*[,bD-%!ouzt`N+q$h/cidG6!s}x1ncKɎ^޸vQ_w _wԱu4GThH#D>RǮ߮b ձ?]Xg vRZb';ҝ3nJW<$3-ȌS {\,ɮz#2o/Qc2mE_J{BCN-tg񟼜"=)?Y&Fjo6l[ >N4뒌z[Uo1+ϱ[5Z{F60Zo5>UtȇѶ!u/MՁf ɟj56Af >h22 vhˠvU;hPٜDc?718>63HOV9 T4WYk;VHcW$؅#:d6F8w~o EI#ע8d,cB x 獊"heN}$afxApC6Zm{MBy酦k-jEM  S*+hbږГa U}񼒅]z~N,`b1e.&1)|Xf5"{K3Kg0l0M}F *{5ti4+X:s`Bd'ZƴmvUJT &ZÅKd>6IQ|sbmIfYI0'c̺X$6XI[㨠 I?JM?wjCQAdJHQHI:\Ū]. N?G-3:MZz1)V%-igPW~Zc|oQ;ڬz07 E"V`I߇FT~L' j ^x(ޏKpR䔂M'X`@#,[1mU[FMl|T+5iFCCtsg/±bA=L9/fL谡7H:;ZK^ E$wΤű EPJ:v&V%*L`5j AXK| +CfNiHb%"ksHEÍ%ҋT*o"_KԱ}Վxs )﮴y[8`GY k0~t%wܛs{qZJXUzk$QSLIj76Y?=<%t}!h(5Vq kV=<]ȸ0wdߵ gb6XF{ZV0XyoGoo)BENNCPdTyv\*eYC쳐g;$yé?zne]Ipހ)fes@]9Qi"6~d-ns2FM' B($ t j((hV-c*}k OnV"゠uJz:c $i['4BU R~>|tQQZ%ڜpA(1i;Ib%!lh\J׬V{=HX9'3V,WY\4ۏWi'"19cf\: Y֫s=DHw@l$TB M?-Zhʙ_9HEqv Z|P* ek7s]ElA?D^;[vYD>`|\*~B )-XŇaH E軌P-qb/GV0b_X5d0 9HZ5| G2%i&zlAJED̆bM28RaQ({x7AghG 8![A827W1*mv:g(J?A5 +[ns1@aF2)z( |c Gn% >LdZN`R\bQ$~ !%Gb;w/ A0kW+*[7[VIi(~ w/<*gA/Jv/1OBcA+}0[f'v%ͱ~vzA9hCm8/fLRP;oA65Qɔ &%rL2[f!e 1b|03|i)^?_bsRRilY nlZR zЇE?%nHeTx7wXe:S><DE8u3:qB*L~ M>h/-s%'JQW+B% 9!+Zr;]>Eq:=(:<^(oE\? r<O>$0'E׹T~URsf.RšaDt\Co؄oiڈIOdf1V(F+wೄ2"Fk^GS"Uؗ'fw4 ܠJȴ UX`_,H0f0?L[z?2PYD( )]G#_J1bVx7H3|p^J''#& |](gbi4'$ @G! *c3d+ QøsLe\//n9XxJN$ky@[O.`FSՋҧF ΡFGkG-l^=O.:NT\Oaи[PQ͊pC YsTړBufL~\(e5,i&-VidΟbn|iGE\:Nq;ӸJp_7k8-;oqIySEG+507Z X)-jh-e PmUj m+Zȋi&&=MOXcR hH¬6A7XvfY&yXw戁Ag31>3|xESBN1EL"߂1F굶MB4p;BOg"qzт&L:JĞ~CIp%4NIm<ڽ]=i*ſW[6ñCv 1|ՠéF֙O, Ā)Q7 )Fu%J whܟvF. yfc.JO82B.`0Lsiaʋm^Lojfr~E -Uj@¦Z ?an} 3`IŖ>MSh {BV5O$Y\5ÄGlY<c"mVƁvCwhҮz_ɇۄz`<+'vy6瀔> pP$Ўv/a ҏ)MGm_*PDTs~(M1>Պ~.2 -mϝi+CoKq@q9tΪ=fo*ljW[m DOg8/ОGqqJe ۥs?^ߋ7i`kQ5B-sW._Mص+i -+!U+8%lAMpYLPl7I7 RۘU5Z1"$|*,ƓX4>~HE{hhtiȴy>M_[`+ s[@ֲu]DL9708K#*MY қS2Z%B-C bZsݍ-'u}yT}pymqT8N]5'C .>@T@P< t{J!\B0T_ FM}IZeڷmXZD8rR]*>|L1>n.iE[ۇPNi^HRs$ K_Nm],9|^/S <㼎8PK.@tڗ*tzcR] ȣcGD5 8=[k~$&o{#)à;MԧJ΢8ӕsβuĉL#՞W7)/{bj+@g rϪ”E7?j*F(띌h.&+4R!D}jwHȄ)Mz*0amVn,)|Ne<r>Sxoe*" ce4vJI>GZ2U$BmL:g#̉}Rb=WWilkk%xQ,} Áu@+ _&uUOcC(8NG6kkpY@eXthIyBS*qk(J /_qFɥ#_ƩiJVIR i='cpoMjU}Xr&Ӥ8mBR(I~t]4HnJܒ[{ Y(g'a0ѿzw4i{K4R ~:V<;h+2x2w7<'㙏(?gajI"D(ϑ:Ӆt[,-^dxfzHS4I4L=a^Y4TR<*JwsF(5\XBEMϩ,l-nxg*o/mGn4?КkxJ]Fu-$P}XY^-+KBh,]XBTp/_Jw V&K37`\!6W(:QmoRהN68 $z7F xLғ;ـE7 4 U5/cluڶwHYPc#QgzxfS-zweK%zOet.$b+|ۋUAg[>,)nu潧vO#u] ٖ~|Xw9譅gCR+?_ !fR*vuZi8GNZ" /tཉ&>٭LVjMnu9R^GxIeO}x}zIX%!xx$ןmb݊!h>ʎo+_x;mBL69ԩOU`yG Q) Chj3^Rx9wӭ/dmrj:844R"⏬t<Eίu&|NQ>^.Xe {S}.z"K(>Ě7mjӼ{{V'W˽E ?M7S-_1u§!ʱD8f[ȩXl#B3l+Nkam"&e4 &w 9ׯ={ޤ /Rk nvxc w '?nf ˱m65\fI~-~pApPL1YjyB~̸*1P˲c"g>Oo m"Z4IE՘a3: 1+Ԭ..K^Q*cBz4IϭXA;SO.!z*GzPR9Ԏg[P>gh])yyeey>chl#n(8Ɠ[.PҲ15 -DgOРk9vVob;YZ" OZj`4=\Vvv;P՜M$:S~pRd7S' &oa*L ,g㵩dfBuTʪ2qi4a: IKxq o.ބҚuIqtK0^Wq=P.=7L,=3Z ^uIjRd[D .۝$ZA\~.L=į/m{t{͂'~VB=Xm'i\,b `..A(H gn;sqjU?VیfF՛}l q*3) bV>Ύl KHy%'w2s_1586`։IB/C]ZhW\֎6˂8>CG"gǯahf=cXK~ķ0@xdmG F?vVs=_7N Ď䆻LhgWV6D~v8}l<+w.WՈ˖ NU4Jt3$ĝd_QT,43ޥzP#[CxhiEu}~>[-[WAZs$?>'cw9Ք c}V tʪvogfưF>S"/dQS/b^D;Hϥ;.闭GNy{fiXnN2uu龂d>5+ꬋd\*^hZ {\z+U4v=iXtB񊰼;[%޵3GQ di4f|p276`?ހEVJDB/A[MgǮ~q΢|<+b ?=IV 5J$ƯҬ+S>oA9 &/`!ꁇLsN@w~Mֳ6|Y k^bDqk]L"JEA^C bI ?iϧcg1Xk}RiEo=* VD&ՔbOPF$bdc $/^s-Ft=$v(_;bZtk'"~" pdwSq=Q>xZxbss9!wF%?}П xf7޲K+iRvЕ TmV씾 aLӑ= TO(J*=#Cj!~ɬ~ n>n}F*Nq:_#uz,Aofrз nVd0;#P* Sy*9uZdabꟚmRu %I:z Xxw$OMK%TGDu5;!d B{:Qg&l;ω~M31yWPWz]<#z[@d= KDd-pԊ/YTeFQNMliV<C_]~"MM5U'J]e- pKM>ޣz3Y0|NI m9n ;,x1paiVPJgON/Zj<l)u14+W9,۲` }%>)\҃qLt]&=vX&N-8MNAEI:,8oWrUI1".ir{whs;5} €f ^Wm=OCnՐH¿?Y@hԨ ğ=)A0fssi:HHyB Fm0ncZ7j\1ɰ/*3X} ~d' H$ܞ'1G*~0JQJqFa;CD"a~'s{X;u7IPl CB$5k'@ieT7WVG"D;&(ϔ#__w~,BZi|CAJG|ŋ1wQ%}0Mw'[]H.҅;{ɧ O~MUU;ߧ e}:#?MS{G =l;c5>G߄GTu:uAPkUcpp2Wp2~Y utԲBzPs#ކ[谡[^O\r'}/?W'KxҀU0hgG+mOpUU_S!u#DΎT/.mXl YVa*JzUM[u3M\dDҌcٯ'e䬃Z5c^B&UAV^}o~Өb 5 eN_pxTeq3R:kGW(>:io ݧ/n0. )G;J=ÈQgli"B̆FaWR+OPqE:|W5h&8U$]"`BUt[9p4"ƸomCb2,Vۏ3uDU84ߓWz{,u s( ]&):-YߛVl%v0Xzlj (gy^>4=8GKF;4H(C9oOWrǗRRʉmwW[%7ugjT^%'o" bg%IDEtJMx Rt(*]DOWԽ=KCtQZV`yu#->82bƹ<'4h_{ƽ($٘+Z"T*/r ZǦg4ڷab@"FݻZ:`yz`k\qM9jq@hIn|/.gTװvtx2 Ii4$h7(# S'{>VE(X4EФKBn"* a}YJa~u(mU^|ԕ+8bhO`ExuK m g (gI2Slkm\vbo|='0 d@4 \g'Σ'b#7 7,s Bh4ZUXI=f">Yö*@Pc4x<0aX*p*I%d)*5l@1"pq y蛺3HCMp*kWpi=,t:ڻ,v-KbK)6ȡhåL.fEeDrؐBJ he!5 dk` @ & m*i" ;Ij"咾S|BiNՖ/ԃ3|0oئh*MRT"剧J2EnMص eS NFD8J |MDA&ہ(ehDvM$QjLxG(vi$CU\7.esH2m>S6lm!Mktj/] att%!:RYBF<=  NXD nZ{t ޼OU3VJţ;&!VQڏG"ATDpd(P*q(W u@Zu]e}dTu&sVb <Uтc`0dE"l He1b_xa.\-P0:fp50ݢKJtٶ&@a(5@G"A4 <9jaayl]ܮɕ(lXEK2P4)/KΥawrEqf-;+) k\DVH\]'Ɲ{j zOpK3iʣ |-s@> 4µX *SB1:Wb:$7Fܼ$K 6MrZٖbWC3T :r' pB?sul24i뙸 9JƐśVǡX6Hfay7\##3K5]tVjuӞ$8 [m8j=r>y-7`y%L82v xPk) ?/`$]A+wTzϴԙb'{(] nP ]+bWo/EaSv Vמ`44zFZ\RgkP>ʙ) 13\3á2ct̞q[C24$%qdIJ 6ȋ?[cAm{ćLA|?c{aw#G޻ɦB1He+ (ϞŕrJ'렒Q;\:Pv. B:_J'`]qؓ~[& $!p d0j,@]ْ{D]uatT< -v% R7mSZdO dizwfDkR|!,:?syC CHAS;WqMkw:[ $Ealdf }rS:k@f=ZvOg^QX&xXz؀/Vn:ĖSߪR|[ܲxt)R| =Cj<}s E%\Q!xS.j8Uk8{H^.Iqn cاcg򑪨JBQ|%%a{x7DTdOAX9bQ9e^LQ'>kyϬ֗'av55{*.}@XwKpm,?9{67̻|V.e&5Y2-7j|1Y8}\~iۢE󽙳Cs>n=+(]Q):,?=^FS> q ' %U-]pe8X]n|ƓN7Jv\1RӋ kD (2H dt]dKKy/T(Dg;/',jZ8F̞?ys^~uy=ma!\S4NwU]^DL3. 'Z..۬#<2^5YP0ܠ':c(`9(%gEΫz7բ^ScuMr di[!İ?;3QWG˾>ݍ~JLXыsI?'xH*\Ӥ ЁvM?7~@w\*[R56U~W Ks[&1v˓sU5aˆM%$,a+&8vRWmLLȳtDHiX9+ӆ:/VmdW6r uq* NK6Ԗ"λ7qVI}m@4/5OqDbPߵ3w<}߻eHuŠaSR˱EkA?iټK1;8|T#\2V|z" D]7)|Õk?V#fo1?>Ǘyb;#7~Ϗy{['ϼQz߿wqҾ_X8^Xp8NBt~|1G+> <GUfwוֹS;' vZͱK0Clv3Dšd߭i]7?~u]eqw_wLUO{WϼVq؊l~/\iUC.'70$rzE-W~2Ş03?쨽v_"Ʋ28U|r븊3ĭoC&ڜ7^2E=LWZ'y'뢱2d)bo9FU`E7gg9q8X][{ gok5·o=묊7;;&| G}&L8&N0N5@c:zW@^c-۸|׌/̀V{8Ƕ/xqhVYO$Fkm?W_z=Vq_1pvc ;;7 85nu%TI盖 7Ė=;,N/V *6f_Y:𾻦p&紊CNJƙq>vCE'%b3 qmlILMn>tRYuI*>{8FamA}E %0jJ7D~4~KEE$} u.}&ȏeO@ VF bLh7TSͽ%7e3rU@ 3kKlIu+yWIkZ8G(dWՎxv/pkq3\ݰQI ,P-֟?f9硠8&qȥ;YN X};ۀLeRڠ20l CZA콛]6JAl9NAҎ7xdJ&HՄT P25p 2[%񖓐`ܙ˸[L&{E|5>d~V21ZV~ 9߱TbWaӰ@ _cmg @WǕ{,h@͈\-X`vRbTPYQzHG S9|{[HcFxqJx6b&>PbKܱ\h]2C=ͶoqAm!vcE.K'F.VAf c TgM̝a1S=}Y`E/xF2hHsNxE&+3+!d@lq E-ҵhwYw4RKZ}1Qy^Np:.UM E5[rt .lpeh( 8ЯKY%[3\IJDfz%G ƩqS7 PH ЛV.ZyG& g{攋tm7+0_o;rsw+b !]`R&AW7}{TK"ÂM\9ڭ~6Lv7xJR?Rб߅bn) FFh®Vq(>ժ5 rV{oJX2HUbOpB}T/&K[Żo.3ڠ7ѓtT׽ solq?jd۠R3bZhrņ!Lӂ 5Wˉ+l!ydpWS$4V|ZLgoT\Csp.4/k L6I*SԈ'wzUHMRcw̚>yJ _kE=?;$ăP;zVk'i'mJ*߬Jٍy?]>M|"@miHŬw ,gQYd4To50YYXd >=[EZ{ oJ,'+#o )A O6d~Js xTN#n5-GDT(Ph>2^,8/^-t(_L=CXXowGaޮ$aE'^bqps5/8]H;&t{t y"G8|dhaw )Z_S(>Z]\CUՠ%͞.Gv+844I؈oU>/ZȔMEfYzEr *7F\(;}w|1ogehhIE~K^X8"G+^Lr D?G#hSa"-,5l)dn]@ڱchվ=VGS&1AR&QqdnIp#kRsF]qɵo9)tb576"GOl79ٴ)= gRW|?m>)L~U\aNǵ >76SˉCRc3Z-6f{x]1F4yٌ c=!^y^|zh( ^l]a ̙@;k&'&峬ÉHR `=M4\XiB*>k 1WYo;}בơJdu3fl6[flnpbuԑkg%Q5i.91rM5ۨߢeu<g#)P*heEhrFl7zj}ͤQԒiRMBkhPɨ!ml0IC-rh L&c|Sظb1&&Ym6E5x ^5ƛ14yG5 `Q / DU?ØhE,bTӆ`hSco#&FCTf[T:=6^+c\Gm&ٓc!f;ےhDhdHIg9t ͣ>'Ȑ} ,96;\ţhf2C%di$$avnWl0ʌdWĮ^ס3u]o3YTF#ZU dGJh(=hFfEЬčhNK0i툈GG-)סZճΏYj I6Rtv0Vk,z 5> a vIewLfGLP$`g Bd08aI`T׍RîU `6Yct & AX)?Vuy 5 2֛IFɨQ ay1m4^iJR0. `*V@^AI9uj3' ђ8'f!:Uyz#ql- ɧӡ!C9fo0fՓPD҃=!r= ; &EgdvmIOpbvŇw|UzݬV20%2E_@m%>>d&Gg_FQXC3I Q8D́i‹zh4%Y LW5v\LyFI)U)sB`2ϒ*לd6Zu6;hK lXA[u2|K8`\Ʉ2`D XuXl %NrDr}f]I/cUM=a$:o}+$RT5[Qg@K +7ӟQiMfBϭBcsH:뜮m1&}LJ=kXT x҃h4QDDA<FP voLgC"h˒(0eq;NPL~;Fd8{lkB͇u/N 挿SK0Z82wM@E}V6Y K)b^8g< Ms<|C;d&Z3ӫ-{nSpU׾Tc|ݸcIC7%Y|1U~Zo N17u=ݬ|պmIڗG_]5vnV>l}}4mN?g|:00/\WMS~S7'Hŏ#^~NJgn7v:qkjOzʭ~j/~;n{eO@ @ @ @ ޟAZx P G0rDqKI mx.2;XL]{Tՙ:0<aVM`s=E]|#Ҥ6cOeG%eAxYP$U"LdFY,LV*M wz}]t3}={9B<}Үk~J߳ ʋI*m;-eU|u edf~϶ݺÿ\/@x*%[7I}C"G(Qߖ1;DDOHOHqIю]P|mR?jr|W%DHWP;0>4v{dplxhessJRI'%` ҭA*[\0OVRܳԎ<[ :>V-J9jQFb.6ExT.gTA.n8R-|J 7\DT jWSZ[YJc8PSdd`« RS m.ŤLKS{)InzX?e&[TjQ^:,8aGz!и}j[EXpa2XjH`8>&$%rh*N̴4',wHUf F eŊ^,6)|3RC#<҃ÉZOs r^ #HE_BB<Lql)S"G?l'd1iMy y8KF&'xG)B$؅joQdZrlux`7n t:d8\+¹bg&3"B- <,C! ~rQ9"%bCWpt%ܥG$bѮ F0<Ľl>ۢ!DlId|vB^:wEIDѺ[5KN[᪁$B4 >pV@ΑX&G.evl0m N6aw!N̠ըp- h PVhAwF e)OU,Ád>AN#pF::A$WVFFBZ%7]M MKduQ_ h{+%QybO^aFA'nTYufB.g+=QTCp26Y*,sW"ٔ5ҞPQSlԖԍF+6kBǑМCs[vj.>xj‚S⹀(ͻ47?Hi[KJ6 L P>,>clT͓ mTrϮ:ɦl<Zty IA#hYaҬ* 0%JuX3|"̒,Qb< هƧ4ݒzX28ISDR';s/ld2P(%o+ &5+1:t!:W6DP3ؼskD(8$靊a{!NX:ս ]2T*o\REB+ߑfrgN-R)FRTkA`pHAAۓ)"/FBE9bǜ/r4&* s"J/ъR*"q$;͵p@SQʑBd/ѴB/m\2OJ\z8E&%Y4бu].F|`5LVSr8ȖCΤt..{mO A.M:%(lIi~ Rx5ƬEZM A,=:w$ J ᒕM\fuldHAVq5B0;@\DAҡ{64㓣 NPUXr>)F$$?hTs( :"#NF$0y6⋝CHm5fҩߦ '誶o]4N tă :(hs/7ђ;}^6l47DZ0͸hDbn6n-ƭc[1 NBWyxEߝ;sV}}C]}soo|щ{ݜeS2y=pDq5gƜK ȦvçGdءĦ7%iwq1arS WaXHYL{!>uqfRf+)6S+ I2,Ň"c{0] 8IX2eH3B[}pֹ:o}eq=MA.5_ݙ!BnF0! D!MH}tPi+@ )Dcg BdEP&auVm]»w:BI'#ӆN+ vCrv\N+X0jP>:皞c,(IB~(9Dgԑ WnxWj̓oTU󓅋gͭ'+ThFi &5 U oKD]lzoWZs$V|ZI%>HGYUUk\.4|}9*6h+0aRC@&")g䭸UEd/ `* pk0=\֌B͘Ѹ 0]_)|@d;Zl1*!#rPkWX9XsHWsc9߀(8t\-T+09p|b{0Fhdpͼ:SJcud Ҫ(UKvvkS4s|Md sֶBsDNUT@dH>R؍4V RS)p<"8!X:DŽs{^98qpNKt<=X :lhLYr۾U=\[oC5+kN13۝hƋFybu bm'X$Q=!;|Kt]_՗I{sO=|5{諭*;~{| ֊10enŦFwt٩^{)Ab]D]i5W5Xlz+Q%CF@W֌o?}qbæ+G59qX4߽gI;"wxTj\Yf=}}kDi]X~>q=]\sZq_.%Ato;A\V=#|F\9| 5WЫQ*)NJ:G8/F$cCg?n#Dk]'^^Y/G?UyԾ^=@_Ŗ Uľ_Smg'S4'Z3Zto?hdcVY'֎m"Nt 9cNJ1K[jsejѷȉ]-oEntH7TiIG@EWr\G (WmY Z\^BS~G`=?m|p@}ρ6(+Hж1sM#D{ǘ|'{o-1b# ">cKmƅbĪkގꍞ/;j.~!Tslj/?zP_n*Ɠ?Y+)M׳c#又(*zӢv֡բg źxhdņoBիd?|tCqgLt=Z*s>Do @}X Tv\w1;n4FW_)sAnHEFJƜv-U,)E~#!TZ1.'7--EMKŲb߿.^.y)ü?O1^lzxҰ'XK;â9Lt~DMP 7,N Q> T$~bt"F?}%bێbecMÌ<"[!~t2*,N-7-X"Y.ޏM=b~A.|އI@WGM0E Q㎟|Oaɕ&n-ĭcÛ|:2c:3יUGgaͦIr3Ip#`R Mv Ҧ\W\BMH!EAR|Iwޯ<*K155 ],W.)P[oGx QG#s f@*F,ߔ ^ϗ[U9 's<.읝odo\o`] `M\Юs`KBs<)6 ی\6- Hwu|c!5C n)uJ^&o"#FqvH@{+,A"p.YG. s 4YC$' cjx߸I7o}DF@˦G9P Kny}Cl|dz+(9 L+On3țn a0jr#wL2_F໼P/5?C0=y7as&UC؀t\:v@tZngz+^7p(дރ)MK_%305Nx khn/{R⪃?Q;Xu/=X= (zJ\q{i7}Oly|IKQ[SV Ԣ=l"*c<6_AWZcUI#騻GzҎF(N2ެN?$ʯ+$ʼnMWKD6|CGOw]՜}%o ę@3ɰޅJ5 --G'+]U%  $f@:OoO PV?ʋZ/<h)y:Za3G|bF?}d 6(JQyk|["R$)xpL}m뙱mSa=ӏնv8p?I2k"W+PL8Q@6PuP/Jp-Nh}JJ$-7'cq q vM[B0I3P:!WmpQ)Z±$)Ržs(48BK~ J #O'`-cŹ'N-f^|bHƍC(8w_e!{+uub+K()i. @{ cJJ>H)G ժn"Πt7ttJ7v@PC0 zυww5SndA?/5^ O G OzO?T=P,R<@`^41sKZlAq*H `J3fKA? | o  A.cUT98憏8?b}3 |DΊk{P [Dc~begҹr2l+;ѠX)U&pCP\jW:~LZ ̡6QM+>\gg6a4ax/~M+ס"58xTy "ֳ_ fFKIku~ 8vT1.s`O G YznGOAt-02vKiF[eA8Pހ)57`mEwA[m mɊŪRdA<3ŏɝ̛_o@})D8YT"Ɓg,רGKs Z)W=PW̤mKxh/)ph)+S ,zyLƁdE.ֺ˚$ uTqan<1xKaǐ()tMe\xqZb-!d3ѵQS޳8wf9[!dLk0 EI/:V<VqrĭЎUtTp,[+EQ}gR}2`#s/Y̶n5mdG98owV3&GonH?)m | ίa;7`i!#kWQyr!koQTDbM>*-fb U#e1 b]Gu,xV~ >{! a3[JIb5x΃&xw$JÓp;;\Y-M~r'~/kaNUb q$NJ*+_A⌇Q5R}a+ގ&5cZYA)o=^l TtvІ/x0s/{KjN k8]jc{Ov:s<oa᳓S(r]lm^O!Y|#;[e̵-PNJ)?+7dđz{eT1_5ߍ1By}.Bрgj6"OblE'QUQ%\Qb^1Ïh=;uQ샕Q{1r[Ϧ}W,8su ¾z_@pjj@ 5 6귺~?Q'AUodc)jb~1Jq4QR4V*\-bCѲS~og%#RC0[ОUmULvF <ų:)mG^+ فV ]ie'CsicpX#p1H4njÄ$$Rķs`oYۖL>&LYV;niH~ dmt;;JJCEһbG{ ~+\@ mbܚΦjto^sR΂DMp)]uiK;pฃ@ ʺ;:x'B&?r|W'[.wỻyp6_E!SL|&8QzsYL5 j,ת.^|]RoOpTNj' UT‹Xq veHzBe%x /UXY/Qk.Yx֮ PMh%K +Q8A^II"wc'p8'OĨwPb؏j`Ò/q dv48$Wx9Ϡz+ƈbC!Ŗ,SuHo|-_B) x UWxTbUpobyyCUOqpnVFaJ$VHg7C95vgR]&4C}Y$PWabSʅ pYJWʹ0)IꁹO̙=?)?&ِ;}:=4'̜0f?砆k0,B٩R[GZ!Mzɢ26"Kahjk9'"Nt1Uo3Ǩjz} FBWCIQ}^f07MǓ_[h2צDɑ"TmCY:C&{F# fc*mSu&:|iDVY6-fG&\0kslݬEYE6:L )P*beEК.C8mt j 5 }W4%PM"А&&f?Oh[BO2)Tyy&dA9DFՠO_hH%.ڔ8 mlTEK=O77VyBFlEXd 3:'dE ӆ Uo|d HIզjpH2-KdN̬4{V<lLIhH҄JsD`sdi o>/4 { 9R=<:JGP@FKHH).Mro0uJ3%+Ғ8zq8Okm(IscP((mVܙުX+cq# Ag JF_x,ޏKpR"u*FC?Ͳ1fلeS_&hbh0=DOW0tR86]|w$( __moTv`v& EN:ۂŀ$VxL+.#WC?-%jZG$2׫YzA/rɎc=sLS-V!!xy(7T82Q]$ǎTmBe`CHeGkc^ 20;(L'  36r]o[`ЊQ`ۄK ݤDhyg0".-%=h0 )痡TAKM 8LGF>0Zhq+7/tgcGБѤ,fތ|87/!暬u:[nEDIc~(ƴd tBrz][*9l7B3#Ko'o }aE+[ZH(+5R |'q4ةEFr{Xhbs׌ l)p$@zyYYSKdFЎuzy3hwJ'bO, #c؎J^Yo7Ȃ5i(!*Gܴ)|o_f#Yfڪ@;/% 3bI) A/-nk80$2'`Mjj"OF^$nYc2hyL/d$rvA[m`E$UMh3kthi] پ>YPL`v,QH^f;5ߠQ2NpM4ՠMo0tVOp7Ү表x$jFKis,TȘ f4##TP`(1D2*T@-_} *]$ThD4Z jtAȋEASc6[_DdYK֫CZ~=Y1 7Ją$NM2 ?%!ᙋc)A1`4_u,08uH(nj1ʻPK Qv\a/O=Im  lxeA 6C3. ( w{ Jr4B4({&F~5嘞Z7R3|~)!WHPW!và]p gA~Q.d%I)Z2K*rq;\],fQl(푧A7=b7T&;SI3ZLdXDї9JV,!AQdkEr BI6q[R;@p9`(8ˎʉRoW:dh|Abqq|^)Ӏ}@;pJ>f6\` ZpԜT`{$8H@T#+5!^qJ ,,5PlhHvdJj^F f+I . qِXlaMGe!&g(jH|*xx1i9z)^',.t<љw@_g;SQgO/Ě."21 #D+yG0V2q3]CXK^xAQ~rjqn~^^2T LY~hl+\/(K1ė#)^(zsЂv & MGl2AIeA* =zGEE4P765ƬG?=|7Cu|Mmٺ3Z3Ņؒ;i8Q-O[M:z+(WźHNSN:*o^v~ٻ=}/ ws7j[o/ H [aQH^ۮO xtSw}qn7+,y]˙鏯FӺbζeڼ6I92鋺ܐԇ-/I_?p֭/Ͼx>u'4M>]'@o֋Asmy׷y(`[>|RAzvIWγbestt+<リo㴛a9>=|mzgPgqU{)ٽMsn}S/=x}~z5x̶tǫNd&= =}+/rn}O{}Sl2!Sc2xV?'k~s~OZ)]AJ7[ZۺvjQ۩f_$7(ۢ${5jQq@SY'Վꯨ@8$wق.+1L3K0Pr"dڹD/ݨvm9z\Y>_כ|^g /S<4-~.qwv5 Wys~і'XlOl]};.2Y dOvr'y.mfpNoϛ LF'z&7lF`3"8Cz( ӟ5DY ^,-}Bnݶ̳ C0:q8'omJm- KX$<|Jy|2_9c|Q&MY'$Ãf5w;ӾQCi m;Ynh7C+ouO-&1mb3Mu$I%EdrR(䍗TuuΕ1aI$iJi2Aq &mMm _yPo^໭@Qȶ?9zx }sOS~K.oooRݼ1nr;18ĺ'ɑv [X_l& vxz[z, W; 0Lm`-u\& wO X0ۈ>bl+h\7=/ouG/OMn4ϲ%]%&tfTYb7LzAmqFaM jw%)9wOXЄO3]. >O= KZ<= ,MM]O,?Dڟc8Iɟiۊ`zC3ţm GOdhsv)fZml" t&ZS'$pvJM5u{U䋼{`{ 88x[&i;0t  WupR)th`dۈ" Г\֩'Ls$ғtTxWɦHnѤ1 >wv6F.=9 <@B,6k_w6hovTaͪn o@p&`1)x)}1΃.93 G"y"k~)EE[[Eu*7mV׸nk\_} ASȗl~ L$uΥE#@POyn0BIUp)A><⧼4ۜ'Qn;|˶40ihgX)'F1;_S"S4;`;5c4uuth852q7:n曺*zZzpghu:%mO4@jmEASI8*K<]3bov:Ow~4};wRM6n=bs}|06]0,[]qOu}/ckޮw'Y焹] J3❻"*+3|W g[هg-8A6g5c}rݡϝ7Iͫ-(p|2>W/_?jg`.ŵl+met98},YO7M%i8{2 U"Wuq0.Hflcsxw<2<fMr$6][^,ޜ`I1T &ɐlw.vXYO #,Âd ܆Y6:W`lfL ;wj[ e$1b!I޹(;$`rOm۹Iv(i RϛN󮻮|Y}k#xY&'_C5 (ϹE쓟x oR翣G}z~>6O[9ieFJꇿ݊ơ+|<&P@H;&P0:1]hgeL|Rh@?Z7`R+˴<5K c32GƱ&fv)ZmTD"D$ HCI-5v L1^XF 2$1$sŏƊa RX1(͛h"zCЌWj55ERe̘Vi!at^oCw;M̈Ɍ x3L۝0n"0JWI#1ކI1Bu ^=&A2u`;aɝLOgF7{#]q GJ hKkxIog4as$ڳ!i{R1&C Dߖ*mH< vex?$Jci3CkjZRLueIQuN}wA/mi#_Q0 HG,1`AO@0d[iO(`x, d`(F01%h+fdfŠ %{ CQѷPL]G P# k2sӄDCTb&2 32(nbInSRḙ\S dh5.j%ݍZ93]3$bL˺ɫH bl Khj6'p<qL0c *xCs\fbdhCnY+g/_&sJ2?5d;ffb&$Ky6=݋[)=[ ?HeT$T} ҩ:&wܥ%*6OM~€i~4ES$:&OMBQH1$"[/Z+(߹^$Gڸ8rCǤ`x4)@a BHs/4mjS#TD-z?f 48S=݉#;"qC&7R7 #5pwi-@bl$6X' $wF WGRb%=ɛ_J?EQ}ܭI8$m~T*eR}x|]*UT>d2 28DĆEX);Nhu(ĕy`![ހmBaNmŒUtČt ^3f$%qvRfqe{Hr7lպ\cTD (k#cͯ&iA=:E|B.Ƃ̥zX; v7Nb /L n,U[蘌)z1fFZDqܽ|E?.?cMf!wWb:iM|eO7l{K*p\#6Ep:WR8MH0r?TD@ΰ5fS/(d5.#`+ Q N_0mր(Olb m.=yOzٿM<K&PYNčH EoGULP\9e=HoE\Ac3]A}TdL-T4"n;nh%J/X 'B^'xTO}HnHBtރ"D?*iXlIi6 UFT?S>HK01A"$3LR쑘%Sg1VW^#`G=BS rm&^Om_6)9%FfS~ZLN3híD]_C(D-Qmujn,lMA) _$k\'Mx=:j6GS<.q(~_ {M fbm90J%r_lNAןS"䅉Zg7ƨދ+bM*MH(Ao?Mڬ m 5,j $k EucG"suJ$xc=|dqEN>h807N)(ô=l;!m>r]"DQΒ狳I;ᑈ)=Žy̜<]&A6_Y&):#Uin8;=+XFL-U_b'Da`4r %)[X&YwHl&1 %Z Hώ)IJïyًWςUP q מ+m #d}? *)||Nq$w[''5qa*<: |!y.v A )܀\EG[ А-e5 MH*7/~ӯ48-@ }`_@&؁N},0oisqFf![X^ / ,`K1cڒmd.\g|hOҲ֓XJtM&]qX.Y!}g]x}ш{B 3MW/$ A 12>| m+# ( ԩ9jL ):v #1Ep},"Y0|,3mZC܀"kYcW/RJtm;d8\ZA5Ȓ Do4E!% c+| PӷNLkt 9[#F'^V2aI1 l3_|? ӧ_~7Rn7׽{u5rv챯qVAGqM3ft@hC7I~`,h~u!㝣(Lj4P5p^U)宷3#% %< ݓͯ?r/RRp~" h]J {q\:+ɒn1\9(a.ͻ/2gѼzqnFĈ@;r. wkC!7bܱȳ+-)ƦMDj#u45uTlQ`綿G{g3a=rzt[>$}t`26PKY~jl卞|WD ͠bdmuux^l5unYDp"J"Mg8Ʌw,ԉ+{:m\:irVgf!k#:<-C_5>f nS!rs*Uq} kprXl>!'/ٌo]:ckb =q:~XGO@{hslnn'/vNe1_C+TX-e1zaHz=,3U sCab n.)O\K[M*[Mo8&DSy/>F;~JdIz<$a1vsׇɱGZ0G"p7،F_i5G!ajN| 88 v< BF7!um,ӍQ{X ޵֞SʗCrwwy%1(MAe *YЛR# v:n{Ȩ`ۏ8r4WE7S0IS=p~:5Qb_Z5r>\16x=~ #j6%pޗ~(Z@4N~%`];pϷQ\?f_*"R+L\C3QW@_S2"м kM&B4:X*Yu fL!ӈ TF+kOG4܏A?FtQw/ cat!C{s2ALMW1`+A\&)ɔi>Hy>刽 ?,fb$ rt78d1:Y{ Fkf!֏(%b,7ݼC(Wn5"`x q+ _!"Bfc ۭW sUyf BОg!p-k7mɭe"L8MlK,ml/+j0^-pnƟ"i9ȕgbr1b>;KQSԬ\ޔnD%osnwp%:6H&)XIŻڵ~( o)8_Oy {p5}Ob#ln"h&YpRr"ٛ'n2qxȒS>NYUF-/',SU##[ӴDyPunOPUKfUāb%T6|+L9Eq ?{MFCc! ZԒn/xFw=EZV]VTŰ몇)rMbod.2y4Zz(XĈ7=kohbS='"NN5?5q%+*C;`9:칛 .OG-{qEVm {Hœ9 2HGU}XxMm,K! V BNF*䏒  %IJ'7:Yktl([N% 6D]?LDm+/1W)Bc:K8tz-c^+/%I5ËBe)fVœ%r 7gQ?g!/\+?O3tApm{mr:7ƃ_18]5wz}y)F#0fd Mz ̐oÜǸs>BҞq?Pc@[/|{OeՃZg 1 x-΁]qٔ'rP_?n3(b3DTcŒvx}=3Ԋqcd/̃}Ҍ~g?WN!!71@((Wӈ'%_s"wU:jK*((K-*#zb2 ;4 r:9/Ɛh*(_\Y[!! ` HA(OG #_@u emAmXUz8xo3U^%bUV>8$(RԲf_ۯ6 n~nn66U<79Ю L/%feAe9oz9gG7{_,VT/LǹD_^\O/NqQ T Zohlf2mQ0 F(`Q0 F(`Q0 F(`Q0LL58͹x0ơ%5U2<{7q-  Vx22(>N]6;ý6>!Ӗ(INz7v$\hh$Mn#3gGkF#Um'{8qfF$KdU^euuYv_$:>NA, H<_sRϦ6nqj?)_ee[Y4KΛo USle7ku|ӷYu;7d=$ kc֖wκ@|CYmٺϯ2mlҵ9iݬol0`{si=ՕrԐ߶]-Es _u CCOgs8ZϩOoEmos5ܳ7w7 zn^{_L5_>?/ZoŠl ﺫZ/H!9E|͝\DMϫ+_k[{Yz7vwk%-&e"?C}wclt^}_^D !n=uU^TPPb`EoMTS^djYTu/Bj eTdʉj]}ZSْ[( ~9f_Ҫn2sBYq8IE먹nr~լJ2yS\xΠul)rxvBllj:N:K A_fcȜ;Ŧ(n). ꢼNrs!;9qj=x6鯤vӑdDEk1#xSĈ@ܛbYI=)bdiJmUvƭ?i:~hA MvkCﶸp+<˯=@?߰in{u}Q jKE{ ^y~xUq>TEMZ*"D}^Z><jlj=XfeX Ŭ=NjXzOmӦlrCUGsSazncӆ6P::*2I,2'W{dꦾ]5'%^hKֿU:&(Cc=aa݅l'ig8Ԡx Rh~kmnnv;4;{5.tt"9+*h7_4s::nl'W咽\^. -Uپ+ EO| +o1Mz2I sۇ\ I:7F{U֖/ϝ~^?)vuu4V.:l^oh6 l;J4[ڊŦ:8K(9-1@AͩO =}ױ% ٭hX<݅+Gp-]릙vm~^L2q4qd3W]҇\N 5򮩫mUz~b)r(gW=Ea,rzrٺDM]o,ײ5G4PNn!a"z.fȍ!n:ZIg7AoG|rg;翣X8?ɣyO[%!"[.Z~MQEu%J)3PԤDQv^f'B [ı8:6iibwBS e{U9( !A+hhthhCH]ɤG#xIz*^Ih+#)cVq:^ N1D)ql4QT:Z16*T$ dc0u mϘdt; BN1Ji w6&Lh#[8!׍GBVұlsj#dc3c6:,ؘұD m=4DF(U||<6w'wGB 9Pt$IԬ|H|b׭Shb46B8ĩp^цFgy^es>s)pt\$qo+k=&d4:JE$@b"#'T`!Iۮe%DR!U8$U}sCp".27$t6K !ձa0 kf* .28ƈ{Pnێu]5.JDE@k mAˀ*G(EZ[I+yyiK@PCmyR)R`5 n2N.yK-℔x6:)cAn>hR 3D15HG Pb 3\d;|fkVM'V\yރ`(-) FyH ]X8XG'J^B2HbV3ihB夢&T8:!CfC}m"s?w"y>6X*ZPȫH[JԤc(+焬q$BE!`ѣG&>^pA t[R%$T"KN:{Gm&p|ۀ˜ :+g„C>S )HR!$:$N,ȓ%27ƻ^@]=Wq-^xzbz(ۊ .,|%RUt_)S(OX0.DS /4 cF2,{h i1F}& 4:$d2o"Mۄ\$B颴[ VYM؈0Fm1LQX!!^˱ LEq^prFh %݋T%RX7%lhH 萅 } Ǧ^} xE0q 4u!tͺnҺb 6YHHumyPTB>Dēg:&ųRUK\[Ch"&1)z{N߁ <$x=cA2bq49yU x#84ǡ L@khұ4H)S&{2ɸbuatM̌12G$U$&S(Y>$̪# ';1ًc3s6p_ː\xeQ6Lӎ@BЩ ? `eǶHd8P%P!㋪~]!D@a;fQeV/]}_S J<ւʆiq_ouӕGg|u]Lc֥Vq02yJʔf]9ZX +4sLIӱiABM;̮@I/fNۙij-,M30EBHۛ[/ 7{&jO%{X(KFQp25Iu$ːn<nA$\2r59O"%u%s9kUrݖb'Z\YUjk:ER%{pcSܶGPiJ31BZ<Ȫh nHn OWkİk:tɖwl}}47>Y}||<~Ϫ> ϟکAKQ1o/m1 ܹtβ'Zg 3 WeqjfR @,FJ6>lDiEED B:@5s$Q01TF$֙%BvbS284,䏙DHcb" r^nSXo^'{8\8!P%diI%Y7b9Ri ٶLuLdl0S˅3J'n8c~%|75 v򾺮[h(ȓ׈a.byN}rpidEGlX`'MReil@Q="m8/.@ GYB\W%nRT f ? $ʷ5v1M'ITF gҨ ktq bg/LoqdRb*.$ˊV; i{&&We%86Bvfq32@Ox 7 Sm R"`9lPp6IT8HfHZ3:0!Yӄ2&)yXzw(B Ͼ+oOİ6cG6LIڨMeQ`{c٬ b!L`_{[~S%x޵b|Wk\\1Lg_?>y1q|D9FcvalYRzWY4<`'Yib=4m^&M$uX1 󫻳cDZD7-#˱HlF[qIE -,. lN$;adSJ5K̓ ahBlhO~@UjYeu6 >^?f߂;&? =B" 3Npc"Pw4=F)cb4'ⴒjx8k RiV٘ NRv>e~0)3+A /@3%h :4ޕ?R;%JFwz9‰SWd{xxyuʼn=Jr\< Y}2ddSmK͞",]2ʷ lWI8)(eڤ.:e:˖|;,K>_bŻ'/Ǝ0~hٲVyx5xs/W,]_?_;9Zx8F?v>`śI(rIaQC7ok/l\7}"`K& Nl_ee\G}OVP?v/>LrK}^wLsHj{=_l?oMi^ ?c|렸eGcԧ~/G.cٷʳ'w}Fw`vy_Z濪/h 5]z^xO>^rӧڲ7˻זI? /nǰy. M!/q4Q|L-tMh4]YHn 5=G}xGT^a'o@,x A}7hk4=2¡Qx.Gq ̀S8ۀ(Of1b,:)$jaQTnk:fփNվMB1+^H햔ʄnaK.9>3 YNNUhYl?V(5N$źި󄡴`72MǾUjЪ~U׫)Bƿא76HLl4L*kuGWv )#E0>5'NBbCq{lXW*o$z('jکgT(1}-qMoEo4_{}LiOwƱM57-ϻTnv 94 C})|d?Ԭ`/ uLJ3)[.u<=FBpgVYxm*l#+ܶ`CH "Ψ/Yd\{8[ßAci&u|yNEYZl 2<8m~fe !i gO{O+8 c}2 g-n8޵"a{e[T<$٭Th6l~|GOlx|7CC P\sS6ʜEUWˑU\է]CMsL{LwE\:qu;&|V& &UTERv~ty*PQ_Qw9Y^8K6ϠU](pjlⓊ{N<OSda. sV 5w:mIi((fB/쒍þix 0 3Xݤ[˷yDZX2ÑH>"'>E=śGVW #$Wc ^ @6Q&$x8 ٌ:z*17O)d5YA$>gG3z°7a$InJuZ`{r4OъF"kk( k X-AUe( qln ~[XQ&N ÎAZ%0\~WYP=@kk=)m#X7?t eBt9\e5ÅmhT{p)5pyml$-E"]bN,ɌMOXj"aCYSiJ`agCrV=&pH>7(,XbA0!߸)5"H!;Ѹ6Zh~Zқ(q,\&3$ߎS;[FV4 q|~eLu6Ҕ864A Y"mV:H4 Bs,uQg^=20yulS vC<77Wz9` WMs6B)/I>Fh퀦1b;"'P-20{cJ[p-bMeagL w'Ԅ#*S>@c~Bn?c$ 2HRs :'媣j8?N:g;xc9"Z !:/$ 9┉K#n3x3mSUMX?l2sN!X*_Gv 'e~\Q ː `+(ϡ R% uDYaz`/["`+M1h6,)E' x yx#eN aszv)()920 ,i Z Y =jmk+mZ Q+ &v'@t^~%~y] BM:viyi*];ž)@;-J#"aAl^*H9Hq᲎t2oCG+H/&OUR*` E=i8V2sJ=Օ2֏LRZtÞ.%uWW!M\w&T+tdAfրBRջY5U0tuK`ږ$kk)\8c|J gXZTla!KcL  aZwƍu`yN\PhvIs:dJSS,C%a4MR G|UE狣Sޚzd=8J=J$y11O yb8ɭB>T۸pWiw}XXwh9!sQ[Iz7LLÔ@HYL5XKЋ~bt-H8 xß6h7`>vq Cn뙚)3U49ܫ)Ƽ?7J>*։T찋3z/Fi;Fɖ༯#jgCl\Nq짜؝# uQvmeQf!+3vʕ LRe\N"Η. !D%V .I[~B$^kvۃna%C&jJ{-90Eۭhy*;-DLn?`ińN~MxA)?B\ =k?˼E+~zvO12AIMܑt}|RV#nD{hwq֋#DPۏQDˎ1^8wBeDu]/\F҉V D]Njyl !*R:6XX&䛶o`=l9彙EIӤrMof^ d%Ua8e]:wv ˾$ٗ?d)?" \2{f4 wj . f$)c#5ofGF]GN0+whaeKZ"3d8:8BVĭO32]'>D$-7}S9;h ?MA}}]f8J5!R oI,} D1<|UpzwҁߐcdҭfRt{m*y7U3O 0F6RIՔ:(òϣ;oՔԚ]o7Yl( ,?X-.)lc 鳝IЪ($gBe\& o ׹N1?p"BsV#B;4DxADu[b!]  sU g#lLZp0WdS~Rsp'+$,Ĝ^]B#L*ig3H؝L2}iكj()QDJGz jb9A$%14fe`76(PXu8K*^ =;vlIv\H28f܌֮&̙q9NE2RICzIkռ R?뷇IZe>@=LH,nTMQޢuK+x. l$9KuiJ2:% dTǗ9ɪ2@ !{/AAA1􃼓|/8~ 1BWYζUq^ }ك;~KJ2j$hX8{ڇl|T|DzZ}hfEyIQla}) M#  O/-t$eg?d3,4i WbΜGX(RT^LFV sOHNCCld*؝ɫ"hpq3[<^#9%DCǠʱng9294f-Tq$BM%˺+]E`6v@H ԝkmf\6jy{`u \8t;g 4Nv,))`NvDDC[#]^aNI,1.:mWRE]Ig;Sx~R'4;zv{+K#ա[쮛 DtG0k.@{CcV~|ʊ5W MUGhKp h_f6 rz? 䩆і>H,I\h90옞pF-?"N0oԗu:BI=(o`?OBߞԅ7NPZ*Wܘ-͢w?;gıQ-gKcRڿibTMnK+VKY[um#H{Pnu攊5/>r&-ڮcQ2>.p0-OoonK-zSsɷԬ돯i:j`F2v&_#mieED G^ݱ6ڌQO*/"~qxA 0԰A /aw#bsY1:* ʶx7 4>N} xp˦hkXTpW.j-uimS$3df:3A_'KQQD%H@@dKE5*T`${{`<Zd~sVd4oݱ=㏩HmE~0,wN: &|[bTdw=Y?ᛃeeDhQ\|Qe(ew%x:ݞ1W'ULJ G5EwD[+AOD\ZT(M(3Hi(1& CӼ;FEл\p E2p3KEb ) e߇.2_\#Ҳ`- 9C >$;vdnm9ܾ~WNDž$VJ /cW-K\k< kHCn覃jJGlG[$Ie(艤!C*6^0U{bqz f(/d glyPq̈́l"vVBP @o *4o[MgBh@e+:t*#bOaKH` =Wfs]u)[eno&TIzxbcGWF^1}]R( 1#rc8 IMD Z+o "D#VnV,ȝU %dT貪`4"+dMX\N$N+4bvLu8$`IJtgʭͳ]bMsk^y#`Qt|d,iԳT# yx,&wmn$vMn̥? d}.ح ǡ}3NVܲAen+xH8ʑBA,A.WEɈic%=Dnp="1,+Bx0D=U.Krz,5d?zse^H Ai l# ^Ot-X 3.Lb!W6ZRUGUrlmT0%nAn2TI.HdN8B QVEʗ3BEq#T"&R$MPʨ,S\ВH9iۣ2ƸZ rpR"\߲ X)`y$Z^Y҇L`SԻH٬r8526d4tPGJ+G+#n ,* ِ {0v"eݒpy82, a`4z;ݐ 2O_eqkYљJySP'rkģOKTdcufF oiY$):`Pe%/%鸔<"sdRAT4W+e*E#\z" 4HB5DmuUMV)󛉂h\@֜S.\^CǪ呰$>ף?'X:N[fi,vq]OKႪ~&7GR%㪼'2]z}T%_F{G2`1_{XlXX?,nx: ,洋˪M HuWnAh;!ͣ$6=;J% c+KduJ]1= pi$dLj& ,ӴlX pM"35ΟR1(t`j9N>Lֲm-Q[8FJom*Ғ`qc+ұm:2P:H"66[wuIHml4MGqlX6?scy|ۊ4NϪ?senۯ6,S މ0wC)+r 2Aj,/G< Uo[Q:ƠS lEIJJ 6-JL{ϟ/t~3U@]  'ɳQ*~-ITSHg2(8jgتt48s1lbTkbNRP@QQsdmlUfMgBf>d8I7&#>Kg |ϓzwf!Um!d%&iK7~R#VuJ_.U' -Ɯ* tU=9`U *ƎG&&@+ 4S&ɇy8*} ]0 Uq ͗AOFH>7 "z(@e:U!D>3;L# )Z"C5wj$ABTc"U7M5E5=D<S0Y8~uA&g\ז\dV6+'ln ЏJ>9?WczuNO(2 8xE’Iovm 3}7&eAg¢CaS`X}h00`9go$ 03DةX<M&)31ͭ&Byχ6y(_wPaqu+6CH_ iQ A Bt.ɵJ3{ժ6QqĸVje 24O*RDV@5HmdAp(g0'x<ǫnEFTUU sWsXp Щ( =nKy6^Ky7B;$$)|bIڵ1`r*0I"ţq؆"x^I3(lڠԂ@{Xժt" OFwnYcJ,d{dL^pƨI$ . b@ C/;/](PYKݗ nv@LM|C* S(tCB1o:^o|FI2g&GP/G:CI4uՉx,]껒?a;KIm6j[YS(q~\] !vrнZZw|r5ʢ}J'RDtݏJ6m OS@7K]-rcH^d+DT Lh E^z\-3ءN9T'f&pmNR_Qa:PȡȭyE5FbeZj7eO(b-.5\HW1 激:&΋Ir}Ul 6^{|eR8MdIr]~6=_P YlWl2spy JEE^}")Q v-gpvtNUIدTg=; 7mx~{Ͽ/O6\ *~jGC<}63@Hׅ P_0ؙVFeoY]su$PD+M"+QQ̒9#3dy&EQ`}dNr7^y TM }7 oÏP4eeYAAj'*HD6mY|48hZd~[ \Ԫ c#&]UF}itRC֦?+pOPLqpSN%йئWNIB+w7pG5qc+a%Jl;<C5'Fh(rESTnKRgfQ%oٶQ0,.$j80sx[4-3N:|T ;T)Ol>|F-M}BO+`9hp0ґ[S 13‘@sXĉ&ZyS8\mEAo*WBzɿ$AHÜD].z})4M ( DnQϡ#wHiC.`l,ոi-~lSTr7fOL.TwЀ凥lQ.PÛ!hUb[@3Z4P@AC?{'ntdzpt4ߜgu\^,!)=38)>d}VPE^fYॏ:L_&c(]^XºrD_4 evzęÇ(k=zaQ(脝E}fWRO;Qc'p0/)\YuDc;Q:â/ʎ-ꎿԠ/dP-?ɇL.x($ugx\$NL2P;B]UzC?)=t"^ F?Na˷ ;7:ưpQ.!} JɟQR6eCRP}64}/UU'RFE SA|!*#Ojz aP]8zOYtJn=DPݺ`K Șau8d,)%:k2 ٜzf12줭LVHHM~| EOYAS0y6S`;c:3Qgȫ~.3ܓ M]yJ9tRtJcn;϶h׭IJEvd4%Mx.yBi3,dɼOe'}EEZ1ZQQњ_z$5SRewoP3*ʝp8uu#[#Tťi|7_uoۜGهN& !Ov,0KQpk~2Y yiy7P tc|i_?ӆ_u;2B@5Ń CDxK_a>__f}}W`D #BsW:80_Y,4d0 '"ly2wMd|1c?#| %%q dOjќɀE8,LsFE~*-rP1ڊfc&]cNRc?p1 G1 ܦm zKv~47O4 WΊ~ZC9|ZQG|ZC5Ր~ZC}ޕhM>A+R!ݠEAb,qczQ~z#@d ydө:8ʇ:0PEfM*ao [ !E!G2)D!_:5;`zP$QJq* \ NJh{Y *! ݼG%(83 |DmU9D?qzĉ2'6g"ŅUgT/^Kơ^ MYB6uS5CpI;Mb!jigs@Wf* ^Us{pɬϾ5t/|`*x#Kϝ7Me^˥ӮCOQ(B݂x(>'P[RdNt~e޾T|&.>\^<j?;TY^ `Ҧ?|Ȅgw5l\|:q5wkl 㵝>VV-g'XS`yJ\=TX~Uji0{9߅y#٧Y tOe筮+;?0vrifݰ%1Jx09:G`|ซ3Ofk;}Ba[^,hu%OcٷKg3VooѠcAws{԰ېQߑYӥ'R%jbh~AiB\?U31f1|l4৿/be fOSޅ GFeomthu0_4h{0==P[ىq@Gǵ+ lyFj#Vnq!/WzLzV9y'1=_,˓JbwfE΃ ~}FjҨ> !iOMއ62k_ Y7G3.OqQwgtgtQǿ/.?C gj$y_vw >%tK `Tt-ۥ6K>c?>[߮0)V!%qR;j/Pm~]x6ᅚRtaTl>BCٻ}sp,OfR?Ƚu2Nߛ`=]1 풅] 7޾?]W549/NOK~>WI;Ľ f~zxCx~.}Q1~ xriL~CaYn 6U]C m6Osew+w.p#;.xEsٍ̪hmڣf?܀vƖvKQк“Qw Mw.qFo5ۣfJx[{ ,>n*?_a;2͡bɧ£_솵(+}@L5iQ:ʕM+ io*:Җ) {Ñ=)127D\RݛP/俴_&̌eLF6#X=ICKIrtLX=>܅S4=p 4>y>,Qʦ}Pri_?+-]~Kx΁i0I=]Ysŝ*kv,?gy僽N&oV[{sM%~ɿ\.^isz 6t͢UЏUJ}o{ax~/;ށKT[C_'qM}Ca.L~I50Fty6mZFvއi-o^2X4h}C\H&x⦭#8D;M.V{: :`djL^ts 6[Jt|,<;B#2 #bW25( |nc&;[<$ۄIk!m90b^muH3a4~z^;| _`, ŴOauݝdI0M":l8 %N($A'͏7G; *7`Cs a^jgE6#uRT\<j@.Jh씉fRtv*X;к&!,"ޓOn#R&V۾Į!VjU xuDmƏE;NiycƗ{=KHh3<8A;>?X O}D#>1E8:vnaP,{DQ`CpE'=%3Y+NONўX_Ȗ-S4OQ†gj[ EæT&@uJ::mliczI`Jj[.>!ΠȬk__X2iFL=83Mlk;fb`k7| fY)5in>iӒ2W{̋stN|PvI(!M^5֐$}ZkK6Yj2UkJkàl޹ڍ}#Glv*lymTXܱZ˖;1'>]=;U%.,M|]}3!;꿩JIapl߱^i6x=Z'-sw _zQopTt]ϼox4yp;yGrt}/ieWu&m$$l6mV֒%ߢzXY9]=̕;7kk%۠,{6iBIc hF&nE&B7溡Uvr:u[䁁>{tgkW4sW/GC jޮɣ~-ۥ_֊-'W཮MkgZ-~CEӝm{C& ܻ4f5ڤ&qPܪRt ,Z۪]XuCvpZv:Ha2aV9K&;[Om'U~p?8ړYp,/ H.ޯq5<f>_{JXٴ_{TtLGյUEDhNe"ŹV[V1ٯl~]ս%,$bTB_a[ڏUq8tjNNV7`ߑ&Nkx mok zca4r>X&yG:wOu S3yG>eLU ;$協c;Ww:.gü ۾viZc:Κ VJKE*Ӧj}B?Z~XbE5 e.Ņ`a-hVY*-nW E)fyzۙ B`f j|1̝s<.qA F2#/1"$Cx+/epy>b!={3R+aT<İPx<= Ѻ!vUm$w*Na(!͝5rD~Ε(`Q*K4BO dAC `LAOw!saT 2` ่>Q n4'X^q"JaGhCmˤ.YTX#. \eHg+٣֯t ` !C>~Mu`"Ῠ OM⡟fBc2FԛYteeJOIh%ܐŀl>Nw,ѡ,I+ҵAt+CQ^Jt\oǾE܉TĹԚ a)l HUQ%7zՊj~Dm(IEj\C/1~QBukY/9$15BupyFf/เa,]cCRM#r:$6S (@M:x1CL%lcQZ'##E5q,RG9(bK~"q>6Õ"6"K6wBR(zEF'RDFq@R '%laԣ7a>| u<$X㨻P.Pj}9 n?SoB:yǟϜx5,rߎhKwVIQ/qs×=n 8'E6h }>?x?B%V$ V{jpw{MT{~=fӹW1;Hx=Go_R)Bȳ^kVm1-iR)rboS~R1gZujv'GM ^Qsak;xLͽ;ĺ ]LLO5hkR6BaZ^v'S<.A3oN\쫘#*:"l۠3+<S h@xKMIJLM3244H5I5HMLKK0227I4354NM6L 2x26DN]KGra *^ -DQ]AJlhTWTU=O{Z>0`>{#3l,٥f|FF+sVySa3~1~WY~(IRi4Tat/TZ 9;ZcvK;W'e^狅=S?}jٴ9.y~_ٓϿzvi6c_-Hr]a֛/>/9|f́ݝdIgoUI{srl8;l 2ܜV5Y ,˻}t/*ff IۘY1 4qEdW6K_Yr&==iݾȕ-Ui5oJ-VŴL.[۸VC_xRyA.NPʶ8W}M>yӎfP2^GPPBn ZX@pX a!JPjjj, rh& o"/Wjlѯm9W3?83ˇaެz֑aO{{}X+N3.Q X8Oädtm?NrZ-C?$V'%=YurG r+jh~rWY^j@i[ KyJSJ,杫Lzc9Z Y㊆jN{UMDl߭IY|hȋ)5h/9Kg**]x9/l{|XwV4ճP|X/kj((Y W:`mTW9+jUŰv!Y`C*:g9b6r|X8m_Th'-A55 ȿ7ᠪɭs -uF6o˅uDvv~ <`]X~j{~T iS zzQ< [_]9[`mqndc?)u5@{m!`Ӻ].M?o-kl̗}*szYq}X P0Յ`js6v` 0hԏCb= _Ρ\cVU r۸Dծ/쇚wSGMd=ۼ/f%F-8M^CОks.p뱪9Za7Q/M3XLjUkU󪲱UcƞY c^'ԡquZ_;6TfYViMi׍]f"fyXUĀc]gij Ը8sW )/Qp,̳ ̺w &ף d;wlbH:w;qi2ހ9>m&mkU%Xc5Wu[w;fz˺q ȋ+ 1-k5*Ml+:m>YCs& |8l$5JdubޞŰӃb2!ݫIq2ouf h>uv sY vb=!<Q8({q̽5#i{ 7l,$OXm:Aw1^oXM{*ƚsϘn@CBl;LqڵX>ڃbGkMV#ݒV}cx$~ jgMe pH][[#7N^֩h{ .2{9>ksTS^LG~ 3"yޛ UbxjA Ŋ<OX{p*EL\,Z,8'c2b|.ߐl_-FL׷~JS܆L߀S*z闿)`/&iuW]~9_-2W<-&^YI[N m;+a̜5I0Gq,3eyzZI>.G|| 0N%G-E:I%R#uG`8}/QQC2H Hktb^J:8SQf:jO+ifVq:Ľ]E)|Z0q. =vmnFa'YmV@\h2o*әi:LO$YFHM3[73F&oT^pʢnF,)B)~g1äaڂ 9`'aB"uR@HBgedIf`qf i"!94|2P&MR@L(XQ-nFBx8=tH)@)`„!Ѫ$StdjzdYb4*/_|Gڴ~fE2hLc V@E }kwꛘ'ENNHΐpH|mX>&hTQb܀z#@&{I~KܪKR+d S˲"."ғ F*! P`o'D2lI8m&zFD`f]ͪy~%qz լ#VHe $/YeXF‰Eۙa (StA2fFI≰ ꉰDJ|JTIqN:f($f{Z$#fы괠(ROzQj@r4/x|& !\USPYJySER $ 'kahXҪ" "/f Hc2zfa€׮1~vfǯVtSbgY$ʩD!)7Q`ӈ$(eRD%^#^DxR*- ;gl2@ˣa&pQx4,`I8d[}3 LU7J|evr,U! \i넢W> {0#f1B7y0ГϚ&A#>TiMZ SI2#bЎ) ww dH1A||z:)%-h5@hxm)bΫT"(ާIddEy Cd}(܃KĄf*AU>mVm_G#>:!267\3'oMp$K@"xzi_M/{'ޙc-pNmI E1T_^6l"&-M49%H5BpS}Ot%2nwF͸E3QwJ `J }A.n<$9?orx!)K2I:0]7o{_lfG^a\wMgiFr&1A٧1Tr-EvEWḦAI:8~ ;&Kr70]diӉ(iPdi4 %?4L4`leh7Qy>MϚBI)e.6CěRɭ^ؠO3m:T/3b| WIRwe+B .Eԟ2ҿro';jIHT yuL-!'c2wdxJ ӽ >4~bm֬StQüթ:vzJ20%ʦLA'NS 0xK_Tm+LnJ3^`\ <7oM?-LJ;9h{ q X͋gM~>@pF3{ ݿû?`MƎHxԉzh& e{_ #އ@-kR&( aeLWQe"}$a=:`nV)aP>š qѻã[cp_䋺 ^}>^a0$irN3{:,#x|+T1y(U㭈$I. HDߌJDL|ADǬh*$f]xԒ(6_G: U=>꣣g\w8`nĊ"]CP@wM_*aLp5{mZ\]aE#=W'n楍$p?̫`N~7s/4V Iz%Ͽ[ ߿o_>}1I[= Ns,ɘMh.~7|nk ޴]7<+i$bjsVi&=/?^CbFhܪ߭6D*25XY3Yiģ(&e>\X\6x}lNo]p`a6t\[O%i)Stu3Ub+4)w@Hxj\cFJXx4PLctAbm7l~QZgt0 g]6U7h04Ѿϟ >9h,0K1>5 >n63lT$d3쬻u4oL&3 TDȣy("B"**TU7`S̷4^NU:uu]OOppg}{>WBozs={q3(E+~╲]J3T(~c v\Uc? rAk2b scZ?^8JHÏuՒN+q5&$s ۮ R/x"5@.9&R Wٹxю<ߢU4xך6:;(<u~ 5#a:kM1}:Ν)&Upڝ]m_R83Q9p!aC^mU˗v7?TϿ0EcC^х6`:*Vy&wL$tt|v߱N&v~}tX'g=E|>`ˣ6\rP5io==jfꗎ~ @w냗ϛo{`ַ-"y?riu8c`EW?*J?U^ⷿx(oRO,VS?}% Y8(C~Ӧe"4$3L2y^\[,f7E3"*ʷo=hk,u-WOcʇz'qb7[-4^e̔o{[Ey 3' jfΐ"( DfFӷwj’℔[1k;CQvlGBͪ@7݁ߴ +O1rFL/qpcvq0gZ_'kIwڴ=O.0TVk!~ۏ`}Fn, )w{/8SKhUVM+R</@f{)Ch id[5UF ! 6C͛:ZGlu#fS;0'm|GbAsžeD'ko&]FЏBP 0OoȰc vdOX\mDCd́@,ڋz(oFs24 .# `hd[:,j`P}Uk(^ee!2i-!Tb6@#lv&)\i^hZ9;6ؓBiވ?H0LB84i"=òhmǭM4#m"{bΚm 1@c]1Pb1P[8B7O;_]5-:#J66X&8ni76AQfAw*mwo=Fϟ5FVffh)g{\t},<7=wQV|'GQ 0n]ѨO L?Y@-=v lb<k~z-g Z(nced "lF6![vvϏErï`!2-2l8-|Na [T݁WS.0; uu;r#Nb]0M ^O5k3H6HtATb \ ܍/0v/îWvF,Rƺցqp'1]ܼvB{]"ZS72,>ض'c(^Dw!te 1O>}69,b't#X7dD}JNIA9˜!<+Dg6a1"haP-N4y'-vt](}$no"q?HI1!5"#r;8+V i7 asZ zς?p'%mԖmuGբW2$"]z,x#VJh<ђ#${"HTJ9hL]wlkmf,ڶT1m^T00EuL*!X/QX^(ԭ32`ST<osϣ()csa FC2h ѷMwHNp}F=<ē)6r;ga+<ת1 {N!hx[Kvw]&ì]_}ظ|IkAcYZY*'_mj >,Z ʻQ&ZԊz.g)ޙ-QخkG;\#t$|vMTtINX1P0}ڹZ*pr]vQ::W7oE5p~xJ|Go[+#R\?n&9ڇAHyΓ]&XujdQðs@;r.h =̪>slqe5BRN-^%1+"ރD[_x09ʌZT],b 2ҟ`YZY܁Z4FZ P1?(DE͇i?S.o_tJXhCȖ=0HmG9 Q62V%'d,(x^%4_@<5y]t8f<~jj7%2~5gI"7qBky$_xc9pOStEgM}i!l5rI.d7d~!egUӊytĘؑ,mőhdV+pukkoE3u8BbJ#x*0Pj`0; )P>V A/i?W;{Xtõ64,7G킒 Oe&7"љ̹n`G`89_2Evcn+ۓ+H!~(C X& ܅{[ >.J`Ϛ[C'+*ӛa'k^OvХҌRAlfb8&!{"՗QSua>v3D2I.S;"_C/htf4ڻd|{j://pWEBqJ Sj7_@C=$H?jHJ ?L%U ęsԑ]%z"i7IA:[_zXFӹk5WZ"BW*[v%HFԛq:O\۱ZwwVv:jQr[M1ufXyIsrm83cmwEa4qCEej]ᾈS7* p?!$8cb¯$0tf$ne -a(FGƠ? ?sRd UACa 3.qa1Z}f4o}!-I}=wsLyYX eF#'A}E6fK<>4e#k}2EsCl'Ͷ^sv HQi8۴CwtF^ M~*A$}c+rOhu)fHx(&})Vl[,kl)V!"j3V K _P<_(=ήتj4&XhHFoh33FI3hn)CG@:I &Ң|?J9'nԒ)fN;e:DR\tw$ꘃN)S("ѓoʀ5PR Y?nϫ&>1: zeo\f#Xq زyN50'%E+RԂ`mDcPҏyv}zQ# [MU#sBRG#R$uUXH'0&$E=!gMhV0ꁜ3h<7K4K¹iʌFSN{CM)d+9&ֺ+Ѓ 4bʝD]x̭MtcدW th d[v:WYtDuȥrnPJ'Ηތ~+88#zb /ǁSv9/|!2x @ @+o` x ,R\G`"/^T2 VhGN$b| .x[˴i,ҷ{kg{-(,RklǦ>[x[˴i,cgȲkf0tnu5 xH%"f>*ʴ,Ƈל%7xx4k/?u.fx4R7u x| x[˴i,/z/T5rZ\tz zBx bHؾʺaQ@ qx[˴i,ѫ,RU>~$oϟyju "xD(ߚuE(RcV=6ԗMx6vD)DzX|x[˴i,RUQ\AoCk*͚-qu, 7)x[˴i,+oJ!4Wuî -xOy<1|Ǿ;Hؽl+qqT t7,׸a-`Gӥ/dŨI  ']x[˴i,RUQ\AoCk*͚-qu, 7xmWug8?G<>ůk/2@$͂Eu/db fbPi40000 doc&{>$>-x#r&jWB  Ź.|x/)I%~# ^x(x[˴i,YN,WĶʟK=F;}zh <Sx[%ޮALEJrf3x[˴i,<ƥ;׼.iqu\+x[˴i,];^-joo8q]=W Vx[˴i,Ubl 7T٦|;"\9eu +xLԌ* `u׬̪sWx[˴i,)nF2SU&ͨ_du xRx}T!͢.x[˴i,9K3=v "mġ jYx[qZĭz,x ]߶=EiœqM`x;k{:_eOb ! \&@e 1ۯm9}gFېgAXҌ"͌Xkg\mޭuެz8iۚfmuX{LeZzm6{뱗#*<5xT]o:<|qzӹ7VӘVo7ZԴZm;{mmwBlseWPq'cwV[uQV7Xorf+>_ Dh}shE_CJ5Y %G?|A=ZNemSpZv Akb0dJ,46shؚ}VR"\n4#aTOARD0YJ. eSݙpS巘GRVN梢Z`a<0rmg{{DLhUXED, @bИ*зK+*73ѳ= \oT)`hu;g jP?`{Ykϡ'{*;#I7WWWwOW0 Y~TXv :Uf[AǶ-Q"I>P39p<(@fl9mLlw;J4Jc`: ݡ~I!*@Vje\jpi kB8u@۞A;TYwzS?Лnӻׇ.*83܆ ]T7^lydGJܨR_R"ܳupg3p/)Ɠa_,= e' {x?Ov~^DjRBr޽2,)X3߬V!4.bߡ;Ki'l"5'<b+4_ĢNs:dP;{HY O#>Jm䟷]hRYS!,EYGUV?^!BN n@Ys]p>vQ 2m'o.Խ]08@rGiWL,f׻4daz@St'>_>,p-_ޝ|p`bZ +Dʷ\_=,B(Yޝ_wn,Fe3s1]rau0~E9A:vj}-hg ExUZP!dg&$kkb4M]8Zֲm6lV~=U>t3Ȭg[u'ń8>_ӳi;bvٹ^uExGhV$( DjPǭEJ6TgQ?NF1~C{"}f*v{9E˅k[ef8K)爢Ѩ-燎5Mj.v~)بTBU2f#* ҇ ذQwP4'Ձ >Nq!s^g//G<QڸƉ`Kx~tHx В:3{.72}ba^8 UrL9ȁ'Y$~e:r*IMh"CP,,!>QԷP>I8b$bXX6iY {г7Vv2Ys~R7Z|T #@w*kQ; aw:M-{FU$D{Eǐi[۪c,?v9[rC#$ +0XZs\yJ Z%4Īa#XD,,k_&h%Q!JqІc0O1pY,UhŬLAj=Ħ:*'vL4Րk7vC>C]eקG$^ZH0Y3"<$){ؕjUuk~U03R6q'Ta/J/و(>\ySa l ӂ%ݶܔ T0$=4]&C Ds x641]J}P. [\i{`/%)6%,Z`AXODGщy# 0Z.:jCw>JxcE @Pa* .k`TFk:9`Et p]8 B= ', TwLX3vEhx]qIbbd_iMA=r`9#:=iSg ¯-n|J7N|+W*q4ěp7??Rnr`fKB|x~J1%xp$YFB !sdMU|ֽѨ?/x ݫ3 KNMπv}:$9tiSa[69?,Svn3DɅбO0+ÔPIۍ? V6axPw3[#p.J08ڮJXޣ Cw nt^޶P&'oλns.@A2m L5!baKǎo8IOxhN]+hhOСNM7K4w2mVҺ٬i9}+@>s_xI^3DBTZbUI tPbVDʫ5R_4fכ<0H}YZ,B-EMR\J}dN'U:^GA@Sۊ_!S!|CczyLSǖ܄vXxO?q'Pн4?~oQ{Ä';xe0;x_[G sJ_f `2L?9ת-G {P=hjKtD21,UO;ZCwGNvx(StNZ*)77ZdW)+FO\E:G[~kfT%OzRd0<5wК̅Br.V\X@&LWsSy z r mM\RN2 OkG2])N [W7Y`ܔ^࿗[z ͭܿ)%62 ]U6 gOsĵmV<('a`Rybj, RF!n)}&a8SB]ZS=bOԌ$,%!$W+=Y4NıZ((~) )ZU֔wEtGSWXT>͂(jae˝I_xOeבE+ErbKDXn$XBG[T*{-,׭]0R^u*sbݺxΐ(_*GaV\I0;LCmjk 5YjFk"Wezeiw<(?XàBǶOQNz,r|S__(2'l{-XN>Xs-7 Z@qD|~gʗnA[&F8\\ug^x.$(251v !аjҫKTmwWgR|.YuDz]Q"0)ƑX8cEwLd3=roas3!^Ev6k*м%aAJK{\;lyI ?e,Ce &^"2'+iq#L z#FΥPxJ}ZV" i!@NN9$MeB|p}B>(qH. ԋOV@n DŽG d.A$< Geڡ+vQP/{y1|3`&O7S D_A:9Xܤ~]y2R^pgN}-Ϸ<e6n483& b("sB}ds`-",Dĝo~Cq/2KxN٦5ĩAEojvoQ%x‰{8g'z6.!Aŵ&66EݶN qA. E2sǶ ;ؖuw?{ܣ?tݎ_|> *}/j"MVr{ #`]p][=4atz QA!,g>)!=Dܣ3f326efɇ{z:Ҙܵ3ϏN掑2ʼ9ᔌ)rc½ʄAI'%~Zn#ˣYyWW@xRQk0~~QHرf+B7oYnHr`?~ַƶme]y5:ImBػzv<—ϛi8LHt|Z7ƜЕa*zsLTKmu 4F-SBT.\'>A ]mqh}K;6~RmnT-"O<˵ljmo%HxQߏ@~߿bp]63իSۘz]4W@vff[0#kAdEmi )5hV6ء 4%f,ԩ?)ed$iט,=|ħfy`QiZg2%:g  $c:em(daP:}=hKEiJ=f] J$H/#gQn`!(qȳ֌?a$bDS:(kEbkt O6% NiT@1bAH(Tu-mq"3w4B Vv#Q*iZT hꍗ ܣN[VDc|9Rmh+^2(\0\L?{*86.to|EMԛغ lkai7>\!}.4 U_=& WAo͖|S%g`+E\\z 3{t |GhT*Y5 WkxmsH?GIHɖqwsd/wWW*!Q oh@$@f{fzzQK܆Ym骆miF#bvLH&d r$Ed\a{ޙzzO_K'EPd edR.&ɒ$LWbŗAmj g&vvI)rUQh54Ih{n꡶UOm=-X'Z/j%1lO uEqː,3_N6{Q39Wό?n 9n> Y#nGZ#Jx$icخ@`4 89m"^0-g-m*cGpGz} u%u}[aihvP I5/\$'"*9Iya} `zzNf`63ےyIlDtCbb85n0܍ڵqna*Oa#{L)޺ '`><Áx6L#xP^loQ |էw6**vPw)K-QlĮGzJ2:ŶGt(鄊 0Ds?;t+?r}z: +X,PB~.̕#2 ދp@Ugcٕfr9@vVHsa{uT^1M0b(w;bd!:Ez tºi>ߋ8w'ϒ; b'J l(tI X`[ㆡdKJr2$Qo,&v{EBGnDϾ㭢KB1/` NJrÉ[_WL7{3E K<3U~AM*.$93֝ɓgdKIKW4U &w nt7=lָbOl7FN"3WQn jK*mGi4db`5hJQr;A%t @eج @\I$g~ʶ>-IW@ouќwiOb'yXm3jn(=RRJbSUY%Le.6+8U =p$f_}F{ѻ= FKŎjN -EmnŇlH>$j]պn;öUҾp:4o=bURU[s95Wq#)m0>|['X/u{9v̆/$Y:)UlGs%[=d-?=Nj/6MEQvKX:f(r32V9[ݺ5X?VvP2X8=ƕi~$:π,&_IƓ^f~{~s7OUe<$*Y =^,KK# ң߸AObGۣʐPd>8TM8uxK,qjѰTVl3Zήd5Z;6O:f+$˙oEQp 'lz' ,WAA 4e۷ c$M30`3jGutXYؒbYpg}<ċ0|&l<fŠވGɈ;AntOKM {x``P"Ryp?d Q t\xm{<G a^A.2nS1BTkh6Msc \rȒJ®?58EQŠN]*Չap>O>Ä)#M_" ,?sV'eP kcN FtMS.b3?vRG5=,ـutc)]0EsԱ8Jȣd.:cd#UKkAÅhA ^@Tb҃Tj<0aG( Y.>N+O(7vw- ="B҆:]tYu L ;&`JO:Xg|ċ4V N IUxCÃAX2q{p]X' F;)݅xK5yr/Π19 Ϩf:yFGf;zd]O}űA(4?6Vd 6G=kVԃvL$'t1HC$%VFkKٴjNc|ZRs>6Z<1 O97w~]K4gIWQ 9=/T)_q 09Og?͟!`B:=y2RR7*^Пw`Sd}!RimWo3JЀ`tz[_{+v>&@V-RKkP! c!mfݞf(DoMu: p-Wc{jV̴a_u߇? xC qIp KurU0=4G>VZ!#t|J>׌Nk2N! <TONw+q.5'{] ї)%JGmu :)53)bd57m[Ј‰32pBsUةc9^:7M`!nJjLhq'{njELYo/ʌX}AEԂ= +BF%lVv훚OMC:l2/(AY{T<}-7W; $c'(\Dx]y>|k/ ȥ(Jؐ.ҙj+}0F@( 娯z*1:t{e*}{3FU;Ĭ140051SbHD(0hPt+ <%`ro.D a(]#RXnNeUSc#BA8{2C=S .E=: D0a7_-eL$/EoOG*8=Ngఠ;Wt/$,_lH¹kH3_5K@=Y2g=7H` M%#"ץKLtMIQر`ؗY)K2u.]BQ/l9"{0- `=}Gi$*>Қ/g *t ٘"~c%F-0p!A<.7u"VQ6 qo&~M h! 1RS5~f3G*Iϯt AkWz:>@/ [Eϧ3fMɚK`РDwn}H~[~jZ uXF~qwbD}i6^ZlFY&oL@ӳ"X' >2K]zgwr_eᔘ XԎĹ>tzc2T7xTLU]wf!QPFa1i?OgM:V)㥈_Emt[r|sXq 3oYZht}"_<( ;U)M$ٝ ,-:&`̗6Z2¨d%8l+RΝm{_o!9tIZ=O0ZIԐ4UO' I}D[ Ԫ6 0P³mŷ/kxB^z /A hWh~+ۮ|9t$&a >m*n7;ç`;rgI#r]@DqG8|_u)C=gzܽ3GZ`Q $xɦ[$alšHpN&c=[13R秓0'*Y٭nbxFđT| j%55b}<RP؏Zaj-Qn62$E qzQfR5~hArNثG-όƬ> 侜#u6y8WWAQt^:Unx:jf6@$+12[ۘ|uQ_drv.c[BNp:j.l;?&U >x!jWx*zbg{cɑQ{x[˸qL3d)\\Iݱj! ;OxiBg*-D9غx&t~8-D!5'%@/(Ay \mf̵jn(>-3$H/mYoeIP|쯧=]H?-ro,m?S2'B9 [xi[-mNm^ݾ~ |l;_7_?D!5'% >-3$H/(!7y↫ˊK>[L)rNKZc3?bFiIfN1؈F-߅Zv秂N H(xO:Rg ur >bN47Pw}.ˑG)a$7т1iԟ`I+J"`xZb; ƀUϑ|koQ100644 iconv_erl.cHPM;ys0[ʇ:g 둝EB}EAQ XbKZ)ukx3bՠ7)!vvlڝ&ʃ*!G ^f:ų8x_@eS:n^xJ K100644 mod_muc_room.erlmxYoe*￑.τSF2oش&.px_@u`j `ӵ0100644 mod_muc_room.erlH4}n <%"ίYe, Fxc 8mjߍakGNc#7m8'W6dӼ{ r6 Aآr+ƻ2_ף100644 node_pep_odbc.erl͡͠ogf #=Sv.Ƴ2GfȾ8K?Q@Hv -xc d?v%100644 node_pep_odbc.erlD;D$;J#M5Sϥ@Qtx#pEsQ6BtXxɵkIi>֦|Wnyxoƻ1,ʍ ]xJg@҄{zCnQ100644 stringprep_drv.cُ!xQLv/`wA?J$8xiBz}ͷW?(dۏn^n[eh``fbP\R^PZRTPn6Av%$Q/y>;;axiBC? v&Vx5S? xXb"Bgfv C<ÄQ^v39|$1T^8Z<100644 tls_drv.c6͍h6Pw\F;&vxXbm ;2,gOݐiov39|VP$5W100644 tls_drv.cbPJC~-*Ly4']Rx@9߹0gTvYַΥ 100644 tls_drv.cDo"5ޕ=,pM*%,`x|jhQ-`y"em Q6bDh&t`R7"@YQhP:1H?⌡oJm9;0ܧ )1RO(R K4Z1O0hyo{7xhjDaOn,Po*}QЊ7HS-6y7yms )>汦/)(B,Мj,eUҚB%L2dxY2TwQp°J٦DL40000 docqqT t7,׸a)src`Gӥ/dŨIK W*Nxljbes l}xHM dpiψ37,x{i,NbbL}n9)u{ux1 WX=D ۗr߱!)őR"xHe^au⯻wGK$bOx{i, #_7h>-P]u{g j+x{ʹiZĭ'?x;%>v-^[:2+ßy)srcLA<-mߓK xSWug8?G<>ůkM&{>$>)srcx#r&jWBK P%j+x[qZĭzHxD= 8`G$:J?^ Z100644 version.patch,#tHheH 9˫u\xz[100644 0001-Disable-all-entity-expansions-thanks-to-Alexey-Shche.patch^ƐR4&i# c'l3(x;tiB]mӍnyd` xxq!{ LӸl$W^[' Ux}¨o|vfev(^*,x;ti23$};.n[B (x;ti? g뇽ԛi_dF3 xTrF}$c;a !/*$)`m&K-eOO_Ow'LXցar k. $O%$꿀"E"Y f2PVx9͖yJIǜq) e @W:mt\ldr57LSS?N cJ^Be/c&IXT( ,[P4!㛀Gu cY@,e.:%\Ud朑'a 5l#~uόw-LRocbdki 7zUD e&M;pxjmX3 K-fZрSqa uzhpO4 Knj!h{njZ(i85jS%XT(>SD1 ?ɲC"\\Zj'u<5ԙfcnLJތd;#bRz ϩ o4)IZ9ӧz`[ھ|?ɺY&i .G]n]]⭴To .Pvof;ǔU~y c\Z-J ! yY1AF éo|xCCK=׎¥{QnL1;媺 ۢw=xПV)}=j^VAضF-GiCB5u2ZOU+8pM9]2ڻ/-j^KIi&q~q'iL}I&9sg&lҒi*eHqH=oJY/7!l䞰}'xF3{a T?/u8q4 U][QklW`!%yf@߮$Ki\6xO=(9=wP} aC\?yuܝgۙY_4p4@y6ؐ{2ǩhH/<#򻷪D3opՀP{y/;Fwg,xF2 e'h+ܒ6Wzs>j_s֪kN( `J?áa @~CόIc4eXEmQW#/NWCͿs0˰)z0fxWW=/ܘM"wsWroZIB3̜~ǾZ˙%޹z?ѢÊ'7w.L *y7'r'7?@Z9(xڹ߅#l*p!*!/$.%TBbA˻{3 C ;S ??<ұv࿵%o~n>ޛ86`Ag}>לD:2a ١qgWMep#v$_.ҙ?K|,xsjl?k:5G%}}c`gtPTS>dRkHÛ~>-'7Z?,(Myi9^%u5oXA8_9sz=oFaGȀx]cr5DCO2j/$7vmL|'.`0k4 CÉO=ݒ@F\Y=~G -KlU%4%^=axj莯wRQreLd73o(飛c\l0ucm>$N'?+~L>av$JR!0͌}~y)R,t>u˜s!JS<K{^&`#E:6U0rzNUhyiB2 b:hIy[W7rk@zuk>vKUX3!-DFpHԵ}H0'aorT g\X>x$rE&=U>e4ģ~dNFKvѼX=_Ezf4AoOfSk)("/&\Ap鋯byN"(WQnGR]0})K_2-wM49Y%oў)w*⵫صCev 1_S}~)/YFPl|>Ϥ[KΉ➖w $F9v΄MafPc <{0?VQpq$A]=v~Golz/h#㏆&\\ Ŭi34k(,R67j:tGD{~/=BS}] 7˜AZnV]A5B!B~W%$]OTA\ ~Iyޥ7s1ٔƑ`%9XEU V?ڟgvF ,sGen4n"΀vPe\{W ͙h 1U6$ZΉ1Wn#|"E֧V-J֬T<|/RfaQl|ɳ|e {goŧVW2*Q*UԓRS"YW,P9QVwSI7 QY؄lR@GinBoC4x1POd\4"IoFWyEr(MzqE_~Fsġ2QXu^K2gFʝFWt8E )|\G"ME9璏;y\ ɶcS ڄ垹'GﺔRc-A#Bw1q8Ԣ.)"9f[8>OdT ږxr:`h)U-o7ўɍ.$sgw _ {`/K9XgyKwU{9d>gpVcJo;<_+$*08Z`'e e vQhaOחX, hwB>O@A+5_˱e5,vQ\SPgW=]V)G}Iґ8gƴӌBqdhMhh,C'[zLI_k`nȓh04L?L}[d4nzIFvmJ-ń%_>h~P G:hXJb;@N79.HP S<>Z~QyahI7qXw@Jg ޫKa|yD4ѬI3@e ^xun\FnAu2QaeZSr7+˗3-"m7.Q_g1-ql8iOh XQ]/<1~oOp|s?Ʒ(2p~<֗j?)H`F< eİ\?? /Z 6(ܞ4kcmnEÚ rU Ec.Cd;Sl1Iҧ? ǰE3ٷqm` :0nPo3x~R,xwM}_o4 pAѝ$t᣶:۸])Bw"6bW($D"<{ϬlpL+ArlSwED*RINe2iܦiVsvݪeIKd  x0^;TV# *ZAaɴ5n ?xW}{YJ'y~0@}l-+0N@ub5[&T7C.8ZIO>IGr9D N3;l(f+ܪ=b4)گ REBf*>Wr@ؓE+ox&>:N*K+axr|:ZzZ%2"@M}NJ7~Q2?RTS'QS'f%r+JK2tBY]EMywJoIyf)~'}h?y];7/u kiXR雒N<~+(qt,grdd'c: yL)4yKvz>YHX9KzJP}-}V$7?48Sm<{Zsg\%gtR|8ܞ,ͲʋPv4 JB>z0)mj75_«!?|oW.9B%FCٞR]KAENZo=Utd>ҸS&& CтƉ)I/3m"lGaGTdaU P>#8t_){x(g*żhZÆ*'qUi r6j5T{N ;AH4pgvbNտ3bm!?Z'<4k8,K)ZTƋ%y^nE|r#IUf(Cj:SēJZ3"\XFz? 60cxֺoiX)s0NYq|K]Dљ}k" wg(ɕh_0h&3佣f̩ 4UV\ \5=aj)AE"ª%(К(|y.QN(z,U&*meȓjNaХ< 1EFr 1w@?s/KR)#0kb5T_QYcNZiBlYwO7S2Y]RRjW/|KP@2$:a1cZ&SЍrk%U:&۫K[P1 l.r]jZG(ǗYPzVgztVZlS X27fWDRb3fo(UΈ13>v`Z*C3*FJR` uʓ/"R|KvMw}d_:(w"WV/i٠m00#@Oz.[6#h1R@ _(x׈x<&=eq:QdNWMU ⷯVܠfSC蜑 uG3b%؄&x'@-R>A&~ @A'h8 YRzG<1ڛ_j^Xޑ\s"22P@îI$|HA6NJS@b9+uqH6,1v0==}y'1Nubo,[ GS fK|R Rf1JDƻhxT84s\Ux93]#731aZZju Ա#-p@5QysJ%fQ ֓ճsGBn/('@ocڣf6-pWղgQT~E(P$Ii+ط MQnWFHy*xH땅d/i%})wδn\N:{& Gϫ."^zHgv%|)@>K9& BS/CMo\6h*u/]`I#rxnO*йwϏ9`e\!_:&,Z.ƒ ϻ XAzϭ``SCi9.G 2iv o$uRlN4%@x ] 5!ZI I:qNhYܕ*.RJE@f+` (R!@t[k>P2D{eyh{j60|Ro6Q56,(N!=`u.y<%.53; |-9hNb(/ c3lrXj1tfW1H u 8s%(/3T4]:q~@C#ON~=S@_L&S6[l& D'^%l9c$YgHü|Գ5ъ͊)dCx?g<3r %n03cY=\b8՞.+mb8yYR".Xe\o=V66 G~}J4JjAy¦z?*0|l4 ~|^;<7SWWQ3'%/<8c 8'k1Й1#@I\CU`gyc}.OE,GM"=hzC*?C\"gXN;FQn&6ԏ"[(K),n;jhPՖL@MT<-$TXڧD[SKUiG (FV-vs\bsBݡcGxEjkJM,.NIiN 坟kb >ЉÇ *fi=6nt?ʂr.5If5;lU*@; zČmg AY+Uq]h9G#-nn!S֌אreɉḂ~zϘc4HURCh jfOW)'2xy z~0"aA BvpYX1{-dW{9ѻN8DZjKb@U?ikQ#!*M 7"Tp >ړ"Y\I^AN7}ofWDU*sSЕ\p3ܸ^guuAw~S;*!$*CmV`JܠVI-53=6G#MGXZS"4uMʨ7K g?{^5E4Ƌ(pˮ\ e;JdIw3/M76tȉ9o0E%_J "XǮGt04( 6xGƜ=7MTf&2v2Ve虳;VEuUM1K;< sWIqCYT51' *E%M,%|>G @QxK'eD*鵿į\D >]z3:]9( ᓹ |o^!h"=kh(^E~5Ÿ>wY[X Ӏ @ty" | Dj-\H[%62:RިZQR~tc)85r,5 J`q1"M# =kҷ޺V&eRPOjo+AbtHq45nJ}y'z2D);,YwGRPH?ˆSVB6i^U>XiCWCs,+DuJw|AnaBõ@ePg;ng;*}" ;f\jIsX{ ։)?2']6bMbvb$"XЅ&X djR-2͕'jKNx2^5OQ>Sf@w %g|$(rWCbˬ79s3/ Ͼ@QI-?mf tZhuR݉ ,M:O0w+īQaG'pẅNE}]M=C  \ Z JoEQf ;-DIXbL73GpBz$AbW`z:uL'hǰ+RHnսus ?nH?)}hhs}Jږiv؀j\sFtF"5 ) ח4yJ \> w`+Iխ5@Z|@L _](f4t=, ߌ.L&4[0zKK ˨We@o ]F-9Hb Z3}P+,yمvG)[8e~4~6UTkr ,yLͻ>W09KUac)>UYݐZ2Hu:uW3g h#  QPC޺|$8?cC$Bug}?7c\܅OSoe2"0Jp;z `~HUM2a=Ϸt6tGʻ@}:i׊hw^)2u%v|kh|3a;6Pdp ^VӋvf\!0dIt2V;LHtGɂS䖿"-u&04/TD-: )!ƒ~+/^*_fbE+1JS`]峮*1*a0Q"'6, Y1O٧[9:rsJ4}(P& 9YDcRU%zS7)J4#EFKWqvdZnlDK},`Xp)[][g_>_t,*@(Bk2n"߈Ozkfc-YYGn;6/ m~LUEueaC耰j>j񛀪I[P܃f̸sk] dW+aYy9-LC4k(y:-+L8^c!slmLBIw Ģ lAG ~1Ira):S nh͢{$4(.p m"i]˔1^`{?(:p'tJ4qAs@^: KT֦e%4+Vթ>mCGʆo%C"{\lA=eƲ-V:­LӕI_Jr /x M+$(h_Iޞe8]} n3 WO$}ɯ&t T]A N&|6D<`P5S7RMF.?D(0 zJFŀh&hv_]yWUM%Ԃ"'.1gU#^hK3|5 &jI,P AI 4ԥj%d*KטE4ё̣@5Jx.-؀30pǍ8Hhz`4Ԕ>\1'< gt73dze-Fx֥~tsވ\_D”vTv Awk-b,Ak鄵mB aZ v!lt#?HpDCfd-;ӌ;B"6LmM%"/|0#d ,o3g[jS{Eqh_ xb)uAn+' %ڽ?ϸEK΢ jl!z["7!Q*q]Fq)1@%LSڀkVT)Nds{v  6X+sEMoN^ %<êFcCi{:a}RWR%&@>J.C7-/Vc@{ m:dNLj?y8&R\6 {eǭ@kPHwTȧ%PdjjtlJqqN";5PqSb%h 6qv}Mt Q* }+ЉW(nۊms(!0몒']v7 }Kt%v>T 46E+nFmB8<3xָ7l33~VId-UfL]>M=/`reFK1zm=':+1ޚN8D #O,gϓقN3_~ܕpzݭ[pdAJSEPN%iw(_TBxB;T3QWQ{>. BVj`t5ټ&D rkEiy&{JWP*utREdN.em̷=t:[hg:e~ip^&RGH2ڑ,.LQKUԥ y_>O49xCڎCtھ5δAb\Zl3(P)*DȎ.)u[ʄcMyj%42j!yF0p37p ;)=2-6*qVz7IZF*Q}ãA6:&IMj$lDBa3}' iǷ*`M\zEn &]͠?J遼8kd|ǔ+2J3$X.UtWʒXP@`{F|>zu~@y-Tf,FyaCTόL_8& m8`.ݡ*GhgeUj2$|"*Z/ G(f&BỌCwx\UlW7a#Ŝ&"#j4άuf5Ϟ\Ḏq+Ag&O{+B??~5y_}U)kbS >t`x5z/$j.b0'd5.EO cay_k!^IJcǁ MiApt#R O?zR~wl1K3 w՛e L$.?8epxFw"YN xߓniB1'+"<vzͿ][*ԡao~B xq^td*!FHJd{+KH}\Ǒwd`"C?z^LHƋBٿ@vK=`+ jXٓ+dGի5B4cяÁ z ٽ?g-/i_\}I`G@^>?sEGbC국C'CKNgTZ K:c~H2 HwzM|3^M)R91BwS/?I?{`Jw6zJdm5egɱ>$1xaQ=wI^hjbŧ/pؼdߦt^:_#Ūn?z6\">0Gmc 4Ȑ{A+ĀP5r|ɐɋ\]ž\?t䩷F%몆C(1G^RDO?0 3`Z p񖔌w1͕aW8̳P!>7 1~=qE$ T, bKhTwӆکWG8 @LnIc队<,7i?r{ԣ`ԥ:1ѹ&UM5 ޡ]w@'1H$2a'6Z ]  f/ _2vr!=dwiXE=(W !ɷp~30XЃ2́F8Oix59Q&U-u:hۺv1ws߷QOJ6ſ|C~fK#t!8Vt͞KŒjڢl#kzѨ|kW_{#|z#b?#h޸]mPɦYcx6+ER, pͰdp&++kkZ?Fz.>#:6#r-"ЏK]4mt!ڳ/4DD_n p}M>C^dB2 \aIVHPOz'4u#9j,=cN`T a-6/(dv#7nM~YƉզ}-7D+O{9_j) "s~w: jE")WZbe(QcWTs$JsTǃdm-G"͵[x!]K'ᖸ^v:N_;lhxOC:H^1|"$neH< R~1Uѱ"zD_Jڇ]~Kxq*0"Cn1C3"R!ri+EŃ'йpk3A(S ZM -bcl6C~ ӜaX8@_drK ~LL ĸr]ha9!;|C^*[kBs[ VXov<$,{.{M {Jl`%vP;}LRN%).I%jJ@ .,.}[ŗBa$w>1;^'lk[R4ZC_ n'a ? %TYr# "dE4rx?ƶcd0 `~HYlb*b~nwݩ٥3/ӗi+vM /Jy{Op5[|)FcH&ީX6 4?Y1 5g )7F .U2d.ȚBh&/>L=*> obi&g./a bO. R ~Uؒ^3o{ $3|,pOZ$weL4.Uq.azžOoȢ%y ˩aaARDOr.~ɩKhH qz!cRkרt olXk;dcy٦Yl-}!YƾpQJr[X\~@ej8h46ԑjuT@\1E ew(9զIu4&NUϪP!j:t?E$/pxЕ 3%{ׇwN@K RHoɫu@- ~(%/AMV;@hY}@8J+}#X:% q;( 􇌙٠$g8n˽QUFU4T BNܜ=y(t+r [`0+}T'>Mf3~Chpib(lRL燐 %XnnWT<:oJ`i0IO8xB} N+9"Qhl%wIo@ }Pur;;@Fn8dN0pr쁡@y /JGgJu פ3sjPG:qga BhÐ ?[?d~pb,@ҝ=_0P-㮾q"@=~ bSPRw9I *'t/$ɟ$ZrG>Mvw fOEw7UʛS8s} 4x$ЄOiJ "23H(U1)2.GrM LX1jŽʩrs6AH~kn rxkU8r ?T0H>k"d>ҠjmdH?Kӆk&jKXBk.\3̌@ I"ȕD|3>Gg~(Yk,N^CyҫvpiVD?N0?Op-jgbO9tA!erQ5Np+?J5ZetQ3*o3TH`֟22>0&RA8ih,eX,9^ ?gC!V< a72,vg$Wd~⼪vD7x{ EZAGLČY!u' Y8y_*/΀аSVОX5oW$5D]/rPd*B ϭr RUxuQTP1DloYn.y @q]M9S3Zje%8-)Ε0 ^T 9܉"PVdg \!YX S8ab0"t`:j GB"xi$V[#AC72pEQIG0NݔT41= 5T||2Zl8Y譼7{;X?I#}E0xp$j?kQ [UG:˨uQg'j1?{Zq* 'Dl_M(~txjS ٬֞ 9,7^ VvMueAegK'۫-b{ ^=h'"UwECqLUz-Q2zBN}2V%gP8W>'\"u$j@ɯ;̭[8UvЮC>~ ^_q;:8j y \kqCBu X[û>)H?gyAˑ,l R[@1߼ph ~$($J"v;Bh,ᴐq:[{F-P 4&gWIV|!aA)ܞQ39gp[iQ.bj[阱>`U|$j|> BInrBh ! }H#TB7g W@W)GweCmPW3TB A"6pN|F!Pdi:PGPs'le ɊNBj&ypBTj-[7H^\{8CUDSج4P.Q3|Ÿ1bHo58s Mbsg\j5䘹C3`6H#j5/)W, @FJq} }G$kEH *V#03_Pa?Z"VpZ"q|v8W BhB 3',Id'tϰese:0 PmσઈܥPaT:Ca::N#\x7+E)Vp"xmJ$z>gxp$AȐAjou.>%Գ"Ѯ7?§Uΰo8KnMlHTn:BY!W^T7{/OH""g. {$yD—S̀4jfb)DymRz-6CL*bbsED7D ǡ0&xofkǝY W vN(| 4AB<êZ+ ]@ۮօP#[TOClk2Pҟ(]q,PE\zP"{A@ҬF½"rl0nc4@ _`Ah=~ʳL_4Ud|CDQtm+Q_1~+M=JV,M`Վ10 ̣[X@^ɉ"I@.A-)N XegZ j3Fݔ+ˆ/xUN_ێ%%"4rJdF#H4`ݟf:F'E]Cȕdz `0h@Xl w~g-t-w|Ca.0u=jznOU>EL@k1$mq nh {d5:DA9N>Aue&\7 o  *^%8h:n|iwu+%uV7FGnFF?U6'^IHH hFg\mWdAog-/LQRnIV|V| .`Y"^e HFE6R3q})&!m˜I?׼Q TO{i!Lת-Q*ҺG2H'4NiSDm>B؊p)LaVD {~zj76' B҅:HmcPvaĿ u@`Yij AQ+EuX٧i 05YFrSŜlN62ۜ"N5 ;ǖ e8TqsL?liXxN*]" E1dT]Ҝ4TTsh=^VK-SP9NBHΫb&G>7٣!$Vj.Mi> HT9NcʹY04 @SH@ vP_;-vS)]b,DHB;}S+D Km3Dxi]8af8XIrs6FfV9T^UaUODit*vqTNw6~|V_ , ؏@"1a~ o&"xPI.KP lR:Qzjn}G@{ BlHlF\C)$͔DFz4n1ںl)56Cmˑ@ SOxv(<(nD.elm®O]J"wɛU)_sHyobGǮEr`*g`IЪp%$?w6prFZtncUI JJBQCe&Cx֋{r^I㐐5Y!D6T7$tܥ0HXuux#P$sqHv; <,r:O $CW:[6 E ĦtE-S{QyZ~]pސNW 1#px  ΐrQ0H-Dge7] !pCBLIhHmHԉnN+VTsF,jQH4-hHdBdڐ\R#n0TEÕ|=oCEc㨎 X)>C8I+L5 h(E/a{w`ReˡT41jk0!!JLрmνҷ ,):HBg&U턂eNe{XS7~_@Ys!RQ$ZI'B Q/+rvNa?ˑp+vP|+HkH H` F]'$suMkFm-+=r2o"Z}m$!5 lbV<噳nc&!ZWw74:<U(炍Ӏ`!^baph/0wViQ$=! 6ʘE"AZZ(ӵj(um?$~R_u#Kkn; 9-7aQ ,qM; :E0@6:BG/d!$'('W;$ u!VQ9d2we&\:@'@n!!egPPCXάFCTBU< m 1+$,`j }BT!B蔐J^˩ V: ,;UE_!eS˄!l QZiR02"u?_=VGYFFV1YL0Ӓl 6,ċ \P $g^g\xX*Xn6 e)bD o4ܞL>s(x@>TFnmht*WVU(!WH"d@ʹлTQ0C_Uڬ_|?UCB"Bޚ396^*'Fڰ`P}T[Vd9kh"iV@E-yѷ؊hetΙZL+焂Cޮ .)+F|( sL*G!):貛Oj160e+Ewv3&qP U;3DzOA "R+}q"6݊.Snի qD-*-J zEb ޥʥGأH߃r`(p8c jBN;39St+帕HAXiZn>G*P}2 m:>k<+~])Jvwn:P}d$K:vn^p+t):œdu%:Zu8Ħ_T78#ںgBO,y̬)TΨ: l- 1ZD·˩e9-Lҝq~a9TCbzgvt91 hUiwtܠ 4H#RjiAۮժU@Paf[ l槥|D4xm4t$uӫ̐hHRhANe6'eOӧ j(BFN)Sb,"Ɨ:gY̷Fpm]/o- ˉaChX Il0`"U1JC>:kJY|K;gb&?g.'d5xl}rsuЃZiNoio7tlA![u-"h۶}{nػ}gZV]-`{ -nL0je!MO96Μ:$7ԙwo#D:7sFM3LIw=EDCe& >B_#{B XmvjoVH`=.A_v qP|C-0P?UE{{{nۿ{ppm aCP yC>szUQHQ;4zD֣Q{W.%h.uA-JBuճ{=]5IQBU41ָBԼN eV wu GAq/Yyiu9' 3'W^h^ܘ`lsCFxhN2{Hz0G4#&9jRUvy֛o]_.ԮYP6 !R6t6ݾwz}抪j=ꇩO4 8(ʭm7HՔ-5LpP#' hXRv( O1$ԕZB?q`K"#xMotvtw`lcaRߘ7S>jʬ֔jsXcf*H(7vXA}6Noow8`4u"C\hqe*rm'$B Z=qΫ{wH B !h!Dhׯ?v4ˢT=㾴I2UA=ز CPԟ\:!jXlFTZ@=s6jQD?6 ID!($\ӻ| pFP'a8]0%iyO婳Uoϰ ɲO^Q؄YǬzA #΢ZkLC0<͢6 O}|wخV;woػqsO{I#qsϟ8~|L{'W.mw b;@C]) P#(kBw^Ǫ Mq5p29 TJ@'o>m狇>TF Soݦ޳du7o?K?X,e/ĶY@S[=E9ujq7v\\.i|i[o/ɓ[2G R󜫋`WkD[--`m"hZ=Lw&I hvuʵkW߿n-Z 'wp…Nm7%jbRܹcN;7oܼӶ !,sc o={ 5 8sf'y(GX9)A]D mk.\}lk-X2? GSe F^7 qdpPohj e+H"4{Nex?Ӿ}ҷTgާ¡!Dǂa`K?Zm"DSf,xISdj9Vp[|XޏQE4j ?!mjssϽWvX ݕ⑇O_|乳; _Xmm_͞md)Qhٝco,?-ԮΞ],a$:Bdti"<kAgC6'8Q*.Z!;%zKFm.ψnsIE, lu8ɜCB-EZ $1[bc*+cHLWrb3$vm0)DյQCtMYThL1XYe۷/i݉!X,⅓sj}r⩝> BW+]?wo-+C;{w ݭcǚE5݊Nue7I-u` 65r\ݕZ91SJ;bL6{MZh(? YTp׃#~в A ~wa4{-s]5R=Py0I9Wv\ƤۆžU2JW0u17~1tz-NT۷[ff-sl|v VsRhE9[jWo{|qիw@.;:{Z.o߆wwvw?\i4h lZ9/mӍ iHzx!Mel+'oXs7д2gs*ocgViIu Ďp[!5'NnܾsWT簋"n\=ybg{rjQHѨAhD\T6N,G8!D4Ԧ mzicQљ%fQ,M8휴4HLd'HɨMGr!n:/9}ٳ[[] =|ίg|A"Z.7߼>xJ4o:9dB\wƏeh[~-+p44U+c?~'PiءtI-a?^ MC;;,?mՋ{; yIŭh%|h 6AMy _xһ=Pꊭ[H^jd%RMUE<l̺' Xnj:$ĩVbɻKW':DJl>y7)MpctLqjCN2 ims_8oROskZSkeM~h TtF_ǰtzz㏟_x…SV>ȃͿy;8X3ϼ/}WVG>/~ N~S//W>@̦/ϒYG:g-#}g-go].; N>ą3g>jg@m&.͔*:eAZȂ$֎-yy lZS)` "VJ)G2eض"jj@e㝂S΃R5ncHP0K|j2`#r:#Jyk\pJxP'3o{x;}عs/|{_ҷ> ?O_<{vWi]So/^KopN{~gG_,Ip0(r6DOObʞD-я[߾tppwk Jw^<oPg8[@5IM w,+1Թ别Grg{!A Dvݶ9Dm#j:-:'"rt=Rv>@谧zE8Y_ns\{{`Pƌj"EPKg8ySekCa֘k16mg^;7wW^}*"=??#g!{駯3\t~/^}wWpίgSO{KWܹ_G?y NaѣɎ3ե`5@xo}b!gD/^8sŅ[ۘ%*j(+xc$BۮղYSLz]yP9,˭-; A$I[(!Rvö}|wI   ^rl+Ϲ J@hǪ:c3w$ 3ERQuEGkZT;B[-wԟtO|?<_s?zݝOǷo~կ}텽8ɝ;?O]|ѳ޻ E?󙇚!4}"l'5޶>/7g\,b{ӟSvV!-i]hC(T$<@\۶m[3A'TECT_`Fh? (YWBnT''mvSϩ~Y/s[>ƈ(X*jඳ>:`ͦL^)/MmddPUE5?1ˡr!NM6kKk7o#kw.q޻ϟ>;ݛ7WGwxwoKW+o3gͿ3gv+:{Y}\#fMߴd4?eoA$:O~sB u֒.n v-]DRR+aU4*A# ZEH*k;AP>%|o]*u 2 /]"t%=RWNeҥqf󕙱 1lox.S! cȠQo{_+Wmut{{\vM|H}ӧwk__gz5S}/W~=~l]B)AOu~=WowږTc?ϟD\h ~rxke2R$+J%(z'GVɭ(v "rdj2oRRgboͰixnTS* AWuaJ=,qnM*=gO_~;_{_ܣ[毞{+Wn&(WWpnvwږri4|iPc7OGf4L${`M]qK}Bz[<{r6 O\|D+:#-n G__;#5MV!PڨiW|٤QA_CnGSbב:VzNIz5}r^~e:^nF"#Y1Ƈx܈8`4tw=/T;t(hg&Ԁ{{?yUzO?OɓهoWמ~ʕ+7<'N<Й>#Ξ=Zw?{?|O;]3*GQwo_rT$@GG?߭eHU}AmeZ;Wb ۻѧT HE͵D *IC_\wftW~Cksp TZ)݃ Vcу'Ad0##R9V:(߆.bUSP71X>Ċض[W޸_~ЇΉc??3{K'8ujO\xsϟ;w Es@Gɇ>}1heL+S/ ;-?:g}m[xBZAF RI`z7D_s!5MW]k [A@Ftxd!N[=U#@RnʤCB*·2_Up< Q]FTxJ)&dOٽouqq|̙x'я>zs/:s؉ۍ={\Q={voO'|>35zut  4B /J8hm3|-i^}rGӯ`r!}+Z'duÝbCUdǨLߘ@7~2lx]a:b[uWtҵv^6ݭǷΟ?V۷_ҷ>iL:9k+%h9$N} }Kɝ/^z.5\GnW򗟹v[wO>VW ~/8L+N|+Yc{ HtJz62 q˃;5cmm+O m n8K u0s A]yhV4wn@"ĿƘi5Vb[4:ʀ|lIVHlz4*$?/}hkk!^3s{+m[moo<+b[zOe+ Ԕ~gxի7:yrSO\قqjXsSKՌâֿX4vR 6imBT7tB4 z%2?3(K=قwK9,R;wF`5jӺQ)IH-~OZ?#8ꩧ^ׯ߶}=v@T+_|Ν~O}Xg3(QsLBj-V[ݴ8eֶAjiihK,ka^<~#mQ,KoI V1HvDQGccȝӎՑJS'Uk_iQ Lښ<=n;w~»_{r1M=t~35m[z+B+x>?פ.vWZum}O}BWO opEw9x5Xc7`MMoy B  $P-܄@i 0liqkzG]_4S G? ï{M?G9?Xw?_? Mzw7)sggqp"-;߹?nt"' y{|ի׮,'?yagg1R ] =T j4_7\4iM(LQSi޻yQJ/9y_ap7 5wcká=wm9un7y;?zßc{ OdؠF8WPKb2)0 &pb5ԳhZ$I$IIP[dQ$텳^ޯ8닗Fjt>zN-AVj9yrĴ!ttwʕrO~2p媾jzi5[߳ti컴>I`nY%dTÅ`,hשVnS A!H#`(YIȄO’uC=HL|@Kȑ5A#i"esbNo\Ê"A"P)F:a oѻpJwsG?:1;+@-o1n祗Nmz{cuv=ȭK8çNw% aٳ8Bxv5ݨ>I MO7xҵ#l(bLÜ+/L<h\݆'ޑ`&nYAA K@ӒWD5l M?.d7I;ޘZx;~bi˖e߿q[.ˊz;yNeddرҒ5ܩ;C׮M;~vۚ 朤 Pak##.\/ p׮-޽2"/ѠmM8,#q  0PCy0PfL܌YjPXp1e)g$14BBu'wbd-EZ9T;D|wSӻU>N[Fm}v򓁅b.۷Cڸe˲l6} w\:֊ݻnu?˃&B]`oC0y}r^Z[s;v3=!SCd"zMdڙF voQrʀ 1sF(@(47w9Hׇ7~#IՔHr")UA-KAzħwI Cz3>^xyX \A>͞ryɰ^COixx'=*1:%ԤPz kŋ7.Q"FϫuWT AFHD\jGp,UA7V՘V&:rmUU:>i ڧ xU%jm^G  y,%3>>xc|lN4>>wT9:H- ]Wlٲ{s47gpll?<񳟝CdT'9HK7Ti{{n%MMTPOi̊Dվ$/EY =LUu N_9R0Pqn@>JMtI@(N"F NH4"Vc͌&E[Iާ=Qªp|T5wMRn;$?y~+צxkWL7 *<"ݻ%ͷͲ|dKSSǏNN*tD??6SUɔUQ2 'jkWo DިXkn*#OQ$j'òe# 1 B`D 3*c: XߍLNZň+xLrK0 `:4Yg&-f|OX7jfUQgV)pr3#hF .֢uz?[lY#{?mmz듓bPggmf}h㗾o.j=;[OO=q {{L&Iw;<<15m޴5yphR]\ycF:'1LR EwD `;p 8:S#\QM-길+"{,;"~@ z~FGg~S?qnni~ kcX*DΏBN{{m]u󥡡eZ۷9ot_<_(=i\x+{2FFfϟ# p, Ȝb2^d7f Kw.F)ٌ(D"0sPd/qFR&Z d L KY,"II.BJv_nj(<(3z ,(m~Bگ.|{GΜ+MM[u]nڶ<הH 6?Ӆyﺫ?FSS߸1ɰ{W?ЮK[ ^"> pξ?;=;AzZ,b _ͳlh9 *$F/eulٺL_gWFLKy !# =F lWHy!d(@2"U~rt $b )$C Ɋlc$Lz/ k E<@e|.2 0n4hATQS~5U#WwӼá}6 "G"02^*$(]U=Ia'=!D>  *E"#XH.fs1W_Cit1qIIυQ ]b-x{qUijERNUԣ:;_~~KSSd?)mz097.~SO{/tPօ r`vm;UNyǎ]J)bEIFUgBT^}7-]CGWrY ̈́wLq @4{zLgQ{ rI0@#|ĈBS@ó`Y$ƛXQPJxv0k=q[j>Zl\a5ۣe7(eXI:~QOz\U-š,$&PU]zZ(kCjХK7x:2hn,Y#~c[A~I!iDH@`w0n5qx(/ E,"JpZbY-k!EE? v_Hr㮍Rsb7az]{L%='H5;Kh_>3@޴kW&ҍ Mh ,׮Mڵ];w953S+Yq] |y>dr SW_P.SmKȬ lܸtnV:}@3Tz3 P Y^"zH9 :I$a hj[4N^ a & "*!3JQh!aaMYlKX/y'6)E*3 +ET菪7]qkk]O[[w{K#zLaP(_2qZZ6,z{VK>?}Ϋzuǎ<̩RaS?r?K[wSpf Xphj>:\ښLqP52D'1LB# H!čHC 1 `(᧚ m* JlDg֎5=9Iި B9WOaN݈F']\:(>:jS_3p=b/׵{G^VCTsG5HdD87I@X_lOjJbQPw&MGGzǡH}}\Yve>M_6,qO-F; MaB| tk `6,] Ey $ߎnDCrQկ0&VNh8|HN@`1!S!$a: !&@^p. Y`xZ`%=<9.&*&T&.}yz u$@Lj[J~$8H*7T65^wO.] w?)DRU쟅 47gsnZ逸N>|9 nZOl.Ը{W|[o $O?=P.뷶vu|?+r78QGg+3[D|zl2f maƍLdnf&Eyq*$i$#!"#羢qǩpXo3УRJ^EAd%I At]ߍJ#7kJ;i"!S#&!E>qs[[â~ZR o[\=׊'/ҹ'86pr$ 2v-+[oݷeϗæt h@&YreK[fMWR{۲e}꩓_4LJg=P'4Cʳ$NSFfۡHG$6NCm&P}PHz )1=r" 0 \T_ID]t-Mij,P8մd }u5഻:ݠĭ &6F(H׏; 6V=V:4E4%zapâ,!0 @g')K[` $a0u}/꥗_:?;Wdmm;{?neEWwU_UV & (=aV(lL!Z0-Cn~ssy\3*YFSQN_(E9|kp/8Dҏi &sv0D=@$F"THr =]CޕI#@*FD/,RJD 9H1EH:6An>ט@H@g<Θ#*L TQ;3BH`\!=8!Ix5EW25=ٿV*ierx_^FΦ[o]gw۷Zp LV2j 岙 ELe29Co\c:?+Wv<9e.^855]&AQ^9J**ٛdž쮻׵7Y-7"@b0J %97o# ĀB}DrBR]H!>r0^?E"^"Dpg"0CS1 F |{ᘐyI.-df/lP! *35aB'p.,o}F/ `ÉZxGR|;5xzo($U{XbbW#Foit+_^҉#/9|Ӳw襁5ȧe⫽x45 KDE Yt^5%Hx}~xOS57}#gΌ@*SS'G eWܺu9j_i,R%'0+qwm˖ӆIsX۬ { ;FJ \ PCi+7>iЮ9e9]!r&J]Cj9 N1 'U%{g6jZ*Ud3iğW7y\/^;zu =7]T.+W EK;?%Bi۰gJTnommgg~Oٳ?>m׮>9 H'i[p:~)hmڹpNXy]>LJߊReJ]Zz"Đ4!Aȉ]Đ#Γ!2cʲ _ɤ)BrFڡ`8-jܭLavҫ)JKF28;1ɽX/qO@SLœi 6띌{NHr^W-nQJ7@e /'_}T ͏fz:?00z}"|}3 EdBGdr81c`llyĒ8dM7-җn}#G\@W'xX7KGOON㍷reMK3fIVOAHׇİ9P!Iלy.n'!(]BBJ`(j Inbvٺ9;TDZTNі1 V%.Y nu:BPz}aynM5ϢOs"]O6ct^EBBէuxImh}l#Kwzt{ܶ90_zLggsWwsGGczXggS\hė.Mq/aU3~}l>=Ƅc-'تU--YS|y| rBu^tc``@Ksvξeڵ6bvR;rX2#c VI\wGPoPn BSf#J^ C,TA{B1@i$EB465$e"ArHwi^t2>Xa3񄈧xXڌ2 @_@M.;0:v qVy_C[*Tu-_jK;*2Oe.!tamn|{K2 pn_c{ξ7-%r IP@<AN<7mttx @DG\/~Vf?LNOgf Bt2J9i cdžggK,izS/Kc%9¬lrhR< E  EB@ / ! ĸPRyCV2"YvHUvf`c`P0!Tjl!Cӓauڴ=O+rT5Lt0G*$tj Eϭjg б9`5~;9 )'5?j!+X=|_I&=jjQe); N=?<~赅twǷo1i)6C<AAV> T 4D\X(=5kK'jn|c[zz~𔺷P('e MMC'OiҞ58FNhQL5$`M(be@!AB "'f%s Y!^_7l#HƳT#`[)rJv_5l@ bW)4cd˽?;"8\rENj.==Gi}ĪT)yClp'!A}i47pkVF|7I"y䶭[RaSS 99r/[{;911zu "%~ZZw{ylZ抿ř/ˡ3f43SQQ$v&S*h)*P&}txD֜2s g1U:"#MD ؀j !FT2iRI Iv8Qk"g3舱7sէ8e.MdU"IjxR&l54O=ɰ֙Q\L^w7=7cEΟ9;7q2u9CXԖyϞU!\6ww`||.&|f3v?g%A 1Dp~vIC?r䪺馛-[&;YqÉtR~T+>`-K> Y 0u#a Qr'YNG̑sK ̐t#d[X1@< T1#BbU "1U}2hZLB%7ċ!Lp 9V8IᎶԜ)YޒEտ*. ՛Ш̞:H:j".Hy$lټ+Om_o/IVxˉqcA0#].qAڵ>x֭CuNwqkxEJʕ_]{ 3?vvh:koLza~DDKd&㢆hrC<V]OLTԙt RY0InABbD58@7b T#1B@O05=@t̶xw:@EJLS11' Kc+I}ԊȳKDb׀=Ҫ\1c#T,+Ҽ/d."nV&NMq֞ヘ߱bE;v?};miBS12鿨ܶmgT*\CcQMuLsŨ =$C^ CdaT 8sʪRj3%$WGx]uSmC(բUj$ĔvJׇx-߿0 Jkmf 9E"/vkT9rʷu+c"`Ѭn,^ҜFF۹sEKKjC izDfR'*Ff %XOR+-ĕ1 q(h@[@EIJq&1I5 4 $MTL:@j8fhEgRCԽ䶡m_M2Y$˃U@ȕ!HftһffU71Y˗ӚϗGo=љ0$6_|sswܱvξ֖k{{+-J"Ƞ=y*[u=q%gZ.Ǐ XѾvmƍKڻsAssΜݿLQE]+::$?X߿D8rdX'1`sHzāDذdNuS}QAe9G"H8VKruFk( uoHKLi֯:SNÂtȉftJ,iQVW=2{KWI̔kL'^/nPCiUŘWr *>8Tg2wNr4D>۾; s0 ܲ11X A1nmMkkTYpꜼ0<$7 gؒoHO!}YdOrC2Kɜ%pu:Doaf. $.5dʼcI $6(cz8*01I5MjR-fuy|cVJզHHV 6JšpuZCu|a&P3|9 kߴiiee (, |WDpءCN=wnB؃%uw7wyڍ{ ~_xܹqQ5޽ZD Q_3CAˈ⤆ " e' AIEĥq%7FF&4.3)D") z d`LEnn2MC2DF&]VfjLR[\F8Hhk IYI";$zYCHK@u<5\@Cjb"I zF{q#ͫaHpk2~vEi.Ka@&Ô#;΋@09 g^|SR9';'r, YMM\.hjb{.ڻ;:rͭT.W r;zzZ!{S@jCI%xi|`D!(@Ε AM jgnsXPS<[3K$2e>!8f4%ZlE+PbMf*Q5'ʫRP}K5a=`DIe>k%Tp#{ 7]=| S5z?dϗ%.1 G=|BJlutV\kݺ+:ڲx&6Qi,F` |X)Bti1n쭷fCS6m'0?]R%@' zPQ9gʤQ[=rو:J100Nl%ROh$ݎHT {W= ds%G0x qn4M5d2dnwWrǫxRcFŵocJb9شTSS3UiL@DK tܴ7aX ·dWP)}o~ 5ݴ-zuǎ}Mx`VnȹK=I'G/]RdիӡmUlܮqq$Q I=M}~'Cגͯ B(A rdH0\5HjO6U3x{]I'kZt$Ł"TrDl9^i.Y:j'r`lW]қ*$ɬ61IXCtp+@n*A8<y$WK ,iY)~*B) C (%21rԷIYܲewKۤs"- fYH)SMnkÊMo5ϗM7vt4KR{h1YaOuPz꩓׮ͨ[|߸P(75gҾZR1,|,sCTM0?yrȑ+}/K[ 7'P"gCcIM7޸4?_K|7/JXP$p*G&H76C I&S ` T#_kYkR* +.(zZ'KM"mdtO!镐sOAHY 6CspʰX9;=C q&Z\YALbE5wVdTq^NSȤǕj'\GŠ ߬9_aaCrXo{^LLETƬ RBId2, I@b nc?}VELc. N#kddKJiL&aY\Wb̋tP2&`#r1D(ȅ#~*`tސ TU# %C}=ȔRU$`^0H6>Vi  <騬t$uQb61+@ۮ$C2RtU(C|^. a\l" zۨn[ҙR*xVlz|ԄCj&ХL5kצ5w]OGmM O6x#T &\ Ζ2իCC7x M˖9S5Nsәdo場!"mڴl.c3ɛi7 ViHf1h8&@3 Ce3 Yi UJcQBͧL769N mX@ză 7f2:ȫQ2ǁw K$&(]5ׄ57+mt!S.35)#dRnS." lkKnO}j?uo|cXѱc{o&,vkH~.R1,<ۛO|d yM@5^HQRD=@ Ir*=A!!c^#U O\v(TH&thR[(b@jucXURAjv]fN=1"UnZ!ߴy󒶶܆ =MM×_xlDktm[kHKaQ!lnX/G JX"p[6PRqۼƥ/Y~jBR<;0ۑL@c Iҍ@*`_,62!z omuT )1ց"F FA"0nBTT;&`LH(W com&e٦*գ4`0SgU3%⛳Jf䠈E޻GFf~c&3w0Sgljr8Ƣ`ii9>*|j(sD@d߿9690 ":%m9yx.衫 %#mը#dI:&h'k&8U4~4~+=莚Fkc)x'ub ԙ[V0Bsg~`RggӇ@{? =o2qf-uNrl6(Ñ7qE`5\pSr~[{+hutT~3) 4OFF'Syğb*{ߕp0 )n@v^w$OoHH K!2D&l$L <_G.wi@P<|$0* :*[ "8>`<l^`I Cd( 7p+!a_xHLROP[IýqWՏH@Uɹ/'b)4tsU9ts.!b>qɒ"\Hbb>{{y.~ff'OLMA[ v~ WC;9X3<梯}eP9[o&rEMa["〓I_߄hYS}BD>Ktd qW|u̎T=4W}02z(ը`UQ5ϸ\P-ԌC,q u צ@~p7l ?əﱉ + ) 9(qMaCϞ=ʕrOqhxx [,fgsHNPVorf,k5NdrGtF&|c9CO@i&`?(`l-g!&.ϙx^j6!SCm6ޝNأWM1Vb,ZJ 䀸XJ3d0>:aO+$!WUjn4+my'q(X\BSDW;밪=H{g~v*Yr800rh]%XwDaYВܑ;*0x`;clvpթ B.["reʕi뗬^4jr EncZD9DK| %*XQTKP3Ţp\%āV棘d;L2$4UAr 6'vx){<|XAL%}|؟/{[[ lܜ!:>q1s>oٙ~֭uDp YiD9.ƭ}֖ۺuYGG9$1|l\uVO0Tɖؼ"G4k-K9zW)4PE QM Z `*.5]#MT*F.Tu 2O㷢;&بv`tB295.bL*zS €N%C#%, @j]l@HI͊vA5F4NJKbkab׮ݳꑯяmiif3-7I{%a;, >*Jt[Z[s33^*ÄRmrW3* %[,3S]ׯ+Bi3C6M(RiDA)+:A BZLfO HfG4FQ1΂7;U8@;&Iʧڕ&r1 `t?Z,5]0x~聚xW= MG*&CILUIJT5ld!1ۅd麺[''7\޸q>-4Q⿐Oh`}Æ;W+t8R^T<9~bllNdժU:}Q, EN? K {1U~0 'FJ" *qHfE,a@0&ǂ^kBIAAJc)NAfR"YCPkhMW6N)%P?%.|jEdxH˥*L d(aIXMOV},q(27X)*{{ot?xڵlݱn]OR0$STᰎr{pll7E]fcÞUQ6教L`K^H,,m6idjq͟ @*T.hnd)Zu5 S|r栋CA'ۈҔmCP@h2C"Ϥ;ZʬfOhqWwb #;x&W 8b_I脍U*5ɦ7DoOֆ)>0jK;0{;`(wǯ!z#?2%*-.ScB-+r^'%${cVK|XRW<9 ޳J UQ0m4KȾ+:3g:,NEovbK;wuP y"˛`CFjKLit. @ a.7ͣ:gC#h r*C,]"B2B=mrk |ScyT @q4PK'l%2DP =ͪ^2Dz%L9j(W35ԉCPQЇT4!80T.jK1 L_%p|z"~mC7P"UooG__2L鿢<|#bҡCWtB>?"?\1][ f}`%7R#{ *"Ɯ0<_Z f0)#-d6]D7nؾ]?1f#wB'%Eg$6&  ٪=X߅GXZre!s2^ APeiŧ~g6 HbF\  ?酅z987FƐI.jєn{gF\{{]\P,O_6㪓|ybIEռqR3GN$!2Đn$ AI܅HrI2MC=YUF*-81O cQI̊ A',p9Ud)^ϵG5NSP#cEz 9XGx űrQ TtgmHZMH%zaE*$*yl\rS.Ѽvm(%^`N&dL )g<9" 7! ݨX׍vư%$SFoXP;ټyiKK6D&+2*9k_Ehs70g$ˉj?1?2s%`f%n70|Anyr"E f Q2wHgwfhqnC҂@JPz;a=%jP6n8L*u)z`;;ӣ@hi;ػuA=F21i;߹-/YP̣" ).eA&Hݹv" 86tv6ύ]pW0fd)sҿ.H̃;G@e܅`2YfhFq+b)=1w[GMt0ȑ^4Y)%č %EPCT(ʁ :ێ"E/g!)RPL@88Lsy&cCEcB2Ơb1AKq}EpM0p 5f | L]?ό_|粹2a]|GI0aL#" C>d/wG[}Ѝb[[.:UHA;|\\1\O&! @Sk=2OMXB`“o)(U2|Zt 9 Wcd'5 f_{YD=~xb ~n#GMIt8FmVaqš* Wb& J@JdQb kպ1%q8jzU9%6*{yͯ[5i>g9ub|`&d2 I~jgT+c}{/@CC''x/CC7\R]-Ui?M 5KJCDgEf\ f2w0JLULiP~%5.fS1T2)] J,--4_ώ*A2Lm>ͼfSzzB^GuEJ]!ږ%LqIcB1/i-z]QsPCӰV~% KB婿^yBXOܔ$]f7\sgcT nLL̯Y D &-93>7WT/8;7ngDh;;G))7N|t늅( G` zd1[m ފr2pnVYL'&@3;!;3XQIe p"bU-%$$xqd(wbƝ%){T ˡ@>( ?.0!oERhj: ŲclDr)aXJ7/==|o8%f)ыܱcc3tt4%ԱcX9fxU N핑(y|E @w@'VO_ˠWU*cUa~[$V*mnLXn 1}v@bu9ky!!T*0PTwWPu{WCnQ!{{I2ɀʃ {{[Z2T<^Cf刐BE%h}F;Jsg__FRE;\244t)/YҺjUW?* ّۖ(dmjFX +F2(׹(eL`| qq@myEi(G(IH&E<GS3„#-/866/wIhG[7|gn-،j&$!6&TOj<CfB̓VFbqbE:z7J%2-͙ 6ƦWLe |xLL-俟:5&+@!bIAmmM-/"67F{*C͙w̻ˢRN hM3s ,@c1AE fTC=U4E MBlO2Ec=~׃z)Ī^Q,2XMe(> 9/a\lcգLC;hO(Dՠzluލ".om.5{£zuک0uu5ww7ǘ*ɅS%~2Y UBHEwHmfb<<<3<:H{g;V'b3Aވ }(8QU%@"AQ%A=d:=inrPt_[zbT[(ƣÙBg=sK\#@djn9JP1~m>MC^uX1Z6lX2U_wĸ[,O~>|%5['ͻP(¹'F$I"Gm3W3ّqz戔X Vaמ`imR1[H8 U%0Om?yph&Ep{Z$ EUt=D/:%'$fhתP¥p:V[meV(pRU)U5pZQ"%IJ?b9rرk}/c6 fgis ג`Қ4XN*yU =9~nBUH%W9T u HАQC 6j:ߥ+DU5&`zj7.e>ىg=3?_jiɮY-¶!ܨwH7bDhmr,LJ#e"x׿Rt῔3Ϝt醱/1i:M4R,g`50*R8m=wgB~l*l3 ֙NdIJI;%y 3"|767]`NK%C*a\l ?bLyd2rDU[tH;@̝wyWoF w>-h'Ej?5؉ ?D`@Hf߾cKY[.`-7߼6<ok(sNm`3=dg E iFd9 HUt d`~N#`ix0d,Qe+@؞HÞh+]E.y4Ԅ)yiC)iwym 5 J5Hm[(.o4^>xJWw=xƍK+CFLpGw\p“O{ٙ\P(:=TF`ΟQ EXlUolh$˝3¨fHk\~c%|rJpl@(1JZKLh 2= BQowQ+daJVH `-˩S֍"wmAb1\nɪ՝b b D@5sLul0Csg &GiS)P[`-Kwߦ\S2%R4ޙ#Jƌ;=A<"=}KJMbˬEHXz{]EA\[+NLJK`%XqSUBdWT&CX] @[ X<9(1jI]. T@000Ҟnuͻ{Z\ l>r H7{eCF8{vɑ|56#E@Qss~e].B\2dN9h= Wj'[g0U#k]0Z1@ IBzhČZl&POr%+XːLRU鰆(Ίġ  PIf3TK?JC.:tޏ}| nP"&dL}(aܳփ1dS\"'QTyiOPGM0GA6~SKz l9GAH4!Z;BqU}/Vp:T#2"// UV$+EmgvdD;(PdQ"c#*A~}0T[tr!sAK}lSCKhP2# NHV*z"Cn _E瘨NU* Cg+ޥDt N?>L!1lг\a[o]mdVw*ҝm@:r5!Fm߶ĉɹ]tbI} ɲ͛sY̽P\X( ͔a}ի;2eGL)59e#=AF h&J0#G3&m=Ҩp?.j%Ww8SB}(#56Jw`URR0>jw5g!8TIIeP" 9HTXgg !Qww=o)ZӽM|MVwNB},iA&dx-mwy`vcG~ ݷϓni0 @X~O>y< Pqү|{i 6rk?QȉA&^(I֊4dBN6XM7r|ApKӨp)iPzI]T;*P|it&НRWpT5"Ib L5}Wpɶ8JzT-%u@d, ou͟=-͙}lC uɟܵvmġޛq]gfVf־ލN HNIEْ,ۚEPDh"y31e~,HJHepI$@@յzYU˽7ofU7@TWef+9W]!FxNj[*)_ľ}'Ο_C[nes2)øŭ[,I/>zѰ B!]c@'N&L\p4tE#ZiBrH;'ֺR4P5 pHL M 袭!VwQ!DlJB܈9"BXOJ^0N!Zn&gh9}:6)#Eab/C~:hԵ:G?{.;9Lxc0sp@(j߳ukap0u\ J<&}ç`E94f;N+wu׍]|D Q@sȶu~g,fr#OէQVN[`I؊pm~Ah7NXҁ2ğCܠrޟX`VDzS9<8ORO.oy5<.{PPrS;9сr6 PB˚,Apx!A@yORHл}w6۹ܰUUNoS*i V~i2~۳'>x~\/9=6Bp4jS5Fy\eo~f $]h[W&qƅI#cD g0Det\MYem8]XAvF0g0o?}NLd?:jOg ;|/g&HP* >-RI\*E"}@g_X'S)AUT9::P{%s}z䏍D׉1g 0B OέU UEμN?A/U!apAr0V1(㱳PZM/s'N,ɟܵ{0+FL@yiȉQ'}F*%ybCÉ :֭EpiMrpVVBM Ux ''sCN&Lo{s,-)tv @I I;L$=|bB)95;[ajBط{8elv,5oVA9@lh7z QNș p;[/>w"PfʊH|9ُ( YشVN\QӐ"@J<`%/' ȫ&EEO8(oq6 qc͓ML/XMQ7z~qC!kG+qު@a23q UQ V|_ ˡN`f޸:i`=)CS5w=i{|p2)W\ަ|䔲iX8PgcHQ$;/$bg Ed ۶J ϠU"O慎Fr L}<ջ.czBDc" B'XDUe,T0Xs3Eb30457G7]Q%񁯼`Y7?zm&pqu7d4[s$p7(bhv9 ڷ;tRJ#&~B#"a5o8CcOVok( Cfhi:?7gGjE%p=ۢZZ3*=]%2 #,;&ؼ9ķuknu3ȇg*" --GkD\|`j5"1&ؾøS8`QH ZH O||LZR5pSm!RJ@OE3Yŭ !4oz(̇-`Ih/8525\.Ts(u{sU [T[ 7ܰ)& DR9[LO_*fQd(Vr0Z.'q9/#\%MƔ“Dy9Q(zJhr,Di7bFG%!qfP Cr& 2Hnun8=:o f$!`j'͵} (s4T3.&O(5^xc1!|f~,['K<8hXM\ak'@lU70[!o^H1,̲V/pxڜU4]WvO` 660avĔN+bۙĘBtKCΡidDaXA1IlQsjB=-UGBƬ WD@@AP[_c坼PB,,rS E4(bz9O(V{pHhk^ h1 i ΁$RPT!CkPf1DEaN^.&^E}9 Ӡ!R*wY1m'Y`J?T"V%"~$ϝD (8L}X!y8C@V"~`BP[ = . = psBD$JEէOΜY ||p % b qE,i+\W^.eY1c~ Eh5@=xSmDe/ADpx!쨈39k'2z0գK{ӆ *X )|DVE'S `(!]LIR)E^4@Ӭ٪[, 7H,[jNe|9!`r*EnٯL-E yPl2mǦSeBAVD:s0{xg"Za=k!Lv ۜ܌Y*nb b)Nrn; TC>BԲi5+_yy)!ߘ >fji?EJd:Bna cQc1uzCCЀ<3 X=gѳ.>NaqL͒ndv>G Sp4=i'BUZ3AZ⎃j4]@9qTx7@E I.EPz8{lY:ur[z-g`f0:-{4 \0M~V} DQz9*x9l0m3FM#PXh!1i? דheX0q=iDAME@Kgg dm HCSS+l ]7_ĝ7DЬMvzX{B\%*_[o-9[j6u A;s+k0躩i&H V$9'KJ :Su۝t"<9:XPНJ2D HڜۼߢbOCJJPrpm@I/BQ~]=k1 {o5K-E1 Pd趁79u g#땃O5N/M}0DTe;Ѥ ȵ{hrʦWf&f+B,~eTV=41to5-UΘ\U#"9I'`־ah}r9ډ8#1B"IӢq[u̲+(- O`b1i剀" - @,&V|}lDZ"#O$~Q)r4m0H(W mVXF 8 =J8#́;#P!RJGwx\Hp~33U#<7W#x9P\rGEam(IUn5z\PLd#FH'!8hmS)f;?GmӕB &g+ܼ8ZA&Uqy3sjUkY䥔DRx #K"M@fjC( lL(TŏDlkeAHH]d+cȪʆzY7(B hk ȸ92/;azkJ-pr Ei5-mQ2Yig!aqQjl6[ѵ~zxl&P4 dDŽnl{,؁b#IQgh8p qh;(Tn< PZ4nn6׾vॗηQ@i^wD. W :ͦnL&N8!Lh4t ˱-wˑ@+߄_K{a"H re8|N.>pUH c Zp=! ١JJt{!F! t9xGE]Bȗ1L,i?= &#) }f$ }#ukU^_CZE?(mh!ɔ,K"s>M}iaZ9%es9ң+ג(G\kk'\P@@ʺohi $]khzR"sqjj'B> _[+6 a{Wi '`T, pSDBD F?T7ְz H!@HBPH83rz[-٪RB'U֝/< o{nuR#z≣[ xDBr| v4qm Umq1Ys$p9#O+8 $ev ,o$(sVch EZIbAP[+p  !Iz0ݕ6RY>9,tp(](.©0kp0o/|sr׮!G!? {ek A >"0߰{f.!L ߠ@-r5t&w9"U)Y&pf0m$rR4ٌe%c|E!Nѧ",eP3 >u!HrTpw&!S`^,&]n8cO>xt!P($Ym>?Ui6 @stѺh7 G0{u2 &$Zo1(:+|(P] B~՞Lw gFNf5BnBUwB0&0r> z=;Ν9y ioS>G0Ʈ #b!>Uj8vt>T@hb"˘Mq!UJǏhD)YzWr\6ۜۘPݸ*vUedpR? k n D4~^8X%gF"rt ![co>{G:FJoYQf3Ȉ_<3BJ*'&*ޅ ϗ4}1r$^>oE YH89'U" =c9s1@Pۣe_JJ:~I7doWz'KxڷDž,A|\,${Lonlg3[˺s_A-Tdښ_Kx#dY;nfH61u8n);a@ET2DQz'[J9EԌÄP0ƿՁ B&[ڭO*^UjY7NpkPQ4<$LSyDpj>nxQEyW*Eflkh3Cۤ29on;y0u+׫DiPbCFnk@k1osRD!T7bTvu¹3a㍰csu!@ ty?Uh+Z &!_p">e:J][aD:/&-E>8>4,"zm/\dDMXU Mp.LY AӔ|pB(sos耺[/gz??@A'cPNYw#)`fa"V/wרx} UUgms* n" *TCR8oN)A[ 09^05o""+r+LDry;Y#VO-:k!}C^fty)8wr鷉Βaey߹Gd!V [0R2 T: @ \>?Db7OMDZuOQK L@Evl?0Lw t{(| Z /Zvq4$[dDyB7, )ULmbU1.։([ SZҲLL`:'dHk| <~) 5$wfP.9t"ۿ1nxd@' F2$F @!?G``a8ڸ:)!: ?Aqv"Lgxx*WhN޻@pD٠4aÙh≷ K6j|?hjQ\"4EK.~Uw UxMKlMM.qypÁBݙ8 H|oqxmu9zOȖ})SӲ 4lfck1Գ+|Qu%\Rr("=ZFVfRݨ+^ ;gXvx&d{Q/ I+d^/JK e-{,M-1fapr'yv~Ə\sVmJiX<+=E%mD )R. { 2rrG̤JTZ҂jV:\Na򉮬\8h)+^\ڈ7P=sGi{ ˇ\4.|rPU}_ .}tb9Ol&"+;+vϷzqu'E͸Ӽ-| 9ʤ4mjEɭ66p=T!y%E=10 ȎЫ(Amk0#7пꕔoOxTHV 6 #>^%8J+N8E۪v(Rج{}TF7Pa|3hҪ[6Dl𸌆~>+nj|8<"!܅^i4*CT2Ge\܈ )qVILӧF+ \?Ü$|j0C;I yCLbLʖcGVB+7%OG}}G= *'N,h4m0XAЧ1[R:Xm1 5=FW{cA>[=D$uR)'C>@wfۃQn6DZxt=i]  F?wn8ʇ/wr+)! $$^X9 g+%yN^9˽pwl>B1 {#%0s1 fj % rva6x. 2 )Yq<, kTR6WlL6%A({&jތuw EXuXLiqLk(D҄5;ziyԻa|j^o8DP{ I{Uǰ*@-39d'5'ܗq q?́WApm{ӤkӐ8aI/GYNepT6MT_ǨljB~N1$m66AMb0(Ja_H`!a ie a,_ Ká&m 1.>,d&8f.ד׾zR .9܅kSѩ\0Yo/2DJ"{w8^JՎ3jLҿ s}NJ,׮ o *"9r3#d.hH\Giu^qlx!Ҧ悉.d0N/)dxokS!'L[M2n؜MZĆ:ÐDvn< `=a^ڼQb+d(r}Ǚb hxyRGLdns\5 F)lV 0 a UUePyHl.v`0ݻ:7yI<- g-ZWWau^|^%BCKOG =;` &˜1S˪l3ΥFIwh"shnup3`Sߌg)Ml0n4u{m&b8`%t2nx7-^xܮB~x,40!|v W`ՅpêIGT /f`D8) o  KٞQ USj%xhUUxɧ,L0 j 3MjL5uרP9hW9o4( ‹!,1xq0Gue~`g87&ezH]יZod:|UBݽ׎ݩJ!3 &!gp͞|^uze6fU'd o߃VnI#ia̬"emx:Uw~yY&3hj~h(R]ҭ9s9ݵ0j3nUNN A|43$Y7C F&ڕceͥ}0;P +^Z8nF?dRFQW6!Έ)C&ҁ,gpF؍,t#ϩD(.DV.gYtM^Ԕ!V]t=2l7Da , 欕_QSdz6*ϏMaajiem5sz}{";aH!u}6˦}9|+\S[6tpB5lDbptVdz1- RiR63ʆ&pKGNr{0-utaWLNId=%ՍƈIE =8xL:UxQXm#J45Q% )29ͿްoQm;=&-iz]Rly<zN T8KS`-E\qcBobĿ vRTi4"~3x( /1-q#A @M_gcBWjmi里Ն Jy\6?d\ݚY3j #,'Y(Ss4'xp_[*cpv.S=1ҚSzO4Qv{8:Oyy\lp2'oW&>ZW IwBtLdwzzؾ2qs.YX@LH܄Nt‡SubIg@!9oS/IY 6m:nXتӪ>0O8;7yZk6Ks؎빭Beq 3CAPGI%F'K%RI 7S!$Jg @fV9C?4՚j\ px,2|!dL ĐNXmSo'V햯 7oE>KAgMDQ3\|mB$8}iOhCw"4,8~1 }A]<͜{>ihtph_o@E1) SGc?H"$LIQ ;"8M~|aB^ި#e O/+ wqqf2ǥ[6{%JXep1qqN? S픐KЁ+m'~ST83->ԫksԞ@&9uD @y I &nֲZݲvϗ dHFM= Ի I@ @q#ZZ  3 QQGkU{HD9i?YR`ب=8 XG2d‘ .$IAF:ekn» MiVMLL:i[DUUD}uk֢)oˤXr42M5wTi(WDPh, )mš$GHQv@ۀ Cj;͎SGfIJ'WOc a[wY\dUsN k=:I17S9P7[Tqv x)p@6q!Cf;1@ƦGNNc %Edy +՜̊l>m~jD20KJ,C>\LSJ'(ʤ1ߤb$keOʽm?5͎<ڞћ]@ff˪,z܎?Bg\# >x߁?"tߨSVueY?s`3?^[7\Hm1֨{P*MMbY/.tѢh!K>v fj4eԐ 1ƋԱ8׭Ƈ BQϻɶjlL8Ï.Eu:vĘV>>NѠElXS¶& QW(VÆzA:ݯ䀼bײ$  Y+ٸY!#~tl w+X񐡴'X ӬdlÞ^aUQJ 'Zr~zWiLQt ֆH='^5:uIm.3eNNn*w[N )ltl_ݞs 4i"V!2mGM{xdBťW,Hik[+RԪwnХ-=V| Oh0n¡pbHNHo0WPKaa-_ݴ)ڤ[˭8($J2(2(>֖Q:݃@FzF^+B9?Cɦ3ᆆEpp]b py_K?V2TlkV#BXǮ;6giZDwCF .q[3bԍBW7{Me#iJE Tif T){FE:j߀C>TTDi`%xKYR ji1ݦGN'#i-T)Rhv: jڄGaiVQFOώsoֱułeQCiQGJ*D"*W>LN^ 5&DIGV)Ԩ^Cb:3WTdHد_TJhgyPY)лB9 t?v|S;u?P,f ,A-nЊDzMLoX.[n `ӷ}2jV8QjvfHp Yv8e,1FV487ݻk)_6r/!\ ƄDm%&RgX5WlG҅е.ZVn#D5N([>$3ERJ8N$'/c22FjpW4CCz>`},*cX'\؋ㅞH-B"u;&`}FYZ﫯Ҳ-),X39lfF% !{ J$j0('e1qaӂ3KY;鷔̔x5:IJEפ"p}asS|ps $p&]WEuכGX愈=Lȝ-V<3d8m, B>B{r.Xr(Z[4+|MYBXY1k;YeqЮWi0>*T[΂ 7t).Z&Rr>T/"iT0Q9 _ ;(3#0$'Z DmצUB(<|} kC^!j]<$< 1S=?J,&Kvq7%~CA3lVهrĚE7Ś–ʍ#XCQjRdR]/ϵkцͿDRz/2C%?f)>L 4/&*Zr*RS[:Pq%YQz%D7eI0Oi3KflUoP?~pDRcE 6x۷ }&d9;F~Sm/蝁mw!3OeZQ5KCt.r|0儋' ,lF7,iaVv_iWY Z%ÿ$}Œ 9 w&5&[Gcoh >zt S<Ͽ]>p8Yh|+iZTQt>Zn ߇gr{,:tH*#^Z2>?ԶuUtR_?#Cx)(ncFx n ZƁzUAPU|eqgڷ+嗭 K <6'f9d::]IDBqs!fۅH?( ȧB z[Fطwx X3eU+25*VY/~1 TVMJj`nChU 7 Ih$`ǀMb&"AF"UÕvFSA@w*=\Lk_ TϲF,_|_{@3)GQְ:yM~p% Y8(OR<XKVy lVUjƛVeՔV^Ui[b oQ'P,ERىxLT~|cÐ;1ܠYlTNX?+@SwBbN\8F ,WعmA !HfK~N$<`eĦʶw2*af˺FHF`-~\= cCDApp15kSȭ3F*,+:P_jeS,K{ G'΍ߦ  F A[At\hxj(2tт˓ E g!B >`-5h5ɔF2G#O܁yT>Z $f;uѕB 7*HqҶ[U7{p.} yC})A.IFH@B4[%l^aŚVժXl֮*ܮC]W "c}6 ON -eA 1o[(&<ǐ#dCv9E8,Z j /ٜ ԫ_ `$f"̬p[,'YDT4YebbAU>'ot|lO4FM8EKwc&>#]76jh-p5ԽY鮿@W `w"Wɏxp/>_D~HoX蒗'C(?O!Wp O|Yh_^lYݪbUcvXjK 18VX$̑Ý[̂jRN*dd@JGAQKɩ}s4CJk̓u kQ%Y" CAlV\92즠ߥ3xZl<޹\VzZeQGˊʅ'S% Mmmg:`J9i.,ۜLW;Nʀ_q6N"Qz{-ƾul奱yކ+w҈sԄU4 (|t\bq5& 9oR{q.G +Sièܧh}lc7xP0D1]pe%vf[^0ݰdzHI%||CլG;'J\RXK}z)NurШ$wIdbXsqqB%kaM0a NJ(kjl#xՈ}5pl-aw;{FϚ 2]pY1cL(ڰHR?rittREKeA])OvSc|Z۠lpʦz &`YOY˙GEK"XAŽ~S x& /L;*==}8\F.&o(čϦ |HFi~ܧPZӿ_E]8}^[xA0o/޻1سi1% &%ʼnC /-=cfr Ӈ6\N a,YL5М6E`@n+hNLkY=7?C_@G y|<^Ãǵ{E~p+nnxƟ!HyVm)~93MD8\[ghTᩉ9ŪӉ藁 E MG]֪F6ev4.LK8cMDV2m%ѕ==8mycJY,E##Ci/ye,y'NM(ߺi0k"v! N_ s2w%L #ʱ1H, A k [{^$>̃+>Db閶NyRwͩF7 $3>593jz7_sblW]& hM8Ɩ(h餰@ S@]lFU%˟>&ʆf{S58k7b3h붺s9>`~%%/p MٗJEh3 f`OƉkhU8yQ:^VTDBP^ dIx],mSC`Q(Gr5K`(lVZn;ͧON,֖jM\X]_|Ybl8s-{kKxu0xIH[\tj2ت xpL8C@jyyuϽh<DžrԖFYXUāžikǂd&Z&ː ls*`u?9QNM]y7;;(dz\H˙E8287{Ǯep{8m1W 2KlSžyo.Q-A[i&?*/,RQM(̥R,*r%]p+)~?TWD:yV#9׮Ud*Ojs߮v+V"OOY'&-njPwdtЙu!7.mc; Lb^N}adWB@خ߮V6kgȌ)`Kݻ0Mb#TSkJ1}5D̂Oy`TT*]*kٖcr:ϟ2 y͆"oo!݅vd0mn&thg C"_$&pUޜ"5I~r9q|td6ٽU6yP׷0t\zk}}1TzJ׼6eSq޴nS*sR4g9^C< G3} io&SP?m4qgvy`~w).=R;Yo[x!c4ڈ2PԢ7@F@ܣ{\/bAC #_t;u>{NJ:hCRelryOM9EU%;/-\,>͉Nz#_Sb{17{?]o5_eQtA V5/[,'K|=q5Pͻ*5|{Y>C8D+'῔n;\W3[I^aUyNJ^]yIMn 4Z%ߓߗ{3dc!BTDXcO]OC*RCݲ;FmDCQJa z,vA Ѿ}¿ֶ)‘K xXH-d<[w=D+X2sO_]4D3^F˦i܎F7^w|cN$rZ6No;_?4aOz9gxpD+#4D\^2 qf#l>Q@mO&B2BAk;{׈b^ox Zch&#xڐ$؜v\Ϗw@+sy/vG#Mu%j}2} e7A+%&{sPk-p!ӂʼn}'k4wm*SXu KϿJ{u+)dHNНO*AB[Q~"x~5[so[|5%D 2m{YlImMCé}{xmUp?3k%@:P $t;hB H oD%ЫDib@&) ֨ 3:0d\\5ƛft:4KͲ\,Th7?C}$'!?|losWSfS=#|!DsTň&}[] Yi4`XYRkѰ͏y~Ma#yߌ_UG$QU~!\ 7Ī߬J7Y!k `uo3|ί?Pw;O#{3y|U.{"rhҕ;@l qtAok2Ph5&b]w"{Wd4()}%ip@׃nXӍUWMqI-&HOuRklU~ XM}CB̑^_5ŘS AAk5g}}쿟Mxc8E*`P z.6v zbx(^M1o8ƄSHFf ?y@CO"RBmBcCBհI8U7XEg/,4m  Cr">pKM 22e|@^A8Ӿ"sdۭu.Za^ZO.9_"$,}d"1dINuڅ|um=v@'wv|Cїiwf}+Ѱ3X%5oV٣yw3ѠO{@1GZ㓿r-ni؁,h*w k?}CL=~_R|{of7W pZȋEz}SPqXc]PNWy/׫*"mGW>Gmwl!dᡌ}>ئY Sz6żv?Wג?A3Dargkng&*iv/[Nl޴4? gt-WCC86F2zeb@|G*)g_]B|zGcEI*rsɛ}#uJ=6K1ρ{}f&voRh^zvxCsᏵTW؁zM;.t8[ғoe܃/Z?h^^̪G?vۚu{זݟ~]oTHUE߽]bX;N)LL^9֙TQvrn_!~PMPdxN};YIft 2'^qr;n2 'bE7%\om H'w-u%~ө \%C.ii_f+;R#1nx'}ks *~nv( yF_9pX,E*in8i1fqͳZvpbWvgrxqSkAݤ{%WS?4=;Ot։kSG(yes`4?w혉?6Na.Q$J݇~ M}/, ӕ %xgW5R12 oa7'GǾ=nOgw:ʇ}zj+~L^2٪ݖ#m/Տ+Pf>f^:SUo[;(H5CO`Iv2g9Bk]fozwKzZ\V1}YW+zKNU~:OUZ~A%1)S}ffX*lq|pmzcq`br-Ór-͗O$=T/zp4Me&>FӵGRC5C 0=<@M1xIL{pph7BC"ֱ 2Ն4`b*! =<ظdj^GT^ϓRxdDSߟ<}$jb"jϱM)Ӊe[+nI-{oko|w3w 3D#Hmbb*yۧ !~o0='^E\~'oRRn|T iVi-GL~pkw_%Sr,lvz7{nnӜP&X7\MT,SbH13}=9/)M|hM&kmeo+9^3TzcJ=$7ZdGk~>S% oX Hr<וM-?e X/dڊXeGx ~JםYͧ9󕱲962lJ>A*3Zg꧋wQ ^Hض4? Z&+9 jNWl[ H~d+=V|s%y{B!mW|:'ėT=b}@AzÔ|/bj{ۮ )s#/Qrܫj09 ?Q ^d:,J 8fa"J@={/ƻo&(7q(Hxw˶O|Z+*tW W~<o_ =w>9]4ڊ׳Du MY?E`d*#ISl4{2$.?V4AspϠfࡺuݙw_#UM7+q'Y%L07Jl8#r*-H6V9XRŇ BkhrL7 b_ttZՐ ~JEB⌙(ZjbAiA,amDZf@ocR=DA}TN  Z\mxxbZǹƦˈjY񖢔k@JW_#ө3;S` $"}Fpkq5 2:g*H|{Y/1.56 hƌnlJais9`=dno^nǤW1[Xǘ_PHx"rxPrO*-&&!WkpW e\nӡH^*^`+icT!E,SZ=aH~j]'U SQjC|bNV.=sPi;z:: p΢iOM<&Hv& T4/JAdž) o tC5Ei`'-zu+uv(q&AԗFvL. IÁb5]ZVbNqؓpw1xzH |mԽ;Z)FVؿWdcn%[9>w+Vў.oB@:nah5-! uQcuP0h(j_ƪ5/,G:KV@{8?5E3E#\ ؍!J|44 |3{ru2_߻x%.bEgSX@]R G&PQz8V}>n7%m$SE_΋ពMiӜp~ďuiAp^n QX\ZQwnNs%JqwsJ!63Xu ĈUubba~Ci[ĺԗJ߼/otS&+ފcђybԷgRKڭ" ){ve[P*8JPTN $T1<왤HaT>%4A{豈6@sǒgJڏ9QòLv(^ɞΘOrr \;h_h%3y)}UΟ[0ns+% [> q#r,y5ÊTd'GpWhV) /$c2t ^3SI}*-^պgpUZ1 a8{F=dķ뭏P'T?U-cy~3q("~mUmS^ KZ#Msj]`g2=4tM+) G~xabMK(61FڼqtEQ:H`"XA ԝ͜BO% aESP܎,X mkJ}Ym#G.?E;'ZEH'cZ Z2\A}w+"5W`m;ͯfR1S6fsל4;\t>i0aM >+̞3לete'xzǮs&6o7hЪ@s?ж>aO ư !O%tE@;tRE՗(LâiagO P;=Di٠bMsMȾ2«?-rݞ*XCOov`(>,N;H$m*FC\:4=) _ryQ,Ěm}|l;HkІ@,N)K^$q?CN)x Ok @GpWI B_AYjOХ2dy?E_Ѭ9Z!to)!ĄMPIĤu6\v^L2ץ6TVJtY?zM0 nTrrxpe/V |z uNnYY*:ơnmDz-FvU:dO)U$V5N箐JT! ig.hlAS"_h ̖1=<uճ\,9*0&;a ]6 &3QgwYk%rҐ~:܌3UΜ~wƅہ2p ~Au8WH :Q O󰪝&U +z f`'K\voT& b# xdҮљyrfc;2#޹]3 +=:}!B)M#.x "FkvKt g>H=?a+[ p3(xQ;)BTnDRYX#qu0YD*Řk9.WM>dqo!Imߤ/i\tǍ!d`f(upG:WH=]iBp6䩱ͣa`se&|_X6`#"XW'>be*2sί99ŽRdǑNTdg0j>B4ʙR i%:%dx^7u}>lO5}/y,"fʁXhrp~ =ŝb΄>yh:%z1HZ8UYB#B U\T,X-gl,~sڙ|:Z}`.3Ϯ p@pْ`}Dy=RN1@* ӑ~RpFmNؘZPud35Iڬ> S1:Y ŒJfr9+- bg*d=y=) iPLJ,ei͵h0,r=ϷbjGu )3FbmVH4K}9Op1HRBr5#[U6$V'ĨN H`Djb}D)RP^lfC3!ϫv팚H, %m")e`s*":ˎ~va6ǰ ӬSH;AJOw۔2Jf܂6ZHa; nU汧.$-x\ݸ(EkVB CiCa2̎{y'tMp 8`{F6]Bׇٕl) u]BkQ:6(8K@5W cW#}?9X`1% " R+#X5XzRc!*\T,LʙG75g[pHîRWR/3#]Y( T<ڻ/)cIs⩔X.,$NGmFӪ% }NzNPv}Q|? icӉ[0S[f&VCBUmzCݻ36ιeyEs:G.'yL)!"=% >oX/oo4S* k JhB| =z}F9%!dNIlGE&0y%1Uqt2}NsF4j0ܸn K³Pw"JN!\p.yt?Xk2踊Jb&)~ +v;3m9Y)gR5x U17AD8EUp[ix#.4T!QX`靘eZQlO{4d7e茬m}ֶB<23!l^B) + n){{]pĂ(^B)&Cc3,şF#9hS~tTgЍsdݺ.p4V?-l ?:w%uTɱ6AN4_΅^QG2nH6aas9Ժ?vg%W_|c3nE|G hB,Dci_{{xt 9ѿjl #TFµ 0/Z:9Du*ϱW%|.賾}ly)́ Qǧ )[OQk~`/ Uׇ4D E5w=ZhP<þ* Gq $z}R\HuXZd{h8}>b)f:I $ gRIoQL>9ѳn+U:!d^{j ӏrQȥANARv  |wH (:sjR8wӕ9aGeaQ\"y.տ z.TiK#=O-;GM'-i! lS)i窃Ž'Gz}!~?@aTTJDMz;\)PT|G>:&6R4FM<z1:0 Rʱ]c <{q`d=mդ[)Mpx[(Y&sHq>Tqgo%2c0G 0:Y>ľ5-a%*p:% -v7@qϨ,FX-W-6ӗt0kYގ.Sk_hθp@]׍.şa%{]˓UDoaЈueԯB·fwf@d}04@ BАq[!ayn;J<z΋=hR%<v 43*V1@Vk⻱? +`I0&B<;&)'˃Nyi-@S5 {*J7Je%`5 cs[@Ktߏ+5׽{E?g;Dq") $S/I%J#|eGM{Zoz7\0MRgP\ѷR,lΣ޶1e謷tۛ|aOT؊c8OwZƭ:]8QCW^;Am J*5KHz3iKݴ78s={w(lClV JRe}N0Ųb1DECo3=&M=9O]ˀtR[<9W~GO ( (! ~!,עԜc!(5ݫZ|O%n--۽},NW"Hy-p bQy^*;^5ӶΑoBg7Ҳ=gal+˧ Ȫef j B; 2i01ARɏw?*Қc]wEIy8ۮ, r;EN+êH(pl`偒%\"ZQKb{?]˦j (']SХQ1x4aqz d-/+=hZՃ9dStG\:0^o v9˛T G#ɘpSi"ӣP܏]ŭƜ|8P|:S&AO=yqc)_ŋ=i7FDۡrU-xD9nUf @8PCԱd^,AÍ\Ks(}D$jBgUFeJ<'Ow+dEXq/GsW=M'v__ O)fh#CC_&]T#5W_W@ߡhxyAZAv/z =ԸuJr!:UfoGAZͧ=4ȣA3o2/;ԥ!+Ԗm / `[ :+Qb9;)@O{9_j1*=SI$G[{6?{q~ŒǏqUQqEӼ%U#cFm.z6m#:p/r{1GU_#,{:(KŌZ[[u0́HGViTZhx72Í>A؅n;DwpGԩ{zPrJEe@ }'-X9_mWc_͕]O\[i`%^o~ Ƣ:j{a2&_~ Y낔XI0V)Zr`W} -pүteysRwn-{a˩8H),; kxU@3;ԆꭕK7x7iW+7)R}/Chޠgc1smL(ɍ-KUoji25U>0]`q5?r QңR)ѩR; FW mOsě|SIҔ70Q9ragKJĄf==iVg2)9.bC^W'C5cj9Y1nYF FPP<8-Nƴ1GxVouGoRd]WI(}Ebu4|8ί. G2M} U$U)(YXi2y*%~u^74F-\jlk*+-v ^&z jN8gA׃{+8e:q-¸g387"]3jEohVㅫƴM4RSjٷSO\DiU{ O{JUz\g㥢\UE2o^å6 ]a 8 !-SZS %;vCL,C޴&{V;>KG ( ^>U. x4j/5afY ؕq4*Ȩ+Ks Ѥy W|4·2: T!˛aJvP2}k$Z}|N?#o:Պoyi'_^H?Zdu>j&2wPqS۳आcU$aS|P.rlrϨG&{\.0eoFcػh:B\d*1L;ETl-Cy{g5.\ZIH:bU/1tHĥªTu:kv>J1@iNk{f'U,=5sX]_tT q$ . L،9˯Dh`Dp`)iA-1n>[LWvZJ**LmRw[qq) hjӚo{1ڜk'<~š*WO_#Dp93-OHL *xY65).z0#G['5p.I O=-]RZ<)2+,5/y"VTŪ!rC4?[(NRNim'yC^Rvf hkxur*; E,vOO}KoNN**N}pFK͂igT{+UKYbOϵn at^le\{s]W$s!o\(٪[>.a%9#;jz3<Bx_ҒP6D{Ɣ>M\ͫt6y >c8?+L.a:YvF$#⍊tSF6?(Rua !&n VB;h[lÝlNmU1S ꛡ@|QinUw+C1+HbHu@, b :DY*og oMV]0BJobPUP?!hYS[KU KqٳNnlQtT9CGN7X\(wڎ o4x{hKwOlۀ/- Ak!tި!v$/)Ďjl. Tz44,@2(*P jUϰ^N-4(hנHϮ#2-sJضU=f1HZRX ;:ڮ s1h Pba5k#STuZrM 6;Z0o{AUGY߂Q Ex=}q*87O'\{c..A%#K3A?̑GeWt9x:〾Ŏ\Eix[0bQPRuzE>mD+`GJ|)>٘]o'M='Э0t厁ˢ=& U{eGdAN¾DD0wcԤD|Pw3JqϠbnvCR? pGszYMwҜL𖴌23A &̀!$l 3"Hs=2n&oLJZL,%]̙ORE>1Ez=gf]'\Pn5ֲt-o\0r=_o7<2x s@W4?k.=IJ˱Gb^Nۏ8M| сeCv/&<볖;#R}]*]iRJzFb3٧w:0ߓV訸, qIUdq%q -X$Q?].{9V}'Q Қˇ \\1 J.B}މd*_yҒ+8KkxqIW^5%@me[u i_6gp]虴^ J.l#Dj/#42Bp o^eK )Xbb@GƗ?kώN& A:bjae>>xQb=>KX;lSx%y]_~8w+fKT#͟:BY9<'G$.lA3"mZ<1Uӆ yW(]$_i6͜ .z`/~; jj|{ʝaU~y G*J 9g0ǯEXEqu:!+0wPh+¤UCyO8{a{8_=nFꚯ]sx4hr#9-CovDָ, =EHO;>?f(B  OvZ9_3*iu?+r-'ZĐ "/O9誷'mZ]ъH2kQM՘%mE7.ojsr{ ""|&=jDZ@Ј^ al Jq`Yydžg1Ih0X: "EE%}=mAZȬGj .UP}W+4T҇N~*'.⊢5~e)@]r!&NMD>,'rmmZϫ['Q])ԿJd| K[' ;nlg萓óEcu$཈+*%`R-Ib+Qk2"EkJ#T%FSvya9V71iy6RN۫@xs G;d (njB e RZDKŖ`hu)b `WՐbI(:#D~s9Y:6~ »CLŸp,:H=lP:x =[!^Dh╍/ߗ+,x}g^$Kw엱m~Ց^ֈ7GM9ЛgDo )@Yr^ys77 K[ӭ_Fn8V,[xQx5 R+6>*@@OF/3?s-9z c4I>gK MY#[nXгH}m rK9?(x9P@I(ѧDJOeh Zt߳1RP.kk]{$"J0x1 %ɷGF:"P!{40Bɦd\璻%TJR"1J"6s)JTn>=-]Rny??c:u!J׷2q} 5ЊTQJ>?#ݷ \Zs{1 fԦ*ٔ#&?|xdR2qMB㏯ 8Y:CgJjL@eQ{ p@J³n2u6O~*YN OѲ|x@'W4v>!;5()@|U!6)3[sY0=9 :rAKCatɂ&C3״TL!,GmZ[@\JVFTG#,FK{ ьka'^ScZSX#V9eྐO=^0bw8:9i"o BN6l%{8}P2|>Uy nF>a].|qd4˄=\] e,pKv#l[Nj)@=u-IhBgxkQ3lc4:9W"Q܆}t zݢ  [(b~+8Ƶ۹qESuӑrD=u;_x 8'+:/&4\FU*yjEtMcC5fK\xZf`SF9 PYY{ rH3}-ii·I6[aVH`Ѿ>xD?A]ĥrFƠ{m1!GXݽf$p3$ כjöR8 o(LT?~n7*. {MSUb|3_=&F("7QQ 2C|7`9*),Cxe*/ Iz -Y/!{"*[_ɞ̃>yx-pb,k8d.{=&}eoqt+ Sc ,"ڐQbsQH@fMfmqR J=88wy{`n2q!$+dJr`%{qOGD$f31jbI8roz:PB~'^ڹzi*eN[F9Ȅ[abI!׈K5]ۅLgP{@APw72H<}-!Y3I`V,}8E:ːFxoLv_T=ʻPjBSa1kxHa2jWTA$ LŐTo:(%n{<@8:OHp sU3-RP*ʋNN[ @" ^p"),>Q? V,9ntxX؍@[&H(mLi )牖B~$E<2aEaչJ 3/Q36ٿ tgmȶ^6QU' 1V} 3I#GM(!2/8JaeƢG̓]чQ˴w> /I2tDѯ>;¾'3 $=܇aua`aRN8߉n K=ÿ lЙ7-T=TVF!2m4>lSƨn %kҐd7:2tAn\ c qEk_bx!_.Vnxn.DLЉX7"n)8 !$Ptm+DfW(oab= EƎS`O6.^? t¤+ xFy4Ct>Y3Z0!CO4uYWؒ5=gh -h+~v  o[hȃ)vTU_)h k#qs1_ipdD筇?6Yc7 HMz4jZF}zSAP’2PsFmzrjνm" G- DCW'^R u= gV f%ٽp Z1p~!-`n%.J<1LDsEdv @ݺ0G fe~L@qeX\-Q,.+F#v :p) 9rtT.#ӨF 3˂%=#BCVo9H=hLLҠa%s@Őؓ1-7. YKA&K~mNk:lh{J[\}nJL߬60JIw2s!K&ؓvH։Cp"a䒥3l % V W1_y a%6Ǐ,8&(72h0)#yp4+S Z& L|N iAG bSJq !v53䤯'ʹV"">)Ek%@ll&ƚ߇4t[nM[vɻl5w{)+׆0#׼,#G@L^[kd= Ge{V~0lobRRK945y:GjsWRwىܩ*Isq&8scp҂eha}H0}X!\;O9K&ҸrpٟQʞna> c g8!4Mk`u⥕)vf&ر4oCdu/zOෑSV.J¦>Fy /"WgmZߖϺKZr0} v:7?{`tRI,&<)\=%djiY,s$> y:GgB< Eɘ8? y@'L\"*>yA\ÁMpfyvh婠/_fG|"#?0ldYWJy}L?n޲Iɻ}ز) lOzѾ![<$6`V1$ $p0,׷З4#1#pc04"A<.?<-g:_EXkrD׸ ۔pm SGMS2}SKpTxbj6^p;ETsᣳ􎾑NӠASՄ, V,}m:y-(F[C Ъr;{bơD[ws-9f]Z|">Qd`&bsbhd>Iq;T.G%-4D2Ͼrq9X+sޱ}W<=)׻[s,gC$"BI hGXfؽv$ 7Tއdc!5^ZQ(fwk'F]Pź0_` Bi#SN3Ǩ#gH¿,dHq!yGx/lښnW]f>#ދB 7QĘy ;8** d-~G5@S* թ}LG}aDlL",qy`F1>aoǎN9`w,"v AJ7LTޤ"(]ĭ`R^cEeOF2Uv,R2RIt7Woynmf#.C)UWHT bis0QQԾM Z50*pK7fTIC]A67==SO㈍M)a>6K mٴ {4UH(@>Ƿ7t&"Q}2c|:UEJ#Ġh RKVq/GuU_:.zUMzpgރk uіU2Bl8a} DibWBZ5_ge$s/An*Y!WJp@d؏\(핆d4ɒ08Xqah}#31YnokeOVg;@>s*j]9JIvn$ msp~ފ+> "҉UzuĤHlcZYGXBF64 ȅDp7Y*d`svv+Fw'V ˙(љՐ]\GzB0'4 lӶEe Xbm[FN Yqf&6*EX ){B8AjOoC+B08z5VmD4蕝ݩqIsN^ kNw#04R͢X4j=ܺS>j }t-a,8GTH:b f{\%AnQ\H/!X A7T>zµQ#˻iT~VKCGg/5V/*.kCP I" vYVS?eT6Q 2򤙖vdKbjU F6Y0tx|Bke)ҡ pkD>B|?HNy󅐾R"ˋ,\p}[ - D<%0o/g/Y3>QO`\`ĿHMµ$& -j_:IMgfp= G}d6rUU&s`pԒAъh=趌4bC֬"W9%*}6F!P 'ޠkُDINM:񘷶LaY|*Ǡ;)coHTaK z?X>W0m '-灡L40" 1CP+F֞C[ݗ?_< ZT`ED `+?RSO",._.}z5 ٙ XK{`ߺ_v >vti;|]ȦHש]h(<`݅i:mA9>pi͋zz'8&x?1FZOٙ;VTxbj'v%fU3 j8l3TT zЬa`i|>ڪD1"P=lLwuk7)72AY/،j%:yWtd=$8OLH^du L֜=ukMX*+sq0ۛ*Ÿb>9-rK>"?CXIj ! [oޤ炓@k٢Mo<ފpՂ=>6yw\6A p{-uqI5T,ʟA,D==qCJe:!}֮3rq!㊱C5@v.YXwA;2jp]swA\+G[I]Sgs0,J턳 =Gx_O >9Ohm,#%2z``ؘCTd*#\/E%V>=g>7PzɾrΓ{m*#7`ȻQS;v+mh9);Y˕߰>K6RbR \D_o]9rT7|4HrRǽV4ńVހ3b?0l07Ky`"[v&Z쭋_ X:n->|HUހ6,ui-sw@z(ճB,Nj9VHOA&'h,*j'[cr*6~#Ǧ_@U:鿠CH( X(Nk!HbŬc$Ҋ_q@_>ԃQFamc/ljYD׭ )~:1LX ʫC1tjg~ )F/ is,?2@J3/e:zΙb!9H a5J~%w@J@ ĹܪQ;AKWh"5`ud;)=QƇ}jUž`qKPU&z4MxOl<YW2Y\7lK6"19f"fJeقv@`;tJF/?N}1"K?_i!QFm+ZڻR+4xG0s <xrVPGA,Nl}α?uzf6F톣*4ōW V8!8$tSJ%KM-נ!Ƽm\ڻfLAof͵U"'@{;b)!%KEN|*DGa ^E88B~#I!,@[!6UOX 18;L]`b nrQ3ܧ~+[M@S 6 h10DZM>z]XMM+Ȋ\lzZ 82_ ޝ:GQ$BdcE[3Nx$.M݆:|fbEM|wL[:,}{h(q䍅~iq`h + +A9 \W^_} dZN5Nvݚ 2iX)LbxQT|3k؉R>533Q F>?aS;SNDn*%"FF>|!.v)ḍ4ӫ ~' w VD8埍ZHW\$$N#\ .`3D3gd1!>yf+2^Ad8;نޙ!y/tԜe"XqnлLW>\Y`Oiyo>koK4 uVLK/5Cx0@|P  |GV7}堒 xPuƆ`{:/#^>_l=dwXT⋰ٻ%f>L}& & f`٪UdP=Dz$toS/wsk2WktwB>swm1НST?+^]s'&!; cARq 4kU 6[?cwҗ?볥(lr0Z< KȂ2DlH~C֌hh|!2+}i^$3|k}kv/>܏с==7M;fX)_~}ݤ#[(O/#ݥָ$F1@Gؼa!]?ĞTZoi#vVꖷm}edօO+V~IBa´%f mK$lr88WSbP~oсQj3ڍNGa-wz5S=j)ԵsiA>GP_kW=2}'ߖb7Gn jkKf'JҐR@4 γqdsz%VTG"^0Ѥtq/4*\V2 9`v)n7A.Xx?U9ʍ\;q F@egbķPJT2Ou` \CW LE!B_b+ثΧ/1F52R/j Ru,?[hq \Qf^WY=?Q]$FGtGEH"/f:pY%׭@-XڴBİϗMzDՆ  3qSqV9`d,vt R2zR5ML"!Yă'R*47ܞ.W\IL;\~,FmzGMÄ,M""{>>C.PW*zfd#NDL>DY"$uiOZ10'lֶ:aznޙ-Po8()%ǯ1BbA4l|[&J'dgA} 2Y#s0A\ d{t(=ݏ*s X.p<*:Bv;P(8-nRx:j7&[GktwG]vjQ }݃?Xtt]},0qEcUc #E#"*3ᝰ63Z?>J\{[ ~ #fIkyЫMV!3#E_ʉrGĎ '΀2DEo˜ܜLy#qϙb͏ضMMmqNt5??օ"uï>=\;UW:}qW D\+'uN0.h -obL?R-_e -؇gHՠyUDC(6IJy~z9j1? ypʽ1 Q{Bwm, gX͝tL}x`jO:h,BqNpw?_"Axqg"ϝ!Xps^f2CNm@thTSߩC#>֞1<}^"lB$3$)w-q=p]- R,1m|XHbڕŊ6c=ܷ"fuSbr~p߿ULAq2{5.>\)#^B X=ᇡ눗o|uހ՞é񀖅KΈ=FOru [.!?ND4))5ZumOFM6E2;vJVlqkl<_=F\9ILn\ix|;yj_xrtg.:&"ʦSUw$fC|2ѪCЁYûaG0?ɯ .2im .mB ]t~J [zyj%YiV[Z i,?CuΦuM7zΜ"-sh0R0jJbUtjPlᶑAXŬ$/-ɯiQb >7x4q \žf]ssIԕ[E{|syp~OoGٍ 2TMjէE[Tڜ0JՅ}<{׺~R}PFR|+Hz7YlF{ÄOT(7+ QW'!Jhy HfTPMB=]_Ղh)qs{zdΝHK 1Y X(LN_Z&Jr\= 0Ɠ9ND.XFt&i )I&`w'Lyr IzEŶ8qj:O`C#c`5kT9QC[9Ryɴ6X5%o`oX" G̮mmQO1 ZΟlc>%g\+N~j@Mտx@z ulq@dߵ7 t&Sa Dy<.M_-ބ=>=(6jR-3ތ4)>^A~O"0*띦'Cr>O*>WTRD9 j9ᱮLft1_2Sr?Ą^mh cKЙ"k}Zb,>gU6x ۱#62[!Ł tֿʄ1DU2H+k#Wy}Iڍ~}|w^˿#w^imM|CyVd:g02(ؤ۴,_|#ͮ$ʁW&˦A.#LmT-nM3þ7R!p^j[=ׯ<~JA/ hoV'[KWS+!kŅK& j9(J"L}y/wiˑ/yuzgWa9)"yx3l.őAr6qZ_G_~y)Г :8OQ =1Ap+`?^ Ӄީٝ<`YhMu ^,V1+*h="W>P͜# Q-g2Qam F7%_"pNigRDNea{~Y$8dN`jݝy`r0x%U-y%e3` ee; c]q"(F`RK>q2oQn gA!5еOW8K96< |֥#lvXɡ\N9Q*/sJlhfOj=M L?󡮩1>xzSן:ތ6gw ؊4¦=MqQFϪ_IWv9n<;xa8S{+hC$U SkV}1/)XY#@բ߳Ŋսw?ܯ`ķG%sjC'.=\ o zP/!OoT۝0ŋE%0Q%o@vJ?Ƿq++fĭNyxx 6Y|O撣}鎊X]]]`]M&^Uw;d-q!WlՔ7z7Ag\P2SON`q巽ݟ`'QcQfyӎMö9$RG7\Ydw>T!1\|V Q+k&RAH7 /k[b@~զf2Y.wMUkpw"KImk~wDv.g؉XCBǂ5gC]eɳYic3",!Fu~`!!l1 a?$$%@?=S߶4ϜwgƳ ׾cs£~Ro__{*y{} Z^e385F[,,U)o=LN}v;ߧBkv[ڊhi?ߖUCD3##2jE7&X t#iag|onS`-t/:`W@0OhrL&HUH2d pjcK&+^H%eƙlL>B5=jEg1`q}Xfd 7 o=`ס'zA<-nBغ!>eԾw(c+<}è "Y\އGC7M/ D?d+$4AR_Zm|kP^fR.*#/?-?C م@}Nd5eoCG|֢w'Jlf4ߪ`Eه' QO$ee) ﮽c5-%A*,Na `{[ʨvusK(Z}5,lvL9ppx,>W\0=:u7 ôÞtHYiSktd ~(=뢷j{kw5N#/2xHaGJ=C~Ls@-Q6QIi?WDu. Vo8>9ni6Csz_Wu˰{eeufhq$Jwpt.}_bÇ{{[;~TN8_ YYjk4|V/4Q!@ Lf|MrN,xɟd8<] Ƨ s]f@F?.(e)t"9o-vH|ԪHUk]0kG_{?q79 k27$k_ψuGXQN#ilX?t=͡)$?#6l&Pgi#3;ݱ,CH%u[BДu(-B!K`=J$30Sٲ}9sx?߯|{> `(Q<q 80R ,ua㝔[ ?Yۻbj.mY?׸t}{xыE7^~(ٲƙ԰;]0uzǂRAK9?\U#w}R,L!hj. rmmV ŦWM7)(+PobSX@$ ԚJD 3N D' x≝5f cF22wv-L' jMVmƙN a8}AHeӵs\H͋JBC#JG:0?><>νX45q吷5+caFXOmr~ˑLR{v!z!sqKD&nZJ>UPȜ y{WX@R/`'WQ6%Ym6=qѹQ^*XA1KH7=fF}Gi;PK_P%$&EN,]􈍏5ԄH^u)%*O s sBQqL 2YE)DL6Gc|ODN4K ng8 IR!K]0$mS#a] ʖ~2tHj<J}R>i>uṥs /Ӽ0̅yH⾏?TyS"7?{)} M2 ݭJ*fT2ؔʩm1,g3 bQGaA\7t-X{kGmUwuwV!N xGF`@S6얀l.qY;&^EjR|&|AFF2TU%$H@S:12&O1j`khL DULea?þDg /V Sc^M&[wqJnRt|ڒGcr'@ECM?QXbcY2$dLܥ1Kgړ/}v_\]yڗ=3qx_j)zQckJ]8yԳ?e{qm((N{l]ynͷbL(Mett$: $#?rBG8ޫ5"Gά ɽ|J d=ɦKCl?LcR$Y<ğ4 xn.me+1-YW$ѹ}ʺѫ_"ڦƆ6;@ E' X5 `prBƓG5B7d4/ `Q}0n-FW% B1]?:pbM0)Yd}Ψ) =XݡNEHw?:R8iyI O颛3wJvStsw-e38#ww 6;$èHgykz(ETtC5T}IT''%Z'λ4o;ߔ8nyԼ'dǕavIvc#.ꃤ]N!ݣ32CjQxv3bl#RXӉjƿb "($[IXВO߸{A>OoLX7x'N6<g(AT$fAL$&w4xuBʌc}S GD`)sǽ49%B8XL"AMǁQզT]}mR" ]%m+ ;QGHG,GjͷT]5s{Mh^x}q16}'5L#(\Yv Ss;* [N >׹C7L˷u*Se /.ļ\wM2͟{͇&4S7Vn +\cܮfٗ` opFv#`膦:laYe{Z?dM)O vxT#%N"g&=Sf(L53 I2;bj } FN O-_ie=Yȼs:Y 6Wo#šZPċnvY'`<(t^4dPWjibexqy[ҭm-6} /4gl.=}'~k 13@4p=#Br֣&xIҲEYSձW.󐃻o9a[-q-<&  (vY;idhxCÈ .U(@០v &M1o,oe@ʩĒيŔրq~cݏ\z$٪%;H2b E!yK lda_(WN"—]wL\҃g5m@wnluxS9]3G?-]q *]_ϭZ>+bt7\&߫&l#謁5IGL|5f9r9A~o$$a #CbF@:{K% -w'JyT0Wm +M2sb}~LH0ܣS1krOXfP̣]#a.8؂sn]A_*K} ym#Y=yQ66N탔&3@Ph rߠݛDzI;e7wO$g5ڗ3*˓WhbA!+D3+7gί>Onփaep_(W}32@enSǗ?*[f9݅ ǹNIllԩwvE9e%GIWϔW+ZvGfN[o04 a+RvAlD{7:[j)`|uK?`,` Vj3U.. { BgBBKB6\Z@yB'bXpaDMM4;qtD(@c2 ۉX>V*15U{FKgġhKLK)E,(h<)B5(m ۽faã+IzT&U=H!/d 4ǰvv0bgzˏgϏܡh2'ܿ׉Y6@8UgΈYXKJ׆(Q^1I+5g=% ~:SDv3=Di !ef'qYp =Ֆ4WQțƌ$PN)ºG[39tJQ}|@kۓCr5bQE0 <Ax{ڀki'wƾ s A&CX ֯DPynT+ ] iEz ls?&h|Es^V՟'DRTH}D//{y s/Tw!Ә?Uuuv Hx4$'Pn"3G[q]%ID?! y:/;"*Y +kn%j"aۢeMڿ̈́|.ChE{"9.;8Wl+n(M'iRb~=l>E }64)4#hm'=8#6]rzZyVԹ x{z[cLhe/rKl߇]ؑ=Et_3Åyni>vqۻz5~G,#ڀ1PFߩ/{V U?{p֦UCc.6S8[x9E!W3i._n t%* {KD\& ϥzJӶGp.*%ؤ}b$,Q|zBC%Y߷F ě|6X+޸\idZa04U-D7*cڒIivn @U jA.\w9W{q'k1vwd01%~w4䞳{~0> .we& El?YI&/$O~ܟ L$!yI^b)}*~vP^b2%ZBػS.!nfuJ2@FNj}gG5NZ|[VJ''E;6$!}|$ "ZZQϭMܷ yL{$\b ZMQY|KA[Hr_[;d_}SCjuF9W@S>1 (p=yc5;׎MՏW܈5{#^XqцNVvSLM؆]JjwR3p*;6bi5/L8yAVw/䬏>P_4t [,\wç{$COs_Ez񺑚\>lKOi^к JaOah( }-;9=33Op`# uܯWƦ+ױ ]>n4jlЧKQc3F5Wgvvy4xߜ2JI3c:]@0rSSL,c-t#nD1\YenljǴC2\%., 6-/o}d8NhkvfLzwɛ%23rݗg]Doig̻x/іgLXK^ &TwNLA*o[@ OW܁v}׼6_c?X3+4mõZ-hJ'p o*茒=$'徶\nqUCR^鹀JΝwT b$o c+^%k n}w][wV9lInO 'kdL!OpY\넇E O ϔ|RB?ʍln~y[b ﻏdGQ̐YOӄK_N_g2;M J^L[T~Ů@/6x~mz6^mQӗxth3 {yǤ\zcEz0cf&9Va8'7?fg7]8io`c/d+ܓaviq C#0yavn}LkQpJdv /N!$0B9?J=.[[uN.D#v'ǟ QMMG >3V^$ɽnh;bAdcƧwKjC1db^VxcN_yw'^Ue綅x=Ԧ7>0{Ꙅ » B)Sy37P&0 UfoEBM,?`xfm &<_,M@./b?V5%7IhtfGe\Yzol*]>>EMjX닝S#G+j}Adܘ= $<gpRU!go$˨:qYd P̳R|{9#zſa*CR9vmSpRѵ nڤPXC-vwjN&|6D \67k.{R.]r+?a ;m7/ 5Q`[Izĩr.AfJ.bT[8Z"HBgOhbxVF%5mt6G% M/i{Lhd`9(-kKyEH%Jaf`Qqr&.&uJdW$r#ZETgUwC5*"FuZoO^H$I WDh2KGKQU/c|;ixFh`@?;}|yc*d-)LM8Jjp$ue> 9(Qq3S^ovCӃ-IIԗ}U™\{T{ZzaHyS._ Z2?`oKikV잏ڀA٨֦F)}I B{†)A3s`<8qɷDތ8hƋoCb3g,ɻ/')7]7V6/0šXlo'Mn>ʶϝ8%.vD ]>p:9  \T_ XNCt@lqd0pt;2z,=|[L0:WYZ-MugƬ}I~87.'Dg*yz<$= 9Ѭ";K $9y…8^EeP٣iɅ7ě:yI9 U prI>ʫa>҇?/q/laM'Z\U<;#FE9g=5|*.şU@ݭfhB|)aͭPUfpю%YZ/I<m#MJ{$w~y9~ݗؓ _mgS{:$ m9 {\>Vjb_tgu'׽:;J˓1RS{;!o0ysu]̷M1ߤ%ٻo}Š>sStEqaBl./zzZ 1>.%+I>`\֓nI2)?}WdXgI;v JL|8Ŕ%0~m&ؾM,V)JN B/Np ɰ/FF F+3cVt}W ?J 0?#5@;3ӑw; [8l"5tiW޸ 9쁮okB|<2 ѝ:%lEIzi$  oXmnȒr"ʄ*a*ؽ\xstw!nvOT/G{eܡkS{v54 gp^rR"I "}R#.90rUrnmZ0u(]J~I :Ƕ=35ѓ_Z2 ^646.[5zӫEwl '`=5(O7:bxZc"yadNm>6n?E_CjM!oآr:`|/ v<'^, SGm _JGf>R?F֬;W1R%r1s*2+J=j免I{,E<*$h93yDg|Ĥr wϼT(*3E0j&%[íR=̕жڇː7'uC;lm tcN2NKB L*Rm_{E<4eۀCP-z ~@ڦ9r}6]c~9)aqfёCC͖#5Tml11=qО6oGBm`;?tbnh󒳦΃)zB׍Dz׮\Ka^S*rIB$}~߻]~ ́*T'>&*owH݀>QCsǀo~BMmagVu( P^εYsn %Ě%fPd j|.d/x> 8itk"6EšrXᶡ\˫Q v2Jk$`D,o?/L6eXX`zPHQ l+>x!P-0Kqd"5PgNkĖx R8gwf~%uH+П?^"Rȣ}a)wwK|.GB_g~K7DҜ8(R[ȼM}}ǘg\LՒWC=xx2š#nTJ,"r Όjk+yrzsBuqYESEb2=9GNvhPwxW ԍB19+=\QLbjgvjh6`j:u_^&ZGK#AJm ֤c `lL$-O÷oPϡ{hZrկ&[G5{~h;Yϡ2ntutG=yy7ٳB\.֡h 'Jس8o,7.4ZAs32?ϔ󫜽ЎB1{ɇU4G%Q5O\dX >evY@fa0Teoߩ g"2;u6i(#lХ(=#1ەԃ%*\A/\Rp,NBK>5RYP>h$#mͣ4VQ.F$)EkiA9Z;|;)`B %ppӺ~b$aMGnALe<=pzho||O8 e~>;'Y)}Zkpc 1ߊ®#)`s e 葆^vZl0qϏ`ȟI1pJ bw*rt1OI`%6ru$b_"_տl@W S|JD c9Ebax4y:I߮FX4GvEycovb CdU&/,78l}pVQ!|6VN.۰;1l/(a끶lP(5v6 ¡`j"M-lM&cu%Byc^E)IzQΥ]-IACugu'<5++bGsZ Љ \7eE]XJ;g*uo{I|CvmÕSͥU%.W>W-H(BLq;kJz8^mmG.%"\\1P~!*me)֙Gf#E'>b% 1"/W:&9v.ZONʹZZ5НH7~ w6xK=+B .5׾#"e:_"mR W[E@cSMHN5vd<-5?GoMҢt +X$^$[GET%EU6ee": O(pwMgi^ ^Illy_SI/tjT<;Ǣ<J/hqN؟;]Q_8o{Nz-i1^v qգ/#P?)r Zbn_:N! v%8@sLt`p.k < n, 4j6!pݵŇa1s&骪w0΢0Oȣ֫EJ~Zma|F@YzJ1*NI"d&inL?d^-J[-NpWuz`  2GhC_lzH`GEC m(^S}p]A҈Q lKC׶;v`鉣k+ԋd';jcq7C* K9X(8a~ t8tFzpRޥĺq o"镰nnaˇ wVZ'S8ΒݓtPz3.g)Y0ܛ,.3A#)dZ>Ƹu'{H]"K&S<|n^Yǰ'wlC- qrV?qXLJ,K>\YNSFft >lB%ȿLޏy~3>6_y!n{*bh]VPf3^:Ȭ:Md j^EN|] Ix]IFӴ witfeNk\&+G+ h`᠃L5$|0 )Y B>xG;R]rRX@n5g>7qAJYqF|9Tܣp5ڭlM񌭱MNsys҆ 9EQ*JeI"!I1IrJNI9ms7u/~~<߯Vz @hsͩw{<8?(}~{^qv"O% `y+fxk( :O=M6I 6قs[4'Rxzxcow@B$'=n#v'܏Lz4B)?w}2HG 뭥)( Ҳ'x2W2gto9׳wS4?`#N Cϰ8V`)ލ!ŐkI ϞɑZ^UQȨ= qxq]ՃYg:Y:CU*B0ڟ%T*; jPUS0$UV/<2~֘e^5,odJZ:[+ۄ{w%A@)O^Ƞr`M#)bO@ ^ ~ Օ; "(-# 6?lT)n~wBu/ޮ~߮ ͿxFCYBK&2Dq F`>?ZO1kKO hzg()C}'۲&Ѓ_nא`İg;ݭQ*:Dd(na?Ek~o$$ \ǟ ܃Wh-rc\[B6l[BMyTW= UccZSQYɀ!tʒLTI$~Vթ4¸މc2Z^X3';w Q~_P>=#5kIZY5oVh"7WUq $\; W<}Y\9*)SALGı䣑ܵd|TXӚ o72_I=֛uoq:ZZjKg=`o# f*!io'>Ik_77:"ȤY(ρly.Au P'dO^[:OwYi8P4۽6WufW@RU+muN]KWaLMKw!&ӊFvy\tAckr3Ao6&8T8g9"?qrW[G'e8'C Gah+VuPA-6zJ쳫܌NY ]iK!NID¬ бSi*owC}9CV! k G}W0eWSng ṸG@Z1-\bBSQ m"dKoG5ګT!Bo#'KdyhLWyU-iȴ]g[EΝ 3!_=v΃fٹ-j]L2tVsE1?n~zBk8lOlCȤ.:Zi^3-AL~V˷ױ?;eY EȃG3ςaqB?Mo[+1I$,#sH{=NL T@oA$9eVb{țIz^~YG(UE{ ռ9ƣeO'vƍlN;WJ=v M$FDQiBZOf౅ڐuor%ޛ{}7;דfD 4^ Ჿ=_|K_V4GSߒyknlwwe>?xa78!X=o0aĩEzQu 򿚖UE sk=-Űw)B77'w5f&ךk&lArݢ_Z^MZx|4- }v alZmh |wƄŗ`+`g4 e**lX7ز8 ">s!{ظk(Vn@9| .:޷AIˑ PjPV"MOhG i P:FSk!BVb6ǰ5kPb,?8 ;|nMY򥖋f9N=rdr)>uIg=H@"]klu^PBq(X@[:8E=QRocGEAYg 6nEI^- {MخGX3 ܩ+Л.1d~~ګ@T5{e<>vKfx`# Nv$D&cfמ'cr+C^ nHiHS#O B -6g~/ _Mmy9eh39Glw*3^5ɭmu2܅f:I1W1ǖ7{c8:w@nQ Fy%iNm*y3B"nVk{P$-ӻiw~uct uh qKX]U B`=d\(-a4[mthtrqBtö?|ez ؠ^a/C"5-W% G/ 㴶 ^ji kl,"%OCI rrGQY)]X>^BYd053 ɽ {}mAus> }֔4GnwX='yux-k7}W'~hDtugbϽarWlFO B; 5Qs:4*BC |\liXH8I'Uq:{. hPrwY7/:劢leO'KZa3O(XpE2ÇA=q.}.@  ?4#*eEuwqxOwY*9K# ^,Eڽ¡|:M1j0ȏI 0JLTBX#Iד{&sge9߭`]zq_G҅0VQ#mM';C"o5~mςUE^Lty-p>"H~3x9N F7EbpxL/jy]ߚ; r63Ng*JwZAc?+~B]]ӱ:X$4ynS:W i|G_xK,\J, 4D;Xw7YQjW$0(`vF J$7s0k{ZHŸgـ&ACl#Zu^Y 2rjIJC(xHh6߶26T Y_hw\_>?=>YxtV)ae^3WٱI^"awf`ڤj4lSv~Cn7ὑ1Ǥ2,y6]U\ t{%vcAqJ`I L9 uB1}A q{ wpU,pm9AZ9BG<[qYp|ʂy[aVVm3 1>Ahz#sTS?|im$$ZxMp\~O[Ce.?y/̖Qq!UzBީ {sm[>[XWF\2g"l::i5;3̜'ﰧ?&3(X\ /p>:{r|_[H3`'aJG߯mtL4qMZv*н(xR;JI>>GvJQGU!/8_I?Ua~?QrQ8aUT-߿?8 C_ P]JChC5,hkh1LlFX:Dy"B;{!ߔ_?ī#\SbMD~ y,ݛ&/2w5H .'Khb33K[u--͆wVL wШ+/?{ 'Jo6oLzdUXحVR*' l|y,h|KeȦ8ڟy" IO;b᱊Ю"4r;H ҳS4b/ָ%b~eipO..vXF! ) QJmVt=j1EE;UֿTb pp`2FI!"o_SO sSʂ!宯}(dCGF+&Һ! yj"\R^t5t}gOfi+>z "zs%a;gv;粷xO78h|!9 =7d+$'ԏ_Jn..zF3¨>4Hd:&?Mo hw sNL}y;!弘ܻw0BC&4|Wqh/3uTioWoY$LCQ1z P[DĎ8x<1Q:>)Bt::/{&zԴ-N "a]~_fd6= @K_B$L4TK <9~t`sN[.gWϑUחxmw^wsy/˜¯N|6۷;vYz*rl&7=So};LldaOghj1s1DO' :c0?yO@utd7Q(,IUu^f_zX>mAABUTPJZ$*4$xuMCW.f1W ԮjPn--/k qhp'v9HGI*m| o@^H+Y^*:ZIE]xuC(^4g[r󃛝@Yp-¾|ˮw$:,r2O_K |3 Wu"C]zk?-!R`#$+=4J? /Whx3kON|{폯^^NFi͒ZRH>H !uo&"1h)ښ(eƧ?}ڔ8H7!wuw4 dGlGh,/aWzh]_k miǚQ1|R5wR8%~BSno 9kʹMhz0|yrŏhjVDK@!Q+b_OLDO՛ _lkk-mk!|.Llpp޴2zfZfڇ?W]}#DZgT:^߮yՋh ^zo0Կ9:{:+sp,B\XZ~f(7dc/͹{TdvYMńag_9~NKʻsa <n̮q[OsdcoL>%q䡲4R#  ȯ~/ Y~.eEcQJde*CD5}wJCNo'-v}A8x)d`⷇a3^T`][˾$-ܵt-#nulHPGbZy}y%0?_Yc_YEcD$z{{ů6^h 5!'۴uh?!6VYœ_!7(dP]ȤqaL 6GaV=,\龎g<%#NNd;^g_8lY moJ, Dh>'iB;Ɗ::/Ύ h @%[< T"?HگI^w$[XNI^PE!ҫ=·B>d 4xφ!ٱ`8朻Q;v%Kjui.r[ &<`&xJT6 iE#i};qv{7Զ 8@gg=H73K,lI#q~P?؄w+(}\[㸳ӹ}a].b-nq5.?|M#0ry& pߓ?blx?)wsȍZiS@Yi4^0{=2gʟ+J>18Jr>$Mⅲ90D @nzˢe.D8[Ι$?*Yh {MNjcuB5?|(>p_dp`|Rqpo?Mv4F(Ψ?{aH4=jaA׊7`+ˢ}h^AD:J;&^-6ѹR"Եbm]H PJ7M9xbbImQz:t8WBP̚skTX7L=HAA5^ Nh}]ڇ$- 5zCC|9|{w;scώ+Lqyrs:qLݧerjHz̸{?.Oau.mv߹:qKagks LN<6.==oGɂ4I(%7(*+§!O8rWAa8 ?};9͡PA ZUE/}K(7q0{?^se%Ҡ3{oAu-tV_0qٯ~BOo!e(RQ'#N+}W}ӡ- 5A|B, &$奯|Fn1* PMiZVn5M/3oX+~?%leNJ,YfB"iOV/܀!?E2×|pȫ/?sd%lYE5ݴT@:'FSnRH՗– B~%yKL={PTAAČݣk0ƣe4nh\/Y`Dk*,vآ&«Ka|~Ao 4#Ԃڱ{w; ;Xã?!,ہgR0޷4hQC+$^X$l'7O-_7"m&M+p }pe `? tB"4_"XAq(Y?cNO붜J*=_1񫴷 ď,PU5w !P+[P_>"K`\u: J@1b !\GS]%T; *0imNi=2%oՂTA&?xeL@ (<JV7bܖp@KID]3&<ZO MGbbbp;TANTݣ=|i3UщĆP%S(tϣHG ܨU&چ+=* V֊|#,JE"Bo[5yɽ$8iꢌcֿ%vNy@q:ǽq>7m L *'&/$ٚ>C5 $8J?fZ5[ϷenO&Q}cb 00;gʧQTex ި~S!!duUKW[$bI F}*)膬||Hipt'3 a kھ'>>/LfEDbm!w` IH3n~N(1<8 6rrmu^gO/ Тݭ4TaJmr-Ƶۻؿ6}tٍ r]fdSorl׺ ZM@44xB;9D,{K:_Ε +'41}t=:W*Lj0K19g}Wm*^Y8P0Uo1L[! C(B7x~w4F,7)DtCnc將5OR'K \曞[. g;oހE9ʑ8\) )ոT^|=k* V\ _}3| ҇`qUoFR0m ne:Ƈ!EPiv_ĖB7,^dQ;f24VLDcqt|nV CW4JBOwDbU?B#5t5%[eҀ}'x4hRf^X-RDhpk3A/tOh:~Ew!L2<{\`QK&XK·ef-(,itpQrɵ۟__z>>_7vi/kS02w/hT$0Hľyo55 XSiWHgK"٬drggI:HKl0|-+rKuXڣxn +m,.0P~/vMOܹ$ 5eW&H.TcFc2X#$B(Gl)~ڤEE(޲ tV#k--n!C3:b%7-s-ҿ}iq*AQ::j9pEĕ7w9} ]O`xjA4inkB7Y3 AleۊimMn:f.?U%4'^yy!bМ:0tT4 /- i{Fm2Bߦ JKȏw䷾ie kJC_@Ry#2 { hŞ7?ew{S:8{}vYۛڝ c[P5w!GHd$kkҩϕKG SNJ:vkwaqr_3gmkȑ#VMQ[pꫩK#6u@۾׎]qd߸;8R/bҙ޳-%{Ǧc}J"(SIX lDPı؍W={[@H |dԎg`̿]t˘GL^gi؊bg{ǸZ @[Joe/tb6u\mjB/*GXT^sKq2۹Sr-Su+֪k-%2!qٽrO,mLc + / \^}p^W$4r$QSl0}M/rm!SΩxTet˼†Oh%BPP#vԱWWT 1˭[SRd@OR?Đ/ (cpq ?w.yQFdۥK/+8gsU<$Y: "htk&-yV:q$S>HamtVsݐ+t"MJKNzO/׏_ۻPNvToJga5wؽ{`ܣ_s3I KQ C`ċ}+z)4L\m~d|˕GHQ:޶l8(f)q #ϧK&.[% ݓ`#Yҭ' Ľ  &U7-a*4dOnV]}}N8g$5wm}QF'7،A/o) {a8a}D7 ~:ȤM}Y\!&+p/81s&T OA9 2a/9JR?B@2)W=Y|ݐ/'M .Iy0%,YîГFx>Ǎ8gj _K;2@Qb\ X Jx[G||PMh"ŭ ිd4s {Ij}^Y\Ig^cǟc1mw=OoUqcync\!\D;WX/5oo]ۨOfA@4LCc6_uFZq9H8ZVorQy%Hś.xB*RE)\rg0mzفu5dӛurb㛮Ll\M^H @C3W_ڔp.%f95󗴂cA#BGQ1W4$]{;|]oLj?^kfza_AIK33Aނ *r;4{/߁Rkv։ߗC.߿f6I$BH}_$4]^~=%!* B?r `>~F-|\`{9$U٪'?7!B_ʉ\V/>/+{x K2 "䐗ݓckk_72kbgY0~_cv`cmLRRQ@SDa'f oSgB9.kjzIwLW@1X WKSJHUuՐ C m~>wON 7>ay;@m^@}|ǩJož[l]AjX\7Il 9q T{A]^?AaWJոTݟ`W$k HtL*C/؝P6I2O84| W.tk~} :B(]mCDes1L%x|i/ [jui |^1HG+ 4qz\C`@>6:#1 fQ{^Zؽ ml8ܛu@ 5% yiaP|P"U&C  o F[-wҴe:z ;{lo ۛ˅4ku=9U^v[Gr~l~Iv@ƾő)vYE4spI#_28ieYXpo"5x۲hPu 1'j*aџJy'7ƾB|VG| /D`dn qʤmc˭h#!}?J=REUa}XP>/&J&; Zc Cւ`4t! ڟ72RwV9)/ڊREv@YwڏD$b4M,D]Q}W1JV;O|0'ggkg׏8xJm\%}-Ja~f֕J >I{&,e_%mҲ)r_3n`_GsoI#'w\0?\Nfihńf~:m"{− xv۷]2tJ#H0<Ȟ S*yCh%[r 5gV+%,~1*pGJ㬅6ekзB(bMfuCٓoWSI}%%k][f١FD^ ߦjnv靑Ⱦs^߼Y'xrBcb]_XC*I*y+[Xt7ď h %+D/wcz! 3A?VJ7bgk/Iz١`):#|Ĩ1@-tI JFHH+ݍJLNqnDJ>s}S0saE`S7=#Owc")r"dX[ fqe3'O~fe^29whbkg2 E:O;鯯=mGG,U(ܸO?hoPY3vۼoUΫҙI~^;KlK}+2R#blTh`O_N|&RX<~F0A.,p2k%:98^IXTL8- XF9i{i!# @XCeh~TKu͢9=p)_4(WqzrؿllEJ*jJ{SiS%r;r\{c :'99?9m4s&+j8 Gl=lFG3y^NW޹pi f_'ya _MDA4dVV c$UMmj Ⓤ 7DERSI( U#8:0EΔl% ,:+O5@|ƪV(6\"[Z l j\L\([H|#aΘD r;)/2LIj!73$FAmބIO~%3%5u!bᖕZ׷B[m2SBDfkp"[ eZ )R MknxDf,a2xְBv, $Y!GuoT3)/$JE@ edBlrپl"sB?ȂdUEnCI0]h:悑cEJLǤ!Eܲ =v;4h 7婀 5X1V~2ڰMf\C/_â9UIʥfrܓo .uI;dDO$Xo}3 2d<-`GH͟dQ"#UV7"*,?*Ư܅?J>]:4'+n;}H.NEK t۝É7ѦRݖ"' (xb.IՊ@PoBus,l"WR<L7Z8<0~JܐD ܚ4 C ƋTv!!D;=U|6rpg*9%J%rMiYU1CBꋂZkm[.2pՊ~sdzTqR(1R$Xwj&6橳?gy?F(DM"Iks B[ώ~ j.ybjfcpJL ,UКh"UV'DAUjPO r^ؖ_ Jx=K ǚj<ΘS(_s2Baz)=B^`9Ga MػԭERveVQhW } NrFqrq?~`ġۗ%.#p;c٧hm"’gBҾ{AuڗB-(;KQh 6uD2/⠻gad8A!БҼ`|%2)Jl嚓3 ^S![MRʩ( sY8&CsEXڿM:@ ͖7ڡ"FSshNi3MO inº4T0 П v}"@Oӎ}aX@pV!|7ͨ H`W1r] j_8b%ȺF!3t/GAqPIpuO˛U'$9څ *@H$-τX/_< +nw<w3IY(]t41𿵑uuT+Lf\.1h}MٜksUB1v"@`ٿXu  Yl`kUMiOGAWt1.qP-ݟ7]=8jbF̈́u]NV࠳exMFVG  l?Ss ?aǺɦa]r%@u&Aѫ:ZPv8N5$gv$֛gbnSBLCl>j8*l;V1 7n]X!??;Q쿕^=[B\*%v٥] ܧnΗ#?vOb(uؐ1g[:9:kZ~|B¶uRrf$s=0æщ+Vw?Bg *=yEhUTe]\AMF&G3exɘ`X=iaQ1~CCfaA0aS dže ę趿zܴC[U3d 0",0f0Y (ŞhW?Ց`gWϔİvZ%~ـOs7Ir&YMa3_,Uⶫ[>{Pk$4C51(^cMS Uԫ/i+;C9v'EMȫBL(OqӀ&u^qdXVĭ{O#ߖ#ϓReًh0ޝHe߶ >קc/#%H-!CvLц=z 㞀4٬PRb@yٶWj>j!io&!on #:;>>6d=mm /$d梅6ygo3|+uZ+JUaHkлzVRv~?=]^|{b) 2:'$GE\WH_+DĔ4Lfƹ$14~_~Lyw5ƢkzqA#㍏V%d씒We*&}|e~R˧Iʐ};V`!KGa Jz0 _ G/*m-sd@T5[ )Mxӱx] d&S#Qڗop>.WE(=t4QxXdԺfu|I+S>gb8+~hjs c+NORmR|n\0M*?SK%2L,^K j(uʛӫh^-@]~a sv Inj';|j'Ϻ*,cәۏ!b]% BΛS~"7a2[MAE>F;9TD'  ×Us6+/X}:W<2|8[ VlntU\Ft@:iƻ@ di MW{?oNvALn^^?dBrjdtD6Z""@HVGMFhWLU[%ɖ4o jQR&5JcxY3Ym]iۑ;] DmN߀e%+‰X͖ITO*6$;= \sԦ0* k+,ݧftr2W~5\H݌뭻(y68vbɧ|n%Ӥv&;hq+X]WȬ@K4vRQ!e&LYAt[88NYUH{7{C 6a$`t:0$xۣ/a!_(V+ |Y[osNW$F~ڞ髩Mgp4 |pvNʛ7~_HAERDΔɽsO)W"}oOfk*G]zAٲϛe`%z>pa͏oKv.]y b2}^n=A|m.aHb ,–RAX]y@/q1***aV#/)۽BA߅qI9faKqUĹPA8FRӘڹ"$1PW SꊮiT*_Q968]MZݽO–=iHz j ]&1igNkqm,l>q%+yOMٝZuhL@RV\"f0;0{f-+ErLC%}cPa+ UP{Y't\ 0r,Pyxx[D .=;KǕ|vӼ=9?mQN4bؿ{g()(A,94i:_Q,7{xf&?(غRDKE^H@{孝R `BNX 6->q4'|WƣP',a)0&9*^Gq"3OČbJ]UXeǺ 8ڸA^*13 +RLs3"hS]9O?C;g};?ǘh'"G-0hXY,߫:L| EyONgo+|wg:ixДmQ#vtmfZ&20Zi-'DB i(r0@&@==2<2Ufc=grH}kaOgC,VsN3TnUAXׇʓJ =IYg lͩZҼ3rB IJ\\O'ъ[-l2(:K@">Yh4G.|7OQnS+LCLX!e7%-r=y X˜h5Y?\OQ1{c#_ 2qR oZ[.o[eg{;ƞ8įթ卻&^AA;KmtO >zSFdL+WhER&֠3 VQ!@ )cCVn^ZP*^pc 䬓4JF͡m$G'qc'YWG.a+3Z %"QqWRbK,zoQ—J%.j,T>DRZ.)_=g_Ȯ AJ #bj2W1x.'Y!L5*+^ށg·QV z3jo.}v^ j zPrm=%O4e ͜qpɷF݋Ʒ!K6}E:r.͉)FZ`>r&1+>GcNmTӾR^o]{7dR;>Kv~nT!ߋtr ~qFwF :yvѕTn v^q~ mlU-0 EY eT{wa:i?Лt+ViwRk0l~iPk 5Z\[r/{"REؕC(xҟM6P|F uds^|Q"K`%E.kQ@yC,cr- ٱ,1iJqwL*":bzNpM)~k?9ǂV h7yf<F#m4̒EaεT+ٷPjt=.ЖF}s:MQK7^`Ȏp r|pN'e]nŃI +cKф ,nƃy8/^xMLcv*JqqfS(:V _5!\BI5BX0Rh(m+Ãp.Y.,MC0#EO#k,l ,`_*X8SQ/1I*8I} u#q3'C4.w‰l{fbW{?0&Cf9B^t/g'Cߝd3a{7bH , >4g %5SɡsѨ`n^86૰ $lz!VV^,Kn@N1Vw٨<^ ƿ:\ vjȺ6&IULY]PԔ FfZQ\,1 i@+8W y!%F|n!߆GaӘ^mQ\d)W1Nz2pc'}:> ע >fo R7B^ 6ݖTib^ ,䒲+Wo$ְHk:+X_ @m=,T eg3QW8^C Zӓļ{gGl{(mn `])4^wFĎT+'t|F+ƚ"s3lL̜q»'Je{XwFn [` !(^Z0U6baWF)~ BzrDU;ۉgHs!KVaIh0CSDHԨtWOc!elY# uu|)Rd('e" 59؂@e8lLWF6vbVdV`bgyiX{V+Kˡ3Hn@2`zG^L cg怡)揳f@}݌%rBHBA\tMKoAMkeՓÉ$oYߕ݃T֚.ZcC!Yp5R>hxkln ^$cQh}LiX|P-@< 3+玁+NȘ ^ayۈmJw+S*O̬XX%Rx~ :#(â _$:0c^16[lakf'[&W} xvwc_)O\G@Z t@v==654yUoXJ&I L&]6o"x^#V;V~A!,x) ݭ1!5M{XHSړ:9°`/Mw|#ڒ8wj-*,׸o~OqNGM ݫ)<3DL0 HYpi=IX8 Q&)>)e6~x qF//T#)o?xÄtN[ _,bOT1$p=%>=+B"Pky{*#:Ϙ| 7Ẁ:/^αѮ79)y&h#eHM6nbM}}J`=ix%~#=Mq'v50JTJ[P|{us.j^3IUu_Qp!'f`%q4`@=OI|l MFtz'9d BP= :o4U,Z8tݭڊ7Y@aL]O l99Æ,~ S>yfM#*:Z5 ˆldju03J51ۋ*3~:yA(0N)ש R\xwdPLxY'zu~ȸe+Z8uKQEF8 d1'ڛ媢Iۛ#E< C+1Xt'y\C2nT<σ_oĶ;'(갘>®˾ǤT< Kd%suB7,IPk#?թw}G& qޖ'J b"@2EJe(@Ǐ5TQoDFeIFul'%q1nk LkF xErߚNĩ&0mRhOb+ԑ'E(%] #ݴU Zd0N ɖ?|smAaV۞}76ԇ?mV8W⑚LUr.YR_P}z&m7<;{Io3TIV7o8:l+aZX71l zǏB`מ?2'M(ZdS0S7yCZr?#F$\V='{ )=z+, 1i< ?Hۤ/&wxRR$u*0~-βvU5q}ӆ_*=a\$ $ QRɅ 3b Yi(~٦ ({X&f_vw7fGiSܘ5}[Đ/J_d~ZrѓqLҬHBv`iJQԍ; dKpb8a5iR_6wshpB;iiv ]x>2 @$ ajoVV~qNA@iN8XO˅h-zc(F@^4DzݏÆҎV!Zęb(Ve=_bwW9u&Kl1ĎapbـQqYBK)-'Dg<:<'[=O}g9"m`8_U bJS>/-]yB2 l<4gdM2|Hxz Xda1BďM$a azRTR_䂨mv>52ek 񃿅Ȳ[ozCvVA8/Ɂ-bqۻl#bWz A!&B49 ez[}p,x9n]- ԪFS*Z'fFگ>!]C!hncM{ k1$!1È C'$$@9ߞÝ>X`U P8`Kr1J-vԠ~ؔOgnyTL%ck,K33{6f _ Rs\e+l?J]e[_+ BbǚU_i {e&nTr'H}~|&IT]S@ݿBS̉ jOլJgb!&I]#6cMʭ 8WZYfo\u7yȚk<_ AZfmTeyz+7f >9=$(L "O ^>{?V{l"-Cygn9ܳH3?+*>H ' `KvW'G󫂛V{π+]ʢr~x; ~76i@ @cgWUR74t24$Y /w7Ӏci"-xS*D=DGLrV *\9 }뱃/f;5kpj_&ͷT4zЯe=E;S7EZzM0p#ԤnM"sIPheUȧ:_ۋ{9GYŏ)3fї평Vst,2a]\)V?Y'5UdB7lDc?Rd C if ܃+,FB]"Vy?U4FH0b1NIk7E!Hu!K3>PQ_Ցc.@Nۙܿo;SD2~rs9W1~hy?T㿲4hB\dKwycQ R;41d^4FsLձu 3?/>!ܿ{PLWÕ/pjR 4}41/"YDNn{?b!7* yP2VQoʓe'P n*KrǯkAf?hgL[[T/: u#i,><ড়'ޤvUCEծ=Ÿkq8^]!uvGb{eX<?Yo{,'E0r˺;.Z0e-Tk6:̧ٚ *I]HC7?zue9{G88mDCW &ePrf&z%qpF$l"Uy^7Pf26zhok)&0UJP)S'TI#Փ`Tz<9gG;w K`\eDruBFS=IGjcsvR@6zQc q`NMs^H4͙i*96 ]hԕSQWT9}e/Qʝҫ8I^,uXj5z,Z\ܕA DJ@Nkᄭ[uxJ-}xQ{{%. "oͣ/ 3pu] #|p?~B-o¾Wkg MlVyrx<-۩zKےiJX4[?s >t]noҭ|,D_X *|ם|sIU|7'e#i-ߤS, "޾de;])5)%),'~r&ð;'pV4\+2 %( PvȧB1MS^.c-:xwn"sR\Iv*>Yec=;WU}|ZDkp7WOGZ`д/4wg,sGOf2mD1xqO@ɛWz}rouL9Kmy's\%P9Tԝn˸ձb㥋; +0 qCP=3 6d !H-Mx:s&(RyJW J!8 E/OOx#Y.gҐwJ歑72s 7_wMffwZԢ. Jy [ݞ' 5qJ<Bt4| fK-hym#󧖟_HDw7burgz]-1Y { 8Ó@׽(nOؖ.W@蛻OmsW+g u~^g9*.vnPstvjGg| |3+Nn{-arA{R(. +(LLoqqh'k1VjDHN;_JxZ~& O 7u$@-6sA|yWx3r8ZN<# DN0ڪ2&)y<}M܉VhF] 01;yCK8Nx`)p7 Pz1ox$Z7d}yw(?9GN?ꕼ"tAR||Œ Ae u4<_.?gCIVnZtU%~]GG0 ^@ѦOVfظȏ~uxK4:s>;V܌>,l[ Fan+X`KR7pv 7z(ʫv )ѱt D`uOQl "#Yy"D#_rJ=aJL]x͍LPm^hQh^4$4pGSM#7gsn,cZTDlGI=( Pv |yn䥪V8T ջB/90c@ÿTa31dy?)Yu0BhjP 3:Ģ}y$y2穀XQɯ97f1%< zH$P%"-`HJ+9HG/,vU[,{ąxă'?KrG Ⱦ@5.$xhcJ1GSMQb=YɆK)۹/H7_;r:r;r;I'?}}kg;`}4meޅygZ? IK@"aTx=^࿵\Ԓ_Gw,US~\Km9օw/f1̚X{^UK|ld󖑑.~89DN f|sol|wֿjm,'K4m1=Dfab8LUחؾW q^xc+q>|!n55(NߝZ%{d;.PN344q&Xg1A){oo +kvn^HS;<9oF+ۖO>U*emv'],濠6u8+8G^+'jo.Ը|$9Z~+&vfp 7ǻ}9۵ |>7_EkxXXٶ:;̨%AJ@^^}((kKD:c?q5;׈9^^ JNbjEA.N`r0RRW!ާCdT6 n6MbqtJhE q\bACz&K>(\{'Eκo45- e ?]Mq9TZe^j pn+ûP _w#MbQdYn*>ɶ!_~٦S %aw#vûچtp(rjoVKp^]w osϿ%tO(f#߄h >:M~k2fvnPVz\y vdl>8Qdkxw' }$\xUZH4'PTRC@veB*DLh{I:N4*RP!Tʒ_>\iWձuSkNdN؀݊KƣhG7_KJv~W.᝝^Im[t\cGqji1μS-?$z#Kr~b7+f' 6y[y!LIg_9@],(NmF"1HҝA@zHwHtKwҍ ϛݽ}9s^_2fT\ ` X36Sp\3%&lge r8A~q*6j\^;(5[Kݯvs-kB2>*\.Oj2i KKZ;T-ݙg$y+YJLØ;MN@΃*9RڪDBrF)7U˶|f89<woYȼ}ʔ?%!tYpH1J6dmcP3Q >֓Rhȋi- S~(?xysZ#mcxG+J^TC'o%S6-Om u`xz\A,Gy j mf&v4L90_T*8j f- z%T*u,P(ɒ>ID7GS [3̐{ ?QE_;st:mp岴A⠩?2KY+&#/ZyGC#CDk#[BVMf @&X#C^$qhGggM4GvywاЩp IԾ?zGT|tm a)Ux2BXkz/j'?^ljWWEA9gkxK>UqHRqm Fp '8 #@A>Fkl ?<|}nמǟzލ4h@!zs9N]ͣv{uߦki*wo_umaua(J!&-k 5BpЏFR:yʟp[¸5v}N, )J1(R2襥k~b*rG"ah 幕=Y|O3AMkw?(D~5C ;K |oˮ,2Z5tFQ? G /Yz}Dy49(q;;~Was\/md6j[ȬPE aD{]/Q'^giN#7(Ra?~NvNVI-~Tm^63"f̥d3 R@pdޟ\T^KJ(5.h>9 ڪUYF #|<.K0V؈oA/;]x1_Zw~~MY~B-!"ҢF N%G&BW7;$ MBK{cy%Q0pV(~nQ (>^@L^Ԙrj G!MZ6!dhLϰ~Ձ~K][Q뽨/9r`ASĖt^axBjcv7}pTDt}zHҷ NaQ_HZnkd734J-Y`s&C:9>l =\<RLm-e7' Gsb}|eGcyHeY{5Ju)I0:7+.=Yb$;eۥE%_KSFQHNvk&m&m5&ċN,w?9rTC6K$9 ?TDEݟ`7 a*!e CY0 5+| ,)h H[Γٗ~Hh.9f& &nsY3.U0V>ۋe#1`j56m8 x=8YPBH3$ֈ7Pf06R 0Gؿ[ dKM='8'B Z1Z/-8jyӰWPVɯIT=\ )C1n^g ݉A90O.11Jf%y R`ωR<̔p a_Q940a+KJlb#׆&IK-ۘu61)9':>-z"2 \ 4Ii ΢ y2u$ܧx#sV, hPxT77O~;PR5#忿(?}=}VVy+u~5ӚɶP]?TV}V/dmDʳ(Ep g[v'{ GُEV5g>)iEUߖHKX QӲk ~3OʧJ'7X]2ႎy#y슟SMx&as5dҁV39@-~/$auUF1~UUݡ"b22HKY-3e4-g$U&a6=pp '%< %{8Sma1`u3V:p뼉L-;QXVEf,,wmahڿœ' cPQ粘NJ) f ɖ[+`o)(Qp[f/q./Vp @tNld1hhysR *z>HEZ+W;DF^O71{N[Y |#&}Jп1`m Lg}O*(mR|怖/a)Z:­0￾P1Z&mnH w}˴w;>`*\ߴ歝,BoLҗ `b4"zb8} 8(UD>7=~r]>0@ƃ܋@Q!]:y=ܳӡmlծD^ȧhƔ.`Alio/@EDLV0\׀Do 9˶E\_|h)?9]dGz szs`=+/sn`15+Bw~YΥa78ѝGI) uŬ@ 65}R#l:R@/B6V{l }Ddv PJ ;qJA-K~_>C*&%󿛠HRg2]S/aFQ>ŊHXY# yRVO,.(]9י$k\&f DFm,n /^F7*?tՀ:c_؇ڄwq 63J2 T밣%eǥS+ a7T:*Html; Y@z+CZ#PR*?A'HDZ.ٍDLaC[&^($s1lś#zg3ZdgBc*JY#[/pe=)@8I ƕyRM␕5*hО QfG?;X*+x+q}bay@'kiם ulh#UY?Vp?*)cיBP.| :8+!'m oPT/HwuNOpcܹp-2)MO-2~57EA _ʪ-2)|O5qZf^NT%m v 1 ^HJ44<;m\[pvuH4075͓qP$Q:OdsgJ73#˞'! *LН _.FvAǫd䏠<n>֏/ IT1p:!bGף>;:E^C9?5:%n/_DTtΗ%Lbh־bK YLA99S u,~-.5ˣo,(p/S=~ -֪@}޶5'8El9#r.2DUI_4뀔u˙+x=N&-3S3s `|q B-n5V{v~ CF1M,`Bߓ82v_i߱$8BTM,${ƕ͋z!nPo2z+r5XvίnsLp篿ROu |^@gN<ᘡ8h!B{Zw-Wa-Isf5&aRȇje^`LQNp}p%E`XQwItjDMyʼn7ۅ͈US4>8m@D_ j, U_yM 8q %> Jiy{L8ɣZ贀xnsWs5sHQ?&M1DTO-嬉{A˃hU&\۽#Q*lB^Wu=dQ\az,@,gEV 'F-X\L8֝r.iُȽ7X 6T )F2r:w˛}'# "/_TeoMk oAHҁ+{Q: .9L3GL*VPW f@xJh.a>P.8@DIL9T$?tWKZSc= au\=-t.Ψ*+KVӋ׶.[@N+Ds)!4$"IkN6AɑͅW l8Nb* d(rf9pw5alB-{$QMn\9l Yاv@Ÿ1[߅8rrC<㤴KOš[H-JڸSҬϕ+PHF+Ǯ쁐>/N4LH%@h":9<-zjm/v[< Єue嬊QkC9(>=@`L[(_avMIuhF@u<+>b3169.W)h2REt5csWJ0L{ں/Rm>5`{V!)oۊjqM>${oJrwwR(5ϩYu7d?de{ƈ:uLBdxq ͉DnoXX8Q٠Gdvh8 N @ 0k7$1} '8:\:;РE , )ܲ6wRJJ_[V)KR뱿 HfDϺqJl0BI$]apIhS۠+~-z6#p%6C[$dX"m rw xA!бBAfQ.NFfh[w5sᴶGP6%ljU`I4@+$z].F=YLzGLfNLp0Xꄫyfz"moKYkZU[v\[$]ňW纫x:>/@PG u?,L|DO̙ &kgB"}п<c]!y ,F,)y=QkP;|"0k Rt>%ϗllB%kSa t@mqQJ\%Qwj=rm . gzb#2eapbp 6Tc#А^boZ u2'LxFma$-p,xX/j֜Vk!~edFC*jiЕd}\L_i}ٲfkw ~.,S=5:^N4![~%ԚLQXWB%,nia_ڊ?Zu}l93Ãvb G [y2g-'/45uuUSypBZSs' V||5@PoqE/Ev12m?+^CP5.$`0K}|10G&|P◬vJtVryixv 2zcd$m`J-A *l8=tj %H~8ȗ(CNh NB$y9@ ͛63 |h=P¼4>MC]co 3}2E`9908*-hmyM6F|v2PO`զ%="&o@"R4&|l?I??ժa' %|%LI6 ;v? z~^x츕QEGۀo-䄎RR[uYHw(7cEZuj2Gpk:$Q n]mWDH1E=cG1/~ ?uYXd޻_4qg[yw?b[yf6 C2ZG_T]TiruU_Y8*{bfeS+No.59ݰLA.a_i>iIQנ&?,|:'m7p6m7Lqp6f-l#=Ed! ~йUܱ.n#7=ۋ1(O |^K Z-^cE壤TL +KaA),^C](hܓ72#o;˒Zw3<-DMFqVu!Z9!MKQ5gТE-|oz1t*i#S^̧SbMIOT3䝿&%g2N7g9C,]'rwI#Ĉ3w kWysBhJ\MݱYW\-ӳ|XsGELDeK~{6)!h r;l*gh/; G)>~%M?@rRl`}0[wؗ rѤYgXGd89xiX(s7"=9XT9Ƒ[z7%鯠NAz a7- c NE<jdRD~^ŚԵ#{)z#Yݭjə qY0Aσe5Sfn)i7gVZ=d̐\ ͟nEք|?OZFI}kLFDF;DMA  cӿidu:lv秜r uqZCi}hԥ~ˢk:l  ;㶈qbIw+HKPeVT%"\s_)w<(C\1dۡ& efU_T SVO5✼“. ^h bBtt_ppy,l"T?8߁ߎ[{ {O‚ h]gKd9! gVtf.M$9bCjx^:624,?<$uL=:* QJ\˴ cUb\>&~coIľ CCyPVAw@YwV\rF/!M5[Nno'|ĭm_ǨҒBfFĥSawXl7+ZR&-:x5>`epqFɮTGGSt;1`9və}c&kc\̻/*#X}nG29U*\,}iL8x6>lh~] (ڋkT+:M`6/x;޿71c7~T)U#qz*7lHւfDDo)Xzȫl,d|taDuxHX;CqR[ 0_+i:W 6mVD KޟVS/pʌ3DNrJ" )7%}f9;-B@WLqyI$Z3+;䦌kU[N/WFKRW ݳ$ݠ5.쯧{X֚o6- 2}~q#ȒukRj f!zٌ٤U~lh%xtv`|-H ۏAax|Q fd\ָ7=/-RL"djvb>=-CY *CKGXCPzS)2VyX!Y .xL> 9VUb ,_W|x ="5ڃ瘌.75hՋ"3tCzKg`qJtestȃERpI|ˡ^#$(y"㣒~>ͪ; }~{u!?lD ]Ri<q 6׍؉њM\=/l[ψױi^\np~;,g$ l>{VI~VyO^EBSj#VOf;x~eYюY;;Ud~c܍li@k!*l!bзYPc^8 NݖߨJneݷF"@ `JU'-,7O;Vy<>?+jtL|@)HEoF~"x>Ff;?C6v60eGX3371VSֳg<6p5@S 8*9 ~TgKفȗds3c̄ ZJ6~tXږъL^oh$1Ӱkk~ρK‚yJ>ܗ%]= +n!_^>=(\X.{@.!u7i"yspyy<BFCr<9d}r^=Mg{X{m;ާeϙ?tBu ٪: ۛj*NM_ܔ q7eQe>iL̑Z_;y6ZbbINc{.w-ӆ`>&񤔊 p0 Ҽ~6y,vf Fab!]<cϴP3췸Ԗ6JK-rpmD4zCXM `pF npDwA+.%Tw_;N_ҴӲ<3ѓ_7|RTR[--u% dEj\]TB>#{P%.@Oȅ9{!Q18\xy+C~u#Aaf^ROتR{c] ^lLrkC =rgQ}F? v_NW>T%o`1l; m%e.8q -??V=0F`=6J!2p}6 r/~t76eOl 4E6v4} *4 I;rO ~Ǒ&aY"|X]_G |okcE*3 '8hT);WunvًVHt 2ES 5Yf[%q!!\Ŀ5%..a2 ִ, >VQ^MB0z%B}@(aC`z< ]ck#RZuV 2A2v̈́5EvA:rS*d0b2sjC  YGy|BwI5ׄHt_ ZJA..Aĩ[14ySL?kin]Ut- CoWbi'&/p -".7&D( h9^*4sL"Sל<;T?B'0.'d bb5JEI~ac[ mfq^RvqԐhP(-o ] Ǒ8` e+(i.W8Lo!S&غS1S5+oN_'$hx(ىԆUZ.6Vbh)(nRr4~~ pa@ Կg?cΛd $.#a vhH!ƀdr '9͋h;,eo# O;6N),aۨ$A1Z+xf1&M-v`*'Z_/^9:ZkfX}rHiKe@ym /v`_:>:9Q>g,OY ѵH()[bGC 7-6/@0F48r}wFX RXCP/ηpոB>i6bzez@U\b-4޾g< 22v_`?)\)J6@0*|1+N6u8br %$EفEv; _b0kzU0m=Teoh($q>m1?v& ] Z{o:! ~2 xzVs$gR) h x gY+hڀbO%1zun^WHqJRˉ+\nՉ*R ;ʴ@U_!yGR<`Mih~P !.3ēD=,=_:l)Y1y5%&80%i{S&CkVn8}ׯ?ǟSJ#_Na8̃QpQK7h"6ZRl\eWn PL!iG]`;92>Km{~-Ճї]ƏǍ% %&a g\ѧ_v<S$ :1DzQ1Y&(,D&|zgTѲck2u -es=%ߤ;'X.6=JQL3d /GɈ17e;aq7w ]qzN1Tyi0!׳TLR зY/MڕPN7$χªod[CJFwFG(RK"g2 t6͞eeAJ+~DA֒R'6=AlbY:uҶP?Ҙ%9Iˈ)u̓xU!Z-l g5e/SC9IWvu)(ii#ci _CC$"'~%JF2i jro)쑉^9Y1Y{-q%Fy%k]eU^dtEAC@G 35,4n~ШBqc*+3߇O/utTwF F$2^dnCUM/g= w~]qvQ^ XW_ė'B@~LySNy7oDb!q գfZlnK!LmB'KuX-! cz1Xm[4SYW=j]d@'SxL Vq6].ap'@Np Bp5.=! ޷MZ귻a?c39/OUq&/A4I0u^7iÖn9}7GAor^9h߼)A60lvO+#R~%,7&u9IcKb^=xeW&V!-3p =Cxo999dHnWCP#dX"Hҿ4}MkAkAH^| ˻jwՁCՆ334Z‰-S*>tE2b GH۝Nźt&? @I[2S[R':xL::,ʮ*~Kaz&뫷SO$=H3LA- z2kyXԆ_DKb[Vܳ\s6k -2?HFeB`?~۟uOW H@ \.`_D𙑢JaG< +-LO#Ad'Si“1"r:~6܀O7M򨾌w~35KO]Yc4xm\!4y(L%OPpSTָu&E jN/:[P5AE+1S$=hwN=9y+whJ:*T2 {w (=|T֞XrDe=#j2SKFbVl; UK+i%)[4?%Q̯/'b9"6V` <6v+"onAY*km[nki%ξi1tVT5hT~r5ULm %#ũz =:(&00 q]z7%w6a a\nqqBeVE:a^6[r+E.R}&PƏ~y.|oQ?ibMI&/kFwnTu_UHI]gZreG$6N!Z॑i<KjlMn* xtjDe s^~9Y_k|Ie o b"e6PD1qoT>ﮧm(A _|~O6Px4>bMxb׀aM|ehA 3h eʜ0Y‘\L~E jpz]忴 !LO&JdlBxu'aYտv6$kb]A5 {dB&ብN>%ȸ8 lLWa8G]]& ?ąz)E<[*Odl Jѭv^Cd)7:Š"PƣuqRHyd=+ҪdËQHWC}?|[,.o(5T^PC#Z&9e'ͯs7 dK=91VH:rh/v|e TQ\Gnej"%#?WQ}?Quc&\3@?*n=2=[Q3MO(t|4=M/|4#~GwylujCGSG7!UGp0Dz-s\r_e98xV;P;@G^8$ϐx]XɮO!mb9W@qP9B)ubZZ'waIDKLPn_zc΁@󳨾 !xAVX~STLvz-#lJ9Q" D!|sI4r n *snĈ/B/w=.Fm0!|ыw.ͼZnRH]T̐3Gf9v0t( _ 9f?Y߇1wOӓ{ WVݟ>O՝Q9( ]zHS/y",B8%c)ɠA"U`_ 8}"_-ho2hCb\Z6/A8DeS#$-8o2nl?iq8J4z~+hVHtϻ䘑ĵn o0ϩԧ/$l0yEHxPRN4k>E昿 Kl uʣ1k^9ݵ vr sx_MKh ]vd937MzUN 'RT+\ENt BM"?R.yڝxws;dR&G92qJ }c%V)ȝ ߮HܵMllCsDi7>fgz+Yx*alQ 'e 8?v(%{w̎ϔdbjQlU~@H߿ r $qݯ|qv5HP;RHFO7ljMLy,j0[wA?^CRys^q?,HRuܽ# ZrZT@k:g2R.irdYA0JX\\dpY_q/',P᫡(i"J (Kg1؞s/}On ,5O|vpeaS Iz]_kk@^G ж`xKۿT7 {4ɭhA"׊{aFm 8"HC;W:=VZ0AW\UdMl>߆LlbIDhෙ*~u~gI@ =bg3.r`}qO&(j$2pB !'~CuㆍaPY$xEKwn'|!|  N^ ݎvvz A-MX3U=(&Y 1@,d{/ Sy{=_qiqh4É2@\{4رYÙm -U)o( OW/MPj>~B%w;I}+"&9 i`^ (HWy+2W +P(aE=e ʬn=@XL*Qms9&l/D2|WgAs$@42`_+Nkˀt1˭*s0$BE?R"M"Q*Y BS3uXY6θh*¶~<̌6O~@gK s|]K#}_ >s3%w'g&&1ᶾ|929磿Y )zL_:,5#wYʔ5C @'RvJ8RNܩZ4ѱ0dC78dvU 6<6pK$2(FpX5FXYD(Q`QzTTGJzEWŽ )WEӸJE0k\M>iĀ" KxjbȬƛY"[~|MO/a{/|'4[š&FI[Ï Po`P3ʊ, <MnBb`,>n- ỹ+g0b>Yr(h $:M%_[ddۛs5{q9|NDgjfv?{*P~}1s|16 J'Qk*p6vqmeqD#S*e}b*"0X EH%߷}葐. 64 }w &b/O0n %J;$K"ce]J 'R`iIxNL8czQ%Q?`[ sEb\^J5RLzG&$/RrN|kD$t":(}@Sh r}`AF΁{vyy/:$&fZ>6.c݃~V-Aw1b+wȖ_R K>*q]O2BZpi<.K/b ][^#* Z?Ou<` 8?G?*B"L%Il%x)d&Dϑ](1<\Ł!D@ MN;TD0⿢PQ4ϟ7(c 0$uW/iF:Y"Dc4Vel@_]d4N'@8, œ*a\s qb肋d8('n8%+^h@y5s )p<ٞ$"U䔧ќDcs Ԣ@zD2ZMGǣF@6$v"`_Bz{?5: ƪ̺rk.eI阵v,s(:xiEDw|:W4U&zyU5G~*1ʲf -1 ȯc8nEI^?ҸSZNc=54>y hŀk >{A89岝dGPd!D["Bx22Kp9̋`UkHH9Ru`LW{>X|pQLn] yk?2R  NfRyvIc6r}؊BK|oI&FPǡ~xnm|b-OK JxYU tY0[*[k7LF-Bȇ\yFg bsٍDu|l|^͗? k.h.oeu37I7to|ɱ F70~4!HvMC[{u )y3;ғ!p8C0L٨o3|vGA8e 8LjiVZIeB2&u`㯞َ;/ U((?r8+߬Y|#1_d; 1c{:Мl-d3UeTԪ[d@[9vح g-sTڠTXGa>_-ܼ/2ʚԷEp77gAJy[al'f}: bwW ^y-F ؅:O*<޾^ nRk2L9ZF!=xfH.qoҐ[()I7훢E]lh59E~<|c4j2nara_`pCB{0vɎG@"m~,o\&~(|[rLrIDU%EJQzn%3&҈M'-+_,pimc K_s/Zu=E(#oU+Istwq;W[XĝZȖZ;.H*8_"j`-*9 Ũ#9-իY뱇%A #C[B)&mY {#;!].CYFscIA#?`wjcc`q1D7IO>'Sfb G9E H7qhAX#)o]`|(}2Tڛot0KEx~Bׁ'_5!‚.Q(ew)cK+mͤ3k< I`[XIc>"=|~XQjՐocVwݎbM IqNu`ZDc%3v%hud#/lTm^rݡ#h6[r;.[ m΍QsҹB<%jZ Iys^n;qUGE|@^ػwoav7SC26=iF 0l@Mq.8GO4^Ɏ77oëtb}RqGk2u\%Xg !5~) 0ѻ]Ci?&/66(:\i:}N",̝v KDEV1\2A F6(Oh,0X4Ĭ z`O5SULkLV>iR~yIG7a"qCjң#Ofy 8:ct٫&g6y @B4xV5迪gBDg3guf|U݅w<sߤc6/WU* DC!u'j[+J2>&,DzMCP5\ځ-Y/#cH2f=q Z"82FNR@ Ɉm" M2VZu1O'<^l|L>FjSx&tzpoԯQА#E3mkwͼ}Nn7\]ݸ^J2,-KYr̬U\DĘ4t^}~.ONS5aK5?꭯}N_cزV7RRۤ:L('ŊG Zvc Y/smVPr>bW;ߺuL6&~Q/Ohۇ<^UEK@Uۡ7L[LBVCͻ`0( UNflxX5LhXnS +<ź{z}0㙉^A WBq z ",o Fqdl=7+Ha^I*kuVm+[R҂*\b/~U'xnՒ .rgY50'r\ONzJrGE-s_^$nqhFR.Y+>8#8gL4o?@dcFa1O6 `_ܪ&tئ2?Yc|m;*2MN7 JE9$b $vDM<ӢhM,Rw6inF D3 ݳ卥7h:>EzT=IuAykwѰJu"RrG)]jb HN2->o1ja4o˺_(~1}(ueb:t*'S9 A-H>[/ F^:Z-QTb%R7' ݺB Di)TmwX7 ]^Fze#42/ۅfb񓱲|)(K1i` V֣oz1wAW⫅Ia DͽL =5(V#L@B=OER>e*ݶnoR_گI8j, ܵ2uen{M{cjX<?}זoj8޽nv.Kmvߗ0)U.8Zhv`"*_ ߮ Y\ffܮBRx7LODzgQ-Yj+ӊLm2A0]{ĺ2܏O>R=>D b|VHT ^E!6!l@%4x1x|P%% qt%bo*7VI ӧ.v(ۃqhdq5f>*MC6IlQ(Ӻ-l{zg'I8*"{^ Mg/H R=8!Jf$oŖ(O 5|z p>}jE&A;[FڜULُ"^u?2'|Opp9Ŭ!?8rW湽z4WMn×ܓt!gK\YS 9:Ը8 H[飡g_1UXY*z6$ܔ~(2d5v0.!ԚNzߕ)=ihWybT7X%t̓%rAP[wP$~(MYQ1pT E工i9(k4_ tjA߁U"MGL&e רbW\H JϖȉVI Ԍ:\l)S$;ZC)aб{f_!0hO`UB\{IZqUŬ'(qr] Jkvˋ5h_rSm'r-0*77(. j8*('ے. 774>{/zh e.ք,/H{]P1)W1BY o}!.'̬'R?M,_FO˖p|`M CR~IӼ`PXAFӱQ-E5A+drЪcX *( b…/4(>yL}_=t@U1+BË#XΰWKXm< c$hy F8@׺eR+xV!Փx~I{r2{LAiJrK` n8ylJQ&̮^eԌX?c.9'Qn4נ(LN Cr}(M5YjE7C 9AZQDgfemVbBTCG>db:8k^P_&Epܮǫ f wS4[RL8&S Cs8>lۉɘӵ$b/O`$:6v2~O Gl-HV!C&8&+Ql-'sô $U>+f?L1#S+9`s7phWǨ=H~$Hpt Vݶmhx-i2k:~ƟR L79'=u1)PzP>( 7-Ii^QQD|&71!H/:S]L+bVlڟI+*׻VD2j?a_ֳH]4:KK^^ND@}Z۶"LԈXog/qAtmseiZ_Zt{7|M"v^k>%6v;Jkl4/{ҙ& =0+?6QX]4i^o](яKl,(.oXP>VksKm4/7RE\}d5(F!$ e@޽0ؐ0*f~k{@veq#wZ:n"ybhc ׈$TI\Q$ dnnz9ŽJSt͞\vc)c)F0.H3 (K~sՇ5/5E5;l!9g9n8)`Og\a.dXsV/~7w]a~OWU$Dv`Ն$sө8SW48Q4]r{6=Mh' ;K BNE>a藻_|6.Pƥ~ގtc4)* :chVI&ڰDz1y}]5'1uR]]GmIFµrvVQ2dA?_o{ۈ8R /+Z:.lol°H~}v6k<Ƒ}yK976ҿTs@J;8\u83RJ#C!j׳)I8~NN:u\ZGRMBUʵ~.}a[:`\;vҋn:JgHr|W{GW dLd9 ;}$3#ttNnpGt6xH#o2AlR˞kٸI$EԖdRe0˛2l ,EUL%I *-GB|W+?zݳңDv[k24He~Dnu[4˅554.\a6 OifOdExur*A/΢ (b1V{ܗa :K3ϗpS`A!Nh5+/w/禬`ߧYb[l`tD`@(+m(΁5 dB,5wW4%ة)5> >^;~&n,8Vb!ğok@Gai ]QE{AN`r@Uv5~@LOm+Uwo0"X$6}eu/0o9ݎHӝ V𮰜C7M໦L9I1ÁY`0-5cvA^MH*}$&Fm. rV,&/1,=S4[GdHazz myM8wCp1t. <-᩸0W3rkVS 1deBQ>v rU$XE^eCJ~L[|oA߄|RAlg;v Iǯ!<!SqVmO\PA )9T]#K^M,iyi-`+~ t)0Ui[ˎZ=~ŠBSǔOU^^QuYMsZ9Ƶ2f-"t^ [BQXB鰟d~~Q0$@1~ y\Yyxi{V.K?ٷB&uв9S6.q]IK 6B[Շ5;Zk9L$t[ΨKkH9)4kD`X 7ee7wtO=ISՔq|Ϝn}SS[eO;2!5c^29/=xsNă(kR!~x )S6W]u9R諵\Ufފ;\IQ0a:#>5P\hGG iٍ&0GzU.amZBKa)| 1N4$ɽpw Ǧ\D~CĬ0Gѝ 4+uuyi Y=Po%ޅk M-/u1@FUI"cA[1ZD㆗L1+}K9f[=2dd}UTQF8gSǮ.8=^9^ۋBRY'Q10p9^ΡR5UAJEW4XUb&7OȬ~'Uk'#]cR[%; DIa ܧ@<<:-n\׮룮=\ GivGX&j]^FdHC:u18>.`=뾏Na(]`5AׂD~[-q>N |{kˤ~Jnl C__=GVם/?<=#{&o/ndCꎎXw^iV{7^[]i}Udϳĸ:q^1]}ZT@_,g%$,m2˼2˞4kTK]`%8 |ZURg 7]RX8aB,Ъ2o;΂@ӎWIi"a6=)|NHvZkX3a&!cuFBT2S8mR4~K+>ڡ͞^Kfghߖj@̴Epx ObgiW ^)5Ú`?&p y[&gVTh΁][?IZY8})!IxK݇ kU۝_f9 NaZ^,*); Z׌b}USnIdrn{*PXF1ž5 Tblԑˈ0a^cZՑ}T0qIkМ, ܨg~G"L VK[`iD%3pY{zڭ'.*::oĂ3D"hNQ)K}u:$ƖL{/lFSv}I!6GFA–:Wk9dl_ڎ;iǶ炕㎷p]ц`0ӂ?Bk3\̴?=Wkw4Ol<(Z>D64$e#J=xbEePzf$Yk>_Ci"D1Y:K-2|Xo5ۗGsGKy=/-VuzW +da1;>_prWn~٭FLw2td3`$NVNieC5 o[0d *\󗐋-a X0>K( `ŋdǺ xעKoZm{-J>J`Za3Yg,JbB+7^^%!e_^qP!I*3/F X'JXdBbpLtux>Xr Fes6o ViRNDF G x)d˼DD 3"S?OX5Gr1ku\MÒ$1 Az.]x4:"Vg,>bM%jzBXz3:`3&/RFֱxgCS{z:zB)|BGHm)X=ST7YAVŵ>6"FTu(41Uzg*v סݚύ'&+ rnyWKSSc:$ol4t150bgr]]̇0&N7A|;\Y^pQ,. ,Tm1ovB<)Zh%;t6m6B]!lDc+/B?ϗ2ʕZm6W 9q XÖd\!SgMqg9SƨH)貛HBW` roDFt%  K.O:8A,ڛTWU ꜟ&ͪ}cg[^Ӈ5CqUnoiscO+1JTpeRY~D?NY t*v %S%angeº;*vNq[O?&㣣A\A+ tnv iv 촑X;&Q<թpb d%x&!igaםsr;\Jx*ՓH\ As}h=Pz^W!<$ Փo ̥BtA=RTŠ.K70HGq\ʋo4j5/fia]䠽0ە-DmY!~q&قu|.X>\S[tN]y^ƀ%>ڴT1N͒qѮ)گ4Lٌ6 \5)γ 0y06( l}V,"<{'GdD;5C*E[&1$$u1eu##ַR9 1&cetߨJ~W6asMSIMphjˬDmrEujH]<Иqt،v&"(BS)n=AgT8A_nGzU8juzT]Bo~oUs42JMQKM1B\l! Hb_?[^icmxP [iBЄNӢ99ׇf+#q"g%(}e\ExcUȓXwy2k&E(B;_ q04\!&MEUe-t45Y4 t }ً.sĮ>?g8= ^ҝdHü?t'q96b֟M=6A SySu=g!c跰Ó$̦d<đǰZu@%&ӻc1.y0>|-uf!Ŋ]RUA(`7̴%%L]=VuIm\ojKYd%S,b44)!{$G}0rַ8 >QZ|ji.&%9RYڔJrTYXj?+d8$Bc`*?ު`ɓNQ~!e氐$!#'?=pfcH!M @) \}&)/Bd)s; {ho7;G[mzk[P 51p,ʲ':R!v$̏쿒Gt.f|'O~\8e;Zݬ!&x;9w?NZ`ʜ5U?{zmxbyA=S_vNƇ:Nho:'{2gJعi8H͏{;2Y]LKPю"Q$T Ĩk*U^IU^t \C$8,V)㎏~\ ,h!"TԸb+dԏ8=&>"xs.;C`iU|e‡|P`+SjF(Wo 92YM2S?~-cIqL{$V+=_L|khdT]NGqi&koV[ܾ )dvy=A{8LGƇ젧A\gin}i3.΂}"?.)P$j\.LD9G\Q~K]`plk$/A\ȳ7R'sZ< *^ANYyʦ2&p37I0OBK $Y0Q#Pi%Y B$6vudgmZš'&7V-Jzo&$S#Ar1Wǵ( 7C?t)Y`JQ.\յyعAѹb/,0®wOƝb7L2f+}f^^Fw}{2A$<,Qᑳ-F)NFƞ ^d']$vJ{o`LgrFoo"oG*1.132\Q"Ս# ׋,lP?h疭ﱉxen81ҥkPְNg=Q7n|q&FM!ߡ tspv O:v"׭-팬Š B}*(t:_6fj[FbsYD,] NY>M5OP,&v!bj?}:ٸ3Acww5Sxɗe eMQv^2Ŧ@kTH J@ю6;x?2&xA\XOߔ~{k~2o/E!VFIA[R/k[D|=5p>dΏxG{Z *sED-Тj [j;I~Gp4-3 t"4,ݢts\D~J z93HzJg5=HIc}` [Yj6ХτRPRm]EB>V Ta s\M^|Ywf,zTkh߰A~f`x9~CR =ԁ5)9i$O0o-i>Nf\wwvLClA%+;TKE+AVAS+}|UG~rM|w8G mgB8-u "(p&p6Ondu_A\Wi$pӈ?+&߭se iz{xkV|և=ⱊՑ*R~lv$$F"W,g^ǟ)]@r qHr|NsrN3DUo- RL0}҈VZajJ#ɳr!%W S'Br+ xּ/u&-W!²UjM=ER>pCAN}JA0fl}9/w6pX22,? ~zZyNOՀQhikHƗ'C},pHÄu6Q]#G}ѝ&@HIhZ4x |&堪YnLXlV֥+Q賝 ԗ$FcdXStT$ UJNA[ז {ydD |\wD7bq C.2 ( *ۆ7> a槜UW>8<ֲBlDDҥ3"Ċ]k;cY; ~VK|S!77!{ܺJQocpFuqtS3eN/1j4;C!tGwR1rM|/OWTުmQu#Fl^ ں Y>DBHhK4S,NKVx Ii_GWLsZ#ʋݜ6>0>')NLDGtmJ"lh>*yFv˭Ư]YqfQs*Ao^˚V N^A3@gdl0wUR6rJ< .8m/b+k"+`}=!d_e>fkd<2mPH4Ƃ6P4VqJ8 #mtcu4|KzoWVS~'~uwi|3 7Ց| w6ap-!#YJߔ+~i~o!zH0r_^^[.b{YKx7h߿`MΊUo9 y>TJ%d J89H\ox49Kf'e*כ+Ncmը9k;8Qr5O֒BɳJ窊\ƦvBਮr:WzӰ*h7>7^3Kಯ"G&[d| jY{v߅ncqn㺞/=AwNū;יP򲋌hu΀Y:lj9&tݩ"bqdqSVމ Ϻtcgim6-} Dߺ"75:M4yoy,nGsAD1sc9h`k~`o+Nٷa  H ߘ䆖Ce _m /?± {dcc4谁6!@GCux5-jmJB+ D,-ǓAmjF[;pWͅw|%CGOh^imwR5gsp 8A qM_0QwxQ⇗evg=w+pa#6^e>PiW9V2"5D3-JDE>dp}&z\X_zR7ߣEm.Ŀ{7~x*lH7?8!00[LqزtK6 J1 * ĸWA"L䃎ھi.&59H X<;jdOrH/3vTi7W6b#O)2zz-jgu_ȳa+2>-OϪC+|Q y\ȡJ ҿ h$F-k2lRwt?q!]s|T bUK}5_ØhcLD{`vÞXc eR)#әEvs+hvzfC.OiMÁBN'"3"*澾 _# 3ӔSBl3PA_{U(y_tX@Zam' "yZ`Um4 _C?mB@=$‡ pP- BwUy=@cyq|ྒྷV _`S2g -K糡a)(jP#i˙76j{\hz}"o ?ά^Ą= 0z="<#heOax8"~I/r}mXމo`//,Xx;B*^spl@ƼCn\& VӔH~友7fgJРJK]U?GMDq8zSZx'%49'3˵E  X>3Ld}џYvdz s8s&bOnG8fd,׳oϛ[Ab<ڕpA E>sw'7e/ZYM6хe_ :J=OvǶN`Tw_XՔh7͑|7lt>`*#u.!f5Ah jXǢ0ugn+in3 :E/ޫC@5*g)ƌpn+5ouC]y3˸6o@mkWI%a47APDZ2__3'P{DS; ]5z8{/-Hb0@ ~`n1}zWOf93ȍmne1d6ɜK$ U>oWVcm},E BeuA T\񹧃DԲs <7d4~kp.d <K@X }8`g|w?6F;o a:bO<-Zc0&-Ϭb>6hͺyb N=#^+[HRMF/,ſ'EY p [臭d)!'.Lz'5 #ߗoDYFon^BI j5'z,"WQmB~n`R4 m}BΌkU\gm .ϻA +X=|L@R5[s_EFmoaO@] /gj[=o,BoF'fe0q1@rhS 3 DGHS+?4dvWbz|ARN'3;+yS,׳?@^H7__w<˒v`s:O@:/';#F*=Ku^^aBk U/%P;zt2Ή% tH8,ċ* >@lFDXj[k6lKk:|M u<&@Q%om}CՅXVsԍ)Gt\x|D`)'5?7H~yS&<Y+3**T'c=Gn?EyǀŁ@ 1@ PJLxeuDN7BBu_1/,py#N|jN lBb:qJzsG*&L-6]o, rZ~ЧQv,Ь'QGHX1:_ɇP8k(v ^1 "˝Gq_-᷻ [C޸#M2kZʻIV#KJa|}·i33Tx˂;ryl-OYIv" Aj lJ!*=UP1i$U qm( /!ў=7z[L4:l?'iT!AU71";|~x͗;]f\eN }|V.5[Dǁ޼YR3beb1ǯ4R w3F㢁` MOw{sY>!ᰡNt1p=FX՟w3c$̢nk<ϖpyJVogkqy{AC ڕ@zvƙi˽ dDggOZψ?c8jĺ94}S9,H#edVߣzL0 'mmOeJ3WHAH$m3;]ksEO`.U(esJwTTsD&kZ{/_?L@N7fXt`v7d'plhar9)V&ݙʱM]g 18q!3M{iѷZE9~*F46^χ9ߢc??QхÚOO, UyHS^dL'9KF%VsTYh`ԅɲŠ|K,uDOjlBeG>:҉ nKWqx0fjҚ# A{%WawЕi{S.#]?B&򃗓0>}gدblÞa}Qf}jh9'@3A=vSI]㓬@IE-(\LJqqmB||zsv!-9eptqcAy¿~V_{x9W/'ܥ9{]yn^ZŹP `-{,utU:7=Kn<$/V߀8h'MCܝyzm8n~#T6"^Ö|?bMY0nn8:%WCO-Ɔpt&&68:1CSc;3!k k;E>vaC'S}CQ;+1hFzF&G@`(lom` N2/߯ W/O92af?)++k.30Ӥ38&7pt d`aeIV6Z6 -# h)S+s8:*:E5HŌ@2P@r0' 0&Zz ,LF&fZ&#;-=#2.:nL|88p9;;Yi(w2g W -ӰOTQ_ҌF7L&R|: R\K-'Em>`N%W2Yxe<\JvC\m B_7,t,7XEU "tYv zԲAzyd^YY9uݕW tٕUq~G⺤xW- !W޾-gi>8\P$bvA;#\8]ⅆZtِMpfvK$CNW5hZ:xO@Zky#xKS >Nb'qA_+˂ó UDG!f ؽNHe_jp~mm SO(u)T+S:-3!lG4ɯـ yqi( @)g\t|mUVࢍ[-*-H~ ]Tun(銖GYPS$ ^bC`Nza6@|9,=9@4ux}{ Rixt/ *tf">dmTH+ B`U#œ?>&g`Rl3ŅCi4U&#dqTȜ=u'/t7w%Z:3dhf1һ⡐,2؊QՉ)gc\$xnrM! $m\xff,IAJ hHy Qo&g{v':N>ȷJ,qYVR}⡬ڋ~$%+c9 Xrr)缾~[Rf Eg'E R#͍t(yOaepmJӒ"7>dSnNF$xDŜ?;T>9 8 eA`7?_(RD/S("‹+'fvM7Fy5exW"M a!,\G{sAvZ9 $WK&E70Rl!v1]EA:Hް# nVdh Tp`wTHWʡ} $a%8FKbb5L(ܡj5Lse#+|=2Y{t>*h>$BAw7$E]Z :\ߌs,mBxDXR>(P̬Uh˻tԪB7OHA,J mI,voXuN6{) u|}\ #3N:h<.s)׆|`w.Dv$\r>dpQG,'<*ӻcaM<_I!7Lo\5H. 5Z¹d9ff7_b8 A%1K}HdJDoW(?0)4 c}D]K ”;.4fs(Bֿ B~}ˍR N&1]z@H4(+jDl$,gR;sRPTY9`ˤ9S.1kcdz>b$I${ıN7i< oqgEo<5dr@rk΅҅4*K-zQKp۵(R)SDވЯαk[7C|.\Fe`LИeB"NmUc4,)?272ehNZp*^40!F>NPUXDEg\jf7r >Kk@y%[ vP @y2 O񃓧p?{ٚ͛q0=+(f(|p} ʸ3 ٰAL6gId1!cO=gyBU.Ǹy"Fx{nFfT~Ϭ1N #:AZe:2:dRc3'L!\FY_ija`K!?xo 7%+ ڠcj>ΒДwmi VY{4VasySq~f/O|^Gwˁ44rVqKmy}g^+'fxJ̈|<;dZ!'پI1:{ϮDzb@0ŻBăY5󏱀 WrkSx9A+TѤ&6N?I?f=r&¶n?y( aJW4t^#'x#5a?Z^?K_kN؏r7 a7  `.wI  p"hA8u F7_@p  Z07 e8=rqxb 89ցif\M" ǏM@;['[#[+"@3rX C~_7݌1'b#d~mI; ~iI %5 */%V%-Gw'Je>3@A;\6UyGct"XLwOhb c?cbx bXlU+8nYxYm O[)Gi)C*C2&󮀠aƬQab-ҟ`b rぎo|Reg{y&Uqg`Ol|){ms\@| 1[{!S+Q1CY9켸*%j>8£6&N[gh|Y /GzӒ65J:Z+DZ*6 I(l+T ^a(6.0+ |N~aλrԱ"Mʹ€BruHXQ'l@A*(25~57Q(X5QIiLZ=N*ld`D"cD`g :ojDKV +xbCo~ĬCtX[Eg~u3Wx>DTr)>.v:3j@&VD;(,ňRCzY+/ of\#;Z2B8dOFjOsMEBEUv'u*eAS! .BډP3L݅ǔ :s5ʋ\wh|$3Ei 1$~ [3-qc\anq?$+}f.y}l}7m ;DF&e nטt7e4]ӐXj4K5vPIc`>6=FO3cG6d?*t\鑎׆>%M tV|1jb8|*5}`gb3O>!"օPM!5} C"`z^lSe9"{B?a"Aah.Q'A$σ,9bPo8hjAɗl:Z^Օ!@\w;;t~ܬU4Ds0u8?'m></aHc!9!BєEΫ'QֲrVX/!mNr`w=Z4-xqx6¯y8Ӿ#_"Ǟ0 CE.A%+윹/mOOy-KԨz F ?Ȯps [b(>Zk6}E5M~E:,$y9g>gĩ_IQ%w|W1J4&ԑz_{jqU1 a٢+x^E zMW֊st70)ComU~3J'Iz5^5Q:_cLd* a g{IcȧZ XS5tmֻޫ ^䷡p.g"怺; ɡCx? $(Sr0,Ѷq0iN;U0\oceg_yZQshZe}-jiKC7+"O`ȕ2TWw H`nmf263TRO'3Oei,KDZ/~$\X|ϫm+)'ח6!"y{s^Rݜ7ki+ -ӣ|iBVkU䩋)-jG8#r8z ɾ=7Tm ?NGis?Mΰ ~۝a# GY>OEF#-B"DEU<\he/Mt2_0x+u[w3RQÙC~%9JKthJYGv^+}g,y[FD-ɞt-%眣hQ7tdM"/4,NMl44ѱn:i'"cucβz6K:Jz(S7e>}+b(m.Tf+1\/o;o7Ӥ͢ۺ r_go!\ܓCR,Ir5<BU$RjykpK<5E2'I7a5Xlhl`8htVgCC5eŁ'ԟ nDߛ۬8^2{,L֔`'_,IXٹZLj#톜DQn A~n˭ iޢ g-SH\4yDw]*yYVd,wB۱GާZsy%i[fB]J7s6TWWΌ4iʋ4; >U#+і1}օj(㩗v6e?e;1on7 QArsD71"`/|EXެxX^ɽ8C"[#5 (Hnٶ '?<7~? Ϛ?Z<ϲg)9疈 !P|#pF@``Q=>wqq F݌^_C|!ow`.E`Kw7v2A`fŀP`x{ w;` N L!f@o5`ܿ( 0_1nvv?YH7#Ď 0s3 C7p愁9oosA_!0ߌ O >Eiu?oI¡9~!b+7_n? pqA_bopď~&7O'bFzk"FEܜ<FUvo'7G@B)ճql>4ibd2q|k,V1iqkFVa:eExP% qIu~.RKFŝo,zrU7 {e;i!)z)Y("w= {ޤjfԦ>ϰ4c 7r士c0MW+&w#њL#wt߹WU>!X~#i>ݓ±"m8 r; Bx(P͋,_ Bعޯ +!gcoQ>&JJl6׭[/|p؎yhD8XuF(SH4S. ٽ'gwޅk=zmڔL4]c+[Uk+A~G>"_ %K™xlKBt*<t"q/IT_ZgGCQm}+)c>TE#B:MKC⒜2v6Ռm"qS>Gc3 sͧ6s.mn,{-F[i |nG\L#vT -~J<7zzARh?.J}fQC4 60^ˮ7"(?A&?_6?<"Ce..O9v.Sn`& nPrAZ]_'Fgް/ w@Gx7rMG)ϫx,+}>G)<_H#WIߟs!sE1݌/ .Z(ӏ*H℈yc*sOI|=!YeE6Mm>X*ԉJŕFu^(-=PV,İ,H98rJV/GF7vФ{Or@l7?c _dQ>Y,hf I L#f)At%B !OziPh$2"U-AS =O1WHcaЊ!w|K,3t`Gji~8 8S*(juPzR/$?מOX—]I-WURDH,*/!6~FH ̘wRN$…8XZG+|gK 6pH́!h6uNm7ud(=JN])j\W~DL1+T"y{R)~pzPϕ+e;^Soq MM.&u@@ XU[m69oe>\ :FWZ#Jazk1y8{%d2IςyCdĤ޾A>dz@9 ܪRfymjpI,SVphj4P'V^4Jg\IA͛ |-Gyd+Sةt9ye>vj#:1bϻ@bً ]%̗P v{hk FS j8]H)E b (@)9{WJ'pP9*s k qyaݑ^UY {#Y`Mz WٻvS868d]cQl>:es=F5qZ))gH/O[;k0pŦsdgmqW+p6TLAE{ދ TؤqDks>O.=K}d64IM6 Y^52)G6k-)~l$)zSۚ+ ֬l g}&KtA(:JϱsoӐFYG礂#iSv /0hk($"i1O~_%ewb67\bncz#7wpt13td뭟~u1†&?-PFXN\AMDNX3899:~n+^u.h=Æ! 7?~ L~G76;)'C+s#!S+ڛM'k&DG@/Su}9Pin]ް#w7_;3o:z&0};(zC 3FX|":7퀀qGs_v& 9qgniA!(ec"(ׂ3@ZoQ]27U;v9 N';05f7,ddVh7ְ葕Sٻ GOIO~\TmX?^;][51EYatl̔<<S=(wjڪwn}I~Ȕʚoq-^D\>S aH9 YsXoK(y(|LxZ LԊMKJNʌ+ζ4{aj`[").5()"^͋Ne^~}*n.t,:9E㮲Vt"*=%\hh¤l'tz/ڤ(qو@d %[r>$RXoiQ܈ Mr-uTd )%jƧjȳ_ %jǤ9jT:ˌf%l/<=l*LHQ*_GUS61/&X՘+$XVphr>85E7\wIżzYœlT& 2{~0vjn##q~O eA};/>ԶٺQ`=qt{ nͦNSy.cQIj^qeM>~.;7-/ǽ>'Wr;jHABs2#{BoW۱c{[ K~AAH4}Tt^I.9#9Sb(ݚ#D&!7P;ģ/|4 e},")?cnk1ki7kn/_ƢaBf`h0@}ێjAԘwM| ([X\/D?SaލQ%ĵ-ܹgucUD;({WT,s`v~0sbN^RH--)3|Kͅ0]i|î…ɠ5I!I$AҢOM%)Qт54BdK/`')"R^UzH4yѾv-ڒE5] 7Two!Rٸ4G;E.uR-grޙ-$vT  Ƙٟ^컚 BfZ|[ƥ?HSTobwSJa\\*U_bUiؗeOԜR_u$u)Ms٫Ǻ6/7OG )OJ盧YS'LMwam!tΰ6@)o~) :- @{$N+JIqGObD}NSd&R4YC%Rg V6dLkR`/qO73lT;vJ e%. C=ԯBx6+C(J2zmϒe \u$x1T $6bц2B/SY=/x} +_d7FLƕ?ZNk5L_4QMчSǰUĊ<zYU\q#as@C\>}3yB @! S=ZO=5PD**Ur~osw+`0Uh{CxWn q4EpzQHR7dCޱV؝3/Te%Qj"}Y'jLgԘs >(_zƔXc9x U_h\ЙIc}h&C_C /({a'$[3.Z74%O3_ȫR[!wb@gG3V A O2I[zvIz4:&ӓ@!6l|"7"X#˔aȣӰ pIҖ<:fzff]G_kW3oݶ Q8u7$}˗P#E[~.P=ݬNg#=w :g)f߉[}KXW,¦:D |̣)k=Fklufj6f%M;dl* eu|T(r7*gY '6mTѾJ)7<ͽ&PI{5DRf0I5a_Doy>IP<_&U詊&P0/{;e~C KpNҢht&F9 ` Z6Fwt mYYvVmdu>ٓo| 7T?o TM>DsNȯuŝV)XZ2麬jz27$׃Zʺ*$ӈǡP( xo 9ϓWݗ ԢcU 1b& ll=4/ӥ7rJMsic|xnוK'k!B6 Wd_iK:2%-M('Rw|lu#mEfQؼ۳j%[uĺCU夡eBûdtp>kke4T馱X%KYm:WAeuALcsVkۏ,νJxhڴs|ccϟ#qT]+r2E٬tukl /1gHneZݟRx1T!͂1mwkzr8&lcɈQTʂۉy(&jfR%!\V}"ްLBI|D=X~WHk`.\_3|91|ҨCH5Q-厮Rݸ$&OV%+!_{"XߪL*'5I /i%7*urn"xcIdId7?L#+~a4;ۊnva&IsG ۨ@]"^^F{n;vt鋄@~i_NbVâ-Gm_E>B{v`PYN$<@ )I I~V4\]ߗ=WhG_^@޾oKx^Cv|kp=hUϱνT6dFSKZ^ =xxOʃ0j8h-h?KSykiIl#RzZC4rY$0[zfqq \)bry(=jvcr/bĒ(8j3A s0<ĬH2?zG!"dt$ Ī^|_(X132oimc:"lXW3faQnHьpz*[ aC]TF$!^!Ws&Ź"QX]^]qAdymZtgfn*-*>cdnj}=tGϚJH|9giYܠ;x(uMrfcM]K[#J1ds~9Mڲީ?/߀ U~>%1̆ghݢhuqCV2b+9&  ^#k` S (̲M\GŮ=SaggگdbJ[1#%{{Z˶inKI.VkUJi74TIcp'VӎSuŵ 9W. D&_327ocR>յjQH}|j&MWS2+aÿ( L:_gx8 cW |{.#M'İ8pҹLٴHSFInYذa_J_Q[d,56֬ڊ*.N54hvFgC*E "o%Ŝ*%_! VXc}(1-];_A0U%ޘGD7Lz`,+_PF';ʶ@MR;xjN wLF11J :"u [:mSt&KLESXn-eEk|>[G.Hxg.9q=ee b6E8uU9Wxj4b2M^HXc\KƿFXIppU)+#?ڌ9.*;}_Fӆc?-E˱T-Ѧ|n 44u8jZ+IFʎ"he\D_]= . ,V=."Ay<`ƀV@g =LڼXgFѯD*ԊW/u#reY*^yk82;jWQK0/!s>$$ O6nݯ}>U#+u5Uv\y]sJ&te# ޲Ƣ; (&S4" (ǿ+ƨ1踄|4=y7D9TG9F·94U}3cBABs%A*cL!ۓxw;\Oey1OL/wn%ϩBX+ۏMg3_6Fv. /=gum\2xL;F[o`// aE{Uu%ϻ|͝&I>~\8kA!uߛ,̬u׮%mN!*av]aN{x/rJYM,zq'ªߌ%x;H,edtVVHi(P[(+/f*;99 hmMT(He\wվl<+oJ-!ֈ 3$^M<Ɗ3MҋQ?Em] 3}(w崻/bzVqлK6<)TmM[e6c_bC9-i߸I*D*y7>,^pS** <Έ{W1%{YY)$^Yyzll,

[MfM4 yV*ɶEͮ7?*Fôh]u/RPDQ>"|bV A`l1a_6]آJ?d_}!>NJDsb#; /: >#'dA„O^.ޕPc_6# 4,Bv JY `TlNP|I)uUf'fTt],zf~΋D0ɋ"[.=S#nQh= İ/tLNM飥p _-&:OS plp4=k8ht2¨EvT%(ǧ&F2DJ6w&l㖏׿HǂSN7ٸR#ެ2ZdZ\D&V^_dj[~+x-ę$[·v{QiLu+,vL3sp,O lL|)xqNZxb͈Ј:RwSDY1+/96*wtF\g?~N,x.{ߗڙ">l:iJ~zVTJsT(>ޒ2qLQ_=d5 Sn<%/UɕsPB[~v*g0 |{i#ۡzb}0,.4\†pRH#p*@d%ePiq.}{@|V=.|Nđ*s>r)('sbB1åCh(U9#Q<)+AR|vG2+T}Q喗cS[qO$4hK%(:ARVpۡ⍤ X]TęraHË&f!{31Qx,%)󞽹`jFp Vf*DHgP/R.MW7{^/ &Dbb߇;6{>1/7Lz $} r(اV^XH]tĒnY0U-+_<-s͹hH7Jʯnll?c 5ɚ\!6m;re)Ɲ r#t^qG~M,.7"½NL2u3f@u=ADŝ 1 uRF~Y+Ş/fسߺi+.9IWQ{25s66NI9N%)E'YgxNW8QiJ~ZS[ЪUe6؞}Y)#\ lxJ4ypMK##y/wY &Zs_~{yJ%$_!osI-S0HvAQ^:z@04\^X ˮ(aEQƬ_+]*s?-*[u] www¡pwwwww)ݡpw(V{}n{A,ș9W&9X#ә>($X1M{Zk @zFG]:ljD R?9c#>foS0rɣz5\3Stb)5Ut6en]VhhlWh'#t 6$YDb̵YO.29d*¥QTy`D1^ ڪ ׁϭr3d3I̔Ow Eg^ޑѻ %:lvN ?*_MJ_C)thRRϠ`o!E!@p_x Ö~;뛔g{NEI%ZjBe-ܩk lc;<S9/otdOJ;j.8oJnnp@ ݖM%A!t%'&#\âƿenNuBclہcZ~FAMwIe?zqa8Ԥ(! _U3F4}̀%OCϠJHN)P^86umGԣw5[vaqynj.m?#ژB8jѴJqԟݮl:?+Au4l}y ĸ o}ZnfvF9`CArJ Q Jɳ)OGW"a?,!K {_9 #_Hw,cO T20;?`心/iľLmeι/Z-J#p$2;;]LH10xLl Vt}/wqyyxĝ顥Sy[y]Hbu|g,3"PDeׯ@%NBK&K4 @E%Ps O,!WY5KB%MjtFݰ\I8`%jxQG_#8c|X,Xp[/W GƆܠb@?xGa(v }dnicRNTvvo׳}=! r|(x:cTm 0<+Ҧ鉁τd·l$!@XA0~~lz\5wp0yƛ}b~}LYƢ$ ѵ-yxU1ϴX [( @ HN1V2!`,I nNƈ?O||s}@P>A+ K}1ܛ|LLe>Eȁyȑ #lCjX$Bř&s2d W%RfJs;[@t94[jVU_ ;&0s-VG)[}ݢ{;%!Mu΍ftBaW+BT4i݅Ij^yzys3`7XY>G0mI`\AOCPƙ<02@pg([<68uM4ng WC)HmAUdTj@UݽI)1yS!ZYtMʓM]Ҵ >}L.C@U4!ĀF jC}1ԪG@ bڀzq =u=Ɔ4 ΃}6L#ܑ: ͝C پDPfǔ^oAFŽ":6ik J@/-/n'{- ߚ(΁|-S~{u)#\'?3w\7moނS/CdՕ 믳9ਸjXRt@۞{Ӏ/d=-)Hh=Y! MNHlgdPKF ?$S`{^1 Eu|5Wz~-6sE6uFc΢WQ1kᑔ LAz*RFs! )RKC4PED/2Ή~Y$ke F7OEk-ƕ)$/?Zo^,տ6~^a &3kgCᨿwdHj;]Ξ9z<@Q0Z&#"FaqFy聪`ކ"6Bi9D'"kV_4ʝnו=Q}aO7lz!j%=H;=Jú9p˳7fO+G*AO0. 4|gpxzhi!=Xo46Qx"vWD_0Bqo)> vBn6"" gYu{;鷬pQ۝Փncf<3BFj607ĞUu}p)cy7UT,d\0Sc Ju.ޞcOjdaNKReqF &!j:*V4WFPrz%9Tɝ #~,;7Oy~$ $j)m@oo5'] m{dn6Q%&ѵBrm΄MڮǧMAn~ZJΗ!&h]rqtѼ `}Sb+]b~nƲ-#T9l L/a v</`߆mmU%%q9~y??;R0;lbmmF`O +yly/l3ql30YYYmڎWь?O5Ǘ)͍;vp(!$#$#AwBA%>̐9M-{~[~˟$2զSƯ0:}ƾ!/YTuf~q@Ѝ,OC~i&|W[nhJV  |D?![OLJ | ~מ٧Ksl'sgbi<@OO<\j14]8'|0sjmY˸(O=wO O;w/ayiPS>??zEPzpdHLHLJ:3aVھDV0()eLp6N,w0<?<7"/ҍ0) ?L؞ @@[ʑkAl2}3&aǗ*O05v  @"J.x.3c䃤,OިiC 5sgPӋG^s\[A|zխz/槪+ 鷄Wv s3" sd 2T& ^ ۧ{fM+ p$>>6T> +ټs\8Oq˪v斒<ՁMKYrGsEq ïЫ]Fdt.?M8a!U+=XMB#Rȍa bMyQ#He1Qz\ ]F^Z߫cS_莃gژ[%1`eA%87Ä5:L? O(u0Anh-@ ‘f5V/̚g/<#6Ћ=G%Jw>ﰴ~6:A cBOҝ*+dF+O[wR-c#|y [<35ɑR^Ͷ x}xO}WZy5j?g;f(rDX-XSm9οgA~fY* ŵvYd}"*>*7BލQtF$M a°ƈNf%_pW 3C&L+!QoT,8F':yaAeIק JU>o:_-v, rEIÎ3ѡT.@!ӥw+"RPCxKjbM.#i3IKnφYo38}Z̓#%.<&ak pz%MRvYE2옜 r1wߢ}}[[0QW0JH[\(OG9-)6:ԗf˳Ȧe; 6&2J︯ b%/食Q x;,iˍG_AL94l6-aR7 5Lѹ,7{ڎu:ffKҦV{Etj@zޞs6)J:w"y1Zf*s wS#KiE_̅&\ʟSBɘެ Jl^-ϋnB2Myl-}_4K]<7iyȾ"p!23Bۡg 8.+azq.b|%2.YW<{ۊnk9l aM-zWV0xmdqIHTӍ]~ĕ$jEH]oCu ss"K`qhi3G~m%,^ph2#VNg{:8)شо\Z]큹vWïy eébP?-:3ЈPP qt*֣̗7ru zEcܾ`[F?ո V#r cJUD f|SR.Kgqw?˂:cI`&%p??Wi`e,"e\5 eA%/)h9J8»JD@[Dc}7$d:uXǁ{#ZR9SCJ5ا^sAUmpmxіt BL#PC)u* /}P~u$lJewΠ6fj[}T81ECTD^CXX?]NɃl{N3d5\Ůc#<=)5B d(_B4Stv]e%eFS1Jegxk:J7n-/,c.&v伎).%q=Ǽ]@M/he&ݷZs/..g [;iKRuZ3$%drh|y_-YVF7ԿT(/ynG`VDE .$B=;a{aQvvIS g(X76#}Z֙c!*W>kVI\Ut0{:y]Wx10drV[D a)V˸{}! sr3󆪂 [ch^A25#E KWγL LR4:Zf:X1e9K5Gm$_"ٔDCaF8@W&ӀpZ^mra rKSIGEteM8pG#J=शU7&iy*f#P9nMLH+}m-3or)I;uv%RGjXq!t*F6T9@M!22ng0[zz/zιQ o}nn'YQ<q\KDl{[Q!򝁘rLaσ:ڽ8ƃ"0`OXfwdwxZS~ýPjx nrc-Cfn?zj䬅ɍ bVf2|Q<U'$[gy#{Z+WH6RuqEuZjTuZpKUj=2tv2 [G85 en5t~Tct\+bJc&y:#C0 f.(TU{1^1wP$"ٛƷi JXLYŤH bA}XC yzIUm+vcوk+p; q<1}|J)wݲJ(%cD\ < Z!2 m()~tSxyZ1+rcvM'ƁzvdmGV@`@P[AMU?:{.bD"bXH['aoG,ag(}2̼r3dk?9;-נǏߡ/"Vyݒp}?I8aRc+Xn)qˆMP'q6tpo) C_n׶xqziIՇY G7*GrH?_t2Jc۽jD(SkfPr98e-*w<,o`:uxE9NUھmQ7Kh }+W_,wj]%ƈ;.XQHszYGKjeqmQ16Fx{Թ*Y\mk;8t~eҖ~`fh9c3њaICrI%!ۜϯ2ћI 1N-JJ3fo#:_bTR9d']3=l9SE_В 1Jcz(]D/=3Oy6wtj=&0vd!P<$;Yeo㎴Ka+3ƫR?vu *ܸ:LH ddA-okv~G?3{y>M{ %һwͽN)? ^Si-Ae ^uoQ )צ%WŜJyMPPI%س.,Bj%t^|#=ˊIQ,FqgLFgEZpcN3mhv#UZ犬u$Ax>|V 4}<0"G% ßI$͟UeɛOi&JZ0i8kpzm;S;35$ '?  ?K-$tssc韍iJ-yzͲe;6M33^5'+㿞ogv_33-?Vg]hW׽9L9+3 #9ѝI̬hYBǏsX~߰_Ӊ1N ,tlNٙ~]mi(B}l|HZJy*}ߎWgf9DN A&ƀQpy-11Xٲx+Bmp hC?L[F'gcom}WB#%{-b̏!`]Q_Ea|о+8`0\NNs_?8PYP`r`>@ZLǻ<@zKbW0?%# q |cvv D}{ |6VedOj$a O5Yi`5z]S3]hG@mbE})@5%xlIsݙ\'bfwC,N` 2E-%iylj]u*۔qq[|*v-{H'l我H{E,'%S3SUB'_^3ejj !ޫAg7!<#[(f);PAA{j((Y9EX_V r 8S #%p<`~jCטȯێ=LGgYygYc\;Knc^(: ٚ4ҫlm^ʌ^t,{5XuƳYױ=kNUq`mJ=B!!ljѓv<7U]9N3QZ#MWԾ Yv Z.{c_QξS0e1ɜ Es`yTF [=n>P7l{\CeVaeQ%j\7GIH~Z%w5O%dAqb]Ưg2M-Ws憻j\.G[7Ii˖] æ]ktV2?A0@Shp3O+H6 d.w{il5O:Ww+_Ey0g8,EHEDc_>;jtA]=xf8 ^M޵Fgw+vQ 3YQ_-`aQ| @T;G8*@"Ԫ:j`sxќbY3R0|5k#k=,%Mmuμ{Wm $v:>lFryҝzHMD>\M$,ӻJp^4ut3 J0@nQB"Y}gtCM_ȤXQ6HvVp&S6eʜ':یkl#Tp#:=l:U 7D+X/ٴZ%s?iK\ZYL-4`む/75@w[M{+aRT 8\Tٖ2eJYVLImtE{ݦϘy)mKImV{ =܌p^#=PuW^Υi @t.aII*,P@e\I{`'p/'ܧYsQZ7{Mj]v;0|$"3 v y8B2v%wNŧD`ɝȢm9lD>9>,΍yT)/CG|b_K#ntC Ș0}OW8qOWU%TWYW?-?d~`$$nd{7{?O(T?xHI]}lG.}gK+#?"c`deB L.D6Ug4rX4Z.5/5ZYMH,u3}z\z5zt^?LXls.6,|!)M%)"BOL9C%#Fql`_fz S&/  o{ztygHU7gjyd7Gwx\\Zց՝P g-` ojb)Tn3 8Og0PԛD<*@Cu=P v* ߲/~'[0ROgJ]XfbŢm('025[ۧeKM#JMS5(>>$B=KHJR+' J{1H.RbRlgwڰĎ.ۮ{S(sw:`=sc#@?AY3q'kkS+>j6&ut _}0Lm?F^6?uY똞A59ԁ? հ>]6LBxc"^mA?N@\ü F8:| 4Bڀ~iH[uo~L79=펀Π= P}›6/E| i~i=%ῆ-“ 有:TT={S0G@ֹ1vOg@-1XH:ӷb^LÄZ߻+7O)()D_-Oj|.xCW4TOh~LXk:3 /]7h{/hkfK|Ձy ħ_A$'[ǽC`1|:ԟ h*ޟeťLG.:@G'xM@Z |9dSy>%N]Bג(r ~ځ1}pFҎXR+jCĸt r_;)!1x7`עj۹ pqe[WQe8xǭ"U`a)gCzclpF+hRm+b #\ŁwOhhļ}DT ;!<Uگ@CqF )͏j66 | O!(GȚgAWn@ =-YV;nn4$kF@ %٠\k3~S;L8ϫ}3E8ca~!FI-Ɇ;Q 4$$;|CC({+@q4a)FI#iإIw)JIt^aFj&!/=< Q[}7%H IAs R0tng.&2~+S!Wf쟎"2^$X[3.8<(ˠB CmDx\E$:"u|:2OگNL31uv v/Ni~Cy}%g(XC]BŧUU*r0Bcvu )pf7LGYm}S%x:+NS7 T4́ʖ%ݘGđ!| OkGX+rSJZ9'CiuK(ot4{DiǨVzhs2^Ϝ;EjC%ir m+ijN"; 2Hc:R+qBsox?w0uId?JG yIz8V'^{-oN&zg {gS7q+*2jK.h00GSݥe>#Si]ۗƶVl۶b;YXm۶۶ֿ}}9ώ1>='&qkW|YY%r;#\i5*0C-+9-wEjhq7qp9}{Vk3hQ$t|`(=[KA׼>b~0ӣ^ZH|kEVytHMȰmEM3CCc4>js|X ԔܔqfT(/|tͬp4V@:΅4C,7 ./iF kց~/~}gxRӕ}K[hjb4Ƀ'լH*ݾk-Vħz"rg=TaVkbߨA]]YO(ٷsIo{%sU}ϫN*~Q]vzN˞3H],֮)c]`>_KHFnv:>JE'cEFJyZ*n9Dަřkik@ah)ybVlFQʰq:؇4 hrI ;Gg?OOqYY{vM&x vYQ5/eXZqs[%Vw}1J~`P*d n)Kvluv]_t/ho78KjDߛ-Ena:1s^3`4E`ٲ^MāZ0! ~?8"]%'Nu2<۠SDb_!> G5@JZo k6~ߗКQi*ջ+T2*zYQQ]ZP"ax`;(rܮw<6*'O1m4\9.lrO٦c K|d֌e%. H/Q*F[[ Ɠ&%?]p  vznƎ4(c[.y2 *?Bb]Ri p(2U}ج j.&Itafxg|0(0 LG+X:1+Cla%H ⑚/&gǮ?B #FbzJ}NC%MHEm6FW$F Kd[_\?sp.:1Cb(#Mui vh%xsKJKM&n֛*;0(1n;2:X+`14~jM(ၙN?U JzGƳ >xRM L>Vu";xN/;.jkޟKjKDŃz?aK I=,s&8xz빢8dyC|=RdM[1OLPW;kM:` I! Vy5e<㋾<ۧPŝQLI7 z#~{ f`0 4d,1wh>a,yD]DgV;W̮c*n`Tx3:wlVm`4jvl9) UrhdTCQ?3!ڡD{%9Bf 'W\ e뺛xx;\zά/;QwuS~o]dv5yAUbܱ4DR>T>ɣ`V2W]RV[)*M6ޚR\-IQG"kl\ԁh,H7W5^9s8J6Ja o6Όi 0܍BWB4hC^ľyQ-EBe ,2MyƮ~O,UTڬӧ_g_@nO?j~a _7zXpEֆkҼkw)Q򛦒j!K'C^A[nMUd01k ]/څ!>+Q~ҼO_D :=.wA;2<0lߧ:OSDڤf%fep~[Zo l%ʹ<6<^5*LaJL-`[riCaVT*vTPmLˤ·6MY|tOX]9SeY bߧN\Dҵ_\49{՞^)|Ͻ0pzDT囕C}!6z7Ǥ e )lKn!{vN>+xQh\֬ nQ9uW=.Oѻ4Y۟cTpBwk1s٥>Adfg1ïF4z'a LN[a~$I_4ĝGKpEw.+ jl=i|TI^jk.|(SPjps+C7bt:NUh[ì`;^o Yf,>M1nN_':W ׫+/ZDZ? ӊ`{]?-b.~1A}/:vn>X"};EWm1⤲ҽdOF۽ .L`#kgnA7R {BpL~NVC<:i&L>D2NJz UTl.GE% (nK{Ꜫ`ÿލ `ZɆeK9=]|ÚDƴM]ף(Vw;,ןw1*d(kݬ/oSl/UT9e ##ʡ1gUwތƑܢ@P[46BݏB4l#OFaF)-4!O!wɧZ<- /UA_CѪK7 &;N㫛Bzjk#frc%c#`}r!B݉nCFt1 X>$IX\~b>8+y{zjP[gǑ;uWjb#CK ߬@u J]T s/nYx)P^kcA`f"y0Ԃa^gvl(Vrd?HTqd<[(V$sӀ>0eCf ,8ǭ9N,-z4.դ|_.YS7'ohO&}C+vf?YkŽ}U%{w Hn-Ľnb6Zw. q-LwLŻUކK0>wuw͠ {h9yKӹs)a{~`I΃cXB;oe] hcxٝ:J+(c~ׄ6"P-H "f]i&2ĞS|0qZtkJ?.b½E.GiaȡFЖ|0ٺd;-=m\չQF\mkg< ^=l_iVٛ|hb&s1}*T^Zh%6XCH<=Ͱ0.de$'u8yW|=J&odwl͟e~ϾAH9aP?ȼ>Z9P3&`?ׯMk̟QӶrAU+cqDבOH W<%{~L됒F ߂"FD˅nQ >xa94 J.:뷂\2.^L$K+oT{M~mư_pHSXq ]ciH RV<@l R> ICHlQQz#]ϭ%lD25\6"|}(1iNBJl̦l"H쳜\O9uה]͙hh6|J` |;7W4SKM'[§l8]dC' !(yGw2$YX3 }eR~wb`Lg"DPU2d0(P ӃbKC|x'㔤vG&V71ҋP,zvR(7bUb]hMFG[yB8JǦg3T7:|Iw\/Mq n]KEb^]<[ِ@]XKp Dmg|BR2 O mLϟoJ:JC]TȘcI0a1lg(4& C]/tGȪ$Cբtio\}Y%}@wM-}Ν UYeyĭO |fA' =dցRsf%RS~xUL=NޙF xH9F vP"s ^ Ij(Y$d~'Ay%(y~C_NK&X]. cR'80nByrT@Hx9<~Jt Kh<D"0Xp%b ?܌^!{(+-}n#mogD.6Ƽ'wS:۩iLl<nƮr=h )N,*'O-hQ$BP 9w $55\+3`x!JU,AHRq}tZݐ er6DtuR!z=C%Z_AXC2ZE8,H̓%ʣ"aɚ>{Tesg"!GqR?z@RQ:?ll/ ɯc{[>yJ$J;vIOn݅8v7'%NIrSڣc^^zRO?\늭9 ~\Ѱ6Cg/\D]>'0Uz*0u1i{yR5@ ,O  FP(pF+]>it&L2bGbƛۊ!vC=#ń#-< 94IX7.+vB#F OJOIؤ,@.c"63qHqԬ,Bܐ!6P*!_xf%فm]KգȔ7⥴xoz*dFuK)K]QZg}|#ipĶA8\ς89p(:ƊNwTvE/шZcE.Xf)ɂ7Lz vz8F:V44PvX(D)k2szHx Un-48Y1Gvɲlj"³űO $gKgI:~X̊Vfd+ \Q$+$2*=ΡAטbJ 8k L>*IQ,?|LodlLB/t ]XFB#O=nGȲȊ<ܘ'3}iadmD— +k0\.uOؓ'~}6Vd\bDpOni՘2NdpQǓ͢}={D@%Ry[N3)p(X*Mzf}9:~@md/9ff }8q~JyFW:x<sdt﹑{5qe2/>mZ5LܓgR0'ҭ?6È`Sz$:2Vp :%>_@+htZ(҂hn;GM(:dw~;u`%"(L*(cmʀع!ه  _޲J }[毕xEps!mӹ_ D4[REΨX;;lSM%}Srb&Lp0u-: gA Xe;{vHznhW!!FU29"H[?J'k.w/eQbx_hW=Jtl"_ҍMSA7|Wfw~Tc$bWAjzZ?C|Uӗ bmIURCi'.П?Ҭ=kSm9]Azt/*?ϘӌFMIAO }ho0lȑqC-T}uF,\igg2DDO:Ho5/IDSZ[]{$:pFn<ԛ;kJmŞJ!+jIc2Z m l&HոݜbG .]Ӏ*_7GB/ ҂q:K+t=B O`SsƎ̴&(t%{`Ev{oC-<,Besԗ M虮Eћ}xʨy}HNqSS*)#hlXe`&i֜xij%}7s~,B+K7'0T^pf|ֽn\-*UHq]GWJLjΐ@Tknnb42/Ofk >ͬQ}2{' М\2cռ6fCDb±y<1{<<0ahc,-To$ʗ_}OZ5>v;G.GR/ =B48tN@gr'@.gq EW$%qM\ ިz# {4C.̬6yY']j 6WOd#&*ԇp?(Uk'UuP@s_UNiE1CW !~}4uo "^(Cpv0 !{PC(!?q8o:Pn`ŮFT})OʌIT`vE*&T\hC"D (h ,Bj9u<-|J#5 U;shDZ*oϞZ6PEho=CwM>ubKkA Vek: Oh44ͺ'SCGP!K#U`hg:I͒:c%[Nĥ_:,Z ꅐmЃ*<[&fLu' ^瑌1ޕ관}eE2z鈚uObe{3=`+iF\,= q7h;[&[dfZ ω/N>G|VRwi}c<`ܹȋWl8^!=DLe;cy495H>''IS?@?^4,gOW>wS[R$Á<]7n9`co!7ֆHՊf ) ƑXGO'*kNZ:RwCܻ_ L.Ή^ L)nC(tL屣*-Җʗ%c+<77Lg2Уmg;vOT$nuZQӧٕ޺ڏb1<=,GޜI"~ ՒQ ~1GKwaSμ'Wi\X9v_]J,řwov(*1sエk*UUNUT- (?k^k / G#/j15 .QұdBNM osNDdKt3J Dy[@uH#n D e >nm틌rY[>3Pƈ.r!C 1t AX/g1-tMqrԹwS`@LQn&6@tX P I\dFwۆsSlb Q5ygcmoS_$I;T‘dǐp>LT(m7ɸX@;dY޼W{O582/{Ξ?Az U,NtlcfB8Ȼ Tk=A|z ^}ߨ ڹ Y  LFo_~wxV Olj>a`d"b?S Skm MlML?*ll dv_r<'6H 1q I) 2 r J *  XBf 0OĐ + w ?],\~Tϟ?z` ^I_;҂m,LlL"b/6_=*9X8n3s_dadgFo_ճp1-X*FOB|?z21#; bUB@YY]rxKWVmao9_)L=B+_$NBwgYwg)1?Ű,rr{-,;IFzsUa_k˞-E_Uk2k 'ܬRR kJFjEG\<6pSt=,IU1Bh#|@{ .b M !$](9@#!b%P?>d`\ rAsS;c_&Hp @PAnHK"L '} 5$װ騨P`|@jHڞr 87V)%WT@@lpg!+-zw6 S J F_k.|'3/+@.N@K*lgi> mO?r4Mc4-^9^[\k5<. )\Gdw'դ.{ GA2{I9< 9݈>ޯ)*/}F'"{D ;@.!m A$@n0~sx6| Aihs}#}g2\C ML-!|ٷNc~K}fHA=g}rIr܂&nr~{ Ūoz>v5~ ۯ~7L_!~`q}S >@We|;} _ iEz K5j t{'zo^߂/;ࣟ1X7S߃_4$$ch;77Nd @HH/=}ٶH#7ߦ8/0/ "Nb^2맲L}?C1U GB=CnF8Wn5gxY"j]Y~?ZJ׽-m J7ճ B0_p~UVt?CZ0LZ~d"JxK}m4:.`r}{XuOU{Ph9yUm<|`cFdSP $AcdqZ:S3IXZd@gه:sE6<6ҿfx> m=*75ajE1jFx"oԞyjҢKɟn{ׄNmO'^+r}i&K84s )SK, E1qsuP4 =C`Ot?L(0Zvh9<eUEQ 0V{-R;i_toqguǨĝ9d]/gvwK0n)F y?@$TޗrdD^ף y1 #K~һ˧v>'FlL ?0bG3@׾UJi{Əߔ΋%`ƖEc 9I5ƐUBFw i{Jx>Txs%.e>+ ?M+ѣ<@3PGƻ"ۀ`DIm Z/8d.1&u jH@/t7&5~r(L4DM3G02悜Qz6[tesiQݕ}:\&PeצW%rː\)tz{%Wh;J`}"鱅Ä5qO.e%-ǿ:tE$U7-3H&S?f,$>x Ԍ n람V7XoVqqE 34#NGKp"ّuY4t|&I1Gdnˍ@}ӈvP3es(; coGˎ1;uYVH"z4ĐVb›2 t4S9kL6:0C:֤ڛ.mJuFJ Q}PxR?_QVk>cB9Mc{Zީ1$~Idt)(uFqJY&@Z)Fiml!m};dNY%P =Q}">v3B>1Xߛ*k1N˼ѡ2J7ۗkGBr80Ðwx稁^PP)҉49IJ6&|"pIt\Yu`4Wrz]&i\NqTQWpyd6gĐ#==Im=o.WX[6`HQXYݨZo QOUk+v7}&z6Gj F; Xusv5pGݓ/ M3n매c@-$>Fv\~\ipr:[:eNCyoDȑJA2S;bdɕ 5EKw cMSYֶ2TԕVYRBΜ !_n eqM>{0zIªjRhFZt'!WIS]yL?2صV$K~6r;~R;gR*^2O,J?Y_B:$Ϟ|:Gܼeю}4 ,Nm\ݡj'gWP3K Mqvhg\  K s (cl/o _+2{;t+/!Rאz?bwjF;4& 3iwf~z헧d|Sp DV5>O̭iky<i24]~ 杅\ІqJZd:)NAU9ʉƑČp?ŬM𾈂84܍,Uj+'FE-ȵ{O͎WDZ)hIkLSsdXֱK "G'"WU yܕ<&@FUeѓȓKg.jKj>?gHJkSz)xx1,I`~s]k՞ H +qՈF{#d`KPYR>PmWIAJXp}ww.Ȃ*c8M]vplt!WE4ex^I]' ҜjCq]Ӱg>Ii&olCh*|fFLTDSHRx,"dh~=i3ֽtvضm۶m[۶m۶m7=gٳޫZZGݹ种먎Lp<K3+^v|@Qy,1ž+RNG`h$݋/A uPC&W̽Z]|:IEU~/1{mt_N;, 4d6N9VQ-Oru*sGgP(bUl@AסZ䉃!zwl`j Ƿxp5 I훂\NڞkylD-Kd5ʓ6@s5u. < ^ZlDug e˜ǧz* 86135ޖ־¢0aϋ&y4Y8mE!~I{ADIGJd+eX_Ν3@WÃ_[?ӴZHp$QwYKU މS q}k Tc,<" O'麸W}5߂y ѯUn myQ5B}\ɪu7I&/&fO8W#`3/%2PBpy߼3d;=5MTef'DלHu-oLG*/gd(GZĊ~2xΪ-)8FoJN +lnߨYl3C;c-!܏f}2VX4@A$ 1`0Uݱ>D;8ƗV)݅v7Btm/r],; ^Tw8 #D$BTVǰ~,Ԩ3h>7)FaKYQZa5nBg hqgI[X{bݦf-M>F`m~Չ n9M~wQE5er=U.T2.Ed~+P}=v Rߓ Ӗ>.Bz4a5^FUY .Ta- 5A?0eP{s`ga&ȶ@N7Δ[p͝CyuNq7D0ꀔL5[uIB .֒2]R^@=eyץ.!OI6Ix"i:%#6¤Ku| Ve+9>dkۂfi/|g&B AIUdzX#mٖNh}pNr VS9;`ne+\BBO|H8Se.1Y^Unz.35v|IZ߹z'\{{̮pP9syD_h6f]R"+xKBv3(@0#cce9W1: `mbY@S4z_g)~2w1~>&nR_[Ь*MfTdGME`x{ԿN f>d`mJ~gΌE- 2- (bG -jj<ڐiyo%WI:i7yN^*1;8vm-}ֺ-p:Q52$ "@J@6$.f/xZ&ն/x ̸7OՏEI puf2hO"oJ%j|=[s. pK{Ά$t=Br@hB}tk/Fӑf5Py_o4Q 4.k}L'Y)]Ȅӯ }HJ}twOj]*ŇS|gJ_e.Y#4NQT] rǗ3#mINȘb(^P~۹훤38cc~gudT5!ބxE٣e0\Ƿ=c2/1j;RN?P1ț ϯ&%?uRX%sTg0Q ZfC:V W,aRh*MfPmI%>E} Myz=GTΪpU/dqo%Qq"By0;3&veXc7X*X1Mi,"7ūX s!'>-AV_ȴ=Fo{YzSO$i\6%~A 5 l'TenT#ȑ}}Ǐ@!v᭏L*?cҶ i=v퍱f.^sUn4-q0gRc|'FS&19nb<-f7=܂8N^Xv~.T[[V>^Ko(?N͓+\QU|x 6Mk.қJ씙A"܇7 r\q5$.z/Tv5w,"6מG!1ؐd9%*^!V){ߕTBy]_+} TEOJ#h2w>i{9k|PephN:d27JFtg"+ʉ5 msT LhhR54آ+e lcbc>?ruz-va֝bI`LL%P"dlT`T<]ޏwة%Br6_02V'Z@&j;B ~ݠF}ܻVٳ$:'vR?F$Մ.-lkKUA`҇l#M6 &!ǀ|7~WIy-y/YŘ ɗ>,tv\=x<îKmaw6'tt|^e6^̇&IsJ⠕oW(ۢ RbcPgƙq[3U[_Dn-McM(V)vJS ևRb'!vsEԭFys2NDǗ!KCg`\Z=U;o\U<k`h{~ꫩ r i:NtL~ b+pbte%3KɈVW_"k~5wn$֠6T|g l zT 6]8 $8EmU5v&79-zM'R<]T.Q)Cscaf)-P˳걽2(W,S)Cam}`3`tlr/ o4iD;cL¡IXʴ)@Γ4ɖЩpdta(ӱg  s\[*cw";-q9ZkWs76@&fSU, ¡=| )((6m"A7R-x1 +m>C/Qhx7vQ7 q/A$EQ/a,Y٩%!<#y<%įqwa~buQ}F߹.2+t*>L>om7YP!YBm)<%A5L+$v!m ͣY\]"l􅃈k(aN@|r-2fǕSk"'&TnP ti_-]td1鯖h Tlm<`xקv϶ԎǴg-I'tah[3m+ I(<^xY,P_:$Px@&>[#ϵ$c9z7> cp֋gJ~)?.:PD\bN\wT$rX\@xEy_~2!fRQ'oǫ£3X'E} teقUʗ][h9m_NEjv#HLHG91M -eyN]Pߢ:](fDhE-Gʘt'(u"mM (6R`{!I]bQa'i"RbӴ(ԋM8,ՓQMf8@bӖ(~|a!#73l9(td ͌?(ݘ-=kGI˰ABƮ@= })#WWn&oR!U h{H N  A.u[kҴJvHG s.0to,]T2R4)-ф3kdՁQm\.Vfo-^ٌx߭ȅ[PV%.ܗ~AIa$2#̗\nޫā> >T!2:OxP@)N 9ҵ~qziSEVDy ji~-h@v1SsXW3]Ld㰄LIXEjFQi3O`j\}qbC$(⫃=]K iմI2Y뀡F E^ %>]t>K[VUy vK҈ۑ?Ne`~M]M2~\+Hp\- c~&c$LIw=!K¸BƘJt61H$w.1)6b(ތ=O92HgJK \>8L7u-<j߷qj{$DAoZ̙ЀvXbz!MEĕFK|xUJ=]͢c*Z ˛e1u0אPFC Srm:t>yHXwQbPZ-5X@N146XX7 L!]9ƷZhN;@69~ݽY8%t%k ݶD˖$I[x3l4GK#M#17"M$GEk5W )G_P3!dK `fQ͌P!lFCWCd^4ձrA:"FFpd 3K;0w-LS\RLY% qN$ym3(3 ;t@)U"}\@ʮ7kg~JIfla MhS4 YIӛ;kl.dl~K|4.ҾxNrOAlf(< ~9GG%H#k9ϸ?4-Pt2|T~#KY˵#7aBj*F\L;Z5imj҇c>mOp1cRZH,K3ݘJ1ΡN"r7!Aے/(Yւ帽}*w Y)m:^Ý~.%9,Sԗ۫œў \r:t%N!C^\=}jiTV8R̈́$qL>j+cX~]U=4˵,TBɔnD:p;5Ōw.H(/\"O P-HqH|7㵷Tb"{:R/Oc&~MSP 'lNQ:σJRv :X8(G u-!j#Tc. o|K#UZmL>6Ԕb<װ+ࢊ'@"]XDCzt=܀&ٜCTo5ҍ10H0U OH<[8-'SᶲfLKO~TGЬ3V1vwr28TC?MLlK.6د(k!WAGAD"fxuZ `j򓑰ƃ 1\=p{*>a98,"*Z9B !} 'buGqw6>D՝.gHL-726[Nn i8-QT* r,r?\wD|2ZkXG>jƯ 4>㇡s ͪ-zNi)MqojU~ <("[e ӷ ,+QX=B'oӪ )+b1c_:ޗZ߆vkJsۡaW6/ZDdҩK MV0Xl?ȝg]&$.?QčӢ{Wg+P`Ah̓EC[ 8gZK`gt: `3X8y,`H:yfLJP3賴vPtc)cw;WK}%'y1[IvKwsl{Y2[<>X <"Kp@I2Ta-OЩߕ H)I 3M/}2 @?Zt_?tX4tX EmϘkCJAZHc{.D Lo>??oB7{ny4 ez@0oZJß-RC?V&J*@T.C@陙 Qa"$o-Qa<{zEԴYt(=FڧiTڧ|f"~#QÖ7/7'o{7o yf'`@n@>PcXR@@CèV4^>1҄A& 9J![_ah, /k'SưK1C.¯RUcMd`uK "}¢lD; KyV*D (>$מ"ZUVOt]o9A^̀8^#)YI=UȌ> NC:LZߑw~P7h"ƞCaľ7Oh22H<^Q!vjD^ly:bQ;[-B f*F EDzykZ a4N)E)Y,E>^b 04īRM<īlwloJ 0VƮ[kF FU(gp@^{G,3ܨ]5 _ok5e 8SJ.maLPE}7Mk (C Y3n9I^|2(Q .wX5gDG њ/Im Ws_JGKUۓOcJpNbHq[`\U9˔Q hrpwr>M]?BmN9/0>E7*e| .Pt: y\ҎFdK97X#_V“'AAiEŠRnFi^yS%.Au8ŧxάIThROHGa5 _N$iJѓ(*(g̉Jfnf"[.h>i4&\mũmwYL~b)B/ZWBMG|ZU :䪫 )݂ޗ(3*=(16]7X˻YTbStS#gE~[Oay7mhpr qxya6]w !G_n3\$1ߺs30Zw tG}Th *99H.t{٫7) וֹ*q<m5'=ܜ7W\}J5h ? Mef^yEkPdT[}(/前9Χh qFȔ98D ep7h<5Q[ө%`ʱU*RT e7MBqWaވ |m.js=sp/UX=R `A豾8KRo . 2Eڸ25ͬuS)| :EVi X-m.b9~Mxxa(G|jo#[F/ @pwm1t] G-v(%n `Ӯ,%{s]1~iHWdH#о8W {|y яHEMirXl:/%#vʹ>_ V/|>3o*B @FpR^/8e۫EU;$z +jRJVWZz9]=q r?~d8[[,.Qܙc^޵hG1K|02?JńvmH͎o ;sv =AFL8Zjχ{ ;65@%$h4=ZpEm `T(&S1ḧ́"ʴԻvqrϛ'V*loRbY5R#_}c$GBdE%x8 le~(2x:PG7V`)jn=3}Jkp?Q\ȹ&C;c>NqL|>5޿~0uVgnql?"]Ъ{}ś%e[ R%Q@$3}-snwҔ*+|ٻ$ 1 fG$yl׵c `/Hu!GS표qUыP[gsyAG $8ꩮ$P3i ck\22<)̹A{h$WqӏxpMb.rl,h6}m7r{2(f؍0WGic=h=Fk`NC(b*Yf‹ٺǴV([&QTU⃖-|nka8 O96B"ײҌ*lɬS+#gvwVȨ wW΄X7]P"ے+(B#$dשhgeD!Q $儽ԆhzOlcxMOZn" HcW-6i{!?."zLi>s{WI>^l |xK&DG 8H➰74P}@K`I7%"Ͳ=npL:)Sd#t1EdmSRltr+ -NY\]t읽QәsRBf9k@K1)@cWo mfOJ(}Gju}ٵǐ{U[=2;qJ78FNm1s_$:F|Ga,mqL@2W_|~.WtVQvoyC%Q=6䖜`33t`O1x0&՜^.{##jk1 G1K!~ij@%u1MQ4Sό3`@q2̖5ww'Ӛfxchv<(,!Ǎ0S׉(qBmTM Hv.7, |Ftz0BbԞP1ʇs)~$FtOje(_(3܉Hfym36 c<3߆€ywǫn٢/t/@#\gn!X85sHZEo(<3ͼeOӺ7e3dbI}3^2`1:~MY ~65Ш_)TK!ߛ!KLVvG㼻1:;h7kG YegX.'Q4ʒH$3P;ȇ֭@;Hw>o HekCަ)W(JsɮٲPh$N+S ſo)mA]}%11d;%py-ZHG:NrFG+ؿX7;(P<vrym`c5,jX㼛yD tlzL*~KZ=߾,nn0݊͌ O%flZ5Wf~25XAv)"vD\>?K`$R G/2(vIB* 5cؿ>˷߇nri:J2\OIy.;aEbaP(IOk܇!^Vz㽓D1aN r};ZLt: mDǰX]2{ASMW+krjL>oT zKiWW_%#ն~'`4Rf2˿7f+3̒RNZ_b,$8>XaZ,6TZܔ|ڼ?Oxi+t3G?K߁% ,,u -tߟGC߶ۚww36XtPd\3du2Q2_ "_@TBwg:iOsBsqR_c8C5Yl/c[rɨu>#u0X!H? ^5!$vQE$Xr|.Rٮ -#kcO㣞nA^My_,wrifr?y"UYA{sp[[f^(A|CPE:o%\&bB%  0ǃ|Ƭz Wy0^}'gUg U)'W, 8b@)fAN."ӀYWˠgC`6xc~wɏ6ᏭlL+&&DƞCπiGM[ԝLObhg~6I A\-@7@lB0迼ŶEbvuok޼nL2`md(w~hMv$McZDK?lHEh p}$Bkƕ %l=6Ikc僆ˊltpCۙk냎S82&+3z!/zEhH ZJǓ' (29%/1eq6`WwUtF ePj4+',~&>0R4pChem#k@B@|Q[;[$ #y{ ̯, V;uQNH% XkkY. = ClKd/>`K~;LD6!ҌX+v̂&F/4эL:^tĠrXmi frXg1oG_=hz[ѥi g^B'ڃdBԯJJʔv,Q+׃IvkC;t1 ,X%m:i(ԬM<֎c$j&XU47Xш/-TY#G8ܒR"B&#Dvi`ӛyh)G5OB=4Lx!OJT߃ߴp j8fMt䢭tR("|*fFxrژ V8.^@ ZXsm@ BC.rAN=ЛA)' "qjXJ6 Yo7~t { Ȓ]Z,:wm~2-R>lZr[i#sE:Atx6Ȝ=ZJwtE%$6y{X]ijCx(J͔K6]wda4 'Y^^GeoB$qWxj4{'"P mqAy4`QFɫEƪDHUpF}$g1hSFZ˹&vۺPd=G_OHJg68]+/Jui˒GI .,<ݮ¯#׶{A rl%qy_Ċg.vmx Tg&I[;g]=&F똠덋˅"ݡޢعMl ۆ޳rFZR{…[EF8t\1uבU® 7&Eo $a4g8>ٞ F~ ;8m=4ml(0Q QW䘐_ O]fXD d視 [-xA%u] *!G=e<uOx{se{|?+CjKNJQc*IG/>!bwC5YSgB Z#uk}׼`RadIDHOjw@pjߔrz] 8,IR"dtJhR:r 䭼uuDp*Dtz5{-sK 5o SO4$<A–^z c~JG|i/EkoZy `y;ݬRU~ovPi3LjMFv4P6EQeV)f3rm Zjtir@ۄE )uHF6nwWagWf u5]+m bJ>RF7o "cf1cd]&d/ݵYVȔW`B-4,cʉ[Ĭ#T8H* & nF+k/0 3f vIB6B~0h^kirz@cπk3?Yj9ٗy QO)zu 0;Lk7\c184HD!a,v͞fy`[vqG] XGt`D rD 03 녢F E0r + $A c>@

x21kϭIRlz{ #kiʞkdNX{]o?fsfTSK[^_Vk*|w)ӊvM;VX[et*ۥ5ij`9O[͋8'[堶V2=Y+SOݵ=cYֹQrgL$ .Ffs+^;i\3?tIhcGc]>on(qvV~>tz鄔USν}Jh>;R.4^1NZT cghՃ£j9}'[.OSTeD~ڿyܕo\]sJ2Zk2^ݘj%37lC5yOvLjo5Suˬ.;5*mO|+kϵxtW[ۯI+o&EefvNt=ٱ&5.&|Œ=?жO]<}t j?i(~H{shul_0;{(コNŮug935S~n/NOp|t3qҊEORוŬt䭙-Ն% ŷVs:~־%U'M"h˻meҴK4v{w'z22,P%,zla[1/5rvDL栚yqaMZt?]i,^²5$nbvw5M>@d#G{.8Pæo_~~G .ۄ2ofxD-6`͹wl#sKw&x|gLŒMuc^E]~-. Lԙ@h▒Ӏǀ NIh1W^ڗz*a= {-u琮2{mFByom[nyCԽm-c;C'uU|grTc7pZ;*A.,,7iIXғlT?1ٮ0Ț{k$_|H,<{yWaE i| &#N).ź0оT>e^ٷ=2o)?p _]p9x ΢zR~V^g676rwY˓5.Ss#v.vጞI>EM"Ξ ?y&S›LR&sUsWkK9zKaW@_muo78oi1iKZ7L^hf۳_>;J;g떵S fp0kzz3r_vBz9ʇɏ{2SF+9|K/o ݔ'q@e.ߕ^qBo*XOŜDb\=#Kɩ/}*+SJ7)=嵛OkM-&?іE"Q3zM߾wtvG.?nL{ݻlBrW˼]ɛ=_ 0|Ҟ I;,-X$ h)s(R7>1=Rѳ[f;ccp-oEifFr5GZϑoXoIՋGC#y6VoУWDRp?4"4oBP5pK-"JB#ue4!BY?<wZނ鏲r4oiuvn4GT 7q D&0c -IeHc #7tnP|+@ 5},PYr4>hA j*>Yr"+ n p 3 : tPxJPULN눗IjC|ă*_E;qGQԙ/$|! /E_$ʿ[adX?E h݆/YxYxi>WE0TT-0.T"~F!B$#+ƌ%.HL㄄$/;(B7HC3%PJ$F+B c`ƍXQ YE 1TE6:ȌsˢB"pcp 0!IBh QqRXg#1t$ H4Al(G BB:PcG) ᜰ4BXn410J (Np{8TPd'Yڗ B,酤P }蔃L3~.$@~PJ{%8º8I3,l#"a) (a?: h CAp{8 (Xq~`5C7 |e!?Ke!P bÁC>/G|9 lea,&Al#P@~ `: nN!(_Hn2a a8Nb?]  MG|It@&$3wqV)c6G@: 0Aaq(3 ?i!_~X(_dqA] A9Ec0aS.TƄ 0}`fU!ꘛ#bgYT=y;@d.,{+Yc5 llqv"+K CbȟEO:HQ6mu c&hxĻTK. Y$K"Y` 9%g$(9 eI* $ Q%KRAJ{}9kޟޚ6c@  (.N*jj @ ( !BٰyE4_d F(#4 /Z5fEf7[~\oyC@;I\9t$b\í Z̵r$AMo%J?~-yjYfݍNT!JyѢLqcwN3B307MD7(AčyFH*Zޅ3D,83Ճs=Ve.ķ@@{@؀ϓ#UEM3+zN~Sj}ٜsSͽQ@禧S5qσGe 7x_t굺9 ڃyC}YHh];2;_FGӦh#\M0L.=PLxM|3^|U˕lhB.zX=17FdEu*h&yfm(q ~ m[ܩt"$6whd7Uy9閦Ry}ʖD+yãUiSyyS2SJw^-e.-O-{/"st Vw'ЊӇFhmh{+aj9#ůhe~ =y5ZW+CFC41vavh=azu|6W) DŽuLql8jֱ|6W\߶2X~f~?f~;cO|P&8gӱNEds Sռ3TLR=J'C4u"WcɃcU]>&_n({X+j)v.}L.޲zrSm^=c仍 ƕz>"ڗ[ mM^X}}RH+xj{'iOJ9j01dKZ%N}&{lk+w쭇s9V Ko q8zjH>0=d/TWMtPN-xkjr8:re˦#UI[G1sψ]͝tw]Ϳ"FݔfG:ˬ ضtClǡZeX"< .땗ry$E-4mNOz(˽IQٴlU$-Jqͫ2guOy70~E4op66c4CYS]m}2fKK2D@Hi)aK&Nk3ɠ޴,X@w kDYw 6"ս7vo$FDdـH`H$H {ϲ.d]x5Zj.[F œc]t J Cb*\AH yc PĨ:_4D0fKj0 4C0!, @ <a.as.6{bS/2__<GHi)bxDu5_/Bw#c8$t9B$;잂39޽U {35261/y5w5/Y0y 3Ȳͩ0uV-HWq>7:R`%_3Ng 9Mg4tn6m|sb8a{G*Yq[ G ɂ}k#|> wu?ȈB<yWeS1.9薪-'4bko6i{ܸC1g )TUQb^~դŲ-ˆ·?[ oe|̔c '袁Ғ)3O9Sf[{'Dq8r|yS$skDt9:RRWU[X({ٴ>, tL'裠ʽ}v+M6뇴_=Py;?u0wPt\}ݤf\ J y{*I^p \«k=x=,7ԙ?Wz&9ݔT?Ͱ`]haHgw"%䵠r(LZι^rZs*vaz& tg'sD=W^S cH8c!H4 -:b^JhLNw]BL\Zb# ԋl/o{sFiVܣa ǿD% ȃn0_>\3 D\CGگwh5f3}qUYY&.@U1M gVKDoF]LrdO1^'wHY9&D9K<ӂ}*a9 wփ=n |O&p|ΏOxU9 !=G5hU~~ wף6F/*fE\sJ}jfb?(^u{Wu2jpànJCXd]\G^{{7$/7MeI1S#rDwأ+{ fv6t yW4= *Ǐ!4M-)LUZa;yko+u[jo RnL40qe|VL t4p&< {nLy[ 8u;%[oBmq%!/Hp FT >WQxEϏ l_]a2yczd2cl|q2&v jH.v2f0 vq_uG@K }9cY"Yp $\C."4 xY1]" `ar7n<+b<NPпV*.\<οO@@s? ( KB5J]D `hI{b#T~jXy aӪù%˓usuwr5InL}31Lu崓XGf{,3IyͿdDmpg@Q%PAܕڠjykMn;`Q"8bvQ\ĕ**whBmޢ?:7ܡ`3{/(4D{18DR8VȧTZz2zٗғ?fP "ґw-9Lѯ1-%jʷWT2=z3\X]І>G(K"/=D|u2}<ѶDG54Dz:5٠]UJO8},끚^e8蕠U *f:vo ~]s#H}?Bt4(VN 1 LP'I~ͳ<'Ҩ?F|թC|`712dE5Zui364v틽{6m5x0ያ374EmҘ:pDf*p2i2?/G֖T2mA)o ?K1IEQI6 O80<V8X*݋W3Қ\ e絢uldurh߸91pIƞνa"x_T6[]w#8Q G^yǝ: \Mo<_WA=8T_:IgwUy,k `;/VUّbc4.Ϛ' PԚKRXB."z)5Vy7/'U|B"aNRۻ{ƗEf C ^C^Ly(N&FKwy/NlS:LuO֧v]U9nyyF88R[fIcE /#[}F8OtҌ0d`^Ѽzs۔uvzGtĎ!?5{2\* ⴻ~it|4oBe Ѻy~ S]‚+Kƌp!I 6nZPQӖ+m̷mW63GJŖ&nŒ368i4Xdd&?l,"d\9jS(FgKHg[+B, k;TsGn} cy>,82%GY?!njjr>{ٌO,]KF<h9YAxJg>xgX%ABY܁HX+xF`Q2!)S#5iQ,adx4,n,%6"'ۅwyB:͇WZnNi^ז19̊K><+ M bj`٧1Q@+rr̈́o9E%($>ŒsfUxӅr>c&5$čԲi슙тz5$A[@S4QQb`9!d}/oYY\g*#*T8쳳w}gLwª[z5?-B#IM?7?'I;:$mS%KAq>DY7}[OL2S[QK;]3+.8 wT]q,^Ћ#8Ga zq.NNx@@r^0sb $4&#_@o+ 9"# <@n- c k/οHtz\8Fb@<E|'p : @+ƌ^8 `.ET:W"pącr9s?t~/I#_Gf~tl8Z 10ϑ1ko1/)OjP6{~9+vCE(T+Cu5$~[guT>%j>+j!B/~u]!阞/hb[?oi%1˲-Wr$jAg3 rZ1VZZtYϢflj^l&EsyJ->`]JzV#xLlC~m<>AS1kY1\5dDF+S6a)j>U/cC +V!?9i\QZz1uI,G_/݉sBfKma]Hʧ˜T?JA&ô/_*F?Vd9~YKל2@NP͞:>X."鄙p1C0[?ASx y{Yw\GhQy$uIϻ #*t{ǀ]io;@XbBB [}*KF?+8o߮44 _1;73%!ŸKG`@:{<7Yȕq8^0)ԢU1WT%xçB}:SN@Ś7 JQ}#[y[ZY+ ݍ~ԩq ٕ%JGn0.Κv#8w0͋|o&9 nR,6e~ B)bc  qa\cf @ v_(a&|1#TSyc-~"lE#~ RcfWG #E- !E6B6/=Hf Go %o(rK8Pĺ? 7=+#gBPBH " H!(!8CB$)`k0!$G`taB"). ! XH8e^P8w3s!±Ϝb'& Bc?s1^HP+;?PYG5X.btd$>jп]`]P$l@s-6&3BR(vF%0;JgeˁDQDg&iA".{?:Ha$y?s(⬗Br6 : ǮG8;^v1D2ʿCgUΣE@">;O*&2;쯙͝[@P%:wx?#/y*,G^VX;E'T(A:9m<: ?w"r@gC;?gs4*r z5ʅu'>4 \|\G+ 9Aa't;Qx:zQw `}5qazNQ3GJ9?Gu!9tGASL|1{tѱ?#s|. 9U?|OB#bwz(?<oF0<8(N`)GB +W P {NeS@8v' gKYr^|౹u^ Ë ogV$"C!ea(vև90ПW9Յr ȳ^.{/>g~KC#C7酟?)t:h ل3 bK)6=acF `S4v%A~[Bg6P(vvH{= 1`SߍSiؿH`،\-?y01#lpQBq]~>OtznvagϵL 4S`"'i l"a;GF =TI80g|3cOrg]㌳}c[(։Cy[O\.QZmS0Qp~{]qCӮ_DA/],V=Ľ# W|!_ Gk3(hYYLA[7gCHGS Pl;J$O''> I̓N'MM 1'm}Ja![~J&W]663QDC"/ j_?.m!^`r[!'JaCXHfʨ(Biv'zk\qn?9Nyj 55q' 49ŅO/ V [Ȟ_lz->긥ڽx?тFRvNKݕafyGJ9H8*x,dS4Qn1ժ:o;Ek([Rrf ǾhlM"VniBf5vTPK^|-$/*{ǥr}ru%i /a{J U.?ü|Q.Ck5/zV-W}fFᵖ^`JS-uD( ]|tM !U'#VЛۦRԾ{l_`c(#Cͅ`O-ϣZ^h[{ !Rl_o}ݽsCxq2ӱK:ۊCR%h옘;~uneE]YE[1Mؗ6$H}"A".f`Dhe>|kٻkݦ^;8،#]{,vdcsl4kicU+ ]$S h[)z.c|Qb!:޺#FZ棼htro+a& C&C!{*OnlZ~=PCLЛm*>yfpѺ3Cc\G`+>?8:P]ZA`_L\ݗ@G4xPxc)oj*vϚD1Lcѝww鹡>{ #ZgK16P$27B_ԯA?V+zY䤐:pXh"yEƼ"t6rJ2Gs\m\SJjˆV:ߥVyOzٞ/ kX\ݿmϬc1zjo_~7 U<pE@͓TX[-P!{(X{1|N; #00B,()ž_qoOd[G5|2$2T \QkkQiDv QBu u?pqrm.ᑆLڻIna׌ԝ.KLm%Ϗp 8j(D2)]IRqB$X8xG8"r#)ADl[ 7gjO BL-yy0Kҭ{;Io#ڙ̸LfP0t^"JCdAyp.ٶIFS|rZ\8qzHW@3S So$_NN??:p[^=", d\o~,|Z?J[j9iSg.)Ri&NISG\&2*Z+w|\2 ?Ѷ'q2M b)3#(AxKߢL-B.߼?A&H8AvlnrCL+3'N)ٱ3#ajΕkZ8?IB ĵJUȌ_O-pYWvXS_#};NbB^4qDG㈞F?hTV%u^;\19q}5C{SV%9r. S8QYM8E+VOZO'Qh*"Ab qÌ =}LSeX_{Z@g)LD+H=T}R)jt~"Hd.X;qhkKw+ y.E`B ˼画, ?lLNTCOZҒRMjxAV`X͢\ٛ#Z>1Y.ĨECVe>sd;,~yB`J '[AaNNPPxF CP:f~Kdy*pO ?wJ(ndu>Rd)`m뢿JPU _A׉jS@>obƇsF 7e}e,LYJ*J|$5<%cNr6z֭v4 66(IzM(EFi).4nOiMD~!@T2ˑS#h ̓}/uǕ{v(F:6ho0V9pfGS-%ż5:7Dev7!ux"@G^QEӯ63Dχ]$xa\-oe= |%]T G'HrKO!گj I Kz;x`mj$H6 /8Gh/YF jq Z=Fip ?LS6'P{Z-! Sft+('45k/m%Y%ֆy1Lڬ<٢X/BzQx Qr!MZDh߱E2~ iW®HR# io nP?{\32=0;c*ΜQ`Z L<ŒŔ¦u'@O_m nLߍxJY>FE:OUrcvE; T0_yAęuYe 7n(J?ӳB*5 p6@6QxdT}@^(I[7ŮՠE[t;kF;"sm^1? z{33s.pi C[w~`cSI_LRWP,e;i,G 9շs~dV0Xq\oi=Q2^ : x]lSidǛAn_E6;Y ik<w\]7aͻi+^]@[3V~#!+륍ĻCF=n7Sꗢ $Touɼr"jc3"djMؑ*[LH-؞uZp>A{ZN,y,Qו;rϾ  f(-3'~o|~5Ca B#^w޶`҈O ߐ;;'+9Lܙ* rQ"gF&M4΄<Оk(D{; CxF֬:C^k-vF0(pYi˳;w BSk^p>`lO+z:͞>˓yEyBYnxGXh̕AF̍)]eZW1SZzs)f*;jFܪɪ%~PdCA2sjo'jUI/ n '| =qyE{X!7ƕ6_?kJA.-#-wY{iS0s+C/";_µƟ' 8y:5Kr|9Iqr+H1BiaMɤ8c듛8n7W;n̵]˩?E fͭ Y}F._vEo~Z-aSS>>4Q3%|aM(k# aӈL_.Q~DH9;nOQ #&zju'!Žnׇ_+ }BS;TD!L)%ܟn?2#YJt :xS4@7 vO<-Z.+sj%uX1QZꔁzN0S_> >~>^nUf|W$gZ%D9cQ\?41UE}K›)\8uY \3×މd^r~%yۑIN0.o 0AqO ;T"ߋΡ0/KEzY'f-liW'68|wekJ61p],4wb HEf7,A rY̓b_T9*V]UUa ,*zcy_>G9uk2mU𳬄"xS,%ٱXx0,Q{ȑ+-_y}/V[-EWdy&t.mȈ5__:@\[}E#HyY&{U:^31KP^_c7[=dnV:p Cөj[)1#*<9|K7Ggo0eˁm%V؟fP=/'2hoDreTҫ4D2 LkӢa~ҤCd&nRҵJh_w_o;ybәq.nw ƸTrw>_W`Ч  ٤r#ﱍ! JIoc^lLhӋii62~}`L!]_4-m&Tk^C4(f-ὟJey':F"Ʃ39.\n f O.~c3.P(=|ueSmK{KMz2W"GJv~PTz[ܾcNLg{wuy9y{w_ YY7ux A0DL1-ٍ<TS+,#,',/("|SXCXGRJZUFVNA!Ӽ&D7 'v[=#!?P E@_^tnFOuuzX|}wbV95qVSl\ohtrr3.]$,*8C ԣכ37}( Ą_ɢ.Zv'̡{s hE M}c*V]qz`7"pS *MleqjaojW54ei%ל AhxPiN>ЩS2!^f {mo|=@X>y^Om'[ۧO&?oHg'șv k*Ռǁ֜6]}G8S|q6FJI{:# !1?}sOo7ݲbyh p7Ykh)S }őeЈ][ARi#dOU%Ϳ.Q3bՂ| A2$ =yC})fh}O$'y}WD(M*C=fhC\f/ĺ'G>R[쳄z'r9KgmܖזÖJgxNRc9F)%CO'cl:~4t60.BX~͎Fiॠ| _6񷭷_%rOKG7K×(oW͉Z=.RY$h,VFY>ߺĚv&۶'Ķ7m6&mMl;9o=uŪz>:6|>4w| :*x$9~L?f%DSѶF@a{f3' 3ծTjo02@ӝ; wOaEϫC4o_/-hHB__W/I&Taz?`W})$x8B$*&|LN~2}Xv@@鷞=5oj.nb@B,Hލ:\&+ t\ό'/0;.8S!HC4EKX.l|i\D|w]mA˰Mxp-+џڐo:_``r.!X*ǍhEn_Y'uWpDOAUJ@whfdҽU"QӡQS#e/m#uѧpKG8#*+)huλ!{j(%e r "ems-? RX`*R1D(E 2Ɖ:aZBrӶ@zY>⯖UՌ"sc@ XiHs&[ۙ#aC,q <*2畣=@Gl@(,*QuèoLpUHwF]+p E>|$ |ïK"Pyfok6L}*Y8yٰҐs^f- 9ɉ.)~ԡ B|<Utמ碻lUf6EYǛSؘCpJ4{yp ^q?^QSh6!rԏ@Prl\B[;rf)Scrv#V"00{I-&Hň"i a l .iECqn*5p/[u8mtq][gl?YgVILnvͨAÜC02h)@(0j<;鋵iiZm. cۢ"n5kKMxfihӰ/h9G$%x9#Ldz/,!# 8ӔNtpKCy9xyp 6>+Afe#BvɰU `fdW}vwqg;Qx?5xW$>rI !RFv-cup, ʼnya<+PcYDсvbL>)PѯQjwQ(P%F'׾3CnfI&NhMBicx{X;^NwЮWwsY}*ɷ}eKq0 B`}ϰVIOfrj~wulZ&|Xgܿgh|v浿z{ۿ⾇3= G[$wGU`tu"fv(;̪QM;1~%xUĬS iuq>$G"G"#b̵%NZw@2us\I{}nނp_wm ؎q[t>zVF1G]je4 U;Ϋ'*% z줯A]z }[ք\ s6oKj8L${ɗIB6%*62Qϫ.Y,~op:Ui/Jcȿcӥ pǐ\ #s\b fFcm:ʦYIvo;)yF#_vUt'Jwl:2 _^vURG0IYa.PCwAJ@s]~%]ADy/fc'˦/cye! kQ64%y i_UJОZwVd#f@c^>"+܌Y?/ E-qiɽC2jw'Wɒ xS;BF8kZMr ,;hsbJjE4M/I 4aP><;^Op{eΟ ~ ])(]B&˂D+dl≜d;\+..$C|s{_a[/38;L%B봆4@l'/=cϨu~"{?6گhGU .0S~E<'ݘz)4'빥2]ڙδҭ5lsn_O =.FtNЉ1n@6R}D0&%Y%䭵^-"_%\۰u\ xNlU)F^|ߗ7=PPqYѕl l:?Q5jxo YU(2^,"n,_F}:ݶ-ZC O A ckԌ/]S4 nt"g'~ Dx*c>%NF 3s{0nQ:,BW4u,JGP]b!'rW ?^r>'<"B9J_Gl ~hWuZpemTOKli K ;hᒦ|ʈ{;ի3 qlIP pB;7wۋvHԌ1ٿ yk>9D\[rR9D a0(WHnKWvH)bWͮG T% ᵁMԗ3E/R?7.Jr6}m1<=tTt >O\.6+ MQ[D3/aM G\i 5bLXճ(UXq{?Z@b3a*wmF`$@懛N=ma? h2:}Gcȃ9D|d^ʅ$vnO ޫ+r%& U^ޠC !WT?E!1d _&t]fA=im"TڶJ[. $&~̾U ^%[Y;.hVkj__ 0 X.DQU%K^c+T&w'Ƹysǔ*NW7p *XA"b9r""i3 mo""ЉYϑq.]׭N^LT|G13}sU" ,(Z[6X_m0NZ'74Y'poܜ&~Cme~C)@hOkKjYRæfзBN/:.~Ca4樳5%Ri ,NW0Q׍TDeC)(R?鈽|,cp(uf+!v]`q:GJQ-{, G92dԨg9yW'M`"cYF{Ii|TfHƂ.I[jE;XMye|ϙeOlԏ[nzcǷ zȠCM8$-%%FLm2h=P0Zm7E a+.nfF( }ۄ`Y-Mb3#nΪ.%[\N 6u@=3T֡G3po1IGUTZu ۥ[ZE a)ҚRVhez" %A`7Ǒ tY5tyʕ(wxFRYf5u *}%W+2>m\gxHZ"4(s1HE@=`  dZ3(2Dնא#.WbtX@XLWf} mX^BFjȩEKL//f54 ռTivSg=)q/R1*!E([+@y-C;K/U8?p?ޣ Ğԝt&A=N>ݍT=&5?+[$wh)X"֏V.brvr.}JVx&PV7#_Sg6b烹'wuIX Gndvs!c^uب|,bB[j4_,=~\я3l%GF'Q{UQmmLI˾Y<=p@n ȯ^*_U ^ juozf՘3]!_jy?+c]ziE._T{cDEBBέ%c2/+OQ1/VQܼj)TI6\G&yE(k?c5aɏCL {9[['4kNDMIYsUB-nB=V:6ܟ˞ȟ+Ƒ")pJp@njXfECi"6"+U_xPlOD81pZRTinS4nrƪ"A^;~m֙\(N2uU^lE1E9MQy_ѩ1E 4ʛi,:Xa'u&5{jGk :`/x_UfW]qwl 4p~5n&0'.#ʦp2 ;UYgUcH@ /HcCm4Zַs}Soд*zYm;5.o;'SH./Vs(~-Ad: 5(cÇ[_|0se_XWo QaKI99_q Ӽ^u_tD; VJqh2c Pdb=%bDt7Lakxfbok[01"WhiT^{78{+$GW|cP<obfEԡyaOueG;4~^bRqqg nGl\MM Iy*?V2&DPgH^LhZ'2c.lH2?9esqD΂fLGc ?~E'P( UwK)Nbݎqa)nBq O{'|RL$?KD>$G,jh[/qYR;e׺sBhYfYv2 b͓YE0dOY,ی>C%kQǥͨ»ҏ:B:CzWÍ: ⊹`.4sUw3x<h׎)i[v _*Ǝh2Zzk0G14wΚ'BuXv?ҽ8\w m},"{bZn{zB2\x}pIN]YA/ȂDω=^s{9k`tV[ `5s%S6 9C.02wB_[#; $7!zֿF,BnbOJ1hg{ɳtQup$PkryZ@E'k৷q$T@Kd6kQlAoV82*&GXmH95ͻt1^wnF&{`"Ε&f~ߧYND,x]|duk1AJ1k0 ڌk}mgcY $eJՀo7_{{AwE\|]M؀^U:B@ߦ]G zj.'.ܩ=5%2:ƑNT@*XՖ}iոN>CSAr7 o ~-TyGS>E $Ӻ4ůKCF|S%ߣv9$GZ#Q{ 8%ar!N~\/,]&c`, |Y\7 HYj jm _!BI/Elc}ބ2l)l:ދ ߖŤ~P]XG._јJ-xsyʆ!Su^}/}n]L%~# l8a֝´D`Xo?1au ^,";+CΖrl[g>v&kn?Dw64bͦ|C|"_=o-(§, tE4uJQu 8 ɛR)>Fd'qU kPMWKAq% 0쿻ګ?)O7٢ SJNQK6Q}8nd KvldQvvc",Z0rihQj?O x <]?CA'ϓެYHFKM:-Z= S7z9D˔Ayu)f^&iwg! Fdցg(ђAü %yo 'ĭ{x! w[b%Ln<)2b1UY̞.)lxOz$#â 3::΋\P%icQdDF۩ē~n쿱V&lኬ,til B2i07?A9w]e3#䩖ͬdL-7 >9ZM#&(^ITET9ngpP5"Gd8SUwN )<䧒;e  VWZ"f'M9\?'< 5tƗPF Sk IXL#u(4h՞` &C+]I Tf)1:E1xbriS>lbB/}qndd'8v_[֮\DTƚѱSӡ#&6ʫ,e/m?Hu ń_fbxx FC[ %+k~[tv!c`C_S&ifrjɛ3~"}UTH4Z3~w6BoG:iDX&̀M\7:aQU5uMZ9QcM$ߒu8){pRVy!A_28 3sg)?dj 29 d قl-lM@v ) HLs1blbmb'rp9Y8A&& g7; ryL]PqpwPxC}m|&ؘWU~.㊠Poo ;8o #SQf W~, ?o3([_d\FoP22y3aoF>U*BDK&,.zb2B}އYBuv0 I`-ƌuTF nLO[Xpcb Fb[RcݒPVCMygdĸ~ r2w`!:da wUEngni)]AZCwvmzie?ML4;}*({s^t,wk9-'562,MCS㺘aZn梴^jhgUKJMYbf^!ͶnYQ9^&XUMSyZ^a(^{ʔs,=?n| /sho"-ݵ:Q Ѕqv9FpK:WFܒ 5|~`ZMu%b*gZNB[њŵCfzǞ"L^FuDh AY-K4S79vIGiSOQ(̒iaw9)_a܏(7~ȧB~'~xқfV 4?S;(v=f:wkT>ۤD['!)y+OX-QbfϫѿSC4 |"/ 耕T% L =6P(63\فn :o/'<" b+pidfjX^XWsZ63$}`AQcKo]p(=F=@tٶc#OoXl" Rnm+7 !Z%_Ә!h'#an.I EgO2mZ=vfߪMX|p󽌶f r;ͨW p1cjo Qٛ9I ]^يO&,sv gˉ!W{GKq/+!,Qǟc2M<(}yAlYpx|L_᜺ZR0:6U&P?0ڜa7ühu;q,ZiFp]+RYt ބ(n |\D6VB;SIru3&ʍ ef>y4Bw \k1H@aB9#5UqT{=ba_ln(}>)q֘X]o*dE`كJzmLxɎ$cx 8ca@\\j -.;&*ꘅIndZvTDZiғDk* u#BzE,\A+fuvg oMHQ_)Xba&6"ah">M z1AMsQFgF/?Eg`}[<ݘ?61})n]X5"ZXhGZ+^QY.dra`wӷOFNyA`|a)EҴ,|aP{-IGb˒KE9Y%g\wp(q̩-NkNb[΂vްO [/*E1?b CBH&EyȁJQAvʆ"=E ) {Ak6&K_NEcwUjW%^_^ u*#7l=+ﵠUJ|,sY\Xhbc1؟ߢ[΋hJez;Iz[9=7b";0썪iO!# w@7Va Knj@Y)O gGNMe5M'wz2 .VXet?(Z&Jʣ(DkO.⾷| 7[.je" ?BUݜoMExH_;}mػZsuډ?5A\_ucg 4hz[6Z9t_|#ꓳyz#Ϯfnq2_ͩj/BkƒCabeZL=o0moblJs&SPԗgj|gKfqGBKaȃx݅[S׶LvXn#qR04]1溮C-lMM6ْlfEdD6i =V&WCD }*F%^"uו_EM50c8ȭ.+}7c:ȇ "KsnJޤ l1AE칕Z2\[]N^GiB4sw80G׋gۏ\\F[W6.[-((fSݓ=נR+gRs 1>CVHZ{WzbK`糶c|/Pbn:cŶqEmT(QK@fٚ#Ή\}avr)T"m\b*k*OX~X\/:Wa$Vnʂ/pE`VM.S mhY+HCşyBqmq;"0@8b/+/)r ccM@;L 6- v%d^RUGAv YB~m%njC *ՏW=(@Lb&U0q3y<ʞo-͉@;43v"nʙڔi dRW ɐlz9wlPşɩJ5y*u-_9\߇L=Z_̂o^?-hqhRbdO>n2J]xFdYB5a50Ո`,dl4n0lh#%&LQl0=plw>?c$#u֩`8MK @at(q~QrF cXq-fA$ Ű++HT z/$pv)`34<0 A/# y6,ܣBƄk'#2r^ uKղE ~<^98s.ok`gHJ} -a@h- Wݘ l?LqgzU͂!Oϼk ra?CA$(EF^>_ DIb2U`(1JC3Š$IbCIAȗT@1?!?I[(6mBG yB߃+`@!@})#EF̟؂XD":F_9 9`j׬@%HwLhpƔO7 FyPI鋡‚^[h7|GB(xL1/jə6u-aI&6Z 8AEGQӯmz0]HtXm#?=|G#`C+c1NBV~q~bs,P Ϻ2S !S|"̲}ΰ^ `->\sne5#Q7M؞z tPB9]3ѕ@mxzbPJ@nx~MYkbls9ڷm]f.l!X(VwGuoڿt Ӎ<+" Y˖716Ar¶<ίӴ͊We;nswn愒PNy2Eո]^Dt0&S<51OXh7TJjR nZ+(l% yjJ?IV40u0HM(YRu1{n6(()Ę ejh(n+Rp-4*M8B֖z"7Я8ƈ_%?wtJ;qfR͏]1B|L8hLOhBtqjݕHg|6ޟn^p|Iٖ-{ktE2QGT٩cLt;ՐonNcg:y7Yi\.h웉vަ :L5Suꒋx|~rRjllVУgy0|XVKS~ŮRjgI?/έk8 _l7r$WJ96͝g sV#. )y k &Kg#$󑓛t?1#;Acp٦5[ MQjpmGѳ(yR{xuR `܌QNt%,xRrezvFb^('I%̄08UO@aqǠ-Eau2AѸhk:3;N/݈QO@n6L fN!zDMH-3˸|U.̽Vwء1djv5fTao;<f r:ٗT?nHv[t_ej)5.t5bC4NAYejv:[e]U0T=P'4VlW0ϜF! ~$qY Q}猢נwg`·=/P, Yr!;`D۹ts;1QsF"~]$^yu9Xc C϶{xųaec }GO 9u}팀V!gKMl^rP}-Ӗh|j4]4mh+<% 'ӷ)PA!b(*,S/غiP2O"8nG-.]Vî, gy6hswqYB;MXܖB$f1oш0x|wfroG=/F(W5|􎂃2ݧئq Ƶg@*6C tm_\57aӉ!uߦ^z+UKtd 'p̳L nsבrO+]㭬@_3hGo<)"x96 9?=A8o["ҽ_gt*"'AG0ݔ 6QzB@ҷW~qR rvLE5/o,I:yh0)A -ffH;t|}Dvּ=XoM6}U(WǦǡx{wZyi=Xl"IY?k{ePnnzy$GpՉjR?6VcYmB?넙ZÃ9Y t` >S-R_nc]$<%*%'S2h/WN !k1yhv($ ۆ+ڲ?E=dlp4%Go-?redz3y={Yxq{>o݂2Ĭ 0b\H?&'>Ќwʄ28}v hВ;a`y&yp:3,FP0Av-eWʦ:X7{lK #Ԃ3.kLHU1y67p3uá2'u$ތQbì91Q9! Pzф#G73A:5XJ=&"ƕeH3+{L\!]h:/`0%ms9S"6K)Bl>\.z.1F%U>.J`D'6Yìt0s&*oɶmBvVgqkҟ>5,Wo`pN!2uN"C- `쥑 Sq-!Ǯ\KA7F7 r(T:͇]:p>~E:ia+$ "=tĨmrOƚ8X'XdqWԜ\W_EZZu)<">sZ:S_C\ժ^mi"*Cu}XB/ò՛YeK OA=D5qږ# =O7.٩ΛPJA07Vk:3ӆ(pkkKC،8tu3.=Ǒ X̣'ݲ!қ3糓 %^J% ɅSyn#?%F$o[Q a)Seb<'ֈ%u6{Rbn_W=$abK1WV\´C~ŸR6ch>IxͼgnT^n)+A9u{֗ KT|TZiOsSjc9!*G"x teJ_֫mڐɯ% 0?Bb4( >ZXJR[Ko/PU/̖R F&,1꿇U%?z C7/CVUÈ!Jl8@b}c^=Ub67Jg@dɨHyS}s%zX|5޾rvqru9Eп?ҠUgb4 ^J 8S K4BQ0I)D)+WCuJ6+y%㷮 1vxpdII!3/2\B?::Lo-!9!i{%<%`~i>Ay[s蘀jifU<1tl20ICbKϡF8~{M}7pH;{4sOgjQ4ۂ!IU8 xDRnN۟~O;pI$s+9RcR^b ,`(,sI0 pD&Μt($bڥD اǜAGW̃b|߽1qAbHT"E o~A0xj0Vdߏ)I0zG:7) " l@Aņ9}V28#4佑`%MsE@ Lyovqr}{s|4$3Q,433n^9Zd=ݭ1Sǎk6[&]Mz{```fN\lǦn?mb4\!!Oϱ/8 tPF$|ܕߛbZ{s] )%.E˼67P=2bx= rsMLmn U/]U`!n*.^Փ.pD4@ lD:q+Wb\*1ruqa&O_.ȓ+MөNJoy5L] 2A<)A V(g^,γ%ԒmT4;`3"vF!": LeqVϹW͈jgߢV 7k&OU7 .1r%>gRG/a3~ϬEGo)MVd ΄ f|cQ]*21x3]Տjߎ.rچo_1<XuMP<~jhSyn ;N% C%rz2yP֬r@oRǠd1y@bax@JScWJ7;EM|>WhI@#=@^EZ \S{#_W+Y/!ԛn}F= Hq@BJ莨 6cPT;([5 XHL;Qv2S;.'ee<`G W/qqJN7s=xfAVrZPɌmӝza NpN1ōJ-*:ZME ͇;$7)׳7|c7 ]駫l-lI=9 A)o;;IP`?"B\.J&h=HOhDF+~V+)rxъ] v"Q0V6=:2m -g?8c5~ 0q)9,w{u%xSP/|5^J7TkejV7w % λ<.{>Ad_2 ~ݱ`i5Ig3L>@bҶqm\80b3P5mfh >C{‡6S*8m 8s6LXVs/RYx>%<Ǧ pCqP'w̾}0#YtoV gpj| ^ݺ>sƃQhX;] 2 UoИ}ӎ]Hvi0U+S , mxغnoJ._@anvuҫ{0[2+#hyy{=@틬;|Rvpdq5{zZk tbY"j-C4' d5{BFPMHGuг빘ӏnӴy }T_fLx:l^lvIgN0wNp%b}T8pKD}KKtnp!l,y={D>xO, ܧ[W 7z,iC#rX)+oHa^8znEbb|.l7ؤNq66;WS0yzR>2Crnr4KFIMEQK\FBME/Ғ%Wr\__ Neq6s3;tr?[&F# `.TtPj@''zHC_,Dr}"YG&KQ S?fb'qڒ0r)"'x|q/on14+ >eNS?MP ~J {^ &v0 PM < ֿҒ܆pgcx#LӶT$!i4:LdC^dA8<bm`9,b\HM(/k7!_J*exC"B |um\70iбww %!Z]ю {ʋJY G[$Xj$H].bv"-$kpG/'}:  +G|C/;6: @M=z~]w(ф4UQ,O#?c$!E4ń(-F4#6{~0'-Y2J~B}vP1CS%;ra|G) 1_2?GQ0r@x.Fbzs,uEy%Ym>h*,+L &0-,e sPo¦5g%?7<}x]HZu!Uf9EsZ8N^w:mxD4v)ZTPJdLuwLռm,>c7#YӟǻV , 1oo!p#Ofαd(;ߙ ρkqGskH+áb"wes"B l^bpNPKԫ GAXJ砱K AX[փѾbGn*9MQ(SIka5_UU.AoAb\ҜAS{#BoX[!L*NzzaPd cߦW.ksfCN1+T[ pܵ\C_T\{Ep̖|yI_)ECf{D7jd:QГР]HV+}Gӆ]ab v5FSh!lfjrC-mHw-W]x,(~W`gN}<q #cc7M zaM:JqM%}."ZJ36ڋ>M=έz%I|hs`+Q"=J\gsh,^KX]P'J^;e늟YI:Z!uKi#;VOg0+~z686-4`zS"k:\%t_f]LigЧI̭=g <:r|d#ZpBr KrEv)Al]-P)@eO0"Q=h϶.i*鄷YixQXR&.*sS>{y@ҽ͚㋳#^vM ,jō-1&.+mHToO#0grWY#%x&ޚ*]>⛫OB yf0R_5.!`hQC1R>UtcD+Kr6wD&dO[Z?.s\U],FFџ0œ;QHiiefʺk;3Gf'|G!j!_GpLqӛ3㰦ljocµ`Ctzv4:a%5Ӄ5DI:ܕMT:s◞-45XNe3/–Pj,'٩\wM_R}V4@ J7@цU tbCy2:9^uVk"paW VruTӝτ IoUL,nʸ~9Nk 2gL=e"Cjx`(JqJ8kbs];DnL9:|Yf_ B!@t0ݘe.` 8] >=Fy큠oVtci\DVZ'nGfN~c~cM+ܛ]2{T^x՛<pH8M=.'S/+{3wm/6w8 ~ _}LpdPڪRhRIz3^usHgr^:3\.B~~MSATdpz[M@B^|0P_)I:(ê$)N*4skqG54R)X̤+AgPT(nhw$klkf}(xmv YϺA 2%ů; L!]KyAX0Ok̂lqWsMk,yO&OKX@͗ƻszdcFx$i(q{J' 6pSHOe!Zg(=S&b W~E4v0&u_KVL3/(V9nc ش|gb/Bb:x Əw\lk*!lMC8M?fE.t.v,:"W?bcx5T~?IUKmY:JHb1 DDnduw_U 5mY?tfGtHV fj 0ϫ0ǘƕު* :DwJ57߉vWܔr"鲯|$_1j~ś)5ds2+MY ̩3diʫնJdTXIY)TGWDMK|(0~<:?hBME9& ADXS{r@RrAqTxzj U_M$3ݤ+"+|nS"!el!"$(++ĸU'OoϽ/WesԆ-#E7BEL’J "&LL BBoLU`@AwDZi^5O4Ӵo4R8_B#{N '==OI(XW@va<0Ɠ` U@4a| 2{'r["A?Inhށk2r.Mo#o{w9gǀo Xw$F 0A8sˀr/V5#ĥ|vv&k*oa*X3z5[^RTN_=&b8xt j%&ZO K`4Chw'4:y_[9:QNZ`j/Ɂɧ B$}ɷ}a|!q&!2U^_ygv>Cs) ?:#^U_3{WP!\<ӏco ` NYBWn՜C^okD̀]di{_ͫ@71]=tW1w18;LnpGXVe%+7L'G=_l3|,&w͊kW>xk{0  {Ou܀>LÈ!BӔ`y:Q |bϊ^1^Mu+BnTZ?A1Ȝuz _},0nFÕx5S"-ۓ[/{x=9(e&zv[K mSH懔\#=$W 9F=Ka%Ef3JU1P#^1}jvO+ΐNsVz1=%nYnBZxBcಜgB`GQ>8\f*],Q|%=<8gHj.\ `AD֢DpC65e&(gEO@/c7j 2ۗ~sbY2c W.[OHg%W-^e =QPyXڱ9^PQ |oⵒƼjQe`Z $"[X*IІZ;dGNڬ踉-dMGfrK߼d':Wc?$B}D{2!J d"#;c.ܶ(YH?$4@&Z%.GAOM9}Z])j0U w*a>}gEZj٢mP+_D4||3d ?+au؋3$ RFpIfp 3+rq;$n9=w36k J` M^j]Gޭ}tF~jv(Sz%ӎͤ8PB K#U!E0 I0+<6݃(M % >)[2 䃌BX 8sKw%~ !T7ʵۚ,*F S6O<z5ޙǓNΑ2*H<@Z@'yr Ә;R=/s㣣Dzyռ珍v!N\''1 Si..{eSXjݤ@IG&e]%yL@=a4C[KDݙ !pzc'=FYvykQ M׵Y%vܤy0F(щ-&Eئe3kO\z>+ p%Mqk8gAC7Ƭk:qz{ LYeيo͠c/ ]V>i cL%Gpv"Jkh 1PP3)uvY%^/Z|cx Zؕ/q?ar@-C(WKjc?^e>^rEaf >> &M PRI.q$43xVE_ϻ yKIm{DHf?lq4U 8'N#o~u&ڐFchbuu%2s=)B.BG!1j1FdFlؼz jdWo T-ZXYR$ =hHFn(.VHˑ:/]^y!MS [8ނ?@8I{El|A| "]G1זc3iq:`&22Z{n-#XUФn÷6:>X3kA35 'URgM צz@+0wtafEN}R7F}XΗS%@VҺQW2`[+sV)g#:5f(Tvn`JNI#%Fj[6Osh~;ו< KVV>U_D̘Sh!ٙ5X(A(Ang`Q,/hqS/ywoӺSS>7NѹEu;;m۶mbɎm۶۶oUϭsN[a=>昣z(uv5,-JM:<(k ΢@( `kپ]= % fh\x_cyKV;K},wɷ O ^NfdHJgѸ`ARf2UX[4ypRչco2&;TgHRjyKL5~HȐtMdW/~!ec;19D3(>Q|<ib'^j8Q'o̟8=X79\_^جW #fx_`D\BvqQ\]oN;j( ɑ[m)SP!.[R^I}D|%!;`B_˨N߻,51H$'A<=!̩<Æ[mԪ!@-ۅ'24iE}Io{#TZykp)l{.Fw#N(67M;u"oVrI/;cV4""i?ońUㆅZE.=WyHܗ0ᙴ-w{Yҧl0V"@DhWa֡=J 1h t(};dp5ɬ Ev6tX!8pLѿ՗۩ojz>7'FW8yIsnYV=\Mp9mTb"X_3Ms#M-ln@oQr:G ]&aF. o9Чrܪs۲%"ﺅS_(|;Ov"͕f@2ԑa>w!u{_0h"BQs@k&Q8e|hN&~H ֒loė.4_ZŔS^u}_C_7Rx,aDr3lWM 9O&ظ£ˡK>Fq,L#PF mPd<[)gt/&,3u|mi TͶjb eOʿh@~kn2O(ʟ?ޤ}]Vg?QD.#Bąz &@nD%8V(<ا!I+,λD/F)]tˢǴymG,N*=<Rl.jm9XmO/Zɿ&ͺ۶Bۍ%Éȫ8Ň zJ_]~ 8=W? N^y&oS:m|+Ghy?TF4H+GP6|nwaJAyXWG(kØ(KgAO535 3v`=2D)FV=~G6=l'zePRw30s?gRe!Qke( wl|pxњswA9ђ(u3ffdq翤{m+dʭ̚Q6 ȘvL98 -1+:hŻڼB6bSo8KS-no8l:Kyfh 5oV+!U[adRJ'9*W<a!kip# ?i-#F㫉}<ࡡ:xn.K|2x\5Vܐ =N)ګЊF)W&V<@DEmJ*M2jȊq\A]'&`<׿BH~r0IOD7oE,ZhYcG9r0US h~\~I:P߃EybPu<^_M cNj4/>L)\K-4чow~LAudaQo&U::~D JaEam q++AtT aX;z&.1V؞#5 ;)O|XnoJB7ΏUtERKSiRX\ иZ@i4{7%)X8(fdijLɧ+F(DQ|j@'0Ri'α R$w` 6@3y9((4qE!潩6>Bjj Ns@_B߽@<< o>D1ǤDžzz׬ۄvzN0"mkxXy7]{È t8vJBq`u h(enfjyeYKzĘPrHD*q !14;pA'4dꌚBZ?bL΄ȢJFM6AТΟe @85C/_ "'WR|>eg!¿-4%llB<; D' R2>|p;UQJLe*Jq~ "P[BeFAKP^lcuK,{ƻ2voſ;M?ai.RykE4ܯA㕃`ghِ=pUx j< 񃓕rgk\9&h.p⩚, 8K[Lp?UBSSvu50_GliUl0?s8UqKNYGȂ3X{g*_)EXr6|q?\jR-u <֗:2zM02ڣtѴ09V7k'ֳk\EPn^scL>1?hdNGD ^;' = ȝJn#S F0vTv^WEv6 HbHFzUά\[SM.䭎Y.)P6M(KrŖMTKF, fr(Ԝv)`Wv3)(&&ujamNTjޞQL5$XiE o?N\~z.7{6}!\r (RNԾTK7tS"Dl|mir|r7J.v.!peS|t0yx+>| yaYBY߻ :p$Tqjk՘u8BDL- mQ\h}To!?cGZ!RJ)*)E2(@h3 }=ǡ`c/#"BSػ@9@1 -.Qj!^^_(66 ʉ>aJ() (c지`Z4%Wql$`w31Ѻ.qնg*jTF83u+ۄ9&AkQw+u1'uymR;N/lnO_L73CxrGR ϲF,*Z6qrMqFD[* t}_2J;o<QrBߖ:Qw6zUi8c>dIeטnDXfH[t[cQ @XMMrk~<®mE:;Bo%iˉ MK}Jt/w#͓hbqD2[c$l~ǽ= \:-:ćŮAk@s䝝?Xb~J Xe~MjY `Xmj%%[+:luOmS-HuSE$S.eZp_7LDe\TofHs@N:aK1@a?rʬ9`W%Yex MTu|wz).#&HYSoCi @"9e>@MS}l3sR U`ZxDE| kHD Q=*:{eF4@A)zo?w p{MTGGѪ{sxNJ '۩XgT9ݞe*Jݔ:"2,IU6,"jZ9{ [&ɏzgg*mSxRݒ%kV9 qL'[OϪmv_46ó>^cu>>**G`7zt٠hk7fYwn+)m/9Ӟp9:2MaY$♏-nK@_:F^FR l8\{};Mi[PpJ^E+4O@0ƈ:-pIjjv(: n/i֡ƌeT޲AXXP &jϷ([GHU 9L,CpiS1Ɨwբks"u+1F9yMqmAqMRII7-]Jr[91Y`j9P .eվ 6{b>[TG/R". K*%1(e*e~Ibq?&uJ&GN5W) i  rx1_ 'yi'mwt*@pZis<vmg^9Ԣ. '/H]o+1L><5#W.4Mï]Pi{:Sel8vp0ڟzov@NJ~[Ws74F=SJ['fMkG䔪=qFJ _87~T''( Q9?8HEE;Cq?m_Fi5x/'M{X "1B/L~ v]j6E %攟ߔ|}~xrr^d9G4ץ*k bQ1QKSU -(PF;:3.+ " zO}% $d ܍';q^`gDVF y'4=Wp#@` ŻN@ڈ~|x</blpA$sJׄQ >?>7P9~# ~X0Q >Qji V/W -! _l|ןS'oS>I515t)xGQ T0FA (> D (0+H Bx |]<]6ބ3jh^ {%穗FAS(4 r1#U˯;p JdO9>CQ+AvodBh}#p5/OK+ч/Q_#?-llX6GbJLJH;!hKcֽ)XNO*_Cϙ oy$y{9:0)>/)#"G3Z&者q3NF~$LVeNn(N%bNF%6k(L/wܸVQmaJ]4PSO[ _wv_s!A^$ƂdD↬}qP'Kt&QQ{n耎>yy]+YG8䷶ϳ<^&[;Pvpri[q:J@T%X5 EېAJh@.Y@$ҽ>L=o 6g a# *1mv1B EjkKMP9K]x#cZ}8ώ&F:2M)Nu"@da[fGu] |6:7ѧaDpX ~ܟ3(z}@ޔ:HGQ>.4dvzMRp2FiG9 `.T5ԛՍ;ٟoR)/=T̟y6W)5-JHa$#㭷$’mJc<ZߋבPAtK|(p>(bkiFa|qv06^MF t˯W΄352|y+&ۀh~rN2ʄ2M|| ٙl+Pxu a[¤ yXY(/<;CCm& kH{1,(1ʥ_On^u=L-D[Ec|`6cWEZG+Q`&_.rN:YM0sbRxLDž=R|6/)Uo,qK1Zą[w.Nf5TBKg6Xky>oi< H勊q>!& +seMbT ,} rɴn'{`<]T9%z< Ќ:.Ɲ Gͦ_S+竞 EE/SrIZ *|?qxr߻L'W|qs׽GQH+fMThm!-*v Vfn+UHs"/cMnne\TJ/N'+L)RShK?n!.a(1WBV&;о| .Pi\@AX!G+[7iqa*0KH;gv㷵IsCB(4|=Mcep=rnJ:8@ X]Kb+;aB鐥Id򠢀7/^'QÝBk ^KD95<67v?4C򵈬rcGI*D4SSv͌k4zAێ)@º`t*Xva(د2&Q+,FSV=RKRpRyL j?5_5ը{֩6-Ci ux'@ܨNZ:6ù+[u6F#uVMJ՛5%r m*X2̹/S]翴4 z-/.Aqy2dT_keb12f[R2 M뤽B+(khRr~U|^CwC?LQ.Ch fn0t13rQ6SQ?KIX*'P6!}48CuQI ^lfҕgn;l}\7ȭipWo%RУpV 4^ZZ{B D8j\О)UCmh*h6"nywn* ;>BһBGGPJ[3qAw46t kY31z% MlT{>xS8l;PKpe͆jo#=?"qJ3)-n1su- Ǚ@kvʽ|l_ql_֦c KH&3& pmD kz456: ޲5n ڎj-$\k-lv.7<ܒ 㮛ឯq3٣<-o0cyI Jҕ vIPUXe1*4JMAPjX„7*,b 2J:pùjI?: ^2zHL`r7nw:?:߶amؿVy7{/FU#8MI:k3!tC48V&qky 7zu6`",Bա]#7#H?M;-wYl[k.4O.|*G-x JSrO>*UZgQ"#SKn  O<5wfT'%Q^:o/T.쨬-9*^*"_n>Fqc(:dh0#hy Ct}oK"5 2k⻥JAK~w3izy!vCEy7R{&<`[>1 kS+eL!"cqMЭJODZ(z#* ).><\ [%.$#_#)pɻ!?miC?`Xh Qg UGzHBYiapN8}hainziAT[3jJJMwF&!M/qv9`@ mv4CpT@ܰ}p@PPMcEC&AZ9@T My :<.m My5 ~ ch#]oH^[frz.Ph0P_3֛BSO5}j_o_@9ث)λ4d9ߝ.'ai|/cXAK[_L<+ϢKW#=n89(^!}umQMt r7"K N]<IPh, Mv/+C@4#)1ls#" $?wIc]ߋ(||J^~-"1A}''O<*y+#Iu}syu *ǘqOb @ iDCV$>6 =_6 (.F+¸5ISoa~)З (L5Sz8Zj8gi}oνy~L[R*#aeefVO Nښ2:easը`Uon;es k`H1џ🮎-m }=& eؙb3^ 35Q @=,mџ"C)DNGMvOEoҽob_n~tf=Qτli?eVj: G;@HJ5ۂ}0[j>ʝ"ldҨu+)'Ѹ|yh>s*s6' }mC৺9 14FVz<˔]_B1]~𦑄 } ^bѦ5'c cW/T!D&Q?Z_膯:0o-?Rn)AW_B<Ζ8i@ttc3n@S耿5Jt\o~=IR|Ty~^@HG"|T{g̑2HPOȩ^{M0$#l2< F2э9湇.7]wbd\7$YpyKV! oKC/=7 ӯ$o+R)ua/ߩv7+Aѕp C˙<: wG / hSk)K[Ac-]glLNǸuE4f] .ZHuI׽>MP Y%D.-CZ"Q/gU\N-=QU0&|:y2 (~+J+ܖou׼dc~`L^h<υ$12EɭL+ Yw%̻TS- :{g-#E²X(=]C F%:j .1o%}ʿچVxV>;cPvOCؼBijh8ĴyOs.Mw.8a~1z@s0V ;B{wb 6\ş.+^#ua*Pl_Pk+(ORkwRyWejaWI\mx=\4+CX DwG6/DG}V3k>z$[MU~yTSogJ`5U:LfLEr QMxеjUP#9V/`b4 =mT&y *3sUX;0bا!.=wEk֦̃/t[ {-k:~K\u|xw2]΂"IO0%'DLDcTπ?`7}υMbؿK;ʇ}Nnq4{A9؛6:z\T¾<a&hd&=c朙9gRd[ iȖ](NRD(*F,ɒYG+ϓy~o9sϹ[~K92~4s,Qu|.?͈\++F*)3սItԶ8A膅j) >0<1.}E 9o.M;j$4xM H}C<#s()EQ)Yh{ eh3M*S^Y HI;>ָEYxήt*:V8|װ2 ~N6y]sZpHwqkfO\H}46#3L"U\Bޅʍyퟥ"T~4{{XiS?#摒E+W\ k9FV VD)0^8~BASo,KR[Ԍ}`1VNJw)MJJ@v˴ǧT}w]s&<|^ďuO|'TĤ YlޙL{W1璉iɑnO*-\5RȩK=q!$kk>[#XѮt~',vnIґݠwL6+X/T*[#ntwShCOmxЇ>D, [镲t'I~jH׭|Qk/kԳ^,XyӛKz_FMVy ̩5zOZk,=CQpOI;mKφ\XMWڱB,p iӉS!R>i=ۆ/(H6'}1踴q60)O< ۶ŅFvn)6#]Kb!uɲ.˄u+y_0)ZZhBa8]XKjVNG#h pKT/"6O.״8/C/3+CZ!)STUt 2UOuH<M =H6{$_9K*itAcʠ3>'GnGmo\^/ߨ?6R6c\j}2/G{(p0tU>1YPhO.܋u7mҵw5d@W> ?Ps1NxΤK2AUM{Gv-ҧ[==Y@| 7<:Ӂ;T6:@6UoȰE6\|vR6{DA;䢝wlڻR')[\v|nA֋G%VOE͘t^kfO..HTM +=}iO}H tG'(ZK 2ߨ<^iГ.7C-HOvMY ԤOw ,]VWea"iYUveoPCěFJ*gNUlLʭc I7w_J"؞ۇZKۈT~ܯR:?xhx_a窳CK!%+7]/L툆[8V>T  Z~%U#K_+_D ! _Yvw&ګâMΞCŁM)u|miR.Mr8!Թ9X8t=z $_iNjqrZ[6'kOK t:\b>I"n^j:%u O^E7>mmOrU);? n4vի6(CZ+ o;KRw[#8!뢣wTP2w;ц%_;VZ[zSXo-bHTқMi_jI"jttQ6#}t{3MdPD|1#)nhr_b;]o38NNdK]|vc{+S##̙=gkQ7ۗEDo W_Ǜf#xQFa!2AW3$L mie=ir/'Zɱ+' \oKЄyc0.f)M=<;T!kf /Xb',иSVسtdU;[>'CeR8a8D!N ߜ[u5Q_l9'#BL#D$wZ9OQ˨𛑥memcǝN!a櫓4Qq%Wq3 kUK[ߚ9(dp~$`9+/v̒0)oVRrC*}A'^l#5 sc68k: "*Hqĸ&+ήJ|$ AXWyǍnD>{n̅n`Na֓ lr"{h90S\qoD T*7Hп[c}ӫ R ܵ MC2rc =]}|U d) dE2AQ qs>F4 E޸:oD9 cC(Ă02 2Qʾn\kjYT_9]9ӎ{ 0_gmͻFeB.>{gՠ ˠcUJ8o/%QmLکL0}sk|;f\#}ɼj>i]pl_O C]po4oGJ-"/Pvæ''S2ߛ@xMh\!֞֞@@RHzy 2R 4&ZX!է ;0 e(=, @JPtGq$B]3D0}Q"PGJ)j, XL7@B@~y.^h9/-BL )ĦAZźw&z?7:|4ԁ >dK֫`34e6pfW;Et񅖯_{*RDY"Es,&sTĕ)pEKS83jM%Y畑xF/ i ߟU*yapK[rd`C͊orf |rĪ}AWrfE;U3+i13O F~8+7mM3Oͨ*܃BZua#]9H޴%.V*PGTڷLIq4[9k9+8dDlmׅ)"&4!TXsDܷNs=Xzͣg?l;N6@jbFy<] cE.T,BI~F.έ X?EZVsep=D:j% iTy 3 ?ޮn-}>Q<$$5ֺCK2jKc=}՗>{XÃ^?N7`l(wx%u#OI/O松S:RxQ}枡Yf1ĪhYsj J!a!'PCrX q+gb BQ6l1zf3mK65F44eFTռ>{]xu%;X^zt\$'}[QdªkBsCr큁hK3{)pRN8~H&=t Tbx픳RmF߆/:8~|iRaj%1w|o]7nq({%U(~$8߾kU8P$|/@"}Yf嵜(*qWPaus3ʶ)ފ2)JV>K•z%_Z;yW>)(Y>EVqzR/ 폱DhH2ޙ)$o ko%֙Sўe.w3cS>99n%0#*S3'N)!;/r'N2q =QAtm^2?6#U~j4LpM6 :7F@0D|( !Qy#uTS8@%o0' Qnk&@ιNԊ_a@yPGi8,G3VLN_ebA0q \|\CĿS gZGr5Ҩ愷YU ڒ[LyignG^wy4l)35 ݸ7{4{QwZ4_/o ]L6 ~WC7{N;=%ٳ[Y}o*oE-y&浾V wewE{@ :ov~њ4~k*!~+0 9R{1yΔ<4ʻ fW~}շIy,,7kBiR~5ϛlR I)EIxP&Y4eI)p=7QC5A &qmDU?1\wAصowpukЫ#9{52@!-vX%:mrWkg iJ76i!,3vCt,0𵼎Jem8/ďB%/-Xw;+£snYƓy'(Jl2)'oNw^ˢthb5W`7Vqw妒z[5lfn_x]qTȽ?6f|QUᷕ=ž;飖7X7_D9f*SU]y_O93C@QsU\ĊBߩ̀%ZII4x M!,&>nEcd<(v!ӈ%ѻHRy3]o{̊%_s1q3uSK3Wu˙! uMW :xB5 q@JyM',PX; 1CNo@܀ǹ{Zړ̈tK />e"Qw:1#ꪛ}J[xחQzW b}bQh 7?ec' br d[ 05V!5VHz/z&~2vCaK9;g득Ϻ>w1B&- eZN~l=u2 5>R>{QG=ṉ/m3nKDAĄ+c_簌k>n3 # M\ê;F\"[ 1=Lj1NQ׭GGLWG<+=KG|Fs׫HqNdO 3E tTD ĶƼWpO9"*xaUF oEyP9|Kq}ƍል8u>.'46cV|~V/gǽ.N/2VrB QM$%i=g^yU=n m&Ыє%$!^әtNMxtHr]t\Ab$qp eybH=aQQo#zR;{5Sn]^&:,Y?hG~A9S#5g옣bE);^i0cqbsSU!*(L:9;FNu_j.5S d6S #_=oUi K`XQnѯ`:Z%kE-$vY=&T+d4`hQ#=#/mԕ:eQ{d% K/` -X|rŠs0?fuD/.X.$(W!XAպܱ04/rw8C@ Z+Ъ8sUrG'.H@Jc?BwM4f? @/9/*3pqï ns8僁R=J!Sb"{R/p8*WG/Ҷ}_,"ť7y0{'cI`)F*0•(A on  wA%@0<"kyi0M:w1l OX.vR&IBl0Sm&~AөAH##l cX8kc_8ז# o/X[nA[/Ɣ4#rd9vtwL[aY6/AE>E-H,d('k9~ A +X=ElH)spMܧ't|S>`dK%Z!k"*NpG ez 4*|Ut@-o3tz[ʫOd:W,GEbdxsiɽ 7x<ϫyٛJ oS'V) m!?WϷ|؅&~uKР `O5iPkch꿾G:G^*kCu!#7c [D]q6V$pD%d x 5o޴mvCBњeMhAؔ*H VV‡S. 6PۚESK8&0tkR6(vv2':H2މ 2} K*2t>4;!W:q\!ZG/1ɾȉuIXCo=gұڷZyϘ_2 P+(L +t=X@JZj(*(fnO}ZI*( ,4uiF?,Jb+BIy,L&D=rzoU2J@ΧNmѪlW\O,E#ָ:Ό_=^x7+ǎ134Q;ˠ,iSS~L*_o-zBo3HMm$Ů+?Vy'N/KH ˄N+0 4P-sV[`xC^(8\g˕Q"|4r|-ޙݺzMIn;c")2}/κA8l,== {xs>s:}&QAwaR_}U&3%ղ,.b B/#rΆm7Pw H=ijm4d-{/ X4=Rm 8a ll-xCR;'*w#BHqКYI8n퇅"Aw Hpwݝ+\7tޜՕ~9Όc{5ꕩyOH0$);t[h; #],k;o'sUύ㌗xckwMt7Sɢ#)Gn4XfwI)"9I&6#DXz %p514zSe]!}DOY̥=c<|xGVqhAh9I-Cu@I2i*'@ռ8²f2x`Жᚂo9^qA/GP :"@WWH\BW'* QA#ԙ15 {#,!_uHPmh3H,oPu{28>ү2" ~ C+82пbԤ ^ ԵH59o JZVPTvD;\n‚.;IJl /Tl:{R't9}~=qI[U|b.id>0pzY[y?@N 'Q{(gqbdtߗ$pI‘SƜm7ũƃ D õ6yZ{mM*̗Q@DO&œT\C6oA}JFcXt_C~<=@ӫSԧED)6V ).kʾM{Շ6 M?7Yh`ȳG:IotǂWFڍZT,g:|1͏)J%%m:hay}qZ<݉73|oG"DƳK%c!b7-#~^ɢlE~ BC!_)[*  /P-G?<?<](^+PC;ǝ_0! $xiߥ_}\R GozQC.:C @-] | Lva%pBS-@׀„@ҕA`P8RwF\P\\^ AW 틆\I P m|  `/ERWˊ/K=D#.uW1?jא] wE1_QA"^j1A^?B3* vY颌Ds tł vzW=@aSİ/e?+E/b0EW#^t^P Tb 0z]ځW!]$!W r ]$ w*3)_9?S_fP'..-ŒF\:ګ\WV#/+U/*} / %m: X]t  "_h/m@E?@UT;E^5ѕ\jW<(b^i0 eHMKW /_M\^RџU#Q]I.r.]iT_,]u\:XrW_Z ^t r'!sZ[m@wȫ\O?om?s7 P K8H pCgz*x.s/,\'/ wb) / ^&xtE\VooV$ ːC? ?ELeK_uҁ/!~+UxeLoIˈ ϟ@$RA.b.R섢%б_ S4z%[/l 0oQ)␾zY7b@&UtB"Bg4X'5Db 3_l*_)./e?^ڀ]Dgo^&zMH 4:}oJФO?U~/93ԦyѶ95ⱬ/njpȍT[G?u(v>Բ-Q1 ' wDVaV~4rS0ocvɞ$!g$,z: cH eq`5s2GxйQDxEaHF`C0L _Ӱ+;nIsRu>NŦ a`z bnG]IzC6<ߕRfq3BU 47WR4GWU4Fe#h4 g%$G9ԺxBiEBY3^y;d0O(O!]s#_aDc@Eb~V(~6s>>w!K#)V,5r10П"nRmg7bja椬o{R ;҇ǰһ\jF)i/hMޯH&1O6: r}ٔoϬ%?*Wz9g NS04"ְQtGoL(}[<7F7y %#_Mtw($Ew3}]Ks:Tn6Jt8N>v ^ `~f54Ʒ6AIN軲l{[uƞyGXy:} ="nz(flk{rM-ۢԈ&/K_>d<^QS-$+#g`,/ӱMo0AK^<iZ9E H! Sasyy%w v-ƀnv?MXBU!vFϩMv呦LVi J;Ko͍ʦrZ-%1y>Ze{,`!k2.¯ȉ׬5<=]'U2c)\?b[[R(A㞌x*O}L4a< DBny@4JanFM\ٴF♿dL+B#fsvj_6F(&y;nB >7vN7,~q|z!ڏ3_.jKr+Q˚LfȄĐ`َILI}ۯѥn?KZӭxz%mFbnLnZ{8aZT-Of"9yhI̴[zcQC!8_^°;ṱRKnDė#q#ߧ2).AQҖMb!hAgQt#v8Q!8=w-2x0-}@m=(T+ PSd(T.NuAO8yoOdk'5]8\RRvd4li,x64|r?01raغm Ռ՟"O3 5q煻l E"FGZoKB RjTl 6>b`1F$ F2R$SȎM%&׺s^r`csNTN;"n3Y$4pn`sәyy=8DŽIz*B+{B,S?V=~#9N"b"P|NuU q3Yp!22uuq2qTؘ VsU;t e5[bMecTaTQR.h=15>/:ja|LҚ~#L,ZioN|zi"^cMweM5E,=|_YX0BωNU^bd0nPAM\Ђ_,SrDdyoaw[ƸDՔ2u|*#4 #ԕC,VZ?*YQ˦ǗaׇU[2EϦU݂Β:[g8&̪ccȞGgc[<==k?A 2`$M r."9WKu؎mCyYπ3M_.fk /f B7TBٱ<͉D0mꣵ5խq3}xiW9~2?m HNUA:i{Ï_S+"z:jw)hCŶd-zINOקa~&Քk`,C֮[Olz^KkzHӃ(-vs%T%k셨!m;QYj҆Vcfׄl'd#Uʰ'rմ@l·V <٦a|h%Qz+m͸dz%U)gŹ6vBZzzc ~ՖbIO]ݑtNԃz޹ /F-ȸ^H9pĹ((UT-xPw=҇k~.3fд" DbJY2=pynusyn;N6@]ϚISsISR:o7)ȚLj5b wVRsQv z~j&NAK))g)I}'Aߐb7VޏƊ7O)}$(mmQ0NxCŸM߽'843 k>Ǿao˖A۽݅o*}816@B|:w.9=RjI-L5b˺7ϛyF՘WڣG8ly5x-<΂B䞟ljg8>$>4FJOT0R[8x;An_Y%8<:)(x) >dv9ph`sBE\{MpfXp<IH`Lr{ޡ ɗpTOp`uBmk-/ᖕ;NBba!%G[/ޡ=:ܤZ_JPxOZuq]}MC6~zoY!O=j OQ O'S(rU>qxV'yA=)H>/}GVօ56 ! N tq)Jo=FL}7,e[>l{ sx MKaNkԻwF)#z.|cU8눊v6kI`6}zAn]KaM=7\\8i%CɷY΀nOƭrt]:M Lgt?b ] \D:y~siaμ4;qrn!;Qpl9`JOQcx{jsm:{nЇgS$Nw2>#G,Nԅ-R5q2O -| 2>)WcH `my j2{#;\ʣ\\[_L1#&ߏ2|S)=M!['Op .n+,$t8B$p_=Ȁ0,feNePG+smE"Dj: ;=EOhN%>p[+=}>pe9MkWn@SC䉺Q WtRO` y'a wWtͻ,|%dTHQXKnk;bW0x.}*[r'n2Ǐw2\i&dɧYFd c]mdpV k08Ll@)D&IQ`ǜSWAXuIb٨0ēshٛQ|*j֤ә궔:Mxri14辺VR|hZހ0Y[nfځ![+/C&9HpCeu|E1Rc\qXe MG_ ốI94/b7 UUDt0ŦѢO;;G}j37rKVRN&l)PYWebSЭJ/o ?_d90}FyHa-~[JtB;"e3̒V:}N?$PMˊH,e FPv}\w|$P} ˾ƦC:wqޯ1d2nIf5D@\"PŻ ʊ2DŽl7oY)|)}h{-#%)ry|V>՞h懻A%/NkpϖUy],cB$0EE?ߙo,Bk8/me4Ӓf=Cza0ZL~}&YyT<ܚ7x Oh;czr?bx$/Ze -1,L5S0KZUm]~%!jCifNŀ]9YzZCk ;pF1#6cD*1峑3Cьg:2֏!B >q^0-M)16li{?l:qcJbFr]܆[ʤț_ʸpgv oS/_ !]$?j(`T M2 ,Q6zsԟ#E3H>T˟؏ 2DF=bWۢ?NUߔ.=ePxVҒ ITgeca.#u\,70Co/[ƈCKfB.^~A0?xOHbSHl Q")]m Vįùo(coEme1+ Qlo-gbl@4=h\vJ1ǎ4C M%{w|~~$Ua٫N rɑJbg3)wso,xE<'&N.ewBovbL(ӑ?fev<٤374iYɪE}gG5ֆKCC:1 !i8w_)Wp}:_oO fэyGr( VˌadiS/ 9Yɛ~ f9&o½YoI&pgy(; <*R :[SSos'(8d-xLM̊N<N7$ ؒssOA c|bR _r ëuq!bޖ \cCx>q݄ڋ9oj<~٦Y_71h:Suo2b]aيgetj#~%*AVF8 <¯Fr1dvZ8 DSx:m:G${?, U˩@j54ڱ"6~Fjhf+(7[<ZMiX~\/yzw,]ۧ1-⤂)_L\ pE<9s#l9i BWF7ŏ<_*YJ{ŭ1h|ZXYuM{`P){y"RLLXʁnBt 2;8ATUlC|Z8?9pt}^ysQ&ps]5wip7o̓+_;(Ey 2kF99JvF{Fx'}8C9=CM|'[b?U 3 |+;yZ_{-hKտ8`d$E~8Ͷx V?ǽ|&fS܏VjZ%'0&s'Ę,;Ua8*3ܰVWS(,5wƖ zE'۪UH%-[p:5Y>V;'7 \եk>\><RwE(7a1ӶvOkm۶m|m۶mӶm>Y'9;;ySy/*M.od`mpd'(YP}侽e^lvx~hTLZsPr"Z6`yO[a(Jye!uŒ0CՈUFuݫ0ej=G <İUl쒊2 IH@>#K~&muǩn !^\ďYU֛L`"<\e4߯9BkLrsJ1w_qgJ\VU0~QԵ1?讶iA /g`@J\|b{;RV9cC&RN3VppG)mfpȢb0I8t^/|6chAU\>mץjs0%ZY5F j6f۷3-!XM@&2lˋ Tv."(Lf"C`LJPB k_RH%6>hq8{Ug+f`q8ŇMy$K ]ie&T5mT=>pn_1`<3?>23b\iY ҌP$%c:aAߞ+K+]k%T  dv? wu^2;fN 82 *r`x>N)ĔphȜ)`Rk-G>2]4 r"Q;77`[9F78n27wݬ*&uv|2|h1';ͽL퇚 &&ČA]t%ڊ4m6גOCz>HX(ip";~-x"0\^9lˠ\Zι 1Pɹ6ct hwGQ [xCѨ&B9 E]<~ {ܱ7*̓ॽBFikPpD!LH"l qtnG22 b_yA":WЙ6zY;CE2\*#0-Wi{ prU  @vΧ0>/+, desWOo"uJ*1c+)W_3Bk*&)ySo@ Ic+a΋yd0j:-_'s@5 yG)`]!/H=7ƙfbF9-]]UL<I҂G ? jXd+.n Սޘ{Y:'o գ3Ǹ+][sDkJ~$Zm$z{˷^jQy#X {cmc֡xΫÆi/{ve6"=`#T ~sUYVw+sE)]Md6*-O"*_Džö́d.#; {;>:5h)ArYkdqZZSO!u|SQ&\X=YΘj'Ό,FZŽZ?Ơ}W_b|v3k1 ~B_1^p4svڴ~{k\A V .ޣI '4T / yAc&lp edm:7HgtOdy(QWa=e_N@ [H'2nN gȞWO2SYC|Ǽ3E'KQ`'a:=T 6xd3i~c&GC%̄C4Е}c)SɳC RY:=13֔.~~[ &ҏ{@2m\7.B*S,5Sic\/b paye='jLw{͋M͑ OߡO)Q0`.VIo[|Y|j&XV0דf᳅N&}s뤻;=?p>#胟FJ, BGKwC:@Y.*1 ]ʻ4dt]f5X1(&])^}XۡmNs癀ޔH![eV^p .J Y}Qm0NM ׎)Ha0((3/`Dlmu>pτJuŁ`x,-]]MNZ&Vu|C^v5G"A|kDz*%#FxV9_yX!^8|!ep@'a+_ SٙƫP0{I#.C2agƥ0<)*u5pv,˶X2$|O/w^8 aH39XۮDGdn Iyg&A!PȮ%E*=9;z (z.;LQ{˫919S~ݏ9aMtŴinj\kY~[LGZdl#tLblBv`XTQ$v$>i\TP13BneSMl\VȄ PK= [vW㹓*fKgDԫh!]4qAM;ğ,Hvb2NQ!")& <_.~iɅ gkЕpɅ~*W W:lΨ8LA>6ZȺnL!24h͠VO'yXXf414_KJº d7/ cŅmDgu2|-s {W1l?H_`{ƐlLL]ƫV.{$USZU 螸Y6q.KQ֊,{G}?mw;[u5m5wF ߚ?ŪȪ{ȣ^U+rbH@y)"yȏ (/tID=.L&% pW"90u[nᕟ6}k|haf)fw1ynCTZ)&흘U1~FˆiZ+ j* Wq2tw^ h+ke7IWxR`! N&4J  f\s2DE)!>dT"P-ۨ{;Jt"SI3> wŝ0a"`}"NLd{%A-@`< 0u\;<bM^ha˅g=F,z7(8V?8?` ,3V?%!-PIOcãB߮0KrO ɳF?93Òtg <*-U뱑 r7rS6OD+,; Scba0njNBdc!T@32F3U;sSHaz9qrnH[{ WVL3AH O4r9zsthx7bbГz܏z\vE0rl t"<0%S&wz zjisSh=geTb(]}o Ģ"CH!9n dQ1ImZ~I h싣U5Jov!HuvhwRG#& jBLIw;:Mr!5^92Q%vo"fܪ}\ erX'DpI4`4ѻ.}G\<>r&#?":H@n Pj®Ҷv2HsZ)Pu$O.udvc&(-?d,#R10h("zkr8tƼ[r I~8HE`}ћʛWH,uJ^5b=L8L< tg.[Ĥ{ pqÇ Zɧ Y`G8|[ewpp䄋@Z_6񠰭'LYB !ԛԷmW@Ҝ`>|1vg+u<6>)8'E{0J4`B2ŬD)o40~1 򬧹AqkQjCsıSi4s}ӰE,QbN9j=UOruRX.ܱ 7ɽf\RFˇӑ&Y 7<9o;6fGg8{9I s۵S4+} ݺ1C`otZcuC5i<ɭemXKQaXDRy QVpy(;UXm hF ex1!Q{4T^d LY؆&prhLB!觗\@ՕB=- ,F<=vU3vUfΦUlʝV|<0h[^gsHo.O($.h7GZnoɡ|={0>!jCn6M͋c<dB !EI`Sdp]3R;S&Ջԙ:-pˠ#%iW~ȩenhκb;*cj񴟶Zk-^'Iԝ0uIOɻ*jӨz*O̅ض cK:0P%!%S/8&20!֛MZxC! 9η7J̈eۘ ,NNxC2LM>l#ʼn*Ȩǔeǐ#ke9t L<WQ9_Ey;]RZ Hl+tn\3s>kOU :fb,%t^Vjt%mJrW$ R(T(TFqr$[ϝ=_Ot_d82Sx^,?vy^3v;cc JsYv\I{g,>/8_tTX.z-"٘/rgurfA2*src (3}[uD76`ۋb~0xOA]q1#}-˷$[#ClA6z9rYdcnEn>'{L~Z[}s7r6X) tSiI29$SwA)3~2_!4䵽శĪʩfN:bغ{`Lwiry$VfGE`2 lnS!c"wIy؃g QnƏgRVg?ѨUd,v%4M' aqAC3;iQgqF$ݭ.}uRg4#K|a 3~q5 C ו1rOϡm ,'9f/CBa2f3%Vj '*'/,fAW`,u"!jꈼ}+t@o1B;DPxc/ E91m_fGUYH*P:K7n-c6"10hcp"2'GHXzwPyZ<nwS0d7jp1P03E5ȏ>)\E|~xK x;0+ébUk-"IDAȜ4٭XN§QBp%3cQW XoW)^b\t&-@:ٻ1s`oGABO&#> R͙;}ǟy  'PNl᝻!ٵkś[~-@3YПգ| / soE!ڌ=L V{KKT~xUOOq71ۛ TN^~8+Cȳ u3ԂdeT˺jgpEzިSm1FU܋g|5;Y,<,Ϲ"FRw1rvo3Ȅ xDԋ,E~ڍ.a{`b( $ݴ+ qM$.W4+U|/ ipp\do=AN~壌vx{7eԖ${$75>@WϬ˾-<3BL1\$KIA!d v WOZ 0r n.b;H]ٕ ^1{AhS նUH9saayeԆ&a A0Cgf( q~*t 6sjΩ.fw6(>yyG pbS|^ dgh؜qo63ʤiZJl.ӭuQҷ-\OWp(R8pk&>e @q5I|Fo4#KICZ>$$_j l̝f5* 4i <]U=u$jWuvCt<ͪ8(C@)+( =]~W-[Z+ d%q'6<;EW hQ؈NW<|հ7WA@E!% ^SFP ]^u&wGH7Wי_VDΤT[n&RQ8{]")૿j {t~&7[_SJUwFX44:m-7O= MB԰(M7l Ri2:2#Bf "E mCyS |KͫX4[&LPpwǁ.{uG [+pRLM'͋m8},;! Ew}@XLG,J1^`"utzX\ fx0Y=Bmf>ɺ`4ʹq%Y}b6]25S:#'%s[Q-Y4S;'P;΁NH T81{OD'h)╄62zc__6 sXv꤄C'GU994wbC,&CgzpvRunM4V iCպ1Щn~ßT~urQ( @;`aϑgQXښʻ% `w0Q\ʧ{z~٤YKAX9*e,A[obpEKST֌iRU 8lWuYLjWQO{T0FF&.Rt"yn7,Od^4ϯ=j/=9*_ڥr)%&uJ>Εqw2 />۵;A gΗ~֪Q|#}R;2#-5`Ejn5雰9Wݞe=JL`%)K& [@ i0O6ݯSvSJv42yc$F+m>E!xȧAF,4X&cL{ b!͛i\xqw S_%% Ͼ<"l&ˎKn3S\X0uN\t,n ,dU"29CԹđ[w~Fnan6>YN7Oa Q4m@Q~N1vS^u.<"v٣.nzcF ꞣE#@!<~ApK*u}UHzAD'D( %,Pu⼼E/S_q(cr"~DUN䂧׃Ήa7_ ^֚f9R6/fUKh4&CE3\t|%'k19-Oez\2 aǛyD_eu!fkJɟf]kϑخx3 %lb *JMƎAbRZyz@oAf)_ɯ uI*uOŚZe~ G~=72 ^}H2U9.9VϤlņ:ALӉ -~ϙ83N{s%{`[,9jK3ҧ[:0o%6("/b`cOB(d&sqċ(@+rz}0D"HDsԸ.8ue~5AќsK".4ɘ}E+Ql/bcs++*X=mU/oOg ?jL^^F%g][{sX%7o0)s<ʳR VxSxY SMyƝ} U {qMx_ 'n% LjbAN(n )nMo۵*U& V|BFt}xGzvH$N(O5tЇ ͏Mo?5ÿo/#6#N@ψg-V.O{4dO!5)Iu *l.R9Ud"Z7 {,Az(zI8&! p+9 zA^Bbt𛡱69k(*iv`5гy3] (Z^1!6#Jmm+ /C>'/?:B);h2FsqZՔ0$ϘC`q׳Pn;۵}bÈ-{^dnQ=jyF&LBX+u o"6SH[Ʉ?<8+wH3M1MŽ?ȥ<~mx:X;;z.4tjU.Wr\L} {Tgժ'S ϴL˘XGZaBe[^{5:;LQ^ 'RZC-pUl|;jU+P){lN}9~) ;I2kcSe꺜 R~I#aG(9q6b1nAL?CCp5ly|7,PYZ-J]!Ӂ\i=!ܒf)wbGCXje{E?od@>]H&.ڑGEplieژ+Xaޔa=B}[7VN`?Z?>׬څm9Tk$e  $kj9 ޡ6UT|H&})lg.^6A)$٬e60=,hyiA61mQ\ ns ,iS&9 rZ`ow0vّ9؈`$$Nb2Aĩe98M-AӫORPa3?k]Csx\+qke)t'׿.1TbV-U,B_q$#5F$F5 ?:*I:=u&.mPJV'ItA+Hwhz;RVT[@OFSNKJR0OcRTM>ǨYRȟu.ELK] DwBKLe8'X-I#4QW^Paqw&F,mf18%HD1zxOWװ%*QZgcpOKJH΄hho0E׿޾(ulOI`bGx'6 ^{Wr+$sĸ)=%ҡ sAgI;Qϵ\lc[D}m9]Q0.' J7"=IVַScWj('WپB#30/1a%oz|`Dv ;97BC8pf^hr >3Q*дZڕPJz=yt0}>< ߝ&_m2U _ Eթ-.O"iڔ>SsGY5'dmd36eW &%hb/w-S=\<ӛ1B?[JRAzrɍHiW2w;Lڕ0! kf<8 L諾!H~Y 󤄃!-!(r{ N[uO KƷb&׉ ff0QϦo%!yg))b{32uifa2Zy«@=-7PJG{4Gyx4 <8 >y.Ϋ-RiE< !r6q$U4idG%NCI_{K]H8#;L,̝S/ Jk  h-C{F>6ZZwi,̾to+#\ {eIBX|Qq+B[1: bݦ_Z'l.d`a8!ؐbhB W?D.PϐyT袨 9?ox,!M=MG!{$ aWqQC?  cqʾEd Ǘ@ |NKEnv瀍o %l+WQP#c/lvg3l+惔2ܣ7]yrŽc  C}8EsS^Q#2LKo"?,>b@u$*QtC ΐD0/r0̵,pڗx(dcite`IWVtED;$ߌ r\6!EvxJLz YV) hf+=4dҬ 4a(rh4ݼzJ@0|&UDtL8I̬rvF"ȐKxTETg"AtW"rw Ńs֮zm_ ]&>7 ǩ _i 5~YJ9\AUUgyE">{Uqqcζ'_ב>YIpv˃/Ύ-HHlմ=(] ;wo,H0jn9BxYĠXJMAi/^FE07l|/ֶGʨkΜI65fTx-ZxW`:Ft&v`lfܙJ*.@DgoC%kMAh>GwC9S-ە^83\UD'Gh(amRZloiMa(Oo{?ևCjݔTK3nfߏ=ǷJԀ{͟+4I~}ea^g9 Co&Az[7+{%Q ;an@M]{[aI @ܚsdDӡaOsܷ採 rO|c!-l`:ÔuOzte9VT,(v[*ll!cFQ%mpԠ הKD:Y*G{m1P #^gkWqjoJ¨̊tTG.nkL~Eԃ\xU828ͧ_a#--O77$P$ي =[)ǂ1&!\M"wRZa-!Tw;/]lr JhM~NJK8JFч_@}-n _3fo-# āE;Hme2Dq\P3$>,/sPup!??/G_g j=GYVt=Tʎ=)2#M j(l`v|'mIRKIusvӯ~7./gvu E4Numl(]}cͪND>LŁߋAһ?ݻ|W?W- 9ÜlՈЍc7z*k{/ F jꓙKuz}ONtb'JzC$t]l y3|][P?8VOd.iiM396j}8z9ac _ͤdD!dp$L&]f'x#R5Sw+uqJ*tōtAmx\۸H1UoĐ[K/!bBO{"QM wV$Q9i@N| 2* :_KL>Og:kb:X[(| Ӫ{<1wN#6SF ~XL}Rh8dckg\]nLhуSf==]Ҳ}0Dƍq lG`Ij!b3VkP-xq`p/LpmG<~G20OhOUv.z. K!?]iht8y" հ?e5/W6bXwU7W8ߺt2 \`Ձ_Se0I15EghP'0F:[WAr :wv^Ap>ӪUukWxf`k4e&?Oɽ:8=~imX?pTH*225g5H{6IUl۶m۶I*m۶mNq=vncuVkzS>N4O\>Heݫ2) aHrN_0AD0 y'HzqO530H{OBڟvm=Y^JMzkőYBrs=K.u`,d Jis΍Hg}-j[zS!fER5>].)x lݩND"[ZذSކׅ,R:-RV4y)!FGMIR5U0Kjڤ9\m".GOCYaqDM{X4_9~Vᷟ3ZrO_i:U8I[)saME/ uf"8b-˟;⯘ʴ͏KhF}=Ε" ȧ۠Ҵ$Oy"90,WnjJRަΏj'y|c~^ ]TzCǫ}DPQ/_z[e5&a 9_p_\JorK(]P}'4gnzիP43[CS 0p}:l~Mܵ*Xl5sP3_oOS$k.yu1xD$Xj TDd7UĆ[6Gk#O;N Z2Vs330%5]U4oQY랣x˧1*$9gt=jI<3jJ<~T|5]EI%4:`:kX^‘. }Q镥pn&0Ef*Uh(ʘ9`,-מl AQUy ۮ̝5?b"m-<3YIƖ%TȱEbz yjlł{aj]3M;(Q0$+o px  ySLT-praPm?IZp>bM a0JLx21bwgQ\O%!A#&U.:fڦt reIJ$"ȝ2=$jыq_ыH|z}3(KɳHpvKT:CnH:2; mv)s?:-}MXLb9SXi!S$O </jN'^E[|WN_b@~7ae#7vY]*#$4noU6/&"#((O=U)k ?cۚ~jg%04%??TS`,cI7;;{z0y{W,Dh3yljH|D֣LvM;4ߴGֱֱβvLjmRT%+u4c~h="G(eor`DTZ`02vv"h2+f,(b陇<?5tO.O_aBrn=$;<} zOu[`}>PDpP1~| WoH#_DB`_~춿w}m;|"#wȭ/5Y=K(Lt31"&jtz-8z! YOfB:GuiReE0s|s3쵔·80RDڬ_91`v]j<\=n4-t(/8bƙn5V3?!t@Fhbn}"`t>'e wnc"%GolE*Ȱ*+iy<Ȱi*zJ2@IY U2܎[v6+a?lkAkb y:?fWWsi *%D:}P,96̒=V! o iUfwǂF$mnkLo$q}hOyl4nWEv=4AIG͏2Knˣ&lAs]!aaO;kK$ײ.֩0?˜峫<[ASLJ`/!5}6^љNՊTJ8ٜE, e jt 31'kNOu쾝 w[/diٲb~gPW Xec>rΫN"="aO^F^ TƷrevdm1N߰3kdcB ,ќfX/xG1Ǯ[oIk]ڱEFüNb[U 7Ӧ$a8fvz ?ms ׻V{Z>% q BLݟbRurg;F4~>f0 U+ҁY&yZæ.TccK|qjĬm$6#iɮX$dC | U~A^xq @h$J\y㞗Uˋ9d)D9A _4$;ZGۋЃU|*W(3I/ƶIT|5k%JM->HVMN(m#_Θe-+~wM>Zt{2I R"=: SoQPx _]BMh)WH-5[hOM8vu$TOb4=l@3:^ @ܕ¾lgzv9"DHmhrLBߛ֦I(E|3J8 /Ct>?S,,D#R爆rȆ᳉`*<=e-z{nccMن4!yc,$Ջ8J-HHq1B4Pf$633 C0٠P)7}&a9ׄyx3լgGCl6n̩} *jtYk08E 5r6-–8][Ru1.zf0pu?  o&TE"X8Om7}s V4l9;ׅ_;7St|1x2[x~D0.JZd5ݵ>Eyf(BIb)C;}Ɗtƚ6Es8NFlىGg<^V$.9fBUsWFmNbi0Sϗ7hl *:b]vk>L-+esIVLz:wюLڢvx/p=) ß%Wi.>Z7n` t!IrtF+ \\ڈ7$WVA煹#$`78^\!VAz7s>gJBl;hǪ琄K322HsE" Mzp8YOsmȐ}ᘍaC{W^bpCh>қ,ؾY14|N[ƃ-? ש RKO©@c8u7ؕ@= }"we5&c6}T,;a<$D%]뫢G~Ix$#ҿrL N:~y֜r]r~#eGo7R}մ21be[!JJl\2]U'^`!:e% L?}/_䴱r{깮gme4$4 }\C:cUdtB6 S<"Hxcu%k(Ֆ8`I(=cIQ+T1Ž;~dq.U~ZnYAFA e<H\eij:[#N4~iKDgq5ߜ;`oU$q }DS"ޗ0r3SI;B}"U#6a_g,BV%K[&)ϕ+MX+d!4{ufa"0*GWQ7J8Ğ%M,eq*d[:Ep Qρ)꾎6Q|)<,Q[[dqQq0Mx]uU"+W}ٿ:qUBvH%tx wyhtŷ59ɌLFՄk{# [ER$Co"xki/r/c[n穩_0j[͆.Qx u닌{b˜}j5׵~'ˑx!a8CFMH*6͒RAFHvM"T "Hܑ/+1HS} Jq&SQxy;W,4Y('j0IJ#U\DHR 񢙬GQjKT;)OQ>{Rza)ޡDaAB Nd%h|R3-ԟ$O{K5̡A)w#z.L= jCw.Fk$z\0˭9Ҳf$bIдyEMv}R^Nm~ҥ9U @0jD8k& yygsZ_XL@IFxd~uěb:Z|#v~J|)uVI oEЯ0~BBҖ+yzfAh pT3l%09@F"c }x")Ϸ;}:1_nr 6ώ!rmt#[N94::vĮSJv]z)|~ fA$&vUCi &RGubNlݛ|Usm#%g[=3 I_4N V6Ls,RhCezceKkb& |Jee3#3@G=B^nB?҆Ia_ܭ@Bc ~1ܿxV)Ps4izDwc\|=ѰOvP{;pbiUMQbّ !sEVHuȖ/ᘡwܷ{ȷxYAnDs%R3ނjGhcV"xlS6H~Me5zLlgEFhr|۽5C.v 󸄔g~;ҽstTgOka! ҵ2M1+LYǔi{^_fnU5j/NjnK{x~ɰ7SXda o6i6qu.>ɞG5P&>[Թ\ؽVAڦ2Iw㇔CCUY9R :}Uy0WZZd۶~7怎Z?ʶL{;FiYNX<' P| )2Ru{ Wc<0c k*MsqQ@.޶مv[c{>zwv"H(}Czv(8N{MaQߎ] B&;(=Mb>ŒA/^3F;5HdzQImnBdE, cYpyLx.׭R\*]W@?l76 V&-sanvqҩ{s7[2) #hyy{=aQwxh `j3yQX9V[=2D`3 'tU[qNHok :b)ۙ| RDήg="^c1ժq&~>>$p^=(yn  IXC"0!u)8h7 il;Cԟ!>QgȜ^꣦' 0p49~j=;p)wD(\.ۃ[$=t?~qhb$Binw N_g9CJqG T]އ,NHk#k Ew6> Gfq0~Py6)3)H>{ǝhtBƢ *:S143؂~ڶq?ҹ鶫T۬cP? dcdrm0y+,f34yk5_CIÌM6u+,,uFCQ. +m0XՁW(:_ZVO;014%f0.`5NNE.lq6*-@r y.K fT&;AM6{bMFqr-m!R)HP1K%~eDL&))vtLiW[-^-FoYawL F:+HkC| 4k{͔1nskڰQ܌05i0Zn&/^Ї*`{X#OΊU!4ۆkpši)QM*CEN\keD6|WD2-zxVS\= دa)l̹_𼟣fmQ l3ˊ5I/f)Z`gtBp(KxX5RЮc? t^%gRÓ :p!G'GQ(Iԃf[LlX4bZ-T<K6kDC<| 64[fϹO)o\M^;q Nf:2<` 龍M9%xDe >|ícv>IXzTyMz-Nb3N'PbF%X0g m݉}h!Ŧ?6֦/}m[)hO숣WMMvgEh8);,%uqcKĽQ) pd+DE[EL:EZHA<B2i4u%bh0f9?T}p!"YuH}ˏO2_CяuɟJ1KKٛ;B}EO\l{@~6Y\3K\QTgJ;P]DniTR3]IrWQi#Ow{QB6<:s۰yfن\ N6TO,gА}_c<8-HdWMX}MXH?;n)̬K]]:Bs}.t)1oBe%y{E `4Jſdӎ4PRW eWC+;̳֢~M'\UE|-t3~}pc~jLd-Si)C \!^!^dzte Nb3͘}U<Zng[yG,VCQĔfu2n e67CNP: PE@,iD}s maTjgnnQ<2dӮ W> rĖ;`kjz3h'|YLJmm,C˼5X닍>f$9./vx#VD?b(XC@BGKK!:>>208PP` bq̱Zj:`$(ֿmu}(81Pcpoy?̑~mPXG'D=xw=+ PII @TU$z349P,~8S8_n{ KOSߗ*w@rdbS~Gټ}>՘8MmoAmm"x0@^Vz6k>di_2 @i|Đ;B@߱@h~J_@I_t?W7W(cc{!rdiʯ=+`Ǎ7 |dUWCno=pi&S_oǴTKop ِh.:hUXk&'#ncuKXlzy &r{WO_V>_}f];^&E5@Հ=[8}966ȅ}@ܽ' *PjH\a>Sqr<|*A||֞׊^NMU<+Bndj?^!ȜuZ:_y,j7dfF݅p 3C<5˃S'kx=) y:zv[CuSWL-$g2)ZSaYfJe!PN1}Ϝ3f Sf:1=NiN|ܣxRBT2XIg9z?]#;7^)b8L"-y{|ΐT 8ml0%|ΏVRO-m˙:u[,1|;@x̛R_=`Q6g$5#YBzOvI=AݟM(~ ϓcf-wuCR1w4 ) %;Ys켶 =_ź-a*-u>EV_:鄻Z]wXId-xqG|Z #5pon b^`j8={9~ѪyXܑQ\1nЇ*`'q|O1*L 2S= =XS.([^Or7qZa_q|k4Js)-iFS,R{Ĩ},`Xa4E6DS6o;ZG)8q\6-H 6 FPhgTHtdJزyb2dk f|mRw+ iSVYKl-}tFzbv(Ur)ӆŠE?_LKLGͬd~ `EǛ ?ZAB`N͂R#g rAlPpe9I]m-1<"r-fp?/^ vza+D=3TxA12[])\૧2$M*|vRflvk}B-K_XUӺߨ.lP{{q>H3C]=7^&9ŢdyM {dښj$_\V߅^U}jhGѵ6;wLԞy``'Xg"<~3c6q RКz^+cM ([3o_Tʏm71;`^ )0ɍnn[9?>sfŰ_KQɏjo`i/M*Uh M}VdZN7A@m4wxmPvA3/֖XD֭* ?& \mW=psq0Qܕ}hx*jا%nG)Uv2"-&h Wc$*V_yoo/r%~[um7.c c!'՜pX pх~`‘ъB>4m@T<Dgjwߐ6E eO^:E]/C}bjSEǟP &yDG<9Ʉk3Yp,{|̱ _q%շJR|%'n[)hms6#=K{UJM+eسT@*KY7$u^tخp*HZ#ڊZ8;#G ?] v%oxJvB_ T*yƽ?SOo#b8`jw\ řj7|nC&_:bOZk[;F|!h} VN"[cGy0=O뭡 };, ׿5}Ƌ zޙRj=LUVi e7'ckUG7X&.-WNуPwt,5ͥЂM[ gXRpЏH2y`\{Kh [G  =o~F)"6CvRݦ%y -tvfwV5H %g2ժ+b|qj526@΋#6э <"8m7cU}`4WX!dqts1~>`ga{u/]vb'e0+Thɐ6s[UmꩰpLޡ\/ \201o]jSK{Pz(K[6hCf}j.9]22$]|D%pIc=z1y"YHK'*}\HcK̰,1`e3_uňH i> :QG;,)|L,~~F@Hr7uvg^x-;Emñ#=A\kl%TExtQ ):(qNضm۶mm''mvNluǸc?ъ準ܳ) R2qpmƅ5(dlӽTЧr˝|[5$kL44x V$e-_E7+Y;v(cCut*n.T KڤM!@ p+^6qHS]@9Ǔ8A(&v5دv,u󊵹n{ɑÕu͚{հy;b|J^% F%dsOĞ%իyJ*Ɍ7fw])ohTJqyCw teGi($t9L#dYҸR͞&Y aUh1atiTaFӷv+ECXUza2` 5{vN2 u2%%G{9^5nXmQXғxT}AIx׻͜%}c`ţ&4EB^k7k"dd56$'nщ&ZW+vON&@li6\4R.L/hYeI1ھVM(J)5a|dlG9%B`}uD?buW M;3lP0Z EďgFHor!q0cBK")R1Doyl:ߣ?~ BǓe9o򠤟ʠ9oANw[y6y~ /YgW;慝-"Xn6h8Ls!t FsļP^UqS1ڒ |u/\VnwjyZ>1w+냲,ݷC@ W^ѰXdXnSN?(Y}ƹsqbtwt=hk-u 7(qZfKK-M!5c4<¶V(s㴿PmEfIU{3,3r()akJʜ[/6QnK9@y&MH}b`o}Lxt޺%c(BX =\pl.SWIq݋d1Reb pn9} AHUr f~n'pNV.$T9cpL4nɚx8?FY^}v7x!;G?x9s6zr>'"潍9>7V.(Ӂ"*lw:t1:֤ec .țgt ?脿Q acb^wFrF1TfM#@5$m?q/kSPMs'] {Fke쏇=D%L'{2UK2{Wu>POFEƞ@aӂ"l zMެai J4>Uw lwK?eijHV({_imE2U)w\HȠKUtENijc_7CIBDpu/LJ4bM2nm2_*r׹00ѧ& ~q,vqt>f3Q}\Jx W*QsnSYƇ&YTn" D)A+i-6M|rKuPULY Uli=/fsg抖PcfiyZ)=\\F*4 m}~c&;psl&_ނ`;)tkT3f~C`}L^|\ wͺMXmwdA*@ #j݁79A%yqݵ7X@wndX-H VWB[/ lc43WGy/@ICSk yB|KΨ !#ƪL,Jx_̡dDNd[ -ylQƀX3!r?}%5.Wm\v";IS&tͳCiInʀItRO;19"e a ac[%T&,_KPj)«I)!X,ld4 u6QdȂog J.cXky)j! lșwV4@cZi4^9v_: 3[o/0@H?8Y)wOȕc'y}Ҁ4+̔C[t˜R!CS(1u0kW]s ufٝP3sZL(X鴺HZ,8Żwk~2XU/jg`h/|>m1F/nZ#M@j}(+-é=JM cuSYNvrk=vɕZˊ57vvLVLtD4x+x sг >2% `$no cAeuȉjAPD[K+i1]̑nwh0!dz\.kWʵE mAq;8 @G(ژ"!/hԍ$Oёm]ltKod-/YСhlV,@)j vU`a;"krh+~A`PvdOJQTC\V3Gm?̅h-j2 T\HKe*|îL7%R>Ovk Fl!/-W)W_ybl2b W&o1i\!Go©l-Y)\%ί7IrL%i*&P9?^'!$KIŅ&m]݇M~YnN?V"b򙋛2QJQ$B=@Ws v8>"R.>e BRKrbSk3Kpkc4H񽟂Yq2~ K#_UyjFr v7QWm+}]KYaj=SgB{MZn<x\Rw/(mW&tn5tS:a0+I!9.P-O+xtA)N,kĢie+hd@IѪrIP H5)3s>F&iz]"fF {3OdGb=#̕W7=J/0*v7&nN=!Jnm_R_s &zvQR@6SSJ&r<_%`}0s{q>y#l Q^ko ;Z |*GR4M*a,V޹~!UKcji rB²*^K47 A+ڪq@kHG"W܄鿔0Gck_ScOX;_Ll ^Z22wsNߚsL,j%zr$bx*# y j֋z]R4ɘ1KJF\Ku=N!5$'L&F/t:}\t~|JcHQFH V!!)0 䋙 'XPy~ CȢ/iGK0LF o1C}`#6t HؽEC/?B$A$Y|X@OmIs"\.<в~?gP<_P0R}443/h1z4{%X@)viDU-}q_,/_OlC58{цછZU}xfB# y99LxC^|tK~ @zA*k [B~dWJǸ]< r?GH_NXVH !s$W"b*mDy~R+<!#mL]<QrBߖ:Qw6zUi8c>dIeטnDXfH[t[cQ @XMMrk~<®mE:;Bo%iˉ MK}Jt/w#͓hbqD2[c$l~ǽ= \:-:ćŮAk@s䝝?Xb~J Xe~MjY `Xmj%%[+:luOmS-HuSE$S.eZp_7LDe\TofHs@N:aK1@a?rʬ9`W%Yex MTu|wz).#&HYSoCi @"9e>@MS}l3sR U`ZxDE| kHD Q=*:{eF4@A)zo?w p{MTGGѪ{sxNJ '۩XgT9ݞe*Jݔ:"2,IU6,"jZ9{ [&ɏzgg*mSxRݒ%kV9 qL'[OϪmv_46ó>^cu>>**G`7zt٠hk7fYwn+)m/9Ӟp9:2MaY$♏-nK@_:F^FR l8\{};Mi[PpJ^E+4O@0ƈ:-pIjjv(: n/i֡ƌeT޲AXXP &jϷ([GHU 9L,CpiS1Ɨwբks"u+1F9yMqmAqMRII7-]Jr[91Y`j9P .eվ 6{b>[TG/R". K*%1(e*e~Ibq?&uJ&GN5W) i  rx1_ 'yi'mwt*@pZis<vmg^9Ԣ. '/H]o+1L><5#W.4Mï]Pi{:Sel8vp0ڟzov@NJ~[Ws74F=SJ['fMkG䔪=qFJ _8'~T/~Qw~QKLs7oܨaacr$O%ۗQy$ I|fsV)HLé&idEbBD9'7;_޾?o=Y9u+BFXT.26y @TTA„,h~ (QNL *+)򂞠yyc_k H&C; )w#N=W4Y")@-<=zvQB MO"܈j(XBFpa(6& $i"=A$ܼC5!Do?O~zzfng_Mm>?0Txa"E)~+tH3V"9;- zT{8xB90vy/B1U+HxjvKD{!}2@[`'ORML ] QA8-`,7nU*{`[XRWc$6-BBG蝻.zaלyHƧ* ୸!khe6ɒc.%IT0:ㄺO^i^}E(c*(rJ֑<9,):$~G8"ܫ\:@t}uܿb6Pc*eukVbA6$~'K}#s=tżn[ߟh(sBB-ezHºJ{cy] x`P(HcgZ(uؖg~]wz62lNM7X?\9VÆ{='L> ,-ߢ8Bx<9Pm S@Z[,.%OVmIQ=8̈R= 9WSE>F4g1, lcX[}msCNex?,8m\k]cP]y_kCF#%tДhUV'~ /lee(;XZz: K0A^۬nU%!كb=PAiU"6 JI XEJ& {NfxͽΊLj?h7%de_#RRp5tH~{$8Gu퀼_R/<}Էg|O5 ݤj%^=,u{\;@!Q_7b9"u}jl|-fì~.;gMwzJMl)x-#idj+Vo~/_u0j9XX)#u멄qIש#N#{q8\XԷqa@DGsJUh;Kjs0q!y>Sj p!ǪYM<|Ooe"Ԣ$Ŕf3c^Pc. <n=Cl #,.8;LI*v KU~&Ԓ{@t8SpϸqWM5^ꆲ8q$uM E7}hGZm2^/5=7j0"pV݁_w]kkӮRFM{܂dJ+ֻ 'snk0a CwRjŽ,CptO׃y:X܍[ooΏ-=ByG﯅U˯lQpsES~ E]!M5Iz$ȍ^j X1Kcuuh(fE:ONdDu{fVy뚋2JoD)i B4Ҕܓ iY=y[/‡}&O͝#2I+Aoie; U6q ;*kKfNü -{[y4r?Q/'H>%b$gzP>]ے~;>gLonnPҿ@}L}^GF2~jcǥ]lPp^ >֩Ou CڔJ}.wAe\tk1;ވJBE"B)A|yO'#p +wo6H \dvnHoO ?-m=2kd>c06`.:*֫-MEJ si.@ Ks[ pxHH%(zgrw??VW:V:n3r,4 i~! (($rt<``o s. 'Oxpl(M/D@ 0|BhǦi'+m \ty0miʫQPX]v0MC1-pd/]~Cjhp֔)0 Fzs#.{uWX&_FltulY7vnc7VO,#0'@7Rn鬉@n~ao{8\ 0WM@ rz?n{*z|z ew+x8塼3VGWROJзi $ܞO{-3ǨuKNw:Uc՚71zX[mT)=^FpB7GӌK`bdNFQCl VAJtك0 XADe/U+]O|Ϙ 6AB{Ƈ|\LTMd78VjP\z6X6GOXbAb)tZ&~ު)" `,wctO^yrHΑz_OsmCZZ^JQip~ bRr/Ƌ&r0WGjFZ}%c6wuL6igz&gK+4WA>uDRڮaqRlQ` F[iO1=E=/SF)Ev7'gX/BN}k2A%aQ0n$1=tkU'I<%}GxȂc\ Y_^m}[zI~%|[qU J{NY +$^ZQ8Ru~X}Ѡ,@ۘZMA \"J n8:ccwzt<+hn6fpygBh=OiS*!rhQ r0qƈ}y8jv2n1U߷@ɓ)8N@+_WZᶤ-l}ku&ÝcFy.%)lNneZI̺ì`-eޥujYX? M?^mqa/ƲGJА0* ]OVmqawy#~w/U6̰ʌ'QL5+|~:L{UF3! xsAms) C㆏IփZ1h؁' En@iw*/߬hp-Rm_Jp "8y ?8 jY#js`h xK>Vz"Wa5+`/-T2mcUUɱziYi2k]P Pd|؁>v+:X奵6e9 oޓU*yr7뺮[5֐F>u4F!KoA `Jid{KeoTU SȗЩj:Qv*`}m<IhE5UaN y.k8)9[; 0O$ :H~ޥ_iBb202?7QKe[!'#NDU0Z>SyBx.o]Q>[WuBwn¨@̹޴An'R#)0(,ޓ1o*ájLQʒ}f39oY&![v8m$ HB)6JdI %zTc}9u3s>~z\w)"wM_GÍC.2T U h=y1e}:?f@M\Ŝ-=џmfPhym6Й;#Y)nE7,$&=)w֎.ɳqjϹ4pfm=".tu`m\xi~+sWsXsqt،-K%Hy|hJg Gr2|@Qm!=he<Zu= 2!LtJgiݯfbcnMCqxDVRr);ܢF)ƘJ9>hai&-zu3sb~>/^f{esR*/[;HDiogDno^@i9O7xZ险z*09 v,(T7+M>|'QMc 7H-:>+5>*ccJj8K~z"daeY£d}k,խQu3r/9e~_=^OȥkIr|m|)Zχy'm6߮$ڿ"SF[ǿﲪ}UƬc֯?S4Ve@'9=Љm&{\M/Qw s"JVZ2J髗Ir" ״ߨneoλuë-:o;Zw-hH|=wVۙ3ZqS.Rnb}98%=;3xl34|rRi2jwqCd Y9zm`(`]Eot[܃fi6;㕺mm'w9"_E32g70]k}s1c/'_9(+0AY|i̱ؐ[ONT}9ǛW]ZvaKN:W[= +@eZK&m%wF[4Di~L${jt]V#qttAm˜DR cvI}X' 00+c\HRə@;}?)#]Q|3p==ՂQSTW÷.zƔ_ ؓ۱g̖|;H9 = ?kdX:| H(>c{T q)f i˛&CXN^zH.-5qM>^r6iMsY>a08~I6b@=p} Ԅ)9[gOpGӎOgɃ;4CV7+B59T!muA~UJ`.Ƅ,36 \wc?GIHrxItRŋ'N,*K( q[^CuW3rH :k :|C&UЍS21mxnAhic.zM*^Q?F,VӲgtO=R4o٩z.ʋ!oΓx>7=]u#mγ %{tGJƋ>.+fT>;_7drXCv=/wþ魙2;y%5zHyR9. ->Z:t:pMZbn rd}w-1Qs*(bDgpKDjD/ށȽT2gz wCt;REJ_6jG;Zi>aǿ|"C ֔O2^~}Gޫ t>c3bqO\8gT(d_UN9>vuG Rդws{\y7]җQVYeuxdYoEg#|QoJD26$rLռ颛ĩMi6"BQтW,]G -~ ?5ϗo ZktWj@do'fUO~;[+z'_(rUn#wC7:KhO4s=rh( {6M 7>.͒j=k6p.cɕwOw]$_LqдF5}[NK Ad2km"'+ĢAʡmI7M3˔ETmڔ\ڳ2eXWτ [־ܖW:D%e$=TlT\ Hk|WhXyPy|wi.S;_+lTOoYGoi><':]q̞yۭBo|KCшеQ'|KYY0.:9.lL ,HDC k#"ΝAT,!U6%v2)ҭ5T(l"Erv8wŪL\zjw Owʼn᝚?Ɲ2?TDz|o9Ϗ)­_-w;3ALHt0{'/caV$O˫>fW`[m5x6X40O4hOX`:o|0-ʻ_kY1ؑvbkZYO[sNx ZνuJ~ғKEV|ou_ŶϗT~;q:BTOTfXwd8YThy"` Lfz.k;=¨=lt=5^y8?o9IސDm;.!)8Hs=wٮu&}J]*H[cy\<T7 ϟsdC&}/p OK,9/2aa{K0L8kx NqӣgWRٟp Z{2~'hNtrO"yo Yr-n v0nޓtt-G`H%] B屛oDpd2' GlSC2x)El"sH!|8qJa 2> !CXdE"IDFE")*tve$c1FTdiAm`: B!Ded /<9֒9G+%T_]٭ӎs ȋm.FxY!^ՠ( KUp.%֓ZP~1^9y X;"JSE'-dW0ˍ F"R8"<$$#%t?D DkOJRQηS`W@ 0 DP0Dad@c3$ d1tT2C ./,X)4u C1!I@Q5DɨxdaP1'/d!D0$%a3ɈG:HB/"ŰL @ ci\@!Hx Db1t bʀ L Ώ(1V8xޭ#"0%X S*CƂ!acuS@G(&:4:ᐂ `LHG~W [0tbSī  ym0 Ad@TaHbӑ *@#!LiFtD*?0:T ZLg$u $)H1* Ӥ@*Y Qi $trA $AB r?Rs"lE'#MTtB0<+[xI@cBl=GtN(T !.EIt:GttzęIq JY^\)&xĻwX/ $KΒ0$9 "q0 ( HJA {<;߹㭩=3#?)G)Ri@VVw+'V Ba5[7{VQ }߹͈7<]ᔀ#|@Z-WwE"+JnO 9?-A /K&{dXN?goO5L [EN-bm߭f}9q\zfIrAju+wB~5w=kNYGRx>?˖ :KE L `lEe}vj6YMf G^/" ݞ%~y/ #yIvz^QFS%!ƥvly!=ɯL4Uq|Fߊ/P+_mŽ( K>ک ;6@6:FUO 6`Xڋd-eYe2GcVkY&}`e@!lj24X~ä9‘|􏼟Cv} N }ՓV/\Eۭ,?H)SvfMbѮB2Lp%r>5>z|cZylg{/w) ;s1] D ĵ.꥖mLvcof>D79Gˬ vek^7,roğl#چ݋j&jKLFpQE3Qa#wHV1#OO pMV4H? 5kVĬcyL7FwHivy&ʊ4Atўʃ&s睋"Kb6\WQ֝{D9"RV*gN"srG".H܉" G ҅qt-Y ZA @1sS @B !D!pV(*Ypzm PB9c_C5GQJfK _FFP%frL0'Eθ܉N4*ɮ0V<ͣň4,G3V N_deZQD 0~\g "=ªEi9Ox)ݙ„=[!'߅d8Lzs 1gj(jyr7 ;+@lWv۽}mt'>80tܲ]KEHv]Q.la ›S վXos5>_`9A R{5Ϳ]\ԝՐ-Qo1yhrHTRF磰eFFvC߯!{- H}GI]6V?lmA(>w Cdbk[UsIYCS_XPa\4JW|fo#8unc׭3EehIL[髟ξ^ dfGg$ ꫫa`eV8u~PNR^y+=FVpGDyWɐhBZ@e|8RFݤyz(@QSѧP:i'\xH-Sf= _FS 4~!4NH7>i9O:ѡE Z=nOCպE9qKL5ڰEb $8Y$sZ]d )8!4Z:w`%d8mʑ>=կ5_ Ĺ&íCʌ>IRLwU_29vV.t4VFY1p1˫5Ćm- kԞ'[E+z"58;sDck;Oi1\Cohk;DM 8*BM1R!Poq1So ˚Q~JrZcb +}àW Szz%9W)zCH,k$KLA 1|2N\-zz9^̠bzMT [fAOo@ 3|'U}rD,4 O&+Z|(Pjf{P'z~[b8mVlMH[1d {3Rg,+ak mtcćpq{- k7\_[Bԑ XçBGMÅnn5OGp\q{# =VFkrPB k6]G_%wҢcxԱ)?UwsoѠJ} էjo9x/%Jݹi 7}]~͸|eRQ^YiH&+MmǚJ0b жkoJO1*ww=HpZA5'eb/8ciL8g oEDVg E.?.= DxfG[LCn*ؒyOw3-I#fȫ #E1K9L*wU0 {g]'@ y!n)y sKBd?$@>#XF܊VQrH9܉a'e1x@J O2^~Z___1Bq[&щ 90О \֑|alܡٝ7@dԄs53ELHU)/aڿYp;@P?,|W/` E3;\xg(hX`Z/zмD! W F\V)52'Lvו=ɚ&uں$lmB,3b +T {Υb'u8z2Pnju D3C1 ([ߘ F9Je窺#`"Kr D-EVG/K L-vrp?G s;"uZw@ډEU6]V{`M&M ǘrA݉ub 4:,'ζlV+ޔqWA(h'ۗ-0ͮ:>/k 5z4*;L*Y1"]Xd,h08G~r1{snɔ 4GhÔ͂zi{j"'P6, u!ʌrM, skym; =yK#^_]զiK)~9`1h Ƿ_wH+aSm̊tdThƥvD'KߩW~ [+oc{j/#[o'%`qݳHnZ:4V!e`]##ߌ2;? qbj=; x}Z]i3Dff!#BwN׍tޝ7[AŸN.2Fk-׎,=N^-W|f{E*7[t;m Y2ym)r-P%qWn+^]/oA o?;^: \/f8vRP#-W+ Ւc|q*H\Wª64mMHKTSۀY`&~Y c2YX>;v$zZ4%˵q½Vꊄu:!+ 7r+ަJvx|!Q"<:,RusV$ ZI$_!ԙ)@5HTn@ P WRT;Z*qP^|% D-2l2"1`AW.9T_ C!.nBQnWX "(( oʗJZV=dPTA2:ł/o;^*l{mZ,j+$^Fћ\Tob=suN+Q8ѧ"B`!D9T``:R:∥9$b^zyG|5׫<1{y~H%5v7k|Qc0qxp6 YnBQfʊ46ͺ#:G?x1ټ )E-ZWPzsVUH }gtQZBU=(Z! K# 9 n DRXea)j ͜"ژDr>dVѫ{1Og1>ymM7n2G׏ XP/Bhe೛P,u8̆MXS8c.&>影J= a0,=V* l?C!Tw?0(˥ v"RvfqrB/PYǧ[ 2x,pSzv{h省?WkMuz[.21#=&AͺK%pgu:G<)ܒJ+v^T1@}f:?*ǿEeU*F5WS$n..ɏb:p5h+j`[˾r{^⹭ ' Өvu ;H

.(H G 7(E/:C K[8: D`vpQC}DD50(teE`P#.bB¡-PoB᰿}П=+()z_}nEBK{t"p)F\+ |eKܥ^rX]btd8jע@ỢpŘ(HZtL*@蹅]V(#D@h("0jO+0wE/hPA]5$I. .zyE$/PzB!c+ ؽ?t1 R]{0et7 Pw*3)_9?S_fq5K 0xjWlUF x˄*>!˸/CsI[/@A/,@\E@/_**r+z5+r+wN}AWit%^.rs5jv~4Bzi_r.ReDU-B+K@\8Sqϸ9+Ŵ]Nߥ+?2JٻK%w5]`PED/eDVB.Н;j^j7E6E9` V0^(N)GB/Й-.WP9^b/ w|EUA {99܀ ED  _9]# \of?U.e!,Ámu_B40W?^ȫߒ@ϟ@HW HƖhStzB4PAhJ.lDaУS!}o (NMȫ&~7zI!"3X'ʵr3_l@Wwx`˴{YO6`tr1+R"PcSID1`X;(4uo  t8? ؙxڵ,:۷$G)y2Y][8ʦ16Ql~oKis_7AܰD c/2bw c+ l@D{ڴ3o1E6 b2[S{`mh; ]"cU|+J$kH#;1 ύUEA:K?>[+[Ĝ1>-LOquBP\6 deRd &֗f>6ygA`jkjM"X:o?mM_q~llC?N]i;yQ׿#X b\!ҵgBo5-Q#BSV:;9M/w1)y/G37sr>8n|ٳHVd&dvLuS9d SL "u}tOǷ[`|6)u*])Zs1_GeJJn! Zz8|Uu0Yϡ1UB3e) 68+)vY'1Wy',39N-i 7[U*J~1 o|zWx{Op'O?D hP|2hD}q#,$d(!K|~R" s^Z?>I1k$ZV@g"hyCyom u{VLY.[PF>Oo; ?9?~U2ZIȧmǶrݢtm+f dbD `k*?fs]e6:x:lh)1-WGp_Q1{+UtϚn8?ۡryI3:.ˇxnWQ#uW;ΙF&z18s㮊A+BgmTNrU~Lww_>ubeM\LMu Z֝c`R%)řk$͡'B Qj7{jϠm<܆5;w2o_|\*ί`mE(sՖU !}(X{xN% F1dQYF\,$@~6`䁠b<鶆{qxed-i867h5cb55aٻKn ֏7#+gĎXt<>0)]laO_9dacp`J2!1N0Rb" R"jȀx2woZO0I4 PZpT2ȌRvqY"_.zsK`Ҿ']{C7̘d{ g;a%jbp5`kF0`D"')/&D*IuyD;O6zpᄒ}p:O?ByMS\w[ȜtD)Ml&D%Ym曷DJ(?Gu;bj%xIE|M<073=8mgzNږ!r~bt Vc}2ŷ$$]0K,@8ali`O#T F0V7вV'g]2ߑϐ–~5L!_)zVXw{bCRcDFaa`cF'(OlyMdǼ\a:DW >w9T'<'s9d,w1OP82dxԪQq`qzq>@"52)z͈ hv͇k)YF L%'@пN<Z\"Dg*qSWU8Np$y<[{$/pLxfc2va{dnFOi1%WaqH݈ҪP{h#?"yJ#}q5Jo #waU??OtJ+bq>Qς_ԢGs-NV(>?Ksy%Odvn.<䇲9) #亂ז5_)bm32N$Re͹=(ApJAhQOäuüʔ~VVP؏9gcV%l_ y5qsAul'ysyGtn4_}Uu#.l+ Ozz(^[~80w ʣI,1ab":s6>׉!ZjP ck ꘱(k/7- WFFVCԓ?Ew0Oa?(N8TsxЯAZpY(!.ضy3)SZj v& oKkg׀q)i8Ӵ^!NmUs6)jS'ShY 9#W$S22DEYaQ͗.. 2'-ZoH-L29.(lΤ-rִA]7I08w 0/s21n&>7SVGTGNZϭcW((ol g30u?Wx毷*yPiff^oKC rgbi6!|Lq\SrYݼ&ѤevS IՇӓ #Y؛o'2mVt+8,6zL|gv13nlu_h8VpvTptE Зמ@ÌNC_TLL'S}c1b%@@;4cCb_˰[ȗxYCn$œ1,WtGw#6E5cy%=} #kCnmK( S̉I=yԾ8=)}n$m1@<):G!alO]KVVq=.Z&/>pnB?* l(5殧W!m 8Nw+S?dz~IlHCMZ>ru8onxw)0@jyB6ז%ZW18@ͦK+v2Wh,<ިe)Xx C?2Pڃ [NKN2>F$!j ewr' 2uR`, aű!$c$_yʨߓ5{1i-*QTʎXHػ ~&.7KvFlɾ "WN=R"d*$ݫZrF}SC"K|-7f9U^E]Y%\7٪EI׾}`ErjQH;G3ɻoYɥӤ 7K褚"]OJ1YtT|^v%KYl(vo.aqJ@֜gDk2չ+ILnKme6KzPDz=^zcjH&dHQ7,߀Ϩ4 A(r+y WMEtLq3 jDŐ@_EܙͱƢxMM1H/(PB^ϐ5al|͋%9Uy)]4 =ØAV*\}E9A^4k]:0}P'с J$ep1gu'W=Ȭ˶K`YVR`d/Sg X>*[B3R4ώ^ݶR(-MunA݈K-]'Tr@ԇ&" 1N]Np;>Kz)r6vwwSx'o0 bS o7IDqG>`g;H7N]\5HG".6k?6e90\{ ~Tk1Mŵ"T,AJ+&E042%ɳ"l򘱜cײ`Նp#}4vӲq5㰫_3p'd7බ>Md`cd(!ۖ3=2gH|rL|zƌ.}睹(>}-]uK)cU^HG7ڗ1Uř8m]hi{{POj^3+BH/sBBN٘?oDa?!jDzaUMSz[O}LݶoxkhIt浗_osx=s-[?7|kRӺlwm(kh⡖ ssZMu;N4;{=HV(e8&,vqA}8/BQ\}@9JQԠ'}? 0S8#n*c#2zE^2U,nTO+lC`-zRZ}iVl!,N\ަXz }M>Nn #^^٬6vׅĭ2bh*f;uThCzfcNq⽐ kʺr[L u~K>Уǻ1kܞ٫w,+&j[95V9;<@}~[AQ^A׽蕅=VcAU?aQynQyK/[VaYayaa%aU[:–V.n6¶vn].,hou`P_ V BU2&EmGx73q''NΞx: eNr/ ؙ=Νy|`Wհ{R=tLq,?r`CbP~6]^Vv RQܿk#leFmE #g '-mF Gfyz84Y-SZ"2cα(Ïsc XWhDk XqAA1 Agy vU$^8IvZ t}^| M }Aȝ^剉aߥ=L;m /'j5#^9@C03[}s:F6@3vܥbX=Eq Hbz*cm`ֺ!\+b]s)N[4s])/h1Ϻ]qۣK{ž:[DVwI5&Gntwe޵ mK /Eδx,b".xS<#|f:J|vJ)VKsmCW|F,eaPevlXPz"i 'hEƅbBq,rqCja8j)cBr`gAO,w&&j'lL qtD˝KDbIQ,L|Y86 4(i8HE>=^=qz}\jwgEWK':q7>@[KJ}?;6w(C󮵝$3[ gL |ۙ8/ސ?|SpQ:mulNwl;;m۶mcgg:{SkߌW7q"Yy>y,&xa_~1vFj !i!6nr.PYnXVr^D P]~F.60-s[ƻ(BƏ+@Y؏%maiR3G) TA3yp.]W_J$,b};`@U|cua5ݴA]+y9{78 BFTvzdP!!oReM;x15ɲ !ME^rKyjSHo:r"A @=gd|e#*FQo:I*~5ՅWYr3K#iKZW+j[vɒl2x\i4X ^7 (rf5PeK{XnȘ)5Eo!ҢS*TSuG l%9lRt GExy`*.J&#)"WheI` }eÈ?\8;GP;pj);6w9(tfˠ~qQf$7 =Zi˼8~I^TZlHCF%$P!Nj'2~EKߡl0~Cy 5Qtʷ$v]Unz;`T%6R :q^'Ìh[rû=S|{~ܰnЯ;LJ@F6˥\YNpبX73 HT_P.VAl\Hcl7pP7ACi$zPғTHFb{"yMiϼ۾z&oo^uʄvJjCMOPe//)k_%e{2J_e#@OU=]\s\$;u 8u'6܃_04oW9?k3+gGnLkǐ Puo7 +cD"q;#Tyý񚕹0(QMJɏ (}Ѓ!! 9 W\ 𕢬v ޳jc}$pRu i D !luF ~]$@$ɶ}s(T +ȕHD.џ?C1M[nH(,N1D:pm$7}tMIen͝1;r3qbD4xS,ڇYqk_d P3`,)7A\a}S|8Ьn\R^]?C~ :VmX׆>&N>ջYt!nv}A|Dq]B_nCtkv_i8$u0.J7M[VͥyOX}MN`@1:,ۄwpHhq7lhUs6^5qssJH^GЁOqn;}K)@ӛUdV!bxW 7x*!p C`M΃fRL/M"UEX8b0u{6X۬2̿c;ٮ͑7Q1eCⴕħo2V҈uS1qrۃ>-.cqN1;ǔ3~vw?g^.n2v⨤yuݠuj!ӝfe<:RiJzN{9a9DDīg]ONӘNC,KC߶e(L{:ֻ/;!D9d\ol&;jh(o`RGIZ0?xd iRKŘ0G˺-!= X*s=n(,. g/6ɰ5H~vI>%O#K 1*Μ]&&1 -3|<,Eaڍrk]= ĢK8܉(*cYij\]|s*#O` g}̯\M%!ifF|} )` r8~ TV)"89RcR啝jFeMooӌA &K1$6r+ԫe[nC@%ےlW GIRT G!V?e4 ` 8MڡI"&W!Q`{箃`O Qnl%KX[:]*3#c?<. Nc:*z+Vb 6mv3Q|'Wpulo|PKr;w+:wUy~6ܕHr}Mf_&糯~VᓌSۊ2>.}D q1|(g5MU >pmxG`Tۖg%K{6t,JfN%?2'1*ULE.Wq0cMxw=,ioyX|*L=SoءZEoHc1Nb/T\פZJ## fuh[縮O !h]Ɲ|[* &A5tjaߚ]e=N4ih Z0#cY7S1Ip|lZ2T,V3LJ`sL(%DfO5ߞʴIIhVA Hup\0~2XVPVDܲhMd3jɷ6 9?aׯhkwȤuJقҖЗt~o" ~_u/f.> q KG< ͪ |B ϻ-@j9@4tvK.EIu +K~jlJB;s! luK܌ ϘL%䓆&Z}zTpM e`B`Ơ>+r7O}!Pttrb*TUv԰`sEۍϙ@ĝr>"=YN,fcuJ7?ҕ"]trU*:1D){Lt*8yc4Ns p|)vxNCh%ScLj2@gP6^9óOv n.}>Q=Pdmxڽzl/Dh3EalG.ڊF)pGg!P+(!;\-R4.}c9"谔 |7su)x5@h5q R+,?U>eƾM߇ij$xy 'PɵI.Q|8'9OP(Q<1 w4]DU~CDŽvcg#7`o0/!by[XRng.>#_79:@O[VJ'7H%@;f%_"=`#%@@zX[w䓯 H,͜2>Oakn.Qqd, Ѻ[ NzO%KՎ ޼x5[޾[p\Bsmx<>z*7 NX6ta eɉ[zuqE]k2R U_W"$L<3:^~5sv.4I>be饹JhZ'3XN޻"h+x;|y.@Yc=V*ӄO㫻*JךӰ^c0C.=>Mc~#Ŝ mmл͕ f@w}Ε'Sl(o fF9Nt` zYɃ3FyGl+͙ Tͤ{TqbbڣqsQ Wt c3"_b|їs@ M.w2'-wvFu~ =ܹUH4[V\L-iHI).KPANZGY}hdYH${Sng`U4   J{Iwǟ.dJ;d/A74LfC/y~䑑ɨF@@UlID`7.7 pKYmk9\_~q>I)ٟ?D*cDtuFI4 .  u$ ')o݂ѻ"M 㷡Zb/..挙wPO :@p'NGyj#뾅NFDҳ\p%ɷO*&0~"ًm@Jö.q%ZiZ:hkx$VaK* kzl cIKĬ6];M󯬙zƔ]+/Ձ9XT%HyZW>Kˆ lFzMag<2ۇ'UxiQGG`jäZu S쮒q\">YӚwN$`;.s>|LfLw?]_@D nFIn@M zUZ@|:^Z kr 0T?n W{k9h1λ~?1 #Z9Vg[y8<9VܪS*ra [6iP6/%E=H)?7Fq*"5}r+x;_k]D%hծc`:SQTM>l=U?b&$2Dh&><T@'&_hqU!q;1s`ڜbZM0eUw"A䫓}8saU~"5'#=8xqu \~<Ԑk1=HygE[tzV{4pP(kc7;٦Dsd`wI+"|:ћfmcˑ?h ޤ܄0[`{RzjoMr@?B¯6oOS0`S ,v֑(j rs0S1u4 :op>qn 6c!_-fWy(a}T4|Hdn(x(d“ˤtOsT\.6ҥ4-]HV=ڕb$_qWՀ ?8AMs[՚UoHOoH0̥u?矤lZZdV#n)6C 9 m0paŕJGF[a-UO!t|i%[%?X&"sb~]/r-Yq14"?ژ(OX*wYOa;LmW盅RqZ0 ?FؗgZIvX~'}(2s} eQD"n֋_L[ 2REI{-orX<(@AiOb<3^3cN.әp~:u{!lKU\&i&]6}Zx ̜(DK]~MϋGΓa`'ėA`p68s.ժgc6%yפ}g Jt@O,\pm6L$=EUgGW Up\UOO:&?7vEI71 sU٣jtd S`GuWiP uY}RCk:Kf&y~PXe0MgNkY]wI}F? P!lnVi_D>~3RNlÙ]9O/:[jM^}fUZ1_gR@tIЂoS+gKF`Agǝkl9+gdz縉⊭ kUk% ,\%ヌ>O9%8(lvSl$hDt7"i^ɻKzE8[&p  wa] g暣 :ԣcЧ;n?jlt;PUV W[_ RBad \ lh[:L`eF - p'ńޫo\"lhMP8 ԕʡI4{E)Csyz98cp5);,@ k84O ;umrt .I7Nm0x;Is1m[zDŽQƛA Jz7{i]?r%nxjb:ye,hFsdF,{L3O#,*LxVl>LD3=W\R>Nkx5y^TTR+[*hAzBTS;>VY, 5z2OQqD6oo_nnKA$N h c6n9}嘏ptHGZ]56ީH~dUNb]l~qy31 |tYhfl0(Fr;'<3a+tDEHm$Däo)fubI'V3f;zV8O3MeocͅuLQ}ӉcJסu12_pҚC. sn#WOOTo %Brh(xţRm3$MX7JX'g֭fZbΡj=S1éW0&fØHWȴr&|~@*Yi=Δ"c/RuJl{{-!:+=@L%snA@)X>"yiӜJ 9N4H_rM'#$_:.[!pg`D)$=\lBҖɰ3y#[cB՛iN(EipW%)ѷq%tOS>a7n;TUg#:fW͍'b3l"o,!oΘqDC9tlH M)TȔ^dDmn<);w^DxwO6f&"`K{Nͻ^}"s{ZWESZ+]_`Ew>Wh8iN6Jr"jhg`Oe`ߢqv:!d~EaD#niP24BqV2g;8YU6:Yޙ>dR&(.9H abrgeo _Bnw^BNGIE3>{{IMgyut-m<{wd xuK(e*lG.58i꒟U6du8v5kN&S{l왗 Y@N9c!l"$K1IR>TKbqipI̢o׿!)z )0~ _ʐbs% _A0DOxl7ՙ(m]}}yU^2XgfP,@Ӻ4J)ל }o#jLFPTv,Zwc'Imne%,Д.G<$]B#>Jf>-Mhy$wk+c[Gt?ot /6 !RfVVB[ nh$iGzio%En:>n{`L]UR%laѪZg$X-"@|+>}y|bZ̛*+Q8=ʛbGU*!{Fcj6?yehN+"7FdG-W?EeK ItczAY>uiҵ| V 58 a$"d j=dғBB11;/[] ]1ULbpN hVy[=. k)P(A/g s HryM\06I}IcKฮgib%Š٤x&_iYd k'wYgy$g'D|e(W۠$ls1۬ P@-vC\Z UM)+ zeY"1g;&.m-Kq|> ]5_ fXA5lku#/9l%j.hj蹒_5wi[L9;KR.NQ"nܲd.FP eN ^Jə^+'hTyI; yyV泝A}*}<ž(34ڕ~Tl͡O^)@N!g:ώ?8E9ٚk)7~+ߏ\*mٯ!\XMpi4ckS{hMq2iZ;5i VJ ["xg7p=Ma٦`6[J>LՍ>?: /@ *j=©m|R)BSu(4jmYu2@M){uX2,{{CEI+/sv\m }j08myYC6#Bv3iث7p*7ݵu;wrg۬#]MPmHI㝎M'\zk̡oEU n\*JW++=.W+e˯@{ړ(nqKɣ;޵xXQH:fSX8TF4)j/_T*7RRBhuޓ~ޫZ(o1)lek5LK܉#5=)V|C F$ѰM[׼=҈q|85Hl[s6#?"?8njSJ!fRH՗>6u&^U iPm azffN9rߜrj2*b*cO$r8)TbKY5c{[[L--\@f 3K d6%dف,LA T $rtw115st9-=@6 ) r<@ /=1% R։9XXYXcbc?tܬ ϓ/cyФlv\>z9py(01&tfu,kBD_d=ea^~~8?vμ|0%%$ Vf AB# @;_ED -dbJħP  QZ,‡C+fY F#v![ &ZMƂ.E|o#Dã2o&X1vyUǥG+oB#fb h ΍":Q}9,ʛ;Eݾ%%FX$8?KOMI(Zgo7[5H=@GRiU)ph]qGx8QR@,O%d-ٛ$A9.䅆$ÐI25]3gT|+G uyFF} ʛ{%áE]^B&A `>CNQFzaGR a` }UIT<|QEc/}cxG~n[k yyE˂ţəYJ+o;y oٓ!h ϮX Կ$WoF|k3aܟf)8@bLF7-`ø 2txe+VZ>ݎc[=&Z<^36;".T*cO/(_Dm Ɵ=p` T)R~ U;Z`V wl}:eO\)[%/Sc.Q6w+nAJ5Qq.Qדzѧ,[,Olt3~x АLc!5b?CSz54aNÒS~J[u?1yy(M߹pBHMW0 qvz\25+¸Լ2(ԛҮUC+ex@ RݽԨ~n<#pA%RME~1>+́x;*7H~x&޹|gM1Oi~̭Ah~IkO8jğYDS'S@=,ϻ˙61H{Me+p<v[ӟ_ݺR.4k鑰JOICQEZt3vm{N׭uß;o]+3ݺ9F= :'HU 㟬ql[JpE^D}/Rd ̴mJNG^d6Fkk̙x])oiMKs n ٬In},H5ͿA1TH&S<2骧{[*8V;5%PQbV}q0ᦛvttι]G>= #Kou&95 ^gkuLEwiS%VN6ܛ֤k(uy/|Zo+LB׹W Ydx՚I^u(%6$4=r2.Dkm)Y}: }a]Yg܊)ʨ8`Լɇ<6Af5m1lnzQel*kYAXZ49h9 @T`'F܏xF{Gh7I2]lyDwZhI_;E>ܤL~oAvh,g}@lj@9 Ȍmj7SQ-bTԀ!^9j]RŵP@>2.1=lϨmp*L9،zO/UFjHX+b'*]4Vz蝣]>*Uhz%Sfl27vvmȋ%.b"L3y~BE 1.ľ]1ް35 9b%ϾFޟaFN]h$Ɩ'p/?G1bht|p 29 rtM?&fL䘋8YkQm.)$3'}SޱAԎh~uQ뽎qzhF|*:OnSx;tw䕩U$~T/)pI fdƶm۶flIfl۶m۶m{{dzOkwSuJH c+: ?) p:CT)SH#-:e3GqW=omxwUZnh-%;?a|ԅAv~IwZ&1'6'qj܍Iʞ<4S1UyV19=DՃص+ٙ-?7'إ:3N%4jɏ4O st iޣ,pY}[OȌadJ`#>xU*f/"ȅ-߹ify1*>U0,/tO9|BF!8:W9aڲ#osk!![jÇ}o* |І (6o榊.T0Twv/jBtcl`^Nxwh㏿tUo$0yBa!oĻο]efQ-(_oY BwUvE88!0 GzJKZ9& _({O?7 LʑR &1ŞYr¤#*|aYN~_POy}S*,B{4GG *ל.)6 w$š +5d],>h#mUvӦޱcIjii\.Ϡ^g2\ɴ uW}7]ނƒX2F2m .YϬNJTnAqN/&)%. _۝R~K5'"EN"gy/ZZTnvb?o 6RL,b?VJ̓#jY#+vb2lptcֈAX~Hh<Ch-~4>FZCIkw#gAg '&6) & 3* /0"'CHj*0-/R4@@E+D Q[77̯z!97J!WQtu 7>+(C"8bи_k wQo:bPa|G?1ހ`%;Ao?OvNa8CbȾF ~FĈ $|OF F a< Hc@a 6G p[rLŖ3f`#}?P(6.H/^}H gMǣ$@~(靈qD $r%{ 8q%AfwpT10?OcEr {~ !x`fQv~JQO+}o{Owt>PP=% "}xqq+^=UlI ")()@}s#|A ~ O+ yhש^p  Ċ|C[ž'x'Zƚ<(y+ =qvkx9폜<}hM[q2=$%{d[;zf( Fzӗ3KIZD80" RA;,xd_u*R7{nPvޏ=WI{4& t),chՇ/?`UHd5udDUx9ܷ<$ʹЪ/!i1¡5@ʴnӁcdB,| Je'er۶TZ\n 3'9J}H ;HiD[T F`7'/4"A2ޓȆx_*fG`"+aR̭Ce'7 2vIPKe{"VT^!q\C>"'H>ylIV{ڏd ?塞;6lDC2: ^alr=qroN `lB}l $44 Mjflxy3v@b=٧6CS+(NgˇITpP '5R1|a<^l\ִz8~gO[,_mlY6/pP< ;ޖ])3Mlo?LLvs[+/{o-tRۘ@}^^U3$oԊLUY\Ԣڟǫ@".1kVs,@tЊ0_yYU.h c)k}uw d_>.(ktb2_y ԋp+xl̻Eda?b$&Fz(M+Y 0uݏ\Do+[(uy0wšҪe¦"PwȕwPm8S rt6 X*mgS71CiָP$Kھz^fL\s-6DV_-?\-;T5VhPld#j1+)f3+(6X&2 ;ڬcB:##i< \=R85|$KtQ=9n e'ldC$Sbxf0UW2Y&=y"#3.R#C=7qkĭmyljt7F7lrn>jYPwa/]<cEs.)ȰөVyb*mXn8#QNHb, ɏDQ|#}cuKLҋqm?-č}SS43yԒZ)V28By^\ǒW߶Mҵ7AB5t=(_/'?xpy9/44 V`&'{VQEIfƱT,hxgنӫ_hS8ULvϽF:[OiSt)p̾-E‹;/ 6&Q*@y5b=iZ(lj&\Ox]l:9h7Ed!KHmI mz(Rk<9VC9VZ#KD8Rͼh‡4/l2nPg;' '3(Ѹv[5L5\ֽ!muTO.̤)Gja%۪,@Vc ~"`e<̂,h9#T_B=AA@8I}2PeCg7a;*so_Pt BS]j0TJa(qS F/~3ϣ#b.lLCkF 4Ri3ҪnЬ H~k+>*a<Vd#!vMR~oh^ʁ0抡YY&jAg瓸x/8lvaĕ$`1nw&AUvt[i݆©+>j;I껡> YD\\%~a-:QHV_UӦ@'K$gHy`Oĉzˣ_Rbh~등g6/9Y$v~c"CQ:o~%a;ׄyxk0׬RdGC쬫5mk )ivY h2:E 7q5-8g\S4t1鯂{gu  TŒ#XOmN|5r V5m96DܻXRt|0y3ZyE0-IY}f컵|߷Ǿ4^U,Q?>=*@;S҆vL 9M5"UKq\N5M:mjY8rOwug8v\H<^s$o^wlҎ)#{n`NxYC V%}Hh\/_9uJu+ĪX}BⓙzRQw(ydLL> ߒ#0#E#~0GRXWC'?-Ik,P>z^P)t!iJtF2\|LO )I?'8o{۴Y|*0sJJσtr@~a熞Ѱ^3S I/Ρ7U;Z 4I4l,$xcϵ0kW[RvΚ&<z%|ά%er!HFk)M;uYVMX;mZ'5V Ow J-"W\9>"|p=|kMTu n0U?ME`&f,&VٛL8dGlH2y'ǛT"> uyiq*GW&' MX+l!uB-![D?{"B::G?ȼKYzx_bA&'쌿tj3Խ֭aX)#O 4j>7_Wtwt/yI/fGvǬm:E;RF5^ur)^L.?c)ͅrdR)xxL8%mRv J 2_B{}>a\ɔ^bk9MVItRudjZKy4k|àChfi@CvE|&gxΟ"#?@iYwPEƃ;_ 4̋!3`-6:nP m'OCGQG'I)dzhyc4oe%%>nfG° TƸh t=?t+o}W({[NpZ5ÞiF\ WfRwp9m_#qXk.I-߰#Ÿϋvq# 7mwFu;HڼHi_X~+!ZLƱvbdQ|C#-^ ^I@ 펥 EL4 $ms`]sjPEMsh;ְ␙$}2f]"MqrtQꨚE4#[?!?hW؈7}fN=r1'Mʥ|9w'MPH RlZ'jO$B\,BШܲlfei1b@( X)p|tp*edJH̨;m?a1[.=N h'R:F@G)azSb52ҝq8z7rgcH {Hu3c~߸mDKmuͻD`ffۚOӼo#aBiJޥV1xqII2lwL/HӈNIQ<` .' /{Vc"w5zgLQeBAь5iy vlguJ-R{ލ?KhVM[1;s瓑oth@>ɠoAFܳvbh\!K{U̓ kBIޤN grgB9x-<{xc~I~x2BtCڅ9YPoeR-hdv %yMI,5cK{Mmt f"-o')![Uyg5Kc$'&+>A `hPwWUV'jd&@ Փ%dW?݋u2q5R8,#D\ذZ)iT*%/tRJdՕҎH bKn$Zze!Rzc.Bg8<1o/ ߉*Ev.cu?+*P5Ar2[nPu5<#_9E{}1p=d_7>q/O*o-xV,Q<p',~`&;..';t;0wV_@1@2Ԡh!~[1Ml00IGY>v@Ʈ4Po_KΆ]Ati6XBY*1 "1L(S0 pj_^^L"rmHg@J{TbKG֥c=&ds=F@"徟RƸD=% s/Ϛߤ "yI D?pJLW#{Lnn ^ơKd>^싥=[,jJ)A%,ҡv>?r,z"]ͬI30~4݉zw^ۥa#-̤ؔ m]wKnsLQЈ2< jNWHRCU#^,Ήө͚j(XViDZҽ.]]vXCYt?E~p}vQN7!_zVo141V0'$P5nNE.\6r;6NҼå+*Y架aH _@b.i,Mڱذ9K4VV9NdSE |*D; %MgL6P$5\>3DK pҽRMWT T 5C2C2& \ fgOLLi'w{-^-f_9wێLM&Az+H|~#Itk{­qCҟ kBڰqܬ": `/~07?xJfKz"_틗aJnRt3g#7~&dST~-G;`;I6y=FA=°NK&Ssqdqh+{KĊ/>/QЇ*`\HΊ[S!2߁ktťm-UK*CCN\o𱷵D1; .Ӫ:r<`L-yexDK~ú~)XT5mF-nb N7%'PbV5X(g mÉcx1Ŧ} 6֦?c}[)罷x_O]]nwEx$);,%mis[ԽI9yMl =y2]Br"v(GW݋B2i4u5bx(f %?T}h1"Y;MH}˯/2ԥ.:/?1T"/[Sb3EkKC8G@v9\3KQ<14*;ZPNYݔnid4rݖI|jTQis O+Xc7Q"6:S9G؎,#f. DՍorM{˹}t$%oTL:Oŧ.B"\1x`4f֭|j!vt1Rm7FtDg<佪ZRvX_ed:;*;࡝Yk.L.~¢_}k>8v)R-H* Lʩ1~OnOsX,)}<]AD\+Q_p ⸕Na,ξf?˃͐`k 1e8`km"uI.Hx8Րi5p2#|zi[#~eg-";vxFvnC^S#> ܻM-!2G>t0Nhŋ,pD0E5!+]+#s=wwc+:d?pWuDplI_Ҫ\`TEr;Qy}DotV&xVMI @Ҧ!/"W<4wMJ*/w)'6(}(" fQ#XR>v?3d<ۧ-h'5(|!*b?,\oLBzmͨ J&m< rF?"{o}nX܍"(ß[>q EMAȟ=_s1e8԰Ĕf0ExnC6do NŠpdToß<\D0$lR qҁo.0Bc)(IQ3\`^xxd5p~͸.$x^/ $t^ȓX}̢ߜ~gY2;(w6-L `o,55~Jp} ^9h7X=?AQTn|&`۟ҕ86btcH jNX㷋 o L㚠׻FkG՞&>_+3] ǸDgPz2(-RO [sU\>\ͺ9@x]=j&dd<3.8%UfS??^&E|5k<@|Հ};O8}yvv@* pjh?|15Q0?sqr"|ު6aBB־.~nmU<B^d~/! /MZ:1?(DnFٮvV݅h;S<5˃K'kd#) y:znGSmKX\Rd3 9hP,|c2!w9VGp) b}E..ˇxvJ Wtb#P+EJw9|Ǝ4Qf<-^>GVe "ƒ8^=L=?& \' -g9!yhJ5oK}у D+{؇ĞOdR 5'\JjA 4{Y]Wt{TDXZg'5d]Vďjh&6IZ̻G~ucEz,ڸZu_#CS"W0}#Fp]-6X r w `3/l W_22Fjp M/^ I&)t~ kXsSuybo}"R2UgUi"}$H>{"0O\ 0t^x ⮀]~jlPQnj$ f벨L~Qs314bE|_pTYܕju+HKҦcWF\f' y.aƸ"vm05om0#"kRQ~ڌ Evwp鋋/pmR ģ2s6HfW@H=ZܓS\3On0)`l$q~OױL 1S?q =Z P-*+XLqp[I`p}k4Ks)1,iFGS,Si},aaD7ŐS;n&:t-9sY9_/a隗mC~VL (P8φKiJ4{@\@ `ӎYͪz/2 (DGou)Y(2I&Y'$6a[&ndzGm1 05kmIy3|TwUhՒz+?$!?߯,IEJ´e1r3LS{DR3'Ӱ(%r@1gr"JQ#fAIMkH7ʛ@槜~)hBv}uу9Tu;@[HLȾ8Bg kT5]z )̎;=vRwΕT kG*+M<Ȓ!q܀(yZe۞7l7"U;qşE0fs=bS>>%H=1KoOgV5Q,= ,˩=gj5IvZq'k=x11,72N}M h`uH/Z XmUM=o̱ COUYH.+Ʒ̛YsGS'M \~_vM^s8oh'i0tL*Ui M|WZO47C@o6wzmRvE3E ޞX̰ޣ&?. \P=ps0Sޗ}jz)iڧ,%*D a 3doͨ]/<3zM^KE!C O\>Bȉ~{32\?zu?Xptb{-bիqqOx17v _x^zwϲ9Ok!`x AsZ]d-mF5nQ#SxN~EQ+P_Xjy>yQg(}jaB%%k&fO׃~O0:ųR8DwQASoLHu~խɝL4P Bzڣ> R| V#bFe<ꭡ _N|;- 7~|& {?Sj=MUq Y䶦bjUYF?7YN-ך0;FXkK+α]᠟d󶾖VIetċ;m# G+wu俣!;i>8s8c Q<{iiWߗE1lKT9 \pٴJD1L\6*[j>A0uMklr8v8^a=W]8xru1,*0벤-kb>{W&$$>f'$95W6{p9 Z5>8~;cbA&2/mOJ+o|.Eٞ"y!x? gbӎoǮvx țbXnN<ͥuڏS1f)cpոaVElKO~`\! Lx&m@]$]6 +Ր|5ɦ1(|R]VXC!+V', y%D?qՍJx7h`Fo}^K} hv4bK梱Hsfb}qAWE(KTٿrY*lNǀ߭ʲDrt`!K\{M2+GbbM;T~l6SgevMƉN`}oծ4w!F_O$k*--Uhl+,W7""@HS k=[âB%͛i'U}ϰȡtl4껆m%+)snI~G9 EPI/Oeƙ6="׉Z1u{\g*sգk39b)s96Nf_;[qt/NH =ߩ.p^ %Ӏ5Mh D'v]wXaģhJ!E-rfo˕3e"滝r;IPE!d 'k`` j~dWc+{LL ûPUY? ^zr\oTnHY#p\6ZLL~4*Ű{PQ-wk"ovΪҁKF)]}ż{FrF>TfE#@5$m?q/kSPMs\ikD}ZԲZpnD&HmA5I$Ǟ0dzUݮ&oQP0H9 ^S0pӰu4c`)RQŪL6Qvw;כ%2L4xM$+t=oxҷEz *̔av .ZD*"4!JN!̳?`"Eߪ&9 X p/9T\OKSfYp;8*oohQ}\J8@*Q3< AؤH,c^XL@]9R1Яh\[.Hx%$%ԍ7zvA'g@ כ=EtkzQ8Cن%0SʞkR)]2`05rin~> C V՜ޖtO),~-Bۙ_o4Tu4۷'!3ɨԨb_H"4~o%>{nSYƇ&Yn" )AKi-6M|r uPULY 6B98kF3܏S.F8i &(E +swHZu QNjJ76UzrWo<7I껳(qB,vꯎ+x:aiW~C'Qw /(5|b4Mf-w]}_*(SPGX[˟[Uw2)??0'Ry)}&6_jDfvG&zX6VE}l=:vI)NLn+]Ư6׍eFpjDCTx|mT!?$.4P \Mo 0b!q9~" c& fk;Wh23XB P~L^yo) 7ʾ%o\yme!DzW'awP28OQ1zqa$56a%ݨɌHۿm[w͗Fv0bh4,b#d)X]D' >nYДD^19<퓿?zm$J\Bc M.4gG y/:&Vo23(a}29{ :6Z5G7†I2Jjۀ?ƹlEw1r͐MgR]wcrD>@ƇØ69JZ)LX>@Eח^?N/!SW*p+S\YC,Y :z׋mlIByx\n-1t~#' _S0v?ECؐ3vhc15U[hrttgn*oqX_:Y<~PRl NUgiV SF;wmщ c.' OUƔd]]7)yf7Z@ULibcj#}'#Coj)Lw B =epKՆdTN4|bV1\^*.G4bӁRGQFWܿ[S{Κv]&ꦲyzv+?"ؽ7OYхQ-WNIBr'Ȕ4ь] 'm}έ:t=3G!„4md걹RU3+-L&`g{VL(c0 Ծ zSWʒ/b_aue-U迹fK8dCbY15]2U݇LO%Gc:}i2xCLc{ A>:CN}gkq>Ja<,݄v~Jc* L8WOUY6쵀j:m&Y"Ht6/.4i>lݷrMp̔VRg.n@)E >y_q˱*KOd]}V{((;%3`#J- Ťf~R9?LiEz?r,R FD9n&&Zׅ3VLAMS>#{ zGƙ+;.64o5z^`0|6UloM] {!”\%Չ%ھ\~vL4좶xmɹ*;L .yοyB{$qFGP$ה$a`3#oD5it W|5IܹbL%8}l%We["\1F6wl.xW&i2G-_U!sCu Kc߰4YI9!YjaY.ͷ4hzegS56hz x,̌>0!H/L/ϙ Iz)zizM8 -6&eP1Y,)h%K;zd/ XǺ|k (sL,"<8lG<i5BE=DS(1`,*~.L:ԐD:@Jb2jn;sYsU3"Va G.*XA,B.O$/f(;6bN%p~Z c" "@%43  "1b8'҇,UWGlhO\{wڇ^wX -HL/ #@ȓfEcc g= RT'c$)ƒAlC w{WlC˾2rBq|Ƀ^ȃB$JZ`E†# |Qp`5+2n%_"ئ =#TŮkbh`RyobHJ|y#< xLpEnjW $4paL2 y-%ćXaUI`&HPoI m\(c v(@kBd!Y g| v8aadZ pr+ s/z̑\G}HA0X2u}:-&HL+._QnEa ?n3R"+YL>nlNlSZ ߋ4g= ^x*/Vײfi0 v8L pY*K\fɞhPd}+h=S LvnG-˻ }[trzLKĺUA̟A$ *t#zƊ5@ڢKM͏ZZ~j|(okKƩvm;/jߘA/g x;HYNtti7 k{Yi/t##*`6M#qe;nngP,ԩQ$, ZNЌ+ P6ָPJt2lR+HJ`Tk?rS+Uc.5<ǪAWõ` [Xa^5%n#_=lQuW"E6InZX9HE+;-w&l @8d^{=_ / {as7pJqLL,(' u >̫hPUBTsU"F:6l=nQ8Z&^ <8Ho* *f-ӴfhfZ|vrms`}4''&N q{/f9r݅?􃋇Cӑ<}7,`f7? lO /RZhxReDt(+-H9>X_2Jk\/\VthgPMWf("/knM ^a#Mq9_1Y@ڜzJc`8M95-iG[Z#RaKȘL"S0'.B勧dXm-':8u}NfM{1okK,@tZ bEⷫ%ȃ^~lSiބ(4z`WV;# 9_K=> ov<˽hz9TYW\2]$ɚ.YVb\ư]y&׫n`tg3B~S]XRS{K 5SS5m&=L; َp 廼;e7G0_Wfܴ 9,!_x~+A某x)&dQEbBD 9'7;_^>?o=YN9u)+BFXT26y @TT„i~ (QNL **)yyb^k H&; (vN݁W4Y")@= +3ORML ] QA8-`"w4Uo򞲙;hKti [&芲?ڑ0!X"i]b rǍ`֮B8 exI8Pz宋^,l5jdJd,(?HBx)nȚ)' uIIg6*8WU_ʘ ſu$#lA~k{?umrb*^_X鯤ԘJ{Z^XpP I$R\N"Cu;h1g[;JpFPyK9ӮRF^i?!T. Y-A! =d W;RH:FN a2w1N6RyaYobOq 'ԧ2#=̯nOFf-6I>'5j0OXh GՔ[wa#b7MaH0E;*W:)J7Q?lBQϼY s#V'k`춄SfsN@,mLXkmȨaxoZ \Ŕ|{4XBZTdv_'afW(kDX;pʞ3(q*_TDІXvU3_I$Aqɗ6U=c8jݎ؉C>Z[.߮ ch%+/ f"$P@My}@ ^IM> ki!{Ri|ռ<^jFl!0[ZC}E. $ ,nU0+ TcyeZEܔm)F`/q5>33N :;iWmc9c 4+@m]itx:B+)TmQ'qș;&l8<.gT $pK:+Qzqtw]+<&ND АV˱p8S,!RT]vi#v+Uב޽6se$i#ˋKnKthc].-1tt:3z YnӽI7k,(; )U5Shf)Q,k8? : r^_H4[=`}YJuړ2Om'߭?rKDF>lͼo8;,r|ۓkn{k/Όۙ؁&Tƅ]Fv@1T_仝9Ay["mM O4M+Zۺ|˻" Gǫ!Fp^ ^1|^.ynv{MԬiSoVOYN1#X6/B?|_ZT_®.HBzӢT$=u{;ӊ}>ߧzOiZ?0US[(OQ5#Zf^3"۱ŏx%X˄v Y}dr BݾHR0NQ=d;  (3GY9_`nbMCnR]AP .W!(.j1fzӶqG<5T>MAP3axGqٝɜgqRӢ4}3 ~Ĕ}螸ZXM`L5@_{Q:*p%~ ENP|E `#Y¨>O^?0N6ۦݫɈf^R:fbwPw#O@DsO"5Irl@ƽO9!;M ϛlK7r,+ ᅻv'1~ RrDa͇ɸ~Bv/^c2T4 ͫyhhL^с:?f ꔑٺT| |8 $EIY f.Uk[0 RJ9*Vmuٍ%Vt 5_9]?0`sn) cUh&+m>'7鿲|y#N'b`=WV -F bn{ Lv;A5JYҠ'é`H-֙U0,Yw>j6"Ҷ`_Q>_X*x$NR wN(V`967o>䋫% S^E1#d&AZ3v7Un8DKȟ[]T"^έR4-qqR)ٯ;S(n2 RM7zČƛ_ 6[L@J%@kr!P ;LDKb˛MouߤřٳLO|J=+L]/*EywIw_Dl*y +#DmpSZ:Z";\l3Q B&qnUlV7cy:n~F )Y&w* h*pSu>ܙ+TZY/@c#p#(CX*z@WvIJO?jbU}FZ\/Vpx^XgNמ!6 4g S&D[J|U(y*CjI N= :{)8Ag\櫦uOuCYs@V:զ޴#-Ya6N϶/F F4=\1}tت;1kkzmUTiO[lSLb02_㻛LuJJ\3sd뵼H:>`q,ːɚS}EO\hp ҐnVh2]'8c]AYF2Sz%e2D~;k0ƫg q=Y`ݍΘ$wclFLA<.a& r0bhN@?,Tp{EG']7|!_KS9r N]BKAY>2ykkQx }(P M㔧qA{<&U 侢ġ[8Z=ċ^>pBx I  A*ormܹ5Xxe9k_HW1 "\'`m+.(M}p2&Zw0aˊ Zz\+E 3)5v1cu-lj@kvʭ|l_qwl֦cs ?L(K]saڈ״5 hjmufKie+_I}71hZIPd\nx % psk]W=f _ G/=xZz.a(P+~DbUhܕTJ=)¡ KodhXeR+uFBSՠ~ dԐיsnz .~U~ ul7MY<ڰ_-n^~eFP/4ְ+ g0,Br@'iůq ֐fGAn:VlE4Zs9Vv lV#^T=NjQ'+o Ј+\4z#RNId)l=|THFq%+ǀ88?>48jhNZ J| Ͻ4 aߜomQY[sUTHEn"̛]Xq x9QT`z.#9 D9k,d~+' fwKw*'fr:6BSK;.b*oH8MxHN}ROGcuTVʨkuCD,[Kݕ`4WQF T*R \D ;{}:y`.KP]HF^ AR"wCzC lynFoAoMG詾0,4F(FFsAccaaW 좣bT$!ɬ08'6 4Ȱ4E 4 {TpKi-G|Ckyc;=IJ&8o ŠBb0 6B[B!8*X ~$nؾA8 __N &rti~!O A *l &pa؆PNEWZ6ehhw1 GĬ7v+QS^D @B d1g~WuS(J/ՙփۿUMynn@!]*>+{ķPneT@n9ߝe.xð4g/&{ׇܕHx&N=yprrp :|e_ŻnZ.82cgwFa&Hz=Y@rxzxE~@?&)tt ⭽1]5O<2ҙ%)f]GX6T ,r͹7wԏ}BYK2W`eQl,,6+bI[Sz,4lU`"͍cj~g6l]a| l*)&cskCɵ|jf9A=vrt 'MTrC%{ws?AbH'jPoxwSћ4OEĘc0.[])w坙:Ze̕>)B-hr;K>yG9.~:FȞW+4<@aelٷQ{A\ J`;,wVJ,qɒJ:RTD*1z/X$~s':m.Y*5S]: GE6'KY=>=Q4)V$8J[7)PLA@M3'*htl]!JoQV.X8)e~e4`9!LZ Fqt^.![|j=}*T[(pR9q3C' X[e3XAqA?`Md =,0mQ!h]:bYhy>/#oKv4\߹CFʐ閴l~e#tP\E" ҅ן3LȊIJ=ۦS07Of(M\/Oi6̎i3G謇Q j\mB{({(IiۆqơKM\GS-L=d</OmЧ4yܜ\e7fԡOmYW3JgKb:"~R(T3Z=$l\?Yd ]"DjoTChkݰC{%'Cjm@%VC5s:VSK2Y&h.J oy co#ڼu ~ FN+ Ϣ#iP#B*q 3(IjϠ9\Yv*cC9kdmX&3GAH&3A .WriUz|nRK~MD+ۈbT nwʦSt_'r&ǒB.(gHn ?gV؟tyEr0g]PEs$MY7;#R@{yṱN5ԟfV KEG`h=3 [ bmɸŻ'$W}ޚU'O8erVt%_i-U|7יw+p$F:i$1>dysea}Yg/4}t=xo{l5=JOoP.QΆzl ks{I-=aUf<b!NX9w֯6йgګ0mAӜ jӝK87|L,!UG,<蝘/r€w8|M#Aˊg @Ŋ1Jөڢ4];Ox ;I䶩2{(3+nĥTKp^Vw.op^U'j}+Zؕcf:)8yf=k/Hn1j#MV=Qh߲bf[dמ1/jJ-LKB`ֽ\UcOSiܠBi3tZU*;H ؇M;rO$I^ʌ4V"{8Fs](/) qo0?SԴV䳍pYub,T3t]1pY~Z~hVp{SڿOO'G[-[#;,_NUSk 0MB{ ) ;uZIuYͼaLp>yPe|3<0 R{5y PήMw& x\-q<q"jtxϋ4]pBu|#OV&휹LHa$ jmyw2zɉ#И*!Ǐٍqzsa|R`ߺ[\ݵ4Mw{F5 *><Ͽp;88bQiD(0\\wӜ) @zwWVTp5[d31i$hTGw-뤕K9\e(XbўSTC84W3΃B [I= Sa]f}[}kU6뤽u{>3lt΄x{D!^pArĖΨN )+]!,i1\6m[9cn>as?͖}m"hEî|NKgaIcsڥ9 vPnU!g:V̦:BHHKN9&e:)2DQHREɡ!9R}Lv3s?y;;ꖿMų^Rhsh`u*V0`QjXbO$+7G*DG[I>mT;3X;nci2Ϟgx>gwpLǎK?m"JUw"]}zh ʫ{o .!q'(-U5+k!Tb2te9 &*Az t߼ּ˩9R7|4>'\%p{w:ŇzAΗQ n%|?R޸I0uq|l-Oq^ J5l;dE_KoN71J_\hUKA{K)y3dM&ֹFСqu͝ߜHB?UV=I-7JylZ#ߞ';[{Ua1f+ +)\_jK=|&2kKQ=`Xt:):wvRvyh5Z{~1I ^7t2z':rerKN|m5[?]|!z\J%^(MgX{j|,jd]Hqo|&_AI\nvٌΜ_W<ՐJCBO'i𰣝َ41!p]j$tT55LuMK,i9|jWY"4^(m[03ۭ*ܬJgT~Y4UZnkR/© L5qNJ3ƆucG\nX7ٙN^)=kڎLѵ*ѳ9+nU+~?H^|J>IdQ̬: [cݬW$B<MՑtvlOޚӪJKNzo5܌v\c{|Ts.0WQ*)z *ك8=+`>Gf;˝cps uÔW;NRwdQMI0cUq]Kv] +RNn流V.ˣeh9hJ#HO#3^7k}=ɏhip}g0ά'2왝{NSqi)^5 O عBу}s[*o1$cm@=`|F|BB W|C94U7x6zXn*CN g|ci z:q,2p +)k¾.cq9E^9bٺ}OX:^m?V۰ei˺cHmyե3z1oej4O])$TZ幆gכCխcD ǞLM ;UZ%Etۭv#7:/7|\"c%HXL;ɧ3M%E\CӕyEodl{A[S/ѩN޻]R*Pt~`D uχ'`pNHI7ZERҗY(uF Dw#q+SY.y-%"ĥ|۸+T ewA:Z>U ^l|KKjG+O(n^Q{˾$._ \t*s=t[V[{ W s^(V[2n_1*8>ҚPS셤̏D维H7(?_w)S>6j,;Vrək}D{Y임"W%y3g,Y+x82FQI eAW7\-"#ޗqO>Jtm1ġDԈo17X /9:^g{ {9 83>mtd};ZWQMEȌ*VCe8IVMuR(XpkYFī%Ktsʣ43WHWSY\yMLk8k5q;6o$_%?l^! Y9$0Nw_x[/U-p垿9_, gѻo;پbX޹0S؛6gVNTMo\oю߾uq_dT3Fm=/ I%c{F.9wdKpPS(ѽ2EvP'6NռI}#uSo!S2p.+\@t^[ČF[c'Ώ>U㯢- ="4W]E,E( T;W1t,|Iq%_;9DOkNXg@lGoaumkE>HĎ%;l>'4`oX\k3C, wy_7Vzv)m+t]1jbq}$.19nQ74dk'SE9&f몆fνͨqœJ 5*.UN~ۃWeg? |ɛgYK{542mfmTyJvTts5Ȏl]6x^T5uK77c'vdjtԲ܎'xƣ+-"Q1+Bufo S1и^/!ZX!bFfppz KĵuзشC~myQ~m-(=3n l0m~T/࿚*M \a LbK|{o71 a Q& l gF607muĎDQ9SH҄߭\ ?P@;{5 :< [DS䧉kjdlJJ r {"U]!˜rڔV)!wB2|~C;&u<Y ՟T ls$cuiK~{WgeaSaL/4NDN6ۋ.bq O`!IKzf@ĸYFQe&`q,䓨‚&;~*k) ɏ4u*fa[zQ>UA?7ߢC0/6[AO];Ef% TLP,6qDRCp*ϙ. XAӚ7!ti,Xe>UpN=""3 ז8ZޡI{ t[,' v=;k5yآ1) `8_MAޞ)3i3ބ~峙7VF4R MKC9fdQ$$M& Y `06ѝ8I!Δ04@`2DtL2HV@~P ybĐa \c$ dV 0E;M 1$4 s~r1"3.x1 (N$1`Ba"c a$$M2;A2+1t W͝B &z*N <8ĺ2 & xQN cN9$a&Ӕ") IFA,b!$ilbb@\=bl&D;@?aB/sL  ! OO 0q0Ya(BaA$"0DL49u )8a'P3CVDI^JCzlK61QQ3}l3_q~^НWL==4`!  !K0ACHuth!Gdg4!eeC+#OsxxTT.C" ӅRtH H7ҰEE;DD ) n閾߻9kYך{{#0le9T_xk+"T[j-Qx6@)~kKu[Ob97&|x@t㾟_۟|mklK2b}6FGIĻSi3HEww-'*%WRI|+Vn:\vʾPLL۷^z$V(zAJt\ixrYVٵA{C z7VJMk`6-dȫ@m,s0M@D*HߒۑƑP ( ⡮ |z87yvu@1.S6Y^7B#[{疽rrZVI_f6x(krFx/tmP! E:Y{~n;dVSRȓ!&XyeEU*DĖ{!C_D-,(WMzZ$LD&nnK_y}k6~tK3̈́<Đ> [()-nx _Et 9Yfе59'&/)OM;/ ԯ uh?;@y†^72tQqaƉ }/'U3<`_ln(@ӡ;S$3~9Q0['rxswo. X ܃U! - ncO_/= YbkozҬpGHy ؘRj,'sRgs .EPcTn8NzF;T}|D5":g/N]9RڲO`+$S6.lKK!VH:Ez!_iZekq; 9 ZÌے^жx`Mi5G5Hv-olf-CFku_$e6(?o7i f}ޯ֠8H`|Ns'`aYdlq>(31pc.|_sD-wިVW?'ԇTO{O-.m"*J(KU9^j.Xݬwʌ.Ig(6cF:U33(?:@WvJ'=y+957k+nH-'9.)T*~S%lNGcݝ@pO~sJ_Y Ɵ[*"@9CyQh^Fvkgi 0]thLgny;[~| ,wC'Zn x"J$ ă]+EHyI[/TJͮ5"%=gz藶K*ٯE2l׎`K4ƻ8ڝmvJ ejPߠ\q FEVZ<{A+PW&wS[.G%'ևSʞ;+_d V4λxgݐJLk5\l6>^Wx*(z9=ha w GTqvVz\m|EZ':huFJ6^]p4uN>8J}zKz чdI^`_2nuBs"v~;ԭ4z5wh]Ik\s8g/qڼ2#Bs*[].ǝj_1ul4ϗIOp~@ ^~'Y#FNa=(sԠQƘFČ@WWI--]˧S?Ox^Rq _gQ*g #])!A?d zE1 ׋@ R[c9[#ʢ5M$ *4G`=9T_.}uOox=d=K}|,bvsj{mnR-a5i(Ғh.~V^SU3_7,@o[Z__65bxWMV;2ȃ)7[\#4#=6/.iYV!x 3Ua 7Ӯa49Mlt.QR:|aQ ^ROVh>kU~ > zeCl>b0>1$]}O᛻3hG5aJ>yj}QF)7dNJ)wK%oǍ~{: mw@>ܝrQ k}L}x3965%{%U P;/zWZ9R.~q}X]2/Cnk.[yZvm fsZY:UQ?^>]sZLIP xfp/hn72B63 )UNbm4~=֚S,9.e/d<(}۴Pw]Ӛvnh-~k_kcNo\}&^S+<B|/:8NE</Ԯw ""&J#X>8g?fqY 6"svQ(,nuKt[4ǧ& l[Ҽ)&y't~~<ߎ) NI zY/-3>[b(<֛o4t;YGɲy1%UY+.K1u ώt9Rh/}F-35%R?^ Q'KrPWQg϶Uzskp1$;Ӻ$Ggݏʠ.IhPߗEc2aƅU])n#c4A!Z4?chm-O  %i9RikM81i0i [R(в]$7G]wN(B&\4r~9sB`>9kKK}!l [v`;##u B!J|!1h?^ࣶ?%T[8Ǝ&G<vA8!\\熁˷L;r:%ZЙ2A 5%*AGoE5AmƧv~yQ?*~'ܴQLTnPI|]suh`2I򸚤Bۿ: @t79`.w |t;S^,ߙ#}DvnLj0™`i}d\w12bÊFNϲ4Dk*ʀiT <34'qŒA^} ފDl&ΈHwCewx)f L@Zz6!"#y$gdh;)fĴT*킵_@t!e ~cd;D@fgsjAv]%svrJ^ ;ge`gKİܾ |\]#xǹGa,E{%msc]e(#rgqc@%n;y "^@= ?*C-]s)?C8 97MƷpSMyDQ)b˘ڇJQ%A[ {g/z"/X%+t-e+?Fe~; ;z#>yoׁli^2<5esVz f<6pNtW҈F%mk{#~g:Brɴ_jvroV$|ܜSZ$nV<7(dqWxa&KϖlnT[<`Z~gQM̒(y}A}ϧYHSUDyp7CsSV" ~'w#r7:Cy i.FWI/z4y`Z; (Knk]Tz, +ћ8<)o1}j&.Ƥi_>%KG%Et 8f:kV̺~abtcOKM}kZIso%v;BJweOI5PH`r;*؞danf">V)Jd.S/fj]Hdd*+HuՇSaA-҃e #ꋔ=F t ͮX\Q'&H+sZ+n%T8)_WaKfӊ=|R,N=M,P\`io(vTIDC?:1.Rsw~Po V\+S~ֈ \5)",gXD ºʘF~ѓJ!/(/<Ũ",UO+3;d.@&wy@ "VJ$zJ]'w=JŋeNE81Ak*֘?{wJןG?|zҜŐ5I"IlOMabwbȦO¶rF{95U+gh7n͌f>劾Ϛhw ր|ˬf̲m )g5+^ܦZI:/3,ׇ[65٠HwD͚5 g{^qޚ 4C5-ཛྷz]#qY\ wrQWC~LRa47xZ}V֪Jױ,T\^m52^X`C}#5ެK/'VO޵u-$ی:7$iVnBLYJOKR}&6qϾARbF.tc-  ðU J*WI`g.7A){;buma@!uSOfZI$/I-W#FbwxqGr4>1t0ybl2oᡏ~Lkmkq"(f]Clg K4H:l?V=<,*㕐b3M9Am#Wԅ<-B(~n!KCpFhRb-fK՜ d,±i,w2m)ޯd$w_V!ICZozW3]}f諾;I|zȟ_DP@%mјbޭ|в1h'It0=4-S:Tu*uTF~R ?mJ4`Ƞ|)̿(j^-ʉ=Ax1jLe'{IҜEZK2[+,~Y.5<إ2|"yOXG,)Ӻ ۯc9MV>mnR7n1 9I(ְ^r:6( '0I*8Ŀ<9ܜkAcfq'iFqڠ K) (m_15=Ǟb?FS̾!vL[]ΆQzv7+ 9%pOhHJ-*Z*Jw5=CU?4G8nAׄ6W[̈8M\ +\]ƶi.xrѻ/rVR=5"Ny>j/E"ܫ 7GW[0p#u LW)d VUn?t5}u/b{Bf*"/T}+ 4S={f }|@o{18RQY9CleHPƣή eXir?:#GbQ&4{jJ_v}[d>i'p?n`oJ+݇w9/_|)D@r/$EUyLgW (\hMfz$136z27u$X"^]G$MJAW @of/ _eab# ! p_Fcqxp8$(܃8 Aa  Cb(&`(nH4C@p D @/0_ljB"p q#P8*@h$pZp$ w\a(,XAFD= A#2hp/EƳg8Q04N諝!8:ADqJFAq b0hDof]刳X4/u@0b'$? B8qbpŮb|[\B╲zo: !1LMp Sw(w0 4~t4P 0 $%GǢp\!Pd|?&pD]u_- A^/(|'#+h߬q[}% ͺ-`ګ {D=a+WN|t°8¹:Uj#hD!8AqRo%+ #лq0Q4_C#P.DÞ<% )ldvvF%,KBAhxxTU_=ҍ( H; )A:;AJD@Jxo{kϽYhu8yXf&d+SF|s9}.Jژ&)0(~&8쒙n\882"uPG\[5оݔGItdiC!rHC`jr XЅPiFϣ4MWCG{O'#o"~pxVU*n=Tvv)kP!'Tkds&xQY)p=?)i%A\L MLI~(QD/OA8.Wd0vSk˻|h]z@ N"YW}u; yP/5aQmJW LKK&&V\Z}*0uI$CѼR#yἠgȿ[0XR_IQ$>9Et* }17?5ܪ]ߒEwA i0otlh'9g'gGn:W?Q3{d7ihvű{J@?xO&WHv>%PÎG#s5q}E;?J)lUӝ/Ι7Ѭ{6@DsN/UFyW8kQ axSBݡxTvWnL;*MT%-ɼR0x8-"I@ܩӃ{.gᗜD.^ZSwmHIQ0+ǵv+ݙ">*?xj;#f97$q%wߛ[^롰 ` Z=wFscƆ,hy,HȠiǵ$҉}#-eSbK.+wEXhXD%Rb^&tN4Qv ]NgI2R)Pw ]!F2¶sA'WtƼgaK ii?g+\֌tL;iptT|oN(=¥lҙ=q\Rzw72rw3̰:Tɡ_?Vكv]U[I Ϻ7 Z-&1k{Uaei qGbkvYg'I<){GzHLM>({Jm?'!%JͻugƋ'x0Q#z'Z;ڦfx39E1 ڇAmY-IamQa7u#gK>&Hm*aV 6ԇa7bŊݩȺa}Xi2ꥶO4LTjPWPcm`w@ie5>y#G*/W/,O:OլjibCzj! ֖ --=G9[TTW[`z0>sGQG{%ˬ%@hD$Зre6J;&9_.}`(ɟ{w|vQŕxFn},eRyH$n> k*CB.S^)"1> ^ {r7}&|' c M"*rYc֭J׳{'HK&% !:{c$#!ܣI o=!ZͻG qmvϋmzN:*tHXznf&ti;QHXuG*3eޑnRNu\nyfPV z|c-=ko;%ehkwhdy^";31TKF5H*k ,G)=.͊/ Zߖ^v̭xբ KZ鹰~j.ZڵP"g.J :?H!/l2_@,r $+w%Ҫ;:P&Ωmvy%9ɅUaSeI`XXKkqn `A&#s-`٪ޝ!}gL>pOlHM*x '~?ĥf+n$k3b?i314k8~"c,m$\"m@;SEŝޗ_)GX0<,mW3[7(p"Vݖ)g\EYCOKx WNӃwx'wDJ}Iv3:i@3%Bu=? ^6]/>z,ޞZTd+Sf[8\\fp#̤̂C>12F9 ? cٽsUuEHVAF>8Kx=nm?GoUdMRJEmb~ny2Rx W!ڕE$ Σs9%3=]+ڿ]^Ք-.-rg;DAO*m"s1I9a>?rY"fKKx~iwѹ%WvY؂R2rRhl[f1y##++cs7<<6&<<.6hK$/1BL#j/;],0D>eIn?*"Ȅ+CFQ.EMcVȞD8ևі{RRM\90p>#fK!#wk)׹(3S:Yv~?jM•jU1x>b86׼19}X#h\ol0 ]iktYE9Ow.3>cf`ƋS`>-)<v Vgz΋4T|Rߕ=3JrAş_>LXngerK+7thD7,`Z9;<_]Svx[VHAtE(~:?ӪA>W^H[nx{б@{bnfީOv>{xje\jIʿ>_}6mV k/$Je(tۡ -M63ela"aw%ݸ6E:H[ʡv99M^m-p5ϖ%UT3Q|QAHy:>SS%b^vIg7<~OEpQ@49As7 ~?J\9l:?9Jy>&jz PExhyq?'NǼUKlu4mwwߌ!!T'kS)T7|5'ԑ{Է?H/X%s>"W0fBof[=`MfZraᾭo--m3=/Q So}JՖocpmt)@!TiU m鏔".{%#1'd&84C~xx$E'5TŦGo|w_z7h[x'EuČ M&˕9;Z< E͘$&JBs#"m>X܀ˬ&HI#soH1'N}v|:H߉=˾ ib9(Cg q|rJ{CճL N\F8Dq12殤l(;]~$ CW=s45Ɍ9s%7JZOXj ҫ DϭJqz-a.$BU 0`Gky3ZfCdG=셵3p:+N79TCoMF~N6|Gj)8G䙇Ǭ[re1+rrFz atIN0Y>@ʈQEFh"n0{9 RhancݝW43vuwl?`5^`NH`a@ɯckкuF̢jɗ3,Lb%zi{ Q52aKԒ+کJ 9%\sFC~nռ}Q{O#Y'x~6[HW}(~'Y(#d39C>fժd_$,T.|F"ҾpI5>) ܝ*:3ƗQ/'٠1rl8mBևZ)>vȾ&o^ba(Np5r f?,N,6rؔmkVLhwhx; UMM`\>UV+P7IqDMR+(Jd 1q';k~Y#epft30 k[b3r[ ro2h"?Z3geGB+6ij$(QRm#wM̝ r .ٯ5DyVI\e1zEp7TTՈLWHa/~EaeTƯ zdE 夡جz7D<$O5Ӓp[zJv5 5a;/?"w6~3/Zp6e-~ɱFST~xai[f^wF}(p(6L%B I%ι9x4N ëИb l_$ ö(H6{D=RTJx bqVb[cIY'X]DY{ >h\N]J 3T *#"{(FfLv%_s+z>k{4fp)k8ѭEeҲR&bABHZrLa=p:G|aCd `0&֤p=hosN^>QGV8/Ty6mO{^ n-B`5Gz}%Xc W,5 H81@({4qo+9pO%.9*qV5 V(Y}xp^{xD~ҀKepڟ0'[5g.뉅 kjR٦Gr&H"gAqU1\?~thhiE<6>2$ x.*Bb+r&ǞWGS??]#6[BκF/kmƮAՂCjS=g7nw{֮ba=JY~5J3 )l v2#gM1nK99¤{. /3JHrhRoRӧ+~(a^g;M/kߊX*:,UjS잴׭b-=Nɝ_xCy6KRWys[%OZϻ<[ toPeƕЁ SyM줹q*_ͯpV8{z_&inpK[٥O9rl-YrY˩'|Z9r0~E‚y/8鎋BPjE[9ou*}yZx^&UTIU1ݡ a^5Ahkj% zB'xLjsT]z;k.z2w6:~ H#H.-ϳ'wͱ0 Վ:;[7kPX%b L* 3FKG j$vV/U)}=NŲg h7B),d'(lAo?Vi/4dX,W{yCteV6z/ 3_ BM?l}h7mn AXIl]6fҹ $i.kLQRQ;gUNP΋*_ɒ?e`@DÀeng?opk,Zo@o$zo$䣝'd<$>'dbd(Pf/ԱbwqϘ 2ZZ$VqcG{K8@Մfz΅Ҷ ŮDWzޒB,&Ȏv9v5LXgFrSl ŶǤGg%K$FC!¬臚8D\㺉2P%i'bF);"k/]H6C# "Ć?NyQe:k8zܓYi6 X^}K!㇘ |zU‚fǔљl7SAB[4>=Iʰ|x߼w ;܆o>Kk. xkAB<++V>}u֌Ϗ$22^-ULF-iװl=`_K6mlںuǥS!_CmhsltV^*-#,Yפld~m[\ *$sæ5:eM/N7h̩7TȎٕ=('Y7*5+#٬ ,t0tc`:_[;O*8RH2aVz*ijz@7m6ؐz$[![!3p#{3Kn+ao/ޯr4ļm6<_X~vn5·PcqEbcS=^\ $ԶƅgS43XޭJS(qgv̫g &Tn(_wڶtw}功=8ccv&0;hO )hLP+f%9`(\hTjhYؒ'?u#S`Ar_cP?DZ~xz] u)=bhvOa}]<4UDR"oOvaZeLىD]Wߩ!И|oA:=?B;ʕ6ͲSGӐt>`H7y9- xsv(+ MFu*l1u"d;}Mݝ mdq !uTT)fR`ß/ESFxvO Qg`MJU8KAc(uRDBsU}ٽrLػfu߰w (y3\# X+mvqw;|ͫȗwDWEL- Xr`z;7WUS_]~HϾ2VF{ uO~}uA9t*]͸N(r٣96w ` ZB SEK:7>')4+5'Vřَ2"ZaDA9g/ТLHab]\rpo }ƚI#آmcL#t}{#TA7 {Qa4V`d=} )H^*X.}nZ g3m]s}T5l~I2ҐlIֈV %e$J9z-W ɦ Pmk@[t-Ul-/7G 9{pU5O< .xX7Ѹn;>6\/K3׃"5^55„2/Kdv(ebPT7?](nm D7Vov~coXU %XoU(h vW8w%]j&yieW}aYª];yeN-⪥9!fMGڍU'Jm1CT^BsXmϤ1!x.op(D⨑Y2ߎV˕ mՂ&VgSm^`:,rbuWż SNA9߼V)$Ҁߓ˰Y[1¬˦"vm//kq(B [u}CU=TwMؓU{ȥh3ɗ EX%7 Lx tu)ݥF_0I)&(}ǖ>Lo ǟٮwc 2+~\r-wN %W)W֛8\).7'.0Sz6-e)sr>0w$BQgE3 [QtnDaQFWyl4Toh{%|<.xu낖fѣCb|Ž^ 5mY:+d}wҍ0ikM'1jVl^/?>&J>G~>>`Ĉ#p9enj3fKsie+]onWmsTҍQ Jqn2xnehV>fZb.n_Pjv8,h,>=>;&'="ai˿TdTRK0B&KxDD)-ϭmm 566ۙs;&Uy`ἰp6@]8nQwݽp0-0*eܖ> [5#1?}urrplv;)#!g&ll&-!Tgh78#8K4Y7EH|^B"FַAp0‚(R_oFU3>b25-oBq)qJ]>=℡kb-Н_aeۓ\K!_K=X5-$?1D:X&HEUK}V|՟Ex`}6}, y&] EuA:R)|qS!?=᧥$eTV|l}DKrt1w[WH=Se?XnEǭ8nQ*8@d UoUջȳsLJ\oޡD ;"A}q) B dQSCR@$D}L%[3@gCƺO,=yƍǘ C@z!{̮f#8ܣa?i&9iQz“>呼~Q/D֤RѾ,`G?{M%yAqsNqOsqϚFxO1V7*i( ^VN1QrԜg!f/Lbu]w" 4/|n~9|bi?,v9x6׬N}dSl;Hu{:qڐ28B<(?}sW% =F{M<U~tzzeAxLtځ uي+sD+96'"VDuҏ~L졝& ),K D4,Zb0`f /fC}vBr~#Pd湝7cu~`>j {֙hth (U$%?LN@oP A5Փb/bG-ШP sДW f$5AeT[xX ܇\ k`y_}kISn/O}Fi[l,蒿DZV "lאP1RhI~$TA BD~eap4cưVŏSfvd]L.K0nH?d=v:Nq%K u;Sx(߲M./egߦ7A"ٔ+`( Z~AInP)Jle ݉|=U s?s|b]LJ̈k,obrԤ5\<{q[[e, ^"k7 ?Nj55n6ou" riܳ I>鵗S#ڌ%i6kf̪c`_J7H}J=_t!ٲ:H{Ma<J2=6嘞s>iҩa4.(*XrsnMTgq:Zw(B59n+:ZDƎ\ј,ıNӪ7jϪ[k#QYt{t01MC#\]K1{ު^1bmqaD" ^kÜp"z'Y3 )/=\.Y\dd Q3؇Wl?XsZuk5wZܩrTE4}'׵w3xRK@m ZO˦_K$h~Q ]T2A*Z53zڙg{:mY-ͼLrH. c^qn ޟ Oq;"N`N#z<2q|p]A%ާU[-^{}K,_śh_`Y ;D'/3IH,m"53]<뻯4x ?U^x%.ƕ!m+MW(B_҅tp%ȭYBmkٟ8fAvS֞TLI:Svt=e`:j;͔@kԖ )NN#[# pJ<QZj]\|]]Bg(ʙ'=E,p^ f#`jv\b!eUKHʈKCԅ|3ޑw1 *ϙכ.ƍænI`m@oXJ) tU? _bqsɈzvpPT SrZmhJj.oS)G۫n{N % x[L8 ݣ7ކ߹R~xvX}^4:eխYgB?+.3Ql;xX5?)!OiQiv**,'˄,8zh &`|FP<*Na@nh|N͆Fx0oǰMzp;e{Y^B3%LOF7N/rB\aa:GXFZϼɷWUȯjc!bȘmWݾ^+Z fԟ! [;6Q+x]4j5:k7歷`1*nf,b3 O/ c_-᪰/_P]%8W=ɶz/|-pik:vnmknɩ ΍r_$I.f%}8o3aeɕDZi&{V*mƽLwqb .wz"mgZt .XJ~+~*yZeX`F}^T6#sdyPXi2X}G"GGYQ<-=C+e2 sȸ?jO{.d(ڬϩ[TJ`5a5)JrJdY`~VQ>.@j&]˾- +zMiH4d/a7^ 6;u !J9V/JU.BIp j/礻2s_Qz=Q(E(Jv49b8/[iA/ޘ0{rC?ܯt,Ma3,8 ^W\V7H=fCTxƳiHx"&)/uIXE&IE@;;s4N8C @/zxyLL/ I@?'(Z0 gbg D/`l;?||<7'\f0<ЄW9(s (0/T"AU(߇b` *`À C@ Aǁh)/$0(߿`8x oŠn!F ex@P4O L*Њb9}6vhn a11I`/F:xxT.-JS4Hww4 ""- ) ]]g}|pֺ~f=7^cF1@ (e;Lvyi׊Uh{WQL_{!)T=⧁DNU2{LZ6"3pZpFiF뿈1ǩ[zRWCS~L:ђ7FNEW%x/0ndjޑjɏYgXL',^FM=NCl'*nNقI K*`E8FBWk+CEA~ H`m!R)`0|59~CwEj[k<@Wղ{(S![ndNAZ"_®bljpT+v\xIk0DOg6@~N;nB+fv=-R܄Uo:~jk[ri$2Oқa>}Ia<08 !)r(9;o_i4R8W PXPпDjF^tuGv9/2+?/u.im6S ?L0v~ʪk03v58۱KcC~k& ?8**UrƊweLD# w Jalϋ)=TDx/3TeTѤ7d1 'H  `G&aGE|A3Q.n$e~RLa嚄Ib%"=52xl 7rh^l5w:=$zkin~+r(<迲hH==?<39΋DAꌪAݤԔe{Âd{ʆ*G_~Gh6dRء:9"ἅ~KpS ԧ%^Rқctl~PA$ΰ>[  bg,VQ&'Lڞ6LMaigHLgEjC:(gW RM4=:\l"(PtY4MzǾh{wSv#dLr?-%!X9UHtڷPTg9t#;L?7Yߣ;Z̙kK{$gn>ݻM\EF9n&e7aOr.LAOHM}N'+oq7oqc^pH)~R 6C,[xnWMz$+["v&oLGαG.F&^*,"[J@IN]Z$TvWK,=RX SK4qivYx!:mTboַd:~gWHGP>= (UMf96!L4ϋ;\MYhK?㼦zgл;`>@?pͧGX$<\`htSQeAF"B%W6TKQ 7m,{_7<_LԳV zD|L_\\i "{JЦQO' ]ٙ/ɖziYȤْż?+@*yJ(70նq4KLcyPG#K&:#\kJUi|K9f;c5&vɚ19/?k`k/YS 6#GU"f`+lX4䯌.X&Ti9yiy\9Ai4׽%ԑ6@#[+J?^?^iu*$hC-'4{]@`y"“q>.a\U (Y7*ϫP Ȇ`p&:͚ gWbj&vWݿ gy%f/şyuty/Ay]>KZ=ڮ[/3-\;֐/%̥\S٧Ol?yUiCȞ *>nm@㲋 B F{/wIH5=g׿?~㗳mp jmV]^bs,t̅L9w=JT6Sشm=$0F9rtEX` =hFheDM%c6; UoFZoIMNxFtjS=m*(!B|~bawaU4s*nE!D̈/}K>~m|5z {$I֕%ߑ !LUF1>16Sjzc?PӣAEE -gNOuq_NPD0͊1#'1AcR2!\{mOMqto2V0*I"ajz-!j'\&ѷB^nK񿏷m{<+*(lV)SF+%<(kW% 36Tɤ(Z'|GJ'"-$__FDK͆4NFr>-V P9WhB~Nf.L55br #$ܹ XeyIf -Z}|)^E&=SِΑRݎgL6I1UDXŤ@/jx`ջoio.\0,gw07 79*9oڟ=|.kMH̗U>9ǦR< P?Lꛣk|FFOww~7̓Z'gU,HNχľ 7J0LaZB$~`;i}!Y"pQ)dZp|s`T٨[bIptMMjhTqSeAf ?ePJjT 6I7b -Ҥu\';$_|#G䉈Lu@RwO 1uTE%aK}gj0Puc4zY9>L2L[֗6b eiEa IfqPU 'Fʖ,1B/ 2'SE640 A'{[] YrViM`})S*˾Ynxijp[x:?ޠH?[YjT.H!ǼgFn:Rʹ>BUI.N Gt ґPB]\b~fU55u755uut0uuuuw}*|A˅Gp0_}O:haV/y\h20|yu\`n_ѩR! |.twvzz`zfէKpB+`0#YD(: H65΍=r ?ߚ֊Qͣ -riY= D)ӛ& vA&|&O VSŜk&4;.=q1ܿ4IB0yk8b(+qpݵ\,kb#h.ouQ\se&-JFf%y!N2 %Ԋ))p;(@' k'A_1vn|C EVMsd>yQa;bM<e-&P*PN3ʅ%yNdY18bVKu72OHeq6],*}:ϖ9/< =gVwm'][_ыi}\8Qsj q6pa~!7ϸް+9-w!Arb$UfA'!bW\V~`/K Jf w ^<"v}hś/uu|- ~w]r ZDzVmuȧ/\q=r~Lp7(X0.^p?clH $NuЊZɈ"̃ B TdYfLzlc[7#ĦOo.`BwSCj䨅%_!QC^\KkL""X쫯tD"xq_oB?P3R{KrynkWKV .!RA- ϴ=l*J?暞"l:?+TP\|&ܫddleеXkO+)xɌylFӓR v.3 eOG},Clsc̰0PaI^8ea v("7S yKCLʴ2]ELPŸ' ->sff6DXq$Nm>V~ k*\eCg̐Լ;g\GZDQ_4NMo;XOd~z}!Y ChV+2hɌ˵~FIdǐg$ 爉?2f ʫoHlk{C1b4-!?ѹ\Ow @~֕D_$Ŏ|L0"FlL≆g?;vӇoQ3eVɒ.ѲKX gJP7QOXq>Pr*܊mV>eo:Ѐ&ݑ?7·Aچ@cꢪK5p ֨dC ZwH,)YNU7.?cJ-e74&K[z_%8DU&Q NM%  V?rLz,Wkӥ 2iX@8Zǭ/yŭ"c:æـ$?ENk˴MHURoUFCsfNNәa6Wl b|u~]UzAU7{vv:r%ex:ڻuG-c /vC-4Mjڳ?\2 xԖ3H*V˸5ʖ¶R| מ--ؚsn0) n&lvl&z,瞜&3ק'UCA2#@[^>3I+>&Hna8CGhӨv$ D[`(kfpbU\\OOdJ\zc”o .:NpM0Xj|YigsWeT=H1k2&E~3qQ+?%gkg;*jJ%#NST.>"U8?ެMDw,ط"ˢ's&׵s2nqPHN8<|$Lk+k^SRW&Y)[w@jbGjP+iurt'F3;Vm VbΡ+d.R$3b_yA4V(-޼tݯ4Ixh:L,TԽYtYY:L t-n!(^h@?wcRӚ[+-e$W+e4A ](}1WZssS5MEhibb= H I4K?x f^n}M&@2I֣A{zu-L{?>+RM2o<Րc%嗦ߐFm79*${ ,|w}V*f@1|ZYM 7RJAռOf"etɯ> İ4v8SGH C=D]O \W,m9(+ejZ1t W)y +IFi6bp j!? 2耇7]˷d/,WVckxg ڕ[#3Ur_ V3\5T_U)rh}/YbO Ӧ&""=;rmEKM|o^ݍ<8>BV4 &za a.e `=? g; wx]}$PHi+zfG`fUR<!⥌;qqVg‘VZ9Ite|4hd%IcX &fIzc)Kvղ-rM4I̘'Rm.toK>k$57?5M(AQi= ߺv} dL)wUM4sō~jtp ˡd^?ލ'jM OʏP,b?W~je'&ՖVWPCX"`,s7sWX+V 5%(\3>98?pǤ& ] aap`8` (u z/1G@a{Pп0sD wܲq?A gF#'b ݫv7J`wA݄v80=L1` Ep {J zys+Re@?k^K9 @ۜU /BVn{v{[ rA0mN/!iVC0㶬;5m%ی3^oAc}Q4ݫ_N{\  c]Eoqqi q-0xU0ȲKkp=춏M 2o{ݶ]w;\[r`zi&(N۾AB o%{Cvٻa}w1 'ۆFvvgx#oA^ ': Anߝޠn.;n19(mw۳?tu63wdU2g@bI(TD1qXLR\GHo%/) 5gwq5vvp6 YY%%`DxPͻǁsDBAnAJHJKH#t nD= ) twswg;swfgw?}vf{hC{iKb@SR10m"8a,L!poŖ3[O ۮNv۸s(3WgFZbbjLIpkfa?Y KUmqTo^g#W1&Qb'Px }|?6ꤓ:ISn7E) qrK6eFbn(9TۦG2smo t vɶ`BӓK;0NT[%4+\ш-n->Twƀ!+&ơR]Ob}ƒ ׈!mYPDc x,GA R9B~R;ތdٔ4; ;aBaO;'"q76grnz 837 hb1CZ;Mi\ fwQwY?YU'NOC}|RblӜ}N'8%Zw|{mxdiqgWOAD)m rL o νF$ +l,Rkܧ+L*ͽ-v h?V!\-OIhM־tKD<\nsWbP2uzF-zdOh0'RHc*J ̖{9U8fJy"s2[.ۙri!V|̣;y܊]kU*Bgr{hWN{+vVQƿqR!O4Cơ9]tT(guxfV`ivΕ'%QMS+,{_b}Pg}vз~Sr2s}ꓰ:/bPU1,|xLu ]謵eJE0:9~jFU?RQ;' \44poN(c'?F7hAt]Sˁc焁a0  52_ c`ȿk x\0qiuA@Q \b/C#! ߿/*"e R@`%$_.II W3gWOgC ^5xxP]. Ғ"'8 !%JHww"Ҡtt7!y9=s̙]{ųo!(5L>~$Cb=6IU&EQyEzȳ!ɶBlQ7=zIxd3[~G6гG.z6AؽSnd._"d;E+ݜREtrX*i ]|npp;:[􋉌πkUKx^`CLI?I Kbt.r~#9i[5_G]w+@:&/8rL Rfi, _[AtcDž{b XS3ѥ!";xbt{Np R鄱gq]4c kLz_;/d<奝 Ν88?"6 lHbPMI}J,'<->dmˈۇ,hQ`)K D"MWGż OD_m lH v@22#2ixe@ӈd2CA2j+kJ핈hfjP-l\'P*ea=iG$ =F'dLJ#)cbo44UC&^<ҠxÃ4ڵ 3Pd&AG:3XMz2ƪW#ǝ͆ #Y5F-YmD9Us8ЅKZ/8AhIos#qo*ntj4Yi1spEtz=bG(G"cKбnjfĂJ8p$C+/QD5 K< E߰"&= c@{OXc])pC/Sy)Npac2`VYnVfcwp6_S?5lL׼g@zQE+¨@ՀϘlב]dU)@n3ԗ-L"*QE5Q!0rV׈(xzsq/Θbirv u/rc/bF=J'L[{ l(@E;`dp:y ՏZ4ɡp 7ujΰVH ßVڹW/颩{ClGr؞ >~f7s ͎|>7d` תT..^Vf/fSP ]ywD=ݣ9od<ɼBȆQy -י0.+JHEaAwKŸfKTeN;# ޺m6)j 2JbFW0ik{Ń.aײtG1N󶎟p-{\P*cQ7[İZKrwI:ܬȤc\(~=7N^uݪ"gXկ_kNH$V46s[7kfA[x?LϦXۋ-7[c"g MVMS8IIֿavJh$QLH6,}vvЖ+Udع6xfO׋fF^=I͑\BeOETg!p־nWyɫN|L{o#eXj} lIn:/KΤT;|8"/ ZΐLᩚeUuٛEwto %˧fڌ?ט\CkV# k:c<4hqV+Q2R*Xq UO-jB*<?,r^@:qV$m.+){D"qE83w MTRF{MgGg4C 9mکl%#r|ˊy:e^K;ݤIё" kގIi>vV2/T3Z( x3̹NSPOLpXxP1Iѥk28ϣV܅kv/%Դ/&FF|}q:\~*]GӉ6@B~J/0?G:c#2юQ% o8‡̋A7h5T,qeԯL 5坕;l?ݎi8GbyʰήbZ ;ywx{ߪ1htբANMu& ִZ/ɔwyXjme\?i'6Fd1Y9lݔiQ]o+p,Oɂ{8HX^L]ge}td==4>5~`89K--yOzߨO0g/vEb 4MHx7~܍E'YynDy^r:ܔe4>ΨԟVb Ά׿ybݒʻϢ6*ɡB6x;553C 0ʑQqGe?Kjv,ސD=tw8~y+.(s"QP,.ccACfYj4nT/y?S[OafյG/^7~޲M~t~H@Q}v OnuK5HmL52Dz\ /bm_>uG{"!'=]&^pbfߟCe]?b-yi?(RJ~CB\R;sЌe8ܤ"EҎEߟ ؖkoNx=%8WkHg ?yH7ELiWLIN~%cȯܽ9 :宔 lt y;Wh-FI9~rMi K׻r~]גS,%[U?RⵧȾN۝m!zcK/`Lu#z椡NN: Ik <׌7X#rσHE'/gL#c,}Z۳NlG͵Vo%u zZZ!ԌDݩE)3ƭ>ľvOJ?5-,Qc'3wPO϶J)4^v8`7)cg5Kݖ~qoKx|QmEk_mNLۃ2? [o ,u9Z2G>ܵ`\ d-r}K.%xrnjY2BXM{%CZU]G2`ڌEIu]~>0֡C2!uGMϾ1XgPq3Ur&3:P6DUj01)S0oz*a|ɮhZεjfwi;;l#\h>h!,`Ggҕ9&*@g|A-B F[>)Dx~Η?-g0< wofCveۘcBVxqs^!Q*C3?F".!qMjx,Y4DkqC=&2Wʁʞ5^G~5~\ ^,"{Og–R+*qEG~훉cW4WP+ӎB{&<ٷ nkb q>3I8EY8ئXB2bh$+&`:װg\ [xnj"=؆3̈%eߣ\-r;- N0!)BT_D);TRVF:0YW#טIt?F_ۀ"s;ss 'b1\X&8y8api3ܫ9|k%_Tn\q4aWY|WXK;' ,I*]J:Kn + )(ײڐje-wxor$,Kuc$Mnɗ03٧/%S"7۹3? -jBEZNB`m;c}JM,P@ߓ Uv3vN[G{Rʸwk7 pun?,*ۦ l\"x湀&i/ZѵKuuf*bksc<.ۚ^X.xa7?f[FG.*KXL~2Y6 ߖzqksrL6v~@rLqoOmD^Y_}9F2.| ɽ+}X geA`KD9&N|8 س#[y&ɋݯϝܘ˪ģ]*~7 όM҈|%)"@ (xZF9D`3*!F g-b\W:RJ>rІCstbd uj 6ZWt;B]`I KPI7XS,F]Oa /كXKj%-Θص?Ҙb,6 v=7AyNj B^r_ST -.7_mcL HvR+*2?t"X薗*\=1o^&fgDD_Ul?=w\!M1R;+zU;e"x.%%!xHhKqNٰQ}pErN#Xτ)V3 DrlS_fv@$M{ZtE_ߧri!Mf^upO}o.Rbh~~ Bof6pDUOO *u"/)rR oHKhu#q.\ՙA;2Xmcږtb'_(QS{+!|!z^Gf_vRMgW TF唛P,ݺ0f'2:ZX~‹&ْ(2iU: SQh▻<HךӹsZzn֐ fJ~ʾ bfy{ʋiDҳd{ˤ1zg%E<+榉 x]: 0 %K%#\Ӡ*+d*D=jS-ZI2\;77txy5 1/gӥS}|c||:d ISܙ)uUnLLOn7+y`+j-QU>(]aKsY2<~=Nh2v H׼gk6)(fViK׺ޱ{dW~5LCw,+sFzK϶GxנI ;Á#S*Ĺ[zwM}j7YqBuZ}FB'1;uX5,$[re""%N8$kgksh]#1;5Ob Au-v[:SzB1Ʃ6>N]!(x[! Vdb(SKFjiܤ$Te8ܵ%$f[7&.R`t/o{cX0@nh/kʕJAUȀHh6H,JrF<񧾊w]%ԆbsاN-P8WaVh]Wzu}/2F ,XlY6&ni}>KUTzQ-枴)g)!0ob~% 7D̀|Z)afXxm %$A@ ~Td`>EW30X3?H(񁠰;@ADLL AyA܉(pGu.@n=$C !(v| `p>pgL2-Z#ZɏR/?+0n#o@Aw빥v70 a(0@8?!̇CqnY@@a("`QK2pI 8C@`;Xo€#(!`TH$ $J!08 uHE)m _U-uP0%A~~0 JHCbDQ1(J (P/!(Ao _J 8n3o1J?`]No1` u-eP[n>ۜQʀP QoE8/Svs% GZp0n=[)ݍwC وw0q]#ߤ@Tn'.H>Cr1߭@$CCQo ؿ`!b FsV腘P$"!u_| 8!B$bh3 98;ݺC13K*Iwo+xXPmצ iTRb;R%D%C`IQA)ACoygwfgs_\< &H> 0cbnڹŭkI۞Ѷ$ыZ .aMƊ=$wbqMlD$TIT.݁{X'A:{hNm'K>%Z[whȺ]ڈV,XnޠիGnfyd!(E{X`O*b)TR M 󦝐횽u>&|\arGf>Pƭ\&şmQ=ɏRҿS Hpd^et/ *=geR׼mkIkZV8<%DՆQ!k3RMW)9Oa=}n uGhgL]*|~Lͮ1QGb<&&YVkC`wEDfE̊[=Gk5Vc#s|VdwEDķɉr@ƤZ{ۖ*aۚޖdfz B58 Wa켼=1֮ǁ@ r[UV$J Q`>&ñY$ |0H@E#;4  \es4I'qsvA 6tCfdRNժ<Iclb:Ƈ\ UXR+=-(pᐏZ )ɨ#(zkH*Js&4+ŌE}M%ڛ~"' upet5,;"@AL 8=IdEK 9P$X^,i:3u.1}K j3h&|0jMozKP/{ 3)&֚$r kyc/E} îdAS}ylW2gB덮w< {d— r=y߾SEϱ%έ+MڭlD3>zqƆWxdRÉʉA/7ccտ(ţ}QkYg3#Ea\ɮacПt S_6- [iVTr%a[T\K-^ }M9{]pKkl% GNBtܼ5 cxe H*JOc\rC@׳Ϙvx'նnu"Q_m0a`Q#C!rjehFkN̊6&#h_:jj+>cHyIqbKߔMtC^3of]N'j';67_ $۸OVJf!=oy g>ely%[8nʂBh)3d+ ׾t]oN-h&tFEkz:u 04yY%WKUύ9\n5g²s;Z~MWsI~bgz7#^YE>t}ڻ^nCjLNmȘfS'. xG5& f*_ /gɖ%4 "rwF/~M/0nP Z:]BFf>7E"δov7Bbn;BY{iƵq+FVBf}D$ zTxtHۯS;Q'$c!`[Q3\m.`- YX*^gW-r zMbcOhwE q42_^k)Jp惀-In>숅;ozIC;0Fdtt,zV$*{` \mh5\f:y{~DZ؟Q&![ޯP`fpζs>ceYLz=qz%@X[IiړʭG^ޗAVˆ Ĝ/"PN>DZU)vgP _<8A1n:nוN> F.S;x/`Mfk)>ݚˬ>l#F8zV)?i\䑠/} u/Q"kThuX`t[]x8?\"ö&k3ƶQ] eY a|o=/ݖ0y# mFd?y(-Y?j4~ѴE6vS%8 LA'%Cb4V޼Xwx򳛖3B3vL5G[g#7/R؁ ~rs?v-|cp[,Vp %Ud_W.zDER!<0V5h7HoWPb$ Ohh,x76J_vkH.vCD|mZEvHk:l VX.͚{]Rg^'δbԁUӒqO$Y^\Nk2,ڐ; G#Y=mJۜr.sDv{ok95UKr}h@Y{~xݽAlΟRi:QwQNE{wM?oʩ\K)Gd^꬗~YWiomIz~65j4;'e鋖%e)1Z6K[yS!q/e6;""5ܯg;[)eK %F8R-S{`ᵪ;/\K~,\5cޤVP1[r"Y6YL-2Z_1*寕[~%꫁Mz~φW ocp#^_/L 8+`;H3@C};GhzR,XQls(ZR{KƯ@zlBJӦAK`O [g|"jrS ^KRYώ:SufU`ê[Ӣ~>2VrS bذ'bԺFj:75'Q"7$$%m]]%$1'GoI'I7Iw7I? O߽!Z 00  @B"t:v*>a)!*rrv+Ms Ea "BX<*!JABD4 Cġ` Cc` +,&e0Iap$ JG ΧbH!Ii!(I(iH$ 郠1 ;O:B $q `$N X #h@`?y( $@!ISDh"C8^4HBM 8R@hc$F2-M86XRq K0)JR`_(ѐ(p0dh$D5?Iz !QBA/m"hP 8)F82KאbB C[)HF_G p8V%A\b ($(b;AA "`(q`BMh\`U(6p TT$@h$Im0~BB p߫@S< !ΈĴ8L\-G{BU@HF ěP4=Ih3Cx]Y H(;NzqC$ A h4D † CCD`y 1Mi񤓑4raQ ޅ+ JR D&&T@pe9>7ĂON'ƞ F hx{,x} POEܨ9X/: C*BtFUT[2 2~<:$+QՆxFHo~ (!)X X@tPVc4I%s"0l3i,0}BRHLӈYD &d*i$@CqcILДaǨJJ1LBd$Ѝ(>]:ia  ;-;8XqY4Q^(H=H8 ׇpv8MYkTB~_o;q4D 5L;-| AX/iTC+yJ'4;ЪABmd!00,͆!BYHcImHRl& }TH,OPYe:QTC$d 7G~G -+}Ht;:v0x혜4h!Ԃt'01,3Ʋ _a ** [:oE&1P i$c@@c: /򑎝VyXb:1Hwbx{xg ay34TT(YпD] (],S QuYgzO! erЬP OH#5tl8[?,&@N=4L# ?B큣 d'_U4MXN 8$#1xB@1src[4Ѕn!DJ ؒw0u~a@dH`ȝQ 4}P@}xs6ُfrsxK(J=W}2z*̾6{ߢ)C)Og&{8V&E!,p_6ŘguB.H\PYf4{150~9zPF^ nbX1uBj@6 {a2dy1Q{B/] a1(`2H 6͔P 8!B.bb@ &:(+h^ 0\ `` }zNBjbXWUCAȀ-`2(89tԡPLBa3>f2֡1*nx{L:/PF'MWlYwp ubiً 40ӉtcRPp3[p$Vؗ.,Ñ0 Tj=db gn׍ÆC ]`cQ {±06lǂu08ݡB Mw1|f>%da6c  pR.]{FXfk?p[YhtpA{E_ss1YY+6A:>Ac#-@):Z7K1 nF?a\֡'Р@^{2``)0s1qC}A>@C_茀`YF3ϲQ=ФБBa n=d >P:Gh? ;\:D بNl& :]PhGLCMڑqaىq1q:rB+ Q@F F cxTK(VtAFn9 hB~/_P 11;zD?$L u,x )dprF4,c4&:7;t#i5 48]% %^OHj59@+bp 9.q ŸcSTjY}.P 4* >(dt}>aG_l>Xg *b(S==0tf]dC _] t 3z`~NtH*C2c)ܣg 27]o ]. mt񄌁#dQ 4=e 氬PE!0 m5pa:#@LPh#Od#p€1AcŨ3=ab[ pJ>;1=r?fgү%-@lD f: +t;V"!b(/)QćN0vr>f:a;ÿhdb˨1͐2u`l!D>@ AUbFTaG cf#<.Pe} ޞ.tH{F9 O_u u搀urJ,HB8x{HF&a-VˀeiEJ$(;~0&; .]]GO=0a5Xq0P"@]Qi#S:e/x_HDBgxj/q9ЩoELMIG6 ]1 +(f . !j02@U2 M3"b$d7j x(k1'XGFpҍv2$b rQL:<v.*.W\͈Cf&b d) dS;H ]wqCxtGOpפcĄq.6FCtLNj0H oxwSap,$y!v*^$LRuWW@]v[ZvVWb*6km%$x2t`: ?OơX  0MO4y"@ $ة8[%t%T!@"Q=*h mLwjF򙺃w Qw?h] '%xo(LH7^h6íeT+M V<hO޺kn kD_&8͟w\\4pQm?לOx.%_Y-3PAD'&"Xv!.C#QECF1<ͪ8,K]faFf4vˇ&Mۢv;{C|W' ez9P 0:{NXw粒Ms~e7<7us-)yo_\}V/͸ʹཡ)wbRN^~;5?!7n!_"#!Z7U;8wk߻7veZKe{dPTQ<[FEʅ7H{QѾ}++YkHER^%'emJ+<'/eB.ϊ"w*m~9S$U$F~w3ծݫfӳ?HDZ! 8QCiKsJr%ƸX/uT=wV:lIÿ"Zʷ֗ :=r̚/_WyFl zkH@CmڕD^7Tm+oh%`GTlۦ? T6ז]M%k[o [m*I6qiqJ-e q2F FLk/LJ[/q?Ong<6kaw.hv>Z`#˃G(L_z~EUBJŻ}$lV5?\jnX"eAaΫwvu&Yx|=̦;-w+שxNHVkצòkPun_^ fL1f_WoF·[۹9^ރc2uo:'~}fi{ rpd4t;ӲZ~ij"V[7}!9-SEPc+T$<@cIDp4LTKq8"XV2l*#0CUЪe QE0?#\,]Aw_`̮zvX{3מGi[Bz8._ˍ^Kj}࣢ W-Ew1vye,oߪYGxӿ'\~M ]FGsF꼟jtl]@PI{\G#E?=xz<{,^p/0S{W^kN=sխd,qm9ۓ8~YX`oڛc=4.ܥ5S!?@`'f_$ EQ6ǰ?^IϟK˜l^T]*x; Y oS/;'Y6YMVIbC}r6+x6%MZq.lJ%?>k9^5P,1*|i"ExnCá-u5zK+>_?Pqѣ]2~h5/o]KU/ޟߤ7^.ZM%.7E?6+SNXd(!AKU5ٱ+c,(|lG^/]|IHzfQgq-.N^uN4v*i)jjkl)',uIAtj:]4>ʓϺRsb$IMُ"$#%:Rď8k.ʓe\-0y_H/mYu'MsظxFW> !z39wKYVe\n/#owRR}w^)fO/OW#0 9w7yK͔,W{6l#mE "s^.y!G -ȫL2坚S8, Bީ | ,AS5mX|OpD}j=,DAީ$0R8zk^na NGUp)lq(|s CT&^a;! VE0 Nj 8exP hBcs7h> nA(N1~8(H WjFFsKi~G308? l 7".Md~x A Ȧ{ oAјdP$!X2Þ oD\ -D0DI@ aq)q)q"m"A(/D荈h[)'d-2<YK4Ȋ#R8[Lx,<'eR#R8M?h dWbPv2eZDx$U20z`:ã@pkMNo#/D8)\,|e9Uw wadsZ߱?xI% k}rRq0(\h? XKIKI[u$AzISU?ms~7WCi/b?L =‰|wcdK ]ΤTݱz`q?MzGYF'mTĵf;']n2'&fBfo nsxev^lt$TN w?{'ȫ<.U)繭\>{Fb;rȇ/[7bR<̋JҼczđpQ~OMzB񲜧 $\%|}}+ W;z- GmYױh{7˃+5*oxLkAG5G>>Jo&ן1{hGW]+{"R4+$h&)5g5\sE'G xt{-J|s9r"+$5v#{ϘP u'k3MDDmq#5ݖo9)( #wgc+ IAKcp},NgiJjRʯ8CHO?˵Ą(ʚ˩dk-_7>[Vnv?νulIRDeգz=+:}Q?9ѿvd>h@ gg_?iK;^*; #h#~/S'gD==k~C<弸͚gjҩuO/}/ex>&!aFN덄>mF9쵝*zk&i9~>څw1jo:6]V߷.g^Ak~l^Ugkn#߮Z؂Gϥ[ԯ^ݟ{ {Ox/;y(#A/=B~:Pms5%/V6pYHuhZjo:×3|ldZ-%Fv{V;ʓ{/]f^L"MV[񴎸¦,7ӸHCs5߭?}5 ~&=딭b\C+{/_65A՗N^V}dOk6|hCaawe:fG5ͮOVCOrBi -AL `X; B( pc87!ԅPnI{GJYíp BYxEY iQQ#9{>x ) %x4zprz=40<آdBxj9 $P0dC{3"Y0Qx& (YQ8`Aј >DxAjѸN#3Xr%HЪ"HYR{38*Q3›H*F>"XvǚGDvLTuddUǞ)Fb@Zl|x<: xwDlG<TCO Rvu d9q`ApfqE>Ɍ1 K{Y1@MTA,(6GR4 ٦V@Z=̾[2f,R <4ٽكO~`di'=(Dk`)XLF̌L:s$kN1/C2/#&]M|(Ӝ+ X$zG@?u+#pKAQ X:^؊Zfv@{W3=wܳU<  dvT"lL! ;&M!7Zdsze+PE#qMQ =VkMPʦGO%3=n^2. ҷf[Pɖ3?l mD u XU#6R/' !n`$ZıQlZ25VrHkxmTd᰺4t4^VRw`S<.)H<[BFYtX1MTDpykca%8qŐ {i͏ GV((& s&DiG "M1!FXLxHWIOdE'nFq͞T!H}0@!R(͖ѳFij/6H%Df*VeZpJ5,|eĺ!`!>!\#9NU [,0jx"JǼFz0Qၞq`% -w568LxōZV8ʲ1*GZ0C`/@#l)+m\2KT-e`^  pC l6к30"/CiȐxaqW٢K<#TdH"y!Ͳ!hi6R&P#Z]S}ͭI0~=֓-[ť~!vCzGS;ru!+H* Kp,k'$?.!i] oi*"r/:5uޠA'(f[י'&]jÀʨ# wOX%FjЈL(1%ǀ Cr 2 =Z*MJ̥dmuc\<ӐQTAp@Q e얈l=C(,`I8AX F4 @L8ۇpQVXd{< mPt{hbl[-L.hNz.;ט|kyrص")!ڻro^H1yʒcKR]c#tڭzU.^;vOUst3ǵyxrd'}+y왹:ku^܍_] 'myWz+ǜ$1M{CT2\!1)|ӔL:S7ۏd9rFljgekv۔%B9=tf 7vm~ \®w~Jt3,{ \`QB%2b~/-MI$\8Okǚ=5oC72xqÉU[ "޽2yeOM~MQ_)gbWF%aEGCi+Ϝ ^m'gO >UFfu`udOrN\}x { ~ɛR;<9^Oʙ>K|t77|{1UJ!qn}!ONJT :hN,sFuj>oO.  [Y,/nR9{xؽ2-U3Ͱ9f 1ؚ$@(A4F@ ;p j[ğeLܮpCE9[R/TE%88X"l e̩@ 7ʣ8wQ F;uga4~2X(Bҗ-;LMWyF{-?}8Zm@,y{xXbu1O~? {+'dIHSAyӧ>g.zΟ}YQ=#Lt 2/$[[-[`%|lMnZZFsNik}EB[X=42PVXw}ZھŝfI][_Tr2JrV`NXٵh3횺R߶O/5:5({$dRo*J[swshyXYsz+gt}QTO;jWMVM9rQB&rSnl!l{b)a~I]2<2I]܎,ϯ4{=R->?c9/;l\_`yWhԫud=|v'E,[KYսB)MB /J|vN-1y}lgۼ b4~}K/cdօD];aq>Ff’'dNR!>/姦Eji_6>ޢjc`OclϾۭh%>{䏸8;7?^*d,H1?wĔlU_OֱpSn:C<2wYJ#p_KV^;#V>Ź&J:9$6q-kjv @%4I|]/+yߺYǼbŽDh=9k]IDq[e蜩K1T[^[yaV־CU \GS,23{R[ __?\?;tWPe׳vq%@]%~Fv?+K[xܝw) [\|R,$[-,A1Շ_?vօ~W0ȉ'H֞tw2/'Y`r,zLݫ S]ߵj#%/Nחy<}ZFn.oe{f ?{ȷst'G69 4E-lyg[)|}c>٨Ƕ_^.,zcl֒9h~Cޤ?s 'u7ce6M>uslnĜ#Զߺ70zvVfՃXYD}]U+ڽ^%=K>M/{ٟm[E\`[Cԋ+FFXgo{n,RR O=_Ts?y徳>+IDUtgjBdǜYp9T&)8|YNsr%3W,X=cN嬷-o#|g4!7җG]vtzxEk\zG)F`'VyȵS/?ߎZ?u S ? x\V|a.l$;$|[rLSx<oSӸt^֚ee~wڏ vtY%gAܝMJ9~]I{)!z'uE;N~>E[L/H߻/)_aө͛xEm=,pf~HSъҜH\fzW_/?ݘk[+dE!BUן BGvzNʜvsq-_eUz׫-~׃v.=w/U d<WY޹=%G8żu=}ʖy  X ͱPMx랉XR05-l f̩i~|5ogkJMg}Q>U%=5׿ykrʊ\)鞗9vnHW6qF|!0ñwnǖs^N2R~[F[Tdj]tЃ*mzJƖŸrZWʜI5*qhZ' 65D3hZ< YђSIX%IHknh-cz~HҠ+|g]TMukGʩSSчHԟ%PŐU''R NHtL|@Bğ7w?:sq=%{ܢv{ʻzŭuNZ5ݻvϳt[bcɩ 9fg/F2mٜhj&؃SΫ?6ۯmClrCujϖ;In PoY=SN<{c]$5s&={h[eGo:E>_q>,qTfEnq7A>bDt4N7NQZFJa!_⪫7ET[f@Gɣ]vφifk FE :-}d ]0@L9U1Wi/RJL RӓtUi{LՔ, ^y(|x|fkC/{wƌmJ6R+Ъ'D$d?Zle>GHgu3=ƧcwR,mEUl_G=dV+|ۼo͒2f[?D~qleOfrE䓔_=j' $M݌OM9Vu ɝG.-+бZ%%2(9H%ѯQ].׍gg &(K6܌*G.ܽyЛ*jC- \ psa߁4uM--'sքf 8딄}t!dz@G 'ZXjJj_x-kN' w*,'_I#jYϷͮ>UHNXYGZ0v0r`aX!g ljUFrUP9c| JK(QsQ4` C9%hYƛR9g$ %&m3^;Jb{pvc96ɠ ȓ+@æۃ(`sF( %ȓF=l7dFQqVF y8SE G78HzK9P bW^n({$i`"< 7JPUv\yzn͆\4@VCCumz"o0:`S˷ٻlÜ.$6yG\los !) + mM ,WPC*lEOEgWDm*oj}ܵ뒌'tuL7s(]5KlZ}J:f{WPĄ3wcC WkHe~7m^M5q$\ +Nk ٹHmQGsH֥eM}SxbUw%Jd*s)Y*gA\ͦ-V/Σxuەp+mX.xN7x+{6_Yz7RWK^k^)~;aڤ& Ӝ־5iܹ?bADiaֹߔ*^&UG6={x*yϕ_G-α:S2-,|ì-kfk㧊Vޙ ΪmgdKoxz^tOrxΝ{}ϓ%b$?\k?GRcfRWz_Tt [uz^-+nnLFZŷtǮ:S~yYpG(]SdM˪WJ{?e:h[Ev-$3I))iK>۴wեVyM ׺q_ZL޹7Oϲ`D0Zba)5yT5 EE\˅YA\ U!a8%@6(hq+AvZ1}-h/zBZujЬ7HPld-[xƩ< η̸D81p3&yvkOG,[2Xa6k'nI>HV,zSdBzĥ*sE쬕4ֿqeB}XY'^P?nY)l"м*V/ӫ.\ѱ>k}DFn~I R&c=EVWjr~I~)~ܹV^AU߂Y{fܲkʣV>%d݂7Y^9-,|Tg]Kn+$>txw uť#eDV^ݨħƽ=un:-Ӊ5p#5|zغ DPv]2|O6?"F]!m~i'wco~Zգb[OfjOUR\ O~͸~J-{n[!1ܝܬ`2ߠ@7[NZlڷ΍ Q2yŭ.rkMZR4{ٍ3%yh޶5y͚ ![paM?XV8;i3'G޻ɫ0wW>~EppF!;N`>/nwKҊHQZ?mSudg_vUMxc4'>̹99)A;W^Zh)>}.1bI՝ȕr_[u$.&wz9U:zh͊زEɥg>btGl6g{G~! ߹AI[xʅ>Xy(%e S0/}30u Z 10@HiVz28P9Eʽ39 @ǛMT!{ *.>ޞ>N.VAzObnXsG q.hBB`' NS2H3ypWԭ1ypLSc׃PʷѳyEjyb==e:uxឯYIq/t՗q\._wH25 ^XDXiFkiڒqK.v?~ z l+?+/S(g{PjNZݗe]ovۻ=IhA_+\WeaݦVEuu-~j>XayH3GKPONLRBnm5^*PX ?i~3X)'*#i<ո'=ロ ?:~5(ԱHxa@iNn iIi$o@=q^w;ʣs=3\ syϔpu3 -iϳ)OW힚o[μZ} @^xE'XlmB&^]҇^kvo\~u)#G0n\ԔҘ܉oSW;sr$/;R1S2V5ƸB|/-Y7Rk.NK҅$H:^(.Lt ;GQ(utb|q4[ :qI2B b_ȣI_Gd62dcAL AWIջtXk 155-"wjHS u|ppc$8F@-ira : ?x98|B#(Ƿ\HD?4IV ݃j%8:vi`F ]2km|| rvHgg\=*Hp+4æ'2¤N#wֽ: qْZҺXEU}bb 2 ے ꩲg}C2]UCG- y!6aŀ-OdȌ苘Ba^!JaZ|ZGЦQe>cս ƉW_SY92Xc+۔*FB'gH}Qž{0/S ܒ.>0l(2Q=q>WcJSS?zXں@/BOY]*z\ D$wҦ%l.jhZAJ䐸Ls9@Ļ 8DOCg)+p,H,c!l'eH!pTOa>^ĭmw*"2"â~eNFJ$ \8<<}XSEm;'O,_g Y\=!Q$%dH73}•KpBZH Ȳ˵eTWw`wRRrnw8cC#e$GH^z%ab`m]'tVBPGIQf./ł~m5!MqB{D͝XTr?jW(H5751 +lWcD^ 3 7b`L/~;gOptyac8eӔqFjjEDI0,B$FhGdQmur2@HeDsAXx7۾(5"a(ז3~\ )Uy.1a" S 6 ZYk=IWt=Wt4r<- |dfG J})LCg޵rqBm_$#~="EsdJjS"k3u4PDɪ{>{BT3K3mjU ;34%n'!xbfGP|mRpq^g wM 7'L;[ \\#Jʂkhaϕv-NCZ[AװN$۱HY~  x0V*yȹAnV 5Ly)6U.η6;6[x<82qa3*7JYJCUc+X x .sMDV{=L>Z E]c,{Q#tC]5:~ˀk=tא:ra\roqP>jmE%Tu4PAg`f룑wo=_& ӦKଳnqX^ =NE۷Z;Ӷ(i IkD_>h:l&h[:tm{H=ոl]{_Ij*R_r%KJV*jW%h][J@^F^g@h"FZ23G6Kۅ^`ɯ&·cGv⃈n3Q%LX Y>dh܁g y;38)%M\ơ(K-Ϧx_Q{YkٶuކͭB[NiGqȥ% _fJpiTNI Q cKgHG6r&5NG)a|j`G CX/q|]N/EuBL1~ګ`޼6V>]Cڌr{N}Pu˽J /QZW)o~@{ό%K\" UpEl~O:S1cgq!:[,G ?o&B%@Ou=e(swl<5l;X!\'/c0.‚<{'mͲA jgk cIP}l+q 0;QytN19rPug l)GlUD%\3I#b2Z,Q {:e/zW+!T \.7 >\yi=,'\YYc@D VIđ:)<1O^ͳgÅ6 ѿ 1{t~ yt T UAk/7T^ln2#V˨FSCa"۸{m , Ȇ[ַEDzowY_-g^8؍X]ĘaiVr;A+:3Tp2Ūx|EG 4MZi}5{>Sk+P]),aFj0~Ѳg&y+TYR xz?\k@nh4fpj>c}UADo,Zf]sg_YU36B?Zckgf lЛ*U` T~R9+33@c`S~s Y Z7NL3c/&P<]+=`!}g;/@~|2c+63Xl~&@o.wF/vϬLfہ脰_WAdZWT@s;k }ê_AwjҿĪ1f`bJo L,-,i x_5AO)r0^*.וKu?C/@o^uV67ǟbEX&fPs>99}O~0SzA9޷e긁׽!p} 'oG$EO"{N+F}FCnҪ{8lC\fɅ0nh˾ #{rsSV<9!mс+p{I/[ P3gBlkl@v?{fDBDlKeiQЁ#m GUI~/1t!>o uUe<=lɶg=*0¨R^W }}rV#L+\kD(8U`=h&9J박}uRŐH#VUO05Ybs"Y- C+)̈́9hE0/e9ْ(@A {S.?_K 4~'<E$?ZgTJ4啐Jk!v (ka_n`d[# .(BwĚOl/-ȨĦ~ \-/Zdz v;, p ǬI3q- V1Oxts3_!EHx4f8ӡ <OW݇?hnTy^ EZz%#rQg D)$}vv©)1|b 1Wٯ.29B4J%Xa;y.&?'%DkZ~O|g3~q1i̫Ik'.O*?=8yup~ {pN|\MKGA{<<]Yt{QXrQXnvauDO(>z vS.PakNuO7 U=fFvYV֞YHqЧ5ңA/7). Nh j}&4Osq9߳O3|I} ?YUz `d/+7j}xޠ}3D;o@smLׁ=-)Okh1=@blWH~5zre1e` z3_tR~ \o\eL@[,jD{ ?[(tM,|* ӝA$ܤ MSAY3KN"Bp7=V7`[!8fxh'-TTsr{.M Y52i., /[{U#I}KP4k39dөAS-igI(dr&AACW׹iiH-R~0mdج -04sa*$ Y&*:8k frw!EuVm'腴V普5]+ߨhV)D']ǻ}O^IkGYku{sٯ4>e:0aZ`FN,m)X#长qYw,/JG4XJpD}&$g,T$39^8oO ]r3IbO=/yQ|kCs 玄$=UIHרBS Xm(wV 43=܏0f8АU=!I3A8FSa<;JO}5h.#+('phu喯BS N&ڂЇ޿Xbؼ ]<$5G͸', ^X{j)XI}CRυ ϸSU;T ]Ώ`VZ%UT4HJ %-.ςRyn'dynCK;B0=X>+t@`caUţbdBOL/O\zCZyE1JJUp| 7jT-MQH܄sDeUNQ),*ͼl3cPVG+* LVkk)Z6=rH> ϋdo)IqGxc)B߻FA:GEN}Pi gSh1]AC^SE3˚f* ,i=Ix1>=1~.;O#C!Nl;Q0|wq2(kRT>KhH`)-O]-2j*j5p]|OUH72@urIcWDq| (Ա"Sb-; iEG岁</)sۻךQVNٿ21zF@JTۣUQ uD~|̑P$ {l w|i]9 PwISm{ ȬaѬy h^͡DN6r! +YS8%t$EiK "(229?Z?aۣU5v暲=?+HY-{7OZ'j(3eΐ:!!s=nzj)[+*T7/T[dN,Mr"~,-y+ Sa(VUbۮ&F&}S̽mMcs( )UwrBY8@ rt|{ЉV'Ek=Y\-^X)STd*CC0l lj)O[ )/YiDhUIK@U`K°m"\dx$iəh䫞J#j EҮHM4:u#ko1EF^_Aond@~{bq k p`J YMYF@ Y4 @RF O1^#f+ ث0we;6ή7[Op. *ǀb(R2 U?*9aa?~H#} ={g='x v4_N~B|._%_vo PWhـ_?Sy~wd+o|td&Gr䟭?~{Ҍ9į?n,O޿[P+_.F9c&tؖ`Au#`uR<+Wo1"C:5QuWw C&8|s$቗<YӠw\hg*#r36iI(4( Oq" ViェDPL2\sԦopDAߐ?`M`+@&A'족Mγܪ$&XZإ2!͈-Df}~(K⹶|870\<3l,K7W>cMV71EXIR8e\QĊIV>|)!li>MQF eO>nb:Xt#}]2̢5TNY1#&h6Θ Mp3zbB?]%@ ٓE Z >>/n%Po:oӫ>/a}1>ĥؿ!+?L  *k8j+´7c{BxŒ3Kw>"`S_yF@Fё3cR #:f[;}A{b]2V+`»sStw֬>7F}X4?jyY &]͓I'u i ڲ9z4FJj랁Xgܗ}k??G/ťDmXyt1dYټ6<[8닗 ȼ`KA0,7\tTFmhz.≉a<1;sæh3cYM{^Z-3:.Mt_TE.ڸI`ψvY?aO>1_R(\R;{k81C~.g~U+gycp%Ӆߛ$'w5g˓pcs$ĐHgeeyC[azvΈ"[ۧ2 =QaScYN5)wh d>NO?Jtzx vi**Ce=8pMa66}\ lXvT2bi$^L^7+7:gpץam;r!A*XA؁_6O'Ȫys)iT@YY4=) QuGaJ*nz^ZVҖt10I OuG).'Tx>) 0 Q{5>!Ek@G%oI N_US7HZy^՘T5ɴUʋgœ||X]kf5PZ2-x#M݌ƂOVS/E{Lth`mt,Foo1+vQo7bl7 Ww{i-̮.| G{DҗxB2+I $  V^C <Í>/qpMV?oݰ~c60o̽IjzHBƱ(I,{ %:4<[5[ގxЍBs {w@3涔CNALF\ \l&S{tCh"޿Uq|@GhHPY\G+]W'{[m-kPz(dE7 &EIaIv2F6U#m pL='"0/Y7)K~hYp u{({3ʉ|nٺ>ڻ{YDr4H2K[SwF*CJMQ -tM?10!>Xt BmaYDX4te.;Ggc0r8=R}.!t&ȿᄚU틁 f`*`}>g`Hв#userèN L+P;l@+=l@2b Cajhߤd/ ~Io8Z+}DTY =?:63;O"=t˱j3;% v+Oo$?f~w+&[emIX%\KH+ }*QՀ[R:Y9F"v <a`A"ϙhJƥ4y=V-U\cU R1ԟU?KȫQj5DaQrR;8ڢ.8^u*;Ebh.*]HiU)Qj_{&mn3K#Ei*V(~:O Ek\֜d~:FB~~O]*ܫ5#5+/t7eB?Y*DUY=k0@h8S"i + R)Ls;7ܶ-rH^i*S o;=A;y3A3 .(!jq2:2<y;֮6EYW6q{G ԰ށT @BqXciNK:7g#%KI#&DH b+2 "9x:%geD ,`QG F,1yxINlc޸ 4ݏl:9SٟB(r7rNiZc.xp)t"%F+ΘĭF6}k*[$4ybL}|ubÜPPA:J$Q|zJlc0;foqaWd RпcX y%$:'lc֫;4l i~m& K^ W)m]8d/ 6=,fV8]~qv:YexWAggEJ QNR (+6tEm6Э~uEi><Ջ?0^5`3{aI<<>OۘM 3^tZ|,Kǟ邅 /M+*5@mqKh5t2mcPT_?Noo ~t-\*d%n\la'q ;9bߦc}L f:[`N}Er/ H,E'1қRL-;>^&Q5i[ =|.D6_mlxaLD݂6ל O*&4b[ִ{_"C\e0HoG~I!Y/؏anN|l0d=aPT3Y gc.Jx+*!5[ɶ(\jqTҭs0zx 2PkVg]*Mv>Ibŕ(r}Ss ]#'R`eQvc E{T(6'($ gDmxar⮝ \"-9PdCF ؆g#'cynw9kYsBj9%4I?XƘLqlQTo?}4sn@@Z?]sPC7,2}:{~,//!6~ث,zG1SҮQ;.7 e#ɳ]ط҇?%OL-/`._*k*rޯǷQ9mXɣP}1_MPȓRp=N<=ED**_`t;,Y}Ã̸rXFwő[\V %Bc 'LL Q[SD}ÂU[?*\<~a4̱꼫 6%ɭڼ>1d=X]Ko$6ηE(OJq0Ɨ+6sL0MLZUUz(VV+)Iee䢑RTOjMpx(E s-ԉj1H08W#.V,XT7=qr <|kmO.th)<#f^}#V ^*Vq؇œ'ƢFuRVI@ヌ@07BF(CIrS* TpB&5L٢Jzs0˅Ϛ$VʎGG]?^DUCVr,; Nfh{밪{M#tHww7)! HHIIJw xz^]{5לkq1t'_5˲*.eBIFkV!M=8^A@YYMۘ"X_VN/ŒS &ڒO6{|-F FjWf=s3׹F2EObQp(<dTlVyY/򂦏u]7 y5uSC I#jc h: K=2냫EOyz 0o/Uϧ٫hxӘXlRKTw Jt?}J_V_w_qFR23@7A(uWeIl2 ΀f*,? cO Ϳ)U52 -O`!لBK`9aLO*0j0ij. "ܝG=!0 #f/,0TE&F"Y].pth:=<`2`BXo1pk]>/XgzZHB=(L? SDQ855RB^} c\f`N0` ?)$*2%~^TYT%;v6ÿJK!d!_ Ŧ[):#[7Jw]huy\spB<D s$67:3-[U nP d#ieA1Ĵ2 OS5pӱF-p\Q1biҊֳ>hŌVjw9`Ei(?IA=ad̈zLqz9a]u V..I.}@ad9]~+dh!^86=zm>Xc;efݧxU*5 sϭ yHPk26=jKэw [yk,O?z hdVoÅD.ycMWH/OT_Z||+;Iu \wĚ8&A:Cۭ؊M|(Z> `>'vtdKL2em$]jp&lªԪvV,$}Ghؐ?YRrv~P @N nLZpyA%Jm*GSkkSjxID˺)F)3~ dJےO.9E(b΋!S%>K '#B d܊)Cx 괉89,8yhw;ȼbg5y{Eޝ SHiێ$Eʑ{Mw@b{X)|927r,4F w|'wfEbA)// Xl=GM]izǔOߜ\%OAc |wze&ξ엿ߝV6"nK/K)兦8%…f ݬgsO (qp ?cC#:, zo"qgil6_eeJha{  ~;*w:EBu %oyuיbrIZbO hN0O`>=́vc+v]\cse* D|9RsYA5FuA8KntO- c͑ʼnnQ4/DZS<*5ᰖ<=(Ίg6T3N!!Yom@-#fǯ|bXhVH j2j{tvFۙ #MDhϷKysdzv+1 u3:ZR+Txl>^ުՒ+0Ln uލ@#Μ,` ]xɵVvvNᮤ>k~+sM䣏T4";~hgپt| Q[WE7ۓkê Oմ_z\f]gqc j J!gވ]4{G#i[~eZޔ,ĻxW -s`hH DOQHʹ4wwX$Gy Ԓf)IoC;Pp/bpFDcH$O-҅M@з\y4J†H7!8vB^n9)xen:m"d;RĹgWEW+=XS,n~z6޵v^+<Ū P ң_'HkM㍜L#}KhY吅R g>?фvW"%$"2هǐ+/PQ'Nv( '-yJ z"Ǥ({VVt ?rʖW$NIJG /i}#q=~~ExY橰JQ"l;F@ܧGd ֻ"=\"&+wN+8b7j*yc l6(ӉϜYm5"+#xB6+aIb ~˿G9vW<|>v^Ef"=m/J=;WzHLXE>HU7;&5#,gToQ+;3"30 = 'L9r(C{٩qj}ʌ4BM -_QSPY ;Qc%ΙbAh]JҴ`(Zz.m<[;Ow`nz͂ * .j qG.3hPR܄$xTF9Â-&Rs&:Ґ J:Z/7r RnaE eX)}#rG Ӛ!&x#Zl[c}0uݼamgb56g nXS>ݲBu rL?^;*@} g k %$&ܝnRDVp%o %Lf)̢E\[$ f$*gbA^VKgsX4>E) ёE`;[Lhbl8: $[J 3%,u%j2N$~bI[^ £ǃ݌N~9x aXpDVgځ F9XGh[)-m`mQ]6rG@{g^Qa LK_$ST1t͔DAA{C>]CFLV%3lQt%K[l1SB[T&(E~olO}!_“sRɿyE8#2.?ft>뛏ЦC(30=1 ~h| Z‡R{z TO%p6 YQkB]AWgIܖmz?O輑<fuE(\zzϺ'mS;gq* Y$fu[t' Z@=gK]{r`,'U4uވv xFy,99ìICˈ}T7(Θ[nZ ae(?%'pYʗ)3ldhY`?>¿cS\"1[Q VZIyqjʥ3yN7wb4V6cvJbd#K}`*/hq&&m%Zj#SehYQ0GPZcܩܙzKYV3|Ӄ)18lUGKF=s%UH]tRZe>HU$EC֤(,2]}ݫI::62YNZ1:JGYz 0cd{GlH?YelцIz H3&R-xN19x1ɣ(ӥ_W2-.u{z:eefGlh!Ue+%~2 8R1PB0ҽ\N2ECcIsmRvU<̴B.Lr9<dyhuW)s8zi!1(x緮3O0*Wr?})^F+.aW:B1]d#XKf I~}iF'Ȭԟu5Z.dS0Gs7^OJJ;V0.*ek\hQX`w #71,Ajqc]-l[ZB[#\`#@}=+c2 4 >`D_7]q2MRMnpf󒨠N K7S5yxWpˊ,$V^-ZлƄ_wf.Np!>9[!Uw,5^|+)r~8.-if.t;De_Vr =zV[Bzg>GS #}a#q|K|K| 6~>?_6;P- be ,_Z^P?H1Gy)6.dA@jo9Iu@00#5Hٱ70Ӥ?[~L:b`.+PG ^=`ߋBI_G.%TWOƀĂDܖFge1 npܖ} 6ـůWGn(poƯ!u0'p M,<:D(3Bf~7~,<߉<g>g3hvy~1>l*,W]aE\l#2x$B4R2UrD597>ѳѡAAT]!|ejY䓌FXu3<ZMɟLl~lw}zIEi#ԲZB _Un c%krs_4 Ɛu;]-kQ<Vn4op=픳 -+lJR0lF1nXot`@ޱ٧IY[\3p]R)wLuLoS%Vs*iK3&ψ:w"?qwfpt0قEMՋJwxB㡽WkE,k%lg^z oRdIiP|H`SL^\}4|LmĦtSk h(A}5)29.;~4zP4z~̭JQJn0DIjҺlpE~u)Tow:15wygS1v2rTP q/Xd;;V˨b#> P If{OHW^З  6p3vAG8%E`jd:S =b8?By1IyPl!ݤaS|BڡJL?rk$';|v&x9-ݛ"Se2&h;U7[EѨ9`[HNOiO'q,mb =T\:EmCW YANY 1e\ [&G8:,>xAY_n6\p0?w*Ξ*x%n|G?vg? be t[T骈8ެ؆jcv/livgBxGC$qeP:XGo˛mhxҙ\_ت4{|ap {1 W֧ t(0IeX tzLOh YmC%Faág|uxY3h#A"L/kL?CO<CX|PF9V -]ZzmI󛥢wWxTvidmwG4Μ\lJ& _FogcRUP:xS=qh PE,};MgzBLbK'0uػx*ԇ܆Ib5lѯ? ZB<5D6@is iZwTҶQ .?-bdfӮb ?Fbٞs_D\u%aRV!m;&|ӼV(?5G|dgXzk2K1L֑|+IC)/؊W0Ђ+VT/mԦ|L鹰NJZD&=H>c({=LbZN3| u˚Q`QKNb#w4AjMYY$pdC;@? .n\PgE^=Q0L,+WT0Zc0e9m I!ɀuu]fmJ^C7-S&`Qx[L8M4Npŗa|&XFh̲ÇL*']nxle~zᾩkvqwq |; ;X,EڝXOݖ^2yz~Gqɾug ӛR +7s+9/p lVQ4!t,<(Vj)̗0D+BL퐬q >~`*;B`54 Y7D|{;; ᭂrNZb)0B8_* ]q2d8UO<_ՠcI^0gzRG77F3U)h(ʼn"& M7OO׮{y4yD{o=-H,:CHp/ݵg7܌넇lc\ߜ̩ (e [xނ*9zeSw,蛏@>bk̇i۫ʤsgqB$n%8x7 K=6/!|HzJPkIz2՗&,WDhJ8W:"~٭ECU1oPv)G1nj!Ѓ'4FjQ b<ۈ;W(~HD@ tPAYcP wD%Mv6ˊK҃ͤ>ǼVZz;D*]z!#X7RxzJP*+H?/3>P 6V&zDr!g=v}ה#˹2#V?4L1PE)O1)Wiv"͇~fC?4Io=ԻRfVd>+޵Nd.-UgCWI_!N(kYJu +/GxAJC[w QE.H9Chd =)C>h$PÁ ıչ0`9nLR@i8?9qFNh"=}@q.o.YZˁCU7_C|Wҹ)+s`! %K+FRE 8pCqǂPs5+ r}PkrY ~%&- 7$aS{;O4# Γg\_%~Dm{\B;/bsxlJbk.#ddN@AJf @oL7AC}@2Φ t9 `8+vٷgܐ"ه;xg|W6^1x^t7~`q>贉/cߖFWu$m]ptp@<-2=j:AK0체1aNQ.qe앦dWxH Y'mnzOorD ^ށd:(|Mrw[7o*4t4 - -v-%ϯqmi@١ es,@ahlǿ7l7W_Aៜ!\ ,5*wh`_'ޠh?, h~dN-؀uN6/h?jO|3ki@ F cJwWL(?$R;qcWүֿh,\%V.#Вh_LgWү,twc:3AzhXڟ:Y\f`xCegL@M,xx3};+K%E?Tvv\ Ɂ__̿}Yv/5@9vf/Joj?Rgf6P@:j ς2S7[f ގG.73A66GcoNd1V.Љ׺ZQ69, FG:ߖ>e.?QX_$Q[VSӟ 3dr,ьt+~2L8[? $Ov ?]B@K?QsA}ѿ~2B6O}oO|pΧqT&6kfɣ3 ܨ‡q/RjILpJ PG-$">}\wgkVzj[m(GTPG<\crbOG!"Aã)A0tp*'i%!K*7(L-e1B'#YJO[4noCd{:yk\Pa@ToR; {j-44-]dg$UX8+r^mnW/4?"9(6 b/B!r|EޡQ9l*'U6h")٠4=g/SFו<. 36LӨi @N{|W9Khv{TkEiݚKF~u#?AUKY!4:68c'3l47Ҟ[Tb&⸳$XUPW 6<`IV?p|w~vV{8J9&tuq}]fD ~[\iI"Y-(U‰oIBUߺL>7TVq#ƭL7[Oq3G 8zx6^ӂTN7 rH.AHsi~\DILP\O%(;Z4͝=ΛDZ"GB/N?X KU`Cd,0K9N}- ظ8N!| KK#q[g4 ճ4DFe1> rsC0Lix2w ?LEd]W!S#9%ŕ%kZ!QW7jj$!=lY-wCdgڒ-k[΄t0acVXֻyqnW2Fv쉸ly(+ɁܘnjHb*/% g7՝d5 8*eq+-C yx`$㕈7!J}R$:IѫĔEwnjLA 6x-I͕Shdz{s$v.Ūꁄ\ǭ=MeJr_9t[nc2MU'( 1Qx, |:\5<ime[>y11k:.~̥RU/&3Hɢ3LM&a7?҅g jSg.sx݉m-V(C83YYu5ВF*nLF/ap#G+xWJ $ugQC_yur#e98 qH)e"wwx'ĪcR\߳_ɾ^0seSiFhM"("q f |ז̈́S̛͠Ⱥ\ ;AQ%XIJ43OjT%\a[m !@dLCȷLmaF>9htPcDCQdH\SkxgOQʯs #վLjzЍZn͈$ )#B-c"0b&wsxŢ9?Fŭs[;tNo *z_*koMa$;Q%dp+f^QCܜNGK*P,xdN@c gC.q*7D5T&[RbT׬8j*kA&Cmӏ&=CF}a=}vA>8>Sna9~ݠ <]_d@0ZҰ,Awf(AWN4zpحW ꦓ?}V!^7)R /ސO=n@ +>'YI[͇>`4ݣhLrXn7o Kjl TTR gk^z\6["t u4«@VD!P|%(:: dVd}97:O {(B__>a`⒚!lK; yH1^k*dS\sS> ,n 7 ,SF2ېZvWqId1ׇ-C!8\rz.$ Y^8H|vsyzD: [eB(V_;(*g˖OOA8˼twxa[ױoP1W1&VCl!>`< t9^a5zNgHg {pT*PXK4('Y7ztmK|LoZ)~_t!"xtW =쁸G@'U}B q9HGL֪q2gzEXeOW"Qroa).B!{)yr KX7 ]BXlѕ%\T+'G 57E}/+YglPCM!$y:xґ& KFs6 cbNtn#Slwx*)*ឌI R"(/0VlsoimN2 c"x n1~ټ, y|M'p|d:9oYy/9i& ѿ/fwwU<#WF=e2t@6>%}dyd$\^y'EOqB4N%=#1V=$?p?IJ~J-cc/ H23si'=ۿpRҮ?y,+,…4@ho*JO 䁀0в858@ ldO\OI_Ee֋|y3וg7ULGdf\?G_^oxAf 0,*[l%.,̌_ R;_E_&*-6t3 NtLY/x__ֈ5遼+V~G$@&K#1c8ߤqh| PV7 u\Q4M~liwUr|b!埽MGYxo k5*ii'Oi4> TMYwFݲiBUz?Uč,vbl1/C s:XTjʫ,W|s)Xb! Js> #gIoc{L^ {\Pk`qzBiJ!]*_hޔ\eY6.Ȕk"B*܀읁G[K%> ϹN#%2lW \Ltѽ<;M} uIEl;z}YIpK1I??Gjpy{B~ˉSš$%ke$ix8T՟v'Ol 9O`NLǼ{صThڡAk_ eݺyG'p>¥ˌT<9#Gmg=enjڪ[h2'ޡUE_;:+ɠj?#z-F݄@'(ӴaX"g>م 6r*Η󐑳. 7{k"Z8, 6umwف4Λ.mh֐": r(%!d=i|;,rv%jMv0- mbId;Mv.ʌzx{~ dUM!fi<~LxޕvEWռG /a $}FyxtKVyTy$h&h/KIZD*+4SzYYTTsܤ枬YV$7s Bs\%?lVdYp# D1rj'?TZ,VL+,Vxt8)rbL;^aGVDR^Ӂ)>c4v:$}Y\sew툛JJ^:~ϔuUL/SWpPE#*h V"N6u|^<}J\n'!'S :.++BE|~Jz;F`jNXI,lk#/~JZm6C5NqUɗ{9݆L7],]u2*P"n7W{ Ca{11yImx[kAzzΔx驋cq$hC3URk'ִд~6P&J8$b/-q>?Xy_+`RfNS:u15nfe)D["%=O1 drxt4$%hGxEn0XxkO, HȻ']khN8qpLݛRW-bGmQ R *1>UXL"lhu.Խ}3GPAkߤ:rAQ|gh D53 'xV}6lsSZ"GQs8zۋ8\y! 3|ɋx5fľCW=X^uC~cBy@2fq ?%a7 efbӘOG*E]9NMW۲Ր$hj@AA:S[$CiiDBBAB@s?~?3zk1LdrVQk1]2(.ǵ H?AWĉ4NH5+/Fǩ7xafćT,a<˟H~8Rl䇢T\Rdf-u6`GR )[lA"uL%Z!R4սihFjyē5',Er*IH060DMGruaNi 2ģV'TORH9φy϶f3a%Kdgn .U^zr3`{TqZ }7b4HO+[gؔ0*ST{ay^K[dYJ<`MHp!dum.9f: E􄖢@(1zac%O\KK(O[$6Ԋ^ٵ $T3Y]%B`anRS:k{j0|5D7?YK:DHW|!w3;.8iw>Iao%e#DM}=I[cNG~(껳C{*S^B|1#~Wvn8PxvO%Q4B-|E6\,#w@Nz{~I렵Rrg&Mp' ]^;=/)d#<@sMZ՚װ Iلyk>.bTC]Th"CǓ*KK{ڹ3ik36>||>7X-jt:rHZ$:;D$mxB:/=UG=<`l/Ot<5 ةJn$~w`]Ѝ3@c^vĽqzPͿcdؼ =+cwi U8&h+-3(23*(tX͎qha\woh Ek6&{3C[z@\6#^w6S;:[ p;] CH-#w[:`+!L.?hA~ o/,3^7t\;^X/SU" ! q4+R(7+H*lAz69Zu:s:KyaD `ѥ.˛jM& 3;6F;YSMeiwJq#' o%`*l|m|`ѽ K`Kf-sJ-z3[?ɌM &-J=rAo/#3>P-o t|i;*YF`in;J:2% 㢵a5ʹ䃜|]SSEN7.KXmh61&.7ȃ)kPpJr$*ք=3;X` k'ES4٢Rm˥oV}vGsa|e ^A4JϠd6FCr-)F+HԑgZ f2X;v= 6el|Zd`^Ny85SBκcnőRwOOlkW.HmtهX%Ϛ5>G,a""S]Z.Z;)!EP¸O.ܰ,Gl?IiH6Mo! 1r\8tvG- YaaʦͮxXK>- W@R|f[IL;Uvݮfe%{/薿9qOO/g=0QocO:>oطz7?uuHc;Lff`H 5${'.l{> ^7*%)&:Al/Cy.gL>DIF+T.R4>˱]V'MR5XCpGX12e>P\oI{ʾҋu\(O>#0lnx))>Sn x,WFh޺s 9Y+9Oxl^.BJ:9,$ŊRɕj}x0ѥ3BUQdqC9=ǧ(A% uC^J&CveUv +oM>eϐ8O_J9e5p&amx:6 ,!ʩѲVÄp¾~f0 aNj( SAi.ݣu?(,{QQAiZ#6G je@M;9ŨsD\I5ij*dRl>g}rn3>dޚ!"b: 0sj#"ߕ OG~!KΝ*qXd,b4RK,щR f=X#E!oL/#SbcCA}1bUOS Wu>L@oV7Y6U. Qõ7c>ѥH,=rY޹Brs>+0|e\txƯ1mc},I=bZjO4Dz5Hp4Y/ݸl3.wl׎m`HTPeBo_Q}ة pnop<[ed$Ԏ' z^@!"X2_̗m[Try=Y}+dM=1Lc%7ľ"-W_OrO?t 9?TB8zqR_AY/GPFU2Q_Y"72~*єm#\%Eʽ0Ja~Q!kZV.ec(2TJeۤ,vzPJ7&-澧:$|tKGyߓcHO#;paIN(7IY_$Qml844hUc==p|_B7䡎1 9%(Q{#d[Si݈R6ül`5*aO"V`{ <İ̅NV|[;~[8d.vv &kV6ۛq(os.!s$yl1V=(uy 4rìt 䳚}B_Tan{UBcʹӔ7 cNW4{|[kC Fh6? 扆,} ZTMCmDG3y1DA ugF~dTKg42H|&fjBH,yu{dHzMd˖I}:;K7t)!( O*\Ik,(>GG SߨKua.Of$5(h+{_cl@Ęa Uħe$tcP&2mjLjtmIdҗa갦$'ɝn&蹍oRsz\=rs !3Ęr7&bY NDZM?e+aRgB4c‹lt |pY%&iܹ7t>).#Dr@,u; &ʵjF8\ngg $<}xF$Oj,r2 YRM;t9m8ѡ\_NVb+ZnR{萀t|G *(3hU_-#Ax^ޣ5>QԺ1 ݮY4w\pI\FST1>Fn1@!ͪ,o[@"wdAiH'fsesDE*^!Vig᧬֫3c3#pDe ʹ73MVuwq/pWx߿eALȲף7?o4, &TA-A7Uۿ}K| H|D{23ѳ& @2@j- (L3̇ llO8J3 Gv~x  +@ceG0B3ne20Dt+3'x2p3V5!0DV@vQ3yzmh@Hn)< F@XcIOO_i b;?XX!wR, X9隘߼xx+!J,?Llnkko62&kNƖY17o6=#F&@ _Cf@gdW3O}Ý RkYɀkh&!pum?hnA6|?h\78`?n|,ܠ?nna?#dغOk?b-v/=dU&c5]@fU'/ ?8G~y|V,gbp{<m鎔8qcN=wl4Y"iq:e)Zg{Iz PP3%!&#@gql…'D5c&*,io)M aGG MHlOYj~/-J$U=Ο0<1`.[tnq J%kQ 8'ui1ûxdwCbD,~($>Nsvf8.&gdSz;bY9i[ q^JoTJ'tȉ)|ݾfudh溁cCܻ6c +Q.-X^K1d܅9E>i#̼!dwE?gJ=x1sevp1z]m2O+C`n"hy-]8d)zk*S~Ou\Ra|[W|q&Eo1] }DFkAᮯiyaOf~&d]%?[VobEذ-D S Uǻ[O*_Тݓ?:!Zڥl:y6ܢq3@Wk99]QXvsu;xø̊E}+NDqaGUˡW-sGE35Ըk3t":?,YM^!P .J~'/0=QgyW]W b}nc3~_<̰ZLxx -  ˀn>G~~zx-ZjR1dCI!`rFăجD @(A(0Y21)JI&,Mv@&VQ9=gKBC< yCftWhv߸UɬO}Br}{/w.Dʟwr kmꤗm䎳gXw2$JF m{=nӼW][otj8W>V#*yU۾oYL~Ddւa;ES901!]c֫QF.s$Wv<רCi(e$2!ydo%WJbQ(_Z1B *aѧi0G&TǬ!o,n>aMHaSd'.H˄#oRK +v z}fAC0vei͆k 1rtnAh+}{0^2QQ_Ol $_֭} r;y3IBޤESSi3R/ k 13hc< IU -]@A\zY\Fз%1-qʴmUS"OmA##rZX1bu>I> T8&(߲0ѧL s@7};>$ut4V)gL0CLSy^`Չ>nL&2Zt)6@&JBѵہn 48$|ԔM#$+}"q‰r`)Jl!eik#]\w^Uΐ0ү`*,x8hZZnG~,(Fb+)ؚXW1/rKR:/!IȤc2l~D֪ǚ=Wa~ul?x{Hd[9iTĂi]ӑq1v!l]@?l=.m0- ?{8W:q`_hӪ|?Z4)M$*;VT9𳲘2؇Oټ)`Hy2/" vc1:ƍ >ֱxԚ,\3Yea HKj|7bҸEQyڻ8d;OuF)49b $X7]麰9&.}NWKMSmX=1z+s&}0s3g_f΍NN7wG[=c@mp\8X70 3׃,R hPKz-D{v-D{ӟ`F`=qҬ#ܑ6<Px>@nݵ@=i޵w`m_&\D(ؼ_@n^b_[x_ZA7/W}+u9C՛W'OQmny |O͟{&xtZz a bAyEf\1~uy{LecMq# OINy7{DZNO5ygʔ]6W 382Yj#4#)gn_23X{_1ƾB]4%jԅ9b>_Kr/+}{;=Yb[>_~1~U; Σ$jҚ%A!Rە1Qsc2싧 ~%E+2p5J,_߃-HBxQx/-[dq=u$Лb!{jM3.5TN#F}8X<(8W("K{qg'@Tq]=[皪io*3bO'V@ ӱ_8jͯwvhЗ|Šu>At*\v/$Ocki#jTPBRGbeXepL qP0QPg՝315j^.;/Z7`xf|]S$5$ođ MSg("K=@v^AlIWlb+{.sG!t˛6x/#iCƺ`[l1J8bށ@2$0ر)NyCdC_U?j# R KPQ082C}lק`nPl1lMdٰ X7oȌI%֎Âk8M\,ʿ䣰$P N.e((~O CD;mj._ FDDỀdb/}#[`܆h#J;VhR cS;Se" .JI'%\Gzz:P wz{w6Hƹ}AW%pH3 ^820.<;phȎ⟠Xiz$cq7J#eD/eº'k<Aً`pi&+,=܎8up5.,ƢӞ[ctQ>}$ DXk>lm<e`xcˍCvY)f9; FT4] y"^AtxBmo<2Njz 林Ck' )r57‘9;y2 vYzl|@c9} W6ʦ#y:#h釴BV8j}΂OzBH)u!ۚs62јH"760d41@pnGYG29)PustN|O)0*`NAWr(U`Uft"s4|eb1K䪸 1aڱ [5z!6Wu^b{$vqw`iSa$fD^T*lJ}|gB a  Jrbګ.Wy<ث9ɲ5Q) +4^+#fJg" ӑE;czk\;wAAy)Ջ*3@#`se[1ژdm6WQDO ? ˗gqeμL y9 e-y_ ٢Ш`T%z< 7-ʤgͱ4Q/<II щ3P%TbZk=/QBݛ*ʎROVYg, g?/9&Y]E87\$zf ge_lG^'_?2#3Bؿd}gH_.V~-YNZMS=C$IEW=WA`Hsc7cM@7Q̝M]|B pa{fn,?eRXֿPX3sZ̀0G$ěBodad&FF-#^{"ٺ [qȼeFv]n|,7|)ko%WǛvC-Gk ÙWe@ K-.[l0Ў[K{x&}܏}5Y޽y,^DUT{1ӏrn~11 [m 8[;C]s8lj 5JTL&a_'`iϴ|ocWJD%q]5ITLoGKـkO˲v՜!xKPBڞ6m|3 Vszc%Cdob{~ϬcZe#*ֹ2&.Rf㝽} ۯ0i@ӬRb #]WVT$KFJɂ HkYս+~4D(/J=nj#NNSqbWj1T%/Yv/&G0_=6z@5vˌն@S!  \ 6 f!:/S@}E}c6q~ d$V0=e!ҝyhv?9H% tb.ʎF ݛ-)w]? MߎcEaoN$:;R8",~b#yr'! H&yM7ȁijrp[Uv9"z@BCр#4E c 3]]xRH (_'6sh K gcIl s Y1}LȞ#}xǭkR)9B,]i6S9whcEem!Q6sUQ~KY0zpWL3 X̒U:3F'=d Ԑ?ܥ0:5O#KOZ+I?j54bSW{p o-z)ox3cJNOrڀ gpvҦTDMt1LI8h|L{ꓜ{rM>6Xd&%Fh6>~@7we!t+ !57l_庇G/ZBh@F?!s.f^9*g$xf\&m_"neR/Ct!_H{hPb)cs}@?t8l>/ |]! NcuZ=^S>8c0\ᳯ$ӖO<@CNZga"^SG k""#3̬ZӕDS'M]> r$UOWSyv9="]JUClv&D܉YpQc-x.`$Ya ݗ*/cjFnxKbh/<g_:e,gyE G( d:>e4G7F]5jWv3jm~\DAٔRY?|J?yR=:$RΘ0A/^)ef%RkX6qy;yY#ٹŐHHXpӰOLg "(K7V?2oY7w[7?M poߝ}Aߝo5 ox`ڴ!!?.ڬ xyxmrgŒz[ex 0_ H03@!xkl꿍 `xv`Zv3TLlHOڭ6{H۲ 8l, mm,- -  , LlteDf-=`iK}/E֍VVߌw3JL@<ALQi5Pi? 㿕YJGJʣ?lmL~U]]7p=fJNg=[^?f @iɰITT@Y9wDE-lQ:#y7)-ChT!# jf M]mR2&28cjXXfX~WʏHeTJ0AOSBpv UG4I~w| )=AsЕg3ݗ1]MQ|w!Z.a$_3 5(m5vMTĩ nU'~A0l<_f}~05OksAK.Yϋt_;) X0C=zkP>XEܞ %<9?-<JNWZ5pھrI=uw/Tz\i!xj"2Pm\/hxʟ.kM*g`q'iKP%irsV2WY8HYm\8=m8ZV~50E:ִٗAEflBQ`R|YwQI{Dq$T88^pI~Ni"^W)Dl\˯]WkF";|fUTV䟜d9CA£c`:))cL#i  ^D;^=_kNv\޴6q>/TCS9&ߝ1.>*'U$帆Bgl޻0ŬbJ>`|cdVB3eGrI7wp_@fU}A/E=z|\7t”$L Q|u#Ek5m4iLuIćkC'&:j񢰊$"Ѭ- RE;:20"g*5EWW-QT8͙%DV@),_Z)`L*{1Wϐ2}f@U"KPp [Ex ֘"`\a&WZE4Ʉ ȭ?eRFj@^{ (\zZ':URlBK6](]"q-~2geC5˴bzzM+&P+XJҹrc: ]Z:+3F!#WZ+M OqȧTCl+va-"3;WL\DIHJQ9+b |R+;K9 %A"0r彜f[iW%jt#!p.׿4nI+6]ZiDՋ=[=472_A t +9qQJc=0d "jF_+a&c_,E̘k܃}кbϊR"|+^5j9Y \(Vu/ *R#YKaJFRT*[ )ʡ-k#vWqmЃz2P; n..G%4$ã:KV#}oiœDQtuKslcWn W ?[1GB'YOmO~kKAMyQuJGsXijM}'  zhht`+ҢbY ` !wǷM_ݚTct'M>\sکTA2g鎗w ;2p< ȱRZ poxm8ƥ%9}jȖŇ}[SQ܂EWN*9k()?ͭ6N}+Oa4y0dR 66&˃h;| ޻{٭62ө|=/xX ^f >CfE+(☞[ʙ,,Kh&WA BO^ $#8M5J͖B{PyX QUI = 0$Ae~3inyzE-h5JE = +Z91Up 7AMϋP2mI/,^ lKnГ]8pZ19m^VOnlɉa4ZntUsoQ4܇ΡВ9m"uYT["2"ÓX})lK9QNB'礆X#1:>⤬#֐(SU~g-UbK2讀⒉. f_ G(}4tFCDVpA+O͛զUbNsxȡWv aж Ep wCفnzgN$/28jާAz.V"͙Ǹ[n4NtJd~m-^tZb`Ihh;`ٌ(N-6<0y}Ówm98%V{(Lp1"R 6T$;+?[y$,2^sl| $=n?lןd= +RԮ`<7)I5h )EWImM9.~5 @1gK&pLK|50K/#*W4/]1>(RbX)}L YJ+gJ`^ [1s,l d//sWùܛfǾȢ[tn{ pG,#t}mg̑]_i" s)d)2:QfR Qpzd:գ }'cX1G-&}A{G. үrLyRk[MkmߎQӡ,j.Ѕ%sL0*WNAc<_=bL]p S~y&}|x n?"~ ՠ` =έ=_xcLϚ9 E$AzX3mb +,bhlSqίX#4NneFoQY<4EF OA-T sQ20̞Ȼ.Ck8V9}m]VvUee*أs ƜuȒ7ڷ-옡0 2=֏oV%"m~-{#qTPQmFJ|$kl.þawUv䚫x§Wg&gMG{~<9ݍ-F]~gYL7?򲛤7Yd t ?Q߬Yc毜Vsڭ'h~hcū>`^s.:O3IK} P\2M]z,v05 q)N Kl¥#*<4E5Y%q?•̖cʥS` {)n_arpʉW;$㌘M.6Igjھ:.kAN;SSA@RKA;A;:8w:ZzT(YZ'RwyRv4s]U>g)2RaL<2&x):_dǔIX_;)zD.JbPpH$3d6r/%H ZwD|0tyYkqFc`XfFR>7C x(}F镏 Fke^ok*a=<@JYwg-w VU ƀ#+.`:3+O77Sf4u_ iPwG$n*3EM$}iYحQAr) N$δe| R\0F|f"%Olo 8Ht|b2tna|qz:&&b-5٣H iwDg$oԅ`1{!UyBP͉I >:|m|dW?4tռSZ D < ׷L 2Q(V$Ĩl^Ws)=N 7f+ze8eG҂5{j`+S3 [aWh(^}fȦ,"~Nb+ªRb.`ubH:'XhUbp 84JNX_{Ri2_>YJb‘yH>F͔ИD#&=*Yb-wP88lLZEhm1![s1 RJ9E˲Q*d 7[ؼ 9fS̠Y$zż@`-`PΊIE+x5f{Cz˘D K><Xoལk=Mگ_E/t> gU 4~gwIjqC( Φ # .q 3ĆG;3Hjt|'R`_o (߅8!IJOjh% I\B"+x`T#G%6kIQG7]a:*c߇gE*BSv`:}MrTD@U8!asp˻P_ɿ19{x}{W5) ~(hs_%-~E_pLip"4]S= D߬u I~N?T*|E"?~ۧNJK0չ幾,/ c6a P"}Gu)Bsd/|~g#V桖"N,!z;VͰ J6 :v!la" YLVa'*6ӧ3=̃ên(ʹpY`ӓdkGeq/!?`q4X\&noTa}k0%*ԘZaۃFKe!Ǩ"c;7 5L<N%m B%=4+ݽ\kGpxe\! `)Fm}Ve*R7W38{7@R]k3<+x\W&3aY}n6b:&R8T[`=%I@sUtVɂ5vtw=@|>u $r9J$^GEL_!J; :TԌHnAj} T>Pd)4Ң f;CyNt:32gh=P`1C0X(R؇̃ ]Qslu*#&>Va[.tP Pl3,ihܓgӇkV0Wׅ wCҵIFTHs]ꓙ΄p!ˉe#0fv\7ܳ$" ٵN;RI3^ӗQn+y3x儇ևHAdcX[.$ύZ՘GTR{@*a {QsI^q(1S"|bvY "͂ ½R8'_xm+Y"Fċզ gsQ:)HoXZS˨ţmc݇!1QT%|Zq7/KlLky/b5cP=뙩 u֯LDK4HiݲR\5%*zP皙E~~lq)у{|6̽JEcڊ BwLɏ]/UQem1묊?^gN/5e !(wL{8DOi!alRgu,4_뽌J\$~/ɜ 1xnZv)rE5'p3IGX?X_ ?w;7g.[U_!pp6Ep6' AH-/שnۏ?ɠվ4 rw b%BYC!R=ڢCC]3?]ςbw+49#אf(shu*brsr)pXסElD!h]Hf^eAm<,M ~_KgnȻ#D y0qB5_>hٳzoz8Ofl\1{cW!u[d0Ġ34bGЗ\V4Y4(JRPѥe/o@sa7ohJQN93/Y6؞sgO]:o%E]6lFkeo C7[es2/G~X CLsXmBU<;p!aޥjt6Fm N{ǘkocjx5C@b3oq}4z/]!~'O71v3.Wid|Ar?3{XJ%?3roivR&#Vkk*= 4RdǠ 43y[3Ԫ71l2!90^lh@~–V(z>Q^6M"v6V|%H ~v ?jeLce{8{sT\DNj5K;AF4;}| 85!.}NpLoϱ-{™ވkV&Ǭ#l{r+Yyj 'IJ/'ₗ ں""y";jKs˞>~\j"Ÿ(1}\v Re88m *\e KGߎ#AqN*Ņ94"v$9XjfX+NtC(&pf {r! # -Jz4N[u>OLG?ߩG̋}, -/nd7P{Qp-3)*}lw*Fb 探`dcR;pqIޕ k!5>>A@Tb.ia` K9̲i`$*q cIN1lt$,,(97s[>X?73-TF$KKNd[,  x9 $oŨWW)ַq*u3Tgesi6aPos/ZDݽ63Rp 3!b&Q/<%F?? 1ALaj=KaD0 mRܜI=ԧ/~O{u{dȾ7=6eA M׵2K<= oISkKa9D!DNk V1}8vW_32AwO\_L?7T&FV83D)`Ssac,,ttgo*|_c|+j0P 0HoƲ@σYfz=V̟s$Os,8"us 13LD:V ѰP8>z*x$@kr/Fm"`1:Z3A#$JNSOZ6Ek=S<8c>`VOZ| ˼& dxc䳇G|x8U$ldg.x5t˾v9*2,VsQ .qSyKeCD03|KDij/뱛 Ŏr:mɈUigF^YU|B~ii<&&kS_Sɫ x%Hrމ|OL8Cqwc/ qU+f1hBt6.mO|A 6;&WJԔa}АG@̸XN``6sidFlɈbi<:A1+:,mK jElGOͤ-MoU wܤ:N3 &܌*ޔ `ʊ 3VtR/t ݇˻KV )YN(?K;A)FG="̔b6jMXnl%tSJ'h1;<.i9d[@AYVl@uYk t ^8 `@ p8,nAyv~X3+d-m#\(O?4 vƔ_u2^G˝G"s ?xudl+EBYPxXt%^u04v+!2xVao~/=Ql=>%Urk0rh'^s)9d7f;Z(حlLy1C54b'w`^',nJ{dz .AT=O' /' 2y\OǟJ9ņ@) &ֱx: #Y}YUnACMD*Xp\Y'N͹"Tm;r#QJ믘(OܨY7?>ȹ7Nݖ٥J6a?7JjS1d|LSN}Gnd)iUu7sm[K e`R'2KC,ijKmP JA,lRf -4g>86ήF> ̏'OLǣCMU~Etg3iP[txf _fę> B XrdMs5k~eU}WCp=q@=ߑ(f|g^`*rxx v(W Zc$/DNQ B5\7d?!R*.eX\Yir"v>=ȩO SR!׈:2fr/H㈋pe@ )$W}QDڈaO[Gl^ {TߢKtH,;eo!0ȤUb߻uzPgBKSjO6*xIM:ML%]`9NȘ>1- D.%1%ݷ{2@Bl׭~?|G _?﨨$3[5.< KhIb2Gl@T;66- ό!wFKnn;X9VXuI2+b y<9JKdQ!ZPo3m9_[ ?a`=\tPXv 6Ȗ'UVg5v2@>}k'pEcr2E %*a:dzf0wbMԤ :^ [aIɮzȢpJqH6@(l6gce%7d)?3%Cz I6Z wY۳GH.# (2*,|'Ižb0&;C@g,}!t篍* |1=/@2_z0[_yNā 0;388Y1p;oqGvM]7ف?<ߨ,'wFd5/ ݾaqBYo `9mtỉcjx6 lPv3j՞"ē7sH2ˍT+6&GBnÇ/Rܗ2 uE&#m[*g;9tWF#Z;W?I L@ "=zUCX˔(JZ#7p=t䪖'|ieIesJa06OJǣJ)P; ƾ>aҢB{uxNI+b&T/9?gWPYXPPO2θ+lEAcPo>4SFYיk&,8kZx usOF$S̮&@Ҋ&ONusFs9ѦԵ*gl,_{^\8x?<|z߹Fiೖh'G1COQbb<(l&tRJD6훔aPe'bUZڐt@D'IJlD_쑇E\b+nB7Z?X9IC%A9!z##{ҥ sx p?JFܾN5-YV3JVw`$~rfو)Ö|p+*{~)oHڃMLg?^)8c!KF\v T%m:7X=av kXkUH Bgگ a:?Jx 1rfy]{K}5eYq0 !jXg2uaV|?vەW* ʊBpqX-6З[\mBFqo)뢀ۧ,'cb:mRV@!^!B bys`y;&g $I $EJ OѲ1oŰi.KBl?UW>#I(uÍgLq ?څ~YBϣGA$H, 1J B1]'PRM5l3ffOe8ܑ^ѪFT#Jo~V`.\+:qro˕}vij3'u|`8 ʤkㆂ*|>/Y}z+buIk@cXϟ妞4{$DtiiXTrG%+\ m[l;f?6*>5+Jiv WE5liH cwˤZzXX^,Ka2P,(xƨ]y}iUi+Uʜ!B#mf|(p<:#Q!j0^&bc ofK+zzH-(%릹'NognjcP[WGODÐ m9MmgaN$h"]]y\Yg6]f-yH`3+WoI>yV'?i`ɷ}$?2;f=Pi~ehy4HJd6rYa%*Ra47DJŸz#"x8YH:M!":B5u DN`+pq\oʕt-ƪ>?%+9`ۂ}|}"{pc<{l< -: nB>L7Z?WȚ8#8]v"] "jLxB@DެB}94WNrlU)xJ;#qLpj[#.. Y`12n: _h^Jޖ>v["GB-A䜟1_) #;?ʙӦ>&?mUVrz1;{`)O Y p (^d~B~)ڸoGccSK$"LIftp Z5X(Xe}#LU^G 8}L&O5a2K?8ῆd#p^7a]q!cÛ MIn_PI#_x%=+΂=p>upr6/֮{;>!A_q=ھi gAXQ\Զvb3923;o mbQwh'x+FI%A[1s *KEʖwX @O;MWNxCOѕ53/v\yk9JAnh1!˨v0p4k E>vb&({ VvM= g:uc%*50,͇#G@4Ld}`7ϟ9m'a5Ƭ`ʴ HQB}}6ϴrpÏ4)T\yn^1i@:龽hr(%s#V%YEPrBS_}-gHkv"P(G@RO=4S8ĦfƋwe.Nxt<|&70B,M`4E/i<ٍ0&y}5yX!=egT]mT]@e >cr%o$P6^;p%;y JLdE|P->3h ŏg=( Ԑ8 䭤Iv =PxllPj{|dL|4#"i!^*_>L1^z܀z I= v S9_h. -݁EK<Y6aNLΎf`Ve?ōṮIMYerXʼ>-T"{; } _G;}:@:&,)AБ10͙vx!/E$%&0~_ijw~#f>z֗yPVSfm\&> Иd\$89 4!瑔Ij9Q[=^"d w d9CO6c@X 1{!|!\fE_}*Ӊ.6jZa}0$:/Sde%M/p6{: pe2' &I#)MwʦrԷ>RqyryMoUPsĈ&:5.bY1S^U>Ri L La>Y,VPuVkKv݄q4,>KGuɢz_ {5)_e2" ^o}2ZEcWE%&JrP EE9#BdLJŬBy%hB7Y]v:&е5ah;A%'b51y1h rRHsڄV-.}q6Zd%HIڰ2!toӕWHH dؙ + _X6\IN 9dQKkŏ`<(ld{WRk+&l6{|H$vvl{۰}{~ҳ0e:-TaK=PЇ m+7 AT{ [ jiRbyA)߸ 2jRAe½/\HJ)L92_Ǒz'˴ܶNV5ԉxRkl=3E{A7"MUSˁ'vG+QVBQuR`~a>~avZuG0LSL+B_r}_NL.)):owVFiզ=0M㮒{B="YMMnZN[R,?t7:_OmU|yE@7) 5}(;C+ Hk֡}!vV2kwnAWVE93 "&Ϛ&ƈI>0/VdV};)C'넺D@?aagm蕬_|P{Y[rQ&V nl{ 3~i1:*u}q"19پoxz*5ig,I:]tH+X v|""IqRC`R d 8]<~*`}zlVXr,Ʃʨ'PW]1x%]W+HVރ^y '*u7d]{gHmqIIRy4X.@؄YM XzMqKM,1qV<7ٳGr rot7G5h^SO_.EjL++:о`4[6VŽdX=q_Eĕ$':W{+Ey4l#Fɱ}-zpnCOqw 9X-I i>t"/ݘ@O-;vE_GѼ*nۥ!*)x䠡XwFP)_e(lqP۫,iL.x&-o:};`g518-J-D 9Fr;:A}I=f,dX)6 ޲l !韴ȇ'?\}I49IM MlVVzQMa}PY~ך% ֈC c +vLfTCy8Xy7c:kV_P3KMX>ryIi*w@ˣdqA@(9HIZ,?EA7Jņ 7t.=q z$iC-3bHPUa!2T, .B |fN :8%E*rUJ#Jٻ7hԛ4Nn$mSODYB^ >7HMBEą8a|3%f;w*'BAqzjiF/ڴsuKXoCgToף<~EH?]|aE<#݈<\T} <H_?c:ov*??~N2 ?!tDH2r@-2Vѿ:#r*]Q}}}{c]k++cawFG57tcp,C6vƷ^SX׿ݒd / `)svD"v@ huy0JZ"hdbW$UͭL錟9?:.[JZJ@nnS@S@JBDS:{l1s{e#susk [cJI'yY J ׆R=|{!{v "{S@ ӏ++>ZO󟋿X~W 2?p6w-0Sst+\hyzW;WL!p0K;ߘ:C[e)!bdv1g.$QbTp;+B#{e/jm9s\okߛKJ,Yr~гH/VD'8/#+hc>X.6c4.LLrMoĬ-OjnVǼu%ep˱v Hu^08I^LéN$G p&ؑӹ:6q(>*m-7µLE"Ս{2WhFYKm=\K1:חsOī|+(HH7GM6YE1Y> ƒAٺӓȣ)QM%*Sq"hGflwޥ|4նS&< !+0^\ERR¥(p.3 w䌳u)^5*D-QyrMXգ:FׅIF\}o A"WX$8Љȩ"Ee?6Ohv$۸Z[ 97ϔSy-\+l*CFJ5O|y~)1?~oӋ4 897kMU5\KjYX >al5}n&}] HSy EǰPoWJ>"9KgZ\x>jhkN-&ǹvr %u-!XjҾWLڴ%E*-4q(r{>c=iAЊe&'*1'p?1;Oz2RbԸXFp K܂}լ6al+Wh:~uGp__{]eKI_]X$Sͨ{}XVh}'G%pO]^+kB+Yu~&oShb XP sX:<'< L/)!I{!q.nJ ZUs%ti\%&Sc@ jl"^ҙh$ h۬kv{)W+#Z[Ϥ/?(˟ß`v⪬:5ԇ}/gsVt62\ >Vhbpckj W!06UN6He#S{=!%i3FxN>QȫdVo4N %pl4F_.xrxȈp4lcc>9_dX$\NVr*֪ʆ5G޸( 7[ܱO꼿IJ@/,&ެװpʛy"kMݕ7eNJLeowO.*Ξ5 ,t#|~U埝W)]33?Ck)\FWJtaw2[38f*^*ubKs)gl}HeUuL洍\uʸOqFV* FSJ&ÃvYoJٔt9υ)ڕ)ݬ-W/ٗhU ڤϞlM, 3D.辶Yh.>0HsxlsYeUD5rVVrq+b8Mr -t:X/N:zub(ԧװh8(Cö=4d]j+lꉞ$Pypz$95yak>$zpP.9&eM]V[;khsf]{O.N<,,yTe5ݨP5ݹpG3(93rD|!?>t6?HI)~~f~tfD55SPL(^sh~AFCT3[FbɎ/EJ^m'fic"EWA~|YzCZ{fF%H -@ !jpX`r?J# FI0c2TȽd F.a_DFz Je׆]0iهFPKKEXW\.dz Z%&2ݞnA=Z,d#pͥ jyrA&")ĮGI N$`[eZ|u_4>:e*5Cw0BRˡ*ZX(6l.9ف獻c"?0{ IEӓ#m;sȋ} %@ZCwuZ A>.>’n*z/s f Rѫ׼ ]F 22PҙZzS GGjJ JǹZOǰYϓ S} ^3yfɩ؝q^p*Ald{2oK̵! P>Oh\LZ3hLJ1mǟ'e/+©s9*Baŏș§0A0A=ߠCZ B8,Iy duG8g~8ZY., c%LHʉ7/k]o2<}7<5!E*n9.ϊFɔ/+^ <5bj"gX6J(td-E2D*^aVnk{H%$M*5?_@^ WzLQyW?I"'d;~;r20;"cd*gPU< G%%QK5k¶fxZVU(ϣTuHq".m#iCE.jK`5zKjLRze}hxfie-|1 G9$zeCH?ӌ~,8}QO)*S9]yL!Pzlj^JMhǜTgfUhE, z:(]~Bn2Qa"9zE"jr848VS&/n+ Hdx#ܼ{5`\ ̗`xév66O)4hx)5'"nB4wK 3֭Y*41`Ƀ>ܙ|9WbgX gԟ Uk1Q +N|!d ږպIhIPNX-\^֔X$VE/qRn 2FX] TvҨ Iyt]чoyW#L*j+ p <ߪ* DP2PS9(*`м>=_R„򧒠yKA{Tna>/QkĞ"pꫧpkuN}GӘtLw<1_Ywa՝8]*fd5'|$?oE `5s#O_;1cbcG@L. "`|{K'"'}j`IH+DH'7_l$.|}?vkyZd\ t36m3x?/#~vt2,Aww$`8.}D|q7,@ gKIڥHqƀ0D@815\W02mZu-w"-" 9k@d{BT,Qء<A+Zrq8,N,9gUepi=?\{kj% $817'Otb2fz" ݫ7NP~s(g)= ȼ$Baљy:nN=ʼnN~Z*=Y]M۠f;TX[nBq.)q>iX),̌lޒɾPQaDs7*{-gT8/+#=V*Sr {@c { tXNbE24U=tNT1T}SzEa mEqV1 EHH@潾Bŧ܉]+]mv,A\9!bG-#{#Rxau{CJIkhlD2^dKxlI5o6fcFȨI6kz0t JF7"zl)dEU# *RKn\$io፬cȸЃrZ(%%cX2/>vy(6u(8YVԲ;&5g A_S^`}-^wLd [t 4{% [%a.f tqXr@%Fo{Q0FF?b Qg@#C҄ Ôƀy4~CwN fo̹݋b1x'0Z8ZuXS9',*s:Ξg1n5LْĎS` y #hl;B:atDƭH}Co,uےҫYn\pA±vޙmAI>nD =׫xf1rr^H2%`m29'٠^i(,ͥ6q2fF5Sf8=xQN~3 `PW#>?@ŕ/n?^ wLT~s ɫTx6iQSZdߔ\oQzUh\Jr.D }b=7lN 3/ޛ}Uˈ ] Y"Ja&cu!qFeBm$&<2_QçS}hdSk}x\{G✚I F<+n E^(NlLpuH`=-ᒦD*'5%nEG"N.)=9ANeU!D!''>/Yp[ UvP0$\|<\HBD=Sdj(">RzjJukm뛥#vJhʊ8Tj=ϛ&J92(|D ,2w+[H4t87!9D鄉| i()XJ[|P BA.ᴠE}sh:un,{О 癹^ݤ LTDQr‡EUI -6챽g)q)3,og~#Wם9HWD+!`D*n;\`QFPf;qȿ ?N_/[_n>Lh­'?X832Ŀv@z[;0`W_a%3@J?o6oq%`y'g?qLdVz 30L8JS`YyE?R̷,73-N:-F;G;in=@<Mx$6=s4ƭ9r

lW,7֥C_ dcOՕ91*KϠgC}gETy~T_܎|A6⋭Z$ױto.Ҫkqò.iǰ%NJ+ldfRU qy[)ϔ3l !%>rz2jִ7i8t}%'Rn GF Z2&f RL-KI.  Kt7p3Zc x+u6d.g,Pa7x< ' #JE~^WeO1֪h8ӻ]u C9w&;{߈ !0:/SSo*DyGU!c!+t_ʶ)YYoՙN[חM6ODQZR>L. I񢿦SJ}c#mp[yґ{p:d5Ȉ$ˈ{rBkHh3M@>LBXB>;Uge+Mk ܻDYYny@H_}^K\JrӬ&pi̾}3]6m̏*顣ہ@E3{ %2w/n$\"U\tpckG1Ҭ3 _?46#' N5y`HeeigQ,VT4/v2.TW/WT&; jqRaZ<k/z]xm&> /xJ/#p K."zC9Z< >,$aQ2; ?hY NrUx2O]uHj/ vM;z/K4\ D\3VMXp)!!!zjP^1iq2FP:gX_: 5 {/p2u\ccw|u/ Kj/nI0/ bg_w rkq˿3MGGӅ[ %M}Ko۩om4&߾6Է33xü!2|? tܾ]c3jՈ 䗋ߚv0gq'w/5/P@B \w G? {r!+o8`2?@'QS:Y-4+y>E%dS8U_\yUyL48h]RցoBjbdG@_R_RXM4mƍ.?BhC狹Q28׆Ksa t.Q0{Ej62k{K 0W6TUUX/,f4G=lsIZhj{Jsv:NPI&<&8ը+t5ޖe 8 (=vwK?^5:STy69#H<RN<{t%"| se"Oq)Q+U3gFCIQqUu<7H#}zzDkWe [읝JN$HyN|uל~|W8V3Yձe }}]˽znVPK=")|+W +]zه $9V[ 5}I!CBFz!9*#l+"H'jATR &G/hڶ^yㄐ| k ̸l#fF=F _Lk(`͛4mM%0 %?SHґ NrLJ 2pˠܙ-:̻z8-PYQz%5د4;Ciy'X 2¶W([ɡ5]JkhuɉA<|D!#" .]?(* ͫXh tvBٱk#a;3MUK;%^|ɚQH2ICn*MȅA~CF'(T:9y-#7F}ԍYu0MS2zȥZKc`*eȑ2p&bW%TaDd3|-"z;Vݵۦk(v|"{Aʺ|_ٷ#Q2g+>%.3!S`s}r^ZWx/d \G&9FGr>ȵ KM~9XT!SPpDRq]&ib'F[H7F?W33+V\cLtݑ!F?PRU:JQ'?/pT873aBaE3=gky'N:y}ZjBh+! iK|n+og3[g8ź?ª{wz3?,T[?!m,MfϤ`ޡ'alC A3f /Z3ԮV;A%yIy1Zu54*f2Nf*yFe5E`wMW\FuI&*;rn*`Cń7*2sk ŷ ݛJU@BRlSeCtp8hx=&[닰AgL;Ŵ 5M9뭭!)C=2*1cF|'CIQ_Gpi\!M4 XmN, 5U IT 8Q)8$+_|:v;N7 *5a@m0;N?,?Ow%LN]1`Hf6 #Ȱ ͝}5bfnMXX} 뀛3Jc 迈b;cnkh/]b?q.'Mo <\ߴ0w?&ozF'ٗ3埀įWL9`r#~`DxY}->} ;E o;ߟ"?f?蘒u\ʛ?MQ<#:"+N3-QoՓED%i$nNvtSO Kw@GG/L7 cD$BHIV/ )% )?u:\ƒ 9"M'Ӳdg_nVNg;Āl⃍.;uԓ:v(%kG$tPfm /\MaO/y׻T?ⅅͮˊ݉_ Vz7PS, yb͛M΍஍{sC+]:BLԢ+X -̣):Pl|ܕ57MA^c? (CBy5 {ҟ}לEfBAѕׅna DXh`ńY$ࣅmq| 㙧!ZZ/ȳ ZdW(o>Y։| F U׸&Dqي3#=C=8QjZ8F_!q4tGslM+(WB2A#̘/ n#?5duLoHs[IbuѪC&t5A٘@{ˮ,+st6ѾI3=&(-޲-&I.|2R~q$"lWEjupMR/蘛PݴNz„OA\܃]UDDŀ\ܗq}=P D vJ&fQ0 ;rC9Ms$LN?7{d>'Ǔ #v K 轑G>(AA-ZQZLzJWKlCbPۇ(@1L'0z%%D[$^̅}qec, ^ hE*CЃBFvho L>SqdoæN@bx(U,TT}`J-nSټbF~/ c% .U!eP$0/mRL-soB >2IpEfR\MvaQ|I~(RGHXSy/΂ pr ӌa<ϑ*XPCt m"Ҩu#.M?0p;bXen('K 9 o N Sڽߜ|~81ڶwޞ--[chuf3ރ8 =7dfIjVtO󁯻o hYFa6 Ό20Gsv~]X#{+eHpeO8_2~U ?'w巺Ċooߕ37= mX?Uߒ_o{};>N.7F(|U6\dANz\ebl .\ZF΀).:> #>^ k{~/x032K3SHxƟ;*> >H=&G2T]zQ#Kܤb#|,~(kenM 5j(rw0Jbtm=h&\l%vuؿGɘ4.6uKo{̢ThmX̂?VVOIJNJ {%"u/#_8?Z!>6:srĉ O$tl+ f|dNpRаTsgfJkq38PCؑ. WkO$az8>/}TRIݨWƓv޳<J&PF$Gz;DU lm< ??x8XO~3Y|/I*l}͗t0Y< P 1AKr#ڣq9$3eA]lL;쨬WPfk>%( R+֮F¼Sq2tv7=B BB\Ho^O!ֻw, ,1K,k?p.geՎ?We/ ލrOWPu}w.IOkh=B4i¥>#3*N3h@7P P3yS\Z ]ФB1#hf Ү+ViL+7`ﭳAiD5،=cwz(@P}fQMi iL64h#_c7/6!-!B5),W[nue/-ik;~MËf 5}핿mS9,4ION,մz("(X*e/h<8ڪQKm!Z@N=(d?ԋL2+~&i8;q0lQͬ}̓7Kv=/Oz!2i۽8׷gJx#;|gW%fzj ǍV G>X$Cy)Mr:!֢uf矍f=:zpyu08(_'OiCD '`jXAQEU,VP.!H,f~']lU$x՗Rw3{iZRZx.mrh@h;fCj.#p#%J)̈#8L(KF@扐Mv0%QW 9!({e'q+si>2aM&^>)j\1OP_$%|V]!9~=wEJ)dŹ揽q}qUmktH7Hw(%J7HwwtwwwttI7yw}k1לw9xyV-uǍ2o vF0 ab̴œ׋u*+հ0ZGZ.l{4sb/s˦=5)V8kSo@PΫ1xutퟵs0 Vרlu,R{?訥KBQ*:;TC~IЋuJКX٨I eqa?,!HR? <= oByfx]idu?aP̋7̈́YMa@eE>DzHfI[f_S8OomN5QmQ9k_~GtQ2SF tz'<}1*` ESmN_E*p?'8a(GM#4;M=|FFE,q 5rMfU>%wVޗKT}}[\E YAe/IO e͚e!o7J5x8EoRɓy~%eTlS:'bf(SAtOK\\w/NUvۖ{@~12S{3u<=ARQk_/b coaOA<{ձ! }18.p~xg&IW% 6M_iVwQՍ 3 };_Gk<\)Jk_ D!T?/|ɪj -uQ>A񴍚 q͉K9g|e &\CR=r].+%P\(JK:j6m(4hÜUc1HBxv#2xGaD,=2;Kiԁ$ŏ$L[ 7k-ڱaJhDE4z )ò3d[f2oB2F#ܹe'#vB *GQQo{w/l-lSE΅ {ʷ{>{+ھK_q<{U_,hX0i=İKޓl _ 3OBj 4T_@޺ڦ nO~rO.--~2`4v{c Yu~=Mo -?y%||$G1GUD Y5{^OO(1cA;$0;7ceY30ClyE16[e{TAl2[,dn$|ͼ)#Z鍤WJ0'(oO DH^UVg[)ٔ~}>dS,-[t}b6:+ܹCR',}7ς=KҩKyFթCga_ɓSu4eg@߼ʖ|1|h Txk4CP}:lN,ELc%QuBsmȹˊAYÀ(/8# L &j% 5Cq#p+E} $&C3 Fr;iO* &1iY |Ѯgٌ< DdžL+p:G؄SJm/b'Uvz!… , ?IkX(4l=l}77{hнR?JYw zM4WTf1!Mb2QҲwe !;()<g K@I,*ם0y) C΢m%L2T 1%yԇ$>̩}8ޚ> {;8>hJח( EJ"i,1E '}ܸ H{XfeUOMV`{I`147 \[m/>HdXXÈӖk|#+;]ÍrqPvU!,ӥ'lFB;7rpP9OxpC ͣ7w |zll|sV?&XNyO)OHqMY-M' Jb+b!֔xmfi{32ؼ9סt[p!}ugqdEL7G|?qI矴p j&XMapײ@v :?;W~Z2{oW)˿ ?I1߿k?^&>_8R@ ~5&ƁvX@LoXlfF"^"*֣&JOHpq<]jf1OզEX-F\,XS<8wŐFB^kGzRAE)RS?+Ɗ4 Db:}DK6t2u[QRK[r*^wRgm]P]\OQ<#@n +{*RVC4լ[N4GMKTKYG%xhKyחAh4y:=g"qbsc{nxZj/00 j?jJT8QB`ʦ9ܓYYESN/ҋ~qj;`ݚN27ؘ~}2'~è7s].0ReK.$Jr PjyS>zdUaG?ҵsY1?'|K0 f'˔ϋF9Ky06c:uшTR | 퀈~ o76 ϕgyƵ;BQf~y3/~S?K0]yO j'*vW.WOf>Ϲ˰՝(T*WW{k>;4yKw1"Y 0d)QQWAR|RL}0/#)#~D\&MG %DHά*S]L?C+;]4A /@JmGcQ^@ K3 g/aR11܋ƝRSCv8P!{Ǫ B݌̍$oɎ ` ?y뒛\C' 3yϺp^_2hMqkɱfB*59ne]<4\H[B:`%,vljUxNFOn@U%;`d]+P4^[(*+׾xkKl~t[CIz;ڢǺ e GQ' IgP/вN@56TTgk\R'L,EK9 ƜL_ȟ0"y_{S9돚&p}I~|ϕu>H'6zzۍ;Z!-3N=W OUM&¼\-ϔ6|DU݊aަMޘ%;oTT_EOXٜ .-"Sl:efPlweeZo]\w ]qsI6^旅#4wkB{~6V~ʠ|݊VԏvҿSyr?R@[ku?ԽbY1mZĢdv ~, 7k5CcHPXjz)Ts|0"^A'Pz C,C'uQov=Lfu33JK!M$ 4k7l[ 2숍u_@k0(PT.}:q(l݀q2Рb@Bg9= (՜.Z/^%"$`"ydN/RfCIE`f|(&\2#yѡܡJh9HE1{qGLBO5cyز.t1$*ӠƐzcБs`x| ,ӋYp!ry(bF#w]vJtզO7/1ԵZ198*mo2(Oh_lR 彎~/salRCjт\+G& wy2I7ߑG Ka߻1>ÐG՟9_ |d<}>q@H1;n=Zb.‚.|ΛpT~\f+!jJ2r'6yu PSvGIl2T_XI* -:JMuLuCjOq֕'} q*`V LRF/b'( 1DXJ+3¨W1/N2au,uwL92aLr7;[NEC )lhHyTOj1љ,}gPOfB2#LyK ͻ8w6wpB, 迶FM|jn(_ؓuAq fDՕung%e;M:Gwĩ +(4xbd Vm)J; a-IkoT}~%%YP)X7].J!2waI}C'$LͥRE!ڛOWRy{|+hYM^ %s)X!*p~D߈ynCoHek|?ymõHWT`A܎l?*j*L{Iĕ\ۮ`͎x.DI93'yY=}5:wzAIG;b>Iz a)o؏uVI}[~gd_~VD߼_'f9 @U_pUs;^/}?(M1{@ /ENRB2^s3ˬЏH\6#}rDʲdhC vDfU> تE೪Xڦ8,i'd#gI8V}f!d,<}hGTa'ƶ^10A2W/\ugzQfwd8+U:/+}qՑX̒{I|Huf97[B-puwJKe]T&exX'Ԍ̮_h<ڋ7 C_E-YҿOCb~x#C]V]WY4|8Y2,E(x/[<{STt0RM]1xts 8_ry"7wXʃgם^YctqMѱ`.R@ >47, $.foڗwj1aU|45֟df)C&9 Pzyv>څs(vW7pǡlZ:g[^.,Xw C ze g"Y;&X[ bP+΋~:f'G::v4lG[sJL8] a򊄆RɕulWث^ R_ a<&؎zEGkn!.{ 7}ڼg㠹q:? jr h@+4SCz)6wJ *̥y01 &/fc-d ?Fҵl WVF]@ MAS[H``R??8j Mɼ0-{svܽ^&!@YFKXJ #Hfdxd0}=`#u]'qҡxbٓnGjNSc ?CR٘ٚI&NS5CNL/^) ГFǼI/Z8`ٴOe_q\d0ZQ? &O^?3!NzX#{2GPG".TQ4Mc&2{|EM`Is1Y;:o>.Z=P BN(3CON 9M{wSÎM !l)04h|`E$TSu,ˍ!0v E%$1Nso޼KsCԁn[9NYڴeVP !x4Bǂ * n:w Ӽ[oܠw*?o21$?, ;n> cPh4SH1al·LVoo*Js>Ӂau/-$I~= ϟyh6YDAܟpk /"JFOQz ?EGJX_t|#ݐ'äQց.*e]a(=sa} Y8)TbEؓ [Z2ItN(4mUOU|" u-8L|2.}"xGV˓* INFM%/ˏ,(OdmRAxR^#|R3T:4kRue4Q+Ce,l\xs!<.}Q PJOҗr;4dǖ C$5Ӄ10AU6 ix6+C7Gna>z,Vy)A[IA(} y.&c|-!eH%3q3hAi])qdp : wq+Xgac@eض$cK t.fR" _~ *P1hgP~ph!{DY<$`چ(򡈵^>WT[ފ+oy/)j=mUԽ'i.>vcjykruzUˊhSCCXR].lw[E%?Gn~)}fW0 0?TCA@K c!C]9~Oiu'Dޔ»O[7`rX/5sw YK_=(Huk, RlKvq a~;lu`)fuF# ][t 9cLGb T9Х92b`#FaK UXbxvGM~pJ)},JޢBt`Jd]QBWD?'-Ȇ: E =Jj#QrUL(b61ce΍AB\7Wb51ia+e}XJrRj$1D!?~cŽ\JHM~P2up%$0VKHU,Y ZDTC&lն@e)n)V&;]QLHƐ 3. a7FU򪅭Hrk)e@;(P`s P.?XQO]?S~4fAnrUz2< _81-ҔG~BWE_l?Frc76d#8)*HS9]( fzCŘ!5!uWrGgR :],EKs_l~4Wc Vv A 3We')*:oB)IEagF;D{ |b]F7LEYoH.YÛ[>nh&ީ; 4M yΔ+m_FϵŢɵU*ϞBb퍛RB>LQ-eH9&js|G7#/*W$b_ fLWup5ڌUXTi,Ds : H2褦 u¤KRh8('"@hzl9 *@|dJ4x+ /KN:fEr҃yfA'@%QOIIU{C3ܽ%}L[qvV$O+|rliez@fJH ]晝El8_Q$13ur-ȭNp@/JdN/Ͽ])ʽUKH &0E9dRP9y_7A r9CT#Q S |"|ҋ~ ge e}k5%?Q0w7Oi &u@ *I$/vؚȝXC,K ,&Sq<Ƣ}z?8?9zz3w}$泾\. etuK:M;ᓝks>l5 ofihB,bJh$ceR6;dD^hhHHi{=C\Gj \7(M$6  a˯WIKP=BzlfiU>M& { X/Zx9ZٶR3!kvcBLv$oiـvV@N5DWܼ.nKd*+Lg|Z ߭0YЪY6y!cY p,q37qZ|9'gt!{GC&c`*`N.PT 5uX+)WO9;3qnHZȵLzeqIpS> ڻh4ke5?`" ]sX2OP4ǽA23^wn%.0s/heqa0WF3`]܎$RwjjJrg ##<wݭ3Jm.Vo;UͅBciA.\P[]dguUX<*Ǿ{zP{miDzFbJr(B"$X0Ɏt4s$`bjnv|e_F^A"4~b&["ㅃ3Ū'f1=M^mwT7{ >7os$6(c |*% t?ٲmZd ;У? F8?쁏?YQC|G<$o<~?o{@Ϗ7Qh!n&k c/@-fpd8CRe(D*H`ad%٩ҏ;?+1cZY"feP30DFYecP 6+ rUy310q̬0sYDbwZ@۟}Ng#F׸;9쟋+g^o`@!=P?30}fh@ƅr7̜t@'++o.aĿ|l;Wce3uV`;i,+\ï0~Wl_3|Ňgg%$m㿢.+N|8S)o (afWe p01h?c7] p:ff`:X[*ᛝ # }l @"*ecs؀%4̿r0h3l?dI%aC٘.Nv`z_ _+0/Y\KNߴ@8~R @F N`Q23z L322wO*+30Fu`23on ?i/k8 2~ը0 9~ ]Ghvc4)O lq??H03}fe-#oR7q;,r0f{&OZY(J^G09 &faMG'OeEl_hF@T67)Z#EcdH Z2L_R@s/fcc֜g7:_q#U`%X rqE2obW=ͬhξ)#SkY8Ӷ nWٵl>sXh ?0YkP1Sj eWN8& 8fNP[l~2$*5<pڕyOv]d,>dMR"2.\Ts!իv~~AO3ٛ)Mo,;l"E/2#rf"+RaHW6lzjx:RsoPTKfG^%Y zg)`ƢJs/4~M94i./RԖ^g6g+i⠪UƄBݤ u^g܄ }?dyoyk>eϨ@S{Fuݟ@kZւwzL3P |r'-H-j~?"E/ .[j|=]lA-]P9Vn~vݭBO!=[}.[4(Rs׭ԄN?RC9r=Cgv9Z5nAx 8je~uwn8>u[E@V4R Gxv2O.BZ`38"x%RpV퓧=IrccQn!+S(-h{:tՙsD[贅m_& ]BAemET^o8gTmV́O!M6dj6,&>.Pd rQD.BYdDdP騞 MG:!R0>"1`O5~d·Fg'K`ai\X퇽a'])bVM \'7xleEߪM%\ِ4?}]Xl?BcE>Wǰٯ0faQپ~~}l1&E J r^du'NGU~ =/a6 2zg0C st\h[<"}'!Y|lE:vL/ц%VCoA3:l?1xHZ&'ʽ;A$/,vej=发|4>=|=Zٺ'\YE lMMuQn8W7$D9w.D &E WtE.3*A` nu=:dZ{;?ev<‘8w>xC&_}5S&>|yqq#u{5Ig} fvM@xIx&OZl0uSY%z_Da[N (Ф&-P'?GB'Jr31G[k = OYR>dYHf/P`bu*ž:)GNuU6u&8i$'ON;.:UW`֔mOZ:VbW`ÅVX7uAw?YFChvս9i8bcհv|/>kI{5{K+㷹vJ=tQ2QJd7ϛjUwr*Pf9USEBhk'I).^|Rϰ1an=Wӵ|wy n}]d9֪Zj >+ >B*.p$$\HT^T- Nd=|[jy|В{Ǫ5ܮ+ÌD9OHMqBǸsp0G(nWh{s)#r^c" {}9wӽ/*nEBX>b҂nn|GysDžEQ+|@h}) NyFDaU7#ȝ±P-[7qIr{MRjLGGZ5.n=DEX2,f7Mq IOĻ_uЖ]n/u!77ی_\Q#d_;~G$gQH Ql3 >d^X_HzrFbb!NlSmu{IC8|´a!{j;gFF ƨkU{2E:*XBLʬUO/yi;*pr敡 {#V $0";Xs6FsXKo'ثL+zO/MAXf[ |5r{U"KP% ٸX ^pTܮZhʌuD\4Q8Nq2U_e9N*RHJ tgbXen@g#uV @V=?V*-zgטarg`gs"*)!wB:80)EiH阤DA,˾Nw]CW+ XXi{mֺ5(p)HN?9dB붿ZfZ9j.tfa610h7D@ '9rd)۫M-&29UEVABPS%,M(+wMܫFt:\ropo_vkb5 >3)sBi@Ç_f\E-M,뫦'YKƛp&yFCU1 VrXRw B]<;X&Z) f#6(%?[@e` 9II&+ĮM<[D 4¢PKZ^!0Ux-r# b%Nfjk91$1y0˻l.jZ:VYٓ/ϛ>25_ZHA X^*\ 6\P8ۇup K h'GԂ !!Ĩn {rx2nJi_FՇLaKPa},g r scz'Be.MTIB+z[Lzy쬧R+fҬ)E.% )`eL뮓j Z~ܝȗ~B7],)|%7+XyNX4Q<M.A[ODA: |j?pp=8pO';o>ٖ+,&WɤJ {joomn0mlTC7y[Ȑ= OL -oPDy^X43Ϸʆ?u@Uk=L7ݍ4H#HHt7t+- " ѣy6gZc9Ƙojk#呩-1S>vD⺽1'@Gڷ NBy)I'6"g 61fs}M²^Q~ZtƍfH~|ß|S8: dhhR).<s<[9&O0,]F_.㒸| ۻm]sã696ܡ>(: g;Ѓٷn))[;}K Jex7M {o!``Mj]vJ?}`2Կۛ,!<ߘ~͖5\uWݫNKA < jUa88[S064O'.iD^&TczX(2%4Cr~4JSd|/FE+ƕm|8\ٗL`LLv qʅd5AI,wjR&hb% (PН">Z`ooemc-eSfYNa/O9^yņ Bs3qY;{<+I**]0>,[5jרE&1C5DFVʒQ[CJfBObgݖ^!#֗P/J2%Oy=T+]H[ӆG?m2FqwQk8T{Y!yR2,e% [,N2I:gToh)y FcJRSpꇃrQ =S^[$&2g16Ff_~3IdpFX~-z[h!4أ 8joT"QMzW|kXc+jC dsiߪ hzL9S0e#ʠkP-@FF]71%(u0 R&jEeq G~eNeX\m?L!HHef/;nNyc#Wa &y8ƊLB0:j7 7m%XͫOoJMtR?tΝ%N/XgFZIiQjAM.#,cI3mfd(~3Fbub\:ʸɄ&Z:ݵca~8AMș.\TrFv /ū(u1e`?g'axFynVxMSqC\Z~vg4BlYXcS@e}ػP`uL[3>Xe'M bҙ0S2)@:Aʼn|,Cώ1Mߊʙh{|fz`>N~b;WXIZ#p ,z,=@9"_w s 6t[n:jOV,='7TfVMOV\SjOr%KVe/Dqnsm+k\ֹTKv/c硟{6D]&={wH8=?Z?Ѽ=T/A]Od+@'5<=C~;Ā  0\\%Y_WvHCS `Ie\`~@w?˟Tq,a5whaow8p*&%~?EN.CPDd X88b2^u~{ي=s\+V8eu x0.S҃zpytr7aOӏ>E_GkeQr{zS!GAnp*H3:z2)1(iړ>dfbn٩ }$v6+S8M(kX5U=r1 WCőBgQ mӈhib~ ]ane Ed:%S#MLȆi{kYᨴU6J?&x޽^=>镽?Nf{%ԝfqRmjIskl{.Z0Xq"~'F}/ܧ/h]99|GB2yw^Q½QFzmBWmS^UfD{Y!!D#_ "4ㅀ{}K{92'=(װvxvl-NNb{um7ob {X;r00vbDVSΝӴ̑흷\˜}_٫F})PrяmrbIŷ`p]w4ҁa.:EÅRx0?7}Nr=<=I.4s˝Y%,+ֈ, 'A<1mĩU<~?Yd{n510~YT z/Rwf'T OYMי4g]ϖ`ʯVeU&U5mvΙ>ZXuf6TE 4TbG(-<-Ho#JC{5" Y4^~#wS|N:cD =*x"یH^tQZ]Ntv+,|f<ML0(.|1pՕEfԈ1}3GaLa*`#zcz"yB Df\=X+s]#/YX2xgǝw<,zh3<8$pܪ~J \vTᾭc+|:Tru":CZ2Q2Ķ~h kF\ax> #+ :\eLFpl{pDzn Qբ؄YZ6:a /u ZJ WSǩ)dFSRQH&MCbubZ)hWؔ^ǶQM'߭r7Mr4g2uw6s4gr7g`f* g[п|8/oz,,?IgTN_x@_K5s5XdYS/˩_.g?U.~q?c9*p(p矬69Y/7_w%෵7uwS~-N ]dߩ$32~;p;4UN夞x$Wa_4;T!}g%Es9e7ʝ|ʼnD.'=TUֻ!%E*'VEG.NX?}u΀2KsW{tr1^Dk=\]BuC|C Ŷl妔k],WjTiSB>vA}?L&c$QWEfbXE$y Z`i0/3z:S%Oh/lvve0PD={af|/T[SɱZ kgq㕻/T\# :^aЀ8D Vx.)rpОRgK[M29j0 C$wjA\OmV5?-۰M'4-^|KLA5Wg^2eyrZKB: t8 BVMl;IIl/TS,)9YatUvx:~J=֒@b 3?k]zU,xUT˗pJP()6BfL~~` &1Q=)Q)=q}2|I:|;CShfS.(8ex^4Gbfv򲨶*_G@a&aC#H#q)w먝:0 \~~lE+]*S ;,Օ@iG4ȋń\p3T:V%[E[VcS[rREVVd h?7G$yM;5Y܀;G.6"9mBU}ͱaYoR ؁fܟU@ ;Pq矖?zVl+V0(8?.n%H?<ߒ_`җ37,EԘ~W}ܿHa'+\$&`јd^0a]:GriRPURa%%tovo O֧jQN]N/X7ȺȽo_*--/%鳟^`(-WLTB?{E7 dA|O̽ Z"N~vNƛM$MQ 3:=0*0a[+CCŕ,oJk8 DP*qgTcaݰ̀jp[à\R^ "#%dzez׸AkcMIPLS9:-{p*qЌ[Wlo ? #%_AFR5D'i]S-g1銁xSpv2l_B8}PoF]dYmU6:Nd!OȽay?n>V_пV<_9m rk" ˟;>17aloM~z;X o v=RqAfRPOCP;qz;5q[y#-|ec]406^\]se̓%5_U犲snɋ8xy?q>[Rklqg୪eI[d51r_ JPhG'&rxhyOy b)IHMͅshG$s)HFP6l0 f`Iœb=}kd4IAFLWǖWp[sɔTw/Q`eAjk$Sj'ӺHLR/epd\Λm AsԛƃV mZXڧaM\g*`[GZo-زGE6.&mE#:8EQl |Riyh `s 2J(=Nd 5zQX\/5<隕UBu d3J-ncxFJfXy!x7ٔccwKmϑ5a5NK 4W]5H:L:\'|X{߻'P>T,dDſ֚>n>>Trȳ RmYlϷfa"~pTCOp_iU[hDiT__+hyg[4)>aafͱZvRߤjŸʷ"q&ש,Tʻ(J@++.W{yW^*i |^:vW- Y!yEڥg'Zp·o+?}X` ߾I(f. /K{IZU4@ ǫ0@U [ihr@R̗Xqo,NhXL8-ifڧEHliG4 ZPNnWPiR1Xlk,> MEngNkUxL%*mnk"T*F*{ XQ(nXDێEdoN;ԖǦ%`QOӯC Nu(Dz!Q蛖켛a? 5}܉DCvn(#ua&T|?m{IV.uؘ{kvPV ۭ3R+Cj.Di)!X*eq,"rHPhL-U1A8˕.鴞x*Tq> '~U 3a7#3o ʥ=M|*LB|LPE'Kκ|uA``JMW|VכFGIJOV9+Nh垡 uf4kYM^.&ˢBꕨjOR (rQ9?|p\,0 S+ȗ"~1/KEFݯWZ\ dO/7ϲK_ol\HǓS& ͯ PK>ȚOm(G7!>'Ьy{-Աܪˊ!b? v^7L)9¶_zhi,R΀Vij\YyoLr^=; @ saقޜqz zgMj[ζֺ!Vg9k==^rC襩ZqB/o('Yd<^/en"_&h "aX69U{  \#d&P*y+3תzMdu# U{ȒRJq(+:5`VTs&3quoλlO{ym束B[¯ɮF38': Rcs2 Jd^X8i5Uu*Z&AvITj&Ҁ,ĵ掄rC*cG*xsb:Yjiy58휼5iSNBj0cS#(Gn->j+y;o}1equrw`-. 4Fּ[s̡:|sƪ+i{R^Zi4\\53ټ{e1ш,ZX6R 'f@OH}sp6Pw:' Wh9Tcj&:!:@Fd^]z^0K:E{B^J1 P {(CVnmT, Š|khDsoif;Yz*bT"ף6u^E@eيhZmG.ԟKt(O-I UێȨv <3dkܭ㯴x|ݙ$)%NRږ>1zCSٻvd0EWch`,Y؅P4T]IKsH}$[CINIbʩO4lT&?kc k!KїRJ ee{"(+JH nHa39Fx[3ו)[췽wqcu TM۸f("-z]ty lסՋ[\afO;2?{rIѣXъőTq=`}MVe!nB߳! ]"Ie[ԙFU<"x:">OD%dR?n xfǺtLi-l[>dFzAN^^}o lhLÈm6WϨ =%[$A|-1ıBgqf@#J%҃c7^~^a34(/?L_FU|=_0ӟS,~OH9DA`ַ_Կ Ӿbp&&Lְ%w!I9”8gM3.cx7Os䶮EgR:Ox66'ϥ +6jLJ#鮜[,1ʊ^I~;ʘQ_?|(3C O}3U6w0ŗ҇z~6-a?#K)y5n)-ǥ+baAOEḹ;^ Zg^U#9wze;GMzJ078v̘ȸ ͍EnP0k@G0 6ijUl3R86MFo9R3*f յ[4Mߜlm[qU]gw,@S8w; m@Rx8q["K,oTZ,/VZjbaQM˴5H\„ǹA&OGe[zcBVPh^1ɚ;kg}L>C<'"5WdҏAg=)tJ|O+ s|plfQMSGt %<6 B'8j$%"~ߤ:t+oДoG Jśvr|'XZ݌{PNfKX`e6ЅMLy DD,3q]ʮNDOc>dZ^`ŹXji(⠶o핑aKv/iE}GunCFfF6]GVܩA J0!OoWބ*p poҡc3@% b4P( eoM)*/m'6xGMnIJXDC.dyk%WU_fJ#a*eRj4fج!.f e!Y f`Ĝ$EXSs-c?@fc׊_ʪ?ZA}=.7G~j\: ǚ\j rQ^D.]mEP"<ӋI8/*Q` Dj 9 01l8BRaLcgxgǁ&.M&jf?R2SqY#a"6v{\ˆwR~ol εYCmQS7p k;52%ȫm9Cv+p0pgok|XCz.5 _k "-ÐPb]y{c[;&UEtl|bF u`HTO;|-g8N$O} P 4B\jWw*4V(lJIVqV6h0,4z 윌&7M=rՕ[V\!*#aB~`^Op $u~Epe?OE=t*C}>zkyq|WR|{L2R[Yl =Yw/ ֐&[V\k)ީɧD U,M.zڑgf'c;k>x +w$Sp[g>nP" uoZMݬ~~Ly&os<Ъm4>g//?V}_1)y0e (XH?φ#s>>3yx~P[c:p\@: a՟j*0*>ꏣۛuUgO]Do4;s3OY?nHpv5OLY /+5հ!oͫ[yٿT}':ӭ n% )cdijStH-bܧe%qnS0nSO^8۶T46SR7BZhiSOcs&?)ªX gSkJF a%tpFWݨezƳJfF'כy}3|3՗0 ×Ϛ߷RCgKsA_ޛ6OCFTfj^j}[+m -ݘ%<3E?Y0ϓi-6jBCS] au%Xrh{֪I3/Z;jVsY9u6ph >R fЊ v_P]ۀ8&"tUMd~x؋NV4bU-.s|ӂtM|KɼYq9hD,E . @qHszڤ'4y "@SI-sx!3_ڎI elb^\kOxsdddy:IWuByc4a4ay0E6(H$(lˆA &rkGn$$ Ƥ㢲T!HD1IVt]oT?oc߀8%uglh5g8᳠ Фl1U;k_, Uߛ0J50>}DLV]!pzc4AJ(R0f(jPb vy7f.O6^hP~|Bq:4+!WL^T?ed]3(fw$q`A!O"EKnBi*YlQ%^Xh Iw[( *jHHLO06]Vi %{I>~*RW/!)+#Vz#(mTle[ NI׶q;.|Ldg@^E PI=?;+@V?$~s/9Y7sU81}HAQԤ#<{+'S 7CDIAi)_xJڌU!% = 5&&uXtDYgЋKg?jNj2S## RX'z)⺇U;DO lg@T"~cd2 |PH۞(%* ((,jCSˮZ}y u׍~sn ~{}@u+zG@E$`$B_l`jjn[ebj}`CByR>bdZt$ Òoo<_+~e@/'׾Qr9+ j*W/3 &C࿉@_@ ~tD0(FY+~JG-_*̽磠$f''0jq 09Fm>q;? VŽurYJmvX3V޴Zkr(n~rס`W?TeMwT}T=s.åFt$^^\IyөEJ|Eɦ^M<0>x>]@pøQKyCчyYz+2-I)Z+{sU3v %jlj yi+FׅW@^a+_x@;;ZbG=*r sG[j/nWlg@L-OMվI RCH88|+Vm]ts mz[ ~YMlFv[_[R&ρtIߓhre&XRvW6F׏Ox@.Ђںz0A&zg-6˚0rysgvtȤvA*WL73pI/$뾺+ATZ2%Ev?yJ"V^r-֘ ns,֖}fm_VYX#uVh9*Nj Os/`Z@"PYĻ"PTK@DJ#\e]@s֯< sCh RpM^ż:&('`a֝ti >4cO=!}>H\qz}FԳC``WVzrYsjjNuR_tU).|Y|ZP<1dLn)C.Nu|u+O7ln+3S"ӭ* U͝&AW\Ib=f[U }0%[t3ଊyK瘌8k`%,DX.te#A&5~;Rݸp$ŌBDa|,6VF\֮Ŗ'EzH oRH^5yC2;-}ΜvpV{ѬeJ 3%{%uQ"'23zPb6SxߞWܽ5HOn8S8ʨ[ax'(N+3f4Zұ:){> 4/]-4K~h4_:Aܧ<_eI;k~Aƫ`Ahص[b:?AixnrW؛<Դ%z/C=(UR#B;4r[3OKU21\eEā*i{SۑPn!:Vz(;m44YIұXϳww-U!NazKLDfu0^ AlsZkX4\*%s&kf-='Ba>y@PbIqzPQS{7 3u"E>3݇r;ײH>=?Цq?M撎sd"!ziC Vygcұ* ōbl?/ 3ec(t"|)d{c07c{q"N &^ĄͽXaf,aw~Q |^qҌ'٩#Ϛt4MU#Eȡ5WW;9 FA~8ԅ f)& ]r:.'2U5ԗm-5.X6D։NFDַj6J H69eɲ킛JrXē6CDagwʩxGcKO*YqG^C]nIs,W :ܑ!{H9tJ w<%fR;K٠v`Ñ%|;tpηU`[AHiskN9!pӝi_I#]=XmaM;z̓)LP|-pTQ֬5M)gX1Xk ެgθ'Լ5=c}w'^)ny Fkgg!fΰQzPFbvlΌ.V4obx0`Uy2jp7=YR:Jx4 *v,9GpRE} Lv(̓--jRw5<'*/Cg/OYvTBA,t깅Z}p:Y$ܢJv]hѱp(rX!}v,i P;gu \Vװ}if@?3}ӾX|zfs %`<`z,5Ip~ۏnq82 ܿ5)GmoUg5݂wwKpwwKgogzw:9wU]eeoieojot^g;KCϻG~~Jm|01ӿ3U]C?Pׯ@OKW؊7 D\iE[ndUckyu "W\$c6Z{ڴ`8^~H٫SG6P ؓOU2_GctV=_>WL?}ZzDs9 1DU f0xrB9*0[.U0Ok4/47|w#zR@UͲr%݂Aܾ\$p=Άm$T]%O~ dOḉ{E(9Q&C&SuUe} ^ݛ6b}3{״$Ydte~F/a3*e*뒇U =~7V;p8uRC'[{:>yu'8RAyGGkbݷ*lhc2}?6l`{藍UʒF?epջX;$MU\V=+2LӁŹ KLMj7X->(t&H5~$xJҀt sP4<uuçKOk7{=+R'2P/MW;-k}3Owvv6G1*l1 P]pKv=t9رO7>u7dP$mw>T+ MDtߋ3@5nvX¯ C^ xE ) CN@@Ƴ<0co?0V<>A M^z1/TlSP^*!W t3hj{>FgeʼsTT8MQGz +zZ|r3ܗ z9ܲPxg[\&p_ewfGu`B.DUt'%E+^sRS#¦j;zON˗R:O&jǼ>,߼[ `s@uTfq8@ Y, %o5Dq9⎬Cj,Ьp7 PP@B" \xm]Ni.&3dLul`<]^l5!Uw[U0-?C2CpH}Dv`!Y0kx| k_} !S Ne4pz h- ~aɄ=քTi!.^2zhD6}UWːQh84g7"}'bjo/#eDb]A搳Fs *+kD?!NvVpuڧHsRLE'd vQ@ ɺi!P<\Ոy1W i#"g<$$Y.˗οd\o+Aǁ")QK\"̔?grk*vmlO3daX5KV5UH9و-!n``x]3M +4Hb;8S#f\ Q,'yP\Lu`/^t)8%~ n?ݫ*,J~1ek= ϣbpY"gĬ+qޝ3AٚCE_H\,}0tŁH-q}!U/JM= Hwm+pi.?_FcIxeR1Wbnڍ ! b}'":Og^d ROlU)~^#T_nf쯋t=v&OS Iѝu~o1?9O"YHÛ5ǡz";'@[ K5EN([ܙ{g3O%Y[ijY<"ե %ţGthh S)L#)D[~O鲑^P#kT6Z*L+2&feFi}mLV80ĸ$2L [ms"Z N枩)8KwsZvKw Ҵ&/D/G?oG^ŘtDO)=6x͎Qp?sWL TIZu ߣ)(Zjر92aY"OĪ~oD!14kMZV@pGjۜm(Eא/rO YXHrES )id= N*U7MJcԡuJkǬݜtͲ݊Zi4'v gī$ lk}9tʧ=j=QK}׎i}yO{̳d)KDF{8 jt>q XϞjwkUUd,h_̾Uzp~}bXӗjitQ,fbO *H_,(jyWz0#%ʘH|RWȑ#r]g3Z]-95IG[y-ԣ2O:CvO3Ńil:{;[c8} $X6 M(eK d1E+o}͊BECV{jO W'/9~ F4S)1eKh6/9"ʵ&itV.P}KFD/]|*7~yC/s\^񑌣 IlrÊz,e͍3fݤ9q̽&m7${F4deb&{)tUoɂCM;v+oWAۼVےvw4Y6)IMv! ]d`Kei׭֦ω=aOqrQrl,rbJ\=3e _ _MkT x@*lj#KSփߒ)4|e^G#>][ +&T 9ſy (Zéω fDPsJ!@ed9-ļ._E)1Sa2OAw郐}V3/Wr:Y~Ã⫘5uօ.BvI 7E.WM1>`^6" _qFyFysof> ïOt0WS|W 9OWE_Sy}yOXLun !{Pl;%ȣYꄈd*SܶOvoӷ^ǾD߅qOu5dQh.ϒ^%ŵ7i25?瑈` _:>\8q7Jۘ*졑1Xh?j\>NN%i`O,YO]nN( - lDB|m[7sσ ءt7"/n@ANp\00@dž2PQ< X$٩0+×?2e|f5h5^Y s{lLcANQJIVpća,kPKLl?OrOg $H1JUb UOP-{T*ϼ~uy+_J,f$HgT:R,uIa:֢`Qc_n$9;OBBmN#Fk6|}:KMFir[j՘Jujo$Z`m k%YrTE-+t#`o(4ehpsP:ɟFք7ano_;C_ꨏ`@-֌}O#Y1񉱒OVDZ~d([X9`o@8sNero߻iW>qF@,`͈ 8̮ 6ǣgz1ok`'a%*<5*Ԉ [q#p5a8R ~kD]e2wrMD}' ix ?%56A2 ,8$MzDauTėhHPcEX#u(է%szX|kqչ5ju)b`D3u{i3`.h咉צ Psup)3]?2_5-n?rV%,>XN<* Y?2J,rW!hHqXm.qҠWoY{teՓ4F4(!ähd" n%,$ 1\(Fx[hMq ♣+3t&a#ĺ$CE*GxP.%p%Q+IZ6%`%@/B.7ⱒjp|S VQ}šju=JpG9Z푆ps;ʕ̂f i6YꑭX"y19`HMq4RTicB{9ouTt#`,'YT3I6`h8Sd<:Aʸ^6{Mf^o=w|s9>hcH"|UY>j P(;"imL`Ў;b i,rJ^քV}pzF6ZFv*-huM8$E[@O]urr7InQv溤dl3cR~@'iyCubg Hi8X2՘*çy:?vS^۰P5D?;U@{R&fm_U'-gBhֻN\<,TbvuHꇸ}:˞4pLb%mi_v>`^J$$ RKPXX |_oa"vquׁM`w5ɘIAТpuNI8,& 1\R,n9]r6m- R2`M8? ~ !a0vAoNF ́(W1rH@RjAI0!#cV0A< 9w!0hTNڏxAPPI>SW+NOTN(QVfj\ҁ3,,Sbkc Sh;k}KDK;W8COz SG&+O9Hqn=1I1\ckC;0tUÔi~nρ"pŠ =Q_=e1ѹCeT%9n6z1ReHv.gnyd/`&xn*88~>p{)-1&0meK[1˙- @nyYx'u`ȩ#&pG,bF[c]N0|6}7/ؠCCd=uL+[׸;_#3bqb? 5M qPj| ЧXƗ換96ya▭z: l+ӵ_dlNlZ##k/*宭bѸ#$)F=lV%Ù&bMq`E, ;e8烁1Ob5wCߤ?+?]S*m;ѽ;{xn 巌';SzwE;+]q.t?oW'| rE 0WO#G~{j{Ro5tߟ[ M.v6ڳ֍gr1 ҽktrxֿp7U#(hFw)L'kPS/7 9 QM#BX<$H%w=OTF DX: T(ҙS&Bzg +T\ge>M G*RKqhȾ/N dF_-y>tI֏_05 U82۝2ߨ'%z6L=%K)2WPLK[6/讕/_cMv~_OnsbL :H+ `ƐF͛q?,0[Q_Ѱ 'f` V"hgp7\L .nSO'kcR.F,|c@(~0kѷyj1VY6c=zK` 4, DM9A폆 $eUe! g̑)%DȒ!>m7CCTv$W#s-nLKۚ< v.wyPޱ,'d\Uwφqunq|3!lYp{C:8$^npA]v\&; ӷuxB茡iu`0G2DҨ , 9Gzr4jiLg8231>OzyϰJs((1we:w_-t,J`G:hO1eoȫ>}c*76s>o|&&ز\!0b#$MK- u֣0#\܈E+]ǣ4鎩ȒPѣk=b-trY8ȇa*އ KEdՓznfnnjĘziG@~@3/׌p-oH}:7 ~Pgዕ 5}FGыL^/@)aB4>!yn= uO{5U*Yw'LzԾ&W>z5? 0ěL5zf='u:HH/S' ul"]k$i.)Ȩ͖WeKj>`0xӅwhr.zF)^[c6*]1s|Ejiv4-V>.a骝ۖL }z@7]vT]'Zz OMŞOM8KdӁF]P+x_vWpx3 !ѵCWIw[;W``%3йyOy}Z&?l@ݝ$@ [̙$,I.T(Z o|i -euxXsq@,YZ\!0D1Sph!.\,2|軃Iv'#iИ']Pӓ\)Ft 7!Ac:>ÉgD^gԙf$`[~צ¼LS'h2 yEg'~Z*5QBE5/mI4r#""\4m4V%|[jN(6;%hyljCtKk_ѽsQyS(K|?*'?쟊⟇̟%/b~ɟNgO ~m~yOpNu)vcBh Ygce:!JF`@<;{uA*"<4dLWױtNoe͖v--u)Pdy倾ܰ͆<-e˻5bz>; >-8dCLw 7ԩeoy}B?d*ZUüԵmE)M~͜n6$H3T7I8AlHV59\T@uN1 ;f :%[|n[p:}:I(ID|X-p(,m@ZcC:VtiJJM*XDw}6.b_燫;v!{[׏Ff:Dr%H U0 ,\_HÝ)F;?űUBvDIJJAnR$NS8|wOi{Ai^sdԍs:O{yc~0y: }&PMJsI~nL-X6&5 qreE_AL~| 3)Qα0IRzm_8Z~mAKU]>a!78(S$@!tf^ B?|'4#f49Ϳ؜$ȫ& ͅ Τm=f<,C+.8'Y 9G I68Sy:cZfݾjBi<u Kam)SaK[0 RTQ=Oq* w.J'@ ;wpZ%}ҵmIHWbdJ28ss-auKx VLÃ洄ܖm,Z:&[}Y9![a2,,+@9Zl=KBd5Zg,$t,.&)t "f!*JPJj=J!٭4]/z֚ѓe5Ԯ%[bγ8Gi9S$9Z["ppz! ܡΟa678T$ĄUޘU ӭǷhNz× PʈC.ٓY|p^.*q~3 ]"W>[W[)1FV=ˎ %L!} mOmz?E4bwwk r䑂2"Q,b^[3|{Bܕ rֳX=k7(zhX쇆O[Xngqb1tޡ=C= -E6̚բ<Į)Iحhվ$YcV煪-(mvĎٗhkjVIn 3Q VyEG'FD])ޠy v@#zr^f 4=(iBtq5(?YΎ ǛOseml#F4Ɵ'< * }~ 46Z<-GN04Dv ;"y=R!0 q{xbYz:liZ*"'[oKΰsK "t;_`si-OOOM /XO`)df0{ $g)(=fLJг)rD2`'T:bDbL׻CUx s 02!l&{Gl_ A@t;(Gt+6M]#̓R/ ԲCk`kTU=,o48)ד8ɛLt篮j)j@G(pGɟ)R=TeWx4l}-M?do.x~btw1W|OHJ5PkjrrW_L w ctԿX&1>#j*Š˻..21S1/220323fn*kbmwr iiMy}?ӻIߺQa|7uK!9a_b?]5bqh_jj_]$ckApkj)[^ u;ʲ΅I b|\G,gQĚ{N&Ed,1{nl|5ʶ m*p,~u7Q#Ej/xA+زC Fnp {NPo}Y,1eBz>~N`-֢Ǐ(a!$@'+`[Qz'`w`g q,M.1AM] K1e§)6BZ⠇l| 5MEa2#b% KbEضq<#TvS:˫qS QIC<ܮQܞ [EwWG;$@gE8BBY.e=n$Wfʖ AO&Otۋpn,!f^H+07)SYcc~<:FCj ie˓SPOe 1v;%pI USeʌȦ!V =/mLdkxl5ɊQ,UPqnUB eƤ`[u--c[F 8y@Ge5a pζYٜlN@A!nmI C8:CcX6%9/ B;9C)_73 #~ OC@HVrǟU )R+4LSOY26# UNPbXU絰E  t+27oҩ*pǡWބZd^VDfi.g[#_4̍Qm}kz~~Btk) ]#\ V|HHCcM@H^$] B ݛJ{ ( b3C HWQ;tULv#Izi)2, ̫hbRmիͤs'yпRb ?[,RF:ZHb{#Iv0\~-/Utd8S좊ώ5oP}ȧ]B}TÆ$Ti}zJK'ksU4S..f#!ޒgꡦ`b)4UٻSl+<,'-BHq_BicKazOlq49ӌi&&e4oy_Al@ƟLZ ss[c \{Kvv^goP1Ʈli=|uk!=cщ0=S\%S#LM/FgϮJl*k3Cv+E-GE`.ĔJrWH}ə!&-v 4=?ֆ}ZY4̚A:~"b JA=XVcl%sGeӠ/sU*\d\eRoLsu s]kd%0oᢢEetɅ?f[`2۪G`:&rB7͛'ӥ-Wn3 9pέy}0*p Aθ7;%t);JC vO(La㨸Q*Uvޘ ]gKO!s,Q,Yעp 97?ojuk=\=xVOsR'+$ij-t|JnN93g=g 2mӣ+=Lj7JT퇡MO}d+Ood̷kCUoku^IZ/廃QѩO~FWIOZ_zw(FZV=gixLYE 0@\//Q8C۪3J5G o:z3U6H˧8f8=4yS뎘e5⵱GQ kVmlh#=_Tmb ސmnhj^{Rzs^7BX5}pPB>g ƭ<D/'bmըCap~ow i8mbb΃,-H{q 6l˪C˷ Ǥ>j/:ǁnY8SNi*-_p0AVWP=Kd$G~1B싅N*EC{na&حTj$JSdKS ~_h]tMP}^R\ڔ3N.Sʏ[n]}_iD%2>,Jh:lXCšY3Y 'gKǯ ~Ӓq/A4Ķ帟jV?=ši!%Ѧyh#8ɶQ[{ہ`F-+[VbzTîDZ+yW\A>b2z^XUq4!  ]_?-Q3G |2,5ǷHmVkl] mAhWa]B "eG1e!PHrQ5ZSB\@-4ԻM1d))ݙ}jזvfblڟz)@え @#Reɒ ߁9Eku!Dn*I tFN7BiPKm`(Ș'ph"_pkPi #yB|vb~5<TZ=^ JTp} '9Lfz}'I+5Mj~x#oHU<^~}o#ATBz勊 ok_T%`x]7B=yB R{59^Nb']W:XY Y|,!_uv$ AvULݮ%` \F-hU|<+)S\f-OPwELN}Z +\ޥ0t9W{ֆ`?Y8 j4gV"z&TnCֺsR3j3ubo-}FB@ YKU9)YMdXi0HZ_dŚ|ŔZ}?|D@4CA)P Eveٰ߷v`[qL(n]+ <{.p +uuFuE5M-m,%vW'spT8縮X"ۍ%T6}vv] S_/p]5 j~y}buR/"m³$=M?CdN ̍zjNyX|x!*}UQ@.H$|p ݱ\# %L'XLv>-o #ܸ mLGN[?8 $<5W=w/>¡߀՞/^U|)9J]o ^n'5V7{0~5|Usz+E1GpzAM' n>FΒxz\s(Y{Gx2~USOZ&;2VK[NdUK&wkFCNIYYQ9:ΖO̳/mTxh%} )*k(c^q=RN1cw VC^gC[@Umtw#ݱttwwH *HttwHwKwo˹~GOsp8ı;ZZk>Ϝ2\ Ho`2qpӰ۟z_?  ccA]@"A~Ͷz6?<2P d <+ ;7'W b~*p  8 77/|kW+XO+.M4ob^*UPϮ}[ۿW[nd6qs6uubv3gdBiéfV_W9 h1_GDY6ǟN?emzc>o >>ߗwb7dwcf PAL^5)_͹~d ͹A%,͎V"{/-Uy6.e˅$ߑCy)%.Yiz d,T7{mavHB~ zh_v#q36@&9m=2uB == 'GOG&U|fU͡k<ݢ&TףU(U"U44NS)e.j=ɤݭ}f_ ;>7, m&+b~I,e+파L]'JW~=G&)h^sT8fU+e䐝u.%&ڕ(M"6έ0- U[g1~X<~#O qi9ؐRjE_J;bdˉom;4űE7 E$E+OOt>@#8c| +vsX1Ki3OZGTfMjިfEcDb0k%Q8mz,O% }=rŹٶ9S1Y#GdCǒƍ5ϓMk%KY $jM4R`!뻏 K)a y!=I$KϬ]@~j=\cK3-x * fd#+{~%uk3 [eMW8V$4_, 3^dS>$p[VWhP7bۊ);}`lӒॠԿ?VĂ-gD8]ڮ={'H<sK&QZZ^J&Mx1yѴW *-p!Ch!`~9r\Hw{fܭ}?^w8vRӄ4 zk%CSd*o!p!ާ)ymctѤ!]"ʀTӹD_B5m0֊$JA&+ޞVIvGةid-[b!^R<3p`lEx``6w%$vѶ TNl'.[RuloVEB.^^hPi>:ݾ󴽾>?mV27+. ߟXXґ1HG0=?`CWt+lz]6/> vҴ?wjU_ y?S`VѬRvyҚ_U!<Ϯ<@.<<|UUx$FZUȏ3k!R, jGT k|v->YP?Ae~dZ㧠Re+s:g]}*uj?k51T* p\Z 9vfV4o+Wxyl˞۷cMj%uJ5mDj-jv/$1W .Y.:?bXV=)k̭::ݯPyU3E#"^,0Jw@uHגUB6n+=_qįg$2E+e@]U4LGIa>8m_(P$5tA뒇9M

@\@us!`EnՃ1&`w@=}t)>ُnOO{^. _tm@y w{z«zݳqg_f5A2*3cvGuA}3y<{ i;L& Wn0喾?5(x݌!ǔ*Nإ)Azyq OL0šH5Q٭+d }waZ>@I"Vy> u/#޳ݚ=>^w*mNIS# bXĹ7ssXL!-QH. Éb{ i޻i%{d-.si]ͲM[4/t}UmsMw΀"T`@ZQӰk< =|nvTLgbjjFX6U$ږ|1T_,zUj<l3=<S u*`OΔ4VKXa61<1: u&"m/J.Q$Bna9o_0FcC\$IwaT ,!ɱq Mu*!}층}meH:vJlmޫ lKɍ/ró`RF-= _z4AI`KKhY[|vnSws oLO"0L;܄K騶+2ٻC1;[:jJ a 01߲ZOzĬ>wx lf,I up(sed%}W26KN;_O%,w@Vǫ}1 {6dWpj륏3LQ97;]$~D킆_gGOsʉP>?-vg&?S QW]W>oO`6rVU1wvafvgs4 fv 6?Sh.( 5~ q3ـ,FQij5}\rpj֒R 9A9m07/#BjN3 pp}P4 'hH5pHW,l\I= _'U >ͬ 9/ gvvcb~zw $1?@G̿ﱖ+?^!@'wɊ߇d~wd'";1V>c ҐxOB@(UL!tS^fKe:( -4~n';a/5,إѱѝӦ"[6Trȧ|̎ءN[djaǛxV ǢiKUpCyv9M28V(nAY9/,K kX. eN׬Gih^B,_OC\8gv>fEv:zLPAB9&EGݢlkܧZ]M,Sq9,P-,vh8߸̔k nZ[&:ls8|7s6V'9lhTp oC`=}B+Z= <N{닏F(bdwHGiA36mN"մ*:#姴7E}PvvK[|q0 Dgt+`GCC {NrnmwD]sm2y\,T _FΗ2|cVƣv$k`>`.ᛠ {c 4;]%GCZ=5$t@HpWBUwyԆ"69:A W4-bZU Ǥ{1s1rx Ǝ0-gb a|gkj>E >{/%XaŌc[!HY">}tLrýi!~Cr04z"]pUG\V%ˋPmc VrsA&> &wV"@W#: 3D}eGH0>7%Oz~~`'\kA6llР?SvW20?HW]l j'|UL!nbwO|NJ!N^Z0 ' ќOⳫFcRB)WsQ1_ ׃60JM@q%!qfFvG#}QKU%Kw9{ ܃|~wCn"-=lF6B^ӞXՖYQ.)hz5ɾQ6!kkpCpEf&Y4(}j*MBP\GuzF~{~c{<_Y{_8Z6ٹ[tLf&@>I~2YlIzeéӗ l@.m4cS-dv#ae3P-Ld:_OrzcavM";6?1eY!* d. 7(3قry~~F@-= XC Ng77c~YGk2 ȓoŻBs;TZ7^ QSr+ GY8x;;x3ѻ=s))s)~IK20ϫP*u]l͠ԳS2L I\c# WlC-mۀ`$ Fn؂tShe|0DϯVx *ΖL@`nuڱ7SQ>B286V]&$.0.pFk$/x|M'd , NO:"{+xc󡍾m+ ޲ ܽ-i(پ>/E/He8 YYau3V٤ʔXP2MooL)L=&OyStwlX,MD" )4l>̘Jo M}Ő%QE&3BF9UlTvz d,GSi))aށ=-g+?.mɃH4ԫϩhnuϪd'-wTrȈJ_Eىz51\E? u IB2;7u 列9)HhLc絝{F"+oZ DAvGmJ|FҊԲYGR)O(JQ\أh1+O-GL>42y1eNj`Ak2P['M""`F69]#}ԛfxٝ39Zfun}*mqKz`T6hRJxz7s2eҶB$M'Fscid;{/u4CE'|yθDZEki`UgqfBlmx 6,M jg^`S^ ;dCӎ'4-<#W.Qϐwц~ya D|gT9#'-/rba+E) =>u`}[p1 9{6C*vq܅[RyD^! *6w)FŲ;O(Pi/u&"igJߍ?7YLVڻ6 p'qzp5 HqJ{_Z c"}4 OLC^G[+AE%ۆKqLx u6/G#i+Wx'2&T\t| za93?*] EWZ4rϐQb+'7+*86<\ mDa2p ϛeqyJǁ{(lئOP]Ha$:X(/@ 3%C7DR54&[}@J-A16s6[֙mx('˃ݻ2ˊr_z=G;2&<fF YΒjƊENci&ݢ%™}3Rˆ oՑwqGJW@#TUB /S WWOd 恋%C; r>TF<:mp‚@ Eˢ$is<{6bʳXd(>nZ#8Ì`J@7%2iQL~يK|ұN*ۆIHЇqxB/2R* sϒZAHWo>Inǐ:.|<2g?0)Hvd%i$zk$NYϞ?Ur <5zPau}!aϢN0.ͭD9J'iuO]K 8rǟ3^pe3H^ܼVNC p'RF;!6'W]IbyGP*܅% uAZaQv~?w"ɩؙdv;ʩ$M˄bWc\K@X}9 hUvOyq "WEprbV1sǠNK,%ߵ)L:)~8X[uA\B6 iM%Dz,6x*#2 +'?н0t0?SG: Ωzȍ ҀՊ5,K %Gz>)NQ+wv TMGe3 7ҙI?:Hn@VRyًOʌ(TCx6LR?44v-wIde!~YmƧ^EJTC{hJちf,qTڻ+rtJ2V7I!Ώu.D,(R!Xdh פEhg/PDz y swCڝ6EtR!}(H!oXZqBkSd^̕#]4@0~LY5{◹'a>cuu3l+!'vMOݷdֲ9_0*]QLQjD~*Xwu"+4~ZӫqV!+9m7=mU$ۊ͙(!ˠD3g"Kt3R:h~]z8U7Pa|',oB-9,M g m:u-$!LnJ7̆D֧]X"D.!{^Ǫ >$cw0_& kC0Xrc` ˿`tDYE~C~ |HCG>{l*[p0)7 DX\qo?4bpaqNv&.& b*A .MOmٶp ڏ rtr 4q xL?lT 'ok c߶k5y* |8~QK?e~87;}wGg;S}w)Xc_#.-9 y.緥Qz!;}ebH_ T _,3s˰&ѴLܟ 8!RIYV)pƤ7:;cݒ~Ue9;'J^hـ>ձɓ70"\aKzO!%n?@w߄^9+4d'j6>=yfH!#YGv8yXfؾYAj)3/߽N;}E 4~ϼZE,~v5ݘ)xz/ ny{>R쏅] 5"yv('Y$'?ݡv}{BkwU4|{3;HǾH=t/zV6f$:*fpxn+W{:֛aI!jqjVϤI! PLȫR#]bn;URgT&FTҜB8H($ˌ'B:I:^^'k1,9hpШxIبy-i !=h/X_KtXEW_TNr 3q&ڽp8PD*M A@mU8;TX~S_a#ϑ1GzMǀ ڕ! -JJAc ^Vw0MYT`.nϛY, #,z9V㗹>P(CԔ)bfq iY>&">"y5@`HQ?YWx%v}1:I 3=_Km+`JǬ=!=&Do.oH G*H9uUt#2 p5+%:3Q1JRF̣W =b{"H{UC(lRm$"V35!C z:S)lz"jѕFPv,)@7,hme_\#}h1eS75J"D6<3Qb䀢HV_.՞ihKm㼽 q8~JI07/QT$Wn]n4EKpɈ"ShgHP1d(EdƵ=59F|3؀Y({Ļ@dgyIl!ZlJ1(VS/s)DnHoR #;F?B4./5hhJjBP4Lkz, Ur' tk-]lӏ֜<ȐG5vxjR~TQ8: ,m)qHmPRzXkG1oӓf"Q ~mn=1bO_8 %UP|m5QqZ5A `s{Ivk^1fFg}5#Pw0)3Nh zX N%.ܟys+8M`vJsKCfw[[/Gk:.HWr:zwwjlj zM fYN[!&kK޶]>hq^p2 }SsdNE$4z+u5݉R@^|kUV-w$9ܫ1j>}E Z,aṃ@3ٴ+s5[DwԵ,劸۹}9з:l1$< ZX=oyA>b]#9suIOh E4V|:ɕr~Q0^[x.n5]+ŕ0azfr 1͙cL>YwMI]tNSi\ d#wE2/^yiڿ9~Wh^Pi2Ӎ }W5O{d3 Ni菍 JLJ~ ҃EE6XBdy6SKW<ݔq'ސVn87URtl9= YK599z1ڄ\62Lkx"_2 Ł/5׮O<$VhNovΐyoT,}"Xj.LfEEGy3C*CX&oǔOM64~~ zf/F,hz5 +6zɃ\9Vq=:0WK**gglZpP܍Zt! $%2|Yäl&U8eSoqSi"x}).GZY+h,!|6cYʜa:Ft\̜l~RFtm򎘞Mr㠴]r6/)s 08:W 3Ě`OsCʈ/Եi'_ ] ?KX7@`b@K5M/`&i x/"4YݝVX8ih0$K=70Nl_o\̥q1^鋟H1x;@pG-`8ԋoϢ-.D _qb|Q1/Z^7} ¼eR7Λ3ۋ?ŊVu"',ES[?W3)dX8kR l2hb; cBI z-v=J/_Wמ"I2;}Gc,vAx;ɥx)qȽ+]s=܂h#4caP:fRU~1X>A\AK|rw OSĤ+6cV"=!A0qfL.tRS[ !v+{#-02C)읋lyplnqNku*TN\v>UEPqjcoswA-LRNh7wR:e&:k$\ޜ]H<-4BQد4h~~T0|): 6Png FxՂwq/ O)G5 $:̒qı$&_+NiUY-󲻼(=ՠ@0t1w64}h'68(WU,:kƣy %jL-ҹ iJ!Z:U|d>dO# lUOО=.O¥䂻E-Wsb`ӗ&Lq5vrkzoiJrd QP UCc'Ɉ!LYAI7}J,HmKm *^t55س">}nwL& Y bt~ KAm eʠG'26"4]]4\9Ǡ*|[0o Z/p-q ;C?`03lFaZAcv%uMyJ {xtb24>9PGRP+94:Q9TğVQD!hſ^R4!\>\@-Kո,_Tn҇sMKޖsI3Ӽ0;sOL^7NLۑ/{>whY>ݥ1ミoi/),‡"m X~.nfl+L,KՓԢ6_yl_Gбu{o.(?KAE~`̯J,Q_rL߭j>3KXX;8gZ8NΎ&6n3oAnbs$ͮVmw%s+$ǽ"RoqWx["-*cŐ^1ݲ-SR,pg]E<•wCYR ť~&ߋNNVR<˿7FHxzܽ|6`5s|a˫#qeɐK&IûD,($ 9u)o5R-;8mzHQ:B񼟒bbEðdo-^fJQ U-T7!o %sF̿=@S=éIySs"86x}~vz1$S`y5Dbt»Pˇ"8ӜXhr՟rKF=iވlUX)u*a_sa`W&TJŨGUTK 5`fW׭7 #6=wǧC@}6d9MTyi;]x^8D4ߴVZ!Z."INB. vzd;Uy[qU7:>ly`Lwk9A`K=fb+Ld.5dBzb1J*+mnavB񏥎0͡^Pimc#xEMo-T$(7~}3$'Bn@r|{ÌjYg϶:ep_vHkE\P Q7h&5fJ0:3&z3W:p>MƟfi^ojǰ̚ɸ>>Wgɘz)m*(G3ne9rzf~Zu<7 UcHd9"ӛP%"o00*,b`vHNPמEúhNd{kW힩 'j$͘/}̵,oJ0RR" H;S];1[b6fva? 幵QwOR={Q"CsM̺!#UYyXTPHDUNa٬ZÜT{1H'#rno.BDsȃߞA"m]M`PEGG(J-SS:vJw>crk q ܸ_Lz4IQVHL>ZZX#w s/ʠQ9\]}juXe7!n$ĉB!.č0w0ǽ ;z}jUZ+@h 0 Pa8@Q}R']_ v_ 3r`tGS[Ó=>O|90C h@מ%}}PM[ΎЯcڣ E@= d-E$>~dHV%h pO?3?9S*3G!K[@"?>_g3O _U u2o_>ܟ-gd4"~l'.?)x1@!e?O̟Tgus?9?*p|_p38~BE5Qw'HO1.-l9$qLV{ū'EM)(fAiS")eŠRtMZԫ$IIK3Ratw<؍Ex}')e[EDPx/Z s.ք9`(ɹ©eNo<4iZdEV!&C;~lsIzG[9+5c 8٥DsTAG)3*ڰUݵ^wѴ1ϗ4-n .4vVC2Sl, <49Nьز1Ft fjcGᐨʙ*il6SD )fKHNy=ᰶp0<)ۡ\UY90 B.M5搰i{Ow"P`ٙt{)0B3t%+8PkiyZE ޝ@;$)zɖ%h.U^2; #0s b:1EXG1beb9 WW{ECP)q,_X " tmB sJrA)qZƛB[\]C6ۂM{KFvCs߉caFޥ_@2$({$Up^v$- Pk^"89w(t6h~Ԇ~k*UM^51-͛S/7w<:H5>0k$ȗIsv?'x hKv7($òBAѲ?d1O W,f=RKC\>i5#P|,9e2IGŻ/xeHzgԮH ׼6c)eXYY._^r%A0W$-c?e\Ԋo^~9,r@ɼ8f^ʱ*_J}q]4ҿԝ\Pc^ނg)0LҭK6/掫W,W*vIZiUV*C&(ROP8Zp,(6x5L]X$R/ܥ՗f>'s9nJZ/;eC {I~FF&JB%bb&N_O4]}wm̼E_e;X!EZZInǢClGbDSp >#+r۹&hxQ!+-A'-){܍g)s}U/zJ 3^l8^Y~ŖkQ7GjTHі>ލW 4)_yi}Өg'֩b tW;uќB`7QPMm䎦lcQ <> XwB2jL x:*DHVz@>Sq ҈j{^ ]< t1zjcjEJw -NIU$*-B9ѱOR( AS&YI *GrHz$2fPm'WHkW})tPvŤg)3 _|šp rܥϼnb<7.+yܕ/R_rB%*vl)[[\GgKSu.:)5>&=qw.~oı[-P"q{=Px۫KH5ߘ-cj |{-SF!HqL G1Zd&fN;eZX3'M"IJڧ᫆ݓ"`uX.uKrF LWVFq38My\b_.ўgw}8˷ygߏ:J,_/`[?FoP5bYh_`#1/Zo:lߤHt?Dgf~h=, 3#=` 0_T@p#S+kpG,dF-}ёjaholAkla`Igeci8\7oml-t8 Y?/̀OK8`@lYz- 8^X{D7X=DVfMxP9;^x)dAvkT~z.< [, WTHfignx՜ZZ6=jei -$w{ǝ&w|@0 %EgXvȻQJ9>L@Qi秉&^4Oi8Td_*:8@>7]߽oWZ>m#mܸ\]3_(YG9j$~dV{}CT̞s2>O|9%K;!gBwX~`esLYp1HKGGُnEg2>G6KƷH(?Ȝ)m"w(=/j $,:cS%YWxuϐ*N8I[ ]NJA A[,:g-7V?pҫGń34.[&}έK pd(k]D"ӱZA0qw}âiS*=0;UWX5BGU{b}tF'#}PlJ]i+n".<,q,&Nk?@I/xr>ZO40mi&S~^ ,p%-%FFaW^ȵeJ65&!(W -tie/6yuhJ ef *8*+ma $uEpǬro 9uE %`}"F A:/F袶$  T)}06%/>,==1GZ3Iz@7 $X* q%/zB Ec0u'}St4U6dԃD4l(in'*i0& dAF_BbWCC i8KQM^+Q͜ $; ƬY-~ SmrBa$$jQ"&\6#^x#0- uk &E,a7gFI݋cV}knϚQu\x{P6^`G&kx1RMD RKeD/{ ={se\Wޥ<)Z&D4Uy!cVw -4$z4Uԃ#([}\[{ Wl}Ә')fN>;^^aҒ^*ȈO:ĮPgiU>"+知P޺GNU*Bɢ|ԝú.Sk}sҨvqwc.}\4 %} 6L6˽b'}G81fV\n]"I,U_pVsN!˴BęWt wN ||SQ)GΦ =7P ?nbPbc?៰B42#~wH2-,@%|Χ'/֭S=Km?7*UF>D"<nnv#w2`J\v>'z޺I`͗27l'+REϓ)"tV =p,q;[VHK` }GPk΀ uؤ[];:F#y5WԘy%ksnT7M"l'ꚿ[HI'| d|}TH<9+Kb}K7;bzkd}ilNj5#tgVf)2Hҟn`̠5At z8+JsK;#V̎`)\’tؒng߉dt`;+a\FE$ągvĭ5gkm04xumCQ7͍oLWRV_BzҨX%W-^7Swߺ25tCvץ43TP⥇NX+bҀPԫ%3#|\D 7rS:=Үɒkce KQ`22}IQ}u[w8vH% rf{TJ?l^K<@#<D];JCYXx텉&[w{OKm3%8|~]'я-?z]_o@ JA/=[-m?y(xL4os :A.)M7%?qʟ7 M񻩷Znj ΍ݼhv|ҁx`2ZSX8MClC{ߙݣA2o `BE TsA*wRlh)@ o,Z+E Ow9A{*ڃiD+0'WlU4]/ ?dfk =:4U1Ho0O5De< ي󇊿lwL5~c6I ?΍Rdp5LV HUq+b̎r#ezƧHKhى[xZ'XPăń ,x $Y ?3ŠPNlQCn//4Z؜.t,ɌM:o[o:Ŏ{'Uc5X<=iV= 5q3!ׅ.)ELr?J) S'k,vM8l -%\d)Tyz=<ä Ҁ:_xX&]aWj(ZrY|"Y% i\~V')"/l~-4tAK (iq`,5Wʧ 3AddG\{›.Vb‰[,yE@8xz3J! ie({a.RZ#٘}_J(R27P.YS\UTu* ǘ#m@:{~wGh&Jv[ub2bZ`cR@?ʾXw Diiو+T8^Y(wJ3EthU$˴BrzsՕYh8;X`/O i mA) #Y1\ pjAOxmKJgx:!BcbF֡fYYM%/ap: N%cD*ɶD-̕VsMNt>㯻e%!\0Yk3XWqop eF!5x6j)P_s+IעОң>MMwkqUT+3DSW C ǩ08qۗ>R4τ?/^ɐW'bR OeZeufN.Y ų`LGJhYڴCqNP؉-EYͣml tOpyMxf^.Wj͝BӤ܅(l }e<4:5 UN'j +{žjMkyE?Ճ 쑕joY _uLÇp ^Q{rwD0hWKPRJ_?q D5#{&'< u[U3$|9HvrΛa'Vt cgq8|Ηrm^ u?06Ta0.VCc6 yR!;=u->GIБe7{Nw:'Mԙ׀ }~@ "Q|7ovzU6Av"-ҬiKbѳZXVQ+b 2ysbk]x_x4'߂-Ow_-w4C=:t-) JU3h$d19'LcA(}5w{ȸ_GXgd.w4`W)*އQQUְW[uK_- 7yTS!i\XʸWC;VAZ;ۆgE^Yj[loo ^{N^& ?qf Uz lXY8sO`7jxp.\\}Dk{9_.gtPO74L9*,6j_e.́!?~8f'v hÑ@xѱ]'к~v3&ȑ譼|..zh5zڜUD;)]Xl-Ӷ2F+y\}+}_^NQl=§!𲻩)l+cN#"ʤ(a< qGKv@t P aA0r:xה#c|LQitF7,̸d.H)J"L =N; i,Y ٴ #CA;x! =ɭhV0ƞMQ1g>RYJ+;x YFQW4I5n!0:X U-;lwY\ᾑ>`/ <=L)nep RSe[AĠpx?%ہ˪@vWᕮ,Ncλě{NwdrGfؑ9Y8B:H-[76rPn(# rM3I2./_>w5:1;9)GhpG,'$<'jcAfU[#[{q+ڙr2QoLUFؕ.Yfkf{zv(Rʮw\}(OqC  Z (~\~}фpXu 18?w&@D@AhR?;3#REn7To@f{_]J?ߎϣ K ?|, t f4?D}b V7āB\-Rs ?v!扼wVimc#Y%!j\Q%D&&Z[zn_V-^vW P4_5P#\ZH /\FHj=^^D-du&Ks04=+(MUNGg-c1&HgڀB:ņM`"$zOH#1vCLYoQ1u2Gש%Z?|trFŹk ,4 9_jAX3D::adWs*,ձmh_lU)d@=Զ5$d'~T{9c'vPȸl~̻cEs$\/768A@=~:EvE򅼮0+,Ab%uvlA8 Ļ IO!^'5R Ps5#c;YEi&s~^o1ÁзX`b=\7Q0TiGa;aU$%3E/ ofH+qKqRsC#q۱F5eN}$qW;08! Wx pd=[x^Y; (mjse2 {(ޢJ mF,.SO4taȍ'ww:U+8Ror)n9ٲW^/d*&0{úx1*%oU0_u掕^CJ<]q܋'IcH!(3c1^mʹs"sVg1p\f&^ oVady%~.]I ߴb."RR~>h"lL4V' 3~k֖Xr4ӄ+=];yLy}mBoU8:ͮ`<4k[j&3a>!3E'魐s爗Uy73WXWag~'vhya?̡m Kx2ϟ% Z \0ФDU2(֡a_"~@ѓ2+_1u1\9t'G8X, 5pyq a$So=v^0JoRkא1?2ZKt;'rI)lRA2Po5Ǣ(/LzxexMRcԃ)dĄ=߿1I×Rf̩do0ٳ9YFD%t#n̺eda WsYF*OCǺa]cf'o ఄ>/}0x =H./Զ&+JN}OΜ"M9R. 醥CU`[(,MPtjvqԉ3% ?HA NޑA'!395%"<3JACfW tv4s|b 60>}n|ؽLmŒ@+B5>RUjpb l~ַr ᛿WS6PIt @4gSZrXe[S>S3!si0<SbUKBoRdU4Rʉ'5Nҁ&A":2 0Fݥ jG&/^.j1rӐ1 W`RfhcJivg1$m0iFIQܴ#iСc&! /&g"W[>ќ~W'_F Ll_aWi^|t0з&) X,&&&剑0:{##}(mhl_%4W-v&Ihi1z?AtO3LAm@yUN/>]{Bfڙ`z8Ȇt24G=ߡߪk!JS.}<}J\g3~_T5k{h;FD-QQe64nǥ~go4gbӉNˋ)KFETBڮKĈ/bS>^; /mޕh5}/BۺZy*Hn?) |ST2x#YvUy3̖{;mI\"oY]h(v!/. d7e'zHs\Osa}it0v{! #}A,fژ BXtajXU皭]Qt6p0VL$T-([ԵbqP^D*pՑ5l+ѝ`U'@*EdyaڤycS@cB-<}q IX`UL5Z|;d]WKKd±Έ]ۮ,[ְ#DHzfpf# n!M7VKy;d`;kh&MGFHFAq#"6xmhJX`,Gԥ { X ƲuVe2}$nӨ]ZAp)FA_A `ayO!bH=f*MEǟ:tԜI6{pVT0BA\u;>P Tf:in״R ߿77Hop6AΞ­2&tmCbθ=5ʓ^HZx:E4*$Ďy>ehy$v%zRfOZYL1+hjiprRFěiGcll dɕE )g8XA|&mӶ%k1x ]qӭiчJCs#*|YTXL2?~Bʘi gxc +3"?1LZAH"pv遼̈ Phyiu](,?fӓNM2>h;s8͝y-] %lapܔk~.U3$q7GJnHp dZV?IiѪ| sF\Y,_ݬ ~0L e؝/DX(fra@K*]~ OJ{3ɢ9]BвR7w>dŮeG Cǡ'4z6?+Uʳ{e{?Mڴu+uh]sBX ySx/MByza#R;JW=t|hmK/ŀes*lٮǭ(BA*$$3wMD4l^gtΈ!@wIytN[j"wyXKjjw8{L!#YgQZy3K|咬6<}wUX60W9lPp-ܢ2\)(EMKM2o[Eˀ&׮b.d)BoHM8$l |>!b^yCi B*}ziX}m;Uț!Q'T $b`X =R lTG&K(p%IPOaܹ;;/6.;h`#NZLA1t> :N0U7˚=jpn C p7JuܣSh>7Tf7dzQ/Yz|ٮg; |'^*/HG{C g`z&ErL=t I|ȟW,1Jܘ`F74crAN>\3H+Z49BP)'ؖ4!K\1k8[q֛e_` êJP0MFs7|!]/rR%!f_s-gt!`_?uEL!-4ݔwmEdPg0k[-<>"}PޔHF Q M zR_#@3۷?(K_|?q"ov@WfF;冟l=oU;[w/8dߺ{jΏ뙿w#:(z=;7WF@'cHp?Y[7I0ߺؘhZcWUoKLՎ~3_U%|okTE̱ ˦eiqD{1Uy>tHCu:Kx:xx;%v؄"5A#J$"ҕ3]k6-<ʸ#zu\fSh Ӯ=Y`й4T{yO 2c&>^daE2lv8?{vmy;sϔ0KML4b::)*=mMC/{u< kF3}M&(_F9^f>#!_ Qqc(x%VK?P]6o|$864C^3p춴ܕ;SQKĶw׷;886~y* يQ 2񁁭 ڒ仗(I45xuB9ӚqF?͛Ue6ՕK/ppnUuwzpꢳx(ͽN|>._>+'\붑~+@ s&DB2?#}o؟}$_=|r2^BWZ_y'&BSSSA ?.6d6 BYaNB9Iokk y:%.i& OԺoefjT$˩պ#5n8ry3M6msqȉBtĴ$߿˪wx2˸)Ƙ3ʨ=ZE^~Y+V_boAͷE+---cir ^_$ ל.L^Nx֭ґ/WWc u7TΝ+kc*Fz!|N/kx~NJJ*f9y7LdXU2K#y5Z߿/X JYۇx/4;Q D_EFJn}ۺ~iyRf2x6;88hr rg[ָ(􇧒|)s33e261ژ'{ 3Ar +/z_011 I}Rֻ5om?PVV/'|kIJ2UlT #jtэEV~gKqqqsG=Y)"ȟf@%]r&c6neĨr 9E32zq5ƺ.JNI ݦbbbn}t`8%2 "22mp="#[#Ч/yne*/`{ڲunPJ#Z %]g%88Po=tQ~`O+^[Ո14wF܍pᴗU"X+/?k :?`ԹKv<"HhsUC8vGk$88v${žbx ``hxs[A T>~1^vTbbGجU8osW\kGPHz?r\Xe_ED𶏌P;+xxV^ 38qY]tyiZZp.,aߢ`%$&X) (**Rrܞi!MOO׫>NIKK"88R%aN>SC[ư<䥭yee%څMs<-niʘ'AR=谴uN As}mb{w@ɰ}ADDĹK߲za5*xTSSmg~A$RvzQp -׌n=XMKT)0'{ܒl_̥A7fK5ۓp/ϓ`Lk-_#"._ٱ.i}wr~MIIV{9Gs^#w<1QQC*T[[Z ӯɫ G'''|x~uҺN܀r{tEq1_糙h GYw4NP;%K>j=WPSK'E V***++ܪ}h(uS=񉉉Hv{eڰ0FضӅS͐f ɐ- y oUyi:;9L NJE*m Wtkd糀p ƫW^s sYZ*g }$QDzٶU٢KJZe<y;=َtI(/цSфF@E2|}O%?X?$enՃo<  F"q#hNw(Na.6.Aw}r,"6lgcYOo?b5OYE0\WbHHHlåW}ڕvyy -nF_;Z\[tv>]?b:|:݈(V$>6B^9vX(Ŝn#V YоG^w3^0&6veY,}AVɰK_}^胹)ieV5 ګǏig ;/kC[?YFbb[|-luiZÚiʙ`*cKm1 mvܥ.{}7@_5튮/_f2VWm] -lY:Bjt@7L2Vaz뺝Kk\444[㒪h4bޥVQ;ĕ JNQHmraKxȾzRL'...H~!z 1%x<8Ck9 `#w`:܁*S@SU?_EqA酭F4~ONNj5x#Ad44dy]<.,kvvN\ѴN ~xU"zD5 Sg;Tn Jy~`V!Ͽ80- $_CCg{MRL{"ߩWeeWSJSRR2*(W*6 $Ǎa )>U*z•4+htOX "TEG|4ib.+R#YyybtttO4y+- %GFZsNyQx19|k䍻jgAgBaee.4$>RWTdl|V6UCUz;Q˿Rcnꠤf;7OEIī&X‡y,#!ZA9;rn=L++lagݸ5eV߾#2R(s+̜4HAl*9x=f^iǘ;?k=Rz­vI)* y@<2Y\9TJZڰbQ0t%9Cihpa.-78ǀ:cdu8^^4cWO\euSGy\I !PS[ީNKS%%Qo-rJ@#9'?<_opx߿ LZ+b}zM!(g?i-s.zܨ6~V@Vq #B^| v ͸=9Y!m:.2P^CRP\&o6ɦsɊ1wVSC5žC5LV{x~)i\#IڰzidooVUi^ C#;5[yRՏfbpGG["wʃ-yޕh,ZxmA/p +, NVK5&5/LwvZn8ߜ`0Rҷ3ۄuRg:Zf,nB>U$&..ef:h9?V^DQ?Bq;zɞК`8to-a !gJI22dP.ؘQ! @ApTr >G,+s6?.hYʁdJ@LAPՇ [[ۼ<rkh]zV"1f'|/g'421jbYO&'0㌕Gf]ʖ02j .cAC2qF4{cSKsAkA t; Ւ a"X Z5Qy;]wvתwtkύu$TC1bS14ݵ8J[c=>N8U }n8;8hC%}6РuGGuu}?rYpڜYn EOaK|hjڢ<|3 c?݌\+xSZzmcc'7Nc"1myd0~!*-}zh'"w : 8ۣy߼dViksgk4L޽\Fer8$8 *[^^հ)C.J{9רey"ݟO5~e>_sh)(.QjZY nni5*+vxMZreT0䧕[ZBWO&(';;3gX,^{U9Yi'+; YStO#|c (L%E qmmZQN`n8Ę,-")!ѥa~?$γx4ß 9:tE&}:Vb~R5Ɲeh۞UE!ºv|miqINxtBLD*LCՇIl[@ 2~=r88A<|\;|D] f \V璒^#}>{$CJ>y,hc0h]u?ܷնԴ4iK+m6z˴uXX4 @)oh*M`g,***jjnzN`[j|wJaJIMKw-8jGǡEccl:VClG\5==;!,`~k@{PPhx-^͙LpFJ( q~U"{nU4ڜ'pdku5 oD}fx0:,1#C46$LVuGllZ<*_޾3(,E{ӥQ,i=''UՌTҒCN~CUxa\T,CNvg{\|2"5뽍ȳ\=vm>ђ zon7f o<~nXo2ߪGڞ_Fj=IK2EVV;p~4 ?h6-1?_q'@SWW>+6g1W1$_OmuZ[AYziO!@LTZ\'C,(, Δ'KYZf:yNsELXuqI<?`?Ç~]w^;c`l܊u6g@yzff_>8ѬHe{L4Fӷߠ4@ übߝ54y/I` vZ̜Wd^_Q4|}QKq>%!!!P<7ŻL@:'`~ S4\ZN>=0f/V։ 40ɪFԞWuxSZ^;L>{A󩑌/޸a߈Phatu8l$$aC95K|3dadd$1<ׯ#5,L ]ˈ?E qEauyW? XR @O%/Qq}&9 g]~"U.O\124TVa}o0ndeeSpߘ焆0}yQWk_ Sw/]JuY.z=X3ОWȎV*h<4ZAkbS,رk%Vp%>Dm)t jxfXá힮Hr_muT)zӇۘ^xۃA+_nB#Ltρ(BEY[j,xؒ‰Ф\ A;N ' :Tvin0 3&W.yI>LkV#'LǪK,gv'|H :%)8~&; uXf{FFnv1yfڗQnJ4ޖxH!c pG\״^~(O[&P)Y7Dwcc&aum؏y+@kӣZ8pE`aσ箠QߨW./1.8-cRV(W'C T3Gt(3͎4̶.3c>h822rsWC V#߼ysU-28r.Z(V#>l2"r,>$AT\MG@022&&| FbC$_YS rM´Ci5++LP5 yպK<=V>ߙeA5 h]c*b-.q?_%ֿ!̊G›r40B 3`r%͞@cxg7 PEpnGtS^. Fˣ@Qpq5h51G,|8PfGov,l@)zzu%znڛ&`h rOϘ֤Ψ˜M֭Ÿ.z+ zzzq7.o m;eޭ|98Tò6}|,^K<@ eYsr0MiڀUw2& d{+`vdU#ʔjIhՅ\U Fppp(`k*QLrD{KOֳB +hU*fLKIi2*6 =*FI(zgV0%Nu}r,C6A${ NFJ6 ":O TW9cDѨd%G0:"*Fu }] 6xFVr_S}'!" $,8HVj!5ag-鉑yK#g(pH0D05z,Wyj;10`QoRaZ{*h3q2f<̲6? E'o.:VvgL#c%za\V;dXچ! u^:3=Z0},Ʋ~" hjYz; fw olLkl03UV~udP&g򈖔 ~c"CV7@2 +tSJD T1oF@z/=Wka MT0k8nտb5Rb KcAg`K 0vG k<=/jll߆5!=1suELEhjHfn9t Zع$SPܳQ5 im^;ń!G.]V;d\Jk P77x XPLe 5DMNx4Z):}(R~Ee]]!*s0$ Lr6`5G ^2X ]ݎGG?q7oX NRjt b9882Q~Fr+a}x)HOu4-έH 䩩`an~y`1GћՆ `r65KJ< ;+wSAI>㑿%QnP{sW!6H[W<|oo2(M'qTYټz׹2O;2XYۻagj;տuXv/h{twX}|:Do,7Wnܜe0 PeG܍-Q.wN₰W+I} M?{4X8qPe ǫoaE|:"ދc0O//[թ+'.ۃU 4^3scg'WRd/{MuZ$gbN5//gP3R2h-ց1oS硡%Fm)kk~W<(Y2d>sqzJz٦=nAC_; T[|1TAAAw%Nܴ%w7AzLWB]1}׮]Sn1n"tl,ͱ+Yoe,=28AhzxTH`PGE|#SQgh䷟Q_1| `.7\pB-\%VОSo 6+̊*X_m$a?XsBfXO֑I{:/ Q`"<cb#_ERU68@XU"SF<AP&\wX gSM׹uxzDyJtSܘyb:RY$D]Xj 6ogu{xcν=Ec:G ,Xci5BM#zUWם ) QoPue$ @% D&U/7c25jJzzkqgE8QJ > y.SIXo_ahe L5Tn?yMAuS8f] _AX]kPanZK#K϶Ub!w .՝ѷqcyh~LF^,Ny:n'{ݬLL_`?["ez`k 'ȩ%O1p3By#pw߶Ԇ Q\\FUD…r'H:v&@&|(YQ t=rZUc(q32;+]s X2c%5FK!se ^;K×2Fн00 (RCD8TMDc-^x m[kka0[gq-6pXۼ.m{sz5+ rdfc܊<۷o.4B'mKo$&굽uXMD) ?,7v<&$L8\fׂ&!|`oh?kml=ZF##|R8'MSSag0HMAvԬ̺HZer8Z600(s-"VW-I ;_!džf7ʒuJ/Q|.];4}=={ydW'+7l,<T(P?qt&tttnRCc[ 9be׮(6DUƏ[YhSiAוN! `5^&-%USScj:ѓ*: aꨨ( LB`́4c2S?ӱ!g>|,[9uY6`P򂢒P5I{ ֚ T}V MIdPt{iB˚AkTeL'o!UMS3&:m\2sru`׻Dvq>pc(z7*B\My#.lU377 ]VOE|r- ut-0Uǡ2˘>{G^C9JH(PyttxaFH-_J juXnՓ{2`<`teV䶁/Lu;r/U ^M>:,(%7|+}N'>Q5R s9I𜫢XeixM!pQ6\It |[HZ4Բ_L|]oSEwm*Ĭ0'0|/~ͩښ`gŴS$B9/y]FmpҢ.$nv5 ʟ`zJ'8j40*'SQ(^z4!\ ]%i(X/ޣ;:@`@*qtOΈg7@PO=rBL#<6z=^Xwo |}TXll[oy&pc8x)`ܥ#w o|z4 xӖ*do=%;Ù Z7x9~cX*{<+SS}?"-Š u~dJJ <6{#M&?mcVz1z46bu7xskKdYcI胯VrO>=%"4R]vV}iV5YZXpi㝝ְ#}=2*"'?2AMg缢[[Y`@< 84z$50`7.MpEj*Jj5qP BOI>~n/-;H_@i>qɡ:jH(<2_r).ZL7=/7p0cbF 68SNL`x>&>@vg\T%s^x'O*7u_UWm-BbDZH_eU:kYĐk{h՞X&kG2~Ctm ÛSZg;%+]$lujK+ F[ .5* o< Clz)M_TX`g>=W ʺM\$9/ 7jq*= =*",U\}'v $^v1C qؔLP``-#RRRt| ǡEP*u;31Ϟ=[W !*,OAۻ! dqX; WujA^BJA7۷#a.Ai}t|@AxKMEZХ )*;+Xx2>a ]ħܧlձ=Pyҝ/GG&Jj(lг@d"َ7,,Kx\J'5Tђ^*@amxKthj $8aٱ^Gj87Wvʷht[_874Oմ'#p* %es~>ؑ{Nw7M uB4SvM d< E]ګb.dr4BPOu  soy%뼈 rrtD{g%{VAAִc{ !9-L^{h>3 xit:sl`|m-X.68YҙC"6ĭ0-ת<%Rٗ AyHt#kP)h`TlWUQ! 覂+g)iVX$<2?*<ŖEZ!=+hX 3y^Zu&(T:Dń{T[::ʢs$"}etXT6Q2^@z33Fɗoނ~ Ŝe&6N P{{XaGfɅ#8#QL:ҟO9OxB n\JN\fB[ "S2Wɥk = |e-MIpXFׯ؜X#C#󴴆ey=͐xO"m'shԤeN~CȰϟmO?:- C {Ѿ pqH"SDĻHdrB_"t{FPy?"ՠeW y4LC@RVvF Zz I*_6t_@}_~'B\%(6 )˭⺃%nC> ~H"C|FL.*paڀw_ƀ\h9DAr̀(] Q^rqqˏ4+t*|}=J6%lƒ9FB#׫pap h[jwGksW B8&&x׶׀Ӣxq]atu9#cOhnbg sr2y }uw\OdG& lKo@:!N"NBZ931 VڧQ,6r~Щ,,1,VuSxH&X pd3l,*Ëy;D[[xׄ´q_B9u1s'cw_ri`g^jIg|ljdLvy޽II()`:R :2 /feMWUQHOA?}w8}7%JQ )eg2(#"&YB QIيB%ȈyTW=x8[|kdZ QY|ϼYyƍB7 Cl\J{PE2)4QP0Dr':}(nR綿bD>v bK[ Mn|Ƞ_4k5%,1s] &'{`jljH;.]Ee9groHѧl{m>f5}.a[}m5JEvLkɄCzOϲU.!>wfн%К<;y7ʕX8gzU760ͲضSFjbyWQ^C%X(jrY½}}983mTVkGPrh5NnnO`<%}L*!* 3H>9sFغ=1E]l::n3:G^{)K'ã8u:RDBR]bF)25DmtI /_OaGS dY檟4<|z["i8I/ dF۰|.p>V[ѱ"2hz?l 4\%gI aDaX[k9tsklnreyo.M{wVV"vE|8 ^ ;}-ICQΫ8VvoK0:]͞t!׮}Mߺ,)aŊoNq`-^& G XW?}UtMr.GX+S2vAVbB$%Lw..+ܯ%j5Bۑ+ík))V8nhfie I#ٮ X@]K?-a:"Z);χ|$@# x &#6CNђ\p/,<YVT=A\j^ty4cu}cwG>x·VDmxKE5̞?g=p`*)q߈U\ R\w͛꿞V&j>F<$^AAwU#!-Mɐ!~nBWq#ʙ8XfV pD²"} % cC>nA#R\u|_w=&f`6܄<\|-u#g*~X8’:xyx\k~۾G$DONNxq.WY 1F77NPx&zUO_ۿKaA7B2vB * :UEvƩFt1Y{G̾s[VX7 NOk7@ ފe̶J '?7--bL332Cdq~BB\Aӿ>0MOiW ޭoyW; ʬ*ڢM|TGRST|2UIk#FWG#j",][xN@<=5WBS'.!ؘ={37#\IT %7ѲBޯWXK .ٔsB۩P\RZAqRBA2^9nsucX询^3В/ hskk}, ÇW{|4`(HGk:5(bViZVk7g%O, WgZSQ3'|#1  Er4NEQ"]XcYNDÝXX(7osk!LC:h~^r]ZgbGyX5+HIH 4{+ n;y-d/?=T 'Wx索]x^m)(heP<tiy\AAy6w:9ucK"I|j; ӗ[(co"A̯'==ڬWbSlDw\KGy*f7/9d6Bk>KЮq5RQhA v|k각e;V[d1 L vY8H[$2NAPmIQQ$F =~xaair$wBWDn2`` )::O-Ѭ=OM:4pXS3I< {NMW.\ Vʼ_|ͩ4E;=h)AniԘa5<ĺG/ЃU%)B$,~1m%$$,6αC!nfj _ ܂x$G :T^(EȊ:vI^/ۏ󟴶pA\f壆Cͩes}Z BQ].W ^|I#gECiATgQܚZ&FhAтRiCD7"!Y?oR6  zy~qQѧ \%>pN~QR!p:QQE<'8Hd__~Y-*pҨ9F:ƍ=GyԄNO=vEpΑޮx@ƥْHD&#j7 ACG@͍?5uo'K/q9Bj:FMOM&)a:y4֪5QH$_oi*s|bpܳ{D^yʡM0~~2Et?0IJz x;( K#bueX-6\zxS6]GĥJmaY-ʂ2ZSMgM ?;( e) (>JcHo}֡T}ݷ%1nv'* BId Mƛ^T{#¶3VV_Жaq*4yHʒT1@D;OWmdmk㕨bXu>-D o_uh!:ꀻ%R8?d(= VX}a}Z3ԼrIޤc06-]3 @-*lE)HOT!Xe2bP oMlld`辿C+_MdDBcP?Yr#PFC]2R{oHy\DP3o #NeZ=~zs1bފ5hM8O GuPOߨSbu :+cqO{:kQZU uo+i6NʴcŎFz>yP$~95620"ݭjv=}xVƵfNpyiekڭeXղB^^9A;f}4R.O$jŏ/~P"vE#^! 2D@\oii ߡw>YBUprQL-T%]|||,U qfP}N*\PًߘQ/t$ޯ1FVv<~x"41kGrPiZ{ ~|1ͤǞϿ9u?9?t;^QL8 Kapڇ=iEVHĚBq;Ģj``[#EH1Q%?H<@3zڽg jXtH*Hz^ T1k]#K[ԽO=?ҵqj 'O_aj:$"Q6ݬzMw295;-DT}nrn`<і4xu|9^{ :U8l&EAγ0:ˆ[ ۶XR'))gpI7AB&4׹, Xfa®]^E_<>}9 O^sr:\!ͳ6UwdbQ7kr,tWn`P478JaJ{b;K%/jH)`SJ, >ѶZT[ǶZgO:4sl #EQ4(_fjz4SLk _biE۫ _6ǽZ!Y*8QV9yf^OלtxmOr0 7o {nd~Ob):e o8q)kEF.@3dLtI9Y9^)t6?/g<`NF[9(EQf佝%L>K2'ޱ@N{R߅Ӧo`5A 3^YӧDwuĺ7$z[ 2D6fbJyGGZ!FBB!R #;߁W/_Z?sױx\L)^g=رcw u"]k˽G53 "J0Sϛ7?ƛ!RA\̏}fO;IVeY~W;;6LD>]# 8q !''??j6\Qulb*a360KS:*#q%T){G0w|M6<#{g?|`Ec<'wzluYOr8崺ef_f8;Rk4No7Fݾ]fetd_ͷ5|mkӡ[pf~X/BUK&s/ ҼM};)/I3!N)E8GU&Tj<&FGl (_րDͼHKMVh~ڧ{o߰AG|xךE>DŽbZ Lٹ8;޽dYlԘnz0a(AgKuM/M_]I3HN)@ l7:q$=ϠԖ Fj9JϱZ#cr1 J a FwMO+x!ˌYu@8+lys++\;oj-"\=w1VaPԾ35Qž}c,Mw\!PV0Pد$%%(|λj> YH8 RAS`r}TmX5{ɿð^ ID!LF2ܳ d$cr-AkƁWs j0?:EfQBj$&{vzNiu$.?nX".hT,ZJME>?qd=] _P?p"v4hg|ц~x50I(ɱ xiTb#Jp`#.yp o@C~$V.EnцPfq -MZht}![aȿj|6ƪ-;3BXɥ^BG@伹 jjӧ\Qy4E.?LDhs*%baMF`bk|y- CX8z4 BIn͝pɂ[l/~U7iu$cg\?طS=Ոq&c %E83u~!(*܆WZf ’B"s2e}g޶^ةD$otVvNmΉnnnD^;}j9o_0S|~uϞ}D[ @8 5P%mG-n 3k-A8:/z]#mҲJc\%vdu" UY$&DCDNi[4}q剫v-7;Pʯ!rk'm.#CaRM1yH4]OU(,>V>vyYܶȫ.%k\O ga)xm2 J%5^RW]qgm靔 *Ja쳥rDfZ^A$Edb}ȃ΋<5{uNQ[h"đ?&p>$B~%)pgYmT')&^'ĕo̓~}FCzWև@TIFwaiw(*?cԖ]71:}᳼zb|\uRɗoq5&jcf&&{]NOvyڲ<5r^j7&:5? b'fs'ǟ?:tÉ,Qrkm,*T.7Wx.@Ǹ!{x֥Wh|e1djzEuZ)G3-b&mmN[O1Ifg: N/CUl/+eIe6a!`ЫWnW#A)V7_Gabʚ[n< uUwuJxhhfU L g^V4^zXdaK3hw"mm`#)Tm,lSN<a T.7R\ CQǵ0wp^x`'aԀM=r=)q-;*@gd::k2oAwb-pc!͘-ީ7J#;tl /TK>V&Z- c*}Ewi\0JD>?M%<55wFLOO+V0\_}BGʅtO~!ߧDԪrtUѵ;#ꐤ\nMqyZC ;TYۜz{{3i)u ,P''s 2^~t=[gSG(rd@D$ F~)8-p~ќJ3\:CltpI9Ȓ8vɗ& h |踶08===\ l9:I(Љ/9~CT3^] K'Cs9旉GV/oh~I@dݻ|ghMU~} N~]\ТU>^UUuyZAF pûzpPL+=x8k-N}+,(svLh4OPScQuck`r* i2|kӞ[̀/DmA$N^彂SP˴aIeVeok𝵚)t~16S:OuE F_~ZfaJ骕3SuW޸( ZF6ھ1- I f!'+Pu䍑t |!Q6&-Ux2!^RS}[D~.㕞"_!H\B vaKZ&SBC V 'KgccӬ .{vC\i^WUl~]:;a"8o X؈b_aL؊G"$PLC&L^OQ~/ 2sʞ,ش!TIn}9BR[ PFsҸԮEиA1?t=S;)A%I%ɖ.]W1O S넨qBGv;~\[LVljL4 wŤy~oK8qHN޽/vs$A- R5b 5Ve=cn=UT(Xn,od+u;YS`5 Ou Nݼ/&rGo?LD2F# bv ʺ@ˤBAR'†4j=DϱW0 b`^XNBz[T1\dҍ 'ʜ5O۲m4#O38T\X.'q]:6{B,z( y_zreq8$؁ :} WZ$Sl;iGY+C>wxxS5߬5̞.hvijᮓeqkA-(ÿ⬁D=8ef>a}v8ֺcXBz}!ZN#Aܺ}Gq\pDL Ams^ADMz9>j]g*5#'0 ]o`XݍkCv훦MlsZA7a}؋*ܜd0/T6h==uńQHH輀 b#ǤLNLL ?HofQԖ%[hA7fD4F7Ҟ[br_tN#r'G HF_ (,{zŎl5(6<[R"vw91́;YHIןhPg2oVF?E.xm+fAPa4ixDG1!Yl3[QrALj>;fX[[௺ɤ]iZ=8h_x̿4-z_=OQlalW)oXԨhKj=X 8g} !je@]v0EaK\ťy/-{%Ž6{OlZ]Рv[#6Uҗ31{#wPVڥNO!!c^?݌ƸRAYkr 4Qӻe}IIG# TPP c~g_Hå1V檵mPIg6|a\Z?rkDkx;_ )rkaiySn 0h&Y%~r=kQJoE6pz} ,=x>"Qcr.4 ΩD}T@[x'ۀI!wW͊8; TM͆rRK,y RRS]REӧu`|dHj'Fa!b/%=Li~_\XKJQ[t[b>'/6>|ܜYvyv[[[U/^h^@unNQTX#뭙IgE $/_t\qS^,('TRC.H\x6 %2n ڠMJ^&BS33kdMLr6:*)xSZ1& 3J& ChL[^ҟaukWD7***WSu!ǗKi&r K%ԿԿ dH  i|ހ%o!6cotIi:f6fO߬v]BGR vu=$(ƶȣӯ&ɰ2V=T]_FV z6ٕdo~zq O s& eݣ-0iiwd:Ҕr4۱*ƌ]iA"AFI+/8.EWNMM!Uoh@^2)b}W'*4 9|] ) Η c6uDE#6.}*e}܃5N8@qe@埅xM0|y}LDnCytgP-Ζao^wԧnhƺ `p:[VAT٩0M4 u^(:rDK`-]}V'uq @:',6 n#mzvetdd C!ʽv:˶F$}3kuy|H > e)|#KŽTXN!(ɃMo^/97Vm4Vi^ִx_ FfpqAaCRE܏>jX먃Fc]7isՊCt;]֕\Eq2"R-Z-")omR7xXA5\MԬtXlh.2k>fv |,"]5@ΝkڗZ7YW'C?;^y˩+-.T\8"" qHdHzG庺Wpɚq퉺Q~zwṘ&Gڥ[s-@PS}a?8bF2"~kQN K\">Wۯ,,#e)?ޫܜ&LL_!xש-R` & 0o_x%d޺'{_tY`Ї%D;H1-ql ?!x1%3mx]>@BЄ9Y(Ees#P6z` )5묺FUCGzqpNZOw"N6;wW6/FýV]W-ąHa3F|6K(.#la{ X @dh X_(-]u17ݤc2ʻR~<FU62>PXbHTaGyNa.S0 \F: xivvyZhsOYǡ2҅0AE̞4P^*H$Z@~`lJGb?0$an>]+c-CswnA:vRo\=;bZߋ1"9[}Do@3( NEmE+b(˥Mew ~oW#^уz#ۧqkv OS 7[N= 8˄FUtt1m_j1/@Ywv7 d4DӂW|p8F(&*ĚJR@D?;0Ă2rp8CЊ|R-Uf-U KUC\1h.S,kCH- zItŭЖ5' IZziUl&k%tZ\xDHd\Eiiǰb*o>a嵢ކ,[y[?/t1SD}|^䦞ܥLbϋ[ oP^n] $qy}rjl<sz-U$XK~ bk^θ =zhQs=9yy 6'z,x57V^ףB#TB(0g~(2)Ny|gc-{nvm=qV|&~giӤ2<S%$Z%B47R@C"&,55-F"ɺsJ]! Ş}.]89(l3]?7f)5^<*z^hn :MW6^m[6=a~ (CrJKZ]"9#tiUUDYt $(">7!UruvXN" 5Bݫ ji#_?!EY7ۈedM-x&h5!LPO!o٩S- L2Kc9!|=,3A#bzh#@p5 >P\S{yw2dPNx1bQacI,j?Nq0]!IBr=}֦ǀYnTpN[ 2luv=aOjvʂ;F|o*DRe o8}iYC=\JO؎2;ѻ]!38j^W;JASu= PV05^UcF5E[ga{sZ\l.(QRJbt\]+&&2p2֒|OANQZkEѵ*\]t, 3?gR5U;ߡطqF Ev$GE[1,8 eILMc>kɗihybxwu\>D~2Q5~uKKƣ_i+Q#Q[8O=~&ִg (ZME_gd.q|dNn;ɹp"4wΝ?ofS4<;n Ç)|rbCq Y3^w~`귷a[DEEC钐.0D@@E$C@KJb!Y}~s>703{]Z׺.!w`md6h_"1׷h߸,QC'6\]'uhh{INla$)ٺ`퇏 "<!/U7#)#CmN6H*mᵶ@`o?+FҍDqW*/Hbӌ,{{@Ja(^[^.RxM&-&fymzɖOaWPt(pЉh!dʛ& K }[NP MX#SN.Mj?<ߡZ8j멄L1z~,+;{HA)gwh6>Tݳ#C8T1K ee0Ĝ,;cwG,ڑ+ 8*e_(3CUu!h]N 0\c|`|7 me "տۂ-ic<abdlstݭx_?R x hۂh$poוr'Ggڿ=jG&WΟkoz9^_ BqaX`]>%@fRҢv\(精yчpJV_0 E9Ϛ{[h(py'nZsYt?jԈUK\i|v|'䦰wndS}:imW.80_Ռq'tK1[a -Vd6p 3^BA{ϡ &DNmD2&˴+l1Ag-,fgaxS)ik6Ze0Ϻ?Xc3/D&-DMLf a<6TWU }jz"Z ["Ɇ$Q*"-*bsZU )س0^d SP6H}a&Qb"d(W 1;mڕb)!A/LNDmz.!Lz|hU[s`ܽ^Wث` B'"I]S Z]B||kl!8(.?\A=)zB{;zD2@`5T{AK_pUimO>yV𫄸4@GLpg{qM9d;B n\J |9-j{ЮYJ5 2Lw_ 䴏NXp@a }i_M?yԄŽCŋW7 I] 4:rY0=L+mI|!R}uyZ'ك!%%wGMNMhȋq}APJ])rI^8K:ppg+hbfkUI1[FQh+;Uif>n9c9=R}("tC$W vr5  APu3ue `{ZB=8Ɋ*#(|2UO06"wC2 .:XfЁTU (p"Ѐ'ۣƥ)(x$E,Q~A)[[8:pʱ{@+IpGCvwfB C.?>s )qޘ=S춠h!}.TCyԗ>+ Ը qplh3x[wz~̲2@Hj6_oDȬ:'o !ЉZzi:-) +NPϑ@w $.B &&!_d>dXU@a2Xh ^vtBv8:4hѯ^Q.ALy]p0py) S(dyHqi:Ap4A\9@DVaς*ᧁzH_thRtPEf Q /3xξ>0\ 7asX*fMkKKnH.vMyie-=`>Bl?=#{;9@}N Ш.b7I=^;Hܺu tzN7|HA57:=9^ԡ>W8+OQ˸Bqqq0ԙ,,- cWk*م+ȿS+`]#.k#|,+-V zȣ@q?!DF4V\=L;{e D}p_@m >)E!++>A;o`f`/Zw0Rp住ԃJq}c|!$oq)_gd'@~,خc\|&E5iPj)lq`#:ei677{'% VDq[kzx#oa6\2bhSZ7W'ӽ Ѱ4_q1yf[[g@`buZgxJhC+eSaPpr`a5L3I{ 7ᙳg *P ?==$}"\B RQJϚAskRjV=,@⮫T&-Je`h]{Q#vfBAEXl7^rǴ*!^ϿWM:rAN5[KN 5f _"ʤnO&GsopN.\@v(.PmH:KCW>vDgw#ุsi@9dZQw?v8NQ6eeU:۩yV]j8&l![lĶr.Xkm٭#0fzyYVaG!WА)) S4b5O޹QW|BjJ0OyZzxy;/`ehPI1sS.is͡-t_ЋA|sH?RL1/#(™82:簶?{$:˲3!4OCDzWGd5}Bϥ>v̀|@dע+R52G{3f66 ";eBzjG.U9-!|ʼCUH38_Ȳ,*m,msg '3MIHJD܆)#Rut04h()#YygGhmb .Az+]N.NAeA"MUw+w]ړp0C?W/ohYTKN- O杅Nԁ9oy2Cw$`cvtd2έ YA2 M0.Rm"XJ[~OgzTYݝ3UP;5YQ{tH9s-d طܐ!;f.As-#A]׏Q!_LRj]5θ{ %2GԦ`H=a8J5wFHNL<=Z05 ]de| "ڞFY̗{։^h#w7*:2O8%~pI9W`l*KtЫd?A~*mh;)Z=뢭)ۋ>@ pqhIXfaЛ-&Zj U-A]$]6̱u,?s;#_ED'r~8i\>7]&VҠD!"mH?@ïjjG_(D\}16βlI7+lȎbb'3llu<gU3X9P@m!`ZګŕMB^)MA M0p%B81]$Fz&EEk+Xp!_k(G9p9^w&+gނ+Jڏ~ ,krjcj'\RV@ EWWu1DQic< |ĶV&]3̖AmX\tsZ|ۏҠB2 y՘|@e"ce@ 9) DC4dl׉"## Umc؆n79yrS|{ܚ?EߡyKL/u.s`-W _~\jWTll9 %{$ImOf[k"K+Ȅz@]ϙh0,dЎY)t53Kֵ͠suLҗi5XKK4O.(ݿ~Ȅ8(LEKo3Gxg错"/VgqG_57Ooin9g>Ȓ~ / 흫); B*>p# !HS&A*zzDKe&گ"9 ܼʒ$?^gQ?9yаaCf[B=vcp{\nK}~1m9tgo?_Tր'?-Y'5= ^soAÖ mU>xo뿬!X )X{Rlpfu ѫ++@ MϿoJpܔDC5RA q{h`6@PCDD/ 8j'0ɆILenM3 if{oavPGBu h`ZA R=reSԐFNa?ױ-KL݃IL =s,y : z w}b K"U! eRH)<:;%F\xZ:= C=5l1N{*u#e(M=@[/r=D8+Mz-ߚ% tV7I`n2@oPv(m=иIql4WXuaZL%}3%%R$'V!@l;<>So []6\@I:( rNaY3  ⠐nBBC3p`"*Kgnsd])lL}gzx]WY$^(<3l~YgPfL% F!VGGG!3Y&Q0^Tm~3qή %YXn+6 *]WֺLlC6 v$Ձ`8fihbR*@0zj0Pv-I7dP_Z^ˁ< ~%xR2`ӹY@BVAvJdOB$^]rM_@H mMWdcU߻?}U:tM ΄N䫹T'"Zg2XALҖ߯ﵯq P+WR6@B".毵j?eI"90 .WH٥@'(V=!J 3g-O6Qyl;[\zy`Bod.jC$?x,w?orZ$7F`&ˡu@vL_yj1@upHȽ>jeuRE F͑>T6eNi!8['H }I:OKNMy{?ُ-~ )Edh!_i@@KQ TCˊmڊ5rCNphQ3׶g0.Pȯ4ИiLR Y>t({iv ࢮ,B IsTW#y/]e UwJrsZ7mw=wV#;' ;+c$еA67X *uֿIOriBΚ"4uSs.x}ԁlUlǞGz9qnǯcЄa+kY6x K{zB m)Cɹ Ctõ9W$f% OnS<{KX7•nȿ彃?}ZN AM$o.Y09i* mq^%,ik{*#S8Dn_ I\( Yd &$JVKH=KߗALwAv$:Lǩ Sb4#oo /_Yv#4 !kpdS*v6FEA/@6Odb26q׹dB*/w` 1==U$$6Ug-!8}*÷Z :k%KDL< :X3Db߸݉q۷XL~ǔ&d'Gb:?% >ϕ}WW(a7+lݭs"6o, 0Wģ.߁:F.iXyWz% ϳpw7637S2 W0ٮA97w\$[f7 {xz4s$bz֝H 8B=bbՀٚ =))Az @y!oԙ X(=3?j\C2OIXX(i2;I|kN9vQjÂFcEq(A1ƥtB9QfՀJpxUY9OѺJOgA(z\!"֭YBjB`d L̒m+\p%%%+έW͕ kV j i78ozf7ӆu9Ϡ8\l9FM9 "zd?U>d>/>_|wd &B(BJ͙" qz @|I,i JA* 3ss {`9QHE\yš RB@tA'EhNv[Ka5{hɏlozc zN64z^;wTy1E3:Q>&Cfi7잺@[o &2& , eC?'0XCa%_AK/.\^Ҭ(KAwZjF<&c5NVHa~:2'I I:3F&:a5VR x2:g6?Pp4>>\E"VENɤ3 Uq)} _Ur()嶞AF)5jSun w#HbRS;Lt$}Н&ƴbẁMү -~ AP(|Hx@:\=Rj'Sj\NhBB7ʼHR^'YyY!؄o,q( FXضLNPOKI{F[St->Ks ͱ0 B#*9:hW {FHFvӺNU$'` &4Jvr@gt-Fl@Kw7w~W&"Yu h2"f0_u"OQ`$@ѠzbQqGOY p|X#qߑ4w͝w0u#CKWo/=vS1ܮB!dTQ񋊋'-R)6@?p؎.h=KBdCl }u;%ap?tshGJ># 貐SPY|Ӈ!Nv&wyMtx*ȩ\/:lG!;4j#H6="^)p#"G5G ?AE[Go(Hqѝ7I$<︥HO_⭮Ym PP0/OE'b/]K1M IwZ2sn^M`i^3їʢ8 x֜o jދi*@M1?+~%)*<{eZP$Z3`)zXip&M{([ ^c Px8'Z3.y{us|w`Ska򿰧/ i~)zq bl{[^>R.ןjTh~ y=( H^g qaz0Z'*I9J17K+X.==q=~VHK'lf # iPqvW1wVd3AչSGB˘-mۨ6 4&KDA u|Mj5s}< B }QHY8vptnj]xʴN9'/_FQ?$qDbF߲t>BEijzu\^uF;é.C&O @0WtDP#T%8M+{LuO5W H?0Vxyp/I?zqڤ\E| <92AE=K \89@:|c6Wף$jP+A`k{[!}֜NF\ϱ czy=s6ڂз ˈȆx%_lS;.9:9X#?޳ed`)qQ*v(u{ƆN(e{NHY̍(XpQfN<[Nv66N(Q[+[e;CxC1csCc w\)&\~(qs+'c 10#uGDG(qݗi!5gk|9:^6,^۰nvuAgAIPZl࢔`Cbg`c`d򰱱m˓5E݄mLU^ >Θ)aa즬\k6^ ;'(*j~2<נڰLPgtk.#yP%"TI1Nl>_1(7 m%c}\EY$ 8wkZWU9V,pOXe@Vgq[J1H%#c03:%DWx@Y~^9377bn6 f Imo;x_aThM9dZmSЖrЕEUw˗h. 6N} OL6QT<[",*'^edzzA#8:AtmݟdzB]ѽq7Naqyˇ%11s)W0nK,eLeuNϽ'c')ۙΏ;"ԝݨ'lל?dw5w/{~&ް㎮N\Ƚ2O`TGn3<ɕ(4nK<?.X,3j3NeX,ěٰyz&'>1K(^竴ߋ^9gПcP! }M/ůZ~Wqj3ŝ;ŦE0KVɗY\wZ{qxr|JjT6\pˣ|>[)''oqDs{]`&>-2W ڼRt)ɳyR7#5~஗Ň\+Ei{,: z&q%T7}P+Nkʺgz`(͆6 N`7ߢ J [3pc:خ8yxb;uם0X [:j#7R\󬼣 ]><:!8 _hc.αЙrcϧ⾝ul0Y9;1%3X@J|G lBϔ[H)QIurtՖkӥ q>%ۆ5H'3yi̯i{[l&@QĔ2H%SN=bN0tB0V%Ƽ,ݵZ(bȋ)dN}#z"O [Y?:֟£%~v_Xg=4:o/J |b@NOΗM+R;p0r*}=)pя<-լ:xn:yyO!9k]T1gԟ˾|ԩW3۔vHg%5܅41mh˅Y9a!Bk7w[虜:eIL-_{5##vyO[rjztQZ$<ȕ|CZ3sEZlG/'.w;mWZ}(g^K&]L e`B_915̸U?vKQt5%o9?~EFpN)nFF1$(W9gE}АyLmػi{ZGߨ3R<r8+H/]h/uRGo[EmK|/DHQD:@s<'=w/A$*' {O~]T4zkLƑgcIkŨy+_#cLa~>ZSWJ)*t}а$:Bʓf9`zpAa{9q;/KD›9r5[^1w(shv;0(,'kLz.lJ'i{uQ7G&~[4:4cv-KkT-RRd2=ܩpz"Ԇr;g9?v 2Vy?lQ͔K/OH.6j,":SWImCx1_m4;NbS)6-岬b4}wv_Nvkr)MJ\Ak9?5:r-<χS1evwWRF `F ՙJG+ݜ3'sԼtHH%]]YalB#Ŗض. ~ RƞQf{VaiSDq{EvvD;锔W-̈>)8*,Os.Xc'ȏcQ8mӇ d:V~>ڶlkox݂6Eu0n;<ILz O_}kۋ3M ,GM-/5y j2F>Ӊr\~ua1S'~@&i +[J5' p6ã~ xLtM!>hWt Ie{oUT"( mރnn>[|ėh^ֽlxgqT& ԥ1J̲'H6j,2 CU֪=uݫe8[}0Ri*Ӹގ#( A5""i$=b^4"?ɾq7 Էo9Ԉ,xK)%Vo)DZ߇0t$*N mylGfWZv s$ G5QUOH=ML~û0y_l3ćOhq[O>=W͠2b!oU]ǣHK/*Ņf~W]|Ȫqo6縥 \+UNr2jִKhhèՊ;;؀B/5 mmsLdelSȯ^KZ<1_ZGR[DBUzO_6(x:G-"iSn[JTl֣Ltò,o$6ih 7E0;am.ҋV,z.G- oeilgȕ{GvtW;PRr矣Oа\qrR_"J-u׮O.{^L_j(FJk=ȴD )oo(>w305W=gpZər.j>'#gzV3RD  #EkxY ki܄CMUoŧ>uY[Vt+gG[WY0V)y|SKM(߹:S~[F8oK-䑣 Gl =Gd~r,٫N8]+g?O?,|;Kԙ}@wtENrܪϲ% '.z9?Oz–ӕO|8< ~rRSB\~xψyㅚFk[WnRQ#3չ I't/T^5x)Kum-x&`^68؏*~NLz+ab (}^= ienslX_5r;) xd(KoO w[YY{Ќ릊HV9L1PxsLptA07g? SɪV_ {[duZ jʫӄ5֓>y2A>Eư6Ə񍱽g`[aFW7>a6;鳐{'Կ1=MtOfh߆~%Ç @䵯}&Ǟ4Ɋ36VⰨ6g| [}'!AT"5쵭]Vn0ք?@ⱥR/Z`'n!%||/Z>^€|T `bVuv3&=s$^yd [>G[瞘ˇL<-T쭢rL({8 X.ܽ K>*2o@q/$Y!e{[[-a` \Mǹ~ NEU(J.R Q>=m\)2 $nvUvy >#jtaMdyܩW[2޿ܽyEPK)_}$8KmOoqɠsIbL[᾽u_s ˯((h/2( w n!hCp7! @yMMܙ;~UJtݧϳgLy 1#>^$N!҆X)ĸW="C8u#`|<ԍir?sKK:~ V^‚ab"JjRT L?){lL/4tFD]l:ߞr5d9ccbPxlKG5һ$L >ȁЖϟ$2 On(n#d\;oᚇqׅ> "j" v4piehJ\pl bBS] $ç<0Yױ胈KLj~fj 7ɑ̗0*+np3?o6E]E]F'/)i9Tu~08³Q08]p1k 4  ) t$QߒZ& u6\^sَ^c(eˋ91) HՕ##߇GePx8FfcbʪC3l5Zd%7Ӷ]\6Z9EQ DZcۈ ՝۞OS%b3iO$nΣh;Ufu۟?fwE𺩹xS4'al΀CޭI= D%1nN\ řSjKL?"7s7dA@b<2AQ9v*?YXca^wK^AC;מiU/*ꌈ!4⃝Ÿ"jŊ>fDN2>>tvb{'|*^8gSfSp*5䕘@n[[[[ CU*0jML9i/8>Tװuv Pc/M"&F{{[qN2 LHHcd"^ozk+Q]K{$i?uL $m8NY^ԳFe A;,BgGPFd#'KpW SԢ䲴Ơi:wG4p+$kYa. D)/bk5-/n'G'>Yk>O]1EbMf?7?Zn: [>t>u`Xmm$ <'? ~./?,,)MdHEf|CDd[Nj@J.F«7e BD_4 H#cپamHHGG/?'f#NM DAFPD@}wp>+=`B^:e} A_ -xο@ *MpP ď \|A$JGʿ ͽϭ?76QQ͛ (tUX^vsʞx6=J^R\P*L߀0C%i/Ϸ7k?fFFq'WWC7GKsˍl/j+- ׷RJ4u`-n /h?$賓7nky7S~7QوFD,SRxYK:&IŋG .`-ΘxS0mSN/:;~aX8hf.-qѶU 'ρ. L[D 2QqYh O/6 By |A( Xx tqQ̡aΞA !Ped/HÊZ&䠞I -֑ͥ/._q}LA t8H `QP_[1IZR)* i|Ka lf-m ;W@M_ P4"$DXN4 O~RY!vr6yzLLQd}ŴW-*X(/8^^& dOSr-(BLh$2bhweł= B˂0X['+SGh4zh!$"  72 86iiwg~!?hה;3b(~gF yV8x%5 x5$qK@Bt8'utҮhMWV22GBb"83ׯES56)=QU`>x00gb^`K///esjcY ы9$lP,,/cad Ve*zb'`d&3F$ֈP2U3jEQIhN$ a|}m|/nr`ZxLTsVD@ hn-inm-oo'3sVwar k&;E=x2݇NtOBZ?nESfw$gw X6I :(`mk@zXͩ\#pY+c~\\+%TE ڝ}hidNN Nz䋗Pmq9;Y(h%ר_֧#w[)u! jU:W7H/ q-Qc~=OA|] ފƧ<8\1VCe8" x55$- lOM(P6"<*"!(CB凍Fғi:i]sR{ AUuWv+JF_5)`:l ~H;ع}"U)HE @iHbR#=%5- w   S07tt:f."蕀C̉-*:lg0G eSgGO?n:u#:i@P)Lg7/@iiIxG K|R%e`V =?`oV12"R3>%W;v<% $I]jP &c[V4%hh#iA64$6H`RP?0[Zhz}G_G)Xݔ5 rپ 4"B:\?ܽ;ʖng͢u}Tn?싓7ˑgObSSCb|9$,tLM$_l b-:px!/+H@G\NXLԬ|7*;ggO0Ņe8X4*@*)Z &@GpQdLOyz`^{Y6\ZxJJ};z;hU:vH,j }q;9 _%޲jK`y%u(\>@jޯnFG/6fr뻒#4[(Zy )cGc2oTX#z840(g3kGK*M7tw@`7~1Gf1, ХKqkiMM&ESQVԁZE|Š&R2Pbݧ(>wȂ{Iaܱy얦ӽ@&XW"H\L~X+ <ća~e7T̲y&:V<&&^ zN4@ϟ/ƾ]3m~0o:ϖ11qFdTo[3L/TyA񮄌ϛMZڨsN=a<egu e5mѷw8h7YhVy:^! д` 坲ʡx^=\@0Dc:ZB{w!Goc~_ @gjת58)O4=e?e<јA0̰%S@` 7\@^#CUўR6\o@ U's8̿ﴕ6ַ ϐ >m)%4=gz39/ h{J{^J=~pƱzZ蚋˫[{\?&ntLx*PS PB\;kcZR\]ix%'H?N/ߡv f+?o{J'8SeSfEBܜn)#^z)Wxyf״5+"OY%K61n1"G8K#m;(KOy<-o7O8*<jE$xUqp?PSŋ%'t3RO>z]|j(rNA^ 'ʻDA螡-9l4߶(^M'TS#nB&y T٨GYG e+PSTHŋ*fy ;P-b"]1J<'ռ '94a7)ކ If^APӍw1͊oqMlVdtRnMoɗ7שR%g=@mnbUdY5I?TW@+=q2 C#Z~kTn0ߑvД*u$'Y:T+c1NTѡ~BRdEgYuqS_|+,<Ȓ،pe^8GONuUܶ -nH~VJaAQ:C\ieaq8O?toA`i+_ P7HkbvOCN޲g땖Ց6xM0_֟9*6hL7M7\ǧ;~7OҦ*T/Y)\j4J&(ۃ{۩jƺcOד-sI} D|pjN/hIhv|BDv^({o}G[GYuKێV.\zC:(U; mu`t_ #SCٸEL)7֛8Ⱦ%}S*7O^&AJZnIXm7-lq/hJ*16 WE%a#Bu)Wٸ_@+u=K&z$A-B3i*,>vvCr%9g7cO`~\.׊jQAjɰH@jm'kFboo10>?C'-~\$}[݈ǍO :a@eaAϼ|7$Q;\*^BTt:UT}u9'>; |ğ|1p;Kp&؏.+ h;uV痷fdjI&Cu*7a_EF4 8r!@|UxӏrWI= %ѪU/$+3@UU*nq)|뽓*sԯ6QpN ]ǙIf.N84%Ӵk_G|Ó1xf~ L:w]龟tV͚w>J(n,F\d'yϗf: >1i{E~̦rʙ])3[fs=RZ壒'CE_$#;bVĿHz_۽E'vKqob+B06"crQnrd\0/D lBQr{&ugpyk[.`kb }^`:4e/tY/t-^2DQ[>ݝEa"TLRߖ0qHd{/`C]~OTm}jhmLق4k֝797.Ր ݱ"7;%D?_I[&=I<ˆK%~.aۡz(vSvxAB>Z;$hxu׍4eǢD?3^Y`ovz ՐS\LᲡưCd-c,[p'y7`K[`)ljĽdoٳƦs5nJ_o:v1_3OXU#d?D`Y'GW8ooe[)9)߉ F<µ @R, V7lg׆F2]>NjjYg!_;CȺQd$T``݌@o/]Lhx s{#hf<1j<:Xk+X55'-ꮭSQOO&uH$KT>TȢ>5 ,-84>j L8@`rEc>qPm[ 0!ͥ M> ޱFHcM70ty-s[҄o F 71&*=mt;Y] 8u3hv1Zb ? O6 ho8^5mTLe\Ɩ-cx/ ylb˦yԧUpR6#&nI4`4_s}X+-eyfŜ9`WX5vDVN ,'VkS;6Ď|w3 ~*ê]ǀ6ex}a7.=P #.efDDz˨hmglQGn~tAw@os }0K/~ ,ס2T!|M '_f ZLGcSQćWʶѮ%G&%Djĺr5U47F[F<Xgd󑪱ΉoFpҤz `A$XJ$3(-;;2G@淙#ڒ7+i1cUm%D)qۋߠ+W~HF|okB6XԿ#`>32Qx] 2n)0UBt|B<rQ0sc 9eB Ņd0tE?ɤC_z)ykQ暃# n ( '>l>AYόBwP+\V-?[(LBWӫOί~~I/{j?Kޝw.42 9*[O,!,U)p^~tN~ynMU ?wZz|5p&مi.E9vS5a9@v6ʮ-tKIwarM)uqn;9@w}* s@E'T4ru-)E.:!N{t[4@J \1Z_4@z735:5'6K6]7L&7SA0r smԓf,Q;r}m}HejjbCkxue'> =*gwO/PQbʼn^#=Lj_]=RG*7?F{U(>yz P/.߻Fy{ P+ޘ?ۿFxy~U,?xdx}Uy+L o o o~8,15Ja=QFKQ*sd]+ӤFO~}^:VFgH.)5&qA1#YH崚1LSi KerjI-P5b֡2Z9fl&Qg$({*kWgT h$VgO֩2F9؃k#K;KQDIDK1DSqQY'A?&Q-fOMvs@[XɄQ'-'X3޳dO2[r sқsd%ci>c Ӝ2loie9ue72`k0e\.kH4U.kr簡e=nݤ.kjȚ)g.UeZդ.U7uNlI]a?^NlI]ԇgWw(_1Qc6*}%1SLmTXl2Rnfއ&7yjҲQރ!7ujd{>A0el̊sA HF{6ha˚F[{6xԺ%ˣF{6I_,sUV,]~|ie޷ wɰewъgԓ[˧F@wId薑+c'X+^ê+6n©#Ӗ{+ެSܬ?\Xgkk'k'FV<-2~+zu,ꥶe[n=3`l\w!g̳wXC7Ht YnV7DtLj q4. 96{.wފ=Q4-W| 53iv\n?} ~ 0o6Yn8~ }5 l    Aqmc*tr f(5\m:Z E3Ylsw gvqf(.2*QbU/2jP^D7fL{Uڐ^H7f|qսP^W6JGz_!v۟\t ׋ >sr57z4~k(^/D2 *Q B2-jѴ& ;MQ ;>mѹ&K# UUxXvj2dpѱ@c0e7M77%;oFwY{/>N5'n``@^(OAwYS?%ȇ:Wt_?%,7;gvi{w88w {Bȝ;4O|z kdwO1N5SHs_8i`_T{N-Z? 1< E'1‚~+V?1=E烈Ea!G?"O$c t~%5)hׅ\?0i7 ]>:CH.4{6!u|~dgv?^;EσI/F!E?"cx@"DY/T_ p@,_80h~|6 WB$Bnt~ K2%8n_O=oLmz^vy&Kܘĸzze .TL >cqy90ozc3+{`bߌ&egWMˆ_$lo 3◅3,ooo}PئPXp1僱Æ05T9>cr#gMJS$C0];֤ȩ8p1+?*3a*"楈k?2rha2#MHWTd_En ["+VI6*S\5lނ .lInV՚ S9?lZfVe'l]aVm94l`TɩL)\67HT%PƤGN UsdObZ"7 9ՊdMT7$1d> z%YQܠF)=Zl"S SMMuP|C-"Iʠ%(Q{ޞQ8hبpL.=ڊr'%PEdيs`#`G$W؊q7$p@7F@.7h}E/B`;h@ "\mj+\ޏ Q03(ѕh0Uh2N(hU}ՒfNV-`jӒfYL=TB+РjZ`̛VRպ kҚDVPռ sڥ$ZVQվ wrSuT ,z+LJjyV6TdT/ )Ts8ؒcFmZ?%(֔-PeЭt0T?AuLӟJo_!uQ3K؁vL2c&HvQL3NdCzjt@tfJtg5: _v]:AӞ{dE3Ԟv]:3@s4u)$GN9>u)&&1)"j?w.3D hf[&j'ǿ&e$Cّ4eLϑ;Ʋ}i꾒e%h%_!޻:cro%w7u仉'%C+ErwK2?E1䙉=%CB/Ir/%CR/FY>Uiցt*}l[W?~)ɭTYum _n]eַ5tUChֳ5rU|T`$ ]'Rzt&AN^i|"_SQhs!٫t]ffqan@TeZ;rO3*aάwiQˈWKU]KF$nPȽKOB!{wS ߅C1> Jr C)Ѫ Co>=5 57]>=U5 ݇7b5j o:z5Ljoz%_*4kLo_^5k(B7hㇶJ: K:SFb3- ;mGvIJoH80 AeܔIHeoҬO8` F +6p/S .rWnofkef?WBHs3І )Zq z' ,q< ~J0O?&*)ToK0n&߾}gEx#.dƅ 0 4i2 5Ho Of:| ڌKWex1jCk[|4Dp CU=yR#3ewNkuĸ$^݉a 7T- -SL׋XJw pI܋p  YٻY 4Z%o?h#t(ˋM#N4<`Ifx/ ^9qU`pAul ;}s#9C$f)ft5=/HPiZM{=@kIE a5N_&х`K+)ۡv*&@b0ؕp-D㺸a)~[>V Gfl!_}%O27zg$V·6`_yg=~,RUXsfzCɝ7eri:D 1v,j!b&E @%$@:>f.vR5$f 1$ӁmHT^3EҁoHR+hf <8޿Zm3Éw =fF'E@w"[s'/XlrĈ[^^R~v033~*fH L[ZNhy,P"] 0"QD@ 8-/o+`Hi|% !Dwv~~x{b!5_&osp7?Gٰ%הeuLj\$uTA](D>120?^Jd15&y'^`"djɸGEW+A+ Ӑ(D!Q[<SGT̐)5  %dy2|3Ghy75bU"9[k ɣGkU/q据mKpI쭼xI cH c6c,nk,<1kKϱ>ͥ&ئk>SaN vY9} 7`r'S+hfލ OTbٓ}5!0E ?+y}ه95]V,T+{p /z+ ̓ކ^f?½ļBS3a37v'HRǛCERjkb"b1WaC q.P:;(J !WR#8г@YQk$ -CU՟6Vr:}Fk Ǭq}rp~@rٔ%oIHus_$M6ovc"_uKIpО\u쥈T+ GХ9\cU-lMB4 Wm>ZSt hXoJ/FD/fD2=3ZnTcUS;+?0a0giL_f-[ 0'8 n< pbdŇW*J`c} qguinCibΡ; $aD[$dH)){Ξg~س_<ᆴloHJ|Lyo6'SE&6z3G!b|4md`A!B67)̉|'ˏ@v{^\J,_>zu#*DuX0>FZs‡z8V`$/cA KE4$gZjo݃LV-E#P%%ڼ#Z)3b/lZB 8X/%kkFg?<-_Uq㛉~ #M@Y0/C(m{I˞yV^=TqDpFN ^CGG+f U4,Y flԙs‘W 5yD5G8㽖i9Q AZjZQ۬ћdE/3IUAARe*rO`Cy4p#9nm`ȃܲ2<lV7|Dd˴<Ѱ;T6tzá~mAeoIn|@xcY:D;Y;O;d#n$]{`dGs ʖ,p;xty5rLQz!ڍkp^`33근2t,FZAT/[E.IyXB@]sm G1rl6P|FNG?x lD> o vpyf .nw(qqf~ݠ=~7%Txudn"HNE쌍~?0TQOiIHņsIYTEUc\e$l)E_Bj^Yb,^-c%乑S%Xz)ո5LK܌+_soa#{ fHh)8<4yiE /+LѸ=nIԯ-2}I}D@_HhA%fqЍ彥fm:g h:iQ`%h5 ;Z%FSeADȥiJN- 02bN%#)E R"8mb  S=uy| > }~Y,٤UY>wSMCΐӆAG<0藅T)QS}ALX{"/ْbhbibb_Ƽ ?hN2~T-a[\888444ʝ)0Kp##*5|o,X-5R`^6I(٧GK=TXZ>cѡ'':")*n)8%T^TiR_W Tt4ԩt'.yMZsw{OCGKvOdz*mqxqcwQ1Iqb11P<32-,jqh<OY)2yG7Q1=~;fEۋe2/ͳ,00p%z`dz(9S٣0000w|C9\Ôo2+ƐޑlDgB<('3pQ1Цx3~9H8W˜d2AliB0{1:Ps'2222G b'c&&c$c$sB2_ (Zz4-hŠ6E^c/;+s/~IH i YF_ˁwα Hccc?|!,,.yrC;gGjr{@0Itr8{`|_ӆJNMFEACZY {ElPPPPG yV2znԔ1?ȶA՘DOt8HΜ?_XnO]BKhGÐ&MNOPc֊V֭a4uyYPZ#_22غ1+CFe,wP qsSg%-de&e>o4H khji-&^>wAJv+s0?IWzFB)T9w})Sؾ_\UV1v$&)qDsGr[ yl ^hK0JIL 'f\yE-[61\MX#V?8т#Gyʓ}~Cr.MD Iuln/k /9N2GDw(h:]x8m8ol RQ =w6^Ъ!ES3uS`qӇMu*>J[t-ߛ ;e[^YBߛ W%לx9@C`r̝9y"@Ym=Yj[k D,OS6{35Xd;O rAMs6/5_UMv+7Zk;{ggˊ ` XfP7mbKAM.IJbSjɦ]ٓŶB5[v NBlD'wd9?%[O;O/unZFL98ԼɾW1ݳíտR@^z4t*#`rhr-~ZijZ)qZIǒq u=xųsF6I%? )9q&,84#8g Ɋ#M?G6Y y0'~LTжùF J,5#ɛ-ӑK-t&k<*7rC8qdȾ3eS0r&~{3r El񹘑Mb2ol4#G[";/^;9y߷\v82&GwQwfCwNVwXw:Er+l$v۷`xD$? mSu'nc7lfotv*ݖc5 \rڗ>ρm WpNul}O\dӊAN(l3ϛ㡎Jҟr F]6}u9 {.ݓc;'ӭH X˜Xu˷isGYڵ>&;}n0w3 ~Ԋ00 7WypmixMɸ#}kzwMɄӻoN>5Q&jGjsZ7S8j!a5oZsjM}kb'ܜZZ!ioGV`SZ 5 tziVn)5HgZk7#5:`P=%uk-77usum4 f3{3xkxşZg-s--kgkYZD- HtȹZ[!mevG`\ G(&\ V..N5B ^3#t]F@^ɀ2WHvC\k6#:-~<\ ­` )+Žѐ;A;06*чBn*E`LӥAr#n$GǠBЁ[ />@CtCgD3n=&i  HpG렳 -vd:OPB*n Y<5X-fvy  P ` _I@;U*p@4Jq3&\qӠo!7tF2F \pgl:g&2tO֍"up$`(k=l1v1PhKEظԷXΜaɨg϶9=3(,5rF9Gzfw6f0Ƿgtz6MtqO*)lٶsguJ v gW7Sms{fgW73.=ms{g.W7ӷms{gW88.߯)(v^Sefi|%;T@ 'dw kegtG}^Z?[pO_"hO:$/4o&T_"h꧱t^{Ū)#( Ԟ9ןOseG ujuAvB_"{r~租rAŇŝKٛcO]2$Pi\`^O]/ SsɒS׿\vyLum1]<2%~`P ;'vyouyj׫WwM^Mn!ɖb6o[Rpݾ@`KMG{{{Gn{nG7l~H`4vm@ڭ!_H8k.;{&|owY>aL?l}<6p ;s5P ]}c&~uh\܇GFx@O~yͯۀ@AKɉheAلwg߂P>6[arVdrF_g 3;!ur񭏝prAggA(M`}<0:= CDxFY7TQv+^1 _gA( (6oC< IF6|Q{$څDžA<9§Q+=ߵ-L*,K*L6),*Qղ"j[܆KìjW=mŝ +~L*]Thc}KWӊAW`rXfU"uA,Ca]Ń^ض1̠bE AмfĂ8ͻ5Yvpyxk ZP5oō$0PGʼn7&r#{~xmW0N8o)bo > VƉO7f-[wFY]$#~GO5yj~ClþcOX? >6 aX,ˆǾ.a]P56 rcK؟Xl%v+E`}XRl9V[uƲ`s?*; $woSh+VO "{nVjViTy^ rr5rd:p^yY z'!jڅȣP+*'u! rE|vQzYI9AzR|)֮*}Bs? Yo0;d.Ј뾏n:d S2_EL,ay' a5d\w07 i /uTj^Bһ~TRn^r96ߩ0*W|NSK'J6)SKMZYOŏY:ռt$erYmSKTܨU<5teʧ7w vJOG&Z˵L%kJ*o(!jאAfb]7$|XS4xz {t)%h~׷YR]}``jR!UitpcOy~>[$!D݋Г8֟کXڍH꥔kHv``f KVHJ|) ۷ cN"mְn ^&} BVՔ1vq4kC \|SW%;ehΡZ|4:"Ҕ2?P'=SH%9CU9@mXjRXj==ĤYRFjG8qrpW/rǠ8O| !qv`"JU[Oqf3 xȸDSu֓۝_LTzl2Usa=h*Yd$j6ྞz4RbL5pYO>p`zC <2g Ɏh]r <בfg9IǾ0<$#fuS7/xYIǢW A>RNh!:yN#g٦.>8TB0dYwpIN~-"IZ~^!P60=`)wlG{JXAFZP}8p|H3 9f^HrSl/B(OuxS̷]&0 cڤ͇nxn&o|O1/4U#*[32[1*d]x.RwtJDoY﫟cH'3Xc1!Uݴ<25tŽ= L3PYk0'UMsfo75qMs)h1gՙqMtnjf i.m攵3S!Ίm6梵f33!.6%sZK6`Pk;㹛~:{A+>h} Ѣ+9@NU7vAH.Z̘w1$c Eu\ ҶR΢ !MpRNkL,}:N|HJJ{uZ=[ݾu~r/P@.$hkjk GEk\]\컞#`aedb/@-⊁vsMGh.:ShB2 5bo0[MjQc6 <]4. =Fg ip+kI3޺kKudw|^ʻ7}$-|lw+\6z~ y.З267ɯ֗)7yhv<6oo((v(Ӷpi :+'{]KVtL]w},!ɾm?9y:}Prs"߭\}UC]ͼ!c>s?,ה??R'ぐ\r1}\MKmӘŁ\^KM>PQ!dŲcهٿzooA]қfp2Dcv[ Sl2|F?FV~ cΘVt@ j ;۱!CY9氕g*xS!FFl}+LVW gV鿛2c[fn=Ej/A%@yhr#R3аvDZ, dftgUX o3!՗J@ȂytZB@eۺjd*iݙqG/$wB?+'!#r@Z'P{` t1lK"ʡmhN oC >H:( 9!Öm=@S6Ru;i>H%@_g>]`hKgM`rzˬfi(uEY@@yK 5}NikpW덐B>409HNowR4h[6N،Vah;ξyliZڇfQ[+˚WSaJfW3a[݁.W7ܾly~5{,ѐ-#!Cҷ4UecHGCNoi=0xK]c*gt_ Ii=llN!1ɳw&ӆƴZ TOcJphdeFi*sJ=%7bR3bky*l(8Ң1n7bmb?}h(:zfWaA(σ٫Gos픡B+I**uotG8 .n"G??tleS@2-MDUψ~e-KDmϘ!2z!ga%2tt6  n DDۚP~e9э L)or\ݺm,3[E/otn%ɦl8缠Ѽuo*bSBj9W1uofyąHiT\Ze/\U:2 29JYDUZ`<̀Cե񂋟H=D(7?[DNQ*ILUZB^T2O>Vy$AН{\xwz$~ä Kt (| HYUǹͤDVdQm&?R9":"86 iQXTJOQ}RB"ը⾆AbL)DQ1=D8uy ޾vj_CDs8evm2DM徆4szKEU9q!8`]N|& 9F%>Qjڪ6J}|hU]/i|J|h_Ͻ[U%J@X[_>|Ġ@i/mַw(E 0}[:R Ѷ} Ƈ2;Xp.s9Q+ٮS,,[vbMR`t]X9)Y:Į!Ȝ[=N؄)` ڮ!ĜK\z~-2E9d,/vWufq5\/H+N1'.=˽]x! OD4S8A# 6 c,Td 4XrB5JF @֮Dgr2c͠F@#T#*UŮmk=t}5R#ζ4ݙ.XӡjR+޶ 1`l0 1a0Z+yEutEwvEsrpqE}|E~E{zŨh v{]CS8 ^[4z5p:1<~ǔJ0~ z7ߔvj13P&npBSZ.Z>k| {:Bq1u1Z1l1f#1d0*'}xmp mXx i 0fwc:_[7BD3@wXcyi*pPjrEC쮊aVqӛŋaˋы}QHPX* [;r"^m X ALrߥհ9NU# P|%􁯫$lJ" ֲ_(zeHU(mh?Zѣ@-ߛ~# Pہ/LCY7k,uП u^Tݔ?g!?rжpZ(?eJџ/+4`pZ$' L?zA{~DZO k[^域_0^ ޒK->MCZYt\^F?"3/-%8Hf$V$:WŏO]OMSyD?ѷh"J|h"Jh"Jh9.BH;O>}G@I BwX4rdw-Lx QEw$uFAD.‹FceZF'Lx4b)Djb$FbDbd#(Gz5 l/D$Nk@'bh 5m o ?%"{Czk.'>>Y$5QDFRO,]eЏ^!lZeL^i_YN[eh'ߏDrSrDƯR/XeJDٶDJ{q;~"<*md*C,*DG5n,-2 *D?nA5G^@FJP &TP;jtITj%YoyQ9%3̬dj*D75BJ)TxQ%}M~83 @O Q +=ͥKtV-!/f*Hb-T-~{IaGoj]=xz I=xaS݇ىY rTF:S7%dT!ur̀JRݬK7gm,S= f)Oǎb&qBFBr?(PgEA4sT$L3* < ?S4m @^zMz~Z.%Hˆ>ahK 2RKп I إkfgh9,,]rQum #꛼@Pc8Eor7"KH=pӐc0E&\͔&d ` -34<4Yt$ڹZ7 2j}4z?;&͛7 PoaLZ/2z Ʃ^e ;Fܑ`SPbSOAa&[T!;=0a-W{4$ʇCӫ"3maRb6,}; B27L}X; TfTef1fSd%h}?2 _v/ppQfb6S *'7$ciik[ǢugЮrrwY?Op3{Mͩ¢8@TUpUW1P/Oz^eo]o% *{&j&/L("T.BԋK:ǹgf|.ȿ*8tTy *gcj,7r=*V7[Ϳu84T?-|VnvG p&^VMyKe 2wc*} TfW=S W2lz!)Pe\h%ηTڼ k,[ ]yUSn- *@_!g#B NF^&"H\pmI_0`/x_"_PrruS@bjre[oN"_h?>M Gټb-|bVS)F1R(eO)ߢi1fca MbKbG0lb|#1?{ \Bd~!d MC!D0/h`Xx91B;$ZHi"2芈T+tHVFǽ_[sEٛwE~Ћ3}_rcvP Ef%ā=CQ>/ql":bۡ8DLܞ|N|{(+ݴO+Sa/Di𚔹 4:uoëEw8X<+k+0:f!$s7 ȱLQ}?».5f t]-vͶ^-6;u@6Թ"{?ȚdBWxx?hW5b{=HdOxL?NG)ҜL#|@p\o,E5_[ pj*Swd$w[.ݞv{?# \S΍.WwL-p|I;7$1 u'cw],kq%`^{kٿgIXdG.w0X6cw_,=ݨOx=k#_8 _>} 0"\$[F*kavADDԳc.0+YO=p K4>g}x?" ٬o[F=#sj¿^-˳rgl>,;!-^N(&4;kAxD3n)oxE<#}y߾vApĭg'ZdzD3Y_nGDE܎:G}vKL^|6@l;GQ jSpd3J;G(煐_ lJvcq+ݗ]bJo?fL 8- } $@p  Z| /WaqZQwHDnX H8һ BQXj#-kR8NI9FjJZ"qf 1 CXµ"K( YV@i+ 6サnƼ2' "S8] )MxeIC3.J$ "B;έ-VƂ]0OAkV {ژE2+N-O F,PTSut+q  29N +!e}B[a3lyX)${QnNa {6 E,ǭlNUB^FBT)UuT/TYڑA*'vPg!p=m/71Je&E)3US^.}طHG0Sǎa"uE<}//iL_@'l\`BE_z3gc{ȃ9OG߾yGyJƻ-݌U8%@S.,Pv pb^tfS[*ˎ73^afa3LoX˨N |2J̫II$t\h)}yn6u-H0'%Xfܩ 5>/U`T7̱jz^I9}ˬ;u&O`2v{14 wj"%2Q I}l;?L~3Nz~w釙 `q CJ,0+-Ecz.mѷj,\k2"RL[nq6BL0;Yo|N:kluEPme vS_2ˏR?VC"h.Zpf0N2 F (`M*,jb/FZeŭ a;U^MGVFYܾ|G)@׮t3A`*_jyM0BYVF1^*]OKbɕqm|1(JI˅moN_(WJN.9lWaa0J[5p@&UfF;0$FMTaau0,MUhS1<ɺQ:)Wh 4 +&7jå2 *^Or24\:2Cݰb|m~P +On4 c^yX Vc^^^ W)0yU`1X褮EGuqDx Rwfg`PkawaZӚPgekǗY79^ah<=2rP]GQҷ34WwL~Kɸ=|.Aӑi*S _0. @pL T]U`LU## *X E+XPI"7+c-,D+1!lðʻV:l_àx iԦ,H7c<*O$023m7"ײ oULoT8e_7 LܨC]>;睳H TvcZpTE(QpWbl%$-:dw W Sl!GϢ.v%Vl! O\]iJ>[a޳y䪕h~3i.ByebXwe1J 2ndzlN,bqXi*V8@J|'r0Cku hYv{Mlcjw"Ś05E Ŋ1Clk&`{y?Ļִkf߫3eZjʙ<:>Lv@ ԎUgZ f͈nZ:YATzFe1HVl3AǎNV63 AajT?# UHm^]}oַ>mNwz1տxj>欺XxvڷQWRH͖ )=W3dd[esc:sl@WjЋǗԚlfɡh8(p%Ѿ|oN䪼"YSU E:tn!濃5{6ϝ*H.ٍpOn1]}Dv^<3yUCnE99h_^+" ӓ,?Eء;s]o|+a~؊c>vN^7;0SSgN k;Tbr>0 >34 ;dO١d' BOpBAtIp&Mtr:uڨ#E#JGWGCG*B‹{/*y»8U-r}Is& y/vG"=BzF> ļc#J8l{InPtl 6A%^zfI|o3KBӀ׎ 41tngl /hp;bш+#(FBێ#(Pߎ ؞'(!1.Wh!_|:;f?=57IdDPyI 4 K|i4CwF^KU]hc$&coi'MDwS,|EL"|WDK@@KEKP^KW@W E`Tgdcd-H4cw:eD=C_}Oˢٍi^ }I&)|ˉ$g33UИYpW:35:,\ %>1w52sSBfx0p3Ƿ,W.Si>eFcl>7: }ˊ7:?3ӣewb_,_V؉5zʿ̋N^ۉaY]'J#-?ss\|$AEO} gǔyj0߱wF3?8O2HϤ+Ђ[AUcJ~6\}$]guԂsAUC6Ú뚏ӴBAɏMtfM}4J,k>LS%= [_jOo'/p*m!1V"UCCVC#T"C8MFr_+6-[#'9}Xǎ>ƨIF& t=lMFMʳ}C4;B5zH8s 92SG2)=EyĀ,dkO=\#>oEb2 ̦{*#黔IOCS!'{jDkNU@$e֩sjuʅشtxWo`N&>P x[Ȉ⬌}hge8p^BYك2*8GBY9T28-c* Kh?  4X +ZٵV޾2 8{ YL{s/UQNa.{46bʻ',ދ= 2geϖˈ˪^$Þp#}wNƙ{WQOeoz˨ᜍoTOl yɜ]qpx́A<. _Sqm-ȃ@Eq pd(P)&4Nn@EݎR98k 7vTwni'88ua=m)8s-:l1NzfkA՛yN'X\pK WΥz:,u.p4#-sOLOR]mZf>qK>IsԒ?7 ^'>9(6rLXFnDkUs#zeFN~퍐ѐ8Fݫ,#q"׽YYQE^ { 6mVm8~׾Y?LQ=0G(4M}M& Mγq  'XJI.jfDY3'zh?S4 ݥ~.vc9E;{ws% KB)x/.$/R{/م%-R:,Y:'(-R/Ƈ,9/&/iP7[A dY%tx.w =mTƒ\~ 2;Vd4ZIs$I$w|rI]#t Z|Xv9|h6acב É#ք:MGF!¦~ǡF+# <юuGj+u`0N8Dx#}䏣C_]?% ,P?k4I"uk8u?#qAq\ -HT (+q g XlxG6C2Ց $8O< 8Q  M| MLH,%W;D?ˇKre,#yAِ'CN+J 9ns}G.e8R ݑq=w,v/PʳJtߗ[ށUP)}AKv<ƿeJմItHhN Sa/vV(t4p8\ޙ:B#ڇpuctZ+XY繼hZ{H8=]/}ypo 0vw>Pr6yZ.X ڗpGdX`ZY/G3Gf0ڟ |ZLԗc۴T2.`:Km۠$C*?uXS-uHM&*j2-(ɐ3EK)BulBcv(bk>{#"Im[%WJ lOu?vV+S@l,")ں).^` 5 E"Ֆ!5j&x]i--cH *SlRWD=pgZe4EhȨcK{e:dES/ņ]gZ%q+1ȕ0fq1ʕ؃nXص^*fC[YdnsWQќ$Ĩ~=N(W8ŘF5KI3*Շد2pJ826RKK3)g?{OJA*qj: x%,1xe\eS|i,OsO %]\yWټ@Q_^ie3创HG)D7 GFvotKюv_[Y%K3G.G EA//-߄ќy"8s73 m:˧@0o-GD@F#fxYD>CG,ډa~hY F@۝Icl(UaaX[1m vSCiό h=dHj-߰bG c6$͚AeWkX[ce,&ahXY1 F+S1iGfW YYIAa F+:i)ԅvWarBᴞì7FƽZg O0I2_H 510ge8ay7'1C=pXƋcA^ Fdz)G1RH, 38Yw8kls+*KIԪl,Y|O BymԒOBޑ_ޢ\i$&&,&3&iF%Fg3}/?C".b!hﻶg>ߟ8ͱk%\ /P4亟:DҜ>u s[יLU]kýHb~궸7g=xP'9"ޖF2jqEfճS06l+njxZBxٯİ(T#5Lwl!]3 Ա}0[Ck@bA]ΖMg cl$Լf&^]q<j#j꫿H̸7 >ޕ̔Ը1&G@.{Es(zxHW¢ߏ y: D}7RĪ[Vwդ lSI3Sqª;|Ozy-gr6Y #Oj]h9{)z\'|nȜT9qڱ% Z?ՒO[yK\=a3!=*ᅒǽq[ur+ƽpESF@ :nA +o=e5W8.{T ~5_=Urj-{UQ :*eي_֏Ey]iMH\nnb~AX!*פ*****7BgԦNyW8*eӚ?7[Qu/'Ō#rUN_ĕz=Ź ] >*Qε2U9!7`4l=" CsrF=99٨?Ւv{xmu86L8'qq #(x}fΆxS f*^KX]n6lDq f1!k}hf_ oPu79SVT;3{ar%^p7#[+BrkQQ+fᖫvikEkѬX[U Pl3QM37hczwT0y=YϾab]|ѰY+Oz|LZ,j{"hC@C+v`P L· QmA9\iIkx>!X8m%n9'e YSv9-`sɅ3c^s*[as[Z G;MKy nY_ҬwNa$F/+s [`u;M_Rjwl$ݛڢSZQtR<#aSɹ2su_6(*ТǿmumL2 ~nWH9-P| v[BMxѷ_2s+\7[jPlFڻ"6-oCӳm>yK|ݚl*Zg|$87}-dɖ7[]F?gn䂺[q|7P my^gnn̷o(=DxӷYZr{2ߴgE(ioI#;@Dݞgq! sR!@c{^ROyd0N':|MeuU'fEªG޴:SlE :n"֝AYyfE>>4M; >/ְ)yT훮z(cДwgH>̐N"prPdFy >ΗTHϜe|Nq $0Tpy|y%>u}bIG%}ޤIV&$ȠVRNdWM3-"OK$49]/'"~.yByS@d O)*&r9YSKډ%DÔg%MDôb"aD^`jZ[kcI\]M{$Og ۴i SһserRB ҝ$7[7R+&zS[g>4(*s{*uf~jHB9p_mS@q゠dҤJTJNMM0MM@(w+H&? xw!?6?X(wρ_̻_jcp>~CSŏKn<y6y}wl nTW}+;}娟J~OIvSV( ?x&UaS]7JoWFxVφ}xVkvq/ivek[ϮN2~Z@3$0!oέ}x&.;7Z4 yd>h Auܭe.E/Z_ Ej?#]4ϕ_f~؍/!۲)Dyh9wVŠw=f{+G;I (7Xlph8U[>z`#}h7~h χoѯ@RNo?4`_}oRH >t#n?߂O)'T/G)3Sg֟?.L8XAcAZ#i 40{!C%*?ig ]24DXhHb\(EaVƜ0_TaY؅{Z #$Iƨ^xWa$M0Ubcd W>lm$wu4ɬPu=x8v4:e4SM4͘:wi74e4@]q&+FW 44d11|=\meγ3葖^` s燫l.1zb.岎Ё;&B-(ƳgU-k,ɕCWf9tHb|s,(wWm$xQٽCn;癥  C݋W+>-2yQbꛃ愮r=~%ѧ5_ֽH 4\uc ~|T 6pe1*NSӎRTl F3T6 WzEv-H7>߭~ P$"<z<;}rƒ39{[ |Oٝlz Cr,RH}Bڎq:]7к ]\nlG;bHpm"ō۽ e 0tX[oBHѐ2VM"FX 먔;1(A4J\˜Po%/`M7,0߀֑[v: j ۀNd_V)tfҁWgRc0-PH׹i>\c=0V9#x5NuӍq $?nir$]rS5F prg/5fJPL'9Y~abG_^A_n>A1fIqWgnVĴZhnkĂ=d B7\pbǮ=n}6u@4\rbǡM ##uM,i2p&OLmϫ2B]\nb<O3B\;sF8u˅'vfJqm*WxKtShnqkİB\c=#J`c`bŰX!"V bE*XAVaűX%4Vu%A)P( yYJ%RDIQ|(Y(J%R@IP(98JFi̞U=?{v{RaR9&͙6Ÿ`/owoT +:&TBs֠1Ϥ˱ ʾL yXNl2Lל {)E2P3Z%G}6O"nޯw|\E8O&(#@;C^;5_olg"]^4IbTDxhײ>nm"$zekI>mbg>O\j_i#e[i>moAD45PDwb@ <T >}#>>بD* ?}/9Ct`^bxhy/qQK=Qj&>{_~ZMDwr‰ (9Ht  8QAR oyR7iAWAΡAAfʠ W4͠^% tΠ_%'D-,BA}ȉ%"q CiÐj")Ȭ5V &Hi M'$49+ y2MW4䒚FȮi:k#ּ2Iαc wQ/idy};*0;'r)]r7\r)]rף\R 񮔶T5WR[JT+-l9 QWj!GoQGsk2]% e%@OFO-s2 MF/Qe2%.uPtp%RF^o_o4P l1;n'r~SܾK"7{*)c.U%p?/K땠j 0W\ E.}٦!,AA|EDjA-6U>xkWk[ZT | AN uՆ%rF1AvR&c_&*Ru&5LgQYlD7Ԉ({z(NQ%MDyg@({ {6[D3GW@*Fl=x?JG5hQ:RهRϨU{(Cz/P# {VDi3Msz+({R5|N卞tOjo"{>@Cҥ6mPTߦ>z."^L$gak0V+<B[ڗʋH= 4P!1kI_}! Jz_##v7̽FY,?eVTzH;+심H]+Jk=kE^ Hi =4EI4CkHi)6Ӵ IY&_N>+R m᥋5ɇx&+L/%@-Qt‡3t0hA %z%(P'aK|HQ3>ɳLG+PIzTC&1o+}-"jiF5y+RPKj,H${x-qҟ[G@_.4<ѹ56C8҄ax%5> {8{뀨vm ,D@,:ZF`T)PD`HtHit!k@}s}XҸ:xBqAq#.uzͽ/\;!$=\ t-s` sEW]B3N.o>+g 2*g{dstM̵Cb2KؓfkBPvh_8D *A 6s9ҭuBJ3h̥A\J3z1,Քc=hy/,ʸG~r;}{"( '?I##Fm8IP4 ''ɘ1`?4'?'[O C`'@2=ɰzl([#z%G7}eCk'(rյ5Pt%P6=F\#c-w֎y@i`@)t?:Pnvb*;֡)YH(bqZcZ<F1>LPv1? ߽VOc M혐fTR1S-M`3MŘ)SM)S?7XZEXs| (4g%MhSM-h5S5M5`53^M^SM=^3RM7 *}Aflr}%֚:}!%f4}S=M`[.4o~ۍUOK9$(ׂ}Ry qA~cV' V篷5-(X+DiƊ,m4o(h:S0euJ^kEW:o[l--X"D9 [m[ N L,B)t/j(XK-j+_ B .U-u[n4\՚\0p _п@6R Oo)`R>xflxrPF> S(gHg>/&,C2f@&rVO6pV aY?9tf2Ẍ́nk>Ǘj~g-MCbg:K1欦1rǴ~h 8H! *#A|3lr L[;댄8K21,}YZft=kTMrÍT/݉h[HpOҢqhm͸Gp(Z3pXwN6û3hk57~u'5hǭmõZ[t'E9G6q{D-[Cq'EQJmu-6 [qu([.Y]2ngW -yWk nf׿K6=q"=wZQ 8Eq}v.!$%^EI؅]AJqE[`iר$e`Z kr.JN}]'e02ES?10J-gh 8y"Ea"D1U '2jjOTJ(7Qh,(뷌 (][ - ce{x heEM2izuYQvC|v!2Ԣj.teRհF95#̤^ fDf@T3WlQ+!,˨W;s jfםտ2\eEu2ס(>eϑ\hT~ Q=5ذX _/ږTPՎVA*-c`!-74qgy|=9,,95 (U5hu\bUUI55ur\Rx/W]AUWWMUWDZUWDFUWA]OUWA,cfؗƬqYFdTW+c̥,9+r$+t.{IIC}RH4<: NȤG YH,/iCx+L d#j#Ց`>:{ ld"HG0.5{9罝)4I)xFp-{$~{E\fO-oeg֭V~bO 3,g>;^KO1$i}jjz  9)ڋ֧`2,f/[ΰbY?4p}z M Y ٥J%v2t){f& ,옫M4t3{؟̀Eʛź%#Ͱא,~5l#Y)W_}5X?=ɇm8 ?tdob_dcc Nl A"ٝ׵6@~H[vHm2vgg&-yᙕD`=G:,%}:(rWn\yȯwyQv_x"|.ܓB^;#J^*hɫG#&!.|-Of06( (p @^F5 b"wU^R QWSiWWPi8tʋw@UuCu;h䥻Q=yv bJz?JxܘE->n)k?܎7}IeN_o ?fCe!6 lǙ7G㱦~Ӑxx+-sFS<&~WB=4X˲/~co7 KM1æˍd o!>Aӯ+ۦ*y~6!K;ӯ\o7O#\3Ӿ..#xs@<6lb<ȿArg}MˤuȏRE 7Hif%9 3Cc!A;X6cp0(ǀ$xda8$Y`̯azX̔1Xϲ=l·iw a-0ÎÖ1 oC1>,0A,;1k90m5|_-fp#rÜӼ`f6|=, 0 =sQLFCɞ8eTſDrNxYObs@~hԅñՎD+2qUm7qUmrtՏr:5D2{nh4x@Q^9]hG]-h(5G5]5v5'^]^G]=^'R]^G]oNlr%ֺ:%N4(G=]vI2ٰ E~lTwUfR%S}̦J+Al1G9XwF2CC\g9Mtعx9y8xPq0?N:N^v^x}d'LǡM Iᢳq/s9s @x?&ʟ9=7hys)[CsuxRtoA~=,]Fl@g{zvO|Fk N$ڮ5Jq jRix˯5 ^ֈ {[3X.N֠Je33k&]`|. N7 iuZ[:EpS"<At=r2"yOӮv`ua9DTv,9UXi^ 3{|Nwit*=kg%#>%=Oa-|U=#`V0yO|tt(b폕U''fIeThJ\W$W"ɜaFNͫOR9_hoiv^htJgsDru'Dí B50qFL×/d*dXI`nmk}9Ű5DE,j kDd?.@.=zB2'B>UY)ZOB }"V̬"yuk?x(q{ cYgL6U;ܾMAh%n)ںF,|XT+ ?P8ue6?`Y@ϒnM$*^\۩8(aK@v?Ê? m$ĥH:fiKE&&B;G҉$=---mmm,M5:_+ănK%flW{3EH\>N0g\)tk#zwhfrk0|"JQ^Eu7ԕV 9%\oVGfEve۝i6*תIjuu㈶!\; ##cMˡJLYXkϪ**x"o2!e{foq8ܙg+E3 vpX5;72ˋ"~ʟ2 p=ףⶳx]im[(5}6Bmߩ_{:ғ%,Uv+]=F Lj@11v&vJ&vjTB'ߠ9*ǟ?wPU4s_v+Ϸ&$/,^% *g[WU ew*>ãhƷNo䢻F[ Z&lP@;MFf)vC ~wN0Do珛JVZ!7e&ةX)Ma=iW~>[ZVj23 ,KW QF`A5:Q엷ދO G myo U:d$0 T*O79oJ#g ڃ6N,7h]goǴۤ}9Ɔlg×r7PmhJW\c~jOG 6QbmL/2-[>jD:oߡmzyˮZа@n4/Sd(3XkXy2yo3+ -FщqȂ%y{7qJwuUpUݞcrC yt뽃wP!<" ryxxt W6Ic ͍T9a DDOL4XU榟ĠuώZN{+0gl|_ 9- QqW:-/qZtuBxEݑ9*+s27ӫ'Urksp榦i겾) ɂO͢M\-Hn<^׶$vIPn `+4""@2NwP\^|g]٥RqԻPZ[Tԫ;]D}vvvkt >kݣzg}eP !4 J1_4g ha>j644,|Pra0$)IIW D4(ջ_Z[֚so,`>Ĕ$޻wojI F6qyxtޮm3決۽ J^!!!vvޱf{Whsp[s6555?- =slj0礁(@B̤+?OH9p/zyoo/Xy{^@| AJt z7 %j99 4 uJ^MH9tGVz95{>2;)n=`T)޽HMbiҸ*OOO2me^$ Aw~Xݿ{WB}$xbrn["-Ćm|}`\b2c_{{y? 'HC <ܢb{ ӧ;B)6*5ͥaNNNHz9u U8~/َ kUGP"""x^juE=',qqnz^vqdgsY@mJ'py_m_tw,\&neɉ rݶ 8q=N弢6Iځе:uTKNu&;?apy3ۤބJ9gAĤ ::Bfaikm(c]vWWS)gs~AOs=yۃp~籘"'O= eń~####+ '\ȧ4 ۖn&&T6`|$ApZt"nY>bmf]/Ie {ĉX!' d"aNT/8كh`.B999=_D4lM6k˗/҉H7]=JuQΙ_c7YZo ,oo{mu!srsArӸ L{њQ8l@5?^Mk ?vhywƿ" \ڛ^Jid*LKKuzoǰX˾B }ɹ;8x}fbf֐jswJM4}ڀ%B#| tQ^MM;etY%S===箱`;qc:7&8"#k82*0}HDI{!-mrTsojmhjq[;'c1=ƏrA |(s2a{ [skʘ?m$LK~6LdӅ溩Wa>6'{55 e;ATjT<:߅^=92~)QQQ&٢fXaaa֥sD1{}B;{k@ˠ:uP`-.~ i4TtcGV0,]0_CԘ\RQR$s)ͭŒuyfm}o{;@s5={jbc5"UwְwxccT啕Y۷v+)v WA/ƛ%Wc2ًdXH0*k' x%B;X@xVnni 0f~mfctX{LMK qLy%88oYQRRS'slG(qMוWrրXN-4GV[`On*3g\.z;|yƉ3׺8MZ\yĖX 7;{S{& M./f(' {k?A /\jRӸXswP"z9//OrQ<-|[HAu.v~MO/CRz2id 2{S&Cթ8pݻg{Z}4 Zt!4BU!7­Ro߾i)^_Dn"=Ph``*Nܨy79[m%E@'bM%"!mfnU4q3eL h d͚=校4Yi^5Xec\~v ۷A cffȠӛLɚ Xqo$rwE]n;L\_bbJ6D)Ef͙]{{>KLGpQ>|)Zu<ՙܼ@,R AIYuX,6ww]F*ehz]jK82 vy26>-!ϸ]JeӡYްҧc;fe 65WaGrEbc}eyEԦ$p| @Ln8-Ih>^{*JFbC :o20dZ ~ M߿//ߊTqYA1eK!|/0gfFMÄ3%S?|^0_Up#ak,SSҶ;IʹpRG#JC,'OͲD'NTlxw ]n(mWEYYvC?n;{V˻U **$ b'ZUHll'Bhj9#we9llr#M'''[[e󋊊JF˲ÌHDKH5CfW#_ P6bFɡJ ypE0 Eǂ$0LrEvizj@T?Yc|~$߱#~ WPuͭ>0|bjO0:әi엟o R%!~C{Ac #%.}+ah8qjE7ȊO!ci\Gavihϴ!|PZ>uv=( ~_֝;1w { T^i!=o`P׹W HX *ʩ^XkaSW?mMz\AzTLRR8`z S ՙC36OoGQE[%}ARՉJJv,y euOh֧;MXάycnns\00.$@{ &&&섯_%9G>l !rJVyxU j_r}@hUd ]%9CR@n*!ZÎjH666 )6@z/2ChS$$ٶ_ 35eSSSp/ +U@9TXmG.neȎj89Gg:^o(3ɰ.wieQLHj)5~cil99\wS6MЫKٔ{uu~Z=iiZ{77ZHH@v(VNHF"wfD0/899LZZZzD@dI.T-7mLY'G9]>`Ϫiq>)+GH/2Nq|=X8(:!B> h^Z :h0V6jʶZ* 093XQ{@ն"Tsr,6QEHrIlZг/g|`~'J @;޾W×;hϽ-V"v@ͥLydž x zc&Pj^YֺWdYF=buz_tDL\ 'ϨBV7 _rhl4֬T[ =sMrGI(-7qRȩ#PWoa``zti 2sʛ\}رc$PX.(y>naRaYɧ\<ث;`h#z b\@W&fycb؛YMwhޯq3_geӯ gʓ|w"S@kVZYVx-n8S?()- 倜6߾XA*v O.-'jľ *xﺱ$(iJO.`eo9g\{q,L;;{͍P/D,'A)~7be- “fTzwI@a"=شА^ei.kʹ'($YFdT빩Z\wRl6 @lp5aW%Hodmlennd/>YW:i`! !U*nZ0탭fфVeu{ ڽ /@rzC켠E87v{eJ2#K7opo<Ҁ5 "QG4#022碂= 35mswfߚІgZAĭ}kk,\Mlf$&&Jr $cV{X}YXXIC̭k'>!_=/-!S| ZW>\ոApJ86r2O1Mzj@ g߼ys#9y֧5_GG z/ަ1eH>` ʲO>qu̲VAkjj<5\s-:Z|&V݀$422>6!եx$gD(y |Y;$pUMz%\e-"d`TiNv4/HaA3xv+͏_H}Tp,'ct f/wpE z# ^ Eao(jPE/rf,j@Gl {~8t A z(. <֣[`wZIS3i쒞>,42RE[q5K[+Eb[F@b[@l$$ 9}vdYG& ߥCi X.,P/l'⡷7VxL2;;Nb1DZ,P y s'T^B@Z"*RZާHӄ!H+>@t pIn:?A ?#3n!DŁD=VVV>X4=b=wl3/LM}} 4>~&RPRE[>EDFA/ɩSmFZRA8' n#ீώԸ ~8<9h(Lttܹ?N@ =$z@v_T49]\@`|K. <zqϟjDy}i|aCY]MEL#h9!AU4dK1/P`R!7\ƾw&<"H~AE/i_t|fAҙGg0`Va; N_ՀuPȎ|[[/"0i$zQxQņ:@MYSa)uzX?<*m%1vdp;M=?;V()R2KYY Gˈ2Tv(dl E=W4E!5 ~@8´:[;cdJQcMR>8!l5cV&㾺FU>wn{n8tƫ~wjGF=k,^T0LuBúxI;׵LZmldʥ9ɷkV\ " 4.^.yOchϵg*[/m)ۄHZ;Ϫ(eyk6PmN: d ((URLmg!D ųCdž٥3js0iȦ[zXCs̽Ĝbu8Ck}^&Q= =װRTD+Qb;3ڬBcTbR|fp5C(!4&=P/%D֞)*qBk+WǺiWh엶xKvOD  9+4ܳu/ ev?SX;|}(17c]qC(9>e(`D+avxUAzO~C*yQC/CkX*u5fRpt<-<ީ@h',^:P*tV%0OKZHjXrMJleAiq{ V.ZD׷dFfWW!YD}a3k"Wy\OYZ\hhPȑw۞RP0|Fל#`SʰVCqgI]:DUbWZsOUn)fgAf,ʢ1OHď,nM7=6‡$`C(`Z6t k% @c7nM,hl&cW3{2⸩6Etj Uc1C􋛇G c[ۆTOc(4fl`VroPL롌ԏ-v|!kvDLv@}|FP94pYAlޏ_ΣhD*R㿗ª4X4o.`p[^[xhJ:<# 58to;]z5cP`*yXd_qM!d5x4.}v*ebI>T g)'u< w'EA@}羥 #3@ƒ|>f&gKm\#mOu[Sz.#Z¨?as_6Ѿ+XsfSΪ||1,PRRNK.+_k5"U~؝#2p}WJYV| f@3/L$* ȗV,`x.p nⴊuѷMՉm}_[Af ~h*s` A}΃'<7C Y|&Y`[~jv;䙐=nnr;k{TMȳ)|!hUs_sA78a-.F/ ڀli=@ ҪR:֯f+Bɨ_y4~: [^S@K8X<ޞ=hj(8hH"f;ϸ$c2z `i.D8-WTjM쪱ʡy mjoҺR"6jIOMG#iu=Oyqep<9Qce=J{(KTL8UOV,w^ePhSU4X|@zTe[?==ek MsկI9$f׃۞:)^v!ԥ6|vh! r̎Nвd$IB#qg/jP86T(j=DЇ*PhE@R6~9eey.!~2̳*AeGIZ r_SlllCY&&&8FvEE(pVsADзЇi6Ư ^d z#'n߁O3,4H teoUe|zF6PUM;_JiߙFdtZ3uyc5tƄCrTR!8UIWVKUXp \q* `nlbl?Xށz!^Q1 j˛o^ٽb]mWT>*]sF@sJU6wAy9Zfhs͢7T_/ n}K}<ʗ:jlljz_RsnN>\(4/_z'yk8 ^{ԑc(:|}BD'2pd'Q6-P'%$b3T~(^>͇qn]<~}tLL0$ryÇZgDZU,BY, q"'2kP41[| BtsN_^pinjf 1U*ںsCI)܂e/Z~ %^gxd_Й_d wwuww?zȃ^AHdҥ접a&\,`I]g\W)%8'I3S(iL||<B{|!dLW ?';1vhEbE{yUJG{@9ZG9=SP6 o6mP R٣< 1qYjr80 _!zyjvMJ&[*,s6Mb`]\E*!׵ /ِ+4]iqZ?ǡ㾧 cZA^X [@4vFiZ=MCZ['ԲT;GsV'A`051H߬SgC ⨘qiN(]uibHtM6$v ]Y!J|ğ FAْ0C:nZ̚j/{Yr iiJ΅:Gʾ~˯t"ӅDi ?^,eT}ll4%+h+hoOz֕r]j-+:Rr{&{3I1C^^^P*j&?ҵ<&lw5#(ݭ'wKjǑzC v&p:ڃxR }#euc_6%{~ +wu}جd >P9 ?dxZݫ+F'paȟKUNQ|8 ãSݠoaks;m4꼙Y- 9x֖Et!# /2}σMpX0{n/ˤ]"*_c/z(:u e=V׋']jіD}޿_>^*1#yj#7<5L9%,=Yl// '{F ҫAX0vfffC@~b6>X'/1=+# _{&[^ML\6UK}?>h#aw>Y(?ľ\ Q6evָ:P`|kiCc^d >vZnhrC?VT}呰>5;D6(hsaJ}UV[!Bߺ|K ;O k8|̠0fu8-]iL]{pؘe 팠xc{q_'DhG1͏H5xQ KАyT߶ѮJg@>]?"RžJ|v qV'~`趗iiDٙ'p㍞UkL)7ǕDWv47]a)X$UG"ryMծҎJЉ@yFL'bDe`@~>T8/(,5:JhqRe;$VE%"f&&O!MIuăTPI\S 1xcT͞$MN@K{vn@|";e훰E 5dfh'%&,M21P2"KT ܾsT_z#Ph6>,,W.#hEHr%!dATiU޽@z mF 4-C2ȸ%NԊpFlBĎEZ5tuo\O4UUFAAr(S(X>\Z8I.L.K(HI9"1U5߹q"2ѓN௮nTʫ8Hb_XءC?W-V[/nXK+*6Ӑ(s,m RNeꞀ"9M$Gj֋)p&h6rf"(C V {?H 9|.F(s :t*̌ ;or@&QgflvZjΦ[b ɯ[wîڍHdѮhB >tҾNR[tkhCQe7`"vAi`yoj7-؅Z@f=/P[o-Z!ūW+]@Ic5ސ=`##EaŇ//ZNŲ*_#]ژ)׭ TOx7; ~ʈ_}e>{h:ռ WDs@tnvfu\sq3r')IOG@+lPڄ6f?4/?TlS*# G#KօD]?)y۟ ApmKA2݃\+yIlR ߧ:"|ʋ[EM\ zt4{ـ[i/*&XWnRHo(gx璵z;")?:eJF9L< cD[/@@ۼl$xAI)s* ;P/Ȓwe櫢{+o]G:5_ZCٛMs8>?|p\9Z[3o/&䷀BN4P-ػ]NN+ADu} G9/{M(x\qu@9 m^BM,]Q.s'E Zw4&½TQ`|wAg+鮥,]\de,7纥?NY\rNG}LiSQ̓%f Q41l,u髷Qy2SeO$!E2lUD}7ϗ~Zb BDrt8_I?8.ʉW' L+׿3#hП嵛?RT$ XG%-[ _gEb7AB`H"4㓓JyPV^xLMeqXc*j1`042bE!-q1A||ws޽uMEEg@rr{ٳǟ|˫#{%DE۲ݱ緓 $G3E\fV9վ٣v挢)(PJRuO?9ja >ŎGY3 R+1D")V_EeeAc5Zϫ7[;0[$ȲQ:Dqn$4441-}g3.^H1*q)icmJk6uH)$kR gN?=w޵|܀Tr&9JI"8v#־U"mru^df <*ʔY‚K6-vH9Aic:'6TUsi{DoOE+rdcvq[r&  ;ˋ0ja_+Nİ!QY91,>rrt9ssLR!!i;`kiiEO ⹰VܤuhcV#òuќ\^^[9Z[C=c0\oS-6Eb)`3 |HHP#؟?[9vK 㘷?h}[+̑bi1*\W|EIb?VVYbc/O(ʹd8 >eol[XDE@B- y/ERjVa(s 9}̗kz99X+--vd@@&I{]\\Шcذrz77@"/Sz+%I5&|wPH ӜQoU5.[but#;)X3jwrˊY1`FAtλ$GHH.In}S1c /38B0pp/*p_Vѱ+mNo'V'xdGɩIܪpb8y[8qBbz$$q1NjM7DN,Юz  RWҽl񟄭SU'ȫRd+uǮ9<~DLr(֖.jRY +5eqTqAu6 ?$mL|Ŝ|qd#N+f6q a➄=>>|5`޹Ӳ2{&\t H}CPTey+vd𱌎" :o)|}XZ'3WezzÇq '#H-@߿~QrP}a,y~GGP#j$.o$rIAAA/  =#1|ç2xo\S]vz)Edx1x2x4nj~vnХ15S !ZDe wGzj/I܆(^#KrQ`ɚNφ%a,GFW`lkn.?bP: bjGbSD1-v?@'UM͠Ԁ|}}Čx>SZCOwvYy퍹|/H]d+Kцxt[LƇSWoPχ+U(ϚIR hI&B'P}dԠkZVY?bO]o7 紻REF7(oeeuKH(@2+ njoQoX^~GL#s(> )K܅Fȿ[&C𕴬,M@L"1`J6gi=t@2Yϕ112>AM꫘L*Ჵep%V? o`?ZE[  bCS0A0CT1 ډtcAuQ\N8=+{'?/0Uy>[q0dg_,rnx%@2&%p\ǻ*?}T,CwI ;;YfT͍;E9}N]gr z u#rV2e@M $wRr~.?Wɗ)'DH@32f07Ny+::?ɓ%S 8XCsH r_AzCưOmԪOqdYē,gF0zmOK_zuP\:Bߠ*1Uة;sq~7PlN?SWSsn%]䮉nػ1H+S,\Z@~FFE.m5Hmr'}eTIHqn\|z>r<$;wq[՚HSlZcàsyV-,N1|S\ @!0SpAPx%WSD ,-,-4u?FS~Ӆ\mU͛}\\"Y'3ߑʘ.M50Ϲp*g iVLxC({ < N:40/AfE)lo[ 3- ;w%%kCپZ]!yX4fNM#Kγ>꩓ :_ӻ~:zq֬P>(sg#$? s_CR#w&z>m}KUͪQ x=2ORIEEU*O7T~W+N C,8 }aEhL999FI =ޔQu.+cm V@e<9C j|HܞqWdeM_0|ƀW+ch#F5Ǵ5jըEH\Ox89v~ɻ(lc%oUՍ60@іzۯ5~!\O_R(;G eU_fýPg`$B!Ookq*tMpw@'uuLM_u Z {(|>y9 .oI}PA0q&-0l +WLKl#X\vP8\rlL-oCrG[S`b;{!ψ'Wh++++y@d@>H'_ "6-oP^rJ*mf'%h;Aq>0tГvΞK|/ov lxn#KOS3.6ܖbd#%UȝGr'Gpn]q;y-@jS''$YRk'7H 9%%6Ud;t5 S?똪Zj$L,&^㳨\@#y]w1p}$;Z"%3T?Mu祝>Ωr!:d/ZL.YW@bX|rRa0Õ%q7wmy^U;[*U&RL\ʟWTh+(ODXiAOUѓgiS\2(4HMb|keSS׊[Į zA$KأNJD c7WnlBͨCfC0ɴMVQ0^ɹsKjܜ;@O|pZYLLlox$|g7/es ᓩPZUbi3Ϯzti>bU3|8z H 6;c au2:dXgjSS>;)d}|Qo)W9*2#=g9t$@-:< Ag-,''p}[TBtBC>)oMsM+),LHC쐖d69HoݰŷJ@wCtU;;H̐re0BS-i{T&!OlHmhxL$RW|G&#FWPw̡Jy 5镉fVg֞P| ,bb{޽_L񕎞PbD#X vXۃWXOTTk YG?~bE x=+]d GnMg܅tkNtOB%Fы|y a NPLvub"e`BH(#¾*+K϶E:kIYs Y]8yM/fU5LM(kDG!1]Zi7vL#|H BpG~G)MadvSn+%OS=sf|pPZf@]]Mͳ:E Ϳ I"X|Xp71%fh$Cܛ5 7Xs,//HJ0`x` |G5J;<ٌg;@&#ߒ~?~l9 Kz/sõ P{NOOc~C, oG>7YLukDx 2V_k&+b/J!4 mL)L@py ,Cu@`h#oɐdiVa\V~KFIK 6⻵oŽVBb\"( }[ ކP~䈏߷wLV--J1\Z1|ft2? A,XFE&|#ϻ¨0 #Ifz2|V>Pui453n!-{ ,nU[NĘҋ˥$1CBb^3MWx ?v'tۋg#Hy#r_# vHn]| ?#9:ڐW4{~ >2x&;\Vf[5PRA>ҫ*Ǭ!a R5XPo1M{9<\U7z6!끣P ?'%113SkNۢ(.D޹gΑ@2={*izȷ D'q(@H2?-]sY>#..ov7N$7}ź^k/r"J^T! '*5@?3#X k| t(2g-$7C&GI!Gqv0hU|m ˴W]d,* iUXdsg{u 1ӸL4L]/md$Rq ͡uKqSƋ3w/9dEи/._ ZqzKwuPkc\2a5٣D ~wLq/y%#6Ou@j=~ r:Z'Q|LO.epUkB ~Eu .͢,&?JxEEpIkj@}\:{8X/ fD3sPmŰ\Džj5k,AffhTI63hۡZ rD8ctźs، a :'lCCȎQcot,/tNP"xbgJ'ТZ}Օd՟i~"s :F \T@oT}?-䈥KBL1?Z=Bn 5:} V*Va䄯iZPc=~喲<:v߼TndJ]rG+q;k`dbdh,8ӡRDEJss{8>X']*e^N~^ڽկiP␏Ҭ_Y5/SkJ]  ^'W`YSM1r&5]w?'gܝ,@OncII~~R}6֚v;/jR$vS򜮫h6Y-r)Gu_4|L2=z4Ts"-݀ e,||N}zoEY!K*YH[fUQAǜD Ƶ6AEׯ{~0 T-M%qk$ck^Q$|/|neXۇ h2 $dP\}GPj4&O"^dGp &<  Q(&UτSg@yɴh֡aLݸGidgtᖱ1s^h; ALF7'V_]ER8 p 2Mqs#ߤG_'(1V;09qB_@(_RKi,OA`C=CYmR^ZthrgΝ B0"|g11״ڌAϋPhL5rV*ڊjel˜I_iu\Q$QBcl\τ$8wJ}Eo.U vvRE" p% ߠ"S!zط*L2%Y>`̨opj<>99-{ǽYYMVHES 1(å焬fM%Y KDs2Q0)b͏lb` HǏU?Z cYrV}3Q/MkYg5;CR4t#IAxtS=v>2Mj_Ou!_dgg:FZϸ~֘2W ^br,]ZnyÕ,|Xݕ72 9f}Eת{rwQᇇ^ 50ZIUD9= JBL_,)bD2Փ\>ήQϾ!"$qŞC?09)飋}gk~Ω3K- q6!(=˳g7ml 4|hnÀBu ft} ژ.Ɲ71 *-w`a13۫ ? yhE)Ќ*VtxdV=إzj%ev5-QnE=% dl:%N0}aP`ď죄 ;Yrƒǖvb,ihh[i3 #Md:*"]a:Gڀ WĂZQ@}-/7&19Vs\3^.Ei!z&5U(G5s͔ge:d94!0!'Wy 1zb˟8$;`>jIGe y {( d0%ߖV$kAh =$ǗaK!a>t`#+\:.\ك[ĺ6}չ ~I~$d ~7^G v={lޖjI+&.<׆aAxQ²rk] ]"h^7um=zM Fn A}um[׎bqBB`hzf  ™ OܩpsoDlȹ睖ďz>>Y TRb*^mHAyGTcBڴ-S[pM433SB#SB 4Q8>/[fdm白|`O5o@,,`>aQP`c*L3}`F;F$ʬ/_pNb.p1=C^Z Z_ڦ¥z0T<"`)r*8ׇM' Uj`eQ+V6 L5yW:n%Vs'U}o%~?3M. CA&SX,iMq]6*~_][@|53`[=tf([Bp tBBae_w,?ыn[$طRlCir9w_ԶDδhmI͊f|csd:BՔc E4ͤ3CCKI xjA~榐ۺ܁zU@2~]+C%f~we:` yߤa@ޠnU/6i#<[(Pٕ-4Pz||LV+qmAo!I=֖s˗71 lƅ@m7gDvkm@b<_|4|v}wL %W:͍Ј|Pa-g xqj%+8oaPUX\njьByrij kgO 49YYXT33>[>Dvi޷ٲMLs31=aڱ]bKf:ZE5qlh`RɈ6'QJ%XK09ՉX8%_zbװs|_7೫Jp MDEl0|.rRfΆwGOŨXfߍ eU]#gާHRhU?Xd':t0$8xS~C;.|g5/h/'_ȏYl~ O 9,4ZgR$R 8K?~bKm_y1!Yd~֠V=|޸U KVU3wixSaGRRg~!\[a$pEc?Pz{ۡD/qm-aQSf. ʊi*fVtstUhphv?> d/6\`PPjո2- hM_N؟9+~cW yogB) X#Nl葑(fj/E PGNSWIt\QYe ,8گ8ڄr \}ZqXӗa> ^(5qkv2G 5YfՒiτrKIi!g2J/'4u65"F!؆h/ ^QAz5SlUѤxa,Li򸥌8U,F6sڿz2W%t>^QR3|IM;FMb4[̻6RϪSs=Y]M5=J1OE=l]  x44"Y hk 7:eyOSc>uD:֥gU5KUKHBf|.a۵T. xvǮj3,re3# @h0[Qt +5\71zoG,K5*~7<^VcЃF q9 an qt˭ly[5-0c1sѫ $pnu%0 ̧rtGB P H*wOt+{"QU׋}GS'eӴՃ}=a$NG_嵽yСǫq1g?ck h&_s">_/C,?扁XJ4]71r\V/D XQܢ \!Kzy4 ꇃKr[pE ~qL9Gm528qk reXd F ̲320x R,&[@'ON]Xǵ*I1K@_sio{+plx*3OНKo"Rg;aB΅;o1nviڕ,ӿÈ|&%B.Un =S5MMst F"|??#i"do9?@HNbi_ Jz ПБjlW濱b}4(*? *R+*jV"$ECӭ\+Tj Ǣ' ;/-Ns-8VX,|8rrT{|w*fūp?֐<#[y:ZÞ<1E*jǙ$.!IBI@Y4ԉg%8J}* nSӰ{^a6J40z-]EJ" ^<~uH@[LMeͲ-"|_oz"M~=HyӨB}" :믽OhBf&iL}IC>'3&W{dǣf'1&~xr;Qx#!^i`IIh6vE{'<0~iH^}35`$-LH{x}l֕PJ^I(d4T2#+ifKT I -3Ie;ާ?~}s95yC優vVXp0i! Z+l38me3G8_~m+鮃M 3 {QB!HuمDX~'GFM&g~f ]pLp4@7])YvWޙ м|M{p%h`*GYj/ Wq$WJò_7-]\>b"Piߤ%q_KCz7`KNNg5eZ<r[4\ܗtCa H~k.lG5rXpr );b`H! shQSV@s׺:D~qQq @b$~7nXO>!=Ƭ7a0~[ŘVэcKE'\ic~U[;PCgj~aW>?޲(Ak9" @nn?K-ZV뮀ƒ@EuwwLӪQÐ'V˾E5|&jHH[?V? UH).c+>7Sb- ri:eY}hMǬG՛{O[6];coar7i|!곸;dm¹lU`>&7Wy$_a 7e}۷m߮$x#JfL?XHmmN}A_C]Q4g`'Uy1Z 3|'h6|!455AIƋ"-/{Ր;lkR)n0ˮ]\>][PrVa4lpL"٘dCY3fyýLb.*O̹PzQޅܲwv.}΍|XՉΝMK(-YXP~\d 6(P &ϳ'22?<X{쵰I啩ǞCto5]KMv~n4Ʒ%̪ޔ֫5y[F]beA G| %V-g8ƾҰ5rnr/Tf('{dٖWYIhZ~lF0B+JyR̃EbY(д JZJ⃚t B>҇t*5[D&*ZXaw_SO*w_xJP&o!KNeO|˚{wv *1Pmjߨ {^7D׶Ⓣ9|oJóݬ[JC(0 }*v1={@py2^Qu]M%!շ_7|i}wӡ؏Y`^xB/W9W|NAή6(`Yrv@(dɢ!xAXK;t75PtZnwqR4;bB ;?n2Ʀ~5 ΔzԼEԻI.xO³Қh(&뽾O;6 U6Q"J|0Oi-Ei諭vjABI|v#E<iudQa. }s2iNseT>3?LP?*(qN:]k[`N1M}1]GLe"]yL:1H,LuUoȮ:.-ttS̺M gL{a8#P@EۮqU`&Xb|,z/#N0TaC ۞Rjp3%@-5.ǝ:}jj Ң?OG OQ<S4rơwƱ _q-Wvb!(*"bw5jW,᪬K ,C% .:EF& J|HxVD0*?L|gjYsݚgFaCS} lp(c ose|ؘw㣚, s5BށURt3$^y $OeʰǁZ@P޾ -U9;Ɯ -3O?32$=[Xfnz)_m*9ߌKD{'ePwͱpip~IGFU$f_j@*&" 5l' -|h20ֳ Ϙr., E`iZ%tj՗OG|){3(q0550y~.66>5$q;x_T%PP@@dΟw?{ZFfW`/#,|Pd߳CLv8-(HDv-F v6jkƖEK z=-}.fP'|}%p\I9T/xh?|# `~~Ct|nq).^D{"]~+Cks]CiI͑w0=T[,>KIlVYn=,#(ktMQ}H9=[X񮫻{Y\FDj?zy4[-5U]! I) Xi|ЂFg>|ًAV(o- m֌VI7z%{&؝7%G]pW R:w؀C;h;^:>7LPDy”pVI/=ń\olg.Q*u}J{1] [ >LboúQ-8P%;:nQ}=^j\lؼ3/XF:**@vTODR̀S@뷒<4Bnan.lAZQG1}%eiS{.As$: w迪 wϐU~t¹5M_41$H;.&b7iP pE;1TϡKC3o[&I,/U:K$:F`ڏ )Q8B>> idѾ߄/x'aI2_Hܬ/Vqa |˪ Qٮ[tie tIR=]'=ғ1:eVk5nݿ`A4ɛL3$uE>f;i"3bWWFsJE #3'8*+fg_"aTχqs 3g˩Жc|zg 6QbXs 7Hn޲y2A8X{Q#F~pNjsFO[Bp]D3mzFFj~F?VkkwbH5w/\R&BҒk򧿿"|G쨯lt/hl&2*\/=1;wWf}&GPNΓS7)jG_nS6boI}099\90ȬM1S#B,]qč;wxA,8,%+,*aaa}7~/.[+[ .Sa4\$1G-kNPMCus4Ponm c+ٲ*͏wۖZxwCY olc}Rœ@=Vԓ )^R~/~LPb=4uػG,_S$Ȱl9xɨ xe^d2˓ƀ"x+n43?> x޽ _اXA۫G@U$}1QxJ7*!E  ɸY7nK/`.W70ָ]ގ $H{~ )3%<]ٰsNKct1hžU*XF_ϮQ)<}@/M[MP[3ѿr( p/|7غVasHpDjI픐`dZfxĥ y ͹Me֨8JqS +Y"r\(4%llST>aa7]CCb]]BG#fJXl Dlg8n;|7(kt4|fSzEp"#6r7s񋉹5&D˅v=h)9Ah@=r{ļ}mu68iϜՍkڡzs"IȡTTcbĈʦ;`PTfL8edKNe_x>̉;+NkȯP |W[,9)`+_ D'W[{ ϟ7r2@aBe-Tqv GCOƖwPFə#pO/\= CkN~^^BpQ&l=f_h !M@Yݐ)X(t70p:25)?J WMuAƵ `[*WrFf&⳧i0T^18ܘ&bUa{);qQ9A njY 2AT;B>Ү0| Y-+7d.ʈ ϟ=h6잖?w餉!AL^T 5X9C~Q 2Ab)YW%?Ki'␆U Fpgg>4+LB6[Ip8(oi'񬌣,|^t){>U}{T==&5>ȝ<'A[X 2C F݆w(kpAvVq|벵C]O_FJV#B$B,F")S[5/([ O؞юcfŪ~ 4.-M(Po[uf'x#EGmNBt,;BVw+߸x"{vu0#w( ir`C@Eة~Š@7}a ]ccuy.h$Ѐo) Tɳ?~5uGmA" CAc%oU{F'g'H@ _pq2z/7wxe Xe\V'{NV,}_iA} zat!˅B6ͤU!A1Jk61؀Gb҄n^IWspJAWBٳx4yLnr=51́XU+8'pGlq@ A>oɝY9wLU{6)&3Vq$`/053vIijQjZGlYP>lNS,R >ǻA F X6^WNHJIP2yYw2iKj`M=3KiF^r#Ϙu_ْ^hT eL+ff/<D(_w9OrӶi` CYJ؈Mep"_B"&!-?pq㖿. Q0 1L\JÀ/@xIϏNe= ItO~V퀑Kvlb`@JF=ٜv`ޏ24/Kǿ=ئ$=Xd`qh7ozUL`F+)w #gy/z2xI‘L0f}~;\EexfZ}6WCoB\."k} 0k 6>,֫n?7iJ6[* >iPFP;slH$5Zc &p\:Nd/^GY{AF5T?px+ jdB2. }]Q3܃C){l zCSy;~^/B֦SԀ& xA}TSb1a޽$uU)9Pgșz(;< T3%TLK8K5oAg!KExbvp8Nw/ϿSirZ'(11;mZ7 1d%,얖FM0UI؛ ' ~4mb/#\ƴr&uF[NMT Gr$kga؅[-?,\uzǝasr8.4^20M;I ېхTLSueZ#AַO4qIJIk>! HJJ pA7mLEu[%u[Ppno'`@.:DG{ԖTh3z1_PQ>U\STc}u6c~/b㨗aˆ< `xZC+{Iޯ@!V~AƒӢF)C4,Ӂ*%}A`|4iHuo|ptݛn 'z&XQ.`.%VMxaPhaS^z#̒ 0!ID`^!3Z<  -Z!}EH\;pIz1\Váwh' [Tkނ,PQ~\d`D([HN }waFWlJ_UUpë7S!OGkhSFR7a҅[FFv%ks!:[ݻIjL"#"=~LLqSG> ؽ_ضUF<Q$;T,fN@WAE%yExc37kd1(O_Yp~LLǷ)J%~@X@̐4--ע8Վb|ClC`4#"A7dq\h+Vd7ge4-pB6ςpYDyen'#c`,0dW̾\#ok5n͸RkAJu@RoqBGuphpk[) 5K+<W~!ҠMg"wUh4`kP[\D#Opp S[Fh5`Ovڍjdpi0ϟ `^sj\KqN8j` Rⷴq<c/M6*6;6+;jb!_TEN喆HIf)_ke@|fq(d.C\Њ@R<X5TZ#w3IFUB&HW+ecaeBeUTQO= j ')0ŅFrb$ݝ8W6Eί?+7ۥnPt+==OlE|){*|s=iP9ĩXp@eOFn?hȈcǝMw㛖) ﱷQR⇮ lJRCbE@bP@Q Ը|8 ˤϔcTZ 70 I9ŠC^ II/ r[+[ּpL SD!LeLE_ g<4.884PkڽPjV0m}Qߺ?~a~FFQĞfoh:?6 @p 6¯xHЧmW|yODmACgbĚ,c \E `pNV}< Z=s9>%QUry!2TOK0DPA2,A*?ia>sJ]Ux0;AUԔp|U(T4^af@7Esg8/$G=  Ȑ;)܀H>MU A:: rnfIdW/*=xi&5f\`;Ty;T5RswV9´tz8wY3?tD:X;e&F (_G'-Fnf(W\vfja]͹Ӟ<;ힾj*0qt]KC $O/ݴiYw0~RW֢+,)`{X/"zlk.x*Ð&Oh{=ň$ j):ׁ={6Zk8@$P~ҴVIS @y͆ U;CmervqjQ Nֹ& *ܵ?2ӦWYmA#~F,s}۽[C5Xe/~׍f'zp2zlbEg&Wx?_cvꢙ/o ໼[zyE'0FK+Zm.%4T+7ܭ!Evu+c|i M`@c{r9gZ΂w"[]"Y$@=V[tA>o"k=3<]6dg1 )>vWNmy Up^&|ߣz0J ˑw`.ojP2>;E'&Exʴ0^%jI:hr x.#|~ 'SAYsXOWVR>N@-eac ,;)?zȴYش~ ^!NG<"~{r 'jb3"h^> gqϹ!5~R/L+.35XGqù IަX1h}.zD=h*Wm~ש0G @" {Xf/}b1tLߌi~P)kW`=f@;iJM ޳/}}^1eXz(Zt!7|p'/XBȦt͚wSv0r h4t8ʊ-edKQB>JڵkaS+695waç/y{<`B%|!cmZYl+ɜJ VEߎ K-DQH/V0((*psչ21txmd-bj9uQeh "]';[(,߿?v*$> DʹӧVvME M]rK]o,H JNSڠ5 j }ݳ DJis;;8 m!2Tj؁3TTTȰl&8H K8j3>nJtD*PR9Eǎ" <޽{wZFI>79j퀓Y4= "WTw(e_ \g0ȧp(INCU]\0[È g?nކܔWQ߃iѡOHd]cTyJ;B"70O<=ZG'N’Ǖ_)m@CBS \yfeȜ@}udzP* ݗ EAWMЇ 막HUx_&$8`̖j;EjH"8xyo䙟:72з{AyZZvF } XqҦR*jT<3⸣Nn i+{u0 \y@jG^p$4yYcGZNP!x4ާZ #xyuS?D($.:&@/ĤFD;M`ԍ|\ ϵEh幺,CQu __ˀ닖%=K&p} j'i`+ Lҭ֯6mjmQGW:wEY'ߝǢc!?M$qeEByE9QKʀ^1h]&;_Jixﰺ!0-AǏ yaN556*0`uLO .9uhI|{H &ً\M9 V0򝘽hbxʫrf}[];眽F Xzm^S{rÆ( "LR. 9N#q6jEX& Q=<;ء-x:'>se&ahtFmei 0%ޢz)(Aqo9]LiHgvuAJ),Id'(+ΉژfB@Q_Q NKhאK;"ԻepG݁`f}(i (SS;uvumfVh%iz݋E#Y';V΀L-3rS^^Ɂ!jէTjK*VNa?|jz ׏3™? :m2kbh(.\A褡2|1*U4?`Fsc~̒i) e޺6ؾsBM5 Qa1IolG名8dv9NǘOzF:ꍂeC?i<<*b[ڸ+h +P ʤKICKwEϛFb\]#:\aGpԘ4Nl+>BVX69ײ OMKK߸N}c`uz=='櫚}J4ʛ&QdB|7<Vm3V4t$g̣+s(//aoPi2;ς\j ޚKOzoBPVϮ\(PiVj@=pӝE]ݳuM\D!!ڈCՀBo S[*, 8]7۬o_BNFM15\Ҙ<_Z\rjNJMdm)Ë(ex^>iZ K3liqIMu!,yvbɨ>^qq*%i{jd~sQDP/f50ZAylNÈq:S?]zy8xJ}@u1y_?[4gaFB,ޚ0Tȅ*&3Xh8N,Ͽ+SMP̾g03"Ćt̐ˠ"е Ĩ뗻 SUҹ5?~((;CAfX/ˏ|W΋ߓ+@~x|ٽEZ[u}a#O>yӏʝ[x$n pQUO 6\J!!5 nH&Z\FxjfiYͪ8U M,C"0ZF)p0& crB͌wg=z!<* !>qyiX%qUQb7Yg2. x[G0bњ$'#&E+k?px]DQo '?K}XU#mmل).B̼W1ӽ<[~ƐW/5|lÚv];4|x bÝ>$wi iT^?a4GU.P&fNjLJ1LkRw~L&Z|o2ݣ`~ u)~>mxۖ!E1䦡ŀKZX EG`m 77ƅ"@NShx?O+,wx"d֭[xсh.P#bŤz/y6ٔ`x /zʕ›n=!wc8+bpnݶ NU)DC4C( ׮_G{}vg2`a]zڼE4Dqä\__20`< &L{1[T|1!kȨ3 <7>M67Bgl<8n9~UGt0H93SM%T]f{f9v&5'i\]1f' BwZY3ʿLG{24ReFl'N|'ObbLt(:ʢPn ?jp\ ~kEX 4֮Mt8uv װUȌ&*GXB\<⣉5wTIyal EnIȚhjfY߯eL{7m񗹘(~:C% zQ__{'x66O N ,ILbgCXݭᕀSz9*'\Nn#D\(Z\M6g$a.3a94qt^r:3ez|FgG̕+T9[ {曚Fa/c٘A ;CA$onBNSo>zԷ?}ZŀtJ"Z~yV5a,#I8( -ybWW>RnFrE~~/ƽ'g4Pݿ4P77@9dVȔ hA.:/_zmH͵pg/qxJI٨אOyg4VmWnry9?Cf ƿyay˕`,{H!3JX:-%nlp19bJ[^{6B[Y4A;x4X}t4K1@vg@2G+9lOM&a2l'oی#ݍQA_)"H "ww)dgd#-j`0;:9}<(-Y u,탙L _Tr$,oP?ikq 1Jut%UBze7g|)+B,M׌i椠NmlxVY2돱{3}U#afc^s-{~PFX7Xs %m410E SK-W?Z5::?g ˺%ƥs:EOjC\9tqyZ3V{ٝ0yUG >r.#{P/)#ʹ1a1.IR|Qͦ 3ti]](U쾜;ȖSX])&`o /<9Yb=NukF;uܚPp J>2H#Y!^NW陰3,TiGM?|Fly]e/2!՞7© Q)T`1 =lpQPkP׊_Eξݾ~0eƨʀ"r\9b'ԎA+g-&֭T0!NgAWmPv7k7z EtX yS7/7(Xpl,./f܎Ю%-3XFo79\xT|4tQ@Tl\=8.LhoH7 ir5ؒTT aF[V`RH#/_cag܇DiaCR1Uӭ-4h=>zUۘALuW6f#V5DҒTgSpo,+OG$s/4(#kèzJ5~ ͮv-k)lSR&4 J=mkN!LvSO>_\[Rlm=kjʦ$5 _bf&cM!WBZGqwd L}=ӳnT/܊S=?n]E{8g8G%_}tS r ?Ǜuu (ȯaƐ$M#_%~yy2@bkGWW~+A(B?<4PϏ8%G^Gbb M<9iqs s 8T"A+g: C JjEAujPlX~o[E"`E@qЃBL~uhAaIv(zpPYp=$%%ZRgXRye ǖO|('>R}Sl9>?\~;{Ǫx Fxe^Jׯa[CRx)ֿzeTDNN6 y.àx4ŕiiRrrW)I0{ա0`Oߢ :{B:V-)n{7nHu܍?jX\9Cɶ~q+Zok $;q[v4*9:P}'\o @yM;唪7hB<5w #Ojv[6}d,dJaEL۲F2ו¢6;Ym X"^WDQMSJlnTy.o]mr8nzΆ)q;=p#2^$"]/$L#'>U 1;U9]CKxZ{|ZǤw}AT9p619op1{wx}ƣ IBp,RfA])HLۯR~?|(UYӺr*/Æc$mˤI&O63yWWG<݆@`J$IS2bFy´Iߚ\C*D6 q3?@yR&Rbb^o*P|~ JZojah=E[; ,ЀM F>2BCcu!/RgCOW.v֟,Lm{Q3c'`?zPSbXj7%]%)Cz!KR z&Q` b]}bd°d+cG}˶܂djH^*܇ RSŊ<{7\ĝ>psWf-a]by{NUو:a}wQJLnwc" $و88y0)R4ncrŁpkn-'*d7S+>nUK muVd*,IΞཛྷ_]7<ѧN]*bZ';~M`iz|=,' вˆHW==ςeh&V5' >3Pj+U\Z9My٨|‚/J=]+DAYsxVBwN~7M-\U~TM~s{QEfq9wnryuԆDG}L2 O'6ryU2+ 1F ]įϤ!f[mMrg/QDAp)k& DS_6b\٣`7OTn \tWFM̫l_ppfpׁlh!"K7?{nA.# i"|CX7nIҏQԅ욄Sh".GJޮE-q~;F>|xrt\ (>udn4@5p7 ׁEB?ΛANCngIv+lY#ekFNVf,ͤŶa2ڕ`?K<pqU#'yUgudU}z#r2YnW4D=ʼnS_9vwSɚg,Q~Q>巁A>%Ү^%r9å](ONMkmGc.+aG_;dOqhe{&! 5sk[2{tw 7A0+#=گa4['ZDHcP^ͮ6̼XMl>?_xN6fþJco+N! X7¸YZؔ#7(6ى~`ȋaCt_ q\m8}KDT^Qf {Bh#BBޛddeHQBF3|uu>G8Yg5]my o֓_CY=T4piG gbn=( nEYrE[=I*Tu,T O3?gK(gҔݱY Ňhڀ6iGtEA}*f+b-;^}&+/p~fR/};H/L%Z\Y03W"LBklWΞ~ߚ< (GV!_dg- nOgG"# m˳<3~1FhWEeǺY>,Bt(MY [~>!:63'>#` AY՝s^|]aUn0avpg9`P[q'I[To<"k$NaP a_~@>)*&m۶7َĿ>J39Z0)#uMʏ5PHVVe:l7p1% 2l)8OWq띠ٗuN#vjkk8\0;|P*K=ę3g"_y'h(HE=Db"|+>0|±ׁK^Grk$3!"0xr(IUUfs( fAepc.]u_[:|,8 ft7`"iG$;QBYrgH`.J@E@鞈|.qklVI]*yfBUbYΈ{Q!f8,=+9 871(a xCgK&"9u0^gfZc/^ vv('}l mi7&+!GM|=t^+7?س8`˨1q 5`-&Ȗpףc:bS%*2ۯVK5YNAE%y V$k1 ˝{΢ L+zx!1=ޚN_ܖ S_6*g2fl2^w]4 MS;j|Uu_',b8vۓLnjVwA}=G^ !6BO_(^i*WHC]}y\FNʓ?ʐn<] bq숨 j˨ UԫrrX7Z}K݆ TW9<މuiI"" 0/yc=E`7*UWk]Q~v\082"FZO}c`;ǿI e+ճI SVbE*!ʬ]8X$>!}mnqQ#5 j]Ny+zgщ9+Fs;ՙ^+y[sn"2;'N JW)*zo)CY$zjb>Yux=D,J`Ww7zYij}ق%֠%8L W(0!^xjm83 c#r&h'<}}с-ddVZcqCθ[ Zo&}&$xE11}@GLMmb".~`i=c8+-Vo_^sXLwu!Οwį(,AO<_#dM!A1/%~l0<\ RV>cy_&40"bgI8C·&fj{ s< +->Z~p>X)rM ݨڶ&_!U+C3l ?Nj+息WByT12mE' |~/"diOV ӱ\Hl"{0~{q+:GYpp:%}lg7߾HX]aScjQwQu5sԛv  +Q4vĦm*/U_E9O3lKNh7>q,,V=`۷AchmsȘ[×pa]^㋜?O~L-C,5YVnvo*\ b{ ^jqƀ{]_^.U> |s1La{ht竭9a7I0qVC#SW|+ fi[ $it2N?DڵQuOeW34¨)(6~fU(ޘ̸Q؄Ib0Gq2+L#~G3 #\Cg6$Du< rɮDIhH.^9K^Ά6dup!.z-)å6_ D70h:FޞV[SxF`? ;zY@q^ r?GA ɥKa/^4;->_h`[=|/bZw~1W٭sȞ"}V:%54Lp:IaLE4q%nv!H |1mҧ, Jb7%|{|7.ɔ8?;pe"jN/ JyZNuZRpE7'؇5;l ̆ )1nA#<UX=Աb}6<~r¼Z~b=i>|9 vr:d&()hc'ȷ{l؉q4aeq*΁aLcX 1j-7zYƼ{Mߓ#r5LƤ7!$H ʅ N,))ء 3[yt^=D/t0].L9=?PmI׀nXAn[Q%aHZM gn3QclwD㣗':i )aNs4!nmNl,ʟ|FZQ *D~{=\xpTTd=*26ʩHX<<=xuG|=7~u6x&%&pR?;@r0246hƨ U.\FMӁ=xۖ s8R GR|htp/hHk2LQOPy,lHB|[_iTWp:M!s2dܹ9}%C##Zs *9(~4c\z nnL 5.| 褮D#Zweni{QQՖ C]x%S7V ,4_\>-9ӶOزDWdTLyekEYT<vjty9N_We<^<:荻$5}UǧH*^|DEEa UhUWxm F[tG& [\K/6 ge}}A>AA3Hɿ  BT:~풦Qjy3F>;}ZNI'رQyh]mfffL~ O:v?ܨncV(+WFD*}:XF͑QiʱͼGJ; h=4 q҉j;rD(ޗC{5lM4<Tvj<z;8srD\G܃ LD8͗dj` .>4TjyN4\!_.>۵0hc#=&Y/U -A|dmtpᕙaqU$_OY,s=7?X(hsRwf=#.ٕ'mk1ܣe7tΞw ҹ>ꉟ!Ր~jp@kޟ^Ҳϫn!W%Rֵjc[+zQa4ѩf8_%!f<B; nKE;f ԱR1wpϝw,f鎬wǂL +bF?kԶ`<ݝbsÎљ:0Ӕq- }mbgA_ZYm{{肄m_ӝ9lCH#ߧ '?]:11j6+>qX*~yBɅ$"gc5 zjLw'A&<ƛ65XGWNk!8tt)T fYŽ}{.T8 Zlp|]<w>Y=VQD:a^R`^OMN籟п#>F9Y~0n(zjΥeot)p%b/D>we@)GlC=[w XÙGr/o?mw^סS[* )SSug9˚bA @//sګeЄ) 8%胻'9ާS p!nˀab8u@ݼaZc1"Iq++FĭK`ͩcIS'Ob$V΋~|`0c,NoC#Nw O.4}Z(娎f @vmOdIctOGA# mFlAm㌳)W$7vR 7z7င\6!W`THL\z :1W;p[4fq<OvcPDLGfIms ջs8wdaF"|BI+W{ɂ7&G,YiimMKai\ ,bpѺ`${0kWcW- C\=K9Ğ2N%<;uyf-.+羏-J<:t5 To jkmE:!{w}4^8֐|AP+₅+ dOme=#)vbPm3#Pb4{Rg奮eN-9Ġ%_GL|UHL؟;g-Oi/ $`Irc)<>Yxi_d;06^WR}"h!TQr̉+z[f 8ʘ lO}$xg *iFtlpv;tƒRZA\+r'keۈ4Ovk؎pr>@AvGSɧ8@>AQtHqW!V|3fa|v I_ 6!ZʝJ|HeFOq`n2eֈ_64إ*Ӹ`8|FLf.Ŕy>ZŢwRTbPc {ogo0kB X~L@ H|JrVtR6 @r" LSS \ΗAR\qx1b"UPGgl(%#y+5 L7SQWŭ[3SSO᪂G$F `XM-00!K{, {:5ρmn2YS;ZjRK6$`FQhOrf$b:4=^ck~6\V0> :Gs‰JvpD2dLϻD<( >;/Pg,}t+6W/[B(-: $LZ8R֊`JD}EepJbU}/J>_J8kC)jυ= 3N/l~JPD W+JNJ8:%#CҌ%V "GD, AU_ٵB,-syp7VSCK!TzQm䤤 n:\z}Fw8Oa,ՌJ*A|~\qGξ{e;"wǡN~̫o tlt b5~X$$"l<"#߅m5 FJn#Qaj|Ĭz} 3H<,,Q{8'ǰPBFjJx4,ZiXyJbM(?ŵ8/"hsB#3Ovl ܠFI`ej8%M@7i*^sNBh\ ;'Sy1L]! Ѡ P-J/9=KztV .(+WWK|OW [^kl'"aQx'űpUlydJm^7vS77uǤ{.}7d-zȜ>![aaav[!@,YߜY--R& !Ikz.As¬,.V֪7o =QDùeXapNXw7Gr<ȮIY`}/fU9M >N~afI|0O199[sZ͵n+>D#A&bzZUY]/ٮfcXt9<X(: oS 'hp(2jO}֣H3\vϹ B׸Z󛥍\@5lH^GK?FY y~(*Z'g %.VȪ0Xy$%o ÜAacU ErL*`@>b/('fͧ;de~}u<o/Uި:OG3;n3޴6*Rbye҉C|V9x@"[0}\wݶ/FM;YXE$Qw"brÜG$##˰~٢D0| ob 4bYV ԁ[ j ry"a/]h;A<'t^nL*ch7I3zJj)l1PJ"H.d~(Ths,8Ub'qooŮƬyI4dwu@w 9hX/uymjCcI z ޹.煬7vAMIhffb9a64XsζT;S ,( q+ʉ<,AE1!5U-4+5K'#0J7=:(OVY! Yf1D7&Z1q&^{2.ũŀnqjz1Rw$Cӵ%|OM]a]U:v1alASTb yI4Ѿy4r[`EkA~7[tBUuoJuY(fݾVbe߂wv64ƃ ,ێUa]8wC Uiˡh +,<gHc\ސ(6((+Y֐hjv@>̯[əoȺ_x8j1w[-煉y;"~-J8@s!w@fK ?k}}:Kﰸpm'A>|x\oy:Vݕ%S0m{N LfJ7'u-N@q!W+s^@j;1\Gb?4# 6 یTKQ9u#.i_svCulڱ?_ͩ!~?9mr !D-o}(XDV`T\~nak2VV`OTeJB[m7D)xgUǣ5>T<r/z ŅcE}HIA1E#֡#_+[1bs0U*i"D]-qϝfpw0x@c3e(??012ZlFA tw*S)9ˬ5uk@%,,%>0V9Ro]Jcȡ~ũF0ћ Juh;i>[E%m`Ԑ˻C(Hd€h3I4scYZ/]Zp jeu5?_&!Kf^͸%.3 YV?$Zq)E/)!SqcRM}47rB/bIKᙢ n.6TG wMˌ D 8Q4 3y]Lz +b5X-R|UK).%=QM칾AENsmbVhN:FItH/vnu܋/d| @|ЗF0 1KFj?= 0Orf|\љqc).3qӦb,H ^X$z>l]YF/UNdd \ldF̤mVѨL- 9XXPI^yArG-|٤yeXQ1 MML dhw=;2ضuU؀@4`iP|gocs {)OD|x{qف2l5iY8KD XO|8e.F?҄jA {z(Q[OYKwl f ڌ3zY&]ׯ %UlmFvl"Vhc$?BW!wrw~ mru6@|# i7'C'Q 4>1ט1{xOF5bծE.l,ۦ/e/mpX1lDj4SQ,L ԓlcŠ 9 GzI}c${%g(ϖ(#iiv0J>Š;)%|9Lq@ -NY$ZRdN'b7ĭ8jųe,_ [q뙖adww3 Ve#3P!ڵ3.|`L~_äa-*2)1c'jwo6f|*e})GdfeRNS?H:}1MPdžwV9oMml9J߀KU0]mY"-_IK3ۤ h;˾oYD4Osm@* ]@dÎ^8*4|~$L{q! UeeR*U 2n)]@FA[ސU;~^SuVwGy.ec|zlIGX] 桭`14F>jjH&YYY ։r4mDZˣ}* ):`*uh޽zv*5NȒqZf? YA+)!u>M}KLC2nk>hcႣskE-uַ[Ec SHPً[S&?ņXiO<\ `iZd"7q'"-MU)=&3P,qrrR{*t#b퟾cڅ]o1M皞RtyړcT%$->ch#ofdH&%|M.430Vgqtu܎*iˊ@~#ܒҐȊUZrVFiHtLlԶ+\Y+nWo,5悸Ua:IF2b=TUQEpm[zqa1{Ys]>dneRHs3+-Q)3>q>)aVH(d-؟fJmhlj=pbNBLvĆ`vS6 ,`悫]b|Bk&4,l h{RqKW]ˊ!81s P=^Ӱ^u ~#"ds9pu?}Gz-ȝh$>5bVEh -]Eωv*dS2!#Gs5:A̕ztX8kuZWpvݕelj .I)?e JȓŨMgK8yOE7r% R&,S5V Z\Z xs>WH@n/$Uu2L% sv`HuT *,(Z-͆& ܪR;wԎPY{"VstZ,1PIk>|@Y"v9?7~|V9?0(Rkסb9,@0~d?HMީ z.<:`qCo<vUm?cA_DK?By*3~Ԁ'rTh A Q(VVSMԉz0fM 8_bb[=AѶ52&?~+~n"Đ9UBw1^ObCLLd Cj=♓,T\VkwnD{1Ŗb u ְySzj_C L\ܮX HPQM Z-!^ LW.Пu9$vd&%$GHe (0ڀPpvvF}efJ) f8Wwx8ן^g73 ;ϾF: &0~X"eVsM7*"Q I:Gi8XT1M  ;>Ki_ps;&' &WbM*1+?S qJ^LBܺЪ51J?Ǡ{UD;}}8Fx .BiDh7pw]~bUs~vխ^>[}L0]LK(G3u"p&JWҒT/\oUazS8yyUtʆd[S=>+[O,6cm}:g @kpy,ƋCH0c"ZQ <_ky—~˘E.o)1.v 3mR ׯ\9@=-ȳgUe=$'Q?󏛌O`<#zq#e LJ$r;-E ZdSHz3^@[?::Iȼjc}w_jy"O=mcU;zx>!|'S8U7!\$S}QfWɸDäpp?PȫqӔ'ʿebfO,%@g^ 묆tz-^ZǪvw6b٭8_Y~jcAlUUx %DNh7i"u5%1^en3͜K|PjgLحyhu~_ qv,LgK*zPųŰg7h?\{xѬTC-vH\4OxFھlo*p`*B 3`um7>KHTpִ_i;uyׯ ;s)gg =N+S8c:FW>T{|m֓,so$GrF%7i%",1!ONUU[43vБO4ژixױ=*jao&CCK Ձ &!I_ęUPtEH4t);&20 gCcT~ 2ϊ)zox5}&Vvjz,^ջ?cV6" ?v ^aSc_Mx1AV,/4_VEޏp &&&&,t~Q #xК~?o#$`;;3L$ gfaD,q/,k+#[S(^KmW11/u澑MBaHIDfɮ/hMDS?N66Kh. 9 5EJ M>(}@+y5sse06}{-MD;L?.]9⟫ D:w9xٹ'6h$ 2ͤq廒Ϧi/}&_l=$ -8kE\z Npd #jl!lE)4|شdi:ә@@iǯ@es$vԷ B TEF!"i4=͆ "Z]]wn'K6> d٬.j^"`3n%ToTk&LYݕBGTiw,PAW18Paܶ+:Τ̍EfTCܑ֝2S#r3#މBBC%O"@g?ץ(fQ7jqfV`[?a`q,@t4IU@0cgBW#f;Z8}hLkMiNp\L^-0:=`w1t2}XU(C/;F[S3ye4oΥ{PCD_IO\?-BɧJ$pJ43aΜL EܼyZ0Dn7wuE?f*?B%`Wb{O"BeONeKK +(Y_ wU%CiҢ6/9z]򛏍if51;3s1ѫ_o䈮~Alk6,U}ri7oF#"JQB 1tgҲ+2Ϩ %lƢ{o4W٘BCO3?He;IX҃k{1[OIs쏟B׻[BHz(#\5 mMU,!rxg&jӨDxU^~̆/7"-Ƹ~Ő19q_znW}k.kЏ> 'X'Wz;~ro44dftNx~iYd{M}C9>bQhB$w޺:~ZVNWnv~Zȅi @}a 4^;+;R.c]GNЫ9"UKNwvG8k{;B|P٨hMh;s[ <}IKK{emӌ 05<uU@oĤd ("!uiQ;~XGT)$u/0vzfq3$I GT >Û+Uď a*ZZ~=w%u_ P7{͌y"sLݼ%gGwKЇWa?]hj²֨%gOD-F Mo) _2nRQu-=ơ,y7K)  2&\wA@/fVo8TS ʾw~ƫ୳z ӶZ_8scpfT,F JSMPֺ!ۂ' ,ďvf%ď2j_Z  cþSu6U`3fVCd(*!l&MGt@, NS=Di?7Wm.MGr8ɰyCǪO6+w y-'-=H.{CXDGUu㰩3Ƶ×ckPgHHxU#е ԛ{wߥXk#Ze|\2;(GxqQ!GPJ>u"kj||WpΨ_&4bwA44ki*,s4F{fNiCLV0Mu'iwv+w ޫ; a:j%o `"G_vRy޳ZpT{Bi:/IJYk|ꯁo^wR ?jql?7Z^,”v|}r1MצGMYovNRszϛQfd鎡8NT`'+= *~GEM$ 9N碲 E\jP}F../# WUvt^D{- !Y'4#7(Q˃grP1}]0vD:jꝭ m{*xH蔂"n;njsiݿ6?y>ścڅm#<3>!cVu[5ך}\Luih9ÕclDk1gŹiG^Y:Nfu'@GCbERsQȝ=isu*  ?ix5:*ƚOg^,}V1ﵵ!buD&\v\X [Նd~'p*0 L3"̿[Q;pI-SÇd0pj̜1 wf߮9P\2ճ>1m扨\[X?iY!> 44a1Ԓ `S%eey1'o%J@ly-̽C[$^ٙỊ' "A PG7 pgOQI@Dդ]|Ŷ2/~𓯮#߭e-2|z NI";PP?Ə 'RQ)/9<<~ f߀/Dzsa&:Q߉y\K3wP"Fٵspps1qqqn`.}\T`3]5HH$-m _lB;2RR[d~D#\\yTP?'ZjΠ@ʗ;oTKYU^mn׽/g354z3zEEVKIYE5GR+NTQ]=+}}#Jg⽠#$w!$c^6:^^gyq忠L'ogc noa.`EJP!"o>WzCq`[H)TQSU@D?Jj;o"o. \Lts|G<%=`{CDE .p!SA+xqTF%Y^?A68xczDƍC]s#Ky@'"~FYp@6v N0VѭUS!g8`ŖN3)Q62R&dH?A J˕дhlahl:-cB9yh0 X$@q!N>i? ERZ-n!'Fd %mb \éQ^)l\~ Pv`@c,&ܤH :̵HwLn_xw {O`.8teķ1M 3GxKFpb yk7-&{ o x{ʝ%{/FbXvՍs.>jKFCDiwmq͆'_+9ȗegO>/Z?.cFd>ttܬ;2cr(~Q 3 p"уɉa{/Jxy3k8vG&nTTPNsW]οift'u\0,-GogWCNs gqvN|6#{ k~OTFo1zupdl[7C<%V.Ꚛ뒮qr@Wir??'V/I@TAJLV{8o#fxuȞ{Kh0Abѱ=F0&X40K h0mأd; af!SYgv^Zk"̞>HJ &o3Șf?1X  -5ٱ|LɥEt%_!@gQYX^Jf}wQ{wody;_;Xw\>KYURq}9/  l[v$9 yC&/0!!3iԉpI jk8]N<l 5 }gXU΀3H-%3uWb! %x/ݗĂ; P⇎^6,'qCb$7jW gUM`E65agb0n^U~<YľAgNyeuJ/߷{t=P<;wrDY(q9?;^.@y+C 3_5W3#ǧȘEc)/,łTZ#4о4wHbG&RȒrǪ6OALIb'wa? 1cI Nwiy AP,El䒆-Fљak/r_6gP]Hkr@D,XD-wh[S $>\1e`/zXʇNמ17U;AaվGC6WR=PkH t:q;EEYi *y 0I$Vg+wi | SW rV"~yy /ŋaM5>Q78>jg:Y%g(L3ʜH֙=v2S'g&>ai&kjw~[hTӳ޸tm+41sA$kaZɨeƘe\ '-{T̘p,4i~T4$l!3ȫHC`h4N~ Fo%EoUaʱ Y9]y=z]{#_>xM~UFgUG>uQdr<Z͉a\,*hb-|ڲQ-QӖ[v嶬y&<&>wuס C /Ri$FFFbh#Q~*O8w&vp*]"ܖZHq71H 0f/^[V4?PfIˆ Umժa$BGeiN(9uYEʶiN^5LĪhUD4pҐd"1À**v:[[ثU6Wg9[ {b+BVKGUxH'ܿySV6;zaֻ:cʉfCʬ_s׬߼1Tŝf<ݵ}5S;ԇ;TLj@̶ߒOUj@ 7Ћ| }&o)ic2`;zBKeS͛Ymj*O;R&1'|sM0 vP(6BW+ ˪6o{ \2aR~\,Nf ҫv?ˆ|J Pt [>=R"𗞞[uIZI D)e)("rt[I7GO(f;p=J 3LtP@>3vlL-+u=%weIޱfEh]7}:'G549v7(gO M'#+W_P̡ǏG/h7},qg 'VDN\K'̞{!BN$"-8 xîG,A+Ig>V@P1d`AۀċvT7h" /__)._ w}C~R+`2]-ep?%.L58?&ZٛPW8"V)|.oO'D/~M>qcU 80!; @NJR1w7!j8'jWE0 kW &-*ސ vB쌇;( Ɩ*f[E]ڤtP\9ݔm`2yVgv2@;ZIbH@p[1'0)m0FAyӟ֑`~֑d_Q O[&yTPT)f1o OwόMe(6񃗨bnuZT`ڼ[ W3/iK&bj3" vUa:{%߇^yv]r,`W_ʊ30gH 1MS'VdН| :z>cPHHHL2>=%isԪ@0MQ8)VwrbB\ QȪ~P&žhTTJJ 4(ZuJ&[&MN hr" J/Pè8r[ny[5Znp:봗=*0 R 2 ;}n?5dpn8O'2v++)hk =*84FӉH*>O,ãüŚXhA.led415jtIQ&W ߉|2mQ×tjǠ:zѝs ' xdsC@%\ J9my?46!>d8C*2RA&@O[;.x|GK0vޘb]+5Sk܇p{ٳEt?AE?c`>|_C̜6,/G?BqooAEJP<cWVQ: ƽ"ԱP5H:ba"nag`avcfJ*]]E z. $%ɱ(cZT-fwaE.SVF[rxLuVW'_wb",o!%]'iba.&3ѩ C Z?,ɯH9?MSjЇLj.Ic::݋PQG**/+uM,Xe04m+Vf3a\N8l×SOj_tR`v6n̷3?%0PU EÕpqsYgjI|ڐ, &:DfMbڭ[ Q,Mit‹nbE"ϰZa 4"z\ř SG)_Z3FW&`;z?{ܔad xG1̹ʨZT90"(8JՅZ U[EH! 5SYq!,V*3 0݊ `5E>uO4bRdCPEp=*epyDBÃfD"})wK횄Wl[SDBt/|:@z^Aʩ>9LU#V̉ BГczcx;8ڵk5> j3409ugjnI+V"8AlVX ?$*7oGm'hd,}$خc7>aJFu#sPc0ю~POOoaЦ{N{^ cr0Pbٕ*9I7M&QGTO7瞾á*/V)?[$2, PQ+Ltuv\~FKppF9+Cn6MBh/8%VH?]b AQC GNR!tگm 2ZwFX8Qt?}~`GoE+bgSTE6z= ]׫$ts-cltEV &VW=a>1+BҨ*tBV+i>9ʳ~c[ mٯ9Hۥ_J0)iW%I͕s׮~^E*G; .CN4JOHɫQkBGlHrST]#fmBذv^n֡~_<<_?P:a5BFvƤ4Xiic^5^)$e~r+ι+7"q:+ 2.0BG?v>E˗;p>BXb8廽ROX7A_h ê x2> ʝ.yy tj+XN%.jl<=vb6+ $ 64#13Gy8C]U[f\fĝ7ue'.Hz(|`~YɃ7qT]R4@;g^驩i"L3O<ݧO%P0%WC}Yz9l^j{N`hiJ h#m?T]D'4Fv$#^&P 8]r1MRk}ƺ+nt9^VhBE^{7W"蘬NmM5M-Qlg P]?M;wh O3ff/8~«>_]ݍ~z5=<Zj_}澷6^L}&Lro]sҁ7o  ~Qp`"a?:v#vNS# >W 5Ә:#0 [$Ui3-_V myٻzoC4MQ|Qw:lT,e ,c@ bŚ}.Ej5>nV*xţfT˧C9,E4U/~"JhLވ9{mM-n)ZvѣÐdGbr %Ѩ;!0IjV-go:K9'v̩?]f/kxMoHOklD܎ h_DSԈ">2 1l!c7S2G[z*~Ϥ7-"Y:SJ%sCofիWe +v-:J%ۢ,wtz7qʆΘ'Uv%>u"b&Zdmcb`Z}ص-tS`Ị4˴Z;0+UG`<8(g%AJu9aqG+tɐ7DQ2cf)u?խiVWM(VxܠbLQFm;3ڨF^@.߇*8|b'eذ]eJZ^ΆFĬР[l)72xkőKwJ(%xl۸p&mM~-)6U>n^uj7֨o0ArEX6u2 O=T V5i{#g;ڿ#9-vn{L87!,x,:#})FAT1P]|lCuSy!6Z7oZ?UC84$bHsA[]RSSެ]OOUZjKE1D: LLW[ff["θJ*7t_):X˵SmP1nonwEG#+W ısUA]~zl*}8PHgJƷl>_%6HD8[1-703h9{[ 8ˉ,=k:Wm2D 9ё SDb3TcUH평 S)ߖ~Nvݵok1)~3d<22C_:4qI\n6ODڂ{!=.>=f{j48/.A&"yVg8ER ':Sʟt֕m9/*92ͼسܽj* H׊?}T.=h5 /r4w% T!ČIltNSkp]:7cX@LL6})!9P}b>c V 8b_iޖI"tv"(g-7P\\!_x@!ٌ!(V/ZcNR@(\?2`t%ݰ_atd!)6qˋPanyRdE_7 ]2f'-`[ >GވIlfloIO/*%rm5yr j?k$KF `_G`ϔ[ZTDhnsiѷd#+eB**mm94PM`\ǥ;k˓ ~qpsx#]D{.eq۫QL74,yǿ0:+f yA v`AOʍ9&,&_[i?z`AV6 _Lk T~^UմcӢzR:oW蜘+ԋ5od`5m4#`G$k&kj"# 2nC\N;XTk&vˆ2[~Cc95 /uI'S޿zaSLb6/N?1̗!I>txȓ q{Y]^+DLL$]bhi?lϷ pĹd$SS Гˠ˺17*nc,Pr]o_ai np/m>~uk냳QĠN+6] KDK}%,CP#n`v>珝CpZM$+ yv0Жp&ݹ2ͦN%v/JPf(/sY:ș"0 (ǃӹOe%'N ,7OECv<#U>e`~cBW'`\ܿag2/2U%`7 80^mtq./rЃRjDq\7OR-)ӆ$;DIZ&N,:=]3 9H{z!Z~/ gme_ '1&Z.3N-S!SWvosl*[\-{ {Aa G K/BPX-@Pu)Ɵ x+Q sZ w0{M蕨#*_z@*vH;@} 7%5S0ɀO@eƾݚEq3DMIk*n\rϖd]w!0!l|,R:%GJZa@]yċḀ;fEv9;&9Q'&f]Dd6Y8聙_vYJ4t! igx[G.ƞeɢocϲDoc&pDJ:[kra8*>Ey_ bnr +Hk6L:g! ^pH~ qS544lp$8i3vc[̠K$1+33*K{~nXQ__U9t)0=4O{(=FIȓK+WM˵I. GmOJڿĩtt ?NU"GKy,9pn:- 4%+su͢ϐ!Pn~1A'LqW;\noF-Q^+(wxvk],F*(҅d94{lbo[SN; W!^ ) v%v:>EC,`oo)ޕB6ӏHK|YCQ_D/_*kb\Q: cW-!n0վ.ɿդ-Q:В͂]fb-S(f,5oҚB M`xK?źiJՓ+s xO"#AR%;7e#WNc)'q/ex|i;/x I@϶Uk^<)Ρ=ܲr^3^TuICv/suf cQ>ݕb}Hv"PT!7p(JiR zJ Ccշت̷y14Vݞ JYQ+{7u] `$l)qP\=4f׷&Km>|V OfS8#>Ie}M5aҬ /B Z{WPl?}p?j1T 9;!F,.RظPZ 8fj^|}e߇/Zen%&S?}2S9"Pwv* 5a @ mBx  bkH`puKg_҇*sltUߥN:֢ɯE-tqG<}RXh:b\"ٴNfƈȀq1&BLq޼ǚLwTsiȖ}U"MlKN>>|[ <ӂ#glӊJ׳R)+^lO1вF"`tMh-`sc#Ȅ-0hBΫ/Mf~A?H(M> /?q12;[Ow;\vImg_deD |ٱodgI&e/Gۑ;z:%Ѱs<ɶcd"J:vʮGعxI(:+y;ة[hٹƫe["QstsgQsSq##[>؉艕l 7( NS ZB_2@ƇzJVG؀Kz⎝RҒpl{[$;'GFժD]\RqHY׈0Yn#rn]|Wz{JJoִcĻ_#r}o0TgvCyjjr9^ Fk>VKs$% fK" %5W-^ҘAμ*fP+CptԺ dٔn<[xtm 7eHC9L;FW-OUw]%ɓ[Fz jvڲ2֒>T=#{_J+w ]w?g%V̫qOHL$ytO)/3 km|KFcKoݑzoXsSD,ǰkEAF:yO)!ȅs?(g,/,.9.0ܹ:aUXW7zIlyrҍ% 7*R\vU7չYײY>v˼|7we0q ~N5ʦ9n)Ed3t ]i fGk+)IdUyӗzmݓ{Hv4]V!dljm28H(S#۟[k{x4Y~v]Nb|f۰ZG=Aِ]Ǒr'+5-pgҚƼ;?S)>+0f;m&Ǒ/=r?r<(ݗH\O;w5~ J*gylat,G>>l&[~=U3+롈8C!6C)-O|d KI ]aE?rku{sAK'ze8]%!O+Y68X*Ҧx^sQ&{d;]-<>?-`Ju{ϫkc/[r}"tCzm:Rȩ/oe \v8 4Ѡ뜓%k _Fuj}~~_+b߯-m}-t.su} Cu4}!hiA}rh߁OLF[Q9Z|0Q+n-Z;,5"%/V3 >dA"A%8GƇKd44(5[6чeF8Ģ0Sݐr$>3l)3ߦor \(J!#>BC"XmOp;r}F_qnBaOΊ#C|6ዾ Px:r1^|:fj^|%k7rW *BTGJ oiibW6~cdXeDvGwL&dK[W-MeiVꪤwnr/LQ4UT \#}q@CE98.i1vp/65+|/wlΟ;'ˇgZ.]r_5y<'g%Tț^JY|t\YSOR}Yio+.c$xF򇸚 =ѳ1tX{:ri(ˆS>Y fn]}<̌}]I̽~f8>@4td?07}mj'A.׬|zI'+&N+DžcȤ}I:+o k)Q\Ϋ20|3}Ç ._jjPOMݓ(Ixq Z&6^KT&IۮD=CY2B3T|{ KEemf{bHo@! Aԫ#u|㿃z0[?P 7M  پ]͏ϮAavLgt} qɸ=~㷪: ~gLz~i[i_ !wd֥I)пcxhnR&Uѓg ppoɼQQQ> AYWjH3LP@ガyy&5u$dPP=*"zX\p^_mG۞€n7foxlBYYd3fٌb|Yh` .0@nD(ՠ]s5yoE@PyG­AÓW)LcYlEhא@M,nm}W q$YQ7/6] P۩\[GP r. b4K/!Nboi"WWJ/k졻ϳeGsLe*>#Bx-`-z)`{(8t8v O 4SyTAk .*^A I@[M |d8(^!A}]Qr_ڀ*;+93)%JQAjy1uLa*C>`ּfi붙sSm$#Z(<9Y+pŸ%yc C3}/MD{ 72)\iIxZdrp 9Fh:p_핿RSXQ(^'&'@m{'"&p+wSEx%<53/ >JŦ$}2 @#K1!?hn'P6jˣ# V{w=V>US3D]5mbUD2ϠwK$샇nT)7]6=ewia_ALt5/D`C5en& $3 :_OeMfR 1."/ݔw#\gY3Oz 0@B@3DFk'啊-.wŒsf034۟9Vqޏ.wx8z n=VWS?^ 81ԩ DU-pOjjf@^\$` 4z8t6t2n![FכW@=:od:T{}0z_pJk0)~|S%< |ЩЇ }n9Ai*BIx /Ri$$ಁȧ{6%T w~a!8^72?tO.uMII"62X?>U4Q_Aj^{[+$k̞_nVSa1yc#gF:NAM`҇p{&B9eX斌9G~XP}{ L'ؐ૲Rjɓ'uO7!㓓5-Uܮ7HrcV Јo}22|l,s_d4PT%3DN3(塍KQ8"g-7C\?55-d)3C3Y09e2MS"0=p :W^T Z&%N3!z({P0zbv)Y:@$a++)fde$iĪ*| &/NCCY䨖@: MU1 9ᄂrA(L`s{؋ Vph+F }U=@r*wDv/)zIkާ,~b>v3j<h~Ef}>/vcqJF V/挎:!z2Д '&%ju{LOVHduMO{bBR[q)5O7r !\\! L oDHz蹘3Da/oAJ tUP"@zoۣѻqh#N <-*FktAMMDuhi9H#aXn?&"ff5g&1ym?G,\(R4&/ﰝp]5gB=9( A;WX>W[WԃTvڀO7`JC-9pXO>aWvKHw$Sc}=4g$eupѹؽAdEpr |ڇZuj]y9|-nλk2}e+G"sE*G! Fę桸g? #=>ݤQiF D.2RLm>\~u!y}/j'αpsO1- vjoi"s!%eI 79x iQ Hȭ7-tDF!I*cA;k |^&q-gxP?K07oO5m|U 6Yg&zgGgrI4h3" p$F߿{)X>lE!3ڍALجc@sֹzB!mbdh0Q'2Hzӳb}oLcBD;"H7]Hqy("Å{ (m?&tp7Xlˎtm-+x@z盕-P RMCV9'/MN6zb >_ ]]515֢ʺT2ׁ򺺕R7)7J0=]( 2;غn4)Ԧ}4c~ SF\Xܨd#.uo99^\T4>|ٷ {8`:~ӳ*{.@xJ5Ltc ? (#``XĹR;޳-3/53Caí-+'Du|Z[Kp ء13!V]խ:L&$LUX^g B0/TƴfsHN ӈcƦ\ `d#8n}>2cKrJҭllD_p>r4ƬzrNJ rL0T@Yy<1IP9=p-u'Ch@̗O恪M@=x w߮y\@Sv~*UwMe*OJB!t'4H9L{2ĥ.v:jU@k@i\@t^QǠ[ aj d(yb[Qe|EqwxeUM9ӉβrM԰}M) S<!Bd*jJ PgfOc<ȸhb[yәt#R(2Q,Rr#>>,Ctez*Er $2/ZȘzeV_]GTT z̿UBM<FكCb! jhїӾ<5#!﫫c $jB pf7ؼ Rcq*ٹ5uYN*I!⧚)y?6@D/-,~-IXZp$pQ"=/m> yiJ6. z,NNqO%"٨ں% bt0z2n޳k~ꉕ4dE"-qE\zFg5M ‚ThzmdoCŽȨc^ܤ1%PG]K(YLL3,2&CM^hV b.øG=5[6w$zIsL1~Abb)+ڜ 'SUMyIsq҈ y\~9i,÷5-)T_{|ǡeV l`{YA* ,C##TLߛ+z="$|DΩQtg1BmB[{Dri-ZͱA WQLM̙zvv(Ӯ`q}A텬ōW7|['GA @#VHIim呚,J;qSJ* pRSh@!5_OQQ@j:j*+ϼ6sABG8@8VksmJ6y%Ր#&SnO<_6Hʞq^hBc &*UlTcpDPtžL޳YD]D\TS?dJ5!WX3s e40WH[}򀩴 |DFíh- zG䛇un*/JqGG6wۻppDD9qi&2@c3/bjF+ Qi^ m)[Um}K5}(̫7(vѹXκ^uIQaP2: N_82ͅ;WP 6ޤvՍV!$g\|TT(+=݊ A wr$8OKq$qEUgk}ǡY'bd44awyx_Wsg9gnkoo(<9mq#j?9sH+g lOX~஢vz%h 䯼z eC&ǺnAL+iee^"\3quvأ-vg[Ƣ]q(vȸ`*9-vOAP 3BCʴT5ѹU"pU Jk4K#;:]&,eЫ/tf%x""_w*59—:=aXܴp-, >( V$6//mW0*𣦔GФ o"I#A~Τ6=6 4m 0Ыl1[ (ouw$B);5O+y6}-/A5yh,1_𤪌fhP>!`tU1q"H˻EUq_e!p |ߕCM7p\4-k .6hI&]ļ1lp(gCJ 2 *gHڿHLrre-ЋSd]^a$g_ZR22u=(G<)}' LIucJqy/?"ןbD|֡;zVjbP{i9b|CON'utrqt)HBCg2g!2hXT5(ae|ؐ}hulF3vMmN  0Z qV(''(X_9d2|P" _uٔ{:uh #7}3428뉢}ߓڶo>—OxiظNuFܐ: %g{31 ~t2L{5wrFaK6 U\囅_3:=\3\癌y$yhj=0,|;1(<]cӾqX3\d\ 8&EUP (JϨ-!8P لG6 'C Ȍ܉VACώVXjg.b396}d ${jBoX]rzDT>po сr6~V]~hwJ-uf{P9z A˒ΪM&8QN^ҫRa" Y(b>f-0',rSIc #…vA.B1THȢBqҾִCےs|KܐLxE'8Uj$9=%PXīY;$+. V Rqb{JrPl7,ZM9(һJ0Lz?'֧?*$' s@zH\!HuY°>?E*?d?r|4Jr}7`&s֛S}o hpT\sqzKfȣɧ̣]ĚǫyCu/HK?{FC \PDȲ 'exEbwiS ݔq2z ҍNDbSiC?W@e5yU!8:fs wV~jή\kSV]43_{ M/oFchtN"誀&Z3$0(ZJ%y$<S3[#idyB칟 qQQ{D!eIdF{w *ؘMUW4IֆeM{"qNىJ=+uu KM55TX PEo@G~C0ϕVMuZ S6~M*Kͮ?$Y56ޟ3ܮ.J-·E&*ƎΪzOcNWU7B&&bĮWfA:xFe!Þ;$fzP紪N#?9:t>'XtudbIV%w% ̻=933ϗ k?8 8zJMz wJޔ1-H<]}^4q[ޞ97{۟Ap@o)lC CW-V]naemrʤȍ)rs!9S:d43԰y05L/V6v (.94&Z/D`ZCv'ds"9QϤjd4&MDAu^c*I2.Mݸ&*HSB^w>nS&Onj@j Xy krgЧ9LKб@Gi4”$A{@[1AV72InbNJI:N;-֌=| niŽyT<8 /;["<뿑qjn:fjZ} 3Ϧzrp@Vkn%unW_jZ$ տNg/joLVS/rnRo.Â{ X(@[KK:&BF&vRPL@bMCs栙7nK\ʗgU wl~>Z,$X@q.Oy3bV!\Pyy-,gnb4+.jk=1_{-YN  zfF7#, >DHC=VPC߿hlTz3\>)*9P^1WmqUbeN셒lrߒrL'mt|vpɔ0UdZkY +OCP5߳} ]tccsE/gjQTzq"׽%(0[[մl@n)5G tS55 TNJ&$S3H~s0*>^p5d=4ڛIb!kGF_3;ϯF<{?LDI-\Ixx-z5-*ODH..v2^1M{݅ݢ=+rvzZ=y}?'ީx_MLu7<*Z(s2kY?UؾUh'ҋS>k=8j'6d2,-9oxh@YdEDO5*' mCвNdjaSF~r z~O,K) RrԟG‡5WN{0LK%em3xkvI?O8@p0A/AJ^_+\%o ag )Gb3~2_;fV'6и0 c QdW\46L#R!27osbq6Rpv1a @y!ڼS?memظX{3iP< 9SP6+s]'P"?ylHE)̪H^qӢ%~(W*PLYhR IU=)mXԬNi@?H: C4S+)dXfB4@Y-3fA Ei*M9Z0LR fi*E9ZPgrtUrNrC`U2ZkYtep*b9L\cޢI*l9Lء췼VSUrCҗ7xy=pxTEV45)GX\^TX-&4Y?qA/IA!j2a ÃV *[^]]Ɖ]AJAM<~N_g ɃR "[7y΃#T_M\!xPtM__xu5M.\}X;˻|z@*(K39u@.(ۿ~ 5ȫ?B~[;z@#+3 ߻B|x[<ۿ} {{\?Byzx{{|DKHMn2!3!]l IV=!m跩YB,w8HC\ !C#&lЩ$*4&l4*4#&lŬ*Aeê&l Ŝ*!e#&lȩdVF]Ybp+p"I,l1TQ+J,J1T9e91[((Q0kO(99[8.8Ҩu+|ʜ-,mT֨u*o_K2ȾȞȁ;_ l1izC,ֈԾя4Zc3x Z/Q,scCֶԕOL1 !=hNE8_o<8>7,# EviX# Gm;n5/Cّrem;N5M g ]ٝٷӒ9p+HnX߼L`aXrh[hG3VX]kDL1[a^ʂ9 %*e^ڂ9ِ_li^9YKK?*Hަӥ] &]K'APʦ̥]O'͠&ݥ]G'Mow^k~\w^4kcM:Uw^ ku1/NuϋU/N3:'TjHuEP4Da"n ÇV(*gL?AlikioixC`AOH>B9`;PQ'ppYWڨF5bPQ'rp!pb 7k`b 7 qvq{5wTh#rB X8}}!{ {X;{Byzxn^qjJca~&IՖ"+Ĝ?B$I$5Ŭ_"mo~%70S)4H~ JCQ="0^&AQ.}30\"NQV#0]!"0EHD,yE-NoDa ƥZVOEQJe_~1ԜUXaح AiNE EZR$u!!C:cipp|ֻ+NEXB9IJuSDn9¤3 J("6{`~ , |M`"ӺQEL8M2i)"~Ն֒Z+(6jck)/ZEcENx(~D̡&8)Z.Rd.1Eiu g,V"#ŴTg$9KC1\3iRHA1,ȈIR%8X&E~eot& | (%$$!&LV3`aw˴ĝdr2teF=Nq2Y A:iʴ[?f{94Y?I@*WtJMB؊^,]Pb!2AQKXPzI6V'k*q^RAjyA' ю mXlzމ3ّ%\/S6LՍ-D,G(sH BѽˌFbR0aL\&d$Tab0)'ae*e\A#2A3qCY/n/d62a]c zwƿ`Vb4}Lx-XO].1 9( K|]G->뷊!c'%te⃂3wtCeʃ3;t e҃3+p3+"ɩ ^bFsHZ-8mT\GjuM՟*0ooL/(\R1U+zhpl~-*5(J1V, 5`*5>y\.j -7P(67<- 2.hy+$g) @%OvNIKn߁-t]t3JM^M:*Z%s/I|Irg%Ɗ6FjRŤS7SxRRSE$ꊦF9ܫM$AqEFIVߣlƶRIQfziݤ ЏQ.wdɴg (kn쵡d^1hluXUy$(oiQ\hfsIF(ga~ jK!&G7+C'iFY6+.$AE ܛcX(Cosg<?*y^fR}>ӗ@E`8(쁤0K eUXLsӳ")}*ͭϴY(4<{T%2f%@afdcru"rGm6ou0bhO4) ۶:݌5ٓDyHRn%-\9P72IBW{CՍJZJɊJQ ԊՊzJ׊JՊJR|J^ًK%g`VR%ɓտ$!ɍؙCVyS!wzɉ؞ՕCw M!s;/Cw=]<$>/|!y(\=yzzHz^x#!xF_?Uek}eHo#W["Q4*4ŦbY+2j41>DG$St{+V-nA<"b) zWZ`ŘRcAŵO,RA q-1TO@!o-: ,p ̦EwSO@Ņxm":S\:j|fש7Xoz*3hW̵HZo-z BnRSVScEabae%Ÿ¦3зPQh]õJ$ )n, K 5BZVƲV LEsR̮FSU;A?R\Z)$)hTjOYJUhi"XTR4#P][@IY|<"dCSD9eq&ۇts ZﭶZeVb [lU'=+ތxh|9Lќaۃ;|лԮr|ƒ{崱72T9E$Ԡrltr0>#4ˇ׷(_W4[(?"[x7k/_ߺ_qetk t[ߣߩlu$6}0ߵS9l[!M$?JJ4U;]婬+gOHz2 TZ=(+T϶lҭ=I]D(d{ ԯRVO<+L{֟ؒVNo#ތxީ,0خ;rq]3MxzGW4w"HJ-o~hc~x [LvQo6 ]]]<]؜]zn-Ҷh`ͣ~jûJ$)1Wk`hWU9lQQ{ͻ=S?0]`4S;~n`2- 2T6(fE!KzdM3hܭ 2Hf؅U { 'w+OÐ5=뇦Yv+N.=w'&qc 1C5>3)(؄j?f_P+χ z3.GC[C55HRn?>ʴ5?gl׆k!˞m[*?B'G=j[4p<ӪaPv5EV; ei,ԪᰭP6>0 eZ8Ux{$qx(t2dhk5,\b5y}A}]n^0uz|yA|]pq$kx}dakFHŝFm;VKN9+~a%O9)*>hEu N'&B*Gwt|$_crsUv[Gs\n:K^&m ~Mxʻ^fm7Dpw Htmx\]t8u/u9`zttrfzʔo8WC!.Sm qA /t"t\⧺9d2}ťu;k}Vlٜ+k}r+jp>;Al?纹5C8_in2~e\icn3iInr&YinΕ*&_ui.nAO=2~}`0&[~P7Jϕt8[{B7 `(Z!+f\.+k0-nryY-< f%5؝o*ŭ}M60'MSݦC,e~L] J=] ǵMզJV,DzMŦ >!MT+EYn7:TO]ve{]ԠoZv^K]ωtXv[wrjhǗF4sm`J?Onva@ P6w1\e \[V3@ЗKãćݶ[3ėU`J_zQQ`A3晗LFv_5f3*k$ͽ^>23k4}{2ٗkGB0^\2=+kGE!Xu2CGk`!^25꣒Vy5⣂s;/M5ʣs;2 kGW^2 kwJodeWKNÁm%H,-m\}f xiSX'6SV6MQ`f_\+Iƴ矺COE%Zԃ.Nb%RQo-VcBZ TZ*+S@d[IT4X{۲F@:=jmkVſkmw'V{Դ!T[sa{ a󢮁v!&<l_jmW-OBoQMbuٹACL /6]ҝ_[9DZ T!&8<}%ml+'؀~׻Z610Y}`g:bn}hڗ6 5A]_'ض16 ϫ%m3}LoZ|}l3UoZ|5l= >mH;0H ִG MlWmG,Lpo#1Le;[Lwl^MeY :d~z t_ i Tk!r,HGs{FNmʏU֊X)hyU>Y9f%HϹWJ ;A ?@Xm7]3rnmt`ˏ 9nۙSM:y0ʀ'ZwpgnBcפZh{V >r <<|<|I^Ph}Y>9?! +h{IdL9+n{#k&w{4NЄ{לN_\^~{IY9!,zί^9:} {E rzrg}Oӝ˂kL顝klw{ euׇ酝;}7jMQJߤ1Ҡ+EoFU6uЩe7*SyƭU9Ph6ѹƒBОC۹`@l1ƪ Gvj V)7X|I`BnDiE|{ ~?`aoSkɛai; kinD |ܣ}[ϹR8;w-BmsO:ۻ\m o\rWVr;@rjT#ZQVi[ZZOⳡGD/owh|mI?{o`VOl#y[wnǿefvwm鏾=Ӗ=Bhp'̮쑟a5v>#[&gOKv[Ng/O .1w4[f(O/w/Ϟ^^,9-޽oVpSBzARi+GC6ۨuS}ˮkC8[BHQ6KJ5fm9: AV?Em1ņ ؋ vmaØZcOUlY)fZӞG[aԭ{>NЁ5{Jd$stn=)pw{AK\dd߃֛yoJHhWsdhFk<~ہ{sx֙yC?5\= 6}(ur}t0l=^34(W\]C[CqG 1gMJ-_˝g][ɟZLz \? j ׼Cj Ú^63 .]jU[_t"7]Z^+BnNz^j hỡtpȽFED8;}.Y+@rvv5ݎ\߿'|yC 'W#7wQ7Ƚo^0~(= ]9@}ʟ?w~nycisWv} %w/obG Ňv] ;3W74JvN/.o}}xsrCn;/W7J>._^]Hv.NoHbjο}vwt,IY:vgF-=$U="ۛY$`]koO}zv0GBV48W$! *!m0X)0#e,8E 0{*% U-T IZ߂L)H{<8ɳIkZq\E_q֓OO9lp&o!i%~{9, PZ$Ώw9!$]hiѻ$+'iLC1&!0!C5! m'F'O2?1>14}b9ӢbH&:TgT&83IWg{5̊3ZҚۋL$<ЙY-! "[- !wu&/W%3&)uf-zI*s?#$u-zI4qhI#x3oO[$ ]tNjsٓ 9x`wd$ΌEOY8I;x3/M8*mDT%8-ԟX?&gU䓐m%s@7BfPK ~/غz^wV"OVb._ɇ 먣HSH+=92^w k'߇.>τqhCPKqx3w? ӥ(G8y;dy&v \&aTeǽfXaTUCǛTdd_jOrx|L kV%6UHuofe~OE٘bu`)fOEⰺLXe+UeU=*g\]jĬPǃou`kfqecuva'fQe"[obZt`{fe/Ŷ8\\nF>rf㠎tF_ȋq~YDr0)m11б$$3&Ó7鲒Yh#t`S#|䥲%u`FR^׋rUF[T~d-wNl`$g4ntWRܜ4:QWUuJac#Y!&L&i~P %>nXçWOqȮv3wr?o/v5$)$]:]!>l[cWPྔ'ȵ|ܙlmUB(s$I6k>JuH3UڻVgBWr}>>LJ u&MaפL)I?x1|瘔4ɣSi**R=ixkixRmirC'Ԇ;ܢOD!ݎ[՟-rߺw. l㠘Iqд&`?v&J:XZ-'o4p`#9QA G~#>wL@~(Lv^TV&4[,+՛$MDU`E&Bݢb8lQ3 (LrQ%tQ!xvQ@l(wF컨vF~tF|p/AO_0V?E;vr"QZڡmZZ/ ^R:[{ex0FǻzT$ N2: 5he'uOz p|'x':-/lh##&-\tZIQ&*Ӡo2: p qt4(A | _ЂNr58_ZtZI& gw@ͳ, K`E!7XP4*IJ1܉B-DW زBrN~t>ZjY x3 ~w(((VQ5#`&'GLεo%}M& D=V'>B/N@zX--NrV'4@Wˋb(P,Q DV+"Q՚^(iBEJ1JGv4Dq:ȃ ⨃4Lp'/pwN(@-*SD-)S$@iɍ!Oxm0Z\z"2-NZ$t/Q6~?g,~2ψ2P~*,Oi(fQ~joQfOQA=K%&( :*J 2˶!QxVB_^x|G˼#Gī#|zWxGz׸"2]|jWP/JWP I..R %v %JvKr %e5q7&Jǣ"#+osrr!g-n B^o+nӗsr&ad.)1[RCMl\LEcaJ\Ok4jL} U>T(ժM}j.k|У%>J(9xuΘUuOzƼBP |U>@U?Y7I7Y]$W$Y$ OVuOtOVLLdMaMd(D C)1 2bUQp<3~(;˪`\s,ȇ[ Pj5;b>tH:/*ʇ@oʂ[8 P3>$T *qe|;UC&ˇJa2V!=Ʒ$ ʝG_;>&UP< Vbb{zEDNpgw'wMMgV'V,,g'))gqHσλq~P))~QĢccРn/P^ҪX" ˉh6yS55GMffGq.X5u!) r,ApXqU|29ǴQkKgŧh5\Vܞl_j-);ֱF9 Z1F)>E:hZ@pOpF8~ca"3{ԗA}"SĨAEȒ5@YEhryxQ70EU(:ܼ(f =@9NLnPةyslF5gЩfI+вayTcj5,?z✁ cDA)(0Eh:pט^MKp5/p@52J܋_ PJaslyL]r+6xDW⡘uTJ5XS=T402(X(S TNl6Pp}iɱL6ǩ֏ԏ6+E &J0X.Əh2T4<6UԞ0?* J_ "T v˕`vcM|ۡ fiO8[nsJOAyFNXؘء\ $KYaǜռkU_~ȅ'.+F\ۊ=9@m˝/_H /  P zODS!F&㣅("cxx? 0 hb̵aTfºBL1 mWYZ!Z[moYF-u3|$-D'B1/aVy-Jc oc!Z-L]*!Z3+仏z$DT IV3-x/FwsЉ&0ANL5@_@c:@E Kn&m trpvN.cZ@ S!@]O Z 9[ %2VCF7Î6Zfiz4+1GtF7Â6Xf:~*1wк Yg } 7d ѕ >EVV% l_kuԻjd}s]0ˊe}7^ҌuᒕJ7aGr7zK?QJ՛ %I'zϫ`.D=/1*9*1*D,' Ġ\j0A0)."6qt>(&EV&⫀*`]$jm|Pj ąVf* ȗ*LA fZ j`H*ME=(1i _* ӓ9Xk)cUA\A#*QOs3CI>̟UgFU<)ۘ$|1LӘ2] jqӔK*ὐhIL|8P:h!oHL!\LbWCZySN1ć< 5yS0}.p'B>t<(`,`W ]'梬i "s38\(gWo6&Jq- 0U?{#z'-HTUW!˱cPͶzR01cY^#aO<7y= ۨlW%w4zb!H M)z)+͚eh?Y9]$EdEqЃ88ZCuu( eO}ytfp Eѕ> @FnYJuJfY$O܀%YoJH,_n[oB ߗJ --mfXr{,W۴wVaX X&d-!n:v~n@.M~'RXŻg[q}0tf?qc~oR%P.2qYnub%SoY]er$1os4v1_ÅF&* sU:s]eJm86wp~HKjuF/wo]75f>b㪼f>8սp_#'Ɖl Nu1?v8$QC$#`   χQaenpmWԏĹ!@Fv]_LjKqc;'a C,0}iwmpH% *6׳p"r~ËZ$nrD2 ZjqC;,'b_o>ԶvO.F?KZM׳ I h߯?k~!W{^4߳CaK3*\﫶͊8'nwYUk|}2oj[Uܓԫ$y]\/:>TJ=_Bm'l 4J9=~͏g4ծ[bOrÇ1ݮr]яh͇1m{i̘]xG{doSպ9b`z%X f])Gu?f;ygnN3ukI5?uM?fٗv~=~Y_<ʸXT@;I\;9C9Z>Ƞ?5],'󔂡9o3N%%RgX*^Eô3;/ '=MAD"w!}+=G g1W#&+GrgY@W~T~Y/pEJd] Ere˕`\{wH,J2\=joύX#3ȍ@ CC$ r¯(oY?su0в$uq%v,+ GgWB7r"deYԍҿ(QYG< L2(b|N2ɳ"Z$=27G?Oz!|Q'滟?b'$FVNpX.X,  Kz(0<2 # L {AP*(S$kAe2Hۇ O˄YȨ#u: ?y%(bK&iг˰+zU2H/ -7_iD?-H~!tBBFrp~rWE/ ._ɉ2 ;p_FZ)'@|L'Izg #"QFK~vM|6HRԣdu0:>D |LyA7DrL2v@tC.ridH E;IU-S_؍~hL~IیuAfK1RTxLl.&,BmD2^zQbsIcXOF;.T{Y=f8tHMX:C_:I13T)$jubhG8ഁ!'N$V` 3q':Q@ui0\?-VaC'/ g ?v}|+nLW;_77J}t}S"y{n"qXA׌=g>"OB2(n  `:NZD)")ZEPA*'FP2#t#<PRbz*)2qr^˴rlF'v-$lbfsxڸiby }F+Lv)}*Q)s*ۦtOҴL֢6e'i2NWxV0<0}=Q0s=0k<-asZwڴY; i>wJ3RwuIj%;guԷy EJotEzB"ޓҤI"APPANRCҤw睹ww?^r}v9HKZ%H}!0(K% }?l"Nx4XuS$ # A*-wHVIK]  bR5?`.4"f-U |eB1MIJ =A ,}0 Y͇ 9B&R`R^h>+Ҹݒ^aHKHc 6/5YZC _@s~x.4/..V ?o`)|^LZ($2BTaa%: ݈y%B߿|i/~= R}#.W6@.>~Ÿ2su}񈔋eeF/T}ie$|!4}MeΤ @H2r{!k:*K5a/H0/\G?e:JY>SB#F  V] t!: l&یW=L)M!x :Tx 2#ګg|kS >b 'M fM9 iFW* V AnT1x{ B@~`f Ia"!)dz#"={+d*-p ]B$Yr \ K).DCRz9-`bK{k{nj%- a+cv1-IVҌ}hVC1-8T8[c![q0w[[mǙ}쇏lEY0Jԏ~D&z-17,|-b^H;d^\X"~X</%%]{ݶ"bzݱ"I{Z%HT^Dx!/i݋%2Mz)OD'In%ɓ)DwHJ|uĞxm:-<`"<`<6o0 ^z[(tO}N<'isl╶EISrrSs+صsh3 R CTE[ԉnD8r2xG_RrR8 `RmVNȭ]*tGB!dLwr -+dx7Yqr?|Hp}Y!~5K,7\^2$XһOV$&Ү}TȺq54c5$7:K\dk'&$':&C<tCW%@(A*6c/xp⺐J,f@^qX#F ᮒE`wO+h7Tj *7g˨*Q(:vp u3[b/Q7*z=@^P"19>J#cYg!.T<\+*,dӔ +z,>vZq%T]B?@T%U5L27 t({]oshQ\_Uu 9U"BrT DMW$XBWW"ŸQu 劽I7Ep'I|_m Lt98 <5<2K$ƻCz¬V$Cͳ" ebkfPwſx:tgXrE*C!i 1Z*@9ʌhMҿ!`/?Ezy%l\ tkǁ ׉l; xR-Dަt\< ĺdks@Ws%P>H'͚2Hb-nduz}ʬ9:9_>khf5p*ZwxaNh) htyyp T6y"+SLDͻѱi WyV,O}1Q sFV0!|e1~`w}_q<@jac(;p=E_D7Z;:AhhΊ)"Qѹ @2i+6~QЃz4b2KH :~$-pTiR^ps J}̀8#͇Rk@LyJee:8 #&URSAO&(Up+ZGJe`zCBeUQ**k|*3ȆH[2$YL齳E3{ed813eL[X̏K9 A@WhU3h" ^%kdN@dFr/eL۾gJ,,d .^΂<3qrKWsđ˿d ttm&Wz/g,9H,e̜sJK6{9Z.ɖwRM Vhr}W>h\g' bhy\y1˃W5oJj3r]..sl],X"XȤy׍3 2@⭆u~Qe(*3Xk+k +`" y]DcUr,c-7X3\Yfa^Te"~y ]&k /d"ve@ɉ\zTԵZ9L2fɵHS"k{_zh=t"{RϮrh\ cU/` C,Wl>M M:.2vW=(UT<}<}jcDk 1Ya{ƪqp;M ۦWhO5gBp]_XK vpܐ׾BpDqm4y(ސ͞t a_ڬ^4QkS33O6n~ i_>vCЌGo9&i74탞)r9Kl+~8cꇭDpC@Qv,In:֏:x6<6븅'ڞEc8pƇ΀<蘃g>D=Ì48<ǥ7,yq1N~hDĆCp6"=؈jm:^rŅ+mz%^rN.K=(G6+).g-ғMw\ )77YyHy(ֵ j/{uo(l'mFm3۔7v AEC.R9=w6Sda lAʾ~գ/`~sE;^ɸȋE6ۮG[~yB;ZP<缅1|([((EE"waތR}%轑hg^Cbcx$2W6cDGZrIi~.o5_LľXYnVc9M!}Ž򎉵u) ,Eʬ!).E1bcxːm5VOrج>*dG4rSL~k XG .W!g8}{m'9%lN2nd\9c#5;T<~E]h{ YS3#a-5Qb~d;ht?bS/cuB0nZbӮ1pBi~3Z3ˑ%?9cK+^cQL /IYV ͘xQ*?j=G\ƒ_PŒ'X>#݁9Zn}O{pI#QclS/ɿ jfXT>r _R80:{~S L|BլPmN|@jf7̏MQMA ok:fh75WMQ24n.aiiAS?f[5G3ࣤqwEtNM 6`/h@llM\|A7plnпk4Ej[5 r+u= "{7}kꦭowoofD=ULUv&Oˏ< ?߿ tEdKd-(rP(ԩuUreP]`IXZd{]5IX*zKB+kXiպ0`rTuj/2.iV"}埣P}twFR^ >}\I [%|jQ3Vw0K|Zwߩ l )ξQmd.߹j;_wfQk}}*nybנYR Z:f!pn 0um\ ]&C<6gy,sa⡔3ֿ|DqLc`1}˘fFL_0˒H4ϳW[gaI{?.T5GmcO.nTIq}xAiL(nzdXV(f j\w郬 UbnpnLl\P7Ml};=ߘ>79N...z|D/n_Ҥ~DZ݅/prXpl|  It~~OV5#/9ݟ kp_' D>d(#OP o"4p[`U~"O8=& Q[w\{d_Iw#r)d}  _Uu0,d&[%9?U~k; Cba &r>RE3{H5uCJ9͘3jk.{PMH]+<ĔgKUJǙHiPx}sP/`T=my/Xr=R`LV¤+=HkC9o4lsrkRp\s'*fbEt&.jfz)h{Q<.F'ET`W 8USOg`M@K]=*UhgO1^QSG=mm{:Դxo^VU8(#Rw >JLjr̷i/JxoG'J`y!I/x"F%P`JZ·Y/j%`J(<7`񑗿%Ml[++xPD#?6m,A6o4PDॿMmÏ=(s^R8"Jm2xXxcI5 Nb};&0_@ǔMY7LpLx1j'o UU{UUխ̣™kZ#v3zgtg@tGPl1 ?CT3-uě2Ú` {vWaea 3x:aN&g,o \+Y2-o&@Rd+ ^e'ưP' 3uׄR' s35B0%¡ͧ 7^o8YѺ͢͠}K6666666GnnXD"E$.F/->[LXY_]LWkdk-ښAwUL&u)uÐZOW3]T:YD + ZG$@6K)@5lҥkכ_"gpn6kD/ #W*< \? >@\ *~:@RA h2(1x}BE/Q=iz(JDIoGI$Ge&{Qb&&7Q⽦Kb#n)RDɥx)QVC)Tou&Ru⳦KlDQM^DlM^WDM^$XVDM/b+&i"\4QfI=dk h2F5gq,k,c}I[˺ୈ`l"m b=\M'=_V&x96,?686j6jBĊ̴2ҵkG{h:פu);q^Ըv/i2v4_4Q;fk4myJm yvm3ymUy2vm<~ĶԮm|N!}NmyN~NnmzNڡN=tF+I Un&͔VϚl7[ws͛ɩ<]y\5Yj$'sej2$ФNNYѼ}y9W T:<;ZIyw&]׸7tl;<ϯAy^h "#h'<FQü x ^ `xO`dF`'[q0;7d^s0jB#T1%ϓ·O)y^qVch't2޷@I20d3xXpul4u>x@6{ECYB݊lBB튪l^ T6^@bEG6/b%W@%Z8_{Kp֗g]W,$|*`]Qob%ޣ@nEKf~Њ[+q W4w\1LxU 7][Hg hVъ+Ƨq"+ڧ=W,O 8VOcBmVLOC VOc凮؜&=J2cx#S2=lƐfc~%9iv]i7gIK{gӜ$- (Ӝ!nœ:-eQE&E0Ik-"e^*B14zk_>&Ջ_㏪ !}‹?TE#}ָCU;bjܷɆ}GUl<G>eGt{g;Ff#Ø}87G>ǍF 1>qy^o_2zYe9㎇ܸ qè o3[ @; +,U7W؂;w_, Mیw`W^nw_3zcya'!(0Q0^4zah| 37݀AÍ~xzqw?~}K.PZS |-SA_@0 6E#J;L}vŌ?7FP7Q׾jܷkW 7 S׿=os.KG;*AХjF;*{%eG+f1߶g q=\*=^V `0wyf=rI|)IJˤ 5IZvV8*7TTTNM{kUT_M}˷ f:Spӟ>¸L⮮?뤮P5&T٭%hUסrz8u*井\b]SJ{ݨG'USEm'ZmGImNn]{*hݺGyJ}0]3*uW8uHPu:,'=[Ѭ:׍zq"g_<-pg]!U6g!8u_U6gj>Ip:dj gckCo"|YG!I L8C9NZJ[D/Do#fB?=U3)Npk.?L껿f CB#VhSݴc}`kD[ٍJ{c-b+ױJUX3m8ֆFXPVc P&*ԓҭThtK5)ZȣzTɴQ{=zk:ʙv@lQU=GiO Ԯ99~̴+Br?l3̫)kkV+Gݱ) rC-^4H&IޘTgP(G޻>~bѺmUyI%⶿@Jn"OZ熖aϮm}77>|,}3$;1bgcxu*(.OkկdS kbC!'xʯU.gRxSi8Wq7zsUuf @tootIwS-)ahVE6 ߟ^$}đc-.+}!n0L_ε3p1x9O\3CݣElLp}qÝ{0k ɶ)bX ޣ.}o6-H_Uh=:.ŬHҜ`Ot#CcC(R݀1/|O$M\ٍ:6JT~h`uɈZi40AF? KY`vfPtxƳ 9eăkPo"]T4RUi+σTVaP/S*D= m[ikN)G~Eg-Rd{ٗq_cqQxҨ{g/76d-J6zhWV{+19y/fNnѥH~[[4H՝/M"⍷ o;~}C4znOeGum$.g'[[l 2ZIJ RrQ S@O R-ӔR]k=QPLT..d~Q<ƘgYM-N-3r9%~zR8u0r}#/єw=87T. })X|ٴ~Vd-?& Q{!}ptb.Ü3Ӧ0V , R6w׽S}zn#}hU? {/0R#($054!h;ğ߁dEtζ*OIIaqi)Nd/`[ b$"A-*? _: PCύ6Qc"*>Z) [y;QF K )qaNJ( aRvGH8JcNuO''P{ h8xzDIS}y'v$,!*)%!.|4_8$pΞw%Itiń$9%ZO'!#&,)%)y_BX$4/1v8_ qNFSJӸo__6O?IdA( 4R2¢NdSu(4>Ppˈ KKJ%}aqD ""N_DkLXf節 {y {88 \H qn%g!EBRi InDJ~9x~??aa{k~|K"x $?c8X[m,쿈鿝x$Xȅױ!Y\s-mmL_aL//BlN`)e0_A._Ȟ#~~N~YTf\,L@V֟ V&1/鷵' 7֯$#Ȏb{2?o{*#+,{&#R d_r a@ yvvȓHu}l &.P aͿؐ#VNJ8;]ByLSB7#sqH_I޾z@IܨzK'm M#PZof8emE:kJZF) ?dX ʺ6~,OBK>E~YhtRq\f['j80; W6tF,shwTy&F?ՋI~K uVEߵB\4*ק̶;&LbO e}ޛƿdYA0R>o LYh˜؅*!@GW!oyO4(yp̺zѺٱP5x.ْ(粺aE(hATv |_m€ѲGn={AU!:8L0t{;Eվq"TȚ}Ll幢lpH"x׶cino  -F(Z)p^ BxhH?"Y?qp֬tC>AZc+vpe\Or؊wy|AbOQI _[7z 'h[i Sϲ8&dFLv'ʣNxp9cʔ;%l O<1,˕OW{h %]³wÎ<61{4NPNI n+ȊJT<[q"܋܋/_cܺ?xDӂc- ApIN{}lD$Iͅc*45tEU!8 $anY^4㗴gpJEYOV$ KޯkxEڤ[@< &:>+oBCd4[(.Ig}Qz}Ugkޑm9|gh, HOF_ojk<#5 Y zu{Тwv߆I$A.v7ZnDDH[X$iD/TB/W7qH].Ce6pDJbT_\ҐNVMFRA؄{tp{˜gM{#)u:0< Bfq@SܮZFuhLZB1qm< mj>?f{hA6W;Ӎ$# hibtK SOag9v~gY.v( $vHvAp6YVIRl7{e0g's16W!Sv򷻡".0ūx2mʳs8OzwCUajAqZ~ ޶2K i|f MW%@/g&8QXSI/kݙ" sO՗!;7wwHuQ {m#fdVvs#MOjV/'AÈujԇk5J:MLJtZ3dOmpnıG경*M F/f6yz:: A_]%.6W3!=dЃבTV%k{:GK'4Roۢ3=0њejv4a]ޏ CWCs(|0̓}/j` SF DC*Nu'^);J)rVuWNtY$ث3L gʴjEF,^9TI9pҰEgFxwC/kaͨ29/PXuU,ә9\Msa[Z9i 2^js߬4d܌"d cw40'Ҽdz:ڙHmAU\~Ν (5`F 6^If?kZzMfW/ES^tppy;)͎ hOFO֡8`p(ǎ\w${РL5KYNXEy`L铜Q*H>ŁqFot=5dEØel,,A]p~qҽ$K ~HͽsbHib OFNجw&Zrc0to`*C,*;=1F[֞H`Iiw"x B/]ÿ/)߈U+y?B}>W>a _s/!ag0q@g RecgBXϬ'w@ ,ėB0eL,9!,Mk4 ƀ" 0BA L'Licq>+d ~>>!O!P0 A3_,Ǽ  O9/o_9oe_2X"\_ho 7l/G! AL  )`@l//oO~Y/˷p(-ChPƀkb{1$jAFL3 Aѽ>;lguA"? iL^-oS_XC9e)$BM)}Ē96,kUú/ZtL/?\Ejgឥ(&+㓑Ea++:8͉@1SG'[x{׎.\Z 7d/ %3Ŭ"|_a i0-Y\m)a ڈ6kR0d<$ҨidV@ `EH (YHo;6)S}87{ <+qܿ.կ@h-|_WdWxaDc+qZgEŻu6Evׅ\[ ócAĨ125Sg?£jؖz^Um<*aA|OΎ?xӽĎQx󑅾rGE)ҴcpM.wZt{!_V kEu$O̱=.AJFwDU 2ժc 7H%w]90o[ iٺvqW)7¹edtC_w<̏ RG=ΏtO*`@B0Kcr4r5%К&EJgÒnɊӀWqm/mb2@95lY/qmjPT.671&52(?5s?a)ʩ3ZZx(reR&rY-xBgw%PJ 6UEAAcBz2&'Ʀ=ߢ Vk"1O[?݉}:O3~kH7X9懁ӏO][ k6KGLϟϮN? A?dXU-aJdғB,$}&UJEGLAR዆)ч=NuxOmpx1LQ.ǧn)#"(w w7N%t>njSH<$[/(V'M DLNtjn"}տ/}F5D[CXLnЪJAEo<{#.XcXrTn]1Tf2l=gfuOOT緈B3 E}_Xc-|Ggn0(znaRQl -\bC0C8RRX.oFMIvi7?J&¹봰JsPS9ǎDzy-zUXWůMCBW|?xNˣ/0J9QFVo$7r@$Hߊq4[Hcx!xZ3|"<:+ 1Vh\6gkԶĸZZB'a%7I{wMH^<()$S{]8 E4lmC_-]lV`xWv:ccG>v.$Ĉ R:s^Ok͟JLOˌmZg؝;VcYNz)d)}M£]6i&Bl >x6t/M)hb[M|0< >3f.;߹]--UXֱ=;=aN3=u7mHgVMmȳuC& (>(ysY ۻ T8uoΡ䲢tťSICHΔ~)A SWy~b&R{]C-[]_>U;DQ1Gp~>tt,QPƌ%LkSqA[ŒL* #ܔ')9d 5g-6ϟrT)&=Sn ݐ.m4?(p2p7IL |-U$_qWF QXQ_~K$#J|*av r`@VnCr(24 DsB&L@) ?( :0蟈t~ {3e%EAAp7DTR?پxd~j6 3BV.Ha-~}Y}JGj Z8 :"x077b2ҳ"8,.a~QO]4r/ pDY?9~_/fOl/*Tvry *Avfnp ZEb 3w*]K?~.XZ;9u[6N>m_\-xSFKrLP mb]sX\Dcf twb ̬2Hݞi+{COl',O1`XELR4|"4A ULI?<̺r ֛EoxzޭVxtȔ('VPt"ltmT1`CCCn RڳR\{v z01aT~C"jiRRH3vKodZg 3 $w4=dr}n= O&IKz/!Iƒx&N,h~C5LFp]V3đo#iĥ*F`4A")#")VM9eSLjW['ڣWD (P)0pT/%\-eJ9b,[(ߡ)Uzk+|ꏵ4: c[Pլ c*B"| Jh`Rkr۹ ʨwGnMϮ1=q̇ʥzv4C{BGEr jg񜰢*ۃ4EZ*.ި6#i}Ē,B&1Z oNKb?kVyYa!D.`:_Uq(+nPp4|ԞIެ^CĖwQHvI-<-iTy+Mܩli/KSpXv1:jVw8:z -$Qy;#;cקmg#?N|!myIЃZTb{ D1wGp1#4e8`m7H Nbat~{Osk;kAly;[N"|? {xՆi@{m؋ns:VEW((@\>~%Y'Q]FJNv | vb!Ft%Jr2䆽R|TNuNDDy݌}CXXƁ}B3^oDآɂH)6Ah-]aTFi\)صZ^;yP:9X&fޱk5ѐ2;R_)EBBZ/cq~$=֋ =,6,Ûٽ:aWm/&ˏZ ͘hIvF\EyCԟl|2OXcq{mq!A!s퇺Ǥ9f\+4*9O%bg8#K'v蛓߰پhR^._N W^?Ol . |[lz`T筜]Uera학ݛ-@ |mĻ@*piCaCYJO4F3*~mY<]-}2 F\N;Ԍ(O݉Mk[ݗlnkHzb[K?ۓ**u2M2RV+amǯܰ{TW9]Ifde1؉I*\\WTGVDh(&+WR즣~y{vMS# %[[R߇_Uu!UK_^C\ HA,z22 (dY! k?"/vp?/,BbA:xR?}E|~s ÿ~Yb 0`V0~{(OЯ5hXnq0 s G.yCɩv/4C;/;vEx/nhW#Faډ{fqL7"Mv믁!Hح:eGWy:\o$.=x%p, WrwTiX»wAfcmV[v_&&"A{|rqR͠QL#i!&BrSY #H{`olr\XA=Pxzwl6QB_®~:X'Zh4n~7zVy=S:MY5!"簖q2æ.xHy,8* ;zs,䷁$6*A{vSƉGq5AX8'l kL"ɢFj&8?`~R0-VfVT_Pq\,I D2iOE#J{H϶P>ʻmuZo|AƧѧE/uReȀISÐ_jL+ra>Bw'|ܜ}Q댠4rYNR3(7Vdu4!T^-Am.s'  b-[7^PkxCuקqmm(񐠧Qn/c"";=u< 3QDFE^ueiuAQWY*('hm?'>[wp,bi@Ǩ#1Hׂc߄-qgdRD(x~~1oks=5]̴g2/\i_^wܚyӶ?;k|\[6DmsEedqmxF}eQ^)u&hɼ\6X,X%XyR$O? Q.fE弢u{[J\_?/ڇ3^?GfVʥ2`~)8b ]44"t^sPr1Mj)=ĻN$ 5G$RY_nQbg#{"Z(G}1k#y>6MYg*[WRxt/\ޜɳ T^dfӛ9ABȈńҠqj?3>h:j|7=ml_'4nZېt(lW2ʹl7WEאbk{w'jT;gAwP^ +Vԅ7 e?-{yˢ%1x6&.ZH~unPϯ)o&3ks[q!K}/+K?&/ov]Ax?[ً2D{m^ӭ@ݨǪ xÀЊ"vسHr:ʕ]># AU0\ȕA#{Pʹrޤwl%ahJ `_k5Mpjp̫OF {E0PCᶣ&;-I, zUu1M0`&=  9llOu4Zd=7NփzN {L8zڧ1?VV:2jmw19',Y 5ḷhX jh>t;"Np1,m *&̮kNH] ;Q"tE&KEF(єHBJ&Qt&, *vUFx]ij W%HSyPh="ҬoSL$mF(Ot?yj@aG~8;/ ?khSR柟%*{'{u X/sTUp[׉mZW~ɗaHn*2f~ީQ]$M WI9f*~Jef.&mμΣa` Mڝ:s;8qlJ]CY8c7p)XWxH2VvٓaxsB! +$+g,L0Rw^rWuz jĄu oT|INH>i'iRP(5hm*~.iqp{Z`sUS"34p߹A5 iY/jG/&l֡4u㩈tK O3NOA[~,0"PgX}3V3WCpS9M4|l d.NJz"WK`Bk(8vBzXhLug:k"-xFwSܵd+֋{O}o==EY`Pb|*w:廲XV4>fB 8.vOh$%sX$GnV}Yl棊#.U89ht ˭[׿Iߺ8@?G{~۟,Gԯl5Ӂ^Ŀ>IgEAn)PH㥖F{Liʷw 9X^hN ( }¤GzV359eAF=>{|O[uQAMi޺iBaU7L -3^.%O]ʑ.wR@?AzDx0>|CyXΞٜDv[q qʾlM튔jY2 p Ue 2 C}2F~WߪiC$Tĸ Nzs@`I4_;f# '2&pM#nfA'(0@\>%/>{?9.29tP!27bRmM&^r}зI|:Kח%ie[WpUk5gz=Ɲ|=gih[ȵޒ~.ޔX@<{Y@lG2; eB7 #]%dU+ZBK?Eʝg8kZ"&g426\] W0`Kټ `ctNb; q?z42іÑ)Sq.gLPmл Gol>xa@Q+Ei5)6{m2:bҖ7ḫ,˯2@յtv3{P0 1;{(FӛHb8MG8yZ- \-5[3X"I+d dXLӌt [#9 *UkosVl, H=<4z"`H)hv*F03c+Sh]mghnQ7` ^, TF9?PT, ;:jBϜ=?u 8M+\Gu[)Sz.vP%EC#*h;"' O\iNR{h/𞘉5(G!˥ZWf,cptO_rZKm܋O$g~$/]{C\ W(-5 &zdz?[Bqx6<0ksJfy]'^݂4*.U5le(䗹M>*l:&/mX*Y* YB^BFŕǥT{9_u'| xGPBeۜh_ qDO{e[e%,o3r_:N$*5$4|x;]I C,4iIBgtMCsU4x^[SEQS)_g/o-3V_$@T_ zFG'0 .?.޿ b/ g7ςK62;;-&-? cp̱C@_/60IJ Yz ҩQ8~Kr|w?/_W_4V0 98?]?_ m= di嗋C/~濝oBooM7'6RrMV/r_B.eQOggh!W߇!V[Լr"B 3W@H'eA˞mYw4ĉ{ñ(*}o8ԗl坩$a>BoPܐNUi Q <EquLT% :b'vr#GٴDi_^[[2RGsHk+Ffɏ LFi|[3rrȽ+ۧDa+fz#ToL?޶ڷre>Lyfܥ*[ /9.( 'p57+@,Rl*#)FXЏjCQc8m/P3%Bp# oG 1UN<jmLV1(%7qb3l*37>-rÒ,__+K\%*hQw7 gꟵ5wp(s4UG:3Bnbߌա?rт/Vc #<7A`|VYtR+̝׷8_2޿}%эXة6!$`|7ʸL8Wf-H/[yEY<*,_GY7@̙ߩ1à %Ŏ&`mjHR̄\-p5 w-uv_k0ls!1\--[ {AzVgnXNUEFY#$刯ʥHbmR^)?B@Cʹ}k;Lmx}myJ0+獶l];#AdMӢe t^F2]BQކgZhd;}́h)diqѼnJwuy;>K)0US}|fL%Oz Ykv[[w3_:"+"|QngeU]URz6:&:0Ѥ]([q82_s z {꣍[ :xqcU2 %ąZ>,,A'>9wɡ#&: DvddYjS-u$aT/Zu22('傇r1e1{n:Ο {L'p@Zrh9.iPw=UP꣛!4W'^$V7$S=0A]ۋ?{+ZM{xC Jx9LU"op< -8&rCEj;0jJO |2cX"7qVqkv+8Q8Q׷l~s_sͿ@ϠQ+ d C?D- AB: mlVhc%"!>[H7@"?O1nS JLF??|=Gѿ2r|;w 8+ Y9 'h{;4v+a߬3Bbs'oJ̧8'E.ǣ&Aӧzt1w^{ݸ1GR=^8Y] Q,, _ 7"`~L%k~q5PY4VcbOny2D`UA*a:vIo :QlssGk>+V=9,u+#J3fW W\p՗^px2tN*)i#Z٪.<^ԴQ54)yq4Lw5Wsr70Nݫa҄d>̃к.vT|;JK%z&gvB^Aeݰ&-w;_j>SqxL]C6<t3X In @hFúJ)<'P GO-pWMJ߰6cu SgiR n@%hraF_:[П MrοOIA:w.huG)LFR fitV0:2@R))4:3$?m,.Wx*Xtyq Q&p8P)ǓGO1N]DŽ'rfE2Ҭ'G*U/)~_y8f*OOnͶQ|;[TZؗrFb )7 t{<\)̞wmAպbxۜe'2uw}!jEbD'{/qPXny-8FZd"&x^ЉȭRgޕy^ic׳v^fN'J腆VL~= Y7 ơh1jW<+'YwO>0*q \lN9sXK.uZzG[}Դz_,l {46&Cb=dâ1rp)y|%Q *XSݑA7%/Zچ҂nX,9)n;<3)\Y~[@Ցm]'=Hpw '}owƈSV]gל:kIAcKCЭ\wu.y, YL180%!\o62|5RGʩ閷_RܪM9Sf#v$vFZc4 Lk# >>4\I7Y"47 :~24&Gذ fP⍲ zCND$bc#A{%-jrA>u1(Eariq 2T_"Sz'ci_.-y̮aih wͬׯNG;lNr =ƷM aY묾ȝ}:0=a&{ʯD769"GEon4")X:mɐŅv`f 0gc@/cXfŒmxhdCp4H%RXA^g\&673,M Y9f}nadZJU|%qE贘r02M%]n\1}a(($'xo ) O=ݹKG׭"2'f=*SaqulzeZ-163 ݫ'Ab9s+h+DW]0Rҍ ۇkh@tr^<^/%D{nԸb W??ƥBZ tWElrU)`vsHpALnbIeL _sg|tcC:%_XBdzq֩3e'[ôlb0| D Š1cAE,!E4 _^Xs ;/?2O~n@+A/H,)iL#g ~K~r&jc͐7_B86_43?u7~zZ W?;@⼾+JK({6Qq_ dՕ6*RCQ IkFd. &lSYVr}_7]Y ?].mlxC\e /!,_^Y؈?UyQX\tTODAW>{jly\x;b;j}HC#J61+[³FeM6+;{(=IY5fo-0ftB`lw]p~ aRk}lMٔ+XS'5̨zڽcq!N ),vg@C@p9dfS/DDL5BJe^POzJim յJwh\1\[gFCݝP *_Tς^Z|V9 K/;C T ds :p^E@*YGQ W)7|4]BS} 3rt&GbHaR:p{ݖdQHPt`;7v߉ΦZe35{a*5K#]G9!FJJ̓4O>vjefOY"&"J0xN`r[U(C)»!st΂Q/ԪI_r{6.11i  wg\XFȲQ p:m7l_Ej 00wG֦̃̕BNZK6A|5R/\ZEp2z}:PJ,g6}H};ƒ%!`(*Cެ#퓛#ǵ5& lTv_/ԧg82uj-K9iibB^.#۽Wp@iw&Xua+u +oюI׷ZyXWeg"+83V-m8P%:Oܢ Y寬{\N=QzG9LaP7 N50HT,墢:#H!ڙxu|:}BotDnz^߭S|#~ZRaPj iosp$koe=Fq1(T{P4>[{րw+ak@/ ͈4D=ggޕZa{-Y:bz_@Al2mMyF2C$|cf%oW՘8"m?&aDZ `̈́cD6|5mK|t1hw$r;:̡^ϰ9$)TMJF&Hz98QR}4+h/p0[HEtžIaeU8C97cIpF|84c#[Z}L}#X֚OFo]%r#q P`thˤx8IF)%,UXYEw嫱$˨Y G=H|oh}^'۫V\lkk!Rޣs{pcoݒ&Ґw$|4]?lɋ-k뾺4ςu*eq)]& p0ObvLD'y+uTq"46F0>  ZtR9a)[/f֥>k>db".ߵvrN1i2*ݔ-db$%e/SN_j3xO~'Ib |xXI=$6,K0qΑ4fV0h^L98%efkw0ݯ/)}BuB^?\ W|rz8{ tJQآFBZ!]BLraFna ^f%8&Ό{;cmYy44v2P‚$$\Q ?çTZB[YT$EˬRw:c9}F.TͿ j5~3/=.mYbPw%\8zK^|ɠ&7h/I 7#+yHdwxJr/=gB{PH-H˪_#ꂀ>X X(U #W޷n|e4pJ̲u*0 B`bO EjKAm_K/^VgWLD2V b̳ڥI~Y7HaJPȅċP(3&~v`~jxA'.tB,-2t yfBlgMܯPL Z̡Yӭ!e*գetQeRJEemP@٭07PDۀ0.Fj]І7'K~Ⱥ)˱ҫӓMaLEʑ5/scZ&]Eol yzI$OF:袀ݦOH>Gs 8O!vh$m;Ɍ%>hM{n=;j9GaII7˪6K+s[OU| 3z+0{aȎZ$AmӬ}|t#RNXSuWB/|LJɲс~uNyUU p0St|·Gt]~ņ~ B]Fh&DG]εѬx\J)9lEn/rYG' 2 aX^PջO+G+ "wcf)𶆻՛1̣F`:|PDۈ﯂YX_dAyƕZXp5, 2#)8BN5E ˄ #IADwP&7Dq$ T>"[2 .eV`Dj FJUF-{0ĽPv)-ڎ(L شzQBbkT\Иw`eW"}U(]ZRVtF%4(95j0bx{Cԋl}H5zls4 '(ꇲG^t#xӅ mhƮc: ( ݗtj$%ܸ6(eFjU@Z$bp7̭Aۀu8s>Z;QKŔKDj"`LXlʼx;*^0g +gztr3gG5nYlcP߮HyMǟ* H;=uLjY>u3!4h͙|-P^YLvz6>FѾ9C@\-Av˗(d~l NtpTۖZDG+lxՊfW񼼵6J.FTX;j|a:jt܁>W} +t_xdGb͔X%ON3e)_,qEn0rX5#!^vz7i,d`D5dUl!3|Qyv+?u9|JQ Q*=w8 e=DII%(</1B=$ܼ\x\b֠jrWe_XY6 ʘ 빎ea}YsI"l20wFόF3ڝg>j,LF,zQf2{kCdx{_vTMٙW mH`MkS9>XD"gY8Jx9ǽI-Sow[:y>]+!dIo]|aoF}?47:"FeC <jx%܀B?\S;ZBx親ĂL6nZlkH@x\FqAH)QQ E\a;*+Z?5ep馜3ܖviS7p2SU0\%\ȏ+mp)B9GEKnsr%H_Kj?du\p\͚g!w 4zŭ3VЭ2Arj[x循b3еx1 siZïǃ,Z\=]R\V5۩N5X' K )$? $כNHC=Wr;'oŴ`(ϗ[ͣ5~)}rơ6=\{Dl !Z@Ali98@{O稞TC#暑N&3{S+N\ȟibN{kB+^hMVu/.:JYpP&,maPaϾM!Wn"9pK-#bRzi~&W6vʤvI*ML$"ۥēA57hG$? gǿG- Wv1`pDZNQu-yhJ:vL* N$Zu*:cw Dt.0j}g eS^8]n>G\˛E/L] 7$|`SӄJAs 9tmD$1^&@FɣlL۠˓&Aoro!ɫ9=׃4Qh71*B˫;7@NJy L,9֏[ .ɎOF 0b\J?&y/|$/-sP{Xvh6IW֮/qVA%3G{^Q|RZg thLP8~gĖUĠ:[4 ٰZ/0j|?Md:#k=\8&f16tW"A.1̺I7um00N0oгhqx}fb pĹG6SUwzzsxϓbv (ã{&.iDp 8la{\:\r%`cnY u@(0~:=0t[y4پ?ߞ>ml/FK P'rP"l5>vG`M*Fo7Sj7]hKh=|[OJ%4~|Vut+)w:͟~} =g)3Wk bؙٰH TEHE|*BFzgNxb wNF=yu9 +3w>oN\{3<sUⰜ(Xxi9u<fr]t@4IG6,scVg P;l(Iո/'n\Nrm$I 4}A vgJK2^[EAq.6J޹羨"*)LLcb4)d(drGfʈ"%!hMdQ YtZʕ,}W9"4k\:(f-ဘU#OU'GV/bۃ`Z'ӻ.h'"=fs_|ӌ m]#2,W4VncH^2V:~TD6hpK?&%!SYU2P)d_砪*QAL #Qe'G6̔+w:3@ &~_8. r>)a~bg\w?my^6 P='gA5I$SFg'ڔ}(d7}+'6K %_?h2Z΢BOD'pлd@o)7L_Hڿ6d*/[``Mz˦/ˆQsQ-ZVqC<I5Өkm7ʣfFL__3ݢz]DJ)ȥ X(ˏPx4%(g˼++XhjRn[@!izMPu '@,F,X{ʷl5. IBhp3|U.GRe„KVgN&>ryUglcrh*DW:A?Tt6 CN犐kwa{eDR ڟ!(a:NL]H'@@8qۨPL5D&AB2X(IE} mO)KG2.1X3t-Y9KXSŢ}hʔhMOa.{!l v<踉PF0:ү.?~a_gf`7!=; _rsR%DC~z:ƜPNfTғN*2v~ yjSQ- 9\GDk z.ӷh./Z^Ryҫr TX: wN0:Ura(-4*+'9㗙rSXH&__?Y_+q{H% TO>mwG @a'Kߵ#$2}ki/GB3k5m\Tj&7C-d{t9 ajWϖ-%V*Ws)l'm!-i[u{>u+0C,y*f>Er|ܙ9NR?tĆ֤QbG礹qՓŐaimAYst*.]H^(gMrU.g༴Y Yr'/ ɄN$ߗ%Vzu,?Mq\,(<<2a}.&*+{˘Q+-?LD͖]s3  9SꝓV)5CWDosv?8CK[Y&T89ARGMæYU0c=2 yFûuw!B/Ds n&%0TJu͋ym7 }Xޗ˨0ְڻW;?JJyߤ,Q1 ǒ ۚJY>LS1[ymƊpRK+LLlm#%gŲ'O G~Dz{(&>+1wh̶ 42VX+Tg/L J=1?w갘]x4V"]p r60#6HŒAyn JbhY|(]b'Pŀ}k%%d}o iCZ[/ /3+\\=R̯jE hH(mn]>tk_CFn.'سQe1J3z#U_#_(0Ur{Upf*=^*j%ڥ<|Fw} Nǯr%>$$OMl]  E:aǃ3Lwćx>NYıG{'b/3evIoA2wn߫~Լ=pJF^G$Bϑ j7 ̵]gMc~ğ)cQBRBgՏ0h/̜"v jM֓A"Qoa/Ч8u[7 nDAA\/ SD7#<†CL8 _wYQ:Him8S!qs_Tp=>)%y'+A@u'NhkBD<f!S5L5WQ!)'+W%%lwO;[^R+|ODj|}QQQθGǛLsP5H=֝ơ[<_M0z{nN={v35">RǏRym@ ^v asl*:DlYPxu{ku ޵s**j4sH ~V!p-/wiFW)Fhtwl1M55ISW;qzQ^CY/1"[;ivO^q 2q)h͆,M߇rd(ir }Kj |fjb``p%lE`tJh}Hg`TUvz 3a9wHuOî ^c;<,[U+Pr4AOB@$J;F|W ᫝7"?!aza>ާ=a[KDw0mN2m~KXW f%BEKua 2"-Ip~#B  9|]O>nC3yTZZO|Ar>>gp4aXK͌Єy 5r>&z+`HWFm,yҀVhTQRK̵[Ͷ3#UyK -Txe{zuiOnYJE.B'Ǚ톳 &23NW3S:"qe*m_ ُQ'FkOH.5ϭ~p7*q>)s ~5]Uй%| [T,^[iýweM:sj3MZˊ2M+^ۚZtִW4Ua;}UAu/mu奴-aF7}C|ɘ|VF@M@(0AĿ|=}^eRe <>1vXz`syf@C g=7h_ұbzItyD,Ƿ Q5< }-;`kvai9ҸͮigEM}c 뻝հw3U< Cً0!컼o$74DҖw-,)ޚ_}'+Å2!"d\Cg+q 2$T>Qt?3JFO0B0vxc"*_PA\hHj"!)đBD"H!H`~BDHDWO7o~lG&%b:? \Ӊֵe^I < *|Q( *.I3@?;>tM돶t'ҧT+ *q~d2^o*-Ԛas!3qm0TɯQF +ߌ,bp۳̔Q a )ؿ_g*fI@[qHN_zJ. &y`F531%D D< OpP`Ater @H_|CAND V{nԈx={!%ܯ"MyV{Qdv!*1`]%c"" ]bZT88?I #TDlq$g xgo}v#o'h[**GV7RPH+2f5ݽ!Nc нN(6oʏqY9B"D7n. ͺ,|?!S-4:>E.c ̀)A f4_A=S,7> \~{T y/ߡQ!|*US;?H!L~E./G^!դ`]PmoTycX^Pi^+|+N&ob'3 6ˤΊk(jqbx]T~*S Iwf|vf -)-y">x^2MMM,@AuwT(*c{uQB&{BUD[{#6P厄~'%os=0i%AQL͒oFoOG31آ`)q婚_u`x >Ur=Z,4WrTb>~s =Frapf uۈ o)l$3U8Si;-/@X&F,2%* !Mk]dq?o/\QAMU<"Pd \p>tYF^ Ef'4x ͇627@bڞtgWD8Ðxi7 e DǍkM= U)~vEL57)`r5?HW[~-_C| $Tܩ @IX)ᴢx 8i>[NHQD*N3뿦ci!6Xi达#<oL͵ؤKmd' &M+Y/ɴ?&ӻq_c#NB#e?fie:\vrGjkKCK.n-w^ts^kq]PzRst#$8yW0BRHcf'LCѼH6 1Na=zTVȴ_xYSyA@v9qĴ88!_2KTiB |Q8S:!-[>e|޶x)N G_=q ]U]1q C+*-(8{|Aֻ *k2)/h|VeDtv{uǷK:c]@ ?]$V:hkG'JžE>QlF(&>  l4:уXnTSk17Z!I,ع0oSJObY+D$-dOR E-=2,ˍ{I͂>f8;YG{q'lBJ@ ' [Hidn)SPJ7˟BԻ[Y3 J%㴎HMhXbT9BYUt+9!63>Nv ݫGb2Z#s73'[}9ka˗TP0A P(P!L`ݓdw*S@B)7IV tg2I5/0tfa2@6/7ӂX'MB虀;1 6<6'd퍑ȣ)$цÁ:xf;Z5 j=Si^o Q(͛Aοŏf_C Bf~'6#'^#-/?&'iY Xs$D4tTL8x8@"i訙~vkz ^nta+7"bb䪑r ԚŃBgބqzzM8M:ASg'H*G E/KDy)ŎhGWmzBU+PWiR{?(Xi t80[j6g64:>&⻗|yL%tn)+-,)˒ˤ.(}a?SuJ)Mk iܼ/nZMj|םVSWXD*/BCVyc}JPInjiIWPbMCIebݻգ=neC{œMݡ#=aC_5tMM>&Mt\WML=Nf=~-Y>i]X8|ҿv3}ym|kh`h`@|~x{A [vrrX^_FjFp)+ QAM'Ɔ6߼$`&Cy<}UӃ}XS_2?#'jOb?}#gO&b(=UMTow:`MBGnXqqXXsګL/s4iHH큰h1V-WNco":V s?"3Fu)o 6;hy*~Zte9ւ _s^Zݲs.KHVмH;Z;6!Nv/zw~ekV7bgH!&҆tvZ2\J#"~ 3=,b {pUFK60BJWEbPҢgM1x)/h6Cѹ-g,5; *Z~yb>sԆJWLA ʬ@Q-)ހ0=Q:5v1JO{lu#Ʀn#S p\dsӈVofti1XH+%I`?@:I~͕ " mןa֭_.0)c(ci1w\Fzfb@T -]Zc{,SW{ߺtdC&jS~x%y9 EB>yo'4 9Z-5@9xbݼ!6+6`[,ۚܥ}0 g})w"@&K%Ti[#FOj665oC%/JU>' :.kEZ'dXbdUf¯Xv֣'4 OVy[ )34I F1+*rP4ѱ8$`=ϔIL†4"x(cwxCO?H`%OB@ym@dZaE ] SjuN,էR]]cDhF0n\0øWdŋ)WiYӍ:z 3eYexp}'3s!H7 ʦaZR]ك(G KV!_'4, J!rx&Nm+[ډK *іtB5t6$}p\5R} U23lbp+PDܱ6sM1/A [2I7\-zՐeS5w :Ą#e~Vn1yKûHai=5 GUzPi *(H0@7' 9bz~xIPWh0_NhePVVtL 7ٿAxzk_@{">=͏R P+e]<XR뇖b !f`cxP5(i /~?VߜhQ < Oӟrpon[e]ÿ5D)E姳ӧ%OwSc h==4M##h0M?uw g_{X'0iVuT]'K)N4xM VI<;Vp92^z/ Q@j2-]uޛCì횼/o|`)I5пz&'iz%h'/ ͨέZ-꧀y;1ܪ5#q;4q`}MjV_٪tuE 랎>˩<2 h*,-IɊ& bL 4gXk? E\Ԭ(U[((ӍL""-$/yL\{?X*mC JH\tPڰ.\D@϶H֒N]VwDp$eS>Lr,l13_"v`޲kCrkyPh5w+5`m>0TA!t"PK>|,ۈ"j)`(U&QTU*|_|g;y}ǁc* eJ8jq< > %5ϑR;ya9 17AR*4x!]xBR7 {"2bpҙ~'Pij5zyG\4p`9bӺOR'DQHBLd>/)8j߶jʝɧp`P¶J_szNiy$ ,| _=D E0 : \HEMa bJb$S3F^szLyMF92073SqeE)z+ܯ[D3hJ"dZfrE8&#uLz0yu>|(s* E{7pҙߎ- Uoa}Llp: ݵрß7C~M?SANrch6%+2x0299 rscbrpT77 ME:Sy$!b2DJ@lhDؒyŬςN`3O5װW> ̆Xgqܳt!EȤ J#aA!f>Ltg Yze"%]~2 %kef}^~8r@R0j8o>Wb(`Nɖy2إ-c {-[-@$MQJOPoU."24Ckh~=cK'BcOA`HjYCتCj:k/Q"i{ϟ3!9]0K U'MCM ih9e3mS[DjXDhl8@nvufBj7UEK/}L{?KRR%rWPlQyMׂCOMeqKbJ igZs`ᒐ!.4e s!y7COx#W=fFBWЄY~4_##]`ltmՎ:snY _Ec TA RK{s #nS2pq`9)Fm^".@"-$_emV/I` x>7Q2n,y."s#d\I62_פ?+R) `aOJTc%\WOnҿHHXFcviAy:? 0-ƿ (P" W8z@M +O؏ֱbaWcbEl].voM:SafG^֗ILJ{6U_d|b烮;a/Y6]7H丐Tw-7(bUD*;)9F%To%۔&#\xv؟|)Wږ_`6>' Aޡ5z' 4B*&K5IɪdSv(#[Y *OS{뒵>1m"u9ٙS*Sꃇ.f_hL ~i] !dl"vHoE}lM+f{0)LSܬ!D'{c&,4讄K8X%tmp h=|`?J>i׆O/FY+ֹ`j0Py *\%ie@ʓ,zq[HtKǪԟlӌln9u; fUGYqhIs< Cm]PJc@vz/EÚ9~Z^qj^ЬOeu%znb׽X [.wvVӭbLzܟNd HxĹM|=<'łgfYD$} &Uoŵ3"VBhHhjR7PD;Xj -f|<֭8cx2:I-nޞ.fĴ2Wـ#Xae wBljW.m\v3-Iº-0 D+E&Bȷn{u>-c3. _6lY8kKS.($WCK`r촮G"j_‹Wvsל8nB3*ByTI sFlVӈBI˟p"C,amk62c 翊tyC/Mp&"%/=FC2ݍw& 0H;A02:;v _N3c1)stfͱ:5m#j➯8Gƒj6;t \`0wf=po+^h@iiCk[AIMπ6~ .RC,sHN7d㨇G6Vrp;`w~˒H\Ppn/7g˼?8R.s1悥а*KH9t>8 :*2@%ח.pH;S_I0WsUy͚cC<(@!?CC({˂zD6d}* J;jc)db!qRN%b>W_ ˜dD⃯Dad;h򣺠 V9E tAQm}Ʉ \/3.S =W݉5 |TH0!ޝcB1տCߠ'C4OjqEz))%%3ֿJf?k=}{yiA->#- @Ɍ zDG'*Wwmg(?1R" p@%eNM (gc=5=`ؔ(d(&|AoVӏdzsm=@p } >)ژi[R[>Ԛk[[2ou O/)h/ձLW_llc3`cxwſNokjO0 dg~cegˎªe?$kiW@ @ѿVQUËYy͌$ekhO-9%u""33 o׉koϹX@B^¤1{6\JY| "*47 YK-pj`x+,$|l[]@tLGt8 / 2'y6fHV+y6qL)y8ڿ`4f>d2sxFV(퀵nsC#:j3^E+n]&NY">8dg,Gq-#|.@ 5\ 7>ت_elbRHa":B e`5yDuLo 9/4bH&$sDq廱Iх|OS5l\7BuV ?lˇ hzb F@m~`xyI49;w۠x=i;OW02}׊_V6W 54 EpqA .SX xS՟/Fڎx[JkoO9`72?{k%v`>O=J@t}B)xmpG'wu;tSUvl$8& t Q1%t PWb5h jY0X ?߱vF{y$mVl,G-.: ߞ*Tg݋B`s.uy A4+qS&"]^Ǫ[p:y'(nYhh5`UBR/tB?.ٽ v!;V=d[VK W\$hB(8I٢܍S⠷"SL}0Y0ޑ{R`f@- -! 6xpm0ۉDi0^dz sLe>,*Sͨv:V6 Ǡ-QZ p93 N;b8o`YkX a0 6|?avNޯ!M;{ZƫϴB&^2QU}öɾ2yaʨ2 vV6Lj߷1.ƀ " 8 |Xە~]b,#%DZE s05/ Ӿ6k/ySS7 w5xCn& 焔YNNUy0mugJ~FGil'*%Xdɩ1!W+p={eNiyB 'Eۺx//+$JҺSkjޛtL!Jc`Vzk7$ós=+MZpJ2̊yBC$ɯOCe@^ş=y዗P7!|46cEA7+:rfg%Z?FȉKm=&@=+/e vͽp_5J2)6|A%i%w$e)EkP{w蚣ĬiOW|b0[[oLWW @A16%B+)bfܡ/3gq\D,lp,~e+q̽Ф%3b1͕ԗY#/JʮRa\c@:dNQr>j# tA9&!]iE󸤧-G,$oT=͸%.EW9ޝ~^bOP7jzͺZ˒t4q: lM f|4>݅3\m֙5HIj=.[!OGPV_l?fF?A +X apf@AÓ3wDۣ3| ?~;)\eIiocc?r ,?q-` DhU<C>ꭶIWX \T$ɐ&UDy\ǏxSҪnnQObl"*J*.?1R;44Hi'͟lpSְ$}5V|NP.eL3*(k5ePgg}Y.W)q?PؤV`^ x-X%KQ*U˪:bMֱ`uE CUNSe G 2t RQb[5}4J;~==~a-__\" VQ%]~upbq1  X/,#v\`BF yM[Ʃ_oh#)rs|UA^N"QhU_W6s1gn7P٦tf{niPv|!M8|l(!r}X"cԌRs9^jy=u*=2z)O5(cFqfo (Yd᷹^Vh,l-a+(2+Lm/طb!SA[ds껺^SpjXLPXoԳ.K?| ͠ߨb: w?4W #pg޲seZQpXXG)p\ARu|z|g*@zlzd~0MdU YJUKD=oɉ VZ0#\upsa'Mfi8( ,h&E16th4ۣׄU pi!'ʏ5,X,TxU<-:d~\,|[Z[ ٧7/arb}ket2ұ heRgm,A"l?/{t0 t!@KpfZD@gb*#W>@.zIL`䥥3\Qdmk?U0*%gpAS$"IP7(~, S fƎy. Pq e%á1lX `wrlI;K7oƝq, 4[7-9=E-9H~qc_M7=1@:?DOO/ȟ6?ޘaƷaF*Q`SqPYL>tFa4(,9ͧznXMYRH?n" ki w%H"DpjT&/._͈>R:5F쾤NA^vQeCmIyƾcLH!z너!9!]Cfy8W R0~Dr-^97Lj{|u\Csy:cG.a!ڹw\Jf$4{R5^8cgiX.SXJPcXUV2 (G+*Iꗆz{mN X ^|üE/|W4k.-9\MC fWz]do.W!$R)v?3عr~^bCc鼼ʼ(Ahu|;X4C~#WHMvg[{#5.PJ62S7!@ `usPDV3Ҹܰ:џm\EdM|ͷIyq%.??)N&QB@l.eL@s%K(6}4!l\l<]>8z,~A^T?Ww?*~RE>ّU ZT[ uM`Æc GyCn؀ܿ AIUg>Vfj- ފ4xgiy1]^W_Km\Uieڽ^h ۵%w>>>K2=N}="K;R0}(/ZHgeY[?Aɤ򌿙-5:sT|l^)+Nb,Tn^z:Q,ɡX"곞7ȗF֥Tc!.k?e^JD)ESWcb(ū)geP+&TLy׾RrwձR,)4n2 fH;pquvR;>E?XI9$Tk;V يcf@pD1zB#|0ă}rb/HjyTk[pj=彁- 6.mY>C9,|#:4~P`A6 'a%%;}ۀO]:agGAf{@D٨=k_ڙߘgh=txq-m]Dv,"׊똣UjGD*x{ 㓰פډY\def^4ǎ}갡:ָBSӤb-|Q&%;^<"Wdb 'NaC'x`vMctzIb"wK6\ES_q@Ԓ(~tCɶHDĖ-M+B*@݊X㲷Sc^P#}{Jg'B>dIΜ:35yk(< Nr( n?c5.lͅ!rLp hL<#nNtjq$AQ9AlCh74,3F|Bu7w{Gz} oXDD=OǥQ !)jU uEdt`TfWziF ,rRun = |. -}:ޖ?v,rx]ҘomZ.r@p/eSh>'T .M9` ~`L VY`LpR2_Obˀ?ú匆'i?Ï?B^%4ӊ!HrK0Sm E"cZdCVҋ)?ڕt.%Z{F\)*x5|V 45[#][]MѴ[Iis0݈pAb'0x!2tiXL3mحU('U[/՗=vwX> 1<HG~օ w֟ƗtwvP\QXZ_{#rǫA4{Q/h0 ^蠦_n(ږ\̐݌yq_87L=Ni yv0OiG5jJLBttƴ>i05|8kծ6(- IBD֖#a}F @RYѽ*|K[)^>O3`%u.qpg4WxybxdZ8(]lcje帞=ǡz(Ka0Pp;Pˢ0N< f|):_6p8TƋց]qeKyǹ\ 7{%yrq#Sju ڬBW*u%[qJ_85>$%+l mK B@]v p&߀e ,FA~C;,y;(E?+v2_e:~D]t??*?C?7= Cĝ<1Wڪŝvt"D~Z%z*2eμ|fsc3CJT6- G <ھD]"1q|pFF"J^Ѭ9ʣm@2Y92bRɆm~vT2=t6Nlbn}4ht`ąqU\|x}ߪ(h'QNfYG^xG^\7Y#QK!e1YGu,3Z;BM9,Cacv쎛3jKySCx*pURt.J )XqOJ?XDޮ bvQL9=BދIc%xpMpww$Kp -^}=ɖwyLTWWZ]3}׵SϘyWV|.>YFQ tJn/7ݒ'Y) ^@Mtι]fDv] Wo"0FalTEK {wG94![]ycmx*3u) x6U6-״x2xe2wftJгXQ_ȇO-`Y2})2:=}[ \-vm٢18. *u*f9"HJ` x/YcqP G)͸p #T/֯O ?ƐcH)+&UsQK\ vD'w2k=uAȠO3^Y=rSL7>mYہ|9pS"f C4 +IvC]Qa/i4m7m7l36Ϣ!}sP=;ew,&ws==Z`1<7'<_~Wa&,Nu@+"6ͻK.Xg)(qLmL qL(X~b*Zscm ?.r+0ȃxHs % |ER܄٢bp6=FrPƵZ?XUȷ~>Kmz^p5aKpDI8_]^"$̈С6sB滄Uy9IN^|Le׎\$wW~M%s Yz# wL-vnuQ<1ۑ|=93\ cP9^3t?3=܊x@ g~WCfE|f]Xx$P8E G{Mm]6 +U*D," CuMtՙ/! 'gxmKy N^cÒ[ Q0cV*9S;ц a~ 9CihkXW3px/AcJiҒ ILGٳAe_},c:'"$ wlswC P Z({lixdg}ψ]%$;a^L[ӡk#:%Ey}%גT-㍻ x;Mc>c3R8cyd} =$Nw}B[S7֌)661̔$+j.\pCo4\F_^КN.r {=Zk"`cjjc)YE75HGyBv&@z<ȰK&1&̕_QsD$$0’[2HsvBd*cp3@`hҳKNQ :1}?*{Epj?GZ!F 5ׇ{>c;GВ01 Xeg7>+!\j;wTW`#DJMأFdgSrfc6\v*H=tckn8$U 6+:¬5AjYE:-,P꼺H/*&RȂ2 T_`z/YnZдu7@;U+.Q.uv.?f3D _=mdçm$Ex}qOI Rw".>A P!giًF0<ׯ/z&"dzr4 MO;(hqo׾LBqؗ3 #P֍_Rևuk QN|g/߁ ?ħ吇F-f"gxaG^Z0*_#bbRe&RLYW3}f4 ~d|q^8a$裯WH7Ë+K`/?N?|q0pF8ݩ (~eN;Ԇg7mNX\{m,0XULWy^-kx?\ەлp<_@N?<+;ҧJfr IBLrY%wٖD#2HJ9o]n&Ք ~`J{f]AʽUb .'q JL-x[  L b"t Ecgg12 ('7gAn|ʒ]0 L2=! -@ O~_C~IpoQ%;#ąpT%;qV4;O]*SouОrbvv?A^^^xH:c1LƞT^?m}]֧,4bV:fJzJvS*jOќ d"-F{7Ynh'F9󟘜'm[W P?p1[=gfT?fdF/؞g/r~ΜjsXeOF" `"P Crj{+ aX ڗFVf%2W9s$Et(jFjg0%ed)X5FP!Iƻƈza碸*7xp|FbHDOk c͎G@Bw∘HN(_CK qU{G Gsi7k8 Lӫ4VϞylomc's >F[^YQ*ZO MiyI' I#HqG-H[-1<)7[|)=YNdbr谮}Z6^k{0\>@k]=% *Kc!{Y?IZDO$Yc'yQ0 cF׭^((5R5PL$f0n9BОM.-8$ҭom~F8ɻ_t_1s:%ˑ[TS7RϮ 4i=9Y}: c{3QWc+!u/Xc:AySŽ~36KR-kHrH_wFi:;>b`ʻ}cZ1x?I Gn6ʖap3$xzMgB{LUtU(T?0N0(ۑg^M{W-r;5LA.Um6R>}`n]Wse]u̒]GA8\nā^6)ē āܧ<h=׮`(N=mMbDA$!^x'dudtl,46&K V% 噙Usuf+nl.K 19jg^mӢBMcZAЦD1 قyQ/n:1Jn[CM LijV_FGݿz>iG׈WTCo:zK RgueCBm3u`1,Q{O8$QuYsUF#o~e17%^B(6O/Ğul3<W 7 ".7$Ckm0NTW"+ZjʑĠ".FDԅ=iXS(רx$\Zez癐醦_T"Td .R @/ .>s?#B7$x_*p?' /?߽? w4F'6u؀ {_Dw_v_6~O?Z~OwJVlh}ˆ['Lmaղ?30pd󈓿@b%afWⓖ#̐/R_mȁƁWؐ~zן~&Q,1lJtTAs &_D(rDib8a%'$~峴"Z`_hlvqA_HG1n_fQz.a"Gao$65GMlqmfQTyzE-hAŐz (TŚf[@jÇ*s-%0(Pe)0+ZH,gz0isxY˥=s']UӒ$c>^1:gwuW ?:\ Efi|vO`M9P3_pc^rK\^eg]` k$AV͒DYoxRcϵ; 37n$!ܮe{XJ Izƛ&swMpo'4É>##*yMxTxuӘrOos;lm)[ 9w(SMوL:DwKtgnIX<ºS>,}sjt`ӧ /9q/+֘>BxU`k\Zyt!S~h r}5u|sӶr>|U1"+־jc$\'{qr|$QnuRꙿd!-xy:2Ly\-a֬;/Rٞw '_'iOC Qw ºwjSl _pS{vK6\|yL\Ko߾y<]Ě;{755x~sH+Ng@ãЙh\~yQ,?OLP8E9s{Ja4 ]Swo[X`/?z'֥FJkir Ś&|gIRoVqm*eŨr--:\hJjۚ*>7Z)W{C$e mլ^H7tpa` T1l 1jضkqBٍ])pa0^f_`rGwa4,յ}rd0JH<4@8݂RLEkHD"|{)FpaXn=q)OKdE0Jݫjچ抳>i6Pk}p;ӽLq8ftX]>C32&Ժo JeݎpOa"jO?ԺhI hySې`F| `8C6&NLK_k3!' U}LE'zmx785k(*\/`ud5l3H(ւ1J|[%AS$uď$Wxjc%  ].%"KN9"ۡos|v:qp7D"/|~R_i9m%D.J" Wc{LC"fs؅9aR9/p,?.T'A~.F;l7L[3'cnɏ,jcCJ}_&dJ NJvqݸUݭ3Kn6⷏t\(LS#{uHk&KF6þ߫d% DUEJ ٰE]{WCl,1ޅS~g4eIgYFQڝK̪llJ1=!mG xgry!0koO-v6„yڪG6ҝ$rSrM.*LbٷM=Fl튌0D(rH̄\ӧa;ä^)Y[+JP+\g*a! `ijd=&: 0Fm2VxmϠ* @7cix&QkL,ST1e(+P[|oyY+f0(]Q/M~yهtVNX6v6#%0*Vajx|%*Ӧ#ph$5|HB4?@XxS .T^d*~Z9Q^>ȻAbc81AvSԕSZo•I=Ht-E:t) e +4!Jb-L ]6 c?KqOHU>s]u 2!|.W>T7#鮐@\zb Ⱦ wwr֚XvE6:\uꇰȏ6{-s*uZ/)Hz m'OĉVjspt+X!JfnKP; pO߮vdI QI>䇽j+ 6ۡjL MBPK|F_w,!vρ~|01m-TW#~N?\JpVj>En Jr~k;H ;*^yIP7m p_I6v| 7_6yB? G:}N2TEњ{FP؆t Ssq CHuG4sG?უQ ȷD5tޗpId6 16Ad'vvN^9 bg `T[[#W0.,[.f8N{.8g@c.y@D+oEo'e J_>pSZǏ9C`sCa?#;P @l@U}c,L,9z^b+s? YV <@1V:vf黿Bc,{Kcghg@gjIoj`homeh ,h szӔo+=՜G%`,@8 R~)ev0?!'/}~DS&MRQ:7UDk)8ׂx5pD΍T0ZLqIG]߱=Y8w~{.֫'~*TU|#Sɢ=G);,Ҥr6 tC8P8d'$f@i6\JŻLUwI4(1VndH|Bt*c1L~hN/JJ@81^@.za + vWs&ue!T RJi6}1^rYȗ,X|_ުOɽLT(fa_fz̠#؄9oqP$/OioH+ =l"e$?Vz biC%`*s8 S}s*wKt*!m(psCL]&sEYDq' :ӻa' $Bf>|$1z;Ӫm:jl!yGJdž)x\p))OuHA6C"]t`_xX%2^>o}!W$¿O 9pNTWڅ 28T)eu /&Ɵʩrwt3㗲 OgFқhnHc:R>cbj`$c(J9{7#6 &2b#A.o<A_(EkuR#՟)^N{l{.m2~N־Df" m{Rq=Nheց9E'MEP0yjTKA4zdJ/u<4y :LDm_dMx93nx2Η}^duq(ڥ6\(s+ vr6X6?zşׂ/ЏBoJ %@7GЗ3}}m0ZH\=];FHP/FKʖ>Q\wŗyy7޹ZJ```D~]z$Ϧ(oGfA!G|1xC##D}{_&E] oR.60_΂ % Yս4*W* Ū'p_?Ltv]xI p;8i )E.-`;H6~.N[)%;MHQ[kZlW'7Q}]L'>q3q 9fCb,og}xGp9T-:gg;ϩ5>\77AzQ1͕&! "+F(b0Cw}Y412@,X[ϊTwЙ,R,`6|r_# vhlL =,BEz4cLҼ*LY}3yLicaoODiz7f)AdՂKŻ/'pDQ4Ud1vʃ?1nmhs '-ڈH¡^CD^Is> J?dB<w,F|ك].:фsjhΫ:7+_Ha3љ,_n*KP?V#7/;䏪7&7PPf}蹧IV5D+kuu2s{8o/3B`k \vDM4K*nm}!K~ajuf*Sʳd/PqEoyCiBGGh^A5c␍(e~N./JǮd,nBlDkVI/kj7=#ʔ~˽1mPNxᙓX.f{3$vZUdyIs’5>..m1]23wCpS)aO_]mW LcrX8 0. $Y#rlO]#ӓ3d ^&H60,@i9#ScG;CWtӿa! pԁ+jldoom 2Ɔ.ĩO'[BTF1 kؿ@Ɵ4Xdi[@`?նxϩqcqՋ-}#V$VBZp.&4droES8Oʤ兪YmJe<5YJ3w$/%6TKJ^!e 7-;+V0ho欨,J7B+.lqa) iO/2f_ϲ !WxM R7t:]-sՒεy:ٖ\ ވutwhI(v6/x\]`"xS>!ܛ,k"` J&V`#?g">4.H*VWɕKYE,^NF6IY|^NU i'^Koz!̽a.oU5aGv ~&0Y/1n䙊`Wpsp1$56W65p0"a MMS: Y[X[S0Bv 6@kaC'S}CyQA-+_XTfiEt!{ftvw#Rv0. R}_:ۯZ|J@),7Tʇ R?u2+2"/24dsZ~L1C'ԇUǗ%{92.g kڏGzmWmCUh 8h^֫ބHm׋skm %ЄH^wU4PhA~|w۳wn-M)`rW ւ_=>g$I56fᷜ@}ov_okSljϒ(d{ayc{nj#8Ly@:`^ZZGN^:qLBz4\[ ܺoߢs]|< (g{+*bq팧]?&~s:!o%=^ȴB{O$Zð`uN=qiݻo._.<<Vhjvfȧ`h?_,t|S^'%2Xg5>rZ//Иӥ=|3FkB_7߮4"]G6Dޏ2.2% j?Ƶ d\6-W?kG7rpzT-Dғ0]F9nZ _Miv6׬8UW6.FH'H" (|K|#&=L@Rj~[l:[>_h+o;O؞,}:8'mz{1=Ҳ\Jk~NC\m[UO$UN'?G~z[Vo:Iۦ]tٻVrja| ㈅q9`8~:> uEYbT{?~_忦Z90-h]^qN;O[i{d.==;.;Mv8_>2Gl]zN1}ٴzwz9¾}nO@)oc3ktۭ|})p[IYݝ}uh،FifWr{<+sLyhcf[1̺"(C~un@)!q4;vpvwmIIMx5UU|3:P[L!bo7qX2NhrxuI9[U>f @og"C5:C>.Y&wg(4w̜eRufLxk=]rˉu;OYՃ`-GGbGסy"ЃQRFdj^; I\"#a/(է7.loB٬mBŷSy5%-۶i[2WjPH8w#۹xLElʫ 93'6 6;()qE+p?ok%<6ƅ`sZ'>(_JvEd+L֊Cz rO?iE+M5!n|V(  ;V\r&w.SByijOQU~ {@HY0ۼ-fbtS.]UQdD+j8#6NKggG`z 3K-{c҇PwͱN1 QpR9D^QJ)7S8(jk]ZQGN9߷dqC.ªQbcpR9ЇNCo>R:jQ )؈أ[B&v`ג*&8 H(PUm9?y5ľѹV![)7r4~]PN㪜Mޠ; %tC66g?yG 1Khpr`[-7"<ȭFd= l3P!!A"o=eoGDqDzpǑE, 6]psѡ"XN_d P9kS!Znh y6K[JjYF;{'?\^Shtʞ@ls[+$0cYj?7zv#4{xliEiy.TѼ\94!B)c<{z[3Udؑ $$cϳNoe?jsN s>QղEf ȹmJK zd‚U[`e2cVPBZcwX6( P!yNsLl9fੱ#cf(l׋oSX:)ci_B'K ny=4 `7!*~H 3F w_r\go> 9f05omw&0}&gb+ K*(}E)!wNRe«Zwpۆd8GB|A~ib{ef;yo K%VcR+{"|=Al ;|Z$Le©QV,#{A<~#G|`c7{$\1R,_郐~[쪼@+_XTAR{*MP9@-O{" ]{etM^2>=}M 5עJO"܌eڔ(T=j[^l[T aLlM՜]m移( T®u6/G듵}Rӊk6!Ђ]V.lBk6uӦ̘F@h=WRz(8Z>.3Gh/ KsuY X l}Sy99P}8yiM B~Ito^SΜk;]{8%}<9 ,Р#53fܩpJ=ZՈ2."J̭XTAn #J**+{71qU&t!eUGe^JSYvTX!v ]Bޟ64PYlfĘ֏$=/ԘSQ7Co6+kxzK@̂ ruqfIC:j*$R0[9Έ]U5C;Y  hQr&?ѺJCwFO Y€ ڻhǀ2ɎĎC|J 0U RQop8y٩'"rojӽ+FרUTYb~!< *+54k{!>%mGHluw+ٙQnOeivX"O"Dn7z-|rr[|Tmv֙:% R0*?̙ vH) 0͋5N>:쪢ۡ>_x*uz߶pV2~-t,LRz:k&t=xJZ%%ͮɮcmaZWH8ګn̴&3SBkbhz;C΢6݉Ĭ]@BhlCo墳Wԕ ϼL~XhlEnWYnu@DolMV5>T4E T'nw@NPM;цA}"f/oSSٸZ[9eΓR7sg arǶJ~s,246֘;d~h¤Z3ȝ:%5×zTЪ#eEFf-u8_ޯHYai昒egxr( "ВE.-ňTI4Z[}rf1ofv IܚHշ--9K C >V W)mu}eEJ[֥LaޝZt|=qG]ÄFFǒҡώ%J/w5<s vi' '\.D%6m S~; g.vϏxHk-kGrÞA%TNlU7ACog-l9k_ד 0AKp-Cp{Ù35}TUwUwJ}ŷYY3RI0Gg؂uRs`J+Oj| ܇IwOw$_;ǙcŘ.f-rng ›fu/Xuw }& La:[UYbH O q$>pHTNVpdỏ0Co+ZڛæQd nV=*D\8n|Q##lSr 8EaRA!}ԠC׶i6a6wWcelSWf[ irrA`a# 6`68H5bu Q)m۽5µQ&Ij,l9f#\V*)Ŏӥ6˾c1Z rzSq8n:6e> 5}l*=he}k*#mbo$Jsvaulǫ*!"W.$/Z޳JY^gk"\vO7BwK37&DieX1 js]2r=ߧ)|ϬF)ͼF};r#e-l M ftg"")1 ˇ} 7!>ӊY U.ٗtӣ y:,lxT0rny8y%N4JS#aU[]7YS^loSਔ yaO#3pݢA^)>a~*$(b}8q" UI;҈>Y@=rۄ/&Ύ-x$6ӧo70ZA M2qkٻ3-H'ʄJVjluMC2׽ +; *8Yd(0?G2^&e1tAzRh!jUA3ZI|],/i QȘcbEAK={Ȧu?PH}N+YuT2c{yt2ƍT#+-jXmܾӽt%  U; Ɓ|F{^Y۪,/H*9)C6rQV7_ðN5P2|6w:q?ȋrw$*￸Db-Um3Nz{Lo2+ط+ =;"ܻyVY&@KBtr`n}>) k\/\!Edb_*' )лxF)MZ:/w/޹, vGu)S>^@HB-Iwp_BvlK=TRY: /RICՇէ 6΀ _.ҋ8?U?d_vJ=7GIqʕϾUK| 15#<* Ԥ2Hkt)Ѷ57ًq]!05S qkB-xMeمg:1Q}-V^T ~R? ܆;}^O:^<;c5[ WGL>қ mPgLl2=Y͔Nj#}j[Ӆgܮ@˕>'!(Up&X$u{ {StllaE4_wbCC]c2w Bo_1-ܿ8="6lGiLgs@< &lオq[v哶OÂiΡ*٧_fIe8]LkˣrfN >kk0&u(U.2jTߋI}yKm4;pZjqRH?mcG~TZa=13a]Lj%&Dr`(ayom+T^lfFmb3R)ϥ&OW=+K,3w)ִDZ܈q)0LeC0T6ͳYzz켭N^}}M,_9c'nko-ѠP>u4ZYȪf+}ja;mƛ|S-qo! AKhT-"aϞe{\)^|8lLl:qw^| nEp;Ҹ}+~-:-1 z# p7wR5xě3U*!$9bQ>3#|>Q3]==ݿdA@ OY UU"C*w~tO0藈f3q}rĴ ÌTJK pz/?XJ.]6[tFOIafl6rTIj;)˄U&~(ӹcۡșt њ8Бjaq]9vdpQK>0_cT6-EmH|N  >[tHt5.]e=rLoJT* ʣK؝*VHHKϖ3bf lWodc'W 5s'%WgKF_}VڔeI9 ykȃկߪ=XuUoxj0x/`^*hd_f#JNS-s5쓮oC7,r\\jDWQ/!=]Ci\-2 % NIcUUeagT+$jPflp;Q:qA/ennqނρY2hn6:f,+H߅GLjnp+ tmVLӥɪt㢳ǹ0v;S]k?6НNMx'Lo ^Hn\7G} 䗖 zNRDA=v_yA@~u«.9(U;Ak#y{Ӯ'ѫSEU,9Ԧl=@4{)Qxg2Mɷ,|04F$" Q5UkPJm!z̧w}կ|xcvvli|4~&sX%VcTst3jze@}nk?Lݿ⋯Q,=왶;:?+lݶ65@;LŷڽծݗR3I]+_8X̎Kkn?0qp=Q+6K}E>F>- ASMGT&uN6!]xi~LߚnEc2[29Z/  ʾVvjD"l־$vugPϡ+H=e3PK?:BL_Im;w-l'qG!8uAXekk5Cl-xTSB[|HLp[E Z=Mq9ۢtC;psS!l\MBW^" ׽Żu5w$`«NdRgNXM$dYm|x~v UH2ˊR8>H=UsJärq,&^`R[/gY@kϡo4VfC}$R4K?"_ aX6Q!^_7`dAGZRl P3uqewiJ܂IcAb iypD$\:k1[Xk_Ncbvz+:,F7{pQh~G0#7*bŝ4?SJzvz΅To&<?!Y3M (}*  ^l{WYy_CK#Bb={}lm폤ut#+xGq=m]8=USƌza753DSW"smsCWȇL!nKԳpgrkKtGT޶{ޑ9o0Jaq{e% \ps/PDf' ƽq#3'-7@mVwZ*of[&$!* C^Gg%EUNG_%ᛋ t-quk|ccq4DŽ~ f<Á RI.^K#V8(5vG'm+u*?n(AnJ?K'%$A4I.Dq'e ,pDARZIr-^{9l Vu.kSEHMm Gk(Z0q퓜G$恲7|cha4l;k#|>5pt P|1DOh8v9YJV-O~m$>bs\*Bhd7wourӊ@!6Y3BI|[YLuȔбAdUK zEVryoDCG?ĺoNOSo$7sh~0Ci,g`dEYc]ͷۋ$hü,-=DWL\2sc\Sw>ϰ'?s`Gqgd8VZ֮P&肾GUWuY3\Pۗ3W3^`I{ ΓM+#؜L9q#?s_^oom94Ι,#rA-GQ@^У|s YGZ6O`?#7BqQ$GJWyVk8P¼S@}^K0;-8[@Sw_bp%)A&, %nK| ?9^HYy"wZ35 ./^>̀Ұq,4f9? (1|x6O2>!Fg-<.?!́*122t;s'|, X-SPG`ȹK>?Ck+K@->0Y4P1z`^&ߔ'%/ފ}85p&OظIt(XHMdcU`d CV[,\-/](PHoK:ȺO3q=qi%mJ}\0>ߍpiz϶ 9G`2 W{VpMliK X?l鳅u<\n݂7܀qݾ^ BH.f=n,^7s2 5bj=di$pX#=PYA~Q>s) _GG T5Qn/UVHG~MSg dʍrL^hr&90ΐg7V{:NZ^x{AX@D4:W^?>p^Z$Tfl V)b(GEW1c U*Ü0Iq[qNE$X-0aZ>42}Տf;W=e^+ǵeS!mo4c{~AAFNNkW'7*.scٍwXk6ZmG0acHgndL`* m)֠}Y>tGT[?޻ epVn1v޸bP`H-]W GJ} Mз2b˜d}rj_DnKfɑ}zJgTe_OB^HGRצt f 7%)|k"LևY\)GS&yeyg~ =v%\V?B;F,W122߻Dzj%0(O~YHaE9  tiJ(HnPW:j3l#gq~6NV# ~2-Jܪqm32ʗfnǧ>Ү}jGِa.{duyn?q_=]REAvهhˢdǞs;hpG]%p`^1F ui8Op5+#;eժQ'^8!TRF]G"[>3 rN̏ Tnuf7YENx [Β&:5avê)hC8ؔހ9)צ3uHj3U1c4vU)v.87 okXp]O~3oP4?#{J@9Ԣj^xhq0h,0 "`MISqF/Ar߲G7`)gcTuҡg86r1 +.g \}3}hM+r1K%VNC P@ze463w3Y0;NjPaWc2p.ZtJ\Yܽe3JғTCd$MT8S)WV.T:acSQOh8F0YGzڧ_" 56T5ڧ)HΖCs+P{H:AȝR JNiVUc96l50!фw5}OoFq'QT:\#P=!<O"6ZBqs6P^poҵ"Vc#ξpCpOI@У A0 cGO 1zu:sT%P|_h pq @|n!Z8?{iȌ:@@. z賴4pcGo$6qwqu =~*&w^ f3f{q֧dݾAK bmݲmfBzH,ZX'/&~JƆ硊N4pc_YΦY5n1? a}׵jV9I?Q84q*w7h{'!25O%y]Ѐg1@3@aZ!"~H*,h(> -+/k@pz{ 6{,lV}oDf w1m Pk)b ~{><]_JgLgV?*P稛1lVttD}^=lplε~UW&1+xjuOq 6T9dF*=5qp* r:s}쓹3c#^%eO\ƣ͆{۩d*M,78Bِ\" ~7NbX{3 h\"siUL=9k|vg5W4:dA -d1MTe4w[Ĥ8?V&% -=rFEK]s_݀t\aA3' 8 b0 V{=| O!1< "X9郡_y Hxڀ"(mgGzPJ🋛ڱdͪW ;mL&n3os @`}y'fM+l1)K+!|TE&i! ЌMFJB@{J։g~~3Q3ZkzBpp/"PC3J%n_$d&<ms*$*p{Iyk/䅷f!3B<ٲ ѯLP2P[S(>gt-rIQ-T|ץJY~R4ѱw*ܑ K'JPWei+9@= 館)$%`") y!~?'/P>;EcLБQN P`i'`*Fdo*xbMv !k*sSPCQ` &_F yWTke)k ;܌6n^Rmn:E?yK%GV9On<QJ(Jû_ϯ{ڠ6#xiy6'S6wI: 3~j cwGy[4K edvc4q P"ڣT@g1KPOpGnaMS{S nBnY ڨwgMgnvjA:YJqeH%u"aS?i#ߠXa!@s#Wٷ;8NyޚxV毵H hհ~m${-'󨥬u c1h"k.`RE(N^.Y o XQB' ƨo魙yv aZ|k {^P#fܜ-z:GV{Zt3{ CPEj}Ĉ*gVxGFe# B+/g@7"HJb($0L 7=B%V;_2G \7:ggPW/# ~-gv--4tL665mk/xlouYZ0QS584_];^?q89u84x:R=1<53y08~09v<=8]x720vqz~{qѽwtp}r{wpxrvusvz~yp}y}{uyxxgTX#/_:>ׁ15A==5 =?;_A ? ARb`2S3/oA08ࢦO@(ߐudlT '£ E(s?##_9C11S-9ւ:7lxQe 7@(\wM$[aϤ@#nv}FV6zboOy9V-cw *¶i~/6> X4SI>. Gʌԩ[t ^YK]yۻs.ӷI:+B pܚz},E8R^_?5&iL+r)(VVj"?&y(Ā/̟Me];{ E, swc̦8䂏:k?(lL9D]>/ B%i)ffa:OөBOTH 6Tjߢ ?E!Ÿ">;*[EAE̢&&"&Č1#bDP1`sƜsDQ #fL`DQ1'~ϮF33s;giTڵó 8hPaA#=9mȰ?OKc VTMUl$GT7TnKf=zIF WM#p`Ji?*?%là掮ʩVi(J7̹Lu^BPjoN5ʓ ܞ`9njBNh\h_\x /-tDX} v 'qnRrT9!1/FXRI~}U_A=CQד8wJCİZ L-bp2 I. 404inIEA$!@pr,2J*P0!F k: lZ#RȅoX7< 3KвBUܤ4XkZ/֚V*tX x5 ln}n}ωO寜SOɟ/fݜ:m;Jz̬cVM_dyq[q]l_/tY2;[U.Vd{g~'sQK\’9mgW75䛮g<0і&g- pdx|O]W&:ug*jEPwF2}K62ߑ6Qf0y[;CO\.pȡM~<E~ o`fOp3j6=2oZ%jv՘RxOFA<sk|2n.V}睇86XAu nU_p#OmR9jnh;:bڧ7fRn/ ]Yv۔/ \_j" ,}w1\Ճo界U$_Yˬk7Բm_}z>ISU=㷇nVVgG|*iӼOK*7r>#%ˏmh)z-YT[KO/R Cb1#*ÊB=XmLJeZ5߱DܔϹc,K)^kXl,˽=$wZZ/!m^_ge۝_m긱e?i,s -n~fDGUq"LN n}z&jIIBg 2c+3.q ~XR'c~=U﯋NݹqSwtxtᖏNxYpO"F,rF ;Ϟz[5 r} U^F5,1\]}.,2?_ĩiѴoviUӬ>Ѫ&n eɨ=g~>oܘ;uZuXs]>t^̀2v;nY&#'yH^rǛl'Sԋx{%mwUiN _|$IuOsz`&S'~Uۅ /(7rGx>G>GzwLyÀxb̷Olo X꺤ī=j~i2-]ͬbPﲵV.]8ku̽ݝnᓻɫ%g?yfvGVN1]Z'~r:-fCa?e[ \.j^95zWnzNKOY|-Y}3|`%5_27zO}}:V-5+_ԇ&Sw^|!kZ`<êal/M/]ڵʒ|sgݸ2M,zXu>rl|[@18Њ#g>ۺ{ YyA#'ч˽jK![E.2ۢnkIqjšwڶ: .TZ\m"ͬ(A]S'9^ݙ1N'tLs[+Z%' WuKVK*XQi]5ׇvT䂏Oe[_0|mZ{shCO-yD/ٷ9Xv]UC?8]7o;[:v~CQX7*—e\9Q7ܳn<#b _45 񙯯n1U'͸{nFw-}Ɉ$[)nf_J6:RjOl6Ry6*X[4bz/GWu[}Z玼v7a7|Pn jwThÂc7\~l&ɣΎq yWm$Ţ'oN˜sDݔW7-X'k󉝁/vbѦ?i֢a1UW^]x1K-mIٚYYWnpݷ>(m)lXSeX}:_8-¹VGCٹ}{6S;zdMFSe}{Yuцқj)5:ˏVsI[Za%T#қj.F5GˎZˎdn柌L d)d)dꂻY?YWG៌t dd9dE{2''''''+'{2`{'D? 2b ]៌0_w!E?Y?Y?Y?AbhrUu\៌͗[ nպT͡@]Uo'3}UjN9u]LO TqCZI%Iœ*%nrhJ.E~W;3(M['&BTu@XHcT-B7JuʕƋKXM# h` MH*FIABL V0iHJ%>LQB*TpHIJ$5emYXJ  `_ ;P 4U"y*'E]EzR#:s)<ێĎ&jRJ)b5))uXdZŊL&Yy@GLB,WtK/m!Œ@* V9ʑx9T=T7J&u ȗT}P_yX0^K,]E%U92UcP3Z}L0R%F O H›~z֣B%DSL<4\Jien(xrbQ DՃ(IبQTܫ0l+YTQ(.5iTW(QR䪩4S捋UzƍUIaN"Iڥ9U'. f2 &L!#wx3bdHHH?F ̈ Ir(7L Ty> GF-, Ti[b]9v% O fAQy};bJb nPe7Q&7~UZ}2̓c5ίiHHy~̀y0#R@@ck9cJ*㗡BF+^us8e RmY"BbaO%paKȥ3!R YVDT02JAppemn шKrSb!Ta`ߨU2FbR0*bi0JȨ K*7XޢUfM cŅc$dذU{RY4K }YI[#ÖXI`arĂk t)P,R"5J$dr F MkbkW\󰼧 RSК T\@'i7Rv#/ *DzVQ{ KH Qѣ%58NHq.Z &=l' .w= ==qckvoX@qGޱW~7ܹݎ_?[*cVG Ξ{;ba5nQc._';"u֍:~8Ck@Gw߲mzLZ4}cԓv K.h ߴk/:iE>/;Gd*Ow_iJ7ӫl޾HLO4ثbL-!kF~ҸZn8'~5KX0_T»I&|/@cV-7˅mN:G_HUԿîbVv+p_Ti(V|X^?~qf}/:ZXwksهV׷_7Dž5yD+iK~vtګ_ƥOZA~Nm%+Eݪo?x"j:.؞Jk&/wyQi_SάYX>`)skmӯH {;nrHvQh;UYUn7v;YAs+yg鸅mYXhKuf6> |І3\;Ixr_Fk֬v=#Shq[fNHك,׶uA{Tml{Olw-?dS6{5 =l.[ W͞bSWܨE_-S@DS>wϩc u i6GňI aR{m'e6Z)R5~mOy;`VoS5VF&v^1jƊ]Q<&{]õ_nxZ/RV:|׻ IخT] $w1e/3ǾxXg@_,;$L%ݖyǫLp~h.-U'[zJEڻ-ص﷛7n`|Rg}jƏ&(jX~z|i뽺G?x!fEf~S7ckb,cFotVVMYPCd;Jsi7_4(_ۥǟ=[q㊧u^cZGZLm{¼U}vҗUk&H\~GNj%ſ(Y^*ef3a}&޶' Rlyqc53)}*S) [&oطbeBz+N]f֟n{m`?4~X"A Li2^͙vP'Y>u-p؏]EWgBJ?kVʾȨM w\-7-Qͣz\TKS }-_G-f\ѬqךWXuta斖74<گ嘥|[ܟxgؠu]rJށk|v9o^ѲM;{5i폗Ϳhpmaz)]Ş['׾i>}.Y[W{\t3hls|:(mqr7Vm|,CJq9g_"v>-;yen=\v,pNd˫K۴nE˥"Ua^y._czS>};u{XޑZT̬vsm?xW61޻ۦBextXX𲠦Qw~oYPqVG!Mll8v>_zi[гRφDvqʦx;p lccCJ%͜4v'zKY.cSGٔ/a*$3V#Шyvvun۾i|/hWzeZkg}vNE˦GĿ*".u%$YFQ[k&}CLZEtz{'gެ\}^{lҚW&/2(ߔ 8ng+|⟌ dWwANwK% [|# Kӗ% I0${Ï:{'3ӗ6wjN_ |x?|հ 5}% -W#x=N_ +_N_ ;}5|&-WwjXʔwjN_*p;}5|=,mȏcY ӷ575taXP‰R*'*+jdO tү1+uc{GsScPekQXw|?G*;a,KdAT(Q"wh`!ë T!0?jt*>I*4jy3bG Ej~U;UXSOb:/1.Z,S͇LѧORW5؆"V,%б݂2PSMOGKgۛXIDE,{$Jo7يm3ThS2Pf;XPY{oPUUXzE"V,*N<ҬуeH*rJBt%ҾC f bP9& VfjΑ JyKgMTpZz,Q!!h = J]kQCL-F%pP1KIsXz]P \q<ێFBkbX,W7CEQXzDMw `E|G $}u) Y 5h8uU-43\ DTԗX 뜵ɱ+/åыvXtXΜ~)}^Zr~ל-G `yƋ2Ub ]|R-cp੿P J]?&$"fhX IJ-I I:B,A6Y2Cxjrb's)C ߣEmjh+ m. b)@RY+.h*@-6~!"K-`W ?ԑу3J@6ĐXn+qR`#r&BbSB©dC EDba#3"g~ff Ew0$IF4h3apO%~$>CRf5ׅ <pK1Xdž\CXp `:`=\q8 h;4iRjU.vЇUZAہCG;"9-!n ՚N"S e_J'hZ* dTސXxTG0r$Q"T!2% #  4 !?!qQ'z э(mW0[3zHtԃ>~$ BE>~!RD&ԐXitEL4{d2 yjE$\:5#G)Krem}Qyek-jxuwX]X(\sĢ;OXviV+q+"#Feㅊ\0qbQ8G,t,`Ǩ&f9b p -LYG2*FJTl ;;HcP~~B8Z<2I2`|@̓~}KE?T9`Qh Q,,0>Qc m 3Q* v NUsB>7Z `$⫨ N IA#4j@MbF>(l5TGH;"('QM"1)b %'V*sB3x7b)0n%941eBS:=Ԉx} ݉-$k,@md=Yjo{0 sK(5B(_6lC@`Q4jthw{ 0(OOŪqÇCOJVh 5(ku \@J$H@PaTl)HrQB>2E׬V?VixbS@u|D5`UZ24X&xTH!lHt6 (__gi  ]t.'()6T6Xx ϱlI b=ǴqrcCe|0/*'PxSIHPliVȚ ` CXPFS*%؈ oH,RDD@eĂi%)` X,n!TJ7ь֡Z`k4YF & _6N_.R5DE8oaC:Z>F/EL0@30XS*kx~ΔDӐE+kxC FfN;f1H\#S8~)ah®@*Y%pݨdV,~ZR$9ȐDGx )taOb5 A=/`B%&X(E 8~emab"4xҹBG1;"imҴ@7d-s"GHyCRhH= #~`#G,F8Xw.DK<> <@*Y\*Q 5'fQCa~~g5 1P6:4*7H_WJKt_cJR:1G,U rGOKTSǒ3;E@<6I9 X?XYt|@ rݹb$F!>e7` !2:Q(@dOg/(Ѐ}gb a|vT$T&^<ZXԊ2*G<N}Ge!%anzqb79/J?&Ap6b)-SZ1b(QBR鏖)mL9nt,SZ9Rm!Be@Mjep RPB27 jp*-`dU@)]D!J,9bC-bABR\] VU`SZ)էF)G,,Dh)4`JW+N†M`h)+hu 䙒HPmXF˔Te;{8^9UeֺQLHe*nYqB :4-g>7"kMZ ,vJ>Ҷ}JZ-22(}mK9,aɅ4*5xݺWMF!J߄<7~Nɑ3ox[:so[mKI?m϶3j>*AjSa=2zk-z,R[M\D+m-bai]0ҨAv,/|"A ,[)|ʮx{3zWuQsVuK7> +Itkgֻ9Á q5[U7+P-:+(+^d[6;ts>wݶ9v;^ܗթg_n+YgB+˞RBzO9D50><󇤇-.zALz iڪnȰtzBRgC aw><{P\'Zt^kK-S'MY=S,S+yf5{zeuϲi'2upL1.Em'k=7aG!y曰$Ǧl,qs cS\EG6ŅgO)~P .MV{B{~t[YEX?VX8M}NڑU+꼨Єyǯ'Mi1O!lxE|JEW ̪_mrw{GU~j{0Oeb;D]]j]jc0^V5El̻fC7UZS}k'9\4zsc’E-nj\U"VZmUnwSc:h7Vz/?ƾ;fw]+-/egR<>.MKJ?Ww495hE]ig >޶4cbd˯pO fYYN*A;eܴ{ nlI֕W*ږM1bSFm;\_dHY]P ;ŧזޑ3V6/S;W{+<1mOtŋv3ZKvMKr>$ U_^ӗu%" G:Lle~M| SԱ{oszhB(|N.-El9t_IO/fGɝ 1NQsuK/o|S.'+G):%v}b\gڄYߦuê*Kw;lN#VuTJa]nVd<]Szա]?6ƽ|i_}.ɝR^='TJ̘+̃gf[Ыٹ+a{UaE?yUg'g$]ݤl_Bٍ7lT溂-g[.wx2kF Xywgڼ 7je]nNH+Oo:a[D;_oij'q2-ZOo:aZ7^d(]Tv}Ū)l"}ڹ6YPH*k >e3g*ji{ھמ_/q6xˆM;9Y+ޟ71}xS#*qԚQq!:m9F]m]Ӟdf!9捱]H|wf^} mptts=}Pn =3ٻۿoAk |}۶;ZBmW]۵#q4뢽vǫϾ=4Sf{}_'.}pё0ax1²fsyʩWN?c{uom_쳗x;eY׋veeӉ=~׌ ?#<:Li㷹?%9z>^k?tJpԆ|;ֻ{pJA VεNO\x0KGF4Ϸ;>|Uv[v\QA_ ߿<3E==ʙME oNmʂ.uV70u˻zؑ2#htn rHPɀIn}bpUၷc+#.{:t3"ETYd_ˉ 쯍-}oԍemЙ IoZ-,ZnYa_ڪ|sˠ#>S*3kli˓ƾ{pǁI-O^|Tƺ|tb9Ii7Uo7 h}뿲떗;7sk,ƵAx;u&/d^=Z eip?# sꌀS3uox*\-Op)BڔcC`WZ0Q d WS3wOE:Jw2JuOf d WSuDd7Y}pGYK2Oe*Op}@ ddgW'TPԉSjnf[2OehN?<¥TTJ]Gf~44#^f W tOK] e>* ?u7OpI7{?)[>efev2+  W ,ˮOV}2Kֱ{'/rH:*\o' '3pOn4S>Bztt>VPn\C-R ([hZp L|yIe`ń˄C0FIG¦ՃsrF[$RrY ŷQ ؝ xy3nZ= T-bxZذ7@У̼BI4i!6"(͐Xd4DVV",H6O(Z,Q$AA$"AQJh!h{;Zy.,j22lB{ IEHmipN aB{ Sl<S3ZR,G.ULdeȱ"/P䴊RbEW_-j=oU YM*[,V,t`rBtp7StRo`E&F b ]׾F~ n8A#@;tNA6[pK@,yMFp ĂPZHPxNYU% k=Z-wY}M$YB1]ӐX&Xwr@ӾFΟ ^?[k 10Q߽F5I+1;h#R# uG(i*wM_YBXR&;|Š 'Z fZRIQ/'Y]A+Ԍ@DK%8AsM/DvX,$vI 7׀X; 542DHk29, RB Dw!B-uGbntX&8qΕt˄'H@4oEc& 3p=bR8Jz6L!B*C-k`{aF1O$ǥn.Dl԰|{8%AE?adbIWTh&>{p~c+)!('W%vVzI{,.R, ljbH*S|x)J 2XWPHN 6f \8vF@v}-7j:HwH8%/ ̖IFxUu P@ XySHP>D]+ĨV),CttxH5h! UxSH핎ŢXCOX')%ZViPBen sR$`o KPoR-ZD+mH*Sxqy7o,mH,lMGMxt yP493bXBiXAuV]Q"E-aUi}j r Q@;.EJDXUf<Vi$RU3 eBV7Ë}xB2}@@j!# @u`DO"|Y h#x@x,~h?Q"+әbiJعKV=XȐ—>M #RRxxq* hȈ+K?ŐT&xw 7B4?*2*,M8 (PE bQ1r2 ?t,cC$YFfhMb±l1XB|RgDLb1C5|F$'Q82 'r04SJΈQDF ehLYS9 Q)0aG-eHcEgEr5TCes۫j C< HS\EY,+ (glTpA$jj hx_* `4&xVq%@U1O|)+7@B$!*"x&Wj# #< eje9T I5;$bl76Ҹ& Z+Us!*p,wpJ](=4 nnat@Fk`3+ex@Eh*M%kT= =\TܝB 60bW!lei;B mR1=ȓ¦0t@d!r*XL3 Ti)(j20}I4SȤB!L1PUgFmZ.Y& A,32 oZk| f@Lc,ȑYզQ2pM"_A9AwlP*}!vU1 EidO`0V%%GGP ؄e5`tm6Xp䩅MX;(Lj-q5( 6:[ns,Z,: ζ@ƉaHa|AZk sF>*՞^Y{Vvp >[!*8(*P`TS98#"/s珪Nj;$2 Ghb&D,``\y'v<4(.?i )<`fe'k9T +;)D=6e|@SWu'bb  ((D A! w!Ș 'y:2&"}ƄslLb`Md$6#`(Jc vt7gm?z,U*ζ/O/˲|?yYRgFShֹic;X,` 3+)\U><٧ڤ<;>9ywߡf*mX+6gIo|^K&k߭_ԗَ2jR)#qm]w-;no-5&S߻Vwܾ9(obo t uornڭN2`dI#k-뿪ONogLw+#;uYUԒf'|מn<;׃W9?w Yu>g1Fjlfp1MÁ;+g|yNKֶf~][tXx1EV×+ʇU{]gƵ;eٍqsGonEqk~%&V>JkUmE{=lV(eg{YVY[WzuVl٥ wakrͰ1]2YMlRz:,kf}1jnhgЉ-,6 qOR\cS̱p s Xy}MW&'[f׭>Oyq%==۟z:YjSg#}> 3|t~wt:ݜ-#Δ#銎o~Dﺏ{'.v2SbW'sґT?YGR+Y+}Λ[ ] w#@d-H*@ݷ'3X&2IO֑T /W'= I>⟬#rt*ҋV[2pk\tFj|8rЏ+r>Oѕ!b@X=1:@0$ ./åa A<4  ?˒ܮ@N dEl>bI LyT ©$&'Iv'Q{ h͈V-LV .8a<ǞThck3_eh A# WXjRCW)T`IV@[>Nrq;ZZtR '7Qyb Zzy eBZʟ x3J!(oLϙ5LPF!hW􊸺^S |#ed_hH!R.ȀHM4yH$h+SeZ?1Z(VdNc T=8-&2C,`p/2~IPmQ(, P k$UY|x%?9TJ [6&HID ee1r D" e&;e,( _G;g&pQ yrv<4 #=sP`iH*xdQilWnR?= KTWR@/GdHI 17m^ roXx͒-a,zbf) Ŏ=J7n=ZR|Lq7@*+!},sM,5dIvgC$+dMM$1 6DЄL4D)X6 AL& )yR3b}!2ÖʑQ14t$PX܀n`/AD(ݡTҏ+ѐX&y9*FT 5?KN^+i{X:z4쳢kr!)5$EK55>KMOmSJaY{]L+`O4`!w-bXy] xFAiH@<ӸЮ-+toЉti AAl~ 5|'H_4oM(4S_#^I>'Hſ?FO |/7`5h9<;g*vCqrXκB(t~^r?UUPL zP;a7L% |W>j~6}FpkVƠ`{6@cQ P;@zUq!REJP]CR5C<~RR?U _UF;D7+L> L{/YU᧩a%a 3%$ƈwÉprϹ'r=Ɵ_4}8>#u `}cWo讲]M #Pf{'ts:Aln DUjc^Th@yp})#8C8O94'{ǨbbD?ZT \QtHws;] JwbT!e2!Yn)|U9R褅{-`>L|bP#{rB"ifgP:D|V4AMkh150Y4:)1scU#͍=͜ǮLAg#ͅ]wtB}MO^uBgf 1А󉕎4 -Sh:@:AU.¿{5B^Ee}b_?JQ"t&*}~_0ȝS{B]k`rpoD[7.39 ?1rLNrxJ᧣5a;ש<,9]#6P|s_r%Z .}{Ei{6F*xM-{2_#F$ܷtיsW_FK.9$$uLgxfaI 3[g{E>֟؜0M = ?ptx/rwsXg=$w9wM6dj\1 jh1;iњ Y!x`&KPUE 8&v#5Kg x0A5>B*{˽qd{=/b簱O+ɳ>wNj@Ù]oo>׌Ū&;N}{Γ|U]@1%XKS5vm[ϵqʿ73:^elkoW܁Δcn.S^X 翬yK=-,,d;Qqʕ5[령b|_5\]\emlgCX}$8͏{7W3;,˳ʎc- U_t/SjeԨ"J.1|ďM?j}t\B͇>Ŭl]f_V(\U<ET4;3fU~6T#5^jz:|vϛQ2 mN!ɯ춟V?>s Q~V <#ʞX>>oy(N=u:^)šk;| ^gUǧzni"77<;eWN#ڬ]ˍMwDX=w~G!Wϭ{2[d|=_mD,Vo[~yGu/үf3m:~wZuٕkܙ[Bfjv-vڥ5לi6Θ_Rnnv璵ٗn9=OS5'̐蚷Wq%}i{2evs-^؞qboR%'eͻQKլӌSo%ߒ:rϳ7[m۶=L2&TJ;;߳pCV{&ʽfÓ3`z9`ꡅou}bm8h[v4 GG: qO})ϫh0 ̝uə^YԤE~dDDp6 Slm`[m巘Vw  k(ȐXAu!f\Ѿym8E· Om`w` hʹHؑ&^SY{W⤵ul/s?٦EFתßm%:{N b:7XRӞr, ?~#V{VGk*UjkDqqԫWiHVv3&~Lc C]8:79])2ϣ[-fxz+f<3sk 7kA.0/(e!M-9CӼj,z|M07F$ ^^A/2Zkæ娞AǪ!ˍȫ7~/CXCst}Sh1c&ѭ7d83Ut)j/^lY(A5e'CTl7v ?kLj_'\f#d5iT7ة$AǨmv+d{@u-TA5EyLeIpйǃOGZJҟ8 ]sl=l` `J|'ymeuˉˬ%s׉-~6wS'f&wm!^WPTRvҟ2#8\64g:.W#D.jWȎ;R:Ы- y}PS0g}e^'eĺժ ^*gOXI7Y>b|g~dFcyk],̿0g~[RoSd{#5+p]_IRت02_M/( OfX B" -J󬏐_ROK$TS{l Yvml>iW$x3$zYjbz^h'jFGWaP<)RGDE-5}V6h8B5zlAhpU5n$SɸmcP!u[)v?}اrr͈S%28E,H;[6f+ -mLScq `Z[2f\I8WD :  (Ӓ!hNFfi8Zi:iA2FHtt'vl3U[j[E#8gD&B&a 񙴮kxfF0<[t1NU]ݳm凮#1`hPI ^tKg&wZN,lյd&Zvmq#V!LJum-o]kɥX,'aGEd'1sb6u6tYz*?fdXP*>"g[i k/3~N/He7{AIYzM@-|=}c#U)>㈦^˝JbXb٬RcC 18vԠ})*-NJԍyi iS$"#BeڶsʂitؘjL͵{k: ׵M-hk{<}&Fd(kĺ6iƛ INԯ_?nCwoںj#B0&-SBz3ւy;%Xg)ȬP^Sq G7%\Al+΢zt4p}ꩣ]=-4ywVq*:4QJgh^5:qFB]4:R8A pQ-> >Kp1nqpeKKVKeX(3fWԶ< ^Cj%_e#/WZ eCmk;4(GuMlgsYrPbQa^\Or,2X>hs_j$b$t%7_`7Ia]6"1>ob@^ߺi}F>*-)`"H;ʋPR`"]Sko&M'uhJl2EBr^YTçbk̓>o6l< A9L9 W-%ti4I%so/{mRhh {"I3iIV>dUoINs2&)5uDLJ VUg44M:%#Nn:jjO*-lzx%anKih"h8 vh(gH R"ѫ'Lµ;"<%S՘=mDNuaiet|λJ%L) k7e%/ᖶAߪy$,K'KWV籠>RHM|/Ԛ(1Ѫ}\l:kaC^DV1J,q>)RsEeT(er߆J@_>n[鸤 9ezߧ@yZ&cU>\UlW ̌|E!3zGXtΙTř22ݖ:sZsN3F rvW3>2 J#ͭeY¶4~|f1.CTY4mǴ3KG~#e|6t#d0%h 6*-lޣs/3^t%Q!r1DrC+8':-d&i [MgW\B[XhXP%5%oVEeߺP6caQ>ƥD#)k˪ryw>t| kn4-I7(3d "{-8yaírvT 5kij $7M`fP䝢=c}]Z]+ީ*[ܤ{#T N&wC3k@փ{'׃LD64ω功ESvL٨`POqQ!NI:֊0/o/=t{Jyo̷ ea]z}lx@ 4u6X0Ǫ <#䌣q5H1y-ϩ5'G^wr ~dHqK0--pzj kId@zA/~ F!o rؽs1z>[ړZ]6;qa{W)5ˌu Y;t]>.v.cB;\MDh;{Pyt1҃)b<{_BT%9M^UyC: {>X>Ny!߈AIJ*.'6Y@y˚) %O6n+4$F+$yMjXh$gy{m4Mk!Wjoj˶KAx/5Wo߫}x4VtGy pL`8Ddg [EV+L5 `Z?Y[`y@c8Wb퉝\[\Eve=NIm;i נ|ޛLYud/{3o!kW03O҉&\ɥdтx3$꯫]/ ^n./P%6%TaL3l(t4h¦ӄ\}33n^m)͔G"H8Q6@"v"2#j[;>|YR5Y̓x9 1-e<0G^&(VdDZ^;t~~Ft6GiА&J|Oͨ$BFW,%DAO8@f1z Cc@[ZA}:˽>eO,BeDk+78YLa6ٽ"E4$Qd@ʊ-32oiKl3i䤕<軹Δf"-dٺey$]D+رH*#{{G5JMfư|#ׅpw5BV#ob~w#NθM[}6-c𛹵WqR^ R +WWd x"@)Ɖ}mkfW7d0>.PCqi<5bm ?ǜ?!`+7ŽF@TLVjRowBxIKOFjP j\>ETe X0W5&I'Tʿ{-*ڄVS=. esYSԻwm\-=*J-TE)ҥ)YʐI2:dIM@=B"H bV#(aj2kys"m5 Џ9󭲉*YP'I BqSJIߋ}0"JStoh'rԾ4O!M' tNUf#!M)a:svVb&M#1{O0in-aզ!W?԰-丿^ZzyLq3E,h X@)^G<* ZD}=+8B=#;iMɈ!у$nm4QH诼ySEy7ӿRQkt\3Jwmަgq6a5Lh$OWzK uqTf !p*$ѹ@C;U.6\ %D10"Iś_Q(oM_c!l[6olyW\rtDnjjK2}qHεqTz>Ed&ņdϷ'jnZIRuMs/rI[ Z$F֪yDy ߶n,@pl̝_cTJLLhC({&iST2ݬ"&1 k+e8r)_턟fohرfjGn,O&!1cqT%V4wj#_2W%|,L+=SYih7쾰{fx(8PZWol]貓DN6?uW b#8W_#\Lw ʹ֌V6+MYT=ŨUGokX>p!|^jniZNJé8n%]MˡalS&C:*" r9H9!oF$vb]h^T Ͱ!2iw8c 9W70U {: [R&-u*VYb 52P;|%Fo L_d7OlpV#.2.?ފY=;e*т1ɥfȣglu ec8C%H ;/\P/FԽ\ЎMNPz[dDkS^6GuMuʬHgyg 1I2Os՞=̏[һhfKD`S0BdJPeA{4_i_~V|ݲ?-mmVYCmRJ1D^?ë.qV` pL!4Fixbij8Š(}ͺukp sj*Ȟ{ wNv׳c4J2hm-F1Mo- ϰ$Rtm ͗MҊ Kw1+n®ijEe8}#^8>4{Z)7X<C^]q|0W,d4WBCk U 3cq/hu qMbmÄ4u3גG B61fMpfwȴF1]fN}jCzGw:nV&_dpߖ'N{4Rm|޳UG0WKZ7 m@`b+T Āp)_MAXٛ}lJzM}y1~p r9 gB/SQLB.V8l`ryuȨ%t4R&ጺAY<\Ԅ' -G[!9A. jc /X:vbmfV*ZAA6gHGHUʄlP,a4ȝr0澉o');w}rAoY5 >.=3W"M|IiHtWU ]\[C稄 Cڃ7g>k0`?AUpu'{~g$Q=;Y}ܙ#P vѕ@V81O4.\vk:&+[W FRpX\t=T({Kd@*5<y22ަnDxd&C}p(fEu ڑ_alxIPk螊V8~1 &esgFuY3`v \*R*\r4dޖƦzsՈn0F|MVvPB{Ahn̷W 7p"M6)1$O!b?==ƫ"xL;.WVRLH74` vsCNH\EHW6_VZ \n=P[Mp!78ͬxlq_` M(FT6I4>)Hci 'b*SX`EV2oW?hrfaz=RPw3'W#H0P CRd~|X #W䮺Xc#j)тGNo`jʳ V,8x^=ePw Px):TgrTRg*8SbjzgPuWZ$-٫)v/E|ia 'ow'MZ|c!N~twW*7>iHzZ^-O/kW |hf(tLT510I[@ޯhOkĬ99zrn4x٧5@;TEC.p!ynXkp0Fw97.Y|L'L 4NW<*ji9RaՏ h([9F~jBo9g}R`}sY^VpHn9Io[{R[̊LFrg}t .|;C!urYfL_Dn5yB03`)'5纭,]ӁSm$J;{^|:&;X0M']3߸XN+gܓ2ݱ%<IJJs-Yn!:#4l+"1:SzӘ)3\\h AZQ4y͆ڭzb.wђ 7uKAOE M6h=|ᬥqCp:j ֊DI:ͥ+U#;oRϖtѡ{hb"Q]bxh*X_,ZKg{4n ;p[;r(ƍ02ԄA_(tU?mW2I$sNE8.g3pOI)㻀 V(!fˠ>u`nۣ%u%HA;$!J 3SnBpۣq!3b=ȧԧg2\p,2fƲ^]j.{fǧ2t(Ɛnzӏ!uUKbov6t"R?<zF+ xRB,YPď4q fN{y&}ʁ2:0zT~4 E5OvV#2vm/@!sO2{ϧ#Ż9{4C 5Or/lM^3J f:+BewͫbҌ{ z&ӾU+ /[bxKǧqcjӎR ?=lڹ>u,~B.Eى6WXG=ل#JfӥGgmr9R5aSdws; Y.&\w`c52IˮTPkb%_hjpZTv;kvo(0v~9ϳBf#*,H{6T_UŠuX@k[`n Y Syԭʈt/߄RTĎD!̽9®?dq*-`@0;0f{>*\?}+ 8nlX4X-[ *OA:#.).ȖDY ';wgh ³ ķg%?;xDㄒ5WY NUw)~TKʘ8oW{ VNN߉K2[']g8h9^EgT=@˪!+>_z焚gRU 4l2?&bm Eu[m^Fx37.l' >ߛUFsFQGKݽ_immin|6An@<|~́cH@A&v`-@DouvNo'l?w $:}o@.媈@u?l@!(TO';EbQA`_PJK"EbԹLd֋(_p/t]ցBd& iA%\ zc{dɳ{cC{ZЫoK ňcE 5A\} ~ t[9׹}z] 0!iG'H30;H7Ox71L4W:kWCvJn݈-hOX9;n.bo_lSCf+߅yd?Ћ\R;vY]LCnƍVCC-SBz$!ύP&:\V I/=;ah]WR]o³N]·)wh:}'%lyk5_() _óorg"?N+AQXԔgUT'p '$yj($lgzٿm}RFb,Seƾ75HtR_/[4ղvϲ P볋4,_ׁ`VZqOA3tQޗ#$.*|Ց\sE 3w\WpX#:YXm ԊPؔ-Cυz_j/:Bt+.#ƝIX&ڪD#Ho[.%d[ ]>|swaW$Æ3OVlmųclS{p!]6e_agc3Hly+l ,h'9=T$ cDFnfA %oWV ga78Vk/xvsQt?3x, eP)NpP8Z[Q{e{YwEUĚQvP~)'V^:F \LGqƉAP%挀g˂U7`YC\vnƕ*2*pKg C=|z$Ɔ؝br1>#aw%Id7a5Q.|B:u-+>h-~wT/=W0 <#P~~zϸ|3]\m #mIc i)z|~y??}9Rn&M9nJkŴ58'ͼP'h@/[FрE锝;2CAtrzC+>Dyf*dg;Sl(Qs(c.hi->O l0&=.m]g'epZfH=({H`ńm$+k (babU©YpcY0m$ydz`ACh\Gn)qYƠ_7R}l#8Px\o=-&czZ]T#_MN*H266($- L̻h)1\QAo۝$ͻ'XzRAI=Aܿ4RZu.ϗe#=-E!l`&R .0m&GU/jYT C֋Pe!xX3MyIjbٰJxy0I |<'117APSṁYt:. xU of6zG ,\smJ[p9ēEΌ.K5X |:@p'Fu3%Qz۸M #Ͷ.)dwv /*v nzz /HJod5#pt纖Q 4vd\ &/Gw_"3}}y ˫L1#s v}1) Ô>WQW}4/rGNz$plYdlP؅nf5Ǜ_87JٓkM :wl>;LeȊC0n; pSz]4J3EָcޥJi<68 ,(suÅ4oċjvչ=DvE%HCɕ+jOQ@YH{/=X\6r^d-gjK 4y'1 [S0يnnWo`WzY0 4?$ No /]Ig\*6o@ +5%SRY=Sm!>5(|tnFND܈2قLRzswm"ʿ'bw5=Z= p&ib& 﫛j-\br&#ړU0/fY^"&,9^UDbڊF&G#?9~;Di])8f KƱK2ȫy)<}. {$k sq"I9-=[ZI5dJ[nAKO~\$<(Es`N~$^jD(!">~*Ծ:6 ApCt}N]L _i.|Fcz)|yʰ-,z`a=uf_zax*BLJò!T1 Y[a(yX5Cʥ"Ϥ3`HTo4qfIm^s@ʻퟩq6e.%;Ys8NCTa`em.y}WX3z&iE⤈Vp.4¿MY8?Su&seMՅB#A_ŧ;rFHn +j@ ^F 5wHE̻Sv}4iࡤ3*x՝|[ Ĩ Y1r)Vg"my/Pa hҴ' ) InoXG|(}QU)ctǽpQL[bk am9i Y-EWk )Q"y0-K!Ec7 7UiyҁTd<~2=<ʃ;v")q~3l'aqXEwTCJְ^[9I<#}D4KA=:%1i(#/: W9³/ax{KNZs.0#O6#,Ry"GbT8h׫\=|\.4~~gp1 `Geo8c;7nH\\c)KYKč-Rw&E'& 㕆i9_'AYz_f~. 7,5m9::9v,dy*h$}2wh!-e$Tٴ-71"Y8 ˉ^x G,mč_s#FRnwX/zskinKKYqڿ :21I/TMʟ¾uQTѺ۷FozerJ푳Uzz~zӃ\•YSc75cTHNtSfkӶ.i/p{ђ#AfuF+{`9鶋`;H\5˚rn߶wOxr.rM|-eQ @VRV:ԅS: d8eθ- Xڮ @y˾b3K& iXR24#2uz%_(_ʥ;er !M _Q69%qo9BKgD=tӁ0s;!+֗w*t 絬1E]Wb=i :rC:/d^yw?G\){b5eMJXkGay*G9{A/ԨHum#)tf(c# ߑO 0[Da ~,n'd6Q-ק{R^b-*y,`8_KJ P(d^N1y(Yf'd2ԓJ!$WG oK}?i7E}[`E5sԵj/󹾜Y|a1c,px-T?CbG ppJVL2#im?% !,n4Д1A$xjn~Nv_z|řGÏjsTZ cnTc*64' !O83}<SDz,bw&$\lvʹ7z0F!)Y&͞dT';#R&8yw\L$_<:?Mk5Oٚu s9MamqjϲݞMe"oTܗL.bB P_?'1pH].>>1頮C=+]WF\"C!2@dW_gCuw`[لƫXr5X .4H$#广h\لl[YO|=z;?@D Z)gn|dZ618cfJ\r@1aхuL_oBf=X<ޱt>52"W"2 %oҲg#T!Ol_X/d?ťKST3_ovfvԠ6gX?ݑrS?B/[Y |Lazܚ?D$!=2?J_WmmB&d* UFLWm[*қsxǢmLP6$N)4ОvThf%b^%Q"@OfH]ۄ%R)+o~OF?eNDFU7@tg:vҡx).šDSJjz7^D%iuu"^̑1 ȺkX>.ׂ㻶UN Ā>qp["C+]i8X^J 2a£~YBh4R=wn0Bҍ q}V6~? B~3-z¥?pL  ;U~!Wqp m|: Pa)/٧7V&O(.;DMfoJ=*vK"T W4 z V~SFtg\u\" Q҆ݷ+B8h/ҩYчҀz@4>Ek5i *MW 91جQX3K p+t:8B3<_)+yi3c#ܥ'/Y &V5f4j)ah;%.uSB5hDaX|G"^uW@Z+L:{N ,R68t)Csdx7騻H&YBW!XZJ2ubȥ*:vdeA$3ldy֚6z@ Ff!Lo1buQ$wQaq"}[ JctT skzz%`s5aNH(rdSyY^.<ЎcH0+ֳqvzZN"4'(:c%&J^z^zfy*\6L.ۘٹN(dP,4@(UtPoȒr ѩ[a}BHhDoXVGE>YLMWM+@G(7`p[h4 }i+}aӻ/Jiٌ2KJz 4f[KꯈЭc~hF+xՉُ ̓'7H8P1҅\Ji ]c[md(4{ӻ>/M熕\ q(z?'(7E䀛+Cw F9[ehb-KoGcּ3G$YY0 ozI}IaZ]<˿.: -;d Be ,}O]TUPwHh <'?FWxE0ŗ64WX֭ vh_OVLErWEl:Z%MsKֹ.x^|R'lkر 3T..K%MBebpiG3u;&e'mRق<ػ3]PSVPlXY@ ׈Zx>}5>~ǵz`t+_-{4I,'j@ PS"}1g[,{y ؏ bh&kWw#,* sz~Ci`#@zUqcS;HǕhF]`&?}`9C/OC+`Z;D]\:! g8'Mwb?M 䌳:C2rhrjDQZ6^#4 ih<"nV4tk"sX, m|}fT8~ @=sKX8݆$Koqr_u.12TJ_"'+Sع{=] &D1ڳTI.?4dH ͥqn/a%W5fZ}1s?ݵ%3K¼.-s2[bMz PKb]]4?| S1;FXVypA|uRe%v}S] a.Jv1yqq &͎kINC3gBJ*b 0"I ;#8VغQ dBnQg̿2ڱQkm dgmDW1WnNm!LO${,I(pdӥӶ,[MR<  *2iԂwt?*cc<-Yztil GH=;T? Đi$o h=xOtX2.;dt7v,TV,Ym%20Eȱյޝ>Le9n؆|WbZmw{8Yg({h+ EdQ];q"q=c,925ayB?LysJύo] L tjTM<rĮY78ƒ̎AD:^8cJuBͶN\e#cy͵/v#Ӳ0ح:jc3pc--ٱ8z!/b}P=E S)_#7~h,@|-[FDPZTk{nMQ9 5oGl)@FٔIY?Obz49 Й ;C~}CnbO<wTe 1̵A#Y*ߴ\x w;< 8%䚟W[(-%_Tf# Rae8m-"oqa^z`pdf eM꾲5&v?C0 1C"vqVd%K"D&)XdH,C[  䓢]6!O3;&x, *۬?.N<_!VqZOIwhC4m#U^SԚђKPl~U=p*%(X- ' b(|#A-9e,%*jWnl* A ~jb/7F9+"E67U&]yKuq'g%[?rNs}Zi.03ؘщzagl N3) Y]W7ay1h0?&؈/Ĕ)M#mqeS4~g 1Yc")? ₾őq@_WWw&&Kr&?ol!-/@ʴ*b{m_vFcH\\)g_? 6|"?d6 O$sQ1 i1L{(CRcr).Ðtw8C%p1}kMCxcq@Aǧw/WVg X(l=Jf˭0b$4`=y4n"4QBjb4 p`5hK:0aS0Fx1l:~D=flS9r>~~(:5Qd}?t ;">La &Re~)8yxPYc gIJPqi@D1>x0{5yآo==O/ou:-;@0; Wܭv&My>}r:h0׎ٿ@s!^vK-2ɰdZ>ks;rPHE"+? {Hx"޼_ᅬYDP XN ЉIc:%~I-~~O80}#qqrfykadll|#zySϡRN'O+4Lb#W_ר6SHm쥙c^Z:\+F0Bleȭ0mIC)uGAlQ>ٛY(Xj:ntc8;R\~ <#~sjE @$ ^:c=Q ./.:m/EB.9WVE|ٝP[O1ueddn`zJs1MDFogG՛"#׽Wi=eEe±^%بa9w[[>LQP&?- A ^O\2s9s5tnmn5Bp<6wO[&?}\}9ĪQ}ͽrw* Ft.v^䯶邼&D(坔O$.V-6 ;^|zJ$,n-B^;5ܚa砷neV%9.F&e HN=ٍ}\ۑN"R-Cj(Z-r|rr.-k"\ʋeɭ֋LBv_fj33juwCcD?O8 5ŇW+B9"Y/auG;#Ix4X:q0ñך[hdU8+X4X1{j.`ń<]ǼãR5y>'NSƮ"* [W3`~RjJVRqsxi4q9HW.5`J68 -~ .s|8i̓jC-DA #0iGcREڧqmU`Q,4UTwHaeob4UR\EFj$'R1+Rۺwڬk^*xXz/ *)%81/ia |ܨ?ظI9qmԸ*HW WɅEAk a9r.Ң@Ͳ'፵^bҔo^%<4)[3R^kɨ}fq"/>KѣK5޸!~.ĀlZɨ kJ#3gĝhњ[z5tno6t0/ɒ˫knEjLu>T-ѸŠVuIK9t4c=TvWR0m ǹe)M4" #htsOpaczxQtC9pO}ʐ)/DAL|RgzUAKAܧ_`[,VN3/.yBNi=*o>[ww**hM2ȱ˅rqx8zGQfbǵE3 7x8ī>aܵ؏io=-L!ɥ65 Fͭj”wWΚ5gxs ݊o΋n]#Rټ 9E>̚a eptے..1@g1)zTSq~DDǢQ}eT e8tNAt;/\.*($]e4x>n;E_/.6/8uSu"ەƵ&7q&/,/[Sr-(ǯŕ',nH# ?9_G|WY5x3%i>c5-hw͐8$X.=L 3nkƥgYjU-JZ[ -ѝmமzLpmuט@fvdm'̕ʍ%3zPIu&Ju rZpOH5},<<.~(s@|'A塖[;HkUܰOIYÙU3-=Ba΁^1NiIqM&]Qcp}x_8w4P|N~pO-:y@ ̻)߼F; 6--.Eߥ߱CpFp.165|~s_!҈fp:Țqe}ocPLTRV~ Wߵa3@) mY\A,I}og;Cz\hCz/^h~jE~jFd~ݖ߂7(_shü5g?G_=?7n4s?Gsϧn49N:ѐSoA>/:!Wy)3=Y;6"_b?wFxc\M jLZnFxؾ?Gj>hh!?a+FrLm Sg_6GncVkֽ$S} "<oF ݬ?(&owg'wW(͉'3%(eާ.MKC]׎ffUpcO;2wϸOݍAif{{XGWj3nJy ?Y|j7_Go}}qfyWLMI6}E~ ji8|eVy{/'y[߶73t[\}']'~һݴUBo;}d|P޿Xz~ߜu c~(|pHM/j_t{||{N|CϽGB-O)=l8B\t`QʮPNr{i Pw lL%WՐ/ IVs́xi:Q7wr`aj">"[BuW̆ |mmW$B W~  ;3 S9~K\jTnY ںq6# 2MRՋ]a`ۥ P}'h[>Q ڠ !o\rq\w-ndZ1b:S`)_ڔDU`.%WbruLClYIzdG HJ=<2&g# ,em<)#Cc9z 6{+IguK*ʗdꂷCl:.i,qO UEXKD6M&b[]Cv%7-Oj2[o x9b;pThOB~0Uaщ&Qe Jmy[VFT9'۟{uXJ1$, c1~ (o{>X܏0 +}X([4e7 Uw]M챜iM{rԲ ЏJp:葒ږx37FY0=Ηhl dHݬ=1ͪr>\ 6[Sf\>v{ΆޝYe\uwwFKR]}ט=5pH\tT].ymƓg+&QS4s'͘+^_Gt㔳 nt! `_Xμ,ȝنn imi45N%sZÎ.ibX^ ou}Yg:$d;';qQwdh:[oZ}نg}i"z43Od*5M-Sɍ38"oڜIHz2$HqÎHZW]ߨ0Mg^ϟ7։n\=MOfC"Rum.sݷgUd^nPVeRcplÏ5i%pnڤS῵k n=2a;ċ-#wų'g]p/{^F[>@uM#Z*G;/* A x$8J|p'sz ɕR°"jԴۋRBÞO\ow(*\iZOP|&jHeR$VՔ Y/1*UsBe碹ef4/VHnS-.ԉG8lslEkٝhV>!15[zj8#43jwVpC!e]قsgoO_1X,s-*&!MHNTLt[Sz6". /fi]4at7\i{ԕ?ClxJ+fF-)E;3Z.M 3t\,{hWjJ_wlCE׾@{rl nV<K h)hpnC%$lJ.LT+1ý3N:I9~E|kӈ,s 9 S+&sJT8˅,;PQC©r/jҦP_3-ON$ʫX]5Pr<$4zH':SwyJgj=_9R˶ȸ}g4ɾ}3? (jo+9˘P7mK^DݾS `]rC=hFKwur 2WId_pC@ WIśb}luW^Pa:nEM02%}kNצ|?*BӖ݈~^Y_#)=s->1Ɓ6rVn+5L]pEj/{!@/%U#Z6{7&AUE8xq  RK㇂#9]-tAgkE!u8ٽ|`JAEv;?_<K ۺZ}]fH2n$=fQQ sx` 끕vרE| 8 =G>.cV΅)Bjܹ.=/=BItu 8fs,@hW4&cPTCjs!^`5Wl-!I%`P qyrhp/3'P½(ˑ1]]mw_[0Rρl[)*hbn+LEmks| K*K<I)l@ ~sodQpOyĔUtx⫪lw?o-hP_'vW=@)[Cs}RQhpȃcU R/=G<&djrCɮJ'h-ZJ+ذ-]eƺ)!JM>yTeD#|z ]NWgZF^Lq][]T݇%k˦/DZ'ia셔X7tLZ Q '{0̏ aBVo>SqoCl!Ǝ3%wHY5O!`6aaG0It3֝TI o2̞Q }wmmA+-vlj^ \A.qN :ކwx|)4ߓ\lG9JT-_P!V!B^Ѕ۵bW@Gw#<{agSMٹ,y!v y.YJlL$8o`ɥcX5ΞT>uq9d|[|׾i:4mYu|,҅`{&wpfw_äiNb`Pi>818~aD@"Z/Fd1Or6?+-Bu3W5ҟ L!j)D*ǫ Cll|rn nnU=xRF}mD48x/`o3P}z(Ǡd q'eF;r#B Di{nu1{9cd%zz°޼JkQ_ʡwIvƸ''Y)WR][Avhν r٨%pXh4 (걊:e*^$|s`2Z^KSEyP }!ƒu$-K:6J \J; fa: |RjN^ 쥫ZttUr|$EL-zdkA+U"yMMef/|.)6 S>XhրS;W 2¿%SUJtIZ twW1+i4fU[SĺnxGn4m7=kӋbX"P-(.BExP)AYC%N΢CC@[,J[׋ Ņ4 -2#z em@Q̿[yqSN>B)ɚ#~JРԸ{9;eΕnå^e$_ՃJp#LS zPf5,`9 Eh't0P{(?}1eCI;gƜ_IS݆D2̸ H 5;*e@P1Top BjxBz*1Ffhv+:u{Y<7oAlHUFf>wӅEzE]p+O28 ᳘3d0} !.nݎǓMsLT~E U<{JWj) &n/z |/ȰJٶ?I ; d"'pHy T$UY \0aos?FEۋhI|};3=Cl5 a}~Oz]ںGJD?Ckd) Khn|BvGMxɵU¸/ s[TBzp9WVg6H`v[<ƎWq;021r :E㵖`5#3ǒ 0W&Lj#h.b-!NŴ"[W#|;Ɉ…riZAR8lQ@?Ch9*$Ӥ2ϠCHCP,I`^Hjb9,HIg>k#J;a]瞭-\4+rս<#1U2/kZZ]n rP 7I%tO=ʟB5lJg6EN|D}שD/626Q,B'@< 1[?8Q=p(ުEzR?7|%Pň.I^0sYT13#UpK =ОZ;z胼JD[l,sa!**1 |~: &Chڅ:pyX`-PVٝUHR ۢ1ǺqA\Aئ4ek1b`/B' ̶:;jΦiBH)ѷс6vp8?$Y 18Mj2RZ{]f_<;Wcl a(x.|Hjwjm )1<_.{4x* >Y,AlM%0Okwt2ڇ͏P4F_Qn+`RUgX*.Ds>ZNJW,{P#}K~3۫t ?&۶m[Ӷ=m۶6mۜmִO>w}={GTeefDEdFUTk)_5hWxEKIzF*/!gP7ipWF21-A#,Pj`,ˁɹIۜ\w[CvZ6Sim!`&Lq!=LJ/,IQZB -R[2jHu~&q8,\l㱌3z.6һb,ʴR4D8u1j,^ (]< ¦Ľ,ű`:y*Ii|bKm(?&Lح9[1nKA rAo[Y(w·'K[ 3^--hp! ? zoSt+n5*)bx %0ߺ{NO2?9b@ xc%z7xKjh.EɂQQ<~> R^1bsקmW2l h6!Qa}5K| a6 &%ۂ'(F&$|uG0 AntA*hIޝs%&6~ S C%!ɞ"( ;@&ɱ D}1.a JN5Y;I|եlc[U/O<>Q?=ay(]+a hu?>J f bix{[T_p仑Ucv5[ĕiM"Iĕ3 QNwkW&As1jytޢ.PDw_%vxq j|,Q ߙp%%͋jC/Pj3aXd!w^"y^E-tSZU@cTb&#GieXw*#,?(5[=E~TPX3.p,/b} ^!x=D\N%AGS^= )9DWO5a`rT5D!qQ r+l4Z(P6 l)1ӳ?޷ D-Р|<.:sSe"vg#kBf?`Χ^WO?_15){59VD}'d5=:F|^=m3 8K '(,KjGĞy8tU3)m`/hiy0*:ɸQ~x@m,ڡ A'?T$m 2܁n5{(ysi*#Je% \dgBB b䀶U +D%-8&r#Qk'tE5A֙+=C }kOrW=GEPqClZ$Q9 w8@N}FX5b՜Zų f}N/?yb,x)Tl mdq=opZ'\ Z $hDC2YЭvqGǜq"T#ٴb@:x_xw Sߏ.Tva̷a6HjŘ-?Zv ENi& A{x7GGZn5}=^?؜ g^ی)=;;ƻS~ ${+צ++n  oJI7o{ԥMb59/g;rl^NlĢC(|䚇NJS1PTFxDbY%z㹭6o9E~f4v5 tWԳڍ2l| [lHl =-_S(ZČb~ @;D- t?/3̲w8X@$]Hؗ"Y3(-F4 d}J7ʖx}t|DQ{D㚮(^+ӪA~!%Hr@]Պ$*det 7:+*^T3L6Dar:,rƸ\llQI4n\M8߰ b-c=wYغ"<^5VX76ج^,0߿mRG}qOr$CnQvuǎOCKvFi̔"4WvY%eO`f<M D_zZ~gE;AB?֙bj> ,jɾA zL߭q297Sal2AwDmee8 FOٝ1%IQuQC¹30N'^xl&ׇ)S dB pZRdRQf_m˨}F'd ljIa[E;c[g!6QE@Ǻ^w gghDK }q [Ju觚U/p 0COr*j#,7r0k*_x(Fxd#!(PU=RKS'^I6҇Q))ibC/2фI}b,>GVG6%5m& XX ȈlHEݯ:'vCofvLV".ugHJ_l4i SlۤQ13Y!Lw"=Kc@ 'ឝ-or׵7JX#KUEWǒ$Epv"h'ˢ}?Pٮ/kJX޽VcE|(8߉2u%堮 f/:nHJJ١쬍(ˍz & o`㬃_ux'Vئ=AUmP[9R7 -zz)r"p1[`wLY36M+&pSʧ:GEÖ| 0",.kְO)ྲhG~a{[JPHyi, H5^TZ̍%diY ީ0pM.6,h9H(2WgGcu0Y=49(AB |q5.78hNl' 7 2SȢ~[s6M҇=_4{56CLZEϯjѲ>ayyWROAsW93_ ks *)m̘\ccS\4 w6&'dKXm)1#钍 N{žh:mlxhgc5@Tv9>G-M՞ qM^ PZS CʽCi͇ϯ0v@VV؟o ăRw$b DÐXehvc3c~Pǐ~#vBEfAo`=&&r8D֥rxϕJ|J)61Z*ˍGѣ24NO~8($hCt Gl%WYLFY"w8/bkm#@R0Y1E}hV@CƄ'*Tgfecǎ^ǿ03d9]]wjN:{|t>A.d7Y{ 1o-դjیXe ᓸ(שLOA>I7k.V{-?EA d]B (+iBx zpR: $F^^P#lYtAzpwXH3zA|G;ܚb4d٧4O>tӎ @KRЧc V_*}B͢]IuQ/OK ߎ&x6F9+ "Ѹt)yVx`@FX"(?sG H0-&o$+q@ [4' !/RI$|O yR }D39{V]*{{TGڎV5B 4Qv=>eq0$%9R5V ̌q٤^jͣ $>%a|Fމ /0s Ra4$[(q/AB~ew֝(C7sM(MiÉ ~R}9 ^/ͅqf.DfT-H_x7^U9Hy$Q?u9&jr,HUoq5۪LhoC_ns"2<ԣZTyIC;T6W#|+ B,qڧegaW-~z~+N8SG]},6̓s[hgʴa]T25_09/?|:We墲sACamuM9Ƞ17n/Ձ2V=sBUwT.bX[2:lGג\<Ei9EhrW:P Le jc׎K>:MA?d'Qx1Pw#;4;"&N1[+G-OJSKRgԍ0/2dL4>OyfG!#4{)Ц GDg鞾krzpd­W1p-x;]Iz_j!B6(]ntEu PN˼oBFwg&8h/.m Tsn BI?NS٢N ~V%6# NƘňUJ{ʭ\j{׭VZYqCgp͜f Y(Da9չU{ĸ9 ,_=D laSS',:Z +3RSGS&zNt-ۑ>`tlzqEpiI1h,VtZJڽ:q-F5YWoM р"j0~@0Br@" 2O&-nؐ{,ÀԸ_f?oa΋t;Ve&\fy Q07f{Hs3vy`A/U{"d´z3>p+,=%Rgڊ' <J7JQ(:YG>1()G-"aU}n6-=Ob}]yUFEޏKImZo=Mf}F"xUxq涭À톑 IW,h D2ޫseV u-O0ʗ:fԮ%>sa^&-+5lhE{/h0T@]˞aaˆTFm%HhΐFfĨF<'{x=GמT|])ZHoIUCغU:::Wz%wՒW|'(^%WHs#SOSrWZ!88>o?,a"W]KvbK/lXh*sN^} XP֘ythewyjʆJ u~cܚ^ h} _'p )b䧊Sns. 8cV5 'z-7<$u!0:욊@hpґᨱ7271uPJ!*^ 䙵_aO|\~L " ^ţ!R!#GvqG <,'h@NZ,iu)9*->Z=?Qc{!vMCezlZXbZQח9:UEy^G$t=~Oulsj͒ ҷUAVR) ]d[xEG0m6@h^zŒcaZլ4Gn@ };se/o.k]?7@%5ԧ 8̌-:K;tHX]jܤ-,-Z Vܜ$G7Ed«DRocfkZ kΟf9K?fɭ7D} uʎ*rYpE\x5ST5~n8<%(5ިpjzPG l*U&OXCk u.ֵ)6;cB,Eey;몒ﶡBYeжݼӪݳvKIlXEϓw&SkhF^qP[a sBf^[Vܞ ICQUo(~[ 51|]FL!Ępwj0wk޲}~"Cl/wi8D 42!pyHE2ioP (ӷί(} ˕$/䁲(VOL^K 0L ]C?f͉$s?"E"C]֒:'k\v513 N*!^i]xcVUsIY#*WN;/M".[=nr+4j um1-(;Y8HBuAGmm\F4"H3ͭmk([! +t0mLNJ3?t>v,#t5+y:J枥P ҹyʫk4>belrt8kgJxu>Sx8b=/E(1KeE罝O#,d=:、Fk 10x|%IssnǨ AOMaItK1=q5%tn#>_T^jdudg3oe`&} jn>.;v+XQV~:.L4qL#j8G&5Qx9f,Ay28ѻgZM6Z:coq=\78N?^a\=wMx=A/c܀?NM{§i_8c/25u^zrehO[TўNUifd8"eyAڊ:BrcYP>X޲bV?O$ Кjit󢫒C&loƥں EV|oL |]?H6S.ұH6,bSo73I|T3꽈jee8-jc!P$̢g|@|"TJ4̤ 4M~}UM=X2+0`?wfyPT)zåOi=^(YšgDåJ~.d\ThE GĴf X_L\'$C^ a Ǹl ˞vmma뵚ZXof𓟵!Hy95~Hɣ*d#  =hЃL#+޹ѧ_*b~챤%c0P4x!5襬`ԓȱlLF\ CB(IO<Ɖm O1于 I8M ?n6ޞ><}Ν3o~R ͪ 胡;#$*h `&L]QLQ| Aa!0 !V]ӏt 7f QUC6 &J̝k@Ns8aF)(.%##HBmf^ua|r[}*x#P LLA㛪yg,dع;KBR%NB˜EK *UIyf"iݒa,<=Av<Ї<9rA9:΍2YOD*1Ԣ)΋T@HOdlzf |r]jɛ ;Ed5ͯRY1Nz E9/oX.Q;x? d#Jz Anop'hI:'~cn^xxl) \ -JGoR7S 1;n^KGڭi$; K%f!dǹe?4"`5%hc2 CAůB :$XVd7]=GLGdx+X GcUQ^1KNon,O=J&JgP8ux?@Z(۝i1`x).'KU*\RXS!;یF$m|m4|CX8l^6ժlIMvTG(=~2?^SWL e /\qܑNyK2Bs/8"a[('XU8Vv;l:kJy4p])^9CrYN^5 {b6^966bv9 =K<ՙ dA`k9%{-+K291ֈn~E)8Ԋ#vu{fAxހ}9qk53+0yES[N(k鑵N= kY-˩/:ig D`.@sP\R44|4qJG_XS&YxY W|%2IW@RID:0O-ݖ$qOˣϞ;}_tϙ l`KNԥ+T{W\?]ճe}Ʀ/8t4,NW.us$Eжx1]{f?o ڳkH_^J eK37&z(ƈֹ|hhdfl#G%On 3w. l##31]#VVSṶDN蒡khM=m`՞}~U9(m7@ۃMFXjo"\uTVw+.3LNҘYa#hr}\-'rb\{m+:h0ZaiqιYl۟Edڛd;4DK6FM)ɽȕ'm&mqvpE6Px> Z;WM {Ps ^L_#"CFqc^K| lw:;jrg#IxN} + P)-p0*%Щ"07ouu?rmN}7.O:Lm8 mK2Tm=3:5m&]'x7h_N? D\yzе]]f`ϊE76utx0CmuKpQmR}](0e=!AnTiQW7KKX !s .^%.oHXOT0XG]wi<2>sEPI]'o-˺R?cX$/[13}]Uxε˨bp ؇\|Pu*樈drt*K  oßNM/on`Iyy1y5;\FLvgH|E,\czEaPʂdj{Zz"Mf4Ҵ @x-#, sH-GdpugPގ5BU5οѣ6W3Qj!XmT$HZ :׉]mmAα|AE : gz"7QWv{?Lci}wq tbE>a_ s{R-: eZgEÚc7άk<c )͖uX$F(#b2>WBɎ  H?2ӺQ26obVSr4r<|L;ɿ7-yx @)6+h2ٗkvPRskIVakO TTwV668%vKQIStCY}tSnea44σ+#۩lO/ߔyefE^۰ s8zJ{Oa#Ep >޼Ŗr&puKnraP$:Wr$v;Ȏ69tKLIܫŷۏ UdbٸOrpe=n+j)9VMm%5AOP$V3_̈~*y!x!ݨ8_*'YIaDpBVĴ[>xIg{%ٛ6 01,kra5S|g;,_|O&Ũ?/$,35^èDl#423"Q2c;IZ^ZWv-?!mRu-K@ϔ:Y粸M69-c[KMz\~[p0(|.@ v q6?qb?,oW #"/"%Z̉;Nz'fǏ6QV~01:Z2&/\3^}!_DƗ>;Wtm_*{~0[6M)z;Vuwi(~v ?iKdL?[9  %%^ d[[n[8fm7ONop'H]Ki&{H RG 9q_5Ԍa0׶%)y ǗeQُ /oxUٖƖefuS$MX1Osh! k;8>/jĪzJ;ltcPWȭ'jš᦭Qǰbwr $Y3y-9lp6`FlKA=7IYM$L$[CŸu{Pf_**@fzq+%jFVqO𳢽79d@A%i_{-vF@A(B݊9@e]bМsՁq8}O <, B}.ao*^a=0>+ܹ͋XYv )ppvPR%዇ aJ6Lmu0i*->h1A|^6tA0Ր$z rWb4꽻B5V")vzM*)OTٯ!D?.nzĘW!:"E \W2Mgsw[kxozi+z??t qJeWhdQ=cؔ2&\1Huuܲ8۪",/jJjGW9I}|$ZKq!n.HeZ.{ŋT5)C#)K=>ˏ"PU7a m߈%mwɶ~;%9,jnmY urUM(1x87ß{O%, G 4&=Er uu{gCVXJoXMnl1Vyex3?I@zE=aBIZ&L?Ia Ԗȳ.5G` sH%xlp('(y[rA)r~*%: M8Jpr4L #b&'Hke+33s'}v2$jdtHSiBp_~hVK;3$"E.=[݄:YvhN'Q}v >A¡!dǟ\|\Xvoߐ\TQ 4#Xŝl[Lb?0=)(2o[vJ5~{a&snWK)U_*s>G(/ Ɣ]a7{S; 2F愧ԼB{2;EGڮkc۶mضNұmضYϹמ k1WNs^B@6݉"jb/Zw,o$.EAE`5c Rf*@({KMe{a~%F55~{jaNb|X M )N7ҍ^q ::szezW XhdEmf22(~*vKػLoQl 7u4҇-xz)s̾E?f$'f몘 jSv s(e66Qi*8b%a0rmg1($ó[?)uǖWΗ+&O^xX#8K?HYj:sͲ@`.Npjyn`\OSY 9^B`aZݞݾ"vL; .0?N!_5-feɫ:o38Uagyb=1КwGz14cÿ󸲆f85PӉi&E2Ý*Ǔ!!2R_c_m]گEj6g.&W߁IOB}@Hv8tV |hކV!ZRHd~)A4 #NAs Ylwv^ xr@ϟ Fxϗ1Qo0rdv](j/Yأ a d+p caqk= &RBEQ>QI ML1`xb_"חGAz>Nق;yUQ>C][s\a #͜SZkCܝ7 L,(GUܫ$`{ TeS)Qcg5/e<;:u_rTx{0G v=}BH]}z~T.Vw-B#"zHI0ΎWE qJ l{&!0<}0ҝ:s Қq]v~jRO겸㊣7ޝu>Xj^E Xp⻆|=]e ))Jr*v/x4 O&|SI  W/rZ_ޏ=\3±2^kf\c9*I|]ƨB3KƒHb:8Yy[k {4ow.ei3N$ܚ^,Yy;f)\۟nTЄцtA[cE, kt.i"sǸԫHkU0~jK`q5ߘhU"A]EO-hKrSt1v3WI?D{ S#6a _g*FV>?[G+Pꕆupaj9d}Np0Uq^#A׫ƬQȍ!Z~@\."f`F^Rz}4:{ HeFY;-C#KG3yf1,1V")*͐gw6E8u4lGfp\G.֯GKQvsh|gH1bmH:^7g(?mP5~Q6/7bڇGVD%kG5:S?XXƣ'q2HUar$ vA' -xL%7B ȡщ!Cm + 7, lFy*Ԛ-WM!Nnp:+U_HֽzHڕQpbX;Cqo;`8G+I'A[^K m`6(fH(:@%W]"E7$yЎs+ݼ=T))G w[Pib? OIQ?$?({{n P=#?)=eHUD n"@ZCTǾsH ZC+K SC>㯽"lŃ~2v=PAi"9kv#0٠J= e: $ P8P2 L!C4?PM"rmI~OB+vI1&.SZK@v#ytqy(~0&.3HCմS2P&sF* 2] 0ݹE3${.D`xϗvLTݸS?cQSrH 7Q"f9@.E/TU5nΏ;V=6Gja(~@q{J_sfC6[χmws.ĪSLQǰ2< j mG@suW!Y2ՁdO@dXjzMa#jxFiXJҍ.]u+ $vx CYtE+~p=}vAN!,(jVO1 1ONgݙ5gmxaܴ<*9u'"zN$6ThU޺œrZ7lYGu2']d9dZk rLpYfYZM7YϟOCc,u5at*]BZmR~ yi' fIlz~Wpyزfl^OLq/tnmGs4I['5aW]<vu$rjX4,me(Y'd˝ ؟}0W)l'ŷ`wҶ%!%mry"Iv|f|UB4-zxQVWZ{QMKg=\c`<7He,԰ ["ŹehEঙ3=I+DYu1fX~.EQlg/$w苾~J5N@_R  s1.7y<謒wP5t8(!FL+%y6XEV 5?Kvndf\-s;YƤn.ІTY qUa9k &L ߧpKH@g}8YuG?_ cS?7.ikd4jqctQy^VX _>=:D.ŵq[sO-%c(UkSc}[)祧xOWM]n{Yx8);<%ma}SԽI9yMl %a<[v#2 EFPQ"/e6;iS8`0 6j.`Xe Cabu?bE*71' Ŧ-Wwq\jem:&rιf#xvhhTvaNip(]nid4rӥ]I|jTQi#3 7K޻XPH(aTh{8^Fg6lGia3nWFgu˙]tDϛL:Kŧ.B"X>x`~ߟn֥|l*~p6\m~7Fx@c<转ZT_Pad:#*;C;;֢ܳnU 6~̢$@}}㑠>8$v>R-H* Lʩ.~OnOsH,)}4]ADT+N_pNa,ھf?˃͐`c!e(淭u9N0<كkYU%&1*)r:vb/WA;W,Ӽi@g+0#Gq .I۾l@֪?ګ|25 ˿#EdETfo4B_-Oi/O4Bld"`df9Ō{Q9*`Jng%1H;}wAT?^"IG? |KHNxOT[*8Q<+)\3;WCe*f+X55l޾LH`;,;¥Pn+B&9x! 65$@0O Nd?-x&!06ܠ4!  L(;M6(hw80`!t Ao;aѥ?`bܗթ@{ 5sD#̀^2+Wdp8q)+P !F_E~C4Ṵ,c04Th8ä 3O j"t!#3#g25Z{ح*8I"կ'#hZQpkS5tȩh`OPYP\$ϤG' D 87JE\^u:wCpAੀs;Q ÞqRI4mUJ1`ɀiz7sƴVV}N\/8/ռqE'lO*ƦMp +ro`Ejم 7RPC y0qJ] Ι]Yo({rqy N9lQkL޸nZeH ^I09 AےrC]ܦ|?fzqc:~n@L|y0%#4ĬϬo}"$F+a4¢tsMfCO1/ Nܒ`7:"}^zF{I:"uT 8!H.lR9}Mffs^x =؞>h.1*5,^1D̖RU{9\(/*yT}F#or,{=؃c5%i>{hF~ԑXz޾$@~`O,\"z7N:(%W0I]ɻ=>z+&B: 2t03Q^.MJ<;P4,a?dV|WD]T\栳D_khS+|\`פ n\.n˧&BO%ߘT6Yo*PV]@ TRYGZI4_:^*"ljJ\_ĭFjU=II/hq'sm63O4ODX5$oQIJ ob!tcz1[?KHKD E'&-+ζm1 ĂܬbKOE1GW-Bᠴ>]oc~ ~[xM8+ot4T<>NP^*;ՠPSt0Ngՠ$Zve}ڻzu7_,)EܔP8:D>oV 6%JV &Z#@m *N2x8Ru1D۷UlW v R&,K9 g\Y+Th6a>Zueꏀh?CTnx{uւyzD)Z`U-;*IGqW?8vgF A$n;dLuƤE8ohy$2VE}9W:F (VK{kJ a#_)<(?})V6mdHYR3 )7B}9+9 k; i_Ϯe"XV$NXU!7uÎo>_G&,%(5(k6NZN/ ##;;d2 %qVMi/e"O ퟪ/)?(9aLaR˗tKchdmbdgQUwƯ朿9ο=:K'xBmʖ`BBZBЂ'mXxg795gpݒ.d4`ઁmWT@|xhhfE늽TȨUxxz|h0w+3(v8 -@ZF1R ?>7>;׆x|AN~%T0c Ásqz G93 iyξ\jD79mn X5xf+0ؿ).ΨNAlg[33m> ـ| x z"Ϡɖ'V0O_?9z?MֆBxs$94ނt ej /qGC!=\'=^ א}U*bRK!cE: flm5sp9wo~dsZT[\/}O`f@y4[x[Qn{y LcRh⠅$;wjuR=${Fʒxh<Nڎep;Ku>sfUTGɽzi-@KK; f8|coKaGqaiT@7'^{7H֬A׎=i, 퓌;g8Dx;?\FUaj1Zo\LQA i,!J5H:䲪 UE筛sȓǧ,$[mCpY+!rU^ێ JfI;~8Ni0\D#7y^#XNkP3ٌH=yi h_ݙ#HLb+&v$aVȿh5K:Ejƿ)#ҘnS{r'a"2ݥ>=;5Rin 5=fwP1l1z3ŲIw?0E:y>8U q^`AKRЭ :<6w%Tmf!j(4BWs\q Z'&LsM% !3Ɉ/\+v)ޢW_k3?5bsOvi*gKdjuWQ #_&tz!8tE`Li:d=M93ZohNBm=ewlҤJ8ru886B# ;jl?/RBZ?3Izb9`^SF`*P7',[y'^B"Z7۱ԫ҆oewg?ҭ1e*6Hʖz69 B=4H T-_c~ P^b诳WR*b?jW̩rqnhH յkjW߲+1\VvzrB n=ȡ6Q_5K` ӥ3[ ~êe7nʺ{@DJ8o.*HzU<ߤ/8'I*7Fܧл"m%kW;ۺPQ#ziQ~Zϗixʵ=.Z#ڿCxl2bԦUxv" "AյBffK">rW"jjJ?h ZG ug1~)+R*uТH甐k;x :*9 ^BvށD&ifo$7'#hC#"0ŹdW@ֵ yP__#A%pHl3*p.|{}&ꮤSGYe޼T65_;y"jT -trfȐJ\G AߚycJ<<`Re=?a؍S8BTGL '.#cYCk,DU 8A :-{aނj6>ϜLtlÛAQN\S\ƕXtМ*,]3+kޗ~d(PeɳMڌj@w} |Ey 5Qi"W8 BRKL&ӎ˄wIh=SK!g}ZYgp׷;] tkYئ|N |\`p|l}gK2;.:j$T!<(ZVsjWo<%Э9_3;h1bW [>.@Jprnծ.*J_]K7;l؅Lv]_tgKne3o&3{0O'µ|OdZt ~yB{v>H06O\c~x$\"]򨮣}]){a IͱgY-U{6906+$fwB39**Eb#J<m6dm"n%9Q=u <%(u$Ȧ 5$ՠ}+@rfNg p->ȇ8`g Xp$+AۤM;+?wr$[M EӸ:C~v,KϽ ~]iy?X|ojaڄp;(rm@SY l &LOhklnںK]@> #-I}fn(F*WP8%lYʠxLbv{e$ᢄdA#! ,^< aLǸ"gV;TQ.µQVy9WfSۏyauC -RH̶F>/6u4OʑIt`[,tu 1A)JnJEp9yD_=Bb>=N1̆Bf1MyjRF DK,@ъ/gV( [h{yz VPLZ@|v7Gtkܹ~8( xQ)cxO tz1{Ǫ0Q\٘: -[H{ {7VTB+-]G7ҁUo }5=b\Fxs'N1mCݡ8>EO5ԅV8SQIdW @B`V =P`K13 $CsRՓ0+gtuL@V*S>a_N}4 ǯ6E}Jƙlbԗ翇y6~|[蓺 ؟!NT užsvFqCJ~TExa Fw4};\٠m&7gepoGmG!ƌίJ>i@v#ǽT3Wda+h$7>!Y=4'׃Ķ&KݐM7#A%+Q eg8 I9`jU\A{C7x"桗д|׳n Y|GA 1*(cEWΓY-Ľw٘2$]@[=stMb܉t{')8Vf_%<|M/]:]Y&{>CX^|xc_vߔ噥BʴXJLneu*^7S'"cd@Il*`G/?_ܨ%>sҕwyI̾_""S>Cw',lP h(؋zA\ih_4M &ҙ*ؓ6j:9mj ;iȏV`ϻwߋ:Y H)̥88i[,_;RLY2nLػCq_Mz9nPQ79圪2œ=h\|ީ|p#JĎ qoF)B>G N$|x)!Wyֹ"c 5 F!`krD U~K$&@oe[tD)J{ ɵ,i"\z^J{|Bsc9ƀynߊ^r6]]Vt9!PsVEFJDMr KOɂn7ڢvqi졞c5/,qe$1@C1\(^ϓ~wL6=s8nы?~jAS:z{ cBpxЂʦ/k7eT3lm%#13lEW,u),WW{g\vbN6"(kbHMhҤY*}?qtTZyӐgъ7i ۤK#!6ꐂ*qdTiTcǔ:d6@I.( ozZ)yp`7~G"i|G o1s,}q}??oEWD=pxT{~s:u \T~zNaoF?,lYgMv=[N 6LXuPvC\(Nr_M9iɷ:-&)[ w1GH&&gE !|jv< a+6ؾ;L1Cbؿ 3uD%#z/MxL5%WQ^ӏxU"WBΛrA$6^1Q?FYsJf]`= Hu>\UK̃M$?l5QMkI+Xun/qX{)ύ})ul)#/ΌbǺblu#6}ũ, -)V8xP\0cXϘZA|(t7ld{V[ҵ:f\WC/+1"c!#! s!NUmX(V̾}ׅ(d~$V=Bu/}Հ^HkTo(ZrNJ5m ^Ѽ>nJ͙a^m՚UZ|Diȟ# a8o0U!-Yx݌‘:1::["?;ȐD5+6e)8 ,9bSMԳs+ X}gA-Uj#TTUlkI9*T7n/YsŹE^2) 6WYWubzJC;mǶm۶m۶mضm6m}/f:&?&woEZ2)pcg(phO3~Ie ݨ6bs(w?XYܽ:eƲԸq`5^y4*k1F:+6y!Vά?Oؼӊhck}P]zF&ߗ@ލ .3lWltLc1+sH 1U4mY4*jQ0,a3T "+|L8"a#smzpT$= =gpǝ h]|u*ءIe_fP34? .p)x=yc}4u Oʒf<:|_q?l}df<3t2<"(nr2]79MŘ\jpzī~I`iV;N{ _ǃCnn3V00T~rSӇ91Io$R}z˿]5-hx F ZS5犫(~H(s9Lk2",iΕ:|EF͞%ۻ7 NQ kOd݅j9ugLjnx_R"Du}{-g5*dw; {Syn')M ;!YRk9PuЩQ]@k;4rp0d=ukKE>B7 SoPK`ꠐ9`n{v ?{#8Y>u_N ~=挥OV!_Զj*J  pYD*߼$ ,muXKXϞ-o<_:\zq,hU6FRLL]L m<6kU5rY ]YA_A8_ۚ~Tg*fYP*h4RJSst"Ġ@X8@@8u# ]%PꁃebFp;)kWΏ$ZC+^0 th$rp 燦"mgndqز9~a#˂gԐX ^Ԃ8~R|F:;H $|]AZ[Ӎ" |ɪ6 0R+K@3^s~ZzJB<˩S{ʏ5~O߃jz?ܲR_b J?Oœx@65lrgL H˦ݧEd=$c7dmC$d ⃜vt0CLß~V _`#w>;nsDϙucis K7O <9 eraږS{ c{z5gBmF9/EPTtk =:bb 54Wwc g~ڏ.>:gc}`]\{ L3 -M_#h/)=.枿 cp{׉cP~ﰮ m,Wdb7 m _}`/u༡{2{TWu_Ǘ5 12h|3[5t PK9_ۨȮ!2 mEsF/1 kE \=dz/<+]g`d~+tu>I9>61^l ~WϪ;P1 476t ώAgG?{ ; ߟͿ$) ofM1_-40_wDm_ ETKρU12*4$ l{w+ uCe!ұG﵁-o;ci~#}}͗ۥh҅tW|+#KO"5㹡Qg0zj GrM*".sۧUːYB`#:Ywb/CgS YO)WV+: 7C#HŽa!DXU|em*ssѢ>${WKЃ)O_WMDDD),E5TDBG @r)G4/㱴B 4o-/u(4+!\yU_O'ދ;9qTWypMvf)MNhQ)lDNG%bpg9C]%F@d'O?4ׂTݒeצ[M(DQrΩ0l9hBSF:qRҷ gqYW38gڔ./ `~+]MIK(\ ȸAL8$ S K &HjU|7t}1B:iOCD(.(4Uy4$;̫!p~Ou38Yq?13 b?)De)^g>XKܕ-X^%6 #{|&)?#N;оYԷ̥~U?x#d9 ?0 Q"x=\"Ǫ\÷N;~jhBlΥK4XMq{xj .(߬l![--L+KaK!`x%Yr˰_O{A܋bXe3{VPmGψ_~ VFJTb46mϳ~t FCRmoq[)Xo+s!* brKPTx/'O.cߎ\Gz/gGaC)잜؉<rӲ=8z,ֿ6[fB -q=1)oG:PGKp˸՗]+*rI\~q:zQ/Iz8v_rGmxy6TfJ4m-Ψg_;A5|P>jITLv3wbI0/I'-|rnkdvɨZs[eSg<y $\.X{Vr2t+R_hW'6}h~,Njf!ohbD]1@`Ga_-OM${]';:}d*\|Gw:zHlH^12GpS0z/54.u=r{?5&>$/mǚYT=Ҥe>Rc1L ;C2ΛgpBFXJ-lΝTjVwTm9D*.(q奌52u _{ I{2" 5`GdH $}-fI% sߖfɋu(I!PjȕZ(71EҗE.$*oσH=P?+x%W Vicw~m|Eh ^8A3 еᶐ!wj.ޯ7H@ bRH)N8W^17zT hŕpox) ܧxcXde'(d"$*X+7S2iTPTVjj`#u=n|Ku鸂32H؍}3N\.W6.y &t'aį1̌Kd^WIq"GMd3+oLJ~5pGqS4Gk!(S 0=LǢkb^5$Nhtsq_fɒ?6g6s4b!Vhq\)!_tق?8tR\gOtӛ%60=O6+!Ø^6f",`گD)CIape?6G:G[Hyq NRXVa ;#Œ%ݍL)1>^ȻYe-p܇J%8jvkuDJ^aqBԟMn'G4X5{OGOC]b"U|Rϣ)ם T-z^SX qW8OaKMEj< z/XxXӍ'Ns%]JTX5}uKŚ9[^Ah TcJ #hEDoA.P8w[E 43%e>;zIoA?q1C[$>bF$JGav`ʋ&lWȬ}b}ۗ<[ݪwnsU ][6wc]Y"7n%qnسc>"l})_!L̵WIvy>7(׮Cp߃7l@/XEu5rE? Cmio.aJ3cj5Z׈*KmG 28^H,<FD*QaPu&) !F2qɊTýt3@*dSZ7LTmXՕ'+l^% .=v=w)T{|VX4sZ/21a5| Q.tǠUg1w(z0tCԟda,mƘ]{f`\Syӏ6nbݝ;wg -pJ "M(nB\(oE{f*lqZ4O*ʶoDዏr  5֝Ւ cgĂw#zW.ե+X7.Q'YcП8|A "b4qܺ?`Lx5ZsZ.JCTpKd G>:!5&:6:NE@1m yon 7F(J6ئpS+ԝBMSUE\B~MZ]#p\7˒> 7*P&mIV)Y~ղD@W>)ĭ@7rFtۦφe7_L&ytwj\Qɘ-&nV 6ὤyn kHnl}\&'4_CCmw*P\E %/MВM`z+4%vƧu]~ϊt f^t+VVY@ SgY2?)jLf0vf?+f-CJĤl4Tz|ZnQRZ\ZkdFWZFsMp{[$L>E5O? b/ .v;M)/|?`p'IdOZw-Vn(t1B5]b SO}.8;Ѝ"E7($4Fs30QA\3DpV+&4 =<=:Cu_EqS~.[vM5'DJi[ИPi/ ">7;I|l# hmі#ۻl- ˊn#!k2GKhcYy[Bٰ3)AX [ی@{樁∷4@CNUp){.eN2[C!sѷ[ \/ 5Y<ڪ >a hyx:K~J_$pֈ^^+m6]yzJ֑>dmr?!]2Zt֙{H /i̠1n]㲷!_K%} kgJ WR2#g^jP(>dy clbhmUpRssfx&"Z̢$~BJ;^YQ}y3\3}M{J_f[4,IU)jV0 9I :hV߼4[a e;KQSF -> wO3a'34Mܾ08q4UʐK &IsKbXp:\WP~Hg2_P5|GBӻ_܆p'R"܏Ku"( Տ+ H4@#*+OcA#{6q=d.iHa1|5[Xֱ 0Au8?vQ,.i"(1бg&øc}rB_r+2ݛQH1U4"Oƭ֩8oΒY. =a%7HRa@;$4$z ηvϥ84d OAoc(߭o!Zpa bL$Ogu4/9Pz " e_w3RfxX`?]$ rŽ JՂ%k_?$9NSA*K8ۄߌ'" 9aAye BiИ$`e+gX{I ;GE7iUqj1hDz?QE _*bҜoE\˸Z^L".HJaU `L%߮=wa3B)gaӤ!=Jp!?ʅpjAߠ#g]=DT vifL /XщPi]eHhObFt-2y ݿ=l7oޝ XhC-lͳwN|8wk+6zµ)K?&˙ygw$_@Œظ;N ܰͫ,h' q 7 SVM5x53wJ*Hx/ ĿbV~vXity6j+8z fQ.H@.l5υr_#RXf-^ g'|4:]5vtjxܗ:cJl:kwg_ՀT8%0MiGt|x:PaJ;dtٝI5>!b7l{j}sUEG }l-Q-FUߖй7)([Si mW"+"dWIM@D YNaHI$.G\|aVM_C!,ou'0MOù  h뭽\LFΕPFJ( dbIz9iTnJ,\CByyMX,sD6M;aߎ@xۮKڨr #/V]~4 jS0 l?pIP6 /,}B%' yg-w'~K.!LX29^QaMo5N ]*'J|μ)|L &v\:mR'ĽySTgߜf+s+=W6̈[4t* b MmIy6CI_Ȝ=GX.cgsEiR^xvW~%Ui[ {ր3[at]-NH#ы'&>RI"9 m FKQ1u> ZfbZPf t}?mՆ?B x֚_ؽ &gP䔪 w  odFw^ 7V($Z:טJC{$Ķ{!0QSq-3 ẛqya@P8mWBLe #j;g(m6LWu1844tAMQ2!Oƾ/I)-ԭם W P9J VSNULȍ4~VF.b<3FX8g#9-mctr4&n,ׂhNpge~f,fJ2Igl 'H6(PI5yjlBi_}(r. W5o#WgF>x9l:#Nvp!A+q'dyCHrtED{0Czr4OfnX2"WuTcBƭD\bQCQ#\LzF \ma>T Rَ7s#܈жR!.%6] F@,0/ylGeDf$6>|n?:[ #IjqYQd^"n*=PF}}ٴ싑Fg*2P2R^Xn2"Tz'ҶKd)Fr]0~ܭXxFyY8:YF\\H&J Ȯ~y!ATQ@_*"l\;B/!V1\5UP0ʕ \ 9Qm)TQ y߲ c" ?,/|{( /8R-]T{/ICz/[ 2jZmpYuT5Gj|w~w45rmh'ls7P^NrwMJZU1<[Kݲ(Dp["YD3o,F)/TdÇ.8`͏wd!wTP Sv{u&A8yWf_-%"ؼNa+a&?p*Pa]~o:z"Cy'urVw'.va+ uU\IF]Ӷ< |]򾝷Ae4uӫ *r!eh0#e:v60iFitQ |"%QkEQ/rF4k^,+V:W>jYl~4{v%N#wz h0'eIG "i^Y(WpE]l{ЈLW1a/./ajXatq4>3Z JӶHc:WY8g޲q~ TK s0TߝLWᒺIDƻY)6(OnbD['63}4V@3Y\U]*w'k o pdlTݾS9ΘCt ,vf~事4b3ێCtg*MT0B1mE9FnQNqRM (F_G9n;E{88ɮ5] J| $ʐ3iLdeE`ȮdL{[CC.FxU:!r%zk> P5ej5Ȑr]RhjϛWdcdZMpB- iD%n@8?8Eْc20qg ^"wSu~tVP3;[.x~Uv>vkZhݓORcf \ttgŽ'gcu,SS\ =ִܘ`1YC> lѧ@c9oH"oΩDhm3,HxquBUD Lw^tm1E8x̯|!Sk7YHZI ;A 0+pdXwt8u.{F}ˌt/+&q^Qax2-0S3{G vI̜jU9> c]䋈]hO]aIјbEp#.ĽNGJ~e0{9MUENb:jZҥ'^=D"/iЭќNf.P y[-΂–!43 c+(}^CN 2wa4{9*Gh!)%C0MԂJowxI)*yp>#eo\luoذky!Vȼ;ZU5B=>EvQّ{U--`m2E9K>U:!p% `Ӊ ,p%~keb:a rwqut_*" x.ݷNA7#L9ϛ.@[SmRv7F9^Nv?2ʟ @QK :H#:^X@!ڑt4]yeZ䱟M5(Z \z!v6/-ᵦ)oRرz_pbt rHwizkJ[26Y\]BX VFEh/jY^m{}x,xz4Ф 7j@bE< hofXc|J/YnL9Vkcx7暥l->=({'T|﹗!W.ÚpU00YaAz=R$<=E(zz|i[ P}K$nf) F-xwak,ZplN0{/kU{75WxU;Zfj0wBOw! >9&R ZAF먃 @vOyUgQ!3ahS`v-} 5]ůQJىNEOnW٦$ơQwpׂtӞ:WẌf;?BڮXd7%d3{u,W2)z%sWy_[IȰO"mBY+~0^ǽed7/RZ2kLP {2C;]|bQzo4CAJ?A2Usv4%2W) O(*lc =dt>/ND.1'^K/:Ơ/Ts2ꄜM^\`"aU+Vf@,<\ёX?.lASf2Vi˜a-}n8{pC\A'3 r=J9%Sɺ;z[AqbϽ=f.F TαukBGZld`qR;$&k t 1kIQbb6ء C)v m318֯׍N:m;3mضmvflؚwZkZ]KOuwOWuMDA=ʓ*Aa BDWt ! Agpm-~j)1.a J1baY΃Fv]A G9 T][95.vXۘ2,U/Dnҗ0$ݫLT*tpmL mгrk67L67v}P|j} >jIEV™;>$8qUx~~ ^1;ayUۣtIZȒAbI:x,IQKà-QWZΞIOqIlFЊ랢A7t>)S\*W Ll[?e}Y Ya1 ?]5%Ty['&*O5OZgb#!-j0{؎Z#3k؀-YBn5 I  >Nl`?&_FHqy9,F3Qsa&O=ͯDmls!n`IKI5/ ͋ =:\ڏDuntɧhR1P6)I>6E:kj8brdIRddj_!Bʲg($ |HT)#$sjs[8*݆#XLzXt88ilu%zv-iVyf|P8&YZ>ZG &suaV`km:^  rLDO2iU;'.eXCъ XΗ@$߀AUc\.0a>a Yy~ОBYub.UZ PI淩DY'gV(@qYb(<2q:HHBEHCDH#[$́I:&WMυiu/8ŵUH0eKiHJ存b6/2o4P! V0O0Ў%^lYpɬ|6l=Qn\J~1t}i9O}\)$'J56!9qB T\K!ac:фC"MRا5Bi&T29qv DpKLNpuV<tTǰh7 kWHu,`;Jm#MkxX\_&*xR,^ Ypb|F"bnv& hfǾP|e/sFG%7^LH*R1RJo0"ZjV ޾I éֻ:{v?!@.J`a~ f*K-çnx@>R*g#.x7ӞZm/R}a$4_Ԯ|.|}e13|jFw~ְl _SjQZi)\օ7,{ص*!.+uq SeTSuk Rde?,,MCLrC}p]/u@xhqUXOH(6P(u27F6/]~V ^b>lHR/\ jվճVx*>]i^(HBu aHfoF^ee2!pnϣa>m.MAkC7&}t)47mK!a4kx&BopMI {<||Ҩ:˿Wj^hklIAx/Y?5\B1hqB(XI *11gok(Õgt+;Ѕ6B#•p }{n+s AsR!i(\V)Õ҂B3q;BW4(ZSLE- Dh[n%K-(D6U4O{%3~ZTVc\ē$0c" ᰛ9]6B!xJmKk(;yM]y31ItCkOJNjVR+eyc5&qrf"뗓q5cǵsGD< 4]ԉeeUqPƞ z"bwcwa q@ɿflmx )"[)YTXawWkJ3R׮!z٤2d~? c 6JCJRre ;֔=9W:I+6XפOMcL gjBSn<\sk|.|c[pxj5R=wpo 4G9Sx h5?~oI.`w|yՂXt }6hĆz&#tx A7%nõbO׷sb;A.yfנİ3 ,H~WCzaT#kͭ)@s1 |F2h^m1ffX+׮NpM9s{|gͳ`e~n>^Qgli3 ^?4S.˫NHj {8JԺVS(z6uɆIs>)_BI :9˼:VZHBT&oB*0eK"<1vjk Iq6+a;kFhhl8GgvY:zz ؝3D<Bc),R|PֹI$v.mϏw(hΘxV2Ub;^<AzqW8w ]4RʼL(&U^\2\%bCs /*u+ϴ[d2 X.`%M ږ]Ao!MāY!?CL+]\dz7궣RWU`+gof\O0ҹ+kFQHhR\SEW?E2į?oh*yuߗi`ى=M JSgK7(-s)&t/;6^\;xUem )j]Yɖ5dHw,TUWgN y=e@ƶs=%Q+_+r`V% T$GNkfu;=ƶ9PKߖKn*kɨS:fN߂j1;[g!!;wBm:XYX8oCz';{7[;`}[.3_ | d3|k}XsmfefE7\]˧HơO9&±:CI)f8K}u|>|tݙx6?tE g 'r; )RuqԐ>qJ0$9G yXsȽ'=`DC"1fudxU>I` ,s#wv hIal+WA?(Մr|@4q`P5_e_:?6os~dry~6rԃs}\+5T|ymm[SA_C>BhZo_}fU}B|)UW}p댎|}=>6q233!>fzٿi5)V?jj4nB) .Bwzsd^ݠm&nK~6례K~I`݅lJ@BDnCB* XQɰUC YY||CmsD"!3| btsrzk~1vj 94|2G/սpOOV W C-{ؔAh567;ƀGŗ{_e ΟgH?@. ȓs{w IsP/4ۅw6m|D~އvac .s_6{E) !U|6'ܪ_T7ʮ3mzK@ K~u/SC]/qZݛ/%I2eYj9(69Tm ᓷJٲղ/& g#172j*N{K#ʃ]IU SkJ}5#w"!v3NqShF \G^_!4*=}}pun-ILAa3p s 5%z:d4[Yi[X@6"&~{Ll }lAٱaF*er?xa/* .;ZDD& rxo9 KGXi9^R.[u#%yƇ(3'ᱢVnרo5PLanD0icT.qO߱ d9J ́50_LW\m^js '[W99flYyj^ن-jO2$Yۚ:JREB)@6$*_tx:H" MCȅicm:5{UHn! 7ImjV@TP<. gm+y+k;~Ȩ tQ^w*|?bIS,fyUrP39up6I*VgDWVnKlӦr>Agvy?HIni w|r'=j<[/TQOIXę &`ls>tζ,FITLv *]*x۳?K5M C [҅i .zD\d)fUKqWrSzpMkP d?ԿpzпP!jHwD'<ت |Kh۳*x>vxlɃ6{~,B 9q,)M'!x7OD ^.Ӳs6d׋RH쳂b藜~& ;xbuԴb ,gpg(}W5D%Y_㮽}A}=i+12Bc0K+]l׉w9Q+?6' =DPApwyF;Y>i*:懯bc"./jA< {;H$7 R%5Bavx1`nJG4JFWd[$천UV"I5>[jto|:ljAŀۘvw#,l3`qySYx@U53gG+T2oX7A}&nylQ\]St@0mdCkb‚ .P$#٢qoWpm+C7tCQZSN hBP\cs+z*7;$] _њB|pWJB1pBdC kDU_IdӘͳADa^*O6ZaqҪ%RrSbHzk dz+Dݿl}Dç=LF!ѳVESڀtj(y;pg#fry iqvDhU[Fj,6qȭW2;Z*WC^i9o>cة=s^ԥ'7قV!MOv1R xǔG;=tTjrz|5a+#N19 z 6qqciJRv-WN~. %d ȡU9~aoϹlZgkygamc)\I*?F "m{+ _ir/=-6HkҀ9f#pp=%Uv`g̏C5IkKLO=`8 :RIL# hekJQE(s+e-٭u(+k]* 3=x3;Y>Id2??K~tX$Eh"l !?fjpA#DmZy0Z県AnG p`O&#N+NVm_sxnB"A=_at=eb"'Nf]JI^lBtWu]q/Tk F[) 4Ğoڰ/MoB'{a)bR5nTn#"bd()G}ii5XR~;Gu0JlVuCiTJz3>~L' Wk9>wo\RZ͍$W@;eLV*_JNʏ0*,ݤ\4PTẢ|~4#~:boAl&P>}Š 2ZZˬ_N~ClJVfNWn0;YɃ:A$%%Z"55{p85$w+^-5kj^ hwy}/ Q%ʷSP9TTX„mvĔL\ɋu69"YWW!x/'2' O^O螈quŠ&~n]"MckB_]`c;{1=4@||n;׬eǃbYiܦ {d{mX8cp'mZs1lإCܒ`L|mB]FE3k^H_cw! V=5Tci8 S 0nCo+ťF0]{iZso3YM~E_ui% X3*b(JEL !GF`9t 0RJޅ(bj+e ܋4#{nMVbO?"~S hO݂Ҵciϩ1˷te,IC2cY %kTCvy$f'AtwE P*\_2Sn>50.;CKIP|߃6"rt'޴gJv||>v9|ҭ7ێI(+Ȧ L_p69SX9wе-4\wEnQW-4-(M2B hW{V] E ,XCDkF7oL&itc[8 o;CtD7@?\k?;JNQ6%PC,­cJA& -)l<1ў1֒|U%<̗*0ί,m˼\I*6Sfe0$(9 ΌKobK (D#Y‘5cLPHȣc=s~9jPCs8$jʴys[%Zh^Qf$)yS"slκKvxKn!/ir? 5_bN1Fh\?ߠomBA)a`TCΎ uCtjW۪{A>\֦1.3|pZU2f،&gǁq٫F!a'n3C`MvAN 1P5FpD6eIՑ;Wlaa8?/En]^n߽s)v̵CUovC#>5*..k+b{,5>qωdw%B'6ҏ+u'G(8vEq :jk"G0o ab~@ɵk ӫ?~VaU! -ND::961P^9)AǺj>r\d jYP$nK?bOm0JXqI-f[sOqHJutkcymSĴMUC\pL@2M7Eih_)ܻ xp ݔ92:vIV1ְTC+ۙؿ>3DHs7d 5/;i3!`g!jBjxBvo9pY)l0LBRD,0DH쓐rj΢FUG@ TRz:K]{).181',X0x zg})(zܐDHZ̼(6)r=5C&,Z)fa.I?ajϷ0sa\=&X#4ҿlr$H,#~TK#a: nVp9RA!9 U[6Z!c|$yR~`m>q *z\fh2$rD2lɝv' IK&םsIk_0D*T|f.=m>%)~L]SV"V@A!ę)X*35Iөk2w G;?"W' ?|\v898=H/";^R?Rkr -RwZ2(5~~;X SG'9kǟdbw v D/B.M6B3 -1Lxdػ5C:'Xj'ftD=됼@,JBޫm -2hm!0u7gGcSTVUO&uuﱑ#߇Z5thp;]ɲ_( vvQerl[& ZV@XWfp8pH1DϬeGDUT(v5M>1+1.V0έ磁TlW U 3A 8Ra5'F?5R?=5]&}'rq*wzCp$yQѝxr}ґ9gʖ9"?ھ>L>B'X袘0:[ Uc YͲpbH4xӻpΦUꢲ+ܦ76xޫuי&i)! 瀽#GPNxVE6Xg ;"[EEèC+- ^u8I "ՌXWJ[> M 9m@P~'{j85zI?TU,11.p dʖKMhir!#AO3#;osqcʳmC|%y~n4O -? π&=6,Bءy ~Qy`iDJ܇풿#M|ƙt}G ⪅|W Oثe쾯fB,D^A@`7ǖ:k1)ȧ.Q#29v<..8ute?vLQcU"w+0Jڊc`$deCg0e06M_k@#:!B,3fΚޠ3P1홐G^twBoCX9݂::O\;ܹ+E*Uo@o`(9bThBv/Z˰y aQ>wp4|Lr?DFPuNy?SAۼ^Nt 3]%+xFYti{v@9F ?|}B^Lj ึd (?1_8:!ʼmS?:Cպ)X!d} &%3 x}6'˦Xn Z_nrJ8Z'[Up u {s $wj+LtSAƥsj|yP'Ƣ2О1L೧깚 Fh؄1D 0s Q˄![ A?FQt8=&kIRºYۜusBФ:Ct!Q텀7.D t6tǫYnǪ̡U0N!skwXd3 [;/Db2 `7.%InhHM3:u,602Ϸv !dH䶯.RG n[Z[m88XWG6S!tnf>,j1AuVR8jTN={S]U]U x粙c .[ L"K^ vא1jޑ,X~1yRё5Cos\MG-}Ed_@ߌ+8Y;1 Īk We:!y»6QbIaa~[];X#=.C󋅍nv:WCQ*N|dў=V=xm1g Y}C턔}J@DR{`hJ%O\j1-+ٕ ¬$NT-*#c,nt]'I_ÒJ#]b0(pl$IUY$;+7 =mt LC/TmVi gpdUa͡]h~ЯԨEsQY?J;@K?"2"WEfAM`ؕm`./1/JF1bPqAb@@EPD|AD||_W:յucG<_|?d3lp\|7s[mkn޳zg l{k?|sZ>O=ǝ|o]g㐏?~myw?\[Kwݼ}LJ_Z?_?;n+wn.\u𛿲?=aף9ּ=M>u]zW nyw69=|ߞ.:n^mGsw}?f-ŷzuwl˻oxwG/7xE>?7ku=xkW}7+?/zs|7‡yN^v>pϽѝ~z}]|3?[-;9遷r G\oF>y=]yG՟ZSNGxlwYK+_gO`Yyƛ붽Ϳtmg-<#n.;w得]_ ^xط{Gۧ痏ut7;鱓ek-石 nޭNļ{Gnom_~b+/kt/~0qnoW=w\ﳎ_<<_}V?Ͷ忟~q뷿{=#_r̟^f;}_ /?cz~Y~k_vٓ/to6?O~pʕ‡>}YglOE~ ָe/ⱏ{t\bG?qiM.[Ηdۇ{V_s'}tg9op;`S?{Սk?u^KNx ~lׯ|wx;ZuȽ;_:ůpv[>b~g{s~u_yѽ'oo4s۶y-6_ewnt)O=kӫ_?/?}]C|׼,h?rF>|o=e7xўwF/c׾G|wU~}/y^v3>3yӋ}\?pz}洃sN~ןʯyСǏ}7se!{?-Ϻp.krirqygՇ] _w5]_1~Kst}K^}gu ??M<}>qoq^Ǐ?zF?늫?>^{mX7~ʿ7=ﹿ?Wovp7}?x:kx6kWrͩ wn]_yۜ5nxypK.UGS7#[Mmt^'.Z9mrsw[_%zovʆ>ݯW-{{/'??邿V _k?9c^xxgs[.Cy;v;{'ə{pY;XOW?Ώ{[ӿϸ^q~?~˽/nv6y~3ZrH?֟z;[_lO?}xc]zVҷmxsK6,=(Kh3{7g`&{g{M=zfG^uns4w{_ϽbcEiEeIyJfWd SJ9nsy5ibyf޸HU'.k+{]r. Loޅv@{AhŒ嫖hO),+WW'Z4ؕG}ҿPߒE)j׫+y ޑ"  (SEQ44E{MBmΘI-dIIݞ=߳찣&^Ya&¬g"iݷy-ۂUcW͞Ԯ4oԱ cVm~{fC-C>"ſ94q{4=v@o A#A*nz.E;#rdnA?u ~ FD@N$ްL~{u@DTXx~O]3 8ީ"iz(,P}ɺ.A8s VN ? @(V[gN$i)V!a cdoy6xtn#3=Rw*cIkIFxnuzOe&Im'iV' H'*SrnLf5fdm-o887x: [ݤH#m(^^eZ$ION#dL)^̼4ߺü˲4Jyo4\o y"@Yڣ ۉ}^.ޏ;k=Gs13S|il~5Ⱥe 냣zXՕZ N_YdNa׆Bwl/FlJ[:V )6㚨?qBz#/`<ȏmzcsL⊪?RFG73+x+ny[bP\dB!6<.yYb~LG?T$[AA}K5('3gk")M<\^;$YKT̚;?j'*g+p0 2- v޴g} 5j{P鱧$B{p#<#ءayĞfR ,މiL]`t'ZR+ΣKS Fw'x;яVZ 8t SθldH$R0ALR`NaC'boUsnDPSxtrFmZtiƑauSd%œ$v2]);k O18* OyDz#CG7-IDYq5ik7ftʽ┢QV]i'tjʊ,#A'vzci[U[5촛ăpQACK -c":yHCs oDtsU"UfHEw5 FtFg?-<(NqD^kGy y6nEc +"Olk( i6n+o).vR4IrL5۫/u9UFTQy$¢`U9E-P%„DNk ,눼\1d$~i:>X,rƶLN mg2EYIB%+dj;M=t yd"c+$(Iɴko7XV裆)9˪GJ&fmJ U޲$"-us_ܜc%tItig{8lOQ{L)uJ9Ӑli3d[8F vq"Ί|өR[ƧrY\]>F#[У`X+ê +~b7P`X+ê/E!OIB̬ ,<84]J(vsBOvQ^Vmg[9y(oR ,":@qX+HGI&#9ƓϻڌscE٬D 6Qey)H5XC1l)hU'L* Sa$ySA!V>)ַ`"FZ[e8ۦ@,l[S9)֕8 Me8@[6b5X6a욌6H1ג㍘B뫔RNLvafg!mam6}*YHti1S\S÷k6J0&feVlԜ֦\ M'r-Z$p$xZT_hR}]d5/+3jOv  C.2=C0a!xrbn4c k18ǝ\m:Ѯ/%=X`KԉxۉJ}A]}z9F3_˖w LLxC2u[*e6esai&hdm'0AۏӶe6mۖ-S7^-eꦛ<$Gb3Ro<긕#L`(b윌Lqr2`>lFn!\1Ϙ2Ieo3/`ƚ~\M5T3ظm)j& 3vPo nd½Ei7ގ8َO Jx;coyB4cxE4)Odc9~7o006?2 խLmK zPy̨VԦ33 G9 rP줐FJlCAB&4 bPJHdgBbQL49GlcFD0,c88,4=ЍiJ(FJe0Â9kFVdlp`cT cZnX0CfxD;B88VOD9!XC0\nvC'F`ڠRɒUh|QpBJ`l G9u!3OH )iȑ!@za 6&ㄔX.UE]fa@b2G w0#>U]oZPr]b+8 (98M.!8.raFA{3(F%)h-$(U F@8X Ɉte.6fI1fD1]詾13̸Z7"2e3vc5څ) ’ x;10jOk-1na+$9 ,A`fVLqߐ| F`ܐnHtI,@8C6O/cHG6Skx)ahSw!J)2rmFjCSU!~?=&}~E< ar->Gƌn\<7#~Ql&x-Lvwedr͡ەSZXfzu}BzKNY19M\Aa0+(Zo K <:qH(+uW6ԅsɯBy4L leye~6*Y<9WAÁ#uΙIbYͥϛ$L;Mf X&ԓYT`l^U`铹Nnr޼LO&9>#f}6CW!p?@QM1 T܏u,a!m:ea@# !]F0vTqU 6qV;ȑ1Ɛ&_utΉ~/֦ӻ5B?=ظ6cCg\X`ljY Sa4]8r?6Z)}1fE\F唭H}1 (!R+~CHt4L` 7OQ xXfP7|Y߰>nܸD\%]?? xV4sR)-FiFlařlalahKt ]xI_iaFLݧ7)8N :~d'\G|š[e7SL^?qh_vS7a*;f&lIS굄lq QZk9Ck}ʱF 7ņQL ψ4HXN^r>دr l}~C  `Ө%oL|b'PҋBGLGt#G8OT.r(͏ C31D&$J.Ĩý>t"j K?| :3߀s?2ww{8MTŋyHc#J!1 8Ku8{:ȓL1VzbI7fc6yj"BF2ؘ~̺C>3*RqU<k IhU&ZASyZ)$Tʦ b_gn Mn8{1Neš)E dn@ Y%g}(~Џ/O*e作~5L3\Hk]2>M3K ᩞ Q58`hRYf,O)A]ǴMTuM9,[) (y )Dd*ui8φ nuQxʉ#FȋO䙧,YԬ/[$M6 xO뛜Pb)6,nwsBvh9A5qSaIyWq cNS+W4AD73Ss[jeG| (`?fFH.D9E۲ESsY9Ϛ;EBZ*0[Lüի/[1Πqcrc۞I.0̷_,6G@P/2؁]rr'G@Xez.?¿,PzdA˭K5_ŵ_mSkaGenUyׅ{O?qU'+VL1|GeV>bEGl lIֹLxV>qB L~|&foUbEXl[M^39MgEZWصEswXtz{Ԋ{/^rF'V\rK|KVl>Ԋ23}vx8:Ā9Zrjq. n$՞:H莘`hMOÐ&ƈ cNة[͎um&uy%$Ӝ_욢A`'*~03&f-3/K;WSgvB6ñ:CmG*`s2iDN'yޯ%"dgT>QoGExuaDkCTԟv $"C|k/|0s! a[}p]6{2Խϧo\;ƠiI ʅ)aO}#+he +$,`C*hxq%"x})*iN߰9m7FF9(ugàUCxNu:Q,{|fbg:IL8X6[huve5e\/7a ߙwp׮y] nqBٟN$*v __7` <5E Z lh:O! 96u3}|d/ FVSkq  uuZl^נVo7c'$ %V_H!=a޶ JS}v·q0ǔ˾#I5(u5vT ,ܗy |"W؉q# C/|A|aW.lx^3|~\Z+vWKs| N~-J(|#$hNv{?o3RB_xf|![Y_RvT: |:p*aW&%|\W%~71ރoJu FAfZ O>0._#q #c0_&B_|eH1Is:ǫ7u6& %`B:y[مz;2zG*pe_UlPmG8+>ϫ!^oObv/}Z6:4652ɧ" ")΁A}8J>Kہ/|C VA4# l_GlB*=-!On' q%^[_ nnC8|پN7ޔ.#}z;in}↷}r  {dYKѰ}Õuye/B): |Ψ&Zz~-P9.J7\7sBQFprcNq^RqhZd`% |V>F^>oO|Q'ޛsF^6GC&>J|]_J7F,Ӏ/: >͍QTyoĎcpG@|>.P\s| fѷK'8KZv^o0kUH}p˳>.,AXϧTǏ >~vBV>`oFMi">^r ` {74\;/mo UInn1ϱ 3x?BFz&prnq818ŞE^__ }# qGYs갬6[>biq}9%+c M1`a(r/c4NaĆfv wz=(.)qL f}EFneu~y}7j)4 \:ͯo%0"Vc X^6~Xi941a'}) _},Ǡ N=6)W"?fL NׄJHA&+Y3[xOٜ-!?(sNR t`oq Lug`vM i+Ј[;vcEQR)vlTlPkMbv T1 GJ]׍Dl}GdZܰ7W8C^0}Pj__K J4WS K*%}d d\C^bX=->KP/`P+NgdTV9B4Kpg>W9+Pe-H4$3PI0_1@v s9gpDO)$a^vH{ 'τHr.oٍw` 9!rE@[Ͳ֞l_'kTnY#AvC& ^8K@q[bZ|nKlt4" z ]!A9dݚP_c-ic$+*&9R+'lWcsABWD$F- dA!&0"3b2%c<--B0|eY$0Ŕޠ.W t[lrcEwhŒDnBl_=.:M3џo,9% \j7ZI=ξ˾V+q,τPߏ[':n|)}{|=a oDO9E̍rjv??6j{[??j0))% bXqVHˋS~.(t^OJbKXW"nƅH`J-"eySکK_77ze"ѝnJ+ c1cNjJGxBFH=ցyy/9{ E$`K\Z}=$ L$'6򅴁[Kڡ0}*R]LlB>XJmLJM9}0=ϳ1ώq%1`1FE_Ҝ,h?= C;NMF;w'qP)<紣pغ299)]_%<\X\al}\]&~1.GX Lj!ɹE:BL`%">Ԁ3ԑKdӂk-r@eiR6cJQH^GB㣬ˆH^?(:!y:\*}sb1} |z삜Sbf\Q77"gyixyDoUySg_m7o|80Cn(o[[ :@EOщLq2 zq+0JSt#R*q'qI .z_B3"G Vn+8⦾YYH=0|\vjS~OSFcr*}GW5b< _pb%}܌\|YU}A3z]Ik|nj0}>.>.E_!r1^Tz3G`rQiikp̛%O~е?Ϲ z-sWXer`K!^ klA_CE_ݗ=Bib^6(/1 Il ¬b̹kNq]9g)5JLjf &g-sq$$g}vALY!Yx@@Ej,w"r[ j%0uUr/Ġ^'킅=c/aT˾D[>([U$%>#"sTKzcX ^dJʽqDd;uV!2Ńrq {+tZ<}={]CЇ kx9%=P!4}\qM˚ w4SyU7,H7,<גcZR">>J=$q)WJ\\6^` f!yJI* |=q`b?sċu"rXůې%h䀓Q׼}+.蠴]_{$l]}jw8<-i&eq%-i=/h_r쎸e)fA:5AovyܪYCU;/]өWGDoX-U=eVL<Wl̓vzyH|oL=bPAh' r A'@<,*V>{5S?wv>"iq;ۗ]j>A0*JZr|$hv:dn?Lrg L| ]s|p9_y`L&y0-IM6y[ L 7Ud} ycϡx&W6zg0B;I<d8%82.RN:EjIpe/'#"6x~ J&%"5X&' dàWߎsH3avq`'߿$M`RB;SKaResyw`<_X9n8|o|גBX Y7oLꇬh|qL">FkDNTiJ;((qį/%h"WDm7}LJZ$J_ɟ8_!wz6`ӜlP<Q1}ţƌ6Gy"%>+uܴ<}&<+aޖ++oNgJ 9SșB~cgʞ;X!.Shnޓۑ})"X.k}0.|*رiȮܟ[>֗w9'}h?_ԟ)+2 )rVp*|Ebi$'Bi'w h'^%0]Dp͗cPt{{7z)xbՓvI_J޽>S,%o3G71)p< I8J_yO]cre9FQ̯=10ykZ$o?i&CO~PZ3vWF!ǥ/vʺq˟QE]LS䔗,Dj}z5ܾ{TakVٗa?]Hb0\]/]GGk*O^iĐ rӇer@ _7RȸW>!c\y5YvǐWk>$*-0l >S$~Ax[ kWl[{Uc}Wu;0 Wޜ&1AJDt 0_yo{^kK4?SU`u;`^߳F-+ nU2鸤 1/WJZI`/^C7wNj,vrǝ$,xo(09w[|MZn30d0wbysR/:P``}gYpzF<%P I(aV`U(4 }yPø7ɉvT!|_VNJL|m1P!n Lv8\;N::#{1طŚN+>1rV=e!:SiF4d b2noOd> i*+GWb<#"Qz ΍503]+]닙@ ^џyFkb3NqC;"~ R'^q)Ɛ;fsq%Ll)`x>FZt$!;WTw1 {A^ֈ L3MWvglK&uK@ d(B^^D>|XBr68Vrn98!Tyv&3FO꤁v<Ἆ'ٛS^t̳[e}El\+uf˹@]|g->˾ܪre~tz yg^濎xLVFﭯ̃b{&Ԯ7jb+ۛI~`I8:n-a[*jk }nRl5 H G"vRLB(}şJb}tF;dجH1^s^g70?"`(?U xÈw} $I?wIJM}l`B<-gc7Z^ԬN ک"%kN VqQF$G0 Ҏ]0^0./&oB o?)Ls%$Jɛfx?s>>B;ƳR+iOa70y^"׍=if1*gx}{r`Pda7HܸF*KKW-g@SzZHE{3/o>%o#0Y&y:`r4I?JMu#$a渶CCrY֗Y7eY7jz1Q}=m3. M!Cޖ3.HNQDU@Lb`0{Ob'UnK&߲FѶ/(LoGLWWk_`H;v!A. ߗ@~;a@ >1pyHL d>LhO d8z2_TA ~Ȳr.ɐs\ }.炽u!78>ɻi+"> g A) s@ɛ{(?y`R{cs:2`r|h̼LjQi {5bck;/d/(,x98\ìﭮil/ 0.{xqL`'&͐ }nЋ ?-a8Vbvcڊ GAl8: T>s? XɁp( Fmfu^X=D6#s0TtPDr U'iGᵇ0΄W:T(HLibȫm *6pVK־f^!Hax$?K;swβ,:_`RLj䀑1zxEq^=0NO=ubc-n}':cUdN|@\t3#J@rlA_q^X!gy[d&%^Lpi'y{`|Ӈ13GY >9F15ɷ!}9=Ӕ˙֒3)Hz[Nƕ-nK.|0͹Epc_`x>}Ovpd*Ll~j$7F)hb<}ypǓ# )fFNw c%ŧ#U.gxA|0{2|r^RZ&#@?Ď5ՏaʻB\ޗZN`rS[7*}/@'ltc p"{RIGmnxrv E ycy!&s&lc-`^309kq۷(%g(0CT'9I0/<-=9sXFqȽ >&ɷt\&+c~_wD`eOW0E7E=t&vQ+DoNj*N/3vrޮe&v|CL|+`X~  2.o8}@0L<09/w]7"Ra0y e?7rfH;Zkd#t-qJ<$HYÌ85 6kZ8le L[Ochq6?JRVI,O 56އwd7ý L8Uos;$?]r<ͼ D6/CԿ_(vڏ|\"rOU[7(xM+otۧ}&0:ѮȁZpҩ^{-9ij3=keVٟpub;{2W<oy]v;Ο??oݞ(`m&z&fU W:aB$gwah.ɦYxu@UM7>tw8 Q%Q(PPEATRLTEE@EwùJ~y{̚5k5ۋ G v(ycXG0#if`"@^v cy(([lU]訢!X_e+5s$u#`4zGkI暚a@ViJPP&5@N+pj)*@[Khh'ym>p];Ԗ:`D<cqC5et٬{zMhxiZmwTC7?dZ~ s{ԸVJeH0s}dѫ'Ǯ}wcAINnu 59 r g1@(9 R78?@po

m Puҡ];|Vc=ߟ7|iLؤGg96_Ivȕ7CIe.6|prN||u/nbצ]rS@99> ˠȨ۟d\~qi~O놾/V[gX>ɯ9ZKx|sk'͹x+%L+J46gI 2/rdEM'f =yf-?E[>$Eo=+B_q У^Z6JJq\N#[ؓ٫_|-Y9>M:c"T-LU|v+sz滈wڰ:DAFklہU[8'8լSQzg >}lw!.cmJ_TSP ‚c*Mͷꯦ..2]mv͚TUItص2cnQqV+]_G^9j˜ =Ӣ_Ž,m]8nR۶#nJ\ധ{<({,؊z7J|)N4:Os h[O'ts5Ooɺʶ[q=addzm<_x]{Iysaۼa$K$VKQGE>y|]ك <- % [nzc,vk~sl G{`A(bp0v/#D. -= e]9"^2Dx\嗧4@0m?t}F;p&f/dѴr 7~zoS>= _/@!Q[z^s?]ϳ1Sh[u‚:T#~ϵ4^{oYGjwd'x´ح41}:cir}/XvX;=WJBp,'̄v$&P]%-ZU*mɎҰ.תpK`ҥv$Cn#%h"N;|0^$ L`'/IÐͶ|T:-'SBG!fJƐX 6?l,0Y&/GĊI H1x,"ǧeAN `BӰxDhDXy 7*~crQՔs+p`qq5B.;<ۺ{?뤵I3hTTQ0ltkw\5SCTͷVlz3}BW j<Ô{uwbfocRN(,g?qq 0/faٳE 4>}]/3IP?[Qs 4:rff:;-%K_' ,ajE9yMfǔ 9/]@F Vyۈ]*^v4>nrj_~q t-p7B6H)IK̊K)ﴸ1ʼӪp6e~-+e;k//1囈sx|wr ~I/T`S}.B٣V8w,ݡkeKNkj6Xy_*y"5Yh7ޣ' Tr-*w?k+=u݉ӷ:%EQKp#;Y\:mz/ݕV=VͅHZp]8q^r6Pi}4\w5yvljJaNJc2ESwևռ_WT[X?\W4;ݞN@IMkZM:߭=Z:`5<ٕO٬Zlo}~ ׮4C?FRdɈd'>jjx_KO9Ӓ]R6~L9Iע0. }f׶nV*;dٽ _U޷#c{ٲ=c)6{3|;=8"cܥN~zx5tvS&5\ow;~y|Ylnz#EKIXgy*j7vg~$CNՇ"0o῱pbCb:bgϵiJ+W$7<^KXl^9̥F~ЄQ2=?WV~c}?}XEWLbg_3 c]<{DDde"(YFe/ZNaB<C##F`iTxOd]h}J!& 2,G`p-:Ɗ}|jJ}!`ih2 w Du@XI3A&1 d4$2`" I2 b sF&0T=_ o zp Bl“0) bIXdLbFȘExՙϺ1vR EA0?T,  +Df|bJX,3y%$%T$n/! 8DDD>E,EOb}2lXY ٧#("#d\D CR8 # a"(cA#~,#̈ʜ .L_HbQN8`)8#GD e-I)7Εm?9CGXXRā27џ" ]5 .V <( #U(<WoՁGr?dj]8vA"CAkFyroQGN.T5yQߊgGQUηw:8ok=.*d=mW1>*sVOsO Dk4cnVO$s&@}Ƴ7J*yo^F}Ǹ9uum4ЍٝVtzEFݲ.SU~CY8랾nM2qo_ي'OQ[)4%KSJyMLOYASuLYՓ,R_$S>{w+DN̈;7t*Da;-F XtGnc. $ RH}P&<0WbDY~$BdiMOĢo)?a() U#/v ]|Y^xS ܬ{h'a$c<:8'=2 iH d .2Cy8€_sA$Q`șM,CnB`,)1A͐0gsgY\`iGf ցG=I?R0EA; +򊱖KDe)a* PX{^Fo+/xCTX<Д4H ޗq0\@ N QcO`)1|w$fto wQmY] |Ao!#!e?a3_cZ:i H0)cd,sz@o#cNm*X)W1? n`SiBj>arnꁺ`uK~+] g,X $mWIX?kѠT^+ؖJ0VY 7JHBIa/뽹OK[tKnofu!:jmKݸ 0V%.m1OqzsF=w6HQ/BZd񗖰3Dsz>)7`60p=cg~<ɸ?ʣBҴX9a]PIBTR_Ϸx!)?RS ݢ?my2Dlx${B^k!Z<^) /qJ Đ7%\E i^Kq6Nl<7͜XJ2ȝgmHcE& suc~xOؾϝ1cHf0h oQƯ@,ӊa3Yv0JbΣ^k5+ZgE& >2ZKEJD:_OqOjEFxCu9~#̂ c HzF4Ye8BEٴަ_rݽ`Wqml>{QBrOW|x|W/Y*I;i +J-tI#WmOpW?Ԓ謥euulvwWq5WѠUH_vtEg+v?g[ުK˓WޕHfCa|E]ኂk'ji<8cmAPp[/x ր_-Qͻ~.[NJwلNz9wcN2윍C \^\s4=瞹z* #f#6Txw=D3vfb2Rx'2O & y!(KG^m[LB(̰˰PاDal1 ZB~?#nޒj5>aҾ4a1asvLf:va6ƭ`׆9 Fa9L0G"EƠ9 dʯQ%,wr,W!t/,o ?d4:Bb//V~tЂ/ !`?M6 xT@.K0t\NJܩL.iSp$)̲rdIC`42 -H+ȄhQ AAAה7f;BL(@ %Y(\'!OY3dwAK !Yinmt!KEpNv-'`7yHbEɿl(P4 yoVx$hhFSp?;dK4;i, rGK#a3)HtV LGÞo.D3,|ЅH,W )9FaJayd׸jy D/𬂻u 3B>?/% ٟz@"L -@bH> 3N 4-U1=K( "8[JmXfK>;j3i#fA dY^2_:^ƯC^05x"k;?j&zB\8# (Gx٥Tn ӈR.@])QDGb$0? ADaA0EN4Dˆ(vY Wk i1O̤Xo0孺!$ 26mn^HO!BK熐+A҈d?_ Apz:8+.a{GHI2błJ+5D -!M$o'^(2]Xg(g-rvăKF)KRO ZwyOu:NcՐ  K^"#MqP<;rh@tÝf6%V6nA5:B~? ڭ%8'o }m˜+/Yw޵`gp ~ͫ D9 8U]JYKq#'@diلDrK"9hr {F/)_lR?RXQPXulKayA!?H!3$"cC11L B NuCn07/ `HD 5pUlKCa( 2<pu(bȿg pm Ks =.&.FFP~T(gA2@ƿ|p5 C1pA$xOBUP(LT!!-> e :P KSXKtJ,K"KglGDa* ëiƷ !w6*?3Y!_*fGÍLԡۥ ̓~) O@ (ґ?hh*ꬢlX?gc_b d Gkx“H륗[ (lHF@B@m!؋,Ht(B@vR. P rQge(ԟ(7/ė"cH$]7agC>V+F,aT5 ֽK RXX’z ~&U)`U8Bb1+2aD*!2+!daK#YY4-,1UEã"Se4@D&.q  Z2h?E Fem|J~ev:g%3OPce%_@i'W  ubi?/' Tց.RJd< D<4ivO"; +Ob9ZKa^xb (F^#a/radY7? 6pL5NjnAkG)/HEz <,WlyW DHh޲OΛ^߹ӳAShERbzo0Zy0egqoǎGߦ9ūz5.9)|J/HrE{rEbEAǯ籯gwvpӛᷲFӚY×mO3P[(r%Fk:wZ`(߫ w7gšӚKe)Uz]cZ'jBlU}96ŕ/ UP3N^W}UTSQ/{-U_[U# >ĪzAޑnsM(ixu[rUvkXЖs>k?kȍάյG$ ˖) Zur2S{N^- X,7 4~ָكºscq 5~lzO3vI{q-Oxiy/Ni}ԘfP哝C7"\Vӻ؞7K.<劧ūծ&;$cb3&oLu >DNTӖI9d< 5 Zp(enČQ}9)_zq,|~ >֘|H_?ϭ"a(r"m@B6Ԁ}>uwR>R-Eg q~}Cc> #۬`dLП2=p!| lα5)A}͑l()^o-2u?ބNy7쾚fQ]0b!5'jv*+,pB:mίnחkקWU8)k/ "{JgV(]ձtw["ƒWvTp|"E+j$hX>Jy=;nC75 #P%2N{3PB Ni!\._#y@YeGcGM-]B; j'>Jo3M5W-Ɔ:37)L=ewo}+xV\ 4{-vGMZNb5}^L|5ozyz.ezG1zEIٞN gE߽~V8ч :t\o|%D~=&H)>¸C{&qc7I\t1]^XUud0CAL2gmjw:PZO=×kObٺ'5MwޕSisO>>0;|i{e74kzn J=SSbcĸKwJW&} PlFokpѥ] >_j;j5| EF{JZDV%da+AoDގo,-qrg8_Vj[Xa%~irQ9p`xyWF:N ^n=m>;ooSghfV]_n0a9hWf nyʭR\+`L3_{Tm{p,nx>vK_6fewgi1f{=>~J"-rU@cޮcb cL Dm*^ta?Ke1X7tʏߊ_ںcflOyH.tIh  ~beeW6lu}c:hOsIﯓRU{9m?ȣwtfe->ggx_{zxo%6ʦіrU1qymAncd^Onp>U"{ի4,x^ }'Z@r5-NS}rnցFS-piZ[JunF3%hBݥw-(#7Uyx4K 5юwyvU FCtI smĎoX=x2׉-f+C5J+БC;WVȤɷ:YWrE "PUڴlGlo *-Nф?.^!ɬ|Lҕ̎fBe^&T<^,{gjeϳ-Evm?rB[]Щ؅ĻE_=BFw,/ 7w=rQ`LXfSü&7?C &l$6쏾]dgחݻN?zՃMS?lJftC>]z:߈)o@E5/Xuh(U0F `2FQ*S=X7ySG |˶r^-Mcfd}7IYsO*MSRnACCƵU/|'an@ .S\N?Z%Hϣ7?ӽsqa.68m MW>lk}!#yy(޲]1}Dcf]'BK2_q/\r\N͟^T \}ٕ͋ Cݼ1sTb*iS/ ʖ^E]y˯N7u$@Ht$ ;FߴC T uMʺFų xVx 1) DF#&PeB1Z01Epx w`a5H ނנ_qmx2B_ `eu+t ůQEnC`a Y GS7 eihy 2n.߄8~ b"ў ;أk)TVI®2md)Fea!S-5+L|ǜ y`K;]ίvǡcV>$#fʹ{%ο][/U1 ɹ‰3;K7ISsYb+_v-O5еUsqV܂ ^:Z< ;ʦkIԗqf,W3 >A+H_h; [NXvj[ʚ:{De'/M{ͳA%m+zG{.$ӝS:G>n7u& $l.>r6'ؕk7 7ʻp}x'Y5]S=9RBl_ekr\{q̜Yr9k㩂 мx6-]pmc+ NNIY{4ll/Pa#wR/rzz|xJ4u]3ܦsAF$Nw뜗'׺fӽ٣|1{n9: go{_ẍGKd \{COp3԰~dՐ#z S iwwf ׀O<]2"W\M7xI޷fA4d/'yY+{Wl[Uiw@nr電eoWwJg3qOtAbMUu'Xxvrxا [7CLQ:T/)|*t;ʷ}kzm4Γ.)nW<ص_V -:25"cՑ_ށ^/ Nz98GZD=<:B.RZըğS? mmn6xˌ?y:XҏGD B[VPcoZW6Ǜ ~e@eDD1Uoo9k'ob8l<&7?fpY:a}^52w<(a7M_1JCW˱׿G7 ;kY~p3e6nݳޝg:ތ6-[뢅LY¯)U0`YWunh)Urқf6OkYF?.Zmu5SϲoWҥS2qGTne!U,16!v@L!8&'2ʺv>r?FlSS}[w_oےN%:R[e堵.G+hbR(6; #.J u-v}Z6Y}|P*U =M =u0myVctv~(xtucq梩rQejj< c/O{8D1ܴgzIA-MVzœ\d[=ND)Zw8I =Lx*B`IJ-U]}%)MUU>,ZefGeeYS<{k_ NwhUo'Z5ÍO SYE:[jT57ĨE['/%i?!UsJguُ}>Ҁ(V?Vqt0ND}À2EeN"'wg>IFr)JP\F Fi?५^@\a)/r Cёq6\/ ^}Fz ojOyt%Uo^Q'VQ4+`|m!?U#'緩I>^+<>aL,gDGi]]E*=}R)MI£ŪT=3ѵp# |%g8xڕ?Svz-*.&y>V>pCr dv]ickO]9+Das lCdDYW])SzSz]:d%ѹ!"VuͫgfVy.z:uDȅxE]; jʺemr]2LQz4e>yw3Ok 3n|s^zxN˥gK"}G8o-Ըxּ~+x%_Dğ F2M_>/-dclNvFZ7mPu:[_w{KN }CDW3v6 \> ֵ'ete[6I!;vTp}=ëbܘ"W#z}OS{kg뜶w"tP|IH܅y n~Q JsVZ ȧ#ꏫ&ϮH'\Ɔg5rjl|yyP߸U3޻X\I⸠e6DA^)^ + .@h'&r|]RW 3eEi naִ9JP=d՗<;,-MqBjjB`Sҽΐ}z` 8o=`6c2!Bb3wsce(͝XX36=9S +9+r)f>nq9%"5Sh{joע0ur`Om9uӀ*!BnoZj<Mvin8637[<C6p Yˈq,A˸Swx,ZME;\ =bj3v+RGm-^'L|gHR]^]YVyΓ^Oz~BLd6{2g/z2S۔ 5 .5=ZatqkӬ (1w<^FQ~iň! a 2+ DoqxP)]sx:y!'Oj*~#%僊`?'9h?zAF?|ȿ޼6'''gRigrYL!153>r~v?7ix_<] b"N_81c b^OP'f[/li=~N'H -y|( c0';:p>MP&kߓ\\Oe= >O:GObga(qнuS; y xWxP,LXf2>vߒjO' 7;8:J ʵ ;@ y jC{(_y 6t^v BQd&Mx61z7$p B3 ͑,qQߤP. a8 ՜mNniP!)n2/Ns/4_vC)ǃHz! \fNCĺ\ &UpU@[|?&.1WŃ2S< ın&/hCwU:lx///*k!nɭQژCֽ] +bHeCZΰ'}VRG"^m^ԽzOyk-lM=^bRB-drq<x?k?Zz9O m1Ө_sSw( 6k2gc)|G:~)|s((o54 yYC:ԗ5BUI6ꂝ cl!m_? ++j [ݨá xQW fcѺԧBEͼ!yZY{u;zǣ)el ~W}cK_HKi=wa"Z*nv-=\f?, @"!j`%,,(Z,+P jxL"Z('m#їH0e#ӯ"؋QGҳbP8.Ŕ[Jnta{Jԃ-gy@D5#{9O\@FESXW%6l f6JIMQܴVkuUIJ#}A҇JW?R<ܻe&,c0h 6( %T`/Y18;\dy8wtPDlh#JބF&؍J<9'\k.e)\d;ͫM`Zw2>^LKzBܚI9fhΪ 5%",߿կPA: aeDW\m4GS9#UDMl{ `ڋ$FU55-*&@1ޕMy͗.6#ֲf;< Ĕ'm gH}DtՙW}eGא[3M!¶vjuh[ipSf.Guk0OϽ5LQ嬕~39#^ԃtӧ. JLRAN/XC8 jA/_K0x%G#\{׼bŸ2@֟[ܝňͥnݽDfS k?!o(jWvbK ~~ "M(\fU>;ا [<7cets,@fTxmazE. m )D&ng vI9$ 2C!@?#P-mo_ED$ˠͶ.3'1)^ u?t9:;[ڷ]Zav`w@ySo\z?EM`>uИ抃tau*IiUpS+2JCl#K]=)՗<*n)z=S mL8bx0x$tvxd\do֤U"h<+9G ? d @om8*aB2W4D,F<"LBc5#O%8Q (UTl[Ea7݄H[Rae`G>y%*FwpOH`ICfpcv4<5!Q|&?:흀X0N-^) i^ _ u|~֭>Rr<9q-v"THӢ+|ړ/$ܺ +\G_<<Ǵ$^3Zqmge[RLN֏6qKfHjL9Iv)/*zV-G}{Tdv&X!cNG=MFYjx3tAkz*|^e(& iWiE\p ߱ L|SUQ 5"|f6g$z|%2 '󯹘z?݋=brOINUDpCDj p?\ҳ {Dum6U}UAðFgs\@TS쓙yCjT_khP?$VT)3 *-%_NCd1ŘxAw?~GGG9鐾6FQYߧi$qGAVZGB/H%m6w2{ӆ%,saQShF"DEψ ~n+$:a0ҏk@a+>wQ"_B^lx20MkLɔz]b|"co8MMv{975D0?)G jkmj v#3)|Ӎv=fQaģ*/+/r( X?Y`- = >Ix0 eyoac^aBY,^|PS/77; O+1p;zD#L3G"_ޜ~㯩u>A?<ȡż(HPs m1#)XzoDO%'KZfpax2Xѵa,S_Q Kv!Mbݜ,hZ0DXT9矞]m3Av`'T7 6z6,RC9 StBm4CT=:=0ZWKEGp?p?^duJù-?e'fF2$vsʁ ׵ipIȽ0X 3[Fc-"eҵ© .Ujfi,꓃VDg']2g 9MY;EGTD!K$?J]&_2OlŔ= #Tf?yD "XC5dY5({ĞWL&h7&4؂ >)Esm˯N½ƔeK+qŸaǸ:;F2' f8;P_[rј33qQ.Zw6P(IⅤ`0zmuq?{A>Q??u{H] ~VjMV$aF ˎ=34M33~ٹ3vւDMT~¾pӣ`rj.myQr`|]͙ EbX=nD(sԥQrB49l+C"F_^&!L5ږa$FI,2 yeJ+Ox):$ٳmC$HR$<i%+ |҇®! wjrls^D 6W#yρy<B?ga߅?˛ -XhTRLׅI>qÞju4z\#>hbޣuW#5퍜S,UټlژƳ.6бRG+K0Z [ (+:æFx%*f_Ղ=`ֽU(wT?Io/+bxm|ݔRq衷 e$,oRKTs{/dT[Ցkq9nwKg.VWY" TK"Ws|5N9zy!k/P"-:p릉%#mmB7=tO2+Sl8ꮞ h*>itv 7ݞxY3]f^\kc;Wa` A?*bؓC"+}Gʺx-:}m~I}?C/;x {AM%<\UYe{_Uv +> C?Aq@W\]l cj*NKKX \LZ38FEDԯRialcʤ6'"shQ]h K5fxΞR 4x tۼO5}ƷQ HQ̉9@Ց Ko Cݸ+Hi9տ"NZ[[n:FE+0ch?)=:b Ҏ?+/2\fubwSnmXEpf_5B/ ʇ&J2 ;.|0y]JSj +…)ʇk: $Fww2V#J\W] ͵!לw`r94MV)2Uh&et; ՘$1 -2'#D~KZZ\<(0ڗԒ?^C7陊Y8Fҵ@4ҬŔsI%1&˙ 1Ѝ|QY}v#%d{>BW@qb@X4Wd*uZ']v~xd6{ RG#egiOضY`N[it\qUH(]Gvixa3F ̅߻=$B"fS*7N7`0s{/;ď~ B-͗>WwNݨLE s QSk Cy y߯\ksIJCsz ?I 6}$ܿpI YX*H)GVv7w'B0jgZ|Xe2Kd04cH+*[n! ѽs}>(XLrBIgCx{,F$r]F* +UEhoD~8uCpkmI?\i +H"ald0'prBGhRSD^ģ(cJ-! [3i<iDpHw@R~(|CZ 3=PS;5.JEi޺Z8cpII@o&"A&\,[9Ͽ#|E4ncb&qPcu!Gȝ#-^ N;! }(ȕ+LvW jice~7CR:NDRgY]C [D+8?n{E>#$LiM&$w 7Գ2MڜWg"cy RlRX m=BCT>*KE&p+R36s })Ňrsms-o J&gN4R zvSэE"+(B~,#O0Tu ٧bP\(VS+ؐc vg*#E2pG :cFMBwVV ˮ/;MɵZW(OE@vQna#$>ŋo"gaSNd)a"LaK-N7.z|Ρ6=y[ܚ.YWR^ zp/D=Rl"jZ$h$sSr-X/lM[.u|∁·M5B({_Y`x[Z\cvk> NLAȹ~hfGL^Y\1c3L(E€ ӗnYF\ĪaxfDsaJ|gYWS%M|MF67p)+BuJS˨IS^ժX\@~My-9 O=N/ҡ-npU1$|=2CU0N%jZ/L,gQtk4@/{ #&2%)oJqK{p(%9Q{l8NC*~j:2ӭ>̛o8XfW3dEcKGvɠ6?KC:QM|΁VRdKԷcAw&!0dʫshCds-4Vov{Sۜ!Z-Ȏ{cB]c2PuѤn.#5֏: ~"ԦߧJx_; c݁<L N ā`ўv|`>8 i}ҏ P,om`oeK=e$kj@?Uˏ|w}Aʉc왑NMrOtFK~r\ۓT ޡEcL]Dg~8?ggM Io!_0̠ PmݟFk/_w@v=/zgPO]qkoކZ MdՆgNΆEw.Ty-e0r-v;/4 N1 V e?1X\qX=r3\B?1YJ'Feż t;){]Jt,&$Gv3{XeڏW)I}mK!e8u:5a]:8Yn,-8fu4gD (a=Eųf-dIkUCR7!YNő8EEJ}NiWauP"TE.].y-;3k}62TȯU2zll11YOzo/5 ;;/Oniqbh ^wy@҇*α2+ct!)KJX]p~0\v |L5fm=;i/=2mpiP{ɲ3u}3``0,'&6~fL.&BfgVH12&l5Q-XV(r\-o`TezUIT'HgH.ck}!=UKث>pĥ'{o11T}Q5gH>;^ {$DsTQTv?6SKtY fӾZGR uӪUR,>V?)$.63%c$hYvH7wTx©' ִb〒$FYH#jOX^|{ Bn yR[2M EKᎸYXf]"|jj&"_b);P$ aRm/'㥳OM*"lP%3QLVHg` ".М ^zREf5]mŦ`^2duj}X!3M_^_PB@ Od%Fqŀ`_,%y^,cSoݦkަ]? F0j9tEo4?inwurݱiXE9<3"W*.cL/JNs0]W ~xF<Ă:;Z=FC엇xԚj)ӯfa ̱ eF+F?Seȷ+ FjBM~Q~}5_p}u0b"XAK Y9e{^њ|~WTfؙg>_P$cZ'f"g,M׸ۀO:클EZ3l87H8x/1(qFFPEl -Z|NB&:.%Ƙ\JtbB[q$ƶvisv8sI M7~5ќٯf^%6wnʺإYDۥ7D<0W7S5LV|u')$&HY9f/.^UԽ7m!(łgi#%zbK'rʤwLq)\i^ΞABU_+&-xA9GBȨ-Z|a<6V@8U~+4MN,MҬ*{m=MtkBq*T;!j9Fx=y~)a "?/ah1DiP& 0ߡj8A}dl;ecp eX7SD~dlPfH8!Y8e4(m,zr3#xfSwϥkjۑ1 x[D }k33mzAlU; _q5gaR=jG=tfMϝɉB]t-i^^v+HnfA0bq1(O{€"c+!ybpϸc!ΐQ _*{չseyX|kO{{:@ ޱ`\apjXIYbƭ#+APo\=EfMJNil6ܮ .昱b%3V7ěX|o$D^@YS`<*+D[54>uB;l+5n 2+Vs "ڱ94C88d/? ý Vņ;ӢQ*kaZDU%g{sڡ_6y^յ5sA:e> iƲB.5_&k c܉kP5׃ b73׏ {۰v,XWL} ?%'\7fmPfH?CB-x 9F(*&0KQ1خ>h:1<'hv.B۟V3N *fw]Dͮ\]$~[8_9)s[NQvRSb41l7ZaZҥQXzi82w럥f-( n Bfvթh M2t8~gwVGկ>NFnDyI71^qQ djǙ cR' <~uf)%pMrrmܩ \!J_1⯨dG@ dz xw=+ԛdUGM ,B11IEƤŵ刿$$_A3>C+YOS (*c0L>7e` '2r]5LO`Yq;WA'1\ԙT@}#(heIC?!@XDx޿Xo9Is7ǡck{@,%Nḹtt#dp|˨8/8N-1Cۓj,:cHţQ"쵴5hLYxZk3;} rt\)ン>?rYr O%5{ '<4kLg.FcWu6ur 6졡?HgEG Z'FV%IJi?`#5wZV_L[JlYN5 zJi}7@ZvEc?[6|ghhgg_TeN[1&8苶ep|߾|&9is9@ik191k0i ӏw RFfrWat{YwknD˔zU@mfP& z۹*9Ž7+bDW,i/Q? *gt"]n >T̆o]|wLfTJNz`Bba'ߩfBk܈uHMY1L.&1[P2€IJgYgޚ`w;q$ktgN&x]xc/rGK\٢Ǭn>[i5\/GF$rdI̯k6p^zr;/?Hծ>[Ƅ r~b[WC%'Z1NK R( y#sgвFW['++B-ˠ?X/]| 6-uZF|0hg}mN,=aߺCvdH4Bq΂2 V(ٵI~;˛Yx$'ir~:UY &\+|5$Ű @J ӟ+hNi #h[[,`s'@s)s?s‘4=MhDT%2765&qS!6g ӞUFi7lHYڼbHNzo+%ӶdDS1άDxDឬ8ՀUR[Bk/c"tkKC#^Crw٬%A^3hIe(7L mXŁer[6 R4ݯi)X}$t7SdR̂^kʱb_ l^<^+dQ'lۤٻxߺ6zIj䄷)Բ0$enP(!R&n+`]J>/~^M6'ԜSB3jdd9e#͝DYW*9VZе>7у98n^HPX9YG&Wu޵5f"KC`#7CXZtI=FLx"o'qYkL 4 wNtr]䒸$$Y((Y4N50{kEb{>,_W@T'U M27I=qG>q⇡vtEMϺm4"VU=M%*[+[<ybP^hMҨ\ɘhicY/, kl(N|UTc8O:GF[󶳰 QBH.#q+5G+N|zW>$4B҂ēIdK\U0#VT+UU%gBf_,֑YAOH,ڑM4= !ecRÌ {f tN'xD .V~=jj4@t\>#k偲q? r 5v*@?\\>?0a?V?p9?P3.S:(ʕrĆb<|O\|T>v~.'xoV_>?$1P%0ɸt; v.B^hGJ(8ZCWxOuO VWlMgɡf@/l9 ĚJAU'ĚI=Hw8 ZQLZ[?eD20f6V)^g^]8d#3?bg7U&߭|#~0WF;kN$kQ$^-_ s|z%}"MKB6λXZNփklUrӥh@H ~(7-K9Je=PTQXŁ6'£|N3Y.;ۀFL ar~ھGulhI*X=j$O߷&p9;#h~ *(J@Kx|wZa&`L)t6K_wɜ(/hFPIxhޘT"|蜙Y8Ϋv{/YJ0{>2h f.a}S3B*9nɎ .L+UdXŸqu+bNÆ5м,,:sT #9жN4Yל}&X+g$fs0s;{˻˿{DHv✷XrJp[ dXYEyHj65mjPZu-t[A O,%JVĢ$dz^W`wADoK2-cSLW7?bOL'9O;fGN?s/ +äHc(ߍ{Op٘H#4pf+v\>jbW<Zo+MrFF_C1Ii_b"6}|{p5`L9~ǤUFVTd"ζx]FkPR{hܷ뽡.y7b};f>Mh{%2$">/n?H/?PU8UϋӟH0}w|ODG1fBD89LIkGB* D%7 z"WGYK 4VQlKr$ t Jȿ=pqxfxOxe{v-w-?t_M>1't 5/CFS)ZPJ}Q{˃f5c[O pќv.Y"!2[KY%̢cL"86,F}z|˓DxlD&!3%_Hk!)ðA2}koOj)(B=wowYL 9r .T<$q!Sf~{iXiͲ7oc3bRp1%ǰQ&QG{.'ua='߄LI=*ދm6k0]y\m#`?Ǝ#8gWK~UXE'qx%Ń/8t=C ,S/ƕ) ')uJ4&2̐y؅'am'(l )Az})/ J97 kٶF![@85X.݃M`% |s9g޻իjVE/Ɯ5`\ rK#ZTh{#b[|U&XmdKZoв[,Kk4W}Rl\HwTV/.s>/Aý̢G- J8$ y!v1qҼoGfB{|5 ;g/;Oou;vrAhFU07 ?F}T?)ju}|OMJ\e³m\M ֘D1Ts>CrGVUDmb׸<=O#~tXEn%~ Esؒlc[DB Lfmhe$<k6gI"sL!R?8=PCGhNLk[m<^Y憳(ͳ|= $ i+fR$y,0x K~u7,/G3JLjdL("-%dIh^aI|'i'gijAԹ&mC"6%ڸ/ơ+A|YX46v$HܨiZ=b$GYo;訂@<I6Z6w;F,]3E(Q&Q7othb`,> ~ ŹQe@({';b{UkߐpT>ٺ,zU.%IJX& %*{:)̰+.uj҅_6);!&;|06r-H^k{^; Fہ9TtYtl雠Ucqr ]mw` Tu7H" ;tk=Rǹ-j'A .?%{Zj2BmGׄBK)K~PrsweWaxzusV4h„t+'A8$:7M\;lMm 2tG=\hlǔ0>V!3Fض9G8 DP0>VVHA c'=(zi)e7FW'k #M1`ѫpN#۵ZPb[N_L>luv~rI+f$uy89t0>,276̀5' _VH-2R C֨pX[}z?"`<ٟvL6d'a53D=[H[p[aJ¨ 4D`~tQĥ7ߏ_"BS?(0W,IIbM㹞视{:ѵyfqIj6Y*:n4n_A޿yТ$Dy $N! PXA,HRƵ&lIVsS܁Wg$Dҹ6>뻦_ ѐL|BU@g2>&{ݛebyݯ,z#'L o誘s6ʑC"4ڼ)r?E8Z Ǝ*6/%u6U-Gvs/?Zɧ d+փEb& A,E;#;qmC„.Dі$UWL{N`. <!xGRo ; $ؙ(׆b# U^=-[,^ʴ o ];o` vwĆD `[H%UeYl޲3l/3vٖysKKF9xQD)~!S̓c03^ciFŮVy_^5׀Шa!xQZ%PLr2R2=!b|,c X3foxX!%0nIr>]J'dyi:#3Uaݐ9aN 9\7_,ڷڱ>`B/lY!ȽJ/K= %y$tdjM~l-bj`4>'+N^Z|% *Q;m8[M z='#kɊz="+bBturҼkKyZ'w:C%ESx#ҹ2ٴ-Ӎ&YXڊ驰 snSR|oP@|0UřKtgFI_-z5T%fDǭAB)nMgrbN=-mԭM|ԇoj ?6~ O ~pu:1^|)AFrsb[t(LQ"zX~D4ɇtH p_W,i"“%moZ Nm}` 5h*b+Ʌ^T:Hٸ~4.>g V=RTuas'}&n>cH5f-GN[t'Z53}_o}_Tw'}*DAWȎbg6Jv;l=a6& zجz$54+'nV+*Lvgof&PjIf !5X\]y 5?w5 e1h[=.00Ia UxiҳHGY|Y{+!/!?M]NQE3&3CgGh+jq?k!{؂ 5Ja3ouIϬno| K7]X!ϝд`Em#Iބ"| Lt5\;6|ƶGܪ+rZvźƕsv{|9v:bv1jo ^zA>TEE2÷c>>x- Iۙ3!]  sm΍Xb?jN\txx`fi-@GSvxˤy$bۡjq)8Iy-xNyr/V6~{ngC2ek%7'p*'.G8 䆞{A,8PDk0/1եfr>B6vn^ ߓ2'q?1%&zo $c'}LW88|5rفOzɠǀ'_^k ߫-Sj.=APٟ("`W d|964|hC;mNPAǫLeFz|EeX@@aG$4` GoZ#*'uÀb:Lm:2jO(@@oYx$, w)}hBU‘ !7 Ng?GԆ`w[l РVd^B2A@L 7"j˿_;=(0ߓ';_u 5€ FzR\uθ8UFݤn&K9E֥l9m dom&bT|f&z~ybM$Rn|($*#mCfhq8'J5+6l&n2pT jjcìkkE<7%¿軹䰋ZiK|.Ӂei*;jLav/JW~*?}v_r0k~׶RmC~uW%*,d@%Mm^&GW<lzì)!ӫḑW}~A*gD.a16@Gc lھ6}OrT3]S2^emj1Ay4zh.Q٧b'K O4wgUܬ[#v!S"`(QLsc;QU'0AJv?BhA!MEiXK;acsxvk#,S:WIAʍQmqho SM|sr0fR+D4kՙMX &!"VA)oJL 5.BCn;[ԏΕ5ZZ9*kb[>OSSE$pK$ zZ6˞]bDF&Kf k-ݳjyyh{.*XҿB"U?'%."!#[P%dvGgsvgW/91ʍ{Y6+S3wżOl$Zw% e)xH Qp]BEyG SXY<9`mNuVg2A)!! T /}k% Sg" Jl @2Dd0)AފުHa%v8tRUm19vrCM{,|P%tY.Ul/)匐*2:~zP' iƞ(Lwɕ8dfq!o%MSHxrYt|QjNxp@M%B+/}&Rj Hy\e(Q@p,¡Xsfo~.Bnn]+jj.FU>aX&墐 4탅o!^eْ`U#-*ɍ0\A?WպެYy+rq0*KP4`KG3qO*>ً#aDDVu}/Cx趕ɉ  $X]>DIS%QWmkZxaJfMheaPՋi) BȽULJ_F%ˏ*&eKZ9^'81*eQ7>(bdGo &IGSł9nS\R3VHҞ(zZQjǡbiIZ̈́tDv<)OErGK93HPDǮ㟗V R*c^7p >1& xȖRCۨlL* M@CX\Ä|vpjd,CACL?)nRQvjK٫`F(lU i谽+@; q[yKxz-r#|~ 5xiVmWZ0GE7f{O[uA5VX&:[l2CmŞU*}i7qԟHsb)ma,5gw,sڈGR]Ctc6$=dWJJEL@JS|:Șܼ* R RЩ`h>pּBt*AH'K0qа8o%Rp)ó#;Σϯ.bJJ|'51+!A=y)߰A- 4MM>44d~=zK&s+&b[x J=l WNLhwݴ5|F]2I0%L]z7uκKWgeHWs_tJ(3w5fK?oUG3пea_i_Ov`޿{ʀb$OͿSxɺI$c|8Zcv@"=IՓ=S>,Ep`yRX$5!Qbf@0f"nf9?>ƃB`i."cbR8?u"psHߢ<s=/O7?K<"&?:c<7 N$=?c0Z`<= N/ .s> )Lo+w8@y~l:Uppt\Ew#_mw(ʝu%nuyELϹ-j_9ǜS,KĬ[YSk@U,XB^+O"Jx ml7# (S _xc#i^ʽi#iĎXi|9[n$ $3sxqlFKVW:)3oM-ΧXI% Գ9#iرADŽbB8ތ& s3(Rm_M0t^kJyP4&=a4 a|7O A痿*>Uk޷C5nNOS "Xg$$P`z ZNC)Ht_?iH`뚍˶%NF~U]{1e^QYOg/b|oe4MD$}ciy/v zsf*VCe͕$?jޙ >KS- kË@` l>dG Hk0e|^kSNwҫӳ#{4&b<nΕ}A4j5$¯G/]+H'eE^o! v-2ODZpO׮_#WZFg [ިHO^H:!kۏC 0 GaʸWY-/wTH /!e4cS%BfoO+mz/*tQSvT37tYpfr=t}xxsI?s1&lz9L T_A<2yOMA|ǿaݜD&ԋačmNk?]SgD[Wi2׻`?)Nbz:ȿ1=a!gQ'&nk8_>J@C5{4*53@!*dw/M72Pz %ԢvpқіAt,9Z&ɖ;PY$"ӛ` D[@[Yr$31%kL=Ə5o\xCGWnH&ˢ*5kȹ:T:j1 ܫC@yJ2cXΪx'Wz}<('Pg=̡o<1xtk;(f犆bpa6v7@C)nP8gFao )0k\e3.EC#CC1x&e~1R=yF.y(cQ,US(s="mEvn%e(evǎ6AFByD[Ƶ}HxirgR:i\ʥB [*7)_9Řgo{K5K}^O[vJȈNk˝[ʗ ~8"$5K@"0;ĿNa !yUG gZ8:e:$\u;Hw$v?Q} ٷ`<5©KQnʬ=cVa#F] )5Q_s,qp.oZ%8m_OT ג&KG)V0?T2=!?mė_9)̖_Fkj ij86bLrD.ϥgZwg|_sļUojު%ةjNI\(KT)PIqDt^f, 2Tfm U N#^hH~mG^2@f8N>x$`儾{*p]() U'Ri%7~[|z`hJ!≼5HCg;Q300TO9#@]ԋyIvxUe}+ߐN!cbzte5S)p}'QD("EmH/d&r{([vDCmƪt uwǙTU(n@_% NJHmE,RLGk%gQ[wLiw|߉<n _5nT"ԋΦ1upOi>EGB Q`AORVPG8,M ~ ?Ux yf#z2Xfm gp#yy @qc!: xO|@Tl(h i+/@:4") (1ՀǩfP@CjOc7#Ň*`"w.“k:8Guٟ|冞<^|n(2< @Z5hX sE_0qyHp\K;7y4$C!pZ|K Yajb᪷j?OWv&qu $9/uuYe+#$3&I׹|_yߚkʣOL7 noT.Va]@%բ4(OG][*/pMjW6wh턊WQWm#=b>^\qjZ$18k1=x;ŗX 5rtWJykЛɴ-'o1XC|Eeq=XQ&G.웛X7\NΞ9FQtH[O~|i߻|R4OlL9"wm v i(DR,Wam *`cz =*IԬ?IT_mA=EV Id]#^σ9xSJ73&K_o. {hOXEДj̻iyrJ(nF-dmuٴ(%dJz2ѹs N1oM"I2Й*nqLaq%HoV^qW] #D2Mv>Ub)C2 *}r&^9dU*E8~|m9],iY?=<**nH*FApy4׵÷g*=&S/$d9 Pe6[ ]u9,<0_/ {lFP܆sNdxd*r-fޜ B 6βME(D4v ,LUGr|kUX$ñFtz2 [ 7Ӵ\S*o [VSYjß;'}ړdZ^fщ~"G $t9+}0֪I{ҥUc8)ZÓa0" $sa/6/\/* (f3Z'ǿ#.^70ewmQQLý^뀓 u,cR9L҂,&1WHb:Q9.G@6yDxMzӖf(b@}_2oECG%5ijUWbs$a_L8BRG 6a>@F[%*}p[d_MGcsb_FG4Zx bLObC[~Fh4mcGÀ9BC"H& ~8zzzo*́?K#>|7\b {~!Ak":A7( lc̿DK.N/M"/ZYI yrGQ?[#ܫ1+aϮeʼn75U{M1nE(B%`b5C76ۧ>x7#G(:)pmؑKH-(fVxמ &9s.:4k˽f:sfk?#!}XkKx 9b = 3)j: W"1a+YSp&lWLph'WreK@Et кhZ7f~IzhxeNk"A'u>{2,z?H<.HRMgI5*:eY_xW2v9k>/~bv: |MVkc7eI*uojIM*[]@wEC:ј uׯ0z_e|pNE=$!4/PGfscp}#0%LМk]1Rkm>]O8MP8"=JԇL]}Y@5g{?ݔͼo,[ ΃"l$+rXוi/ĶbL,Ele p*g,I s$ԢRGf}t79+iN] RQF.)NEsBrh_?00s E$AZM?ӽڝ;}KT >he+[߾竷/ =67ܹzҡcctk[OgӆQ2 OwuZ(KAbS*W2f{ҘnV(SmB}=BhM2q)6J4(X(#fؒ>c0eˉ/DŬ!* 3ξ>[{S9MZbwmmq/f4_ׇu9Y~S@xBfA{'ÀrQLLL/n^(D'GvcN*=^3{#qM,2.47&M(C@ ׿!GZ?/[vPj.c;ZU7p1zi.Q3Tm @ֹ 7'#.~ 7G'F]ݑPHS! r=1^`L&q)?4S>,6@ moOb/YLtV U3y>(&z@sPTx\Vпk.Ǭ 8z\8V`}qO Rvп˕Sc:= :C+^ ]!:{N\RAYdZN{*~)=() s=C,MWT 70B aPmPM{:iY%'l"-IG;1佊/gUQ}|쁕M?8!391pFQc(ʐ v.54/,{mS,2Q!T@PRsϟaGډuwlZG:#Y?^/'B~j8ٓ zQiЏvtN}~|-2A51;ȾQ~Z q` [VPhJ|o3敞xÛ?JK޼ q2~ E6xYC3|Q 5nŃF%S5~uMmf}î]?&!wv2)9M EC-gPEZB=~ʊ{$@aZ9y*i#"1!jtܾpb2p'm_}нpU[hq]i-8:M~ڂx3,;+:iIH;uJ_P%:Dȣ*z9@|*6dYnAcA(ce+}DAԭ7zQY`a M#jSĺM6$S"?~bu$.b b[ 7G2#.@vjc_xR6c҃' .-=9T$ǵ$>tmGɣ{ּ92 "Z, ߂ObŦ>v݈:+TPWC /S} 9!̗.om۷fNbGA#CSX#d8e!Ã*PGY+~A[Y lWMĭ 2:V2z\k1ql.\]T\>=tR R;Mf4-gFp0 ~V7,jצU1ʤ[AM} ,vv:;}Q,Ğ`.CH3qۂ8.m@Nz7>N=W[8rTmƛX̶ܽmEp^Q/fOE=w^9~?%vwרQKU҃viQ+ g5_̜ڊvH1SQA^->va'"@ 3=w_4 J@u|<2yLb>\[xS?n RVMՋ&v7-BލԞxla()&ja<]]S|66Mf{N`@\zRߐn ЎBq3 QQp>kGd hWi@)_Z>6[`,7s A/WXc1,4"E}ϟ2hՃ6"R]^UK U0('>%h$I`~A iRϹꇺJe130!4[ڂ`!VSمdX%I4}"?U(!#ѭQHcJ*;s`YA<<ٻ%/>շUnYumAѯX)Jd$y%1dXl!@@:ua@ulԝ15uی25hXpKO4sz> ( `oS b~3.ieD߾$w~*8T@~&AI:/q:Pj-tLANk/BÃ'%E(_\3~"eefedKzwۢ u6`)>;7#ǟГo?uľ\ &Ȣ= b7-tE bս?*,7+PU/zZ9>DcOh̴Nڥy:Zx~\S)D?c(lPc TBSU-qLK_ 8RDaU8D~[6Auy5^o1sm(jη \m1OZKV.ޙ%2_ ;qγg2GHߤii6+nM$`6&IzD5U+wءV.(v{ωԔUe>%hV"aVؖU:NadҩMnj I~$[ ]eCyH2M,(: jj2DNrإL ˈ7Y-Kı˽  hWsDea:3̌gwB`x/ܢ.4bx7·X5MÞlD"hGf=Z/haķ@B鱒ׄD拆h^2 8 ygMy60٭MfBqw2!JM2ˏ)mia Wbi{%Y4T 5ۉHj7oUX&Gg?k= ҉H8)*;'"c92ZD+tu4ީvE,{k["[UTqB.&S; p͗2%Wʘ+8#3F"D*5f>.m'bd_^A^ޱr3Ko nFdGʼn}Y3Tlz(<ڮ)=bA_.h2g?(Nu^L8)iK x3jTמͼߐ__I"#[J)yz0d@o6_g^-vjEBe5Ywct+BCI[Nb⩽sS`IڅX'*M#9zMb9ǧqx~Mą37x 6BD5_p]JeB᥈wUb8Z B"R l\VPtK}Q@V_9I^F;,(l *OyS:t_$bŝEUV52#[y$.A՝ Nl7!*mt()i{Uo wݮ+9Lu-j>WWW^!.'{ݴ *, x쁢N"uRYx~# Blr#&_ !"ssMF' dڵ^cWXn;h~te UvQ$"p:Ġ*g}@)2ot>8PMn)p5w(N>Ϯn ڀ㐱 "9/dW9}n*pޡ mL0 jk'#;=`WR8mr,pXtd( 4ltas߯Gݎz 2-v4R\!n e,t"'4+sBC o/nKl_g`'zEN^{wL44T+zu\>:YM|Vn)K56>  ^ /"o/ϖ?5Ev  xl,<oMRE~l0Wzq*1Z`Mrk[{6i)΀c/홣}!2#lMRR gn^\gjp՟cf4vWfBi>^n.hӤ6YzDH5Uj7ާf.zrWȴmֆݱm,`̫ 7ӋY1^MlP\nŅz$!alͫlm?\a J" q(t)/ekghwyyb*˲6(1ڪ.-74ؓiyMh;ß.Fq/^uSLOޮ%hl7 S/_I87LV5(a]CU=V4 d̛ QL7trl| S=xvpqcz4'(FZ,@-)s,=}XO(Rt:)U⁕r9J& 75;_'z6''XīWU4/&nwOs8➐ЉͽH?{xgԙ7fٖ4, yüd3 4I*aJu@0m%lBLRipg(Go?VDU"aS}Qėp%AR0)VlY@;.3S{QNRV|ȫL^vĉM*B;8Ep 8-fXjsF.3qwF'U-.mv/z4<"2a|0_]}ˊkyDO2iVޖp?HDv#W냊m^ 4velH>="yHf*`LZAWО94ykB_ nx]&"kB6<ܩ{G%iCW+fd !12yX SfED^XRR$(|u1jRAaD ˏŏAN &Wu[8]32-J}WP)q/$en)*?-2gBjA ̈JYA#Jlm@`x! dnKq\a~ww%W-olJD!V|3O!]|ߨkа:zn?8ov\A;\ .dT%U6rY;MO'xb0L>ZZv:mhsPBhK9 z9/Q=TaqB{UY#v ? dyIE=УMjpRVb}$LAMXᅼYfi:{ 3X{Y"9{/Rگڙ^.l Sg{㱈P;Q̓Oӄ?ݙ5e}-%G- e2aySҞ>`D>Swr07Ov:] ¯ԓ ]-ͭ!rU.:)-`vͷ@`\|pH jj١ cH[OݖĘ%5)^t@' ʤM8J<}*x8ˤNaSy%:X Xfd;}iŢ%xg4iqlT.^:+\XϚUaݗJЌ\,¨96"UG/RrkίD:u`OtӠ*I7Bq5C00/|zg;RF}``v=in+d[&@Vo !b$aj,ԂVDyK3%TF NDn% r"0j!eij=ss ՛*),9ڨeJ81ש4 R,q2VL;Zp׎WQ6,L" xI1RǮW51ti .SXxUMs@\<0KWٴE1'7J'XU06hJ?q8ujC72V>5:<ʍZC3B󒦷 ?lHV lY'>ԎJy)^?-D[$t3 PFuWlҠhu ibpj&¿5=@| ߵ;< 8KYVx^ ZR=I6%"oa ]k[*#8)VaiMVW5ɶ@{ =6plcl$ILw顯Ra1I`xX),6@#T_yc"i3Z`~QjC[Ѩ\gԅ]cgJj4|KTz<@2f-(q|Śk|l`+@L!"##؈\͍]pM25)M 1$$^C/]ZDjh9Hj#3ÓO~7(U/W8+m<8Ecʂc&Ez %oVfs'K8[G6]%874Z&֡k*6_b5v1*r4y kngQ$>B5 A?ܶXrաsnYBoNG%c%Z?g/v2[r^f])LXHޯ`gI8َ4B"aRI񊵭myk-fS(i]d/9YW ~hX{E0r{9_خ@XfbUYLr"ܛc!\0Z6>U-r`0Ǚ(*O3=Kۀusr"YMe\rwS )}›L75 itgM=i42I}:>q0U'fFn%6 q kͼU_T>!NFfcƙqd̼iW5{M}+ _>;MW[\yy?:ws'KqJ /dNQB3b)fn^B\ V.kTB9?ntGFyRq۫{%â:g K"6A`u"겖,[FB (yS[l#+d"ln!$P,|̮՛K @dl?H} CM?W@$}QoFn2/!8Ko=ijK@Z,aF54оP(&⿭߽"'҇0vcaQPKhq"<&/KE!ӼcfI`;)OU)Fol^Wduġ;+4qQyPnftp[PD*TAN~_u\=ѕ2~(CZ 4sE!0ё˗1<<8QI54a]5G|PI [u`dpŇB_gd5SXA2yF::̠ 37M8 vNDw/VX+y *}%uqD5J0ٲP߬Vj**~LjW~>CSHt`W5 G4xӧtҔ04B̘Ʉ&C$7_]{ArjvȷyO=Pn<3=`kz~ޓ (y^R\H4j Ina2B;#3wN=Xox)w%_hɗ6;GFz^4x v/h0?6|yR azlsBi [kqA36!a3sry R 0в_iGڹ5ʇÀf``+@73w /=PKn!5Q2Zhº;ˆՔv|9kYch^en?nl?Ų15 ޝ\w}L QO,w/7r|֥5&Ms#2 ع۴PLQgﱯJ;\juD?:{_6'KGҐH": Kcfhj փhhMʼ,`KfСQUrwAåSjBPM˭:P.uHBS][\ܲC#a:ri0whQ =9Glh(VMZЊd#RR oK֦e*"A>y-ӊ޳ovxϷKNşLJsSYk2g|UBK?uBEJ@݇iDCh}I:VFbrd+>X(iS!}C+c#I{ܴVGmt Pb0gR:頳(農?Ǥxඵ?lن-e |]z/inmzj"=}ن}BARBrU8sf4N}uq!#6Zԗ+&)6Ʌ)(Fgp;:!Aꈬ=ٰe_j#cNur?GJaҤJ0,t3Ƴ醭.hF L.GY_ rk^6oxpٓwj~#cJ\5&ҽV\4qEGoo*'ˋg|yJ3Yʅ/eMF<~u%9dETKD,p+YZ⇳E6D%G쐎?֊Ogd+p: Yb&$>F{5EڈHs WMAFlQ Fse1'>S%;Wh)`Ǫni!V6֠>-*\ :ZGR dlG?i>r1LE:X!u#5MsPggN3V\L| _!}}Vz΅jLcII!3ُ| [i Lu^2)(i|ؐ~-YٱD[7IdF6/0m'mTqr0k\y`Erdg2l/C>;c~Ej;6.Rc!xW*4<}ѧR>ѤY,j%nX DV |9<l?IѩJfpے_~zפcY74EdngϏXeWϟ&DlҺdY= }O:{ e|Ck @`Uߋ  ?*W<HF,l;5~}(6 3Hj1Yk/- ŕK1_8%}f{@1gN3v:gob2!=hu-oUzWe4]NJ>*(_/Ti?64;Jlh(M,Xy| jէf>^ء8g uk~y9 w^CkTJh,&K -1:lE8ZB.Mt@\i ;he~ VYrQT"hMJ^&} |IG>!Xc(<0ꃳuD|[G!LJU(ZW$||oI&/$/ǷU/>&&,o2ckl? <[l˫Gvӯc*laA1IlVI(: ÉJw 6?Y3W[G 6?V ˣoFMtҖG_KQ '}f:F }Qg%ZN(v*)$ŪϬI98%':ewo{&E:w۞ 7BwzʸAqS7dݒqшBPjFB}5M(ʼXOS@"J^G[MXh2>R_ܾ_N(|e3^`E1[%~~=DJ:Z%.Vc]wQK;aL2AUcgk1Vev Aac:)P pClI6Iq]wJXk!Ru&D{E}F"YNAi޸}6Tq/"Sᘅ!  I8zPY0Pcz_<~e pzbTP˪dT:E jQqYR5S ik${f] #o\uJY4dž>aދsn1?8h%/ZPl[nq~1?=6 6w,H5ZXK=Yyok3k\S +8eYHjfɹ.j)V{<ߴ%ϪPB❲x P]5F"X]`I0RIūM? hI=SGsVU0_p9ŘӞe(hh][ 'd[XKl`%0wS>dzXM5cP'&oEUC&OlA3Զ9}JA_CįYtF Fr,dʤLd81HH`&N⦁:F3w@"Vί}qkvR_|:R~f Z[..]7‚+ ESr08[\.ĐEKN $ 0FZn0[eiY40[rㄡߪsrTp{le=wB-b.;'  7LB' #Maq%Jӊ`VCb )C Б)zڋ:_- zFh? Q5z\) = S2rc.ORܵ{Z5,W-8 x= 49l:'#ՈhCPSkuP` ΞƃnهhIIyqR`*݅#Gn;y!Uh{H i&][yW CeM50k#|#No9~iX͌vU;yܵ+G A}lU_X`tf̅^Uٿ ztGTA+bpa~aʅ 9jIA-]/N_ q_ C29,Ցw} zZ= TMp z2ħ,dYC[3TyסoΦP?&*̲ N= rW{9ȰX=[x\ ;* o`~N7j}>UaiW[K{ZW)u+/ڨ9n.&s\Hَ<}E!'mO;}~'=]{}:Qo!NeA@%7Zqaa,,0C/c,9`^Vg;e%^F5Sz5C||{ihH|FVsoVU ܰ7-%) )ftHH H7RݡĻy]=kϵs1ǘk17V;b-e|t}x$uliqϵdii>DKAژ(5ӂ[6kL9]>Pǻ/&`\,(頺^>uwmJٯ0ta`ɢzGBF1 V/<} f6d}4Hv$~4Ӊ˟{;`ו~Ao~Ȼx~fd5;j@z։f%a$U$&]6wևḨH3m ]Ea+P[,Q zE.VjU p*h{%4wYZu}*1/EMk#!E􃷘'+E{<t_rcYkyC dQ{ʝȔ{1ohB1[vIm=mr,'z&zS7wHVUKvẑb/\Xqߌqٲٵ + M;]?svЧޛ58J aݪzb5KjNG{YN^#Z U9IApN. 䍽S:3*ݫX6ܮ/qG#'Mv Om߼ʣ>` myGm.N]xѤcFDLZ+Q Ԓfg?K K2PPm= ٱ!4-:<=cnTʦrtɤ֡nSq#ӂzr[ءw^%H-o*^*.u2e-##4d{^1a2px!ͻ7.VJ9vLmJ߫iHf)aW{cRv.j兕vJm4˻S.e*tX\-~j672 5^룋_6>Q,-XUsXRI;f0#܏(׼1pGJTLjIf#WGas= .KFk5=75 emjD-+%r3>Ӭ7h>#ށuqx9^/mD"; )g+xS{dܔފ$Mw"?jHԿߛz.D}~]WF-PĺV52 x\:3KW2) ;R)=OWa:ƅX+zatWQͷNwߧI9D'~e8S@e+˯:–h<x"%rq 4tcwP\xCg)y;! ×tuVTv0fb(mRs!hj}\-d|#]-hN?.|lͭG:Vq&De,!n`LG!Eb28khE6%GأxGUz.H=ݻD ' P-i3g,5 ;$Jz8 {\5ckثVygmQln[g^l!,#kfTbyD"ʀaʍ=~mgUb)?to(\ac~&kPL l1 BIrqLOme5uIGGvPWӇ9ϗ_FMzHQ_Üɇ/com}rߊqnլ`5.*GJ"㇐}QqyΉ.q3(1"Ohwtb"XQ! (hHټw ذK<H.yύEHK+?9#L Ze$` B " b !߄`" >$ "hXHXQHHcA3 CԸ@~\LTf#j ~]  E%BPNE`Q07>9B@D/$-qqM|&&xD&xS %&Fx"kЯ#"AEoBb(D'd @l&DT!hD!PFa $3& /THQXh"_O3"Bp'MHpwsv* eBp'xs& Z?xD_Ĕ" BAʴ"P88bt#(PpC6  "PD" Q4WɗEY1BD& D_t` b0]!jCHZG<AuuCEt漧 BB*08 " p a)1BPAHCد7 "038tCXCſS OhQ @1PZ\!?Ml T~Ayܤׁ#(x(D_ !Q"P9CwphE!!ĠaB!ڸ~S6D:2@d@H_DPDCEAGJ@Ft/(ЋBs7؀K&$ 2 CąEo'DHPa7z$!fRP%b''*8Ƞ1Ġ9+M lrUSHA"2& B0B"7/8D A! E\EPLv29Ia? $@C+ 2vX_CSl^frh4so'_~_ĀLR@&sJ%tt|NoSU(+?-ڰƦb—= G$ Ք}U^qɔ|/D>r0YYcÜNs~6P`ox]^*_^ljVj821|| |9hrc{_ :E'ec-_ToO?wE&ZO/?ו:mTgsWSs#岫~;>̏)˨W;Hyχn3kqk!?X?ZOdgw}rW'꼷m% fo'~m&ٿ=$&Kbܛzd~, {sեzE[4c+ |O^|!g"0>[!HMStO \NbGÑ Qo+J/jWF*"4/;op n:Hl??Qք˗/HS>PJe kpiKٴ#(OlgBDXkGkIM-)cܧ.B&sęӷ*pŵ?Zd"WsY«?G-p,b_xoӟrڍ"6_e"CɧֱPE?~:vLԹy=PSIgtXl*WUnZ#`pIРPaN p SqزN#9`r 8`N0+l6M_R4N,׈KK|~Y0,03c|Ϭo,.ajcxOg't+ŤO3|KϤwD [k:ISWk5mR1,p^kl,d| d#=So5V/B[s/=,Q|oY~׶U(m^m{RO([6r(s D}XT)$q0ZwϷ{7^eD}j4݃ϯk}L9gr[ T;be=J>D}f /Pwv[4VEu<9&ۅ(-NHYr# vg??LX|l>D8ZJ%L\ qkZYyeî'>ٚLڗڲ&aCLQFTք6'd"#ҔE 9#g6Mwnp22}} ISuvh:=9S2>q~gdEBuN7{?$G;CQ&_bN!HrZ);g<^mh|t>No@qg{KStu\6<%OhZA囒hִujoJU+l>]?\NEz"pyۂx]2i7JBoRLԲCwnk%~O̸ղ7D[y_?쪳2μ"7R$(T'#S#$)w/T0݃OI:߶]:LS|An >r\s֗\"aʽ"C=Abh$$`Wid=Gc.cQC~E%u +w6xM.W (T]r{{tnB}Vo'&7_)&ucVEYUw}sb2)98'YpTfV ŝ)0p.6#+WR|m^+== ˁ?U%w=_zA-l}h`IxYPwvĹ*v &&;"Fof^Z$Ҟe!@ROث]*P5B揖l>sr'OyLg%Rg6]Gl*O,=.ZTʳ |D0$HY颇Λ~n71K}"n9^̏6'$$z$D%41i闠*rdITT(ԔZM.A6M JWdWt{,+6T1[8nԜD`sUqG ~ҬDPk5ޫʿ Wee٭kD*S[> ?47bu #a"NZO}^NK$wFw3avXa9{P! 'l8NS8vX"e* 4y.I_dPI5\„2{\gf/>o<Ƞ}#$ٝ,"CUբP:guQyPC얎S؋#^>=>57FE_{}1R"۱/(V5FuFbt [ޛuS},e3HAM\4~vF% %ʵaݱ.v6f .G C!gl|姴G [~fGZ'R ǂM U3moai")Hۼh?PZY?&vZ^w7=uXqN}StʋXAij"-t"o*6``-T\g1QEU۫xTpC.LHGGdǥ&9>B 6wή|}<ֺ}@%ǔ$f>ްdUV$6מy2B2P"=(x0se}"S`E% ҶѺ;sq&F5֊*Ŏu$>R&͝*y\ԛldËܛN;-OQA侠A3YݻŭwNůjz Il5%=ד|=.;ܮ# :].ѠzKeO-D.[Jy~HdaNӜm?c s%°gfE.Eb+!cw[EZXgQ.sK_ƚ0ke^&扵חy5鞢啙v3wxmOGV jL"H4 HtZ3@ېO TxX縡 CV8ѺMVs1٬}&QOkѹWV>?שeL03G}S<\K׉׎ljr+H[[ by?*w+GLW2B W<` @vS"۠5x0 wyݛn#d % UőodG "7@FP\˾b38C__ 'žPG 7">9(LFƈ^ʈ"";#JM$ A^XP[wh&(.?: AD;B>Zƙ WW^E*f⋠ֺ͓hŢ>nƥ*><N" ?k9=g^mrOꌍ̀oK- 4isb,_1XyT/kWPT5>vĦT!%P8Z̆Yw։@ZRKӞdVh{f,4gDo Gr`7(.no*>#~qV|1 ;&TbwYώC\OAOAOfD9q@K $HcM}=V$ Y EPyLMI"xD`  ), W(@;^\7?he ܒ2,/`b +~&a$ȿ$ D?T7f 5*%zwwV)+7ے5pAk [pHkVԀtx:] M)l8uFP7Wݯr3t&T\e*jQ>X~@Iiy.5B&Dϟus|诅 UkY-+/VUu\ F*i0PA< PGP?` m@[0A]p:}+Go|U+ |]!^+l,A9N۾ XZЩ`0\x(w֘ӈ*uXI2ؓfBiuraCg~g1[w"?ԈoL<3tb1ꃢd^F9z0Y"WVT1˶ /hQC%kSY#Bk-KkC8ǰX?W<,7=Ltٿ5nil_!3"? aU8}?Mu:"!tn.G\(Rn4vNqU'f#ߓkM9N#ad.jF½C\`e8S=̐ĉgOw)I(&#Ƃg,LTSoҡB@ |iN@iqYTa_`AXekN)v u!Tm@mֶ+ރ'R\15ڒs,#]dؗeI\Ke](ڪ"O{3NWPF3-W} sη-`gS;| |O 5NǺi9 9>"|-}9o0M?Ny8W:sSc^Dqu?Woó"D+d*, Rܤ,J~RT#k }ÂP{~ ,7ދmR6u2zEg;GXAI :skbG⟙Uة-w^Y cH |LV<|4l *ZrCwBtGv![~8y__н0mqXrRXĢb nԤլ i)؂TJ az$.5FI]zK^10Z}{![e|\@DN\n*^7n;G н̱e ;zng\Z=BM7`#!'=>{##A^37uI jHbnp!K vKۃ*f:B1+yCmetm3=/:QȎiHQgNqc<þ>Q#.rFgmevM åZ'(K_W!*bly8_n%׾5 ݟI8lzkԌ7V՚}JE5l&{L9|`~f@.yJq'D\G%fJY]!椑tu>aHS.z<ϫ/ bBɮ>oΑYS9~=mIidG);b"[l{vM(L;%*:}<v½7G:|%mڵam`cd( :2 KLӵEk?КW@Y=h;L+K_د(B=P5M9h7`}¦KecMJR FBB`w0.M/C0(E|g?1*(A'` N y[2sZdt7`+I$1MDaDqڒp) 2e.ufSʔl/ q ߛ K'p3ri%ާԠ\ iw :\oE^zɓ,ts7}{}N9TZb.q熴 6#vN7eO̢-5m1ۇ$BD>WwHuجݜ+ȥ"(ZToTeo>?SN=) -^#k>Sq=wZU*!{~ 8icBGm_"=@皗3qQ=AvoY!(*%2Ry z##='>K<{4D2p/4]IĊo흘r_a_QVC oz'Z8Zva/DzdnVCުɘ <7#]FfLLl-=*E${&6FYu IG+˩VX"9'VgziO'/޹~sb?0wGJ+]k|R d3z ay$CTW;P4QŕE\"}(Kt]5A:,Uo v#lL*4BRE!|Nĉ ot5²V̧v" y'ﭨa^ !|#y&c$A=&3IK~6wQtVãdJwo_O/Q{5zBcz6V+b}qnSJ>DZǥjKUNT*xpDmcàM'Spx%\[\cf.CCNF `8.N +6F ++;j5bpKtx;xjց^X>l:͎uz-?F'5b8aJV8Ks;ºHVVFqH|?*;Pv( ky4$_8$n.fuw؀`40Q+].ݠ؉*!$WA.=K/XRŲPg ܏Ϸ+݉V?LY C$ѝiI.rJgq}1EcQ{Q!OG_5&F435̓5%tJ26e{D";Пû']b D'Sd1.bGD/k<+uƘ!Y]G0芄QPkɊCKl(+1 Ǣ LI EVw')eV J' Jv10 />vy6t[8f+û-2"Z$NܱM<;Аgq>骿|49r-I +WE xl%YNWÒ󅺧Ok$eow"$kzLLͷoǏ(,Ƀ=c6IQãX۫qD]AniAz)w^*guj}[+沰AX5-rsfbbE$/{u{.Ϟ5В^fMeLXGҭ5J C uN[܊Yk{A? ί01"2a7A l bl   6 X[}'fV=)Kr؝x^?oy8a r IxH5 MciK8x (h," q# QU_?„9PU#Bw`"$5QP)_UR5ߩZb>$,A?rK8\mߦԺPĬ(2QDDn>;oLEN߉OD_Ňh%JPO0Qo$55 %Iѿ/Ib~0z叧Rרw"QXJ\x!n; /_jO& !,Y7 `p*:h9I,; EnwsyG QGUX2ѹkpޝ-OP+m2!yylgK1=xWqJmgG[ӏF{8z9U*z u5q0Qh^GxW.ߺCq!."/tj΄(E0SV%LpwuDg60rÖ٫3>1+k)mjwFX99֢My[QE$oYZa7gPYb'Uc=v}W VUVǫ6H\67o<Qgsbz_xu߳,9\Pԕ6={d< pM/!.~uaYʷo<h/Odzf̲ [# ǣZ'eqQhy8R^B|Uٱ"I}C/2=\{a(/k5b1VV7dGyMtBN5'KNU5Vr`1q +@aW-.;RRY:]o/$6smA >h'gvlësc(Yƹ2OogocStJ¤FXB0a d~t4{bc[-@ڑDÚv1^8]yQXQkc0nHѺ]VS7FUΡObr"JX 8eG]6:VГ;_3@c«+dF:BRO 3ɏV71>p޵0A`J䶬hD\٫=piH(o+7N15-ҭ9!HWu3=o SYm#RlK=Bơ`Un%/~ZE!|p\bWOs%GnF^"}>O]Wt^m`Vߧi0|hgCAU|d5Oi,]4^Y*)p[I/bYH*gt6VJ!:Nb8WN(צa 5e0u;EFSd?s5 8һA0j#/%4dxhۼpoDݥ?pgT=la_XHig+H?gȬT;t$׸3>Ctǀ_(tJaţ[{pTM:u@~cGt3=.9YufF!Thjg;}.6?蔒R/7YfN_= E-)N e CBҔ_qWo߿ #~h}Qy݁r}'?vL(W*QG'4)4W{:-o~bezVp6MѲi3_`n8{-0vD##IpfR6K~9X.=!M?vILSS,]WEKI٬Hr8vmQ˅oޜFQWGkҺu4Jm:KYkku&og;vf55h;oUA}wdpF=fD x;WE>wJjIS2nipU'Pܣ &BԁǶT5͹fIH `7b.c% y[Z?\|((q|J\1ԛiAL:F)o( =gOzNU>SЪPfi _'-(na@@uA>gg3kY{Th&ڌ@ND]E:MW#ORcuVާNdy+?%?~+z>(?覷n{]=ڂ̥+OGw-!7jnMFFsn[^gW$nyO]fnaZ#ǮXL{DG~R:%]>A 4 -jaM^(2۹SjxS߭t8O[݅WWAβAVp+ܶh$T8ԲW]^c#\7dfgaӧДNк:F^- ''F0 6Mw݃;|W/t]QAs8qTºQT'*fK4=\$T)Ee}T'$QQR.R-5%vt0 B';PݖH 9U_躣e9QY/r;~HfNiP;AJ'B<+||9P?g0t F4n hf܏򽽽2ϰ$3J̗\?{KS2\ ﹵9}Q<N`&%|bׅ2{렸n]Ҹ;nC$N-dG>3_Mww{ﮮZ ki us:n2[ c[I?Pe~M%+HqKrqoj=FmT'OQEHE^Ki,MmyZ8a9*\ "JUL C<#׍834vw&M_#}T݀&b;쯄?v'x[9:dicnS) #k%KDw2`1?os ]^#h :XpsBrN~=)nf#@#!BV88@'./%wAcdbFؓ5,d_k"?ˡB3O$mxU4;2c 5ԙYP:sv*m\dNi^cXݠfKp8wȽ[1fPyIķc~x-yy2( ]m**krW(V:+A|2(X,67Y1#%s3]BdQ(t C($ aE B 0s=u825) f$0r!9QOVNHV9APRoՔL& ">F4jg^yx`~DrW]IwҊXCJS6QoghS0 Vy3Aij/96eYCbϵx?xcM e卋O[Mey3.]0^[:`Z }|34MX7{=-3FڜdG^`ݳ&ee !l()U[zӁf>Q2r%#\Cy;hmPH]碊ϚR"'l8Js}V4L]uW&T 7&1-U_iA , 3ol8f-AG ""ԩ`bУmlrLS3>ȭS@ygD0{o`ϰHq0w"Yg1C @94J'Xp@"o*Vz4w@߹IP37YQs+Wr\OڼoļDy^ $ ś%WMi+iv"j+j]Z"CKӎׄՈT-;5e'C# 6DS J\d$Uam<4q.:ͨ>=8*!gn:Dس^&l{7ytZMghCLtPfzIU,m_᠍yƯhr\~iQu&a!Ǔ .IyxU(;)OPq JǢGy^MCc&1t%J‚.>tj5Nϻ )rOK6s̆ Q4 6ƩK-q$4"9Z ;(WfT-1SLgo jMSc0B{]ElmZXwar0aQP((qXfܹ\@JGmD=ׇͮ S3r_V1+kͬ Ko/8S?%tqٓ̂ ( *yF1݂QK2\X5IQbp~X^4%M6lv gR=~RY6EuuW[}lRcV,hRzR̮gXe6~!uU sš;&a2Τ,^S{na7g/9Ss-XqczT 6%5r2kݷOm`xlʛ8Dx+[I OR̈́;,8Љ[!V*8b_$/Qӓ5X{I骼(m K#`Prpx봶Q4w"ewR#>Xӛ^6W0x 8`&SQ`pA?/Zy1? ;,SP,O|Xc')YѸ+ׂ0qj5/2N@SS)wnb+TkQy>OƯzoJrPjEIghJ;XOpbLc[8^sA'M ph[Jq5|,rNbQ"|]/m+~p2$/ȼYOoî{JZ,/_žFn}DՉYLGB83ጲxNmREhLZ2LL 崋iXkӨ1_ h4;GՕҍ/= Aѳo`&cGLưZi'!#r-l-HZh>.3Tjp9 8rzЅ[#q>r"q &X*>=`zػ Tv t1\W+oHi =eFXm5>? 8ixƪʦUI; ;-wg:~tYL&H@)T?c{0i1؅4`Im vHyU9~. (R.:5M2i*xѕ쑢j{akv8i2rظԿm+C;[)77P/Jn'0@Jsl_P;}=^B e:@ltbȆVB&PZ#>u Sdax-t:=6Sh)xbXƣY]VV4Ţ 9&aP(ڗh BW3Ёe N:`ݶvK}~I?m\ΰq43]- kB%7Mez:4||c^/#Un`nF&/UWkӎP'T\G4ز78?(9>rS6n?vhz(ydC,> P 4ɰT~dE'iy>1o֒RdZJU_*! ˟,(ckj$g.Jj/rREC2m}" ;wZ1+󦧟/9ZN~f/yTvmk{_i24 p̵ṆI#fwr˻e>р~])] 8WugSc!giٗv]{NASabHd0]g>J Hʔ⁧6cUprubU%V &R'? .A9lDd<836īG0 FkA p ⽫bЏ3wq>^uւ V\hF&})2 >hK5phW3`I;du8xX;7D^ y[dH$l`e$9;)\}bt'\ ٹtTѺq,%R ACia>Cf%iVw3]Dx)Iwݰl!J3A}>F:?GG oojm3J۟N]SmQ (zZd7X(7b 8M蔟V%U09Pjvb,fnYnN;0Qe㑶<’%+baӚ$ Kd "J"Ŭkb7oR24[.*=p9Y?ơ4Qq/86USpv,#Tp Q> ZE* ?>'^Q>SzD&K ~E%}%?>j@gMJ!IHzAނa'uF1 # x8ǡ/v1'YM<ۺPpubeE5!cd%¿)Q>0ZOQ]8`DmW!L43:Gh υ8#Eurѓy}G+%פw18{S \O.Hng D ]`wI?$]+ /^^5 ʑր-T:obܼ\\g>|I88ؙ9of?y oTdZy* $5"&$zA b},+3ov_RpUB8p@, 2Dbg~+EsrCdW!cp&#;98 (0FZœ^<͐B[fP|<. E7buL؃s{ȾvÌgnS`JwH g~,Tʢvz vd]ԨQIh8ǭgcmX}-2Jkug0(&Al;[_KQ{+N+Z׹@蔁f5~)|l<"r1PmgCe/d*Q,p~Eр_EJfxD^'ϋ Ԫ$|ёtW ;[H]dR:ɕ}J_jŖg"75.ۿ{㨝"ot-I$@oKY}3B ,V4%`l 1wu<$ә5V*UNtw?~dP8S;D$ȤE B@q&aؒxs{T\*et?DZFcK,F/-uZ%ZG\* W3̚]Q1ժbQ6;<ۄ<"% b ,O LpZkŝ]C#{jl,=ɰLUA& x_^0a|?Q2E$!SZRLM wZGB Dx?gF9Y`v'0֑}E*dz>:u][MpiiL$}d)+Ia Nf=Z+|:zD%.}&%-ZԱ 1]S:pPZKxcxy^3a]ʍ72oo-(p0;mH"KdžOna'waS>E'1Jojls;vjPM'ØfJM~}㉄x60&@ Bŏ]ߔdN'7/^!"W,y\=__W,#tU^}a M?m^ׇYMPɟMT! $p~!.ۿ6>.aBCEbcffcŻ.̫_h(d$< /<\:Ɲ9CāLCDQ@!ĔY$k7SG8kͅ/ƀpvuAkl=q8[ZA/βg>5CA"JuD*w.r4d9^8F_tdK%{Wɢ'+<ц2auqo:~p;ONEtMeG"alJ#!INϽtߚ43%j;b@IBBࣺ/K65k;oJ_[cZNQF/پ]])|[2<$Fuϡ*Ye{8_j>=٢)P3MiyM۸^iU-Ga:q}äܽye cY,M8!\[?*쥐O=j]Y0Rr H:ly4c296m#(;z?!̄t汨LO~`Ct ݔdR 6ale} $jivc{z#0c/)0(T)M1lK+L __(QAGX|5m_xO XK&50$;)-Ka_!"o{dY]z@G3~?ݻCćY yursjT1ZJCh FS1-b|,X 'B~eY"&/C8,Pkƛ/*  5J6鵉5dz~B619H[|Y=SޢDu:EDKsM ]kikl-">oю]5";0#P;]ӧ} 4 |62TbIY })d oI8\$ $=yX(P?uǙiUB_0SwVVLԫcUyOh/ XtAEIwPbP 4 ͩS2BJcfNޯF{p)"Pe3v,)'bQ\xeb\=v":v1(_#O&/ 1W/l_(ܫ9RPmRAܔuX>,\\F_h/9wJc^}U$^ G!~#IETyHgp]H\TfM? l>҅qvJm6I)jÄqQڮj5i$Δ f+[RE%&/]N$"WkG:dx?$L^F\JIDbޅm}>u?0ƋM[)F!Ft:VSZ_-PXm%5-oµ> =nGf̎IOvnjxyY?0ɺ(=+I68Q[ vS Nౚ@ ^ ߈-o[֘ rsJrr^l]*\7RQ7L6Qh{:ڮ&frrP3Ѡ]JyLTufzυxOz;y9_Tb ƲyxTyM*bŰݽzu *m{8TT҅=J\^ՍV樁櫢Q}+p H` @N1HfWUQ>c'ȦgYGk~ZL9eRs\'5rsm X0Z,sЉd*̄ ۯꆝ>@ ^ (FN I`j>w4uHzյ TsAP: y52> r"6kKo+-ulpD?A%pIFOw wtbpb3FEhrx{=_,yX% 퍲? qތwx] p>#Gh DqdY? ψbJHoBQzO;aLfP0>?0&)O-'߶t9:#bgfccukLNOI^Ȑ_ԩHaX @H+",73/vBA?6 D:gկsƆ)UG~Xnw'*DMq2fQi[ۇwew7Q8 Ʋ+;Z[XbW/cH`J\[[:Ч05.*6-=\ru-Ew=fj :ѓYme BӃ>?1c`; D}@ęM@jn|B&U[KL}L<1JN,ށKITy+NeV=MBɐM\[}5qnY V.'Z >mɳ1\wmrJ!`*LS:0hrXYЦX?0."4Z\5N? @sm]z3v DzS -1ZvU+=viInK `=gDew&]mJF"lb Qn(u$LEq){`%q A$b*ܦ7Ŋw],";q|{+ UĽ"|e%䒂9E^f1漱$ Vv D6E6{N7~ZyىܢMGoHm%&ćcb"Yo/B3$Y]Ě'7` \*a|8ـ1>(#o7D̔%*Kv#]I:5Šn7v預Qs`M9x[ |+ ~뮉1}@ҍviVsH;~Ks8%V(("Eu6bG&j/sDIfr7asa%.k`mC=ds&s w#`#΂A+,ލ'ᘤn7aX@~9F, A|vqr99 V YF|ɕ&% > 7U7r <%ctun8*$ j·`LL$- =\=od0&9TbA8eبm*"$\Iqᴣg&^蛭 ծ# D'>fʹ")]T0k7D߻Vzb& 3u_/ЎI¶rȉNk)WrśqL~uQM/u(Cr6);̈́yjr; إX,J%É62A0?^T]fԟ||l/_bbʹ!%$(5zrKu׫LelXfҐԤK1=>@w>4ÉG;ҹXבx8*xKȪYN1ݭ d9>~,%WbA&45bx4;r$5t$l M'ko)fEiMϓ+`u0.fҲcg'7 [Q_kTNy*0/]"v;=+w6u6Z3P'*zD(EH'N-uYẓp(`ga;۬tZaU*)͋B!&=?1M0ԊE,ǿ!X]i<+7ge{yɘPp$IҕdlY KzOt w?H ?ߒ_lz )9ϊr2~k1srPp'iF._h, P?9Pivv& Ӵw6] /G $\# _ t&QUe.,q74Z!Doc;Km/Xy7j4%_`5l0~2'}dX;>L ItD=wsIOo0fbъ̬n+bL<ZU0*z̗ۘ/Ҵ4qJI$ X%nGx7I2 Ejs5 "ALGP}׬Cl,FEyFƲWg@ϔQ ^ywRg ,*y(/H;k-*ɎRH&HR޲S\(u/(x;!#iv_B*{|)Ǒ Lp?^nKeGLIYm nn+Hˣ7 <~p,+b7P(ᲦJ~^_CM]5YZhKU"ՐO%x~syCʧAδwdaIJݞUi5].GCSSNAy)PgU/ϣzw>Id4T][ bGZFN\&sXqVV*O{҄ZFGnUT%( Ξ)ґi̇1cױ/D-m[y}Pݍ9hO7P" BMv ;1 e鐬}-Jx̨'300e2 cE)+MNYOP?80?%#ko2:0mEߘVo|{5CٮyN8>{`k'Dx"S_.ANbz1VakQ &,JL*sUykItiû/C,**.CJB"]!7 Эđ N>0l;G:{`zlo"2}ij*_娝0_%*3?=:r h8k4Yl]>1 c؍ܨ.q0:虤tQCRڷ ?뮃OC91:v"?;1'~& j3aG@1Gm @?sZxwKGH.Ü-SWAe lz/~ (UDL* %n6ʕm/[^ptVvX>SSSN'R t.baK'36P7f$ DoɷGm.yy"!G,nYNkH|**RXeĦaej8X(Ar f뽚<;:u8qB>?3.߉?}iM ! sWjLcm*-N4;VDc}3wL@^^ܚUӱ0qo^+z|crw7Ռo}[P2HJ7[`#tP' Qu#-kxokز\)+i6ԑV Ln%O+*t*  ;믬c7;!=_!1M*4~xFwMV4s>?-舽p[ !o[;Ӟ,#*{egrd^f5~,)G7IrGT9K1f#l+gP}ލlձKfWQ[DҼ&B x ]L1 mU3+a0huؕ1V_55X\`e )o/Cn N>?n-?ߌ-mlZFտGCЦn7;>~lX5H԰EL`x(^h _ߋmr(K% ̀H ]] Ṃ0Aw&9 'Y``x"fGtS^̍EoJ ɋV:=~'WVvDz%TQO5g,c•sv66g `tqO5q `oo UTqA.VX9?_:t )ok_ KX9(DbAs$^Brpr1Qp0a:B$D@6349q2@HŀؿX  q@~¿ k@y`wŁJ#`aYXUzE1>Lچ'6ʤIwzZZFcZ<^;~[;?8RBrly۝aDP2_j۩w,sK'E]x_bQ" E3aq, (݂wdp''0 . /{sw=?5jժUkw8rgGi_a޹dmٝXTIIl45 b +/GǚjW((- 3?%߈ *X }Jn[1͍o+ `6N6SxV ; W}<si5UtNBM_I f B2MGs-Kg2#Tß:5ɢrMX ỦY HE o*L˘o~A߼U>PMEICg%}ձdgf |溪Xpw1k~`㍻i&MyahO ~RuW?$"C0G3 >޷#T1`z *y^]||IyBe!EGGz,w0ژwnr^QIE&\geu6ِiAjPb 6uH0dy |_+(޼ݺZŕKE?q}Fy`7 :v @NRUT۶Lƞ'7h͠ Qr|b_DX ~&Lv#+V:~ݴt̴ײghN0mjSyrI%( 4V mzU?j㎋mhCwHJ.k G*dZ@`f{m‰fS}/t 4hh_[="M-,D?jJdD f_@wsdm}F?~^I)v}&_m".nPCjm:g)/ Wc<-j)I;QNol`q 7ri{QMv&""ijBsxid<N<|Kz)Not$8G^ & 8yIG1٫aF\WI:`΃[8\ώdᑭ?;KJ51Q]2x/?$˲oVxQ#VU1 ҁAˎLCהiB-̱f>Ҏ| z{!-ϱҖ2;4=)xђ뵪- $}_2Ѿ.qkcv+' %:L͠:k ΘA7X? זbAq25)4 њK7bR2X +|'&ƛ'Vghs]W+0pOg9$0}|'mCBbRDoJϟ7L睺W_O23qsAk$y.vBggg%wAZncG4e~aS>Q|:KVP;߳85*kŜ)—-)=jY,\!U4W!K(nQtyU4 <^r׏Tcճ?!WN6ωN13ۇ;2ʞB^j wԡ\>=7 !ԉ8?A 6. nH+'qI< D EK̸ϯ$yOBN(bnjuIQL1W_ًOh%!.ɝGǸH8|H5`sVCBiDC jI2q/ɻCȉz(O(?@tيw~ >b[^w=\T(Le C"RycC|IKu aDL"GM.d4|aY~jp(u05b$LfJ5柞/ۓEr|ՁgGFɧWXB3. %UU degʬBYH( KMpQ!.`i&䤣ﯱ ~xA)=eƦlvrMH~a稤T o2IݧF\|ʘݔ, 2M*dVfܾa\b̸0m3q;ؓ2w~+Q ;xC?n)e&F?x,5UO 8)+,^|0s'ϖ E5htB1,-v`P2+PP2J\7UqlwaN+9O'fzsIءGßPdp/aT]VBBY0y84㯳߳:U:(pTeOz07jk32)+ڵ E ޮG.)x-q. @@|kN5 DEu'a*sCS9|ȀQ"SDh#ߢ)Ye0v (nxzs zW6Mb. q 8L#eob1" $*)fy; R"TWcW 07h_4@ʙryO`n ~}m)Yb[wcn9ڥ4ykhx-*C.\R50mO%U'ۭYG]kBMUDc< ePwM{<'v?с]k/&yG*XCk P)vh{s<~M7 v=Eɬy3a$/ɸ|>9{.O9՝go:~ܺKT=}d6 ;{1ZΪ`$Vq`w$a mvU#\w$*)aޔyN.^{Yiy/3JάvOQ>l*i;'+-#;"v6[ln㼰1rU.#]76!4k숝>hEW(/HRYiƈK^ᇟ;zç#$yZ*ZлZȲiEķ{1d PF!P5"jU@]n%枼nr=V~>Z5 (/~7a @}rVUglFϫu\SH#JftLPN3h(;wq 5$Z`jPK4]Qq`0PR y?h&0Fq_@2+–kWtZPjGçn|jgY$`$mbU_ yЬH0l,"-t?#-N=s6ّ*@֣pf|v?@cDd)Ӟ^ jaH``% ) `rZI/z|gއB@xe7sI4 1}*N"jK5GFQ$ ޻QwiT Fŀh־:>\*x6.weJG19+iwN"z fv(xpS .~`ƱJaQd+0U=MV)) \2ι3W7+9<(U:7fwW8&unuCO4/#MOE0!_p D튑ȣ{?ZMOB`2]U"Ɍ ,ig8Ra7Mx`EJ+]V,pckA07H# S$>x4|[ib9^61m+"$B; |2Y)AR'$qa|og)\ &q*Ȯ*S K3qң=<QyRY)Փ9q8Y0 "1P}.[Ø%z!E+ç OHbP94uj M0wպ5 r$maG̻1!I[lx0靱,P8_6Ѩ=)'__'q՗I%<6Ȉ(~}aUP-;V@ NRjh/Ħl{W.jATV:fZSd\ѼaڶHpZs28nPYlrPVR v?\onm320.|⃧X+B2Cp^DȃAp"N/RQZRVf6 5"n%*p?Zouc[KŸ&ԖcۜlX4ט{iH ٘*bN_ ~9:}qS T#3B?k\Żɻ)˦AzY2e{!1SJ^ng9b!jN^iJc+kqxn\ +­bt{\L8vuU6~v{Uq#&FKcX/2{ MĈBQ@n dBo:l4R%ֹy?>b(FR~؝F_K;ִ0rb^M0_!)m;,COSVZ4םjD%enpZ/q_Qa{<#AC$^jnrN& .ɪQJSpm9ߪё~Z\9[lp5`F4+ ۀOAeJ̦HJ8!B]B}{30ʉz 6!Q# qrB,"Ș)<@ޝ)kvKwk&9HklhROEhHTj[ݵbARV@XC=k~Zޕ`lN9eXY}%do0",wh4ŵDrܒg)~7@4}ٕ-xFF= -[[íxGU3b-ڴ -)Dutl=HsE{Ju2=r~:ƒBگ*ɛ 5iԷӽѪ*S'pS` ml??gi-񀪍033,XEt01XGa Y5~XMQa޺?B l(ƉQ:s G VC*BJ4w? z*T Q:Kp-q(W%6˾ IN\YW~ŋHig9VF"7T;j{[?s_Vk%z]L?u~"a*VӨʣ]<{o7rLі/FɱF ( >u0(\51ͮ3N"ҥh5s2pl!/-`wͩ?LVn~\AfZRJf͜p[rސmaGet]κr|"\XuX C.v tƕ=fτ \ӊϔʑ2 p_M6"21u߶,_d\>t$zԿ/9]zw7w#f`ʎO;2U: g9D3d#MI*a*6[~B@Nqo@>NK:Zt>Owe/@X5ƩGxiwMi> )&Gh~\gS.Jgh b lIE|'*Dyhjk&$DSi#D,|ЇqƯZ4O]ű\}ğԮ ?O@#3&cN}MnTF5|R O{0 P!1ogm4"U 7һI+~GdA5u>t&eJѧ ww8|5Pn3괝X._f>{qSt%r)^naxn|*Rr_r23='^XAONF01 )_s2/KYbn@xh.D8,әm.:sJ,ߺ fm0n³&KDҏowXQ5 7S !GgMNBӰT ̆#L`Jk$!B#&u|hI|^|QKcu,WW.W?C(|)%q&z@xWW0\Ժ 3w g $mK\W~5 t(K' (5pG[T.D^e5 u>0]]Ea`0 0 7s @k+Mvmrof>Zq|%uaDWa~%o ^SBp l:DI*")*ӌ]T*e}2Zb95-|(glZyhfBkP B.io봶P7I]nbY^(}7,,nEW^U^>< 3@ {E+$'=~.ź^sW1p,*BK7&>QR}Ntn6Dm`myb](bɦ,o-  3Sq(aN]WۊqYO\-C!ՍdqyC6<EI&r;7$|B@m'~C5z?F{Ѱ2{$NAa-;Xv(MڹE?h9AgN8;o / ~O6;oFm60hO or/r  {h]K.MNπ4`<-Wuk#mg6煽%͍!wErTVhM3Y!g/j]I@D?2#ìtp~ZoT8ֺ#XAi]/UeB0WD8,Ǧ'SS'd)qje۳!˗SdK_MUU L\* uw٫XpN&[o3;|1ݿP?94jbFzvYS>*`p;G=;p+]km_U,t=4]"$?24]l$)HIijW暪,@*"pF=ѩ>%F'oFAo q.s23[ @cG k)E٢$Ќaqt'Ǐj kܴe[F.S~\rXFm;s_HIK ›sP*n> L$>@'~X.|ENM qll _HAJEAHAB}|^LG)vƦ{b럪 G΋%Va~}DcU4+!{тPIEil~ rVoXdoc/ew t4w1AsҜPTE +$}<ޖsQHV")ZLc=Ks8y-7C!9.ʏH*Ǩawek(@1.sQϻYgXMpkg,m wg R7m6VQvěcK?XC P &(X[^h4-LV\ķBl}~NǻXcz!uE)gϧuxIVwHrP- .rC("Gu$ri$gr~!hx֢/$8XNh4.ݩ\LSف>JYuy⃵Hѡ0dfI(|;3%$Í| Bq'7U2^y-i" '.;F61ucHՠfiK|L}#&NJFy̷\_ <@q.a|^;룞b!ړ]ʌӑ?_fkq3ف'El#Ӝ{ @š%h0f@T V{sᚱٶ#8kKY=ӝ31~2E'֟QOW0Iݛbbx&\(&Fr|KADQTQta$:} bZ\vh|'h4}])%abnf2 g^1>f=M&zeyYqęA3 s@}-Z4i_? Z8n+U'hW q׃bXw(nk2ҋ“!i-aC6–o_a՚ G*D4T/xD% +7[<b0xOAY<@eWgMǏf:b:ltX?+霔K_pg=pUFR0x)|NQ;3-783a~#bA>OWg)`W, 2mVuC[wЗpC@XwPE k>ZC[;jDT$Sa {afx*-̲dL(b?bI”0|PmzY|"l"xڳ3~&\\XEMk&6ؾIF9>'c:ubs%mrB>:"śtX[>lc/l(e~?cvv0!  [ҼM\h%A |M`P^~;׋{#b'1 iOeb1w>N옉QxB|vLŃ'rSuBf[ l&oam1cjO=߀Ç-O:C/E!J= j;ՊRM'Bbt|ȑʔOtpz+Gg蛲Jl^7̑:_(Q~'7ReLsX"B[OXZA&<3x έ&k{d)ZzqCa17Lx)[9]RM]4(!Ih ~muS0E (($1ݏ$lR+5JIV~UT$n!kܞj%g7u4/(oMΖjm[@viɿi{A5.n_3`2ջ+[z8_V+oб0q^_f%a: 4@3w4:$Q-g"i̞A#vGT" G{'WYnنdQ1T2PUN0Z9 RFڗfg0mV:qW $Vn~i$Ղ|Yx1G(6/>?>ҿ |AA2Hus?`>WF,D'3.A\?@ ǒ``ix/h:lq=^hm-BɈ!l9~pRoy+njn>="wDC30EB$D|*$Z,Uq=戋rDb9uQ HW{IP'y"6PTڲ p/c'K1h/{m@KLs kٵXpB83̨]OO7|Ad_3ԤLljVwAB =:c Aۏm$:rw[cRSi:.aXB;ZrDʚpts总&שP%J_]T=۫ȁQ1Z>a|ά6o5$St`kͧia"B I ml,e,zF&[Bi`H׏Ǘ#[ilcha=3g칲P큷EZkddm&3Jnq)`Rω<ţ/F(GOYQs?uvj fTIRqsd5nI͸YRdJ$`$w 0Ḧ`BL.=xe I^_ 1;ܹwVUDT;1o\2 Y{.#dY,JqjE% L;K3qV3Ȑ$4@T/]Q08>&W -r_  EY<8cW+|I/}h^ʄlbWn6R` G@/}R<\!+&Pw"w8"^' tUpbɝ sEm66`PO+ Wc?81I#[5j k(OmE{2/^7C0) qc?wmlovx6KAL~<彼+^Y" 0^|G~R }GG,M{R#&ԉJ4j9뵐Qk~wABP؂e3J%Y-GcM_W5CvǼV|M9 Z6[/Mi}A ꨛ%:3i> X#<~{v}n>d/7!>BBdPUƼv}1A/ iHr"j̼.'!(!Ye YN JiM_lϬPLԂ'Ha1<[j%&xK*!k5l=eHU_oBTۉaro}S˾bOםy| OcMUs>8aHJY|}.$Ä@ޗWE/0&[%t$׆Au/z[۫s7٬_t1WLVX X7/L!i!Mҧx >άhUO=.($i4|Ӯj 횤b߽ޢnI,V1: x(kVSY!b‚t`A99eoZ g+/(1/ oU @I VNCN`F:`/P\lnr2sٙ=73;E!q>NW틃  N6DG(m:@"4H~[h?̹Q@M괴&-˴.wCSnnoI @CH]&GpXMWpaĬ<8\E'j,D8Ka(90Ui-hzy9x! fA改'RNWI曢҈@NR6ʓKJMZ뙞1R T;e4'BXȆGW6Ÿsat7 };xLy ^KjЧ-6]ln?\ |+K5t_ VJt J# '͐[J%Ey0T%xFz+)/Kz½;bN4˫5v2Ϻ)qG9ðuv\[&{+G!)zhr&ޑފB%?.d,KR:nʧjh4h~.(bWN[ijK ͶC6 z֧Bƃn6̳Lwcf.*J`gD4P\NG"[G41(b X&(+ŝXYvܔtpJvdބBH#3[ݭ*i1׽ nToo(=I|7\{Z6O_}mF+[ٕ=' T9oʼfÖC&`|' P~< ȸALeKQ3GTgE*8jN0O37>^`UkϢ~KqV>0aDpX)aФW|y ݙJS4(F=ߎ2#F^0oYA^T9?|;8jaס <ȝXʷԊ}\hz:Td$~zOg9y̜Ӹ}F[$L_n>G(%  6R`Oa\6Dq?;5i>4@aʒfyoz5Ja2)Hf53$>^{$%A{0$.N]|h2,u RqAZ+ٸĪCgFulpX vנ(fjv>P;<ʳ@b G.l}J(6G~st@L.ȳEN;H[OWᦐ -"Dʇ/bz^tОZF[:Y:q߶k1@B*қ82) oo8~4,Ϭ@\#%cD.})C0i/ {qB-;|8/4R$tLNC!49]ϖnEi{oKWׯ-|2)mZ=2?CvsֶI2ɅB ઐxo|5/ܶ::DgvYJ! ;/eүkmQCNALs1"z@R(k}$DJp1$(S=^U[l{%4{H}E=EgZxI0J ; >@RSU4Ő(z'|Ό|WI߰z )Օo!S$v SKsrΏ'j\kտ&5^٬h`Ek#-^ }XX`rcaC6~uh~PDdSIFJ>b "+^F^YOf흨6O'| ;k_ ݇c P; L_:K1/tFKz޻d昊 hrUփ0 sFw.z]-hB&VDa-7 @ܦY9KniTMИk%[>7cqWqptfw2s;ͷG 0<)<"-"Аb.;ȿ3\;WȿĉL T$<[n*/_x_ $\"|P _>} fm[t a.^>lkݛ)A\<EX"\4|\ aK4"\"P ڈQK$,A"\gB_@ L%HDx &% /TBo"A)i <;4, m|d?_LOC(\ yeyv/O!O腦$Z&B\ !A= m/俲.DJ{L/ " KЬP_AО6 ;lum^ӒCw*O2ttt4oH1h=G_1xbZ |nPLjaFחu4]TR휂RSF-~8Wo7t:Q_eb݃`.6o?̟"[bR1fLdխ<]'UeEG( rL|J-0ׇ&r/>ٝSΆ~?L| uփs-cXiwg5ɪҒB c*Tp"X('p۹ܦ{2wRߥc4/ G;_Vlrm[ 63 R}pWRww*D/hWNw+7{h ;T,vlvڍҞ+oˬ5iw2/Nك?=b(gbK4B~Cdcs6YE;?;.ӟ\jm0Yz>-tq9o0/FU׼) M7D04S4N8k"N5Ə3OKFacKYL>@I Җ^):\mL8-Zq0,z6,5g0nŘ,nIObX X_oCdX䆢кs$D.}^{-IշIeKODǒqkV'B{MD%F?UZ{BP#~Ug`,X V{2b}ӡP<\n[k|/5u&H=Ȇ=lO蠕fȿ4=Rا }Tkբzxf `1n-.3,ie ˻7aX2LQRFﭟniWFDq!Wi:atȍs͹8i笩R.#j|"96Ow]JQo㨬-ܡ*_Q.Ssͳ+~p\Ȁô,>:[SFrM2 ϯ95t5CNJ>oScWSk7n_wq {L澑x ޴w 04)dT|43u|.u: ` VE UFzꎆ[âI &incBTiS <ͥ&^4ƫTafpB^n(yy\mR$t%S''l,.L4͎"$e{;Lt Fx}G޷g _%ߥ2xUE Wfxߘpt*[#]WJrp-b`47]Zm33w4"7hBE/1 *R'XTu&(ha7FxT@W#b9_щ|M8YD,VA\b3e(IۇWb>SիEzx&݁j=[N_px'hv#5 % CjZD4)TIV$ym+k!9rOs1hz૫d-~>S:b BϢxD ]RnXՔ)` _.1tvU`{v0s^ǩjv_(ٿ&a C1^RO˟m0Xj7A?UH4܋4<։ :=bNTN_PS!>f˅݌0& cᏚ,ً0Gۺ=8)^8k,7A"0糈MLO'fD Z8ߎ6T AgTb)uv]-t>Ӄs}e#?fQq*?YM%N;mO+D(ba2oLB6R>T%5cra~Xb?#!_?yhˉg\O:9.0оd.3B>V8זRbEOi.Y2铔V}bb_Yή.xgKW0h,ۼ#iKD&i.kW"=] QOrR!Kz'xrYMn`I;/S^,VΜ6c#*H%߲I\wl+ 6lLo2y݅vO67$*"뫫K,,Yovd/k]zɖ* ϡ]BKˁMret<2n~ .wҡdFkwu=p)+x@PZ$PD "̑⅞!rGJп]{P-% >; $CVcsxx@4|/&ZKF"R9!/  ?0၆!rCE8&GK@HЄx_>y^>_ w(PX>4h,X@(F@ ~jF _* _4FU.DƠL ?TywT l젿@j/H5fbR^S/z}!K=+()?|"w`_ `|=<( 0?kfI Ç~!2/\".҆W@vR:ՠ a{/lEH 'N!:}<QGp]D"jذSj˴OSQzM*R]~[@Ɖl48Q;IgO_{릇c1opFÝUz.^6ulUR4!cyM͇8k%D3ekw2}lDe`Qx(Hgv5[- C$[ZKjЈ?Y:el5"GCip:|hk)N_M PⅎA/}$.XB6V 妕?o¬_z__ߡPmq2 -JECj}$UbBwtiيA&nA(H/_3|"/Lb!˛x9pٺAtx)*1Uw%XSX\CܡM^C%l'nN u7,uBg|ݥtAW4e"wPlE gK<]5'+_GC'QIiÓc?KopºcYNPkc^dP&)ڃا8/y|_HZf= 6[XqK=W肔&ْZ DVY{cι\^!6>YT$-wLq-^9i" ΂4%%ߕ;>i-:6Oٵ4F)X^<5jF,K-[j%>3y(/W K" '~OWKSE}e w?ȺS&S[j|) rC6lmPI$nej6xԢoyOx4Am5B*^u`krSY_zPl2-^M`Fxy C8Vn<[chlj;i]:CQ.`/C@ wqŽ5a bUzVE1AaYHa 6AbL56]U?-# 0/wr_/`ӲI}i2R={^r[3q0/CB&P ,st́l =@g+%++CR.fP.%`)X>,Cvo]Qu-DDVVkGjGI%|EW}94 hλ/s!T:es"aJ_ u[$C %u,Į u0gp0gQgHgfhEU`P6uPhp!xLEDR'+֯ u fAgAM fff}+ʯyknB_W%zE>+V ]W VDM2zpZ=K5(MR\1K#(CR!{ʕ=ZPzE۴/+{ hz4/7`y2i_WO ʤi\ߣ?~Y\YJ#[["[i"qTdfMTeM%҃ՙSsFm/xT_dd*dَd.ɪյ"SU+%ɩ蛳=BV-ŝtfNdf;5ۮga*fEQJ<^ާ,qi;L^ (޾,qE;lҾAޟYq9;<^UR,qU;"q],nSQ/mXḲaSvII&I. Be4Vf<3qɎ)ry 0a!a$a0aB8a/a?xˎ)~y7C8.W8̟]8\Iq.WlU-b8.W|Ī M8.eUT8.eDi͸.exUz8.eǰ 8Ǩ5$H5~R HNHNRDNİ5RXN8t$UJ8~p$+.qXݚIg+*qdھkHWK05qRȗ0Zk&&F&F<&4rze_/oZM]][}I|sb xYܗKD7 vC2o=y6 eGF)}6n.&{kϚ[CؑoAݒ6 IG:Irzl,ꖅL~S>=uH5/s&(Q$&\!+'FߎC&gj 2i:qaB3TJIUMСc{"oб=4w@K)3k:bdﱹ+֢W 9 b@1MӜ9Mk13ZD)Mk}%MjC{V-ߢ bɻӷk:@QE?l9|4O}CN}F}n-g) AϜU쭉leL{\{Oa(g4<c#diMi  cڏ46|?`4`d$VA) m2$Oƨ WӼF &WiVN;Gl1+Ӵp#dt Mh 52&i D#d ri_#%e, -Hh0ᑴV<$ H^(@@xPJAuhZjO$Wl+mB̐!c1 c"C#x"\e:sd"5YD"Uj\{^۫T"u裑۽妪\\dђOjSu.ndQOJSZdіmOZSZndD(V x*~i{¿V\#;x4~{ϿS՜.`j{q&aNa[c[H煾EQrr2l95H nXlR){eG.&PW fѹpK1Pa ۻ@ u1phb; obu;wߠR;wzPԎŅ4@ qTd,Hf*2@1BSLF.X_$kű)+i鍲).I6(իdO'SV+6(;`NGV-:Y'҉UJg_Co8KY$uW^t*eɯ"=S:m2!i!^k_:m1iQ tਜm QV^)l:騪mIVѸ.e:`ThhTȡ:N8lh\@`lEI`K!0Ji7Y`'OKemj|\.t%0O;Ų-kTYyqMҞFw>y*TSh}`J9 )T~TIQNҋiղ-bz׬jݤ="\(WkM퍢\(tj݌Qv.NGw.Tjpy^o⽢7DJËA! b dBIB H3r$@T!H5rBL!qH'$AAd :H!@!3` A ʐQ9A!Ɛ( C Abم4)in<|+ƣaMP*F{x o#^<<~~F'i X>{YAR# U}Nʽr@\9'TH4B!p RѡZ$HeFTmpHoHP `Czp7dnI(!=F.\Vsvm)AW {(7݉WO7=Ϭ7yS!=^g~S6D;knﺿlHIJ"P3'(!=gD/Õ*sXjFI;WwF@p3)*qJwH) @1c8b8% %~1Ĺǒ w)@7D12H2 a2b 82/DR?t6r: gW<,|CDe>n yɈZ$Gꐕ].4rB-+cT8[!ro6g~(p o^GFPV\#0);P¸+,J LgJcA;*Wdn϶G2 \,ul$d UR$t+Ц^MC qDS7ۙ!)Y p;mYO)GS+{?`dd7|pfäC&ݙۈW'h΃QEWqLAj8$Tؑ=`hy8!{Qrˍ;W?$BcL3w?\\.4M3y?[ijq"*hh78<ֶ ն,7 JXxP#=;M}( c +'kU$(jj>*\%?*h#&T $o)iVDIP]5,MP*_U2_'յʮЙ%w(JK^X4< aƂG # H3(/Fcv1fL 㣍3n[N>Rb`NAI\?Ax8C} ީ3[F#[pNPo\sʬ#/ٜηz>~ hTO_ƛn+Ilj9,h"|Xmh-Ӑ-h'46AFMrŰ'6N 5R<\A$dFTZ!a0 }#%W"ܤwbПD<o?k o_E*jBKt *` ce6DYfF=CDp(zB.]08\Y7w{4=R:+La70h cO=|#wV2>1"Ɵ#v apfXџdaVHNE[ = }}orL(O91Å_`yFWT_CBԖ\۔}9/SepIRx.yh=j"^ޓw=0ߣ?%Ji!F+TMV\#?> V-GIFxI@݆r8WFlh?J\!gb܆:*zXIxqػ|>ՁA=1q#LՏH<,Fr0o1&I&AO@!C،O^VM?fHJ=]qjWE yX"S`#[7QRɞ5޶#D~oZrp$~pA1\s(uPjѹe1AQr2S=]Bsy$5z[5M- KG< &N-5T- p }k7P%dz{ʱg0/\ ̾K:=V9a[Id }ăsBKPT8#/5EKs?6q?EN?Iq)s8uy'%>A n/2?N,nwDujȊQ8r~reU~5! A% * |FlX{ sd~X7S{r75(C[jIbZVްt YqA߲?xeAYe!/R.ua`SX:6Mxcb} Q9硊fNCG& bDN Qx\aȳ!=<,Hv놾L@^> ʆi?;*5PV0%gxȞʚ&Fƛ&|~Do6_H/..++#+vO- p*OC^*&(hm5AQ[{ޤ N-:8z]]蝄]nSBfM|*GEEgDdDeD.DGG9w&'6+GʒːB7n)#zndndee/e.eeddeeddddOe6Ln))^KvSojoOqp1 9c0{7Mo=Y_  ͂Lj&&q'I' ')?x6j{? Uٴy k {+Yiy)9ɷ=r(낱3K{z&z'~>0=n>nVx\<™j$K8hHRu xhpkG=͍jϿuq{qwp6~ߗzzHSHI<nhlݎoߢ_9ELU'% bbip̤^!\ȁVԀ9~$#IB=nkXwFȫ^fW͡Şp;{zstv.P-x4$cv b u1>v^7-j(Z(S3/zÏWa0r#v oh@>6l1.nVM{IGNC$ 8P 7md8p!ȆI&.p`(AxUqY] X A܏AX:S0k6P53d3F(e& Ê`o`?aTlky.ax l 9a ;L ~{a !3 fۃà0"L {aÒ`)7;Qasp^B-'E*':l9J&*ֹ4'6lyR*ҹ'&v:MU"sN\l]*\mKg%N|\kKE>VMUE4tșUr@|Z+G˫G+: *+qo zzf:-&>׺)}&?Nn*^]'JR%U (]KMUͣN 0ZhWW8O~v`hMf@roT(_15O|r~oTԥ^q:>PN7z* V>O}q 74A >)=HъS]q!Aؓ32C[da83T<;`$c|8p~@+Q={'QQ[6sPq5@&QQg?u5@$Q6U7u~@%Q1UG<~y\:rPr5@\` j4kZ]AJZs:iīPT :2hɬhQheǧⱎB+EemNW5~Pռ٬Ϗi3?`f?f$J]Au0(y,y5ym"ACDHÒ5@X"O+ k8dë́ACjrA7M KN.QNQoI \?d\蘜19Fד3A˰B ^"=|9: \I>]qnS.>]>^SZ>4ܑ0֜8RL vت[L W9]9>XڐDfUл/ЎT_Z7pg x/g/]M2j9}k9e;VmC]}'eV>CU};Q;VOCSI鋣;h}96;VeCm}Ǫ6V6Ce}۪8J;V'CckJV2Cy7UsNvƆ5U N-5Uv>/V\߭*i~Ղsf!}ւs}b+!~҂s|Z!тlD+!zkؖ9c;V}CF&?z9F2皖Ic7zAj~-4 H %z* z TiRCoP)!TAHҔ"_kXk{=W>0u7gz1NҺmK lnXްi ۩eɸ7urFܳ/ Zz@RÜ'ډ%I> c3v\eQc50 ;1Mu;1]?Fe(ud⌝@Yܘ*qj]=X}tx]a%}ҝkʫ7fvyYc6ypb@;1zO%Y=qZB@fg֝[>k{-mۈI=Ɩɤo?e =|{-g<&{8jyؽN{2=Qo}_M/{;{xFx^ TO{&nng^O" Y?cP)3o} &`{n}'|o 'ҿ!|X{z ˛7~x6GG`{A'-;@NMLRkGkԺdк$9~_|M|݆}㮢;ҟgssx2EIw?uuTγb`=l]ceܺϺz:uu5ٺz:z̺z:zкz:zƺ:غ:ךbo޺uuuo]V=4'Nݛ L[wo>YOQOΙ.BBv1}5\%m?k21Hsתk w9X¤;-WO(gQ;iXe0% LQ5P^c;Ci4QQc?dxcq_;PH*F/q#<OK "nzb. ;9(}Nf }dyʠw8xwyҾi⧢Sz74YCNkO\PnZ7g7p?:)*OصqC\MjO̟q,MGԐ} mZT?3EP;IRLFQidn&V~߻dΌ]$w-bUb*t o,}՛1]$~2w)ՕՍ&.t i<5ӭE"kuiuZɭ]݁@r`W`1|q&bm*œg\@2u.V- )Hyysc5ZJ YAbtUCQ/A )',Nuie;֛RMb]pYpt*d)Slu"[$ǘcl]ʫƬ!ecgdV ZsǘWcw]Zfc,qmUweh ϙȪ JJQo;\AU ]zҝɮ*b=]Ty+*fB.vzW )r=dԷ=W? 4wƺW%NH)qO<9=<_ Ӣz 7Bb[Yhz= :OdhtF|ތ)Da>Azl":PELي#tlz.zlH*!q1ID R^&Ut\ƆX2.`"t2rҜgXOռ) [ ;A#Jaizɠ⊌ycuyo ڲ?цIm+ƞlP+>fhGПٌ@}ܒ1 `\>p8XYWR9pqA'W -/-uS녺jm2.&ʻd]{an56eDzܢIW3D&_MsXܦ"E> /[Zd\AGwHd@%$\$HdKğJMTt15I|yyW V"X14l.1˱5-/3H?Q3,4*Y17m)1(A|[1fa/ *3̈́G%0 1(4B3dQFI1"-a *B1rua҄d3x~Q 5('AbF0:'{z3QX>\aό(tThEAyBxQƒp5L WQԨ\L(}TzEAD4a݌(bTYxEn7__e(F+-3Q.@)L({q`2>5|j2AqP_TCE }MCV|{2ע!xe5h nN^y;Zڋ鵺 l|{uWC\rd8f cPi)ƯB^ߑW 7#t"wD5qYƄ#ȥ)%͈,!h k C#| Wl GTG K1;b܌aD})sGF-__%b`c~)t+t 4LK_7"#y4\ 04µ#z תHQ^Jߑ>Pzj1²#| +,P_=Xv ~D`)nG w%^A(86ME$f\k滙*ڊOmssKM2$fϹy5j%ι1RBn $7}TyCB>6s7>fhQkY>F T5v !;M(&/aS&X|zʘ)8Ǥ #wklS !#w|3S #1˃;N-)3!&'0>&ppJMd8O+ N)ĥ")R7{Z쿝SGdȈAo*#>!SBd}T\c) >Hy\ckR9%}@zA'uɒ1 O5 H ]g)q m~VvJbAy;bȕHLfЂOuGh%l6N7P5#..C=͠]z>6K7x5#E=]fy{uG] i7筳8iH}e%e䕲ORnlU2Z*z!%'HMȠr TqaǺvk"q}F/ȉ5JDn PuC+@O`_;W!1kbq}]k2Jn_GL O RSkQ|"qMrO! \?;D䚈Zݓ]+k{J-3D5=ð}ZDS< (0&< t}CԞ^C)F?v{E6؛s^ō 2灬s^R2 }~۫Q-#d8pP{P=Jճѝ** 4W*Y`ތ rF{jFG9ֿyzUXŕ)zǼ"S x`ݬw1{HxЃY5W\YW3!YWSe }L_}_OIWPL-Cf Yd?GDwe%K嗼OLo(m&67wMj̱mll|*趟Ga},_#I*gƩMkNpCT.CTm4494N44hVԉ5:bbL++yV!\% c;$ke`2!\#? dXjsx u@taRd< sҳ@1gb.Aa2B UWZ Q<6V$(؉)<(׉^P9nfrP7XP$1;񦜽ę¼ğsbfJ*p>kwf s:o͢`*wL}pab~/ PY :ll(xVD(9+B? ^UBf^UyEJ?+G*>+G5+GU eIk I=I~-@T25^_ ZqdfO6IZjdzC| Sdv#L#j*N1 țgK-`0S4sIkuju"fAJM'-'&~dOz1wbZ+W+̍K/xcɦQCL [1SHq~f)Wq-3ŕ+@$*vީձI'&ð;uz1H~̰b'ؽza$蝆+ C|u`c %k}\Qâ5M0 az+Mu|Ոafb"/[g ŗ;È冝+_?r:ɧq^(#ȕC(^FH2-ḭGWZ%{0o4{ $޺y5oCiM774IVX-U:0Ĉ~-ǵz~\ ,q~\z+Y~n Y C$9q]^8{Ll֝y$6enɨ& ?nh2HO?گzHKܒܯ}N皋ݯy sLWKߒޯr9qe.bKxH'ݏuGz7G0l~-~ѕcDd$^DT45Z.6To+q3LK['8Ι{K65Ѣ 9%qx(ՙK&Km 2L90I<oQfP;jë:gv'<+z^}`/^ŕ &$>xNE-ltD 4UP:|}b֒4/PP9l\džL*y&ppR|čZy=h32'rF^7khVG&IݨZ:`%7ktlJ̒$|Fݿ 'eɈCo4\XfO ,U:%|fp>Zo= A8WRT|ncY\_9)OzJc:%)OxzKqY6[%OZI}+Gf"ƽ`SAVNs4>@1(@+ai sys49$$p$7<~bȫָRR2bש&= Rh̊bt}REs MWK~ҏ`vu4KJGW$wk4K̆JFVDwku[Jfʣ+һWZJg6JYF#Vwthe"Fn݁Vϥq+_%foJGW W~D։ؚJ&b FM)Jg&snINOvϝXaNvp2AmQ)\:y[ Kti(fkQfPasNo<AU:ߛWVlVw튅;+,K+bbjɶ1Cw1[Hy{wjA[ұ1-3cƫ؁%SJzUbKBtA4ˑ@g])K,Q] fv#"kۅZR\```Wߦ%̱/wa-ihQ]5n_{q_ӗ|-}\(ҦզIV%dUߧUUDZ1wzSתXZ92 ى9{Jl\1Ұy 9*ҍ;BuKFVw$if rD }S8R~ >ʛ#,;؈_:U@-nuz7#Wvu`Gެjd ~5_]{#g*?u9_8FAV83~MA'5FJR8=~yN1FC-Y#."I <1z6 Lӳ G0d>Xdw:x rAħF+c|H]Wp `t@̂k sِ> Tihr_GH]ڮzL#$k5ܳC\Q 51hde@vfF:@Ăv> F u'Vtm~&&]{ {ݰ}~DXSST]`i 9Q Mj%<?L6hx63̉WDXLTQ.oiSa1SdQ nXZYL8ԕYtHMA>H}az*٭7٥8rsj򍏜/NmY{VX x(VƔ-0lm,!1Cw:~,{Y{"L .pU$v1Ů4ub,uLʽ^;-qTWבl1d;x~ ^WGu/'Ab܉u]0Ak&{&k>pEdM䡩zj攑3 [ϽXCzvg'ZG7C  ߝ;\xͻc wg8ᄃww)Z^cR6Dŷ'7t=*M?1)'PIw#vO"Dj40ėȵ=z,!$h  n!1"0 _ZhJ$d-fO,5 6Leɨ 4tϸoLүa0ĸI=ڧd-l$ZԞaӮV#rRy-}Oiwg$ZĞa/R F=Xuȁo'1XI=aïcDp;I!cb,!Y,!h}G}@4Hl_8>%2n?:!jbbjRE#uƠ}I ߾UuWXXھREWvƽSL_^ 2\:e1 7aT,|:]REzlӻP-&'1ܮӉJa1N4JN>ʝ'qߜ&N> t5A7h^X~9aUN{1EzryړE-ғ=e['o[m̋m,\rm8O6{&UޓÞy=r['x2uQ['3 > %I;'Ai;*5#q|yM}_wK_VQ 3y"X~p,/wT3Xn_cܕ"HLυ(.pg_=usO\R ao칬h\> {7V/'9rAgeD=$hF|#^T ;K^P %DpF䒔Z m !`MȒX>A}I)b@$O_"p-%i˒A?o%, KvLxj5JjqxfL﬛jjxzt/e[1S-Yr/*.jzb6%IIW-Ȕ7ya6S- ; ޅ+Exb7 jH$4L߷iȰ)7a-)cujD ?ݰO[1WbaV1I7~Ujc+WCP')@U1rUίx-<.V 8P0PC?lA"R)J-"韽#8E mH);ޏD6>˱E*SyMeL1L.|j}՘5ޟΚREI͚ȿ4WeP&L3 ,p_۴/oCC*7lg6*K߮n4Ϡ*+LJV77ٛg=I Ze2d5fK7GΈx(w\. @6Hy+w^5f $x3~Q@[- 4̈Qɕ{@';9=i5#}k&yo~AQoR``|͛ ǙY>,Mt%e|}Z@)'/|dl דs_J[V[)Z;?+6[~zpPބ?[Gǂ*m vġQV,}><hweoxl7ehct^qHz]%il%KŒWE`ެ8nW*KvYqrq,7 }8~o? &~s}}m0mdaAWـGt.XSsN9R=zJD``Υ``L&4giYi7A (0ń/&y'u?yZC+gmػ݉DrbWbɌle=B!`F$$م&dbۇC&mA$"E Hd.~R?N]RR)82S'doLOx=_vS}chvjQ%;yAӲca47Od19pW=sz'= 2R0f I 4OIRဓ0d$*Lg}]9+P/gYj C>̿힘Y{:ȁ$g󯃧I' Qխs\_@0U:WV+Oح? OjĄda0UR:֞p\&?L*g/˛;~tYgo^g1PbǛUw3OY}  t|Yڬ>Y̪bOY }2r&?fϔ; _o!5NQyOnS^/*Q>*q } v/_y.$6Nj J牔Y86/?=i1gBKvKfO'LmV_J7?PCPcGͷ?9[?n=h ^M`<O{&GM;ssGe߾ )c8e\|g wJ8)v|.331΄ʞfdCgl-Z:yﳹ:Pd+bk$7F9|MVd Y9 ʀ8'+(Ruq9Sd'%n a\+B"nzwG:TWϲG^&9aJR7b4#䕬r%C\+Ҁt }VH;ҽ/gWWYY"\g!fEDZܿ0O,*iLSx v# wĄޞ97Fywzj5Sބ"mz~z:j$l  zxjlb- >7MLՄ'|r;o>CA}?؅%@ﰿ`MMA=|.gWRr *>!.F[) Opc *t@qA'w>Q=.H㔗ǽ.hGJÀv~-cJv~K f@[Lzu-*ɏw1J; oT/dNO}A&|  Y̸^fW]Q]ɬomԫ3?ܵLf~ks "Ԝ3 yhyyMzcN+ +a?GA㞀HzAWI0Eʰ{:a K#1B`#?"TG&7tooY_zy7I.o6(-S羔r,dwީsa1CZU=QkDc'k^5k ._qPQ #=IJ,fv@wܢ&xڑ[ 6>lxkost76=ȵ ץFܙ7IdĢ&|&ٱrj| &{,>Tw8ܽȲIDƛfGwTË]Dlr8fwcSyY,@5,W\NEMľՑ1dc]7>u ZE1ow8[co%FWIg^RjyqG]d'TƩYq5 $| [N6 t>,x. ˺8 f~$CtcF(- ȿD $B&X WHek`B[,Y$YCN)t)l7CR9YweՁ.3:S'`:> ^څ5FDiMuLp'߾Q{q>qcN'Q JQa3 IS0 0C>mʩW2!QWdB)+BJ)8+BW)tS8_q}^yMŵzH9Aa;M9ǞǙHcC:t i A9U+$yN+tRIl ݠd ɦp La >yCuz"/טrP,˅W<ASI.r]_7kYI T[Q0Wm7Ҟ }5aښCϧITr?Mp T|+O(-(ۑ@6s#倘O 4*zO *1IUCӛQ75>IIv}kL/0A9Ig0 :19gv6vIxDk/rDD X 8ȋՈyXm82#C2qg.[L >έyU}IUҋ}sG'sHqGu}>Әo/# my6_/0Xho@}sާsR9ƩK%{7L]\x0Wz9Ljdjr@O@oT k7tj`52Iix@ [⊷þ_s['h\b뜣l1<痎WoaU7k\̒0N7+Rxܤq9Kr(V\ h DW\Kh~--g$<ʷn<#?`eK'$X_=%`kb1o5WrGs4[.Jh'ϽB7] |1װrtX8Wl?v͖jdB+S I>F!bXrϤ'`ӛG?tWL2l'VoW9^5W[;,K../+z'kke.eeeuJ*Z\9CȮqT3?+Cͧx۫fI#l3X3>4ojS0H=]s~8x|fs39O̩_賚Or=2~Gv|Pnwҩb̹Zq9?3B=79ׇ˻ӣbPsbm,1i!WB.@Y#%tOcOc~}("Թ<.$AۃREbqs}E|mHѝ4ĢKuxiY(YIĸ|J#̭O Zi~@mg`fƒP[rmYU ,.+ZY\y`a1@Wr<+8͕칮;wjkmդ[/wuvزY+1öfxX,ʾ6`;& ̭cS)4y_@]}/&w5#5/& ;;}7+/z HKԏg.kk=lV">7AFE숥˗z'߱0͂"|W^c>9 l@nJT̥*.VBTp%2VUԒ\6N^p0 ^-ev/b$)) )~>R 9 Sc/gZKǥk Q"4llc(]lD'46Z@4rE~@Q~k0 EcһD6)S<ˈ;6 &QmhI7fu4r\t3yP89E3ql<&GĦl*9' $ =J*JۘƬhƴC-cы+}S4" \QHQg[S%$V]Wt}$dK@j_1<\ꢕ|xHZmY)prYye7Ȇ.^IboGs]zE+3 %ߠ/k .6n=vL GLݫ.}HA W"޾$.TΔ/ R$SR]0u%L#, kG'׷z+I'6vx?:hZn~+y]ģm o#|@_sȋ2+^/FˬmNxm{5l%^9m2;l^_c4Y- cS=I՜Jќn;lT+jT7];ke1kmN.&dߺǮ#t u=3hSu#I3+Ex5mDj=P Ğ׷e>H@$MZ/Dܩ5 ;HlV!x-#OMW]l|χVno2-R-_K%{K$!E Tʱ_1.y%7͒8˜mx9/&sd]ݰ|=D-7_g9nes~ZS1oV9Wzv5އxVu'Z-YGxW}pgXD5Xk}cK n6b{q*ye,}huJ1ؼ-tDI˶XqAUJ-غ-[މéaS['ԧxWJmQsc.+j~U;iv uDA;xnӜ;p1 { `Җ0}wJ )?FBp||smYK89[¹~*'s F(59CGg+kEpbxt8"VkSh[=:9¸Vy _?J8"VIO/ ^^?Bm Gg߯5oRmsGg'WXno& G9gzCW7nmGsgW777 ࣶ+kffL5$_- e'Xn  NoT議@!pT^*+*,I U4|pbG%KLcAB#@#{})0?`ݶ1<0Y+!9*wA!fi48ѐX34Z8 rbf^I ,wDYWpBpA!Gf48ux3 -cEUf448񠞐ŎV\Y8dGO Wc2͎6 38;7?8|idpAC!W;b~ZqҶ톜tD< iͅv$>Ĺ݄h}VkL / iS4%xbº`D}xS–aw̻*KBP%B79BW_B<v*t&$2pKÛg-cls'jc"5ҿyb[xaW0n s?uU"/ } {9$!E:tUh0&0G BƤeC`^gHC`NǮ 3;'2$t 0B2C0=E_P=ўp PX՞©@ ~N6v1rѩP i+\ gb%I0~[)edOT& A}e¦F)fD27V#5:ؽB 3.ҨhVϸhE+-}xYLd𧐍S-^;dDE.kAArʦkWܶ6U<<~ge<{Rs'^9HXDGXitꁥ=O\HYy b">Ƃ)jO4KE_lf ;!'EWfe{8!JDȾ:w4~M2TSw-Yim@ZZikmiQM)jbbDMc)5#j/_TȷgkfO8Г=|qa/]CaĆmg~ȰRφm9gHԣ ež#Rʫ2q=?t5=6^q{~*֤}CE9gQlglɆl9Ä A20a~ȨІl9aȀ /e?Fw7d~9!Tu܆tP9a^ 2둹s ,"Pkv^P=;LT &2 f&:¢<}EE ',++?𷺯dhck{֒҃` $$ :$R(LQ0Hyg?{5v_sLiL؃ D-E<𨹯^P`T 'XSA}CEMݎwa*PXFC F3 ']uwa<c8B>Bt (U0;mtbގC[Z[p~A>- @M ߜfO۵YYpάYY}Yɬ!LGpV~kARQ/!^8#L Lߋ@L8L Lf =6pٳX_&-,eɏGL&,]'80 ? tdɏ8J ;7@u00_u$L,$kETw׋dj kG@Ck2նlDuzL~K2-|?ÿد2,_{R_l( +_md2R)_^R[_cp:kw} g9`wKK̗\;9փy99e $/~Β4X.=,B3n#[z\ȣs-v+on;  n'8gRL\ jso^Brsֶ-bSf0圷mlyqN Ҿ,G^CMϹ.mȓs-0r>f>^HK+F}o[&%MͭT01@M|@㢒faC=1 p\2DHJ K2 1 I+X=d,\8|O;d7ńE$D$EE_Gzxp"I {;E/шStJ^Q?+"z !$0 `8@'$D"bk4 1_?$$ߟDLrD%R?_<660x *p/|T:〳&UBvj*zr/.Yx c[٥>"jIR1/_ػ4s+])7n>?(b"iYjPoB\N>wl f13yZ>uh}}Fy 5}aN ޣʁ)[W<Ro]7֖DAѼ$7rPkQ\d .:yWdӨJAĥ*y8ݤ-C:;%z{(2xlsY:AvWP9fO\ƪogu,ŕa%riӌx|^Sy*}-{>'Nπ(}vclnmL`R8$=rѿM;O=\-=P(* (XPƎ+bx袒\P=, pc k)bKك:p~.&P_m%Huq`&l`fy~])[5[ }tF3!7&]O)žPI| O>=z՗'o>wݳҊ$=h<'ɟHD2tH4IHq~lS^hQhJhc>SyԪhALLܰW"=)/Q޵TO&pgلlm#1k]D_bM?荔};oA|$s qH%YK $;)Ơ}׷d.֢!&g/GiOC8R,ԄӪ4$ d.}f%.B!^X8G,R]6t|EvGa4 -ذVG BiGp su$ѼNh:mo^32?H0xDJiz8+,ђ,A4$76/ [aiD̘]1V~plU8 +2bCh7Œ: ͥ Vؑ1gKk4 14M(ure$ifƿ6*''ieb*%+^u: #p#wt@%ı#Vt6ۼjvbǑ}:fql~Qu5qu˛A:oQfEěT-Nofz2/XU@ڣ =᎝Pd"_+V%ћh bZ^g"MC=gXJy 3qb3xL&1vG6͠;3GySg8G!J7f@Qp:|giE O4v>޽aqg'Z~~}9 1_aso'1;~p1f< g5D pm8a>ͷ5찟\ o$sҴWՆ. T#I.WO$Khj9 ωX]D"1!1HӤ@Vp`qIz*dVޯX=m3(; dn u_Dr΅ /b2E}fOw Zbv'Wח#p%v0|4="a`tv0|T\{`tV-Ӄli˲s9t&O>!g'Ai%Q0g[`OoTmC.?2OqhkbIQe|7no5&!g !Sh46W;C%#."S?W"7"C!#!FEb&.Pt4j뮅`rɆuXDF5De0Bn^D_u^/r BÃO _v˗PʧL#I27岟[0[ ޳\q+Gٵ@VԠaWvO/[i1=N[I =:~{Ͼ2@4ol/RO U‘Ds9]/g۳\IwvΆg\P{~ɢg ϓԟ?-jz[W~V٢ֱ&J]3pQ㘢=gmS~iN_܄ %DD_-Zr~b >"^A"n7"~$$$I|III~IO8}Y H\QC柍XbÛ6U+ZzҢ&>g'w5 YzeYc%~ kec6䔾~b!wJ)ǎ ...ҏ...a]!R r֏nJ£5SA)Dgk3dW: qԩNǷ.R,9HG[" щIYYwW,ZMAc.纫6Buʸl-7p\c,}'j -;մL:rQM`i"wѻ5*C]G6>()6bUd DL\+}rM jt43tJJܨq2>f@83_fQfdJfec~~4uש@L=1`cKHO}\o}G$j WM6ʵV>yD7~TQL|x%.gycpǟKғው[AT!s|95҄ឍAr9`S^sSՇ4Ae]p.U{+F!s|YWs+H|W p8XlF9UYv[WÞs⫢k pYWӍWZrWásk͛ùsk)aN{Mv z\قv/k b딤;~;9MlG=ςp X%n K Url_7e "1I rS wJv<;,!>a&އ Q~>aY :k$> omJoPMke{ ϲO;#31!޶ ǞL8&dY]c*BQ84B'@"?_lB %7(b"VHŨ^KF=|zY7"'@AEՀdÿP#K]3rC+T|-hϭ#Ϥb)(-(.QC͍]lFwo:@xC$HF悓j$]с 'D!r6Б2p<~SmSi&hW7TYg8 w(rڮ<6\m~r7,q6WB㘛^}M/* C66 f+w O ze+ 㸛T0܅cm;UAv 6 Ν* o ҉',k'Iդ߽Ҳ,ymk''i[&4'^leyI׿tXFNcnx36W'fJlyTLnE{6W*׫.m{Szso+ܛr^:sw+՛v١x |՜7۷S<5M\8;tRy1uu}|+l/#Aelk; _)gjqkv@l_veֺe-,^:: oo ۩c2!@UoB_A0CuJr9S[ǔA9 )`k8ew] gFw(O &MIqWړ/rM 3=;'EVWӦ;'AM93C;'%kWpSIP[к"BdM@%j1@RYD1`F"eաt^SxCn-闽iH>Fn9 Gg}W$jr F֯+'L-UM^ m[ 擯\E"/0/CQWH'922)ƴ@\^FUvo!K.D/3yL{7xms. `ڹnz$?e7Ѩ=狗׷}9[磗rˣrr֟1jHk]ln]Рf5mhn~<vMx >/wMρˁkқb0mgnr <Զ+GpsM|St홞_~)s.oJn7;7{˹k\"̨7n'+)*RB b30gu&㭙],(/d#Q^ בbf/FV5kTv(^S꿦xMߑߡߡ &AĆ#1x&A\7k-4MNdW6 1 U eef éWp`h W}*2ܘVhyQ>u*@)4S>+J$Ba^ZFmxp G*1^hyI#u.1wP0ƻAw%Ng1 zHқ܎vv"'rz~9| &K0'hgPaGMK}4.6w,iGEWł>Ewܻ~}L.NIbox6,ֱaqTqavȰ@TBXQk\mǔvm,8JYCQf2U_"/v: |PqBQB :*diYQ9!(# e|ZQ4!(d.mm.ff.T`U`.ecfc.[+# /YM8+.=@&$=Or?&ӎ(Ik#M:ns_"|Q5 cqoƗN?`(w!lKar?VkO/܍5/eX1'E?M]$zNY0sa$ZwhN#'jj> ke%_Tt*(يnU[tث= mEt/핞JbEB}ߒ,* ^JG@mO%/e"Mz{%RmQsPESK9-)_+<FGAM]O/en"PEӽSKk(xv*/Pc ߻ hc?a BD@Gfı|M65 #`u4U:b'y4~蛟f`?]%C~IJi& 驢@%6fG \wx]Ʈ/>IOPbc^zr[> +!wp%v,J , DI,I3VtB pm2ܤ#-`~`/$w7U=n=2PM mGo㒌\+c>&dOKB!ƪeLzKRgTēzKܥ̨0$~Ys{%BDܛ$x "ͤl[$y Eń?Yd联ߛL.>KrgU蓵{ $BU[L]z뗤d^_3'/HTf'{ۖR9R%RA N0=765Elb>-6 )rby q@ _CqC!PW n}j2 W9M ? ޻+t+hddJE}s.z{yW%*BK]WrG"]ʒ]*5!d%oumU@)BD2dq*7]Sەq&J:}m8曣sJ(Ca*$bT`3J _Gt1P/'<Abęa3J@G{FݩfuDFaf^uӡNufFNގXuafA[IvǛ)WZNm&{=hf[1F&l}]fW0&n1 B;*۝m]i;᱅yLKD1EhPwi˄1EUO$Ù}W;Bޘ/ o6vmBp6P-zQ[r/ UCgc Ŭ{!=%F%TKD ^4bww1ƻ}wwíwq#8ٿE0"`r?'؂-v\@ⶰW1wg7֧yavoǗnI@TKۛ?dCǾ`Wy*(# e_|Wt*(M{M{_DpSTX؟zО /1UE9]eC^E+*(ZL䉙XϢ*300م00*2hU>}x?H{:i$Dx f8~qDvXWHܧa'bYp˒Pb",4XqnoGDqw>_r{ߠ0LX%b- aB{,_(N%̉[pL%i@N PccNNMMP/`M썵bk0V'MnY 5WIgVhU QoYTE%peL|LU  !BLV2<d1I8VU!<|LֽUVU2!*L{D @TǙzd&_91ؚQK<4Z Iɽ}K$\qYZ IսK4| Y| I1]KDZe zI%ߖy㍵ē2{Kd܍q3Z; >I75@MN 4qh^>HMc{ ,*|%wES Y}YhX`_PF=-z4faSb[=6PP1u昍=n)%BE/Ɯ j)BXE7Rh ={q+UJ}!c"1;^^:?/2sg )Yn+q:킨>UJT*#:W{R$XJMNЂ-Uʵ2_ #O?] K/!NkQl^qiXtۛdK`y+^iޥ8D/gAi{Z^ezMz%R7m}s .HfT-+w +@>-KބL.VM/xAizZ~)~-}f]E}B3왢=c[]|r!l0 ŬLg2FQxk˼Dzs kBľ *br?հ~|X(x#*va/n,0ufgpeㄢ#'qꬳ2ŁRc^tYW6OdXD(yFІ1, ^<]nDH?"V^bFwL?#AǦ,?9FNtUY&NU]]寸pg\tu4no.9LɗC:I7y!ޗ&}U4{^vqTY=/B;| 5u̜8uU3&>RLyZU>iR`o:GJw籔Cd͌Oq$I挫ϣ& [a$XGr' l a2Imԑr lĻ$!RqI aEV줅xK": *x:*pwH6*GXEhՌN:ۅTa2IZ"ufv2Vx~ČxDlB&X/9 Bk8888x(q9))n?{JwZE܄%[߄)CUքNۄRUڄ#*lŒƍPU4a!S7uG PUr GXUp 7@U6ê; b(N1cqS89⪿cIùO+AY |YS@ u) ڄ8sZߢs;[霹 pigakp2{[@ FguDE1D'p5[{k|2p5.#䚐 dn-@k8OA \~MhNu λEX gX"pքVkn)Ekgp53"d"!HP(Xa?A-c!BI`8P7ԃ.x+g^V'ݤ@V0D('k|L; 8Tv+@nE#:mȀ| ;ԊYhY`=4Fvڭ8?T=ϊVˎڠ9=ϋUW 9<ωtě C8F9 :T?φ]ZUF܈á96^F>7(s/m7~h|{D7RO=GMyO^wWHٗ1=z9#MBظ5-uj ژZ>mOE &QU0|NVSO !ҩO,ǫ=je}3XlZX Xq[UYjyXmX YxB/}E鷗^d3SuiN04Aڸޤ#͈O-ȑK7 Lp-.;J0V[hD;3Zo1w˕Zo̗socL+sn7AbbU)xk.[qBiW#M՜߷1]U+oLJZ9oaI̠Uڠ9ȷc/ӫxpO\7q/kZ_4#4R) \N)@[@"M-å\.T 5>BfM1م՚#C LHw.$ꖄW.= *2ąC _vМ$tcNWqd()ehe3*\+K!75T&CǺ"k*ǼmNB@0X4Eԕ*9J_GqX!nNAY1i20ߞMaz6X }f-#gk|S?=;"lwϐupB.U۴ 4븊䴐jش ݦ;ªM,T^M50O41MXTETcYU9ﰪjON3zMˆ90LsTYU@˪ipvE{;ӒX.iA,Sjд< >͋e:MW*ӢX+Uشr ?<[|-U3~Mi7htBӮ-pM諍C_$;!C6-J-AANr\iMsZN)i8)5WΛ0n/p-0q W?Ș+- "0)hx^`[Tc[ WSD9")Li*^ȓ_=nӘfQ+$X@7f + h̰b. tk| a`O^- q#Oԅ]HPl⸣gPc \u9,EI.7n-9!=Tu#Pj$]S8;θi/X6!Ux4NݎwFm!?^K~' m_Xr n-\g4 C/.K^oeEc\٤3 i6u?)JOnljD/t:J)g4<ʏ^t[Qx:N~}sU.+g?Bs^-1B}{p/S:ξi|<_t]R~ Dxj^f|DGm]ڀm]mЂ\}~+hh hh+`]A>0Z31~+N.,ynׯk]e7߈wvu`їsC=VK^]G>&wz׺oK<7n .?tKv H3’%#&{R%%+^M !%s^a=@̒ V A`@OAπ̀#-- '|XTS6k=Hԅ=Hݎݯ 6{^6b};=XBX1w`{XlqokCy5YS_ߒoddhGjGC|;.e_lv%V\?!)p G޼;PO ^mPzy >P_qWWmP] WGcnh|lqׄWOX6K(vqńV[XNqWq,l3}}U˛]XRhuB~v\S VQehX XF.{&-lD.,Gƶ##;!ɋ{'m@:ydr~0$Q~u##fY|R,Rf۞̿oy"\y"-CJW`" fŽ%ϯí_.KBJ:VAE`HQpH{Dz#cUq-=y޾iApe}ؕ5pv+A5pe^ؾ*.A?w;Y۝\\Ň+-[],_},+;qw9 6#W2v9NzlYu$Am<9t}49M;R;i(n(777Wq\q(|`Q聚衫cհ.1d##Mro0G}aSa:iV+4>:e(ϗmM2\i^6EO,}a=ޜΘ =a=sA3+d)M!IXW}%Z !I>pO!A*Ip(q"K@M)Iœ)'$XS޾MPf"ǖGGX0ZD݂XAD MK؜I_a'yQua_ߡa>'QPL@€|6ѧ?嗘z`RaG11MҰ~1e!JzzJGYϳ ڳ(LH(Ck}i}1=c}*9厖PIRR]i1N!zz D~3@!| D~=zu` D~[F֠:̉dZ._bv`o 1@ D~#]HD~Go1]Q"~`)zr {Yh2Ȇ>ddo48iX0XFfl+騟s_i=2i`69{dI>.Q݈B?`6%}Ӥ~`&Q2 ldIC4G,hJ&I>EvR;Ig<~Y!tOL&Z,i\M7jҏ~Cgd=I'/i~'W6Ecz R>f'm#%T|ɴ/(O;]m? - m=J[K]Y Tt2ӆ3;3Lk(@4/tm|ӗh_Oڬ5ahoLKMBмߘSi?~,DP^ytwxdo;1=u⊞ 'J[88/@@S迭?2q?K~+Km/.^ rF$!C *v c{Rj.& &/&b ZZz I!KD ƽ D; z;{qNVdqDʽ$^ l;tZ0 z; .x]/CfB [&ך>!Ʌʚ>@[R!*T,ی&*: +VND8{X#?&6;X}L:vbpn[q0 ^K+g? aK+G ,q_h"h- G$1u͵HZhėkmŴ&y&-E'v']G%&DbKZ +MY",MZuLDyD8&ͯED$D$Apakng&߬v'X=ÍO,[:#OZ]_']'veT55eP7eP 1UeVͻík*Ro*Tc*hO):UMSq d96Բd$spfL'm{4j"M$ZP'4ű61))ZnSR4SRC-) )2Cm))q){)qm)&ba-)&Ram)ۯl_i3Oi5MdSFM${ZSM{H#aL/;N:f>ag^1%oߣbZ5}CkwB CBȋiC؊Cp)Bi~nGgHERG?qN,p~̸i#DH#ǵB!= #QD%*=mh`<8l *ou`/8v * Z" ,COQ]AKDW0 Y@A^&[0sA1*]x` ?jL>,L>xOxP?$ӓ'ٞ>O >Or7}؞ 7+}pm˓|l+v`Mugn~Ӈ)0bJmj;;6cձ7}`eۧD`ոwاW~Ty~zYY))j ~R)&w,H^տ,QY-0vmw$p|q_.yh;}mw"Uۡ^W}uw+=%V-nGWvlKޯ؎VV5PZYjk;:c%r#&ɱj~;"RٺRu T+Qjr;WBwm_~lz_Y+)ju ~]ٳ+7}}ɀ}рK}3n~D~q3@*RgFB`~ɆH~†KR~3 'EF\|56Vpۆ:I8qEĭ\q1ITg?3cOc/| 0ScL#>NtX3ҽh0G `$:f{`ZR=1f-i^ǯ<0-1Z-<0/yQKg,Ʊ%sEQLaƘFzbt#xzal"3J0<0^ ad'EQ?IQ4Ƙ)zbOwyaN21'Nt2$q:Mˆ:Mʖ;V†34ˣh<ޯ#ѷKsjh==m%1к*oa^TzIJdc9 ?] ZI>ݸ)ݧX9+%Rl+%dWy+=zx=])xc,\ >x比<;:/zڝ(1zڝfo7byv'm,Evwv'ظ8Ͼ|Ⱦ1tP^slc,::#>ic,"zqzyv1 ; NYswgYzٙulc r st{wR\SE@E мmE)m_Iɯ)m[I)NɨɓmNe vXɶ[Tv$47K)P^'z>@(i@$1K  BI#. XzӴ1"CJ27 eKwCY1Р4u Q (q10 J^G^eVo ҫ׫C10uPzCyQ.},ʱx@R aF0tCP6!F (]{z+e=eDA9/1P((0u~u2;~1(_PN?5r=h-r=Hs`,V?= MxryPZx.4yT ,4)/] /4i`+=1I򠲱؀5$ (!_6*GGpL,J ۨ6`b=Fc^{Gı;tAD-r[jA.F數{-hF"! 'y]A '+w y|YVѿ,W-%j.i]Uk\՞@UDR]5Dj^kF|_iW +Zl D,Guk#.U]5C!jy5>ZhU6(xs?6]Jc׉9z>Ixld6Vs`Ӝ>ZEZ 66 ֑KҭhҺ`s$@Z6"A5fVhfW`?m++fVn n6 G5cю{0+"j+Xmajŋ֍+{m"JК`+em "(:`c(ZX ;6bGkBNhcC2X C;kdGвZjNG#XXfF<.]bV3<\3AXb5SA_b5A^b5Vb5{`0A`0;p u̼Ky9s]=E᦭sO/KN䶉TЈpM+\x<97 k>P-l4T z@5PUt+6:w^(3nWs0lؕZ Jg6J.z]iV+lЕ\4 ⦆R4(1qC!Ex*n.K\P"wRP S\!O!0wy]LP$wq]Ɯ&5hHg`,?xPyGnT7<`*Xݸ@X4P@_4ٸ@^4V4xk7Eߐ@eo؃$ /D~ ־`kGkc = a75Glj|]6-a}-M[cG6{-D6/CONaM]gyysn|_FSŮ`F(FMFͳMCͰݸ^]HnhG릗tl*l^܍o o؍ekJuE566oFǾwlBz86F44B/z2w.PJ͓ݰ7~?vc/7z] 7B.zv.s1,h:H1,;1,8(0r"1!ȥ`~䧪9G0r#\uA.nD;(!W 90t!VKW[zm9>5.qN.R!k$8!#!5y6E{H1I4Ld#[}Ht[MCh4@#KqCht<2l49!YRk_2k.~xd: ¼:in/E.9N DKaH%S+wI$k2QaX҄8DZ-YB %Cr$d2 XR?V4^2?S.~ Z;肰/i@#Nǡ%ѫHؒa6}NhJ>;tM>RyFfjC>@ ˦ es^G P٭v([9i0 Jf8d;3iG٢Jn9F W*;"<`sqN8j/綊Džb_Ů`KV qSlW\UL tVFQ_+eb+.3^F)7^+^+Ob/&aGq=KehOKߞ7/cza.={/#{`;.{~_\zٱɗ.0e [s,;޺w"/=`NUlelhWy|< ׃}s{e0l٥%woleǿ*)e5M(bq:Jy DR^%UoR$W%W QN̨^%QoR\'U%VR%&Pf"C T7QdKyf!=}\4T X ޾'`WK!FQ E)A,9TmuJK+GJ7%&DJqoXL ܭ#&FAӇ7 7C PH -Q"y+$D!@_ߧ"u}o>x+K۷VtFA>\o:Xo$Xܫo!Xo ߞܪo.X؞7,D[]?S 7=R=$[<`:#w?P<$j )Twʹ*f xb{MtƎ VJZ?"夑.Ac!-4dDef{2" )q?{2dz- ޿1d8rHZRb@Ih$9ĥC7@26.^8HL Y6nm?}VO>gVʰ;eAYtUqFO`󵿕p[w JA{qL6fs|J4FuOd/<u]-ku#r]%oClesdU^6mrC3QMT^rRžWX/{/"u^>-#i-=ٯX=LWV}yN(V."1cx1JcXb{k THva׼s1 g# Mu?',a΃IE;7 *ӕNANW23+߄dַ村餣uz6|ܶ3l`ނ&X+܇% "]t+v?8<$u!+N-i'B$|cZ~0A7 x9h9UdCg}_~v`/ow;:O` #RٺRGKNX{,}{mG~[֣v:T>o.MKe`$<i+G=,@EzSD0AD+]_pΛ LuG /+/95в?.1l֡ϻ~k*aA.^0gZEsq'6v RÍ`/ZHijqqr[!k6 [W7xfal>oݕbc`;ikz C8 7.~xKX'fts7F¤S~hO_l}ZK }ǥًQCt4RyU(x͆̒qׂ\Z˧`:'jvOv 'PrCF}i*9U siXU/d{:)+ :'<vG&prq4!2!߉Ib TYSpkYWVW_n/ڽݐ=9G|Js9uq~ްhw s-9:oq( ts ?oo.ads2Rd'9m+k4HuO0D%pX՟rb(jCC.ߧ:7B[3:% ʿ=|Ehϻ%-]ytgPWN?ѣUQ'˂tH.̛TGЈ?G ށ}jVp@Gtt,R*и 7/hZ)P|;+h s!c*7^#P}=֞sty&xG5ھwۼ|q = ϫ0½Q]6cv m@4Q} 䧳z2Pf92|fw%#Pw7kJu5!. -w5:Z#v~=mZ_Dmp[o[뚛o~ݚm!؍`;k~'9K:#2ViCx.m-ˋ :$AS;<׺p\MMvgY:i˖؆%l17 qܚw^?usW> >a{ r}B3O03JbeԪN%QF6|R\dӑx؄斃n+ >$-dR5>x}ϵQ^6MIqi-CAh)6wGOoy~P X 6GKwXT36돐&Mu\5;俹/7 2t,v)sk9iM7̈,keN|tS'יP `Q'I XX~VGϮ oYz/W+P CnlJWdx7w%'{We`$ug9#)* у!}x9㹜^dn)!~8xe- 9SmKG )#cD/| a䬸~z.뗾1nIÂѬЊAݿGꇯ'^> NR~Uj_̫/{ǪC:U AE~ǁנk}BW" g-oײ.jcw&4C'[wZk;{o;θ?fQfSsy-TD]HvW5JJႮD u Qjog}$-WL[{,].8ߋq"J#S 0dM;]x/Ekߡ3B15RmDnCv fS4sj2s,6OH>%/K/ ,X䆮)`H&K& V)9-)[8]RZ:&\jPe_~4E=v6\N^5MU¤kD P=گ[,QX qI~nT"z^39R+Ap ͓5Wt)ZXMoaܶ?{ӱNb}K`1wjy~d}F'! ~NY}8aS7CX@R0rQn+ϛT(qqyvk :&6% `ģbaK^;`9^UE >5x"  ۫pq9 BRML.ٜ& N`&)a7,bF}si=D˫uPi4JBBnYQ5 ]zoV0fci(o*Q{FgTNEhw^n΁H&5CPZ%V|}2_p=X ` N`G4k)r4~m+efTFLҏa:T\ԁ4a_ /7GM,(ĉ㈷]'t`D4$Rzoaٛw}q/7)jA;nUJ=VU- kHDh&_xwI؍9 AvAw<VW 'k('"2TVW.m{yn-3›u::gl?AG>  {[o혞?c5)ripx%ѝ4'  Bg*f37B%?`QMAKm@/õ1)΍HR/ ƅl{.M>W/YM7>F}$#q9y9!JH頿7fs^kdshN2 d 9_ v?A,BNX_Wg#acym |, nȅ,eM?x8lN.rv^n׮, 7L [fe6W~ڈ Dɾ# *AtXC=h3/{=D K'r"H+",`o!煁0o?- La{<,;7$vaYrP#b8xl/%}>6h2 A'i\0Ў QÝ^ņ闲nk+_&X4ى1Co f8d=]?^(E]r +D2pH:fyt4#ޠ1T8C w B}GIw4a~̾J[J.ѽu9- 3:B%iE3{sxd|]m83m#!짊[̤~ ɠaDZHXW_2=dŎ()'lRl{h&T4gƚASPW&@n/KYfo[}vcmf'Pc3aR^$I-bdF=>97 Zŧ"Kc,)B]TN|4Rya*RbȜh=R zWa׳WdL4 O$}%췖KK4!G.$8m|C'V(m <+/mx~TRuE, K7FQ +r\04)xJ\d#_ Gq:aS9ѬĢ.㐴C>G,E},vob+F-;睁#,*KTM WFsD4d$]<쾬 m4BWX F^߱:xoɁqA/(Yj*R&n.x?UupĮlHՏ汔LXozm=9wFmnqҟKdB֦[ oR-xȌaQ"|~=XP1b Zk| $05{6M&%C}A =x>Z^ aYsڄ!*D;\,oOyscKY(/vZ6\h?`2R1~;]T:khcХ~.KL*xlxH\qqR=X4VT""Ts17{݋#RrfO뙶5~٣` Eg 6;VXA5/ e~[!kݫEP/wAg<񹳨z6'g9.{wG`?L֒ԃ?I\6P39e>w5ṕ S QstMVB/0i7Vͥ 4 ,BPF*8mYtN>>9"*\ӸHQ jHqki sGbԓȭlpʏzGRj}DГXX1Rm*+e~ϼUkPn5<`rbΆ-~GY&@r%z:SOB[){/q' bG*j[. fI M;w9"(އy6z! "~=Wd(F1*C 2$±!PiD񉬔rZrɹ#Ojl Z="־T4(D@)8:p3ڞzdf)Yi2lQ@lQH02DYշeH+8 :{gW &}@[`F+O7HzQ$9"{VM#0íU敛Ə{NMSM }~2w37|`-3E ~buNضPqiK%,oc$ +{]v(tFbFI~S!%oTK%jIRF[`ګ<Fԩ2ӏm\j6as#`w3)`@ԠoRh}c4]y8"">cVaB3 h 8Mg-SX 0ymUjFPu@hVnY(}&TѲ9L!~QX3[ޚfv n1ܸWϽ)0ʐ_ &j괆ϊSيB3T=A΀oTQ"xcvR n y')INr'2hNCg)(=4"O[m97kDxM]-uqrfGsRkh_ꇒa>MN8 P6n>gR{\3TyhPTV[7ktu`˪+ e#udF:I#ACMÖO&OgF3߯:|-,,tg-ꕰ"a_2:U.Yl%Ako0ԵŸ8oN?_񈐨MɣC8p 5L\6W, ¿ s@O,#4$V+,4cHW2+5A 1EeL ?7gi!g)08lM ayb<ݺ|.t|KX$}w$"ɦ0 <#`jZRr%c>o!, +Թh"v4.Bpyux`uE G-+/`NS!L]'ȗ6"[vp4ijX*jGZ# ly %$hl%=ƸP7/>~L%ZkYPAUH'ޖahp>d!fD*eN_S牓v QcmL3""CQ۷3O:8㯅֮mKK8{3iaQ}!*l^;I-Z#HOP t%f|%%2'STE@]y"c4dAf"E"][%ޔ Te)>,[N. jjf?;=P~vȽ|OLCs4{aŸfL/ve[Oݾbn"qQK1-JKa#l#NAz);S zRFq',IŀQ0雽LHj)jvETo4VK[DŽc$ o3w^x'OSm.2Z( VLo30vDI2j" t* Z?nX1(Hp DxwdʪI;6%Э@  $v v*͏#ڶEOy(jRaz)'; _;  ]I7U;L<ZVubzɖ;krGb,/t4Nĸg{!,eS͗J]m%8nعjtH3§qk7(:jt0q I^lof=7'N'_]&*f̞QJ 1~__YtF?@m~ baU=x?|cYezx-΋gKz}%|szsJǚCk&\4AYJtU}cJ"mW 4Yȿ4O SgͿ,P@ [zy "@3GlC}<顇iz.7cr+{eKIc T3OFBf~FWƹ4=9 Պ 3L>TAET)rGL,Ay&66fdPGu'du1*yF|3隅LiisLdжo2PO3w&7ֲz%DEзL9p,<Y NUcnt+yQ#B=lyb *oe(UZ_bv%QOlDI׮[W]ˆZ8eYP $zkRKmpXX.L\r1`i/Lm3bz.Y~?m誃5% 4g RNQ}Zs =86tCN8*}eatUp&7B]rlG{viGȲKT(X֌Πn=/Mwf1:Fy_ʜĖ3&vܝ o}!=ݱO뵇xZ)rTMYs0A;< h_$`>2']EcaּeY.lckg1zGkԦhw Z9*Vqk`SEĽ ?ݤC \@9w$M-[5dBb+*4[K~yXκNu3z(GQYxFQmv#OC)0dT"@.MhbBɢPr{h 9"J'Mr P;W*+bo9\Ig]'s4RXK |t8/n5N"7AxOG ,|}qtv+?Dț>K\6)?53=|C5^Ml2V̫rPy\\#O0Xn1\9Syp3x H`$s%ZuhlkRi96\(PF+ cZ6iM^^[,f\YlMJ[]"DWڏ*hIPn5WY#Ewy z a1XpMj4e]r*@?b//J0l?iVv[-ƤrDBr$]f Sn k%ηL|Z\za]bUgs>vNV>A\g&׹wr5{+/nP%H~ҷ50YCSg'. O~9}A{\A[o3:=H*n\u;WYxS7{Ӱ^j`  5 `"%YGWJLF;}p<Ri<Fj-ٷ ٝu6i炒y3B.!sEKiϲi,`C}$CN/u};m ȄtThkQ?38kw^q}hu{NW;L•o0vZYlBϘgz[pSu 03+A$O_ T;`)q.vr9.p]]w*'!2g/E bBf8@H| / /_VHap#7}C`de"g@@r / ;/ ?`Cļ,V@召wIJpB @ $XW-Hz5d$M @=0\@$쇤a/$$:W 0v:׏?6~Ì%_\{3D$_("_:W*`l);$+2X$foTC Q%ހN3J&!VMwb1oISLoޫ8LLP"?mɫIӫn#=^So㹲s×N宼xHL]B;/|\-;l2(dT/dH`;|.vj;@=WOI,-pp7R6x4_`S[]R(FA`Yٸ8@qr+ߋw{b ixAg\=" 0}@@C?D̰9xr9w1@,C!J aCB_8֟5b5ypxLi_?g_3uuP ax[KSw֣[)ZLE "Xr '1sʙN*k`TR3OGTv15wynf%~kCV 20ZlL)NOu% Vԕ[=kJ^`P:VLBg/`rXG$ N5>ƬGGyn4mUDgD6V5 z2}7*yx$p_uog S}pi5jwFT2 K˴1P͖N>%/Y. ~t*4VI0Ʀ`M)G}lQIy&N"b/C*4up༥K$8  f.*9|!iyۀFZp8p_b`Z_툂MC,w6"X- F?c}ǰPHwӇyʭo/ϷhK햽,>BӮXTJٴD./YPftv?QѝI']T*>LFYmedk՝S!$djsBԗ#Ee,8?jgiR#.H/ _fz|T-n^n_U޽ 9q- I QSo";5>Q.C̫e52/ +lKE ?:rZ HTzo,~W쎺ޟP^y"ۆ "OɑII<%!A6L;҃_%>ho/wQ_ (#).jLD;}eg`#n/:~P\\ꤌ=G~ @Yލ 1>r :챮o  )[tea>ԧûڝJ/r;r)tw5?JF^ +GK 0Dyby"o9ҩWxh]+W;;h%>K~k ?oe}! dZ>E#`tKL,yoT1`Y.vl|2H+&^Oe؟fWiv]U+h"LR H5&YM{} u!t0.:O즪i@>vHֳfwLͤABR_tf9m8eO]V}}E|3KhNgN/=eyqm&Z;q 16cv=655 5 fC.7qP`K.\HA;#2j"%CjjgLm+kj?ʑ7WJ0_#{C{pfPJ+o, 1Xxs~+l?g{-B &eh3*ܤ\DWmT%R hIv|-#Fh%A\+zˋNZIWp `] Ȅq]uٸv/^#{QZ;//dMJ6w "e٧^uFZ̜&7xE{n0He\}k閦BNDdc7n`xn ?f=2z&,7P3@, ,a&GV+I" "A&cXsa8fȧW=ccj+ަ z/#bܡ# |,lJZQ .*[*%ԵI1KqqAcQ$ڟ& a^_0BM{AIJBH'7CEU;|xߢ`/52M6THEeJ PqZAHF7VّG`I6=|/'Eygl;sb$rX} VONC”Q3olML0GJwGI8VXzM$ƅ h&K> ݻé@mTU9v||N8[X(ԋK"yЙǙd"{֓FGE0YB+c^X@m]=(sc.9Ux@"f\M|mg;9j}DQž2kxB'CDo炰3%FSwSuQ#, >|R|I^ǘwgpZuQ9\ˠ!%;BWW%ϱl;zF oE;:/~v~([11 R֒CчJTRǁrWOM<<{[l,p L1E;=< => Hvˈ F% R}ь.:"ck$c @y B%Jf#ēBhHVU,NWTb"T8j)v|aZgin h?ڮ9Z_[ל_tAɸEqt{5 S8T=`mkHKMT/R\[Ŕ9|c2!f}je7[ Wv+~M&f lp=rΆ\n jT"۝֜<1/҇NLJ UzY=SE$ g.;M8l?GN-tx̲ ˩. K"`ې$ 6u0ic7vޯ@"(֣^LFvzA"#TB`!w8C=5?lhGRpoGC00~d*J7!ԕ; ZɞP~`6R}>$Wqc/5gw )i`(2Q^`n!LZf0yVC%99RZc ܇+(1{}angz][;h75+7 GSD'*q3?W+IbŚӫd͓Ih-E cוe^'T*]2zy#ߞ^vfFM/ƃϯA:̙~WΤEW_(P'6&$~է Y:dV#lb wt_iQ8Da U;'w <QkUTS0wվӢ+[ųOqWRTQwB"?KLQql(.[C#kN7Nq=www^s}tQݣzq)ƖulEFtbY<4wkPp@>1|5/a[A6dN˙Ѻ"ہ%EiqǸFX.9,D Xʄ鋡?4ؼNWHu{r}užKD fDL+|f,8`II%'ԏ`$+"a|%Z#3b]4{ȬĶU}e toD4E4_Üosr͢ )gMi YfzTў/DrLR:ҟ{Qx?CN2eO&ØLA`q5uLc>9VIĠ~2) b>8f%pPvAk:xVRJqh)-lD@70I+y{f#i2%̷uVC`k[Y4Dj{Ep?˧AKlΉ3%qQ+w|nHX'BU W_k~sg֢ ܭ0,s*{ -!' ڙZxߗi8D:'xBKXe~×a|#D6=EV`U4b{(:aUD">_w9t% 8#wIUOhp8IKF>5 P)5m6|& ٍ~fXj zopuv}3 D "K;J5?'zmt)$(/g{ftp YL$1pG{美Fv_uephZ"R}8quƶ'Wwu_kcޟajcd(PZA/𛮩\-$UБe.o}-X/d*NKlp }A_P?>|x@`'CQ x$q55 ƶ@~>j07PƘRuS#V`9@@  pRPcAb5bd` 7[/@䃂x|\B`YQcpoa*<7u OYn X3×vcRDoUR+G{B#tʙ_VV$BO]tS{&bwYWccy~cW㗡LY+x,1ƋG,EoOVN8;ǭ 2k iipIf#"]+Ou-kRVAN8xwd7έa*r[J벪=_Z%3 UأvbmQc! jz[onw#" 03dzo# 6Y E_;~6ʝ0ý1dJ"9Et|5OqOךI~1x%u%eARl1?פ "r.-hI^Խ5XUnWZycV$Y%/d݃cUi ~ #Be-+nBY˳ZU"bHber*ho p@̤I++]7v6^UKL=k5S@mr|ցVqa)r7BI7Ƃ@Zi*k7nVLi DQ7LOfߡa*ED2q?̈́>7sDX0,]'B 0(x4YZ=FFY>唆@%|kjj7B(^xl$^HF~$OÙe@D_[@ ]OR;ǐeng؎Q}S`˥pW ƫ$Zo/ x_~MD_ǔZ# 2ڿ[8eKQ pX/~JJ;=|5&mZ(}7nqdZGnfX G,-ozias_]#+7F |4mC1 wtIEx[Mx#.pv\p|h˞>ֻ#&0ut--$(;12V#Y.rUKKALzf,Ex7qn ٱv '+dp av"%vV~.Y}^9U 6ƙ}P+҅K醙q52!q"u{ {Pa lgMO"}8@KG*JҫsPeF u7K ?mVvlw2l,nn-.-'·A&'-H?5bHԡlfw:&S^2uս  GC 45$q΅"zU".G9sؔˀq6%SL1㭭>|HeD-*]-Ոb޼UDwYv2[_?g0׷]·]0o~^Sv&n%Oa "j;2zhּg =oQԅk @*OGI{@浸w %K %6ʹEٳ\*8Nc[-/\Yq-j&wBi ;= wnFҊ.몳_(5wVgV;QVTB_~J/!\q,^{T 3wHGǙΌzuE=g4*g/qQߗ<{wVfxnQck7Lu=B#;U*eUj=w0OV/s{~?Jr{쏼z:ZXR}b7ysNKXvrw_rBwU2s7DGC[OZ;2SXpxP Rh)*.OCQPuG7lnKsߞU-7%(Oo;%0.δ@y aptYgMr[L/V&çܶ5g"4b!͈tO%Nx G[84#7ZrhڄƜzwu5љ[]͉-!Nzj$ /P+őO "ٛ<"=ZŌ]L(Q܏U9>065Z"vJ1eIwCCAđXIr[' ^^ |ʚ Z傠 t;M1 \BYs=. Ggy8?v[[[V7y eOvXKLunqmh%X3i~9G>XE>Xki%N=q'RqB[ڪWU8Nfu{|XP%p.oQY*ڿ\|O*ƛfSsīB#c6V/WcMf@.EL9*̈i _ ঩ u"]h{Au@sy l*]@+irT6'''MX<$e2)3̗NCo3pBemǂ4ێSĒ@ҵ 뇾xK>Z]aE>jN Q(V2oΖv.D !M9 !Ɏ.)%3MLxOBKZϒ&&UӇuJeF]V>wÂ=zC$BO'DeG.o9,o gQ=65 `~G2 gnv$U.{Eܭ/0)\g6.}-ޏnta}JL,s`1SkvMK 2ʯ%d< A‡Dp~_c/QO͚Xpnp=qH0VU%R VR[c|SztA%D5XH ݎn"ui#K6\/I`@е 3Db5f3Br/N ;ET޽ZlsϕRA?po5C]>̄ hQ >~/"Fucqio4m`TGy Gܫ)T/GD< L[Sf- NԔfT1Wy[ w5~3~2dŸfijsdټ zv7C2,oxiPܹP82& &3?ɴTʼŇXBFu{b2CT#e-:MK6ZSnX p mfl~)͍.iP20% hnܴM`ˎ4ԭ oRB;>i݄CJ@P r+%I pu%;66C,ji+K(L n@A|?܄DL| ºgdbAkZЅկLipT d(1tc|'dL7BN7ԚD7[mLs(~ 34t۳F.IvĵK-1TSMh҄2ģOpS[ /cxE)P7Jq }|Y!OY)|W떘W۫0c7`jJ y:1eM̈́Wܨ_#ޒcJ|אn!{#HzkaVQat`'ԶqI2MgEE z4ZR \RWzV+ӎa^hҠ RzZ*1oFEFϨJ|״s6CԖxT %-ΰKlO٘+=>+E=uu˜EYr 7y~ Fyd%X:#}V2v;Teo8{Vo1<骰( MR{Lcx>n2]Z$d"vwօn 00,\rPA[L^Jas4ڍ$Vc c 6S2ui[m<_$6s:U|FiEt0qx1Os|M9lCǣnNǗ54ϋrn U4'ٗ'j<[9Qhr{zw_Řh8*KONO8e&iZ0g\IU%`#[Ѿep}*p 3Wf S MBg`2[h}Ǡd*$.4OŚ=eNjfMHOgQ ?-u-xSפQ45vR6pݐM8Ba o.[=y$u~r:SD{Xn\-uO)Yo咓%J^^ :Vwe2/aaX9' I!ua@邈O$Ci!'j)ʵVj9pFvix5u"p,B|h9mۇiD|nl*>v~oAzU[udp#9\hЭU s=ΎHPL(,Y̧@_Ckqzr \fYC:l<74C(Ӯ[f*diJe!)w a߆j ~ k;p1~욭W)sfwe)7О\aciσ* 0䰚ɑ8> fVm$q&{RmƢ49Ռi Ⱦ&`9 ּves7) # /mOcҞdEא!K[!Kw,>PT]E<ЮpcAu(-{c[GΡո ŗk#HdW]e֕jc uW&*`[vn>gfGĝr ÷^z -_di@:#QoB:HrvJ!waV#}>׸\ZJ=5fq6'DJ@>{5`ST$eCpqKH1 w辧sŰ|&2ld)f h|&`YH.GHK\ [F'۲:#H^W/sVG!q,n3υ;+wjϞ,\7~]~u?dڸ)bVVY)bUkݬsGHVqW{~t+RY L٤3oVJr߉՟[&-d0oMwNGԄ#[ZW-hm;Ye^YF :CNGC'ű)[ )4 ϷlQ 6`oÀ쨀% @aJAu"vh{SvPM5$v&kFKګ9C.U6)7i;_# c,R y+Z(15r>_a,Y&S{۩msl맄{H.k+U >;ޔ68OȹL"\c~m7ZgW9Z Y 0q8Nۘxw$존|^(x` ߨ^YSc]މ#n=~\/\+nۊIi:"wؿ,9Y)GzpLxU+_VG L7<`#l^dOPXih|={/AY.@yUbNu1(^|xZ+|)/35u`jɽw j*P'T*X~h//l:y{57ן6$( )!M4”qĎ_A .S3^Uc_qc{ᤖ9&JRMWubPd5~R8n =a7W֓+OW9 faC*u-fJ$Z :Y_M;L:̉.WRZ 2 _u^IXhvߎ]B;ֵMze"Kq)d<t~6~N(f/*|]=+r2^jQJ:S88$"68rU 2%fIOXTC~YW8X3ra۱!/*1?l%ǝ%IY6im['r1OCh_Eym&MKQwp=*h5 u/ȁʄ% R5){wnrm] kcTϤ ザlw Dwf PQ$aʹ hg8@<8G.AIou`"L_,Z8)דK.4{CorAK2E|η(qz*ĩBy-@ϗ|'V];r  m#"QO!zCƒxC4Žij\EҔPf*}쵱]PcW=n|E,*+qM( mդR<(QG*Z/(7ҕ5d%ȏll(D{iZڅ0^GHF m4fQg}KuO p5ymb I)dAs7v} Tn%Ϯ?So2yFz #k{qzQ8n_" ,.9i9 |\J9UV'!^*B*S25;bu%fBDD$oq`WoI1@K+Ӊ܍+NޢM9@z#OjJQ(\E'e:hi t5uBO&"Ge7)~Ϧx aP8~'ĵ5xMuc&^sdE:X8O6rM{DFŒ pESBpK:n5rr|'.4%9U}9F/*WM 1ֻC<꽾}uzz ܿOMp'*XhfL)^P.xy &)5\Ber_RF_ߘn@ Xbb_|`R R(TD(Z=*'t>C+à x6P̏r'qqA|@^>~j7z=燣Z=b bFE! pA:gQ"0@%vPp=#^WWTH JA뺹`7 ˓"[×$O5E%rAPr?7%=<_4h͊! pTOw)7nyB`ONϒvZo/1e:tZOfϺQ5-Ug Ly uԥ|fU`g& +X#5dAj.%Sd]q譍?)d#B{M/zF%.CELY98\7@eĨP72 \*˜|F&⸜B?6Z_:T3[{5\U]cc\~-{xFH?,M;2A8 ׍fٍ du^Oxag/qx!hgț. %O;y/aC*@֝ia u#mHnrNeDӃIXBXpw4H\[scvJf@.**N?JH1$޵2u6z`X7۴Ͻ\($5'Q̽m8uW7B#{Oia>G=83&1X?zƒr̭FXN'V4=:'8l_LZR toi99BZr']TSLv`4"~AqVM+)B~ÆqJ+H )OsNMzAd=rd}0 FG뚴1p^3P۶}QI-ͳyd١zqΪ^cK7x/?+F Zi?# #ֆ#; B6 Nk!+NOKOED" r VTqx07IuUM4K'MK빅 fQ p,A4'U {&] >\g8',~1Hb6&C'ryʂsHz)ms_q*p׫[ӈCd po;ZK|Ё * P;4*7ttD3w` 'XxM@ ~A DԚqFC[ rn _QL!A@=^y`M Tbgteʑ35ډ@q>/ߟ|ONnFD} @.G3 bbNu7>54 @Xu@:ti$Dya+e1":"1,' ݟ)c-E"KzGHSYvŕ"34QbCbmdtdF 6f12lEC~; p %]> ;--᜾g_ k Zl]㡇}\Zȣ: ٱ( q Mng^ykYhW$,gʁ3!m"2_wQ"пi\It&sƸ$/&n۪'Wy6z"x5x4 ə IJ :f Axu_c oԃ}tb#]jOjwӍ&ma>y]֚F_ơV=F `Au/Eژ~ njpvz BU|n>1'ARytBq탬DcnC !ϪANpԟ\;c >\ 86nF?'s?;r1aqPPe[g37K`a&q,iX+@pK0^Eq|UhV]յ%|UEuh>ǫQ),VJW?|C"ίĆ-'0dUW4<ڥմMӹXQ?e\~lNaƽOVeB)U9@\ƠuB9X8TFd֔Sq&;jnUXrT8L _2oO@(c`Hb쓍Q \eS{>txOɍ[۵9s*bJ(h*yj9D%J<@ "yCa#b58(eK$BX<~+I/PUŧ+7"fZo6l󃩭_4x0Ab=K3v0h.rS_!O.fkO΍Z뀍\;fk<+aﯪFⴉs yהH= G\]lW<_n*p[I,vpF0f&C)8Vs6#_8tB}V}ȑ"ZJ5~)qn&uVAa6׀P/w_Z(%>n?pQ).eq/ N\Ba-'Z?HX΋9nUqeݗx/ӯ{w|& UV-[>pdd&KrKJGUx#a򫭼1Gw/f?$D& U~,B>/#b-BCPjtxl2,{My~j0'OWJ% t*@>5RCP%lI ' % AGTh,5*Kg>vy ^A H:g&˸P<>TU&ak/7/@ (GK f;ge,j "6PY _^:pUOzY5GVJ-D-!_z0Jl1^圑Gcz~"m^R,3BjAnCD /IѫC#VP'tѯ)B[Wyn%MX+JfX\@Ҿ~(;٘ՒRq6[U1KQ?l Z,hMeKFze,T0⭤pn`۳c3~ ͡/٬5͐'MiWDޢ#?z+^ ;vW#XH6#Y-US[!Mc4:ц_n fl0_J+2c$ 3YV VJWqjBX>}ZпDѬ{:#T¾@YE } ⵚJ [rrϋ`CVj% k{Ps`dp[pvONir5<5hsYFVLn4 Sf&Xj$!QeT۴|'W{gCQ%oUekJ't./gh{ƟĭPCL䊦QjWlZ,){7!<=:*XA_#>-cؙڞg3vcfƊbk MPtllXǗHS{ȑvUx m6Ÿ89lDi[.xqoF.WIRXzBfIr+Wmˈ)>J'a]*)B Xnɘ+xBHH\Ca|?֌\|}@Alj|| ~ /+ ~^ KV [E[AݷfgQhMzsKYM  N:F$GM*HqrrCwh-\=j%?㖆V_ yfXJ>_DykpͲhAP+vXm XR6 R 1۾?sBxʙgX =Զ1S0C1 ^c]׏},= /OT$qv9h{o~-:,S}7;'b# <+Kڻ  ɺ͛@Z3vƶ1*~LoɁ3f--NA%]UJ!Zi]ϻytcPooǹ+)P_y\1 ݝy AٽƍTAUkO[¬Y^( r`h  .~7al* w;:L+eCL.TüHfv4.^avdQHU}R˜ wOXsUdm33+C`g|'oɕ9YGwcR(#p]:a.xks_H3S <<_(5&9 Y ~mW2Ml%pR6X DO"RlnTNњd[(捊/f 56`:H$ruyy>z>KmZK˜{Jk_6&V89;7!Ǯ- R.Oh %"Imf5軱 ~53#q(>+=Ly"__ +SR \ܘ=PF7? ˻>FUw&b&mqn\LJҴO`Db՘5 1%R\R Pj<!DjZ ijY'?P"mt35$MwÊء#~n,Gn_Ę Ž/j:F,/MWS5^7uXW7I{Aេ:U:- Dzf4 OZS]0<#ĺǔ?2.jxU||f\4>~漯.kq[H{c d*Wr':4Ƈ07`Z &c+2Dw e&X}'ZfyQ S2-w V+/i$+^>Ebd*@52UV}~+_XKB9=7X| U*~+;qEɳP)ɕDz7%&=|՛OOp~SD'Ti-vWL%(qڿ!Pո ˌ35yڼH!%X"(QX?bwU4Q/;̟yk8I4k#;KJ,M^&;  IWȜ}K?hD=\AJa IǗ cօqkpw&0qk!N܂$Aww !p!YιQ]ݳ{;ށ#$ƮN>* rB5]e$͸R~am \"Rrw$WaI R=^(~4Ftuv)Q?P±G⤃r -e;oچWX1, K kP} p/~xYY*d xN̳둼9T=R 2ܓƏCi!s+ 8aNw>W;S2SrxݜcI;g;,2&a_"/m }dJ! +ذ ^SP׿=+PJĶ17;~";aM;8na!,z| AIb ;9zf>co^GSDr!pGI/?z V41-bT&58 @R"#E'O1@I'25[e^m$‡ow),{ZV5lm*?B;^cݳ6aXwb\pCPRSfTŽUyHtM_؝NbW9#8 xrU-a? [jt~oa Zs|@'@yY;\e{q> L<@>6] [6/דƑdĐ'N ]C~ O0)\l@>> . x2oJGu_ߑ!";+G`BEQv*'ؠԩNGc O1S@b0nz}4Xc$ p\8!>ZzKǙN 61ڇzf^wۚ KakPݗkd> T3y~A6IZϥQFl{C =dg+!^CDNK-LqV:TMGY8VG Blw+'/[dU0|bih}yEf訧z+W嫞|@J)m)=xH赭ri1EE QlZИ<4 ]h0ISPcG`Cm"\TΣY:Eۉ{KV5ـx2'GQ$Ż4{NW&.2IJyoT_+)6[65?M#CCdMG -H+N!3'IHBϔU~8g>pCK!z |ܨJ,fhaet.CPC0 >,aY&# t-F&p(q {A>]A,"׵KJߵIC#"ln\^ vʀ|A7>|J?FTaa+ zNHRⳝ?g.E*q9sqxrI6&,,Hl5!f _5JXz 0 PIsWA5ƪ!HbgaZ%PEk" x MТ"tTJ/;ޤ7.BHpeyubS?,ntf~efhR5ęPɋV6/ ̿L;\xR(*y6zt *^1k\oicvI*CK{*\ޘp'xeWmퟌYܛJ2h Lz.+M>*<PIU=+&@Zi4#+Iއl* ZΧf7hԷl\t12] iQj* 76 h+Ouź ]*|h^O ii7'Dh{eU:r ewV9Mtɋ|p}; vw o`ҖMꪥ5 plo$bֶK54T3 C.Q5Ԕe?gbA}щ kTM* r/%pO B2e}d^Ild67 V.:|y^Ms V[ٶo٢T*؋I}5&Scr ĢRNz d}L[tv]PNtsI Qd%tr~ϲתrx] ^yv= K:Mi} ;GWWnk־-Jɸ5~Q!\G̥ R-ui ~'JGpa|J?T8q@,'pQ`3WsDWdJ9TC\ OK>҉Sˍ-c FlWߍϦDfZV^k+xv}h0I+96_ uleE 0a~^^PkE5iPK&/VV8Du" _K(Mҡ{w6X?u'-UfrPh#ܨē|^H6c+bB6Kƫ*0JɐoKkk%+VPWA+pՖщ3 `d3o (}/},##+eߪLqю"S sUpAB&BHIt̙0~%7S~(ʳ"fRJe⛉MN"w:hv^,!JslJ~t?@myS4< m z#YS,\N&RhᡖٺIm\|bH\y`{ґ3U++Y[O[s5bkG#8d A3 eMABm<.A{rm@OD +']f8G903c'NfT0L{޿Uj@DhSB )檭Mk9B0c9,1757cxexgyFF<7rh\UdАޛ7__k Tک 0+TF~f_?8P(x =MAa!!9 ) C+ݝ)~'AJO@$x=GesC1)!0JХSHϝCiV|.SI`ፔZgO(D=NqEy(:&G~P3 6h$/GQu"ϣY-Y]HWUr~EV1崸k%|dpw3^ U&˰o0Hvǎ~/1Ȍ R ڷI"k (\^r1pUߢ\Ok$au%*qSqrq9g p R:7 ^ Y㋻ێfMu#a&!|Şq~Nje *q%(!4嚣~m/bKOkW[y7qL_ 7T}V4\-+uf:V5~Q)˂ŵwj6|#ǂ fp0$*/01[<ګ`49} 32.Vmy:4Un]k_"ۂW~!ȧFsTák[C:">l2%dmOƘxLZTTYCuMT3{έcS5Npw@Z1؝k<)cl@XӢ޸\{Z7 iR5L7Q&-6|%;08ÃO?=B;0> kr.6=@]3\6 5(.yhlV^ [)V Қ&5 pۆ4 x5w>f 87VmU0@>Ȝ*@ Q}lDBq S"#뷈 r\5)=?Pq=ZB |f5l9 &%UdR+! <~x[KeΆ?7uH\>!Տg`09)0K@Cf{h;S.bF-[/*SѤh.dE>vv拳/9/_n,_A֋';'B6Ut( l#(qn{L}lػU[ Vz[3Q >4"J{J᧡&buМN\X^+S-R"[jHEQ0|F_7c>SB/|Ϊ% wPO9o~.WccQm'5ciOӻU5ҾF.̹, K̬7]d >I5]ӛ,cy;n?z,yN~s0Ϸ.d`bA:]9 dbJ}P\#`}m:R}.PRr{Q7vY?%$]e(/9J0W=_ aq3Q=aъ[ci1T!܊䢙$d}JO>GeDR-ںiB[L@3,4 2B IC8+ D<!DZK͖lj9A"$^hd%[(b0 J Nnc5;6`r%ؖ>nT/fGc8I ogEj>p[q;2 t~x_do'NQt$Bo 쵎BzՋ%$%3 GqvQi]ZbE>JXq͙쩥'A}}.+hFqN_3ۦr~kǵtp,7bL1y .pe-#V{b&Kh^2=`6F\.4Z%i؛]0:3zK*|x7oR}k}2"Rlc ݣN֌oKQsʎ>F}4))l9(4I qAg?oǔ&M^p!T`+( |C'Smq4<&Øh_}^͏Ee$|6Nd@rjYK3ԥK(ć̰X! K X)dW# OC^sݥ=õ0mrrD`4N};'phE# O>24Tp jF`ŏRD_zZ K s#>T/IʙO??zP#]{zɚb̋٭vlEM%_k=94( ]F1\@lK<]S}uzo;eqY#HޑF>fF_&Qk3\s*2l66_~w(FgCI|~Ŋ_v?҉Q"Tc rJP{i $גe (u\' .ݐwo˗vjnI{8J>9⾦Ce)wKy`c㔋4z ̣Z0`<\Eh\H1d@ :zx2|oD秆 c=U]S"}02ѠnH_YdoCe)vD0Ce톡*(sJ7p ɀ75=JM!;Rfƣ+dB/S편}H #F9WQiv `Eڣ}!W6D"+lGF.{ÒTXV3WyQkZmfj!} ϣȏ7j \pŝphgoo7=fRbvb=w)Hn  9ᄛCQ{/eV̊|P{PBl *5{J'dd‹+YW{co+"ڈ66&G&T _ CeQ.@WRzEe:30ub[J?OsC0L:a7Z!2Z.J <ݓ(kpoad pjMXaĕ0_Xq_C׿Pe-g"TkLПݢ{EP鏶jֹ#YQU2tr%ώȫ}Z1Znl/kC_2p_#R4:jc$UjixqZƌ]d ߯ _qO=* '!@Acz.m.g쌌nّ~6 H1Rt*Gb 5cΣӻin0$"'p\bsJ7߉K^+9ӭB0:JZkRS2јgyT*ͅu :"ΠU'?l>m]K7 !!dw5UI:'$,ߐ֊۷D^z$ +2a;}"Q?jL^br`($Ŗp(eq]:d&hk9Mٜa~68-+Df8bz >-lYAp Nc8 qX—.\zīgCٴL1:#X`_#gQ}AT/F-jK|>*3^]p9).A6x5L/9Q8M樉sL:zE !1O*ٻOKle?;/IN@V`]G:#^hϜK UBmFCpŴf ~m!JtW ~/!hʈﭨjd>^+ ?+j٘=RiQtqYz2_EiKNN.܊ WWWTGj?ޕ4N`yV7 TսueT-d;GLGRc?/sP|%sCr8A/$=xϟ$81" A(ƒ)DD &H֐F:|u9A<|H 3 ( < V4?;`p ĒB$멏c`I;Yۏxr|",/ 73D4Hz@&-W|7O/;mx &'^+tM+t# ?%A@H`8m(mW¢j}i8AW`@c8~=( Lӧ{A(`p~s Jo~آh8B!w3BH[_OfP\q fFe%&h]uٵ}P<͗yW%fm2D%7g] 6 CB٪q|l$SXN`2"L~S,li؅ V[U(Sg+D=^Y4ڲfyڬݪtKXvꇒЂ-enZgr7}8pV8*;xWEjъN%gb,[JUц"iO )*,34<#F,qRa#M4$*X-ja{֗*V[caRQ@oͥ}&6ͱ ե}v!U0f&ap\VPeHfSrRҳqBe]#?/g`S6&ByՏT9(N߾xj9ܧԇzI3RWk]l25kA \Ϝ U~؝Nq%Hq-O1#.l\-S*8j""L[ܿRZzuSMŪK)RCβoEO>gt}nP-XvwˤNi1kș[^+>~p&Ӊ@?g O^b e[x'; ʔ@.Jiw\:)FKz =,~;~zvsxݑ~G6>j-??b}[ yMp3_Xc\\wJHppI}$4k'3Dg;,&SW FS_>;4,WQzO t #Sjh]ZV=&\31&YVD`|\E`X]<{=^[8`b@C*ߴȎgcS F1(w#&m8#M y+dA?D娀ٽ;͂컇-\߇E<93v?~{6aF^; ZEMtSHj L6!4W4?&wPjM2^nUI'ϔld}_ E;87rz!ÖP )s0LQ//;>ȵÎG`Ŷ|hia=mWM7bqM&,H A'bވ#x&J^;s>ud Wn&7SA"Q$T>HRz.nl74w ~X]šg̺Mܽ>n|UPY2@ ?CJʉ[dAzhn\UZN4aG@BW)D,rxHUOzī.݀R}BC3g/BQjViJ8xfWD_\;GwSQ;BYТ5,PHe<"tJdTJ2T.ҘǑah yu꼩мNE49_J[Bh59NyQq(vM2/ j)V>C44,ȷWg=NLBйiĩʽUuf Iiv հg9rsWPE\G\5O'IoKre AX,=88 h#Wn΅R-MݷpPC 6#W qV[.8tNO OpwG&~"BK>jv rєKI;-u$ NK"O_uH6hiHD ^пIoۋ ?YA|OVNYr 2x=u452oGt_Œ@|vlCORMmPc,!x(ǣyPR &`h1B>N<~O hwz~I>+0=98/c;@>4h"X52Ϣ~7t82!7X԰ ܳCh ;yXH R @H +TH<(!HhhawzbqAOsW/9;' AB5aq*GeЀ]m]Y( IdXX^,,%>/??C8`X8y9qQt<I0DyCN PX{*n~u:,&a 1CVؿel=oqi(, z7xy^72wNrzmVZx)T\}/AӸfF1)EjڤeFmJq]hJ뮸܆Vb$R2%wu$U4W%4N䈵N[o~6QT!o ҫq{Qںy=f,>V[ToϚqSӊYvf̳q$A&d`Q%f_ $dn{ 4kydL$&b"~1.S ?~^Ug @#)p!I$9[Yb ~AW#`\vI1{mEb/=&lo𡕔fJlh֗m_^<׈0ͷ &Yo~BNط۾8+jIͰáXvw#D4f QNw{dc[cCƟvoZtϐ>ޭF.Tc0 {mqLwD፲ J[}>EÎilU>Vߗl]2uǓzV':.o7G](w)(;/c2d]ES % 2=trȊFE5]YiH|cfLmqux)"Z."`{k~4: ~0;rH|OQ;u\'oyS [?ف(9Mc忤CQU )Kor k+׻A%s5JLbI:ToZcN;&?mM,ž:.m %CEl9n{OAQELDݤ8X(vb)xf}yyݝvsSO:c9zu'Yߟ{/^}SR!gbs5@^QK[m۾G6{g_֏#iv#ʮoSۧ;{d&m=GuO.Lrڴ* K/ѻ{:dA [obsg\Ȓ~u{Uƞu6W({բY!/\{rsS7qZ~pGƅ&7+s8*|%%T*=>[,~tŅ#ToyϠsSƞf7 1 T_rS֘矸Q wV\{-.O}EŨI:>cFO XkjKGiq7vp/w.'5I#Y#uMbg6x!u `ƍ60۹MI˞v!!IOjh2?re_# _%fU6+J;Oz^tot'}[ b3 ٻjӈ"~$>k*s6V n>Ap@Em?=:֒W߹v9Mft ^}yoͪN{PQz}^[v:zoJ<__vx=!rf+n6 A?GDhŕtn7T=晾ws ;yaK4X^ٶC;Ϯ5ί* .f.3o1TN{FԩOo|MOKV4}Jp餈-+/kp>Gs/o-;'54:o΍s]M,/[CZ,Ǿmw:\5/LLmĘ 9 %?ia^Rk-'<4$W/ /e1݆ӍDŽK<5jao=SrCgwJ0%}tfQ'o-Y0pΧ].hQny(m#k$25$橫=JXcY=?d.yaK7|8a۲u\\rϩj8ع ߾K#8({h֏aico5~]R3:vM~> =kq3M'_m:ݧ<)Ֆ<@j%j 1!IWWyM9WWH^S5`DN8 xg{p!.Q7qFM+CQW:Bt]zZ{L>0}hɸ#$;}lyd߹upoz% ~1472GAoݯ@ +_.RVwСpCP75opcj#[͸Y@ߍKmp[j. 4T32k Ht 䟖A@/c z#Lw/l ~puq]Df@$ m a`s|%t I'%\U.GܝeVꓨ_u>h5]lNu:,j ,説b/:g jkdHAvE!UjY0k7!wVk2^Ԅbj\+c'H2'3% (ޘ:hg>("˔"F#%N~tfEmFͿ{}۞ޢCnr\Kf[ټ~֞wǏ:?+o)MɁ\7*.QooʁC,3=zDZjgȟSóV5fGxڟ[|OTJ[v=!^\W|nj⺖;o$|{l\۵U Z+ etkJ "`Nظ9_J3w/1.^sc ).3>1]@˯HUϙiд& @!~e㛖Y~hnCO/ KtaϽuM!\~;cύ ^\P_3N.~זoZG`Rgь GC:qmۛOobdIPQK+܉I٠)%%Ud?K; zF.ppjC})z`w͘[=daJO)i%v}ow:1~.["{ U8z׮H EoN]Cnt[7_.?B ٛOv[u פӨ~gLBl:O~`~q9c弘n o40ݼom9 ~9rj]-{.~Ztqg 7/:=R7L}ūŒ\䠙7{(S+ְd]㫆gMuyd {sZGw)9$ڹ7NcdnF(Ui\HG ']YvMKsWPCz{}j2[5[wᕴ9=tftܦ]!Max+{hv.A $/ھr<%'P^o$mMbV;]lS"j"0{|vՅ/ۻSF|_:{p ?Du_դ6;zɻ4^9KBC%OBb7uUq۠t^F; ( wO.M,R]*N?]Gݜ93ͷf#Nh6l!_'\v"cQɨ(+S;oN ZDlsO(lW6RKH{4'<5+X}ȥӫՏo]j~6ٓ#8=F1qST{:gϱ#<3LNxwo,v+ݫMkt¸1|;VAzS?-_0ˌ߇jX>ăvr8AQ{OኅߣǷyrW?һ_%vi]GmGO~5b\C(ldG7R{xѤ\}晤͈tcn;ߞzr5Ru6'ڸ#">Zm)FKU6kJZfJC%9/(pf$|ZJ)݆\ -QPX#]g/6GW_=v(%^жƓ>=Q3o;S үjN"AoG&@}B8rA{,d+E2WIX?D?\0ж_CgK!tpE,2U2 9sȓ#H$πlHGۑ҅%]HV)nb$~_FX!Ra?Î Z Vr'ۆ2!2Ð;^!˼X^wH WƐSnЃOʕ<'0iB~gzumrBߞXg$ˉV_9/A6D+4@ lz%ahoj9>JΣF 8P)SD2rɢwmdߕt&iN.9Ex_¯D񾀫e ƴŢc B RȒ\if,Eqľ>!vvX 4H)%%'Iln(x h87 {=B R ˚YA\aROƭD*So\I`8sO,X?2ddx{cB$ͻP)A\dP4'w}`Di (iN el!5R \W ]2$%},^CzL*+k@0 :FVx|NMF Z-cRxr0*}. g(88A-4Xs87d3+ͥ0id/89424! HO.Ap\ &Kw ZD)(@JEl J{PN!kx]xX$`:x?8y f{5Ico-p.0A}4S7x% W%)X: 9`> 0D2@/)5Һ҂9hRsl;Xw $`"r`X#JZ1 I`lHЬI -QfH@Eɲ.L O1@;+{ cs E `/W:182 `:ѰbaO 4P`-QFQ'`jwOgR#X]Cuj%b|&b|zi7zBq!x 4H \@ bӖR",E033  ttMTi$qf^BxZcOseGS.* &-R hai#%+ek@z6 Kq,{#p⁨d!%Ԇ )1bg%C㸠B k2,0HF8/RM%:izn:4ӱmJO #{Wա e{-}{3aIcd/7ϊCo8l2eFg!M8KnuY*6{=.tz^#C6TЂIH|;N+;8{ki?M~0[cδv/5x)<دobl1϶ZިtaW }V&,ӓ^/(ReuRw"9}n<\m|jȦq?F}7_䷺ }F[D6ӰSdyCӊٻ/8#yJ 9]tMۛ0Hˁ~4RUl?_7I^;SphWrrNŭ̧fO , \1%͕X4rTKd>Q:`Tޏg>nxCR|c9WXݐκ/wxޣ1ۥiU&CG|)l;pw|>Td0`\wuBK\eG.^N`gjn.k~q_W;rwa AFf #/ߥ\Я|Jў:qjlRystXMa ^|fj|ϓ& t5` ~ H*Rd7ɜxR]TDiѫ::rӵ޲]3JF5BA[̮[Kո~/c9fe=#3pq%/5>6yŏ緾esRkEf1bMA̶,h\/0+樻I;z Z9ޙS=n^۶yUNX?i_hxٯ N>ҏwI)MWxT13掏 r٠^ Yz.>5ٸ*,p2uMO]P V}ft˴EXވo}Cǽ{~Z{ZfE_eɧu{pUwdf?LQYE4s~9љ+UoAttהʖ)ۜq:vSD~`U3+v1\gSVQ.N۽U/-sqhoêS[N7촭lFf3{1IY+6g|cͪ"?`\Uq)*`gdn9#Vx?\z:tl0Deyg }pqD9CdFXnQc^äV?^׫'Oa|I6~}>{7&U sguwhr N8GX=Uu;I"̦?Pp+hӝi6g<=x6SmZ37TlFH@:>d?;pZ;:n٥9sev94/!|*1KAw s6 ~J 0^Ҭ˝g}&<-y贐x{ɭŷ2ܱ 9*㐀 KmZػ!/>Ou,/&'.Mh?>ӳUur||Wtk]aFgurYJ)C^[\>'Sܰ~D7Zj8nX.ƹ\dP>ʼU_`P:7}[4>P=Ye.ҷ|+V\_@\dQ\lk7mЬ&ꗗ^mhrIB>]ѽρ%1 2ym__1qQ /&$z9Z%n_Uokj߄ib"R8| հ Vӏoƒ eӐ̠ *r%W&?jXat }R\]H\mKPfdv$FTpB. jz+ݬ-H-0C֙@H V E)M/[Q끌R,֤p=c@]5$THS1ƾD9|cݶ 0#):X@ae(ES!< J㒻%o?2;)nؠ3+98}@*0O ؁ +FEmzI`ue˝[2*lGWMQ*WfUT,w 뵤*$p+*J+ί$%Q|SbI!x[ZG%QqֲԿ%Q%ِ<6?e>aBj0X/s 7Ìd}ijx-Hg ,T1L* &WEى66o/VP{+wIΈRݧpCX|| o\` D´R 7nMJ79aoOs8 `@⌷yՊH;"m\}o&XPR Exʹ D4-SL؍@sE0YR rYX=P%,#nP)fr@)/k:W]&AÐ{vąhP( Ϲdad !GQYuq=Pd!`5-sEsay7R.BqĘq V1&!Qݤ}XFp(E*œ= V$w2V l? %@C7LJ668Hw%$»xOr ED;'@|,@:+Xl\7Ba8HU E0:Wxo$%áA1\ mbJx7c+(qPV.`% !aNxVb\ lUCmmx% IqVPRhBHG2KEE#u!#AɦqLrWƟ$`@d:CoF GGVX'!#|)f0RefS"kĈ|(^g鵔fti|~ \i`y4np`Ayтx8+@"V!U$1)ǠC7aQK+qqQpI `fX+0sxY19ߪ: z"Շ.Ů52vҍCYkz6C⢩CRvV۳k^|\qݛϜt[uˏSWՉW:z^>AL|~>6,Pjc+ ^љƇM/h祯A f4-4ewAs7)v7|B<~rVISsXm{8wm |n6p󎍱w&iy3Ҷ=:͊0ѲoٺrSKw|<{0=7C:}H ;V^cX%d{iϒCޙ0Uۺ~n'qVsv6\5k3!vNO/~`Tuo J7x;ˎzWnm&W 'q{֑݆m מv9;|2wNpxdlν+xbw!^ S+rÚ= 0^AGf&JV͌f%1elmoH)?7aFPb􂊋Fց+NbB3;I?กߖM:?d֭qJZX/iq;UwsR)}WLZx]i=GH =yp3nK^`koklߝVC2}~[}Wy&uq#h%8UCLf]pZh2jHX\77w0W*"p17 ߌi?۶W:vsVR-Of6EkSOqr0ae{d+:ko )Y֔-;e6,wi.DQ^}. V 3&Lu+[og8~Ր '#=N;<ӪgWl._r"cV >z6ug={s)rάKǍkz J:XG[윴ˡJQ78q]E)8R]>3/h`5)r) ͅ3k0H5AkPԼA-hP Ԃ!Z`4 fAAРVjP+կCE˯]?*!O+b."Rrq4E`\:µ= J V)Z|V* d$JR0 ^ K{`ຒ?a&p\))^J!3@XBQy ^UaX\ӕRrNI/6=(Ϲ^3T~?jt a?TOz?3XSQ )YSN ?tD˃8| _ ͆2|?Rq_f,>aw=`m𤘼J\1kr>kX8Ԝ,"1v sPRQX8uXw=.DI?WbƩkܢf3e^pJRL84&hb@nX 1|MQ SKAbK?W-~BY ?_=xc'Mh\q%MQ~xHqU ,(/s\88lC!f%]ڒ,9`䉜/0msB/ePePceYR9=LK?N6ĵcڒ ,uў pêO&Z᪒RxaQUA7'P iX!p3GˬǤ9BJ^9H0nV!(80l=`, 7:S9DD=xQ@JdZ,ͧ0d13 |kƤ>ꈈ:mۀ$tׄ9\!te <0v ð` '[ ^RHQ5._|cs-@Qx<`yB+߿GJF7 v)uD\ \ u%D5gX(A\ Z;WȤJZ| e%d,$!j$GK 3PXQcݯ\L$s/i'v`ۇ9*/--VoS"!ać,5XaՃ[*iGXn}RWkRF ŭZx@=(^LeN%G>rsXGF9=UNJV'%)q ʢȐ-RL 9t=ůԑ 3k^,'B'GwS=3kZ|cL Tj5x~-X 7kxsY h6DBz hmKĸ܃)$bt78qjGO\BHD&3WRmcxQDSaIB/Vh9K+h(T5q` R ^ĠkCL2]O'f0fan(B$nb1陉3 \pZh_hJj>qa܏(qJ&AnⴛX&FnH&mYmYmYmYmYmYmYmYmYmY-Aj35~?-E>|\]=!( >%u3҅_Kb.(_J9aS;5Ԁ,A*66^^R*^^<H4 +351hlq,YiM_e>r5gh^4k 4  dk[ JZ05\jA)4F\'$kc_f2w_HF`´PKw#_}/y&z)C d juwF-)Y[fڐ'kG∝wAx5%&%kk▣nAV-.KջeP=ak qy#sGbk+Cãċ؃娹O"Y0+kOOMҰB S4zW{ 5 Q$sh֧:S8;&B~ٷy8 he4}vf`(0?~RYNue>ki@`zd5Hk N)vA"V<5BX5PK)k*R jm 2]DIgpկ6ȃFyeᶃ'fj~q daiz jC2:Lk2cא?. c1qqFǍi*\!+b$Y qKevW,M[%2s mvGFåzeֽ VR:(aE7dP3F YcV3RE9tJSB !Iw 4(&ϘobNDMZsSfDVICø4--R!x 9ߒ5Bix xFJazߒBnմ #HޒոQ?na` -E~eVX,} RqH疬* Е (m4,MҴ!w@ʬR[4#IyEw@y/40;?ƪ ˩ZXU:bXmVYܬÉTYEK?Țʨ]0 Rɬ+9< b5[E>9)Gc"1u;`Y-P4nC@lbolyAixZ}Hc@-QX6Xrh,-h,A(qzLfe!,Fc - nbb홱 ~"г[2ksLD-YM36efSY|_fQT՚ Lp4xP/Z,Nk0X*< iRPRZR`xLw2kftO3vGVZ2T{^ eH&?~{C iheYE}w> )a6?^{,7VZ"d1wgY6-J$ZdD](1^KMRZr +(-R9@XkYm1hfE+-9,+d]4j`oL2*v-I=9gkãoj0,Hfh;O<ʆ~ѲKll>q(j"j ,v z,A,ySLR=bdV8ٓxe)bXە /Я`8D8-&dNBmg&9Z=|C/m z񫰟°J̤8e]ڮZIf?4 W @")E¼Tlj/fJ=G74(ŐV;vP*v5]E^SeR7ŊՂa4nQjKޒ94hO aY8L5XfpK񒭉ڤ졄Zwa$ԺK}UYq4~*jiVBlL(/15ԒD IӌiauN/7(W]W7a3d&AlRlwiFY$Dc hzCZd͎IdĠ;ZbQ+}Zkǻ޵׻k{}Yg3rsj`cܲה%SF.EĜ|(AZVTQK. ڴi6|ĆP`}~s,X iˬ1l0tņ-8N\b ?ՉNm7𹃲Z?;a΢cIW3%IÞW',7I/^{yuo7N$l MG0X[kg2|ׄgFJ?e/~<CUȏX[q1OMƴP1-$PuWۢ><Ɲ-qRs,hdj6˒6V'auŸ:| dDmR5X]0a2lQ Qj0]_Rlun1Zn&%͡EPp>xWk0gyg?.hanޯY [hs]^|_sE^i>͑Sf>l:H_3|[7z5żϘ|/eaIel?~i%XRe0Q`=ЋJF4#SPS QqU ,& QYQ2M'W G׍~W;iD96_pi#,]ӈEgèЯ'gB _\8|y|ġnM)MX>{Ձ.F*azlbe4wm35~ǚ.Es]͋b:6t(+8voP:ЁGp~:b3K-aeĆySgmq6R\WV_V[[~+2 I\)6/jm\/qd tf>ͅ6,?wb_{EڜXt ½!bQ'bhX7(쫫S{?Zom?\+nWťr邯6[FPv :uYI[R|?ni7_)i [FxL.cyi~T͝3<'a*4Igǟ|⮦牌[aXOg^[4tU7"~IQ- :-- u&uo {3I*l?k!YY]{B74\]7ܺ;3뺮axߞzTiyxn`&;}Ǻt7t;5uN]=4R_&mH@pamQ|.nIxcy]~&Xs1gvߔ 4Izrj}/Nwowz)qY/-qEӫyL\$SU,p㩩__z]WKsTC=hAӳju))Z:Ш3d~|`w=q8reB8k ~OV'{Gwpe#e _={9{sFўҙn{"{zY*'7δ苑?'?ˇc/>ڷPtdBmEzPw~/n֜^a?nq:e*^;"\+݋Wv/ήmΤU]_4~wkpTy`'4ƕ!v:{trUwtvvew\~ˀKAD]vĭ/wUSkza?07snW;i#O<v ? O쓺Ywif.*6+>w3V~کRlk'3;;NݴS7M;uSV෎l?MMhnv}bHΛ;jtS\h Yw\47q(;}?G J%=OٱMoGu6opƵvCw5|Az ݫ{ ,).w'?ЅK,2/_7n%7ugͮ~u/_R՗oo%Rxq~䳬o.baѯ!:E^ď)J;Z?2qx?mDzc,Fӫwb߸dzN~-bWW/a%xqITW<~.|ji8 S<Jjyk0T'k4{M|fͫ_!,NrX_5!ѭnͯW3**_s#56W5~ _^m5#O5x=o}]{O$v~x}V"p3|g!/^u6v^o91.g/SLYˈXRMe]Sfg&֎X S<ܪ %`^oiY-pz h-4ݭ'YXUVzU8Pmw~=9|{ U**B0ϭAowTSd"Fe6K>vzSR 4ׂS߆;B8B!pe: ZQ8xO ߆X zkBz} R0ӱO͉԰0i 8ZE&K몃-#V *`4*ܡ\>D9(,CN"+}_HA04Ejl+qIX@Tg FZTǢ @}[--G=UFYaF]sP$b-&Wco e^6kWktjD*LVzU8TSv9fY߇ECѕBsţZC-]-⟳ = RXϪTu{dpRE-T1}i9mU}Ns6N,=O8-P]~r1j21SUk#Ǚ_k#FG~`=A/fv|ibV**lёk{>h"E^z>jh䰃ZQKw3QM}zV AuhSU P၇~GBݙ>6Hdi#M.ȶ)^ )”IDVľͤ'6v:nءV!NJixƐ``32EVtdaV|N +˭uRC )__[bwDL袎 $dLbgi,XEwh:a9b RAI#&=8$$ J3kMjx4c$_hd7X i1Yw8 kL$`,S+uZ?LU Z9}kt\1c)Zk0@#8M6.IJ Rh`=%b[N! Uœ<:gv4lIKIyO*ARÁҙ@&Vm;-% d`SJR-& ("X֧B i-Ogq7zE){=XՃEW 2S<>; {³14aS#$0}@HMq@IP@5K"˞v,:?`clZ'0DAAZh֌E&LxY96F6Nmbb;~ၳk)8ѯZiA& $hLQ8 'i؎S :5$Jx-v$%I|qk35KZC2x=^oE3[64eM8 ZB*mD5F-t)F'Y:x! Zoi)k'`mԺ#BfG)')8 c 'tټIk&`qSB!- -KH|Q$*{f0 !VB3;+"-SP$!XN~c w<ѭ_>HuĐ`|》;p>@M# |4* \:CǤ>'G,4THJb_/ .fJ.tjqZH>$ΆJi޲u@5𽧺^Tl y=`sGҞ`W{b4̞ =(F(j|kɥP  扂^"m@z$PEOw`[0^)Γ#A 7z;63}gx l8z;WT7ogp+Hi`sk8D/Y _7 b)XU j 0m FxiYpǻÕ5ӳ LO(*lR~m(:JI8_v*Z{()ն,fTnVɶF 3ș] 4ZYl;8]қL>B}s*FV-v4 )IvsDHzj)\@|U zPE &R'2>0S̰)n$NN#.fdX#ѥ>1 -Z{CN> -oQn(Pgȥ93GTTj u&F-[^pZf2SN"W[AD-dX1y-QV8GKha9[KȒ;IE{ܗ_'0j҂}Q#!:v=Ģ!^ĬBR*iVEɷHʍ\}ޣVGR ws5EIR}AuD;2tD7Z{y[GBIAȌ6OpxKLO K18VypYTQWMxk8KW,jgT邖 JiR@>.#2H;7 S2SGKq虉b|!]hoRyy. > t+J1`:un&4HWBL)=avL j;B#A;cz];PA%F#)n/Lڗ.|u]!FL_8IaQHTG[TTt6 Zwn13t gA߬ 6saSSk%&}Ml(CL+=X[a:ӂehzb6;%XE s0͎.HiJp|:)PD!'}`*$҇R51{}c,$E%MutC"4ab91`_(1(wTXHHǥL晘> gz,kpWnصymvOc ӝ)ّsB,=0iezL~"XEBzJЂVn@H9U +)OCֱ4L9 mS݀6nMh_,jK( dP j ..#"F=[jQ. ֨GadO#r*6'T5P차L(N[Q5Z-њV+ ~86E!E1a`rQ HvcuNo)D).묓y& EX bq0Md:d F¸B)bcCchAKL470TiQQDP# F1TO^IA AgH6)zHQZc2RMy<YƑo'Y_` Ŝ֌q(Q3V ;ПZ/cY'D L 37Dh|)WYuR01`$nLx!B'v0(/`T`B CYM==h"%I}sÆc-H0#L0J'ݓF:>)ZVM\Hf81F~AWX.(f)ώ`4%)47I|Q;HxOE8OrSoO2D}Q5~U jHQ2DM絭ְV'm5\`U3Vb)#Y7wKX&yD2 _%︅ MT(R0vFozBO3H|,2iOaUO$9S eҌq4ԙlN #7=4@n$fMS41}Ʌ݉2 Fpd +D p4JRU sJ c3lЅ΄dd4qJ@RR%@ Q2P n2J M8t*h"L.`-"HEUO#14 CxB$:Bqhbш-b)IsY'DAش =F!X\xnn8_:I*4%!ѝN&!rLFGԌ71u˸E.hVb !&  gQ8z|ɴOt7 pokGQ;&R0I5Kac``i7젭pAKk HX %QmZ&S\ ƙ9پpE't-ҴqvO$ؖSQI`|Ԃ N⋾H@hsd&N񋇃A>T;`3g~݀OtCNS`" xVEn}COfSpIn,HEa8q'I̔ Kz#BdoRoY^'ҍdniNgˇ_g+O`sӽp(`6$r%9|8sD`ne)7,Ë+:Ar'%U^ @ܽ>jxC@Ex6c21oqsB/KAl^x*nG:]Kbk{qb* .| H/=Q&h'mHb)4 ^".ջ^0?VJ{ZIad!볘m*Ɣ1ҰΡ*-Gz 4,RPx?rjꌥկbQ* g"3΂WOISu| FP:2#6MZ7`yE"4/81HO" R iH <iU`&}|U7Δw U-}c{:}*XkH3nx?uW*8KM5S'ySV+ykT I{ tW0OTX~X|R,+,?RKO Re2$@4bO$ FEADT÷Gd$Ó?iX6Pv\&ksnZEL̉׻ջԓO^:c9S'>$i|̻C o>FC}xןy_Ka$p÷ν0骕Xxw}z9je-Yq B@, haY}p[ƗF{˳ :‚VL{A6`rAy>[앧A| +?^Q(JBz}'@(KS c3fbʚ@M(Y:, Q{8)4hc21rY Lk!%*8 ܇i{`i_}j!3g`>8 0Z0 A6PӒK?ѱzR@:8 tڂ.x Z-a-!wRMBS j$< x9pItz\+:{h~}K|Q{ysNk_y*NFw{$=sFhY׆/V> ʰZp,qf-}`a/y1XYT}N:sBBy/C)Y8'΢+38;_Y`fy$+ wE>8^" roBAZu:4CcQWE'@1Hg*tde]3XGb~ 0kDfHMs1#2 vSIXѱ˚:<eܱ64-oc?\J['xev"V'En1eHME;00  <7KN)i;%oN1X!ܠ#yl<4B@2SK.\d3;pTh3&cf ,Y7V#cnfV,dY8@`,+lpS4谴- ,W+f@o .mysZ h۸8ogں H7ٹIA]@v~ގ Ob6pq"%RjOJYUTc Wy?#k|ux S>J'-&9 g)&@lFjK(7Қ%I^[gҥiw$PN5I_NϽ{$iHfJiSHEәwHn8Bd\kֿr]tĠ ?^!%;EKJȽpM O:Lڟ,ӊ>mDsb`t6G7?k1% i*JZD>`{[Za._OE ):d^a ̾. [uu /pj% ?|txH0F {x?p pO%8= 2. 8}ZGx:RvҎզWbF gI 8&5=&: I昝ϙ0":ô{ 38wm@Ȼ]2^K-8/-y| z0̍_X4 jXl{b/*J *WagD"7foRߧX f-YG5.FxdH=g =):(u;|ZfP&h6x6Mox8Y/=1g=rtHP3f}|5{_yo*u]KaPI[-WUA~N_Y/>véƗVnOA[sH taifNwەp4c+9<7,Al-qb[jo;zƒ ۅ/i% k\4sije#!8d86a5jo>N-`zͤj[W~-ʁ.D"-]3"^2,nrI˨yό.@5'n'"@>60ƫKn^4ԔڢΪ l *W5?}Ǧyѡ:|o\&HqYibgyFι.T+8|]v69ifjyM9.߱s)/3JfBzM^ƯK;ğ ] UoQ<䃮I:w0˧w?$)cK~ 0o[P:}2n 7z"u^!s=(Y@tFד$VHbGD(&Vʫ29 vfT)a?df?vY|:F!F^SgWCzkԌ=u:s1p7j8=-R'UM@ v sq)>)T׮񆖘g+3J<ʔf1T'B#j*{æq ?,- KQաc$igl3~o@GvZKO\=dæfY̗*Ψ_cr4li3h0=Z^Zy;|65!~ȯG!4%sWiWkڪ-mz`-Ԥ72;ZefMWVj VU $9#lS-Iօm]HօM bB۟۟(ې!nAm 8寱s[98Ow ޱ@K'pb.=LiepAݾi g\7|7 n;hTDBCh2i bH("FjEaKFa@j On*##DB0D0 )FqqxI("M=@Ƣx1g@e `)(,Exk "qxx4k̢s09ϝ / RX nO 84 &B.p$<AC$Ȱ %Px*aY  'cx ,xeh&YGcqpM2x"P4.DFP YfAGa὇b!o: |a(h‘10!EMXeh=s0(ёzNYDaQH$ 6GxP o,wO&O YWtzq<ǐwxR43as;s|gv%  OՙecKqXWNb2HKb'anS7s oF-sE 2~;˴/qںAyѫu1g.19p\cdWw7ɼ ïN> y?҅[ܘ>Ƥ毒Is5'C'* z;e\l=6ayQ@ 8- Z4vErQS[>,QtGhd{$*a ՏyTʷ⠙};岝(cxX\x~nE +kFPkWyineNLXZ /ȗ>޴ׇS6w;1g+kƒS|jA~{)O/o uV/(* b~2D%Hpm*XdTiă$+px=( ֆ@{&;XޤdÓ1t< &d^ mJE K@ AY@!}A*Âe>YJT>PXon =baY+j<FZN;9my#T|eE%M](쐴`򔼅Z9[tГeriuW]O1q jDl9 x_phuCن`od,^],i.u.p`MwDFza[GŃۃ7>l~ @I AOlaCA{fnR¶ T-2ęޥ<~"PF(R$RibN W_͎$IݱHkG >&ns"ԚASUnqEs툔N}ʰU0׶%S"(1zu [|s '?82MaHa1 F].$ atSA PYⅴDh e>(A s bO˽C t |s\`"+2o6i[T۾¶OvoMG6%eۢ'o ;3-Jp{.-ܡWx2UAK+$¢u0 ;W#OPpH]@*HF0$A!L)h/&Z6( c]<=х1Az!(ߍ?Zs PxGNP!P<8|*Z!7 }y67?҆m+(5NCt,D2oWQ>ՒH>00]'MKϿC RB.!$zK(B'XykمE^ {%n|Mn݄D$YPPK ]'8 ,VP< v?mF,c"wLё 5,8?_1o-&hvxLçzPbH>>@q!8Mi@)INm]_͛È`gzE+' RԈ xݸ-} eic: j\ӠMWg*#bѰ-o]n,*}Gzmw@k>VFZM7xJ17scLm*.x%X}zDB_y/aR^]/0NyxloLht{OR=z&WޗaJ^O˕v8ށ\ۓotIˉ;!J\U:"@P܂:gsF0T=ЀA g=V"ހ) |`j,Yv}zS]ebzΧ#j:d6xVyZ/aJsd\_@}_?Cȕfl<ԑ"tOn<|}u밁weSעT{Zo(5K 3J3Wfܾ OܴCVyxvZIU?ruؖ*#;/ӣTަg;)}/Zy췘~[o8dQQ#)' Ñ=:nvj5t_~,;RpwcyQh؏|.oDEfkȰ͛|w ^k_v(C3ΑrQgvt䅤gzuma2Hվ ]4)5G-Oz8xtv $+>ĸιtSjE꽽 ?MEZ|4JkMqSlZ}$Oww:?SCs6._!+ax{@DSReYIe#m {&}fGq\+ sza˅‰|,@⑊Iӛ_־5f޲M ʝjy偅H򝎘/n ;SZ πԪtYł}?Uz\^~f|"~Y b`oT kgho!Qs;w~zԵ0VO-.\2{# ^ QOYz(-z۶p9ra[CЈ!h4vq;FaVHip G3qM7ͲKj!v  faÆ+Ea% Δ_Ŀ4 wc%QXx E(Q8"iD̦ ll0j4X @3Ctn;.,%TD`pv,yI4w L@&0#@Vt Gab;Gc6s8"`sv8?9HXxD Xg2FJ)e7Y%Q4t?w#K|y?, ͥ-C `j 7m\uUqtr aPx9x!p: 2~y^"?,?*b Ck $A(PMqUo2ziO$&fW_rm5/{~8s'q3 *{ 7[Iy=UleSΡ9G[9KUm@\'JfjsJ/ebDz,VJc5Y7eEVknϭ9Z;pIuX)P4$?}|v\*[~RS t#CA͟!vR\/ߖ~KD1>gH=Y-5y|B{e=fqa_pـ1Dr̀[vaۡȠ\;oQ1Z5>j/ל/^\x(l?XiZ.FBC'lӹk+**Gl-#{xFsFru}] ޅo)P7k6ԴQ#D EYEx |Ǖˉ'&\Qˮ%?>~?1aQ˧难O|Of/ "_$|!_,|\1t gg w6}$mLunwb]+2 ? GDZj xΟXu!7&|>faҼO36qySm uo`G0]_us L㿓p TN|Ƕe/``N|/g3$_JG H,l,dTv(J GFYoy\5lMaod[5*\.9sY~wJԖ J0+\ꕓJ*F1 lH|8G{/~%նIAL z$,Yֲyԭ`rpʛluv}0cKzn> ŦvMzn~,|TZmh7MY8+2a> }cCռfoif>JVm6aJZx:P{#/N9۸ 9DѴ'VDCE$atCᱠCa#TqNA uh?M@(jU@_(H χQX:Fo>5n'ɀj~NRT/A7%^zXE+1C]WL 8,0.zC_]4@١Pi< =#rbĜL,g'"_'h}Z諭}O̙! MzV6);Da~Ph/N'X3d^O*`Ko/Ʀd_.JiV|agM\%LC׻.=qc鐷pj|r3tmXU,}+$ gU\&{{A#"毊|L#xBNJVxqC招\dv MsɎ'B3nqgэe[Jc鍏͕OUZֶ e>.pwbFa#"NvywqmVUgN2- 868AUӨCNSP+s2WokY8؞A?r7R()&<t'e+b'/ތCK zz PرH)]߮_<IY*)[.%$_ۑ`˵̺{aj<>朇޿E2PS9OQ2\|+9uxɰ0SOHV KS@E ɖSGw-H}9t9=/g\l2.| +L5߽}swuў*ѝL]wC9¢3^Jua7taf"@K[v?myPۮec^r0|W,T"=8/{0s@a;wwO\ɵC|v0iWε—sëIף9>$K .-Yݸ>wpP*e!n$mTiñqRF2`SXc!v/JPhT1.Ĉ^ns bUC҉ {Be"; ?ZxipܸђNڢsuueľ$N=5r+;/J*LbK@Evcj! ֡p 6^; CMZ{~K=l/UXt[r+[o%5KQ*=MKW90745I w3 y3e:z s'"'G#WuE3p",,fR7_q6p=\ E䙹 Gb^ɼ SiƉKHm7'>#;2OTa2V*~BY}-@kܿz*I'dlӞ|/khV^;AmibvJ!v؃c|p ]y]2aYQ>Rʤ#2<EνN쑀w_7iy7*ʧIiǺ"*YP{,T|WuODpWC+o25kЙ }_(QoY N[LzQ1mrcuwb@.%ۯ)2d|h?B!~u\]I[]ŏ!AG-S\j{ LpTyZ}|͵w/T/Ј9B 7BWOM&iLtl2#zbszK@\^漇~N5HF07a^bs]58NJ^| ^rFmƆ3i,͚n?^sF eЮ 1e.*= ѯE4^9p'E;O@|jH'bUO+gE޶,'-rS=n;2;Q1nT^KvTMDNp=<}Nӳ2MZEpt٧}lIE]/_a`b>̴3ձBf6s?C.1ٻA\9b|R5lnw)FpG\R!C˃eRW}j'{O/-ksY"ǩÖT.DjjkXS!M8E?Ւ[#H#wLđ67NjzO&Ҫ;Zkd]bw욳2q}jreب3o)aNm079Gp=䌟7{F|&n1PgV^;2!6p׿]/8A]c`)O$5D aR1lԜJA'!nG#olm "qY}779[WA,v^: OQ8Z(:@DѥS%`@H A"1~EsҠ!~!7ÆPߍP `ChXXɤϱBB.H! 'Q F zŐ@,rpuiw&ØE`^V9Zrp\Qu1,"ie}6ki=<ҒGp(T _"6yG404FˆhMFN&HXX0Z!):6 m#dr6V;憢(2U ))=ޤg aD]? 䯈9l&#  aFDT"v&PTNF=nn9E`7+xm7!ڮc(hV#[FZw#x8#hFvgYx:D{gaKWD_ꔠ)CAFtDo'm o]nEW_} >!"L1Wy0h 49Nz?ͱ eK+ț0%{UF^.?--W4yՏ FJ-O4VwU'UeawCδz^){yffg,{W\{ aդsJ3͑3)Bӓ% /yMWGLPL~k_"u7SO\͛n]RUzGn'S19=J@!@Z[DUPMTKEٻS;r0p뤁5@/×oJ4ĂtKi[k5E7׊SK3F6-nIKfݳBW1L˸}2 N: 3֎U.chlaU:Sb PPxY5Wyț+'gW < 2]\ȑ\ VȾo{w|&Oh` a^ W˞cyoQUmJP!Y`nW׋ \l}(=x_"JL;JJIKhMʇ7爨KatZݕYr R_w**h?08ٮ F+xqkݲ~"x=`^Mn"l8nvG~I.OjSDj>Ѭ͇ͨ3ן:soj4ҸZ\۱ ds]ԁ _p\~i~Q`WagX%?ީF@ p>_yF9 ˩Ur\oe+DgF኷zOQ`k'o>zrMf:rO YIyXHQӡ3+5]^aJ=˥IŔM9Y雷s?WQuȶ(=@ ~|3 ?m'$͏|^=ĀiW 낡ԩӿI˪BKg2< d? pENBOD҇s *tひs>L,edXcR׸71M`Z>Xķ֪cv >;ۏ GhhNir6aa~\2?Wkbx!Se;`Y: $@jDnA;νiRUv"l]8SUnVDǫ̲+s*.m#C!F%4̖rIPIe?d<2oHSb.Vɉ}I6iR@J€+5H^ ʆ o X'o2>Ff1g Uz;1v83XסNR'Di"sYYk.dBA :̬`"ycMt%G̈́Of|x$6-`d\96^9VA\PcK|$Xuvk~sg"R>VۋbR =0+eUm}x}$~6K1')JGn>IGqIY16yxn#E&\ErP"z|Ts;cd\TҤZѫ']Mr>5iG ]3(ꞎfzHG!F>qL-1w}r@֞<#HT{_ArWH (k*i!N0[/a+/=*f=1`"`zʛ%i\);~JGEZ"*hu c4{[^j6yON*1"%d?)EY^#pP=:>HQjc>s{~ ;آcѥ;4ش̪֋A~@dlȷ.(8/!_v[θW.;׎36]xeS+AFcy?[I ?xrpV՗4?u ii~rRNBfx~W$Oc6;_K%o_q wQ*[W(V> vT1PbY{f? K^ĥ)$+>I‡9?mRa%wxcg#fXSS>kXBEzzMqY}:s!5# tߪ'튧2W 'f.mpUv8S/vh]+_Pf!RF9?@W0ȁ?q8Qqpw5,oan E&w"XRAFz _8$!9a&sXyGiȎs^ z A/J6&N Cb[T@. 6? ټ윬\\Vm5?Y`g7kD,#.xyq3bq=AIy_pi̪-x == `7ta.h6H#^|]Sl˻/4 jh&FE/Z_M7ww[EJY鉆%cm3K.XV\,<{Yl8=M]t栬:ܢCv;.!V≳ǟyꅭFq~ : d'IVsǓ?\LRҭ5qSq_M0j # F8Z-* hoԆjB㾎ΦQR8+|+C nFVʕ$%96Ur`BV([4 F HznzM}X3i;$I[zAs8Ry\WyUB^Z{GȬj anO:5zOZpF껸ɘDft9GgiQ-ɰ 6lۓ·W[*{~$ ?y 26+}kBUlXn_ŨjֱCipPdkc+%;Z"Q b YȈ{,vvթ۹S/H uQaʻjRޑr;pi"Q=I[{n"ZAwèMiun c@^nw2z{øJ}Й[8U"$0d!j@ =_iȰc&QT> ϬeN/C! >u## \a9k@0P|cxPlopՖ0/PKپhzx8>kA zg/[+d3ZL_[3(%@>~UzB[ !8N*Jս rZaOX-yoDM i%/ȁSWr?~%g5CZ ΃APٜcےAA,)^=Dѻ{?P`!|%7Dd~ʋlJ !pC-yN ~Ca={cA}/%,XPj%@L Ӹ /-[W~n` ܦ >55?s Z'PhA 9I:F2(@hwOIr|tK|B V:YX5 *Gy{ xA a:`\G1d_ק1\3Bn-l޴WOa7zG3OA?"vx Zcb@s _0bD!uy>uIEv ÏЈaABbr.ՙ^w2hz/\+>MΟ:w3*T2ƿ5W7*wЛ`a]9Zi禉R}MH| j-O-h5[ ;)9fVZnlxϺϤ^T,M|'e|}!ױą?2Kug;Tc}'Ze*q !w) vO*x[A^ 2~}:a(|YU %iI1GBldgI}T>. @= >\Jt(6&AqIrs9^3& NxtgIлd#U$/-= y !t uLR،;Ha|ibP5kzx!ԟ #1Gbgk䪓ɛ*t]rُlM@paHm<)di;FǧutX0HҖ tUC9% |)9OnTdp^L2(\ //\K C{7BQ]1c`}bfabBK|<Tp}pA!Ū10΅3䦢;yt NtFJ}]+F P@9(F}GJQC/Ieo)Le͠%ݱ;OY!!tznyQramIN((#e\=8@ ի_|Cc-l&Зդ k:(aWY`ϹCWHQFY5ԃxl<Z9-=ALƯFiBv|A]eG߆RMUh,&Xݔ}d%/_s!.j'C ܦ V@ԶDvG-ak@/xטFm9GrO*ARMNO1> 8@ `njv!`BFxJ:jC%I/Z׸XQuQ2qԧ}M/KLl&߫JnѨWLג^+ծTnT>awV@: YF,`Ok^bôoˏc߉3h-XLn{]fi&H7*c$ZɌ&/2ljFh(q<4 yQ $GgC-yC%H f_X+!?y\@.f`xH/dѸ_h^8X8yxxY9s@9>p`@"#{^QN.VO*9^l;xX<|

z{Q & {(y:׆~l3ψUF%sR2TEy$?<<FiQ~C3Xɪ:+f%L=P|?k+L*C٧8!p CZN/n֯6nث`aky;CP:䃻?jN+wd5BC[|af)Ӕg|k7Ml>V'MHCg~lwDݵ[.C /h\X.AfYĪjs<MFtP@jbthh(:j+5@M=ҍesa>RP@iEJBo!1m6n`BFOaJ*.<>Wicn9>5pM.ud9sN =\egafV<3yFoGOLp_r&۞:.fZu AIb{Tq=ccaOSch v%Mav#ۛR!,e%dfֺu/ٯM6#$m(xI8ݳ=js)ƍ$yڽhdR9(Xչq KUUWu$rYv̘Li43k]4.,-ci^cn#O:u@x2퓻U{<sw>" |&)s $Ӿrؚ3({LB)qyH {e gOg@uVgQQfB2 zN9](ĄRU׉uΉg L͓.Bg<+) ނYsSUZWhI#!O8A1dX*D:$!b*gXCΡߧ]Yp+FăM6ҞޅJC@[3?}.Z~xY{M6Jxv[ß^ܸdVD߽s m8of!%;-bHaH<ִHgx7)dKF"(?w6Ґ),ɧ,#S1BAI-sO*GOA('7_ o/Z`s>/<(` W{@괷5+zW ?bAV"sw3Q4hSjGo!E_.::OR DpꌽuBs@36X6op9{n8" S )ڸ$ !ӓBèPJWaʋYۍNO{4ٕaiXDSeP<.P`C"2\W;%t;JekJ۝]y? K[Jl[rpP5чpɫt1C N+zuK}} *p宷>(]AeV;o`Yt'ec@RP`yHsޭDVoL?N1Vv&f>ƕ?]OIz9WJia?VBH6\)6Ĥq` sxrn!sovfUS |gZ d8;̾Q%'?V?!>JYЄQE=֣ʺX~HaQ{>ꦅ՘j' y|UGԖڬN3Ԋ6bQDaBIjVwY04aw,qX,1TtF0?aG~ #vɠs$D%niR Cw! m_Z@boAMkta} s*ax?-=p;* @gYpE)"+Օ+ D…!dž944~no N@ڡT:qMʖ EZDttnT.~{x+D}ָ=JVYykJd|ył7Д#t%BYLjΌcW+GpHy;CCeYTf>BQo[瑽Diƾo7#ge?;)qBvihZ>w^p+z2wAC"~ sWwpR.'ΐ*#88x0߀ć;潑jJrj!a5=^3rdhS=0՛%JÃ1]ڨY=fXbfIݸOtę]>(>1]L5,r`C蛰iPqN}A>c-"]u 8kr|/ D>ڰ's;H5YNmQEy,YVaFET4D l9ToÇEzXiquwSkf9i fԴpf|vA\*]6f ؓ-0-  qMhbFjޏ*v!'H$J|'5z-9P7 bTD.57UJҮfokj:kC Pt"[K޼Eh|?a0! ^E(=H/cWLʪರ |Şxk=:'/d! QĺX{j֟rˏQ_pz{T">#qG*Ƶ e^MiqdUAҴOv*:~pACCn#7M-mp2!Hȁ7Y a83> OLT8:5=mq% jAqSn4 i٥z&EٟOiT_Yg͊8?ͷ;@•v "c[<[xm 嬆_'+ 2J/tTKw]92g y-%cn6 ,E`2t\m@TOXbb"}4N {:G^6)R( H0Orߢ7)}.A `ڀݖ o G'}qktcqpX.8_yx__b t7L\M2ϋio 07/8\ 97/+_If jR# >d}޾g0Lʷ"f6cOe) x_Cf#1 >_`L;6BRV5.:ۇ \p ;Ib{G4[>&߬+ \R Y[AXH1]yV| xNk Io,G5t(J8 %#EhSɘ!>L]( η3JꔅT F.95V;p~)DG!f|i(w֫>}+EU{x>S){#w b[Gse`Og">r(_+eŀ2]g_<YX$?`"wff.z*7f!oS Ө .=mMb="ofILU'ŁD~E)Sl`ak%ZREe!1-%*B>ՌfyoG є6HƙsDY^~g&TOvָ1G,Y29Ͷ((B'j}.-r{Gv_ؒ gdStE?2]RЄX;}vD7bTjqobx%,lGs^!Ä@X+䨿+}(OjA57YNሒ4%oSf=/CR=f[b| L(?e>cRPQkR"f֙j;(5%|hk?9D[{{]rNaԤK z`Kqyx!RtC߅۫Mp2!Vn!|A)g\ Xcj5/% c"n,wt'~El樚$|ڟHcfZuߥ9QIL& zqaT]>MuHL^ZJUF 5Pj s1>r>ѧ@AǸKsd6/nzMOtɟ3n{8N'jE[w*?"5WH 4\uL{̶wXpRc.Vi|CWWֹt/w`l*fXt>h4C˚P97Hu r9#]LMKƴ􊢯ln8`wa'VݵFLP4+o©[ #2A,…2(YJz/F Qc0B+ڇn_o%c "8 ļ s]8>,׃Qi41 "΃\_JS o3b4coPAU,IߠJÎ݂wskW)4z%daGUj@O@m6 )WRb(6W_d;BUVdߦxkiIxOIkVwt$JR!lםsLИE*P$팽nƽ[FѮт4A5 ,Cpi܃ A{s=ߙu﬙5 ~YjGdKC#Y6Oko 黽w8sɷҖMF}9kcJ:ߗvjV,J?1{|[ɡ\7rNh&oG]@-aA[x|sq>ʲn5N߈#6#5WkѶBxc#.~K 1U%6y)9e`{JH>&@K팕YD2^q@.lA;Ɉԗ{orz6$Ke%( CA~= _K>=IIB m8æoW4EFyU@ńs}P!Ѹ;#/^S?Lzט ؠUt=\Su?F},)[xgKMNzh -÷㽐OqC}Ra{T;anj`Ž&Y}]٬XAtAsC9bulTN|7]ZMQ+j1.3z3\$lH*M;DI5kÄp !iWn*5xQsxհ:$x8=HhD"mHVQ VBE65~c#dWdi ǻCLej9RvPdNQ"lL֝w)n-)jGdjm;>`7Xs=|8wZl\7tS=&VJ/\ш:ŇaXaoI`Yu@L5nӻ}w1jku:_+~{uy4MxU5ڕq!|n!Y9raMy5)@Q@rX#I,7 k:̚s)s*R y gER^>> N'FD|g?A{EL__{xj1 B `KE">B%|e]d&Hjw} ̤8c~ 0'>gJ:" ';Bg%5NL>jj{/^;Fms+ Bc"CﴯyekZLe6lM0Q_xJݦ e0;_~O2ږ*:y&;J5svPӬ]J=NNEwxpFT湣ύ8 ,B8Xt #y毯 K~[B%Ĕ K׺ x1DEqotrΖ pwZ_$][9@4evKpm'K):C0Ee\1+Jg.o"Ex>>3 Ԟ:9C:9=2*r#š>|@qπ{___~׬8徴oq爸!\(dRhvNZIF*j/}h`0 $ud买>QL/:rE3a;-hϻehhaH.I`{Ն)rJj#Llo13|D [<). s ڥ~*)]ؾ|v`E;mL_ri Fn+y^kՍM)-*t /!:"O 1/r|jY&R%h-Uy1RzCnג7cGC.U[Ї4g Cލ+0:Oq㐐0΃q! Fߧ*nC.j{0r:.Edey#Zza {"q  _Mٌ %Oۦ FBU%sg< dts.rKklA I]9b޲,a_+ ν6X|fIul"V)ޣؘ:m΀ϪA#;. V5__wn;hZbrNc,t~|djɝMYFүqKFZiHRO!ǣ`n|ma~09'j,IM)M>ܘ?ň3\vcBI4A5xH?~,l)4=2=5Z^|>i=Ƽ տu ES|L=}iˋzX [1-rFb@d?)#$-fG~ۓ8-UZ6v@?|@#?}vޅS6.İ\DsژQ_K'^OІ@}1Ð A- h7g*_h5Mz/R $ehӢ߲R­gb+NJ)1W{fmE2+D,,_2>)LnzNe LDqqDҽsې_&B*!"MywbM.@KN8qO^cً΁5TR࢒oD(CE?vGHs?֤ ϰ9{cOʅ1}DiQ׷řSf<;YY6dxL:-o}8C*H624ghBm.zGh8cܿnj,)Tԩ`i<:Bc=Sg=ovE\V#||R{PxgBUxScmxASezDujhG>K9!Vڶ>̺#$Z`=YU!m?W(p˱_N]mn# T<ԡ`א*cF1fv1"Wb^qH3]¸٘h$Wڕ^6?C#-o_߲:| YȚԇo.;{c0:V[%%^%)I*ii~<)׋y:T-w,ݙp:_p:qxذڛUD{pZ$?m;u\{.`D;_ĻwB TVfCX`O2M&l˴EH#:eaX/\q1iB14LEH4//-Do"cM-^ݚkK,ftyWԕ?"⨽R/hq7Lp}U홧VwiKb?ber녈ͳ^n…4M'v״Lb༽/fu 2.A]l$9Q'54hT_FD`B?fu e^v%PdXY碥°tKdsV@LItES˞ ? =v$G~?X=* ȀWetc߳mg_\WdkP.jcjx&A јM|;M#9O+ѝ8ڞDJ_:0Č')S@`>Üb4Ra*U:pl1?M5࿲zJ GMD]E b|T&euNћy1n\ %u<[m;c27Aj= `H~3]BJ)%&!1Ñ*?DpԪqlIH)ۆ輙QJDZ%/(69%FVG7EY07ʷ#obh{QH2lUhϥV+C{~n#JEPT̓ݷ'H?zo"kܨRԝ[Kp~'F"YgA<~#ȑ EtBx2Ƅ\m 󞏟9 q xKcmΚn"jHxqhhI6zr蕰!fY.c]pt>ozW4N*Dk#ն+ @3\/ZAрYq}1CnX:=iuMdޚDQKo@'t-X; BfRԇR'{߹<ѳBH6>#%M*Zg%2F^9Sۏ9E{ֶt^/46hngLl(=m7swK " W~ҸMsOO‘xG3 Ez!7?[~tDGԚsUo2 hբ K/[ZgD? R r菖?1Q&|:r==!?zOyZ$[8{F/Y^vVFe1Qn m$~{DXyO8C!ɳ73~|O<{ @:JȞ=M8ukOxㄏ)<`_lt?xny„Ow ʦ>]ݼUgFnVgާ/ x-?m8Yy (`Չ a% g]=8^t0"f$ĞGʟ^!8px; 3A}yVqA=qͳ4H)ijE$ !'.dMl>S=qe$p^t6pi%z5ͥmթsU tP+ /w02<& NMssWΎ5IoE1ܻ0A^I3#0(46NoI N6bt3jҴGx8M89l u# /F'e5Ky[{׻zް r{YP#oQiZRvڙ&F螊|縃Xib+ YRQo;mxTb2xZĎK!.u *\R>>.׹K`9PuȤWSzv*4#O\h &OFVy"o/, -?ʫGl5Q@&M]AKaZ==\cQJW"5%uQ:j6J,_bD?Hq#\ɫ3'2t)x0S%Gb$ @tStEk&/&Kmb 4: S1D5DlFCK1t""W5,$@QZx 櫏+"JÅr]h/6ˣ_]Ŧ5tcC'7.oebiiMuv!yx%Qo\I/mLdX q2zy6cPc.Ļjf+W}ZafIMOSrVS F|l} <6"FM4_3OY:h~-;"1j\22*#7fܴٟ̣EMò`Epђ`))A@I/J61-S5uY!W-DI짴ؾ6O6p'<0 ۨlD`M程"naz]d*z0PVʂAM,o;A8Wڛ}`2wƽ[ПMqB^@<_ߐ1+k zqrq|zn٬oLa@@grПlmͳÁ~M=jvq{/UFܩ[2"Y'nN=!E@nRNjtͥ sQQ@h琀sIOZ& B(Hؗ!nL8W/WZ'̙!^Lj?$3KW-oM]omCp7/"rXE4֎E!RDiy6׻۾YY%1Z{zii a j\ {Ky#Q Ak|f@wzTb˖pΚI֯W(o$߯׼e+r`IСA?h-8&AɌ^ 6_m+T_(SC#B S4 EYEqVqy/R@6NZ"=UU ED'BK9e_7veS07 :_@mg2C.ڛTk&V_\2:tevP>oSLTKw.O?S,?˱GnhYvHSZאn``7ȯdDyJ[@|1{?*b׉ViuRNWv,q|4ehP&'. pfa]GfaFctL]㗯|WYA#x2Ƞ~*]4F8-nDDY} ?e;((pJouT3H?`RB8Y=Θd*el i=YTxpG_>dRcCVER]7.DFfՒ} tij𿉴(ߧ/ѩ6s dQ*{0]%'ɎamDy(~X3{+<*&i&4Ku|1) c168}jڥ {яA ("G_ahQ ֔ 6Ná託SJdR?E5S.qz[ձ(yHh0AL#>+ wZ*x{C\<Uf'@@@@@@@o slm? |@v' mmAeO>g-7$"dzexO؛tNB~zV{"\OLQ8~!y .04O{9 yn όʑ ?s1Q Xy98#?wA}ڀƒ<&,z]=A]a}&HLw Hƅdi gA\O8XEbMnRmtv_j:O9iIZ_۱X3SُDP߭>eY daN76.lיL^ظb2&r94ؘI6 O8oerаѰTSylZ<4ţ*S@tu5P^3&Q~!Ї  Q{ݔz׶WӾa =Qv>9ՃbYrՏ6:ߝ N*-%4n(E958A/53ɖ- 45÷ 6#2 )ϣ ":fX5k//z;GT>NE,d5JK$DW Jym0r.,@BwMGyL*=hn-_* O'j(fBK&Oa? QܐfFBh"lb_K[SUhsӁ-^nfTM ~ߞpLxs}=vk+N{\;XڸwhA(5‰}k+h8w—BI]^/&fHԳ ,{"9̛ J.f(bBF'ϱ/ƴoXWjv_"%64 el+ҝy(8񅎲tv'^yW=ϽK( m%՛u}q\O`n oY< M lZJޭ`og.a{Y/-#7^LҊt2 8~Z-6l;ݨ-ф WMSkD8L^hK6'$g rﲻcoYfѫQigEL%A8E^P lS'RЩ\ JI&uJ*&?Pyxrn}~Ts[d7Z[3Yd<țwe}VI-,җj>sNmm)S NHos 4i6XyCMԣ){y+ -Gɥzk%I(1w& k< ߋ^C'(ѴBù 'Y<(\Z[25\5ȞF]Sa }ezl|oێaɞ/&I4'b)YD2fƝ(m_f*Ӭ4WF/cz,}W)*ǜޑ벪Z]Jt[c dy@Z([̘uHfUV%fuRQq- tǝcӲӈ zSW'.{Ap UFxa ݙψH`60l; \pvSzPDv}u'Q0c6__66v:{- :0Pv/_1w~g(Z jO+Վt N a=~["tnLcO5崐u sN.uDy天`kZ-oi&se%B<_n9b{AGD8֊wqK(U*%WuAh~p9'k tn#=PxWV+>V6Np{gQ 3_K(י $%>Ѝ[2)N(¥jN . Wzuv}?6Sڴ@^j!s=64m5#Y?_IpGq/ܗ@_0_hWQH23$y6}*O fY\dxһؐiaM)fO~7*o;PM  mp8qMYO/qs?'E@Ch𼖌[ L>ЉK 3_ bf9x/,_sh%+ӧ)bv<"h/7:mߠӼq*c_lOnT*N id#abseM:C/Zi`ǡ~ݖ3uj .!lLMJXZ;,Wn?(igCL/Qnh&V[,]Lt1 %&^xufyO3%3hI@yߨ8oL&׋()RIWd*rULۃ%/G?vѹ z?~P+7׸`NR2Ӛ|wjW''ǻ7'W(Z@HD@[VyE{#b(f]>+YN*{ԙ=~&ɪݙNѹrM钱k,qU_B**{{1wẃ:K<XBsګ-gOpEg퍶E {J.׌a_}:+TȆ粣QݎO 2' _kų91B=u]vJЇP%醋ԇ X_etX EF/z w`gJeKhߥ$kt堵lofvAreoIkjX/&Bl\Qhr=Q縢g^-DŽf^^_ōQ&)F_ڥ3Mn;۟0(˘QӀxVL8~4ٝ W? Ţ6 Tƺi(Uy'EO"nPJ}S2ӏkWx֏<_,=ӁaQ6>Zy\,W5Qhϫ2k дj#M ߴnV|I{O{Cyf¶E^HYdm(U #ϗO2tJiA{EG輸ưWEw/˦*֋|)A,&/\ 'vdH6:T+ lT8v++Z^x[U%/bJsh̲??r&!֖MeVZ9mL-bInQT4dD™3?~ ֗FzR/MDwnTj*91xD0ËyCs'V@͎-NДA{nEhs ~&<1mX:gc"=޻-G!RƎ/=_"⟐y >7Ss]LHj`2|m~w.Ac{;U{4Ie!ǧ {2[97plN$x/zdD"Yl: sLlCjIoTj8ش9rP\J;!a^d-EgnWȂ+!EkU1FqsGff,J& D}Yh]R;FjT\XX2{t3ɑv&O`M݅czna4v*' C<2];=Vn@gޢ[ROgq〭~OL* QJPo:H E*k/~I܅Q Fr_=} %<U~_f %%>>>約Qn^Eb#&doz,5.B OS' L =8 3@X83AH">+;xvC} a!ИN8tlSӈR.`Kip=/Pcs<4+-ZX:FSQ3HRGwzpK8B/L(Qа"K]LTűNhwy9V xk ͚^)p{ӉssM+MbH)̰T7tw F_2]s;4As 6ci}/O^Ԭm%BK^`ش̵%S37p'_ d\\ Ze$-+(l[Mֳ ȋ njXdu6ǻ2IUݿk_KGnx;6Gnl'^_B_rJY(ZE.'/1^~x}A 'j>Ր僝}'`͗=IcOore.`.D]W-V]6(\_6>0{ֆ41xH.\;)A9;:]'L %bF"h6/uJۦIFz%t!|La (pwT9*gJ3%.7FM hmNU[2;nIQ#(KT M-sD?U7MLj^Y M+ 8Z`NRb]N&|Jd=, -X>;Dq|K/YȲ3jٸQˠrsena˷n+f[qf~ZQFF5wOꪽűUS  ,춀Twvsc+Mbj=κߤkc^SF$5LB#QG]z,kM13E7 a@QtD5)y@6+s~`ꍍqQ[^(JVKH+h 9`́=M-Fp X:ss 5K/A-4a lmTAEƘ]~[4-FND\rg4G8V㒉.ʠL5o hsjPm]2:fn7^kY\w (T?Hk" MInq/fv6z6\ ܆0ڐ=65eCrX Pdy_/Cq\[,9jڠ׵iՑ (BRB~ ԛ3c%tc7>~``惗|qfpw'd1qe?r]w8lwsa7gGUe0hQ{jR$cLrgcZ?v=쁾"7oWَ_T}EdaKY+e)ٍEY_#+$VZFթ֋9L O+|UW3]UJ#2Jk-ʇ e'9ձ5i/<(,CR~=Ri|`,?4 T騴T#*LMՙx7,q`%{1%t ]Z,*!*R*',n&'#)S٨ͽN'M? " /K52װwyroui]W#pJ.4O>E/-L %2hca9Dtn4mt(p1^WfjnDĸ~ׁP#e75m0WP7GÊ b"%Y5/F0J 5W6vRcxHfKa;* n-XZ0kmlh ZݹzԶuc҃"^πһjAullJ(L?5XD#):ɣXp [ܼFfĎ<BTMAL~ _T0R)ri{濵r IpO''mwn,0YݧRQtְc.kVsusp:kI.W|I RhRXQG︊R斸]g@7)࡭:n1 ˹n9fcvHDAa5:m0)X 2:xY oI8`突+Q_q | ل>C%C7^ٓ7:m^Ob,Օʂb7#`Լ]u/#G+Z[>W .Bi?y9&A{fk XK;r Xyi)#2Iw} 1 AAZvso0}J)'=U6aIk$baRЏ,W4H)zUJ7_]N)4Rh*c.H&٠a5D $q}[^mCj!Q.h L$K Jvꚣ~ane&̆KLÄJ6,hF؜_Sg.u7d;₨e 9.Cې(ٰ:N,SEwv_43GpVyY@**]5뙋pKfEçIl:LmR:5[d9S Vƈ>lTRҿz==Mn;ј/WFb3{{їq'xASZ%'Y5.jsV[8%E Cs?o]VI/:$"/cgJς;$o,-0;,=VT҃==XOpoZW}ݮvL $ !+'zn a&le<3QРQ&F}Ց+է}0"(0V_x[3EիجҶ SFX}Gj>JF L^άP31DwL\ޙ:vg/mAqZMj3 Cz5X-AWk=zemKnAe(*EtO<ש5 ,sxi}ЕtvpLCz/Pî\; ^U]Jf y'r"|^!B)G:3;@/#o!F|}l }lMzi()Ps)Ltbj ,4#p {対#i\:/&L  m Z,cUOB_~@޼Qc5 -cW3Є 'ˢ&ɇX3]6*]We-F?Q @- 2f ok]_h}mbJb] z ||( (r4.5q#[.K0TW!<;.JnH4qZne?l f ?vGX܉Kh$$~%BhS^]T%]WD)W#EǼCVW,,)ۃc!ʝU%IZPwM5ß+ DIyFCvpK * CF[:I"/&XHӊ>o z& p}1{WYsVJz`87ĽDF)31<}7c\'~Ann֍\5Po,w;AXjd&W".&=+zmz{+|} g4yvዱ-JsݸTxo؞BAs**:S9ACz('a>i[4|=RN N,P\&cDzC~u䎱L,F5O^%0&+Ȥ<wu ܂ثLГ{?a~i=jJV(t  yдΩ_)Ki댎q_0}`xB_wO}HQõ<ztOTs-)?Yaao>\`Xۓo+xruLl$`h_RaX˝fHˤI)l`0]lu}!J7 `80-_Cpw;=UNR7Jx _ȂH5Qɷg}Tݍg0崽,5Aʪ0([ e9>zg%Os%ݩhѯWŶ*!ZRy S\t;7?hlo1r'ٓ7lC>'q|Q.87asr<zhyhh2GiWn %:$c娝'~f;j̥i`Lcyu)ťy9k3عu|'zGjTz{T$|#pƉI7 %mm7vHc<^6FZCF?;sk??zax/ ;(8{m_i :b%^Ç |&&/; G۶xa1"~byd ]'m[7w5Tlx&7%Pd mb}:0^lzxޮFg"Grj8EAFLL=4 {ݞb|`=ysh WB\[TvxAdbX Pƞb3,RL((bq焑w!$` IdCdBk,&%ArH6[- /X{@z+@$!J&X!9Q=~pYo6 mGn|B*nTnQ JB 6\aT:-045 IFTscI-A z!gHc< @C)X2phj/8p4sw@[!1=m..M9I^'2@[xPsB͵$,u~MF$gV#|> V?/hfq,rrHcs 7Z& mf{nlTڳjm;[\TؕȆ ;ԵB7"RB4-̾D4ὩO: i1-U L+>8r޸֟P)t5`]["|FK9 g8s.@+Kizo<2I6# MZPߝm(s]-h‰U5p pewdAvV<.焴;?,hʰLp{|TFOQ)W<^vYa2mFܴćٌpWښN!P~zLj 9KSW +?]YvD EN 5G,Cx/H{vt}\x)P ydyn,WJt߸_?KDc Nڷ޶\ᵬA`^=b_)OZjW:="Cpjxi$eՍ"}xȭ8|Df$㑻߮%Ȯslghh[G,DW&x(+~r}Ð @* ¸Ju_fcPvj-vud6j{+iǎi(9]xN<6٩0k|JG"cG=5DCK)d7u#ơ_+ءrq0d [T1(Ͳ9ZADN˭zZ۳C$w$Fb,Xy6 û5Ov|Nfl)ۓz ~z[MU0R5^5C^xYYoGM"pVe7;h!4) !x + o$723^Y1DqoH*yoA1W*Amw`j+niq9RB^tҗA ոMLөJ{p.]+Xَzgx_)buG (b S3 K/ίQqH@t(/B]NP w2 kkW쵌|D8zt+ϭt>*1,/eeqPMD{~AHwwḘ( H@{&y6VzA^mL5P>6Aw@: d>Z%Mbl!$$bPBG8oeʲ@njNav$?,\ܼ)˚^{ZP(JEDEvD:.e4›m‘JnB0ӎ1mnx8k\۶;U_r'G|#J ѓ72/R6<>_Pd׸uvsD=Ny]_8y#9n" \OL\]ELwAƋ5o8RPϲS:mԈm|"Bjgfn]1EW#0qmy;O:i]\s̾)s'+ZG g[969=I=Sd)N. \s9H|68\e7J{85q=wyT6٥$OJ! y>g@c~h.ʇ[^]+1O͙Xo`/h;G{<[ki!ERk )\FE웙_=#>Y|}ijbSը:f߹AKf2v1Uߩ^B81S5U 4Z:QdLx#:odPȵ(%  'Vǿ9ebC `'hsqx@4<|w-x*Ny/%mmG$|!YkG<%PaNJA~Xbң^hfr*_Za]]!DXqxq7e~4܏/w O @N۞6У/QzyB*xPefx+0𳩉֋ yU+A,7BQݒ^kz}焳R"xMtlHdVb݈rk;DI߼^[rݭ&]9nN~-'[Dc AB/M`=KvĞyS׀츍gy`$g$cd@_S YEۧ<93憎_5%=8U|wM`+ n鬦Њ{ʅ E?zKK{yc,T7*eچ jI@^TP T\<>ᷭՔlaO/jq:L1" 5v*iruYh,i׈E,!בg+ޜX֔qW?c\}֊.f姏[IC1* OnHU֘qKHN*ju)W| kŬ3QN:aR#P'6&*Gd%66wnFjeNLjP5J?$&Q)Y:ԝ%OX u,DvMu(QsDe|Z AgjE5" ?Ble*!8sQK: wnDhaZP.`Ul)9j(`Opx>Sr3]\q:w^\rjt* ~ ||><B 9h-6[8@>Ⱥξ9xYz۞giS۰*!\ Lzvq_ȓPڜLJPz(f>{82Gqw1zHntL\8P26a^nG|:z)asoa: 'E 4<`^ /#q'4>`sĶE=ɞpqpq7|4Wh0V>b0lLf kd!nU;V;% SrrxD /F@wtÄ`<'3!,LC&s+d7pX| VJw6cQKƲ"I61`cpMc gp]c12"PlHݜHh$eg"90d6φ?dtfʈzAdI6Y(ՍPᕮ<9q"q΁o;eaW%ڏo|uNS[1D>b2 &G8O}T[o4%rBK<0J$rBaA̦* ^0UԴiE6Y2(q:fׇ"N0P y[s5smCZ["-;˱4>a%[Yclj~q=2(bJ\PÒ4^:F2u2zZz3Uk}ilh3)+[Zɖ| D]f &5Xo6 #00/D%k.ҷ6U hZl}Żf.zZH=4"Nv$/+lK+8۾w=l) ti$UhifZ%"?v 2EnIe}  wYaNP|Y`u>UP̋RkN}ѡ> Du\Gd"Jb"Ȟ ~)} 6Z"@gUӴVQ)/֢&VB ˉ:fQ0thW=Yrr*y O6Jݦ>]/OTXgjF/cf a?C+;L1e@%TlzSK~rѵs71 3m5,&?FPDv+ҭE=7$Š9#_}Ʈl崰&B !,Q&/UkMO{pzgeQ'-W,߬&,[ T *-p/O${"^ d@1d탕( HLZy:~l^WbVkv@,Z4W&)#f΋ok֐󝇱j(5^[ ޳JZ6ؼ7?b80r(~~굧o3ڃ~ $b6O Y %^1'8k¿2.hQEN$0x,.lyr|F926q=kS˟icXG#!ҥL, bH) ]t 1#f&'~ 9;~Pr gdF|7l?hh0_8}VO_D0ya1RzӶ^7:66׎:_Zҷxw] ⑵炊,{>K _g\wW<ݏrl~YߺZpk<~ oB(oL;)lL_׃ +e a /[[rþ`XL%I牲J[W. ;H I `@8Gz#"(k?'ͷrc+@)I8.g@qpрlj CV舤@nG$dEK y蓢' ~\ Lzҹ{[`vxI_:\K`Hl?ihy8_iv, `5<¥e LY/ _!@D p&O]ȿe ƃ}$q{؟ TAE#&pvo #`,^# @<m*'Lǀ"?$dunH/!0};a];,fzzt&&M!qm1UP@6tx9߽/=XZ7Z?D)3WzƗw}OB҂L迾⫇I"B#Gɿ +S sߌn?:lQUOށ. 뒨6PM`!͉i ]Ƈ-ZN fޏN>~Ja@ e}9S=#/r3eN ݯV6ǠfsHs:.jRKsG`")ށ4?su1f cs;u^6}$j$ė><$pH P?ЉXm|?cQ#eӕgV/PPti Gz]bQF[lVqFR/+ pV0%Y Vb: جldѽڏfgՕ}4q+ph0^X!up)T)jL+;ۋN!Q.uAhѳWJwX%5n(x :/3"/ꐘr44YBrV|6wa 8m9]&lZИfq䕎iP̪0SF#XAW =;@bTHURƻg&^ЊC%3^]Nݬ_e'q,"v5-pY5HX+x~=JP=' lXSHuE.n wtt7krZig5, rh ^U6=۾ 6}0t88pu$ p-7m:DXv.{Mm>`v.h=zvsz;*G/YtaWoKO$z gJ>txwk gEY9* ׁp X h!߫$ϽO"D&^ ]E$APAː|k/Q6 UdU8FfX\yLsg& vhR[qd_-Ka>E8(wIoF,dL\HYq c h4*+U|e Je_eÛ}$Z{S\+[eWLJYzN9>-Aϩـ8uմ_3rk*6GZ36ױiD"?(҄\E׻2(SX 91]yhjmQux*r4];BgoQkr]w`!sc術_ h :G)$r@I 7cCJx<] %ځvMeڄ6VrBy["\+0ax^ezڹr:A޺ALҘ=|o8(tayg>{ߒa33U16>}+.TcE\Any!/UOD/ɤI8Q&)dݸq-P-;0F#JX_z/#oz/Jm̰ qGD @_- bBUyOJIACm|x^3nTZ4pCjy{J4$>:AhͿe'Hn}S!屁ݾXk{%'+ʬٙpl)}MT=n8"p;L)ʗ+҃9Az7Yϗ{3@Q̳6Q #MtDzTEJv9>}AX4ךm#rBIl,X^?=u8TV/nnʷd$Kn= $8zL`1+U蛖agK%R*+A% Xt(*4)HxzK W߮8ȷT{PsNw6׋5kiÈ/PϲnsY.HJ\M%q ]+3 d0s7"/y?F] bO6Þq žg.*ZF5i0 aWuDي:6l- ^Ԃ"E:M|W;|vtd.l]l')AfWvaUٷLo_h5c&͚|9(N7i۬t*}Z34K}E1G0|,ZB{8(ߥ'.A t+*pE\` b`a.qfS_4U*fW xڗ,[_QhFik*_7l{¶^RU6`xшg%o&0W6e_!Q6bskdd!j_uꍹM" N(ŠeMj`;7HBtR]w]Sį,m<*vzRXm-Fhc( kt>hɵu  Yk8/Ҁ`_mD;^llz{GW]Z@YhC:t A~Im7_^f뒓Tn@4KPU"E%ˏwy`OZ>*;JRzJ}̛zadt}{wSУ'N|x [N< Zl^9mc@.R,b}m%w"w=G5q5͚A&KFi M ;6{4!G"1팷NMns ۥ(ܯgР*ΈXZ!NqgۧVs(PWǗ3o=דg>5Jc6ݠW*ds^v3>:rD*|PcW\'q} 0w2)@B^ͯѽ|xqk aa@xlq?GU"S@qNkK<DZe<)US數no,Zc߸rFEٕETS\Uxg7H0 ?Q|ަѱRFAWHK?\t~L;6ѳMsZOCʉ(\PDZG"goyj߭#^++k<82rX Ub/DL1O Q *^ߍص.srչ4pc0t0elnu,^&@.fh`yєNq@'ѐsYe`N; BW~|i[ޛ&jL`tho~\B CY >Aj{I u~J,sz"dz$m 7c kX}2w[4ut mGЙY3O;)(q,X-R`'tDFc[~wg:|CzRQEGbAhtpo7q߸ܚ| [u4'?fF췎^VmZSGKKs@aB?٪p[K8vPG+RYCO}@e <<16kXͅFkLP6wx#7{hn3l$xj9P!G[f|3{%}4ɞYhZ.#R@_F$&y qJe2}E]YjXA{ywZ8?^0 q%偌OX;1%<^"+L3^~ <t.a=/ad.+s +-SSjc/E`HG91x'Qxxy8 |rOI ؞5 0=.ɋOfh UjbP|'[=?_x|qc0x@7{!XbXkl66I'׷R*w,:1!,Uzy0wK͛Ԛ M\,qc t/L&jۭŦzbބC=מ4N=\ZRdMWN77Cp)텅^x/ƎʆŏS4:U'G5ol%[}.F )ӛs32՜x;.Q,$pAUސֻ*ʡYj,}<{כ6|g"1KxSP:+:& _AM~8Mr6mG5i%'5lN|@~[*R I~ܸx%iAqq/BMiQ~k1Qa6&zw', 2! d`W؛;YLodA0Hak WO8QΜVxzdtpNybӨU`Gɬ=.T {   #׍2ACfZm>A>:ei/*\1uL=Xttm6iPS"]oI0.M Xbۑ܂kMi@Y,lIf2(ŬVERdэ^Fu5 ,E~vepmsޑQtr{#[k(QYk%+0,&0Qk{^a2h,rJ-P1caҿx˯e+g%Ơņ1N#ÀqOU#GT9^dm֝}~Jsi"" H80, rrH LDž FLU0qQpy7Ҁl N-/.?^9# f`uCX&k2>aϥ?PT/h(F_ljs92s)ҊZP(7ߋ1NWƌ͑򣤰$Ra6ģ,,ravZ g}J4DH9ŕ;c}ZKF']Y 2e#UI^eO(2<F7_s{q邕5g>._ eR/;2x5VDD\l>8N2sV9 *m1ɘ`$H*y64afВKR%`3M##BrR`)A4X2dRÙ,RAK>@ +yOOeo9D%:R9;"J Tfߩ4cΙRx{˨6[@^/݂Sh ( EJq(N(A{?}~os8W\{+cd̹\kczGyP^`:ga 7 ΋/g[}X]CdieJd$P|g,5&O+=ڄ.)}cG]dLߣ <n#wioD<^*wsqj{Fr > 4ql 8WX5zǰ\&QNﲿ(W)g'}Lү,Pw2Hڔu HfVsv6OI380M!R8=OQʐ%)zЃ;`"NH2j%dJSuC8NWhj_{0].ĝ C<1O[>7+4w-£mk.9,1-a ~c1:%ƿчbb'[iBcsi:rf1J V]kP4vwl"ttӌ ?GHmTI8^sQ ]ɦSGnw[nOJ{|xMj𩞗_HS}^VcVuq~~[2BMkx/d@G(M0.u'R/K-jk/|,` puK C8, AAzA~A GH/ % o8~(>DrÏ3[8 `!(==㻟' "ƶ+; \a> n)=ǺB=Ixšb 籿_^ F`() $ |H? /$oЃK_1#%$ lD< <; 4s`=![{N'Մ![«I>CG 3 ݷڮj ȉ40*ڃOٙX]mӠA@( qpqdFP~@Z(l?>f00uPB|@Gqouq^YA.=Ggo "~AgG16imR]f Do~A'e5u.Dq rʢ/潏“>k{uCc103{g6]hS?u"bfqD}#AΚÈUt` [.H8 `ȵon`p 2;||]I}*9ݕFETP\1L{]~#$)pkq}$l O1I9u1g)کm^`& tN|VF؊1Pb_zhDw :*z 00`D,B0X0z;J1(kUiJIдbX(Ov&fCmrH%;Ii-%@ ;\oV PN"1G7Tt͇bA=Eu0mE'pUeIfW]8̐0)-way<$i]u&+Ϩ<۳. [a0ۡKU~p=oɱȊe Crxv~e{W\DESa;Z-L3jľ/A݈,QŜ3m-se7~xs h2VwjkJĢ:l5sa~#6NC _`Vq"JbzDseaw%;nxh~9t9q_*8q^?j|&cT^ c}k(=$HϲQcR =DutklvJSԐgzy1@jyV}%6)Zm3:$A&*htꗾ#˷Xv}_rT2a}VI`=8t+O~u S^툝@w}V ؙHHHFK{zW/TzE–QFXBaÊUU ]OGQHΝV>nH=1ܑjNJG~BttJsw D>Աޫ *Ɲ%>rj޽!A#:tgy8,EǮ1Bz?^&C;0vQ20{dd9 @t$G ;7tZ`ʅ,)>WX)dWXC10Ou $Fa < Q a; . sMOoP @|` H=ؙc( =G{ O ;Ox q߷zT-Bko;˨%(q-~Z݋^ =8>a8JzNE"2yz`Yi>7R WI[LfZ \X0j+_kA ;Z/yZZTy5f i(lIjB:$!Ǵ_' BRfv!x,!T{{q~0-P[yIgpvOQ%σTV)P%%1`ijqlmċc+ 2<~jw 5mmҗf!>YnBՖ/nNH ϟF3LWKIIzl]uy{4%?Ԉ.bakVvuL{dF­>[vQEsjUCTrW" bEN,SڕTPNهBmܚYqr35H}qkedr$>{'҈ CC;ZfN04FL0\$L92wH;Mח[8[n|QRd\%z$mͿj_( GН?Fͷ=V]?OI%U9|-] E9x+s'ˍO? !U&A ,yVٓ Ӽ9uS!4(yNwrEK7Q͝h#ܕ"r;s0)_բAQ%]Wwu7 mC#*+J\DpYEz? g>vw/3p zhhIGd"{mfB1⩁n]">$a#w%}+Q(@:CP{+Dii,м[AN"Q xR6jHJpƐ~ñԨv'%¬z|% $4h) bjȴƽ-\u$]$Bt]r|Ga;,kr]xDÐ஢"`wNDHa:jE{J,56dMz>׬pt¸֐"kdBp}*VGӯQ VRx8_ RK%p}drPⷶ>?0i+}^P5GQ2e.zpYcUfEJOi#xwg­-#fzkzkqx wgAۯBdC,J%~"c ~@&`zhJ>W*dB -#X+ Aّ%o*s@qb7k+Jڧf32JS55wojfM ܃#/GNcL #-ͱ!ݭP'm zaAo^eOP 2@@O@x: a wW ^eN'os/Ӂ o{f"ByMWm9ؐR @. {?,/tt~s/ă @!(\2@ ߋ6R;xDC_V,:{b*wp@Y l0O|t0crև-)6(Wlo`sB)' a")/9=]q{Nꎋ Dfi)xW?7,T,WKa;vH+|Z =8yƫQ'vuHYS60:Ipgk߾TO7:^T̠Mɞk:Fw˂a$&ZH"6nݨ:=~Pj7X~/zuy:h+n|a ,ZQsE%*,n7b^gCFLIֆt~e~ԭ4sgHܮU%|}^Z?DZ^j#V0ӱh!&ְ6PDI,^^a=`dІP,RkZΕOxt*^UT b D}.e4F2zLE;Y0,';T"m-+*'3op2Ϛ7Y[ Lmy{Д*z$|u辑 ? IjIC+s2.+ҝ#5fLlr9.tTIMkw.x։Y@?+Z v\2uJN oN SkBOse?9!b_ Wke85OBu?NR;Kߓ-wԸʈ!~".: n|!2q&<0ƌP{Z-[cu$evIђt+xhuRm~+وЧ[XuNZ$l>jtl`WڴsWfʳu!܌K*u_& ~ņ(QE^I?FEVֱjH)u!⢐kof E\-b[Ѭ'gz|XUS?dhg2!7iT1E#L eGY\H4LjaUb J 9 {t+/+&$fTFmTLu7mxQT[ K8,Wd%'G]T|# O{Լ:%(AB$Tt7~eQ7֥^Vv*[o"KdR_lPob7RB xQ~f]XEa+ {"I 责JvI=?X|u`sWh>YGC:(nVf5ů)/L"k¹n^c(ٝ.:TH#փp`DnRG"= @F7!Rin?cj{aqS}tK1ѵ֝<~z6b۷ SVXFdXtq_A h%jưʺ&skK,rd6.\=))O|o).%V~ Ta2TCΧ *r%PC?I9S]Ũ|1@@{Lxl  9XAL &C=΅BB{ >/&C:,0|}`X |x,/?-oqɛj@kr $J!K<IKpL8MXj/o~Lwν_&xs]w{"$ " n4]> O$Z4y/5<%@pr9"ćK?RzH )&7ܾ~[BD4d>a!a("L9}A7ܬxTe#'7SqWo9S%W:׏) dZΑе-;Zb1VBX|5fṕ7[SZ q`]i(<\T6SOeA2#G5USY)NNW!&Ar kPj?tdnڙHe 2 ZkͨLx J1{Rk44Y=&#Bh8bXS1ҕ( l[ٹu }=l޷v'}ə7 q=7f G0rP} 8h~\3\a<[iI62̧1kX~*X羆@m(OdzPk|MM "~uo}1F]{J uVf#J^OQx(?5z+ħ:!jQik;4\l֥0Ig4X?izh+܀S=гN@Jq!rlm?6x9'*,%d٤^7!e⟩^|~tk^w1M5ݒ=N -I;2}[ھaUAh&䐰{WߟOl&$E=evO оl@nz:\go?Fw 56;f ӲR < +`+&UڀO f()Ikg敋zFZQ["Ai5"#'Ҙ?85V꩏ǣCvm2~5Mb0* bmSvҨynvyud?xs (kD; wzķsCG?py&휫FuC'uk"^32m,tY+JEـ\b8҃!z5%G]ffr sWHHBd=16rgzG |ȦNG`g+XpEk;v;_SOr=a{hlDvvfboM+v_hׅ}g2>;|wm}P"OVLRe׽/@Wʗ|nPaw8,vLjYxWbM)e(fɜptEihJEejW? h]]력.cEbEO %<:Z{Ѵz$Rk KRBo :{n |jXYpYb#)ҀgaM:AFMl+'ͬNQT Ɣo/J#ET~PF`l RNF"btcZx?Y 3Aɩ-yFj3CTm8]l .S aHF4H=|+pk8-4ʔ6p+4{FCk5,CT(OPݜ]HPǞbXNCM rYL 33 : ckIs3pSJYBk+{ pHrQS.G@ZlJWZ_ hlF2 l$ئ"-X F4t77|B.R;<Q却;iɣNkHgO++#sp>5.۾܁;`3^\-SH`^L~]IA8@f@vHx=4| ~(| (Љ_^ #$ P`x,&C? hE$BpD!oj1 w8 OWۂz=B$lt1O48ۣ -Me̢PF˜yڮ(c)P ko To"EMNkW7xnK5%?e VcfFKMIŠC'P'aA%FtO^KG>\ -*T'y„ĄbB`2 NnͷX[Ox aIZsIMʀ ]+j/ٸ2xG*F]wx`ab6gD m4hr+Ck98=*'b'<8O|Trx[+uޑ+f),B:LғY[Zth?م-bHMDdaӨEx( 7_ ,i%&_W47Uџ-ԡVxN0K82Hz]ɡ ĥbhZũĩtd %٨%_J/gMKShu-(5e$MT. 8Eso'*&FA}SVPHEiLcTV$ka$e ]Lh=Crt1'k!ʱ꼮* eNBx Ylbv_Z5@;c~BXb>ia#6'g&g3pBB'gr auY)pfF̨v\al9pK'|QOq&s,W60ڪ(5o|]G5{]JIܝY[#E[U[eWǾQv>V)HD^,Ww֬}IbUJ*SRܒGS.,@j%448DU5Cǚ0O+yHd?-[#'|{kN'lUwz%oA>մ4-`n5jDz_.^:[y6N-tR[$cY[5|3XuAnȓo{:e x)iHE٥Ȍ޴+՟Jlz#Uv-yY+i_/լQ鮢Зrb1D5oF&ʁkWxcBKEtC|, vdtO흯a>4Hg'^`?k?{Q+0t5FY#b6Sd#s₧/q!1ͥ H>UA7[D>~k׭go|S(²!aO1b (>Cu1qncׇ`TFj[0´N ص|}]JU*g:D˕ʢW휡 \.~'ʚ EpDG NXł੉Y#|>=o} XV}!ATV A[z. =;]k7gN˩_\/p|I8P?v9]D*r:]dl+T|wn9Mm9*LI30 EGRO-k:Y?Fw|>=ޘiT_>>7XE)5M7 V[kxcu&^zґ,h0wXb&Xt>}jVS/X" ]t"hR4XuHL IP~;'3 +?J\~DxT"mrDu3mW8%W*u/>S)L>ևdݍpX8e7Ro-s?$$}nahmPfVg/ki#?] {\r,"KL^".TJH'Mf%ޟaXrU4bֽכr*M^5qde0]',d{=/Tu;˦~wc>?DmG^\tiw%k*֖bõ/3PZ,,ԝ6@MNp2nirv*^Ela ^Ŭ^4d\|z=uz7KJ.bDI" gj{ e}ЯARQPᩀZO0dE0C)jl(RO#kj;mCȍg="5*\qG>Wxqb A&SCt !zC:dٲ̈́ XyǦL/җ&31\ò#/&a>h8}Eo=.X.7r=hiaA!oJt%A? ֘)iRʱO1>aay$V̞Z9l/ցNvQ\MKD(8Ul\Nb`_95ܝYX*"`ם@ξb!i]RzC^+ԸH╚k“l9 S[F#Bs؄jl>PJx}tR[zMsRc]A&錏dB{ VKʋ>B6gcyj7hV;$q J=It@3/wWL4ѪȚو;Ns -ߩ"G0t,ぇbhBǪf;?0-!m,Sb 1Z8$cshmL^F݊`Gan$=։"y9&;s֘:VB(W![\ZϿRK*?17~2hJA=-ْ:Di^f/֝T @ΓFClӘgRucE }v.ϸXHO:OKՃ>LdP` xhJ 5@W BI4ԍ+2C~;](JL (>,9]Q>_7U7/~B^c{#L\#S]ml4dqVK$0rqMs&[y,C|W7ѿW7UGwW IT_H4-:<lLJEeqlRW,#{Z/ 7Sq 뀓!/tw_KJp}&$53MIg t#d-oy%2(,r`N2u2pe`5)ky_l Jxc&vee'.x"~zlv<:%7DDuY)P#˕X GMM;AҜ9Yr\)Cݜg/y&t4Y* > 2c^Ꮖ! ʻ!1p_K!I054%p0u<Ś_"OuT٬i/ոeNȃͲB+h;kWE;Vubl@JSwlnxG/I‚c&c1F{ )ZR͗P$R:tBr(:?P"N+dRKT<&8#memhz,y9/,2Azmؤlô^we]r}gurLDg-kAyRV57*#3yM-A]|q2LL//-/V1\$76$P&x;Q8㏐w4| [|Fb Ќ۝?qqQřJ4|B@C0 hpz,J!/4@ ԂA>.@0BP=Ooܓ& Ax+;#| @yp 1K =9ؚH !{6'@P ?^z ?#LӔo!MQ8Stc FGFG d  A1W\CTVrKcQ8x>3-,)7n9,&mld5نq>>c&H$D8U/(aBk'dWt s9UT= g~}jx\ՐEhl/}YkbA 1Ҋm AKh3A/hc"GW?Z(ԣp?KcGy ҄,`>$_|F*.69~M߇(f؋FkX~ ur@OMZS6Um*:{ мZX/5s.L63Kݥ'(ptg$[]3ZAT^'l46Ry`_ص'RwUh/ZL-e^=Y)Gbԛb~720N|d$tc鮵"갢䉟!֯޷8tɲb$]T:zZl BK&%qj.#w'm ]vQb[BcCqR4O;, wjd_"8|꾹#_@G}8~n7z8cs7ŪvDSѤ;2ݩ)Lvů+K LEAQ`!Rsݱ9[(Э4f&#R#։,^x]r$۶QXpym{$m¯XY e$/,d'۪s t&S`4WyV3V1ٽm;ӱX;HIGz5C'f?7n7eаR#sƤ,x^\ס=Zn lK ʂFl !\TtP%+VB'A/5C˭ *S8|JT'X|FE.#<_/r$CɲcYcҗ3WNRR:hwduhĹ 7M6'4RpCW\:Xl"n|m>}٫>EhfSZ LPryރDRtJOjԏ@E zu)S}ZCD$h]hC%œ.+Rӈ@o1yW1ljb[ON{&KB>s>/lp?C&5 kC.Q^-_Qj | iI%?8X!?^[gc)%C‡ {ٯ;ܧX3ϬE]_W_FWbM7/a,+LQb{21C8; _YRʖqI>M&'<*`ϳm e|3 *Sϫv[IJ=xt{k\IW޲G8R! =[z:5ْ{yj|\ȼ\a3"RH7Gyr@N~rNP'Jy5QX&^*@,N=&^&~֍; )*fKdY) t]Ģ1:hV[aHBu<pc#n%*grh T#u>UoD 񌫯AsjYQ/+N.+GS&H|2ۆuSNvb ș"ܗ\CL>$$J ֧e-F^ޡѣ>@9az2ENxReàNUyAXv bLjBp]c[ knu6oOjwC^` "o `QŽ-n Oh R@ўּ*A!S(f;' N#1UK?*ϷVrE# uyWB6 &׹X_Fsi/~~a@s1<;M7kp)\e6@/ToB0MAp9&#/R@CJOc+m }((=Vb6s'an0}kp3UDėS73n6G0\r%_gΙeӉ[*mM^ Qw*TݦsK1G[K&ϐ {Br\=-:2p^θ*sz8`cSk.{N_`lyu@wG5oxwc7^ iJz?ߔ)ܾǦO>K,PbaD&8&Zj<'_+g.kGǠ61fNDI8I #%̸1R#`?9ahQmvP|rm&[P2̯^abbA`Aa^qlGs˰`Ul;umD'O$ ZoLڤosl2ыDD% zpD&K~P?nHڋl֩L5VT(` ImxɮzȌJL%=$lC71uN70. ' ,GFͪXYaH/\\YٶJ&orT35&[7hA;f||* rVZ3c_zoTܟn@#N#l[t;Gk3?h9HhB4^'=C6yo XƎE.!#@w V O @ 3Tے%j3اV~D-JbMdaؗ5 63˄7 VmO4 2:Io |?4m-#;2˴)@SҢ1D`LjSw$a$^uK+Bk}()l~T&ap06jh?{]Ra@hw2Y)iǔ 7NOLF|SoP'%`F 47 J} |Icd)>m587#:Dk=1Q[K]8]V㶬E M, f*d1;ğ`DIe۹ꯅ׿b8c`wa9XvmS]ځ <M+Q9xh%L֢,7M\0N#kc9;O7f-8=OOg }~H5TfP tZeJP¿dGL#>"BHbXF. {oyh%C(0+lݙ)*Tp~S6捦vr(\Ǫ}3*Whyxbɪ'ߒ3sSI'\/+N- 89)С TfXi$^59TtL1exvꇱ{8 QQ5JBg7KfN ͍& f*mk>}4ߨ mg9mhıa gZNdPYF^5vUOǂuH4"`EN[E5ݏvbGm*XO ֚zjBxTk5wbû8e˃tnd4tnlV)/{89]Fz,9SvIk7,@䚰Ti`]RσD7e2Y?w LT8|aB\ tM b:JI&$ `QxZrXrkr$DSX9i"}"HnazQ*rtPn[g&C|5ҚUK%g'=8S'>;>H '5ίa4z4ax\E6B_2VlPNt-Asffݲ> }\[e,~9I!tۻX{2p-C*O\Ut,YZE| Hum/GPJZڌcশwQYw,|yNJnc -jٗzP^{4m Ѡ⇺T><2ߴ_'Ȍ$՜ G$B~D c ?kt"!Q*ш>@d!P=L1@ⷦ/"sf nT̊;AOVPfʽEF/D>gaͲHqm꤂[:jMTOiJ1#ӜoMm+j-4NYaՊ*$y|kK@.C5"y,]Su\ķ?p>.͔(0Adj|׿3{5+`aME x &1 ue46L/H`/u_P` +eG!CCpnL㳚~F~9L4[osYKڳl5 =0,VE'Ϝyi{Ce uaA7&A a;3շF f*vu3VP6$U}}`D?f% нXKGvcisV{~x9*kR9>a1|LJu BT܄GQxr0O*}8Rg78?%Ug~2n%4ӁcEJ2IBw8#R 2On+R bFsWl":ʈ:N.-8J;μsV,EdTIVisAkFTJz6tthuPT43Ehr*#G7Uڿ[W؜'Vl|RХoa[q L.̗־w6W{6@'$M1r\~ \'eYk?_?HC*o9???A!?뱻Nd`;Dv}X7Q:Y?jAkAΑ4lPbĸ^ޏaa@3JpkydO8-D`H.1 - &%:_5XJ^wdyl۵SҹUy(<Sj#j:~n6%9|IqgE U?w>z8M1-d0_Ukr8s^ .HgR$ζLn9+Vh|NvIUb+X]HT}gGDRz_s*%ο8Ž|)jͳ.^YD}&ִ4!@z!fKw3!MܻfRqT֊k!h~0,A+Q5{:]C}Y<=>hqȻ)$Q bDs|*-vO'mCU? mmI:~gy::20G\ˍ{sޝfFebQߐ!8ݠNǭ%gXK^iX/I(;;s]EEⲽ\nV0) F?XDXtH'u*ſ]:+؅GҰ)"\Bzf05C%(Kl\.G.I޾=ëԧV[ip(ƴCF+F߄£R\ ʫYW$ b_V){](bvrkr%.zƤ0hz [+[qCH8 },Qhqjī5 S=ES/r_Abz-Xb' l"^pz${ E:? lh0 [e$wiy^Uvm{jK G;Pӆgo !S΅7$'HD#  ?2?n57B uCZȼ@xl"  q16!|и4F(3;1MJb]f9~%<@8K8I ctgt1]U+3\ȁ0pYˬ٘aAqF.cy?F1oHG}?Hv㐝)LIl4Ջ3Sˆ^ՕM>.mB l 8ANy {8Q.]t&.h! >2C2#L%=In,^Rx+S Eݝ=RbLvf8|N4}iMW̗kxn8JLkkc,t Y MoLdCP7Hᑴ\yJ T<5mS#(h.s~`ܳa5^Vl>+]hВ1) uw!rCi^O=sT/wI7.7@*znͥ K$w9Z{E%=e1ЯE fЁ]C>EFƷzi.?"WQ(:Vy vq[l m,yh2X]Ia_O'znVښiEk%84@n[-Y.Y(Ӽw"t1^lN{RV4tF&Mi7t)ҍ)e3!36M.`WK| xϲBcݶ.-n#A1rL F.P|j&5Q mE:oO`?S=~4&5H_F$gW<\L3)UԎ7LB,#LJ DE89Mp}/ZČVy8èawAYl~T/5q=Ǹ#Ko=vo`#J"H/Tɞ-!6i(QtS}:Wlkۉ[moWeG:'+=_3~ Mڇ{3Mڜxa >zx@q ?voDubo6SKWpXSC>p|KBYէ35f>aE= JX}*QWkAJþ,Tu{/Է!&AEd#􃲭]>/ zc0/;(͒ 7.SdfS#`MG IWXTIܴ N-$no;qϲ8a y(շqD#Q]o.:I<NœA/&Xַ_/b mmwYJyB)j_|$~`@tAm J X>ZlET# hڮ6stVj>lIV:7жx,<18 Ԧ :5(?M)߄sx܇Xr̻Μ()RȤK1d87s8!G*㢢~DEW=ehS >b(~W>cYfH~zW> !Ab{!3G&`ߧyWxsMJ~1(mzFo{,X. e %{emLSi3ipuymvLpT%o OC֧چѣ''/]hץܐ&W7) #l¬x "8b@>@NIƀ.o 9_nXoμDEz~}ܵħyΗm%6,틸4Ftʌ+ΣEÚpC;>k.AG>y1j;CI/jڂjfɴEWW7>ޔ#,:fL\nS^?6VJoWx4!"(8q411ttnb;53 }'pUg&u/I Y! inC<"#O3>V{^'8'^3[V*nvVb}]*s)%[^×7VOHP*η".ܡRR"\~&Gў‘h+\ aڥuH% Ό7NV^54R-t Jj .2N5eH*KBhR!ީ: K?j,51<_ A(,ZJB+L@Y@Rת8ځj VJkܒ1~=>j#k=.ka >.!?.U,,1/^ijݖ!0*~.@zCfϴ @}?*?\!8____0/!ѐh_4/k_0/X/X/X/X/8 /ȃx?P@yByx'-b#!kt@c0Q  <~Sр0Ͻ?A|<G_ODp=$\xS6o o㿍@6BdȼJA߬#|K @*`hp_\d\g\\*4u=|Z/o׎ P  @to ſÈEBs9 @`A~ \ޚ$lB$~-A^H0H[ ~Ĉx%gy}'D&ϴ=|{ 4|'&Ct?ś7`Ax31D?C{P  I|hq ~PnADYaR?= J ӋO#i,xL">*@bC_!<ޠ[{_CFH w nOcZ'+yB*]Dv MEbw'3=6I0tNϐlv]:Ǎ/RMl_ZG>Γ]ū# 5 ]9=&<9<ȱ)2w;=*UX`w# v*u>]1Y2z@ȟ֟/rn}FuٰKSBeYp+aھڬ ;Ns%It+<c+oW6RjIų q /*|b0_SRAkrYMٿ)PSV"-<.P8ڭ[H~0%9O~ rސ?Ɲ6#̄ymUI)j\[' a=z` Jll^Xb>&}랦!1~Ff.gѻҹ'j_gSZU:3?mE&ҞAi h쭤H>Iȏo>5{yQ3DZ|<1~T6vq-8ƵҴ؅8Y1WOERW?ZJVBFyWn~PUYL&oon107Sr6 x|;qP k Bxq L3)+q?8S"42`pVxJcWp%-C;]̝ 1N (B*L&V'DKJ"3 #|aENͬLQUNMJR Md]w+ejQVur) jZx@_υ%5 yLj ^Obdm0=)!x4E)5Eu`ГkMdppvH4AGW^szq,ۣd%5"7oq{cy zb(svMm ~&>Y95A~/Ec}yScX$5imFI} bEk>3f$M<%nrZkKUA]MF_2J6|8&`ʌ#eaDLRw`a@uWfHNEW0-I4l*J.s2I,wڔV嵵anOq$ ѷs8&.2uMK"xf4HXbԈ|uo!'7L"sR?L=$hv67i5lEP&úyc%t8>oNFtA-OJvJ~Jw1X ]r[oih&mD%ݺN;V#33GvtuPm¡u}PJ+l Dďj&ºwjȜcpF3t{L+P'L6M؁ [ZNz!Vdh[/n6ze4Y\4,+Tmo7ӣ,PCA0#f]rOuɩ2RS[V!Y泐.Ju*_5NFź* ؘ1،6gmv2{5rD5ޚh, %\ȩ߳waK ENڮcg =n*xp VA"t E{3 ƙΣYja;FܑnIFdظqpEl[r;E]l:YMӶG [s /VNa7%&dۢ*. rRhlz:t-GYF`ms`tm$VrX px` ʣ8I2jn.{VQk'Q1JvPItEpz~Mc3b ="wZ>{clUJ?Uij8X$s5U ƫQzj`|> [ӶkiJ{S^F d)>h@0@ A>H@s>yo !|HT)2oP\gE~D@$ \ Y} C wiP#`-0aNLy|O4Wl'xkS6rJ{e@fW[wĐmGl%M-{8\]ӻ4&!".8KsW.3NW4d9&LMhiQ>p5bD] ?-3&,v^L7wo= 9nHASO,9/S>rY{E_R=kZ9my#nS}-9MÌ^>Ch^Tx(:zp {bAO )J5F<eưˏ )IN\Yї^f& #LV%CGJean]kuM5-)As%kAI%Wc囂Dp4((:BgzayթqC跋3N+8j=Tgv)TRBTtA,xgl-%mYʇ_6 )iaQmzLl ږ?/?Oz J3hBx/o.=" %c\ a|=T'6 jA@j52H f.IPV-/MxLI+KJFxeSϩ2K24o 8Hr^UPG.FɷT<;"u,=9hQ_FU9^Pp~!XDW^ ]kG?I Qn&D*|5lyϤs2ə;ǣ5gMe`ϡ}WqFOF2b)ŐD?a\Gd_#H=- K? Fϗ_'Ư Vs>ÍWknpxRSO+%n#[糵u :aMnh=5as<*T!hBGi]Z"1&5d|tW>O<<C/*Ds?*K-s3Xgں _zۤYL\rs#T1Oȡ<)wpx5~{cU>d F7WN;5D-.apwwP)ƒCpACpww@ xph5lRf6sqNUV^c¤4r}c4i hs/yx"jlF 6%P=YMEگOZ%@,;]rsk?S[stޮFUz'_J0p?߸[S}mk'0.&q*&W,+ԫ)zim"bʸDSmHBbqhhk$Ome»e>Z#S^[ˊM!!9"ƹ6܈;?(iʧ=pKTU)n4#T77N$ w kO 4}վ[u >yD +q}SQzVK_sQܔ"h|r`J'r"xk8.$E!$t/qARiEsKu}zpEa”bF!.~g}e: g60]r~q:uyyI,3_NJgХ1^[l^FXNK:"|5'33}2[<}jQ p4'?= GkB<ezL׬秉BW(\'lCˎvt ~߅nu0/E9ٺp0k ?" i:ޙM)%˞{vbz^iYLv=n|`j>(dZ@1[ ΁=Ðx-M&o$? 6 h!Z'4U5L |a} :I^.H@)Eb7exNWIrjMG޳K L%f&J`ԴL ۂ#S,L߼XW=H B  0L%O[`BrPȲԓ: ]r_ /~;jFl㔧n&2I8ҿGFL54uQ IJqU9ʽI˫'${N͸s)60c:5CiϛZq֣fDլ]A7S`'6,aWyP[A4ۑ6}NxJ6jCNo)XԢr8Ưyٴ/VYOdظFJ,K?x-!tVq֣K}XȭGbg@.-xxU);4;ch@V0h+kJ_~}#f'|d>3$wM3"jel]"]Lg|eJ0_~4/ 5L1*7U5U0}śIIksB( 70Do2h$*Zdۼ;1#&; c Xz"D@1NLŌz;S)'`"f+ ]ޢR8Τ fҧn?S v[bUBozwРrBBla+$_o"?׿+(<=WF};7RN^Vv 9+~֘}u%9_}g  E$ʈn$\T" 0 qDM:zY IDggO ir%ધ,p[MΎ4&lL+jŁ BM!1 s&1hRJpy\夠-)Wir,č-u|GLz3E\CnP6oguK,TUT>P+I:ILRsk7}$0~R5KYFQAP70 lz+L7f{ݴ.nN_lõ5n% 1V*K4=ݙ?&WkW{ubz~*pC{޼ywwu00RP:tҝh3qe1g9̟QPLjb5P8e%W3C{])A"'s3nTvjܘOr4yۮ(/qjk RpG7r$2 $o{J}M \<[&cJ0JiZP?)X)s{%̔B0B0uaAݰ`3JF ;QH';OSF=%Eyϛ ͱ8y(qik4izC'@YEJ_rXJ6sP27ȧv-{ B1k4w +2ӤB}n 5)ںslhŷOT9Άw] ;2Z]eh X}hWɔ]ddd[6ԦeęHJ3M?4yDbBr# D.٫Ғ@|/ݢb>"5~0I٣tΙQi-x O=E+ice \f;mWլ1v/*Jȡ(je5D/G*2w[JrcMp?&ǥ O M~~zʈ~sӹ;iإMcLc\1%R2%De ٛУt~0Iv*u+ARdbB? Qd{\赱o9>Âx 5 2}Gi#Bdȳ{d./f/n5(6V(BcA*;_F5ϳ"dρA,$f,ˡpcM9b6r1]{!kͰv4yԯ{vhdn~I'˜ :YOd 'R%g}"MIϒqZI[G~q'.yaL g ԥ,  SïowӅ(x쐇|@A?}RGXKcݹSH>㱥#׊vfWfB-U,F) Xu;|#{4e%oF(|̓J':ڹ@12{wa?Yn0a{A!?%0ŊrBQ1'wa۷j[m:U|`O]t{K]moEV.HHɬ%eۤJʾ/x*?*Kp{[ WQh܍ִ\~~ w_`Gu1CEx+AjOSO/[=RIj$ZO#\ @&Dڄܟ97J#roZBC_.Q[:{I :vX7<oCgz8RHUWhH$hwӥ{ӁϚ8[oJqbKj6/ޅOihβk}]@E8}.ido#hҰ QD"7I·9tQ\|b1uZэMX79FKE}Q_R=F1q=YXO.LzE! 6 ̤͸<]Ch2H,z}ks:c[hEP0k JQ۸SmS-I3!fN' S僒GGT%RDu.b"n3&!GŠ s乀A28+&q;(K rq#w8ߌĿi@+46Xffsqssfߕ"`h>#c]󺊓J zJ>6V}8y~ߖ z|RN9W+^oo!;+_T(Dp x7vz]>q@V׷}<דJ><띌do6lpIz`>u̟ FcO"_pM6VR w i >4xNu'n?rL\nj 6Aoh\!6o'^!u?B2}4L/W_=%@?k*Z:Yې~#YmLYzD(ؽ8 enzG@O8NήQUeUeUҦpXvkF tчv@[jq|E767Y&J;~ ^.v'*93ki2 pt[LlC6p++&g+J_jBCr3w$٤=)"HGb}.U-6 rB~ 2 #`Ί2fhhH(X_9c OS\m-ubC u)y?6>EVz@`|F:D$Ll_ؖ;|-|֤2x[VsΡG3>u&6;GxN` zqnBocb+5 6c^rmh+LsTpKu%667l*bfuY%.3?z2Yg$Һ:w@lP )4={ީl[ۗg%CRy`չm"ߟȾX]|:1# Jd(_D_k RKN[@Dy;]RX&]Ggz̡HܓW.8u=hUr+l͋^4Ϋθʚ$ny8FVDn৯bU9ne;paG.a G@|'$%C֛'3ԮG4C`VR77wȹTb-%UdUQס%:/wlEEpŘ/^N H@#$T@˄H8dWb)-sބ;$a%׃amh!lK@X' zUV쬢=ޢ%d+ө?_Tw=jOs ڮ 5mG ]k=_zf/hriWkA zu6hӐ, LCg>g>8J'07hgd, 5>' ن7y2h`jJV ;B)JBP._? 2e*f]HcҜ{@~r2\ w fs2?_$fL$^{ ytzp֧QvMcE$&)w #SL4LhŔ2)Cz0\1znً.wK1^.SIMMP8`0טoq3ݛ1̰gSVpm~#o5#aBY^m]E +=rCd Dz[MmCh&AP2`*U\ G9pϤ ) eඣ%-[/Xx(]20*GW @풀NV&S[WS}$^ݙAU /C_OswNU[/)#Q1KCY)ި M,Gg×: 3C4L5+- [1\p^S1 #k]fYvi=T-(*۾Bo7p_᫴ Ws' 1wvbvmn03mU&6vTd_$ImW_?S EǏ3eyI70\yjO8Rc\Vr.1zQmK8r@+ܤ_8KnA!L1Z2Ӹ`G:w Ϛ9MhpI^oS*@sOO8?'4U}>12u?k_޼޿p^{#h_vSYX;r Tڭ]k誩91mϬ vc2g_qk ֪Od%)R/hytBvX0t697gwNo=@_(+(1YnZ/pڎIgvn%#*)v(㗖+'+acZa UF|"mx[ i]% kI$ d°(fV#Wz}6:DLJcਉGPmsCPR-zTgr(=Pԕ~gL(8&C}BC:<.Gm$ڿBM*[ǐ=yNkߢYyib-M1Pc[seQH-T} u;p_mnL,ߖ!YVv2R1>g=LIKr7Ʈ^*D,nxqӛg~}>'D(I IAR*-w9G6&:К4a7[ ~fd ڌxL-NJ軕eIuL]gJ(Gr(@}[Cc)i&R4/IQ8<%Ƴ%D;UDBX`a:Lh5Jڏm>]3S(aLO}Ft+Fcua!YNgdZ8Di"A)0DXKy$mNW  }̞C IAʩ9NHݝCﺍ{`!?|j|~NQP5`wy7`z⾈}Rjǜ*操u;Ti/kn޲R'*|~{+$^* ,7ZS1v/@](J+ Ttc "ݟeޟR[Lܨ 6.8NjQaL BTj.XuXӰJ5cCgA>ԉSҴ*h.xV^7f vA!uPK٤O?s2 3*Lvw-G2q8&)UzG*^yXc`ަ loF>l_ vЮ@mDLRzvMUԮao@m}ԺgLJ?8JW=aPU} mC (21p63p׵,Q @|ѩfWRǙ=EvHG~\w>L)ϼ;[^̹40:$ܓ#T 创zz7Ӈxf,XDD.ԲJ*E]1{ ؼ}~.E}XY,6AĆNyK* ݠn@B'ۗIX|E猽zC7_{Դ.P^=Rk/oo pۂ>5bi6R ª~In5 lq0{t>' 'uE` KlUnS_Dj'ebv2ZY Ȏ_'$@d],E_KFV@ ne߆>bz'f;?x©:ʓʞn<1VZڽQXBj%Z {HOס_ O=wGk#uިZ \) t=P9m+)ZՒ5%zXno9cY%c҅Ž\,%7'xŲ,e`g!x\buձvlKɏ|H I7^FjH>bqojYގE(s?8)=E*P\X{# (W>%n$ƾ ,@=)N ߪ&XP@zX8@+;s`Y;)x=_Nt7?H\Cao B҃<|sD$&Vf[ 9ݨ ٣ Zɗs "Hځmн&%t'}?9U͝3S}ю5z})7c@:;>Ȟ_FR(e|٤LkSd3e̮dh?5Jw+3; CCG[uS៼H[mx}x{k|A'ϗF%,)`Zz,w\Q;R}JJ4u:H`C:B А^AS뵯6 Ċl}P2ډkZ^;ڥAj5FvR%)h'Nǹx|ƥZ#ne!Ӡdw7~ g5Q 9o!Rۈe.mL&gCHP7p,h3WƢ$`q2Kd釛Hkzfa3w 0@C&6Fd~+'_!f ˽g30*d9.je鯻.eܴa2,O+1@?7:g8/lShxK(nVNvrvN?Kl}ٹS p $8.< @ ;A_"]`JS{0̯`O3~Ac+xY  R?UqUO'<<p!w$Q@ĎC_ /zYr#˩tB!LoM !9coTL;6R 7 ohdZhd8XCqapS8]jڮQRPhiSD *>F<M9DŠۼ*sPl~ PbEa3d^&j4~}y;% hnQKΜ(IH ÝEݦ͝,BY !^eZٞPWT\@%뷔zV)?@CmC߷p˙^Po65ZϩbHC'k q=.rM`kWS|Duf}ݞDp|<ޚdlIP=I#fjwF.fOZfѱ*aЬ 5 dOkLmtMsPo>7h\Na!*"z0e $e)ufSg0u?ՍBۄ0 xSlNP,Ve}-Ǖ *~8៪SA@iZ^R>NOQ=5|7B&ou33qԭfHKo2b8Uz#~h%m3p+պ6WwU}h_Q;+󧐁\3qxV%IwoE2A孺^ٙ‘r>V?~ |g<8OhBΒgO(-t}JR@.:CH""{˝0;qܓ/N<%5}K.|郛1c sƄqmOLh%F*on/"mnʁrS)1_9YFMg†t.:l㱯 oTS+Mw@obpKvU+U|m|ޱU/O3X/;ϟ _httl[[B#]t(Χ<'aOz;70WV)" ^Sٟher!Ee*Iy"͞DMZپ@v >HY hX>J.*1&!]t:?Gwtݮ &J=!x_i&]| r@/lrsm_ -0Nv{B?YA{edTm8+Z+_!r\~S~1U?GiYX 0 VGdegrk;?;<FE$rrB/.V*ܬ<ܯPh=S3^!Υsr9Y^ ;7n&qB JMZ Cha!L>ߒT)| ^$`z̶%؂8v.rP2ͪIBi:"l<ՌB]Ru봧4os_\Ym'`t^^[``2֎͏CɰM&ӿA$7|E @v9k⎤eJ+<7;P޺{-Ox7OhZFeu47NNCN1xF&=]# S?Ϟmͯ{ԄZ+d4%14z_zC=[Ό ӤlP1C5g9F',DH mf}>9[[ݕv}g±k.6vF豄і8Y'FE>J{𧇺]eEgN[ J{M"Og[ȶ%䙴f *:=27Rv6Q,f 9mvZe}Ê;G:]k"*wyGpJZ`~ru^OQvsK.)}?jXD~y6l ]nn0*:aQϠ֧*GemR!TRz*UAFҦn^gC G)O~vͱߕ"Z\-ڷ}ŧ9ݵg&0G3c:S{f s-CX@ gef;%0Qhv%A//ߤ>Qo{M/_Ose7}mLX jwz称Q7(`aC4ZFP&_M"N 6ۼ s%eo\T[46uJX<NjzhڽlXEC%!:+UOE ) G#]8p;.6CE/W@5CfrVX6&$d=5F1Vh,sL#t5hӲfB-0=TX*-N NV5By?nT`0fx_B&>6Vz>~m\k}7|֎~܉8X<ǎ*;L5v΃k<kWtzd,i0h,i |l lDLL /`eƗ#) $% 5,1q#(ž(&_vza042Ͽh,?k~e9w%vпHT(0q Ԁ-q{7(pȉf6ՠŒsŖZW0Tҋ 䴍i2f dYz{N гXXsl8#kx뛏m=13Vu_.f{+3cW8|0JOWj"μ;҇1‹$3k6~R:Ytx+v=oj$X DICb԰oG=ga&>mƁc#GG] _7ߤs7J`֫lQoK-8\?lfNV:!ʳ9.#)&pbeVooŁtQjm`PS#'َml 0;q~WW$1A6;ܽ J[o7F:뚘uZu I1,Ҧn3bfIlGOkh\AlBALq[G` A3k0CM[qm׬~O=>;kMQ+00hk“ A,RzC;W&LP:o*ELf`gv l@+^m##}þh.!`% .5,ƣyiiCI_IHhz1 C=|g|-C>[>mM Ӣw%G{3DȚ%MQc䐵0,"\M;4|tu:F><eg 7BQZIK6 zSC9ZV#s6羕HȨ %SC>K|6"`L< VʙCS)r͠=ʲCU_يsgR}hwO`׭/^Il x(lZeYJS)9>35G lq8ܼL>%y#ɴ+" jC3z[t^dҊkDoϮVA^۱s `F8"IYtSB|)ǹc} jP>Ї8-!yg75h!|EߵձϨ$L$* U$ Gr @|#us$ k M)niT4(Sٸ&|u{QL#j{׭h3%sWF~OI7Ώ KU܎H]IucU:B Ɍn J9(0n,R\44!yaRMHykJj}P9p֏)=6Fs _ Wvw e{rĞ JRaJ͗K?X`dưl v82%*N>^}Z'#dGmY3hlG=&"MВ8@~~4j^ϫ-BYLұ@s_ԋEwIR2)YQ*zj{ *d~M7nOiA&n\V5)zd&mITcI.N-'*#!U> @R @ :L~6E'>~ lc9Bo3.#??/R ocyֵڀ(o8۩|OD8:Qˮh  ؊壖cǎ@*I#c+Oegq'[|ȊH? 2BcQxel-{AMQ4]1%Ӷ &WdV8N(V~3n;΋Mm5^S5?wZߒ'(&_\$6Y\g9 Ltmm@7u}@KYG`5@y!/Mtсh&l~ p~^!/T_SltYVyk,A<GBk MsDĆ@:"J>5-DZ Mil!I'AusO˯*H8*&X+AG&6MwQ;ֻ QWUnS8TT,tKSb{ɒ-}EcX4U[ %'A$4Uz4`wcT{#<܍R:6S | zֲ42gT^ֿYXznKwDŽ)HƜZ}%}"`'^1J"LaPHۤ5׫`\w&Wij-Zvo/  4!wZ`uk@$Ub[/ Kz}}zي#D@. xiwzU9% ⧺XPy؋gl .W c:3r  M IJcO˪pv2Vu(%-r rj֓F`܊@PXv H r҅BgcYfR]ig/go~~47?2;p|G!RBeIȽ:3"uƴUsIҜ6F0`< lWM7{g}6nTjqp x[hIV2٫fd5kkyțoB&Jb/kWe /,f}ocy|9b \V (zA#ZEf V1o1ߋ`%XguY4L`@>SZ*$HLIx7R&Z9ޛxX"XG#[В[x8>+1Uݮ*wY zQkox܍jfR >rx;̙&[Uլߤ.-k IqD1 ݙ,6Z;pGv UNf-9vw3 !4]$ļ()KXYӔy^M U(Q hvjkbYM .i_sS|u<50XU(bcԓ3:Y b)of*nFty`ƒHxtrA*=*m ~\*EfGh:wsDNWUg @_ҚLhŀTqfp1`d7*p-rx2kc'x^$Le}Ȃ< py*wjO/m *`0kڼ4(:'iM{\N :3_9**e(Cc?1:vKj B=_syO'^p"ƴjsP蠔-2~~NM&Hޅ{Cj7d0TxQv- lB՟Tf1Ib3}{?ElgˌH~hwf=ms. /&Pu/=-N cD! #1 ?Ai۶~f>Ynih|%A+x*g4&ktyg5K?{E,EChVhBn^d=}~5y!G}> J/&(\w~#WTW8.5K;Qލ*R1utD vJPzv5%7 ݕ#D.lE+.lVj5G(ٱ6 eIcJjF 0wGޜ~Կ տd-ԣփBj` ]4XӁwBf4-Qt,al.0oayԽåEC7@dcpodFفE{{akhIvC[RڶW˱#:~Z:h'iZJS p5D#𮦶'|r+@5YtMi"k `)cIRɬkz 9Ζ [aڕzLzD霡óMj& `S=M?k]\OU^fO!-K ̪JkZv}0T>Nq)u?lGw2$ GO #\ޞ fjj Zp#T+"cOD!X`睗/qʸ>o![^8'GA/6ZȧBX.p-Tps~{:68Wn!g0W\ ,5=#zlp0jjK0_[\`1,\Dpݦ߰]wt߈?Aw'u!!yzY ]22H|qRgsFe>_h,[Kp^ -/~6_$KcboRۥ(CɎba} X__g!?{#K V 7Uya}+|6.8Ψt>j&b1S@T#˗ !L:&LNλ}N =ۅYdPV!X"*V^ LTZ~Dˑ 4/N~(,:8r75@G ]fE ^2?Jr(ǒwA]SVH SWȘ M5["s.:nřO mBVBdQg5ߐ^KDiw@?4rh# 22<,-loS!oU=2P ͱssmU)ڊ0؉y[/QhJU{e4y6QgàoŠIrmPx0p9TJwG:Fq!X1QGзʩcYlL&K{ב0F797|1`V` p~˛\ȔJDyB-eDu= 8^(D<|2Lb[O7Y"\G V̽M%F䱯ч٠N8<@d.[ ݎ'dAMEtԫ 1}hjVǍecQBNuuu$1^Պ9WY?x\' ¨iW]ҙG0L eUUj;r`_V DΔ'\(K~A-BgBWYrȚD+u2,9ZdE~.̪`7E$uM~ fޣ܏pehBq'1hr{Wh%dz@'\ݶe&R$Zݦ55R,"o`CGCWがG#`^.zT„)48[}']QG]0fG_%hB7 g/CS .i@ o2aƫH ѤA6TzQ|2P|Ǡ{BQ42xxX4$Ǩ([rRHd_xQ{Fl*0GR?ET,f ̒#d EzθHoYZV"(nڶ1#>77+_@A(X(/<̓6jUxVΤ={vuV4LT&vf&OPT4m C_QE(3 ?G:UE?UH1s&Ҋ$eCD^ek4XeɭEɈkxe:9G}qmYhk/nqHW =Ӏ3jB|AGp|?\є;abi|rkč>:i+J2ciک>>CyL5c#$NGn;]A`a(HA@wFfc9sUkxnr&=hRHAEz5-A"5i𓺐'@Ԥ\-w=ױ4L964Ώeõf;+>9gsy.Oq =~q-Yx^,)"~oɤVy< !Sם:~ζ%!G9"&tf+cD@kɴ cs.N%wɡI]F݅>U^%q^scuf<I|mT^N_2]?[%pGtYaeI;5!Ϳd_ keM kXLPu?֝o6"9DX!hf(\7Zl㲗2tދa/4)\[0óylq_G /~_{w9*",DHUWY&4[@f4, J͞"x+>/[K#^딚E v;|xܞ[:j6  i (LZ/U*ڼږXS\m7Y%z'ge6 >%e6*GɔN] J\*rlr-)/|ʨ9$U8R5UXNZ5T-p;7/ c`'V$!6U \_MqHEuPE%jjk8ƌ}8Yp=FUK =kHQdE4L˶M-yйӐ^qfZa5 ]ξ~ٿ,Q֠:5d + E>_# 8Oe LRmj;D*W1ɨjlLXAOT }d)b$A}QiEX)|~6 z|R w>SAؓHCҟLI'n'uubq <z!V1=!{HjdH *|S8Y!5^y#(!u,/q-Q{Rv ~& (|ϡai̵.}j9RQu |mBJBEAjMyJS2S }S*_d\RV`GPu$70J{xWLn&EA; \*m'GV6@-1\6<)l{F"x]N`yqT0Ro߳T(޴ pgX>CU198x ׿O]^NgrGUZ}p39a\e2#*#6̰u/˿F?)g]4̡4ID9t)7C8VFY3]Mu( k;!Sڐ<+Z}0Q< Kzcş#F376Y{SOۭDQVąĎj %QKIy(|F,M6C^1+HCP}J1k-͒kμuNg#+=Ȳ*Ne9dp`ݛ& DTAEy~u{"R՘$i ܔ)8У34YZ'MhXȥ amkVUKGi-{BTH*FegmY-&7s)DVUh~a%%o%@s!`X]>]t2+kиz`KSuT0׋K|Q'ȉ/(id&f ~L 5 t.De J3:_Vd^@RT_O#C$iTM@ ^ZLӲ:1xW+>Mvi <1cuZ|Y?Pw+Td ˆRDt)FT1>9nW#P;n? ?nj V 9uNA+r8JGYf͓4 DهJ..T>Rw,{ȏ kzkҫxg4Z^ Mb677=F'@6KL!EHʂH3EAo{$ ۿQLlHX%KJ "Pl m.+0JFIVRP֠}@dvw{nS/XϬYڣL7$#pJ"ד?c^E.*M I_4 fxMg ǁkJ/=K(ӷٛ9xDq5pAAO;@Sˊlv-Jv )Wp3-jhn-Z$*ɤj|n%UpY2D*"0ݴ٘6#<߻R?FH-紿i}<M@tLyPݎFXFXy(&qOhZoUMGDAH _kqZMm6(՟?<`*{ZWןMTeVBѵVJRY>lӜh$wݏ .A3f:X2[Fs2 ݥbq3<}hZqNhkTLx*@LfJ 9 f*-ßإD,Z 3'9 8γR}gJA)d_V+| "Z(A=g7U2pQQoio{Ld/0>+n)Z3v%uaY]tDLlVHBQ3bvEP-Ul!P ^opaȁ R h׫}*D ,!oY #ͽa">\P~gdTz8U :ك f00j<'-mA}OD,̚q*Z:fcU"*Ee,RGA@l d FIUaa ry WmJ) W/hNޞneEV_m`=ug #w+ -,#$MQlM1|U\;n{1D5ƌ1f+큯ٹx+#T&hp|d:?նRˮKmTۢ"MB.'^i BU~@D%"A*ҩݰz:"cy9l&~=- u) ӽI1@[:%.#̮BML(cy.$ǺGf:ur Sp ?G}~C n)4.lJ,>aa.А=; W]]JmeO,C4|[X>^8 m#/V- .^٠Uur`, /BS!/ {KL`q!̏H㎍. ~`U2:9_?B}DL$hPM(`a r2PSw})MZzJ[6ُhH3e[R~!&:Eb| o Z Wt9O2 fH‰^Œ1:Op7 P!w= ! 꾔/:JF1Z5>xh s!!"#'J„Ypĩ=E8L>[O0 kq(2)MbNvڿ !.WSeR R?!{;T`2#Q :S$\pj`ZĬA뉼5ԫ#YT0= KQٳ2\'HG3D_P/ o<w5!KpOUB?U yrςNQG"ah ?%7 WH80T@<yy\P Zja|'2  ?`d#ar<_*⫌!H'ha'cyﲊܠ)\˰a(!hn B!h. +&_"]hHg:4!$uW32!9yi9x~NTKnT_k x~D=4EA3`\Q[ `yT2ɽVota}٘y[zlʷ:QjVlaPB,6n6Lts'ѫG1%\>_iދlf>XIvecI`PxƠ2 JķRVKG#G> ߤi\%$4r͝xIH+qN$]%QlB>`َs@+9^M|`8DSX9iT{ @N( 9bF l,^Vogh{5S*7IY[x_uj5!r?".r'Ct /xe$zi?oO*5/eh[1|%|`r{9U=Ǚ&"jBPJŜAUQR y f+]o3R cuXܭ=_[ 2cDLۚ (TxbQ/+Р6cfY(XBtoh謕ڑ!L"!}~pS[hUGhٻ'<)`7g_Rewa_C~ݯ<ྕtlz3K_iuɩq>xY)/(PTk` y=;hpP\NƄcoCQN%u"W,RF_d'`I}ae/%E " y  LiJ]v|tOW;ͣ@(0UvA^_QҒ(5H( jzQL^+;g50a}i+dǩ҅B̎׬KqyK4jV}q4պ1=q& U.TO~u O}eBrll= -g{SDP@cHF"xRymaԜ"0/MCN 瘊Y\YAVz]ذ3X|Yh.[67rx f[, ۛhP&Dϲoz-զy=a`Ek N$ۀG 0frS۹Bs]UI>|~'j}LgL EVDpnyqYtQRΏ8kqt]ܸG6׊!RE|tH28ˇw6 SFNcú`=[&[,/ֵnQоQCϠ^0Pc(x9x!&<'hz<pU\|lqr N0" k-HG `yYw9~~%AJ8yg'%f{Ntem0q?Zjz`oZg{H$Y|#f2 6o@!;2"a#(N55 kK5 ƪD7n$xZߛzBZ>j%uat n" =%M:5ɗI͔O}*oKPM/;9Sxao&}* 6ԥ>ʻ͇{&;.ā .luH6 g3l65-DG.5\Ez6 aM[ރlې#Z*ɷ3n n>^Ǿ,OUO "bQWk-U3SC9 %MMk=Ye~ǝ L#@y!MyټMyݣםImVΟ2#i5ioc\Bb3LXHMB=Dl*L%Z2YP7ǎ#%loEZRbVFDNJx'\Ӎ06i2 Rϻ[?J.[* -FFHgf7?!ZR\x3#nIa<% ě{+Bc"`d3ޟ>&^d-1md``9 Ь . 3ugAơ$\Vڌf82ɭVh̜ZE\/x @!Uv%)b_v-D묊o+&aɢ놚oDsR֘'bW ԋ]9dKPԇ*茅_3=`TӀbϧ]@_jtT ~3MV[hY'Ry~qn0UxzKNl+$U<ɶ1;dzT͋d=? rP:Ĥr%56rJz`ۘcʒX`eo /26.^Il_3PV%_P:<W?U´f\ BEۂZ=O#hɳMj  .DHD*z=o@rLP.P`a-@5rrVGimp~o.te!~\W:[5~b0ʡ^"9k4kJ*k62u\Q"&KޣdXD%CZ)XSOg&5 R.35QY}-)\W;aL,ةNk~pћ!Wmʱǝ \Q r MtgY)O'aqi90|PG\?4|X9uqqoJSn??I궍ȁ־> +g/9<6&BAKrK (ƫ|*Tk!/hK _UxB Y 8|hJ^?=?7UgX﵏9#fRr7A `!\8) n\l\/ MK7UtHIrqso B+//+i`^&cy.n +_`?ĩoʔ<Ɍ/ O6 BJlI## Q Ʊ7K7kKx ϋ~  Ɓ6 @H~yyec$! +/<,_5Ix1t~|ńaG&땐m=PV2:`=W-]vqDd:b|Ǩ~/a*gтAkljC/;X!T=;P 'B୉ϏDE ^g8a O> qxr3ҼAG 99=vP+..ˇ:[d '\AkDi:Bwf޿1ƄRU!:t8bR AO; I[̈́ѩ)Z1KkQK#Y͐UlFV [\GyuWEYgDiɧIE#ҠÂtI"8L~BEkK~w4zX3r ̙Q0rqYV3$~Z!~_!rAH B*dE,gh|Ygɡ JEcL*nD~i+6Vgr|A猽la@ G SOV>|&lN*G2f˱`Vv좪ܬ_nw.(~([Z^W㵥og1,F$rq Cicj>9iC*`Aoǵg\//ozFw|b-4> &\mŅkx)R?W Adpu~_u~&l'ZU) Qx^lY:PA=T<۰S XS1K4T2c̯3 mBhŃMʂyCkx~2~&XJv +K͐ػj+-]}3%7CvK2"v`3.9Y^MJzRźnߒu}T B; .\2!5qrlA0)dҵ~4Ϙ#0O[- ʐ>7Frk.^-A!եk(>X(|!j+fU!ĂOshm^ bCR׫ƢT3! L@:PO(aͮi&*7[Sg}aGFl l~nu8ȆAXD6A`@~޿ѿN H{=q?V?!GR Qd/c䄬 q@~9b|CG_Ri|50I_T|X,hN<d`2 RRDx0o1o:İX/@>6 FA/z 1GY 2l)?϶~-,$kO,jUس?HLXV`/ {եă5WvsJ-<8sv<:_]lIz+\Y JV%FLA^lTAJ}^?xV|O,Nnťh<3le69EF?l{ˀRjxj k|4ڄt+aeI?|[A#էǯmlZHϖBГ׆<"uDNŧc&BV@jxl+Ɉ;Y D{hZ0h'_tA`rUM|JlJ+.C5V\Xpxu$"OA #ej,KywL7Hdo>e*4kP|"}4!̈8 =o]-tKgH'ϕ<(A !LW Vi|k?ۘB'4`8B<(7Kσs뾨f8 vI o*=|SBYlf)T]yܥ m+,mS /&́V&7uZ,SP_7B_ZN:[Nb] @v>k Ϟ?aV]o f֠(81?jT'sk$ʷMo9h${#` TtЗ9QC7#fFfn2H7^YY'c=Wgd ߢUmZ_z_g|]yV +7BjMAqei=(! sTGG8ܮwCZn91Oaj%fֺ9Ig5Y3s> WkIThDn'nwQcp; :7:51niHZNۡ [ei/ὒư0s42fy; ت?',Y~}ywx /@]֧oix+wU|7x|[>f?m^l ɚ=!{k*n4tx46P:@]E,HbHCS}ͼsN$)Xmt58ѐ60c}N$/߻n`Ҍ+$SFbLCH.צLM~چK5O?f@E;Un}[?V~zǟ'(_o`ӇA/k.y\-βh}^Mj*wrQ"t:5hiAb isP2NUB~.|=ƶ$vjEWSM^m:I!k,:zQkTa.keLD!+⍦5=2d]X'q+$\LOLC';YfK@D8FH6qU-1&Tk]qJ%oОt>l"J}#{sй3.= Wᙥ)ɳ5WJc+.N|ҕCGn_eMvʋrޏv $2ƻ XØ9gz-c%&E2܀H 4v]Kf}D^dHtf)( SfɏP:3;VFq']c^eJJvʺI`7m̋B6_풧A9*O#5tGb )/sií}$ql9RNj9_<&@QGz:\a`$`&IGv Ck*Hh+ H#O)}HaT3g, eq/5?j&DmS-ekoEQ¤VjlY=M2gg'XY.ՋB ږ&$ağ9n8?mκ+ND, Y}*@}h8ʲ1(SŜ?;0AJ+۟x#nuvl̪#| <+L=BүMK$ ۏVjjC 2vP)cTL^흶^pv3sWjRp=tP빹{||ҫmoa2JE3dwRN34wyXa7Оygk2Vm(2d{N (-e.B4Q;Hk4҈doE/".8 i|?#/DrYf}0'އ}v=ry{@BKZ\b[5[f>#[/ ]wI1μyg?vUy[`YZ8OpGc_,f =MK(QX["9g \MA󋓪$@} @RVnit i@Z@w>}Na?i4TcN0~)(E(Gh};7 Ua7]yCVdpmsDp_E"agزqpQrs\_y`!) Q]!0İ !z~_lXbjCBsAL@ܠtZ8+ddba&h&Y2 Tޞ93|rE˳"9ʏ/$@a7F bwS,\v@ŅH˯*;%+#cS#9퍏l;ڽar. ;f?"%x-ZZ){.:-[}(l9e>;k6ߍx7u[+9)&h*{Xh(X1BEj?R'qD-$Y`22_N+0m ʇ=%" ~'N{SR[ k4NLH2% [v~eoq\Sw5~ܢp%@dnaR]<#"zڒG*$™>ws ,K $Uv͛Iҏ~~җ ~#v!e_[&ȱjmagf۫&)w2@l!_].R7Ym=!m!RnWq\$٬Fnւ6T}-Fo9ƂSwUd断;RŚX?Y=[恗U(ΠF58*8H,u%cdemZKNc?c8M O˝ter6>Y`˨]Kck /#,5$?~]vUzo%PH +Ygj]򄌁 DtDVBigzz'~ H;8zFGw*3m4MJ=+pu~NtqIJԝ~(35L(G$li#e"~'u pNPOڰ) }0籾Qշ%I^^r۸ eS\1+T/=&3ͽM9V-؞fz/< T:/ A:0j= #b`̯YPpp_/^]N+>rsqWǝ@$*Q!Ґ,w$H ,ġ, %%`bA;0 9(?)  4'EJ!#BAT'`FT s4+;\s^GNlm$} x'SjD| v=y2[=H^#)lPDޓSLoݛyXo& GZD~3By q;`,aI +1<oc QOSPtSn Vjި칓Ogp}򡟤3TN]oqW{zM^$:m~nLB-W[ʤ櫂ߙͱzF7lF5K- ;kѹGe,0*a'9 'پ*W'K 4ܤ+l޳'-1q>037A-T A.&3 _77}X-OHyr00:|v[Y =բ>͋]8fõyuJӦBeƠ?c ن܎`6QvA[ǶL-:La"^r"Z2Hs1JBljٟ蛛1H#+dx#PA42/4_TqMx,I-x$[i5ADfx'Y^qJ0f(d6+"6ZY4&n1_nuKcn~u͒3*f2!A֘C}njodޡ.;2fpLݾ+mb8r2?2wyjϚQ)m@~__s3H`v࠼ ^R&f̿eC؝+ ٩_O'CQV4t8,Đܡ w6a#^mAm3wZJ9CTa:H=5b$;ci@3+Tͭh1B"zʤ-;:  /|Q5r9e8R]p2#r㾥p'Σn?pbMCߏa뾳~|G6~TݹL6 eu? Cc 6{aWެ.#=X6DcNC9GMFq<*EW\ 栗TV~ґq ed*yd4"&zr“Ҫ"AqnS UACx7T'9EiXL}6X>/@9rk#jl 9v`LD! \0$i &qjٕVZiqZ ~{dx{`Dx7{iqйj H;@2 %rh@y0L8y7. -H<,^.$bMw 8rv. +p~Qt٨QGvB^4(iKh8sh$-+ǓycVm6dZZk]eǣɑDD#QFfevoӸDÓE:(ڄ7V ?I3|H `Y!;`ZLDOD,t\w">u#6x(GFihhDҔi  ׹_:d8Mk>fѻ\ip֣w%SܶcPET hnΛKmK|Y| 9Z4p'oӈOLԃ2.5M^m|Ug(& 3 5+Wyqk HъJk{QJÙɜn/f(0lpEDJro]|¼~~*FcwO}:Z@sR>ՙ5WcmzgrjF+*7.eIEo Zk)=%K.#y6Y̘^YJ dZ*Gbx;TZXX_n shkЭ"6툣÷@ `:,Ĝg×G9?sB"ҟf'Ez !-Xhr5|wsf~"0bmzr&f?ņ@[CӖ PyG8yg7H鮕^wChH0Ԍr0݅ 9^=|I͛>Vm)_Q}5`$&ka8`unU'0-qdIRB)FJS Oى$PNeb;Rk]莧,&7M,/Asc+؄XHq,!nd !zu.d~qm}Z>Zkkx^<|l`8r8=LD@|y31O NQ-5rv:|Q vCTLSLuԝW3Z5% Gljb\},0-lye%5ILHY ԗfI<-cVdIs(hR`pʅM5%Wq&_gG`A;[q\W p3]Ű:vZ:)'!_qsG-oOf- g+ϽqskЉ@HLLAf_u!ko$=qxO)[2qC p=?)֘fYC\Ξ(TrZQV ?=Ӂb,Ѹi(s]xqRQVߴ9'#+X@嫬QuP[XMz裯N2*mE*K!;!k`pACn nCɹ~gn~,֬Y XGc$WmF0xsì?/&3TT%5&,VùAbǡ nAo/GwdF)œ9rgӇ(<[Psxh"z9ThⷵF~TYX)Rُ u W6׿sϟg6)ȠaY||ρ (G~z0M>) Y+/v #T՝ ]}9b PN>e<.Pl惲*!ֱ`Ohs CgvD&Փtbymլ*2+4Iy !}DF | }e[Qaj]a`yf6AD 2Сt *.+K*5!D~HCL04/SޚnM˫_֒y$WPfLtp.Ǧu H@KTj:j/Mqۏ :@3K` %$I"2b#h^k`gsm|4ؒ@:; B>L@ir/EVi<9eW$IEmu! (T$#QBDVjTd\ pnbG ǃ y=$`vV1f ` uFS[̊49t)<|~Y+ZojtBww8:ټTIn/׾̟\F:fyn'TCys OvL8mg%#*]U7=ehK1K.qז3@ܩe. %ґn6,-I Ԭ o g cJ; f'S٨dxm G5z[1My$#MI#͔";#qQ(Uk@1ؙP3 h׎qBx0˞CzgMlu/۰I5U }ð/jN<*]q8_}EbB 5f端LXyϱ`ZFD?tH8F&V~>SsP.7WmRAhc ~);Ŷ7"KӯQj3?pZ75+Ъb2[KyhUF :w΅ngnvF2X-{/Up_ {lD i?'IeN%mJZYyĬX=+;w\xpjU~2V3ۆ9hȃ lU_{Tmju+p$'0q p 1?T)tCKX 5x *g(ާx?7{?G} OUy Q:R_C(3T\"?Mq9BgUMEƃ a#lPA)w⿡: $e<)>2CH7"&kMCgYA[ L'_DDhhb;YKr9Pgid Q [LPqD2y V ]suaEQ!I@#O.`RX8>!c8Dt=@A 9}Ŀ{:dZ-_<pW[;ꖦA&2Ac2P'-rRy=+}jć%i-PXZ?[a^?"Ѝ}Yp(.p&vdCg'py*n4ek,3ԇԳ۶D/:(sh5'W$}5%%AԺ$t7H'{olsiC%%,Mi:`\ (.O0KZO1LMtXZ \ ZfO&WŦ]063 N% Z3Z(ș2(PI!]Wx*wmUl%!/ZcZIQG^Us)Xz;][yC=w9OG7&ܐԧ(&.gK~qUE6s8GLI. kW "+푰W+V${1\Fg |3=T"FN{4*~*Mw R Ǯ3 .1[ZռF:,'WUīc/x$vEхi!=|>\S7z2)5x_ a&Մ0~dF6ӾV Ig}UU~P[PCMEr\]^?ǛhSX!>~NW>z>y37>}48E52 t34@…0L^X!,/^R" -dऽE5T-RqGLY,\HgPiJILhzrf@GfPEӋ 9xy$^ÄAuQD$Q, j@2e&׍ޅY(dfgɘ\ijr` W3BeiׂZWJU. 5 㮝 ԨyccU]VM3/,|?Nf؜ h)3"ӕs;w~([EQh}T~r5i1]8FI5N~EYoĬ4^|{!⼈e]].a1dLʷ5X 7(&.ڶikgE4eO&!\K$ZFD|,A~LD.N?P8)aÝw}`L5`i֪iwhPa %U3R5 ̕RHw8*zWHm'!!mKe?o?bp/d~g|WG3(#i%si9_5:5|$*#D^>#qX݅ן9?Ëw5FȎb4w8)G#L|Bd2qi%2@i 0aw6n6#lrXN͗w+a#gKW]mχj@Yv=@eE@ (Ch4^F!+ڼER"jeK6܄FE8uj'2SarWK1XxPV+<)Ba?f'6=H0P*&2+=aϴ-g#A:jfk3>rukT( +ăPZ VR![{(-aYR1lV⿗`[IXs ݨC6+-\bFkTYQmQ݁}4TB}]D5Qt_'e⒱[Ɵw{ɳr<ׇx GfLӇ Ѳ_:/F J{RN|8 f :w5w{"*R~a] o>]n+8ǟYʻs$;!?-ׁT$?+` $(/" Q.3Pvl啼Ҟ';:"|@/¸;Im|k2ZgZ2<6Ԧ?ajJKC̀:^y,ԍ߀yi6zeF >r9.GׯWi+?Pyޮ tW>A9zzn$8g`{_&b6x1!hr5#*ZrõDBF";m􊷯tw;1}`8Ҷ/-3b "Gd,J[{ϵ +m(Q$X^} oϫX juU!t-$V!L3JYϽkH7ш|b!!NbeDnNj6V^xWZwJJFX.^|:Sܬ=u> 5Cשy"60(8B sb] q6EϚSA6{EՉ {ryz  WyC@e=ti Ê rh!8VƗEV^tZH/ *2 Q*8i!TbwB zH2|)AV+{鱛.(@jjw]R–l=Q5 W^4YEKjgw4,E׹[G=gx,u0C.*5nm?d^myϼY(K:D?t !NZU͐ bJ%D%NJ %H@س8HwL-z_do.kUL\Ff~=V3+M\Ћ3i-[ʾt0'Ҫ5q“qJa B=OR7)A Mx-Xx'?ҹi磥|^l߷.kF%^%ߨ b>Cb7<ʚh`UdR}mF dxRϵJ{"xs{;p{dZT׉t4F CGW2}oߢF'1'9|^*[q>/ T03>\Ӷ l ]yjٴZBLtFV"$6iӨ' C"W6(dHKY#zMa ӲDxDU{ѝ}͓FZLw E]?:n>dWۿg 9Ť.ZPKx\PPf!"X~klEt9o VU[RƜ?8dՕ eKlL"'_D}-? #p}Il7. h j/>XxL| YMl&b Z2`\} 7/,Uc?G3홒? T{ _w6@n&cV i/WVؼ!%~Ezmlȸ;!TV>ِP[,G$~뿩9ؿ&hBų4{@T@|Z{ןK\Ш]C&qlγ\ `@ߠ`C-P3^~*0: VY: xYf8CSOO}k:4M C t2 T +ڡr<Sn8OɀK\\2 2!J u ~TD%rC?; B߰"SR߈6h>5.T= _i5(2:Ž*]+!ܞ@̳r*?_3B3$ AD?pE'</%<80\"reB;^q!*vٲO ={[0P du}\LP^1dt_3s^/?Y,-S2գOiT5J8/hns?n#޹$WA!K:0|n[ɯQh[Lއ% SG/TAvo6H~Sǝ,?¤e2Uj8" + )+HVݓ\-*2MW tdS2N-h|RHpUQ+_ _M@3!\ʷvw^ v!MX*_ݥBmCKX]ҿ7M5$m*H!wȡ~v?_ʣCjY o{&&ZMf?H?Jnjx,G;J#7;n){uxofy-Y+ԘI/0ɿ|Tkz47|_mbѶLZN5Ci,[TR9߯:匳r|_}:z6-;#Fwzwjp&^8KF͌3ҧА52~得|Wd8+bb(̀FVԏ?!D"2AcLW0 JYh5eT!8s^vN(a_MyUScoĥYaɅ0ZӭTS-^Ȑg Mc8L cW::H^/V8{Cϊ9q?^r^{' KN1O%Mk~ڥ%olg7 2Č{TҎNsY,8?xiL{[O0_^O+u},UNZ.J^L.\42%oU.z(+'ꆏ[c;4IXb  )<@C@LR8;U7- ?6D$zH _㸹˦xqu!,""vZiJVxNhK)Cq[=SFQ 7VضrTf<-qp4lp'OS[E$*7`gOpT*QCRWjDL)ҐjB= O-Nba`N.E9 "m8 VdҸU)Q,*W29Nԩ :OT[HV!:qա<9ǼtUPgvt:~Y| !a߶^P aq2ͭuDCr|,ދ;S-Fc cd*!7 ~ i95:*HJ=KPR=xMOD=lޛ }cLv{m8"]i ERq^_5*9<8+O=~,}[j]L^Zja`#B> J mtHEon kAsx+t|Ih>=۟e)}l5'7nud(y%_+ ~P:s3p~kN,}_VTTjVMԜNL/q>@+ҡy͗X3袶jwttch&ta{dZIKHwc^6w46vA.Wߋ _jm{_*M6s-:N ( ʼEpCHy~Âk 67g ;9ЦOG\h*8s-=wJBsN}dUs&˛`B@XoKE|#hSyn0Gy.D>X C s`㴚0 Eab$ y1؋tW* ϏmfiK28n)s'sX?.*(5q@댅AO2NQ&Ѧz!d#O3&R*&̡h1M׀ΐѓ5Ke7=Nv6$x9#{us on{T8_1%:S]/ n,0RTV=wҷ8\\!c 9 :-ȝay(К\رƛ2ӹt_4^eϊϡأf?>'`^J2Dh46bD]Kݿ7JYm0p*qG8|UJ 5'YP[C t@~9֨2&32tM)3rqT\` SzbKOyOdgBh\0 T)XK?HE AV+265Vd9ȸ/B -o8NDߙ y* [r]lFdrZ웻tSUmj,UK1} ?! SUH0HpbdK2.*ǀUL%,ri82Klk۔U+&5nՉ,8J(i]J7Nv?zʀ{{~4c߭Ɯ=&#sEp=KyG8@'^bBwÆΧ9Iu8!C@T4K Boςέ 2vpVelfqƬ2d hGѐbe'g~oHxSt}ެά\ZeofT-,}O%[ P棫@œѼJ>?]{m{F~}ؒ7,YV6Z^/@l R1G6$^ZjfƬJ2[ "b?4R>x@T8=qGo(28(P{ZtmSZLt5+xgnv !_4g<j0e)edɎ"^{Rs?`[M !,!flVUS.B0yӄ"*yotiI&X Q `qLwZ3MNKPl¶ ShB)Z< D jl>@"`PA߄s {[wC615~u ;-go4P\X5,w2}nD(Cpb@۟A*U߼lrpnK{y l5 \ԉ)e>-;%K5MC>'8{:[0qE9~-V ,# ~hkc~q>`aCyߢ?Vfr,o59VAjM3&W!5'!Jp(dLȵ1}FVg ?=W(`[<(/V>}C{7=E(Ok.>gS* u Uq +j9oͼ_0<{KѠm'jg9}&S*b}̍jF0Uϲ`|ۏ`7ihVz9DpVnf+NiB*X)K&lQ%fH+J!N٦rwrE l`|ߙzMY8"wO[ן/˜PW72n#huytv2K!W0<̭ x_Sݍ/P_{#H$HaAP`ã>ԚpsL\js8Aor6.NZ-Gqd`>7ehkd98'7R +G??Hv u6s:AEN#(΀losCr* SFRh1<Í*ުIL!a1՗"v_}#_@.w 7 \ޗVk-L;%yyb u.j )>1tݨ1ZIHNP Vtg߰1GM_yQQV."h5Q>7b~} J Ѽz~+ MX3MzD|Nrovc'P#7d=Tx.?au>> x>~"@~0:/ Jr!xx@Sx@@~.0X O<Ix@0?i/-ϽpP_( uA I@|1>8Bበς.p%Y?:!YHO{qϖL$:"B,Sܿ$!粍j!xǬahvRg_pLJUuI|l8J syA4<#aօ]N};XI/Ffp\ta J1b |4%QڟT67ň wďNK|4fqb[XgQ K(/mk͗OFpz[%tq#~sSV`^`9I=0wO=eKtЩbb sOLCRqGxC sf4ۉ95h0I]m/`cM=o>!; VO! *MB IJR/֩gұZQ DZd8@]]e'̉DxN)0,{[ra1 = 6&:H0Ks.0ՒZg;B= O'cz϶vCL :Їȸq䀤O1ɓ`_5 @& 庯efیJlR~u"к1s{R{蛍6V2/. n*42k%EƒFHlFzSM#%Pf_0)q)OAFJۓ^.J[z|SSy7*e8)bśt(I5AJxn,a̮bYsƚ:Ш]" 1'K^Ɨg/%%!v*ax;;tיGhg9^%#V#M ,fn$Jf7DѨk !(.-S]CȼЭ=}<_㨛mA$C5L{(R ]l13XM8MJ-((مLfŊXn$Fb&5>=4+2vMA+w|;݀$m[<&_ͬ3mSymzla|Xi}>B9zױxX׿FԖvjBĪjko!{H+tzffPTWV6X0gq቟k3}6?#tzXq)ygS2"|Τ>^IɇTec b}ρh^ÒYsc7NB͌5BEȆprXd/lٰȶ2TEWh8kG_R,+a(_sw.";9 у1ʡZ-Ls$3|Kܯp>!=aRc|Nn/`@H8fT횀("b qG@ wQk$PV~B!sM좩{`/R'#Τ9mM^t"H 跙a`SX +& 8XG.8r,ıR(O.zs#Ha'݄sCMtԄZuf2gdB |D$sP 2BW;~e<шubl! 2agib7uJ2!=n.M)cw\3pIڃ*.L=k}efk_4triξEJRDe'gQ|h.,T\_4/,߳+AR(@ Mxƿp.~.g(GFP1`>K8k.Va1'('&;f,!d%}K{ώ2$JLR k ^W+SeڍtאAbHOÃ꩷ٜ3n:JM@%7ƍVYꋡzg*X7k܎[ KbV {bF6hԪ^_ N0o˥h )׋rŜO ]SjGcۈy pFVxĩxƍ4U?A*%=tRU$\Q9xC93Eط]5M-'`,3UP&l@ DC*ws^Mx`m1>O̺Q 1N+g'bhPzˮcj,]B׊ud ]= Z6P~z+c+&lHUBVxMt%B.i-?0-̓ xhH1Qd /?"1U 擄7ȗ ̟DWD| cהo^LjTo|0+Q@D~wsj@FX$%F\3ՒyQj% 7LkO.ܧəOfͧX qN<DDߘc쥓sRƚU}N8*|wCRNo-aa&R!wGS6($F+d= %W=6dӦEi ȊJYͱ#ZszL MQ—KzHb6>'n.}\>ۘo$Œ2Ưw2f www[pwwwe $=߸czUWwתYO?sNƛ}-343߀/Opt:|l:|-x*/-~$ݯ9y /V,'oo*(P'>\à2…Xby pp_^hҾO2W^vV ZPSWBZ~|`gdP9' Hv |J;UcGމG+_$:v@$/'3.GJN,t6H&`Xa_ F44EeTE_u'  e?0-ɵnS<(`sҫQMP#& ?Sk? Pey+Rj1@6>eT {):;oW}3 gT^dΌ/2h}Ȍb#آ 2,6Tr>5_hIgmւ(cRMIyn|>hd2Kk\~0 pYi ä&f~sx`ح~ύmюpj%.sʛ w>vZICh[8NcLi2+N3Wo(b:N?R<ͅr,f锂T,|`j'(C(O#i_S.AHK` Qqwʏ$ư(H]% 0Alg?"L}rl3)2WKRÖWEܠ;ifC6\AB9壣o ͷ"X-Ju h!=؃L v> Z V{F _V_*BAɀX,Ư^<"utCd )3$ ]x!R>Xw¢yG؅iie;\0w R9UW ڙ=#8}u!&~ CFaU zr;;Y|hqw<>ݹ|xߎqEUQ@;S u5^N(mtP(}Kriz g+% fOs7FH_70`" $BɁyXPܜs2u=W6Fz]f/{6x.'O| IH`fڑy7i$Yh豈)jwe|f'OqJIuTi{*غ(*M%.vmN.Jr܋;*[wjWh9=vg٢sccP֘q7-o܂JTFM/_PX6-4`?< BA L--"`tV)ˢ~>a<,FŤY͈ז'DoZt0UHffR}ff&CÕ v'U"lsތߎ* &{A H#1 ֧hRݕ{x3ΥhV߃=\JhV7 KIU܃t;:9ͣ;6 -( f_.Oʮص ?AЋLPf('[$;tD['c o,=9fījLa30^0kOrpg%pʠ&"\KTo%a:JΗV>HފDDy|.$XLwiH IKsDY7ɡ;g$&h8w钑]@zGts|Um#\?>Uqy D};=&cm\d%A3=x.S_L"~Ⴒ\ ]/w^δE6ѨTϩA oLȋàNK8f LmK=I%LHܡƉ#rvߤrlPKs^Vt. lcz 5r**D+"-Ubd/p nC^4&l[Jv/0Ov/I[`)_$FNĖ;\mtJI6Y.@&dH  AE ;Er4\uo?08,:n=yDt{|/ iݍ=_ qe@f~hc3)0L<$UO}u=}v%`y־G.Z]B*ڂP! ڜM1u##8:|bQm!utސڤ!^w0G*LTeGFY,.ʠ5vo :d72'ob ]Àvigbae>/t-Y]{=SCvȣ?dBJ5(ꚎV9@xgB%G4$h1'WZy={'uπ p,ƅZqA(Ʒ#/Um=NbUKPμ^ɡ^LB)"%Sد-+# HŞdbO7UM@uﳠm0ݨO5+7QffMJGj&=ĕ8VJȾkI[—әeH'vCjw4.͵w Yp25p. cߒ||,\mB #_  V :7jwA;A^*K$Ccpi+PF=&ay :]$:mqgP)X7"ˆ'eUDI o/:~6 W٤@Hfc7|) {գ闏M`p!] jB)Tnˣfͳoi7 ;:ÒQ tp;;=Kcܝvggmt>Z`M 8Qli2H2G-aĪW sa$z'Ƨ=^j)C4Ue&-Cp%?vKpr.x+UBu < BY24aq`)$Vȓ wim咬]-$;FHG^(;X㙋o< |*2a֯ ã_ܯA V ꃥl u׉R 4G`_w9 oxkkT0wW{ca _np}X_ @у?@c]`#&zhg@Wr`TulNO%^*p]7 )QJ^ךE߶:zJe.Q\H$O>Jdm\zzM}f;LbBo[UwGg@MH4(4 }owNVAm0í'*IKka0~#G ^4@^DQ>Ҧc=eAdmT˘g?%wVٶҽOpC=WrUsڢSu*ev#1 }B ӕjO@Һ .k3($zg4̰gyFN➕敵j|sH2xѯ |wG7"]"l6]+A-AGǵ#قuuE;QV,̫cs =S׌R: }{aRxW~05lf4ΞhŸd8&]9<'HMM A0ɡ e,{ԝsK)JYib7HZ5>fk \N LJn^.{,n7 _c#\_nI]_xAT:<1,:ePc>50pSh|rab&m7SڤkHW0W?(K# ˡTr]h%ֿ -}H&'EZX`sMHiAoz$  Oy~wOݐk8}e'YAg놡L9U(lN]^TwU9=sTRGo=!{/߫'_X>KijZ^}(Aj T7;PhEE-/Q ">uQy p\-]ۅm#߅AX^20 5\$\jC|G6indVaBʄ.TRm=~9Z>ގ@.)LbߟV7zj~W /x3t#`Ҙ#_c)A`oi,TcB!6ec8g#Ȝu Mh~'D)$Es4T jA6ѻr됧#i뵴R³oOH2S|*M6wd#fKQǓSK})6w}4Iƣ:n CO(9=/dk7/oCr&X*7<kKA|@&S9 t"QF>uLp 9$&4?``XB.s no;D )6DuJv ~XǎYP]yۛ!gCo^*}c \WU6CLa7'yW. lxsx j'U7Lb6OM;81iݩas0IJx30@nU]9tlt8SRmҟ{"\. wUTᶟs*yĴ|엸VWZJ/]ҽsvBfWlM\{ mhJ=jA|ը߮VTjYʐX"RFr9nND!DnRM 7_4oṕ/nu/fgdy M}I?&aq22{2Ȩ\2d nkTp`ze^x } "fDGBӫ8oVBL'ѳC "S W.)% ,̒ 1Ȳxܼ c!gXƀ2^3= %[,%(nien&݀8v;~eZʹ%d g0m-Xt]Uݞgԏ7~ʡp=jpܪOTM'x1r+Xk9!0ԘX'P(η,ًQ @ֱ}*мPHTmBDMo(4;`K\dp#xܧS.pqP)iݠ?Z>f+૬<6?SG3,NLL,^@zJYGT|mዽIbpstthӉA$h^t%/CϘm&I+2rl'[n'^>7\:*6|'pPR޲xe4z :/1H9 l$ܱQqk} ;- 5Y^bp94E耚RꮬтD6.~u@94#z-\#b_E(ð0 قꣁ)H4NY MV[jcbHKH!w] 8 ֽ܇-TeB{F@ow.Y hZ!s׾yՓHqbW ]}(УcĻu*x dݲCXt D$KdXh,k;An ytL\mݽlHkY|vBx{oG_)a^vsL?̶?| 0hDbu@V{FO}ʹEȭzj-.uwL/p lE=!ltg 2 /YU Zbg_,^6 ?pHZHs[#N.H^tKHQ lz>|)=ۆgJZz'C0hw1Vͯ8Ў=#s^bLcOѸ'2|4Ί*/|x}[`sSRPyiXf;2@Ax߂cQel?CHMfɃ%aո༉s1Hђp.a?pꉗXuphdǟǿ 1q 1aw)$VLkA{H|t, 8 o?8,[x1Jo& <"́pq)ސtFBSP=Yer9REJKFvMxjI0+Ik~-ȣ)9u)c^W +)#wqK{boowxAorQԾ#;=oHjp|^QWP{XԔOR]FWCOcZvO hW9lt8Mhp#QԵw,?BEsE{-֔1Q6yG%$y 4VvP395ƥ&l~*γ- 7+q M,`RJW_L{yRs=}~u{gi)ٴ2`oLئDxE|E=5# lp XRf:Ҝ%=*~j vJYw@=#"Vhp9h!K 6f}V}n3-%|8vMi$\EQu/E̔m]cՉx; .X%+p^nS]M1Ҡnn'RT* <Í*T0M<y܄{%m[rz` kY(]Tԯ{k9,It.x}ISh#bNm6n>Sˣeh6fs<4(ttSE9O˛W, 5Lc s#rv+֖ |X4/CB#j#q'tkdU1irkdzi |`c yUɶz&u}i1gR"z{*<)v={Hr{[^|E^Kbsg # >^WUU܇`]K Oeyt~"TٯA 望Pj\|BB5SK ,o[6fַ2Z$DXRnH\El;N EmtDn Ts Nˬc .z噯{/Bd,nG ?ΐw)6h SD+`nUSғu-pj7q<^Y7wN85̏lk8E/rNpBX:~ǀunrMB\gui~STw>qӉ=`g vfo^-TՁF0G/j{/KTLpCwkDX6N}|aWC:/!ug238Cvv?;eceTD:~?ݼd-e0 Ƥ1")򝨢ig Z/uPHdqmRXHCbpn+G|ĹH>x$ywucDy%azl>b@ g3JU&U--;@TS0r= p+xiz& `j'6&c"_y-聬l֨_H1V\b늁6pK.,v˃%RG˗_ ]h,Hn%@puC܂ ѳ/Ӕ~E*Y!d#GÀր{Q*SnzեƏa)cƛ™e3- oǰZ[;!qT8mҨ)t4pIT#zRM sl 1+ r+12 "|h.I4d7z3o';hRFCCCG\(F16}^C;ۗ~TAB\A"Afo$fO^ fڞ~t h9BFEt̸t~O GqQܨVe|y 23Rw5Xrz@e^e4G%T9N|6-|Eau~l.ɉ?IcYqi>`kcy)ڣ '#3z#E/If=˙AiXSRs G;)+AHcZZڪxs!cz }D߼QD_0=F|Հ%}Xn7V, fSLfVֶK`Eɦ`ngXGfX'@)1js>BMeA+׃[D koΜ̝fE>!!h܏Ci\)X)'h}h*&,NjBnyZTgD}FP aAyٷ]:™<?2{>]z^|;igUx4y1FucM-au˜a#S j-4dq  i&W 5&6o8ʪy#Èb@i+=CxIRq/O1ͪ`ۭ}^ogBRB$I}d<9<j .72 z [!1^8z@^ؾH \q}Kb#~=u7o-?%YՌy^jQyhI} !5\:&+2_݄҇:SS-dX\ ݙ)PR"CR ~v&zqh/'B-4yi9]U|H`T gF4f'aIr*/TJ\J89)S[| ~v6G8199ǁL]T~WS{p1w ^7n׶;~u/ݘ_-s`h?[}L-W'\)^/%O ̿:W bN5hů6#oTIjέ~ FCIͫLb[_Cr]& X+UiHM,$0]JN jY=gz9Tޘrl%S"8˃Ըjvd"IL>7!^Vt,ۗ8:'hV)dCOTS4,wJv$RZ%\gaʹ1+ɏbʌqm`s;)Ph5e8֥Ki*NWq(I#f5>1Jq(=+ ':W5;h~ &> OޥJ[RI%4H3 G=k-dٸFrV{_mU}cBA_VP™z]%k;uiR}veA]w(Y;wfY3'Nip(:1kэdk_l,1ϩNãM*A<)ӖLӜA^Yeii7xT(T3Q9 i\?\9i9()YcLաLl@{ɇ7*it-Sl^%tM1u)u-Sc=ἫE &H%j}/]]j'a!>8Nm7fY;#Poӥ5ίZ '=~귐]8}pYY-!S ]  S"R k߹ Vj<:RY V L*vpI-) 0L˟DRPB- `hcQADŒC-ͣ(U @\(ڮgDm[O?'/Η˵Ҭ@bW [5T7 UW4 m4pI9T|{ Fhyfϣ+32n)7 lgo=Sq]ve{.w/JyvY٤';1]D &? /F6dW/4ww" x cHA7b`sph1 ڔ؄ ,iS $ 4G@wGhe=d91sM\ÎiBNhl]/U^}Ow}NRvTyɰ)y.|魍m nX} RDdp`ז 7~ 5qYį`]xp|6VIqi)#p[6f$eަ{H|@sK>ԉ?l7 @xjO\mZʊS^އMZ/&rAT+=-*Ǚ(?pw􌐏5E p1Du2Ud+I?IU;mn9zI_2 j:p9ާq [ZxVgk#:47~\7ͧϼir額`!ǗFaP)}VOMCRC9wa/NIb>M毃@F,/XW"$ ,M'0+IJ=FӋ-NYtD:B}V)}x/0}n3)ϊMά=-5KA ‡Tcq5@s5A R|qx zwZ`N` h5W,j xpЁwd/1ʐ`f K68!/C+3kUjwB%^`,b{3p ˵l)%]K~d*#YD*9MkFd#"2=&yb=EX;Y}@se[!]5U> >Iblx}5E1f{/n>W 4|S/bxRXHq(asqwq.NjPĠ@_[_%噀ȿ3x9 1Wx~0@+'/SҝP oRFa9O:|#>֖ZXHctN@!EBX) si4n[lȃ;ȭs7sl/ NlgJHܶUmeHszck?1*6S2#ۤr|WGdMrي z Ohϛ)x äݖ O!|&2"PQ@X8,Jӧ#t綇j;˜ ]\#WNf%bbw9\,(NϨƝZ1%S;q/6J0 7j=zGAQTgQ{PNf \ɕgd0wMIViK TWa%iCc&Jmؠ"{[DT9KW]o(!r#Пw;oCgL>>@TUT 9ʯL :Q-+>R!\!h+4bם<ߜy4h nҤ5q93[k@"o<JD`y݊d|cnOw9fpTj$Bɩ;ny#sԀ b *PRl|M.9J /vc۶-шccN}u3%mj/ 8|SCZ9Vl>O$40U=frvDX{8fm-nCLpK`p@ AC5_׫t^ZT[~DӬwpS#,7Z#|ydx1:Ɩ=ķ\Zf;`fOsk\ZzkGnUf*ŹEfR^e x_3*^*鑨ErVC6$kc9N8Cz2 {J+8ۻޕ7[|V)z槗[}y~9s?yn5}j3v ֱ݆A=,gltel?3yf0 _Kd(]y F߮ !H[8q@>n?#dڏ'{8#!N4) b y(`p /7] @_(Fk3HbH^|/ZK״v|yјW\w\|~͑t)/u2_&,M)EAFhp9#1%^SRg3`I>|OA8Vo+6-x L5d΅v(aT'Kk4;قs%餶wOVЇ>ny`v8Zy Mӑқԑįv{t,_<ӳ9ݧ:&5A]oG,I8}Mu"'q!YM*3 @37t>5ܹ͉y\b7Bbhka|KoS(cߵ*ʭ$T P~xbP։L"֗F[W2VRwY0:Tlq6\d%۪.RI)ȾۂK7eyB gD,lvuLCq2[N~:.MprܤBz{>jv-Ty\`"vFӠF;G771Hn%qIϴIBYń06E.qAmM%U3(*\Ӻ| 2gc^eAN]ܧ 6$j1k=i -ҏ4,e(P0[6FS>F^Mb J /Nj R +UPfٿvRf菖4IExwk9rk?@8UP 2&EL-r~@$ VqꚹU"JTL &m@ VylO:Y U` UNc`G)zV~l;&2\'^6s'jDe_2xɼmd{Z}[ajz6{(+ s60ovGƀ <۟W+kA'JOe: Ð&cc8b4 ǂ:xv Z2Lvz@S&oI~\Ƌ=+>8@=)#C_'>CFDiU72vDW2xj8o3]k|C2'Yd?psL8.b7bU|ΠTתfV'}>49G >8wFr`uRm_[R;zg<'S$ɋ)8ɸA>p7QS=%|X~m0yYƖQ2i zdh*N#Pt 6/w悸'^005s)/@CiYd5P2YuliȩWw0'`)py0?`'W;\w_X*/f!d ?(BW /E(!&p#6J>C8pL:#xh`C.`cb ɃYApV=N@}䪄ڡigppT"^]"qã$L >4.O ߗe<} ;&E?CʧE @L.i1AkCrs&.kYƧʍ8%ݯi< V„5"qG #^{LD>[WlEP>AL&lbxz>h ױ=j|/pZک|GC 8見6Zl[ݹ=IBcӡٓq!j7;ѵF,__.[/qc8d 3$nMߦRsHʹ}WĠ(VwAޘ2,:WPjU._͙f.Uג؁].h ĊH2f͓qJHA-rCBt:LJV J7ꀘǢ{`Z[eI >sc˵dĻgTm.|e*}>IA}g`y>7 i_^Qɜ:+|ٍE_16B]miF {LbN(|γY>,7!U#GK'* ϸA wd-[s6x_[{ ])#ULV6rM(4wXTm-ŸI `J<1wZH@BHc{]oIʃN@Hpf9N;ѐG84v-;ߕ6_p>@<%P)=Zu!z,wH<2Pw@F- $`08Eԇӌxhrs@Dm e0HO|lF3Wο>1t]CD hh):ft`,8mhُOW#9n {AR (aN % +"{lC 6g'{C @+/#i/cy"V}wEW50I!a0,h_hDq.P$|XάPEzaI$bLUp6 da-` $jɿh> &)r(OK" ׀xi?h ӿ,kNh?޻yMcD_swSYQ[//9?m3q^Ui}}QW}Čq`ȑ+pI>7)T'='P!X#H*)ˑgÉ6}HA~OXd 'zuZ 9U4{GG?S(,n-';Ti;q!Ӣsk20"2lY(ޱڴM=80|cux ,^'aY_lF yDX$4^-KNջŋPkں^9J/sU3Hh^Y;ksa7R[Z4(ᡷ+^3J̳3ݡ q u>hq5}2z3h#o OJwB-(+W)~..۲NlV9ܗ-fZxF6 (ϧ'Vk^_8F ߔ 5#M섚 H\#\|l=#.LJgYr3#35d9)SCzbo}Z6r)@X-WXh"u .VNh-W"Xl#81ɮeZ̟~+-?}~ʋ- F q$ Р +ء|+$ή8D#l[L(0!O D=[haxa&}q$D:t J(.{,65@20 J;Uͣ%jٽ@o0WT y Gl&doJ3:IARa)XIZ1&l`$Ϛ uI)gl?UJ C(tszh!9>mۡ;/%b<4F% g@F;=)%d}&_-E{]ף O h &! Oɢè>Ӌ{K .=W`=o0+tճ0 ceTxi:FUcUyg<%z&KljNnO9M*V4>knSΓ4:BkM!}5cGvyF|քH`IlqxL@jxYG2W߫_K%+?`/OD dj t 2Q#_X3a: ~󮙈^GTmE-ѢfMޡlYlaՋowI="?+7x{ ^$P k4on.A| g,ih@1K2;jjU!I<@sAg/@.|wtkg8K*-kO9zu1Rr΃ 'NK\ǼҎQ| nYY4'Vmڞ (CkelWU:254;b!뉳` ;>mx_>85nD)ZȈx[;z a^ȭ!hxaӄ|"C/BI@(K0U#3Pj=LƤ[ W!ȓfj (}8 J 9S"I>(_cKqN0ݒl-َ;́UimA]k!B*c'!^Z^FpMڼ (F!GV.0>=A6|0bujYU9kԽ Ik *RT/R;8fQm6NV:hXGcYM\ )&ƍ!f6pmxms&&6_p" /۶#ҀѤ9&K,3ocho9H>4xzAQ,sͣyYFLb"ܯ9RRqѫb".$Ip;c}%cֆȖ2|vpD}-\Dq|ʨ6pF<4˦ "E *VVC692cYy]n]ˢO-n8QL5*jEKSOUZs 0 iZ3Fz(,ՔazjMg'/?Wc͛h?ÄLK|׽X7F!OQLh"Zҡk7K -ioQPDC>q$TF/bqkB#o!2hmok9۹78Ï?jQolhjd}H>ko>XktSj \iAm_g .yxkUn*=M>-`BRi|ORkX\luvڄ8Ż[^8HBh8(RQ> 0o;NlʾIt~) g~J+lilY:U .Yzfp˳$juB)_((>?) 4T ;NIƕ~GqUdD'Xz&^:)n@<;Zk=٬w'%, >Wݿ%]Pm~ފ޿ڀ4Fj?A&!>Q=[ģBd>?fs'\NOs?&@;*k=iA#A!a + VkvAo$[XüŻ7Y5Aߡv*xJ5ȁ:d;ZAL8n4qp;rq @,=#SR`2+s%>7 >{O難^gð!Fa_- b HLpX#jEƌ Dknm'ChxzcS *JEtmp30K@x# L;8K!2[c!OwJ!3d'i. M$Sv3^u!aZ_ŰδtؕL!j{q6`/Ջ7aiڐ|>-8qVxv1Tzӻ˪]ժT1Oَ7-hǧ͹8gIu>!B2R}tJ;0DkF#hLAS-KEuSi8z<7hJO֏S7[ sn_suY A/&%)j|LKɋZY޵0z *k[k%;C-LhBg{Rڃ%&$F$Vwt)tv ?2ע1C4&Br 2pMuQ MY,f0փ)1W>(B*vŐ=(ՀhS)M#0eH~fw͛Y5ۃ>I6)K *Ӟ>}ld^U$qPnrƐG.e-t\:ݨGuo$Fz=ɦU2 BiNVqg~ \0 +D;f*xcdK,N8<w19z3:sI%Cqh0͊Fj&c;?PeK`SXW.}7_a;I ͊ ATm;c>mIWt1\(Y+BHx2wFQ7px9R&=f-h?Lv8)uZ:H,SqCq.J?퟈בkNUN`<>CRK ceXqD́U0=t}+p4q $2ݷ-L͹0}= 6D@rε'kț^VuUL!q"'>${m VzCDP3K( 8 U^@D²-`pK7 MEt9$V x{H(?xa [`ETbߺN2J3w 9%tY.%y+W>6dy'Ü|ϛgig&AT)y|֡ϑڔ_ח,TBuFCOu;O;3WS1f{zF8Ԧ߳ǘaExXB0ŸݿW Yh3,FVdLəFj?*} Ġ{W{9C}eyZ=:^j(#b+IjQ/bpsEqPAaIJ]oq('F{_1n=f,iwv̘B )Zׁ+ _3>^6׷Oc$ĝpU9?ɥbēۢ0[X޴"y޵ɋEwvjhq @ZǭϥVgNU,yB'+#8"θnpva#ER:hP9e5JlNR\s^f"u52cg^8hIR^3Xd+DiDأDHx0cga[ k~1κ&{ԜEJ|?pu8!0,d N!j?_@v' A*AX@݅Y d;ԓPwg"F.CG8#9H> %`dq @'rBtRO甁ϜUALH#?יJŸ<Հ'/R 0ur{Ytb<5!@Ge?*Bx2DNib[p >9u܊ZZdM|Ju4o \LO6}9}*o TwT#;2)ø^zޤi6V *iuŅVUv8t Yu$W\^b`p꯲:SI p^oh`u@ᐤ rRHE,I}Ljd=a=EuVK'hkMo`%845>@aQJŒڮgOG%\2^᝶d%n_]P-Ȃ87@Anj>rWqZVDH,<>@j@zE,& %,` ) _ Vl 7=/V6Cv|NL ɛ:_+#|>Oj@>bpc DWMT(b/2{ gL̛5ÿJ_K]p 99V{e )-#|bvGJJmDæ}E=ྛI;-pFǸ =ӊ^{y,Z "37\X/T&Zoc+Fvбj J;YWu.gtx_DU1Bܸ1EFڛJ$_$|(lߜ.hk;ru:k1CU2(cbvBslbay*alUejk#.?gT+~]1h!d|W|u}sPӛқ{Fz^F[D"׃c΁z<$<,bvHX_9dchIӭb<]C ֺ˔/ݘb{E:UyIYpk~s+6kEځ ^U\ݞ؄N=F:<]wߥL5E6X$g/l`s1+KY< ,u]W3!R:pueܤ"%Y‹+1KO t΍ tig%% P L n⓿@/㴰NUwE}`n'O%ۜK8O삅yH @5Bb6yqaEVof 3e47fݤ,+X E~if'!Kdc?dHX7.(pfJ;q`HQ!辰N$6ʀ; tQK}xwkRxSc)):i֭6`:nö|hsq/rw?ڣmgD,auxrhIyt!t* ;E¡ޮP.*_d `1l@6kDWm/AŨ0a,.w6Csͬ*dVψދ\/HR@ýW};Id)7|o]}mAR$no@ЭZLk&!n) ހԑCNL4ֻ:I>Iy߷bH1 m}Ɲs$w9|W͎Úhm.)F[gRZ"436* BH}`@dnvGnmqDgGwCR B7п_yS䀩ޚȿo cRRB2jf_'{6/J;i/=GU"R{>A5fHjv?B /yeR_d&jGeMQ0-KQ5t5QHEJˈVoOVE!ZR1#£r;sd/3]^囀~(kg.ÝBǢJ}qRnQruDhCYjap|'G ``Uշ~[`7SPSK|!o7V#` nD4u0c*Nڝv?$IWIYDuDB^&KoUђȚ.df=.9PRZtӱ2WAIDշm Ed sZ*Ѩ7W؛xQ6Ȣ<S3M-I7#TXXgEK(UX\ֻ͒/2$~xKST+j\OnYhqɾqIKv!C3l@e8RZ0d6ᆪ'bAKKH8,#WuX| wE飕8==ўE}Lb+:c42F: ':чJ?ߡ׀9Be~1'c}zKkY9o2ФRU8]C->$ 6_#; ̪f4ORP8R^;+]&ǴEw`IdyԪB!xZYd)"$Dg%r7nĽqjq>)$/CPrƳɖaCSp_ba2 G+ wdJozǻMswsJHle"ԏ2 Α/%C|/ȠZAKsN,F2 _F$&rT+9W~KKlmA)}ZQg.Œ|HY\>7)5. Mɧ/UX*+^񍁧ň^,W+Ok:P:{+iV~aN6Zy]0'KRDf{zu!kި1׶k*ݕt5q_í/~ktsz0w͢"t}'??.>iɣ?~QBsN4aH]߆38z.$I*+L#cVke[O (ěTBd<s7f`37}/О,Oo<`_jak:p kӠ-ɑxM4Tǿ>vPdZrdk#Gd3 Kdfx]vp'3l`F8ZO|5S{Ȩ#mk.QTtF3ftKM%Jf>KQ4ƻ?ij %!k;i^Mѵr޷W r_x"{+uRh,c׻ә\}u_Zњ}boe[Hv;"Fmyz"K,ks<9e7?wqK^S1e{|GܫQcv9g/}2ux[q?/ugHvjYv*eQvZW y)(TE0i_bkf %z"LN<7qZIf?o U.Ox'\|b\*y4h3u0&u!YB"0%YyQ lp9Aʖ"2PIzTFCNl%'l.VT>M=iD88Lgp$4bl&xLI j}#c4#j%l yl&ظl> 51[')6`rcr|f>Ϧy[QT3co(/:T\YFGta44 "Ȕ`hI|oqܻ|EJ8'8h|άm\ aDݔ[,g.wni;^v2xz՟壆z=B10/nǟdɻڒ߶g >ڿjl[Xk}~U{G9?%T^.Tx5*PvH6bj.nehGީ[}i旻WˬgΕ.hUP{-O[Sͧt 9Ƨ`w7JSYh6n>:mcÃZQQ>hz2VԆ5[#fyoU}m׮&Ulk0%ff?jWY-[Y ['>e.јzwGrwfs[ttʙ!k ~Xx&M54d` ZBXL+|o^):㝔K+&q^SVqըEaMMʕ r`Y޾eV 4UxrĞhw?!%լƹDZY[6Ea+1~0>8n/fNzz˓cn t },kF|4vg :T-޵mIs㭍r0g C܋Qk]fq1Eɋj>,j芰QR.s9QevhK^>3ҭoWO}_h>lnee+ǖ]ѱ;%reeͭOz aba}f heR=/,i cylhƥnЇ &4Z(o:07+*$iK놮o7m+nʟ&*hr<3o{L?޸~Um€9͎8~PW0!!s=Ո/+t&]zɯc=e}bL9Ϊܳ-.NK.y "_nMY/|C ȧd`E5?˫+\Zzae㨼:X͈_B 1nq@d_W|1YHx[|5.fYbָ5.fYBYLBb΄&Ĭ 1kB̚&Ĭ 1kBZ3H E Re$bl5[̚-f-NEl1k5G̚#fYd$GY)#9bp+fYsŬb\1kHHV$)L9qdY\Yb֤5)fMYh]ԩ;TP-@1@)U+IS] x(CR9#×:Ǡ?eEN'jdfD ̅Qޔ"%KJb)ԻA Y$@}ry+8&ZЋ_RϜl$11UZ1eD[Q 樁u/T҆ >Qj[Q]!iTL Py6(X 1`+j Irs`^* _lDJÈOs#Hڣ \+A sԱ9 {HQJ2Q|sෳ Xa:4 fy]5H)AMlojq6Àb퀈VG EVjeEia#o@ O֡WN5V` m̑ tY[b sJOR^9 n糙2V3#!!QmCaE-e GofQ{ }6t%P5 gggĄW5L} \5^GH|qԝo7rԺ;U5ەu]zwHdzK:H#W>asޗ>OJkz<޴$Vxo{GK *$^s.3N,9k46 155\'ꥏT^Ԑ=1f5Z,<%Qſ;&욈kE~u9pڴykWJސa,iG,=0FrX'4Xq3m8ݥoY)}p V)BKc۩mͯs>)홦~ErCžRa܇&G ?u|JuXQG3<Yк\4|VMm݅⑻zh}?]J IYLr]"$/뻝tM?â-X*^ꁞ܄_uw۹m/^X}a rǘ5jY9Ani59G,rz?PtQU:uڇ.8K|I2 Ϝ)V ^i3;\x:K3gaqņԱKi\=V{zk6c9^\i:jEo?Pۚz0#cXZu/UIkübͰk45lVzZ,qx6Qm|U SfGrLKg3vZr6֣W3}:,!'MՑ> _oZa Y3fV^RRaؑ)Ӧݿ1z4IӼkO=h|`x5) mC2MyxucG[n5;9*gךQn\t&,nN9?*Չ\,pnL4 2IKK,.#F1Θ;J2vK?z|BSI_W/ݷPP[DKA;y!7u1?\̀yyǮDϗZhz^^ /-.:p$Ư e ־gϜ#o^G3),O-l|#;'g(|~Qyw%E)uS,%?T?a7^QU9Ǵԩ13s6>#yTҹRUťۗv'H_wfPㇴx.oj~xŭ[D1o+^K~۸s_yjVV$>|.³*}[µ?-J2-r+}PcϮ&̈IL?OiVnx쇂ݭY;.Df͘&gQ3]tz3؛ /{Rў4;{á{ԁ8P{C_e(/N^Wzp+kCտh1h22uE;7mbq=eZ_'DYInr |4.%߽FZ]KؑۙfjM5wUPImR2Ҙ›~xU1{8C֫nb:9=}2'Th r:B $*Z|jv+OM ӂ?3E;{i!c/zXq’=nQSU>ݷeoPTbs逊{~< |Ztshiӗh|NlF;>/η3 w7U.-]`eK3.CW0t cORM:cnk²c&ɟ5$YbS.̚;#{|㛟moo\ gP'V:pr]}]nz8R;!}"082zCB o#0A6Yl8bVXBiCNil~A".r$Kzi!|rIsj{owܧ,U#L+:Ţu+$ &1O+i)*zdaRKV~O'F]/x0{b>ai+~ߐݫ|B⡏xlə+jK̂vސTs(&IIq"9q[vӔj WkRRg]vgacK<`4?fԽ_4"ogPOTJslU,SUٰ\f>Q3v4EČv "?8^ffwMvTm䑮38y :3/`nݣ7A~:ͭg2,ۯ v:L-zɭr+&G|7jJ?v&H W>xJ^X4`ۄk \~fBVm{)9LvƙpٔKo4es,[UI×ˮO:9*xxi匭]߇?-45ڧs[d99hQb(]1GquIuOMIWh u(nO]!덞*ӌ*ͦj 6Bja9S_6@lqծ*uт)0= UD(kR,!PϖAtah* Q!9bcĩz +lH,c/J|}+K<}OVt֦'5f0ls9z6A0322lŏS Jyx7IǰatL(݈eC JN6Ɂp$~&F2ic#[@ԕ@Tef(34TpyL79L.fXeB&?w ִ1  F (r"LNSgB2.0٠\ a?c,_D5$*I&&s9LΥ,0؃FJlGo8L7q fs_j6f>e֘& A1#"7\90{.֚cLA˂3:`?I 'PI9-6I80%.DюX($`/89hK@I HV SMgc":Y=ʼti0, 008v"Ѩag%asaX`'0q`)є=̥%1y5) X:X >f^,ET] 8 ;ayM}TD> rwQ?G¦~80rTM`٣0 8` bE <6rT8LA#4 =Hf ( Xl&Q0aDv(ciʳ ӦX= }:h/KP{;2TOuVq 8p6`F/,A8Z) glxB@ݛ 3~NBcZJhGDhtD+%8'+ye4H*vA[$2 PD !`hhP r2oTT&4}$cćqkh`a#P$K3{ '/X&< PvϱPXѴ3Ϯl٠.׈$yLTc4&z)  G/*Qlhz H>5"Cd!D*y\-Q>NK6r*塲|50Y`[|`QDVfWĔ/ZA0ȑȾMZoNL# ps"TC>(!Ԯi4ZK)Z'Gun9h. xkx SG >r(`pQA*`?2`a/h, ɣ @8GC?g` %D҂cPC6v8 4%åpEua;$-G#lz7H8"注)tP A>"+R DR!@`!`p vehDv o2Xd#"K@_ hENYN].4BgRB(0[H8l|3 9A1udOy˂6luFA0@ pšb'Wd#ƦŀmO:SI 0bltxᐲ!rѹ2C&;V?&Wa jKQ+LuFS V{FvqlqM)Asqn_<"kkf>#G踱tT5 ?OqQ):dp_ 9?τ`?fSq?"=0S,bZځEC|.tؔlR:Ula6DH46/EDAmӑ ڮ &%x[>T@VN݂u#GY>Kp l8IopA#̼=$hS~ KLK ZzFngO>cB8f(u[O0uJ9,.zgtji;GoMcgtSL)h92IM8:{e{+nMVD5Cǭ<.(U`|Z&{Hx{zw)i38.hn5Gai|GJnkuXm#*[;RЯRor27tbt|ybo mgidʓkWe #/=8VӋyp4IGkj5fqlqQf2y-}/v/=e<8'q. w2aԵn>뙁O/Ypf lmdFXǩORldVUVQkJ9nvu]|S [f1(IL=ROddXtL^9_:v5]7rWQN6rH~y1GB'MPyМcHhVƥ¡r3%f~}37ms\8mτNj_31O^a>ٴ>O˔Ϳ/{Up4wۡIk'u(kG]5an c;StO[eVK6~t涃'bT13%Ak64 %ZdݼcPix䨒O:ro½9s Lzuo hݓn0 ,;T_\d}5üK޿v;[>ojY3uF$Ov;}aҹn?Z[2:\atX :ˡqIc߶0G(V9]mPWW+&y~#\kS Vܵ!/ZŀWM2>rnw܆-/;X@=xۦFvy'Y4H|a{z9}k\12,ʩҦ{G%>ORO=-Hjtvq3hkQ ˣ]JN>3m+{NrPvRm_y%*QQʨOGMfƍ̈6& iug5N"pި`71ۇvsy=I ^ƃu:eVVكKj/ *^Ut>̋Vr-igưf.0-^6 wbxaMK$9/f"8h"jy_Kj Nn=XSFԙš -TJlO=&LjKeSF㕼o9 zZ_xqI/2aGa]_,,y鈽ݷGھ|6YkAJl *Foy> oN)'k?(=sDidb/|ϩ쩮951-BE$rBvnpVcooMz_z}Az]Ů:T}h+nePzpݯoEToKsП߆Uf?r <7\,33h3g #%R<Is5lz5B֜31vy VGw4pl*[x8229 T)$N?Yj|Z0q=F1X`1С?W8̾VҢ:f}Gg:N;4$[jyKwhҗd6wFyAx_J ѥCֽ)}xuMKc5u U*q5Yt')lT;wyϣ橕+ ߙOmneYU`Ϧ7ǜ!iU1|ybףM [xΨל>ݐE7x^:]|o>mO>?K KewT%zS[MmKQ r'S,F*E*Q{WAPH Fb dIey8;{CdD3՘8{L D({LDQԉiLO62Z%Uc JGrJ:rRC)wH}c5Dɍ` `+,Sc0:LVEƁ!,0Nɮkހ`l@X$%l5p{Sq/`T f:{߉bTWx&Bj b  DY~xǤ[$2maюod߷%YHȎHjX #0[mT(s{'rf7eM9!!X7f=Dq0yq:ed/֠CNoؿ3zs@ Qe ayc"h#1;}$Nrc$\xۃA< 9YV b$BSH"=&UrTXVuTH$|8ZMT%L %Xez&@(DEg" PZx PQLEhD)}&]Y"yw`Olq4*1d71JáJ?y8Y(㇪am` J84epJ+x`D\fi+6"N( N tDG=GdXjLZĩ8M(GP=(_3L2C%*Y5U%uH=:[G~O8bu8 BTLP;_I7)NTQ̼u;al.@ ;B$k7f7ex\/(XQ<0̦M$o&CEr6 n|BD< 'Ddt?RTv<q8Ab>$Yɫ*-yлbAStd0 +&E>N`B@pCHEj9h!K\5[w51y 8ZY]>C@ѕ#B"#:1toW{w؁)r\' SzިȈ"Gf{}5} ȲiDipбiBEA=EYdZX#6t*'Q-ex,1\ZUQ8g"!XLtQUɡ9X4,Ett"! 8|Y(n`> SJF\*'6˝AE5t@/Ϣ ]FVU9 ߪ`CW9:CP6>.%BHflV5q@2E~D t/G\T~fE$K#H.30[j˨C"A>@YR]Z9'`-@-SP#WpԤ"}ۢ:6T}F{An:*6,;MvI*CuIdPLLm@H `g^;*'٘04iDd>HiD8tbC@TG Hf@pG8nD.])hl\̌)ĞB&)&t=doڜfi83RU6'E`A < '11x@@./ s6ɐEU>y_=[9h'6#^ Hp9cu PS*Wt& f q8A!!91)?`d WLj0nw$Ex恧A"I"LXR.)L1@܁4|)hdP @vU0AL@ay: [b!Nٟ1h3s̆"1p`S9TDdv,AA ,sZR1j|LI(# I-oJTj?#;0e|l ,o9qm^󥓬 /T[ȅzm~ _z{WTZAH],9IXO]΍bfBCuՓ#$ce^F6 .ݬ w=7HVPV<5ƆjI~Y/|%x Gw-,Y;!SǦzUKktԥt*=ˋqST,y`SpFyS/W B["Y>f+O$y?֧>-zd|{bbYF Y([Vr]Kg_[x}e~a 6.QR?iܸGÔF{/Qp}ZtQ';x1ǬIì} moV4tmZce" a׼͟#nyz͉G1fj>8? ʪ?{<e9lun6=mv–Y; Yө׿Y2wζt֕3ooKi'k6-S`xf:Z8M &d8α{M9&}ឌ+v g!l_6/IT{5&Gwx7hW?Oʰ" pMX?6FN5qVb`aAs32q]X84g.&T^ϦidH֘MUFIwzF޷n}vhg_Os ,N(Lr[\l1sVmk8÷]§Vwv4q Gb_l:jE[š/o?h߸X甜_맃'y 1rXˋweZz3Rj+r#&Aؙl˖7ldrV$諶++p}񂂆"6s?z|!kYO_fZQJP(8 "%ˆ ( 6(1֠X F#HI$$j@> -ФG>EAucJYAW[=n'q* ?@JlJfHA;Pk'jA`S 3_+pXE""z;ѱ-GQcO"PNn"uD  BgT*lE-\pZ@YLDo^i.".G}F}N$0ir/Cڲ#C_C^lpFL1)KFkAd'u1`Yqz(-EOB0C6J1CD-pY!MPg*~]@@xYtVZNPx(LEM\PD0PxO4vD?Aa|${<>xfgq{:u|=ft~ G;ygQEP0w(HtFDl g"Q[-!upro,~WZ z-%tD11] /1 FY,1ҧCz2ul{C_e #et} GMJRJifhJMX| 0P%@ mC)J  Pmat),/q x*P܋R`t`T`5whI\Գ\ ?з> 6棗n_hJpȬT$H0w}$u e5 :/F`XmHkP-Ru>=])6P`P"Z$'oޒgDYVEo09EbQ&`zA T杘IIdJYPcieAR񧣍J6d1198*yi)5I \u= ]}I})\+_659-ο"{-\g;{w-\VVH]?0II B(b[%0#CMBW\ʶ$21KoЯrݏB~ygl)})(WА$ܬ3/)_$~Ǫ}*_6SG?/߇V- 4DTξv4 )MQO9ɣ]JZT-Em2T`\ zR H~0ԛ L8(-cd*S(PڇDFKL3ejԁ[/käcKʖVH(Bt" VT)_ؠU-!5*!69B SF;Py/5O.l87U&uHnvQSI'I8Zl~"cv(~;*Kz2&ŃWݵlb"Λ^/OŵZ^NM8)V^Hh`~'c(Sٵ.iTFiVt]4NW:璽RXh㧍6TȸTBs !uc<͓ثӻedG5OX"})QfO o ϰ{ h7f_*S0oV7-gK=8?-C\IL!4cˉ  ϋ*+$OkU>uvO~{8I^.Zum Fp_9غFOdj*C&sM_w`;?YW7k01RjSpS/>+}/x}c]jc/5.&՝;t8kI%̡|G }i`G^}JXcܯ! (ϞdO2 es7)Nk^MZy Yq=csChd;F.X 3w]YաYjbv7XYV('e<9kpiKɉ}u.|P,έu7~؎q'xZv-taiÂC>+W׌H8?s˚OXinފWXY#n%?7h%!͹K -ogv𒓛x_EY'}=AkM&NJ{] Tw.n[lkKqcQv3M*<6]zcz+;oڟn5ōK&Ǟbx&氍򛤮l12?qھYU]Ge]\"q77݌uzy[Qi$s%ΌtOv\ʕįe7Id+ zv_aEO@h("WAj(U/REʁ{&RJޫ ̽%H򹭳3s߮LcGgz+X3._bo;v,69Z|Y桥2679 6QmTY&MȐFB 6[jU~ш~z8[wG1zwd_$tg{PE? /yJU"k9i`kl7t،gcWѤ}'[}3v=`XL2^4=GmlTJ>aDm*K]]7-72\ÌuF;.=oyʍy{ʭז/S'I+::}x{NÆ |2t9gxѸc<Ȗ]Xg|#kXN[lz%UF$sM4'XOF?6ywf^pҚ8~Y\Qnunq+<_6qİFUib;Sx<#Vg=gW1{;u EnMSs=/X˙/O-Ξn؈OKT|ջ!|ˎl|Xg泍E<8ȀӏULC#_xAH |G|toaBg?V?<0ú|O PoԻ]ꇣSޚpMt=/]eCO굙x`_KZ}ׯ .5rb2ן]úФ½lnȳXHg/}onEE2rLeFg)ݬ`ްwpִT{ aS̸S˿ P*ےuSI&EN^؆WOnH5f_-~if̧7hsG6km:U4Q4#'/~(nZ__{eUK55gN?ٝ˪ʲԯn+__ t4_%TlmݞauϜťχ5{{|՘Uw w/'E_禓Ú]pI~U{Z''4̙~Cճ^dMro_WqmG/wk׆jrL$m!O_%/yNϧwfAI;r;a]#];Oυ{UpO  }Ҷ& 74\k_̓ Ą7}g<(_}b]o?yuW ʌz"Yq_½F ʾFhq.dfu= g^ 60kC2;$G:&;,Uo(]*eOOX5okj]ip F =%i/WFwǣ᳋45ȼ.Uk~hO͐CW-iY ;T_V9zlL7?v=r!?|XmY?WgL5oҿ_mKv/~lSNh~=a7;~Nz'V=|} g._mɗv]'JTOq䍭Q[ֹSsGsM=?o_~iRݿq’1z{Ys>읻7J?ߚnK_?E-ԲM>yrnyFņVsvOCgD/զ}/ϯ[q|ഛc?+V,.fs_w.G~䇊~w6m/3+mޚ[QSج#?.\7~mY}t6#NgcBrIeU9\2`}hOy=7^tF"n^eYkݺpդe{۲] P毖OmؿK}w5xgۻ^ړtɁu}w\ _x}xĆ -KxXg^֩EWoq.; }xd˨u{Uy枽᧨iJG4~:pC7K]rzy˿>j²emY q5Kyy2Mۥo/Ⱦ>.~v{y)dx6VamK-ѻ ZO:yԫlזNlVuxy{=ߜ;}ąyzYq o{{PuQxѮ-~5zނi7TZZoԌѓJ-~vn^utv/m'ig|~\1uĹI}j7h[sr~’2ujqwZztZ8)|%szo&9j׋=yr9{Nv#<2UTy!_:Y+NIWj0ٞ7N=J%2r?Jk뛢fk;*`ĹOᶇg6G}<g(knuZN,'7`OkgNYXqַgG<߯I^ /^@e pЂu~#J[rg#C#<ݑK7tvKl(滆]ߤ7hgWgRz._,k5>{~I1󔟞<&w PE~h1uJyjي_߻e}JG-<\>~c.>Whߋ|MwϘc\z_xNIs?ؑw},n[?PR46tx@ӥw~ERruo'jSrz۪b1j-͖?t׫ZXb٦M-~wbǟa_sJђvvI2 5GM:KK;o=~:>Qz6 /f]uC;_ruW:_m/|cu>-sȎ\:roY6۹o-6{-qֻh7*ǧ[üsFњ..Z|čٵ[/Qb٤]^],n{r#_'NҺ\݌;M39z]~߼,?4˄E+sO^TGVlޡVm{~&QN<3v}Y&|[]}z\‹l[f~6iq`}q}[>b![V<[wspԺ^SF(#|jMw)dm`޹/zΑw4[ۨ9CּV})YYʦF3{a'Z,zỒnѫ6Y} M8_r̼3^9>&Mk]D慛/[rՉ+YF|[z7!K^SXHfiW[85otl;W}hkwU5<~.TӶw=; YNh=H ;fS^gKovl{ 3n{qpZۄkg;ҽp[_K\tNr/퇏>jbNK㗕|oͷΟ3|JklVwȉm_;rѴ^q^ϯ/XV_;٢vRTO5ϽmϠpa6YӢc-rR/no1#ql:nY͋UFk3cCˬ.F{k+ ^΍Մͳy}&:҅+2zO]fw@M(Qy۹5^{kXw=+Y<ףJ̮}h':6:eWy-Y7q</>:_mӾwΖj;uɝߏ/p.fKTҽvm&9]aғK&,U|JVejo>}''nqՙs>Z[h]aga|ĭgV<7֤Mrmπw [jㆧb Ǚ>Uq.xpۅ1e.}[RWk%w˺]Ϸ^TF6'ϗhhh}}OJ-dg< _}{K~olqw`[7_vܪ I/g2 v 8r؊7 u-ܞb-F*k"% 1g;6G _ -{$J6ymr٦3X{?5/(nEѹN>x5_%N[赛Mkܧ ]:)#斛?~>VW`i]}uX<B7/^Ů2#-5-Z{jK%[#=tfي53w-SH {|>Ϥ_m*|uAx)~lŽھYjwvS{rʟi'fnaFVlPn7WxʗtyM ֝#OzGH7]oVFڍkRIaU_ S5zR>ջtQ%Ve˻ۯKCVFӏHS*_<|U쳄Jf]錗yUh$ 0<8tTtP5M+Fa"R_uӝdӅ<ڳf W*ڋt`7(/ !&U3'UM0[orwf&Ǣ~*^ݙ %wa,Ş C[v U;W}zDPmq\P=dP흁 k@uN Oñ@o5Ξh.a|"!_xfN < S@M7Z#Vu_tss_sߠ YI:_OWU\(d> ]<мJP ˒L>(/Jb I1>-%í/&}X]eڤ>$)EAP:Oݔ݇eF}rQvH݇NsP1RW7ڥf͏3&T}sRq6*.5ſ.=4`N ?KVF3}~2=Oo}U"?f@>?}YbZ/nbOO 740^u۬n&`WZ]B)Puϊ8;U5} Xc;Mw}mƄwxBV5abĒV|O2%L~5bv˅ $ӔspuSj]㷳Bj\bs3A5]sBϴPaBBhQfǢyt(sB tpuF ,y!H $52puǰ]}KDJ%YIX„&+HR ]#yxi-!QM_g6[pz$AFGaf Bd~Iz@S I~Knϯ0K10)퟉0X Y7i#11 8I 1`҅a#)lE'3߬1LL !/ +Pi'tM?Ȕ֙9o8Vh(-LL[iAFZt ´ aBd:LXU᧑}.p. 22'ȝ@ibU{{RaLKwB*>q-3 QCؿ_"UJ|xEKC)ҩ!u* V)yy!,VCTh{WȚTV ;YJ[IiX/^HC,蔤=LwӞ%nt$9#k4X,e]wpf'^%r9dB&Btw'1`' p,cر7T aD!|w-rߝN+NQ𑣆%N2) gR )D 鵉&i: ȕ9[{Lp{ʹC:{{R:t۠ [BX`)j<9=S3fx> Q%wiLcz.'O >ٻ&%Şy_Șb@"n\cB !W>&,5(5fp(@tSp%(6Gf'#g;sq)(;f@G8v9b+!݁X0d8sl|[aUhp?ṔswGRvO@KRpu~C:mF`KAD]r9$i3Es OUW·h&k'ϠLU-(f t={{~tL8gǁ48Js&m 2^v[BDU1c/:'ӡW \ :q_抯ۥ[0S<8 u}z(d@v.MV;vԷRe*JMFiv&W_3qV):mZan?jx 6 ww>C Q]=5֪kLF V '=q}kszuy#h3=xSJ~%h ͘{3 $ U(Z0!\Ƣ;t1 `E#1*ᜨ{X<#@\~9skJƹPn`.tRݕXuVUG?U=]($RpTGaIXY25ۤy&9*֭9ڊL4Q<((zpO]]2SJ'a U'G^;dzEBΡ@p9,OTGIeSiƛ(X275x8 ,SKw9jxR!%dHGY9<5y([=y;]V=9tA?7o ڄK3Idw]Q< 0e!=%gcHhBTi<>%o{vG)<l[fi퐵R3HWh1O a`-ڛ|%v,4_;7k4$Ȍ,Rq̮C_potsgJ/ sQqE"W06?axF5ѠK5wj髻F2峭L34 'Y(0/ntGI';fG5˚\Ƕgs?n[ F[}1<Ӫvݧgfs(tݠo];/^P(Fdp;zq=I @"bX,.k|Ut-^,2O{Cozz Zdu_ܲs bfUP >#&nzU+c+sNz_S WүH W`}4D#Ew W1t|uCp_Y6:HBahWI𫡧*IV}f^GwGe [?"!M}r6q >|7~Y` FV |e"`^Wt,]iDH=j9+JhgA^ a- Ș F=>_rSϒP's$}5N̤C!/r;jWX/'f*ͬU/sNsLⴼ_U1zQPLOc)/7(*:6dWTLtIg$aL"-W%CcKAG2ͬ{V }ebo̒odQJ;uKuN(Ѓ )hY3&+E+3|M~:~ 3/w Ok%Ӯ|A&2ƯAfnb_FҊ+|Ot{M4B흭`}d[&-,Mn#K勖uչ`8WC1JByz3ZP[ԒRn~*ë"))d~?m33FDOh A+K"LtCDROD<@T>|`/;:@lp&W`:|-(Pv.s-S2@h3f A! U20I2ay<$!@u`fS' @J:nWR},ȣ2"1lGqi:nh<"Z:l0R 4@1J';w(:sYWf"OuEqnr)^tO1F7SP35PJDl8jqBtYTLxbYg99 ~jDè(!gT$a姝d$YᄦyA{vsM&?))mJ#>`:N{M^e*d U*IGTib tM#\TMz޹W`m2$U0h$v%P5ڐi AXGPiA'1Ewi[A`*LdGبK3yD! N*3A@edE@^^Ba1* afI*)QUwR@W*oL'R(SQ Z/XPFv@Py  =PKy!(!V1ŃİF\-N`(U3`Yə%j$F +VPc1S%3(dh ҙT-.Dֱ*RMDUQ%a-,OR;C3]x#4h i$ $Dv@U*)h NUY$L 8*9QQ%r)@&7zY>@)CRBO w(8MňPZtbvuR1ʴ@idGgKiy2"h"djap^RT ցM<ח4S9"S\tD<6Q5Q DNsyP i ieHB4!1آNHRmMM#aEh?-Id ڤ.dZ%rVtu.FLS)O+UgX6EK"*` 9MA I sٜ e!.f 2c%u)t:h ƈ-]OĂgpA!]RwGA%\d вxu7:0_ .MT8bMu@TfiQ%7Q@2]XN E$~d*l!1F猑z"~o%feqT7Ax&ʣ3 |,$ H)``d0%(oh- 4ɸx` L N1zv"dCSb_"`*A!ҮD7RJ+DE25OoSnc4x'U {PJ &p~Vz*nP&2ї~L!Nk䎯^𒲄W^RhHma&DwEV1}o|ՃKh"\doEGi &gʀ 0G~Jg ^$交߆FGJXqP9>hBPI8%HMm`^ބq yH,d0\!4c~dH0PXXބ:9J #.h;uf 'HP:+YUM ͑U&#kOTreXjyް 鄓4բCt- < #6OTyw.< ^,~hA0;!u*R~ .~΀ jPF#ˌPIV`!ƈ!TEaxGV =urz,%cK-udzyiDO0=/]Dd5r…)~g/0I7/a^ .IQa"kmO^( FW $z1 3H ~ Fd(:E-kf r[Zg,x7@)Yn6% CD &꼮[H SL2L$,b5w #c\*>ЁE96L-2x+Dtx6~G.@%2H0ьxB*9` `H1}z*cѝ*x7v:HdIHHXXh"8,eXP-Sѳ_>"BTkc1 &>d?wLzYcb%wSbt%l] ~rCd#R Ť`(I!'aM-T ?ԂKWRn`EnAfN% J0ↀ/c8h{|hxh= HacBU{gy$$7#;1&(U(Y2>oTІB"cZ^)w↡0Q@ H8X G4^CLHHxu bHziwn8b tӈyDA30@cM@Hg*ȀpbF޹+( 4dELLM<>O1TvNf^LGI<,$o)5byN:KtLHGtN 蘿}y]TBD LCKz^;)a$za%a XPWy 2P1  T#a-Cah5U0tOS0膅; [bл1BЛ0 y\\vDIUk%iIT3%0SJ%DI320pjyAr4 {"a>e0iLE!oǘ 3楍4"e|L\G Ȋ0uh: #?IA'6$N+h$yiP=gRH0, Ǚ5Fcz0W&Ћb$6>'0s\K Nt+d$$;Ð2#Y-~/a" Ic"x5Q2x]L1ԧۖVÜ.r?C 鈒,'ZA Pp"STґh(N,R2L7L[Rdwp ^J1LU$`玀ܘ0< i2 ³LTAx^ ùQĂP#.nuJ:QU$^Nh03PLˑTLzmlVr%DE/R1Ǜ0?-O!XB4I"?-I\LDo^b_U Jy+Ur-)P%8 dUb6bxu2F# X*e}hIf]/rF1s0Y#3MI8JǣpBjF !T0`~h@0D^HeRy{ & R|d00Nt{|lQ"9(IlgBF*`B*։՟β,$&a4@@ H~LrAudr+%b_&c;S,! Uq2BQđ``xW$ *lT<v; 1x3$x829X<&,*VæOjgO%Fed 2qwB)yBzu9`|kȫqϯZ~PJ%!9\ܤdDLE 84"[0$073JKDu^w:G*Fh Ӹ;Pc:9ML"o<oT;#B1 3PhBC&;lY`* 0ژoXAIfJdyD;=>B&oOA>WM+!ȡr 5TXn-P&11-Wyd$0F#Rv ä*z09.c,YL$rHH9 K ޺)DSiRj T1 }hBrCC߄"yuMk*`ّr:`t?H,' /NVM$FaO$.4?4P]{Yid YH|#T>+AmM6@|bfh{CNd0` ͋WNtGH:{q3˪L Shw7AYJ%SL6 61 3op0 0MKEiClĘ@S$7p]I^7%2 A0r_Q#&#S M鈚ګLC@xL&BVv~L^SM<|#1@YgHH Ȗ 6qL!ؤq@,` S?PF#wTS bOɗ"B2u򴱚)BLz bT3*Rx0+Ti0Ѿ]5"Fi`*\;1 y!$g>Y >fo'EX1qZ;&ZϪʫUWjʕ1Q\xDZ$ w^}աcVhiY?ZY= { x{b-|ZFFfF\).% .VF@I3|R̝LML  ]M,M-L]M-l*U*.I,*(JM42320RUuw#.@92xuXs`fDSaTR@i.)TD ߽=w~73|?k=;reokew\zM8 ,ؐ~O(]b`HO}謌a \o  ˏr-C4,nN,bpWS;~͝<_-l73_QF׬[Tr[4شr C\Nƒ-|nOQ谨K/8[31GW.Н|68ʙv1yHZ92Z 7} k`idŸ:^ !56+v\kxMlN eRrrtb^Vp[MRYy aa\_rQ mp;ݱX;ns6!>L04 E}PMMd&BR?MK<9`;ϸ*e .&zNo˒]^娿9X!t,tywrj9exZ#BZMLSX(T׺PM&킿7*aT8g;R*daQ5v+P~uWnh2:F ձW x` ʙGY0 \ QCDLkh)' *k`&5*ߤhd}G@< q 9'Zr]ZH6$<3l#lDNd?~w9npc\H6c=I#ژœD$U2vw3o8c9:P&AjG[|h?9YY?4*J]EUkX|*kaVJbD:פj YIVd+_i$a-I36_EKǠS UeBܔo >?N.Ф]7dR~ۣW!"Hs""ΞT]ĥ]FN5:}sg\>+]a;w K1=n}3>/Xvr V1iʬT2Ls_h{͗)dϻt8Eq{Dt`ʩtPyCJxjZa0.7U )֮#)NBJ5+I31=4ӭL퀅o[LO\lj`Kģ'覹J5ӬҹAO{.xT5&AwѤO5!J ;z9?F# mp>dPKAPP!`R@(޸z̨@R P 83Cj,M IPBB aApq/l\")-bB0!  AvSFyvbFqg `BZ Ԅ@`@P)$B$.&XFNi` $KA0dȇ$F9}7A@)q !\p8= g gTx}@ ?8p0-'4G-1*z|5̹߸wT UցHU4V5RH&zoY/_sK N>k]]rws/o Ha|2ÁO-VUe\[B fúb, yumxT|SY{e1ZKb\xjkXf u˽>}I+~F ޥ/q,Y׀g 5h-pϯ6ƃ,Ri;MVY)-7kV2^NP2nIT(`aoU'iQǰ 1Ѫ`Elz:KN뮼xD˅KxoʏRXY8>m 4%j,?P կ Lbgj`a=NxP+qG4^Vhf 9q6+|zC2[6*/}м]?f Nt&M1QsmVkXdd?BlT9d[e'R3y;F97W$S;^/]KӨ"$*b$\/bl&րSd׽2=ʋkBF-3^r(X~iWCS U\Z1rlnj +t|ob.ƧbtS/u:f!2^Uk7[\-< B]{<,b/fU,NV=F}9ͯerʾL v5?_kt^l94F]}m {:Xkm\.n_m'ٱ"ifpdS7v=ڱ&{;}{ o:]Rt"!N \? jm<| W}!lhQGM [ s[՜k (P<9!(ɞb`/E!N",ը5Y<2#~"=t_C}ʌr۱h-}O]ةb.di&؛Wyu=wMyM=Ck _DFxt"HY&5Z#nf~_՟#SMxJugTXR{zNbilűΥ|G#9dJQorWO'{=sHX'VSovƖ[Bm/;J*0M# buR:G*n%eo;J)Ԓص đê)qѹ9\:-LZt=ɏ+$9||?}bEQ௏ۺmo$7"C9_̕FmCϽthZV|aiwwL~i\2Twn/#ƄA-ϒƖ{fZ tY뵽G 1 4}\SK"{۫,qh[Zj*t'TF!kkMc$/2#Cac]B&kš47t$.JH!@0( hW|(xb4) rF#d0Fp D`7NQh0 38/@OݧD/(p T(hQw80qN]Yf80=5Qrv(=ʕE8^'A75Kp]84VmceC1;/G۴7>ԇFha-vC>Wd82(*#:j:[E+.eXWܿ%}?D߿T48RzMF{I?A{x7s$z/VSq.P9nn5i w~Z>^, .$Fg_vs6 <y›; o&Z42E/lV^9TlFOa VHS5{AWd|V~F|RF?GU;P>#}Yqfh !N\җJJ/&_N#ߎJ17nW 6F)G+:$<8\Bl,e`d⥡}>'1bȑG/.3w{iݏٙ2>#PPW*MG], (D~U숶?,[oT jZXx R/*JtMXno9*ƨCRwV SC:E"N}h?rO>nMFTMnhⴏj{Y^Y{c@hpO>L~puW|m͛/V#Odjhev'Kh'+9K$kˆ8½ڞ)m"Dl^@c"b.&i>mЩe~iJFw &Z|%7MyHm%Q}翭kU}^  Jo|(~+v5(\sFT%P} n\ŀ*+D'&alJeRo$@ʥK=\nŹ졹kg:``M>4wrDӟ"[zݚ'G3P;0 }u-RڢyÞZ]dk)aq?pGP w\WyLfXf&=GGq΅X| >{*n/YWH7_Aϥa Eo3 L(~-!P\F9޻Yو|=^=JY!Γ_n4-RcԬxN]NGPJqwm1Pox_°lE'aTǟ$rp*Ůb lt8c Qsԯ Z5Uz­I?*z+x"_L]N'um)K44D+mOjoZAɏn ”4AsnHt )~{`VWHO1͜7?Ujy>aj&K5#qpr;'mzf| ;W"ggLG?>9sTK?W ڵt˳5݁vր)[yv scDzukr;0)BX(17f@ٶVhumcqAMxw%>ˎKⲎ=G hNӋ mADnDj(#urQ:q ;G1V,cF8F%Az~$19%1@!0E4¿R(zK'L8V؂11 E`O cJzI: >`^!&z`m>5ojR~̧h~]֔}o ձսQZuBI׎3CaG{sbN&D ^zm{\Kn>~^J>ws} RBM]42Ưh6Ǜhg拟`6CC$92^aOd{XAFMCvET5A/woHz* El@/s*=A_;MT D.M氙xPv9Sq!* oi/Ϋ%ks[˟uU^06%X i|V-&?ݽQ㪛fibGDY'^:qsoN 9Ia\60Ǹ{\UƹT* O~\-~2(&R-*@<ڑOIrD5s#ϥtӳ0HnI07<^? +Xbڈ䰍+9CETr=d 7 D=y\Bn f`f]Dh QKgNWwN:Dj;"D .Ƴ>ޑHn%w%ۅ'q3*}0w WJ%'֖#I3BLΣp7HSb"\2=}{/p˻ u \ $׶hhNjy"z/F6D9tS'!FOnl{X2{/e6qoYYHc_Rۢbn1"(ic ٣2h26EIёGؠ0z D[xo#&j(I89~Ӫ󸜢^{cHxh3bSмN7 7!XN}bمijw9F;3ȗnEk,$G,Ռ_>+$s1ΡeHs2ͣD8 3Dپ~ +LICsZrRMlRk">bC7B6t.\;zM: ,OEFk{MRj-*1Ż9Rmi⢀G2ְ;'W^ sURzCRcS?)S1:@޳Sb4` wn,_b%hMV'c\/#Ӕ>'bEfKy?#b(ME۬gdF2496r,:i8S45;Y?n<pMea>26|_wD/u‹a_6)xHX(B?.W_Y.щۑ zG(~s V]p"nXR w,R&VL]bČvx[Ȃ XЅ@γ ]$L һ?ңϜ5ʁ8,tTWU%h{zen˝(2Ur@oxe%hj@ۇ'T*_xI_{E}SӋB[j~m:3(gyMؾQX]<9Q|#ylms^a5t|I4K)A$~Q M G3Jn}o=W` 2~@M5C ,%W:i{)flmm[&vZ/Qe8mڔL] MWY1\L$>i;|i]}{#ݴ3OOM/-ҒM켐g;7>YbrPGCf j1HK\jwxʐ>UwG&z7y*(]_"M,sqɞr9bFƦ{&[pib#&Ȳm HF;uz+72 3쐣k˷[.ۄS㍮&;fЗ3/hkN4#ďα=lML{5@]$$İ= :#p8 V8J<0'8)*bkqVx,?ZBD܂ʆtuVm ;k}RE]fS?"~@P3(봷Qgx.ͮ)]Y?+V;c:[1&"6|}gLj5ۈr>b;pѹ(g1{e5 WXw0OE?kڸA:_~1bوopRl x?p)A.,|I(.TO3~}?"Y9Q"P+6t=+;aj{ʞndkӼ)T12X&_,UYap#r=L:Pw M`B{_ p>"րetUTx ~gDeiD7K@v;s#SKJ\2yq-gt/-2aK -]J/w7?6fUo| R9e7a/o'^'(. 9mSq G Q<]/+Ndh 4Y,N|QQ'J^^ޏg!ŹRP--Ra-t .J Ct$`p(%šP JI @ =hYd#w1v8{@p u^1 jZi_]B B`2`DY`F?]812}R0n@_$EI"@f@ $%6h| & *<bI1.pD?IG/}q90BB03@" m犇h8o ]T@! <ZS3#߻3pt0VocCA3TpAT. IvN`gS1NL9@Jlg:$ *`~Fcfq> 51Fx$ HpQQ2gyK3Ce=ym3 fٞD`iFSyTk3YD%?v[l%?/%,Un9'7.;Xȩ%X<ڻ-X`R`=m.y O0z" ġ/ 0_ U_No]d#n-:y[V&Tq&=OLؾxVföatW]HQNkM (AۄɎwcC3dzQ:=Fx[/ҁA)WdPa1$J{גfjkӤPxzUOI~j>݋'.D*\G/)4ޤǔ>M!ܦM!hr-_2:AO/H ۰~ f˴N%Fvg+/m-Lz|eωd!K-R'far-F*}:TEBE >UOHt(r)?SFL?|GVa;e@ agrG[-rHX$X#V:}lxys= o_dy$|T(C<+{7xlOSy(,nByxz/~(Ɍ QGu:]4`*e:b]coɝmw5 SD)^:S7sь %Lʌ-т(7ԥ'r0  f6{OKl߲ː.uyw;<ۖu@ ¦c_=L-Run׃5vDⴝT= pI+pæw4L`|K&e&GVj.ݬ&͆̒L|W~{N>j7l<@N1!ϑCRB*K"2;x6I][CzsW(X+{д,& }66mTf|%|Ō2v0tPoHAg_KNJ<6ԇ'h9X=z㒹cU>J m&VW ˡֻHO8T3E{~!]"}c;yՔ.s෾3u=X}+tΟ`I"J]caYYrѮ%҇W\Lr=- ӟ?*̾&.H])EȭI\֧/ РmrТ?Sj-~1{FqEYm"3\LbzsErYS5X ʶ2猄;قuyCD>r][pĿ2jayiֽ#.X'iC%pt%B"[Q*$tA0#L?gG"*Yo? İ$?Iq$ۃNe㊱C$^$!LkmU^HnRZ[@@7qD$˳ $.z!Jn%kE#؅IőS@<@woaByLp(f%LEw#H A@0LGlZ m$oTGx̘ȌîO.N^{RWYSn|>#X}pj%+*(/d ڪ+WrL<寈y|*']Hk]җ(H`y{`Jq RR>yw]%!^7Kϛ)}_o 3Or=LٱxK7q^ _v=m8Զ8*g[8eC7-T1=$K`ĝvҞFXUOܷ^U9y_Yeq3zEܕ>ۣQ#T]PJBټFJg s%5jv?.F 'g~{y/k Ҋ=fߣУL&HG~ปZ}\#bVFUi`]wB9NxjFIiDz,VBծ0ObZvڭMݷ`+tYBJujm(kY [Vf4!tH$8lדǷ%ͳ;nl|_ vd˅J/4`=^xE[+AX!vk{Ø2WO"ܳWth,?7D:6ސ|iד;*èy>_.D,ǐ4$Ppnrklv@ZpIKҢYĀJyˑHJDЎXh?Ѐ4}45J|Jͅ%l3DJg =S#fU"~zYyH'Ŷؿa ϳ-\Έaڮtp|j xrdfű/*kH:Ht[P(zD_ 4]恪DZފexv|*hӰ`Aٙ=uGǬ[xKFqϕPnq6-F~Q E ӑ:-ힼ~Q/dFo1EH"..gu{'@3JlK^(UծK/sZg J`i1.o+)XZ .C;C/K lv4+ߝ4U6R%}8k?/G%$/C^~PG[p[&e7$;F=|:t,Oeiu0h,|x;܌f|B?+tjE7`{7`aiB89k<:V)E8dÍ@yK ̞-OL72:- 7 Ѷl.8K^ڜ3C33:k!0;]ܖxF7|tm:r/ݘQoʕ+qi8^-Ua`lBVDѽW'aa/se}dYhq^L+Ö L\ŭ)  ]xPApI$_P D G*"$&o 03K#zw @-v$$=,-{r:i5R pFƿpmf{{Gh5j -NF$A+fb#'}>a;&++OÉO[=CQ#$ə}1\tg} (P3z%Ke| I[Muд@J\r0_Zw!'}AvҋTDf˅RM Mc ZYH5&wcʱq#L XY \XwkuNL_Ⱥ+ v[,]q] LS?}golGc6_fЦ Bf|Qͤ4f'ϵʞl"e],.7%eV?DV]ASn;9 %_.$`Bw*m\e[eH-9pEA(Z%g vlSi^P'.^ ,w0ģ"]2iH5чN;̞P |ѥKs!6$1Nk8".K3a f}mu; dUv쳓Q/'Hcgʔ4TNCp|Vr`Fg ^_ЯKQ&FC1`L0ؑSk/Vp+A!H"i=ᐱ.4q6VȀVb (BE[z5jف"9{,Rf/PGNTKrN=ӌ( v)y:H!Ei<IQJ|h#/~K-cm ڶMTCw|7lv3OC@ldpr:eZtS?ksG$yZJْLi]+S`f}Y? W_ۢб?uY'T_G*+rE#2&KwWWK|:B^fc]bWD5^qWwD'Cve8E9D,9GvȴtTĢ]=ܬfdg-!\2􀛫EM=9՛O?kW7gfJO)̠T;>U`=EWHdWnꬋfo܅NLn{8VfoV;w 2}t䕼R4Ϯnw4Nu6~Ic]6ŊXo87k]H[!]qז%r-ykM:ggf6A+|/ gqd.?5k-7u<#"N zi_'_\}e@\=-^dlxqw)n R܊[qP\Z.}{9g%;Y3IRa3j3@sc w0ӞdIs3\7)i%xfa,r5QT(PlP(iLa(v0]4qr@3[$ibPQ%b"[.l0 *d.$'k`Pp"7 Nw0b6?|7Av MS]}éSul]ӻ/D !,+}).WTd"[=p!vѲ:iOު ם+ԩŒ8!_egTE5M ~MS:LD 7l[s(-|eHV#6Ԩpa[θ`Q2(|]H6qa'?hf~ݹB/u ff=_4h 9!<4B * /1Vy[Ԋ񻁆L w $Uk)0Ł. AH^Ї`Ɏ41(* ހ?N2J.p^Ϋ|\MIZʒY 2\.~ UA,AZrTeszbb#C`>В)iӶ)Ƿ_7n24'Ds7-Ek%31 E )[r zG{(dٓƣ"5k)nE~}/Ƃ|sA?lRRѸ\v?jEe>ku mh%E75p>6Fɬ#,W\s=9 HD!5ɻQ ֲl7R+%3(I'e9?(8>91zpufet3K=Pd3لzŋ ["jE6tW~\ǫܜʾ cO8c^OvSdcؕWxQ"8@$`[XYsT_duDLSuU-qΜ/r,]<$Z=Vqx}}< ̆L&7SI Lhgp1D?jnj\ؒ &탐t.+7pC7Q}l.N;4hJ?4J/8<"R -k 9jdrPq@7 TtT n)l}n3跣hX ȔX![ pA9mj7~FUW9fn㆛[= ;>AvuZyw:j`{;ZY>iHHZa662DM4Mdi: شzBET!MU-!o48Lj'\0@Gk_?zj&6(=1`mb(CMx^ۯ"ĘKO(壔v p-ۢ8x7r`imK}y'`wQad䆩KYgUAа#hUp^ϱw2snu NW)n;ʷټO"!7~b ɼ1h:";(8wY:4R@S),.ծpJ\Z 5gdug}_YfXS8MkR`HSIw'[Q;gtæ|Ѷ9{2N,dn4o^9(P3] ƨܢB/T(X1F2cqmT4Wg~Oüe'شt[SkWqyڔʼ``]>0 Z<]+i} #$, x"9XI0,:v[էހsP593@)^m#Gܥ[%ݥďM~mS(FSo'+8&dwBDגF͙ZbUR)ICMo޸@}Y[B$̙Qjrp7ZS#_/+Â\PQ< f$vG(t#欜yuR>Z1y.Sǫj-YP'q.2 >^*?A_XCq=B,Bc j?I}ji搟;4 bኛQ׺hX^*VCvSyzZ"ޅ̾ưOܘ ]QLesFHk짂#c 6Aݤ/lVؑAfc-j+}aFȉYEk8't ,Y)P9}a},P 2,NTYŮzab6ЍIAӇCw n#}?fjxYې`PObbDc-3 ֆl`WSz\=OશʯXA=S ӵh<у3|Scﶶ=P=ҤBXI?F$,j}uveҒ8J2ʺJ, 4 D3]x6QGSҹ"% jvբSA10y@ל}upjrDcw|1xhW$CRF>Ä޽qzuxxS ޘĄ v]zd JNr. etԼG@ .G訡ۀ>}(8whG"2rK㗟RhÐc_w{Ic {qkѬ@]cZ1(8HT(akp_ (NInm<[Ϗ1]|}r>]XSZkr֍Wjx˃*6jv[ K ߟИȾ8Xp]jnW]$L29Z:͠FPJ~j2;]Чd~>>(oQ\53i/:*,$xf'yhvhaY#$R$9~,x 73;9M_k5@ {@_+0R1*q-x=S;`;Fy:޼uԾЮ%AUPx2g42JeY S6ML;-2OZDnm\S}/zePյ%Aa`N>2Sfv.iT2JhgW+wwQ57Us9@H4'nۨ7 C_'5gV RhV=H?Uh[V mʼ;3|8H9T#Қu_I.ٞϊ! jOҨcS(tOIHP{rlAcR:nZ++2X󓳘qȘN#wZ*;$ʘw' D뾎,9\GZ׽oNeV>ouw]'P_<\c:&*M;8-ij#>nm oHgϕI@d aI҅9{ɘQa}4wG!:ߵ+\-fj.Qg?g Q(aXi+iђq%S=%[\2sĻ!NKRk*]$E=L8 w[ B $֩2Gf~idP!JKj.2|[xnpkv!Y e*2-"c0+#zb`hv,ch,LbTZbcC$u"gv4dD:Vt8| 'F-_F_8XCͤ~ PD? 駖k)=@؀q~<dv꾬eNY Y~ ΊGyq8as /]Ȑ nXZ%}Tv:HpO;pUY#Y@j/{ޓO"-H8U$dUSaEdZX2͕EQqnb}Y+S6>}-K#F[X2UgiZ)xj6<H'Y2}FI1064[॥/()I蓶LT3:;]wy]RWpYs`}ʕrC5:Yh $frJ4㛤2D@_2&1fNjJ̇_:Jd !5> Ɉ/V:~/? ݔ)ȋ=@B,Kj ~FJMu3% FiYMB\ke9{siK`U=a}qsPk F|*=B볒n\~AM`Xj0ɮӗj%7N\Br`mg+l-@|7Fs4 Mgs>@8ZŲtLJeUj)u䝶+J؈[&4Nm{Q  +?D+u,E "T즏WrHbDMq8s ب Ś+qP5#Z?U)%4tɟ+H_?Du;Qs,i hcsk/حƿj"+Ao XET ^E`*u]Jʧ V=um΂O*:9"ޙ<{HYNt)=bf~Sd^~ݔ>wo9]q氓&'JQ"#|V9ӏXO#!KOʃ nu; cϔf:{TQX+1-6wX`]VkGGx!qC ]B 3Ԟ]S>:;*̆ȩw&f0_'+AQ7Gf[)IIxY z$VLg)"jLɑ<23)tW"hj;Ҥ~DS)g?G$:*LE; 5׾]9[W֬RT[kn}+3jX9@*?… C2=Ԇpz487M]S_?/QKa6FC?l-xj)JaOTU"0/m?H[S9Ϣ,!:.(Eb`1yXl su{p$>qQ8kRCLb2~Wb!zo'C*-{  yWw3K“.T[w$i{W? >YjBy5>,+U0>Gtq^EӓWʔ]E-J &9TwnB^ENJĀ`KNqHf$s7fB5nlO82yrA] :'q5=;y,5r8.M4ı?E~~^6Ք\>!d}# ^7yX ]?{mt5E GUBu~EgRN-wQy]s~[O-='Ȗ pN֗c/HN>VXv99[ 92:5-NiИlUXJ]ILg}{RzDrYːk]̵,+)Y sߏϛstȩy''[= OO((B$#Ci97`:zXF9^%ݬY;fhZ= 8Ρ u\G}Zd9yjq(?"DcOqDMcaLw'[Ҿ $ִn` IօZĚ6g蟓Us*ԁpSѴlkN2ȥ-oTZ㥲+4@o;"hrS I2ІWm1aG/aAώ[0jnRvj2lP?d ^;tTf҈+U M5HE3a3:&=Du.84řGb#Kjhz$/z[U]R $~Fyb6H#ty',|\ǟs&eq)s~ͦS䯠cݾfsrF#8~ƒ][k".Ѿ7xm=MgYR yX~j7nsKc zAvIn $*w_'3\5}J6ѧڞʗw> MMćֳ de*vmQq4bغ>Hw'۪$Gx9znB\B/P`fBvWe@TeL>UY߆NP%i[:=_35q38t,?z&-6;'bbdX'2(o{Fź0)1"鈴`K+[ybr`böHЁB藠ΜD0;#=t65*L37qS/#+/5xPs \*KMVge}r'gbo4gX7qğGKFK_TD"ܭ͎(5q98gc̈}J0 od7~$;?v3kaYy#=) FC1*'qU\ їqXDd5 0 fw"\CX|/ߤtC\e$F;yȽ/+ܘqndzvg£G2EM8s%0{|"ӋO*Zվц:rʞ2CD 1Eh;Ť0tdž R3.7UY`Mq{,. \Y$nʇgwVpt@| "c& %f}bЀq\Dذu~~\Ca]ζp/fn̏EdI`.]8i+sƭDDsM'f,dž6Ɛ_D˩nV!<wIH4쓑g6UM\&"lQh΄jK/܈cd 3#|%M/TGWl,,uԵC^CEJ^A7 NkQ ]rEgT>g(T]N!ZRNs@hbH/>K)ɵ= DŽ52E1T]C.#TVʙwYi5'H]'ߞ*Rt%]=;sMyY;w-{UDKtn5N6-arG7o"d.҈i LJ'*tt!7">;31 |0{z7.\gOox? wcsˢ&= Lfg/Eg7ba*,D{]ZF<$1ب֮:MZVz@$QW "&ԬAfᒂə~D' iՠnj{bYŮޚ"~k|F$m= *{ jNF>R>a0`.u׾ H$ $й] 8so2!+> #Fr'Է;*dEg*PDL?`[N2 _Wc8Y>n@ʣt~ ȉM8t?n+O#"nbF6n+䒬m$ [i\Xm+I& ;g@\5Eec"߾aC@/ܬהBn 2&YI<F#m{֠lU[L:KÞoSZoɢ Y.o}feyd׌n)am_4EXKGvyc8 nBZq;CfpeHwMr0ZjᬸLI{g%7*L2)2y]FbqZ%n\oΔ-w7~u0SFt M=)0r BKf'jCwšVh 4&|K&ҟdJhe,'̈́=yF^x5/Q-l3^$Ťe$Ebi/]UI/丷|` P`{c.g]en0kѼ k{PrT$"Z|]Q5 TfqVj58#LhVȦ~}t8ȿi7Us)ѕPB_ytX!~x/V*z+%jHXk x2[*B7=ݦS{ 1?3f?舸-aՉGL'@kB+Xz oj]g ]/nj-[VѹnRcE{(̏i\}.i 3!~"cs?}Əw(JitMȬE|#!mw@;HUX}٧=[޵?AQEOiptg'e%F"<+nl`0Sک:KvK{ٵ]f}gY˫㞬V>66եaQ"/l)Ň!ss  dXA!r?"{Ku aşE\.aZkh}-s`i+]B)klm~%ԞXmfs8}4`r~=s1y@UȼL툭k_i 2!|d0Z@6U]V8V2+ ոN*l >R}2TP *ȸoD9kzirx89yy@~.3L(_A>>*^ 1@vB^`9\o@^.v>7 e?DWeGoP';nvn/'DCAI݆(Bo\; fW|hX>142; sſYAaU 97b?aap\u*|o@W-Tr%y  `+[H, A|o\s2[ Vd?=71NH c$yځ ~WDX^ ^nG / @o q"A`P!¢B"1߬OV#9topu .;? 77oJ\>vpzoyޘ{ko*<[ qE&rs߄\\ ?Ws@ᆤҐߪa:7$]N?2U_(_,oX`F;;7PaUqRNbs&v Hh$Cqm^?M (߫`u 7\R|GW}:.RN>ݕ[9U3dW.~ՕP!*nt<P7<⏮2ㆼ<+1Fb=vG[FxoaܫaC3FtXs2¡Qs)jcrE㬀PԭgLw3Cq?l4j,*uwE0hfdRcsvmP2im9J۝>;x=ן$Nwz3 ˃5=,f:grQ#ԁu5 pVI/c7|`UnިQwc>m ن "[yavu BҊ˯Ryu%^zI4Sk#ǥz>.p+Tc}X4%nGJo'e9X%kh{S5+'ǮzXLO~"ml/MrI{*W^eGV_O@wǭE̹'#:Z[%{eC'J䡸?a9^WznM%6OvqxW~:l.''*5ԫ&_\$:؄R~o,}ƨN8K˂~L)wB!ڹ+[´X؈*y6ȦLi:‰-v Յ5.tiץ2i'4|[hXv5 lWݔB <1HrMNZ2K*["϶mg]Aix LM%όz2|Y8T:<@[z)-́Ci4hv="D##wԨLf\pfo$"(,K3~Vi9`M# }"2ۏ L+o۪m7wc1,'4<7/߿4hRX&x7ό ̈́dAa0wђ`5`yx)Tx Q^*f^ݸ@/oY&L xx|0޶h'3(A8TofئԮ`DSfÁEkY~KsWYO7"HY#aؒ%*1|NLD1^JPS ^ 8_lzz;91̯ya>Y_ql~zy:6FQ' 8A ղg!hU($p|A3%8hu|^۫Su9Q̲_"9$mJvʼ(l^CVgQLN "A 1]]{ǩuEmh۶mvc쨱dGm5m5i}Y\5Fj$chkiW]NgKVz e#`+K4[Ii!sH(ɲ/P?(Re8~H^FwHmp1!sp<&pF{/iVC#g\%]|>e+"6Xb-!` DuV 5/Bl4duנŒ8Q5"e4`p!bt2jJqI&TSjmX8dslB^Z)9k9gYiDQayRo,îA}b'7Lv_$9u|uj* dzFIn :E2l /1MdruZ<+-JB9fAN7gkuc(mxQ]Y~f|tS{y͚>RQhV!e/"\ձ 4p\hZ8G$^߶u[_֡6aA Dn [uQ-]lSF:Stx_I&kmb$J)CeL0FDo#rfwB?2y8hyT)v'o޸`hpINKPT6W1YpG<w~L"y=)S!Ա:39a6?!j`}u[}(q(= jpqYؕ t;[Iz_\ޯd*͊B,Ѿ^ʉ+(ם{rWvjE6B4?(<f`Ǐ`|F'ĿI#a8P]l(Gr %@ D/i/wsz"" D5Uq^!TЛSMDb6Vlcx.Mj   a!8@jtznkX˵OT D9r.!`zKWB <ұUfO7Q1`WӮ]Jq&dT*5iߍK[A=C˫}z.KɴSmJM>K;t ˡސ63%cTւew߆J?+f-JV1GҬH iGa(3T+r|i'G+s#P^=J5Jh/væ h~TT0 KZsclsް)X}uȬB!U$.y; 6MP:<MFh I`}¬P]1ޑķd0cǴ] !UǏi@7ic}wF+Z!̐[Be9Zn={0Ŵ"t~%`;9uQRY /nHjt1a4r.Lge"=GܲQ}ҚMNs3SE >*>蚪J_P,'2c: L>U9Έ~Ͷ'z &*%VL%ž>/ H=3@|PDcVKj0,C6-/G~+e0ɲ~I|>1mVH{&U o veFtp~etwwgg1O4Bלr6-x先7߲6a¹Dz;a̡2;J_XO2x< 0"tEkFkd#MFJY4 Wq"*Ykn8~0@r)!(B{KY~>x3F,5?ݞ*Bɡ By(bQՍpßos>v~e`\)KQO\S g)gUswB9 4Imy[9 b0EtޯiJhݴX(hFXϒ%븣y 菴M4ЪL+oDp&r+3; R"1ڹ;'$dߖabiKp.`GuO4k % m\Q4K۪yƟ26=DŽ~tzM_*xGY}W촔9;; > Xx8"4̬"%_/ȬNb6hB_f ?ą>*08B=0\AJ7Y_d"KF!C:9%$) )MXKH"loݟJs@ Agȼ*u}:y6 ;9r\X/ &Um)Z}+5uER>h SHyS: ql ;PG\ 2ۼ%&Qғ"WtDEe@;J/3 [P$Џ]S"䰋 3顅`EOQ{.Lj0L~sPyt98D!X%kA%r\8Z͖'&&uڰRշhQ d-H.>hyiߛJ!ˎ %e``1 2|QƳlfywiwG7Lo3|Z.J7ϝ7h2 "_ 8&p闲͒< w#I6.~^q,мwjHV&bJ[u_^Guu2JQbR=8 6 qːWlb0GbUBjHReF}ȍT^ x]Z~<y6e7ĝ33<8Ks0* fEj^ِ5 &);YBz5>| p w$~4(gM;'{VmG\^~t^xL0v,}c5V`zg=gznӪ;u)6\Bt~znMMc8Åy%΅(b#I5y J/ul;'$B9)R j )cW7lQ0?b (ZJz5"5O>DLU ~/2,RpGY`oB] N(g h. t  `A3 ";7ȥ:pc!fgffg$dfg!egeag>q%s0{K 8+8iasaC: kܨt8ȥ }lm!W1M wNG= ΁W䛹if}xcv&insEprGUæ}$hS>lIa>,0߱ m Vn 1w֤1Iǐ,`]msF0ီiB@#_x)0{ݘcÙaR&4I!-,t_$N& M?g./q9a3%}kK)\bXRʺY9]Ap Ӻa>+uoAODqWm(_ i$=<NyXPP4WfUrZ]zsEeydgJ0 PMsx4l݋8ߡ^[~I6WWZɠTj7 o;:lcMTWb3.ŅoN/,}~{ WhrqSETvF38z2KWǚę˛=|XGG/nvl*'9`$m9`5Wܫs<qHTGmv'_kmnᡟ{8p-5ܳbLLz`JtۧUn:q^PUۦ5ȉNĤ26#ݦ}zN kz) Ζ;jx!2qÃvyWd[ā<"f&k`IEo`Rxp.FG(C;KUI=Aay=B^fIy0h!`*œvl2}V (`;࿃rr∎mQj71b3րaƢx%i$5ZT 6B? Bg$|Rd6+a3;Z<šEYDCl $+7/2~}og5yuc*lo@;2e"]'jR}<1/0Ím0s/'b ."b~VWDaٵJi7 b'5zV;:Az o _}jFrPIj/ayKI]UKj&Ҋ [iA Pz Jce OTd/)Q 譡~omD;VxڥEUя~H0d b⪑FD2^xRڔ ]Q 3 E=ӳ&A<']Ble Uڂ9 :Pql( Ǻ4EĖ 2EE MjsT'ڼ3_XuU }=R] HB;I!K"-ufU?Ro]/Vfn?8 /$L F$P45 >?-b-,=%J]ltAHX m.ncgU2AXcm0=xGUD3&]iz!]h)Inܨu0!s&JoyvDCHCP+E;YO4^jǹ_7tbPn\O58Ti#.U/)/7I]weouFJșh>;_6X)equ\dPS6ٺKQiw=(PU¨]$gF)v'^B9TkRtm'?T%}#9%MrZXCyA/\Lk ࠇ Ǔ%!djF]PEV~(4DSIOL_Sԑzi\D)cnLDp]ޟU+m7@)l$ u塶cB'{@iNz]t'E\tZЊX۪&p%_7YƑN").UQ%#ӗMkV s菍FsQNƞ64g Cgךx> j/\>iQ4DIFI#e0l`G.+/i`עd=Bi+ Tɓ-Za(>C++F ;.xh7PDd6>M5Ј] `(8GvBhd6"Zf7 .T'A+дv6I3пWo F/h~=|2 Yp p[iSjg@\2~N=<h{-@^Qap߄!}mDC稁dW3_D[UDs"pj׳RZM5} d5qGP2}[Cfv5`{24qJR:h!8w4K..p♌gicz] ѱ[S5 8zan\QJsndGlڐ,/ZA3Fl3, CCK\g'ۙ H6F ky`mDrN^>3iGB8Z[^ƘyWǫ9 ̃*IGcQf$z⿌|Rfm,5-/\th~Ž6IJ%}¾U _ 8xAl9rp%XBo_Xj5hTB>fVNR6^f^6>R.V>fNnRvVVfNv"@NLjbC-UWzLL :# nfn.>P?On i#r@o pN7$Wa\FTS҃\V\g:k/%I.Lz3a=> xQ 5siDɝ|.ԧ4Evͭ6KyG&UQz3)L-]MK[OfX<3𻧔cZ;t Umܝ_fd ib#Fjluz|ݥuFN.6כ+e$K ~[0HO]'ϕuEs)C vT$a`6~&͋!KGhN"8Hͯb-=OG.>vꃓsN;~4,mѧ4G:RLѥUq=T!P2@>Gen,8pq6M-5\M߼(rh;+y8miQdkHO ޕ/D.j[=6M0;'@´ )`8a4,j{׃@kq%g99rw!C?658;#-Ŗw.AѧVƪo}v%' -uGX1vkk-L!VZP"btyTD#9n5Ϝ}["p Ttפ*T&f+R}N}g?1P wB| $b qA8n8H[3:ahҸ6[Y_Pgv<apo1&YDfPb[Q!֤ S/g,K' k)k,[וqew9uV+lEX'XL~`95$ʆ_w`{&*lt.-U`r\ƊQa%@ߖxz:lUw8I΅uokC 3XwZ}3X$BCQl>5",}T %eH܈WJ~.?rO~<bsaa{BɜtضA!(? fWL P"@ON!=>K/]y:h&9|2 !CKelQ[vЩ2q)28^0* &&bY'Fb 'qN@d`'EFI"ýq\0/Fcع5=@iZ`y۰oۙ3͗Ѓv1>+y:=}Zey,VK31  +l}U|S:M m<gE:nWu.oQI~SI$[2s]@XVSrpt6m;7XMuH^ G?Z(Ǘ^˳si6j?RzaInT/(EZ8m [)\'݀ `FP{rѳ)ŽO Si hZ lc y}nͰ{ Oԝc}JV)`aLD+39'y*zS}}~ ׉=G[ocNtDSQl)Ll)g_U+jLܷ3%/Grx*rUX9cQ~@ ~Sb||YK b)Fnb2{UAidXSٗr3ޔkg=y/?\Rn&yng]^XZϗzjp^b~HH!)S -~ZF]ΐ.S nbȐJ~ B7j L/XPO #*íX_oZv&r 'HdJ|VR ᓥhmS"ؙ喽y"x`eS1b $m+NQ{VL0R3M *6hFXӂ`yڿ?;#'v7&7O;$bJ^~mZQpr7(v*Id\ڷ60X4 vyIec3.:tm^swcQOgxkÑȳ|2UJ&ǴĴnePw*?fC #/YZt+ncud mĿu- N%Nq,e7Xx'4 A>#*n9T+# NI{&b6ނfH n9YQ<]ޞu9ga% Sc^:`6󎐺X([Zf  fivUDQ&z"LH.hoD+!x_<+>tK y}3r4oȜ~7 Q#/WݑKiޝ mXk^_8Xa&A2.)oqNn 2'e#SEzͩ*I_Xw Tj-XF21er}ӣ0j]ߘI'im 9KSӔvC{v_A]M^9\Ϊ< ruk-֜ŀ6`q\)%2!F]ΓL|jfE- "ax$nbZxl" 'EjL~\ud@s]:9A fwNa+M8AF-qAِl 2(j_ Z&\Kz' db$$:+-FB8W:1>me\NJfrzrz>NK Z&E=9L. a..Gm4*%O;-'~ק͛r2Wss/:&~C3HqCkRf2%es7.;̂9BhzwRo(CkJ<ˮ7gc辑uR(q+}*UHSK6 ^w+`N*pmf;V.,dNLv3w3S1}"1/])/!2}CJ4eK6>wDTi\u6E/gW'3%3G.E(`DftVN¥CS1ˈ{|adA7Ad9YK)l>FR^p xi-$> և1ZaC3n[B)TG4Bu L>Qټ5O|aZQJlv< 8N_TRi,;۸t&#T5)k,zf&ࡏAh[]W@ +D+9u2eg3c>||HE$nP2,"4 9&pF?2s: 8Ӏ4.ϒ'h_)LGi_?c/ k_[<ä2XXdiFf#Pl7·WSJH#F8X~nk pҳKU\@]|hr|8Y *|ODqdSOݿƴ/ ꖙGi^͒Bs9cʒa5r'nps.̕ r. ڸPiRdi~Y!zEӾ1ѩe׈!w2f> -;`?/4z<惹ÒYUwDIW?=Q8o q@ LT8NЧ`իHⳤJAb˭E撻Wb%13g.rpTRX?/۽EIi.ŃmYq5t\IB@^\ԹLXgeaM YG( 7(Ekph ˂F{ s mfQ6Rty&NvZ'/P9}>坮@x_+rH t 7$zq hn0q6PJ߃sx9$ b ΌJ4Q&cc ןaʴ⚼wx ;:=+|1DHٶ8?A"=dbk,j/\}X?o[;~RT:@ +лK˥j߷xe¹NPdϱhL. 2q̾;ӭUecЏ_;/>;̂ ]hI;/DqB2tB\b'[t~Ig@}_a wl;OfM _1ʇIRS'Aq9inʲǽk+ĉEp%ߺ&RKGw_1U0`xCՇ%>0&e#$Hۘ+0Y)cX53otcrƮ] :Fb"Ŷ YUPݵd M~/JAv&5BQx6<'E}fjD+G Vϕ# kО8Ξ,$Oz&g^0?.lUFkGN)p =6XߛotDޝȜ*~1Fp۷G 0dWGVE@|fKR9w3} 1 х ?"0*B&wo /~ 6^$!h< T(kP`1+>ѭW^k=f,Yñeizok  ?뿤)_R"FWrDgx\(ӈ=РDVzB.fNV.Rnf9\̼<< g4z Rbr0s ee&fcrBSG dD쬜IX99x%0rrK*O(p ${gB !egc;q;^}g@{cP/w3S&P"'$1(W\~$(cGI[ypi7Lnjq~P@A:Dp6P @$@dggTY!a#G\TDg7nƁ4Ȝd"Z{]hQφ&WP[+y$EZeVAݸt˚,uFby,{eޤQٙW S GF?=GNҾS]J*kFRx9OFZCEcd?6 M] I,XthNJQY`TOD$?oͧMs Z*_L3R|C /[_W9-iv\d%>3 0))^!Hd=ᛧ{V3jLQqG(Oj.vDR56ߤ> }.uyNïp}Xp}~R 鯅!**Kz8AX v O:wk۽]QI2aܣr@x!ΰoq5mube mbrrz?x׃}V Dq6II%9 F U/n` MpT=6(kPL柞ZYI٭qL<58lXZtcwxmG+8oz$pqa xÉnХ(iaE>k14 LT*w̹ SAX߉&E J{h 6RfvJ >`SoLi,EZO1ьyxa$X_1t[()M+1uL0 So=!A_}9W}y%ʂH[Z ;*{d) tgߘwymvх}sD„VP!Hc~V_uq%L0Ib @>kNѼ!Xj<~АTc)'AΧ״_?$!kIEZ j$Z?=;DKS5%$n#ci?I;KVibh#-0d /i_)SC3/L)_# hRS <lld*!Z!swdNWJ[gr Ӹh0]-6!zg :lWGC||1~SHZV66$+[c -jiye]'Ynm|qVhN||DZErZ|m6y|qS3zʛ D@LFWGj)Vۮ9#ߵ,*#` ~yU{ߞ$VhvV(1MnNh+a+o^@_:}%vFV;. |ň5s%rX} d&VuWLbơBM5 ߖ\y O$ƍo|~SF5 q*lK:s^ R4[m}ȿ&a:hrC7 *q Byor1K ^z=_!+_?{9KbtmcO\{IlsDȩ Ok\W (/M!+sR Qȩֵ>gTS͑K I/-z \TE,1ʊ 5tUxLAMQ,# *Ʋ/7f: ?B$C)&ߖ?t0n]M# _hCYS^{dhS_|ˇ-] '\".w\_7۳]v~RDڇ~AWA 8ެ޿>zJJ 1(+v, _ CSb0F v ΄/88e! "02() MH̀A'wۺPęW,b %V3Zh?+_0/g:0rКf3֞Pu[JC۝|a/ T^$/!)EނrYO=M.Xv9/ͩ3W}]21Bbu xƸvۂ&}kDHSO"VT4N#K"RmT1BơnvR+kCԄM}-s^<ɜ} Gbؙ=4\~~\3zFU&VD+̰udM$l LHhŚCWf/]5WZYv;WĤ]XC<ɜ)ᔏƂj$ˆZy#ei%%ہ!ehvE;7NІ]XR297,Gvz*rs$~/ Jfǃ2e_r`( #mrN W﬉r]# >%2n[2n7U#<}4l1N&?͡YdV<'!՝sQW{ cmh1 kL˅A5v"#Ho1P8NA$n}I5Q?4 w ^3'ʲ3y::ғ! \Iײ%HC3oz4-1 .0Џ#B}CeƵO}{+IŪ8{ |i9rzL:LUꎍ#p -_xm贴[W/7ץ(O(SވY/V'yF9n z1!Sxpw^- %>rg~#hȒrZ4 VxFFW,|KMu-M ~ ;ws Bъd-v 'ސ#Es VT*l2n=>.2=P („z}8nQّI%VﮑM׺ńPBZ1XNIqiDXD1:7&Gz/Ur1UY}O0xl 1, ]A$Eh=}؅[bM ZgZ%F ߓ|2!y;٠{qN꜕r$ihZ)? cT<u#N!_^ID9MB+%O'spǒ2brDt2S| ޮs lVeh=4<#:bqzW.?{>/%JA~}k߸QgReujw|4!9"ノ1hNUsWSm4Gtkv%g;>2 #'/zTR>nYӯ޾JG_HsnҴylMIqzU&4/u7abc=J̽; %ZLN޹2h|u`$=CYt\E_# MCU\3ڷrC?:N0k|]s"OŮ٠'/xZDg(Sݧ7=oR忸չ`4;)Nvjǵ' &;=VƠTw#@oWW{~ӵz<ӢhY8rߕxQ:ʍP#f_KĨ+Sݕ!'Fvq@!=#biL}Q`(1i~@c9LcWعzt<~<+ƪ;{D&d\rz88n"~l^hl'Ke1>xh~ފ^(MrB;K OI$Zvh~dH&cW& N07Z-i2ZcKhSqb[qRKs-;m*6H? r1\V xv:)Ϳ}|aZ7$l9)qmwkHIܜ%U8r9p{庥4&bF[ii޳ؖ#?؍81@GTo$]ϣmz,[aS9˩_7-cަW{MEHڒaw$2@> 9D"ary8ByH{daP&e 硊\Ăx$XFWGde 'Jdǡ@IDHRw!WSqh$,Z 'b$䊂`') WCL$" .Ch lHKPmJ <CÒe(#` 2 _ ` ebAYf·e(QP @bH"Pj=-#CL BbaWPbgj010œ1!xC.׺MK8|fv{VO]NWcclN'(kn X,)$pƀ_&ʡalm Z6kz'߲' 5PK&V{| s aL`wn)@=֬,ӿo7|hW$qz2Xoy^hi>Hox%$ rx.j}''5)jΑlwjm+9- Ah,Y?`L)rHWZg1e"''J٥b9=OR45<_)A=Ī94f`T*e&n3K9WnS /ȷ%Ki2u0|Y55h'oI]+,K]7)25'djgn1yW=*]NS8@v'ޮ|rn &փ'  0n}#xFPAY c8o6_F#5In;eCαªWs(qI=łV́%r-2WߊWoq* f m"[:fiYٸo'>ZY?]Gz*w & 9.q)>$Hd gKȻ#fߪ*T\~htL}~XػiڙEv&_*Zaoshz\.PӢ4;mN߬\5T0="{6TnQ-{yt^Qa3%&rjygAWg&_岗K`* D~ɟ)~^CVX90ef\R4t5‰ŌWh5 E14'7=؊?`nN1$<=q-h ~~|{ļ? WɊӶ+ZB ;Έbo,q4n012k Ѵ_s)ܟEfvvueJtn)* 3 ]80bFzn8K[:JsHA@Rb29e`CJT̗S쬏Z]SE;/- Z׌Kōt{="c!1.LNMw H2Qڞ O=[AojVllY]<:fF^$~MWSr/-2sLV [d~C'TZـ'`~->Ri%aL@ H鏢H$cq; CwvoAUM,m(hg8eo %+9Xx?]EE%"Jt~Rt[xugcGOgb>Ԓ62+cc$6/j7۳> yn- I4)\_۫ןS}D(jYKo6 ݡwWOwP/2&yV%BiRcr-͍|篵v7čİg(1'oC;~ OeA9arڲ!]pSacY2mM yhZqr^qӠ@ #/8GT`oNk ?vʎn פVIآ+u汞o㾜^esd,@K$l4bhM^vƽP,؜aU~[oN mG0^CGFy܋ڊrĀ VUh~pJD6ܕtq9ﷴn}NչowMԘIT]'m$<"u`Ntw^q-n!>7a65eӹaQ*>%1:aKѹ&# ƒ9O:S&GD\VCD璘|1M)۝[oHmty::#D4n Vxy/nMG_lđ/YG!u<[pƭ$8Mk,zeFÐw8V >3M;F̃[]b_d,1nA;+^ ^_eeê̟<&|Tdg@Ց&xoNSno˞sEǻeQ|Fa>S&QU{ ǥ{ `F0/q26v^bFN镠:"k\0F[7ѯShoZڜp\Zz;S~ ~Le|pd.X g愆:sOeֱ3=^e.8,ЈR|Wv&뾻a3YwK~|naM¡)ŹuCʄ#[G- xN;i{ 2nH)m6bez+5Y?_ܹs.#YDWߣ'6M* tnoFo_Oeq֐ճ'xWg[Ů߹[rC5iyAL`j%dS:>FdO{+uH.'c{DQ}"S}PiV~)0ruY#՛%~?\EYd Zv o"uM*']<{uj E-k8W~F+w2Ţ~jAK{bearNr Fg m7CaT꽅(SͿԧ Ry:j8R%{FfwHfՑF;3Q3{ zQ"(yanejWSpeg"@TxD  Ɋ&IVY8yyxh CjZ>;"Ú9 WyL韧jhY5; ^rkKF Evd}'/< o+=ܟ3Bs#R#"AVz-Z9zĴfI~qS#K;MϽZ*a_yI9\ ;Ny?GP^~w|ncjZ?xf0ږ~:|m(o+oAOau? ̏>w.,EvDx7׹eN)-Z(Gˈ^[\]e ?Qz'-k Ӵ}m~cȝF6Zs.~6]T,ʢ{RV}x-p\ʥ) &}:f3?N?z  @!-$RXjHaSy2`6]M}}7Ok2N.\GԞG<ȶ#NJCh͝~-*^:AyUS BZn(>? }H1..mnFVsaQy'qw#42DoFUH)=U9~4"рnk@ICMohPI~"-̎]M:m|mW|G&a4VcĆ(O ?1u̩39kRGa o03^?`=8oHWl~;$\xRjNsƭ}&sg^/i}#_/)/Vo -Q4[!\+ҟ~뒃RZmR}ucC;:?գ:2w"vNN5=QE%X"&T%-b}Pw.޲f4?eQtUWg/GѻŠ QX Q. L8wݢr[vPڣ/_Z7IxwD#f3S&q &nT/AHa( R=[KQ4()YL$ME06^ fe @ f48A ;HF$`0ĭT4Bj%3?,˜!wvPʂٶ6RǛȌʯ)oȐFf͗\k7S걂4}О&nYy&T}Ø:r xX1lDzY\(9#K苩ƾ1DL AW6:KCsѮZ!3{V^⸏gpٞ`8?.ZW`!/>!+3N8Yi+ĭIО.z*u[_/o^tUfBeVllþα;v:U 3ՅeMWtKi*gW:+L/nGwO׋ZJgg$W2:_pèׅ<m<vfAcFxgFԇn~i?֘ٷ7Y>|ik\؂op x|VI gl>U=|!d 9l7ѡ8zGd,skR=9t)k 7TU}[ ᓷ)ԛ mIG>S N^q]o`&>I@[>c=,:W<篇nC<~{ۗ~QTM̺ہgßlG 631h/{d8|o8~46.z)Ul&j$D}!zB&eJJ]7~Òn=d0[OSXZG2ߚ\v#˽yURԃ05Fs_ߑ |2؈rCce Nou&}%cQ%!LQS.~ yo L%ٹÂ8b̳] G}A&pWw`Hc9w.'3NRhE%AGnSy%G_sH4\+m$5/hޮvmfmmGKx*^Ű7&̝+?Z{cr%ߕdK|K%-/PHː[ouH"^cbܦ709\[\ Cc߂}WS00/*iVxW.*0IjlնL&%n(}e:䕨s7ffV 8>đs'(:#[ykJߑ!tz-ݞ2f࢑==S\ǶWwU>+TRymǕjG:Jᔅ{ M"_XkE ۅfI>!>%42#fr1(mM`Ag `J)CANlRU5͌o8JR˛.մ,F׫?Eʡz h0OV";]2GumqL_,"S1[#n8J2]{}JAnBczwD"+Ňl ^dNAvv]6 ,/Ag*ATqԄI,YV,%tz(JBǨs0Ȯ73~1ʆUI.i\rTw?lJΨ^ᦑtGfW?xT=4xg'ző M`xCS"Ce(Pk-ˡr хN)춍Ldv|H;7Rs>uhKCYsq`L% KՑ qM٨ V'iUcijQk2"DR@S#ƙEE;REħgDKmSJ-ӫf o;idANSQlP:>\ā ncgX׉V2C:ߕ!pڱgWd{ĥjYJUF۸?/';C~DOo8jԯہ"F^닁֋ې ÷.r?mLGe}nLf"jRů Bz1VOSȥDzK2 S_<}vcn{MB!_\Az 30q &,ݾ1&?Xl]1soM<;%WjZn]V*wbKv 7cڢMw 4s%VK;<8jd_cKϮ"Ʉ,ᵈdvaZ-~Gr8k }쳄Bb!G|-'3Yz>3k9>7 9\~v;K?7SN4N~-sŁ'uF) Jr)Q;+;$Uv<+xYy[[.$Ms1aOÖ]9l2 WI(>z5?p^B@fsI(d +C]sI3$q;u&\y+f4VKNfJBݿW/ڟ Igxnļc(lB(OخX5WB<}TL"p&STEv`ӸRpݗ ĵjd3}FI&6xlUޕ" 6iAb2C1'%ezev3_oJSFaz/s!P "&ҫ]b_=\P:jw1n!i}BC(qe5iٰyE7Չ5DKm2:Wkm GƇ[v:wWsouc^T[o_Eɳ˝4Q7~AEw;/$V&J9yS/o1ߍ^ vz2; hO:G69R^< ZCiA.>XȿY&ކ* (̭aRi0n`\F ߃ )jⰽKHOvBQ5 !:xAt6 C$U _HCsH'BQ<#o12:x !)0!"0D9O6TAIfqHDQ aL Mow>gZF ?ߜXm \&D L2}hqv8:>j=&lG@00Խe',`,80 S01 K F7 :aF|ڿgH!H4kDR5UP6$lH4/0se Hh8߀Y~FXB7zU*RD F c`D6Gu!^F@`? K}(`Z4.1GAEW08@9w*@9'!Xٽ6U"J"TFK#[-u̡)b!U;d?gr?(j"UԬA-l'0f KqWlà @-hJ62JFؠ0 d0f wt2v=hx0k`@% /qY {IܐL;>$rdp{K7t8;Pqq|zAw^D}^0Ef{ӓi2=${:&@w1` &Y&`4R4NvoC\%ZHf3U)(1]?!{(o\p21xg)|`' !$p{~YFM; :aS6= KH(̀,̒TxI$ |0O"89'탠TA*a]@C4llt2x8 dIˑ=0=ȏ# b(| HZ>.::a  #~IQN*_`{H`dQ"`*ZwP%0@J W?=㦂oO ۟ xuo((,:%bJtK#aEe*_8Rږ`n$*2,2L@\j*@NNjpk`}X0{y~aQ*%\ bdRyIꦂw5TpPGϊKWpȃ` {08Y g_83< 8vU^m;:@ Z- &NC&@ ?Gqm&8-!ƣPa"n6^QTû{& /&B xD}VDz~n b|{/"O+t>BӵDzK08`xph%H+ 4Up1(Nߗ3O!R܄| ؋mBp4^._܃޹?.?$yY 8M!I)0A-#x4 x`Rg%Q @&ԇ( 8epp !@C H70~J{ |~pv0)? ("`cDN X0%8-kq4\ȫ=bYܟԠR"7/q\ 4Fj (AZO=E L4 E ?!lXğy~?8M(1'p;`ԁVaPSiA^ڛhox>WE^ d97R'?0b R4!pE(h҃韱&;|#3~kK@ԁؗ@ '>\>ۺ`Ba{~ (AO*TI w!?n^LZO&ce|VvCipaacN%8b'~C;sgsPA憷s0|jBxw:.xfxF [)Uo DGyP(A-,|\2 +G\@\F ]' 6}@ 86 oB1gQvesDXܻ+#.pCVWQ[Gn?FFS*78/(s8P{P+{B'bQw,  ޠ.&%dA#1Bx %CVvu(Py~rݓ_Gl1MD4AeЗ")s@/Ýȁ`ShJ`nʿU}f̰}8y9JR ?,.;Im1C)DЏQDOFzP r57P11 ;$^{q JQf', 3 5PH>%bk`R? \{- v <bAuXbSi0b֔GbXAZtݠi%Ug)M$mwG9@_0 1T( )[Bķ3@z<5q4MRp`Hl݁mmRmWw9 >: Rz/ܫ aW+1@jc3xD9{+!f`|h bSĎGr3_&/+/A99%^ (4L^K ;*ne3pRfFĄw$ Wk8{YsRK߻8氷O&b$n"&^[դwP⿝BDV8rE] :tD)S%6_X ݌ O@3K \+'2LrlPRgCa7pgsLbXVQ.;\B  rF|!.c(,/W8BCluϻsۧr&u xh<U_R˱ L ޏ]f]L.\6%|}I^_?n3c6j7_`p'*V^&,|XyH9dv2"U40.5ΪJ2 q]Y.c-;hrnQb>U<71Afܟޯ@ZGDRESÔ-_߰$*= -W!q?j]yj%!?qmh8%hg6U^S0G>H_zsيZ|NE9>;O͊^lΙ|~Lǥ}”P˒9$5ֆ<8R wեUnL(VG(u \h 15`9e{^"I!K̮ܔPf~C{гoVjI"0zf,Y֩X4e8iwLű/5MTE\bYq$TCMi*bhdnstShֻNo9ź@ͲsKc&Lpt0QwǮr۟Z̸&~-Xi ݱ_V=2H!rvRܪ.*:8N5vQ'DVkZ D+F:w>V+:[>YG[Rԋ(G.Jm?/;%v})NR8*^벓Q\ 7z [wDVζU ?'4~"6*[{|# !v)“835~U8tgՆE-Clas/1¾L%^$XReܢ[[@:XPUJAQi%`*|y}3q'Ϝs̙=W2Up?Sk')yKU׾祻 G*7ܑX ~TEx\ϟ6- DiDXNH7R>wv3S7=S7:sW(s= І,$4hUJ~hJب_EP(m6 ml^lτ]СT^T^Aph9fGRIБHqݜj=н\Tʜ\_/E&(O?^N+WSP4xX=ʡA5)6hRr|VgYT(Ǧ+@:h5u(MPP@Zd@Kyu Z'^{\"ɄS{wYiy-yǴ{gj5YQcLV-xW+*K4&-N7ot]vo4Ԫ,\贂LJ)Zs坫Gwbc^d'ڻsN5b-^m׶؅VVmox}"b:wǃwo\}\¢5I3 G̾^kOj~2-J9wDӏfWcRe]L>k;ҖWJWxZSS>_\hI.߾2z|z_v/s,Y6[ȡn^QFof%h<1U5Wm͗ߙv|W*U]GSot^T˻95s\rZ~-d3+lwԣ{-IEo2 j]wFoZQ̵9=p'2NKۿG kzxx7-|-coT+5KCϗSqYkxӵ@ʝK/h˻γns9+͚u2]!,:JZ[r]65Lk\j=3lXh5F\}]\Z6mZYQ+>a%˥5op 56]̵a}'4WW9MolazmFB>lΩXQo[<ܯcJ%ï#ϜHijNq!/*S叹qM~c앞%44%قxӺmGloJc|r?].<,jVj?t!_nﶊ?.6a1'fs-ɻь۴aBVvo ˚o>h^d?"G퐪ڧhu7^q~+̭,6\V)S|ƨg!X'kĺ}]qixMW6uLSA2WY gޘ^sU 'U.\E"z6)3~j7ɻ.?v*~[އ=2gt}ܗ۵Y5ΚY3Κ{.ٴձ9}7'8dحUFikN,9͸H\uVA/C!c}0oTsnwL~qҊUz~S +߲ɨms;̮_R22ߦևJOK  |~゗G#_:nz\Սo,7].l}:q? 8h-$oˋ?vi?o:n壪kNE%b;,A7U1`AS*W߿Y~;S툥۸bJMoL311ϽUIcfe>Wΰ2i%=?eAc[X·ܘ2oubs OƷ7riݳ^oZT'jyվ<'揾61jSL]y6fۚŏfTڵ7g}Qjukܒվ-XuSk,~3ro&>{b€Oco 2Ԩ_6wPnW|Q\~y>jD9w~s˘/N^[UnyipoOV~q'}6/GJ޺pnW>!ܖjy[>Fo7"xoGdSѓh毗l\t;ԭkY;}񩋩TKqeo-Vo`w&[_Oަg7mw[JIj٪n6gߍ6=vzi%WM>>v]v궳|*eo_cg)9&>sk89衑pP[N_ao9*qeO(#ëNLW[e%+ZMD4~9 GJCV9~+ıնݼ˵2zSNsw6 _q~ldr N^f՜r&5u߸f֥kM*2η7_98R(zgE ljӎ~aiWf[:L4lil Dwp_ehĞSOQlꐿ~WkrT{U1ӭkHYIufLQJw~{[9v=]m~VUw<_(~ɩ]F\eԦu>9tzW݋Ms5.|t{Y[M;Z`/oLwmbþ>Ĵx3o _wP]ԩ^װ>G,/ߔyـ ("[Ce*_hѴa%k+x4 NlhoL?O"nhrnmKBjm]и~cP OXpZšX^~u GQ)5Sqܹ;1p6Vj D C$ ]HرI,OлsOc[SmMvf)Wb Dךk1 \K}5;-~܀&Q?ugJ?fdi;5턾/z6xeg;~ 9~{xm2Wse4W53 uҁ古?7K/YޥݡbW\]/d?qF̎Z%e5.Zkt,TR>nn>>{`nbsuZReְ>?]z2Aec\67V|3ZmQ2= uO8s(lAb 6w-o[ }.Ԝ!0 go72֫${.㝑_ۼKś7zQsC3(myVndӟà)UgT]z܍<-*sV(Y|SŅީ?2MgMi1/϶lpmRAzFľj߇[#Um^qy秩*{Z/4&ͧE:+T-~edKw|zU" :wf+pc``όm:}ӼTeĀ^֭n9~o+0˥\;[rH4- ~>kR#gWOll!Or*vJ]{GOl%;z~gߟw:ـ_hx.? mܸ߱ǷL;Ggs^ט__N/ۿvN+2T+{bǒg~zg},oϾ~R78>plӇ,;7wAϨt11m:xE}eJ/i2-. (P5zH[@ ]6=nk6d)IzunsH6mSFλUǫer^e]ӃwJ/{]v0ǤG%~Û{ٵrҬ߾}|[V}u7 <[p}l9<FU}$Zm}?K4v=UG}9}z? ͯ=|]<{7+^ 439ȟ{Ya.Vې{U v,[yL蹿ԎC+_Z̴#+|DѥKf \pӒXqgc#ѽ1[ LSnS.R~]wnWtncl7Ey}?Fڲt?|I?_AIzbh"ׯ\m H~7?I U )wקrڼ;." $쪔$;ۭ!_˞Pެ4TI6l 5SR*0TqL^5&)SF.#†'I;v Py߄_Nʪ'C1JR iB GV(}RQaסT0WNx< -ݽ~cK%xi{'{'ol^oq Yޜrcq^"bywkձNUG6RH`qKG_VN };i^>qRZG ~L.Jb,vB* CeJx>U?˄%ViC`f-.u` cjaݻGxTK/gxLTN5Qb9߉֗fH] /{ x&иS/wLW3=9dHY>d$N$sC `pǵ+k'Nq&/6a _"$|N9eۓ#K$Z(N^g[fh![>p*۴g3Hds_AhDŽ(D:C N˙Xj -j? {*fר(",R;TLcwS֒i~ש!?D:f~L 6N"wb`~$IcF}'7%Mq]=yO I?"}>2PLxyG`:j`ơնBնCvB'VcxڻBRDLs>u>U<$O-q|ex+kpDX-"8._dF ڊԃkL3~PLhX$[ +Lm*,ϰKQy/8()eQ¡-b#JS)GٺUPSxӛCie5X.U3hB(1#,U',')l\0WZȩ#)ZSsѪ!ǏI!v!Xoꎡy8QnIP{ >[Dn_*|U7Mݫgp[91Z.G6۶WH[`tbfA+7uMTUkjWڢ~ٍuRh5X|`inyGbM/Mw5н>67)ҤǦc^.p^:(sx`Uv&*R,/8t`ҷz傶Ř`DxRHw?^_` U ?Ҁ>U-ӗ9ӤU_f5XK"!ҏ)KWEJۖYVUMñahax+SȄ^T)jx* *X#BW2T`xSUyp+ĔzwHF@ȫP' XuZk0ze.啮ʽĥ?Ǫ-&wcu3X4|X[=˱,ZK)= "!XGO19e9vvQ,M~,.izQ KVAWÏΊyXHe;$X4໶C@L mlℤXs9ֱ"+]+hpFZֈvѹhogE{sQ?hq|op^?6I$(j^wm׎c l{XQEm{}ԲLx,,`'}Xq/p`:%Zbg:KX S\ieCKBo8GY|!o3D@E+c*@+|mi֌A a8M Ľ2:QvpOmT+Z )l/p!Svp:9|@5a:KA&r*N0# GɎ:56rT, )IPMtC31%4A:gV*c:mSbdyĄHDv-G1@(59<#9K~Gq]u܎Jd!M%C.ob! [`%c *l6HcьgI.`&ԁT ˱pL+4b9&n"$.GS5MNCF\KAKLlGh\61[ H DArd9WU̠Bs0ݐw4J,*u,sXIVg"`SF'\;a0&Sv@#*"dצZ VAy3&~Ė ^ sƠ*aU1dAɪF3\4əժe G,Vy 65ΕZPkfiV}U8Yqd%&ec2S. VJ N#t` Mh^No;Y:̌lsd;2G) 2b[!VX.O˓FapPAv;#mP# y74)3:`@OTF1ۑU$|i &6.|>ʀ8tq#*/a|)K)%o:N"_d e6` /ʂ#(˘K9$kk2/qcUtt68;2gLc̅|TDqa#TBZA)H0jo."T7j[(/GAe=,;!t7JV*ń,}@i(ȹl䖶%ml? '142 Er OIy5`J.B.BbZXl 2',*MV +x k.M+J3hBf6+ ̧;%-`Б_`3>HgkJ?0<1IDպj0(!qi :>(\f-ar}aئaVv;Æ|h%!۹X *hjg0h{ +<vd9_5v 6-.1 `T#a$F>Tl2? {1ٜ j(Փgn"Z c Z k*(5K-mj?Xmc:j =6DGfفRkjA$aǚ9넘 52c48sS^e o`ipN+pЅ D@;:*,HA0Ic¸[::5cQ LdBgO&̫:&u'fE@.VRҧp/ʧ]<4`=lU(W᚝j,oĄ:pR6`BTfZcPOĶ HaPۂötiv2꠽1ap5>0()\8Q4TToȸ`ԖRSaގqi,Ű~!ݴ~(l#ke48Pa)9MKx0$!(~Xe`@i  R-Yi ̻X[%eQeNe)M{{?,/a*3vdK#ېid2&GQЅ/eT/=ѓ|HByY":– 3-ÅpzFU&0cxs}Y]M(8iGlC'~K.fcJ+#`TfI&һ2(Or-la&صQ"Mz Kf*Px [nь&Xŷja\Z8@ ."(_C3vJC?Y8Wp$ ྖ{&)YǓlθI 6vy#1SpbCFWl)1[Ͱ9–1T1%{zH(Ph|@ ɋlC|Ap*nh|yA6bJpg3M;VB|HTsF0Lm>o*PqZ0uz31,5J*a:S@n\IƪNXEnUK {aBDNK6c 8xcXNJjBH}dHH^DsRAGLW` 4KXD{`L"Uj/`|,h0[|q\-PX9 }upay.dj|xj- YhE<(s8\-mm((  9B(;;*l,.~v6޼t GC۳2f$79(`?t j8I&;\AG `=VTAqR:˒Wu.d} OgLu$:S50zAIdmtE͂AK ,u}PuvfLtVFb^p -ؚ+&;E2%T $ _̕v#dKR;p*KRB$"KQgt|Ifu`b lvݎfAWmZJR.թP"r5 yC5$t$0[?b vdVxntdsKq(4 $G0@:,)]rM%+t_gm\[ym˓Zwp: .2AJ}vSbwdKhlE4]LMKz2 R:[$,0&|H[p0pA-rx]&o_%V L%x ^+V4B)|k Yq*x:{Pە*!8YXua+ge6Lg/P'nXnHfYv) 0mY j~Ít]ؠf:T"-b`e :Bw0ɪIpرTFol +0^H:G0 z@ 6+F 2r h z=)`)ulj&a8,N醍<Ð8`9g7נ65tO7yRcwu$>`eZDvwY ,ft v(U:4*ԑwLAdsb@Dk@8&|>,#Qh ̰"H,q #aVS|I )[BYF[ :U]T=Yo l+cl1BLDL(2 s8v o#a(Z:kJsl  e  SmpiI^pa`˖"F\84₄pI5lѥ(`.r0TMf.7u&gl+Cġ >^PPJ>Nt q+ص1 ӁfQNT&LWeO=JkBO88 xE7C#tф8 $<eP)` o2.Ɏ\&*``O>Аd \tcHTl- &2̂}&c cVƱsLH+g><{B< _|@S%,2](IR2#B )l,I}xc&8o*ltf :J熂*s&G,B:Ky$$&:ϵa0{T ]߃q @x]07 X"k%^ped<x~BU b~1ب9y|FSV04 Mg[EJ܅ v iRZ(L'⦧plɔ ϕ+A(dMxmO*ZgS8O>@CL\ O,ev'O`JNk$0!p#Rq7{D,;H#̋=E4? UUFqIʺb. o,wh'BGA\8"ڂ%uq#@׵Pڄd32P{>''-td ^A3:84N. tC`Ic-K^,C„' ^<le9޵wa''[MlO 9t˜jf!a`5Gd$ Nd &PoB A1$̒\ɠxFܭ" ]_9H99U񆽩$h:^7 xLЄWk^tkBX"&`%VbLS<.O![FmzXv  pp?M[M<*w+4?B & ova)A sOe ++ךF8$^;*X$T{&f?iOjUxdBm705dOSCGVt$ ෗"dfNJn{-dO# ֶhRb ۲\Y 8懐5B2*慕CɧD{a:`n[q-1{5yKFL3f?%*h`O] l:HEC啬6Gj]>|O/}2aT˨X / QweMۤZ Q`:(e\#Ko@Wpŝ00# +a)tَ0=w I!Mu оh{0 (c C;'/¼'Σ'I/ tFu6!9 lA2?k Xsn"ޝM_1d*BCrsJ/gv`]2S N]kXPv46!5'3 <jHPk4a4C:`$4#MS8kD bv{]944X<|Ϲf dt4h". }VcRu~Ǫmn =W4nA;3d*ISU䓁Y߶=4__iD~[5Y#}SۂV%Jw~Pi)U(E ~.ޔL8,CQfQ>? H`P 1;o44`z`jj,ʺ0hd uZy A*/ZF}#P0 ($TAU8BnXgP 3q@s\$r!E. C+KH#L$3]j GKK@c!3Iǫ{ՆI271.Y.͟Z6M+눱ӹЍ0?:5YnYճ[dXx4bjՑ]% \`~&T,L JHjOc 5!p ̎iNT+ߝ),h?3QB.!7Ear/oR^5n[o\90K~°ći:$N>}M$Y[t(ԠIBk2}}}Ϙ.{Zuss%ܒK\W YzI?GY"0CÉă臂>W<}xz,Ϊg%]dt$yMORvW9O3 e}.uE eFR)/toQ^1u$z=Q%:$@6f|ܛ ]m)+q ):%LDZ).;ѕ0l7uAȗ*NG!3#ctog-u)^ǪZ/'K{oơ/>asZ92ef/Z4!]؂ݏ{规r}fDz'![5e,P[ͽ_S>lԢ:0C>L<յl>h;Ϊàw7  C6UB(kaPA!(j)r8}i@Y1eC FvPfP+5uAuhdM^,gΗ`쾸il j+ b Hm S+``+'a&;e=0-ʥ:=09 D!g -ݾXX7{˖Vآ0HGh<-Yq0 I_%eM?#Lc{>ܛ/~M6\ùEj<ִr뇫GiWt ɻ'~ JՒAPCCN%ݨ6od0K{w7 ۹Tp 6?N8q5{1 }OW 5 (ߔۦ?ȕ5sлf5^-H"K^6qg~FLY#zsCCcG*ytLd"]/|oՒϹ2΂pɝ&sv{0cqWd#Ѱ)} #fržЉCG|,yP*1օt:W6Q8o ^4qyg#)3Es]|J7`a34l=3/Gi<n):9% +\c%(qqJfؐI߬^Pynvthb˿Q1̭H4~N0̋xD)iYl'͗`/C~f?3|FGq"'>ՌT8YZWckli4++-"gmF|A?_0VaWђskE̊J4bdYͨrJyaIvF]*ew9kucA㱁Ngױt&@7yߢ h&_%(,G/i=]ԢVc9ygʱʇޓ.ɒX&Kh]_.dl0{j]9ʫS9Wh;#Aף l֨3U#mS ?™^$`nϑԈd MT^7.\$Gό҅KqgOqS*'y17n9ph;eéEjav}M#Or$9߈׬/U1ZqxDX `qXQ."oJI>K=&^y0҅XŃ;99X N:?a[96@Hs^z\1W Tt;kYA?[2E<.?|ЌQKɬ 1~n%$1]D/xx[J*Pi;}U 'cGH'p>{X\ ǒ >0hdb䛮oo޺%/ual8g;Ry^W(h,N#ƿ%p q@0]\q\aT#$ƪ*389"TvD~Û}H?x9ܕ> 5UGI<)  $^8zddS hh]BEz{0,4zF;8pĹ~MEOzYϫUBe9?Gq۶/J.pWX@w~hyv#1-Ͳt~N {Wv cGDqշR= li&z@n/uw7bw.;1r£w G& {nw"'=s p=8F)D8G!x8x8J%M0Ľ)x8 5&xH ǑS˂Nr~f:P 2|b])n>'q'8 M(|ł?"-(ǐ8 |c! Q$d Ƃx % Aq#oQQc~rEd~?b i|XbFX"N9% S, G P+4DVxk4:9^KAX a(Ԋb("97a\Ţp ʰ+>>' 0d  "1d"Ltc x< "X, CQZFpA˶́`4U2?` ` z 0X4ܳ?Sh~9 e0h4EUb%a| OgHŀ)#xȴ  Xh(HOz?H Gp/(8L=]V$)^4 GC(, A!})@3.F"P(0#f.O/t)@:,cd%z|(<CAl%a(hT{ed$8ȡHu9Y27 [!8$ *dv8܃Z]V!Q("j pz"#?8CvAv$ IQG0X4+Rm @@P"x"M>+fS6Wi h_/}-߳sh=*:Su|."c$6DK<j N)`s&:j$uAdI//r5fjltl0-6Crf ʘPʞ_ WX.$ylzS5>b5Ux1{1h? F/Vj*2_{J}kp=I9}瓥=Rp?06ľp.(o2j )G-VN&ZrBʞ+kƋ7ULZ3˙B7] `qW^WdetţzCҟ*#:I{9=yk>|ߛyulQfzG]Dԭ~zzgeD8bdcHT'?[ Y0^EPq&׉>-i- ?2k_ &׌}߻<%7e.[اjS|6fO;Mů[ؿ~+pAJX?Fˡd {:^~ "{ (q;qN< mD<<Ǡ f6&%0 Ўv\$rȉ@y5,]P<<'@Gđv\x= X ߩfQ|2# ߎCB B;dDj~yb4 C&qm; Aj/(D%PBm-M$Bpe)I^|$ F^)) A$x4rQ+LB(CbИ p0A^%_xA@:%9pTEC}d{g%dV8p"䗱bwpfFdR u 9S ¯(o B@Hd  )j@-Aݱ t=Q. ?rȀ "!!SAɺ(HkC 9O  'wU@p zZQң% 4]4VXH ) :$JC]p4n0c*~4[ ABXExGtn0 D Q$?D`f0e@F,4( dyjobP"C4(0;fm~,ijL|8+AhMd@Ak0Ia{]\ zՀ3{DDetJ93$ ) ߁gv]-!!## 0"dnEGZdh-9y|+jhx↗~6D9vOx?- pQ lA"lpb']E:{b E9R9oaavO_ƀcaZRƦ棃4&kH'™nUܥstLjU.?Qv趠V+VC/]Zg|,7!;}a-c ,ϊW;|UXэIͷj\6Hx%R~kCk?w6νKN Ƙbg7RUdKj0nK边-68|e]gS I5qwe嫖cd:{yizdAF<.`D /ǴedaS@YŒsZI_f,ԲTC4RGQ˛{h~Uixl*N]3"X=pbA8GG朴SR"/[2M)ujU/;7̺gPu<˓DÛTi[|c/ʫ?4=GdkL*7Eu`9OV3~q6Wwgw5˻!n}/})Kke~5~|'i*r3;vtn@TL,o .%XDqj? }L'n(Aɟ6)_QG{ k:/4UJJ_kF} '{x<\F#xoNB?jHJf&]"..ndPA{uG4:Rf d*8oGU+/6E .tWY?ZVbY>=٩oG?ٿ\!e0 I\?y{SVգ |k{%>x5;HQ]yti~č g/~¢Iӡs9tS_a4+x~w[M%gk*Vj˷Ĉ='#l'ˍJl=Z'o`m,ܸXھURy!'Jj g Kmv?ϬE*%I7|dѮ}:Cِr{:Gŋk1 TB+O}´sz |'=^jEFS,;1/ _!BX6rwVL@ii5wPGxr^5K&nQn(̾%ҟ}Uey +31W:ܻq.TC\kɲ'K,I|yD2NZ|ABQ:#i$_(FlO+ޗ"r*:+xR.ԛ_|xTϑjFF0i k!6d쫫N;Eվ2g熻JWK֐ɹčcYy`lgt;$rsW/,'s|)x@mbLq] 5ŋ]TN5g ޿ǥ}_ Ff5([}LlZ߄íH{ɘ!FQ7'#f!\GVJJHT8bYf_TRqUezR\ĺu?kmx*qZM#@9ھ)>iX<}Hs*C|Ag :3}5@^R[ّgvm޶S#^ZvR!ʬ[^k_Q!@| >3vߩ%3=#$?= kU(>9ED4%®Lw&774>{y)0\ZͱcΦz&K`bxpvi Kg!+LR5^0h.]{;Z_R,Xo6$p߯ƻy+@Sg6idh5Μ<=ys^gYfi2=]8tt\S-H!@G'[lm?eoHoItyy\<=M;կ'=JN:M<iEҧŢ<˂7O ZEV[ryH`ѵ3IMB旤h dz'~ay٨Ab;6yM&͆'21M]tPsm{A:6j<[M"1 ;MeIJyto]IK܂Gt11߯ɴW>cکPUr#xY٢V/YYz`E9udP͇Ar>Dd0Y<Ky[}=T>']+Z4jMZ![&CPES5rϴ|?~|r)tÿVr|j[/&9?j'p"3l{CrFTR%KY-^,VrNOlF43\!ڶPaű5ƾZekSזt83ͅjݽ_=(s=w8Q^=%p~-rwpr"<h* -'*`ޙ:P  }NZzGrS&^V/djjpϝي(o MSکP4Lɛ "S4Ls*'6kd*&>s0?f3g$vXt$WQ @ey^Z@Eǃރ@i׳CUy`XW5Ew'o8|?$R;q4 ^))ͱh@Ky *n&~rfGu09.-wy߫O"z ?==u|(X7i1.Ldcۼvς :i/h~0;_?4Dj7Ն7c ,J/Tu$zp&|Fڟf?25uHs*0<{nͥȥndzUe._︀=!\eAW fU>ɸ#tK,"MI[.uM~mOMHoQezqJ)X>apEK{,P3iB2 e $J\hzjrtY Il$OCuEkU=|WBwԯrQU׍#oxؤe,(=*玭n?Iv[ }$ًJ:oG(/IwW*OIÛΟB8?pОxR؜Y]y] jSlZoZ)΄$O#P<@O7Ov9xv yiS˃NÁ(WY!8z܊HP3sNsxl2gLrȤZnF֌Tl>_ᭂo2{h3R3AlܵQC?Jnbq}kꍦRo@CFGɋ~XgI=떼F^jO;VvxO A*2H=9b0>W*UtD"'9*Ȃڑ.E՟˧r rBPeM υW^`gq1n U.E/j"4|R'ޓw'rT'H[hNe_ܼzaznCrGZ>/=ݞw\cp돳nߜ\ҡ{^f$s1d8ӨyLA8 r6w |-,h:Pw|ڛ-ߟ*+ZLJ6=zǮFִ iN+j$իyQ*@X@H%)&4̬nRM^o=o3G1 Q^H^t/ {x=T0?Kׇg~Xx2M/ =i*ʻ@Rs돫f88'}#g/XF+ۧ:~csR3n+<ktpP?A iYqeL %Yog(Pޙg>us,?Rh|!M!åMg YAg S'C7'wM=|_zw4Fw:Y՟{-c ]Q>3xfZZU}wqb7\ZxCFk>,N A05oxֵO/>q13P.@?lz ޖt05Hy:U;')[^mw cH2h>qynHrY)ޙBmy4eh\O\r`IL߰6`_RoqqQ_gi:3>C;K\Iw],Ǿ;F,BoZj&O m=?0"Ðk>`ATo#OU?0IbΧj"~IϜ(-9l_{ۦ*Gxϱ"?5QYUgEO1<5f`ڮ7қ:m>LPy/ ?e܍ ;ϡ# ,_~|.+,cF>}ovU/pMNvhjI47jK>qƏ)j$?wUZXK5w"JHg9^ le?\G;5Ig>K_Qj`]O ̼gp5w\Qs)=1]JσZ &a[޺}g^v(T#iܳrs/QP۞egD]#:|A:WaI}&Reۇ ~ 􅜛.Fqgݩ$q5<) ~;BRУi9>7m4iMxWmFZ zE'.+Ia%+O?y'W*`8;iKɠOH-3s"xm}] Q/Yq_6~uGVG %}nhfHd*?z"wK;q(>g!tM@FشhL1珏l?|E$wK*a ݍiB@.A | I2l#a6q& +O[=nI`}:b8|vvh. ;ό WK_(,~NzC &̛>_%z3ð=Lz]Zr~[S>O7$&c ̻^*>etL?n1\@hML SD8b_c)ȊOgd^O=엪sm]XP` Vf3p;.߷NPīvz:z"A.`ieiy٥L9Q68fHcqD1U'7|TX.#dzMD<=fyfsb +4~tI)-a S(Zy+Z[9Nd̃41cA|ϫ9g}UCOqoZp*奨h6)d^1#u".^Щ1εܩQq=M0!$݂48,@p wogVw3ܮBO;aZ],*~bwnnKZ1* Jms"/M5бVQhI}3C\h'jO0C/D7VE򛤬tjCBBۛ .SHQACRy[l7fƋ0^rwy#k,قBUc+MB|@n Sh{;~C}){SI#X !^]sZW#&[)f~]&}[:[9loˎ KBX3 #  vb4NUib&3fG&Bu0$AdcЏ4E0‚T*l,]ҹ /Vh˂U *HwըZ)o.־4ǝ7#Udp^ϷVn1 4))lY].yi Gz9e,⳪(KHB{0UCЉC%AyNyW:B_W|ܯ G+r{G‡>(Pc,`s<Q ȃ6>C$޵c3W |:I O<&Lo_8O~HOt"O8c}V/'G@߱)0:&$v|3^)oGo~D3N Cs`)Sr9f68?/׿,qta=0:͋t"$G-#A _/p@wB:Im!!9z5L8 7M Lɲ^ByWb@s~?nŽJQju1Ktm8a{ƛ2gUJ!/m -dk{uurXť2J@kr|+s FCB GY{xE".x-?FUcx+OnĝD5zmOU5uiwߛO@\rU%%1}O;:~ZmyjEhzp.N i=#ti];/"0:|J<7Ff+y"WDt%t[Wda"u%{\.kx"!fv7r.qTuT7Thޘ+cU,c9IuT{+3O{Q\\[h$3_l p)Ƀ}AT#Ej O>exab",J%*؏uZnu(Q rP`;k$y8x.ˌX&ؓD.r xOЇ#JZ߰|/lm܋5niA%w_ ͐߆(dd>dkxZYQI q5Z̢V۫LTόΔ;)0}xVhz3kbJG&z%I`kBթih%渶H! 寰vPѼf97),`˰ssA׽Y's%*Sx3ЬɴV_x? -zY"?1r"Ppz(nv]V0`m$Wj\N2a,] 49%X'3,$&>Є>>)Jn|NpVw̞ ʍW{ñI[Uj!/؊M'"E5ʵ}Ȣf˝Йx>:)d>uf,S r=OC GAQDs3Dko鿺n±#? @_)lq=5A X kL&_,/qg{Ċ{F²_<~%΋YG!_Ap/#K7.bh_Xdk`7<8vfX I-8 >  wl(G,N^/;#)@̄@eF,㗄ڇ"H< ۿ?b>_8=@.*1 E=: *K_W?k;0:L;b7yYp(/AN]\~ n{;HjQGzg['<+ekW⯣'i]aW<[0{P^WjJT_IbmZ3v}ͻn9c]j]i; /CWzu}rXI 4Қu:Ez@'N8# pըؠlȚZi+e՜;@vF"'Srn^BC`\ȵ)K^/By NW>Jꂸ̞ߴ `"jJ`Ȓj饬We 1R X%?6[f֏+C@O- 1H}ZiiKB&<֮Q<}4 [VQLxkp1 N7zh]`Ê,S/_=\gi)fEp0F,P#JP3 E8AM*R %F|ȡ644̴̅4fW sVK?bM<<ۅd K6?rH>&-T؂.̹hƖ[+0 ^mkMrI0m(C_{_^XD}1z|>ՖF?DĹv&f7xV}d/9BhZ> nz7 ְ}o3ZSO7xAHM7>}?w WR9ugNu3{sJʂnMn7/OFG_RWa~t7_ƌFA"mɪqj6n^RѩP~鋃tW4lɪvFFGץL9OJśd_ҪzN j;l/WxB戱2Aؽw>-)AגُuB{/`ȳbD̏8 +1sOPW?{?w RZrh٤&8bFcپu9fo?4ﰁ*]aawxgsqOmʝ-.mfP@X p>져7,Pc;a(ne+^RX.54P+rlppKȸG躐-`!+ $QW?}TX B|wpЖ:iX.)6)cq!y 6{گr2j'ᗍ6JZ+w93LNx"k#'Ƨg;٩^TbdF ß6H92@fX?KFNw vHz|5% _JO-ժx#V<0tG'uuDS-"JND=1fب"o"ei 3ו.={gGA7#o$4m8N$&e;tf4t@OKaHm # S?d|~A ,9?_Ƹ8 V{SiDb"hRp 1Ơ)/ )zE %ZI_R/E&}_$H6(1\q1 fЀTHd#% _H @bLGFh/xa`?D]߱'&ҽөpmL8.ԋikH+|H ~@M1sji ZZBj2`..8gO14n1$Js]NfG9fMҏ^ 2䚘d#gk@_4姷/Bh e8H">{7̗Y<)c`_w弓xNbut#˖1ws9O|Ҭd k8T]^2&:t 20`Ӂo\ #GV ; {_6^n߄=/7})uzU1*).!1A Qש[Cy';FFr>@!N t5nwwGQS,s:TQ=~<9nKV/gAVشn'^gz FyDDƜ0ϙXHi\g [}ti$N^)@UTL3__S~Hl|hWlB|%<-biE[Hw`gv X8 !Lrn_'oyk63q+g3h\qa8(%e/ZJ7˶9!։X]4u|gL]q/p{קQ-z"A퐔^ ˂jhnhvo}'D$ :7.i~ ˙1_TL\ 1؍9jtma0C4.f){zocǍm-΢c&uS4 "ȷ?D诳juz2/S|) $b$#_7 1 6fR5sH.+M˾Vۏ)uփ/ ZX1|~; =z(Bkݺd|N 4WAEP@w%Fǿb;Y] ߝ]CQy99Eo'#;< 1'lFP " ^+qD e2Hlp/֟_X2 EBUMHwn2kD%v Kdr C3 ' ( e|CI6!͂t-gL?B/!5J YԱBi]0 Q#:5DQ}89nbꇁeF"Ig'Y,`Ui*uĈO:TEג-ePH`xm†V@ 0 VYس|d f &J̠?ţI hl<&VZDyx_2$U BǰjnŴO2c+#),8/sU%㠮e<<ƹ kס\aFV*S VEFS̒ mRl6 *Tp/,G \-U.yXtLG)~)V9veFȹݡ-ae>UXj{Z~EtD~{kIh"6{K?)Hwwa F{':UrTr"Mwv)H!81᫲_Ί-~瘕Z&`M^% mju2!0B NAŢD/{ُ-ua!I0AG5-܏3!5ئ-kVhue]]EeNߝ%ŧE⤆XNA9OJ$exywԔkdsNlDD DT&ߕ~c)ۂ#~7d{8\ x#Su$a^k.C7s)/ܣ#cOK_ V0$+nxx_ܬ`$H$SVI^i߯,KTpl<#z0{ m--5ۺȑ$Cu_ՠĔ>t~Fa5<Ԗ[À$H \697>]3`N/NpCyzjkFTI;Iknuo˜y2"Z ' =YiQԌʓ[aa! `)_[!Jntd~l W<)sNENepD|0e<یozSc-L6Q=ՌkɧaNu&4L/C@w-)̯+IPH~@k,-S +>?662 'sj4 "s4/ů2_B]\]q2<,FYQ96`qs;NY볟})ЬP5~] \j[?RŐC|f[l" RTMpkWp]/D*"|ka*qnOeXU{-{xãi3oyUsU@_(|mw$X5ldIYb2:}5ճ*nZ5y2D( "L,{-z/1tlV]^]. X ;Gb0/8iL Ě %lJE&)Ȱ#I!bׄٸAcw&ښΧ;Y9iu5]}/'"ǥ% :Y}̑ {ZMcljT'i Ǖ0ypBh&pB2k SDv|)p˃R|O2& H{j1u`QV#FWSWt?hJF`w|*򏬊Az qx{+Q: \h;L;;_XOX-&S~X+~z(вqsh&*kl e}~U0 j]_"9/4 :ݲr!w(8X#ˆ蒀dD^K 9~Ķ>Tq](K栛IiYK 5ނ!Cw oG<8JR؃H=,vZվCǧ|!]zwz)@X[Щx&{%,0Ȥ/8-!09VT)Z–uP;WW?諵,jRM-є] (͐L /H%M<:jfS@\#6x8pXdy^#@SiENp()'BwRRLM DNq+]I1ȟ0vt4`sڄQh}7'sp WYV;wƉ.8f >Q/);+8ާd%8:]; uJvMv5kD(wn•z/HCZΕm;Uymc#,'ْ",^ή^mUk@I18r/&% )Dv=͡B "f{֛Gؗϯ<—xfuâŭYy+_uVܨsn'pI9|b c|Jfz3Nk {FUOOɼ;Pfނ7ԗ.1PCsOZooL] 7Qr"1;wE&ӂZ'nޭ&_P!#VIǓ,٣*GLACuJŃ R=.uM.9fb=lj"3I@)|I3F)'=Ł_HJxP B$֒qM'p_ $+-'4ot xewq%I,K%8@@&  Pd/{Ł$|t~D*BRoHxm`+?B2JS||ad]lYekdIP ?HoOsj&qSX5ߛ;:Ĥ^s׹*R"iSrbl+9d¶ f^ /.Y@R@B:;3O f)>C{{2O⍂o#7ڿOu"2*j>uSqu-q" DἌU\X.($wѺ=uB#]frb02/Oμ^Q> \!G~%G l|7_<6$0xB-}2|Hbb Hsz-H%I_EE%ғ8x+ߘJ<Εa КJ߹~$"x|_;<񬏠{O]S'K82$k ;JB$dysT kj~+ e]oګqQ[lӫI+j'vlr1b| !|aZ ׿W L f!:j3̋f/B;$w1ŖPY1U{h ÿPT3_ -ƈ焹~ LBEQ 2^ H{ȥ[ZVЋ ?oN"\?1~sgzrTRh6|{?w4&}h4 ~U)f]=>HkU4s9 EjLuK6fm^C1%^p2BuӂBzl[5u [>\ZH>Pvu)`"Xdg>-3] $?nV<Ѵ8++,UEB^ geIH+ΪHa@xILD1A%fpq(W4,^uaJ#Н̲ %}3\ELSɉBzfReʹhwp_QkeḮ-0(]Fփ9%^Jg-h2ԊfFM3Zs+dO:Рy#Ȇ[f_G@pdŔˠs)!"VHu.줌JꂱcUOψUG@ q88ԐU:~`ridFlpZ($b[oNʒ30nZ\7_18MFBpmBY4Q_c>q(KG3כ~* KGp\.ho[(XT ?nc}ӿ^_#{=8~ l)~[s&R~ȵ9Np^W^ֲZY*W-h=@Ru|[wBy`nDEjiqV/pyf,9E}EG7"4 tc7њD,¥Jr>lL7" 42uP|nc&jxrjg:j%>>rUGmMԅdmŎhE觴(Qg`ju~[tSˉۡSLdZTؠ7_ǽm &BzՅP >7xp5X߻T]~k\0 ?w4_ *|\*ƘQ'+~d|ŽƩ{*G"q73m*O7:fvTY X{Oya>6UvLk9rv!}ĪE2%ƭoC2=%A5J2E_>\%*B˞ Q QT.h@SmvR"WDMF"{0+_upx֣v>4i'E7Duxߺ`|vhh_a4&@jDݿ>F9Ere@[Ɲz-$n0=Xm'ɞ[1 [5QXCD%dKzu W*̷ߞ VTf%?`0gØ=s w;% +A12spqx;2srq*Lvp V5`%(`XVBfT7ﯚ쿟z |ٗ,hb`fUwOVp!W,<8֖#w`+0Ò?qB`ee1ض@ TxlG޻n!oط\K8 nu!!^mg窱|5 ,L;5rM0JpÑt.u=Vx5$f3Otz6ۢTv ?`4,!}謡RR?74Mbh>xI XB(3`mKw^qXO;W3 p&P GVD$KIt5RH6̆Rf*NG$ T:U%lM-&U5ЎA|VJT壨Pgq6tA;lxdN&QqlP!KzГy72 &*My"YՍcZ» P"abh/ݼ3 01"^mi9HR w6z<*I^W(И8hzS N$$/7Y@'0oZi* \u=aBXDyb zmޟ$Jaֽ櫬JcDRo 8j]aZ1zE4²ߜ75]&;ЛZ7@+2%?qN VH$F%:)WD.JG3Up:Sx('o;ZX+KrM2#"-=!WLdY z K}*g6~VnE-v`GeBrGy+{AryM>.*wS'tz1pˡyq apiH BjCc_,EuʒÉV6-G&g;Ogxso 2L r'RUS\g#+߶!ENAo>+j$}y~Gd@-=#s ʷ K8`59 z2.FZ| &G>D\\\V@tAn(QQAOUc2ȢZrMT@ AqQiEfEhFm=8%uI{*J"+Z}sU=@z”u&;Ĵօi"NeeյHsZwaqBU䳍ebH.]V {B'`=৮bgdC@̍Ug >Pɨ!XAA;P ! WBWTǢ%StKF 0]N 3G7bSuRS?7q{#Q) wq z-;wQ 2t2}1$l1QK/Fx92M ޗɈ1i:@S赆}YliGIN<̌AFN"ZeKxQ;OJT~ga ک“0r2*dǘM~}m ]i*f?Z+ ۼ"4LRDeÒ]ze^qDX.h=]C'#k=ɚaOW50\gWA"-/ze_x<97H%"*t6L5*b xmw),DjϞCU=k8(xW՘ht=W;OQF>HIuev*-"a; B i v{02i\x9qz3W &ҀcIo$@NXJ'Ipn!R :'0߭bR3t'ƣDU' AI~^sDE'Qa$v;ا(òA#hmFBqHZS_"Ju*K:s<ax `w>Ӈ: hĩe-Go gZKdQ 쫼?+!Pul7n75] 4vմ*(} /tmwr /'3mljt3{g87@bqTS1&-!`ͨoU"(ؼ-Ci@i'q[)|tD q UW<7)UpC*P]<2+^i6pQb?*+yݸ-OJvC9l XTOLMU dѻ:- ]pM ^h/H&D>fR PVlMBm`W~+SuR0Hhg^~$[Na\507].\#u%Y #QF36^G%}cc̳{/x|ss_qE.1U|!j>Ekkw1&27ĜVM9ls3G)Ans8Ԅu*R3e(@G@%qA˄Tqvt$F؄Ѧxfkm=FsS->52 vtVLg*sEmכa~]xCkbgq;]ُ _q!?4t֩ Z}3%D"1eLَ|C8 1rZhԍlq_nm|O]}@ӡ(ǥOۚ2Rf m.7a0'<Xr_ʷ.ԿV<$&.>c4`!F%ƠWyG(p#(1}0S85BGM_>NA&$ 9Czt }Mԯ39~OY2ʅ5k $,܏y"_3q-rCiR״O9X C^ƥxQam=Ixm@I3q&ȃ{?V3)JKm{Y}  %AV6GcHm֘wJlئ#מS&aӭZ{dHS )l^4q[% S;W::T1?TFiС- ꓄ި;P|;8Lu J_e&=&6YK|zc&3,?“3ȏlD|ba^8<͑tO8& [q*Fv\9k]uj2<ChJWa>!sIƟ18 xӜB8L[(/ڽ7pȀĤA[XG} |ޒIJaCpeӯ잰A wMd|V j9ޡGk}(ۡwf8鋂VM'oZA#^+ [#Vȕ;W Di:K 225H Zlr&1Y'n\Lr߳hL; )}=*ۜvoBhyE ^0*q>ُC,"HY:- I7Suy49}[,֝ZVES2 3ִ9X!XB4䆕iij9SaX]xݨ*&vdB@,͚ugVB" UXޮq8&8!=`ݚ4RCO*tbrQBtIPՇ0C~)L}0o]ܳ:Iʢ:|=0!, ݍPP⢌?Fj&%nEG%D8S/]5觿u2&q.gg U&ͬ8#[oۛKh3m Ņsw< >nՖ؏Dx䏟W ?G~xJp4mP2MQēY {Ž﨤!/@ʼIY}lvuRʴřO;c9 xܒ, B$1t`%t'L̓B]gx"5;En>T1h~&v: նw$eas[bs./=_1bUH0:j:'t5(+ԱU*D6ǧ4hhe``:S߽HGѠcޢI`ם*W8>b|#GւK(mmʇKuNMbxhТ^ )ޮ.t6DCPGz[K5qF.vcJl"9,UXk{+z k2 0xWt%CD9!Ax"E'C+euXpxIgzrD^P>D,Xetz mږyB2Yk$ FMKd {a|Iݳ%/Otc锣'B\N|T8X&kіDswJra?GEw~@|@xoI<[ rUn?㩿}9J֘/,NrT9CnLּӢ{&hϮWۚ)N0aB&~$3/V[~EKV_ QU2 lhǠJbBP.IQ\{k3ThU$+vt&l{u@]뿸NrRMu\{O0vX&Q;ܑ_„<#Y'I}!}/PbȓҩE F1DP^bHuǐ0_C֘tvt@_[ۼR5@ƾ%ioGۘզX =?:3?x EGBFgSEG lJ "uЄ$ 09Уm\9QG J=ٕ-03HR⥪VfJ4<|jcKX#JǗh_ir3CHsS39ӡ5􆲕wF"*L֖(Q|)qI9XS5W0KCl3/O C9 @Ȭb=Vq!DON8 _vN-AόN^SCjѼ_W[ISF`5,O87M s+Xl5?d+>wYi~id 6QX9|O5<5|EE)&4bsy%G;({oG^KḞ;$YwE ʾʣf]zf>w418?]#px>bH8qM'T"#]|$ 9D+5{oS)} ;ZXEFC~j{EѡO0'PSk=Qj_+a^?>-ĬƎ"ipQ17:)n敾F-\gS:`kϸs؎I^^'WI?]ZNRVչ^4:tA,˟ܓ-Ng ğx LZ/Qx!OFʆ#':63D/0-s܇[!{EYLPfkQ\7G˔0qn.fqBhrr甭ckϡItѧF^;>r`Yic1NiZ ~RJ!BIX_#Ȧ7 |,xB5Ϩ``G~`п"p_ [Paa/ؿA ]FǥE[x , fp9@ݲIo]`Ve@zkBE J#%.L¢p w(z3BAo` fW؛^^;WF[, o0D@Q؜[ݴTz. H)NآĐT>H`-RQ)Bi·x֕|0B;WDg`и.^+) _82AΏ7p5ʉxHR휪l, {)p 6l I4yS҅ZIoB nJTi&#CNj㙖;:?Xy`nM|qg_} ;i3v`)9og^..)9!g+px 7 FûnTBKyc_wu~jok1{᨜[wW䩮`17BagɄEo#.ZScTH c&hYw~ϠGMD_Z+A/cmH'4-*Eލv>Um>P[XA&{/$=J3K}Z!6QL@m=ZM g95tw驓o۰}aPTx?C[:w͚O  ^{.'_뫞r^]?]Y[R"Өm!?[MH#AUc䰶aOZǒ[[{%n.s^xl@Hr֘R۳p㼟az 9WL4Ud6%yTO+P $uHLN+)hK'[ _ziyls ZSiZ^PA>4+5VFS't%rWLc)obYf< nn b/+$K=y|##xww%a$5Օ§b2GHbatZkrNwj<9 "k=%`= 7"&a([kf;z]m./53 yO,ILfEέ|(g_Sxz|d+Oܡ9qxd|r L|Lp+TCw mdYXCG( rѰgѫ\`]-S1iS5b>l9vJ^CPb̭ EzJdaGk[(x*Xʨͤ`e_GJ_C.u<8ld$y):r.@?i-.Dy)d"Nf{! O"G29=Y^xymE&1Ǹ8]~2[=.B5*y+7y[C\k Y, 5VmS $s yT'CĿMɖR e cKC #(pCtJA]n"wA$~,c˄ʏMA\E)JѵY'Jޟlyzfhp˚z֏d"Rj(\2Mi"K7:$]iMyac3wnZ Yt=]u)a:7gN$1g,D)Xeω3> 6I{rNrRg{bXdc蛽٭ļz8 Scig4Z~HOEюQS-UXF*r5Siy Т9~dKeIa"˲60zMumB#%O54, xHYrJw}Mۏ?>xuq w#0<łM.ĝCtk4їI rCgGqӯRF> Tbw!ϥ`:x;&wHm4ldi[D_+x.߯ﱸX$ΓXnUa15yݧFUAg΃UV2~5tVilNǾGMr"bA/vjvhF.ll҆[#]DxԂ2DkvjH[&Re Kث&Փ鰤?DE~ [%}$ABäV67`TS 8\T%%0ytug02SGyxUrd?˓eb:ӸWuIp^;JA 0kAvɪn}(Hت ZȊe^#~OpDEl)_A  ~BJ2EZrߤP3$IpxT]eK,ڐt&UCY(V}x3ndMCtgy M} 2>L>t9~`\Y@ez'я;NE%#L~1/vzhw8~sEW"H9ԗ[T,mN]ͻz稨nl摰jX3 qŋ? @S^4u lp,"@~x;}dprMlk&54W œ@ae 7q[Q-gq'RikN|Ț[/Z_Uf-B(Ŏ 3d_1U;V~׊Dn N*ԝ&$nzd{?kSEj3}LJ-FQ9}]q8d 6"Jpj#fekBvʃnFyz 2=DC|;# 0(6vu0Oy(ܡ."J53&)zs7K_D}sְ)1Ejfc8yUX3^x@: 6R%AAЕrZ}>+0 _~񨋈o'72BAPkcx[sML̃Ӵ."%&q&1w躖$a&qR .=[ 1U4:MB(1wb :MᐓFxHGCh&Qڋ~)c2CZqDA$/+`݆52j>|q;; wMr5 C^j T>Ǐ -Y.v Z:9~TL׼з,gLQD++l 0f2`=0Ǝ4i:5W`rwìvV`zj0}nlSk5;LV/N(bU醣 >$iV΁5VXdƣ<6aSoS}e8lBD'9%.+cQ}T뾃|pk9KP}l| CyB?B GloyK:3 ZCy6{>X֜s~Vq0ױK;._ӑ {C|ЏߙSYQ&z:^0(MЉ`^Ni,9T>,ݎl݉<6R]HsO-a= ɖIDrLݾei2ݧ` W"IkO7?|6|!̱[QQWn{ȹ>Cd"^˱mE~) ww#Z ɿzDZPLWTԈF)8urѿ_uvѿ ѿ`_(} Ϲ0 @a(+T$! Axas&8Q w[(Xon !BDP]PAD@(6y0!G`&].8[YXD0 f̚7t$ B@#mn:c &A![[>#/%|z:\}^a=B7 `p .*>}~ZPmގsU5D E4P7of01⦟KЍSQDģˣf0 9lLySBSR/  !@'gU&buMv2$JU[_ߠFE |eukNC'GMHΩ=_!qnQǏe #TxxlD2~jA)~,Q$ļ-.#z,3l_僜DRdc!txaN2xP%(y6!MZQ@&F\X~ON&mʙKaQM yBjD}؅;Br;KEJpP{?1Gz7*Om]ϯKvqZ?R#5TWRu1g*^YmmB*iB|]:M](baLݏl_×$SI=̥ H߈! USBևS4r Yœ}B$j’+)4o9zpVQr9#&ϻUC,|O /9OU,n1^ߠ2nU{ַoCKZ' rʷw qL}&}e:c"#eɕ87$ g]}&mtW|~s7Ok*rpޥڄ6'=2=Ȅiw[?Sd ? Lԯ!/&* wM;$οր[~ @{u}y+  CCYn~S~Cc:S bagٕ-4,mbRѪ4y|6Y #v6ogb0#zZM|Zl;2|+z(;h!A.Fer [uޯ`om_xGjȊ'Z{.C'N6FP d O~T4y5pzM*!+26c1wsۢeV bk"KC=0lE>%1Y>wRM\Cfw|0 xC(FdEMcHBJpp0zOCGD?̮#Oُ7_}"VL"iri#@nET7<#k(WA`.Yc1Ag}K XWЇ+Ί(5i +Z:J^E|Zr/xքX@>YD;sv!dl8ܫ'9DZ\\2VPnhk`WTʁ:׭wwM+qdqyzʓkM}Va}VƱ~lJHgOqS?57*l@CCC]Q?oW&EnoaM/*, "nx0 #"9Y0\j|7ѭRnP 6$Kp R(L%p 䖇 M:." 𛫀"$qV37;`5@O,Q]&Tმd|Q3v@) Bnd޿NF Y2Т00ONQ'iX B}RC?w =Q##R4)xNfʨu|\iμ 3]ts^;@zzTKNxW #vze%@ٝkE p5ߣ&6Y\J#ćӘHf-/$.&QHp.۴->qϽXpt|᭘*<#ځ=!yEozh.z3t-T:~ΥG(,`a},תRfqoiG*G)FDיЖB<}*o%R\MտG$?n; vVꏽ׊F-n@7^=7q'u"GE/GPm{[DG}Vi_v4g$ kCE1%J]4d+Oleh46?BIjm#,q0Ǧ_-,Յ|tǦ~Y iN`xtH{ qx4Vv (RqN~JQ*Bx0rS0%w}ڷ㈶B\t|x9Uj/ҎnPRKjSs:P)1 ,МS mÎW䩻k@^(,ÐYΥEoI~Xm`|iQuL1)}gDŽ>l;"^N7lV^"L0fȽ2^!pY9%s@Wq{T5i7ڂTwOi4XM{ gȵ3&agczB< E9{n>J?W6 JeLcAYzȿK[^\MPO/I,#SP:uًML wrN"GOދ]:hs0S$jqj@p˷lm]LUSLFZ( I3r5ςfg7Cem4).JeYfj H5'1Ǹ/eW7 ϯJ4[Dc-h6crIfeZ3!]IWѴ˕cof@^HT'!3wwJ?y:me'Ԭ^PvdX혋9^ȧǝÛ)蒢2]JKu"2jKd aʤ[,)fG6HB+'EkkmNfhzT W2$09Y e|Fsڤ-|d)?뾫;dc> uhB'bjVЬvKfF+fxFRYvOWan!Gh""$zb=!?.<#\ k8 ;Fx %%?vkW++D?qdXN^YY/:zTərd0R _?L(ޥfdiD#K4향@R-gär:Sj, ÀT3kʻ%c7ܔkڪ/U_H0b65+I4'07AM4s/0+{=1Z@ctQ.M42>>xssI>z(lRc,ya~c ΖIj|/_G qgC0/Uͥ=Sz] Lqݦ"/O}Y^bxl–Űο!i.ah/9(442ƻ$BI\~@.6>rտ3s.li$0$,Zeϋ}8z wv<|g5~錝3?ړ9rWy^Sya(k0pUcpaI)t$yELibxY,5O "# Q° &z<7o="7aO+R/p\5B( …@QֹR`~ PBlIj0@q]7ݸ;wwo;w'@pݭ!$ 8$XKBr杙sީέڽ׳ۨϓZ5'+??XA{hxev<.>Vv~yu!~aAj}opDObprqr=3X!$p:$rDϐgn/GSsr P Di5OhqkuڥWfBLQLkey]e۽u*1WwoCt?ȡVUfF$ye +@5RZ6ȝmJi:Yj˭+X>b< oU7Ѩ$T!v,]ݤr,!bഖ(tt< {IYib~Ѷ*#ΩWìKWgT]~89/̶>Ð-2V75<<Бor1 79=@&VpW׻䄶P;HvɲOgybKMM}W}8%w2M$v { %vF>~&3x$@O1bPX2tR5Gbr))PrBuKW>g>(}LƲ*=) ٍ`p1kdSFBa#4l/4-ˌum+ﭝwFgn#jhiF[W&&IsVߣ]qFmvJFR#Sq@hA,g6*s4 )e]+s-{u:&Lͪ`*6@9ȇ$] \gU.|'8-Vxi{&-Z#>ADȍtOJN-9LxQ~Uq0"@xېxec--& v\y$ᗀH7^" :$ө$2}^dhm.94B= 3z-B?]}b-A|]Xc7;jF+i_Nm͂ɴa{FZ(fAK 2Q+@AMO|2Զ8l"MMjܠ3C퉕&IFvYC_oK[|uxiue6/b+린 Dm_淘oV6"Y,8H:8ovB)fG]"iPGD265eӏy '6ǗM>)Fo˥K4Z/nTGs&1ǂ* /8$Y2C*Jhv[1pN~`<ײ6jƊ~ Ѣ#P5i^9lt@Z]pؓʑZ"Aks%Raf|uz{*+0'oO >q5i!Iw-]4i&FFSRB0?^_/'G'u+7v/'`ɡ@w= :z5VnH6 _Nۯ- n;0G X=0P|Њ >8YF~;LuvE&v#3 l[yFŘtݟ̙h@N]{ށ%|X^tbf8s~!ptv\h-ZJ a)֝rD6`?6.~t2g2z^a7Rj }2kevivxYF9Y!zۭ'm<[,J Uؾ`;1WJXY+T;Xi0/D{=e 3ft> bń IZiѥGӿ^qmtOČfP,qctu^Z?b(bD\ 8g`Y[-I%雁h!P(QR}:6d^Sh*j{"=@3AU64sz2 ,L FHe3=ڋkyV#B¹`284RR\gSX#QsLb7ډ?u 9ʎ0쯠|ȉPL0$ǚ'̕Ħy<9FGy7A$2~<Mݭƭbfr`.,}:Hځ yS RJ^n "aː,. Ԙ^u&7Be~z.MZO վֺx&M23,H!o}MafBY~Cֵ a_e9Y59+gxi|J tqUj/Y"ф.8KnȟczIAaYAi+PAoKR [R;G@fE)$`!1-J5 % xuJ JU:hx\wxC*e~ ʹh`?zڳѧ31znJLE>L7J"o59N+*vϢ@S؟aд]ާ^#}Ϛ' HBvrj&[$#)%M7UCC;_盡Jś /afُ˃\ 'g<-]BM ʩY1Z(rE'Ȭ^-Vz4XN E[N`ݘd/]-"#Qt(ty0;G1Ruw  g':tG6wÂw"{tWxka< B7>2hQf?HxAb'&^aiGz`XEQRq^ Uܦ/wf Xa(-Ip:Abӯe 6MHFdy0r.mk^;9͛.f lfߩr|n3XV[zIEAZ[^L4L#CF ҝidmU:TR@etYV1 V 0GPƟTalCTvclE4椏+["@Lb /EɝQG GC̓|;wJc%/\ 0psCT7d o?2ƭo9R <1bh /'‹]IPH6HRaZCŧK 3OꞪۏPEQ Y< f% :r}،\txg#"$2̒fV W-|`e3j$ v.xfv$0>cXNJ&JuGQ4ߚj\tWo3lh f>xK &'Ɠ|NVvp63 >zܜF8y([ojۦ?zIKI{Uy.='9Y'Qdf 8H$6;X9PSƗ{H{\ " *ļU89%ϐ/H5etYu'.9xc'ɶZ_ͪ+ OX|_԰|TDf*+ז(aiFj%=9ron ϵ'1ԏ];,ejW^? ݲSq05urie4n]k*t7VR! I/v~0'eʐqMpz6zHJ'b IWO䉽f;=Hhj׮'1~7!H%Bsj \W82,MJ oZoU- iTIb`j=-hum4Ф&ӵH$h<$M1,9$Zbg -=k`RSREhY)qԫ/@a\J(?lb<*VfdJOJ/'i^jLZNR5)Xma^-x|!wiYlg3u'q*‚KQiWb0iU[XmЫGGpu7ۇ*-%gG|m̈,A@)FDYl_ 1Kw꯳S(0(t;Q %*Y\zW2Rjoϖ~$>]cH6}BDc/z|v\1ſ$_ډ%S2? wz#֡p*ԖBG $^UZ' B@W:Ul;~4I<"W>Ju\RLp!k;@\\?+&!?^Y,M) ]T|x 30: #Xu!ePSY4v- ϣ˝E;] ~k<yʳrmS{Ki޵H^;c )S]# 7ʔCNYM( N:.v5ȣr;)rK+:r07>ւr1,):'@T4 )4o#TL{T_l"ő!fk?xXY7 rJWsn[sw+ x֣w~xȋ% &KX`ekKP/e&Cop{.LAˊScp( S%j L`c*?f)ht/<f C|G17F[U,{T<,*YRfvC:keGsO^%Qm.}8bYhj F+BS l8Zk#XSpOlxXl)< ^L*>F0U2}u /qzo;ͯ`m]ڳ0xm_|qӍa\}tTq=V̻c6k/nx9cv{z 4fzjlm}Ԗk,Kl1Tb&[9ޏ4,r/-!ڋҼv+_X*p7n쁀dI &SQl9x.Ab[Uq~ vA8}9G)eppO%|nYƠ1&Fjʲq\L}Usd>qhuYOaPP UZ%@~R1}HAx|Cu8<Yh@@y|!yn.S;MAhB<0'0UsJ/w/:(xqAP4[u}"dmu9'rUpC}1LyS@1 MIrJ1ˇ0)ypqP{):M:BUt'?Bvo*F-S[k:kLrEG_&Lμ%ܾ;Rp01 e簝~9Ȫ-ym7fP2o=o2A{ KZ5Y\ s>h"N*,e=ūn "' =4v8U dQ,7l$qa+Qh"C_y#D"U/ n6FcQ83M݌ʿB#!VAj8XX~C17ٖ~fOs v:ugeޑ|ʀg w sE> {`NJ?BeGuF@ӻM=ʯe[p}LͰNE0>65:jfv@O&sж%tUג"|v+q+vz7Z5Q+|3#T3߶~rC7TIlͯOKwR?ht66,204MҁA/,!`'yŚ_(nt ZZMfR:g Bstf(Cy'.xVB,JE?\,y< d594&1UqV/l xC~` HV>,i%1#^[=pE8G1wfС]CyUцLF-zsd• qZ[qBiAIb?"v&%b{L~;8?&tpr6_pe^Q7_ygҘvff~6EJtV3?Ϋgh@l8fPGD-U|+^:;==O>%YltJuAߎ:CPy;o`ch8"s-M!.P[>? elAvN9g7* 37Ūs{?l \o]s,W/pEpEsLcktC HR qx9xY9yҒ8'c ?CbA(PapAWWx1P*?ɮL/Z"߇E.6֯\Sk G}~;u)>p#9.xXM;M @b!jȼQem oQV5wY3顡|h{{UHOW}]X ZoOˏK+_KfۜTz<q׳TQ)t{aFtI%Lf\h$1nT_ vžF6ƃ!wNVм-giW6fyR@F`iزZ_pbڦLd.т 5d_zG$'_ AU2i23irZ "%ST6Ha@aϠ=] $c.C-Wq{Eo9qCJmK9ḥGD3b0itޒuA:r'gH|4D$ӘT5Woꯙ<)"f7 kHHR\5PedՇ+C+]  7˚0{u,y9~aTT0ubZՆ+5 drf%#xa=>*%D\;$iץDD:Blpa=w"i붢:e%iY\Ǩj(*d{u5dʳ#FIϹ!}-S%p> Kწh~iBMxFN mNK6<,-.y&٥;3Qr$hwg )ODu&rtLs(e1k"s')~URPJ><68LX۞Z1g3[\4UϢn84;_0fn>@Y,"ĜZ#B3zmLrE(vyQ0G.ۖMKv~ډT܇#ZG+́.WKWJGB;6a[]K)sh?!.$Zm&4/7;ћӌh~4XDjdU}?} 聯 ;o7X?נYq@|/j`Ӓq96"rgF;;%QBN$x+y!L  &/%ĒO75-H bE2?nW d r UdHVߘ%հXl禷kM.O(yя^XOjK9q{̪#E3p*&DCgѮ_F4y4u +;Fjs}Ww"&M꺲Vpo|!l{|=j M9{nM?*Nvyӑeqm̪ʅQ[#W:9O9%(/G C4<%} (VTR`2r2+Kĥ=,U H/fADґif2,ds#Xl2E:/"ֵɦC^-9bZ~m|@U.UiN_o3Y7uy ffKD;=M] :Dp$ knW{{5p#@kxx{5^ %e, +Y8kzT-l_(X#FF@$RmPlt" ­i7qbܛ]*CkB,ws[ݯU$SLZi!AH1NɃac/F6Q:\Zfeo?kS@d8{Fv0SIk83'P-%qwu.M hr.~w w^/ KFpO.K%/Ki`idtuyFشY/ƣa&e92:Qwo:Jb%!~ 5&3ne<= 9lj% =k'(,HeX>rwJJkwY&_0BCVic-pwg; 1. 0$*ڄwv,ڊZHaSqHB+ %)lA.{@o޺3B"=XH7gq *?DUs7ލ\Y &>C,Jɖ;̥N# ޥ.yyt=Rx gS[vW{@vWK(b |x p?W uvQN0d~b}  dvEwvt `K!zU_= \%5Bjw /% ~FM-Tw^+|mY(iQʗ!I]䕮{b)5 M@Gag,o;Vr`H"u-f' *g'>S\\ZWƒ<\{-# 2`\-7CQo~0 ۹D[$.c&Zi]N(L*r2? HuFv7WT33Ur>&}G%?p@;W~ 8-3\Xx;Ί@*R1-gjAK~*C_ʘLj=ΨKr,Ų&Vi*5x\lθ׆異(g Eq^ݝ#vV9z|@A\#V9'7BG\$zUNLPg:ֶu:XQFJBϝDI6C%Y~},0[,oЊ#4z0[@*Tɷ/^3CGֿ cFW7 Uэ2 K]Hd4٤F|RaBӒ%۶S_Jj5"DMQ~Fb3`ys#3VO{N6 ֓ "bPqƟ聨[hпe")}L ~g<)/+'d 9?Cn!\@<,߽tT@t#H734![Xr>s @l6]O*.t.E9"@I}pm^&V ,Is%YJb njo6#ԙWgn~$r ۜnN5q$ӪR@RZVFoNaajmNFiiyé,LVQ!J%SO&97{K;S;ق~EW$$[,?7 gg+\T@p2ܽ5OǼd MY42yրKczb+K|զ&&y &'8/*Ip+57r'69cPBiql3 :|֭J7bLp/i||C<+Ȭ{N;R"M:Q"o8(_'rIc U8j.L5 ol@!1.N>>Ci`$R1}E{_eyLw\z)y7 >3 Bm|Dk3GEjaUW7? MSzS>śɊǍ,='.#1w *"==VGнy8F8&V}o1>fM?ݘ]ʎ̱ʕ4>.J7J"߃ڝ)K*MҗH46|Rihޕ[>3FR79FRvGf.C%my+PVqeiFfe:]6_2O{D薝D=;.>pMXfѪq)! ×˧Ȟr%Y,9˾R6pC\÷~ AƊݎ;WsZP"0_RQe'wa|Y@4$Z`̒s1y.f{NpA9"aB}IeY ?j7S5v]A cV~GЅuwW(i4jtkέ>w)E`{,^ݾ뚒uma훺|'X*$T:Q<If*T62꾁D GHƉ{fjPP[7/Y>A&(G3"m)aHoY eObA.=5) Ȑd GU_"G0W?baz{4x '2jls[۟l}qGgQwKZ7qmmRX4{vERl&my|!>ƊmwRR`5<+ŏzdLjdc\{%$D&gVY{#pb4 l#x +fCT9J׭(^ܬ)3qȵO2Pl\'Lby<\7|#0GB9xZu"~ΧW#x҃p#h 7>|2 ty38| `i_0@LQ_ gAsmp@/=J~߃mhX*`-%I.0~tobmׄ?ȩ$ѫo Lѯb.N6C湓ToQa8w9)NB4 x@Io7w$b\>t/E2zMp8pA?8 hd$0+$xӌ]*\n-t/ogg.O2Vl"|YڔtϴTMQSZțP/G$7Dع56r#m,uvϤ)o ?i4^b;I'^eUa~"9K峎z jpHu|N{R}pjòc]Wj KyW׃> W5|z`8G8TOq#(q#Z2}f?iކCy 럯Wl8?~uF`}s"ؠjq*Ix6nvّai/zDj -:KisKQsH WCXROHaphѦj #<:8x+fȜOp\sŬD8hl]3P݆WH^zR DI ipr o? Mgܯ՚l9"x&nǺW^fLNjA|YڧK 4#7ȸR-4RۓE8ҭ1e8AI7; &wU3YÀnU: Ceuvʰ NctlΠxw\5KΌ!QipzaDpA1PFȨ8fb~頻x>+Y* 0 t@v,ʟhͥVU +UYςTPvB'YtU5Ud 1ͫʤ^08#hM; vZ3*rp*;sfWUqXZ* Ϗ"޹ˋI\X\7FPMO0{+m(°pׂkB&3u^9 YQ]dEJ/36A~Q,wx A\}̸W6%<8BiF¾rX3@lp=rc~5M -Il$ C8$ RVF*g"- eEMHotɲf%^,wW֥,B?E H"Mmѓ1+ӇIJ^@ L %u;Rk9p} t-F+x_C;#쮲C}-cA4%aw:knZ!sIk"**~llME$uKQ4-j"vy/! .`VϦ{в? !ZAh]{pkqw =@ 5!@$wΙ7_w-U{~WUӦL,UH@)xA(w޿AMC(UCGw27>ߚaR+#otBwu+KϽZ"S`юw|xި?2NDư$|Ɵ&#f/܃jj"1V#'JE->8\LXK>%5b(Ĭ_pl} \g4Bz}ӄWo@M,p]PkS_89-DBZiٺ~[qXibͧ ]znDʘ@tߺ_T~]S,.fά[qp.՚z? u!+# zJϗ8$7r- j?MY&~g $;qqJCrWSI;(@I% k%6nhMxWƆN36#JeɌ>ryJ!n}|l sj)W2W6LOk5#ҁUNRǕeE}( =j7"=sa ?XVKq%F16&].H>U6~YTkcn(wz*T +WS +cJ}  %p5}_pdt-+$.hA \"H|xz̓wV!߆ Jb^f3ߙzԝ6s`k(ZddgPۖSl*Ef vcz$`j oXnlk 5эZ@esS*tXO\*H*8o?pdVWnhubږ~!ᑇZ-RG˲p*(@eцD8XNBA.pr|xh^@: ze7, U,=MAS}Er` "! &(䯮TiJR?/}y'ĸlV{Qc7VN-j] Xϭ8(}@۰|Q%i`fpI`vھH9FȻّ~rz(6 }0HZ<[FC+/7/浵ͽ'?Yqk ܲ{}H*hH 䨘 W$i(/ ~t?ُOM4['Y:i> mi~ߊxn9qn_o_jwgoo7ţZ*JB|{'_/ 9KF`^o9 &=/C.\ot~g|-{>i_G2VGAUKMm[C;r >f߆f_OϜX!6O*Bkr/Yxv{gÙo? {I˳Y[Ys1̾M{5|d,OIUs MLGOLK;â"f&dR IsOih H.v2{p¢!d `ßkJ>SRs Ec$]7k\V`a-LW#'!g fo_ǚpRXzpL棿A&<" K<~F2à xޫtRsiWǻARJd'}|/F"+,otz ?h& dH gHu,߶yBH铻>OrŁ'>Ґ"6:@khRiuC;|`cuӦؘqoŽfRVUe k Zˊ䢆Z .҇sD~wӥ_?j7U4>ʨB kytn4.tX=ժP E K&2.3yظ.n kh\;'c"jb3F#kƍn6S! @? @i4NTke4yfypiљzF`V-Uf&>Fհ9[K!2%p J :9aBYOݶ)_M-y?1}AmסӀY=pBveRl4+gY8$X7PFQe؊(٤'x_5㲻 { 37% >"yŨ5cX^j6{0«KBw mK4%J^|8YŖKS)pt^JxR)hAJ)Nbd+y[2!?G5.*IQmk, œuUCiL|rBu$Gs@w,s:{.USTai^G Z/We!a?=O8 |ΌA"}8yMjDIIBˆ no5"6I5횃e9+zZq=;X32ރfp#DN·#[gu@^]IQ#}H1˓RH(о<?3(Yɇ彼Уo_>jn3RuluId̝#uvr% 0f01qisHeepՅ+[ze=as҄"F- glq \{;B(. ?WI2/_vsNkο-,qZX{{od3a  dBkO ƅ fRp> q;A|XN]He'`rSpX rr<%^+GS7;cx;g.VГ P1x"*켬O?XAܿ8 xl$x'dfO(@V.>_O95@֧Y9~ "ss[EO$cѓ 2 rr@)H98| &Jh/Z>_SnI,1+8sr>.qp="/;+zc !R> +I߅s4q9~qZ6M!{ЏGKAs'd|Ah>P>!@q?Vr9:z@[Q p9k8Tȹ&d"F Dx-|h}|F%Ĉ$%p|AĴ"$b|#@ = ӊWvSh uR6rH,-8%@w d@ BĴce/Ǔ*&7="^BMIYɊ bsȄRE1סJ )LBR5(#I )ptqVAs_' Z ay:^QȦwLXl=HUy|Qi={aV@fо1Rs]{+~VsދBźٞ]߫[ 쇍+-wVn6gИ3q _I50n2^fX߃.l#]emiZ qqښ~jEKz援bLXbBj:4 ļ胗qWlkM׋L]vۮ??yb"m頮Tymt zvB5*>Ts}w/XihYmQZ']BbE |WMD&2n XjƽY)ۺ#&1SWD$#+@9߰˵.;gY(Ƀ{@ڌRB};{n诲/V/WVBaEtхUϬg3V;RbUi#PQNr )ʪd&8Mհ2oZIQ!+ih)OH/:Tuʀ"^^ųqĹyc8ZB:fCd}=Y6Jl6mDǤٽDx tcyA蓫䐾kd^fq7Af:3A/ᕡκOWu:ª, O! oxQ k̞G`!%Dg0KʉܚLYB6{X\24FA6%w$sA͋ =6c _ 7fMԛdDLO9 -yQK*c |X ;z'1N4}ˉ}ۣe&_R]hKEMk(sY=I{2]=i2+K.<{\c(`AR,zt{lofŷ]w:r”>PslA߻@l\K-JK!`%[=Hbw[ u녔b<%WV]q[Ҏ.%Ƨ3 »Өnp̖~x8ʼnncz6{JZۗV0Heh' UC RwT91>U傖?Osp/oI|*Qt *jH#q-]6jՈyiԢ OPk;or-y >ӟ`طmg[m2Q@Y%8WQW6:eU[aΕss#9bSժk!akhP?Ó]a "x*K~).H#vIkz5칦vOv;L>l 1U@? ~c#1 +/?ttv=LE}#7!"7{ }}B&6x qρOs,@op?}?W a$  xDݠGǙztfIr?r<.N^_^:Gx- ֏ @"  Pxɰ,$a 0dGΓ0 -И rBpu4`zU5?Y@OV\HUOz`:%+k+) _L/YX a܀8{񒐢k!@ #@Bn/ng1Iw ,- pop/rNlJ%iNHQ6A0qi]z(A2⢕Ъ S/HfХ^-O7:/_$/NϾkhH%2\u|vs0+VD$Q΅ ZTyTU-&2 ۋ.x_YX[ʊ7G4] d hMn&H/VfH`}3eԹBًoLP0pZq̴ݶw.Uƽ;swZ]w<1촒uL5`22="_&~AA_pi[qCbNx~~epRmxMo闟vlļ%r|zܯ%ͥoDʿ[Nw,׊ 4:AǪr_V?mF#-.YbO ٚN7W_HS=bhDΒ8&E'bWs&NaS8E/0 m1xL4*[Rp{ύ,t-$Ҷbo<~󨝟|=qb:%Фg`HMhDmbПrk^۷dт5y3b,.0vUrs-}V Ç1:"AP]_11:V:68M07jc=o ,kO"j<"@@y "믨d/nI̎~NhKȯttњ}^D)ЉE #9po?Rhu[}C N2эg,§ mGn^1Nbw|dFIr na]C^kl/jL.m0p,|^Ok9OfrJͨߥE#%\]+t2pGT/DLx{|:Z_TǗ&1Bg88K!C6a'sXrPgfTPBV:>Y2JB&ԧYv'& EӨPK񷆼C ®>m- fo٠IȖWHk/lN44Y WDf;waCP׀(3K?m d[n7pZuڐG:8Lw/1cPFEv,K¨Hͤv=U%N̵9*910CFpFZKV[\ Ø$QuNr*D`t)iZLlx8b֌m^ar[pUG;\eS8A61tf]dϢ27~̛ٔ CiHID@q3k ftHe-?ee7} IV`wHz.&x;w-$’%Zu/{2$gDJZ y'.%WuÏ)K_ M*Kjl×⃻i0H[PK5 ~Ij#"pYy8  S!C pOC2-wY5c=z ?:,xW[eJ0V<-@hH~AvikhEmO@TtYsLwz1{Ueι 8/D`Z~)HB{-}eAXϖ](nsU% %pVQ@ 9;;^69OU6=[""D|"R,o ~6eh[nL!2L+t4ּW~Q3 7N8M3\wv')~&* .M]ay[K- WӊnSCJeZEHo@(i_Yߛ(X,fynE1,3wW4fZ ƙ!-uyou0it|d𐉕{m5j#\+j *Wʽ |A`h׻<3eW+!斚\ڡ#ҔXt5q*8T.vLI7QQyuE`/<)HZMMRwSD 4VA7w;#/V8S/ Okx0IS>Ǻi 8ۏkO7Ё#LDC_v[#лŒϡ/JE6"iVDGS`@ PL1ɶbi40[ sTҞC V%m,v02=s*~\^Mg/KАƉpSX48{lL~,j `Fz'ti׃6/j,rꍃ =|iT=MGY,"U{cJL!Tdy/s(!+`Tq~r@k\Arv]&2ǢZL#hvK<-4Z~I ayKɻήVFEx7@Z e"Uy1O@7U{Nty;z~7m ,m`~-xF~'Q9++^BK b|x"E˓a `A~ c6RnVnv. >VGDM4_oOlݫG|( CFY~bE%@'m7+H;Pi#'W}H=5 q`'t 0<ŌURTSDH]( zQ* `[vzk@Hy)1,?LMz ?Hx F:!E3h_ JX;1g;$7\~!FKDDD/ L`~Aw>D9 @ H_C*c}!X\8R00'IP =W߼,SpA&#T`pBDraCUVR?;=\9~QEdUM{.L#kz#*@) Xud}^dNh!UW^4?Ɍv{i9xYߩF+ x;/@t%z1ձ>*Oې8vTš+Te7ENAA2!|w%8HEV\VmN^m/S lMHC{2z!%M>P te]kiOj9'Ɠ\ z!"-/?wlw99/HYiz3V Xh{5+/p^(x87j R,scn4RjxTZ5Q0j v+L5_sej']y[z1P:6,|~nbKW﫽mI?#eJh!]g)g`W$l [f8MZWV~MLѸO8w9{j ju1HsI~]VRySևp+.Q[nJ'q'l:Ypdu=tL~Jø%7j81P~K`k|ٿ%t$cD F ʨphMڞT 9]+ͶN/Lp#5onSEH?TE{Bە`FS~*:cNlK\ ]/(/l]9$ڥ_8܊ U{!}ܼ җ_lLx܃mBH Cz$0BOu%f*x5$ա9Fv_Ya|xj4V`[3=?9)Tף5zYgcgԱ%:(=`Q3AEh h<6k|!{H 6ᱻ j`gY@#T}ϱG]h|DsP@:DJG;[0~Brzr!CvׯTXvhLz% V`@~RT!'l`p .Uȫ?x 4 ҵ*36__7B&]#S|qAL\Z4 ''/fdJRxΨ{w:*V6(0('Ti[ՓHv33E~xz1Cݳuݸy*Ҳ4rEUL&,VJ)C:fߖ?\2Qٜs!A`mcQw3,5,Z%R|r8Cx۵76_VZ3T>J|}+ŎK@1Z;le%\TH W`)w37:RŰ ~`Mi*w"YQ@蔱 `_yy"= ƪ:)M%fmK*bl^viΫq ZTu,wMRWx!5c *(EXnfgl|Uk\U6e2 #6Y1@:DŁ}t+=O#޼X1ǖOR__Y O-e]9u(\L"++V:F 3ô_!UfA=; P!T=h<0/P*߂>V$<[^La%@96ݠ7xjktBpw_Pռ Erv"$v\: *Wͽ,?r}yrp e{}`nUȧ',c=x}=N+L|#Y ~ Ki oȋQ`*NA `_!=C;B4bRP32<](EqJZ+ 6޽PorA޶W']W o0JGyԯtjow6ɫBؽ rޒqP&;RFGn]q1s\^ڋǒ^Zm]98+g[L䠍Z#^ϭY;,܎'?4'͏Ofab:t`*TAPuA7a9K)3ϗKIT[i4xx\ EV2 b2aF5`l!WEghAo8vo?A^FWM&S\G2ª9l8>,vMs00Txmhc +%JCvu !]k^@3BŴ木QSNhLj}Rwph[/7#|9)p˘y~0id-H.KZL1[śo'ӶfwSc]lB*Bc~UQx1K5ITbmd٤vIF;/8$bR$u07X]`ɸ 9oK&QqFQͅUjsU_s+eʫ6֋ z5xӑq,I_;]q?+Kihgw1J` PHސ!lM&HXÔes/k C.>8'Z3\O1~[5*7sQ`]Ďjh9d:ل[ uic]I6tY*]$Ez$/liSI$ξ=/E}K84ae\ֳ2y#ܵ$KJ_$2v+3['N3}f%J'6CqO}{x$U}Ny툑uF'O3Y _0o+KK[00-jTޑǂGInyy-5^PeW029ѫJj_OA܏JβB"ϴO43"l/R:{- @W,6!8W?LP9FpS'"찐16ռr͂)U{@2k)!Ϣ@qJɴ,\ 16 v{/Wzp)܊1 B' iCYϖ-+LQQ'0?}kT#aCdȂ4c,yI4Du[ִhPڤ.&ѰCxz?voB\?qqݻC'jli/)u'U=d&9Y(rڬajc|U^}[ Nrz*+'kGx޷`1j·#zIIE &<\0-l޷B6n]Vm p}8mY3$к{0hj$h~xS<Њ=oXEWKxL^,Kiccls4ۺnf9\hB融NnGbQk@& 5 oAϗ5&1Z}DG6 , cr..34tZ@G4SxR7$7R0x] h76Q \ǯ^}jOE.zŅ*WO39v.52wn6E]sS952NKd8衂+' Zy0jc Wo^ Fː6Y(l~Ҝk(nNa/}PL=O 7Zs`[^Ywi ]d" N)>4K@:O- '>&y|^9!w=t,똺鸵2fPvA'24C‚eF`U֖ܸ P -[sKPO}loHI #K??H.d!vOJ6~g'wgGcxX0T~eڌGc*=Ot+?_u2OjYٚ]nqTd-E47+]l"B7\+o1] Gl Eʨ.edo\We/yBΚմG Z~#1ˮ@&zGVvi,G=s8hJ?Gj2̍U'oՙ[:̢S /ԙVCy4{rY}nZh1Mس.\HJN- XrX4DHGh) Bi MF NJP&d{d~- 1[`}d~Ȭ(W+>F#.d{7ҔGy5 ΙXi=!^7[%/},osтrA.k3 C9tT֌?!ocn+o# 8JE䯯x00v-jLItP\5$[";-0H܍3 y\g=.+ GY2+5`?8>x[$I4&f`+nJ 4'۟dI/AmR/̉-Lm -8\̑豴=!?}gqu:uփX׿N6" `,W@UHCiy_:ؖDUȭ[Z4gIw疲wƃNuqanoD$܌,zu|R*6nF]C#UKS/~?‹jU "{?M~o.Lv=ۋ'>efG@& _LLǔb27l Վ7hC${=,.r`of?_Z$| 3*H~v:gn[q?ӈH6> wyjh~jzMT <^!OR_ڊĂc^y. nX-Ιdyn\{)SMdnӦUR Ȏµ[Xnp{Yx+ͯwt d U=1h/x2$\>s_⑄d{ƣbpl+Z2 W/N(a\:Y_D.bܖ6ɎJK7!-2'GW"f|U}2ɠ™ԅַ7th$fh'AOC 8~@r T?4:ri y X|p Uoª~֚]ExQԬYØilpyaGy|A4?-cJX(x}d>ܮNOR\1;2ґY/At@nɱI9S:.=zCչ!̝'f[Kl) ~۞2#$!,q'p僳u{AITXRi+`-YעXݵt`,Wq=fx #`x&1-?6n*/`KvCeC.r듀G ^uu}{=EYߘ0ڕN `m;UiPc,L$͟GN(ʜ[c g?fm~" -}" 9 +7Ҥ%]4ߟYKѩ4.6D뵳Q{:ç!GZ4=o6Pסj~2X]RU贑AᠥA|YZ"`O #sdRHK a%e/ `9؊L YS 8ǚy؍&^o{!)I̝ߚ);?'59W(K ΐRҚXMߏ#hmT`/ b+DŽEOaԷ ϪC4=8[z fOPvh5[ʥ~r4#ЪhyRS=hL7gc|MkI-]wJI(=?1QelB؀{:SdƔ |׸ɒ ö;u#*) ☬)6;v|ìfnX'>tT~0NB7Ժl63;'f|?(~JR0^e+߉}۩EV@pD+r-ujc^ş`e?P2>wi< =w>"jZG>EH >6?9na{YlY8?(VPd+? OTH,Ml@:v<aqˤQ`j|hј$-'r޾1?C~ouc32n`6#HWbԄ^f[pJ~Znh#nd" ,# bńϬջV+eg5^IZ95DIƬ=K]nY %`LN!wyl[ +<7R6 æ ztw0֩EDjsbLhGi[ghhGnT(Md ""wHny(d\1ދ8̒yۻK%`nd h!|ap>l 뉕(u 2~~xǺ9"j]1^TF;D\|qQ38Ql0J6&wESu;V3lrFiA9o{/Z"5 11 ֵ:>?݂otma@I@ONlu3D N=d>UN!dR"Y:b Y%E,/+fRZއj9qm΅[pW p"j ^Q-y*h>WzWؚ~C"NίpݗȰj w!@d ' 'BBJ׃viSm,Ty'~Eo6X8X gWǻ1*!سZ/i5 O_iVAz9 p'{0u&",ҩOf3vDY7u75xGA:s1N@?*o%,>Ms'jISs X新'H.%x`I̩~;"ib G_7}<`eWmIAHЇ{]of˦[uXOY@k),#g*~ GĶX|U+T3G/I>_bV jWNuߌQͧTᰭF'+{Hj/z]cqu5'?~t<4ZZm|t&U}1Ks |+vnAiB ?af<3X(ssKrP)ecupA 4@F830@37@'@8`sp;rv #uuEߏho-](8%ߵc^!p˃t)b<"Q6҂Ŭ@)aW?-/w.c*3lIҭL1:H((T}Uⲯ-su0jFм4N:=^7~ _K\j߯+>{"Cqexp2`ܧ=7SJk go{ꐔh0Д & mJMäS"KdaA,|'9z[yli{}Ж7E9Nu`vTN R=&y#yɭC549>FN\bZ(aO#HTy[c+GsWȭ4RV鐃ΩRYoRi 6i5 bT.;l^ ,5Iy;Ngox!v]BH#*3U]V@ O5WA+<;x nTXnEOC`תa1ܚƊ1]YJQ#1گQKqfΏ7n Ɛ$ gB?Y iJ$u'mdJp1WLƠb|D9Қ:ni}10+(NJ>oͼ5?ڪ=QĴT.Rz6^ئ#@҈eo-\dO#QGJtU=K!oZ_*qT.Ӣ!ԡqܓ%<`e`ဨh 6;,9Sc霍h:Q8^WG23n=.׳bDqh?,Ou5w*lasc]ո"~=9^8譤|8\f!dSv&^.ϰWa7wh|j/ d5:,fy#nae;Naj'm)bm5J"|_O}{ٹ׌sӺ/Sf~C\"}`hʊe8ʕ"rlx*L *od1g7Җf890&?k-=XH4^q  WIا4Q?nzS IHe1i? @#:4Ocf(D^rާ6, %;-yĿs"ɮfGf_U_{b]T$lt.C&[.Fϑ#WH],O`1jcc}98 D 'Xgf?R4?<IJc?'b`c0uh,yH }@9Y ݷ;Q .3_gkS;oѤX-Dfk?R$}YwD:xZKu7vxh';-aŴ]s^r&fY@!'Tdc#F)Kup㽦xn_"cn-Æ^:LVbJj~ CSMɠz $cr6'A|)=kiO|⌏#bieV҄Vk/u Y+=<\!tieAW2 bacs}Lg cݼ790HM|Օ;c3HB}B4"Dɪ0Sb`;:N8P?UnT)9HȯB \-֜mrgqL{za-&Q_H n䖼'<``cVX=yn*ߣ܃kq_:nҚD6&^#$Y1-K=KxU؟<;.* йv I_/tZ>}0$%򾪐04n}w C'򄟶7M6xB9Ȯ&\fi Ú|TbH`БJF`5ŗx\U !pXP*4EPxI<ʕSi4UTwVք+24n\Tx)SJIw<|Pݵ,׷e]j|Nz+ fx S$Hm*UF@ /}JY(Ȕ@(t7ex2[dnXrȗ^f0bC6*ၤ[SIJse!<ӛ (QܤQ}ڑm7I< աS mhÅӮQi׷#FCS7 Aq';A25.1D#ʔo`1enөC 2fAO݅T/bW_2 '+Ȗ޷6±V]ۣJvK>\-1MS E;OѨ5ϷMVd.Vܜ侮e &!1TJ\0Ws-pˊ&$/;Q|} f5]d2T=rQWYs.DH]Ah :tba.k)*{]jWP S _JXGr2P M AA)jsz:_xJ}Y't՚ihK\V5,\'};2Q`Ln2di>Hmsıۉ|tSERb/uo hF*OU(-?&+V:.F+t{p,,b048h{E%5nWgr5U#괠a?"G+&a'85;r_}6a /Ҭeπb3Z,c'p9ȸ}~ XWa˸CȨ#`@D5},Uo-db K4O? tUVt<doBhLP8P.^je$)ֶUHWІ$(-gDt|:g{ZjPYk0O'oc]tc\ G#[E\sqV:eq/-yujb7=rKA5I`BAz'_]C^wH}mq/^X2%vR*Fջ0{3y-4v}CUǥͲTAa3zҽBCg;#%#uwI3Kˤ {]Ho93v܊پtm<*#nnNh4,ќFd&ZwW#fg$(bZBXH 4`$Yϑ"GIۡ#4xf=a>Rgb/3$6)Os-] Y>57WݾMG,3hQ3|) ON/`@J=ޕd !h >_rjt:Y2ʝaj7ņ J}>zaRwx'A g9^W(}CJ!(N4b if4b7 q9'{%z6+hǔ9pTi#p7^i(n8wjCT0Ýn~ΘcJ2.A~9І&[ǼGD.5/0J 't߲Z% f#сkJ4w((&h!>'1bTbV5b2ޢ3S6>z3?fNL$qm_j;'{[2"r5z@mC_=?{)T {_P`Ҋ'.v#!3 Q * fІ=9Ġ{ѠyfdQ+;2K<E ϗԬh/JUȹ78_w b{,KxQ2ׂdD/4]IabqƲ4+[` WE}RT~Tojh65uy;lVt:)̦p+g7~Ce&}eN˒Def Wс-lT{l".ӏkC92-^ח' r-EneImg/K*\mD Vb6mO {$ƳI9.bZBah`M75/]l"̙) Jm W B?Z=/"zXrńy\+}1>=39JHG::HUJ&)taZ8 !<ų$QEg_dթi*oGKU {Bf 'Y:LE\Qcpjg8m;0\J012W-;D!w%VVBjWy}H`s̥[e7y],tuë \0k/(9/7gHt!r[sG";CoQ|\\gF 6[oa[oa C@Ά8@fH@ YA*XbBH8 xx%?͘!/+N$ zKa#8TJ k^pkh ^`!!Y2-u듟Wɣ?OQ2J=D .0@ + |(þZ_^yp@DH%,P^^ Jp@)oX vb/1eH,ܫ34P J2ÿ}Я@H[;]:OHeW7*Ls'"xaE!x^yc0(_M!m`¤l|(&W GSOx 2u'?/?'/ DƕСA A˦g)B" Qp)@ 6]B%d^׏ ,Q!>H5!9OQ/(lH=0 |()`yu}]#Hk[ 16+,4mX;]TޣJ^6Ac68dwua՝$79w&gK -Y5t߼?Vg9U`5?.Y /V.D|pPV |pK2sdx>n.-;rAyM;a7x99NT:dY ]Ǩiu=J6;io<ʁPNփa QYǰ;I;˺Kuh?+g/5qLgU˼{'qZsT[:CP2h*IUV7tCYsM)med/O syT\MS )݈ȴ ku28k{n`dn ;UaQ߫b'X (VDth)rl" f]F|< =oV?} gzͻDvfGJ'oծ-vviqBcq^ozf'6ʉt(UI]/WI(+-X*K12mM%r(,l({(t}VUhixݯf;7R<ޥBK ^1"0LbLB2` fNŋ]_o%)z(~﯇egmr,ݸkM qXCeos "CM -9J<Á;. +n;{Cn.Cһ/]&?3N`lktcT:e,RBUlŪҿ=}{ 0r7pJaE"9=sR·f @xixMEd^`q~\><䷋%q%NGXՎdSTkz&E uX(zKI4ټIz,TVdIŠnӪ&Kᢄ33F/w0m'ԟ'\>OѮ|7Pb./='%ٳxNA!TrGxD}Qg0ϙ ߌN{ɄJw$OjUyO⊱`vy{1G:A-\NzBZvdO!,rIe>@+Bь9v&v\!Jt4"PnI& ½P6kI^Q=JAy}/&Cjū;)k~ fEǏnܒnaY`(jTv6ijᵂWT5<`+!+Ԗp 0Z-[ j$g%+BNthpsȸb~>*Wkߙ )[%XNh-#q0i4f8%C uUe79"lFlD϶>d#>DCabZ6@G$xhv]Ҙ?˅ӏ3(tJ~_#K#,y"ip6y9ɓU fte>ŖϛyZY - 2"j-柵f<ލ1}i{k]q`V$kՆBEVi`R C"UWmbH!U!K0LEv{>|&eA)#lJNԍrBOX fdp+ؓ7wy~jw&BmnLm7;j )Larm/'fnc@ql 8M65Co_t@?UNcXeڕ f0,$j#% ^֭Fi1_CP ?D3ϕ~]- H͙$AqHI00"ѱ__I οs=] ׂLxͤHBxМ%CmhvmH h =YM T;Dza7ofeˆS3(!kf9~X5Ɓd~pDGy^bB|p`Oq\_uo0}?kPC^n0@-i:=v]'\3HhS `JK j@q?e3h\T ]޴66Qwu*fN1`OLt t!kUr*}T\N1ODT3r'gg+sU5u{nSyQ͘41!ݞBZg)'_8F NJ:j Õ5A0H`n~$uJa>(4R޳\.pe='mtEܮZǝ[j ͝s^:nnxnP{F%`&^ˀPC?)JKMWb58I-F!TH-';t*ʂAU_`d_`^m'7ط"ue܊$]Y~dfi5柹. ^sR@c[bh5{'>! K (&'GҬϩgZ? Txx-n櫬i#"pb'>P- *ķ"k,X xv# dm*; s px_y|$:+5ѣ*+nK 0,*֫[(Z Wc66f׶AD|v_ǎJFQ_ :I儹l %#SI^Լ(cϕ *sDFuj(9]I&l|t}<LP-Qp)})!f4Lѕ&m(y-qMÂj:HWZ⠲^~\.ٻ/ˬ_ٓc;yG5fD!Dp!N匼 wӨ o/1g'qu+qSm^W8b yHC&u̫N9g/ Bb_GSΙ![KxHt0 jĤ׿PFCe9y2?R5rOOŌyf\xfF_Sָӟ0!, $8%F`WY)c`HH 9%g #¼jwS6\q-<7Zl晷8afqe&|^vh^9G]\*^lXNl9OKa69~8@M{Pm4CߖmFC6Vy:=aEйOɳrqJ<ƹoX^Ҕh0c"yO3]+* { ۽D boH(TIjqZ26kzadC62zy2[]ou%ml|z,og+~o)/.i-)4Ye/҄fB4%fj $ /0N[,R{4 ekw(fv/0y#ZBJ>nHd`FZe-aIe=22QFKR\/S=GC|۫"4@e#v!\n HZ$ ա#4j%஫eA=^t8L/T]9p 1諏#,K;G\LE>]ccaPɢ5щ2! <-V# b*40}SzYaDžӆ(@=>rGm W|`,ltDP$2IBU_3/Fddd@hyԲ"NʋErFNQy7ڰ\?u8*55[HA0ʥ;̖bB$> a#;,jS3ftdJ'ΩU{5p޸qTyǾ-c un2ߋ!v_ (F,O;[{Nk'mT?~}QD 2೮?M<3~8\pjߦLjU7 _A*)/a*3p)0Fi%2ǘ` .W5HwgYz0Z Mr7b--#X=[.bciLrriG񉉤խqUhoNn=>w^ڤXIqMuN}Co9Y0d8MjbU1pheD0>uMH;ur!ڹLz'ca>tb#֞KaC70̪[7*QhDŽ+΂Ra[qj84=Fۆ"gxn=R(x\ w^6S6lάG *-/]&m:#ϜvAOY%Qz? QowVkY|@aVsYh,BElDXz)|lB&}[,kW7+"! o::D͖"_9Knz$|gavx%wCYuo;T/lkq?w۲?ج޷m0翑33v|}"T5roпL^7*HA Mmm$+CT7q_L w)3PA \(Aao\QhG%nk(Ĥ X2 w!C{urɣr[b. 2v^B%ީyt/ђAЦjr| ʐ7"H8,D (=]"Ka-JFNKj뱓F̉I/Σ^'^Vkf]id#IjZQ1+q?\w?.R`3x%{ 4cI"HݾY7)(ZBUfs'1z {+:qh}DpS,n ۑDPic~=.?\f͟mAWҽ ٺ 3}$U21f E?\+it%h0"CJO+l5n9"7]\ nڠjD>R`թrg>m#c mS0 S}F0!ë告sgދQR%d3" )v_845Ecj %U©|n-2&>^=*ħ#*CJ%YV2֌U*(67)cq ]+!>]wwև|GQLp'w xVϢJ~/C~I_͎v '+L8tɟO mS  `as}D4! X@ZxGdA2B; w/:Б: }sbuJWOŧ4yR3)5,_Wa.N_gY0e!r((\J0-4HD2ɉ8PFX] .Q~SMȰsxYedˤk9 p8-ܠW׻j} 8.^qiQ砍?1h$.b2#p]|dO߹h Z#B[mk4=\1򞄎sZ"e!4@QRUGE 8u26EK͕9T̲{bCq8h \H~K1}?lL<+:ﭠWOc'qϔf1 .tߗ k1XNYEVvoU_e9V.R~? ,_ln!b1F4'@&螔.%?<C` ;>] -J-i=0}pkwQ'r7V7(#D3 ̂hjIx*i7 ſBb~NK!Y;C dJWRҊ&ZpZpisALSA@[> &~04Ю΅)T?D0Gqw@X*$VEԽ=lƊӗhӪ²Tc|)F6`9_F- Jhe;Occ /(Gs&9PwDA)!,8ν_(1XΤ.wʲt8uX Qg;-j5O* ı)XGd jΥLd.ɲ%ˏR?ÀA0*s#JYm]Yњ+Il6°W͟w ?w7J1AA N9xoS+\Ի3@-~_j-jo#sG}a߃q^.ߓT9v mҙG(M3M{**/㇝{1fdxl]-4ÜZK͎q@J- Z@Eo:":1[X̌Gs6.Jn <";(D(sR,9*NY9cv)߄ʗEe95-p=PZ¸JMLHWXq(Y흈L,"\_'3ftD|LW[dAͽ|?,%ӆ߶ t1lje9TS%ԧO9}dWU{QPkx3ӼJrzÙ#2 R?t|/ ܣˆY$&nXŠq  sIV'AsI^ RP عfĒ&|7>Nbd8M>CYyDB_u Hng(ZO˵ӯ^X¼5-#!ʅo)3KZB7li)$ՍUNf\\4eNk~: l^?}|ܯK@fs"NTL 7Z2<2z)+t#~7 })d\o 7?x6[H *w=fauѵLOQӜϲqC\t)27J97r֯94K߮Eke9R]^JOYcNo 4ˢ-3{Nct62Xx} b|$9R "oxfG|@f$(iĔ]'$#VΓn% 0q;Ϛ^v tް4q\?rE_0nh9$z |s,bVy,꓇%)$l߼ck2_R -/(`EriޕfD?!:Wfn*ד|jKk ZA }Fva1VwL=BbB׌z>%|~z&(ɚK-jmǟT`09[3"eĀ9[rF6#-n5u4 DNzvI&T+.pnGrB?n;5%\GILXԤI i.Ӈ:nqbqycQk}b͓Y+>gce5wR'ezw >#LӔ#ri`UY> N˗A`Ն+ Hc"eG[1%E#EquXK 8+,[\$b!t gXJI% 'i-IY/[˓ˏ0gB+u]7Yie5d zbLQ lNN0CkSb; !4E*e4Ց{7#_2)(A^ ͒HM +l=Cʣ"L)xEM)S\Z0 tнQEgxS|TsAQ"N@b#~Mh6O|NxX 57S[wxI%)].6l1b d}n1ZO :a!Ŝ}DRK"m a[rՔdmqS =bȮX7n2(#Fyxה]^YLўKa5SPA'JDLq^ͳG"EVf3^~X/0=2 g 0}4@~|@Q~V=GNURi>{_Cv9P]ҩ:F۸zA*f#`cfPhe3T? GvmԚ]yc^]: ~4V:5@Ndұ=\v/(icd kQԜl.վ]!A>1VBfF)͙d3UY벳Z'rt[v.wNO׏;[Lt0EA7䁭L7!/EEn28FLL<.J>>աJr%FXqaә!z~UT&7m'A }dѢk60ƨ^RZMYHQje' )Jk|dž/M7]kkhv^ś1^Ϻ#;| ?񗢨H&+?ȸ@8Lo[$4,c[麸.?,98:4y:HKD *`AgHdbAaM`)G3:I;t{q0_< #=5Âtl}iX'; X ؠn"KQN[xVݏ<>_FZGaXRQu3E emz^L]Qx)S?(޳3ԕ /58NjO)̠ᒪ(HyBIa1=+q\oHթg KcUOXbZ-K<: ^OT8UXOy@ 'R]kB.d}TaJ'|2Iq8a4ux-SS\迚ػa^1W.vƁMegFO+F 3$*G`m>T4#aΤ!9`(Yٚ'@C<ܤP=*iTAp!d{D"]㢹ٺ}|,VG5%Ю5B6f UmhIt cyV0`vIHһ"CȔ'z 'bw'1OJb j~uDB-} y_^8 ؽ~f7Il;=_)},[}:J#T|1-1IsIϣgxM.lF`};}Yߙ֣:Fw.`9q?RA~~ԝo)6"s֞ >T`CZW$Ϙd 8cA-=$Z֪9ykc=(bZmG}^[h-u;j c O  ^ZK l2Wc%<5X<U+3zXEeN8EOSQaK)b/3۶lhhfohiz])z' f+Vn# ge{#b<_~>ʱcepj}\C[Q7ksHGi$#SrTRtyR:o sl1cpDO`{riu-hA9>j4\kہe akK<_.ca;y&w_i4` GWhϷ+_[:~r3IV3 J'֟є /;jH"%KF1/1&1"/HHENV26u"hh_i1Rx p.kȘ< Aсh*[8U=ډa~t .+XBbr #zǬU bbE@4l3 L9̤~R!jn8.{Rvచ K4nV=ƚI|+4BUlbpr|E.Z2~6{LgrQdkPrs{;uGw3ytj:{9CY8" qHh!_*NuKҸMC*i[+YSͅ5>=ddơNh&PSa+V02dW@ ִZnH`{$9|xO$bJ2ziS"UeCm38TN.T6"Q&UߋPl|YҮ tHȝb{?)P(m?73OZ|AJM? Ba.C\Euݪ=3 M|iV &u>Ó 3d,sL_<eap|Č5ǩ2K>c @CHVu)>lVCK04ZV9a$Q%^c+5D)N/:BH<ꁑG &f3 wP23N_3[(q;tgKƄ|LB+SB|**wM8:2$eM /Ma+Di *(eo ,'s ""Y+L0 f{Rz;T;1>ʸAx]aSeGc$)E%`tU${Ue=2\sF 8Fc\qD[-M-04W _*3â} I7΃zmk#!IðB@vZb_'*(c#/V$]yMqDYgǮ#ON2EM(魚ˣbWmz%N_z7Hgvw5qfPQܹ/.ntyȦM=kAS3;2oQ\!S⚳kHp+CQoRX[s`+`{>, +oj"8eC7--/5wx5L>,V}hSL/Jnt9 `FPSըD?)IB6$I!*<ɩƩlf#| pZk30fifSF`m݂v+R.]r2ySdnzQHYr^[ʋ3IpocsSSG60,$ tX}XJ1PMߺSYھDy|—]r5*02vI5 9Ȯ_e]kByM`Gl0СM)ZXE$p0Ŷ a /SocF$0Ai8ƒbB"4Z;* m k0̂۸2ycߑ`7LNU­U Ό1 #TM "sk7{^iUrkjزgꈂtRdIGP?%0{=)_a[%Fc ͼjeɁ.ِVsnu$,.MQ*fa4 񤷳U8KڐD4<%3U3b ;\^9%e(l/25T$`pnc*ntx-aτ+ <'2sImB-ݶґ‡FU˄8A2cRC#cPF|yxWaK*vHЗr[Z=쏪@w>z=#ݭ~;J4N$dC<y ['2:y~tGXRLrc!uN( V'K1yx ЦƯ/Mn_>T8+"‚ Eۦ#C .ӰP(y<#HUv-1a6SvH+^ԺIqk}5~5e)}KCXuOs/qeį(^m9ۨ211JBrĢ ʷpm6T۰o7'O<JJVT?cel@|W2ދ|&SQ_]T/ߔ:^`"'_!n)|7$wtM9Z-]G$IJ_x'L'; )T0š5;P/S{2gŦrq*yepzYDHZ7|wbE>sS/vB='ṮLӋ bwYɘUt>ĤHӈ:]0m1]6xX UwmEQ%.{؛xV62V;??^" - jD&:8FrkrP;gB1pƮ"A7CRyAatgP#.9Ryϔ_ZDÆWLf_Dߘl&c 3Ѱ.6z;p:7珨 9,naSaA%X`3aV ".f(2ѭ9N> K4N|8LhAGGIX C&@؀MW.~ !oř=k?W)At&57]&~9}@XI!iT[,A&Et+vdSJAwxƇp_] '1y%:Q: G/>*&YܣUΎͳ_gl[hI%Iʫʀʧ;,!} u=Aw}fU M  1?ʄx) @EĹք2_kJU60Yŵ96[w?f2`Wb 8qz~AZɃ b4Djt&&)Fdϟ>RyWHTUYWU|VlC HOd_˩}H7vՓڳQNzKѹאTzKq@NU{_crԮq)Rx#Moo+BUKddΌ=DYs--8tvJ~7Kw4fiؚdp=U fZc:W%$В"qd]*?:Xvp7S"?<%oX4RFgkTf; =E(Gˋ/Y? "Qh^s`qx衠h8zMwjsNXWZRb {p,6z3&b~|6eأL.U;N]#_Mv=Uؓ6hBZ2k$=cT-^U`UsVcw=̛D]Ͼ2z-%C++~wˉ1wd:۪W~+mG~&N/ a5^: 0DN1Ph4¶.W02ZBPc MʢtCPC>Dyd;-Yس5?P\;^;p5(l(M"bdG&q%4pl/M@Z"hCǪYlk9VoO-65nC/s;LmO+$:VLPԧu$щǽo%εWΛi~-=Q6<6:yI= . ,w.ڶukI2{JMC_H;@} ʡ es~ C'`kA{ТL#_,^ƥm W_'$۹+jlp@:)IcA3hzDFHVMs#*+*%w(Ł]vcrlXn "Zs#;!̈-b5ix{NNS no4̉,dJ%D'p*v~r!qE a#@(O^` O +prg2^G‡'P>kyqͽ0yۣhHcXprhe:4y~  i =(?)_g=[zqg.vNxh(LB)ġ}$C`C-i*G~PRo<3uqfS ?oZ4}|1Rƞy~s}${aHD%Y 11ddXVt.b|H M cE) ':IL|(=v xu`6J6fLHx!;/lA3J Y}[襌$69Eԟ t ʾP.vb9 2$c=&H4XUwGY]21 a>w(d3O<2BJ5" 6n4HDp2 N:XkSܔ*kԇ ء XMQ(RSP }yeuWk810hksY򾘊5$/ZS/V7.潛_ƶ-1ap,- ,}"D6Ztw, :U2*mpww!Hppw+܂[pw|w>=??UsZ6gc>zW~PkQ2sH).s:;#>+L!84ξ0:"@җjR2 2h_P1IvuÉj4I F[H +j;s@H_{d/G"JkqkaitRL؜US)JytFh/ g懧BԍN5&SwBlhmݒ0ھu=* KR)6`Y*/fl~eǞ4E ģS}t#]u`ϠP$9ۈ,S-;eTiZcP"ocSQ60̑6}A]dΈ&SHҶOf0{1C)%p'H>Ib q/fMƮ0 %SI>cFOAZ$=U|;Jj3>\uȀWmhV=Pxz>O剞aMQ(>;G/˓]^H}ndɵ }dn4nX=&S=4|j=ǒ ĩ)G3r`)?r+0a{ke=f1Dޣ1(uG8o,zUөEuOߏBNB6XP;D-`70$]to/M|~mʕ+X2 rKŠp*q:W!w"}I"|cWfi{ԗD`!sߘϮ-%W1pLq>:\i1B^7Hǡ*%1G cnvSMZ[1I-bv-Lo/H6H(#im>m0@YUga#V!Ճ(7C  Gg&׆NU&>Ez@t"@Qu@s"qсY+PȪ<z$ɯfQU"^ #G:%l?Kmik~0<NJLs CdJ>!tj=iE"3F L_y;~{l>HA"Pנ*79"Y Cn{"ϛ=ˆQ]Y빨g:> x `uG;Rbwِ^-,o[J)bdI$HăGоnc*K\Ч!?.6 q, =ꐚ>΄z@1=;a״wip e:6+w;o?%()}RG^(:ѐ 5A 0-f,X9Ӆt=Hvp$/IW(z0^? $U b+Y>~֑*`TI!2x! 7pW9v@6E8Mn4mѩnǸ~P]ƌR M vJ!_ǬNEYc.# 5]l '4^te֝@Iw]CCS~N>3"RrF[T8ob9cy${cџc & NJ&FQN;J-~W<4 ~)"BXϞW(gć ֫Y0} hc "9p&'-ƃՋwZd9Mv}6ljb8"q3"O MM>g]\+˾wQxNZPX~lp?$~ig~KAӱIX$c&4߳Oh( :*GۤTp$ƿ$^"̑u(AGKe1["Sd4T(܃E&%)6qFtI?/qH#Cwy8^yċS ~aWYz^5:T5TMm j ?[X1<̈bƵtnj5i ^%d"s?]GO@@CSѾ,L>!G0.FA5ē;U4 dSrO#: ?ɡm 8|X0_hS!VW~x3i7$Ȟ{ɗ̳7p sjfZJ0$W+0N{塳κl8NrG&218(aA`\ؙ"0 M0}dxKε#>퉬勂 BI![/[g\-I`rE`m}:tx»%!DSX|>2O+SM'~>B @bu!;dؤHo;y!nJݦ7'qC͍o ]R*6di6Œ᳣3mMrBQ Z`TaZnuƪ}^M3o0J| #"dWZA| Zo)tE:;Jy,37!c#`d l%&ΤǼK`^ozm: v7iL!/P1c5ɗ݈XDMxbMڤ.x]kA3F Ә-c 8xFGh osn sJ"ٍR!H?,,Ch1Vbܝ&Rwƫ(V^qs%Qӹ#`ٴ@ %7ލi ScNjˤd$-ϨP6LJo.{y~KuS wtBln3NyW9-rлkE:= V%"OPpbF)F S;}*/d- h2"@L"NnOif uﵟ;p;-Cǖ(î1Lbm,@m_[T+iՓkK-w,y~nt3oaQ66{!gJ ED^UHz+?<;W_JÊkF!L\KrQQMz2c : er Ư4b7ŐP Vh:i)umBÎd黨{jPy) 1xLxzIkwazUhT?0YRoE;J.eHuN:LVKKJÈE-zJo5& {!]U.S]R܁:#YJ_YLAѝ\\ cSUftxі|5rdB(.COr[3(ר  Ğy:$ғ7KgK j*RkrV٩hRTۆnjV=%9Z:{JЅ5Ðm1k| Qr{=rux. u4! ƹRmĘ*,R_ww IV/arOWCT0ʼ GSTD4<6uY3dF*q |LH[N[ڪfl嫧Ӗ[}㛡u?\QO3׫aza"i 10-\1bf/0;֚Ͽ.9?~Js-;Վ5=;1??YEp/#*^2 0۷A & /tpt 8h繨3:e_!\P|f 'ra!N?M[`94xn?< k"9~is2bq-OR';os_V9+2-7 -/#"/CF=m]65nQmye냬ҖFS)z|7rzko,56 K9:Ht/䶀3 G͊g狇+30IpV)_@Bold)wkXCam EpRP)/P3~OG}; {Xd' B-ԭҴp>d# &Yxl҇oa) vxХx.0 PC 8goi)mVP%n-5Jjy_F'UO]lOו1y.iPz&teB?rHE+ 9ޚ0Yk".F`w?3,x(hX9]v Jm-at5E$7:Vt#df4 >ͥ~?Yf pYsd%'gԼ-ćLi4N";$@0mBX`HrY&^ŧ<+`ֹxK19dq}r RLRXıf`6${j}hSU5YAb tIaՃŐ8k{vחK%ڨCCnk f=ɯi ;bX %Swn*Γ:[Q1(S33;骐f@keS5QOEVqb#t[/T&YsPY쑄txjq1bF+ւgֿ9H<\y<*՜ʣ58fDՕAfY0̔[^s[T#K !柫eHI\]G oxMΠ 4[O>Ayߖ0N}4IU;h=47e~p 8wҹޡJVuC u@T, ۡSF#[)kZg->=j\U/'.х/ LW G7XBʹ#eIeAG˦q;1 ?:k>߀"?.?R/y 6a"Ko ʕt g9v cRMxU{`{zm vN* CJJvVmu[^V,7&ojcv9Cl``LAC٩In?9dQ/Οݙ믱/^L}e+iEرag0`I `{qF* aH߆2&'?OX=w`∟MIIx\q=,܇+W?_߂`6?78?D\X0kϯ ;kK'"aI:~ &nG )/E#DrNPiV Wֲ?ν^(?C'2ۉdvJ 57uap C]"' bj$ybX 4ee Y9*mdQ0 8hz;UDoh,AdS}~JdB7SʪaV{Mۥ8fۉOEH.Q-(bdb}beZIʖB~G+#q $t|]) <P\ksC*M<7_rJLlBldM: 0M"1E yxIE/:7|EOCNlLc<4ye: HjWuh0t/ob]A 5F eDr7>U-EWSCG|wZ 9?k:BK6E2+ '.{ڽ[҂$s8哾 2Ӵom2N:+B4O@fs/ I JEgϸd`'C_ /)?OT#qta _'!U n(?IJU  y*] (&6x5˿ƴpRs1 `[1u6U&H_arUn , ZGګXXX"S/v`Oϓ{˷aHXj/IZ+F&ՅCQB"lkD*AܢA0i WR3K|}o!nH_ha^hYqn$xdb2"Tn,0-)]mdlZ?Mロm[阀BM1yvæ}7!Iܥb{/0ρ+IńWZmeSU1riy^{pbR[^!B.{=MwXŧdb/+ >[c!s^$ @'!E]Z Բ },Yh J 7`pGc"Jൾ')L%%ٲVAtB_Q [9QקoiŸgַVVpiAy~ g[8P%aile~8$ok*EZC8`ŬP*V܌kU[3@.LzL(zvR pBTAy\: U/gzM SnIgc!^^`ꪈs ^Ոg_rW UbϰV?y7;'6aȾPbi9P?_'z̚=7)pDamPF[9šY6oZt;b{v񓷞{fBMZXŠ=C7z I^|axhgc[\YHJɚ}7cH#y#{ :FMOCQ5\m完6q/vXneF(T4I)HāՈVa81(m؝˭=bIq'PYݽ['zK*R[km9R0ĭÃ$#9gƿm\@)Z-EX_ߖقLl3qh4L&_v[wFgd]<7nl 9'*xB -fp[B*TwP,m=zkd©}Ȇ؋BK?YN8Zih9T,iޚ[D%-Qfy7RT m@nw|},Ey}NxDwX$AbnV_ lAnJKIX;"t?6 <8'hLFU9dptIo5#c6l13JEvesѻ,]go2 7GxAdd830K y+< E%zbe+#[ûf"KD@fS$ _;<6C]hM e4|z-niKK;\kvB"! |Yzhp\j/&J s|0dG>ДI慠xt%kB2[_ʷ-@ˊ%}YY5y??6RSK$ buf_$bD28K4]XguX;7B@V?B\Ӗۓޯ9A))strR}e(iQ _;1B[>tc~R >SpJOӊ "H zCWɮ;@ypChAO:z)I+m:0ǽ5<_"fDx:,{*Ivw.P{u-o[c+>K/ηl*ɴe 7@HfB8c5-MLlem?OņOi< _ʔ"DH-xx+׬dt7&4Y2,v$>wh~JG S${+">DeVrGPl'1C &`!D&"ʍV ((aՋ%zQٸi5 MHH]wa̢68hǘ6=_Xvjy1I!':fsaxXRAi"g9ci㫿m2v>=P:![! {2*$PXCiT-eF+K # j,p3rN{Z@o++M?+}KN|cC3zEnA$hà`qx=0u~#Mq}5vic˻&EWŋNn6W%}p.hS5_^oAۅED:IeǺ+zp+Mwp<ʎ ҳiv(>εTRw29oX9ѓ;yq;Br >b4 =*.]{QrK<[x"K$,(-ܛ#s؛D&`yÂįev+J >E[(F;"-G:z%gAr^yo5CtC$!)I>K}`z_DZ/Hڮ \ߩ싖p m&tXXt nXq{wiuYޒP 7l2xͅ.\+ 7 9R3M݉TZg_:]ZAi}?{e"v~ Д,+ 2uU@G\Z+&y &ncC$+y4IZSzJV#Fr7ur]ݣ|Ktx&D#6&ξ0>Ƀ'zmL~C+)M%fҮa `k8gh/sKyǸ4Zn3W/*$ikim\şlD ].wk 22 9W̿?cW)O %_dE! 2u?۝C-3U".m +[#c%ClR{(gs{4GI Gƹ6:p1O Ā!ӳP[XM=)1c z0aLVN|>kyD҅{v(er*Y;6$y鈫$Nc *;(d`X0aI??+_7PnluFs2+WvfjP׷S>5CadC2V\#?CTJ[q,d!y/,Gs4PB  4ObUs4wi{8ʠN#:X*hKbRk郼*Koqi ؑ0ͫe_%c[]fGfǷ?b:Z'7'}3[[Go|#w[gPX^yj0z!t[S EZoXPpZ53Y @ҁdlVhICX.$ڵbr3KUAW\s{gHz?̖W0x@wyww/"|F'BD~j h X@b)eJZTn={LA~66ꫭ͛7V#^m^LL-]meX;$lG۽Eٵf #eFr(X򰶞ttO߿.`moT*qKڅz}{aHչNqɗ(QL.V?[j[Dy.> Z'y BN!=r Wd_ #vyDoJ8 A4HM"(M<ͬd%.)ns_D}RxaUIXþb[o.6.f{pEvf|>]-̗74 .$Um3YFk*>9d#ٴ8Z~u (Gz7 Ȯ n*v:ָ]?=A,<3p_{{ù=f#VZZnpPKHB Q<ʝ -DCm*l&r ׃/XBޙ|`JLl@K֘p Ȉ8(> |ӮײdWMj^1ڸWD܄4{o{H_ sX`?{0S+2k/98 H .{ ō_ `ağ&C-t?{@5> JHq5$4%o b!YPb>Ȉu>_kd8l鏙6Z4225HX]@dƁN?)ЀVN6ܳ]MDcB@t"Sn2.6o>nqP]qH|v|x %uL8.쬎`jYk /k,`GbMhG| Ñ+ !tei.AT73GWUÉ j8&jR?"Omڦ*eW-1TMN /`4 V+:ԧYA!#}1 >qy,--^,e`&]I_ֽ:-1LAIwwE*6ޓ?8FoP *^@B>Y|)Qf`&RAO&qHf\p)D[e`: ؊Nu~V#<@ Ab<@Da4lVoլ8D&)K'v:Gj y`Bs:X6N!NL2aAu_18&Y_KKUCϷ4`v{ww6,Hy*o0= 0#wBi|DA:6kT'k%*Sje"F۲J(vκXfB Hl_Cnjr )|t% O2]`1&a|&%#p}j;HZO$S y;-,m '}?|VZM;#;Bl 'mxЕUnC9vĻx6*DFyeƑz=vLǏ8Ʋ4I#F~>i4\(Vщns~uz^*f EQ|xͱUj4#cJP`7 $<" <T?@eÄdün3cEVX x[ G{һt w$S}f ȍVmÄ;cԣ*YrPQtҠ7tӃ8 FS'd7-􅄽IeUr}ªqD9WK}ø#0kz9k]>&*Wt¦z$d!kqK1X"o}G4ȻFw=?z eÑⲦP4>ZVc΅ V0/FԧA[6NS5x֛7 ֈFRT +7V](F9:#{Iv t.C.E@c]@6>MPoEm{ʄ]krX/ekeK /-nyK;ɦݖU]TǬS.u)&P͎iZ`0!9-  :6߹g4r`ewblP`HΟ hIՅ9IR( * lQn(,p8W <bwv6o!/&7Z!/xZ L@870 ,0-8Plf_r3Oqc,"oQ_Obٸ8⌥bxP;;fx:Egʈ[ sKS] ?a^X8c9n>J'f.%#ig4>Xx2PR/4|ճHЈlSs5%ؕAsѮҢ, {aOm+^\:oy?Y/y=oq= k$OrfesXsJ֝soSJ3a|L Q !p_5;IHkⓒZl2M:S:ɯrDZ Q 0?Ҷ ~$GO Ws -S 8@|$pބs\z}b%kP).r5/8:[6qg"ꥹjnJqcl4 KyRMLIub$z_Ք9 ݋H9<;GԱѹؘp]Q; ӹ$IC= &CMwQj׊ m@2t6BN ޢ!y3%+eXѲ-,] }-; d缻=^FХ^5]z+HH`ˑHwRņZHQDM'ݕX`3"&GX1],h[ @2V31Tn iH@N5XLDͮ[dB߫>t8zAF&U[6/cҢ}gILM6 /;t25_.rYX8f:a+A) 3V$ Ћγy4y)IB B!x^mmOck1o}+E#O>H3#ǯjc"C<$2@pC60(gGIzi+ղ(xfeK.o:WN]eU|p ԅcM@!AV,5gwjWYb5Cvqժ2SFC$"ղ5$GJ!vsޣ︥"ϔ$f~܈;Yfx@HJKL5Mx?7 r.NдiD^M-PN~Քx:xzǎLԘ4 PyCfΈBn :Rn#W^9f;8[^3<-E{jEp Ll Y0&?A9u >SQf}SONM8ҐI% )sFCjtv B#o J[]q $O;˛[1[ƴk+s/HǫEj#%"ErՂY ƝQ .Rz G lcgA2[D;+kXx;# $HТ̯ +pye. w B(9^=64 HGG!-z?j׋0Yz Ar \.-?=ؠAWA!Y(L0~ if~W {ZЦp{LB͑ve1ЮWL( Act.|;Ch՘PZG86*zP@G G :93@s95Xڛ,"3x7WauC+]ot\߇~rwLJ%K$y \mZO-A*+ޛ$'q(93fuZz83YqGk .l5 :ޢ;N4DFAو2LLN=џ <틽yR<6hyaN(BFð|WypdA%|~bR[ e`'M"3E:'jҮ닮*[:X\?A菉lןR{:_}@" U[#NRVf1nID̨=:3+MvRe5S {qǚ!qgVƒN(u$UyD/@kFrК@l.R?9K$=ʦ|ݑ:+}wCW E{>Uن˟c Tʓ= T2 #4 O!T "3@co$HyGB-G CC t;2 p8\Av# $>iL;CxAXa da*$deKXmPj *3vmΒaNK[.# 8X~' d IFU+VXrwjD8y[ߛ][3ںx|c&anTV?.wfJg뛑]m$Vʫ f\k>R7qpKv/v5vl]CL Ic<g!}yLPɗGϜdQ*2YmWt~ЛnipV(,]=u%+c~>tUM$h I'a56; 6 1|#++>=OHe?UO˼">p xh @ 4}$a>zr*OS𚵡V,D {_HIG=c0oy .ן}1T:#]?K,=Vѿ~6$=\Y;LpPVHYPi\obqkQ3B*fLj*{'g9 d|O!gH;`pDe~!X=)K-|t}$"Lg y'}뷈/tR{ė(TQ¸K? ,uwB_os_06jKG(VƵﮍQ&˳BJ/nI&Y!:u?] Dr2e:ҝݍ3LIf5 ma"e _ UflT>Ɂր0(8s*$6pŠ V1(d3zYZ6v峨$IwE!ݜ|r)&w$6ds~%(6Tj,JT*o ^z*v^!rS8! 8!15Hb 8XXX^%+ +if`9AS&__>[+gg"a`ga"yEL,jTs9$- Y /zo6v&nnNVNV_SVN&n={Fݯp_5=QFYK[T&>${_D Uy~WyЁt" ݥ뭛x-=Ѫ]-hъ8ՕJ졔M{cﳡ67QI*ᢑ]}@8Q67Ŧۍ[tEK.cnQ"J>T1:BԦԶC̹ePwTFI] [k̬"T<ճ!;vu.HsBpb*R+~-jVy|L{WX%S; &R/ͫ5/Htlm^ÎQV5b;n@p0iGgllE㒦F%dvjel7FY2+x@&{Y8C`+jW~]\b![wD\ۂu (3ms ui|te+l>hWDN|Qކ%.ITUPYU|BjPӲOGVʍM.bz٭}OO:j>nQR`)~f`ƘF* jbYyǒM6;dV;\~)%#gȁϺLQdcC6 &rRv/ǧZƋ2,@hӢi%$X" OJŠ oc FǞAg !@P8/RG b=)ϭ_ 0s*YYP}(IWIJ!?5@~rp:nȕhems& #~Ej휷s׆Xe|Nuҗ5yf`[ K2Y h'p9Pn2)}1v֣Yhܳi:|푥9+60! qjEF֩@; i[cH0%M~< = 8Âa@䟳}G|'' Pp!n`ϫʧf5Fd%tD--(ԄÖSZis>   &{ZK|JxֲrV4:1:u?ˁ"lJLq3Љz{BIv0յrmڮ.QD 3| σRփDԸwiFHQ[bJy@آ=l'dU3d%bQ޴"dTqKM̤ɋx$ q9>Ao3_0۾L(?C|p ~_EN RkoN$3; '/;;; 7/+ZzKܠM^HfW+7 ?7`A2bsKo=%ʑɑK~J1W]H^Nn 9Ӑ>lVR%OnAScbZ\|é{7ק8Ӧx%ǯܺR&g?Y@ːu$r~uea|ؚLi sR>WK)i &Fý(NXDuar˘uݗKgR&93m2 y4 ChjO9G >d<2<$o3C 1>/o*er|,B 49o Hc:8NfrRidw.@!F_ C;bfB SÓ-;6۸Z ::ΙXBjs%i9_M_kyCSR"jzp[֤ܿZ[Rl0>w#&6lp׺PlhC7KȷL -d@k @(6rS+"6=S X¾Tx57cxDNYزrGcN(eFV$, ˻ecc!2H;낷$k4gys\rb/ kɛ"8,>u f&Q79{fa#M" b%~5qsꙗ ֮EzcNf&ʦj-X)}cd})lBs s'A؀7<$9zuk&FdO&|? ZhDxISQ?'6VUlP/JIu>}(fI7,3S׾俖PRaNH&솱% g]|v`)Kfۨ%;QsyKm O%ıcW+ ~- Zz81: `[#q @ޓ Rn9b47c{so$Юc6iuQ[,,PUɗRܴqiP0xqXb18(Ph(W(b˝]ZtbCCIt ~ek^j֛2K nCKHn2s4yӍ%W;\DCD88HQ:t &j~wk$%^$Lfi|m Zu2$(KkWb88*e?3'~j&X 'C8C@`yiX< BGHeT~L#VLaܙS (l"WCU]%#?_ X`FnZiOE8 ɾC<45+i-+i3EGqֈBtnW|2O;G)ˉH,ڟP ktj:bvK\y>p'$.Y$ڼ\w?[N!ToI˅0":~y^13U}b e .^$*<:6 rpMcʀΣ?=$ԯXOh P._ srF0@0{R'翄FAg~*{X;o@p0@CmI̗̎Tiѻӟȱ"u0H>HMdVRf ]-Ȳ ܾ߰%[a4&=86!-&UFZ2E> HM@2M2|f( {o#| <ޓrD1 U``_Q'9( Ew Y߅ l )%ɀVxMuWL |F_dgm BDb^\w;8A9f@cd/6}.[-/DҌgӔ[׽.%*-;y`VMoQϾ^jb|j~HbRM~&V:ZOTsnln{*j-('3P[)L[ !4{j"ΓM#I z'aBoWRe&Ҹ1R~6d5-/<46ގ΍ @J/aeAǁ锧?y=#BOj?AL1ɃxNɖӨc3HަrZ!wrCzb%Xm%[gx[w"}v9ʚO=_cc=b =PD߯~p 1 CE4,&)UXBz H,LDb#Z\L!dUbpInLK M4ݳQ #!iu~!L?5XFk8In&G r: ر?>(55*N uvDq% 2 Kr֊]:vr-XĪ)ˆ M K^}20x`.rSKw6sa)d/_tXLsՂoI+޾rr kfYW1OR D1NOgp5[ٻ֖|<&4ۇgf֗P~LT( Z)M+E~ŶޫPL!ơ^]ȯZS@jŪ') [! ڂ d^3hR P{jtvXdHoHۄ7ȬVܿ?-]B0ҲC?C_M 8y~}uu@em.T[MTbįkqrdˑ6+9\Z4qNV"ahQCb}}'-rFLS}VkXЂunIkE?`1𩍚Vx.xeD ꇱ+*gsz ۇ gБS}oHF_d\s4 y<N `vLLa-6d?jƑ)FM,0ɨD#zN67؂K=O'j%>V"VYL]Ӗ%'9I c0Y:vӢQo"b7>Je2[in:^́؟JӀːZMa ƣT+fKIBhwl,;Ə94եs?o/n{EǫOi"q?pr=?y$-@X-xZ% 7X0͘~ϘLlQ@-aգ>QeKn~mA6wW0ſJ1ǿpqTI\Ys)MпJJ-Ď;%/R,'Ґq8dS|n~zLJ9#nzyS&Ka\{؞I641LZ.m}M:D<)'`" gb|ÇK_~"#KX͂\?P>$4$; .uM3A^|?,&3If@E@#w7?fЦh@۰|wd(go/.~ůڡ_Lqs j AN clpAЏBoL-h̠,oh`$?h`/[p:PkW KJ8C%Oh>ro=wR@ 0"4T_Gb^[ev-xhyG)d\?Qf3/Si1/3+dT-z^|=f #*wb1$f7I -B?oG-p?bp4X_vw.tc(^\5FssGHrEsBPX@4-6PEYKDi vt71dp#*r@2͕M4 8S'En;n*:!u ֍o 2(,Z]- uV%N Lk_Ru4[:#'m"Zq8CV滎;9!|гl7:d>6J#IAJr VS3"HLgqxl~TY]Ee{K q`} hXF v0N+[>?ZJ9L/WB-$~)A\_ǪO`"^ $tmy>Ʋ"i#doVr$aZ7P70tۇ iؒe~x_eTyMW5ԋ k`'ػ͍\P*ع[gC_&bd{)@"Νdos5lkä{O-3'km;)Kn=QPSE!u^OOfTm*y`clw3^i,)ɞdYÞ)IvW@DDsalܕVR.[%!mؖ&;mOc\. |6fUrdso}YXlX+P`غ l1jnuo+{"ql:͜voP,N& ^=zoӳtf(B]C}bBmyG÷QHf,/;]g e+Ts`|7^p%z׽V:+ӴJhΐf*SGט/ Ֆ[4]lI6'+x/bxС$Wd#=*wKr6.N7&v#J GD?S\k;i:}$J j ZC;*X~5.C*>^$)NрY,}0}a{A䫔M5RxȚC们K+[kEd~C  kj؋rÉУh6;\ӓb D3Lyc5?_1!ԑAÂ%FD'rKz5Xs<9u@} fQW"f[C:>0Zx%"X64rp׹+qmCC r`z\r`೐^}p,GvcBޗ^ވ#yjifFUenV%A6pھ/7,1z}EvO<8<TD?Iȿl FkH|ٻLb+, HHE H.xW_?9uDAd Z ;Ͽjy nkZB5?hpa@1uzfh!t!tHv^HoqX9 A:zX}Udt ~+UL?J t:bign-3QMƬPtSwj͹K/ |a]NDH@7Yv" =A/ͬQ&;ʱ`KH*u O%(= _Y[ݦfx#'gG(Y &<2S=+V qqV!% 6a6fN~-߁EK9u:&aSwrrǜIdf}7 .-t5Bбytd5&8467Yb0Qdfv K~$sBm1{ӱ}hM<'0aop>.ۂ{pW[/fQ:W zףN͎RdFX]}2:V*)8NzpFE&UNmQU^{zDߠzޘ{M`Տ|kι?=W> T+i/k XZ8C#!Q(,n |/0pPc m=)ڤ%&5BDJIݜ%g`zGp8= DUHTL3. v%&E\fbMO٤u*~c`NHuodF<^V*|đRgH;ۺ=kC/]ڍ%Z zPE yգY6Ξ7'=RJWL44!9aUfpPpcT`t|܅jxDNRG~@T--v=B%.%.뺨ga~܌ N9KG5A^ K4_0*MJ.L_.r:8} }Y +77*]=&8"+9'\AݽSwQ >L:50|\Ρy4Կ2/V" $)wgSΞi^y:E)rFsa|&؛(NKGON/|-KC0 7΁%g:F"s4* )‰/|إ3{{҈7av-?[en~pYg/‘)א9@dYS'ZW L{MpCfBo<4 >ɶO/XP~1)A;9Tb8Wk[Ԟ˷\VUJ])|Y_^L/{|Hc*J'# 7ID,9˙k~$ͅJW]X%N@5K6j$LY|\\[k\(܇ }G[9}6i +KA8K6F6f"Iy$O7šAVjLbC. QMM9q:EE.<`InѴV :aQggRݜK^팔(R>wU4AM,BP9:(\T*)pm,zkEq¬G챘 wȆd A"ib$)I NGɑSic:4 PW8K;p (s1kfD6 +oX.[(aNvͭݴJql֙&:1AɻgLsݪD^Ċhdiç\!縰i?ά͠4wDE,Meh98\%Yko2=ko #3hpw AwI6[ ܂[pwH 99ޜzT]]}>P{ (Z r ACo>!Jx+OK\U cXh MOi?|>/(AXM$!M$o>-4(y)&4xnԍ;淁g~Dw(?QƮ-Lsә`M cfQm?{?N(wMQvZ_ɏ'8KLZLJ:>͛>FA5gnP/_=3 >XU*cX8SFGDx3]5єA?JM_{xfbpd 0sy7, [Q^+0Ĕ1RW$_,Vv1nu*1܈OZÌe}MG C">KlK(8:HұWL~׈`rbD|V%WwsgbԹyb"n5$ZUs8l>J +(V )XL:h9XyG( @=%'fă (01&Tj9}JzYD5#0dmeg;I11oE'(zoF]eLM$zJ 7*|{?rH1t I1i/nO$.wD.xtb ,z@vxWIꐠvkb(ȿETe@)xZ>FJO'JdrH^@FZ *{E.o̲ ZeOSleW%g%]Ǭg~t&~.P eQ{SSɏhre #8Z4ew]-hb oQO \ݿz*f8ﹴ|Ӭ?iy eDbnX~O: wO9Yet}qcU#vdod"ՋBU|xLKsd֣KgE/ϔJr ?DASs)}̞].],o;uݢ٧y[0 Iwy!1pm^ZԴ{vL(mΰ ϕ13#|T!Ttp׏%a6CeUKQ5S)@e@N nC '0!ޘ2L*rOȷ a Cذ%` b%77#?,CUNߌd~pE@2=HRp qa`X9!Iߋݠg/1H?_b8 |/Y4#_߁ʑb{F8o$O ofxXal{ Xa ~8>_>ծ:6yvl ߮]e&s`̧`A 64'd \|mH}2^IwBMh A."Csܽsw䨾٭JR8ɦ_'zM[v]wHM&8j'|:b;%7Lˀ])߃3;}ZۛdQe% #]@r# kSkoVkF/3zgHLK;PX/ya3\df.Ka5rqV x '0: 3fKC~ud"9RUĐA06.^sX kWDA & Br6ȝ EdIVL.o<ɔrGl4x-8 %^܊P՗ Y^_zh5x֢ФE+V @ro gqet C_rpkVAv2Nxcӑ"[.Sy]/URYGb ѹ/p%L o00Am/ԙٖ0S획T87VC,+&=[4x?C,N샎Ḉrxu=&WKXۭu؏&9Ƞ P/ҌtPdNNf~LѲ >r}BJ6.ݥ}JD ;nQٵڢqu&7Ser+{Kވmكוb&UY#ԬXJSÆW8o̩As tW=10i"8\+ g60W(wŬS9̇2o5=6RjdCk ="$W4%P.ҝU6Z&ߵl|ёD^{:2lыρpNc͢V-Зc}wɬ6xA ZFSXN!%\垛OԌwQ\$'ybƉT⻶y\"EF?M\zz*!B\8ido_қݪP?#O6,VQ(/T%L_LEL[RQMXh{o5дM+oY%.7k Ol<Q`nw ׼nnp&ɪYqm9t\Ҍh{1F?mlT[;-I 5m9c;㪾ENOv3AbT[=&wkUFEXTƵ)귧7Y{&+iE_ÓL*RׅG!"x/itbCUW !{k1G]l"U[ %).r+óPT= $+Pn,2k̢Ym~MCC><Ϲ.VµE bO2>18Y3/G[u:JtQ^l*?E )[n/23sb52&7j&`"lw^! ʼĀ :aoSLx4O} 'mQjb٪w{Buz\oTԥLY%d%]S P?Mk'yzNKթ-4kS@]s8=>\WIyR( :z(3>1ѧiՈLK-f/*nEwS8`[Ĉ]$4c8U $H2({lqnO_x REֆѨ0œfE3j 7yhZ}p4[#%s3Vǔ׋NI*g8og 6:F5 "D,F)(/"OgUJJo >ˬ}%2<#i?,Ssc_>5@1(#TOC*Ҹ(LΚOT|:V4N'i <P6#JgzVCplPISZ* !uv}c~^zڒT(rs6gX/6"-(̧;WQ%S{ P9[̐XEl,[x:m.3ɱL0@=xQ*>1LYI1M- 20IqIZqbs/Lӱz&w8`JWD L8veW3鞳zS~J".v%B?Ȁ)ZﻓHNypKa~_?48.`S6YO'dNh>]ᥒB7;бrEPYGk% nv*/Ex iQľқ-AK}"`z.Y^'4L{r1ˋOl'kF}'|E`)srvv<ĵlwU%Y>!K2ZH)F* lN ,TZ1w &!W*0N8eKc|KOGq^;Jli{+N{2d8K5x4ԟ|޿+JeC3tۉ h{vꁣx )Qn`o#ln[cu6 l7m .S%măBbzW%3Ul5ܕԎrr%{Skﳧ]",ř:.1H|^X[dgO;*T^QJ,YզqZ2K^Ezv|z_*_NRjˬ0$ϟhB=AFn/xm_ Z[T}yCdg؆^E}hOjF6o-\1S75lXJ)qs^o/zxp'EԠ+Y oCz*5L6 -m$;w76[4YoЌ8oǟt* 9Y b.Ć(PcX ~@x\'+38yy"KGNDg@?P^(8g}ΔKMHnn^YܔBp5Ll7u$Jw!`zr'kP&;أ,; 穦}9^[F@o4%[Q"JÒ}n<ɸLdױRj7{j.Rj3{0sdlpR48eԕy&xLZ< ޑ.-od+M/sEqQQ_Uj3{+OH~a xH˧zr*!E_]B ct?PA0ћ΍ZW$=mNf]Hcbۦn˄S8I3@]`q) qhS0 wC,U!ؤ㎉zrPy;{zd ~P|ۡ*xV=eˌޏpqT͗o8׻ķtf-KXNϢE7_X޹A7Nx{}9(lNgRy|t2@7/zp۷_O #uSX[a1+Hш7!2}4VQ] \ϛ{>> 1.e)"sE<I(!#z߃i jE!"A횤DhR|BUu˦Ϋ{b awM7AC[ܽW# }5mpl |FTn[c"(097Y^e ^|f~٧M ŚG7Οyno\BFU@Gs6f ֑Ǽ,7V{/ZG<]NR37NKݥ]TgHw0pll4w)I)Of~-pZT6AV ?H]X[et ~wZ\6瘢]"2o͞+;mJˠnq;rRWÞ @=48ՒCpJ!7|)[a|Ld5h[G׮4}؊25RېUhxW7/u dt! ϑ݁:MZh[K[44zllA#⾪֋n.Oa}F$]\ƚ#}*d&,rk#'ԗ*)d[2(u]m;`'&vߦUkB}VH8,3?ȁe>t\l fN ,$mMgg ?+2pp3nm@ϗ~kowY)z6:d@_rL 8ٙ8~+LdX.?P0?{<#lq_V~&F߂fMcgMví(9//ֵQ&y`FƧ !, ]۟nt9˭S2ȍU;ŕ#)QB‡]rdJZ+Sޑt˿ħ\sTv=A) fTڅA kAs*vŗ,]%r^bFh1Y [4OWw8}7sD dr  Mo8~F/$ r }GeBC8-^] ޿+׸ t!m0+{OO y%?$hA@*,JXD,K<)Hń,_Cަ0X~o5`ApcDNnHĄN0˿6~2Blف*l?Xt  J?-‚8~F[|ÇObĄJ}5)1S)jUH,x55`&) es5# ߳ы^qw_Ei'YHRc1sx" qңlY5Zu\XF$9Lr`~19K*4k_oKF 9C[o+#bP3khKB~GNXp@]^'>Ǩ]A\W>ES4M&,/Tqztn'Q6 a=t ɱ/ou5a ?O**yID?/Lc15>aDZz=d*\g!*7Acr*I _i~6Lnl@Ez6P5aDRB4`y@ GpH[/aZ(C=g0$xj;@qJg?<+Sj 4FFpqeJ*J:gsʚhXolXX?awahWq;l5;h#REY@c2M#s_5< lη<~ezrXaim~2gR 4Kד!PR4#ڇ`]zՅ\|DB&8\P;ػp0$d΃go^EzѝZ̧=ȿhi@aPu (7w_I-L%skfjٚ&b+*ZvCۢI7i[2ܫ,CI<72nQ&=-%ߋs̽$;,GqΦ0%ki3+wK"4z3vʇ %C"}p5_ӓOL12M*ot#Yi"ZUQeիI4#V;0a ҂;e[np %݊Pjj@f\eGun^3 Oee\Ҡ##viPMGa>(%#BN_I%nڱ'kem3 a>M"y4,m3_MG}y JPY2@rJ )Q;W{XqjNT8fWQ-dKr5\X`(ZЭ3QK.ރ,ٞb: /𙚬=j8pH*@&2H[ fE)˶YYmJH̻R##KoKFA=(ZEpjm9fM'E˖ a, \qXawZLoztp" bnpSoȻ>\ψ"79Cjz-.@:=A*]xWCyK-O#8|s.ƍ@pㆮb{%v|$Q{r+2Tp%_@x fWY9NP:6%d{J`өޔޗ;W8nsRe&\Skj ](1 !P=va+,Z>⇓wFF2hoԜvσ6gt}k05Wb/*^uD4 mHseoZLS=ks39Ǥj~rAl-D+Y+Ft*1@4VO9O͏x9< ,o/ǟ//@$BcC֤xg KBڄ(B@F-Ұ/J D9&"eY$!ą~y&3n#kl#j%X3aBI=ݔw#IOAǖNj4e:KJCcoh,b.~̲+G\7Aˍ;ƴl'YF $E_:ah՗5  +I6 ? 4hǘ-N4gO+!3\9B8_BP_[Ҡ\|P`j K#>*Pq-7~jY;*82m mb<W˱ gio5ʧ8Mf>ÁZ^i}g ;)  VdQU "d iɸLoj!s f/lG_2 cD iu׎t>;2GtC.Gv~~+g珺E"x}ݷ\Jo軽5hC#6ژWW<Ztm6F蔜y:ybq#j^{_wH2kjS75n\%9m^%V/ 6}jo{k|MJAdq<* 1t! zǨK ˂fc> My^DĆ(S2"%{Wt$BD`!R@&HY b-z5ϡ[(x5 9" NurW28L촃1>;Q'"y_κE)ƦNkڵvp+ٱ@HjV5{d"*Dp6 ZKޗ{Fv+1Fjd>c׎_9ڎ@8 $*ZA&8b41K$E[=/\G5ݝ q #G^]}cĠpj*f3@*vsM:=H7 BG'TָZNAn#)(ÍS|"| W*J)ށ֔UU:PJSoij~#$y"lVR0b $ulߵĔkHOܦs%^[,k43*w nrsle v/z:]s22FZz j6҈1fo_&e,QZgmrU=g!ߪ[Sug ٬dkD3sUcY-OI@3u/Gdt^/"ɻ 0b=~f)\]uK0|z~0 ( }ĥv|eTM}1憻*k&\aq%=C4_ _!7$Rp2 $7^9Sj0Slx\br6 pddsSg?:{X?hza`+}p[e2E2O{|1^ K[.2eBu7 w㧆mz>Ra 5T/WQ`vOPU.|tI[n$CկBfh$_l ^:`A];V|sr^JW՝SE㌞ʙs n,.sNI~n"` ~e<\3 BHףř >MW/f(.1Z37]>䫜)L&xscV5țc6҂K;jnjK P铢-Ai4D50LȢ].Wg(σewP,E ְ̢ܣpPOBQWq- #ȖB&,i5ۘWO?MkRkETV72>\6кi gӾDv|$%~L`|3H!C[9Y~~G^;ߌ6wŚ檳To!m2eWֵ'].PViW1m*)sOmk!K1Ld$ޤ/(p5FT.SsS~quE/|/ވľ(iqa)U _Y26?Aa1wO0-xdo~F|{]`ϗ.J$עb2ѵD 7my7hbg7t 0 S(8 sWפY x ٷ~I(bu=^ -i_W':9/U 4me>C2 |b,{!mLc!s:pP=&/E {,24y8q4'PWb xrJo@V*/w4K8o:z<>>[/1ؼ\,4[0"gǔAAkK HB(D[JkLqEI],PQXo& NƧm+-Z1ZBfOIeYEô#;֨5S}㑥~E0tsHv2z;h) ۨz瀤NV[h\=WװRigA8L+z d'XtR{H3t^r$nNB\^TM?":gkOkΕKIr IcuJu@Pc.nG0a"((ytsg\yncGx7> ՘ ܿw|Σ!9uJfxIZ&rz". $#_nڮ6&ٜ`Slkܰ[ ITLf3 C82Z+Yԑ{ \ ]jo|B@l->R͛ࣷP[{R5d^w+2*{BdU"Ey*%Z$*!ed3"~6ɧN8KΊ%n?d.%8kH;]~XE;>@ztBIDWFmZ{;9pF';>đuOmЌYTJQ)ƢR-wStC^ p5¨[ץiT8cG=>[|?V{'pWElT˨1+c}gϤ;]bI o=,?㌁ 9U qNoK|gpZ.k/ƺ~;@RR2%'jrK3h+Ed< 5K,oj*ףjqn3_RӅ ;"V<O eoK5y'eu%w2*`rf6HGfINH~Ɔ|wf%z^W9qn= W'-s-xMkFQ8W}c"x_zߊQ)sN ƒT 3O|Rc^@*O䋼4n97kw+/)hRyޑ[m3 GXQRL{t4q"֢eKwqlHHS;~CD~%3뒶^G_ɔXɽr笶_ɜx- @Lrf?o9}[^Pe[t↛!<1&Vy|+Q:tmE;ZRⴤ?[QV#>J`&he%O1YúLWٴdZ7gw̖ 8: ٢R `KxiM|-uFIm==";WnxRᦗqԔj_8Rc}b ^<{iA|_+g.ljÅSG8ּ;8Џ'oH} WCG=5ZߏMj<#DuX^:mLψw ߴ׹F.ΤY]w1k`i)}_T_jM~uCBJ )Z9wx|'/y;m^`u_78.^m_[4S5h L. tM/b?n9[:@.gpm\1v&+܈8jE%Kqh..t8)t8'qOhůI8^T;'ZVA//d9 m Ɲb5Pȴpw\96ΪIk˄Fox'`E'..G^؜|kPrVx*]vnʶjz5$&tl##Ʌ 篢/ue%W+HSDW;φ8\jdw"on^+LQ]7b Tm<8ū1Lj́;nI(7=Hεr}bW1[KG3c=v ou>f+&Ooh:m/fvi`EMɢUVSZHռٙ$=[FF/vZg9?: X ?ÆO&-LIKxvr2)b||X%Mw6 Z%%斵] bfyW~t*6TZ'MMbjk^?'rYɍQ+»&Ûyk D+_~e?:q]=U4Oٽ17 ςO *Yq%;6\e|j{OՕD\V_);*VrLưF{TTs8]=+a3 gj=)9j0tWCJM5i]=]8sTB:Pۘ}`ARZ;I<gnq;p\&X}}CI:')ky/; uzM[5= r}y,"dI'Ӷ!'X ˫.}=񞑭*ϙ.>h:> 9?_wUSjY본TdtOefk`g='8|3˭Kȗxww_6i_=uxO$ %_"2]XIS޵%Kphlmp#)%[ƲDc׶V0QH :y)jlR 8dme|\QL]aRk $s&gZ}Buy35k_V^=!^:|iŚ= ࢹnK3aKO{clƠ:#Ζ/<%=.BiLe9gFUVn%%\[*`G[YM%l.Qo{V{%lo:gsZF.ص Ǽ4I$8MOî_l=I6'ot;xŘ<sxw[7شZ U!!E}+ȨG-2#vw+-o%y/ԊF6AwJ/2NsT2m@2۲cq|{|=$"%'2=Tw9SlR;CXGzvi}~!⢄nȇ$_f򤸩tr%T%͝z/kT5 z#'RΛs|i뫏nte>UQ}򮞩ү7:R^>\ʎqs(f/ ܸYvӪqSזŁcU Ψ}%=:*g$5sSp4=^+BoVt.vu?جZ%bb7|xN-֭i~yjԒPum6ZWAǕ!{nɍs39Z9$:L)o5}*ӥVb~^i k(zf=/\Bgfcռ56~:]vN.Fjd Lj~ހg6aRS}}盾jlwoPlV=ZbTiܜxE]Vxߏ=@J?Zz+P`"p'Z 4 15:H+6ZŅM ~=+RGFƭH Y&Ex_wdH_wifXT jx'_6SNĉJHszJ!/p'ia,^l*p"1\b` *(ʅP8_` ja_ܺh/>o.=T7n/"߸`T/fpAh `;lg֜A8twY͓CHI@c?l=J>SwM!'rĶI8 W4X'jcl̦g]nX_!Z :xkxMF %1LOm7fj-m9?dʆ6ٳLOgY]FJ•c2jCl͌C|WP?-q{un%UZS|֒UpZG5ĜwQN>uq/j!C5ty>08s N*c:ㆹ5k>*wyS_uv/+]'f9\ocwTWy6. ޶4c4V˻v{0#6=K7o" &ݫ8Z^Wvs/kT۳mC/f:ߠZbhcV?_%pɵד=tʻ 0L~;c|}>ؗWC{;z1#a:k鮔5ۿ*r] ?9IhŚ ۳̃\wO r_Z2'㹩ƳJϳkn(~N vܛ=Ԣ!=mq"{s;ir-5`{ty&'C'{[ꗰ^۬:jcE_ 65 ^{JU$kٸa`, 7kFP7goX4~;'N|/!iEV 0­jc)RGqBp"6<vpj= 覉h)9ڟmGoTŮ?>vՋUӟV⽃O_ yWRW3 4-T.6[XР1s7}Rsaz,HaȻ51JqW+![ s ~pNt{_y8{ʖŸ\"~/hrn&VW-XKr7,mҜvS!gW)#6g:3]}}7^ x||~7Z1}[b'Ձݺ9>qWH֬>lF#\Y}3Ъ^}/¦7-Cvg8^R\Y%~(+{a:ųAx kַc/e]z@!ofrcNCK%{}+bR̦Q9,&%/%-ʃw6?DɱRFNiWGo,cձ75uJ}o^uV֧cWY{[.J0YJ_~ kbbjﴮ5qyf-|V!b]hdK9|]hsb l4?rSxK6np3F<'[v4TiQ = wxw{;b=g|$mS9):T.9l0fL3;*| cIqۦu^>'h Y$r*{V+Ilyz~qd1\եov58pVWUTV69Q>7ds y^Vs9&ғ`3Eu~2exv%n%VCOB6 ReZr튟17;}Oߪ)t޽~J{] QaE%ʶxL Uy)4"#^f[xG%bw3W43|6Y.}&̟SS|&_[M qʴ~^myKGq K(,(`_ebhL[ i1m14-ƴИNXeA_ A7}qdh4NE2A Eq3'g.N\82sqd?#W#17N + Izt""kFDOȤIT]D$+шLxQGXT1DCBE1hOQz EřV!ҙJD:O"PL <u (mUFed O"Vxوh]w@#D>! FO?6 F5%>",GI3)xQJS7O)ld #b/-]Pk ( ' pD 6Dxx:Fz [T% )cA38} 94G %c% X68e8@D?fqHR`Df |D`{+": !D ܐ<0b# V@SJ DBCu.qh0b M h0/m0N"ŋ 4" e ԗq@n V*GwOAʳj_ѓ'kFR(CCGv8K PHA ÂR\MCp*kA0Vmk{R=r (ɀ4*'*pU @GB$&X6{`H]Jd0( ]`4ƔYH WBҁRIl;ZpHeP֎od`J%edvV_(+HSh!ItF'G!GjJחat ҈`b 9= C~Fid)4*(/-:-Lp/;|)T52ѡWMQV@ЂfL&lQ1dPs22X`E5G`]x ` eB Y1@T \x*`0E֐1!h6u6c##GD ,&4 "BŠo"}@5 ڢaC(]ѕH.0:?AdFK*:%(@L GqPF4jrt"PHP"x- /g` 9(aSDtȘСfMhؑ%bhTK,&%`a"X;& PCMJ0aU4f?HS`^*@O0rM n1aL@̯?Bk4lJ*4^$Q8v5l]#=*AӺE w/XSEEiDu\ UzfmKZ/+V~ gc\ Fqj,'(6Kus]ŗ68Tg7`诚$TfdMv/ijJ5N]L!f}SymObk5;nbz0v|BַdWsIY !Vodh#^ o*׍w~YoH_H?~I׫&ھ~ 5Tn#BW!:a;ZĻe2؁&^jxBć 86k 6NmW@ힺ,cߣ_6:k+}^*1cMfVbSmE; N6fX[W,mklkz 7_ VeHlٙH[=|w _֨*͌gu:^?z?cWW{8V{Y짃IWl}lץpl}.fK2>MVgՓW6?JH9뫤5{PSY*?8_"i~àpNCxawQwO?%\6nQCKܽ&Kg;Sok?5QFy~?.ѐzЪ[e<`cԂS`Cu]E~F5ldW9fl\(Θ5" n=ɚ6{~𽦙+z l۶f1 1899~?5a7~S+g^Zٝ|vëY׳Ã^}[UbZ+'#lHo]|mµaҹ"O$q.1a8Э`nڿf^̊%Enpi;"J,\5UoG|v+Eo3v|qbV~1KΓ]MGײ =ڹ'$x Xv袮i~;=EXggKԟ0}Ѻ??iN і5ϞT2̹}pQ$cşqu;~Z\+U>Ɩ睉ȗ?o+2fsU諭wg,ri'eY*rɥ*Gx3DbZ:R-CѨܪE? sKUxs1hFTb~hȄ3 :y n%,igNoں}t!ywBIm/ccլWvw梚dؔ۰>Z;;* N}GX:O ,1ؽN뺜]kMW{5K.z!]Yf\Jj`gTsQb+"O{Nq=}lKGAc^RrE"Z>8?#RoW$ ɺ0*sMޭsE!ǽ;m*4+/t~qm̫}j~4۳^9.P{g-Ěx}O6W\ zn5l`Z K,C-덞VVa ~Q)Qjq&:HtZ փ\%0-rBU%K/gbћaw[œ2Ϛvs^ʿR|#K΁*K!ji]&6ϋ^9 {!F!cKR7*q޲[-]v>~ 璊L:3OOx<6Z^qdT7>c%Ǐ. r%RiY &3o>>jfvouLO}6:yy닭2uzJiZa۝ٔv׋r6vX sew2~TY|Yx6쥎HHĹ%bsf|G RK8pX}YqS۳ v|볠b4Z$<[FRF%BːD"muB[l[' muBS+!\98TATNtAo ǒ SQچ,y*XnO, +]V ߩ u@x $Π(aQ +L&b%KY-rZP x\ ѓ$ln1AA\: BLx0{NdO4AU˩hBb$JJ*i |ai\Y6.A qсVHà d{hQ4X#6yB8)$c&t2,e P d, L.Fu;f"/?U9 dͰGH}`F?h fYzFz AlK c0h=SP2bG l2=EAe?a.95pBR xLH#a'@e` l Zb$Qh-'pO ,SX̀eUߏE*&14cD31#_&OD1 n 4<RHSZ:%,C`$s LVX"2@ ($NNQzKf0Pam +wX# `3NPW?3D1yzr*䐁\fŸ*,l!+@(h l`O/[ID3ʁćY#n`0$&V%Jɨ F ,;$H $3`9]jplesKf̆'KGJWASj"֋DXY$,P8+za wPCĺ9U @y`IT:D2FQrZI*U& GG9F`3,@܂t]fdT!_@kI[Oc6'=& L{NlPCy M&H:V0l<sЀL16 ͈<"A7 -@I`ā 7D|c8씋`Ez j+/m0jLFv@\m!"k%h!VoS10tП6?nV LGJ .rfT2-]W-GBG@I2Lo1OrymzہrFvCJq .FB3E.=Nܥ|1'JHHƠa&"]4e0ʁ`;2}{LX,Ρ@m6 i1-'=Dn1l 9$ "L| mp@8C m4v}I2[` )_] ;p Jd$T1`7]ԥpW5a],x 7p"4j艓nLL! BfPAlB5L ɖ`&k¸`?&Zs!evc FxD:֚Z d/uC䡱'pCOAN:A5,jXceG*$9Ǥz{eƒ6X@46=6Ci~l)o T]8=`*AubP2b@B HƀH6 10n` ICv@Zd*ʦI'b%Gا?H0nV`r ѕ0z dHFw!D*:hְ 4EaLE€h`^%#0'G GyȄ@ [mBÆ" ֿ n@0D!P#.MU}X*a`@dE!= HP&bbAK"9kq*0$OIF%_5E $$<}& ,&&Y _0`0cwF 8LT1~F; ,/Xf {v"8h "[y0(cw TT" nkٛrHlf5d!'bwF`1pd2\4Es (?#12l>m\ЉX0%L;q(`XhAMa Ѕt@!e #@(v;XK2O7 h$ @iS@* ' j 6硟 '0t@>'JQj9  6LC5'2D!06>rCI$ C0@6>Q14hACABźX :: z΢d!T/ ;&"*0 daP^ ?hO% #]*Ll0zn9 /2ّ.:(W Vs #Tz4 h aEkrmw'= vaHe p)hE(H 28|LpO :SU EFL";R\@jؽ,Py4vPd. =ʂnA$1z8itDjDp=tGD~UFPGD#B5/2E)\ :19Y;,DȦbfxu6kjofJH4sM]99H+p*%ՄHiЎzDX\xUxõe\+j;OvZfկ8jm0^dsmFC:V'vxw5-򵹤䮹qI'<[xEI[G_q ry-'|Gd;.|mWS(aĴ 2Ӿ IOEմ~"~xN-KbUZ>ݗO,()$LfiJ'b|TKtkS]3I"'Td>sGsZ9p'^(}!9V:1]#V6D*}NgZu|n uUߙ0r'OK/ceMBݿexZܽp+V ~܉ά &j],ydCvcZpHM)IjCia7xɯR (`0PN 奦:q.U2qi=y%?yUݳ--Jy Q~.Lqlqo+Mx\do/ Srj*4dÑ t_>`{kAv N|pa5:&&(7NmΦ=Uzbm*2dWz5 1T)^PJauG^Ewk]9C:2{1IkաM{-☟*4+mh'ܢĔQ9=z|)nJG,` Cv/gi;n4pC/uMtDMvTܜRJ|EspZ^Mgٮ?"|끕5\^ ?b5%<;-TQLJv9{Cb`jYLoA(p8O۹w jh#wcӶh%7cdue_(OhLdPR*1&Njyv_wgqO ۳)\Ze\QɛܥeO*|uwD_rɝjxׅ lv22X4Ogƒ\jңTT`VB; H FuLgKfm&|oW{kQ\ÿ{>rQA);JS^bW!6t5DFGQb=XK4AW{ܳS̜6眹e^Ӥ nm}X=dN.xv.]iXv-o޼myMLVڃ7}bs;^×=;5pg{{vYz;}t]O~KV|Onjbv8p ;}wz$]\yyrwO_gΨO#*{_7_㝢Svt]~O;nn?ngOrCoBC?ͦvܻo_k-36?oK_۷~E>ϖ,{F-9t]ի>rW<ȳ:~xu]g,V/:s_ɗ^PYcna=G}sڟ5[r)'sN[yjܼߍ{6|{]֟ްd]|Ʋ#nknj/3#W]er;^4=~X?s?ea!6Wg_mu{_jV?o^Xx'7>w'>ϜWs pW~leSNOe'ow#sw쒏W\vo[̺ʦfsNM3]x;1=2ovCē}߭,NNl!K>>G{uzT0|v͸nS;]N=Ǘ9O3ge3ҝ 0&\GM]㭯ȸ3kҽ^zOqOp#g;>_?,jxޗ]}IO^>]?yq}u'/|0n/jȉ=w̿];k-=g +}ssvq+of_u:`ͺ_}uvɋwg\>ݵ˶m&|u<5_4f^ټ U{~???oz92)߀Gգӷot?}~ktٽˊ{$|5I 5^]Qdc;?$WUmln;R٢ /f3inrG$_[UtZ,.\̒J]E7YrEHjGhRO" 4rmH:F{~y.yMZ:7aQ `/gA!W'm%a*M:=~o}O%Zv23gRgR띛p)|&xBKe@ [i"V㲸 {%T/_\qE(YM_I*gpv[p[{4g}m—(t+6tCH2-{:s} 8o84-a+slgW& un)p_XާRߝC6Zz+$atoړN"R>p6gRB~ι=q6r9H96Y#< y\57+vy7vza5d|R,\! l=j& ͹CFTTARő8)ذli nfu=rnG3p]HJGnu;/'l7t؋xh_l5|gfFJe=6Ȯٖ{/l"8ҿk0a=JTb s9_gs/IS|_btavK\.=8HgLI0]rReBcP-=2R$#!ɲ 0]:eK;(eo㥮c[.[ a*7`B^FIڅC\crmTt=f܀ɝqZe&v+[mLs rso1AdkgGHHFƗ|lP+e2q+ i@;s"oTpjMbl2+k7U=\i[80UrV83fj(2vY( qO -8!8&7&JOWXIvh-eAZmQ^$_2}#B[A;FqU9P(цIvJWacfng[h!g.lӏ$;K=|l{n Ʃ @k>·*=~Ų%ew=s_^毒2cT~IC8k`A#ьÊl,з`:q|qq^S*gcp.oqYPp"wE{]2'+dl̯c$ΝASĉIpxN6Tj=Y )E v l8H'ǿcb7{$ ]hSȎj׻]as.͗aࡴj7b0z,< H^'/.ve*MV2-Ds{Weʱb"8l2&rȽ|.U3$4Nd7\TDK# e:RC(?x} !^vW%Qy- GsNm%M3O㼶O-.bXpN[yLK*b\{ޟU11a,@H1}u?/eť!qi&PYRqi,Gˈ<.M f2t3.bwᖣ5$E$Y {Rև^BeRCR7mYv^Ȯw:朻XTMktUr0jNإ!%hH jsü$4bn5X>"G7qa6(ov~0N|C..">=£^C"4u9Ԟ?&n8#4)r3Ӎ99? 1/{C%"ߊY[f7yq]˶{D_V8ZryvfKf!Rg 6Xʅif專 ,%3K9.u||\ Kؿwl38͌Y(l8Gcqb_{R+?* ɦg?!CEG9D&0Z){'$&uf]1$79(V\/-m1pNq|ni8jdlO1۾ ;'T>cDt"g<$S{ {S{B;JCoo )5 9a9뉓 egTr$yBǐy얍sι %'I.>:wvE+zO;¦dN`];Q*SVIge3v-bBwҚ6.mvYoXoyi<}=]nMgs7w N}ձӛt5M~h?6=7P/8ygx}ݰ&-:wfOA|wuy.9y}}'ztc]uӞA={l_ˇsWˇ;o'h=b;Nlۍa9X|koݳ升v9=8ozgӾ=QzM[qEWnq63ue ]v%7/{'?ڀUN^/;v[a7eA#Yz[_s;Erڻ/^{M}/_Y=qVտtͯɽ^fߥo51^̖}Wskÿgs;j>{ο W{.`$N?I;еyiP{لپuOxKsN%H"/ <&iIgt[hEbO櫕wl(n~peegnKƋ~"gp\ae!n,'Gqʥac9X%ULfJS_ёtB "zbM(lhұ7Sق*ۖuJ7Qy6F?)yq:Mdǿ]ʉlxH1D$$GLh$ p)h$JLeitH8M%x0c.9Ydy*$u개]#6GΦ-o$O`ڕ}RJS1l9S&FG#ʬ@9 3ΩSf^ԮK7~9.\:Ȯ21Og}Y$HPYһK` (FP A{u ?|g?3`?s`? ՎT%;[WrUk~c44uj qCS0^y#YnÖ&m'Wzt-h0|6~S~$ezj!qilrMxT~ B/Խi}->G)k^M͚^vʑMiĆ>;9W~⴦/6g}U鵘*Ne aV>dWNhG%{N2pof?&/xǛ*I{JT6u]|ɓM٣fJ{wyTtyFx#q22?nZC}_6=GT6!K/~w:ۋ,*=[ͪ| _}b(hSJ מs1۫]} a}Ҽ1y?W+idX:> irXލ:Ȑ)}NJ柫7WUhC8U4Ev͍",); pu;zv]a>7|8,kwW7JaA *o-e޺k+ 4 1Cᯑ=*Ny%v<K`'_4t޽ա*[lk1>. \sx4{}ԮR'4"6QEO|@TbJJW𑭳7c]3ORv?7m%Ts$~s? չ?_1u]x}j:Ͷ:xTQgJ *n|ѾDTnx$w ]=T43,{>MNOW3խeuu]i<epS^R6mLPQ^1Xe>~MGw5cGMiTQ&H- VNl &(<۳VW{A LW4Bϡ"QsbY_Vl.`!9V,`xib`Q*ZA#2y5/[JcBy cܝ0X#"vxgeoQWycIXRЀiI.z0d@$&A0O?S ΃(QuSIXJ@L KRLda`*€ 28ζ}j.&ubUc2LUA1ί/ Lz|ske`FUBˁ / iT7PBlx,@JvrǣpBGU K,ōVJH9HSkJc^.cT=X> sCUiI7/yuؓUILGt2Lxcv̞~WoW?*MR$MRg{ƑGR;nͅѿ)^X&xTQ,zrK֔;hƑsfÄ~P {o(=V.VZ5%B&**eh* aQ9?&1tufA,g]ԍW ;7 *\C]_q1Kp(IoXPCg(ufVe+QhA s~%rd1 *-3h]BV%rF Ŕz.ϜtYeYt XgUDĥ2 MY8S0%)5lRD^UG#;*{;[Li3Ku&XUXL<8Όlǯ}w,>Q!}fkGtff)V46 &띻)1%),Xe#֣aR Bb;t̝P{DĬ1Qav sD:g}|3-.I<}/g IJ;~ѩsׯ9>hQP?s6-}ZG.&v S:l0SXqf O-&l:0QZJ9kg*MaSAN,6]N9"@ QE>RIduQ$Qei'3 hc7 d#6 rPi" F%J9( r#e|2 3B%ztAVYD|a!'zj+p`ݓԷ δ J2*Y5AAR[]D+-B2mAݚ 39uQl&-9K eM$@3Ȱ~9~L K8pYN:I M"wRzS3nXg49_vSe;'-T؄vw~/8^veiw:^UiW9]| خ-Ɛ:^RN+Goi2QPKao2znөV΃/f_׽)$ XЃSeb]V(l(>ݝ,UWCX*LKG@>a@|IJaCvLj_p#/iFLZ 1 e|ڙ^(v:{aw[ֳnLs9>ѻg@8'=>>3K{TnAsm܊1<Ɍb/˲(e!3`OS5^l+k 6VX^"Sڸf{rh;OO4ry/oj[ےn֯6Ae]i9^KuTV~!S+M.v FQ>Um6KizRqnk>T+CO}PPćR[Eo\z*=OkqnX[ho,k?(c0v-kzi@}n@֧߸(;sm]P~ahD{u a_Pa/Xi /uXj?S}i`_ك ߸OO[Yj;5Xxw>>=}0?apmq Y7읃ipE7{ؐz\gPc8z4RܸvHm+4*hxmP;5vlGkR3k=h\tcǷY8}]6.ǭ[+*\[7F.hW4׆eSCi;Mq58ʫۭ;^!s}w޼zpOލ#j+\?Ͱ^]%pojǾ!Ewt._\'#kzG#Wɩt ;zbch_ZSARh{y5i+U ѥTvBvW~+Ѿ|؎i&\y1U&i-.y9IpĄvp>;%3aPׂ0W^Kqӓl`lguݽUq$%yk."k]XbVbx;c5T|#pE ?$Ѭτ, "ՃVyc8)=gZ4XFi翽;q ;+kMpk!Lh]Z ?HQL$a3I+8AӒܙ `yo؈gAG?8V%CCBLMZ}tgvɎ'HGɌb}ՑWhίğmn䎑~ڭ ON"'&%W \mAs6bNk#R#}u;f?` Ǻ}=~&4+G>SjDc@+##pg^ fD 2Ӗcqu~e}RE t7p~#"2mKwJrP(5QR+׭e| I Fqo6#/U2&7L4( ڃq,0m@ө#`iMKR1DB WAP{\h*K@AqjЙm`0*jϝ, gkic?4 ?`HMhS`/`ܞ\,C4j;]+cn'l4ȗjwM7ԆU:݁d6~X&?uveX|YH R6j$[iq қ @#5)` }N2m0!*aD"H1p @ԣHD IS ` -(mH "@f<&DS LBFn"_ h%֧}xƤKf.c&-oZ#X W_#!Y_ 0YA!0w!O(Q܎TYIw2C80h7 @0C,k 4ć"ccm4 O[da_I}Ƀ 8oU3s1c*@QDC)H~'3*K,@0^iVejVVY$W=n]ڤF>ߤ%+$ ELT* Q頞deVU蠣Fdl @k@ U*51+}H[Jd)T SH$L@H(4!PyG`:$im_ĠR &Da n(cl.Z]iIw\2L#ͥk j0a<:,&,tv5m|g n(V'(o`Ʊs/"Fh봉;ڥ_D DM A(0IvMy gC{ @#M#п (3j- DRiմDQb=NDXpҹ2B[~Z͢8 @ьb$HZEH)8PI1h3Qp Ru@/P9c?:"_2j*00`O.Q18q[1Љf,V$oo:™( v'T́cD:Nt k"~݁a&-pXc 8 @ ʖ%YT8OxA1n$@QO<[I #6.%6I]$^HK\'| @&2#$ʉDКV@H˩+W$PZ'1h0UKIƸIXFlvDZ v!fH$ëQJ=DA"_r:i}At!- Q B$ E+qe]0##*7i"Ǥ1|w0!0=;m+x^Z3=AsU<K<ʞre :#d_xc;I.t9-o埒AxU^I[.j>c,_uoIH'ѴN QNyVwȬui @}1}aHם,}JiKA3SKBϿ7 9:(3Lq 3Q! 1(F*|7C3ѐ(v~)S3h\ ,! HG0"eQ8Bb:8%K$ $4 F"=˷@,#’Y˓:V ElcrUA"C1?WwnBC- ۷ݲ%&"2@|JURforʀBή>1F٫gF!y})`/@V=v=]Ib/aB(%%w~˥Yefhr.e;:L(SB(6jWh/OXR@Z?SHGxu!_D,~ a8v^vOjX (53߹uRPEzp oWT2nsKd_!eb`:@1[4ǥJi^0ݍYSs$i_4`U)\+TFi^a|[sHN[D@U6*Å`I eaQ%}* Y/HCIpDG$.(؀WT>j.@9r-JgFpA &(.!7#Aե w.(9\9ىX+3!+B6iP=@{%mvd_vE~%"/Np=")/)K>EAd_Ds:FIi% .i`$!6&roҕiUc U((RSاI!ΊW2~Z0//0aOmN8_G9*|hM] >?-w"Pg>+S{ox gT<C풽mpLԘBZoew!T6Y˰Q9W>OJYI\ZBZ 9 f Fe:ʐߌ`6&,V@#X:i&" (Ă}r =Trmor)T:ӮGܺ DQ-pY="UFD|,A؈?!sT߰"8|Ց:b8hac*&k8Qm. /&";*s#p qt@T@hx_:ʅuggK\Y Q['5` 8 xD,2߫\$x8p >ٳޏvn_$] q9>c pWA(mm4( &|*R"IR$iFR1^*O B'V4K߮^uM 86P߀DK`]IYz9a Ѐ^$} SA{%JyB80 X!\@{|2pĿ@ 7 &+谞v9P6 HOvIh0 9gH$@9m`Û<IȆrc x``0c* FatՍ '> KX١{d= /'7qBА. OɁS>tCN0,s4S`NR ?L6}I Ma >g"$9cXO9RgZ_cmd إ\t`}+<HNbw4$DH>X&)}#YfדTC] (m%fi]>%zG?zHJ @fIAXx@_!P3AY@6pR*%F3WRA?jƷd!pWq4Hr;tkXΨxV!-Ug&h 9,zj_ =j &? Vܞ/!Ф1i8*o'娮E`M˄P(]M PNщ?\LC(B% 6|8%8($k{r ce&A?mT7k₅ vreC CANHX-%+b!?dvHNk Dzʋ?fF } k8 H%߮A0S/dD0,ʱFIDΣo&H}`Hz,Y멳 6GlkvrjDBrx}#wJB@&͢r1p)I`.9k H`#V`&1$!lE޳@& ]($ rn&adc <``Og]ZA--* ZTV CXP0%*Vv){4|Fb llL]u0 ^2-K848yr4]ѱ8U .Ʊ1~s T59G7 cMqv"hmS {Ïh?dBР72â6 *t{%I y+0RB&?#=LTqφ!bY׌{ LSCN0'~@30ƎIǂ X8wh@  r5]q3A*;bǜ ` W& CjT$d`~t9!PILBj*0wCXTH-u@$}E`K!73mk=R|g>‹B'PǓ,o@ |w$j @o=c//Z^(0 T_HyL ՁS %X1b'!77Jb.[b%)4ů(Ω=І&pѣX]!~Td8)N4] 4,*;njU%J~w"D*dcx m:.=`ʷS,B.R3p"U`% Y #nAȐQp98ĂR@r0F$dh ør@wuYK$H F@ABBr6@9oHC$ 6Iyƨua+@$DDpm H*AЇ0fA>N}`\$3kxB֚|lHU³!KE #?EJ+Bs&h2 HW&qJ!Us"+l|#t$noṡ@Y{~q  'f|N8B0 (xS̹b }^q'`q`ti8|FD0'$Iµ3&ADh$$ H $DDoLI(&1*V"=B\'lb !1:!3Njc5-#_x$&O.@6:~iL|F'`0 xK)P)Q$\9kñChՓ'Og Q4yN ,U1oAAǘ `or$ gBB_r "ڐTw5kN3ݼc[q,3ּ2n Y6Iij3ztFLo4sf̞stDE58jfm譂Oxdw<_#oFޅ7e(DGȪd=#I,df"z~su^׹^׹q_h~hX`!pPEI zOq `d^x X9Pǀ _ zg Kb"r= Gvv% im<ĥǮT`zTDkr$q EwP@,[RDjDPV\J[#6X%?E:郣Ւ2*񙪠>Sw2ǜS]$Պ &egg}&c*'mW[5P˨)H&fSVUQ e &ɁDyg}() "ƢPK_2j*!MO|f1\+0+: _ yu=Sk^2l{J4E@.TBZ/N*m^ͱ׋?8(ݿ SOr]wp#!E4LU\ˏrNN] gU%{tNO%g=9/&6ζ|U^)+Qw)M)bRhck7g6[ܱ\ZoÑ_]s&&t!l}CtOKݴ6]Sq rn=a炐Q|K,L"0p a`()!K .04 E``r (!d"`ǐ8"0y P0rX(GQ 'z<Wε B!`L76a'8^ 0,ApEHD4:+U$ CC`lP)CL#̃ahmZ59r2!; jA(@0jwE,\dC(`B1fI078a]&GXaKG #e@UViL(udX8&0~6BGSH~ywt&ݣ~EX $egV$!ɉ,K M#Pp4BqhHJZ<-#+b2RE6Qξ?$QMe!OpӥGlD?qc}n:.P;!voط@տ=;o}@ =?X(FC+cu *Ey2Vҟ:U#B=BzS*ijCDBjyU8W>>hـV"4efy|T*渝Npu=p}U%1a`3S]:KB>Me.yQjnypXnpfG!x1qybg`a.X~*e`e;oE=6viv,2|ĕ]c d]ᓖ@I7#Ld*f ]J#觱=aL*-/tr鴄F!& EG]_|K;N|, wobį 9y^,d,t IMaW/&o>ƛv_"7r9cVY6ߟxE[>/p -An:gF|AՖ? Iu" ǽ+M0V5 YӽI(Pݠfe~f=l3>'g/ytyokW)]NfsiУV^¶(P(h{I*^$s) d#8ľGoMw7LpyWCPCT.A}F:ID\6$Gn^-?PDKG!bOu=߳/sJ;Gn{OI`6gs8Ǎ\|ǭy>  [G&:eFkE/$.ݧӯNs*u#>Ȕx [.{e~g;;F~溽lMwی`8;|KI*WƘR[On7w'ǣ''ejEtøRzxk"d.{-lyKÑYӇ ~*"5VEf] Ym2,se0Vzq'HL2=͡x뱹ki1*8TA8: ʇZK׭ ':'k9:HBtin,GtY~F7!" b+%婩øl]E‘x|mrFa3MvZƈ s>~O2l 띱v{;X{r]M,YqJxJSl@ QSڟXC"՝RܭA?կqL%qF) "` w0E˄?5DL@-4< d8j@^H #ȕ@ ;@3P#':/%)fh1c p&0< b0 X?C0{ZLc`rP,`fŊD50y1-fɆ% H}`M1?!0fł!"< 5 E}8-h bE _^G&AE8i!Dߚs;2]3b&8ρp8)?V2yZr_'>2@!RU]ep$ .LIri"GxoBIX+xkb1rpe!00✑0y8ay. L Muϸb<'2Pamx޿l+\iBk1ёMb4E#rֱM[6q3):n+GG -V3hZ|&ܘu.qLsk'9ᗭP8~UEq'ɀo(cnC˛\՟ʻ ?oWztOMhBR&s ,DN%/ㆤןUL(7,pE}_%N_daz9LYMeRL ;yWp7Z`&'4ˌaG]bg.vc n~yDj-R.by秄 E kR ˅ &t/wҾZFTtL&ɸ,kׯ/i%a(/5Y&lM~dl>n} hd=]nlpj<'i\vt$ &CP,IG:9ŵc E/ն.䖰/OH 8ɴ㴴ҫ7?H`wc;Sa7l?UnF~+̗bP(ۘ,t^x!k}=/rԮp]|',f;G"sB؁ZWq~I߽BÚ[xasfqcEv&S]MqХB>2k:WZ 2/G)'tS܋g ~zOH^2[wjS8Rѩ=N_}i({tG(^SVi])iNo='e;8SԵzLum]|6z(| *uЛ)X+\nkـCE~{GCA7`5W_(ZM=|K܄[qmF엍oI&;~%+ԯܗəpd:?ҬiJLaB숃k L8 N6ƹ r,|gM6 W"9mAaM_dCU/3^}7C}exOZT񏟿sޕ]7m@(TR!bP{7\' %K]y'A30r=eSlݎTs0px5,~&׈eː]f;`Ѥ>-JsdHIǡ!4nX7Vu2p^h{srnnI z~*L`"{;=_xim7bGE+)}7u+nݢ_aCݕ}0Y!uU 봂ug>~5Ļ3.E x[\֖o6_Zͯ-3QX[{O_ HK˓hI_aߙ+[V"`e4yUи0?wO+ d./h:qFf/ l~a@+%ˢ|ep>%vxYpkfvZE?m {4e ?.kL0tǞ[$~_Nl:MQ7{dvl^}B$)\6O2m?~!(v⦅Qw5zO^^(0RGثMٜ;:N__Qhݨ.Ek_YܰHlep4Xq 2{$DÈVJ$tfCr2)TMg"&X[dc,1yȕM  f\u2NZ[[JK%1R*ЙQ89853%~]dL%+J&y&n^ӣr56 tt?%Y~BɾF[ /W߫YzC1uA{fۤVjtc|?rǍiw>:b94q~lU[YMբk#G\Jq+'" ߩʢ4}::R2Tf #j#k~t+eUq7OBwߘ1P:.a#p$;_#$!6Y`j,OȎ 7H(Z@"xjrQ|B{jD )<A`sEc9U$Y3!0,!F4@KJP@ $!GV ?~J:l+HE:4 )paw6tX E@"AC37-0(irKɀ2$ޤB'i'&%^ a+ $+lK4Cm.^tplq=IęOMs j/Ilh6g=.X2u\|YfYw6oVL̾d/N1&N_fv (xK^,qla/}iKXbdnS3M)bV%dʖ$ҙB"t"PI,g7_\܋zC(]}xxzMɡkH:NXW&ĴsO;&zZMhВX^ʫͶozTNCgچU.~|ᆲ;STJix] f|LƏǸTbɓN;r U{9Pp1lԒy7|D=wZuyճjIq|.] ʛ$OxnUYcgs1Fc5aT{94!C:蛤zY̜HZ$(+/f>NZayuCz뭥+j:ZE; $J\ashjY%S4җ>܎-2$;/{> 5Y$>;,2>cHGAG1)Bʉ'JհvZ㚤]2U̻u|])pїP듞 qTҳ_ !șJhگ]/Z$|kwV-ddGX50 ӆc=py>K~ik=o"yIJ#-􍯕Fwÿ z/~)ax&N)߉+EUvJ CS=JOivJ5ޞgz J(/ l/p3;`Op?XrVtCrǔOy ީYɸ'Q'M=ocG+H_Ό.wc*Qհဤ}@s(+D>HwL;J)m&ו)t!wqhr 쿆0\Ӗuٳ{ŭD-xC- ~_6~+gͣ_b%P^]-hiV4į؃ܟz t\ wA8M:o %[?/2RHZ:)bpao}򼤅KQ77]z(}g^mJF"4PGK7[Coz -:ӝ76lTȟe_/Np\owF*'6UdM]7d"_kv~VyqCs*rm\]rl |7ۡt##Ho-8CQtiM^ zR#\Fqoi*+la"Q{g/,sܡO-FO5!ص[3v][^kiMe7 HC~< k|+Ź3=G\Y-@H ZE) BΡn!Qe;IA/$&8 o"o?z]omF'd1h8 Āמ [rV(''H `FΙH⊭ oOcϷv5(e[/i2+\ˬM})GO۶EY"1@Ͷ0P EKr,EO"kZniD/^4F|]<8NB)6)b|XC&&k%?ť[:VOS .PG9dW~I7:JكZvߤ+Я 2~' )MhEW"&K+?YN:I@omja6 )LpӘgNwtnrfO4 )/.d}Ì} Ռ޵Z؇gu1TFM9o~mWfxD0@.uovF-:aDY*bjMp!r/Hyn~"s^:jvgG%5w\{?)q*3 ;%OZ:iRX6˪CS?2IdR/ ?=Txh[:oGCG@sD`qvh/$XEv0 nꐆ11V-d(؞G_t^S,C;G9|asҦ5|ӗ1RQ/t0=;0zcD6cRX/q65F;0~Y'U Dt w(TPHkioI?XK䥁{A/ZVƔk0I|evÓ4y^E/^}I 9XU#rLsH)oT TFJyd~;AM/ݭ!0Ƅ[rXΟzi2'YyY SYnI~p2zD4IVڏSPz.*R!9쥴#0r$7 8RmGvn+<6ɳ[G[T_k;Oе9L'_>xkj?TsyŮk\]i,gW-B=oU\/8T97Nڷu!wHi[M͍>bFgz&`jr{J@DRT+ma+GJ=Z캐5|dU1&-8ʖWG*erð.~.G%GR[6#^v10zWyLѫ>C_iB;nh?d^Fߡ6VYP.zg]ki9'\iѡWG5^UwnR9݊qT{dϾ' ˅9G=uSXh1<+sS##JzǍ<(I2ap~De4HUr,הvY54<.VDUދLޒo@c.]N60q/w~;[+qhN2D9)w~YJ;Z6+ ].d\@Q0:KuT}LbxT:ŢHz*G[I h88$$8f _Ph8 AV}r a4^}D_h$c' GpsV" /ĒB$M~~ c$,q~?$0CQ6emGzMsX/*pJ ]Ǜ^sayd;\Ja5"lA9̪O_=ޟ)~6?E/b^ѯ?7q)7^<TY&s.?vP/Kutwޯx]f_8dvbX֠99LWIp=QoĂ->6FLGI3!}]鐱Թ?0|P]۝_,삗9/?Ev~Xvύfn5K0+YGHTo:Lt_D>7muv ) %Ш?y!?5v.V/yfvAxmc92ѢM;R̡Rs?Wk6OGu%͵zֵ%+eG4IW&  ^r~]J8}v=fbgʄgM'v/ι9 ioqAHlū>: {GuCqrI9AcV㐾nb/t4%豷o*`Ai>]@H7[%bS`N3݃/q1w1ټ}9Vg3khsZ[%Oq@gws-_x\Dpy(Z19X=6+c>RxCmBra*Oqj Kًy8 w  sx^WϒANf梡xق}GLs&W NY<>>~V۰{>$t$ZeM+c5Y^b`~I;C s2λ\΃~jgJ7G<-1ϑ2pJe֬I/ubJ2?]*]RiG"\Ht{?{2ea-q{U"WӑXZivȰ [M~ˢiLM^#흎_ab7-R qp5ou+kLxZ\4`gc8=osaChPRwǪCCo|9Θioo_K_άԑ~U0Qؙ M9|>c[%] ~@ 7p#yFCi,}w{IzImowMoGFt{ȕZNwl'.X`(11˳w ((ռ6Gߜ8F < 'U>\$컡jd/$HIs͵;q{Dsr?1_Cg]E/_RxWkť^|c+gO\cP"CÓb: pmv_DxZe?ߩo9zvu?}C"M;rؖN/d!!RbwޙI`6 hYɍpٚc\]̐0ť68=!3fvF';h? T0abB*AQ cKr>\IQ8#1P$J&w~IDB͆BB&-!N6u 3D ؚ0$Q۲@0VyzUdOCJa+i|Mh$E@) BG/ "e}s` $1 '7u϶ڢGH^Xʣ Ӱ5;N߃)kgZR_n]h ټOA!;ȮzGwNc9F7t|k*=,qvkmʑյ]6)i1!1Iӯ^O_gaw{D5Ⱦ4<.4z4Gf|*1x( TG%G&GN3QŦ'Ktb}8;wښ?BwXbo\\0^^T$"Z[B2?5cYD!'ڵt+O>}yߙgѤI|nO3KIDd\Z1Bͭ׭KƵ-`%7_?CS^c=Kpk\[ib-)fBBOoV~DZ^%}GgVsՙsJ=ds 2Ԫ>~d>enWu9\M2׸H%!(kWe]t(O>!r!nd= :nyCw'QD TĚMԑ{ҪLܰ*S&]#9Aq7ň.| ?$|$S]pf܀|Jʂ/<F#N<ǺBK3Ǽ-'sf 5nw8o3:Zh>۶p )Ix^9Ӂ1_*)l ԩN#?Ȥ19 J{%Յ~8?H&z'a.kZ9m0Aa{e%{ k̸Ҫv<?b.o2M mp[5c۟U],6: .[Cۣ oLYJ%۵f(ɤsF妼*Sc/Y+lJK\X~<O;K{hi9Bj.2bIt!dOPet{{}XUXBY3+?O;+;-Oz* Ter4;8\ҳȐ% 0/H/tY7T% T{`߼Y𣸦Gqk)A6nE佘ƽIKboCfc쥁Sh|~?'i,g+9}Y/tQYCyuѿMN+DdN)SFSHsjf, K)B}rj1h\FSo2 0^Mc\ڊ*.;]o%k\^#>[J*^{%pT l@RkoR4yl1G~?p`g? N/hǏS'u<ȯL{6XeE^ ЗW QK,a0P4~qw.O}i>\e;xˡ6!efj,͗yYd2R9GhpQiǢ\G],K?fpqo}0YXY6>ڼ.د՛Ztw,>1F̋yUzNKn+mlK$|mw}F{ڵ捭1֌aL<6wM9MœT(tU cSSeIa)gm',{-Ss/:et$ۨ;3o9rd*u d3`rY:J _ؾJۻ÷NUeP\ѷMnqwwOkCn]Kp'X hH53uz/}v>U[{gu!؛2oL:>-":Os^%xIF"szg^Wt= ˉ X)[/Pّv\5 7ަ $vA񢺍C:+2p:i91!ŶlB=}b~/A)lxB LX#Rpvz $ \B~Af:6N'2KIkq<\ x[JT7?qg awl|ܼǎx^9MV/֜'9& XW!Sr B&b9>= }ItNXtW&$,쯴Pdar<*3Z4eloAHV0)GPoz71+WXނd4HV[Hxn\ 7 /+rry XT &oF`l@,x  &axX75,̑`LBک) _A `6f(88v^Nn7rx{o\Py"XMa(<-w#}}l@>kyE-#?EMa0gP6<,j6#7Q,R/Cn #K n-3y jÙ`O;B9>SA14n 'l@3=CQ"%ti_F(xH6>HAj3j+up(z3w^)HuZxx8 Ncw3V[k7oo.b274㣵Y$ʷ^xo 㝨6U 2@Gַ jp[6XEOSj eϮh%UVtaHɦ] T=CM51}TovR>=ތ1: xA2)gP ? uTR^3Jxԃ Q>dY]}y'V> O{RĔ./tͼVZQs]'J0vz2"~{4k;oJ"OF=5rrtd%o:~nN°I 8h 0T9hq>hæ80R;wJHʸ qEu~vsԆaNܯw D'N!szpie YupZjr B"Vf3"Rc!W[Ξ|G]B}70jռ?1 q0WU"KQ*ǂ56E$M={4No: AF5!: ,~byyv }(;3gǛ9F]@Dn -&ě/fְ?!< rE%|R1` xӻM8,[Um1ў=I[%l ~ޤZ/@fYt:T 򽕬Coϱdw^r_kv7i#gyaۗs_":<)򩉻> ̒+lEyj5H*~858M\wń(,.ͤfCwS.9=&l=M=7<`Tc{w;Pn-O+|]Vj5oPY]?xeneig\@a恤F|x}DmbZDye$|{2VV 5"XZ[خ~'܃DŽէZ*W1n( xW;' _i?&,/I Qo*Mu1yMz9<9H/z2\. cԁ3KZw‘Ʋ$9sB"+ tu @I312$AD 1 \Z%qR{n 䡵3h.JghoXЩnIj) fX=#1a1a,+i 1IY'dB*K>bi}B^+&TАg]XL Pr_à a%jAI vqP;<((S*Φ7Y~,2=BزAa$mI) [õBR=)gٯVw=*S{9AM1o%Ce|7e| ߅]49ǃh`{t +"sps9X^Y99f>о uR'<.EYr2J14ttH ǿXcWyR+ d[׋&}CFlLBl&0ؐ!?F쯮]#g0s._Mr _y g¼eVb{; wcCsp2c`&;BAylj8 ( õr) `oaÁ)|kw`f 3*-&*q~R(\3(F24yZ "RB}_PŷKX4iDY$|xRH/WP )h0.y{L 0O"XOv8w _!V.pi#-;ZcNjUkB^!=cix> ~^uF΄^^z, lg58]B AiTόZLN B`NIoK<8sۍTA@3BɆoVyK[AW#:R҄:j.2 ᇣ?bQ2j2/N|H,d@gL|͋ x^o. @Q7:j@<>JvނGx}NB%T` Ipf2ZR;5!v+:q*r]/E(Z(閛ZeNp"ED3tX-\9,y<嘐*miozwDM*ZU+L>+瞴l !_Pq>ȁ$3R8;A&+ZrĹa `OVӄ~nfh*Q_ɊRp Jg5 Z$CK GO V빚9HFF={{RA0 Zk^e:rLfbTG$:Rb!vqՍ!1*_y{>udG-b,~}lsQ\?Uqcxtv|d7Yh؋E7,7|d7稒 k{*OpHw:9zw=x-ă*ؐE`kݺ]ϥsn`yKZBk&u)6a0qж'!,954± pB"#ˏ*$vMd`Zjl8䵼ϊ`&^xZ|yrr,:t GՅao) %h7Csǯ :P}ՓmٽbךCSnT[`?.e8'@Cmm4B!;xw˵߿.xj X8la2s|]ؗ4|` k{JS@EInWE&&6.v L|XֆZr<µ]Y1R3i{n4qcSN>~kL˟w 骒/-eKh;Qjz}*ҋ3,vlKgQ8坰3"6u4פjq"k_D Ѹո"6nRfb9mW(8hCv,+3j(Djl6smUUs|IIծ:Z;X.9o+B5;j4ONRJ5drz]| ᳲ2 7`dz&^Mܓ tMɰ|ӏ#kx]l0tN|ɄdDm߲EU[%Av+b[[ RG-^a,MOYnHoVfhNxot 'aRѽGTqT0 ϓZw_ ;OT-/ DGON%{$Zzk[Kh(z5bqLN$R`ELL =LWzZ{7 Zd~&*|~lK:U^[sXO fxߢ9LJIXUTK#Y5ܺ^1mY~02L3'5N5}MlNdK=od{]mf욌Ç{T0!/&֋[ZZH.%WVEs7"::CS~BXQ)6q<7VS䜍k=}n9IT?EDry>}~6l8L$Xٙ~IFn{16 So3>}7RW7s'IBrRˈo'lp0XWZz]%b(GY!B =M/sQgwcf$:/=R<9p@K".$[TWF+ty5t?`ܮWEvc'5FG:qsgU/Q y吧)ďevA؃mv6/KK\*W*=J^;ylX> m\L[_V%lPFƲ`b@g!ŃVH3y*2֞0jOGt YiP$0Q5lBێD%9ăho E~@l o "oW)>B[#ԗ:V@`fl5n1A $g5 ݡbPH3HWT$9iMJqzGkšˊ.*oz~&_-2V >?294Ɉ ?p6J>OeޭW/_aI҈b$6_Ǘ)NDQҺCmZzS1ow(y^(Eq^R8ԙ٧Z # l](B+:lUp|٤T>RH,AG%ÏAFǐU;%Ji/\m@bh\vĖFE(ή}VCJ4xx}*443nz{~$ոH"&/5ԇÓ\d=vTL nWa$?g9xK BkeR󙖁9 :Ed$hO߂cB/ʟv>̂%r.O(cKܕ|nXdRaCl!DЏ ߊP(Dj h:_{r"@} '/;O﫫s.TTA0)(*|qPPڌs{LLL@EC'q)x<sw}Cħދ!/y֦t 4.5L*`4!SRhDDqy[sS?2=TYvuԪ 4RaPlxR7v fdH'MagH D*yȮ 6o\f:JSjY37ڍ8xorUFʪXoz&b .ʤWbg#{(hhm`Rm1!PN[ f+5܂ǁEXeOuY0EdG_[]O ίp\.CdIĔx2>a`\kPO_4Tw? Ӡ>'4sfp {] vl<,dača-I5a)WmV:%h8ی\b:T 0@IJD/B fcQVrbDi^Q|*Ȧ;S Yj]Bŀ CQ0ȖK phu !zvI>s~KB#0a8*:Gio]y4ZZxgp̅)9VQʲ*c7yn $5f@D8W+.ͽpyQR#vddLւbG gSrEYvG}TT+>eCϐߞSnPFO*qޝR֓utM#Q#;ܩPS+SJO"tr\]"9|!Lcw!cM 0spRG˻;'\ި^}/WXgDAZL`wEHQՊ^R]oKoBu";0PQy^3EPHK:ϼprSʣq)%ġ 6$ekztE|m87'k`̑Y+"Êe3ݰ"3^AjFs氯4 X6x}w[Mx1i>MMMPFZ cvUqIgn ahVΦaY!-lA]?ֈw! r=SS *.=𖉑_fT?L0@-m%/  \8ޒArUbHq4+^> {/~@݆+D/Z jzi\,pńs\&\zV>޷aawIVсDxiv-Z7ܱ\KnKi 21[#2:kԫi\p`=SQ~>[a%K.oKyTz=cͽ:!bܤ mW˫re3 ~=6WO5-p=r2Z׷N-/}ᆹ$9,hx,Ƹf]DkʦN~ÿ,L 1&oDŽ_.|@S.}:%1xizʉhjWjlB'Hڂ fvepg7t-3N@4y` f^w99b~%ܑ߬w@c.=$c^"{a41쁱_/ɡOyyȄ5c)G>.E?K̩X("G4&jԑ0А1@X;]L^q_ - ۤr?\h$|~&e&Lbcȇt3 Hg*nGDM4%_ZLȵLhb)|h;6$ :}SKDU21Ӑ}^oӥ Ep(Riٙ1YL IUNtP}ێ4QuOjzpՕ[Iτ?>?qZI<'i؝Za*girM޺?Mx䓩!AKeϖګyX2Tʍs\$pтbwh< 8zk*\$G۝\"v ]X9\fni3e$Ô;%zq}- r^TE=1PPm9Wn-悃|"`~q逤ZRsMj jyx]#֧N,ؗ=5)tZ4(C6By 3!_57`>q"0,J^8%A0"l> V@)rIFgwnz„Hy$Fa׌X'x%}!Q4C鉘sٖϻlMHJTe߃ȕk"@YzUC2uoSQt- ˄h~6U2X?4&=d |`K zXA7؅OK. 6/N{4Vc`*unBS1Æv|K~]44`[@&[h%" z˷5߂ ;шkE}NjM_սMn7KKĽ=8I<A,uC|gWy"!ГW~Xdb8ڟA?L8¸ߒ6F jP W1W}Yzt?;{eel簰CPisӥ@j/3hpp$v"Xb.Rk8g>e+*.){&HhɌ;0 V++q*Vs1Doe2Txd6 iؤdu ˿X+LUϏ><N^K"|E>֘?#&JIQT `/W ז?(eG3苊b{¾V~l0VrǨ$ޥs?)f(0FaD,͞#<ɷ1O^ kzW-ʧc$q8?]za~y{Qb#4CR ϲqlʘkǚ5^z%u|d~ cuor1JwZDIW||'!-0BW@I<`ҭq^D$]6vQIӞV3}G( =Yɕӝ'hADD@It+yadC]q̕$-7q^4 NibU.ďh&J별GIJy&݆oy,x~ *ytώom~n =2 4'KՊDiy!πCrh6h"DOq)܃H"nq P[p6ޠ(ۖT7ۯo9Ĭ/ 0[M a/o_C*ÿt+{+G|^\4S}UV¡;qEL lSjk{06lqm5$".v6Y/Xg)O]2KKL x:Zӛ {pO>v[^N$+@ u@ߪ')loei K^9yxd{uZT꼯6 ITEkD$qVyzo,8V7E|||`PYU$Nmjnh%kQ-q-]O1Iq EZn:4MDFJ*ع %V'g-UMY}QQ'5gg]0\z8i ĩ,KԢ˽$Ks}G{T0AEuo ><>) Zר}hFλ"#p vnuOKDj[mler2?4XGϖ{/-H4@M ~;eϑ3k]-C9y⪔2SPrQ1 d9~ ݼC:Z䋣U"x[6b"q2, εĈ=b^CHFoVfۮe`O5:,彪Eq,mLwC % eepϢ/pUZ+ R( g1?җznb vR ɉ Cw_+^Y+@vs?'T!˻QͥpܭP!e:V8$,É}"s,07Df&dRv #W>1=05-ף7E#Xj9%iݹ5z %`1My>`ڈ.=$R9~+ʚ/zX2.gaJ22–1,*jpvE+(BO(1H_JLu)%tu\IL4NgK=)+4xR&܋nC;3w~eK˞pE >}oDMiXEX8#C*☇7NOc15-U S7Ḏ!dHی_uJ1xW|l/j*ϑ[i(c}{h^̴EA, j\Jx1-d1jlw,w"EJtaq;tˈɥ SվcpiYnJy['8#g,'E)( |CDQw;롰$qo{3TWLk~wkhTgƨl,1[&xH5͊8&uDx ]ǁZӳu54=ZVΡ1ED6<]VJݯʈ-C+NWg63- i^[9%JtK29~˒-l7;-hLXh`5L'8o,K0Fg9N&DtGr6ߢP ljʓIҁ;Ƕufsoez^(aI]quũ <_B)MMMQ@*Vwj-jzM/[Մ mN3)4Rfgq +gT=hE%bþ0j\a@6ZSf 5J&&_\<I-} }Iur8vfX?E K9U=$e}Nsͱm}(e+嬦2F"=qJ!ԛC*>VOm1qTCO3+Yru@չPF-c!zXǛ9*21ܜ{í1pbOYj25z~*>L6os.t &G5Lj+Ha36CA䠰/n-W"/YE.٤J> ';)yCmH^DVO~[W>VKQ3ˍ]Z̰6#'k}͝2b3*% "u%(iZVzV>%{*D1J !FFQ-^::?ơܒ`NI^{s瘾j\j ~\o# o%cBFDZLukL8lB;_c}Uj"Dq_9& f5Uku_gN;OTmSHǺr>yuJ% K!1DTk4ߟ?raj"Rc\Op}FR1k?F kpQ_ixha kYD۾8?$ ]4$חH=+Iir\YQ7sn_(v̉> e>ǢG 7huXTkj+2zװ0~NLʬūuOlghЭXgU |8YYI.)qJ&x5Ѽ kdfɪt}冷ŅDOM*vt%~syTQTP~N5uPI͏4~n81‘ǾELz;l`6^V]$?¢vpS6;.X:F]wN82LcƠSJj(˦*\vT&ՒI7q31/sbz/ W/(:QIIIA/>,%x8IIHZ3lWџ<JbsQpr9)8A@^N_/DO"(*e ^rPerA0AW,N@!/!ʕ5?ꟵA?yA8KR U L CtZZg )5*'Z)q^ PK?*; mA\7t]nBqo̘0 d|}Ϥmr<{9Qc< >J|˿=_\'Vc{0\º8z?hLɘFIGKxcÿ*|o)T:GN;G.ݗuh S=LsBe^7[="wUޕ&yx(*P<@02ΝI[Ir49]nDWzͱC-/χ} `O ]z4ﻱi^4aUТnPdFPlD𺘾Z96;a7o oä!.^㫲zvoZWjb1Hנ`_: ‷K~ñ81J7]*urh% ')[nOW- ^_cn71}t>}{Ln0]>/,>t`p,#+mqCT&5v'ɴ 0 =( aYJo|ͫ܁BoQԯv6MOzA;0rJW-%:5m XtקE}PN%Ѯ T;jO-FUT>_fR)rS7!g[Ow=3:d^臥螈Z/"pE?VIDn$֖u&Y.?,J[mS?mcE)x!.LXL#w85`Oߍד[g@5o,Im Ѿ,lm>rҪ<0*r쿜Y$.9y҅. kwK4>TjU%&Xn'K宧`R <~frHz0}yݖ7F1=I'R:)#Oܙ2 Ttݞx,asR[a`,WK[pdF?@!6TyǹJ}n2CGۮ ؒ b3<6ܶa@1z=Uuy0W S]ĩ$^-?6ڶe = eX^[g!Pl^sFlx[X孡LO|kRYCQm]UץyDgnlYii9[jsB[[:uI睝kީG8!eFX@qS{Hڸҡ9uyJ2C<9&y5&zHpӐd,6$4 M*hx~2v6П+_:Aד_dH3@ fdeQidoS_r9x L ?0(ֿg\_I=gR jihAXaВB` ]\X6VAM")̀#QfɈO")6Z_jtI y/?xB ej&|,3~fZOC.zV2WK8lXҨ;cS(㜛wtiNX&uv1u?cPKL>S!KnAVEz?Iވ-EO4a}h%YTɌ2MطP֛|V* S!JF'yN$Hװ[K+M`7$|#۞C'@6%45=k58I~B!t9 CYGTuKV劬D4>Zt$G{ӌZ,9xҙB5ES/GjT6'7 IVyc&6ܥPTGMzԡY.C2C6דEmn1orn<}4'4-ӺM#$]7~JyOݝ劃#JU:dgSUT`Q\zw{6-i+ֶq\  V5'VnMOuCr$BI~Y  xҭ*6afc0/Ӕ_T҈YK0չI2qnj=wBD!}/q&{t^jIzcnk/ bEjsiWJ]QI\ "3R{L'|a -'%R w2DS馫ݚvP$i__^ 4,@8."'/9-Ěͺb7ZěN{}~f6ZH2:ugy/`#+[0,5&zpXcU%rԛKxIO_K7}lY灘8L5%n[=Mwi2gjjL056bOXʃV37qsh.lO JPR9 sZn:m}dS$JX&´(y3@!D"ƫ7k_syZO4߄ Kt[fhcDcfAVA@J[c..XͰmꚪȝ9Y}LiJ i[ ?>jMBu8az/ڐNW/rG-Vh:0Yi]}\Y#&`jgxlcۏAvӬ>F-1΄HK.;}~>䤆tPeiWdON=2 *Z'~ j1.lkO;5! 'ͣMD ~8& 4*i=c8S~X <\0b?% MxT)ӏG]e.O!,. CFTQw-#k6?#11-!PrA#7Iy5V8! #&z-/u|_w+s& <fO|ԦM mrBC'FȣcDbDWwr_>J[B֨Sq{ 8i`l!aL|;uO=Hgsjģcp&n(' O_/?<90}PC囇5#% 9ɦ?Tg :t$:Ӿ^E$ = #Nd_(Bx.LGިy &"Ugœ6()˔NM32ϫSnIJ{qdaafԒ)E~ --]#JK4?[pIȒ1s{XDH3 JeVV\\X~(78D\zxe9< *cs?3]}!sdIY}q2?#VWȼ)]!lzˡ.b|]KC"xd'ywoL!K1"KTX4X}zH/"rF*u<b]Eѿ霂{Q'R/#jGL= 2 0y98pQ$2A@^@@vVv +d㏸GN@<`Gx9p9B?)w?J g\?BJIXH\r啰_%+VQ% ia'C!%RAgj@GyD%S d'8ѹ)dcJ~~Ć!wɽuhB_8X<%hlH:럻@?߽ߛ@4q!E|vv +4 pB(Caq y]YCm_Y{אPbsbL8~&Z-=;7'wdw̆vxD{{5elBj}4rEQh1\F֩}о. u0gC}N]e}ӫInR  /S#maovZ|w2Wdy"WȢAO);j7wٔeu\]v޼d e+S~oW9NlX TԹҭ/I"n[)XNg25ϑ,+&>kW^)כ69J6p"7lE5PO>Vf"6ʱikw"FK?8Va *Dahh~!s4PD+߳|,Ē kFAE@\J:ʪ9ضp="f(K4Cd`264<-[l;p>D!jS"Zޣ;=f7_"I; 6)o2sy X̬aUdۤE sSCI#X.4VBuj-Y&_  X # 6_ɦ/IV9: zWC-ukaJ /noU "f╨/:>L44 I"mME7Ӌh8 }M[jALjJu*;_G{rE*30ӯE.Di$x#Q]ˍTh)iL I*$(R~*f\0`gS!-":ޗV_9?jbw)U88,7Vs_@F⻳>Ę(BƭV4 }䧳XWT(S+H(Px55u[tC)itFĿ`8oD`!J9 Y7 ԇyYVQ2> `\ VW'YCf1S(v۩W0M׵ItKV<1(=VDPS ᖇԙQt?NBk)jS(zbLcrK=|JTPIBm) ]9VPZ˳EҤW+2ϗ wgCQ{d*'~0cO|yFӜܭ#o5.4" ǗqK5ھ}LM#ur–9'ξ$(qډWRJ:mp*Ǖ){%b8L%Ren r)8}ν%e;wFE -jD `8LӚwX$=(6LތV 8A>-L,ELJ`H0ΆͲ8Y_\)~쵎R-v0>5-_"11-<}_1vEQs6z뽍 A?"J@,}S`+\ZȐ=mG8(?Zt8IX *$d lIc N/MdM~ ]`'yٸ(R-66 _9ašo B;ae@?EaQ@'q8@ q\|6п8:F0{,x_{qRXyϘ*7vv:8X qT;EY3 H8d4K42k纻_d|LfD9?7h"LSS8{qDg KޝWpjΣp:~G?T=˨.QR,P'񏅬|8=#GHݛH [C|+(=B4*5PS9#ML=&'2 AN<|&a9~^6jd~1s 6]8-`80QrǙPvtlS6hby qx/Bˀ% MXy #9%Otu_y$1{exP};*8!˾G|ӹ/Po3ΑHKR5_O` {oA|$#?|[LeKb#V%tgJ&e 2~V+Qs cFE A$!0j=^!UȢNe7CͲa*_!6зBfk6h4$6hT%L&8l\XYkЭaִF4y2EN*,(NmgyʭYJ )"P3AC\;}0"3|`epzĽ\vGk@ f@|)jX򝢉۾T<@m̯Uq^ǟus k"1;%$m-lmU}HV}=sq{H%S]ͮHΥ$:<شS-zq{T/$5ɿ@ 6 /#S %'ۢs*vTÜ`>aV3kHL-yc8%`KG||g͕t/$MYWza'c'.R+G>| {&NT+Lg;bN@=9DVvTWeKx ..u}W&m< 1_Ԫ~ jȅÈs%DŽ֢nrجϚ9ΟrIPdgHe[n=;%r ;p\ս>% 1Sdfiٖأˋ%Lk%QjG݃E7kY$$$=_uMDGYst_1gzkjXANK[F8ť+0=noW2;-y:^J_6M/7wF=ĩO7+9g3ndsswҫ.]ۚkW[kP[y&kb+7z~EdH"h"Խc3+6,2>^p9f"Ivbgs,-6Wjh_DF[uw!~9)Xj]m]|A31ɿɓ$[> /eu@e7}`|$v\qnTD,Ġovp7ujM hY\J!3͎^,_AbU!;ઇG#؛)'oҬV>9)4ڹK@:8^&8Cz6@ {%rTXD 㝨K 1G[.> f)eϨ]02cCG'vVd:'gY+e霦4 /ƃ p]lըon?'IFNP:*lSGS'n>泯;i yNOVCr< *]X@iT1v8騫Q E MmrڨՐ),_NI^:24Ŷ m芑e R`6gmc3=ﯚX?`УK1|Yl?~Bm巶5 D>x!^<٧x,uSخKHq@Qa xOf2@ D.Ҽ. i@dUy6tkS1%s@>޸f]uCf7m:Ⱥ{HV9fW$*+[GP GpUߐIzpi-}f |Rkxg4\x6U4& ?HM#ke`+߀|Ќ;Yj`%0Zo_fY_8W'Mjn_I ?9,@5|N-܋; tGT1)$/Jb}fIvh$y6<?\#YQcnP.:stSK?jۯ -,MB%'l_~ĭZldn$9ՓpN]={M59Z-u0J OS%P <]WBt?@͈"r~>=Wd&kjjˇjyv8[KQKT"s`KZvɌ@=Ha0~ڵ~cb ܥ=EXNV;G@ULcmcR<8_\GYg;c \b- KiO»8vmϢkK_vk=@x2 r־P޹BNJOka*ؓr(T87?RtMo5IS؎3_:qǠp+'| t[ARs-Aױ8qPdt1fH4*(Pa*܏7smpg45d887"3"$Ds{x?=͞!-rIO82b9WUa'ĦLͣȺ5Q,o 3t gHn;cwF:kǧ|a!Ww=>C+D.ny`BcB./ N p!p!WG Zp?QU۟+ʅ}${t§('^) gRJcrP+bjBǣha~Tno@$x&A1 xQ)@ )GS0uG=?69|a&c)= c ܚ^8do?._yIon-̈X}EԾ+n $)`_ ޖ>ƇΖ^oh[&l> DW>*z1U4  b+1ņF#6(v{^,/1M5oOhsi); /`cn4\oVyf[U&,%uIB#;n.ݣo,ɼh؍[aa1\b͆4" / Bluˤ"Swyj2})gal6HwIڳED$fqJHPXAXh:霻[bH}};Pxi<5+|x-{/e6NSc\δh;h1ۻNHV 4@ƨk^KsW2F'U}PL- C^ijf2#DP##!UF}/JS jDU>Z;[/V+ih5a) % ^g0 {|nJ*Dy{?0Dt f6C Bax` S V~bBKv4D<3do-ʼn$ 0BDh& C l7\)'VXU]:F/f6\*H\l`xU\_QԠ|UȻ -# ׭v^gX49c/f0Q FMK^L1Lem 橾wirH͕1KIܠܩ" 'Y4T%=.&d]L%5JxH90ZgVp1,l< Vo 3MR~=Oa8Uo"YEь4&Dؕ[j1OWLSv={-\UӅ]5|tRR10}7Tz#X|[rYqSұ+k=ZOȶ{AD1%  i(?c٘{,@ _E$.7& GCl'؎2t]@iO'hN -Hgc]>ӶG`WjC߸F,pE/*N\ҤP;.c.VFöG!m6o̜ ( +ZY2rt|͵-4UiJb?L&4M)%*Wþ|tեªj&4鰁*)+Ifwmgz)j lh6:<\fY^vx`U0^iXFwW9RHiӎVƤE;\ s5EVUO.Tk`=Q3(Z9/;k.H( /b_,+c"F/Z/q *A@)A!+ȄW<`y5NТ_JVMHmn@H?Vo3E|l>;TyF!oi/&tB1Z_m`Fq9پRі.jc_ TU"˭rF\oKm36ocd> ƐػWTR~]ߴqT׼w- CP %gdɇBp_Dp|C-NVl7ݓ^%MhG 'gk1d>\@%s$Į\v»;ݚEqHaz;b W+0(m|3"XLYשU铀*'5vDajxd,*xsGOMyuU+%!vўaz|ydc͸4PqOb/&%Hɶ%፧jxuA_*έAPᡇߪZ,Y$-XuxY a0at|Z'#%n_"x~7`k;1wPQ3/z_Ȫ[{}2S?굡Bh=}e] փ "^"bonFR-.Kkw䉮Î]tX_ U+%ZC[y( UAךPMtC-t4HKdu}'khdipBlm>+ۅJoDd3Jz a;pSW1d#+p9R bݴ)*e1TVtˮވ'VBH2#c.EڠvneLkS.c8āk]Lݿz^1+|o1qS=Yd:ln ?va6[$WЅݜsDь:IͲ_v?\jto^\lSPH_LIja`?b-^ۿlye^9~n"zOJq&k'*~eȅP;b7TQf |?FKe G[IeuNI}/DS}>,P`e4ϲP 7K~i)#&-Uε Θ&H]WKӨe;o=Pq {Tn=X6lEXҌ&36,ˑbҩXefntYt/@6Wxżx΁,ʼn8I ٣n# JT[['%mh-2==<[qM[;Ǭ~F'D #FmbM\| $3M8nӟ{b #-0ȭSzN#ݎe+eƏW?ccB;+[jiCUy1PCBH1 J1H.?yƾAt=P.Rfz{#sa׺qpʽpú]&43tAV(F%Q ?vL9L{c]Vr_G{fV<85[l|x[q"+Wɥ/.I V>JkPϢv0H>I b%;O.ĘX8eY6ͼOh~Aw]Eps+y꺶aa@;[JA%%e@:A>o}~3gugs].*^PV[-=_ԂGA==#mJ e`֏8H*4{,UBk!͓e5r{-d1/[[hޜ$'c 82`dԊ,IHO|kbf,\G=@BoȨ}zd80xdte+(61lףuigH:3buϡZ*4d/ Nf.7 .s.ٗ<(8^h#b;I. q#/B~?4"03,=B5P_i(Ɉ1 iu>[B+>VեS "G;cݩlyp-@&5oL}c!5<?xzAs>&JmEQk=4H +^X%G;ax/WGbFOq&NcczdJ[-y$qyQ*J@ֈlE͂OerQv ]Ģ4w)LO]]ۄK+]n{Υ zreϫS_1qQb.GS^/8jrvbm___|3CO" /ngO[*.&vDp)G \"f$ls)t8AṁDpϛ?,m?_o]ౘX2 ,X7Rnsq@*󗥑uЫ΃i~ 7oIA7.l]4.s~ɛ$? | huDZv[>STH?國f]{6m~ߟaVgIk8R 1pfjnyy.چ.u>@IC]KEb;nOyF[c(܁ Kviąɕ[(j!lX 0W<K5Wk܎1|*FtCI Ɣx2HpV ]Z➡(Ksv-87jgc^6}Zn?p;pVϲ\¯{UQTbM 9l'Я2x  (c˕]+wNj]ͽ*L&Q.QEynJl/FJ9V忢W9vAB+XA_9>D42$}`J"|덊9i9+ӅKVw-[^% ~r1:me,woWVKﳌK%+1 Wi~(}P|8ff-cÛ&]Q%8,ߪ bzDj˳l;r夤aFs4,u4$VVr ED,P} D4#b~ŧD^9w/iQS L%5aS^ KۋGpkO ӊ"{z@0{ED9%pw! N++  ";30 TῄJ YBɒx*X } (3t gAA)!1xSTbdY!==T? 0*/ώq d#G<C1H>Z l |m|`akN8^b_yVtG^#;Z?R:)Y0f}j(_Gd}_V Z nAK%ҟg˦n- }ipReθ-u//z9-K_L%tP4;""~N'1X\k|r EϬ!Ea"ԖH>iL}rA_6SGyg3dX:nkvdI2iχ +y)bqD*T~vm4:,Ϳqk6~KȐxW;D>uK>iu;E7Z >lv%tb V4ω!bty*a$.p) BǠγp&?q'b#O7H@|˚&i(zKݖR,ʨT e[ELc3/Җ#([p{') ,0E cR+4ySQ&]k <-TEf^W ֶhWy?^@G Ppp~R̪C(TyQ踭@N?g7 y @C677)tq_I颳$5?h!hbe= 2d`!ݦHG)1Dyٮ+{`iIcL@>pT\sT3A6ţp ɣ% Zo+jAʐcV.氦]8:ZfN@J~ˉaY=W$uMv-gNq~fWtRozD+p ;gcH/\gt hb8E>=CMaj8I L]{OY>˄u(oM^j= n6gTdgh8%"1=,{{21S762'SIb+x1π`߆!߫JZ r`R̗̃Π1h@vUO;\cxHHbW=*j+4ΰC8ƻRKm"!(d{na\~蚧SgA&'?.2Qa-c<͇ϯ.d_foRz9Z84I26냥bO=$2\-F%9fRË&~ە199s\(kĘhS|S}> y$4tjoYo心 +&E{y   CjW  B?ua?]?]?OMIO |_cog 8†hHB:&(Tt/M*|_ ,z4 @[""u ` ne p)3-5SEZ3X$[>J4)w7}@{ PJ+@hใMߨ$Ҁa` B@w &1Pd_ BxuRhEU_n΀tXBbcBw \0H-%*' AE!bHh4Hz;Ld3d6K,raHxTh|rL'g,d?G cps_n^$/>j PE xo{Zw [SꛩꉹiG\%d7g2bߒSҳ~mfqȷ.Y Hk+za1J| }1M𼓲LFYe ev  _A62k}Mi}# ~PpsڵH4{yHCһQmYT?ZnpL Sjxf⊳87dxr~hx3/w\w%Y%gZkyb%t]*LDlGSu:蕚yuJ%8oVla&}'.| \טZZԟ Z0]1 #QLK4BTQȒ$>w!˳{?H'bWh`~ZBJ'm'fCjdoɄBFaKP翦M2o UBPCKY#I'g93ާly@ MF`q"=7biIiĂv{1+Ʈ#ө"ƆBt@9x- g^k/ ?/ƒstsTۿD|P"Ab}˶,P|3 wϕwZg]yt{e7p{6\)wmik}~e D(IK_.\jy8˔-נOYv&p,*8[`kS~ X G17\<@-9 饚E+0kN F {IU^MfǙ0/xlXWxweEEQ~& ! }V WQ !aVB!FKcJ[Ì8]J_4~SL%YR WXўuW.>깵vQ&S2Q%ꗲLB׏=UM*gG`8d)%pKMpD+{o֗ 蟎Q=v0薼c e 扗~@rR pͥJ+O'&F. |,|35 S갌~\sli.!0c*N *;B?'J(0`6 +8c2|JڴiD 9/=]{ OxҾu-7T٧y7jBk+\prYw[! tO^G}-Ru' Yo=&鲯*%+ iYK *eɣƈ,a'|BTy)T,QC/* ƾ<ˣz9hX)݂fּb<$^::6-ppsW[}X Ɉ%*"屩3 ]L-Nie<({A#_ENYKN,$`#L l~Q5k$c^^ "Į/%'#6zBIC0D}5#(HH\ŒShVDr2( m_vEV,JڧHG i"6c}9VGz{^Vkl5cc vylTfv]Ð_w{o$|w0f?騀oӯgR ;u &@$d#'0@H 穑;s] JN&s yy& *;V>1lb*d'gf|l]6կba941{R>Csu .MnU%fH_cd•> ]X(ScJllU 6NF0˒vGkF`1~کC,(U~KߞSvPVxӴ^/{ႉ3g$9fr[*8.Nt*ʥ~dKKngK)"L+x^:e.޽l?ԩ|& TÄNdY3m }]l;85',8_^ՆjiLoLUYKbeɾ5H\,k\:Vy }"w,{^a^U7a;'7vx5DCS` 鯂J3ϲ\X ofKpM+H~[8q0 g%D(zǫ ġ|A}gɮ4@Ԏ"w8Y@P}݃;7<S&e[N?t&YwB2%-rç:˲ IpvG>-9//uH;#fᑵ/cr`5/NhS8CVvxZ7{)ƕeO!TL1<5e2dﴖ'dTOf޹7LȰtxfD4؈d/c"}*%8(oӉ2Uw]vX}ZgӜY8(1'1D_H3(ՁG;'#$={^OB՝LpИ>g1KGI[2-RlM)-kTzLTjLE93oF&aW6q^2nd͍9USP[ɮSNܬwQP\$-h03$+=I,"'ЙuӬĊ:\O=qN*Yȧ g6 ײmLlg =;̆d 'cm32mFբ+/'TDblwi &;kw&fub-1czmhP_k2d1:.(sz Ҽ&!2,3A$_ն7~8}֞ɓ{"$t5`` f+v+f;c7:T]HO"奙ѠI Cf]K2AӍ.!k,kֿٖ|,FЙhRV#[\ׁ]>~ UF;K:lȯ|SLnwleӖ㵍 6?"H,c[ygm=GFhK~RVGoLv+ > Ty^ܕaj /:xdOXqLBB붛ü?7M8Ƿ8VKSS=eţ]!H/c޺_cߒ>%>j =2"2|ru`><߸ɜTmf9#;nJKQ,թtTaJDŽ{˽e&+TU@#;㇩)u vI )Q2ktRRz"ED7#fn]q^ + r_B"7h)@*@?!J:*zaQU@UuEg3TS"n=y|%n$;C}cuf#:4 rx鯃4ka>"#CGmO[VǢ+iV:QdG=*L5 o H}QZ<'eZ5*G8HժOyG`u ^2PlcXRA SŕC9R}5ʖ2Qe50@:`2^}'$u {r7.r]~_RA)@?l tb$+ n /I?]MΈև:*~@,w2Op~w MZ'nl~yPpRN&w`@iBlesy3;3]5?$8/=g)sk~y5|g:C-GIkS1T߳h~xt ^kV޹(K·3KCkшHl-kǕS5otD Wk"՟IPKŋ i3|CcZ-u"OhZ̍[ܟImxˏ+8is* z]9„jOÍks_>I}HVJ 6L*Fո7##nfZrqKS,{Ju2ўEjtV%}By2)߃fߍGl76\jN6HA}:e|g"cpOFy—eEpyL-"_&aΛnPMTɤ\k*v 8q@ebxx) O_Zyț5־ߗ|]/ e>AxzP8g_8I^W}(6*i!CW1%VJPȎI?;`^YV?_W³STMbZh@>j.Sp 愛&1 Vyĵ 9_36 N(n3Qzx"ߤ0"̶EtRjt^yP&Z2'iD|SՓZ sgaGrl.IO1]h6V5 V3nB^;L6@&}40-.Xcm7_I*krA %̌ 8JҞDw):2~YlB5"22T ҃  `M|ߛpa?iAZ{{I@bP$( 3`XPUrK0DAQ"AQQ $MvO MH (\PnN{mpL^n_JqL*zX 0\U@|&*_8P^x&Ttd GIޭ;sʇWQ:02~w0!&XX@T:}^;+!~!v(@ I Fh $I0лYRJ i-:{ǻӅ6 A`X EXP_>$]d.Tu*"c>d`"}EB<j.5;*^r!\DQFzבp/`d!ϳd`Dqos;%YHē1M!E6v_^\565&Lj=S@G֫EQSΧOWoMOjh)d#hc٭:&|ϹvK_DIb*ߩWa 8N؏B{KJù59;i^ :)2ޓUR "֡FRi8 -ȣi=']:Z-[[Xg~"L/%~2Y4.:aqЛ'(ɗP)|S j0C5-Ytղ}&J׋PBQ8+Y\#Nzf! g@LJ("|sv^<1sbQL uP5lTFvll)yf&XtsurZ׹XdB/hyOe?u9T,:a&yeXJ\ڬ+N(GY>`*uWOv'"c34Rbg*-X'; );tb%@3џeVX+|gK~{yS ?%*W,1GW@gTGh=P;cK1rڣz4äC:kQf5֪J8*UE3 ٜ  66P?MĜ BhMFTesʨ?Vx@3r3RC̬JxuEsH\)7VTgID^I~&<e5ia\z?Ж*.)&}YbxD=Q1$x +9?J1ཿF /L﷘W]Fa1ŭ ̇92/ 1`֩mJOL§U6;$3Ji}@S0Z]+7\n?>/l"xVYd^KtiӕLp Ly?8ejR!c!gyth(BT#(!ץ7.۩@v?19{ X. hvfq~95&3T!(^`ԟ;{Q 6 [r}K*Y6]˷ŗc)tCdUI8ߤ:CuFksx-[/³ ̇sVD4Mr2 ?V|B3ujMQJB؄ɋ$ΈmgX7Pb+L]R%PѤ4(le5"DwKl)4cSn:IRhQF?C@:A/l}Cwp5k=.<鹏矔1\6F<h=d#&׉\z4!3'2B\4nίTգ6wi|F*X- j B{4+ T`K*)6#b" #Y¬+@ld¯>;zvU/ϯb-v&yX#.db d x]:6K C K85pE>uTcmMOv}}o]6s ]4h&9G(qz^4Cz?i=PF}=ɿ)?ǧy+A}޵? ,Y1wIUd$PR0 [Ϡ@.qJy%< wX|5 t霸SOMH'.jX)L#mO]g#>'qvcϮ0 {"O[j)GF^H{j]kG6ɥ"LB/ vb_Pf}e5M3Ơ hAr4V$u6Z~9kq- o剌T}3֏2$DgE/Y/CB~Hv; ɯ1ʈ(<,IYwX[a#?Oi8k[SzCH\Lqt<&:e?(rʡPprG_ٯx@=ǔ믘Pjcj,{>(3C~Ы;f,H#@fKQ8 & Dwa@lȽ0d!C#0P^}l ,y|- 'f{X D9 #1R C';Ǫx"& }lUݻy%a>97R9`DD#.Bzޑ5ElȐ!Tr|{NGo9ޓBݵIoCzXhOA@N Dlx|GhQrpPk//Z6.߱K$D K#G51$w!qّ*/$~4xقe`LMx>O3'9oEh땯<`n/3Z>L/oSH="\[/3ī{tmzT~cǪ~,^󼥾 -~v[JđB*@fm~\MFU$LX5w,ƏO8j]8RmۡT, RyfK9uIECa5>v5{8srmp]J=ئlX<~7D/ / hN}e(*;wm>}l¥`=>[籨[yq@=hFb"U,o#$UW\EpvoZ0}C )E'Q~\oU yzvx m=Cy:%ߘ_?Zo2Pdm40ƐԖ]R5i}#/[w| A_{x`Qjq^VOl{f/<'SHc<'&gporMe6`C)77?OO?Õ1Pr巵<\b\:̾%A`]*ى^1΄g G]+ODjmA:X}s7nި= MFmc/ {K0:΍E[āzIJAed_4hp2Ym׼YpRQ#~7ôS~Y5IA+d4bLn]mӮo|aCdôHu&<_I"(OAS1_0gYD0Wۧt.e홆Y.g>i-E`5L=һ/@u_;W0&{Uu6&QƠB|88`x8ycpS2IǘWd i .Sf/9 TIBEW=XtTao4yCo>^S`x㱦KCͶWsq!B4'Cto#_,݁ ,p+deFw t]Ż"ܝgJ8o/o'%N?J^E/*֜+iYSSR!У*>.$O-}Jk,tT<Ǩ4z6RB8ط;_) 9{i0o,&3J9+1v3FBE!k:e6J"iW]*f0GR 7WQ<μyƤ Lo?va Ŝ!M,Ɍ9r]?0+NxF=juj]Ю}(˄NjjFל~XiVbsY'ztO٩ I摲h яLr~`05>b<"xp?ȹ 7v $ǭp?࿃ (1b!d^ X AVaiO]HDP G2>,=;0p3Dlc! UH[w ,hC+Mvg*!*)TRVܣrp(:e{hMsM˹ݞMogZx#BQr.fK&sbC QY .̳h4#bM?7tΧΞ_G}sik4"57n³T X-.s4guɗQԙ Qq6l@M%tj{eՀwIƋ :ѝVƣDB#umd9*17;w`$CmYk}F,So^Ҭni<}Ť>UaPcX]=]KS|Cn/ UPzD1mSSVm P3i4{z#nr\ug+MS>A-^'5&T}X..wN(șw٘DpcoڵRK CťShpw )^KX"Ŋkqmzz7r$s?915,fJI'jiQ*jqR?x!W jQ@ ]MAzUO7!ͭ -к~#yAs";f:} Rm5 j8YUP+"+m#BD䏿 JFȘSc\%6p&m'WҍR P8ٿ 7Q8E)Nj;vȘ'W\\A\QhIV=n}X0 ZenrĖ_@ ›MSYtӍ==/ʃCn$LD_Q("r9Xs9(@?*p!UfM;H`y!$4% v}Yb5 U܈$F&Ek9UꑊF8/y4z{~'xCM)fk<m SOnz?1F`)' jێpkCkQ˫^?[5z[hCxTds~yrQƮS[.tSS-r7_ž+3k G?(SPcP)VCߧ^vEoDk .b*a@zmYMF@aw1H$h 3p״ @;Qv`o&{߸jtwŶ7~L7xؑZT+-&O*5}0gǶT)AI<ʑ_Qn7swl^mJ:x8~oKCG!o/h"zڇd6FR2*eO} 9N⻋fʵoʏfEWժ7Y+KƤWssoЧ0Ie btyfaC̒Yt g=w3],0W4=Ca6U7,X :|!șl׻tϩpyycTjF!ߖ) N; .v\0o Hr?G2P>kxy㔀Gu?{OWg/v1_vߴ,˿soW,'9ܙH ( mȤۣꥐ#u:w nX X5k͔aی9P.5|p-d=&>_00'y<gX$` FϞ sa.(o\oٱ+%Ttmq7ڊDhSmm |?>I^Ux_KkgA;S2r!NM!5#O\"W $#9?t7nȦsQE`9c"*v}Njh`xԹ.JYT{;#@f̈|LHy?3;y[%ju( ,婽&x'%,FOCot#[_S{O #BT`~. 菀=҄/,K]Sx p@x`\v?uȈ58;@x g0[`0lO0u(S_uy#o)@PLyP!sY:I~UFvկM-Tj+Y͏t&<ޝsvP=rR%ᅗS= z.(W mop3@# d*H)}WNtXqFU)Ǟϛz(zFʠ ';OM? %=oôc{pv6ATl:$rp͆Oc0yЊc _o:):qlC%F{3KIŝ{ GE]}H")34g})z}߬#4ds]N[5` onfX(>USoTiؕs@G=VD&MrZ+h߽{"*rZwTP/ i*F43"¡F2XfpLLta!x~_H,xG2Pޠ h3?BiH w+uj8o%zb+7쬺j_IPBcы)~t3Q90PB4٤A vZQ5ŧ=_Ɩ56/ګǑj>p*,IC-O{yKRh"m4ݽ:Yef7 e=Z38kMkT)H_B4rrq9;˦*(L~zw~/Rn 'CH͢\c͒:1}eh`b =yq]ĺDFvG;$Xֳ\Apz( 7/`M9U Wm[ɖ\y} gQ֮OSIQ1gɁ[V/uTWehnEa&4@nqKrfs/o@ 4O kN[.of(_\~-d'k83 aErpc“%SϧHH&:&Z?2a $:(vo}?-YVDN Ъ4l˶s %/yNg0$Ac[L-X- ~Ks%)#͕UZcoas^(HlekI r!ahBŜB Zڎp$`jXbWG}xNwж.$A8l_4YSݶsQJ^} ־u5puX,J1LE& g6w2DZ̹JoA=V".ejؽ$_l*R ؒaj䩱ã6f~'Tg7?Fo}r:\ M,Lld]uߙB!O lV|iFE-+-{ٝX-ʞO^x^hM a"?ֽƇoV?!kGb;ű2Qϸ0"cpXF:0H3k%T[} --0*ϡ00TY\a±qR>Y7vgx8%krDGlz?emB&qm[\y3M FaW4噖:@^o- ]JtJvCa˅o>s9[*/MDE;Y6<9G=#Fe-'nTdF'f_< w5/8I](8 7@SEb%Cx8  T`_]x I97ҁ >/qp!TXy0aˤNR0lyx]af܄Ĕ俄 /10q/Я`'р/v|Ń~}.p [X7vA2 #v=N%y%Ge;G>M̲qؽ NSMU'{sXHѧB;6Rzi/!K:Eb`κyIU}~ldREk@Z ޴ FE.xlIT1]6K]P-j XouR% [\Y/"\f`P{+`hcqQvf[nlFĘMґtS*2r&kKX ~F%fND+LḿB^z,x!zG]ͷoپn6DEfbL _Q*5\W+6!ŕ߽[ё7~KBt`)sJ;W5vUiLO`p NWDÂN]Uz6'H!oIu*_Npijz׋Ja*pFA6~\U_ -Q vDʓiEo)JN*j` 3H]_~lhDho7tL~t21ew7L+g6~)LCWP,˒^@>[M(LJu? !2Mf:բhE| A.g! )82R8yW>yV*88EW/f/$(e*ݞ9K ƥ4e'Kx\)bq8%@CVdjy_x} yR\q{Zf鎎g0CF|*0q1xK#rNw=Ł~zhw^G< 8|6#' :;|eakVk0:t7InL!)7!k"݆:8# w'-q|rsD͈TxZ4)UrGl{yj،0gͮkˎl sBRQRM3E_eR"R:iʥA LtgiP'33e'F%3oSygp}E菢 BvwG専^bx%HgŖ-1&.HgN=Nh/̒uF'$-?ht|~?;\~/pppA]O<>277?77vx˚GmN'k` ^P<OiKnpݍd;J\n7I7 }XŸߧ1PfJ:-7ލi7YFK"&1dBЂK\3_0.7U噊 &Fmjm"ֱ @3?w=< Gqkg|ܚWiqSha8t %]UTln^m&3 .q6Wu9(Uvz-ͷ Sg&nL(\$TMn ts3_7:ܸ5R\eZ6V1vv<;Z.,^_wM}:ht։ .] tBXo*+~JM{Q/>a^Jd])lL|>K:n4 `%͠' TWLK ԞN EM]FaH@dKF: $!nƟW v@SNF53l8yb=s/,Yz f@׷rLL.m:UGX<,Mt..P ^9Տ:B#:>1pT1YKBeD OI,EU.0 z~2;x@&qr^-[D";jEk} @RKL|^w_ q8R2T [M(D5?ajW i'H}+\{-T[JlsS݃dH(iܬ5- 2jQv: d՛>{@t$o8=l7c‹_b4ݷZJ ^lfkBp# =*ǕzӑXʦQŷ=˛F9[Ui߻Šm|(E6 5w9BwuN2UEYWZԅX}Fbn29 BD ?]cBN:nrڹQ 6 KڙHu,"% $&z@sJf4}}CxbCϲӫG[v7rr44znF˜ovf1VB*Infp~tٛe$jhv".}DMk!Q(u{CV 7@nT| a)d0?ss!ss%#>8p`yɼ>.>*^^.~w^ \l F n/L1%YsDu# 07ِaj( -/U~3?U!R9x 3">?5mX\_y |l$o )[Լ`>^>? .^.?l@  #)~~aJDU9Ex. F@煝b3Ce~7 3\ 4,EhngOJ$ť}qG,&heıbu;jt}tB=A'#ÔZr?o`LART: w!94K5~HX/ MbO@I|;XVrZ<ʐj3as0m\_1ov>] .J*/tT u7R)sqE"+:v\VnW^}ɅO(-_n~jAYv΂vM?0|B`K: QM ^HFƂʢKch5 ^](dsNtI3̽%pÕV}T˥ϭ: :YS &lX z݊qf*?6|,j^OߕVՒjX`nPK>[Ypҁ7b&h9O7[3T{IԲ6{}[+\C5KD.luwЧď0tZ]ըɡv?Jn,YքN+cc.iiOh"|,>y/:7\tǒ`}m iۗFſkx!8QcWy~;Ty+>Ğ9]^D h/8~#7uznn~D]-*lsunu}YePw)#lyw~~LS,c0>S'UՕ}ZՆ/R0qvׇ\TYl\Gw-^v r3g,ZQn@%7{5߷ >Dr=WX ˷#&Ξt5Տ l_2 q;Nv,DJ~!@beH \4@MN/~fķ_f}z/;y@!;ER#(bhCUHXC~I2G+_Ϝ\Y1L Dh'pby3RCt)BD%l .thL%h!yz%1'ڄq"߻J?5lA(^6ۍW;H5j 7a4KmϜAWAIx(_L "::]})_؊y.ɕK[7'k͔#8DO.پw{~וJ|0$z}ܹ}̈́0q4OKXw,0V '(g~m〦1oU)V׬Z>izlC'Qd-SV=\_'y&#w5tՓFOrrY)1GBأv?M&Spf&"nf磀y] GJH4,|4ݔ(NNHt>iiԵ/.u[4~:- ܧ"G N @rYϭ (r&ag;RŏEm[F5ZZˎ_iWIxH&.d3b?t~$wcy](x>UV2X1f7*s8N)KlkPphu$ˀQ9p1 nz+ wGmnP`2K |,\> 5,cr"Xib' ۙ ]7 R9OA#QL~ Qki,l$Jvu =79A{֚c=+鴾EMpD˖&@5Rx_6Sע_cw.w;Vv&'=|yGwwI2%>` W~'jk3y$:5lޝ7;kY):L:Ku:/':kDZi +ȟW+}ڕDt 5m_Xy1)R*yUD[cۥ 2$#L9]ѺWͱ/3f7ů:S!EY;ND;E|(^Y2Εw%Yudh@8M-ҟ`HI4[Y ɂS{d6%uHwVBf/Yhl,2G! ,Y|MVwe>bqЍdg,tÛ-(XW%ӯѼl82sԬ<:sOp(Zfy/Ɛ-`cK`?F g/VW;Z1ؓ8'5(RZ`t ܚDOu_bM\Bvx Q7buj1.0?4(Tr&˟"vĸ{4%Qqg3‚_?;@xP fmښ>#p"y pp?b0dߴ@l%AF4X7&t4! ;$aM)FUX ,]l r(m*ik[Uf5#}qd]sE6~CpߵGܣ>[Ch9Cww֚ijPWow<ݵl+ݶօ>[G|]dH]~%u1hxAZ#EeSI9og pY5r;>N҅,K~nt”4т47A f]1YgNF>>.O=yK!-L0 yT׵?ǥVwoIˤKR'}Xʫ+YQ\-*.sWfoMyZk_‡Eհ @b'^.rTtˌlSPt 7a $ E¿*ezԇI5dBYmϭHOB쌚&Vrx Lp S8rc=͌6NDу(`bϑ\>ҠuXbp>|3xޔP`z$c c[e2GΗg;66Tģ7<r ip%#+f[jxE׻~58F +6~Re#݀~MyPXFX *P?Hݝ귩cq!j`4ަ JpiZU{XsOji_Gp3v^ϫ} /Tb$*ЭwB#84IXwFQQ z>O%HIxgWG@Sey )gA&q\@:Is,9o$1!ye} ~ǎz^~UQ[G%e| ͩ\MAي!BBG8TMB*Sc$kPR>wύk O 4M݊b\5AE}0fQٙ]գ?';/hcOST㖠2(z qyg|mчWrțy"Qe{ 넩`eԠY ʧJ|Aqi6$ O/jd`c*~ ]eZ~N3x'n|$Ԑ^AjFpkA'W%zu qDPW5I;tii4H^薧,-|0$8#sVk"xx]lI/zaSSѾw YinDe::+ӼEh}[[K(&l>v Y:wbu%j7bI$׿ OdeeʿU^n1"!q-Y~o?((&/K l ]@ǍIHhaa5o'k^~9O`y+˜Hk)^XhVcL"X֕Q_x ۘvfǏo*C?nޱE"ڣ!RPӈTXpwN33n_Lz>nsg߿F;TrIF r^o?lm 8G_; tÕgzvy,P6q*V"cKGOy!V¦a׌j RjMFf tQ4cxgo}ί$>S-{i dR)Y ޳x(U*UD^EU0pVj~Du8v}X>KD=aIR dk^xka.Q Q:©(uL:_Ân͘o(ɑ?J~8@Р \N:Q̲QQ~tWPoKG03MrJZYE/gU,@J 'yLKQ,iZ[ Iz ,X20EQ)5żej\ii匹ZkLA~hXP{jk 骟!18)Jp!XTzZ ; WVc;մgUWHVp&: }6^.IorIƟ c1L'nQVJ}UI$*s]IXSuEΪX-̩*Q\,[M%x>F^"+{"Nٯ n}=C:98" jqBL,̿RT29_ 4`*`u kvI܋t?J!s.K(U"3Yԇ6˂~wQpc*NZر[3Q^QM`>!mZ5Xo 孙=lÎo3vd B/]LD)@S<KY8/j֬'ގ8yiDҙNVHZK˂&8${ f}G'.Ŗ4iPZԚncggO@>lK0x &- gkxBv`(gq[`)m'tL[gv 0vn\->!?T9Qy6Q&9z(S33{ž29eEt~\=跢± $mq> B՚@|,,}r္D0)&h=/s/%͗Uy+x 1Ğ/.2z+_^sT;x*x-QB,{n 6t"CQЮ^ȼf2QA3$8sr'azaRnXv$$CZ%aAEPn~^33̙=\{+ _UPZz^v,Ώ@8qaba,BB/p| JFr&oQ:k ^{R\LK;c[}P$߲5,O(J?uݚڳIС@T́NoKx^5+땂q}4*_e(OZ"#ĹŇ/7 /29J̋:KKJb)SJ_U"6^9 R~cJ=wpAS)BS&^Pne:x꧱܇6a2ꛫA/#̣wh=1rm}QbReTAЯ$REN>2/ bG^8̖C\f*^X{)i3>z?IP pZ|ík<I<.T07̆P ԋL~I|&`*\$FwP@}cEV=Gh)_uMؙ@J`xv1$AK&V7,$1*=/3wzA\Ip{Dlj6mX!;mUWRcYBnYtnXcN_kMR ߯}}%~-#8/aǗ ND52Uqso ʈL| ey7'YZ RE)g5-{Dz/s)(Y>~XJƐd :Ô[jJ_F;c"'!kfLddDN~DyZ=_H@e%,tI]$s5w͔T*J0$JmI h&(J>(0(3߈khMWXW0NwhַxkO46i3ma1>Q!N_ӌJ"D ʏW0|;x!C+˃n(߃_5lV ,6T! /jr ]R_T<753x+i_ ;?4.z taNmY9,]?;u*WnIS`ZTƎ.HT4ƙIo) 񫹸b,g:[[JV9ee W{ aEdM7_g=*S kjDeΙ/)jJ_q0Lk0>J"0uR׾\jlG0*qއ\%n@< Bvڨ\XV ~*iƅH]`!Qʚ>§ibZ_r=zh8;lLD^I#1׼"\M( ^l^#ur8 4pɉ.gQCr^gR/?'(l {z`C'Mhl.uԅXGU0@*Tic^EYL2E+z MJvziD-U\#F8%w0(l['nyDLXpYcFUCi76/MN\na$V=q>!vwg6ͮҮ =++&лd)-IwxcY g'@}M3DafiD9-TOpdXQ ^Mn8ֻiQx9iY煮 83{D(R߇U$c4=dwQ+CX3ʹ& N_uM򢿼NWvm:V @?'E24 aYhnM/b6Hm'#6A1]CO}_$XZ̏uږKv>顬]9qS[x]QGX2 /v#+Hy#׷o,ut|'Uxkߓޡb1|ظbY,7^:pr@.n\y!&-ڣ2^}]ۂTUǵB9z#QzUF}YNJkhΓJLׇt jK|\ O^ !heIZjwYod<KY(ץ?'L™w43n5]~gFC]ֆueg񏾧=iݞP;V2Rkh - WO}kPNqDTU踢&+lf%vUfsܚaUMɳ<4 Gy ;vwѯQ5*!4 BX|#l"lj DKt0&? ^R>bLi]x4Iyz^T6!uW%^kwIƁԏ(i{WMPLm^XT)N% ck+%p@أwW&*=8~T7gQh+BW~ Uoi{hTjܞQ2cdby ?(z{Y\)9bad%HgAMm<[O~0=ԅKqzu054|A=!%(ﻢwV'q[p I~lpy@~>OĀ[R9l\_ [9Fg)Abk&+~OGf{УFxg*V'RbGVƍV3W\%5jg5J=S{׬7S|uK.ϗ%vZ<$`hh!RaQc@PY$!4:.h%E#Wdg ӈ@Dz@B?i"D,yuM3  _רeGS'KJǜ;Rl^gS펛&瀡sYmϖ+x!O& Lj#VU8:FQLw*˿в@V6(V*saõIm]m.K^/j\¾u{UDR}Wk6rO4 W!:YN%B^q}IFF ZǕg=\:ʬh$3wdD 3/e0|mc! t\[;bϯPڟZBt2~*~vzt)U.IUh'!u9YP.wn~뎘 k~YĪɜ}+BKQq m5M`h Ufya{ĒKТ*7 P@BMRЌ~ĔdJ6%fK7}g¿JL\<'}KƼ.#vv1O95F紩?GTloǛՇ))\q*9k45=CSB(NGX t0G'KOkv 4>bg+GDISƮYK4Ts]~cI3PVS}XĠ8ϣ9hb $>++~ukރn84G PǎJ~8]a{EFw^℻c d4oPw#Oy;t-+'q1H4$H /cڸPUY(YDyQTKN1Lx 8+ 2/zi&H[@؈:TUg.vE p c*݂LUDם"EJ~1Z&ih8ش2S-{˷5N\߮GX~=g6*}bPlGm_)E25"p[OYBKV`UV94ᐴ0TLwCx4-)Ŗ*cQ(p U0s{eGjT7G|EIɪB %MN' /C:%5˩ps8 YwƋ]'B-($NG'G6W[pݠ-2[0 uy=CZ_kJdn d1:,AaR(;EYog ѽYTO51Nw !鄘D2ZmfTÔy-ۨևFԟ1&K9ň_ яJvNa8U8Hh ݾ0>#6| ~pSak;~a)O[7ͷmd =l'U hMcwTQ[~/4ܥ?B+ ݂A"xT/l]{p n2*o'=go[΅wr'8WyZsCfpxs;dhCU8\>xCZPqɍ_"ES !T'蓺s7_j[}#MA2] < p?f~Iu.@hyL+Y Y swAE "ڇ Kk[UۯA$k:;jWY٧( E&I%%S!Zн_nXdbdh3.ԘbRiR 9TJ<{,.9ҥƥ\.sv|nfm^ 9F/a f' x6*!clpI"+GC V-X,8=h?&Y>-{?,f{{ Qk9Vձ ,KH1Z VҐ'g~ckjqnX4g#Oz$H;vhɼS?&m.\*bh9! |x<쩢26bύ!XjK_>=Pf;Q4yݢP ԟvQ"&ZQ)nD}&.a=:4#SpV/mƈ#ly8CrB;$Vi)ƚU~=xl_!w5;Mn߈F &uIDh6Y6+vY~9v´o%莉Y=u\lvOΚ4Ehi?TiXҞ~xy&zMx]}:BFqPVT-J#kUg)/,bvV547eTc}pYօA3^#@e*{ ߈U¬$,/':G֬mO-C|hJ)`EwƠ,Avr5r]h8uu^GZJV&Q՘ӹjuϋnncE5==6YPnZcTa:fo D9CcLCe-\@|!0!*0ǏTu@CA|bDQ6pl7b19/? R)^ @yi@\b޸G8uV/qRC3*RK^=7/ 3jWc Lh:hP}2_.{##GA{s1@)`4.~d}RZ 3HMyy4=Z8rG36}A>TC /rBZ6b@ȿ<Z8 ػ27{W؀fy'bsCr9,˛_mb*Uۯngh  xn~75lKx| IL#jٰ8WhIij.XۍO-oa ݄09isY qQ}9;;ZQ?(p5(W3^ N[Q6촒LEka FoZ6j-w]<&Pd%MhKSouM#ew .yW,m``c"BXtٜ"eL-w}\ 'O0,O/z>ycpi e]^xWvzíہ5fSơbA Fт{;';Fozc[=^[1SrDڋL*kZ>!;v{(jyA5yMn{fZڂ#<3Vw<WS-Lb~-tc[HZ)|4Lm/+IʧDvd3c ].cs18o/i& VcGoF4 `ผ] w«!5#]t>([uW̴=?Uf|b#+cT1GnY] &>}5q,*{ֆN䘏7W]))+qYÊD`?c UkhVJRmzQ!AӉm7~ ōP!a≱Ѱ.!r2؀ețoPS7Jێ wF<&~'n)mXnNӠ). nyt Q7or\FnfGxc:2]0є=y&ΰ+K+4F=E)SڷWutDm$Ri؝c`H|JiGCĆJr=*=sZ#Fdr˶H0abȳ9@RǶՔ35[v܃zGM'ޥMCZF#?-~=rk(c_jF<_V%@ ,bfA6T.􁜚L^D렃l! C+kŘ9Lpgi&qojOoZ4Փ.c~y*C 3Ym=GP*%E5vfR񧸮|؟/q%TuT=IгF2|@BTJo~ӂe#ҽ)p1=ZC|e .@(.HX fX*ܕ!?Ria;7t7t1=u YI51rr+XDz7cHm2|l^ ja@ g%O 77 0"¿!RFHʃ(Gz !]+(  "^C !r >pC@ԣ PĠ[BaC@(O@@q (}ÅԳ@?,H7gwmrD8P1 Eb;N4]iY:1fۣ 20vGEX9w-ϥUW=_3=I)K_yY2^Q1'':bYP pI8ò-n=IDSspm2yޒ2v+ "Saߋk:)ɴ&{9kfv}ǿ5?9t aR{u.jl{~qyŏ׳]=,F9h{uΒT4M'?362J اN( Z݁ϊCD\zF;|z#\\(Ԫb|Pz#zǤ5rw I!!ĒgY2^i\XՅ2f3C@gpv>D]VJL]vЉ ؘ\o;>l*Ȩ֏ hnUqU{/NJQ&D)Ilz6 gn6)FAڬo2ς!G,8? ;O BHvގ CBl4`CP2Z ,lqϚYeS%ED^̉ a7P7(jgT9w!7al9CDTѽ7PC f~@Ղڙz tAH=\!}$<_Wx:35%7 cuY(?A ꧐#0Ea$O\S*@le0n#*oQzBq灏?gWB owތ'1M{S_kҫV^u:KETim~zTaϝWu^ɺjwl}{z}MRXXfq5JA| yA6M/Gqfa. Ն*QƼ$1K'EG }ֆQS9yvH͉Lf@w7/޲3/}V{AU`v}$NƶTao";۾L)gCj`P|,4!"2[i?W;abq-+$g>|<'ØgQ9U,I h~9\l|D?'r{SM'i qL |CL˴*wѸ=JgFĪ^LCO α4YrNryh~3,$|v|$JA 8]P! V> MɌ9~u$$j Hf/1[of4a>N 4-$ToU/wɔC[^nN,TYHfiB%5lv\*y;+ \ %K~m\t3`93^Gho˓ζﻶq.& T:CkJke)ZI3T ;-1?wp.z[v `9&zk[Lԭǿ 0 (+kdӉ+4꽠%aX;'l~/1%ںw$'XXM;䠎JԳч pBNF_н=խ^,ܻtJ2IXSk.MY{4OΧخ(`4YkwTrz>Oi̲lmSC^OfI$᜷)*9#=:p~ƐW5D޹i}J%Ί#vt6O#" u'wՂ Dѹ@t"c%kb6\[x5U !jzB/ʽUz,i$9I!qv֣rFs`yxIpÕ}.J 3Tf()$މ"ty"e*3wU;l0<~P@  hs=o.rMyyϑ.)" qAy \{~0? |\_x Lj_8??!DOk@?7@{Yz $,@\g S Y M9YIR|~TK'+ZEHI'E]x؈w5+gN`aU@z eQU$B&ϔ*HF/_rLh{fIrld? &n^?KQņ["/L=Y͚ӳϜ#6yoя}=8C, J>;;=?iǷ58˧/;l(nm$4&nFU|NJ-l`@6ίUx: # Qt3,j_N 9}]ps8v~9fWE+ɭB4 ۮقJSD*Č"yeo'rG\*bԇ8=xqs|/\+9@ 9xd-w/b8V`^2JQ t᧍le5e"lұ5 K&̶:X&ْԋ1Н;@UΓݮ[z=kaM&sq;saQ-mCv;W{BPgsTja, [( mj>3<йy&"ݎ],I㗇9d u׹ +!(TiLqRp\6Q {{}7~GnqPo}Z^8,٭ 20F{OW$Y3HD$,Ja:oZ:=,;j=9>^CpyfI|'?7k/=­O.v YZ0]㵝or|*]t6迈 7PYOK( CRlr&|28] 3@y*noZJL9Dh 3ft@cza݃t&ub| 6V)Zgog!"ˆpw쎷V}"YY-e`;-, 9Scv$od" 4~"py e>|am*/tÈ"?9lȡu@1v>}{Ʉa mq,^-tYWm|"Sr%Q8w638 M)݁*{8{”_H-G(I,YΏP)WDSz7}Y9~^'`LH$]Jݖcs?* a*sѪA |2AM|m V4u\1z~ B_?`^?=5zSPmJ@x4aDZ^Y1ʈ'+ķXj;+GvoK :$ |YeRH]?Jwcc.C^JY>2-ݮLSSǗ052U'̅ 3l0HEǠf ܒˠv J ro"{F8X>6Yc7z'*mYddhH&fW|=fU##/ ĢSےxW:F\X.Ulxius&E^2*oi^[,MzRag ^tfGZGwa va m׶?@'$ O_'!FB`H[ L{@i <<\1p3!B(L A`N@{a>.^"C -Χ@B"/BbEDdl Q 3^_1A<`K1ep?Դxh2f0 62,GQVѸG0蟳H>ĨwHҐCgQP#{Fs qbUiS!n\Qu@RDPA "8dD@AϞq&$B&€@@\}'  C=A%B4"M 'RۢRw76|h""2HQ 'vN4CHI%X,Y*F?2Ƞ=@XG(|g=-{~u/wH5%\Cg<-M [Fŵm@Npwww[N54$97޽?5vWլ51ٺڞYUq*nRCq:jlt]d2I(EkFNv?"GljݙlXB#Al^OXpč;3a] 14Qӹ앝(I]j .&%չta/&'RÊX؍Te FҐ^Av묞 vm[)fXn]s^G[E 3A8# sLN=Ҭ)\$o_!%_ d>7)\ U7\Bv1(vWR 3m5WqEʑ$WF2eH7H*{7P{VC>4gna2BJQ\1wcnJ-lH}Onqzu> `B02>wzdV]Z8mZ /thvJ@2uQ.ZsXO%3~f&NVOYS7sKCaouy{d|I-*>V ]*["68 'WGq^a`7;䎄4ļv lU*?Z`+, B]Yǫ)݄EC}@)13#[I)5v1Ʋe >vT2:KQǁUda#zvUHq)hgI Kǜ GYoX[P.27Gz:~/Sth%.딹bkyvI |&*7Rm?C昅=Vlbֳ'짬ah$TD:T%\83nƲI}~Gu*xaQ ^[#SGB̞EhR^hKIχ " 2 %LocAQ4-Z>7}I0KZr~謟E?O7jH>ɏ!Rl鐙Ŀk=$c+l[R@;w7zip0f-2到1_ XgO$>͛5 [T "?зEkv^wY:/9^z>;$bK_nrɭ&]CX۪Xm` O Z{_W]r12?hL _~:ex4F=qӀ'mQ}nPOwTo Y/{o,,+Q2lkd1Y>t5[_a6Uto0=yr.lU&soA; 泧:y#qqJ0^X,yKtf "`׹Gs)~NS1l+>hy_arG[%鹗e5\١?hM%D(x QmgYn$h޳1[6SܪMjk'7CGp>E?[A/i9-,ZxPvnƌеB,7AsL_ъ?^kvm210zf FXt@G`ZF=*lh|wSڹƧ4/徹q/FW'^(UϲK,*$?ژc(M6_UW}T)}} Z4"k#NZ[q$;vQhM׶rf坹'6A]t0R =koK& Q@*BXI`WF$?jC5feUl # \\ZzX.#-9%|0QN>X~W^<. 1}nލbU>pXY99pB!7^pK/8%%؅'!X8L,l$\X ('W bPn6ο6ɂseZ?`\ *$fUrtƉB= ?JX9{1@kx Na:?D\ҿ0\\ȄBN{WSz!pl 299T\ +pLVP;OPyU[|YnUUχoD )< |$Nmei[?yn\5`Iϸ~L@0ĺ+{o"#а!sPxL9ƛBE^e5M {n1VX(_LMҢ;[Ĝ w u Mm:~I(ӻQdB\C^&]2Z@-*g+zR"p==:=,̘8,P"tb]5YxLk$lok|^K*( ^Q A '!%|z'׸?щN4/ǵDG5%UPUrԷ8 JY܂1׃IHP'XL%26˳zxSRͼiy5WKqiπɨ^Yh/:n{.[Ǝ/|ZFtɐhX9w|sJsǃN6iC󥱬VK3@AߠtWs~*k3N5^qⲬ`y1fE&$]Ϗb.< I-#Lwδ3NzA(VU;tׂ]_4 /Hp8`#p =:r96u-k-v<q: U1T*Ns"Wo;^B'z,(ɫm9cYG8;1~l|P`[ yڑ@]{wFsݡFmxsEi6 i~=K W7@Ud}["?S|?\?aW@5W,ِіi'a xDc8㞏2Rh8zv' +cY9abpXFwH;_w7do_$   "5VivB|rtP7ԫ9UD)_.=qBKH͓ )lѿh&@lHE* 6^PSᠩ5!YݿnsEb"m@UtӃ?v.&ȫEϷ_g@$B9C~TV|@*EhCeY"=b6[k<_%ghYQ:ޏ._R< SQR֧ BxT(?' ~4u.5'jnȐ>e;b/!,P-D h|,[8'DV¡Š-TbzeA<NB;x GZb2VYw.;-XTV`^G_ajM{PW0^%A[ (*i=La:5ݐm̀UFEWC 궵"BIPXXja {B^-WŦW㶒rw>PDdIK`*E0c>8+WuR@88:ӈni“/Zh%K"G:9Naݦn'-bՊRϿ VI4keAK ઉR f62,DZ1sEk"dah7w8d _`A,Y= ӞLҥ/$ߴ-V9ʱ#:8& u.Ԣj>9S@%w}vŭ:sBoJ'ᄀ}5/_?taCΕ-96T.~^9b(Nfw{RɊKy(OSWpRSc;FG N4isvbõ#wuΙ1 wv&U4Q])1+jaQ̀X_2ͼ@oG.[⏙=D+ǻBL )7ʂ3ݠCXh.?Jt>шzZ+~TCfJOy] (b@[-sV%6ɭ2K*An*UmP?F$`p L[#z:OBFo4r$zAƃ7y}Wfl qbR0/)>Be/u}T?ZGU}-FR0Ҥ׮,G1uq(shV%~nh$_jWRwp_î;WA+^Ѥ?P,{&% o~Oy_W@QNC!x?[zBF )sl"X>'kۈcGcA푮CW{ց,z$t vyH4)q]xEALFf`49UoCfHGzD;:>O;x&U J8Lrg r=Y?2%hi N y=V1:k$eqgkUo457^ߨ[g\q@6mҿ׻^W `8>}& *-n^~5RCa=y~zT7m7\z,u4w>j}P?ty]Hi4xoy VKphp|Ghqˋ_K! Baw{]?xw~#nj-U.k'nLbVY'7܎4w.j{o4Yk:~nj@W_1WcEjǯ4:0ȹwM* 4ѳ)w{sGh{C m$qX%J?ȁ $*N  9,9B04u\:!(:_D v*6Ј")qU0m…|F(\2'cdl+ZݼvVFCF3Ő,@gչyUfoW_Vtt=O2_@󫚡*ƨ~-{+hd˂XA+Ժ8X)Kv˘!3B^&6җfw7N7:bZts1)x;B*72d/LlEW;GZ93~J?)oP!!MLrz5߄oe)uY~׉"{sdCm?zAYm+9mcNH@݃(cpX>^kJݷ + Dwc{('=S؁ltǼs)Y{bIߋѠS(aP!Qa+-*$RN;ܩye6%7ˡ#NC79h&dÕZMlJ<ͅझ.PwU,{vحw7O=m&br4 PEW=_o׿eL+,%0vD\L,,$,lL\;8yH8Xw 6CINCLd74ߑ,Z>\HdBq`s'Ƨӭ 0N`rW%7?^9Y_l ܉y.&U?Ȃ?-0i>@@1f >N(>(2dQV:7ȆnW/R#?}YE B8}3ݵ<̎-kOf+J' 4Gl"hοwF*|u9?ql|#2*: w脠f\11JqeY4}n4S4201:ollv>z4o]KLX:lǗ,|Ӱf'^8x)fJAw I%`0e+$IQ^̜CJ.|a,r(贈td­uFJ';aFygouX\ 2+Otk_Ngo" YClHrPTzNа*V|$Ъ3$ 0jKSU"1HJ)lc7i` ve>.h{ip,m0Kbg\eRDRو:XV) hy@"1 DjHK^[!U?_̀"սD@1Bd@%͕$舗a&B?L.mhȕ8q--,1 O.ip8Xsܼo56Eh3\T͹JxS^NA^73G>Gw>2dx/\Rrɡmb#X9Yk;7.@K0:8o66TɸЛo,Wlk^Z@0y|st4+-RxcubsZZ8֓^,㛀o|* C$0[+< %x>d-mJ'n9A lq◪| /_C/ܮyncjn^ BheϡObxQ#Lv{Z:?)9NG뉼Dzȵ=^މ-a[ 3}?0Rc !԰_U=MIyѻTTS,uQ~^TW-@|d*Lqq/f(Ɨ{{]|4QX*ǎ91dzJX) CcglȈ& XV+@O,rD=§f5m /T*ֈ JZoLw" ^YqIxp6<< R`N92\,Ye4:p\UȪ;SLEkE6S|@;}\ywO}zl\~i@1Ozp6]oQאXG'E2PbrjSSQcJ4OWH}9v[ǚ<̐gZĮh(dج(x'w̋z hPY5Jԡ42ݳ{s?[xHxUYJYΰזּzw=f}z]'!{dOmVę^n2f*NK׷V Pe1'z}E%+FВdoF |_6ߥ+aa AOR1TVϸD=9nT9v{ph±?] +'. tݪŪHE9>Ó|kiYp_[Z2=C^ j fTj:]-t+ZB9v^ nsk^ ;"tq uZg4`(ac8`<1`^_d:wHb`~gWPsȧ_ .͵G9^ |b,cUD+ _Z<>M122lڣBA\N[IUfy`K}C6RWiMeJ{3xA~!Rw*IWi^P>.>SLwk$eߣA"sW~$Y% QpD1y dZZnD ᗓOr<9`:H<8 0˲&ӵԁȴ 5S xET1MϚ5д F h\*YTz P&ñ>߼̟sioɘ_ dr*] =eCٵ>KKOCT,]14T t;zz d(5M],)-A<vo06W%_Q \PiU  ~~Fj-+Bip7I; )g[D2uda,[ؕ@z<ؗ$QcS'X B$2ylk}#vM(|$g|*y}qH -.^ 6|<@"^)>T+)xiZnRxP xkdGcx-g-u/aj\jF]0MpHTT2MX38ý^~`U8;Mуcݍp(y111=e)p؄V$h|3Kec>ziy0%vգU]P5fj6[ ւKW~eq(\:;n/A33߮.oRαV8tLx+Q#VS#KaS| PS[b֫NI*y{y}rf%D.?gو)?a3lϗ[y @q'${FQQg JzNmxXTÝ\E*V|Z_ ]YxTfl,-rȁXݕT;'Xrx)E#iWA(.)~(WX"si lb:tA(GdPjG a^GF!ڜ[TopJ$`h2 T-9DZWeJ|ɤ]tsx#jw ms/Zrg ~sC.jȘrݺƄ48eD+m,]qc." o kG2`T_q`ThcEy4K*U% sjX[8"~]{8 7)OކgGqjRF A竖ck`ԫʫ"P |vZ$ e*: N~܈`ŧ~^H#AZ0+`H 8 ꕭ%%ZHw%1JmC3N:=z9ٚEpsFu'|uT#f-xi;mRhLOIbaAl$7G%Va[FqW` 7Z΍{gfx]jsaEonykJfw{/B@?Y_q(Z1z8QK ƌ `C0m _܅/N~WC8vaq-Nv%O .(TڶYANgUU'"r 4abcc'faab;A D ¸Ĭ*fP>8jʙ_]C<5 /OGbLa,@+<@\7ahAmiӦPvčg_&c``ފ Jжy(?\dj]tG~AJ~%Ø~\^]ec,mmW[dz~В`B?#`*-C<wrt床+π/)i+Uj{*ue(wyhAlx-iDIu}/ڭD{MN֪|S$.hb尼6R儥376dF}ud}Оf~O5 M oO0G}o:|U@$SűN]{Ar$D.Wv.}%qZ;w4Pdpy\U:m։Nf"1m,\)VԕؓjT Q [PA"?Ɩsy-C cFE \ӹbԠk. I+5;*A O~kqD qN0udӡZtBUY璲V;=mJJU4,.LbFqvaU.e:r$MjEc#g}XOju A{LpRPBQI{gNuϝ9T1b+vAsLp0" c s4d!4!+0%1>eb<ݫNXo4M4 痺*F"?g$ w"G@oOoG0 w.OxraVZ glVSVܗ >imٜ{NbE7ѐ%&2WNM[yc_$--K5Iqo?=5c~9ױjv; yA7<|WN/{I)Vڴ|?>S-Hd?OV՟]v)O~m>/eE;}QS{adwOXP>k`~IK囃OYqws^c\)Fwbj7t& JDz,uQ&EHVikQq}$L2Cr/9K{{Z;}Bx nA`]ʙ&tµҊV{wgnJ3# Yb VnR>X3Azg`hjU0hi.e3݁IM=pl;r4Rg󧷛p_? 695K ?Z-Q fсCy?uZa/NV۽p85ǚ7Uq{0uʔvsV4{]Ws ~7iOdJ\.bdsrRLjxsHv@SE^02١Lnt`rs֮ؔ}*l}<KÑ-JMUvn~po&5F+p(zW7p:m/~֌W 5Q 8>yuwKzixş[\z=;-[ gNٹ)P .#9؂9Ae菌t|(_ymglX )2+[ӰAP\ {Y7v]΅whqѠ1HN hյ1Dx삆F4n4pD4@L7ĢBo( ')H6ZꢘZQ>ksVN1G,QZX]٬)158 I'$۱!N,fetv&EY&P<Wv6 /kux hE:\PB1roN=QYbZoZ j7t '85%Fov% 2Ho |p 7L0cBwARY÷zc\&OQ(Xaȡm𲭋/3@S}VfrmrSl%8cR$7asMefŕ"9_{+Gr;WEL?}MD-Px2ΨD[wTʖ%AY FEonJ~pvڶaGard'N_]H2XNbIxm#;m /+],r%>v|N2r([JKrr3ѻ8.zžÝ?h"U*hd=?Wђ K~BFf-O |[M* <5Y{y1"24+ǺbN1$:JȁϺ{9~!_m\0Iޚ.bh&(7.@˦VƭEP,Ǘixjԕ4}h5 ~nt[zVh> =v Tb kR:J+-~ZLIh:A%X nF@DH:T 8'8(]rF AٞQ Pi\I<[%Քu($S$"œZ<_kUAEt,spX^JCeᚑϕX~X#U H'+Ę x} .ȃ æ)9 4jHh=׼2ܹ n nS_ie3t)V[ݡ[)8{I2W, ⧮}v n۬mqO)Bw,oZF"ɾt^Kߍ7x^9llq0}o]-MWЁ"b3Gf}DQޟ,'U*][.a?H?˽2}>lDT~sH-g~Ov? WboT"NL6+waoaOǜޕ#f? WNHC ?H)x@Pt*f*D `efKȩϾ p,z g rI2RKlk;ϕ'Lة2&Bؾm4o2tj2ejqk6cAHk1M~zInTsǑNYscAf"<u_&80B{S"U[b=Tdt<=:ۡ= Xn~mLE^P_cT]Wʝ?))myYlffn1ϻqw //UsېLzjF;< '5ٿ'{B:ƺl]bV/ڙ9Fw]|3Mn .@ˍ2w3IN]y;BsouD ˳*M$F-:$;z<%2q/MЗ<iNEkֿ.ؗhg ϗ0r-U9 UBe. * Rc~LW1~a BwʋLsn»"G$~(u!;S<ē#Z+ܠBh69+R}w+yץh5= e!ac6r \4sHqq}ߎOl]:""^IMY‡4~C+얣ūinZm(wqMϟ CȸjP[mpMcJgc(&ކ>rjkfHWp^BBV.g5J8Vo,џS /K'ΩT.pLae{ۖӔZ WH cxdA[_$ vj 1wj{ HAG}Ձ5S+]{(0cd~A𔏃D7^̞Wl)= Jz8Y:uy*/~G nb,<)GtC)Źj`=eCk7'Rz^![͞S2sDͬOkO'P ߑNw**I[?HAY-Ú+2CWg?SʆHJB+c~@Q%!\dOe.eFG\l$?q}wWGwq7Rpk?, Im=.\5U/y+.nkKYhPiѯbAA!?Nq/|vOCpĈlKu+gj~tzIZ*/icu8"ޣڂ 2c"-V \8dbwZ"fNx cqM,C,re{FDckXU|2O3\EBEj*6Z{sX-d_51v(+ 0`%'Q!VUv ؞ =S'LӃomPA$C03C5fM (TK lI+#ٱPλy(($г8IkC8u-bEm_z|9);_ašVv3sUILXu>"f{='âuĖ=xA+`^ {;\11~7G}nq/~R3]pSk" ZؽU"Ħpf|4$g*-ԙ"2)>{|11xbvVS)`O:79BDmtM'h34={5& sǜ8=bAπ嫮ĥ1 DgZ_,ֳCCY*U1e@oFz ߫ i>G|>PI 2tVVlS n9.۶2˶Ccew+3' 4 <.'#+@{`ٹi U'&WQUa](,+#_ƅbpVUU ꟈ, 2!6O0P bTsabB!yjo?Nz.ziuD< bLBc;>|ڦQ:Cys!!m[[ZZG?^T6a(S_|>&x ~GWut&*XQ⢔%YW_:M]%TɡV0urqI$UUNs+3S[Ųˊ[u^%asʩ=ڝؙRbU>읏&X:|O0GPdIx9ZFv yy-c7I(X'_Vf;OSW[ώ:idǑz `dvx:hYkf공o7'atTpH=qz+KHuVkuC8-)B|r ʥ֦%45ڢLrK!yz$cWoDV[MBM'ȔW;@Awˀ\2Ⱥԓ_*$]Q׵ ^eF۱E #(Y s>Z;9XndO>|<{66hX~*ʛ^+~*k!I3?R@);B?HQg}Q"τAFꡱmYX̍CW|xTC緷j=e(qbFGNqj}>m:M7J_,,5F-<~[DMBxoepf抡aƆFż,:6WճD6!+ʍȲo7~=|Kk3>5/p3(.c!fɪzS*?ջafD"N*0X(@%Ib%7.EUF@FTfcՕksmAnGFx~?ǧgȜ╮M%10@;ľF=՘RouvFcaNL%1鉲(f!# x`'!Iy]zRr,7O )'b/1~w,iPe[kXħ5A~b\ 7XI%]F fcgS 팀|ۤʏj3w!p/Z>q'W޷/'t;(kj bd9]Fp@"=Ul$>79#0:-+`%)vXFSeԭ_$Oi#b.&;g *}TzC?m}8ts.QSovUTc5Š49^DRkw oL[vDtɴS.^s,em>a,7$aV=+LjZ74/[d4e]\M0pX?Ud7,w+n0'!3 z`XXS_YDN%t+Z۵E[2|{@ek>|𝘇]*!۴%i)̗: >T>;jciv\3 dPjT<, -@W.DZ[VMys~ Il[9AzJªzB, 9WS7wL>D(Xscm#UX21aa}5 j?!7|lB,( GwSJrLg-jP ( W6K/)wN0*%'O%$Yoa". +Zjy~^/%75hV#Dl ;R(Lh"<<ا V^5g3/8kD8kU35L2]X4lu$؁fNk*KӯBf:9c[ϥѳ??C+1lLEy2CY[d&%0ho'p%rcICM pI0S(JHkhco@=fdJUtns=MsmDv+nZOXE3XmVAB/w*ek0>8mzS:hOm>@g'HZA f\U6;^,rcHٜ d'r5~ʹ^ G <(x-Da%Zce7߅NS0:Xaҙ֕rB_пwJnw"6`*]qOp 6`H^xt{l5M.ֿ3G[$}Fh\fS2-oHCA@ n=p()B|2w=C,?BuKHIt6!i?U"/8O[Ơ 3$q(kxt3HV;;fb`YajuddMnoK%rr?( ^%d k ue81Z!F\wK\'F5b„/ _PC.iꑽyCĪ賕QrbE0rjH!:1y) _them fhb)/hQ*[ \u9PB2ǐ>='h\}ҡzd>mޯC[Ԝ s0c*1Pk*@UF+lzdrG=] /ckɧ֧TV? [!-,T}t+jmU+u?4njCf)Q9>B8$c{l>E fHWA0H@1#0V ?DPy`')Ǜo:z"XZ^avђpФ{̋OEPA _J vAűι tWSZ2"(|"ݍehFZ *+=+ItKͣx6.@@5 ~W=}Sd' )t~cz=l)'DWSZ/ 2sٟ(7h5b/z᧕O@g96Q_#E,B0JcRZu='}4W[xVw2٦j Y~R\Qk6O(-oۜn^ EsL\/]kFfzQX0hi1뜄 嫆}o Ld)KHҙMo\ [ۛ^Wm Ύr #j4H]C~?cHw&!1gs +ޕ??#޹,P@P,8,G`"efa@Y,E6TDFPČl\  xS/'fe{AvR.F!r2rrps1r'0Fz8 >#bq30sXܠ&.o>0duq?TC-3VY ,? @(  bP;$]zhS!@ @v.!.VzklW-w[Mc*j`6_L&B5[Q>ym(fDɦ{|w1Y[GQjc6Sk(AG( =8r50vo;s@v2C\YLfMCcx[h˱*&^+p4Z^pҤ!s_$mWԪhIjAkn+͞V6seJ>%ߥij5gFǴq h[ƀ ۉ-t2 @ڪo= pQ@ ³H`A[(zr9MCV2cb‹{|Gd,5qgC9.J {rRXaSQ4]EjVWPPhHm{B&_`menxJZ4'S`R_&V Zw4b"l .XH6J Fn*ȘQC)w RWo pŨ|G ;(-UK&?5qHi$РS[SW`Mnʈڏ?o=DuVH…p]r=dd soUG6EԢ?3)\Vd_eYM|HDRO m?t$/kkח!I>pB߈*8 6xg2s=:F ]x<<m?!k`K{X9T&KOޭwl]!R`BJ.;]Sے1*lcej! T ֙R(_%JO.[T[ PA>40xl6bN?XZ A~)#' 񟪩I5z𯒟@1p2rp03r|'qCee`B12ѠNsCтXl\ bdfAj@CnMmFLǪY]IqK'tJGk7J6Ks/"?(,e6~ RA!9Tm^F̖%]s̈I9ӓ[SFU&O9=7:Kz҇\Sgo6CY*4o?;u/Gf7>D|M`Aecm2Mg$%m~!@`!h5{0p@3 GY9|Y>.|u=Q3P/_Ee^XiʶԈN vem|YK(ӦvWLg]7RL8:@ۤ m?0>t?*(~WEѬ1ߌ!AD.tTy|IgSԁH@ui@8RڞĭBsbLM3$~<|s]N.*y獄Jv) K,>BY;R&oͅZ7~ >QԱJ6Q@Pֹz6o`JNyRfE_x=|.~$ۼ[v>Xb2(U1(oI[qєv; ]c5I@,![=Qznu.z|c. Jsȷ! k=RE+NlR-t5&wutuPzaa,DiwpzhOS7\ոruK|ӛglXL|LaR'm@5D j6dvV/1/=i?:ѾG1†鯔^N,⣟L&"S~ 'iT d3]=±fz븨{XkFc@inK/y~gه Z1%Ǹ`gPn' OC6)~^a|HaRG@"OɉJS+p=hbnAĥl՛Ct7c=kbʴ0&p)[hM+H(ZE[ׄp/+ Yk9.@"=\sHL-pF+f' oA1ɑ?`-4xH ]$WLE}{rRFY>S:qr -+)f"^E޾~AuȞ5EoV5!~r+`z7O vƫôdJ ;V/ fJH M|c_FllUpb[ @!RI U[dt|EIx_GEN*{^߁xiVQC2λg{c,fcGP>￁[3ٵZtICɐ1/;zNJgg ~':?4 6x$pk88>u׈'15&w( - C.T PnlDJ>Lϓj- HR*PբZuW35-5Qi!e G#.#D^2~y\?* 9Y{n{OVJ6O")9}t3)#ڶ^=;FyAμ#bD #Cx=W߿zпWX!?5?Ag"#,v@#Qr~'D_S 8yA<K,`Z&2͟eJG”G1lt5")3|, -'~F,q`e lwy,=X [sFQga0U_sƕ|x`w[^GkXOG_?e!&C$Ztj`, RUbN1BK~,ۓ/sFl.^+6˥r-T+rߜ\Y#~>vׂqh'n![:1.Ps3~I!!W6|i#3|qLn7 /3'tdx8L~q|D&5)PsҶO9Q s~Ʊ0FK"PR`9 'AZ-BH&E(%m$f"Qx/ʒ#Q]+󞮔U=X;> _wxUܓ,l \y|p5nnq<2e$ZҡE,Y|Л {A\tMF('`*ߨL'1 uG *wr7 CDo&6lBLAs*Z[ת a`/,J 79ޘKWxuP &E:<9Sd i🰤8,A;j6 |wF@蔙'Vэ]ET0ׯPkLS N{AR> ͸|Z=}p,ptEjoѐFg֑{j9шһDz؂ ټf;< W}0'\m-HLP{%,ܞ f#io_o3R}_R{?bYL.|Gz]!sШ`joy:z]:c"@iBS)WkPE&"|B#ӓa"DG7 8/< X >=Op ҳs>#j>ngC%a?'oB@27!\|I8ܼ g| Ӈ}{/]9=`"XÊctyxk"LF!i)A J  $0b8bX6~yxb:$,ԝ=F|<{8}_nМ: R K,85[_AOZ%№[+BƦߌ6)LjSBAsiWVLᨃKi'N}ŸЃ.kq^ swZp\I 3KF;ڮwY4C ֧tMtA?W_>5:f [{2 :X?mD32V3KF#gf#x=+'%3t }">Mԉb*9ykrĔ#nJBm Zf~wlk*JȋivXe;4QfX[S+,ƀ@yYZQ+^M'6:$*48B36+(L>Y5+PPi.Xiʱ4|in-Ӎ_Cyy ?+⽜s)EU o|Y N ;H>|D6k hi%pT=|DKFkcc>J9^IDsoohw$(re$c5[N,^@>LXcXh%B;4j|sRA>pQ4q$1ub2/a9>(aZ3Ctx$M\IiC6-.$@' w0CNFu1:[>nC ?H ٯiiԀ#S*FBIlZhL =r{1L$_%[tI8< \#qHIG|(5JZ^XuA\&tÅKp&P! j_<8̌sUWSsH+P"Fߥ(mYM+E}Jj^)oyKv/94|SYQMTےڧ084"Y?U(Lf؄C3o{F;{< 38" d'HoysB:1nYOA8B}HCmՠEqd޲½{.dϷ;&xқ)4UK7Ki 0_IZ]4)^ ﴾9M~;؎!@̯ԲUk룬E \[ 8t(3$YPQQ$gs? $$nk?LGbъ;$=?LtTflJ)+IhD%5dŔ́ϰ*~h1rbh\w@L8DueC$~9f:!_CѭgKH,ŒZpF`xM2 0d;"ldXZ츾Z|?v!3v~TثBг捜7.suoWȸaP=,[v#z$t~L`{߸C"y!LF X^kq&b>,79͡eNs)LUkٞ8[)Dh ,vK-9`WNJZS-G 7nA< vO(2'5;w`!W?@<2~N8cNf#S!(vtҹ;|rBMb>]fxg:-zj]M8}4=o貄~ v_80#Y{:Ɯr;5cl䃣Q>HSAVN'u@jkW&V槑A76ڡ.j < )UAUVFXv!h$Et{QV;e3Jt]cRGo7dj1czB؀?ԪXtoFʛq-UUQ:nګdݎMjL^lUO(<1a gB3Xɾcl+/(Pw>R.Эy0=ؿ3Ǣ9𢳻/٣5c2jւζ+Z{ iK)} %~O(CatRR"ǫ&n,k"=&bآcSa'u45zٵs*>'K hu ?p`u9fw3S}emK-RsUv3bCqWXf[W|-Cs}q˓zmZʕMߩ$|AD*/3t_ 6}P8ϯz3)c+lo$h}x ['N>T&]I=)#~h@&P>a,}e$uEl!oa$vAUޠvAڅ,K=pWC pˍHa03[mNJ dQn>:Y`ԧQꖇ0;o0 K/dB_:ZaZ.taeF()>8if.ή! Yd._s(oAe&qf Jq^JGBỎUwT^8dž5!vt})\o'Or^/^8 ^0ĝM)WȆE{.~%:,nBԎk@/쑥ZPb9ʕZ⫝~:ܐ= =b{pYHu2pj ?bdc@i?O6^/!*Ӓ ֹ{-RFAǗk[/(KA*3U2Ŕn_(ػB;47xsKTG~1F󵼮 2~\B&dPn$kzH0VٙnIedK/80 ~Q&hVZ1cX\p&Wĵ2":IPx=R/8~c$4KJ]݂fB{&ZxUC_".=2m9x vyWx$.Lj<@nhONtJzDXRH_'0*GNk.L.k<87GL'ȶNsd.O{B3z>R)`YmO<0ZwA^I'֎Pc- .dp;.sө 쥊 dѼ^d."1HaZdL –S`1Yû mdJ{8%V7$h~\2_&ݒ6ntLPX3Щ̓bL^p§֋J!LIc\4ޔ^oe=ʯR@ͪ}î(1,q"n?!wL<29NYs0h$~D㻝{gǯ k%Lj`_9hRԟM2^i,uх0aJpD<t`c^7@Ast)< Ow?pp(3Z  pB~ IoRnr`E@b<- ^ǯɁx$vqC8A@@ @[]29##@t~`57XaPvMS+s8TJΧ>aωV5ץ-|󿭓3=Dv`s [SH⮸q!ї4=,tm5_ >eM8[oc"3GQk:[' e(YA0~h~qR!~zp}{.~?5@.r6Pt ', Ҿ>5]M}Y/ڿq8߇'iPZ<Ƭdf>(8X*M/8ƘsTWm8qQ\| SweHq=KG'H8yOLztRX&ŲRi@jI"0|D%e< q&^~]Hym Op!- kYCMLv;Hk6pޅ\21#0꼿0ѓRR04K=hlPB6A6V 'q>u{/[}<:塙 kEK4>XzC5??{F&Y,3'E^⵼Mlb##.YUMD_rlњuJwy*4>}k fuyV73)v퓩ZF)R(wBً{E漂7ػN5ӭ-#K]āMLsdQ>kyL/ \>I"\5>wKy ϏS빒4OA E-%@Ґ7\)y#5fYU ( FyMpmzN.ZFߋMNqsFSc?Lγa:Lݒh j7ʜ]fe𨴧wȂ x).yکh ^M/U~ɩ캟 PI~mv].M=EǟR{]OT4AEDT\&wЬLUꑼ#S'F6+l 츌šS6ٽM y.gp]0)( ]W%Zx!cq "D3]sP? ͽp;6ZX`ȇo9QL ~Jey=/;Q"=5JVv\D#mdR>Uv~/U>-nw[ɖ%`Lr⠾ jD)nǃO$Fղe5䰘'n1DĨ|,I`GW 7#tj1~_+Tok]KC=>$+,ez*CQ ׿-5&}o cZJS^(OFKeB*?2}_E̯FXQw?rr7k||}NW>-Ҭq#AB+@x> f`O@?a@LX)<2 LMJ9F\X;s\'R/A ^/τ=J&gJ[ tݶ+ZL8P5d?rw"eZ9ΐP]yY/{@'8Mq( =gUY(}Hfm% |{}%\ Üm/w!ameǤ{cQHL -Y yX,'aQ, ^^c3m#7ۓv, kbj,C_i 14 1^J黷o޽ہ ~HL1[5[QZ2<Uԋ|3UXst[bhq7W"cwdFБ m7^z H&Tʏ1 _rZD|l$BùG $ |O.n^+8jDnS6JhV_G{h1Xrϙh74(+kVrsJ(]8:MlxZU=hJσ(T=tywZ6Ŝ Jt )4Rgw шFHnP՟ɝDUhX e= y?lGοdҜ*`ɻ 9N?\ ; żUG{Z;Ijeҍ0k|_6@I4]ǐ}y=NilS>g*A&)iN'b0>4 uB6$i(Ar;N bE4$J"dZZpe:JiYnHv/xS9C'GӮ @ |4k?Mv_* G)+Y *ȾN?NCBwv)~̟Z(944?x,ě XU岊SGL-{185$4&4Q6-PڮXJ1HN|ktoU-uƬl=C}c]Z%9&=dbn³R-}B%eGpޔER"wi{w7nD=|ex0olB#bŷԚ>^;P}XbMqV:\{R\b'}4Sf<t8\WͤBČ#{L#q.*ɠ\MaTfa{KLv2DR/jPD"$0/ \坑N!,*EFإ&m@Q2i~=fE՛012õcTfǨ3'Tk :zKx|)@yqGM:*'jF0vq WEΦF?M_O اºD~IDZ,mrd̄hsI 0e,Ul>n>\{AմyI*1ՖNdg )%*%tBfPU E0  R5hY*eZ|(-̜{oMvc/p6/>L)EjhPˑ4# A0 TT͎5v5u}uRK65J~l}*Aw Ca[^$>ZxjfVM^:% xb)A?bMȧ`EYy+}~X[4s >,h+T :IVpWy{, o}$mWѳER0{*cs*vPuKAu9zu*?yج{q-~pOԅS NU5  ׇ 7i7NW+k@j" /'7?5Oy? ㇽ\.@\POS_ ssy DcŒaO30G䀙. ~Npa 9y8?t< Wyxy9yndAӟ oXe( 0,8?dX{;PD d~]sFuaEd@bX+<0)?bİ{ .$XtC rr'  rø$R &ߑVX9 RX6vE2&OYpƿ?N? Kӏt=l5T'Ua+D E˕BtֶW,?\Q˽:f3FЗU%CRO$ l&:In8nf/j-wtVQYz8T5{/G-}״۷C+W@QG3!6#B vw oZQhɚJ-E> F8L}5/ )܏P_{rP393Jg}!Ш(Xt1s$a^ ~u$pp0]VG;{4)>:1*QK1^Jp]Si[6X{dY'),E|Z/ܪ*mWe1{@?%B /*G^OOpsO&&bq4V_ n#j\MROy?4?|>c+ /@(*I*EX(N@^%ezRSCX=rŲ %(57̌(K|QhfvNc8}')}JURɣIԮa@tG^U)߅b KN|=us1 $o"T@_wQˇQZ7YNlăvf(6pŸU^j{8.F8S9^7+nt9hI*u0lԼIR2'~qG=3R 3DsANKBt{5 SC#0ibvƥqnM[qܪgE1rUցxGH"Ci䉡s,<pz蔮 Av00pq%g$a>EuKɥ`:4]+w8@qf{iufdO/6Wp.y1@9&qLrd Ob24YL^Dzw(ZT{b7V4^Zw"![Vf%s v0r/jdwKUnmۿw/!@~CA!4O\g$_ۻqwߗUQMg8UGOq2a'X$Ujt%N쌩 5e/jh;ufsgi NK1zjmOA)*9a6T^h.8mCs;rl?M}9 ܠ(֣|gh=íQnTm[<) ]<}B)-&J6}bBYQUHiXԕJ[8P9f)jl*gֵ6MڗŢ_(`udELv*7Ll]GĜ/z@Uņr-w((鋖WVrG,TW?3v:wQUSzݭ<_/bFױcM-MU#V X*-)KKzlJ1v;Jr@[LԤoaǃ!NH"wKQI1ԖCs&Dr VHb85*xNCK[1*g&OkDw]vߞu*= 1C_L#7ZtDX/Ȃq+8+U NA,<> s^~ FO&@?}@Dx`ϟ!> UGfjtFE/:8;n \S:dJ@MˢV1W*^+KP8Y}lQ19\:Y=zv]Ip5mD}v1 ׈+tSF(+|_t"mŏ2C#MXϫR-?wzQQ#k6uWĪos8л2wys;ًJC,nxxтk ԛ DJTtj>87ߢr7vf#(Fp&j+fu0}ӀݳMiwƫ Nq Ul^f0'%$~%TJN|!t[z#|}i%X{st7!B,"UQb, lON"].ӏ8'|6GFVe7 Z9PqA@LY<^4a9'n"`?pwc68} M[elXwۏn$ȯJ`Nh/<-v4]1{c`ҫ2),8YAN[mη*Z n:}\!ޓWԬZ]fN PDŽ= WD/6EH&}:XVA>"YS% Ru73z^D9WnJt!jr(UCN' wyJW n 1jщ2qo ݰ12RXRC,#^lح#3de}`$FǠ]scp%>fk>i 7a rrtdzP;Ǚ=d PiThI{Aӵ|]$b4cRcvjs); eDo&In0č܏HruWSuӷd~gJza6RY@,oI G¦@R⤏:.\JݹB&OYJDfܙ ^s⧺l'k{1H sPǪHF[;@;>(vc!s@=l  tJAc5c %f ͑ SVb B**y69 S8g~<;Pӌc+PaP Bs4<:)!?7܅HIV)l,M73NJn׌6>`|rJAcc/jG$sJ=JG.7+!~LQd7gLTj:;ٺ,Tzb-&)mTuC1NA(Cg?ZNr U? 4e¼71ý MUWH jBd:O&U2,WU=_f̃=~>A9[z>9e$Dq06 $Tf!jDHɋ ο,7`NBLpId+t2Za"@>āx8 '] xy^N'ThdV@x `pg?IWXd8I>WciR#/aV^<$_!wLGynJ4@tӁAd8)b!Ö"*3n@ށRn@rI֖祝 i4HCmB[Ay9W1+]v C1T~= 'Ł(kRQߣ+=xWrE Hu^$cfqbVyKh hM}♚#Pb8Ž˺8meh5`׮wV64"v ЫgY[cx86{C& i}(Jnm! knXdTXz aq JHWџ;*4zׅ _uq{$}>27]ꌂy1%e#%h+~Lrv[(us@_P;j5\zs\yͥj`9aNєBd26bީ61, J41 ^)wS8?cܵwH_ T:l$/ƷnP2.(Nes.ѕ jbQҲ[oGn # CpwH\; K<>;]WUwu\=}Z? I0\70dnnZg˷3R%pPkqCamYU2l[ z6lzxXq`px1 UQ$%anVFcc^; GաIɐh]NQutCȨ@=1:"5i}pW㉏nzmmײQȜYHv+R~-n^JKo| l'(h4 ۹ᡮ HZpষ-MiT[⭒!b{[SWfg⾯&*OmbILhϠ6/[BD<ѵ2Ftb-)3- XvZq5twj-Rܴ6%9U.\A`ݼ/n] =-fb%;v%yljb/ AI@dfqK4cPpg",a0#5DM$O&W9y1zfX ;iM=>@҉XѷJSwV:ڮ7>! Y> 8qB42w+;)3u4ɇ%lxN`h~@ȇ5P^:Drw.'8{mh=`&4wre7Z{ax~#Ot%)Eק_'odۚ-ISUz[rQ.M s?u?XD[0]C{ϘKM^; Y+ίԉwMT /TEK' f_6ܗ7>Fq?o: ]PxfGNw(0'ۿ Nv43rsO@ \M&oc o?X+XQIc`~aف<|@.~r.?0-<<|@c6p-b Ql@>^~rN~ J=u%_<[wMl@jSAN66 sO7ə iM&I<  X F4," P$8|#h0*l+SpC^@b-O7Mnoo cث0 bW%4AI,FI޼DBDb 'ޥIO/~uSɨzuP.O}%9Z}X.VTws,L&/:ZZ*;Q8l ǁ|0eK=+2F} iNX@ȩ)#mGSss}(H`, ?+أ6WtLSv'-2xDH*Z9, Ԥ?H b}io^:PLM-~v\Jj qUp_{\'yO49xr+Qփ w>ǩhH%@a^bZc`л]w}&#>A̓#PD2OCO KNؠRA}iLQ=L`۫Q]5I-0\PLHX+<;g_JS:?^7L}+dA(|z뽊%nBV,}hTPRol ھ|މD]؄+54K-; ]Gl ls儆DnkB?.|4*76.ݯ,tiaIv(<p r>{X;]n *|ii}X_'sWO72 :6#E4N݌, /*,ZE Qt驹G#+aki.9YMZɖw*^TE @$Vm~hK )OϊO2aQ1aWQQbmx] Fx uϼ䧏X̻&qa-z;2.c@2p >lT,)0#Zwf,#O6hKzy,'뱑$/Ƕjâ󙮧X^&D )b=+`K/@䑔d0S\\tԶ*݇bLwoZCª@&W4J\2RwSdJV|C4.`\Gpmc⵻s٭/M+ iwF#=hn?Ty!aգI fJ6,j m!}WuqH@09' a[Ogs'Jx@^o$ج<(84#-_9i!*ɘЧ8\SJ 4ё *|LE43A) tZzKtGĭk*g @AI+ˉҎGRR35ޑKMxM4=`C3$Tx>\T/OWW<=_Kdl:[KNJr= cq+A9M'Y y< ㅒlL)j"&(!8B%_lvDnI$*jyHwF֮ë.IE4ʺir+x;]=&y ѳ&S, wV,bVL>3ns׸ &g 3YG~wπœ `=FT~Vc-8]ux nR)WBl٦$*]?A{Si[_2 " QlgCa|ݻw@ F(ZV̸]œASf+;oB.Ⱥ7Ś܃2cd_X@ Sbǽ@bTyxٹفl| 86C  Ƙ Y2$HKY;6UMN} 7Yp,41A܈'N :׼ɫy~W׼u3U`hژt6ע[+£= çǬwi󎙦WMkT`rȒǕ[26R0T؃dCJf^_]@O3GlqIQd4:Ѽ=Ix\*{Į.(V܏BJݓ VP`vj)4n#>~U$ qNOq+Q[hΥ؄VэN ;sb_ĵ޽ޟSO}ERҊjW>س: )IUރ$ݸZ]—M[ۮpm$H|'˻^'A\eptX=d%|i@eK0;AB]^B%ۃF$y8W/m= &EO "Fg2uӉX,@J89n63FU}O:AE_[O$`>4=@@.4:\dzy4ެisH t4 lgxk0#r*_s.zDEo0AV yXtՙ5YP3R('/"~Z{v3*s𙷜#Z@_jrJ ̞J}͛m @5PG5L~R +wE?'CѪ򋇵ϜDBB:_u D U.uWʵC0I!oB l X:( q!"XXyu8Q#Ti!wo 9l&Cxעuw9Oط wayVR|K!qFo¿w;p悽_Nb#?P#sX2<)@ǸW[^@e'_jCg;W4#|MQ-U,}%G|aFP0ݨD>x `@I~Ԯ1Xjugeht5#ar0j&<F;sGb44Z(4]/ç'q {kn6i93 n#(FDr*R} +w%ʽTa&qdEt7Jo;,O n騥"6_ZDlS<% v-畇AZ{P'c0uqmERւo;CĘ >`yq!zjK$|Q^ WLC)Uv]~ǧ_8 _qrRWSJ77Y_/evIe3ÇZya҃ sNkZWjJɵ^Vϋ{47' E[)T@|:B_ {9 :SW׀WEib97{t. rKm/5!^σ@BCa]5ֈ:hNZX4.ᘎ1V«^0rw!9*P4dԍjc~-͡^Yģ(ش6{aW}{h HL{r󉘌c#4ىw'nDڒPj3&x r&_86JO1z@ I@MmĈ pv`lQAO |zx$1 u#3&C=BXƩT}A&;|ᴸ3J .m\l{*y&dY3 ^6ǾQ@0\I,xm6M2>+edw{CZn@Ѩú+G6z|c@ݹj.V5+ 퍽_KvG#Ǵ#6 !ؔt^ xrV}rqЊB@5""G28Ŷj-; ov4.H@q?q@~4KC/K Kk(Ȱ2Rwl`ZRNk/G ׿8ypz0M{\hmv=,}a$]^4DTKi~ IC\b`߅P];қ."דz,(uu [rgچOU4ӌfHco'?Jt%Ă(/U!9djJ_3+J]&B\LNm>=Ϥny?5ס!R!~yMȀ<ںh.-zѽKޮlTkwڮ9ICbaSJچzJJkNg僋@9ڜ=G"j,+w!^[ìӠ᡻IPrёsHb°A09qhRcp#bIcyPπ`5YT 3$Z5ڄKYaZw"_aJ VKGI+GWPЧVN.0mH'^`_ ٠7pQs&"~@"9ߴ ۉ!4IveԱ6*j] b^Nqu\:'zYFwwT Ҽf0D53"'܆ЧR}E6)hbjKQ-fڜ'=W*FwoJdyFd·50Vy* mx$ BTx#.p"?qiE!?ܿ$^ ''97;[?҈o`Ŕ"aCAj{.6~ ;E_';xBFHx\.^Px\|@8d? <|@>?E@nnЬ<JU5& *_"5CZ/>Z`NPFǻ(O`KHx / huQǙ+Ѝ+Sg6#fN? ,IS7tNCwDgzo7>q"5].33T\(! w˹@]:Ł^af$:?:0D naW{vT5?!i %33Pl4:Hk'cf\\n]j4,0t=yȖbG+KfG1h :x|0Bw&Cf8'$P_rE=؟0JəW|_$'PeԳYμsɉkſqZOȷ`S|.}Mw!mvK Y>1A ׺mX 2r4P { _'\k2]D9*8 Y6޳%"Fg'g/?@R||k3FԺPhR/iH Db5:zHr, CCr~xq W$302 C45t0W,@4-|.I!QåTb"صЌC}ɉD \ن0RR *) PFfw-%Q4!hlsqXn&ӣh_X2Am:<W#Iu6"Xڊd>FinfzfI;F3de8{̂Y_V˒7a /;- ֋u[RK%wtfa[ou8 /VlT {_BPXR#X}un>sKjVĻCfLO{HLqSEL3G]{+#Y3db[QQ+ tK >31*==%6 D,oLϋ6o7\:\Zsj-tW=-esdμ1fp\wO܍7\^eL]%2*?x;=ň#Q@E~xJƻ(!t5OY?);<ؔ!CN]dDcw:i]s :@^|VOth%216ȯ&xYf"\JM {BM$~_3Gj5=~߲t9fЍYH`^ ܹ|/ij_ snR+,ެ S cJGْ xo$3C2 ;ߊn-CT=^=/nwdJM{ɨٻ6K쉖|rDΤRTAn<2̝V4ubI.fgG- lez+)U1SM5( gͫ:f ;R^5oMC[h=BݶJQXͤ+yEheRG%eۜyz+[;nAp;#x& u]ڷhk>WYQI T>|bhQlA o}..T@~ydm( >Dm3|ם=GZO|W\i$m4d`ash8]I#51`5fuZIQa#LO_Z/85HtBm)ґ$&¸ۣ^mOZoU gSR0'!!0:AlŽC%3b"u !AdG51¬/؋}VCv"~J;ZK H^Hm@v347JGx-1`{}Soh1Vα7hbF>ҶH3kYeԂwVCx5爸ÝI>t'90NSѣK'xW3./u(场khTυƬfܭ~ %GNZabpK8wp0| ;C1/9' Zlf#x۠2gphdPxGNm¢.z#@V?aF}iJ;} AoDGD/'iT _LFrEzj#4oSP!eR0`McW28Wa (w^Gf}⃵D|<ߛ6&F<%#]^=G|8mM_>ȩT+0?eO?zG)D3)R%YFϊƂ/Ta(l80/](\ IG P,mKO*颒>僿>LJGMƜ+`jC[bS]F;%i?=vàP9P{WU3q?bLԒ[#6/m-!L ȈkzD X;՟0tfʕ?(!WkwGKP7‚`%lR|'֣AweIX9#_bB?jZLWI׏! l8bdYz{i1]J.z1f&)IJP Ȁ'&rn!a$ê앚=$і`+.-"#\CʵTU,T3=প+?wH}ko]".K˕,%`nwv:өuPM@ddoRܝĄtW;m1 W.}[w9XCIU6texeFI4^s= AѷR3ΐH-*J**& w"v Mu:zRՏ:bG%5srL(;oQ(%a2@-yG8 tWr O;GEJW퍱rHiJyscFg3 ,2|\xKlX|/d)./8߽!w=bø{>`LFZ6JEDEgfI,aRPvf4!_?)|_reWc, |/^0iX{>< QOx$ ̔1n3*ȐN&o!m<,gf1Cs .~:;l:G?[${cMdb ֺcaL9y]2S/"ʌ@ UѤziL5+6P:8V VN41^/V7I 7=:*l?w_y/V+6tJS6'!Mop9o866b v^^v ??]ʿ =[_ڡ?9 >xß@NF8uZAnK.{E27x+sfK U{vt~qަH f^==8j6 Ր%4>9횷LK|+&< Qls2V3ʗvbL[C=4oF_/;gKb5T oy⒐x쿯բբ5li߹Ɒ/q30!X*`;,x+` HXb(a0E"&i" 1 \`?PIz 7M$j}/0zԎ b ѥb`=f+@df>͗%V²"w-Ym=qȧ3-jUvcQI|)\! E 45V1Zg.;D.': ]$OVJ!1 șlPn6xhaRs)2\bnBC.S IzE;thOڏ7!U2n}~?K=[vqd[;ӭqf@W<"+1be)-^)fj؉dQczK, B`2 J܋d :ѺʷԍW!MCOC+cF9}1t)ۺ&[dm`Kof[MgrV4\yW6=A#g~G 981!ddU>ۑ k[cq]bM 2dړZOC# .F)3Mg1o߁}0T>gJ%B-rܩ4KWZnj^Z>{꘡;OlL߸{ 1@6_SjBܷMG%Z/ {]EIRJΣNZ߇0p>l}1dl%cӃ+⭥6$iB`W35L|mtoMޏv4tDx s˟[uQcf|¾A٘1c ?Xv 2CZ;%+jC[1Ì?y1QMl{sqIAd V^YBKfC~ZlbJc)2Ӭ0ySҌmp |z/*fOHْlԹ  t!+gcTsod+T$Q0|TؼK,ˊp3.V0BL{Ow  =EX_h=0n-{a=cN.-irTG0bQ)rr\_My]Fp/F+')}2Р(`’jU=D6 z<m~]F׍I(r== r*i*f+mD{s;T)/ QU0:6 ѢW`gҊ$+pK2>uaK*.6Ҟ`vLWˮν+8s]3ɭ톑~yl“ZYvx_~v|z %XRbE,k*C8.oŞ^F a HaX$NJ5鈴E"iԨIxM9!_L~I*-&eZKf}Xt\Rw?Ju9jkn9#nq!wU@e<.Hܷ56/bVǞ=AM[w:MPThCcIAO]DkZ ( 4icq*).+=pzrEM`vZRT;ˎOKa7O8w$- *H!dzNw89=@@p];{^}~"KJ>}QьRa0qvusEWu|^pj_zqɲ=ӥze6lϪ{J /ȴ58Zeu~TV]wRt1x|J˨BsК+SوWvP )g@$lښf s!  UǢ…cxlF5w3P^zu=UYu~*E`ve H_UC1 2=q@'n"+)/t5Br h o}b|ɐ?:|AGN; :`n6HeӲ <"Q{] ~ò֨v iJw[EGtC|"ӇnWpne b߂}; ڄ >6S6nfghj11Qc`Rړi+ՔU+E W@NS|/s5HZ׻mXy Wjx\xRЃ'8M#J!gڑc/פG{ H7nqvTᑴf6ހ`9Xww5J*pA(ZdҎzSU %IۢaIkǞi)m_3PdP62O <0[1ZfeAbf ʇ"E=tf!v %Qq*r[so3󙺍p|L,t(xv _đP?l CڇpB]rfλ0n/-K)p6!胄|7\yL(=קq?w}iF}1!HYD SW4%yL0UPRYy:QeQ@ xszl *ӜcW̳EEqA9f7R~^Zy'}=:zO12ZBQޒB0(䛬[4k, , @ ' .-5$#}ySNtUU]uQAoo: $##QZ c86qlw֒*ّS@m1k:NΩMs޾Y'KnF?Cbxbn?d'uB|u|cI@2X; ͏ cY@Xd-w:p[>jH A N94v\ok^1QIk<\ ҿ79[<_v[q=93x2i60@HOXy~̍(>'+vRѡrm!/bJ1Sb2·sI/!_aF _m\Rl='BpJY>j//`cxjg:hF*c|gOgS7Y1:/ɇU; o~:_>A3v&fw+dR(nrk>Z(5hJ^E oFjdw)IUhyJޒWV3GvGsՠy[I''-Tmwɞ(pKJafS{'*ȃ2sEN.`[gvHNbsٜzCU gf|̣lbӮ28މ+\uK3U_1f#Qg D s)E !NXBZ>ka@YPo9u7<7#$7LI</(X%;8x=cC8+]ta: ǚB%0omo/ǥUj*")L?^dήkX>rZ6;O~FGս;`I\e;5iKd3}qy^s8 ŋ/G=:3zǯq+d/Y?S\a|-TQ[F |N #L\:q퍿.bܤ>~t gHwT> af):`\|u8jܲ B,EeZI##|]O |f׼aF@}7;CQZ٣},ɏKK- ?-N$yk@RJB+g~Dž][@8Ji8 |:Zj4JO Rև7a" %`\4RaXC`FrPDf$;l4GZӲ™ңJt}%:fj&C'IUw!-}+cX!KDve؃n)*5'i$sOvzZW_LB"S%U],h=a{tי@ ;ځ_c6ǡ$ T2V(: &4ςnmW*ݍpm U$RŰ_ ̯y.9v%%%>uq(U+=b5ͅbXʱTi ! gڋq+( ra9ߒGNADv cJVHZ~-&V֛pJV&%m+4j- mBh1es{_Jb˱6=zAQ$laն-*TfcJ ^l+8/UU2xz!s'ĄE1my0+g¦펙G[).q^tKX:ojƯN5Tc;"R{4$կ ۫9Jz/UW/:w"e0̖0jج~_^T lvS_I)h@1:}rtKT @ =4lʅC1,;Rtfh]a\:A(qH%D eنM[S܇~G!霋{ 3ҠGeϑuA1*lDNJot #%Qem83$jSOtMKU?,\,E#8R\_N-q;BJ߹0q@hlwnI z)X#Ew~j9^YJU(QK`C^Y6JU߸m@pbWycAd]z4 ΂GP߽h氡9*Lh/_߿52Kf/ <70Ll n27 B:)b႑wUA`jqqXv:OD )}\0.vxLXH70V,(Z >OS ā Ii ȓɎܼB|$-5( 'aV9a|@?~> tA1)ݎ])b5aaux{B )Ik*񬓊E3>Y9fB%'  t*\t\]7O{ Mbi+F-7@>])(:+)䗺B0_03ζ>ם.͊rw-+@0ȃQ;Ԝ{/.FһjirNr혫n{K7nf! ps6WQPhw0qNDMNY(@VEkA <& 5fҏі6z}ņ|^WM|޽U?1~0֐ܖ<;T ֦EkHE#x9j[Sd %ߚY̋;'ۘ%y[+%uzJDe!q/bˮ\^dzeds չc/\Ze'`| $OiYyÉm^ĘIo_%]TwZw%wEE88$vFkdn_LVX"p%=~GADР A@?Ϯn%1fQiDtUeɖwXbB+y$2י hzTfRGΗ m24ڍἄ0Ne=|.>3EJB{&B#kZ zG(ߑ@; uC/drcp`:* 5|t_^W[ϕOӫ:+\O!0i4Q *e)7M'Wx> ><\% mgH{zo${YP=EY}NU.Q\_Lt5f"LLM-./~OK}Bves@^@Q`m UBswsՌj~urv˂J&)PIۯ%p,9\$*$FaoBboJ-W$-8g?Z ϒ!Wmy\|{RHhs?>7zE+@z04v*$)c@bHq*wy-^6uD2UH(CmW(WGvĪp9sVƯEG`ul xi\@.R-z>T*]@naA!_(2j/=Oep4']@V\٠]PYǗl #CXﮙ֎Ukwo:?Rm.Lyx^ŏ%˞— *K|YԳT?j>6/ށC25Uh0NV'UR{KdI5?eV 2#ML|N5l=eQ:FN^q Q\gNAl R\(˝%TMk4JQ7|Քhn>#~yK GW~%FEҪ^ۍg4vf D#3c{ZtM R5EO֐Vu]wߗJ H 7%穲2]RYCb'Hkih`W2*Tٰ>{ODHQ]w-Um6 ĎAcpÊ tzlSUыWT]duxɅ]7GoUj SCyjS"Zo_,\B-\$C4 0lh['C: 름cJ0'C FĚǀP92Uɏ? o25Մ HXZg@*DѦ6!S٥1v 7vNE7؎9_u >lV!x~>U\" 8"ATǃ7қ*(f!Y  xi)WAqJnG 'I'(^A6X6׬?kƝ%5n:)χ"ޘs;oMnmtka(zbʈ@s;~[a`llŶUEjwØh~G2~e;jH7 f-iQ#BѬiJӍp0b Q+9\P/_9\1 ]|lrohZaC68nOgZ!-UYJP$3^o05;c{ƫZ3ZecZb=r̓ vM92hn E5)3#sly](p\F٩{]C*jcJ*~Hբl '&,2_pSΝ_5_faenEi_ mk/=0?~3*FD㎕۪^HjǰBpIgH9G6CP 9v\_45T1""g+U]~.u@Pv%p Aڑi|AGR͹-,Y.P7<>yx]*lZv)ΑnRfFxhM`*nQ~jtue,bCVL+.}6E%gTt6~5q?E9U@Y꣰{VEwi)uʌaw8Zah(~<*$n7bϤ% %7}y7~I47FInHp驹,I<=k4u|: ;߂ѺPͲdG^dY̽X׆_2.X{C~.vPkc)LJW1b8Zib>jcQ5ZސriMkK ƇBS^-~A'üϮ}F: {&RsGzDs)_*g֩/-MC8,PV׿9A]c-7$-pD΂,+`P`5Aw&U{ɱ'1(Gڞ_Z0LR@ |n`8Oo ٻ+xg/Mg9`أ ަ} &Yo ks4ez- I lHtk1i^BS a'@;u`'@J7̵q| %5MӣsqE)X*DMuղ.y64ZN73g_Dm4ٳ.:N.0$ n;ד5U'J"pX"K˦w{5PoԁuwG.g&_M@QnWZI7?RQ[Q.^A/csmHsfŻV,kzhʁꭘ&B{0L\gL96g⧭< U]䯡g0$G@qSSF ZЅ$$Go"Apm);ԋ]ϺQwp)+fI <pĽH;0!u$ 0Mь(2f<ǖTSUEA>3+Ժc4b/mV;$)dgKcjR.e\EFѥFrw,-4dE@^C=O_'d%6Pa k}]%i\$Dg'b 6xDʊ][mg=V}b$ I\Ţ pf7&PK+*O݇̽bo[.5:=Q6X0{&j% N5iAq҈[p sE89q$&tXm,xu`P9¢+uD43A,jk,϶ aps)wKySC ƺ>8dWTD JBh^E! `-`< n&yjf=6gp|PμIByůfyKgXb jрoͣUпD#D.ybWInTV(vէ|4n٦#jl{iN؁ùֶpuH .ƽ,= ä}퀎awÕ3hJ>Q]aHC8n`U*XSQ8-kNHf5|;[t=Jϻ k"-w<< zPoϫMDpAx0 {x[7ȟ3ب7i"~὘Hv'bo0cZ2CRϾ,=1ljށpX^f~;h13B~?Ki$ۊﻔ19o;wQJqgVg@c/^&.f:4TZj:E{RVmRMWȗ,E#w33u NYhY@с:6ElVsWFX?{-#8u笲1L}c#%0߶o>̓aU_7v뇽%^bw/vlfňǎg%ǟ]_rxiqnʦA(=`B$v?޽8YUlv6o}V\ S@?0}|5{$6Oxҁ\!MH[l,/ƖFYMnL Lԕ0cmIJSRRf[RvðeW q_.B)f~D"楐^i$ݰ\q|7K}0LբO6wlo͂z$ 붶OlK944. : ,?RRthSF=٨) վERy3?%*Vi}B,|}6KusFȒl,>GB$DAQז~"XS. `DJx90"/'Oty] w/ƓҺOĕ+ ON~n3J 4=!kեThH%!TsvY)/VyXC gu|*>DSq"| :ȿa6+7`R6+!rn4^ FrN,|R~^ u|c7@96OZ|2?I`ݣ3߽5BKW R A]9P 604G &p | Až` Rx_WA-X=q $[wG+ ?]z޿Eņb1POs4">6D{U*m%OO(ߧ U +x^b LC -d3A) 2&f5'dždMlE. 3^]'#&yLUNkdi nyyjtR&OY(Jf64RF)(xChYONĠMLmkNǾl)H\5:dr>Pwn:|?Bn&A\L= N>>7LYHMh%$|hM}CgZTUh1Ry63r۠=8xqAx=ẁDm xvzA&0DMYhx 9\< H „a_s aH \xϟ`d/6 byDT@0\dnr^L]:ioF-H ҇a=w,ll'WyTudW@+q~_^/O7l1+ӃH'6@ɋ20Pi0W%=E#ۙ3A KNL )x`'GOS(S_-"tx &sBP{WE*c b*rݡ7_GYd:hvͪJ4#0ф/̆(d8I+1skqainIA܆/I88G+f%7SGKӆJAZ:N+r^eg̎yOװ3Qv)r/CWic2?o1!?ua9y0W4)w'6;ϐq //7Rs=~mK+j>.ƧEԉB:(bg? qwשצc QOO _}lm ದ&lԠLy΋Ssgz]є]':li8xXhKMg"t`Aa˶}@϶Z=".3D]QB`4PDy(9y1n'!AisIӁB會ѧ=v^=,Ӟ*" uۥ^BG:4,bf8qLY-&2u -& xLnY=|Q gE-dCڕR05'+j%͠J_Z+6j`Gkjag t$$o4fÌ'QoUR7k A=+ VG-O<50ι|ǥF6Wcp1^f tܡ +z3><\F{e2>B7 .?]7* [F5I՗ݑʟwSo(OE-_YFv3W>; ;K—X륶a+KQF1ȅĉЭ8(YY: ZClR%Iom> QY`B$]xMSOt=턭L]z95YOSBT BU&5 A4$~zaȚoDc5>%+kupvܳ2qvqX$ڤx<_{Nz_@TB#㎿捠dKe(%owWW)*y1"6' 'gc'oOOk?7]bA@"KeHi6ye6D!|BߨH5; O=0).xVhRʕNf,Cb ~䄌"v>֤-vp^s8IsL@iR+E~sv?$-U}@JZTڕ<A Or; /4 fJs t\Vӟ\Wz-5w ~obxܴ4WCZ Xz6Eﯣ=tm2˘tSv/+{ qA!IPo}]\̘#(=Ư-oj_{eR쒷[>Ψٝ΋։/_mjފ. :M)#l'H_Rx9rz JW_ ]rAykɋf;R& _+ze0s<{{5Kr՘7t*~1pisWLL9Q`E]5FݾVJ%b9H5)m :Aiv )<s٣Ctnz]aaD#˂=c]і罽<폹1Y方 ~"w(C^j-8e΢d!:̬GJ%C:Y *SH`_an&*pcraڶP`RէgL`_~;dBз,eS4*H8o5U'58`5<4vܘRw9IWk$R16ZZ(9ij9_ !pMNfj&g{˯ι-.ONy?0FYg$ Rs7{IƎV`W Y :T ?#a8{P C`v;02 AiY#"1٧S=pjlE=ngdv:^0p6(3`2kgMjN&{}!>\7/ˬXq4c`M\,1O\FҏZ r~c1 "+yN[I>l$iv[Es NȅA9 =ِ{̺ua^P\`a+"yaSMO8S.un9fO/pQ 3S.&ErZ㇥K؎ˆ5ZQ2'j}f6TKTo; ՚+w(jbzwHo4I2b,yrAK2Gg)Rhryd-$Dzšuj1D _y&BA M79wSpuM>o0Kɣjhk+1YS?m\s**t`sd {%2c@^ zrƆVjО!$|زqCOK][zm镡KxNMpg#΀MfQY;9؛^wl4 L릻gtyƎЊYa x4GI;(KSjJ(c fE+VV"js}hJML̛OJ@1Xd *7;`t"Qy=>Q9z=J\<,p짎_n1-4 ³kaq0k%ꢙq3;`Cszͷ/WS.arO:?6"K:FJ߭ϋ~o) ˉW}ԏrJNY |Յƹ);n`(Zvc=YrPU H9=vڝ ݚ99>N?ySh6.MNQhBJ$H1RAYzL"XҍcV!d`b4F nA!qyUx&#= І4BA zjc'|wN_CIM2I1Qr$>m7ςWJ͆ӲQ]8Z̢0&Eҗ)c+׉-Q١3 L7aCbچ?*f@ ^ X,:"J|i*ȣ,Pzқ$sFohnS #T:w|CǸ: s4ɌoXmsᡰc9hk2H,JM31DZC.'o_ G7.nTqpLv&8z +z!&BI޷㭯P /]Jk.(|{8ds\e"gIetg!\5+AIo)~ P"Թqc4b4S1{Flt悂"!z}`rXJV1D#M:#h|{`4 ߫4:+Fs-`Q&`ͰKDwsJR.JR>rTHI'4տ/o!(df`#X@+"S%1q>DٯAZ 1gJqbB>95$nRI u$૯C!1>1w|. _cس,ΐN$b@~A +F%e5ꝣJ`P< ^?,?&j[pg!A_sB^x4aC3to֒}zs8;gOԓ+jbh犙o)/V֛[6R[}~L\}k0CNWub[*ur;c$R5n `DRI2%*DQ|xt$ [)p0how+ ؠ=Xr,I +N =Θ1`1S֮u+=nJw(Hw7XfP8mT4 4j9. A<4D62Hrą0`ߩT@"T@lz{!TH%Aӹ> *)')?&`j b<^ ;@R /ܵBWI %@ɋ2(O`L_oOgYf2`BP2+dBQ2+CEH! QhRIʐz}ޯg߳{\+Z!*d KۧB,("ގZY<S.m%Z%yMuXJEUoDDJdSsRpƴ_U* kk:>ˬ~Fܵ|-b7.Y3'i,k:/ mWw:l{LlҪRWS]}5/~zɳ*znΛ]1ztVFRZWoJXJ5kǼCkWiۿa^U˧lUj%KiNF~c돡Ƹ]^S/Mli:s M4󂹑F6=z6rޓ,l_z6y=lhNğ:^ W<•-xwL-k:&zdc=Jaq=s>猺 yCu/wZ/vǺSAH@gy~W̕-ϭL5e/ڛ/ _׬nHX.p'$O\9ߍrM ӽ̻ lNoMh;`5#Y?&;xL?i`W6;xͩAz%kdoF_Aypgp9ڷԱ|rJLs2_|qK=f=@Z #x;5AC,3 h8~0fhyI?roؔ퍿)d4_pC,Exy#bI~SX)Unbs_@@E Fxj>ޥ:7V_7q(^wxݒ)j"DžnjvrP+AkKy?*=zwbnGa-iZ|f߷ZFNi^V5^^x|uC1|]3&FKLwDl}Ql!rg8ek⵬ -a<6W^ћs^ZAluQA>*_.I.-/KS uM'E.?6,_ksVvy km\TӲrY.aWtH1=N¹r'/Th/.%q ky M4)E9%_N3&4'T蠑^2xFjרތ\֥>Bܾ'FQjp#Nx~5Ua`0:Mh`@ 59N۩-[<328m׻p#SM!}o_{cDaRɴe ʍ(CW+~dҾ7+Wͬ|Kk5yC/G໢.IOgeNUv}^T:,\=:XƆd?Tzbd%]}W p&UmQɿ\3s^]A/ڑ蜵VqYY+%ӑ.ӥU!>jtNbyĴ3M{fﻁ]ٙUȻ[|e]7a%׮=xhV*=vo`x wʙfKY_}31<^"G[Nsi{ Zvt ,ߜZ*so2}=-~-Lvʣ_.lgBYocA %cII? ȤӧY 䴿~[=ZU q\JeH$.^NMG(7n;бt]7]+a)1@ye'.e8 ͤJpŶ]@7??} j y?n"@Mٍ-ս4tB_F[x[РF[p*?b.=2( ' :kFp}Zht 巃r9ŋjE{~+F[ )FTJ`?,I^wkMw 0#" }(؃;}47ʞpJP *Dr(<Ž~0 wz'FpqsZ{s8u\DT. "Z>) \H>'#8MN0 ̑Tbe@@J1ȡH mYg2[V[r:=Yo D"hV0N 6E_:,Oi,QW8+5dGOzs ĶoN坻nq<0MPϵ|G1?j1myN톙GaJ ]=y}M1 Z-8 0J'a? /TAĭ$/Ӄ\keRԭj޿kd-כ=3?SԦĐ[;pT⮖|B#Ny'M}˫.NG,9 ߜ \rռ8/ܳx_2nzotoNSAG.S1o|_g4^݌oذ;|hIX8>?!;F+"뿘njx|Ϙe<.""7~6 {QUb,FM0ZZĬ!ʏawm*Y^B7ީL8lA-oЩk PIo達="?!Z&[ͮ,GnQ<2uw vn_cssX7|#6 $z:~yBys7fT^=2GKJs.9?yIG${v?4sF: oO^>*U7L4=qޝWezUbk_Q7X෫x+2Gqt!.J} A;n :6>!&Q#BkP&kQ,hxA!|/͇ 4YzцˏOͮVPn]!lo񷟔jNuq9.Ǘ}8VNQZyp}C< ?{ ?+,P:FN]׋۞&X1<0%e%_?k}D/mHCOV$.ؑ }懹)C+?rI;^\!LX@3(JaUh|?ST ;$>~c>b%ؔ!Xsz=vp؁kk#c4C[d0g?\[2[̑G)',V3GUS.c?HEn8b򡵔)L֧t l DLnI9ˊӳLCӘK&ܛH䚢J ]YۏR5ur ƐyE7P`sE,%JX!zugњ8BO={s~X/P yuBW*,EٰpW#*'tzrh#Ae߬5;v} jnī:tstiO Ef#HfOE>^yؼ%)̧#m'f̝Z8wH T.Twt /|y6ag H̊ do{u>fGO8}=_Ľ wcN0e#r,WOG ^u}bQF>'׻Ґ+3;u zIOuŹ=2S|TenSk][+~hUm Wܦ6_![[t,5K-Rc _9YU1O(RGhfV˾.U '^/y'L=^PbC %x7OJFO=۞U|3uWf6|.SS!Zz5REn-Ļn)bۚ$nHl'ʹ/𠜕עtubIE@n}Nn_u;hص#ֻ>bs>AAC㨾AwQFqZ}MYqQ&djUo>DkN,H7~ hXX6qH}K#)m_zxy/%d{>i+D?.Qxyo?'=9Ap^+j":\꿬W4xj{{Ɉ4L㢱6 2ez;>"y|I~۞pcfd\S3i 4O99I? >;Tc>Ūs7գ5^6e}{l?j;\`QK.Nq,ʡIdRHXVgQS`bL]LI0u1 .&TV^S.6 UrEl N y;n jZ?@+t-n+'mJsF+9DӃנs?q.yۄ Zh$ ]~WMF4P)*e#8[Saf{F֢Ӹ臡wǦq( ABD4vp! 3' ~,~ DĞm.Z>/xFG?m_nɍ~ř,tm@ !4F"qDN&܈X;+MfRt4`*P4<@#QfVK DOL%LLa Vf)`78DOL#aSL: OL'`x=''G3tfP$02;2ixjT؀bs9'fLGfI).CHh Xk.$@r"1 dO+Yjh<A\pVL:]ALxp> fR |"vr1eQ2@T$p CxPPmX>[%>«9q#a L y0w5$P.ނM̉B ЭR٧^!`ߤ=3W@IҠs.xv 0?Y Hjd+IMKYlͧ ‡~E &Q C!&Q1}cM_#&RVg%+>ܺ)nux/ `"̢׶tYZDn~lq6*gom -`dڳn0c}=Gڐ 5cKsh*[xՙw+oLyYwggYM_==d޲"3$Y_ 7nv&A7зG['}63N}uok33ON&q>m_5t=|sWt彌<7j1I%YgSz7?ϞGLĥ_cf߳ySK5§/*;pSWUIץ]vƆGBsfwHS5+s3U_\PLG=/h}Q»ݽ]Nn>qr9 wFB ȡ+'XPT G:I1l:_@.N,s;;U[ztCW'؉;g(\=ԴrPX_z_s_!zyj+ JDϹ*g%9{LU=.~ܧQH{TBg}q%wg66exl͒MKw89gGr6Ŏ܏~;i:!7R[|9,:nq+ɫCWLjBr:֝׷w'ږjюN_߾FYm'K'_;%&>__֦]os}vDǜI"+mĭ+mZn ٖ۽2jmϙV-Zr(T28X`_J!e«wyU'||z- U6VX|4R+KX 3X!w:h'wMW8c-hyW-i}躔5eRrw ;ҺXGM].آ$a5  {_Xu}ȇ/Bd2&V"|I>'j,]PA,'oY{*G:dԑc_BQQ\p"?Rؗ#y$ k򑐜XwÕ}ݺWF$   =3_D3Ya', ݳ,ӵY74,%(f~פ~n z]Nvd8}on4g XKW@$ෟNjk8tPFqw}U?vH6BXtal {'Z9v0Lx9U諗)ʎ#o^ķp*20>R)\>2#C_%crxR󷊜+!T1 bG qߛ\ܶkGj>D6v(iq>k֮vɬ>a!YQ !na0{+z&p2-$ZbvIpϊxN?9AfWYɖm5&ɪ޴k^N !i_|6=n ظ\9%Ú]]v8}F)Imzds 5DRU뵟:ٹK!<`ým_=(yU\i }i^=F E5 IvIr=7<96t9祡3}~vSG3f"5UᑥI{Zqܺ' lUr7;Uv?͢]ٛ37|S{)smy(O?:ک1eP\qd m %A#;\޼q̎#5C`X2ȿ죯`Pc"8T{ej"b}vH]vr1I^^AWRTJ&Y˥uE-zƬ3*jPRo2rɧd> Dq%eO=Ҵ9mm]i%xMp#G ay,~\G_%7ƫ [vPZ/=tYof~솟kH1N6S{諂>OXdG5gg #7$Go ψYYE/bBD~y4O{<5>0(-=-U<.GKݴݝbb6%cSJs5;k~'2|$ZCwWƅ,qm}ƞm;~ *rvVM"?y/׬d=|l~2`Ǘt^o7?qexS8Չ^% .!ÚLa1Wr&x,:_rd:lO6)@ʮ9:9+nX@2 +lK,2ja\]/Wlhνs麲GcWBK\bVr`\lź^ʼnC[jm{qԗ6|uvBʻMtP}]M⎭!eE|=ksG{`(9s6aleq]r:Qi)+lu/{ʢ;/P/׿8Qac$r&n.a+ܝ˨s_MPݖ?_2;j1`{.k B6hB M;·~ ൢ/<>>V,it*v MH/B#Qљ8u"mqxA^34\nlka! De^9}^@26aI$dȀ_2du yq-7l4p 3lRR#p|i 2Cࣥ`ӗM)WZ p0WwUW;ׁ @3=ʎ0FLؒ< 8eHДM ,0T-wݠ 8ctƘc{@zУ>3Wgf ].@B7MKE1l5g<CЌ4#pUaq߫Y&47ׁi&cp ne̾֋cf[/˘ 0֬[6nP3hG .ĉ:W  E* \ d, ZD T@3HOdߞ" lOIBtH)_47?Tba @cB@vY5[%xQ6;n7DZQx t7*H H&g~FD_=@ [?&|eWd#++B8I3ԃp1p  &t ӀH@3D<l!$01(+Р(#! &܄HDBDD$ (@S 4LP(Xdl(E =^~ O!JHBof@Z=Y;&`օ@hzKz3S Dx4<@1#6#6 U*Hb݌. Oy(<0Igp (3\y0oRNNi>2jH.S8(pJd`C-@t + "-p&KZbP)x9gD6^`%oE$<<5,4 Pa +XQ@I ` M< EIbH!b4ϧcD=`Sg %2 1`C٠z @% Fhs"Vv; Tk&,*N) +h4'`ņ@'?XL@,)n:Tz28R-O\?{.!$N*DlVC, +y vn6p]d0*Ѿo," h!X3D Nn_( $Mt#[?0-$;@}m K40eD!æbg{^? >L Q"?{!{kP) 2ly멐%HB.D\`@[Y!(J79*}0bGK-D:H1]T ] ~AAMAն fӹ | RlM-8 xnaҀDȾ/3\r͐ucoܠ0fU1$~0얲vHCʦ'l0Jyk"Y.C_U슏7n$χ#+j^s 묌v2 iux3.g* gCS5*W4g*!`}^! IΧ)r̄1|h;ɓJV[~lKgf'qV7Ks^Ս\3ZU<]:QG´S㾜 ?=#>&wĞa}ju.ig .1+S( j 5sRL  ̩gֶ66 ;]ot1o3Y:Qh%A^E|4L1vmXPqΣAr?? 6;6U䑅br:7Ibꙵ~BnΪo2CK jDe㣼NJռ{~ul:#Woq}Y}/uP;q1C% H'ζ;Ѭi;j xim5>uKkBWHtѽȆѝKJx_ڻݽ/l?%g ly#I3m((T/{̖⨮NW,|i7*~زIINs/O6\"mq4*95X)ƑWUڡ|\a̗ܚ%.ٻB[V"Q;*M}9ohUwWͿGsh&wнq2yUN매zֻ/;*F(z[0^\[G:N*iNdEnO1vPtbqXäk­[ʪ=|7hɔzi(lxP5j:_ٜA^g=KFEʗ!.U7)jr4ӐkΎʨ~{/\8ܸQQ%Jkז3[ruT 3:Z~;1Ԇ" c]Z]5&~O}z-:c J<=7BKrx~PT}TgF?ҟr7]Թ9Y-„ʝMN=`|.R|gzf!ʓv&O,l~a@5v&ihg`C[.6ޢ ֮Z{jjyr^rP"%)Fqnk7}O`]󣻓JЋT7BFՉ_[I~I[9~[넬'DM7](1w}:F"GɿYiZF)HF&/I9x!AInoH54PNה֮Zee"tY<=I,=:w(,t8M]_ر?Kt jۿR&K^wxfχE/?]AΉ U-O۰ŇK_2/|6`#m*ʘnU_l{0AC6iH~y F6쬯l`V8N#Ƚ tQQS 6…gSpe\Hכ'I^ϥ{.s|W[fŁ 䳇ƛfܺjjq]gZ*}N{n"Tb3㺢t#/Q=G_4ʯ }_ev$>5}d8hxFREE+8WHf_`mqYtFpC_%`q֠o ?޳&+uU/KdWZ*9%GSeSJNΟi S:P<K te&u4:Ƕl0A{],!3D 0)l6B -΄;Xn(h>N7-P]y=m%-"N-=[Ol l_Dhl6g8،LD${Il}* y_4he HڋM 'aށ̬B`8 AL`}R$y"z [1a`" 58ɧC`6GԦ =5`p A=+ÿ2@ gYd &ZC ΀ Ö:2jp?$@9 ]ʂ_Pz"s()ɂ(,;oah- 3Σ@DXPbD_T a6j[Eւ(Hy 0տX` "h=X;pCT!P4K&f&Q :paf.&`'QLª0rXf "{6r 3 X$=:0S>~[^QLE*?^6^<%V=M>6\/T@ei6 xo%|]j.+cݫKFFY?Ti~ӧj0ujI9-ArT.[;#hf3NC g5*x"WVdHg?xX,G1Z7ѷȧz#\kJsA#GZ+ v^T58; ?j[nq&p:7V:+3ۈWDnRۻݾm6ZZxfY%{1½\Y9:iً)9u7kgy=F׋,;*KnWn+x`hk*7 gU; 55J_4QA8"' RwnRKm}dN:ksYC9-@<}umQ}C#%x۳t>oFgs$Hɭ.?YbMoZ+8vOnv8;?O]{M,]d5rq+<+{?304 âBskBPQ$qa0('/BL3DfrM-d̓DUPDv\QΩ{o13Y_%V^5`q@QW4@baOjy:{i+x2-kaUǾBc⥬_3K?+d&{eTz!<*e:*wMdgȊ#YH$Mӂ Y#sLG>zMvjd|d 7<{lƒ$.+:xAPĦӵ8$v= }-i5:F$;l3ZYmع#Y_[!\&]jByuW4a{?klF F98l#Gб#Iҗo)ʥRYT|`aF myEƊ2Fuxs}f-13tXW Қʍ4_6-H1_Di! B~ּyeKΒUf ,9 1FGhןLY*M Ѧ8F7Q<'} dUknf0o]C{Wa]]YKLŲuphMdS͞19VU>*rnc^c]78z{7- ihɩ8؃>4ΝL:Xd1_B|1r'4`yԆ]03`bySiKK"T7Mz˦~m]+vO|iǕS_ qrqr5'n(vѨ& tSW(t:&e.9pʦ3OvSwQ@g)޲ֽD<2]v8Fܳ!ݼmj!$qm:eSY㎧8e"=턩DAϖ4瞟׆ 3؎@D N0Ϳ~w8z$ߝĉJWѿQ#*C O?'K;>"V1}X~SKLŀs'?"6q|D_@ZO4Qa*WTQI(g>&ٳ  *⼏-&Ou+iݦ~'n8{e*U鷮OpmzUZ͓%bm!̹ؾ}wNelդ;iLG91] 1Lw}\eUuŕRĻiklC)ۂRTm%^;$Lǧ?{٦^r{J]:&:|ݻ'kڌ&@휸YKԱ혪TGHO]TަmFLGAJuʛIk nW⎭jѲ9-^|\42GnPD[v]J:>,k@׍JYLs^e4 C\i NmMtNM7Ke>&<vSi~no~5?oBkMϕϾ䟺!^?_՗Sz;KŖ V\*ݞ:$TWi<饫.ϝi2jЦ']{57Ħu-g_yHۨ+/ҳ.?]AO7\.ߠ/WC'|: ZP?k~i}uJW-gqMlVHz7A˘Ŗ!VOژ^w%}zt·ŪAtқGG|JwWQqUX̜]%$M{m?54ỵ3h;|Gl;D'~Wp3o׾+^:jǦǧ~٧~tYU鈫E0CY bn^-t.PWS}!MJF;iI%dHL^# elT ?pgplS! QεbPZQmcZ Sb4%|{V)D:be׉ިQqM+{ƌ7gRq9`׉:W5;r<෴1V1fjkg<7_|)z0-MFZ;Ljˣi6AlDWLKk?zw?A1U{Gd[7 /zxV1G$LcNPqӎ拏%tLd]pWpXfӁ'fι^g|5.$5wdE*U:%Q<&٠aNH,o}<-:S1=lp} G/f[ H%[> r>]^#~:rب*`;2ܥ˩$ /ns܁do{O*!HFFY+};>}$6 < TMtm4N11c=^-\:v1;!3M>!junX/<{[h@ӴJ29}/3Y[@_#O!wCkf=s7 aZe-y;ntk+NT8RhH0+7m1:~ڀv]wٕ꺶Y0e ? 4:*fP4Ju@ߨygśs֮j<$/w]8ju4_2A j

+7Z {惭n/<\?~VuorJ_P7cQqZov"5}Y^;YG4&!Qe^'}駑‴#b!y]߈fu\*lDŽУbvSPPTi7bëI],upW#lW%Y Ѯ#e_jm#E^(3e3_ߊktӶl#e5ݕsULW6}wbe߲Z^n'+/zʙd=ve Y4ZxX,>#KE{;z4h0M<3FqA҄^q/ُ g9<~Dč>,0Ve{SzϩqF7Y9WY֦f08;aZu}sg=*^6 #3`LbMk oݎ Ϳh;1ttFI'. ѐ~BĪ׿'3$Wb& Hk&3cipCzp̧rIAlHWOv8aZ3 nJq h_&􅏋=3Ok֭X.",B/ vulѦc+&LSr!4ذ +&ObaWds%M<%6) ;ZGZLe4tbk޴"?GLtSLbn5=)sO=Ԗ˩|a˲ _QǯRi:6Nzd4$ab6XNc@B<3)cnRܾWn"lXqC5OO. 1!%O N5IDק6*l8~Gt{e]ܰ{K-b3\>/sԒSk̐F߆fL?S[]d#;*+2–l`"Kԅt.ÕXxg}e?ˡ:dC.1H󡛰ߘPfiTnzlb{"Ku}~ݫ̓Z6va93o؜.C+Svnne,mm'Յix<.4uN.dn=i'VĪ֕I%uF]9'}Iz#w&ktɈTЅ6IяMX5|֤򻾲jĐ(jn睫j_3Qw0˷+ok}e&s0a帯ԷS ,pIO{`|kQ/56Z9N.PV| ֥NG=YZGG}Ԩf*f/s6wڕCu9Whyv)ђ >m4ʬᅬ0ze[ A]R7KLcbNQյB`# JsXT:C8!P aP*@IUvii$,ly _( :Q@pf|%2>US60 ҀV&-0z H[+#!ۃgDWse-(X*4"TNgB|ګC\KN ̈jQ hm9VYG~*.8Fi.%dGmGJ*+ rt|% >?"r֠,{7V[S&.7{5#.]g&-gK'%DoMuKR2\FguO &R9R eD *% Ku_!4ޠD(HNe $d:D^W% saino}Ť- )O*%Ƣl[FwWM̗\UMЁc:\Op5 c*ǒ2 F,+[gPrz ^JK#Dv@%.IVIVjTBQ@"*U>U2e$N*D &łitOΥ#x `u8;Fa lGm@+ ex2W+#NJH#>]4 Pdp•F:XhPEJMYˍN j*a|SAiJ&WHdUa{VgBu&r¤a\C#,C(8HYQ\:'yP4uWY$v+K._#4 c rmkgО4|*ôJ AG dg4s*5v?$8l v#[!kA S!W8tZ(%n}|[9)Dhf)/!k7 ҉M0;£Rm f` Aװƺ2ԕd6AUOA"Um^e .@A_S0l4V!L.lDi 8=F%,08ֺ=.`*ZD T#Gcy@*O|H4‚f@vf> L )]I4!ka?j_V 퀬}+/ 'T=,~yu t_ɼ΄1!` 68 h#A[$&$ [GD*aMfAPHs;44Ũ Zʀe F,ĒO YK.GXS eH[e1Y3$O+p} ,>"S C\\~jaIu%4 n BIdOIt0Fa΢ȰD2 ߥrx!{+-۷՘B2 5!8bDB@&sXp -f}rL`5,O$ap1n0' n]Dg@İxHAuCw|x}z 35Pű@$@i@0vP&8-h,B' ` E%%)_|@S࣎0_z%;{%5U!+]2# p,@q-c%Xbо-rܼW:*kX:R *Bd=fjhG]^Vdr;r%"l (ƄaLaJ],c KYrf9 ,9"0I䆝`sbLVIK[[|a1}pGG4$aHeUzryϱ18~!+-l6I%K,\jc(޶Sz$KOmskiqT&p@wRɌ+p*ROa| ЙѰ%|.J[^BBW|h K8z B+`:ʃb]劳j~.$RRHM`l$`&ֲ@{F`OqdayȢ+%{-c|Fs3+C"e%ߋ.gp^4Ƥ!|G(#\]&F)KEliPpT:cwD༅;;ٰTn+r2 0 =M=71ڀa$*-0NF}=X&ʨ,N# YpGZ`i Ozb}tM! _ B)"*dFu/6mƆ5wI.lu nbu2@̖3Qyga˒RU) e>?. = V Ecb9"U!9 :-P. @0PIR6VqLt0Wye-$x˩M,O1rUV,n(LaCs0/ ҝ--] ,oIVËUTYwXHqðEk إs_x*QG B :Aע)q%t RJ#l㱠j4AI:y%І' H2bU*cxg`t5N,t|]B v+Lo ̙ӣ3S@)=ff`W @ȠI$TvE`AVlFUa$S<]rHq0L6 < LLG~~S?O݇k$_N:o>6}0^_C &u|%`L羁>I@Ij>\?Do7UQknRʧg0֧VtfbsC0!]A'7NVjL'RM_KNt } `v M,AQC"?LCGM 1MWA库 [Z[ ۘV\mפޗ39 !ŖQWXvT5d$ 4& 6ɨ4)c33= زt0]q&_0T>B`dqJc9ܹDE}' 62FHYG;ڝk1tK0HAufIJa+Vp 3f% +">,I`0%Vɗljk؇ё KB*d2vR2>س7o!NUqrI<&.KОXC\RP91?*P&ΖS.T)1F|׽ptN0|j (6AB|U"$B37)myG9 dc Ԛ! i;l`#KX:!QB ٳn˺Qt0u[TـXc$I(=؂Q[?G%$P-03={cAϤIG0YY̖:&Z+`ppDjn @L33!( "_%J q0S] zsH$ڂ 9 4bVg :7ذaa־xf)W:xG[pJR7Yro~/6GWƴrroΥ`o b '}YpʞxO/ATxc`,b8z 1W'lA7N F `p2[uR!i7 aTTWr W"8}3b8 LaH[0U uDۃ`,5/5~IȎerVsN9]a_s0b/(ejW>gXЗ0b GBrzDC; %78 qRi(g &i&`aZ 4 `<` >O 9o}~JC9aNÐ}Ko@| &Tff4!7k 2`Kp]@9vp FZt"r|8۟g1,,TDQ^=  i >@s =e)`ՠھQܵ r`I0H˷;{@?`C!U !j4  ,$X unTpplE\%-R0[K9XQ j*F jtK) |SP ?WS Ɨ%@02G4Ȣrjj=Ļ} #fo`5Ѣc,:Rc@0KN14\#@2mL 2?J#&BGR]L#7;ijjOAm|v0n%P%mtK-cv{̌|+$(00wBcj`ݳV4hءb+xAװ}]!ΆL{(%QWXMUwOfҹ]|v/{p+/S "]B{I,RNS;\pU8awڻ9`p߁`wiF +gSܽ%N0%Q/1c.?YlxwHa+zˣ CwT$vEE$5DGS,//L崸Kr*ŲG狴eAZ&wҨ"K fn\~CI0HϦr:̯G0 Lg_?IWnJhe!``A T$u0|e+HΞw)kxrZO(r&=GI:^ɪ-i`bpHds|^(Ҷ$--Fvp``$.H/z$x" igej~: dC%%sa'uV}]yі.I9 qS*D3;B` ^ˏ#IMc(SrtF`T)bRz Kc BhXsI`dMe&u~GS/ syGEwys~ʷy֎SVfأV?>xlu@T٥C;e]vnPn;d)n8 Hҡ4t !)o~~~͙<3ϙ}WdTP@wI_1_ui,5ʖ<DYb>U k~՞ .tMs*4,i"[Fހ\ZΌ?+_LOgݼ6g$ut흗B4YŞ~f#a;Zg`FW :Cm6c2kxD1M(C9Ky |bqjŠYnz"nMc&׿8SV[NUGcmvO*Pm)؋Go<~{r2v;}CRl(yaؓ6$ڼF6fx8nU]햒lܵد0ʉny'DCBRr:>3M%JS&F#{A'jaiaJ1*Z:hڝ8{?gyecLu'gPzΫGY}ىvo~ Q奵気K˻{e[;8hE ts@E[>k~x"W"!}~@u=~?GCW5 --/GdK[of*cMwD=su[;[_Ot:4p(i4@ Lܧ'R&#VR3_m%cʘk@+0JШŹP'߿7 ~{annڊQSNuJ B5\/+# hIu>i04>\Am]t'\%r~^M q \Ȼ&/sb^n}:7ȍ/Œ_%OC6-nzfqL o`zϜ_4y4?ER/5>2F/wҖɱ!ȅ>.Ht)m=) Ɇױ;cEӾ=%q%b:FB4fު:@2-d|jPy\|7mC9s7Wp3ŀY]R+S.. 77g]5 XpW+ut=8vx`5},4F7)퇨pm(`YuH(KiF->E<_=Ql8h }%jn? W%,,،Z5]I'b՞gV9G8֬CW~KR@:mɴOSX#]J4>r)91)2*#)'mD2-B֝}uy')^xj:g{J+>ӊlg{б2WN}U۸ٖ][1sQX {%_WW4R 982H<5{3F㲙fU%UB:ѿl!n˳j'QlEQ|HC$: 91"nxA$ ^㞆I(d 8G s/Nef,R25!6QG~ң<5,LV~?.6*Uf 'Gg9~brOOn"3-B^˸ݝbAnT4P!C" ra_bUFrS^Ye0hs(z[zW{;?#v~^nc2w9IzT=ոWQȥbK 7/PWH"xQ2w^3' lѨѓfW5w=/<[A ϜhEQ~/ٿh]&M'8;:)ep?Fνs1WL#B--PToţ4_Y '%D >XE"Щ/I,6ve[gبDGsJ^%ռq9u0wm!z9G<0*&ﶽ>@X|ۅl/HY,H15Ct^~sقNHw̬6gٗʉ t'?ԩ0 1 WvyVmƌ⢼{ obFR׫2/(3v3.wֹ8%ܹ{@ [[ݤwa%}4oIDfO _vOPMit>V&(rtaQ[7FBHmHl˳)>ǣvͧ# yciı kb)Igzb`r2)VrڂKI:Al?x'˰I,OPb]+`)/UmprzIqwLdDnD:oQGH\~= j33 Unu?tz^EYCS*'r?7fZ=vWx}I( 7o]⣅,"{kc~ʅ(-2IPu[>gH.jZ/8h8hmP9p`KP'IEf㲀KN#>hnì׉gKe+4‹H چwV9EBwg Z "}sq5d+DĴCl@&X ”?!^5V*%jƃ|;\c}mYka'5[ba5}<[r~i}n(җd{ _sLH¬(Qr׷i4smgl٩]Vyw4mQMoT7#?3<扇^UUk7A2;1Qc'>nOH3,a!:Ŭk"롒j|Ogvkrr!J r"ߏO+!]75Wu MsOC |Ak "ɚ) _+; عR!i!6?.F^>ɚZa*hT@҇#Vc+c}ȶ~}yc'v%r/1>lZϩkM~E3vQHLHz!ӽ|QP# ߧ &*l+L. orr2y+%ShEFē]^w=̫9hDNe>8M3D0~~dY+geM1y[>FM8`2Z\BÐ4x},!y8w< TQk\?' 5e3PiS+|K 4 j'Y"+aњ(wGݏVck~h[6!nRE<]5^Xrtȴw?+m󱡂s6uQ[Z=l\~.Z&!&y2ohE6e_dRA#ɚEQHkF urI3Z[$Oj͖EM8Wgۭ>b;g\-bO%F7gSUsv͟9-Wg\ܬZM^uo>k8_=J~ߕ 60f jO@Tp gGC`"0v$T"Kɉ +jL)LBEQH8@i]2@" OA`p( "eӒ\yܫ$(%dG$i'\` zD%8 ^) [00R"\"H$C/x!)whm/ FTJYG{ ^ jyG s96.MBmڕek -tisyXX-u3JlWy2UUTO.-VUԴ&FB x꿫DotѡM3.BJga6U.oh XrbVId]~\~@)+0)ϋl^}^>xXn A}l!*!(Z+y;s~aaB. AP5LTW ¹m=Ӹ&tcՉM7O^8Rv8'*%J5id֏gOyz9pmOɣ9ډ*Zܑ׳4;[XFY9C"=iZ&x"JR VA eΝɎ>s -G{귍䙒±G޵`ƜJṮQES\:|uwJ7=;:2J;Sb_S8+ B]2ک7+s4X)vIlTMor?/]-?k'6=*^ޣFDh"1+|w-v.,LStvcv iS!Qc<(^Q5&ib8n}3`5mOڄݞ(Uh{Tiѯj,gXQP>0bэ~hxT7]v7l͗NLnB1O-L!\ AlrLN +.KZ.W#QXij56N x6vME&]_=69>OxOő%K6 U.OxWʃ( K<łgUJt=+1`y('ToԜ7kzx?\8,]l_d"].g£ ۗvqו{mܟNNѻK3g`A7uXZUz[[Nuw7äxQXYHUX]_j89t }Ț8+C?.KTuRkPCR/ o 6N6W[{{Bl+v, iabdnN1f8nѓg-+;luG}ʹGnH)4_$J활.ynpfzYf[8nx&yINL5'+Zxu?% 0ݘדZBJ.Ze Qc$Q`/Ohdon2{:ڴHp6l|LX{zcn+g 4HD[!ky4ݎ#H3hJZ!o_3ؤN$Լy*ߖrK^qI0߰{ *>M #qꞟYJ|A6 r?\*d_r*~|'WXB -Ra; j')w,B߄cO^']Q%v:w )i^iuYdeJl.k@,*^oO0x?ptfXؚz ݇jJ]MٙOzTC2(NV) ~fX5+kZkz4ֺ'YT7>ۄT`Jd xq蛽<j%PW_t9_PGqyw 1i PVދQYVEg:P!iB1^ΗކkV |rpGĖ'xgϋ˰ݢtI#ywL GRp4 ~⓾]!lWP/G+x y+k,=Կ V kڞ +$ RCIUOJVN"-<Kz&?W/7mJQ[J&@`*CDHG #(L5A!xCXPmb01 56 OC!" ю)JnB$kmrI>hL} 832kE'r`g#'wix7;<} 82,"?kDˋVдb^1in&O/1VbVA~kks@dSy.ȢZ_hIﳝ. y=˖lbnat7I;/R\ԍ]kJ2&|<~+5y+DtS?-5ަ= 0/u]\VɤBa+qC`ޮڨg\QiቦmI 2nF"do}@j݇^cGR8vSJ-=˳mF}aDO__k-zX GaD%Ya{H 8Ox#g~r֖w~/Klff *]4elv-71\fhu|vJ멷Q/{!13ӞΈAmq9SWzɡ,o(+jQR |q7}y>ƫur8޳HNyG7j4=,5@"gQft2P /oY1c]Nd+ { .xv@ o}@Ýy:'V/~p '䧏 UԮSb.k/%*{:AyWY8.^S+9""[bhdx&D^ g:aWEQ>A־YOz|+vDX&bb݇ᅰ0.SIRqѨeEȱMD VKġ <fNϧbIeTԺy>tZ@o*rhAp+~T];,ȩϊǢ%-λwm(lZ-V uϥ9lVNMq05KzAɻS?=zTuG=dC! HEz-Je)}jRuyC=:Xx*n+a26Z/gQfPa?tS!+#I}A"%oBԧSd$y[G^W)r7?F(4kׇ `B+~~C$Ror4iW&O?Jk.=Rkjd`\م9fL9^e ٺ>n})j"p2S"OȰpվn^cH ݓfgiDp;AAR9o6XU9~]J||rz2XOygc2ɫ҆_0r-n߶bpP/ߗH_!p7#|t`* oawܲ/vMpTˣy_w88\ylWЙl -v†e҃ߛ9R)*E{7xiO 4j COuJjLT'ES.''ESO9`y C+\r㧅! 0qv Č&""@ (o@ a DHC`(L;$ cGD!?'PClJ0e> E0-HD d7 EE!0d{a@3~o=H!bDCH;RW $5Qb8 .DA(8_ xD5bRZ$f߃ I~HZ׈ .\F9UG r`i)` BcHG3.|CԿ48" 0}f-  30? "il~j1(?4 V 656TT{C!oÕ::>F]PoҢsD@Z5if [͎m6Nn֌c6\7&_v<SIzVtJ1ɲLL7Ib﹥T>+Wg*T2''(p.I! ɹG&GyM/5H /IzZx0mkcs +(>GVT*U׃'G\KbI1Z/f.O";Rъ KxJJL|S⸕Q'Dfh-yre#p!_ӳ~{ƈR5}6G$Lv9jwH7^bD}o{Hai [8+A5Y^@|Z/85]KaZuIY'k /8ǽi./ӗҟ!MW_;^W%.)%AiHcs"}\$Mu>7-?{.q˖9M`>0?JI}묠OonƗaUVj9gʌ ,M5=p ɠN^~ 0\ʤc fP'pwp:*=>?.+S6aNIS>k~\RZ$#y~ԶxI > :sDɟKϧörbeQ4O =x5MF)R!2ڟsơo^>`cڴ"JꁦU+o5ɽVщFA= 3Y"-ws=7V)*SXQV w7| bJObPfƤG 7P1A]BL ]rToOD<(vΉ}0w1]^݉^к2jWۼ,d '$XL MlaP~*Pqa)( <\{s5MiqA '߃x;'39A)18r]).e(3]م,ͱ#T$~󇿸⨺*jW.VLʿI<9:{Pڭߚ@?}c.nk*JQ(W*$S q ɾgrM0X֌?nyӁE <y;t僷U/jֳOL6CTRNfa5}?L\TƜy^ u#[x <6\&wk7nީ;H󎜲fI3S>pZ.GA4w< \] eׅosʟgۺAvKN%w  m ݔxm\ >'_ TdHӍ_rݮZ˾*K{ZFgd򔁧S5=Gʒr,2: F|qsi@<]fȺL|+iLXt Oq^km'v7GAy;}@z٢bܟօe+vj"w)}Tִg3-l}bYLYE^r4ˏ}0K3/b +V~b}`j7ڠM~MZ#lx,\9i`bas*h Eb0?1mioZAiBY0 "n4CD CAkKAŐREAP8;\#`‰/0J &&ȰXVND|:4@:yFcHEq +_ 0žab&@$ +HxBDb Azp  e\ ?_RL/Ca`<>t+-P[LD1 dx2 1OxThZD?P-$+JۋS{ E<`9H$W ؛Z0QAV(fk?PMLD, G-&""A$&aS]t`LF]qtjԁ/ F%%>6 4ebϙ7Y?eԛ F t!A( r8a&("T`jZǚ,9gV6i^VG2F-msP_I`_E^\0U}`*w~׫ 7RݖEkMH'Ge^b7jj͖pV./,o51525=߄b4 vegԵrm *FAgޢ!Mc䯜]In@ LϿ;m,qgA_)_pv."Zᓵ1ljI܇$j$ݦ}xUO?:mhy=6]Rjk. U TY{݈lC +ٯ=[k-+ܐ4\+]>~4)Ɋ@K-桿ZoxDYAO6MGj Z){w#-?Bօ'vf^{r( gϟ?)``5 1|qF GYUi^39qGyW^ Jc: ӨJuV̇֠o?1Ot Ɂ}q9i/6#h/r6e~1nܪ{\45#okxOL-he#0ʢ#Үݸ-"̙VúU,Ex(PE{07 ˖ $^\o{˯(x/G7I)o={j {NWzgTlyR? j? \ߑn@H†F(G "%~bLE(R@%FۂD PO P,$rKD`F # b MXH 5 [c`] BH?n%!a @Df1?8$7`\Fq%  @25._cG=|@ bru&80BvDZϵ DDcrӂ)6H#4G!8% _#=>13A#F;t!<k]/Wo&]XhZN2,o4xSzmW!SʗX.8dV_NGFo0%nv+wU3e(k9I$邶wq1ӵhU׶k+_fvDgG Dy(u r;P"9[l}wSrO]5sKOSIB TvIgÕV b^U'>sןMMIFmWz럽S ~>:7~nRpYyI4lKLԦbOMS 0ӷhy~eU ґD2Ru8p.|)ȹ*¨"Su}1y)wKIK4MJ_9x$W+SX|WOdHHm*0EL(B&#T|M$^єY;M)φRmD)+ ^~ЊJ_X sMI0 pe(Ξ]*PvQ~ìP,5+~G}1KυK,1d`!: (u9? [.of1Bץ9+.9o*[J UrNtt Np6si|߰yJ,:+mcl OsA=.mq?@!jl QzGr\F z HQ]vu(+4S\Pr+5F0!R$inVw,Y=׻ERX"k*{QR5i,Éi9;WX:{QOvpּŦQvgijW)zv?@~m\ 8?>ݝٿ3x_;^)ayvsy~vԤCx;~W@[)v%V4C"w}iF=8muNjcθdd%htg㔑`k8 (:^| 2C@ [bcprSAqׯ{vvH~hcO# c^Nm>2RB>$% 5Qnl {-:?A.KЁ~+yP-V0T>*oыGxd j~螡g&i,刿z.:/(){joes.=5X%􉫳c3Oh=n.Fp4ov ?p ݼz%~W!t qCO A̸)4w 7$R`{\koK@/Xei0Y{X2nAe~9W2i.*3~㤓A EWDa~]xT>M||F0=z6iޘjGC]}vځ[4 ѻfNj]L}j%!D ݚZ5:[q=:1|N\&;eզ:=%ЎP;W o  ff`}gtG!96]iW+FdB+y7 %>SSG#΅Eƒ042uAwNj.+.6[YCu3SYA '`Z}NVFFaoK!Pth]p鍣,MO!F%8r^OOW1/Doyu))Uyõ setH ݹپfj*GqQdA|Uvss!Ҧ#,V6jf- U?LNꔄ/4N+~A'tL٣_KDtQqheЁ1=JYchF+TB?(z^@0P!2Jїi`" 7ȳJ78 kJ(Ġ(R`%9sI*Ҡ2@t#s U mwU[UPh3 1/٠K:|;%pdW 2[BMUT5BH,PB&|5As uY8b ݊(Fr5+&829K !)bI!8pC m &4nkI$U(af+CNM. goZ%V%v'XHhpinpB"p_R%0.z&CЃ})_?}>]PmL_crOä9I룇o`޶Lg>s(n-fX>}ɸ[-(Cb^@Rju5[dvooU e o2XpH`>5K.@/{ɰfHΣ _[dǹo~6d|e<Nsէ'%g/f㛃- Ep. rG󖨨y:\{ /W .EקMq5VG>*:*"s˖x}CGik&SK]4MhVQԇ'n8$J4K Zhg33R5tdVKMc,#MLQsQ="NQyC+H]aKLCm:V<>UqG|p1cL9iʬ*ߑ}$IӲtrC%n׺kׁy֤й4(Y[)^/\w=n :x%xOꕞq7:^R41wt,gc;bZ.t]+|3]\;ծ}lƪQYOD9I}2^MBtwȏ;qign!{5_e7(L9EojHMiY|>CԂ܁MB|CӮR;CԇG2F'VЈ4E~Bh}8  , eUN%"2})?).0}vI8SAddgps`ej8s~_rsGi۩D3)΄'CT:+/QZs@rQ#;n^J{Pd:rf,E<8y#T>)t!\7Kcc7UC)0L EGw6U4χ&.͐a/eɁvE޳@p4kRL>6Fri!H:hjbSݷ϶ӄZNR+GQ/ 6ZEe .JQpDZQ3ffSRIe\>ӕy1v?2ѫLJUC_.*k4& 9 8zQRx?%ӍRez#=Q/(i"L:0 I\X[<_f$ %wdQeσ`~pTe}R4W' v>(L5NFX0i p3 d$.(39ؖPJ{ed$L2]@/GGX DZ\-ys]}{E;ʏkˬ+-R3=Mܧh%5nVO1l.]v*,/kWnAhug{6d(+7M4.#KB(?s>#%y{Z)d 6e90ntZ~u/k60$G|E"6`/a+ϣzJ)sd|߽U¾e`c$u5}##6KveePZ!ǽkY&uS+{ۆkgb]i4nJ#[Z KJ7[2xm9ic♠V/C@bxt)vyQW/"[{%1^+ %OUFZ;'^@ù L\ÍK0=zTZ59]fNO݉nvNX3w3m{(W"OZ^?~oi^'Y?%پlѧ:i#!*}3 SymptAG |}0oDގPdPRJ\l8217z{D\C~LÞ{Jj,BH6e ' `/1LP7ɚ?}yv1֍38ҟ^jȦ?0h1/Wás@oOh b45y)n|CKuĭ^?Lz/(ZV7%j\(_ i̥1AΩ.BN!A= ?r܁;bC_W44.ddi֖(0 X,7LgZ`c8 bIaJ96?ХmwHOP82,IE 3pdΟ F|C le\wA:u%Qy(4|fQ |ɿ8a1sQP¸1@wP桔@GNE}y=j-> ^.>X?F(H́R娵?B2 ^B)T˅BG%}U45w G}+Jr aj0ps *,wPd+]3Ea 1k!A~PɾZdS)uwF8k#|Ն m?SDG/Ӈ,+Jgg|y1ۊnlG.B XIGA!Gj89"̻]Әn`cWoj~n)g@I~deޙu'4ܠKӍ!`O|`2Vo%OE1_e{+Q *_چמ4q2Y)ξ H*GuYr8<]}*K1~9^^n+=svn (nyqKF/OOjꨐu+UF~ hyzHGOSƃK#2PV9>B/>+u)CjZ̖{Z*C[2uw$/xdc~eUj=S"O~ɲqqxX(w]uvSl㝻؏~'<7RoR[.J:RU1%JLMae*mR}$iYOIe/~ԳQZ&+q졗bk,|*"=* - 9|,f"]|H.nEfdE-?Qg^ }4Ӡ_7LѣQ dOaهjqdq g 䌅ל.ӯIQ"2ţ2و ڸpɂSGj|IOY?n|g ~Q?m(ajtd!1&Yz)h$TB_d7!^s$;&`i:<>L/7v%-p{?Kɚ-]Ǯ͢i}ù:QAH\="E, {V_vEE&,n Pxai*r7UHu~b&a|~g[!ӓۏ&s?+QpyEZzV3gJ~ԳxWRTC_H=.sښr#G ~C5^*u]I9?l\.֗MϴZ} le-mNQm3lH! ,ؕ5= Wi0k;_kq]AԊ(;swFK2$]ftb"w+^_c 32O#5D*jZB,иeTB))akU@%?? ],C~32ޠ<?zТg͂ˆ'P6* 1@..@EZ-!qy?|ԆQdg :9: Ѐ7AP y :'\hF B*01k? $`qԆLcu(k D#%ğ'KCFo} ]34|\3)H|Y̙L'bHfƔ4Gμ5`{{~)p*n CHjD6y#Ǿ{ ;!'qno1ŽאuznUI>Lrbds] z<I:ϞE?E4s5צx"zm$oeE$2KK]Qởsĥj"m2vEz'dzlbr{BGe=5ycϵ/gh妿vɲbR aIdޯ\;Nח/]ck_Ցnx7d0e ;XW'/Ijg=iz?~qw'i'r?sšdzBC2ru\~\DK.:NUF2 Y쉽pt\akOVJӓ=Sb6m HW39Sw?Mg %kyS;AIgΏRww*&c碙C#MVXߙ IaHi7hPZ C2K&sI_e ͭyD\eiWWs>ӟzGi42Ec&QrsEIa }vrI;;aM}(CA+1b\=/3x5`{4*D% mN<n?%~˚{N2BJBL&".(M"3^E$YQQ)fSFFw qYX|VsJI 5z ,(7mz*wo~x =:ؠ]ػ_ޤ * ^y3,ơŤ ,VxoqmvEi wJc^mԟ;Oӥ{ryO. Tk 41$'>Ow݆pw7mci V ){|6lӣԭਥ,n*⣋xڐ2E/P0(HKnvP^*dO`aaa5P ᦏ0?DEL$!S\U:3X= UxF_\zlWLuxkfC}a=0bxt[F!svl {vܞ qOZ^;sܷ5y% /HlXy<tS E"dڜ k P)l.6ͮ$EdB6E[E:[+RY =~ډĹQ]Ϡ97NmJ8ܑq%&7Bzwg 09[b]iAd/F*s t!*}p\^ҡ1J;C 2+nmXϟL ?{йQAV?qU&ZEJBfGΒ%w Wp|CCZ=CUP# o3B0Wj{劳*&ֽL#Nm ꣛JZ:8%{Qaݹ'mF`X[4_Qf-:hs?F#eve|#S?h24]ҟr`! ts# lPO% c`IPsva; D.U;ӊBN,q28j6B(-a:+/fW?\/D:\B]M(=w,irsL= i qj uj@ALC'f hjza3_I  {BPŸ6ߥ;dr7Fϰ?]d8Xzݎjsʽ榹NG=SӅ p_J%JB_Cx=t6 ߎ:Ez *t"Q5kIx]w?4W_&R}.sWs/>#,2zs!z^|_ThJ/sewDQ'9x88Ƙ{TzF |6K" P2uP5\m3 brخ;evp,;]B6?cJSc^(YEM:Y$(ޯcѵ0{Y⏺la jמoNrb巟_2<{@ȳ5DȏqOTiuiM0Pؓ|ݶ E̷ϓםȈ^5TW?!/(ԹbR iX~i {95 7ж]I tR:G_HHɍkO j7fn6(]W]PɝEf0z](áM@xF-CgceٔCȕeJlzqē>,`tvi)g `~f0uۀXܠ9i99xuδ4/cTV|-GOu))ۧ蓆ܽKDu##-;=&yu bX*"nrawyo\9ɽU@pG"%n@.S^ ܙ[jfa.HU<3y[W{({`p%ե +]x%~:[Gc/wm!CKoN^4r/iΐOSl$}i[KpbxAafW*F?ѡCGq,@)))Ӿfy 7B *>؏KcžZm8oz`pwSm㓵GrAmjϨeC?n/.>xrn f3Ji<VR5\S1o/S #)6[ Hgi說59g.z[HxWtx gz$50~ż1}/z%-R)YW?m@Ce就//3k$ttDzAH>J4+pcõ_JOE}$shēTB]A~ h91` JsQM)(3suKeȀD6(Y2 }9VP}2F*p|& Tu MWQ%pIsYE⭡HQK%9pI*Rg(r\@nW[ 9**,[(lBuq5QcqBKҟۨQnKAom*<8"/ɞKrAUEU"7wP绨HkLcU* Fi>Ҡ>` D" }Z]ү;2 @~b%PO2t}#V-ESf'VLVkvz} 8↋\qYƍ/B_Tܟ̢|XJ6RGRIi <od1eo:R .HeD,vMʾ%+ F~ټ-s(\ή6[oUf6=oޔQ+R mEպcoFH # !cg uiǚo\K@բ>.@,f}KaW^wo2CfPJӶ>m!fTs뮏p-o}xcC3e( ͼ->ӞұQX8#ϟ;Hg~J;fwP턽 8uxsWkGuڎ} 4;S= 'l=o%M[tyQ]bJ5ƅSZHzVr؍ tB.z"}kKZkY5y{D:hs|KLxw}^KF+Rqxx04EҸ^C$Y)c Ӏdݚxsj*3e~ă^r!j\8Bg&W3wfi؉BqQ؝iꝑuy jcq<|ܑr5wîv3W2Je.f$a%.󌡑\: `0ucղN$0=zu3%9sx &go!;cQk^ً [Eo~&{#xe迊\PM7J.5gvϽ\ r3rܫ[,[8vf,ʅv9v<|BGanWoEbn_CޝwŲ<]XM9jj]jJv,R[PwC;2;N@.}8{9xC6GUo`@̌(eKշ"2m&{x'Y8`%̕i Ū0*SWt [t^LC:!lvG?qN,XZ? H'9~bhm&Mj%h_ :^)WMAgHhUͦP?~ۯ42taeh+ ~))\{ߕZ-j,,,ffgH)Re,bg#* RX\^`9ze<P~dJ!_@(q^`Vn(]G} DZF(Yp4 j5 jy&h@Af@WK4z&kkP P r4у^@i 4Z0 eխQ[P'xR'J%$ B@ Uru% .d?^P(e.t Ɓ:LBWs?Ƞv44E} B%7qP `Mqԗn˫(\^ Bi$d9' MB}ڡsL;h8=4=d=kO6imSszWCjƴ6t MeVXvfQzu&nMC\idjtH\:g=Q3م_HkD(e\}4IrZa|ոgs.s{ Vj ыN&bNo{ZESl}yyxOYMSUyȃV "æ~Ecf[BL5Qn/(IxrR:hgv)|}61[di2%fl$qi __$S%L{x*=Tm 4fh~>*Uf/J]Uo8my)[e,,yλ>xG#rfx*A]y$6ݗ5ѲJ[?1:ߧ(=׹ꀨm6nAYbiPDF@AIHwH#4 ߂ٙ3s |$L"~]"HmEo֙/ɦaқ%Er4Vr,RzoxsS},3-e-j)$65J5E!Lu,fwFZ:S٦Qobd5bꔓ ,\]n_6$c0}IEnDd]*Fp~X/`g$mfK*+>ՙcy VA U׊E_*㢕ױQQeC\ $ɱ_*c)s=Iyr'x͔ bҚK|~aV*!.;d"Vʩ ]==OZ%eipONnW>Ld@P@j✽R2Ner[.{Lzzڽb+Ekҧ٭/Vy8³nQzQ e8$oAcdB |9@5+(}욭zicW%z]z^I "<CEY 6jx4ya=: EϘ xPs#%^"~r4vqGEbEn+{lz3'i_,˝x7VݯY>a7I1[ C8lp]ŭnm%07ݜ0Xwa"IjY`*EeG34::nWʍ^Oj%<,Ⓠ5M8%<ތY_m(9GK]a~kYgo؞zZEUVf>[Lj{'uչ%I-Z.:z.3|-g5Iݑ Ґ.%xt@{)Wj\GWd͎L.M(TNW: |7dW64}/ y‚nܘE/Y]W,Q~fc÷UY%[Πbo1/g:ZP16K zzT t. [=FJWu%kE])06_ 2I DuV~xQw~jPWqT'oCo7)?3Kغgۣdʍtiɪ$DUd52NO[y*Y@<y4KOL䔪]P9+4D >);gC}ـ5x<BHY@~rzctQ*MMA&=оP"Q>V4?Z< `%n}x~V&Dy_nX`0 B(TJ?|itڀ={pq‹ LB[ Ӆ\|WoǝY.]5܋,_D/ @ÍhW)tHt BX\lCTu:Yq`b 0@x.c̚O9sF.I$ @puс A>zy9ҫx˄Du YHxܼ !#0CH"[.̑!Kk%rf1D,.! c_0FޥSfS~|| /J\E 9@ 2`sC/W4BEEM<zn" Hw8J/ôWisAƠvr̋RV j~]>$!T=4\ȳ`+934 @_9Iwz"^g@{43Pw qd$MQb #μLFv *)HB @ Lp W `E: D*aS2'm( ؠv/4ztU(B@Kf$˱Yw/1OH77¸ !#\CpXX0GR<xU}(1zKH1&)Q;Ϯc-.Ni FP L 4fwljңO{,Oj> (X%C;tǦJR}L3TAS6RO2͗y%^A_?YE`Y% W\134mi=G-baJu9| !;L!|kwH=NE+$UOkR?ZPݔG k~{j=[c+M)< z])rNo@^rm*d_(^^RatZ,;e\椨 /#G- @ƅ+L&&GVUE|@g*8iE_ѷNTh1dЫb}{sgRҾ]k ZYp^&!)塳xzWsmPW0~U̬ܧO F3[NU!jOrQX%3TbQc~fئwAϛp@ףŖ̀ql6\F쭓J+YwOP9;$B m0Epod-~hK6!򮢾7PS#vʓ_DJESiytUޥ]9gĪ$(zd}GGUϜF$RR6sͤ=C{ʅP7+f7*s.7|4^eoJ]tި^~2uVtf^dw=0ndb'u<'%#>bB ESB# ax'E:#Q+:KVc]A<‡s 9:3m=) c͍ ruB3! ›gzq044~2]9Q}ՏZJ4L)ZL]:ė(ڒK3)=KWkͼ?P՛=%=n!8p3zCa=8ID6I3Rvvvyo@psD#7봛2O^+Ǒ[.&-ds@w. 1+he. 415AT6z>=UiqOs,*%t*1p[**i+zv'.#3#!ę~mu@{X}wvBO ʼ社 9;[}zk״(԰߆잕'5CN~E~#g/q' Nؓf_CTxJ`ó*& ?&e#-!{C /m-?-\+6&IWx6b\^Qy O?r+ r`*M™-&{?emrCṃ- Q4T›f=7!Aru7jR%ʝr=&o.̗΄>rDVGc:& 4^ba!"ej<9<)8lM߱}Au0r,dKC|eC2P嫜T> mgS@>)kiwEF?hPC`BХ@ ȭI&uE[sixy>/^8|*ω>Ƃ<t= \I$l1C>¯#ۿ5HҸL!vM`j#$6@BoWd hĆ^ud?$7A1 coo˴d+1ANU=` m!8ׇ͎!9 0D$QkIT3c@'jЮyht\"q _d;죖acQ5ovr'ίsBj]&푯vׄYזe:N^8\G`8H;-ïFJjb zsw_)] Ve{APA[S5%z5Ń%*xM}߷@# F9BYB/A\.jZTâp{u Bbvy6WDBLQRK4b('QnJDl5_؄t˭fXOCd}!bu81yw[mG .O@f͸xrK^~gOaXY֗V:{(.hɏ.,DC5p Lw}_7 PZإcŪ&ɟpZztkZ2,iuYZ9Ob܎Φl pg%ͱ":!?'A)B Ð{elH6.b;h/\Pxvu]gVF:iQxm.iN뽧ϛSKm  A)fܰ^LO>cS?hězo%jkDM~lBJ%n ߤ#1avp#nCQ^Dĭ6c/I>b v|;wۃF)j57{WTo8zϣuBPqdI֕C,Qqf|o. q[RMɾЦ4b+Ӣ7!.Я.Y3;D4mG:vV~+0\jEaOYxFEuxԧ @4P}/l.obL &2y5~>iu3t#M}`&W ]k !_b&OaH 9۸.[_[Yf󳷖Qll 3Diٔ-ˤ~ hPOB$(nu 8e p64afe 32kdCe$U0Z~eB$(y` ǻ EI#Q "uNaWOG /0(lƏb{e w1Ƣ2 bRSgEKǯ!km ;|`#~9󨛈ؚ#eusq}HԆCr7}L`5F ח$ňC6}$n8w gWɓMW֚nQż3hBv bdCCmˏfo!X_|L]Rh >ggOE8S\ZeFA>_7EO\Bv@ YymYO%ʻ LmHp|AxQY4d&C h= RMJ@w5\hp-۝\Z:Ci"rQ\u/213 P1ߞfbɡ8GqoWҽ'1 ՐP)9%5tO-no@OOG>b!f84Ed|Rĝýdz2`ܡ%dS ͡Yy U3>ʭ}uQN^0S~L{#va5$·vt|4HLDbS/O3̽TivQ KeC g_q"+ Z(ИT$yw-g(('w޸#z>zw3Vs0cV ! GNThoO:9C~+h 6?Db5Mϴޥ1ᥨO*;n2p0JlGG$B5w؏(z|1ž>4F(*e`"a:]ZGO=O6=[fZ8a~?MOOrWwI-?v$7sufbEn>y$+%fMHN,cо8~Z0~4*N~)wbNIo?&xGqLn|C\ovQŒ@oGDWFiG ECM.E]tp 㹫ƹsBRn$ 9S?ܧ~>CiY )8iʕ#_*k,0I}`mNp|e/Nt8ksjꔂ @&XAoG͍T/wnyڵy o,%EJv6/@lIW ^R$oHf00~u~]._D!w / iAp~K( ??=#$x};$=Eٸ40>~azaaA>=_G@y0@\Y"7pVDʵ'RA>G^H5j"|a$+z(A~>8?0 ]>z?Zb`ɍk !WYltu.7#I!* FV'<ar÷ Ny *͛f¥h Q@|EO*;o8˙ojR/vzS] Zb`EK:|'|:HDXHnimFg BK#]tȯOQ RAjL PvJ&+̊0[ۨ,`QVyP=.Uaq#i+hpwGNnPN4FkؖrS6cTB8'>N5=ޅ2Vc&atVYQ()D9ґ]Q{EZvnϞb۷u4?N6y)K^ j7wG(Ej: Oϯ5ގE+#tv[?zW~eOތn$A o:9XkμOIU^fM YL (i7(e{L{v|kwfm$Qz98knhZ'OKpwh>^V=5!1!_FZNt8oz8XUr ,vrwYq_N^}Dhe9MKYzuV(TYrSr|lQ>:uk N^k^AD*Fp} Fj޽MCG_" =R""IZ/3Fřo&Wvnogcx?%sKjeژEto4~27ЄFG^oa2GZA(vvyT*-#oB-G7Tw$i oAR^*5}u!r-Bޝ;SGg.y{1 'eI|zϥwĿ plD-1okm͘9 @+38,qWuImWs\2\ {_踵efu'_?.fu!h._3MWKϻ?gf}{L`.R8qC%U[i}cՑ Æ,napQYx^hf^'jlg:X9|l(KZ"#CROY @#fd!PXi\]Pa,#f(l L4ʶ,2Vgd3x_<;_3.h 918AOMB@ ~X3څ$m ›GxRh;-q6|HcIqWU*`3uE'U1ͣ9BEʟ&by#5گի~kZ\AAsq&??z藢][Phľ>~i*m>qW47R|J;uVU 9=˝akJ_d&+~y)TfݜO?XL_z7qDL<_Stxt$HI`BuV̔DنJp.*T"MޮI-oMTry+Ar}Z7$ȥ@*yxo0smSD0)76&<!Tצ}40(= & DZ n.k\`b/qղ !8Dj:!?{أ h*#=*^ߴ^~5;kDmbYVS HviCΌ(ʎ`{w?pN;; MA#w˅#6nן4b|23{"{$ƈgVL>|ɷpPfC=^jM0;zgt -i&`,= .SL/njj`uRddU'Vl=kKx靳U;nMn/2ꠄ :NTc:7 |Ήkn.YY}9{ީN\[<^2RX qpKym:ӎI$jukWF -‰]ROsub4OG7]u_R:%-s-Š+1,Oע)E6NvYǒ:~N|<~O͖"Cur8GGi-zXZ6w$5( Xu] Z\"O=YԞƽSu$;;1j]Ƈ{[%nonHз6zUv:6eRwT48}vOHRu=sWD|%nw=nḚC hv`qⲸfhYvAyqik`g#jO+cMDmMZLMk™uk3Y]ѬE.7mS86QD!127$P7Li:{ \Qb#|"C F[q+ߤEp:qi'T9m4,~smO˓/# =Gn-QZv?W.4 M߷?ڕlh ZIUH*o5o.\Sj&صJz? ,BrT=4~cVLdV\э /qds^c Ck>bl}1'\s)> BjF'4F Aw}_rG2R͚?ݘG\5-hWBȌm>Myk̛U#bYQNjFSUFfIHo*@''w>F(^644oH}:xWeBӉH/Y_'\cV+eװe:,CF "{&r yqj ,FG6<#}/Of=,pX>q(a+猧 l6W<8 %RA5# BC1+0Qc)>mrT6bDB.u]e} oIm+5IGuϓ^?A]75Wݬ zqC󋛜;-'֤(t~x3Hzr~cuY8>:ݵ!y-٧ $Q{?%X4{Jǹ"o&a2CTyU`1&%mxE^k"x-d.5g g!0.z Y45sE@qҏ2U$jCncihA 6O_>b>W#R W{ Nb>w!.&$/-jV%h=gr7iR&_,@WbzT ϵ ⾔wu 2:[@"* Q^2c mdW4.@/oOM~@$@a_!WO/J_!m4DNUjH-c.Л`foo% Z8ˑJ 67⛤b\O Zټgw\w\lj1?/(Z<0l51Β ,u,d)<>-Oe@?`O'b{l]`x2czl~'Au^:)_:۶9E^_GKɂarO#e093>{qi`G0Jǘ2EeFd=!C+7v>YP^"kAnTW'䎉lo@?+MX{%Is0 OG|[%:"^ZQ ȣs{;Vm;kLB61gg'sS`p fA)]K}' 9)Z<{11!v[-!~L!oQ94'!/n($Kd{Fϖ9v剳Y|Ӓa}VD[8D$!P0jwRͲκҥ^ PY|kc|gU9Z1 i5QVc`mIfOEhWKD7E~pyrϔe?tj_}HYZ~Gtca/YvJ^"`j$Bph_10ՈmH0vP ^oMXX O&0!`*(*z^!d|udKD'fn.Po%đ~QUjN:!nR\WoN}'e+5}u3m3 :^.W"W0ѿak"lk5_𸻫 TB$s4IUޜ 9%#u>*C(q#ϐ8A1ЄyPL}ֈyMeРP(` 9,AE"W1,"̙!1}b('p=Di)3&wU9eS$@qڲ^C~]BAׄD_oB{Pfbeĥ % G|SUT(M 60HUlPNtE~A=y&:Izw(q%_?l,K7ГTp/Xa0bx`Dm+^W7SIQB6}cgL7@ [Lښn,D҅z8+1;ѻ"Z`"ټЉɨiL.,5T<60 w'x1Aϋe2ZGeD_x-xFdq>^(gdMFIg^t,I-)>MLJqZsӂuMNVNHZO-·vKb_xj]@J P8?Z|j ѭ˷&z; =pN "x|V*eJF9 Lz@o * 6 ;7]or/=͗)3Y!WUrPQ0hʛ jmWrJ{jJdI+;P#˕ӌ&-/IO6tuMO]Xhi7ྔ XtϚTH~9L|u3 sN̐\Svʙծ8"WFO W,n Nk}meb!gh%H:9wع۔ AI_Eh*_k*G ]ׅk|m/'|]]X@0)~ \mW8J Ay_gPu`)tYD7@PS待0$lW@JfۙbBP o>^C).3G!,J?;?17!8 X#[TDH'"+lT e"BH<[?uZ!W8gV-RDiE ;毶QqC?T{0=ΓT{I"SjvKIP6( 2X-cQg][lA]1Z& X(h8G .֊-[={_@0Uk#(M{[# 1)sn\+?MgW nW7 nW n\Bgh92PY&eGS 䚬sa)<mU#0pXv͢0û[uED0C?,d9Te/X!H;vQpxFmЉۯ5pm KJ y%9WB$H\K܊lKDd~9-"Aς>v+J Ar)zpGFry8eUjAK>`^isKEYZ㛡̗i76Lf|Y[f3b\ VlXj2r:mNƔy[Yz׏J]k |d&H I)JE)4I:'{wfWc;קi۩7lӡ{ʹP%1f( S0jP-&3ȝ[S&6iA؈5(T὞@PX? {AiÖP}4 68 {x"?p-RpqPqTʰ-Eog֛pO)?o; cW9pۯAbI ?6LT;(iipin/wjF) *dCh&)&0qS<8KC;`[N? EvpÈbS*!EF{^ v40B;w;)T08mMI \`T{WU;*5`0|:dxdSHXb䦱c5]^(pW"@ߩl"6Q|]_)pW !S=Gl'|ULb/ýO4)0QJApS0} % ĔeWM_E3#|@cxe‚LP`)H),JW:l6xZ(qz&8ӫ ~A2]ge2}2SZZ/I{nl(3xsJƷ^-UjrXJU_D~_Hks.\wmoԍϚn6bjeJKQj`cuEƌDbB_<m/)%@ r3䈟u&t:37Y5(&JA{下?a/I)+rqCʓ _k=27Aj{O}Leȇ 3U3SZ ÁW5ǴOdRYjF/@Gz fnNZݫ7^ ?BoƜ)6֒_Ըd>;e~ܷJI=l%W٢Ou7=^$a3Y{hHw^WPyCƾ'9GzvAڕf:q? ~DS12텅sBh7R+][6~u,>F7_TC٪xhynt] uǡQƭ4%SWg9b(Ʌщ->ĝ?P&?'^w]o;޵дi]xԐP:Jˀ4w'dN! RJO%qpw>$M<1~Athª09y<#CV][=>kג 30\_ۨ\1P(t؁XHROƞQoTzڜUTaX) H)'ʍDr)g3u O^tn$V?Wx-*E4?I>3ajfs/: 2/ y*qC)u4+n}NY?[3` RyOT-G7Iz /ڵ%^m=Y]BU3)G.hjzpi[!1 | oR. 89ohQ}j,#֌gr65IU0z~R:dfh ZXd^5r{ZK.VS֫1*a/ă?*10ȶ*u^+y.LtbL6yeз+I|wz$$@Zg9?rzQ<7h|H"Vem&/I<%q;C1$ytKpեTSNɈsمoZIj谐 3l,xw;_mT $1B.ja׌E7]}'EoOyR1!9U+eQhs/~L7?T>' c")t?7irr^o&Q_`<~hƐ9kWtSt<5}ib33IYSPĵ2Aa'G8>?WA:p g¾okNO>;r܃M¹)O==h\",8j]ɤ T9š/v陲Te9sw&oShsqˏ z_ҐtUGje% p>ku\*Oི)_6T]~53xr|2~Yu&ɽazAڃ$ؓg}ݥ+Z;lמ,JuUW(v̔p#qFjG\{qСZ2m${XJwd?p0`ORRٕ1O,ރޟ [X" n>tXB{nȒ)w)OgϮ;yܝB_ y׹@{shVg8>ϳom D]_m\ N qj՗|x dJڞ\<ƵSHGl/7Jv4MO"к ߻݃ nx{9Àkivph+ʣp` BVTE,͚!4,a 2) ,@x/FP+PD@~{o` 8S `ԙ n 4X ET ahyU,âИZ9xm;Ryb wUTG&5Ejq( ;Q*f8Ú-'Kg>휇4"؄}_k~G083pTph甤ld(M }"9w%)i(-ՁF|DY,+auVdjNG]ekzy4)O MvC[?|Qd,-95!?Tgѳ *+ULBst2 a AkJ,4؇-U"M_<.:{λn鱾(~ϿiVbU 2TF}2J R`'NS::E1!s+ˣ<֋V"'%3 .3ANVW--$>Vݗ p Sy3wLtˎGiҷy^`LxѱG>8<L#&񾚿p݆=?.fRk@FT:3fkn^u!)'I &J v8(lusL_e.F^k[zֿD7tlG-6W=|8%ZH]rNByscGG7p:F;6%1 N w%R2$_b#$Bvcz;3b  ܨohݤd5!Vk7pe?wWU^Ƭ i" ܚ7^2eD3+Ն8I}WCׄR~8~+p&U=& 1kʗb>*qJW6I!E&A/ *92"g! {|vS@uݱ$\>j~tȁdžsWXYgݑ{rtٟ2$"߻pW拏.G5??P\JmHp儵,$Lh2Xr;!7:>"Ucg'C삛є()̿v=BGcW |)fR0c$F $! QEY~@)YV$zH9@F°0 (4AGSŠA/;THɶZR`ܡ@XEEư&#|kVĥ{a4!i@aV&>)5hW*q)Ì}9;5j|cJR `%Vnˏr)pCv;P+[gz7fcֱ=7tٟ-FxO_6r[$վx&Y#{Y%M6\VZO(7C_֞Ae*4 CҺ1QLNY_+\MɃT\K7ɥe? 5ɑ c?OQ_ullUW:s"Q -5+5J;d (?}#-`3 aHyR]mitfAax:yq0N)N¥ceMEbɬ'nXJ_=ZY? N[[ϊsUzMv R{Ť>8Ұg {`+/O a!i.n5mQ+Ϳ{;6Fp22.MҾiGil4q^~R4 #tN$L 'aCR/%=G1DwqZWpWf vMQ5hU=vRbZ.^.+t;f%ڴ՞ ==C#އ\]VNGAyO|1,/]>VVR\`bW'Ƶ5U_Xs5bkҁٹ!+DѲ8bRo Ǹ",>6EN\tFc ߵY^rQȺaת86OnOS"X7>WIjfxЎϙy#/%>qٞ"_*9 -:ؾ5ؽڢ!:EV" 8cM ɹJlnh c?%x_~~s(&X[dH7Ai߃4/ 9'пx%:iyGL &QTEN[b6#96#nܝ3 (ձ-PN ,Uk~@pRqNG$n vB iAl=Q&+#حM]NBr^r6)!% BSSH?$~46iNiQ w2< ㍘U\ eB%KNAmyqm.ý7na_.=Vm/3=5[̧GJ_0\ 7A";ˁJ˳KWS n *k7{>ēo R:CIrV"|-g${=&s:'}fzv=M*0 j>V_cٜ(G+ˣ2/Tseyg_T_Pw\%ƚgśip˟{b6قkk]d0H }Q^} 3X$l0[[gdw0IZCGIJY#l~ uAlOu')*0bl*]_u<:jІ7Sb6}H܍2}{9* 0cǮo +,Q\6Z Hÿ X$xΉEeg(_%s篍;G3Ծsq|%)k3Ixsg6NùNg~)s%k|e!G1VIk/-ԇF6ؼz}_x 8xϵqh |aۂ׸&Cf_!^ i+!'nN;DN1}1{t#ɷ7XK3<U}m4iӽmsC4#$㷼shmմAW"bqZ4Eԛ 'H*;b/dȋ4=h\j0U:@O3ϓzF&5G)YגQ{eFoՄG ¹&zd63ft}-bMxNjv&,'>6Mj>MRw[,@ Ud\}5~5ylz*2'ǜ+O uT F/=v՜ɺoԈSy+tm=bhm||{@5?* !%FYVtIZળ77i<Z {)[;mA\/>gT[|-WlXd=X.U+&W(^B3JLIR}tDuuw>k#N+nɝF5,E1duʛg~!/Q)uȧxXs{n%WǞ4Jg;9֕lX],s8RUecL::_N>r8_t??S {'h yA!M>D=ĝS+%w^^Ei+ُ玖kg(EHIo7R +ݙ˹ǿrwi{yY|{WREo]bv>]l!؄(ielJ^[ޛ?=\`H8]E<VoJVpTgh_i>I{ +D(WũE4^_@peHDN+D@ C뺗8|ʷ=%7zF@1_ $̡3ݥ[W9,:.K?ZsnOyq608QOT340=LFt.7'fꅱ$>A0|cg ˃b{p,8[#d_.=T`Itqoԙ[ދQ8=*oC&[?̜w2:5;kb$ނws] MKd:$Ro|MYmQsZڠ%_rIʻh0:d:b-k,cmֆNa航*LU-z s*4{t63b[govHס a )[781x74*9?@Kxx4~(m-઼( NHF0DDb n!oSV8||_HN!PF%sbm >"EVބâQ pX!,b #`5yU@#;zq3};w:F8"BgC.({7͌qڭ8ޕg$Qޅӵ z$7.>su;_<;]$}%Y73tWr&GB{F+}\ ÎWy+aI6!\\|j9'Ib^gI=іՙ4;ʌNurr7>3:JI;t X>){Q"ub'_-Z 1M;c഑($|S%Vέp*ԜY-ܨW^hJT5WI?11hڟ)iQemsȘҧסIZrbvѧoZb}Uϩp) Ni>RYŀ6~e>_uؐARB1÷Q/5ӭ]pǦ>*uWOg4܉yZg*|0[^|ưN顜8w8Jz_ḶL]iG*q1u^]U"bM]7*:c}c6QS!WAUǟ5cvg:%cY){b`ؑ7 &&o*C>C?bT'U֓4`b7l>/h>|>=nYHӬv1IxoM3>$+U{OTH}s!9+yrYaܡ[xD`حQnmpb|`agBn+7v;Kv_ (vOy— )OmNiۯg軈f?F"S%cP"9uvf<8EH<8%AavPpA(՟Xb!v K" RQ<=<.#ꃫ4 ᮅK~W]*F)ce82K,֕mc!DX ϭ `{HX++ =RB@l΃0K11+ *!vM}3=Ntz6#8a#f4c0s Qҙ!m2CRtv|M%81)i;Y SE8Ppq$x< Oq"F@[Vt>@m%8I@W0'/;98!ޭ{N~mz{K|!Lx]qTyP ,i`].H>)*Ϛ n8OT-pB [FF>I~CrRXFy剰'4G//WIx~/}/#hICli >K9BiH_Axwk(8d X |Ia=d nv~IfM#NrAkX#|㟬BzOG BuWزuOQVM.7%|JC8])d y-2@U#@@d[J4"s[ R!MIy?xJT=ڑeIhٸ8=HEeȂB(A]|[T3 Z&U _J'B Ҧ)#^p~WzeMv_F@-IӃR|j-YS|Xih+2[r!1>3 ڽt'.vn]J+C9Oj\OJ[@&p?%E97)fM (KWxlF! ?< Z1Aa8@+fY<[edryf -mq*uOG9rz/ v)|JyKڃڹ:́'DrI3Iƿv˴-r֔+h[M4RRM~|V~ Ң9KN.y< yɱeOđ՗p Z2h9qO_vS4F_v8ب|ɀ rY"z ;\~8G']z}k,@#=7C&~덺t#ҭf(^m`G#OhƒmUVd+d7ՁI&=-ŽɧA6:x~)ٖuQJ 'ƍ6 *۱Zg e+)(f{bG5ۛ R<hR }3@&ӀoLZs LB0,@&o,d M@}q2;8=٦DR)` `C@k9gf:R${}$q@r_IQ"k@AF7BA,A,?o  f?@4IF+/tzIJb dtԖw'@QߑHxso 3vD/$Ll\X dtl .W2 ,ooۿq#muH56 "Aۦ@Z_ @(~@F9TW{*!@D k6,hH' IK&T$@ 5"fj@sMXrAZTc"EZ"!Ua>:![AFH|`,#^qx#\ ![}V5Xb1 .H-{t]̊PowF$0 Җ®#m@j** iK.%-dD=@GQ~ӂH &‘Bp_6"(Ş@2Q@"^#RаHe8HFRq afQama-!Ā:E*x=đ0UqSrVHk?Hd! |n'A /Hȥ @b *.iudT" *X[ٳ' S IP bI 2Ғ#|?H!US,p[:J"d` 2pL9Yr dT4@%)HHbG"K-z;b@|dQ±*ĎCnWDvf& " N"HEBvUF~)!™ W|xE:,hW|.{X$F)U@J$Y W 5.HRP=PKdQTNrDI.oUrn5AZjk:@YQښ6"$+|to5t5A|+d4h ZEqTOFe\y?yRІ.=HH#LjS}߀>=ncp55FFWMR04|@F5FweA.\}F@{pZ%ƌ) XZ4Nsq:+Jɽ-M(e: B5Zu2ʶdrNԔHY[Т: +;֬@y;Q.t<:&kP jP.V6ip xlm P#kہ9=@*Q:t cQH {8n7~yiɺ%XWl YiΖkB$#醤#+ tC2"HJN>z򦰲"ǥxc2]W eM#N]s o`rpk]r+em-yRrRA|f%,µ9-*Qe6]<SO!(IK{hih?d[幆QJ еףR冫)U*w4u>|媛7%xec#sŧSAgro:x~myRi(j'LkƋFNN<&Mn3Ҿyb*6Ϛpֻdž9W1b_DWU`^fhIR.ɸ9X(Ȼ7HÛ -gDgƿ۹2LcIkʒgI.z&uS f)l/wfO/1Y( aD‰K*6']Dc-""`V[mZ*^nmW_Zy<^y}e_$gi4v15+n^hA8WW lɇ.-m$(9cK\\'J0lzDLٿgܓsU$VTQ\6 5~WQ8} ϥӲ%_>rih6Iph9!9q~"\ TIuqJ2F+ +f7VHTp+]r҃ۅg,/I=x]d6w*|l'pCAcL#yfsnl|t_"6&=;*#Q/aAL#]Z-xO hP6v&$F7d { C ٻޥf$t;,<$zCw*ҙ;Ψ ,[l{AҨv3򘞢HkWO9{ϯ!E94D m״\y Q?EKeɵb?e&Lf+RaC z?2y) QVOnRRw$ڇ(fC]GzG:U5& Lʷ:ײ7hZc%omή\+O|p`HHKx,ɏΚQQ p Y}d H5`LsII0u_>@@ 5 7 ]DÅA` |^}0NTh38Y@@28h;ؽ`n g@:vaQ= ]|1&#rUFs`v3&9R2 ($ 0_ehFဦvy68o@ 2o ĞqpFrAwd~NEd 3_Eu8 PhbALmdT B]|Ɨߏ ϗE@ ^,OFF1^ǐ+v.%#`e"HePpE5DIgIm${e}IBDlF(YPdvTHDdd2"=F/}~s]uC \PrTD4DG@X DTe H~,G$xn߁(8<㊇<+xFC]7 Swayer//q[Б2ioI$Ce B~%Aw!WL2$!%=-(ajJakDރJ=(;p@*|#4ԓ4g k΃TC>?C")MNDq߃2ރxl*gw0՞Q0o`5Hx[ '3 KɄ9 ΂C' #\zS`>u |6w7~>(TCrc0"oj%(x #0FhYXᬡrH`Y8|1%Xe p8C0ad7Wl.$z2>T d֏9d1fњ31LKrcű| a5\qYm"Hñ-Mq쐚"]ǍJ ZhR> e,utbոӼ9/Xhun/Y;u>"whXwߧ1eed>2ELЛu_r~.o5S GהED+tM3b?%}2:tKn[ц6#GΟ[4 ^9aMYJZN9!K:=u[GB5U}d8OhcOB2[G݀ir?ZMo$pǺa i& RZɲ֪=cl(VgW<7+vWU[Nfv=["=7j_yڳiS?/3/J>Бۻ\[N?8=Agol⑮gZ%اgf6NP2N'7>i"?9>qViʳ_V:rn˒ögY,KO](zI]iUWNULb9yur[w_Gxh_=}UbA"h[Uzm)OuHxC3ꀩg4C>T֬Ӝ% 9ԕ vըbhƻаǾJlo%Oz)ga*|X K/!S=px4oGИTփ*ۨ57/ܤ&)$H#XHBAc(+jJ)pir }q`@3)^t 9T)K졠JSi@ ˡ7+GN꽣auhɑi.%6 4MLoa;!Ґn`3 C)m/WOE&Cg/}{0rʃjTl@Fr"hs7@2RieK*&}yLQv6krnnilgMT uG)9W4 w:-SZ>fVTL-/3JB-L`,b..vsdm5i%K)j`)B V܁Ӏi Op! bҼ !IC`cɻL-}ԡWCx`\hDts $;RHcdB"pEP a@ )bѩB%*+;F0_^ *vv-O ?˟S\t˧=PME5:~&17 E'Ѧ& S%LNd쪍}/[Vvv6Ar$#YH%`LiI;JcLi&tH>}M/DTBUFnH! Q5t !Ri%RT^SL^V3J؄=ٱ̢x<ofWD"71O䬩H[ L {A.dpˍ |Jf ҒD }=96j&) B/o 9R[xpi<{;b qNcTίM^MpsZ/jf{ޚ) %N ½QU$ؓ  顋 3FyoLc6d^rZb(KxrLb(KeW93uU7nb98J4Cz+ͤ L3yD3 B T]lwL ~gTUdUolH 3 P08hG'vei㜍*úik+ި 3t6Ԣx6D72)G_" PK TmJD0_Қ/wKV2Qw)`uΆϥ oa.G)w& ωyz/ٸQ:sUzjqㅕj$?i6X:&zUG#(`h#C2/]}KQdU5[jUE-1S洭׮ct$S>Wmqb珊7*-$/qx8w\7.)3Zy@ͻȩtc8%:Xʉ%)9[zvJy-OR$FX7VMFytG[.sˆXt;+S[c򲊲.-+GVtM◴{:(VOYϭ,Lr^?A6]o)1TL {j=MH+a3]o&BI,t3 S_.^]a `;o|? KLь t0(~,rq\e!ƣ!S!:^XZx\gbG_Ψʼnΐ0WKt}-Ԃ.Q%1wMeNN=U*<8R;"Ͽqye^X9=Cd^vglЍ i}z~憩_L)rU6j1<7hh[Wֹ{Avy}IvHII$hd7So%h 6~08ɊOӸHƀ 6ףf8pd8xohzBbHAP;b_v4p@]OQB5>W(aj6Q^3k&$82ۛK19"M[N.RW=5fW#tU>W'⢍kؿGȼZ{YDkY>6Cӊf,։Hk+ώld؅Z]-i /n 1X;Bp;6roS)ALCq8@ YQ\ dNo|SSδS.r(Gy Z\7Nuv1nBOӡTZ97{ 8CD?3X!4PY)|KOF ZmMθ C8Q zGԗ52g|=(jୈ!io'*0Qoq뿗=, (.9ULvIN0Q *Ô{݈)A x{-|Ƀ8eovbl%mdY}GMg9a3).otMY.Okˢ_~ů;ci \piȪ !ZN-(έ7L{DŽzZ, Ld>uikga(tW`Cse^5a(`q)W}ƽ)=s+څ~/~ٚ}{OcyGXzg(b/w5vO:/B\.&|>/0!t NG]l­e 5<rP!gJDp/D7WS St{墕L>8,hNĄ)Șb_DfgDZ68n9"0;6=zcg"9=v/sb~2'wLUz],7FVwiB_{%g0l'e{{I+>D c)<^sbsS˷p%k#I.4^~z},HM+-͑;pagw-cQKpk}'5ځ,* Zczos9~SZEVnX)L1 P|Npy燕XWBB8c{kzìkz`ϨU8o%//!o)}aгon"_81(z$쨈h0/*+wN@r0Q,6b=oũΒ<^Զ! YsGNE -P&d?N9|#-asׯ2}l/@g>tsKYZnǼ *jY6U,^'y$#O6d% Lt$i<tQo O Y3W @žsy%igsKiW]Nc^u0[']7alDqmExECȞxCo匫<*sn̰d_ASd]頄(cѥ#a9c{<'LYP'6vS%bJ7cY{5ooKjٳ)ŒH:Umd~r_ق q5|ᓿ3qke_*9(Fb%M*ܑse=VBXBk tD 2Ɨ qcRޒI*i ~ݏ=&7C3KȺ,Jɵ &Km|)rT uFs"Oy0D#'a5.t ./%S=2D/I0+RGV ~7={Nol* K@(Qr[okSx;bxIgdWޚ_nL8S)A9j%ENmC.X%Icb,al3i(v0KVX;ܮex=uGEami%1G6uplI3KvH|4ײ-'Z~?5n~r`OvnK[@[Y3N%wPd\r3?K(o1ž`FftƙG ~9-ϳ\\]8$vҚXǗnщ e٨{xuY{OU!@:>-Y|c^n,{75K,qrSܣ[2o\$[M`Bz0R>653:~elٖ݀Y%Amk&RgN?}/1qD;$癓/"NiϿJ]LH\iOP~vO8g}w6^y=myq,W%*j9SӯjܰO 茞*ِ8xx&R_LS^|]ލJxsIFW~O_/$U j#&y 4?j>~7fI]l!'垿J}06``>-8?hHf*ev}e?R~>e;} 6q~ד9GeX=f֬H90d#Ӕx#sWR{,DY^$'7qk}$IHn0]YO4LO;G?7`: {&՜2>Sո&KbGJ(}LHЭCK?T6˨oT(%0S1-rfWDe,j\}8ךW[;DbuO{ٗh? z.uG)Sѳhn 3#N*]4"O+/.]1lJyn*~vQ$1_E)5*kgD[xy$IzqD-KމX5u_KL 4_i:߽~3E߄"њašLDY*IObn[C{p\%jq[ʢrGOl?eƈ~/ݵ5~:aߗAGȧ0pT2Xqy5  _zMS+N3S 5~V>n(zvO%Osgic>MR؞pd ؘӏ&wgl6F3}g/֡=?4 p1i;*qk`h[X<5&MΧ|՛8ӓi~ęYP|l>MWWk$}gϑ_hP"6o =:ٞ6]zäw닞%K M)8<,jt^Ƽu6,b :@Xq'ˮ e\s|ט3=B BGWbF9xgE3!JYd9)^r('$V׸8e1L|D/7:TqE=&H>r3\x{T\F-z|M5[rhϜvz\_4MwlO~])⧾GZEkQ@W?&22'>{őaE 8\|)MGaLlW]hFe;޳v"ޏU2~G cZI(t']^ύ 6qTMYŌwx>sE!-h4˲?0v 1`'^H S2[Ϟ '7BG&4E?O<"yد[9"KLIaW涡MC"GXǺK<~~jm{Jsw˿jHthz%haf%&rxOcP޺.cOlS܆&LIwK>zx-3st&i-',X2VN:HoO!Fet #Xz!|fՇgB%9Bѽ|"*YָWoZj_<At?mNdAv+z{ae' "9ʫVi𻜘r[4\|px[}+?!`t0Bh7v4YGvnx|0.`^\n( Nϓ:<9J#``Q"_xt B#|a;_=6纟]5٨\eB-Y{Pvs~+LYm Wcfrk:Odp İ;er~AaGf_s*qkΦ2+/>U?ן ,Cso7 } ԣ0ҙ]jN^)]7PqPs89a"QM%/s*\,S&bVP"T}|NQ{B͎gE] [LF=J;N^.ի_$:kehA 5[4]/^lGiQ mF\r/HdH} A=]Y'{>~Msuj =gʻ>bQy%..25uu,'J,(q1\{[NQf;,wzҒi SRqKq#\S%;^yT/}T)f@Î\ט>up6 ?l]N'g <'2FL -"ESOK:J^ӗ~>Cbo{G!x$Fhr,r&Skճ d1>} MBtq91Ǿ!q#OfŞVyfť ѳ\IQ|^97jÇR}4/|FR'vߵ+?6Rr/ԎwT^pHC}FE~! {BNZ:CGGiLCA&Z 8LNJ-9Ϛ7D`SZRRWB>$|EqKMwL5YZ/}ϫqٹZ&T $_l9wIn;y`EI4sb9C|_ƶ4>-1`A*[wd󈓘3{3jix`c־OU OgXu0['յ]_P~FÊh3GaTXU>=ZTțr`m%Tig~=(zIST'k^بa C\Dٸ{LېVj/=饰cZ2dHs7 /[>xfփS6%e`KWǛF'9|'k-;j:"&tZ ۯb0Uнh/m,ϮvBC}UG}o@ώ?׻!m=`h@G&]0Dn?[@gha|ҡm]V3 9Uٹr=qVӺ*#W; s~1gfu_qdojF~.Fۈi;

[]\yD;ۙԵ6AlQXjf[o4K<^HG*zcJ.T[z\N{XA̲U&9(A$`w1`Jb! [M]mͪR9E ]j}5̰յkyXO d3iIZ1 lgeng6fy1LO:PkTT"\qï队0lk:Fl|BKmv7aC&-+:X**AĠV)< u E31WwM2Rɘ|r(wx-v 9(# iXۄxb4jzZniNJ #Cz@Ma[8bnNQ8"͍:_pozc]6J d#Mut5(Xb>u*ֽxƸXH$eX~G"zWRWpYD9G v3,ɩ_ѱ=K )`d700#;3ͦ:+Oi( .epl.PRpJ D9.eDDy_ݾ|fu-O =QrY 0FA?:oAU]]y75ddj$G6`vw%V<:y ? 7A4d,ÛhWGL# , gvmM#I3mͽQ;vxVhR3v~#8T#n:vr %RC$DφU{R33/8ywo ^=y;RX [}~k؆d B2` .( [yMln(v7w&z=ǯ,H>s:MJpU/00#>0`JBD ;]9DW7h@@lCyhh@_M(`XDtoѾK'WT>o2?QBW?joA]I#3~&L~Y3[;|근LKC;}7 N4| \' ?C(ZWډ e|և|?2<߷}&P] qP yܹwDS4OyI ~ StgR@svq3|W9vW3]Yp0 g ˛ҙcOWg Ukm~]\_-!9$Oڳ>s@Aomڐi v5[<$vl_o+3!8CWHxZlM쭕k*~dXj f9UՂזrh˫uxNpP,WKDŽciǧ= E߷w FCC'8x U`ٷ)Ab8ȭ1)SWRCz.h,][`1"j#2D2N|V%܅fTm0 $NUz? ә>*&.tmEAa6t?qMOav?nJ\Qq9d@gԔsPl%r?!#&o2sdkd^MF6LbodԎU4GɒaACl*\X ~A֎S݊z{=69z~ȍ:BC5I9 OFBQnAcMf2z ҄`h9]aO@gNC2RW[^=_€_RcQf{ '4}X3+a6ݼ"-vlb|Z7}M%]RQ`~ti]AG6}!p!NSȏQ~5ZABǹm7Y+H&VwȧGeS5; m F`*4] jCR18x>zEǶ%CSr]bKqeK) : zLtUoxIoO6Q C; ig9$E@ۉe݇_>1){Tk5&ɥ\X*Ya v D> E:KI~EH|gx5o)"4 6SR"l-`۬\M>E?Out?"u %$}U\x7W%O9_lhM @Ĝ0gYX毐rQt\ `E( K9Ÿn}&{-֏e%Q L|l },u4\'ܟDSWoN2Bt^A]nTg%D^6mZ0Wuy'Y &Y,"EA< #Wrpr/XK}xې9*jA}uPjOYQF4[nɣMnPzD-wlcõk^pWޒN3Y#F"zwނNJםhe˷~bLhup-- ! +xbחf^V+"3h])tǣ ʵWжwax&2jC Ԟ*4 ,z?c47 hԯbȇ¼G 4\T':?d`/eTx|<ء?Ǖʪ(GW̐K0 L3V2 z|E#f<ͶF!91֚ڀ (^{c  q\DRU[&lvqފN7r{:j7#>Vy_?c -HiЖҞ+ ;t65|s@I^&X$r>>#b8lDBAR85xl[g\ >y [vNlqγޘPmAa8&* DrS6hzPB]mlϡs)ZvVk޺:kSoް%v-VHor& g:ro7]\v1<O[sUMwce"Tk1 -ߨ+Yy!'yD\hM (zӤe~岼5eemMY^m&lߪQdr3u{ėτRNˤHm}[d5rdV,QSfUo.)D6h~s\A2RvɌU\'4Z$lY^?@08@ *΋&U./{R[U4+cޣFҝzF. xڢ~\oH$՚cs4·p)\ЧIXϋ).vvl7l6ҧ٘'&vBw'٤[N3ۗdbHe/bJaBCLɘ5 KԄ+ʺh?𞞦W9e'GPAkB'~,T>MK.@XF@>Mzifa[ǔCCLHXGA.D`zqV DA@&k=HԫV{0< G(AqgTIH[-ӑMXܞ1wF&5q{jKjW n~O/Z## < 3OT @FW+~w0$9ԫ9NbxjQ2<HvXJ^#VSs`SCrՍUR᥄[1%\rz=CCSe.JG153_Ob}mލL;1؀]a;94|]ʗJoO߶y:%G/u3#&Eh|ZoI` ?J $;?ʕ0q?΢f/C1#!d2 :`B ߨ.x+1r-ЪhF VH;StS 2MYܨlGʾj u1j!؟q*:%nd |%#;(J29'ںD^&,)̃W55"'?.!;bg%qfS-m,Żf/;Fz&B:ha鴎?yӆq>_dl~vd[l ,8E~j+N"加`?!P)8BDXάJ-^t[M$WLdNЧ AlKyFsw)GզPâHӺ^0X@,5vZ.! v"Ćȁ{0< FYae8Agrf#ÝOjJ9N~8fT W yAu&o -(m+  n|kg~Vʒ4a, P蹖J dgJ\N2D?1gqp,eFU%3c-Qc*Ѳ#_"0.%މWY=_:U.k`.}p_}1Q+b ;n(s}頊;IΤS6¥R3@.­`IA E/+n<3ӝ1֑ HyY,Ub*_`[b&S{'$mQWn 9׷s1$)&cIPH2j'?3)}+; 4 rf@"5O:1O z6rx1pHܜe/,:H#4 (3Pǜ){56 g%n%;,wr#,LoPzȯF6ðE((Tv:1wۖ1&a}#LkSy|t8U:u+UlVgIٛFo&_4bY/ƠڜhF+5BxS  ̐8L#ٴâ@q`^N!˼:kFGR6[q fAz(ǩ7Ď8}\HAy\*E/N1O\i/ԠvϨ+٣)zГ7܅sx]5"whp1ڵ55$_@:j2ՈDB3+ϞCs (ϻ6Pq92!XU/a6T;4ՅV8###v/_VF 2&fŠBdcQu<..vvWt M X)iJa_IE)/uQdlKo#.Veϲ{Pvԫsf t8F* y|j 3Olu5Ic HhI Ig觩LW4]vAz2GR>ڮ)*&VjExݷ5gF2#}R\sd'#|L򌑹dMP֍+e-Z8| _h^#I$$l{ hi#7q+xDqJM{-OLe)7 >^}0 νS?mHp}&/Af]n_[H>zϒ Vun6?GP<˱$Bg~3匥 72/$7~+HzGƑƠjXm8$J^TDv~RJlO)?^\EzdlmH4A`23v=}?+*X)BK0|؅AᎺ1QV(⦄woxhtof*"zq1om_dN%ݐ {fVKO U0QgzQ:4?HD[Jꏄl9S׀-P8a'cS46Uwg͉üP ~Meo~@Z.zW!WJ]gcht4Y| 2{喛)|"(uvdϕ9 <޼6(J +{ uUj !CMO̷J2'gQLa/ܵkkh  HhBψSvv3UΟZIx/M ?<\lʧľД3\I4 g{q_ d; #c['<K=sT&g} +Aj;q!+9VNR‘ ^7csUzh -nkx*=fZ HC`!D<}e>lQflM+&9N1$0*kgJ˪BzN{~(f_ǿyJAG(kG :j~&-r~ ef܄6"v*j?Iu_KB*J}A o>޾TcUr) 1"jDnOԂ˸,H>G,\V)1er6W!7DC7aGq I ek^4axa ',u"8X5AD3!^M߽}s]fy?ȼE,Ө1D|YafIҴb{:$ st[;£}g Vhؼn)MPEFJOuҽ,^m?.&ۯP-5 }O:u"O_T Ryfz}qZ?\P+`%r-~0<<}ne=T@޶j.HwnFޒSZJ9dSmL`\nrJ:|tXWp{s $Utjs+LtSCƧsj|{R<|6Ԟ5JsAh܄5B 4w Uς!_8AQr<=! IV¾^ۜsw1Bج6K|!Y퍀?!D t6AK|ϫUnַco؆oMҵ'fuv`2 MͭI*1 tirìf~4R.zQpVǩ 3+@ggDP JX`X] x'x©C# =%Č7}oU9,Xu'M-GMX|F}>}o)6߽oZ8nm}=z&r(*nwA==}nuo]S7' g?\}f[.~o?zhsӏ??ޱ~ߞy0I 8v~~/>ۦN38/]:^ϴ9Gޮ-{i=|a-ײ_>&^q'^|G Wno咉;Mjm^ڥ^[vthڴ{{٩P>pӽ{Þy޲_m7/+?~3~{obM9gʪ7o [66,ٗ~~e1u^>|בe;;v~wKwn~'Mo5㿿1G}f)'֛=W~r};ƥ/8b6h;n~⼥wL託_]7mqWU7tۧQzq|ޞ}{xc_7n&ONnv_u'~k_ʞskwspĦ_>c3޽-Kf['k콨Ǟw(;듯<-_rzC|sތ}nr̻.{q[jrzbmt/;m_{{}̝WK#lӫG:Zdv/q+ǖ`oj׫76@}%;r[}M/ wᄊWL9aks%W_zߧ;kXimۢj^;ҾE&o}<=jN|@}k^˯mS~x%l,oTBM]i;lMC>bqPP}BUϏ> Wsjo{+wԟ>O]5mafʈ9'z)_~-56uv oX8r2~Է=³wϻ~>F/>|xz@_?}s;jEϩؠSouWl0w?%Mk&kj釫w msqɅ=ft{5\jǻ_ƇVvtovSqږc_i~{̹v_|[N{ĝ.VsI=-MzF[؃G\7FMvOw6|ݷt;\u5イlϬd^'vֵpעmWaāsmk>c݄>ܯ/sn o+2W!uc}7:?m߳ຎw򀳟nr֮Ӆ/legS{Ukn5jGj̖=2ub~]N}]|sAdw3alM<_ܻ??5{7,xnY=ע6xvZ֘5}vb;ٵƷ>̄9*i |𢙟⓿ye3xZQ ~7Sأ/4ݒav!̭7y䛋jN5+ΛUE׻q 5k_x7씵ow~ePwӒ}O~w>Ӥ%2pU^3M\zn̈́?Wzن>xuxd7~_/tӀ.yޤ^POl%;.Y^e[_8va{n}M'xZm .O\WY˞O.SG>}䦠Covߣ ߿[,_~۶7WѸgOク{uqYz#lSmAbbn7-='Gv#wѨW'۪Orm7I}=ﱥwtϺ_gp5ƪc\?o.m/qL[h#?lmͻVG76lS|~_wkƊ~ӲY?nmrҬO]1ߝtM_ȴnϯ4:I-Ggux@囍=|=͕/tv;^ڎM{[`Vǻ{lZN+6xjeku25]|P;\y-ə zO՗;nm]Gw,ΜCSwK<項w{h)Mn4n  8~Cn]4nr袺LςNݸmեV,CS;G>`-m>]L{]rnz^zl't첱uҶU?佻nbʩmFn^_嘆yN[YI4޸\hͼ~o9]?ѯ}wy7ѝ9sdF~ܵiv%G,Xo6 ^O=4{z}շm={{;xkEK}W=ϗ[:xݏ߶/ kq6zQ=?Z֮v/1kky#oɏ΢S5MxF3b[>?m>x:/?aVe>~g}?!>c~;=}Ԭ_^{~?'?;g!^VIu11暗j?xΚc}8'q_릵-<9x+7]=ƽ&n\hz+nv;-_QM[5FTdgtCM3S_~Yӯx6̌- G#w¸+oy㯚U4|`]'7_|·mOz{y5^--x5 k-F(.9h={Յ.=dC{rʡj^粕:xfć-?gҀ[z_O[tͷCOj|^.8;v֗?t{.Wv}#v,_~n~=nӧ:V?bE;'Se7]^#K]xOsΒY6{ޏcv|o]ht'N޹w~gǧC˒JtJ7ӾY;0rހ{e.KAx,gV2{>):,ҘU?HӺSҬs[}{R:-AF^QYţZ :j53|hհJ*lB["6$jݶS3IDH$ $ %QGZztmՋ$}D2H)I"ɯ汥b"uѩs$Rw@HQ@ƀҶg瞱@.EH GHO Զk6@0MjR~y9ulO.y`Vc[2~yu,ݝ38RO7AqtОGG?猎pFB}y);zl߽k?vb\it;dfiD0Uj./D3fuHJk͂ kT4Y* paR]`8f,9Gx(;3 dggGa LЬi3˘G1d! >BY3i1jDvYFQYBEXe(@c~V܅܅q}a{PJngW~Hqϱ2Py)S]P(1rhQ嵨yCVT^mdR_{ٞdgzU(thW+U"(0 C$yuJQ $!9%ʕy fe :E^"܀geOD xVt E^^TU9饵c#9"dҦgkSFmz9me-H.#ԭtr3%C(4VRS%'zfx6e[-jy)g~,!DJqWš:5_!Z7(BnZ7yUyj8$w:r3ϲruq(5)Id3L;ՖrV32$IZfR:0c(ia(y3;P҂P9vY`I10- $6>J4 B8#"a#"]J<"6"J3O!"D$H؈b- "@D"RH $HX(5Un'yt#7y6$@IX@Ff<22JqK"DY(8RDi4Cy,dAAyQV r< Z9q<رNܤM_"of[6S /ltӱUbkMWX0IydCBp < P!C0By(d!>yc4B8 OX'Ͷp<ֱNm q<ʱ@Nm 8y|co^ '1`)Ss, v[.hEfg٤rIkܵݖYc}\I" .o*d'l\@ΛOtв44Щh=nM[B prrڋ\|QZгD5C auTBLe9 ۔iңMqgW^^5hDEkDvLJwdIKGu>rx%Ouwh3`2R34"7?i.EģAǭ@L,YtАTL}JXFVqCxfʐɠ QVFdVF)" [2E;Xb]D0ukKF(҅ɞ%.$F{2[] wI30 sT2PpTGUQTG>iÄ$_26BPOI!L.bXttWKPL56Ɲ-F$`X"ӎEJz$(] .= ]L&w)H[;*ouIRAi#0!IQ6$hC6$F̓(UV\xLTa2Sq#E\)KT#/Flx /8rq+r%se*$v).aGt)8K)EǣQz\1Kj=DnF2A[<֙xdx0 Gѕ(4&vqM|1KjuߘY%ebd&~a?SL:+ܬݬ_cIx0SqW([@)gIR<uk9W,-nP 3md 3aJJ8M83 S3$N ԢS pqjXI]daq/S/ej:ѾL8Зո0v#L Lv@5U'D<~X8f'*ˆ#z'H7S%-]-_qJ2T*S&&$Ow+M7+oW,%MgX<52Ʀx& =qn"HS¤J[=q|q9>Hc 橌B(EAz%%Mg ^iƯwCz@@U?XV'\4W# eQ"e=F*)6Qr^m r4ʳ9bscnUWMN/)AR^n8o[8$#*feSCmqbڮTWHhGgo7c⅖x:/l*ԱEu*#MN83ckĂXˆ,HNWcŘM խdX˱[u894M|N`oT|߰K~X pHphpэOqL!NWYuBt vcE,֯)S8x+FxefBENtaUbIL5fWU w<&Ωb@(GŰP`!u'*Ѽ)b(sRŠ1 Y]%\dM8 qi aJsYR:'AfF3Ԕ=+%O]+ʋ~;aO=_si'Vr[֯8v58T~ƺKYe'FJ׉b8Vrq1ʱht-(ǚ{שּׁX/eR:7[g&rk,1 qPj[v.r<Ӛ=``0g䡑wⲇgdC"R!A8dutS&ݔI7u.vTo|G*d(VI'-J]xV`Tɤg*Jz9D,vԭ==؀0Ѧt*y`PI$gKb[ 4fҫ U*y49MT>aBG3:Hz$= O^DVp2 wI:Nz<͙lQf1U6~:\$}I_W&#,$]v+t٭-Vmn&IB`d%jt5y434M>IKǺ)ҏ(@񳜧V(?VςGE: /N-\LC˚,?et٨V%JCai5jXyEssy] ?~;*mG)18GYP\9vqU#r~1<-@£4GINcrf;c h"ZڨeU4֝J{-7jX0e界.r!QC )h8zyT 'f[e+ZۭifCҪmNzR >ƞ8Nr4~H >4Ye4{۴ݘ#UVQҰ%%c*:dGQVqRIo$LElPZҰO`yzi0ptiհʲҒ*L/ijyL-/O ~^IFˇKє-)v9n1mTLD!͏T9f-R4캑Z]_?-cCmn4E/yv_QcjOE=T -Ԑ0mBc*g(m~&~=\7D O-uCБ=[l~A4|~Ph3a8dpj[Įc*Gm~$5 l#>i/"/^8-Fx'`nHc ⍻4?_{>`]R]%O /2 u|τQ9Ifv]C*6 gP m.Gl86 /*6Y1O.__s͋^[Ok؆!hLmC$߷)l Ps \~< ?~j?c B.[QVpBx"$#v]s~ uad??9Ev$gai)$K9h { 앀r hx_ ~)|8%s2G/?{0暭_!~61`>/9C۩#{`Th:g&hLgg7FPW4)~!##>0 )A3lMOu ,CG?q)/lø3U<ژ<!^3!Ɨ&uNA| c] ]`NևdLcF!P>fi[ad ʢ?և"ic80@%PS{ CI'>0& m~`e#]5<b5E=֥-?a<4Sx&uq>GV(KEy>;̗Dfh'?y/l_A`޳q1EžOC>P,G“6ސڋlH.}@[>-<{M? ~ nsanǔClՅ|~g0-i 4{?b+G|1Oև|ϢA<#5 (y~|[fgp> !s`8*jp?T׀}kD| y"1"SX$FHOܐ!%DvO> O'}{IC!Rdo 84_ ٹMiAjyp] la"ePՅN(iqxMJO伡xMk?.̣K.iDRӈE рO*9rvLu!(|^?6$_yI?̗|s#/{T=TBuAHCڀo=A !" ă|['$]#!Mr,k7"=sڦЇ|5ci|$̥c+MfZ4] 'Fgpnh"ib>GJbN2/`BI!/EAR  *U{mRi#-#"A)G!}7J?<)/Ec #q f=`3->*vluvP7v@(s>@yv #-<9a]Ha*#s# a*p"&kV_4"b=%_*{J⾐Ym(akP'L5.TR سVJ~R!䠔Oq%͇`(#n@ Yo4Ma\h]B]2bl8+! vM"_f<̂mWt8hrió$QQ{(Gj${TU4p>glBBtӚ~2_ ?_:YSU8A<Ӧ4ėhObf &5⮁ P!?䴈&a4༣r𓐣 aCgS@ XӁ?pn4ʢq{J 5rෂ#!=Ai#EkNS@bqͳȦ ̕,hkt`_E9A~M l#ˢ0WП>P CƑ%lkh`h"Dؑh`shœ$o " ߐLa CGr>IJ%L`L~P'(w4]9@Fb.7 . *༊6 kaȉW%8e.[匃xA΁ NBga hpV%`ja#J)r!čL1p`P.m{j6xEvA崽*ꗯଳ n@^pG]Ǫ3ێ8D4|}l[~A^<ٸX0ZýaO0yhG@dacC4¹6|U AgޚE`W?H9/҃30 ;wMiXmޘTgkAzp]rwtܷ_"7&1E46LjbIamI x B^&i:`nHwXf<+M2G) Wg3ʓv^ACpGyphm{| tNSҎҾK4XGJ>cޔ+$bV^hÇ#K!"ܧS? wxJ й+N&C[]߃}b%6["ܗp9`?h|/' rx.}~Zj|R|AŃrQ9 |3p9rop9E-.`7r`/?'(xwBVŸC rkPw+ 4y̿#_ =a9B59Ohh{fvq ؂iv4D=C4^ Ξ3ͶLi|6b~ivNBΛ uŻH|3ƶ|syg8Es>BΦnGW!  9(}?~ ]~Jbl-Qڃs|pipO=+ QcaSk G1?f;!`e _9> w>йÆ1?M`}^3 X[F~-$~>pzQpvOCf4b0w+@#nxˇD0  xC 8+N4'xi ߞ`>sڈnq?ot H(+r`;MEvl-ع% X_w |Ʒa!߃h/-8oL璷5l/`\R [cGۮhz$&c om wlŇXw{D Gq~iە ?BxhO+4(9U"8gN4EM9X N@_ϳ{h Nm @oTqpf΍p=``_}.m $! m/>ٜ7C@)=`W.1B,÷% 4l߇3%!q\жl ]崣v? ^; : _m5b_]P>mFعR[D&z h $R-Ug,=[։犟E'!UUh~[]D3DKDC/xI|i!vNIøHʷXHn |Eߩ!ܱ,[%' S (~ }xV x<7/ȣx͂P:Q¹WP\J sKAo0/D| hpMiB4M:s*~:Ίk<7aiˈw5XoZ4BHIXw8:D3=++ ޲[6. ?#c{J4ڇfƔ_ݤP i |/h_ cgo2R&1|Q 8M;ʅr~!m%40V!򳜐O} Q>@G3e0`_h!<|wb2{6.NĶ|ۖ7P>&07WPdBߐ4`.3p&"?" s< _ϰpywNχ/mN&"mwg('g|vH=f d572o QЮX'Sc@>Ds|c84 fO?q(yx9o Ξ F Ds|D rD l|Gc Q m\/dX*p|/5@dO: WGg9#6.{ħgucs:>Gi~ip/_cN=;.+8' 8d#*jrJI/)+]jֽVJjayOgsNn3ﺵmd[֪UHR-K~H-kUVVT(;# Z׶KZ;"QمHx]{Tw!2~FxԦИy[idX̸*P?4W搄RlC7je.uԔʕ[j&leuЭm~}y6?1J]AyofEb""nV?\<V}8<,";9h]wAΗIElXH*&`nK7Ѓdd~9Hcm+"Op=s5Pr\" Y!,A \%cHQ۞f&@SKgQ}n?Q,LxBX@Y4#4YGX#=|g,$=V`7uMKK{ˑo-~ (B$zB*穯Hĥ ].d#+Sٟۚ! ˕ʤLY|&eǪ MPC~~l!SYC1$jf{P"VE~òJUmZ6fO1Km XZ@ =( KfmC8hrq|sdum* Z]V=KL/Kh4NS?4n}YyC8~gW/ b*NE_@BQ#9h=ck-8Dh(fK`azMe;Mj2bCuMw-gM[? ,ghQE(%bbpK+ge% xh*'k`3XQIÄz0gB_@vdbyb j7=ўkunHARl=C5:l!/윫]sW~>6mh0z'$O)a>"MmLJg@3m9Nk'1-mq`~!?A-<ƳAtg6OCK\e7#%U}py*y9݇C81}/Ë2yyRbV#=]q ]AqLHc<^ֈ>J* N:] FqPQG>S哉p>~ -E._-(8 m;3R>L# ']IyrH-,6t)yဎ__eˬ[H> &]B.A9GU?_059-)7+=m 3=|!,wx6: 9Μ!!+ߒvN;_rixK+/V_/&Z̑[4xiD)7j 3x塑2,x3dXΗEМm9Rw5xC@sjscƼ !߮%7'x{iW K%S}yaHdN Nx8Yg6^.L- X70xκu/팻%l~gx;Ӆ ,xvVǮnE՗O4cQRxu06wЁacѭI100644 de.msg5)jrv^f2@IQ w`kkt:FlKARŃx^+: H@=< #fBwx!j:Yj?~ZבQx͝),8y+^3<<[~-+ Kxf(*my0oŗz::cN!JGI 3^{&5M,mK=ݾn%I2\ɓ jƳVUBqܸ -ؘdxL0RbLZfYYθ3 ZB4Vcƛ%RR,~PBÈ71_EՐW&]x(hnX xW[OH~v~+$Gq4,nA[vE{̸-b3c㱓Awn߹7Ie8=#Gh4TFRd9mG!߻ ڗe:˹J㡖qΆ=:5 /\R!_^E:"Kɗ-0"& jƈYٽZ.P X7_RnفGFcjx-`Pn<<`#ƣR+!*nąPYhjs/Xcn1NDpCS e2mH!}w~T;XEyUh#0(5HXf LT Y|DZ}2d2Xn;Zhv64dΪfvT@+1sqoZ<94?"NfҠjRG>fJvzV:B̕(WE&zJCqخSU5Bʝ &-Eraae8TXqo>ϗ}&f|ej+%/'5Rp5yG#-"@d5Y5iK,G'}qen9\1zTDF|sx^iQu]⢒~ P)C*⚊m''j{ bZt$=3 .N: !~exGA"E[1ͩEԀh=(iefVdJavѢ`Z3:vUHvbnA5m^/i}&?Qf0Kb]Mxru 2\o]ؔ`0Zk>iAa5Qg4؅OUw%YwΟqy._{cvAmkPXB&~yb!11 }3|6h"5kӑܺk@P틆Uj_ 잂jLd<~y&X1Ώ(:NgE5 $y Lx{L^\WWW!5+1))(EH2'JK ikkIEytu'~kacmacy rF~C D0\,h%iSy~1am` O@i/#xOIJKLKJ+K-*peM<ة3x{ĸqBTjQfj15/7 |>;l^U-f'ةfx{8qBtqjQfj1Kdi'µ< EVn3q*تxݘn'tvu|:G$xOIJ+H,I*.΁ +*Ԣ(NxOIJ+H,I*.΁RJ<X Ļ5x_k0şͧԴuPJa8mPЇ)mIoYcBpMtҒ ,+v t RTLsL䐊+Ҝ%PFD8jjk&.v 8&?Ae݌=x-Pv?:^A zX,^|3 "RpZfwl@)3NHլ6Cb2lh8{3|fZ@נ֭OjE9v:\ J5=/p,FoKDnxUQk0~v~Qg;i!%#0(+a/!žZdHr>Iv'i>}_|2ݛI/(%?]31R|N=B|]Ax|ƹHKs5;ZI3.RCrL~'&sbd;[.diɜa[&QӁpϩJ\#- pW 0$7^PՔCpWuC9kϴP;`n.&߹YbiY~N)dv9LH1DYP7Q&Lmz3B[V]7 MI-nLLҒi{vZgZK:Cy`9Z}WZ7Iu$vp6'ɲ4U;݅r,xWmo8 < סҮᲶڽe֡w(@D#GICQɇ|HI0F!E2Y̬HdJqcPfcs&&Apˣx9p93\ C 1R&`Pj; f2+s_MQI ՜e=S'_ 21A~ۅ KT_و❤tZw*}2U6UޅA+(|#i 2ekJ6L8a ٺXq}Bd'x["|e~`pĝ.zAO8Sdk1NI"<`YfRd?DuP2Ec)0hϥ"N=΄-+=ȱ[\AamS[bt6tq5`N4^rE?07}<؇.簕s "rR[H-&89u! \tΝ:i^fn=%SoN1lAL-V)M/MixKQTOWGTj+!\;zC.ƒq~t趤Gû;#kEӛ&^ /kE.]DieRH diWJՂ4* BYNi_^ #ޝ Zˀ-.e~I[uZ;<Őt'hpu޵"횼*0H`O9]3 S7nE|_47[Yu& jͮZMjduNєIW +$_RSI cR;ֻ"tcj;QW -o˔CzIgۅ"o"c.(ʚt4szғ]nw.kۋn mg^pOj?,hxYf%V?,QMMTwNh "fLd:J|qv1,Gtl ,ϡyw=% Y9.3+=ɝ?mQ~;w,۰#ϒ̷YKof:_cP1?W NYNxTmk0\05l}*E(֪HFR8i7FAO=w"5̞] έ@уBaTAYrᔩ  0t:"yZH%%mUuXxX-" F Or>>\G#QA4MN_,˲rTIt A:w02hqeT b-EzcO"ʇv2ÆEA} NE9DezxL1]3} ǕݔG]wuC+ALaw(^.ms+}oY4'l)!d#գt:6\}`.M#ٗ.?v?ۻa2uVr`= 7;-L5ORjP.KI|SBG;OMa4)]^_/~ᗶXxsgYt!%'5XA-[E N)zMA K6 J^ RIta <0poyCZ Q>)>'!ؒzc)sz%xQKO0 >/V}L2T$Ipm9d\/d}QuP3rApTjrv9աڙjJ9{`IWU.ӠXʺFKjzlKdY-佚vV-I-%dER@(C>G\h8b:cu41V -s4ULGrcR> Sn)3)ICnP1dQ%mчoU!'G!9 Zz /g^zp8>ئxredɳWpiZs)p+qZSK?O;+ 55-X66oNvaF˽?Cㆽs6ְ$k5/6x}{_4KR&庮bɍrdIԭ>}Vښ"Y.e[eؿb]r%+I=Mmi ^`~e[./IY鬬>K'gSēW_I ZMVVVy:kv{mF{~h4 > k= Vj_ߪhԶ_;uzݻP1NO0Nƣ4MNɧXY=UphHuLhuΦ:}RzT/-Wg[avXmh͖svFfߌ}' ?ZzZ7 Wp;aq+*42}ڴǃ&O^s: YUQiwzh2'd U^47UcJm?U1H.W'*l+Et촩>\vx 0oΚ`9ҩFxTs|'CP*wJRaVoڂ ŧ(D*xÖ(#Ǔ}&7Xt2U4HctN 769ꪥN.ު..W7х[赓pMѧY:$T5Z.Pu?~nOq1l_ohk̐T4T[]3ΰoFWU2Ɠ̡ʛEP,zNjLdw%=P_7;k|m7ѥ&8QSƟ0T;$kT`Va-FW lt4}^9uEubK|ĭ7qlM':t6M3E<ި= a?^Gm.6yDM: `r15jvpz7:ALyvh{/Tsc="֋ڪfU~00}g>!-v]X+K*38Mc)$;Ji7 T-j`Tm “>t~qczUĶGzպ]uZrÉVIÁ\v/n@}'O,@R ًۖdyq20M1WWf.4 t;T_!bn/fܞ+pi$.Y+7/obcwP^2umy m. l/P+ >f,,/o*pKA&,مKn=v"+JEw׵Cfk?ڟPCz AvU8]F[}8)}\󰆾*/AO WWvo4}ŕcQc Rfyk \jOD߭OT-e:H-P>xˌdArd2I=Y3r*llVdBz0EV%m|hjiڍ5_>jǡƸ'i^k?^NZ`tB׷מouj֞f&TZaNbFmSTe:Ok=#҂EDE8둍y{l ߓ+4J%wldݲDhAa^U|[]Y[ F>=[c=ִx j5`ԳT7My& Hl练&e?Mx3Dپ\3">cp&O {"{IVD:(( p t* BY]b)m裖A/m{''vv'{?wzl@فwkH*lG3D]Y_4.0^xFMOe͗Qw!gw3$B6 /=Ed-F .ykЂQ+"iT MNk:iukoy6h:Izdi<ʶMؠzﺺp0!wKa/U-CR=B u$rLrlŪ}?&xp'2ZS傛rdi"ivj~:XmRot|h'y߂O֛faEOw-=F7q4Ʒwa&eRJ|6n8S7ǵŜ 42ɥƙ05'"pă&f3͝+ sr"Ӌi|4&B R+q KpdttC`CRYqͣSL!V.Thv\=Dʹ8͸=$퍶툮4NbytAz ߣHE~#kVu 09 hv*3Sܹ~ћtDaa-z jfA?Zk\.V;N ,,̰| *daѡ xy(޹QJS XM'u/TBw~̻!kí#vPpakPc[G_RX>ZgV~O'|@;0ó@#c$r'O 0ធ+\۹6KrϺSJsCB?37s7Y;:kaNݮlj "-  N:pi߀m4pOL9eM[Kh޽Tr2ut|5 ~t5wJ1Hǔ?0RϟۋϷX}.CG0e#B_`jq0FԤ< "1 24X*bmx`َP7mXSz.<:`Q̀GK?F֕k $)lZ@9Zבj֪ -r3 xիW}{wk0Bipj<‰w_xF;@P%3*N'[wJPKpH EuN4MtTOGJSw+ ~U@39{z ?THToc_LU}'º?|:a D_ JAgSpMf< uv0{qMّyZT sF?7ih-r4[s0''t5ZgLͺƏrx9Yۓ yWyWWWjxPǀaj+jWSP*t :%\]OZ#I [x,޲k*Gj11!]v2\QaĶxG8i^?m>7'kfGRӁTbMU6XgQ hӣ&NS XWZ)Ts LW4O@1$4%P ,QlZpn_/EZH)"j5X.o v VXoVȚn4܃ڴ|{,{MW/&]+?1 T`7!uȖ8$OuUЀ$Z f+qk`-Ng,&9t!+,UiD!i |Oj ao:#x,D,UqprYVOvKH26*R=ǟ oJV)ŲYiԿux<11I1޲5|1]axwx??M^RfQm5ć'5{DݕN(P}XɧxƤZMޔui7N]Fk|Ќ'p#iy v5C(t0揻ʃYe9%v7/>O?`4 -Rst$ _nqC| 7pC4'L <G҅yKoztdo5{;nqi8G78wt\ Z=VZj`w[1o,|1l4 ZfA5 =]F#9h38m45^'‹6,?Cznsǃ7^^#V7p׃C"+LZ' XO/ehj Qs6{N8wIo2AѤfN/`|`#~!Zה!Es:%bkT]'kWA̵+s+%סb.r񣕠is4;IO 慀==β]U[?l.tk(4D7w/nŃ,i4|s8Ka*# 14?n7%B',Gǒ Dc$15y=C93hb[%5oE@Iqք%N"{[420@rxT /A $,pq7v!s4I}f=}KT8߽D?ߩ9g"r "tiçS+iKJd\/~e$`,p|fXkv e!G=cJ hg?A.Y dwFK?IStU $X$?k񾗑<&޿|gAhğ RcFGӏ9tDC,g$<1ֺ䔨)BnkZh92$x4JJGmpjݸ/Yq]F;ULk:hQ :2WC42@?ߴ :/T{u{E,#{P=+ cvMj࿫΋h 1>ֺY2@`D6y2i]e^zz?گ%YUqQrcQ|18^S{( [A^"?..x-3.nnЊLo/5w/~HVn_KJHٱZmv@G!`njsxYh*Mڝ,Syh\nsm#g#)٘Eif(CWR7`"M<+W /6?˯6,}\Q.ʕ>1+> YΚ#CEMwka|`JowR~̓d&z`Jؑg7+m.8 vYER?DU6ShrV}YN4R4. ܏۞yn_v2ѻ4S^I_ d_鈞2n!`|HMSzlPJW\v;mjQwwvp=^߄ uΗфyon1kxn[fϋ8EVT;~yי~mϕowC'(uʮɮ1=.o{Hn5j1m#.HISQ:k8>GUo (p O/Mx듩Dq' ;fy A3pp\v&E؇$W|`:sȃ͏^Rq陣7!-ăSVk2iN {x3> 5B2Qn!(44U&OO!?YMz!PM6Φ9 1_ػ$KʾE][Z` X.Vyj^G"|RBAd! ʳ>hO.u¡U"k«q? 44%2s^&dCl)@Q!@yBx%QTޮ8( !vD'ȫ$*S_!V53_Zb)5yZXEj2)Z=(5qWM̪,67["+|ѧxBg戀?G*NHΖ'M?jXyC>_F<$*/Z #YKGE@Ewv9J%5)xNN@ށq/$אw?`e}5+:X\BL -/:ϕ >ʱ0OB jC!V]:r+yI|(&*jjwLy`EWmpy+IqC8$X|`#H1vX%r^*J:^ZVP-{S zoUQ 5Ph|o##m?}yMr+5[uMַkmk q1m>[LrHeD:j8Vr8kw;Q/z&HɑY((,t&4\~8$EW_*6aT}e?j6M " o?ǀ`u4m1~ʹ ?!"ҵc+vi R.cy&(bu^rEhi^Yv(*!NȞGΞ?HJ0P˸43˖9ڵhK1<~2 B1/8^tgZyIk.RJr-+$#E ʯ9`9)r=y!oD~\uXv\.b hڌI~:vQwZxuPKNovNv)'Zj!&6R2yZmm6WzVvX 7Iyji{C XWDoaZ27uur٨A$?|, zE5!R6Ev4AA*?W[w{:Rgt;wKT F-yhf)tޞhUKc |enù|=3<{^Ǐ-&s^0x;.S/_G9#{|6huj 9 \5]0c=~n/tloVOP-o\iZ@IݍtD3[feXzdVٌLLM(c;k3:@GrsWF%*3vfUPQ{u6W7(n¶ꒉoVv9k% 3f4@BY5ԥ82gNFCVG{@k,C#a@I$$K.Wk0kK>0lb} V9LY{״w[(8I[0[3` "=0~ޚ;sDxz;#%feeR[8ph0lIJ/1hY!h+\P&Etãۣw$$~óÝ{'] T7 {^RӿtFJxڑҨb"eW(_V;)L%OzAwLV|-kgt-vQf= +v~;<x_ 1KVRiiιe툃2o}o !=o|z+˦70R!G]]%$Le)C."9P47RBxC6=$gUyvjM|~ĚM@bh!O2 ^r|;=ƾ)t\,Ķ!6oZBcx(G+uUgGG^xj*rkujB1)0IH^;:Zxl7y" V B|y2-Ɩ+eRlI%Men\z^j CW-zkcqsȶr5RP+.E{x1OtS]S߂cK"U80_e,%zcPưM`"SNƅ3j6 `\2,y.#j|wntJCՖKL^4p%ڤk,BV&zgYJSUf@*Ǐ%U4ɐ9!}F+1<^9&,e<lL5 a}c{ 6'>%d s.8ΐ QIZ$EtQ,6ZBbCBgbd(sM<$ZuOIN: wh^ƋPr\p /Xu/Xfd\A>-بyQ&^1( kHMr%2)ϙ5`zr& 7 - pNy)V׈=s Pم 5c똍5 `|uӸd-1K72n^|kc<@+PT}I|ZFdGZ𩖃@n) %Y3͞ };n6e71[w^ZXIܯ֋ɘu])bgQ 4-}q7ghE[%AWB}}1W&evZVU5ɆDQ:4#Kɶ◅-i&(AXŃr+pEN(|âc,^9d<ְeE Y!a\7͎x|NDC,l'C-\ܪz9M%?bX'r<:&.Vooߌ06E+Tٯd4ʹ,nA14}8.To4G^|뾩k1=;9S&JȆϿcng #vCADp}&`Nx7&[7&ixLk3\3O.<ƺx|r`fD83ĜC /"5"{_?!@O$t: %zx4 \ _-(@%)~&˧dHr*X%9-0;! XYMbNcXTnyfl;E &Ke0`¾oz=q/^՝Kpyמo1؎u]=&x!+7WUOi$*y!|X"12}EZ+oyd#^yoX:Nks6.xn2Gs3f'64+ mӺУpd/ؚ+-3斏 '8ftOfz6^7L4oF)p͎W3 {&Ox˗XU޹קs@2vuk$T ۼ.;c_6LWY9Wp^BrSf=*P\0Q2 o ᬄ&< 1|"aBdF cxR:eėQYUѴYV0VfpG%{gb}b3)0,K{Y], B<#~THP 1]Չq%Yr7'J+2b6(|.,ۭ|bn*x1)a$",A@?_aY38 Č\ǽ6n'ʵrL$DneIѾPy bX}&ZrwS6`$k{.r%v!N HrO ڈ%m+L&2rc_7ݲw*c_$J^$jE a׷8yzsut=64E}AրLlPMejN@53OFx=ۍr= #I&}us߂i᪚ijt }D\͗HN_pyKy,&Kܭ+`"Ku9O l1N/C=^p= SQy)zJuOgrc%1Rhl qݨ^fjџ]w!vrOkRL^!OյM 腗T 哒 ҪZT Q5#C1'oѠ6*YT&n-} Ի5=gTxꊽTŮ-N+Lh;@o{%:g'!ۂ'hb  uk!T:|4ھ$yDũ D*"t{J`JPx=Xw~q]ղ]~ SC1g_+VR% a7Ӟ9Hobzo:\<9\ku:J?tk6?fl)8[*ᔰa;Qc~drWQNP` ,b>ZDQޫd# 0qaSs.L2(`& 3TȊM{Aq1~ѲV.v>0ǽJ(cu(FY56]0~3Y(Ay@Pp"_dA*}k}KzQK,2QȱMVhw_-9X m +*P{<˨=??{sR'2P[A!$깫f\ ^"N,Fg=?L[ f\Xn(pYC2(eFETt{c,SwJcpZϦXU20)u}7ohSPzgAs+?|]2/6^l9lr.,_*psFE/|>fjAKY[dop{i$X_w)m+cȃ6g-yK}4do͝߁l2(u'E'}xv6gl"0~n"aޞB$Jpúx(i{>JM/=K!aDuovb u,#Z7Pvh ls)|>)׺^O-0r3i&v#%Ь.h.(ե2s乬SEl|AɅr2L!*Uw4u>J ^)\"dmJeEjt 0{`.Y i`_m oCd0+DCJ{2Bכom5;k.eF ^0'P^y0Cec`VٴT!i"ը|*ުٿɒ^iPȜ= q76g76VM$'`q0#XYl('$iPPԢGBJ^= rbR'>.JP(I]Cx6aPI ̱~0ʄw=E!p2S-Έ2 "&X,sEQϪ~C1Q هYdpaXj#v.Ѱ˖{V%.`3+ Y{y3)A4fr18ԯY ZHq7K >SAEo)\0ҥFSK3f^a (8fa3MOIx_w4|l̉XrRz|αKn7=r6JFG$0- Z=xw,e1`"&e7Q5,JUi}" ^?-l.}+xW?f-vh} 1fx7H H*$Rƈji떀4Fk7 fRt\o\iȟ97H5H'DA24"nLqkPJ/)6mi`!n M9F@J&|bwXh!+6v=[ĝ̗*%2u%_4JdAMDFh%TH̥PqNamЩS% \IebOKqZY6r9H8O!q{s Be7TϤXUʝ )72j7aΖ%᪻9K,(XqPbų8z ?X(!c3ѰD#L4Bf4pһ{ӻ{q)+2_Dռyl![#s;9}-t7$3x:+E35tV䪱nw%Źi- kuhuV2,oIa d,>;a([2G%& `j h;{.l_<47"ºͭ`Fsumà]Nd5Swv 1*ÂpYցeX*Ԫ~j- l)njAr<ˉ~Q]:Нa7v p̗zo ύHbNT=,SI(6ھoRn<32 IӿD3Z6& y~k&gV7N016@~' d10qBS]u{8(ԁ/u`g!CzwﻟRF zq{a6)ZB6$qvY?1 &b 6ࡊҏԛ 7VX*0;L/Ҋj`>+M~9=V/8}4gOB#|U]FZ'Gp>?EW'"jwSu]nAbG@̋' dՏ oBph/,#ZR^'͉.<W<Ȯ.n$LxC#MߕBl^I5\3Nj txެkd6qT }QT lɴy3v$UNnono6v@xwپgԏօX˒ϺӾ([½С~;ŇhT;*l(Ffq4/D=5C)Hp97NZ{o;|9꙯@C6-Ϳ 7!\T.#ZI7ax#=N/ .rS+J-S>&YS- &2ع$0 "q-*y_ϐֆGB2788pD:e]Wa)}ni$bʌٜzMfD^WS,,F6 fQW(x r {)ySu}uL^1S/ {wS!+h@|  'I$=']uH_\M*̅5H dWL.6Og\vX crKL^2N ccѲNA鶡|XPLhY+[*^gjũW}L[QTzϋbz%z[FIyOQ{ioI @<csq"*^sIx&.`kkrj>U,IQ|l?{StEgcQ˩NaIuHP"kWd˲Y1(_*%IB_MOT,#J B$';IX$C*{A%w>/LL#ncus &Gכmv)˚ ky9 6KbQ[~HF7q4DkB[SQM.US[!Y-84X &{d.w\\/:_/Rd>$v,e.MŇIvQƂWǥ,< C+6{+_O~מd\/E}-~].=/F*ȷQ8J3cyԽ~'![1sɋbY 4MWɏ]#!|\b]9+A5r~bG(}9eXNԑT5J[U=zU`jT,dJʹh:yyi^ձg2%t,km̊||u[W=en=xz; ;^gc xkP]QjGX/+&Gа8-аVσ/bfg Zl $fS$B ngժ.V)䤰P 9He/Dc dz#O/pO?Pwj7-kgsMg/ӿEw2' ?+aIM_xtnܽD5431]][+եހS9Pyh}u7qt"-,`sJh*nNP$ ȊG:rAPC_`C9z/{i47E sr`:^^bk`FbIzrf2R]}^rSކ+&-Y*[$pMrg#Z-9U]*1fhka笵}W dKRYPr aŇ:bJfq~HhP@DԮyM;mGT$G5 ƻhdan-=T˦ہLKm]BX` Emh[ڋj?iC^ \yt( 0[&7_4;.Ʌ1+I.'ꐳ!')?R z#W_N̸|B4OgDeĹw6q.˃yqbAǁ{Gu/H^gӖHv秃eSA!諱(+6Wd͓0tZUxijX&f5C%Cp( <8/alJp .KFq.8A3{]p=a\Bѱ n遘@V7{٢:\iHmj?ǰ(%f)Сq~;r B+}a5 D!*3ڬe, _XGnE0$#XGg\|E-FrI[eaΝ=Od0/H{l8Ms jӱܣ=q)"\)^wv7: k]H°kUjW8}%h3|Z:!޿xju^wtt lhPyN^=1G5gMi51&_l4W-v}Lāc[BѓO7!_N8/- n^d":u&WmC.A^쟞pNqV8nd)d]9H6hrĠZ3V> ,4w:PO82ש TATP-XNGu> v&Z?zua(}d[})b5ӡ20_'tyF@j^`WE΋Yu]*am¾zuM$%Wޢޛ[ֽ>Ek~'I6oV-[DPUo)/Howo^(C/+X Ez>wOS/ʜZ$xۼ"m %(wr/xH ` sC/ $Š6>_H؂~j1#b)2"F.RfMT2e'ͦ>Bb>~Xz|Y%_K 6FC ǯuo"`4kCe&3YaAiur=m|s;GM% ރ1lG4~~Lkm]R}ܹdoo5Vy f(;;"ux% /[MAHG C!7uLkrF Yvy86c"V7ymp8>v)836+1}9Xw{s#;tK %Z d/9ܫ*;s{jwfE}KGQ­~'5=&꠩O3'V+"'Ӣ%W^MxI^ \98"R^E,_~ן}bɅٛȸo\탥VǏt)mzd Ѐ01i}!0W9'4i򅉭i[ gLͧBUo(K<H!9C^6($)EQ5n몣+++s5 > d ;I쌭˼} *.`EQ>[ d)pMGZ8z(D@}(. ioheO^)$gPχ@ S5smbɸ26>_1e ڼy^ ܰ{q{‡ $%^&6s1iYxF/U\Y?1{^smyK¸}wԻ u]/`G̼x.#p2)pO@?%m4PՂ0O7 #~K{fWz=뜣qM7dUG~^nȡ R?E}iL=ay02h!f kW;؅q4!RhsbUWp̀GgV((@%J^UpbAuE n};vޒAǽD"@i4ϸ!OaGSĨӦEQ PEMS(ĵFv܏d%a?m#JY:=Wܖ&+דW_IRgyn;?no+mG5'Fc*VRg]ÁԿu{x*pa6x3te4L3Qo4xl4^ifXo D~_"+*xmQMkSQŚƨXJ%QcҙZhJ1ä$"?P܈ԻwݺP nĭ qT] w83̜#{r?oJ!y)K4跖foo3 ahKJpp",1HQO3^nxmK 9E/,PKdFXm)fbem폅^!FRdm00ѐi.Uӄ1$gҙ$!5#> k5 nJPBPF =J(%b2­>Wfx{8 efx{8 e'x{ǘ0!O@dxK`mdxKd,xK xWmoF_1q1&$*&(pU1^߁ٵMڨ:Ց<3|S–UG_tMb'wiŞ s(5s(%H7F3،-6S94nuPoÄ^Ot:~⒪4<櫵FYŧ\tEu:NyjfQUc 8Vt]?&%._FwpCyd//xVNwjw]EE%BCR fupQ!8Q˄/ GhX2>[Wrܿ*Z6nT|7׿)0L$9j׍CppT7 "Vݷ}&^L:Q Ϣ%Uxی7>A:Vk) 育)K18a !j *Ss1 '@ͽs"^^\.T2ԅQN,148y#JZbnȚfj{ȶ|Zh W_>2*ͯ>uu85m뫟_۴kx amb>0vL\B6',rHGL6YQ4 !xs-j6.Cc2UOcq̓VHT|aaF"]/$Rep$ޱ9?# z&M}163GYhWZ`>@坔{}J &15jZ:̃.Ǟ؎^egL&;gk#g%UQIiv2.ip-Q1megvXB%R.@/Y5TQU*q2'?H(ΝYނ9#o6e?8^$c+ ]zx}E$ a!T=>NU8~ N5hR#* Sd;8g20^1$S e`PL鉊. %dyYBGo0 "7ꒆ  lN0b(+aR;jR*Ϋَak/QT Ȗ?onێKZ-CG|φ*ĵ5x>Uw=U&zI!z4x*BQPlxtiBRuEqGs7uVtAcߴĮk_sٰt6 PHOf_s5wW>hdAF]+,<۳"I+cb5,cq&eoɥ˅>1x7)p<jLPf7x67)p<jLPf/ԌR-N(K(Ty~x67)p<jLPf/Ҵ[˙C,L':;S&!ޚSEx67)p<jLPf/A»u[0ܷyrGBz x67)p<jLPf/˓Y\= >x;ti./l? /Rs0ixI⽯?|奄&lIx˼(X hݺ-x;tiB1ΞZYo|C *x;ti.g,L9<]bz0bTxF2dt?ϑZ̈x;ti.Y\O7d 2l+xs#.l6BXx1i֫MTdA Jȑ#xxrl΂^ כax^2xG˻h̫t̫AHg_xO! ܞLxu xďd$z`>ר3-9x\USSVQjfx%&)Rhռx;ti. /ڥ#X4fs/?>x. VxГ\y5Dڗjkx6w,=Fs,k/{ys/}Ϋ{R3qE~JϦ;FWv{$bH3S ¦rOpC9>MR2Ed_ӭGL vM[g⧟/_t {91!GIGpUE)Ouy=o '*DZq.V 4TTrTQGsDϏS|_ ֚P ''WbXo;|bppWN_~Tsuymw}"4N2A#[W;;4ÓOhD 880x09/1uXIu"u\(ܳԨ5ES PỠ-+na,tX #[5S~~9jYu9LA2fLI^ '*5[pz4\%#C[G^MLw:'BX7tRhiy1Hr: ̊"9 A=<QP12]wL."%̼>;ˣ#3G-ϣ*C w­x*+Dgj e}<@v ("`0rgPAsD I5F(S3xAd OWwOW/n*)fL|iM$qB08H)tV}?7J!:Hh@-]u qO%wijPX,2\ e!!D,U5lّ%!\@4˜X\jpKYΜFtpym *pp)H T(ʣ" zV[ezD<5 乆qހEiEWuVJ@/Ordv%iRڹ("T"؊γRI9B| Idș0Id,ٳ9qLjW |sh*'0CNUN.KkAdx '+W*EZ9j`[)1Zc{lN0^rs|Uh>]cfOWSq \Kg 0 };q(:cx=9Wu-[(Vº=ۅ L$Rk]h156/ C ROzY~Sؓ8+82Wnd!9\WyeFg7Uo䆡i!d^,FS3VaV,Jz%p(E樔dW;v-C@WK V*FAbS2xxB.| n}ԩkHGob ednTrC^L}kuee\&8vL.'~H\f!BU\̽,Y+f=^S"cx+nQ/k fxN[΀DQיKkO(`{y[L#[)}rX9O=SPx(T>DK-BA#H<$#(\SبX $9CKA781=U!$#H,ZPPX$R+ r*sRr*63$4xe1nAEE6!#@IVڍ%HrEdtLub/8  $_?~[ѣWl[i\ .L>I,R 5@8L;~2)薊_gJ8SSUOczNA Xcl _z[`))=_T{,65p9.)B'H;N=z2#/^x1l[.6˺/Dn D\ 92'0,Jj8BkkՌU)a9i5^,xj WV_::9/5x(wss"iŹ‹2KRJ2R\Ã2sR&3YNdkZOJLJJ-JI.ѳP(WM,Ik+JMN+AV۝ $: lx% 0D!+ +b 8F[6Rej:&k޻y% -cx_Xk:X:/6HI"kj@2^FXxe43#$ MkZ 4Y| 6 x(=S^K-BA#H<$#(\SبX $9CKA781=U!$#H,ZPPX$R+ r*sRr* fdd&)'e+ HU(/.LI .x͖L. ڐ~xZ0changelogJb]5Q(ǚwSu CcBR9mO"Zl] lSb9?QQE˓^Xs%8Fxkh (XZ;za-~c:Xf&+nJN/51̂b>Ƙuni7w![r>f7#/x^'3 AFd 5ñ&xkhP040031Qs fxj*ݏOzr|c&pY֯x|qK݇W^̜i%rcVl6{qsX({ksx8l970SyGFX_ړaYIIE)%9z wl?q[:I71D/!?^mg.ʽ}jҮPc2Ksrw(Wj)g;V$'?($$uiW^Pwͪ~;y#]]O6e;v1F'g,rܯ/onP[u\a: mxkh,)ضF%X`\%-ò՘ WxK`h&ڳ,(y&"-x7:1wDDl~6NS盦υmY0w8űL;Exkh`%$[kǟVիsqFՍpx9:'b-xyj,ѵN aY;Ls)w  Gx:ſ- )N tx9:bV-GCf¸v\{N˭a4k3aPk 2d ;x29׎#:M&⇔100644 changelogn&"%Wn"NS: .7 0`ϗh100644 control.in>$*4J֖Q1sJ4ͽB| ]@3$r#1#qHFڝUHMTݓ t]PK5$fg9"ςhXl\xQ:ò)Or]C1nhN(-$R$[ gt :b"Th&K\a֫sN z:x[{ <(xU:8Lq~9Vo`!d_?N1*#j]%)<]otbk$dx:eޕۊxkŧױN+<x9:5͈t tAlNF# |~9 Hxkh`%%z$׵U ~WF+x J޵}38X̓ړhYxQ:펈jj Z&9NǝI39Ag- t]PK5$fg9"ςh$_x8:rFjE Nh9ŀG]o 3W5;Fxkh`%T?x]72ϗF(f跙 sqx9:|#+Ko,r+NQ!m#ܛV13;zJqm8xR:%7͔cw%d/4NQ!m#ܛV13;zJjS/sHnVHOn d"fax8:f~ۦ:Qs4RT~NYǝqEH 2w#a -PFf2RFx8:WNO6܅)#OȱNnƛ&?ݩ$ۍQ_Hw>Fx]:k?򂴧uN6כ oNS:"8JM %[100644 control.inR7%h5ꛔ辱&V)Pkx8:Ssҹ*Cew NNR=)4~6TfxmFxkh`%2Qu?ۋ ?眹o33ڀvqx9:hwdJ^-l\N &&wamnE7 ΍8xR:ȕ{{JN"9ǾNCʒ" &&wamnE7 (ax8:puӄ7xקNK]bJY Wk'V[m+'x8:/RQ/1-uNd#ʸ B eGxkhIqfčmMݤ:Y sxu:ɥW[|9kR'j`NWV8C,*f8v@njvp,6&\*100644 postinstdd\fe.E0`C\\5̸g3xkhId | ߾;0W!;/L@1x9:@թYM"%stMCwӱN4$z(YQ+\~5 yx9:%L_3.f Ddj+NۭisUx)M8 ]Hx8:n@dإ$c(s/RlϱNzZcV9EPg x8:썱Mr' NX!3 *\cx=Ux8:e Ȋ܃i;'vpNj୍,9-5auRx8:BD~1dxwrN~Dƙ;{& tGe cx`:LGѨjE>y]2Ho)"1NSDte7.)X] @5hcss"y|FD1>2w 4o940000 poMH85!wD#}at?j~vMЍ᎓hD.x:ش\s2| N\xw:` B_qA*o>)sNS:[0}q^C#ڝ?=\100644 control.inRf6{r:ۚw^f6rNJFh ڞ4xkh`%r:J79+v_Eaffؿ 2xR:2=RS~Li# qűNKц A .VYg11쓭=ޅǝi%){_6Z&xk:+y'% Vu&NK!JӚEa=͌As? V๟'Tn! @A=3ϞYfQ{3!zxR: B2[',PNW25 8o>3u$ɶL 7z%45% w!`xf:TgH4xs 7ȱN?~M$hiG@W'a9vCU@_2o+$듙T9 L"3f7Zml1.tx9:R;BJrɍ\bD?N넼r:68E"q Gxkh`%*)ngљ|s2FˠrxP:̓T>r+h3+9N0[)&կ3, ؏mֶcHxOUw'g$^xkhI$eۧ?s-507/L  xo:@ΐׂJ%Pq\aCNsZsOLP?3P 1n'33n8$윥40000 po; O fا'j4mH-~xR:y -@Z#NK؊6pC{d3[=9x$C+³&s/xkh`%rzZ+;"Ooim跙ͺ 0xez8Q3E䬹~[ ,oM\ ^xE4#ctlextra.patchUѩN,AZ3!z?&{Oۢёl x$9eries. sΤ)xl;w7x{qBHMsk8־`~}ݙ+rӬ4xbb!5aӋͭ\Ě>{_x6h(\j4@-oyȑ|D0Vvcp\ dа6$x6h(\j4@-oyȑ|D,`^0H}#]6ExbbMIpu7B>]~ƮcY Mڿ@xfĤfh``fbY_pT…'xi2,C'd)@3(.x6J[Bzc;fM/K8~"w Gx6J[Bzc;fM/`U]t]F} x6J[Bzc;fM/A w2(; -K+$Ux6w ݅o`̻EHӑ/ |4<$5 -_r_޿yZExI>KUΧt˞/mqx;qn͉W+'<Mx{m -B؛@ٿp2c?3zx6{m -B؛@ٿp2c?/-Skv0e_?gY"?x6{m -B؛@ٿp2c?/1Yk7WAƐXa+yr֥x6{m -B؛@ٿp2c?/ "m?[3AWʸEx%h^$['̚"Wսqx6%h^$['̚"W/|,\pY 0^ ef5(ί~)5x6%h^$['̚"W/@ݟdgbB $ $X-zx6%h^$['̚"W/ۭ#RcZT` WpR}Exin; 3C.cw4wC [ox6/F0.chrQUNm/:o7x'[R; pF3x6/F0.chrQUNm/,vc͂HE|MݎfL3?b=xm1 0 8x-D~x|=x-kZȥ&js)] F(Doñ &[eIxK vfx gTxQK0+5):AćMՇ:@h67"|~7y2Ť[,.xӫqX~ҧJ"'̬q hHFx˩`otp'2RWd^Ǥ6 cxA4杠;V67*MBXBnfi+rz Mxti~]Q=Z!O&˦L`0uzS zxҢ=UC(T~ב^b)xti~G;H5R1e׿ \x&HgYRZ0՜qmLxĴiLL,g jhax .ܸ3x('x Qo߮d\ʲ2A3d =\%@Sȷ|K61  J`x̞Q[c`1 qbPRS u /51/ (= 5 R1odbc.erl\Svrg-gJDIAL1Hpam.erlȨ-MʾHY100644 ejabberd_c2s.erlvqd&FDAث?M0W@INN;R=̌(m2Z100644 expat_erl.cic%c@l'=ݺ%' C-X)9.kT

kGoz|gm9⦐v+~40000 mod_pubsub =}YFpΩlB.H2A+"<EB9HWg^~ ԓL<*P$~3 S =~{+wŽP퀭#ì>@p#5)!OWI/фr Xm|}*lx'F>M.x[ôiLi2jY ^wsz \ܡ#x:3ᢢ=N,ϓUISlGz^ jjx[ôiL'mwmvޢމkjx[ôiL{gtꉅf\W|jz- Dxo֯Dp͕<]sx(Uakuݑ푭S2"x}h]$nb⑭%Qx[ôiL3?īg ~ʑkR ~xmF|E9OVi-x[4a-xk4)&Wmn?VHNw:PE -4.;lK78 1 40000 toolsv 9c؂7ӿ$/*xbAZQxiXvUubZxb[aSȱVvUpڙx[Ʋe+F br_wWL[f?F g/x[ƲeBTɫN?UzdCXtF΍e Zx[ƲeBH)_i_s+ ~eY xT >F}1q|f&iir_2qZ.yVZt86ljKuWg?Ql+CnŷS;_P|;[[[CԋxQJ̊QA??e4~E9dZ"N\RbL W-<~ltX{,ڻmzo{o -gz\,.ti//xt`srp<ײ1-f Yoa#aE^C;jQG u4ATNcyN'ě;49e DEVݿ.KL_y3ؖID9ecт)j9juT 9RAĝc`Kw"(ӆ|V02=It7I#WLd,l촨)#΂)!RL>c]n:t֝:qܥ]A& 5N/.@qB#}Qۈmuѝy H(wL#@Y)=e Q?B&̚I d:+ rz<s&@R#(E+l (=?ljn.+r e )GA#?KQDjE7$.t6U#T*ydl|:8@20ƧT6K UMR \ =zMD7JQ^A@{Eq+!(Kmv\,!= ek-tR}>4#vIΒPsys%L4hTX0L*OfҾ x?1IlNőhgj-&Aᵾ ñu#6k@,pbbcN/R?Bg*^F6<40o;8>Wj/R_%AI q1zGn=}6 F|#AiYw\@k}Y|P6TXT#wOCxUA@c}u>K OD($)rPďixC]GE:%-'- 2v/ r(p(Al50m qYA8X0"^:F4gV`kƽ76tXa8v 7*k `Ԇ_ Ҙ]%9vKr3{=ӿ7a7_nGr| ?]#f{wf_ORΦZ{-  'dp\dEν< 9y־m\b-X#gΈ0"!PDXKD^@z9 cB|`y!^+3ˤG)x-S6[Żq"VFL&heo| c@ Kz Ø,۠R#3 Ə:'}ݜb8 (+ /S1Xaa~J0aLO#OJIՔL5&]xѥ#ЋBs6=o 9 ט1obfq6LMZ, ,,^ hal2} &}0az,zfqy|~t8< lޕEġT#CxCqAhIUT׃[L/ӲQNrڭ}WZb`Qd`* ̟){O\6۪M WS$NcJ#7,rv[p˔-A 'YrCA9?rh w1WRƔghs&Y7ei\u)W7l;eUOcI15Gk2.~ř6鞍Uoovqd\`)?^X3G?пu@c:Z\O0NtaM,M*¿ PQky뒓 ”@YB"'Ft &Ȩ]|M|kʧ)Vxa(D>2畨4j %HwȬa~W[ͷ| g8eX"wOcdxF E1 ]W#w^c!#& ͮ8n o0L2R -mly-ƥp1&g~?U#?:TʐZT.{L)JlQlPN^>nܹۤy-.h硙Cֽ cBQsb's2-oc7U y| TYojz-DK'J @#6LʆURS a(E? `.IXx'j5`ʹy~IwR~ΌX& ,ɃH} -o޳\˕bWxu8wT0 .3D=}A8R )LGs}!y-~Ǹz@nkfpÒ>K!.>rMp5uf׫Ԫ\mO*u^m2INT;qRB`XTS24[MUl =bx %ɚ#=VDKep AqW!.ٙw4O)T0ߣly[P9w鯠vٻϝ$9nf.YJp/  k7UP5fơtxi(ogDq@]͝lHTCCF !٪_ (A\yfƼQܾ Ój_AϜwhZAQS~ລr=FL8I>mxh*RO"ނ6h%.{ w%X-8?D`?#(7`&@"&PUy-y:*p >*pݠC 6/XӿO[Kv~NYMB Lkʎŗ,_x`[Rlw_iجYwR *3{Lo1zSLI ŏ"OJ4\9x6 ɘ֧._1Z-#*\豿HZEz΅_\ <:)MiA|\n`Cᶠ=I|<1 AǢO5c k$I oMxA<7!_NSߊk-%Sfjt߼uˀQoO &ӎ z6:QyP#|G#fԕpeN,08R8wvȧMaG?j)8c,Sӻ!k2r q+:+HxBO(l|aj_Keꆺ$A|yMPw/%!Ny]ܫ6 h:w %ou^қ#UXʴ21mf|y ` -j 5 `CPt"tN -G vz!6J.kF%pBJA~΃q8#5Y2PvU)ͬ-d|I(*5|ܟ297FEHÏ:Lq[ :vid c{/cj_G j[@35w$߲HI9DxZO~~Mℿa0+f}n[/ =!n*B/R53\,VgуhW799"vbOm$phlw"\S2翽:٦ZԐܙm/cV4˕31QWvsb"v`k}tMxez rj6b +`v>@6\!axeT3oh6ǘ.ݎyj&;Τb!"b2+6`eIf]qJ oa!E%%8'.!EA}tl`d=ؕ=!de|# OՅvfNF2i8*#r^V%g 0V]&+ɵw,ಛJVKSмQn.m{nJj#B ?l}bn+ߞn~ Sٚtea^>Ѿsm_'R |8#㨣k-*I(i1F(aEqH7B&̪ |;1x//ڎ ".VmK*kaO~~|G#oٜ}^d:;Dyj;g?#tظ3/Ӭr{5V+q Yf8_w+XOR?_we |Ϊ" /~{n+V{i_S91lk\qVsi1u_ٜSl8)oaH_:jY,B $44XS_gJJwÅrƻZ4&Ɩqk6xfl{8Ԉubzaў|S-`ly8 %VUaJ*V|6g%bK+KzY/fr@R<ё% 8A}4 2SѝPGm}ec=oNr:بRePtS8J36Su:- G</e#oaܲ^שʐH/$/3PW Uפ<|#%k$tZT̈hnGj̹ma@Д*و6N]g5p =ec66LJف54lb 99i1ƃĹ'S̽naB|!˒\cj50'LH3P%!?dvEbHѱ#ب8Q9誻c!/Gq M$(U\ccʤȀ|e@TWA1mݘ. 41[c>E{wM1r`_+=r˛&cu2 jǮ =`6TY5V: 1>nc!_W/?jݬt5(+UY,!sf`,&;8M/gӆ9ƉC8ՁIaXXT_GzxYo6l{ڐy&Hu [t,4)NWHlyi:R"PshN}y0,KYym3|s!nqE]ELAHX૥}|~G;=ZTz+LW*BSO(2&)lbyՔ7<@|jp|Qa+KG,r֖LUj^^*ZjquSf^S S Fzi~v Dl,3J`oPook9J$$^sfE:Ed`g Oz<{+Tk{hTIr(*B Õ.ׯ>=Vs"cTw;$8:i B%GJi()0Ifa"yT?:(kp t!f!.G")Zdl4D"3 /qNO>DZ hb_Y& D=Trb< ce"+qso;pr+q)/R~||&dg 0Eױvt*ڎKxzϻD+=VvMsYɜHB&1\wb^ӰA\ 5S~{ ICc6'XI |H Cy 8=}+,b!\K. yTxޥC׻Sҭґt3@"Lٙr& (_Y_ +B)&;< 6=5"JqEڴ9)Q1 0)`_9F8P. /#+YOo刼i) ) "B0_v$F(j%'NjNN'תֆZč^DᴊW0t:g^0/dn6@9:/ê!zPhJ'P=˷JY0L $mDiBUlدML MT@8`@U\{1O=N ?,z(Ot4!*Ui#ڑ5ppqu&3~O;K%=52ȅ:eFtECXb5ģJ=JոJiNuSv}RC<`pxw +D_s#WxQGGAO`h#9b`.RH9$Fy}{×.)=40BF%dFFx) !f̂ޭKжp胷[W{L;$mXN)`ȢXo :M1(_XD5W(FW- w%n2JӇxWmo6, BC&nAheȚ-? Kjd#)E8AhϽNEӇdByܕ<ݻAh"ʴکV[N}z,5[6HjnNoc(6!]Bϥ4t'q oyRILѨdlXm=^o9 "$d="JخRU67Fž #jc$wOq*3TܧjbF5.Q6w9n1aU}L<,Ci|IeA@'wEb+Cw#Rrq(q!kzǀ'̫(K-¦J$k$F#Uك$5נPUнMeR)U Ta#-Cuad;$ka~0ՠZ?ˆG`jka# &Gm4kaOΗJzJ osW(=wdPlVx5䪇׏~WE?bSBT͸oת_k $lE]k]\wf+벅V7徾* KXjcP{c}qpdo,jr^ :B$ [y0N[S6P 8P.# [M8_8dDꇨ b&xW{o9;s%dI R 宴DAGRV]'1xm|<!]Tu^ooQKT\f2j֊}H> ln Z;wд1I$tg hB?M(iݚc>ܚU >+\>σ=dx -z2B'A*Nt95e!֟*p3\,2<0ج2 0LqgdATWNP y ^v. nVj2e| 4 0@P1lI&2ǁBS_q=C)ZQ S: 7|T,ÇLP& 7:f7ZH4ĥ?(NAQmJÄur@21F%I I1iOg,d ͣm=fTJR=eQ?Lh=Gn"7<{_$:#e}o%ƅf#b~*ȟT?wFiyozn뽄n[gge'8) [c`axK\G`vl.q Fvi"[kh[.H1$j3̳q]<3_ p?l7ЙY{\HO3O/LJ' 끵GTId_9bVk82J>5uz-AT(ӽlZCK. ?h1>%^R\,N 1.m6w]2+eD+WO1נgt;U*4WQs}Qj1_T:)zÃ߿ݩ]V6iS+|IJ3(iP;>P PJ`ŏV}Dt*7}̛/ok¢F.<ɠ.fЋ;O<;]qC;- Bg耳]-ܙ_"7rbDƣ:ndZxޔKxI.*w^5oKLss.nЀlɦʣ/z8ᜬIGp!콘`lEf'&xq=UmTA>7tpTݝ('1&䅗cRڠ6Jv"zES6 ݸ :vxo_h ث|^.xMK0ͯni@PQzٛa65n,T]nӵ.0̼޹bh+Tpij(44b< tkkQh%̓i2&-dLȖ)&A[9f(˷ bg {YƀAaDQ#C )aW|zFR"GrfLHA8gU:̚`Z®j#x5~'<*yzq:V bݮ'@O0?2]ތb_?fâLj?\+r6to-C;rc/)죆iLxP?[X0鑫){x[Ŵitu7m: }=ؤAsz Y(xůN\bhɑ?Wx[ŴitZpvnQ"dt6˥Xx[Ŵit5wR<9D4쫸,1x =촁L2;Pb Ͽ!`x[Ŵitx kC Œ5b& n xF.rEV#ꝍ tx(S(P+\Rg#$.Y$Gp9xtqBč"]Wԧ\X-;uNs& 4cxq[L.4joB|.Ʒ5 Qx;8qvnhA52ӽW[z? Oxyo^Y}#T<<@F{x氁o;#PR0܌F,x+H-KLK())OKst RRRKr 3ox%=p#1ly6󹰜t̹qO '=: %x"1ZgB-oU|'=Xxޮ54د#c<{s|1xaF&10WO&6/ ?x"[۶9#t=*\(') xKJLJJ-JO.KLK*H--H,ɀp xeO=O0szi%t,e P^K+E8qoxa4!gbiԢ>BCxif!̴k?W[CɒUβxXmsF2H,[84tfҷa$b(wo ^,%mv}nC_&٬_'n=di&'iğWc`^_y5 b9qN "Oļgv/9j(ΔK3 3_r)p9©Hj8ѷR e U~[#3e? 1 GЪ/_+{?AEB#KjgDӹZ8U%k i6/ޭO;t)#j2:rP_r]=?sOR-b$*p9'~opeH:F۰,[S汔SJ_Gi0JW{)@ӝ9&$r3WvZU|N" #<\ǔgPRJ%N|و`=x[yݫ1<,J!){?oYeB$fTʬX"/ 9.?%B՜B+w3؈I⯦BE┠Oq@Ui[ J? 온" ՅKvgZxL48ž bQ[X Nn[G&)|p_F> ߛPǻOC*ϹO4&cU0 轨#>:yBui,()E"Dl&^bgyRsκʎ/= L-MXTޗo ߽<~/#pmI i:?z^87_s~#!A%XDSE=2f,,\V$~ܔg2/W<&_a~e:~=ju#.va@]!JA/nLPD 5lRvQ>u#箴X%UA^ei,]Ca!Q/'. +rrZlg.f,)xqBĉ6Tx!41ko%FlnH(xuW]hI#i'x⑝DQFJ$9N$+fixEKcY4#'M[ +З/K!KRJBR(S.҇;Jk8~sG37}07kߪրaef#iwmugNqu ~3ivߘB Ap7n;\Rp[þ3[:!2nv]rmm8Nаm戧nG=+4=u°1nܱ~ta1Lt-oY{FuxÝMVd p˵A9ۻ!XМȤL#v"(.Է03vkH^X=4$ҷZ NOl[C6ޤ)T:6o+ Fv,J!*C Ax7L&6dܖ]#6:~>nZBv3j۳z}SA2 oAbQx"A, g Xuj@+ + fYG2#N~%ŒXnrIIZ#S"rQkl3W.kmg)9\FkeJ#NQͭ@"*UJ KI8PDLCUuHu$*O\<UOZ3I$e(Jqs#$B]'%p ˷2?M=R<V0[~-w2CD,19M`g'd*'Rt+Ü8%-}1H_@%~Y$ Ө+V]Q۪ 54ߣg@o ׷%[AF2F sXɏ>*q4Y@~3_<* kX_^D>#~#9\bXf /8PBXcyϨҮ|XhVT뒨54)aI{Ĥ`uR_*mj!Q}tC6G+BR1V8 0 p"'+‰we]Ř A>'ҘfTLTh P$ERk)aa?_ Y~{< .dөWLc'"8YʺpE>l5q p U@? 92?\j1+_`"ATۖ ˢސMi. \f]S W4r 5P+ zp u^=Ndz"CFH 5tS렶m;IC!w~D\CXFNUw}s_?(//7?"UDKexp3i7Wџ0jsc߃Nة0w@#&ak_<>L `w sZP nh/:}Apm.q~H2;y瞙ƞm؝k{<|vk,=8 n! /˨~xv:vG%-ڲ#7"bN1:w#:6&ULxE 100644 control.in_uLU#rt`7AjPH,,vC3 xD:uol XGxb nN1:$Dk+hl |@N;$100644 control.inS~J@ӈ}[#3_݉^1q#lI,?L:.+ʨR100644 ejabberd.postrm+= _Lؠ -N>Qx\:7~>y)-M7N19\bi^]MyA9?h100644 control.in66$'pfjͱ[$>x1cHk}4n< ~G+9lx9:{֎)oQHO"NZˑ6 M`P@,08xE:LFzd0100644 ejabberd.cfg8ZN~O€+z,yd+?ClbYT 4+XzҖy*l/JiB@G۶ '1/Wx'׃qc-Zm40000 scriptsE ɕ0S#0100644 watch\9G s:fmgxE;O0wusBUB ,1_7ikG~-x;5;)XH3ހIki "] mQ˕\Z\T J(M50PzϣKť!WR1;bEjA }Pj|:Ncx bfhkmCnL8֡4mS׺n#8L P>Tt_ܥy0-9Yq~*3 rSaQK!~v{xVmo6lKvҤKC6`aēY"Ur?~Gٲl]Ax﹗37\Hc:-DJŃ$` :!o&'gC YT uv,Glf+JFI\h,LcҦk֞Bm%: *l J[VIz7MBhԊd_BV%q Jqz6V_;¾t Zy`1pV.x;E o_N^:@cQw`Qp|LΪEQr)tC):CjL?^!KRп- k?:~љss$Ru7 uV];ٸxyC#-}&v]'QD`2XBsfqx$ELzƗODZ2a?F.4V:NJQ%ٔX S?3>잊aDp}±I"#Ju.%`$p5f_6xG^{Z)}ߖ~Qk;TPN HDF 6!&͞ Z5CKC0]EÙnmWTʬ4iJJs.j[qAj+i.)*˱ԍB|C@PEmr]m_vKե87oٙ_G{uTx.UE.ӾKu\d§d؇㳍Cba܀ۘ;4D]+j{.{H 8kҏQn hm. *J'n޾񧛻՞x? x'~Ix]oX4'˳kL6gcTxv7q S-NSHJLJJ-J+H͝U)-s>f.mx'_|(dyvi33[=ix$|IxafFG$+Kڼe#fONf- ^xTMo0=ǿbE]ZM[mb% ֱ'cGJ'ѴU){Z{3o<3~YL+6j©&@a$ӱG<YV!c"kPJm0 HZ<#w},v֕άmJ%N*]ʚv+Ri1ڿi<.&/_hAM&nT#Wbq%2.Vd 7TLknZ3'#PE}롗׃;w :[w>d ȶNgefZ{ c%w:wlNsSN7 7&%tAJ PV܃pHdN!{,2=K#6X/8BÒN6hCjm*+G,)KXBkSڃgm8',[9q$X!;Tl<{OI6㩟!Rܘ(x}2tOz38Ҿ<%t]asuTI9ZO)ѧo1c]}п}q-`uV؀P4[ѐ kIfܯlx{̽k%?"+1x{̽}{|ck~jI~jVbRRjQ >Y)B Jtu JSTPL,UMCxxGڣC ,"xn9U&LZK(Ùh0N0 }V\?blj#:dA AwCӰ=իaL$6[)lLVG*{#e`J[sMypSPJ)-Z0qM _"2ϧFRj4RY |^.t|G\zDDXX@?FE'iSLJ (Ōܹ-(-25YKGY^Ye!rYiR!M^Iְ1NvG L[ .K`N-/>|X.ojj5s; SgGM$m/Ω_?8PrѤ=iGj?]u@U҉♀̓K8~WZ "52T7Bp2sOpjR|I%k5ba:n>N|0^KS6xOزó0w$`r| ^AtTNǝI09ʚ+gS|z{69 ;9~U2 ڳ!y<­Tn4q4=y񨃤{I2>܅WM7\r(m*ͺ E^ڕ?± %ɭsңǶC_k tY̱c5P~ŴfJ3`jUI{E=`*|0]. ~@77F208s.W 82pi/>X+<:Z0R~*\ -9x7~+`K Z'v@n3^!R4uhJ-f\$|7Y ^]8GⷫoP jw މp21*ŖbFcawb>VP@5f2\lQX>X&m|dKqc .\Gi8{G[/;Hga}AlVZy,`%btc LUA2@1-a~@PZcTy<j"l嬙JRȨU!( mn84*gp w#rdѶ ᴪӿ8smikY+ k;RJzsըrq%. 1pO¨E !Un>X,N< ?Kiٸ;%]{/z ~X0V0vŎvE@IS7gޭϱpC# ,)6}@AS@Z,(3r : sm÷>;.MVD~UW7ƒU~Pu x^uWH0<1TnMKnlZX˕z4G줒T/]zzy^]=\]?~<ɳz(+O?˓?O^\s//zp.Jwo\Ys}wwo⯇]yiꝍwwq_F/ny?x'pp{mo._Ə?o˿X7{_9j>~Cg_FӨ}˓zy}8?į\뷌1|ǣUя{ܽ^z>—8@i&O/zws7/noj?ǝ^ݿpf]z>~~ng,Yi-yǦo?<η7:nǝ~{w/nܝ_ϔnnn~]?ǑX\wRf\oXw|wC_١{uO̓׷ctUIߟ_苯i_M9H<ûjh?L৫wwœW7^Տ̞׏Mxu3vLOpzQ}3%Y hw{q&O??y/!d苿Q}gH.oz~wz2߾zy_0)߿d 5Oyzz6vO~5xþa7W7/x׏Ҋ>-gYu66/gERw-$Ҳvj23(0~[Z)(e r Zy!K^-Z1Wc/عcԪ/y5h9Y1971CWĸxZbx/5L3&9b(ec5by>1oŜO"s~&w{2birb2nkBY06&} \cEh#7U]J}g^ qO .^R2ֵMܧ0Fb+: s;W{y+sֱ.!7k?0~ȴxzS<10ikeK .ňJ?K Ƙ0 i%:(-k5ϊUnj~^K̓TE$nѷ4uce)*cd{|Z,f2t)&y,L\ORr*`̘ Q!. S&c6X"w̼0ޭJ +fmż1!}NzR[ӝDžYmCHS b/šHLq@^,ڗ|i iqnx0XU,MNW w'FƝ!A{ǚ r`mib\Rm/Ϙ1恴̪@ƒZFHalCr̪W1z[v2'= u[ 9_:Q JHo:X{ȻXԔS9.Yycg61m O)N`*f JLxt67$_Ml(/c7UuQLG5" k@l! ޖfwȸ hTb$G I5C&@lz-YX¢:r&9 `g 3U,f6s쎴gی>ĚbYS$0F;ns(&b}]-gtl\atkvGLɚA@j6l!cƳ7:I-+V$%3cTHxӘON-ԫP@CE`LPClDŽ68)3A D8!3i:s-MM@VC(D¦j#۲nALb|B  v'Ձr6D L *XML7 !f25Գ16MM0fzQ'/ǀ1elq5R7:<+T ~ Wu"<1ĠWU0^TC`̝C6musܴ0#BeC`is<5DGѨ;$WCȁTܡvk8?d 2'CټKA̖1 v݌IfmFM 8;z'M;5GB"fqN4,n()I!M%D~^#fZE D ="pՎY"ЧtU6dl =Q D!PaD!P܋2p`[~SF1Eh ]5UUCeBUcEE$eԝ@©j$ʼcȐ('ab6a\oPGLfh1I &#D@U ؆j*NK5UĠ L(ܰP0I^ ۘ0ocj*|;uѓX(Iԯ F^L,.YTUYaqo aeQ61|d YjѫQk̦@͎IvB|@TЫn?U"+b` M˘qj_FJ2=RlO ~t㹺4Q"!96u}pa02(s%LE |`<7 *f**QG9S4P"׌K%SПPI':l0AVszB`UW.*܁ sDD9]`S\Mԇ[( Q44KM`X!1%1" w+hܿ cj@?UQ (' 8yBY8 F /؜{;Bt1TU|;.~|llݍ7-m?T<"8NF4MIuKl =ƹ4]M} waS~Dv$:C/ r@.J<,IQdQmd"}pDweE Ch_ƍR/2b@vU%,bkeؔ O?+8cg P$TJ\6FNxQ~w" Q ux0L,dX6 '~ n,_77p>C΢K{c, 1y.o|LS147C ; +0g:§1F7Il?:/~=Uah(w8&/U8PLSW [gg٧ A*7OKxzvؠ5+Mw/oz؋WW鎟O|a䫞0+g=q)})C ~ZS Y w`L5@|!رϡN&Mϖed-W-hЛrѷEw5R6x@C`>";9f6q9]zTio| *Ɏ^[^W^W3-D,H 7Y 㥥}E(܄3pY'aڦy5YORWh$WVEAMCSL6ѧ܎ا`#MU!pAf &7y`-\>.U5H]HaW\+Uw՗.MK [Gor(7ӆ߁ CglRAm2B3n}lqʽJ/|*7pRتQa>?؈3Lnh=etN*H=n41P_<d=+W%A -o74̀C<c` %0 4 exf =MsKgWv>u_dnq$Sï6iFI45 @ O~IBc~-Ļܩl*񛵖9iJGE#"JmӑEKv=&\yǓ6I MI}Ss5"7\^%+n}.RЕҩ؟l%vǓq|Kɷp>'oQGdCD_2S#]JWK9d{|Ͳt Mzs%iIߢ3C\JcwiC6qf mzjNbÏ \|"r՞jDwbx5y5K=#yi}zx;9eBh lXEG>_ 0W&yFXl)ʖR9? {d$ Ah fH|30cK2>jJtf1l8B2-2A=I26Jlu 6HoPlBmlC/"wcPM վ5'ҫ餀H|1 @G. #$` M]oɞ'I1`5 8`7G՚08i#Q :^ɴF&YDd Ɨ6Byaxx#UA7  J]T*j2ew \=1;h4)||Py)ˑ;AՌ* o 󵟸}ND rtB+Є}l^aҞ(Rueۙmo"ҋ\X|Pm#^T2yZc:h,P1@~mlobDԳ˃%o#Ʊ΃b_Ed{t2}: ! l9myz՛Q%@8=~tI?dQ4Wkr+ɫL*6|0ܠ"YU}^ l*׿Af`L&FbI05J='b|*9klʗ̏jgxAd4"Odz42)TUuV-eK5UzG! ZN\d3ˢ'·(Jf%7r +ْ>,p[Tsf='qHB}{&:#zɇ~dE'E\2Znt; ixK3V?Í<ў U%aHwPF-w9p7H&RGIAڐ;뫘Hy1FO $6 ;]$.sYϋezkn_[,>;䩟]lmZ%oaOe*)Ib ߽ԘM?լ)[ϥۊW>fɻT/[>(T*?.D )Lv*,_>pҷ6b"&γC< ZY6`arayJA$K_V"i[`36kLG,SE>*cUEF\ WL{~ uoH{2@Z_<Ȭ(D@rdG9({]r?9$E\41˒11< 6ˌ! "b8x2J׸HRy;-@ޅa@>ҟ+/8}PJ/fƨ1{3*5Y1v蛒I7n D%rQf̙@־;58@kbRE~kƎ{w1{'mbhZm{= NTxr򧸥q7>࿥]/2bGgn$@UJXJm& Q̟Md`n` { 4Y&q wс̷Y%l} pm="뻦Eϲo'Lw6o1cyA88%#\97wSz<U}hᄂЛ v"}t3aHEhe7|:wxdm/.͵ZC=HK"Y|6Qa6f9~8=9؉iȝ=rN>Hn l~8xO&"U&L㬖1qt3ͦ9oY֛A3>(9efœMc^fMO1jI5(gqg^Y @Yez|)>fkL>(\A=c-^Q²`eaG 7oVRCqL0 ˵?㉜dN"7Α8=cj>݊\E=w/}eϞ`Oe}b}dds*kg@[&[[uf\YR5UY$?p|2{l&QfmFnpf5lod;W3RTO35lo~ kǓrv%̲Ql~H^ɳʨS _sLY[,k哔G.eRĶ>w]O֟kF2p}mV6_4 ym' d!9`j8Lls;+bZlkG6zDqȌÈԘcQf|cj: AqX=!LuJfBe Z&wXm%qq-JVr1lJFجMF'ܜUSo.q&nF.(o&wT[1\{8lӏ6Z׆S &Q<8se\ƥ(l0b-qc4ALf6bB 8nN2u%xGG5í0@9 gyY \<c)C%(|~k('Ŵs:k+DȔ 14׌X$P{9ky3,?:Rc _Ix{ %xxq]Y7飧V7XFW:FIq w1ѳ LnSO9KOҸС?yU ψ@zteOҽOg;͟xx7v?Efpc]pe֪& gl1xFtwН[1>縒a}9GDcb8=499*Lz$r1VA_f8'Wm ,BhWh /T7?ffz:}vGS6 J_ OXzzahVYdie|nK,wN XwPP$< oܩ<9bWGWxj[z_I >f:DjREN[wsTCTF`U-z`\RS!k)qPxy4`1}k~+qW㧬ބ^6FxG'100644 Makefile.in>qF)pZ\'Ztzoa^12$x=kw6_eTン\7VZږk9m:s>e:ob'g!ºpMϓ p4d8Jӳh0&Ӥh:Iygނb,`dz 8J]x;ay C2IEggq>ټ+MӍy4).ݦY4xtgS3=>o.t2żFk @-4IuW\WF-~~\o 4e3OL} ]k6C8MNf̋tk3`Q=F6,A{;]b%@]` 8f-6ۄ#́yH0sU3]m-Ң4ud4=OlNɤtu̅ABk Q_::|]\\GU^NT{7(jm]\Cúaz!Mo ]vGE6>ǜ;+HM5^M"vC}b0\2f܋j,PKx'!tQIN tr$-hW/5]Ƞ'`_r ;g$9Ex17I|KkƒeP<6l9pI*QLdvDz^fW] v^nYsaƗ=rE\uRAb>xufXk )'U sYCkw|<8ߵqsw*Z:6Zn}T{S I6ƶȆY2iw*~r\B`wXx.c'>+3G++.y$gYV/;@o`G$Q'_DMy|Ź+h4&I* H#{܂񇐓w 4ۚꪈצ |{5~j-Nb#bٖwjg3K29NzeFPCힼ?p;:-p ><ܒxt!IN"&QGm'(mх=it%).$93pA MVؚFOSu\E ^  a<9Yl$)oQ> 뱀cA2f`RCru)(N <'#Z´YBN};x 9M ܊U9Y6(>ہLTu0?tȕV0u$̓K>`+sv-ֈxZ&Cl ?sW26У"?IK-3</!/kbF!`$l$ {}!c*E^6B1V_Ti oI.c-xsS`!V2&=;WrgNOfB!}&D B>#|bNUN܇(]MyL8+4xaW8nS4BM|g9THxs^fK2*1hlˉޕ+p..3Z GQ/͓"rZ*2aUW'٩N*hZD|k9̮qWG ic੥m|K{|{?C3XZ@qW1o $*Z(}_h\lgkKE9$f_l bxG֖rA]O+w?@xnѳaq C[z@3o]"—+ ؠ +^Uv8Ƕh*8tuոNy043}^jluڐ[ީ0 J2eK MVQ95#jFaP&4I7!#Xow{ÓOJ:1gqtFZ$ZG[Whҙ),M;KSIO8 vHLtFASWƅVtWkGU%'MЮA}U~ɠS;/䗖C[n|xU,N(N$e"A.t49tR28 \U2}-Le9`C+r^,myc4 a@k:]|^pA18:/<[.OqtHFJzޕ IjیIWU~8cĿrƯj0%]0eZ2Ȉ Bj8'"#,ge&,8O8܅f*g&v/ e$Enxf-tUU,]9]*}9H 1ƟugIvUݒa_g(R7E@*yU, p= _V%i<(/U2mNNƩ%nQV@L $㴈 4KO :AŝPJͪSyDR{O8#`ohfpvdY b*b`N*ML/NV%.r(3;OD9iХ T IOyRd!u)AFO 2CSJ E*eq?J%)Lj<^ ,Π0S>EKkw\:Z&}wbS)'g9d3b)cLVL 3dˍ- Mm=ٕt';r;GN+pL&1EN “z:qE}"LwX5(,DL/(H#ޜ/2|W{:[Ob׊@&eu983NlO(Cj$_̲N$DSi0<B(9RǾd9L⻖u(Yf'3T@;hv,',3bdyH>,xCًKkV71@hC,Y2۶b0Ѧݖp3x^fEAi(iau:5lDe8mA3Iy~[At/HPVr]GEDj`c;92w:+~:2n GhPh+{1k_ oeMkIuPMUt9{]-ɅZl.&Hש=*>~ʔ$QE> b#Sub(e;QV0!k5ꍖ)/ |.0ixNyG BOIycS_;3ɧ 6N 4mhBբ!r/I!@k^[>W'[R! k[Q c:cl&%~)fY~+! >?(K&z^ cyeboE\饐)A2 &S)c9`AxG^%E66(]A6AUW&yl {ˑ &x?KN4l+ me4HH Uc[5_ ɼ#*s*3iV#i37~tTi MAS trPãVngk ]]SmEn􆛅`ȱoW۩qXg>E1HK7gNC]TBl {!sKQn"gVS ĽD+`Z4C2F7U4IՒdKVa\δY.|GPҍX/ɐPw܄фu,Zw*i!ұ 3zH>R}1/;S(]/F+Ѥyy*JOXЬv"3 2t \nScs"Gi=WQf盧*V_`DRƱxgR+^q̉V^,  ZPsҟÁC͑@s5^)]|_ҳws E'+чD=u6Ii5RƒK*ŕ?0J_KS]{){nh䀙}Ȉcr%WPY!*W%0D^zo_L#KȥE?WV];nA̟d 2bwr>s >x褓s򼍼DU+9U5mF&l]Zv`w>iƌuooqs?C? -ϣ,tWKNDڀ/ 9I<-09vEm'ڣQӣW{4IXP0SnPoƧ篤.K_^"']YYp gn䀦珩,Gٍ;8'6X(-n'[Ǜ̇7: Kġp_YH?9;tȐVV)Kzs^Ʌ Lrnbr3Ò*Hb!hV7"\.1hH#ykrX6`|rƳ x"e[S+Dē»DcJ~7Rp;QkjFLd[}@|tkеϝoSqbxفq'duK};%xΫ|l@߂!quhWԢh]vu\#~ ;ʟ$kbt眵N/NS+e#Y~N"A2cȁȎR;e"#*;r3rN4ͭrRnM\^jJ^%-]ϗ4QZz49ݖ4e32eC5# pcti8J(W@M6sԘB5z8&kyC2uprCq ܒ!BJW˞5u*;rZyam\Vn4ESEXdEDMM>vԘ:|ʹCřִw76*|)m`4+[6 {aبmYAtHah* |6P6T@] U HR+--"%xA>[D*`ks-S3XH94$L]f*p\m[d[TZkmUŧՋGz\4o*;LIm(ԝ ] x˵0"dbdE2DNL"gO͖uoo_f5 ^g&gQF#<ITC + D5$qH#;Pü3oėzFKƷ _amQٖn- \-U`tVK`i;?2D]#v*\hؚ=Ow]\o7ncX<&6!7/{kX_~B{ ךG =tZ}&jhnU%XƂXfuORlut\ r2O^/=DZ߸?j}2gX'dl 'tow;yi%lE;aݥv]h#OՍyJYW8"VUڡ + WscXgfSw,/ŕEG7 \_m]\m{]uB=TX>%%==FStU2 +֊s[/_9>'B~ g{cQˋ&;z˵b#!&w@2C$4liV0~Spݰ' ;.Jx.+d CSACpf@ C7-+XC:8j T)!055wԀL/'m|鹎pMY A%_`*᳅WN}VbjkQZM[*#TAz;CTmU\ ͹2˴%7 L17,>R6R2%^3ľv2ʆfK]E,iүzRIxv7\zN5t}ޞSep"Y&Y'95#@mku_"J¶G$&.k9Ƿ((֣0-am0P:QwwƬ8KMH'&0zk wvWb ~t2C|J2;TԚ[zx.;Hx&V?@ӲUZ%R`|̨oOPtc^ ƙ[5jQ,E2(/HvH}b$jRhPD!B0vhuqԧrMȶjui@vEtkT{/RA=.Mjt7\ņZLt-)Q'{zQ 't5lcU-hrS5[٤ѽ&n^ XFŇ]ʏ#ymr9f(XڮW@'~0<wf,?pi"q% #T^v%d[;ҥ4΄x_BS?"ډ'm͑H H"ȓމ g8/7#9Wy< !l{n`)H$gRڔC("e9NESRq 9?|;ߵ7ٔsR 1ĕ")XT.mDxσ~#4'ޫj&ޚڔ$)a6M/yCZcYX"u]XOl %"a{&S"rw.R\qu7B B:=PQ%4O[΅[S棶lr5[sk!?z{~l3;Kk^ EE/V+kMݵPgYqGyul(kעM+龬rr 2D(^c{HmL02lܦx8qDʼnkܦ)xX8AoMJkhܦAx0Ao&%PIiܦVx¸qBĉܱDxqB#˝ mF~OYiܱqxxqBĉ)IRܲxxqBĉ">n6}ug_g4A9ܲ7xxqBu^^A>ɚK+v)]⁡BQ)H a_ݙf9=jM(ܯ$x:PD$lmFkN0XzIM{]ёKd +4$P,_wN@.Qk*q3ZV}>a ] ʟAs100755 rules8<^[e`040000 scriptsEKG@@V)$100644 templatesuCzV@5 bn100Y`cܱ"xv:C[NpT>NS:NnWX/x- &100644 control.inuMy 8iЮtޱBEKG@@V)$1F5Yxt~kH棤ip R_Bޥm;vÓ5d0@6:G f)sQ100755 rules4JfTVY"feWR3m"F>hј!@V!<xcG&v.Q]2tfV"FCOxk:SbEԃZ UNKd +4$P,_wNz9M a= B&6kg@A@0xV! -ܬ4x[ŴiteRm+rYH{/8gzC ܬaxP~=`Ihܭx[Ŵit+O ,_i_u%3{ ܭ=x[Ŵit ~x'=(스M򍉫ܭjxe P3EAd,ua1ܮx7vZk,/:4 Ž3 K:[\,Q0b ެYѓ  x!ܮax[4aMjFOboEІ/~FR&@P\pcɔ( QӮϜ\_w_d.Fg׵ xSVPLQJɱL/LI(QHI-30%\e Eũ%  E\0S8A,`J-xVmoH b-brګzCZI߾BK$ fg^w{(z.N)fQa !fƼY9Mwxy84f; bPYsޢR'̤(`"C",גo3#)9r_g0?e`:xϼ_烑;;oQ 'JՑl ud . _rA3qzX*ʧԿpN7 9Mg9 2ȋӑ"OZkd!l,#KCI{#0xe$yJ׌xՅSqs̈X%~AGѧ8 h&BVwpg&`DiTA K!!\0>::[9%3#i*8\KB*yʗ6V~[X$jbPFBDb; . :GSցs*aPDoɥQ e&3[JTL#Q`ށ%Q186z*l6kf;F&eVJ;ū개#1˸Lg]KU%HsΞ7&ݏҪJṭ\hbFcexkvU%WsYY&#MTFRp>Oڷ#6_Wt_V)([2N:el-&<֬ݟ,Ws2j:[,e"Xg|53kРzde &&mP0_jG7:Oϥ~D`ƶKonIzhv磙yIL.guTQL29ij `?}tֶ?&PVMguc_\ӳo_ΧϯggNzX[[E;m? X(ns>8bqFy^sFzَ{ ^Yte",N{}bZX7zǑ9I/&cKy(K+i)Lzt!xe`|VЦ"H@6M:&l}Zs,@mֆ҄I@v-G _A G>Yٜ))7'YK:q3l S^ sciYYk}"XLF&$X-z]%rxqr\pӐ4XMWww*hOTo 3D~A<3I;4[(oB9WoC򓵍Ӗn-DtFO_ܐ70$'?#(W_Q0 yѳ6$ǺgK lf梧fۘAꞓt6W}>2rԥM 7N `]~לTPCV';dϟ-NP:Rp}PE0S4^ڥ8#JQKm)]~QuK`cIuSO*xpQJOsvi|{ӣ@N-"hVMםJ?I7.JO Ҽoݱ(bkF;Hѫe yDU2hsिTVx6MZ6}8tŶouZ͈vhSEݔnj\>R `57M(CY%yJϗwfQt8CC9Jyt8':}[/>%SL| ơ}p|F@昱'h:[';ivjE?tdcFE _~n*kG(nd q,".'AӖy=^N3 UՏE|Ri* :!.S ,30|\[Qʺ̿GΈyec t屪8LE(y*s}- jd7"3\Hэ@E9қ!1'06b$RZT(c/=ϟ/`>4Yu/皫E_Nj6ZM.W^X]]yb~ѣ<ÿ"Y)MMۦ󛅷i_/+1OtYp3_|6㉎>u1-&QNnb&ON, ovdv3 &> {rkִlۿ9aէ&ƿuk)u}}e? `o/?,fZ.ZYG#ip=NG[r*3k9\fr93S<@ bS<lpm[P :UVs*fԿz}O^/=z_\Ϯ`k5oG3\\3Lo>%'9LTSa&?[!Vy=/?Cl wQ060.ѫ706¼7nPdGt5#&ET6:W~-E7%#fso{(?Vd2`X>8u\[rrm'mMWG5%6b-@`[lj t' |brXډ>Cr ݟ<>~F%O1y&~LNt2?ƫ9AbpϞuqfWNjn[` -߿KcUX1Tv\'m;3o5-KikpO\Uka W໌krW߳O 8M&HM˘:˘'^#B2ހXxa Vf\!|G@j8˸>˸V8' iS7 pk!pӹ; +9Lmn7bX`9쏛`5vf!8`7 p7 #I4tb8yQv,MODّƛ=6hND=pq"nPW_y'|7 0dQ?~p"Od(ʎQ OQvk^Ր/tDi6KN_ickߩ<_UI˸v6p ag - , $;BN# ˻ydf@iz4a=n&!;p^%Bp9$rNmIuY_xܤ_/bz^EA{K=K٣m[&i)8 !O䛮uylj3%uu鞱q"h]Ѡږj#dW7u_A͸(Ggv. Ɩv6'V90^ gj+$a@˾aNqy:$6 ˻FwJ ]N;2YHGnӪHs[.a0GoyfVzVG f$]Ce*}0HW5 p(m&{7t Qw}W:2 +6܇zlVatNFah z Ӈפ'7kd (tFCYg"g0߿8L QwmCiV搷k y7U mSot M7Y)[hKQ#ġJ,8Zڣ tf_Y)D(- [c&p*͇<_xhԘ{ׁFR%WH&:JGH]p]e6eРϊI/m6jCvmŮrư0:>(*o9_-xRFُybKPO)Џ!"=@M'0wOJ澉r?&Tn .76Tݠch\i!M^B$&*zChYƼ(}b\=U4N؆Q̓OTm^,!'M0Ce(xGfDʐin2Ѻ.#ɖ0Pd.M P7!B HG.zMvx"1ttFVzQW }ZƁ*SSSܫ38+ڽdن ~oC脍f3c%c듰ܨXc.YaVu3 ܂N֏#ME17a Sgm9q/JB:$: ׊#qD nű%1p[dՆ=BEWYeԏv4DTl2q|\Q2m[D@Oi ,"  N*&  je}7b#Y}&Y!^!A{Rǁy6C:="!][_^ZZRֵ>B6 W7kX'x:<`LSv ,C\ Jٞ.-ڎd*C TVU}Znƪ6&o0cTDWY3^FD:-P6BOD/,^e V\brHoI@t *mH2]v®, +S6{U޷:\w#u }xG_hR J] E j50WMޘ3Hb{1P$8aC @cQ5TkAvuvP:jdp]lWcz+6 <O`1 ;T45_>;Ta3Z gZ@CFG@VTAMLsٚ#^P-_= v3S!'NhK4MKMB5n46^mNY#2qiЁ˶],"+D.1u)e|&1j.a 4PZ?r5.yIc}?[yr &M :jS^aaU-[n$$Mv@R;ظz-d䝐P͋Ҫ-[F58tPOgJ}Vѩ )Wx{#IRƑ3*`MQgt!HdϔKg6 ѫ[Zs~nWIg:~ϧ>e3@XkZrF(+%`vfJh_}gCͷ~5M׽jdQv^{I|3Ӻb+DOiCSs?s{)fiUֽO t;P3y{T2'+$eof{*apQC?R|wҍO6!uW')u# v>+솵P {0*(Oxb 4F;{i.:tV !f|,}ykdmk~ac%cVy7vOH=NZkZnHܭq;*ugvqGetFة6+u$KugLqCccFjvR:aE*RֈSqlZ6Y7xgO"Q%=%>Vcώ{I*՚o%PE3.@E 5kkqɑTO3K =x|s̒nf:8mIN2b^5}=eۤF:lߝaʵ^+]Pyeȑruee -;=}*i-G-}<@a_* lXZF>`R{x,; QDsܟKw.3gXnw*W;#0KˀgzP6P1Dlru=߽+~w߾gnU><ٗZR!lg$.eݔ}Tay6g RH\ s.aL Lܳ7e"H_?JrFzI~zoJ=M>5A%O@uTK)$7u0Ϻ ?QˍGҦz<4z{\Y^/O?@^*)GMIbo{>XW oDYM'770|ϓj1=Z厫}"H,0$e]^6@o ;])yɯ5_yN)tj;?.1̱;f6Aֻ'J.ܝly&*NX&$yBP h͐ yVr yc$95j7Rߠ! OqǑ[X KSdiT KJ|h%(Va*Z,y՝lȺha~_JXGaÜ,ٝCۖl4=l" CnisxݦzQP' N-c=I>粟ĺ`?Õ֭ըbQlN$}tkq޳` 6Q&׷A\m-mzXqgصʌɍ1ᱮ%B؝ vVzxB99 Uͮ*8\An=l: :\RV9 F.\zuDH'M@W(A'e4HmC'jÅZgXIP\QȐ39h` P"g:l>f1ڣTnG5m :B2AI+o^i|d?6 =yfBaIig!.yWc} . 7^4ay>(!D Iࠥr(HXKȃ,D<5YXݣրKmRTMt2!݁ 6<~(;{Y ~O-H鎣\U͹qy{+Mr\}tP\ zih@v)U"zd Ρome`:#UAv]U2t *Au=cͬ8J T(TpqoFP%kleڻA}WeBSlb^N&3(.\3[r)y]{2Ua7^ܧZ3s .#vkJi,2;lJK4=-ϝJ'Y-6UÔ;Є5ِ6HMИ899@ǢyŦ%03;eV0nsQF9EGrl#l2&o$ Y*bUc飀Xޅ~ޘJ6ܯq{oGzuK\YP6n?Jw9m0,ٔ]j:#c OrlU_)qJ3ԏcmvYv;cbc渵`L d[hC__yVWP#cUd9*Nv;|=o"U-J2]^vKJ ӆ-8G2D,Y]׍̩.6;6.b]b}@oBfDz_+,&0@ec뫑֨Zөw=3>-k۱Ѹ gՖrirȧ1\zٖ,n$u9mptg$J~uUؠeg6Ȕ;64r6쯊u@`/AS n-VXIr9 ,LT~CܦdnDKWC{Zn:h52Y[Rz\QiekG0<9I@{ό_'[adĪVa=o۝;[sP걫L^ou6Qع6틻|l&~}ܸޱ=S2j? ?Xw[k2k1?&xG!h˹FQIc@$:0ςm;@nzrP/ʾ)6nmB;Gf7K#qI%I*Q v4R1rcUtVgM%*;P:Ci} ƺOsbUR(ZݥOC ;$cMڔjJvM5NX*/z:8\ݻލ)s\)iX;FkeQF(Ӹߦ7|3šD>su3P,M'MXBlk3:H ?+!=LTZAC+ag1^v@PO&1Iz #uAhĽ&<1ݳ35$&N-Qħ,lYhATnԭ^ wִYoup{ZЉ=#]u,iB6-զu]\N -3,(KMjM? !ߎFL<گh(]'rץMlگFFc7D /c7eqx{=!5H0Fuj8eejabberd-2.1.11/.git/objects/pack/pack-3597b394a439b3587c942076c18d8b958eb0f5ef.idx0000664000000000000000000050634412240230175022343 0ustar tOc-E]v'@Sm*<Tk #AQl/Le})BVx0Lay4Gdw$9\z   7 I b v   2 F ] m   + C W p  - C \ r  $ 9 \ w 5Lfx)>Mh/F_r"8Rp  .FWm+>Ygt 4Kf %;Ncr#9Tey +6Y_M?,c *8.D<qt#VwT?o҄F L'M0EW!ϭ)GDSe/iN &-nDaa;95]d혺A߃ ?Pv惬"#F2dt?ϑZ̈HBdQFO@V$J#$a0RTW-r5ms0XUp̐C)ܲEz?{sI)n6~7ֈoV<'@TH§bۛoe^HJ N5J29M>S&rvA {4EV0>8np|KP8׳B0"yRAФP;ޢKy*Fô :JfK|UФB`@*0MݧnyEj"qS3rFjE wJ7.td=rzҖy*l;g[JF$]H'ss&(oH+?A+?2!#-M*\]tv'@/^`c+ Iϕ{]ҿo1#KHeiӱ,,#pSƣ:"D.1f Ww˴!Vo B2[',P^f6rNJFhcMdK#7U:IK:b?W b4V[t:[O>0U ףP:=D%]nb!82HU%X޹TaGbՎ!Sh|'ZL3O2hb1&'<0Ywwjwh RΣ`ZT%[ #knf6=/>,dD)b6cA;$beP 4傑*EQ-`@"u=ZE6Exˇ&&Aܗ,;# ˟anDte7.)X] @I]M4?.$2~e9I܎5ac -,!8Lw /O S*Ox@j=ը]. m*,xW+^pYiS[8<6x73G4p ёa6ak-S3 %H5)n$Xk*9^q'F 1pf d 9AԎۇ) 5p[VJkƛs᮫|; ; ar6{e>3L`>G; +MqZQp\e=:W\ [oڨ|*vt*@fxzܻ=I.׮X,LU|zZS&8vvf6x QcS%68LzRx}T!͢VBIGo1JiZO:*\gXT^LEfL dԭ3m"'+\invWN.E9r _'oI "ͽUye>0_ƟBTy5ƺWɏ]&)xn/|IoWøۼ^ԎBW|b@#3@ؖ#`m[0Q\pv^<=5h@Uz D4 l~ $Pr9 dUodB&*[\"?}f\Rc%u0Z{> Jz0- pN'CZ]s ]ŁTFai),@K&Y>QK,S(Q*u4P-omn]RqXD~cm?LiU oz&)(H vK-͞6ܛ!6$55<-|Z$!*a3޴s2ҥΆUH 7a"@b,.$C̆ D-@QaDA kN8aQ K\:rju01Wy2>U*U{ \/ є,:~cwP(V>5C\g4Qf~_!cWu8nAU|g64: gPj|qP!pyOFa.(X!u0se) _% ,35^3,ȱ@xl*F zV=bW%nčvqѲ[zxUB.Gd:6 &o!''}KQg$ĪUHB$Fgkrリ|Da*‰%KFB4ȝ$/І&wӅ9EG6߁2VIjNR8FJc)ߎs ٴMr-t9 (u%|ޫYX"a 4~Z}/ K”IbM RhZ = 2h0|b$0u x M;P|ѥo4Y'|$ `E[4J e*.=kmyZ|M t]PK5$fg9"ς |4<$5 -_r_޿ !Q/+Më[A( 8Q!km!j 0 y!1zd| NY$ >W9ħvI'x6 hֹyV;d LediF cDgͶ,\d @;Κ@=.Yh A3i.Jp't^è\ A8)]v+&ׇ2n W}H6 i 8b> ^>G##gql> dMA-e`><~am j FLRHίO u R9"Er |}pI ˜L-Mp < d'u{^t!k 9 ȣ:e- G/k E-S jwj{ 2 .Y4nHeOq (urb8<% "" 3)yhv Ky:ηZA rd݀LwTfG 3(u3),kk %ϚC)b3?! 7iktg:J@- )U\0- nK_ 5^lJ r H8!gKXx Kj:{#-:QrǮ N]q؇`FD־dhP T2'gWr UUU?٘Xr XTU*@EƲ g- z:x[{ k/ip~  ;DGZyK P~ŶYp7T L߯:=BE30q `\͕[]&7 )ƒ.S/ ƥ(p.4c/Cr ԛYvVBwwl 5:SzbHh |! ,K Z (~ ͜XoE' Č7Hx IDPY; y72 *O( B&6kg@A@0x Oޫ,' ". )&h pŨKE 0t^2:csxHNQe A &]T&ԎG=a Z!40>B< [*Z#TpvqX t>n(F &&wamnE7 ߅pľ7 O{Ts~ U^;4{)bT n>~qB YF!8qbΪ Sz!hy9^ },[xA_6Ԓm :#'zVVzZ )LycMlP =mDBai RPR1 ] LD2f ծHV xu15}p"Y 9;3N{iV J5z#\+@b~ AM9i$z$B 6;(Ofnc~d4Biu  l&(Ɩm*_}V(?"+r0Edz(1w僖'7v2&_ gG2QZݚAx'6@<ǻ(rQtD4]Ɗ;Gx{d__̍oJWȋǂT] U'R W@] NEOg# ^*G[j껅wa9'x޳0lxpEgHߗu CcBR9mO"ZfͫXu*:!'}+C5s{ThaKRnVpzbV1sSZ>[ X}sU/Vo@WA w2(; -K 9Μ!!+ߒv;-T~5gΗݺ+@b ~$zc+@@H+o9 T ̀LMPWA+k=1'aT6W}1vݍ&,k?*G^p?ʰBBX߶ԵdFdΛ%^=oS%^책J DDLy($-na̵uRq@ow NA9lˤ=qv.hvVe=ߧ2=St M͜Ee1 Ħg|Ls`V4" = x*tӘ =zb] )dwǿT3 c={eRi.UTv)$)1b~+[PDShnpuqdpW}-q08CxK8'Y-SZYYVƟb3E.o]`r,OG/`7]x]E](\s%.aK7ԕOINfP ¯n-<%!K䱣Gib֐bGVPY>f& s?"2KIKAf!h YES񄀴]e9V6[ߌ":ن/o3 W= VSoV.[@yG8&kZ@m}]zRE[3wTA*oNu+h#(/2uux1l8.C%/ =̡w nD#!ߪSfe˼(X hݺ^OXDO,;Z\gOԮh{ ⦐v+~evq :PD<aӚ)j.+_`~;.{?gz=jiʰEF 礥rN S],U% _ѣ6#vȓ'E^R%ltv9ſz)RN zfX3B6,y@O=J[xL5/y&9,Y19O)? +vcNE;)J{t&;]7vKF[}--)QIRp&uf@]! z:ƣ5ȱkeLHzY܏ t3z]:CXMq|B`܌MFːgf]( "56Rje|{D`X!'*B_H垩wS:ք^"-Ix/>bZ*"5ձ`6z#R GkgGZ>HE$[Q (!8:0MS4BEľ 1+L?ZGEP _yYVeauݭ/qGȲ1 ȥayg Ssc=OR%l/K˱80&=RS~>%cy[am'&~X|AVJrwzFI[/ea7\Ii s㒘P\bQ'QǧDnaa\seRɽ&i,ά?b0b'pSu.ڲP/Lvgt.?CRg ur >bDب*!^3sޱj{4ҋ'#q5KS9< 腔}h)i(Ӎ!0CD%(FeDЧӝZ")+nEk*jwT$뉉FMD ɞۏâOZu<ў0lwzvL՚t`+*'n`:0#">*_( Onr[@" q;d甭hto-P΍{0(E 7!s.τSF2oش5f d0Iz = _K߃jHfMD07'KVFGHds*4ٛ3{e?a$9߉N*ܧr{ўUFi>z,*X,'cԚ_Eʳٷn/LuT &d2 @6&bZ ^WWЧd5H2U/ZmU]mo Ζ `v}^ k J+,Ty`s ͧ= S%$ʁc2[#?!Av(Hcg>%K{=;N0~}>zJZ$qtbtZMNk'0>yQ%q6wHIՁìa,~ywZGO'#`aLs@2N^3&GadΝ y (gւ{XlA opm/?-;:*(y m0&=3 u%e*QhRI:ؿ^œh$}sb඼/}q }~;q@ao(fQ3O!TIK4턗v耱cB+[,ё7!<|h'^niLoMN2hY֎1}z&WŧƂr)a$7т1iԟ`Be)Օ_uɀVq E7B TrK*4afNaD7Ut,5)jrv^3`~jCvsؚ.H~lj{q?Rd}. Yܵ7пd0V#ihGB(4's+xQjE잢% *\k?򂴧uN6כ o}Echy x)M9&}}墤w覚$,C_BϋJc)q.FZ1t6RS^YߝƱpj^#8mZ GAT;\Rg#$.Y썱Mr' ]@c %f (1[l`NjTڮWo<\:ƃV)uWMŭ`<U !YY#4v氁o;#PR0܌6xPV)N,1 TbtHTO=2\ gF.jtäG w·FGۮD(pDܹ2=8 .j-&m|(.l&j\9G s:fm%5eb 3 {3}(=3ˋ59ˉ(1άƍ%8ۢ5>{F$fᲥEWIӳ_atsD%Ņ,|J:d_gdž 7@~``U]t]Ff~ۦ:Qs4RT~mvrMLW=F_ ~D2UT÷~Zr?x>- Sm~^XC3]tGb_^l T}`eY5C\# OAS}5&,h_Uo|䟣II= Y+ӆF[dItxpe٢t=p59.G[aSȱV־̢zT0& zufl/,+Iwe/x!iСu3ku6Xr; 6%:+E˜qR6V$*tM?KG7B$TeC+Me l+ԛSCF d:}5̀Ct(gC+"*1-Go,+~(v, 3MEBy3vnixBsX 7M*JwcPV  3V8uZD+ BM/" ;Q! ,ejq7pSF#W .,V r2^ 7%bܛ3R:J> єqÉ"'F|WeR}61"(ֆZDﺜ[U"Bgfv C<ÄQ^"C'0vP(C+"EnvP6 % TUY7"Jmpg/X½^`2"KRAn#Aֵ(X(J"[?$ilۀрx"]2lWGHўvu2"bCsVv !"tk lRs"uS{KLF:X!i"?s"^X۩r; R/I*RJ|!.`9#CpuR)s,Dr#l0Q7}X#Ϥ qJ Y< m#ĺ,6hlG[^$ G7Y.8 =,;i_$ N:/} Pz-@$^%P<͹?aj$ rm `1 YO12$3Pfٙ&YE5It$D?EDwJkUP$OS=~nwBNO$t  Dwq 6^$`ZW<+i3o$Z2 " k=z$e4jg "$Vz#+5ZW$ͣhJno4 |I$Cwޛ" ]N$kc2sι̍ZC$&DWSUF6KC% o+R+'4C;% sKٶ1R6%^] mUL]"%zy3m ۮ~:c%Ĉ(O%6{?o5"w%(#`%[B)%9ڙd:~"pDK%F:A I8mU8]:%GQ4ẖ]o%H2s{G%Ph?G* ˚i;%%T3`8HbpvI %eϋq`@%oߙ[hqv!mD%L>3~hx)v%CʧXh\o_%)4O9.b%R?x:W毄Ȭ%O5xRTƟng%3K΄j_%=}%d0Qwej=%#=Gq]]%o+wW%'Kt%lNsxwT>%L_3.f Ddj+%dq~CMsb&sQ#`yI&1"vW^ʴ& oBf-@;s&-}>sCXL/&C)F㴍w|,#m&Iz"XjDI[&XEYLS/@`?6&kP552P8%&sEtt!t< =?&bg*NI7%*qd&ޕ $Do&zn4M2v(i}&m35d7W&`ܥfyu9`-a9&JR.t<,&'ߺ(1%<shlp&'"繼dN$>&aٿ\>ķ N' ^e[ y?@'] UFPE"5u'60y}YocdJ93'7#@YF}!⸼'YVIjD'_Vj-jR aI'b-xyj,ѵ'mww hNN/'mwJVN[Ow'nӰ.ft-}( v0^i)jn0!(*my0oŗz::cN!(Uakuݑ(UxQTSK( O%QA.Ϗچ5(-$R$[ (4OsD(IDTՆBn.Xvn(c߫K L(6RxR._BfHF(rKL1I=c('Pޘ(bp57N(pQl?+LM:([,7v)<a( ͅ<(۰ ꩽ\7Z(c",yH? {0 ()iԷ;~=('V!sOd-$)mYMؕ$ޓKЖ)KݐDjTBa)1Dr-U(4?F):rym(xL7)>Hcso)DFQdZ8P )U5Ap:Ym2')dB"-KLcsY8)qai3#en1)x&߉d#)zDSxMq)?CM)Vg3AnI.)>^cq[uR)(~5FwTL) *͵Yb'M(a)'m%RݜFPmXT)&Wmn?V); iϳ)'lCU=DO7)'fM[u"Ƅ)n(BlJ7m8)>0>}T+)j h[1̖)STַ$ A)B2*h I?k)Ǐhgv!Sx)L \?XM*r@;K'*H CkϗBE~* 92atq r9*.-4I1:w*DIVp )b&D*Pnzvdv *V&]sqPAI|*d ´= H޶`*dt"(DUDO*l| @^{B{*nrUZTAr p*n.^3>z&UOE'*r?Ȥ:g^]X*x-˂HߟwWKk@{*| ^LwnEOK,+**|~Qf9sˇʲx*|⦞SYO5FL;:j*d&) A*L7z+3oh\5Kz#e++9_\O7uhH+qb\/+;aX𰮑 C"Ҧ+A%[8`kBݧC+KAP nTKc[} +PqIʜdIx-v+PNQN+^1U0n;9+n#z ~He?G|6D+u9fDds+x6,mDg52@-rZz+}ҹ. C/.b+ENa=bufG$x+7y n(~R3g+S!}_i8Bs+y9•tϮJ+4-ZW91T`+BB/% P|n@0T+Բ~vT`noܡ+qΛ7Kcr+йzh@(+Zަl<+ۧzȣD6anҖ+@09.n%:B+=Eٟc,- +ˌGRYA %q_y>+u~mq(A+eSR `8N +hkFߌ` +tۍ< jw/+d+}pa:]Y+bKxSr٦, =ڞ8n/9,fx|u˒1~R ,$Gl\,'˶!do6d ,'!+)(F4,8DCD1,D *xʸ"W;nJN#,N$5Z)l`Y V,Tjx28VwdM{o,XQBB*#bxU,^47P%[q.2GB,`^0H}#],f.fq1@N2,z+׃9DiG6,PaxFv$HU,Ғ6pz&LCA,gpT_c-9mLt,@Kl'|CmzKu,/Tͻs,^)r&V0"S$',_}.3,]]frG-r-zI au׉-M&Y1p-lc 불M.=-)*=U Tcd0-!if%(?&A["t-"N/lY2gg峕-$F >XBP*J-1 [*.5?sU'馧-2_og\t/yG-;l;7r%t| `-GX`H>88c[-yS[|%?RȨ*-0|Z!-gc,r}tF9b-\rc`7[[pc-aS?$Q(X-µ? soo</(U1-I9<}Ao`8-胔'#%ׂ-'6oH̠1q.G"ʣS4 3.&U!xE2.-g?s"_cT'.;lK78 1 .M%Knb3JƄ-.S: >h8>:d|y.f~ᯁ63ELTm.k1tBvh1A.m%Ԍ[9WbI.u Mƪ>|,m>H.}DWjTi5}J36.z.ՍXΡt)Ɔ7h.MGvX~. VxГ\y5D.I&&;-qM u.CVS.".\l9T/`I|2n/_%$EJ2/#t -N mM]Ќ/*I&$)~7WF[/0(Ftg8ѹ/RQ/1-u/_8Ot/O/cȧҟ3EnJ j//t{AE~s#/xh$G҆ŵWΧ/ (= 5 R/og4/YD?/h K?/)pkC;Bi/0.({+Ԭݧ/_i1~d1UC/[ᅟLۈ.QB/2`Ğ3|O_)/; Hr  ڼ /ؕS&@H+{Si./F0.chrQUNm/82u#0/ABlpC#:0ѥkkbEӍ0#жܫ-xS#G-VY0.4?ߺ?x&b0/jZ,]'G02QKy>(&008k=.s|WU0OZB!)k%h10Q2Їlf5: }o0RbLZfYYθ3 0X,X7(30_¶R`+QW+0bV&錾Or@00zй G̑̾0Ɯ&AJ] *0ˆxZ\ieG"0Ɣ5lA|qԼ0~=Uiը7_ ML0ےy4eA9]IJ+0h_4O1,@rlG0ĺc =VrJ[hlԶ0A5dw4հ;+1 _c%!$1iRԹ"M1 "1-@嬑1߭n4/14?5:0p1FEiDaB1[I0`K~:^i7O޹1\a~9C : 1] h(<8lju1rcźKlx1rBY1c |şwg1uĞ/f|[ '#,0hO2o/|y# G2< K:v c2PJ`zYTXZ2QO;,ʭv\M21 2OM2=RS~Li# q2]0 Cfb2k9f,s2FdtX<%-2#> OsI'' uA2dK PT[v22jjs2@IQ w`kk2ęFyO2ĹpcXqKz?2_޲暻@S%3ַ&xu{H/8m3V` /k|̣3(}rGi3+O!-bG3BO#uO' Y3E`e;p"'nh>[M83I9-@{T>)6G3R֝*Mr)h!q3e~TP/H9D3i?-#{+*%x3npb1x` UptF3xkJeH3{pu Wd' 3?nq%z3(9.F&aD4;3ԆX:+z3;o4!FB3Ûb&X⼓iI3+|jWϿ93V!: grBW3@Ϟ\"o {3M]#|Aұ+3)23kR/gݜl)3³G[P9B9!3Ks1Ò4*ȳ%#4`ț#*۞{q3 47Pw}.4'kCŻt~/TO48ɉkE^7{%<ܡ49lMxHxsYoxH4=CNm&Nr:N$4B(^Ǚ*\4M8>~(4Z*6${8'4b$0kjxmas4dy 5dS'_;34h\57vTy\}"!L4( V 8p:ꦛZ4 6P48@M'4a?q l3U=v4 b7%>='|5 &WxL 5\pWΊ&0>Q5d`+ҍze6(8s5CLMҢњ5!K钿Z%5JՎF8K~5MRx&zU" H5P&u(PÜ2c5VMi%pmӺB&}q'V5YqM9[5kcewG-^R5pHE)~K΀r#5_ٝdP>pHu5UIwtL5MBҘw5dCi5;D>r(D521b*m6׼][5Jua?-'yA;5hdMuXEd5Z(# - A]G5 BEljWo5sψ3<$~5Z8xJ&^\6+f3Ox Nam6f@lk6tK drx"w6d/[NZ* H6vD)Dz6;,}wLb6(1s@u,`#k6)M{K>FM7CSF61 :\ܔzM,+156;B!ʫ6>j#٥x)Az6gډkJ;voаWC6k2j:4Є$.YP}6qÌ_ssc96q\crcIșWrE{^U(6s_ɢ2( ݬ_8f"6vKE  Kϥ5F(s6}cb(&o=6V-VǫH6( gϑԨ6͒ʨ2 EءV@6aLįw3(i6cL>1IüL u=64kYc_A ua6DWJrnXT_96iNzEk+nY6Z-4 >%6k&g"LEjS,6arJQ |>L6d`Uj,R>O6͍h6Pw\F6 8K0< 76Eܬ,@۟jTl*j6~0Y:7'N.6BXqDdeʨ5#Z6q=6}Cgx$QwO7UNX?;LoJR7)p<jLPf7/Q vlѦ2EsbAk74.S0X+V78&|z&?l!;7M1O;d=7adgM_-;7bԤDSmP7t /Ly)-M7770x(}^V7)* #=WqT7.R˪܊fF|Y7y&?I m1Dga74{ 9 k/7a7AjPH,,v7*7bY2F7̞z~P;AQ7Y- .T&t ˆ<_s8Amm$$5휿dLR8Lq~9Vo`!d_?8P4B?8;Nfa+9ġ8gxbڲ9 )9΁i(069@--K9L-^(H(5z9ڼ7!4,E/9 L"3f7Zm9Y q99o$(r:p@9kU?O ݞǘ# :Yj?~Z:$&AH$]2 秇R:&bzD0e‘>:H8;W2+պׄiSG`:O"@2r?SQ A:OTϠeC)c:X"s:K-t<:o7x'[R; :u2չ*MI`/p ^:B`ԵOah:0!}#,p:.ײN'Ca8:#) e`-/3:L&Ck{pES4: [N. t M:o'qtt,o:]7zq2 #z :{gS!~V=:ܥ׽Kn#:놰i!^o*-E>:Ϩ{x{W JE@:J\P`_z] 2:ZŤ!&u]%;ԘZ'6c1;d1Sb!tM1; O fا'j4mH;%|W` 1?Xg;=Lm! H1;O1+WBp.ǀܖ;Zzv!:t"يF5;]ٛ~% D`mY*D8e;R1;$?4!;}zUnn$NR#;dYa ] dˡ;E0qnC+;qūQb VXQF;$nwFWd;3:dGAL}};,Œx=Fmh+;q\"B53jW;c2LCY""WȞ;{w'Ojݦu,<t9?f SO<r@O`{k`a&q<nQWAGjhs< p6e).i<)`-ߚW H"dE<AwnBN'O~<"|byzmQ=5q) W<$ [$‰mbElTcL)qؤX=e+~eӵ)[=wWvLj8=j6Ak[;EXZ#"=>6M#57=H:q#? YN#B< >0s F ү&_>qF)pZ\>H*d+3:ua,P>2w 4o9>5Z{@7P=g賢>5~ex5)6 <>hl6(Yp() W5a>rP;$um6>uN"#G=>$*4J֖Q1sJ>H핁xu6I!<>Q\{W`ֿ1"r(> {v:-*N]k>$Zm' /I&~>' aO|rJ9>ñZVn;[>`7:FDr1'>ՖL{[Ev/iP>۽o1T=|1i0:Tq>Y (R#6#>+]:܄ˢm>ϲ\*. J$">GkG{LM>>rxϚ!ȷTFOD?¡0\_)ٸ漊o?m Zz(.?o`k <֮[?"ogY;@F?1z@YL1+R?2J.Ko'Q]~j?L"Kyfzc\`Ўt?PC$:S q?T9dzo6D 904?V9iLWʰA ?YSDe i"\HH?[$_Î`S?cx묓pN%NUq;?dz?R곫qw4?e3u8V|f6%?gG[:f^u*p x]?in$Ix6SmZaxW"?kmyNmB?tΐO8\b,Oxkqˇ?{xT71N Z??M~K>b?76S[Hn?ɫ/XlMHdB?k/7OsH+URO?HRp.y8@B3?**QXWvy*?ʛ[ߺfsJ]?„(X3>Kܠq?*<--1!?:m|hj[ǡ0?J1I8|1$Ҙ2h?x(GUF--[.H?ڨGzTm#`qB/-?L}4?<'&?㰞 _$L4Qb?I˖MjDP#-? ̛}vC Sjӹr/?qAo=Sy ?t.ZKZ{BgZ?ƕIPc'* @YMޤ2L t,@ ~l0o=u'J龢KRo@{b}xeFE@$͂Eu/db fbPi@1JtUm,Į@6h7ЈNzPʼn@<*qa )+Э@?Z ql(!@Ci] ,@C#Sc(K@E LTu0d@KQ .Zg§@` tw[줸M@jU,:,VcH`e FYH@p#5)!OWI/фr@.Qk*q3ZV@{ojͣ`~ @f`mG|Z@XF9< +93z@m&4,)IT(sa߉@8cIxRoBNr@@y:DWL)@kL lz K%@`ZޙP q`<^@ˢ4ޚ+!x@թYM"%stMCw@1k$|,6@ݟdgbB $ $X@ӼN^%<3@˳8S_^{@b Rvr f6o@!g܋IJ8wfUAWΈHԦA9!=A& N5V ?}vxAP,$L;5mTLAޖAYaHRk@ Tt tüAkhP|k '%ԋAn#ZM#BAuCPh=']AAxZn߻c( F:Az|5DVD\ť %TvALij~݌NP`~UsAw}AQBD~1dxwrBYE1'ȝcǴuB &Ӟjl^աoBWNΫl1DyC&%T2hʤ[:yC' 1p=|C][.QeTCLwC_D {1N_CmNnyROm"LCMs,%0q'C;/\['CJ*AxxLL-Kc5CZl^ҌCZr?mJ".A\Yh C'Y6+$qiƪ%Cm@-lB筓D3rCQF}X/CHg\ C񴪵2ք𳠗qb0hC$[Y#rJ>\C=Q^J$pYYD qP)]Kv;DDb(pǗ((AG9DSrQA-;GD#߾5UGKVD90hF &b (SDXyexaa^DZB`q|F.ּAjD\]IoP.W*H1>D`#8fxNn}DfGg>s%[>Dl2WYb{IDy&aj]:bܘwۚDOkWkb@Uns%>/SD_fP$/lj\ܔDm QN>Tvs蓭Dۧ}ns,M DRܒwB\H( 6D!>1R0,D C%D;D$;J#M5SD_ $ޝf~sѷT DaOn,Po*}Ddnl7g1MDn|\TA xߴC)E0 tClpSr0EC?W !FǤ(*kBdEQj N/aqTETڦ]!2r8"H5SXEWN#aO&Ao1ONӆEZd9d lKNE^RV*,6ElZcNZaUEeg>r"p8ˏwSFEg{v` (w1E}{=ؑEڤs8R0cŻ{GE4 f2wVE^[~cI K|E^&|bLœyEuSpS#?F Mj~KEC\(o*^~M(zEL֐YLͼE9tǟMrEKG@@V)$E ɕ0S#0EXJ2Jq8E/kZpȰmF 3ScSAN][Flߧ:]%ߒF(R hs|ΘF+"DVdBdқ/MF.rEV#ꝍ tF9"BgZ8U06RɢFB| Z/_˔vGoB3FIǃCGގ@FPį=ƂYn5AFQ d _WU6cvFW{nP1PppDFYESуthXLF]SiMcFlC31YY1]FGcR\iFtApS@g`0F=u_$wpNzFťN%:׻ߵlFw{JyZmx-;~Fܶ@`/V0Fz-OkySF,mBb & F`"-'FoZ>U'vFl)y VPHG ry]%+A0W0GrOwj߁K3!ŲG"?a?{G,B`oŁ^5ܿPG1\)?67#"oG7ohZT Lz#r΃GN: 6Z%{IYGTE\ux0耱yzAG\bdJ* I6Gb3[2gGz +Z¦]4z{#G8Gjdr?3XTRGTVбP.G1%MxzehU6=AMߡGZDߵ$>ȷ|K6Gmօ=ߕܭ0|myGl +DWh|XGH !''ʿf"jGLvCն[D+H=3 !IpHeA7МH%"ZZQj ֲ/2H(~BknH)LZZH|*3 H1Za?GU f\V!H6BAǚ]LyHl@@8QAnmg2dHp$y@ۮe HxsC=u=TկHWc:}ā@ygEEH>\r^/Ѱ+mxHKQtlUUKUHiF#͇jnH wrעF( XHW{a]:ȣ2uHsLuYah< QWHe^au⯻wGK$IݵF]ښb*I!*]'V_^+q<#I$HΣ^9Ё0cmI<`K̀ IC?hN$k֮+rIF}-sW\l̅.nI[]W!@obRIfJ*{ rgXSEa-,Il5_N4=KƜuIm2Ӻ-,4w5Ix[uZܥlϷ{Y6C5QIdraY KM>˥I.zicZI⽯?|奄&lIv<ɶ\6ȖOIȵ%n"m=XAQIـ9 ĎהIG~ypT$N'I I`ӯHt)Jy›D}J/l2T,pVŻJ5AqiQkN'tuJ=ȾN.׎ 3Q&2JdRV8uB۟k>Jkyq$ytqJxZx.E9fJteJp.-ɣyOJ)pa%fu%SJ޵}38X̓JB.`\+Xs0GJt)(Kz-NJyVF4&!efJ]7D?W)yJC֌H),NUK*? g7k궸@`K8~"wKB|+/$8swK?n)M4u_cKG@p*{nSK[G ;L`!8K]bJY Wk'V[mKh$SS Eb2L$KiiPP Y62K|;P fCa?җj"`K$jlQ.j*uKk`2 NIE2KU/6Lsg%;K}3^ coK0bN+FOUVK|9Pg ȠxK~Z]Ԛ ~;jK\oo +°Ny2K3z|6CW4[׾wL ϱhcD5SrL ~# QNhѧKÞSL rsL *^Lٸ:OoNKOL,k^I.?d(L dǒ\LmͺX;VKBc6s@L:.+ʨRLY枋0VBPlL&x(,,^/HL/ZkBdy*VYL4q-)4z<[ňL:)w%Qj=n_=LI<- KeSPHWNLZI!2҇ha;&&nLɖ`>T bV+L6Tv.[LmQR3ckLFzd0)MJ@L*=MrIˁ;½N2lĀB ovN* _b]A%ݴiN*E-7Kf£ N:fN.ls1w nNzG׳ݧNv[wOxu:NyJ^Q"L6NpVd%wESxN/Juoq9SPN؅[Ouݹ6_NHjj5zNyꤟX*VNO&Eh2rS\|N|P|"f4޲NW|We]8C0-SOeFfDE ofאO "p2k2}Ozef|=y}yqnO&<4TD~:lOŋzI[]K&CE5ďeO>}wz #i7Oy#RuOʥ&di?QEXcO?8f\v9 qOӓC2' A7FouOr[FfO կs -WհOiGB O)U*gX}SK^Pj4a־"RqP]a]@c\l_dPn8fp,P57oYv9ot=؇[1P?7=!D5:)PSe4pW0^vP[ RILJcȊz}Pp=^%g7#S``P'4vA$0qP8eGu^6|5ϒPD$lmFkP 4jя.d`OPzNۊ4I\39Pê_8 |+'PϦrSr-"r.P+]\Iݔ'GP~=`IhQ6IoUR Qk.WwOQ!m#ܛV13;zJQ'4Og?PQ'-P”D#Q-̗Ű..p*lQ2te^)t*Q3!rN:"?f +O^qQ5Uu" ㏜EQ5؛Ϯ{5^QH4nx|#TjQL.S3 UQL0t$m y˯QO3o*NgQt$yѳo\子OQyelro뎝Q^ C)3Pez7Q6ꇊ-,kYQVU;]=f|Qq9nA1j^cQWQjCȀ*&z³3QƬ skJTM^p\Q-̄T_ UR7RZxq%CR&aQ/r-CzɧR%nOಊwe{R5Mzau3>khiRiP|* }ceRn2xN^> 6ئRp6 7SgMRvxA<|'EhxRybͼ'. Rɯ}~w>ǎYM$nnR_ #z\QlRP>ə܃r!Re˺HNRɣd:ERe`S[܈) J R` - M.KR%iwE5~Vʃ&R"CHpGrRъ YtBnQȞwRJrs}e76Cg=}kSHO6biT^"A 45SD rtUR8SS&)h 0kgtoSY2f+BoUS!y,-chgϻXkS,'ss)6<ȻfSB]kM[rzs\>[SJ D@$Wc+Vt-SKPق,7Z}f)S`ѫ>\oZL]kSlps2Cc}6lS>$k{pǪCS4zJ~Kh¾Sp1`Gcϛ6S&M8v] "ScDv[6?%Ӡ|S|Ty:P£SwgC:2GUES_LBA2{+SG}ٲE$vUiT_o,1ڜ%O$TFWm]ꐅ@RTC}/5 lTԡӴE;eNbTఛm؟FWT"Wze T#<0kZ'vgT"vϯa aT" !} 4t T4儺dt$ymWT6yNQ/3!5[)M}GTJ >>q8ˌTNØ(ʼn~uTR$`zN`vT\|L,3PvކT`QvoBmrz<.0sMATwQp°J٦DLTo&dTX*"jfzp TQ;v5y[PԽT8gj NT5k_3g|\ $T&#MKT˨A88(nTO&z0T6j^dhw%:[[wT$hӥ~XU Rr_&Zdw dT?U!.Q3(U#U8!`_Jz~oQ.[U*۷>8<6R|hAU+ro uk_⻰U7`D7<=*U@UZm?ٶJ{0X!xOuV6Uޏ4edN̚3UuMC$.*U}#W@plTV6ң pVl-9jt V iRL`)z V !4s<]Vw :fȺ*Vgӳc\֓C4ǪVj8sWP~gH@Uxz-2*WE .=IyW%ܢNSzzeW&-p\كo1tWDu. raWQGf is@sWaSŴ{ c#7kWw(ī WsRW}ڕ@2 8|EHY9WraE1&E{vW2ҕl5WaW<L MAʹWp%'g'3IKir+W]°jRr :MX"QmDPW۬p@v_X%pz'ؘ)"چEX4:M,ul+>װ#6bTXKj&4{8XZIxm_;3SeXpԔΎ QKp|"aXtI9<TaXyCIɶ̗["8)95fX}74M :^7X~3먽q?_.qXa<0ꕘKXR4C*Ę&z~tXF>S ̓ؤk5XΗEМm9Rw5X@Mos$9bZXD`=giAMPX>h]Ca߫X=1C oɧzY.vcu}߀[c{Y x|{g\qsa>ےYSF?U9<70 Yjnod}lq.EPYmaޓGucinPYt5w`۹?iuY<3b:t7MPYe {C{QJtYXNJ˱1YV(~.++FNFY݅۸d)F9mY{i2eezszYFB%d0[fY /l"_G'Yc8#) ޽y )Yk4M!yGjkY̎1E}:Yϩ)e*ЁhT8 9YڹpC17 Fߎ:Y2T?4[Y40x28) D7":RizQZwn}1:}ohZ*իwEȉIu=kZ>ݯ aZ$Ҟû]ۅئZy};jPxZsOLP?3PZ!1*pHlNZԤlNH,83HZ(ʅb i*~Z?āy?>Z/ys&C!$5Z0to =M׺WThZD{TĂo @nZ$Un[IcY\IaC4j[ z(.ʅ<# lK\QRcsL Ǜ\#=YEO3y1\f'R \8D*{!ګ^"O7] Uɍnͩ O>]8Yȅ OB{!(]EI.EM]D#鷃]Sր ;C]j+n9~9,RH=]s}Rw,']wLgPhıjP]msz/mW]RD@4X+Қ] 1\86 a]Q[,ݑ8a]'g<']!}_6֢3]ρ|LaTnn] =h' i/T䓆@ ]MʉI-&tDn] lSb9?QQE]18p~?3uP0^KWxE򿮨l/^&'?4֙}&9է^.~rQ $>uE;^/_m ?v%_2v6ZOJ)_3~dE9؃r= O_I1"[" ,9_UifbF!\_ukP,hMC8N _%p(E7m0qA_I^& |jc/r_#lKWʹgǼ_ VV}^_Mq(YD+_NS<^M{vY_9N'QWć_<Ɲp>`_7ʲ~sE劇f_. E,}?cbrn_ЋB\Ot*:7{_FLCŽzJ42|n`ڽ4Sqo3>!j$͍`D_Vo=@yI`@iL71\%`r]ш5 {U]I`sֶ?tr,2T`v7PrHZvx>'`LM0vv3?fl)k`>]3-[sf`$81 :,5%`FA5RUk]`YAڹOɬH0` cLؗA]_N`jf!ہԴ=X`.g)P$TD`˹}^% σ=Z0@q"`̴ٹgCM/ ]`Ρ3<[O/HL`aM٦\jqD,2nW`Y⢊_F=#^\@a؁yJ)4& q$a W̱[3k amc@TPO#ȋa*Ҫe)ZZ9a"-}/$Sۓ>l֑a.jatcf}*aa4Kd(\a7K"a><}!_ê2 B1^a>%H=;7(;aPxscӶ)H~V&waV E Mrr'aVBXBHA;6bORaVW7Iґdݟxa7aV|ېFXشK߷paa^,28rM~Se ab?G%_a|yq.gT UׯݝaceLa;H)n DU|,Z}a f~mdDЄкaFTt[Օ 4[5a䀮rw2n8DQtae倩'_+vba ye~Ag灚aڐnJn,Q"aqʛ5ȀKpb٘kXI-^bࡼ@%Ƌӧ`nFbɶTizAb3ǻF+Lb%ʼnb7cEſ蓀1 : <&.b8ͮP4 ;q}1}Lb=~5U<^P%k{FbDh&t`R7"@YbGs67&tRd'+rb]{&<#0XDG}gb^8 m6Ҍ'(摧bn9Mbjy ۔ۄ;b{hϥӂbEb ͐O blAQi& Mb Pdxƣqmc Ζ}d4L[7c+Mxy?mK#ic7Tb0 ق2cd*V"U@} OAd(d|&~+[Y Ydm3kIHpdBn\&ZdʦK0jLJ\d)f>:C)A7Ed=l'΢2MP ddP7ugFy.Xfd1ԯ!P=k6-d\`uYm yj@dyR/+g5d ÊXoIq2qK|RdbӻjG=d[8rM"9\_@dhls64do05 t<&Tud*;˥I]aXdt & еr,_d 0%e J9WnAݴeKoYKyKWe:2 imjBESe;@_dY؎0SeFI28~BS۬eTD`ˤY2}٣em\ jleq@ T?OIe7'D5ңOLA}ne 6]! ?evfQzA~ TJef~jLiF8#eQ-w!VI!DAse(q=Ga{reQ9!P V/eںSmƀ~f[f' ֪*f^;4/< >f_$U0Հ1Sfob`@E{W9f'I$f9Kl R!K6NGfv*4eȢR}NhfHWYG*X fޠBu@UdhSfvr̕K=fRxhf(vf/$ Y?_+fˆ%NMOu P+AFfm滒cvۻ tfGZDGCi,UfUP-^ r$z`fnM~hՆO,qg1_w ,Q=ovg .qS eg tb/mKۨIg xCﳛ$ۦ㍝gt :b"TgM& dbC6LgR9x@nQBOVg`yOTwg#eJ67g2`mLۆwtSV?(g odN+ A.ge=_Gu~+wg !`^Ǟ^[gVͯ?i{g\s 6c Qg01DW,SDgf<Qy-`x%$ghIfo%1X &gR TrQg@C54,U*Rh(U5EUWDl-h5xɱ8%h.h^ 0eǚ 2`\3 h2'ȁ?hߗ \8`myT Uhcss"y|FDhgQHVM[hL.v.>nkhb)K? y7Ciݜsmvdqqvԧid@ =J~inCA,WRwq7i"Opnti|ݵri3j0aiEtu(+iC \S ܯr>^ViJj3"D=;Dp кiN (4Y(5iaڬ8+ hfPi}UFm )iu*6P0XV3Җi€Hxl/v9icEuޗa!>Փ1i!Kg)󪾧R"imۘXnrsiY'KYglic%c@l'=ݺ%'i)އ ,[Myiܜޞ= k 6 3i!*AA n˰iB@G۶ '1i B"xi4^ͽcfe6j0n[V~x}<<@%j8?O)rF?btj8'$?߶6v6lVjjP,hkՋm>jYπC/cLHjmO㑀u+ CǺ[j.w*Od[YkgYEEeW0ZA ]xkPK}hŪO:tO/Ck%=TTdXhQk)1Pz-Z?kJKvӧ`Ckc lcnX.k¾[0Q .xkT&~~"50xvkwc^=݀aPNk0ví>g!k4«[n`֛ l (#}+v B{znPwl>7u>1/LlU_,߯Al%14)`l2BN>Szul:T3$U.;6l? i,yMU w8lActMe_MM`lKyymfhۑ|lW>]SOrĺll`hh E5q%H Plle|_Z f1bluŽwrI \Yl|3°qP7IV\l|,lA|5掽lUп ^z<f;ly6󹰜t̹qO lܬơRXlD0؉6Ӹl~uV^πI0llwr,ElFhv1 pDhј!@m7|&WJ8\`9RADTmbX׀)UU mf+=4 oU4!msEw֎{#2m]`ˢ9C@Bm/ŔgP$lmI֊Mr&BM m\zdStx Mh=l"mF@r\.gQume)YR @AH.[imlQ,&MmBEc}1Mڃt6mֶcHxOUw'mRy#K hmxC@\Nrrm̾s?ֱn iQmΔ}v:3|gmΨ;5Q9*ȍ/m9шVH*|vbO_cmY_ߑ>\mڂl ?pylí٪zm]/Tt#Crm&h 8X1m/,1!"(mMϮMZ!^US1mta"d*QNe~ emvl~2ՀmơK۽6ve=amsoA q OBmb׿aamnkv<ܻEMh{*$8nm*p!4:oSl0>qAnq`t= @ 9XvKnqűRm2 gHn(=nsf9;Z.Hon፾+wř%JV`n?Kgvɚeiڥn)DzL&MonEaψ=~sLnEtN/(*H_nbX ]jnwϮd=o#|~1EKiH3oIZ%&0"bNOo+h8; `o ~7R@t)NƇ@op> 4*VZ1o,-oCJHtQiohQgX>RP_o5 cbec{ro~&%*=-%o)3`Ui07_o֯Dp͕<]p 6}]OdvpЄ7}mIp-JAs*yurpIAI- IpJTWɴR,#pd+btʢ1. L7Opmd<ʠ)`x֦.$6ptʼJaUfbo&(jkqWpXڴ{Q<1plDAO&p!cՃj#ߐ7VpƇ}n$8&Sp}iqS+ W\Wp%TYIOv`%^pvE>]M`jpIvߢpb5p9w?dsM8p𤖀;JLL p?11Ռ(1>Jup:g%3/=ϳ\q'E|: `.q+LsoX`Kdkq-;YHt'To Kq4$}7E0*q\1TW@z5fXdqƱ#q] .Tqj)&^w>qly!-9hh:SK;qtw)/]yi -qtjiƑֹ(N;qyb\6-ߜ8-PҞ0q} pWuwhRN&=;~qoV޵ǂ/mUeqz:3ZDԃ.q }n(~q# |h{fZqQ7UQtI ^tY=^epentjLoy QF+gqttisjum78ϭt{$wTbjłDt:1Cq^$tg+[$6JLǔt{<w"|ä(tè~er#'o2Yt.눾crΨNslrVtWQFga!t5Nr52Ӧt{[I)*!;w#tpLl$Z 0/t‹`BVzc%u YRC3$7+Sa>vuMAy/u8$au0 4&?u/rVCZ_SMuLRW@I" uSFdh4ӫΌu\2q:&6fĺwbnu`j `ӵ0urLɋWi_َIuu@QmJ4;oˁ' Bu{QS`t.pquy%Ϋzd!ĞbyuradY^f@x_unʗ7*6huJm^~D'I$wu) %8͂@&auqtdz/{ҭeuMy 8iЮtu3g`1'^pu)jYS!/&uj:=[)X5'3u5'pu}au)+kAunzSREǦam8Lud"WeJJUiuo3׍u# vߜvI%[x2.+yv 9c؂7ӿv8I_t@^-Qv,!$e; ,w$}{v?*p}N{~vA0r.&tvvH2F?ܡW L]W@[wQu<62.u,wŽP퀭#ìwV #Yvw̚7ps|z?wR~E`!gx%w0UB/21Tw L,[4N05pEKwh,G>9bzӈQےwA M:="ũOw]jWJͥx 4))9 >TPx}kPs6pN#މ;xHqL/hy3,뤺<>x}kt!Fa>x}g&T(v'7 kIHx~`y2~<KPjOx~H5z x; Ch_wtxѩ.yW<=x5u`$`?=GXxDhrSJМFO=x Qo߮d\ʲxr9k"ΑNS8?x˹ CO-l2x *NM˻@85x|cPU4n+xò짒0:n 'xԲZ8X8dJ 3x4k/?ux5[ĵf#jC[3$y D&C-ഒIp2y__ z:x~3yq;|)o:ryjf~\y6^vQӍL`ryҰbΒQ4 \dy!JT(&*P\y9s',p-H uy=qz:֝s5(zyN7DOx+T{y7pOlOXBz7Q]sdJzz=c4EfҴ J^>S{.z@灔W.t/VzE3 N|adѢVdzK&_|ޜ3*5PewzNy,zA( dNzS sf[H&zTr).@(3ze _0a|x/z~! 0;Nz \xY _ˑxzchO*ݶAzK&8=ަ-zTgh6B^ ńzsܜNsY )cnz$|oIJ9zlY`Wz!E&{<'I(l6 ~G{x7VÊkتL>!{#qV)2: PMbP{7x  Gz_L {DDeE Xb ceY{Q^T;BZL\JFX{\2ċr=:#{`J~ }o]i {kTX+'8"gQ&{kjɧ/-zdΈ{m -B؛@ٿp2c?{r9S[@+HT fKXl/ƽ{XT1N/Y A{1. ]1c*7C{֎)oQHO"{9Z0y{9;7rA{p%nt''sn{IA蘿ݺ<5{Ɓ/LcLD&{ʽd>YROdw}5N{-*%ղ'XS{ ,?hE9@Tx{c+0܍C9D|$25#-eTQ|,\pY 0^ ef5(ί|7v5 _WԮ[]J+|=xڰE]kO Z~B|EGM1nMPV|`P|bZۂjи|f)akkGrj|mb,◖&f[.?H|pFa%]j(|mecħ-|hNcJQ4T|VP$5W|;;h1|Dװ}yFZ:8-|%jFcFYm|\(v+jch\TgTd'|GlD?*|"yG;a|GMF鶩Z|DFSۊC=} lN$,95yzŅ} A|G.'qǁ&}UFpG}צ\7}+vעi+*X sfQ},kd֬䏵i}-vBrָ},^}=թZk$u#V%B0}@LOAjBf_{,h}Bo0 b.In'Í}ZlzyJjX}|@Ha 3Wxߗ}2Bpn J+}¨o|vfev(} O0P}Nԫt_}kpU͚wR}8mV;7%Mt %}ƊLT;#1Xt}tk!K;>]ݞ}߇2'?v#to.}g(aB[mU2l}]?/wi*);2q}ܯ*G er}rȫj#(I\}Es)=~l]<4{Tv8d~ʯ fst6~$WY}Aǁ'Pj3~,uhoVi!M}V~-d3@_s g|GlV~Dƙ;{& tG~SaJ ꍦB& Y Qz~S?x7{3V8Gb~gD)ɃGގf#~sG[#-_;R~ꝧa -,ֽ2Y~1RVbhl~"er#z}~"0``6Vi~5j(:+ܟZؑ~=Xˀ y~`Ga!Q-#;~zQ[#VQlxhA^"9ǾNCʒ.6vpAg5V[C 3y*;ۣ4T9^VjZ MR;ք^ o9b(EB,Мj,eUҚB%Voũ_CO6C_Mk R8Y;bچlqy_@] pcT`[i <4,BSsaT^^`rdl%]6TZpM6_$.(6lWqw{C𭮲* ^w sT뮕ܓ{zCm/ B})_4ߏ(o-2UM3s6Ru%BNMTzL,^{чE-1E#5 ƚbhG+%"ljMh5Rtq=w<_W25 8o>3u$ɶdLI*(@cLӀyWJ [A]z|O$8]oǀzZĜ/L\M:[)3ELYp~R^7RàmŔ'sl/PӅ, cV1y "K>ؼUbxMtbC^mZ~kxl4L%<`9s.ݾe?xfZʀFLC b:`M6΄À;|p~b: a#S9jdu\USSVQӜaw>fAw|vu[p/}Q"ȧz2| ک5hBf!ضSwЁacѭIŀ(WS݇J-wx m{ nMGnqtEH 2ف8&ȱ.tU;ZVbD8&T]R ^hj8Jۡ]ˁ@m{ OjakZnטjNa{掸6:P\/S|Eٗ,waB I% ȁIbс2Vֱi`1햔BU=`liT*}>vr?)ACnnBEb߂Dά]BEr]Hݒ=(4ZΠf k. ǖbB:/wks߰PAO.5%u͛إ;tD_ۂp'$G$Zgлꂿ ,> TxgȂ`6ڲoxˌgs _ŀbBDks, p֝_'9 RX CǴ wEkHJY q}SRuebV/Ư d2:[Sc4AcN & ڏpf`'3F8|#pRsQR#~"}5o`Q(*cuy2 [-M򃊬.u0sBMd-M_i6r`8u/R>ۃFFіGE$ (W\J336Ef;Ճ]%Wnh 5>~:rxYC@% N Yo>N<1<9a'꼏ԓmhÃWk! A'vuvqd&FDAث! zҟory ͌#E\Rg@en41޸B FNi* 8~(z,)O9& iRIfF$N8^y{ShP$P.6%X3ײ#]SDŽ]NX}ݾm~ܙzLx3CHs^E"Sq>;(2њKMXU7Fl.dH%"f>*ʴ,Ƈ(Ae7҆a]ȎS4!&cɮfUNj~L;ӄgN SJn:3d =\%@SY*|%4L|=M"\_w?#0Qljbes lϏaH;bKK`[Zѡ?R#6xw A$$B2|({,c{f .7߻3% 8이@@giK2o"GMˆz/8eg>5X̸G$݅0Zb W˕0Z(A醥,kR"K/M{bm&^{T;Py›O^׳. ?zFτ% N wdkGyBNd2FFYlLD-Pi;)XKj̜a,PQK ,:bii/i՘$nݘz2g!;p҅~_/7xs]+e%b@ַ+&r+7-eTj9ǼpOх}Φh5|]SW\~q!0TBOZׇI=ly؅A6y˹szMW (ĕMeo# \aEy,HYҖ1*JN!;FrTrMnx+4z|LɀƯn|Vn]dpI7q=2:;v<=#O r1x &{gN߷v)Ùxt{Qo+Z10:9$O*w"^1O#X0EҰ!6$χ2DC@i}*!'"ivBݜVrE+JJ&4$e:0;W-J%|OPďчHbc*t޺O!L;8t|IsіuuP NÇq٨㟺u^hVڎ((I[˞28u66Gɰb'CߜhiyI,&R2I7ڇB׻&2!OO,ϷךA@zOVl M #B<^r} /ч2%2)ȘWUPŽʡ6X+,/L>+Ȕȹy]ޖފqt~Nh[x!8lz9?mMygWaCp4KC]iĵi]tw=JPOui}g4׿kF^mXԷO~ 39'qˈ =UV?߈Es`WtqJ5}rX6R9 ܈ar[Vޖn!ԉ\2cIO}oCkud!7vAl4z"u=mCϮbBޥm;vÉTh}>K\a֫sw|w$ rX{!%v?)U+ 3&zT >[#*_lפˏ3ޥĉއ֓"9DZ$0O醗L 7szl؋p vh;RB}C]T WÁ lTxĖ*f!A,1GVoIWN6 ,d?aLu"Ylׂy2TBi"goc͒cGQpkNC-Z*HEJWŊILV,6zQⓂP3vW@T5aũ].Aج!ӊvz*jHxC>NJ}>a ] ʟAsٔizd9i>']銡iCn1QrwL! nY=-L)f{bzy 7I9+SѪU} c:Ȩuyi˛ё*snw+rR}A'Ы Fbe=30,YΊ aY;Ls)wt tI!G߫/#F8hGg8ZQ\Ml!Ϧo!NvSdT:xex] 3=c-18%-!YTy!sI'p‹VkZT@/%PUAUxvR%2_S x #|PU\bF` &ueC[l0 z*,C|\Svrg-gJDIALgz;VB3/zߞ.h>u}2# 161As&LCY:S#8s<2h7Jz㋸>f5[Jӊ"!NËb g*y3 I׋*֐Enњ/NjeeܑNMVZ&ܩ||TmpHT"ZwRmZ%um7' j|: Kq'GAN P:3'\#(vnюbU`!B`V9Ō2ʪq"=*(U2wRo/NƏK#~-ûJۦUό^@xA#gi~BUN BeP^|=SBgg%9"0ɦatYvڊՈ}mc29&& Җĩ?]?%9L t#2.awpL 7z%45%؊6pC{d3[ć#ԮcD"eԵTJͻU?kI~S//4,OӲE sOR9, e(« P>2І\1 یAtrT+t I~F?g&ߌ1ԽF7(p.w _a=6XWէY+#U;p^\g[s<)$[5Zv~,s l,SQʖ_7ЃiGڍ 0C|>V ,sfMGO$UÎx`ۍ(hnX3Mp0طXIs$SM@2܃w^͍X():' RLhY6H>H;Jh.~ԍ^Je{_ Tgbj2nc׸ݤv{9rpfWXiIJ|(Y'폜HC $0駍|"Q'朠(⍸б׌׼|ͶtJV+ .ƚ7@}8}cд=[#{35ǨCU/LU+k>8s͗8aUV~g9͹9Ŗi#~hHG ֫jX/Eb.gũB_Y,Bhv601FyصH?uP4 )-Z,&,0Je.OlK9L#>PNMQnO2͎C;BG::F C-X)9.kTH3 w.Kj Ʋ:FlKARŃ< kå_KD49xH1a^+: H@=< `2Ѓ5bLNWBΏd\OtiNkdSjn*`rǗ KPYxVK}tkYRKJpSO -1u}vuOi38S`UљDL bTjah&5(׾5rz!xU@6zR}/J'w|>Zݙ )j9~-&t["xP :ًOgݯcůN\bhɐHpQp]@?VJ iA]EJc #߁Z&DIyO j*Y1<̾/S8*7#>0dzLg@m_*ro>k.nIK/Kplg M Ӗ(Ju.9!u>8B4~onmDߴڜΐG*JA<|p8yrBwWH͐`n/x/˅]+uߺ K<ҐJKp斿ӝ!M QucfD7b%$>b NI%,|*h(D"[ӑB[ }c=8)z5Z RTs}vjّ/"s5Ԯ>< 83nG }vXPH|mo1\y6H2‘SXɹ|H0_Jp&b.gލLfe;Nӱv=k {g{Z:G?0eb@-IлJݳ{]O`LCit*tgQQ;aP>557^wGM>P}3>2U,I_7uň!SЌf@}*]߰C>Zg!f^FvZFʖdu$ܒTmzkUJo?;C+ME0pkPO/onbE8ђ)2Ua?Abѥ8aP;Q*7:lsd*.*ڑ.P9L-Fe➋ꐒSjV'wcTSI e@[ot*EK);pFE=~ XA5u<p. 8d}$,xeԙY%d =zZcV9EP~2|dX[2/U?Da!AɬT"촤1TbU úT_b&dHUc³ גQĢȪvl 4`rp)&{Nkly: q)/\.0 x$z#:mmS"ڝp`$+AK1xpfY 5Aђ۸[%{NET`9 c#G0"9 #oB!2EiPeh;+ؾ;RBHoJYIE"kps6 Rdf(Â7c%%D566S70aT<D|OQ-sRZPxFd|_HPԤt(}37򡣾]#[d Rj˨-)))Uu6&-BAm.×?g?)wmWΐ\1귓Eςp}cBv! K Cċ]:NnœMH85!wD#}aOrx;gBV}d=P2c3|"%Tؓm<&Jݓa U30o\e2G3"ְrC4m&);hs7ߺG2M$v|=+8ul<_G7`ޓ1ko%Fln*1,+&tԑ\H|?(D Ԁ(gǰ.xvWV8C,**7>)&k\˖˄/=osvvGϰJILNK̚/5B͔& Tg0ˋ|/ufg"WU?6p)=@N(XR04 U5ՇLRuκWm#,5*jRM}=K! g6Na'[(ܔKOY1T\#cBwupHgYRZ0՜q,h%!rjljB<Ȧ]M){^憭W+7ԉ2[)' 4.Y4V4jΈВ`I $sN<N*:VZW>B0*R#yyՒD~k<(mc3H{;T<1> ¤/{L@n(}?]'CCxgj.C@hMHgBNЮԯ:]3ͱQ=B_ÁF~og>csy*2Vl~š#ŒegU>!PvoZlԙȒBޮ54د#c<{9;0ܧ )1RO)+zT,` ႕FSal`qB.rf-xAwh+ {r?e-iq?1뇩Z#rN:e$h]贓r1JLnaG.ӂܡ3zoDXU^U,Ծz!Ƽc9N9'mאcOoGLf#~TGRo+I֥lȹs񥢾]ez󿶊|Gw#:6&ULxE |#wR:ւp!F1e|$1T^8Z<򾛖Q F 'HEc9h}YL GzcN \cgeZ'P/zgV@plZ$]c@<ϧFB8G(&٨v(˂D e.H1>_>Bcfвd/3$  1lr36PkC^xfΫ ً>mE #8w;3M|b6SF6|2Zv=ʦk'|eN8 FVzX3z²3v9UPlXǟ,WKyTt Bejc?(ٱo%'¦EͤJ3_>%P=8ut;l5w|vw"8\z_=j8:ŗ:[\,Q0b ެYї< 5jo"7}YPI+C ޼Z%󒭄 g/%-}pX9(=!֗zH *q1 EBo>?tY/(X UG0c㹙>X#YC1(Q(EڗEUVqrtpU {fܥseX<|RwB]f5 k X۵#T i FTMaO)f b$ΐG2T,f!UM~ ;aOtģ$Jj'4xQ1+#î߽O(&磘/ xFՃ9 ^埓ֹ Q=6kdY". 򣻾uwzBl~v:׬'9H8Z/혖ɼOM~\^ s _dtܟS},OwEЖFTM#2KzQȈ=ka@5D#5lDĘJ[Bzc;fM]0bT2˘؏!|V T ާ̘5J6+6;aG xJEH{FP<`tȝ~E52@}#c-јR K4Z1O0hy/iҎ٘wF蔋&uVJ pB@Phs+|ЭFbuB#M(+XkNK`C&KqlZ`cUYcڼ:< ey 5Һ2j-PskwD&=ln! @A=3ϞYwXg٢B@2GfȾ8K?ՊٓJ֠Ӈ/ D.`r6ռZрOGQ?)||Ț=F N_ϣ{P홤 k%!n0|ISlGz^x?f dHKY[4Nk)8sOlrEbLҴ[˙C,L':;S&!Ij/]]Q>uUt2ZYEuoWhh Sn%Hck{'d7|M>zD3~H \I˅OcԚfv+بvz5AVy^8}̥H:PG9 }0~!ؗqW>]ң Tɬ-%\Y[-A6(X`-&5Qu*z\9OimxL皓tFƣYgGs'Ƭ*ͭ򚣸 f-"$6dv ՘D_$p\\ik(wb]vTϿgD2U\ەwI CAH; ܖz12:Jw0jnxb00Hg]tw0PwN 'u kOTK`ltgN.ߛ W`[_Z.k78xe$@'wӚ>0=Fvǁ!C~N˕xW9,Eg"77;^rR'aXDBb^ƛW0>q}# *^p9FDIu+GwfM+r{>Sp)c֎oyWڣɄ~o: T 3%8_qmIb3pw4]yBwW=^9!?|ڈeI>KUΧt˞e[&j L>&[4{ #^Ki/)k]B蛯Du} |sCۡUEYTP'-͛d3w(3P^|=kGěJ|$'pi4wCX":K/\PΛnO$ rџ Q蒅wCФ<"fO %[K's1ùTvSc {&gWC4"?/fGkg#D޺)y|c$5lWq%Ҹ,nozo7 jq14 lh%"؜A4-F+'sP x-pD_IcȜYA}v},MhaUC;lRzgely乳劔p"TOWRsK`8.6Q (zLJ6BؠJk]3.ȟXkc6M|2hɜ]ekG%*:q,z$&]$E}{o߶=EiŜ;RIY{TN|QoǙҴD̻AϾP2'3S؛rH ($Op&Qa_%TxV7݋⭜̼Jo.#szD5Vi%E9.r]7baXGw)7^!薮C6c#1?{կoº{KGPzK2G"6,vOunbcJF\ S3{#4^Rrݝ]n#UTe=H`<Ֆ_m+ݙji{cyl.ձL޽uevd5{vg䉣>ӀG;V۝-J0$/N~M slug5JCX7_"= ѝU:R 53{>Q=#̭o'BM o^%#g\UQ|&s'f҄{zCnQ/3{byQKoɒ.Q-Hxe̯>G`;Pٱ5x؝_~]Sy䕞"HBA>}!4Vr&o^#'.&BLm7&:t&CLl@e5 =(j')V@nn}+yX8`hrϜÅЯD:FAKdԾ . 6V/'#sx'tyv~RVlfxEz9SΟaf6y&.@A}0g8 Aìxz>*~OetJǻFLGDC WU(^SX)Q`暈.lX!3 *\cx=m*Xr71AOխ?VټP2h렙R`>B'dȕ{{JF\ VԀ&roUdT'Yֳ^ET+ib ~hG,CUG[,o#o4r:Ei]A? v7c{3Np=gʽEariK*"0b^Z i#,J}$ jQ#K 8bDġ q*qq镋-<K(뽇L&4$8)s9 $yC֬㟓$%Bh t('}ɇ^=->z4 (C37g] !<%F(38c" w_#:^@ږZ xptޒyCzT,a22l^L-+km OQ|ػ \6U۸ү23Ph˝1 ;^vVǮnE՗O4c| u hK0NdEg_Oiwt8ը:Mpw^! O/P&(of old/x RC:TqOQvdc.t]K[RUרB j{E'8ϴH%)blTsY< I/J=ШafDo_:=gE7/I57O8,kgM6x#?Ӎe:UNc[Z5 c6Eⲗ)ع5քM]d,RR%"hwOB2mb1wDDl~6&}Dc髄;p m8?Yf}%N LeBQ n!4Rd!UcId)ynPJ]jn}_ *W.MlNe*\&DJ[ xrl΂^ כaxᤃ+y'% Vu&o+F {eF@+C}a0 77M&ͤ6$4PLٙ5xWɄ8%f]6n?~M$hiG@W'až9NK`h&ڳ,(y:w>/徿U*Y+{˘nWV(5إ*NLP bXc͵٥*X~]dF"䒥ChliLm@ݣwG{P:1H?⌡oJWbai+ŗG]啥]*48O=I;ץqj#v Ҩu$2t 5:8W䥁`g57K|Qu^\P#Pͧ4꥘|g#ZisҖ?T+V{%iV֟.Du d  ѡaW\PEA ό$<&SKWSu,kf7RMPrWLƭ,&aP)L64{(#S=f\mp-hwӏxn8Jґ ,ǓB+w+CFH?OAD=R,wV WIڧ؍=|3g|eܧ٬-v-{-*~ާojw))0ךgQgj23=&~է҅3S F:{](HL}۱¨ @#3W]J19י4/3՗z¨@]؀Ax cJS{0*H6ݳ{ycfӨSk H)kfez:>y CS,-'Ut@@5i~ ^n=:7;ThG\#H+< &Tw\y_/.i6z)Q'0TF ։lHRɢ1'w :v9hB`cާy:/Y©i 8w1Z>C@G\hYSP*Dq썡< J`x̞Q[c` \ϕ.dSNK:5$SP1~1x#XW(d4"xcro0TfI׃̪"ᄟj[@=DHq`-rg22-S@㍀!ym̪5KSH ,ol8Yg6^.L- X>R@s/7<i@AZPe R4# xPEҷB.=8.{Tn}\7;}wj5 Yb>;4%R'T;aZ*{r3/=It񮈰ܪbΜNxq wXx>ISa2OMAyhG9 ۶ؚxSggIel\$N5qOd힘Ѳ84 Ǯ,%ksTHɺA(۪ K* .MӬe.BW0zF= o}BZ z)Y2mr7etjv) 4ΥO|ݫD> 6PARnN)i5fpW#[-@9[/μV2q_QuM;t8˦#~Bk[Pګ<͹:kοװYO@m +*Ǵ7I\yXG{k{p5I,6Li cӗD 0pN[89rwgS2ϦFꞑ̟ݘZW꼑fv;q~]گ .􉦙"* + ,&7҈L]өh?M0W@INNC2Y+7}11_5U'cg1qp0LBuxn0^@sTe^z.O0n&L zs(~!ކ1s1aW>c3Mb`ݬsQREQ!+qZ<z, C>J6k*ꡋ򬨼̫pj˛ita04IkmY"qڙϬہuݙx.ѤZ}~I61mv˯Q}h]$nbCz\]ʭPPQ]> Qԭ =}YFpΩ%#$yYu)+ƭ4F".{FJȭ9iHTC%Rm\*JNѓO"3N.'d-WqB[z٤niePfwR;8jn筈Fۀo٢zP$ׁJg9%kS?u\-??=G3k=_YoS9ȅ1/.4i'Y76%h2iA޴ksu lbb"jY߬ɨ/j}nlŋз< 3H17>H<*P$~3 S =~K ?κQԽ{x=LA<-m߯OQzDYyg"l +م?`Y`&La:bOAWṚk%1c@>Z憯[^88/ZGfN;&aa2]ԦLTӯdah&U!+eeFJH;̉PuWlh[$y%{V9Kܞ؍i[ ZFO$NRMET,_sE1D U q$ښEvPB0)!)TnUto ۻ P_ϯR'*܁tOzM&zB a{ngܯ"p^̗.G u1 +X V+r:d"*lhU>Q+,%m#B!2S`Q8J:°,χ{FȢO;>ư-7:8%X\Z16y%™Rǩv>?U.7R(ĖC{vͰDӧ~%eaJ2>aF&10WO&6dㄺ+A/ASg|VFMzT'0!ahTT =f@~Či_L;:I k!AgrA1ؙkި7ؼkB$zY[2uq}f $q :Utر&Jڱy/ eޜA.? mX3xwۭ8#un3,X;ɧM,+πom3 nl#z8ꞙFuo9;6ù○?Ռ»Tro .<9) >T$2fw yޔuUK7pV H/0.bɲ!7(ϴ`Ŋ%ΎŲTgH4xs 7Ȳ}nTN!AO鑪ؿNBP 8=y'Pw#.5FD 'V-b4Vb>4$!T$8*vgl!' f?Vq}3|pkXɹgyo^Y}#T<<@~RBHԨK8xO~rV5)7^B㗳A!eF3VFНٳ7[T-8aȣUA.zk՝/qj]<~JLE双96|#w;X;)c Ӧ@ \E=[ fwȺ5S+14 jbʿ^p1sqWhDL٣ói "ʣvI@!-Zkՠ!](p5GRQ?,V@QdŴ6-)sZ1fbږJ'eKN/cU, QoϪ:@%7͔cw%d/4'FOf d/dSdwpAz gbM 35}ta@mhMpJj%G-T+oN$}uCzV@5 bnyJ7ml}٬phI{IeDM=Zb KPCUtsSuu @5p>B99˴Q򤾍l(-O,J"&5G/Ӵ- ^+ke Rr-7NJ8 >Xi;kW(UiJn=AG8_B3w 휠jrM}]i  Fݔ%26tHHҚ%хεAsXP)UoW{wZtNAGεYSgZJq ui'f9^y:BlKݵpd;2s҅,E~69k"B`qbPRS u /5:Q*3Ec3BcR5<ִGN답;J)$KEYC15#鏵ĔMO4 bc?]%uAY-_gŵKܩbyl$=խZ?YJ(ɱ'cJR+gxϠCwFқ3]2s 쬷 IRWfRPo7q*ՎHq܆Yvp} <~rI*pe *fU^bOuؚ|US_?ጅuGIԆbV4]PM.:xVz[w cȸ0k*_$dG+Mw3|_IH|Xbyeq6m}Ȗ7j@2rl?*^YtbD>%2I|c w؃MQHE?1&4y.0X#eJ[蹘"Y]t~G鹜|5T;9]o]ݹuWm& Y3ǹ[cA^ ?Cb*tIO'^MI\Vޅǝi%){_6Zzڹ{hdKahHV>2jKy)y?Yb}%eκ)4&7 n5"m%+Y眀Y4>q ݵZv52r~+b7t>]~,;H@jb7pRZOWIP.z&8" L@T$7_UD,7JZ F4u;Q5$k\;U=>ċh%^)A1N*h Zla-\v@njvp,6&\*Q9QbvN hBov纉J Ꚁll (R¨Nu\osCi:]#AYXUx׼a߶dХ7< n4TW%ک ̴'\W!ѭb"ui9*# Zi&;Cp堃@ JE5O.5T|  ?afzDBxLT w_ۈ2CP;G657@8ł nK&wcڻo4O~~ʐ8үunJ%Z gRs^N%"2duV`K(λDwWPߕDػSx^:oIJ1"AkA5tofuoPMq?4<)-qNKسDe8׻kZaRkFC/'PwD}V=ao {'9XqаI "3v _Ro.0q`q7f 2t'VDR7) Aͼz;̈́L|P TTrlhkAݝ͈:-#{OLY[9^Yu@0KA`n/{uYk M_9&UŻ]Z#nkJОw{5Yl1sJ_ݻۭ#RcZT` WpȉEH=7";(GV*;!PVfMzX6}y; 9@[ pšlVq5А"}6& L*k#݀#9_E d6]&u5/ "u#~&+EM={2%F.lʎ<\.(JV?P3o1;sdCS3t>ƒߕF׼[3汦/)t BG^.o,{e̐~nSHS5\ܷ)L.M@ >]=VVY'%\Pn{E½ Zί lr6MDo"5ޕ=,pM*%,Pe-rδ)}8ٸCO,Aj|Dm .+JМs(WXCih? ؽ@+Bvy\eJ 2%=&>[ 78}^ pg/oQBÈ71_EՐW^~&I|sn?KG¾ /-dH+ax{77Rw`&ˎ@Nč=)λ!Ia@L"5V л!`qS7tSy _%_Ό.<<ҼaH/lŎpz^H F;LZ %S%T~۞Ye sk.ǿb;ׄ# p?}ɶEqqs4k;tS  wh?6v R`޿\ȷ`Tk s0w!FquH"Ru?u5; B`e6p,݀Sg+P/HޛM?M #ck|E9;eѽG;zO{, M1rq<1tPyhEX`<1|Ǿ;HؽlBc;jivtF8.jX]G VTpA2_oB_FK9l;k"*0d#ʸ B eNގ hECCV(&AvC̛'^9{5wyڞ,]!k!| ,1CgLֽN$ؚ,싙IG=/7 lHeR6^1.x|+D/;s3 ">,39t\ q*& VznNn\іbK!uQcG;~W&ٯRf6{r:ۚw^͐c6/@hu55- vň6)F':M/td.FfJ?82@7@e&h[6i{zX΂^#]XOS-44F% #IWTΙf [zFu3j:7&^ԡ~(?j~vMЍ$$ sԘ?+;eKuq0P =촁L2;Pb !DC8^q\Sm1!JӚEa$6sűcݝ),%;G!\].V:/; .)+ :a &z78Y,jV blzX+[eʌL>> f_0z!Cm;#Ɩez!H|ved+z@G„$J81e|,<łb®/PM?9.{P+t ²sZ7yh$Ũ:µC$Q8Zc+»o$iXQ ¼w Q5Jv]¾U؈78୔WS܍L¾â¦Ps]y +¿\yCsMR@Y5;qŖTf RWvm8 vp҂= ZN &3R)O("~x#Wp4ǭxj]\9K璁EZ_'6) hA Q: &P9Q_ל9;+/<uxŪiMU&,'h o;hK$̄;Nkc⒐2x1^&J̋N6(Ý;JX"lL)ˠq 1htH|6!Upv8E.̓S#i! 痡F03@$":@2z ܋RvrKi,zN!:˽yfY8d9D|3WE=IUODA,M7[䊃nM[/_ hh  J_ C_rixK+/V_/&Zez}qcvd0q#-3+ZCFW;A8AB-ĊϞhE(0ěgmlβY ?ĝDJd2ڸ'osNqϬЦa2OFDpG:"Lʅ Jd.| =>$Y-^s`R5G&Y]~܏CNw Y8fD6Jd0LWcZ~:"1Kɫ'&QyWrrfO" qfAl2D ST0*_8aUnG.wxNfQG@Ǫ7lO$\|2X){={Eh v2)A%OemnbMBz|9 qG$-PehV*K9&=~)"['=^hkT|:\5Q(,;`9_PٲϡvXnŎ\FB4T47o}hŞBU Jв ŠZ[8,yssGŧ4 C\7q$_ Ů|Z 6SngyűSD ;EڗKcű1)͐z(PgIŵ;Ԑ.vhhhqp2OZ9&l6a :hW9s1ǖD# }-MD!D`5U;̐P]:cx)ih6%CjJ;6 ;k-&+Ld9ϳu>zo B4"'qPT1o&yƚKg^y D=ƚZT*CJ{,ƨdrĴ;ƬarP/l^+yUƮۆG'#ǀ;ƳO w At ſ- ) )h- A`hfB$Bs"#g=y  -p&Q]05!1iQvl{?E  jٗ3$0iNeΒ_ !eO;ײ"U8@7M14r7^=ҝH~~-G.VT/ At @n}c$vJS%g$d3OP#'$]ö&[P?[X0ȉ]TVf4;Ș+XXC\sV5"Z}1ț;.`"R8]ȡiN5f;zqvȦ\C qȨ-MʾHYȾLjuF:-d ?7 ,Qt/, (U3ЩD&дEwvgq| d4Z] o% $8*1{*lG%*'IFRH,xcV_'ޱ,r1>}$w=qSμ7P3AeePF&&R%+dfΉr,_QT6L v)nor4X4F:X6yev!хᕞʂɸ݊"Ř}ɸA3I M0E*ɼfX}w)/M ]΀'j ?֫bcI+bVp2WCr>:UHekcEU0ͱE&*ʓhZ@=j31%Řb [G_VL`BC޾_?!`Х!"Mr#QQޒ"[vodr 䢌& ˜"x57C0m% 7_#qvxdF4JfTVY"feWR>y8WWAQt^>q kNv0uAsatOǠ`NP'QC{;G;]> &N`}éoa~s)9aWAjSg5͊ÿZI ʀCCN SRCm3wʈ+tC\ҾLjD5aNʉ;l{K  ?Lʙ7t"s\uW>ʠ/\C/9c+Cŷʾ㑣ysl s ^ʝ1;h~Ң=UC(T~r5yuue]G&Yt7=@XTQ-E]_mzjd :"-%h^$['̚"W&G{N8{=e$.--Skv0e_?gY"4sfXjӈDȹ_6Lb θtG(P6h-/sm[.pŤT˩uuF ˌD͉Eކ VqZE˕Mm}X/ˠ[ۅ˥iwР$Ie(b˪ՀXqBl˭a4k3aPk˳895Se欃 $˷4^-oh ǁCM!4;?Q5)9rf%eW7hNiW?|?'/9y #tW-o]I FP!=Ll4R>%0mcTp濱F5 vp#1J,v]Y U"2?֪u +$H-E E#:~j%[14@,4YaHN uu0^._MIR+/ed iYe4xqF 6VƗ֯c%A%&)Rhռ!:E]^x'#}û?q} D{3A4b12 uę7@KN[{p29< zApkF-Ia7.z dg Waw2o{M[|t#jtU@j{1?sQFuol XGxb n~Hq rVgy.H :`c̀ fV֢C 'R+̓T>r+h3+9͌As? V๟'͏8A(fXjt1͟$ -;cT1ͬrȜ65#hOͰiʛ."#U4145͹lw#,<˯jT$ (ͽ^9,!>[;mzbsn|fsՒ'^I ;B^&9};;S 쇲$8|ň|s>otbhE .ˇ68 'sS^|/Kc߆T- gk 5'%>v-^[:2+ßy"ffuAZ#=$'U7ٜ9H'a;ZpB"p&>SuycZpKJ rɔ\|M]7@Mqr@_Ti\ YPdBbe]HnMyȚEno: @s)yHy΃%~lg sj)΍:%åTA7WΓͽݸ7U=3/Η\$~m:(#4 4Η|pd;j;H2Θ:k|owΟ-G ⃹isWΩ\Նcn6?e"ԁ5δMppTv͋*Mb| .7 0`ϗhٙ!WcVvi یWXV27(6hG͙LexAtxV%Pv ݘn'tvu|::4P!;o.L ګ/_ue*-`&hJb]5Q(ǚpQ?xu\djf<%7dJ/ϸr!,j%Ef#2|ND/_.v4;QSڥҡG˻h̫t̫AHM*(l1g` 2It)%=BGe,9ƽ!Ry`πA5U8Zya*[Ui;χQv\\0QV|.ϋ,.I|ϓCϣ"I:iiPpϥ@Qtx#pEsϩVLjj_&ǵ[wod{I| %~j]O\;UKE12 =~d5e V6YCSC`= yo b_yW"g_!i Iҡ+O4KčLqR^NSңn[s !1q2ҫSjzb oҳ)XbO$kz^)ҷGHy%Ўwt0’ҿ"6K`xƏ|QҘ@H~uOORq*.-F ӕd%jIqk!O.!Rk^˛q;Mcߪ2{_EFjdӬ\xw_Go0;V,PejOxOUStc1ٕ{BU<*ڏd|K3$?oڦ)*X:e!>@i,?@pZö-,o ,Z`oĹ1/'Jb/arhaQ9vCU@_2o+$?NI xcYJt5'wW̰=SaUuhsTiWȭm&42ӈZw`هT*,Z\߷v#GC=sEg`2wl)!k; zoWN;?vFp8„,DŁAvy&$smN4X Ӓ•].=Ә³f{6*j9pd=Xӫ`HL;9X]cpӭO<&d|EӵazUU6G ›DKId UrXj>Cj@qޞ#Y3wY77tBjUZiKc$cнyMv5gP{)v#LyX~] :T~onXo£1:U ԓo-92YۚLxԥzX@RP ԧ U~ yodԵ%dmz:JV7 ԶϘmAPWɑXڊ0?AQ촐ĉY߳ǃuJ (<˭aNxr#}Q2rXjED%fOxvYRa6ĝ6{9S)&YOz%T(3uRo(kTK# Հ*lR vaXՎwK_ޝ2r?ˤՒNǕ0>BJ^ՙo^ *Sh<|ImսZgv.L9t.-]]ʈFsrPz>ܥ6H/uہ: m(a:7 =?f[rqR>#-Y{\|UQH%iu % OdF9#g+)}~A_w-|?+Lxc@KI\ʽmF&shg$7:h- Dit53$T6O[>Vz֒kS(Ncһ~*)F֜% ~xA tbִjvo0%PRbֵj(@ E͡͠ogf #=Sv.ھCcJtDN12tvY (գ3A6⥎'G~02+p.`=L z<y3ke˸ ;}Xx2)UFk 4RRXsA(: S(:,ήx4* \uGؐ|?ج{4zp=F#JS|q>)WWXN&hjDsK5) [װR=̌(m2ZZ$#m;NB,dH84<נP`P( װ,l0IyK~׻ӿ@}3uFuWJ`Ja ?~ ƀUϑ|koQc ڈzCzH6o9K篖hdn)(D {b=D'΋/u-2~_D;^H{KX<5RG_t꼻tʺ%32UrP|f[Rw(1e\NX+SR |9PB͐ųk"LBg Mj4l\pp.SQVnEx3 ݘ*uGV.DA~2؆pUpd*6<;M8V$C8X=ڏzO Kh{)ڔ kc.Ơ}CښE%X?yCڝ&ʃ*!G ^f:ڝ^pi`1,^w zڞ[^x릳n<:ڧ`#z`Yڧ4љ0?4(-|/؝Tc%x\NLVL޾м1Md}΃-fHDtiRZ8!jqѾgg(C10l6ܓ݈yA8|z'6@>p5HoJ\>}Pc 1"9oϿ\B&r{F`Y:9]=UqFߓ3tT(ۂ%ݔ.@ 91ۄ;::xaqqBsz2ۡwNhKBkۣ:SW2rۭisUx)M8۶9#t=*\۾$r!Եp bo"u g3l㑋: ᝡ'f1ﴅ (O"$Ğߠa,VWx*zbg{c By:8*}RO 7sksqOemEMkR6r` <&!T 1#qHFڝUHMTX/r?٫׀p'bL# ^mua֙M\< @17L@NܗdumLWLl~ܟ분V =G+{|Gr t6±/Vm|}*l %lUS=b`U T5uEeGcdA:"LW7rFY=J=0- S|C-EVKy7ԸW{2޶AWF dźںI[0}q^C#ڝ?=\dP!FMNtr+?>S Z7-|DmѴ>(j*Mk""8 o#l݆{L$6ҋfҁx?nD^ݕhXlˇ<ܗ$ݲ}yX8Ei"_`ݵ İ|?]<%wfΪVj*R{fՠ7)!vV+a5\0p#at!Lq@kp'3#3Un {7 >ɺ'' 0ˎe8N?5n 1~3zWLkB> V ߅Hz3J O5e=zo/BdW%Ku 4a*`ߏ|ԮKKW@pðސNB@0:xXަvTx{n$(Mrޭr?JBI-I޲umk0/#`}Jl_т͸ "]e=WCͽB| ]@3$rԋ.ȍK / wНJ7yfotd^7_9~D^wE:_X_h$Ik.Y>r&7gt~C~w/jԯWdev yWFR ĖeАLJP(]m.}]O! ܞLxuUܵ `ၕ,\h(]9OW"A߅[ 5%6=gI߈-P rn0͞>(ߢl/+9gW6+L߯u-B$<6߹0gTvYַΥ DžY{ p$$+3\K#'A$iIAJWA)!$HAԡ~7^&XE ݸX O!!r ৑<W04LU:#AjN7yIBuʃz:VPn btUhXT+%nF yNz l:9K隷̛^hH=kGpG =߱!)Cӎ1P8[uȧ 3yszgdlf,ji݁'0pyPى1 xjMجiN2z9OɰdnNŶ҆*G[XCf ocfx?17R@2Xuzd+9qɉ'd}_{$ul+:0M/aD%n-Aǚl~62Ŗ8͇"_:6fjJMѵ0p/T vla :PccἎ $˧2:ʉiD)7j 3xO=Di>j޸vK-Yl#Zˏ/K1?QZWI<ڐ1;z'/Pl1ĂBi6wa(H?n$ݼʘF<aϺNq"}TRQfQ&2/99a}Y^7+ἝDžTnd^ks`.ʳ]\H+p9GI 3^{&5M,Ja |Fjn\aL5H8s)^M3L~z^QmKMba;ȇjJ7ѐC1T:ٯ$u‡aϞUh`}V|%Jdiu: 62y,RuvuH8% &G_sn⮛ʞ 3[֨cNbgȥyDqW ioC,2"-5?/;Ox]䚟getk5`˯LfVk4׻9 Ssf|FZV_QG,1$^qWշKе7UĨRm{̀7r㌮>:DC % Js(ZRsAO0=]:W^1fW$n4bT noMvTo.Eo>'=N6HhwfQfGЋLTL,:e;6Ӫ Z4JÁ!]"Wu -^X$ne!? GuK<0 1m˦VC/S7T DTފY5b!DBtũY%;#VIle[M*K Z"%D ; ^?l]s,&{L@4С.*#j]%)<]Mm#咍!+f@XTL܅4\lK+aV)zCp帡Mj@vz庫+wcKMYtn_5Bcuh]B<&mN.ģAP ˢ̂+6G."}( ڞ]>?γ-ƯB!߻tY*]ɛwY,掴eS:n^xJ K4`Fˇ֜r+f?m( {NnN؉bx$B!KV]_!Ӫ1 =zt .uj#̋Q"^ +K w^7r U&)e,Nh.w*sQ⛲CK)wZS洿iJCH}#h/#jf@ڹI\fiQ%Cp=}24E/4EZz9M a )zeqV@ɌqUAUm|**K?xE&x":z5 El؈{6i'> x@:@bT1u\>_B@\\4M}^_`jŎx >IU3&$d`L1یѹlgg/ ^M]WiJVQ3m&'tDx8` -{;J:.}E&|KDQq&'EdD^7 Ks$盦υmY0w8^wsT$coSUӔE cN7x6>{ bHWzb=L@:voF) R  Af۶԰n[.:,iZw',o)J+eiMةW1n(k_a/nh:4hVYms躄P ^C#ud ӌjYYaZ[%ޮALEJrfFV8+n`.wT#f -WıC<;ھ2_9JxJr&-`_jG7Pn`sd nNIaѴ>aE ymZɶz;@Re(ã=>Ayaѣz8e%{.LkpGS('{PWzk<_hgQ©VmR d2-o:ΔE:T`|=iu#6?;F$zaGd@cdzj_Z}Py\'ӜUUH"y鞤 <"ۗn顨9dwMu#1^GjtЧdha 麃 X~۪h7C:;w}aNzkd@9hI=W u׮h;St2ڸY϶vF5KV~ܹӇ۱Ռxȋ;n ;)j?)s,ϳG7U t[t}Qp= jvi_QNj/A ȵ0D0͑%!|"}\'EKhNpCu]5g0[hU/ư-y^hyxYD6GQ{} 0[#-хFlǍW|Xn= #Q4;QqCkm, f7{ImlUV|}dO 7넼r:68E"q -YCF됧5_kN!2(?2)|$O S맻@ ̩p79>ˉ̋]oYb| a{뵜[V\GH|3”c׏ obԊ2 M.`!U+ |i_b%h i0vb)Oh\B AXum 1A 1,~AMX0޵\ MwهRP3{+.2U32Jc͆rZWLP J2 pVNp5U6cJyO.U:& Sa憞seɇp>4Gx$rJ븕@ĞvlRY9VP,TkSbm7YXtl"4Iy.GCI\AђE= Q7.6aUZԮR"nkdkZm+H:/l7uHʮv1؝v_]N8ƿ펈jj Z&9ӧ͌G/ }jTM0qICAp_\bã|tv^1xJRXl#wE:-?0)TiMd(>H{G$D !혟'Je>‚$"mN38I394-!#RM4 }7;"tPRp)uޣ^8'u~hk]~N]X4~&ń'j΢Cz'G"gzQ5n EXWXFg(^2HYS4 4#XV#Z_ kWX?-NR=)4~6TfxVa>t_!eh"(%fV2OڴW;n󧺩GvgA{2CUz׃I )61"i@>OgYTI&KA&*{0{F3BRQwɪ(n7^.*rR=9\7j[@o~7,)WVa*@rU}]颂g£7A|<8c P Lj5lGj`d Ί ?r Ż?q1X;K%R_‹n'33n8$윥w%8ŴLyʸ賷[7vy/8z :#Ol&!O'7G:8zٺl̓A}esFϢ/-o1 _X:=;?vUG3fqm,.r< AGK ;keۮ1~HM dpiψ3U#fN{ 7ǂV4ק։p ,W^IKY*q}ai7-P*jrzp.qv{cImI/yd+?ClbYT 4+zbbtB`+%vƹYzIRnj~6zkPq!ՂJViJ9%1o+!j|ƝC̺ʿ)ԭyct5LN)HW[P'Ly7&gbȟf'{CNR(G:avGHW)Z7[x: ' \}ثSq psArnn/+Ŷ#r; YhV]ΐ_Ql-_=a=hnN2/'LGѨjE>y]2Ho)"1L( [oɆ2D׮L룢̐Ώ@PR*QPKHr0Z⡀}@P](8WFLL4Ftm<XVҒ,-UA*n&5/^ VHP69h[gߴ57Yy)۔E +^OA»u[0ܷyrGBzRKhdKI'[طzR[^xHrܷ[>/>A@m w|nNi,SESLJ8%\w*EPԳP]j0<, ,ګY͉ԷN86O.p]Vla_x on</ځ#u=_-PÓ6qfg/;iO7 G?K]?݁E hӀ0L4%#qO2Zӳud i x|gT$k.-uӅD޼D`v{JGv7H>.x͖PLpr}!<(b~NryyeءgIRŝgSZ TWOa&H:=LrW2[ BCN2Kpd ;uц=!+Og_2)Q*m_K*:{#x?/ Tj ={^H\r!M6e7n|=됛aFbB_ y˺N @N18:vFY$`wLL\lYleeIJ*)#%qMUT zsE~x\# P7\eUa~)hkjwp@H^f6V("eoq9qt<17U,"$LLTQډfc.>Y1]Nj5Uj().x_??^F  iU`F@9~O4unHo8rEPM &?aF}؇51h,cU)`j4R!dleW}:u/ U?$x~0Xz9Ɂ骰%7X7+KarBG[wp!ض(ŒkM|TFB%D&5 tePqQHՇm3HƦaT;ub2 CTnot~)`&n}LsZspqo;)t!/;G䁁"NߛTr_/!I]wQQǙ$]HL@H X0|Hܑ:b/!q*R| I^>16n LeIL {1NKq!x^kLd) ҌUuq Z9w]+H$@Kf=I9j]╣@T$n'bPk"+:C*DckGs6tR+*K3+wH#.l֡N3Ñ٧,A23J \ ])`\ֵ]a̡)@VЁcx_xE,?|dr5rxnB):ђ*qZ3{4|a4H&2tOγ͇FLl5ps6i)X .Sk=8;ci\+٫zo8.ʛT$ ͸ܚ m'ITńƕXd;Ño/d6rupmWG 8`G$:J?^ ZZ׳!QIKBűbI„/oc{Vˑ9kG֥=Go,oHB9HWg^~ F ٖ]I 1q~y* ZNF4bԹ[yLHMO}գ+jhe>I, 7ޘ@z Pa}hP>RzKe:n4jϬ*",.}lI҅ؤ- \)Oug8?G<>ůhuAGQv"c6,h>ثuRM3eݦEKV +9PGqa7)vșC/}S7M+"-x5_::{{x'׃qc-Zm %q]|Oqp*mt3oxiɂ s|X&1Ţ oJ"ئTRp%*gMRϕm]>G6ǹ%kztX*/o!ǡZg揆ڑr9i#,S`;tK΍ J |e;_vVU}k~+qW㧬ބ^#*tD<ٿj>J_@h9lQ2ִXaΆn8DjF%JY[?9WQbWNއ F ^i*U54.-by $K3G.cœ/?.ѼM[mM q= bHؾʺaQ@$Dk+hl |@N;$3TjY63b} %66$'pfj:!O 9GosڻhpIT<3ӤWg٪y՗w~>9o .GTLޖV>*7uuר3D"qg`1%Q "i(ͯyHϗ犑:0zTsY;y zOpl8ay'.ƨz;_uLU#rt`Pm=@)-0m||r(%IH;c twU.'[K,p&z|qothڏTP&",[ʬPn%|ӭ)d= gݤ~@IUq\#.5F 'qz!2fcvy kK"7 P? &63S^;FlCnTZz̠-,| evjI\)@4גi}lk-gV,kDz4zF7"r;c_pd}St oHK.!{% 3L'C-Wtx|A/8S\qqg̅0>yIoʛQt*%1ܚ>;(bCϜ12rZ[U7L款ﯙz ]_uu=$29E{{!&iT*I𛋀]'ō}#,fK-pdĵy5˔3<_9 TXOs:?hYxra˂B_:E>7H,bQ Xe ǘ!G3\OGB%xRa^3HӈqrU.7mN fxx(nI~Ad\d N[>!ʅv1 #vЋڗmKD YyИuO#uw8yO y\3zG[U{V"M/gEqTfTRcg9M#艖1p]H?c;g6dͶÛbCn6S&< k LD0S7)_gGSp-ϟ R@OQXE˿瘦Rl2ϔ/ FAƫc"s6'>l.XR,+~و,gLbf~X8^+Wy7^l;enz:zp!^,=_!<܈n :4g3s==י/ _i]>3ys?|(A󋈑Z(t9~m #4 M8!@ݔcټ%B,4@4[o@0<])J~9-MFQH5Ci`y#UhEC:i%K=^z>ۓ8O2.* 2y=ɱx\+v':aW'`LӿBD,ɦ R@`ag$ؖE$"c4]Zvn/BЕ;c, = LwFvn=ʳ0az0hy|Rwv87,6䄓SY&jE Zpr.'9QV& $;^Aaګ$c m"$L@!eA|!Cto~c^{>gΟ+IVMTS~u>$gpI;Db &l :vc#3oh3H#pkeyZyT)Bqi 0貕RnJ-H |*ݷ뎜E/4e 02T.b{!6vuUq@ ILAC Kk5waO.7{׌@Ql #y]y^ ,[?-*v#ViXV')Fׇ}<)~[ }mʣ'iȸ \hosUX<6 9RN(MY l/a+萧BYߛ |cU vtESCmewd xY9XɃ:aK/V.\n,AS1i9~QuAb%3DL:T-/~NLu*p@]%%, f!Gs/mXrtfE/5*Qf҆_ g@={Ӥ!/`j62]dkY x!sxdd' ȲgIS֧๓&(EJ2lY`җ Jg\ҚE~]"<>|/#"3x>U&&)l+Ynz0tC[H,Ra:NFal{Q}wvwP[2:0-z:ii^`*1e٪L }=rhw d(z]w%ؓ| Ʌ(4UuHJzZw5AUS.\VpG8%Owo[oV1p/\;hܤ4KYU*`o<w VW!TRb|ڣRkI!Si-\n-t`(\SI(C;:4+SNhQpcz!Jmqi6CT]L;~¦íi$O׳]dL} j5x =NmXhTvԯ !3y0OuH˭_@ &xUhioqH'yB&d _P#[ .? /~h(faj7(ϴ^-[|Yl)q$ye&{56#<+s"g#se|8H~kj򸀒GliEkBJT%[5wC:@ʦ´' ?@lMg{D>jOHJT/`zGmT2ófNaKOO3 IA+&~aQneZON).gPIZх{kū%/H = 6G\'}ޣty/9ݢ:^iƫ"JwKp}ޛ`?u:=@*[A%%;싪& ֢/"v' S6yޗ^#:k~RsVO~u ?T*<_(j8XmB4$i:O΃`x$ !sE,jLHj ٶ:S7qxJ^>=HJi7E dc~V0=!ױ{ $I6] ,^ŽGvۿN~{zOeԊ#ig90W3fJA]6:zdSf`[ಀuRr[(\l ,j%~Z+H(RCjU.>+_D0,$[-$ ŽcsSd7jV;&[W_j5,}{JDW$0wNh ""5fo2+aӘ_xr9GHD<50oؾZKL/5TUQ0u{Wvnx\/>9e4tGdA"  DGr?fE{le0}/o,#Lgn(%4eKiR&{(DNOcA p!$~HcxΜec@;m4h3;S;uU\ =dYV^P2HÃq_핧=Dy.̾ %Y #3;{Xvߺ?1#wJuי4 /c!|CQ.La;28OX)I96/!mb<xp&NL2df] y%i{PIgo=F*)|[gJ\Ͱ}d|{Ls!2qxC 5xt& `,!*\Vzgl#XձMÉL by@',kp7Ki(^2lGw:s_Oo3)#D4yzcecZtqߧ o=}҅n8jlfīCQEͥĀ;GL&1(U,z ^̉-d0-y Q5/\TlN*C0L$&n"@<.T2 u*Y_6Z G lMSBBphW;ܞE`DJ ;$G7Ϳ^׋G*^",tu|ϤI aٻ 3zM[亟u 3}zh4% ^$w54  2$̘Ꮱy=8^kS}C46u!p+HS,wvJ}[ᵢe&auNw]`Jaβ%=Y}},Aߌ L{'ӆ2sZIOLB+O I}[KV"VȲk.(hE$nc!zx 0}x9Kx5F{pY QfhnE[7g!XM #S ŷv\ 5&i.$КT'm0Q$z~Z|d?M?b u:}v׌'t7RGFjKu8uK)gBNћ#^Fw]ң@DeiЬ3rќh;9|V҈Fbo¬%Z.ykSPt7^}J G+w|xE1z#McוxZ'ۧ{L_n6?{H'(oѸpͥzۡ65U%|h{γB aL ~{pJ:^rr?E q{}heX>\o^=o8yJJ颖dpC@Ť]d韌g1%UR{ʾ #;%pW}rk7ufG)L\η5cZFtGuwv* K<O 9~9*ʋaChSe)uß5b2tQǡ4 rї~K0t_4&F\I%՛T͔ kZH%pb@\<Р Xmu?e3 RFDφ> {;xza$y<`L\glޚMwy„ ̧}uSQh1G8bO,6y*BN> \eoҜ]vՊS8Yj4,nW1w0<3QDV%%Ad/K՗PS}iʒZ򦀙N^2-Nfp{'8QB^ԣ8h4XSl;Epy" GKLqI͵vcaY534Xd+Meh֊3$ SR3W;KEl;g'jIeˎ X#8{nLEҥZ>Y WtBb8tn/יeP+pJm<=2*CcS6_+wrPj&MPZ,;C &(TY:↰HJ,xPcU)j;cFQmȤ{" |Uh#,%LlY.PGb/y \ԋ6oWE:D0 |+b!W=+{t$lۤ<Nx ϖ8~iߩ-mϦ?pSS;KQ{N dF0#V$2+g8QR+ C++L6h5=e\({^$NH'ׁ8ڣ,7{E " =z4csyN(,BV;? }T'sRl=j>zzcG$%.3ؚ\Me;^XX ݋ sOd@oіk},b#6µM}H 8 # snn=p jف@lj5i(GDrZ.$Cr9=?|q[q%"oа\ {  y/ 3hŔOS& kft fmc'H8P*,)tht~!_fRSi\P}u8g48Qk&3-20R9F'D}YǺd,QXz r%TF,+{]лw{BWI{b+4GH$kR|@ Y_&k5ɱ}nZd(W&+Q`yrx#.z ++n=&e=}NGa!wx]պOo+l!V!qnHoVPP?H0'@dSalដzFOX 0Ex6 +UQDO<EX LnXrWv[ ^ܖz.V^o}K? SLy@~)lkp2.@BdS?Y M{y*wʼ0n #{*6wCP6iCGz}P[ ؃*+3H&I#{T4]g薔kp)&u'M&Uoߗ>|9H%EG݂8Z5.~xu+qqCR"N|[:PF D5O*>U۷l78s~բn -@O)ЄJ/X19"TrPΰx4F@-A5ļ*Pn kjR3R&~PK}d x^JPdC1$&>p+-ΰ cȈ+j ^xW%'3K'ߟǸ=I gfB;I)KuV@kKi}?|4E7ʎ^FC e>XdVQҨVPp=M[֡FP&CȄlCAG|ȽCk}V|ض91=\윃#@YkaHH Z,wLK6~BM7#S1A*0<#e0ZzVSĞk֡6B[%p_Œ'< ދ1GEM7ða{zHlS0B!w9jvwۥs5L*tcuC__ ^b?` *f-쉓Im'ǧPqfllɏhGx{/ ɭcOw W5#)}SN9,pnڡ޶i[xr/ fYt m"!S5{>X@ZuN|ȍ^rS"Aeզg\0p;aRӢ')v KBnf A~l:^KpD j҇#n& 8r7A:nYW&6xKR/#ޘ7ouZD.몃^W<8^Wj+DHOvKsR#\|(F-ݞˤyʌLB ק W!W2 }3B'hcd r1OMYMG!fe+0{; )3 C;-mahSah[x12> վj4)n.pn lAvb^8[*+Fij"V7Yˮ9lP)lL0A)UB!Exv~߾( Jz>_w Zvypvhۯ{cIZo8| ]xkP(^6K$SU=> Gͨ@IAʳ`$#S4#vZ[3P84ȽƕɈ(a.-LmVԔE"rO+qnCv&vs!ec4V^,&UIh }aP4|i+I@ZscE~se6@dx)Xtqk Uq@G4 O8x2iV'l|-!訲 0gJ7Ur6#_G+w?׎_ee]4"I¼UUF*9u ke<އ3#10)IrAYA3]iCjyvd[k0S.ӡGMbj]6y`/r?6hfc}`{w wS&՚9G)&` œ/wehnkY_آ@rienn7 z9snw6B{.FE,E`wZ ք(b*O7vbeo ,{}&poakZZMXVLļցǩv* ycTv9VWOO#AjM:&7o h@攵J<n ;| Yw;;By7Zg0xV~ a2LאI K߈ *cePQSvî6&:)88DB ]CbԻNᓚ6#lzI/9LB,/꘹N !'>@,|1UR,~nЬkL'[p/4hGVL'Pt]g<P%m\DKiʩ1 &$ zBcx/N> œYt`SlҾ\T VMJPO-)UO\ {k_qFzOt?u9櫫\z$ EaXXEZgT\-TmKd־\: C:OVۯ@Hv<Shy_ܴXd{PM B@f!?05n|gp wK<ehkuq́k]w_1`6n!iZ P#$$rxVDB4˟{D:Դ)}sqIKc^j,=?nfX;VŒl9C:6NsCfs*r[E$J+fuǓ21 r%Gm\9mQ[Z,]B](dDj}AC)GOfz$3?50.45CC\ۭ}YwnPI jolݝQ0qwZRDД/ ߝ\rAr9svrq\7 rjzliց¨a?B5إ.s7'Trqhs$ Z u<Q2{+eKX0o1'װ-lr:Cl[c.[b'8҉5LɬN\Nr0gtͺi~s!fK MPMb1T>L*;$t?:AH׻Z*{;;2A} y D+ĩ8y3s ZT 7L)TWWQة·u+cۺޜAca,'>;ܽrQ;xM9z`ZAVjGl;kV--Y "#> k5|O̴Hzb '[Hp"v^@61Cb?팀']!EZꕾ%Ʃ.5!87OlU^=B۰>nd&/ i-\XJ=54AנOF@_Kaw9UEQ;k;g-{8F1}!"2Pّ:,9e޴$1X(V-Pߑ~aR)&9]tuYҁW ;pv@:E|GJ/K:dY5uH hG>4MO%hV CUtTHHrjW@ǢmVG;pbR:EfRzw2+1L">ǎ[ b]iW ɑU;?kr-\a~:K$ ҷQƊBװ^4 2)hK|NTzY]BO CKA7[^6FP> 2[o!i{ݱ2#5ͯz>L F@{wٟXlSX;$$<=~}j-;o1[׵aVd [[<%MիPJI#C Ins7鬥[>q`L\KI%C:4n!āmk:7{6Nw,OAb ڽ s~$cPIYzw%M_@ wr;r.&93fW5me>_ä%7A;S*ͦԻNU|* 8ֳk .^ ?bVxѩnܚUt {|^QU2n(2>鎨1+f-;KpVf"Gշ~BI\]  HzGB 1I3Mk5ȟFse!+i9ft2i% w*OEhH+(ViC*d ľ6 ^Z}ڰD, w0a *R0(Zăw3dD@j6|;oIFώ=EŽi8&uX(bK z.r.)lt)81]X_]3\ͪ_6l%ly\:BQ3G Y0UlL1+dž.%X#SS@0l}ϜԹA3zj i'3QϕF[$85!.t7(L6C̭.*:Qp&:_nf zĎ]Ҝf7`#5w1E{VдTmcں&pEu469f2%G8ڝ/OޚUBOY ٌ1"gHߒAx&&_,8e͗)3[]8 chm).n|XT, IƗ" %0ۣ#*W|zUEsOtQlx\aUaSN zVMy vnErɨ<1,jZۚb^ =_w8H?fe }A9gXqcTRQq } @-ĥmk}"˛] |` /]e^s^,6BpW߬4vg'K4I#>oe=WwSeP;PuW` - M .?#zhZoo#k )oг ţhr$AxNٖ, È䭮ɰ"N`17./( =+-ŧԌ|bJ$~ӿupf%,ocf*%c 2O/{V<}.~?P0p;Z 9͙- {lا@,1hum{" >Z_[ސx.—7IM.J"c4mbMxK3uxg{Ai=ŸiI)+'k$ =Ic\՞'dl{`wz(R+|7̱bPUe +GMdlDQFkN1EfZNCJ#n9EmFj_cKB' fHU סeNxt:FM23RAൾo&-DXh!T.ݕϼ*}G O2܂]ꧫdPcUi?HgTJ .X*)α)ӣkBR -J6jgY~7]O\uI}V9.XGl"Ƨ0µVK|B8/9&*t@hcwj"+wC~»/=ؕn C=%?2'vލ;U? : ssolj&yd+ՓG9W!$\ &G?IQ/ɖ38>jl1, v0;F|^ &P"^#M!󇲡/G g=T.lmRM˴4dSHv~%*ENN,I,ZYˠ[/(Bƅ=yc;jVEWqM Aɭp4YXZ?*;ʹ-' vÇN崋l4v1]!3drK=S^2~ <.}I=Ys; MXJA7\MNYƜ-wuy+ݸF,a#Q3#M2"Evd>3yCu_vΙ$A"3hqBUm'EvXl1VRRJm Vt̩btY ɫk]G*qAGM=I}-֝d_K5DBu*zkȮW+ITlY7IwC}Q1LIs%q4VPJ:# `"ȓ xJ#,W~v~nѱ)Qbʧꕼ 8NSfz@&WioQ{&njfyԘoiG 3eY#'ٴ;B:s#޲Y:Zg9 K%یeK 1fm"NZXD* .i!bm;tшaRo譳k`gED!r@jkUgCT頂 =VTzyVl2fUf݈>߮%z{4^s/g}ųa]p gR?X&\XH ־U윻23)kF#֬>ۄ|"/M^ZfzZǙTfm ˷wo<'߂)%mnhxxnU/C2it-+n̍Ar#ȸ%Āb@.Gij7KB-br'TjCb32Vj x̀oT?:aㅢpGB)qRaE҂ԄcTV?+&1y~b x\jN;dmo0B'JnZI L%@骚G$y>,JSɧto7%Ǎ*QF芛eva@_!z5ϕ~^GES΂-{C%Qヮ¥l<:&>DW6m0TH?^阙=p_8ʭ_:aN[PN6#w/Hu נǐ˄'6d_ 𼽎m '\íA/ `iO3[ԗG> M~"(LOO^ ^KPeC4A,"};o>҆W[2wBrmkڜ܆vRUSRwדbG dd\_4f)ąn1M1qY"Vo;ȢcEM9V,IeV{1raE%AyMib\fҬL{i)=45S'v68aB%K,6l*wGpߎ]WkzPskOt)Yl^YY+_. -d1x0s#)&jZLB"TEX[&_S'B3=34URyG9J4L[STQ&\)THϮEaYI:l!E{')&R.A"eBؕ~~R& )g&3V+嚖qP=@̢ .ū"$FCbw# 6{G!ne]bϦ tMm Ҽzq0l˴U˪S@}g~m~,rÕYH@y!0No<(9Q $Rʎ`H1dҧ+bm1ux #uGKbqcR\J{zۙN7ֻߙD^fCB7ZJ\Ӎ #=N!HusKfH˞tm eh)oY'JH:LX sDϓ:eKѐmw=JP/ҤtqOA 1#rӱE[GjvQqa<.^[Q4ˢztNnOp'70(z 2yvܢ7m@7On{k xwCK{#a:\zuL?W6Ȟ:'Eo(3ʙ4k G`+2x7dJ\!qt5S c_ ggoQ7TJrix|2EϜK +FXΣo&sFKv蝢bбU4O& EM?}Npb2pmݡϐ=ˮ[}҂xproQ+pHsI#E D)Awy0l:{.N&J]om;N./52fKgSJYaWȍK5IrQCh?F>\$:^ U/oTs2S l 9UEb?C,.(k>aT{mR8fnP<19rUF[Z_Bp7L2q 6y+1uK5yG]c40c<,TGbc$ǵ{1΅X: Wq;~:YVC@mi^''n0 4?t0YJ XYidWx`~)x ^((Htnv)/E 2ߊyAnJa=5@QLoz[l[2xGY؏`acjx&%mn'(HU#Wf,>Y4DŽq hlny5'gru -H[}nz/ 憓`|5Ey88—3z7ǍS:nS,w֦/Evfp>4EiܹY*UM*+p&>YXvzԹ23~:M l.xV!tnLDnH}L`:97\xtoV%3fVl ׳?6zd޳yu_PShW j@r`K_fi=,Xݧ`ceYp+81P"rڞ7BۉtS5U*]s)ټD.Qؼ+2\ۦ"xwiJt_^/. ۋv/*vx&{Sǥ#]XnTU9(訏 PFF(NR?F]˥эDgf1)ZC 6+hSdR6ԧOɀ 2 ZqQ ёXr’@ ?D&C6F*>͞9 MNBYc=TZ )΢D 9_G3BD!!M29'bY"ÝS?NH$\4&?iӑ/؋X93 |ʖغgxB+cPlKcXNW.(*֦ z`P4#&O5>rAOlc*V[%:]HN%D }z=#E#*pQ6:irap+^6驷ܤQ8yz0JPxrw&gri(t!y + =`+J5B\:2wa݇2x@!'Ľ%9X+%r,|Q2 4rF5ռ)ܗ38t Ia*g>-#,|^Cvϯr8"?NFegt5ib )?^ ELG"tS>7-Є/SCl FR1=U^ڡ*ۋc,u {Q(Բ=z)m649P$ ɢ j?vj_ϳ ]`h}&#~7]~=F'&Pn! #J4/[S C/ Yx/붻 0b7D*oG3٥ *<ћV/29Xp/ۜL~9G`=z[9?Cdp5>8gsg= =NP@[I/TZQR=4gZd'{qJpbC4`R.MEhY’]m\3?GܶC] ĕ+梕ߩn _96F?6=K| miL' 4>; NCfs 0a("zMz898#Qtkz=;qj;w)ۛ kx#T9 zz56$)k4Ohi#Z ,<r?wy;DiIcFl;r3z(!Ijcioqt( 5j-8%T8F57 zA;b_77> Pߎ8{i4d;;vkttc:=(rfBsz'z;|9;Whz f$ #=WLjq.Y$R]7]IKGk3z&'zq~X89$ rmt%;i !z rB#ם;8:OL71;V; L _!|$3 ?rbO7>lE9LOz(nzDb$3::?rHij%FrRF@'zpu!;rh;2-Bz;Y "z%qi:+ӽtq?Q/@dUjwr܅5R7PRrhf0b[(;yw7Mz3hz;ύ:sU2rƖqid)k"߼x1SiE{.z!1.vZ!$pt8 /;=u/"WTuiryZS-t_>9-z2N%i5 zrt\"W#~_z ti={@k&2tw5iCtu!br;tr8K71 ~R/R(iBrqo:?LrgsΟMi#-'9 t*!3+t(/: f!:(';1;Wq9n$3|p;5;i=Li\ !n/8:Tix76D$uKb9eO;Ǟ5u&_#"8[zO8zAl;6k+>N~zar;mz+Rf> ;J@rlui( 9t-l_ 7[ !rթs {+^2sL\1';T`Sc#;o(\j "p 0kC(@i:L8I(`rڎibs%zNHQzCE rtjs:<*ZJiE, )rc-+`3{Mxj8#z$P!uB(t=wFfGs;>,z j8.~_.Y^eyr4y)Ϗ%f_i ;Fɘ6Ni@A,irz {?"MiBxW@ i;72Ai' ;·r:iC!5S;̡&\iu' rH!jz1+(;Wz~t$$}(i!CiR ;˻&֞qk&";Si<\8&&Q'!6[;u8];z02!h;#l>0t7#*zvqtzA>z~8A}isӶ' 9t;Ҕ%!ݾk;r='iD$8/ԫ7…uzڰiq_#/sz'y(Kd0;Oy;?;)yz7G%or"v--&Lkrzv; t@:q |Uk;LKAizt>>jIΑԾ"X8@#l{*iz" F$ZT@h)a 3/!!kr;!tt anޞ$-rz+w3'^;*nCc;Dt:=PZz=czH-D[jg;ȶ3tiL;Ut0rӯ3E- y$$s?;!%[&CRp!3%"Xef;;dہr@;;‚#ZX7f6e<j/?Tw7\"K[N;+k_r o<#+ttO z}#/Z>#;,iR;n5rl<p*;4;k326GyiiOt"09rg;k'4!9Сi:Z;z~cdXXE~+rfij ri0X<r%p+"$P`3r`a92c"^:'i>2#qeyG;߅v9:|zz 8FW!>9$#0w;-l?$+z=B6zMp{N-:;BCG1%N27]OS4r۬&t: <!;>@[#LSzAz)q=ijlrǷU}D;ifkpi i:qtfA{ oQeN?zB{F);Ɩ9-'@$Gt@%etwt9iEi?i$tVGq%;GGi_yl$*6:tMr?zG3jQr;y;@ a:Pr$f8&zFO!7P0rk"Dz*kk3;ԟt!k;@%>6PUz,q;k.7]:<3= bs81^9iM$Kz2fuz5rg9E50ri-7xvhj $4rat2#l.C#%;gZrj<ף*r 5arz*# |j9z9 k+i&!ZWv'#zHtRz'_zkW?5z;7iurfiF-z:|Oi%Am*br;,7@z z;iz/i<Y;с(?7rЛr&:{rk&kz~hG.SnY$M6Gt80 5+9Π̺5iT4ts?fqs@|N:? %!'rk&k*zw!fj¡(HOre$2prkU5i[`w?;L'^iJy6=nsiIraJ$s+6KsS"u7J7e?Nhz%Si5l48;WPz !4Nz-z!@&q;2 9jTv  irk:t ;ir;kS U;;;s0ʅI;5z@)3x"$ݏ};m#z4y68N:I:iOS;U8 >ij3r9͔+l"y;nrҶ: ;{?z&rhzgi;! zdrk5:#YM@!y9ڒ?* /7Riz&i%7[/L=3To%~#zN;Br8FG5r7U@"^oAzmzM z)<zO 8.Cr'Kz@$1+;`rC4$te'[Y`|re+k&JHnRJ:;$k@!}t%}8c6or[fak0z2|;,NR?k6 ;<t&$z;~t9VxAr{[HzG9u?2<U91;zM/29e;\a]z!qZz*rٱi=%;ڿhLf#p;i2 #E#zH8KW{#tOpri7Odrk06k/mi?|;)C z;rb"BqoiizG4/r]z'08zIf*@0Lei5-cz& xVi  os4|Oa~$ݩi k!-rfm"I"#^r&i&;!Co.lXi{ it)_?|rD$3&ri99@sitB&4I*'"=Rprx؞1<!"r58qtvt+Ûir},V!:z<#- ;%#)-;rt&+R/: 8j642>r>3z~; o;U;"rԪz2 z.Y$%=]w4%2_"g9Q|h;;{ }V75V/Krcc+ t/7Ý;>?K;;8&u7f\5{k@#{q?Pf"/ hy2i;@{>qj{r ;CX`i=EiiLRU4J<"trm#qGG#RVlBe/?;ns¹8;ň;1;\hv;r{:ÐGM;068L-%z!0$Vl3OaUt(;;94FqJ)yjVr,q--n q^A9s9r؏z:rу@ jz8iE|z *}oB;DPZi:d47v$Prŷr1?1vi/m%qrUjH(a#9a$Qk%<a)I4P[6.z#;;&)0fm7?93y6 iX/Is^;;Pe#8zYs;#0W"Mr;GsrcS@ʊrF%y#;sr@t7(z gn#_u;8;;Z2zCP t tr;:!$8h;!H`iQPtQ >OX8T5%dDֿLp3 !@aC`0rî$_ZK}Ez)"]y$|Z?.k+k/4#?z/&Hi;3+8js~t.r`hO*i}=9*3;R*Nip rrSrj#^j~i:-#-z@"Ti%iVy4R7#[zNiS[j#<:m76)T3SK@i"0MrcW}i0)a,ueg:#@zjv8-i:ii" 7V9ByiA\&trsvr2irb`z$izA7eq_'@#w::};I!arj)I >TpmTX" M_!K*im :t0T#z9Hzz4_.@%u7e9Bz\" hc9e;s+aGZJi; i}sr8KZ$,-9e;rݽ"j"`'zHHz(t:"7iKuCq%Ϣt!rk&#zr^5sP>#s??zDk)*Ttb-ӭirTsJ:&`qt##3kX)C!S7giH;ÛsvS2Ɵ!~#AZtT8b!1D)r?u.hii|i@S,KbS{ xKdr%vq|k/1\**zw;x8M #/i0%@irc.kg$ RyFrr<La:PY$06*k/7r@#Y%epQ.Z&˩^t@(:&Ctk.Wz6rtz7s(1ir-ҫz!mzL9@:3,@!i4z})m=8h>68b(s;zW7\b2?Sh|J--Si?rOk0NrA4I3j8;W!K?i=hr=V8@$^7Fwt*s@[{]</r7O}$)u?M TqrrFA:6;ѯFi+5;0BXzqJ/o!iE";)Y<6"8.zr=''bj"vS:a@K< > r@"ؖ;;^iIb3!\-Az'<iwru!:;= b|@q0G4_y@UrhQoqF';)i"4iju  i?i# ;.z&cjlZ8 r:Wgr<#"k0$1!s:<3rzLaslrDP1u8 zArnK; {Zi(zFki#zLr*?;ӊ$)t,q/&y*75w8RrNrbQ{ M;-R.;Fy$zEp!G6#]Z1_:;v j|ugra:Ҵt&lyIA^+#p/xt$#+k&['|7u+6jvl`k/\)W%kRjsz4x;HdV;0<!/q+<5Q7X{:I;M&9<snwq R!Bz7&; 3 !! $rc[zZz7vphr9((0{@zC 8c[;Vrk1"7;,<?XjZI0}0iWz3.2<M(F;js7$?~N @8ݜ;wMT"HPH$grjm4jKk&9Qcrz3<:͍?SM;rh7h(ocBrbzi9Kre ki<&;;މ@ez/'eozRi?Ql`u04|75jR0z0ewm/K>OH#7t?8 H:iq97d;k%R$2r8L;#kB@liq d?7#1id? %A3i"/r. Bd_c<am YC9L;V77R=DF$$ }?vrم% 3"rY räz;e;uz;BHt4i ;5ur9d;;k"7ek>9@rz/riHOi"7rpt$?'..t"H$gõk%8d9"t6f$:A=~~z.e<Mb1z0//n<5$bsRrf2!r*i;Cs)y"8 J4?z$9k;s 38GJzL4RY;!t$+! 9#@ҞlZt!z=57krP, ho9q*p6+r 8s45fz+z+yP-a{TB=z+F&!mi~}(7:\+;z{nracNh9z!Fi  r425v2;Ht-%zr*'k.cx: `it T@&(t'Zd7Q0)j<IYj;{ -*Sr&zfZcyri&/iQR{%dG!OR& zGyx=t"#]t%zBnpI 8M$F{ ;Y8T;ɜi@@juiU+Ϟi Lz^L)v*(XzrgGrq;)=uizH73/xiz@*#z5xiBlvkzc;;z$K!TZ:bz'*gz1i!ȫ\zhôir&8:Aq$d$Q'rЇ"qjo,BK;l;|:eHvk5rvr4sjz(;^i22v,! L,tcdQrnjyh9f@$_izW5b=.j4"j:QzK!׌'s7$ܻC0"w"!k.mhPr=z/r@=h4irT/3 Cz>e~btjk'G,sg.8SHriNz(r:coXm3'!k.Yz"biA19$: 8$ y zj $%:#]4 { i]|AUyi  Z<.r:6\::Vz.19t+ x h;eg.k+ ;D)iU'7zI4fk.+i .s!t{ c;@^c9lI[ 7r9r 1"Hv|7|5&yB\Lu?*[/dph-5bz;zZzzOc@. =#/s9 z7ga"?~!UiCoPL?]::&4k.zsjk+F|;z?Fz { nj?xB`= ";sѤrd9Njk4 _s,t9Q>kt7oYg0!K)V`7o"H(;e0};;2[w/i3IKrlH"Ar@=]"@@'>z'11[$BCήz.$"@<!i7kbV*3t&:8G.u$lf<"t+9o=rM/'d)z?4^&xBi7Sb$Zq;>5b-rLi_0^kgU}{)ĸz^;z;)5+ z> E/j?[;C/q  rgqtr_<7jzjr?i Sc`s4;{.;&^-GWt4"@&Gz(A^&". r$u!n<]ivFrgreeL3|¹k$n@Ok4!+ 9)<rsЊi#"hIzX,z)2cIf4@z <;k=('zzU8;D 8_ $r; &1 k-9z i88L ;:ARri|F?`z.^;rZ uzDirG.y(/v76@A:Utk h7Ƽ, sk.B4ɩ-!tpI#;{Z_^"8/jr;;;BOWQ0itk%t#r~r5`.;S;';$;ArA9")$t.i]9jj@";ͻiBLs-n"r#:esk#+;:s!GirŊ3 z$|]8h9x-tb8yz9sV6=k55;#2Wvi=yb?U@~;'"K-brh9LzBr?,;QzF3 [r$l$;rc{/;erk40.+r=*;*icqDz9z9s#giz>rdIV@d/xea7z,SMOx%rpҒB&+kr yl;st?ݍi.iA k'i"jX! !.YzLrȔ3KXrlh5I t%t1'a`z1 jnq !_@#A!u@&d/2}?t'"q-HX4!׵7d^9L z9@s*2 !ڼlt r4"Kyy-vy#1z<Ti};:ht#ti=l@ ~$nzH?z%hkrػ,7Pn>:+#5j5$+r<C&Hz))k6p$ a;y|oi;l/;~rfzi9/6jrtzH?38&M;f2risMsq2j"ji?!?~Trh7i8.7ws?e{i;4)?at Zru0#r`?΄̻E&:Mѥsiyk_1]z(͚*{Jr^nH zBV`Px;sw\rkBz8&t+:rd4s;Q0qqQk'W@0;yi @ti>gv7Y `j_fiJaJ(K09f;(r "0krd 4MDt!._;!-ʋgq`i<x<u{y{2;$79z8R[Kjr@$j0i!8 /-88dgLX>[{PIzy8&;c39 : z>!D4 hk5o<jz#iz)U"3y$=Yz@9_Gs{?I <gx rf8TNBtk8(i;M;KzO0oi@"9r!ljH<L7v;y@z;z.iA2;<ڷ.xi'u9v1zss@#j8S$C2sS?Q*:j9__v/wE@ d$|fq H}"@g1R@Qt-0™k"X2'6Gsz ir$s,:T1\J!=yd[jLrK@9_yA?o 9,<0trH$Pk."t.fU$z1zF~(ž;}ƛ-B0bzGck'z}7UkZiD|;9_`;i'zCv;޶"Dk&tzO 9Mmc#Lz/%#2;A#3 Ir#p!QUt#Ii@'1a&u@;HqMrȿ0/w"}#;S;t`8& hair2|(?j>`a1#z zidG7&gr5;ުH;7.CoNi!ti!$R7z"2&w" 7rbki5#\gw i#)-҇z6zn:&z&6/3Kz/A!WsH@RXE!ser$tsm6jz''s$jWR4Fh;ojÓ`r;8dP4lQtmq3Jkz5}2@r)#6!3 @9$RiMa$,Kkt!Bk+45rz 2-cr3-eMWH:z7Z;*z0w!Xr<&@?y\πf@{Ci=_1zl9Sx(h*"\9?i~pB!;.Zp>ks;xzMdp< 1n`0 j>Xs^}K:"gw<X;*TzHic#nj-2BCzer!t::8<t,;t"k6)iV']:;j/3iumzkK;ؒ?j)zHL;´k.jK?_x;[l#1Bz+9_iJ*"zfiF0i;Ir31Ġqc c ; )^hiB9HDs;J`>t#z<j ;IiiidaNM+!Mi$;.qi~[qh*0b;np3h!z;;< 8r@"yt,8iBBj=jrՂ{}7ri ’r[)]0Fuj8e#Iɨ6uq"1ӵ9Mejabberd-2.1.11/.git/objects/c9/0000775000000000000000000000000012240452476013035 5ustar ejabberd-2.1.11/.git/objects/c9/e4b7b5978067214bf61ba381d1a4c3ab7d18220000664000000000000000000000044612240230175020067 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+Oy'oVwݿ/l PH+)LbPkŒON"}HIMLcP`ojّnms ^/Ҽ_q^ "Z[ZpZ}Ŏ}'1[LMU[ QR\̰/W|o*]̰Oi&D$??᣺[_j+Y.0L7]uejabberd-2.1.11/.git/objects/3e/0000775000000000000000000000000012240452476013031 5ustar ejabberd-2.1.11/.git/objects/3e/818d45bc5b91304d8bb5a61a4771aaf38d0d790000664000000000000000000000044512240230175020153 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1p1VR~wkYd9 eٞ=.MwfljEbnANj1i5;l16UEo.DIqQ2V_ 7Z]߁;o %9 ݒR[јraz1ssejabberd-2.1.11/.git/objects/cc/0000775000000000000000000000000012240452476013107 5ustar ejabberd-2.1.11/.git/objects/cc/334c6c3d137714cc1435bceb3339ff1fd98ac30000664000000000000000000003433412240230175020312 0ustar xvױ,{9ɒE8&fy=ϯǣ,.E~f*.҅'t]dfG"?M߿oƤ:Fq&;g%gٴ6/t1Q>ef.Nϖ|^doqN`|,G|<|j/\Mi;}/?&)̒O>~ b9yY|fszӒqi,#{6fTd =97Njo՚|.y?^\fP>q[lV{nuYeߖU|*4_$4[7\LTz93g+-gcβdz1`l ,`/A_g&s[Z$/R|2_Er=NW^olrh{>9ӷo߾``QbQ$lV{,XrD +aۍ_׃tF=6ռsoAz$9P/ؓr>#ٹJۺ$⯧WUW}?D9h6ewg/%oq"pVo`P?RSD!9Io$96Vo+[OId" v+֒ɮkaw|șƯ n:\6fS;~p-@㥌}6ϱ݃! ]/# *R#6[8)/K.R ^`Kr.'2??xo&f4-}muwn?D 219 To>|y5K6ʮZqa~On,Άn"'~=z<(,Tk#5ϊ| 9uv$4k5QN;7o Zy;( xkLمc<ٓ_~&t^FP֯ @|OWf".)3!33Y/ HmQD5@,Ig@Y?{^kv1~2W:ެx~Xo=c~"7yBc2vt?',I5 _,(sL6(*];Gk\ xvrth߫ťV<֮*yKJ!dC<&yK$,QT0{8y  X.z-^babr6fI$]^q>HL)a=~|r vQ}ݹ!BsDj oK9b->d@&xf.N P,ì(ΗN_nܻbhӔwk:w޽F ly/QR .榧榧63L8 '._foq]\Lѭp[ae.YmO&5,kV!Uz>p{ф n#$MUEGQ8ݰDY-Vf:h: O-7 mN0k p~8=SALg굈fsK$z1YmZ~v8 [{HEc7]4V>ja$Kx3htϛZQL|e:N)ɺ>M\O]OOH6쐥/xNtX\/~|~8N<8LqGB.oqZ 㽢'x:+(|qn;k촛R͆f-/ ;7a;te!0ZD9EEy̳L`n"MK+=(( _.X<y^|'3ĆIP7ȝYEOX?s g\7ל/DZHxka<`%8t1^ԙ~=]i8Y{ĐWBxИ3HRIS\ oI{w|B x`*- j:`)P^SYh]H-QBpD^Fy `!*=ߒQVW|z3O0"f.!NirblO;!U}Pkg*iK_N\ v]k,-ٱT.8ϰ@o|_hCpk`0P &q.d.~;Q)lMNUXZ~+.o4~8 ?A?זXL$HB 奱* ǔYC}%Ôk;FQ[>m0!E*m>UpdSCoZq!ADwVQ5kUųr+e6F/!IcbA?Huq ^D $yaV&asG9>RBN9\`7zSE,r-!)6C] -;.5Ձ$["AA#YZP#kY!IiN*39諚{>\~S6YBm<=}|V{ "c9O%`pxQ!O%=aQ{>goo${-Zq,BoG]0-ɢq&V:;\0tm񪖷oERnPƥ\sKJj'mJJ &dx%DM**Gf=Sa[{aJ$6 k;7!.)1+ޖ0mȳY PvL'#F{>@lO+0yl?F=5ۼ'FaXdw0 00ey+oO4Oy s 5!Xr_幂t2sx.MFS~ O&E+pSW\'2l_EѲقAFY{bHR|`xWW}#|U=ߛ<ӛώO^֏ M}|K JͯF !rhԡb,,>HpUV5i(1ȗ??dDY547GGgD :%V hRwǶ b:*/Z)K^k %Hζ,N.K9O^#@W`\WC9֬VdBM'JH)XrI-(\0Q+_VxMb)t@AZ,vXX~K6kt0i=7OY4˲By@bLce|4wN̎[y`'p>r!8S=7@2ZX$79߾N=Fk~GY 2c]ozުr8v:շ*Ϊ%bU`A$X 'V3~ox7N"晻wFWdg9q&:_Cj~1*Gcb/AtF nl’VW?[,SVmq Em#-+̡p1XEU1Iֲ;b^/Tx=^b{0t]Jer䦖sԦFC-ZM@ˢ_l9wV SM}2-xcUk5 xf~fob,k{R5)~Q1h~ Udx4DVzN}۪0ŝM b6g|5kv(yA@Qc%BqOry8s<~VuFu=1ܡlyzQ}불a>613h1b %|L8Q T"EE37pD$&`r\CwWƾsgU\~ⱬ<6]K㴁xr|%#ၼC਽Ҡ**$=LBɗŅk}!=AC֊Fj*7UoPc;H|o~ 5놹apȺ-EJST@[+A)+GXwpZ@2QQRj\=Ԍb1vR7ϕP}zacKyV(Qzj>y#h- RX 6X`va}&SJlmZ~&x{ N=N-A9?UCnO@V[lv\IwRwu5*Ƙlh~ eVk۬y q5d7k?@0UØM7ho_YNju uJB{_n\iAN]QĴuXQ4'T sվg&gTTk^jlJiyS%iC0Cd$yv@0.0)k幨k"DXB%K#KQGn :GD{!g .QySQ? ~ ”PN7ӥ:[%Oc|edI`TTUXJsrO^4֝uVCSP"y:)F: ؠ2ZQRa*9G媴8Fl"#3QQMNH{],HU}[4s.]n3Tߨ ?xhv6RP'pT:o^KH?3w i a^3Se0ķ` BQMp^ f9 wΧ)WXaUe֪ 0UBb+{~>QEټ*3 El)5ӉlU@FyڏxnM<5^̝.$r^|+hνJ ޸˜뱚a&@9UMO nB^3}t 0a(r )2nNSj\E.̪6;1뼓 27I$:{R˪le]Y\3b/v- P?S{=ugFFŇ)ݯ:;x뭡EkGrP)KIj!g?X1WkEq%-/dz(o~ ض>$\XYkoЅ$2[X2"bh1堼O<9U5ɧ ͷej4_~,yn{w/MxʗIέc*"&=֞yWxY1/U=vbEƧ8mNџ?^ Riq73Щ~aXJSɔөӫEV~͵bIo1uhpEoʉ+'Ki#X0"EP(+&L`|ewZx^]5Q%X]O be ;u7N TQ _fwkV٠;iҭɹhABP<Le![1eT2>%)!m(D)?+]yuXS|q9I`ݖ赛IрPtQK}dd+`P>6*Q_Uj7S|Pu^9;*%uzhj1Nњ\5U!K/ZG- vZh'cJ+9aA16[EJAͪfMDXi'ڡv$TfXLZ"]9b`lwevt1pD.[W@HS/$|2fb V?3GM#Jۻ &a[}B ᖯ Em1L%,ҵN- mry SX@&4AQLjx'ENb ը}P6u|ln!grJwI1ʄ*kVCkg[A¥x#zoefY@z{rŶE9+6Xdވ٭*gA0:݂c ,s[н}HlLEY C qYㄛu층Њ㓓ȹj %ol΢&tK@W܆Т`'D8g,#q_^@++*Nib4Ok6j׎cڰfP5RQQY^Sf0DNbL 78Pܘv#hy֑mJbVFEƿ͆\1;QtXMW-WٔbLk<;Jγa;t)sGk{t%Vge,pU$&Ou6Ӳ,:iOLY`RjZ޶.KaYWs%l[ۅ|Xm3 x~`s]6 ' *d _hkM9KʀV8X 4m+@uW?'Ӧ.fqV:W5TiYVvpa0}Z:ZR|,"8*j\jJw2>LB'RQN,]""ͥ{rأ(j=|ZR$^Ze:H~ %TL|];$uBrtGo5lVQ9*& :p]ZcA㔏F =; siA~A~ KEm:g;YvgoBrȚJT`=ahDQqF:7d_GDv\} 6de.@7'ÖEбj6+'e0$zypYt;p ҾJO:R߶1} 0="u}'<á$0!g}T@^4DŽ R6-iqMC!Esg@I2^-`yRdYe(:2XjMT+/R>̈́BZ)-W( b%nK!ɞ1b(q} 8(Oo:嫓>_K ͊UTU\/T0M3 C;D !v+΃&9$sb)U ik(ZКF790c8Tb^KYV^EWl/!sa  uM Z-Xja =}6U*"` Qݔs/;gŲrѭ(kĜ[w(G` W"tA["A'?لb/k r!*+tb%x 4^nJo4$>,x^ QB,LⰊUw$?j-x48n>ܒTimJ4'XXR4c_mx5LJvGַ?>];n4IګR#t$k-J/q&p"r"򦽽~(P VwC. J܆⑸R6nv|_hqԵ^9;6f("B !%)Dؕ38s ?!"rY}/z{XMYj̍(wVA:AZ KN>yf(qn6*q֡ma.nxҏn? [}6L L `U䃬L`ǘ[]NCXp4Ƴ9㗱WդBjaE1! H'(2.R= &9Q.٪ϭҊ'_ia /c Z~C\h)~9IY?]]E'*@eA8~[ MW -={ Dyѥ:>?üًWeڤܕN/I,uuwڻ 9׍%/vy,rXdP!ʌOlXZnt%eAPys-K|3]W=*`s۞{Py}gD0BA n"B:=%[lQl%"X+q'ݠ9JR|awMKY:>hP| _<,f\N͋dq34YjѤ@K𙭳gJHnpɌ؝ ї MrebUCPpY<ʪX?DbA6Z3R8U' ^ln%OȷoO^bzO~zC 1|T2J!ɻ!XdVwsckIГn>I;U<+uI1Sfm!J$>pνJ+&P~ɲ=9dF5 &.s[㞲zh\6Z߽klt[%k_m6۾qbjDA5)e{<5)dqKB#y=9ț .[U{ĬṬf  Qz sڳ 5Nx_|}8E+(u^yJT4;.3"bINՈ&$;?×XmOOF 1a=ĻXr*r x-*>:{0~]k$'GSwtVVpjr- Rђ(^ u/ V|[SZXRh1Cdm8`옧B4F%jC סиUՆ *Aѽ؜ w1]NOUR&]G Nr{<:Y2j"{rؚ:vAnhkng`BVNyBQүS{MbGӗz^YA+%t5q$Bz'c^1#UEDCǭ&Qd|uZ9Ӄc_ NZAd/x:rʵINX~xw E~іU5za?( J)4n+[y6%4U=lK | {qxN۟,C蒷_,ӨP`YnʳLUq8CZwDnl8HYj@FEgB6% 'KXa}|%_|rVY-gR9| Յvb4*uIo˂I̪6ddmh"hTF<+:M vc9c:98wGHQ?Q;zcr{L+vbO RORLYDRVw G8濑<o~ftV.eT;KB9ae[$m۝]ם#ru֖22&26gw[; ˻C Eʻdm;U[HӢtlfTt&X *nZ"<ۏ]&T뾕)O\Ɗ9< 8=QŴ~ۭDn>|e> E. 0* 5c*)(ZRέB*ω$Rj˩⦦EnC[Q[?O,vgjˇc+gV 'Jgޙ@Zjʽ4LϠ.wvvsqo}YԱ9ZOHCb1_ӯv\5S2Qm֩lW(~P̀(RN¶l-Ø>:>Ԋ+p *a{<$u42<[qcVNEB^bV1AeTT QB@2k,V,($cޜܯ8]MK@()Crqװ2dO<ݸ\rdTu ]zKt'iuӐ 7e2x3= A*& `UD+I++sf\ N; ͱ-c}k;%eH6ao WK'˴Qi=p4K:g. w89 ]Ṿ;%r\PG7Qr)5WhmHcIoT|R$#[ PE494V~ YtݑXXqG_p+ypcuTƾX{y XٶIpF @IthQ,e6Gʭ (;V1q6edtejabberd-2.1.11/.git/objects/04/0000775000000000000000000000000012240452476012745 5ustar ejabberd-2.1.11/.git/objects/04/4370ebc29e051afa72e3a55bd4d2efe32765dd0000664000000000000000000000044512240230175020301 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&18u6tTαnu^BTA~2ÜHGڲlnߦ;c3D6"1 'ᴚNVcPmZ(b[O.@7ْbnɿhLd0ޘsj sejabberd-2.1.11/.git/objects/0e/0000775000000000000000000000000012240452476013026 5ustar ejabberd-2.1.11/.git/objects/0e/990a972a7fa2f89430211cb42138ee09e715a20000664000000000000000000003412112240230175017726 0ustar xrYKE6/1xI2Y\f鈏yT 'yG^4Y\Eȓ"]f"'<9q]̞cFNGY:0BYS)4'$_}4*rjl$/<2QeɲF^0 =YaC3m5/?$ }_&7p2ΦBIS]\yH:\h7/y`'{/Vk6h3xbW2M$IZf;iv:# ~wK;+y2|9MCI(s>gfl~e"7/J|<[lJxlu~\IOg弰}MƟlMf/H_h2_Er=N~vk4yP")fi<]ثd1!N3.ۍ/A>; {;wus<P%~Q tmt'"4;*.Oi~ss}Au}t4pqzOFEQwҒ 4"Cq:vy6I?F kX1^wە&u!Y)JiV: Crslv+H'ϳt ='þVK>EQDtj^!cFe\/I6 v+3|]MAw| THskN Kz)=^A'l$Ssǻc/~9t0Ta/xk_"rxqm%>%'rM/$J_&f B>6:;M¢V̓ݰΛʽuYZdai:OOOlDf] ys}[Nm˫YMIQv<׎n&ȓ?1A»vOv~OGw ͬ*'~DOGQB5oauFA9"GqNnLNr@ a~MQN;?850|\mbQNsDj >yd<ʨ'|lg+[n3'BR~^Yc)[}ʆd,!=\@XYQ/5 m5z}/nl"wk:w޽F {mXhfvpmq36FI5bMOMOm2Jg!.-p}ٚ_fNrơvy G@V8ح}vŬ6'JMRw`E[ݪ0C/Z 7Lx >Kr$"UtydUK鸸,)ϒ2̕.t[P@,O04hsYW4o} cקQL23YKfsP $CId͂m;GǹfE*ÐlE#i5F{߻d7H٩WMQs>u;"YTA|&C'$vR <|':h Nɋ!O#f!B 8-\Z|XO}<:Y>d ۹J5Yov/Tiagˋ` G؎*|YVQ{NQQm(,6ZԒ4/,Qv ͓5ĆIP#Yά"'_LNHWsk"S0_ZKPP/L.V4,n=bȫq!e[D~blgS_=~/+=,&O5R[օf3&6[ QF^FQZE_j- ?EdNSÈh8 ȉu=T—:]8ܧV/i9q]#pl;u0D8ϗ@o|_hCpk`ѕ0P &YK 0"J8ܢťP,݂|6d *8q)G@˄PF ["绍Ca͚7ÍVM2j#t$1Zʁ:/"~YHy0+u\Ͱ{깽PiI= ,@O}sHERT<݃va.0,":"Lv*$8䅰h,[bmZqCZENqU=ZɊ\)QX('+RBLm2rzrs$ }!&7-u#P.ZuT(p*D1xAV MV;vxOh)ɳڰ7k=rӑqKe/h ;K-XdG6@.\pIRTArrD#6O{nX#۰d8Gi/(nÂyAkXv_|ahlɡ~`[Gx\@ko_p"7·fd5mXF ;E:w!!cCh=`n3.4ntnO; -;.5Ձ$?Zц"AA#YZP!kYLf j_IsRF_%-흂QjyXh|qϩx. h.F} .1U9D}~ $lъHdz8ꂉnIи,.Be8t"wJaU-oߊhKWYFЗrD&N!BLZQ4 ĉUTz"Eշ} ;҂9'܄WpsĬx[´"zL1G ISfvSzrF%Ox2kr:kA䪷Pc}L\/?JL4g!2y Qo{mZE€S3fQۗokl)`rՋEd1jF ,&EF]\V^.O؄U5<vZ5Fy?~d+3Po9Ev#E;'(6.=\"l@La!CQmjlQ/rЂ%, ,}ex NYѥR C峔b8KSc<7ӡ /A~GhEu:Vۿwyw/t$A% _y&CDШC@YhY}ഫj$PKc/=~~2Eڶi=%Bo4;8(IψuJ 아WǶ b:*/Z)K^Tn$GIg['\YWOa#@W`\WC9֬VjBWJH)XrI-(\0Q+_VxMb)t@AZ,vXX~5K*M+_7i=7O RU˲By@bLce|4wN̎VG`'p>r!8S=7@2ZX$79߿M#Fk~GY 2c]ozުr8v:շ*ΪПbW@`Y'X&")0N%E3w)#3?r<Mt0[_Cj~1*Gcb/AtF nl’VW?[,SVqH^"ɏ{1h--(2C ה0ZG,߫ '}K1t]Jer䦖sԦFC-ZM=]eQBܯx {rp+)c>T іY*ތHl]?7A1=x&OG4_BY(0'{1Uުu߶+2LqgiSB-ͬ03_Z9J^PPԘgla`Mr@^<(_Wbч`]O w([^k_o-bwCr1 >x Sy&(g*SBF"CVF Zhwk@g؜;el _Z O7@+ 4eG̐[nn00 iR&_ X7 2(GV|5x`L'ZEuCM͛ܪ7(Bq$_{}~~3PQXx0W\# nY7HQr꼝V hcyk%({`%K Coi]F()rhje|TW+~8EMr++QV ÓmPNg<2 )5(A81gD5R$rᏚ8-FVl<,&(YRS=eP]ktlƔ;G&**e6LM-`L)G<_MrOG~Ts"T^RmEzƨIAkfRJJdl[SeL)ѳeM:2MNߝzZrܞ݇̽Xzw񒀭IO#.ܾ%@@,"re;^a7 /E^V :X޺Zo%[7 mbZɺt[V,}s(E~i9Ej3Z3T*%z/5s)3%ULԴҼ)δZ!!ދ2F&ec-B<5uZ̅3x*Y@vY4@Db?r!(8?" 8[aw1eiVlu-KkIq"JȒ((:08ʟhP;;y물tkD uXSq26VCf0pvJNF*>;Md$4c&*6JZ I|jնo|euO3rY32gĩS9~JlNIu?ot]g@d; #/& g`oG@1.(rx"GF٠|OVxêʬU9%<`l%=YͻA:PD q=̆!0jHQ3VEߚhd~koяWִS3B"kηFܫ  fc[Ԏ1,5G"p cz6j M!*.'iϐB)C! _ZnrAjasXi\ߏY睴LtHW$zS˪le]Y\3b/v- P?S9PUn#W "5ފz^9(_%ET$5tƳE`EԘeay/dzo~ ض>$# zpp,ƵJـ 7ֺCeH`>%#"SJ35U|ڪ|k:HsǒwB9f>w h'B+ Idll9'r5:֧4|FF$h |U4CdX)x 8mώ<ҟ?^T8ԛz?ŋ0,dΈ{h 5 (Dz_%jsf[37|b]k|+\gQ#rb(`{~9ˆ-B+8@Y7a3iByu֌G4bu0h@2;\{++8iW/jyևԤEٮ lnmm{ݤ܈PꗄO~ƗX'klܗQMVHx"ۄ3ذnp83֑JGV b!2Ε|vNs1ߧndjΎ ;^^EW0kx1_Ec:BE$fMxJfw216b (NA-Px@ zY*"lb(ژQ>*!7N% 0lz?޿yvr?R-Q#sv}r؊ԈPίar_RBd$pq(#0?_wCO=XuqǕ0!qѣ<%oViXmNHO:YHZ wLmYszd/ ?&#V+T5\%'. ;n凣걃 >Z+w߿11 H%.1pFѴe᧤2EeG9el+$R~܊w+?J^ Ʈxj. #D=*R"^d(m;~m}]ρChj[a qݨVђMG#lx7A,QdKfkQ_G^bmcy͆}|'4\1Cg}m~U\6<_.&;G =U"{ Fw|zR!p@SBDw6GV&\†s6qe^ҩ; Qq%g!zH G]{BM[D^+8ZeSz, 5bnϏ{A<_LIQ0RɿFk5|F$\Z7rVmV dW,[l^mE荘ݪrF;O -< +Z (o%toR'SEQPB\8馸@;n-mx/rnvB<( ݃z~c0";( =s3KkW; ^puJSڥ)" G{Ӛ ǘ6,T_(92TaT:uDaF"'qD&Ts΃tnLv<M%1 +U#"W_fCY(W:m+@Tx@2S6eDVfvl *B8ϦC7"=wVYnGWbuVG ]EbQo3-;ȒROLY`RjZ޶.KaYWs%l[ۅ|Xm3 x~`s]6 ' *d _hkM[U&h2Z&,g zT$x~7qh5ai7e9kzH&t)˕ 4upFba0*CgsJ)!$pIͬmfPB"3 4ku8 2 icu@o=nfXG9^,;Pf {6*c}O}{g8ٸUؘW3;kY;Rշbʂ|L| ilY w;{4Y%1f+,aX/<(a>rMlbd8DwqiSZJyG/[ON2VbDab d,ω10@YU UZU\mxLd1֨,KE8JZ5Zҝ  Tw8p4[NaVޣt[YɃVj'3( Ëjt9I٣rU3yKXeR/u|.ykǂ )f'h[{{w$4҂4AA+'bM4V'twx9`ԏŸP?ՖCd[ϕ 'X{"ш΍tnȾ:㍏!D%t/* 6de.@7'ÖEбj6+'e0$zy4);H|~Q%@ltE<ɗTGcYoB8EV 7Du4eX|uR/o)@X}fu&r7)^af` vky7B> e+VMćs2-ITb)U ik(ZКF790c8Tb^KYV^EWl/!sa  uM Z-Xja =}6U*"` Qݔ/;gŲrѭ(kĜ[w(G` W"tA["A'?لb/k r!*+tb%x 4nJo4$>F%:2\,le-Oc'dbÆ0!D)a|5U`">s+\rCtU+ x7?e`_&eW + a<@J?QFq\~10QΉJhDpV}nV8IZOk_ chB"T_F3~H ˗tI zZU.E(K!+jtV6I.j; 5VEd7U "ص{k,\K@P-tNa^K2[o'W],J+&P~S׆?9dF5 &.s[㞲zh\6Z߽klt[%k_m6۾qbjD+n9Sg'3#^d}~tte.{:1T3e@Ui<'&P-{+…&^`=v{̙PH@>vPvMJ,rMYܒ{H(G+z fV 1+YBdFBT(Ar7BM_ 4>$9ME+(u^yJT4;.3"bINՈ&$;?×ZXmOOF 1a=ĻXr*r x-*>:{0~]k$'GSwtVVpjr- Rђ[Tn{1׽'[ þlMiEbJ!gňO]؂c  &_vCVEVV*D6#ERbst%:>!"TJ@w5xh6O8UzMNh{\m:Nnpm>ښSF^zqPoc^{˿ͳ~ADJ*]qj7IX@g)WL닍_x̃]""VK(u>K"Ǿh^Tukn'#zA&q[-7k~PS}iް}Vv`ĮXlP>(W -)-W-u:gc'nK+ڳNFnCeZ)23U ƙST̊ia!RI"e͖-z 02 /cu0Z~QxXOg}nIbTiEЩ wUѦ*v" Mp؜x-' F1Y tw;LKbc`I6cT+JP̀(RN¶l-Ø>:>Պ+p *a{<$u42<[qcVNEB^bV1AeTT QB@2k,V,($cޜܯ8]MK@()Crqװ2dO<ݸ\rdTu ]zKt'iuӐ 7e2x3= A*& `UD+I++sf\ N; ͱ-c}k;%eH6ao WK'˴Qi=p4K:g. w89 ]Ṿ;%r\=nG"6j7*>Pk"@u[[~},H,VA\_:H8@s *c_e,a傼xl$8#Y {$:̓ptTÇOc2[#} 82r9gQqyO1nYqY6M,] /mFdYdӳx2:#[\F;_1Q6/ WuNxˏIYG/a>=_,>1g6<-Lg2ga6_AE@y>g^}vR>ɇⒷ "NHPcIO/eh0dE\ÃF{j%&3Q/O|3}I1/s~xy]6 fEe#%g76HXyz%g}6EcK4nZ_'h\Lb9ͯY%Z}6?EH_Q(;z>S\>Ṃhf{p9Hnnc4jO9ҳ5 ҹ%*0O2Vhl_,E dU&^Zfzg4g9a>fG_H|>O$E, ًFV e^}΋z/ ]lQJ7AʝNqmrS|'|̗$.p1I]lͯl؁yeɒb8bUឰUl ,`Q/AeG& `FeadkÏo^~\H1˳|8M^?{Ƚ^=O?{fc")fr<]ثd1ƨjl0Ra8̵ vT/.; k;wuSW=W~Im9ذ jLi\~:9Ι!z%L)?A٭h˫E:Ye;y:g[}yQ3ST!VuGٺ[jĆ]w\l#Yk=8J`fW5)eȡw|ޘƯ ( 3L'fswv{VS@CK;lcCAu _FX9j0G8Pl K#/||-K]w`~.Nߒev9ɦ{[RYFOF3}muw.?pH07|ꂻ2Ul[j?Em]'%qa<4[?>i٫`I=jT>9k#?+ 0dV$4k5QN;/;e`lA} j$3NjsWiQ'r@-{OEbѺgBpT^Fy `!*=Q$H\+]|_ޢS@Fd<;KpX'[NHz_(|i2T44> zɏˉ56H}?}DUA';Y}/ BL=* պބ7bg iK~>o3U l8q@߲fQ:dS1W$(sz?K *cZyVאvN*39諚{>\dN٨f g Ɠ%#6%i%b /_%ÃA|QzER?t(}A++$(R6=\"l@* PbTe3[ƋA G b#o o]PPY)+x̣kw#g)pxvo=FJ1eyU f:B3)]} VeUmXDW!pt&ybOoT .&i6Y8llQ&S~ϰ et2N.9bD 1C6{bhԃ]{k( +ETDD^$疯kf}x^m\Ln+ [ `Jmf޾|v|~lh{(XzHPj~5j C~W8ge)OAӮBs Q_z|)ALN)zqQ}DIzFШSb`E.'@W'o^"nԫhXB\[()Est68\r_<@!G/8(WCX9֬VbBJIX)XrI-l:a$>Š S jSkUX}`aїBs` 7zn RїEBy@bLce|vX= !bN(}Cpq@TӧwJhnxS$~&X 0d|axdq_ouomf#?j-ɿyn>+up8EVא6ve#cb/AtF nlHċGE픕%`=H7M~{9T.`Q:~] *\S$kY /z҇},Ґrvmظ(#}wM([,M@ˢ '8wV SM(}2gƪx3k"EvX k')~Q1h>*zXܽ*@oՉܷI}E),mJhֲ~tqXk;G -2{ J4Ԟ˪Sl5eӋb^E n3s߁C.p]Rga*τS@%b_T4sC7HDbhBJalp,>9@g؜;el$˷O~? p?T@& !^7DMW)*M$=fk$A)_, 8- H|QQRj\=Ԍm yS}[I.ZmC_ \:bh =)301~Y 3ދt)D\#THb2dvgeψS}r(7E:zp$աZB83x"anlALߎ) cĽhO0a㹊6eq>Rr*V倗Hg^Zt,U Y(^fC2ĈL53VEߚhd~koяWִS3B*kηFܫ  fc[ćN0,5G"p cz6j MCT|]NҞ 0|k7{*fu6;d9DCʛ$I:e 2sͮR. }3b/ZvKg(vCed>^{ z7f#}F -NZ[Q^O}t+ekʞ }czH"V 5J6Ql{E^zqRZ&`Ht0ĒC)m ~S$*6ߚ;ݽ`@'7A]s÷>(_&= NJ0JƖX{Қ/I^]Jgd$y~ +/r5>Ei{vڎ̌:'HCZx4L11Zx IJXDmLzk憏1CX|oE,j$xVN05X8ǞVuR0"EB(+&L`|XV/4Wef8~?A@UvJFΣp Vl}aEP]c.I؁)-(̀VFQ;0M͍x+ j~IKu^_&N}AJ A5 J;~GPKPC1^dVJE:b(ZQ>*!a\~tpU/\)pxԈÜ}i&٦_l V3DT愂_(੡9}w<$-A^7w솙"%oViZXmn&N:im jڍ; v,:eboz`G|Q+c*A65\%- ;o6cA|$Vgo߽{=0/cb [CrM7{` [YAaw?ʹ Nހ.d%2D-6p3ʂBq Qp3۠ѣZUķݐmsaU[+ݡbAmޥ;jd]ōSUԩZ(-)yG>M59W-#H,u+EP̚ b!.SЧ4%duܑܻ-23G`<.k/.3)LRq\v3)=*/blBq 3h:U5mfs ;xR"P'&Fpqjύ䪩Ry]*}P܄C%6ƤsP;@*sRTV_U)Qo ㍜#ʢJLQqqm݋rl-[ݜ睧t(o%toR'SEQPB\8q:vZh^c5yol΢&t"` +nCEv`'D8g,#q_^@LJSڵ)" G{Ӛ ǘ6,T_(92TaTDktl:0#8"Je Tv:7UA+Zupۦh/Fl,WGL^+6V s< n~9KӮ=ZFde&kƠ*/lX{ZE\~ꬌi^ʹKNSZcjX7̹ՒqbܭBԂx>.ƙv|yn "FcLBŋG=+A{(r 2(H(4ջ Qsc~s5lZMLֿd*֙VX#+&GWM,,..mJP \2Cp*ph$ V f1J?'Ӧ.bqV:W5TiYVvpa0}Z:ZrgX(D/qTzժ:͕d(<7|NÁX1ޢtB4vO{2zfsj'Z%5ELx*S(7ձE]O/(Š8`J!7p>|ϗdΠ(l/}0="u}'<á$0!g}T@_4DŽ R6-idwBC8u&! u™Aacρ$Xyu "L ĐQ9|w#!pXjyD|8'Du."}+a8MQkZQ>'ؼ|v TV`bi4bUeYt[Ec\@c+ACd3h5?Zeo$(-}vxT7% |>hlY!V$U56{̓~Cp+X Bd1hIc#UbmA#U^EbA'V@ {֫ićډym!<yӏs+\rCvU+ x?|2yU~T(ŮV6&4)DEEsD9'*]U%[UZ1$k>5Ozp7E8f/|AZյ\kPxRi;I TdUBiJh$ a N,pg/^ۗ!BkTW:vnga[G^7|CpXmG]=M[O^%ܳUHZsJPjt?#-c:7bd]|fċ,5scO0F#5pf%&̓zmݲH_ԕ-\hxܜ s^!se4b|'Eq}kRxtkR?CGD=z^9s7\] YGR"C5R2@ |;.wxk.; }A#n3[PLGpyMWS*-nS%l&9YxF<|pWHt_*C.1PC:R7hV CVEc.{.5w)w7!;)T%h(kyN&A> x-*>vaz m,*1H;ժ COaeHVpj̧r- Rђ(^ u/ V|[SZXRHI6+iwQAe=nd!nJd3BQt/%6']LW'D*WᮣfNr{<:Y2?D娷5u:vnadng`BVNyBQ_/xkK5<0Ď֯gק/۟{M'VJVjHT O8KA1/6">b@yG0v%[-M봎sFŋǾh^TuXkn'#zA&q[-7k$(Ah4Nd+ 0bU,tm(\Kiቫ{ؖp+ :1YXD% Y KQ7ޡX㮍?ܔg˙{)q*fE돇) $pNowh٨왐@y+4OUÊս|:sL*'OA wQIV`L zk5&UGxGl}3`|Cf2bk%Hes*5nQ 2^Ngb[چo4Éwux\E۪R؟Jh [Տ5(RVFንc쏫ɺ' &q2RU6dD6z4*#r[68NSXΘηz!RkeξzRݱQ=&s ;1]kq'umLSN)^{Hi@H@Ql:+I2ݐߒPNXYvV'$GfWsDN)wHOkmI(`*#nsp༼<X{K6ޖ\فt=-MNFX`F刽Ne -;LLczM:[^U =pa;;\L*ZJʖb'ReF%Afl ʧVT<€9sbas:3Iradi~][q$~XԖ4WάNjϼ3Ԕ{hꙞA]즹21 l@_'YԱ9ZOHCj1ow\5S2Qm֩lW(~P̀*RN²l-Ø>:>֊+p *a{<$u42<[qcVNEB_b2*^Urר\;?ksʋu1soNWæ%lܔ!kCm_zne .d f2:Ȁ]Įp}?~i?d2X|䠕ypAhqllFR\=٨@7=<<6)qaaqfv_w x&jdv4b2*FwM'̅p"g<1~[-UxYut%RsF`^.a,>Q5O*&}{Pݖ&-߾ b>aw`QW+\iZ젮/~$9X20rAw}s<&Φ Oejabberd-2.1.11/.git/objects/26/0000775000000000000000000000000012240452476012751 5ustar ejabberd-2.1.11/.git/objects/26/b155e0e0301a52126f2cfa4fb3a04e7b423fb10000664000000000000000000000020612240230175020101 0ustar x5A {+WR vԀ吊C8f4x}޷`GΟYhStg#gyEK#Tru,{9ɒE8&fy=ϯǣ,.E~f*.҅'t]dfG"?M߿oƤ:Fq&;g%gٴ6/t1Q>ef.Nϖ|^doqN`|,G|<|j/\Mi;}/?&)[\fgM?K||< ٜ_2weȞ|'ܞ9xImݳZS{%NjKނnӋd8#BBM)-.<$.0_ `ދ^J8qMf|^0s#'Zms:_/(zi=_9I^.&̓'hf{p9Hln4jݏ5Bҹ^ZN*f!t`K]}N"_·["OEr<̓GQ)HR>ΓiHin$ylͯly̒b8bfU`yl , .Ad&kdk_~\H2|8M^?{Ƚ^=O߽}zl")fr<]ثd1Gj Ra8ĵ vT/&; kcZ;׺k_ ŪB觃I~i L1旪NK.slFH'X}%s,/0~TXNt(l7z_<;^ޱ?d=be2˩@(g>yiup}ռOsc(qէ)Ih#j2ɣv_85v@0[TKr󕙬9bOo|ڲp#1٠t:SwYDBnd#emAhxk_\JDvE [W ,npAc,ś @`B ^xO'/xOeԓt>6c)Kn3'Bl V8j1garF <3˴0+SF/ӽ[/6MyvskП-lV͌Q0+3 1J2&tRZ:gi2{W䘅c5p}_A VrfdRsU)Zg}mՊ0COQZ 7GMx >KsIͪZrNzX,+\M{j4zÖ O- ݜ#`*#͞ {=]G3ʌD&{^mv; J3ȚV헏hsaͰT4!f7Fj5G;d޽~oyS+KƼQqv\s&O}ǟ: )l!K'_蠱f^߾[cOj2q1 Lji)\,RXwY;[Κ7;'niagˋ` G؎[9enCgJcKV+=((/(;Op8I0 r zgVt]yq+5 V)Z/-5F((X ]u_OANFw71ո@CF? rA5P{+?{o1|/Vb</Y^DM4Z5>FJj)36[ Q8 YE_jS@Fd<; '49N&񝐪Pd5ih>}8mkmzg^k,-yTy4r?g+Ђ+eXZWtۛ"Upd<!,ߴB B *o86!6k΋g-AR6l2_Bt3)AU_^GE/_)OfnKw\p߿zn/qM e@Oc{HE֓,<݃vai":"Lw*$8䅰*z ]Vv i5\99TArNVJ [PNVbȓe7uX#؟Sd>qR>>{ "@S!q2UYn+X7Y >C*pN8%ytS“`_-EpVGv:2n#| md~&9)E{T[0ȅ 5)_Y*HNwdcX@| A܆-̸&96or6,WD ˊn'Ɩulr}E}5%Fl*"6j\O*1htV3$dlbL%L7?g7/)byDPW-u}ˎkEu@Lﭬ_ ̑,-([YBg9j p~pi;g+ggwP+06S$]&U\2I2T2,jL[ ɭodV\@"$7.Xdr&V:;\0tMxU")s7Z(UV9tQnɇ(%IPsV wB`&?qbHzQF߂0|GԀ@T YMxu 7G̊%L+'ɹ/ II B+4qOMş,,`[<,|)Pޢ@1rE n|s|zӋ~'5> amsV$.-kԐm!S]hd1Q2Ri+(өfiьY<壳a|7lkIbOδ56_|]Oi[$^ԍ/"Q3Z`1)jMg5Bpx=`Ħ$D}{x:1[]@GN04S/hESce^yBq򽇫^mYJjlVcfx]#(Al$ **+eEGGFH14RAg[{k^1ڽVjC~o6j0YMk,nr : 3157'3xzˠZ8t%I'p`g{2)=,{W(;qp#b= Y',siGLm\cGaXw0 00ey+oO4Oy s 5!Xr\A;e<|/"y&)e'עZ8 )`kXJAAllA M{nhև^?5tf)>0˫߾>Z=Mfg'/dž&>IUW^Q94Pw5PC~ZD$8*dp;i(1ȗ??IJgDY47GGgD :%Vcr4{}c[1 z6K^Tn4GIgo<]I5 rrU:,?O^ 9Pިoj5&T[ -nAjI%'I†&J _ 0=!hV5}(Ԡ`- r1 yY$$T*9(:YgΉՃ`r+6rG8g[ L5}z7>uNrj=3Af̷qJV?VVY5 !/6Q QDepb5s[wR1m2>O|o+~8EMr++QV ÓmP'={F!u0b8K[sF4x.E DޖJIcYga0qF t̒Q)X%:%PcbS?TTle!P˾Pl0^F)"H Z:|6I΀gȏy_ [ʳB8sK=4PAkfRJJ2#,5)Rgokz6خ4S8}w^vjFr{w˚(fP^U}')NiqP1dC[G[x(Zfx\߈0!]CRYl&A{C*OXFh6z+)}ݺQZӂ*Di%9l5[ ?hO&g6. }hMBP56Ab "P70\]"ڙV<1{[Fg t#o 2P,E`]#q'BFx*Y@vY4@Db?r!(8?" 8FN2G453e#čt}VD_Y1UV\ ug'cnm"J2᲼akZCGoTFR+C!38JJ;]%H\AǨMd$4c&*6JZ I|jՖoK}F.k}[&87*=~S4;)`8GRn%$]ߋ3w i a^3Se0ķ` Bq/(rxGF٠|O?WxêʬU9%<`8IĪWrywU!Hg(!ِY1"S )L':Uѷf}4j?[ջ5m {1w6yQ:*%xB?cj#V5>S+L- y`F1bØCSi_ghC)C! _Zn<Ʒ݃YŇaq~3F;2!AǾ&Dgp0PjY\+˂v% Ka]s95Y^'ލpmdp8NzkhoEy=mEʒ"*{6!g?XDԘ+DղayŗYyH7tl[sly gsEba zppvpDtG|Z@t% Lu`>%#"S$%4I>mU@ m5.S wc vۻ{! ]4OnƻoWLznpVa1 왍-5_ΓF?"6I*_X)h!`'.V_j|[ep .z{jET2egtjj:5@&)cٯVL3魙>.b5V P [91`{~!wFH5Wpof?֌G4bu?;hPNyTW\܊/Hʴ+~̅x!5iQ@;0!0;*ڨ7jݤ܈PꗄO~X'lܗQM$$<Wm‰pbU78@j Jrґ4;*q`sG4S\*`Ebd掇Wѕ&̬a,^ y[w@"()#J4of_hq|ۇ\G}tjt( WQH\[ 632W 3ʇ5T_>$ˏNz` |4x㳓k"nv7$S6k6a!2 pq(ʜP<54Gb=a~8ڿ%(z|f㎒0!qѣ"%oViZXmn&N:YHZ wLmYqzd/ ?"V+Tlkx뱟K[v`mZH~k޼Y_ST #> gQNMy_~J+,lW.;(c[!VLZQ MJ' 5vŋXVs>N"Vԕt2$C9\CtuԲz@<ƽm3+'wZEKf7ÏP!@ PDP u䵪-2VZ>.lK;pZA:?kk₶Arq5rM`H`B><}8T@!'M1kcmŊSTT>=VU2]^q̽7~ƫ$BXnHoj gl?L<n@441s]JL#jIevZXmg&SA;gA >;G&o߻!;+zlY7h>3VCBO٪;jd]ōSUԩZ(-)yG>M59W-#H,u+EP̚ b!.SЧ4%duܑܻ-23G`<.k/.3)LRq\v3)=*/blBq 3h:U5mfs ;xR"P'&Fpqjύ䪩Ry]*}PfXLZ"]9b`lwevt1pT.[4U݁^H>QT3e~܋g;͏H*5n@J.Htao X[.m29"0huzFǣ.=Ʀ-wbKhF탲[֯&x&.ݞ1&yR:`J%bՐLz+HoVmV dW,Kl^SmE荘P??<5w(a:%-QJ>N6Q,qM\mu층Њ㓓j %lFEM4@W܆ENq#XG^zށ$ZIP{Kk}gSD5f5kG1mX3Qrdg(¨:uD 8"JTv:7UA+Zupۦh/Fl,WGLN+6V s< n~>sӮ=ZFde&kƠ*/lX{ZE\~ꬌi^ʹKNSZcjX7̹ՒqbܭBԂx>.ƙv[U&FEh2ePF9e$?IbC/f"]MA t/{>~Glh"mt_ ,NFq3Ty6<<%TR1. ZLwLj yZ)'# 4!mN==Ptˏ MGb7|`3,̣bS^/(K3=nO}{g8ٸy *bfg-zG[~:_t%nga< UV$lO%,˕b?탇g,ƚqIz2ݬVL_ˢv k<kq [1E][ţicX$r^sT]䨹Slm:jȈ6F&_F6[LH+F eV+W#&LCt6%KDCpԮC*ph$ V f1J?'Ӧ.bqV:W5TiYVvpa0}Z:ZrgX(D/qTzժ:͕d(<7|NÁX1ޢtB4vO{2zfsj'Z%5ELUQnc7.^PAq]o*וCRMo߿_w+T/8P ?IAQX^xVkϩxVoNìk*zu)k;N8Nh4{8@ 0' Z9kꗠ_t޶8sqewV-D-ɀj G$q'jvq9)pChq,C vӴeb&jBk7V3k 0<2;^cz d;RpAv͓E6DۇGİy]Ng8&DS*&V?4wAF>ÐNh1nC83(l 9+/ղ*EZBso)61QݤJ"L)4զ0q "Vrxnɖ1#qp/G&{r0>Ȋq;O ؁yZ_S:gC~M7+WMPʧxRi]2! 4/n$|V:[8Vd[9HjJNv5qω)6/á*:XXzY]eQ8~26p<}X)lruxf# JKg],8M9wϹ}VVmnE^ _܊C93V٠sw Z):)Ę&|{X[@1DWXwЉ%xM*y!v*|E[|@Cc~ï@ ^B!~i݊hț^}|oA ϳx ߽w ߘfW4QbaU4&@Qb8CA*pKR*c `I }լsLS]Pr?47avI^͕1K&V_/VzxyuE?67Cw/kr=o8W"6  |q{B 7žc nBy*/DЫY\~RO]99w{FX"-GHG!ՔN[=T"hSGSTq87-q֡oa. nxҏ n? [}6L L `U䃬LP`ǘ[]NCXp4Ƴ=㗱WդB)v1! H'(2.R= &9Q.٪ϭҊ'ia /cK-!t.Ie4㇔h|N狜$ ꬇/U"^[JIL"D"HUB&apQ^#btβO0{}"/6xSh v |uuwڻ 9׍%/vy,rXdP!ʌOlXZnt%eAPys-">왮૞[v9vm= p]]Uy( MCkZr+Iy},nf8 T-` >79{vYaڭԏ̸Kpݩ(}\d(W/h *\5[g̓E(d\5#,XuVKj|(:`.QQ9oLc8d2yݰGjǮXcA-Zbdjtk.J]d̔xvH=IsF)Tl"'"L1La^Ј}k;G5)+XF9n[[vmn˽:ڼzfeeW#"Զp"IX=q+@7Jr65hԞ>7"GvX.I+9Q"Ew)}HwP ;nvͮeG9$xɃzP+\⿄{P`uNU ~8_SBG`dŢ|V\r,;^FBVLwόx+ٱ5scO0F#5pf%*5M'$*e\+;Zk9缂Cnʜi_N>^heפ"פ-zrn"o6<,UA R1DjDev] fמ]w;G,Qg,Z|_UF,UZܦJq@#Mrlx2Y%Xս=TV\b>=un*\/Ɣ]\jRnBvmI(t@b{QO<}ؚҊJBFˆO]X1O h JԆxدCqFVV*D6#ERbst%{*|BDr*0o:jZYP?T-׿79ͣ%cdTz^n78mMv&$n唑^\-rֱTsIhҞ1x6xu׷/악߫/pn:RJWsG"ZM'~h?Y i}>y+QUD=tjiE]u00(^<=8EDz*\t=qyw?P4mY]/ A :Eq&[mbkCZBO O\U.ö˷^udȺjJU2g1,F>xb6>8pSe,g3ǩ%?¾C, tcñE6[l]Lf pt^WhEΧ*Ga^>r&SI]kIL`*hSIV`L zk5:UGһx Gl}5`%/5l6KUjv;ݢ"e̝ Ķ" /shjE)𸊶Uk5?:5]kQp.+ǦWuOz[o~atV.eT_8!'-UNIb̮r爜RڒPF'?$UF nkyywy?JHyl-|jkzZT{kuAV-@ Zwg{ urݷ>z@XQ=_ww24VoU ͧ-_Y3ŠOBQGJ.Bl ʧVT<€9sbas:3Iradi~][q$~XԖ4WάNjϼ3Ԕ{hꙞA]즹21 l5_'YԱ9ZOHCj1_ӯw\5S2Qm֩lW(~P̀*RN²l-Ø>:>Ԋ+p *a{<$u42<[qcVNEB_b2*^Urר\;?ksʋu1soNWæ%lܔ!kCm_zne .d f2:Ȁ]Įp}?~i?d2X|䠕ypAhqllFR\=٨@7=<<6)qaaqfv_w x&jdv4b2*FwM'̅p"g<1~[-UxYut%RsF`^nC;ZF'zM?bu]nKC~Kd9@,G ;*j+mA3Q*c -}7cu&50'iD}Z6`S:cl<DAejabberd-2.1.11/.git/objects/65/fa04bb6f79c7de498b5bda9a8734296829ad100000664000000000000000000000044612240230175020203 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1fo2SsNoI*OfP[6Ct|glȦV$3Vs_c}~mSUVB%3^luup(#"[SQ-/,sNv~ejabberd-2.1.11/.git/objects/75/0000775000000000000000000000000012240452476012755 5ustar ejabberd-2.1.11/.git/objects/75/302caefe4f6a1e0eda38dbcf22fb4a843880960000664000000000000000000003426112240230175020376 0ustar xvGw_E{1- $>I$ʶܢdOϙ]$Z (}fg`o`nl7"Pf~A*3227"2&Ym-[zvGN{j5Z_%iH&"o8?wIoɟsmO?_Wr_'?=I~>$YgU2&YZdpYq~:_wE\tt5fTd"bOVy3ϯǣ,.E~f*.҅'t]dgG"?M?kƤ:fy6;g%gٴ1/vgbxi|6%";_-Ǔ$(2/4!]xx^~8oq%_}4"r8#|fspӒqi,#{6fTd s{g'- C>|/.y O/d 5INķtH~z/DMv^5ߎq:Jw˧I yNjvmf;Gz&Y:$6WtU -s|(^aʤBeEZka,oQy[0CW/iRngyr:"e_*9޽`gŢHلO=j9Y1ii~Z;j?.; kB[wuSW=W~lIc97ذ jLi\~:9Ι!z%L)?Aիh˫E:Ye;y:gۇ}yQ3ST!9Io=굎no߫vq/Id"*v'y]׸!~&s,/0~TX@It(g=qN7o r hx)c{bsl`=.Ck/Bmd ~E2=pK.5 ^`[r.'2??xo[9/ilEGQyNw~.;(*Sš \eϗWN/:y.73P fɟݳ-f?uQT>9k#?+ 0dV$4;kQN;/;m\)jcB|3ȆxM9h̸0+@=lEr Q.z-^bajr6F$|s./8$bT <>8fQsݿSur“!9*5aĮ?LxOeԓt>%!Vm~hXcm c09# qEe pRévs/~ mZnQpQCjZ͌Q(PS1Jj@444&t=QZcy2{W䘅c5 p}_C {OVr5fdpUi(Z۾jEIߡ(Dل&\{Ovx*<H Kc%?`ei탖s>o2IQx<аxZbyýa{yt/j Tf|&2yFb=VPy=F6,X[v_>=΅/Rd[.Iu50{"{`4Gn(&.EnOOOH6쐥/xNt\\/~~~F<8LqGB>oqZ b ԟt,WAIʇ~wM[N30Ea#lG~.F+B{N٢PY&lF6?JK;S!ez=x!6L% qޙ]$5}Kש}ynps:|yB9tKy>q VC.MANF71ո*4fxCEOOq/'tо%Eg,vɌ/""UZ@I})P^Sj+1U=u4GB8XJϷ|iT* }W#UEh>3% {;O#bR& '$Ru/4wlrNɏˉ5H[:>KA*U Γ`s,r>Z!F&aj]moBH !Qjf\Gفܔ:Te_=U7{BHeA?Ž ʏk"mR>Н XiEcYC}%r;0hQ>\i0![ݐ}4B/y >BXiŅ0U8;6!1k5΋g-AR6l2k_Bt3)AUL-x6@ʓYn(G<ܫ7=׾K)E\rS;)|pBܼ# “/OI3Gw7 >E!B)q.RtB3I^ͮ7eamWܐVToĝSumdE{dEJH)uU(P>dPHoO~qٻ&~g! x_ЊąeM2dl9&=J?@*; xE"w:5ju=0q<+g|t6tM{" a@)fQo)` ՋzEd1F ,&EA]\V^.Oؔ]5<5FyiHiWfrvTK ^S XpߋmR! CQcl/rЂ%`ԾQ2uA@e>3͐bh**j6sb^ tfVS*0˪ouc9O^ љmm4s/@mf:t^ob{Ul63㓗dž&>IWW^Q94Pw5PC~ZD$8*dp;i(1ȗ??:aDY67Z]GGgD ]J (hͫc[1 z6K^k %h&'\R'|/P+ N0UKD~90m=7OY"!;wN̎[y`'p>r!8zn d;%X47s{?{|G,Vypׄ~GY 2c]o0Ur¨1;Jl,M{ԡFC-ZTz`!x &]9”z1JhkY*ތHl{fob,k{R5OG4Cy=ZB^LdDLuR_a;Klf /j6Q:{bCXzk&}9@!c.30g)rf1/*!o$"14h%`İ 68ow}طz`skޟx,+dcqTq D9z@ހASF|pԩe4ʭJ3M&iMqZc@6ȠujZ^pyq#wf8/߾>ͻW?4ýPQXx0W\# n ]7Q<^4uN"oIR$@YpZ@2w)zO>/ħ⇓\$\!uj9< zRlg<`bz )5(A81gDR$G4THb2$g@䋊yIEJ;~GPKPC1^dVJE:b(ZQ>l*!a\~tpU/\)pxԈÜ}i&٦_l V3[{@n*sBf j;zz;JvLdV 7W\t-gPq;d'x@&s杄{-9˷NY$Ǜ^#Ȩ1 zg.q걃 >Z+ݳ޽11 H%1pFѴe᧴2H" I[v 2)zn[btPcOeo5]p|$ l NO])KgQ/C2Ei0D_[9p(M-7 3nܛ6rr7Ud*/|<5M%K/l_G^b-cy͆=|'4\1CAaٻ*.hj^.&@X}Q]  Ԯ)kwjނه(䱩:FCx-v#Z?E~JEc5Z^%G(ʡ{㷎iJp +D5 $=O[yϖ󐿜ypMVC&u>r.7 ?YiD-.@"Q a; Pd*Hb6g'ba$;7dgEoۜ-Fa-[xJwXI#OOU8%P.50v^2[ Š%e>HܧI!Je A_LIQ0[V1jH|F$\Z7rێx+6+2E햼W,Kl^cmE荘P??<5wky V[нsHlLE] C qYㄛqk''o{sհJپ": ;h7jE@W܆ENq#SXG^$J:5ҮNi8 ;lը=ƴa ̠j:Gɑ"f֩# 39#29t\@ulscZuYG m*yaXb6ruEic5]:\S4eDVfvl *B_9φЍ?HUӕXBW&4YKWMx0DIʟ:'KX>+~Gcg,ƚqIz2ݬHHeIv[~ĵ8儭ј.ӭPQOJ4 7 tyc9M9*@.{Br)sߜsdDP#f?u&#Vʲ ѕb & !K%WxK8Jz]}rjeɀV8X 4 :Yω10@XU UZU\mxLd1֨Y> ыp^j.ts[ &r('ckNaVޣt[,{N{A+H ^Ze:H~ }PL}]$Çnv=2O=gP6/}ÐNh1nC83(l 9+/ղ*EZBso)61QݢJ"L)4զ0q "Vrxnɖ1#qp/G&{r0>Ȋq;O ؁yF_S:C~M7+WMPʧxRiݝ2! 4/n$|V:[8Vd[9HjJNvo(Sl^>;CU*+u0m4,-ʢq1d.lxb|Sؤ!U Z-2ŷGfJYLAqs4+W*݊r[~Cp+X Bd1hIc#UbmA#U^Ebn/ЭWU(Bx xC~E\XE7 {LcVDCL|L~%||3|c^KPDm8~LqXE+mZA %v9=4$M)!k*D5%K0ՆW1 `NvN@NTrWP8^mkpڍ&Ig5WjĘ.[}*(l '"'"o"1.+bU9<>pDhm.+uf6@]o{( 穈Af}Bs kCJa<v Wn9BZlw/z{\MYۘQԁZA:A@]}>̶dǹl;` ^ (Yp Ɠ~dXp.5QLw0&‚Hv0%LU梊3 @ŧ9cnuE|;Zu^ЮbD~_^2OʯW Ƅ0=O#OQd\z<סA LsZ5>Q9\U[#NFW$_ Z~C\h)~9IY_=]]E OT*m' 3A8~[ MW -={ D9Rea?k2D^hmҝJ,lw E j&\7|4zQ? V}|ó2J` EFjKC5`bRՒ]du%+)KʛkAoߞ 9կnWq[nw{AJv5M^vg@5:=%[ lQl%"X+q'ToМ?%PWg>[xesB&%S |Az:>YϪhP| _<3VD"2Y=M춟 9i)K(ag+< VT*9 F[,g%2uo)dTyɺ̈Y:n}jB:Cw=Ptj*™Pzj0OI Tt"|SWvp׆qs6Xynϕ9| ǽʮI)EI5zrn"o5<,UA R1DjDe-v] f}P4wX: nYB1]5Y^OCH:."FdmeJ"#;;|ֽ=TV\b>=un*\/Ɣ]\jRnBv?uEt(]NОŰt5p 5MyJ 7ΜbVxH Hҋ @q@n=02 /cu0Z~QxXOg}[ΤrR1x*!p! ,U5NBx谢cdRoл ]7:'}8bǷ.1tIa'!V&h]T6WRb.ethp&mxAFS.:HqWU*%hi芦U\ӏ+euaX96J{ۺa'!#meC AdCA2"e,45؍|!n/TwlTnIv_r{ENLWA\|6Jb)Q]`/=$oO_Y6CWNnoI('oDUcc#9";'燵k'ʈ;ko18/.G) )r>W6;E+̨LVdU<Ez)xiLP'}+S4qU@zGq;~'Ci[Q Bs=Z5^ $uT,$h"ԌVMA@ G0vnU,2TyNTg&IuR[N=,75-ҏ6v8 ݙᘆʙUbÉRw&rM=3(-4S&xm\~18k:6'^ ihQMB?[{SØf*Xf#ͨJmB bUrOenL~=QQP\7lP %N~W>d8[H1AeTT Q w~ U5V,(4cޜܯ8mMK@))Czqװ2u_zne .d f2:Ȁ]Įp}?~i?d2X|䠕ypAhqllFR\=٨@7=<<6)qaaqfl/cdVP`@dv64b2*FwM'̅p"g<1~[s_,:KB#0H0OnޚF'zM?aP]MC/.rXO5wUW<[_ h8VGe쫌% \@m>gx; dDu֚*qiyRF{k{ڀOC),vOejabberd-2.1.11/.git/objects/fb/0000775000000000000000000000000012240452476013111 5ustar ejabberd-2.1.11/.git/objects/fb/32527514b30464c23cfafb7758fb3da49dd9a10000664000000000000000000000026212240230175020226 0ustar xMJA @a}IW/s$T/k zzeOq\OTqFv")pC Ȓ՜(-W2='xYShJqJƑ}[!ąOfVKqVz;/.ona9xFG8z4 7)}IRejabberd-2.1.11/.git/objects/77/0000775000000000000000000000000012240452476012757 5ustar ejabberd-2.1.11/.git/objects/77/81c1a6ef4d70a96ecc818c78f439c9456a02a50000664000000000000000000000104112240230175020111 0ustar xmr@DscR*K 8@b1ZvcY >v|M_K0JcpTՑQR*4LH|x0nl$4*f&NTy&ݭtgQ e)+h>;mi˲IUNQު6L>$¶J:F}hܳ38w}]@YWOH';ٺh"6 ô wwخ4h|)41m*ƎcwӉ–k#N-gr8ݫ1Y_g+qAj^c)Jw?vQ{C庞 =:ᘩwUu/&߸ /27H t(JfYn/NQw;k1yYjvE1 Eiv9Ѳ I>+Ry'ƘDra$R5tNa8 DQ:lg+x28%רz3ZD۪_pr%}7fWt~/g\_Rͅ7ߗxejabberd-2.1.11/.git/objects/4c/0000775000000000000000000000000012240452476013030 5ustar ejabberd-2.1.11/.git/objects/4c/1b0a4a8629e77077e9c29b51a33b6b4f439a000000664000000000000000000000027012240230175020002 0ustar x1n!ESs-9 +E$h{?ө aL%je fZ3%MpP?Q 53͖9f`fEy 1 ~eQn>N]]ʡTt-p_dS Ӄ%u>G{YORgn  h\»h_ [ΐ*3?dkU{cآ/bejabberd-2.1.11/.git/objects/7b/0000775000000000000000000000000012240452476013032 5ustar ejabberd-2.1.11/.git/objects/7b/b5176b3a9b27cf921822a57fd47ba0b1beb47a0000664000000000000000000000030112240230175020271 0ustar x]Qn! DSVu%5mo_R-UƠ_//ELΏʘ,vzOR]0\]PDut*SjB&@"A\p.JAŴb&=$P'eHj>|yVz̆ ퟔQAtmpEyejabberd-2.1.11/.git/objects/29/0000775000000000000000000000000012240452476012754 5ustar ejabberd-2.1.11/.git/objects/29/c2edc6dd369676243dfe0c8e0b1fb5833d10ae0000664000000000000000000000044612240230175020315 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+Oy'oVwݿ/l PH+)LbPkŒON"}HIMLcn8bHg(x܂*OfxHRUN{s;x2ljEbnANj1i5;l16UEo.DIqQ2_:\t1>ͦ՚ْbnɿhLd0ޘsjw`ejabberd-2.1.11/.git/objects/29/f186ef161665c52bac88191f73bad5aef02a1d0000664000000000000000000000035012240230175020226 0ustar xMJ1FݚSd7 O%-"+Q]t7t'C:A}_&:d)Q?q + 5)]G'F&"=8h݁ 6[ejabberd-2.1.11/.git/objects/31/0000775000000000000000000000000012240452476012745 5ustar ejabberd-2.1.11/.git/objects/31/71011d9b44ea5da8c39d365d3f46f36fd6f6bc0000664000000000000000000000044612240230175020242 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1<ؗ4uAj7kL;7;.4U0'ґl>۳b MH-I-f8bǾ-&Tۦօ().Jf֓Fk˱;PtG D$??᣺[_j+Y.0L7WSv.ejabberd-2.1.11/.git/objects/8a/0000775000000000000000000000000012240452476013032 5ustar ejabberd-2.1.11/.git/objects/8a/a5158c7e450af8dea33479abeb62eec56296850000664000000000000000000000162512240230175020255 0ustar x+)JMU040`040031Qs fȲ~fj8KIwsw+rutusIMLcTh SWqez Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?@g?,9[+jhS[XP(6ҳsu`W cyKYmw=}?F/uq⼲}Fp%E% Y36<8QTX՚:1E[(%5-4odٵxw*[N=LIfQ1 O}5:`ɺIũ &V:۾/A,iRBM1Î/w)N_&CSRR,~o<|-|g<=]UrZ:؇ 9o^Ybt_)mchKrv~?|}֢k/(LLaEbnANj1(kqWVY۟~IL Ǥ&3/D/R+dvn5 3{bdae$0 (hQ0Rdv>9Os'`(/I,Ie73FDS7@9Ϭu>ļtkW]"q o}uI&@L7@ )fؔg\N4ֺ(>"!lw<y:7t% 2<^:Ѱ`.NP}\wނ vkU_^ȠM䊱LEQ*Pƈϗ66XN>ǧn*I[}]/^V ŵboV\Rd^`CMvc` \s:5-PE`Tb^7gD)Tͤ ejabberd-2.1.11/.git/objects/46/0000775000000000000000000000000012240452476012753 5ustar ejabberd-2.1.11/.git/objects/46/b54741564eb93039819e832f6a0524bbbd61270000664000000000000000000003426512240230175017610 0ustar xrW~{"L+ rܽDٖ[鉉 v(h(4 DO>>s @v7fgd:|e9<4z-=?dUo֛Zav~l~|S_f?!I5s>oh*E~w$y6&t1J.FFKc^I>[i:g$[d"&՚UG%`Yq|y4OU:P$].&YLjSRy,lhlЃl6D=[Cqd6Q6]OOvq5!`EӃ޼ XAD,h:ge Jm2_d}MqB?eQV$Dzd,獍/|^fK]^|jZt8*ujyanwU$R__l3?fdp44OuueQxӽf9L.\"Ƽydq5؄q//q~YTwxZm}{1NH;h^ԋ|9deVf?%I9}~6KZf;i5;f3i4u'y2|9MCqs>Ggl>-`|,$`>-6lu{Ҥ5Ngsi>>%?d7ټO%Fڑ޾!~bfW"/Q>yh%f'Go<_lM=v/F3teDjux4sq踥my~=KwBig24;.Y~ss}au}l8pyveQZ2n)\(-AіD2ptɞԖQ 0I^uە5mbq̤U?s9l6߿ZQY`Y˚iYQO+7Vw.o+?d L0~9*e6ӡ|b#v=#8"0ɇgp2̳Q!ok`ŭR|9%J>A8Av35_ǭ;@֐IY>/k[y 6eDd G1d.a'|xeo_8 Jt) ^XڬSDD%˙jt+" >>$fU^yEeiYv޺GWnO!YB٢Z:AЈ̤80I= _ ?g9&7I3v<_XHZ=ZĀKc.׺q5m:w5J;wĶu64A"5fDɏ?dףy>QOnltJyf!$ԎrJlq)$3\ijpvb9dEqp*p8 h~v<ݨڭ^6,s43;Ɓ=FI5bMOMOmW~ kvv$z1YmZ^v8 |HEcmvhhw~= 0#fVc_6E`M_e*pj_Eg"ܜ^s^iu ⭅b]brhQgtddq4pCNFT1 00XY<&֧ʗ!K>ZT /ŢG"$- j:d)P^cYh]H=W`!8czmIj݋poYU$.F>߯.ޢS@Ft4;KcpX'ۓNHzO(|iy5ih~2p:H~Z] v]k,-@*2 ΓA`s,r>!Xt% +TnIȲI.^~;Q֭ӯ?&q*[kXjZ^+.?[i82^Rܐ|If4AvƐjZƪO((J?S f5q S*(F%v`nRLOb(>EMO~qXj ,,F ["绍CA͚bRF\+Ħvg!Kn:czq Rd}܂mIW_E nFhE$BiwĊ?$HhC~$ұܑG *kW^+2w2.]e#_MTU|8@ 11'kQ 'o'VQ92 UzYfޑȑ?a-p&e:#fy֓gܗYwVH02?3*yǓYD A䪷Pc}Li\/ߝ?JL4g!2y Qo?jGF۶F &2E5F6\'}g f_vNH N͎jhX >{mZE€SsfQۗok)`ZՋEd1jF ,EF]\U^.؄U5<ov[5Fy?~l (·}A;ˍy`x U 5"SXPbTe3[FlR ZÄe#o o]PP)+>KCPf>a#]<`zlaӓ%'as``XmzGWn1&Ûi: x s5&Xr_幂t2sx.MFS~ O&E+p`MXJ /"hlA MaoѬ.1~ktf)>0K߾>ZQݪH]fg'/'&>I~PQdu(!? -Ky6 ܪ@9 e;ГX(KT78lvqTQ%4Xy+ Nlt 7U^R'0Hζ,N.+9/@!G/8Js0'YŘ/B-H]-ST䄓>i{[P:aV= S jS*Y>+BUVk 7zabteJň"E<hX= *N(}Cpqzn d;Hnxs?|G,Vyp0d|0Uk^VVYu1B^l l^?j6HQ/)bHyaxyN6~ShYފ5 W"x;~>+1DAg;oO[arSdc$Oxr9`񼨝$S_ecM~{9Dkp&~SelA)a,XW ^OciP926.=ʈ=>6> M-wM([,R{˻ʢ_l9wV SMG}2-xcUk5 xf~nob$k{R4:)~Q1h~Udd0^)ͺ{1Uުu߶+2LqgiSB-ͬ03_Z9N^PPԘglaKurC^<(_Ubу`]O w([^k_ot[0_v#r1 >x Ry&0g*SBF"CVF ZhwkP~`skO<}F+|iy6>o_&2R;04hʈ[! ս"GaHa2Ҥ0M-._ X7 2(GV|5x`LZEzM͛ܪ7(BI$_{}~~PQXx0W\# nY7HQr괋V hcyk%({`%pK Coi]F()ru|ije|TW+~8EsS+I6('L3 ]wY 3Yċt)dGCh+]ex~ g B,)VeP]ktlF;G&(*eK#6LM`L)ď#]h؈/9'_T#?N*~O/ml) 6JO/x#h- RX 6XɝLm#=^06bL)ѳe}mle);/;X#xTY={*y%[Gxĝ]Ê1&:²6F|F\}Kf5X Ev7ho_YNjuP޺wZo%DxL.BKLSm8X)TњRQ{kL)Ab 5 L)Wv"D ^aw@(.0)i全kb.DŻPRȒq"B$9F!^H:iT((sOORZAJib .լ`܊(y+#KP>T˜+A=wBҭM[69aMY5PAe$22Ur4UiqDFB3fgX|ȑVmh_/@]}O3rY32gĩS9~JlNIu?ot]e@d; <& g`oG@1.(rx"GGF٠|ORxêʬU9%<`l%= YͻA:PD q=C"0ZѨNtdoh84~lh>wkblmv)5[AtUJF~\F3ʱjcj碘p[ cņ1=5@i_ɞ!RB 9hCXGQqG|?bw2!A^yDKO-VkverYZvh۵\:@ x\vNM^BV-gS_uv2[Cx+;PAZ,)'+4,b+\M-Sĕk/<m7 cۚc{ l8;((ñc";*e*X]L(#뫃 ZL9(o*)'TMYjhZ ͽK^ a؝h|$%7| S>*"&=֞yW̢Y1/U=ODvbEƧx)=;IfxG:'Hš\@)^a)M%S=S^-Zgd ʱDmLzk憏1CX|oE,j$xVNpc;U:VEٿx&0S>Hߌ;^h4њ⨒F.s1m2VYfvSr7rkW0[NġL|Qϳ>&- fOvY _ͭzvxOW*Y0dלM@r"jy Orpj7 4GRt:W aU8$Cƹ#.(~.ML~P"1s«Jfb0v/$& __pU/7N_uGeSCs$3xIZGn6f:$#.zT@*>-7]-T Ø`q'Ԗ;WPLA7dyJ𾼆KEQ=k݋j[H~k޽z_T#> gQNMy_~J*Y$!)z.\vΠQƶB"כϭz앎jL$ l NO])Kg/C26`Q40ϸqobjfnThɌT^yj6< J( 2X#UmItI fC\>Ԃ UԡYx_۰hOKچds$@ΠS* غЯ$y^;p>RlMyB @F:WM@MlNA2ݘR"P'&HԞUSTh{x%x^ks‚clÕ )U͚NC HxQT3e~܋gG$w %$Ml['r`nHy[^ȊX"]PPy&N,X:u{$j# D>Fǣ.=Ʀ-wbKhF탲[V=G1Dz{A<_LIQ0RɿFk5|F$\Z6rVmV dW,[l^mE荘ݪrF;O -< +Z (o%toQ'SEQPB\8馸@;n-mx/rnvB<( z~c0";( =sKYVyV`cK%UB-.3i͆YcL CpY*0sktl:0#8"BǥTv:7]A;Zupۦ쪑h/Fl,WGLA+6V s< n)\_t2"+3y^;v>VygSݡpO^8Z,Ww@WbuVG ]EbQo3-;ȒROLY`RjZ޶.KaYW %l[ۅó|Pm3 x~`s]6 ' *d _hkM[U&h2Z ,g zT$x~7qh5ai7e9kzH&YGurxwF+S EWwYè U-+J:f%6R C ]XT f*0nߛ $xȔ&Չ?gЦKQ0l:[aae;*bݡ24c߳Qk|ۓ/85\ƼJY˪ޑʯS|^#K N%`n٣)F(1[Sd GralwX3GL7uIwHeI4ϭAd?^qpDQVx'~%HoyEXnV[- tym9M9*@.bذSlojȈ6F&_͆2[LH+F E ѕ[}b & !+WxK8jn*+Z`,(&H&AAb\m{Ns \ũZ\PeYv DkjJP\Usu+Pxn8^#p('. Ѹ ߑh=Jeϩy/o\tW?4)"T }V>_q~;>FמS^ 7+Y?UV!RWRv,phmk/pÜFZ&(h_@_~y۪Nb`/NCZ:[Ys18\)ʸz,',01H3hBTŽKO>{jC_pc|b="u}'<á$0!g}T@^4DŽ R6-iQMC!Z|™AA1@W:XYj .! ֧Dv*UV3+U>̈́BZ)-W( b%nK!ɞ[dPzxATGi;pP6__uW'2Xb $շz`VwYj*w+Jiva`(w#!pXҭ̞$Qsn/"]0ҨAGbFJj(u0m4eUeYt*ʦq2#G|Sؠ!U \-2WfJYLAq<>s4SV-> G!~z?Wt[ Usy_ W4FnE4d/>>η;S0l9^wo+>,JW$in$d(H^uMB;xoq<,$UW͇[*-ܦ5%K0ՆW1 `Nʹj/h'*P9~da}R8^KkpZX^͕1KV_oVzh9&ȉțrHK}CXߵY6+qvG>?KٸeP5s[7f(g"B)!)Dؕ38s \kCDi(^(3qHc5e17)[yei.9|Mdǹ٨0ZRm|lI/vl]dl5QLw0&‚Hv0%LU梊3 @ħ9cnuE|;,:/HWi"hgo~8{+Z VjR\v[eugc圀3Ъᒭ*qL֊'Qr=bp7E8f/|AZյ\qDv0UYB"c *e0g(1Tgه'x={ھ Zt)v;)n=4i&\7|4zQ? V}|ó2J` EFjK5`l4nt%eAPys-K|=gzo+UV۝=\S;la%Ƀˎln!Pm -b6X(,nМ?%PWg)>;xesB&%S |Aج r]qgUy( MkZ3V.'EUy{,rShR %ٳ {n~$78d] NE&G23t3f0檡}(8ӬmenteU,"G jig)Ī/6QۧPI`D1[dKt"r/ߘA\0]8d2ݠ#T5cnq s-i1z2B: tW{.I2foq{;_u-#+H@u{M]D-j w$4VR`BM֑o{ QsAh}ʮMmwWT}lZĵ~j[NEGKϤx{s8UNo q1+NGmI(ܢueߋE=~ފOkJ++U 9-F|(| }TƨDm7:*RA%"(RӕTP*U`>uԨZP?T-׿79ͣq:Opٚ:vAnwdkng`BVNyBQүS{MbG7볗yݛg-^}tӱU$!oj=DF/R⯘ѧ#UEDCǭ&Qd|u;<DO}-8i)&zOG;b0MF[nVE$(AҼat6]ӵ|p-Q'*a[R[@h[VtOebBW2g1,F$pSe,g3ǩ%?¾C, tcER-Z6G.:,ad8A^:/ 0Z~QxXOg}nIbTiEP|5$&]zbV`L zk56UG҇d}Gl};`W _Rklկ7Z U< Յvb4*uIo˂I̪6ddmh"hTF< 1oC#֨˨zRݱQ=&s ;1]kqu)ڬSN)^{Hi@H@Qwm:+I2X%-UNIb̮9Czr~XkKB Tq3"[U檭iQenr:6N3*Gu:l%YO-ha P";B]q>z@X=_ww24VkU ͧb'ReF%Afl ʧVT<€9sbas83Iradi~2ЖQԖ ݙᘆʙUbÉRw&rM=s($]&x;&m',6cs럐6d- c8ӹ0/9je&9ڌSZP(UJDC1H9 ꧲I c&}?(PT+n Ұ\7lP KL':Ur*찺 +U!wxRYc)ꭼ\gA!3~:lXBBM}?%{]^BƐk& eH[ڗ;-OCV!(AR 6_"vTXgw4Gߟ2%np,]8ll[؁./D +(k t-Yhomb[0)Pv:cl<~dejabberd-2.1.11/.git/objects/c0/0000775000000000000000000000000012240452476013024 5ustar ejabberd-2.1.11/.git/objects/c0/8e6091b3de910d6c182be062bcb91540bf1f8c0000664000000000000000000000025512240230175020216 0ustar xj0S+?ZY/CW}J?OH7L^0~C,6m*MR`ƨ.q.$1%LؑmYy}SFUg^k1YR 8Eup:M__!1CVjl}6Qo(Mejabberd-2.1.11/.git/objects/c0/1b75a6392cabed6a77c3ad4fa3c7c207214dd60000664000000000000000000000162512240230175020354 0ustar x+)JMU040`040031Qs fȲ~fj8KIwsw+rutusIMLcTh SWqez Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?A'pf_gU ܴ[F](? QnmgN] "/-3At/fz~%E9 Jߍ^yeJJ *23JfFm6ypګ5ubv|)TQJjZbiN c7bɲkZ0U巜z̢b"j|uUsuS"L|u}9^kw}YҤb__rST3ګ7Lʧf%&%Y0l7xZl/32yztӱrlS% V^E&_PxR|~/Š܂bQ>䭲?oITMf^f^ CWNjZ-;Df¬+.IaPƣ`\ȪX}rN!Q_X 1oRgnvrY7}PEy@%믺ΧE@L @n3*2R^Ͱ)i6uQ|*TE>Cƻٲx1totP+ K@extan#]!$5E 8֪,vAc'T/ml4 }O*075U(*er-6*^@8đE% Z|wȼ&:?@(I 0t]wEukXQq[6/A0ņ@o܉ +,Rjoejabberd-2.1.11/.git/objects/11/0000775000000000000000000000000012240452476012743 5ustar ejabberd-2.1.11/.git/objects/11/9ba312536cc93221324a38ef9da3309dab73d80000664000000000000000000000027312240230175017776 0ustar xKN!Pלi&1ƕb iZN<#x<xēH b Fʓ `8Ӥ%V5%;+Y||UAۘfr[uq^{:^ƼI h2JwdoՏ۶{1ku%ĹɁk܉IȃVOejabberd-2.1.11/.git/objects/dd/0000775000000000000000000000000012240452476013111 5ustar ejabberd-2.1.11/.git/objects/dd/105cd771498f8e63396f29fc8be9bba84dc0f30000664000000000000000000000041112240230175020337 0ustar xMJ0`YbI6 CgH\@ܴ6){\9|縼@yCRr8;a; V+/0㠽g-4WALrg4ޘ~Ra#\5J6QL=7gx\VԮV\#rZIa&s~؄VNaɭ@Bufc'}<Ö W)t =wxb7hGkw%׎mܖ+ &Pƨ}/r~ejabberd-2.1.11/.git/objects/3a/0000775000000000000000000000000012240452476013025 5ustar ejabberd-2.1.11/.git/objects/3a/320ecc2f943aa9d196d4a32163013a1048288e0000664000000000000000000000162512240230175017711 0ustar x+)JMU040`040031Qs fXbsyWmK|,Xj*|U rutusIMLcTh SWqez Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?@g?,9[+jhS[XP(6ҳsu`W cyKYmw=}?F/uq⼲}Fp%E% Y36<8QTX՚:1E[(%5-4odٵxw*[N=LIfQ1 O}5:`ɺIũ &V:۾/A,iRBM1Î/w)N_&CSRR,~o<|-|g<=]UrZ:؇ 9o^Ybt_)mchKrv~?|}֢k/(LLaEbnANj1(kqWVY۟~IL Ǥ&3/D/R+dvn5 3{bdae$0 (hQ0Rdv>9Os'`(/I,Ie73FDS7@9Ϭu>ļtkW]"q o}uI&@L7@ )fؔg\N4ֺ(>"!lw<y:7t% 2<^:Ѱ`.NP}\wނ vkU_^ȠM䊱LEQ*Pƈϗ66XN>ǧn*I[}]/^V ŵboV\Rd^`CMvc` \s:5-PE`Tb^7gD)Tejabberd-2.1.11/.git/objects/98/0000775000000000000000000000000012240452476012762 5ustar ejabberd-2.1.11/.git/objects/98/4e8db39de0f186416637af3d4af9c4e0f62c7b0000664000000000000000000000162312240230175020260 0ustar x+)JMU040`040031Qs fм.&Nbr?ȵ:깤&e&1h5<}VW` gg*,/-JNe0 }o ˻j à C]6ުqoJi3;'g$楧3+8oʱI6dW S[XP(6ҳsu`W cyKYmw=}?oVZp\Mp%E% Y36<8QTX՚:1E[(%5-4odٵxw*[N=LIfQ1 O}5:`ɺIũ &V:۾/A,iRBM1Î/w)N_&CSRR,~o<|-|g<=]UrZ:؇ 9o^Ybt_)mchKrn[-؉3llhbVSX[Z ZܕU_S1,KaT ݩ[MBeh̞Yuy%99 ;x+YO 5"KKRk3]oU-PEy@%믺ΧE@L @n3*B״y쎫v6BU3r xٙjMP& P+ K@eLVÇó3~Mh:;IMQ.;oj/ ]dP&r (@OG8uGFsSSRPj\^yW$A5G'e30.k-"\l$3+fbuuyaGoټ`9 JYl ̝"1ejabberd-2.1.11/.git/objects/bf/0000775000000000000000000000000012240452476013111 5ustar ejabberd-2.1.11/.git/objects/bf/e1faa3c8bb67642331925df54606f94b3e6f070000664000000000000000000000026612240230175020164 0ustar xMj0@uˆPj1Ҍ,#YGK os0ޒfJ2,ѭƐ≃ۄv:8eۤMʘcnmv#P fyQJ(~NJY  7q|k9kԥ`8S~d٘Sejabberd-2.1.11/.git/objects/88/0000775000000000000000000000000012240452476012761 5ustar ejabberd-2.1.11/.git/objects/88/a49d26a058c5f23efb6b7f8e08f5679045898d0000664000000000000000000000026012240230175020060 0ustar x]An1E)z&DZ!A&HQwh\[p")oM&Xp3;%ʻtUJHkxЂ6#}YD둘; Np7`=QWPM; NɃo+Β:\c2S !˃ jejabberd-2.1.11/.git/objects/4a/0000775000000000000000000000000012240452476013026 5ustar ejabberd-2.1.11/.git/objects/4a/ab80b28b5079cfba5bf0a5d9ac66bc7c2d87a70000664000000000000000000000044612240230175020530 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+Oy'oVwݿ/l PH+)LbPkŒON"}HIMLc1ଠyjR5*OfxHRUN{s;x2ljEbnANj1i5;l16UEo.DIqQ2_:\t1>ͦ՚ْbnɿhLd0ޘsjFvejabberd-2.1.11/.git/objects/d3/0000775000000000000000000000000012240452476013030 5ustar ejabberd-2.1.11/.git/objects/d3/a5070a2f654f678a65784aa9373be7ba33005e0000664000000000000000000000024412240230175020010 0ustar xK 0@]d&6WzIgl#1xXui`? N#E!! KL)pGU hp *_XlɊͥ]k q~eSo88D8E4磰@:i30qJ.ejabberd-2.1.11/.git/objects/05/0000775000000000000000000000000012240452476012746 5ustar ejabberd-2.1.11/.git/objects/05/7ad87d95f95be6d16803713a870ee3e68fffb70000664000000000000000000000136712240230175020217 0ustar xT]o0+ڤiu[S`b oc4lg;Csݼ9 GK¨)]ORYW}W"dKFݣ D1( vZͺD-(%-Ek@c4l򜼪6kWz6XPVZ"f%J[VSiۦAAЫ;ĪҰ.(:UU #Nߑy :IR J^%EvFVL # +x"b|&c1*'K1>4N&xO6+xKlUNMNw92\!-id0֕L=[ WJ\U66yf͍D9Ɇ5"}uFrSH(,0BٚS"\鵅6MtHbxhQWYfG"z?lh0*O~>H3D<ư$cp2].b.e7 %)PņQ"eSYv1yv<^ ϭ@+mf$N"+4fiLd'E6̦ɻ_E6Oyr/.1໙cfNGY:0B⿪^~MRMH||Z+da11^6,YȞl@EX ƴ||3a~5h8. 'IN3H:\h4Л2ԓu_Jt-6wlU:All"l &OM6 f#>Zۗ'/R2_Er=NqΠk4G6y")fu<]6rϐso=t4i3?f{xYus<и% tj*ONEivT\.4ڍhl9yoˋT4ڝʐl~Im90#)exnmW~:hbNy3ji`>O1~:fWt2N1~x V%mpVڙ߮$Df<wi^>cLGwe<ϳI䕢 v+}]Mw| WHkNr, C})=^Al$SsC,~9y0Ta/8g#ʞ //^ $ǵWR|_,I67ے(l4i4AhnӸQ(,je< J>7ZE*41HdX޷ZV){%ؔtzQes}81x?y?&Hx~ncot~ jD3%Gt/=j٨myXlyϊ|5mp'kZwځaZy_^4Zl" lLم]Ž#O߾qh,[[S|A=@9D!HLLVzuB WDjY΀C*{/|2W2ެx~Xoݣ+z6k̯YB٢Z:aИ̤$3 $/@[` J3Af4_XHZ=ZĀK#.׺q6t9N(_驹MF,N߶gspF<} "tk!b1ɤRSH}V*$P@1Q|Fo4IK]FՒt:.. ̳ 8s V;T&T[h mN0k [Aryt?JT*3>[~ okv;Hy=D,Xvrn>΅5/Rd.1F{߻e7H٩wCQs>8u;YTA|&C?;d) 4ބۿzbȓ;Y?d -NKIWY1SOrNa;WV&NUl`"ذCpcJw>_!@ԞSTg<V{*T b?;S!ez=~x0 rDiKqܙ]$5}K}9_psjxyB9tKy>q VCEj pG y5. Y)@"Ȋ4??e[D~bl'k_=~=,&O5Μ[օk3&6[ Qi|O(h"qw5~u W"2bw')aF\B4:ٙgBBKL@YMCܧV/q9q]#pl;u0D8O@oz_@pk`ѕ0P &I EMO~8YhŔ# %H B (o8۟6!6k΋g 7^!6l2_Btk~*&ek I¬Mr 7r>RBab'a.X^wDr=Axϩ" 4R 3~]taDu"Lv*$8䅰h,[mZqCZӞENBsOU=ZɊ\)YI7)'+RBJm2rzrs$}h@x$oԭϏChOQ @©8؃zUY8^yM8%ytSH Kܨ%HOGm/a=@~mee7{aj-gTt' BU Uov6"_;>=ghQBXe x_ԉăcM2dkl9&=J?@*; ";j6;%g˳byVGg8w&($pgRe͢/( S1hubԌXLگY8<\0,a I(kvZ1Fy?~d++Po9EN#E;'(4.=\="l@La#CQmjlQ/rЂ%l ,}ex IYѥR C峔b8KSc6(2 ]Ҵ-_6 ;>yY?64IJ,=$(55LʡQzв'$iW![HC| _zdkf1e1o {J8hvqT(IψuJ @ 아Wvb:*Z)K^Tn$GIg'\ٗOa#@W`WC89֪VbBJH8)XrI_=-(\0Q;_VxMb)t@AZ,NXX~%[*M7i=7O9 RU˲Cy@bLcƲD>;'Vf #_ar8ix\ jLm,hzO&z^#ܵM#̬1߮F= O^9hWs[[bgGy*mz , ۤRDe_S+DAg;oO[&lIxhusyQ;e%@InjT%RH˿sѡ u,E@ *\S$kY *A/)g,Ҝrv)e l\{{|l}Q QXjm7wE q 'vDכP-dF[gƪx3k"Av̞X izdS ?b"$Ji݋V]_a;Kjame5/jQ::cK _: qx Sy&(g*SBF"CVF ZhkPy`skO<F+|iy6>o_dv4<7`hҔ2C4{o5E”b(,Ia|S\7ñn dP:tlj-/Nj*7UoPc;H|_f 0-,0y aF&nJxiдl-NP N@@ۇ 8- H|QQRjZ=ԌiT((sO_d#6h9]]Rœ+A=wBҭM[69 `M5PAe$22Ur4UiqDfB3fguX|ȑVh_/@]~]n3Rߩ ?xhv6RP'pTΤ:KH3w &ύ^3Se0ķ` BQMp^ f9 wΧ_*WXaUe֪ 0UtXʞ_N,U Y(^fC.ĈL5Ntdoh42~lǫgk䩙blmv!5[AtUJƅ~\Fʱjcj7p[Ɍcņ1CSD"m )2nNV.`/̪6;n>eC&D;ZV (3*岠ݵĝ{)бktb76윚,Ͻ*"&=FZ554|FF$h |U4;dXqO<g7*Ϭ؇}?,8ԛk tjET2egt ͽZ| cٯVL3魙>X+ߊYH񄭜 p\clQ+H&_q )7-Lϫ{f&- fOvY _ͭzvpOW8*YɯdM@r"jy Orpb7J 4GRt>W aݳU̸$Cƹ#)~.ML~P"91s«Jfbm@;CU4v(TD3\ 1cߴ4of_h;c,лR?xP!"AixJ8-Ú /ctׇ(A7a;\iͳk"nvX뛶v,Fr "c 3FTd 00jhzr=IKPbwvLd{E ?Zŧ8c;!V^YHZ wLmYszd/ ?!#V+T5\Ԃ UԡYx_ǰh_ 5ꗋΑ9L`H`B>;5Wॢ 9y@^V?eߧj|J+PC3o]xVmEI=YM_OTҙ}NZ'oA~ˈFD-4 Pd"Hb6AlZUħݐmkaUXvqQPF<:?YWq@uj`eFqIsCi_wtiҭɹhABP<8Le![1eT2>%)!퀬(D)?+]yuXS|q9I`X$SLkD_j~$#8 Pɍ uPٚ@bîJ@(G0ceS76ZJ9uE AKd;-K]c_4cUdN٬jtLv]jhWB+TװR X:n0jEcEzQux].ܕp:`ā".cNo566\:*g%4Uف^H>QT3e~܋gW$w &~#9|<-dx/jsdEa,au)l 0eJUjy,=e]aέnnrNa64͙gt$ܠૐ)|M䢕"7seU?=&b˛VGIpO jwZ7k`kzm q!DX#wLC^:`>@ƞgA`_R22 5 a6Y (&*= rZ G"ǵA0O +C 2`;'\$`5{]n)*v,S=Q h¦h lPIv`uڞs_ Մ@;LL|8kzH&YWurywF+S EWwè U-+J:f%R C ]T f*0nߛ&x6Ȕ&Չ?gҦCQ0l:Gaae;*z@_1٨=?ɗrrgVbs^ReUSHWߊ) >L1%Hpd4є?w#JĘscR_?y;x=cy6֌U'okYtw=a-skُxܰ5Se*^<_ [F0[AF]^[Nk P9*69;oydD VS#f?u'# E ѕ&LKt$K^2㵇 ,MS{NV +`A1FmbnĘstX[r8,nJ窆*-˪P.{<_&O^KǜUkTj%B"\GGK\Ns5:rci.{aVޣt[YŃV)wnJ*.Ƌ>)y/1>6|nxP[zq9),yG$Y X82i˞P+ePK-6ߊ|c5T *pLO[PLɐodx)! {D 뒧( Br Q:yf.H=،@֧qڻǩ?7yL!h!qg@I2^-`yRdYe(:2XjMT0V4 k]tB3ރf{K6#qp/G&9Ȋ񀨎vl]?딯n*yzWHo|"}UU|/T0M+ vk{7B e+z`I9Fb)U i{(ZКF790qVP`bi4۪˲UC1d.Gk+ACd3h5Zeo"(-}vxU7% |>hl"噊Ffys/bnޡՂ+@P^Alй;bLxdP- uӫXwЉ%xK*yҐ8xn>C£G?X+ªsy_ W4FnE4d/>?ηwc`rV;|+YꕮHD =8"ym:ǻe!r4|%R-m:'ZXRiƾj9&̩VD*Ǐ,o%a VKګR#rk#J/q~&p"r"򦽽~(㵺@ڇ5+qvG>?Kٸ 75s[f(t"BZ !%)Dؕ;8Xs^gkCDi8ŝ^-/HWeXp5Ƴ7ߟe-z5PnZXQLíiR2̋T:3rNh8r@{d>J+f$+ӧo1|$_l.й'՗ьR!/r0Hzz*/E("??yM"#=.94ᨈ7r1LW:.L>d7U "3Z=5r%m F@##T @7pV%IL-yo^,J+&P~S "r65;kp\3Lj &$lָl5/qRٵ6-nh%k_m6۾qbjD3E5.scjNME8T&̓zmٲA_.4p=ۆI?uEt]^ОŴt5p lk8q+Q|;/5d6KUjv;ݢ"ᢦ0wb[چ{?1NU*%XԩMAU\Wvb4*uIo˂I܄̮7ddoh"hTF<+:M vc9c:9wGHQ?Q;zIc=a7+{m .U>.űX}J)eupupw26蝌CV!(AR 6"vT2Wh5=Л|˔|NGpfv?Nw x$MXA[2idTZ\N…w89]ṿ;%r\=nG"6j7*Pk&E494v~YNtݑX&^i /~$\9J20rAw}ʎ]zLMnejabberd-2.1.11/.git/objects/a3/0000775000000000000000000000000012240452476013025 5ustar ejabberd-2.1.11/.git/objects/a3/c8f0dce9c4b4a9364c3bbc11710a10956d190f0000664000000000000000000000040112240230175020203 0ustar xKN1DY-!Eߌ#!o$@ݓp|@zQUyrPWT:9ZG(2w>u]V ;ڂB]!zD-V֯2hBS.ɩMl< 9qX8 pل=yGKnbVgM|KvR 4!>h9gهQqyO1nYqY6M,] /mFdYdٻӳx2:#[\wF;_17Q6/ WuNxIY?Fϒa>=_,>1g6<-Lg2ga6_AE@y>g^yvR|wⒷ "NHPcIO/uh0dE\ÃF{r%&3A/O|3}I1,s~xy]6W fEe#%g76HXyz%g]6EcK4nZ_'h\Lb9ͯY^l~΋FɷeV{mB4u+Iy,} ofټ޾$:̥2V膕ߺ=R]`yc~Vl`Gh|r>s#Ǖd^sɶV&Ery0 wI9t~3鴞/$o/OA3j4Iu=8$_5Z~a0 |Mq<- _WEmꝸz_fo^*2ot{SZnER=,YΞx?c.|>O[k, m)3 $D~Xa΋z/Ì-zէ"JMAݣv{[X)4_$4K7\Lo|̚Ư  @!!@>fswv{VcK;lcCAu _FX9X'G0 ~E̅R^2М~.Nߒev9ɦ{[ROYFOF3}muw.?L 62;t\2Uݾ4=_^`w esɾvGo<4[? ٭XI^}<(y{.k#QOS;hGdG;@p~k8xjuxח5dO\x@fE S`/.Хw F%n $fU^y4^1{a@+v,R!xlQ-Gi[hWfގ=IEh’l>dL`e_Xٻzk6֪[njmr|q)I Uo^)ulHLI+KN^6X a.z-^bajr6F$|s./8$bT <.8fQ})mrɓ!9*5a?dy>QO.l||f[絚| P;8 3=\@XYQ/5Uk5z}Q4z1iʻ[G;M^laZhfrm,a/)QR 6榧榧63LX '>Oe$,ۮA.G V8ح}t j|2[۾6jEIߡ(Dلݣ&wk9$kUtJ-9Nc?,яy|g=lNua˄'Ֆ\CnN0kf˔ϞǮO Beg^WE6HjCid͂m+GǹfXE*ÐlE#i5F{^Wd7h٩%c(ҽDKoOOOH6쐥/xNtX\/~~o?E^ }r1 L8-s_|XO}<nP!kxǷtYf-m6 0lyl!۱uKw>^!@=lQm(,[Tmɞ~~?JK;S!ez=x!6LGqމsy> `M_u*pj_Dzg"< ~}!@:[ <+b5Hx8`#S͞`("yXb'#2_N06jog-v^9oE9˫ɓF9RƧ"h]I-UBpT^Fy `!*= Q$H\+]|_޲Ȉ=ߝ|R& '$R _ ջfq6 'O^r{ Rlku ?*Fs<`s,r>Z!~ +Tn{߸~WD\g6֦P6?q*K[Xj]qؕ}t v4pwT~l_mcmܐ"=Ft|L $ƪO((J?o]-"u-G0*pE3=XH C N,4b# V\AAP-g!İUfyqUE"\ ԦvMfKn{411Hek I¬Mr 7rם}W".s>by# “,OIȎG}=hʱ!B)q.RtB3I^ͮeamWܐV wKuZ-dErdEJH)Ev#7-u#P.:*H9{Po/^j붂uU:;SgK7%< aῥnjHNGm/a=@~mI_E }~ $XlъHdq+ܒ,O.tTRRHoO~q&~g! x_׊ąeM2d)˲r(~T}AD tjxf4lyV,jl6ZE€S3me͢/_רS1ubԌXLoY8\0,a)I(kx|9*ak+M}Ӯ@1 ZX*AWhAPD@|꽟mP! CQmjlQ/rЂ%`ԾQ2uA@ep)ơYJ1lvo=FJ iyU f:B3)]} VeUmXDW!pt&ybOoT ."i6Y8llQ&S~ϰ et2N.9bD 1C6{b7hԃ]{k( +D^$疯kf}x^m\Ln+[ ՝*md޼|v|~lh;(XzHPj~5j C~W8ge)AӮBs Q_z|)A,LuN)z〪(Qj]Nf/O^pl SAP~bɋ Í(lbGr=B]_pQJɫs0'-لB-H]-RT䄓>i{[puDI}|Y5A:תf/´An?9fҚ /JŘ"E<9z0;CnQNl빁O`FۧIuX5]af5Ȍv5VG㰿tWߪ;$&!?H ,Nfnin[g+ZE<R'?)\4,o mc+QV<;[ xf՝7'-_HpuSdD'^K1]26.=ʈ=>6pq9jS!K-qS*{o=`!x &]9”z1JhkY*ތHl]?7A1= dq_TL#OzF^LdDLۤ"w6%j p_885۝uEyƖƽ _& uxjωE)}pEf"w橭p]Rga*τS@_T4sC7HDbhBJalp_/9oYרߟx,+dcqTq D9y@ހASF|p i[Uf&Ca!M k]u rxԡ `kWny{K[ꦊzƍܪ7(q$_yu?@`h?[ CDY`bu\q0MtDxy;I hcyK= =ˀ-͗ٿH%EvC|ڶy'>շ?&9 S+I6(Гb=#hH1%A 9#EH"Aą?ioK$,C0n8X:fIMo"*A8w:Ɣ;G&[EpԲ&Xm;@fJH80/l3 }Y#>-}FC)0 Ճ#;p_Ǚ;紅H/ș2Q!EaMq^ f9 wΧ_(WXaUe֪ 0U8Cb+{~=QEټ3 El .w٪[3>so-ݚ6yj;[]HrV({q1c5Lrlxکܖf0#@naLF)شzI3vuzv7[rAŬfҸ #v萠c?xDb8@(ZBPfٕUeAw^쥰C.q n윚,yDF862n|8[[g'o5HyW"eI=iƳE@"j̕lj0EA] kkŗYy7tl[sly gsEba zppvpDtG|Z@t% Lu`>%#"S$%ԫI>mU@ m5.S wc vۻ{! q4OnƻoWLznVa1 왍-5_ΓFD"6I*_)h!`'.V_j|[eGu8Njzs==O" Ki*3b:czh ʱW\+ cX+ߊYH񆭜ap lkq=; #R$WpofiByUFkƋJ_ x[E`n<*+ n_$e?B <(  lnmm{nRlnă_aeTKgK'?^Jr6uR R\a&a6Lo8*i Do 9W aV8Kƹ#)~.ML~P"Y1s«Jfb0v/<حP pԔ?%S7ſ/48>C>:pT@^:uHfd{PZ$CXO{-Ú /L'|A0J aW˵HGh;i )mz5LKk l8[OMeN(Ռ#0?_wCO=XuqGnlQ 7W\t-gPq7d'x,$L-; v,8ebnz`G|Q+c*A65\%- ;p6cA|$VgoB鯌)T@*pp3('PƎ/ ?AvIHz+`Hs+i(&kE,S@ H'X`LOp~JY:z.Jۀ!:Gwں\ρChjYa qĶQ%3PyᛎG o(Y(hxae:Zk+]NTNk6ĥ{t֤1I (?27WmC̓j 嚪U5~}`MyV;p>=x聨SXM1kcmŊSTT>=VU2]^q̽7~ƫ$BXnHj gl?L< ܔ)le=ihR}c*28y 𓕘FԒ$9<( MD)vl|v"FkVM߾wCvVٲnVѲ|glt4UwIНɺSc/3P ZR6(}tkr$ZFσ'2SYHV 16s5B\OiJ@#w[ + 5e*gʏJy@]<_\gRr~zfR4 #zTR_&ل*gB7*tjbTvB1aGDNOMMXԞUSTh{xŒӋN z,Riž6',h 1f=\0HYլi+DY;P>pY\@]ÚG0J |u0B"y{aQ2E.kr4^t0rw$"\> s0"óݕ]SjllPt"T*Jo}TuBz!@GS8W1cq/N694?"Ը) mr'r`n y[^ȊXʢ6׹\MzY./ױtj HԔ&3JH G]{BM[D^+8ZeS_M1LN]һ=?mcL:2!;'EulJ5ZX!Vpi19 o;,ڬ4KW/yXؖѽ(,1~yjnA1Pt:[н}HlLE] C qYㄛqk''o{sհJپ": =h7( ٱ[U&FEh!@Mg zT,q uNRۛ}l8@v5ai7e9kMR+h劌}u7:iPSIY 4fVj63qlBE3 4k:lӄ:Gp @?){6%Ͱ02LsxXnw/lTƺ?ɗrpgb慂`Jl̫Tzmշbʂ|L| i.,=,`TY?uN|,W~jȈ6F&_F2[LH+F eV+W(&LCt6%KDxK8Jz]crj&eɀV8X 4m+@ucvianra8U+,B};0>x-cr?VQ|,8*j\jJw2>LB'ZQN,oj:!'=Zxm=H95xԒ" &*S(7ձE]O/(Š8ͮ`J!7p߿ϗdΠ(l/}1,U X=I-ˇ k{tk֢(]PSޮ-Eʾ0m 7sѹOd/b蓒!cvƣHU5 crKP8sV|!8! {iڲg1h j[of )axBev8v2'm(&t.L#$aa]t 2p(d1 L+YU9M~h6Qqԃh d}!ٝА?Nc!DC$4pfPs V^ƫe,U,K ^@RSmbIjEʧRh^Ma D 7-!bGv^ M`|c v4eX|uR/ԇb 4[=0ҝoVOB422dCh_H4tZq64QsHjJNv5qω)6/á*:XXzY]eQ8~26p<}X)lruxf# JKg],8M9wϹ}VXmnE^ _܊C93V٠sw Z):)Ę&|{X[@1DWXwЉ%xM*y!v*|E[|@Cc~ï@ ^B!~i݊hț^}|oA ϳx ߽w ߘfW4QbaU4&@Qb8CA*pKR*c `I }լsLS]Pr?47avI^͕1K&V_/VzxyuE?67Cw4kro8W"6  |/uf@]o=}?@TD_W>!乄>0rsű1D[?YwC)ks#ʝ:zP*E.t%v<qn6[C)u6>]܂Y;.~ @(;l baA$;YsQř_ SQ1">ŝ^-:/hWi"hg?}w/ch'X׫IRjaecBn=O#OQd\z<סA LsZ5>Q9=\U[#NZ7$_ Z~C\h)~9IY_>]]E'*@EVe D-M=FRea?+2D^hmUJ,l"wrK>_˟ +B>>YTo~% "#%ˡCذTd;YlJ҃ZD|3]W=*`s۞{Py}gD0BA a"B-b6X(,nМ?%PWg>;xesB&%S |A|:>PϪhP| _<3VD""Y3E?o{ͦ+3/;.pw5HM"YJMI=6nC$Wxʎ.4pA5)e{<5)tqK#y=9ț .KU{ĬṬf))Qzn;ٵgjrKgqԙ-V8$o_UF,UZܦJq@#Mrlx2Y%Xս=TV\b>=un*\/Ɣ]\jRnBvmI(t@b{QO<}ؚҊJBFˆO]X1O h JԆxدCqFVV*D6#ERbst%{*|BDr*0o:jZYP?T-׿79ͣ%CdXz^n78mMv&$n唑^\-rֱTsIhʞ1x6xu/o_+ W_t"hd8DHZO$~,ы4b##W17|`W{4lN8a`TQxzpkI6OPUN6{8)h/5r*f_At FM#Vb+O׆F\mIo^#=>?uEt(]VОŰt5p 5MyJ 7ΜbVxH Hҍ )kl9вQ?w3!# y1VXg_ i8{tv˙TN*&O%џv:9$1УMUs'!d8;H1AeTT Q w~ U5V,(4cޜܯ8]MK@))Czqװ2dO<ݸ\rdTu ]zKt'iuӐ 7e2x3= A+&PO`ꕕzvGQnzyxlS'݅XA͖4"$MXA[2idTZN D:Cy4c$[Α~&J. "݆vZ?9#1/=5'?Eq˩U2rRw (? QnmgN] "/-3At/fz~%E9 Jߍ^yeJJ *23JfFm6ypګ5ubv|)TQJjZbiN c7bɲkZ0U巜z̢b"j|uUsuS"L|u}9^kw}YҤb__rST3ګ7Lʧf%&%Y0l7xZl/32yztӱrlS% V^E&_PxR|~/Š܂bQ>䭲?oITMf^f^ CWNjZ-;Df¬+.IaPƣ`\ȪX}rN!Q_X 1oRgnvrY7}PEy@%믺ΧE@L @n3*D\̟t>Ǚ*2͖}ǃ@y|OZQ_\r. v{q )ex-QmVeᵋ D;Tl|ic変_|PBQ)(P/kUe}!,N.,()f`8\j[,EV=4jGI*0fV8+\߲yUT I,6zsNTXaR{Keejabberd-2.1.11/.git/objects/9d/4ace1e12d1e37389e80c8d23413f7c3839d6fb0000664000000000000000000003164312240230175020175 0ustar xrGw_E=d' r=DV$kE㎉ j(4 Dw^>9~@?;3de<yɬqqt-==fdl7Y[yQ9OOY̆Y>d1;&?CfӴ͓"I>I޿:NF*%;qQfa~wp}dF#K1ၓ9EqY,U8,f.Jjb6 &Ҝd?%b$鶒ltZn?l[Vn]dQr / _bҸLɜaHGu2`A4,lH?%xd./$8y LLl|7)Y2e(*?mk$G$//.Mjt:G&wIy6-'-/e-ɝ.,d*s"Y2)';b{~o_f(^0Q.^buj]SYdeKyt75~3(ATT Mtڇakml[,mܨL\L 3Nf8KUfqZ$y@g^,.YƮ ͲbMܿ$)/Y6:<1^!Y,?'ʔ/|sxJ_2f()gJ$W$ n+&VtI_dOV7y8&}pؗlҽgQLy2eW?sYqfr_K*F'IҒАG#dDY ̾agbM0l,.&#G`A&3COgl]I? oz9wW47@>f|DUbRv"S~_ "bz>KGL:fʥDq:ۓ| "_?28C^m:{mYyS*K)%  d%A}ϵ!x l#]Wt VEEHˋS\wb *.E>4bGM83;Ur|c66u2wt_,~R|:<2WP31>ǯXy&xKtgs2ie1#^}Њ.-TQ ?G!~,cA5dbnic HAwBt??lV.N1씍iqV^"{mKR3Ԧq_7Np#JD W?Znb}܀ћ~m /^v_{/qsMi!\g C$09Ba`[hpw-ߵw18SfSKC|RkcU`L'pAxMz~H"9KgR7~- %ByL6gk1Y^3y1[9|S/a6@*&8"V*HNpdsXf"c#5dNv ˜c{n\ MFC7bZlq̟?Awivhu{3lKz%HW/d?Knw,CxLF#s2-WH8!qwg vgr:S]Lc }{`Eu@LIW `OӒF6V"{lGTn\1#;I!Å';gqx|rV*Ŵ!Gih0T$ ÓZBF'eٌb wmo"RE?qW$zt+I+`c#Uꞷ5DRvPm 6\$79MӋXwR`<(.ܶe^{%al-q ?FsS*_Yi2fTǒHGT=IQ1ae׵xV0xYH C7(Pk Bg/?H*!2y9->jGF۶F &2N,`09?K@ v% @t 6%-ьi8ma;m*'ğʔ57K޾xSQ6T81ԏ"i-0i<=\ؔSV5 _Gy?G@~H0a9Rr+#I݄0 V=X>KKh1ͦ V6o첚A G b*o$Z>lgAeCc??nRHm$֔A`0Y.&~!WGO/1Km^.ARTL5 iH?#k5/4w\rĈ8b~O6.Ie(My],:zW|󎤂EX( ^hv*=Ɠdt=I/ O%w鶈DgŧfS} Ôj<6g#Dφ-fsRP~3 aol͊%9$Lsb*bۊ{?7Mawn[i$/q '8vQ67QӖYQv)zA&R(a<'A۞R߇_\#Cjjv;EF}ԗd43_F;LP6X'ԧow~9>~\-*Ol_Ճb5`]}NLw\95wi;0_۸ne.30Ud"X Vx:OIfkH_oZ 1X'ߺ`V!A>mlh5.͊ jrRJԩ #A@i8avߞEW9A :,;۝uHwGmL78gܸarN% %أڿiX%-%Чcbȡ"ʊ5 8dRkɗQ3y92ӝuIHa_ 1Ÿ`B䋚{IW;2VhQl2$VQ}̍'C2*%V Vr+`9b O nok|G Nl [Z4'nelלZ!7;^kӪYy-dpQCRU.@mkL|HW*//mveEP<5:庶̽@YgGZ,s==QF[{3Rߩ8phJP'pTΤ>KJj?"g}ڭ^ؤLuQ!Eah8*i;AՏ|Z|1[s z}P R7s!e<3KeËl ebS'RL':eӷV}4j?6 iOяֲS3\*kηFgI^kK ̹ "]M;uM|LAVb2#1rh )"@dPPs)Nu/fU힝[br伕 x$*VU+̵Kjhw+`^J; f39+DpNkht;[)sPn7TUdnI)ƻߔ"Z$lu%m ZKObV-3A6,@B8/lnH#0b#4 h!9`'.-r5"VᴝSDf>#O RYyaZ*Sq5(5n&5@&)əgsAsXVt΢FB/ll(?web4"EBh 7??Y]FtZ?fC2vS 7gs\­6ZsguJm( -0?ؾjߑ{:N<v96/H.#: H@Cz,^ )IHR- -[!1C-p$F+egȑ#}Y!M3JrSι#\v雪vEcTfwU.̼ʀ0vv-_Fg:Be$ .-kaiv6z6`z"nn1mmt%u#e=O6r]:A-UnJn х@+`Nh|1t)F0򵰡&;( =sK+޾$ED1V.ڎ7j2ᰔ;S_TC"X6,9T_FWF)è3{^U uAHӮ{:_oSCLJl$Zj۬E(ՑSYQq[ \_Bw22+sy;vJ#!陣=N%We,pu$H7IAra ]VjI)+ZCzXV zҡQI#H-9a}764Cn~$ܠ˔)|Me+M>j\UUAnmDt8Oщ۝Ե h246(%X#t9$)y8U9{mo|-CFFDʧ#!E/܂tV+úAp,^:h`|C~C8`0يk7I : _e4F(Ƭj$Q&x~'{_ bդ:e!R}8+vH.ٮڕ/\Mw wbөP4}΁qS+Y 4VVY6sq[Jj yJ.ޠhB٘zB:1i?Q>t2[aim[*bݾ*0ge|wۋ/փ43|ZR`֙C}(߲tl69S4VGz.Ys58\-Xな l{S/cwJ6M>1j] Y1<ջT9]ѕZ$_k 7CI%vmhRlژx|<*')pu8:AWotriyR/1> X,9D8aqa3^;' op?Mՙ+r6|%jk'tfkqO(0b!d"Y"VD&6zୱXKTiZC=Ӳj2ٻ:Jgn[Ӊ=iN"ݔp&CY k,l^ӡ:eT^[웎^VMWIu0h>sc~8ruxLmH*j8ˀi(Wu^X!sxƣKD<26Xm~Y?)5{vTKfAe{%!vKmb,xf ѥ\[@qD2^oiN];̚{-_sq ᖧT5s*dKF[u`#ouP߿(2R{*n<8L:BJ^ zf'H1vWdbŇ1Gaz BZ0 u\?`~~We[5zQY Yftb!۴Te;Yl*ғD{6+*`k7_WԮ3_AA nW'ϲy@5:=X'c5xd`fiɦRR-<!NI{O wq73z^#vEm7=BōU<ϾJS/cPYDG4i|er괳v{eN7di9~H5~k&-08sPo<}(8nldn eu,/tXZ+NY :g]ۧT_Qz_\ Tbo,cnt\2|ȮUsՒaWn!Fph1 tWW{STTxwzL|STktMWʹcC&Ԙ&n1sI#&Гq`sּ }{dWw<髣\r'+_m.(*~_v\UdRҝNrqp\EnX03EN/X mWHg^6//ՁnF0G#5pf)&ܓ$jeH_5.4Z <ΎWk^!!ke _L>eLǣ&E]7ەzR;0vy [U{ĬU̳f))Qz ?g/;.|xKrtH$pIޮY5^٥KsYC#;y1x2Y7K}m%`k*FBHA0TQ̔]\j=ݘxĮUMnSrNurp ҧ )g9Cl,+1HOChZ~1u1~xE7A5r/ Rѓñ{1{Q_?o'DJ+kU 5 #{>)vq Ǝy>1*(1DYׁq!F*rO#EJl*|BFv:0l;kL-l(?Viݔz4(DŽʛlM}z^n{080[F^xsPńhk{M֯mǯN^Ż7O_Y/DOǂV*V'G7xSB$N=8)QK9%eF:~3ۦrF 5y- 턵PvmwbNl+wȩa et3\Rm]wwWwovWYcv ]/rSpb#tp ާ6ZSUWGX;.%"ޙӍ ]ZK4q( 8'C^ :{Q BTZ3ڞmo}:j}]` 4p:7{shMl2T'3;H-L75Ofuk֒GkI>ڝ5Nj'R)nۭ =6n]cMZO(Cj5oXZ5K3SQoƥ͟)M"$l&r > Fw(}j%=țA,'qw1&:lV$_tfE׫Bn xRUUc\wA83~l;mXBJ2Mn()Kv3w{}2Z3U.CaWBzS?z'i'bzyb^ĂDt{ZQ\ը@oznSNJ9= ͱ s~k:EH7&HӋSQs5k:g^@;tg3oqO>wRraw|7ɭET|Q43&ۿaSMRcwd5A8)7T}Y#}CuA50ٻk߃KE Is+z(vmB]%a*o=Gejabberd-2.1.11/.git/objects/df/9b786975a8229f2c7e34d36e8f5967e760d3df0000664000000000000000000000044612240230175020156 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1<_8/yZBKm5( ?aN#GCm|gjo"Z[ZpZ}Ŏ}'1[LMU[ QR\p{׭'ÍncwlI~~N1Gu߿V4&\`^o95vejabberd-2.1.11/.git/objects/13/0000775000000000000000000000000012240452476012745 5ustar ejabberd-2.1.11/.git/objects/13/0b5cb3d964a18da6c90f63106d1d1d27ebbcb60000664000000000000000000000126512240230175020271 0ustar x}SO0gjdbP!mlCɉ#6PJ{E Htf4qR .#К7RA߂wpj_/iFep]!|A;TJ-1AS(w۶涂↗ ו<ǼGK @M-KYcejabberd-2.1.11/.git/objects/30/0000775000000000000000000000000012240452476012744 5ustar ejabberd-2.1.11/.git/objects/30/784fb0a9bc9ca75a229406bf5b2bc21df5ffc20000664000000000000000000000034712240230175020364 0ustar x]J1@a (␿$ b*> t$YyYb%U+DJp;9Yo}B[ZH;ca{MHIAьrdM = 6jb|pV*y-B.GG!W=ߘno {9#w`<+\"+ST.n|/zin;jejabberd-2.1.11/.git/objects/30/5e14c0ec9f2391b1b7149e5629c535d066368b0000664000000000000000000000025612240230175017657 0ustar xK 0@]Ci&D\9&4]x{#zK:oz[|tC$# ŜbH2Pԋ2^-B>09#z##jD&I2\4.pjc3_ĉCm3 aRcj3 K"imSᆴLO-ejabberd-2.1.11/.git/objects/f6/0000775000000000000000000000000012240452476013035 5ustar ejabberd-2.1.11/.git/objects/f6/a0e318c8372d001fcb79a96d0fce2fa42266ab0000664000000000000000000000103012240230175020272 0ustar xm˒@E+z5g* ؈V[UTvS}Ձ`TMĻڨʬS1XLpےx IqԤ)HitL]Y~}Gز\K1U]U%<8)ۃ: 8@ՉHOpu(/VPξȮ)7md4|IĔ]oDOv=EJ ry;L Lj|)P*]pl롲ۤɺePD9M{sZ;<=MwS\|rtBUSV1?Pɖb"|]҅P`ϫv~^UD="d1 CEwЗP(CiQn6tz\OelqȪ,N Vkq:LD8%?K6RϚAooejabberd-2.1.11/.git/objects/aa/0000775000000000000000000000000012240452476013103 5ustar ejabberd-2.1.11/.git/objects/aa/4b2ba64f585c8ca25206b3aaef39312128c78b0000664000000000000000000003340212240230175020213 0ustar xvוwIɟ }7ϗU'QLy2[Lx|e2+_Lg*I'd\\̊y:ϒr8˧;$p\Yy~&tLEr/li6fvq)>f_5mFd1-,J|xE2ˆY~~|Eʴż(V{ǝ4'8,fW.lV6b1f+לd?%I:ﲳjwpi'_..W݃:epQ΋$lJ$)ΓOWl|:.Ot^?+Zf釋ӳE>1勲鋻ܣ[ҽ^۫rOQ~b7ј7^C2v_y:]7xsf%,V7IbQHID'iC({%lv>˳QbxY}y:.ґt's]$ﲫ)7}wok24-J@4I^zJ.slv.=Ag-ӑLBJzf͊l 6~+D*D `2*=G_$Y~b&g7ɢԧR}K)>.fx]eq~܎DleI B^o)x;&h]ʰW4] ey)w5[lF){&ؔtresهQ6&#* p?1AͳvkwfvYLF鷣 lb>e9'A#z>}[OS5 Q8#]aNn~ _7i8agN;0?8Oytx^◗ 痘 +&2u:mle}mfy-R~hq`}K9丵S6LI<3uLGz<_h85i ~wKMg.Bxnwٻר!?wz5(&٭@9`ɌO{';*n{Hy=D6,ݴsEw k_ m ɶ]N=la$Kx3htڽFY}e|'YƮjeP!W=M\O]OTwH־vR} ބ{Y^ yr]L_[B@dٰf> q7w ҝAoE۽n70EaClF},)B=(;϶,6Zp̈IDIeUwy^7OKk (GA;˿t \חI15g$d\ˋ@:[ q|V]b E>o2f:_p2?:bȫ*5fCE\D>e* "?h18D__~r,HZ}Rt/G~ Ճ~wER[A-t@bzEAk g%S4Ȍ8p #b& =τl-κMig/q1v]#p{u07AP`s,r>!Xt) KTnOAL3x-,wGb/jf]87;Ur_b7k]죁l:N!A'ŧ@xdR`ȓ4ɯ1奱* cJ\,A+jǻl`RqmGuÈ0jpgzC#A,jڐ}2B/<!_.\AA g!İS6yyUF\+ĦqKn:cz?Rfb}܂~Yl Z_ ̑4- i+5亾h|!Ie&G}{1\~6jXO ż6>@E돈XO`t X\2 $9T2,gL -wmײEK.jH7>Xd {{]$ұܑG *+WA'2w*.]fZ_uTU|8LIĜyD`'Q92 !h-c3H Ajs*^m rE"9%!)cBt8'BGńQ=2$JU2$WAZ cJe>oAbG= a)[zm%$rda70DSǤɉYHW$|SCv|D4tqV.lo6J{" a@)TYc(˷a:U1!vV@A  8?kg t W,~g?>(o="\Po9E@;ˍ9 OxB`܃s/¶E &)'|nLi02.L^Np)`MXZ /"hlN*>|}h4s/ qy3Y7 շKBUVkk 7zn3l^*9E%z0;BnQNL@Tӧ]"&ImX ][;zzjTɭҦu0XzU5bgY y A$X '3"('"晻Fdq&:!mhU#wbh V-_HpuSfcHxr|lmx^LY P21qH^"ΏtטCL u%ZfV5%Le_j`3')qQF/~Hnj{]j4DYbܔ^U,'`˱s+R]o#ZȌ4ef=De=\ > ?f"*@Ji݋VU_a;+jamf /j4Za:x Sy&`*SBZ"CVF Z3h+P~`sk5OM-|^OuBڸ\!uj|5zRLl7,o J?Nv,E \>hQ4,2]h8Q$=5 =C"N48.}2:KD;jQ`"x/~Hl1Am]`R&kŹk"DXB%K#KQGn :A1g .QySQ? ~ ”PN[da-)|VD50+$ c0**O%9 zǁ-tcDz )BUTERKC GIi4i>PkDFB3fgX|ȑVm6hs.{z1#<-}F;CZ ԇ=vc IWu<3xoAW{\ rf vDHQ# k>,jrtjU GK,Z^#qV^˱Zt,u Y*^fCĈL4Ntdˢoh42~lgk|lmv!5[AtJR?cnj#V51eZcņ1CSIHw:~bA\Aq[|[i cI"9ozS˪le]U\l3b/v- P=S w-utoXo -R^(oO}t+ekʞxUs6QL=LPWƼh_\<̧eV.' cc 9;((ñC";:eCYJ7|b@I__dDb? ~H$vj69 2tBEd0w W}Lx\pʇWZY$Pc6ʝV|9wzcbdJ`DƼW@3ovb EF)Vᴝ3}͌>'Hš\@V)^a)M%SvFLvLm2^dXDm5Lzkꆏ1MX|oE,j$xFNnpc< `҈-B #PVMgGxIZ^7w\53=* AXFhV*ng`u'VHD}Dtv7r^9d_^[~ҟ/gռ,q+_I$ޒ*(NN?{2&&P`^8rehSRV" I[v9GDLD"VL^Q mJO5ŋXVsEtQ'৮T!j0D9p(Mm7 3nܛY9:Z2t?B͆g~K%>@AKDkkY[mv1;}R.lK;R-Ȱ:ԟ ʏw UyAP{y9obEjwU0@$qO_HxE|ॢ 9yl^F?ec_-⊣ e['^%p"}[v@|OVS'UӅz0/o&pS=Iv[Ѕ4f BsxQLR5X" $>}me;e Z =?id> ;u7N T٤ _fwkV٠;47\I !(Odl֭blA *k*rO@qGrAV"kTΔ."x)̧j%~y\=v=)<~ IF6qJ3h:~DJoT_.େbÎJ@(F02Ʃ76Z^uE Ał3 i\E* $l+NRl5k&JPC;*`-.qYT+vo3, T&ՏBt]ƋrF.D i~F@dwtt1pD.U[W@HS/$|*fb V?3GM#*۹ &OӅao  :Fm1L%,ҵ mԫry SX@&4AQ"58u 56v{XDh5jMݨ'87Ԉ1&һ{~ژtjZeBvNQZ5ZX53ꭨ,O|-zoUfY@f{rŶE96Xd٭+g yat݀c Y[н{@lL* %UnJn ԱBόONކ"a'ȣ":o76.Q,_s*C=JO>{jM_pm|b̈́BZ-W( b%lm AXfyd7%dw-btvl^?1T,O*_U,$V+җMPunʧB4c`(>^K4Vt[q6$QsHjW% 4jCkqω)6á::xX;*J 6ŎƐ:p^3-" \/2GVfLYLAq< >s4Yϙ~Ym~Y!{rT fAi{!A%tR1MK bjNoeX ^[֛' 7oQßG!~?Wt[ _B{LcVDCLM@0[)Dg0l8^wo+>,x^ bo9a5ɫ o>[!ϻ>͇*ܦ5%a fc+B@NԠrWP8oҽs7$\cdonW\狫{o ioxIg(;[(%g6  |?w+ٸf 7kK6nDPh?OEz9cBKXR ㉰k̹9nyHY3/z{ZNYjQՃ2PCu@|Mdǹl0ZR (p ƓAp{dbÆ0!DD梚3o DT0c̬pqW U[H8ٛOt2Vye~T]-(&4)DEEsX9'*]U%[UZ1$k>m5w:gpB"T_F3~H tI -z򵪼c+BJ$a&P[D"HeB&apnQFRef?k"/6%J |:DلƒFo;yBмO,oJ` EFjKC5(3>aj^du(K7ײ= VbxMݯWԎ3[0BA nW<@zVFX'c5JDt٠9JJ|aZMKݸ:u}q:*<_&5-rD<2L=v@5݉Z4)|iig!Ԉ14)cwjD_68Wo2x+/h *\5gڍ̓E(d\#,XuVKj5(:`^Ū7r1LW:L>d7舲nJ=5rm F@wFzNb^K2o'WY=+I@m6![&n1rIhE~D pƸj`5/qko[{7]:ZIʥv"] _ayV?/Bmשbo:S\!W8 ȵw[h>n"G.I'9Q"Ew x.l0TM5R]ղvYd\sz~T.NK_B =_YP`uNTp8xEuX4^FBVLw"K.sl^jNME8\T&̓zm5ٲh]k-\hxܜ漂cnϕ9| =^R#&E,nHh?t$Os[=GyūV 1+YBdFBT(Bovݳj; }AKAZ'qnYB1]5^OKH2."FdQHl&$;=8×6XOOA 1a=w)w7&;)TT;0 Ѽ!}{ yZ v|-*>:{0~ m,*1HkZ~1;c NT-ƝBn%P*Zr V ]C}y+>sG֔V&Vr6ZxSI6[0vQX!иQՆ A{)9Ab \L ێU <4O8UzۜѺ:OpٚznA~`p`kng`BNyBQү: <05_=N>}/߽yҫ9"R/?I h~*/6"*`앨*":&"[n᱄ xzpkI6wP]Nymҭ!pS V< C$_hjBKӛleFV + =2qY`7ېzE޲z^}ֆ,=a4j;X֨,c5S@8sJ~YQ-"e-Rl8вJ?mOx! ,_]b7;-Ck'zmZOwMՑ!9e[L)! j ? 5FnsF8/ƙV}O:D)xmN 6`*uzESPU?2䕲zaX;6;\NV=mY0Ym׆ @p ^ʈ^`yEn,gL[=*jG/x=ޱQ{{LWte ĥʧ_78*N:{!q #yEmYIzx( ص[ k!QĘ$lS;'u6$0Iw9bp^]P@,R޽!o_e@U榠c#t0r^6Z]Ut Ђ-Al1B\lO~*80VDwqW;Z\Lgt*ZJךI(uYQKE_7PXLʏyshM,2TOg&IuR[N=,,ojLִ%ڒyb;S[pT;Jl8Qu>?R@S rm7V ޞIn0gkm{28k:6'|c~ Ƿ:-%11WT$GTq*Nh(f\)'a[T6ɖ?(P(oJ(z^7 Q KL,'8ev*/buFEի B/$Rn[yѹ΂B1fv 7eH.PfS쨞g72\3Ud.CbWFҾhyZ~i?d*X|$1!d|S(xe-zeelT{7=<<6)qcaޅXA͆m5 H$H˴Qgx; dD֚*qiyRE{+{ڀOc9gSA7ŭejabberd-2.1.11/.git/objects/1e/0000775000000000000000000000000012240452476013027 5ustar ejabberd-2.1.11/.git/objects/1e/8ae296848ef3de4ed5b5403ad438e7d48037170000664000000000000000000000034012240230175020110 0ustar x=N0F}h@b'ۖ &( \|{ӗyWg4"~F=1Sd#UMc!L8[th)cMeVx \`y/x7onѩSe]TI^`soS>T Q>1%j%ء?\64zTcY;;uZlBejabberd-2.1.11/.git/objects/35/0000775000000000000000000000000012240452476012751 5ustar ejabberd-2.1.11/.git/objects/35/690009a9a5f8628b16799433270a4596210f850000664000000000000000000000022712240230175017314 0ustar x5M F]{ /Ä&j 13eDzn#}{C}*5yG>jBH vEL[:NJ OqQ %\ D$)}8@+@cieEִW4ejabberd-2.1.11/.git/objects/55/0000775000000000000000000000000012240452476012753 5ustar ejabberd-2.1.11/.git/objects/55/ac86fc14e003b471cdb8d5474940419eb980250000664000000000000000000000102112240230175017726 0ustar x+)JMU031c040031Qps52045475+H,I`ؿxa۟&Nv+cLDʓ * [s2Mkbc S2rRu3SKRust+ 2Rs/sOBX{M7PT5kՍک?]`.j{vԜ<ݔ̲"ݢTݴ iG,k>jelj*OH-I9럐hoU5 z:@ ?'G7)3/R 8j|A׊o,[a*2RSKRr2`^)Ͳw_OR$UWQjrj^ 5Zmu˷ƪY" Cejabberd-2.1.11/.git/objects/f8/0000775000000000000000000000000012240452476013037 5ustar ejabberd-2.1.11/.git/objects/f8/db9e16abf64c7f9921b60d54500d0a113b60ca0000664000000000000000000000340712240230175020216 0ustar xWsF;B-; dN):| 'Y3w:;o$!v!ؖ؂Ed60ۣNF=*Ֆ]]ړSF HHɇҺQW+x<,t):m[jT h&|o_c6 ^h%kEȦ^r$bM|Aoސ-C~Lf)9j",Fj*m4ZF#g<-8w6IFHs<"]*TB5a$pǼ*#$w^տ2! C>;{zlTȘXTgPp^!66tvE?.Bsx\h&~v1͎\lhi2?>9<9 '=3w˻9ukPоٰDMR 5i)@_yBKg{h^+kDNIaJ~fS~Lgbfsrs`vpob99)uz,cަ!؉&Ry$'(zDX:i7?>4:Yϑ[QDBD% $I2QE` }2$ 6hu˚Mt ):1F aTvcneQ~ejǧ 8.EyC%Aɉs̷ UO %\xca߀r[vf2;] 7^Od`mj2gQ;.7TDs Bx61, @zn>Hz޲k1轐B]ʗN,¦,61 ,,Ȍ n51@B KzLzA`M!2v2΄Į; @RMo`rOkU}g. TgE a5GТHm]j d1ڳu؄@>E5Cp f&6J\:/!՗BAᙃo[ WIev9Ttrt?7[ejabberd-2.1.11/.git/objects/6d/0000775000000000000000000000000012240452476013033 5ustar ejabberd-2.1.11/.git/objects/6d/fa24fbd64ec21db36c737821611c123244e49e0000664000000000000000000000044512240230175020064 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+ír'Ě9gQqyO1nYqY6M,] /mFdYdӳx2:#[\F;_1Q6/ WuNxˏIYF/a>=_,>1g6<-Lg2ga6_AE@y>g^}vR|>ɇⒷ "NHPJ|1I$ Ǘ6H4z"A=l|N\n_|>xVV ә>buҤ_Lo˜^s^5BYtFٍM/}^dY:|MR~tVI::yqXNk6Q~K=&>K皣f+N<ʘg!$:},OQ[QFtֽ]6?o"g<bE8RUAW-6ʯ(9@~7^$s`,/0~TXNptt()7z_=x9^ޱ?d=be2˩~~>a4yky<ҼHmF|+wqX,I67ے*}[6z4I0-}muw.?Lo76|\邻E2Ul[jEm]'%qa<4[? x|:Jeg:/iO~`%'ͣNGP6G~V`(ɭ)Ihz̯:ji[aǃgVilчmi7hU`/.pƥwUKpͳ$fU^y4^1{au^qG .1E o-9m Lwb'ɷmYlPU: ]Bɭգw8ݦZw\.Qm>]h)bBX2ȆxM7h̸0+=l` M.z-^bajr6F$|s./8$bT <.uc{]hf>69I0|BN^&z<ϧ2u:Y6B?,ڱ6G `lό~2r8̊|Tnb|KBxvskП-V͌Q0G1J&tPZby2{W䘅c5wp-n#\,fY>\UjᶯV~XL*=M%f[p XN=TEGjq:C\a~ȳ{ 8sAөlҘY`h <f^1Ҽ^/}u~#DO+(ͼL#k,o[V_>>΅5/Rd.Iyh50{"{`4GN(&.EӕDnOOOH6쐥/xNtX\/~zW?~g,!_M&#f!B|D 8-3^||XO}<nP!kxǷtYf-m6 0lyl!۱uKw>]!@=lQm(,6ZTT^~~%Ee)2s_<&AQ}mܠwfEy> `M_u*pj_Fzg"ܜ^s^iu ⭅bO\crxQgtdtq<|C^ Bcg1T$$rA[RD~bl__,~~</Y^DM4Z5>FJjT Sn{MS~-|O*HVW|*E(xw3 '49N&񝐪Pd5ih>}8mkmzg^k,-T"8Q@o|_hApk{TuE o\+"y3xDNTkSresSR%%~,V|T8> !9ۿ???A?D`X7djH_;H5奱* 6qFW8GK-(F%v`nѢ(|1 )``CQ!hW^l:|LȊ 5a4%lx<ڬY;/*=HK.ɬ6B mϘ<&iV90YGE/_)OfnKw\p\w_=RvRF典yG$''[/b$l9Mo|. BXS\N$8gV]R˖jۮ!"':=ZɊ\)eZɽ#)!g6dMV9H!O#bmj '\,V `*`+Fa\giAA6_*Jr]_ԾIe&G}USχK۟)?լ^6>E>W_Z'8bٰO%=aQ{>glIn}7x#["!YľiuĊ?$Z:pXD#p5U-oߊhKWYFEJ&N,_AMZJ4 ĉUTz"Eշ} ˜i$ noK6VYO)s_2&S/Vh(2?wYX3*yǓY^YS:$WE c*>o^j}*0o H\h[֨!$CF˙cңd, W$P|SCf|5g˳byVGgoMٴ*Ği+klſyFI,[_DfbR~jed {MIZEXW nu_c^Amԏ,v`i,h_Њ|h*, ʼ0 Ⅺ {W5 2f٬"*G-QH`F/[TTVʊ,0ݍbh*]ڽ5z+5a7T5ͬtU5XaUekvb9O^ љm0먫߾>Zmfg'/dž&>ISW^Q94Pw5PC~ZD$8*dp;i(1ȗ??^DYw47GGgD :%VKr4{xձ-NAʋV%/ĵR4GIgex)œ: rrU:,?O^9Pިoj5/&~} -nAjI%'I†&J _ 0=!hV5}(To r1 zyY$$T*9(:YgΉՃ`r+6rG8g[ L5}z7>uNrwoj=3Af̷qJV?VVY5U !/6!:_} ‰m#{:%ޏ?yn>+up8EV!m~1*Gocb/AtF nlHċGE픕%i<=H7M~{9dLww̐"5%LQb '}ؗ"}*gצL |2b \!)qwhRKܔ[,*X7pc~Wn0%t҇j!3qo7cA&R/l|Pemϱ@*bps"$Y:60ŝM =V6|5kv(yA@Qc%BqOWry8s>~YuFu=1ܡlyzQ}불a~mbf;bK* 1LpDLfnH M(Z 1 N#]V t6͹*Q?XVhƾK㴁xr|%#ၼZ਽Ҡ**4=LBŅk]u rxԡ `kWny{K[¦zƍܪ7(q$_}}ӛw~q 0-,0y aF&nxJQr꼝$A41[% Je giA?d"Wf >m[ۊNrjrJJԩ$@fI}ߞ`h3Ll֠qtǜ^K 5pF[Hl[A0n8X:fIMߔE`U,pu11)wL**e#6LM͝`L)G<_LrOG~Ts"T^Rmuzj>y#h- RX 6X`vXa}&SJlYfwoL=wek*!' }G["|}-?l%[xĝcL6uqe5mց<sk?@0UM7ho_U^ :X޺Zo%[7JyZSWT65d]:f+9G"t4FŜ"AI*4&ULԴnҼ)δZ!!ދ_3<;Lsy[W %by.j;*7»PRȒq"B$9F^H4*pj9AׯRZAJip>p+i,B S cCɋպޱ{`J6J%opY^05Ekt-#& *#! %ƮxQj{OܳfDFIk5=8!u~#Um| uY]\.LLqoUzhv6RP'pT:^KHg@d; эm/ș2Q!EaMq^ f9 wΧ_*WXaUe֪ 0UBb+{~9QEټ3 El $w٪[3>so-ݚ6yj;[]HrV({q1c5Lrlکܖf0#@naLF)شzI3vuzv7frAŬfҸ #v`^yDN8'ZBPfٕUeAw^쥰C.q n윚,yDF862n|8[[g'o5HyW"eI=iƳE@"j̕lj0EA] kk< Ǜ_x:9 "0W=w8V{;8"b#>zqRZ&`Ht0ĒC)m ~jS$*6ߚ;ݽ`@虏'7A]s÷>(_&= rJ0JƖX{Қ/I^]Jgd$y~| +/r5>Ei{vڎ̌Gu8Njzs==O" Ki*3b:czh ʱW\+ cX+ߊYH񆭜ap lkq=?We뜎ZaDP(+&L`|;^huS%S,ԾtVl*҄X{ ŋ!*u*"b1rxJf&g}ȕwG (;y)Rm9~8Mb=eM9zi"c gwѻ Q>SCs$3xIZn6( 3=* A,y#OErzo w3AvABR޸polgjKS+(&{ vr^9d_^[̥?^r8ޢV~8nS=vG[k{ݻ2&P=F|(@;6,VY$!)zٮ\v(QƶB"כϭzjL /| 9Bc2= +e,eHr(mkr=exƍ{fVNF8@o:fC3 d"ㅕkU[ev1;}R;]R#vd= f+&u(?27WmC̓j 嚪U5~}`MyV;p>=xBNc4b8ۊ]O}zW˫dE9t{o1WI>.aHt݆$$ߑi+Rx7o)SzФTept'+1%H$ja!lsxQLR5D" $}me;eZ :l.݁'}@wV'*nN (B1hI٠;iҭɹhABP<XLe![1(eT q>)!m(D)?+]yuXS|q9IaՖ赛IрPtQK}dd0SpAިQ m7S|PU\[/Ŝ:=Q45IF0ceS{nl&WMrRKNd;-HڜfJAͪfMDXi'ڡv$TVN(g6,*lBq*X6Td. vBdty<$T tJVw;E(pxZaVvӆ%0%G~"({NSGf$rGdrAUrPlbd8DwqiSZJy8=_` G [MNڟ" +`A1F0mbsb9m:-Pr9,jsUCeUoW9/GcLǪ5*w%B"GWK\NsÇI@;8ʉ`-ZM'DcG+Qi=|ZRS$W/2urSP$r\R PnzÇ[|OƁZI b[=[8){T&oB\֥"ڇ{q}ՆN(0xز:V-bE$,D9] ngvA7C N%z)-Ll߼ϝ oD>);H\Z? 6OJKL,7E0ǝAX\sXI ű6pd3OӖ=!GiPS-6ߊ|c5I * 8-lL!d͔BZm W( b%l A<pTm's޸>^8(ᆳ:嫓>_K Hꁑ|"}U |*Eؕ!@sFBȧlՊ`pNX4jGqh^Gb1RY1iшUeѕoQŎ׎!sa  uM Z-Xja)=}6U*"` Qݔs/;gXITV5bE ;Z0cJ+ :wǠ%BlW9CTqz5{X ^7[қk'Q(?O?8nkun>! @߭9vg љ <[ zizUȚ*j0 x.j9!xA*O Gc<:~{E<*^M*bW +py~"" b`.Ъᒭ*qL֊'Qr=FhB"T_F3~H ˗tI zZU.E(K!+jtV6I.j; مTEulC©[orGޛ*o5u:vnadng`BVNyBQ_/xkK5<0Ď3O_˷?>{m NǑxS뉟$ڏ4zqcZ_lD|Ā*`JTyZFqi *O}-8i)&zOG;b0MF[nVE A9HPN!whVv`ĪXlP>(W -)-Wvu:gc'nK)ڳNFnC])23U ƙST̊ia!RI"em-Z6.{&d3ad8A^:/ +a" Sbu/n9I$.BP|5$&]zb$+ 0N&еx#}r<އ#Q|Cf0bk%Hes*5nQipPSW3m 㽟u'RqmJ j`*uj)lU?2JY]m+VM?R'.xIHmWِnEШm<+:M vc9c:98wGHQ?Q;IuFd%W4te ĥ'\׵qT3EN:{!q #}E ²$].ʨrvCMB9ae}[$m[]9!=9?%N~IPb-x[*sf279a#: ꂬ[H0c35oe{} W1{ H(vdhTs1~v jA(qG_+[f|ۋAJ] \1~kO@̏yshVb!LDufT) RqS"hncnI<ڝ-i8Y%6(:ygi):3=aMsec`O6cs럐6d- c8ѹ0/9je&9ڌSZP(UJDC1H9 ꧲I c&?(PX+n (zțA6%N~Wl}*[9 }qvcʨzUA]?sA@2kͭz+/:YPh:̽9_q"PRpSaeɞy&q71ɨ >pw26NFŧ!ndfzbAVM*+I++sf\ N; ű-c}i;%EH$ҫeZӈɨ853…;u.hm/nI#W}g!M\JyE Xk~xRT5MVu-M-o_\x0@;R k0yX;_ h8VGe쫌% \@m>gx; dDy֚*qiyRF{k{ڀOC) ;Dejabberd-2.1.11/.git/objects/de/0000775000000000000000000000000012240452476013112 5ustar ejabberd-2.1.11/.git/objects/de/372d680e8337fecb1152af907c55e9c5af1c400000664000000000000000000000162512240230175020240 0ustar x+)JMU040`040031Qs fȲ~fj8KIwsw+rutusIMLcTh SWqez Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?a -Nvg eBivLQ~nAb C}?vKnN\E^Zf:_,9*[gͶ*Jsb}ًTeg0d͌lDQaWkmrSԴҜnŒe&a֫ o90%E +3??%.ES'&%2DXlr4GeI!5 ;r8ZgWo OJLJJ-Jѳ`n9__`9ib*T`njPT C&ZlnUu|{Ylq#2 JZqKyUMt~.6Q `3p1麺<װƣl^CaR) {ޜVXR٣#uejabberd-2.1.11/.git/objects/40/0000775000000000000000000000000012240452476012745 5ustar ejabberd-2.1.11/.git/objects/40/8339d1ea156fb447999f5c64a91901485d59be0000664000000000000000000000567712240230175017723 0ustar xZ[sHW+I 7aloˌg7lg7[1Z 8 OCRu_uD|o/e< '~򾈩^p+ή_Hw&cx{Jx d+oKIW{y_d,N,X2H?Wk, bWQJMҢ˫_5ޜ棵00B%c')ݙ;){ g&FHeĽb7 S6*,& c!(i"L0L1 $X'[@AtC_:P-XAih7-h(ϕyzQBb-ŽfS٠iel8ܦf?:>u53vZχNp0lu[{[s^J&Ma "@ c|ӗv{r <BzZv+Ng:vb۶pq4lAx!#R;/^o:}"vv.qecq}2poc}1|ف=+zvuttrBG<ϬvG7AOU08~ ^D+JTl WKԄ}Rޜy:"`-`& ӈS%?LJHTkG9_ e%ZF:A_ ,SǟܚV;y@8Qև%!Jg Y2"H*I"̦980 } "}Ab #a;UŒ;K' p B<)(tmJHUXU54chEj&M!{w} raP}mKE͠6 7R@Dzeb華˶k(Q r%*3"giRha' :^P_aV' ;ci_rVwjã#bS;f~,j?Ve% `yƃJR/2(' R#ۏ\,ơ l /)twTծ(,AY mAyw\Anט+(uT5R w刃2o(īԂVjwE}ݢo)%WJirt8r}Ԧ2r1!D!ڏJ\ҐhASkeΣg1=Sv!!9Wx$2NUx"$E&d% M\ i̸rU$GԖ$fсKβH;`ȗWa_$~P+=tE'S'#IDI:@.uM~^z}8 ZڼĽTmKw'Rq䩸{3XzŌTݪPC|tc6;Pq"Z,sD34],ME<0n.){ 2N7FB9wI}u~CƔ$8HBѵw!6GFQj?Ww>%(߃]f/rRdJnW 2 0wm*gRQh"ǜIX{O=  F̯q" kp'HvDvf΃Yi@W׷i.I e86Uy.UsgMΛQ<9-7B#,Wۣ^PD{w؈Tg ?vJyCg0+as iHTh<.'c K[6&(f$c-"C$(zřEb 3$ N}ތdNq7D].%N';_<5&`d\7fēp͜>JvF#(Ѭ,y,|҈BNmF s !iw?|I$9Ыڢo[=]g?K[YKUْJWRw(-8"G0L06Uda Zp.5Js*X>ZNV^@0r*v] Y5H'* *fι hŢMc?d?X Ui?͖r@9yJ4V9M3Dk!+1[N7b]Cn5ѕed㙁7%BFnb%$[WG}̦bVY 0d)#.tAO64 nS. !O6E{4i=[\VC,#@6J%QtY &aS@5, 3ٴ9#؞LZzob zk<eI 93h9 քX_I o+ ;z[dQ$IXZ HL0@\ u .;o##-Zf-t% =J&c &.˕ ض\k-ʥ߂IwV^a'X=ӫ;ga޷:Mn"07!) B B>yx.w}c(ƝA~v{VOڭî36ߗӶ豝$ieN/U?>xzeFODDq*_whęNfCl t8 %^͢ 6GJ3xLV锞у"B@yIU~RLsqK̫yVyɮWXK0B<}Ѡh4x (/IKЬ(xʍY1BZz<CLzҸ̲Q`0"u} cƂ3>`oLQ+[ejabberd-2.1.11/.git/objects/40/28a99d88266ae21a5f6d88c422e1442d0df52c0000664000000000000000000000024412240230175020016 0ustar x]A! = ?k*@dYXExdz,{YSd<=0zln=ӆ֒zh )Nסʡq)&a:`JE(0أˡz؄ZZ9)&(b 8$5Uc`{eZyb2poYI.[aejabberd-2.1.11/.git/objects/d2/0000775000000000000000000000000012240452476013027 5ustar ejabberd-2.1.11/.git/objects/d2/8662f3731461551e2f293d656246776ce4f55f0000664000000000000000000000030112240230175017533 0ustar xKj0@)fj$A(g5A5=Ce޶t"jr&?bhÄFʔ&JꉝJt~8;K4kS` twQ!+wqV~>PoN}v>z}|\zOT7zb[ w3n/Naeejabberd-2.1.11/.git/objects/9f/0000775000000000000000000000000012240452476013040 5ustar ejabberd-2.1.11/.git/objects/9f/d64cffb09ba2a2bac8da2fa1808216c1a26bd70000664000000000000000000000306712240230175020516 0ustar xWnF+d݊Ć/qҴMDI_ X#1%vWvTWuvyHݦaȻ;gΜY1a8 ~x2Q"uR&d`rpbPH>$;0cw,TsLT0(D(RL Jlͤ?# QabM ,WmƆc"Sga)1,\D!3etJm<9> nS.)sP-%x 2h0El8c }a(GϏpӰ;ɘ_S۵]mTco1 q@uHǮ//LK{4VprFՕVB+ p,8Ru\?TK8GRo u儼'? ) oSoU*  vlwN&#o=ReGǮYruu-at`G׸>&`e:+.?j]OGd'kB,Ӑ/0vAZLu?qpIJ`+ʳVu*oY,Y2ܓc]I~XJ6),V74]Kǘ1E;0%X ņBWLcM_32k6^:db~eĚZCe-Vs 򑜓"=Z%'˄ϥl E4m*%G7W--}W*j4m5jxj=Y.r)B1JqK2t/a'xW1Ћ>ѠOvUy8 Pzhf2ժzy$;v=Nwpj6"tnJ^@/ !u}-Rw֨V n=0=L(.ުA.&RnQ%dTLF#9 DumEi^qgMEVQԋCב$xl)|u!{Ը曯ܡYNg RYaJ;9RID׳t.K!K;|CWEl9*s"\o6iٵ_m0Ej&_u.- Iuejabberd-2.1.11/.git/objects/da/0000775000000000000000000000000012240452476013106 5ustar ejabberd-2.1.11/.git/objects/da/ab52b0d0cc3d5b535eac10dcbf73483c2d76520000664000000000000000000000103512240230175020415 0ustar xmK@s_1)j%VD"{fxX >nuw}}i( ߺsBq!38_,V_cAd׹ EN2@+ijkN% ȼ˯FYL}ey5PkQ Zt}9a.E/t@}Mf)E7lMG>_"uvLw vݎj_YVTY6 0wdtm# tPɽY =JmYxC:qg#ׁ ʫ)J?fte|=G4ǻ#k!=䦍U%[T+jGiZ>óf~ "Ou[:CWm1qLv s0k[)gv &ɦ3K;ϷbJ,$Vb7(f;pwWػ'%YUJvHsGrLْv1~qcȥ"G$ݱh/6ejabberd-2.1.11/.git/objects/08/0000775000000000000000000000000012240452476012751 5ustar ejabberd-2.1.11/.git/objects/08/21aef9277dd647b4fcfbad64b0816d83a947910000664000000000000000000000044612240230175020173 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1K0y3eaNwA'3̉th-Xvm:36CdS+s rRNرd>?f ն*zu!Jn/dpr}-)fڊD 9FquKejabberd-2.1.11/.git/objects/28/0000775000000000000000000000000012240452476012753 5ustar ejabberd-2.1.11/.git/objects/28/694313dc2299b43ac265a908e4d6d3c7dc758b0000664000000000000000000003427712240230175020044 0ustar xrW~{"L+ rܽDٖ[鉉 v(h(4 DO>>s @v7fg,:|e9<4Z%[z~͇^ެ77p:)8`9-n)Y/$9b4M|O"N;z<Y\%O%E|Y:ټHxDŻgIgfrC>QI7EV'_6dqN?"OlvMwl\<_\%޷)|t9jTt|n_-8_6fq䋋_$|z1\SM0Ո^6,Y|b9+lzͷ㈡l|ƣl(4$9?ՈMz6zbVݣ6mo^̳t+ 3t6(MUL|%+i6 kGY 둱76O@vyzg,uu{n=jɋr_M=tWM }ݲ u?Gaԕ:~.{٧r\I^_Ey0oTkd9 Mm_^$N_o?$vb.wѼr>ˬ>Jr4i%lvjwzfMhd)]Ew͎E~~\FqX]";>\/G!}Yԃ֭L@4[JWn Jpi6ѷ̳q6]'5S 0I^uە5mbq̤U?s9l6߿ZQY`Y˚iYQO+7Vw]ߺW"~arpUlCh7*F{xؕ`k7eɑy/NVtB",xQk't:[KcMZ_?0~ ejNrwO<؃6t~#TV=pc`_Rȹ- Hk+9-9]fWlz_\l%Q=ihF⿏Nˡ)x7&XB8K7>l$hzfT"3ϮG قJd`SavAg#fj<5B#2*Fϗˆ',|2lP${.|a!mrkhC.m[Wh\ԈJ+$yOkb'OlҽR4!2M K*-ndp!Sc\Z(|Ēq$],tBh'?c޷S~n{L7ۥF7qΕض!&&H@ (2ӗz4ϧ2u:-.!V)B?,ڑC[Z->eP9xfx.N P,(.N=g5[uܹkԐ;׆eff8/@(_驹驍,D߷fqF<}"tk!b1RS(}V*$ǿZ 7LxKۭ}Ib|4Qq%XS%?be+]ZMg_ޡ2IY`h VAip/$wǮO Beg꒽oaa5d^?&5 \+ušAh Cnt q#ٽW]ǛFs{Ԋb+æ(Թg1, >[O33!?;d) 4ބyg!Ő'w!~DR[BҮ8b>(> -\[Κ7;fϖ[UPy&0ZS%k(( _.X"y^ף|' j (G7ȝYEX׿r Wq7'לׯ/DZ]Hxka{ĐQ!3! {;M#b& '$R _Z^wl߅ c56H]ڟ>K3L$d6>\6D] պn"l "sxDNԣu돲 uܩʖ?+ڥV8> !?94~:ǿ;*?ׯ-7$_4M1奱* ǔYz#}%Ôk;FQ[>ӓ c0bQӆ쓡_'fv}<B<BZ8 򖈳nb*jfTEEXS\N$eVՐecM+nHyҵIV;Yd7r"%$F,#7'/???稨 t @vK=t $ Q=-^jVө`<ɏGt&<[)I { -ApVߣ0`:4n#| md~)sR(->ȅ 5)_Y*HNwdcX{@| ǂcr0 (m2mX0/0ߏ`ݮxjycV.ݷW][3QZö{oP ˝]:!fH7ma;Z[t5}&݅f %W#`<㺁e^8ou VbHP~ԨHZy7_CҜTfrW8?|4D{lXzhz,*8_}Esj5D j.F}1U9D}~ $lъHdz8nIи,."Iac#U CjyV$eF e\5:G$6pebbNʣAtN 'Nrd3I/ѳ ͼ#-'# ~ZMxu 7G̊%L)'ɹ/ I^U%!,a>ef7kaj-gTt' BU Uov:"_;9;ghQBXe x_ԎčmM2dkl9&=Ng f_vNH N͎jhX >{mZE€SsfQۗok)`ZՋEd1jF ,EF]\U^.؄U5<ov[5Fy?~l (·}A;ˍy`x U 5"SXPbTe3[FlR ZÄe#o o]PP)+>KCPf>a#]<`zlaӓ%'as``XmzGWn1&Ûi: x s5&Xr_幂t2sx.M)e'עZ8v 0&f,IŗAAlb u{nh^?5Rf:p^%HobnUk.3峓ӗCn$?DCRרa2DT:] < N nUs Q_z| ~L]Jśm~m6;8(IψuJ < 아W' b:*/Z)K^Tn$GIg['\YOa#@W`\WCu9֬VbLJH)XrI-(\0Q+_UxMb)t@AZ,vXX~K*M5i0O1 RU˲By@bDce|4wN̎VG`'p>r!8S=7@2ZX$79߿M#Fk~GY 2c]ozުr8v:շ*ΪbU`ڟ@$X 'V3IGh?IxEʻ=c+up8EV׀6_ybh7{Q?nBBMY<`kvJO}="K65?XMUѿIֲ;b^/Tx=^RΎY5BRظ(#0$7ܝ65,nZnJe /* ~Nػߕ[)L7!ZȌ4Uf=DeHt谦ED8=Tax4DVzN}۪0ŝM 6W|5jv8yA@Qc%Bq/r y8s<~UuFu=1ܡlyzY}ym|mbf;bK* 1HpÜDLfnH M(Z 1h'⣑߹֯UvCq͹*Q?XViFqTq D5H/ħZq.ZmCODZ1OAi8azߞ`3Ll֠qdǜ"^K ˅?j⌶EX,C0n8X:fIMo"*A8wuӱeQ~.ʇC-0a4kW 3?ty: `# H|Q1;E><+ۨ+њ>CcTs(c㍠R3HBb%`%w2zۈYjR0Dϖmlm!ipbSe=>d׫ێlUIwRwU~6+Ƙlh~ jVk۬yq-O~ba~/ ߠ!Vxg/OXFhAUxq{kM rꊪ<&Kl7OE}29/1M`1HPMFkzJE{f1e)_70\]"ڙV<1{[UaۺL`E(F@b&B%K#KQGn :D{!g .Qy3Q? >IiaF(Y-rTz>p+i,B S cCɋպޱ{`J6J$o@^Ї5eZ/cHjeH;dGIi4i;QճfDFIk7=8!u~#Um^ρ?fvgeψS}r(㕢HCQ=8v{-!.: ށv핃2HYRDeORCWLi%#"SJ3w h1B+ Idll9'r5:4|FF$h |U4dX)x 8msҟ?^T8ԛz?ŋ0,d8gܫEA9}͵bIo1uhpEoʉ٣b[@~a*[t #R58eބ̔7?X 5Z3^U҈eqC?f^Ƴ*vJFΣp &p+8iW/jyևԤE.K+3`vUQoubs# ;CZ:_>fb r_nBPD 49#8[!ቸ[nN3B[HVXGZ*Y!LSd8W~D|j_:;F6`xxYx]iZ=Őݺ  G1HLu7k8>C.<:pT@!^:)uHfd{PZ$C@A汱ku䵪-6VZ>.lK;pZA:(?67Ⓐaj1 3(T ) hWsT@!'h1kcۊ]𧬟RQX&I2]N8BQ]uL$%3d۰<,-!9}6ရ=0쇧c*?} 𓕘F4H$ja&A;gA r`," $}me;Ųˏ"'mWd4UvIɺSc/3Q JNnMΕDyDf* i݊!F`.X,TG/pܑܻm23G`<.k/F3 LD`IрPtqKdd+`P>6*QUj7S|Pu2L7<쨔鉢Ik#8R8FkrT).޿h>(oɁlvr=޹ڜp%C?ufUm"ePC;*5`-.qYT+vo3, T&Bt]ƋrFஜD ezF|@dx2;~[ "JYɭ+MUv to>Ռs|u31d㙣IHIE?l X[R29"0H:6T+S/%:Nڈ,9 |O)vk GQlV=UőF1=6ƤsP;@*sRTT*Z )Qo mGEfi%6xw`z#fS|w :ŠB8J[ GTQu?09yދ[|P"6,*lBqغ D|m- vBdxRքU^wpppRIP{KK%L,u*E(pxZaVvӆ%0%GF~"2[(H$6qy΍i=rЎg/ܶ!aj$Zjlx(SJt[:jJ1W&]{L׎@U^kٔrtwS*ЕXBW(a>rOlbd8DwqeSZJyG/[&2VbDab d,ω10@YU UZU\mxLd1֨,KE8JZ5Zҝ 5:rbi.{aVޣt[YɃVj3(  jt9IyrU3yKXeR/u|.ykǂ )N.ж80IhiVNĚ%h/+N$rh8ߪ5ϕ 'X{"ш΍tnȾ:㍏!D%t/* 6de.@7'ÖEбj6+'e0$zy4);H|~Q%@ltE<ȗT>,7E&t!a^\1x9%(9+ZaG=4mٳjk[of PuaxBev8D )Bv͓E ]lC+I#bXB8EV 7Du4eX|uR/Ӌo)@X}fu&r7)^af` vky7B> e+z`I9Fr)U ik(Zk4qω)6k*b^KYV^EWl/!s8"p^1ٌܼlf`m:<W LUٮRqSPꦼD~>+iT561g"VQ-]cЖHI!G6 G!8ʊ5;oC^7Ok'ϣhQ~ȣ^,qpa+|WC(2ѿ[ y3 s4p <[ zp4KI9 0#*WAn>[. Iä!%UtᖤJK8c `I:[W1?$95Ӫ@IIx-j5bI{5WjĘ.Y[}[U2ף(l'"'"o"1. bU>:fpDhg  |/ef@]o>:הm2=~ j֧J+F$-ӧ⯆1IԿ\X4\j sN/?@Kt:_$aVg=|tu*qE(iֶ27*:,ZkFY 3ͭm)k1QL.q|$Y]7r1LW:L>d7U "ص{k,\K@P-tNa^K2[o'W],J+&P^S׆?9dF5 $Pu[㞲zh\6Z߽klt[%k_m6۾qbjD7"Gv.I++RzmvCء=vkvZvM2.x?6yXo=sxRPrWVy56XSuUA?//F!#02bQ>+n9Sg'3#^d}VtteG.{:1T3e@Ui<'&P-{+…&^Y=v{̙PH@>vP˩ EI [yVDlpuyت$fb5K H%;h] P4wLCiue z4 wd{u?E6U"͎iG5"뚬Ht_$*c]b!>=un*\.Ƅ]\bRnLv{>Ivцc Ǝy>*KcTP6ě~ [Ym[ K)uYJt*|BDr*0o:jT-l(pߛѸ'lMuxNv};530!q+j()ZR̽&{FY˿ͳ~AXJ*]qj7IX@g)WL닍_x̃]""VK(u>K"Ǿh^Tukn'#z~&q[-7k~PS}iް}Vv`ĮXlP>(W -)-W-u:gcnK+ڳNFnCeZ)23U ƙST̊ ha!RI"e͖-zo 02 /cuD-HT([ΤrR1x*"C>CX =Tn1wZ+ 0N&еx#Cr2>#Q?Cf2bk%Hes*5nQiDlmEh^~ĬCt8h[UJVSSMAU\+euaX96J{۲a'!j YZ68bBn,gL[=52jG/TwlTnI_r{ENLWA\|u]c6딨S.x7'PTݯlJ⡌k'`7oI('oDUmc#sDNڒPF&?$UF nkyywy?BHylm|jkzZT{kuIV-@ Zwg{9gN'P{*qWO~*80VDwq j.knD-%r{E+{ƷI(uYQIE7(10`ܪX,d(L zX0Y*njZL6e%hw|8rfpT|~ @S jm7m ގIn0g[> Mp؜x-' F1Y tw;LKbb`I6cT+JP̀(RN¶l-ØI>:>Պ4,W TS'{yIhfex>d8;cʨzUA]?TeXʭz+/:YPH:̽9_q"PPpSaeɞyƺq71ɨ >pw26NFŧ!ndfzbATM@=,]l$U'VFᱹLttc5[ƶ (3=!kff' ZS'fh˗B%0>vs-,5^eX~˩),*fX!>)q/Wz_5L>?Y7)8!Wgۗ9ڽv7(%M A)f 7ũO:zq|jVbRRjQvŖ;,砫JNKg=p!->K\6Mz M]rIMv;q -Ua +s rRDXKbj?&P5y%z) ^!;5vIh # .3$1'o@qGq"~cy;SDQ~IbI*CvCwmƝJv?(71 1蚢dUH[wݢ(MrPE蚶?"qqU|UQ/;S^ j|D[jEA~q ȹ wp~~xv Q#)ex-QmVeᵋ D;T~:1GtT`njPT T-+ 89 ܖ$̂boV\Rd^`CMvc` \s:5-0aR) {ޜVXR٣#@ejabberd-2.1.11/.git/objects/8c/37416330a94c4e69557053c4b73adadd71e5d80000664000000000000000000000026112240230175020017 0ustar xKJ1]o/6'D\9>3iOoU- JۭM0P%g6-ՋbjPX),d3 5 %φѳppATr1F؏U[1>^Fxē=N_j˵\[? -OOXejabberd-2.1.11/.git/objects/3b/0000775000000000000000000000000012240452476013026 5ustar ejabberd-2.1.11/.git/objects/3b/f8fb583045b00f98db6dd8be4412c9b2d3ffe80000664000000000000000000000044612240230175020410 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+Oy'oVwݿ/l PH+)LbPkŒON"}HIMLc2;?jiW+&3Z xhA'3^yGK*O9|D6"1 'ᴚNVcPmZ(a_XfT.afjMlI~~N1Gu߿V4&\`^o95WItejabberd-2.1.11/.git/objects/70/0000775000000000000000000000000012240452476012750 5ustar ejabberd-2.1.11/.git/objects/70/e616d8b64b308fe201d22ab82736ae7866668f0000664000000000000000000003421312240230175017750 0ustar xrW~Dwlw%Qe {cb]$Z (ϳO/0//B/gݍ%/_~y$?K:~_gg|zQ|=ͯXgr~M7$Ϲ6]ɟ/|ȯΟ$Fd.xz M',ټHxŻg'gfr#>QI7EV%?ht{dqN?"OlvMwl,_\&cuw3{J>_U:%g, ='Uݦl2.|qdOy 0I&|Fu%"{y0/"[,g Qϴ|c>|3a~5h8. 'IN^tТAo^SO^֪=l|e3f ٦8{͟8+D"c=2FIEfK=7ͧ>2IGb^'/.i~6y'_E"5u6c~H7HK׃d4_QY& j.]Rmo'͸="_·ruէOI2XN&d͒VNZͣNLnt6}4_$4.& b6ͳ$ ")l=fխj 2f(e]6Jnڊ߾>~bDf"/q>~z%^=h0~x g\(b6AWEnZN:C3^ya8{.&^]v{uZkߖn^D{1F B`7?]e<>͎E~~\߃FqP]";>\-Ǔ}Q64p0¶[bv zFSy@0[TK10T5bd$߱hk6cAqWt& w i;Gkpir$EZ5W#.Z'ɛ|Z"tQ-+?ȆxM"H,Q0{8y i 1B.z-^babr6fI$]^q>HL)a=ތy}>}3wt]ht}muzwĶuq.,19"5aq?dy>QOnl|JyfԎrJlq)&gD3\pvb9fEqp*p~ qKnnQpӻר!?wz / &G;(_驹MF,N߶fqF<} "tk!b1ɤRS}V*$P@1Q|6F o4IK]FՒt:.. ̳ 8s V;T&<4: ڜ@a*#e~8=SALTY-CT IcY`yε~q.~0]ovhhw~= 0#fV_6E+#(( _.X<y^|' j (G|7ȝYEOX׿t ڗ7ל//DZHxka<`%8t1^ԙ~=]i8Y?{ĐWBxИl(HJIS\`%Ag-vb1x`*- j:`)P^#Yh]HV`!8czmIjݏpoiU$.F>߯.ޢS@Fd<;KpX'ۓNHz_(|ii 5ih~4p%?.'kmzg?}f Hm}b mn ,uA7$CcD2gGS;`3._qف܄:Te_ߪRove݅Ӂ ??A?זXrI@ 奱* ǔYC}%Ôk;FQ[>^0bQӆ쓡_'Nx11tr ,,F ["绍Ca͚7ÍVM2j#t$1Zʁ:/"~YHy0+u\Ͱ{깽PiI= ,@OcsHET<݃va.0,":"Lv*$8䅰h,[mZqCZsEN6sOU=蓨sNVJIJE9Yfm#OXԓӿ#؟sTTF: yn}~dEkJN(b5u[ɪ^yM8%ytS“`_-Ap#/?Y S?9)E{kgk,E$'G;1,adIvM dcaf[nf\MF[ܣ b~CcK cv"/|*r+|k&JKAVy|]pmԠsI'd -lGu6`Iwp|vC]ǥ6ϸnoqY$ T B ҂)*Ϣe2[u}QBL0*hjVPOs">@E端xNƓ`t XVSu1B(dp oeXԞϙ [ ɭodV\@"$ЛQLsK=gqI^+yRxU")s7Z(UV9D%Qɇ.sV wB`&?qb#HzQF߂06@t6 k;7!.)1+ޖ0mȳoAbG= a)[z9|mQ;7ڶ5JH6ɐ)®a4r(? 4Dtjxf-ϊY- c3FiU$! =;8*klſ}F=I,E[_DfbR~jed {MHZEXW nu_c^AC@GN0ES/hG>Rcq2 oxB`{/¶A 2f٬"*G-Q²7_.YNa]!8T>K)û?Y PvL'#F{>@lO+0yl?F=5ۼ'FaXw0 00ey+oO4Oy s 5!Xr_幂t2sx.MFS~ O&E+p)`MXJ /"hlA MaoѬϽ1~ktf)>0K߾>ZQݪF]fg'/dž&>IWW^Q94Pw1PC~ZD$8*dpz4҃K@ b,fvxO͎##J3Fu4{%aձmNAʋVĒQٖ Wex)œ:b('U+DAg;oO[&,IxhusyQ;e%@IJnjT%RH˿sў u,E@ *\S$kY *A/)g,ҙrv)e l\{{|l}ZQ QXj-7wE q 'rDכP-dF[gƪx3k"AvX idXS ?b"$Ji݋VU_a;Kjamf5/jQ:8joe4hTrkw!PXH4/c@6ȠuZը[^1hi5U4o3*rޠtv7Ǒ|Oo߿@`h?[ CDY`bu\q0Mdݔ"Eɩ.Z *iZ䭕쁕#,pZ@2w)zOS yS]$6!WDZ1OAi8-3 MoY 3Yċt)dGh+]ex~ g B,)UeP]ktlƔ;G&**eG!6LM`L)G<_LrOG~Ts"T^Rmh=^17FZxT!l;Fz`m,5)Rg66k}mGe);/;X#xTY={*y%[Exĝ]1&:²6F|J\}Kf5X Ev7ho_YNjuP޺Zo%T˜+A=wBҭM[69 `MY5PAe$22Ur4UiqDFB3fgX|ȑVmh_/@]}O3rY32gĩS9~JlNIu߃ot]g@d; 4& g`oG@1.(rx"GF٠|OTxêʬU9%<`l%=YͻA:PD q=̆"0jHQ3VEߚhd~koяWִS3B"kηFܫ  fc[Ԏ%1,5G"p cz6j M!*.'iϐB)C! _ZnrAjasXi\ߍY睴LtHW$zS˪le]Y\3b/v- P?S9PUn#W "5ފz^9(_%ET$5tƳE`EԘeayŗYy7dl[sly gsE=w8VvpDtG|Zl@k𡲋 e$}}u0ĒC)mZ%`I>mU@ m5T wc vۻ{! z3OnĻo}Ӑx\pʇWZY$Pg6ړ|9OT>#P#T4DB2N\O<g)/TYiq73Щ~aXJSɔ)4j:5@&k@PeJZ1ͤfn?ĺXV4΢FB7lQ[ ?^s:j)Z+8@Y7a3,/*i28~3f/]evh;%w#Q^qWp+W"q(Ӯ1_IG]@Wf`skhި{&F<vJtV$|:Y5gP' %hrGpBq& Gp3 $U:Bfl3ɐqs>uS%S,Ծtvl*҄X{ ŋ!*u*"b1oZS7ſ/q|ۇ\Gytjt(R WH܇xMDiƌaUegtׇ(A7f;\iͳk"nv뛖V,Fr~ "c 3DTd 0 j;zz;솙,y#OMvzo wB"֭07$ۙڒ| ^@"uMFW kx뱟yz(Gݡ{QMAkosٻ:N+cb@A汱ku䵪-6VZ>.lK;pZA:?kk₶Arq59 gP]  lS^<}8T@!'h1kcۊ]𧬟RQXWtyrrc|8\ >CV ;H I')kϓ*Rx򗓷o)S~x*K̏>r. ?YiD#_]DV aq@xFYP(n2$Jn}~f B@y-ªInΊ޶9[֍*Z,(yvEvXI#[eYퟬqJ:50v^2[Š9 ;4\I !(Odl֭blA 2k*rOAqGrAV"kTΔ.<x)$0n,Wo&EB1G/5>lMyB @F:]WM@MlNAbÎJ@(F0ceS{nl&WMrRg vZh'ㇺƾ6',h 1f=\0HYլi+DY;ЎG*a#h |u\`Պ} Bx r]k\3+'B_C,̎:Vccȥ9RpVrJSiO5_]Lǽ8xi~DR)q{?RrAҤ϶[}B ᖯ Em1L%,ҵ mry Sw@6 K(BcDjp<jl"z'Zj>(UOocq$ocLw{~ƘtjZeBvNQJ5ZX53 bs`툷h,m ST\b9`bFn,@oV3ByjnA1PXZhG x+{:٘*GⲀ 7 p-N7qk''o{sհJQFEM4[( ١ENq#XG^zށV`cK%UB-.3!i͆YcL CpY*0*Kktl:0#8"BǙTv:7]A;Zupۦ쪑h/Fl,WGLA+6V s< n)\_t2"+3y^;v6VygSݡpO;Z,Wߣ+:+c"1yڨ˷dK',0V)J-o[]԰+̹ՒqbܭBԂx>nƙv(a>rNlbd8DwqiSZJy8=_` G-^E:Yee@+Ķ :Ycvianra8U+,B};0>y-cr?VQY> p^j.ts; kt$%"\:!; GV95xԒ &zi{؇".bPf#E @0uw? }2O}gP6և:s*[f0g*^uj]֎S>N.ж80IhiVNĚ%h/+N$rh8ߪ5ϕ 'X{"ш΍tnȾ:㍏!D%t/* 6de.@7'ÖEбj6+'e0$zy4);H|~V%@ltE<ɗT>,7E&t!a^\1x9ׄ%(9+ZaG=4mٳj j[of PuaxBev8D )Bv͓E ]lCI#bXB8EV 7Du4ewX|uR寿*@X}fu&r7)^af` vky7B> e+z`I9Fb)U ik(ZКF790qVP`bi4˪˲UM1d.Gc+ACd3h5Zeo"(-}vxT7% |>hlYHssѭ(kĜ[w(G` W"tA["A'?لb/k r!*+tb%x 4nJo4$>„XXicA\Tq&WTT0c̭pqWˡ UyZH8ٛOt2yU~T(]-(&4)DEEsD9' j|r@{d>J+F$+ӧo1IԿ\Y4\j sN/?@Kt:_$aVg=|tu*q"TNf*KH!}l4]%l05"F,pg/^ۗ!Bk.T:vn'eೠ ߱=݄ƒϗFo;yBмOwx[f_ ,aHtrLlXv͖,=*oe={ Vb]luκys*Uz?̖F]<?Ֆ)"v`Ոb+2^A;Su5|CW6'l\2w VE7"Gv.I++RzmvCء=vkvZvM2. 6yPo=sxRPrWVy56XSuUA?/ϩF!#02bQ>+n9Sg'3#^d}~tte.{:1T3e@Ui<'&P-{+…&^`=v{̙PH@>vPvMJ,rMYܒ~H(G+z fV 1+YBdFBT(ArBM_Ӕ4>0 =ME+(u^yJT4;.3"bINՈήkJ"#;;|ixu!؆ԑAkJp*vsA{H !N)-A+GY3Ouzϲa$OR8,ߢ#\neQFxBrT/ ?u1~"]Zں3W$JEKnQP_P?o'x5*#>{>Ivцc Ǝy>*KcTP6ě~ [Ym[ٌK)uYJt*|BDr*0o:jT-l(pߛѸ'lMuxNv}?530!q+j()ZR ̽&k{˿ͳ~ADJ*{j7IX@g)WL닍_x̃]""VK(u>K"Ǿh^Tukn'#zA&q[-7k~PS}iް}Vv`ĮXlP>(W -)-W-u:gc'nK+ڳNFnCeZ)23U ƙST̊ia!RI"e͖-z 02 /cu0Z~QxXOg}nIbTiEЩ wUѦ*v"Yp"]WѶ`R+&Wh;\rlq:Ye$NBfv]2 6z4*#r{mp1oC#֨˨zRݱQ=&s ;1]kq'u)ڬSN)^{Hi@H@Qwm:+I2X'-UNIb̮9Czr~XkKB Tq3"[U檭iQenr:6N3*Gu:lYO-ha P";B]q>z@X=_ww24VoU ͧb'ReF%Afl ʧVT<€9sbas83Iradi~2ЖqԖ ݙᘆʙUbÉRw&rM=3($]&x;&m',6cs럐6d- c8չ0/9je&9ڌSZP(UJDC1H9 ꧲I c&?(PT+n (zțA6%N~Wl}*[9 yqvX]QQFu ʬ[V^tt{srv6E,f ]þl=Lt.{op!c5QA|2$vel-ѝOC!+ ̃ B/z X V^H^Ygw4Gߟ2%np"]8ll[؁./D +(k Z:]5J끣]`D_Z!زSvd7鴚$\zUíb i `l0 T_$s,/7qR&o#Q*roqD l6>g@-j* ZTa ˓;Mqdw\þ [rlpejabberd-2.1.11/.git/objects/17/0000775000000000000000000000000012240452476012751 5ustar ejabberd-2.1.11/.git/objects/17/5e1a89e1bc748f6d9f6462f90033f7d910f0d30000664000000000000000000000162512240230175020036 0ustar x+)JMU040`040031Qs fq{o>3r Z':깤&e&1?x*RrɅo^q28(94l߾3T r/rR-T* wg{rƽ)ޓϘ\Z*Π,|GiC+9\|Ni7LQ~nAb C}?vKnN\E^Zf:_,9*[gͶ*Jsb}ًTeg0d͌lDQaWkmrSԴҜnŒe&a֫ o90%E +3??%.ES'&%2DXlr4GeI!5 ;r8ZgWo OJLJJ-Jѳ`n9_XF#<3vtyّdOND"2 @4<=&H[n7j.ݣ'˪pM/p,{4qou]WӏU[^UqU7nմhr8q],]˦ܼi݋ʹXoZ{Ӭ-N&]W=[`}ѹv?ˢM 4ܷd%UsuXqgޞd莽nY0уe׿/e"fyljw( \uiuOfM^޺5~He]MnzwY37X8p;EܸGGg-q,uquDŽo]4:ו˲[=ef=+ŷO#ꛧq}ݧw9k7v]3}W%ݿ|:{>,]/_'.?~mW8SaZv~"1Yѧ[䫢`.?秮˲ӹm&RR|^ͺm1%znC(|]o/x\Un=7yUU1qߑOi+0ܸwu޻{?ލWxxce͊]<~NIb; [˼V') JPɆqSc*d_lbF/-PwLϪ!|xrђ4i;!#2rp1}WxVZԎYfW"Xh+Xi 㞭i9' y|lp-(d{4ꞥP@fDK9kʹ(hí'sDV3>͜|pZBxXB0K^c|"Pjڔ,эV%ɺW1ķYe a<% )zeh~ِ~AYZ,W9 1iU:GSSJoKg\B'P-bDr,gxyyGwh X\PAe8ܷ>La ]e\$,s1v 3_ThW ͶiM=neJMqdѧ ,yP(^+@@"w&2d%,E-0|~Ak7F1*b;.,*5dYϛ$JP}F۽Z/?MgG/<&RxkT;+x|xcCc gg! :SrnR0q'/ ec@M2  ү,;8Y_or 5~TENrP+t^ąhd9f$@TRT3L;۔8~@1νG]&ىȼg79gQ`-TT={cgf^ WYQ&j1?6,3twHݢDQEe;ݻyMUzE_ 5=wD,hJcuU^yA搷cU)[/ӎ~@ o<[8(d!׼5p2Wp M+ADϻBnUisrccWX$L=Hw=xdYp>PD6?3tyoZ4W| h⽅@D܄bAF􁻓M%MtEU>> -(F7.kf/Gbb-t!%yr|@˝dϭ ໪֨Ұ312>4^U3\3\-n!;SpZa( t;6ż(Nvz%5 nX*8#S_W4/vծ`լVV[dc[/JmqL(W8d( .̦U~qZUxֱcxNϏҎjެXRB(E>eb9Ū k~U5%Ršˆ#wyie l}sƋ,6m& xAEV ʦU22b vXYP *miv,"rZiM<g$2ƈ]pE_+(#~x~X%0g1ܘ~S€@+Y!D1SJ 1s~< rg#fxΣbWePSv}ϐ:o#YXb,tb-̫9f:#4$%$ +)uSgYU'x kk8z{zwQzudt}ܷfd% 8 $$%_n{$@&?Y/YK2fX" }l="`(G+be#I!/#!Z\56QScBQТTI15B0^%ėAr[TsScSܣ%990Nh'X č4/{&`9fK* ^ޞ{>]mxF!'ءёW~w|t㠩G0I>Պ1qPL)(TGFE;ݞf<=h A'EbHw~>VpyYNL?+Zuh)HYdO}(i<_+߾xE:rfdK0 q,ifӝC}.@"U6 aϪʺS МR==I.wF1÷~) E[I_B|K!Y#$hTj[ҁSX3d 2Iބ sesH /W aeX0s|qw\3-{?~q1"@U8piǴpJJ&/ :[eN뽘B9 5S<~&uJ;u{Q©E `f'α0շH P#cנbWUƥ=Ia]g=cKo,z7 =RR`}!6Vb6WJdy]ETnLdž*̩Rtkd͡ʮ1TahlXnײѮ={Y|k-']5zoC9cO3~kGe&G`xcAQ Ifv:qV)nt-/F-Tx|^.ue65#_Z>ÍS sW&msZhtk59i(φGym;S`Y2^6cJ}1fW#\Qߍ46sApם M[#Qg!TǻyHm,Oо$SO9h_y&r m$+8̣4J[x!GU8f6ݳMﺰ Hb2XMR2V.cNT2PiWYmDN Щc /۷f {_ v~$||!8 ,F:Qo}*hFHz/H4n 2hQ2pz TK{]͡DZWJ4+_ۥ)FaV-׽8~Uu|`]s o6fc*,IGh9N{g]X#$3@m0^GYceQ"m;ZyW'%>QX^/`à&͎|Ua˜pFL$IMBkM@*(aHۤ8cAٜQ27:-/-3xI펢_Rm,{ EwȖ`Rj$HS,U$'.PsU4==үBi Ae98b/'ZHVBF!NLs;:`dM)08(ya}NQV9PRL6lXuWJ4x\v4C_XoLJ:!~iN'w+P$]w92C8N/E <cg-kE͚/Aysl} ϑmkfذ UVϪrF10*@EsH 8SQi ᢛ2̍F ,RIGSu͊w.ɪ]`EpDVV8m&¤]JH3oÃ/gmI?~d/+ı^q'i~4X᝖7ٰ#m8g`lLE@16қTv}=06@z|Fo؞.ơLjydFgvlmf~!-Z`6g/Ϻ LNi9ωx m H1-=t&8~~$ESQ{ )|I=X,;3f?쭿LY ͳ_>`vʠLGǢUb\1HT2{(ұ>ԇ!:(X-Ԫ`}fu;Fc @0x #T\'?J]*O]ivY3Ƿ/F3 ĽAKO (Pک,- gzӮA~xx*3b}w9+T"VzJYڞ i |9")=&#㔉ۿRk ;&±"[r?x ;3ЎSZB͓H'3O $+u2 8J"QGگVsx}"%r+m2XCG_)lwj풦BC`[^lgh>ɶ 6i2iFä"V窈v +=9hZ9p'rZER uEB/Dc$!tDI0;d./t̛ffS; 9;YSYI}S^kqJ)o$yu%G ƙw-;wLWrgwز){Trmf> D85shVO ($r&7zމepϜH!~)$Bk|^Mm2vhz| ;riOX94 8o€{!uNJ͊?G.)$ɋx>5M@[zNoΚFG(6#X&5Q5†MP5xa"4L\icU$u_HYz^Duwں Z)ϋf)}=<6'9m7xc7Eg8ǚztLwDyLJO?vs 7y}ejabberd-2.1.11/.git/objects/17/6a7fa298a6755eaa643056dd69d77cc6be9e660000664000000000000000000000113012240230175020201 0ustar x+)JMU076f040031QHN,(IH+HR zN{e5B1P)ʼnI9yũɥE9ɕEP"1 'hoU5 z:7?%>1%73Y}wT-^1/Rs+tS2Ӂ--HKAjoLX%\'~*3k• <ݜ|X8Wc|klz-|-N.J/(KIbnjIjt`@t5f/Z- Mbe_ZZaVrg`:w[n[85> ;=>43'%-'1n]ӂ<_-#Dm'ejabberd-2.1.11/.git/objects/67/0000775000000000000000000000000012240452476012756 5ustar ejabberd-2.1.11/.git/objects/67/16aa6b176e4e79158e5e43f3e6e487eaf1ee150000664000000000000000000000024612240230175020202 0ustar xKj0Ьu>Uzfdb+(2!xjmuxC|NҚX}fG1f1[pQOrLH$k|:X &*ш Utε& /k?n,e%㴷 K[U?NL|>:1LLIejabberd-2.1.11/.git/objects/6c/0000775000000000000000000000000012240452476013032 5ustar ejabberd-2.1.11/.git/objects/6c/df32e28cb4434e29a90bcc501b6b2f8f0d89ee0000664000000000000000000000032412240230175020372 0ustar xAN0EY#D؞!.+6pw [/sY-R׷qmVJ,^A!<=;PS{4,?K3Ǵo^*uGX f_ejabberd-2.1.11/.git/objects/92/0000775000000000000000000000000012240452476012754 5ustar ejabberd-2.1.11/.git/objects/92/b939943f92bf031792ff2ce0fe1794ab59c1df0000664000000000000000000000331612240230175020202 0ustar xWms۸WWlus^HԋթwIi;] H` Ȳ/s}JK|_X\G^sTBc:wĊy)XkE V- zʜB;M;t^p%'5Dy+yJYt\%3:^dAJ k% 50toW8HܭĖ]*%r!!P=VqG*)TK\uL4. b`BC&-eMz1"[!gHrjQ1Cߍ;Ny& |wo\Fd$?Od6 -]Y#s[<ѻt"ߌ՛_N.\j|xc"8;g?pe%.j zt^#w5JHY**1ٺy DFg/h>b:jM[ -uc:9}Ρ#P"ՋpX-/8ʻH=-,ub5kX?_7IM.}:[2dwsuU%+ [|2cD7W>3y/ߖ!N˘H4Fe%Z9׊}ĮD_0>;Y[=|C3- ξW]k.JyiۀhzI+ NAf$,^lT<gzSCem1Z==wx"sil؆yc׾{mdObjo_-0.}Ɩ[[0^Z]s濉<廒Y}, f3$R'c)`l;\[Y@+X,?+d5Ǽ,-hIeoya|R 1c*\`bfre<B #yTOF+FX8}?g[W~xϥۘ^z,`;jd&WrvnkAwNp[<0l4nR Ugua+<͛7/Wejabberd-2.1.11/.git/objects/a1/0000775000000000000000000000000012240452476013023 5ustar ejabberd-2.1.11/.git/objects/a1/95decf86dd2c3787949405327095a2cb469bd30000664000000000000000000000072512240230175020040 0ustar x+)JMU055g040031QHN,(IH+HR zN{e5B1P)ʼnI9yũɥE9ɕEPejabberd-2.1.11/.git/objects/6a/0000775000000000000000000000000012240452476013030 5ustar ejabberd-2.1.11/.git/objects/6a/391be635319a22170dafcbce91b9755ede73b00000664000000000000000000000340212240230175020223 0ustar xW]s6ō^lDɟQڎ=N:M'ID  @HV:Hig<8Hv6?A~Y&mA;d4I]kE3MYuYpDQ8r~0V.OϓN _VUZ@zH/z|BUƵ%xI 5KhnM{!Rx ߌ-xL#J4HZC+cocڊrS/MKVO wLR- s=zrUm,w1h.\u^1'SM/Ō_ *,d+m(YpIBpvUej[Z>@̍6xFp&t.4M'{4ٛMfc[[}iF*W$Ct@y;Bb& Cչh8o(P>V69 5g|ka^˵/ )>Aqk_t7܆)팗ŽqۑU[Ƶ DQw3P@kʂ9!S:D =@kN@Blא 輐D]Ve,,1 ,,G c3A+jb™D Ԝ햴Mbq[&7LZ0"Ap$bBKN;~ssFf2߽fH)kkYz4r:Et/=`BfqY\ R3Ylʶrl6!еO^zAei8IMƗB[\և@ӂb(gaY Kz!x }4(ư_bɃxKc{rE''$Tl!vÞ9ĈYoBCR_00HbUp JRv:)fRb*tx 1 ,es & \6ИOw¢B3<'TqbE%ʮ.9Ih$*Bg5I\׀̹F–gw ִt:K䟁wd4&X339Vվ.sOB1/%6Lma\|_FU[ks7\!wlY^bcxJʬlpvpaƐ~sc8:.6݆3"ҊVrr{7~JTkV`Q1CqW_ > a+܇GU`"xXhR=-yBN8=z,| L N9R11&O T!+/H +uȢ6e~pxR .ՁAīLču o/ ¢[ yaB I& I[z=AYf Hl'}b_ɋ[dB\ɸM -Ж*6;9X?xEAT&GKH@'ejabberd-2.1.11/.git/objects/6f/0000775000000000000000000000000012240452476013035 5ustar ejabberd-2.1.11/.git/objects/6f/96b3316e0ffedffc0fbe21f870475e05e63cc90000664000000000000000000000044612240230175020414 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1dxܓ 30eB'3̉th-Xvm:36CdS+s rRNرd>?f ն*zu!Jn/dpr}-)fڊD 9F1tejabberd-2.1.11/.git/objects/d7/0000775000000000000000000000000012240452476013034 5ustar ejabberd-2.1.11/.git/objects/d7/8c3a44ad68787cf64f3253863717d4858cc1370000664000000000000000000000162612240230175017715 0ustar x+)JMU040`040031Qs fm!WF)9o:T>U%5)31ACq붊CVo >=Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?a2EAlW4T8 S[XP(6ҳsu`W cyKYmw=}?F/uq⼲}Fp%E% Y36<8QTX՚:1E[(%5-4odٵxw*[N=LIfQ1 O}5:`ɺIũ &V:۾/A,iRBM1Î/w)N_&CSRR,~o<|-|g<=]UrZ:؇ 9o^Ybt_)mchKrv~?|}֢k/(LLaEbnANj1(kqWVY۟~IL Ǥ&3/D/R+dvn5 3{bdae$0 (hQ0Rdv>9Os'`(/I,Ie73FDS7@9Ϭu>ļtkW]"q o}uI&@L7@+X=na>'炐1:|we c^0Q_\r. v{q@RS[pnkT\1v(J*I{Pg-sSSRP:^6)bs½ dCY\YPRpՊwX zhs ԎT`qN}WT繆5e= JYl ̝"1~XPejabberd-2.1.11/.git/objects/0f/0000775000000000000000000000000012240452476013027 5ustar ejabberd-2.1.11/.git/objects/0f/2d497ad89170cd11376585a519c7e329b657fc0000664000000000000000000000162512240230175017760 0ustar x+)JMU040`040031Qs fXbsyWmK|,Xj*|U rutusIMLcTh SWqez Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?ጱOp=-: S[XP(6ҳsu`W cyKYmw=}?F/uq⼲}Fp%E% Y36<8QTX՚:1E[(%5-4odٵxw*[N=LIfQ1 O}5:`ɺIũ &V:۾/A,iRBM1Î/w)N_&CSRR,~o<|-|g<=]UrZ:؇ 9o^Ybt_)mchKrv~?|}֢k/(LLaEbnANj1(kqWVY۟~IL Ǥ&3/D/R+dvn5 3{bdae$0 (hQ0Rdv>9Os'`(/I,Ie73FDS7@9Ϭu>ļtkW]"q o}uI&@L7@Yf,+[bv7zͱ}Ҡ*2͖}ǃ@y|OZQ_\r. v{q )ex-QmVeᵋ D;Tl|ic変_|PBQ)(P/kUe}!,N.,()f`8\j[,EV=4jGI*0fV8+\߲yUT I,6zsNTXaR{Ke6>ejabberd-2.1.11/.git/objects/14/0000775000000000000000000000000012240452476012746 5ustar ejabberd-2.1.11/.git/objects/14/3b0ae82627e90ad1d0527419189ae5491eb5a80000664000000000000000000003426112240230175017734 0ustar xrW~{"L+ rܽDٖ[鉉 v(h(4 DO>>s @v7fgd:|e9<4z-=?dUo֛Zav~l~,"=g,tpqHMoh*E~w$y6&t1J.FFKc^I>[i:g$[d"&՚UG%`Yq|y4OU:P$].&YLjSRy,lhlЃl6D=[Cqd6Q6]OOvq5!`EӃ޼ XAD,h:ge Jm2_d}MqB?eQV$Dzd,獍/b̖8c{kvOQ}uG8N^\-/:lNDjm, np> 9:jUb}Z,#8"0ɇgp2̳Q!ok`ŭR|9%eP9xfx.N P,(.N=g5[uܹkԐ;׆eff8/@(_驹驍,D߷fqF<}"tk!b1RS(}V*$ǿZ 7LxKۭ}Ib|4Qq%XS%?be+]ZMg_ޡ2IY`h VAip/$wǮO Beg꒽oaa5d^?&5 \+ušAh Cnt q#ٽW]ǛFs{Ԋb+æ(Թg1, >[O33!?;d) 4ބyg!Ő'w!~DR[BҮ8b>(> -\[Κ7;fϖ[UPy&0ZS%k/,av ͓5ĆIP#B]ά"_LN8Wk".S0_ZKPP-L.V4,n=bɨ*4f +D~Wr<X~oIG*w|AXh0ZDM4Z# jk=+ ,gLT5Im{?ąB%[4Ȉ=ߝ|1s ` Nd{ Z /-/ջfq6 XN[O˱cٮkuHE&y2zlnEB"[aj]M7IY69aJŵ#¨-Z\ I Bj1XiCЯ3>NS !!_-AeehDyK|x1hYvQL*}3܈kԮ6D~ MgLRC5{A["m' R7 ;OxWo;8 ; |pRܼ#S “/NIHjG}=l "B)q.RdB\2I^VjȲeڦ7E>}W_Z'8FbQ'I S련=3A7@[ߍ=DH7.Xd {"V:;\0tm񪖷kERnPƥ\sKJj']H!&d<*DM**Gf=Sa[= ;҂}9'܄WpsĬx[´"zL1UU ISfvSzrF%Ox2ː(!TU:Ȑ\jl7)+Rp廓_}G,U0o!GHh(!$CȆ˙c㤯, P4_-8[Z><|o^HB{ wp.U,m4lX zQ7,FhŸ6׈ Ǘa0(oԏ-60ES/hG>Rcq2/ oxB`ޣ{a۠Bd JjlVcfhMB zl$ **;eEGGFH14R.O5nr՞٠LHf5 "f'sЫa0<Ss~S 2]}Clp# F陎(HgXpc:|1"b|F=\1ɻfy4=54 Jy'KNږab$=#Jh)1`_'@W&o_&nԫhO,yQa%mYpe]Wr_<#B]_pq]a;ϓ`N7[Z 1_B[Z+!ab '}puD0z|U5A:kU}`aW,46ߤAn?*H%W%/ Ey%9z0;TX QNL@TӧwjaFS$~6X-af5Ȍv5ax Nw b`D6D' ‰mR)"2_R]pS$&h5 =CR3ט2SPHMk/R.LE-*0Qm]`R&0" Q#X\P1wd%A D(#IrCuvӨ핃2HYRDeORCWLiڿ2f[[EF_7)673T`&9:)).E0@?6Lo8-i Douґ4;嫘qHsG4]P\*`Ecd掇Wѕ&̬a,^ yWحP pĔY:Ѹ6-]|>B;ʣ~GPKRCrXdVHE>$l:&Jkgd6fj0 (|H@ b!7^o\)pxԈÜ]ߴb=5"k헔k (yܭ' "c|H>gWГE.{lqe7tHG\?`U|Zn3{[ ^1 SKzN½-9wNY$򧛃n#Ɉ1 }y o=3|5O'zTZ9{$2&&P=F|(@;6,TշHBRֳ]AmDʯ7[1N{G)4+?!/b[rID=*R"^d(m;~m}]/Chj[a qݨVђMG#lx7A,QdKfkQ_G^bmcz͆}|'4\1CFaޟ 5WxHAjwU0@$uO_HxEw|ॢ 9y@^V?eߧj4YNrrrc'I>,aH!+݆$$?Igl?L<۷ ܔ)le?? jc! a${7dgEoۜ-Fa-]~\+s0"óݕ]Sjllt,T Jn]i!M|~f˘1X'5͏H*%n @J.HT/ٶ`O:5Ὠ͑! E6ס\MzY./ױtHFd%@|H G]{BM[D^+8ZeSz, 5b1&yV:`TV1jhMz+HmXo;,ڬ4KW/yXضѽ(ǻ,1UP?wF[y V-QJ>N6Q,qM\Mq:vZh^c5y7QDgQa%` +nCEvhQ"{3&򺃃CXJ[:]* fby߭Cb)" G{Ӛ ǘ6,T_(92TaT:uDaF"'qD&TK΃tnLv<M%1 +U#"W_fCY(W:m+@Tx@2WS2eDVfv|*B_;ϦC7"pVYnꬌi.fZv%/&X*mu]Sò0VKƉrj 9R g~g3mNP[AU&rJxF$oWD;sh56xg٣DX#`&! W]&&+ױ\%A&_SF!Gʦ#!yZ۽B jHu1?Ӏm.auzyЊG- `«VG}(߸~zI)iv3SD_I}7{cݭP}'@-8wEac}p9[=[8)oV&o B\֥E%A}ՆL0xز:V-fE$,D9]ջ'(]P~ҩDoז"eߘ޶wTS 'E~/b蓒vƣȄBA5D5lՋ9/瞲8g7Bc"lȰ瞦-{CT~/|+R7 O̎'·!_ȮyH1SCA4kܟm}p%! {D 뒧NyC!I`B\9ibC{lD[ 8 ) ݟ<B83b ρ$Xyu "L ÐQ9|-FBȧl[O=I:^.ER*a8m Qkc̓F790qVP`bi4˪˲UM1d.Gc+ACd3h5Zeo"(-}vxT7% |>hlYHsu(y<91bPj (m D6DN 1&< _^(8B QUVyp؉%xK*yҐX;Q]|E[|@Cb~ï@ ^B!~i݊hț^}|owc`rV;|+YꕮHDIQVrvxpYH& )!$UZŹM_G$kKa fci^@NTrqs+5bL,V­*rrM?67Ckql8W"6  |q{B 7kJnDPh?Dz5SB+XS ㉰+gp0AL78pgQ5OzĢRopR}!%/_"' :맫kU-BJ$a&PYD"HUB&apQ^#btβO0{}"/6KSh vR> j{{hM!n,|i.'tgQe6 N,j Q؆%hj;YlJ҃Z{`t_W 8Y;o{aJvèK|n"B:=%[lQl%"X+q'ݠ9JR|awMKY:>ϪhP| _<,f\N͋dq34YjѤ@K𕭳gJHnpɌ؝ ї Mreg> g`UCPpY<ʪXDbA6Z3R8U' ^ln%hOȏO_bzu#rzE$_.1`qd!AGjǮXcA-Zbdjt{.J]d̔xvH=Zf1FV]56![&0rIhL'#lC-]`r羚7/^jkW#"Զp IH=q+@6bW4*xڌoQ{؏Nxa̚&ȳc8H]5 u bͮjQ6ɸs~aT.NK_B =_YP`uNT`xEX4^FBVLwόx/[fzhSSάU D@E!ZWxF xm87gWw2gW@1">A-vhhG&E,nIh?t$Os[=Gya boy,!2T#!*Wav{BM_Ӕ4>0 =ME+(u^yJT4;.3"bqNՈήkJ"ӽc;;|ixu!؆ԑAkJp*vsA{H1!N)-A+GY3Ouzϲa$OR8,ߢc\neQFxBrT/ ?u1~Ngui'j|^!ےP(-EʾC}݋zJ9'֔V$Vr6ZP$E-;i;,QAoud74nUd!nJd3DPt/e1+ѩ U}QC©[orG;t*o5u:vnQĭ2ҋ_/xkK<0Ďogg/7^[cA+%t5I$Bz'c^_1/6">OyG0v%[-Mvx,!/ZpҢ "{S=aSM8w ûa( nܬ A9HPN!y&[mbkCZBO O\U.ö˷^Ѻdʺ":.yehbX:y5jm|Ix'fÉwux\E۪R؟Jh G|\) pʱiUdݓޖ8 Uum7EШy :M vc9c:98wGHQ?Q;zcr{L+vbO R哏RYDRVw G8濑<~etV.eT_;KB9ae[$m۝]ם#ru֖22&26gw[; ˻C Eʻdm;U[HӢtlfTt&XK*nZ"<ˡD;w:S!ߍ| W1"{H8vdhTs1^v jA(O+*_3ŠOBQGJ.BhO@̏yshVb!LDqfT) RqS"dZ--'@31 '3ĆZ3L -5^zP`W;lInLvLr9ۺ`OXgmSk?! m06Z@p|sOa*^ssLLrD[^ PbErOelL~=QVa"o٠:[NRG3+óu1& pCP&730.m2)`6XExe#:2Wh6=M?eJX>p+2ݷq]^dVP`@jxv4b2*FwI'̅p"gˊy4c$[Α~"Wad^Y݆4ZF'zM?cPݖ&F֪o_|!b>c; D|•6~3NT*c -}7ce&10'i>J>D}Z)6`SXuٔy "hIejabberd-2.1.11/.git/objects/14/2a975d52e9a30f63b075359f05c9743ea9c7020000664000000000000000000000101012240230175017651 0ustar x+)JMU032e040031QHN,(IH+HR zN{e5B1PYIIE)EP .;6d?l`ؘb ݜݲĢݬt݂b^ &/2mXb]oBXg7?%)Y7̼ta7S.;ɟ,++z6$-E@ź9%%%źE%0K-/>s~LJIF}S+s rRa I)PQU0sSSr3zJ`[ <ŵ_zLv(J$C5$Vd][Z[ޘ )KOOUfք+py9pQ&&ՖԵW>˝8(1W7$3?/1G$%E 8pJӁQ |ohѮ64\}fPjQfj1Cʎv |ksy۶/Pũ)I9)i9p,/=ml ejabberd-2.1.11/.git/objects/25/0000775000000000000000000000000012240452476012750 5ustar ejabberd-2.1.11/.git/objects/25/ec1100e7a001ddad6dc92180a3202ab70002690000664000000000000000000000162612240230175017736 0ustar x+)JMU040`040031Qs fm!WF)9o:T>U%5)31ACq붊CVo >=Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?iWGqW/T}(? QnmgN] "/-3At/fz~%E9 Jߍ^yeJJ *23JfFm6ypګ5ubv|)TQJjZbiN c7bɲkZ0U巜z̢b"j|uUsuS"L|u}9^kw}YҤb__rST3ګ7Lʧf%&%Y0l7xZl/32yztӱrlS% V^E&_PxR|~/Š܂bQ>䭲?oITMf^f^ CWNjZ-;Df¬+.IaPƣ`\ȪX}rN!Q_X 1oRgnvrY7}PEy@%믺ΧE@L @n3*z=e7j%P f>O߿AǼaa9 \K'>2} ꯏ:(᝷GZ՗.2vbSQ T1 &~r)[@榦 E@=t>lRV{_˷88(p[nXDb%X1㜮s k<*.{>TQ9(8&ذ͙;QaEJ-=:b%ejabberd-2.1.11/.git/objects/97/0000775000000000000000000000000012240452476012761 5ustar ejabberd-2.1.11/.git/objects/97/c0ad015a070bf80177d1baf3ba2a065f7c05130000664000000000000000000000025712240230175020115 0ustar x=An! E)rGU6=2c!5KKߓx{|]F@BY)]ѷ/qCϴ4 H%:u=1[,*dMtƂPNeر!Txoh/7o(Zt찻k1k7M=!q:hejabberd-2.1.11/.git/objects/97/9a86afb341caf60007e1afebc99cf20f0929f10000664000000000000000000000026112240230175020315 0ustar xj!}uPJNsLVh5O#>K"FuKETև%Nk4d\fB/KChh d1>[&e=c}t>n0\""֔)F+`YV|b^!PTejabberd-2.1.11/.git/objects/69/0000775000000000000000000000000012240452476012760 5ustar ejabberd-2.1.11/.git/objects/69/6064ea983c776b54d3676c8a59369685a25f650000664000000000000000000000101012240230175017556 0ustar x+)JMU032e040031QHN,(IH+HR zN{e5B1PYIIE)EP .;6d?l`ؘb ݜݲĢݬt݂b^ &/2mXb]oBXg7?%)Y7̼ta7S.;ɟ,++z6$-E@ź9%%%źE%0K-/>s~LJIF}S+s rRa I)PQU0sSSr3zJ`ط|N՝rx=^;(5'B7%3ҢL݌ļߪ&TENYzǯ2&\k/Hɇq5}ͦ7oR7\]`$榖XI*MF 4@_aEN_$vpQuAE );ۅ7O=|'m۾0BUƧd'f椤$-kZ܂k5?4|4>ejabberd-2.1.11/.git/objects/b2/0000775000000000000000000000000012240452476013025 5ustar ejabberd-2.1.11/.git/objects/b2/69fd0180d9184b3dd25c5cbad395c994a388600000664000000000000000000000077112240230175020110 0ustar x+)JMU03`040031QHN,(IH+HR zN{e5B1P)ʼnI9yũɥE9ɕEP7^h׉[ .ʾ3((3c\G?ή>85> ;=>43'%-'1ir NRӖLyejabberd-2.1.11/.git/objects/f0/0000775000000000000000000000000012240452476013027 5ustar ejabberd-2.1.11/.git/objects/f0/9a638b1d4972cb533dc0b689bb389b86a6e1740000664000000000000000000000031712240230175020110 0ustar xEKR1E 7unH%y Bb7mut H Ooy#H[E&Yw 6ć^hCK膗QgeMrLw^0\AZƂPIXIJ]d*|E4rͭE<R:sLy4ܡi/ ܹuHu]uBk8ap+R_fqQejabberd-2.1.11/.git/objects/af/0000775000000000000000000000000012240452476013110 5ustar ejabberd-2.1.11/.git/objects/af/1cce749d58e69bf0a9583acf956becfbd3b3eb0000664000000000000000000000044612240230175020716 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1N=eGu㉐U޼{&9 ?aN#GCm|gjo"Z[ZpZ}Ŏ}'1[LMU[ QR\p{׭'ÍncwlI~~N1Gu߿V4&\`^o95nx1ejabberd-2.1.11/.git/objects/a4/0000775000000000000000000000000012240452476013026 5ustar ejabberd-2.1.11/.git/objects/a4/3cd3ba5adb23afa44c38e43929227c99ea7f530000664000000000000000000000340112240230175020306 0ustar xW]s6ō^lDɟQڎ=N:M'ID  @HV:Hig<8Hv6?A~Y&mA;d4$]kE3MYuYpDQ8r~0V.OϓN _VUZ@zH/z|BUƵ%xI 5KhnM{!Rx ߌ-xL#J4HZC+cocڊrS/MKVO wLR- s=zrUm,w1h.\u^1'SM/Ō_ *,d+m(YpIBpvUej[Z>@̍6xFp&t.4M'{4ٛMfc[[}<;592'*aQо@; M55h!@o__š@vk j̊L|R[[ _}TN "%\l;6ͤMhgvݎ 2e ; pA*]S14@D$!j\{p"eƯؾTxGl%.*cf&f&f`a9H[1< XVS$jPg6l-@h 2agZU#aZu32)5;@J)\x0M_*G#w?^$8I-aVLgEjʵ EZh?E˦l+9a]䥗n ]ÁMTti|Y,u_@m}4-/xV:gOb lE^.<7Y )47,Wy:O޼~BaJr.0n7YqLoACȟ&>+Yc C: \$VX缐yX.iRkx)u?/qhM*!@ˍR6ne ymt.,-4sBOP/h!{nQTacFb-tAaIKZu |k$!lyvG@:xX a/lM۾A1m^`KhpGKkl53CoU2$t Rbqƅ7;.=eT\+,Z lv*db:˽EnqkրvR 'eA^ ĕ m bQ:㙃o[ WIer9T tr8K; Pejabberd-2.1.11/.git/objects/d8/0000775000000000000000000000000012240452476013035 5ustar ejabberd-2.1.11/.git/objects/d8/3350712bb91a32b96b06e4c0b5b2d5387e3fec0000664000000000000000000000044612240230175020143 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+Oy'oVwݿ/l PH+)LbPkŒON"}HIMLcw۾ny֣S*`*OfxHRUN{s;x2ljEbnANj1i5;l16UEo.DIqQ2_:\t1>ͦ՚ْbnɿhLd0ޘsjEvrejabberd-2.1.11/.git/objects/ed/0000775000000000000000000000000012240452476013112 5ustar ejabberd-2.1.11/.git/objects/ed/a805df3b81bbf8b53b4694106c444fed44484c0000664000000000000000000000102612240230175020234 0ustar xmr@Ds+昔+Rq* a f]hq>v~`鳚 Ќ9 D$1TTF#Q0Q">rm`c5qӻJ G]F`1+FL9}Gߟ_X"# <9.>60`NSM7Lxva{.ffg@ (-U7_q\DSUm[ACN5)(/c5ė#Vxحc̹K;]*ua3Q.* eSLg!]f1Gi5 ,!Lhs֝`^+nIrjز"[`}3E۬5jMAZòpuj)tGwRO\=r3ŏ,ʵVѕiOcVVܼ^h'mhjpopl!9Vv5;=jۋyEc8kE8tE)!l"4OS)no_V~ejabberd-2.1.11/.git/objects/95/0000775000000000000000000000000012240452476012757 5ustar ejabberd-2.1.11/.git/objects/95/1dc02ae3885e4b908b84a641f6137b22028cb70000664000000000000000000000074512240230175017736 0ustar x+)JMU057a040031QHN,(IH+HR zN{e5B1PYIIE)EP .;6d?l`ؘb ݜݲĢݬt݂b^ &/2mXb]oBXg 83/] 'D7X(4fCW[gΏIY)aB|jEbnAN*L?!i:j;j`Tun~J|bJnfPOI,48} VKΠPdԜ ݔtktK2u3Rr΅joLX%\'~*3k• <ݜ|ZgeaboRmO]|ܩˍjsu J2stAZZb'4PK_aEN_$vpQuAE ebX~q]Zl5Pũ)I9)i9p,/=ml *ejabberd-2.1.11/.git/objects/83/0000775000000000000000000000000012240452476012754 5ustar ejabberd-2.1.11/.git/objects/83/1825cc764917435900657c7e448ab71e269a720000664000000000000000000000042512240230175017456 0ustar xKj0E;*tX0~"Jdl@Ē,%dU?;ks򗜈@Qs9$Ye;E.$bN28bzt+vu¡AtSLpa:9q>1Qښ-diJM(v'm?`Mr99ANU t;%>mV]@Y=KqX yeq`:)WxѰ/Iejabberd-2.1.11/.git/objects/d6/0000775000000000000000000000000012240452476013033 5ustar ejabberd-2.1.11/.git/objects/d6/410e66a84ad3ada81357a6b42e25bc7a3e0a160000664000000000000000000000044612240230175020210 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+Oy'oVwݿ/l PH+)LbPkŒON"}HIMLc8 ]Rg۬k?Į{ ?"?j^JU:A 9 WwzńjTպ%E \š5r 4VkBdKs>%1zcΩ>wejabberd-2.1.11/.git/objects/71/0000775000000000000000000000000012240452476012751 5ustar ejabberd-2.1.11/.git/objects/71/7f3b66fba263414ce39a17852b4a5c5b77d3090000664000000000000000000000042412240230175020014 0ustar xKj0E;*tX0,6A&%5)6%OBv_.ι6nR@PT" jЦBPIFJŽzcd CG Ťd=zB (ZC.:%q[%կckƔkc`G*/TPJvHKfE8O7:8}sS{>}K !۾@FS@ {nБ>XWvfL9#_)ejabberd-2.1.11/.git/objects/36/0000775000000000000000000000000012240452476012752 5ustar ejabberd-2.1.11/.git/objects/36/0421b4cac1d1ae790109350df9b47e6ec05b8f0000664000000000000000000003362312240230175020143 0ustar xrW~Dwlw%Qe {zbb]$Z (ϳO/0//B/zݍ NK^2$?K:v_gg|zQ~,"=dHl:$%ɿ%bIշ˂֋|9f<"Oşi&fhf<&_7ݭ]]>ΓiHi.&IZ$<_j'<_,)lfխnxxf69e.?%g7ٜy^<fkÏo_~\Heȋz&8^9߿$ˬXI1p"ax6ɘCW;yփt4iﲳp=ռۿ(Kb_%+uM9QIj*ONEivT\.4ڍhl9WQOyD+6fSrMO3- ; qO~]`_<hV$?MV4_-85,],ypVڙr7FJn٪{%l~>g$OGX:W{pЕ`K5eW5B#9w| WHekd\1b\ͦt{VϳLR1{P=.o$؍l.?"g7Ҽ丶cJO_ev9ɦs[9FOF3}muwEL'7Ǥh]|8|t gBzokxR|y5K)6ʮlMGo6^0 YػѾ_Q(;C3JI4:8>ռ'5) ?jrgE>J} ؁F;ivp}k8xjux^◗5ͭ<@Lm|iv1GG{p{/@2]:(iŷ ͧ[{`j3S| HLLVzuB-9L4HL)a?ތy}>}3wt]ht}muzwĶ}a!9"5aEH~eM|*\-l|JyڱC[[->e@&xf ?0+SF/ޭC[uԹ5jϝk2G3kk/9H> cT/&tݮ p}ޞ_fNrvy G ~+~sŬ6'JMRw T+Be ?GH,&ju-[ X& 9*<2%t\\LgXpjV)@FeHY`hVAi~t/$wǮOiL231)pfsP $CId͂m'!\X3"aHٍGQ#ٽWݲǛFs{Ԋb;'3NyUkkkÐrdY??D 7___ eCqp$aPhlb>,> Z+Yvҭ~gM֛v3Ul`"ذCpcJw~,F+B=(϶,6Z<2((_nX<y^|' j (Gt7ȝYEOX׿t ڗܔ3^n2S5 V)Z/-%F((Xib5Ix8`#S,bHJӶ̗K>ZΟNjsWiQ'HZʎfBjXa&v?BTPFQ^Ej)Z ?EdFHd<;̈KpX';LHz_(|i5ToPZ8ܧV/q9q]#pl;u[gi9`Ro8꡷Y}/t B5JVt߸~˴:[6A@x#c{Kq!Of|L մ-/UPP4S f7yLS*(;0hq+|1 ``Ģ 'C N,4bc3!eehDyKnb*jfxp#bS&%D71Iy 8r3>nwmqR~{dE{JN(6b5u[ɪ^y M8%ytSH  Q_IE#m;Y S?9)Es8X .8[s$V*HNwdsXM  +`r0 (m26,' "Xerz3CcKcv:j6[v߾"^EnvoDi #j6ڞ =C5/OtBFgBBv!h zo=+g]h0ݐO; -;.5Ձ$?Z"AA#YZHZ!E iN*39諚{>\~S6YBm<=}|V >"NccZ`t XVQu1B(dp oeXԞY [ ɭodV\IՐ,BoG]0-""ϻdKe8t"wJaU-oߊhKWYFзrD&NALYhݿ7LEҋo5qwr:'܄WpsĬx[´"zL1n^z:\Z!|n*BZΨOf% P"@1OrE n|w|zӋӷ 1򣞅-D6m%$rda0h9sLz ?@*; ";j6;%g˳byVGg8w&($pgRe͢/ֆLi;DŽYEubԌXLگY8<\0,a I(kvZ1Fy?~6J"|)t")ڱ8A4.=\="l@ob#CQmjlQ/rЂ%l ,}ex ZѥR C峔bPVGRp@Lt {J8hvqT(IψuJ 7%f$L޾:M) WyJa;qJJ%m[,xcdY'u0P+ N0X0+ױ-3dbpM ew2_z`3')qQFoAHnj;Gmj4DYbݔ^U,'`۱w+R]o:FCmiX{63{"cYs,`O18􋊉pD9TURY:m"w6%j p_:85۝uEuƖƽ _%ˉ<6N/NC?';-O/7{1M̡~Z uIa<<r~Q !|# E+#-Y|4r[طy`skO<F+|iyBr|%#ၼC਽ҤQ]\֨9 S &iMqu rxԡ `kWnyt]LzFEnwX!f8/߽>W? g~( L,@^Cn+?^(9uE;A41[= %!N ҷ4_f!#ETDH>Z14u'>ՊNrjrJJ)V0fI1x0dK"۫l֠qdǜ"^K ۅ?jEر,C0n8X:fIMo"*A8wuӱmCD&**rpN4Pl0gTO^-̔_q0/F|1ə>b1vR7"T^R 6`:zj>y"h-< RX 6XɝLc0bmrZ~&TY{ N=N-A9?UCnO@C^,|J޻xIVʼn;cL6uq2mՁe<s@3 \5ىW q+d4g! c0**.%9N'/TN{:+!)D(e`yx֔M\k *#! %ƮxQJ{Og ͘ʟizpBb#GZۢ| uY=nj\.LLqTzR4;)`8gRn%$]_ƙ-lԿ:jբȨp8~'o5HyW"eI=I ]1=g5johz E^rʅdl[sly gsE=w8V6vpDĴ5̽g,Gxc>Tv۠X2"bh1ux۟vIyפjO[PCoMi8:0MQ@ƚMx>e9< .+*b(3`m5_H^]Sm{ %0"IEc^z7@ ;q"WSi{vێ̊}xGQPo1Щ~aZJSɔөӫEA9*Qk4ޚc>uhpEOʉP[  ?6~8=ˆmB+8@Y7a3@fϴzGkƋJa xSeNyT=W\܊p*. q(Ӯ1OIG]%0;*ڨ7jI~rNgK'^Jr7uR R\a&a;$<Om‰pcU7@b JHK_#+iF3.ɐqs>uS%S,ԾtNl*҄XŐݺ ԩĔ>Ҹ6-C|>B;ʣ~GPKPC1^dVHE9$l:&Jkgdfk0 (|J& __pU7N^uGe!V֕t2$C9\mkz @S &fVNF8@o:fC3 d X5[:Z+]NTNk6ĥ{YO-Ȱ:(?17WmC̓js$@Π=VU2]^q7~ƫ$Bϐn.Hj xRY>[ 9y6ႛ90 M갻}NZ'oA~ˈFD-4 Pd"Hb6A󄀠ZUħݐmkaUXvqQPF<:?YWq@uj`eFqIk JNnMΕDyDa* i݊!F`.Xl)I h]w$ndE!FLLX"ǚLSv"zefR4 ]#zTR&=N}&m TrBG]& &po8Pu2R"P'&XƍWy]*}PfX LZ"]9izFX 2̮:Vccȥ9RpVrJSiO5]Lǽ8xi~ER)q{) iRog;>a+t=\+n!CQ#+B ` tmKaCB\^Bk8Ȓ3J=Xף.=Ʀ-wbKh\F탲[V=W1Dz׽mIvU&dU_US>ފoo,ڬ4KW/yX؎ѽ(o,1UaC?<5w(h-[н}HlL¯* %enZn ԱB+/Nކ"a'ȣ": =h7nQ,_q*CL1%Hpd4є?w#JĘsc%Ա+&fܯg'=n>оmDRtVU݇{ZG"ڇp朸t/* 6de.@7'+cՂVtOժ5ksda7i}3pt*۵H`bxT0}#:IwgUFWq1^I|Iq4> G */jj8s ^;ŒwN`-Tm˞P+ePK-6ߊ|c5T *pLO[PLɐod̈́BZmW($b%nK!F-btvl]?딯n*yzWHo|"}UU|/T0M+> v㍄/;+.[:8m">oI:_KԮJNCi5qω)6/ǎPʊy++:oU&5bE ;Z0cJ+ :wǠ#BlWCTqzk8Jh%~z{[AfW4{SV 6 ݿಐT9H\RB^Eo>ܒTimhtOµ }լsLSsE(9ډ TYXJǗaV#WkFG^%s=^^MDDM{{9P$+WCXߵ{R~(npHgR6nv9|_hkͽsM( 穈AV}Bs 3CJa<vQ5w{ _sq ᖇTYRcC%+(wVA:AZ 讗|Mdǽ0ZR ,v9p Ɠ~d8p{dbÆ0aw29Q!䃬LTT0c̭pqWˡ. U-V@$\o~:~{E<*^M*ۮVp}~"" b`.ЪqDpV}nV8IZOk_ cHԿ\4\j sN/?@Ct;_$aVw=|tZU^kPxRiIT,!tвEܳa ׈] s^/C&RBςZG^7|=CpXmG]>'ϢYޯ Ydvd9Tc &6-U-ًnt%eAPZ۳1]W=UV׬;o2]}gDa/;ϳE@-l'IjF`` v)>K!+jtV6I.j;f~fϪhP| _Wx- %,,eC9UwPjtrxX4^FBVLwܝ"KMHg^v\5HM"YmJMI=l WxF xm87gWwfW@1>">AkRxdפ- 퇮rro"o6xuy8$fb5K H%;h]Aͮ={&_ 4>$9ME+(u^}JT4;.3"bINՈ'$'?˗ZؗmOOF 1a=w)w7!;)TV;0 Ѽ!}{ yZ v|-*>:{0~ ,*1HkZ~1u1~ngui'jBn%P*Zr }/z/ V|[SZXRh3⠼dm8aB5F%jC סq" q+T"Rbst%:>!"TJ@w5xhp׿7%q;t*o5u:vnaĭ2ҋ_/xk]K5<05_gק/7^[A+%jHT O=8KbZ_lDb@yG0JTySDyXB ^=8EDQ=S^t9q \yg?T5rA$(Aּ&[mbkCZBO #*l-))W-ugc'nK+ڳnFnCmZǏ g˕ƙST̊ia!RI"e͖ -z 1 /u0Z~QxXz/n9M$.[=^sHbUG-NeEͤޠwVoSu$}Hهp73 6ǷcZOfC~MѺlZa-*".j q'mxA_}z@*VT􊦠~eG+eh\rmq:Ye$nBfv2 7z4*#r{op1oܻC#֨˨zF1ɞK^Ѱӕ6xj*|r]$f>%ꔲ eFc]Izx( ؍[ +"QnĘ$\S;'$`*3nsp似X{K6ގ\فt=-MNF8`F刽Nc -;,LcrM:[^_U =pa;w24VoU 8#b'ReF%Afl ʧW0`-B*DqfT) REɴnC[Q[O,vgj1 Ǖ;ĆZ3L`S@S rc7m ގIn0g/Qc{68k:6'|c~ Ƿ%11WR$GTu)[Jh*f\)'XV6ɖ_~}@u(}7=țA6%N~W뀓l]}*[ y찻 *U!w7xRYc)ꭼ\wA!3~:mXBB2$wM~(-KT3w9{}2\3U]d.CbWFҾzӐ 7e2x3= IbB" `QFR\=ը@ozyxn.S' ñ-sh;%eH6aoMWK'˴Qi=p5K:g^@;t1f6d=r/Z$9+ېZËߨB]Ioo5A.TɡQrX0A5wT yxw .МqWKxo ﻁ>+۶<|Έv޿N5U!󘥌H ceǮs=&Φ̃oqDfejabberd-2.1.11/.git/objects/36/aa4455bd5d4a8467ae657f5911d833c8f4116c0000664000000000000000000000162612240230175020030 0ustar x+)JMU040`040031Qs fm!WF)9o:T>U%5)31ACq붊CVo >=Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?Eq˩U2rRw (? QnmgN] "/-3At/fz~%E9 Jߍ^yeJJ *23JfFm6ypګ5ubv|)TQJjZbiN c7bɲkZ0U巜z̢b"j|uUsuS"L|u}9^kw}YҤb__rST3ګ7Lʧf%&%Y0l7xZl/32yztӱrlS% V^E&_PxR|~/Š܂bQ>䭲?oITMf^f^ CWNjZ-;Df¬+.IaPƣ`\ȪX}rN!Q_X 1oRgnvrY7}PEy@%믺ΧE@L @n3*D\̟t>Ǚ*2͖}ǃ@y|rDA~q ȹ N4l3}d:_?uHMQ.;oj/ ]dP&r (`cK,'MB~Sv MMJAz|x٤\ͭ o/+;qdqrQfAI1V+.b)2/ꡉ&P;JR1 b.9]W]QxT\ |rPp0L*ea/Л3w [*{t$꣯ejabberd-2.1.11/.git/objects/7e/0000775000000000000000000000000012240452476013035 5ustar ejabberd-2.1.11/.git/objects/7e/141622a42263b2a150b5adeb3fe92ac15461910000664000000000000000000000044612240230175017761 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1k¶I,0*OfP[6Ct|glȦV$3Vs_c}~mSUVB%3^luup(#"[SQ-/,sNɵu#ejabberd-2.1.11/.git/objects/18/0000775000000000000000000000000012240452476012752 5ustar ejabberd-2.1.11/.git/objects/18/9c8e92895c141b492d6b70236e4e3685a7ec8e0000664000000000000000000000026012240230175017763 0ustar xEKn1DvwHH!V mu{1ⷫ^K0lfdŤ3|α.tFj̻rDlc4uXU'{~cmoꓞ+d{+Kkv_@ᥧT_O}K$\*e<-'8?x3Nejabberd-2.1.11/.git/objects/18/8c6812cc525884ae04a599a953e900f91e38490000664000000000000000000000044612240230175017627 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1̭tnyO0 ?aN#GCm|gjo"Z[ZpZ}Ŏ}'1[LMU[ QR\p{׭'ÍncwlI~~N1Gu߿V4&\`^o95H.v ejabberd-2.1.11/.git/objects/18/1767ab3c440afeb2915106e5e34a24c8a8f9110000664000000000000000000000044612240230175020004 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1<=☨nV1j{.~@'3̉th-Xvm:36CdS+s rRNرd>?f ն*zu!Jn/dpr}-)fڊD 9F Vuejabberd-2.1.11/.git/objects/50/0000775000000000000000000000000012240452476012746 5ustar ejabberd-2.1.11/.git/objects/50/8f46fd4f2818e38d5ebe6586919916032267d70000664000000000000000000000043012240230175017632 0ustar xN0GB]A$Rb#98Br5K:W\]ՌɽANzU'EL0fPv |'ɛ+tZN^ : 9RsJ=[RCX)iwa=a+˾-; )X CPQR׮%var,u#.i$*lK衍M}߬-uB<ߒ®1ˮ7녟k|T 3Ӿ'_ ejabberd-2.1.11/.git/objects/50/4289808878159c3efc073ac18f7f163818c4180000664000000000000000000000162512240230175017550 0ustar x+)JMU040`040031Qs fȲ~fj8KIwsw+rutusIMLcTh SWqez Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?AĚ녚KJ$%f=ۺ(? QnmgN] "/-3At/fz~%E9 Jߍ^yeJJ *23JfFm6ypګ5ubv|)TQJjZbiN c7bɲkZ0U巜z̢b"j|uUsuS"L|u}9^kw}YҤb__rST3ګ7Lʧf%&%Y0l7xZl/32yztӱrlS% V^E&_PxR|~/Š܂bQ>䭲?oITMf^f^ CWNjZ-;Df¬+.IaPƣ`\ȪX}rN!Q_X 1oRgnvrY7}PEy@%믺ΧE@L @n3* LWrnVp YP f>O߿AǼaC(/.9҉mL_wq82\ਸ਼[En"W`*R 6F|r/T?>ew T·MʵܪpzپG'e30.k-"\l$3+fbuuyaGoټ`χ**äR9s'*HGG 汣ejabberd-2.1.11/.git/objects/c3/0000775000000000000000000000000012240452476013027 5ustar ejabberd-2.1.11/.git/objects/c3/65ccb4b87b81c8549bf0e279d9ddde3c636b4a0000664000000000000000000000162512240230175020414 0ustar x+)JMU040`040031Qs fȲ~fj8KIwsw+rutusIMLcTh SWqez Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?o&tE?(lQx\tLQ~nAb C}?vKnN\E^Zf:_,9*[gͶ*Jsb}ًTeg0d͌lDQaWkmrSԴҜnŒe&a֫ o90%E +3??%.ES'&%2DXlr4GeI!5 ;r8ZgWo OJLJJ-Jѳ`n9_2} ꯏ@RS[pnkT\1v(J*I{Pg-sSSRP:^6)bs½ dCY\YPRpՊwX zhs ԎT`qN}WT繆5e= JYl ̝"1|dejabberd-2.1.11/.git/objects/9c/0000775000000000000000000000000012240452476013035 5ustar ejabberd-2.1.11/.git/objects/9c/68b4e30d8a9e294620b6a8bee0061b7ca668320000664000000000000000000000162712240230175020103 0ustar x+)JMU040`040031Qs fm!WF)9o:T>U%5)31ACq붊CVo >=Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?j '͋{X_sN LQ~nAb C}?vKnN\E^Zf:_,9*[gͶ*Jsb}ًTeg0d͌lDQaWkmrSԴҜnŒe&a֫ o90%E +3??%.ES'&%2DXlr4GeI!5 ;r8ZgWo OJLJJ-Jѳ`n9__5b}ߜMb~e,QvV04[!Iq>HNNq|~8jRoU>ΒѲ\I~9dٔȋiR%.dgfɢ8I?~ooa:dZ'qNƳ'|2fes.Fj%%OygssVW<<+=7^'U!YiknaLҫdaݯ"<3Ȓ|Fi^@+$b9}($kID'ic*;%l~6ϳqrtQi6)ұ$&Ygeeif ,'2d4gl:.- 7OmE1ߎS4唞UדqPzr`((GqZlt9uɏ濎;ځ1??IC4:K5ڇ`SSLEv>GA\žϋYbJ'?z ]-cҕSg#ʷ~-[{`js9('8x\f|a&+^^|ˀE >^d,IgI>2O6ڽA]&*c͚wGg3-3E HX`Lg9VPsL?_N;Y{sL62LP m.XHZ=X!6ѸM;hE~~x)˔6o^IϿNc䥭;/0{8y 4&⻒JϹo019Y8L"}oQ|_LzLݺ1V>ǽ[Wb:x /3DjlI6TF=JMo,?KrEʶW̳/s)[}Fi>MgfNiH.QVgK ;֯nɓEn7w5Vag }_$Ec4 7= 7=8a"@+C3xǿn/3U/yơv}(G ~#D7>;BXٿb֘IE1K5趯ׅ!Sy>pӄ ~3$MutylHӼc%?`e+]u:m9G4SciuV$9)P:4o`ѝm}t>ݯ@9`Ɍ!'{*hm{Hy5D6fbuAa.n*5$GwJ:Vuߩw.@=oe9 16 ljkkÐY÷ۛ~|oHaŐ'wD!~ui)Ix*i\0oQΠ&^+Ul`<ذ#p1cJ>_!@Ԟg[z T c$"}~ ժ;dHb' j (G4A;˿t ԗI13gd\5!y ⭅h1/&.1BAJN<_4~3]i8YGv1e^ OCH@"yh.["[XN~}? //> 9si QS$!HB)NVu!5BpƼQ& BT?h9;ą?Bj) ?Ed :r #b& =τl—-ΦUi rFZsge9`Ro8;yM?YLaBۗgGHh(!$C 9&=Ng f^@=O5ьi;'Vfuȭ<`r8ix\ j+ZX$7<9߿M=Ak~KY2c]Oz E[Gn_]U#vVìѬ.#?z^De/)bIyaԘ-iN6~VPhYщQۆ+QU<7-x{p Q[`e6aIċG+Δ%njUO%RHǯ{9Dk_'}]elA (aG,uBד>%I$)e l\{{xl}Zq Q7Xj-7wE q 'rDכ}2-xcUk5 xfyjO2=!7OG4* PaRub"Q'bmWdʦZXYCaKgZGQw<l0P øj9Q>|je)vZpyvy!m9@!c.3(g) f1/*&o$"14h%`Ġ7FZV]6֪V#54]d+|ey$U""y@ހASF|x iШ..rkw!PXH4<ñ~ dP{tlj5-/pϘ^kyQ;}0VH~I^ h?T@T& !^75FM.R:EZ JY */H4}aje|TW+~8)DM K+QV NP#P'`Ȗ|#۫l֠qdǜ"^K ˅?j⌶EY,C0n8\:fICo"*A8wuӱeȡ"[EusNG4Pl0Z~3n&/@fJ/I80n1Ť`@䋚yIv B鹍-^&_%#Y/C'OZuX 6XɝLmc(bR)%zlcqpo);/;X#xTY={pZ~ fݵ)NI :cc-,Ym,kO/E۷sE g HfҴQ-byV"/+mF,n o=8nWiZkUy MLkYQY$drvcbN$ :^jlJcDUlXR.LE=%#ɳzGuI@E(gF@by# ,e ;, g "DMc=FN2G8eJ+S6B:Mlӥ8^[%wc|fȒ((>08W^4wBҭMɻ[6uCXSq26V7cWi<(ץ}p8~ܳfDFIk7=8!u~#Um./@]t1#<-}F;CF ޑԇ=vc Iu<3xwoQ?􌜙*!;RƈhO0a㹚ZUbrŋVf/8 SEg+UZt,u Y*]d#NĈL5Ntdoh<6~lǫgkblmv.5[AtJR?cnj#V51eZcņ1CSIHw:~r^\Qq[|;i c/I"W eJ62sͮR ]KxmKg(vc?S w#utXo -R^(@}t+ejʞxUs6QL=LPWƢh_\*wJ\^ԇ8ԛz?ų0,dNԎբMkLր~͵fIo1uhpEOʉ٭b[@~QEh_q n+?X /*i2O~3f/=evh;%w#Q\qp+^8i/jyևԦEV@Tf`{khjA&F<v95/.N:Y/gP' %hrGpBq&6$olgHl#[):ciud0(r!2ε|vFs9ߧnbjΎ ;^^EW0k7x1_Fc:Be$fuB;ʣ~GPK RC1^dVHE>`阨ژq1j*!a\d:3QXov'_uGegGxIZ^7w\ 3=( A,y#OMvzo w3AvaBR޺pomgj+]W>^@">;⛌X9S /s?sOrQWøv[[kWC2&&P`^8rehSRV" IvSfDOz앎jL$ l NO]Jg/C26`Q/[_3PVogܸ715rr7ud*/\.~ &%J|VבתXXkbv=]Rcv)Za!+&u?k[򜶡abq9jO`H`Bޓ;5WKErT!;YX%)*\^&%ʡ{9Lh +D $O<+fKaɟ_}pMVC&uݏ>j.oA~ӈRR]DV aq@xJYP(n2$Jny~fba${dgEoۜ-Fa-;xJvXI#[eYퟬqJ&50v^2[Š} I!Je AT-豛IрPtqK]M20SpAܨ#R& &po6xrao< svTJDԤ5̕1Nњ\*K/ZG-dN z,Rľ6',h 1f_0LYլi+GC Hx9y[|P"6,jlBuغ D|m- vBd|!<upppRIPwKK%L,q m\aVvӆ%0%Gr?KEFm)Z*[wwBQTv:7]A;Zupۦ쪑h #P# 5p:\S4suȈyi*B_9φЍ?LՖ?8+>+c#1yڨ7dK',0V)J-oZ]԰+̙ՒqbܭR!Gj$[ql5 Iyju3yKXeR/t|U&oX:8>9 $MP PMU ì3j!m9ds` t6H4"(Ƹs#x#}{$E%A}LU0xت:V-fETZP#-ڽ!?O9%!Z|™AA1@W:XYj ΀! ֧Dv*UV3+PG4 k\tB3ރ%a8ć#BH9Ȋ9б㚣nO ؁y@S:'C~E[=0;߬H_5AՕ+ "L !@sx#!pXnyD|8'ߒDuΗ"]0Ҩ5}Q>%ؼw TVqci4˪+);_C?_p{hrlf8(Жkcq0EPZ>*g0n +|gŲηw ϳx ߝ WLԫyI G$MB;poq<!7nItTsQ8_7uIsj%G;Q# _NIVH;htWsF[^%s//p&p"r"򦽽~(U@GGR~(npHgs]6:J|AйtnCDD_W~MskCJa<vQ9Z>X"-?kYRcCZ)Ky#ʭ2WjA[{gy}kUz?̖=PPAUGYH-b6X(, o7hΟB9Voe䒩 l7f^>8|Im/CȚ떇EŌUIy},g8 T-` u촳VjĘHnpɌw .;5A/7<ȕfc݇3V^WVr&r y֚vA:Lbs+%} E~x(Otȡ\ @U9ɗoL c.t2|Ȯes"s۵;k,\+@P-^ŃR$3e8Rz-{V]5zm#C1La^Њ:qOXv7j^6ZPٵ ntKE\.~_S3)u#j9 dC8"7qk3^. ѨA}GoD]fMN=un*\.Ƅ]\b=݄xjSS*xDFNX6Li}@ 'r$˷(X%9/hX#i<F /p>U9 +VY-gR;|gx; dD}x֚*qiyRE{k{ڀOc9gSA7 sejabberd-2.1.11/.git/objects/d5/4926807c555031be958b36c48b02b6189c706e0000664000000000000000000000162512240230175017612 0ustar x+)JMU040`040031Qs fȲ~fj8KIwsw+rutusIMLcTh SWqez Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?!fyc q{Ko^鋶 S[XP(6ҳsu`W cyKYmw=}?F/uq⼲}Fp%E% Y36<8QTX՚:1E[(%5-4odٵxw*[N=LIfQ1 O}5:`ɺIũ &V:۾/A,iRBM1Î/w)N_&CSRR,~o<|-|g<=]UrZ:؇ 9o^Ybt_)mchKrv~?|}֢k/(LLaEbnANj1(kqWVY۟~IL Ǥ&3/D/R+dvn5 3{bdae$0 (hQ0Rdv>9Os'`(/I,Ie73FDS7@9Ϭu>ļtkW]"q o}uI&@L7@ )fؔg\N4ֺ(>"!lw<y:7t% 2<^:Ѱ`.NP}\wނ vkU_^ȠM䊱LEQ*Pƈϗ66XN>ǧn*I[}]/^V ŵboV\Rd^`CMvc` \s:5-PE`Tb^7gD)TTnejabberd-2.1.11/.git/objects/01/0000775000000000000000000000000012240452476012742 5ustar ejabberd-2.1.11/.git/objects/01/237e5cfd4d5b5be8d4e852f32b54ad9348ea370000664000000000000000000000030612240230175020236 0ustar xKN0DYGDzNI;;=gj]O}1H#gލ6&{JcN]+>J%̨Ԩ Y^8j3ٖt>RPI>WU_Q-o@3B^~2q?e{ F'dRejabberd-2.1.11/.git/objects/b1/0000775000000000000000000000000012240452476013024 5ustar ejabberd-2.1.11/.git/objects/b1/58f3d2b1803992918dfbe824df8e3fe3ca3eda0000664000000000000000000000131212240230175020401 0ustar x}Tmo0k+ueVJ`46 $$4+@眷"Nrۓg'R6c}X4ȵ6yOQ8}:1"dP7?A/ O2i[+HR⡘y2Bo0܋\Dm\/ ©§hJf{ph .*ڲ?YV\Nv&x*Z. yK'^N.KbGng9ܦ|T˨)3 knD:݂mlYd)QM+HKkbӸ{bU#ł\S -YX᭟v& s7xכ,<77=f (?-GJG݀MF, KsY,p2aJՇq@kp B[ hCVi7^D"dx3~"s}!CDk7 FqhU>WO#ҹPbҖvzέFއ%IdU ŔT.0PecFZA3Uu[x~W`͹Z6A*`Ag;鴻[JHcdQ -d57)~wNh/1O^ zUXW$]Z)=@``H?q냖t!^ϯow}*1cfƤejabberd-2.1.11/.git/objects/a5/0000775000000000000000000000000012240452476013027 5ustar ejabberd-2.1.11/.git/objects/a5/6ac3bad5b413b244836cdfc9f21ec6948d21f20000664000000000000000000000044512240230175020306 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1r Ւ.>R/9P s"9j={(V]~Ԋ܂bj+v;YϏbBmj]dۋ.n=nvEwD@dKs>%1zcΩ>-tejabberd-2.1.11/.git/objects/9e/0000775000000000000000000000000012240452476013037 5ustar ejabberd-2.1.11/.git/objects/9e/70cefe94c692703cd2061ddf7912f84d8bd50b0000664000000000000000000003164012240230175020254 0ustar xrGw_E=e' rKl[q]d@(׳7{Nf'ΌY'{s2t\&ݽeOOO(4~U"~:_&<=g2.fߒ< <.>OI(9K}%9>~yI(wb6OӋlV&$y8l EA&c5_ _/b1/C1vQ2T,avV0$$JiiI{:luZVOu;Vx__eO_LE:JNIeeD]19㼘$tq~Q&|'Gqϫl8/fed'I K'%f$q6γ7Xawt>{b<ʒ'Qv&rBD D$kao6d`kolnިa2%6b>6x8'1MgeNZ~)kI܄eq%WlwVS1=ϒL9y3k{2CYv5lRvvTCt}횆xwLF Q&ؼ9Iyqs_׳DMeѴ[I}&ŢƍʴŴ0d]qae!;L87 {5r _>e캙\,+٤1.["eYQγI1U?ϲ!^}mLُo:90YU>ӟ+Mxlr6O}UJR bҝAoE۽nE8iu'`}&k|.ɤ'Yvh=';>i&ip$- y|?ryKA &.sHbE>wTgx+gμ(h_NY>_$TH͊9I$??;F?ϲ,HiA8|TF^k}o.R^jΊL" &"OyQ,X%:hߒ"WR؟Y:t92-k>rdr<30t6^֕C>PIG~wES[Apc C`aIT),G軚l.=E} ,tw aF\J4,Z(=š,1c6sh8%Y:aֺO 8>RBYLo8uE7iYTċ8u'q rqBM>\CS fd3SS-?fkZ׺A/(~M0K'#s?Sc{̌e'irDwy9X[ PPV.3%\hoтiJՀaH@-0=Z4` !8/8s>O3!],@} B͸aCxrwBalLۍh[⌐6l5>rI .> ?5k䓳W1/d?"NcmF"IXB2J(9|U<,Og,%ׄo$k{|+ vo(&VZ >ަ[IN++y5ՅWA'2nkw\G%Ѵwp)l^Ă(d=?䉈Ep-zlk , c3o`6 W,FJ%M˕y6'<F<xpNj& +sQ=2D UW:PAZo`D>}g'oAGU i̛E|mA;7ڶ5jH6a7pdSǤɱYˬ,QbvO)of.Ni0ߙncW9 0 TY09~|Hhl>OE|=`Ʀ$Baj<+~g?>(o=}@ Ab?Xaľ@6NR&< Dz򹟋m_B#ύi6my#g =JU }# Ol<`< ([!qvGj#o eur15 ^0kx]p섿Vt09Š z6l1 _^{fsxvnV?12z2t p Uמ6WϛGVs(ިW1aRKOp"*ʑL{\ ¡4qభ,WHKOc/=zb>7^1zksQ"=#Jh5?2SJjAN'o^t 74GdŃ>rdtYGM0P+ A0F}<~ drd{jU~6Y|NurHMmmQvL t尧k&JE/U=K׺f/ŜZUqͿ+*lQ )ʜʵcK,wF܎[y`'p>s!8p d%xL"ቦIMX ]-if=l-0?"0P7 Vہ-B7zL$ÔwV'le /j4Za>:>|+Ǹb"|pƉE=(vZt'Sy^Cy9}\>y SE&`*ө|nVTq_?9[}Q FleƆV£jif9w<*KZ[".K9' 䌪&ݦ갻Ҥ1]JJ:anУ0z+|ת lA;_gjZ]9yѐ;VQ$}yw/~|},ļ͇j01hx1ה¸?\hysE=#Iܠ]$ "= pZ@1>kSN=zO3 _ySݬ6. W/D k0ff l_{Yac ]WtxVtS|>̍&(礎YP=UPbR2 }:&'29~.!PɰC&u|i5s 3Yt &O>G~T]qOmn)cf&CYoWx"h-<*Rb`%r)rK/ݰݱMzprSU=gWP5뱪OsV~~6:>n@v/ 5X EX vķhٍWyU OxVhW㶈փ~+C6U#*OD7i;;'Z>]縦h8X#XFqef>QU|HR.휤EH&b zuIY@.!3%>xE܉P1kMEvY4@Dr?j$ѡ(8z8w4pb]L%k7-& ;Cx'nM<+ $ h0**/%9N'oACMvm@Rэƒz1)B\k 2#Q #XSxSk`@ܫ T%j6JZɉz o?zU>zI=p_m71#.ڡC7vo uGuLS|;s/r7MzFLT;RƈhO0a㹚Z펊3XZ:g 0*u3_ Yͳ A9TF q=ȆP&6u)Et#[6}kGqpcxl-:5ӞϜΥr޹|+htœ մc[ćjU+&3Q>>*h ^- D 08?$LJ\=~G}tji>:)UHfd8H܇ 6'&*oƌa]UO :өHFIb@oU=߽~yI Fe+&VIy>jj.}{R1*T]!O#X5xTU~L&KzQ@W0ߨG1.`(u]$$Sdb?\<͛;G@^R9ϩZ7 oí{$U4*LhZ𔶠d*Hb!П|p5=N^nkmVu#-ݚбF6<=?yWq@Mz`eFs6IsCi_w io(RhAB<LU!bȱQ\2AO@}AȀklm)D)?+Euء"JaO0EрPaK}ddSqIިZC@(VlMqD?ƚ]:g8$6n%ДZ'6',8@bFU8U޳m"4^kV"Q&Bի."W? ٵv9:/N0rw$"\񿰀X#, #]y꘸sT.+U[7ؽ6]Lǭ2 nwnR.Vؠ4|̆cxU琤Ty !V.5a6Y(*=~[Л1G jW8-2Yp[%t [ p.`]n*t`]e;pU hP$5YPI$M0:KmOaĪI3tBFqV-]]sW+^6p껁ŦS_h F%!4Vpim0B" L m{]@Aф1tcfC~|d$v÷ 6<(pUv}U~9a|Zoҷ_yXy!bcc=͞L~X/@<`"`nxPi@U(9[SdIsi o Wo*i^7G܋n4unzWlQ`PP$K xgYJQ5t)\8ZMX3"dpbWEy% [EGq9{(0 B83+?I' xP\(,lS813PԠ6ՆZp Vtnʳ,m(`"tC^ʲ|.:*ER;nt+GįVtor{C ,Þ ̩E/_U x~,'ZLʹ71"@B^4)'O_T]MOcׂmV O9ksWteך8.л}rR]}c6&߼σ o}J$\o<{~Nxݵ\ZKLB$D<`N8QNX\ Wps~IďyEpuf1J%7~i72z Z{c &dHٷH)ф 61Mxkl35ϮӦ) *& p>;Gb%Qy҃hd}!ٽ@~zl4:h!qg@I2-8PTuwS?Dv.U$֨z)ֵMWh$b'錟 3ْ fEdw%d#Y1:vkbmi;pP}u*-~]uj!q=aVp-9Pϴ,㵚;knutnOsHj7%P¡Z8˧d4WctNeՅck4UӕwR)v,&.Bܘ_s-9D63j\a,S|}e)2`UݴV/;hR.L Vl{kb nޡՒk@P^IA["E?لBt):BQ-LbpZv6Ouσg?C:wPݗ5nM4/,;n pg>;30S/i("6\VӼ6]0Zp~?iqI ufʱg µOʰW1?1"57A/MEc]0Ńjo4I˵#r8[^r/.ym7QNDNDoxOOhǻl=^p.[6::tr%y/\[6vѹck ًkND zW<?'îTf98pSϚ9]CZ%ˌy#ʭ:WjEXaw| =E7sYk !%k YlzKƓAp^E1ԘP0=QԃpQ-_ :cf}E|@;\ u ^Юh"j'?yxV,B%v'1LÍiR*+5ǡZ5!ٺϭӊ'ɯUQjã/W9B#V:2[CI_=DENiy×5?E{] *m7 A8[ M-[=zѥ>\?`~~ɳe[5zQY Yftb!۴Te;Yl*ғD{6+*`k7_WԮ3_AA Ńg<@R^Qi7627::x^',X3ŋ[.S*ûW/)Dq~zK *TN7r1WL7:.Lg؈jɰ+}7wp#VR^ŋ)I*fo;OH="}NC5+ fڈ!jL$WCuLI8yOu9k^>Z߽a+ l;Ž^.]E]L_ay ^?/Rm;[Q*2)u#j tC8"7,pQh3^8zc:}m"~v7M:g)p]2v[\ ;׺~jv)-;.k?gWƱ<sxc|- %xeTp8CdE5Vr<1r@BULwܝ"Ov{+3\/@7cjNME8JOOIgm5ݲA$WxE zwgǫ5͵f/b|&Ea}pWVE^.nuD=ZnK%9:uSGV$oW]FlK?%ά일F|p[,HIA⾶[S5u#tӠ J}f..5RnLu!#TJ@w5xh6pnJaj]#BM>^mqm=LH-#ϽZ(J|BֵTǁ&DW6'y'/-^~cA+􎓣H)!'cq*닍Cs#{% SFQy7XR)^=8k!H6z.6s]_?<;VgjA؅$(Ah^}zr(bkCJAO #.;l %)W :6Wkl%,ۨчk?X#Ujjq:˟XnɔD~<`JfÅ-ޮ=fB5R0r>F /pT O+Su|Lj7S-W?x! E]ܝpeEͤ~@&t;ޤ:>9e[_Oiߺ07CMN rzkF/Ɲք4}w;MY] 8P?_}zS ?: )_kQJYo.W]f\NV#M]0um+*! "z4"rS6򒓦񜱜oܻC#j7zF1ɎKtU ĥ˧_5e8j $P WP8`W@H@QoftW^.ڨtvMOB;am;]۝32ʝ+r*CzrXgCATq;-&ե("UHˢ;ܨMVTUh-Kwt#Bk&bA sEuwa쎿UtA׽D|*}|m7> M.K0jۛ=À9&6 fՙEҖSK&OśG5kɣ$~XVjwV 'KOde uP bm7Vޞinpg.bp&u|N|-' F5YIou[,[bb)7cROꔈbUvoen9 o; >6W _N~뀓j߸ev+/B kU ! [VttGsj6M,gMҋۦ}7ٔ%;덻콾 CBpѩzPJwU1x<x/IbA" ]:SXE=xezim^j{7=?7)qcŜޅXC͆m5 "$MxAkEЌt53/ p sH̳Ϳ'p\w; D;tIVƢv*k ߋ԰&1 �LSW'~B]|p*ƾX k㡺m og݋[%:Yloea[0)PvH1 6Eejabberd-2.1.11/.git/objects/85/0000775000000000000000000000000012240452476012756 5ustar ejabberd-2.1.11/.git/objects/85/dff6336fdebfeafb1c386f4d95e107099784640000664000000000000000000000162712240230175020300 0ustar x+)JMU040`040031Qs fm!WF)9o:T>U%5)31ACq붊CVo >=Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?a -GYS6{zGFy ejabberd-2.1.11/.git/objects/e5/0000775000000000000000000000000012240452476013033 5ustar ejabberd-2.1.11/.git/objects/e5/c44161273046789c4fd5ab0c44de4478aafb6c0000664000000000000000000000162512240230175020157 0ustar x+)JMU040`040031Qs fȲ~fj8KIwsw+rutusIMLcTh SWqez Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?o&tE?(lQx\tLQ~nAb C}?vKnN\E^Zf:_,9*[gͶ*Jsb}ًTeg0d͌lDQaWkmrSԴҜnŒe&a֫ o90%E +3??%.ES'&%2DXlr4GeI!5 ;r8ZgWo OJLJJ-Jѳ`n9__`9ib*T`njPT C&ZlnUu|{Ylq#2 JZqKyUMt~.6Q `3p1麺<װƣl^CaR) {ޜVXR٣#&Bejabberd-2.1.11/.git/objects/e5/8a8873521efff11fd4cd4fa1216cfc8bc17c0d0000664000000000000000000003344212240230175020457 0ustar xvוɼHey:ƌn]6?%g7쫦 h,|W4/S>Hf0˯׏o_~\HergoDZj4߿=9_dL8j1qƨ2wm%E|?oe6+e jN$?M{wYi}?8촓[~Yqd(U_1lŽ$)ΓOWl|:.Ot^?wm׷NGg|qzx,o߿䏯[+gY2qnߗ`Bˮk@rݽAKgд(*DXMUr#gu :{_=h~dj2wl٬&{P߆>o*&؍l*Jh_M0k 9n,bM8\kH~[6z t:W Z2soKˋeiƇ *F*f,Kc6J4(N>4i6aYx݅; o[7b2Jeghf))=i UדaPzr`gQP, sr+Où;wځx䣓gNlhl>6ؔ0T|iv1C>%hVLgۓ^}(1AI[̿5m1dKT[0E,$鴘d]l`\L4,K)ahVeϞ7ڽA]&[#͊w=g3 -1y Ho-j3@3璩5bwg/w,| ڒDflPU:$\06z!'<$"G:5n:ݤsťVI4Rؼ{%':ɆxMT$&/mݑ}ˆny6槅0,1^ [=G~wJlZП$f32'?t2&Ȩ',-m7s\>ͥrZRlq)&g$ :C#S@<_h85i ~wKMg.Bxnwٻר!?wz5(&kkÐYwۛ/~z|2ˋ!O+80xRV9V'\!NU3zmF6}6pبҽϗhEeF58/sB,|ny^7OKk (GDA;˿t ڗI15g$d V Zb#T/y7r|8`C^T1 00d*%)/xWIG3 zs>0gq5E쳎Ep/x9ZXΘ+"o!,D( ZH\#tF>ۭ/@fwk3 49I|&js H迠nq orN;{ɏc۬kuU3 ~9i 6"W} mE°D.覛M˴:[6a <2~U}l_YSc)n0I@WRMXieM1%aAjh0ڎab-.(b! ,XԴ!dW^Ly >B\ԹPF "绍CalLۍÍVM2O#t$1Zk*/zHy0+u\Ͱ{PiI= ,CO}}k,9/|b ?"c>w%`pxSs1B(S˰l<1A7@[ߵ=^-!Y޴`bşE$4!lEwVJrG1,^H܍tk|)QITml$g2%IsVL wB`CXGȬg*qö ͼ#-xB I ~ZMxu7G̊%Ly6gܗYws IfvSzrFOx2ː(!T]zȐ\jm6)ɑ+Rp廣ӣ^},U0o!sv$nmkm!Shd1arRivP4_#8]F1:|g^HB{ wp&U,mcNv}LU4P{P?>,Fhl:e|=`&$B˄}ُ1[ ! ÄWb?[N.Ў|hren ^P X=`ߋmQ! %Fi6m0y#gW=JX6XQex ZѥR 峔b8KS#)XCo AuzJWe_'KRAg݋F=ۼ#܊FaXӸR/ږab;:~<24IJ,=$(5!rhԡb,,>HpU5i(1ȗ=?>1%L,u"{JoqoQ%PoK^I}ud SAPr?!v8"9J:۲8ʺ /0xD k'O9Pިoj9/~} -nAzI tᰧk&jc2QP@k]}`aї,4פAn?9f(6ټ,+$T*ss/K䣹3b`v<.X܊&;+ř깁OErMO?b:w 3Ԩ[M`W˫jβb?H ,NgnE?PF!O=E3w5)#3?O <Mt0-:_Cj~1*Gf^1o! zyٿZ,Ixh}:`ЙdbW㘑*½Dju1h-XuUqrM e=b*A/=I$)e l{{|l˽Za QXj-7wE q 'rDכ}2-xcYk5 xfyfO2=!7OG4* PaRub"U'bi՗dʦZXYCaKgZAwl0!ø󗓓XI`'ui XWʖ'~6f@-\Ấ0T g9*JThnЄq?9kJEn?w؜;ZU m#Y _Y|8и"̯d4<7`hДv72C4 GaHa2Ҥ0I)/Յp]+ZM <0cbBp0Q4o3*r٢t i7G|Oo߿͉n6 놹apȺ)ES]T@[+A)+@XpZ@"QI#hje|TW+~8.D ++QV NP#P'`|#۫l֠qdǜ"^K ˅?j6EX,C37n8:fICo"*A8wuӱeȡ"[EusN4Pl0Z~3j&@fJH80nb\0 }E08W^4wBҍM[u', ]?TelPI- io08%ƮxQK`@g?%$GTj۷A$uYӓmn3Tߩ ?xhRP'pT>KH`\ e9+𡲋 e$}}u0ĒC[J3&u|ک|T(ȰAbB Q s;`|$%7\юMVp)^if@Ɏj+wZɫkmE(I*_ͼZH؉%ͧ[vK53>p zsZx4L11Zx cٯL3魩>7.b5V P 91Vlkqȏ?We뜎FiDa(+&L``YV/kb8>6{O-C;)9+[ġL|Qϳ:6- ,@:2f[Vc?)673PyItIw z}9:)).E0@?6LߒIi Dou֑4)d8~D9l jW:;F6`xxQz]eZŐݪ G1HLuƵtO216b (NA-5PO zY*"scvFjcFŰaˇqyԧ/F b!7O'<;~)R1Tsv}8m{M9~I KV™x*2xkhzp_(:XuqǕ]3!qѣ"%oViXmv&NڏYHZ [wLmYJ' HO7{`G|+c*A65ug.r^:x۞tN-w߿>1/cb(X}d;-Hڜp%IͲfMDXi<jhGB#TװRX:.0jEcEz<Qx].ܥp~/!7 ё:Vccȥc9JprJSiO5]Lǽ8xi~DR%q;RrAҤ϶}Fk )o!CQ#+B ` tmCaCB8\^Bc(8Ȓ3J=Xǣ=Ʀ.wbKhF탲V=G1DzwϏ{[A=_LIQ0R˿Fk5|FiXo;*ڬ5K׬xXضѽ(B,1uaC?<5εy -QZ=N6bhG⪀ 7 p%N7qkg''ossհJQFEMV( ١ENq#/XG^[?cU*nv$}@]O+6jWcڰfP5Hg(¨-^WepA]8+c#1yڨ˷-dK',0V)J-o[]԰*̹ՒqbܭR!Gj4 [qlcշ<`g0'ͪa-aUHԁz)[;N8NhprqaNB#-Ir/ 6/ASEm_qBtw+10}ZzYs18\)Xな~,',01\K3hž {QIЧn=&S/cuB6L>1*U Y=իHK9]ջ'_+]P…~ҩDo׆"eߘwTS'E_U ]x'%C%&G,7E&t!a^\0xŔ88g7Bc~E[g1J%9iZoEY*@R|Su2 7O)фq60Mx+l3%Oo[P,& p> tXl94CkwLC~sKB83b ρ$XzuoI:_ ԮJN[Ci k(Sl^;Cu*+u4}SeUtl/!sau9ֽf [49D63Ah^eo"(|vxT7 |>hlbYy3v`{~Cp+X Bd1hK$c#p)DbmA#՜ {oC^7Ook'ޣ,?C b~ï@ p}5j[ @߭9`g;S`pV;|+Ye$ Aކ#sjWA&|8CRewy}՛7$U:ŹM_G$kK/ ^:$95WAݯqx{-jo4I˹R#tk-HW8~Dc89y^ ?2P Vw݃=zVG)?agx$n3[6 ^u-y/\[:q nBy*/DY\RO]kTf98pCϚy|y֣rRcވr lCzɩGtA)|ͦu(exb `<D ? @6(;l baA$;LAT0 k.9`ODs<wz ] 1OG/ch'XIjŠbBnI[U<+uI1Sfm!2+g5^׆?9d-F5 ({#TlC9nu-]`qKG/^Zĵ+L>/GEm=:A<\=q+@6*r65N}~tMe43'0 WH.AυjfU~kvZ.k ~{WOov 9i)K(ag+<jΩToˀ߈SȊ򎳓3#^dx;vzK]?vw@ c4RөgˀRӄyROM&[v+W">AkRxdפ 퇎rvn"oxuyت$fb5K H%[h]Aͮ{BM޿|A/h|xIr4H$-V(&UգQ&۫)rwi\fEH,<mdDbwvFPYC50#u6h0TraU4&!d#V;jV#7Ourϲa$OR8ώ YEEهRg/yAmE%IqM/wbgY]Zڸ3W$JEKnQbS?o'xȚJBFo{>Ivцc Ǝy>*KcTP6ě~7*7RA!(z/%6']LWS"Bԁ `QjfCy Jox{r&SImA 9$1УKUsEx谢cdRoл ]鎷:>$GC8b)[_1dAa'!V&h]T6׭R{b58ۊּ>Yp"])FONCh G|RV/kǦٗɪ'- &q2ڐnՋQk,45؍|!VsYE';6joIv_STG%1)Q]`/=$o$Owm:+I/eT_9KB9am;$]۝mם#ruΆ22&6.g;[ ˻C Eʻ7dm;U[HӢtlfTt&X *nZ"<;]&T뾕)O\Ɗ8* 8'C :[Q B3=ZSڞq> E. 0j 5cUf 5#V10`-Bj$Rj˩%MMiݚQ[?O,vgjcjgV 'Jgޙ@Zj{hꙜA]n&*3 l`OXgmSׂ~B`lЏV~T$ 檙 j36NecB) "$l&r sCPJM E+fp5*as߃<$u42<qcNEB^8[cڨzUA]?TUXʭz+/:YPH:̽9_q"PP ]þl]^WBƐk& eH[ڗ;-O/> tCP%3$&$B/z X5V%Uճ;jGߟ2%np,ӻp+0q]^dVP`@xz64b2*FwI' ;u.+ьf_ܒl8G~Erۑȼ-iZ?-Yhoeb[0)Pv:cl<79ejabberd-2.1.11/.git/objects/e0/0000775000000000000000000000000012240452476013026 5ustar ejabberd-2.1.11/.git/objects/e0/be6295a086ab46025489d602b9b341a134da840000664000000000000000000000162612240230175017723 0ustar x+)JMU040`040031Qs fm!WF)9o:T>U%5)31ACq붊CVo >=Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?Eq˩U2rRw (? QnmgN] "/-3At/fz~%E9 Jߍ^yeJJ *23JfFm6ypګ5ubv|)TQJjZbiN c7bɲkZ0U巜z̢b"j|uUsuS"L|u}9^kw}YҤb__rST3ګ7Lʧf%&%Y0l7xZl/32yztӱrlS% V^E&_PxR|~/Š܂bQ>䭲?oITMf^f^ CWNjZ-;Df¬+.IaPƣ`\ȪX}rN!Q_X 1oRgnvrY7}PEy@%믺ΧE@L @n3*z=e7j%P f>O߿AǼaa9 \K'>2} ꯏ:(᝷GZ՗.2vbSQ T1 &~r)[@榦 E@=t>lRV{_˷88(p[nXDb%X1㜮s k<*.{>TQ9(8&ذ͙;QaEJ-=:bŤcejabberd-2.1.11/.git/objects/0c/0000775000000000000000000000000012240452476013024 5ustar ejabberd-2.1.11/.git/objects/0c/323103a0092d8c8cfc14884f9841229710fc2d0000664000000000000000000000044412240230175017642 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&Xͨof.~9TA~2ÜHGڲlnߦ;c3D6"1 'ᴚNVcPmZ(b[O.@7ْbnɿhLd0ޘsjޣuPejabberd-2.1.11/.git/objects/0c/8f1ebedb3f7871ecbb1f05c5319478fc98077c0000664000000000000000000000162612240230175020335 0ustar x+)JMU040`040031Qs fXbsyWmK|,Xj*|U rutusIMLcTh SWqez Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?aK?x8X3uDsB܂~F Ηݞ# 8u'tklXrT<Κm!T0(~7z+?N+5+),L(aȚjԉ-PE)i9% %ˮkMìWraJ2Vg~J\W=OMJ,Ne0xiv fIBjv|~#MqSh0A*Zg{ksx8l9誒xO>\yKMiCS\4[{]|AIdIK]` +s rRDXKbj?&P5y%z) ^!;5vIh # .3$1'o@qGq"~cy;SDQ~IbI*ĜI1"Ҟy~fA&$]S:7y[O21`Iؔᦄ]#"!lw<y:7t% 2<^:Ѱ`.NP}\wނ vkU_^ȠM䊱LEQ*Pƈϗ66XN>ǧn*I[}]/^V ŵboV\Rd^`CMvc` \s:5-PE`Tb^7gD)TwO]ejabberd-2.1.11/.git/objects/58/0000775000000000000000000000000012240452476012756 5ustar ejabberd-2.1.11/.git/objects/58/842d8ee0c4da25743ff131e28b58a7c1345d740000664000000000000000000000044612240230175020025 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&13k6wZ0hЗG8@'3̉th-Xvm:36CdS+s rRNرd>?f ն*zu!Jn/dpr}-)fڊD 9FuRejabberd-2.1.11/.git/objects/fd/0000775000000000000000000000000012240452476013113 5ustar ejabberd-2.1.11/.git/objects/fd/1d6998c8a724811869d1c6fddab99c49d87f6e0000664000000000000000000000065212240230175020312 0ustar x+)JMU050d040031QHN,(IH+HR zN{e5B1PYIIE)EP .;6d?l`ؘb ݜݲĢݬt݂b^ &/2mXb]oBXg 83/] 'D7X(4fCW[gΏIY)aB|jEbnAN*L?!i:j;j`Tun~J|bJnfPOI,48} VKΠPdԜ ݔtktK2u3Rr΅joLX%\'~*3k• <ݜ|ZgeaboRmO]|ܩˍjS2SL38W.-V9Xu"+TEiqj|JAvz|RifNJZNb:̻]ӂ<_-#ejabberd-2.1.11/.git/objects/53/0000775000000000000000000000000012240452476012751 5ustar ejabberd-2.1.11/.git/objects/53/80cc4438fe71c47ee43be6d70ee16c204b04da0000664000000000000000000000162512240230175020225 0ustar x+)JMU040`040031Qs fXbsyWmK|,Xj*|U rutusIMLcTh SWqez Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?!unK9E;~]41Y6(? QnmgN] "/-3At/fz~%E9 Jߍ^yeJJ *23JfFm6ypګ5ubv|)TQJjZbiN c7bɲkZ0U巜z̢b"j|uUsuS"L|u}9^kw}YҤb__rST3ګ7Lʧf%&%Y0l7xZl/32yztӱrlS% V^E&_PxR|~/Š܂bQ>䭲?oITMf^f^ CWNjZ-;Df¬+.IaPƣ`\ȪX}rN!Q_X 1oRgnvrY7}PEy@%믺ΧE@L @n3*v2} ꯏ@RS[pnkT\1v(J*I{Pg-sSSRP:^6)bs½ dCY\YPRpՊwX zhs ԎT`qN}WT繆5e= JYl ̝"1|ejabberd-2.1.11/.git/objects/cd/0000775000000000000000000000000012240452476013110 5ustar ejabberd-2.1.11/.git/objects/cd/84096bf0fd1d2dd47a0a8dc2a176b476f99b300000664000000000000000000000162612240230175020316 0ustar x+)JMU040`040031Qs fXbsyWmK|,Xj*|U rutusIMLcTh SWqez Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?- tZI[x*LQ~nAb C}?vKnN\E^Zf:_,9*[gͶ*Jsb}ًTeg0d͌lDQaWkmrSԴҜnŒe&a֫ o90%E +3??%.ES'&%2DXlr4GeI!5 ;r8ZgWo OJLJJ-Jѳ`n9_Cƻٲx1totP+ K@extan#]!$5E 8֪,vAc'T/ml4 }O*075U(*er-6*^@8đE% Z|wȼ&:?@(I 0t]wEukXQq[6/A0ņ@o܉ +,Rjobejabberd-2.1.11/.git/objects/1c/0000775000000000000000000000000012240452476013025 5ustar ejabberd-2.1.11/.git/objects/1c/56fb6d96725a465e7ddb401db7551a8ea647690000664000000000000000000000031512240230175020110 0ustar xAj0@Ѯ}ٗɒm Msxb)HǯyeVh `[B$SH9Ac"Zqc"Ih&d?zB{v֐5EZ sJI[^ ^;mR浰\O`]joӦ|U*d2f?ag_Mc ejabberd-2.1.11/.git/objects/45/0000775000000000000000000000000012240452476012752 5ustar ejabberd-2.1.11/.git/objects/45/626f2af9d8dc30456fbf9a311984b97a6ac1f70000664000000000000000000000044612240230175020176 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1_/Yk.a>/q ?aN#GCm|gjo"Z[ZpZ}Ŏ}'1[LMU[ QR\p{׭'ÍncwlI~~N1Gu߿V4&\`^o95v}ejabberd-2.1.11/.git/objects/2a/0000775000000000000000000000000012240452476013024 5ustar ejabberd-2.1.11/.git/objects/2a/bbf9c53220cc2d1859d5da41806caa42a603ee0000664000000000000000000000105312240230175020260 0ustar x+)JMU037a040031QHN,(IH+HR zN{e5B1P)ʼnI9yũɥE9ɕEP"1 'hoU5 z:7?%>1%73Y}wT-^1/R Rtsa94֠[3VU[\_P WbnjIjaRi:0|2 -u†& J-L-f*m5[$ Wlܷ 85> ;=>43'%-'1ir NRӖ4Kejabberd-2.1.11/.git/objects/e7/0000775000000000000000000000000012240452476013035 5ustar ejabberd-2.1.11/.git/objects/e7/bd65b4277dd070cd31748a313a1aeea1c9c9250000664000000000000000000003441112240230175020222 0ustar xvGw_E瘖^KբdO鳇]$Z (}fg`o`nl7"PH3vX Pg,4;==;dUo֛Zd9-$C_d'.I9ߦ4e~/u?ӓ}y^%lE 'yGnmY2,Gj<=>,d"bOf߼Q "JWIvMBϓW|r:.t7ycRA8yϳlZY^(FɲNGwgdt>I/ FL v0bol>^>&4ڝf-.%|z>X}clN/yZr;2edlЃlГ|nx6Y%oA^7E2Z!& )-.<$.0^ `ދ^J8qMf|^0hݦ}*NѸɋr_wo"语ڄ `'h VY..y!q}5HFuKeXV +u{\(4N1'";2"+|\CF+Sɼ6KmMƋb1+j a,=E棳a-K%ڦL_Q(;z>S\>MϬml'Qs|h5݆5iԺkMkZ&)UN19fy+vHCDþܝ^A4R1{P].×_NdQ@!'{yv! Mj+_d]Ne~~ޖTS_ӤьuGƝ` O>LCTϗWLMFu\g g3O ς6tv+}'?W}4:8>j'成m$4k5QN;/;69RI0|O^2<ʨ'|l RVf6>O>l-Z͂y>ksDv[}ȆL̈ f.N P,ì(Η*vOn4ڭwQCPN[-s43GF^@ϰN(UUsSsS&BMi8ѧ2_ucm }u+>:BX?qY>\Ubܭm_@$PSbVlQGނv*tҥ1 ㎘]?[Bȯb>,> q7(I5[zn~6}6pغ; ъ S(6y ̭d*N b%Ee)2s_<&AQ'ڸA9e<:8/"3^n"Xs^iu ⭅bO\crxQgtdtq<|wC^ )XhOQ0(pY<,1Oq/'tPc;igb%?"UZ@Iu)P^SjP`!8czmijݏpo9Ө U$.F>߯@oY ?E dNSÈX)pNdk Z /@]8ܧV/q9FwǺrK# m}b -n RuE o\+"I3xDNTkSresSR%-~,V|U8>:[Fzr ;~8 ǿ;*?ׯ6nH;#G:Bw&jKcU%lm f7q S|`D؁qEP,䏃 \샡_'NxcM+. 򖈳nb*jfx"T.jS&%D=cqZIuq ^D $yaV&aqG9>RJN9\`PJ ?XNI[xΣ> w%`!y8)`S! ~$/fWkڶ+nHyIlew"WGWzr"%F,#7*=D";pH햺[(t Q= b5u[ɪ^P:  WSv)ɳڰR7k{m#6—0˞_ ?6Av㿟XdG c-\lQ򕥪pG6% l/I r,ltmŒk2i/(nÂyAkXv_|bhlɡ~`[G~+W][3QaYA oP ˕=Fg5CBv!h zo]WϤp|vCRJG uN\7з츶YT$ Tj ҂j!mUh->}L0?ٽS6YBm<=}|V{ "c9O%`pxS!a$Kx{Lկâ|پnFhE$B}8ꂉnI'Wib*a#U CׄW~+2w2.]eC&*[|8oR51'k+ 'o'VQ9: -cwZ  IOܔWpsĬx[´"zL1z}x BGTBQ=ʧΚu!- nxSF)W7ǧ?8}RM?Vنy QoHpUVw$PKc/=~~2Әi=%Bo4;8(IψuJ PhJǶb:*/Zm'0h& x,ٓ:j('tY~<s28QߚjM(,Z܂ՒX) +EKN8银 W'LǗ^ӿTaJ]-zC~j8~Pa6ȍ'ǬTe|PSgY";'Vfuȭ<`r8ix\m=7@2,h9߾N#FkB#̬1߮}*Y9hWc[[bgձD6DG ‰m{PލKQxE˻}FWdg9q&:!m~1*Gocb/AtF nlHċGE픕%=H7M~{9T.`Q*~U *\S$kY )rv"*gצL |2b \!)qwhRKܔ[,*X7pc~Wn0%t҇j!3qo7cA&R/l|Pemϱ@bpS"+Y:60ŝM l6|5kv(yA@Qc%Bq/ry8s>~QuFu=1ܡlyzQ}불a>613h1b %|L8Q EE37pD$&v'⽑A^VXlΝUqDz|@H6 _Z O7@+  4eG̐P]Uia2Ҥ0M..X7 2(GV|5%)nhެgȭz GW?~? p?T@& !^7DMW)*M$=fk$A)ѣ, 8- H|QQRj\=Ԍm yS}[I.ZmC_ \:bh =)3 Y 3Yċt)D\#THb2O#.ܾx g  fjiV( ]hS$=5 =C:R3טf)vAiruhgZ-LoI&9+LB<5uZ]d)AxdI8!86 CQp~Dp&aw1eiugF(YR"JȒ((:08ʟhP;;y물tkT uXSFalPI i? %ƮxQj{OcT&21?%$GTj˷e|ԥ?t>#>-}FC)0 Ճ#;p_Ǚ;紅H/ș2Q!EaMq^ f9 wΧ_(WXaUe֪ 0UGCb+{~=QEټ3 El.w٪[3>so-ݚ6yj;[]HrV({q1c5Lrlxکܖf0#@naLF)شzI3vuzv7[rAŬfҸ #v萠c?xDdHJU+X5J,h]vh%.A ?S{=ugFƍgSd୷)VSAZ,)'mCߘxUHDMT-(+ammp<+OހmkCB8/lH,UA`\@x#0$ 2.dDbAy۟<U5ɧ ͷej4_~,}n{w/MxʗIϭS*"&=֞yWY&0"IEc^zM-$ \O|+qڞ?3c# RPog)^a)M%SvFLvL3^dA9*Qk4ޚc "_c[: 5ްs; .m V8NzGPZaDP #PVMSCs$3xIZn6( 3=* AXFj*f`q'ԖWPLM/2jrL%fKpEapܦz59x[h(11 H%1pFѴe᧴2H" I[v2)|n;dtPcWeo5]p|$ l NO])KgQ/C2Ei0D_[9p(M-7 3nܛ6rr7Ud*/|<5M%K/l_G^b-cy͆}|=\1CZF{myP\\Mv\S* غЯi4OߪzΧ/=PcSuZGb[k)OjyLW(.s:*ɇ%3۰;[Cru7{` [YAawʹ N^.d%2D-6p3ʂBq Qp3۠ѣZUķݐmsaU[+ݡb'lxtg~)*yˌn- J#q&ݚ+$TҺC"(\fMm)S2:HȊBd@ʙ#EP5\m߸z.^ ELjIF6!8 P u6{9UŅrPyQ)ESd#8V8FkrT).޿h>(mhc@B;TZ H٪jW2 RlV5kZ&J;Q5T\PװR4,_PH>fXLZ"]9b`lwevt1pT.[4U݁^H>QT3e~܋g;͏H*5n@J.Htao X[.m29"0huz@ƞwA`_Rgo5j ixdm@ٴ5Uq$$al\Kݫ.*e 4gKJXi6`A ?"IuU jQ2)ePF9e$?KbC/f"]MA t/{>~Glh"mt_ ,NFq3Ty6<<%TR1. ZLwLj yZ)'# 4!mN==PtO MGb7|`3,̣bS^/(K3=nO}{g8ٸy *bfg-zG[~:_t%nga< UV$lO%,˕b?탇g,ƚqIz2ݬVL_ˢv k<kq [1E][ţicX%r^sT]䨹Slm>jȈ6F&_F2[LH+F eV++&LCt6%KDxK8Jz]crjwdɀV8X 4m+@ucvianra8U+,B};0>x-cr?VQ|,8*j\jJw2>LB'ZQN,oj:!'=Zxm=H95xԒ" &*S(7ձE]O/(Š8Ȋ`J!7p߿ϗdΠ(l/}1,U X=I-ˇ k{t;آ(]PSޮ-Eʾ0m 7sѹOd/b蓒!cvƣHU5 crKP8sV|!8! {iڲg1h j[of )axBev8v2'm(&t.L#$aa]tE2p(d1 L+YU9M~h6Qqԃh d}!ٝА?Nc!DC$4pfPs V^ƫe,U,K ^@RSmbIjEʧRh^Ma D 7-!bGv^ M`|c v4eX|uR/ԇb 4[=0ҝoVOB4O2dCh_H4tZq64QsHjJNv5qω)6/á*:XXzY]eQ8~26p<}X)lruxf# JKg],8M9wϹ}VkZmnE^ _܊C93V٠sw Z):)Ę&|{X[@1DWXwЉ%xM*y!v*|E[|@Cc~ï@ ^B!~i݊hț^}|oA ϳx ߽w ߘfW4QbaU4&@Qb8CA*pKR*c `I }լsLS]Pr?4avI^͕1K&V_/VzxyuE?67C8kro8W"6  |/uf@]o=}?@TD_W>!乄>0rsµƱ1D[?YwC)ks#ʝ:zP*E.t%v<qn6[C)]6>]܂Y;.~ @(;l baA$;YsQř_ SQ1">ŝ^-:/hWi"hg?}w/ch'X׫IRjaecBn=O#OQd\z<סA LsZ5>Q9=\U[#NZ7$_ Z~C\h)~9IY_>]]E'*@EVe D-M=FRea?+2D^hm=J,l"wrK>_˟ +B>>YTo~% "#%ˡCذTd;YlJ҃ZD|3]W=*`s۞{Py}gD0BA a"B-b6X(,nМ?%PWg>;xesB&%S |A|:>mϪhP| _<3VD""Y+.9#N!+;NgFq~tte.{:1T3+1Ui<'&P-{ O]…^`=r=WLs (wQ$ G;(&lG&E.nI=t$Oԣs[=Gya boy,%2T#%*Wr7BM_ 4>B`6:3e (u^yJT4;3"bINU&$+?×K 6TЧ ZUPUј˞K CMGvJ9h Z9Z!}{ĆI>Hᄿ;^/@|D@^?v[.J5Ҏ'GSwXtVVpjr- Rђ(^ u/ V|[SZXRHI6+iwQAouh74njCJf^JlNлdOOUR&]GV <4 '*&y4tdQocktݶĭ2ҋ^N:jx`5_3N_7?={e NǑxS뉟$ڏ4zqŴ؈U <ؕ*":n4"[:AU/ZpҢ "{S=aSM8w ûa( nܬrB8u6Uӵ|p-Q'*a[R[@HtOdbJU2g1,F>xb6>8pSe,g3ǩ%?¾C, tcñE6[l]Lf pt^WhEΧ*Ga^>r&SI]kIL`*hSIV`L zk5:UGһx Gl}=`|Cf2bk%Hes*5nQ 2^Ngb[چo4Éwux\E۪R؟JZ>:G~\) pʱiUdݓ8 *2 "Z-`qEn,gL[=52jg_p=ب칿ST6Jb)Q]`/=$oO_Y6C՗NnI('oDUmc#9";'燵$ɏ0I9ap^]R@,R޽%o_e@U&c#t0r^2Z]Ut Ђ~l1B\lO~*80VTwq j.onD-%r{eW֌o{1PQP37(10`ܪX,dL zX0Y*njZlmq-'@31 Ǖ3ĆZ3L -5^zgP`;,inLvLs9۸D͗> bp&8ulN|c~ 7:%11WT$GTu*[J_D43`~*t0f2⦀犼y8dJ^bw58Iͬ yǘSWg:&8W5?$*ܪscܛ)b 5(7eH/Pf[쩞gwY{} Cw!+c#\oi_d<_|YᆠLog 9h%`\d\)@"T2Wh6=M>uJDpX+2ݗq]^D +(k Z:]5J끣]9#1/=5'?؍m/iP7[WS[XP(6ҳsu`W cyKYmw=}?F/uq⼲}Fp%E% Y36<8QTX՚:1E[(%5-4odٵxw*[N=LIfQ1 O}5:`ɺIũ &V:۾/A,iRBM1Î/w)N_&CSRR,~o<|-|g<=]UrZ:؇ 9o^Ybt_)mchKrv~?|}֢k/(LLaEbnANj1(kqWVY۟~IL Ǥ&3/D/R+dvn5 3{bdae$0 (hQ0Rdv>9Os'`(/I,Ie73FDS7@9Ϭu>ļtkW]"q o}uI&@L7@~m~S3;̯["!lw<y:7t% 2<^:Ѱ`.NP}\wނ vkU_^ȠM䊱LEQ*Pƈϗ66XN>ǧn*I[}]/^V ŵboV\Rd^`CMvc` \s:5-PE`Tb^7gD)TNFejabberd-2.1.11/.git/objects/76/0000775000000000000000000000000012240452476012756 5ustar ejabberd-2.1.11/.git/objects/76/6820bf5102d584538f6196fb61c5626246200d0000664000000000000000000000031712240230175017437 0ustar xIN0@Q9E[D˖bk࡜DؑSiB܀ sA ƒJ hW*T)ڑ68$tR#j (\MQ9mɤCJ&lb"Lvrl5}'G>qgFBs#~0tpF)n3 NGLz~p~y{YR[dxejabberd-2.1.11/.git/objects/4e/0000775000000000000000000000000012240452476013032 5ustar ejabberd-2.1.11/.git/objects/4e/ff1a3f3cfa8ec626326ec0570151530f20bb250000664000000000000000000000113012240230175020120 0ustar x+)JMU076f040031QHN,(IH+HR zN{e5B1P)ʼnI9yũɥE9ɕEP"1 'hoU5 z:7?%>1%73YKS\+dgPbD2TCQjNbnJf:5Ey)9UM+ď_efMRך_ geaboRmO]|ܩˍjsu J2stAZZb'45ً:qKaCEae3|-Yt:ۖ=,(-NO)NO*IIIL[tw״`'~iKek~h&dejabberd-2.1.11/.git/objects/38/0000775000000000000000000000000012240452476012754 5ustar ejabberd-2.1.11/.git/objects/38/20c8f093a23580a9a8b4e7baec54041b9bccd00000664000000000000000000000065012240230175020214 0ustar x}]k0w;C)#m#q=Ml5$Ѓl1^-)+9Yj)q ҈E{nW%w&,IJقHն@ؚ&Nr}VuMq$j_lD`D\ $9dlvu,,`_9n$~ECzB' nxm:eڎ%_4SpVg`SނJAp _ jejabberd-2.1.11/.git/objects/info/0000775000000000000000000000000012240452476013455 5ustar ejabberd-2.1.11/.git/objects/info/packs0000664000000000000000000000006612240230175014471 0ustar P pack-3597b394a439b3587c942076c18d8b958eb0f5ef.pack ejabberd-2.1.11/.git/objects/0a/0000775000000000000000000000000012240452476013022 5ustar ejabberd-2.1.11/.git/objects/0a/00847e1d7baa2249f7c07ac72a0b651332eb1d0000664000000000000000000000162412240230175020115 0ustar x+)JMU040`040031Qs fq{o>3r Z':깤&e&1?x*RrɅo^q28(94l߾3T r/rR-T* wg{rƽ)ޓϘ\Z*1oef,V{as K&8_zv{u*2Dw,=bQ:kPQRà寜;=^W(3=!kff' ZS'fh˗B%0>vs-,5^eX~˩),*fX!>)q/Wz_5L>?Y7)8!Wgۗ9ڽv7(%M A)f 7ũO:zq|jVbRRjQvŖ;,砫JNKg=p!->K\6Mz M]rIoZtm%'-w)H-I-fc-J*k/AT@de0T*zح&ղC4`fO,̺̼Ĝm< ƕZَ'iLE%% s&uƈH{f(.UWtMQ|\$nQ?&94{u/fEWȐUϐn;z<:Ԋsh/hfu~'>~IMQ.;oj/ ]dP&r (`cK,'MB~Sv MMJAz|x٤\ͭ o/+;qdqrQfAI1V+.b)2/ꡉ&P;JR1 b.9]W]QxT\ |rPp0L*ea/Л3w [*{tUZejabberd-2.1.11/.git/objects/1f/0000775000000000000000000000000012240452476013030 5ustar ejabberd-2.1.11/.git/objects/1f/1065b19d4f5da50b3249225edaafd26412d47f0000664000000000000000000000032412240230175020132 0ustar xOK1=S{iI&"-EsgD٪g83P95\ܵj#hbkdv 4tsBZ(k(yKx;b$[ۥT84[p@W׾Ju-eel გsf7Bddx}|߬?O[~d7ejabberd-2.1.11/.git/objects/2f/0000775000000000000000000000000012240452476013031 5ustar ejabberd-2.1.11/.git/objects/2f/7b5e3238b61e165eff0f6bddc66338c16da88f0000664000000000000000000000044612240230175020333 0ustar x+)JMU060d040031QK,L/Je8*4`V yzPU~ F"'e8߶}SasGTI+T^בMا3u$ PH+)Lbc(su,ڏ1@T&e&1Iu>Sҟ;?%'.C'3̉th-Xvm:36CdS+s rRNرd>?f ն*zu!Jn/dpr}-)fڊD 9FTWvDejabberd-2.1.11/.git/objects/27/0000775000000000000000000000000012240452476012752 5ustar ejabberd-2.1.11/.git/objects/27/1984024b03cd03f943e7e17c2c66c1edbb47ba0000664000000000000000000000162712240230175020145 0ustar x+)JMU040`040031Qs fm!WF)9o:T>U%5)31ACq붊CVo >=Uaq~iQr*i}3g^V[UϰV{SJC'1߹ lT>9#1/=5'?iWGqW/T}(? QnmgN] "/-3At/fz~%E9 Jߍ^yeJJ *23JfFm6ypګ5ubv|)TQJjZbiN c7bɲkZ0U巜z̢b"j|uUsuS"L|u}9^kw}YҤb__rST3ګ7Lʧf%&%Y0l7xZl/32yztӱrlS% V^E&_PxR|~/Š܂bQ>䭲?oITMf^f^ CWNjZ-;Df¬+.IaPƣ`\ȪX}rN!Q_X 1oRgnvrY7}PEy@%믺ΧE@L @n3*f8\Q"ⱿvQUϐn;z<# K@extan#]!3@jry .pTۭU}Yx"j7+N0E@#>_`9ib*T`njPT C&ZlnUu|{Ylq#2 JZqKyUMt~.6Q `3p1麺<װƣl^CaR) {ޜVXR٣#zzejabberd-2.1.11/.git/info/0000775000000000000000000000000012240452476012024 5ustar ejabberd-2.1.11/.git/info/refs0000664000000000000000000002262612240230175012704 0ustar 8d11f756c70cd512eb2c73669fc514a1fb1418fc refs/heads/master 0ea99c66cdaba71358752a3a211d27137df52bdf refs/heads/wheezy 8d11f756c70cd512eb2c73669fc514a1fb1418fc refs/remotes/origin/HEAD 11b9b259b92d538b5a59cdccf259f656c69fec62 refs/remotes/origin/debconf-perl c352294f1784ba02dc2822a388c5c7cb7e78231d refs/remotes/origin/experimental cbe90ebb05573f7c3f27f32fa9aef1fa06fc3902 refs/remotes/origin/fnmatch 383e2687748fd21c0bc288b3b2f93c5f15c473df refs/remotes/origin/lenny 8704f4ee40845e61b162b1a2779a546a8348c991 refs/remotes/origin/lenny-backports 5eae550cd084389afb4a8534dd574ca3f235f811 refs/remotes/origin/lucid 8d11f756c70cd512eb2c73669fc514a1fb1418fc refs/remotes/origin/master 2b1be0fc9c6da13b9b6ca295b7c202525b9361bd refs/remotes/origin/precise be547edb9efa59653c7abb08e5d9a49898aee5a5 refs/remotes/origin/pristine-tar d133f4af9a0461b4d6b38a8617cd73d1b1e4cde9 refs/remotes/origin/squeeze 7c6629c5619bdb039a87af6bb89c6b47ca72926a refs/remotes/origin/upstream 0ea99c66cdaba71358752a3a211d27137df52bdf refs/remotes/origin/wheezy 2f15f9fd0f5f9925e524dfc31645844a32ebb0c1 refs/tags/debian/1.0.0-2 d8b7809515a902c25d0f743ca2f0ec8110e607e4 refs/tags/debian/1.1.1-1 55235538210388605f4a7a7efc8d6f512ee35b05 refs/tags/debian/1.1.1-2 c17535e1352de6070b768810c588e336b12998c7 refs/tags/debian/1.1.1-3 751e1c30dfcd01f9098bf2f993340826fde9873f refs/tags/debian/1.1.1-4 ffccca32bf6ddb4b49af50931d39dfc66e0af7b7 refs/tags/debian/1.1.1-5 8de40fb22edcebe58c67f6c5a983425f592cfca4 refs/tags/debian/1.1.1-6 4e98eeada4486a94ae6adec5c18235a6febf967a refs/tags/debian/1.1.1-7 9a390b0c7d3000dc7e9421d89792718ec119bc57 refs/tags/debian/1.1.1-8 73dc1f8ee9f9b330b59c3d15f023c2b09f9b9b41 refs/tags/debian/1.1.1-9 c3c8f9fd5722f22cc8e4fa63eec0d04ba19da82c refs/tags/debian/1.1.2-1 747b00eb0ee4a424ae8cc477548bd0626ac58244 refs/tags/debian/1.1.2-10 f4f2d3d76afa7257c06b61c667b8ad58556abd57 refs/tags/debian/1.1.2-2 202e941d2c561a0902b7bab872f0dbfe321ab35e refs/tags/debian/1.1.2-3 062575f49c900530085aea00daec13d77bb3e5a7 refs/tags/debian/1.1.2-4 d437b8d4dd377442b16a5511aa5a8469b3a1e0d8 refs/tags/debian/1.1.2-5 ed61e0abcfe955105ad4ae909152226efc6b1564 refs/tags/debian/1.1.2-6 a608028575802c6bf007aca188ca66a2fd3752f8 refs/tags/debian/1.1.2-7 66fdfe6e4d17007e1ada6817d5868d4fcf2cd771 refs/tags/debian/1.1.2-8 f8b1088d2287effbcb4ea9df9b94beace2541204 refs/tags/debian/1.1.2-9 acfeb1d41313f7437a5ceba3cf5d8d11daf8feca refs/tags/debian/1.1.4-1 acacbd748c8ab861f98530a4c934c3014985016b refs/tags/debian/1.1.4-2 e0dd8127b9307f70795084d98931c50b86b2d01e refs/tags/debian/1.1.4-3 24fe08d31026449affed57531c5546d036a54b43 refs/tags/debian/1.1.4-4 a09d0ea2465c089a03130b56d480b52672abc16f refs/tags/debian/1.1.4-5 f00e1b9d3ae423b686def64fcef3a1e8dadbdd6c refs/tags/debian/1.1.4-6 b2a9c548cd5a5c799f106f1fca961c5e7ccea14c refs/tags/debian/1.1.4-7 2e539f3a0bded5e43ee96838e8e93e3a641e7c79 refs/tags/debian/2.0.0-1 8f8bb8317580e87d76754f6933a6f69738538460 refs/tags/debian/2.0.0-2 3611642f5b4e7fe51fae165a0e2a060d481ded19 refs/tags/debian/2.0.0-3 93299f29ec992955cb01fa751eb680b536b426f6 refs/tags/debian/2.0.0-4 a449f71764ebfb29dbcd79876ea918e51aa8d150 refs/tags/debian/2.0.0-5 3442fb972813b05eac11a7c799142aec98cc5c83 refs/tags/debian/2.0.0-6 49e1d980d2398bfa91d30f1caca9a70bc48ed794 refs/tags/debian/2.0.0-7 726d40c4eeb68cfdb1e6bfb895a2bb692ba61352 refs/tags/debian/2.0.1-1 7c82e86d1c65a4639cb998b104e596c4a7a12d8c refs/tags/debian/2.0.1-2 43f1b4aab532d684f0b3a097b3d7711e62309b68 refs/tags/debian/2.0.1-3 999fd1804f479d513f29bcff90e47c7cddc89a3d refs/tags/debian/2.0.1-4 717477142901192fa25d7916b80369c4f20d862d refs/tags/debian/2.0.1-5 142a59ee7a8df8ca3bd111fe6f24ee69ca788292 refs/tags/debian/2.0.1-6 34e1c538dbc240b694a0f9b64def89fb27b2f4ec refs/tags/debian/2.0.1-6+lenny1 892f73dec04b272d4c7fbc4c42dc91c7380262d9 refs/tags/debian/2.0.2-1 72ed7070c81f7ea52046cd5c95e3c58465af802d refs/tags/debian/2.0.2-2 bb13c3f7af9b95c46e8a4bd0192677ea63cecbda refs/tags/debian/2.0.2-3 2c81f5ff5061784676beadf224485504968ee491 refs/tags/debian/2.0.3-1 2898b5cc3618d15278522eb05f4266484619b0c5 refs/tags/debian/2.0.3-2 42bf12c0d413a4ace59ee9383eb2411951f288a4 refs/tags/debian/2.0.5-1 f4828b4140dc6dc909857790c57c1bfe6eeb1994 refs/tags/debian/2.0.5-1.1 2e93ea40ba3ce5ad891ddb8410e22ba477fbc9cc refs/tags/debian/2.0.5-1_bpo50+1 7c6d622ccde29796cdc18f012666e65b032e3f48 refs/tags/debian/2.1.0-2 20d532d5af21e53af5864f2af2689be895e7d3a9 refs/tags/debian/2.1.1-1 dd0ce4d725c16ce8b6ed558a5314da3ded6206f1 refs/tags/debian/2.1.10-1 c352294f1784ba02dc2822a388c5c7cb7e78231d refs/tags/debian/2.1.10-1^{} b12a995bffa88658a867e681deb2f937d985f6cd refs/tags/debian/2.1.10-2 6073d6b63fef7497722c7f97a5d5325490e8b7d0 refs/tags/debian/2.1.10-2^{} 98a24504d09646aa544d23324b87ac907a51c888 refs/tags/debian/2.1.10-3 0ea99c66cdaba71358752a3a211d27137df52bdf refs/tags/debian/2.1.10-3^{} 3673e7ae5fc9a232b42820ddac5f3866c02204a2 refs/tags/debian/2.1.2-1 e5c0ff266d074e2ec4a30241d650bbe8f00bf5fe refs/tags/debian/2.1.2-2 ddb509dbdfc4b07c3f5d3cf725faae778aa066c6 refs/tags/debian/2.1.2-3 6233e5c4f1b591c7bb97462b4cf5e2f36225c589 refs/tags/debian/2.1.3-1 cd0bec699b118959650034f9b4c71eee787146b0 refs/tags/debian/2.1.3-1^{} b6c7385bec8453eeafe10317eb4dadfd3f085ac3 refs/tags/debian/2.1.3-2 52cd0f7f22d9438303489ec27090a58e95477200 refs/tags/debian/2.1.3-2^{} e8316e28851fd56b5f8c612f6e681a92d13a9c7f refs/tags/debian/2.1.4-1 4d6d2fefa0e329d7cf28b61b099e7a06799f0894 refs/tags/debian/2.1.4-1^{} bcffd2ca1d25f58854fab273871f01e59e2e49c5 refs/tags/debian/2.1.5-1 7f8a17352b97a2a16da4e2d8f84cbbc097200b1f refs/tags/debian/2.1.5-1^{} 47315c293f36a2c2eaec8b063723eacf22f3906f refs/tags/debian/2.1.5-2 49467d2d00731957915c9d6cf5cc852ec3c31b6e refs/tags/debian/2.1.5-2^{} adbe97a769f0270e89593710363c48a5cdc147f7 refs/tags/debian/2.1.5-3 e81e802052910b1dfe0a4117c666dbb6d4b0ad6e refs/tags/debian/2.1.5-3^{} 2d54bad22f84fe790eb676e6bd23f03273bdd745 refs/tags/debian/2.1.5-3+squeeze1 d133f4af9a0461b4d6b38a8617cd73d1b1e4cde9 refs/tags/debian/2.1.5-3+squeeze1^{} 9a35411a56795e1b389c7dabcca548023a5047be refs/tags/debian/2.1.5-3+squeeze1_bpo50+1 8704f4ee40845e61b162b1a2779a546a8348c991 refs/tags/debian/2.1.5-3+squeeze1_bpo50+1^{} 44f26e7c815c54f341dbc00cff9178dfb443ac29 refs/tags/debian/2.1.6-1 c8388c124037a24db131de341e929f7237bb5ee1 refs/tags/debian/2.1.6-1^{} 312d9640e5ac919fe631dfadeff76e19342f8bad refs/tags/debian/2.1.6-2.1 9323d95b64a3edb3d40b01cf52e3ea6afccba82d refs/tags/debian/2.1.8-1 6f5fab8556fe986057126068f5b988fb65b39018 refs/tags/debian/2.1.8-1^{} 6ca86c18faf4d877afa1c9eff2721b8b2c45d1e4 refs/tags/debian/2.1.9-1 0f3b2d547e358aed0767f59690d8ce9791ddba2b refs/tags/debian/2.1.9-1^{} 0ce6287ed5f80ccd9ca458de6fd04527cfcbe7c9 refs/tags/ubuntu/2.1.10-2ubuntu1 2b1be0fc9c6da13b9b6ca295b7c202525b9361bd refs/tags/ubuntu/2.1.10-2ubuntu1^{} e65f9821ccf1d3aa310ce39f3dd47a740ae2932e refs/tags/upstream/1.0.0 9c9e5d65ef6b47dc252a17d23a71951a2c108e7a refs/tags/upstream/1.0.0^{} 4e909270cb140056c96425778a4553baf894e078 refs/tags/upstream/1.1.1 a7bae6d3f4a2c02f48c9d3738060161521a93e68 refs/tags/upstream/1.1.1^{} da9e5b178aea985e91ba78eba6b36ed01f3c3adf refs/tags/upstream/1.1.2 7fb54104aac9db81ef3ad5db09574f777459c9e7 refs/tags/upstream/1.1.2^{} de904e17421fc90eb940b5c27f15303ac77858a0 refs/tags/upstream/1.1.4 b3a4375b911f3cf3d4c3c1c7d1535dc084340288 refs/tags/upstream/1.1.4^{} abf2dd98fdd35af4071df8578bfa83eabc911666 refs/tags/upstream/2.0.0 808d37de52c3a06dc59427736c2f50d3852cb00a refs/tags/upstream/2.0.0^{} c03b7a4f7b2c0e0df08683b64d7ffd9931727116 refs/tags/upstream/2.0.1 2a6409c2b43debf2abb82048deb60e60948aa5f1 refs/tags/upstream/2.0.1^{} ec6c7d152a17118874b16efcc7980f1a3ed98752 refs/tags/upstream/2.0.2 d4507bbcaef1e429990476d32317c0a9b9bed04c refs/tags/upstream/2.0.2^{} 23e0d38d60d23111fcab38c212846d918aed64b6 refs/tags/upstream/2.0.3 20db5691ae04a3b07ac38f965581c6b5ef8be3ba refs/tags/upstream/2.0.3^{} 666f620084fd6040b3eb457bd557396627498324 refs/tags/upstream/2.0.5 2d328f8f5f6f81b767b3d35c742f79ed9f47d2d6 refs/tags/upstream/2.0.5^{} b362e4e02e7df2e97c93ae4a23a6f242e9045970 refs/tags/upstream/2.1.0 96472ed382dca18ffa33ba057a0eb6e86f10c044 refs/tags/upstream/2.1.0^{} 599f9e56288e7e2e2b2bce46fd0408fb4ec9e846 refs/tags/upstream/2.1.0rc1 3fdaa89ed7477a546db9022360714296b92f2dcb refs/tags/upstream/2.1.0rc1^{} 2b6ebb237a0ce67e0848653f974786837c953644 refs/tags/upstream/2.1.1 e0267f7704df7c64a2a801b31581cf82c13585d6 refs/tags/upstream/2.1.1^{} 20ec34de6481821da182a074f69216d911f3c944 refs/tags/upstream/2.1.10 d8ad8ab301acb7f7bf34f75fdaaec33f221cde55 refs/tags/upstream/2.1.10^{} 8f999055e1d19944b787c14c960a62546a616826 refs/tags/upstream/2.1.2 5a2ad5ab3cf7c264ed94a713e8e775765b43ed45 refs/tags/upstream/2.1.2^{} f71218fc975e48ffa05cf7ec72214d1792bcd416 refs/tags/upstream/2.1.3 af124ba8c90b923fceba51d3c4d4bd7be578ff3d refs/tags/upstream/2.1.3^{} 07fa519b1b826724c4aae0909a17c65548028b93 refs/tags/upstream/2.1.4 bbb939b2b01e5e95185975821c40f6304bfe4181 refs/tags/upstream/2.1.4^{} e0c8a7a618a996ead6f409337973a77a136764a5 refs/tags/upstream/2.1.5 0fa6975e87ecb185197f4ae5b2dd0b44444c79f5 refs/tags/upstream/2.1.5^{} fc0a5e08dbd169002aa391d25535342e029e2d62 refs/tags/upstream/2.1.6 a7492727f476e373ab6b5423c3566dd7385953ef refs/tags/upstream/2.1.6^{} f885a6fe97320a43546e186f74857e2902b6ab60 refs/tags/upstream/2.1.7 df055e1577fff2f9f745a79d17a5eebeb4dd033a refs/tags/upstream/2.1.7^{} e226ee32ee2fb039f2b639ac617d595e0237a81e refs/tags/upstream/2.1.8 edbaef2110e4e0ed989ffe82274a65193ec28224 refs/tags/upstream/2.1.8^{} c937501d33af41f065e065509746932611e41926 refs/tags/upstream/2.1.9 7e53c3ed3f78377b3356d3d7e0e0384794620604 refs/tags/upstream/2.1.9^{} ejabberd-2.1.11/.git/info/exclude0000664000000000000000000000036012240230175013365 0ustar # git ls-files --others --exclude-from=.git/info/exclude # Lines that start with '#' are comments. # For a project mostly in C, the following would be a good set of # exclude patterns (uncomment them if you want to use them): # *.[oa] # *~ ejabberd-2.1.11/contrib/0000775000000000000000000000000012240452476011670 5ustar ejabberd-2.1.11/contrib/ejabberd-modules.repo0000664000000000000000000000036012240230175015750 0ustar % List of ejabberd-modules to add for ejabberd packaging (source archive and installer) % % HTTP-binding: %https://svn.process-one.net/ejabberd-modules/http_bind/trunk %https://svn.process-one.net/ejabberd-modules/mod_http_fileserver/trunk ejabberd-2.1.11/contrib/extract_translations/0000775000000000000000000000000012240452476016143 5ustar ejabberd-2.1.11/contrib/extract_translations/extract_translations.erl0000664000000000000000000001670412240230175023120 0ustar %%%---------------------------------------------------------------------- %%% File : extract_translations.erl %%% Author : Sergei Golovan %%% Purpose : Auxiliary tool for interface/messages translators %%% Created : 23 Apr 2005 by Sergei Golovan %%% Id : $Id$ %%%---------------------------------------------------------------------- -module(extract_translations). -author('sgolovan@nes.ru'). -export([start/0]). -define(STATUS_SUCCESS, 0). -define(STATUS_ERROR, 1). -define(STATUS_USAGE, 2). -include_lib("kernel/include/file.hrl"). start() -> ets:new(translations, [named_table, public]), ets:new(translations_obsolete, [named_table, public]), ets:new(files, [named_table, public]), ets:new(vars, [named_table, public]), case init:get_plain_arguments() of ["-srcmsg2po", Dir, File] -> print_po_header(File), Status = process(Dir, File, srcmsg2po), halt(Status); ["-unused", Dir, File] -> Status = process(Dir, File, unused), halt(Status); [Dir, File] -> Status = process(Dir, File, used), halt(Status); _ -> print_usage(), halt(?STATUS_USAGE) end. process(Dir, File, Used) -> case load_file(File) of {error, Reason} -> io:format("~s: ~s~n", [File, file:format_error(Reason)]), ?STATUS_ERROR; _ -> FileList = find_src_files(Dir), lists:foreach( fun(F) -> parse_file(Dir, F, Used) end, FileList), case Used of unused -> ets:foldl(fun({Key, _}, _) -> io:format("~p~n", [Key]) end, ok, translations); srcmsg2po -> ets:foldl(fun({Key, Trans}, _) -> print_translation_obsolete(Key, Trans) end, ok, translations_obsolete); _ -> ok end, ?STATUS_SUCCESS end. parse_file(Dir, File, Used) -> ets:delete_all_objects(vars), case epp:parse_file(File, [Dir, filename:dirname(File) | code:get_path()], []) of {ok, Forms} -> lists:foreach( fun(F) -> parse_form(Dir, File, F, Used) end, Forms); _ -> ok end. parse_form(Dir, File, Form, Used) -> case Form of %%{undefined, Something} -> %% io:format("Undefined: ~p~n", [Something]); {call, _, {remote, _, {atom, _, translate}, {atom, _, translate}}, [_, {string, Line, Str}] } -> process_string(Dir, File, Line, Str, Used); {call, _, {remote, _, {atom, _, translate}, {atom, _, translate}}, [_, {var, _, Name}] } -> case ets:lookup(vars, Name) of [{_Name, Value, Line}] -> process_string(Dir, File, Line, Value, Used); _ -> ok end; {match, _, {var, _, Name}, {string, Line, Value} } -> ets:insert(vars, {Name, Value, Line}); L when is_list(L) -> lists:foreach( fun(F) -> parse_form(Dir, File, F, Used) end, L); T when is_tuple(T) -> lists:foreach( fun(F) -> parse_form(Dir, File, F, Used) end, tuple_to_list(T)); _ -> ok end. process_string(_Dir, _File, _Line, "", _Used) -> ok; process_string(_Dir, File, Line, Str, Used) -> case {ets:lookup(translations, Str), Used} of {[{_Key, _Trans}], unused} -> ets:delete(translations, Str); {[{_Key, _Trans}], used} -> ok; {[{_Key, Trans}], srcmsg2po} -> ets:delete(translations_obsolete, Str), print_translation(File, Line, Str, Trans); {_, used} -> case ets:lookup(files, File) of [{_}] -> ok; _ -> io:format("~n% ~s~n", [File]), ets:insert(files, {File}) end, case Str of [] -> ok; _ -> io:format("{~p, \"\"}.~n", [Str]) end, ets:insert(translations, {Str, ""}); {_, srcmsg2po} -> case ets:lookup(files, File) of [{_}] -> ok; _ -> ets:insert(files, {File}) end, ets:insert(translations, {Str, ""}), print_translation(File, Line, Str, ""); _ -> ok end. load_file(File) -> case file:consult(File) of {ok, Terms} -> lists:foreach( fun({Orig, Trans}) -> case Trans of "" -> ok; _ -> ets:insert(translations, {Orig, Trans}), ets:insert(translations_obsolete, {Orig, Trans}) end end, Terms); Err -> Err end. find_src_files(Dir) -> case file:list_dir(Dir) of {ok, FileList} -> recurse_filelist( lists:map( fun(F) -> filename:join(Dir, F) end, FileList)); _ -> [] end. recurse_filelist(FileList) -> recurse_filelist(FileList, []). recurse_filelist([], Acc) -> lists:reverse(Acc); recurse_filelist([H | T], Acc) -> case file:read_file_info(H) of {ok, #file_info{type = directory}} -> recurse_filelist(T, lists:reverse(find_src_files(H)) ++ Acc); {ok, #file_info{type = regular}} -> case string:substr(H, string:len(H) - 3) of ".erl" -> recurse_filelist(T, [H | Acc]); ".hrl" -> recurse_filelist(T, [H | Acc]); _ -> recurse_filelist(T, Acc) end; _ -> recurse_filelist(T, Acc) end. print_usage() -> io:format( "Usage: extract_translations [-unused] dir file~n" "~n" "Example:~n" " extract_translations . ./msgs/ru.msg~n" ). %%% %%% Gettext %%% print_po_header(File) -> MsgProps = get_msg_header_props(File), {Language, [LastT | AddT]} = prepare_props(MsgProps), application:load(ejabberd), {ok, Version} = application:get_key(ejabberd, vsn), print_po_header(Version, Language, LastT, AddT). get_msg_header_props(File) -> {ok, F} = file:open(File, [read]), Lines = get_msg_header_props(F, []), file:close(F), Lines. get_msg_header_props(F, Lines) -> String = io:get_line(F, ""), case io_lib:fread("% ", String) of {ok, [], RemString} -> case io_lib:fread("~s", RemString) of {ok, [Key], Value} when Value /= "\n" -> %% The first character in Value is a blankspace: %% And the last characters are 'slash n' ValueClean = string:substr(Value, 2, string:len(Value)-2), get_msg_header_props(F, Lines ++ [{Key, ValueClean}]); _ -> get_msg_header_props(F, Lines) end; _ -> Lines end. prepare_props(MsgProps) -> Language = proplists:get_value("Language:", MsgProps), Authors = proplists:get_all_values("Author:", MsgProps), {Language, Authors}. print_po_header(Version, Language, LastTranslator, AdditionalTranslatorsList) -> AdditionalTranslatorsString = build_additional_translators(AdditionalTranslatorsList), HeaderString = "msgid \"\"\n" "msgstr \"\"\n" "\"Project-Id-Version: " ++ Version ++ "\\n\"\n" ++ "\"X-Language: " ++ Language ++ "\\n\"\n" "\"Last-Translator: " ++ LastTranslator ++ "\\n\"\n" ++ AdditionalTranslatorsString ++ "\"MIME-Version: 1.0\\n\"\n" "\"Content-Type: text/plain; charset=UTF-8\\n\"\n" "\"Content-Transfer-Encoding: 8bit\\n\"\n", io:format("~s~n", [HeaderString]). build_additional_translators(List) -> lists:foldl( fun(T, Str) -> Str ++ "\"X-Additional-Translator: " ++ T ++ "\\n\"\n" end, "", List). print_translation(File, Line, Str, StrT) -> StrQ = ejabberd_regexp:greplace(Str, "\\\"", "\\\\\""), StrTQ = ejabberd_regexp:greplace(StrT, "\\\"", "\\\\\""), io:format("#: ~s:~p~nmsgid \"~s\"~nmsgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]). print_translation_obsolete(Str, StrT) -> File = "unknown.erl", Line = 1, StrQ = ejabberd_regexp:greplace(Str, "\\\"", "\\\\\""), StrTQ = ejabberd_regexp:greplace(StrT, "\\\"", "\\\\\""), io:format("#: ~s:~p~n#~~ msgid \"~s\"~n#~~ msgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]). ejabberd-2.1.11/contrib/extract_translations/prepare-translation.sh0000775000000000000000000002162012240230175022463 0ustar #!/bin/bash # Frontend for ejabberd's extract_translations.erl # by Badlop # How to create template files for a new language: # NEWLANG=zh # cp msgs/ejabberd.pot msgs/$NEWLANG.po # echo \{\"\",\"\"\}. > msgs/$NEWLANG.msg # ../../extract_translations/prepare-translation.sh -updateall prepare_dirs () { # Where is Erlang binary ERL=`which erl` EJA_SRC_DIR=$EJA_DIR/src/ EJA_MSGS_DIR=$EJA_SRC_DIR/msgs/ EXTRACT_DIR=$EJA_DIR/contrib/extract_translations/ EXTRACT_ERL=$EXTRACT_DIR/extract_translations.erl EXTRACT_BEAM=$EXTRACT_DIR/extract_translations.beam SRC_DIR=$RUN_DIR/src MSGS_DIR=$SRC_DIR/msgs if !([[ -n $EJA_DIR ]]) then echo "ejabberd dir does not exist: $EJA_DIR" fi if !([[ -x $EXTRACT_BEAM ]]) then sh -c "cd $EXTRACT_DIR; $ERL -compile $EXTRACT_ERL" fi } extract_lang () { MSGS_FILE=$1 MSGS_FILE2=$MSGS_FILE.translate MSGS_PATH=$MSGS_DIR/$MSGS_FILE MSGS_PATH2=$MSGS_DIR/$MSGS_FILE2 echo -n "Extracting language strings for '$MSGS_FILE':" echo -n " new..." cd $SRC_DIR $ERL -pa $EXTRACT_DIR -noinput -noshell -s extract_translations -s init stop -extra . $MSGS_PATH >$MSGS_PATH.new sed -e 's/^% \.\//% /g;' $MSGS_PATH.new > $MSGS_PATH.new2 mv $MSGS_PATH.new2 $MSGS_PATH.new echo -n " old..." $ERL -pa $EXTRACT_DIR -noinput -noshell -s extract_translations -s init stop -extra -unused . $MSGS_PATH >$MSGS_PATH.unused find_unused_full $MSGS_FILE $MSGS_FILE.unused echo "" >$MSGS_PATH2 echo " ***** Translation file for ejabberd ***** " >>$MSGS_PATH2 echo "" >>$MSGS_PATH2 echo "" >>$MSGS_PATH2 echo " *** New strings: Can you please translate them? *** " >>$MSGS_PATH2 cat $MSGS_PATH.new >>$MSGS_PATH2 echo "" >>$MSGS_PATH2 echo "" >>$MSGS_PATH2 echo " *** Unused strings: They will be removed automatically *** " >>$MSGS_PATH2 cat $MSGS_PATH.unused.full >>$MSGS_PATH2 echo "" >>$MSGS_PATH2 echo "" >>$MSGS_PATH2 echo " *** Already translated strings: you can also modify any of them if you want *** " >>$MSGS_PATH2 echo "" >>$MSGS_PATH2 cat $MSGS_PATH.old_cleaned >>$MSGS_PATH2 echo " ok" rm $MSGS_PATH.new rm $MSGS_PATH.old_cleaned rm $MSGS_PATH.unused.full } extract_lang_all () { cd $MSGS_DIR for i in $( ls *.msg ) ; do extract_lang $i; done echo -e "File\tMissing\tLanguage\t\tLast translator" echo -e "----\t-------\t--------\t\t---------------" cd $MSGS_DIR for i in $( ls *.msg ) ; do MISSING=`cat $i.translate | grep "\", \"\"}." | wc -l` LANGUAGE=`grep "X-Language:" $i.translate | sed 's/% Language: //g'` LASTAUTH=`grep "Author:" $i.translate | head -n 1 | sed 's/% Author: //g'` echo -e "$i\t$MISSING\t$LANGUAGE\t$LASTAUTH" done cd $MSGS_DIR REVISION=`git describe --always` zip $HOME/ejabberd-langs-$REVISION.zip *.translate; rm *.translate } find_unused_full () { DATFILE=$1 DATFILEI=$1.old_cleaned DELFILE=$2 cd msgs DATFILE1=$DATFILE.t1 DATFILE2=$DATFILE.t2 DELFILE1=$DELFILE.t1 DELFILE2=$DELFILE.t2 DELFILEF=$DATFILE.unused.full echo "" >$DELFILEF grep -v "\\\\" $DELFILE >$DELFILE2 echo ENDFILEMARK >>$DELFILE2 cp $DATFILE $DATFILEI cp $DATFILE $DATFILE2 cp $DELFILE2 $DELFILE1 STRING=`head -1 $DELFILE1` until [[ $STRING == ENDFILEMARK ]]; do cp $DELFILE2 $DELFILE1 cp $DATFILE2 $DATFILE1 STRING=`head -1 $DELFILE1` cat $DATFILE1 | grep "$STRING" >>$DELFILEF cat $DATFILE1 | grep -v "$STRING" >$DATFILE2 cat $DELFILE1 | grep -v "$STRING" >$DELFILE2 done mv $DATFILE2 $DATFILEI rm -f $MSGS_PATH.t1 rm $MSGS_PATH.unused rm -f $MSGS_PATH.unused.t1 rm $MSGS_PATH.unused.t2 cd .. } extract_lang_srcmsg2po () { LANG=$1 LANG_CODE=$LANG.$PROJECT MSGS_PATH=$MSGS_DIR/$LANG_CODE.msg PO_PATH=$MSGS_DIR/$LANG_CODE.po echo $MSGS_PATH $ERL -pa $EXTRACT_DIR -pa $SRC_DIR -pa $EJA_SRC_DIR -pa /lib/ejabberd/include -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$PO_PATH.1 sed -e 's/ \[\]$/ \"\"/g;' $PO_PATH.1 > $PO_PATH.2 msguniq --sort-by-file $PO_PATH.2 --output-file=$PO_PATH rm $PO_PATH.* } extract_lang_src2pot () { LANG_CODE=$PROJECT MSGS_PATH=$MSGS_DIR/$LANG_CODE.msg POT_PATH=$MSGS_DIR/$LANG_CODE.pot echo -n "" >$MSGS_PATH echo "% Language: Language Name" >>$MSGS_PATH echo "% Author: Translator name and contact method" >>$MSGS_PATH echo "" >>$MSGS_PATH cd $SRC_DIR $ERL -pa $EXTRACT_DIR -pa $SRC_DIR -pa $EJA_SRC_DIR -pa /lib/ejabberd/include -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$POT_PATH.1 sed -e 's/ \[\]$/ \"\"/g;' $POT_PATH.1 > $POT_PATH.2 #msguniq --sort-by-file $POT_PATH.2 $EJA_MSGS_DIR --output-file=$POT_PATH msguniq --sort-by-file $POT_PATH.2 --output-file=$POT_PATH rm $POT_PATH.* rm $MSGS_PATH # If the project is a specific module, not the main ejabberd if [[ $PROJECT != ejabberd ]] ; then # Remove from project.pot the strings that are already present in the general ejabberd EJABBERD_MSG_FILE=$EJA_MSGS_DIR/es.po # This is just some file with translated strings POT_PATH_TEMP=$POT_PATH.temp msgattrib --set-obsolete --only-file=$EJABBERD_MSG_FILE -o $POT_PATH_TEMP $POT_PATH mv $POT_PATH_TEMP $POT_PATH fi } extract_lang_popot2po () { LANG_CODE=$1 PO_PATH=$MSGS_DIR/$LANG_CODE.po POT_PATH=$MSGS_DIR/$PROJECT.pot msgmerge $PO_PATH $POT_PATH >$PO_PATH.translate 2>/dev/null mv $PO_PATH.translate $PO_PATH } extract_lang_po2msg () { LANG_CODE=$1 PO_PATH=$LANG_CODE.po MS_PATH=$PO_PATH.ms MSGID_PATH=$PO_PATH.msgid MSGSTR_PATH=$PO_PATH.msgstr MSGS_PATH=$LANG_CODE.msg cd $MSGS_DIR # Check PO has correct ~ # Let's convert to C format so we can use msgfmt PO_TEMP=$LANG_CODE.po.temp cat $PO_PATH | sed 's/%/perc/g' | sed 's/~/%/g' | sed 's/#:.*/#, c-format/g' >$PO_TEMP msgfmt $PO_TEMP --check-format result=$? rm $PO_TEMP if [ $result -ne 0 ] ; then exit 1 fi msgattrib $PO_PATH --translated --no-fuzzy --no-obsolete --no-location --no-wrap | grep "^msg" | tail --lines=+3 >$MS_PATH grep "^msgid" $PO_PATH.ms | sed 's/^msgid //g' >$MSGID_PATH grep "^msgstr" $PO_PATH.ms | sed 's/^msgstr //g' >$MSGSTR_PATH paste $MSGID_PATH $MSGSTR_PATH --delimiter=, | awk '{print "{" $0 "}."}' | sort -g >$MSGS_PATH rm $MS_PATH rm $MSGID_PATH rm $MSGSTR_PATH } extract_lang_updateall () { echo "Generating POT" extract_lang_src2pot cd $MSGS_DIR echo "" echo -e "File Missing Language Last translator" echo -e "---- ------- -------- ---------------" for i in $( ls *.msg ) ; do LANG_CODE=${i%.msg} echo -n $LANG_CODE | awk '{printf "%-6s", $1 }' # Convert old MSG file to PO PO=$LANG_CODE.po [ -f $PO ] || extract_lang_srcmsg2po $LANG_CODE extract_lang_popot2po $LANG_CODE extract_lang_po2msg $LANG_CODE MISSING=`msgfmt --statistics $PO 2>&1 | awk '{printf "%5s", $4 }'` echo -n " $MISSING" LANGUAGE=`grep "X-Language:" $PO | sed 's/\"X-Language: //g' | sed 's/\\\\n\"//g' | awk '{printf "%-12s", $1}'` echo -n " $LANGUAGE" LASTAUTH=`grep "Last-Translator" $PO | sed 's/\"Last-Translator: //g' | sed 's/\\\\n\"//g'` echo " $LASTAUTH" done echo "" rm messages.mo cd .. } translation_instructions () { echo "" echo " A new file has been created for you, with the current, the new and the deprecated strings:" echo " $MSGS_PATH2" echo "" echo " At the end of that file you will find the strings you must update:" echo " - Untranslated strings are like this: {"March", ""}." echo " To translate the string, add the text inside the commas. Example:" echo " {"March", "Marzo"}." echo " - Old strings that are not used: "Woowoa"" echo " Search the entire file for those strings and remove them" echo "" echo " Once you have translated all the strings and removed all the old ones," echo " rename the file to overwrite the previous one:" echo " $MSGS_PATH" } EJA_DIR=`pwd`/.. RUN_DIR=`pwd`/.. PROJECT=ejabberd while [ $# -ne 0 ] ; do PARAM=$1 shift case $PARAM in --) break ;; -project) PROJECT=$1 shift ;; -ejadir) EJA_DIR=$1 shift ;; -rundir) RUN_DIR=$1 shift ;; -lang) LANGU=$1 prepare_dirs extract_lang $LANGU shift ;; -langall) prepare_dirs extract_lang_all ;; -srcmsg2po) LANG_CODE=$1 prepare_dirs extract_lang_srcmsg2po $LANG_CODE shift ;; -popot2po) LANG_CODE=$1 prepare_dirs extract_lang_popot2po $LANG_CODE shift ;; -src2pot) prepare_dirs extract_lang_src2pot ;; -po2msg) LANG_CODE=$1 prepare_dirs extract_lang_po2msg $LANG_CODE shift ;; -updateall) prepare_dirs extract_lang_updateall ;; *) echo "Options:" echo " -langall" echo " -lang LANGUAGE_FILE" echo " -srcmsg2po LANGUAGE Construct .msg file using source code to PO file" echo " -src2pot Generate template POT file from source code" echo " -popot2po LANGUAGE Update PO file with template POT file" echo " -po2msg LANGUAGE Export PO file to MSG file" echo " -updateall Generate POT and update all PO" echo "" echo "Example:" echo " ./prepare-translation.sh -lang es.msg" exit 0 ;; esac done ejabberd-2.1.11/contrib/extract_translations/README0000664000000000000000000000121612240230175017011 0ustar extract_translations - auxiliary tool that extracts lines to be translated from ejabberd source tree. Building: erlc extract_translations.erl Invoking 1: erl -noinput -s extract_translations -extra dirname message_file where dirname is the directory "src" in ejabberd's source tree root, message_file is a file with translated messages (src/msgs/*.msg). Result is a list of messages from source files which aren't contained in message file. Invoking 2: erl -noinput -s extract_translations -extra -unused dirname message_file Result is a list of messages from message file which aren't in source files anymore. ejabberd-2.1.11/COPYING0000664000000000000000000004332012240230175011253 0ustar As a special exception, the authors give permission to link this program with the OpenSSL library and distribute the resulting binary. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library General Public License instead of this License. ejabberd-2.1.11/src/0000775000000000000000000000000012276225575011026 5ustar ejabberd-2.1.11/src/mod_roster.hrl0000664000000000000000000000214412240230175013672 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -record(roster, {usj, us, jid, name = "", subscription = none, ask = none, groups = [], askmessage = [], xs = []}). -record(roster_version, {us, version}). ejabberd-2.1.11/src/mod_ping.erl0000664000000000000000000002002512240230175013304 0ustar %%%---------------------------------------------------------------------- %%% File : mod_ping.erl %%% Author : Brian Cully %%% Purpose : Support XEP-0199 XMPP Ping and periodic keepalives %%% Created : 11 Jul 2009 by Brian Cully %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_ping). -author('bjc@kublai.com'). -behavior(gen_mod). -behavior(gen_server). -include("ejabberd.hrl"). -include("jlib.hrl"). -define(SUPERVISOR, ejabberd_sup). -define(NS_PING, "urn:xmpp:ping"). -define(DEFAULT_SEND_PINGS, false). % bool() -define(DEFAULT_PING_INTERVAL, 60). % seconds -define(DICT, dict). %% API -export([start_link/2, start_ping/2, stop_ping/2]). %% gen_mod callbacks -export([start/2, stop/1]). %% gen_server callbacks -export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2, code_change/3]). %% Hook callbacks -export([iq_ping/3, user_online/3, user_offline/3, user_send/3]). -record(state, {host = "", send_pings = ?DEFAULT_SEND_PINGS, ping_interval = ?DEFAULT_PING_INTERVAL, timeout_action = none, timers = ?DICT:new()}). %%==================================================================== %% API %%==================================================================== start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start_ping(Host, JID) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), gen_server:cast(Proc, {start_ping, JID}). stop_ping(Host, JID) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), gen_server:cast(Proc, {stop_ping, JID}). %%==================================================================== %% gen_mod callbacks %%==================================================================== start(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), PingSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, transient, 2000, worker, [?MODULE]}, supervisor:start_child(?SUPERVISOR, PingSpec). stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), gen_server:call(Proc, stop), supervisor:delete_child(?SUPERVISOR, Proc). %%==================================================================== %% gen_server callbacks %%==================================================================== init([Host, Opts]) -> SendPings = gen_mod:get_opt(send_pings, Opts, ?DEFAULT_SEND_PINGS), PingInterval = gen_mod:get_opt(ping_interval, Opts, ?DEFAULT_PING_INTERVAL), TimeoutAction = gen_mod:get_opt(timeout_action, Opts, none), IQDisc = gen_mod:get_opt(iqdisc, Opts, no_queue), mod_disco:register_feature(Host, ?NS_PING), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PING, ?MODULE, iq_ping, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_PING, ?MODULE, iq_ping, IQDisc), case SendPings of true -> %% Ping requests are sent to all entities, whether they %% announce 'urn:xmpp:ping' in their caps or not ejabberd_hooks:add(sm_register_connection_hook, Host, ?MODULE, user_online, 100), ejabberd_hooks:add(sm_remove_connection_hook, Host, ?MODULE, user_offline, 100), ejabberd_hooks:add(user_send_packet, Host, ?MODULE, user_send, 100); _ -> ok end, {ok, #state{host = Host, send_pings = SendPings, ping_interval = PingInterval, timeout_action = TimeoutAction, timers = ?DICT:new()}}. terminate(_Reason, #state{host = Host}) -> ejabberd_hooks:delete(sm_remove_connection_hook, Host, ?MODULE, user_offline, 100), ejabberd_hooks:delete(sm_register_connection_hook, Host, ?MODULE, user_online, 100), ejabberd_hooks:delete(user_send_packet, Host, ?MODULE, user_send, 100), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_PING), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PING), mod_disco:unregister_feature(Host, ?NS_PING). handle_call(stop, _From, State) -> {stop, normal, ok, State}; handle_call(_Req, _From, State) -> {reply, {error, badarg}, State}. handle_cast({start_ping, JID}, State) -> Timers = add_timer(JID, State#state.ping_interval, State#state.timers), {noreply, State#state{timers = Timers}}; handle_cast({stop_ping, JID}, State) -> Timers = del_timer(JID, State#state.timers), {noreply, State#state{timers = Timers}}; handle_cast({iq_pong, JID, timeout}, State) -> Timers = del_timer(JID, State#state.timers), ejabberd_hooks:run(user_ping_timeout, State#state.host, [JID]), case State#state.timeout_action of kill -> #jid{user = User, server = Server, resource = Resource} = JID, case ejabberd_sm:get_session_pid(User, Server, Resource) of Pid when is_pid(Pid) -> ejabberd_c2s:stop(Pid); _ -> ok end; _ -> ok end, {noreply, State#state{timers = Timers}}; handle_cast(_Msg, State) -> {noreply, State}. handle_info({timeout, _TRef, {ping, JID}}, State) -> IQ = #iq{type = get, sub_el = [{xmlelement, "ping", [{"xmlns", ?NS_PING}], []}]}, Pid = self(), F = fun(Response) -> gen_server:cast(Pid, {iq_pong, JID, Response}) end, From = jlib:make_jid("", State#state.host, ""), ejabberd_local:route_iq(From, JID, IQ, F), Timers = add_timer(JID, State#state.ping_interval, State#state.timers), {noreply, State#state{timers = Timers}}; handle_info(_Info, State) -> {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. %%==================================================================== %% Hook callbacks %%==================================================================== iq_ping(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) -> case {Type, SubEl} of {get, {xmlelement, "ping", _, _}} -> IQ#iq{type = result, sub_el = []}; _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]} end. user_online(_SID, JID, _Info) -> start_ping(JID#jid.lserver, JID). user_offline(_SID, JID, _Info) -> stop_ping(JID#jid.lserver, JID). user_send(JID, _From, _Packet) -> start_ping(JID#jid.lserver, JID). %%==================================================================== %% Internal functions %%==================================================================== add_timer(JID, Interval, Timers) -> LJID = jlib:jid_tolower(JID), NewTimers = case ?DICT:find(LJID, Timers) of {ok, OldTRef} -> cancel_timer(OldTRef), ?DICT:erase(LJID, Timers); _ -> Timers end, TRef = erlang:start_timer(Interval * 1000, self(), {ping, JID}), ?DICT:store(LJID, TRef, NewTimers). del_timer(JID, Timers) -> LJID = jlib:jid_tolower(JID), case ?DICT:find(LJID, Timers) of {ok, TRef} -> cancel_timer(TRef), ?DICT:erase(LJID, Timers); _ -> Timers end. cancel_timer(TRef) -> case erlang:cancel_timer(TRef) of false -> receive {timeout, TRef, _} -> ok after 0 -> ok end; _ -> ok end. ejabberd-2.1.11/src/ejabberd_app.erl0000664000000000000000000001437312240230175014117 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_app.erl %%% Author : Alexey Shchepin %%% Purpose : ejabberd's application callback module %%% Created : 31 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_app). -author('alexey@process-one.net'). -behaviour(application). -export([start_modules/0,start/2, get_log_path/0, prep_stop/1, stop/1, init/0]). -include("ejabberd.hrl"). %%% %%% Application API %%% start(normal, _Args) -> ejabberd_loglevel:set(4), write_pid_file(), application:start(sasl), randoms:start(), db_init(), sha:start(), stringprep_sup:start_link(), xml:start(), start(), translate:start(), acl:start(), ejabberd_ctl:init(), ejabberd_commands:init(), ejabberd_admin:start(), gen_mod:start(), ejabberd_config:start(), ejabberd_check:config(), connect_nodes(), %% Loading ASN.1 driver explicitly to avoid races in LDAP catch asn1rt:load_driver(), Sup = ejabberd_sup:start_link(), ejabberd_rdbms:start(), ejabberd_auth:start(), cyrsasl:start(), % Profiling %ejabberd_debug:eprof_start(), %ejabberd_debug:fprof_start(), maybe_add_nameservers(), start_modules(), ejabberd_listener:start_listeners(), ?INFO_MSG("ejabberd ~s is started in the node ~p", [?VERSION, node()]), Sup; start(_, _) -> {error, badarg}. %% Prepare the application for termination. %% This function is called when an application is about to be stopped, %% before shutting down the processes of the application. prep_stop(State) -> stop_modules(), ejabberd_admin:stop(), broadcast_c2s_shutdown(), timer:sleep(5000), State. %% All the processes were killed when this function is called stop(_State) -> ?INFO_MSG("ejabberd ~s is stopped in the node ~p", [?VERSION, node()]), delete_pid_file(), %%ejabberd_debug:stop(), ok. %%% %%% Internal functions %%% start() -> spawn_link(?MODULE, init, []). init() -> register(ejabberd, self()), %erlang:system_flag(fullsweep_after, 0), %error_logger:logfile({open, ?LOG_PATH}), LogPath = get_log_path(), error_logger:add_report_handler(ejabberd_logger_h, LogPath), erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv), case erl_ddll:load_driver(ejabberd:get_so_path(), expat_erl) of ok -> ok; {error, already_loaded} -> ok end, Port = open_port({spawn, "expat_erl"}, [binary]), loop(Port). loop(Port) -> receive _ -> loop(Port) end. db_init() -> case mnesia:system_info(extra_db_nodes) of [] -> mnesia:create_schema([node()]); _ -> ok end, application:start(mnesia, permanent), mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity). %% Start all the modules in all the hosts start_modules() -> lists:foreach( fun(Host) -> case ejabberd_config:get_local_option({modules, Host}) of undefined -> ok; Modules -> lists:foreach( fun({Module, Args}) -> gen_mod:start_module(Host, Module, Args) end, Modules) end end, ?MYHOSTS). %% Stop all the modules in all the hosts stop_modules() -> lists:foreach( fun(Host) -> case ejabberd_config:get_local_option({modules, Host}) of undefined -> ok; Modules -> lists:foreach( fun({Module, _Args}) -> gen_mod:stop_module_keep_config(Host, Module) end, Modules) end end, ?MYHOSTS). connect_nodes() -> case ejabberd_config:get_local_option(cluster_nodes) of undefined -> ok; Nodes when is_list(Nodes) -> lists:foreach(fun(Node) -> net_kernel:connect_node(Node) end, Nodes) end. %% @spec () -> string() %% @doc Returns the full path to the ejabberd log file. %% It first checks for application configuration parameter 'log_path'. %% If not defined it checks the environment variable EJABBERD_LOG_PATH. %% And if that one is neither defined, returns the default value: %% "ejabberd.log" in current directory. get_log_path() -> case application:get_env(log_path) of {ok, Path} -> Path; undefined -> case os:getenv("EJABBERD_LOG_PATH") of false -> ?LOG_PATH; Path -> Path end end. %% If ejabberd is running on some Windows machine, get nameservers and add to Erlang maybe_add_nameservers() -> case os:type() of {win32, _} -> add_windows_nameservers(); _ -> ok end. add_windows_nameservers() -> IPTs = win32_dns:get_nameservers(), ?INFO_MSG("Adding machine's DNS IPs to Erlang system:~n~p", [IPTs]), lists:foreach(fun(IPT) -> inet_db:add_ns(IPT) end, IPTs). broadcast_c2s_shutdown() -> Children = supervisor:which_children(ejabberd_c2s_sup), lists:foreach( fun({_, C2SPid, _, _}) -> C2SPid ! system_shutdown end, Children). %%% %%% PID file %%% write_pid_file() -> case ejabberd:get_pid_file() of false -> ok; PidFilename -> write_pid_file(os:getpid(), PidFilename) end. write_pid_file(Pid, PidFilename) -> case file:open(PidFilename, [write]) of {ok, Fd} -> io:format(Fd, "~s~n", [Pid]), file:close(Fd); {error, Reason} -> ?ERROR_MSG("Cannot write PID file ~s~nReason: ~p", [PidFilename, Reason]), throw({cannot_write_pid_file, PidFilename, Reason}) end. delete_pid_file() -> case ejabberd:get_pid_file() of false -> ok; PidFilename -> file:delete(PidFilename) end. ejabberd-2.1.11/src/cyrsasl_scram.erl0000664000000000000000000001423712240230175014365 0ustar %%%---------------------------------------------------------------------- %%% File : cyrsasl_scram.erl %%% Author : Stephen Röttger %%% Purpose : SASL SCRAM authentication %%% Created : 7 Aug 2011 by Stephen Röttger %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(cyrsasl_scram). -author('stephen.roettger@googlemail.com'). -export([start/1, stop/0, mech_new/4, mech_step/2]). -include("ejabberd.hrl"). -behaviour(cyrsasl). -record(state, {step, stored_key, server_key, username, get_password, check_password, auth_message, client_nonce, server_nonce}). -define(SALT_LENGTH, 16). -define(NONCE_LENGTH, 16). start(_Opts) -> cyrsasl:register_mechanism("SCRAM-SHA-1", ?MODULE, scram). stop() -> ok. mech_new(_Host, GetPassword, _CheckPassword, _CheckPasswordDigest) -> {ok, #state{step = 2, get_password = GetPassword}}. mech_step(#state{step = 2} = State, ClientIn) -> case string:tokens(ClientIn, ",") of [CBind, UserNameAttribute, ClientNonceAttribute] when (CBind == "y") or (CBind == "n") -> case parse_attribute(UserNameAttribute) of {error, Reason} -> {error, Reason}; {_, EscapedUserName} -> case unescape_username(EscapedUserName) of error -> {error, "protocol-error-bad-username"}; UserName -> case parse_attribute(ClientNonceAttribute) of {$r, ClientNonce} -> case (State#state.get_password)(UserName) of {false, _} -> {error, "not-authorized", UserName}; {Ret, _AuthModule} -> {StoredKey, ServerKey, Salt, IterationCount} = if is_tuple(Ret) -> Ret; true -> TempSalt = crypto:rand_bytes(?SALT_LENGTH), SaltedPassword = scram:salted_password(Ret, TempSalt, ?SCRAM_DEFAULT_ITERATION_COUNT), {scram:stored_key(scram:client_key(SaltedPassword)), scram:server_key(SaltedPassword), TempSalt, ?SCRAM_DEFAULT_ITERATION_COUNT} end, ClientFirstMessageBare = string:substr(ClientIn, string:str(ClientIn, "n=")), ServerNonce = base64:encode_to_string(crypto:rand_bytes(?NONCE_LENGTH)), ServerFirstMessage = "r=" ++ ClientNonce ++ ServerNonce ++ "," ++ "s=" ++ base64:encode_to_string(Salt) ++ "," ++ "i=" ++ integer_to_list(IterationCount), {continue, ServerFirstMessage, State#state{step = 4, stored_key = StoredKey, server_key = ServerKey, auth_message = ClientFirstMessageBare ++ "," ++ ServerFirstMessage, client_nonce = ClientNonce, server_nonce = ServerNonce, username = UserName}} end; _Else -> {error, "not-supported"} end end end; _Else -> {error, "bad-protocol"} end; mech_step(#state{step = 4} = State, ClientIn) -> case string:tokens(ClientIn, ",") of [GS2ChannelBindingAttribute, NonceAttribute, ClientProofAttribute] -> case parse_attribute(GS2ChannelBindingAttribute) of {$c, CVal} when (CVal == "biws") or (CVal == "eSws") -> %% biws is base64 for n,, => channelbinding not supported %% eSws is base64 for y,, => channelbinding supported by client only Nonce = State#state.client_nonce ++ State#state.server_nonce, case parse_attribute(NonceAttribute) of {$r, CompareNonce} when CompareNonce == Nonce -> case parse_attribute(ClientProofAttribute) of {$p, ClientProofB64} -> ClientProof = base64:decode(ClientProofB64), AuthMessage = State#state.auth_message ++ "," ++ string:substr(ClientIn, 1, string:str(ClientIn, ",p=")-1), ClientSignature = scram:client_signature(State#state.stored_key, AuthMessage), ClientKey = scram:client_key(ClientProof, ClientSignature), CompareStoredKey = scram:stored_key(ClientKey), if CompareStoredKey == State#state.stored_key -> ServerSignature = scram:server_signature(State#state.server_key, AuthMessage), {ok, [{username, State#state.username}], "v=" ++ base64:encode_to_string(ServerSignature)}; true -> {error, "bad-auth"} end; _Else -> {error, "bad-protocol"} end; {$r, _} -> {error, "bad-nonce"}; _Else -> {error, "bad-protocol"} end; _Else -> {error, "bad-protocol"} end; _Else -> {error, "bad-protocol"} end. parse_attribute(Attribute) -> AttributeLen = string:len(Attribute), if AttributeLen >= 3 -> SecondChar = lists:nth(2, Attribute), case is_alpha(lists:nth(1, Attribute)) of true -> if SecondChar == $= -> String = string:substr(Attribute, 3), {lists:nth(1, Attribute), String}; true -> {error, "bad-format second char not equal sign"} end; _Else -> {error, "bad-format first char not a letter"} end; true -> {error, "bad-format attribute too short"} end. unescape_username("") -> ""; unescape_username(EscapedUsername) -> Pos = string:str(EscapedUsername, "="), if Pos == 0 -> EscapedUsername; true -> Start = string:substr(EscapedUsername, 1, Pos-1), End = string:substr(EscapedUsername, Pos), EndLen = string:len(End), if EndLen < 3 -> error; true -> case string:substr(End, 1, 3) of "=2C" -> Start ++ "," ++ unescape_username(string:substr(End, 4)); "=3D" -> Start ++ "=" ++ unescape_username(string:substr(End, 4)); _Else -> error end end end. is_alpha(Char) when Char >= $a, Char =< $z -> true; is_alpha(Char) when Char >= $A, Char =< $Z -> true; is_alpha(_) -> false. ejabberd-2.1.11/src/mod_vcard_odbc.erl0000664000000000000000000005230712240230175014445 0ustar %%%---------------------------------------------------------------------- %%% File : mod_vcard.erl %%% Author : Alexey Shchepin %%% Purpose : vCard support via ODBC %%% Created : 2 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_vcard_odbc). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, init/3, stop/1, get_sm_features/5, process_local_iq/3, process_sm_iq/3, %reindex_vcards/0, remove_user/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). -define(JUD_MATCHES, 30). -define(PROCNAME, ejabberd_mod_vcard). start(Host, Opts) -> ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD, ?MODULE, process_local_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD, ?MODULE, process_sm_iq, IQDisc), ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50), MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"), Search = gen_mod:get_opt(search, Opts, true), register(gen_mod:get_module_proc(Host, ?PROCNAME), spawn(?MODULE, init, [MyHost, Host, Search])). init(Host, ServerHost, Search) -> case Search of false -> loop(Host, ServerHost); _ -> ejabberd_router:register_route(Host), loop(Host, ServerHost) end. loop(Host, ServerHost) -> receive {route, From, To, Packet} -> case catch do_route(ServerHost, From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); _ -> ok end, loop(Host, ServerHost); stop -> ejabberd_router:unregister_route(Host), ok; _ -> loop(Host, ServerHost) end. stop(Host) -> ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), Proc ! stop, {wait, Proc}. get_sm_features({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; get_sm_features(Acc, _From, _To, Node, _Lang) -> case Node of [] -> case Acc of {result, Features} -> {result, [?NS_VCARD | Features]}; empty -> {result, [?NS_VCARD]} end; _ -> Acc end. process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", ?NS_VCARD}], [{xmlelement, "FN", [], [{xmlcdata, "ejabberd"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate( Lang, "Erlang Jabber Server") ++ "\nCopyright (c) 2002-2012 ProcessOne"}]}, {xmlelement, "BDAY", [], [{xmlcdata, "2002-11-16"}]} ]}]} end. process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) -> case Type of set -> #jid{user = User, lserver = LServer} = From, case lists:member(LServer, ?MYHOSTS) of true -> set_vcard(User, LServer, SubEl), IQ#iq{type = result, sub_el = []}; false -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} end; get -> #jid{luser = LUser, lserver = LServer} = To, Username = ejabberd_odbc:escape(LUser), case catch odbc_queries:get_vcard(LServer, Username) of {selected, ["vcard"], [{SVCARD}]} -> case xml_stream:parse_element(SVCARD) of {error, _Reason} -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]}; VCARD -> IQ#iq{type = result, sub_el = [VCARD]} end; {selected, ["vcard"], []} -> IQ#iq{type = result, sub_el = []}; _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} end end. set_vcard(User, LServer, VCARD) -> FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]), Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]), Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]), Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]), Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]), BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]), CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]), Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]), EMail1 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, {elem, "USERID"},cdata]), EMail2 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]), OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]), OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]), EMail = case EMail1 of "" -> EMail2; _ -> EMail1 end, LUser = jlib:nodeprep(User), LFN = string2lower(FN), LFamily = string2lower(Family), LGiven = string2lower(Given), LMiddle = string2lower(Middle), LNickname = string2lower(Nickname), LBDay = string2lower(BDay), LCTRY = string2lower(CTRY), LLocality = string2lower(Locality), LEMail = string2lower(EMail), LOrgName = string2lower(OrgName), LOrgUnit = string2lower(OrgUnit), if (LUser == error) or (LFN == error) or (LFamily == error) or (LGiven == error) or (LMiddle == error) or (LNickname == error) or (LBDay == error) or (LCTRY == error) or (LLocality == error) or (LEMail == error) or (LOrgName == error) or (LOrgUnit == error) -> {error, badarg}; true -> Username = ejabberd_odbc:escape(User), LUsername = ejabberd_odbc:escape(LUser), SVCARD = ejabberd_odbc:escape( xml:element_to_binary(VCARD)), SFN = ejabberd_odbc:escape(FN), SLFN = ejabberd_odbc:escape(LFN), SFamily = ejabberd_odbc:escape(Family), SLFamily = ejabberd_odbc:escape(LFamily), SGiven = ejabberd_odbc:escape(Given), SLGiven = ejabberd_odbc:escape(LGiven), SMiddle = ejabberd_odbc:escape(Middle), SLMiddle = ejabberd_odbc:escape(LMiddle), SNickname = ejabberd_odbc:escape(Nickname), SLNickname = ejabberd_odbc:escape(LNickname), SBDay = ejabberd_odbc:escape(BDay), SLBDay = ejabberd_odbc:escape(LBDay), SCTRY = ejabberd_odbc:escape(CTRY), SLCTRY = ejabberd_odbc:escape(LCTRY), SLocality = ejabberd_odbc:escape(Locality), SLLocality = ejabberd_odbc:escape(LLocality), SEMail = ejabberd_odbc:escape(EMail), SLEMail = ejabberd_odbc:escape(LEMail), SOrgName = ejabberd_odbc:escape(OrgName), SLOrgName = ejabberd_odbc:escape(LOrgName), SOrgUnit = ejabberd_odbc:escape(OrgUnit), SLOrgUnit = ejabberd_odbc:escape(LOrgUnit), odbc_queries:set_vcard(LServer, LUsername, SBDay, SCTRY, SEMail, SFN, SFamily, SGiven, SLBDay, SLCTRY, SLEMail, SLFN, SLFamily, SLGiven, SLLocality, SLMiddle, SLNickname, SLOrgName, SLOrgUnit, SLocality, SMiddle, SNickname, SOrgName, SOrgUnit, SVCARD, Username), ejabberd_hooks:run(vcard_set, LServer, [LUser, LServer, VCARD]) end. string2lower(String) -> case stringprep:tolower(String) of Lower when is_list(Lower) -> Lower; error -> string:to_lower(String) end. -define(TLFIELD(Type, Label, Var), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, {"var", Var}], []}). -define(FORM(JID), [{xmlelement, "instructions", [], [{xmlcdata, translate:translate(Lang, "You need an x:data capable client to search")}]}, {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "Search users in ") ++ jlib:jid_to_string(JID)}]}, {xmlelement, "instructions", [], [{xmlcdata, translate:translate(Lang, "Fill in the form to search " "for any matching Jabber User " "(Add * to the end of field to " "match substring)")}]}, ?TLFIELD("text-single", "User", "user"), ?TLFIELD("text-single", "Full Name", "fn"), ?TLFIELD("text-single", "Name", "first"), ?TLFIELD("text-single", "Middle Name", "middle"), ?TLFIELD("text-single", "Family Name", "last"), ?TLFIELD("text-single", "Nickname", "nick"), ?TLFIELD("text-single", "Birthday", "bday"), ?TLFIELD("text-single", "Country", "ctry"), ?TLFIELD("text-single", "City", "locality"), ?TLFIELD("text-single", "Email", "email"), ?TLFIELD("text-single", "Organization Name", "orgname"), ?TLFIELD("text-single", "Organization Unit", "orgunit") ]}]). do_route(ServerHost, From, To, Packet) -> #jid{user = User, resource = Resource} = To, if (User /= "") or (Resource /= "") -> Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err); true -> IQ = jlib:iq_query_info(Packet), case IQ of #iq{type = Type, xmlns = ?NS_SEARCH, lang = Lang, sub_el = SubEl} -> case Type of set -> XDataEl = find_xdata_el(SubEl), case XDataEl of false -> Err = jlib:make_error_reply( Packet, ?ERR_BAD_REQUEST), ejabberd_router:route(To, From, Err); _ -> XData = jlib:parse_xdata_submit(XDataEl), case XData of invalid -> Err = jlib:make_error_reply( Packet, ?ERR_BAD_REQUEST), ejabberd_router:route(To, From, Err); _ -> ResIQ = IQ#iq{ type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_SEARCH}], [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}], search_result(Lang, To, ServerHost, XData) }]}]}, ejabberd_router:route( To, From, jlib:iq_to_xml(ResIQ)) end end; get -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_SEARCH}], ?FORM(To) }]}, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) end; #iq{type = Type, xmlns = ?NS_DISCO_INFO, lang = Lang} -> case Type of set -> Err = jlib:make_error_reply( Packet, ?ERR_NOT_ALLOWED), ejabberd_router:route(To, From, Err); get -> Info = ejabberd_hooks:run_fold( disco_info, ServerHost, [], [ServerHost, ?MODULE, "", ""]), ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_INFO}], [{xmlelement, "identity", [{"category", "directory"}, {"type", "user"}, {"name", translate:translate(Lang, "vCard User Search")}], []}, {xmlelement, "feature", [{"var", ?NS_SEARCH}], []}, {xmlelement, "feature", [{"var", ?NS_VCARD}], []} ] ++ Info }]}, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) end; #iq{type = Type, xmlns = ?NS_DISCO_ITEMS} -> case Type of set -> Err = jlib:make_error_reply( Packet, ?ERR_NOT_ALLOWED), ejabberd_router:route(To, From, Err); get -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}], []}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) end; #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", ?NS_VCARD}], iq_get_vcard(Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); _ -> Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err) end end. iq_get_vcard(Lang) -> [{xmlelement, "FN", [], [{xmlcdata, "ejabberd/mod_vcard"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate( Lang, "ejabberd vCard module") ++ "\nCopyright (c) 2003-2012 ProcessOne"}]}]. find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) -> find_xdata_el1(SubEls). find_xdata_el1([]) -> false; find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_XDATA -> {xmlelement, Name, Attrs, SubEls}; _ -> find_xdata_el1(Els) end; find_xdata_el1([_ | Els]) -> find_xdata_el1(Els). -define(LFIELD(Label, Var), {xmlelement, "field", [{"label", translate:translate(Lang, Label)}, {"var", Var}], []}). search_result(Lang, JID, ServerHost, Data) -> [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "Search Results for ") ++ jlib:jid_to_string(JID)}]}, {xmlelement, "reported", [], [?TLFIELD("text-single", "Jabber ID", "jid"), ?TLFIELD("text-single", "Full Name", "fn"), ?TLFIELD("text-single", "Name", "first"), ?TLFIELD("text-single", "Middle Name", "middle"), ?TLFIELD("text-single", "Family Name", "last"), ?TLFIELD("text-single", "Nickname", "nick"), ?TLFIELD("text-single", "Birthday", "bday"), ?TLFIELD("text-single", "Country", "ctry"), ?TLFIELD("text-single", "City", "locality"), ?TLFIELD("text-single", "Email", "email"), ?TLFIELD("text-single", "Organization Name", "orgname"), ?TLFIELD("text-single", "Organization Unit", "orgunit") ]}] ++ lists:map(fun(R) -> record_to_item(ServerHost, R) end, search(ServerHost, Data)). -define(FIELD(Var, Val), {xmlelement, "field", [{"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). record_to_item(LServer, {Username, FN, Family, Given, Middle, Nickname, BDay, CTRY, Locality, EMail, OrgName, OrgUnit}) -> {xmlelement, "item", [], [ ?FIELD("jid", Username ++ "@" ++ LServer), ?FIELD("fn", FN), ?FIELD("last", Family), ?FIELD("first", Given), ?FIELD("middle", Middle), ?FIELD("nick", Nickname), ?FIELD("bday", BDay), ?FIELD("ctry", CTRY), ?FIELD("locality", Locality), ?FIELD("email", EMail), ?FIELD("orgname", OrgName), ?FIELD("orgunit", OrgUnit) ] }. search(LServer, Data) -> MatchSpec = make_matchspec(LServer, Data), AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE, allow_return_all, false), if (MatchSpec == "") and (not AllowReturnAll) -> []; true -> Limit = case gen_mod:get_module_opt(LServer, ?MODULE, matches, ?JUD_MATCHES) of infinity -> ""; Val when is_integer(Val) and (Val > 0) -> [" LIMIT ", integer_to_list(Val)]; Val -> ?ERROR_MSG("Illegal option value ~p. " "Default value ~p substituted.", [{matches, Val}, ?JUD_MATCHES]), [" LIMIT ", integer_to_list(?JUD_MATCHES)] end, case catch ejabberd_odbc:sql_query( LServer, ["select username, fn, family, given, middle, " " nickname, bday, ctry, locality, " " email, orgname, orgunit from vcard_search ", MatchSpec, Limit, ";"]) of {selected, ["username", "fn", "family", "given", "middle", "nickname", "bday", "ctry", "locality", "email", "orgname", "orgunit"], Rs} when is_list(Rs) -> Rs; Error -> ?ERROR_MSG("~p", [Error]), [] end end. make_matchspec(LServer, Data) -> filter_fields(Data, "", LServer). filter_fields([], Match, _LServer) -> case Match of "" -> ""; _ -> [" where ", Match] end; filter_fields([{SVar, [Val]} | Ds], Match, LServer) when is_list(Val) and (Val /= "") -> LVal = string2lower(Val), NewMatch = case SVar of "user" -> make_val(Match, "lusername", LVal); "fn" -> make_val(Match, "lfn", LVal); "last" -> make_val(Match, "lfamily", LVal); "first" -> make_val(Match, "lgiven", LVal); "middle" -> make_val(Match, "lmiddle", LVal); "nick" -> make_val(Match, "lnickname", LVal); "bday" -> make_val(Match, "lbday", LVal); "ctry" -> make_val(Match, "lctry", LVal); "locality" -> make_val(Match, "llocality", LVal); "email" -> make_val(Match, "lemail", LVal); "orgname" -> make_val(Match, "lorgname", LVal); "orgunit" -> make_val(Match, "lorgunit", LVal); _ -> Match end, filter_fields(Ds, NewMatch, LServer); filter_fields([_ | Ds], Match, LServer) -> filter_fields(Ds, Match, LServer). make_val(Match, Field, Val) -> Condition = case lists:suffix("*", Val) of true -> Val1 = lists:sublist(Val, length(Val) - 1), SVal = ejabberd_odbc:escape_like(Val1) ++ "%", [Field, " LIKE '", SVal, "'"]; _ -> SVal = ejabberd_odbc:escape(Val), [Field, " = '", SVal, "'"] end, case Match of "" -> Condition; _ -> [Match, " and ", Condition] end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %set_vcard_t(R, _) -> % US = R#vcard.us, % User = US, % VCARD = R#vcard.vcard, % % FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]), % Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]), % Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]), % Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]), % Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]), % BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]), % CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]), % Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]), % EMail = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]), % OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]), % OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]), % % {LUser, _LServer} = US, % LFN = stringprep:tolower(FN), % LFamily = stringprep:tolower(Family), % LGiven = stringprep:tolower(Given), % LMiddle = stringprep:tolower(Middle), % LNickname = stringprep:tolower(Nickname), % LBDay = stringprep:tolower(BDay), % LCTRY = stringprep:tolower(CTRY), % LLocality = stringprep:tolower(Locality), % LEMail = stringprep:tolower(EMail), % LOrgName = stringprep:tolower(OrgName), % LOrgUnit = stringprep:tolower(OrgUnit), % % if % (LUser == error) or % (LFN == error) or % (LFamily == error) or % (LGiven == error) or % (LMiddle == error) or % (LNickname == error) or % (LBDay == error) or % (LCTRY == error) or % (LLocality == error) or % (LEMail == error) or % (LOrgName == error) or % (LOrgUnit == error) -> % {error, badarg}; % true -> % mnesia:write( % #vcard_search{us = US, % user = User, luser = LUser, % fn = FN, lfn = LFN, % family = Family, lfamily = LFamily, % given = Given, lgiven = LGiven, % middle = Middle, lmiddle = LMiddle, % nickname = Nickname, lnickname = LNickname, % bday = BDay, lbday = LBDay, % ctry = CTRY, lctry = LCTRY, % locality = Locality, llocality = LLocality, % email = EMail, lemail = LEMail, % orgname = OrgName, lorgname = LOrgName, % orgunit = OrgUnit, lorgunit = LOrgUnit % }) % end. % % %reindex_vcards() -> % F = fun() -> % mnesia:foldl(fun set_vcard_t/2, [], vcard) % end, % mnesia:transaction(F). remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), Username = ejabberd_odbc:escape(LUser), ejabberd_odbc:sql_transaction( LServer, [["delete from vcard where username='", Username, "';"], ["delete from vcard_search where lusername='", Username, "';"]]). ejabberd-2.1.11/src/cyrsasl_plain.erl0000664000000000000000000000545012240230175014360 0ustar %%%---------------------------------------------------------------------- %%% File : cyrsasl_plain.erl %%% Author : Alexey Shchepin %%% Purpose : PLAIN SASL mechanism %%% Created : 8 Mar 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(cyrsasl_plain). -author('alexey@process-one.net'). -export([start/1, stop/0, mech_new/4, mech_step/2, parse/1]). -behaviour(cyrsasl). -record(state, {check_password}). start(_Opts) -> cyrsasl:register_mechanism("PLAIN", ?MODULE, plain), ok. stop() -> ok. mech_new(_Host, _GetPassword, CheckPassword, _CheckPasswordDigest) -> {ok, #state{check_password = CheckPassword}}. mech_step(State, ClientIn) -> case prepare(ClientIn) of [AuthzId, User, Password] -> case (State#state.check_password)(User, Password) of {true, AuthModule} -> {ok, [{username, User}, {authzid, AuthzId}, {auth_module, AuthModule}]}; _ -> {error, "not-authorized", User} end; _ -> {error, "bad-protocol"} end. prepare(ClientIn) -> case parse(ClientIn) of [[], UserMaybeDomain, Password] -> case parse_domain(UserMaybeDomain) of %% login@domainpwd [User, _Domain] -> [UserMaybeDomain, User, Password]; %% loginpwd [User] -> ["", User, Password] end; %% login@domainloginpwd [AuthzId, User, Password] -> [AuthzId, User, Password]; _ -> error end. parse(S) -> parse1(S, "", []). parse1([0 | Cs], S, T) -> parse1(Cs, "", [lists:reverse(S) | T]); parse1([C | Cs], S, T) -> parse1(Cs, [C | S], T); %parse1([], [], T) -> % lists:reverse(T); parse1([], S, T) -> lists:reverse([lists:reverse(S) | T]). parse_domain(S) -> parse_domain1(S, "", []). parse_domain1([$@ | Cs], S, T) -> parse_domain1(Cs, "", [lists:reverse(S) | T]); parse_domain1([C | Cs], S, T) -> parse_domain1(Cs, [C | S], T); parse_domain1([], S, T) -> lists:reverse([lists:reverse(S) | T]). ejabberd-2.1.11/src/ejabberd_socket.erl0000664000000000000000000001672412240230175014631 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_socket.erl %%% Author : Alexey Shchepin %%% Purpose : Socket with zlib and TLS support library %%% Created : 23 Aug 2006 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_socket). -author('alexey@process-one.net'). %% API -export([start/4, connect/3, connect/4, starttls/2, starttls/3, compress/1, compress/2, reset_stream/1, send/2, send_xml/2, change_shaper/2, monitor/1, get_sockmod/1, get_peer_certificate/1, get_verify_result/1, close/1, sockname/1, peername/1]). -include("ejabberd.hrl"). -record(socket_state, {sockmod, socket, receiver}). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: %% Description: %%-------------------------------------------------------------------- start(Module, SockMod, Socket, Opts) -> case Module:socket_type() of xml_stream -> MaxStanzaSize = case lists:keysearch(max_stanza_size, 1, Opts) of {value, {_, Size}} -> Size; _ -> infinity end, {ReceiverMod, Receiver, RecRef} = case catch SockMod:custom_receiver(Socket) of {receiver, RecMod, RecPid} -> {RecMod, RecPid, RecMod}; _ -> RecPid = ejabberd_receiver:start( Socket, SockMod, none, MaxStanzaSize), {ejabberd_receiver, RecPid, RecPid} end, SocketData = #socket_state{sockmod = SockMod, socket = Socket, receiver = RecRef}, case Module:start({?MODULE, SocketData}, Opts) of {ok, Pid} -> case SockMod:controlling_process(Socket, Receiver) of ok -> ok; {error, _Reason} -> SockMod:close(Socket) end, ReceiverMod:become_controller(Receiver, Pid); {error, _Reason} -> SockMod:close(Socket), case ReceiverMod of ejabberd_receiver -> ReceiverMod:close(Receiver); _ -> ok end end; independent -> ok; raw -> case Module:start({SockMod, Socket}, Opts) of {ok, Pid} -> case SockMod:controlling_process(Socket, Pid) of ok -> ok; {error, _Reason} -> SockMod:close(Socket) end; {error, _Reason} -> SockMod:close(Socket) end end. connect(Addr, Port, Opts) -> connect(Addr, Port, Opts, infinity). connect(Addr, Port, Opts, Timeout) -> case gen_tcp:connect(Addr, Port, Opts, Timeout) of {ok, Socket} -> Receiver = ejabberd_receiver:start(Socket, gen_tcp, none), SocketData = #socket_state{sockmod = gen_tcp, socket = Socket, receiver = Receiver}, Pid = self(), case gen_tcp:controlling_process(Socket, Receiver) of ok -> ejabberd_receiver:become_controller(Receiver, Pid), {ok, SocketData}; {error, _Reason} = Error -> gen_tcp:close(Socket), Error end; {error, _Reason} = Error -> Error end. starttls(SocketData, TLSOpts) -> {ok, TLSSocket} = tls:tcp_to_tls(SocketData#socket_state.socket, TLSOpts), ejabberd_receiver:starttls(SocketData#socket_state.receiver, TLSSocket), SocketData#socket_state{socket = TLSSocket, sockmod = tls}. starttls(SocketData, TLSOpts, Data) -> {ok, TLSSocket} = tls:tcp_to_tls(SocketData#socket_state.socket, TLSOpts), ejabberd_receiver:starttls(SocketData#socket_state.receiver, TLSSocket), send(SocketData, Data), SocketData#socket_state{socket = TLSSocket, sockmod = tls}. compress(SocketData) -> {ok, ZlibSocket} = ejabberd_zlib:enable_zlib( SocketData#socket_state.sockmod, SocketData#socket_state.socket), ejabberd_receiver:compress(SocketData#socket_state.receiver, ZlibSocket), SocketData#socket_state{socket = ZlibSocket, sockmod = ejabberd_zlib}. compress(SocketData, Data) -> {ok, ZlibSocket} = ejabberd_zlib:enable_zlib( SocketData#socket_state.sockmod, SocketData#socket_state.socket), ejabberd_receiver:compress(SocketData#socket_state.receiver, ZlibSocket), send(SocketData, Data), SocketData#socket_state{socket = ZlibSocket, sockmod = ejabberd_zlib}. reset_stream(SocketData) when is_pid(SocketData#socket_state.receiver) -> ejabberd_receiver:reset_stream(SocketData#socket_state.receiver); reset_stream(SocketData) when is_atom(SocketData#socket_state.receiver) -> (SocketData#socket_state.receiver):reset_stream( SocketData#socket_state.socket). %% sockmod=gen_tcp|tls|ejabberd_zlib send(SocketData, Data) -> case catch (SocketData#socket_state.sockmod):send( SocketData#socket_state.socket, Data) of ok -> ok; {error, timeout} -> ?INFO_MSG("Timeout on ~p:send",[SocketData#socket_state.sockmod]), exit(normal); Error -> ?DEBUG("Error in ~p:send: ~p",[SocketData#socket_state.sockmod, Error]), exit(normal) end. %% Can only be called when in c2s StateData#state.xml_socket is true %% This function is used for HTTP bind %% sockmod=ejabberd_http_poll|ejabberd_http_bind or any custom module send_xml(SocketData, Data) -> catch (SocketData#socket_state.sockmod):send_xml( SocketData#socket_state.socket, Data). change_shaper(SocketData, Shaper) when is_pid(SocketData#socket_state.receiver) -> ejabberd_receiver:change_shaper(SocketData#socket_state.receiver, Shaper); change_shaper(SocketData, Shaper) when is_atom(SocketData#socket_state.receiver) -> (SocketData#socket_state.receiver):change_shaper( SocketData#socket_state.socket, Shaper). monitor(SocketData) when is_pid(SocketData#socket_state.receiver) -> erlang:monitor(process, SocketData#socket_state.receiver); monitor(SocketData) when is_atom(SocketData#socket_state.receiver) -> (SocketData#socket_state.receiver):monitor( SocketData#socket_state.socket). get_sockmod(SocketData) -> SocketData#socket_state.sockmod. get_peer_certificate(SocketData) -> tls:get_peer_certificate(SocketData#socket_state.socket). get_verify_result(SocketData) -> tls:get_verify_result(SocketData#socket_state.socket). close(SocketData) -> ejabberd_receiver:close(SocketData#socket_state.receiver). sockname(#socket_state{sockmod = SockMod, socket = Socket}) -> case SockMod of gen_tcp -> inet:sockname(Socket); _ -> SockMod:sockname(Socket) end. peername(#socket_state{sockmod = SockMod, socket = Socket}) -> case SockMod of gen_tcp -> inet:peername(Socket); _ -> SockMod:peername(Socket) end. %%==================================================================== %% Internal functions %%==================================================================== ejabberd-2.1.11/src/gen_iq_handler.erl0000664000000000000000000001601612240230175014454 0ustar %%%---------------------------------------------------------------------- %%% File : gen_iq_handler.erl %%% Author : Alexey Shchepin %%% Purpose : IQ handler support %%% Created : 22 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(gen_iq_handler). -author('alexey@process-one.net'). -behaviour(gen_server). %% API -export([start_link/3, add_iq_handler/6, remove_iq_handler/3, stop_iq_handler/3, handle/7, process_iq/6]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -record(state, {host, module, function}). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Host, Module, Function) -> gen_server:start_link(?MODULE, [Host, Module, Function], []). add_iq_handler(Component, Host, NS, Module, Function, Type) -> case Type of no_queue -> Component:register_iq_handler(Host, NS, Module, Function, no_queue); one_queue -> {ok, Pid} = supervisor:start_child(ejabberd_iq_sup, [Host, Module, Function]), Component:register_iq_handler(Host, NS, Module, Function, {one_queue, Pid}); {queues, N} -> Pids = lists:map( fun(_) -> {ok, Pid} = supervisor:start_child( ejabberd_iq_sup, [Host, Module, Function]), Pid end, lists:seq(1, N)), Component:register_iq_handler(Host, NS, Module, Function, {queues, Pids}); parallel -> Component:register_iq_handler(Host, NS, Module, Function, parallel) end. remove_iq_handler(Component, Host, NS) -> Component:unregister_iq_handler(Host, NS). stop_iq_handler(_Module, _Function, Opts) -> case Opts of {one_queue, Pid} -> gen_server:call(Pid, stop); {queues, Pids} -> lists:foreach(fun(Pid) -> catch gen_server:call(Pid, stop) end, Pids); _ -> ok end. handle(Host, Module, Function, Opts, From, To, IQ) -> case Opts of no_queue -> process_iq(Host, Module, Function, From, To, IQ); {one_queue, Pid} -> Pid ! {process_iq, From, To, IQ}; {queues, Pids} -> Pid = lists:nth(erlang:phash(now(), length(Pids)), Pids), Pid ! {process_iq, From, To, IQ}; parallel -> spawn(?MODULE, process_iq, [Host, Module, Function, From, To, IQ]); _ -> todo end. process_iq(_Host, Module, Function, From, To, IQ) -> case catch Module:Function(From, To, IQ) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); ResIQ -> if ResIQ /= ignore -> ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); true -> ok end end. %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([Host, Module, Function]) -> {ok, #state{host = Host, module = Module, function = Function}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call(stop, _From, State) -> Reply = ok, {stop, normal, Reply, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({process_iq, From, To, IQ}, #state{host = Host, module = Module, function = Function} = State) -> process_iq(Host, Module, Function, From, To, IQ), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- ejabberd-2.1.11/src/ejabberd_system_monitor.erl0000664000000000000000000002716212240230175016432 0ustar %%%------------------------------------------------------------------- %%% File : ejabberd_system_monitor.erl %%% Author : Alexey Shchepin %%% Description : Ejabberd watchdog %%% Created : 21 Mar 2007 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(ejabberd_system_monitor). -author('alexey@process-one.net'). -behaviour(gen_server). %% API -export([start_link/0, process_command/3, process_remote_command/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -record(state, {}). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link() -> LH = case ejabberd_config:get_local_option(watchdog_large_heap) of I when is_integer(I) -> I; _ -> 1000000 end, Opts = [{large_heap, LH}], gen_server:start_link({local, ?MODULE}, ?MODULE, Opts, []). process_command(From, To, Packet) -> case To of #jid{luser = "", lresource = "watchdog"} -> {xmlelement, Name, _Attrs, _Els} = Packet, case Name of "message" -> LFrom = jlib:jid_tolower(jlib:jid_remove_resource(From)), case lists:member(LFrom, get_admin_jids()) of true -> Body = xml:get_path_s( Packet, [{elem, "body"}, cdata]), spawn(fun() -> process_flag(priority, high), process_command1(From, To, Body) end), stop; false -> ok end; _ -> ok end; _ -> ok end. %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init(Opts) -> LH = proplists:get_value(large_heap, Opts), process_flag(priority, high), erlang:system_monitor(self(), [{large_heap, LH}]), lists:foreach( fun(Host) -> ejabberd_hooks:add(local_send_to_resource_hook, Host, ?MODULE, process_command, 50) end, ?MYHOSTS), {ok, #state{}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call({get, large_heap}, _From, State) -> {reply, get_large_heap(), State}; handle_call({set, large_heap, NewValue}, _From, State) -> MonSettings = erlang:system_monitor(self(), [{large_heap, NewValue}]), OldLH = get_large_heap(MonSettings), NewLH = get_large_heap(), {reply, {lh_changed, OldLH, NewLH}, State}; handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. get_large_heap() -> MonSettings = erlang:system_monitor(), get_large_heap(MonSettings). get_large_heap(MonSettings) -> {_MonitorPid, Options} = MonSettings, proplists:get_value(large_heap, Options). %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({monitor, Pid, large_heap, Info}, State) -> spawn(fun() -> process_flag(priority, high), process_large_heap(Pid, Info) end), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- process_large_heap(Pid, Info) -> Host = ?MYNAME, case ejabberd_config:get_local_option(watchdog_admins) of JIDs when is_list(JIDs), JIDs /= [] -> DetailedInfo = detailed_info(Pid), Body = io_lib:format( "(~w) The process ~w is consuming too much memory:~n~p~n" "~s", [node(), Pid, Info, DetailedInfo]), From = jlib:make_jid("", Host, "watchdog"), lists:foreach( fun(S) -> case jlib:string_to_jid(S) of error -> ok; JID -> send_message(From, JID, Body) end end, JIDs); _ -> ok end. send_message(From, To, Body) -> ejabberd_router:route( From, To, {xmlelement, "message", [{"type", "chat"}], [{xmlelement, "body", [], [{xmlcdata, lists:flatten(Body)}]}]}). get_admin_jids() -> case ejabberd_config:get_local_option(watchdog_admins) of JIDs when is_list(JIDs) -> lists:flatmap( fun(S) -> case jlib:string_to_jid(S) of error -> []; JID -> [jlib:jid_tolower(JID)] end end, JIDs); _ -> [] end. detailed_info(Pid) -> case process_info(Pid, dictionary) of {dictionary, Dict} -> case lists:keysearch('$ancestors', 1, Dict) of {value, {'$ancestors', [Sup | _]}} -> case Sup of ejabberd_c2s_sup -> c2s_info(Pid); ejabberd_s2s_out_sup -> s2s_out_info(Pid); ejabberd_service_sup -> service_info(Pid); _ -> detailed_info1(Pid) end; _ -> detailed_info1(Pid) end; _ -> detailed_info1(Pid) end. detailed_info1(Pid) -> io_lib:format( "~p", [[process_info(Pid, current_function), process_info(Pid, initial_call), process_info(Pid, message_queue_len), process_info(Pid, links), process_info(Pid, dictionary), process_info(Pid, heap_size), process_info(Pid, stack_size) ]]). c2s_info(Pid) -> ["Process type: c2s", check_send_queue(Pid), "\n", io_lib:format("Command to kill this process: kill ~s ~w", [atom_to_list(node()), Pid])]. s2s_out_info(Pid) -> FromTo = mnesia:dirty_select( s2s, [{{s2s, '$1', Pid, '_'}, [], ['$1']}]), ["Process type: s2s_out", case FromTo of [{From, To}] -> "\n" ++ io_lib:format("S2S connection: from ~s to ~s", [From, To]); _ -> "" end, check_send_queue(Pid), "\n", io_lib:format("Command to kill this process: kill ~s ~w", [atom_to_list(node()), Pid])]. service_info(Pid) -> Routes = mnesia:dirty_select( route, [{{route, '$1', Pid, '_'}, [], ['$1']}]), ["Process type: s2s_out", case Routes of [Route] -> "\nServiced domain: " ++ Route; _ -> "" end, check_send_queue(Pid), "\n", io_lib:format("Command to kill this process: kill ~s ~w", [atom_to_list(node()), Pid])]. check_send_queue(Pid) -> case {process_info(Pid, current_function), process_info(Pid, message_queue_len)} of {{current_function, MFA}, {message_queue_len, MLen}} -> if MLen > 100 -> case MFA of {prim_inet, send, 2} -> "\nPossible reason: the process is blocked " "trying to send data over its TCP connection."; {M, F, A} -> ["\nPossible reason: the process can't process " "messages faster than they arrive. ", io_lib:format("Current function is ~w:~w/~w", [M, F, A]) ] end; true -> "" end; _ -> "" end. process_command1(From, To, Body) -> process_command2(string:tokens(Body, " "), From, To). process_command2(["kill", SNode, SPid], From, To) -> Node = list_to_atom(SNode), remote_command(Node, [kill, SPid], From, To); process_command2(["showlh", SNode], From, To) -> Node = list_to_atom(SNode), remote_command(Node, [showlh], From, To); process_command2(["setlh", SNode, NewValueString], From, To) -> Node = list_to_atom(SNode), NewValue = list_to_integer(NewValueString), remote_command(Node, [setlh, NewValue], From, To); process_command2(["help"], From, To) -> send_message(To, From, help()); process_command2(_, From, To) -> send_message(To, From, help()). help() -> "Commands:\n" " kill \n" " showlh \n" " setlh ". remote_command(Node, Args, From, To) -> Message = case rpc:call(Node, ?MODULE, process_remote_command, [Args]) of {badrpc, Reason} -> io_lib:format("Command failed:~n~p", [Reason]); Result -> Result end, send_message(To, From, Message). process_remote_command([kill, SPid]) -> exit(list_to_pid(SPid), kill), "ok"; process_remote_command([showlh]) -> Res = gen_server:call(ejabberd_system_monitor, {get, large_heap}), io_lib:format("Current large heap: ~p", [Res]); process_remote_command([setlh, NewValue]) -> {lh_changed, OldLH, NewLH} = gen_server:call(ejabberd_system_monitor, {set, large_heap, NewValue}), io_lib:format("Result of set large heap: ~p --> ~p", [OldLH, NewLH]); process_remote_command(_) -> throw(unknown_command). ejabberd-2.1.11/src/ejabberd_regexp.erl0000664000000000000000000000446012240230175014625 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_regexp.erl %%% Author : Badlop %%% Purpose : Frontend to Re and Regexp OTP modules %%% Created : 8 Dec 2011 by Badlop %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_regexp). -compile([export_all]). exec(ReM, ReF, ReA, RgM, RgF, RgA) -> try apply(ReM, ReF, ReA) catch error:undef -> apply(RgM, RgF, RgA); A:B -> {error, {A, B}} end. run(String, Regexp) -> case exec(re, run, [String, Regexp, [{capture, none}]], regexp, first_match, [String, Regexp]) of {match, _, _} -> match; {match, _} -> match; match -> match; nomatch -> nomatch; {error, Error} -> {error, Error} end. split(String, Regexp) -> case exec(re, split, [String, Regexp, [{return, list}]], regexp, split, [String, Regexp]) of {ok, FieldList} -> FieldList; {error, Error} -> throw(Error); A -> A end. replace(String, Regexp, New) -> case exec(re, replace, [String, Regexp, New, [{return, list}]], regexp, sub, [String, Regexp, New]) of {ok, NewString, _RepCount} -> NewString; {error, Error} -> throw(Error); A -> A end. greplace(String, Regexp, New) -> case exec(re, replace, [String, Regexp, New, [global, {return, list}]], regexp, sub, [String, Regexp, New]) of {ok, NewString, _RepCount} -> NewString; {error, Error} -> throw(Error); A -> A end. sh_to_awk(ShRegExp) -> case exec(xmerl_regexp, sh_to_awk, [ShRegExp], regexp, sh_to_awk, [ShRegExp]) of A -> A end. ejabberd-2.1.11/src/cache_tab.erl0000664000000000000000000004216612240230175013413 0ustar %%%------------------------------------------------------------------- %%% File : cache_tab.erl %%% Author : Evgeniy Khramtsov %%% Description : Caching key-value table %%% %%% Created : 29 Aug 2010 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(cache_tab). -define(GEN_SERVER, gen_server). -behaviour(?GEN_SERVER). %% API -export([start_link/4, new/2, delete/1, delete/3, lookup/3, insert/4, info/2, tab2list/1, setopts/2, dirty_lookup/3, dirty_insert/4, dirty_delete/3, all/0, test/0]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -record(state, {tab = treap:empty(), name, size = 0, owner, max_size, life_time, warn, hits = 0, miss = 0, procs_num, cache_missed, lru, shrink_size}). -define(PROCNAME, ?MODULE). -define(CALL_TIMEOUT, 60000). %% Defaults -define(MAX_SIZE, 1000). -define(WARN, true). -define(CACHE_MISSED, true). -define(LRU, true). -define(LIFETIME, 600). %% 10 minutes %%==================================================================== %% API %%==================================================================== start_link(Proc, Tab, Opts, Owner) -> ?GEN_SERVER:start_link( {local, Proc}, ?MODULE, [Tab, Opts, get_proc_num(), Owner], []). new(Tab, Opts) -> Res = lists:flatmap( fun(Proc) -> Spec = {{Tab, Proc}, {?MODULE, start_link, [Proc, Tab, Opts, self()]}, permanent, brutal_kill, worker, [?MODULE]}, case supervisor:start_child(cache_tab_sup, Spec) of {ok, _Pid} -> [ok]; R -> [R] end end, get_all_procs(Tab)), case lists:filter(fun(ok) -> false; (_) -> true end, Res) of [] -> ok; Err -> {error, Err} end. delete(Tab) -> lists:foreach( fun(Proc) -> supervisor:terminate_child(cache_tab_sup, {Tab, Proc}), supervisor:delete_child(cache_tab_sup, {Tab, Proc}) end, get_all_procs(Tab)). delete(Tab, Key, F) -> ?GEN_SERVER:call( get_proc_by_hash(Tab, Key), {delete, Key, F}, ?CALL_TIMEOUT). dirty_delete(Tab, Key, F) -> F(), ?GEN_SERVER:call( get_proc_by_hash(Tab, Key), {cache_delete, Key}, ?CALL_TIMEOUT). lookup(Tab, Key, F) -> ?GEN_SERVER:call( get_proc_by_hash(Tab, Key), {lookup, Key, F}, ?CALL_TIMEOUT). dirty_lookup(Tab, Key, F) -> Proc = get_proc_by_hash(Tab, Key), case ?GEN_SERVER:call(Proc, {cache_lookup, Key}, ?CALL_TIMEOUT) of {ok, '$cached_mismatch'} -> error; {ok, Val} -> {ok, Val}; _ -> {Result, NewVal} = case F() of {ok, Val} -> {{ok, Val}, Val}; _ -> {error, '$cached_mismatch'} end, ?GEN_SERVER:call( Proc, {cache_insert, Key, NewVal}, ?CALL_TIMEOUT), Result end. insert(Tab, Key, Val, F) -> ?GEN_SERVER:call( get_proc_by_hash(Tab, Key), {insert, Key, Val, F}, ?CALL_TIMEOUT). dirty_insert(Tab, Key, Val, F) -> F(), ?GEN_SERVER:call( get_proc_by_hash(Tab, Key), {cache_insert, Key, Val}, ?CALL_TIMEOUT). info(Tab, Info) -> case lists:map( fun(Proc) -> ?GEN_SERVER:call(Proc, {info, Info}, ?CALL_TIMEOUT) end, get_all_procs(Tab)) of Res when Info == size -> {ok, lists:sum(Res)}; Res when Info == all -> {ok, Res}; Res when Info == ratio -> {H, M} = lists:foldl( fun({Hits, Miss}, {HitsAcc, MissAcc}) -> {HitsAcc + Hits, MissAcc + Miss} end, {0, 0}, Res), {ok, [{hits, H}, {miss, M}]}; _ -> {error, badarg} end. setopts(Tab, Opts) -> lists:foreach( fun(Proc) -> ?GEN_SERVER:call(Proc, {setopts, Opts}, ?CALL_TIMEOUT) end, get_all_procs(Tab)). tab2list(Tab) -> lists:flatmap( fun(Proc) -> ?GEN_SERVER:call(Proc, tab2list, ?CALL_TIMEOUT) end, get_all_procs(Tab)). all() -> lists:usort( [Tab || {{Tab, _}, _, _, _} <- supervisor:which_children(cache_tab_sup)]). %%==================================================================== %% gen_server callbacks %%==================================================================== init([Tab, Opts, N, Pid]) -> State = #state{procs_num = N, owner = Pid, name = Tab}, {ok, do_setopts(State, Opts)}. handle_call({lookup, Key, F}, _From, #state{tab = T} = State) -> CleanPrio = clean_priority(State#state.life_time), case treap:lookup(Key, T) of {ok, Prio, Val} when (State#state.lru == true) or (Prio =< CleanPrio) -> Hits = State#state.hits, NewState = treap_update(Key, Val, State#state{hits = Hits + 1}), case Val of '$cached_mismatch' -> {reply, error, NewState}; _ -> {reply, {ok, Val}, NewState} end; _ -> case catch F() of {ok, Val} -> Miss = State#state.miss, NewState = treap_insert(Key, Val, State), {reply, {ok, Val}, NewState#state{miss = Miss + 1}}; {'EXIT', Reason} -> print_error(lookup, [Key], Reason, State), {reply, error, State}; _ -> Miss = State#state.miss, NewState = State#state{miss = Miss + 1}, if State#state.cache_missed -> {reply, error, treap_insert(Key, '$cached_mismatch', NewState)}; true -> {reply, error, NewState} end end end; handle_call({cache_lookup, Key}, _From, #state{tab = T} = State) -> CleanPrio = clean_priority(State#state.life_time), case treap:lookup(Key, T) of {ok, Prio, Val} when (State#state.lru == true) or (Prio =< CleanPrio) -> Hits = State#state.hits, NewState = treap_update(Key, Val, State#state{hits = Hits + 1}), {reply, {ok, Val}, NewState}; _ -> Miss = State#state.miss, NewState = State#state{miss = Miss + 1}, {reply, error, NewState} end; handle_call({insert, Key, Val, F}, _From, #state{tab = T} = State) -> case treap:lookup(Key, T) of {ok, _Prio, Val} -> {reply, ok, treap_update(Key, Val, State)}; _ -> case catch F() of {'EXIT', Reason} -> print_error(insert, [Key, Val], Reason, State), {reply, ok, State}; _ -> {reply, ok, treap_insert(Key, Val, State)} end end; handle_call({cache_insert, _, '$cached_mismatch'}, _From, #state{cache_missed = false} = State) -> {reply, ok, State}; handle_call({cache_insert, Key, Val}, _From, State) -> {reply, ok, treap_insert(Key, Val, State)}; handle_call({delete, Key, F}, _From, State) -> NewState = treap_delete(Key, State), case catch F() of {'EXIT', Reason} -> print_error(delete, [Key], Reason, State); _ -> ok end, {reply, ok, NewState}; handle_call({cache_delete, Key}, _From, State) -> NewState = treap_delete(Key, State), {reply, ok, NewState}; handle_call({info, Info}, _From, State) -> Res = case Info of size -> State#state.size; ratio -> {State#state.hits, State#state.miss}; all -> [{max_size, State#state.max_size}, {life_time, State#state.life_time}, {shrink_size, State#state.shrink_size}, {size, State#state.size}, {owner, State#state.owner}, {hits, State#state.hits}, {miss, State#state.miss}, {cache_missed, State#state.cache_missed}, {lru, State#state.lru}, {warn, State#state.warn}]; _ -> badarg end, {reply, Res, State}; handle_call(tab2list, _From, #state{tab = T} = State) -> Res = treap:fold( fun({Key, _, Val}, Acc) -> [{Key, Val}|Acc] end, [], T), {reply, Res, State}; handle_call({setopts, Opts}, _From, State) -> {reply, ok, do_setopts(State, Opts)}; handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. handle_cast(_Msg, State) -> {noreply, State}. handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- do_setopts(#state{procs_num = N} = State, Opts) -> MaxSize = case {proplists:get_value(max_size, Opts), State#state.max_size} of {MS, _} when is_integer(MS), MS > 0 -> round(MS/N); {unlimited, _} -> unlimited; {_, undefined} -> round(?MAX_SIZE/N); {_, MS} -> MS end, LifeTime = case {proplists:get_value(life_time, Opts), State#state.life_time} of {LT, _} when is_integer(LT), LT > 0 -> LT*1000*1000; {unlimited, _} -> unlimited; {_, undefined} -> ?LIFETIME*1000*1000; {_, LT} -> LT end, ShrinkSize = case {proplists:get_value(shrink_size, Opts), State#state.shrink_size} of {SS, _} when is_integer(SS), SS > 0 -> round(SS/N); _ when is_integer(MaxSize) -> round(MaxSize/2); _ -> unlimited end, Warn = case {proplists:get_value(warn, Opts), State#state.warn} of {true, _} -> true; {false, _} -> false; {_, undefined} -> ?WARN; {_, W} -> W end, CacheMissed = case proplists:get_value( cache_missed, Opts, State#state.cache_missed) of false -> false; true -> true; _ -> ?CACHE_MISSED end, LRU = case proplists:get_value( lru, Opts, State#state.lru) of false -> false; true -> true; _ -> ?LRU end, State#state{max_size = MaxSize, warn = Warn, life_time = LifeTime, cache_missed = CacheMissed, lru = LRU, shrink_size = ShrinkSize}. get_proc_num() -> case erlang:system_info(logical_processors) of unknown -> 1; Num -> Num end. get_proc_by_hash(Tab, Term) -> N = erlang:phash2(Term, get_proc_num()) + 1, get_proc(Tab, N). get_proc(Tab, N) -> list_to_atom(atom_to_list(?PROCNAME) ++ "_" ++ atom_to_list(Tab) ++ "_" ++ integer_to_list(N)). get_all_procs(Tab) -> [get_proc(Tab, N) || N <- lists:seq(1, get_proc_num())]. now_priority() -> {MSec, Sec, USec} = now(), -((MSec*1000000 + Sec)*1000000 + USec). clean_priority(LifeTime) -> if is_integer(LifeTime) -> now_priority() + LifeTime; true -> unlimited end. treap_update(Key, Val, #state{tab = T, lru = LRU} = State) -> if LRU -> Priority = now_priority(), NewT = treap:insert(Key, Priority, Val, T), State#state{tab = NewT}; true -> State end. treap_insert(Key, Val, State) -> State1 = clean_treap(State), #state{size = Size} = State2 = shrink_treap(State1), T = State2#state.tab, case treap:lookup(Key, T) of {ok, _, Val} -> treap_update(Key, Val, State2); {ok, _, _} -> NewT = treap:insert(Key, now_priority(), Val, T), State2#state{tab = NewT}; _ -> NewT = treap:insert(Key, now_priority(), Val, T), State2#state{tab = NewT, size = Size+1} end. treap_delete(Key, #state{tab = T, size = Size} = State) -> case treap:lookup(Key, T) of {ok, _, _} -> NewT = treap:delete(Key, T), clean_treap(State#state{tab = NewT, size = Size-1}); _ -> State end. clean_treap(#state{tab = T, size = Size, life_time = LifeTime} = State) -> if is_integer(LifeTime) -> Priority = now_priority(), {Cleaned, NewT} = clean_treap(T, Priority + LifeTime, 0), State#state{size = Size - Cleaned, tab = NewT}; true -> State end. clean_treap(Treap, CleanPriority, N) -> case treap:is_empty(Treap) of true -> {N, Treap}; false -> {_Key, Priority, _Value} = treap:get_root(Treap), if Priority > CleanPriority -> clean_treap(treap:delete_root(Treap), CleanPriority, N+1); true -> {N, Treap} end end. shrink_treap(#state{tab = T, max_size = MaxSize, shrink_size = ShrinkSize, warn = Warn, size = Size} = State) when Size >= MaxSize -> if Warn -> ?WARNING_MSG("shrinking table:~n" "** Table: ~p~n" "** Processes Number: ~p~n" "** Max Size: ~p items~n" "** Shrink Size: ~p items~n" "** Life Time: ~p microseconds~n" "** Hits/Miss: ~p/~p~n" "** Owner: ~p~n" "** Cache Missed: ~p~n" "** Instruction: you have to tune cacheing options" " if this message repeats too frequently", [State#state.name, State#state.procs_num, MaxSize, ShrinkSize, State#state.life_time, State#state.hits, State#state.miss, State#state.owner, State#state.cache_missed]); true -> ok end, {Shrinked, NewT} = shrink_treap(T, ShrinkSize, 0), State#state{tab = NewT, size = Size - Shrinked}; shrink_treap(State) -> State. shrink_treap(T, ShrinkSize, ShrinkSize) -> {ShrinkSize, T}; shrink_treap(T, ShrinkSize, N) -> case treap:is_empty(T) of true -> {N, T}; false -> shrink_treap(treap:delete_root(T), ShrinkSize, N+1) end. print_error(Operation, Args, Reason, State) -> ?ERROR_MSG("callback failed:~n" "** Tab: ~p~n" "** Owner: ~p~n" "** Operation: ~p~n" "** Args: ~p~n" "** Reason: ~p", [State#state.name, State#state.owner, Operation, Args, Reason]). %%-------------------------------------------------------------------- %%% Tests %%-------------------------------------------------------------------- -define(lookup, dirty_lookup). -define(delete, dirty_delete). -define(insert, dirty_insert). %%-define(lookup, lookup). %%-define(delete, delete). %%-define(insert, insert). test() -> LifeTime = 2, ok = new(test_tbl, [{life_time, LifeTime}, {max_size, unlimited}]), check([]), ok = ?insert(test_tbl, "key", "value", fun() -> ok end), check([{"key", "value"}]), {ok, "value"} = ?lookup(test_tbl, "key", fun() -> error end), check([{"key", "value"}]), io:format("** waiting for ~p seconds to check if LRU works fine...~n", [LifeTime+1]), timer:sleep(timer:seconds(LifeTime+1)), ok = ?insert(test_tbl, "key1", "value1", fun() -> ok end), check([{"key1", "value1"}]), ok = ?delete(test_tbl, "key1", fun() -> ok end), {ok, "value"} = ?lookup(test_tbl, "key", fun() -> {ok, "value"} end), check([{"key", "value"}]), ok = ?delete(test_tbl, "key", fun() -> ok end), check([]), %% io:format("** testing buggy callbacks...~n"), %% delete(test_tbl, "key", fun() -> erlang:error(badarg) end), %% insert(test_tbl, "key", "val", fun() -> erlang:error(badarg) end), %% lookup(test_tbl, "key", fun() -> erlang:error(badarg) end), check([]), delete(test_tbl), test1(). test1() -> MaxSize = 10, ok = new(test_tbl, [{max_size, MaxSize}, {shrink_size, 1}, {warn, false}]), lists:foreach( fun(N) -> ok = ?insert(test_tbl, N, N, fun() -> ok end) end, lists:seq(1, MaxSize*get_proc_num())), {ok, MaxSize} = info(test_tbl, size), delete(test_tbl), test2(). test2() -> LifeTime = 2, ok = new(test_tbl, [{life_time, LifeTime}, {max_size, unlimited}, {lru, false}]), check([]), ok = ?insert(test_tbl, "key", "value", fun() -> ok end), {ok, "value"} = ?lookup(test_tbl, "key", fun() -> error end), check([{"key", "value"}]), io:format("** waiting for ~p seconds to check if non-LRU works fine...~n", [LifeTime+1]), timer:sleep(timer:seconds(LifeTime+1)), error = ?lookup(test_tbl, "key", fun() -> error end), check([{"key", '$cached_mismatch'}]), ok = ?insert(test_tbl, "key", "value1", fun() -> ok end), check([{"key", "value1"}]), delete(test_tbl), io:format("** testing speed, this may take a while...~n"), test3(1000), test3(10000), test3(100000), test3(1000000). test3(Iter) -> ok = new(test_tbl, [{max_size, unlimited}, {life_time, unlimited}]), L = lists:seq(1, Iter), T1 = now(), lists:foreach( fun(N) -> ok = ?insert(test_tbl, N, N, fun() -> ok end) end, L), io:format("** average insert (size = ~p): ~p usec~n", [Iter, round(timer:now_diff(now(), T1)/Iter)]), T2 = now(), lists:foreach( fun(N) -> {ok, N} = ?lookup(test_tbl, N, fun() -> ok end) end, L), io:format("** average lookup (size = ~p): ~p usec~n", [Iter, round(timer:now_diff(now(), T2)/Iter)]), {ok, Iter} = info(test_tbl, size), delete(test_tbl). check(List) -> Size = length(List), {ok, Size} = info(test_tbl, size), List = tab2list(test_tbl). ejabberd-2.1.11/src/mod_vcard_xupdate.erl0000664000000000000000000000750312240230175015206 0ustar %%%---------------------------------------------------------------------- %%% File : mod_vcard_xupdate.erl %%% Author : Igor Goryachev %%% Purpose : Add avatar hash in presence on behalf of client (XEP-0153) %%% Created : 9 Mar 2007 by Igor Goryachev %%%---------------------------------------------------------------------- -module(mod_vcard_xupdate). -behaviour(gen_mod). %% gen_mod callbacks -export([start/2, stop/1]). %% hooks -export([update_presence/3, vcard_set/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -record(vcard_xupdate, {us, hash}). %%==================================================================== %% gen_mod callbacks %%==================================================================== start(Host, _Opts) -> mnesia:create_table(vcard_xupdate, [{disc_copies, [node()]}, {attributes, record_info(fields, vcard_xupdate)}]), ejabberd_hooks:add(c2s_update_presence, Host, ?MODULE, update_presence, 100), ejabberd_hooks:add(vcard_set, Host, ?MODULE, vcard_set, 100), ok. stop(Host) -> ejabberd_hooks:delete(c2s_update_presence, Host, ?MODULE, update_presence, 100), ejabberd_hooks:delete(vcard_set, Host, ?MODULE, vcard_set, 100), ok. %%==================================================================== %% Hooks %%==================================================================== update_presence({xmlelement, "presence", Attrs, _Els} = Packet, User, Host) -> case xml:get_attr_s("type", Attrs) of [] -> presence_with_xupdate(Packet, User, Host); _ -> Packet end; update_presence(Packet, _User, _Host) -> Packet. vcard_set(LUser, LServer, VCARD) -> US = {LUser, LServer}, case xml:get_path_s(VCARD, [{elem, "PHOTO"}, {elem, "BINVAL"}, cdata]) of [] -> remove_xupdate(LUser, LServer); BinVal -> add_xupdate(LUser, LServer, sha:sha(jlib:decode_base64(BinVal))) end, ejabberd_sm:force_update_presence(US). %%==================================================================== %% Mnesia storage %%==================================================================== add_xupdate(LUser, LServer, Hash) -> F = fun() -> mnesia:write(#vcard_xupdate{us = {LUser, LServer}, hash = Hash}) end, mnesia:transaction(F). get_xupdate(LUser, LServer) -> case mnesia:dirty_read(vcard_xupdate, {LUser, LServer}) of [#vcard_xupdate{hash = Hash}] -> Hash; _ -> undefined end. remove_xupdate(LUser, LServer) -> F = fun() -> mnesia:delete({vcard_xupdate, {LUser, LServer}}) end, mnesia:transaction(F). %%%---------------------------------------------------------------------- %%% Presence stanza rebuilding %%%---------------------------------------------------------------------- presence_with_xupdate({xmlelement, "presence", Attrs, Els}, User, Host) -> XPhotoEl = build_xphotoel(User, Host), Els2 = presence_with_xupdate2(Els, [], XPhotoEl), {xmlelement, "presence", Attrs, Els2}. presence_with_xupdate2([], Els2, XPhotoEl) -> lists:reverse([XPhotoEl | Els2]); %% This clause assumes that the x element contains only the XMLNS attribute: presence_with_xupdate2([{xmlelement, "x", [{"xmlns", ?NS_VCARD_UPDATE}], _} | Els], Els2, XPhotoEl) -> presence_with_xupdate2(Els, Els2, XPhotoEl); presence_with_xupdate2([El | Els], Els2, XPhotoEl) -> presence_with_xupdate2(Els, [El | Els2], XPhotoEl). build_xphotoel(User, Host) -> Hash = get_xupdate(User, Host), PhotoSubEls = case Hash of Hash when is_list(Hash) -> [{xmlcdata, Hash}]; _ -> [] end, PhotoEl = [{xmlelement, "photo", [], PhotoSubEls}], {xmlelement, "x", [{"xmlns", ?NS_VCARD_UPDATE}], PhotoEl}. ejabberd-2.1.11/src/ejabberdctl.cfg.example0000664000000000000000000001115012240230175015357 0ustar # # In this file you can configure options that are passed by ejabberdctl # to the erlang runtime system when starting ejabberd # #' POLL: Kernel polling ([true|false]) # # The kernel polling option requires support in the kernel. # Additionally, you need to enable this feature while compiling Erlang. # # Default: true # #POLL=true #. #' SMP: SMP support ([enable|auto|disable]) # # Explanation in Erlang/OTP documentation: # enable: starts the Erlang runtime system with SMP support enabled. # This may fail if no runtime system with SMP support is available. # auto: starts the Erlang runtime system with SMP support enabled if it # is available and more than one logical processor are detected. # disable: starts a runtime system without SMP support. # # Default: auto # #SMP=auto #. #' ERL_MAX_PORTS: Maximum number of simultaneously open Erlang ports # # ejabberd consumes two or three ports for every connection, either # from a client or from another Jabber server. So take this into # account when setting this limit. # # Default: 32000 # Maximum: 268435456 # #ERL_MAX_PORTS=32000 #. #' FIREWALL_WINDOW: Range of allowed ports to pass through a firewall # # If Ejabberd is configured to run in cluster, and a firewall is blocking ports, # it's possible to make Erlang use a defined range of port (instead of dynamic # ports) for node communication. # # Default: not defined # Example: 4200-4210 # #FIREWALL_WINDOW= #. #' INET_DIST_INTERFACE: IP address where this Erlang node listens other nodes # # This communication is used by ejabberdctl command line tool, # and in a cluster of several ejabberd nodes. # Notice that the IP address must be specified in the Erlang syntax. # # Default: {127,0,0,1} # INET_DIST_INTERFACE={127,0,0,1} #. #' ERL_EPMD_ADDRESS: IP addresses where epmd listens for connections # # IMPORTANT: This option works only in Erlang/OTP R14B03 and newer. # # This environment variable may be set to a comma-separated # list of IP addresses, in which case the epmd daemon # will listen only on the specified address(es) and on the # loopback address (which is implicitly added to the list if it # has not been specified). The default behaviour is to listen on # all available IP addresses. # # Default: 0.0.0.0 # #ERL_EPMD_ADDRESS=127.0.0.1 #. #' ERL_PROCESSES: Maximum number of Erlang processes # # Erlang consumes a lot of lightweight processes. If there is a lot of activity # on ejabberd so that the maximum number of processes is reached, people will # experience greater latency times. As these processes are implemented in # Erlang, and therefore not related to the operating system processes, you do # not have to worry about allowing a huge number of them. # # Default: 250000 # Maximum: 268435456 # #ERL_PROCESSES=250000 #. #' ERL_MAX_ETS_TABLES: Maximum number of ETS and Mnesia tables # # The number of concurrent ETS and Mnesia tables is limited. When the limit is # reached, errors will appear in the logs: # ** Too many db tables ** # You can safely increase this limit when starting ejabberd. It impacts memory # consumption but the difference will be quite small. # # Default: 1400 # #ERL_MAX_ETS_TABLES=1400 #. #' ERL_OPTIONS: Additional Erlang options # # The next variable allows to specify additional options passed to erlang while # starting ejabberd. Some useful options are -noshell, -detached, -heart. When # ejabberd is started from an init.d script options -noshell and -detached are # added implicitly. See erl(1) for more info. # # It might be useful to add "-pa /usr/local/lib/ejabberd/ebin" if you # want to add local modules in this path. # # Default: "" # #ERL_OPTIONS="" #. #' ERLANG_NODE: Erlang node name # # The next variable allows to explicitly specify erlang node for ejabberd # It can be given in different formats: # ERLANG_NODE=ejabberd # Lets erlang add hostname to the node (ejabberd uses short name in this case) # ERLANG_NODE=ejabberd@hostname # Erlang uses node name as is (so make sure that hostname is a real # machine hostname or you'll not be able to control ejabberd) # ERLANG_NODE=ejabberd@hostname.domainname # The same as previous, but erlang will use long hostname # (see erl (1) manual for details) # # Default: ejabberd@localhost # #ERLANG_NODE=ejabberd@localhost #. #' EJABBERD_PID_PATH: ejabberd PID file # # Indicate the full path to the ejabberd Process identifier (PID) file. # If this variable is defined, ejabberd writes the PID file when starts, # and deletes it when stops. # Remember to create the directory and grant write permission to ejabberd. # # Default: don't write PID file # #EJABBERD_PID_PATH=/var/run/ejabberd/ejabberd.pid #. #' # vim: foldmarker=#',#. foldmethod=marker: ejabberd-2.1.11/src/stringprep/0000775000000000000000000000000012240452476013214 5ustar ejabberd-2.1.11/src/stringprep/Makefile.win320000664000000000000000000000203512240230175015603 0ustar include ..\Makefile.inc EFLAGS = -I .. -pz .. OUTDIR = .. BEAMS = ..\stringprep.beam ..\stringprep_sup.beam SOURCE = stringprep_drv.c AUXIL = uni_data.c uni_norm.c OBJECT = stringprep_drv.o DLL = $(OUTDIR)\stringprep_drv.dll ALL : $(DLL) $(BEAMS) CLEAN : -@erase $(DLL) -@erase $(OUTDIR)\stringprep_drv.exp -@erase $(OUTDIR)\stringprep_drv.lib -@erase $(OBJECT) -@erase $(BEAMS) $(OUTDIR)\stringprep.beam : stringprep.erl erlc -W $(EFLAGS) -o $(OUTDIR) stringprep.erl $(OUTDIR)\stringprep_sup.beam : stringprep_sup.erl erlc -W $(EFLAGS) -o $(OUTDIR) stringprep_sup.erl CC=cl.exe CC_FLAGS=-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -MD -Ox -I"$(ERLANG_DIR)\usr\include" -I"$(EI_DIR)\include" LD=link.exe LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib $(DLL) : $(OBJECT) $(LD) $(LD_FLAGS) -out:$@ $< $(OBJECT) : $(SOURCE) $(AUXIL) $(CC) $(CC_FLAGS) -c -Fo$@ $< ejabberd-2.1.11/src/stringprep/stringprep_drv.c0000664000000000000000000002470612240230175016427 0ustar /* * ejabberd, Copyright (C) 2002-2012 ProcessOne * * 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., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * */ #include #include #include #include #include "uni_data.c" #include "uni_norm.c" #define NAMEPREP_COMMAND 1 #define NODEPREP_COMMAND 2 #define RESOURCEPREP_COMMAND 3 /* * R15B changed several driver callbacks to use ErlDrvSizeT and * ErlDrvSSizeT typedefs instead of int. * This provides missing typedefs on older OTP versions. */ #if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 typedef int ErlDrvSizeT; typedef int ErlDrvSSizeT; #endif typedef struct { ErlDrvPort port; } stringprep_data; static ErlDrvData stringprep_erl_start(ErlDrvPort port, char *buff) { stringprep_data* d = (stringprep_data*)driver_alloc(sizeof(stringprep_data)); d->port = port; //set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); return (ErlDrvData)d; } static void stringprep_erl_stop(ErlDrvData handle) { driver_free((char*)handle); } /* Hangul constants */ #define SBase 0xAC00 #define LBase 0x1100 #define VBase 0x1161 #define TBase 0x11A7 #define LCount 19 #define VCount 21 #define TCount 28 #define NCount (VCount * TCount) #define SCount (LCount * NCount) /* * "canonical_ordering" and "compose" functions are based on nfkc.c from Gnome * library */ static void canonical_ordering(int *str, int len) { int i, j, t; int last, next; last = GetUniCharCClass(str[0]); for (i = 0; i < len - 1; i++) { next = GetUniCharCClass(str[i + 1]); if (next != 0 && last > next) { for (j = i; j >= 0; j--) { if (GetUniCharCClass(str[j]) <= next) break; t = str[j + 1]; str[j + 1] = str[j]; str[j] = t; } next = last; } last = next; } } static int compose(int ch1, int ch2) { int info1, info2; if (LBase <= ch1 && ch1 < LBase + LCount && VBase <= ch2 && ch2 < VBase + VCount) { return SBase + ((ch1 - LBase) * VCount + (ch2 - VBase)) * TCount; } if (SBase <= ch1 && ch1 < SBase + SCount && ((ch1 - SBase) % TCount) == 0 && TBase <= ch2 && ch2 < TBase + TCount) { return ch1 + ch2 - TBase; } info1 = GetUniCharCompInfo(ch1); if (info1 != -1 && info1 & CompSingleMask) { if (!(info1 & CompSecondMask) && ch2 == compFirstList[info1 & CompMask][0]) { return compFirstList[info1 & CompMask][1]; } else return 0; } info2 = GetUniCharCompInfo(ch2); if (info2 != -1 && info2 & CompSingleMask) { if ((info2 & CompSecondMask) && ch1 == compSecondList[info2 & CompMask][0]) { return compSecondList[info2 & CompMask][1]; } else return 0; } if (info1 != -1 && info2 != -1 && !(info1 & CompSecondMask) && (info2 & CompSecondMask)) return compBothList[info1][info2 & CompMask]; else return 0; } #define ADD_UCHAR(ruc) \ if (ruc <= 0x7F) { \ if (pos >= size) { \ size = 2*size + 1; \ rstring = driver_realloc(rstring, size); \ } \ rstring[pos] = (char) ruc; \ pos++; \ } else if (ruc <= 0x7FF) { \ if (pos + 1 >= size) { \ size = 2*size + 2; \ rstring = driver_realloc(rstring, size); \ } \ rstring[pos] = (char) ((ruc >> 6) | 0xC0); \ rstring[pos+1] = (char) ((ruc | 0x80) & 0xBF); \ pos += 2; \ } else if (ruc <= 0xFFFF) { \ if (pos + 2 >= size) { \ size = 2*size + 3; \ rstring = driver_realloc(rstring, size); \ } \ rstring[pos] = (char) ((ruc >> 12) | 0xE0); \ rstring[pos+1] = (char) (((ruc >> 6) | 0x80) & 0xBF); \ rstring[pos+2] = (char) ((ruc | 0x80) & 0xBF); \ pos += 3; \ } else if (ruc <= 0x1FFFFF) { \ if (pos + 3 >= size) { \ size = 2*size + 4; \ rstring = driver_realloc(rstring, size); \ } \ rstring[pos] = (char) ((ruc >> 18) | 0xF0); \ rstring[pos+1] = (char) (((ruc >> 12) | 0x80) & 0xBF); \ rstring[pos+2] = (char) (((ruc >> 6) | 0x80) & 0xBF); \ rstring[pos+3] = (char) ((ruc | 0x80) & 0xBF); \ pos += 4; \ } #define ADD_UCHAR32(str, pos, len, ch) \ if (pos >= len) { \ len = 2*len + 1; \ str = driver_realloc(str, len * sizeof(int)); \ } \ str[pos] = ch; \ pos++; #define ADD_DECOMP(ruc) \ info = GetUniCharDecompInfo(ruc); \ if (info >= 0) { \ decomp_len = GetDecompLen(info); \ decomp_shift = GetDecompShift(info); \ for (j = 0; j < decomp_len; j++) { \ ADD_UCHAR32(str32, str32pos, str32len, \ decompList[decomp_shift + j]); \ } \ } else { \ ADD_UCHAR32(str32, str32pos, str32len, ruc); \ } static ErlDrvSSizeT stringprep_erl_control(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { int i, j, pos=1; unsigned char c; int bad = 0; int uc = 0, ruc; int size; int info; int prohibit = 0, tolower = 0; char *rstring; int *mc; int *str32; int str32len, str32pos = 0; int decomp_len, decomp_shift; int comp_pos, comp_starter_pos; int cclass_prev, cclass2; int ch1, ch2; int first_ral, last_ral, have_ral, have_l; size = len + 1; rstring = driver_alloc(size); rstring[0] = 0; str32len = len + 1; str32 = driver_alloc(str32len * sizeof(int)); switch (command) { case 0: prohibit = ACMask; tolower = 1; break; case NAMEPREP_COMMAND: prohibit = ACMask; tolower = 1; break; case NODEPREP_COMMAND: prohibit = ACMask | C11Mask | C21Mask | XNPMask; tolower = 1; break; case RESOURCEPREP_COMMAND: prohibit = ACMask | C21Mask; tolower = 0; break; } for (i = 0; i < len; i++) { c = buf[i]; if (c < 0x80) { uc = c; } else if (c < 0xC0) { bad = 1; } else if (c < 0xE0) { if (i+1 < len && (buf[i+1] & 0xC0) == 0x80) { uc = ((c & 0x1F) << 6) | (buf[i+1] & 0x3F); i++; } else { bad = 1; } } else if (c < 0xF0) { if (i+2 < len && (buf[i+1] & 0xC0) == 0x80 && (buf[i+2] & 0xC0) == 0x80) { uc = ((c & 0x0F) << 12) | ((buf[i+1] & 0x3F) << 6) | (buf[i+2] & 0x3F); i += 2; } else { bad = 1; } } else if (c < 0xF8) { if (i+3 < len && (buf[i+1] & 0xC0) == 0x80 && (buf[i+2] & 0xC0) == 0x80 && (buf[i+3] & 0xC0) == 0x80) { uc = ((c & 0x07) << 18) | ((buf[i+1] & 0x3F) << 12) | ((buf[i+2] & 0x3F) << 6) | (buf[i+3] & 0x3F); i += 3; if (uc > 0x10FFFF) bad = 1; } else { bad = 1; } } else { bad = 1; } if (bad) { *rbuf = rstring; driver_free(str32); return 1; } info = GetUniCharInfo(uc); if (!(info & B1Mask)) { if (tolower) { if (!(info & MCMask)) { ruc = uc + GetDelta(info); ADD_DECOMP(ruc); } else { mc = GetMC(info); for (j = 1; j <= mc[0]; j++) { ruc = mc[j]; ADD_DECOMP(ruc); } } } else { ruc = uc; ADD_DECOMP(ruc); } } } if (str32pos == 0) { rstring[0] = 1; *rbuf = rstring; driver_free(str32); return 1; } canonical_ordering(str32, str32pos); comp_pos = 1; comp_starter_pos = 0; ch1 = str32[0]; cclass_prev = GetUniCharCClass(ch1); for (i = 1; i < str32pos; i++) { ch2 = str32[i]; cclass2 = GetUniCharCClass(ch2); if ((cclass_prev == 0 || cclass2 > cclass_prev) && (ruc = compose(ch1, ch2))) { ch1 = ruc; } else { if (cclass2 == 0) { str32[comp_starter_pos] = ch1; comp_starter_pos = comp_pos++; ch1 = ch2; cclass_prev = 0; } else { str32[comp_pos++] = ch2; cclass_prev = cclass2; } } } str32[comp_starter_pos] = ch1; str32pos = comp_pos; last_ral = have_ral = have_l = 0; info = GetUniCharInfo(str32[0]); first_ral = info & D1Mask; for (i = 0; i < str32pos; i++) { ruc = str32[i]; info = GetUniCharInfo(ruc); if (info & prohibit) { *rbuf = rstring; driver_free(str32); return 1; } last_ral = info & D1Mask; have_ral = have_ral || last_ral; have_l |= info & D2Mask; ADD_UCHAR(ruc); } if (have_ral && (!first_ral || !last_ral || have_l)) { *rbuf = rstring; driver_free(str32); return 1; } rstring[0] = 1; *rbuf = rstring; driver_free(str32); return pos; } ErlDrvEntry stringprep_driver_entry = { NULL, /* F_PTR init, N/A */ stringprep_erl_start, /* L_PTR start, called when port is opened */ stringprep_erl_stop, /* F_PTR stop, called when port is closed */ NULL, /* F_PTR output, called when erlang has sent */ NULL, /* F_PTR ready_input, called when input descriptor ready */ NULL, /* F_PTR ready_output, called when output descriptor ready */ "stringprep_drv", /* char *driver_name, the argument to open_port */ NULL, /* F_PTR finish, called when unloaded */ NULL, /* handle */ stringprep_erl_control, /* F_PTR control, port_command callback */ NULL, /* F_PTR timeout, reserved */ NULL, /* F_PTR outputv, reserved */ /* Added in Erlang/OTP R15B: */ NULL, /* ready_async */ NULL, /* flush */ NULL, /* call */ NULL, /* event */ ERL_DRV_EXTENDED_MARKER, /* extended_marker */ ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ 0, /* driver_flags */ NULL, /* handle2 */ NULL, /* process_exit */ NULL /* stop_select */ }; DRIVER_INIT(stringprep_erl) /* must match name in driver_entry */ { return &stringprep_driver_entry; } ejabberd-2.1.11/src/stringprep/uni_norm.c0000664000000000000000000064112112240230175015201 0ustar /* * uni_norm.c -- * * Declarations of Unicode character information tables. This file is * automatically generated by the uni_parse2.tcl script. Do not * modify this file by hand. * * Copyright (c) 1998 by Scriptics Corporation. * All rights reserved. * * Modified for ejabberd by Alexey Shchepin * * RCS: @(#) $Id$ */ /* * A 16-bit Unicode character is split into two parts in order to index * into the following tables. The lower CCLASS_OFFSET_BITS comprise an offset * into a page of characters. The upper bits comprise the page number. */ #define CCLASS_OFFSET_BITS 8 /* * The pageMap is indexed by page number and returns an alternate page number * that identifies a unique page of characters. Many Unicode characters map * to the same alternate page number. */ static unsigned char cclassPageMap[] = { 0, 0, 0, 1, 2, 3, 4, 5, 0, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0, 14, 15, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 19, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 }; /* * The cclassGroupMap is indexed by combining the alternate page number with * the page offset and returns a combining class number. */ static unsigned char cclassGroupMap[] = { 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, 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, 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, 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, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, 220, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 1, 1, 1, 1, 1, 220, 220, 220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 240, 230, 220, 220, 220, 230, 230, 230, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 234, 233, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 230, 230, 230, 230, 220, 230, 230, 230, 222, 220, 230, 230, 230, 230, 230, 230, 0, 220, 220, 220, 220, 220, 230, 230, 220, 230, 230, 222, 228, 230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 20, 21, 22, 0, 23, 0, 24, 25, 0, 230, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34, 230, 230, 220, 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, 35, 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, 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, 230, 230, 230, 230, 230, 230, 230, 0, 0, 230, 230, 230, 230, 220, 230, 0, 0, 230, 230, 0, 220, 230, 230, 220, 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, 36, 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, 230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220, 220, 230, 220, 230, 230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230, 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, 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, 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, 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 230, 220, 230, 230, 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, 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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, 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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, 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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, 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, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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, 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, 0, 9, 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, 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, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 91, 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, 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, 9, 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, 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, 0, 9, 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, 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, 9, 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, 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, 103, 103, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 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, 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, 118, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 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, 220, 0, 220, 0, 216, 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, 129, 130, 0, 132, 0, 0, 0, 0, 0, 130, 130, 130, 130, 0, 0, 130, 0, 230, 230, 9, 0, 230, 230, 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, 220, 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, 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, 7, 0, 9, 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, 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, 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, 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, 9, 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, 9, 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, 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, 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, 9, 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, 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, 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, 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, 228, 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, 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, 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, 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, 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, 230, 230, 1, 1, 230, 230, 230, 230, 1, 1, 1, 230, 230, 0, 0, 0, 0, 230, 0, 0, 0, 1, 1, 230, 220, 230, 1, 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, 218, 228, 232, 222, 224, 224, 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, 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, 8, 8, 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, 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, 0, 0, 0, 0, 0, 26, 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, 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, 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, 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, 0, 0, 0, 0, 0, 230, 230, 230, 230, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 216, 216, 1, 1, 1, 0, 0, 0, 226, 216, 216, 216, 216, 216, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220, 220, 220, 220, 0, 0, 230, 230, 230, 230, 230, 220, 220, 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, 230, 230, 230, 230, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #define GetUniCharCClass(ch) (cclassGroupMap[(cclassPageMap[(((int)(ch)) & 0x1fffff) >> CCLASS_OFFSET_BITS] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))]) #define DECOMP_OFFSET_BITS 8 /* * The pageMap is indexed by page number and returns an alternate page number * that identifies a unique page of characters. Many Unicode characters map * to the same alternate page number. */ static unsigned char decompPageMap[] = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 16, 17, 18, 19, 20, 21, 22, 7, 7, 7, 7, 7, 23, 7, 7, 7, 24, 25, 26, 27, 28, 29, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 37, 7, 7, 38, 39, 40, 41, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 42, 43, 44, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 }; /* * The decompGroupMap is indexed by combining the alternate page number with * the page offset and returns a group number that identifies a length and * shift of decomposition sequence in decompList */ static int decompGroupMap[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65536, -1, -1, -1, -1, -1, -1, -1, 131073, -1, 65539, -1, -1, -1, -1, 131076, -1, -1, 65542, 65543, 131080, 65546, -1, -1, 131083, 65549, 65550, -1, 196623, 196626, 196629, -1, 131096, 131098, 131100, 131102, 131104, 131106, -1, 131108, 131110, 131112, 131114, 131116, 131118, 131120, 131122, 131124, -1, 131126, 131128, 131130, 131132, 131134, 131136, -1, -1, 131138, 131140, 131142, 131144, 131146, -1, -1, 131148, 131150, 131152, 131154, 131156, 131158, -1, 131160, 131162, 131164, 131166, 131168, 131170, 131172, 131174, 131176, -1, 131178, 131180, 131182, 131184, 131186, 131188, -1, -1, 131190, 131192, 131194, 131196, 131198, -1, 131200, 131202, 131204, 131206, 131208, 131210, 131212, 131214, 131216, 131218, 131220, 131222, 131224, 131226, 131228, 131230, 131232, -1, -1, 131234, 131236, 131238, 131240, 131242, 131244, 131246, 131248, 131250, 131252, 131254, 131256, 131258, 131260, 131262, 131264, 131266, 131268, 131270, 131272, -1, -1, 131274, 131276, 131278, 131280, 131282, 131284, 131286, 131288, 131290, -1, 131292, 131294, 131296, 131298, 131300, 131302, -1, 131304, 131306, 131308, 131310, 131312, 131314, 131316, 131318, -1, -1, 131320, 131322, 131324, 131326, 131328, 131330, 131332, -1, -1, 131334, 131336, 131338, 131340, 131342, 131344, -1, -1, 131346, 131348, 131350, 131352, 131354, 131356, 131358, 131360, 131362, 131364, 131366, 131368, 131370, 131372, 131374, 131376, 131378, 131380, -1, -1, 131382, 131384, 131386, 131388, 131390, 131392, 131394, 131396, 131398, 131400, 131402, 131404, 131406, 131408, 131410, 131412, 131414, 131416, 131418, 131420, 131422, 131424, 131426, 65892, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131429, 131431, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131433, 131435, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 196973, 196976, 196979, 131446, 131448, 131450, 131452, 131454, 131456, 131458, 131460, 131462, 131464, 131466, 131468, 131470, 131472, 197010, 197013, 197016, 197019, 197022, 197025, 197028, 197031, -1, 197034, 197037, 197040, 197043, 131510, 131512, -1, -1, 131514, 131516, 131518, 131520, 131522, 131524, 197062, 197065, 131532, 131534, 131536, 131538, 131540, 131542, 131544, 131546, -1, -1, 131548, 131550, 197088, 197091, 131558, 131560, 131562, 131564, 131566, 131568, 131570, 131572, 131574, 131576, 131578, 131580, 131582, 131584, 131586, 131588, 131590, 131592, 131594, 131596, 131598, 131600, 131602, 131604, 131606, 131608, 131610, 131612, 131614, 131616, 131618, 131620, -1, -1, 131622, 131624, -1, -1, -1, -1, -1, -1, 131626, 131628, 131630, 131632, 197170, 197173, 197176, 197179, 131646, 131648, 197186, 197189, 131656, 131658, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66124, 66125, 66126, 66127, 66128, 66129, 66130, 66131, 66132, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131669, 131671, 131673, 131675, 131677, 131679, -1, -1, 66145, 66146, 65892, 66147, 66148, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66149, 66150, -1, 66151, 131688, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66154, -1, -1, -1, -1, -1, 131691, -1, -1, -1, 66157, -1, -1, -1, -1, -1, 131080, 197230, 131697, 66163, 131700, 131702, 131704, -1, 131706, -1, 131708, 131710, 197248, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131715, 131717, 131719, 131721, 131723, 131725, 197263, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131730, 131732, 131734, 131736, 131738, -1, 66204, 66205, 66206, 131708, 131717, 66207, 66208, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66209, 66210, 66211, -1, 66212, 66213, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131750, 131752, -1, 131754, -1, -1, -1, 131756, -1, -1, -1, -1, 131758, 131760, 131762, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131764, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131766, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131768, 131770, -1, 131772, -1, -1, -1, 131774, -1, -1, -1, -1, 131776, 131778, 131780, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131782, 131784, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131786, 131788, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131790, 131792, 131794, 131796, -1, -1, 131798, 131800, -1, -1, 131802, 131804, 131806, 131808, 131810, 131812, -1, -1, 131814, 131816, 131818, 131820, 131822, 131824, -1, -1, 131826, 131828, 131830, 131832, 131834, 131836, 131838, 131840, 131842, 131844, 131846, 131848, -1, -1, 131850, 131852, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131854, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131856, 131858, 131860, 131862, 131864, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131866, 131868, 131870, 131872, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131874, -1, 131876, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131878, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131880, -1, -1, -1, -1, -1, -1, -1, 131882, -1, -1, 131884, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131886, 131888, 131890, 131892, 131894, 131896, 131898, 131900, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131902, 131904, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131906, 131908, -1, 131910, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131912, -1, -1, 131914, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131916, 131918, 131920, -1, -1, 131922, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131924, -1, -1, 131926, 131928, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131930, 131932, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131934, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131936, 131938, 131940, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131942, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131944, -1, -1, -1, -1, -1, -1, 131946, 131948, -1, 131950, 197488, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131955, 131957, 131959, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131961, -1, 131963, 197501, 131968, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131970, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131972, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131974, 131976, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 66442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131979, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131981, -1, -1, -1, -1, 131983, -1, -1, -1, -1, 131985, -1, -1, -1, -1, 131987, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131989, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131991, -1, 131993, 131995, 197533, 132000, 197538, -1, -1, -1, -1, -1, -1, -1, 132005, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 132007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 132009, -1, -1, -1, -1, 132011, -1, -1, -1, -1, 132013, -1, -1, -1, -1, 132015, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 132017, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 132019, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 132021, 132023, 132025, 132027, 132029, 132031, 132033, 132035, 197573, 197576, 132043, 132045, 132047, 132049, 132051, 132053, 132055, 132057, 132059, 132061, 197599, 197602, 197605, 197608, 132075, 132077, 132079, 132081, 197619, 197622, 132089, 132091, 132093, 132095, 132097, 132099, 132101, 132103, 132105, 132107, 132109, 132111, 132113, 132115, 132117, 132119, 197657, 197660, 132127, 132129, 132131, 132133, 132135, 132137, 132139, 132141, 197679, 197682, 132149, 132151, 132153, 132155, 132157, 132159, 132161, 132163, 132165, 132167, 132169, 132171, 132173, 132175, 132177, 132179, 132181, 132183, 197721, 197724, 197727, 197730, 197733, 197736, 197739, 197742, 132209, 132211, 132213, 132215, 132217, 132219, 132221, 132223, 197761, 197764, 132231, 132233, 132235, 132237, 132239, 132241, 197779, 197782, 197785, 197788, 197791, 197794, 132261, 132263, 132265, 132267, 132269, 132271, 132273, 132275, 132277, 132279, 132281, 132283, 132285, 132287, 197825, 197828, 197831, 197834, 132301, 132303, 132305, 132307, 132309, 132311, 132313, 132315, 132317, 132319, 132321, 132323, 132325, 132327, 132329, 132331, 132333, 132335, 132337, 132339, 132341, 132343, 132345, 132347, 132349, 132351, 132353, 132355, 132357, 132359, 132361, 132237, -1, -1, -1, -1, 132363, 132365, 132367, 132369, 197907, 197910, 197913, 197916, 197919, 197922, 197925, 197928, 197931, 197934, 197937, 197940, 197943, 197946, 197949, 197952, 197955, 197958, 197961, 197964, 132431, 132433, 132435, 132437, 132439, 132441, 197979, 197982, 197985, 197988, 197991, 197994, 197997, 198000, 198003, 198006, 132473, 132475, 132477, 132479, 132481, 132483, 132485, 132487, 198025, 198028, 198031, 198034, 198037, 198040, 198043, 198046, 198049, 198052, 198055, 198058, 198061, 198064, 198067, 198070, 198073, 198076, 198079, 198082, 132549, 132551, 132553, 132555, 198093, 198096, 198099, 198102, 198105, 198108, 198111, 198114, 198117, 198120, 132587, 132589, 132591, 132593, 132595, 132597, 132599, 132601, -1, -1, -1, -1, -1, -1, 132603, 132605, 198143, 198146, 198149, 198152, 198155, 198158, 132625, 132627, 198165, 198168, 198171, 198174, 198177, 198180, 132647, 132649, 198187, 198190, 198193, 198196, -1, -1, 132663, 132665, 198203, 198206, 198209, 198212, -1, -1, 132679, 132681, 198219, 198222, 198225, 198228, 198231, 198234, 132701, 132703, 198241, 198244, 198247, 198250, 198253, 198256, 132723, 132725, 198263, 198266, 198269, 198272, 198275, 198278, 132745, 132747, 198285, 198288, 198291, 198294, 198297, 198300, 132767, 132769, 198307, 198310, 198313, 198316, -1, -1, 132783, 132785, 198323, 198326, 198329, 198332, -1, -1, 132799, 132801, 198339, 198342, 198345, 198348, 198351, 198354, -1, 132821, -1, 198359, -1, 198362, -1, 198365, 132832, 132834, 198372, 198375, 198378, 198381, 198384, 198387, 132854, 132856, 198394, 198397, 198400, 198403, 198406, 198409, 132876, 131719, 132878, 131721, 132880, 131723, 132882, 131725, 132884, 131734, 132886, 131736, 132888, 131738, -1, -1, 198426, 198429, 263968, 263972, 263976, 263980, 263984, 263988, 198456, 198459, 263998, 264002, 264006, 264010, 264014, 264018, 198486, 198489, 264028, 264032, 264036, 264040, 264044, 264048, 198516, 198519, 264058, 264062, 264066, 264070, 264074, 264078, 198546, 198549, 264088, 264092, 264096, 264100, 264104, 264108, 198576, 198579, 264118, 264122, 264126, 264130, 264134, 264138, 133070, 133072, 198610, 133077, 198615, -1, 133082, 198620, 133087, 133089, 133091, 131697, 133093, 133095, 67561, 133095, 133098, 198636, 198639, 133106, 198644, -1, 133111, 198649, 133116, 131700, 133118, 131702, 133120, 198658, 198661, 198664, 133131, 133133, 198671, 197248, -1, -1, 133138, 198676, 133143, 133145, 133147, 131704, -1, 198685, 198688, 198691, 133158, 133160, 198698, 197263, 133165, 133167, 133169, 198707, 133174, 133176, 133178, 131708, 133180, 198718, 197230, 67649, -1, -1, 198722, 133189, 198727, -1, 133194, 198732, 133199, 131706, 133201, 131710, 133203, 131080, 133205, -1, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, 65536, -1, -1, -1, -1, -1, -1, 67671, -1, -1, -1, -1, -1, 133208, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67674, 133211, 198749, -1, -1, -1, -1, -1, -1, -1, -1, 65536, -1, -1, -1, 133216, 198754, -1, 133221, 198759, -1, -1, -1, -1, 133226, -1, 133228, -1, -1, -1, -1, -1, -1, -1, -1, 133230, 133232, 133234, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 264308, -1, -1, -1, -1, -1, -1, -1, 65536, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67704, 67705, -1, -1, 67706, 67707, 67708, 67709, 67710, 67711, 67712, 67713, 67714, 67715, 67716, 67717, 67704, 65549, 65542, 65543, 67706, 67707, 67708, 67709, 67710, 67711, 67712, 67713, 67714, 67715, 67716, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133254, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 198792, 198795, 67726, 133263, -1, 198801, 198804, 67735, -1, 133272, 67738, 67739, 67739, 67739, 66124, 67740, 67741, 67741, 67742, 66146, -1, 67743, 133280, -1, -1, 67746, 67747, 67748, 67748, 67748, -1, -1, 133285, 198823, 133290, -1, 67756, -1, 67757, -1, 67756, -1, 67758, 131106, 67759, 67726, -1, 67760, 67761, 67762, -1, 67763, 65550, 67764, 67765, 67766, 67767, 67705, -1, -1, -1, 67768, 67769, 67770, 67771, -1, -1, -1, -1, 67772, 67773, 67760, 67705, 66126, -1, -1, -1, -1, -1, -1, -1, -1, -1, 198846, 198849, 198852, 198855, 198858, 198861, 198864, 198867, 198870, 198873, 198876, 198879, 133346, 67741, 133348, 198886, 133353, 67819, 133356, 198894, 264433, 133365, 67831, 133368, 198906, 67742, 67726, 67772, 67763, 67705, 133373, 198911, 133378, 67844, 133381, 198919, 264458, 133390, 66147, 133392, 198930, 66146, 67861, 67773, 67862, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133399, 133401, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133403, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133405, 133407, 133409, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133411, -1, -1, -1, -1, 133413, -1, -1, 133415, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133417, -1, 133419, -1, -1, -1, -1, -1, 133421, 198959, -1, 133426, 198964, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133431, -1, -1, 133433, -1, -1, 133435, -1, 133437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133439, -1, 133441, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133443, 133445, 133447, 133449, 133451, -1, -1, 133453, 133455, -1, -1, 133457, 133459, -1, -1, -1, -1, -1, -1, 133461, 133463, -1, -1, 133465, 133467, -1, -1, 133469, 133471, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133473, 133475, 133477, 133479, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133481, 133483, 133485, 133487, -1, -1, -1, -1, -1, -1, 133489, 133491, 133493, 133495, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 67961, 67962, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65549, 65542, 65543, 67706, 67707, 67708, 67709, 67710, 67711, 133499, 133501, 133503, 133505, 133507, 133509, 133511, 133513, 133515, 133517, 133519, 199057, 199060, 199063, 199066, 199069, 199072, 199075, 199078, 199081, 264620, 264624, 264628, 264632, 264636, 264640, 264644, 264648, 264652, 264656, 264660, 133592, 133594, 133596, 133598, 133600, 133602, 133604, 133606, 133608, 199146, 199149, 199152, 199155, 199158, 199161, 199164, 199167, 199170, 199173, 199176, 199179, 199182, 199185, 199188, 199191, 199194, 199197, 199200, 199203, 199206, 199209, 199212, 199215, 199218, 199221, 199224, 199227, 199230, 199233, 199236, 199239, 199242, 199245, 199248, 199251, 199254, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 67704, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 264810, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 199278, 133745, 199283, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133750, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 68216, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 68217, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 68218, 68219, 68220, 68221, 68222, 68223, 68224, 68225, 68226, 68227, 68228, 68229, 68230, 68231, 68232, 68233, 68234, 68235, 68236, 68237, 68238, 68239, 68240, 68241, 68242, 68243, 68244, 68245, 68246, 68247, 68248, 68249, 68250, 68251, 68252, 68253, 68254, 68255, 68256, 68257, 68258, 68259, 68260, 68261, 68262, 68263, 68264, 68265, 68266, 68267, 68268, 68269, 68270, 68271, 68272, 68273, 68274, 68275, 68276, 68277, 68278, 68279, 68280, 68281, 68282, 68283, 68284, 68285, 68286, 68287, 68288, 68289, 68290, 68291, 68292, 68293, 68294, 68295, 68296, 68297, 68298, 68299, 68300, 68301, 68302, 68303, 68304, 68305, 68306, 68307, 68308, 68309, 68310, 68311, 68312, 68313, 68314, 68315, 68316, 68317, 68318, 68319, 68320, 68321, 68322, 68323, 68324, 68325, 68326, 68327, 68328, 68329, 68330, 68331, 68332, 68333, 68334, 68335, 68336, 68337, 68338, 68339, 68340, 68341, 68342, 68343, 68344, 68345, 68346, 68347, 68348, 68349, 68350, 68351, 68352, 68353, 68354, 68355, 68356, 68357, 68358, 68359, 68360, 68361, 68362, 68363, 68364, 68365, 68366, 68367, 68368, 68369, 68370, 68371, 68372, 68373, 68374, 68375, 68376, 68377, 68378, 68379, 68380, 68381, 68382, 68383, 68384, 68385, 68386, 68387, 68388, 68389, 68390, 68391, 68392, 68393, 68394, 68395, 68396, 68397, 68398, 68399, 68400, 68401, 68402, 68403, 68404, 68405, 68406, 68407, 68408, 68409, 68410, 68411, 68412, 68413, 68414, 68415, 68416, 68417, 68418, 68419, 68420, 68421, 68422, 68423, 68424, 68425, 68426, 68427, 68428, 68429, 68430, 68431, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65536, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 68432, -1, 68241, 68433, 68434, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133971, -1, 133973, -1, 133975, -1, 133977, -1, 133979, -1, 133981, -1, 133983, -1, 133985, -1, 133987, -1, 133989, -1, 133991, -1, 133993, -1, -1, 133995, -1, 133997, -1, 133999, -1, -1, -1, -1, -1, -1, 134001, 134003, -1, 134005, 134007, -1, 134009, 134011, -1, 134013, 134015, -1, 134017, 134019, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 134021, -1, -1, -1, -1, -1, -1, 134023, 134025, -1, 134027, 134029, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 134031, -1, 134033, -1, 134035, -1, 134037, -1, 134039, -1, 134041, -1, 134043, -1, 134045, -1, 134047, -1, 134049, -1, 134051, -1, 134053, -1, -1, 134055, -1, 134057, -1, 134059, -1, -1, -1, -1, -1, -1, 134061, 134063, -1, 134065, 134067, -1, 134069, 134071, -1, 134073, 134075, -1, 134077, 134079, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 134081, -1, -1, 134083, 134085, 134087, 134089, -1, -1, -1, 134091, 134093, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 68559, 68560, 68561, 68562, 68563, 68564, 68565, 68566, 68567, 68568, 68569, 68570, 68571, 68572, 68573, 68574, 68575, 68576, 68577, 68578, 68579, 68580, 68581, 68582, 68583, 68584, 68585, 68586, 68587, 68588, 68589, 68590, 68591, 68592, 68593, 68594, 68595, 68596, 68597, 68598, 68599, 68600, 68601, 68602, 68603, 68604, 68605, 68606, 68607, 68608, 68609, 68610, 68611, 68612, 68613, 68614, 68615, 68616, 68617, 68618, 68619, 68620, 68621, 68622, 68623, 68624, 68625, 68626, 68627, 68628, 68629, 68630, 68631, 68632, 68633, 68634, 68635, 68636, 68637, 68638, 68639, 68640, 68641, 68642, 68643, 68644, 68645, 68646, 68647, 68648, 68649, 68650, 68651, 68652, -1, -1, -1, 68218, 68224, 68653, 68654, 68655, 68656, 68657, 68658, 68222, 68659, 68660, 68661, 68662, 68226, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 199735, 199738, 199741, 199744, 199747, 199750, 199753, 199756, 199759, 199762, 199765, 199768, 199771, 199774, 265313, 265317, 265321, 265325, 265329, 265333, 265337, 265341, 265345, 265349, 265353, 265357, 265361, 265365, 265369, -1, -1, -1, 199837, 199840, 199843, 199846, 199849, 199852, 199855, 199858, 199861, 199864, 199867, 199870, 199873, 199876, 199879, 199882, 199885, 199888, 199891, 199894, 199897, 199900, 199903, 199906, 199909, 199912, 199915, 199918, 199921, 199924, 199927, 199930, 199933, 199936, 199939, 199942, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 134409, 134411, 134413, 134415, 134417, 134419, 134421, 134423, 134425, 134427, 134429, 134431, 134433, 134435, 134437, 68559, 68562, 68565, 68567, 68575, 68576, 68579, 68581, 68582, 68584, 68585, 68586, 68587, 68588, 134439, 134441, 134443, 134445, 134447, 134449, 134451, 134453, 134455, 134457, 134459, 134461, 134463, 134465, -1, -1, -1, -1, 68218, 68224, 68653, 68654, 68931, 68932, 68933, 68229, 68934, 68241, 68291, 68303, 68302, 68292, 68384, 68249, 68289, 68935, 68936, 68937, 68938, 68939, 68940, 68941, 68942, 68943, 68944, 68255, 68945, 68946, 68947, 68948, 68949, 68950, 68951, 68952, 68655, 68656, 68657, 68953, 68954, 68955, 68956, 68957, 68958, 68959, 68960, 68961, 68962, 134499, 134501, 134503, 134505, 134507, 134509, 134511, 134513, 134515, 134517, 134519, 134521, 134523, 134525, 134527, 134529, 134531, 134533, 134535, 134537, 134539, 134541, 134543, 134545, 200083, 200086, 200089, -1, -1, -1, -1, 69020, 69021, 69022, 69023, 69024, 69025, 69026, 69027, 69028, 69029, 69030, 69031, 69032, 69033, 69034, 69035, 69036, 69037, 69038, 69039, 69040, 69041, 69042, 69043, 69044, 69045, 69046, 69047, 69048, 69049, 69050, 69051, 69052, 69053, 69054, 69055, 69056, 69057, 69058, 69059, 69060, 69061, 69062, 69063, 69064, 69065, 69066, -1, 331211, 265680, 331220, 200153, 331228, 200161, 200164, 396775, 265709, 200177, 200180, 200183, 265722, 265726, 265730, 265734, 265738, 265742, 265746, 396822, 134684, 396830, 396836, 331306, 265775, 396851, 396857, 265791, 200259, 200262, 265801, 265805, 331345, 331350, 200283, 200286, 265825, 200293, 200296, 134763, 134765, 200303, 200306, 396917, 265851, 331391, 396932, 265866, 200334, 200337, 396948, 265882, 396958, 200356, 331431, 200364, 265903, 200371, 265910, 331450, 265919, 331459, 265928, 134860, 331470, 200403, 200406, 265945, 200413, 200416, 200419, 331494, 265963, 134895, 397041, 200439, 331514, 265983, 265987, 200455, 200458, 265997, 134929, 266003, 331543, 134940, 397086, 200484, 134951, 134953, 134955, 134957, 134959, 134961, 134963, 134965, 134967, 134969, 200507, 200510, 200513, 200516, 200519, 200522, 200525, 200528, 200531, 200534, 200537, 200540, 200543, 200546, 200549, 200552, 135019, 135021, 200559, 135026, 135028, -1, -1, -1, -1, 135030, 135032, 135034, 135036, 266110, 135042, 135044, 135046, 135048, 135050, 135052, 135054, 135056, 200594, 266133, 135065, 135067, 135069, 135071, 135073, 135075, 135077, 200615, 200618, 200621, 200624, 135091, 135093, 135095, 135097, 135099, 135101, 135103, 135105, 135107, 135109, 200647, 200650, 135117, 200655, 200658, 200661, 135128, 200666, 200669, 266208, 135140, 200678, 200681, 200684, 200687, 331762, 397303, 135165, 135167, 135169, 135171, 135173, 135175, 135177, 135179, 135181, 135183, 135185, 135187, 135189, 135191, 135193, 135195, 135197, 135199, 266273, 135205, 135207, 135209, 266283, 200751, 135218, 135220, 135222, 135224, 135226, 135228, 135230, 135232, 135234, 135236, 200774, 135241, 135243, 200781, 200784, 135251, 266325, 200793, 135260, 135262, 135264, 135266, -1, -1, 135268, 135270, 135272, 135274, 135276, 135278, 135280, 135282, 135284, 200822, 200825, 200828, 200831, 200834, 200837, 200840, 200843, 200846, 200849, 200852, 200855, 200858, 200861, 200864, 200867, 200870, 200873, 200876, 200879, 200882, 200885, -1, 69816, 69817, 68376, 69818, 69819, 69820, 69821, 68430, 68430, 69822, 68384, 69823, 69824, 69825, 69826, 69827, 69828, 69829, 69830, 69831, 69832, 69833, 69834, 69835, 69836, 69837, 69838, 69839, 69840, 69841, 69842, 69843, 69844, 69845, 69846, 69847, 69848, 69849, 69850, 69851, 69852, 69853, 69854, 69855, 69856, 69857, 69858, 69859, 69860, 69861, 69862, 69863, 68342, 69864, 69865, 69866, 69867, 69868, 69869, 69870, 69871, 69872, 69873, 69874, 68415, 69875, 69876, 69877, 69878, 69879, 69880, 69881, 69882, 69883, 69884, 69885, 69886, 69887, 69888, 69889, 69890, 69891, 69892, 69893, 69894, 69895, 69896, 69897, 69898, 69899, 69900, 69901, 69832, 69902, 69903, 69904, 69905, 69906, 69907, 69908, 69909, 69910, 69911, 69912, 69913, 69914, 69915, 69916, 69917, 69918, 69919, 69920, 69921, 68378, 69922, 69923, 69924, 69925, 69926, 69927, 69928, 69929, 69930, 69931, 69932, 69933, 69934, 69935, 69936, 68255, 69937, 69938, 69939, 69940, 69941, 69942, 69943, 69944, 68236, 69945, 69946, 69947, 69948, 69949, 69950, 69951, 69952, 69953, 69954, 69955, 69956, 69957, 69958, 69959, 69960, 69961, 69962, 69963, 69964, 69965, 69966, 69920, 69967, 69968, 69969, 69970, 69971, 69972, 69973, 69974, 69904, 69975, 69976, 69977, 69978, 69979, 69980, 69981, 69982, 69983, 69984, 69985, 69986, 69987, 69988, 69989, 69990, 69991, 69992, 69993, 69994, 69832, 69995, 69996, 69997, 69998, 68429, 69999, 70000, 70001, 70002, 70003, 70004, 70005, 70006, 70007, 70008, 70009, 70010, 68932, 70011, 70012, 70013, 70014, 70015, 70016, 70017, 70018, 70019, 69906, 70020, 70021, 70022, 70023, 70024, 70025, 70026, 70027, 70028, 70029, 70030, 70031, 70032, 68383, 70033, 70034, 70035, 70036, 70037, 70038, 70039, 70040, 70041, 70042, 70043, 70044, 70045, 68334, 70046, 70047, 70048, 70049, 70050, 70051, 70052, 70053, 70054, 70055, 70056, 70057, 70058, 70059, 70060, 70061, 68361, 70062, 68364, 70063, 70064, 70065, -1, -1, 70066, -1, 70067, -1, -1, 70068, 70069, 70070, 70071, 70072, 70073, 70074, 70075, 70076, 68341, -1, 70077, -1, 70078, -1, -1, 70079, 70080, -1, -1, -1, 70081, 70082, 70083, 70084, -1, -1, 70085, 70086, 70087, 70088, 70089, 70090, 70091, 70092, 70093, 70094, 70095, 70096, 68262, 70097, 70098, 70099, 70100, 70101, 70102, 70103, 70104, 70105, 70106, 70107, 70108, 70109, 70110, 70111, 68937, 70112, 70113, 70114, 70115, 68941, 70116, 70117, 70118, 70119, 70120, 69956, 70121, 70122, 70123, 70124, 70125, 70126, 70126, 70127, 70128, 70129, 70130, 70131, 70132, 70133, 70134, 70079, 70135, 70136, 70137, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 135674, 135676, 135678, 201216, 201219, 135686, 135686, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 135688, 135690, 135692, 135694, 135696, -1, -1, -1, -1, -1, 135698, -1, 135700, 70166, 67764, 67767, 70167, 70168, 70169, 70170, 70171, 70172, 67712, 135709, 135711, 201249, 201252, 135719, 135721, 135723, 135725, 135727, 135729, 135731, 135733, 135735, -1, 135737, 135739, 135741, 135743, 135745, -1, 135747, -1, 135749, 135751, -1, 135753, 135755, -1, 135757, 135759, 135761, 135763, 135765, 135767, 135769, 135771, 135773, 135775, 70241, 70241, 70242, 70242, 70242, 70242, 70243, 70243, 70243, 70243, 70244, 70244, 70244, 70244, 70245, 70245, 70245, 70245, 70246, 70246, 70246, 70246, 70247, 70247, 70247, 70247, 70248, 70248, 70248, 70248, 70249, 70249, 70249, 70249, 70250, 70250, 70250, 70250, 70251, 70251, 70251, 70251, 70252, 70252, 70252, 70252, 70253, 70253, 70253, 70253, 70254, 70254, 70255, 70255, 70256, 70256, 70257, 70257, 70258, 70258, 70259, 70259, 70260, 70260, 70260, 70260, 70261, 70261, 70261, 70261, 70262, 70262, 70262, 70262, 70263, 70263, 70263, 70263, 70264, 70264, 70265, 70265, 70265, 70265, 131874, 131874, 70266, 70266, 70266, 70266, 70267, 70267, 70267, 70267, 70268, 70268, 131878, 131878, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 70269, 70269, 70269, 70269, 70270, 70270, 70271, 70271, 70272, 70272, 131870, 70273, 70273, 70274, 70274, 70275, 70275, 70276, 70276, 70276, 70276, 70277, 70277, 201350, 201350, 201353, 201353, 201356, 201356, 201359, 201359, 201362, 201362, 201365, 201365, 201368, 201368, 201368, 201371, 201371, 201371, 70302, 70302, 70302, 70302, 201375, 201378, 201381, 201371, 201384, 135851, 135853, 135855, 135857, 135859, 135861, 135863, 135865, 135867, 135869, 135871, 135873, 135875, 135877, 135879, 135881, 135883, 135885, 135887, 135889, 135891, 135893, 135895, 135897, 135899, 135901, 135903, 135905, 135907, 135909, 135911, 135913, 135915, 135917, 135919, 135921, 135923, 135925, 135927, 135929, 135931, 135933, 135935, 135937, 135939, 135941, 135943, 135945, 135947, 135949, 135951, 135953, 135955, 135957, 135959, 135961, 135963, 135965, 135967, 135969, 135971, 135973, 135975, 135977, 135979, 135981, 135983, 135985, 135987, 135989, 135991, 135993, 135995, 135997, 135999, 136001, 136003, 136005, 136007, 136009, 136011, 136013, 136015, 136017, 136019, 136021, 136023, 136025, 136027, 201565, 201568, 201571, 201574, 201577, 201580, 201583, 201586, 201381, 201589, 201371, 201384, 136056, 136058, 135857, 136060, 135859, 135861, 136062, 136064, 135869, 136066, 135871, 135873, 136068, 136070, 135877, 136072, 135879, 135881, 135939, 135941, 135947, 135949, 135951, 135959, 135961, 135963, 135965, 135973, 135975, 135977, 136074, 135985, 136076, 136078, 135997, 136080, 135999, 136001, 136027, 136082, 136084, 136017, 136086, 136019, 136021, 201375, 201378, 201624, 201381, 201627, 135851, 135853, 135855, 135857, 136094, 135863, 135865, 135867, 135869, 136096, 135877, 135883, 135885, 135887, 135889, 135891, 135895, 135897, 135899, 135901, 135903, 135905, 136098, 135907, 135909, 135911, 135913, 135915, 135917, 135921, 135923, 135925, 135927, 135929, 135931, 135933, 135935, 135937, 135943, 135945, 135953, 135955, 135957, 135959, 135961, 135967, 135969, 135971, 135973, 136100, 135979, 135981, 135983, 135985, 135991, 135993, 135995, 135997, 136102, 136003, 136005, 136104, 136011, 136013, 136015, 136017, 136106, 201381, 201627, 135857, 136094, 135869, 136096, 135877, 136108, 135903, 136110, 136112, 136114, 135959, 135961, 135973, 135997, 136102, 136017, 136106, 201652, 201655, 201658, 136125, 136127, 136129, 136131, 136133, 136135, 136137, 136139, 136141, 136143, 136145, 136147, 136149, 136151, 136153, 136155, 136157, 136159, 136161, 136163, 136165, 136167, 136169, 136112, 136171, 136173, 136175, 136177, 136125, 136127, 136129, 136131, 136133, 136135, 136137, 136139, 136141, 136143, 136145, 136147, 136149, 136151, 136153, 136155, 136157, 136159, 136161, 136163, 136165, 136167, 136169, 136112, 136171, 136173, 136175, 136177, 136165, 136167, 136169, 136112, 136110, 136114, 135919, 135897, 135899, 135901, 136165, 136167, 136169, 135919, 135921, 136179, 136179, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 201717, 201720, 201720, 201723, 201726, 201729, 201732, 201735, 201738, 201738, 201741, 201744, 201747, 201750, 201753, 201756, 201756, 201759, 201762, 201762, 201765, 201765, 201768, 201771, 201771, 201774, 201777, 201777, 201780, 201780, 201783, 201786, 201786, 201789, 201789, 201792, 201795, 201798, 201801, 201801, 201804, 201807, 201810, 201813, 201816, 201816, 201819, 201822, 201825, 201828, 201831, 201834, 201834, 201837, 201837, 201840, 201840, 201843, 201846, 201849, 201852, 201855, 201858, 201861, -1, -1, 201864, 201867, 201870, 201873, 201876, 201879, 201879, 201882, 201885, 201888, 201891, 201891, 201894, 201897, 201900, 201903, 201906, 201909, 201912, 201915, 201918, 201921, 201924, 201927, 201930, 201933, 201936, 201939, 201942, 201945, 201948, 201951, 201954, 201957, 201819, 201825, 201960, 201963, 201966, 201969, 201972, 201975, 201972, 201966, 201978, 201981, 201984, 201987, 201990, 201975, 201798, 201768, 201993, 201996, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 201999, 202002, 267541, 267545, 267549, 267553, 267557, 267561, 267565, 202033, 1185076, 529734, 267598, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133211, 70994, 70995, 70996, 70996, 67715, 67716, 70997, 70998, 70999, 71000, 71001, 71002, 71003, 71004, 67961, 67962, 71005, 71006, 71007, 71008, -1, -1, -1, -1, 133228, 133228, 133228, 133228, 70996, 70996, 70996, 71009, 71010, 67674, -1, 66157, 71011, 71012, 71013, 70994, 67715, 67716, 70997, 70998, 70999, 71000, 71014, 71015, 71016, 67712, 71017, 71018, 71019, 67714, -1, 71020, 71021, 71022, 71023, -1, -1, -1, -1, 136560, 136562, 136564, -1, 136566, -1, 136568, 136570, 136572, 136574, 136576, 136578, 136580, 136582, 136584, 136586, 71052, 131856, 131856, 131858, 131858, 131860, 131860, 131862, 131862, 131864, 131864, 131864, 131864, 71053, 71053, 71054, 71054, 71054, 71054, 71055, 71055, 71056, 71056, 71056, 71056, 71057, 71057, 71057, 71057, 71058, 71058, 71058, 71058, 71059, 71059, 71059, 71059, 71060, 71060, 71060, 71060, 71061, 71061, 71062, 71062, 71063, 71063, 71064, 71064, 71065, 71065, 71065, 71065, 71066, 71066, 71066, 71066, 71067, 71067, 71067, 71067, 71068, 71068, 71068, 71068, 71069, 71069, 71069, 71069, 71070, 71070, 71070, 71070, 71071, 71071, 71071, 71071, 71072, 71072, 71072, 71072, 71073, 71073, 71073, 71073, 71074, 71074, 71074, 71074, 71075, 71075, 71075, 71075, 71076, 71076, 71076, 71076, 71077, 71077, 71077, 71077, 71078, 71078, 71078, 71078, 71079, 71079, 71079, 71079, 71080, 71080, 70277, 70277, 71081, 71081, 71081, 71081, 202154, 202154, 202157, 202157, 202160, 202160, 136627, 136627, -1, -1, -1, -1, 71013, 71093, 71014, 71021, 71022, 71015, 71094, 67715, 67716, 71016, 67712, 71009, 71017, 67674, 71095, 67704, 65549, 65542, 65543, 67706, 67707, 67708, 67709, 67710, 67711, 71011, 66157, 71018, 67714, 71019, 71012, 71023, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 71096, 71020, 71097, 71098, 70996, 67649, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 70997, 71099, 70998, 71100, 71101, 71102, 71103, 71005, 71006, 71010, 71104, 69066, 71105, 71106, 71107, 71108, 71109, 71110, 71111, 71112, 71113, 71114, 69020, 69021, 69022, 69023, 69024, 69025, 69026, 69027, 69028, 69029, 69030, 69031, 69032, 69033, 69034, 69035, 69036, 69037, 69038, 69039, 69040, 69041, 69042, 69043, 69044, 69045, 69046, 69047, 69048, 69049, 69050, 69051, 69052, 69053, 69054, 69055, 69056, 69057, 69058, 69059, 69060, 69061, 69062, 69063, 71115, 71116, 71117, 68610, 68559, 68560, 68561, 68562, 68563, 68564, 68565, 68566, 68567, 68568, 68569, 68570, 68571, 68572, 68573, 68574, 68575, 68576, 68577, 68578, 68579, 68580, 68581, 68582, 68583, 68584, 68585, 68586, 68587, 68588, -1, -1, -1, 68589, 68590, 68591, 68592, 68593, 68594, -1, -1, 68595, 68596, 68597, 68598, 68599, 68600, -1, -1, 68601, 68602, 68603, 68604, 68605, 68606, -1, -1, 68607, 68608, 68609, -1, -1, -1, 71118, 71119, 71120, 131076, 71121, 71122, 71123, -1, 71124, 71125, 71126, 71127, 71128, 71129, 71130, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 136667, 136669, 202207, 202210, 202213, 202216, 202219, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 136686, 136688, 202226, 202229, 202232, 202235, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, -1, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, -1, 67726, 67772, -1, -1, 68186, -1, -1, 68187, 67758, -1, -1, 67743, 68188, 67746, 67747, -1, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, -1, 68195, -1, 66124, 67705, 66126, 68196, -1, 67862, 67717, -1, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, -1, 67772, 67761, 67762, 68186, -1, -1, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, -1, 68189, 68190, 68191, 67819, 68192, 67831, 68193, -1, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, -1, 67772, 67761, 67762, 68186, -1, 67741, 68187, 67758, 67742, 67763, -1, 68188, -1, -1, -1, 68189, 68190, 68191, 67819, 68192, 67831, 68193, -1, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, 68185, 67759, 67726, 67772, 67761, 67762, 68186, 67739, 67741, 68187, 67758, 67742, 67763, 67743, 68188, 67746, 67747, 67748, 68189, 68190, 68191, 67819, 68192, 67831, 68193, 67756, 65539, 68194, 67861, 67773, 67760, 68195, 67738, 66124, 67705, 66126, 68196, 66146, 67862, 67717, 65550, 68197, 68198, 66127, 65892, 68199, 68200, 67844, 66131, 66147, 66132, 68201, -1, -1, -1, -1, 71166, 71167, 67769, 71168, 71169, 71170, 71171, 66212, 71172, 71173, 71174, 71175, 71176, 71177, 71178, 67770, 71179, 66212, 71180, 71181, 66206, 71182, 71183, 71184, 67757, 71185, 71186, 66204, 67768, 71187, 66213, 71188, 71189, 66205, 67561, 66209, 71190, 65546, 71191, 71192, 71193, 66208, 66210, 66211, 71194, 71195, 71196, 66207, 71197, 71198, 71199, 71200, 66213, 66205, 66209, 66207, 66210, 66208, 71166, 71167, 67769, 71168, 71169, 71170, 71171, 66212, 71172, 71173, 71174, 71175, 71176, 71177, 71178, 67770, 71179, 66212, 71180, 71181, 66206, 71182, 71183, 71184, 67757, 71185, 71186, 66204, 67768, 71187, 66213, 71188, 71189, 66205, 67561, 66209, 71190, 65546, 71191, 71192, 71193, 66208, 66210, 66211, 71194, 71195, 71196, 66207, 71197, 71198, 71199, 71200, 66213, 66205, 66209, 66207, 66210, 66208, 71166, 71167, 67769, 71168, 71169, 71170, 71171, 66212, 71172, 71173, 71174, 71175, 71176, 71177, 71178, 67770, 71179, 66212, 71180, 71181, 66206, 71182, 71183, 71184, 67757, 71185, 71186, 66204, 67768, 71187, 66213, 71188, 71189, 66205, 67561, 66209, 71190, 65546, 71191, 71192, 71193, 66208, 66210, 66211, 71194, 71195, 71196, 66207, 71197, 71198, 71199, 71200, 66213, 66205, 66209, 66207, 66210, 66208, 71166, 71167, 67769, 71168, 71169, 71170, 71171, 66212, 71172, 71173, 71174, 71175, 71176, 71177, 71178, 67770, 71179, 66212, 71180, 71181, 66206, 71182, 71183, 71184, 67757, 71185, 71186, 66204, 67768, 71187, 66213, 71188, 71189, 66205, 67561, 66209, 71190, 65546, 71191, 71192, 71193, 66208, 66210, 66211, 71194, 71195, 71196, 66207, 71197, 71198, 71199, 71200, 66213, 66205, 66209, 66207, 66210, 66208, 71166, 71167, 67769, 71168, 71169, 71170, 71171, 66212, 71172, 71173, 71174, 71175, 71176, 71177, 71178, 67770, 71179, 66212, 71180, 71181, 66206, 71182, 71183, 71184, 67757, 71185, 71186, 66204, 67768, 71187, 66213, 71188, 71189, 66205, 67561, 66209, 71190, 65546, 71191, 71192, 71193, 66208, 66210, 66211, 71194, 71195, 71196, 66207, 71197, 71198, 71199, 71200, 66213, 66205, 66209, 66207, 66210, 66208, -1, -1, -1, -1, 67704, 65549, 65542, 65543, 67706, 67707, 67708, 67709, 67710, 67711, 67704, 65549, 65542, 65543, 67706, 67707, 67708, 67709, 67710, 67711, 67704, 65549, 65542, 65543, 67706, 67707, 67708, 67709, 67710, 67711, 67704, 65549, 65542, 65543, 67706, 67707, 67708, 67709, 67710, 67711, 67704, 65549, 65542, 65543, 67706, 67707, 67708, 67709, 67710, 67711, 71201, 71202, 71203, 71204, 71205, 70085, 71206, 71207, 71208, 71209, 70086, 71210, 71211, 71212, 70087, 71213, 71214, 71215, 71216, 71217, 71218, 71219, 71220, 71221, 71222, 71223, 71224, 71225, 71226, 68234, 71227, 71228, 71229, 71230, 71231, 71232, 71233, 71234, 70088, 70089, 71235, 71236, 71237, 69908, 71238, 70090, 71239, 71240, 71241, 71242, 71242, 71242, 71243, 71244, 71245, 71246, 71247, 71248, 71249, 71250, 71251, 71252, 71253, 71254, 71255, 71256, 71257, 71258, 71259, 71260, 71260, 71261, 71262, 71263, 71264, 71265, 70092, 71266, 71267, 71268, 70054, 71269, 71270, 71271, 71272, 71273, 71274, 71275, 71276, 71277, 71278, 71279, 71280, 71281, 71282, 71283, 71284, 71285, 71286, 71287, 71288, 71289, 71290, 71291, 71292, 71293, 71294, 71294, 71295, 71296, 71297, 69904, 71298, 71299, 71300, 71301, 71302, 68260, 71303, 71304, 68262, 71305, 71306, 71307, 71308, 71309, 71310, 71311, 71312, 71313, 71314, 71315, 71316, 71317, 71318, 71319, 71320, 71321, 71322, 71323, 71324, 71325, 69852, 71326, 68272, 71327, 71327, 71328, 71329, 71329, 71330, 71331, 71332, 71333, 71334, 71335, 71336, 71337, 71338, 71339, 71340, 71341, 71342, 70097, 71343, 71344, 71345, 71346, 71347, 71346, 71348, 70099, 71349, 71350, 71351, 71352, 70100, 69825, 71353, 71354, 71355, 71356, 71357, 71358, 71359, 71360, 71361, 71362, 71363, 71364, 71365, 71366, 71367, 71368, 71369, 71370, 71371, 71372, 71373, 71374, 70101, 71375, 71376, 71377, 71378, 71379, 71380, 70103, 71381, 71382, 71383, 71384, 71385, 71386, 71387, 71388, 69853, 71389, 71390, 71391, 71392, 71393, 71394, 71395, 71396, 71397, 70104, 71398, 71399, 71400, 71401, 71402, 71403, 71404, 71405, 71406, 71407, 71408, 71409, 71410, 71411, 71412, 71413, 71414, 71415, 69921, 71416, 71417, 71418, 71419, 71420, 71421, 71422, 71423, 71424, 71425, 71426, 70105, 70004, 71427, 71428, 71429, 71430, 71431, 71432, 71433, 71434, 71435, 71436, 71437, 71438, 71439, 71440, 71441, 71442, 71443, 71444, 71445, 71446, 71447, 71448, 71449, 71450, 71451, 71452, 71453, 71454, 71455, 71456, 71457, 71458, 71459, 71460, 71461, 71462, 71463, 71464, 71465, 71466, 71467, 71468, 71468, 71469, 71470, 71471, 71472, 71473, 71474, 71475, 71476, 71477, 71478, 69907, 71479, 71480, 71481, 71482, 71483, 71484, 71485, 71486, 71487, 71488, 71489, 71490, 71491, 71492, 71492, 71493, 71494, 71495, 71496, 71497, 71498, 71499, 69870, 71500, 71501, 71502, 70115, 71503, 71504, 70074, 71505, 71506, 70118, 71507, 71508, 71509, 71510, 71510, 71511, 71512, 71513, 71514, 71515, 71516, 71517, 71518, 71519, 71520, 71521, 71522, 71523, 71524, 71525, 71526, 71527, 71528, 71529, 71530, 71531, 71532, 71533, 71534, 71535, 71536, 71537, 70124, 71538, 71539, 71540, 71541, 71542, 71543, 71544, 71545, 71546, 71547, 71548, 71549, 71550, 71551, 71552, 71553, 71328, 71554, 71555, 71556, 71557, 71558, 71559, 71560, 71561, 71562, 71563, 71564, 71565, 69924, 71566, 71567, 71568, 71569, 71570, 71571, 70127, 71572, 71573, 71574, 71575, 71576, 71577, 71578, 71579, 71580, 71581, 71582, 71583, 71584, 71585, 71586, 71587, 71588, 71589, 71590, 71591, 69865, 71592, 71593, 71594, 71595, 71596, 71597, 71598, 71599, 71600, 71601, 71602, 71603, 71604, 71605, 71606, 68362, 71607, 71608, 71609, 71610, 71611, 71612, 71613, 71614, 71615, 71616, 71617, 71618, 71619, 68369, 71620, 71621, 71622, 71623, 71624, 71625, 71626, 71627, 71628, 71629, 71630, 71631, 71632, 71633, 71634, 71635, 71636, 71637, 71638, 71639, 71640, 71641, 71642, 71643, 71644, 71645, 71646, 71647, 71648, 71649, 71650, 71651, 71652, 71653, 71654, 71655, 71656, 71657, 71658, 71659, 71660, 71661, 71662, 71663, 71663, 71664, 71665, 71666, 71667, 71668, 71669, 71670, 71671, 71672, 71673, 71674, 71675, 71676, 71677, 71678, 71679, 71680, 71681, 71682, 71683, 71684, 68417, 71685, 68421, 71686, 71687, 71688, 71689, 68426, 71690, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; /* * List of decomposition sequences */ static int decompList[] = { 32, 32, 776, 97, 32, 772, 50, 51, 32, 769, 956, 32, 807, 49, 111, 49, 8260, 52, 49, 8260, 50, 51, 8260, 52, 65, 768, 65, 769, 65, 770, 65, 771, 65, 776, 65, 778, 67, 807, 69, 768, 69, 769, 69, 770, 69, 776, 73, 768, 73, 769, 73, 770, 73, 776, 78, 771, 79, 768, 79, 769, 79, 770, 79, 771, 79, 776, 85, 768, 85, 769, 85, 770, 85, 776, 89, 769, 97, 768, 97, 769, 97, 770, 97, 771, 97, 776, 97, 778, 99, 807, 101, 768, 101, 769, 101, 770, 101, 776, 105, 768, 105, 769, 105, 770, 105, 776, 110, 771, 111, 768, 111, 769, 111, 770, 111, 771, 111, 776, 117, 768, 117, 769, 117, 770, 117, 776, 121, 769, 121, 776, 65, 772, 97, 772, 65, 774, 97, 774, 65, 808, 97, 808, 67, 769, 99, 769, 67, 770, 99, 770, 67, 775, 99, 775, 67, 780, 99, 780, 68, 780, 100, 780, 69, 772, 101, 772, 69, 774, 101, 774, 69, 775, 101, 775, 69, 808, 101, 808, 69, 780, 101, 780, 71, 770, 103, 770, 71, 774, 103, 774, 71, 775, 103, 775, 71, 807, 103, 807, 72, 770, 104, 770, 73, 771, 105, 771, 73, 772, 105, 772, 73, 774, 105, 774, 73, 808, 105, 808, 73, 775, 73, 74, 105, 106, 74, 770, 106, 770, 75, 807, 107, 807, 76, 769, 108, 769, 76, 807, 108, 807, 76, 780, 108, 780, 76, 183, 108, 183, 78, 769, 110, 769, 78, 807, 110, 807, 78, 780, 110, 780, 700, 110, 79, 772, 111, 772, 79, 774, 111, 774, 79, 779, 111, 779, 82, 769, 114, 769, 82, 807, 114, 807, 82, 780, 114, 780, 83, 769, 115, 769, 83, 770, 115, 770, 83, 807, 115, 807, 83, 780, 115, 780, 84, 807, 116, 807, 84, 780, 116, 780, 85, 771, 117, 771, 85, 772, 117, 772, 85, 774, 117, 774, 85, 778, 117, 778, 85, 779, 117, 779, 85, 808, 117, 808, 87, 770, 119, 770, 89, 770, 121, 770, 89, 776, 90, 769, 122, 769, 90, 775, 122, 775, 90, 780, 122, 780, 115, 79, 795, 111, 795, 85, 795, 117, 795, 68, 90, 780, 68, 122, 780, 100, 122, 780, 76, 74, 76, 106, 108, 106, 78, 74, 78, 106, 110, 106, 65, 780, 97, 780, 73, 780, 105, 780, 79, 780, 111, 780, 85, 780, 117, 780, 85, 776, 772, 117, 776, 772, 85, 776, 769, 117, 776, 769, 85, 776, 780, 117, 776, 780, 85, 776, 768, 117, 776, 768, 65, 776, 772, 97, 776, 772, 65, 775, 772, 97, 775, 772, 198, 772, 230, 772, 71, 780, 103, 780, 75, 780, 107, 780, 79, 808, 111, 808, 79, 808, 772, 111, 808, 772, 439, 780, 658, 780, 106, 780, 68, 90, 68, 122, 100, 122, 71, 769, 103, 769, 78, 768, 110, 768, 65, 778, 769, 97, 778, 769, 198, 769, 230, 769, 216, 769, 248, 769, 65, 783, 97, 783, 65, 785, 97, 785, 69, 783, 101, 783, 69, 785, 101, 785, 73, 783, 105, 783, 73, 785, 105, 785, 79, 783, 111, 783, 79, 785, 111, 785, 82, 783, 114, 783, 82, 785, 114, 785, 85, 783, 117, 783, 85, 785, 117, 785, 83, 806, 115, 806, 84, 806, 116, 806, 72, 780, 104, 780, 65, 775, 97, 775, 69, 807, 101, 807, 79, 776, 772, 111, 776, 772, 79, 771, 772, 111, 771, 772, 79, 775, 111, 775, 79, 775, 772, 111, 775, 772, 89, 772, 121, 772, 104, 614, 106, 114, 633, 635, 641, 119, 121, 32, 774, 32, 775, 32, 778, 32, 808, 32, 771, 32, 779, 611, 108, 120, 661, 768, 769, 787, 776, 769, 697, 32, 837, 59, 32, 776, 769, 913, 769, 183, 917, 769, 919, 769, 921, 769, 927, 769, 933, 769, 937, 769, 953, 776, 769, 921, 776, 933, 776, 945, 769, 949, 769, 951, 769, 953, 769, 965, 776, 769, 953, 776, 965, 776, 959, 769, 965, 769, 969, 769, 946, 952, 933, 966, 960, 954, 961, 962, 920, 949, 1045, 768, 1045, 776, 1043, 769, 1030, 776, 1050, 769, 1048, 768, 1059, 774, 1048, 774, 1080, 774, 1077, 768, 1077, 776, 1075, 769, 1110, 776, 1082, 769, 1080, 768, 1091, 774, 1140, 783, 1141, 783, 1046, 774, 1078, 774, 1040, 774, 1072, 774, 1040, 776, 1072, 776, 1045, 774, 1077, 774, 1240, 776, 1241, 776, 1046, 776, 1078, 776, 1047, 776, 1079, 776, 1048, 772, 1080, 772, 1048, 776, 1080, 776, 1054, 776, 1086, 776, 1256, 776, 1257, 776, 1069, 776, 1101, 776, 1059, 772, 1091, 772, 1059, 776, 1091, 776, 1059, 779, 1091, 779, 1063, 776, 1095, 776, 1067, 776, 1099, 776, 1381, 1410, 1575, 1619, 1575, 1620, 1608, 1620, 1575, 1621, 1610, 1620, 1575, 1652, 1608, 1652, 1735, 1652, 1610, 1652, 1749, 1620, 1729, 1620, 1746, 1620, 2344, 2364, 2352, 2364, 2355, 2364, 2325, 2364, 2326, 2364, 2327, 2364, 2332, 2364, 2337, 2364, 2338, 2364, 2347, 2364, 2351, 2364, 2503, 2494, 2503, 2519, 2465, 2492, 2466, 2492, 2479, 2492, 2610, 2620, 2616, 2620, 2582, 2620, 2583, 2620, 2588, 2620, 2603, 2620, 2887, 2902, 2887, 2878, 2887, 2903, 2849, 2876, 2850, 2876, 2962, 3031, 3014, 3006, 3015, 3006, 3014, 3031, 3142, 3158, 3263, 3285, 3270, 3285, 3270, 3286, 3270, 3266, 3270, 3266, 3285, 3398, 3390, 3399, 3390, 3398, 3415, 3545, 3530, 3545, 3535, 3545, 3535, 3530, 3545, 3551, 3661, 3634, 3789, 3762, 3755, 3737, 3755, 3745, 3851, 3906, 4023, 3916, 4023, 3921, 4023, 3926, 4023, 3931, 4023, 3904, 4021, 3953, 3954, 3953, 3956, 4018, 3968, 4018, 3953, 3968, 4019, 3968, 4019, 3953, 3968, 3953, 3968, 3986, 4023, 3996, 4023, 4001, 4023, 4006, 4023, 4011, 4023, 3984, 4021, 4133, 4142, 65, 805, 97, 805, 66, 775, 98, 775, 66, 803, 98, 803, 66, 817, 98, 817, 67, 807, 769, 99, 807, 769, 68, 775, 100, 775, 68, 803, 100, 803, 68, 817, 100, 817, 68, 807, 100, 807, 68, 813, 100, 813, 69, 772, 768, 101, 772, 768, 69, 772, 769, 101, 772, 769, 69, 813, 101, 813, 69, 816, 101, 816, 69, 807, 774, 101, 807, 774, 70, 775, 102, 775, 71, 772, 103, 772, 72, 775, 104, 775, 72, 803, 104, 803, 72, 776, 104, 776, 72, 807, 104, 807, 72, 814, 104, 814, 73, 816, 105, 816, 73, 776, 769, 105, 776, 769, 75, 769, 107, 769, 75, 803, 107, 803, 75, 817, 107, 817, 76, 803, 108, 803, 76, 803, 772, 108, 803, 772, 76, 817, 108, 817, 76, 813, 108, 813, 77, 769, 109, 769, 77, 775, 109, 775, 77, 803, 109, 803, 78, 775, 110, 775, 78, 803, 110, 803, 78, 817, 110, 817, 78, 813, 110, 813, 79, 771, 769, 111, 771, 769, 79, 771, 776, 111, 771, 776, 79, 772, 768, 111, 772, 768, 79, 772, 769, 111, 772, 769, 80, 769, 112, 769, 80, 775, 112, 775, 82, 775, 114, 775, 82, 803, 114, 803, 82, 803, 772, 114, 803, 772, 82, 817, 114, 817, 83, 775, 115, 775, 83, 803, 115, 803, 83, 769, 775, 115, 769, 775, 83, 780, 775, 115, 780, 775, 83, 803, 775, 115, 803, 775, 84, 775, 116, 775, 84, 803, 116, 803, 84, 817, 116, 817, 84, 813, 116, 813, 85, 804, 117, 804, 85, 816, 117, 816, 85, 813, 117, 813, 85, 771, 769, 117, 771, 769, 85, 772, 776, 117, 772, 776, 86, 771, 118, 771, 86, 803, 118, 803, 87, 768, 119, 768, 87, 769, 119, 769, 87, 776, 119, 776, 87, 775, 119, 775, 87, 803, 119, 803, 88, 775, 120, 775, 88, 776, 120, 776, 89, 775, 121, 775, 90, 770, 122, 770, 90, 803, 122, 803, 90, 817, 122, 817, 104, 817, 116, 776, 119, 778, 121, 778, 97, 702, 65, 803, 97, 803, 65, 777, 97, 777, 65, 770, 769, 97, 770, 769, 65, 770, 768, 97, 770, 768, 65, 770, 777, 97, 770, 777, 65, 770, 771, 97, 770, 771, 65, 803, 770, 97, 803, 770, 65, 774, 769, 97, 774, 769, 65, 774, 768, 97, 774, 768, 65, 774, 777, 97, 774, 777, 65, 774, 771, 97, 774, 771, 65, 803, 774, 97, 803, 774, 69, 803, 101, 803, 69, 777, 101, 777, 69, 771, 101, 771, 69, 770, 769, 101, 770, 769, 69, 770, 768, 101, 770, 768, 69, 770, 777, 101, 770, 777, 69, 770, 771, 101, 770, 771, 69, 803, 770, 101, 803, 770, 73, 777, 105, 777, 73, 803, 105, 803, 79, 803, 111, 803, 79, 777, 111, 777, 79, 770, 769, 111, 770, 769, 79, 770, 768, 111, 770, 768, 79, 770, 777, 111, 770, 777, 79, 770, 771, 111, 770, 771, 79, 803, 770, 111, 803, 770, 79, 795, 769, 111, 795, 769, 79, 795, 768, 111, 795, 768, 79, 795, 777, 111, 795, 777, 79, 795, 771, 111, 795, 771, 79, 795, 803, 111, 795, 803, 85, 803, 117, 803, 85, 777, 117, 777, 85, 795, 769, 117, 795, 769, 85, 795, 768, 117, 795, 768, 85, 795, 777, 117, 795, 777, 85, 795, 771, 117, 795, 771, 85, 795, 803, 117, 795, 803, 89, 768, 121, 768, 89, 803, 121, 803, 89, 777, 121, 777, 89, 771, 121, 771, 945, 787, 945, 788, 945, 787, 768, 945, 788, 768, 945, 787, 769, 945, 788, 769, 945, 787, 834, 945, 788, 834, 913, 787, 913, 788, 913, 787, 768, 913, 788, 768, 913, 787, 769, 913, 788, 769, 913, 787, 834, 913, 788, 834, 949, 787, 949, 788, 949, 787, 768, 949, 788, 768, 949, 787, 769, 949, 788, 769, 917, 787, 917, 788, 917, 787, 768, 917, 788, 768, 917, 787, 769, 917, 788, 769, 951, 787, 951, 788, 951, 787, 768, 951, 788, 768, 951, 787, 769, 951, 788, 769, 951, 787, 834, 951, 788, 834, 919, 787, 919, 788, 919, 787, 768, 919, 788, 768, 919, 787, 769, 919, 788, 769, 919, 787, 834, 919, 788, 834, 953, 787, 953, 788, 953, 787, 768, 953, 788, 768, 953, 787, 769, 953, 788, 769, 953, 787, 834, 953, 788, 834, 921, 787, 921, 788, 921, 787, 768, 921, 788, 768, 921, 787, 769, 921, 788, 769, 921, 787, 834, 921, 788, 834, 959, 787, 959, 788, 959, 787, 768, 959, 788, 768, 959, 787, 769, 959, 788, 769, 927, 787, 927, 788, 927, 787, 768, 927, 788, 768, 927, 787, 769, 927, 788, 769, 965, 787, 965, 788, 965, 787, 768, 965, 788, 768, 965, 787, 769, 965, 788, 769, 965, 787, 834, 965, 788, 834, 933, 788, 933, 788, 768, 933, 788, 769, 933, 788, 834, 969, 787, 969, 788, 969, 787, 768, 969, 788, 768, 969, 787, 769, 969, 788, 769, 969, 787, 834, 969, 788, 834, 937, 787, 937, 788, 937, 787, 768, 937, 788, 768, 937, 787, 769, 937, 788, 769, 937, 787, 834, 937, 788, 834, 945, 768, 949, 768, 951, 768, 953, 768, 959, 768, 965, 768, 969, 768, 945, 787, 837, 945, 788, 837, 945, 787, 768, 837, 945, 788, 768, 837, 945, 787, 769, 837, 945, 788, 769, 837, 945, 787, 834, 837, 945, 788, 834, 837, 913, 787, 837, 913, 788, 837, 913, 787, 768, 837, 913, 788, 768, 837, 913, 787, 769, 837, 913, 788, 769, 837, 913, 787, 834, 837, 913, 788, 834, 837, 951, 787, 837, 951, 788, 837, 951, 787, 768, 837, 951, 788, 768, 837, 951, 787, 769, 837, 951, 788, 769, 837, 951, 787, 834, 837, 951, 788, 834, 837, 919, 787, 837, 919, 788, 837, 919, 787, 768, 837, 919, 788, 768, 837, 919, 787, 769, 837, 919, 788, 769, 837, 919, 787, 834, 837, 919, 788, 834, 837, 969, 787, 837, 969, 788, 837, 969, 787, 768, 837, 969, 788, 768, 837, 969, 787, 769, 837, 969, 788, 769, 837, 969, 787, 834, 837, 969, 788, 834, 837, 937, 787, 837, 937, 788, 837, 937, 787, 768, 837, 937, 788, 768, 837, 937, 787, 769, 837, 937, 788, 769, 837, 937, 787, 834, 837, 937, 788, 834, 837, 945, 774, 945, 772, 945, 768, 837, 945, 837, 945, 769, 837, 945, 834, 945, 834, 837, 913, 774, 913, 772, 913, 768, 913, 837, 32, 787, 953, 32, 834, 32, 776, 834, 951, 768, 837, 951, 837, 951, 769, 837, 951, 834, 951, 834, 837, 917, 768, 919, 768, 919, 837, 32, 787, 768, 32, 787, 769, 32, 787, 834, 953, 774, 953, 772, 953, 776, 768, 953, 834, 953, 776, 834, 921, 774, 921, 772, 921, 768, 32, 788, 768, 32, 788, 769, 32, 788, 834, 965, 774, 965, 772, 965, 776, 768, 961, 787, 961, 788, 965, 834, 965, 776, 834, 933, 774, 933, 772, 933, 768, 929, 788, 32, 776, 768, 96, 969, 768, 837, 969, 837, 969, 769, 837, 969, 834, 969, 834, 837, 927, 768, 937, 768, 937, 837, 32, 788, 8208, 32, 819, 46, 46, 46, 46, 46, 46, 8242, 8242, 8242, 8242, 8242, 8245, 8245, 8245, 8245, 8245, 33, 33, 32, 773, 63, 63, 63, 33, 33, 63, 8242, 8242, 8242, 8242, 48, 105, 52, 53, 54, 55, 56, 57, 43, 8722, 61, 40, 41, 110, 82, 115, 97, 47, 99, 97, 47, 115, 67, 176, 67, 99, 47, 111, 99, 47, 117, 400, 176, 70, 103, 72, 295, 73, 76, 78, 78, 111, 80, 81, 82, 83, 77, 84, 69, 76, 84, 77, 90, 937, 75, 66, 101, 69, 70, 77, 1488, 1489, 1490, 1491, 947, 915, 928, 8721, 68, 100, 49, 8260, 51, 50, 8260, 51, 49, 8260, 53, 50, 8260, 53, 51, 8260, 53, 52, 8260, 53, 49, 8260, 54, 53, 8260, 54, 49, 8260, 56, 51, 8260, 56, 53, 8260, 56, 55, 8260, 56, 49, 8260, 73, 73, 73, 73, 73, 73, 86, 86, 86, 73, 86, 73, 73, 86, 73, 73, 73, 73, 88, 88, 88, 73, 88, 73, 73, 105, 105, 105, 105, 105, 105, 118, 118, 118, 105, 118, 105, 105, 118, 105, 105, 105, 105, 120, 120, 105, 120, 105, 105, 99, 109, 8592, 824, 8594, 824, 8596, 824, 8656, 824, 8660, 824, 8658, 824, 8707, 824, 8712, 824, 8715, 824, 8739, 824, 8741, 824, 8747, 8747, 8747, 8747, 8747, 8750, 8750, 8750, 8750, 8750, 8764, 824, 8771, 824, 8773, 824, 8776, 824, 61, 824, 8801, 824, 8781, 824, 60, 824, 62, 824, 8804, 824, 8805, 824, 8818, 824, 8819, 824, 8822, 824, 8823, 824, 8826, 824, 8827, 824, 8834, 824, 8835, 824, 8838, 824, 8839, 824, 8866, 824, 8872, 824, 8873, 824, 8875, 824, 8828, 824, 8829, 824, 8849, 824, 8850, 824, 8882, 824, 8883, 824, 8884, 824, 8885, 824, 12296, 12297, 49, 48, 49, 49, 49, 50, 49, 51, 49, 52, 49, 53, 49, 54, 49, 55, 49, 56, 49, 57, 50, 48, 40, 49, 41, 40, 50, 41, 40, 51, 41, 40, 52, 41, 40, 53, 41, 40, 54, 41, 40, 55, 41, 40, 56, 41, 40, 57, 41, 40, 49, 48, 41, 40, 49, 49, 41, 40, 49, 50, 41, 40, 49, 51, 41, 40, 49, 52, 41, 40, 49, 53, 41, 40, 49, 54, 41, 40, 49, 55, 41, 40, 49, 56, 41, 40, 49, 57, 41, 40, 50, 48, 41, 49, 46, 50, 46, 51, 46, 52, 46, 53, 46, 54, 46, 55, 46, 56, 46, 57, 46, 49, 48, 46, 49, 49, 46, 49, 50, 46, 49, 51, 46, 49, 52, 46, 49, 53, 46, 49, 54, 46, 49, 55, 46, 49, 56, 46, 49, 57, 46, 50, 48, 46, 40, 97, 41, 40, 98, 41, 40, 99, 41, 40, 100, 41, 40, 101, 41, 40, 102, 41, 40, 103, 41, 40, 104, 41, 40, 105, 41, 40, 106, 41, 40, 107, 41, 40, 108, 41, 40, 109, 41, 40, 110, 41, 40, 111, 41, 40, 112, 41, 40, 113, 41, 40, 114, 41, 40, 115, 41, 40, 116, 41, 40, 117, 41, 40, 118, 41, 40, 119, 41, 40, 120, 41, 40, 121, 41, 40, 122, 41, 65, 71, 74, 79, 83, 84, 85, 87, 89, 98, 102, 107, 112, 113, 116, 117, 122, 8747, 8747, 8747, 8747, 58, 58, 61, 61, 61, 61, 61, 61, 10973, 824, 27597, 40863, 19968, 20008, 20022, 20031, 20057, 20101, 20108, 20128, 20154, 20799, 20837, 20843, 20866, 20886, 20907, 20960, 20981, 20992, 21147, 21241, 21269, 21274, 21304, 21313, 21340, 21353, 21378, 21430, 21448, 21475, 22231, 22303, 22763, 22786, 22794, 22805, 22823, 22899, 23376, 23424, 23544, 23567, 23586, 23608, 23662, 23665, 24027, 24037, 24049, 24062, 24178, 24186, 24191, 24308, 24318, 24331, 24339, 24400, 24417, 24435, 24515, 25096, 25142, 25163, 25903, 25908, 25991, 26007, 26020, 26041, 26080, 26085, 26352, 26376, 26408, 27424, 27490, 27513, 27571, 27595, 27604, 27611, 27663, 27668, 27700, 28779, 29226, 29238, 29243, 29247, 29255, 29273, 29275, 29356, 29572, 29577, 29916, 29926, 29976, 29983, 29992, 30000, 30091, 30098, 30326, 30333, 30382, 30399, 30446, 30683, 30690, 30707, 31034, 31160, 31166, 31348, 31435, 31481, 31859, 31992, 32566, 32593, 32650, 32701, 32769, 32780, 32786, 32819, 32895, 32905, 33251, 33258, 33267, 33276, 33292, 33307, 33311, 33390, 33394, 33400, 34381, 34411, 34880, 34892, 34915, 35198, 35211, 35282, 35328, 35895, 35910, 35925, 35960, 35997, 36196, 36208, 36275, 36523, 36554, 36763, 36784, 36789, 37009, 37193, 37318, 37324, 37329, 38263, 38272, 38428, 38582, 38585, 38632, 38737, 38750, 38754, 38761, 38859, 38893, 38899, 38913, 39080, 39131, 39135, 39318, 39321, 39340, 39592, 39640, 39647, 39717, 39727, 39730, 39740, 39770, 40165, 40565, 40575, 40613, 40635, 40643, 40653, 40657, 40697, 40701, 40718, 40723, 40736, 40763, 40778, 40786, 40845, 40860, 40864, 12306, 21316, 21317, 12363, 12441, 12365, 12441, 12367, 12441, 12369, 12441, 12371, 12441, 12373, 12441, 12375, 12441, 12377, 12441, 12379, 12441, 12381, 12441, 12383, 12441, 12385, 12441, 12388, 12441, 12390, 12441, 12392, 12441, 12399, 12441, 12399, 12442, 12402, 12441, 12402, 12442, 12405, 12441, 12405, 12442, 12408, 12441, 12408, 12442, 12411, 12441, 12411, 12442, 12358, 12441, 32, 12441, 32, 12442, 12445, 12441, 12424, 12426, 12459, 12441, 12461, 12441, 12463, 12441, 12465, 12441, 12467, 12441, 12469, 12441, 12471, 12441, 12473, 12441, 12475, 12441, 12477, 12441, 12479, 12441, 12481, 12441, 12484, 12441, 12486, 12441, 12488, 12441, 12495, 12441, 12495, 12442, 12498, 12441, 12498, 12442, 12501, 12441, 12501, 12442, 12504, 12441, 12504, 12442, 12507, 12441, 12507, 12442, 12454, 12441, 12527, 12441, 12528, 12441, 12529, 12441, 12530, 12441, 12541, 12441, 12467, 12488, 4352, 4353, 4522, 4354, 4524, 4525, 4355, 4356, 4357, 4528, 4529, 4530, 4531, 4532, 4533, 4378, 4358, 4359, 4360, 4385, 4361, 4362, 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370, 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456, 4457, 4458, 4459, 4460, 4461, 4462, 4463, 4464, 4465, 4466, 4467, 4468, 4469, 4448, 4372, 4373, 4551, 4552, 4556, 4558, 4563, 4567, 4569, 4380, 4573, 4575, 4381, 4382, 4384, 4386, 4387, 4391, 4393, 4395, 4396, 4397, 4398, 4399, 4402, 4406, 4416, 4423, 4428, 4593, 4594, 4439, 4440, 4441, 4484, 4485, 4488, 4497, 4498, 4500, 4510, 4513, 19977, 22235, 19978, 20013, 19979, 30002, 19993, 19969, 22825, 22320, 40, 4352, 41, 40, 4354, 41, 40, 4355, 41, 40, 4357, 41, 40, 4358, 41, 40, 4359, 41, 40, 4361, 41, 40, 4363, 41, 40, 4364, 41, 40, 4366, 41, 40, 4367, 41, 40, 4368, 41, 40, 4369, 41, 40, 4370, 41, 40, 4352, 4449, 41, 40, 4354, 4449, 41, 40, 4355, 4449, 41, 40, 4357, 4449, 41, 40, 4358, 4449, 41, 40, 4359, 4449, 41, 40, 4361, 4449, 41, 40, 4363, 4449, 41, 40, 4364, 4449, 41, 40, 4366, 4449, 41, 40, 4367, 4449, 41, 40, 4368, 4449, 41, 40, 4369, 4449, 41, 40, 4370, 4449, 41, 40, 4364, 4462, 41, 40, 19968, 41, 40, 20108, 41, 40, 19977, 41, 40, 22235, 41, 40, 20116, 41, 40, 20845, 41, 40, 19971, 41, 40, 20843, 41, 40, 20061, 41, 40, 21313, 41, 40, 26376, 41, 40, 28779, 41, 40, 27700, 41, 40, 26408, 41, 40, 37329, 41, 40, 22303, 41, 40, 26085, 41, 40, 26666, 41, 40, 26377, 41, 40, 31038, 41, 40, 21517, 41, 40, 29305, 41, 40, 36001, 41, 40, 31069, 41, 40, 21172, 41, 40, 20195, 41, 40, 21628, 41, 40, 23398, 41, 40, 30435, 41, 40, 20225, 41, 40, 36039, 41, 40, 21332, 41, 40, 31085, 41, 40, 20241, 41, 40, 33258, 41, 40, 33267, 41, 50, 49, 50, 50, 50, 51, 50, 52, 50, 53, 50, 54, 50, 55, 50, 56, 50, 57, 51, 48, 51, 49, 51, 50, 51, 51, 51, 52, 51, 53, 4352, 4449, 4354, 4449, 4355, 4449, 4357, 4449, 4358, 4449, 4359, 4449, 4361, 4449, 4363, 4449, 4364, 4449, 4366, 4449, 4367, 4449, 4368, 4449, 4369, 4449, 4370, 4449, 20116, 20845, 19971, 20061, 26666, 26377, 31038, 21517, 29305, 36001, 31069, 21172, 31192, 30007, 36969, 20778, 21360, 27880, 38917, 20241, 20889, 27491, 24038, 21491, 21307, 23447, 23398, 30435, 20225, 36039, 21332, 22812, 51, 54, 51, 55, 51, 56, 51, 57, 52, 48, 52, 49, 52, 50, 52, 51, 52, 52, 52, 53, 52, 54, 52, 55, 52, 56, 52, 57, 53, 48, 49, 26376, 50, 26376, 51, 26376, 52, 26376, 53, 26376, 54, 26376, 55, 26376, 56, 26376, 57, 26376, 49, 48, 26376, 49, 49, 26376, 49, 50, 26376, 12450, 12452, 12454, 12456, 12458, 12459, 12461, 12463, 12465, 12467, 12469, 12471, 12473, 12475, 12477, 12479, 12481, 12484, 12486, 12488, 12490, 12491, 12492, 12493, 12494, 12495, 12498, 12501, 12504, 12507, 12510, 12511, 12512, 12513, 12514, 12516, 12518, 12520, 12521, 12522, 12523, 12524, 12525, 12527, 12528, 12529, 12530, 12450, 12495, 12442, 12540, 12488, 12450, 12523, 12501, 12449, 12450, 12531, 12504, 12442, 12450, 12450, 12540, 12523, 12452, 12491, 12531, 12463, 12441, 12452, 12531, 12481, 12454, 12457, 12531, 12456, 12473, 12463, 12540, 12488, 12441, 12456, 12540, 12459, 12540, 12458, 12531, 12473, 12458, 12540, 12512, 12459, 12452, 12522, 12459, 12521, 12483, 12488, 12459, 12525, 12522, 12540, 12459, 12441, 12525, 12531, 12459, 12441, 12531, 12510, 12461, 12441, 12459, 12441, 12461, 12441, 12491, 12540, 12461, 12517, 12522, 12540, 12461, 12441, 12523, 12479, 12441, 12540, 12461, 12525, 12461, 12525, 12463, 12441, 12521, 12512, 12461, 12525, 12513, 12540, 12488, 12523, 12461, 12525, 12527, 12483, 12488, 12463, 12441, 12521, 12512, 12463, 12441, 12521, 12512, 12488, 12531, 12463, 12523, 12475, 12441, 12452, 12525, 12463, 12525, 12540, 12493, 12465, 12540, 12473, 12467, 12523, 12490, 12467, 12540, 12507, 12442, 12469, 12452, 12463, 12523, 12469, 12531, 12481, 12540, 12512, 12471, 12522, 12531, 12463, 12441, 12475, 12531, 12481, 12475, 12531, 12488, 12479, 12441, 12540, 12473, 12486, 12441, 12471, 12488, 12441, 12523, 12488, 12531, 12490, 12494, 12494, 12483, 12488, 12495, 12452, 12484, 12495, 12442, 12540, 12475, 12531, 12488, 12495, 12442, 12540, 12484, 12495, 12441, 12540, 12524, 12523, 12498, 12442, 12450, 12473, 12488, 12523, 12498, 12442, 12463, 12523, 12498, 12442, 12467, 12498, 12441, 12523, 12501, 12449, 12521, 12483, 12488, 12441, 12501, 12451, 12540, 12488, 12501, 12441, 12483, 12471, 12455, 12523, 12501, 12521, 12531, 12504, 12463, 12479, 12540, 12523, 12504, 12442, 12477, 12504, 12442, 12491, 12498, 12504, 12523, 12484, 12504, 12442, 12531, 12473, 12504, 12442, 12540, 12471, 12441, 12504, 12441, 12540, 12479, 12507, 12442, 12452, 12531, 12488, 12507, 12441, 12523, 12488, 12507, 12531, 12507, 12442, 12531, 12488, 12441, 12507, 12540, 12523, 12507, 12540, 12531, 12510, 12452, 12463, 12525, 12510, 12452, 12523, 12510, 12483, 12495, 12510, 12523, 12463, 12510, 12531, 12471, 12519, 12531, 12511, 12463, 12525, 12531, 12511, 12522, 12511, 12522, 12495, 12441, 12540, 12523, 12513, 12459, 12441, 12513, 12459, 12441, 12488, 12531, 12513, 12540, 12488, 12523, 12516, 12540, 12488, 12441, 12516, 12540, 12523, 12518, 12450, 12531, 12522, 12483, 12488, 12523, 12522, 12521, 12523, 12498, 12442, 12540, 12523, 12540, 12501, 12441, 12523, 12524, 12512, 12524, 12531, 12488, 12465, 12441, 12531, 12527, 12483, 12488, 48, 28857, 49, 28857, 50, 28857, 51, 28857, 52, 28857, 53, 28857, 54, 28857, 55, 28857, 56, 28857, 57, 28857, 49, 48, 28857, 49, 49, 28857, 49, 50, 28857, 49, 51, 28857, 49, 52, 28857, 49, 53, 28857, 49, 54, 28857, 49, 55, 28857, 49, 56, 28857, 49, 57, 28857, 50, 48, 28857, 50, 49, 28857, 50, 50, 28857, 50, 51, 28857, 50, 52, 28857, 104, 80, 97, 100, 97, 65, 85, 98, 97, 114, 111, 86, 112, 99, 24179, 25104, 26157, 21644, 22823, 27491, 26126, 27835, 26666, 24335, 20250, 31038, 112, 65, 110, 65, 956, 65, 109, 65, 107, 65, 75, 66, 77, 66, 71, 66, 99, 97, 108, 107, 99, 97, 108, 112, 70, 110, 70, 956, 70, 956, 103, 109, 103, 107, 103, 72, 122, 107, 72, 122, 77, 72, 122, 71, 72, 122, 84, 72, 122, 956, 108, 109, 108, 100, 108, 107, 108, 102, 109, 110, 109, 956, 109, 109, 109, 99, 109, 107, 109, 109, 109, 50, 99, 109, 50, 109, 50, 107, 109, 50, 109, 109, 51, 99, 109, 51, 109, 51, 107, 109, 51, 109, 8725, 115, 109, 8725, 115, 50, 80, 97, 107, 80, 97, 77, 80, 97, 71, 80, 97, 114, 97, 100, 114, 97, 100, 8725, 115, 114, 97, 100, 8725, 115, 50, 112, 115, 110, 115, 956, 115, 109, 115, 112, 86, 110, 86, 956, 86, 109, 86, 107, 86, 77, 86, 112, 87, 110, 87, 956, 87, 109, 87, 107, 87, 77, 87, 107, 937, 77, 937, 97, 46, 109, 46, 66, 113, 99, 99, 99, 100, 67, 8725, 107, 103, 67, 111, 46, 100, 66, 71, 121, 104, 97, 72, 80, 105, 110, 75, 75, 75, 77, 107, 116, 108, 109, 108, 110, 108, 111, 103, 108, 120, 109, 98, 109, 105, 108, 109, 111, 108, 80, 72, 112, 46, 109, 46, 80, 80, 77, 80, 82, 115, 114, 83, 118, 87, 98, 49, 26085, 50, 26085, 51, 26085, 52, 26085, 53, 26085, 54, 26085, 55, 26085, 56, 26085, 57, 26085, 49, 48, 26085, 49, 49, 26085, 49, 50, 26085, 49, 51, 26085, 49, 52, 26085, 49, 53, 26085, 49, 54, 26085, 49, 55, 26085, 49, 56, 26085, 49, 57, 26085, 50, 48, 26085, 50, 49, 26085, 50, 50, 26085, 50, 51, 26085, 50, 52, 26085, 50, 53, 26085, 50, 54, 26085, 50, 55, 26085, 50, 56, 26085, 50, 57, 26085, 51, 48, 26085, 51, 49, 26085, 35912, 26356, 36040, 28369, 20018, 21477, 22865, 21895, 22856, 25078, 30313, 32645, 34367, 34746, 35064, 37007, 27138, 27931, 28889, 29662, 33853, 37226, 39409, 20098, 21365, 27396, 29211, 34349, 40478, 23888, 28651, 34253, 35172, 25289, 33240, 34847, 24266, 26391, 28010, 29436, 37070, 20358, 20919, 21214, 25796, 27347, 29200, 30439, 34310, 34396, 36335, 38706, 39791, 40442, 30860, 31103, 32160, 33737, 37636, 35542, 22751, 24324, 31840, 32894, 29282, 30922, 36034, 38647, 22744, 23650, 27155, 28122, 28431, 32047, 32311, 38475, 21202, 32907, 20956, 20940, 31260, 32190, 33777, 38517, 35712, 25295, 35582, 20025, 23527, 24594, 29575, 30064, 21271, 30971, 20415, 24489, 19981, 27852, 25976, 32034, 21443, 22622, 30465, 33865, 35498, 27578, 27784, 25342, 33509, 25504, 30053, 20142, 20841, 20937, 26753, 31975, 33391, 35538, 37327, 21237, 21570, 24300, 26053, 28670, 31018, 38317, 39530, 40599, 40654, 26310, 27511, 36706, 24180, 24976, 25088, 25754, 28451, 29001, 29833, 31178, 32244, 32879, 36646, 34030, 36899, 37706, 21015, 21155, 21693, 28872, 35010, 24265, 24565, 25467, 27566, 31806, 29557, 20196, 22265, 23994, 24604, 29618, 29801, 32666, 32838, 37428, 38646, 38728, 38936, 20363, 31150, 37300, 38584, 24801, 20102, 20698, 23534, 23615, 26009, 29134, 30274, 34044, 36988, 26248, 38446, 21129, 26491, 26611, 27969, 28316, 29705, 30041, 30827, 32016, 39006, 25134, 38520, 20523, 23833, 28138, 36650, 24459, 24900, 26647, 38534, 21033, 21519, 23653, 26131, 26446, 26792, 27877, 29702, 30178, 32633, 35023, 35041, 38626, 21311, 28346, 21533, 29136, 29848, 34298, 38563, 40023, 40607, 26519, 28107, 33256, 31520, 31890, 29376, 28825, 35672, 20160, 33590, 21050, 20999, 24230, 25299, 31958, 23429, 27934, 26292, 36667, 38477, 24275, 20800, 21952, 22618, 26228, 20958, 29482, 30410, 31036, 31070, 31077, 31119, 38742, 31934, 34322, 35576, 36920, 37117, 39151, 39164, 39208, 40372, 20398, 20711, 20813, 21193, 21220, 21329, 21917, 22022, 22120, 22592, 22696, 23652, 24724, 24936, 24974, 25074, 25935, 26082, 26257, 26757, 28023, 28186, 28450, 29038, 29227, 29730, 30865, 31049, 31048, 31056, 31062, 31117, 31118, 31296, 31361, 31680, 32265, 32321, 32626, 32773, 33261, 33401, 33879, 35088, 35222, 35585, 35641, 36051, 36104, 36790, 38627, 38911, 38971, 102, 102, 102, 105, 102, 108, 102, 102, 105, 102, 102, 108, 115, 116, 1396, 1398, 1396, 1381, 1396, 1387, 1406, 1398, 1396, 1389, 1497, 1460, 1522, 1463, 1506, 1492, 1499, 1500, 1501, 1512, 1514, 1513, 1473, 1513, 1474, 1513, 1468, 1473, 1513, 1468, 1474, 1488, 1463, 1488, 1464, 1488, 1468, 1489, 1468, 1490, 1468, 1491, 1468, 1492, 1468, 1493, 1468, 1494, 1468, 1496, 1468, 1497, 1468, 1498, 1468, 1499, 1468, 1500, 1468, 1502, 1468, 1504, 1468, 1505, 1468, 1507, 1468, 1508, 1468, 1510, 1468, 1511, 1468, 1512, 1468, 1513, 1468, 1514, 1468, 1493, 1465, 1489, 1471, 1499, 1471, 1508, 1471, 1488, 1500, 1649, 1659, 1662, 1664, 1658, 1663, 1657, 1700, 1702, 1668, 1667, 1670, 1671, 1677, 1676, 1678, 1672, 1688, 1681, 1705, 1711, 1715, 1713, 1722, 1723, 1729, 1726, 1746, 1709, 1735, 1734, 1736, 1739, 1733, 1737, 1744, 1609, 1610, 1620, 1575, 1610, 1620, 1749, 1610, 1620, 1608, 1610, 1620, 1735, 1610, 1620, 1734, 1610, 1620, 1736, 1610, 1620, 1744, 1610, 1620, 1609, 1740, 1610, 1620, 1580, 1610, 1620, 1581, 1610, 1620, 1605, 1610, 1620, 1610, 1576, 1580, 1576, 1581, 1576, 1582, 1576, 1605, 1576, 1609, 1576, 1610, 1578, 1580, 1578, 1581, 1578, 1582, 1578, 1605, 1578, 1609, 1578, 1610, 1579, 1580, 1579, 1605, 1579, 1609, 1579, 1610, 1580, 1581, 1580, 1605, 1581, 1580, 1581, 1605, 1582, 1580, 1582, 1581, 1582, 1605, 1587, 1580, 1587, 1581, 1587, 1582, 1587, 1605, 1589, 1581, 1589, 1605, 1590, 1580, 1590, 1581, 1590, 1582, 1590, 1605, 1591, 1581, 1591, 1605, 1592, 1605, 1593, 1580, 1593, 1605, 1594, 1580, 1594, 1605, 1601, 1580, 1601, 1581, 1601, 1582, 1601, 1605, 1601, 1609, 1601, 1610, 1602, 1581, 1602, 1605, 1602, 1609, 1602, 1610, 1603, 1575, 1603, 1580, 1603, 1581, 1603, 1582, 1603, 1604, 1603, 1605, 1603, 1609, 1603, 1610, 1604, 1580, 1604, 1581, 1604, 1582, 1604, 1605, 1604, 1609, 1604, 1610, 1605, 1580, 1605, 1581, 1605, 1582, 1605, 1605, 1605, 1609, 1605, 1610, 1606, 1580, 1606, 1581, 1606, 1582, 1606, 1605, 1606, 1609, 1606, 1610, 1607, 1580, 1607, 1605, 1607, 1609, 1607, 1610, 1610, 1580, 1610, 1581, 1610, 1582, 1610, 1605, 1610, 1609, 1610, 1610, 1584, 1648, 1585, 1648, 1609, 1648, 32, 1612, 1617, 32, 1613, 1617, 32, 1614, 1617, 32, 1615, 1617, 32, 1616, 1617, 32, 1617, 1648, 1610, 1620, 1585, 1610, 1620, 1586, 1610, 1620, 1606, 1576, 1585, 1576, 1586, 1576, 1606, 1578, 1585, 1578, 1586, 1578, 1606, 1579, 1585, 1579, 1586, 1579, 1606, 1605, 1575, 1606, 1585, 1606, 1586, 1606, 1606, 1610, 1585, 1610, 1586, 1610, 1606, 1610, 1620, 1582, 1610, 1620, 1607, 1576, 1607, 1578, 1607, 1589, 1582, 1604, 1607, 1606, 1607, 1607, 1648, 1610, 1607, 1579, 1607, 1587, 1607, 1588, 1605, 1588, 1607, 1600, 1614, 1617, 1600, 1615, 1617, 1600, 1616, 1617, 1591, 1609, 1591, 1610, 1593, 1609, 1593, 1610, 1594, 1609, 1594, 1610, 1587, 1609, 1587, 1610, 1588, 1609, 1588, 1610, 1581, 1609, 1581, 1610, 1580, 1609, 1580, 1610, 1582, 1609, 1582, 1610, 1589, 1609, 1589, 1610, 1590, 1609, 1590, 1610, 1588, 1580, 1588, 1581, 1588, 1582, 1588, 1585, 1587, 1585, 1589, 1585, 1590, 1585, 1575, 1611, 1578, 1580, 1605, 1578, 1581, 1580, 1578, 1581, 1605, 1578, 1582, 1605, 1578, 1605, 1580, 1578, 1605, 1581, 1578, 1605, 1582, 1580, 1605, 1581, 1581, 1605, 1610, 1581, 1605, 1609, 1587, 1581, 1580, 1587, 1580, 1581, 1587, 1580, 1609, 1587, 1605, 1581, 1587, 1605, 1580, 1587, 1605, 1605, 1589, 1581, 1581, 1589, 1605, 1605, 1588, 1581, 1605, 1588, 1580, 1610, 1588, 1605, 1582, 1588, 1605, 1605, 1590, 1581, 1609, 1590, 1582, 1605, 1591, 1605, 1581, 1591, 1605, 1605, 1591, 1605, 1610, 1593, 1580, 1605, 1593, 1605, 1605, 1593, 1605, 1609, 1594, 1605, 1605, 1594, 1605, 1610, 1594, 1605, 1609, 1601, 1582, 1605, 1602, 1605, 1581, 1602, 1605, 1605, 1604, 1581, 1605, 1604, 1581, 1610, 1604, 1581, 1609, 1604, 1580, 1580, 1604, 1582, 1605, 1604, 1605, 1581, 1605, 1581, 1580, 1605, 1581, 1605, 1605, 1581, 1610, 1605, 1580, 1581, 1605, 1580, 1605, 1605, 1582, 1580, 1605, 1582, 1605, 1605, 1580, 1582, 1607, 1605, 1580, 1607, 1605, 1605, 1606, 1581, 1605, 1606, 1581, 1609, 1606, 1580, 1605, 1606, 1580, 1609, 1606, 1605, 1610, 1606, 1605, 1609, 1610, 1605, 1605, 1576, 1582, 1610, 1578, 1580, 1610, 1578, 1580, 1609, 1578, 1582, 1610, 1578, 1582, 1609, 1578, 1605, 1610, 1578, 1605, 1609, 1580, 1605, 1610, 1580, 1581, 1609, 1580, 1605, 1609, 1587, 1582, 1609, 1589, 1581, 1610, 1588, 1581, 1610, 1590, 1581, 1610, 1604, 1580, 1610, 1604, 1605, 1610, 1610, 1581, 1610, 1610, 1580, 1610, 1610, 1605, 1610, 1605, 1605, 1610, 1602, 1605, 1610, 1606, 1581, 1610, 1593, 1605, 1610, 1603, 1605, 1610, 1606, 1580, 1581, 1605, 1582, 1610, 1604, 1580, 1605, 1603, 1605, 1605, 1580, 1581, 1610, 1581, 1580, 1610, 1605, 1580, 1610, 1601, 1605, 1610, 1576, 1581, 1610, 1587, 1582, 1610, 1606, 1580, 1610, 1589, 1604, 1746, 1602, 1604, 1746, 1575, 1604, 1604, 1607, 1575, 1603, 1576, 1585, 1605, 1581, 1605, 1583, 1589, 1604, 1593, 1605, 1585, 1587, 1608, 1604, 1593, 1604, 1610, 1607, 1608, 1587, 1604, 1605, 1589, 1604, 1609, 1589, 1604, 1609, 32, 1575, 1604, 1604, 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 1580, 1604, 32, 1580, 1604, 1575, 1604, 1607, 1585, 1740, 1575, 1604, 8212, 8211, 95, 123, 125, 12308, 12309, 12304, 12305, 12298, 12299, 12300, 12301, 12302, 12303, 44, 12289, 58, 63, 33, 35, 38, 42, 45, 60, 62, 92, 36, 37, 64, 32, 1611, 1600, 1611, 32, 1612, 32, 1613, 32, 1614, 1600, 1614, 32, 1615, 1600, 1615, 32, 1616, 1600, 1616, 32, 1617, 1600, 1617, 32, 1618, 1600, 1618, 1569, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1610, 1604, 1575, 1619, 1604, 1575, 1620, 1604, 1575, 1621, 1604, 1575, 34, 39, 47, 91, 93, 94, 124, 126, 10629, 10630, 12290, 12539, 12449, 12451, 12453, 12455, 12457, 12515, 12517, 12519, 12483, 12540, 12531, 12441, 12442, 162, 163, 172, 166, 165, 8361, 9474, 8592, 8593, 8594, 8595, 9632, 9675, 119127, 119141, 119128, 119141, 119128, 119141, 119150, 119128, 119141, 119151, 119128, 119141, 119152, 119128, 119141, 119153, 119128, 119141, 119154, 119225, 119141, 119226, 119141, 119225, 119141, 119150, 119226, 119141, 119150, 119225, 119141, 119151, 119226, 119141, 119151, 913, 914, 916, 917, 918, 919, 921, 922, 923, 924, 925, 926, 927, 929, 931, 932, 934, 935, 936, 8711, 945, 948, 950, 951, 955, 957, 958, 959, 963, 964, 965, 967, 968, 969, 8706, 20029, 20024, 20033, 131362, 20320, 20411, 20482, 20602, 20633, 20687, 13470, 132666, 20820, 20836, 20855, 132380, 13497, 20839, 20877, 132427, 20887, 20900, 20172, 20908, 20917, 168415, 20995, 13535, 21051, 21062, 21106, 21111, 13589, 21191, 21242, 21253, 21254, 21321, 21338, 21363, 21373, 21375, 133676, 28784, 21450, 21471, 133987, 21483, 21489, 21510, 21662, 21560, 21576, 21608, 21666, 21750, 21776, 21843, 21859, 21892, 21913, 21931, 21939, 21954, 22294, 22295, 22097, 22132, 22766, 22478, 22516, 22541, 22411, 22578, 22577, 22700, 136420, 22770, 22775, 22790, 22810, 22818, 22882, 136872, 136938, 23020, 23067, 23079, 23000, 23142, 14062, 136042, 23304, 23358, 137672, 23491, 23512, 23539, 138008, 23551, 23558, 24371, 14209, 23648, 23744, 23693, 138724, 23875, 138726, 23918, 23915, 23932, 24033, 24034, 14383, 24061, 24104, 24125, 24169, 14434, 139651, 14460, 24240, 24243, 24246, 172946, 140081, 33281, 24354, 14535, 144056, 156122, 24418, 24427, 14563, 24474, 24525, 24535, 24569, 24705, 14650, 14620, 141012, 24775, 24904, 24908, 24910, 24954, 25010, 24996, 25007, 25054, 25104, 25115, 25181, 25265, 25300, 25424, 142092, 25405, 25340, 25448, 25475, 25572, 142321, 25634, 25541, 25513, 14894, 25705, 25726, 25757, 25719, 14956, 25964, 143370, 26083, 26360, 26185, 15129, 15112, 15076, 20882, 20885, 26368, 26268, 32941, 17369, 26395, 26401, 26462, 26451, 144323, 15177, 26618, 26501, 26706, 144493, 26766, 26655, 26900, 15261, 26946, 27043, 27114, 27304, 145059, 27355, 15384, 27425, 145575, 27476, 15438, 27506, 27551, 27579, 146061, 138507, 146170, 27726, 146620, 27839, 27853, 27751, 27926, 27966, 28009, 28024, 28037, 146718, 27956, 28207, 28270, 15667, 28363, 28359, 147153, 28153, 28526, 147294, 147342, 28614, 28729, 28702, 28699, 15766, 28746, 28797, 28791, 28845, 132389, 28997, 148067, 29084, 17323, 29224, 29237, 29264, 149000, 29312, 29333, 149301, 149524, 29562, 29579, 16044, 29605, 16056, 29767, 29788, 29809, 29829, 29898, 16155, 29988, 150582, 30014, 150674, 139679, 30224, 151457, 151480, 151620, 16380, 16392, 30452, 151795, 151794, 151833, 151859, 30494, 30495, 30538, 16441, 30603, 16454, 16534, 152605, 30798, 30924, 16611, 153126, 153242, 153285, 31211, 16687, 31306, 31311, 153980, 154279, 31406, 16898, 154539, 31686, 31689, 16935, 154752, 31954, 17056, 31976, 31971, 32000, 155526, 32099, 17153, 32199, 32258, 32325, 17204, 156200, 156231, 17241, 156377, 32634, 156478, 32661, 32762, 156890, 156963, 32864, 157096, 32880, 144223, 17365, 32946, 33027, 17419, 33086, 23221, 157607, 157621, 144275, 144284, 33284, 36766, 17515, 33425, 33419, 33437, 21171, 33457, 33459, 33469, 33510, 158524, 33565, 33635, 33709, 33571, 33725, 33767, 33619, 33738, 33740, 33756, 158774, 159083, 158933, 17707, 34033, 34035, 34070, 160714, 34148, 159532, 17757, 17761, 159665, 159954, 17771, 34384, 34407, 34409, 34473, 34440, 34574, 34530, 34681, 34600, 34667, 34694, 19799, 34785, 34817, 17913, 34912, 161383, 35031, 35038, 17973, 35066, 13499, 161966, 162150, 18110, 18119, 35488, 35565, 35722, 162984, 36011, 36033, 36123, 36215, 163631, 133124, 36299, 36284, 36336, 133342, 36564, 36664, 165330, 165357, 37012, 37105, 37137, 165678, 37147, 37432, 37591, 37592, 37500, 37881, 37909, 166906, 38283, 18837, 38327, 167287, 18918, 38595, 23986, 38691, 168261, 168474, 19054, 19062, 38880, 168970, 19122, 169110, 38923, 38953, 169398, 39138, 19251, 39209, 39335, 39362, 39422, 19406, 170800, 39698, 40000, 40189, 19662, 19693, 40295, 172238, 19704, 172293, 172558, 172689, 19798, 40702, 40709, 40719, 40726, 173568 }; /* * This macro extracts the information about a character from the * Unicode character tables. */ #define GetUniCharDecompInfo(ch) (decompGroupMap[(decompPageMap[(((int)(ch)) & 0x1fffff) >> DECOMP_OFFSET_BITS] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))]) #define GetDecompShift(info) ((info) & 0xffff) #define GetDecompLen(info) ((info) >> 16) #define COMP_OFFSET_BITS 8 /* * The pageMap is indexed by page number and returns an alternate page number * that identifies a unique page of characters. Many Unicode characters map * to the same alternate page number. */ static unsigned char compPageMap[] = { 0, 1, 2, 3, 4, 5, 6, 5, 5, 7, 5, 8, 9, 10, 5, 5, 11, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 12, 13, 5, 14, 15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }; /* * The groupMap is indexed by combining the alternate page number with * the page offset and returns a group number that identifies a unique * set of character attributes. */ static int compGroupMap[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65564, 65640, 65738, -1, -1, 30, 91, 141, 65, 121, 65701, 38, 94, 1, 65604, 124, 44, 100, 12, 76, 77, -1, 48, 105, 17, 84, 136, 54, 113, 23, 24, -1, -1, -1, -1, -1, -1, 140, 64, 120, 71, 123, 65573, 99, 10, 75, 129, 47, 104, 16, 15, 83, 135, -1, 110, 22, 86, 137, 59, 117, 118, 28, 89, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 102, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, -1, 65713, 65575, 101, 65550, -1, -1, 42, -1, -1, -1, -1, 65576, -1, -1, -1, -1, 130, 50, 65678, -1, 65628, -1, -1, -1, 115, -1, -1, -1, -1, -1, 32, -1, 65742, 65600, 67, 65704, -1, -1, 5, -1, -1, -1, -1, 65549, -1, -1, -1, -1, 107, 20, 65626, -1, 65587, -1, -1, -1, 87, -1, -1, -1, -1, -1, 142, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 106, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 37, 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65624, 65722, -1, -1, -1, -1, 65632, 65730, -1, -1, -1, -1, -1, -1, 65597, 65699, 65567, 65649, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65728, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 81, 131, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 119, 33, -1, -1, -1, -1, -1, -1, 65546, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65593, 65696, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65675, 65554, 65625, 65724, -1, -1, -1, -1, 65731, 65590, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65729, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131073, 131074, 131075, 131077, 131079, -1, 131080, 131082, 131083, 131084, 131098, 131102, 131085, -1, -1, 131086, -1, 131087, -1, 131076, 131078, -1, -1, -1, -1, -1, -1, 131103, -1, -1, -1, -1, -1, -1, -1, 131088, 131104, 131101, 131097, 131092, 131089, -1, -1, -1, -1, 131094, 131093, -1, 131090, 131095, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131091, -1, -1, 131072, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 34, -1, -1, -1, 122, -1, 96, -1, 8, -1, -1, -1, -1, -1, 80, -1, 65586, -1, -1, -1, 85, -1, -1, -1, 26, -1, -1, 65539, -1, 65707, -1, -1, 2, -1, -1, -1, 95, -1, 7, -1, 125, -1, -1, -1, -1, -1, 51, -1, 111, -1, -1, -1, 56, -1, -1, -1, 0, 138, 62, -1, -1, 65664, -1, -1, -1, 39, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65736, -1, -1, -1, -1, -1, -1, -1, -1, -1, 97, -1, -1, 65714, -1, 103, 14, 65622, 132, -1, 65581, -1, -1, -1, 65727, -1, -1, -1, -1, 139, -1, -1, -1, 65566, -1, -1, -1, 65706, -1, 65663, -1, -1, 72, -1, -1, 65670, -1, 79, 133, 65582, 52, -1, 65556, -1, -1, -1, 65687, -1, -1, -1, -1, 63, -1, -1, -1, 65744, -1, -1, -1, 65659, -1, 65595, -1, -1, -1, -1, -1, -1, -1, -1, 65658, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65661, 65545, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65651, 65542, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65682, 65559, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65733, -1, 65657, -1, -1, -1, -1, -1, -1, -1, -1, 196618, 131108, 196619, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65618, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65612, -1, -1, 65611, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65734, -1, -1, -1, -1, -1, -1, -1, 65656, -1, -1, 65655, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 196611, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 196612, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 196613, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 196614, 196615, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65577, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131105, -1, -1, -1, -1, -1, -1, -1, 98, 65584, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131106, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65578, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65716, -1, -1, 196616, -1, -1, -1, 127, -1, -1, -1, 65630, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131107, 196617, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131096, -1, -1, -1, -1, -1, -1, -1, 19, 65695, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 196610, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131081, -1, -1, -1, -1, 196608, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, 65538, -1, -1, 196609, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65616, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65679, 65557, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65685, 65561, -1, -1, -1, -1, -1, -1, 65743, 65601, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 114, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65673, 65553, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65540, 65605, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, 134, 65591, 65692, 65693, 65565, 65641, 65739, 58, 116, 65568, 65652, 65543, 65609, 65610, 65710, 36, 92, -1, -1, -1, -1, -1, -1, 9, 73, -1, -1, -1, -1, -1, -1, 53, 108, 65690, 65563, 65639, 65737, 65598, 65700, 27, 88, 65541, 65606, 65607, 65709, 65572, 65667, 11, 69, -1, -1, -1, -1, -1, -1, 126, 45, -1, -1, -1, -1, -1, -1, 13, 78, -1, -1, -1, -1, -1, -1, 55, 112, -1, -1, -1, -1, -1, -1, 29, 90, -1, -1, -1, -1, -1, -1, -1, 70, -1, -1, -1, -1, -1, -1, 128, 46, 65683, 65560, 65635, 65732, 65592, 65694, 109, 21, 65642, 65740, 65599, 65702, 65569, 65653, 65544, -1, -1, -1, 65574, -1, -1, -1, -1, -1, -1, -1, 65552, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65537, -1, -1, -1, -1, -1, -1, -1, -1, 40, -1, -1, -1, -1, -1, -1, 65680, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65570, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65705, -1, 65660, -1, 65614, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65698, -1, 65644, -1, 65741, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65711, -1, -1, -1, -1, 65619, -1, -1, 65676, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65668, -1, 65548, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65648, -1, -1, -1, -1, -1, -1, 65547, -1, 65715, -1, -1, 65551, -1, -1, -1, -1, 65681, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65596, -1, -1, 65647, 65536, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65721, 65583, -1, -1, 65558, 65631, -1, -1, 65688, 65562, 65637, 65735, -1, -1, -1, -1, 65646, 65745, -1, -1, 65571, 65662, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65580, 65579, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65602, -1, -1, -1, -1, -1, 65613, 65712, -1, 65669, -1, -1, -1, -1, -1, -1, 65555, 65629, 65725, 65588, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65718, -1, -1, -1, -1, 65708, -1, 65703, -1, 65697, -1, 65686, -1, 65684, -1, 65677, -1, 65671, -1, 65665, -1, 65650, -1, 65645, -1, 65638, -1, 65633, -1, -1, 65623, -1, 65620, -1, 65615, -1, -1, -1, -1, -1, -1, 60, -1, -1, 74, -1, -1, 68, -1, -1, 61, -1, -1, 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131099, 131100, -1, -1, 65717, -1, -1, -1, -1, -1, -1, -1, -1, 65691, -1, -1, -1, -1, 65674, -1, 65672, -1, 65666, -1, 65654, -1, 65643, -1, 65636, -1, 65634, -1, 65627, -1, 65621, -1, 65617, -1, 65608, -1, 65603, -1, -1, 65594, -1, 65589, -1, 65585, -1, -1, -1, -1, -1, -1, 41, -1, -1, 31, -1, -1, 49, -1, -1, 43, -1, -1, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65726, 65723, 65720, 65719, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65689, -1, -1 }; /* * Lists of compositions for characters that appears only in one composition */ static int compFirstList[][2] = { {824, 8817}, {837, 8119}, {3530, 3549}, {837, 8116}, {770, 7896}, {837, 8090}, {776, 1243}, {837, 8076}, {837, 8114}, {783, 1143}, {780, 494}, {824, 8772}, {824, 8742}, {769, 7727}, {769, 7688}, {824, 8777}, {837, 8178}, {770, 7879}, {772, 481}, {824, 8938}, {769, 1116}, {772, 7737}, {824, 8824}, {776, 1259}, {837, 8099}, {772, 7773}, {824, 8833}, {837, 8083}, {824, 8814}, {837, 8069}, {776, 1268}, {776, 7802}, {837, 8074}, {837, 8110}, {837, 8183}, {824, 8840}, {837, 8094}, {775, 7711}, {837, 8130}, {769, 506}, {769, 7726}, {3031, 2964}, {3158, 3144}, {824, 8931}, {824, 8930}, {769, 1036}, {776, 1247}, {824, 8821}, {3006, 3019}, {12441, 12489}, {788, 8172}, {769, 511}, {824, 8941}, {12441, 12487}, {772, 561}, {837, 8066}, {837, 8102}, {772, 492}, {12441, 12485}, {776, 1261}, {824, 8802}, {769, 7800}, {837, 8086}, {837, 8108}, {769, 507}, {775, 7785}, {824, 8876}, {12441, 12482}, {770, 308}, {770, 7897}, {837, 8091}, {837, 8092}, {12441, 12480}, {837, 8077}, {837, 8078}, {1620, 1728}, {1620, 1747}, {824, 8877}, {824, 8622}, {12441, 12393}, {4142, 4134}, {12441, 12478}, {1620, 1730}, {824, 8713}, {12441, 12391}, {12441, 12476}, {776, 1246}, {12441, 12389}, {775, 7780}, {774, 7708}, {772, 555}, {12441, 12474}, {769, 510}, {824, 8939}, {3285, 3275}, {824, 8825}, {775, 7782}, {12441, 12386}, {12441, 12472}, {837, 8100}, {12441, 12470}, {824, 8928}, {12441, 12384}, {837, 8084}, {824, 8800}, {837, 8070}, {837, 8106}, {12441, 12468}, {824, 8655}, {12441, 12382}, {824, 8836}, {824, 8816}, {824, 8769}, {776, 7803}, {12441, 12380}, {776, 1242}, {837, 8075}, {837, 8111}, {12441, 12466}, {2364, 2356}, {2364, 2353}, {1620, 1574}, {776, 1111}, {776, 1273}, {824, 8603}, {783, 1142}, {824, 8841}, {776, 1260}, {837, 8180}, {12441, 12378}, {12441, 12464}, {837, 8095}, {824, 8740}, {824, 8879}, {769, 1107}, {12441, 12376}, {12441, 12462}, {770, 7878}, {12441, 12460}, {772, 480}, {824, 8716}, {12441, 12374}, {772, 554}, {772, 7736}, {837, 8135}, {824, 8813}, {776, 1258}, {837, 8098}, {12441, 12372}, {772, 7772}, {12441, 12370}, {776, 1255}, {824, 8832}, {12441, 12542}, {837, 8082}, {12441, 12532}, {837, 8067}, {837, 8068}, {837, 8103}, {3390, 3403}, {772, 493}, {12441, 12368}, {824, 8653}, {769, 7801}, {837, 8087}, {775, 7710}, {837, 8109}, {12441, 12366}, {769, 7689}, {824, 8602}, {776, 1272}, {837, 8132}, {12441, 12364}, {837, 8093}, {837, 8079}, {824, 8708}, {824, 8878}, {772, 478}, {769, 1027}, {824, 8775}, {3285, 3264}, {12441, 12446}, {12441, 12436}, {12441, 12538}, {12441, 12537}, {824, 8820}, {775, 7781}, {12441, 12536}, {774, 7709}, {824, 8940}, {12441, 12535}, {776, 1254}, {775, 7835}, {780, 495}, {775, 7783}, {772, 560}, {837, 8101}, {1620, 1572}, {2364, 2345}, {824, 8929}, {776, 1031}, {837, 8085}, {824, 8815}, {837, 8071}, {837, 8107}, {824, 8654}, {772, 479}, {775, 7784}, {776, 1269}, {824, 8837} }; static int compSecondList[][2] = { {3545, 3548}, {3545, 3550}, {3398, 3404}, {2503, 2507}, {2503, 2508}, {2887, 2891}, {2887, 2888}, {2887, 2892}, {3270, 3274}, {3270, 3272}, {1575, 1570}, {1575, 1573} }; /* * Compositions matrix */ static int compBothList[144][37] = { { 8179, 8060, 974, 0, 8032, 0, 8033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 204, 205, 206, 0, 296, 0, 298, 300, 0, 304, 207, 7880, 463, 520, 522, 7882, 302, 7724, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 8115, 8048, 940, 0, 7936, 0, 7937, 8113, 8112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8118, 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, 3546, 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, 8157, 8158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7873, 7871, 0, 0, 7877, 0, 0, 0, 0, 0, 0, 7875, 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, 7846, 7844, 0, 0, 7850, 0, 0, 0, 0, 0, 0, 7848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 8131, 8052, 942, 0, 7968, 0, 7969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 8154, 906, 0, 7992, 0, 7993, 8153, 8152, 0, 0, 938, 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, 7962, 7964, 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, 293, 0, 0, 0, 0, 0, 0, 7715, 7719, 0, 543, 0, 0, 7717, 0, 0, 0, 7721, 7723, 0, 7830, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7986, 7988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7990, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 504, 323, 0, 0, 209, 0, 0, 0, 0, 7748, 0, 0, 327, 0, 0, 7750, 0, 0, 0, 325, 0, 7754, 7752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 8002, 8004, 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, 1217, 0, 0, 1244, 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, 505, 324, 0, 0, 241, 0, 0, 0, 0, 7749, 0, 0, 328, 0, 0, 7751, 0, 0, 0, 326, 0, 7755, 7753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 7743, 0, 0, 0, 0, 0, 0, 0, 7745, 0, 0, 0, 0, 0, 7747, 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, 7786, 0, 0, 356, 0, 0, 7788, 0, 0, 0, 354, 0, 7792, 7790, 0, 538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7701, 7703, 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, 3402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 7757, 0, 0, 0, 0, 557, 0, 0, 0, 7759, 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 }, { 8105, 8043, 8045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 347, 349, 0, 0, 0, 0, 0, 0, 7777, 0, 0, 353, 0, 0, 7779, 0, 0, 0, 351, 0, 0, 0, 0, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7922, 221, 374, 0, 7928, 0, 562, 0, 0, 7822, 376, 7926, 0, 0, 0, 7924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 377, 7824, 0, 0, 0, 0, 0, 0, 379, 0, 0, 381, 0, 0, 7826, 0, 0, 0, 0, 0, 0, 7828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 7853, 0, 0, 0, 0, 7863, 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 }, { 8188, 8186, 911, 0, 8040, 0, 8041, 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 }, { 8088, 7978, 7980, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7982, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7923, 253, 375, 0, 7929, 0, 563, 0, 0, 7823, 255, 7927, 0, 0, 0, 7925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 8018, 8020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8022, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 192, 193, 194, 0, 195, 0, 256, 258, 0, 550, 196, 7842, 461, 512, 514, 7840, 260, 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, 7680, 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, 12499, 12500, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7847, 7845, 0, 0, 7851, 0, 0, 0, 0, 0, 0, 7849, 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, 7915, 7913, 0, 0, 7919, 0, 0, 0, 0, 0, 0, 7917, 0, 0, 0, 7921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 8124, 8122, 902, 0, 7944, 0, 7945, 8121, 8120, 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, 12508, 12509, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7954, 7956, 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, 7760, 7762, 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, 500, 284, 0, 0, 0, 7712, 286, 0, 288, 0, 0, 486, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 979, 0, 0, 0, 0, 0, 0, 0, 0, 980, 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, 8141, 8142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8143, 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, 12496, 12497, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7872, 7870, 0, 0, 7876, 0, 0, 0, 0, 0, 0, 7874, 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, 12505, 12506, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 317, 0, 0, 7734, 0, 0, 0, 315, 0, 7740, 7738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7995, 7997, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 8097, 8035, 8037, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 7729, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 489, 0, 0, 7731, 0, 0, 0, 311, 0, 0, 7733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 340, 0, 0, 0, 0, 0, 0, 0, 7768, 0, 0, 344, 528, 530, 7770, 0, 0, 0, 342, 0, 0, 7774, 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, 12502, 12503, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 7756, 0, 0, 0, 0, 556, 0, 0, 0, 7758, 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, 8056, 972, 0, 8000, 0, 8001, 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, 1117, 0, 0, 0, 0, 0, 1251, 1081, 0, 0, 1253, 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 }, { 8080, 7970, 7972, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7974, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7808, 7810, 372, 0, 0, 0, 0, 0, 0, 7814, 7812, 0, 0, 0, 0, 7816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 8010, 8012, 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, 8058, 973, 0, 8016, 0, 8017, 8161, 8160, 0, 0, 971, 0, 0, 0, 0, 0, 0, 0, 8166, 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, 12412, 12413, 0, 0, 0, 0, 0, 0, 0, 0 }, { 8072, 7946, 7948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7950, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 7805, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7807, 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, 12400, 12401, 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, 12409, 12410, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 8162, 944, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 1263, 1118, 0, 0, 1265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1267, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7683, 0, 0, 0, 0, 0, 7685, 0, 0, 0, 0, 0, 0, 7687, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7690, 0, 0, 270, 0, 0, 7692, 0, 0, 0, 7696, 0, 7698, 7694, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7857, 7855, 0, 0, 7861, 0, 0, 0, 0, 0, 0, 7859, 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, 509, 0, 0, 0, 0, 483, 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, 12406, 12407, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7987, 7989, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7991, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 8027, 8029, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8031, 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, 7691, 0, 0, 271, 0, 0, 7693, 0, 0, 0, 7697, 0, 7699, 7695, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 1233, 0, 0, 1235, 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, 7963, 7965, 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, 12403, 12404, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 236, 237, 238, 0, 297, 0, 299, 301, 0, 0, 239, 7881, 464, 521, 523, 7883, 303, 7725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 210, 211, 212, 0, 213, 0, 332, 334, 0, 558, 214, 7886, 465, 524, 526, 7884, 490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 336, 416, 0, 0, 0, 0, 0 }, { 0, 0, 7764, 0, 0, 0, 0, 0, 0, 0, 7766, 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, 8003, 8005, 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, 1104, 0, 0, 0, 0, 0, 0, 1239, 0, 0, 1105, 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, 8184, 908, 0, 8008, 0, 8009, 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, 7900, 7898, 0, 0, 7904, 0, 0, 0, 0, 0, 0, 7902, 0, 0, 0, 7906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 8064, 7938, 7940, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 242, 243, 244, 0, 245, 0, 333, 335, 0, 559, 246, 7887, 466, 525, 527, 7885, 491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 337, 417, 0, 0, 0, 0, 0 }, { 0, 217, 218, 219, 0, 360, 0, 362, 364, 0, 0, 220, 7910, 467, 532, 534, 7908, 370, 7796, 0, 0, 0, 7798, 0, 0, 0, 366, 0, 0, 0, 368, 431, 7794, 0, 0, 0, 0 }, { 0, 8170, 910, 0, 0, 0, 8025, 8169, 8168, 0, 0, 939, 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, 7787, 7831, 0, 357, 0, 0, 7789, 0, 0, 0, 355, 0, 7793, 7791, 0, 539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 476, 472, 0, 0, 0, 0, 470, 0, 0, 0, 0, 0, 474, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 8089, 7979, 7981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7983, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 378, 7825, 0, 0, 0, 0, 0, 0, 380, 0, 0, 382, 0, 0, 7827, 0, 0, 0, 0, 0, 0, 7829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 8019, 8021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8023, 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, 7682, 0, 0, 0, 0, 0, 7684, 0, 0, 0, 0, 0, 0, 7686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7955, 7957, 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, 7761, 7763, 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, 292, 0, 0, 0, 0, 0, 0, 7714, 7718, 0, 542, 0, 0, 7716, 0, 0, 0, 7720, 7722, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 8050, 941, 0, 7952, 0, 7953, 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 }, { 8140, 8138, 905, 0, 7976, 0, 7977, 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, 1232, 0, 0, 1234, 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, 3018, 3020, 0, 0 }, { 0, 0, 501, 285, 0, 0, 0, 7713, 287, 0, 289, 0, 0, 487, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 7742, 0, 0, 0, 0, 0, 0, 0, 7744, 0, 0, 0, 0, 0, 7746, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 508, 0, 0, 0, 0, 482, 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, 8173, 901, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1024, 0, 0, 0, 0, 0, 0, 1238, 0, 0, 1025, 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, 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 0, 0, 7735, 0, 0, 0, 316, 0, 7741, 7739, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 346, 348, 0, 0, 0, 0, 0, 0, 7776, 0, 0, 352, 0, 0, 7778, 0, 0, 0, 350, 0, 0, 0, 0, 536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7700, 7702, 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, 7891, 7889, 0, 0, 7895, 0, 0, 0, 0, 0, 0, 7893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 8081, 7971, 7973, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 8104, 8042, 8044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8046, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 341, 0, 0, 0, 0, 0, 0, 0, 7769, 0, 0, 345, 529, 531, 7771, 0, 0, 0, 343, 0, 0, 7775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 8164, 0, 8165, 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, 8011, 8013, 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, 7818, 7820, 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, 7852, 0, 0, 0, 0, 7862, 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, 475, 471, 0, 0, 0, 0, 469, 0, 0, 0, 0, 0, 473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 8073, 7947, 7949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7809, 7811, 373, 0, 0, 0, 0, 0, 0, 7815, 7813, 0, 0, 0, 0, 7817, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7819, 7821, 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, 7914, 7912, 0, 0, 7918, 0, 0, 0, 0, 0, 0, 7916, 0, 0, 0, 7920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 263, 265, 0, 0, 0, 0, 0, 0, 267, 0, 0, 269, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 200, 201, 202, 0, 7868, 0, 274, 276, 0, 278, 203, 7866, 282, 516, 518, 7864, 280, 7706, 0, 552, 0, 7704, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 8136, 904, 0, 7960, 0, 7961, 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, 232, 233, 234, 0, 7869, 0, 275, 277, 0, 279, 235, 7867, 283, 517, 519, 7865, 281, 7707, 0, 553, 0, 7705, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 7728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 488, 0, 0, 7730, 0, 0, 0, 310, 0, 0, 7732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 8054, 943, 0, 7984, 0, 7985, 8145, 8144, 0, 0, 970, 0, 0, 0, 0, 0, 0, 0, 8150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7994, 7996, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7998, 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, 3271, 0 }, { 8096, 8034, 8036, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8038, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7890, 7888, 0, 0, 7894, 0, 0, 0, 0, 0, 0, 7892, 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, 7901, 7899, 0, 0, 7905, 0, 0, 0, 0, 0, 0, 7903, 0, 0, 0, 7907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1037, 0, 0, 0, 0, 0, 1250, 1049, 0, 0, 1252, 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, 1218, 0, 0, 1245, 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 }, { 8065, 7939, 7941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7943, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 7765, 0, 0, 0, 0, 0, 0, 0, 7767, 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, 7804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7806, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 249, 250, 251, 0, 361, 0, 363, 365, 0, 0, 252, 7911, 468, 533, 535, 7909, 371, 7797, 0, 0, 0, 7799, 0, 0, 0, 367, 0, 0, 0, 369, 432, 7795, 0, 0, 0, 0 }, { 0, 8146, 912, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 1262, 1038, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1266, 0, 0, 0, 0, 0, 0 }, { 0, 224, 225, 226, 0, 227, 0, 257, 259, 0, 551, 228, 7843, 462, 513, 515, 7841, 261, 0, 0, 0, 0, 0, 0, 0, 0, 229, 0, 0, 7681, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 262, 264, 0, 0, 0, 0, 0, 0, 266, 0, 0, 268, 0, 0, 0, 0, 0, 0, 199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 7856, 7854, 0, 0, 7860, 0, 0, 0, 0, 0, 0, 7858, 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, 1571 }, }; #define GetUniCharCompInfo(ch) (compGroupMap[(compPageMap[(((int)(ch)) & 0x1fffff) >> COMP_OFFSET_BITS] << COMP_OFFSET_BITS) | ((ch) & ((1 << COMP_OFFSET_BITS)-1))]) #define CompSingleMask (1 << 16) #define CompMask ((1 << 16) - 1) #define CompSecondMask (1 << 17) ejabberd-2.1.11/src/stringprep/Makefile.in0000664000000000000000000000225012240230175015246 0ustar # $Id$ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ # Assume Linux-style dynamic library flags DYNAMIC_LIB_CFLAGS = -fpic -shared ifeq ($(shell uname),Darwin) DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress endif ifeq ($(shell uname),SunOs) DYNAMIC_LIB_CFLAGS = -KPIC -G -z text endif EFLAGS += -I .. EFLAGS += -pz .. # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif ERLSHLIBS = ../stringprep_drv.so OUTDIR = .. SOURCES = $(wildcard *.erl) BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) all: $(BEAMS) $(ERLSHLIBS) $(OUTDIR)/%.beam: %.erl @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< #all: $(ERLSHLIBS) # erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt $(ERLSHLIBS): ../%.so: %.c uni_data.c uni_norm.c $(CC) $(CFLAGS) $(LDFLAGS) $(INCLUDES) \ $(subst ../,,$(subst .so,.c,$@)) $(LIBS) \ $(ERLANG_LIBS) \ $(ERLANG_CFLAGS) \ -o $@ \ $(DYNAMIC_LIB_CFLAGS) clean: rm -f $(BEAMS) $(ERLSHLIBS) distclean: clean rm -f Makefile TAGS: etags *.erl ejabberd-2.1.11/src/stringprep/stringprep_sup.erl0000664000000000000000000000515712240230175017002 0ustar %%%------------------------------------------------------------------- %%% File : stringprep_sup.erl %%% Author : Mickael Remond %%% Description : Supervisor for the Stringprep worker. %%% Created : 29 Jun 2007 by Mickael Remond %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(stringprep_sup). -behaviour(supervisor). %% API -export([start_link/0]). %% Supervisor callbacks -export([init/1]). -define(SERVER, ?MODULE). %%==================================================================== %% API functions %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the supervisor %%-------------------------------------------------------------------- start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). %%==================================================================== %% Supervisor callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Func: init(Args) -> {ok, {SupFlags, [ChildSpec]}} | %% ignore | %% {error, Reason} %% Description: Whenever a supervisor is started using %% supervisor:start_link/[2,3], this function is called by the new process %% to find out about restart strategy, maximum restart frequency and child %% specifications. %%-------------------------------------------------------------------- init([]) -> StringPrep = {stringprep, {stringprep, start_link, []}, permanent, brutal_kill, worker, [stringprep]}, {ok,{{one_for_all,10,1}, [StringPrep]}}. ejabberd-2.1.11/src/stringprep/stringprep.erl0000664000000000000000000000557012240230175016112 0ustar %%%---------------------------------------------------------------------- %%% File : stringprep.erl %%% Author : Alexey Shchepin %%% Purpose : Interface to stringprep_drv %%% Created : 16 Feb 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(stringprep). -author('alexey@process-one.net'). -behaviour(gen_server). -export([start/0, start_link/0, tolower/1, nameprep/1, nodeprep/1, resourceprep/1]). %% Internal exports, call-back functions. -export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]). -define(STRINGPREP_PORT, stringprep_port). -define(NAMEPREP_COMMAND, 1). -define(NODEPREP_COMMAND, 2). -define(RESOURCEPREP_COMMAND, 3). start() -> gen_server:start({local, ?MODULE}, ?MODULE, [], []). start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). init([]) -> case erl_ddll:load_driver(ejabberd:get_so_path(), stringprep_drv) of ok -> ok; {error, already_loaded} -> ok end, Port = open_port({spawn, "stringprep_drv"}, []), register(?STRINGPREP_PORT, Port), {ok, Port}. %%% -------------------------------------------------------- %%% The call-back functions. %%% -------------------------------------------------------- handle_call(_, _, State) -> {noreply, State}. handle_cast(_, State) -> {noreply, State}. handle_info({'EXIT', Port, Reason}, Port) -> {stop, {port_died, Reason}, Port}; handle_info({'EXIT', _Pid, _Reason}, Port) -> {noreply, Port}; handle_info(_, State) -> {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. terminate(_Reason, Port) -> Port ! {self, close}, ok. tolower(String) -> control(0, String). nameprep(String) -> control(?NAMEPREP_COMMAND, String). nodeprep(String) -> control(?NODEPREP_COMMAND, String). resourceprep(String) -> control(?RESOURCEPREP_COMMAND, String). control(Command, String) -> case port_control(?STRINGPREP_PORT, Command, String) of [0 | _] -> error; [1 | Res] -> Res end. ejabberd-2.1.11/src/stringprep/uni_parse.tcl0000664000000000000000000002372612240230175015705 0ustar # uni_parse.tcl -- # # This program parses the UnicodeData file and generates the # corresponding uni_data.c file with compressed character # data tables. The input to this program should be rfc3454.txt # # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # # Modified for ejabberd by Alexey Shchepin # # RCS: @(#) $Id$ namespace eval uni { set shift 8; # number of bits of data within a page # This value can be adjusted to find the # best split to minimize table size variable pMap; # map from page to page index, each entry is # an index into the pages table, indexed by # page number variable pages; # map from page index to page info, each # entry is a list of indices into the groups # table, the list is indexed by the offset variable groups; # list of character info values, indexed by # group number, initialized with the # unassigned character group } proc uni::getValue {i} { variable casemap variable casemap2 variable tablemap if {[info exists tablemap($i)]} { set tables $tablemap($i) } else { set tables {} } if {[info exists casemap2($i)]} { set multicase 1 set delta $casemap2($i) } else { set multicase 0 if {[info exists casemap($i)]} { set delta $casemap($i) } else { set delta 0 } } if {abs($delta) > 0xFFFFF} { puts "delta must be less than 22 bits wide" exit } set ac 0 set c11 0 set c21 0 set b1 0 set d1 0 set d2 0 set xnp 0 foreach tab $tables { switch -glob -- $tab { C.1.1 {set c11 1} C.2.1 {set c21 1} C.* {set ac 1} A.1 {set ac 1} B.1 {set b1 1} D.1 {set d1 1} D.2 {set d2 1} XNP {set xnp 1} } } set val [expr {($ac << 0) | ($c11 << 1) | ($c21 << 2) | ($b1 << 3) | ($d1 << 4) | ($d2 << 5) | ($xnp << 6) | ($multicase << 7) | ($delta << 11)}] return $val } proc uni::getGroup {value} { variable groups set gIndex [lsearch -exact $groups $value] if {$gIndex == -1} { set gIndex [llength $groups] lappend groups $value } return $gIndex } proc uni::addPage {info} { variable pMap variable pages variable pages_map if {[info exists pages_map($info)]} { lappend pMap $pages_map($info) } else { set pIndex [llength $pages] lappend pages $info set pages_map($info) $pIndex lappend pMap $pIndex } return } proc uni::load_tables {data} { variable casemap variable casemap2 variable multicasemap variable tablemap set multicasemap {} set table "" foreach line [split $data \n] { if {$table == ""} { if {[regexp { ----- Start Table (.*) -----} $line temp table]} { #puts "Start table '$table'" } } else { if {[regexp { ----- End Table (.*) -----} $line temp table1]} { set table "" } else { if {$table == "B.1"} { if {[regexp {^ ([[:xdigit:]]+); ;} $line \ temp val]} { scan $val %x val if {$val <= 0x10ffff} { lappend tablemap($val) $table } } } elseif {$table == "B.2"} { if {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+);} $line \ temp from to]} { scan $from %x from scan $to %x to if {$from <= 0x10ffff && $to <= 0x10ffff} { set casemap($from) [expr {$to - $from}] } } elseif {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+) ([[:xdigit:]]+);} $line \ temp from to1 to2]} { scan $from %x from scan $to1 %x to1 scan $to2 %x to2 if {$from <= 0x10ffff && \ $to1 <= 0x10ffff && $to2 <= 0x10ffff} { set casemap2($from) [llength $multicasemap] lappend multicasemap [list $to1 $to2] } } elseif {[regexp {^ ([[:xdigit:]]+); ([[:xdigit:]]+) ([[:xdigit:]]+) ([[:xdigit:]]+);} $line \ temp from to1 to2 to3]} { scan $from %x from scan $to1 %x to1 scan $to2 %x to2 scan $to3 %x to3 if {$from <= 0x10ffff && \ $to1 <= 0x10ffff && $to2 <= 0x10ffff && \ $to3 <= 0x10ffff} { set casemap2($from) [llength $multicasemap] lappend multicasemap [list $to1 $to2 $to3] } } else { #puts "missed: $line" } } elseif {$table != "B.3"} { if {[regexp {^ ([[:xdigit:]]+)-([[:xdigit:]]+)} $line \ temp from to]} { scan $from %x from scan $to %x to for {set i $from} {$i <= $to && $i <= 0x10ffff} {incr i} { lappend tablemap($i) $table } } elseif {[regexp {^ ([[:xdigit:]]+)} $line \ temp val]} { scan $val %x val if {$val <= 0x10ffff} { lappend tablemap($val) $table } } } } } } # XMPP nodeprep prohibited foreach val {22 26 27 2f 3a 3c 3e 40} { scan $val %x val lappend tablemap($val) XNP } } proc uni::buildTables {} { variable shift variable casemap variable tablemap variable pMap {} variable pages {} variable groups {} set info {} ;# temporary page info set mask [expr {(1 << $shift) - 1}] set next 0 for {set i 0} {$i <= 0x10ffff} {incr i} { set gIndex [getGroup [getValue $i]] # Split character index into offset and page number set offset [expr {$i & $mask}] set page [expr {($i >> $shift)}] # Add the group index to the info for the current page lappend info $gIndex # If this is the last entry in the page, add the page if {$offset == $mask} { addPage $info set info {} } } return } proc uni::main {} { global argc argv0 argv variable pMap variable pages variable groups variable shift variable multicasemap if {$argc != 2} { puts stderr "\nusage: $argv0 \n" exit 1 } set f [open [lindex $argv 0] r] set data [read $f] close $f load_tables $data buildTables puts "X = [llength $pMap] Y= [llength $pages] A= [llength $groups]" set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}] puts "shift = $shift, space = $size" set f [open [file join [lindex $argv 1] uni_data.c] w] fconfigure $f -translation lf puts $f "/* * uni_data.c -- * * Declarations of Unicode character information tables. This file is * automatically generated by the uni_parse.tcl script. Do not * modify this file by hand. * * Copyright (c) 1998 by Scriptics Corporation. * All rights reserved. * * Modified for ejabberd by Alexey Shchepin * * RCS: @(#) \$Id\$ */ /* * A 16-bit Unicode character is split into two parts in order to index * into the following tables. The lower OFFSET_BITS comprise an offset * into a page of characters. The upper bits comprise the page number. */ #define OFFSET_BITS $shift /* * The pageMap is indexed by page number and returns an alternate page number * that identifies a unique page of characters. Many Unicode characters map * to the same alternate page number. */ static unsigned char pageMap\[\] = {" set line " " set last [expr {[llength $pMap] - 1}] for {set i 0} {$i <= $last} {incr i} { append line [lindex $pMap $i] if {$i != $last} { append line ", " } if {[string length $line] > 70} { puts $f $line set line " " } } puts $f $line puts $f "}; /* * The groupMap is indexed by combining the alternate page number with * the page offset and returns a group number that identifies a unique * set of character attributes. */ static unsigned short int groupMap\[\] = {" set line " " set lasti [expr {[llength $pages] - 1}] for {set i 0} {$i <= $lasti} {incr i} { set page [lindex $pages $i] set lastj [expr {[llength $page] - 1}] for {set j 0} {$j <= $lastj} {incr j} { append line [lindex $page $j] if {$j != $lastj || $i != $lasti} { append line ", " } if {[string length $line] > 70} { puts $f $line set line " " } } } puts $f $line puts $f "}; /* * Each group represents a unique set of character attributes. The attributes * are encoded into a 32-bit value as follows: * * Bit 0 A.1 | C.1.2 | C.2.2 | C.3 -- C.9 * * Bit 1 C.1.1 * * Bit 2 C.2.1 * * Bit 3 B.1 * * Bit 4 D.1 * * Bit 5 D.2 * * Bit 6 XNP * * Bit 7 Case maps to several characters * * Bits 8-10 Reserved for future use. * * Bits 11-31 Case delta: delta for case conversions. This should be the * highest field so we can easily sign extend. */ static int groups\[\] = {" set line " " set last [expr {[llength $groups] - 1}] for {set i 0} {$i <= $last} {incr i} { set val [lindex $groups $i] append line [format "%d" $val] if {$i != $last} { append line ", " } if {[string length $line] > 65} { puts $f $line set line " " } } puts $f $line puts $f "}; /* * Table for characters that lowercased to multiple ones */ static int multiCaseTable\[\]\[4\] = {" set last [expr {[llength $multicasemap] - 1}] for {set i 0} {$i <= $last} {incr i} { set val [lindex $multicasemap $i] set line " " append line [format "{%d, %s}" [llength $val] [join $val ", "]] if {$i != $last} { append line ", " } puts $f $line } puts $f "}; /* * The following constants are used to determine the category of a * Unicode character. */ #define ACMask (1 << 0) #define C11Mask (1 << 1) #define C21Mask (1 << 2) #define B1Mask (1 << 3) #define D1Mask (1 << 4) #define D2Mask (1 << 5) #define XNPMask (1 << 6) #define MCMask (1 << 7) /* * The following macros extract the fields of the character info. The * GetDelta() macro is complicated because we can't rely on the C compiler * to do sign extension on right shifts. */ #define GetCaseType(info) (((info) & 0xE0) >> 5) #define GetCategory(info) ((info) & 0x1F) #define GetDelta(info) (((info) > 0) ? ((info) >> 11) : (~(~((info)) >> 11))) #define GetMC(info) (multiCaseTable\[GetDelta(info)\]) /* * This macro extracts the information about a character from the * Unicode character tables. */ #define GetUniCharInfo(ch) (groups\[groupMap\[(pageMap\[(((int)(ch)) & 0x1fffff) >> OFFSET_BITS\] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))\]\]) " close $f } uni::main return ejabberd-2.1.11/src/stringprep/uni_parse2.tcl0000664000000000000000000004177012240230175015766 0ustar # uni_parse2.tcl -- # # This program parses the UnicodeData file and generates the # corresponding uni_norm.c file with compressed character # data tables. The input to this program should be # UnicodeData-3.2.0.txt and CompositionExclusions-3.2.0.txt files from: # ftp://ftp.unicode.org/Public/UNIDATA/ # # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # # Modified for ejabberd by Alexey Shchepin # # RCS: @(#) $Id$ namespace eval uni { set cclass_shift 8 set decomp_shift 8 set comp_shift 8 set shift 5; # number of bits of data within a page # This value can be adjusted to find the # best split to minimize table size variable pMap; # map from page to page index, each entry is # an index into the pages table, indexed by # page number variable pages; # map from page index to page info, each # entry is a list of indices into the groups # table, the list is indexed by the offset variable groups; # list of character info values, indexed by # group number, initialized with the # unassigned character group variable categories { Cn Lu Ll Lt Lm Lo Mn Me Mc Nd Nl No Zs Zl Zp Cc Cf Co Cs Pc Pd Ps Pe Pi Pf Po Sm Sc Sk So }; # Ordered list of character categories, must # match the enumeration in the header file. variable titleCount 0; # Count of the number of title case # characters. This value is used in the # regular expression code to allocate enough # space for the title case variants. } proc uni::getValue {items index} { variable categories variable titleCount # Extract character info set category [lindex $items 2] if {[scan [lindex $items 12] %4x toupper] == 1} { set toupper [expr {$index - $toupper}] } else { set toupper {} } if {[scan [lindex $items 13] %4x tolower] == 1} { set tolower [expr {$tolower - $index}] } else { set tolower {} } if {[scan [lindex $items 14] %4x totitle] == 1} { set totitle [expr {$index - $totitle}] } else { set totitle {} } set categoryIndex [lsearch -exact $categories $category] if {$categoryIndex < 0} { puts "Unexpected character category: $index($category)" set categoryIndex 0 } elseif {$category == "Lt"} { incr titleCount } return "$categoryIndex,$toupper,$tolower,$totitle" } proc uni::getGroup {value} { variable groups set gIndex [lsearch -exact $groups $value] if {$gIndex == -1} { set gIndex [llength $groups] lappend groups $value } return $gIndex } proc uni::addPage {info} { variable pMap variable pages set pIndex [lsearch -exact $pages $info] if {$pIndex == -1} { set pIndex [llength $pages] lappend pages $info } lappend pMap $pIndex return } proc uni::addPage {map_var pages_var info} { variable $map_var variable $pages_var set pIndex [lsearch -exact [set $pages_var] $info] if {$pIndex == -1} { set pIndex [llength [set $pages_var]] lappend $pages_var $info } lappend $map_var $pIndex return } proc uni::load_exclusions {data} { variable exclusions foreach line [split $data \n] { if {$line == ""} continue set items [split $line " "] if {[lindex $items 0] == "#"} continue scan [lindex $items 0] %x index set exclusions($index) "" } } proc uni::load_tables {data} { variable cclass_map variable decomp_map variable comp_map variable comp_first variable comp_second variable exclusions foreach line [split $data \n] { if {$line == ""} continue set items [split $line \;] scan [lindex $items 0] %x index set cclass [lindex $items 3] set decomp [lindex $items 5] set cclass_map($index) $cclass #set decomp_map($index) $cclass if {$decomp != ""} { if {[string index [lindex $decomp 0] 0] == "<"} { set decomp1 [lreplace $decomp 0 0] set decomp {} foreach ch $decomp1 { scan $ch %x ch lappend decomp $ch } set decomp_map($index) $decomp } else { switch -- [llength $decomp] { 1 { scan $decomp %x ch set decomp_map($index) $ch } 2 { scan $decomp "%x %x" ch1 ch2 set decomp [list $ch1 $ch2] set decomp_map($index) $decomp # hackish if {(![info exists cclass_map($ch1)] || \ $cclass_map($ch1) == 0) && \ ![info exists exclusions($index)]} { if {[info exists comp_first($ch1)]} { incr comp_first($ch1) } else { set comp_first($ch1) 1 } if {[info exists comp_second($ch2)]} { incr comp_second($ch2) } else { set comp_second($ch2) 1 } set comp_map($decomp) $index } else { puts "Excluded $index" } } default { puts "Bad canonical decomposition: $line" } } } #puts "[format 0x%0.4x $index]\t$cclass\t$decomp_map($index)" } } #puts [array get comp_first] #puts [array get comp_second] } proc uni::buildTables {} { variable cclass_shift variable decomp_shift variable comp_shift variable cclass_map variable cclass_pmap {} variable cclass_pages {} variable decomp_map variable decomp_pmap {} variable decomp_pages {} variable decomp_list {} variable comp_map variable comp_pmap {} variable comp_pages {} variable comp_first variable comp_second variable comp_first_list {} variable comp_second_list {} variable comp_x_list {} variable comp_y_list {} variable comp_both_map {} set cclass_info {} set decomp_info {} set comp_info {} set cclass_mask [expr {(1 << $cclass_shift) - 1}] set decomp_mask [expr {(1 << $decomp_shift) - 1}] set comp_mask [expr {(1 << $comp_shift) - 1}] foreach comp [array names comp_map] { set ch1 [lindex $comp 0] if {[info exists comp_first($ch1)] && $comp_first($ch1) > 0 && \ [info exists comp_second($ch1)] && $comp_second($ch1) > 0} { if {[lsearch -exact $comp_x_list $ch1] < 0} { set i [llength $comp_x_list] lappend comp_x_list $ch1 set comp_info_map($ch1) $i lappend comp_y_list $ch1 set comp_info_map($ch1) $i puts "There should be no symbols which appears on" puts "both first and second place in composition" exit } } } foreach comp [array names comp_map] { set ch1 [lindex $comp 0] set ch2 [lindex $comp 1] if {$comp_first($ch1) == 1 && ![info exists comp_second($ch1)]} { set i [llength $comp_first_list] lappend comp_first_list [list $ch2 $comp_map($comp)] set comp_info_map($ch1) [expr {$i | (1 << 16)}] } elseif {$comp_second($ch2) == 1 && ![info exists comp_first($ch2)]} { set i [llength $comp_second_list] lappend comp_second_list [list $ch1 $comp_map($comp)] set comp_info_map($ch2) [expr {$i | (1 << 16) | (1 << 17)}] } else { if {[lsearch -exact $comp_x_list $ch1] < 0} { set i [llength $comp_x_list] lappend comp_x_list $ch1 set comp_info_map($ch1) $i } if {[lsearch -exact $comp_y_list $ch2] < 0} { set i [llength $comp_y_list] lappend comp_y_list $ch2 set comp_info_map($ch2) [expr {$i | (1 << 17)}] } } } set next 0 for {set i 0} {$i <= 0x10ffff} {incr i} { #set gIndex [getGroup [getValue $i]] set cclass_offset [expr {$i & $cclass_mask}] if {[info exists cclass_map($i)]} { set cclass $cclass_map($i) } else { set cclass 0 } lappend cclass_info $cclass if {$cclass_offset == $cclass_mask} { addPage cclass_pmap cclass_pages $cclass_info set cclass_info {} } set decomp_offset [expr {$i & $decomp_mask}] if {[info exists decomp_map($i)]} { set decomp $decomp_map($i) set b 1 while {$b} { set b 0 for {set j 0} {$j < [llength $decomp]} {incr j} { if {[info exists \ decomp_map([set ch1 [lindex $decomp $j]])]} { #puts -$decomp set decomp [eval [list lreplace $decomp $j $j] \ $decomp_map($ch1)] #puts +$decomp set b 1 } } } if {[info exists decomp_used($decomp)]} { lappend decomp_info $decomp_used($decomp) } else { set val [expr {([llength $decomp] << 16) + \ [llength $decomp_list]}] #set val [expr {[llength $decomp_list]}] lappend decomp_info $val set decomp_used($decomp) $val #puts "$val $decomp" foreach d $decomp { lappend decomp_list $d } } } else { lappend decomp_info -1 } if {$decomp_offset == $decomp_mask} { addPage decomp_pmap decomp_pages $decomp_info set decomp_info {} } set comp_offset [expr {$i & $comp_mask}] if {[info exists comp_info_map($i)]} { set comp $comp_info_map($i) } else { set comp -1 } lappend comp_info $comp if {$comp_offset == $comp_mask} { addPage comp_pmap comp_pages $comp_info set comp_info {} } } #puts [array get decomp_map] #puts $decomp_list return } proc uni::main {} { global argc argv0 argv variable cclass_shift variable cclass_pmap variable cclass_pages variable decomp_shift variable decomp_pmap variable decomp_pages variable decomp_list variable comp_shift variable comp_map variable comp_pmap variable comp_pages variable comp_first_list variable comp_second_list variable comp_x_list variable comp_y_list variable pages variable groups {} variable titleCount if {$argc != 3} { puts stderr "\nusage: $argv0 \n" exit 1 } set f [open [lindex $argv 1] r] set data [read $f] close $f load_exclusions $data set f [open [lindex $argv 0] r] set data [read $f] close $f load_tables $data buildTables #puts "X = [llength $pMap] Y= [llength $pages] A= [llength $groups]" #set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}] #puts "shift = 6, space = $size" #puts "title case count = $titleCount" set f [open [file join [lindex $argv 2] uni_norm.c] w] fconfigure $f -translation lf puts $f "/* * uni_norm.c -- * * Declarations of Unicode character information tables. This file is * automatically generated by the uni_parse2.tcl script. Do not * modify this file by hand. * * Copyright (c) 1998 by Scriptics Corporation. * All rights reserved. * * Modified for ejabberd by Alexey Shchepin * * RCS: @(#) \$Id\$ */ /* * A 16-bit Unicode character is split into two parts in order to index * into the following tables. The lower CCLASS_OFFSET_BITS comprise an offset * into a page of characters. The upper bits comprise the page number. */ #define CCLASS_OFFSET_BITS $cclass_shift /* * The pageMap is indexed by page number and returns an alternate page number * that identifies a unique page of characters. Many Unicode characters map * to the same alternate page number. */ static unsigned char cclassPageMap\[\] = {" set line " " set last [expr {[llength $cclass_pmap] - 1}] for {set i 0} {$i <= $last} {incr i} { append line [lindex $cclass_pmap $i] if {$i != $last} { append line ", " } if {[string length $line] > 70} { puts $f $line set line " " } } puts $f $line puts $f "}; /* * The cclassGroupMap is indexed by combining the alternate page number with * the page offset and returns a combining class number. */ static unsigned char cclassGroupMap\[\] = {" set line " " set lasti [expr {[llength $cclass_pages] - 1}] for {set i 0} {$i <= $lasti} {incr i} { set page [lindex $cclass_pages $i] set lastj [expr {[llength $page] - 1}] for {set j 0} {$j <= $lastj} {incr j} { append line [lindex $page $j] if {$j != $lastj || $i != $lasti} { append line ", " } if {[string length $line] > 70} { puts $f $line set line " " } } } puts $f $line puts $f "}; #define GetUniCharCClass(ch) (cclassGroupMap\[(cclassPageMap\[(((int)(ch)) & 0x1fffff) >> CCLASS_OFFSET_BITS\] << CCLASS_OFFSET_BITS) | ((ch) & ((1 << CCLASS_OFFSET_BITS)-1))\]) #define DECOMP_OFFSET_BITS $decomp_shift /* * The pageMap is indexed by page number and returns an alternate page number * that identifies a unique page of characters. Many Unicode characters map * to the same alternate page number. */ static unsigned char decompPageMap\[\] = {" set line " " set last [expr {[llength $decomp_pmap] - 1}] for {set i 0} {$i <= $last} {incr i} { append line [lindex $decomp_pmap $i] if {$i != $last} { append line ", " } if {[string length $line] > 70} { puts $f $line set line " " } } puts $f $line puts $f "}; /* * The decompGroupMap is indexed by combining the alternate page number with * the page offset and returns a group number that identifies a length and * shift of decomposition sequence in decompList */ static int decompGroupMap\[\] = {" set line " " set lasti [expr {[llength $decomp_pages] - 1}] for {set i 0} {$i <= $lasti} {incr i} { set page [lindex $decomp_pages $i] set lastj [expr {[llength $page] - 1}] for {set j 0} {$j <= $lastj} {incr j} { append line [lindex $page $j] if {$j != $lastj || $i != $lasti} { append line ", " } if {[string length $line] > 70} { puts $f $line set line " " } } } puts $f $line puts $f "}; /* * List of decomposition sequences */ static int decompList\[\] = {" set line " " set last [expr {[llength $decomp_list] - 1}] for {set i 0} {$i <= $last} {incr i} { set val [lindex $decomp_list $i] append line [format "%d" $val] if {$i != $last} { append line ", " } if {[string length $line] > 70} { puts $f $line set line " " } } puts $f $line puts $f "}; /* * This macro extracts the information about a character from the * Unicode character tables. */ #define GetUniCharDecompInfo(ch) (decompGroupMap\[(decompPageMap\[(((int)(ch)) & 0x1fffff) >> DECOMP_OFFSET_BITS\] << DECOMP_OFFSET_BITS) | ((ch) & ((1 << DECOMP_OFFSET_BITS)-1))\]) #define GetDecompShift(info) ((info) & 0xffff) #define GetDecompLen(info) ((info) >> 16) #define COMP_OFFSET_BITS $comp_shift /* * The pageMap is indexed by page number and returns an alternate page number * that identifies a unique page of characters. Many Unicode characters map * to the same alternate page number. */ static unsigned char compPageMap\[\] = {" set line " " set last [expr {[llength $comp_pmap] - 1}] for {set i 0} {$i <= $last} {incr i} { append line [lindex $comp_pmap $i] if {$i != $last} { append line ", " } if {[string length $line] > 70} { puts $f $line set line " " } } puts $f $line puts $f "}; /* * The groupMap is indexed by combining the alternate page number with * the page offset and returns a group number that identifies a unique * set of character attributes. */ static int compGroupMap\[\] = {" set line " " set lasti [expr {[llength $comp_pages] - 1}] for {set i 0} {$i <= $lasti} {incr i} { set page [lindex $comp_pages $i] set lastj [expr {[llength $page] - 1}] for {set j 0} {$j <= $lastj} {incr j} { append line [lindex $page $j] if {$j != $lastj || $i != $lasti} { append line ", " } if {[string length $line] > 70} { puts $f $line set line " " } } } puts $f $line puts $f "}; /* * Lists of compositions for characters that appears only in one composition */ static int compFirstList\[\]\[2\] = {" set line " " set last [expr {[llength $comp_first_list] - 1}] for {set i 0} {$i <= $last} {incr i} { set val [lindex $comp_first_list $i] append line [format "{%d, %d}" [lindex $val 0] [lindex $val 1]] if {$i != $last} { append line ", " } if {[string length $line] > 60} { puts $f $line set line " " } } puts $f $line puts $f "}; static int compSecondList\[\]\[2\] = {" set line " " set last [expr {[llength $comp_second_list] - 1}] for {set i 0} {$i <= $last} {incr i} { set val [lindex $comp_second_list $i] append line [format "{%d, %d}" [lindex $val 0] [lindex $val 1]] if {$i != $last} { append line ", " } if {[string length $line] > 60} { puts $f $line set line " " } } puts $f $line puts $f "}; /* * Compositions matrix */ static int compBothList\[[llength $comp_x_list]\]\[[llength $comp_y_list]\] = {" set lastx [expr {[llength $comp_x_list] - 1}] set lasty [expr {[llength $comp_y_list] - 1}] for {set i 0} {$i <= $lastx} {incr i} { puts $f " \{" set line " " for {set j 0} {$j <= $lasty} {incr j} { set comp [list [lindex $comp_x_list $i] [lindex $comp_y_list $j]] if {[info exists comp_map($comp)]} { set val $comp_map($comp) } else { set val 0 } append line [format "%d" $val] if {$j != $lasty} { append line ", " } if {[string length $line] > 70} { puts $f $line set line " " } } puts $f $line if {$j != $lasty} { puts $f " \}," } else { puts $f " \}" } } puts $f "}; #define GetUniCharCompInfo(ch) (compGroupMap\[(compPageMap\[(((int)(ch)) & 0x1fffff) >> COMP_OFFSET_BITS\] << COMP_OFFSET_BITS) | ((ch) & ((1 << COMP_OFFSET_BITS)-1))\]) #define CompSingleMask (1 << 16) #define CompMask ((1 << 16) - 1) #define CompSecondMask (1 << 17) " close $f } uni::main return ejabberd-2.1.11/src/stringprep/uni_data.c0000664000000000000000000023174112240230175015142 0ustar /* * uni_data.c -- * * Declarations of Unicode character information tables. This file is * automatically generated by the uni_parse.tcl script. Do not * modify this file by hand. * * Copyright (c) 1998 by Scriptics Corporation. * All rights reserved. * * Modified for ejabberd by Alexey Shchepin * * RCS: @(#) $Id$ */ /* * A 16-bit Unicode character is split into two parts in order to index * into the following tables. The lower OFFSET_BITS comprise an offset * into a page of characters. The upper bits comprise the page number. */ #define OFFSET_BITS 8 /* * The pageMap is indexed by page number and returns an alternate page number * that identifies a unique page of characters. Many Unicode characters map * to the same alternate page number. */ static unsigned char pageMap[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 8, 8, 8, 8, 8, 25, 26, 27, 28, 29, 30, 31, 29, 32, 33, 29, 29, 29, 8, 8, 8, 34, 35, 36, 37, 38, 39, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 40, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 41, 21, 21, 21, 21, 42, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 21, 45, 46, 47, 48, 49, 50, 8, 8, 8, 51, 52, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 53, 54, 8, 8, 55, 56, 57, 58, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 59, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 21, 21, 60, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 61, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 61 }; /* * The groupMap is indexed by combining the alternate page number with * the page offset and returns a group number that identifies a unique * set of character attributes. */ static unsigned short int groupMap[] = { 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, 1, 2, 3, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 7, 2, 2, 2, 2, 2, 2, 2, 8, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 9, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 11, 5, 10, 5, 10, 5, 10, 5, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 12, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 13, 10, 5, 10, 5, 10, 5, 14, 5, 15, 10, 5, 10, 5, 16, 10, 5, 17, 17, 10, 5, 5, 18, 19, 20, 10, 5, 17, 21, 5, 22, 23, 10, 5, 5, 5, 22, 24, 5, 25, 10, 5, 10, 5, 10, 5, 26, 10, 5, 26, 5, 5, 10, 5, 26, 10, 5, 27, 27, 10, 5, 10, 5, 28, 10, 5, 5, 5, 10, 5, 5, 5, 5, 5, 5, 5, 29, 10, 5, 29, 10, 5, 29, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 30, 29, 10, 5, 10, 5, 31, 32, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 33, 6, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 34, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 6, 6, 35, 6, 6, 6, 2, 6, 6, 6, 6, 6, 2, 2, 36, 2, 37, 37, 37, 6, 38, 6, 39, 39, 40, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 41, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 42, 43, 44, 45, 46, 47, 48, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 49, 50, 51, 5, 52, 53, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 5, 2, 2, 2, 2, 6, 2, 2, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6, 6, 10, 5, 6, 6, 6, 6, 6, 6, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 56, 6, 5, 2, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 57, 2, 57, 2, 2, 57, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 6, 6, 57, 57, 57, 57, 57, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 57, 6, 6, 6, 57, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 2, 2, 2, 2, 2, 58, 2, 2, 2, 2, 2, 2, 2, 57, 57, 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 57, 57, 57, 57, 57, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 57, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 2, 6, 6, 5, 2, 2, 2, 2, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 6, 6, 5, 5, 5, 5, 6, 6, 2, 6, 5, 5, 5, 2, 2, 2, 2, 6, 6, 5, 5, 6, 6, 5, 5, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 5, 5, 6, 5, 5, 5, 2, 2, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 2, 6, 6, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 5, 5, 6, 5, 5, 6, 6, 2, 6, 5, 5, 5, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 5, 5, 5, 5, 5, 6, 6, 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 6, 2, 2, 5, 6, 5, 5, 2, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 6, 5, 5, 5, 5, 6, 6, 2, 5, 5, 2, 5, 2, 2, 2, 6, 6, 6, 5, 5, 6, 6, 5, 5, 2, 6, 6, 6, 6, 6, 6, 6, 6, 2, 5, 6, 6, 6, 6, 5, 5, 6, 5, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 5, 6, 5, 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 6, 5, 5, 5, 5, 6, 6, 6, 5, 5, 6, 5, 6, 5, 5, 6, 6, 6, 5, 5, 6, 6, 6, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 6, 6, 6, 5, 5, 2, 5, 5, 6, 6, 6, 5, 5, 5, 6, 5, 5, 5, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 6, 6, 6, 6, 2, 2, 2, 5, 5, 5, 5, 6, 2, 2, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 2, 5, 5, 5, 5, 5, 6, 2, 5, 5, 6, 5, 5, 2, 2, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 6, 6, 6, 6, 6, 6, 5, 6, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5, 5, 2, 2, 2, 6, 6, 5, 5, 5, 6, 5, 5, 5, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 2, 6, 6, 6, 6, 5, 5, 5, 2, 2, 2, 6, 2, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 2, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 6, 5, 6, 6, 5, 5, 6, 5, 6, 6, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 5, 6, 5, 6, 6, 5, 5, 6, 5, 5, 5, 5, 2, 5, 5, 2, 2, 2, 2, 2, 2, 6, 2, 2, 5, 6, 6, 5, 5, 5, 5, 5, 6, 5, 6, 2, 2, 2, 2, 2, 2, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 5, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 5, 2, 2, 5, 5, 5, 5, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 6, 5, 5, 6, 5, 2, 2, 2, 2, 5, 2, 6, 6, 6, 2, 2, 5, 2, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 6, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 2, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 7, 2, 2, 2, 2, 7, 7, 7, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 59, 60, 61, 62, 63, 64, 6, 6, 6, 6, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 10, 5, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 65, 65, 65, 65, 65, 65, 65, 65, 5, 5, 5, 5, 5, 5, 6, 6, 65, 65, 65, 65, 65, 65, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 65, 65, 65, 65, 65, 65, 65, 65, 5, 5, 5, 5, 5, 5, 5, 5, 65, 65, 65, 65, 65, 65, 65, 65, 5, 5, 5, 5, 5, 5, 6, 6, 65, 65, 65, 65, 65, 65, 6, 6, 66, 5, 67, 5, 68, 5, 69, 5, 6, 65, 6, 65, 6, 65, 6, 65, 5, 5, 5, 5, 5, 5, 5, 5, 65, 65, 65, 65, 65, 65, 65, 65, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 5, 5, 118, 119, 120, 6, 121, 122, 65, 65, 123, 123, 124, 2, 125, 2, 2, 2, 126, 127, 128, 6, 129, 130, 131, 131, 131, 131, 132, 2, 2, 2, 5, 5, 133, 134, 6, 6, 135, 136, 65, 65, 137, 137, 6, 2, 2, 2, 5, 5, 138, 139, 140, 5, 141, 142, 65, 65, 143, 143, 144, 2, 2, 2, 6, 6, 145, 146, 147, 6, 148, 149, 150, 150, 151, 151, 152, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 153, 153, 153, 154, 58, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 2, 6, 6, 6, 6, 6, 6, 6, 6, 153, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 5, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 155, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 156, 157, 2, 2, 2, 158, 2, 159, 5, 160, 161, 162, 5, 5, 163, 164, 165, 5, 2, 163, 166, 2, 2, 167, 167, 167, 168, 169, 2, 2, 170, 171, 172, 2, 168, 2, 173, 2, 174, 2, 175, 176, 177, 177, 2, 5, 178, 178, 2, 179, 5, 5, 5, 5, 5, 5, 2, 6, 6, 5, 180, 181, 2, 2, 2, 2, 2, 182, 5, 5, 5, 5, 2, 2, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 6, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 6, 2, 2, 2, 2, 6, 6, 6, 2, 6, 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 2, 2, 2, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 2, 2, 2, 2, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 185, 5, 186, 5, 187, 5, 6, 6, 6, 6, 5, 5, 5, 5, 5, 188, 189, 190, 191, 192, 193, 194, 195, 5, 5, 196, 197, 198, 5, 5, 5, 199, 200, 201, 202, 203, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 204, 205, 206, 207, 5, 5, 5, 5, 5, 5, 5, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 5, 222, 5, 5, 5, 223, 224, 225, 5, 226, 5, 227, 228, 5, 5, 5, 5, 5, 5, 5, 5, 229, 5, 230, 231, 5, 232, 233, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 234, 235, 236, 237, 238, 239, 240, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 241, 242, 243, 244, 245, 6, 6, 6, 6, 6, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 57, 57, 57, 57, 57, 6, 57, 6, 57, 57, 6, 57, 57, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6, 57, 57, 57, 57, 57, 6, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 6, 6, 153, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 5, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2, 2, 2, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 250, 6, 250, 250, 6, 6, 250, 6, 6, 250, 250, 6, 6, 250, 250, 250, 250, 6, 250, 250, 250, 250, 250, 250, 250, 250, 5, 5, 5, 5, 6, 5, 6, 5, 5, 5, 5, 6, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 252, 252, 6, 252, 252, 252, 252, 6, 6, 252, 252, 252, 252, 252, 252, 252, 252, 6, 252, 252, 252, 252, 252, 252, 252, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 253, 253, 6, 253, 253, 253, 253, 6, 253, 253, 253, 253, 253, 6, 253, 6, 6, 6, 253, 253, 253, 253, 253, 253, 253, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 260, 260, 260, 260, 260, 260, 260, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 262, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 264, 263, 263, 263, 263, 263, 263, 263, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 265, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 267, 266, 266, 266, 266, 266, 266, 266, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 268, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 270, 269, 269, 269, 269, 269, 269, 269, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 271, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 273, 272, 272, 272, 272, 272, 272, 272, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 274, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 6, 6 }; /* * Each group represents a unique set of character attributes. The attributes * are encoded into a 32-bit value as follows: * * Bit 0 A.1 | C.1.2 | C.2.2 | C.3 -- C.9 * * Bit 1 C.1.1 * * Bit 2 C.2.1 * * Bit 3 B.1 * * Bit 4 D.1 * * Bit 5 D.2 * * Bit 6 XNP * * Bit 7 Case maps to several characters * * Bits 8-10 Reserved for future use. * * Bits 11-31 Case delta: delta for case conversions. This should be the * highest field so we can easily sign extend. */ static int groups[] = { 4, 2, 0, 64, 65568, 32, 1, 8, 1587232, 160, 2080, 2208, 4256, -247776, -548832, 430112, 421920, 419872, 161824, 413728, 415776, 423968, 432160, 428064, 436256, 438304, 446496, 444448, 448544, 4128, 6304, -198624, -114656, -266208, 237568, 8352, 77856, 75808, 131104, 129056, 10400, 12448, -61408, -51168, -26592, -12256, -18400, -30688, -45024, -110560, -98272, -96224, -122848, -131040, 163872, 98336, 14496, 16, 17, 16544, 18592, 20640, 22688, 24736, -118752, -16352, 26784, 28832, 30880, 32928, 34976, 37024, 39072, 41120, 43168, 45216, 47264, 49312, 51360, 53408, 55456, 57504, 59552, 61600, 63648, 65696, 67744, 69792, 71840, 73888, 75936, 77984, 80032, 82080, 84128, 86176, 88224, 90272, 92320, 94368, 96416, 98464, 100512, 102560, 104608, 106656, 108704, 110752, 112800, 114848, 116896, 118944, 120992, 123040, 125088, 127136, 129184, 131232, 133280, 135328, 137376, 139424, 141472, -151520, 143520, -14690272, 145568, 147616, 149664, 151712, 153760, -176096, 155808, 157856, 159904, 161952, 164000, -204768, 166048, 168096, 170144, 172192, 174240, -229344, -14304, 176288, 178336, 180384, 182432, 184480, -262112, -258016, 186528, 9, 33, 188544, -17102816, 190592, -16080864, 192640, -17111008, -17113056, -17115104, -17119200, -17121248, -17117152, 194688, -17123296, -17125344, -17127392, 196736, 198784, 200832, -15394784, -17133536, -17168352, -16920544, -17190880, -17192928, -17182688, -15488992, -15464416, -17237984, 32800, 53280, 202912, 204960, 207008, 209056, 211104, 213152, 215200, 217248, 219296, 221344, 223392, 225440, 227488, 229536, 231584, 233632, 235680, 237728, 239776, 241824, 243872, 245920, 247968, 250016, 252064, 254112, 256160, 258208, 260256, 262304, 264352, 266400, 268448, 270496, 272544, 274592, 276640, 278688, 280736, 282784, 284832, 286880, 288928, 290976, 293024, 295072, 297120, 299168, 301216, 303264, 305312, 307360, 309408, 311456, 313504, 315552, 317600, 319648, 321696, 323744, 325792, 81952, -245168096, -245274592, -245381088, -245487584, -245594080, -245700576, -245807072, -245913568, -246020064, -246126560, -246233056, -246339552, -246446048, -244824032, -244844512, -244875232, -244942816, -244963296, -244994016, -245061600, -245082080, -245112800, -245180384, -245200864, -245231584, -245299168, -245319648, -245350368 }; /* * Table for characters that lowercased to multiple ones */ static int multiCaseTable[][4] = { {2, 115, 115}, {2, 105, 775}, {2, 700, 110}, {2, 106, 780}, {2, 32, 953}, {3, 953, 776, 769}, {3, 965, 776, 769}, {2, 1381, 1410}, {2, 104, 817}, {2, 116, 776}, {2, 119, 778}, {2, 121, 778}, {2, 97, 702}, {2, 965, 787}, {3, 965, 787, 768}, {3, 965, 787, 769}, {3, 965, 787, 834}, {2, 7936, 953}, {2, 7937, 953}, {2, 7938, 953}, {2, 7939, 953}, {2, 7940, 953}, {2, 7941, 953}, {2, 7942, 953}, {2, 7943, 953}, {2, 7936, 953}, {2, 7937, 953}, {2, 7938, 953}, {2, 7939, 953}, {2, 7940, 953}, {2, 7941, 953}, {2, 7942, 953}, {2, 7943, 953}, {2, 7968, 953}, {2, 7969, 953}, {2, 7970, 953}, {2, 7971, 953}, {2, 7972, 953}, {2, 7973, 953}, {2, 7974, 953}, {2, 7975, 953}, {2, 7968, 953}, {2, 7969, 953}, {2, 7970, 953}, {2, 7971, 953}, {2, 7972, 953}, {2, 7973, 953}, {2, 7974, 953}, {2, 7975, 953}, {2, 8032, 953}, {2, 8033, 953}, {2, 8034, 953}, {2, 8035, 953}, {2, 8036, 953}, {2, 8037, 953}, {2, 8038, 953}, {2, 8039, 953}, {2, 8032, 953}, {2, 8033, 953}, {2, 8034, 953}, {2, 8035, 953}, {2, 8036, 953}, {2, 8037, 953}, {2, 8038, 953}, {2, 8039, 953}, {2, 8048, 953}, {2, 945, 953}, {2, 940, 953}, {2, 945, 834}, {3, 945, 834, 953}, {2, 945, 953}, {2, 8052, 953}, {2, 951, 953}, {2, 942, 953}, {2, 951, 834}, {3, 951, 834, 953}, {2, 951, 953}, {3, 953, 776, 768}, {3, 953, 776, 769}, {2, 953, 834}, {3, 953, 776, 834}, {3, 965, 776, 768}, {3, 965, 776, 769}, {2, 961, 787}, {2, 965, 834}, {3, 965, 776, 834}, {2, 8060, 953}, {2, 969, 953}, {2, 974, 953}, {2, 969, 834}, {3, 969, 834, 953}, {2, 969, 953}, {2, 114, 115}, {2, 176, 99}, {2, 176, 102}, {2, 110, 111}, {2, 115, 109}, {3, 116, 101, 108}, {2, 116, 109}, {3, 104, 112, 97}, {2, 97, 117}, {2, 111, 118}, {2, 112, 97}, {2, 110, 97}, {2, 956, 97}, {2, 109, 97}, {2, 107, 97}, {2, 107, 98}, {2, 109, 98}, {2, 103, 98}, {2, 112, 102}, {2, 110, 102}, {2, 956, 102}, {2, 104, 122}, {3, 107, 104, 122}, {3, 109, 104, 122}, {3, 103, 104, 122}, {3, 116, 104, 122}, {2, 112, 97}, {3, 107, 112, 97}, {3, 109, 112, 97}, {3, 103, 112, 97}, {2, 112, 118}, {2, 110, 118}, {2, 956, 118}, {2, 109, 118}, {2, 107, 118}, {2, 109, 118}, {2, 112, 119}, {2, 110, 119}, {2, 956, 119}, {2, 109, 119}, {2, 107, 119}, {2, 109, 119}, {2, 107, 969}, {2, 109, 969}, {2, 98, 113}, {3, 99, 111, 46}, {2, 100, 98}, {2, 103, 121}, {2, 104, 112}, {2, 107, 107}, {2, 107, 109}, {2, 112, 104}, {3, 112, 112, 109}, {2, 112, 114}, {2, 115, 118}, {2, 119, 98}, {2, 102, 102}, {2, 102, 105}, {2, 102, 108}, {3, 102, 102, 105}, {3, 102, 102, 108}, {2, 115, 116}, {2, 115, 116}, {2, 1396, 1398}, {2, 1396, 1381}, {2, 1396, 1387}, {2, 1406, 1398}, {2, 1396, 1389} }; /* * The following constants are used to determine the category of a * Unicode character. */ #define ACMask (1 << 0) #define C11Mask (1 << 1) #define C21Mask (1 << 2) #define B1Mask (1 << 3) #define D1Mask (1 << 4) #define D2Mask (1 << 5) #define XNPMask (1 << 6) #define MCMask (1 << 7) /* * The following macros extract the fields of the character info. The * GetDelta() macro is complicated because we can't rely on the C compiler * to do sign extension on right shifts. */ #define GetCaseType(info) (((info) & 0xE0) >> 5) #define GetCategory(info) ((info) & 0x1F) #define GetDelta(info) (((info) > 0) ? ((info) >> 11) : (~(~((info)) >> 11))) #define GetMC(info) (multiCaseTable[GetDelta(info)]) /* * This macro extracts the information about a character from the * Unicode character tables. */ #define GetUniCharInfo(ch) (groups[groupMap[(pageMap[(((int)(ch)) & 0x1fffff) >> OFFSET_BITS] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))]]) ejabberd-2.1.11/src/ejabberd_frontend_socket.erl0000664000000000000000000002605212240230175016523 0ustar %%%------------------------------------------------------------------- %%% File : ejabberd_frontend_socket.erl %%% Author : Alexey Shchepin %%% Purpose : Frontend socket with zlib and TLS support library %%% Created : 23 Aug 2006 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_frontend_socket). -author('alexey@process-one.net'). -behaviour(gen_server). %% API -export([start/4, start_link/5, %connect/3, starttls/2, starttls/3, compress/1, compress/2, reset_stream/1, send/2, change_shaper/2, monitor/1, get_sockmod/1, get_peer_certificate/1, get_verify_result/1, close/1, sockname/1, peername/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -record(state, {sockmod, socket, receiver}). -define(HIBERNATE_TIMEOUT, 90000). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Module, SockMod, Socket, Opts, Receiver) -> gen_server:start_link(?MODULE, [Module, SockMod, Socket, Opts, Receiver], []). start(Module, SockMod, Socket, Opts) -> case Module:socket_type() of xml_stream -> MaxStanzaSize = case lists:keysearch(max_stanza_size, 1, Opts) of {value, {_, Size}} -> Size; _ -> infinity end, Receiver = ejabberd_receiver:start(Socket, SockMod, none, MaxStanzaSize), case SockMod:controlling_process(Socket, Receiver) of ok -> ok; {error, _Reason} -> SockMod:close(Socket) end, supervisor:start_child(ejabberd_frontend_socket_sup, [Module, SockMod, Socket, Opts, Receiver]); raw -> %{ok, Pid} = Module:start({SockMod, Socket}, Opts), %case SockMod:controlling_process(Socket, Pid) of % ok -> % ok; % {error, _Reason} -> % SockMod:close(Socket) %end todo end. starttls(FsmRef, _TLSOpts) -> %% TODO: Frontend improvements planned by Aleksey %%gen_server:call(FsmRef, {starttls, TLSOpts}), FsmRef. starttls(FsmRef, TLSOpts, Data) -> gen_server:call(FsmRef, {starttls, TLSOpts, Data}), FsmRef. compress(FsmRef) -> gen_server:call(FsmRef, compress), FsmRef. compress(FsmRef, Data) -> gen_server:call(FsmRef, {compress, Data}), FsmRef. reset_stream(FsmRef) -> gen_server:call(FsmRef, reset_stream). send(FsmRef, Data) -> gen_server:call(FsmRef, {send, Data}). change_shaper(FsmRef, Shaper) -> gen_server:call(FsmRef, {change_shaper, Shaper}). monitor(FsmRef) -> erlang:monitor(process, FsmRef). get_sockmod(FsmRef) -> gen_server:call(FsmRef, get_sockmod). get_peer_certificate(FsmRef) -> gen_server:call(FsmRef, get_peer_certificate). get_verify_result(FsmRef) -> gen_server:call(FsmRef, get_verify_result). close(FsmRef) -> gen_server:call(FsmRef, close). sockname(FsmRef) -> gen_server:call(FsmRef, sockname). peername(_FsmRef) -> %% TODO: Frontend improvements planned by Aleksey %%gen_server:call(FsmRef, peername). {ok, {{0, 0, 0, 0}, 0}}. %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([Module, SockMod, Socket, Opts, Receiver]) -> %% TODO: monitor the receiver Node = ejabberd_node_groups:get_closest_node(backend), {SockMod2, Socket2} = check_starttls(SockMod, Socket, Receiver, Opts), {ok, Pid} = rpc:call(Node, Module, start, [{?MODULE, self()}, Opts]), ejabberd_receiver:become_controller(Receiver, Pid), {ok, #state{sockmod = SockMod2, socket = Socket2, receiver = Receiver}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call({starttls, TLSOpts}, _From, State) -> {ok, TLSSocket} = tls:tcp_to_tls(State#state.socket, TLSOpts), ejabberd_receiver:starttls(State#state.receiver, TLSSocket), Reply = ok, {reply, Reply, State#state{socket = TLSSocket, sockmod = tls}, ?HIBERNATE_TIMEOUT}; handle_call({starttls, TLSOpts, Data}, _From, State) -> {ok, TLSSocket} = tls:tcp_to_tls(State#state.socket, TLSOpts), ejabberd_receiver:starttls(State#state.receiver, TLSSocket), catch (State#state.sockmod):send( State#state.socket, Data), Reply = ok, {reply, Reply, State#state{socket = TLSSocket, sockmod = tls}, ?HIBERNATE_TIMEOUT}; handle_call(compress, _From, State) -> {ok, ZlibSocket} = ejabberd_zlib:enable_zlib( State#state.sockmod, State#state.socket), ejabberd_receiver:compress(State#state.receiver, ZlibSocket), Reply = ok, {reply, Reply, State#state{socket = ZlibSocket, sockmod = ejabberd_zlib}, ?HIBERNATE_TIMEOUT}; handle_call({compress, Data}, _From, State) -> {ok, ZlibSocket} = ejabberd_zlib:enable_zlib( State#state.sockmod, State#state.socket), ejabberd_receiver:compress(State#state.receiver, ZlibSocket), catch (State#state.sockmod):send( State#state.socket, Data), Reply = ok, {reply, Reply, State#state{socket = ZlibSocket, sockmod = ejabberd_zlib}, ?HIBERNATE_TIMEOUT}; handle_call(reset_stream, _From, State) -> ejabberd_receiver:reset_stream(State#state.receiver), Reply = ok, {reply, Reply, State, ?HIBERNATE_TIMEOUT}; handle_call({send, Data}, _From, State) -> catch (State#state.sockmod):send( State#state.socket, Data), Reply = ok, {reply, Reply, State, ?HIBERNATE_TIMEOUT}; handle_call({change_shaper, Shaper}, _From, State) -> ejabberd_receiver:change_shaper(State#state.receiver, Shaper), Reply = ok, {reply, Reply, State, ?HIBERNATE_TIMEOUT}; handle_call(get_sockmod, _From, State) -> Reply = State#state.sockmod, {reply, Reply, State, ?HIBERNATE_TIMEOUT}; handle_call(get_peer_certificate, _From, State) -> Reply = tls:get_peer_certificate(State#state.socket), {reply, Reply, State, ?HIBERNATE_TIMEOUT}; handle_call(get_verify_result, _From, State) -> Reply = tls:get_verify_result(State#state.socket), {reply, Reply, State, ?HIBERNATE_TIMEOUT}; handle_call(close, _From, State) -> ejabberd_receiver:close(State#state.receiver), Reply = ok, {stop, normal, Reply, State}; handle_call(sockname, _From, State) -> #state{sockmod = SockMod, socket = Socket} = State, Reply = case SockMod of gen_tcp -> inet:sockname(Socket); _ -> SockMod:sockname(Socket) end, {reply, Reply, State, ?HIBERNATE_TIMEOUT}; handle_call(peername, _From, State) -> #state{sockmod = SockMod, socket = Socket} = State, Reply = case SockMod of gen_tcp -> inet:peername(Socket); _ -> SockMod:peername(Socket) end, {reply, Reply, State, ?HIBERNATE_TIMEOUT}; handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State, ?HIBERNATE_TIMEOUT}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State, ?HIBERNATE_TIMEOUT}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info(timeout, State) -> proc_lib:hibernate(gen_server, enter_loop, [?MODULE, [], State]), {noreply, State, ?HIBERNATE_TIMEOUT}; handle_info(_Info, State) -> {noreply, State, ?HIBERNATE_TIMEOUT}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- check_starttls(SockMod, Socket, Receiver, Opts) -> TLSEnabled = lists:member(tls, Opts), TLSOpts = lists:filter(fun({certfile, _}) -> true; (_) -> false end, Opts), if TLSEnabled -> {ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts), ejabberd_receiver:starttls(Receiver, TLSSocket), {tls, TLSSocket}; true -> {SockMod, Socket} end. ejabberd-2.1.11/src/mod_echo.erl0000664000000000000000000002022312240230175013265 0ustar %%%---------------------------------------------------------------------- %%% File : mod_echo.erl %%% Author : Alexey Shchepin %%% Purpose : Simple ejabberd module. %%% Created : 15 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_echo). -author('alexey@process-one.net'). -behaviour(gen_server). -behaviour(gen_mod). %% API -export([start_link/2, start/2, stop/1, do_client_version/3]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -record(state, {host}). -define(PROCNAME, ejabberd_mod_echo). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, temporary, 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:call(Proc, stop), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([Host, Opts]) -> MyHost = gen_mod:get_opt_host(Host, Opts, "echo.@HOST@"), ejabberd_router:register_route(MyHost), {ok, #state{host = MyHost}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call(stop, _From, State) -> {stop, normal, ok, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({route, From, To, Packet}, State) -> Packet2 = case From#jid.user of "" -> jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST); _ -> Packet end, do_client_version(disabled, To, From), % Put 'enabled' to enable it ejabberd_router:route(To, From, Packet2), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, State) -> ejabberd_router:unregister_route(State#state.host), ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %% Example of routing XMPP packets using Erlang's message passing %%-------------------------------------------------------------------- %% To enable this educational example, edit the function handle_info: %% replace the argument 'disabled' with 'enabled' in the call to the %% function do_client_version. %% ejabberd provides a method to receive XMPP packets using Erlang's %% message passing mechanism. %% %% The packets received by ejabberd are sent %% to the local destination process by sending an Erlang message. %% This means that you can receive XMPP stanzas in an Erlang process %% using Erlang's Receive, as long as this process is registered in %% ejabberd as the process which handles the destination JID. %% %% This example function is called when a client queries the echo service. %% This function then sends a query to the client, and waits 5 seconds to %% receive an answer. The answer will only be accepted if it was sent %% using exactly the same JID. We add a (mostly) random resource to %% try to guarantee that the received response matches the request sent. %% Finally, the received response is printed in the ejabberd log file. do_client_version(disabled, _From, _To) -> ok; do_client_version(enabled, From, To) -> ToS = jlib:jid_to_string(To), %% It is important to identify this process and packet Random_resource = integer_to_list(random:uniform(100000)), From2 = From#jid{resource = Random_resource, lresource = Random_resource}, %% Build an iq:query request Packet = {xmlelement, "iq", [{"to", ToS}, {"type", "get"}], [{xmlelement, "query", [{"xmlns", ?NS_VERSION}], []}]}, %% Send the request ejabberd_router:route(From2, To, Packet), %% Wait to receive the response %% It is very important to only accept a packet which is the %% response to the request that he sent Els = receive {route, To, From2, IQ} -> {xmlelement, "query", _, List} = xml:get_subtag(IQ, "query"), List after 5000 -> % Timeout in miliseconds: 5 seconds [] end, Values = [{Name, Value} || {xmlelement,Name,[],[{xmlcdata,Value}]} <- Els], %% Print in log Values_string1 = [io_lib:format("~n~s: ~p", [N, V]) || {N, V} <- Values], Values_string2 = lists:concat(Values_string1), ?INFO_MSG("Information of the client: ~s~s", [ToS, Values_string2]). ejabberd-2.1.11/src/ejabberd_local.erl0000664000000000000000000002747512240230175014440 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_local.erl %%% Author : Alexey Shchepin %%% Purpose : Route local packets %%% Created : 30 Nov 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_local). -author('alexey@process-one.net'). -behaviour(gen_server). %% API -export([start_link/0]). -export([route/3, route_iq/4, route_iq/5, process_iq_reply/3, register_iq_handler/4, register_iq_handler/5, register_iq_response_handler/4, register_iq_response_handler/5, unregister_iq_handler/2, unregister_iq_response_handler/2, refresh_iq_handlers/0, bounce_resource_packet/3 ]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -record(state, {}). -record(iq_response, {id, module, function, timer}). -define(IQTABLE, local_iqtable). %% This value is used in SIP and Megaco for a transaction lifetime. -define(IQ_TIMEOUT, 32000). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). process_iq(From, To, Packet) -> IQ = jlib:iq_query_info(Packet), case IQ of #iq{xmlns = XMLNS} -> Host = To#jid.lserver, case ets:lookup(?IQTABLE, {XMLNS, Host}) of [{_, Module, Function}] -> ResIQ = Module:Function(From, To, IQ), if ResIQ /= ignore -> ejabberd_router:route( To, From, jlib:iq_to_xml(ResIQ)); true -> ok end; [{_, Module, Function, Opts}] -> gen_iq_handler:handle(Host, Module, Function, Opts, From, To, IQ); [] -> Err = jlib:make_error_reply( Packet, ?ERR_FEATURE_NOT_IMPLEMENTED), ejabberd_router:route(To, From, Err) end; reply -> IQReply = jlib:iq_query_or_response_info(Packet), process_iq_reply(From, To, IQReply); _ -> Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST), ejabberd_router:route(To, From, Err), ok end. process_iq_reply(From, To, #iq{id = ID} = IQ) -> case get_iq_callback(ID) of {ok, undefined, Function} -> Function(IQ), ok; {ok, Module, Function} -> Module:Function(From, To, IQ), ok; _ -> nothing end. route(From, To, Packet) -> case catch do_route(From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p~nwhen processing: ~p", [Reason, {From, To, Packet}]); _ -> ok end. route_iq(From, To, IQ, F) -> route_iq(From, To, IQ, F, undefined). route_iq(From, To, #iq{type = Type} = IQ, F, Timeout) when is_function(F) -> Packet = if Type == set; Type == get -> ID = randoms:get_string(), Host = From#jid.lserver, register_iq_response_handler(Host, ID, undefined, F, Timeout), jlib:iq_to_xml(IQ#iq{id = ID}); true -> jlib:iq_to_xml(IQ) end, ejabberd_router:route(From, To, Packet). register_iq_response_handler(Host, ID, Module, Function) -> register_iq_response_handler(Host, ID, Module, Function, undefined). register_iq_response_handler(_Host, ID, Module, Function, Timeout0) -> Timeout = case Timeout0 of undefined -> ?IQ_TIMEOUT; N when is_integer(N), N > 0 -> N end, TRef = erlang:start_timer(Timeout, ejabberd_local, ID), mnesia:dirty_write(#iq_response{id = ID, module = Module, function = Function, timer = TRef}). register_iq_handler(Host, XMLNS, Module, Fun) -> ejabberd_local ! {register_iq_handler, Host, XMLNS, Module, Fun}. register_iq_handler(Host, XMLNS, Module, Fun, Opts) -> ejabberd_local ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}. unregister_iq_response_handler(_Host, ID) -> catch get_iq_callback(ID), ok. unregister_iq_handler(Host, XMLNS) -> ejabberd_local ! {unregister_iq_handler, Host, XMLNS}. refresh_iq_handlers() -> ejabberd_local ! refresh_iq_handlers. bounce_resource_packet(From, To, Packet) -> Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND), ejabberd_router:route(To, From, Err), stop. %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([]) -> lists:foreach( fun(Host) -> ejabberd_router:register_route(Host, {apply, ?MODULE, route}), ejabberd_hooks:add(local_send_to_resource_hook, Host, ?MODULE, bounce_resource_packet, 100) end, ?MYHOSTS), catch ets:new(?IQTABLE, [named_table, public]), update_table(), mnesia:create_table(iq_response, [{ram_copies, [node()]}, {attributes, record_info(fields, iq_response)}]), mnesia:add_table_copy(iq_response, node(), ram_copies), {ok, #state{}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({route, From, To, Packet}, State) -> case catch do_route(From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p~nwhen processing: ~p", [Reason, {From, To, Packet}]); _ -> ok end, {noreply, State}; handle_info({register_iq_handler, Host, XMLNS, Module, Function}, State) -> ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function}), catch mod_disco:register_feature(Host, XMLNS), {noreply, State}; handle_info({register_iq_handler, Host, XMLNS, Module, Function, Opts}, State) -> ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function, Opts}), catch mod_disco:register_feature(Host, XMLNS), {noreply, State}; handle_info({unregister_iq_handler, Host, XMLNS}, State) -> case ets:lookup(?IQTABLE, {XMLNS, Host}) of [{_, Module, Function, Opts}] -> gen_iq_handler:stop_iq_handler(Module, Function, Opts); _ -> ok end, ets:delete(?IQTABLE, {XMLNS, Host}), catch mod_disco:unregister_feature(Host, XMLNS), {noreply, State}; handle_info(refresh_iq_handlers, State) -> lists:foreach( fun(T) -> case T of {{XMLNS, Host}, _Module, _Function, _Opts} -> catch mod_disco:register_feature(Host, XMLNS); {{XMLNS, Host}, _Module, _Function} -> catch mod_disco:register_feature(Host, XMLNS); _ -> ok end end, ets:tab2list(?IQTABLE)), {noreply, State}; handle_info({timeout, _TRef, ID}, State) -> process_iq_timeout(ID), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- do_route(From, To, Packet) -> ?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n", [From, To, Packet, 8]), if To#jid.luser /= "" -> ejabberd_sm:route(From, To, Packet); To#jid.lresource == "" -> {xmlelement, Name, _Attrs, _Els} = Packet, case Name of "iq" -> process_iq(From, To, Packet); "message" -> ok; "presence" -> ok; _ -> ok end; true -> {xmlelement, _Name, Attrs, _Els} = Packet, case xml:get_attr_s("type", Attrs) of "error" -> ok; "result" -> ok; _ -> ejabberd_hooks:run(local_send_to_resource_hook, To#jid.lserver, [From, To, Packet]) end end. update_table() -> case catch mnesia:table_info(iq_response, attributes) of [id, module, function] -> mnesia:delete_table(iq_response); [id, module, function, timer] -> ok; {'EXIT', _} -> ok end. get_iq_callback(ID) -> case mnesia:dirty_read(iq_response, ID) of [#iq_response{module = Module, timer = TRef, function = Function}] -> cancel_timer(TRef), mnesia:dirty_delete(iq_response, ID), {ok, Module, Function}; _ -> error end. process_iq_timeout(ID) -> spawn(fun process_iq_timeout/0) ! ID. process_iq_timeout() -> receive ID -> case get_iq_callback(ID) of {ok, undefined, Function} -> Function(timeout); _ -> ok end after 5000 -> ok end. cancel_timer(TRef) -> case erlang:cancel_timer(TRef) of false -> receive {timeout, TRef, _} -> ok after 0 -> ok end; _ -> ok end. ejabberd-2.1.11/src/ejabberd_captcha.erl0000664000000000000000000004534712240230175014747 0ustar %%%------------------------------------------------------------------- %%% File : ejabberd_captcha.erl %%% Author : Evgeniy Khramtsov %%% Purpose : CAPTCHA processing. %%% Created : 26 Apr 2008 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(ejabberd_captcha). -behaviour(gen_server). %% API -export([start_link/0]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([create_captcha/6, build_captcha_html/2, check_captcha/2, process_reply/1, process/2, is_feature_available/0, create_captcha_x/5, create_captcha_x/6]). -include("jlib.hrl"). -include("ejabberd.hrl"). -include("web/ejabberd_http.hrl"). -define(VFIELD(Type, Var, Value), {xmlelement, "field", [{"type", Type}, {"var", Var}], [{xmlelement, "value", [], [Value]}]}). -define(CAPTCHA_TEXT(Lang), translate:translate(Lang, "Enter the text you see")). -define(CAPTCHA_LIFETIME, 120000). % two minutes -define(LIMIT_PERIOD, 60*1000*1000). % one minute -record(state, {limits = treap:empty()}). -record(captcha, {id, pid, key, tref, args}). -define(T(S), case catch mnesia:transaction(fun() -> S end) of {atomic, Res} -> Res; {_, Reason} -> ?ERROR_MSG("mnesia transaction failed: ~p", [Reason]), {error, Reason} end). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). create_captcha(SID, From, To, Lang, Limiter, Args) when is_list(Lang), is_list(SID), is_record(From, jid), is_record(To, jid) -> case create_image(Limiter) of {ok, Type, Key, Image} -> Id = randoms:get_string(), B64Image = jlib:encode_base64(binary_to_list(Image)), JID = jlib:jid_to_string(From), CID = "sha1+" ++ sha:sha(Image) ++ "@bob.xmpp.org", Data = {xmlelement, "data", [{"xmlns", ?NS_BOB}, {"cid", CID}, {"max-age", "0"}, {"type", Type}], [{xmlcdata, B64Image}]}, Captcha = {xmlelement, "captcha", [{"xmlns", ?NS_CAPTCHA}], [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [?VFIELD("hidden", "FORM_TYPE", {xmlcdata, ?NS_CAPTCHA}), ?VFIELD("hidden", "from", {xmlcdata, jlib:jid_to_string(To)}), ?VFIELD("hidden", "challenge", {xmlcdata, Id}), ?VFIELD("hidden", "sid", {xmlcdata, SID}), {xmlelement, "field", [{"var", "ocr"}, {"label", ?CAPTCHA_TEXT(Lang)}], [{xmlelement, "required", [], []}, {xmlelement, "media", [{"xmlns", ?NS_MEDIA}], [{xmlelement, "uri", [{"type", Type}], [{xmlcdata, "cid:" ++ CID}]}]}]}]}]}, BodyString1 = translate:translate(Lang, "Your messages to ~s are being blocked. To unblock them, visit ~s"), BodyString = io_lib:format(BodyString1, [JID, get_url(Id)]), Body = {xmlelement, "body", [], [{xmlcdata, BodyString}]}, OOB = {xmlelement, "x", [{"xmlns", ?NS_OOB}], [{xmlelement, "url", [], [{xmlcdata, get_url(Id)}]}]}, Tref = erlang:send_after(?CAPTCHA_LIFETIME, ?MODULE, {remove_id, Id}), case ?T(mnesia:write(#captcha{id=Id, pid=self(), key=Key, tref=Tref, args=Args})) of ok -> {ok, Id, [Body, OOB, Captcha, Data]}; Err -> {error, Err} end; Err -> Err end. create_captcha_x(SID, To, Lang, Limiter, HeadEls) -> create_captcha_x(SID, To, Lang, Limiter, HeadEls, []). create_captcha_x(SID, To, Lang, Limiter, HeadEls, TailEls) -> case create_image(Limiter) of {ok, Type, Key, Image} -> Id = randoms:get_string(), B64Image = jlib:encode_base64(binary_to_list(Image)), CID = "sha1+" ++ sha:sha(Image) ++ "@bob.xmpp.org", Data = {xmlelement, "data", [{"xmlns", ?NS_BOB}, {"cid", CID}, {"max-age", "0"}, {"type", Type}], [{xmlcdata, B64Image}]}, HelpTxt = translate:translate( Lang, "If you don't see the CAPTCHA image here, " "visit the web page."), Imageurl = get_url(Id ++ "/image"), Captcha = {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [?VFIELD("hidden", "FORM_TYPE", {xmlcdata, ?NS_CAPTCHA}) | HeadEls] ++ [{xmlelement, "field", [{"type", "fixed"}], [{xmlelement, "value", [], [{xmlcdata, HelpTxt}]}]}, {xmlelement, "field", [{"type", "hidden"}, {"var", "captchahidden"}], [{xmlelement, "value", [], [{xmlcdata, "workaround-for-psi"}]}]}, {xmlelement, "field", [{"type", "text-single"}, {"label", translate:translate(Lang, "CAPTCHA web page")}, {"var", "url"}], [{xmlelement, "value", [], [{xmlcdata, Imageurl}]}]}, ?VFIELD("hidden", "from", {xmlcdata, jlib:jid_to_string(To)}), ?VFIELD("hidden", "challenge", {xmlcdata, Id}), ?VFIELD("hidden", "sid", {xmlcdata, SID}), {xmlelement, "field", [{"var", "ocr"}, {"label", ?CAPTCHA_TEXT(Lang)}], [{xmlelement, "required", [], []}, {xmlelement, "media", [{"xmlns", ?NS_MEDIA}], [{xmlelement, "uri", [{"type", Type}], [{xmlcdata, "cid:" ++ CID}]}]}]}] ++ TailEls}, Tref = erlang:send_after(?CAPTCHA_LIFETIME, ?MODULE, {remove_id, Id}), case ?T(mnesia:write(#captcha{id=Id, key=Key, tref=Tref})) of ok -> {ok, [Captcha, Data]}; Err -> {error, Err} end; Err -> Err end. %% @spec (Id::string(), Lang::string()) -> {FormEl, {ImgEl, TextEl, IdEl, KeyEl}} | captcha_not_found %% where FormEl = xmlelement() %% ImgEl = xmlelement() %% TextEl = xmlelement() %% IdEl = xmlelement() %% KeyEl = xmlelement() build_captcha_html(Id, Lang) -> case mnesia:dirty_read(captcha, Id) of [#captcha{}] -> ImgEl = {xmlelement, "img", [{"src", get_url(Id ++ "/image")}], []}, TextEl = {xmlcdata, ?CAPTCHA_TEXT(Lang)}, IdEl = {xmlelement, "input", [{"type", "hidden"}, {"name", "id"}, {"value", Id}], []}, KeyEl = {xmlelement, "input", [{"type", "text"}, {"name", "key"}, {"size", "10"}], []}, FormEl = {xmlelement, "form", [{"action", get_url(Id)}, {"name", "captcha"}, {"method", "POST"}], [ImgEl, {xmlelement, "br", [], []}, TextEl, {xmlelement, "br", [], []}, IdEl, KeyEl, {xmlelement, "br", [], []}, {xmlelement, "input", [{"type", "submit"}, {"name", "enter"}, {"value", "OK"}], []} ]}, {FormEl, {ImgEl, TextEl, IdEl, KeyEl}}; _ -> captcha_not_found end. %% @spec (Id::string(), ProvidedKey::string()) -> captcha_valid | captcha_non_valid | captcha_not_found check_captcha(Id, ProvidedKey) -> ?T(case mnesia:read(captcha, Id, write) of [#captcha{pid=Pid, args=Args, key=StoredKey, tref=Tref}] -> mnesia:delete({captcha, Id}), erlang:cancel_timer(Tref), if StoredKey == ProvidedKey -> if is_pid(Pid) -> Pid ! {captcha_succeed, Args}; true -> ok end, captcha_valid; true -> if is_pid(Pid) -> Pid ! {captcha_failed, Args}; true -> ok end, captcha_non_valid end; _ -> captcha_not_found end). process_reply({xmlelement, _, _, _} = El) -> case xml:get_subtag(El, "x") of false -> {error, malformed}; Xdata -> Fields = jlib:parse_xdata_submit(Xdata), case catch {proplists:get_value("challenge", Fields), proplists:get_value("ocr", Fields)} of {[Id|_], [OCR|_]} -> ?T(case mnesia:read(captcha, Id, write) of [#captcha{pid=Pid, args=Args, key=Key, tref=Tref}] -> mnesia:delete({captcha, Id}), erlang:cancel_timer(Tref), if OCR == Key -> if is_pid(Pid) -> Pid ! {captcha_succeed, Args}; true -> ok end, ok; true -> if is_pid(Pid) -> Pid ! {captcha_failed, Args}; true -> ok end, {error, bad_match} end; _ -> {error, not_found} end); _ -> {error, malformed} end end; process_reply(_) -> {error, malformed}. process(_Handlers, #request{method='GET', lang=Lang, path=[_, Id]}) -> case build_captcha_html(Id, Lang) of {FormEl, _} when is_tuple(FormEl) -> Form = {xmlelement, "div", [{"align", "center"}], [FormEl]}, ejabberd_web:make_xhtml([Form]); captcha_not_found -> ejabberd_web:error(not_found) end; process(_Handlers, #request{method='GET', path=[_, Id, "image"], ip = IP}) -> {Addr, _Port} = IP, case mnesia:dirty_read(captcha, Id) of [#captcha{key=Key}] -> case create_image(Addr, Key) of {ok, Type, _, Img} -> {200, [{"Content-Type", Type}, {"Cache-Control", "no-cache"}, {"Last-Modified", httpd_util:rfc1123_date()}], Img}; {error, limit} -> ejabberd_web:error(not_allowed); _ -> ejabberd_web:error(not_found) end; _ -> ejabberd_web:error(not_found) end; process(_Handlers, #request{method='POST', q=Q, lang=Lang, path=[_, Id]}) -> ProvidedKey = proplists:get_value("key", Q, none), case check_captcha(Id, ProvidedKey) of captcha_valid -> Form = {xmlelement, "p", [], [{xmlcdata, translate:translate(Lang, "The CAPTCHA is valid.") }]}, ejabberd_web:make_xhtml([Form]); captcha_non_valid -> ejabberd_web:error(not_allowed); captcha_not_found -> ejabberd_web:error(not_found) end; process(_Handlers, _Request) -> ejabberd_web:error(not_found). %%==================================================================== %% gen_server callbacks %%==================================================================== init([]) -> mnesia:create_table(captcha, [{ram_copies, [node()]}, {attributes, record_info(fields, captcha)}]), mnesia:add_table_copy(captcha, node(), ram_copies), check_captcha_setup(), {ok, #state{}}. handle_call({is_limited, Limiter, RateLimit}, _From, State) -> NowPriority = now_priority(), CleanPriority = NowPriority + ?LIMIT_PERIOD, Limits = clean_treap(State#state.limits, CleanPriority), case treap:lookup(Limiter, Limits) of {ok, _, Rate} when Rate >= RateLimit -> {reply, true, State#state{limits = Limits}}; {ok, Priority, Rate} -> NewLimits = treap:insert(Limiter, Priority, Rate+1, Limits), {reply, false, State#state{limits = NewLimits}}; _ -> NewLimits = treap:insert(Limiter, NowPriority, 1, Limits), {reply, false, State#state{limits = NewLimits}} end; handle_call(_Request, _From, State) -> {reply, bad_request, State}. handle_cast(_Msg, State) -> {noreply, State}. handle_info({remove_id, Id}, State) -> ?DEBUG("captcha ~p timed out", [Id]), _ = ?T(case mnesia:read(captcha, Id, write) of [#captcha{args=Args, pid=Pid}] -> if is_pid(Pid) -> Pid ! {captcha_failed, Args}; true -> ok end, mnesia:delete({captcha, Id}); _ -> ok end), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- %%-------------------------------------------------------------------- %% Function: create_image() -> {ok, Type, Key, Image} | {error, Reason} %% Type = "image/png" | "image/jpeg" | "image/gif" %% Key = string() %% Image = binary() %% Reason = atom() %%-------------------------------------------------------------------- create_image() -> create_image(undefined). create_image(Limiter) -> %% Six numbers from 1 to 9. Key = string:substr(randoms:get_string(), 1, 6), create_image(Limiter, Key). create_image(Limiter, Key) -> case is_limited(Limiter) of true -> {error, limit}; false -> do_create_image(Key) end. do_create_image(Key) -> FileName = get_prog_name(), Cmd = lists:flatten(io_lib:format("~s ~s", [FileName, Key])), case cmd(Cmd) of {ok, <<16#89, $P, $N, $G, $\r, $\n, 16#1a, $\n, _/binary>> = Img} -> {ok, "image/png", Key, Img}; {ok, <<16#ff, 16#d8, _/binary>> = Img} -> {ok, "image/jpeg", Key, Img}; {ok, <<$G, $I, $F, $8, X, $a, _/binary>> = Img} when X==$7; X==$9 -> {ok, "image/gif", Key, Img}; {error, enodata = Reason} -> ?ERROR_MSG("Failed to process output from \"~s\". " "Maybe ImageMagick's Convert program is not installed.", [Cmd]), {error, Reason}; {error, Reason} -> ?ERROR_MSG("Failed to process an output from \"~s\": ~p", [Cmd, Reason]), {error, Reason}; _ -> Reason = malformed_image, ?ERROR_MSG("Failed to process an output from \"~s\": ~p", [Cmd, Reason]), {error, Reason} end. get_prog_name() -> case ejabberd_config:get_local_option(captcha_cmd) of FileName when is_list(FileName) -> FileName; Value when (Value == undefined) or (Value == "") -> ?DEBUG("The option captcha_cmd is not configured, but some " "module wants to use the CAPTCHA feature.", []), false end. get_url(Str) -> CaptchaHost = ejabberd_config:get_local_option(captcha_host), case string:tokens(CaptchaHost, ":") of [Host] -> "http://" ++ Host ++ "/captcha/" ++ Str; ["http"++_ = TransferProt, Host] -> TransferProt ++ ":" ++ Host ++ "/captcha/" ++ Str; [Host, PortString] -> TransferProt = atom_to_list(get_transfer_protocol(PortString)), TransferProt ++ "://" ++ Host ++ ":" ++ PortString ++ "/captcha/" ++ Str; [TransferProt, Host, PortString] -> TransferProt ++ ":" ++ Host ++ ":" ++ PortString ++ "/captcha/" ++ Str; _ -> "http://" ++ ?MYNAME ++ "/captcha/" ++ Str end. get_transfer_protocol(PortString) -> PortNumber = list_to_integer(PortString), PortListeners = get_port_listeners(PortNumber), get_captcha_transfer_protocol(PortListeners). get_port_listeners(PortNumber) -> AllListeners = ejabberd_config:get_local_option(listen), lists:filter( fun({{Port, _Ip, _Netp}, _Module1, _Opts1}) when Port == PortNumber -> true; (_) -> false end, AllListeners). get_captcha_transfer_protocol([]) -> throw("The port number mentioned in captcha_host is not " "a ejabberd_http listener with 'captcha' option. " "Change the port number or specify http:// in that option."); get_captcha_transfer_protocol([{{_Port, _Ip, tcp}, ejabberd_http, Opts} | Listeners]) -> case lists:member(captcha, Opts) of true -> case lists:member(tls, Opts) of true -> https; false -> http end; false -> get_captcha_transfer_protocol(Listeners) end; get_captcha_transfer_protocol([_ | Listeners]) -> get_captcha_transfer_protocol(Listeners). is_limited(undefined) -> false; is_limited(Limiter) -> case ejabberd_config:get_local_option(captcha_limit) of Int when is_integer(Int), Int > 0 -> case catch gen_server:call(?MODULE, {is_limited, Limiter, Int}, 5000) of true -> true; false -> false; Err -> ?ERROR_MSG("Call failed: ~p", [Err]), false end; _ -> false end. %%-------------------------------------------------------------------- %% Function: cmd(Cmd) -> Data | {error, Reason} %% Cmd = string() %% Data = binary() %% Description: os:cmd/1 replacement %%-------------------------------------------------------------------- -define(CMD_TIMEOUT, 5000). -define(MAX_FILE_SIZE, 64*1024). cmd(Cmd) -> Port = open_port({spawn, Cmd}, [stream, eof, binary]), TRef = erlang:start_timer(?CMD_TIMEOUT, self(), timeout), recv_data(Port, TRef, <<>>). recv_data(Port, TRef, Buf) -> receive {Port, {data, Bytes}} -> NewBuf = <>, if size(NewBuf) > ?MAX_FILE_SIZE -> return(Port, TRef, {error, efbig}); true -> recv_data(Port, TRef, NewBuf) end; {Port, {data, _}} -> return(Port, TRef, {error, efbig}); {Port, eof} when Buf /= <<>> -> return(Port, TRef, {ok, Buf}); {Port, eof} -> return(Port, TRef, {error, enodata}); {timeout, TRef, _} -> return(Port, TRef, {error, timeout}) end. return(Port, TRef, Result) -> case erlang:cancel_timer(TRef) of false -> receive {timeout, TRef, _} -> ok after 0 -> ok end; _ -> ok end, catch port_close(Port), Result. is_feature_available() -> case get_prog_name() of Prog when is_list(Prog) -> true; false -> false end. check_captcha_setup() -> case is_feature_available() of true -> case create_image() of {ok, _, _, _} -> ok; _Err -> ?CRITICAL_MSG("Captcha is enabled in the option captcha_cmd, " "but it can't generate images.", []), throw({error, captcha_cmd_enabled_but_fails}) end; false -> ok end. clean_treap(Treap, CleanPriority) -> case treap:is_empty(Treap) of true -> Treap; false -> {_Key, Priority, _Value} = treap:get_root(Treap), if Priority > CleanPriority -> clean_treap(treap:delete_root(Treap), CleanPriority); true -> Treap end end. now_priority() -> {MSec, Sec, USec} = now(), -((MSec*1000000 + Sec)*1000000 + USec). ejabberd-2.1.11/src/config.guess0000664000000000000000000013105412240230175013326 0ustar #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 # Free Software Foundation, Inc. timestamp='2009-06-10' # This file 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. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[456]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:[3456]*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; EM64T | authenticamd | genuineintel) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else echo ${UNAME_MACHINE}-unknown-linux-gnueabi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^LIBC/{ s: ::g p }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ejabberd-2.1.11/src/mod_blocking_odbc.erl0000664000000000000000000003343112240230175015133 0ustar %%%---------------------------------------------------------------------- %%% File : mod_blocking_odbc.erl %%% Author : Stephan Maka %%% Purpose : XEP-0191: Simple Communications Blocking %%% Created : 24 Aug 2008 by Stephan Maka %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_blocking_odbc). -behaviour(gen_mod). -export([start/2, stop/1, process_iq/3, process_iq_set/4, process_iq_get/5]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_privacy.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), ejabberd_hooks:add(privacy_iq_get, Host, ?MODULE, process_iq_get, 40), ejabberd_hooks:add(privacy_iq_set, Host, ?MODULE, process_iq_set, 40), mod_disco:register_feature(Host, ?NS_BLOCKING), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING, ?MODULE, process_iq, IQDisc). stop(Host) -> ejabberd_hooks:delete(privacy_iq_get, Host, ?MODULE, process_iq_get, 40), ejabberd_hooks:delete(privacy_iq_set, Host, ?MODULE, process_iq_set, 40), mod_disco:unregister_feature(Host, ?NS_BLOCKING), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING). process_iq(_From, _To, IQ) -> SubEl = IQ#iq.sub_el, IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}. process_iq_get(_, From, _To, #iq{xmlns = ?NS_BLOCKING, sub_el = {xmlelement, "blocklist", _, _}}, _) -> #jid{luser = LUser, lserver = LServer} = From, {stop, process_blocklist_get(LUser, LServer)}; process_iq_get(Acc, _, _, _, _) -> Acc. process_iq_set(_, From, _To, #iq{xmlns = ?NS_BLOCKING, sub_el = {xmlelement, SubElName, _, SubEls}}) -> #jid{luser = LUser, lserver = LServer} = From, Res = case {SubElName, xml:remove_cdata(SubEls)} of {"block", []} -> {error, ?ERR_BAD_REQUEST}; {"block", Els} -> JIDs = parse_blocklist_items(Els, []), process_blocklist_block(LUser, LServer, JIDs); {"unblock", []} -> process_blocklist_unblock_all(LUser, LServer); {"unblock", Els} -> JIDs = parse_blocklist_items(Els, []), process_blocklist_unblock(LUser, LServer, JIDs); _ -> {error, ?ERR_BAD_REQUEST} end, {stop, Res}; process_iq_set(Acc, _, _, _) -> Acc. is_list_needdb(Items) -> lists:any( fun(X) -> case X#listitem.type of subscription -> true; group -> true; _ -> false end end, Items). list_to_blocklist_jids([], JIDs) -> JIDs; list_to_blocklist_jids([#listitem{type = jid, action = deny, value = JID} = Item | Items], JIDs) -> case Item of #listitem{match_all = true} -> Match = true; #listitem{match_iq = true, match_message = true, match_presence_in = true, match_presence_out = true} -> Match = true; _ -> Match = false end, if Match -> list_to_blocklist_jids(Items, [JID | JIDs]); true -> list_to_blocklist_jids(Items, JIDs) end; % Skip Privacy List items than cannot be mapped to Blocking items list_to_blocklist_jids([_ | Items], JIDs) -> list_to_blocklist_jids(Items, JIDs). parse_blocklist_items([], JIDs) -> JIDs; parse_blocklist_items([{xmlelement, "item", Attrs, _} | Els], JIDs) -> case xml:get_attr("jid", Attrs) of {value, JID1} -> JID = jlib:jid_tolower(jlib:string_to_jid(JID1)), parse_blocklist_items(Els, [JID | JIDs]); false -> % Tolerate missing jid attribute parse_blocklist_items(Els, JIDs) end; parse_blocklist_items([_ | Els], JIDs) -> % Tolerate unknown elements parse_blocklist_items(Els, JIDs). process_blocklist_block(LUser, LServer, JIDs) -> F = fun() -> Default = case mod_privacy_odbc:sql_get_default_privacy_list_t(LUser) of {selected, ["name"], []} -> Name = "Blocked contacts", mod_privacy_odbc:sql_add_privacy_list(LUser, Name), mod_privacy_odbc:sql_set_default_privacy_list( LUser, Name), Name; {selected, ["name"], [{Name}]} -> Name end, {selected, ["id"], [{ID}]} = mod_privacy_odbc:sql_get_privacy_list_id_t(LUser, Default), case mod_privacy_odbc:sql_get_privacy_list_data_by_id_t(ID) of {selected, ["t", "value", "action", "ord", "match_all", "match_iq", "match_message", "match_presence_in", "match_presence_out"], RItems = [_|_]} -> List = lists:map( fun mod_privacy_odbc:raw_to_item/1, RItems); _ -> List = [] end, AlreadyBlocked = list_to_blocklist_jids(List, []), NewList = lists:foldr( fun(JID, List1) -> case lists:member(JID, AlreadyBlocked) of true -> List1; false -> [#listitem{type = jid, value = JID, action = deny, order = 0, match_all = true } | List1] end end, List, JIDs), NewRItems = lists:map( fun mod_privacy_odbc:item_to_raw/1, NewList), mod_privacy_odbc:sql_set_privacy_list( ID, NewRItems), {ok, Default, NewList} end, case ejabberd_odbc:sql_transaction(LServer, F) of {atomic, {error, _} = Error} -> Error; {atomic, {ok, Default, List}} -> UserList = make_userlist(Default, List), broadcast_list_update(LUser, LServer, Default, UserList), broadcast_blocklist_event(LUser, LServer, {block, JIDs}), {result, [], UserList}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. process_blocklist_unblock_all(LUser, LServer) -> F = fun() -> case mod_privacy_odbc:sql_get_default_privacy_list_t(LUser) of {selected, ["name"], []} -> ok; {selected, ["name"], [{Default}]} -> {selected, ["id"], [{ID}]} = mod_privacy_odbc:sql_get_privacy_list_id_t( LUser, Default), case mod_privacy_odbc:sql_get_privacy_list_data_by_id_t(ID) of {selected, ["t", "value", "action", "ord", "match_all", "match_iq", "match_message", "match_presence_in", "match_presence_out"], RItems = [_|_]} -> List = lists:map( fun mod_privacy_odbc:raw_to_item/1, RItems), NewList = lists:filter( fun(#listitem{action = A}) -> A =/= deny end, List), NewRItems = lists:map( fun mod_privacy_odbc:item_to_raw/1, NewList), mod_privacy_odbc:sql_set_privacy_list( ID, NewRItems), {ok, Default, NewList}; _ -> ok end; _ -> ok end end, case ejabberd_odbc:sql_transaction(LServer, F) of {atomic, {error, _} = Error} -> Error; {atomic, ok} -> {result, []}; {atomic, {ok, Default, List}} -> UserList = make_userlist(Default, List), broadcast_list_update(LUser, LServer, Default, UserList), broadcast_blocklist_event(LUser, LServer, unblock_all), {result, [], UserList}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. process_blocklist_unblock(LUser, LServer, JIDs) -> F = fun() -> case mod_privacy_odbc:sql_get_default_privacy_list_t(LUser) of {selected, ["name"], []} -> ok; {selected, ["name"], [{Default}]} -> {selected, ["id"], [{ID}]} = mod_privacy_odbc:sql_get_privacy_list_id_t( LUser, Default), case mod_privacy_odbc:sql_get_privacy_list_data_by_id_t(ID) of {selected, ["t", "value", "action", "ord", "match_all", "match_iq", "match_message", "match_presence_in", "match_presence_out"], RItems = [_|_]} -> List = lists:map( fun mod_privacy_odbc:raw_to_item/1, RItems), NewList = lists:filter( fun(#listitem{action = deny, type = jid, value = JID}) -> not(lists:member(JID, JIDs)); (_) -> true end, List), NewRItems = lists:map( fun mod_privacy_odbc:item_to_raw/1, NewList), mod_privacy_odbc:sql_set_privacy_list( ID, NewRItems), {ok, Default, NewList}; _ -> ok end; _ -> ok end end, case ejabberd_odbc:sql_transaction(LServer, F) of {atomic, {error, _} = Error} -> Error; {atomic, ok} -> {result, []}; {atomic, {ok, Default, List}} -> UserList = make_userlist(Default, List), broadcast_list_update(LUser, LServer, Default, UserList), broadcast_blocklist_event(LUser, LServer, {unblock, JIDs}), {result, [], UserList}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. make_userlist(Name, List) -> NeedDb = is_list_needdb(List), #userlist{name = Name, list = List, needdb = NeedDb}. broadcast_list_update(LUser, LServer, Name, UserList) -> ejabberd_router:route( jlib:make_jid(LUser, LServer, ""), jlib:make_jid(LUser, LServer, ""), {xmlelement, "broadcast", [], [{privacy_list, UserList, Name}]}). broadcast_blocklist_event(LUser, LServer, Event) -> JID = jlib:make_jid(LUser, LServer, ""), ejabberd_router:route( JID, JID, {xmlelement, "broadcast", [], [{blocking, Event}]}). process_blocklist_get(LUser, LServer) -> case catch mod_privacy_odbc:sql_get_default_privacy_list(LUser, LServer) of {selected, ["name"], []} -> {result, [{xmlelement, "blocklist", [{"xmlns", ?NS_BLOCKING}], []}]}; {selected, ["name"], [{Default}]} -> case catch mod_privacy_odbc:sql_get_privacy_list_data( LUser, LServer, Default) of {selected, ["t", "value", "action", "ord", "match_all", "match_iq", "match_message", "match_presence_in", "match_presence_out"], RItems} -> List = lists:map(fun mod_privacy_odbc:raw_to_item/1, RItems), JIDs = list_to_blocklist_jids(List, []), Items = lists:map( fun(JID) -> ?DEBUG("JID: ~p",[JID]), {xmlelement, "item", [{"jid", jlib:jid_to_string(JID)}], []} end, JIDs), {result, [{xmlelement, "blocklist", [{"xmlns", ?NS_BLOCKING}], Items}]}; {'EXIT', _} -> {error, ?ERR_INTERNAL_SERVER_ERROR} end; {'EXIT', _} -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. ejabberd-2.1.11/src/Makefile.win320000664000000000000000000001104112240230175013403 0ustar include Makefile.inc ALL : build REL=..\release EREL=$(REL)\ejabberd-$(EJABBERD_VERSION) EBIN_DIR=$(EREL)\ebin SRC_DIR=$(EREL)\src PRIV_DIR=$(EREL)\priv SO_DIR=$(EREL) MSGS_DIR=$(EREL)\msgs WIN32_DIR=$(EREL)\win32 DOC_DIR=$(EREL)\doc NSIS_SCRIPT=win32\ejabberd.nsi NSIS_HEADER=win32\ejabberd.nsh installer : $(NSIS_SCRIPT) $(NSIS_HEADER) makensis $(NSIS_SCRIPT) $(NSIS_HEADER) : Makefile.inc echo !define OUTFILEDIR "..\$(REL)" >$(NSIS_HEADER) echo !define TESTDIR "..\$(REL)\ejabberd-$(EJABBERD_VERSION)" >>$(NSIS_HEADER) echo !define VERSION "$(EJABBERD_VERSION)" >>$(NSIS_HEADER) release_clean : if exist $(REL) rd /s /q $(REL) release : build release_clean mkdir $(REL) mkdir $(EREL) mkdir $(EBIN_DIR) copy *.beam $(EBIN_DIR) @erase $(EBIN_DIR)\configure.beam copy *.app $(EBIN_DIR) copy *.dll $(SO_DIR) mkdir $(MSGS_DIR) copy msgs\*.msg $(MSGS_DIR) mkdir $(WIN32_DIR) copy win32\ejabberd.cfg $(EREL) copy win32\inetrc $(EREL) copy $(SYSTEMROOT)\system32\libeay32.dll $(EREL) copy $(SYSTEMROOT)\system32\ssleay32.dll $(EREL) copy win32\ejabberd.ico $(WIN32_DIR) mkdir $(SRC_DIR) copy *.app $(SRC_DIR) copy *.erl $(SRC_DIR) copy *.hrl $(SRC_DIR) copy *.c $(SRC_DIR) mkdir $(SRC_DIR)\eldap copy eldap\eldap.* $(SRC_DIR)\eldap copy eldap\ELDAPv3.asn $(SRC_DIR)\eldap mkdir $(SRC_DIR)\mod_irc copy mod_irc\*.erl $(SRC_DIR)\mod_irc copy mod_irc\*.c $(SRC_DIR)\mod_irc mkdir $(SRC_DIR)\mod_muc copy mod_muc\*.erl $(SRC_DIR)\mod_muc mkdir $(SRC_DIR)\mod_pubsub copy mod_pubsub\*.erl $(SRC_DIR)\mod_pubsub mkdir $(SRC_DIR)\mod_proxy65 copy mod_proxy65\*.erl $(SRC_DIR)\mod_proxy65 copy mod_proxy65\*.hrl $(SRC_DIR)\mod_proxy65 mkdir $(SRC_DIR)\stringprep copy stringprep\*.erl $(SRC_DIR)\stringprep copy stringprep\*.c $(SRC_DIR)\stringprep copy stringprep\*.tcl $(SRC_DIR)\stringprep mkdir $(SRC_DIR)\stun copy stun\*.erl $(SRC_DIR)\stun copy stun\*.hrl $(SRC_DIR)\stun mkdir $(SRC_DIR)\tls copy tls\*.erl $(SRC_DIR)\tls copy tls\*.c $(SRC_DIR)\tls mkdir $(SRC_DIR)\ejabberd_zlib copy ejabberd_zlib\*.erl $(SRC_DIR)\ejabberd_zlib copy ejabberd_zlib\*.c $(SRC_DIR)\ejabberd_zlib mkdir $(SRC_DIR)\web copy web\*.erl $(SRC_DIR)\web mkdir $(SRC_DIR)\odbc copy odbc\*.erl $(SRC_DIR)\odbc copy odbc\*.sql $(EREL) mkdir $(DOC_DIR) copy ..\doc\*.txt $(DOC_DIR) copy ..\doc\*.html $(DOC_DIR) copy ..\doc\*.png $(DOC_DIR) SOURCE = expat_erl.c OBJECT = expat_erl.o DLL = expat_erl.dll build : $(DLL) compile-beam all-recursive all-recursive : cd eldap nmake -nologo -f Makefile.win32 cd ..\mod_irc nmake -nologo -f Makefile.win32 cd ..\mod_muc nmake -nologo -f Makefile.win32 cd ..\mod_pubsub nmake -nologo -f Makefile.win32 cd ..\mod_proxy65 nmake -nologo -f Makefile.win32 cd ..\stringprep nmake -nologo -f Makefile.win32 cd ..\stun nmake -nologo -f Makefile.win32 cd ..\tls nmake -nologo -f Makefile.win32 cd ..\ejabberd_zlib nmake -nologo -f Makefile.win32 cd ..\web nmake -nologo -f Makefile.win32 cd ..\odbc nmake -nologo -f Makefile.win32 cd .. compile-beam : XmppAddr.hrl erl -s make all report -noinput -s erlang halt XmppAddr.hrl : XmppAddr.asn1 erlc -bber_bin +der +compact_bit_string +optimize +noobj XmppAddr.asn1 CLEAN : clean-recursive clean-local clean-local : -@erase $(OBJECT) -@erase $(DLL) -@erase expat_erl.exp -@erase expat_erl.lib -@erase *.beam -@erase XmppAddr.asn1db -@erase XmppAddr.erl -@erase XmppAddr.hrl clean-recursive : cd eldap nmake -nologo -f Makefile.win32 clean cd ..\mod_irc nmake -nologo -f Makefile.win32 clean cd ..\mod_muc nmake -nologo -f Makefile.win32 clean cd ..\mod_pubsub nmake -nologo -f Makefile.win32 clean cd ..\mod_proxy65 nmake -nologo -f Makefile.win32 clean cd ..\stringprep nmake -nologo -f Makefile.win32 clean cd ..\stun nmake -nologo -f Makefile.win32 clean cd ..\tls nmake -nologo -f Makefile.win32 clean cd ..\ejabberd_zlib nmake -nologo -f Makefile.win32 clean cd ..\web nmake -nologo -f Makefile.win32 clean cd ..\odbc nmake -nologo -f Makefile.win32 clean cd .. distclean : release_clean clean -@erase $(NSIS_HEADER) -@erase Makefile.inc CC=cl.exe CC_FLAGS=-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT $(EXPAT_FLAG) -MD -Ox -I"$(ERLANG_DIR)\usr\include" -I"$(EI_DIR)\include" -I"$(EXPAT_DIR)\source\lib" LD=link.exe LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" "$(EXPAT_LIB)" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib $(DLL) : $(OBJECT) $(LD) $(LD_FLAGS) -out:$@ $< $(OBJECT) : $(SOURCE) $(CC) $(CC_FLAGS) -c -Fo$@ $< ejabberd-2.1.11/src/eldap/0000775000000000000000000000000012240452476012104 5ustar ejabberd-2.1.11/src/eldap/Makefile.win320000664000000000000000000000212412240230175014472 0ustar include ..\Makefile.inc EFLAGS = -I .. -pz .. OUTDIR = .. BEAMS = ..\eldap.beam ..\eldap_filter.beam ..\eldap_pool.beam ..\eldap_utils.beam ..\eldap_filter_yecc.beam ASN_FLAGS = -bber_bin +optimize ALL : $(BEAMS) Clean : -@erase ELDAPv3.asn1db -@erase ELDAPv3.erl -@erase ELDAPv3.hrl -@erase ELDAPv3.beam -@erase eldap_filter_yecc.erl -@erase eldap_filter_yecc.beam -@erase $(BEAMS) ELDAPv3.erl : ELDAPv3.asn erlc $(ASN_FLAGS) -W $(EFLAGS) ELDAPv3.asn eldap_filter_yecc.erl: eldap_filter_yecc.yrl erlc -W eldap_filter_yecc.yrl $(OUTDIR)\eldap.beam : eldap.erl ELDAPv3.erl erlc -W $(EFLAGS) -o $(OUTDIR) eldap.erl $(OUTDIR)\ELDAPv3.beam : ELDAPv3.erl erlc -W $(EFLAGS) -o $(OUTDIR) ELDAPv3.erl $(OUTDIR)\eldap_filter.beam : eldap_filter.erl erlc -W $(EFLAGS) -o $(OUTDIR) eldap_filter.erl $(OUTDIR)\eldap_utils.beam : eldap_utils.erl erlc -W $(EFLAGS) -o $(OUTDIR) eldap_utils.erl $(OUTDIR)\eldap_pool.beam : eldap_pool.erl erlc -W $(EFLAGS) -o $(OUTDIR) eldap_pool.erl $(OUTDIR)\eldap_filter_yecc.beam : eldap_filter_yecc.erl erlc -W $(EFLAGS) -o $(OUTDIR) eldap_filter_yecc.erl ejabberd-2.1.11/src/eldap/eldap.erl0000664000000000000000000012336212240230175013672 0ustar -module(eldap). %%% -------------------------------------------------------------------- %%% Created: 12 Oct 2000 by Tobbe %%% Function: Erlang client LDAP implementation according RFC 2251. %%% The interface is based on RFC 1823, and %%% draft-ietf-asid-ldap-c-api-00.txt %%% %%% Copyright (C) 2000 Torbjorn Tornkvist, tnt@home.se %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA %%% Modified by Sean Hinde 7th Dec 2000 %%% Turned into gen_fsm, made non-blocking, added timers etc to support this. %%% Now has the concept of a name (string() or atom()) per instance which allows %%% multiple users to call by name if so desired. %%% %%% Can be configured with start_link parameters or use a config file to get %%% host to connect to, dn, password, log function etc. %%% Modified by Alexey Shchepin %%% Modified by Evgeniy Khramtsov %%% Implemented queue for bind() requests to prevent pending binds. %%% Implemented extensibleMatch/2 function. %%% Implemented LDAP Extended Operations (currently only Password Modify %%% is supported - RFC 3062). %%% Modified by Christophe Romain %%% Improve error case handling %%% Modified by Mickael Remond %%% Now use ejabberd log mechanism %%% Modified by: %%% Thomas Baden 2008 April 6th %%% Andy Harb 2008 April 28th %%% Anton Podavalov 2009 February 22th %%% Added LDAPS support, modeled off jungerl eldap.erl version. %%% NOTICE: STARTTLS is not supported. %%% -------------------------------------------------------------------- -vc('$Id$ '). %%%---------------------------------------------------------------------- %%% LDAP Client state machine. %%% Possible states are: %%% connecting - actually disconnected, but retrying periodically %%% wait_bind_response - connected and sent bind request %%% active - bound to LDAP Server and ready to handle commands %%% active_bind - sent bind() request and waiting for response %%%---------------------------------------------------------------------- -behaviour(gen_fsm). -include("ejabberd.hrl"). %% External exports -export([start_link/1, start_link/6]). -export([baseObject/0,singleLevel/0,wholeSubtree/0,close/1, equalityMatch/2,greaterOrEqual/2,lessOrEqual/2, approxMatch/2,search/2,substrings/2,present/1,extensibleMatch/2, 'and'/1,'or'/1,'not'/1,modify/3, mod_add/2, mod_delete/2, mod_replace/2, add/3, delete/2, modify_dn/5, modify_passwd/3, bind/3]). -export([get_status/1]). %% gen_fsm callbacks -export([init/1, connecting/2, connecting/3, wait_bind_response/3, active/3, active_bind/3, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, code_change/4]). -import(lists,[concat/1]). -include("ELDAPv3.hrl"). -include("eldap.hrl"). -define(LDAP_VERSION, 3). -define(RETRY_TIMEOUT, 500). -define(BIND_TIMEOUT, 10000). -define(CMD_TIMEOUT, 100000). %% Used in gen_fsm sync calls. -define(CALL_TIMEOUT, ?CMD_TIMEOUT + ?BIND_TIMEOUT + ?RETRY_TIMEOUT). %% Used as a timeout for gen_tcp:send/2 -define(SEND_TIMEOUT, 30000). -define(MAX_TRANSACTION_ID, 65535). -define(MIN_TRANSACTION_ID, 0). %% Grace period after "soft" LDAP bind errors: -define(GRACEFUL_RETRY_TIMEOUT, 5000). -define(SUPPORTEDEXTENSION, "1.3.6.1.4.1.1466.101.120.7"). -define(SUPPORTEDEXTENSIONSYNTAX, "1.3.6.1.4.1.1466.115.121.1.38"). -define(STARTTLS, "1.3.6.1.4.1.1466.20037"). -record(eldap, {version = ?LDAP_VERSION, hosts, % Possible hosts running LDAP servers host = null, % Connected Host LDAP server port = 389, % The LDAP server port sockmod, % SockMod (gen_tcp|tls) tls = none, % LDAP/LDAPS (none|tls) tls_options = [], fd = null, % Socket filedescriptor. rootdn = "", % Name of the entry to bind as passwd, % Password for (above) entry id = 0, % LDAP Request ID bind_timer, % Ref to bind timeout dict, % dict holding operation params and results req_q % Queue for requests }). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start_link(Name) -> Reg_name = list_to_atom("eldap_" ++ Name), gen_fsm:start_link({local, Reg_name}, ?MODULE, [], []). start_link(Name, Hosts, Port, Rootdn, Passwd, Opts) -> Reg_name = list_to_atom("eldap_" ++ Name), gen_fsm:start_link({local, Reg_name}, ?MODULE, {Hosts, Port, Rootdn, Passwd, Opts}, []). %%% -------------------------------------------------------------------- %%% Get status of connection. %%% -------------------------------------------------------------------- get_status(Handle) -> Handle1 = get_handle(Handle), gen_fsm:sync_send_all_state_event(Handle1, get_status). %%% -------------------------------------------------------------------- %%% Shutdown connection (and process) asynchronous. %%% -------------------------------------------------------------------- close(Handle) -> Handle1 = get_handle(Handle), gen_fsm:send_all_state_event(Handle1, close). %%% -------------------------------------------------------------------- %%% Add an entry. The entry field MUST NOT exist for the AddRequest %%% to succeed. The parent of the entry MUST exist. %%% Example: %%% %%% add(Handle, %%% "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com", %%% [{"objectclass", ["person"]}, %%% {"cn", ["Bill Valentine"]}, %%% {"sn", ["Valentine"]}, %%% {"telephoneNumber", ["545 555 00"]}] %%% ) %%% -------------------------------------------------------------------- add(Handle, Entry, Attributes) when is_list(Entry), is_list(Attributes) -> Handle1 = get_handle(Handle), gen_fsm:sync_send_event(Handle1, {add, Entry, add_attrs(Attributes)}, ?CALL_TIMEOUT). %%% Do sanity check ! add_attrs(Attrs) -> F = fun({Type,Vals}) when is_list(Type), is_list(Vals) -> %% Confused ? Me too... :-/ {'AddRequest_attributes',Type, Vals} end, case catch lists:map(F, Attrs) of {'EXIT', _} -> throw({error, attribute_values}); Else -> Else end. %%% -------------------------------------------------------------------- %%% Delete an entry. The entry consists of the DN of %%% the entry to be deleted. %%% Example: %%% %%% delete(Handle, %%% "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com" %%% ) %%% -------------------------------------------------------------------- delete(Handle, Entry) when is_list(Entry) -> Handle1 = get_handle(Handle), gen_fsm:sync_send_event(Handle1, {delete, Entry}, ?CALL_TIMEOUT). %%% -------------------------------------------------------------------- %%% Modify an entry. Given an entry a number of modification %%% operations can be performed as one atomic operation. %%% Example: %%% %%% modify(Handle, %%% "cn=Torbjorn Tornkvist, ou=people, o=Bluetail AB, dc=bluetail, dc=com", %%% [replace("telephoneNumber", ["555 555 00"]), %%% add("description", ["LDAP hacker"])] %%% ) %%% -------------------------------------------------------------------- modify(Handle, Object, Mods) when is_list(Object), is_list(Mods) -> Handle1 = get_handle(Handle), gen_fsm:sync_send_event(Handle1, {modify, Object, Mods}, ?CALL_TIMEOUT). %%% %%% Modification operations. %%% Example: %%% replace("telephoneNumber", ["555 555 00"]) %%% mod_add(Type, Values) when is_list(Type), is_list(Values) -> m(add, Type, Values). mod_delete(Type, Values) when is_list(Type), is_list(Values) -> m(delete, Type, Values). mod_replace(Type, Values) when is_list(Type), is_list(Values) -> m(replace, Type, Values). m(Operation, Type, Values) -> #'ModifyRequest_modification_SEQOF'{ operation = Operation, modification = #'AttributeTypeAndValues'{ type = Type, vals = Values}}. %%% -------------------------------------------------------------------- %%% Modify an entry. Given an entry a number of modification %%% operations can be performed as one atomic operation. %%% Example: %%% %%% modify_dn(Handle, %%% "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com", %%% "cn=Ben Emerson", %%% true, %%% "" %%% ) %%% -------------------------------------------------------------------- modify_dn(Handle, Entry, NewRDN, DelOldRDN, NewSup) when is_list(Entry), is_list(NewRDN), is_atom(DelOldRDN), is_list(NewSup) -> Handle1 = get_handle(Handle), gen_fsm:sync_send_event( Handle1, {modify_dn, Entry, NewRDN, bool_p(DelOldRDN), optional(NewSup)}, ?CALL_TIMEOUT). modify_passwd(Handle, DN, Passwd) when is_list(DN), is_list(Passwd) -> Handle1 = get_handle(Handle), gen_fsm:sync_send_event( Handle1, {modify_passwd, DN, Passwd}, ?CALL_TIMEOUT). %%% -------------------------------------------------------------------- %%% Bind. %%% Example: %%% %%% bind(Handle, %%% "cn=Bill Valentine, ou=people, o=Bluetail AB, dc=bluetail, dc=com", %%% "secret") %%% -------------------------------------------------------------------- bind(Handle, RootDN, Passwd) when is_list(RootDN), is_list(Passwd) -> Handle1 = get_handle(Handle), gen_fsm:sync_send_event(Handle1, {bind, RootDN, Passwd}, ?CALL_TIMEOUT). %%% Sanity checks ! bool_p(Bool) when Bool==true;Bool==false -> Bool. optional([]) -> asn1_NOVALUE; optional(Value) -> Value. %%% -------------------------------------------------------------------- %%% Synchronous search of the Directory returning a %%% requested set of attributes. %%% %%% Example: %%% %%% Filter = eldap:substrings("sn", [{any,"o"}]), %%% eldap:search(S, [{base, "dc=bluetail, dc=com"}, %%% {filter, Filter}, %%% {attributes,["cn"]}])), %%% %%% Returned result: {ok, #eldap_search_result{}} %%% %%% Example: %%% %%% {ok,{eldap_search_result, %%% [{eldap_entry, %%% "cn=Magnus Froberg, dc=bluetail, dc=com", %%% [{"cn",["Magnus Froberg"]}]}, %%% {eldap_entry, %%% "cn=Torbjorn Tornkvist, dc=bluetail, dc=com", %%% [{"cn",["Torbjorn Tornkvist"]}]}], %%% []}} %%% %%% -------------------------------------------------------------------- search(Handle, A) when is_record(A, eldap_search) -> call_search(Handle, A); search(Handle, L) when is_list(L) -> case catch parse_search_args(L) of {error, Emsg} -> {error, Emsg}; {'EXIT', Emsg} -> {error, Emsg}; A when is_record(A, eldap_search) -> call_search(Handle, A) end. call_search(Handle, A) -> Handle1 = get_handle(Handle), gen_fsm:sync_send_event(Handle1, {search, A}, ?CALL_TIMEOUT). parse_search_args(Args) -> parse_search_args(Args, #eldap_search{scope = wholeSubtree}). parse_search_args([{base, Base}|T],A) -> parse_search_args(T,A#eldap_search{base = Base}); parse_search_args([{filter, Filter}|T],A) -> parse_search_args(T,A#eldap_search{filter = Filter}); parse_search_args([{scope, Scope}|T],A) -> parse_search_args(T,A#eldap_search{scope = Scope}); parse_search_args([{attributes, Attrs}|T],A) -> parse_search_args(T,A#eldap_search{attributes = Attrs}); parse_search_args([{types_only, TypesOnly}|T],A) -> parse_search_args(T,A#eldap_search{types_only = TypesOnly}); parse_search_args([{timeout, Timeout}|T],A) when is_integer(Timeout) -> parse_search_args(T,A#eldap_search{timeout = Timeout}); parse_search_args([{limit, Limit}|T],A) when is_integer(Limit) -> parse_search_args(T,A#eldap_search{limit = Limit}); parse_search_args([{deref_aliases, never}|T],A) -> parse_search_args(T,A#eldap_search{deref_aliases = neverDerefAliases}); parse_search_args([{deref_aliases, searching}|T],A) -> parse_search_args(T,A#eldap_search{deref_aliases = derefInSearching}); parse_search_args([{deref_aliases, finding}|T],A) -> parse_search_args(T,A#eldap_search{deref_aliases = derefFindingBaseObj}); parse_search_args([{deref_aliases, always}|T],A) -> parse_search_args(T,A#eldap_search{deref_aliases = derefAlways}); parse_search_args([H|_],_) -> throw({error,{unknown_arg, H}}); parse_search_args([],A) -> A. %%% %%% The Scope parameter %%% baseObject() -> baseObject. singleLevel() -> singleLevel. wholeSubtree() -> wholeSubtree. %%% %%% Boolean filter operations %%% 'and'(ListOfFilters) when is_list(ListOfFilters) -> {'and',ListOfFilters}. 'or'(ListOfFilters) when is_list(ListOfFilters) -> {'or', ListOfFilters}. 'not'(Filter) when is_tuple(Filter) -> {'not',Filter}. %%% %%% The following Filter parameters consist of an attribute %%% and an attribute value. Example: F("uid","tobbe") %%% equalityMatch(Desc, Value) -> {equalityMatch, av_assert(Desc, Value)}. greaterOrEqual(Desc, Value) -> {greaterOrEqual, av_assert(Desc, Value)}. lessOrEqual(Desc, Value) -> {lessOrEqual, av_assert(Desc, Value)}. approxMatch(Desc, Value) -> {approxMatch, av_assert(Desc, Value)}. av_assert(Desc, Value) -> #'AttributeValueAssertion'{attributeDesc = Desc, assertionValue = Value}. %%% %%% Filter to check for the presence of an attribute %%% present(Attribute) when is_list(Attribute) -> {present, Attribute}. %%% %%% A substring filter seem to be based on a pattern: %%% %%% InitValue*AnyValue*FinalValue %%% %%% where all three parts seem to be optional (at least when %%% talking with an OpenLDAP server). Thus, the arguments %%% to substrings/2 looks like this: %%% %%% Type ::= string( ) %%% SubStr ::= listof( {initial,Value} | {any,Value}, {final,Value}) %%% %%% Example: substrings("sn",[{initial,"To"},{any,"kv"},{final,"st"}]) %%% will match entries containing: 'sn: Tornkvist' %%% substrings(Type, SubStr) when is_list(Type), is_list(SubStr) -> Ss = {'SubstringFilter_substrings',v_substr(SubStr)}, {substrings,#'SubstringFilter'{type = Type, substrings = Ss}}. %%% %%% extensibleMatch filter. %%% FIXME: Describe the purpose of this filter. %%% %%% Value ::= string( ) %%% Opts ::= listof( {matchingRule, Str} | {type, Str} | {dnAttributes, true} ) %%% %%% Example: extensibleMatch("Fred", [{matchingRule, "1.2.3.4.5"}, {type, "cn"}]). %%% extensibleMatch(Value, Opts) when is_list(Value), is_list(Opts) -> MRA = #'MatchingRuleAssertion'{matchValue=Value}, {extensibleMatch, extensibleMatch_opts(Opts, MRA)}. extensibleMatch_opts([{matchingRule, Rule} | Opts], MRA) when is_list(Rule) -> extensibleMatch_opts(Opts, MRA#'MatchingRuleAssertion'{matchingRule=Rule}); extensibleMatch_opts([{type, Desc} | Opts], MRA) when is_list(Desc) -> extensibleMatch_opts(Opts, MRA#'MatchingRuleAssertion'{type=Desc}); extensibleMatch_opts([{dnAttributes, true} | Opts], MRA) -> extensibleMatch_opts(Opts, MRA#'MatchingRuleAssertion'{dnAttributes=true}); extensibleMatch_opts([_ | Opts], MRA) -> extensibleMatch_opts(Opts, MRA); extensibleMatch_opts([], MRA) -> MRA. get_handle(Pid) when is_pid(Pid) -> Pid; get_handle(Atom) when is_atom(Atom) -> Atom; get_handle(Name) when is_list(Name) -> list_to_atom("eldap_" ++ Name). %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, StateName, StateData} | %% {ok, StateName, StateData, Timeout} | %% ignore | %% {stop, StopReason} %% I use the trick of setting a timeout of 0 to pass control into the %% process. %%---------------------------------------------------------------------- init([]) -> case get_config() of {ok, Hosts, Port, Rootdn, Passwd, Opts} -> init({Hosts, Port, Rootdn, Passwd, Opts}); {error, Reason} -> {stop, Reason} end; init({Hosts, Port, Rootdn, Passwd, Opts}) -> catch ssl:start(), %% ssl:seed was removed in OTP R14B04, newer Dialyzer will complain catch ssl:seed(randoms:get_string()), Encrypt = case proplists:get_value(encrypt, Opts) of tls -> tls; _ -> none end, PortTemp = case Port of undefined -> case Encrypt of tls -> ?LDAPS_PORT; _ -> ?LDAP_PORT end; PT -> PT end, CacertOpts = case proplists:get_value(tls_cacertfile, Opts) of [_|_] = Path -> [{cacertfile, Path}]; _ -> [] end, DepthOpts = case proplists:get_value(tls_depth, Opts) of Depth when is_integer(Depth), Depth >= 0 -> [{depth, Depth}]; _ -> [] end, Verify = proplists:get_value(tls_verify, Opts), TLSOpts = if (Verify == hard orelse Verify == soft) andalso CacertOpts == [] -> ?WARNING_MSG("TLS verification is enabled " "but no CA certfiles configured, so " "verification is disabled.", []), []; Verify == soft -> [{verify, 1}] ++ CacertOpts ++ DepthOpts; Verify == hard -> [{verify, 2}] ++ CacertOpts ++ DepthOpts; true -> [] end, {ok, connecting, #eldap{hosts = Hosts, port = PortTemp, rootdn = Rootdn, passwd = Passwd, tls = Encrypt, tls_options = TLSOpts, id = 0, dict = dict:new(), req_q = queue:new()}, 0}. %%---------------------------------------------------------------------- %% Func: StateName/2 %% Called when gen_fsm:send_event/2,3 is invoked (async) %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- connecting(timeout, S) -> {ok, NextState, NewS} = connect_bind(S), {next_state, NextState, NewS}. %%---------------------------------------------------------------------- %% Func: StateName/3 %% Called when gen_fsm:sync_send_event/2,3 is invoked. %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- connecting(Event, From, S) -> Q = queue:in({Event, From}, S#eldap.req_q), {next_state, connecting, S#eldap{req_q=Q}}. wait_bind_response(Event, From, S) -> Q = queue:in({Event, From}, S#eldap.req_q), {next_state, wait_bind_response, S#eldap{req_q=Q}}. active_bind(Event, From, S) -> Q = queue:in({Event, From}, S#eldap.req_q), {next_state, active_bind, S#eldap{req_q=Q}}. active(Event, From, S) -> process_command(S, Event, From). %%---------------------------------------------------------------------- %% Func: handle_event/3 %% Called when gen_fsm:send_all_state_event/2 is invoked. %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_event(close, _StateName, S) -> catch (S#eldap.sockmod):close(S#eldap.fd), {stop, normal, S}; handle_event(_Event, StateName, S) -> {next_state, StateName, S}. %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 %% Called when gen_fsm:sync_send_all_state_event/2,3 is invoked %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- handle_sync_event(_Event, _From, StateName, S) -> {reply, {StateName, S}, StateName, S}. %%---------------------------------------------------------------------- %% Func: handle_info/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- %% %% Packets arriving in various states %% handle_info({Tag, _Socket, Data}, connecting, S) when Tag == tcp; Tag == ssl -> ?DEBUG("tcp packet received when disconnected!~n~p", [Data]), {next_state, connecting, S}; handle_info({Tag, _Socket, Data}, wait_bind_response, S) when Tag == tcp; Tag == ssl -> cancel_timer(S#eldap.bind_timer), case catch recvd_wait_bind_response(Data, S) of bound -> dequeue_commands(S); {fail_bind, Reason} -> report_bind_failure(S#eldap.host, S#eldap.port, Reason), {next_state, connecting, close_and_retry(S, ?GRACEFUL_RETRY_TIMEOUT)}; {'EXIT', Reason} -> report_bind_failure(S#eldap.host, S#eldap.port, Reason), {next_state, connecting, close_and_retry(S)}; {error, Reason} -> report_bind_failure(S#eldap.host, S#eldap.port, Reason), {next_state, connecting, close_and_retry(S)} end; handle_info({Tag, _Socket, Data}, StateName, S) when (StateName == active orelse StateName == active_bind) andalso (Tag == tcp orelse Tag == ssl) -> case catch recvd_packet(Data, S) of {response, Response, RequestType} -> NewS = case Response of {reply, Reply, To, S1} -> gen_fsm:reply(To, Reply), S1; {ok, S1} -> S1 end, if (StateName == active_bind andalso RequestType == bindRequest) orelse (StateName == active) -> dequeue_commands(NewS); true -> {next_state, StateName, NewS} end; _ -> {next_state, StateName, S} end; handle_info({Tag, _Socket}, Fsm_state, S) when Tag == tcp_closed; Tag == ssl_closed -> ?WARNING_MSG("LDAP server closed the connection: ~s:~p~nIn State: ~p", [S#eldap.host, S#eldap.port ,Fsm_state]), {next_state, connecting, close_and_retry(S)}; handle_info({Tag, _Socket, Reason}, Fsm_state, S) when Tag == tcp_error; Tag == ssl_error -> ?DEBUG("eldap received tcp_error: ~p~nIn State: ~p", [Reason, Fsm_state]), {next_state, connecting, close_and_retry(S)}; %% %% Timers %% handle_info({timeout, Timer, {cmd_timeout, Id}}, StateName, S) -> case cmd_timeout(Timer, Id, S) of {reply, To, Reason, NewS} -> gen_fsm:reply(To, Reason), {next_state, StateName, NewS}; {error, _Reason} -> {next_state, StateName, S} end; handle_info({timeout, retry_connect}, connecting, S) -> {ok, NextState, NewS} = connect_bind(S), {next_state, NextState, NewS}; handle_info({timeout, _Timer, bind_timeout}, wait_bind_response, S) -> {next_state, connecting, close_and_retry(S)}; %% %% Make sure we don't fill the message queue with rubbish %% handle_info(Info, StateName, S) -> ?DEBUG("eldap. Unexpected Info: ~p~nIn state: ~p~n when StateData is: ~p", [Info, StateName, S]), {next_state, StateName, S}. %%---------------------------------------------------------------------- %% Func: terminate/3 %% Purpose: Shutdown the fsm %% Returns: any %%---------------------------------------------------------------------- terminate(_Reason, _StateName, _StatData) -> ok. %%---------------------------------------------------------------------- %% Func: code_change/4 %% Purpose: Convert process state when code is changed %% Returns: {ok, NewState, NewStateData} %%---------------------------------------------------------------------- code_change(_OldVsn, StateName, S, _Extra) -> {ok, StateName, S}. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- dequeue_commands(S) -> case queue:out(S#eldap.req_q) of {{value, {Event, From}}, Q} -> case process_command(S#eldap{req_q=Q}, Event, From) of {_, active, NewS} -> dequeue_commands(NewS); Res -> Res end; {empty, _} -> {next_state, active, S} end. process_command(S, Event, From) -> case send_command(Event, From, S) of {ok, NewS} -> case Event of {bind, _, _} -> {next_state, active_bind, NewS}; _ -> {next_state, active, NewS} end; {error, _Reason} -> Q = queue:in_r({Event, From}, S#eldap.req_q), NewS = close_and_retry(S#eldap{req_q=Q}), {next_state, connecting, NewS} end. send_command(Command, From, S) -> Id = bump_id(S), {Name, Request} = gen_req(Command), Message = #'LDAPMessage'{messageID = Id, protocolOp = {Name, Request}}, ?DEBUG("~p~n",[{Name, Request}]), {ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', Message), case (S#eldap.sockmod):send(S#eldap.fd, Bytes) of ok -> Timer = erlang:start_timer(?CMD_TIMEOUT, self(), {cmd_timeout, Id}), New_dict = dict:store(Id, [{Timer, Command, From, Name}], S#eldap.dict), {ok, S#eldap{id = Id, dict = New_dict}}; Error -> Error end. gen_req({search, A}) -> {searchRequest, #'SearchRequest'{baseObject = A#eldap_search.base, scope = v_scope(A#eldap_search.scope), derefAliases = A#eldap_search.deref_aliases, sizeLimit = A#eldap_search.limit, timeLimit = v_timeout(A#eldap_search.timeout), typesOnly = v_bool(A#eldap_search.types_only), filter = v_filter(A#eldap_search.filter), attributes = v_attributes(A#eldap_search.attributes) }}; gen_req({add, Entry, Attrs}) -> {addRequest, #'AddRequest'{entry = Entry, attributes = Attrs}}; gen_req({delete, Entry}) -> {delRequest, Entry}; gen_req({modify, Obj, Mod}) -> v_modifications(Mod), {modifyRequest, #'ModifyRequest'{object = Obj, modification = Mod}}; gen_req({modify_dn, Entry, NewRDN, DelOldRDN, NewSup}) -> {modDNRequest, #'ModifyDNRequest'{entry = Entry, newrdn = NewRDN, deleteoldrdn = DelOldRDN, newSuperior = NewSup}}; gen_req({modify_passwd, DN, Passwd}) -> {ok, ReqVal} = asn1rt:encode( 'ELDAPv3', 'PasswdModifyRequestValue', #'PasswdModifyRequestValue'{ userIdentity = DN, newPasswd = Passwd}), {extendedReq, #'ExtendedRequest'{requestName = ?passwdModifyOID, requestValue = list_to_binary(ReqVal)}}; gen_req({bind, RootDN, Passwd}) -> {bindRequest, #'BindRequest'{version = ?LDAP_VERSION, name = RootDN, authentication = {simple, Passwd}}}. %%----------------------------------------------------------------------- %% recvd_packet %% Deals with incoming packets in the active state %% Will return one of: %% {ok, NewS} - Don't reply to client yet as this is part of a search %% result and we haven't got all the answers yet. %% {reply, Result, From, NewS} - Reply with result to client From %% {error, Reason} %% {'EXIT', Reason} - Broke %%----------------------------------------------------------------------- recvd_packet(Pkt, S) -> check_tag(Pkt), case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of {ok,Msg} -> Op = Msg#'LDAPMessage'.protocolOp, ?DEBUG("~p",[Op]), Dict = S#eldap.dict, Id = Msg#'LDAPMessage'.messageID, {Timer, From, Name, Result_so_far} = get_op_rec(Id, Dict), Answer = case {Name, Op} of {searchRequest, {searchResEntry, R}} when is_record(R,'SearchResultEntry') -> New_dict = dict:append(Id, R, Dict), {ok, S#eldap{dict = New_dict}}; {searchRequest, {searchResDone, Result}} -> Reason = Result#'LDAPResult'.resultCode, if Reason==success; Reason=='sizeLimitExceeded' -> {Res, Ref} = polish(Result_so_far), New_dict = dict:erase(Id, Dict), cancel_timer(Timer), {reply, #eldap_search_result{entries = Res, referrals = Ref}, From, S#eldap{dict = New_dict}}; true -> New_dict = dict:erase(Id, Dict), cancel_timer(Timer), {reply, {error, Reason}, From, S#eldap{dict = New_dict}} end; {searchRequest, {searchResRef, R}} -> New_dict = dict:append(Id, R, Dict), {ok, S#eldap{dict = New_dict}}; {addRequest, {addResponse, Result}} -> New_dict = dict:erase(Id, Dict), cancel_timer(Timer), Reply = check_reply(Result, From), {reply, Reply, From, S#eldap{dict = New_dict}}; {delRequest, {delResponse, Result}} -> New_dict = dict:erase(Id, Dict), cancel_timer(Timer), Reply = check_reply(Result, From), {reply, Reply, From, S#eldap{dict = New_dict}}; {modifyRequest, {modifyResponse, Result}} -> New_dict = dict:erase(Id, Dict), cancel_timer(Timer), Reply = check_reply(Result, From), {reply, Reply, From, S#eldap{dict = New_dict}}; {modDNRequest, {modDNResponse, Result}} -> New_dict = dict:erase(Id, Dict), cancel_timer(Timer), Reply = check_reply(Result, From), {reply, Reply, From, S#eldap{dict = New_dict}}; {bindRequest, {bindResponse, Result}} -> New_dict = dict:erase(Id, Dict), cancel_timer(Timer), Reply = check_bind_reply(Result, From), {reply, Reply, From, S#eldap{dict = New_dict}}; {extendedReq, {extendedResp, Result}} -> New_dict = dict:erase(Id, Dict), cancel_timer(Timer), Reply = check_extended_reply(Result, From), {reply, Reply, From, S#eldap{dict = New_dict}}; {OtherName, OtherResult} -> New_dict = dict:erase(Id, Dict), cancel_timer(Timer), {reply, {error, {invalid_result, OtherName, OtherResult}}, From, S#eldap{dict = New_dict}} end, {response, Answer, Name}; Error -> Error end. check_reply(#'LDAPResult'{resultCode = success}, _From) -> ok; check_reply(#'LDAPResult'{resultCode = Reason}, _From) -> {error, Reason}; check_reply(Other, _From) -> {error, Other}. check_bind_reply(#'BindResponse'{resultCode = success}, _From) -> ok; check_bind_reply(#'BindResponse'{resultCode = Reason}, _From) -> {error, Reason}; check_bind_reply(Other, _From) -> {error, Other}. %% TODO: process reply depending on requestName: %% this requires BER-decoding of #'ExtendedResponse'.response check_extended_reply(#'ExtendedResponse'{resultCode = success}, _From) -> ok; check_extended_reply(#'ExtendedResponse'{resultCode = Reason}, _From) -> {error, Reason}; check_extended_reply(Other, _From) -> {error, Other}. get_op_rec(Id, Dict) -> case dict:find(Id, Dict) of {ok, [{Timer, _Command, From, Name}|Res]} -> {Timer, From, Name, Res}; error -> throw({error, unkown_id}) end. %%----------------------------------------------------------------------- %% recvd_wait_bind_response packet %% Deals with incoming packets in the wait_bind_response state %% Will return one of: %% bound - Success - move to active state %% {fail_bind, Reason} - Failed %% {error, Reason} %% {'EXIT', Reason} - Broken packet %%----------------------------------------------------------------------- recvd_wait_bind_response(Pkt, S) -> check_tag(Pkt), case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of {ok,Msg} -> ?DEBUG("~p", [Msg]), check_id(S#eldap.id, Msg#'LDAPMessage'.messageID), case Msg#'LDAPMessage'.protocolOp of {bindResponse, Result} -> case Result#'BindResponse'.resultCode of success -> bound; Error -> {fail_bind, Error} end end; Else -> {fail_bind, Else} end. check_id(Id, Id) -> ok; check_id(_, _) -> throw({error, wrong_bind_id}). %%----------------------------------------------------------------------- %% General Helpers %%----------------------------------------------------------------------- cancel_timer(Timer) -> erlang:cancel_timer(Timer), receive {timeout, Timer, _} -> ok after 0 -> ok end. %%% Sanity check of received packet check_tag(Data) -> {_Tag, Data1, _Rb} = asn1rt_ber_bin:decode_tag(Data), {{_Len,_Data2}, _Rb2} = asn1rt_ber_bin:decode_length(Data1), ok. close_and_retry(S, Timeout) -> catch (S#eldap.sockmod):close(S#eldap.fd), Queue = dict:fold( fun(_Id, [{Timer, Command, From, _Name}|_], Q) -> cancel_timer(Timer), queue:in_r({Command, From}, Q); (_, _, Q) -> Q end, S#eldap.req_q, S#eldap.dict), erlang:send_after(Timeout, self(), {timeout, retry_connect}), S#eldap{fd=null, req_q=Queue, dict=dict:new()}. close_and_retry(S) -> close_and_retry(S, ?RETRY_TIMEOUT). report_bind_failure(Host, Port, Reason) -> ?WARNING_MSG("LDAP bind failed on ~s:~p~nReason: ~p", [Host, Port, Reason]). %%----------------------------------------------------------------------- %% Sort out timed out commands %%----------------------------------------------------------------------- cmd_timeout(Timer, Id, S) -> Dict = S#eldap.dict, case dict:find(Id, Dict) of {ok, [{Timer, _Command, From, Name}|Res]} -> case Name of searchRequest -> {Res1, Ref1} = polish(Res), New_dict = dict:erase(Id, Dict), {reply, From, {timeout, #eldap_search_result{entries = Res1, referrals = Ref1}}, S#eldap{dict = New_dict}}; _ -> New_dict = dict:erase(Id, Dict), {reply, From, {error, timeout}, S#eldap{dict = New_dict}} end; error -> {error, timed_out_cmd_not_in_dict} end. %%----------------------------------------------------------------------- %% Common stuff for results %%----------------------------------------------------------------------- %%% %%% Polish the returned search result %%% polish(Entries) -> polish(Entries, [], []). polish([H|T], Res, Ref) when is_record(H, 'SearchResultEntry') -> ObjectName = H#'SearchResultEntry'.objectName, F = fun({_,A,V}) -> {A,V} end, Attrs = lists:map(F, H#'SearchResultEntry'.attributes), polish(T, [#eldap_entry{object_name = ObjectName, attributes = Attrs}|Res], Ref); polish([H|T], Res, Ref) -> % No special treatment of referrals at the moment. polish(T, Res, [H|Ref]); polish([], Res, Ref) -> {Res, Ref}. %%----------------------------------------------------------------------- %% Connect to next server in list and attempt to bind to it. %%----------------------------------------------------------------------- connect_bind(S) -> Host = next_host(S#eldap.host, S#eldap.hosts), ?INFO_MSG("LDAP connection on ~s:~p", [Host, S#eldap.port]), Opts = if S#eldap.tls == tls -> [{packet, asn1}, {active, true}, {keepalive, true}, binary | S#eldap.tls_options]; true -> [{packet, asn1}, {active, true}, {keepalive, true}, {send_timeout, ?SEND_TIMEOUT}, binary] end, SocketData = case S#eldap.tls of tls -> SockMod = ssl, ssl:connect(Host, S#eldap.port, Opts); %% starttls -> %% TODO: Implement STARTTLS; _ -> SockMod = gen_tcp, gen_tcp:connect(Host, S#eldap.port, Opts) end, case SocketData of {ok, Socket} -> case bind_request(Socket, S#eldap{sockmod = SockMod}) of {ok, NewS} -> Timer = erlang:start_timer(?BIND_TIMEOUT, self(), {timeout, bind_timeout}), {ok, wait_bind_response, NewS#eldap{fd = Socket, sockmod = SockMod, host = Host, bind_timer = Timer}}; {error, Reason} -> report_bind_failure(Host, S#eldap.port, Reason), NewS = close_and_retry(S), {ok, connecting, NewS#eldap{host = Host}} end; {error, Reason} -> ?ERROR_MSG("LDAP connection failed:~n" "** Server: ~s:~p~n" "** Reason: ~p~n" "** Socket options: ~p", [Host, S#eldap.port, Reason, Opts]), NewS = close_and_retry(S), {ok, connecting, NewS#eldap{host = Host}} end. bind_request(Socket, S) -> Id = bump_id(S), Req = #'BindRequest'{version = S#eldap.version, name = S#eldap.rootdn, authentication = {simple, S#eldap.passwd}}, Message = #'LDAPMessage'{messageID = Id, protocolOp = {bindRequest, Req}}, ?DEBUG("Bind Request Message:~p~n",[Message]), {ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', Message), case (S#eldap.sockmod):send(Socket, Bytes) of ok -> {ok, S#eldap{id = Id}}; Error -> Error end. %% Given last tried Server, find next one to try next_host(null, [H|_]) -> H; % First time, take first next_host(Host, Hosts) -> % Find next in turn next_host(Host, Hosts, Hosts). next_host(Host, [Host], Hosts) -> hd(Hosts); % Wrap back to first next_host(Host, [Host|Tail], _Hosts) -> hd(Tail); % Take next next_host(_Host, [], Hosts) -> hd(Hosts); % Never connected before? (shouldn't happen) next_host(Host, [_|T], Hosts) -> next_host(Host, T, Hosts). %%% -------------------------------------------------------------------- %%% Verify the input data %%% -------------------------------------------------------------------- v_filter({'and',L}) -> {'and',L}; v_filter({'or', L}) -> {'or',L}; v_filter({'not',L}) -> {'not',L}; v_filter({equalityMatch,AV}) -> {equalityMatch,AV}; v_filter({greaterOrEqual,AV}) -> {greaterOrEqual,AV}; v_filter({lessOrEqual,AV}) -> {lessOrEqual,AV}; v_filter({approxMatch,AV}) -> {approxMatch,AV}; v_filter({present,A}) -> {present,A}; v_filter({substrings,S}) when is_record(S,'SubstringFilter') -> {substrings,S}; v_filter({extensibleMatch, S}) when is_record(S, 'MatchingRuleAssertion') -> {extensibleMatch, S}; v_filter(_Filter) -> throw({error,concat(["unknown filter: ",_Filter])}). v_modifications(Mods) -> F = fun({_,Op,_}) -> case lists:member(Op,[add,delete,replace]) of true -> true; _ -> throw({error,{mod_operation,Op}}) end end, lists:foreach(F, Mods). v_substr([{Key,Str}|T]) when is_list(Str),Key==initial;Key==any;Key==final -> [{Key,Str}|v_substr(T)]; v_substr([H|_]) -> throw({error,{substring_arg,H}}); v_substr([]) -> []. v_scope(baseObject) -> baseObject; v_scope(singleLevel) -> singleLevel; v_scope(wholeSubtree) -> wholeSubtree; v_scope(_Scope) -> throw({error,concat(["unknown scope: ",_Scope])}). v_bool(true) -> true; v_bool(false) -> false; v_bool(_Bool) -> throw({error,concat(["not Boolean: ",_Bool])}). v_timeout(I) when is_integer(I), I>=0 -> I; v_timeout(_I) -> throw({error,concat(["timeout not positive integer: ",_I])}). v_attributes(Attrs) -> F = fun(A) when is_list(A) -> A; (A) -> throw({error,concat(["attribute not String: ",A])}) end, lists:map(F,Attrs). %%% -------------------------------------------------------------------- %%% Get and Validate the initial configuration %%% -------------------------------------------------------------------- get_config() -> Priv_dir = code:priv_dir(eldap), File = filename:join(Priv_dir, "eldap.conf"), case file:consult(File) of {ok, Entries} -> case catch parse(Entries) of {ok, Hosts, Port, Rootdn, Passwd, Opts} -> {ok, Hosts, Port, Rootdn, Passwd, Opts}; {error, Reason} -> {error, Reason}; {'EXIT', Reason} -> {error, Reason} end; {error, Reason} -> {error, Reason} end. parse(Entries) -> {ok, get_hosts(host, Entries), get_integer(port, Entries), get_list(rootdn, Entries), get_list(passwd, Entries), get_list(options, Entries)}. get_integer(Key, List) -> case lists:keysearch(Key, 1, List) of {value, {Key, Value}} when is_integer(Value) -> Value; {value, {Key, _Value}} -> throw({error, "Bad Value in Config for " ++ atom_to_list(Key)}); false -> throw({error, "No Entry in Config for " ++ atom_to_list(Key)}) end. get_list(Key, List) -> case lists:keysearch(Key, 1, List) of {value, {Key, Value}} when is_list(Value) -> Value; {value, {Key, _Value}} -> throw({error, "Bad Value in Config for " ++ atom_to_list(Key)}); false -> throw({error, "No Entry in Config for " ++ atom_to_list(Key)}) end. %% get_atom(Key, List) -> %% case lists:keysearch(Key, 1, List) of %% {value, {Key, Value}} when is_atom(Value) -> %% Value; %% {value, {Key, _Value}} -> %% throw({error, "Bad Value in Config for " ++ atom_to_list(Key)}); %% false -> %% throw({error, "No Entry in Config for " ++ atom_to_list(Key)}) %% end. get_hosts(Key, List) -> lists:map(fun({Key1, {A,B,C,D}}) when is_integer(A), is_integer(B), is_integer(C), is_integer(D), Key == Key1-> {A,B,C,D}; ({Key1, Value}) when is_list(Value), Key == Key1-> Value; ({_Else, _Value}) -> throw({error, "Bad Hostname in config"}) end, List). %%% -------------------------------------------------------------------- %%% Other Stuff %%% -------------------------------------------------------------------- bump_id(#eldap{id = Id}) when Id > ?MAX_TRANSACTION_ID -> ?MIN_TRANSACTION_ID; bump_id(#eldap{id = Id}) -> Id + 1. ejabberd-2.1.11/src/eldap/eldap_utils.erl0000664000000000000000000001167512240230175015115 0ustar %%%---------------------------------------------------------------------- %%% File : eldap_utils.erl %%% Author : Mickael Remond %%% Purpose : ejabberd LDAP helper functions %%% Created : 12 Oct 2006 by Mickael Remond %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(eldap_utils). -author('mremond@process-one.net'). -export([generate_subfilter/1, find_ldap_attrs/2, get_ldap_attr/2, usort_attrs/1, get_user_part/2, make_filter/2, get_state/2, case_insensitive_match/2, check_filter/1, uids_domain_subst/2]). -include("ejabberd.hrl"). %% Generate an 'or' LDAP query on one or several attributes %% If there is only one attribute generate_subfilter([UID]) -> subfilter(UID); %% If there is several attributes generate_subfilter(UIDs) -> "(|" ++ [subfilter(UID) || UID <- UIDs] ++ ")". %% Subfilter for a single attribute subfilter({UIDAttr, UIDAttrFormat}) -> "(" ++ UIDAttr ++ "=" ++ UIDAttrFormat ++ ")"; %% The default UiDAttrFormat is %u subfilter({UIDAttr}) -> "(" ++ UIDAttr ++ "=" ++ "%u)". %% Not tail-recursive, but it is not very terribly. %% It stops finding on the first not empty value. find_ldap_attrs([{Attr} | Rest], Attributes) -> find_ldap_attrs([{Attr, "%u"} | Rest], Attributes); find_ldap_attrs([{Attr, Format} | Rest], Attributes) -> case get_ldap_attr(Attr, Attributes) of Value when is_list(Value), Value /= "" -> {Value, Format}; _ -> find_ldap_attrs(Rest, Attributes) end; find_ldap_attrs([], _) -> "". get_ldap_attr(LDAPAttr, Attributes) -> Res = lists:filter( fun({Name, _}) -> case_insensitive_match(Name, LDAPAttr) end, Attributes), case Res of [{_, [Value|_]}] -> Value; _ -> "" end. usort_attrs(Attrs) when is_list(Attrs) -> lists:usort(Attrs); usort_attrs(_) -> []. get_user_part(String, Pattern) -> F = fun(S, P) -> First = string:str(P, "%u"), TailLength = length(P) - (First+1), string:sub_string(S, First, length(S) - TailLength) end, case catch F(String, Pattern) of {'EXIT', _} -> {error, badmatch}; Result -> case catch ejabberd_regexp:replace(Pattern, "%u", Result) of {'EXIT', _} -> {error, badmatch}; StringRes -> case (string:to_lower(StringRes) == string:to_lower(String)) of true -> {ok, Result}; false -> {error, badmatch} end end end. make_filter(Data, UIDs) -> NewUIDs = [{U, eldap_filter:do_sub(UF, [{"%u", "*%u*", 1}])} || {U, UF} <- UIDs], Filter = lists:flatmap( fun({Name, [Value | _]}) -> case Name of "%u" when Value /= "" -> case eldap_filter:parse( lists:flatten(generate_subfilter(NewUIDs)), [{"%u", Value}]) of {ok, F} -> [F]; _ -> [] end; _ when Value /= "" -> [eldap:substrings(Name, [{any, Value}])]; _ -> [] end end, Data), case Filter of [F] -> F; _ -> eldap:'and'(Filter) end. case_insensitive_match(X, Y) -> X1 = stringprep:tolower(X), Y1 = stringprep:tolower(Y), if X1 == Y1 -> true; true -> false end. get_state(Server, Module) -> Proc = gen_mod:get_module_proc(Server, Module), gen_server:call(Proc, get_state). %% From the list of uids attribute: %% we look from alias domain (%d) and make the substitution %% with the actual host domain %% This help when you need to configure many virtual domains. uids_domain_subst(Host, UIDs) -> lists:map(fun({U,V}) -> {U, eldap_filter:do_sub(V,[{"%d", Host}])}; (A) -> A end, UIDs). check_filter(undefined) -> ok; check_filter(Filter) -> case eldap_filter:parse(Filter) of {ok, _} -> ok; Err -> ?ERROR_MSG("failed to parse LDAP filter:~n" "** Filter: ~p~n" "** Reason: ~p", [Filter, Err]) end. ejabberd-2.1.11/src/eldap/ELDAPv3.asn0000664000000000000000000002471412240230175013703 0ustar -- LDAPv3 ASN.1 specification, taken from RFC 2251 -- Lightweight-Directory-Access-Protocol-V3 DEFINITIONS ELDAPv3 DEFINITIONS IMPLICIT TAGS ::= BEGIN LDAPMessage ::= SEQUENCE { messageID MessageID, protocolOp CHOICE { bindRequest BindRequest, bindResponse BindResponse, unbindRequest UnbindRequest, searchRequest SearchRequest, searchResEntry SearchResultEntry, searchResDone SearchResultDone, searchResRef SearchResultReference, modifyRequest ModifyRequest, modifyResponse ModifyResponse, addRequest AddRequest, addResponse AddResponse, delRequest DelRequest, delResponse DelResponse, modDNRequest ModifyDNRequest, modDNResponse ModifyDNResponse, compareRequest CompareRequest, compareResponse CompareResponse, abandonRequest AbandonRequest, extendedReq ExtendedRequest, extendedResp ExtendedResponse }, controls [0] Controls OPTIONAL } MessageID ::= INTEGER (0 .. maxInt) maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) -- LDAPString ::= OCTET STRING LDAPOID ::= OCTET STRING LDAPDN ::= LDAPString RelativeLDAPDN ::= LDAPString AttributeType ::= LDAPString AttributeDescription ::= LDAPString -- Wahl, et. al. Standards Track [Page 44] -- -- RFC 2251 LDAPv3 December 1997 AttributeDescriptionList ::= SEQUENCE OF AttributeDescription AttributeValue ::= OCTET STRING AttributeValueAssertion ::= SEQUENCE { attributeDesc AttributeDescription, assertionValue AssertionValue } AssertionValue ::= OCTET STRING Attribute ::= SEQUENCE { type AttributeDescription, vals SET OF AttributeValue } MatchingRuleId ::= LDAPString LDAPResult ::= SEQUENCE { resultCode ENUMERATED { success (0), operationsError (1), protocolError (2), timeLimitExceeded (3), sizeLimitExceeded (4), compareFalse (5), compareTrue (6), authMethodNotSupported (7), strongAuthRequired (8), -- 9 reserved -- referral (10), -- new adminLimitExceeded (11), -- new unavailableCriticalExtension (12), -- new confidentialityRequired (13), -- new saslBindInProgress (14), -- new noSuchAttribute (16), undefinedAttributeType (17), inappropriateMatching (18), constraintViolation (19), attributeOrValueExists (20), invalidAttributeSyntax (21), -- 22-31 unused -- noSuchObject (32), aliasProblem (33), invalidDNSyntax (34), -- 35 reserved for undefined isLeaf -- aliasDereferencingProblem (36), -- 37-47 unused -- inappropriateAuthentication (48), -- Wahl, et. al. Standards Track [Page 45] -- -- RFC 2251 LDAPv3 December 1997 invalidCredentials (49), insufficientAccessRights (50), busy (51), unavailable (52), unwillingToPerform (53), loopDetect (54), -- 55-63 unused -- namingViolation (64), objectClassViolation (65), notAllowedOnNonLeaf (66), notAllowedOnRDN (67), entryAlreadyExists (68), objectClassModsProhibited (69), -- 70 reserved for CLDAP -- affectsMultipleDSAs (71), -- new -- 72-79 unused -- other (80) }, -- 81-90 reserved for APIs -- matchedDN LDAPDN, errorMessage LDAPString, referral [3] Referral OPTIONAL } Referral ::= SEQUENCE OF LDAPURL LDAPURL ::= LDAPString -- limited to characters permitted in URLs Controls ::= SEQUENCE OF Control Control ::= SEQUENCE { controlType LDAPOID, criticality BOOLEAN DEFAULT FALSE, controlValue OCTET STRING OPTIONAL } BindRequest ::= [APPLICATION 0] SEQUENCE { version INTEGER (1 .. 127), name LDAPDN, authentication AuthenticationChoice } AuthenticationChoice ::= CHOICE { simple [0] OCTET STRING, -- 1 and 2 reserved sasl [3] SaslCredentials } SaslCredentials ::= SEQUENCE { mechanism LDAPString, credentials OCTET STRING OPTIONAL } BindResponse ::= [APPLICATION 1] SEQUENCE { -- Wahl, et. al. Standards Track [Page 46] -- -- RFC 2251 LDAPv3 December 1997 COMPONENTS OF LDAPResult, serverSaslCreds [7] OCTET STRING OPTIONAL } UnbindRequest ::= [APPLICATION 2] NULL SearchRequest ::= [APPLICATION 3] SEQUENCE { baseObject LDAPDN, scope ENUMERATED { baseObject (0), singleLevel (1), wholeSubtree (2) }, derefAliases ENUMERATED { neverDerefAliases (0), derefInSearching (1), derefFindingBaseObj (2), derefAlways (3) }, sizeLimit INTEGER (0 .. maxInt), timeLimit INTEGER (0 .. maxInt), typesOnly BOOLEAN, filter Filter, attributes AttributeDescriptionList } Filter ::= CHOICE { and [0] SET OF Filter, or [1] SET OF Filter, not [2] Filter, equalityMatch [3] AttributeValueAssertion, substrings [4] SubstringFilter, greaterOrEqual [5] AttributeValueAssertion, lessOrEqual [6] AttributeValueAssertion, present [7] AttributeDescription, approxMatch [8] AttributeValueAssertion, extensibleMatch [9] MatchingRuleAssertion } SubstringFilter ::= SEQUENCE { type AttributeDescription, -- at least one must be present substrings SEQUENCE OF CHOICE { initial [0] LDAPString, any [1] LDAPString, final [2] LDAPString } } MatchingRuleAssertion ::= SEQUENCE { matchingRule [1] MatchingRuleId OPTIONAL, type [2] AttributeDescription OPTIONAL, matchValue [3] AssertionValue, dnAttributes [4] BOOLEAN DEFAULT FALSE } -- Wahl, et. al. Standards Track [Page 47] -- -- RFC 2251 LDAPv3 December 1997 SearchResultEntry ::= [APPLICATION 4] SEQUENCE { objectName LDAPDN, attributes PartialAttributeList } PartialAttributeList ::= SEQUENCE OF SEQUENCE { type AttributeDescription, vals SET OF AttributeValue } SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL SearchResultDone ::= [APPLICATION 5] LDAPResult ModifyRequest ::= [APPLICATION 6] SEQUENCE { object LDAPDN, modification SEQUENCE OF SEQUENCE { operation ENUMERATED { add (0), delete (1), replace (2) }, modification AttributeTypeAndValues } } AttributeTypeAndValues ::= SEQUENCE { type AttributeDescription, vals SET OF AttributeValue } ModifyResponse ::= [APPLICATION 7] LDAPResult AddRequest ::= [APPLICATION 8] SEQUENCE { entry LDAPDN, attributes AttributeList } AttributeList ::= SEQUENCE OF SEQUENCE { type AttributeDescription, vals SET OF AttributeValue } AddResponse ::= [APPLICATION 9] LDAPResult DelRequest ::= [APPLICATION 10] LDAPDN DelResponse ::= [APPLICATION 11] LDAPResult ModifyDNRequest ::= [APPLICATION 12] SEQUENCE { entry LDAPDN, newrdn RelativeLDAPDN, deleteoldrdn BOOLEAN, newSuperior [0] LDAPDN OPTIONAL } ModifyDNResponse ::= [APPLICATION 13] LDAPResult -- Wahl, et. al. Standards Track [Page 48] -- -- RFC 2251 LDAPv3 December 1997 CompareRequest ::= [APPLICATION 14] SEQUENCE { entry LDAPDN, ava AttributeValueAssertion } CompareResponse ::= [APPLICATION 15] LDAPResult AbandonRequest ::= [APPLICATION 16] MessageID ExtendedRequest ::= [APPLICATION 23] SEQUENCE { requestName [0] LDAPOID, requestValue [1] OCTET STRING OPTIONAL } ExtendedResponse ::= [APPLICATION 24] SEQUENCE { COMPONENTS OF LDAPResult, responseName [10] LDAPOID OPTIONAL, response [11] OCTET STRING OPTIONAL } passwdModifyOID LDAPOID ::= "1.3.6.1.4.1.4203.1.11.1" PasswdModifyRequestValue ::= SEQUENCE { userIdentity [0] OCTET STRING OPTIONAL, oldPasswd [1] OCTET STRING OPTIONAL, newPasswd [2] OCTET STRING OPTIONAL } PasswdModifyResponseValue ::= SEQUENCE { genPasswd [0] OCTET STRING OPTIONAL } END ejabberd-2.1.11/src/eldap/eldap_filter.erl0000664000000000000000000001533512240230175015237 0ustar %%%---------------------------------------------------------------------- %%% File: eldap_filter.erl %%% Purpose: Converts String Representation of %%% LDAP Search Filter (RFC 2254) %%% to eldap's representation of filter %%% Author: Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(eldap_filter). %% TODO: remove this when new regexp module will be used -compile({nowarn_deprecated_function, {regexp, sub, 3}}). -export([parse/1, parse/2, do_sub/2]). %%==================================================================== %% API %%==================================================================== %%%------------------------------------------------------------------- %%% Arity: parse/1 %%% Function: parse(RFC2254_Filter) -> {ok, EldapFilter} | %%% {error, bad_filter} %%% %%% RFC2254_Filter = string(). %%% %%% Description: Converts String Representation of LDAP Search Filter (RFC 2254) %%% to eldap's representation of filter. %%% %%% Example: %%% > eldap_filter:parse("(&(!(uid<=100))(mail=*))"). %%% %%% {ok,{'and',[{'not',{lessOrEqual,{'AttributeValueAssertion',"uid","100"}}}, %%% {present,"mail"}]}} %%%------------------------------------------------------------------- parse(L) when is_list(L) -> parse(L, []). %%%------------------------------------------------------------------- %%% Arity: parse/2 %%% Function: parse(RFC2254_Filter, [SubstValue |...]) -> %%% {ok, EldapFilter} | %%% {error, bad_filter} | %%% {error, bad_regexp} | %%% {error, max_substitute_recursion} %%% %%% SubstValue = {RegExp, Value} | {RegExp, Value, N}, %%% RFC2254_Filter = RegExp = Value = string(), %%% N = integer(). %%% %%% Description: The same as parse/1, but substitutes N or all occurences %%% of RegExp with Value *after* parsing. %%% %%% Example: %%% > eldap_filter:parse( %%% "(|(mail=%u@%d)(jid=%u@%d))", %%% [{"%u", "xramtsov"},{"%d","gmail.com"}]). %%% %%% {ok,{'or',[{equalityMatch,{'AttributeValueAssertion', %%% "mail", %%% "xramtsov@gmail.com"}}, %%% {equalityMatch,{'AttributeValueAssertion', %%% "jid", %%% "xramtsov@gmail.com"}}]}} %%%------------------------------------------------------------------- parse(L, SList) when is_list(L), is_list(SList) -> case catch eldap_filter_yecc:parse(scan(L, SList)) of {'EXIT', _} = Err -> {error, Err}; {error, {_, _, Msg}} -> {error, Msg}; {ok, Result} -> {ok, Result}; {regexp, Err} -> {error, Err} end. %%==================================================================== %% Internal functions %%==================================================================== -define(do_scan(L), scan(Rest, [], [{L, 1} | check(Buf, S) ++ Result], L, S)). scan(L, SList) -> scan(L, "", [], undefined, SList). scan("=*)" ++ Rest, Buf, Result, '(', S) -> scan(Rest, [], [{')', 1}, {'=*', 1} | check(Buf, S) ++ Result], ')', S); scan(":dn" ++ Rest, Buf, Result, '(', S) -> ?do_scan(':dn'); scan(":=" ++ Rest, Buf, Result, '(', S) -> ?do_scan(':='); scan(":=" ++ Rest, Buf, Result, ':dn', S) -> ?do_scan(':='); scan(":=" ++ Rest, Buf, Result, ':', S) -> ?do_scan(':='); scan("~=" ++ Rest, Buf, Result, '(', S) -> ?do_scan('~='); scan(">=" ++ Rest, Buf, Result, '(', S) -> ?do_scan('>='); scan("<=" ++ Rest, Buf, Result, '(', S) -> ?do_scan('<='); scan("=" ++ Rest, Buf, Result, '(', S) -> ?do_scan('='); scan(":" ++ Rest, Buf, Result, '(', S) -> ?do_scan(':'); scan(":" ++ Rest, Buf, Result, ':dn', S) -> ?do_scan(':'); scan("&" ++ Rest, Buf, Result, '(', S) when Buf=="" -> ?do_scan('&'); scan("|" ++ Rest, Buf, Result, '(', S) when Buf=="" -> ?do_scan('|'); scan("!" ++ Rest, Buf, Result, '(', S) when Buf=="" -> ?do_scan('!'); scan("*" ++ Rest, Buf, Result, '*', S) -> ?do_scan('*'); scan("*" ++ Rest, Buf, Result, '=', S) -> ?do_scan('*'); scan("(" ++ Rest, Buf, Result, _, S) -> ?do_scan('('); scan(")" ++ Rest, Buf, Result, _, S) -> ?do_scan(')'); scan([Letter | Rest], Buf, Result, PreviosAtom, S) -> scan(Rest, [Letter|Buf], Result, PreviosAtom, S); scan([], Buf, Result, _, S) -> lists:reverse(check(Buf, S) ++ Result). check([], _) -> []; check(Buf, S) -> [{str, 1, do_sub(lists:reverse(Buf), S)}]. -define(MAX_RECURSION, 100). do_sub(S, []) -> S; do_sub([], _) -> []; do_sub(S, [{RegExp, New} | T]) -> Result = do_sub(S, {RegExp, replace_amps(New)}, 1), do_sub(Result, T); do_sub(S, [{RegExp, New, Times} | T]) -> Result = do_sub(S, {RegExp, replace_amps(New), Times}, 1), do_sub(Result, T). do_sub(S, {RegExp, New}, Iter) -> case ejabberd_regexp:run(S, RegExp) of match -> case ejabberd_regexp:replace(S, RegExp, New) of NewS when Iter =< ?MAX_RECURSION -> do_sub(NewS, {RegExp, New}, Iter+1); _NewS when Iter > ?MAX_RECURSION -> erlang:error(max_substitute_recursion) end; nomatch -> S; _ -> erlang:error(bad_regexp) end; do_sub(S, {_, _, N}, _) when N<1 -> S; do_sub(S, {RegExp, New, Times}, Iter) -> case ejabberd_regexp:run(S, RegExp) of match -> case ejabberd_regexp:replace(S, RegExp, New) of NewS when Iter < Times -> do_sub(NewS, {RegExp, New, Times}, Iter+1); NewS -> NewS end; nomatch -> S; _ -> erlang:error(bad_regexp) end. replace_amps(String) -> lists:flatmap( fun($&) -> "\\&"; (Chr) -> [Chr] end, String). ejabberd-2.1.11/src/eldap/Makefile.in0000664000000000000000000000213212240230175014135 0ustar # $Id: Makefile.in 2842 2009-12-29 19:10:52Z badlop $ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ ASN_FLAGS = -bber_bin +optimize ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ EFLAGS += @ERLANG_SSLVER@ EFLAGS += -I .. EFLAGS += -pz .. # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif OUTDIR = .. SOURCES = $(wildcard *.erl) ELDAPv3.erl eldap_filter_yecc.erl BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) all: $(BEAMS) ELDAPv3.beam eldap_filter_yecc.beam ELDAPv3.beam: ELDAPv3.erl ELDAPv3.erl: ELDAPv3.asn @ERLC@ $(ASN_FLAGS) -W $(EFLAGS) $< eldap_filter_yecc.beam: eldap_filter_yecc.erl eldap_filter_yecc.erl: eldap_filter_yecc.yrl @ERLC@ -W $< $(OUTDIR)/%.beam: %.erl ELDAPv3.erl eldap_filter_yecc.erl @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< clean: rm -f ELDAPv3.asn1db rm -f ELDAPv3.erl rm -f ELDAPv3.hrl rm -f ELDAPv3.beam rm -f eldap_filter_yecc.erl rm -f eldap_filter_yecc.beam rm -f $(BEAMS) distclean: clean rm -f Makefile TAGS: etags *.erl ejabberd-2.1.11/src/eldap/eldap_pool.erl0000664000000000000000000000536612240230175014726 0ustar %%%------------------------------------------------------------------- %%% File : eldap_pool.erl %%% Author : Evgeniy Khramtsov %%% Purpose : LDAP connections pool %%% Created : 12 Nov 2006 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(eldap_pool). -author('xram@jabber.ru'). %% API -export([ start_link/7, bind/3, search/2, modify_passwd/3 ]). -include("ejabberd.hrl"). -ifdef(SSL40). -define(PG2, pg2). -else. -define(PG2, pg2_backport). -endif. %%==================================================================== %% API %%==================================================================== bind(PoolName, DN, Passwd) -> do_request(PoolName, {bind, [DN, Passwd]}). search(PoolName, Opts) -> do_request(PoolName, {search, [Opts]}). modify_passwd(PoolName, DN, Passwd) -> do_request(PoolName, {modify_passwd, [DN, Passwd]}). start_link(Name, Hosts, Backups, Port, Rootdn, Passwd, Opts) -> PoolName = make_id(Name), ?PG2:create(PoolName), lists:foreach( fun(Host) -> ID = erlang:ref_to_list(make_ref()), case catch eldap:start_link(ID, [Host|Backups], Port, Rootdn, Passwd, Opts) of {ok, Pid} -> ?PG2:join(PoolName, Pid); _ -> error end end, Hosts). %%==================================================================== %% Internal functions %%==================================================================== do_request(Name, {F, Args}) -> case ?PG2:get_closest_pid(make_id(Name)) of Pid when is_pid(Pid) -> case catch apply(eldap, F, [Pid | Args]) of {'EXIT', {timeout, _}} -> ?ERROR_MSG("LDAP request failed: timed out", []); {'EXIT', Reason} -> ?ERROR_MSG("LDAP request failed: eldap:~p(~p)~nReason: ~p", [F, Args, Reason]), {error, Reason}; Reply -> Reply end; Err -> Err end. make_id(Name) -> list_to_atom("eldap_pool_" ++ Name). ejabberd-2.1.11/src/eldap/eldap_filter_yecc.yrl0000664000000000000000000000531612240230175016264 0ustar Nonterminals filter filtercomp filterlist item simple present substring extensible initial any final matchingrule xattr attr value. Terminals str '(' ')' '&' '|' '!' '=' '~=' '>=' '<=' '=*' '*' ':dn' ':' ':='. Rootsymbol filter. filter -> '(' filtercomp ')': '$2'. filtercomp -> '&' filterlist: 'and'('$2'). filtercomp -> '|' filterlist: 'or'('$2'). filtercomp -> '!' filter: 'not'('$2'). filtercomp -> item: '$1'. filterlist -> filter: '$1'. filterlist -> filter filterlist: flatten(['$1', '$2']). item -> simple: '$1'. item -> present: '$1'. item -> substring: '$1'. item -> extensible: '$1'. simple -> attr '=' value: equal('$1', '$3'). simple -> attr '~=' value: approx('$1', '$3'). simple -> attr '>=' value: greater('$1', '$3'). simple -> attr '<=' value: less('$1', '$3'). present -> attr '=*': present('$1'). substring -> attr '=' initial '*' any: substrings('$1', ['$3', '$5']). substring -> attr '=' '*' any final: substrings('$1', ['$4', '$5']). substring -> attr '=' initial '*' any final: substrings('$1', ['$3', '$5', '$6']). substring -> attr '=' '*' any: substrings('$1', ['$4']). any -> any value '*': 'any'('$1', '$2'). any -> '$empty': []. initial -> value: initial('$1'). final -> value: final('$1'). extensible -> xattr ':dn' ':' matchingrule ':=' value: extensible('$6', ['$1', '$4']). extensible -> xattr ':' matchingrule ':=' value: extensible('$5', ['$1', '$3']). extensible -> xattr ':dn' ':=' value: extensible('$4', ['$1']). extensible -> xattr ':=' value: extensible('$3', ['$1']). extensible -> ':dn' ':' matchingrule ':=' value: extensible('$5', ['$3']). extensible -> ':' matchingrule ':=' value: extensible('$4', ['$2']). xattr -> value: xattr('$1'). matchingrule -> value: matchingrule('$1'). attr -> str: value_of('$1'). value -> str: value_of('$1'). Erlang code. 'and'(Value) -> eldap:'and'(Value). 'or'(Value) -> eldap:'or'(Value). 'not'(Value) -> eldap:'not'(Value). equal(Desc, Value) -> eldap:equalityMatch(Desc, Value). approx(Desc, Value) -> eldap:approxMatch(Desc, Value). greater(Desc, Value) -> eldap:greaterOrEqual(Desc, Value). less(Desc, Value) -> eldap:lessOrEqual(Desc, Value). present(Value) -> eldap:present(Value). extensible(Value, Opts) -> eldap:extensibleMatch(Value, Opts). substrings(Desc, ValueList) -> eldap:substrings(Desc, flatten(ValueList)). initial(Value) -> {initial, Value}. final(Value) -> {final, Value}. 'any'(Token, Value) -> [Token, {any, Value}]. xattr(Value) -> {type, Value}. matchingrule(Value) -> {matchingRule, Value}. value_of(Token) -> element(3, Token). flatten(List) -> lists:flatten(List). ejabberd-2.1.11/src/eldap/eldap.hrl0000664000000000000000000000251012240230175013664 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -define(LDAP_PORT, 389). -define(LDAPS_PORT, 636). -record(eldap_search, {scope = wholeSubtree, base = [], filter, limit = 0, attributes = [], types_only = false, deref_aliases = neverDerefAliases, timeout = 0}). -record(eldap_search_result, {entries, referrals}). -record(eldap_entry, {object_name, attributes}). ejabberd-2.1.11/src/mod_privacy_odbc.erl0000664000000000000000000005564212240230175015030 0ustar %%%---------------------------------------------------------------------- %%% File : mod_privacy_odbc.erl %%% Author : Alexey Shchepin %%% Purpose : jabber:iq:privacy support %%% Created : 5 Oct 2006 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_privacy_odbc). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_iq/3, process_iq_set/4, process_iq_get/5, get_user_list/3, check_packet/6, remove_user/2, item_to_raw/1, raw_to_item/1, updated_list/3]). %% For mod_blocking_odbc -export([sql_add_privacy_list/2, sql_get_default_privacy_list/2, sql_get_default_privacy_list_t/1, sql_get_privacy_list_data/3, sql_get_privacy_list_data_by_id_t/1, sql_get_privacy_list_id_t/2, sql_set_default_privacy_list/2, sql_set_privacy_list/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_privacy.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), ejabberd_hooks:add(privacy_iq_get, Host, ?MODULE, process_iq_get, 50), ejabberd_hooks:add(privacy_iq_set, Host, ?MODULE, process_iq_set, 50), ejabberd_hooks:add(privacy_get_user_list, Host, ?MODULE, get_user_list, 50), ejabberd_hooks:add(privacy_check_packet, Host, ?MODULE, check_packet, 50), ejabberd_hooks:add(privacy_updated_list, Host, ?MODULE, updated_list, 50), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY, ?MODULE, process_iq, IQDisc). stop(Host) -> ejabberd_hooks:delete(privacy_iq_get, Host, ?MODULE, process_iq_get, 50), ejabberd_hooks:delete(privacy_iq_set, Host, ?MODULE, process_iq_set, 50), ejabberd_hooks:delete(privacy_get_user_list, Host, ?MODULE, get_user_list, 50), ejabberd_hooks:delete(privacy_check_packet, Host, ?MODULE, check_packet, 50), ejabberd_hooks:delete(privacy_updated_list, Host, ?MODULE, updated_list, 50), ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY). process_iq(_From, _To, IQ) -> SubEl = IQ#iq.sub_el, IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}. process_iq_get(_, From, _To, #iq{sub_el = SubEl}, #userlist{name = Active}) -> #jid{luser = LUser, lserver = LServer} = From, {xmlelement, _, _, Els} = SubEl, case xml:remove_cdata(Els) of [] -> process_lists_get(LUser, LServer, Active); [{xmlelement, Name, Attrs, _SubEls}] -> case Name of "list" -> ListName = xml:get_attr("name", Attrs), process_list_get(LUser, LServer, ListName); _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end. process_lists_get(LUser, LServer, Active) -> Default = case catch sql_get_default_privacy_list(LUser, LServer) of {selected, ["name"], []} -> none; {selected, ["name"], [{DefName}]} -> DefName; _ -> none end, case catch sql_get_privacy_list_names(LUser, LServer) of {selected, ["name"], []} -> {result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]}; {selected, ["name"], Names} -> LItems = lists:map( fun({N}) -> {xmlelement, "list", [{"name", N}], []} end, Names), DItems = case Default of none -> LItems; _ -> [{xmlelement, "default", [{"name", Default}], []} | LItems] end, ADItems = case Active of none -> DItems; _ -> [{xmlelement, "active", [{"name", Active}], []} | DItems] end, {result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], ADItems}]}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. process_list_get(LUser, LServer, {value, Name}) -> case catch sql_get_privacy_list_id(LUser, LServer, Name) of {selected, ["id"], []} -> {error, ?ERR_ITEM_NOT_FOUND}; {selected, ["id"], [{ID}]} -> case catch sql_get_privacy_list_data_by_id(ID, LServer) of {selected, ["t", "value", "action", "ord", "match_all", "match_iq", "match_message", "match_presence_in", "match_presence_out"], RItems} -> Items = lists:map(fun raw_to_item/1, RItems), LItems = lists:map(fun item_to_xml/1, Items), {result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], [{xmlelement, "list", [{"name", Name}], LItems}]}]}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end; process_list_get(_LUser, _LServer, false) -> {error, ?ERR_BAD_REQUEST}. item_to_xml(Item) -> Attrs1 = [{"action", action_to_list(Item#listitem.action)}, {"order", order_to_list(Item#listitem.order)}], Attrs2 = case Item#listitem.type of none -> Attrs1; Type -> [{"type", type_to_list(Item#listitem.type)}, {"value", value_to_list(Type, Item#listitem.value)} | Attrs1] end, SubEls = case Item#listitem.match_all of true -> []; false -> SE1 = case Item#listitem.match_iq of true -> [{xmlelement, "iq", [], []}]; false -> [] end, SE2 = case Item#listitem.match_message of true -> [{xmlelement, "message", [], []} | SE1]; false -> SE1 end, SE3 = case Item#listitem.match_presence_in of true -> [{xmlelement, "presence-in", [], []} | SE2]; false -> SE2 end, SE4 = case Item#listitem.match_presence_out of true -> [{xmlelement, "presence-out", [], []} | SE3]; false -> SE3 end, SE4 end, {xmlelement, "item", Attrs2, SubEls}. action_to_list(Action) -> case Action of allow -> "allow"; deny -> "deny" end. order_to_list(Order) -> integer_to_list(Order). type_to_list(Type) -> case Type of jid -> "jid"; group -> "group"; subscription -> "subscription" end. value_to_list(Type, Val) -> case Type of jid -> jlib:jid_to_string(Val); group -> Val; subscription -> case Val of both -> "both"; to -> "to"; from -> "from"; none -> "none" end end. list_to_action(S) -> case S of "allow" -> allow; "deny" -> deny end. process_iq_set(_, From, _To, #iq{sub_el = SubEl}) -> #jid{luser = LUser, lserver = LServer} = From, {xmlelement, _, _, Els} = SubEl, case xml:remove_cdata(Els) of [{xmlelement, Name, Attrs, SubEls}] -> ListName = xml:get_attr("name", Attrs), case Name of "list" -> process_list_set(LUser, LServer, ListName, xml:remove_cdata(SubEls)); "active" -> process_active_set(LUser, LServer, ListName); "default" -> process_default_set(LUser, LServer, ListName); _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end. process_default_set(LUser, LServer, {value, Name}) -> F = fun() -> case sql_get_privacy_list_names_t(LUser) of {selected, ["name"], []} -> {error, ?ERR_ITEM_NOT_FOUND}; {selected, ["name"], Names} -> case lists:member({Name}, Names) of true -> sql_set_default_privacy_list(LUser, Name), {result, []}; false -> {error, ?ERR_ITEM_NOT_FOUND} end end end, case odbc_queries:sql_transaction(LServer, F) of {atomic, {error, _} = Error} -> Error; {atomic, {result, _} = Res} -> Res; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end; process_default_set(LUser, LServer, false) -> case catch sql_unset_default_privacy_list(LUser, LServer) of {'EXIT', _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; {error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; _ -> {result, []} end. process_active_set(LUser, LServer, {value, Name}) -> case catch sql_get_privacy_list_id(LUser, LServer, Name) of {selected, ["id"], []} -> {error, ?ERR_ITEM_NOT_FOUND}; {selected, ["id"], [{ID}]} -> case catch sql_get_privacy_list_data_by_id(ID, LServer) of {selected, ["t", "value", "action", "ord", "match_all", "match_iq", "match_message", "match_presence_in", "match_presence_out"], RItems} -> Items = lists:map(fun raw_to_item/1, RItems), NeedDb = is_list_needdb(Items), {result, [], #userlist{name = Name, list = Items, needdb = NeedDb}}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end; process_active_set(_LUser, _LServer, false) -> {result, [], #userlist{}}. process_list_set(LUser, LServer, {value, Name}, Els) -> case parse_items(Els) of false -> {error, ?ERR_BAD_REQUEST}; remove -> F = fun() -> case sql_get_default_privacy_list_t(LUser) of {selected, ["name"], []} -> sql_remove_privacy_list(LUser, Name), {result, []}; {selected, ["name"], [{Default}]} -> %% TODO: check active if Name == Default -> {error, ?ERR_CONFLICT}; true -> sql_remove_privacy_list(LUser, Name), {result, []} end end end, case odbc_queries:sql_transaction(LServer, F) of {atomic, {error, _} = Error} -> Error; {atomic, {result, _} = Res} -> ejabberd_router:route( jlib:make_jid(LUser, LServer, ""), jlib:make_jid(LUser, LServer, ""), {xmlelement, "broadcast", [], [{privacy_list, #userlist{name = Name, list = []}, Name}]}), Res; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end; List -> RItems = lists:map(fun item_to_raw/1, List), F = fun() -> ID = case sql_get_privacy_list_id_t(LUser, Name) of {selected, ["id"], []} -> sql_add_privacy_list(LUser, Name), {selected, ["id"], [{I}]} = sql_get_privacy_list_id_t(LUser, Name), I; {selected, ["id"], [{I}]} -> I end, sql_set_privacy_list(ID, RItems), {result, []} end, case odbc_queries:sql_transaction(LServer, F) of {atomic, {error, _} = Error} -> Error; {atomic, {result, _} = Res} -> NeedDb = is_list_needdb(List), ejabberd_router:route( jlib:make_jid(LUser, LServer, ""), jlib:make_jid(LUser, LServer, ""), {xmlelement, "broadcast", [], [{privacy_list, #userlist{name = Name, list = List, needdb = NeedDb}, Name}]}), Res; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end end; process_list_set(_LUser, _LServer, false, _Els) -> {error, ?ERR_BAD_REQUEST}. parse_items([]) -> remove; parse_items(Els) -> parse_items(Els, []). parse_items([], Res) -> %% Sort the items by their 'order' attribute lists:keysort(#listitem.order, Res); parse_items([{xmlelement, "item", Attrs, SubEls} | Els], Res) -> Type = xml:get_attr("type", Attrs), Value = xml:get_attr("value", Attrs), SAction = xml:get_attr("action", Attrs), SOrder = xml:get_attr("order", Attrs), Action = case catch list_to_action(element(2, SAction)) of {'EXIT', _} -> false; Val -> Val end, Order = case catch list_to_integer(element(2, SOrder)) of {'EXIT', _} -> false; IntVal -> if IntVal >= 0 -> IntVal; true -> false end end, if (Action /= false) and (Order /= false) -> I1 = #listitem{action = Action, order = Order}, I2 = case {Type, Value} of {{value, T}, {value, V}} -> case T of "jid" -> case jlib:string_to_jid(V) of error -> false; JID -> I1#listitem{ type = jid, value = jlib:jid_tolower(JID)} end; "group" -> I1#listitem{type = group, value = V}; "subscription" -> case V of "none" -> I1#listitem{type = subscription, value = none}; "both" -> I1#listitem{type = subscription, value = both}; "from" -> I1#listitem{type = subscription, value = from}; "to" -> I1#listitem{type = subscription, value = to}; _ -> false end end; {{value, _}, false} -> false; _ -> I1 end, case I2 of false -> false; _ -> case parse_matches(I2, xml:remove_cdata(SubEls)) of false -> false; I3 -> parse_items(Els, [I3 | Res]) end end; true -> false end; parse_items(_, _Res) -> false. parse_matches(Item, []) -> Item#listitem{match_all = true}; parse_matches(Item, Els) -> parse_matches1(Item, Els). parse_matches1(Item, []) -> Item; parse_matches1(Item, [{xmlelement, "message", _, _} | Els]) -> parse_matches1(Item#listitem{match_message = true}, Els); parse_matches1(Item, [{xmlelement, "iq", _, _} | Els]) -> parse_matches1(Item#listitem{match_iq = true}, Els); parse_matches1(Item, [{xmlelement, "presence-in", _, _} | Els]) -> parse_matches1(Item#listitem{match_presence_in = true}, Els); parse_matches1(Item, [{xmlelement, "presence-out", _, _} | Els]) -> parse_matches1(Item#listitem{match_presence_out = true}, Els); parse_matches1(_Item, [{xmlelement, _, _, _} | _Els]) -> false. is_list_needdb(Items) -> lists:any( fun(X) -> case X#listitem.type of subscription -> true; group -> true; _ -> false end end, Items). get_user_list(_, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), case catch sql_get_default_privacy_list(LUser, LServer) of {selected, ["name"], []} -> #userlist{}; {selected, ["name"], [{Default}]} -> case catch sql_get_privacy_list_data(LUser, LServer, Default) of {selected, ["t", "value", "action", "ord", "match_all", "match_iq", "match_message", "match_presence_in", "match_presence_out"], RItems} -> Items = lists:map(fun raw_to_item/1, RItems), NeedDb = is_list_needdb(Items), #userlist{name = Default, list = Items, needdb = NeedDb}; _ -> #userlist{} end; _ -> #userlist{} end. %% From is the sender, To is the destination. %% If Dir = out, User@Server is the sender account (From). %% If Dir = in, User@Server is the destination account (To). check_packet(_, _User, _Server, _UserList, {#jid{luser = "", lserver = Server} = _From, #jid{lserver = Server} = _To, _}, in) -> allow; check_packet(_, _User, _Server, _UserList, {#jid{lserver = Server} = _From, #jid{luser = "", lserver = Server} = _To, _}, out) -> allow; check_packet(_, _User, _Server, _UserList, {#jid{luser = User, lserver = Server} = _From, #jid{luser = User, lserver = Server} = _To, _}, _Dir) -> allow; check_packet(_, User, Server, #userlist{list = List, needdb = NeedDb}, {From, To, {xmlelement, PName, Attrs, _}}, Dir) -> case List of [] -> allow; _ -> PType = case PName of "message" -> message; "iq" -> iq; "presence" -> case xml:get_attr_s("type", Attrs) of %% notification "" -> presence; "unavailable" -> presence; %% subscribe, subscribed, unsubscribe, %% unsubscribed, error, probe, or other _ -> other end end, PType2 = case {PType, Dir} of {message, in} -> message; {iq, in} -> iq; {presence, in} -> presence_in; {presence, out} -> presence_out; {_, _} -> other end, LJID = case Dir of in -> jlib:jid_tolower(From); out -> jlib:jid_tolower(To) end, {Subscription, Groups} = case NeedDb of true -> ejabberd_hooks:run_fold(roster_get_jid_info, jlib:nameprep(Server), {none, []}, [User, Server, LJID]); false -> {[], []} end, check_packet_aux(List, PType2, LJID, Subscription, Groups) end. check_packet_aux([], _PType, _JID, _Subscription, _Groups) -> allow; check_packet_aux([Item | List], PType, JID, Subscription, Groups) -> #listitem{type = Type, value = Value, action = Action} = Item, case is_ptype_match(Item, PType) of true -> case Type of none -> Action; _ -> case is_type_match(Type, Value, JID, Subscription, Groups) of true -> Action; false -> check_packet_aux(List, PType, JID, Subscription, Groups) end end; false -> check_packet_aux(List, PType, JID, Subscription, Groups) end. is_ptype_match(Item, PType) -> case Item#listitem.match_all of true -> true; false -> case PType of message -> Item#listitem.match_message; iq -> Item#listitem.match_iq; presence_in -> Item#listitem.match_presence_in; presence_out -> Item#listitem.match_presence_out; other -> false end end. is_type_match(Type, Value, JID, Subscription, Groups) -> case Type of jid -> case Value of {"", Server, ""} -> case JID of {_, Server, _} -> true; _ -> false end; {User, Server, ""} -> case JID of {User, Server, _} -> true; _ -> false end; _ -> Value == JID end; subscription -> Value == Subscription; group -> lists:member(Value, Groups) end. remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), sql_del_privacy_lists(LUser, LServer). updated_list(_, #userlist{name = OldName} = Old, #userlist{name = NewName} = New) -> if OldName == NewName -> New; true -> Old end. raw_to_item({SType, SValue, SAction, SOrder, SMatchAll, SMatchIQ, SMatchMessage, SMatchPresenceIn, SMatchPresenceOut}) -> {Type, Value} = case SType of "n" -> {none, none}; "j" -> case jlib:string_to_jid(SValue) of #jid{} = JID -> {jid, jlib:jid_tolower(JID)} end; "g" -> {group, SValue}; "s" -> case SValue of "none" -> {subscription, none}; "both" -> {subscription, both}; "from" -> {subscription, from}; "to" -> {subscription, to} end end, Action = case SAction of "a" -> allow; "d" -> deny end, Order = list_to_integer(SOrder), MatchAll = ejabberd_odbc:to_bool(SMatchAll), MatchIQ = ejabberd_odbc:to_bool(SMatchIQ), MatchMessage = ejabberd_odbc:to_bool(SMatchMessage), MatchPresenceIn = ejabberd_odbc:to_bool(SMatchPresenceIn), MatchPresenceOut = ejabberd_odbc:to_bool(SMatchPresenceOut), #listitem{type = Type, value = Value, action = Action, order = Order, match_all = MatchAll, match_iq = MatchIQ, match_message = MatchMessage, match_presence_in = MatchPresenceIn, match_presence_out = MatchPresenceOut }. item_to_raw(#listitem{type = Type, value = Value, action = Action, order = Order, match_all = MatchAll, match_iq = MatchIQ, match_message = MatchMessage, match_presence_in = MatchPresenceIn, match_presence_out = MatchPresenceOut }) -> {SType, SValue} = case Type of none -> {"n", ""}; jid -> {"j", ejabberd_odbc:escape(jlib:jid_to_string(Value))}; group -> {"g", ejabberd_odbc:escape(Value)}; subscription -> case Value of none -> {"s", "none"}; both -> {"s", "both"}; from -> {"s", "from"}; to -> {"s", "to"} end end, SAction = case Action of allow -> "a"; deny -> "d" end, SOrder = integer_to_list(Order), SMatchAll = if MatchAll -> "1"; true -> "0" end, SMatchIQ = if MatchIQ -> "1"; true -> "0" end, SMatchMessage = if MatchMessage -> "1"; true -> "0" end, SMatchPresenceIn = if MatchPresenceIn -> "1"; true -> "0" end, SMatchPresenceOut = if MatchPresenceOut -> "1"; true -> "0" end, [SType, SValue, SAction, SOrder, SMatchAll, SMatchIQ, SMatchMessage, SMatchPresenceIn, SMatchPresenceOut]. sql_get_default_privacy_list(LUser, LServer) -> Username = ejabberd_odbc:escape(LUser), odbc_queries:get_default_privacy_list(LServer, Username). sql_get_default_privacy_list_t(LUser) -> Username = ejabberd_odbc:escape(LUser), odbc_queries:get_default_privacy_list_t(Username). sql_get_privacy_list_names(LUser, LServer) -> Username = ejabberd_odbc:escape(LUser), odbc_queries:get_privacy_list_names(LServer, Username). sql_get_privacy_list_names_t(LUser) -> Username = ejabberd_odbc:escape(LUser), odbc_queries:get_privacy_list_names_t(Username). sql_get_privacy_list_id(LUser, LServer, Name) -> Username = ejabberd_odbc:escape(LUser), SName = ejabberd_odbc:escape(Name), odbc_queries:get_privacy_list_id(LServer, Username, SName). sql_get_privacy_list_id_t(LUser, Name) -> Username = ejabberd_odbc:escape(LUser), SName = ejabberd_odbc:escape(Name), odbc_queries:get_privacy_list_id_t(Username, SName). sql_get_privacy_list_data(LUser, LServer, Name) -> Username = ejabberd_odbc:escape(LUser), SName = ejabberd_odbc:escape(Name), odbc_queries:get_privacy_list_data(LServer, Username, SName). sql_get_privacy_list_data_by_id(ID, LServer) -> odbc_queries:get_privacy_list_data_by_id(LServer, ID). sql_get_privacy_list_data_by_id_t(ID) -> odbc_queries:get_privacy_list_data_by_id_t(ID). sql_set_default_privacy_list(LUser, Name) -> Username = ejabberd_odbc:escape(LUser), SName = ejabberd_odbc:escape(Name), odbc_queries:set_default_privacy_list(Username, SName). sql_unset_default_privacy_list(LUser, LServer) -> Username = ejabberd_odbc:escape(LUser), odbc_queries:unset_default_privacy_list(LServer, Username). sql_remove_privacy_list(LUser, Name) -> Username = ejabberd_odbc:escape(LUser), SName = ejabberd_odbc:escape(Name), odbc_queries:remove_privacy_list(Username, SName). sql_add_privacy_list(LUser, Name) -> Username = ejabberd_odbc:escape(LUser), SName = ejabberd_odbc:escape(Name), odbc_queries:add_privacy_list(Username, SName). sql_set_privacy_list(ID, RItems) -> odbc_queries:set_privacy_list(ID, RItems). sql_del_privacy_lists(LUser, LServer) -> Username = ejabberd_odbc:escape(LUser), Server = ejabberd_odbc:escape(LServer), odbc_queries:del_privacy_lists(LServer, Server, Username). ejabberd-2.1.11/src/p1_mnesia.erl0000664000000000000000000000324512240230175013371 0ustar %% ``The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved via the world wide web at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% The Initial Developer of the Original Code is ProcessOne. %% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %% All Rights Reserved.'' -module(p1_mnesia). -author('mickael.remond@process-one.net'). -export([count_records/2]). %% Return the number of records matching a given match expression. %% This function is intended to be used inside a Mnesia transaction. %% The count has been written to use the fewest possible memory by %% getting the record by small increment and by using continuation. -define(BATCHSIZE, 100). count_records(Tab, MatchExpression) -> %% the result contains list of [] for each match: We do not need %% actual values as we only count the data. case mnesia:select(Tab, [{MatchExpression, [], [[]]}], ?BATCHSIZE, read) of {Result,Cont} -> Count = length(Result), count_records_cont(Cont, Count); '$end_of_table' -> 0 end. count_records_cont(Cont, Count) -> case mnesia:select(Cont) of {Result,Cont} -> NewCount = Count + length(Result), count_records_cont(Cont, NewCount); '$end_of_table' -> Count end. ejabberd-2.1.11/src/treap.erl0000664000000000000000000001177512240230175012637 0ustar %%%---------------------------------------------------------------------- %%% File : treap.erl %%% Author : Alexey Shchepin %%% Purpose : Treaps implementation %%% Created : 22 Apr 2008 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(treap). -export([empty/0, insert/4, delete/2, delete_root/1, get_root/1, lookup/2, is_empty/1, fold/3, from_list/1, to_list/1]). empty() -> nil. insert(Key, Priority, Value, Tree) -> HashKey = {erlang:phash2(Key), Key}, insert1(Tree, HashKey, Priority, Value). insert1(nil, HashKey, Priority, Value) -> {HashKey, Priority, Value, nil, nil}; insert1({HashKey1, Priority1, Value1, Left, Right} = Tree, HashKey, Priority, Value) -> if HashKey < HashKey1 -> heapify({HashKey1, Priority1, Value1, insert1(Left, HashKey, Priority, Value), Right}); HashKey > HashKey1 -> heapify({HashKey1, Priority1, Value1, Left, insert1(Right, HashKey, Priority, Value)}); Priority == Priority1 -> {HashKey, Priority, Value, Left, Right}; true -> insert1(delete_root(Tree), HashKey, Priority, Value) end. heapify({_HashKey, _Priority, _Value, nil, nil} = Tree) -> Tree; heapify({HashKey, Priority, Value, nil = Left, {HashKeyR, PriorityR, ValueR, LeftR, RightR}} = Tree) -> if PriorityR > Priority -> {HashKeyR, PriorityR, ValueR, {HashKey, Priority, Value, Left, LeftR}, RightR}; true -> Tree end; heapify({HashKey, Priority, Value, {HashKeyL, PriorityL, ValueL, LeftL, RightL}, nil = Right} = Tree) -> if PriorityL > Priority -> {HashKeyL, PriorityL, ValueL, LeftL, {HashKey, Priority, Value, RightL, Right}}; true -> Tree end; heapify({HashKey, Priority, Value, {HashKeyL, PriorityL, ValueL, LeftL, RightL} = Left, {HashKeyR, PriorityR, ValueR, LeftR, RightR} = Right} = Tree) -> if PriorityR > Priority -> {HashKeyR, PriorityR, ValueR, {HashKey, Priority, Value, Left, LeftR}, RightR}; PriorityL > Priority -> {HashKeyL, PriorityL, ValueL, LeftL, {HashKey, Priority, Value, RightL, Right}}; true -> Tree end. delete(Key, Tree) -> HashKey = {erlang:phash2(Key), Key}, delete1(HashKey, Tree). delete1(_HashKey, nil) -> nil; delete1(HashKey, {HashKey1, Priority1, Value1, Left, Right} = Tree) -> if HashKey < HashKey1 -> {HashKey1, Priority1, Value1, delete1(HashKey, Left), Right}; HashKey > HashKey1 -> {HashKey1, Priority1, Value1, Left, delete1(HashKey, Right)}; true -> delete_root(Tree) end. delete_root({HashKey, Priority, Value, Left, Right}) -> case {Left, Right} of {nil, nil} -> nil; {_, nil} -> Left; {nil, _} -> Right; {{HashKeyL, PriorityL, ValueL, LeftL, RightL}, {HashKeyR, PriorityR, ValueR, LeftR, RightR}} -> if PriorityL > PriorityR -> {HashKeyL, PriorityL, ValueL, LeftL, delete_root({HashKey, Priority, Value, RightL, Right})}; true -> {HashKeyR, PriorityR, ValueR, delete_root({HashKey, Priority, Value, Left, LeftR}), RightR} end end. is_empty(nil) -> true; is_empty({_HashKey, _Priority, _Value, _Left, _Right}) -> false. get_root({{_Hash, Key}, Priority, Value, _Left, _Right}) -> {Key, Priority, Value}. lookup(Key, Tree) -> HashKey = {erlang:phash2(Key), Key}, lookup1(Tree, HashKey). lookup1(nil, _HashKey) -> error; lookup1({HashKey1, Priority1, Value1, Left, Right}, HashKey) -> if HashKey < HashKey1 -> lookup1(Left, HashKey); HashKey > HashKey1 -> lookup1(Right, HashKey); true -> {ok, Priority1, Value1} end. fold(_F, Acc, nil) -> Acc; fold(F, Acc, {{_Hash, Key}, Priority, Value, Left, Right}) -> Acc1 = F({Key, Priority, Value}, Acc), Acc2 = fold(F, Acc1, Left), fold(F, Acc2, Right). to_list(Tree) -> to_list(Tree, []). to_list(nil, Acc) -> Acc; to_list(Tree, Acc) -> Root = get_root(Tree), to_list(delete_root(Tree), [Root|Acc]). from_list(List) -> from_list(List, nil). from_list([{Key, Priority, Value}|Tail], Tree) -> from_list(Tail, insert(Key, Priority, Value, Tree)); from_list([], Tree) -> Tree. ejabberd-2.1.11/src/mod_caps.erl0000664000000000000000000004367412240230175013314 0ustar %%%---------------------------------------------------------------------- %%% File : mod_caps.erl %%% Author : Magnus Henoch %%% Purpose : Request and cache Entity Capabilities (XEP-0115) %%% Created : 7 Oct 2006 by Magnus Henoch %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%% 2009, improvements from ProcessOne to support correct PEP handling %%% through s2s, use less memory, and speedup global caps handling %%%---------------------------------------------------------------------- -module(mod_caps). -author('henoch@dtek.chalmers.se'). -behaviour(gen_server). -behaviour(gen_mod). -export([read_caps/1, caps_stream_features/2, disco_features/5, disco_identity/5, disco_info/5, get_features/1]). %% gen_mod callbacks -export([start/2, start_link/2, stop/1]). %% gen_server callbacks -export([init/1, handle_info/2, handle_call/3, handle_cast/2, terminate/2, code_change/3 ]). %% hook handlers -export([user_send_packet/3, user_receive_packet/4, c2s_presence_in/2, c2s_broadcast_recipients/5]). -include("ejabberd.hrl"). -include("jlib.hrl"). -define(PROCNAME, ejabberd_mod_caps). -define(BAD_HASH_LIFETIME, 600). %% in seconds -record(caps, {node, version, hash, exts}). -record(caps_features, {node_pair, features = []}). -record(state, {host}). %%==================================================================== %% API %%==================================================================== start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, transient, 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:call(Proc, stop), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). %% get_features returns a list of features implied by the given caps %% record (as extracted by read_caps) or 'unknown' if features are %% not completely collected at the moment. get_features(nothing) -> []; get_features(#caps{node = Node, version = Version, exts = Exts}) -> SubNodes = [Version | Exts], lists:foldl( fun(SubNode, Acc) -> BinaryNode = node_to_binary(Node, SubNode), case cache_tab:lookup(caps_features, BinaryNode, caps_read_fun(BinaryNode)) of {ok, Features} when is_list(Features) -> binary_to_features(Features) ++ Acc; _ -> Acc end end, [], SubNodes). %% read_caps takes a list of XML elements (the child elements of a %% stanza) and returns an opaque value representing the %% Entity Capabilities contained therein, or the atom nothing if no %% capabilities are advertised. read_caps(Els) -> read_caps(Els, nothing). read_caps([{xmlelement, "c", Attrs, _Els} | Tail], Result) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_CAPS -> Node = xml:get_attr_s("node", Attrs), Version = xml:get_attr_s("ver", Attrs), Hash = xml:get_attr_s("hash", Attrs), Exts = string:tokens(xml:get_attr_s("ext", Attrs), " "), read_caps(Tail, #caps{node = Node, hash = Hash, version = Version, exts = Exts}); _ -> read_caps(Tail, Result) end; read_caps([{xmlelement, "x", Attrs, _Els} | Tail], Result) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_MUC_USER -> nothing; _ -> read_caps(Tail, Result) end; read_caps([_ | Tail], Result) -> read_caps(Tail, Result); read_caps([], Result) -> Result. %%==================================================================== %% Hooks %%==================================================================== user_send_packet(#jid{luser = User, lserver = Server} = From, #jid{luser = User, lserver = Server, lresource = ""}, {xmlelement, "presence", Attrs, Els}) -> Type = xml:get_attr_s("type", Attrs), if Type == ""; Type == "available" -> case read_caps(Els) of nothing -> ok; #caps{version = Version, exts = Exts} = Caps -> feature_request(Server, From, Caps, [Version | Exts]) end; true -> ok end; user_send_packet(_From, _To, _Packet) -> ok. user_receive_packet(#jid{lserver = Server}, From, _To, {xmlelement, "presence", Attrs, Els}) -> Type = xml:get_attr_s("type", Attrs), if Type == ""; Type == "available" -> case read_caps(Els) of nothing -> ok; #caps{version = Version, exts = Exts} = Caps -> feature_request(Server, From, Caps, [Version | Exts]) end; true -> ok end; user_receive_packet(_JID, _From, _To, _Packet) -> ok. caps_stream_features(Acc, MyHost) -> case make_my_disco_hash(MyHost) of "" -> Acc; Hash -> [{xmlelement, "c", [{"xmlns", ?NS_CAPS}, {"hash", "sha-1"}, {"node", ?EJABBERD_URI}, {"ver", Hash}], []} | Acc] end. disco_features(_Acc, From, To, ?EJABBERD_URI ++ "#" ++ [_|_], Lang) -> ejabberd_hooks:run_fold(disco_local_features, To#jid.lserver, empty, [From, To, "", Lang]); disco_features(Acc, _From, _To, _Node, _Lang) -> Acc. disco_identity(_Acc, From, To, ?EJABBERD_URI ++ "#" ++ [_|_], Lang) -> ejabberd_hooks:run_fold(disco_local_identity, To#jid.lserver, [], [From, To, "", Lang]); disco_identity(Acc, _From, _To, _Node, _Lang) -> Acc. disco_info(_Acc, Host, Module, ?EJABBERD_URI ++ "#" ++ [_|_], Lang) -> ejabberd_hooks:run_fold(disco_info, Host, [], [Host, Module, "", Lang]); disco_info(Acc, _Host, _Module, _Node, _Lang) -> Acc. c2s_presence_in(C2SState, {From, To, {_, _, Attrs, Els}}) -> Type = xml:get_attr_s("type", Attrs), Subscription = ejabberd_c2s:get_subscription(From, C2SState), Insert = ((Type == "") or (Type == "available")) and ((Subscription == both) or (Subscription == to)), Delete = (Type == "unavailable") or (Type == "error") or (Type == "invisible"), if Insert or Delete -> LFrom = jlib:jid_tolower(From), Rs = case ejabberd_c2s:get_aux_field(caps_resources, C2SState) of {ok, Rs1} -> Rs1; error -> gb_trees:empty() end, Caps = read_caps(Els), {CapsUpdated, NewRs} = case Caps of nothing when Insert == true -> {false, Rs}; _ when Insert == true -> case gb_trees:lookup(LFrom, Rs) of {value, Caps} -> {false, Rs}; none -> {true, gb_trees:insert(LFrom, Caps, Rs)}; _ -> {true, gb_trees:update(LFrom, Caps, Rs)} end; _ -> {false, gb_trees:delete_any(LFrom, Rs)} end, if CapsUpdated -> ejabberd_hooks:run(caps_update, To#jid.lserver, [From, To, get_features(Caps)]); true -> ok end, ejabberd_c2s:set_aux_field(caps_resources, NewRs, C2SState); true -> C2SState end. c2s_broadcast_recipients(InAcc, C2SState, {pep_message, Feature}, _From, _Packet) -> case ejabberd_c2s:get_aux_field(caps_resources, C2SState) of {ok, Rs} -> gb_trees_fold( fun(USR, Caps, Acc) -> case lists:member(Feature, get_features(Caps)) of true -> [USR|Acc]; false -> Acc end end, InAcc, Rs); _ -> InAcc end; c2s_broadcast_recipients(Acc, _, _, _, _) -> Acc. %%==================================================================== %% gen_server callbacks %%==================================================================== init([Host, Opts]) -> case catch mnesia:table_info(caps_features, storage_type) of {'EXIT', _} -> ok; disc_only_copies -> ok; _ -> mnesia:delete_table(caps_features) end, mnesia:create_table(caps_features, [{disc_only_copies, [node()]}, {local_content, true}, {attributes, record_info(fields, caps_features)}]), mnesia:add_table_copy(caps_features, node(), disc_only_copies), MaxSize = gen_mod:get_opt(cache_size, Opts, 1000), LifeTime = gen_mod:get_opt(cache_life_time, Opts, timer:hours(24) div 1000), cache_tab:new(caps_features, [{max_size, MaxSize}, {life_time, LifeTime}]), ejabberd_hooks:add(c2s_presence_in, Host, ?MODULE, c2s_presence_in, 75), ejabberd_hooks:add(c2s_broadcast_recipients, Host, ?MODULE, c2s_broadcast_recipients, 75), ejabberd_hooks:add(user_send_packet, Host, ?MODULE, user_send_packet, 75), ejabberd_hooks:add(user_receive_packet, Host, ?MODULE, user_receive_packet, 75), ejabberd_hooks:add(c2s_stream_features, Host, ?MODULE, caps_stream_features, 75), ejabberd_hooks:add(s2s_stream_features, Host, ?MODULE, caps_stream_features, 75), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 75), ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, disco_identity, 75), ejabberd_hooks:add(disco_info, Host, ?MODULE, disco_info, 75), {ok, #state{host = Host}}. handle_call(stop, _From, State) -> {stop, normal, ok, State}; handle_call(_Req, _From, State) -> {reply, {error, badarg}, State}. handle_cast(_Msg, State) -> {noreply, State}. handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, State) -> Host = State#state.host, ejabberd_hooks:delete(c2s_presence_in, Host, ?MODULE, c2s_presence_in, 75), ejabberd_hooks:delete(c2s_broadcast_recipients, Host, ?MODULE, c2s_broadcast_recipients, 75), ejabberd_hooks:delete(user_send_packet, Host, ?MODULE, user_send_packet, 75), ejabberd_hooks:delete(user_receive_packet, Host, ?MODULE, user_receive_packet, 75), ejabberd_hooks:delete(c2s_stream_features, Host, ?MODULE, caps_stream_features, 75), ejabberd_hooks:delete(s2s_stream_features, Host, ?MODULE, caps_stream_features, 75), ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 75), ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 75), ejabberd_hooks:delete(disco_info, Host, ?MODULE, disco_info, 75), ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. %%==================================================================== %% Aux functions %%==================================================================== feature_request(Host, From, Caps, [SubNode | Tail] = SubNodes) -> Node = Caps#caps.node, BinaryNode = node_to_binary(Node, SubNode), case cache_tab:lookup(caps_features, BinaryNode, caps_read_fun(BinaryNode)) of {ok, Fs} when is_list(Fs) -> feature_request(Host, From, Caps, Tail); Other -> NeedRequest = case Other of {ok, TS} -> now_ts() >= TS + ?BAD_HASH_LIFETIME; _ -> true end, if NeedRequest -> IQ = #iq{type = get, xmlns = ?NS_DISCO_INFO, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_INFO}, {"node", Node ++ "#" ++ SubNode}], []}]}, %% We cache current timestamp in order to avoid %% caps requests flood cache_tab:insert(caps_features, BinaryNode, now_ts(), caps_write_fun(BinaryNode, now_ts())), F = fun(IQReply) -> feature_response( IQReply, Host, From, Caps, SubNodes) end, ejabberd_local:route_iq( jlib:make_jid("", Host, ""), From, IQ, F); true -> feature_request(Host, From, Caps, Tail) end end; feature_request(_Host, _From, _Caps, []) -> ok. feature_response(#iq{type = result, sub_el = [{xmlelement, _, _, Els}]}, Host, From, Caps, [SubNode | SubNodes]) -> BinaryNode = node_to_binary(Caps#caps.node, SubNode), case check_hash(Caps, Els) of true -> Features = lists:flatmap( fun({xmlelement, "feature", FAttrs, _}) -> [xml:get_attr_s("var", FAttrs)]; (_) -> [] end, Els), BinaryFeatures = features_to_binary(Features), cache_tab:insert( caps_features, BinaryNode, BinaryFeatures, caps_write_fun(BinaryNode, BinaryFeatures)); false -> ok end, feature_request(Host, From, Caps, SubNodes); feature_response(_IQResult, Host, From, Caps, [_SubNode | SubNodes]) -> %% We got type=error or invalid type=result stanza or timeout. feature_request(Host, From, Caps, SubNodes). node_to_binary(Node, SubNode) -> {list_to_binary(Node), list_to_binary(SubNode)}. features_to_binary(L) -> [list_to_binary(I) || I <- L]. binary_to_features(L) -> [binary_to_list(I) || I <- L]. caps_read_fun(Node) -> fun() -> case mnesia:dirty_read({caps_features, Node}) of [#caps_features{features = Features}] -> {ok, Features}; _ -> error end end. caps_write_fun(Node, Features) -> fun() -> mnesia:dirty_write( #caps_features{node_pair = Node, features = Features}) end. make_my_disco_hash(Host) -> JID = jlib:make_jid("", Host, ""), case {ejabberd_hooks:run_fold(disco_local_features, Host, empty, [JID, JID, "", ""]), ejabberd_hooks:run_fold(disco_local_identity, Host, [], [JID, JID, "", ""]), ejabberd_hooks:run_fold(disco_info, Host, [], [Host, undefined, "", ""])} of {{result, Features}, Identities, Info} -> Feats = lists:map( fun({{Feat, _Host}}) -> {xmlelement, "feature", [{"var", Feat}], []}; (Feat) -> {xmlelement, "feature", [{"var", Feat}], []} end, Features), make_disco_hash(Identities ++ Info ++ Feats, sha1); _Err -> "" end. -ifdef(HAVE_MD2). make_disco_hash(DiscoEls, Algo) -> Concat = [concat_identities(DiscoEls), concat_features(DiscoEls), concat_info(DiscoEls)], base64:encode_to_string( if Algo == md2 -> sha:md2(Concat); Algo == md5 -> crypto:md5(Concat); Algo == sha1 -> crypto:sha(Concat); Algo == sha224 -> sha:sha224(Concat); Algo == sha256 -> sha:sha256(Concat); Algo == sha384 -> sha:sha384(Concat); Algo == sha512 -> sha:sha512(Concat) end). check_hash(Caps, Els) -> case Caps#caps.hash of "md2" -> Caps#caps.version == make_disco_hash(Els, md2); "md5" -> Caps#caps.version == make_disco_hash(Els, md5); "sha-1" -> Caps#caps.version == make_disco_hash(Els, sha1); "sha-224" -> Caps#caps.version == make_disco_hash(Els, sha224); "sha-256" -> Caps#caps.version == make_disco_hash(Els, sha256); "sha-384" -> Caps#caps.version == make_disco_hash(Els, sha384); "sha-512" -> Caps#caps.version == make_disco_hash(Els, sha512); _ -> true end. -else. make_disco_hash(DiscoEls, Algo) -> Concat = [concat_identities(DiscoEls), concat_features(DiscoEls), concat_info(DiscoEls)], base64:encode_to_string( if Algo == md5 -> crypto:md5(Concat); Algo == sha1 -> crypto:sha(Concat); Algo == sha224 -> sha:sha224(Concat); Algo == sha256 -> sha:sha256(Concat); Algo == sha384 -> sha:sha384(Concat); Algo == sha512 -> sha:sha512(Concat) end). check_hash(Caps, Els) -> case Caps#caps.hash of "md5" -> Caps#caps.version == make_disco_hash(Els, md5); "sha-1" -> Caps#caps.version == make_disco_hash(Els, sha1); "sha-224" -> Caps#caps.version == make_disco_hash(Els, sha224); "sha-256" -> Caps#caps.version == make_disco_hash(Els, sha256); "sha-384" -> Caps#caps.version == make_disco_hash(Els, sha384); "sha-512" -> Caps#caps.version == make_disco_hash(Els, sha512); _ -> true end. -endif. concat_features(Els) -> lists:usort( lists:flatmap( fun({xmlelement, "feature", Attrs, _}) -> [[xml:get_attr_s("var", Attrs), $<]]; (_) -> [] end, Els)). concat_identities(Els) -> lists:sort( lists:flatmap( fun({xmlelement, "identity", Attrs, _}) -> [[xml:get_attr_s("category", Attrs), $/, xml:get_attr_s("type", Attrs), $/, xml:get_attr_s("xml:lang", Attrs), $/, xml:get_attr_s("name", Attrs), $<]]; (_) -> [] end, Els)). concat_info(Els) -> lists:sort( lists:flatmap( fun({xmlelement, "x", Attrs, Fields}) -> case {xml:get_attr_s("xmlns", Attrs), xml:get_attr_s("type", Attrs)} of {?NS_XDATA, "result"} -> [concat_xdata_fields(Fields)]; _ -> [] end; (_) -> [] end, Els)). concat_xdata_fields(Fields) -> [Form, Res] = lists:foldl( fun({xmlelement, "field", Attrs, Els} = El, [FormType, VarFields] = Acc) -> case xml:get_attr_s("var", Attrs) of "" -> Acc; "FORM_TYPE" -> [xml:get_subtag_cdata(El, "value"), VarFields]; Var -> [FormType, [[[Var, $<], lists:sort( lists:flatmap( fun({xmlelement, "value", _, VEls}) -> [[xml:get_cdata(VEls), $<]]; (_) -> [] end, Els))] | VarFields]] end; (_, Acc) -> Acc end, ["", []], Fields), [Form, $<, lists:sort(Res)]. gb_trees_fold(F, Acc, Tree) -> Iter = gb_trees:iterator(Tree), gb_trees_fold_iter(F, Acc, Iter). gb_trees_fold_iter(F, Acc, Iter) -> case gb_trees:next(Iter) of {Key, Val, NewIter} -> NewAcc = F(Key, Val, Acc), gb_trees_fold_iter(F, NewAcc, NewIter); _ -> Acc end. now_ts() -> {MegaSecs, Secs, _} = now(), MegaSecs*1000000 + Secs. ejabberd-2.1.11/src/ejabberd.cfg.example0000664000000000000000000003474712240230175014675 0ustar %%% %%% ejabberd configuration file %%% %%%' %%% The parameters used in this configuration file are explained in more detail %%% in the ejabberd Installation and Operation Guide. %%% Please consult the Guide in case of doubts, it is included with %%% your copy of ejabberd, and is also available online at %%% http://www.process-one.net/en/ejabberd/docs/ %%% This configuration file contains Erlang terms. %%% In case you want to understand the syntax, here are the concepts: %%% %%% - The character to comment a line is % %%% %%% - Each term ends in a dot, for example: %%% override_global. %%% %%% - A tuple has a fixed definition, its elements are %%% enclosed in {}, and separated with commas: %%% {loglevel, 4}. %%% %%% - A list can have as many elements as you want, %%% and is enclosed in [], for example: %%% [http_poll, web_admin, tls] %%% %%% - A keyword of ejabberd is a word in lowercase. %%% Strings are enclosed in "" and can contain spaces, dots, ... %%% {language, "en"}. %%% {ldap_rootdn, "dc=example,dc=com"}. %%% %%% - This term includes a tuple, a keyword, a list, and two strings: %%% {hosts, ["jabber.example.net", "im.example.com"]}. %%% %%%. ======================= %%%' OVERRIDE STORED OPTIONS %% %% Override the old values stored in the database. %% %% %% Override global options (shared by all ejabberd nodes in a cluster). %% %%override_global. %% %% Override local options (specific for this particular ejabberd node). %% %%override_local. %% %% Remove the Access Control Lists before new ones are added. %% %%override_acls. %%%. ========= %%%' DEBUGGING %% %% loglevel: Verbosity of log files generated by ejabberd. %% 0: No ejabberd log at all (not recommended) %% 1: Critical %% 2: Error %% 3: Warning %% 4: Info %% 5: Debug %% {loglevel, 4}. %% %% watchdog_admins: Only useful for developers: if an ejabberd process %% consumes a lot of memory, send live notifications to these XMPP %% accounts. %% %%{watchdog_admins, ["bob@example.com"]}. %%%. ================ %%%' SERVED HOSTNAMES %% %% hosts: Domains served by ejabberd. %% You can define one or several, for example: %% {hosts, ["example.net", "example.com", "example.org"]}. %% {hosts, ["localhost"]}. %% %% route_subdomains: Delegate subdomains to other XMPP servers. %% For example, if this ejabberd serves example.org and you want %% to allow communication with an XMPP server called im.example.org. %% %%{route_subdomains, s2s}. %%%. =============== %%%' LISTENING PORTS %% %% listen: The ports ejabberd will listen on, which service each is handled %% by and what options to start it with. %% {listen, [ {5222, ejabberd_c2s, [ %% %% If TLS is compiled in and you installed a SSL %% certificate, specify the full path to the %% file and uncomment this line: %% %%{certfile, "/path/to/ssl.pem"}, starttls, {access, c2s}, {shaper, c2s_shaper}, {max_stanza_size, 65536} ]}, %% %% To enable the old SSL connection method on port 5223: %% %%{5223, ejabberd_c2s, [ %% {access, c2s}, %% {shaper, c2s_shaper}, %% {certfile, "/path/to/ssl.pem"}, tls, %% {max_stanza_size, 65536} %% ]}, {5269, ejabberd_s2s_in, [ {shaper, s2s_shaper}, {max_stanza_size, 131072} ]}, %% %% ejabberd_service: Interact with external components (transports, ...) %% %%{8888, ejabberd_service, [ %% {access, all}, %% {shaper_rule, fast}, %% {ip, {127, 0, 0, 1}}, %% {hosts, ["icq.example.org", "sms.example.org"], %% [{password, "secret"}] %% } %% ]}, %% %% ejabberd_stun: Handles STUN Binding requests %% %%{{3478, udp}, ejabberd_stun, []}, {5280, ejabberd_http, [ %%{request_handlers, %% [ %% {["pub", "archive"], mod_http_fileserver} %% ]}, captcha, http_bind, http_poll, %%register, web_admin ]} ]}. %% %% s2s_use_starttls: Enable STARTTLS + Dialback for S2S connections. %% Allowed values are: false optional required required_trusted %% You must specify a certificate file. %% %%{s2s_use_starttls, optional}. %% %% s2s_certfile: Specify a certificate file. %% %%{s2s_certfile, "/path/to/ssl.pem"}. %% %% domain_certfile: Specify a different certificate for each served hostname. %% %%{domain_certfile, "example.org", "/path/to/example_org.pem"}. %%{domain_certfile, "example.com", "/path/to/example_com.pem"}. %% %% S2S whitelist or blacklist %% %% Default s2s policy for undefined hosts. %% %%{s2s_default_policy, allow}. %% %% Allow or deny communication with specific servers. %% %%{{s2s_host, "goodhost.org"}, allow}. %%{{s2s_host, "badhost.org"}, deny}. %% %% Outgoing S2S options %% %% Preferred address families (which to try first) and connect timeout %% in milliseconds. %% %%{outgoing_s2s_options, [ipv4, ipv6], 10000}. %%%. ============== %%%' AUTHENTICATION %% %% auth_method: Method used to authenticate the users. %% The default method is the internal. %% If you want to use a different method, %% comment this line and enable the correct ones. %% {auth_method, internal}. %% %% Store the plain passwords or hashed for SCRAM: %%{auth_password_format, plain}. %%{auth_password_format, scram}. %% %% Define the FQDN if ejabberd doesn't detect it: %%{fqdn, "server3.example.com"}. %% %% Authentication using external script %% Make sure the script is executable by ejabberd. %% %%{auth_method, external}. %%{extauth_program, "/path/to/authentication/script"}. %% %% Authentication using ODBC %% Remember to setup a database in the next section. %% %%{auth_method, odbc}. %% %% Authentication using PAM %% %%{auth_method, pam}. %%{pam_service, "pamservicename"}. %% %% Authentication using LDAP %% %%{auth_method, ldap}. %% %% List of LDAP servers: %%{ldap_servers, ["localhost"]}. %% %% Encryption of connection to LDAP servers: %%{ldap_encrypt, none}. %%{ldap_encrypt, tls}. %% %% Port to connect to on LDAP servers: %%{ldap_port, 389}. %%{ldap_port, 636}. %% %% LDAP manager: %%{ldap_rootdn, "dc=example,dc=com"}. %% %% Password of LDAP manager: %%{ldap_password, "******"}. %% %% Search base of LDAP directory: %%{ldap_base, "dc=example,dc=com"}. %% %% LDAP attribute that holds user ID: %%{ldap_uids, [{"mail", "%u@mail.example.org"}]}. %% %% LDAP filter: %%{ldap_filter, "(objectClass=shadowAccount)"}. %% %% Anonymous login support: %% auth_method: anonymous %% anonymous_protocol: sasl_anon | login_anon | both %% allow_multiple_connections: true | false %% %%{host_config, "public.example.org", [{auth_method, anonymous}, %% {allow_multiple_connections, false}, %% {anonymous_protocol, sasl_anon}]}. %% %% To use both anonymous and internal authentication: %% %%{host_config, "public.example.org", [{auth_method, [internal, anonymous]}]}. %%%. ============== %%%' DATABASE SETUP %% ejabberd by default uses the internal Mnesia database, %% so you do not necessarily need this section. %% This section provides configuration examples in case %% you want to use other database backends. %% Please consult the ejabberd Guide for details on database creation. %% %% MySQL server: %% %%{odbc_server, {mysql, "server", "database", "username", "password"}}. %% %% If you want to specify the port: %%{odbc_server, {mysql, "server", 1234, "database", "username", "password"}}. %% %% PostgreSQL server: %% %%{odbc_server, {pgsql, "server", "database", "username", "password"}}. %% %% If you want to specify the port: %%{odbc_server, {pgsql, "server", 1234, "database", "username", "password"}}. %% %% If you use PostgreSQL, have a large database, and need a %% faster but inexact replacement for "select count(*) from users" %% %%{pgsql_users_number_estimate, true}. %% %% ODBC compatible or MSSQL server: %% %%{odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}. %% %% Number of connections to open to the database for each virtual host %% %%{odbc_pool_size, 10}. %% %% Interval to make a dummy SQL request to keep the connections to the %% database alive. Specify in seconds: for example 28800 means 8 hours %% %%{odbc_keepalive_interval, undefined}. %%%. =============== %%%' TRAFFIC SHAPERS %% %% The "normal" shaper limits traffic speed to 1000 B/s %% {shaper, normal, {maxrate, 1000}}. %% %% The "fast" shaper limits traffic speed to 50000 B/s %% {shaper, fast, {maxrate, 50000}}. %% %% This option specifies the maximum number of elements in the queue %% of the FSM. Refer to the documentation for details. %% {max_fsm_queue, 1000}. %%%. ==================== %%%' ACCESS CONTROL LISTS %% %% The 'admin' ACL grants administrative privileges to XMPP accounts. %% You can put here as many accounts as you want. %% %%{acl, admin, {user, "aleksey", "localhost"}}. %%{acl, admin, {user, "ermine", "example.org"}}. %% %% Blocked users %% %%{acl, blocked, {user, "baduser", "example.org"}}. %%{acl, blocked, {user, "test"}}. %% %% Local users: don't modify this line. %% {acl, local, {user_regexp, ""}}. %% %% More examples of ACLs %% %%{acl, jabberorg, {server, "jabber.org"}}. %%{acl, aleksey, {user, "aleksey", "jabber.ru"}}. %%{acl, test, {user_regexp, "^test"}}. %%{acl, test, {user_glob, "test*"}}. %% %% Define specific ACLs in a virtual host. %% %%{host_config, "localhost", %% [ %% {acl, admin, {user, "bob-local", "localhost"}} %% ] %%}. %%%. ============ %%%' ACCESS RULES %% Maximum number of simultaneous sessions allowed for a single user: {access, max_user_sessions, [{10, all}]}. %% Maximum number of offline messages that users can have: {access, max_user_offline_messages, [{5000, admin}, {100, all}]}. %% This rule allows access only for local users: {access, local, [{allow, local}]}. %% Only non-blocked users can use c2s connections: {access, c2s, [{deny, blocked}, {allow, all}]}. %% For C2S connections, all users except admins use the "normal" shaper {access, c2s_shaper, [{none, admin}, {normal, all}]}. %% All S2S connections use the "fast" shaper {access, s2s_shaper, [{fast, all}]}. %% Only admins can send announcement messages: {access, announce, [{allow, admin}]}. %% Only admins can use the configuration interface: {access, configure, [{allow, admin}]}. %% Admins of this server are also admins of the MUC service: {access, muc_admin, [{allow, admin}]}. %% Only accounts of the local ejabberd server can create rooms: {access, muc_create, [{allow, local}]}. %% All users are allowed to use the MUC service: {access, muc, [{allow, all}]}. %% Only accounts on the local ejabberd server can create Pubsub nodes: {access, pubsub_createnode, [{allow, local}]}. %% In-band registration allows registration of any possible username. %% To disable in-band registration, replace 'allow' with 'deny'. {access, register, [{allow, all}]}. %% By default the frequency of account registrations from the same IP %% is limited to 1 account every 10 minutes. To disable, specify: infinity %%{registration_timeout, 600}. %% %% Define specific Access Rules in a virtual host. %% %%{host_config, "localhost", %% [ %% {access, c2s, [{allow, admin}, {deny, all}]}, %% {access, register, [{deny, all}]} %% ] %%}. %%%. ================ %%%' DEFAULT LANGUAGE %% %% language: Default language used for server messages. %% {language, "en"}. %% %% Set a different default language in a virtual host. %% %%{host_config, "localhost", %% [{language, "ru"}] %%}. %%%. ======= %%%' CAPTCHA %% %% Full path to a script that generates the image. %% %%{captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}. %% %% Host for the URL and port where ejabberd listens for CAPTCHA requests. %% %%{captcha_host, "example.org:5280"}. %% %% Limit CAPTCHA calls per minute for JID/IP to avoid DoS. %% %%{captcha_limit, 5}. %%%. ======= %%%' MODULES %% %% Modules enabled in all ejabberd virtual hosts. %% {modules, [ {mod_adhoc, []}, {mod_announce, [{access, announce}]}, % recommends mod_adhoc {mod_blocking,[]}, % requires mod_privacy {mod_caps, []}, {mod_configure,[]}, % requires mod_adhoc {mod_disco, []}, %%{mod_echo, [{host, "echo.localhost"}]}, {mod_irc, []}, {mod_http_bind, []}, %%{mod_http_fileserver, [ %% {docroot, "/var/www"}, %% {accesslog, "/var/log/ejabberd/access.log"} %% ]}, {mod_last, []}, {mod_muc, [ %%{host, "conference.@HOST@"}, {access, muc}, {access_create, muc_create}, {access_persistent, muc_create}, {access_admin, muc_admin} ]}, %%{mod_muc_log,[]}, {mod_offline, [{access_max_user_messages, max_user_offline_messages}]}, {mod_ping, []}, %%{mod_pres_counter,[{count, 5}, {interval, 60}]}, {mod_privacy, []}, {mod_private, []}, %%{mod_proxy65,[]}, {mod_pubsub, [ {access_createnode, pubsub_createnode}, {ignore_pep_from_offline, true}, % reduces resource comsumption, but XEP incompliant %%{ignore_pep_from_offline, false}, % XEP compliant, but increases resource comsumption {last_item_cache, false}, {plugins, ["flat", "hometree", "pep"]} % pep requires mod_caps ]}, {mod_register, [ %% %% Protect In-Band account registrations with CAPTCHA. %% %%{captcha_protected, true}, %% %% Set the minimum informational entropy for passwords. %% %%{password_strength, 32}, %% %% After successful registration, the user receives %% a message with this subject and body. %% {welcome_message, {"Welcome!", "Hi.\nWelcome to this XMPP server."}}, %% %% When a user registers, send a notification to %% these XMPP accounts. %% %%{registration_watchers, ["admin1@example.org"]}, %% %% Only clients in the server machine can register accounts %% {ip_access, [{allow, "127.0.0.0/8"}, {deny, "0.0.0.0/0"}]}, %% %% Local c2s or remote s2s users cannot register accounts %% %%{access_from, deny}, {access, register} ]}, %%{mod_register_web, [ %% %% When a user registers, send a notification to %% these XMPP accounts. %% %%{registration_watchers, ["admin1@example.org"]} %% ]}, {mod_roster, []}, %%{mod_service_log,[]}, {mod_shared_roster,[]}, {mod_stats, []}, {mod_time, []}, {mod_vcard, []}, {mod_version, []} ]}. %% %% Enable modules with custom options in a specific virtual host %% %%{host_config, "localhost", %% [{{add, modules}, %% [ %% {mod_echo, [{host, "mirror.localhost"}]} %% ] %% } %% ]}. %%%. %%%' %%% $Id$ %%% Local Variables: %%% mode: erlang %%% End: %%% vim: set filetype=erlang tabstop=8 foldmarker=%%%',%%%. foldmethod=marker: ejabberd-2.1.11/src/win32/0000775000000000000000000000000012240452476011761 5ustar ejabberd-2.1.11/src/win32/CheckReqs.ini0000664000000000000000000000071512240230175014323 0ustar [Settings] NumFields=2 [Field 1] Type=label Left=0 Right=-1 Top=10 Bottom=70 Text="Erlang OTP R10B-7 (version 5.4.9) or newer is required to install Ejabberd.\r\n\r\nIt is not found on your computer.\r\n\r\nPlease install Erlang OTP R10B-7 or newer before installing Ejabberd.\r\n\r\nIts installer can be downloaded from" [Field 2] Type=link Left=0 Right=-1 Top=74 Bottom=88 State=http://www.erlang.org/download.html Text=http://www.erlang.org/download.html ejabberd-2.1.11/src/win32/CheckUser.ini0000664000000000000000000000044312240230175014325 0ustar [Settings] NumFields=1 [Field 1] Type=label Left=0 Right=-1 Top=10 Bottom=-10 Text="Administrator privileges are recommended for Ejabberd install.\r\n\r\nOtherwise installing Ejabberd as a service will be impossible.\r\n\r\nIf you want to continue installing Ejabberd anyway, click Next." ejabberd-2.1.11/src/win32/CheckUserH.ini0000664000000000000000000000053612240230175014440 0ustar [Settings] NumFields=2 [Field 1] Type=label Left=0 Right=-1 Top=10 Bottom=50 Text="Administrator privileges are recommended for Ejabberd install.\r\n\r\nOtherwise installing Ejabberd as a service will be impossible." [Field 2] Type=checkbox Left=0 Right=-1 Top=50 Bottom=62 Text="I want to continue installing Ejabberd anyway" State=0 Flags=NOTIFY ejabberd-2.1.11/src/win32/ejabberd.cfg0000664000000000000000000001161212240230175014167 0ustar % $Id$ %override_acls. % Users that have admin access. Add line like one of the following after you % will be successfully registered on server to get admin access: %{acl, admin, {user, "aleksey"}}. %{acl, admin, {user, "ermine"}}. % Blocked users: %{acl, blocked, {user, "test"}}. % Local users: {acl, local, {user_regexp, ""}}. % Another examples of ACLs: %{acl, jabberorg, {server, "jabber.org"}}. %{acl, aleksey, {user, "aleksey", "jabber.ru"}}. %{acl, test, {user_regexp, "^test"}}. %{acl, test, {user_glob, "test*"}}. % Only admins can use configuration interface: {access, configure, [{allow, admin}]}. % Every username can be registered via in-band registration: {access, register, [{allow, all}]}. % After successful registration user will get message with following subject % and body: {welcome_message, {"Welcome!", "Welcome to Jabber Service. " "For information about Jabber visit http://jabber.org"}}. % Replace them with 'none' if you don't want to send such message: %{welcome_message, none}. % List of people who will get notifications about registered users %{registration_watchers, ["admin1@localhost", % "admin2@localhost"]}. % Only admins can send announcement messages: {access, announce, [{allow, admin}]}. % Only non-blocked users can use c2s connections: {access, c2s, [{deny, blocked}, {allow, all}]}. % Set shaper with name "normal" to limit traffic speed to 1000B/s {shaper, normal, {maxrate, 1000}}. % Set shaper with name "fast" to limit traffic speed to 50000B/s {shaper, fast, {maxrate, 50000}}. % For all users except admins used "normal" shaper {access, c2s_shaper, [{none, admin}, {normal, all}]}. % For all S2S connections used "fast" shaper {access, s2s_shaper, [{fast, all}]}. % Admins of this server are also admins of MUC service: {access, muc_admin, [{allow, admin}]}. % All users are allowed to use MUC service: {access, muc, [{allow, all}]}. % This rule allows access only for local users: {access, local, [{allow, local}]}. % Authentification method. If you want to use internal user base, then use % this line: {auth_method, internal}. % For LDAP authentification use these lines instead of above one: %{auth_method, ldap}. %{ldap_servers, ["localhost"]}. % List of LDAP servers %{ldap_uidattr, "uid"}. % LDAP attribute that holds user ID %{ldap_base, "dc=example,dc=com"}. % Base of LDAP directory %{ldap_rootdn, "dc=example,dc=com"}. % LDAP manager %{ldap_password, "******"}. % Password to LDAP manager % For authentification via external script use the following: %{auth_method, external}. %{extauth_program, "/path/to/authentification/script"}. % For authentification via ODBC use the following: %{auth_method, odbc}. %{odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}. % Host name(s): {hosts, ["localhost"]}. % Default language: {language, "en"}. % Listened ports: {listen, [ {5222, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper}]}, % To create selfsigned certificate run the following command from the % command prompt: % % openssl req -new -x509 -days 365 -nodes -out ejabberd.pem -keyout ejabberd.pem % % and answer the questions. % {5222, ejabberd_c2s, [{access, c2s}, % starttls, {certfile, "./ejabberd.pem"}, % {shaper, c2s_shaper}]}, % When using SSL/TLS ssl option is not recommended (it requires patching % erlang ssl application). Use tls option instead (as shown below). % {5223, ejabberd_c2s, [{access, c2s}, % tls, {certfile, "./ejabberd.pem"}, % {shaper, c2s_shaper}]}, {5269, ejabberd_s2s_in, [{shaper, s2s_shaper}]}, % {5555, ejabberd_service, [{access, all}, % {host, "icq.localhost", [{password, "secret"}]}]}, {5280, ejabberd_http, [http_poll, web_admin]} ]}. % If SRV lookup fails, then port 5269 is used to communicate with remote server {outgoing_s2s_port, 5269}. % Used modules: {modules, [ {mod_register, [{access, register}]}, {mod_roster, []}, {mod_shared_roster, []}, {mod_privacy, []}, {mod_configure, []}, {mod_disco, []}, {mod_stats, []}, {mod_vcard, []}, {mod_offline, []}, {mod_announce, [{access, announce}]}, {mod_private, []}, {mod_irc, []}, % Default options for mod_muc: % host: "conference." ++ ?MYNAME % access: all % access_create: all % access_admin: none (only room creator has owner privileges) {mod_muc, [{access, muc}, {access_create, muc}, {access_admin, muc_admin}]}, {mod_pubsub, []}, {mod_time, []}, {mod_last, []}, {mod_version, []} ]}. % Local Variables: % mode: erlang % End: ejabberd-2.1.11/src/win32/CheckService.ini0000664000000000000000000000046612240230175015014 0ustar [Settings] NumFields=2 [Field 1] Type=label Left=0 Right=-1 Top=10 Bottom=50 Text="You are installing Ejabberd as Administrator.\r\n\r\nEjabberd will be installed as a Windows service." [Field 2] Type=checkbox Left=0 Right=-1 Top=50 Bottom=62 Text="Configure ejabberd service to start automatically" State=1 ejabberd-2.1.11/src/win32/inetrc0000664000000000000000000000002312240230175013151 0ustar {registry, win32}. ejabberd-2.1.11/src/win32/CheckReqs1H.ini0000664000000000000000000000114012240230175014505 0ustar [Settings] NumFields=3 [Field 1] Type=label Left=0 Right=-1 Top=10 Bottom=70 Text="OpenSLL 0.9.7i or newer is not found on your computer.\r\n\r\nTo use SSL and TLS encryption you need an SSL certificate. You can create a selfsigned certificate with OpenSSL.\r\n\r\nOpenSLL installer can be downloaded from" [Field 2] Type=link Left=0 Right=-1 Top=74 Bottom=88 State=http://www.slproweb.com/products/Win32OpenSSL.html Text=http://www.slproweb.com/products/Win32OpenSSL.html [Field 3] Type=checkbox Left=0 Right=-1 Top=93 Bottom=105 Text="I want to continue installing Ejabberd anyway" State=0 Flags=NOTIFY ejabberd-2.1.11/src/win32/ejabberd.ico0000664000000000000000000000427612240230175014212 0ustar  ( @ejabberd-2.1.11/src/win32/ejabberd_header.bmp0000664000000000000000000010271612240230175015524 0ustar BM΅6(9   |U}U}V~V~WWXYZ[\\^^_`abbdeffhijklmmÐoÒqÒqērĔtŕuŖvƗxǘyǙzǚ{Ț|ț~ɝʞʟˠˡ̢ͣͥ͢ΦϧϨЩЪѫҭҭӮӯ԰Աճִֵ׶طظٹٺټڽ۾ۿ°ðIJƴƵǶɸɹ˺̼ͽο}U|U~V}W~XXXYZ[\]]^_`aabdceegghjjlmnp’pÒrĔsĔtŕuŖwƗxƘyƙzǚ{ț}Ȝ~ɝɞɟʠˡ̢̣ͤͤϧШϩѪѫҬҭӯӯԱձճմִֶضظٹٺڼڼ۽ۿ¯ñIJŴƵǶɸʹ˻̼ͽξ}T}V}U~VWXYYZZ[]^^__aaabddffgijkkmnpq‘rrÓtĕvÕvĖxėxĘyƙ{ƚ}Ǜ~Ȝ~ȜǞɟʠˡˢͤͥͦϨϩЪѫҬҭӮӯӰձճִ׵׶׷ظعٺڼڽ۾ܿ°ñIJųƵǷɷɹ˺̼ͽͿ|T|U}V}V~WXXYZ[\\]^^__abccdddffhijkllnoprrst•v•wÖy×yØ{Ù}ś}ěƝǝȟȟʢˤͤϧϨЪѫѬҭӮӯ԰ձղֳֵ׶׷ظعٻڻڽ۾ۿðIJƳƵǷȸɹ˻̼;ο|T}U}U~V~XXXYZ[[\]]^_`_aacbddcdfghijklmnopqrtvvwyz{™}Ú~ÛĜŝǠɢʤ̦ͧϩѬҬҭүӰ԰ղղִֵֶطظٹٺڻڼ۾ۿ¯ðIJŴƵǷɷɹ˺˼ͽ;}T}U}U~VWWYZZ[\]\]^]^```aaaaabacddefgijklnnopqstuvwzz|ÛşɢʤͧΨЪҬҭӮӰԱԲճմ׵׶طظعٺڻۼ۽ۿ¯ñIJŴƵǶɸʹ˺̼̽ξ|T}U~U~W~XXXYZ[\[\]]^^^_^_^^~]}]}^|]}_}^~`~a~acdefghhjlmmoorstuy{~ƞɢʥͨЫҬҮӮԯԱձղճִ׶طظٺٺٻڼ۽ܿðIJŴƵǷȸɹʻ˼̽ο|U}U}V~VWWYYZ[\\\\]]\]]~\|\{ZyZwXuWtXtXuXtXuYtZv[w[w]x]y_y_{`{b|c}d~e~efgiklnqtz~Ơȣ̧ϩЫҭүӰӱղճִ׵׶׷ظعٺڼڽ۾ܿ¯ñIJŴǵǶȷɹ˻̼ͽο|U}V~V~W~WXXYZ[Z[]\\\~\~[|[zYxXuWsVpTnSmRlQlQkRlRlSmTnUnUnVoWpXqYqYq[s\t\t]u_u_wayc{d}gjntyÞƢ˦ΨѫѬүӯ԰ձճֳֵ׶طظعٺڻۼ۽ܾ¯ñIJųǵȶȷɹ˺˼̾ξ}T}V}V~W~WXYZZ[Z[[]\[~[{YyYwVtUpTmQjOgLeKdJcKbJcKbLdLdNeNeOfPfQgRhSiSiTjUkUkWlWmYoZq]s^xd}hnt|ĠʥͨѫҭӯӯԱԱղմֵ׶׷ظٹںٻۼ۾ܿ°ðIJųƵȶȸɹʺ̼ͽο}T}V~V~WWXYYZ[[\[[[~[|YyXxWtUpSlPhLcI`G]F|[DzZCyYDyZExYEy[Fz[Gz\Gy[Gz\Hz]I{^J{^J|_L{_L|`M|aM}aO}bO~cPcQgTjWo\ua~ipxžȤ̧ЪѬү԰ӱղճִֵ׵طظعٺڻۼ۾ۿܿ¯ñųųƵǶȷɹ˻˼̽ο}U}U}V~V~WXXYZ[[[\[[}Z|YyXuUrSnPhNdJ_G}[DyYBtUAsU@qT@rT@qT@qTArUBrUCrUCsWDsWDsXFtXFtYGsYGtZHt[Iu[Jv\Jv]Kx^M{aPeSjWp]zfnv~ȣ̦ϪѬҮӰԱղճճ׵ֶ׷ظعٻڻڽ۾ܿ°ðijŴƵȶɸɹʻ˼̽ο|T|U~V~W~WXXYZ[ZZ\[[|YzYvVsUpRkOfJaG}[DvVArT?nP=lOjP>jP>kQ?kQ@kRAkRAkSBlSBmTCmUDmUDmVEnVFpXGt[Kw^MeTlYuakt}Ǣ̧ϪѬӯӯӱԲճմִ׵طظعٺڻڼ۾ܿ°ðIJųƴǶȸʹʻ̼̾ο}U}U}V~V~WXYYZ[[Z[[~Y|YyXvVsTnQjNeJ^F{YCsS?oQ=jM:iM:gL:fL:fL:fL;fM;gMhO>hO?iQ@iP@iRAiQAiRBjSCkTDmUEpYHs\K|cRiXt`~it}Ǣ̦ϪѬӮӯ԰ղճִ״׶طظٹٺڼ۽۽۾¯ñIJųƵȶɷʹʻ̼;ο}U}U~V~V~WXXYZ[[[[\~ZmVFpYJx`OfUq_}ir|Ǣ˦ϩѬӮӯԱղճմֵ׶طظٹٺټڼ۾ܿ¯ñIJŴƵǶȸɹ˻˼ͽο}U}V~V~W~WXYYZZZ[\~[~ZlUFpXIx_OfUq_|gr{Ǣ˦ϪҬӮӰ԰Աճմ׵׵׷ظٹٺڻڼ۾ܾݿ¯ðIJųƵǶȸɹ˺˼;ο|T}U~V~V~WXXZZ[[Z[[}ZjTEoWHw_NfTq^|hq|Ǣ˦ЪѬӯӰӰղֲճ׵׶طظٹٻڻڽ۾ܾ¯ñIJųƵǷɸʹ˻̼ͽͿ|T}U~V~V~WXYZZ[[Z[~[}ZjTEoWIw_NfTq^|hq|Ǣ˧ЪѬӮԯ԰ձղճ׵׶׷ظٹٺٻڼ۽ۿ¯ñIJƴƵȷȷɹ˺̼;ο|U|V~V~V~WWYYZZ[Z[~[}ZkTEoXIw_NfTq^|gq{Ǣ˦ϪѬүӯ԰Աղִֵ׶׷ظغٺڼڼ۾ܿ¯ðIJųƵǷɸɹʻ̼;;}T}U}V~VWXXZZZZZ[~[~ZkTEoXHw^NfTq^|hr|Ǣ˦ϪѬҮ԰ԱԲճִֵ׶طظعٺڼۼ۾ۿ¯ñIJŴƵȶȸʹ˻˼ͽο}U}V}V~W~WWYYZ[Z[[[~ZjTEnWGv^NdTq^|hr{Ǣ˧ΩѬӯӯ԰ձճճ׵׶׷ظعٺڼڽ۾ۿ¯ðIJƳƵǶɸʹ˺̼ͽο|U}U}U~VXXYYZ[[[[[~ZjTEoXHw^NfTp^{hr|Ǣ˦ЪѬҮԯԱԱղմֵ׶طظٹٻڻ۽۽۾¯ñIJŴǵȷȸʹ˺˼;ο|U}U}V~W~WXXYZ[ZZ[[~ZjTEnXHw^NfTq^|hr{Ǣ˦ϪѬүԯԱԲճֳֵ׵׷ظٹٺڼڽ۾۾¯ðIJųƵȶȸʹ˺˼ͽο|T}U}U~WWXXYZ[ZZ[~[~ZkTEoXHw_NfTq^{hr{Ǣ˦ϪѬӮӯ԰Բճִֵ׶طظٹٻٻۼ۾ܾݿñIJųǵǷȸʺ˻̼ͽο|U}V~V~V~W~XYYZ[Z[\\~ZjTEnXHw^NfTq^|hq{ǣ˦ЪѬӯӯԱԱճճֵ׵׷ظٹٻڻۼ۾۾ܿ¯ðIJųƵǶɷʹ˻̼ͽξ}T}U}V~W~WXXYZ[[[[[YkTEoXHw_NfTq^|hr{Ǣ˦ЪѬӮӯ԰ղճִִ׶طظٹٺڻڼ۾ܿ¯ñIJƳƴǶɸɹʺ̼;ξ|U}U}U~W~WXXZZ[[Z\[~ZjTEnWGv^NdTq^|gs{ǣ˦ϩѬӮӯӱղճֳֵֶطظٺٺڼڽ۽ۿܿ¯ñIJƴƵǶȸɹʻ̻ͽο}T}U~V~W~WXXYZ[[Z\~[~ZjTEoXHw_NeTp^|gr{Ǣ˦ϪѬӮӯԱԲղֳֵ׶طظعٻڻۼ۽۾¯ñIJųƴǷɸʹ˻˼̽Ϳ|U}V}V~WXXYYZ[[Z[\~ZjTEoXIw_NfTq^|hq{Ǣ˦ЪѬҮӰ԰Աղճֵ׶׷ظٹںڼڽ۾۾¯ðIJųǵȶɷɹ˺˼;Ϳ|U}U~V~WWXYYZ[[[[[}ZjTEnXHw_NfTq^|hr{Ǣ˦ϪѬҮӯ԰Աղմ׵׶׷ظٹڻڻڽ۽ܿ¯ñIJųƵȶɸɹʻ̼ͽο|T|U~U~V~WXYYZ[ZZ[[}ZjTEoXIw_NeTp^|hq{Ǣ˦ϪѬүӯԱԱղմֵ׶طظٹٺڼۼ۽ܿðIJŴƵǷȸʹ˺̼ͽο}T}U}U~V~W~XXYZ[[Z[[~ZkUEoXHx_OfUq_|gr{Ǣ˧ϪѬҮ԰԰Աղִ׵׶׶ظٹٺڼ۽۽ܿ°ðIJŴƴǶȷɹ˻̼̾ο}U}U~V~V~WXXZ[[[[[[~ZlUFpXIx_NfUq_|hr|Ǣ˦ΪѬҮӯ԰Բղֳֵ׵طظٺںڻ۽۽ܾ¯ñIJŴǵǶɸʹʻ˼ͽͿ|U}U}V~W~WXYYZZZZ[~[~ZnWGqZJ{aPgVr`~ir}Ǣ̦ϪѬӯӯ԰ղղִֵ׶طظعںڻڽ۽۾¯ñIJųƴȶȷɹʻ̼̽ξ|U}U~V~W~WWXYZ[ZZ[~[~ZpYHt\L|cQiXta~js|Ǣ̦ϪѬӯӯ԰ղղճִֶضظٹںڻۼ۽ܾ°ñIJŴƵǶȸɹ˻̼ͽο|T}V}V~V~WXXYZZ[[\[~[u]Ly`OfTmZwckt}ǣ̦ЪѬҮӯԱձղִִ׵طظٹٻڻۼ۾۾ݿ¯ñIJŴǵǷɸɹʺ̼ͽͿ}T}U~V~V~WXXYZZZZ[[~[z`O~dRjWp]yemv~ȣ̦ϪѬҮӯ԰Բղմֵֶ׷ظعڻڻڼ۽ۿ¯ñijŴƵǷȷʹʺ˼ͽͿ}T}U~V~W~WXYYZ[[[[[\gUjWp\ua~ipxžʤ˧ЪѬӮԯ԰ձղִֵ׶طععںڻڼ۾ܿ¯ñIJŴƵǶȸɹʺ̼ͽͿ}T|U~V~W~WXYYZ[Z[[\\nZq]vazelszğʥͨϪѬүӯԱԲճִ׵׶׷ظٹٺڻڼ۽ܾ¯ñIJųǵǶȸʹ˺̼̾ο|T}U}V~V~XXYYZ[Z[[]\v`wb|gkqw~œơ˦ͨЬѬӮӰԱԲճմֵ׶׶ظٹںڻۼ۽ܿܿ¯ðIJƴƵǶȸɹ˺̼ͽο}U|U~V}WW~XXZZ[Z[\]]}gikpuzžǢ̧ͩѫѬӯӯ԰Աճճֵ׶׷ظغںڻڼ۽ۿ¯ðIJųƵǶȸʹ˺˼ͽξ}U}V}U~V~WXYYZ[[[]\]kmqtx|Šȣ̧ΨЬҭҮӰ԰Բճִ׵׶طظٹںڻڽ۾ܿܿ¯ñijųǵȶȷʹ˺̼;ο|U}U}U~WWXXYZ[\[\\]psux{ơɤͧϩЫҭӮԯӱղճմֵ׶׷ظٹںڼڽ۽۾¯ðIJųǵȶȷʹ˺˼̽ο}T}U~V}W~WXXYZ[[\\]]tuy{~ğȢ˥ΨЪҬҭү԰Աղճֳֵ׶׷ظٹٺڼڼ۾ܿ¯ñIJųƴȶȸɹʻ˼ͽͿ|U}V~V~V~WXXZZ[\\\]^xz|~Ğǡʣ̦ΨЪҬҮҮӰ԰Բղִֵ׶طظعٺٻڼ۽ۿ¯ñIJŴƵȶȸɹ˻̼̽ο|U}U}V~W~WWXYZ[[\]]^||~›ĝƠʣ˥ͧϩЪҭҭӯӯ԰ղճմ׵׶طظٹٺٻڼ۽ܾܿ¯ñIJųƵǶȷʹ˻˼ͽο|U}U}U~WWXXZZ[\]]]^__`aabbddddfghiijkmnoprstuvxyy{™}™~ěŝŞȠɢʤ̦ͧϩЪҬҭӯӰ԰Աղֳִ׶طظٹںڻڼ۾ܿܿ¯ðIJŴƵȶȸɹ˻̼̽ξ}U}U~V~W~WXXYZ[\]]^^__aaabdddeggghjkmmooprttvwyz˜zÙ{Ù|Ú}ĚƝƞȟȡʣˤͦϨϩѫҬҭү԰Ӱձղֳִ׵طظٹٺڻۼ۽ۿ¯ñIJŴƵǷȷɹ˺˼ͽο|T|U~V~VXWXYZZ[\]^_``abcccdfghhhjklmnpqrs”t•vÖwĖxĖyė{Ř|ƙ}ƛǜǝȞȠɡʣ̤ͥΧϨЫѫѬҭӯӰ԰Աղֳֵ׶׷ظٹٺڻۼ۽۾¯ðIJųƵǶȸɹ˻̼̽ξ}U}U}V~W~WXYY[[\\]^_`a`abceeffhhjklmnoqr”sÔtÕuÖvĖxŘyř{ƙ|ƚ|ǜȝǞȟɠɡˢ̣ͥΦΧЩЪЫҬҭӮӯԱԱճմ״׶׷ظعٺٻڼ۽ۿ¯ñIJƴƵǷȷɹʺ˼̽ξ}U}U}V~VWWYYZ[[\]^_`abbdddefgijklmno‘p’r’rÓtÔuĕvĖwŗxƘzƙ|ƚ}Ǜ}Ȝ~ȝɞɟʠˢ̣̤ͥΧϨЩЫѫѬҭүӯӱղճֳֵ׶׷ظعٺٻ۽۽ܾ¯ðIJųǵȷȸʹʻ̼ͽο}T}U}V~VXXYZZZ\]]^_``bbcdeghijklmnÑoÒqĒqēsĔtŕuŖvƘwƘyƙzǚ{ț|ɜ~ɝ~ʞ˟ˠˡ̢ͣͣΥΦϦϨЩѪѫѬҭӮӯ԰Աղִֵ׶׷ظٹںڻۼ۾ۿܿ¯ðIJŴƵȷɷʹʻ̼ͽο}U|U}V~V~W~XXZZ[[]^^^`abcdeffghjklmnÑo’pÓqērŕtŕuƖvƗwǘyǙzȚ{ț}ɜ~ɝ~ʞʟˠˠ̢ͣͤͥΦΧШЩЪѫѭҭҮӯӰձճִִ׶طظٹںڻڼ۾ܿ¯ñIJŴƵǶȷʹ˻̼ͽͿ}U}U}V~WWXYZZZ[\]^_`aabceeghhijllnÑoÒpēqēsĔtŕuŖvƗwƘxǙzǚ{ț|Ȝ}ɝɞʞˠˡ̢̣ͤΤΥΧШЪЪѫҬҭӮԯԱԲֲմֵ׶ضظٹٻڼ۽۽ܾ¯ñIJųƵȶȷʹ˻̼̾ο}T|U}V~WWXYYZZ\]]^_``bccdfghijjlmnÐoÒqÓrērŔtŕuƖvƗwƘyǘzǚ{ț|ɜ}ɜʞʞˠˡˢ̣̤ΥΦϧϨЩѪѫѬҭҮӰ԰Աղճִ׶׷ظعٺڻۼ۾ܾ¯ñIJųƵǶȸʹ˺̼;ο|U}U}V~WWXYYZ[[\]__`aacddffghjklmn‘oÒpÒqĔrŔtĖuƖvƗwǘyƙzǙ{ț|ɜ~ɝʞʟˠˡ̢̣ͤͤΦϦϧЩЪѬѬҭӮӰԱձճֳ״׶׷ظٹڻڼڼ۽ܿ¯ñIJƴƵǶȸɹʻ̼̽ο|U}U~U~W~W~XXZZ[\\]^_`abbdefgghjklmnÑpÒpÒrĔrŔtĕuƖvƗwƘyǙzȚ{ț|Ȝ}ɝʞʟˠˡ̢ͣͤΥΦΧШϩЪѫѬҭүӯԱԱճճ׵׶׷ظعٻڻڼ۽ܿ¯ðIJųƵǶȸʹ˻̻ͽξejabberd-2.1.11/src/win32/ejabberd.nsi0000664000000000000000000004064412240230175014230 0ustar ; NSIS Modern User Interface ; Ejabberd installation script ;-------------------------------- ;Include Modern UI !include "MUI.nsh" !include "ejabberd.nsh" ; All release specific parameters come from this ;-------------------------------- ;General ;Name and file !define PRODUCT "Ejabberd" Name ${PRODUCT} OutFile "${OUTFILEDIR}\${PRODUCT}-${VERSION}.exe" ShowInstDetails show ShowUninstDetails show !define MUI_ICON "ejabberd.ico" !define MUI_UNICON "ejabberd.ico" !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_BITMAP "ejabberd_header.bmp" !define MUI_WELCOMEFINISHPAGE_BITMAP "ejabberd_intro.bmp" ;-------------------------------- ;Configuration SetCompressor lzma ;-------------------------------- ;Reserve Files ReserveFile "ejabberd.ico" ReserveFile "ejabberd.ico" ReserveFile "ejabberd_header.bmp" ReserveFile "ejabberd_intro.bmp" !ifdef HACKED_INSTALLOPTIONS ReserveFile "CheckUserH.ini" ReserveFile "CheckReqs1H.ini" !else ReserveFile "CheckUser.ini" ReserveFile "CheckReqs1.ini" !endif ReserveFile "CheckReqs.ini" ReserveFile "CheckService.ini" !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS ;-------------------------------- ;Variables Var MUI_TEMP Var STARTMENU_FOLDER Var ADMIN Var ENABLE_SERVICE Var ERLANG_PATH Var ERLANG_VERSION Var REQUIRED_ERLANG_VERSION Var OPENSSL_PATH Var OPENSSL_VERSION Var REQUIRED_OPENSSL_VERSION Var ERLSRV ;---------------------------------------------------------- ;.onInit uses UserInfo plugin, so it's as high as possible Function .onInit StrCpy $REQUIRED_ERLANG_VERSION "5.4.9" StrCpy $REQUIRED_OPENSSL_VERSION "0.9.7c" ;Default installation folder StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCT}" ;Get installation folder from registry if available ClearErrors ReadRegStr $0 HKLM "SOFTWARE\${PRODUCT}" "" IfErrors 0 copydir ReadRegStr $0 HKCU "SOFTWARE\${PRODUCT}" "" IfErrors skipdir copydir: StrCpy $INSTDIR "$0" skipdir: ;Extract InstallOptions INI files !ifdef HACKED_INSTALLOPTIONS !insertmacro MUI_INSTALLOPTIONS_EXTRACT "CheckUserH.ini" !insertmacro MUI_INSTALLOPTIONS_EXTRACT "CheckReqs1H.ini" !else !insertmacro MUI_INSTALLOPTIONS_EXTRACT "CheckUser.ini" !insertmacro MUI_INSTALLOPTIONS_EXTRACT "CheckReqs1.ini" !endif !insertmacro MUI_INSTALLOPTIONS_EXTRACT "CheckReqs.ini" !insertmacro MUI_INSTALLOPTIONS_EXTRACT "CheckService.ini" ClearErrors UserInfo::GetName IfErrors admin Pop $0 UserInfo::GetAccountType Pop $1 StrCmp $1 "Admin" admin user admin: StrCpy $ADMIN 1 Goto skip user: StrCpy $ADMIN 0 skip: FunctionEnd ;-------------------------------- ;Interface Settings !define MUI_ABORTWARNING ;-------------------------------- ;Installer/Uninstaller pages !insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_LICENSE "..\..\COPYING" Page custom CheckReqs LeaveCheckReqs Page custom CheckReqs1 LeaveCheckReqs1 Page custom CheckUser LeaveCheckUser Page custom CheckService LeaveCheckService ;!insertmacro MUI_PAGE_COMPONENTS !insertmacro MUI_PAGE_DIRECTORY !insertmacro MUI_PAGE_STARTMENU ${PRODUCT} $STARTMENU_FOLDER !insertmacro MUI_PAGE_INSTFILES !insertmacro MUI_UNPAGE_WELCOME !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES ;-------------------------------- ;Languages !insertmacro MUI_LANGUAGE "English" ;-------------------------------- ;Language Strings ;Description LangString DESC_SecEjabberd ${LANG_ENGLISH} "Erlang jabber server." ;-------------------------------- ;Installer Sections Section "Ejabberd" SecEjabberd SectionIn 1 RO SetOutPath "$INSTDIR" File /r "${TESTDIR}\doc" File /r "${TESTDIR}\ebin" File /r "${TESTDIR}\msgs" File /r "${TESTDIR}\win32" File "${TESTDIR}\*.dll" File "${TESTDIR}\inetrc" File /oname=ejabberd.cfg.example "${TESTDIR}\ejabberd.cfg" SetOverwrite off File "${TESTDIR}\ejabberd.cfg" SetOverwrite on ;File /r "${TESTDIR}\src" CreateDirectory "$INSTDIR\log" ;The startmenu stuff !insertmacro MUI_STARTMENU_WRITE_BEGIN ${PRODUCT} ;Create shortcuts StrCpy $0 "$SMPROGRAMS\$STARTMENU_FOLDER" CreateDirectory "$0" CreateShortCut "$0\Start Ejabberd.lnk" "$ERLANG_PATH\bin\werl.exe" \ '-sname ejabberd -pa ebin \ -env EJABBERD_LOG_PATH log/ejabberd.log \ -s ejabberd -kernel inetrc \"./inetrc\" -mnesia dir \"spool\" \ -sasl sasl_error_logger {file,\"log/erlang.log\"}' \ $INSTDIR\win32\ejabberd.ico CreateShortCut "$0\Edit Config.lnk" "%SystemRoot%\system32\notepad.exe" \ "$INSTDIR\ejabberd.cfg" CreateShortCut "$0\Read Docs.lnk" "$INSTDIR\doc\guide.html" CreateShortCut "$0\Uninstall.lnk" "$INSTDIR\Uninstall.exe" !insertmacro MUI_STARTMENU_WRITE_END ;Create Windows service StrCmp $ADMIN 1 0 skipservice StrCpy $ERLSRV "" Push $ERLANG_PATH Push erlsrv.exe GetFunctionAddress $0 FFCallback Push $0 Call FindFiles StrCmp $ERLSRV "" skipservice nsExec::Exec '"$ERLSRV" list ejabberd' Pop $0 StrCmp $0 "error" skipservice StrCmp $0 "0" 0 installsrv nsExec::ExecToLog '"$ERLSRV" remove ejabberd' Pop $0 installsrv: nsExec::ExecToLog '"$ERLSRV" add ejabberd -stopaction "init:stop()." \ -onfail restart -workdir "$INSTDIR" \ -args "-s ejabberd -pa ebin \ -kernel inetrc \\\"./inetrc\\\" \ -env EJABBERD_LOG_PATH log/ejabberd.log \ -sasl sasl_error_logger {file,\\\"log/erlang.log\\\"} \ -mnesia dir \\\"spool\\\"" -d' Pop $0 StrCmp $ENABLE_SERVICE 0 0 skipservice nsExec::ExecToLog '"$ERLSRV" disable ejabberd' Pop $0 skipservice: ;Create uninstaller WriteUninstaller "$INSTDIR\Uninstall.exe" StrCpy $1 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT}" StrCmp $ADMIN 1 admin2 WriteRegStr HKCU "Software\${PRODUCT}" "" "$INSTDIR" WriteRegStr HKCU "$1" "DisplayName" "${PRODUCT} ${VERSION}" WriteRegStr HKCU "$1" "UninstallString" "$INSTDIR\Uninstall.exe" WriteRegDWORD HKCU "$1" "NoModify" 1 WriteRegDWORD HKCU "$1" "NoRepair" 1 Goto done2 admin2: WriteRegStr HKLM "Software\${PRODUCT}" "" "$INSTDIR" WriteRegStr HKLM "Software\${PRODUCT}" "Erlsrv" "$ERLSRV" WriteRegStr HKLM "$1" "DisplayName" "${PRODUCT} ${VERSION}" WriteRegStr HKLM "$1" "UninstallString" "$INSTDIR\Uninstall.exe" WriteRegDWORD HKLM "$1" "NoModify" 1 WriteRegDWORD HKLM "$1" "NoRepair" 1 done2: SectionEnd ; SecEjabberd Function FFCallback Exch $0 StrCpy $ERLSRV $0 Pop $0 Push "stop" FunctionEnd ;-------------------------------- ;Descriptions !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SecEjabberd} $(DESC_SecEjabberd) !insertmacro MUI_FUNCTION_DESCRIPTION_END ;-------------------------------- ;Uninstaller Section Section "Uninstall" ClearErrors UserInfo::GetName IfErrors admin Pop $0 UserInfo::GetAccountType Pop $1 StrCmp $1 "Admin" admin StrCpy $ADMIN 0 Goto skipservice admin: StrCpy $ADMIN 1 ReadRegStr $ERLSRV HKLM "Software\${PRODUCT}" "Erlsrv" nsExec::Exec '"$ERLSRV" list ejabberd' Pop $0 StrCmp $0 "error" skipservice StrCmp $0 "0" 0 skipservice nsExec::ExecToLog '"$ERLSRV" remove ejabberd' Pop $0 skipservice: RMDir /r "$INSTDIR\doc" RMDir /r "$INSTDIR\ebin" RMDir /r "$INSTDIR\msgs" RMDir /r "$INSTDIR\win32" ;RMDir /r "$INSTDIR\src" RMDir /r "$INSTDIR\log" Delete "$INSTDIR\*.dll" Delete "$INSTDIR\inetrc" Delete "$INSTDIR\ejabberd.cfg.example" Delete "$INSTDIR\Uninstall.exe" RMDir "$INSTDIR" !insertmacro MUI_STARTMENU_GETFOLDER ${PRODUCT} $MUI_TEMP Delete "$SMPROGRAMS\$MUI_TEMP\Start Ejabberd.lnk" Delete "$SMPROGRAMS\$MUI_TEMP\Edit Config.lnk" Delete "$SMPROGRAMS\$MUI_TEMP\Read Docs.lnk" Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" ;Delete empty start menu parent diretories StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" startMenuDeleteLoop: RMDir $MUI_TEMP GetFullPathName $MUI_TEMP "$MUI_TEMP\.." IfErrors startMenuDeleteLoopDone StrCmp $MUI_TEMP $SMPROGRAMS startMenuDeleteLoopDone startMenuDeleteLoop startMenuDeleteLoopDone: StrCpy $1 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT}" StrCmp $ADMIN 1 admin1 DeleteRegKey HKCU "Software\${PRODUCT}" DeleteRegKey HKCU $1 Goto done admin1: DeleteRegKey HKLM "Software\${PRODUCT}" DeleteRegKey HKLM $1 done: SectionEnd LangString TEXT_CU_TITLE ${LANG_ENGLISH} "Checking User Privileges" LangString TEXT_CU_SUBTITLE ${LANG_ENGLISH} "Checking user privileged required to install Ejabberd." Function CheckUser StrCmp $ADMIN 1 0 showpage Abort showpage: !insertmacro MUI_HEADER_TEXT $(TEXT_CU_TITLE) $(TEXT_CU_SUBTITLE) !ifdef HACKED_INSTALLOPTIONS !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "CheckUserH.ini" !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckUserH.ini" "Field 2" "State" GetDlgItem $1 $HWNDPARENT 1 EnableWindow $1 $0 !else !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "CheckUser.ini" !endif !insertmacro MUI_INSTALLOPTIONS_SHOW FunctionEnd Function LeaveCheckUser !ifdef HACKED_INSTALLOPTIONS !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckUserH.ini" "Settings" "State" StrCmp $0 0 validate ;Next button? StrCmp $0 2 checkbox ;checkbox? Abort ;Return to the page checkbox: !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckUserH.ini" "Field 2" "State" GetDlgItem $1 $HWNDPARENT 1 EnableWindow $1 $0 Abort validate: !endif FunctionEnd LangString TEXT_CU_TITLE ${LANG_ENGLISH} "Configuring Ejabberd Service" LangString TEXT_CU_SUBTITLE ${LANG_ENGLISH} "Configuring Ejabberd Service." Function CheckService StrCmp $ADMIN 0 0 showpage Abort showpage: !insertmacro MUI_HEADER_TEXT $(TEXT_CU_TITLE) $(TEXT_CU_SUBTITLE) !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "CheckService.ini" !insertmacro MUI_INSTALLOPTIONS_SHOW FunctionEnd Function LeaveCheckService !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckService.ini" "Field 2" "State" StrCmp $0 0 0 autostart StrCpy $ENABLE_SERVICE 0 Goto endfun autostart: StrCpy $ENABLE_SERVICE 1 endfun: FunctionEnd LangString TEXT_CR_TITLE ${LANG_ENGLISH} "Unsatisfied Requirements" LangString TEXT_CR_SUBTITLE ${LANG_ENGLISH} "Unsatisfied Ejabberd requirements found." Function CheckReqs Push "HKLM" Call FindErlang Pop $ERLANG_PATH Pop $ERLANG_VERSION StrCmp $ERLANG_PATH "" 0 abort Push "HKCU" Call FindErlang Pop $ERLANG_PATH Pop $ERLANG_VERSION StrCmp $ERLANG_PATH "" 0 abort !insertmacro MUI_HEADER_TEXT $(TEXT_CR_TITLE) $(TEXT_CR_SUBTITLE) !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "CheckReqs.ini" GetDlgItem $R0 $HWNDPARENT 1 EnableWindow $R0 0 !insertmacro MUI_INSTALLOPTIONS_SHOW abort: Abort FunctionEnd Function LeaveCheckReqs Abort FunctionEnd Function CheckReqs1 Push "HKLM" Call FindOpenSSL Pop $OPENSSL_PATH Pop $OPENSSL_VERSION StrCmp $OPENSSL_PATH "" 0 abort Push "HKCU" Call FindOpenSSL Pop $OPENSSL_PATH Pop $OPENSSL_VERSION StrCmp $OPENSSL_PATH "" 0 abort !insertmacro MUI_HEADER_TEXT $(TEXT_CR_TITLE) $(TEXT_CR_SUBTITLE) !ifdef HACKED_INSTALLOPTIONS !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "CheckReqs1H.ini" !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckReqs1H.ini" "Field 3" "State" GetDlgItem $1 $HWNDPARENT 1 EnableWindow $1 $0 !else !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "CheckReqs1.ini" !endif !insertmacro MUI_INSTALLOPTIONS_SHOW abort: Abort FunctionEnd Function LeaveCheckReqs1 !ifdef HACKED_INSTALLOPTIONS !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckReqs1H.ini" "Settings" "State" StrCmp $0 0 validate ;Next button? StrCmp $0 3 checkbox ;checkbox? Abort ;Return to the page checkbox: !insertmacro MUI_INSTALLOPTIONS_READ $0 "CheckReqs1H.ini" "Field 3" "State" GetDlgItem $1 $HWNDPARENT 1 EnableWindow $1 $0 Abort validate: !endif FunctionEnd Function FindErlang Exch $R0 Push $R1 Push $R2 Push $R3 Push $R4 Push $R5 StrCpy $R1 0 StrCpy $R2 "SOFTWARE\Ericsson\Erlang" loop: StrCmp $R0 HKLM h1 EnumRegKey $R3 HKCU $R2 $R1 Goto l1 h1: EnumRegKey $R3 HKLM $R2 $R1 l1: IntOp $R1 $R1 + 1 StrCmp $R3 "" endloop ClearErrors StrCmp $R0 HKLM h2 ReadRegStr $R4 HKCU "$R2\$R3" "" Goto l2 h2: ReadRegStr $R4 HKLM "$R2\$R3" "" l2: IfFileExists "$R4\bin\erl.exe" 0 loop Push $REQUIRED_ERLANG_VERSION Push $R3 Call CompareVersions Pop $R5 StrCmp $R5 1 get Goto loop endloop: StrCpy $R4 "" get: StrCpy $R0 $R4 StrCpy $R1 $R3 Pop $R5 Pop $R4 Pop $R3 Pop $R2 Exch $R1 Exch Exch $R0 FunctionEnd Function FindOpenSSL Exch $R0 Push $R1 Push $R2 Push $R3 Push $R4 Push $R5 StrCpy $R1 0 StrCpy $R2 "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\OpenSSL_is1" StrCmp $R0 HKLM h1 ReadRegStr $R3 HKCU "$R2" "DisplayName" ReadRegStr $R4 HKCU "$R2" "Inno Setup: App Path" Goto l1 h1: ReadRegStr $R3 HKLM "$R2" "DisplayName" ReadRegStr $R4 HKLM "$R2" "Inno Setup: App Path" l1: IfFileExists "$R4\bin\openssl.exe" 0 notfound Goto get ; TODO check version ;Push $REQUIRED_OPENSSL_VERSION ;Push $R3 ;Call CompareVersions ;Pop $R5 ;StrCmp $R5 1 get notfound: StrCpy $R4 "" get: StrCpy $R0 $R4 StrCpy $R1 $R3 Pop $R5 Pop $R4 Pop $R3 Pop $R2 Exch $R1 Exch Exch $R0 FunctionEnd ;---------------------------------------------------------------------- ; CompareVersions ; input: ; top of stack = existing version ; top of stack-1 = needed version ; output: ; top of stack = 1 if current version => neded version, else 0 ; version is a string in format "xx.xx.xx.xx" (number of interger sections ; can be different in needed and existing versions) Function CompareVersions ; stack: existing ver | needed ver Exch $R0 Exch Exch $R1 ; stack: $R1|$R0 Push $R1 Push $R0 ; stack: e|n|$R1|$R0 ClearErrors loop: IfErrors VersionNotFound Strcmp $R0 "" VersionTestEnd Call ParseVersion Pop $R0 Exch Call ParseVersion Pop $R1 Exch IntCmp $R1 $R0 +1 VersionOk VersionNotFound Pop $R0 Push $R0 goto loop VersionTestEnd: Pop $R0 Pop $R1 Push $R1 Push $R0 StrCmp $R0 $R1 VersionOk VersionNotFound VersionNotFound: StrCpy $R0 "0" Goto end VersionOk: StrCpy $R0 "1" end: ; stack: e|n|$R1|$R0 Exch $R0 Pop $R0 Exch $R0 ; stack: res|$R1|$R0 Exch ; stack: $R1|res|$R0 Pop $R1 ; stack: res|$R0 Exch Pop $R0 ; stack: res FunctionEnd ;----------------------------------------------------------------------- ; ParseVersion ; input: ; top of stack = version string ("xx.xx.xx.xx") ; output: ; top of stack = first number in version ("xx") ; top of stack-1 = rest of the version string ("xx.xx.xx") Function ParseVersion Exch $R1 ; version Push $R2 Push $R3 StrCpy $R2 1 loop: StrCpy $R3 $R1 1 $R2 StrCmp $R3 "." loopend StrLen $R3 $R1 IntCmp $R3 $R2 loopend loopend IntOp $R2 $R2 + 1 Goto loop loopend: Push $R1 StrCpy $R1 $R1 $R2 Exch $R1 StrLen $R3 $R1 IntOp $R3 $R3 - $R2 IntOp $R2 $R2 + 1 StrCpy $R1 $R1 $R3 $R2 Push $R1 Exch 2 Pop $R3 Exch 2 Pop $R2 Exch 2 Pop $R1 FunctionEnd Function FindFiles Exch $R5 # callback function Exch Exch $R4 # file name Exch 2 Exch $R0 # directory Push $R1 Push $R2 Push $R3 Push $R6 Push $R0 # first dir to search StrCpy $R3 1 nextDir: Pop $R0 IntOp $R3 $R3 - 1 ClearErrors FindFirst $R1 $R2 "$R0\*.*" nextFile: StrCmp $R2 "." gotoNextFile StrCmp $R2 ".." gotoNextFile StrCmp $R2 $R4 0 isDir Push "$R0\$R2" Call $R5 Pop $R6 StrCmp $R6 "stop" 0 isDir loop: StrCmp $R3 0 done Pop $R0 IntOp $R3 $R3 - 1 Goto loop isDir: IfFileExists "$R0\$R2\*.*" 0 gotoNextFile IntOp $R3 $R3 + 1 Push "$R0\$R2" gotoNextFile: FindNext $R1 $R2 IfErrors 0 nextFile done: FindClose $R1 StrCmp $R3 0 0 nextDir Pop $R6 Pop $R3 Pop $R2 Pop $R1 Pop $R0 Pop $R5 Pop $R4 FunctionEnd ejabberd-2.1.11/src/win32/CheckReqs1.ini0000664000000000000000000000113312240230175014377 0ustar [Settings] NumFields=3 [Field 1] Type=label Left=0 Right=-1 Top=10 Bottom=70 Text="OpenSLL 0.9.7i or newer is not found on your computer.\r\n\r\nTo use SSL and TLS encryption you need an SSL certificate. You can create a selfsigned certificate with OpenSSL.\r\n\r\nOpenSLL installer can be downloaded from" [Field 2] Type=link Left=0 Right=-1 Top=74 Bottom=88 State=http://www.slproweb.com/products/Win32OpenSSL.html Text=http://www.slproweb.com/products/Win32OpenSSL.html [Field 3] Type=label Left=0 Right=-1 Top=93 Bottom=-10 Text="If you want to continue installing Ejabberd anyway, click Next." ejabberd-2.1.11/src/win32/ejabberd_intro.bmp0000664000000000000000000006357612240230175015441 0ustar BM~gv(:g  DDD@@@@DDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@DDDDDDDDD@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@DDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDD@@@@DDDDDDDDDD@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@DDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@DDDDDDDDDD@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@DDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@DDDDDDDDDD@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@DDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@DDDDDDDDD@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@DDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@DDDDDDDDDD@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@DDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDD@@@@@DDDDDDDDD@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@DDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@DDDDDDDDDD@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@DDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDD@@@@@@DDDDDDDD@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@DDDDDDD@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDD@@@@@@@@@DDDDD@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@@DDD@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDD@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDD@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDD@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDD@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDD@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDD@@@@@@@@@@@@@@@@@@@DDDDDDDDD@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDD@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDD@@@@@@@@@@@@@@@@DDDDDDDDD@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDD@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDD@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@DDDDD@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@DDDDDD@@@@@@@DDDDDDDDDD@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@DDDDDD@@@@@@@DDDDDDDD@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@DDDDD@@@@@@DDDDDDDD@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@DDDDDD@@@@@DDDDDD@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@DDDDDD@@@@@DDDD@@@@@@@@@@@@@@@@@DDDDDDDDDD@DDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@DDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@DDDDDDDDDDDDDDDDDDD@@@@@@DDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@DDDDDD@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@DDDDDDDDDDDDDDDDD@@@@@@@DDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@DDDDDDD@@@@@@@@@@@@@@@@@@@@DDDDDDDDD@@@@@@DDDDDDDDDDDDDDD@@@@@@@DDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@DDDDDDD@@@@@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@DDDDDDDDDDDDDD@@@@@@DDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@DDDDDDD@@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@DDDDDDDDDDD@@@@@@@DDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDD@@@@@@@@@@@@DDDDDDDDD@@@@@@@@@@@@DDDDDDDDD@@@@@@@DDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDD@@@@@@@@@@@DDDDDDDD@@@@@@@@@@@@@DDDDDDDD@@@@@@@DDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@DDDDDDDD@@@@@@@@@@DDDDDD@@@@@@@@@@@@@@@DDDDDD@@@@@@@DDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@DDDDDDDD@@@@@@@@@@DDDD@@@@@@@@@@@@@@@@@DDDD@@@@@@DDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@DDDDDDDDD@@@@@@@@@@@@@@@@@@@DDDDD@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@DDDDDDDD@@@@@@@@@@@@@@@@@DDDDDDD@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@DDDDDDDDD@@@@@@@@@@@@@DDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@DDDDDDDDDDD@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@DDDDDDDDDDD@@@@@@DDDDDDDDDDDD@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@DDDDDDDDDDDD@DDDDDDDDDDDDDD@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDD@DDDDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@DDDDDDDDD@@@@@@@@@@@@@DDDDDDDDDDDDDDDDD@@DDDDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@DDDDDDDDDD@@@@@@@@@@@@@@DDDDDDDDDDDD@@@@@DDDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDD@@@@@@@@@@@@@@DDDDDDDD@@@@@@@DDDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@DDDDDDDDDDDD@@@@@@@@@@@@@@DDDD@@@@@@@@DDDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@DDDDDDDDDDDDDDD@@@@@@@@@@@@@@@@@@@@@@DDDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@DDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@@@@@DDDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDD@@@@@@@@@@@@@@@@@@DDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@DDDDDDDDDDDDD@@@@@@@@@@@@@@@@@@DDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@@@@@@@@@@DDDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@@@@@@@@@@DDDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@DDDDDDDDDD@@@@@@@@@@@@@@@@@@@@@DDDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@DDDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDD@@@@@DDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@@DD@@@@@@DD@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDD@@@@DDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDDD@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@DDDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@DDDDDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@@DDD@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDODDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@@@@@@@@@@@@@DDDDDDODDDDDDDDDDDDDDDDDDDDODDDDDDODDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@@@@@@@@@@@@DDDDDDDODDDDDDODDDDDDDDDDDDDDDDDDDDDDODDDDDODDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@@@@@@@@@@DDDDDDDDDODDDDDODDDDDDDDDDDDDDDDDDDDDDDODDDDODDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@@@@@@@@DDDDDDDDDDDODDDDODDDDDDDDDDDDDDDDDDDDDDDDDODDDODDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@@@@@@@DDDDDDDDDDDDODDDODDDDDDDDDDDDDDDDDDDDDDDDDDDODDODDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@@@@@DDDDDDDDDDDDDDODDODDDDDDDDDDDDDDDDDDDDDDDDDDDDODDODDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@@@@DDDDDDDDDDDDDDDODDODDDDDDDDDDDDDDDDDDDDDDDDDDDDDDODODDDDDDDD@@@@@@@@@@@@@@@DDDDD@@@@DDDDDDDDDDDDDDDDDODODDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDODDODDDODODDDDDDDD@@@@@@@@@@@@@@@DDDDD@@DDDDDDDDDDDDDDDDDDDODDODDDODODDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDODDODDDDDODODDDDDDDD@@@@@@@@@@@@@@@DDDDD@DDDDDDDDDDDDDDDDDDDDODDODDDDDODODDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDODODDDDDDODODDDDDDDD@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDODODDDDDDODODDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDODODDDDDDOODDDDDDDD@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDODODDDDDDOODDDDDDD@DDDDDDDDDDDDDDDDDDDDDDDDDODODDDDDDOODDDDDDD@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDODODDDDDDOODDDDD@@@DDDDDDDDDDDDDDDDDDDDDDDDDOODDDDDOODDDDD@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDOODDDDDOODDDD@@@@DDDDDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOODDD@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOODD@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOODD@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@DDDDDDDDDDDODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDDDOO@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDDDOO@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ODDDDDDDDDDDDDDDOO@@@@@@@@DDDDDDDDDDDDDDO@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ODDDDDDDDDDDDDDO@@@@@@@@DDDDDDDDDDO@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ODDDDDDDDDDO@@@@@@@@DDDDDDDDDDO@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ODDDDDDDDDDO@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@O@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ejabberd-2.1.11/src/adhoc.erl0000664000000000000000000000765012240230175012577 0ustar %%%---------------------------------------------------------------------- %%% File : adhoc.erl %%% Author : Magnus Henoch %%% Purpose : Provide helper functions for ad-hoc commands (XEP-0050) %%% Created : 31 Oct 2005 by Magnus Henoch %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(adhoc). -author('henoch@dtek.chalmers.se'). -export([parse_request/1, produce_response/2, produce_response/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("adhoc.hrl"). %% Parse an ad-hoc request. Return either an adhoc_request record or %% an {error, ErrorType} tuple. parse_request(#iq{type = set, lang = Lang, sub_el = SubEl, xmlns = ?NS_COMMANDS}) -> ?DEBUG("entering parse_request...", []), Node = xml:get_tag_attr_s("node", SubEl), SessionID = xml:get_tag_attr_s("sessionid", SubEl), Action = xml:get_tag_attr_s("action", SubEl), XData = find_xdata_el(SubEl), {xmlelement, _, _, AllEls} = SubEl, Others = case XData of false -> AllEls; _ -> lists:delete(XData, AllEls) end, #adhoc_request{lang = Lang, node = Node, sessionid = SessionID, action = Action, xdata = XData, others = Others}; parse_request(_) -> {error, ?ERR_BAD_REQUEST}. %% Borrowed from mod_vcard.erl find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) -> find_xdata_el1(SubEls). find_xdata_el1([]) -> false; find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_XDATA -> {xmlelement, Name, Attrs, SubEls}; _ -> find_xdata_el1(Els) end; find_xdata_el1([_ | Els]) -> find_xdata_el1(Els). %% Produce a node to use as response from an adhoc_response %% record, filling in values for language, node and session id from %% the request. produce_response(#adhoc_request{lang = Lang, node = Node, sessionid = SessionID}, Response) -> produce_response(Response#adhoc_response{lang = Lang, node = Node, sessionid = SessionID}). %% Produce a node to use as response from an adhoc_response %% record. produce_response(#adhoc_response{lang = _Lang, node = Node, sessionid = ProvidedSessionID, status = Status, defaultaction = DefaultAction, actions = Actions, notes = Notes, elements = Elements}) -> SessionID = if is_list(ProvidedSessionID), ProvidedSessionID /= "" -> ProvidedSessionID; true -> jlib:now_to_utc_string(now()) end, case Actions of [] -> ActionsEls = []; _ -> case DefaultAction of "" -> ActionsElAttrs = []; _ -> ActionsElAttrs = [{"execute", DefaultAction}] end, ActionsEls = [{xmlelement, "actions", ActionsElAttrs, [{xmlelement, Action, [], []} || Action <- Actions]}] end, NotesEls = lists:map(fun({Type, Text}) -> {xmlelement, "note", [{"type", Type}], [{xmlcdata, Text}]} end, Notes), {xmlelement, "command", [{"xmlns", ?NS_COMMANDS}, {"sessionid", SessionID}, {"node", Node}, {"status", atom_to_list(Status)}], ActionsEls ++ NotesEls ++ Elements}. ejabberd-2.1.11/src/ejabberd.erl0000664000000000000000000000374512240230175013260 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd.erl %%% Author : Alexey Shchepin %%% Purpose : ejabberd wrapper: start / stop %%% Created : 16 Nov 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd). -author('alexey@process-one.net'). -export([start/0, stop/0, get_pid_file/0, get_so_path/0, get_bin_path/0]). start() -> %%ejabberd_cover:start(), application:start(ejabberd). stop() -> application:stop(ejabberd). %%ejabberd_cover:stop(). get_so_path() -> case os:getenv("EJABBERD_SO_PATH") of false -> case code:priv_dir(ejabberd) of {error, _} -> "."; Path -> filename:join([Path, "lib"]) end; Path -> Path end. get_bin_path() -> case os:getenv("EJABBERD_BIN_PATH") of false -> case code:priv_dir(ejabberd) of {error, _} -> "."; Path -> filename:join([Path, "bin"]) end; Path -> Path end. %% @spec () -> false | string() get_pid_file() -> case os:getenv("EJABBERD_PID_PATH") of false -> false; "" -> false; Path -> Path end. ejabberd-2.1.11/src/ejabberd_auth_odbc.erl0000664000000000000000000001754512240230175015273 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_auth_odbc.erl %%% Author : Alexey Shchepin %%% Purpose : Authentification via ODBC %%% Created : 12 Dec 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_auth_odbc). -author('alexey@process-one.net'). %% External exports -export([start/1, set_password/3, check_password/3, check_password/5, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, get_vh_registered_users_number/1, get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, remove_user/3, store_type/0, plain_password_required/0 ]). -include("ejabberd.hrl"). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start(_Host) -> ok. plain_password_required() -> false. store_type() -> plain. %% @spec (User, Server, Password) -> true | false | {error, Error} check_password(User, Server, Password) -> case jlib:nodeprep(User) of error -> false; LUser -> Username = ejabberd_odbc:escape(LUser), LServer = jlib:nameprep(Server), try odbc_queries:get_password(LServer, Username) of {selected, ["password"], [{Password}]} -> Password /= ""; %% Password is correct, and not empty {selected, ["password"], [{_Password2}]} -> false; %% Password is not correct {selected, ["password"], []} -> false; %% Account does not exist {error, _Error} -> false %% Typical error is that table doesn't exist catch _:_ -> false %% Typical error is database not accessible end end. %% @spec (User, Server, Password, Digest, DigestGen) -> true | false | {error, Error} check_password(User, Server, Password, Digest, DigestGen) -> case jlib:nodeprep(User) of error -> false; LUser -> Username = ejabberd_odbc:escape(LUser), LServer = jlib:nameprep(Server), try odbc_queries:get_password(LServer, Username) of %% Account exists, check if password is valid {selected, ["password"], [{Passwd}]} -> DigRes = if Digest /= "" -> Digest == DigestGen(Passwd); true -> false end, if DigRes -> true; true -> (Passwd == Password) and (Password /= "") end; {selected, ["password"], []} -> false; %% Account does not exist {error, _Error} -> false %% Typical error is that table doesn't exist catch _:_ -> false %% Typical error is database not accessible end end. %% @spec (User::string(), Server::string(), Password::string()) -> %% ok | {error, invalid_jid} set_password(User, Server, Password) -> case jlib:nodeprep(User) of error -> {error, invalid_jid}; LUser -> Username = ejabberd_odbc:escape(LUser), Pass = ejabberd_odbc:escape(Password), LServer = jlib:nameprep(Server), case catch odbc_queries:set_password_t(LServer, Username, Pass) of {atomic, ok} -> ok; Other -> {error, Other} end end. %% @spec (User, Server, Password) -> {atomic, ok} | {atomic, exists} | {error, invalid_jid} try_register(User, Server, Password) -> case jlib:nodeprep(User) of error -> {error, invalid_jid}; LUser -> Username = ejabberd_odbc:escape(LUser), Pass = ejabberd_odbc:escape(Password), LServer = jlib:nameprep(Server), case catch odbc_queries:add_user(LServer, Username, Pass) of {updated, 1} -> {atomic, ok}; _ -> {atomic, exists} end end. dirty_get_registered_users() -> Servers = ejabberd_config:get_vh_by_auth_method(odbc), lists:flatmap( fun(Server) -> get_vh_registered_users(Server) end, Servers). get_vh_registered_users(Server) -> LServer = jlib:nameprep(Server), case catch odbc_queries:list_users(LServer) of {selected, ["username"], Res} -> [{U, LServer} || {U} <- Res]; _ -> [] end. get_vh_registered_users(Server, Opts) -> LServer = jlib:nameprep(Server), case catch odbc_queries:list_users(LServer, Opts) of {selected, ["username"], Res} -> [{U, LServer} || {U} <- Res]; _ -> [] end. get_vh_registered_users_number(Server) -> LServer = jlib:nameprep(Server), case catch odbc_queries:users_number(LServer) of {selected, [_], [{Res}]} -> list_to_integer(Res); _ -> 0 end. get_vh_registered_users_number(Server, Opts) -> LServer = jlib:nameprep(Server), case catch odbc_queries:users_number(LServer, Opts) of {selected, [_], [{Res}]} -> list_to_integer(Res); _Other -> 0 end. get_password(User, Server) -> case jlib:nodeprep(User) of error -> false; LUser -> Username = ejabberd_odbc:escape(LUser), LServer = jlib:nameprep(Server), case catch odbc_queries:get_password(LServer, Username) of {selected, ["password"], [{Password}]} -> Password; _ -> false end end. get_password_s(User, Server) -> case jlib:nodeprep(User) of error -> ""; LUser -> Username = ejabberd_odbc:escape(LUser), LServer = jlib:nameprep(Server), case catch odbc_queries:get_password(LServer, Username) of {selected, ["password"], [{Password}]} -> Password; _ -> "" end end. %% @spec (User, Server) -> true | false | {error, Error} is_user_exists(User, Server) -> case jlib:nodeprep(User) of error -> false; LUser -> Username = ejabberd_odbc:escape(LUser), LServer = jlib:nameprep(Server), try odbc_queries:get_password(LServer, Username) of {selected, ["password"], [{_Password}]} -> true; %% Account exists {selected, ["password"], []} -> false; %% Account does not exist {error, Error} -> {error, Error} %% Typical error is that table doesn't exist catch _:B -> {error, B} %% Typical error is database not accessible end end. %% @spec (User, Server) -> ok | error %% @doc Remove user. %% Note: it may return ok even if there was some problem removing the user. remove_user(User, Server) -> case jlib:nodeprep(User) of error -> error; LUser -> Username = ejabberd_odbc:escape(LUser), LServer = jlib:nameprep(Server), catch odbc_queries:del_user(LServer, Username), ok end. %% @spec (User, Server, Password) -> ok | error | not_exists | not_allowed %% @doc Remove user if the provided password is correct. remove_user(User, Server, Password) -> case jlib:nodeprep(User) of error -> error; LUser -> Username = ejabberd_odbc:escape(LUser), Pass = ejabberd_odbc:escape(Password), LServer = jlib:nameprep(Server), F = fun() -> Result = odbc_queries:del_user_return_password( LServer, Username, Pass), case Result of {selected, ["password"], [{Password}]} -> ok; {selected, ["password"], []} -> not_exists; _ -> not_allowed end end, {atomic, Result} = odbc_queries:sql_transaction(LServer, F), Result end. ejabberd-2.1.11/src/mod_service_log.erl0000664000000000000000000000506512240230175014657 0ustar %%%---------------------------------------------------------------------- %%% File : mod_service_log.erl %%% Author : Alexey Shchepin %%% Purpose : Copy user messages to logger service %%% Created : 24 Aug 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_service_log). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, log_user_send/3, log_user_receive/4]). -include("ejabberd.hrl"). -include("jlib.hrl"). start(Host, _Opts) -> ejabberd_hooks:add(user_send_packet, Host, ?MODULE, log_user_send, 50), ejabberd_hooks:add(user_receive_packet, Host, ?MODULE, log_user_receive, 50), ok. stop(Host) -> ejabberd_hooks:delete(user_send_packet, Host, ?MODULE, log_user_send, 50), ejabberd_hooks:delete(user_receive_packet, Host, ?MODULE, log_user_receive, 50), ok. log_user_send(From, To, Packet) -> log_packet(From, To, Packet, From#jid.lserver). log_user_receive(_JID, From, To, Packet) -> log_packet(From, To, Packet, To#jid.lserver). log_packet(From, To, {xmlelement, Name, Attrs, Els}, Host) -> Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers, []), ServerJID = #jid{user = "", server = Host, resource = "", luser = "", lserver = Host, lresource = ""}, NewAttrs = jlib:replace_from_to_attrs(jlib:jid_to_string(From), jlib:jid_to_string(To), Attrs), FixedPacket = {xmlelement, Name, NewAttrs, Els}, lists:foreach( fun(Logger) -> ejabberd_router:route( ServerJID, #jid{user = "", server = Logger, resource = "", luser = "", lserver = Logger, lresource = ""}, {xmlelement, "route", [], [FixedPacket]}) end, Loggers). ejabberd-2.1.11/src/ejabberd_c2s.erl0000664000000000000000000022017712240230175014027 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_c2s.erl %%% Author : Alexey Shchepin %%% Purpose : Serve C2S connection %%% Created : 16 Nov 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_c2s). -author('alexey@process-one.net'). -update_info({update, 0}). -define(GEN_FSM, p1_fsm). -behaviour(?GEN_FSM). %% External exports -export([start/2, stop/1, start_link/2, send_text/2, send_element/2, socket_type/0, get_presence/1, get_aux_field/2, set_aux_field/3, del_aux_field/2, get_subscription/2, broadcast/4, get_subscribed/1]). %% gen_fsm callbacks -export([init/1, wait_for_stream/2, wait_for_auth/2, wait_for_feature_request/2, wait_for_bind/2, wait_for_session/2, wait_for_sasl_response/2, session_established/2, handle_event/3, handle_sync_event/4, code_change/4, handle_info/3, terminate/3, print_state/1 ]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_privacy.hrl"). -define(SETS, gb_sets). -define(DICT, dict). %% pres_a contains all the presence available send (either through roster mechanism or directed). %% Directed presence unavailable remove user from pres_a. -record(state, {socket, sockmod, socket_monitor, xml_socket, streamid, sasl_state, access, shaper, zlib = false, tls = false, tls_required = false, tls_enabled = false, tls_options = [], authenticated = false, jid, user = "", server = ?MYNAME, resource = "", sid, pres_t = ?SETS:new(), pres_f = ?SETS:new(), pres_a = ?SETS:new(), pres_i = ?SETS:new(), pres_last, pres_pri, pres_timestamp, pres_invis = false, privacy_list = #userlist{}, conn = unknown, auth_module = unknown, ip, aux_fields = [], lang}). %-define(DBGFSM, true). -ifdef(DBGFSM). -define(FSMOPTS, [{debug, [trace]}]). -else. -define(FSMOPTS, []). -endif. %% Module start with or without supervisor: -ifdef(NO_TRANSIENT_SUPERVISORS). -define(SUPERVISOR_START, ?GEN_FSM:start(ejabberd_c2s, [SockData, Opts], fsm_limit_opts(Opts) ++ ?FSMOPTS)). -else. -define(SUPERVISOR_START, supervisor:start_child(ejabberd_c2s_sup, [SockData, Opts])). -endif. %% This is the timeout to apply between event when starting a new %% session: -define(C2S_OPEN_TIMEOUT, 60000). -define(C2S_HIBERNATE_TIMEOUT, 90000). -define(STREAM_HEADER, "" "" ). -define(STREAM_TRAILER, ""). -define(INVALID_NS_ERR, ?SERR_INVALID_NAMESPACE). -define(INVALID_XML_ERR, ?SERR_XML_NOT_WELL_FORMED). -define(HOST_UNKNOWN_ERR, ?SERR_HOST_UNKNOWN). -define(POLICY_VIOLATION_ERR(Lang, Text), ?SERRT_POLICY_VIOLATION(Lang, Text)). -define(INVALID_FROM, ?SERR_INVALID_FROM). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start(SockData, Opts) -> ?SUPERVISOR_START. start_link(SockData, Opts) -> ?GEN_FSM:start_link(ejabberd_c2s, [SockData, Opts], fsm_limit_opts(Opts) ++ ?FSMOPTS). socket_type() -> xml_stream. %% Return Username, Resource and presence information get_presence(FsmRef) -> ?GEN_FSM:sync_send_all_state_event(FsmRef, {get_presence}, 1000). get_aux_field(Key, #state{aux_fields = Opts}) -> case lists:keysearch(Key, 1, Opts) of {value, {_, Val}} -> {ok, Val}; _ -> error end. set_aux_field(Key, Val, #state{aux_fields = Opts} = State) -> Opts1 = lists:keydelete(Key, 1, Opts), State#state{aux_fields = [{Key, Val}|Opts1]}. del_aux_field(Key, #state{aux_fields = Opts} = State) -> Opts1 = lists:keydelete(Key, 1, Opts), State#state{aux_fields = Opts1}. get_subscription(From = #jid{}, StateData) -> get_subscription(jlib:jid_tolower(From), StateData); get_subscription(LFrom, StateData) -> LBFrom = setelement(3, LFrom, ""), F = ?SETS:is_element(LFrom, StateData#state.pres_f) orelse ?SETS:is_element(LBFrom, StateData#state.pres_f), T = ?SETS:is_element(LFrom, StateData#state.pres_t) orelse ?SETS:is_element(LBFrom, StateData#state.pres_t), if F and T -> both; F -> from; T -> to; true -> none end. broadcast(FsmRef, Type, From, Packet) -> FsmRef ! {broadcast, Type, From, Packet}. stop(FsmRef) -> ?GEN_FSM:send_event(FsmRef, closed). %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, StateName, StateData} | %% {ok, StateName, StateData, Timeout} | %% ignore | %% {stop, StopReason} %%---------------------------------------------------------------------- init([{SockMod, Socket}, Opts]) -> Access = case lists:keysearch(access, 1, Opts) of {value, {_, A}} -> A; _ -> all end, Shaper = case lists:keysearch(shaper, 1, Opts) of {value, {_, S}} -> S; _ -> none end, XMLSocket = case lists:keysearch(xml_socket, 1, Opts) of {value, {_, XS}} -> XS; _ -> false end, Zlib = lists:member(zlib, Opts), StartTLS = lists:member(starttls, Opts), StartTLSRequired = lists:member(starttls_required, Opts), TLSEnabled = lists:member(tls, Opts), TLS = StartTLS orelse StartTLSRequired orelse TLSEnabled, TLSOpts1 = lists:filter(fun({certfile, _}) -> true; (_) -> false end, Opts), TLSOpts = [verify_none | TLSOpts1], IP = peerip(SockMod, Socket), %% Check if IP is blacklisted: case is_ip_blacklisted(IP) of true -> ?INFO_MSG("Connection attempt from blacklisted IP: ~s (~w)", [jlib:ip_to_list(IP), IP]), {stop, normal}; false -> Socket1 = if TLSEnabled -> SockMod:starttls(Socket, TLSOpts); true -> Socket end, SocketMonitor = SockMod:monitor(Socket1), {ok, wait_for_stream, #state{socket = Socket1, sockmod = SockMod, socket_monitor = SocketMonitor, xml_socket = XMLSocket, zlib = Zlib, tls = TLS, tls_required = StartTLSRequired, tls_enabled = TLSEnabled, tls_options = TLSOpts, streamid = new_id(), access = Access, shaper = Shaper, ip = IP}, ?C2S_OPEN_TIMEOUT} end. %% Return list of all available resources of contacts, get_subscribed(FsmRef) -> ?GEN_FSM:sync_send_all_state_event(FsmRef, get_subscribed, 1000). %%---------------------------------------------------------------------- %% Func: StateName/2 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> DefaultLang = case ?MYLANG of undefined -> "en"; DL -> DL end, case xml:get_attr_s("xmlns:stream", Attrs) of ?NS_STREAM -> Server = jlib:nameprep(xml:get_attr_s("to", Attrs)), case lists:member(Server, ?MYHOSTS) of true -> Lang = case xml:get_attr_s("xml:lang", Attrs) of Lang1 when length(Lang1) =< 35 -> %% As stated in BCP47, 4.4.1: %% Protocols or specifications that %% specify limited buffer sizes for %% language tags MUST allow for %% language tags of at least 35 characters. Lang1; _ -> %% Do not store long language tag to %% avoid possible DoS/flood attacks "" end, change_shaper(StateData, jlib:make_jid("", Server, "")), case xml:get_attr_s("version", Attrs) of "1.0" -> send_header(StateData, Server, "1.0", DefaultLang), case StateData#state.authenticated of false -> SASLState = cyrsasl:server_new( "jabber", Server, "", [], fun(U) -> ejabberd_auth:get_password_with_authmodule( U, Server) end, fun(U, P) -> ejabberd_auth:check_password_with_authmodule( U, Server, P) end, fun(U, P, D, DG) -> ejabberd_auth:check_password_with_authmodule( U, Server, P, D, DG) end), Mechs = lists:map( fun(S) -> {xmlelement, "mechanism", [], [{xmlcdata, S}]} end, cyrsasl:listmech(Server)), SockMod = (StateData#state.sockmod):get_sockmod( StateData#state.socket), Zlib = StateData#state.zlib, CompressFeature = case Zlib andalso ((SockMod == gen_tcp) orelse (SockMod == tls)) of true -> [{xmlelement, "compression", [{"xmlns", ?NS_FEATURE_COMPRESS}], [{xmlelement, "method", [], [{xmlcdata, "zlib"}]}]}]; _ -> [] end, TLS = StateData#state.tls, TLSEnabled = StateData#state.tls_enabled, TLSRequired = StateData#state.tls_required, TLSFeature = case (TLS == true) andalso (TLSEnabled == false) andalso (SockMod == gen_tcp) of true -> case TLSRequired of true -> [{xmlelement, "starttls", [{"xmlns", ?NS_TLS}], [{xmlelement, "required", [], []}]}]; _ -> [{xmlelement, "starttls", [{"xmlns", ?NS_TLS}], []}] end; false -> [] end, send_element(StateData, {xmlelement, "stream:features", [], TLSFeature ++ CompressFeature ++ [{xmlelement, "mechanisms", [{"xmlns", ?NS_SASL}], Mechs}] ++ ejabberd_hooks:run_fold( c2s_stream_features, Server, [], [Server])}), fsm_next_state(wait_for_feature_request, StateData#state{ server = Server, sasl_state = SASLState, lang = Lang}); _ -> case StateData#state.resource of "" -> RosterVersioningFeature = ejabberd_hooks:run_fold( roster_get_versioning_feature, Server, [], [Server]), StreamFeatures = [{xmlelement, "bind", [{"xmlns", ?NS_BIND}], []}, {xmlelement, "session", [{"xmlns", ?NS_SESSION}], []}] ++ RosterVersioningFeature ++ ejabberd_hooks:run_fold( c2s_stream_features, Server, [], [Server]), send_element( StateData, {xmlelement, "stream:features", [], StreamFeatures}), fsm_next_state(wait_for_bind, StateData#state{ server = Server, lang = Lang}); _ -> send_element( StateData, {xmlelement, "stream:features", [], []}), fsm_next_state(wait_for_session, StateData#state{ server = Server, lang = Lang}) end end; _ -> send_header(StateData, Server, "", DefaultLang), if (not StateData#state.tls_enabled) and StateData#state.tls_required -> send_element( StateData, ?POLICY_VIOLATION_ERR( Lang, "Use of STARTTLS required")), send_trailer(StateData), {stop, normal, StateData}; true -> fsm_next_state(wait_for_auth, StateData#state{ server = Server, lang = Lang}) end end; _ -> send_header(StateData, ?MYNAME, "", DefaultLang), send_element(StateData, ?HOST_UNKNOWN_ERR), send_trailer(StateData), {stop, normal, StateData} end; _ -> send_header(StateData, ?MYNAME, "", DefaultLang), send_element(StateData, ?INVALID_NS_ERR), send_trailer(StateData), {stop, normal, StateData} end; wait_for_stream(timeout, StateData) -> {stop, normal, StateData}; wait_for_stream({xmlstreamelement, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), send_trailer(StateData), {stop, normal, StateData}; wait_for_stream({xmlstreamend, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), send_trailer(StateData), {stop, normal, StateData}; wait_for_stream({xmlstreamerror, _}, StateData) -> send_header(StateData, ?MYNAME, "1.0", ""), send_element(StateData, ?INVALID_XML_ERR), send_trailer(StateData), {stop, normal, StateData}; wait_for_stream(closed, StateData) -> {stop, normal, StateData}. wait_for_auth({xmlstreamelement, El}, StateData) -> case is_auth_packet(El) of {auth, _ID, get, {U, _, _, _}} -> {xmlelement, Name, Attrs, _Els} = jlib:make_result_iq_reply(El), case U of "" -> UCdata = []; _ -> UCdata = [{xmlcdata, U}] end, Res = case ejabberd_auth:plain_password_required( StateData#state.server) of false -> {xmlelement, Name, Attrs, [{xmlelement, "query", [{"xmlns", ?NS_AUTH}], [{xmlelement, "username", [], UCdata}, {xmlelement, "password", [], []}, {xmlelement, "digest", [], []}, {xmlelement, "resource", [], []} ]}]}; true -> {xmlelement, Name, Attrs, [{xmlelement, "query", [{"xmlns", ?NS_AUTH}], [{xmlelement, "username", [], UCdata}, {xmlelement, "password", [], []}, {xmlelement, "resource", [], []} ]}]} end, send_element(StateData, Res), fsm_next_state(wait_for_auth, StateData); {auth, _ID, set, {_U, _P, _D, ""}} -> Err = jlib:make_error_reply( El, ?ERR_AUTH_NO_RESOURCE_PROVIDED(StateData#state.lang)), send_element(StateData, Err), fsm_next_state(wait_for_auth, StateData); {auth, _ID, set, {U, P, D, R}} -> JID = jlib:make_jid(U, StateData#state.server, R), case (JID /= error) andalso (acl:match_rule(StateData#state.server, StateData#state.access, JID) == allow) of true -> DGen = fun(PW) -> sha:sha(StateData#state.streamid ++ PW) end, case ejabberd_auth:check_password_with_authmodule( U, StateData#state.server, P, D, DGen) of {true, AuthModule} -> ?INFO_MSG( "(~w) Accepted legacy authentication for ~s by ~p", [StateData#state.socket, jlib:jid_to_string(JID), AuthModule]), SID = {now(), self()}, Conn = get_conn_type(StateData), Info = [{ip, StateData#state.ip}, {conn, Conn}, {auth_module, AuthModule}], Res1 = jlib:make_result_iq_reply(El), Res = setelement(4, Res1, []), send_element(StateData, Res), ejabberd_sm:open_session( SID, U, StateData#state.server, R, Info), change_shaper(StateData, JID), {Fs, Ts} = ejabberd_hooks:run_fold( roster_get_subscription_lists, StateData#state.server, {[], []}, [U, StateData#state.server]), LJID = jlib:jid_tolower( jlib:jid_remove_resource(JID)), Fs1 = [LJID | Fs], Ts1 = [LJID | Ts], PrivList = ejabberd_hooks:run_fold( privacy_get_user_list, StateData#state.server, #userlist{}, [U, StateData#state.server]), NewStateData = StateData#state{ user = U, resource = R, jid = JID, sid = SID, conn = Conn, auth_module = AuthModule, pres_f = ?SETS:from_list(Fs1), pres_t = ?SETS:from_list(Ts1), privacy_list = PrivList}, fsm_next_state_pack(session_established, NewStateData); _ -> ?INFO_MSG( "(~w) Failed legacy authentication for ~s", [StateData#state.socket, jlib:jid_to_string(JID)]), Err = jlib:make_error_reply( El, ?ERR_NOT_AUTHORIZED), send_element(StateData, Err), fsm_next_state(wait_for_auth, StateData) end; _ -> if JID == error -> ?INFO_MSG( "(~w) Forbidden legacy authentication for " "username '~s' with resource '~s'", [StateData#state.socket, U, R]), Err = jlib:make_error_reply(El, ?ERR_JID_MALFORMED), send_element(StateData, Err), fsm_next_state(wait_for_auth, StateData); true -> ?INFO_MSG( "(~w) Forbidden legacy authentication for ~s", [StateData#state.socket, jlib:jid_to_string(JID)]), Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED), send_element(StateData, Err), fsm_next_state(wait_for_auth, StateData) end end; _ -> process_unauthenticated_stanza(StateData, El), fsm_next_state(wait_for_auth, StateData) end; wait_for_auth(timeout, StateData) -> {stop, normal, StateData}; wait_for_auth({xmlstreamend, _Name}, StateData) -> send_trailer(StateData), {stop, normal, StateData}; wait_for_auth({xmlstreamerror, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), send_trailer(StateData), {stop, normal, StateData}; wait_for_auth(closed, StateData) -> {stop, normal, StateData}. wait_for_feature_request({xmlstreamelement, El}, StateData) -> {xmlelement, Name, Attrs, Els} = El, Zlib = StateData#state.zlib, TLS = StateData#state.tls, TLSEnabled = StateData#state.tls_enabled, TLSRequired = StateData#state.tls_required, SockMod = (StateData#state.sockmod):get_sockmod(StateData#state.socket), case {xml:get_attr_s("xmlns", Attrs), Name} of {?NS_SASL, "auth"} when not ((SockMod == gen_tcp) and TLSRequired) -> Mech = xml:get_attr_s("mechanism", Attrs), ClientIn = jlib:decode_base64(xml:get_cdata(Els)), case cyrsasl:server_start(StateData#state.sasl_state, Mech, ClientIn) of {ok, Props} -> (StateData#state.sockmod):reset_stream( StateData#state.socket), send_element(StateData, {xmlelement, "success", [{"xmlns", ?NS_SASL}], []}), U = xml:get_attr_s(username, Props), AuthModule = xml:get_attr_s(auth_module, Props), ?INFO_MSG("(~w) Accepted authentication for ~s by ~p", [StateData#state.socket, U, AuthModule]), fsm_next_state(wait_for_stream, StateData#state{ streamid = new_id(), authenticated = true, auth_module = AuthModule, user = U }); {continue, ServerOut, NewSASLState} -> send_element(StateData, {xmlelement, "challenge", [{"xmlns", ?NS_SASL}], [{xmlcdata, jlib:encode_base64(ServerOut)}]}), fsm_next_state(wait_for_sasl_response, StateData#state{ sasl_state = NewSASLState}); {error, Error, Username} -> ?INFO_MSG( "(~w) Failed authentication for ~s@~s", [StateData#state.socket, Username, StateData#state.server]), send_element(StateData, {xmlelement, "failure", [{"xmlns", ?NS_SASL}], [{xmlelement, Error, [], []}]}), {next_state, wait_for_feature_request, StateData, ?C2S_OPEN_TIMEOUT}; {error, Error} -> send_element(StateData, {xmlelement, "failure", [{"xmlns", ?NS_SASL}], [{xmlelement, Error, [], []}]}), fsm_next_state(wait_for_feature_request, StateData) end; {?NS_TLS, "starttls"} when TLS == true, TLSEnabled == false, SockMod == gen_tcp -> TLSOpts = case ejabberd_config:get_local_option( {domain_certfile, StateData#state.server}) of undefined -> StateData#state.tls_options; CertFile -> [{certfile, CertFile} | lists:keydelete( certfile, 1, StateData#state.tls_options)] end, Socket = StateData#state.socket, TLSSocket = (StateData#state.sockmod):starttls( Socket, TLSOpts, xml:element_to_binary( {xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []})), fsm_next_state(wait_for_stream, StateData#state{socket = TLSSocket, streamid = new_id(), tls_enabled = true }); {?NS_COMPRESS, "compress"} when Zlib == true, ((SockMod == gen_tcp) or (SockMod == tls)) -> case xml:get_subtag(El, "method") of false -> send_element(StateData, {xmlelement, "failure", [{"xmlns", ?NS_COMPRESS}], [{xmlelement, "setup-failed", [], []}]}), fsm_next_state(wait_for_feature_request, StateData); Method -> case xml:get_tag_cdata(Method) of "zlib" -> Socket = StateData#state.socket, ZlibSocket = (StateData#state.sockmod):compress( Socket, xml:element_to_binary( {xmlelement, "compressed", [{"xmlns", ?NS_COMPRESS}], []})), fsm_next_state(wait_for_stream, StateData#state{socket = ZlibSocket, streamid = new_id() }); _ -> send_element(StateData, {xmlelement, "failure", [{"xmlns", ?NS_COMPRESS}], [{xmlelement, "unsupported-method", [], []}]}), fsm_next_state(wait_for_feature_request, StateData) end end; _ -> if (SockMod == gen_tcp) and TLSRequired -> Lang = StateData#state.lang, send_element(StateData, ?POLICY_VIOLATION_ERR( Lang, "Use of STARTTLS required")), send_trailer(StateData), {stop, normal, StateData}; true -> process_unauthenticated_stanza(StateData, El), fsm_next_state(wait_for_feature_request, StateData) end end; wait_for_feature_request(timeout, StateData) -> {stop, normal, StateData}; wait_for_feature_request({xmlstreamend, _Name}, StateData) -> send_trailer(StateData), {stop, normal, StateData}; wait_for_feature_request({xmlstreamerror, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), send_trailer(StateData), {stop, normal, StateData}; wait_for_feature_request(closed, StateData) -> {stop, normal, StateData}. wait_for_sasl_response({xmlstreamelement, El}, StateData) -> {xmlelement, Name, Attrs, Els} = El, case {xml:get_attr_s("xmlns", Attrs), Name} of {?NS_SASL, "response"} -> ClientIn = jlib:decode_base64(xml:get_cdata(Els)), case cyrsasl:server_step(StateData#state.sasl_state, ClientIn) of {ok, Props} -> (StateData#state.sockmod):reset_stream( StateData#state.socket), send_element(StateData, {xmlelement, "success", [{"xmlns", ?NS_SASL}], []}), U = xml:get_attr_s(username, Props), AuthModule = xml:get_attr_s(auth_module, Props), ?INFO_MSG("(~w) Accepted authentication for ~s by ~p", [StateData#state.socket, U, AuthModule]), fsm_next_state(wait_for_stream, StateData#state{ streamid = new_id(), authenticated = true, auth_module = AuthModule, user = U}); {ok, Props, ServerOut} -> (StateData#state.sockmod):reset_stream( StateData#state.socket), send_element(StateData, {xmlelement, "success", [{"xmlns", ?NS_SASL}], [{xmlcdata, jlib:encode_base64(ServerOut)}]}), U = xml:get_attr_s(username, Props), AuthModule = xml:get_attr_s(auth_module, Props), ?INFO_MSG("(~w) Accepted authentication for ~s by ~p", [StateData#state.socket, U, AuthModule]), fsm_next_state(wait_for_stream, StateData#state{ streamid = new_id(), authenticated = true, auth_module = AuthModule, user = U}); {continue, ServerOut, NewSASLState} -> send_element(StateData, {xmlelement, "challenge", [{"xmlns", ?NS_SASL}], [{xmlcdata, jlib:encode_base64(ServerOut)}]}), fsm_next_state(wait_for_sasl_response, StateData#state{sasl_state = NewSASLState}); {error, Error, Username} -> ?INFO_MSG( "(~w) Failed authentication for ~s@~s", [StateData#state.socket, Username, StateData#state.server]), send_element(StateData, {xmlelement, "failure", [{"xmlns", ?NS_SASL}], [{xmlelement, Error, [], []}]}), fsm_next_state(wait_for_feature_request, StateData); {error, Error} -> send_element(StateData, {xmlelement, "failure", [{"xmlns", ?NS_SASL}], [{xmlelement, Error, [], []}]}), fsm_next_state(wait_for_feature_request, StateData) end; _ -> process_unauthenticated_stanza(StateData, El), fsm_next_state(wait_for_feature_request, StateData) end; wait_for_sasl_response(timeout, StateData) -> {stop, normal, StateData}; wait_for_sasl_response({xmlstreamend, _Name}, StateData) -> send_trailer(StateData), {stop, normal, StateData}; wait_for_sasl_response({xmlstreamerror, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), send_trailer(StateData), {stop, normal, StateData}; wait_for_sasl_response(closed, StateData) -> {stop, normal, StateData}. resource_conflict_action(U, S, R) -> OptionRaw = case ejabberd_sm:is_existing_resource(U, S, R) of true -> ejabberd_config:get_local_option({resource_conflict,S}); false -> acceptnew end, Option = case OptionRaw of setresource -> setresource; closeold -> acceptnew; %% ejabberd_sm will close old session closenew -> closenew; acceptnew -> acceptnew; _ -> acceptnew %% default ejabberd behavior end, case Option of acceptnew -> {accept_resource, R}; closenew -> closenew; setresource -> Rnew = lists:concat([randoms:get_string() | tuple_to_list(now())]), {accept_resource, Rnew} end. wait_for_bind({xmlstreamelement, El}, StateData) -> case jlib:iq_query_info(El) of #iq{type = set, xmlns = ?NS_BIND, sub_el = SubEl} = IQ -> U = StateData#state.user, R1 = xml:get_path_s(SubEl, [{elem, "resource"}, cdata]), R = case jlib:resourceprep(R1) of error -> error; "" -> lists:concat( [randoms:get_string() | tuple_to_list(now())]); Resource -> Resource end, case R of error -> Err = jlib:make_error_reply(El, ?ERR_BAD_REQUEST), send_element(StateData, Err), fsm_next_state(wait_for_bind, StateData); _ -> %%Server = StateData#state.server, %%RosterVersioningFeature = %% ejabberd_hooks:run_fold( %% roster_get_versioning_feature, Server, [], [Server]), %%StreamFeatures = [{xmlelement, "session", %% [{"xmlns", ?NS_SESSION}], []} | %% RosterVersioningFeature], %%send_element(StateData, {xmlelement, "stream:features", %% [], StreamFeatures}), case resource_conflict_action(U, StateData#state.server, R) of closenew -> Err = jlib:make_error_reply(El, ?STANZA_ERROR("409", "modify", "conflict")), send_element(StateData, Err), fsm_next_state(wait_for_bind, StateData); {accept_resource, R2} -> JID = jlib:make_jid(U, StateData#state.server, R2), Res = IQ#iq{type = result, sub_el = [{xmlelement, "bind", [{"xmlns", ?NS_BIND}], [{xmlelement, "jid", [], [{xmlcdata, jlib:jid_to_string(JID)}]}]}]}, send_element(StateData, jlib:iq_to_xml(Res)), fsm_next_state(wait_for_session, StateData#state{resource = R2, jid = JID}) end end; _ -> fsm_next_state(wait_for_bind, StateData) end; wait_for_bind(timeout, StateData) -> {stop, normal, StateData}; wait_for_bind({xmlstreamend, _Name}, StateData) -> send_trailer(StateData), {stop, normal, StateData}; wait_for_bind({xmlstreamerror, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), send_trailer(StateData), {stop, normal, StateData}; wait_for_bind(closed, StateData) -> {stop, normal, StateData}. wait_for_session({xmlstreamelement, El}, StateData) -> case jlib:iq_query_info(El) of #iq{type = set, xmlns = ?NS_SESSION} -> U = StateData#state.user, R = StateData#state.resource, JID = StateData#state.jid, case acl:match_rule(StateData#state.server, StateData#state.access, JID) of allow -> ?INFO_MSG("(~w) Opened session for ~s", [StateData#state.socket, jlib:jid_to_string(JID)]), Res = jlib:make_result_iq_reply(El), send_element(StateData, Res), change_shaper(StateData, JID), {Fs, Ts} = ejabberd_hooks:run_fold( roster_get_subscription_lists, StateData#state.server, {[], []}, [U, StateData#state.server]), LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)), Fs1 = [LJID | Fs], Ts1 = [LJID | Ts], PrivList = ejabberd_hooks:run_fold( privacy_get_user_list, StateData#state.server, #userlist{}, [U, StateData#state.server]), SID = {now(), self()}, Conn = get_conn_type(StateData), Info = [{ip, StateData#state.ip}, {conn, Conn}, {auth_module, StateData#state.auth_module}], ejabberd_sm:open_session( SID, U, StateData#state.server, R, Info), NewStateData = StateData#state{ sid = SID, conn = Conn, pres_f = ?SETS:from_list(Fs1), pres_t = ?SETS:from_list(Ts1), privacy_list = PrivList}, fsm_next_state_pack(session_established, NewStateData); _ -> ejabberd_hooks:run(forbidden_session_hook, StateData#state.server, [JID]), ?INFO_MSG("(~w) Forbidden session for ~s", [StateData#state.socket, jlib:jid_to_string(JID)]), Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED), send_element(StateData, Err), fsm_next_state(wait_for_session, StateData) end; _ -> fsm_next_state(wait_for_session, StateData) end; wait_for_session(timeout, StateData) -> {stop, normal, StateData}; wait_for_session({xmlstreamend, _Name}, StateData) -> send_trailer(StateData), {stop, normal, StateData}; wait_for_session({xmlstreamerror, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), send_trailer(StateData), {stop, normal, StateData}; wait_for_session(closed, StateData) -> {stop, normal, StateData}. session_established({xmlstreamelement, El}, StateData) -> FromJID = StateData#state.jid, % Check 'from' attribute in stanza RFC 3920 Section 9.1.2 case check_from(El, FromJID) of 'invalid-from' -> send_element(StateData, ?INVALID_FROM), send_trailer(StateData), {stop, normal, StateData}; _NewEl -> session_established2(El, StateData) end; %% We hibernate the process to reduce memory consumption after a %% configurable activity timeout session_established(timeout, StateData) -> %% TODO: Options must be stored in state: Options = [], proc_lib:hibernate(?GEN_FSM, enter_loop, [?MODULE, Options, session_established, StateData]), fsm_next_state(session_established, StateData); session_established({xmlstreamend, _Name}, StateData) -> send_trailer(StateData), {stop, normal, StateData}; session_established({xmlstreamerror, "XML stanza is too big" = E}, StateData) -> send_element(StateData, ?POLICY_VIOLATION_ERR(StateData#state.lang, E)), send_trailer(StateData), {stop, normal, StateData}; session_established({xmlstreamerror, _}, StateData) -> send_element(StateData, ?INVALID_XML_ERR), send_trailer(StateData), {stop, normal, StateData}; session_established(closed, StateData) -> {stop, normal, StateData}. %% Process packets sent by user (coming from user on c2s XMPP %% connection) session_established2(El, StateData) -> {xmlelement, Name, Attrs, _Els} = El, User = StateData#state.user, Server = StateData#state.server, FromJID = StateData#state.jid, To = xml:get_attr_s("to", Attrs), ToJID = case To of "" -> jlib:make_jid(User, Server, ""); _ -> jlib:string_to_jid(To) end, NewEl1 = jlib:remove_attr("xmlns", El), NewEl = case xml:get_attr_s("xml:lang", Attrs) of "" -> case StateData#state.lang of "" -> NewEl1; Lang -> xml:replace_tag_attr("xml:lang", Lang, NewEl1) end; _ -> NewEl1 end, NewState = case ToJID of error -> case xml:get_attr_s("type", Attrs) of "error" -> StateData; "result" -> StateData; _ -> Err = jlib:make_error_reply(NewEl, ?ERR_JID_MALFORMED), send_element(StateData, Err), StateData end; _ -> case Name of "presence" -> PresenceEl = ejabberd_hooks:run_fold( c2s_update_presence, Server, NewEl, [User, Server]), ejabberd_hooks:run( user_send_packet, Server, [FromJID, ToJID, PresenceEl]), case ToJID of #jid{user = User, server = Server, resource = ""} -> ?DEBUG("presence_update(~p,~n\t~p,~n\t~p)", [FromJID, PresenceEl, StateData]), presence_update(FromJID, PresenceEl, StateData); _ -> presence_track(FromJID, ToJID, PresenceEl, StateData) end; "iq" -> case jlib:iq_query_info(NewEl) of #iq{xmlns = Xmlns} = IQ when Xmlns == ?NS_PRIVACY; Xmlns == ?NS_BLOCKING -> process_privacy_iq( FromJID, ToJID, IQ, StateData); _ -> ejabberd_hooks:run( user_send_packet, Server, [FromJID, ToJID, NewEl]), check_privacy_route(FromJID, StateData, FromJID, ToJID, NewEl), StateData end; "message" -> ejabberd_hooks:run(user_send_packet, Server, [FromJID, ToJID, NewEl]), check_privacy_route(FromJID, StateData, FromJID, ToJID, NewEl), StateData; _ -> StateData end end, ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, El}]), fsm_next_state(session_established, NewState). %%---------------------------------------------------------------------- %% Func: StateName/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- %state_name(Event, From, StateData) -> % Reply = ok, % {reply, Reply, state_name, StateData}. %%---------------------------------------------------------------------- %% Func: handle_event/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_event(_Event, StateName, StateData) -> fsm_next_state(StateName, StateData). %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- handle_sync_event({get_presence}, _From, StateName, StateData) -> User = StateData#state.user, PresLast = StateData#state.pres_last, Show = get_showtag(PresLast), Status = get_statustag(PresLast), Resource = StateData#state.resource, Reply = {User, Resource, Show, Status}, fsm_reply(Reply, StateName, StateData); handle_sync_event(get_subscribed, _From, StateName, StateData) -> Subscribed = ?SETS:to_list(StateData#state.pres_f), {reply, Subscribed, StateName, StateData}; handle_sync_event(_Event, _From, StateName, StateData) -> Reply = ok, fsm_reply(Reply, StateName, StateData). code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_info/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_info({send_text, Text}, StateName, StateData) -> send_text(StateData, Text), ejabberd_hooks:run(c2s_loop_debug, [Text]), fsm_next_state(StateName, StateData); handle_info(replaced, _StateName, StateData) -> Lang = StateData#state.lang, send_element(StateData, ?SERRT_CONFLICT(Lang, "Replaced by new connection")), send_trailer(StateData), {stop, normal, StateData#state{authenticated = replaced}}; %% Process Packets that are to be send to the user handle_info({route, From, To, Packet}, StateName, StateData) -> {xmlelement, Name, Attrs, Els} = Packet, {Pass, NewAttrs, NewState} = case Name of "presence" -> State = ejabberd_hooks:run_fold( c2s_presence_in, StateData#state.server, StateData, [{From, To, Packet}]), case xml:get_attr_s("type", Attrs) of "probe" -> LFrom = jlib:jid_tolower(From), LBFrom = jlib:jid_remove_resource(LFrom), NewStateData = case ?SETS:is_element( LFrom, State#state.pres_a) orelse ?SETS:is_element( LBFrom, State#state.pres_a) of true -> State; false -> case ?SETS:is_element( LFrom, State#state.pres_f) of true -> A = ?SETS:add_element( LFrom, State#state.pres_a), State#state{pres_a = A}; false -> case ?SETS:is_element( LBFrom, State#state.pres_f) of true -> A = ?SETS:add_element( LBFrom, State#state.pres_a), State#state{pres_a = A}; false -> State end end end, process_presence_probe(From, To, NewStateData), {false, Attrs, NewStateData}; "error" -> NewA = remove_element(jlib:jid_tolower(From), State#state.pres_a), {true, Attrs, State#state{pres_a = NewA}}; "invisible" -> Attrs1 = lists:keydelete("type", 1, Attrs), {true, [{"type", "unavailable"} | Attrs1], State}; "subscribe" -> SRes = is_privacy_allow(State, From, To, Packet, in), {SRes, Attrs, State}; "subscribed" -> SRes = is_privacy_allow(State, From, To, Packet, in), {SRes, Attrs, State}; "unsubscribe" -> SRes = is_privacy_allow(State, From, To, Packet, in), {SRes, Attrs, State}; "unsubscribed" -> SRes = is_privacy_allow(State, From, To, Packet, in), {SRes, Attrs, State}; _ -> case privacy_check_packet(State, From, To, Packet, in) of allow -> LFrom = jlib:jid_tolower(From), LBFrom = jlib:jid_remove_resource(LFrom), case ?SETS:is_element( LFrom, State#state.pres_a) orelse ?SETS:is_element( LBFrom, State#state.pres_a) of true -> {true, Attrs, State}; false -> case ?SETS:is_element( LFrom, State#state.pres_f) of true -> A = ?SETS:add_element( LFrom, State#state.pres_a), {true, Attrs, State#state{pres_a = A}}; false -> case ?SETS:is_element( LBFrom, State#state.pres_f) of true -> A = ?SETS:add_element( LBFrom, State#state.pres_a), {true, Attrs, State#state{pres_a = A}}; false -> {true, Attrs, State} end end end; deny -> {false, Attrs, State} end end; "broadcast" -> ?DEBUG("broadcast~n~p~n", [Els]), case Els of [{item, IJID, ISubscription}] -> {false, Attrs, roster_change(IJID, ISubscription, StateData)}; [{exit, Reason}] -> {exit, Attrs, Reason}; [{privacy_list, PrivList, PrivListName}] -> case ejabberd_hooks:run_fold( privacy_updated_list, StateData#state.server, false, [StateData#state.privacy_list, PrivList]) of false -> {false, Attrs, StateData}; NewPL -> PrivPushIQ = #iq{type = set, xmlns = ?NS_PRIVACY, id = "push" ++ randoms:get_string(), sub_el = [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], [{xmlelement, "list", [{"name", PrivListName}], []}]}]}, PrivPushEl = jlib:replace_from_to( jlib:jid_remove_resource( StateData#state.jid), StateData#state.jid, jlib:iq_to_xml(PrivPushIQ)), send_element(StateData, PrivPushEl), {false, Attrs, StateData#state{privacy_list = NewPL}} end; [{blocking, What}] -> route_blocking(What, StateData), {false, Attrs, StateData}; _ -> {false, Attrs, StateData} end; "iq" -> IQ = jlib:iq_query_info(Packet), case IQ of #iq{xmlns = ?NS_LAST} -> LFrom = jlib:jid_tolower(From), LBFrom = jlib:jid_remove_resource(LFrom), HasFromSub = (?SETS:is_element(LFrom, StateData#state.pres_f) orelse ?SETS:is_element(LBFrom, StateData#state.pres_f)) andalso is_privacy_allow(StateData, To, From, {xmlelement, "presence", [], []}, out), case HasFromSub of true -> case privacy_check_packet(StateData, From, To, Packet, in) of allow -> {true, Attrs, StateData}; deny -> {false, Attrs, StateData} end; _ -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err), {false, Attrs, StateData} end; IQ when (is_record(IQ, iq)) or (IQ == reply) -> case privacy_check_packet(StateData, From, To, Packet, in) of allow -> {true, Attrs, StateData}; deny when is_record(IQ, iq) -> Err = jlib:make_error_reply( Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err), {false, Attrs, StateData}; deny when IQ == reply -> {false, Attrs, StateData} end; IQ when (IQ == invalid) or (IQ == not_iq) -> {false, Attrs, StateData} end; "message" -> case privacy_check_packet(StateData, From, To, Packet, in) of allow -> {true, Attrs, StateData}; deny -> {false, Attrs, StateData} end; _ -> {true, Attrs, StateData} end, if Pass == exit -> %% When Pass==exit, NewState contains a string instead of a #state{} Lang = StateData#state.lang, send_element(StateData, ?SERRT_CONFLICT(Lang, NewState)), send_trailer(StateData), {stop, normal, StateData}; Pass -> Attrs2 = jlib:replace_from_to_attrs(jlib:jid_to_string(From), jlib:jid_to_string(To), NewAttrs), FixedPacket = {xmlelement, Name, Attrs2, Els}, send_element(StateData, FixedPacket), ejabberd_hooks:run(user_receive_packet, StateData#state.server, [StateData#state.jid, From, To, FixedPacket]), ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]), fsm_next_state(StateName, NewState); true -> ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]), fsm_next_state(StateName, NewState) end; handle_info({'DOWN', Monitor, _Type, _Object, _Info}, _StateName, StateData) when Monitor == StateData#state.socket_monitor -> {stop, normal, StateData}; handle_info(system_shutdown, StateName, StateData) -> case StateName of wait_for_stream -> send_header(StateData, ?MYNAME, "1.0", "en"), send_element(StateData, ?SERR_SYSTEM_SHUTDOWN), send_trailer(StateData), ok; _ -> send_element(StateData, ?SERR_SYSTEM_SHUTDOWN), send_trailer(StateData), ok end, {stop, normal, StateData}; handle_info({force_update_presence, LUser}, StateName, #state{user = LUser, server = LServer} = StateData) -> NewStateData = case StateData#state.pres_last of {xmlelement, "presence", _Attrs, _Els} -> PresenceEl = ejabberd_hooks:run_fold( c2s_update_presence, LServer, StateData#state.pres_last, [LUser, LServer]), StateData2 = StateData#state{pres_last = PresenceEl}, presence_update(StateData2#state.jid, PresenceEl, StateData2), StateData2; _ -> StateData end, {next_state, StateName, NewStateData}; handle_info({broadcast, Type, From, Packet}, StateName, StateData) -> Recipients = ejabberd_hooks:run_fold( c2s_broadcast_recipients, StateData#state.server, [], [StateData, Type, From, Packet]), lists:foreach( fun(USR) -> ejabberd_router:route( From, jlib:make_jid(USR), Packet) end, lists:usort(Recipients)), fsm_next_state(StateName, StateData); handle_info(Info, StateName, StateData) -> ?ERROR_MSG("Unexpected info: ~p", [Info]), fsm_next_state(StateName, StateData). %%---------------------------------------------------------------------- %% Func: print_state/1 %% Purpose: Prepare the state to be printed on error log %% Returns: State to print %%---------------------------------------------------------------------- print_state(State = #state{pres_t = T, pres_f = F, pres_a = A, pres_i = I}) -> State#state{pres_t = {pres_t, ?SETS:size(T)}, pres_f = {pres_f, ?SETS:size(F)}, pres_a = {pres_a, ?SETS:size(A)}, pres_i = {pres_i, ?SETS:size(I)} }. %%---------------------------------------------------------------------- %% Func: terminate/3 %% Purpose: Shutdown the fsm %% Returns: any %%---------------------------------------------------------------------- terminate(_Reason, StateName, StateData) -> case StateName of session_established -> case StateData#state.authenticated of replaced -> ?INFO_MSG("(~w) Replaced session for ~s", [StateData#state.socket, jlib:jid_to_string(StateData#state.jid)]), From = StateData#state.jid, Packet = {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "status", [], [{xmlcdata, "Replaced by new connection"}]}]}, ejabberd_sm:close_session_unset_presence( StateData#state.sid, StateData#state.user, StateData#state.server, StateData#state.resource, "Replaced by new connection"), presence_broadcast( StateData, From, StateData#state.pres_a, Packet), presence_broadcast( StateData, From, StateData#state.pres_i, Packet); _ -> ?INFO_MSG("(~w) Close session for ~s", [StateData#state.socket, jlib:jid_to_string(StateData#state.jid)]), EmptySet = ?SETS:new(), case StateData of #state{pres_last = undefined, pres_a = EmptySet, pres_i = EmptySet, pres_invis = false} -> ejabberd_sm:close_session(StateData#state.sid, StateData#state.user, StateData#state.server, StateData#state.resource); _ -> From = StateData#state.jid, Packet = {xmlelement, "presence", [{"type", "unavailable"}], []}, ejabberd_sm:close_session_unset_presence( StateData#state.sid, StateData#state.user, StateData#state.server, StateData#state.resource, ""), presence_broadcast( StateData, From, StateData#state.pres_a, Packet), presence_broadcast( StateData, From, StateData#state.pres_i, Packet) end end, bounce_messages(); _ -> ok end, (StateData#state.sockmod):close(StateData#state.socket), ok. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- change_shaper(StateData, JID) -> Shaper = acl:match_rule(StateData#state.server, StateData#state.shaper, JID), (StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper). send_text(StateData, Text) when StateData#state.xml_socket -> ?DEBUG("Send Text on stream = ~p", [lists:flatten(Text)]), (StateData#state.sockmod):send_xml(StateData#state.socket, {xmlstreamraw, Text}); send_text(StateData, Text) -> ?DEBUG("Send XML on stream = ~p", [Text]), (StateData#state.sockmod):send(StateData#state.socket, Text). send_element(StateData, El) when StateData#state.xml_socket -> (StateData#state.sockmod):send_xml(StateData#state.socket, {xmlstreamelement, El}); send_element(StateData, El) -> send_text(StateData, xml:element_to_binary(El)). send_header(StateData, Server, Version, Lang) when StateData#state.xml_socket -> VersionAttr = case Version of "" -> []; _ -> [{"version", Version}] end, LangAttr = case Lang of "" -> []; _ -> [{"xml:lang", Lang}] end, Header = {xmlstreamstart, "stream:stream", VersionAttr ++ LangAttr ++ [{"xmlns", "jabber:client"}, {"xmlns:stream", "http://etherx.jabber.org/streams"}, {"id", StateData#state.streamid}, {"from", Server}]}, (StateData#state.sockmod):send_xml( StateData#state.socket, Header); send_header(StateData, Server, Version, Lang) -> VersionStr = case Version of "" -> ""; _ -> [" version='", Version, "'"] end, LangStr = case Lang of "" -> ""; _ -> [" xml:lang='", Lang, "'"] end, Header = io_lib:format(?STREAM_HEADER, [StateData#state.streamid, Server, VersionStr, LangStr]), send_text(StateData, Header). send_trailer(StateData) when StateData#state.xml_socket -> (StateData#state.sockmod):send_xml( StateData#state.socket, {xmlstreamend, "stream:stream"}); send_trailer(StateData) -> send_text(StateData, ?STREAM_TRAILER). new_id() -> randoms:get_string(). is_auth_packet(El) -> case jlib:iq_query_info(El) of #iq{id = ID, type = Type, xmlns = ?NS_AUTH, sub_el = SubEl} -> {xmlelement, _, _, Els} = SubEl, {auth, ID, Type, get_auth_tags(Els, "", "", "", "")}; _ -> false end. get_auth_tags([{xmlelement, Name, _Attrs, Els}| L], U, P, D, R) -> CData = xml:get_cdata(Els), case Name of "username" -> get_auth_tags(L, CData, P, D, R); "password" -> get_auth_tags(L, U, CData, D, R); "digest" -> get_auth_tags(L, U, P, CData, R); "resource" -> get_auth_tags(L, U, P, D, CData); _ -> get_auth_tags(L, U, P, D, R) end; get_auth_tags([_ | L], U, P, D, R) -> get_auth_tags(L, U, P, D, R); get_auth_tags([], U, P, D, R) -> {U, P, D, R}. %% Copied from ejabberd_socket.erl -record(socket_state, {sockmod, socket, receiver}). get_conn_type(StateData) -> case (StateData#state.sockmod):get_sockmod(StateData#state.socket) of gen_tcp -> c2s; tls -> c2s_tls; ejabberd_zlib -> case ejabberd_zlib:get_sockmod((StateData#state.socket)#socket_state.socket) of gen_tcp -> c2s_compressed; tls -> c2s_compressed_tls end; ejabberd_http_poll -> http_poll; ejabberd_http_bind -> http_bind; _ -> unknown end. process_presence_probe(From, To, StateData) -> LFrom = jlib:jid_tolower(From), LBFrom = setelement(3, LFrom, ""), case StateData#state.pres_last of undefined -> ok; _ -> Cond1 = (not StateData#state.pres_invis) andalso (?SETS:is_element(LFrom, StateData#state.pres_f) orelse ((LFrom /= LBFrom) andalso ?SETS:is_element(LBFrom, StateData#state.pres_f))) andalso (not (?SETS:is_element(LFrom, StateData#state.pres_i) orelse ((LFrom /= LBFrom) andalso ?SETS:is_element(LBFrom, StateData#state.pres_i)))), Cond2 = StateData#state.pres_invis andalso ?SETS:is_element(LFrom, StateData#state.pres_f) andalso ?SETS:is_element(LFrom, StateData#state.pres_a), if Cond1 -> Timestamp = StateData#state.pres_timestamp, Packet = xml:append_subtags( StateData#state.pres_last, %% To is the one sending the presence (the target of the probe) [jlib:timestamp_to_xml(Timestamp, utc, To, ""), %% TODO: Delete the next line once XEP-0091 is Obsolete jlib:timestamp_to_xml(Timestamp)]), case privacy_check_packet(StateData, To, From, Packet, out) of deny -> ok; allow -> Pid=element(2, StateData#state.sid), ejabberd_hooks:run(presence_probe_hook, StateData#state.server, [From, To, Pid]), %% Don't route a presence probe to oneself case From == To of false -> ejabberd_router:route(To, From, Packet); true -> ok end end; Cond2 -> ejabberd_router:route(To, From, {xmlelement, "presence", [], []}); true -> ok end end. %% User updates his presence (non-directed presence packet) presence_update(From, Packet, StateData) -> {xmlelement, _Name, Attrs, _Els} = Packet, case xml:get_attr_s("type", Attrs) of "unavailable" -> Status = case xml:get_subtag(Packet, "status") of false -> ""; StatusTag -> xml:get_tag_cdata(StatusTag) end, Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn}, {auth_module, StateData#state.auth_module}], ejabberd_sm:unset_presence(StateData#state.sid, StateData#state.user, StateData#state.server, StateData#state.resource, Status, Info), presence_broadcast(StateData, From, StateData#state.pres_a, Packet), presence_broadcast(StateData, From, StateData#state.pres_i, Packet), StateData#state{pres_last = undefined, pres_timestamp = undefined, pres_a = ?SETS:new(), pres_i = ?SETS:new(), pres_invis = false}; "invisible" -> NewPriority = get_priority_from_presence(Packet), update_priority(NewPriority, Packet, StateData), NewState = if not StateData#state.pres_invis -> presence_broadcast(StateData, From, StateData#state.pres_a, Packet), presence_broadcast(StateData, From, StateData#state.pres_i, Packet), S1 = StateData#state{pres_last = undefined, pres_timestamp = undefined, pres_a = ?SETS:new(), pres_i = ?SETS:new(), pres_invis = true}, presence_broadcast_first(From, S1, Packet); true -> StateData end, NewState; "error" -> StateData; "probe" -> StateData; "subscribe" -> StateData; "subscribed" -> StateData; "unsubscribe" -> StateData; "unsubscribed" -> StateData; _ -> OldPriority = case StateData#state.pres_last of undefined -> 0; OldPresence -> get_priority_from_presence(OldPresence) end, NewPriority = get_priority_from_presence(Packet), Timestamp = calendar:now_to_universal_time(now()), update_priority(NewPriority, Packet, StateData), FromUnavail = (StateData#state.pres_last == undefined) or StateData#state.pres_invis, ?DEBUG("from unavail = ~p~n", [FromUnavail]), NewStateData = StateData#state{pres_last = Packet, pres_invis = false, pres_timestamp = Timestamp}, NewState = if FromUnavail -> ejabberd_hooks:run(user_available_hook, NewStateData#state.server, [NewStateData#state.jid]), if NewPriority >= 0 -> resend_offline_messages(NewStateData), resend_subscription_requests(NewStateData); true -> ok end, presence_broadcast_first(From, NewStateData, Packet); true -> presence_broadcast_to_trusted(NewStateData, From, NewStateData#state.pres_f, NewStateData#state.pres_a, Packet), if OldPriority < 0, NewPriority >= 0 -> resend_offline_messages(NewStateData); true -> ok end, NewStateData end, NewState end. %% User sends a directed presence packet presence_track(From, To, Packet, StateData) -> {xmlelement, _Name, Attrs, _Els} = Packet, LTo = jlib:jid_tolower(To), User = StateData#state.user, Server = StateData#state.server, case xml:get_attr_s("type", Attrs) of "unavailable" -> check_privacy_route(From, StateData, From, To, Packet), I = remove_element(LTo, StateData#state.pres_i), A = remove_element(LTo, StateData#state.pres_a), StateData#state{pres_i = I, pres_a = A}; "invisible" -> check_privacy_route(From, StateData, From, To, Packet), I = ?SETS:add_element(LTo, StateData#state.pres_i), A = remove_element(LTo, StateData#state.pres_a), StateData#state{pres_i = I, pres_a = A}; "subscribe" -> ejabberd_hooks:run(roster_out_subscription, Server, [User, Server, To, subscribe]), check_privacy_route(From, StateData, jlib:jid_remove_resource(From), To, Packet), StateData; "subscribed" -> ejabberd_hooks:run(roster_out_subscription, Server, [User, Server, To, subscribed]), check_privacy_route(From, StateData, jlib:jid_remove_resource(From), To, Packet), StateData; "unsubscribe" -> ejabberd_hooks:run(roster_out_subscription, Server, [User, Server, To, unsubscribe]), check_privacy_route(From, StateData, jlib:jid_remove_resource(From), To, Packet), StateData; "unsubscribed" -> ejabberd_hooks:run(roster_out_subscription, Server, [User, Server, To, unsubscribed]), check_privacy_route(From, StateData, jlib:jid_remove_resource(From), To, Packet), StateData; "error" -> check_privacy_route(From, StateData, From, To, Packet), StateData; "probe" -> check_privacy_route(From, StateData, From, To, Packet), StateData; _ -> check_privacy_route(From, StateData, From, To, Packet), I = remove_element(LTo, StateData#state.pres_i), A = ?SETS:add_element(LTo, StateData#state.pres_a), StateData#state{pres_i = I, pres_a = A} end. check_privacy_route(From, StateData, FromRoute, To, Packet) -> case privacy_check_packet(StateData, From, To, Packet, out) of deny -> Lang = StateData#state.lang, ErrText = "Your active privacy list has denied the routing of this stanza.", Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)), ejabberd_router:route(To, From, Err), ok; allow -> ejabberd_router:route(FromRoute, To, Packet) end. privacy_check_packet(StateData, From, To, Packet, Dir) -> ejabberd_hooks:run_fold( privacy_check_packet, StateData#state.server, allow, [StateData#state.user, StateData#state.server, StateData#state.privacy_list, {From, To, Packet}, Dir]). %% Check if privacy rules allow this delivery is_privacy_allow(StateData, From, To, Packet, Dir) -> allow == privacy_check_packet(StateData, From, To, Packet, Dir). presence_broadcast(StateData, From, JIDSet, Packet) -> lists:foreach(fun(JID) -> FJID = jlib:make_jid(JID), case privacy_check_packet(StateData, From, FJID, Packet, out) of deny -> ok; allow -> ejabberd_router:route(From, FJID, Packet) end end, ?SETS:to_list(JIDSet)). presence_broadcast_to_trusted(StateData, From, T, A, Packet) -> lists:foreach( fun(JID) -> case ?SETS:is_element(JID, T) of true -> FJID = jlib:make_jid(JID), case privacy_check_packet(StateData, From, FJID, Packet, out) of deny -> ok; allow -> ejabberd_router:route(From, FJID, Packet) end; _ -> ok end end, ?SETS:to_list(A)). presence_broadcast_first(From, StateData, Packet) -> ?SETS:fold(fun(JID, X) -> ejabberd_router:route( From, jlib:make_jid(JID), {xmlelement, "presence", [{"type", "probe"}], []}), X end, [], StateData#state.pres_t), if StateData#state.pres_invis -> StateData; true -> As = ?SETS:fold( fun(JID, A) -> FJID = jlib:make_jid(JID), case privacy_check_packet(StateData, From, FJID, Packet, out) of deny -> ok; allow -> ejabberd_router:route(From, FJID, Packet) end, ?SETS:add_element(JID, A) end, StateData#state.pres_a, StateData#state.pres_f), StateData#state{pres_a = As} end. remove_element(E, Set) -> case ?SETS:is_element(E, Set) of true -> ?SETS:del_element(E, Set); _ -> Set end. roster_change(IJID, ISubscription, StateData) -> LIJID = jlib:jid_tolower(IJID), IsFrom = (ISubscription == both) or (ISubscription == from), IsTo = (ISubscription == both) or (ISubscription == to), OldIsFrom = ?SETS:is_element(LIJID, StateData#state.pres_f), FSet = if IsFrom -> ?SETS:add_element(LIJID, StateData#state.pres_f); true -> remove_element(LIJID, StateData#state.pres_f) end, TSet = if IsTo -> ?SETS:add_element(LIJID, StateData#state.pres_t); true -> remove_element(LIJID, StateData#state.pres_t) end, case StateData#state.pres_last of undefined -> StateData#state{pres_f = FSet, pres_t = TSet}; P -> ?DEBUG("roster changed for ~p~n", [StateData#state.user]), From = StateData#state.jid, To = jlib:make_jid(IJID), Cond1 = (not StateData#state.pres_invis) and IsFrom and (not OldIsFrom), Cond2 = (not IsFrom) and OldIsFrom and (?SETS:is_element(LIJID, StateData#state.pres_a) or ?SETS:is_element(LIJID, StateData#state.pres_i)), if Cond1 -> ?DEBUG("C1: ~p~n", [LIJID]), case privacy_check_packet(StateData, From, To, P, out) of deny -> ok; allow -> ejabberd_router:route(From, To, P) end, A = ?SETS:add_element(LIJID, StateData#state.pres_a), StateData#state{pres_a = A, pres_f = FSet, pres_t = TSet}; Cond2 -> ?DEBUG("C2: ~p~n", [LIJID]), PU = {xmlelement, "presence", [{"type", "unavailable"}], []}, case privacy_check_packet(StateData, From, To, PU, out) of deny -> ok; allow -> ejabberd_router:route(From, To, PU) end, I = remove_element(LIJID, StateData#state.pres_i), A = remove_element(LIJID, StateData#state.pres_a), StateData#state{pres_i = I, pres_a = A, pres_f = FSet, pres_t = TSet}; true -> StateData#state{pres_f = FSet, pres_t = TSet} end end. update_priority(Priority, Packet, StateData) -> Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn}, {auth_module, StateData#state.auth_module}], ejabberd_sm:set_presence(StateData#state.sid, StateData#state.user, StateData#state.server, StateData#state.resource, Priority, Packet, Info). get_priority_from_presence(PresencePacket) -> case xml:get_subtag(PresencePacket, "priority") of false -> 0; SubEl -> case catch list_to_integer(xml:get_tag_cdata(SubEl)) of P when is_integer(P) -> P; _ -> 0 end end. process_privacy_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ, StateData) -> {Res, NewStateData} = case Type of get -> R = ejabberd_hooks:run_fold( privacy_iq_get, StateData#state.server, {error, ?ERR_FEATURE_NOT_IMPLEMENTED}, [From, To, IQ, StateData#state.privacy_list]), {R, StateData}; set -> case ejabberd_hooks:run_fold( privacy_iq_set, StateData#state.server, {error, ?ERR_FEATURE_NOT_IMPLEMENTED}, [From, To, IQ]) of {result, R, NewPrivList} -> {{result, R}, StateData#state{privacy_list = NewPrivList}}; R -> {R, StateData} end end, IQRes = case Res of {result, Result} -> IQ#iq{type = result, sub_el = Result}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end, ejabberd_router:route( To, From, jlib:iq_to_xml(IQRes)), NewStateData. resend_offline_messages(StateData) -> case ejabberd_hooks:run_fold( resend_offline_messages_hook, StateData#state.server, [], [StateData#state.user, StateData#state.server]) of Rs when is_list(Rs) -> lists:foreach( fun({route, From, To, {xmlelement, _Name, _Attrs, _Els} = Packet}) -> Pass = case privacy_check_packet(StateData, From, To, Packet, in) of allow -> true; deny -> false end, if Pass -> %% Attrs2 = jlib:replace_from_to_attrs( %% jlib:jid_to_string(From), %% jlib:jid_to_string(To), %% Attrs), %% FixedPacket = {xmlelement, Name, Attrs2, Els}, %% Use route instead of send_element to go through standard workflow ejabberd_router:route(From, To, Packet); %% send_element(StateData, FixedPacket), %% ejabberd_hooks:run(user_receive_packet, %% StateData#state.server, %% [StateData#state.jid, %% From, To, FixedPacket]); true -> ok end end, Rs) end. resend_subscription_requests(#state{user = User, server = Server} = StateData) -> PendingSubscriptions = ejabberd_hooks:run_fold( resend_subscription_requests_hook, Server, [], [User, Server]), lists:foreach(fun(XMLPacket) -> send_element(StateData, XMLPacket) end, PendingSubscriptions). get_showtag(undefined) -> "unavailable"; get_showtag(Presence) -> case xml:get_path_s(Presence, [{elem, "show"}, cdata]) of "" -> "available"; ShowTag -> ShowTag end. get_statustag(undefined) -> ""; get_statustag(Presence) -> case xml:get_path_s(Presence, [{elem, "status"}, cdata]) of ShowTag -> ShowTag end. process_unauthenticated_stanza(StateData, El) -> NewEl = case xml:get_tag_attr_s("xml:lang", El) of "" -> case StateData#state.lang of "" -> El; Lang -> xml:replace_tag_attr("xml:lang", Lang, El) end; _ -> El end, case jlib:iq_query_info(NewEl) of #iq{} = IQ -> Res = ejabberd_hooks:run_fold(c2s_unauthenticated_iq, StateData#state.server, empty, [StateData#state.server, IQ, StateData#state.ip]), case Res of empty -> % The only reasonable IQ's here are auth and register IQ's % They contain secrets, so don't include subelements to response ResIQ = IQ#iq{type = error, sub_el = [?ERR_SERVICE_UNAVAILABLE]}, Res1 = jlib:replace_from_to( jlib:make_jid("", StateData#state.server, ""), jlib:make_jid("", "", ""), jlib:iq_to_xml(ResIQ)), send_element(StateData, jlib:remove_attr("to", Res1)); _ -> send_element(StateData, Res) end; _ -> % Drop any stanza, which isn't IQ stanza ok end. peerip(SockMod, Socket) -> IP = case SockMod of gen_tcp -> inet:peername(Socket); _ -> SockMod:peername(Socket) end, case IP of {ok, IPOK} -> IPOK; _ -> undefined end. %% fsm_next_state_pack: Pack the StateData structure to improve %% sharing. fsm_next_state_pack(StateName, StateData) -> fsm_next_state_gc(StateName, pack(StateData)). %% fsm_next_state_gc: Garbage collect the process heap to make use of %% the newly packed StateData structure. fsm_next_state_gc(StateName, PackedStateData) -> erlang:garbage_collect(), fsm_next_state(StateName, PackedStateData). %% fsm_next_state: Generate the next_state FSM tuple with different %% timeout, depending on the future state fsm_next_state(session_established, StateData) -> {next_state, session_established, StateData, ?C2S_HIBERNATE_TIMEOUT}; fsm_next_state(StateName, StateData) -> {next_state, StateName, StateData, ?C2S_OPEN_TIMEOUT}. %% fsm_reply: Generate the reply FSM tuple with different timeout, %% depending on the future state fsm_reply(Reply, session_established, StateData) -> {reply, Reply, session_established, StateData, ?C2S_HIBERNATE_TIMEOUT}; fsm_reply(Reply, StateName, StateData) -> {reply, Reply, StateName, StateData, ?C2S_OPEN_TIMEOUT}. %% Used by c2s blacklist plugins is_ip_blacklisted(undefined) -> false; is_ip_blacklisted({IP,_Port}) -> ejabberd_hooks:run_fold(check_bl_c2s, false, [IP]). %% Check from attributes %% returns invalid-from|NewElement check_from(El, FromJID) -> case xml:get_tag_attr("from", El) of false -> El; {value, SJID} -> JID = jlib:string_to_jid(SJID), case JID of error -> 'invalid-from'; #jid{} -> if (JID#jid.luser == FromJID#jid.luser) and (JID#jid.lserver == FromJID#jid.lserver) and (JID#jid.lresource == FromJID#jid.lresource) -> El; (JID#jid.luser == FromJID#jid.luser) and (JID#jid.lserver == FromJID#jid.lserver) and (JID#jid.lresource == "") -> El; true -> 'invalid-from' end end end. fsm_limit_opts(Opts) -> case lists:keysearch(max_fsm_queue, 1, Opts) of {value, {_, N}} when is_integer(N) -> [{max_queue, N}]; _ -> case ejabberd_config:get_local_option(max_fsm_queue) of N when is_integer(N) -> [{max_queue, N}]; _ -> [] end end. bounce_messages() -> receive {route, From, To, El} -> ejabberd_router:route(From, To, El), bounce_messages() after 0 -> ok end. %%%---------------------------------------------------------------------- %%% XEP-0191 %%%---------------------------------------------------------------------- route_blocking(What, StateData) -> SubEl = case What of {block, JIDs} -> {xmlelement, "block", [{"xmlns", ?NS_BLOCKING}], lists:map( fun(JID) -> {xmlelement, "item", [{"jid", jlib:jid_to_string(JID)}], []} end, JIDs)}; {unblock, JIDs} -> {xmlelement, "unblock", [{"xmlns", ?NS_BLOCKING}], lists:map( fun(JID) -> {xmlelement, "item", [{"jid", jlib:jid_to_string(JID)}], []} end, JIDs)}; unblock_all -> {xmlelement, "unblock", [{"xmlns", ?NS_BLOCKING}], []} end, PrivPushIQ = #iq{type = set, xmlns = ?NS_BLOCKING, id = "push", sub_el = [SubEl]}, PrivPushEl = jlib:replace_from_to( jlib:jid_remove_resource( StateData#state.jid), StateData#state.jid, jlib:iq_to_xml(PrivPushIQ)), send_element(StateData, PrivPushEl), %% No need to replace active privacy list here, %% blocking pushes are always accompanied by %% Privacy List pushes ok. %%%---------------------------------------------------------------------- %%% JID Set memory footprint reduction code %%%---------------------------------------------------------------------- %% Try to reduce the heap footprint of the four presence sets %% by ensuring that we re-use strings and Jids wherever possible. pack(S = #state{pres_a=A, pres_i=I, pres_f=F, pres_t=T}) -> {NewA, Pack1} = pack_jid_set(A, gb_trees:empty()), {NewI, Pack2} = pack_jid_set(I, Pack1), {NewF, Pack3} = pack_jid_set(F, Pack2), {NewT, _Pack4} = pack_jid_set(T, Pack3), %% Throw away Pack4 so that if we delete references to %% Strings or Jids in any of the sets there will be %% no live references for the GC to find. S#state{pres_a=NewA, pres_i=NewI, pres_f=NewF, pres_t=NewT}. pack_jid_set(Set, Pack) -> Jids = ?SETS:to_list(Set), {PackedJids, NewPack} = pack_jids(Jids, Pack, []), {?SETS:from_list(PackedJids), NewPack}. pack_jids([], Pack, Acc) -> {Acc, Pack}; pack_jids([{U,S,R}=Jid | Jids], Pack, Acc) -> case gb_trees:lookup(Jid, Pack) of {value, PackedJid} -> pack_jids(Jids, Pack, [PackedJid | Acc]); none -> {NewU, Pack1} = pack_string(U, Pack), {NewS, Pack2} = pack_string(S, Pack1), {NewR, Pack3} = pack_string(R, Pack2), NewJid = {NewU, NewS, NewR}, NewPack = gb_trees:insert(NewJid, NewJid, Pack3), pack_jids(Jids, NewPack, [NewJid | Acc]) end. pack_string(String, Pack) -> case gb_trees:lookup(String, Pack) of {value, PackedString} -> {PackedString, Pack}; none -> {String, gb_trees:insert(String, String, Pack)} end. ejabberd-2.1.11/src/mod_private.erl0000664000000000000000000001556412240230175014035 0ustar %%%---------------------------------------------------------------------- %%% File : mod_private.erl %%% Author : Alexey Shchepin %%% Purpose : Support for private storage. %%% Created : 16 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_private). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_sm_iq/3, remove_user/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). -record(private_storage, {usns, xml}). -define(Xmlel_Query(Attrs, Children), ( {xmlelement, "query", Attrs, Children} )). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), mnesia:create_table(private_storage, [{disc_only_copies, [node()]}, {attributes, record_info(fields, private_storage)}]), update_table(), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE, ?MODULE, process_sm_iq, IQDisc). stop(Host) -> ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE). process_sm_iq(#jid{luser = LUser, lserver = LServer}, #jid{luser = LUser, lserver = LServer}, IQ) when IQ#iq.type == 'set' -> case IQ#iq.sub_el of {xmlelement, "query", _, Xmlels} -> case filter_xmlels(Xmlels) of [] -> IQ#iq{ type = error, sub_el = [IQ#iq.sub_el, ?ERR_NOT_ACCEPTABLE] }; Data -> mnesia:transaction(fun() -> lists:foreach(fun (Datum) -> set_data(LUser, LServer, Datum) end, Data) end), IQ#iq{type = result, sub_el = []} end; _ -> IQ#iq{type = error, sub_el = [IQ#iq.sub_el, ?ERR_NOT_ACCEPTABLE]} end; %% process_sm_iq(#jid{luser = LUser, lserver = LServer}, #jid{luser = LUser, lserver = LServer}, IQ) when IQ#iq.type == 'get' -> case IQ#iq.sub_el of {xmlelement, "query", Attrs, Xmlels} -> case filter_xmlels(Xmlels) of [] -> IQ#iq{ type = error, sub_el = [IQ#iq.sub_el, ?ERR_BAD_FORMAT] }; Data -> case catch get_data(LUser, LServer, Data) of {'EXIT', _Reason} -> IQ#iq{ type = error, sub_el = [IQ#iq.sub_el, ?ERR_INTERNAL_SERVER_ERROR] }; Storage_Xmlels -> IQ#iq{ type = result, sub_el = [?Xmlel_Query(Attrs, Storage_Xmlels)] } end end; _ -> IQ#iq{type = error, sub_el = [IQ#iq.sub_el, ?ERR_BAD_FORMAT]} end; %% process_sm_iq(_From, _To, IQ) -> IQ#iq{type = error, sub_el = [IQ#iq.sub_el, ?ERR_FORBIDDEN]}. filter_xmlels(Xmlels) -> filter_xmlels(Xmlels, []). filter_xmlels([], Data) -> lists:reverse(Data); filter_xmlels([{xmlelement, _, Attrs, _} = Xmlel | Xmlels], Data) -> case xml:get_attr_s("xmlns", Attrs) of "" -> []; XmlNS -> filter_xmlels(Xmlels, [{XmlNS, Xmlel} | Data]) end; filter_xmlels([_ | Xmlels], Data) -> filter_xmlels(Xmlels, Data). set_data(LUser, LServer, {XmlNS, Xmlel}) -> mnesia:write(#private_storage{ usns = {LUser, LServer, XmlNS}, xml = Xmlel }). get_data(LUser, LServer, Data) -> get_data(LUser, LServer, Data, []). get_data(_LUser, _LServer, [], Storage_Xmlels) -> lists:reverse(Storage_Xmlels); get_data(LUser, LServer, [{XmlNS, Xmlel} | Data], Storage_Xmlels) -> case mnesia:dirty_read(private_storage, {LUser, LServer, XmlNS}) of [#private_storage{xml = Storage_Xmlel}] -> get_data(LUser, LServer, Data, [Storage_Xmlel | Storage_Xmlels]); _ -> get_data(LUser, LServer, Data, [Xmlel | Storage_Xmlels]) end. remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), F = fun() -> Namespaces = mnesia:select( private_storage, [{#private_storage{usns={LUser, LServer, '$1'}, _ = '_'}, [], ['$$']}]), lists:foreach( fun([Namespace]) -> mnesia:delete({private_storage, {LUser, LServer, Namespace}}) end, Namespaces) end, mnesia:transaction(F). update_table() -> Fields = record_info(fields, private_storage), case mnesia:table_info(private_storage, attributes) of Fields -> ok; [userns, xml] -> ?INFO_MSG("Converting private_storage table from " "{user, default, lists} format", []), Host = ?MYNAME, {atomic, ok} = mnesia:create_table( mod_private_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, private_storage}, {attributes, record_info(fields, private_storage)}]), mnesia:transform_table(private_storage, ignore, Fields), F1 = fun() -> mnesia:write_lock_table(mod_private_tmp_table), mnesia:foldl( fun(#private_storage{usns = {U, NS}} = R, _) -> mnesia:dirty_write( mod_private_tmp_table, R#private_storage{usns = {U, Host, NS}}) end, ok, private_storage) end, mnesia:transaction(F1), mnesia:clear_table(private_storage), F2 = fun() -> mnesia:write_lock_table(private_storage), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, mod_private_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(mod_private_tmp_table); _ -> ?INFO_MSG("Recreating private_storage table", []), mnesia:transform_table(private_storage, ignore, Fields) end. ejabberd-2.1.11/src/mod_version.erl0000664000000000000000000000521612240230175014041 0ustar %%%---------------------------------------------------------------------- %%% File : mod_version.erl %%% Author : Alexey Shchepin %%% Purpose : XEP-0092: Software Version %%% Created : 18 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_version). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_local_iq/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VERSION, ?MODULE, process_local_iq, IQDisc). stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VERSION). process_local_iq(_From, To, #iq{id = _ID, type = Type, xmlns = _XMLNS, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> Host = To#jid.lserver, OS = case gen_mod:get_module_opt(Host, ?MODULE, show_os, true) of true -> [get_os()]; false -> [] end, IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_VERSION}], [{xmlelement, "name", [], [{xmlcdata, "ejabberd"}]}, {xmlelement, "version", [], [{xmlcdata, ?VERSION}]} ] ++ OS }]} end. get_os() -> OSType = case os:type() of {Osfamily, Osname} -> atom_to_list(Osfamily) ++ "/" ++ atom_to_list(Osname); Osfamily -> atom_to_list(Osfamily) end, OSVersion = case os:version() of {Major, Minor, Release} -> lists:flatten( io_lib:format("~w.~w.~w", [Major, Minor, Release])); VersionString -> VersionString end, OS = OSType ++ " " ++ OSVersion, {xmlelement, "os", [], [{xmlcdata, OS}]}. ejabberd-2.1.11/src/ejabberd_auth_internal.erl0000664000000000000000000003313512240230175016171 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_auth_internal.erl %%% Author : Alexey Shchepin %%% Purpose : Authentification via mnesia %%% Created : 12 Dec 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_auth_internal). -author('alexey@process-one.net'). %% External exports -export([start/1, set_password/3, check_password/3, check_password/5, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, get_vh_registered_users_number/1, get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, remove_user/3, store_type/0, plain_password_required/0 ]). -include("ejabberd.hrl"). -record(passwd, {us, password}). -record(reg_users_counter, {vhost, count}). -define(SALT_LENGTH, 16). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start(Host) -> mnesia:create_table(passwd, [{disc_copies, [node()]}, {attributes, record_info(fields, passwd)}]), mnesia:create_table(reg_users_counter, [{ram_copies, [node()]}, {attributes, record_info(fields, reg_users_counter)}]), update_table(), update_reg_users_counter_table(Host), maybe_alert_password_scrammed_without_option(), ok. update_reg_users_counter_table(Server) -> Set = get_vh_registered_users(Server), Size = length(Set), LServer = jlib:nameprep(Server), F = fun() -> mnesia:write(#reg_users_counter{vhost = LServer, count = Size}) end, mnesia:sync_dirty(F). plain_password_required() -> case is_scrammed() of false -> false; true -> true end. store_type() -> case is_scrammed() of false -> plain; %% allows: PLAIN DIGEST-MD5 SCRAM true -> scram %% allows: PLAIN SCRAM end. check_password(User, Server, Password) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, case catch mnesia:dirty_read({passwd, US}) of [#passwd{password = Password}] when is_list(Password) -> Password /= ""; [#passwd{password = Scram}] when is_record(Scram, scram) -> is_password_scram_valid(Password, Scram); _ -> false end. check_password(User, Server, Password, Digest, DigestGen) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, case catch mnesia:dirty_read({passwd, US}) of [#passwd{password = Passwd}] when is_list(Passwd) -> DigRes = if Digest /= "" -> Digest == DigestGen(Passwd); true -> false end, if DigRes -> true; true -> (Passwd == Password) and (Password /= "") end; [#passwd{password = Scram}] when is_record(Scram, scram) -> Passwd = base64:decode(Scram#scram.storedkey), DigRes = if Digest /= "" -> Digest == DigestGen(Passwd); true -> false end, if DigRes -> true; true -> (Passwd == Password) and (Password /= "") end; _ -> false end. %% @spec (User::string(), Server::string(), Password::string()) -> %% ok | {error, invalid_jid} set_password(User, Server, Password) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, if (LUser == error) or (LServer == error) -> {error, invalid_jid}; true -> F = fun() -> Password2 = case is_scrammed() and is_list(Password) of true -> password_to_scram(Password); false -> Password end, mnesia:write(#passwd{us = US, password = Password2}) end, {atomic, ok} = mnesia:transaction(F), ok end. %% @spec (User, Server, Password) -> {atomic, ok} | {atomic, exists} | {error, invalid_jid} | {aborted, Reason} try_register(User, Server, Password) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, if (LUser == error) or (LServer == error) -> {error, invalid_jid}; true -> F = fun() -> case mnesia:read({passwd, US}) of [] -> Password2 = case is_scrammed() and is_list(Password) of true -> password_to_scram(Password); false -> Password end, mnesia:write(#passwd{us = US, password = Password2}), mnesia:dirty_update_counter( reg_users_counter, LServer, 1), ok; [_E] -> exists end end, mnesia:transaction(F) end. %% Get all registered users in Mnesia dirty_get_registered_users() -> mnesia:dirty_all_keys(passwd). get_vh_registered_users(Server) -> LServer = jlib:nameprep(Server), mnesia:dirty_select( passwd, [{#passwd{us = '$1', _ = '_'}, [{'==', {element, 2, '$1'}, LServer}], ['$1']}]). get_vh_registered_users(Server, [{from, Start}, {to, End}]) when is_integer(Start) and is_integer(End) -> get_vh_registered_users(Server, [{limit, End-Start+1}, {offset, Start}]); get_vh_registered_users(Server, [{limit, Limit}, {offset, Offset}]) when is_integer(Limit) and is_integer(Offset) -> case get_vh_registered_users(Server) of [] -> []; Users -> Set = lists:keysort(1, Users), L = length(Set), Start = if Offset < 1 -> 1; Offset > L -> L; true -> Offset end, lists:sublist(Set, Start, Limit) end; get_vh_registered_users(Server, [{prefix, Prefix}]) when is_list(Prefix) -> Set = [{U,S} || {U, S} <- get_vh_registered_users(Server), lists:prefix(Prefix, U)], lists:keysort(1, Set); get_vh_registered_users(Server, [{prefix, Prefix}, {from, Start}, {to, End}]) when is_list(Prefix) and is_integer(Start) and is_integer(End) -> get_vh_registered_users(Server, [{prefix, Prefix}, {limit, End-Start+1}, {offset, Start}]); get_vh_registered_users(Server, [{prefix, Prefix}, {limit, Limit}, {offset, Offset}]) when is_list(Prefix) and is_integer(Limit) and is_integer(Offset) -> case [{U,S} || {U, S} <- get_vh_registered_users(Server), lists:prefix(Prefix, U)] of [] -> []; Users -> Set = lists:keysort(1, Users), L = length(Set), Start = if Offset < 1 -> 1; Offset > L -> L; true -> Offset end, lists:sublist(Set, Start, Limit) end; get_vh_registered_users(Server, _) -> get_vh_registered_users(Server). get_vh_registered_users_number(Server) -> LServer = jlib:nameprep(Server), Query = mnesia:dirty_select( reg_users_counter, [{#reg_users_counter{vhost = LServer, count = '$1'}, [], ['$1']}]), case Query of [Count] -> Count; _ -> 0 end. get_vh_registered_users_number(Server, [{prefix, Prefix}]) when is_list(Prefix) -> Set = [{U, S} || {U, S} <- get_vh_registered_users(Server), lists:prefix(Prefix, U)], length(Set); get_vh_registered_users_number(Server, _) -> get_vh_registered_users_number(Server). get_password(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, case catch mnesia:dirty_read(passwd, US) of [#passwd{password = Password}] when is_list(Password) -> Password; [#passwd{password = Scram}] when is_record(Scram, scram) -> {base64:decode(Scram#scram.storedkey), base64:decode(Scram#scram.serverkey), base64:decode(Scram#scram.salt), Scram#scram.iterationcount}; _ -> false end. get_password_s(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, case catch mnesia:dirty_read(passwd, US) of [#passwd{password = Password}] when is_list(Password) -> Password; [#passwd{password = Scram}] when is_record(Scram, scram) -> []; _ -> [] end. %% @spec (User, Server) -> true | false | {error, Error} is_user_exists(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, case catch mnesia:dirty_read({passwd, US}) of [] -> false; [_] -> true; Other -> {error, Other} end. %% @spec (User, Server) -> ok %% @doc Remove user. %% Note: it returns ok even if there was some problem removing the user. remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, F = fun() -> mnesia:delete({passwd, US}), mnesia:dirty_update_counter(reg_users_counter, LServer, -1) end, mnesia:transaction(F), ok. %% @spec (User, Server, Password) -> ok | not_exists | not_allowed | bad_request %% @doc Remove user if the provided password is correct. remove_user(User, Server, Password) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, F = fun() -> case mnesia:read({passwd, US}) of [#passwd{password = Password}] when is_list(Password) -> mnesia:delete({passwd, US}), mnesia:dirty_update_counter(reg_users_counter, LServer, -1), ok; [#passwd{password = Scram}] when is_record(Scram, scram) -> case is_password_scram_valid(Password, Scram) of true -> mnesia:delete({passwd, US}), mnesia:dirty_update_counter(reg_users_counter, LServer, -1), ok; false -> not_allowed end; _ -> not_exists end end, case mnesia:transaction(F) of {atomic, ok} -> ok; {atomic, Res} -> Res; _ -> bad_request end. update_table() -> Fields = record_info(fields, passwd), case mnesia:table_info(passwd, attributes) of Fields -> maybe_scram_passwords(), ok; [user, password] -> ?INFO_MSG("Converting passwd table from " "{user, password} format", []), Host = ?MYNAME, {atomic, ok} = mnesia:create_table( ejabberd_auth_internal_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, passwd}, {attributes, record_info(fields, passwd)}]), mnesia:transform_table(passwd, ignore, Fields), F1 = fun() -> mnesia:write_lock_table(ejabberd_auth_internal_tmp_table), mnesia:foldl( fun(#passwd{us = U} = R, _) -> mnesia:dirty_write( ejabberd_auth_internal_tmp_table, R#passwd{us = {U, Host}}) end, ok, passwd) end, mnesia:transaction(F1), mnesia:clear_table(passwd), F2 = fun() -> mnesia:write_lock_table(passwd), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, ejabberd_auth_internal_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(ejabberd_auth_internal_tmp_table); _ -> ?INFO_MSG("Recreating passwd table", []), mnesia:transform_table(passwd, ignore, Fields) end. %%% %%% SCRAM %%% %% The passwords are stored scrammed in the table either if the option says so, %% or if at least the first password is scrammed. is_scrammed() -> OptionScram = is_option_scram(), FirstElement = mnesia:dirty_read(passwd, mnesia:dirty_first(passwd)), case {OptionScram, FirstElement} of {true, _} -> true; {false, [#passwd{password = Scram}]} when is_record(Scram, scram) -> true; _ -> false end. is_option_scram() -> scram == ejabberd_config:get_local_option({auth_password_format, ?MYNAME}). maybe_alert_password_scrammed_without_option() -> case is_scrammed() andalso not is_option_scram() of true -> ?ERROR_MSG("Some passwords were stored in the database as SCRAM, " "but 'auth_password_format' is not configured 'scram'. " "The option will now be considered to be 'scram'.", []); false -> ok end. maybe_scram_passwords() -> case is_scrammed() of true -> scram_passwords(); false -> ok end. scram_passwords() -> ?INFO_MSG("Converting the stored passwords into SCRAM bits", []), Fun = fun(#passwd{password = Password} = P) -> Scram = password_to_scram(Password), P#passwd{password = Scram} end, Fields = record_info(fields, passwd), mnesia:transform_table(passwd, Fun, Fields). password_to_scram(Password) -> password_to_scram(Password, ?SCRAM_DEFAULT_ITERATION_COUNT). password_to_scram(Password, IterationCount) -> Salt = crypto:rand_bytes(?SALT_LENGTH), SaltedPassword = scram:salted_password(Password, Salt, IterationCount), StoredKey = scram:stored_key(scram:client_key(SaltedPassword)), ServerKey = scram:server_key(SaltedPassword), #scram{storedkey = base64:encode(StoredKey), serverkey = base64:encode(ServerKey), salt = base64:encode(Salt), iterationcount = IterationCount}. is_password_scram_valid(Password, Scram) -> IterationCount = Scram#scram.iterationcount, Salt = base64:decode(Scram#scram.salt), SaltedPassword = scram:salted_password(Password, Salt, IterationCount), StoredKey = scram:stored_key(scram:client_key(SaltedPassword)), (base64:decode(Scram#scram.storedkey) == StoredKey). ejabberd-2.1.11/src/ejabberd_commands.erl0000664000000000000000000003471712240230175015144 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_commands.erl %%% Author : Badlop %%% Purpose : Management of ejabberd commands %%% Created : 20 May 2008 by Badlop %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %%% @headerfile "ejabberd_commands.hrl" %%% @doc Management of ejabberd commands. %%% %%% An ejabberd command is an abstract function identified by a name, %%% with a defined number and type of calling arguments and type of %%% result, that can be defined in any Erlang module and executed %%% using any valid frontend. %%% %%% %%% == Define a new ejabberd command == %%% %%% ejabberd commands can be defined and registered in %%% any Erlang module. %%% %%% Some commands are procedures; and their purpose is to perform an %%% action in the server, so the command result is only some result %%% code or result tuple. Other commands are inspectors, and their %%% purpose is to gather some information about the server and return %%% a detailed response: it can be integer, string, atom, tuple, list %%% or a mix of those ones. %%% %%% The arguments and result of an ejabberd command are strictly %%% defined. The number and format of the arguments provided when %%% calling an ejabberd command must match the definition of that %%% command. The format of the result provided by an ejabberd command %%% must be exactly its definition. For example, if a command is said %%% to return an integer, it must always return an integer (except in %%% case of a crash). %%% %%% If you are developing an Erlang module that will run inside %%% ejabberd and you want to provide a new ejabberd command to %%% administer some task related to your module, you only need to: %%% implement a function, define the command, and register it. %%% %%% %%% === Define a new ejabberd command === %%% %%% An ejabberd command is defined using the Erlang record %%% 'ejabberd_commands'. This record has several elements that you %%% must define. Note that 'tags', 'desc' and 'longdesc' are optional. %%% %%% For example let's define an ejabberd command 'pow' that gets the %%% integers 'base' and 'exponent'. Its result will be an integer %%% 'power': %%% %%%

#ejabberd_commands{name = pow, tags = [test],
%%%                 desc = "Return the power of base for exponent",
%%%                 longdesc = "This is an example command. The formula is:\n"
%%%                 "  power = base ^ exponent",
%%%                 module = ?MODULE, function = pow,
%%%                 args = [{base, integer}, {exponent, integer}],
%%%                 result = {power, integer}}
%%% %%% %%% === Implement the function associated to the command === %%% %%% Now implement a function in your module that matches the arguments %%% and result of the ejabberd command. %%% %%% For example the function calc_power gets two integers Base and %%% Exponent. It calculates the power and rounds to an integer: %%% %%%
calc_power(Base, Exponent) ->
%%%    PowFloat = math:pow(Base, Exponent),
%%%    round(PowFloat).
%%% %%% Since this function will be called by ejabberd_commands, it must be exported. %%% Add to your module: %%%
-export([calc_power/2]).
%%% %%% Only some types of result formats are allowed. %%% If the format is defined as 'rescode', then your function must return: %%% ok | true | atom() %%% where the atoms ok and true as considered positive answers, %%% and any other response atom is considered negative. %%% %%% If the format is defined as 'restuple', then the command must return: %%% {rescode(), string()} %%% %%% If the format is defined as '{list, something()}', then the command %%% must return a list of something(). %%% %%% %%% === Register the command === %%% %%% Define this function and put inside the #ejabberd_command you %%% defined in the beginning: %%% %%%
commands() ->
%%%    [
%%%
%%%    ].
%%% %%% You need to include this header file in order to use the record: %%% %%%
-include("ejabberd_commands.hrl").
%%% %%% When your module is initialized or started, register your commands: %%% %%%
ejabberd_commands:register_commands(commands()),
%%% %%% And when your module is stopped, unregister your commands: %%% %%%
ejabberd_commands:unregister_commands(commands()),
%%% %%% That's all! Now when your module is started, the command will be %%% registered and any frontend can access it. For example: %%% %%%
$ ejabberdctl help pow
%%%
%%%   Command Name: pow
%%%
%%%   Arguments: base::integer
%%%              exponent::integer
%%%
%%%   Returns: power::integer
%%%
%%%   Tags: test
%%%
%%%   Description: Return the power of base for exponent
%%%
%%% This is an example command. The formula is:
%%%  power = base ^ exponent
%%%
%%% $ ejabberdctl pow 3 4
%%% 81
%%% 
%%% %%% %%% == Execute an ejabberd command == %%% %%% ejabberd commands are mean to be executed using any valid %%% frontend. An ejabberd commands is implemented in a regular Erlang %%% function, so it is also possible to execute this function in any %%% Erlang module, without dealing with the associated ejabberd %%% commands. %%% %%% %%% == Frontend to ejabberd commands == %%% %%% Currently there are two frontends to ejabberd commands: the shell %%% script {@link ejabberd_ctl. ejabberdctl}, and the XML-RPC server %%% ejabberd_xmlrpc. %%% %%% %%% === ejabberdctl as a frontend to ejabberd commands === %%% %%% It is possible to use ejabberdctl to get documentation of any %%% command. But ejabberdctl does not support all the argument types %%% allowed in ejabberd commands, so there are some ejabberd commands %%% that cannot be executed using ejabberdctl. %%% %%% Also note that the ejabberdctl shell administration script also %%% manages ejabberdctl commands, which are unrelated to ejabberd %%% commands and can only be executed using ejabberdctl. %%% %%% %%% === ejabberd_xmlrpc as a frontend to ejabberd commands === %%% %%% ejabberd_xmlrpc provides an XML-RPC server to execute ejabberd commands. %%% ejabberd_xmlrpc is a contributed module published in ejabberd-modules SVN. %%% %%% Since ejabberd_xmlrpc does not provide any method to get documentation %%% of the ejabberd commands, please use ejabberdctl to know which %%% commands are available, and their usage. %%% %%% The number and format of the arguments provided when calling an %%% ejabberd command must match the definition of that command. Please %%% make sure the XML-RPC call provides the required arguments, with %%% the specified format. The order of the arguments in an XML-RPC %%% call is not important, because all the data is tagged and will be %%% correctly prepared by ejabberd_xmlrpc before executing the ejabberd %%% command. %%% TODO: consider this feature: %%% All commands are catched. If an error happens, return the restuple: %%% {error, flattened error string} %%% This means that ecomm call APIs (ejabberd_ctl, ejabberd_xmlrpc) need to allows this. %%% And ejabberd_xmlrpc must be prepared to handle such an unexpected response. -module(ejabberd_commands). -author('badlop@process-one.net'). -export([init/0, list_commands/0, get_command_format/1, get_command_definition/1, get_tags_commands/0, register_commands/1, unregister_commands/1, execute_command/2, execute_command/4 ]). -include("ejabberd_commands.hrl"). -include("ejabberd.hrl"). init() -> ets:new(ejabberd_commands, [named_table, set, public, {keypos, #ejabberd_commands.name}]). %% @spec ([ejabberd_commands()]) -> ok %% @doc Register ejabberd commands. %% If a command is already registered, a warning is printed and the old command is preserved. register_commands(Commands) -> lists:foreach( fun(Command) -> case ets:insert_new(ejabberd_commands, Command) of true -> ok; false -> ?DEBUG("This command is already defined:~n~p", [Command]) end end, Commands). %% @spec ([ejabberd_commands()]) -> ok %% @doc Unregister ejabberd commands. unregister_commands(Commands) -> lists:foreach( fun(Command) -> ets:delete_object(ejabberd_commands, Command) end, Commands). %% @spec () -> [{Name::atom(), Args::[aterm()], Desc::string()}] %% @doc Get a list of all the available commands, arguments and description. list_commands() -> Commands = ets:match(ejabberd_commands, #ejabberd_commands{name = '$1', args = '$2', desc = '$3', _ = '_'}), [{A, B, C} || [A, B, C] <- Commands]. %% @spec (Name::atom()) -> {Args::[aterm()], Result::rterm()} | {error, command_unknown} %% @doc Get the format of arguments and result of a command. get_command_format(Name) -> Matched = ets:match(ejabberd_commands, #ejabberd_commands{name = Name, args = '$1', result = '$2', _ = '_'}), case Matched of [] -> {error, command_unknown}; [[Args, Result]] -> {Args, Result} end. %% @spec (Name::atom()) -> ejabberd_commands() | command_not_found %% @doc Get the definition record of a command. get_command_definition(Name) -> case ets:lookup(ejabberd_commands, Name) of [E] -> E; [] -> command_not_found end. %% @spec (Name::atom(), Arguments) -> ResultTerm | {error, command_unknown} %% @doc Execute a command. execute_command(Name, Arguments) -> execute_command([], noauth, Name, Arguments). %% @spec (AccessCommands, Auth, Name::atom(), Arguments) -> ResultTerm | {error, Error} %% where %% AccessCommands = [{Access, CommandNames, Arguments}] %% Auth = {User::string(), Server::string(), Password::string()} | noauth %% Method = atom() %% Arguments = [any()] %% Error = command_unknown | account_unprivileged | invalid_account_data | no_auth_provided execute_command(AccessCommands, Auth, Name, Arguments) -> case ets:lookup(ejabberd_commands, Name) of [Command] -> try check_access_commands(AccessCommands, Auth, Name, Command, Arguments) of ok -> execute_command2(Command, Arguments) catch {error, Error} -> {error, Error} end; [] -> {error, command_unknown} end. execute_command2(Command, Arguments) -> Module = Command#ejabberd_commands.module, Function = Command#ejabberd_commands.function, ?DEBUG("Executing command ~p:~p with Args=~p", [Module, Function, Arguments]), apply(Module, Function, Arguments). %% @spec () -> [{Tag::string(), [CommandName::string()]}] %% @doc Get all the tags and associated commands. get_tags_commands() -> CommandTags = ets:match(ejabberd_commands, #ejabberd_commands{ name = '$1', tags = '$2', _ = '_'}), Dict = lists:foldl( fun([CommandNameAtom, CTags], D) -> CommandName = atom_to_list(CommandNameAtom), case CTags of [] -> orddict:append("untagged", CommandName, D); _ -> lists:foldl( fun(TagAtom, DD) -> Tag = atom_to_list(TagAtom), orddict:append(Tag, CommandName, DD) end, D, CTags) end end, orddict:new(), CommandTags), orddict:to_list(Dict). %% ----------------------------- %% Access verification %% ----------------------------- %% @spec (AccessCommands, Auth, Method, Command, Arguments) -> ok %% where %% AccessCommands = [ {Access, CommandNames, Arguments} ] %% Auth = {User::string(), Server::string(), Password::string()} | noauth %% Method = atom() %% Arguments = [any()] %% @doc Check access is allowed to that command. %% At least one AccessCommand must be satisfied. %% It may throw {error, Error} where: %% Error = account_unprivileged | invalid_account_data check_access_commands([], _Auth, _Method, _Command, _Arguments) -> ok; check_access_commands(AccessCommands, Auth, Method, Command, Arguments) -> AccessCommandsAllowed = lists:filter( fun({Access, Commands, ArgumentRestrictions}) -> case check_access(Access, Auth) of true -> check_access_command(Commands, Command, ArgumentRestrictions, Method, Arguments); false -> false end end, AccessCommands), case AccessCommandsAllowed of [] -> throw({error, account_unprivileged}); L when is_list(L) -> ok end. check_auth(noauth) -> no_auth_provided; check_auth({User, Server, Password}) -> %% Check the account exists and password is valid AccountPass = ejabberd_auth:get_password_s(User, Server), AccountPassMD5 = get_md5(AccountPass), case Password of AccountPass -> {ok, User, Server}; AccountPassMD5 -> {ok, User, Server}; _ -> throw({error, invalid_account_data}) end. get_md5(AccountPass) -> lists:flatten([io_lib:format("~.16B", [X]) || X <- binary_to_list(crypto:md5(AccountPass))]). check_access(all, _) -> true; check_access(Access, Auth) -> {ok, User, Server} = check_auth(Auth), %% Check this user has access permission case acl:match_rule(Server, Access, jlib:make_jid(User, Server, "")) of allow -> true; deny -> false end. check_access_command(Commands, Command, ArgumentRestrictions, Method, Arguments) -> case Commands==all orelse lists:member(Method, Commands) of true -> check_access_arguments(Command, ArgumentRestrictions, Arguments); false -> false end. check_access_arguments(Command, ArgumentRestrictions, Arguments) -> ArgumentsTagged = tag_arguments(Command#ejabberd_commands.args, Arguments), lists:all( fun({ArgName, ArgAllowedValue}) -> %% If the call uses the argument, check the value is acceptable case lists:keysearch(ArgName, 1, ArgumentsTagged) of {value, {ArgName, ArgValue}} -> ArgValue == ArgAllowedValue; false -> true end end, ArgumentRestrictions). tag_arguments(ArgsDefs, Args) -> lists:zipwith( fun({ArgName, _ArgType}, ArgValue) -> {ArgName, ArgValue} end, ArgsDefs, Args). ejabberd-2.1.11/src/ejabberd_config.hrl0000664000000000000000000000215112240230175014576 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -record(config, {key, value}). -record(local_config, {key, value}). -record(state, {opts = [], hosts = [], override_local = false, override_global = false, override_acls = false}). ejabberd-2.1.11/src/mod_shared_roster_odbc.erl0000664000000000000000000011204312240230175016204 0ustar %%%---------------------------------------------------------------------- %%% File : mod_shared_roster_odbc.erl %%% Author : Alexey Shchepin %%% Purpose : Shared roster management %%% Created : 5 Mar 2005 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_shared_roster_odbc). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, item_to_xml/1, webadmin_menu/3, webadmin_page/3, get_user_roster/2, get_subscription_lists/3, get_jid_info/4, process_item/2, in_subscription/6, out_subscription/4, user_available/1, unset_presence/4, register_user/2, remove_user/2, list_groups/1, create_group/2, create_group/3, delete_group/2, get_group_opts/2, set_group_opts/3, get_group_users/2, get_group_explicit_users/2, is_user_in_group/3, add_user_to_group/3, remove_user_from_group/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_roster.hrl"). -include("web/ejabberd_http.hrl"). -include("web/ejabberd_web_admin.hrl"). start(Host, _Opts) -> ejabberd_hooks:add(webadmin_menu_host, Host, ?MODULE, webadmin_menu, 70), ejabberd_hooks:add(webadmin_page_host, Host, ?MODULE, webadmin_page, 50), ejabberd_hooks:add(roster_get, Host, ?MODULE, get_user_roster, 70), ejabberd_hooks:add(roster_in_subscription, Host, ?MODULE, in_subscription, 30), ejabberd_hooks:add(roster_out_subscription, Host, ?MODULE, out_subscription, 30), ejabberd_hooks:add(roster_get_subscription_lists, Host, ?MODULE, get_subscription_lists, 70), ejabberd_hooks:add(roster_get_jid_info, Host, ?MODULE, get_jid_info, 70), ejabberd_hooks:add(roster_process_item, Host, ?MODULE, process_item, 50), ejabberd_hooks:add(user_available_hook, Host, ?MODULE, user_available, 50), ejabberd_hooks:add(unset_presence_hook, Host, ?MODULE, unset_presence, 50), ejabberd_hooks:add(register_user, Host, ?MODULE, register_user, 50), ejabberd_hooks:add(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50). %%ejabberd_hooks:add(remove_user, Host, %% ?MODULE, remove_user, 50), stop(Host) -> ejabberd_hooks:delete(webadmin_menu_host, Host, ?MODULE, webadmin_menu, 70), ejabberd_hooks:delete(webadmin_page_host, Host, ?MODULE, webadmin_page, 50), ejabberd_hooks:delete(roster_get, Host, ?MODULE, get_user_roster, 70), ejabberd_hooks:delete(roster_in_subscription, Host, ?MODULE, in_subscription, 30), ejabberd_hooks:delete(roster_out_subscription, Host, ?MODULE, out_subscription, 30), ejabberd_hooks:delete(roster_get_subscription_lists, Host, ?MODULE, get_subscription_lists, 70), ejabberd_hooks:delete(roster_get_jid_info, Host, ?MODULE, get_jid_info, 70), ejabberd_hooks:delete(roster_process_item, Host, ?MODULE, process_item, 50), ejabberd_hooks:delete(user_available_hook, Host, ?MODULE, user_available, 50), ejabberd_hooks:delete(unset_presence_hook, Host, ?MODULE, unset_presence, 50), ejabberd_hooks:delete(register_user, Host, ?MODULE, register_user, 50), ejabberd_hooks:delete(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50). %%ejabberd_hooks:delete(remove_user, Host, %% ?MODULE, remove_user, 50), get_user_roster(Items, US) -> {U, S} = US, DisplayedGroups = get_user_displayed_groups(US), %% Get shared roster users in all groups and remove self: SRUsers = lists:foldl( fun(Group, Acc1) -> GroupName = get_group_name(S, Group), lists:foldl( fun(User, Acc2) -> if User == US -> Acc2; true -> dict:append(User, GroupName, Acc2) end end, Acc1, get_group_users(S, Group)) end, dict:new(), DisplayedGroups), %% If partially subscribed users are also in shared roster, show them as %% totally subscribed: {NewItems1, SRUsersRest} = lists:mapfoldl( fun(Item, SRUsers1) -> {_, _, {U1, S1, _}} = Item#roster.usj, US1 = {U1, S1}, case dict:find(US1, SRUsers1) of {ok, _GroupNames} -> {Item#roster{subscription = both, ask = none}, dict:erase(US1, SRUsers1)}; error -> {Item, SRUsers1} end end, SRUsers, Items), %% Export items in roster format: ModVcard = get_vcard_module(S), SRItems = [#roster{usj = {U, S, {U1, S1, ""}}, us = US, jid = {U1, S1, ""}, name = get_rosteritem_name(ModVcard, U1, S1), subscription = both, ask = none, groups = GroupNames} || {{U1, S1}, GroupNames} <- dict:to_list(SRUsersRest)], SRItems ++ NewItems1. get_vcard_module(Server) -> Modules = gen_mod:loaded_modules(Server), [M || M <- Modules, (M == mod_vcard) or (M == mod_vcard_odbc) or (M == mod_vcard_ldap)]. get_rosteritem_name([], _, _) -> ""; get_rosteritem_name([ModVcard], U, S) -> From = jlib:make_jid("", S, ?MODULE), To = jlib:make_jid(U, S, ""), IQ = {iq,"",get,"vcard-temp","", {xmlelement,"vCard",[{"xmlns","vcard-temp"}],[]}}, IQ_Vcard = ModVcard:process_sm_iq(From, To, IQ), try get_rosteritem_name_vcard(IQ_Vcard#iq.sub_el) catch E1:E2 -> ?ERROR_MSG("Error ~p found when trying to get the vCard of ~s@~s " "in ~p:~n ~p", [E1, U, S, ModVcard, E2]), "" end. get_rosteritem_name_vcard([]) -> ""; get_rosteritem_name_vcard([Vcard]) -> case xml:get_path_s(Vcard, [{elem, "NICKNAME"}, cdata]) of "" -> xml:get_path_s(Vcard, [{elem, "FN"}, cdata]); Nickname -> Nickname end. %% This function rewrites the roster entries when moving or renaming %% them in the user contact list. process_item(RosterItem, Host) -> USFrom = {UserFrom, ServerFrom} = RosterItem#roster.us, {UserTo, ServerTo, ResourceTo} = RosterItem#roster.jid, NameTo = RosterItem#roster.name, USTo = {UserTo, ServerTo}, DisplayedGroups = get_user_displayed_groups(USFrom), CommonGroups = lists:filter(fun(Group) -> is_user_in_group(USTo, Group, Host) end, DisplayedGroups), case CommonGroups of [] -> RosterItem; %% Roster item cannot be removed: We simply reset the original groups: _ when RosterItem#roster.subscription == remove -> GroupNames = lists:map(fun(Group) -> get_group_name(Host, Group) end, CommonGroups), RosterItem#roster{subscription = both, ask = none, groups=[GroupNames]}; %% Both users have at least a common shared group, %% So each user can see the other _ -> %% Check if the list of groups of the new roster item %% include at least a new one case lists:subtract(RosterItem#roster.groups, CommonGroups) of %% If it doesn't, then remove this user from any %% existing roster groups. [] -> %% Remove pending subscription by setting it %% unsubscribed. Mod = get_roster_mod(ServerFrom), %% Remove pending out subscription Mod:out_subscription(UserTo, ServerTo, jlib:make_jid(UserFrom, ServerFrom, ""), unsubscribe), %% Remove pending in subscription Mod:in_subscription(aaaa, UserFrom, ServerFrom, jlib:make_jid(UserTo, ServerTo, ""), unsubscribe, ""), %% But we're still subscribed, so respond as such. RosterItem#roster{subscription = both, ask = none}; %% If so, it means the user wants to add that contact %% to his personal roster PersonalGroups -> %% Store roster items in From and To rosters set_new_rosteritems(UserFrom, ServerFrom, UserTo, ServerTo, ResourceTo, NameTo, PersonalGroups) end end. build_roster_record(User1, Server1, User2, Server2, Name2, Groups) -> USR2 = {User2, Server2, ""}, #roster{usj = {User1, Server1, USR2}, us = {User1, Server1}, jid = USR2, name = Name2, subscription = both, ask = none, groups = Groups }. set_new_rosteritems(UserFrom, ServerFrom, UserTo, ServerTo, ResourceTo, NameTo, GroupsFrom) -> Mod = get_roster_mod(ServerFrom), RIFrom = build_roster_record(UserFrom, ServerFrom, UserTo, ServerTo, NameTo, GroupsFrom), set_item(UserFrom, ServerFrom, ResourceTo, RIFrom), JIDTo = jlib:make_jid(UserTo, ServerTo, ""), JIDFrom = jlib:make_jid(UserFrom, ServerFrom, ""), RITo = build_roster_record(UserTo, ServerTo, UserFrom, ServerFrom, UserFrom,[]), set_item(UserTo, ServerTo, "", RITo), %% From requests Mod:out_subscription(UserFrom, ServerFrom, JIDTo, subscribe), Mod:in_subscription(aaa, UserTo, ServerTo, JIDFrom, subscribe, ""), %% To accepts Mod:out_subscription(UserTo, ServerTo, JIDFrom, subscribed), Mod:in_subscription(aaa, UserFrom, ServerFrom, JIDTo, subscribed, ""), %% To requests Mod:out_subscription(UserTo, ServerTo, JIDFrom, subscribe), Mod:in_subscription(aaa, UserFrom, ServerFrom, JIDTo, subscribe, ""), %% From accepts Mod:out_subscription(UserFrom, ServerFrom, JIDTo, subscribed), Mod:in_subscription(aaa, UserTo, ServerTo, JIDFrom, subscribed, ""), RIFrom. set_item(User, Server, Resource, Item) -> ResIQ = #iq{type = set, xmlns = ?NS_ROSTER, id = "push" ++ randoms:get_string(), sub_el = [{xmlelement, "query", [{"xmlns", ?NS_ROSTER}], [mod_roster:item_to_xml(Item)]}]}, ejabberd_router:route( jlib:make_jid(User, Server, Resource), jlib:make_jid("", Server, ""), jlib:iq_to_xml(ResIQ)). get_subscription_lists({F, T}, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, DisplayedGroups = get_user_displayed_groups(US), SRUsers = lists:usort( lists:flatmap( fun(Group) -> get_group_users(LServer, Group) end, DisplayedGroups)), SRJIDs = [{U1, S1, ""} || {U1, S1} <- SRUsers], {lists:usort(SRJIDs ++ F), lists:usort(SRJIDs ++ T)}. get_jid_info({Subscription, Groups}, User, Server, JID) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, {U1, S1, _} = jlib:jid_tolower(JID), US1 = {U1, S1}, DisplayedGroups = get_user_displayed_groups(US), SRUsers = lists:foldl( fun(Group, Acc1) -> lists:foldl( fun(User1, Acc2) -> dict:append( User1, get_group_name(LServer, Group), Acc2) end, Acc1, get_group_users(LServer, Group)) end, dict:new(), DisplayedGroups), case dict:find(US1, SRUsers) of {ok, GroupNames} -> NewGroups = if Groups == [] -> GroupNames; true -> Groups end, {both, NewGroups}; error -> {Subscription, Groups} end. in_subscription(Acc, User, Server, JID, Type, _Reason) -> process_subscription(in, User, Server, JID, Type, Acc). out_subscription(UserFrom, ServerFrom, JIDTo, unsubscribed) -> Mod = get_roster_mod(ServerFrom), %% Remove pending out subscription #jid{luser = UserTo, lserver = ServerTo} = JIDTo, JIDFrom = jlib:make_jid(UserFrom, UserTo, ""), Mod:out_subscription(UserTo, ServerTo, JIDFrom, unsubscribe), %% Remove pending in subscription Mod:in_subscription(aaaa, UserFrom, ServerFrom, JIDTo, unsubscribe, ""), process_subscription(out, UserFrom, ServerFrom, JIDTo, unsubscribed, false); out_subscription(User, Server, JID, Type) -> process_subscription(out, User, Server, JID, Type, false). process_subscription(Direction, User, Server, JID, _Type, Acc) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, {U1, S1, _} = jlib:jid_tolower(jlib:jid_remove_resource(JID)), US1 = {U1, S1}, DisplayedGroups = get_user_displayed_groups(US), SRUsers = lists:usort( lists:flatmap( fun(Group) -> get_group_users(LServer, Group) end, DisplayedGroups)), case lists:member(US1, SRUsers) of true -> case Direction of in -> {stop, false}; out -> stop end; false -> Acc end. list_groups(Host) -> case ejabberd_odbc:sql_query( Host, ["select name from sr_group;"]) of {selected, ["name"], Rs} -> [G || {G} <- Rs]; _ -> [] end. groups_with_opts(Host) -> case ejabberd_odbc:sql_query( Host, ["select name, opts from sr_group;"]) of {selected, ["name", "opts"], Rs} -> [{G, ejabberd_odbc:decode_term(Opts)} || {G, Opts} <- Rs]; _ -> [] end. create_group(Host, Group) -> create_group(Host, Group, []). create_group(Host, Group, Opts) -> SGroup = ejabberd_odbc:escape(Group), SOpts = ejabberd_odbc:encode_term(Opts), F = fun() -> odbc_queries:update_t("sr_group", ["name", "opts"], [SGroup, SOpts], ["name='", SGroup, "'"]) end, ejabberd_odbc:sql_transaction(Host, F). delete_group(Host, Group) -> SGroup = ejabberd_odbc:escape(Group), F = fun() -> ejabberd_odbc:sql_query_t( ["delete from sr_group where name='", SGroup, "';"]), ejabberd_odbc:sql_query_t( ["delete from sr_user where grp='", SGroup, "';"]) end, ejabberd_odbc:sql_transaction(Host, F). get_group_opts(Host, Group) -> SGroup = ejabberd_odbc:escape(Group), case catch ejabberd_odbc:sql_query( Host, ["select opts from sr_group " "where name='", SGroup, "';"]) of {selected, ["opts"], [{SOpts}]} -> ejabberd_odbc:decode_term(SOpts); _ -> error end. set_group_opts(Host, Group, Opts) -> SGroup = ejabberd_odbc:escape(Group), SOpts = ejabberd_odbc:encode_term(Opts), F = fun() -> odbc_queries:update_t("sr_group", ["name", "opts"], [SGroup, SOpts], ["name='", SGroup, "'"]) end, ejabberd_odbc:sql_transaction(Host, F). get_user_groups(US) -> Host = element(2, US), SJID = make_jid_s(US), case catch ejabberd_odbc:sql_query( Host, ["select grp from sr_user " "where jid='", SJID, "';"]) of {selected, ["grp"], Rs} -> [G || {G} <- Rs]; _ -> [] end ++ get_special_users_groups(Host). is_group_enabled(Host1, Group1) -> {Host, Group} = split_grouphost(Host1, Group1), SGroup = ejabberd_odbc:escape(Group), case catch ejabberd_odbc:sql_query( Host, ["select opts from sr_group " "where name='", SGroup, "';"]) of {selected, ["opts"], [{SOpts}]} -> Opts = ejabberd_odbc:decode_term(SOpts), not lists:member(disabled, Opts); _ -> false end. %% @spec (Host::string(), Group::string(), Opt::atom(), Default) -> OptValue | Default get_group_opt(Host, Group, Opt, Default) -> SGroup = ejabberd_odbc:escape(Group), case catch ejabberd_odbc:sql_query( Host, ["select opts from sr_group " "where name='", SGroup, "';"]) of {selected, ["opts"], [{SOpts}]} -> Opts = ejabberd_odbc:decode_term(SOpts), case lists:keysearch(Opt, 1, Opts) of {value, {_, Val}} -> Val; false -> Default end; _ -> Default end. get_online_users(Host) -> lists:usort([{U, S} || {U, S, _} <- ejabberd_sm:get_vh_session_list(Host)]). get_group_users(Host1, Group1) -> {Host, Group} = split_grouphost(Host1, Group1), case get_group_opt(Host, Group, all_users, false) of true -> ejabberd_auth:get_vh_registered_users(Host); false -> [] end ++ case get_group_opt(Host, Group, online_users, false) of true -> get_online_users(Host); false -> [] end ++ get_group_explicit_users(Host, Group). get_group_users(Host, Group, GroupOpts) -> case proplists:get_value(all_users, GroupOpts, false) of true -> ejabberd_auth:get_vh_registered_users(Host); false -> [] end ++ case proplists:get_value(online_users, GroupOpts, false) of true -> get_online_users(Host); false -> [] end ++ get_group_explicit_users(Host, Group). %% @spec (Host::string(), Group::string()) -> [{User::string(), Server::string()}] get_group_explicit_users(Host, Group) -> SGroup = ejabberd_odbc:escape(Group), case catch ejabberd_odbc:sql_query( Host, ["select jid from sr_user " "where grp='", SGroup, "';"]) of {selected, ["jid"], Rs} -> lists:map( fun({JID}) -> {U, S, _} = jlib:jid_tolower( jlib:string_to_jid(JID)), {U, S} end, Rs); _ -> [] end. get_group_name(Host1, Group1) -> {Host, Group} = split_grouphost(Host1, Group1), get_group_opt(Host, Group, name, Group). %% Get list of names of groups that have @all@/@online@/etc in the memberlist get_special_users_groups(Host) -> lists:filter( fun(Group) -> get_group_opt(Host, Group, all_users, false) orelse get_group_opt(Host, Group, online_users, false) end, list_groups(Host)). %% Get list of names of groups that have @online@ in the memberlist get_special_users_groups_online(Host) -> lists:filter( fun(Group) -> get_group_opt(Host, Group, online_users, false) end, list_groups(Host)). %% Given two lists of groupnames and their options, %% return the list of displayed groups to the second list displayed_groups(GroupsOpts, SelectedGroupsOpts) -> DisplayedGroups = lists:usort( lists:flatmap( fun({_Group, Opts}) -> [G || G <- proplists:get_value(displayed_groups, Opts, []), not lists:member(disabled, Opts)] end, SelectedGroupsOpts)), [G || G <- DisplayedGroups, not lists:member(disabled, proplists:get_value(G, GroupsOpts, []))]. %% Given a list of group names with options, %% for those that have @all@ in memberlist, %% get the list of groups displayed get_special_displayed_groups(GroupsOpts) -> Groups = lists:filter( fun({_Group, Opts}) -> proplists:get_value(all_users, Opts, false) end, GroupsOpts), displayed_groups(GroupsOpts, Groups). %% Given a username and server, and a list of group names with options, %% for the list of groups of that server that user is member %% get the list of groups displayed get_user_displayed_groups(LUser, LServer, GroupsOpts) -> SJID = make_jid_s(LUser, LServer), Groups = case catch ejabberd_odbc:sql_query( LServer, ["select grp from sr_user " "where jid='", SJID, "';"]) of {selected, ["grp"], Rs} -> [{Group, proplists:get_value(Group, GroupsOpts, [])} || {Group} <- Rs]; _ -> [] end, displayed_groups(GroupsOpts, Groups). %% @doc Get the list of groups that are displayed to this user get_user_displayed_groups(US) -> Host = element(2, US), DisplayedGroups1 = lists:usort( lists:flatmap( fun(Group) -> case is_group_enabled(Host, Group) of true -> get_group_opt(Host, Group, displayed_groups, []); false -> [] end end, get_user_groups(US))), [Group || Group <- DisplayedGroups1, is_group_enabled(Host, Group)]. is_user_in_group(US, Group, Host) -> SJID = make_jid_s(US), SGroup = ejabberd_odbc:escape(Group), case catch ejabberd_odbc:sql_query( Host, ["select * from sr_user where " "jid='", SJID, "' and grp='", SGroup, "';"]) of {selected, _, []} -> lists:member(US, get_group_users(Host, Group)); _ -> true end. %% @spec (Host::string(), {User::string(), Server::string()}, Group::string()) -> {atomic, ok} add_user_to_group(Host, US, Group) -> {LUser, LServer} = US, case ejabberd_regexp:run(LUser, "^@.+@$") of match -> GroupOpts = ?MODULE:get_group_opts(Host, Group), MoreGroupOpts = case LUser of "@all@" -> [{all_users, true}]; "@online@" -> [{online_users, true}]; _ -> [] end, ?MODULE:set_group_opts( Host, Group, GroupOpts ++ MoreGroupOpts); nomatch -> %% Push this new user to members of groups where this group is displayed push_user_to_displayed(LUser, LServer, Group, Host, both), %% Push members of groups that are displayed to this group push_displayed_to_user(LUser, LServer, Group, Host, both), SJID = make_jid_s(US), SGroup = ejabberd_odbc:escape(Group), F = fun() -> odbc_queries:update_t( "sr_user", ["jid", "grp"], [SJID, SGroup], ["jid='", SJID, "' and grp='", SGroup, "'"]) end, ejabberd_odbc:sql_transaction(Host, F) end. push_displayed_to_user(LUser, LServer, Group, Host, Subscription) -> GroupsOpts = groups_with_opts(LServer), GroupOpts = proplists:get_value(Group, GroupsOpts, []), DisplayedGroups = proplists:get_value(displayed_groups, GroupOpts, []), [push_members_to_user(LUser, LServer, DGroup, Host, Subscription) || DGroup <- DisplayedGroups]. remove_user_from_group(Host, US, Group) -> {LUser, LServer} = US, case ejabberd_regexp:run(LUser, "^@.+@$") of match -> GroupOpts = ?MODULE:get_group_opts(Host, Group), NewGroupOpts = case LUser of "@all@" -> lists:filter(fun(X) -> X/={all_users,true} end, GroupOpts); "@online@" -> lists:filter(fun(X) -> X/={online_users,true} end, GroupOpts) end, ?MODULE:set_group_opts(Host, Group, NewGroupOpts); nomatch -> SJID = make_jid_s(US), SGroup = ejabberd_odbc:escape(Group), F = fun() -> ejabberd_odbc:sql_query_t( ["delete from sr_user where jid='", SJID, "' and grp='", SGroup, "';"]), ok end, Result = ejabberd_odbc:sql_transaction(Host, F), %% Push removal of the old user to members of groups where the group that this user was members was displayed push_user_to_displayed(LUser, LServer, Group, Host, remove), %% Push removal of members of groups that where displayed to the group which this user has left push_displayed_to_user(LUser, LServer, Group, Host, remove), Result end. push_members_to_user(LUser, LServer, Group, Host, Subscription) -> GroupsOpts = groups_with_opts(LServer), GroupOpts = proplists:get_value(Group, GroupsOpts, []), GroupName = proplists:get_value(name, GroupOpts, Group), Members = get_group_users(Host, Group), lists:foreach( fun({U, S}) -> push_roster_item(LUser, LServer, U, S, GroupName, Subscription) end, Members). register_user(User, Server) -> %% Get list of groups where this user is member Groups = get_user_groups({User, Server}), %% Push this user to members of groups where is displayed a group which this user is member [push_user_to_displayed(User, Server, Group, Server, both) || Group <- Groups]. remove_user(User, Server) -> push_user_to_members(User, Server, remove). push_user_to_members(User, Server, Subscription) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), GroupsOpts = groups_with_opts(LServer), SpecialGroups = get_special_displayed_groups(GroupsOpts), UserGroups = get_user_displayed_groups(LUser, LServer, GroupsOpts), lists:foreach( fun(Group) -> remove_user_from_group(LServer, {LUser, LServer}, Group), GroupOpts = proplists:get_value(Group, GroupsOpts, []), GroupName = proplists:get_value(name, GroupOpts, Group), lists:foreach( fun({U, S}) -> push_roster_item(U, S, LUser, LServer, GroupName, Subscription) end, get_group_users(LServer, Group, GroupOpts)) end, lists:usort(SpecialGroups++UserGroups)). push_user_to_displayed(LUser, LServer, Group, Host, Subscription) -> GroupsOpts = groups_with_opts(Host), GroupOpts = proplists:get_value(Group, GroupsOpts, []), GroupName = proplists:get_value(name, GroupOpts, Group), DisplayedToGroupsOpts = displayed_to_groups(Group, Host), [push_user_to_group(LUser, LServer, GroupD, Host, GroupName, Subscription) || {GroupD, _Opts} <- DisplayedToGroupsOpts]. push_user_to_group(LUser, LServer, Group, Host, GroupName, Subscription) -> lists:foreach( fun({U, S}) when (U == LUser) and (S == LServer) -> ok; ({U, S}) -> push_roster_item(U, S, LUser, LServer, GroupName, Subscription) end, get_group_users(Host, Group)). %% Get list of groups to which this group is displayed displayed_to_groups(GroupName, LServer) -> GroupsOpts = groups_with_opts(LServer), lists:filter( fun({_Group, Opts}) -> lists:member(GroupName, proplists:get_value(displayed_groups, Opts, [])) end, GroupsOpts). push_item(User, Server, From, Item) -> %% It was %% ejabberd_sm:route(jlib:make_jid("", "", ""), %% jlib:make_jid(User, Server, "") %% why? ejabberd_sm:route(From, jlib:make_jid(User, Server, ""), {xmlelement, "broadcast", [], [{item, Item#roster.jid, Item#roster.subscription}]}), Stanza = jlib:iq_to_xml( #iq{type = set, xmlns = ?NS_ROSTER, id = "push" ++ randoms:get_string(), sub_el = [{xmlelement, "query", [{"xmlns", ?NS_ROSTER}], [item_to_xml(Item)]}]}), lists:foreach( fun(Resource) -> JID = jlib:make_jid(User, Server, Resource), ejabberd_router:route(JID, JID, Stanza) end, ejabberd_sm:get_user_resources(User, Server)). push_roster_item(User, Server, ContactU, ContactS, GroupName, Subscription) -> Item = #roster{usj = {User, Server, {ContactU, ContactS, ""}}, us = {User, Server}, jid = {ContactU, ContactS, ""}, name = "", subscription = Subscription, ask = none, groups = [GroupName]}, push_item(User, Server, jlib:make_jid("", Server, ""), Item). item_to_xml(Item) -> Attrs1 = [{"jid", jlib:jid_to_string(Item#roster.jid)}], Attrs2 = case Item#roster.name of "" -> Attrs1; Name -> [{"name", Name} | Attrs1] end, Attrs3 = case Item#roster.subscription of none -> [{"subscription", "none"} | Attrs2]; from -> [{"subscription", "from"} | Attrs2]; to -> [{"subscription", "to"} | Attrs2]; both -> [{"subscription", "both"} | Attrs2]; remove -> [{"subscription", "remove"} | Attrs2] end, Attrs4 = case ask_to_pending(Item#roster.ask) of out -> [{"ask", "subscribe"} | Attrs3]; both -> [{"ask", "subscribe"} | Attrs3]; _ -> Attrs3 end, SubEls1 = lists:map(fun(G) -> {xmlelement, "group", [], [{xmlcdata, G}]} end, Item#roster.groups), SubEls = SubEls1 ++ Item#roster.xs, {xmlelement, "item", Attrs4, SubEls}. ask_to_pending(subscribe) -> out; ask_to_pending(unsubscribe) -> none; ask_to_pending(Ask) -> Ask. user_available(New) -> LUser = New#jid.luser, LServer = New#jid.lserver, Resources = ejabberd_sm:get_user_resources(LUser, LServer), ?DEBUG("user_available for ~p @ ~p (~p resources)", [LUser, LServer, length(Resources)]), case length(Resources) of %% first session for this user 1 -> %% This is a simplification - we ignore he 'display' %% property - @online@ is always reflective. OnlineGroups = get_special_users_groups_online(LServer), lists:foreach( fun(OG) -> ?DEBUG("user_available: pushing ~p @ ~p grp ~p", [LUser, LServer, OG ]), push_user_to_displayed(LUser, LServer, OG, LServer, both) end, OnlineGroups); _ -> ok end. unset_presence(LUser, LServer, Resource, Status) -> Resources = ejabberd_sm:get_user_resources(LUser, LServer), ?DEBUG("unset_presence for ~p @ ~p / ~p -> ~p (~p resources)", [LUser, LServer, Resource, Status, length(Resources)]), %% if user has no resources left... case length(Resources) of 0 -> %% This is a simplification - we ignore he 'display' %% property - @online@ is always reflective. OnlineGroups = get_special_users_groups_online(LServer), %% for each of these groups... lists:foreach( fun(OG) -> %% Push removal of the old user to members of groups %% where the group that this uwas members was displayed push_user_to_displayed(LUser, LServer, OG, LServer, remove), %% Push removal of members of groups that where %% displayed to the group which thiuser has left push_displayed_to_user(LUser, LServer, OG, LServer,remove) end, OnlineGroups); _ -> ok end. %%--------------------- %% Web Admin %%--------------------- webadmin_menu(Acc, _Host, Lang) -> [{"shared-roster", ?T("Shared Roster Groups")} | Acc]. webadmin_page(_, Host, #request{us = _US, path = ["shared-roster"], q = Query, lang = Lang} = _Request) -> Res = list_shared_roster_groups(Host, Query, Lang), {stop, Res}; webadmin_page(_, Host, #request{us = _US, path = ["shared-roster", Group], q = Query, lang = Lang} = _Request) -> Res = shared_roster_group(Host, Group, Query, Lang), {stop, Res}; webadmin_page(Acc, _, _) -> Acc. list_shared_roster_groups(Host, Query, Lang) -> Res = list_sr_groups_parse_query(Host, Query), SRGroups = ?MODULE:list_groups(Host), FGroups = ?XAE("table", [], [?XE("tbody", lists:map( fun(Group) -> ?XE("tr", [?XE("td", [?INPUT("checkbox", "selected", Group)]), ?XE("td", [?AC(Group ++ "/", Group)]) ] ) end, lists:sort(SRGroups)) ++ [?XE("tr", [?X("td"), ?XE("td", [?INPUT("text", "namenew", "")]), ?XE("td", [?INPUTT("submit", "addnew", "Add New")]) ] )] )]), ?H1GL(?T("Shared Roster Groups"), "modsharedroster", "mod_shared_roster") ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [FGroups, ?BR, ?INPUTT("submit", "delete", "Delete Selected") ]) ]. list_sr_groups_parse_query(Host, Query) -> case lists:keysearch("addnew", 1, Query) of {value, _} -> list_sr_groups_parse_addnew(Host, Query); _ -> case lists:keysearch("delete", 1, Query) of {value, _} -> list_sr_groups_parse_delete(Host, Query); _ -> nothing end end. list_sr_groups_parse_addnew(Host, Query) -> case lists:keysearch("namenew", 1, Query) of {value, {_, Group}} when Group /= "" -> ?MODULE:create_group(Host, Group), ok; _ -> error end. list_sr_groups_parse_delete(Host, Query) -> SRGroups = ?MODULE:list_groups(Host), lists:foreach( fun(Group) -> case lists:member({"selected", Group}, Query) of true -> ?MODULE:delete_group(Host, Group); _ -> ok end end, SRGroups), ok. shared_roster_group(Host, Group, Query, Lang) -> Res = shared_roster_group_parse_query(Host, Group, Query), GroupOpts = ?MODULE:get_group_opts(Host, Group), Name = get_opt(GroupOpts, name, ""), Description = get_opt(GroupOpts, description, ""), AllUsers = get_opt(GroupOpts, all_users, false), OnlineUsers = get_opt(GroupOpts, online_users, false), %%Disabled = false, DisplayedGroups = get_opt(GroupOpts, displayed_groups, []), Members = ?MODULE:get_group_explicit_users(Host, Group), FMembers = if AllUsers -> "@all@\n"; true -> [] end ++ if OnlineUsers -> "@online@\n"; true -> [] end ++ [[us_to_list(Member), $\n] || Member <- Members], FDisplayedGroups = [[DG, $\n] || DG <- DisplayedGroups], DescNL = length(ejabberd_regexp:split(Description, "\n")), FGroup = ?XAE("table", [{"class", "withtextareas"}], [?XE("tbody", [?XE("tr", [?XCT("td", "Name:"), ?XE("td", [?INPUT("text", "name", Name)]) ] ), ?XE("tr", [?XCT("td", "Description:"), ?XE("td", [ ?TEXTAREA("description", integer_to_list(lists:max([3, DescNL])), "20", Description) ] ) ] ), ?XE("tr", [?XCT("td", "Members:"), ?XE("td", [ ?TEXTAREA("members", integer_to_list(lists:max([3, length(FMembers)])), "20", FMembers) ] ) ] ), ?XE("tr", [?XCT("td", "Displayed Groups:"), ?XE("td", [ ?TEXTAREA("dispgroups", integer_to_list(lists:max([3, length(FDisplayedGroups)])), "20", FDisplayedGroups) ] ) ] )] )]), ?H1GL(?T("Shared Roster Groups"), "modsharedroster", "mod_shared_roster") ++ [?XC("h2", ?T("Group ") ++ Group)] ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [FGroup, ?BR, ?INPUTT("submit", "submit", "Submit") ]) ]. shared_roster_group_parse_query(Host, Group, Query) -> case lists:keysearch("submit", 1, Query) of {value, _} -> {value, {_, Name}} = lists:keysearch("name", 1, Query), {value, {_, Description}} = lists:keysearch("description", 1, Query), {value, {_, SMembers}} = lists:keysearch("members", 1, Query), {value, {_, SDispGroups}} = lists:keysearch("dispgroups", 1, Query), NameOpt = if Name == "" -> []; true -> [{name, Name}] end, DescriptionOpt = if Description == "" -> []; true -> [{description, Description}] end, DispGroups = string:tokens(SDispGroups, "\r\n"), DispGroupsOpt = if DispGroups == [] -> []; true -> [{displayed_groups, DispGroups}] end, OldMembers = ?MODULE:get_group_explicit_users( Host, Group), SJIDs = string:tokens(SMembers, ", \r\n"), NewMembers = lists:foldl( fun(_SJID, error) -> error; (SJID, USs) -> case SJID of "@all@" -> USs; "@online@" -> USs; _ -> case jlib:string_to_jid(SJID) of JID when is_record(JID, jid) -> [{JID#jid.luser, JID#jid.lserver} | USs]; error -> error end end end, [], SJIDs), AllUsersOpt = case lists:member("@all@", SJIDs) of true -> [{all_users, true}]; false -> [] end, OnlineUsersOpt = case lists:member("@online@", SJIDs) of true -> [{online_users, true}]; false -> [] end, ?MODULE:set_group_opts( Host, Group, NameOpt ++ DispGroupsOpt ++ DescriptionOpt ++ AllUsersOpt ++ OnlineUsersOpt), if NewMembers == error -> error; true -> AddedMembers = NewMembers -- OldMembers, RemovedMembers = OldMembers -- NewMembers, lists:foreach( fun(US) -> ?MODULE:remove_user_from_group( Host, US, Group) end, RemovedMembers), lists:foreach( fun(US) -> ?MODULE:add_user_to_group( Host, US, Group) end, AddedMembers), ok end; _ -> nothing end. %% Get the roster module for Server. get_roster_mod(Server) -> case lists:member(mod_roster_odbc, gen_mod:loaded_modules(Server)) of true -> mod_roster_odbc; false -> mod_roster end. get_opt(Opts, Opt, Default) -> case lists:keysearch(Opt, 1, Opts) of {value, {_, Val}} -> Val; false -> Default end. us_to_list({User, Server}) -> jlib:jid_to_string({User, Server, ""}). split_grouphost(Host, Group) -> case string:tokens(Group, "@") of [GroupName, HostName] -> {HostName, GroupName}; [_] -> {Host, Group} end. make_jid_s(U, S) -> ejabberd_odbc:escape( jlib:jid_to_string( jlib:jid_tolower( jlib:make_jid(U, S, "")))). make_jid_s({U, S}) -> make_jid_s(U, S). ejabberd-2.1.11/src/mod_shared_roster.erl0000664000000000000000000010536212240230175015223 0ustar %%%---------------------------------------------------------------------- %%% File : mod_shared_roster.erl %%% Author : Alexey Shchepin %%% Purpose : Shared roster management %%% Created : 5 Mar 2005 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_shared_roster). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, item_to_xml/1, webadmin_menu/3, webadmin_page/3, get_user_roster/2, get_subscription_lists/3, get_jid_info/4, process_item/2, in_subscription/6, out_subscription/4, user_available/1, unset_presence/4, register_user/2, remove_user/2, list_groups/1, create_group/2, create_group/3, delete_group/2, get_group_opts/2, set_group_opts/3, get_group_users/2, get_group_explicit_users/2, is_user_in_group/3, add_user_to_group/3, remove_user_from_group/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_roster.hrl"). -include("web/ejabberd_http.hrl"). -include("web/ejabberd_web_admin.hrl"). -record(sr_group, {group_host, opts}). -record(sr_user, {us, group_host}). start(Host, _Opts) -> mnesia:create_table(sr_group, [{disc_copies, [node()]}, {attributes, record_info(fields, sr_group)}]), mnesia:create_table(sr_user, [{disc_copies, [node()]}, {type, bag}, {attributes, record_info(fields, sr_user)}]), mnesia:add_table_index(sr_user, group_host), ejabberd_hooks:add(webadmin_menu_host, Host, ?MODULE, webadmin_menu, 70), ejabberd_hooks:add(webadmin_page_host, Host, ?MODULE, webadmin_page, 50), ejabberd_hooks:add(roster_get, Host, ?MODULE, get_user_roster, 70), ejabberd_hooks:add(roster_in_subscription, Host, ?MODULE, in_subscription, 30), ejabberd_hooks:add(roster_out_subscription, Host, ?MODULE, out_subscription, 30), ejabberd_hooks:add(roster_get_subscription_lists, Host, ?MODULE, get_subscription_lists, 70), ejabberd_hooks:add(roster_get_jid_info, Host, ?MODULE, get_jid_info, 70), ejabberd_hooks:add(roster_process_item, Host, ?MODULE, process_item, 50), ejabberd_hooks:add(user_available_hook, Host, ?MODULE, user_available, 50), ejabberd_hooks:add(unset_presence_hook, Host, ?MODULE, unset_presence, 50), ejabberd_hooks:add(register_user, Host, ?MODULE, register_user, 50), ejabberd_hooks:add(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50). %%ejabberd_hooks:add(remove_user, Host, %% ?MODULE, remove_user, 50), stop(Host) -> ejabberd_hooks:delete(webadmin_menu_host, Host, ?MODULE, webadmin_menu, 70), ejabberd_hooks:delete(webadmin_page_host, Host, ?MODULE, webadmin_page, 50), ejabberd_hooks:delete(roster_get, Host, ?MODULE, get_user_roster, 70), ejabberd_hooks:delete(roster_in_subscription, Host, ?MODULE, in_subscription, 30), ejabberd_hooks:delete(roster_out_subscription, Host, ?MODULE, out_subscription, 30), ejabberd_hooks:delete(roster_get_subscription_lists, Host, ?MODULE, get_subscription_lists, 70), ejabberd_hooks:delete(roster_get_jid_info, Host, ?MODULE, get_jid_info, 70), ejabberd_hooks:delete(roster_process_item, Host, ?MODULE, process_item, 50), ejabberd_hooks:delete(user_available_hook, Host, ?MODULE, user_available, 50), ejabberd_hooks:delete(unset_presence_hook, Host, ?MODULE, unset_presence, 50), ejabberd_hooks:delete(register_user, Host, ?MODULE, register_user, 50), ejabberd_hooks:delete(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50). %%ejabberd_hooks:delete(remove_user, Host, %% ?MODULE, remove_user, 50), get_user_roster(Items, US) -> {U, S} = US, DisplayedGroups = get_user_displayed_groups(US), %% Get shared roster users in all groups and remove self: SRUsers = lists:foldl( fun(Group, Acc1) -> GroupName = get_group_name(S, Group), lists:foldl( fun(User, Acc2) -> if User == US -> Acc2; true -> dict:append(User, GroupName, Acc2) end end, Acc1, get_group_users(S, Group)) end, dict:new(), DisplayedGroups), %% If partially subscribed users are also in shared roster, show them as %% totally subscribed: {NewItems1, SRUsersRest} = lists:mapfoldl( fun(Item, SRUsers1) -> {_, _, {U1, S1, _}} = Item#roster.usj, US1 = {U1, S1}, case dict:find(US1, SRUsers1) of {ok, _GroupNames} -> {Item#roster{subscription = both, ask = none}, dict:erase(US1, SRUsers1)}; error -> {Item, SRUsers1} end end, SRUsers, Items), %% Export items in roster format: ModVcard = get_vcard_module(S), SRItems = [#roster{usj = {U, S, {U1, S1, ""}}, us = US, jid = {U1, S1, ""}, name = get_rosteritem_name(ModVcard, U1, S1), subscription = both, ask = none, groups = GroupNames} || {{U1, S1}, GroupNames} <- dict:to_list(SRUsersRest)], SRItems ++ NewItems1. get_vcard_module(Server) -> Modules = gen_mod:loaded_modules(Server), [M || M <- Modules, (M == mod_vcard) or (M == mod_vcard_odbc) or (M == mod_vcard_ldap)]. get_rosteritem_name([], _, _) -> ""; get_rosteritem_name([ModVcard], U, S) -> From = jlib:make_jid("", S, ?MODULE), To = jlib:make_jid(U, S, ""), IQ = {iq,"",get,"vcard-temp","", {xmlelement,"vCard",[{"xmlns","vcard-temp"}],[]}}, IQ_Vcard = ModVcard:process_sm_iq(From, To, IQ), try get_rosteritem_name_vcard(IQ_Vcard#iq.sub_el) catch E1:E2 -> ?ERROR_MSG("Error ~p found when trying to get the vCard of ~s@~s " "in ~p:~n ~p", [E1, U, S, ModVcard, E2]), "" end. get_rosteritem_name_vcard([]) -> ""; get_rosteritem_name_vcard([Vcard]) -> case xml:get_path_s(Vcard, [{elem, "NICKNAME"}, cdata]) of "" -> xml:get_path_s(Vcard, [{elem, "FN"}, cdata]); Nickname -> Nickname end. %% This function rewrites the roster entries when moving or renaming %% them in the user contact list. process_item(RosterItem, Host) -> USFrom = {UserFrom, ServerFrom} = RosterItem#roster.us, {UserTo, ServerTo, ResourceTo} = RosterItem#roster.jid, NameTo = RosterItem#roster.name, USTo = {UserTo, ServerTo}, DisplayedGroups = get_user_displayed_groups(USFrom), CommonGroups = lists:filter(fun(Group) -> is_user_in_group(USTo, Group, Host) end, DisplayedGroups), case CommonGroups of [] -> RosterItem; %% Roster item cannot be removed: We simply reset the original groups: _ when RosterItem#roster.subscription == remove -> GroupNames = lists:map(fun(Group) -> get_group_name(Host, Group) end, CommonGroups), RosterItem#roster{subscription = both, ask = none, groups=[GroupNames]}; %% Both users have at least a common shared group, %% So each user can see the other _ -> %% Check if the list of groups of the new roster item %% include at least a new one case lists:subtract(RosterItem#roster.groups, CommonGroups) of %% If it doesn't, then remove this user from any %% existing roster groups. [] -> %% Remove pending subscription by setting it %% unsubscribed. Mod = get_roster_mod(ServerFrom), %% Remove pending out subscription Mod:out_subscription(UserTo, ServerTo, jlib:make_jid(UserFrom, ServerFrom, ""), unsubscribe), %% Remove pending in subscription Mod:in_subscription(aaaa, UserFrom, ServerFrom, jlib:make_jid(UserTo, ServerTo, ""), unsubscribe, ""), %% But we're still subscribed, so respond as such. RosterItem#roster{subscription = both, ask = none}; %% If so, it means the user wants to add that contact %% to his personal roster PersonalGroups -> %% Store roster items in From and To rosters set_new_rosteritems(UserFrom, ServerFrom, UserTo, ServerTo, ResourceTo, NameTo, PersonalGroups) end end. build_roster_record(User1, Server1, User2, Server2, Name2, Groups) -> USR2 = {User2, Server2, ""}, #roster{usj = {User1, Server1, USR2}, us = {User1, Server1}, jid = USR2, name = Name2, subscription = both, ask = none, groups = Groups }. set_new_rosteritems(UserFrom, ServerFrom, UserTo, ServerTo, ResourceTo, NameTo, GroupsFrom) -> Mod = get_roster_mod(ServerFrom), RIFrom = build_roster_record(UserFrom, ServerFrom, UserTo, ServerTo, NameTo, GroupsFrom), set_item(UserFrom, ServerFrom, ResourceTo, RIFrom), JIDTo = jlib:make_jid(UserTo, ServerTo, ""), JIDFrom = jlib:make_jid(UserFrom, ServerFrom, ""), RITo = build_roster_record(UserTo, ServerTo, UserFrom, ServerFrom, UserFrom,[]), set_item(UserTo, ServerTo, "", RITo), %% From requests Mod:out_subscription(UserFrom, ServerFrom, JIDTo, subscribe), Mod:in_subscription(aaa, UserTo, ServerTo, JIDFrom, subscribe, ""), %% To accepts Mod:out_subscription(UserTo, ServerTo, JIDFrom, subscribed), Mod:in_subscription(aaa, UserFrom, ServerFrom, JIDTo, subscribed, ""), %% To requests Mod:out_subscription(UserTo, ServerTo, JIDFrom, subscribe), Mod:in_subscription(aaa, UserFrom, ServerFrom, JIDTo, subscribe, ""), %% From accepts Mod:out_subscription(UserFrom, ServerFrom, JIDTo, subscribed), Mod:in_subscription(aaa, UserTo, ServerTo, JIDFrom, subscribed, ""), RIFrom. set_item(User, Server, Resource, Item) -> ResIQ = #iq{type = set, xmlns = ?NS_ROSTER, id = "push" ++ randoms:get_string(), sub_el = [{xmlelement, "query", [{"xmlns", ?NS_ROSTER}], [mod_roster:item_to_xml(Item)]}]}, ejabberd_router:route( jlib:make_jid(User, Server, Resource), jlib:make_jid("", Server, ""), jlib:iq_to_xml(ResIQ)). get_subscription_lists({F, T}, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, DisplayedGroups = get_user_displayed_groups(US), SRUsers = lists:usort( lists:flatmap( fun(Group) -> get_group_users(LServer, Group) end, DisplayedGroups)), SRJIDs = [{U1, S1, ""} || {U1, S1} <- SRUsers], {lists:usort(SRJIDs ++ F), lists:usort(SRJIDs ++ T)}. get_jid_info({Subscription, Groups}, User, Server, JID) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, {U1, S1, _} = jlib:jid_tolower(JID), US1 = {U1, S1}, DisplayedGroups = get_user_displayed_groups(US), SRUsers = lists:foldl( fun(Group, Acc1) -> lists:foldl( fun(User1, Acc2) -> dict:append( User1, get_group_name(LServer, Group), Acc2) end, Acc1, get_group_users(LServer, Group)) end, dict:new(), DisplayedGroups), case dict:find(US1, SRUsers) of {ok, GroupNames} -> NewGroups = if Groups == [] -> GroupNames; true -> Groups end, {both, NewGroups}; error -> {Subscription, Groups} end. in_subscription(Acc, User, Server, JID, Type, _Reason) -> process_subscription(in, User, Server, JID, Type, Acc). out_subscription(UserFrom, ServerFrom, JIDTo, unsubscribed) -> Mod = get_roster_mod(ServerFrom), %% Remove pending out subscription #jid{luser = UserTo, lserver = ServerTo} = JIDTo, JIDFrom = jlib:make_jid(UserFrom, UserTo, ""), Mod:out_subscription(UserTo, ServerTo, JIDFrom, unsubscribe), %% Remove pending in subscription Mod:in_subscription(aaaa, UserFrom, ServerFrom, JIDTo, unsubscribe, ""), process_subscription(out, UserFrom, ServerFrom, JIDTo, unsubscribed, false); out_subscription(User, Server, JID, Type) -> process_subscription(out, User, Server, JID, Type, false). process_subscription(Direction, User, Server, JID, _Type, Acc) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, {U1, S1, _} = jlib:jid_tolower(jlib:jid_remove_resource(JID)), US1 = {U1, S1}, DisplayedGroups = get_user_displayed_groups(US), SRUsers = lists:usort( lists:flatmap( fun(Group) -> get_group_users(LServer, Group) end, DisplayedGroups)), case lists:member(US1, SRUsers) of true -> case Direction of in -> {stop, false}; out -> stop end; false -> Acc end. list_groups(Host) -> mnesia:dirty_select( sr_group, [{#sr_group{group_host = {'$1', '$2'}, _ = '_'}, [{'==', '$2', Host}], ['$1']}]). groups_with_opts(Host) -> Gs = mnesia:dirty_select( sr_group, [{#sr_group{group_host={'$1', Host}, opts='$2', _='_'}, [], [['$1','$2']] }]), lists:map(fun([G,O]) -> {G, O} end, Gs). create_group(Host, Group) -> create_group(Host, Group, []). create_group(Host, Group, Opts) -> R = #sr_group{group_host = {Group, Host}, opts = Opts}, F = fun() -> mnesia:write(R) end, mnesia:transaction(F). delete_group(Host, Group) -> GroupHost = {Group, Host}, F = fun() -> %% Delete the group ... mnesia:delete({sr_group, GroupHost}), %% ... and its users Users = mnesia:index_read(sr_user, GroupHost, #sr_user.group_host), lists:foreach(fun(UserEntry) -> mnesia:delete_object(UserEntry) end, Users) end, mnesia:transaction(F). get_group_opts(Host, Group) -> case catch mnesia:dirty_read(sr_group, {Group, Host}) of [#sr_group{opts = Opts}] -> Opts; _ -> error end. set_group_opts(Host, Group, Opts) -> R = #sr_group{group_host = {Group, Host}, opts = Opts}, F = fun() -> mnesia:write(R) end, mnesia:transaction(F). get_user_groups(US) -> Host = element(2, US), case catch mnesia:dirty_read(sr_user, US) of Rs when is_list(Rs) -> [Group || #sr_user{group_host = {Group, H}} <- Rs, H == Host]; _ -> [] end ++ get_special_users_groups(Host). is_group_enabled(Host1, Group1) -> {Host, Group} = split_grouphost(Host1, Group1), case catch mnesia:dirty_read(sr_group, {Group, Host}) of [#sr_group{opts = Opts}] -> not lists:member(disabled, Opts); _ -> false end. %% @spec (Host::string(), Group::string(), Opt::atom(), Default) -> OptValue | Default get_group_opt(Host, Group, Opt, Default) -> case catch mnesia:dirty_read(sr_group, {Group, Host}) of [#sr_group{opts = Opts}] -> case lists:keysearch(Opt, 1, Opts) of {value, {_, Val}} -> Val; false -> Default end; _ -> Default end. get_online_users(Host) -> lists:usort([{U, S} || {U, S, _} <- ejabberd_sm:get_vh_session_list(Host)]). get_group_users(Host1, Group1) -> {Host, Group} = split_grouphost(Host1, Group1), case get_group_opt(Host, Group, all_users, false) of true -> ejabberd_auth:get_vh_registered_users(Host); false -> [] end ++ case get_group_opt(Host, Group, online_users, false) of true -> get_online_users(Host); false -> [] end ++ get_group_explicit_users(Host, Group). get_group_users(Host, Group, GroupOpts) -> case proplists:get_value(all_users, GroupOpts, false) of true -> ejabberd_auth:get_vh_registered_users(Host); false -> [] end ++ case proplists:get_value(online_users, GroupOpts, false) of true -> get_online_users(Host); false -> [] end ++ get_group_explicit_users(Host, Group). %% @spec (Host::string(), Group::string()) -> [{User::string(), Server::string()}] get_group_explicit_users(Host, Group) -> Read = (catch mnesia:dirty_index_read( sr_user, {Group, Host}, #sr_user.group_host)), case Read of Rs when is_list(Rs) -> [R#sr_user.us || R <- Rs]; _ -> [] end. get_group_name(Host1, Group1) -> {Host, Group} = split_grouphost(Host1, Group1), get_group_opt(Host, Group, name, Group). %% Get list of names of groups that have @all@/@online@/etc in the memberlist get_special_users_groups(Host) -> lists:filter( fun(Group) -> get_group_opt(Host, Group, all_users, false) orelse get_group_opt(Host, Group, online_users, false) end, list_groups(Host)). %% Get list of names of groups that have @online@ in the memberlist get_special_users_groups_online(Host) -> lists:filter( fun(Group) -> get_group_opt(Host, Group, online_users, false) end, list_groups(Host)). %% Given two lists of groupnames and their options, %% return the list of displayed groups to the second list displayed_groups(GroupsOpts, SelectedGroupsOpts) -> DisplayedGroups = lists:usort( lists:flatmap( fun({_Group, Opts}) -> [G || G <- proplists:get_value(displayed_groups, Opts, []), not lists:member(disabled, Opts)] end, SelectedGroupsOpts)), [G || G <- DisplayedGroups, not lists:member(disabled, proplists:get_value(G, GroupsOpts, []))]. %% Given a list of group names with options, %% for those that have @all@ in memberlist, %% get the list of groups displayed get_special_displayed_groups(GroupsOpts) -> Groups = lists:filter( fun({_Group, Opts}) -> proplists:get_value(all_users, Opts, false) end, GroupsOpts), displayed_groups(GroupsOpts, Groups). %% Given a username and server, and a list of group names with options, %% for the list of groups of that server that user is member %% get the list of groups displayed get_user_displayed_groups(LUser, LServer, GroupsOpts) -> Groups = case catch mnesia:dirty_read(sr_user, {LUser, LServer}) of Rs when is_list(Rs) -> [{Group, proplists:get_value(Group, GroupsOpts, [])} || #sr_user{group_host = {Group, H}} <- Rs, H == LServer]; _ -> [] end, displayed_groups(GroupsOpts, Groups). %% @doc Get the list of groups that are displayed to this user get_user_displayed_groups(US) -> Host = element(2, US), DisplayedGroups1 = lists:usort( lists:flatmap( fun(Group) -> case is_group_enabled(Host, Group) of true -> get_group_opt(Host, Group, displayed_groups, []); false -> [] end end, get_user_groups(US))), [Group || Group <- DisplayedGroups1, is_group_enabled(Host, Group)]. is_user_in_group(US, Group, Host) -> case catch mnesia:dirty_match_object( #sr_user{us=US, group_host={Group, Host}}) of [] -> lists:member(US, get_group_users(Host, Group)); _ -> true end. %% @spec (Host::string(), {User::string(), Server::string()}, Group::string()) -> {atomic, ok} add_user_to_group(Host, US, Group) -> {LUser, LServer} = US, case ejabberd_regexp:run(LUser, "^@.+@$") of match -> GroupOpts = ?MODULE:get_group_opts(Host, Group), MoreGroupOpts = case LUser of "@all@" -> [{all_users, true}]; "@online@" -> [{online_users, true}]; _ -> [] end, ?MODULE:set_group_opts( Host, Group, GroupOpts ++ MoreGroupOpts); nomatch -> %% Push this new user to members of groups where this group is displayed push_user_to_displayed(LUser, LServer, Group, Host, both), %% Push members of groups that are displayed to this group push_displayed_to_user(LUser, LServer, Group, Host, both), R = #sr_user{us = US, group_host = {Group, Host}}, F = fun() -> mnesia:write(R) end, mnesia:transaction(F) end. push_displayed_to_user(LUser, LServer, Group, Host, Subscription) -> GroupsOpts = groups_with_opts(LServer), GroupOpts = proplists:get_value(Group, GroupsOpts, []), DisplayedGroups = proplists:get_value(displayed_groups, GroupOpts, []), [push_members_to_user(LUser, LServer, DGroup, Host, Subscription) || DGroup <- DisplayedGroups]. remove_user_from_group(Host, US, Group) -> GroupHost = {Group, Host}, {LUser, LServer} = US, case ejabberd_regexp:run(LUser, "^@.+@$") of match -> GroupOpts = ?MODULE:get_group_opts(Host, Group), NewGroupOpts = case LUser of "@all@" -> lists:filter(fun(X) -> X/={all_users,true} end, GroupOpts); "@online@" -> lists:filter(fun(X) -> X/={online_users,true} end, GroupOpts) end, ?MODULE:set_group_opts(Host, Group, NewGroupOpts); nomatch -> R = #sr_user{us = US, group_host = GroupHost}, F = fun() -> mnesia:delete_object(R) end, Result = mnesia:transaction(F), %% Push removal of the old user to members of groups where the group that this user was members was displayed push_user_to_displayed(LUser, LServer, Group, Host, remove), %% Push removal of members of groups that where displayed to the group which this user has left push_displayed_to_user(LUser, LServer, Group, Host, remove), Result end. push_members_to_user(LUser, LServer, Group, Host, Subscription) -> GroupsOpts = groups_with_opts(LServer), GroupOpts = proplists:get_value(Group, GroupsOpts, []), GroupName = proplists:get_value(name, GroupOpts, Group), Members = get_group_users(Host, Group), lists:foreach( fun({U, S}) -> push_roster_item(LUser, LServer, U, S, GroupName, Subscription) end, Members). register_user(User, Server) -> %% Get list of groups where this user is member Groups = get_user_groups({User, Server}), %% Push this user to members of groups where is displayed a group which this user is member [push_user_to_displayed(User, Server, Group, Server, both) || Group <- Groups]. remove_user(User, Server) -> push_user_to_members(User, Server, remove). push_user_to_members(User, Server, Subscription) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), GroupsOpts = groups_with_opts(LServer), SpecialGroups = get_special_displayed_groups(GroupsOpts), UserGroups = get_user_displayed_groups(LUser, LServer, GroupsOpts), lists:foreach( fun(Group) -> remove_user_from_group(LServer, {LUser, LServer}, Group), GroupOpts = proplists:get_value(Group, GroupsOpts, []), GroupName = proplists:get_value(name, GroupOpts, Group), lists:foreach( fun({U, S}) -> push_roster_item(U, S, LUser, LServer, GroupName, Subscription) end, get_group_users(LServer, Group, GroupOpts)) end, lists:usort(SpecialGroups++UserGroups)). push_user_to_displayed(LUser, LServer, Group, Host, Subscription) -> GroupsOpts = groups_with_opts(Host), GroupOpts = proplists:get_value(Group, GroupsOpts, []), GroupName = proplists:get_value(name, GroupOpts, Group), DisplayedToGroupsOpts = displayed_to_groups(Group, Host), [push_user_to_group(LUser, LServer, GroupD, Host, GroupName, Subscription) || {GroupD, _Opts} <- DisplayedToGroupsOpts]. push_user_to_group(LUser, LServer, Group, Host, GroupName, Subscription) -> lists:foreach( fun({U, S}) when (U == LUser) and (S == LServer) -> ok; ({U, S}) -> push_roster_item(U, S, LUser, LServer, GroupName, Subscription) end, get_group_users(Host, Group)). %% Get list of groups to which this group is displayed displayed_to_groups(GroupName, LServer) -> GroupsOpts = groups_with_opts(LServer), lists:filter( fun({_Group, Opts}) -> lists:member(GroupName, proplists:get_value(displayed_groups, Opts, [])) end, GroupsOpts). push_item(User, Server, From, Item) -> %% It was %% ejabberd_sm:route(jlib:make_jid("", "", ""), %% jlib:make_jid(User, Server, "") %% why? ejabberd_sm:route(From, jlib:make_jid(User, Server, ""), {xmlelement, "broadcast", [], [{item, Item#roster.jid, Item#roster.subscription}]}), Stanza = jlib:iq_to_xml( #iq{type = set, xmlns = ?NS_ROSTER, id = "push" ++ randoms:get_string(), sub_el = [{xmlelement, "query", [{"xmlns", ?NS_ROSTER}], [item_to_xml(Item)]}]}), lists:foreach( fun(Resource) -> JID = jlib:make_jid(User, Server, Resource), ejabberd_router:route(JID, JID, Stanza) end, ejabberd_sm:get_user_resources(User, Server)). push_roster_item(User, Server, ContactU, ContactS, GroupName, Subscription) -> Item = #roster{usj = {User, Server, {ContactU, ContactS, ""}}, us = {User, Server}, jid = {ContactU, ContactS, ""}, name = "", subscription = Subscription, ask = none, groups = [GroupName]}, push_item(User, Server, jlib:make_jid("", Server, ""), Item). item_to_xml(Item) -> Attrs1 = [{"jid", jlib:jid_to_string(Item#roster.jid)}], Attrs2 = case Item#roster.name of "" -> Attrs1; Name -> [{"name", Name} | Attrs1] end, Attrs3 = case Item#roster.subscription of none -> [{"subscription", "none"} | Attrs2]; from -> [{"subscription", "from"} | Attrs2]; to -> [{"subscription", "to"} | Attrs2]; both -> [{"subscription", "both"} | Attrs2]; remove -> [{"subscription", "remove"} | Attrs2] end, Attrs4 = case ask_to_pending(Item#roster.ask) of out -> [{"ask", "subscribe"} | Attrs3]; both -> [{"ask", "subscribe"} | Attrs3]; _ -> Attrs3 end, SubEls1 = lists:map(fun(G) -> {xmlelement, "group", [], [{xmlcdata, G}]} end, Item#roster.groups), SubEls = SubEls1 ++ Item#roster.xs, {xmlelement, "item", Attrs4, SubEls}. ask_to_pending(subscribe) -> out; ask_to_pending(unsubscribe) -> none; ask_to_pending(Ask) -> Ask. user_available(New) -> LUser = New#jid.luser, LServer = New#jid.lserver, Resources = ejabberd_sm:get_user_resources(LUser, LServer), ?DEBUG("user_available for ~p @ ~p (~p resources)", [LUser, LServer, length(Resources)]), case length(Resources) of %% first session for this user 1 -> %% This is a simplification - we ignore he 'display' %% property - @online@ is always reflective. OnlineGroups = get_special_users_groups_online(LServer), lists:foreach( fun(OG) -> ?DEBUG("user_available: pushing ~p @ ~p grp ~p", [LUser, LServer, OG ]), push_user_to_displayed(LUser, LServer, OG, LServer, both) end, OnlineGroups); _ -> ok end. unset_presence(LUser, LServer, Resource, Status) -> Resources = ejabberd_sm:get_user_resources(LUser, LServer), ?DEBUG("unset_presence for ~p @ ~p / ~p -> ~p (~p resources)", [LUser, LServer, Resource, Status, length(Resources)]), %% if user has no resources left... case length(Resources) of 0 -> %% This is a simplification - we ignore he 'display' %% property - @online@ is always reflective. OnlineGroups = get_special_users_groups_online(LServer), %% for each of these groups... lists:foreach( fun(OG) -> %% Push removal of the old user to members of groups %% where the group that this uwas members was displayed push_user_to_displayed(LUser, LServer, OG, LServer, remove), %% Push removal of members of groups that where %% displayed to the group which thiuser has left push_displayed_to_user(LUser, LServer, OG, LServer,remove) end, OnlineGroups); _ -> ok end. %%--------------------- %% Web Admin %%--------------------- webadmin_menu(Acc, _Host, Lang) -> [{"shared-roster", ?T("Shared Roster Groups")} | Acc]. webadmin_page(_, Host, #request{us = _US, path = ["shared-roster"], q = Query, lang = Lang} = _Request) -> Res = list_shared_roster_groups(Host, Query, Lang), {stop, Res}; webadmin_page(_, Host, #request{us = _US, path = ["shared-roster", Group], q = Query, lang = Lang} = _Request) -> Res = shared_roster_group(Host, Group, Query, Lang), {stop, Res}; webadmin_page(Acc, _, _) -> Acc. list_shared_roster_groups(Host, Query, Lang) -> Res = list_sr_groups_parse_query(Host, Query), SRGroups = ?MODULE:list_groups(Host), FGroups = ?XAE("table", [], [?XE("tbody", lists:map( fun(Group) -> ?XE("tr", [?XE("td", [?INPUT("checkbox", "selected", Group)]), ?XE("td", [?AC(Group ++ "/", Group)]) ] ) end, lists:sort(SRGroups)) ++ [?XE("tr", [?X("td"), ?XE("td", [?INPUT("text", "namenew", "")]), ?XE("td", [?INPUTT("submit", "addnew", "Add New")]) ] )] )]), ?H1GL(?T("Shared Roster Groups"), "modsharedroster", "mod_shared_roster") ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [FGroups, ?BR, ?INPUTT("submit", "delete", "Delete Selected") ]) ]. list_sr_groups_parse_query(Host, Query) -> case lists:keysearch("addnew", 1, Query) of {value, _} -> list_sr_groups_parse_addnew(Host, Query); _ -> case lists:keysearch("delete", 1, Query) of {value, _} -> list_sr_groups_parse_delete(Host, Query); _ -> nothing end end. list_sr_groups_parse_addnew(Host, Query) -> case lists:keysearch("namenew", 1, Query) of {value, {_, Group}} when Group /= "" -> ?MODULE:create_group(Host, Group), ok; _ -> error end. list_sr_groups_parse_delete(Host, Query) -> SRGroups = ?MODULE:list_groups(Host), lists:foreach( fun(Group) -> case lists:member({"selected", Group}, Query) of true -> ?MODULE:delete_group(Host, Group); _ -> ok end end, SRGroups), ok. shared_roster_group(Host, Group, Query, Lang) -> Res = shared_roster_group_parse_query(Host, Group, Query), GroupOpts = ?MODULE:get_group_opts(Host, Group), Name = get_opt(GroupOpts, name, ""), Description = get_opt(GroupOpts, description, ""), AllUsers = get_opt(GroupOpts, all_users, false), OnlineUsers = get_opt(GroupOpts, online_users, false), %%Disabled = false, DisplayedGroups = get_opt(GroupOpts, displayed_groups, []), Members = ?MODULE:get_group_explicit_users(Host, Group), FMembers = if AllUsers -> "@all@\n"; true -> [] end ++ if OnlineUsers -> "@online@\n"; true -> [] end ++ [[us_to_list(Member), $\n] || Member <- Members], FDisplayedGroups = [[DG, $\n] || DG <- DisplayedGroups], DescNL = length(ejabberd_regexp:split(Description, "\n")), FGroup = ?XAE("table", [{"class", "withtextareas"}], [?XE("tbody", [?XE("tr", [?XCT("td", "Name:"), ?XE("td", [?INPUT("text", "name", Name)]) ] ), ?XE("tr", [?XCT("td", "Description:"), ?XE("td", [ ?TEXTAREA("description", integer_to_list(lists:max([3, DescNL])), "20", Description) ] ) ] ), ?XE("tr", [?XCT("td", "Members:"), ?XE("td", [ ?TEXTAREA("members", integer_to_list(lists:max([3, length(FMembers)])), "20", FMembers) ] ) ] ), ?XE("tr", [?XCT("td", "Displayed Groups:"), ?XE("td", [ ?TEXTAREA("dispgroups", integer_to_list(lists:max([3, length(FDisplayedGroups)])), "20", FDisplayedGroups) ] ) ] )] )]), ?H1GL(?T("Shared Roster Groups"), "modsharedroster", "mod_shared_roster") ++ [?XC("h2", ?T("Group ") ++ Group)] ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [FGroup, ?BR, ?INPUTT("submit", "submit", "Submit") ]) ]. shared_roster_group_parse_query(Host, Group, Query) -> case lists:keysearch("submit", 1, Query) of {value, _} -> {value, {_, Name}} = lists:keysearch("name", 1, Query), {value, {_, Description}} = lists:keysearch("description", 1, Query), {value, {_, SMembers}} = lists:keysearch("members", 1, Query), {value, {_, SDispGroups}} = lists:keysearch("dispgroups", 1, Query), NameOpt = if Name == "" -> []; true -> [{name, Name}] end, DescriptionOpt = if Description == "" -> []; true -> [{description, Description}] end, DispGroups = string:tokens(SDispGroups, "\r\n"), DispGroupsOpt = if DispGroups == [] -> []; true -> [{displayed_groups, DispGroups}] end, OldMembers = ?MODULE:get_group_explicit_users( Host, Group), SJIDs = string:tokens(SMembers, ", \r\n"), NewMembers = lists:foldl( fun(_SJID, error) -> error; (SJID, USs) -> case SJID of "@all@" -> USs; "@online@" -> USs; _ -> case jlib:string_to_jid(SJID) of JID when is_record(JID, jid) -> [{JID#jid.luser, JID#jid.lserver} | USs]; error -> error end end end, [], SJIDs), AllUsersOpt = case lists:member("@all@", SJIDs) of true -> [{all_users, true}]; false -> [] end, OnlineUsersOpt = case lists:member("@online@", SJIDs) of true -> [{online_users, true}]; false -> [] end, ?MODULE:set_group_opts( Host, Group, NameOpt ++ DispGroupsOpt ++ DescriptionOpt ++ AllUsersOpt ++ OnlineUsersOpt), if NewMembers == error -> error; true -> AddedMembers = NewMembers -- OldMembers, RemovedMembers = OldMembers -- NewMembers, lists:foreach( fun(US) -> ?MODULE:remove_user_from_group( Host, US, Group) end, RemovedMembers), lists:foreach( fun(US) -> ?MODULE:add_user_to_group( Host, US, Group) end, AddedMembers), ok end; _ -> nothing end. %% Get the roster module for Server. get_roster_mod(Server) -> case lists:member(mod_roster_odbc, gen_mod:loaded_modules(Server)) of true -> mod_roster_odbc; false -> mod_roster end. get_opt(Opts, Opt, Default) -> case lists:keysearch(Opt, 1, Opts) of {value, {_, Val}} -> Val; false -> Default end. us_to_list({User, Server}) -> jlib:jid_to_string({User, Server, ""}). split_grouphost(Host, Group) -> case string:tokens(Group, "@") of [GroupName, HostName] -> {HostName, GroupName}; [_] -> {Host, Group} end. ejabberd-2.1.11/src/p1_fsm.erl0000664000000000000000000007020112240230175012676 0ustar %% ``The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved via the world wide web at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB. %% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings %% AB. All Rights Reserved.'' %% %% The code has been modified and improved by ProcessOne. %% Copyright 2007-2012, ProcessOne %% %% The change adds the following features: %% - You can send exit(priority_shutdown) to the p1_fsm process to %% terminate immediatetly. If the fsm trap_exit process flag has been %% set to true, the FSM terminate function will called. %% - You can pass the gen_fsm options to control resource usage. %% {max_queue, N} will exit the process with priority_shutdown %% - You can limit the time processing a message (TODO): If the %% message processing does not return in a given period of time, the %% process will be terminated. %% - You might customize the State data before sending it to error_logger %% in case of a crash (just export the function print_state/1) %% $Id$ %% -module(p1_fsm). %%%----------------------------------------------------------------- %%% %%% This state machine is somewhat more pure than state_lib. It is %%% still based on State dispatching (one function per state), but %%% allows a function handle_event to take care of events in all states. %%% It's not that pure anymore :( We also allow synchronized event sending. %%% %%% If the Parent process terminates the Module:terminate/2 %%% function is called. %%% %%% The user module should export: %%% %%% init(Args) %%% ==> {ok, StateName, StateData} %%% {ok, StateName, StateData, Timeout} %%% ignore %%% {stop, Reason} %%% %%% StateName(Msg, StateData) %%% %%% ==> {next_state, NewStateName, NewStateData} %%% {next_state, NewStateName, NewStateData, Timeout} %%% {stop, Reason, NewStateData} %%% Reason = normal | shutdown | Term terminate(State) is called %%% %%% StateName(Msg, From, StateData) %%% %%% ==> {next_state, NewStateName, NewStateData} %%% {next_state, NewStateName, NewStateData, Timeout} %%% {reply, Reply, NewStateName, NewStateData} %%% {reply, Reply, NewStateName, NewStateData, Timeout} %%% {stop, Reason, NewStateData} %%% Reason = normal | shutdown | Term terminate(State) is called %%% %%% handle_event(Msg, StateName, StateData) %%% %%% ==> {next_state, NewStateName, NewStateData} %%% {next_state, NewStateName, NewStateData, Timeout} %%% {stop, Reason, Reply, NewStateData} %%% {stop, Reason, NewStateData} %%% Reason = normal | shutdown | Term terminate(State) is called %%% %%% handle_sync_event(Msg, From, StateName, StateData) %%% %%% ==> {next_state, NewStateName, NewStateData} %%% {next_state, NewStateName, NewStateData, Timeout} %%% {reply, Reply, NewStateName, NewStateData} %%% {reply, Reply, NewStateName, NewStateData, Timeout} %%% {stop, Reason, Reply, NewStateData} %%% {stop, Reason, NewStateData} %%% Reason = normal | shutdown | Term terminate(State) is called %%% %%% handle_info(Info, StateName) (e.g. {'EXIT', P, R}, {nodedown, N}, ... %%% %%% ==> {next_state, NewStateName, NewStateData} %%% {next_state, NewStateName, NewStateData, Timeout} %%% {stop, Reason, NewStateData} %%% Reason = normal | shutdown | Term terminate(State) is called %%% %%% terminate(Reason, StateName, StateData) Let the user module clean up %%% always called when server terminates %%% %%% ==> the return value is ignored %%% %%% %%% The work flow (of the fsm) can be described as follows: %%% %%% User module fsm %%% ----------- ------- %%% start -----> start %%% init <----- . %%% %%% loop %%% StateName <----- . %%% %%% handle_event <----- . %%% %%% handle__sunc_event <----- . %%% %%% handle_info <----- . %%% %%% terminate <----- . %%% %%% %%% --------------------------------------------------- -export([start/3, start/4, start_link/3, start_link/4, send_event/2, sync_send_event/2, sync_send_event/3, send_all_state_event/2, sync_send_all_state_event/2, sync_send_all_state_event/3, reply/2, start_timer/2,send_event_after/2,cancel_timer/1, enter_loop/4, enter_loop/5, enter_loop/6, wake_hib/7]). -export([behaviour_info/1]). %% Internal exports -export([init_it/6, print_event/3, system_continue/3, system_terminate/4, system_code_change/4, format_status/2]). -import(error_logger , [format/2]). %%% Internal gen_fsm state %%% This state is used to defined resource control values: -record(limits, {max_queue}). %%% --------------------------------------------------- %%% Interface functions. %%% --------------------------------------------------- behaviour_info(callbacks) -> [{init,1},{handle_event,3},{handle_sync_event,4},{handle_info,3}, {terminate,3},{code_change,4}, {print_state,1}]; behaviour_info(_Other) -> undefined. %%% --------------------------------------------------- %%% Starts a generic state machine. %%% start(Mod, Args, Options) %%% start(Name, Mod, Args, Options) %%% start_link(Mod, Args, Options) %%% start_link(Name, Mod, Args, Options) where: %%% Name ::= {local, atom()} | {global, atom()} %%% Mod ::= atom(), callback module implementing the 'real' fsm %%% Args ::= term(), init arguments (to Mod:init/1) %%% Options ::= [{debug, [Flag]}] %%% Flag ::= trace | log | {logfile, File} | statistics | debug %%% (debug == log && statistics) %%% Returns: {ok, Pid} | %%% {error, {already_started, Pid}} | %%% {error, Reason} %%% --------------------------------------------------- start(Mod, Args, Options) -> gen:start(?MODULE, nolink, Mod, Args, Options). start(Name, Mod, Args, Options) -> gen:start(?MODULE, nolink, Name, Mod, Args, Options). start_link(Mod, Args, Options) -> gen:start(?MODULE, link, Mod, Args, Options). start_link(Name, Mod, Args, Options) -> gen:start(?MODULE, link, Name, Mod, Args, Options). send_event({global, Name}, Event) -> catch global:send(Name, {'$gen_event', Event}), ok; send_event(Name, Event) -> Name ! {'$gen_event', Event}, ok. sync_send_event(Name, Event) -> case catch gen:call(Name, '$gen_sync_event', Event) of {ok,Res} -> Res; {'EXIT',Reason} -> exit({Reason, {?MODULE, sync_send_event, [Name, Event]}}) end. sync_send_event(Name, Event, Timeout) -> case catch gen:call(Name, '$gen_sync_event', Event, Timeout) of {ok,Res} -> Res; {'EXIT',Reason} -> exit({Reason, {?MODULE, sync_send_event, [Name, Event, Timeout]}}) end. send_all_state_event({global, Name}, Event) -> catch global:send(Name, {'$gen_all_state_event', Event}), ok; send_all_state_event(Name, Event) -> Name ! {'$gen_all_state_event', Event}, ok. sync_send_all_state_event(Name, Event) -> case catch gen:call(Name, '$gen_sync_all_state_event', Event) of {ok,Res} -> Res; {'EXIT',Reason} -> exit({Reason, {?MODULE, sync_send_all_state_event, [Name, Event]}}) end. sync_send_all_state_event(Name, Event, Timeout) -> case catch gen:call(Name, '$gen_sync_all_state_event', Event, Timeout) of {ok,Res} -> Res; {'EXIT',Reason} -> exit({Reason, {?MODULE, sync_send_all_state_event, [Name, Event, Timeout]}}) end. %% Designed to be only callable within one of the callbacks %% hence using the self() of this instance of the process. %% This is to ensure that timers don't go astray in global %% e.g. when straddling a failover, or turn up in a restarted %% instance of the process. %% Returns Ref, sends event {timeout,Ref,Msg} after Time %% to the (then) current state. start_timer(Time, Msg) -> erlang:start_timer(Time, self(), {'$gen_timer', Msg}). %% Returns Ref, sends Event after Time to the (then) current state. send_event_after(Time, Event) -> erlang:start_timer(Time, self(), {'$gen_event', Event}). %% Returns the remaing time for the timer if Ref referred to %% an active timer/send_event_after, false otherwise. cancel_timer(Ref) -> case erlang:cancel_timer(Ref) of false -> receive {timeout, Ref, _} -> 0 after 0 -> false end; RemainingTime -> RemainingTime end. %% enter_loop/4,5,6 %% Makes an existing process into a gen_fsm. %% The calling process will enter the gen_fsm receive loop and become a %% gen_fsm process. %% The process *must* have been started using one of the start functions %% in proc_lib, see proc_lib(3). %% The user is responsible for any initialization of the process, %% including registering a name for it. enter_loop(Mod, Options, StateName, StateData) -> enter_loop(Mod, Options, StateName, StateData, self(), infinity). enter_loop(Mod, Options, StateName, StateData, ServerName = {_,_}) -> enter_loop(Mod, Options, StateName, StateData, ServerName,infinity); enter_loop(Mod, Options, StateName, StateData, Timeout) -> enter_loop(Mod, Options, StateName, StateData, self(), Timeout). enter_loop(Mod, Options, StateName, StateData, ServerName, Timeout) -> Name = get_proc_name(ServerName), Parent = get_parent(), Debug = gen:debug_options(Options), Limits = limit_options(Options), Queue = queue:new(), QueueLen = 0, loop(Parent, Name, StateName, StateData, Mod, Timeout, Debug, Limits, Queue, QueueLen). get_proc_name(Pid) when is_pid(Pid) -> Pid; get_proc_name({local, Name}) -> case process_info(self(), registered_name) of {registered_name, Name} -> Name; {registered_name, _Name} -> exit(process_not_registered); [] -> exit(process_not_registered) end; get_proc_name({global, Name}) -> case global:whereis_name(Name) of undefined -> exit(process_not_registered_globally); Pid when Pid==self() -> Name; _Pid -> exit(process_not_registered_globally) end. get_parent() -> case get('$ancestors') of [Parent | _] when is_pid(Parent) -> Parent; [Parent | _] when is_atom(Parent) -> name_to_pid(Parent); _ -> exit(process_was_not_started_by_proc_lib) end. name_to_pid(Name) -> case whereis(Name) of undefined -> case global:whereis_name(Name) of undefined -> exit(could_not_find_registerd_name); Pid -> Pid end; Pid -> Pid end. %%% --------------------------------------------------- %%% Initiate the new process. %%% Register the name using the Rfunc function %%% Calls the Mod:init/Args function. %%% Finally an acknowledge is sent to Parent and the main %%% loop is entered. %%% --------------------------------------------------- init_it(Starter, self, Name, Mod, Args, Options) -> init_it(Starter, self(), Name, Mod, Args, Options); init_it(Starter, Parent, Name0, Mod, Args, Options) -> Name = name(Name0), Debug = gen:debug_options(Options), Limits = limit_options(Options), Queue = queue:new(), QueueLen = 0, case catch Mod:init(Args) of {ok, StateName, StateData} -> proc_lib:init_ack(Starter, {ok, self()}), loop(Parent, Name, StateName, StateData, Mod, infinity, Debug, Limits, Queue, QueueLen); {ok, StateName, StateData, Timeout} -> proc_lib:init_ack(Starter, {ok, self()}), loop(Parent, Name, StateName, StateData, Mod, Timeout, Debug, Limits, Queue, QueueLen); {stop, Reason} -> proc_lib:init_ack(Starter, {error, Reason}), exit(Reason); ignore -> proc_lib:init_ack(Starter, ignore), exit(normal); {'EXIT', Reason} -> proc_lib:init_ack(Starter, {error, Reason}), exit(Reason); Else -> Error = {bad_return_value, Else}, proc_lib:init_ack(Starter, {error, Error}), exit(Error) end. name({local,Name}) -> Name; name({global,Name}) -> Name; name(Pid) when is_pid(Pid) -> Pid. %%----------------------------------------------------------------- %% The MAIN loop %%----------------------------------------------------------------- loop(Parent, Name, StateName, StateData, Mod, hibernate, Debug, Limits, Queue, QueueLen) when QueueLen > 0 -> case queue:out(Queue) of {{value, Msg}, Queue1} -> decode_msg(Msg, Parent, Name, StateName, StateData, Mod, hibernate, Debug, Limits, Queue1, QueueLen - 1, false); {empty, _} -> Reason = internal_queue_error, error_info(Mod, Reason, Name, hibernate, StateName, StateData, Debug), exit(Reason) end; loop(Parent, Name, StateName, StateData, Mod, hibernate, Debug, Limits, _Queue, _QueueLen) -> proc_lib:hibernate(?MODULE,wake_hib, [Parent, Name, StateName, StateData, Mod, Debug, Limits]); %% First we test if we have reach a defined limit ... loop(Parent, Name, StateName, StateData, Mod, Time, Debug, Limits, Queue, QueueLen) -> try message_queue_len(Limits, QueueLen) %% TODO: We can add more limit checking here... catch {process_limit, Limit} -> Reason = {process_limit, Limit}, Msg = {'EXIT', Parent, {error, {process_limit, Limit}}}, terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug) end, process_message(Parent, Name, StateName, StateData, Mod, Time, Debug, Limits, Queue, QueueLen). %% ... then we can process a new message: process_message(Parent, Name, StateName, StateData, Mod, Time, Debug, Limits, Queue, QueueLen) -> {Msg, Queue1, QueueLen1} = collect_messages(Queue, QueueLen, Time), decode_msg(Msg,Parent, Name, StateName, StateData, Mod, Time, Debug, Limits, Queue1, QueueLen1, false). collect_messages(Queue, QueueLen, Time) -> receive Input -> case Input of {'EXIT', _Parent, priority_shutdown} -> {Input, Queue, QueueLen}; _ -> collect_messages( queue:in(Input, Queue), QueueLen + 1, Time) end after 0 -> case queue:out(Queue) of {{value, Msg}, Queue1} -> {Msg, Queue1, QueueLen - 1}; {empty, _} -> receive Input -> {Input, Queue, QueueLen} after Time -> {{'$gen_event', timeout}, Queue, QueueLen} end end end. wake_hib(Parent, Name, StateName, StateData, Mod, Debug, Limits) -> Msg = receive Input -> Input end, Queue = queue:new(), QueueLen = 0, decode_msg(Msg, Parent, Name, StateName, StateData, Mod, hibernate, Debug, Limits, Queue, QueueLen, true). decode_msg(Msg,Parent, Name, StateName, StateData, Mod, Time, Debug, Limits, Queue, QueueLen, Hib) -> put('$internal_queue_len', QueueLen), case Msg of {system, From, Req} -> sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug, [Name, StateName, StateData, Mod, Time, Limits, Queue, QueueLen], Hib); {'EXIT', Parent, Reason} -> terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug); _Msg when Debug == [] -> handle_msg(Msg, Parent, Name, StateName, StateData, Mod, Time, Limits, Queue, QueueLen); _Msg -> Debug1 = sys:handle_debug(Debug, fun print_event/3, {Name, StateName}, {in, Msg}), handle_msg(Msg, Parent, Name, StateName, StateData, Mod, Time, Debug1, Limits, Queue, QueueLen) end. %%----------------------------------------------------------------- %% Callback functions for system messages handling. %%----------------------------------------------------------------- system_continue(Parent, Debug, [Name, StateName, StateData, Mod, Time, Limits, Queue, QueueLen]) -> loop(Parent, Name, StateName, StateData, Mod, Time, Debug, Limits, Queue, QueueLen). -spec system_terminate(term(), _, _, [term(),...]) -> no_return(). system_terminate(Reason, _Parent, Debug, [Name, StateName, StateData, Mod, _Time, _Limits]) -> terminate(Reason, Name, [], Mod, StateName, StateData, Debug). system_code_change([Name, StateName, StateData, Mod, Time, Limits, Queue, QueueLen], _Module, OldVsn, Extra) -> case catch Mod:code_change(OldVsn, StateName, StateData, Extra) of {ok, NewStateName, NewStateData} -> {ok, [Name, NewStateName, NewStateData, Mod, Time, Limits, Queue, QueueLen]}; Else -> Else end. %%----------------------------------------------------------------- %% Format debug messages. Print them as the call-back module sees %% them, not as the real erlang messages. Use trace for that. %%----------------------------------------------------------------- print_event(Dev, {in, Msg}, {Name, StateName}) -> case Msg of {'$gen_event', Event} -> io:format(Dev, "*DBG* ~p got event ~p in state ~w~n", [Name, Event, StateName]); {'$gen_all_state_event', Event} -> io:format(Dev, "*DBG* ~p got all_state_event ~p in state ~w~n", [Name, Event, StateName]); {timeout, Ref, {'$gen_timer', Message}} -> io:format(Dev, "*DBG* ~p got timer ~p in state ~w~n", [Name, {timeout, Ref, Message}, StateName]); {timeout, _Ref, {'$gen_event', Event}} -> io:format(Dev, "*DBG* ~p got timer ~p in state ~w~n", [Name, Event, StateName]); _ -> io:format(Dev, "*DBG* ~p got ~p in state ~w~n", [Name, Msg, StateName]) end; print_event(Dev, {out, Msg, To, StateName}, Name) -> io:format(Dev, "*DBG* ~p sent ~p to ~w~n" " and switched to state ~w~n", [Name, Msg, To, StateName]); print_event(Dev, return, {Name, StateName}) -> io:format(Dev, "*DBG* ~p switched to state ~w~n", [Name, StateName]). relay_messages(MRef, TRef, Clone, Queue) -> lists:foreach( fun(Msg) -> Clone ! Msg end, queue:to_list(Queue)), relay_messages(MRef, TRef, Clone). relay_messages(MRef, TRef, Clone) -> receive {'DOWN', MRef, process, Clone, Reason} -> Reason; {'EXIT', _Parent, _Reason} -> {migrated, Clone}; {timeout, TRef, timeout} -> {migrated, Clone}; Msg -> Clone ! Msg, relay_messages(MRef, TRef, Clone) end. handle_msg(Msg, Parent, Name, StateName, StateData, Mod, _Time, Limits, Queue, QueueLen) -> %No debug here From = from(Msg), case catch dispatch(Msg, Mod, StateName, StateData) of {next_state, NStateName, NStateData} -> loop(Parent, Name, NStateName, NStateData, Mod, infinity, [], Limits, Queue, QueueLen); {next_state, NStateName, NStateData, Time1} -> loop(Parent, Name, NStateName, NStateData, Mod, Time1, [], Limits, Queue, QueueLen); {reply, Reply, NStateName, NStateData} when From =/= undefined -> reply(From, Reply), loop(Parent, Name, NStateName, NStateData, Mod, infinity, [], Limits, Queue, QueueLen); {reply, Reply, NStateName, NStateData, Time1} when From =/= undefined -> reply(From, Reply), loop(Parent, Name, NStateName, NStateData, Mod, Time1, [], Limits, Queue, QueueLen); {migrate, NStateData, {Node, M, F, A}, Time1} -> Reason = case catch rpc:call(Node, M, F, A, 5000) of {badrpc, _} = Err -> {migration_error, Err}; {'EXIT', _} = Err -> {migration_error, Err}; {error, _} = Err -> {migration_error, Err}; {ok, Clone} -> process_flag(trap_exit, true), MRef = erlang:monitor(process, Clone), TRef = erlang:start_timer(Time1, self(), timeout), relay_messages(MRef, TRef, Clone, Queue); Reply -> {migration_error, {bad_reply, Reply}} end, terminate(Reason, Name, Msg, Mod, StateName, NStateData, []); {stop, Reason, NStateData} -> terminate(Reason, Name, Msg, Mod, StateName, NStateData, []); {stop, Reason, Reply, NStateData} when From =/= undefined -> {'EXIT', R} = (catch terminate(Reason, Name, Msg, Mod, StateName, NStateData, [])), reply(From, Reply), exit(R); {'EXIT', What} -> terminate(What, Name, Msg, Mod, StateName, StateData, []); Reply -> terminate({bad_return_value, Reply}, Name, Msg, Mod, StateName, StateData, []) end. handle_msg(Msg, Parent, Name, StateName, StateData, Mod, _Time, Debug, Limits, Queue, QueueLen) -> From = from(Msg), case catch dispatch(Msg, Mod, StateName, StateData) of {next_state, NStateName, NStateData} -> Debug1 = sys:handle_debug(Debug, fun print_event/3, {Name, NStateName}, return), loop(Parent, Name, NStateName, NStateData, Mod, infinity, Debug1, Limits, Queue, QueueLen); {next_state, NStateName, NStateData, Time1} -> Debug1 = sys:handle_debug(Debug, fun print_event/3, {Name, NStateName}, return), loop(Parent, Name, NStateName, NStateData, Mod, Time1, Debug1, Limits, Queue, QueueLen); {reply, Reply, NStateName, NStateData} when From =/= undefined -> Debug1 = reply(Name, From, Reply, Debug, NStateName), loop(Parent, Name, NStateName, NStateData, Mod, infinity, Debug1, Limits, Queue, QueueLen); {reply, Reply, NStateName, NStateData, Time1} when From =/= undefined -> Debug1 = reply(Name, From, Reply, Debug, NStateName), loop(Parent, Name, NStateName, NStateData, Mod, Time1, Debug1, Limits, Queue, QueueLen); {migrate, NStateData, {Node, M, F, A}, Time1} -> Reason = case catch rpc:call(Node, M, F, A, Time1) of {badrpc, R} -> {migration_error, R}; {'EXIT', R} -> {migration_error, R}; {error, R} -> {migration_error, R}; {ok, Clone} -> process_flag(trap_exit, true), MRef = erlang:monitor(process, Clone), TRef = erlang:start_timer(Time1, self(), timeout), relay_messages(MRef, TRef, Clone, Queue); Reply -> {migration_error, {bad_reply, Reply}} end, terminate(Reason, Name, Msg, Mod, StateName, NStateData, Debug); {stop, Reason, NStateData} -> terminate(Reason, Name, Msg, Mod, StateName, NStateData, Debug); {stop, Reason, Reply, NStateData} when From =/= undefined -> {'EXIT', R} = (catch terminate(Reason, Name, Msg, Mod, StateName, NStateData, Debug)), reply(Name, From, Reply, Debug, StateName), exit(R); {'EXIT', What} -> terminate(What, Name, Msg, Mod, StateName, StateData, Debug); Reply -> terminate({bad_return_value, Reply}, Name, Msg, Mod, StateName, StateData, Debug) end. dispatch({'$gen_event', Event}, Mod, StateName, StateData) -> Mod:StateName(Event, StateData); dispatch({'$gen_all_state_event', Event}, Mod, StateName, StateData) -> Mod:handle_event(Event, StateName, StateData); dispatch({'$gen_sync_event', From, Event}, Mod, StateName, StateData) -> Mod:StateName(Event, From, StateData); dispatch({'$gen_sync_all_state_event', From, Event}, Mod, StateName, StateData) -> Mod:handle_sync_event(Event, From, StateName, StateData); dispatch({timeout, Ref, {'$gen_timer', Msg}}, Mod, StateName, StateData) -> Mod:StateName({timeout, Ref, Msg}, StateData); dispatch({timeout, _Ref, {'$gen_event', Event}}, Mod, StateName, StateData) -> Mod:StateName(Event, StateData); dispatch(Info, Mod, StateName, StateData) -> Mod:handle_info(Info, StateName, StateData). from({'$gen_sync_event', From, _Event}) -> From; from({'$gen_sync_all_state_event', From, _Event}) -> From; from(_) -> undefined. %% Send a reply to the client. reply({To, Tag}, Reply) -> catch To ! {Tag, Reply}. reply(Name, {To, Tag}, Reply, Debug, StateName) -> reply({To, Tag}, Reply), sys:handle_debug(Debug, fun print_event/3, Name, {out, Reply, To, StateName}). %%% --------------------------------------------------- %%% Terminate the server. %%% --------------------------------------------------- -spec terminate(term(), _, _, atom(), _, _, _) -> no_return(). terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug) -> case catch Mod:terminate(Reason, StateName, StateData) of {'EXIT', R} -> error_info(Mod, R, Name, Msg, StateName, StateData, Debug), exit(R); _ -> case Reason of normal -> exit(normal); shutdown -> exit(shutdown); priority_shutdown -> %% Priority shutdown should be considered as %% shutdown by SASL exit(shutdown); {process_limit, _Limit} -> exit(Reason); {migrated, _Clone} -> exit(normal); _ -> error_info(Mod, Reason, Name, Msg, StateName, StateData, Debug), exit(Reason) end end. error_info(Mod, Reason, Name, Msg, StateName, StateData, Debug) -> Reason1 = case Reason of {undef,[{M,F,A}|MFAs]} -> case code:is_loaded(M) of false -> {'module could not be loaded',[{M,F,A}|MFAs]}; _ -> case erlang:function_exported(M, F, length(A)) of true -> Reason; false -> {'function not exported',[{M,F,A}|MFAs]} end end; _ -> Reason end, StateToPrint = case erlang:function_exported(Mod, print_state, 1) of true -> (catch Mod:print_state(StateData)); false -> StateData end, Str = "** State machine ~p terminating \n" ++ get_msg_str(Msg) ++ "** When State == ~p~n" "** Data == ~p~n" "** Reason for termination = ~n** ~p~n", format(Str, [Name, get_msg(Msg), StateName, StateToPrint, Reason1]), sys:print_log(Debug), ok. get_msg_str({'$gen_event', _Event}) -> "** Last event in was ~p~n"; get_msg_str({'$gen_sync_event', _Event}) -> "** Last sync event in was ~p~n"; get_msg_str({'$gen_all_state_event', _Event}) -> "** Last event in was ~p (for all states)~n"; get_msg_str({'$gen_sync_all_state_event', _Event}) -> "** Last sync event in was ~p (for all states)~n"; get_msg_str({timeout, _Ref, {'$gen_timer', _Msg}}) -> "** Last timer event in was ~p~n"; get_msg_str({timeout, _Ref, {'$gen_event', _Msg}}) -> "** Last timer event in was ~p~n"; get_msg_str(_Msg) -> "** Last message in was ~p~n". get_msg({'$gen_event', Event}) -> Event; get_msg({'$gen_sync_event', Event}) -> Event; get_msg({'$gen_all_state_event', Event}) -> Event; get_msg({'$gen_sync_all_state_event', Event}) -> Event; get_msg({timeout, Ref, {'$gen_timer', Msg}}) -> {timeout, Ref, Msg}; get_msg({timeout, _Ref, {'$gen_event', Event}}) -> Event; get_msg(Msg) -> Msg. %%----------------------------------------------------------------- %% Status information %%----------------------------------------------------------------- format_status(Opt, StatusData) -> [PDict, SysState, Parent, Debug, [Name, StateName, StateData, Mod, _Time]] = StatusData, NameTag = if is_pid(Name) -> pid_to_list(Name); is_atom(Name) -> Name end, Header = lists:concat(["Status for state machine ", NameTag]), Log = sys:get_debug(log, Debug, []), Specfic = case erlang:function_exported(Mod, format_status, 2) of true -> case catch Mod:format_status(Opt,[PDict,StateData]) of {'EXIT', _} -> [{data, [{"StateData", StateData}]}]; Else -> Else end; _ -> [{data, [{"StateData", StateData}]}] end, [{header, Header}, {data, [{"Status", SysState}, {"Parent", Parent}, {"Logged events", Log}, {"StateName", StateName}]} | Specfic]. %%----------------------------------------------------------------- %% Resources limit management %%----------------------------------------------------------------- %% Extract know limit options limit_options(Options) -> limit_options(Options, #limits{}). limit_options([], Limits) -> Limits; %% Maximum number of messages allowed in the process message queue limit_options([{max_queue,N}|Options], Limits) when is_integer(N) -> NewLimits = Limits#limits{max_queue=N}, limit_options(Options, NewLimits); limit_options([_|Options], Limits) -> limit_options(Options, Limits). %% Throw max_queue if we have reach the max queue size %% Returns ok otherwise message_queue_len(#limits{max_queue = undefined}, _QueueLen) -> ok; message_queue_len(#limits{max_queue = MaxQueue}, QueueLen) -> Pid = self(), case process_info(Pid, message_queue_len) of {message_queue_len, N} when N + QueueLen > MaxQueue -> throw({process_limit, {max_queue, N + QueueLen}}); _ -> ok end. ejabberd-2.1.11/src/shaper.erl0000664000000000000000000000445412240230175013002 0ustar %%%---------------------------------------------------------------------- %%% File : shaper.erl %%% Author : Alexey Shchepin %%% Purpose : Functions to control connections traffic %%% Created : 9 Feb 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(shaper). -author('alexey@process-one.net'). -export([new/1, new1/1, update/2]). -include("ejabberd.hrl"). -record(maxrate, {maxrate, lastrate, lasttime}). new(Name) -> Data = case ejabberd_config:get_global_option({shaper, Name, global}) of undefined -> none; D -> D end, new1(Data). new1(none) -> none; new1({maxrate, MaxRate}) -> #maxrate{maxrate = MaxRate, lastrate = 0, lasttime = now_to_usec(now())}. update(none, _Size) -> {none, 0}; update(#maxrate{} = State, Size) -> MinInterv = 1000 * Size / (2 * State#maxrate.maxrate - State#maxrate.lastrate), Interv = (now_to_usec(now()) - State#maxrate.lasttime) / 1000, ?DEBUG("State: ~p, Size=~p~nM=~p, I=~p~n", [State, Size, MinInterv, Interv]), Pause = if MinInterv > Interv -> 1 + trunc(MinInterv - Interv); true -> 0 end, NextNow = now_to_usec(now()) + Pause * 1000, {State#maxrate{ lastrate = (State#maxrate.lastrate + 1000000 * Size / (NextNow - State#maxrate.lasttime))/2, lasttime = NextNow}, Pause}. now_to_usec({MSec, Sec, USec}) -> (MSec*1000000 + Sec)*1000000 + USec. ejabberd-2.1.11/src/pg2_backport.erl0000664000000000000000000002447512240230175014102 0ustar %% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1997-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% %CopyrightEnd% %% -module(pg2_backport). -export([create/1, delete/1, join/2, leave/2]). -export([get_members/1, get_local_members/1]). -export([get_closest_pid/1, which_groups/0]). -export([start/0,start_link/0,init/1,handle_call/3,handle_cast/2,handle_info/2, terminate/2]). %%% As of R13B03 monitors are used instead of links. %%% %%% Exported functions %%% start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). start() -> ensure_started(). create(Name) -> ensure_started(), case ets:member(pg2_table, {group, Name}) of false -> global:trans({{?MODULE, Name}, self()}, fun() -> gen_server:multi_call(?MODULE, {create, Name}) end), ok; true -> ok end. delete(Name) -> ensure_started(), global:trans({{?MODULE, Name}, self()}, fun() -> gen_server:multi_call(?MODULE, {delete, Name}) end), ok. join(Name, Pid) when is_pid(Pid) -> ensure_started(), case ets:member(pg2_table, {group, Name}) of false -> {error, {no_such_group, Name}}; true -> global:trans({{?MODULE, Name}, self()}, fun() -> gen_server:multi_call(?MODULE, {join, Name, Pid}) end), ok end. leave(Name, Pid) when is_pid(Pid) -> ensure_started(), case ets:member(pg2_table, {group, Name}) of false -> {error, {no_such_group, Name}}; true -> global:trans({{?MODULE, Name}, self()}, fun() -> gen_server:multi_call(?MODULE, {leave, Name, Pid}) end), ok end. get_members(Name) -> ensure_started(), case ets:member(pg2_table, {group, Name}) of true -> group_members(Name); false -> {error, {no_such_group, Name}} end. get_local_members(Name) -> ensure_started(), case ets:member(pg2_table, {group, Name}) of true -> local_group_members(Name); false -> {error, {no_such_group, Name}} end. which_groups() -> ensure_started(), all_groups(). get_closest_pid(Name) -> case get_local_members(Name) of [Pid] -> Pid; [] -> {_,_,X} = erlang:now(), case get_members(Name) of [] -> {error, {no_process, Name}}; Members -> lists:nth((X rem length(Members))+1, Members) end; Members when is_list(Members) -> {_,_,X} = erlang:now(), lists:nth((X rem length(Members))+1, Members); Else -> Else end. %%% %%% Callback functions from gen_server %%% -record(state, {}). init([]) -> Ns = nodes(), net_kernel:monitor_nodes(true), lists:foreach(fun(N) -> {?MODULE, N} ! {new_pg2, node()}, self() ! {nodeup, N} end, Ns), pg2_table = ets:new(pg2_table, [ordered_set, protected, named_table]), {ok, #state{}}. handle_call({create, Name}, _From, S) -> assure_group(Name), {reply, ok, S}; handle_call({join, Name, Pid}, _From, S) -> ets:member(pg2_table, {group, Name}) andalso join_group(Name, Pid), {reply, ok, S}; handle_call({leave, Name, Pid}, _From, S) -> ets:member(pg2_table, {group, Name}) andalso leave_group(Name, Pid), {reply, ok, S}; handle_call({delete, Name}, _From, S) -> delete_group(Name), {reply, ok, S}; handle_call(Request, From, S) -> error_logger:warning_msg("The pg2 server received an unexpected message:\n" "handle_call(~p, ~p, _)\n", [Request, From]), {noreply, S}. handle_cast({exchange, _Node, List}, S) -> store(List), {noreply, S}; handle_cast(_, S) -> %% Ignore {del_member, Name, Pid}. {noreply, S}. handle_info({'DOWN', MonitorRef, process, _Pid, _Info}, S) -> member_died(MonitorRef), {noreply, S}; handle_info({nodeup, Node}, S) -> gen_server:cast({?MODULE, Node}, {exchange, node(), all_members()}), {noreply, S}; handle_info({new_pg2, Node}, S) -> gen_server:cast({?MODULE, Node}, {exchange, node(), all_members()}), {noreply, S}; handle_info(_, S) -> {noreply, S}. terminate(_Reason, _S) -> true = ets:delete(pg2_table), ok. %%% %%% Local functions %%% %%% One ETS table, pg2_table, is used for bookkeeping. The type of the %%% table is ordered_set, and the fast matching of partially %%% instantiated keys is used extensively. %%% %%% {{group, Name}} %%% Process group Name. %%% {{ref, Pid}, RPid, MonitorRef, Counter} %%% {{ref, MonitorRef}, Pid} %%% Each process has one monitor. Sometimes a process is spawned to %%% monitor the pid (RPid). Counter is incremented when the Pid joins %%% some group. %%% {{member, Name, Pid}, GroupCounter} %%% {{local_member, Name, Pid}} %%% Pid is a member of group Name, GroupCounter is incremented when the %%% Pid joins the group Name. %%% {{pid, Pid, Name}} %%% Pid is a member of group Name. store(List) -> _ = [(assure_group(Name) andalso store2(Name, Members)) || [Name, Members] <- List], ok. store2(Name, Members) -> [join_group(Name, P) || P <- Members -- group_members(Name)], true. assure_group(Name) -> Key = {group, Name}, ets:member(pg2_table, Key) orelse true =:= ets:insert(pg2_table, {Key}). delete_group(Name) -> _ = [leave_group(Name, Pid) || Pid <- group_members(Name)], true = ets:delete(pg2_table, {group, Name}), ok. member_died(Ref) -> [{{ref, Ref}, Pid}] = ets:lookup(pg2_table, {ref, Ref}), Names = member_groups(Pid), _ = [leave_group(Name, P) || Name <- Names, P <- member_in_group(Pid, Name)], %% Kept for backward compatibility with links. Can be removed, eventually. _ = [gen_server:abcast(nodes(), ?MODULE, {del_member, Name, Pid}) || Name <- Names], ok. join_group(Name, Pid) -> Ref_Pid = {ref, Pid}, try _ = ets:update_counter(pg2_table, Ref_Pid, {4, +1}) catch _:_ -> {RPid, Ref} = do_monitor(Pid), true = ets:insert(pg2_table, {Ref_Pid, RPid, Ref, 1}), true = ets:insert(pg2_table, {{ref, Ref}, Pid}) end, Member_Name_Pid = {member, Name, Pid}, try _ = ets:update_counter(pg2_table, Member_Name_Pid, {2, +1}) catch _:_ -> true = ets:insert(pg2_table, {Member_Name_Pid, 1}), _ = [ets:insert(pg2_table, {{local_member, Name, PidX}}) || PidX <- [Pid], node(PidX) =:= node()], true = ets:insert(pg2_table, {{pid, Pid, Name}}) end. leave_group(Name, Pid) -> Member_Name_Pid = {member, Name, Pid}, try ets:update_counter(pg2_table, Member_Name_Pid, {2, -1}) of N -> if N =:= 0 -> true = ets:delete(pg2_table, {pid, Pid, Name}), _ = [ets:delete(pg2_table, {local_member, Name, PidX}) || PidX <- [Pid], node(PidX) =:= node()], true = ets:delete(pg2_table, Member_Name_Pid); true -> ok end, Ref_Pid = {ref, Pid}, case ets:update_counter(pg2_table, Ref_Pid, {4, -1}) of 0 -> [{Ref_Pid,RPid,Ref,0}] = ets:lookup(pg2_table, Ref_Pid), true = ets:delete(pg2_table, {ref, Ref}), true = ets:delete(pg2_table, Ref_Pid), true = erlang:demonitor(Ref, [flush]), kill_monitor_proc(RPid, Pid); _ -> ok end catch _:_ -> ok end. all_members() -> [[G, group_members(G)] || G <- all_groups()]. group_members(Name) -> [P || [P, N] <- ets:match(pg2_table, {{member, Name, '$1'},'$2'}), _ <- lists:seq(1, N)]. local_group_members(Name) -> [P || [Pid] <- ets:match(pg2_table, {{local_member, Name, '$1'}}), P <- member_in_group(Pid, Name)]. member_in_group(Pid, Name) -> case ets:lookup(pg2_table, {member, Name, Pid}) of [] -> []; [{{member, Name, Pid}, N}] -> lists:duplicate(N, Pid) end. member_groups(Pid) -> [Name || [Name] <- ets:match(pg2_table, {{pid, Pid, '$1'}})]. all_groups() -> [N || [N] <- ets:match(pg2_table, {{group,'$1'}})]. ensure_started() -> case whereis(?MODULE) of undefined -> C = {pg2, {?MODULE, start_link, []}, permanent, 1000, worker, [?MODULE]}, supervisor:start_child(kernel_safe_sup, C); Pg2Pid -> {ok, Pg2Pid} end. kill_monitor_proc(RPid, Pid) -> RPid =:= Pid orelse exit(RPid, kill). %% When/if erlang:monitor() returns before trying to connect to the %% other node this function can be removed. do_monitor(Pid) -> case (node(Pid) =:= node()) orelse lists:member(node(Pid), nodes()) of true -> %% Assume the node is still up {Pid, erlang:monitor(process, Pid)}; false -> F = fun() -> Ref = erlang:monitor(process, Pid), receive {'DOWN', Ref, process, Pid, _Info} -> exit(normal) end end, erlang:spawn_monitor(F) end. ejabberd-2.1.11/src/adhoc.hrl0000664000000000000000000000222712240230175012575 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -record(adhoc_request, {lang, node, sessionid, action, xdata, others}). -record(adhoc_response, {lang, node, sessionid, status, defaultaction = "", actions = [], notes = [], elements = []}). ejabberd-2.1.11/src/ejabberd_auth_ldap.erl0000664000000000000000000003301112240230175015266 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_auth_ldap.erl %%% Author : Alexey Shchepin %%% Purpose : Authentification via LDAP %%% Created : 12 Dec 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_auth_ldap). -author('alexey@process-one.net'). -behaviour(gen_server). %% gen_server callbacks -export([init/1, handle_info/2, handle_call/3, handle_cast/2, terminate/2, code_change/3 ]). %% External exports -export([start/1, stop/1, start_link/1, set_password/3, check_password/3, check_password/5, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users_number/1, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, remove_user/3, store_type/0, plain_password_required/0 ]). -include("ejabberd.hrl"). -include("eldap/eldap.hrl"). -record(state, {host, eldap_id, bind_eldap_id, servers, backups, port, tls_options, dn, password, base, uids, ufilter, sfilter, lfilter, %% Local filter (performed by ejabberd, not LDAP) deref_aliases, dn_filter, dn_filter_attrs }). %% Unused callbacks. handle_cast(_Request, State) -> {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. handle_info(_Info, State) -> {noreply, State}. %% ----- -define(LDAP_SEARCH_TIMEOUT, 5). % Timeout for LDAP search queries in seconds %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start(Host) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), ChildSpec = { Proc, {?MODULE, start_link, [Host]}, transient, 1000, worker, [?MODULE] }, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), gen_server:call(Proc, stop), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). start_link(Host) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), gen_server:start_link({local, Proc}, ?MODULE, Host, []). terminate(_Reason, _State) -> ok. init(Host) -> State = parse_options(Host), eldap_pool:start_link(State#state.eldap_id, State#state.servers, State#state.backups, State#state.port, State#state.dn, State#state.password, State#state.tls_options), eldap_pool:start_link(State#state.bind_eldap_id, State#state.servers, State#state.backups, State#state.port, State#state.dn, State#state.password, State#state.tls_options), {ok, State}. plain_password_required() -> true. store_type() -> external. check_password(User, Server, Password) -> %% In LDAP spec: empty password means anonymous authentication. %% As ejabberd is providing other anonymous authentication mechanisms %% we simply prevent the use of LDAP anonymous authentication. if Password == "" -> false; true -> case catch check_password_ldap(User, Server, Password) of {'EXIT', _} -> false; Result -> Result end end. check_password(User, Server, Password, _Digest, _DigestGen) -> check_password(User, Server, Password). set_password(User, Server, Password) -> {ok, State} = eldap_utils:get_state(Server, ?MODULE), case find_user_dn(User, State) of false -> {error, user_not_found}; DN -> eldap_pool:modify_passwd(State#state.eldap_id, DN, Password) end. %% @spec (User, Server, Password) -> {error, not_allowed} try_register(_User, _Server, _Password) -> {error, not_allowed}. dirty_get_registered_users() -> Servers = ejabberd_config:get_vh_by_auth_method(ldap), lists:flatmap( fun(Server) -> get_vh_registered_users(Server) end, Servers). get_vh_registered_users(Server) -> case catch get_vh_registered_users_ldap(Server) of {'EXIT', _} -> []; Result -> Result end. get_vh_registered_users_number(Server) -> length(get_vh_registered_users(Server)). get_password(_User, _Server) -> false. get_password_s(_User, _Server) -> "". %% @spec (User, Server) -> true | false | {error, Error} is_user_exists(User, Server) -> case catch is_user_exists_ldap(User, Server) of {'EXIT', Error} -> {error, Error}; Result -> Result end. remove_user(_User, _Server) -> {error, not_allowed}. remove_user(_User, _Server, _Password) -> not_allowed. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- check_password_ldap(User, Server, Password) -> {ok, State} = eldap_utils:get_state(Server, ?MODULE), case find_user_dn(User, State) of false -> false; DN -> case eldap_pool:bind(State#state.bind_eldap_id, DN, Password) of ok -> true; _ -> false end end. get_vh_registered_users_ldap(Server) -> {ok, State} = eldap_utils:get_state(Server, ?MODULE), UIDs = State#state.uids, Eldap_ID = State#state.eldap_id, Server = State#state.host, ResAttrs = result_attrs(State), case eldap_filter:parse(State#state.sfilter) of {ok, EldapFilter} -> case eldap_pool:search(Eldap_ID, [{base, State#state.base}, {filter, EldapFilter}, {timeout, ?LDAP_SEARCH_TIMEOUT}, {deref_aliases, State#state.deref_aliases}, {attributes, ResAttrs}]) of #eldap_search_result{entries = Entries} -> lists:flatmap( fun(#eldap_entry{attributes = Attrs, object_name = DN}) -> case is_valid_dn(DN, Attrs, State) of false -> []; _ -> case eldap_utils:find_ldap_attrs(UIDs, Attrs) of "" -> []; {User, UIDFormat} -> case eldap_utils:get_user_part(User, UIDFormat) of {ok, U} -> case jlib:nodeprep(U) of error -> []; LU -> [{LU, jlib:nameprep(Server)}] end; _ -> [] end end end end, Entries); _ -> [] end; _ -> [] end. is_user_exists_ldap(User, Server) -> {ok, State} = eldap_utils:get_state(Server, ?MODULE), case find_user_dn(User, State) of false -> false; _DN -> true end. handle_call(get_state, _From, State) -> {reply, {ok, State}, State}; handle_call(stop, _From, State) -> {stop, normal, ok, State}; handle_call(_Request, _From, State) -> {reply, bad_request, State}. find_user_dn(User, State) -> ResAttrs = result_attrs(State), case eldap_filter:parse(State#state.ufilter, [{"%u", User}]) of {ok, Filter} -> case eldap_pool:search(State#state.eldap_id, [{base, State#state.base}, {filter, Filter}, {deref_aliases, State#state.deref_aliases}, {attributes, ResAttrs}]) of #eldap_search_result{entries = [#eldap_entry{attributes = Attrs, object_name = DN} | _]} -> dn_filter(DN, Attrs, State); _ -> false end; _ -> false end. %% apply the dn filter and the local filter: dn_filter(DN, Attrs, State) -> %% Check if user is denied access by attribute value (local check) case check_local_filter(Attrs, State) of false -> false; true -> is_valid_dn(DN, Attrs, State) end. %% Check that the DN is valid, based on the dn filter is_valid_dn(DN, _, #state{dn_filter = undefined}) -> DN; is_valid_dn(DN, Attrs, State) -> DNAttrs = State#state.dn_filter_attrs, UIDs = State#state.uids, Values = [{"%s", eldap_utils:get_ldap_attr(Attr, Attrs), 1} || Attr <- DNAttrs], SubstValues = case eldap_utils:find_ldap_attrs(UIDs, Attrs) of "" -> Values; {S, UAF} -> case eldap_utils:get_user_part(S, UAF) of {ok, U} -> [{"%u", U} | Values]; _ -> Values end end ++ [{"%d", State#state.host}, {"%D", DN}], case eldap_filter:parse(State#state.dn_filter, SubstValues) of {ok, EldapFilter} -> case eldap_pool:search(State#state.eldap_id, [{base, State#state.base}, {filter, EldapFilter}, {deref_aliases, State#state.deref_aliases}, {attributes, ["dn"]}]) of #eldap_search_result{entries = [_|_]} -> DN; _ -> false end; _ -> false end. %% The local filter is used to check an attribute in ejabberd %% and not in LDAP to limit the load on the LDAP directory. %% A local rule can be either: %% {equal, {"accountStatus",["active"]}} %% {notequal, {"accountStatus",["disabled"]}} %% {ldap_local_filter, {notequal, {"accountStatus",["disabled"]}}} check_local_filter(_Attrs, #state{lfilter = undefined}) -> true; check_local_filter(Attrs, #state{lfilter = LocalFilter}) -> {Operation, FilterMatch} = LocalFilter, local_filter(Operation, Attrs, FilterMatch). local_filter(equal, Attrs, FilterMatch) -> {Attr, Value} = FilterMatch, case lists:keysearch(Attr, 1, Attrs) of false -> false; {value,{Attr,Value}} -> true; _ -> false end; local_filter(notequal, Attrs, FilterMatch) -> not local_filter(equal, Attrs, FilterMatch). result_attrs(#state{uids = UIDs, dn_filter_attrs = DNFilterAttrs}) -> lists:foldl( fun({UID}, Acc) -> [UID | Acc]; ({UID, _}, Acc) -> [UID | Acc] end, DNFilterAttrs, UIDs). %%%---------------------------------------------------------------------- %%% Auxiliary functions %%%---------------------------------------------------------------------- parse_options(Host) -> Eldap_ID = atom_to_list(gen_mod:get_module_proc(Host, ?MODULE)), Bind_Eldap_ID = atom_to_list(gen_mod:get_module_proc(Host, bind_ejabberd_auth_ldap)), LDAPServers = ejabberd_config:get_local_option({ldap_servers, Host}), LDAPBackups = case ejabberd_config:get_local_option({ldap_backups, Host}) of undefined -> []; Backups -> Backups end, LDAPEncrypt = ejabberd_config:get_local_option({ldap_encrypt, Host}), LDAPTLSVerify = ejabberd_config:get_local_option({ldap_tls_verify, Host}), LDAPTLSCAFile = ejabberd_config:get_local_option({ldap_tls_cacertfile, Host}), LDAPTLSDepth = ejabberd_config:get_local_option({ldap_tls_depth, Host}), LDAPPort = case ejabberd_config:get_local_option({ldap_port, Host}) of undefined -> case LDAPEncrypt of tls -> ?LDAPS_PORT; starttls -> ?LDAP_PORT; _ -> ?LDAP_PORT end; P -> P end, RootDN = case ejabberd_config:get_local_option({ldap_rootdn, Host}) of undefined -> ""; RDN -> RDN end, Password = case ejabberd_config:get_local_option({ldap_password, Host}) of undefined -> ""; Pass -> Pass end, UIDs = case ejabberd_config:get_local_option({ldap_uids, Host}) of undefined -> [{"uid", "%u"}]; UI -> eldap_utils:uids_domain_subst(Host, UI) end, SubFilter = lists:flatten(eldap_utils:generate_subfilter(UIDs)), UserFilter = case ejabberd_config:get_local_option({ldap_filter, Host}) of undefined -> SubFilter; "" -> SubFilter; F -> eldap_utils:check_filter(F), "(&" ++ SubFilter ++ F ++ ")" end, SearchFilter = eldap_filter:do_sub(UserFilter, [{"%u", "*"}]), LDAPBase = ejabberd_config:get_local_option({ldap_base, Host}), {DNFilter, DNFilterAttrs} = case ejabberd_config:get_local_option({ldap_dn_filter, Host}) of undefined -> {undefined, []}; {DNF, undefined} -> {DNF, []}; {DNF, DNFA} -> {DNF, DNFA} end, eldap_utils:check_filter(DNFilter), LocalFilter = ejabberd_config:get_local_option({ldap_local_filter, Host}), DerefAliases = case ejabberd_config:get_local_option( {ldap_deref_aliases, Host}) of undefined -> never; Val -> Val end, #state{host = Host, eldap_id = Eldap_ID, bind_eldap_id = Bind_Eldap_ID, servers = LDAPServers, backups = LDAPBackups, port = LDAPPort, tls_options = [{encrypt, LDAPEncrypt}, {tls_verify, LDAPTLSVerify}, {tls_cacertfile, LDAPTLSCAFile}, {tls_depth, LDAPTLSDepth}], dn = RootDN, password = Password, base = LDAPBase, uids = UIDs, ufilter = UserFilter, sfilter = SearchFilter, lfilter = LocalFilter, deref_aliases = DerefAliases, dn_filter = DNFilter, dn_filter_attrs = DNFilterAttrs }. ejabberd-2.1.11/src/mod_vcard_ldap.erl0000664000000000000000000006143712240230175014462 0ustar %%%---------------------------------------------------------------------- %%% File : mod_vcard_ldap.erl %%% Author : Alexey Shchepin %%% Purpose : Support for VCards from LDAP storage. %%% Created : 2 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_vcard_ldap). -author('alexey@process-one.net'). -behaviour(gen_server). -behaviour(gen_mod). %% gen_server callbacks. -export([init/1, handle_info/2, handle_call/3, handle_cast/2, terminate/2, code_change/3 ]). -export([start/2, start_link/2, stop/1, get_sm_features/5, process_local_iq/3, process_sm_iq/3, remove_user/1, route/4 ]). -include("ejabberd.hrl"). -include("eldap/eldap.hrl"). -include("jlib.hrl"). -define(PROCNAME, ejabberd_mod_vcard_ldap). -record(state, {serverhost, myhost, eldap_id, search, servers, backups, port, tls_options, dn, base, password, uids, vcard_map, vcard_map_attrs, user_filter, search_filter, search_fields, search_reported, search_reported_attrs, deref_aliases, matches }). -define(VCARD_MAP, [{"NICKNAME", "%u", []}, {"FN", "%s", ["displayName"]}, {"FAMILY", "%s", ["sn"]}, {"GIVEN", "%s", ["givenName"]}, {"MIDDLE", "%s", ["initials"]}, {"ORGNAME", "%s", ["o"]}, {"ORGUNIT", "%s", ["ou"]}, {"CTRY", "%s", ["c"]}, {"LOCALITY", "%s", ["l"]}, {"STREET", "%s", ["street"]}, {"REGION", "%s", ["st"]}, {"PCODE", "%s", ["postalCode"]}, {"TITLE", "%s", ["title"]}, {"URL", "%s", ["labeleduri"]}, {"DESC", "%s", ["description"]}, {"TEL", "%s", ["telephoneNumber"]}, {"EMAIL", "%s", ["mail"]}, {"BDAY", "%s", ["birthDay"]}, {"ROLE", "%s", ["employeeType"]}, {"PHOTO", "%s", ["jpegPhoto"]} ]). -define(SEARCH_FIELDS, [{"User", "%u"}, {"Full Name", "displayName"}, {"Given Name", "givenName"}, {"Middle Name", "initials"}, {"Family Name", "sn"}, {"Nickname", "%u"}, {"Birthday", "birthDay"}, {"Country", "c"}, {"City", "l"}, {"Email", "mail"}, {"Organization Name", "o"}, {"Organization Unit", "ou"} ]). -define(SEARCH_REPORTED, [{"Full Name", "FN"}, {"Given Name", "FIRST"}, {"Middle Name", "MIDDLE"}, {"Family Name", "LAST"}, {"Nickname", "NICK"}, {"Birthday", "BDAY"}, {"Country", "CTRY"}, {"City", "LOCALITY"}, {"Email", "EMAIL"}, {"Organization Name", "ORGNAME"}, {"Organization Unit", "ORGUNIT"} ]). %% Unused callbacks. handle_cast(_Request, State) -> {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. %% ----- start(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ChildSpec = { Proc, {?MODULE, start_link, [Host, Opts]}, transient, 1000, worker, [?MODULE] }, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:call(Proc, stop), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). terminate(_Reason, State) -> Host = State#state.serverhost, gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50), case State#state.search of true -> ejabberd_router:unregister_route(State#state.myhost); _ -> ok end. start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). init([Host, Opts]) -> State = parse_options(Host, Opts), IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD, ?MODULE, process_local_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD, ?MODULE, process_sm_iq, IQDisc), ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50), eldap_pool:start_link(State#state.eldap_id, State#state.servers, State#state.backups, State#state.port, State#state.dn, State#state.password, State#state.tls_options), case State#state.search of true -> ejabberd_router:register_route(State#state.myhost); _ -> ok end, {ok, State}. handle_info({route, From, To, Packet}, State) -> case catch do_route(State, From, To, Packet) of Pid when is_pid(Pid) -> ok; _ -> Err = jlib:make_error_reply(Packet, ?ERR_INTERNAL_SERVER_ERROR), ejabberd_router:route(To, From, Err) end, {noreply, State}; handle_info(_Info, State) -> {noreply, State}. get_sm_features({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; get_sm_features(Acc, _From, _To, Node, _Lang) -> case Node of [] -> case Acc of {result, Features} -> {result, [?NS_VCARD | Features]}; empty -> {result, [?NS_VCARD]} end; _ -> Acc end. process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", ?NS_VCARD}], [{xmlelement, "FN", [], [{xmlcdata, "ejabberd"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate( Lang, "Erlang Jabber Server") ++ "\nCopyright (c) 2002-2012 ProcessOne"}]}, {xmlelement, "BDAY", [], [{xmlcdata, "2002-11-16"}]} ]}]} end. process_sm_iq(_From, #jid{lserver=LServer} = To, #iq{sub_el = SubEl} = IQ) -> case catch process_vcard_ldap(To, IQ, LServer) of {'EXIT', _} -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; Other -> Other end. process_vcard_ldap(To, IQ, Server) -> {ok, State} = eldap_utils:get_state(Server, ?PROCNAME), #iq{type = Type, sub_el = SubEl} = IQ, case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> #jid{luser = LUser} = To, LServer = State#state.serverhost, case ejabberd_auth:is_user_exists(LUser, LServer) of true -> VCardMap = State#state.vcard_map, case find_ldap_user(LUser, State) of #eldap_entry{attributes = Attributes} -> Vcard = ldap_attributes_to_vcard(Attributes, VCardMap, {LUser, LServer}), IQ#iq{type = result, sub_el = Vcard}; _ -> IQ#iq{type = result, sub_el = []} end; _ -> IQ#iq{type = result, sub_el = []} end end. handle_call(get_state, _From, State) -> {reply, {ok, State}, State}; handle_call(stop, _From, State) -> {stop, normal, ok, State}; handle_call(_Request, _From, State) -> {reply, bad_request, State}. find_ldap_user(User, State) -> Base = State#state.base, RFC2254_Filter = State#state.user_filter, Eldap_ID = State#state.eldap_id, VCardAttrs = State#state.vcard_map_attrs, case eldap_filter:parse(RFC2254_Filter, [{"%u", User}]) of {ok, EldapFilter} -> case eldap_pool:search(Eldap_ID, [{base, Base}, {filter, EldapFilter}, {deref_aliases, State#state.deref_aliases}, {attributes, VCardAttrs}]) of #eldap_search_result{entries = [E | _]} -> E; _ -> false end; _ -> false end. ldap_attributes_to_vcard(Attributes, VCardMap, UD) -> Attrs = lists:map( fun({VCardName, _, _}) -> {stringprep:tolower(VCardName), map_vcard_attr(VCardName, Attributes, VCardMap, UD)} end, VCardMap), Elts = [ldap_attribute_to_vcard(vCard, Attr) || Attr <- Attrs], NElts = [ldap_attribute_to_vcard(vCardN, Attr) || Attr <- Attrs], OElts = [ldap_attribute_to_vcard(vCardO, Attr) || Attr <- Attrs], AElts = [ldap_attribute_to_vcard(vCardA, Attr) || Attr <- Attrs], [{xmlelement, "vCard", [{"xmlns", ?NS_VCARD}], lists:append([X || X <- Elts, X /= none], [{xmlelement,"N",[], [X || X <- NElts, X /= none]}, {xmlelement,"ORG",[], [X || X <- OElts, X /= none]}, {xmlelement,"ADR",[], [X || X <- AElts, X /= none]}]) }]. ldap_attribute_to_vcard(vCard, {"fn", Value}) -> {xmlelement,"FN",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCard, {"nickname", Value}) -> {xmlelement,"NICKNAME",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCard, {"title", Value}) -> {xmlelement,"TITLE",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCard, {"bday", Value}) -> {xmlelement,"BDAY",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCard, {"url", Value}) -> {xmlelement,"URL",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCard, {"desc", Value}) -> {xmlelement,"DESC",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCard, {"role", Value}) -> {xmlelement,"ROLE",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCard, {"tel", Value}) -> {xmlelement,"TEL",[],[{xmlelement,"VOICE",[],[]}, {xmlelement,"WORK",[],[]}, {xmlelement,"NUMBER",[],[{xmlcdata,Value}]}]}; ldap_attribute_to_vcard(vCard, {"email", Value}) -> {xmlelement,"EMAIL",[],[{xmlelement,"INTERNET",[],[]}, {xmlelement,"PREF",[],[]}, {xmlelement,"USERID",[],[{xmlcdata,Value}]}]}; ldap_attribute_to_vcard(vCard, {"photo", Value}) -> {xmlelement,"PHOTO",[],[ {xmlelement,"TYPE",[],[{xmlcdata,"image/jpeg"}]}, {xmlelement,"BINVAL",[],[{xmlcdata, jlib:encode_base64(Value)}]}]}; ldap_attribute_to_vcard(vCardN, {"family", Value}) -> {xmlelement,"FAMILY",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCardN, {"given", Value}) -> {xmlelement,"GIVEN",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCardN, {"middle", Value}) -> {xmlelement,"MIDDLE",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCardO, {"orgname", Value}) -> {xmlelement,"ORGNAME",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCardO, {"orgunit", Value}) -> {xmlelement,"ORGUNIT",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCardA, {"locality", Value}) -> {xmlelement,"LOCALITY",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCardA, {"street", Value}) -> {xmlelement,"STREET",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCardA, {"ctry", Value}) -> {xmlelement,"CTRY",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCardA, {"region", Value}) -> {xmlelement,"REGION",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(vCardA, {"pcode", Value}) -> {xmlelement,"PCODE",[],[{xmlcdata,Value}]}; ldap_attribute_to_vcard(_, _) -> none. -define(TLFIELD(Type, Label, Var), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, {"var", Var}], []}). -define(FORM(JID, SearchFields), [{xmlelement, "instructions", [], [{xmlcdata, translate:translate(Lang, "You need an x:data capable client to search")}]}, {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "Search users in ") ++ jlib:jid_to_string(JID)}]}, {xmlelement, "instructions", [], [{xmlcdata, translate:translate(Lang, "Fill in fields to search " "for any matching Jabber User")}]} ] ++ lists:map(fun({X,Y}) -> ?TLFIELD("text-single", X, Y) end, SearchFields)}]). do_route(State, From, To, Packet) -> spawn(?MODULE, route, [State, From, To, Packet]). route(State, From, To, Packet) -> #jid{user = User, resource = Resource} = To, ServerHost = State#state.serverhost, if (User /= "") or (Resource /= "") -> Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err); true -> IQ = jlib:iq_query_info(Packet), case IQ of #iq{type = Type, xmlns = ?NS_SEARCH, lang = Lang, sub_el = SubEl} -> case Type of set -> XDataEl = find_xdata_el(SubEl), case XDataEl of false -> Err = jlib:make_error_reply( Packet, ?ERR_BAD_REQUEST), ejabberd_router:route(To, From, Err); _ -> XData = jlib:parse_xdata_submit(XDataEl), case XData of invalid -> Err = jlib:make_error_reply( Packet, ?ERR_BAD_REQUEST), ejabberd_router:route(To, From, Err); _ -> ResIQ = IQ#iq{ type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_SEARCH}], [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}], search_result(Lang, To, State, XData) }]}]}, ejabberd_router:route( To, From, jlib:iq_to_xml(ResIQ)) end end; get -> SearchFields = State#state.search_fields, ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_SEARCH}], ?FORM(To, SearchFields) }]}, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) end; #iq{type = Type, xmlns = ?NS_DISCO_INFO, lang = Lang} -> case Type of set -> Err = jlib:make_error_reply( Packet, ?ERR_NOT_ALLOWED), ejabberd_router:route(To, From, Err); get -> Info = ejabberd_hooks:run_fold( disco_info, ServerHost, [], [ServerHost, ?MODULE, "", ""]), ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_INFO}], [{xmlelement, "identity", [{"category", "directory"}, {"type", "user"}, {"name", translate:translate(Lang, "vCard User Search")}], []}, {xmlelement, "feature", [{"var", ?NS_SEARCH}], []}, {xmlelement, "feature", [{"var", ?NS_VCARD}], []} ] ++ Info }]}, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) end; #iq{type = Type, xmlns = ?NS_DISCO_ITEMS} -> case Type of set -> Err = jlib:make_error_reply( Packet, ?ERR_NOT_ALLOWED), ejabberd_router:route(To, From, Err); get -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}], []}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) end; #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", ?NS_VCARD}], iq_get_vcard(Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); _ -> Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err) end end. iq_get_vcard(Lang) -> [{xmlelement, "FN", [], [{xmlcdata, "ejabberd/mod_vcard"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate( Lang, "ejabberd vCard module") ++ "\nCopyright (c) 2003-2012 ProcessOne"}]}]. -define(LFIELD(Label, Var), {xmlelement, "field", [{"label", translate:translate(Lang, Label)}, {"var", Var}], []}). search_result(Lang, JID, State, Data) -> SearchReported = State#state.search_reported, Header = [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "Search Results for ") ++ jlib:jid_to_string(JID)}]}, {xmlelement, "reported", [], [?TLFIELD("text-single", "Jabber ID", "jid")] ++ lists:map( fun({Name, Value}) -> ?TLFIELD("text-single", Name, Value) end, SearchReported) }], case search(State, Data) of error -> Header; Result -> Header ++ Result end. -define(FIELD(Var, Val), {xmlelement, "field", [{"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). search(State, Data) -> Base = State#state.base, SearchFilter = State#state.search_filter, Eldap_ID = State#state.eldap_id, UIDs = State#state.uids, Limit = State#state.matches, ReportedAttrs = State#state.search_reported_attrs, Filter = eldap:'and'([SearchFilter, eldap_utils:make_filter(Data, UIDs)]), case eldap_pool:search(Eldap_ID, [{base, Base}, {filter, Filter}, {limit, Limit}, {deref_aliases, State#state.deref_aliases}, {attributes, ReportedAttrs}]) of #eldap_search_result{entries = E} -> search_items(E, State); _ -> error end. search_items(Entries, State) -> LServer = State#state.serverhost, SearchReported = State#state.search_reported, VCardMap = State#state.vcard_map, UIDs = State#state.uids, Attributes = lists:map( fun(E) -> #eldap_entry{attributes = Attrs} = E, Attrs end, Entries), lists:flatmap( fun(Attrs) -> case eldap_utils:find_ldap_attrs(UIDs, Attrs) of {U, UIDAttrFormat} -> case eldap_utils:get_user_part(U, UIDAttrFormat) of {ok, Username} -> case ejabberd_auth:is_user_exists(Username, LServer) of true -> RFields = lists:map( fun({_, VCardName}) -> {VCardName, map_vcard_attr( VCardName, Attrs, VCardMap, {Username, ?MYNAME})} end, SearchReported), Result = [?FIELD("jid", Username ++ "@" ++ LServer)] ++ [?FIELD(Name, Value) || {Name, Value} <- RFields], [{xmlelement, "item", [], Result}]; _ -> [] end; _ -> [] end; "" -> [] end end, Attributes). remove_user(_User) -> true. %%%----------------------- %%% Auxiliary functions. %%%----------------------- map_vcard_attr(VCardName, Attributes, Pattern, UD) -> Res = lists:filter( fun({Name, _, _}) -> eldap_utils:case_insensitive_match(Name, VCardName) end, Pattern), case Res of [{_, Str, Attrs}] -> process_pattern(Str, UD, [eldap_utils:get_ldap_attr(X, Attributes) || X<-Attrs]); _ -> "" end. process_pattern(Str, {User, Domain}, AttrValues) -> eldap_filter:do_sub( Str, [{"%u", User},{"%d", Domain}] ++ [{"%s", V, 1} || V <- AttrValues]). find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) -> find_xdata_el1(SubEls). find_xdata_el1([]) -> false; find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_XDATA -> {xmlelement, Name, Attrs, SubEls}; _ -> find_xdata_el1(Els) end; find_xdata_el1([_ | Els]) -> find_xdata_el1(Els). parse_options(Host, Opts) -> MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"), Search = gen_mod:get_opt(search, Opts, true), Matches = case gen_mod:get_opt(matches, Opts, 30) of infinity -> 0; N -> N end, Eldap_ID = atom_to_list(gen_mod:get_module_proc(Host, ?PROCNAME)), LDAPServers = case gen_mod:get_opt(ldap_servers, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_servers, Host}); S -> S end, LDAPBackups = case gen_mod:get_opt(ldap_backups, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_servers, Host}); Backups -> Backups end, LDAPEncrypt = case gen_mod:get_opt(ldap_encrypt, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_encrypt, Host}); E -> E end, LDAPTLSVerify = case gen_mod:get_opt(ldap_tls_verify, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_tls_verify, Host}); Verify -> Verify end, LDAPTLSCAFile = case gen_mod:get_opt(ldap_tls_cacertfile, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_tls_cacertfile, Host}); CAFile -> CAFile end, LDAPTLSDepth = case gen_mod:get_opt(ldap_tls_depth, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_tls_depth, Host}); Depth -> Depth end, LDAPPortTemp = case gen_mod:get_opt(ldap_port, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_port, Host}); PT -> PT end, LDAPPort = case LDAPPortTemp of undefined -> case LDAPEncrypt of tls -> ?LDAPS_PORT; starttls -> ?LDAP_PORT; _ -> ?LDAP_PORT end; P -> P end, LDAPBase = case gen_mod:get_opt(ldap_base, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_base, Host}); B -> B end, UIDs = case gen_mod:get_opt(ldap_uids, Opts, undefined) of undefined -> case ejabberd_config:get_local_option({ldap_uids, Host}) of undefined -> [{"uid", "%u"}]; UI -> eldap_utils:uids_domain_subst(Host, UI) end; UI -> eldap_utils:uids_domain_subst(Host, UI) end, RootDN = case gen_mod:get_opt(ldap_rootdn, Opts, undefined) of undefined -> case ejabberd_config:get_local_option({ldap_rootdn, Host}) of undefined -> ""; RDN -> RDN end; RDN -> RDN end, Password = case gen_mod:get_opt(ldap_password, Opts, undefined) of undefined -> case ejabberd_config:get_local_option({ldap_password, Host}) of undefined -> ""; Pass -> Pass end; Pass -> Pass end, SubFilter = lists:flatten(eldap_utils:generate_subfilter(UIDs)), UserFilter = case gen_mod:get_opt(ldap_filter, Opts, undefined) of undefined -> case ejabberd_config:get_local_option({ldap_filter, Host}) of undefined -> SubFilter; "" -> SubFilter; F -> eldap_utils:check_filter(F), "(&" ++ SubFilter ++ F ++ ")" end; "" -> SubFilter; F -> eldap_utils:check_filter(F), "(&" ++ SubFilter ++ F ++ ")" end, {ok, SearchFilter} = eldap_filter:parse( eldap_filter:do_sub(UserFilter, [{"%u","*"}])), VCardMap = gen_mod:get_opt(ldap_vcard_map, Opts, ?VCARD_MAP), SearchFields = gen_mod:get_opt(ldap_search_fields, Opts, ?SEARCH_FIELDS), SearchReported = gen_mod:get_opt(ldap_search_reported, Opts, ?SEARCH_REPORTED), %% In search requests we need to fetch only attributes defined %% in vcard-map and search-reported. In some cases, %% this will essentially reduce network traffic from an LDAP server. UIDAttrs = [UAttr || {UAttr, _} <- UIDs], VCardMapAttrs = lists:usort( lists:append([A || {_, _, A} <- VCardMap]) ++ UIDAttrs), SearchReportedAttrs = lists:usort(lists:flatmap( fun({_, N}) -> case lists:keysearch(N, 1, VCardMap) of {value, {_, _, L}} -> L; _ -> [] end end, SearchReported) ++ UIDAttrs), DerefAliases = case gen_mod:get_opt(deref_aliases, Opts, undefined) of undefined -> case ejabberd_config:get_local_option( {deref_aliases, Host}) of undefined -> never; D -> D end; D -> D end, #state{serverhost = Host, myhost = MyHost, eldap_id = Eldap_ID, search = Search, servers = LDAPServers, backups = LDAPBackups, port = LDAPPort, tls_options = [{encrypt, LDAPEncrypt}, {tls_verify, LDAPTLSVerify}, {tls_cacertfile, LDAPTLSCAFile}, {tls_depth, LDAPTLSDepth}], dn = RootDN, base = LDAPBase, password = Password, uids = UIDs, vcard_map = VCardMap, vcard_map_attrs = VCardMapAttrs, user_filter = UserFilter, search_filter = SearchFilter, search_fields = SearchFields, search_reported = SearchReported, search_reported_attrs = SearchReportedAttrs, deref_aliases = DerefAliases, matches = Matches }. ejabberd-2.1.11/src/mod_offline.erl0000664000000000000000000004712412240230175014002 0ustar %%%---------------------------------------------------------------------- %%% File : mod_offline.erl %%% Author : Alexey Shchepin %%% Purpose : Store and manage offline messages in Mnesia database. %%% Created : 5 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_offline). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, loop/1, stop/1, store_packet/3, resend_offline_messages/2, pop_offline_messages/3, get_sm_features/5, remove_expired_messages/0, remove_old_messages/1, remove_user/2, get_queue_length/2, webadmin_page/3, webadmin_user/4, webadmin_user_parse_query/5]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("web/ejabberd_http.hrl"). -include("web/ejabberd_web_admin.hrl"). -record(offline_msg, {us, timestamp, expire, from, to, packet}). -define(PROCNAME, ejabberd_offline). -define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000). %% default value for the maximum number of user messages -define(MAX_USER_MESSAGES, infinity). start(Host, Opts) -> mnesia:create_table(offline_msg, [{disc_only_copies, [node()]}, {type, bag}, {attributes, record_info(fields, offline_msg)}]), update_table(), ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, store_packet, 50), ejabberd_hooks:add(resend_offline_messages_hook, Host, ?MODULE, pop_offline_messages, 50), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:add(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_sm_features, 50), ejabberd_hooks:add(webadmin_page_host, Host, ?MODULE, webadmin_page, 50), ejabberd_hooks:add(webadmin_user, Host, ?MODULE, webadmin_user, 50), ejabberd_hooks:add(webadmin_user_parse_query, Host, ?MODULE, webadmin_user_parse_query, 50), AccessMaxOfflineMsgs = gen_mod:get_opt(access_max_user_messages, Opts, max_user_offline_messages), register(gen_mod:get_module_proc(Host, ?PROCNAME), spawn(?MODULE, loop, [AccessMaxOfflineMsgs])). loop(AccessMaxOfflineMsgs) -> receive #offline_msg{us=US} = Msg -> Msgs = receive_all(US, [Msg]), Len = length(Msgs), {User, Host} = US, MaxOfflineMsgs = get_max_user_messages(AccessMaxOfflineMsgs, User, Host), F = fun() -> %% Only count messages if needed: Count = if MaxOfflineMsgs =/= infinity -> Len + p1_mnesia:count_records( offline_msg, #offline_msg{us=US, _='_'}); true -> 0 end, if Count > MaxOfflineMsgs -> discard_warn_sender(Msgs); true -> if Len >= ?OFFLINE_TABLE_LOCK_THRESHOLD -> mnesia:write_lock_table(offline_msg); true -> ok end, lists:foreach(fun(M) -> mnesia:write(M) end, Msgs) end end, mnesia:transaction(F), loop(AccessMaxOfflineMsgs); _ -> loop(AccessMaxOfflineMsgs) end. %% Function copied from ejabberd_sm.erl: get_max_user_messages(AccessRule, LUser, Host) -> case acl:match_rule( Host, AccessRule, jlib:make_jid(LUser, Host, "")) of Max when is_integer(Max) -> Max; infinity -> infinity; _ -> ?MAX_USER_MESSAGES end. receive_all(US, Msgs) -> receive #offline_msg{us=US} = Msg -> receive_all(US, [Msg | Msgs]) after 0 -> Msgs end. stop(Host) -> ejabberd_hooks:delete(offline_message_hook, Host, ?MODULE, store_packet, 50), ejabberd_hooks:delete(resend_offline_messages_hook, Host, ?MODULE, pop_offline_messages, 50), ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50), ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_sm_features, 50), ejabberd_hooks:delete(webadmin_page_host, Host, ?MODULE, webadmin_page, 50), ejabberd_hooks:delete(webadmin_user, Host, ?MODULE, webadmin_user, 50), ejabberd_hooks:delete(webadmin_user_parse_query, Host, ?MODULE, webadmin_user_parse_query, 50), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), exit(whereis(Proc), stop), {wait, Proc}. get_sm_features(Acc, _From, _To, "", _Lang) -> Feats = case Acc of {result, I} -> I; _ -> [] end, {result, Feats ++ [?NS_FEATURE_MSGOFFLINE]}; get_sm_features(_Acc, _From, _To, ?NS_FEATURE_MSGOFFLINE, _Lang) -> %% override all lesser features... {result, []}; get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. store_packet(From, To, Packet) -> Type = xml:get_tag_attr_s("type", Packet), if (Type /= "error") and (Type /= "groupchat") and (Type /= "headline") -> case check_event_chatstates(From, To, Packet) of true -> #jid{luser = LUser, lserver = LServer} = To, TimeStamp = now(), {xmlelement, _Name, _Attrs, Els} = Packet, Expire = find_x_expire(TimeStamp, Els), gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) ! #offline_msg{us = {LUser, LServer}, timestamp = TimeStamp, expire = Expire, from = From, to = To, packet = Packet}, stop; _ -> ok end; true -> ok end. %% Check if the packet has any content about XEP-0022 or XEP-0085 check_event_chatstates(From, To, Packet) -> {xmlelement, Name, Attrs, Els} = Packet, case find_x_event_chatstates(Els, {false, false, false}) of %% There wasn't any x:event or chatstates subelements {false, false, _} -> true; %% There a chatstates subelement and other stuff, but no x:event {false, CEl, true} when CEl /= false -> true; %% There was only a subelement: a chatstates {false, CEl, false} when CEl /= false -> %% Don't allow offline storage false; %% There was an x:event element, and maybe also other stuff {El, _, _} when El /= false -> case xml:get_subtag(El, "id") of false -> case xml:get_subtag(El, "offline") of false -> true; _ -> ID = case xml:get_tag_attr_s("id", Packet) of "" -> {xmlelement, "id", [], []}; S -> {xmlelement, "id", [], [{xmlcdata, S}]} end, ejabberd_router:route( To, From, {xmlelement, Name, Attrs, [{xmlelement, "x", [{"xmlns", ?NS_EVENT}], [ID, {xmlelement, "offline", [], []}]}] }), true end; _ -> false end end. %% Check if the packet has subelements about XEP-0022, XEP-0085 or other find_x_event_chatstates([], Res) -> Res; find_x_event_chatstates([{xmlcdata, _} | Els], Res) -> find_x_event_chatstates(Els, Res); find_x_event_chatstates([El | Els], {A, B, C}) -> case xml:get_tag_attr_s("xmlns", El) of ?NS_EVENT -> find_x_event_chatstates(Els, {El, B, C}); ?NS_CHATSTATES -> find_x_event_chatstates(Els, {A, El, C}); _ -> find_x_event_chatstates(Els, {A, B, true}) end. find_x_expire(_, []) -> never; find_x_expire(TimeStamp, [{xmlcdata, _} | Els]) -> find_x_expire(TimeStamp, Els); find_x_expire(TimeStamp, [El | Els]) -> case xml:get_tag_attr_s("xmlns", El) of ?NS_EXPIRE -> Val = xml:get_tag_attr_s("seconds", El), case catch list_to_integer(Val) of {'EXIT', _} -> never; Int when Int > 0 -> {MegaSecs, Secs, MicroSecs} = TimeStamp, S = MegaSecs * 1000000 + Secs + Int, MegaSecs1 = S div 1000000, Secs1 = S rem 1000000, {MegaSecs1, Secs1, MicroSecs}; _ -> never end; _ -> find_x_expire(TimeStamp, Els) end. resend_offline_messages(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, F = fun() -> Rs = mnesia:wread({offline_msg, US}), mnesia:delete({offline_msg, US}), Rs end, case mnesia:transaction(F) of {atomic, Rs} -> lists:foreach( fun(R) -> {xmlelement, Name, Attrs, Els} = R#offline_msg.packet, ejabberd_sm ! {route, R#offline_msg.from, R#offline_msg.to, {xmlelement, Name, Attrs, Els ++ [jlib:timestamp_to_xml( calendar:now_to_universal_time( R#offline_msg.timestamp), utc, jlib:make_jid("", Server, ""), "Offline Storage"), %% TODO: Delete the next three lines once XEP-0091 is Obsolete jlib:timestamp_to_xml( calendar:now_to_universal_time( R#offline_msg.timestamp))]}} end, lists:keysort(#offline_msg.timestamp, Rs)); _ -> ok end. pop_offline_messages(Ls, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, F = fun() -> Rs = mnesia:wread({offline_msg, US}), mnesia:delete({offline_msg, US}), Rs end, case mnesia:transaction(F) of {atomic, Rs} -> TS = now(), Ls ++ lists:map( fun(R) -> {xmlelement, Name, Attrs, Els} = R#offline_msg.packet, {route, R#offline_msg.from, R#offline_msg.to, {xmlelement, Name, Attrs, Els ++ [jlib:timestamp_to_xml( calendar:now_to_universal_time( R#offline_msg.timestamp), utc, jlib:make_jid("", Server, ""), "Offline Storage"), %% TODO: Delete the next three lines once XEP-0091 is Obsolete jlib:timestamp_to_xml( calendar:now_to_universal_time( R#offline_msg.timestamp))]}} end, lists:filter( fun(R) -> case R#offline_msg.expire of never -> true; TimeStamp -> TS < TimeStamp end end, lists:keysort(#offline_msg.timestamp, Rs))); _ -> Ls end. remove_expired_messages() -> TimeStamp = now(), F = fun() -> mnesia:write_lock_table(offline_msg), mnesia:foldl( fun(Rec, _Acc) -> case Rec#offline_msg.expire of never -> ok; TS -> if TS < TimeStamp -> mnesia:delete_object(Rec); true -> ok end end end, ok, offline_msg) end, mnesia:transaction(F). remove_old_messages(Days) -> {MegaSecs, Secs, _MicroSecs} = now(), S = MegaSecs * 1000000 + Secs - 60 * 60 * 24 * Days, MegaSecs1 = S div 1000000, Secs1 = S rem 1000000, TimeStamp = {MegaSecs1, Secs1, 0}, F = fun() -> mnesia:write_lock_table(offline_msg), mnesia:foldl( fun(#offline_msg{timestamp = TS} = Rec, _Acc) when TS < TimeStamp -> mnesia:delete_object(Rec); (_Rec, _Acc) -> ok end, ok, offline_msg) end, mnesia:transaction(F). remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, F = fun() -> mnesia:delete({offline_msg, US}) end, mnesia:transaction(F). update_table() -> Fields = record_info(fields, offline_msg), case mnesia:table_info(offline_msg, attributes) of Fields -> ok; [user, timestamp, expire, from, to, packet] -> ?INFO_MSG("Converting offline_msg table from " "{user, timestamp, expire, from, to, packet} format", []), Host = ?MYNAME, {atomic, ok} = mnesia:create_table( mod_offline_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, offline_msg}, {attributes, record_info(fields, offline_msg)}]), mnesia:transform_table(offline_msg, ignore, Fields), F1 = fun() -> mnesia:write_lock_table(mod_offline_tmp_table), mnesia:foldl( fun(#offline_msg{us = U} = R, _) -> mnesia:dirty_write( mod_offline_tmp_table, R#offline_msg{us = {U, Host}}) end, ok, offline_msg) end, mnesia:transaction(F1), mnesia:clear_table(offline_msg), F2 = fun() -> mnesia:write_lock_table(offline_msg), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, mod_offline_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(mod_offline_tmp_table); [user, timestamp, from, to, packet] -> ?INFO_MSG("Converting offline_msg table from " "{user, timestamp, from, to, packet} format", []), Host = ?MYNAME, {atomic, ok} = mnesia:create_table( mod_offline_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, offline_msg}, {attributes, record_info(fields, offline_msg)}]), mnesia:transform_table( offline_msg, fun({_, U, TS, F, T, P}) -> {xmlelement, _Name, _Attrs, Els} = P, Expire = find_x_expire(TS, Els), #offline_msg{us = U, timestamp = TS, expire = Expire, from = F, to = T, packet = P} end, Fields), F1 = fun() -> mnesia:write_lock_table(mod_offline_tmp_table), mnesia:foldl( fun(#offline_msg{us = U} = R, _) -> mnesia:dirty_write( mod_offline_tmp_table, R#offline_msg{us = {U, Host}}) end, ok, offline_msg) end, mnesia:transaction(F1), mnesia:clear_table(offline_msg), F2 = fun() -> mnesia:write_lock_table(offline_msg), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, mod_offline_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(mod_offline_tmp_table); _ -> ?INFO_MSG("Recreating offline_msg table", []), mnesia:transform_table(offline_msg, ignore, Fields) end. %% Helper functions: %% Warn senders that their messages have been discarded: discard_warn_sender(Msgs) -> lists:foreach( fun(#offline_msg{from=From, to=To, packet=Packet}) -> ErrText = "Your contact offline message queue is full. The message has been discarded.", Lang = xml:get_tag_attr_s("xml:lang", Packet), Err = jlib:make_error_reply( Packet, ?ERRT_RESOURCE_CONSTRAINT(Lang, ErrText)), ejabberd_router:route( To, From, Err) end, Msgs). webadmin_page(_, Host, #request{us = _US, path = ["user", U, "queue"], q = Query, lang = Lang} = _Request) -> Res = user_queue(U, Host, Query, Lang), {stop, Res}; webadmin_page(Acc, _, _) -> Acc. user_queue(User, Server, Query, Lang) -> US = {jlib:nodeprep(User), jlib:nameprep(Server)}, Res = user_queue_parse_query(US, Query), MsgsAll = lists:keysort(#offline_msg.timestamp, mnesia:dirty_read({offline_msg, US})), Msgs = get_messages_subset(User, Server, MsgsAll), FMsgs = lists:map( fun(#offline_msg{timestamp = TimeStamp, from = From, to = To, packet = {xmlelement, Name, Attrs, Els}} = Msg) -> ID = jlib:encode_base64(binary_to_list(term_to_binary(Msg))), {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:now_to_local_time(TimeStamp), Time = lists:flatten( io_lib:format( "~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Year, Month, Day, Hour, Minute, Second])), SFrom = jlib:jid_to_string(From), STo = jlib:jid_to_string(To), Attrs2 = jlib:replace_from_to_attrs(SFrom, STo, Attrs), Packet = {xmlelement, Name, Attrs2, Els}, FPacket = ejabberd_web_admin:pretty_print_xml(Packet), ?XE("tr", [?XAE("td", [{"class", "valign"}], [?INPUT("checkbox", "selected", ID)]), ?XAC("td", [{"class", "valign"}], Time), ?XAC("td", [{"class", "valign"}], SFrom), ?XAC("td", [{"class", "valign"}], STo), ?XAE("td", [{"class", "valign"}], [?XC("pre", FPacket)])] ) end, Msgs), [?XC("h1", io_lib:format(?T("~s's Offline Messages Queue"), [us_to_list(US)]))] ++ case Res of ok -> [?XREST("Submitted")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [?XE("table", [?XE("thead", [?XE("tr", [?X("td"), ?XCT("td", "Time"), ?XCT("td", "From"), ?XCT("td", "To"), ?XCT("td", "Packet") ])]), ?XE("tbody", if FMsgs == [] -> [?XE("tr", [?XAC("td", [{"colspan", "4"}], " ")] )]; true -> FMsgs end )]), ?BR, ?INPUTT("submit", "delete", "Delete Selected") ])]. user_queue_parse_query(US, Query) -> case lists:keysearch("delete", 1, Query) of {value, _} -> Msgs = lists:keysort(#offline_msg.timestamp, mnesia:dirty_read({offline_msg, US})), F = fun() -> lists:foreach( fun(Msg) -> ID = jlib:encode_base64( binary_to_list(term_to_binary(Msg))), case lists:member({"selected", ID}, Query) of true -> mnesia:delete_object(Msg); false -> ok end end, Msgs) end, mnesia:transaction(F), ok; false -> nothing end. us_to_list({User, Server}) -> jlib:jid_to_string({User, Server, ""}). get_queue_length(User, Server) -> length(mnesia:dirty_read({offline_msg, {User, Server}})). get_messages_subset(User, Host, MsgsAll) -> Access = gen_mod:get_module_opt(Host, ?MODULE, access_max_user_messages, max_user_offline_messages), MaxOfflineMsgs = case get_max_user_messages(Access, User, Host) of Number when is_integer(Number) -> Number; _ -> 100 end, Length = length(MsgsAll), get_messages_subset2(MaxOfflineMsgs, Length, MsgsAll). get_messages_subset2(Max, Length, MsgsAll) when Length =< Max*2 -> MsgsAll; get_messages_subset2(Max, Length, MsgsAll) -> FirstN = Max, {MsgsFirstN, Msgs2} = lists:split(FirstN, MsgsAll), MsgsLastN = lists:nthtail(Length - FirstN - FirstN, Msgs2), NoJID = jlib:make_jid("...", "...", ""), IntermediateMsg = #offline_msg{timestamp = now(), from = NoJID, to = NoJID, packet = {xmlelement, "...", [], []}}, MsgsFirstN ++ [IntermediateMsg] ++ MsgsLastN. webadmin_user(Acc, User, Server, Lang) -> QueueLen = get_queue_length(jlib:nodeprep(User), jlib:nameprep(Server)), FQueueLen = [?AC("queue/", integer_to_list(QueueLen))], Acc ++ [?XCT("h3", "Offline Messages:")] ++ FQueueLen ++ [?C(" "), ?INPUTT("submit", "removealloffline", "Remove All Offline Messages")]. webadmin_user_parse_query(_, "removealloffline", User, Server, _Query) -> US = {User, Server}, F = fun() -> mnesia:write_lock_table(offline_msg), lists:foreach( fun(Msg) -> mnesia:delete_object(Msg) end, mnesia:dirty_read({offline_msg, US})) end, case mnesia:transaction(F) of {aborted, Reason} -> ?ERROR_MSG("Failed to remove offline messages: ~p", [Reason]), {stop, error}; {atomic, ok} -> ?INFO_MSG("Removed all offline messages for ~s@~s", [User, Server]), {stop, ok} end; webadmin_user_parse_query(Acc, _Action, _User, _Server, _Query) -> Acc. ejabberd-2.1.11/src/mod_shared_roster_ldap.erl0000664000000000000000000005517112240230175016225 0ustar %%%------------------------------------------------------------------- %%% File : mod_shared_roster_ldap.erl %%% Author : Realloc %%% Marcin Owsiany %%% Evgeniy Khramtsov %%% Description : LDAP shared roster management %%% Created : 5 Mar 2005 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(mod_shared_roster_ldap). -behaviour(gen_server). -behaviour(gen_mod). %% API -export([start_link/2, start/2, stop/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([get_user_roster/2, get_subscription_lists/3, get_jid_info/4, process_item/2, in_subscription/6, out_subscription/4]). -include("ejabberd.hrl"). -include("mod_roster.hrl"). -include("eldap/eldap.hrl"). -define(CACHE_SIZE, 1000). -define(USER_CACHE_VALIDITY, 300). %% in seconds -define(GROUP_CACHE_VALIDITY, 300). %% in seconds -define(LDAP_SEARCH_TIMEOUT, 5). %% Timeout for LDAP search queries in seconds -record(state, {host, eldap_id, servers, backups, port, tls_options, dn, base, password, uid, deref_aliases, group_attr, group_desc, user_desc, user_uid, uid_format, uid_format_re, filter, ufilter, rfilter, gfilter, auth_check, user_cache_size, group_cache_size, user_cache_validity, group_cache_validity}). -record(group_info, {desc, members}). %%==================================================================== %% API %%==================================================================== start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), ChildSpec = { Proc, {?MODULE, start_link, [Host, Opts]}, permanent, 1000, worker, [?MODULE] }, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). %%-------------------------------------------------------------------- %% Hooks %%-------------------------------------------------------------------- get_user_roster(Items, {U, S} = US) -> SRUsers = get_user_to_groups_map(US, true), %% If partially subscribed users are also in shared roster, %% show them as totally subscribed: {NewItems1, SRUsersRest} = lists:mapfoldl( fun(Item, SRUsers1) -> {_, _, {U1, S1, _}} = Item#roster.usj, US1 = {U1, S1}, case dict:find(US1, SRUsers1) of {ok, _GroupNames} -> {Item#roster{subscription = both, ask = none}, dict:erase(US1, SRUsers1)}; error -> {Item, SRUsers1} end end, SRUsers, Items), %% Export items in roster format: SRItems = [#roster{usj = {U, S, {U1, S1, ""}}, us = US, jid = {U1, S1, ""}, name = get_user_name(U1,S1), subscription = both, ask = none, groups = GroupNames} || {{U1, S1}, GroupNames} <- dict:to_list(SRUsersRest)], SRItems ++ NewItems1. %% This function in use to rewrite the roster entries when moving or renaming %% them in the user contact list. process_item(RosterItem, _Host) -> USFrom = RosterItem#roster.us, {User,Server,_Resource} = RosterItem#roster.jid, USTo = {User,Server}, Map = get_user_to_groups_map(USFrom, false), case dict:find(USTo, Map) of error -> RosterItem; {ok, []} -> RosterItem; {ok, GroupNames} when RosterItem#roster.subscription == remove -> %% Roster item cannot be removed: %% We simply reset the original groups: RosterItem#roster{subscription = both, ask = none, groups=GroupNames}; _ -> RosterItem#roster{subscription = both, ask = none} end. get_subscription_lists({F, T}, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, DisplayedGroups = get_user_displayed_groups(US), SRUsers = lists:usort( lists:flatmap( fun(Group) -> get_group_users(LServer, Group) end, DisplayedGroups)), SRJIDs = [{U1, S1, ""} || {U1, S1} <- SRUsers], {lists:usort(SRJIDs ++ F), lists:usort(SRJIDs ++ T)}. get_jid_info({Subscription, Groups}, User, Server, JID) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, {U1, S1, _} = jlib:jid_tolower(JID), US1 = {U1, S1}, SRUsers = get_user_to_groups_map(US, false), case dict:find(US1, SRUsers) of {ok, GroupNames} -> NewGroups = if Groups == [] -> GroupNames; true -> Groups end, {both, NewGroups}; error -> {Subscription, Groups} end. in_subscription(Acc, User, Server, JID, Type, _Reason) -> process_subscription(in, User, Server, JID, Type, Acc). out_subscription(User, Server, JID, Type) -> process_subscription(out, User, Server, JID, Type, false). process_subscription(Direction, User, Server, JID, _Type, Acc) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, {U1, S1, _} = jlib:jid_tolower(jlib:jid_remove_resource(JID)), US1 = {U1, S1}, DisplayedGroups = get_user_displayed_groups(US), SRUsers = lists:usort( lists:flatmap( fun(Group) -> get_group_users(LServer, Group) end, DisplayedGroups)), case lists:member(US1, SRUsers) of true -> case Direction of in -> {stop, false}; out -> stop end; false -> Acc end. %%==================================================================== %% gen_server callbacks %%==================================================================== init([Host, Opts]) -> State = parse_options(Host, Opts), cache_tab:new(shared_roster_ldap_user, [{max_size, State#state.user_cache_size}, {lru, false}, % We don't need LRU algorithm {life_time, State#state.user_cache_validity}]), cache_tab:new(shared_roster_ldap_group, [{max_size, State#state.group_cache_size}, {lru, false}, % We don't need LRU algorithm {life_time, State#state.group_cache_validity}]), ejabberd_hooks:add(roster_get, Host, ?MODULE, get_user_roster, 70), ejabberd_hooks:add(roster_in_subscription, Host, ?MODULE, in_subscription, 30), ejabberd_hooks:add(roster_out_subscription, Host, ?MODULE, out_subscription, 30), ejabberd_hooks:add(roster_get_subscription_lists, Host, ?MODULE, get_subscription_lists, 70), ejabberd_hooks:add(roster_get_jid_info, Host, ?MODULE, get_jid_info, 70), ejabberd_hooks:add(roster_process_item, Host, ?MODULE, process_item, 50), eldap_pool:start_link(State#state.eldap_id, State#state.servers, State#state.backups, State#state.port, State#state.dn, State#state.password, State#state.tls_options), {ok, State}. handle_call(get_state, _From, State) -> {reply, {ok, State}, State}; handle_call(_Request, _From, State) -> {reply, {error, badarg}, State}. handle_cast(_Msg, State) -> {noreply, State}. handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, State) -> Host = State#state.host, ejabberd_hooks:delete(roster_get, Host, ?MODULE, get_user_roster, 70), ejabberd_hooks:delete(roster_in_subscription, Host, ?MODULE, in_subscription, 30), ejabberd_hooks:delete(roster_out_subscription, Host, ?MODULE, out_subscription, 30), ejabberd_hooks:delete(roster_get_subscription_lists, Host, ?MODULE, get_subscription_lists, 70), ejabberd_hooks:delete(roster_get_jid_info, Host, ?MODULE, get_jid_info, 70), ejabberd_hooks:delete(roster_process_item, Host, ?MODULE, process_item, 50). code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- %% For a given user, map all his shared roster contacts to groups they are %% members of. Skip the user himself iff SkipUS is true. get_user_to_groups_map({_, Server} = US, SkipUS) -> DisplayedGroups = get_user_displayed_groups(US), lists:foldl( fun(Group, Dict1) -> GroupName = get_group_name(Server, Group), lists:foldl( fun(Contact, Dict) -> if SkipUS, Contact == US -> Dict; true -> dict:append(Contact, GroupName, Dict) end end, Dict1, get_group_users(Server, Group)) end, dict:new(), DisplayedGroups). %% Pass given FilterParseArgs to eldap_filter:parse, and if successful, run and %% return the resulting filter, retrieving given AttributesList. Return the %% result entries. On any error silently return an empty list of results. %% %% Eldap server ID and base DN for the query are both retrieved from the State %% record. eldap_search(State, FilterParseArgs, AttributesList) -> case apply(eldap_filter, parse, FilterParseArgs) of {ok, EldapFilter} -> %% Filter parsing succeeded case eldap_pool:search(State#state.eldap_id, [{base, State#state.base}, {filter, EldapFilter}, {timeout, ?LDAP_SEARCH_TIMEOUT}, {deref_aliases, State#state.deref_aliases}, {attributes, AttributesList}]) of #eldap_search_result{entries = Es} -> %% A result with entries. Return their list. Es; _ -> %% Something else. Pretend we got no results. [] end; _ -> %% Filter parsing failed. Pretend we got no results. [] end. get_user_displayed_groups({User, Host}) -> {ok, State} = eldap_utils:get_state(Host, ?MODULE), GroupAttr = State#state.group_attr, Entries = eldap_search( State, [eldap_filter:do_sub(State#state.rfilter, [{"%u", User}])], [GroupAttr]), Reply = lists:flatmap( fun(#eldap_entry{attributes = Attrs}) -> case Attrs of [{GroupAttr, ValuesList}] -> ValuesList; _ -> [] end end, Entries), lists:usort(Reply). get_group_users(Host, Group) -> {ok, State} = eldap_utils:get_state(Host, ?MODULE), case cache_tab:dirty_lookup( shared_roster_ldap_group, {Group, Host}, fun() -> search_group_info(State, Group) end) of {ok, #group_info{members = Members}} when Members /= undefined -> Members; _ -> [] end. get_group_name(Host, Group) -> {ok, State} = eldap_utils:get_state(Host, ?MODULE), case cache_tab:dirty_lookup( shared_roster_ldap_group, {Group, Host}, fun() -> search_group_info(State, Group) end) of {ok, #group_info{desc = GroupName}} when GroupName /= undefined -> GroupName; _ -> Group end. get_user_name(User, Host) -> {ok, State} = eldap_utils:get_state(Host, ?MODULE), case cache_tab:dirty_lookup( shared_roster_ldap_user, {User, Host}, fun() -> search_user_name(State, User) end) of {ok, UserName} -> UserName; error -> User end. search_group_info(State, Group) -> Extractor = case State#state.uid_format_re of "" -> fun(UID) -> catch eldap_utils:get_user_part(UID, State#state.uid_format) end; _ -> fun(UID) -> catch get_user_part_re(UID, State#state.uid_format_re) end end, AuthChecker = case State#state.auth_check of true -> fun ejabberd_auth:is_user_exists/2; _ -> fun(_U, _S) -> true end end, Host = State#state.host, case eldap_search( State, [eldap_filter:do_sub(State#state.gfilter, [{"%g", Group}])], [State#state.group_attr, State#state.group_desc, State#state.uid]) of [] -> error; LDAPEntries -> {GroupDesc, MembersLists} = lists:foldl( fun(#eldap_entry{attributes=Attrs}, {DescAcc, JIDsAcc}) -> case {eldap_utils:get_ldap_attr(State#state.group_attr, Attrs), eldap_utils:get_ldap_attr(State#state.group_desc, Attrs), lists:keysearch(State#state.uid, 1, Attrs)} of {ID, Desc, {value, {GroupMemberAttr, Members}}} when ID /= "", GroupMemberAttr == State#state.uid -> JIDs = lists:foldl( fun({ok, UID}, L) -> PUID = jlib:nodeprep(UID), case PUID of error -> L; _ -> case AuthChecker(PUID, Host) of true -> [{PUID, Host} | L]; _ -> L end end; (_, L) -> L end, [], lists:map(Extractor, Members)), {Desc, [JIDs|JIDsAcc]}; _ -> {DescAcc, JIDsAcc} end end, {Group, []}, LDAPEntries), {ok, #group_info{desc = GroupDesc, members = lists:usort(lists:flatten(MembersLists))}} end. search_user_name(State, User) -> case eldap_search( State, [eldap_filter:do_sub(State#state.ufilter, [{"%u", User}])], [State#state.user_desc, State#state.user_uid]) of [#eldap_entry{attributes=Attrs}|_] -> case {eldap_utils:get_ldap_attr(State#state.user_uid, Attrs), eldap_utils:get_ldap_attr(State#state.user_desc, Attrs)} of {UID, Desc} when UID /= "" -> %% By returning "" get_ldap_attr means "not found" {ok, Desc}; _ -> error end; [] -> error end. %% Getting User ID part by regex pattern get_user_part_re(String, Pattern) -> case catch re:run(String, Pattern) of {match, Captured} -> {First, Len} = lists:nth(2,Captured), Result = string:sub_string(String, First+1, First+Len), {ok,Result}; _ -> {error, badmatch} end. parse_options(Host, Opts) -> Eldap_ID = atom_to_list(gen_mod:get_module_proc(Host, ?MODULE)), LDAPServers = case gen_mod:get_opt(ldap_servers, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_servers, Host}); S -> S end, LDAPBackups = case gen_mod:get_opt(ldap_backups, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_servers, Host}); Backups -> Backups end, LDAPEncrypt = case gen_mod:get_opt(ldap_encrypt, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_encrypt, Host}); E -> E end, LDAPTLSVerify = case gen_mod:get_opt(ldap_tls_verify, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_tls_verify, Host}); Verify -> Verify end, LDAPTLSCAFile = case gen_mod:get_opt(ldap_tls_cacertfile, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_tls_cacertfile, Host}); CAFile -> CAFile end, LDAPTLSDepth = case gen_mod:get_opt(ldap_tls_depth, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_tls_depth, Host}); Depth -> Depth end, LDAPPort = case gen_mod:get_opt(ldap_port, Opts, undefined) of undefined -> case ejabberd_config:get_local_option({ldap_port, Host}) of undefined -> case LDAPEncrypt of tls -> ?LDAPS_PORT; starttls -> ?LDAP_PORT; _ -> ?LDAP_PORT end; P -> P end; P -> P end, LDAPBase = case gen_mod:get_opt(ldap_base, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_base, Host}); B -> B end, GroupAttr = case gen_mod:get_opt(ldap_groupattr, Opts, undefined) of undefined -> "cn"; GA -> GA end, GroupDesc = case gen_mod:get_opt(ldap_groupdesc, Opts, undefined) of undefined -> GroupAttr; GD -> GD end, UserDesc = case gen_mod:get_opt(ldap_userdesc, Opts, undefined) of undefined -> "cn"; UD -> UD end, UserUID = case gen_mod:get_opt(ldap_useruid, Opts, undefined) of undefined -> "cn"; UU -> UU end, UIDAttr = case gen_mod:get_opt(ldap_memberattr, Opts, undefined) of undefined -> "memberUid"; UA -> UA end, UIDAttrFormat = case gen_mod:get_opt(ldap_memberattr_format, Opts, undefined) of undefined -> "%u"; UAF -> UAF end, UIDAttrFormatRe = case gen_mod:get_opt(ldap_memberattr_format_re, Opts, undefined) of undefined -> ""; UAFre -> case catch re:compile(UAFre) of {ok, MP} -> MP; _ -> ?ERROR_MSG("Invalid ldap_memberattr_format_re '~s' " "or no RE support in this erlang version. " "ldap_memberattr_format '~s' will be used " "instead.", [UAFre, UIDAttrFormat]), "" end end, AuthCheck = case gen_mod:get_opt(ldap_auth_check, Opts, undefined) of undefined -> true; on -> true; AC -> AC end, RootDN = case gen_mod:get_opt(ldap_rootdn, Opts, undefined) of undefined -> case ejabberd_config:get_local_option({ldap_rootdn, Host}) of undefined -> ""; RDN -> RDN end; RDN -> RDN end, Password = case gen_mod:get_opt(ldap_password, Opts, undefined) of undefined -> case ejabberd_config:get_local_option({ldap_password, Host}) of undefined -> ""; Pass -> Pass end; Pass -> Pass end, UserCacheValidity = case gen_mod:get_opt(ldap_user_cache_validity, Opts, undefined) of undefined -> case ejabberd_config:get_local_option({ldap_user_cache_validity, Host}) of undefined -> ?USER_CACHE_VALIDITY; UVSeconds -> UVSeconds end; UVSeconds -> UVSeconds end, GroupCacheValidity = case gen_mod:get_opt(ldap_group_cache_validity, Opts, undefined) of undefined -> case ejabberd_config:get_local_option({ldap_group_cache_validity, Host}) of undefined -> ?GROUP_CACHE_VALIDITY; GVSeconds -> GVSeconds end; GVSeconds -> GVSeconds end, UserCacheSize = case gen_mod:get_opt(ldap_user_cache_size, Opts, undefined) of undefined -> case ejabberd_config:get_local_option({ldap_user_cache_size, Host}) of undefined -> ?CACHE_SIZE; USSeconds -> USSeconds end; USSeconds -> USSeconds end, GroupCacheSize = case gen_mod:get_opt(ldap_group_cache_size, Opts, undefined) of undefined -> case ejabberd_config:get_local_option({ldap_group_cache_size, Host}) of undefined -> ?CACHE_SIZE; GSSeconds -> GSSeconds end; GSSeconds -> GSSeconds end, ConfigFilter = case gen_mod:get_opt(ldap_filter, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_filter, Host}); F -> F end, ConfigUserFilter = case gen_mod:get_opt(ldap_ufilter, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_ufilter, Host}); UF -> UF end, ConfigGroupFilter = case gen_mod:get_opt(ldap_gfilter, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_gfilter, Host}); GF -> GF end, RosterFilter = case gen_mod:get_opt(ldap_rfilter, Opts, undefined) of undefined -> ejabberd_config:get_local_option({ldap_rfilter, Host}); RF -> RF end, lists:foreach(fun eldap_utils:check_filter/1, [ConfigFilter, ConfigUserFilter, ConfigGroupFilter, RosterFilter]), SubFilter = "(&("++UIDAttr++"="++UIDAttrFormat++")("++GroupAttr++"=%g))", UserSubFilter = case ConfigUserFilter of undefined -> eldap_filter:do_sub(SubFilter, [{"%g", "*"}]); "" -> eldap_filter:do_sub(SubFilter, [{"%g", "*"}]); UString -> UString end, GroupSubFilter = case ConfigGroupFilter of undefined -> eldap_filter:do_sub(SubFilter, [{"%u", "*"}]); "" -> eldap_filter:do_sub(SubFilter, [{"%u", "*"}]); GString -> GString end, Filter = case ConfigFilter of undefined -> SubFilter; "" -> SubFilter; _ -> "(&" ++ SubFilter ++ ConfigFilter ++ ")" end, UserFilter = case ConfigFilter of undefined -> UserSubFilter; "" -> UserSubFilter; _ -> "(&" ++ UserSubFilter ++ ConfigFilter ++ ")" end, GroupFilter = case ConfigFilter of undefined -> GroupSubFilter; "" -> GroupSubFilter; _ -> "(&" ++ GroupSubFilter ++ ConfigFilter ++ ")" end, DerefAliases = case gen_mod:get_opt(deref_aliases, Opts, undefined) of undefined -> case ejabberd_config:get_local_option( {deref_aliases, Host}) of undefined -> never; D -> D end; D -> D end, #state{host = Host, eldap_id = Eldap_ID, servers = LDAPServers, backups = LDAPBackups, port = LDAPPort, tls_options = [{encrypt, LDAPEncrypt}, {tls_verify, LDAPTLSVerify}, {tls_cacertfile, LDAPTLSCAFile}, {tls_depth, LDAPTLSDepth}], dn = RootDN, base = LDAPBase, password = Password, uid = UIDAttr, deref_aliases = DerefAliases, group_attr = GroupAttr, group_desc = GroupDesc, user_desc = UserDesc, user_uid = UserUID, uid_format = UIDAttrFormat, uid_format_re = UIDAttrFormatRe, filter = Filter, ufilter = UserFilter, rfilter = RosterFilter, gfilter = GroupFilter, auth_check = AuthCheck, user_cache_size = UserCacheSize, user_cache_validity = UserCacheValidity, group_cache_size = GroupCacheSize, group_cache_validity = GroupCacheValidity}. ejabberd-2.1.11/src/install-sh0000664000000000000000000003253712240230175013020 0ustar #!/bin/sh # install - install a program, script, or datafile scriptversion=2009-04-28.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: ejabberd-2.1.11/src/ejabberd_s2s.erl0000664000000000000000000004432512240230175014046 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_s2s.erl %%% Author : Alexey Shchepin %%% Purpose : S2S connections manager %%% Created : 7 Dec 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_s2s). -author('alexey@process-one.net'). -behaviour(gen_server). %% API -export([start_link/0, route/3, have_connection/1, has_key/2, get_connections_pids/1, try_register/1, remove_connection/3, find_connection/2, dirty_get_connections/0, allow_host/2, incoming_s2s_number/0, outgoing_s2s_number/0, clean_temporarily_blocked_table/0, list_temporarily_blocked_hosts/0, external_host_overloaded/1, is_temporarly_blocked/1 ]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% ejabberd API -export([get_info_s2s_connections/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("ejabberd_commands.hrl"). -define(DEFAULT_MAX_S2S_CONNECTIONS_NUMBER, 1). -define(DEFAULT_MAX_S2S_CONNECTIONS_NUMBER_PER_NODE, 1). -define(S2S_OVERLOAD_BLOCK_PERIOD, 60). %% once a server is temporarly blocked, it stay blocked for 60 seconds -record(s2s, {fromto, pid, key}). -record(state, {}). -record(temporarily_blocked, {host, timestamp}). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). route(From, To, Packet) -> case catch do_route(From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p~nwhen processing: ~p", [Reason, {From, To, Packet}]); _ -> ok end. clean_temporarily_blocked_table() -> mnesia:clear_table(temporarily_blocked). list_temporarily_blocked_hosts() -> ets:tab2list(temporarily_blocked). external_host_overloaded(Host) -> ?INFO_MSG("Disabling connections from ~s for ~p seconds", [Host, ?S2S_OVERLOAD_BLOCK_PERIOD]), mnesia:transaction( fun() -> mnesia:write(#temporarily_blocked{host = Host, timestamp = now()}) end). is_temporarly_blocked(Host) -> case mnesia:dirty_read(temporarily_blocked, Host) of [] -> false; [#temporarily_blocked{timestamp = T}=Entry] -> case timer:now_diff(now(), T) of N when N > ?S2S_OVERLOAD_BLOCK_PERIOD * 1000 * 1000 -> mnesia:dirty_delete_object(Entry), false; _ -> true end end. remove_connection(FromTo, Pid, Key) -> case catch mnesia:dirty_match_object(s2s, #s2s{fromto = FromTo, pid = Pid, _ = '_'}) of [#s2s{pid = Pid, key = Key}] -> F = fun() -> mnesia:delete_object(#s2s{fromto = FromTo, pid = Pid, key = Key}) end, mnesia:transaction(F); _ -> ok end. have_connection(FromTo) -> case catch mnesia:dirty_read(s2s, FromTo) of [_] -> true; _ -> false end. has_key(FromTo, Key) -> case mnesia:dirty_select(s2s, [{#s2s{fromto = FromTo, key = Key, _ = '_'}, [], ['$_']}]) of [] -> false; _ -> true end. get_connections_pids(FromTo) -> case catch mnesia:dirty_read(s2s, FromTo) of L when is_list(L) -> [Connection#s2s.pid || Connection <- L]; _ -> [] end. try_register(FromTo) -> Key = randoms:get_string(), MaxS2SConnectionsNumber = max_s2s_connections_number(FromTo), MaxS2SConnectionsNumberPerNode = max_s2s_connections_number_per_node(FromTo), F = fun() -> L = mnesia:read({s2s, FromTo}), NeededConnections = needed_connections_number( L, MaxS2SConnectionsNumber, MaxS2SConnectionsNumberPerNode), if NeededConnections > 0 -> mnesia:write(#s2s{fromto = FromTo, pid = self(), key = Key}), {key, Key}; true -> false end end, case mnesia:transaction(F) of {atomic, Res} -> Res; _ -> false end. dirty_get_connections() -> mnesia:dirty_all_keys(s2s). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([]) -> update_tables(), mnesia:create_table(s2s, [{ram_copies, [node()]}, {type, bag}, {attributes, record_info(fields, s2s)}]), mnesia:add_table_copy(s2s, node(), ram_copies), mnesia:subscribe(system), ejabberd_commands:register_commands(commands()), mnesia:create_table(temporarily_blocked, [{ram_copies, [node()]}, {attributes, record_info(fields, temporarily_blocked)}]), {ok, #state{}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({mnesia_system_event, {mnesia_down, Node}}, State) -> clean_table_from_bad_node(Node), {noreply, State}; handle_info({route, From, To, Packet}, State) -> case catch do_route(From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p~nwhen processing: ~p", [Reason, {From, To, Packet}]); _ -> ok end, {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ejabberd_commands:unregister_commands(commands()), ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- clean_table_from_bad_node(Node) -> F = fun() -> Es = mnesia:select( s2s, [{#s2s{pid = '$1', _ = '_'}, [{'==', {node, '$1'}, Node}], ['$_']}]), lists:foreach(fun(E) -> mnesia:delete_object(E) end, Es) end, mnesia:async_dirty(F). do_route(From, To, Packet) -> ?DEBUG("s2s manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n", [From, To, Packet, 8]), case find_connection(From, To) of {atomic, Pid} when is_pid(Pid) -> ?DEBUG("sending to process ~p~n", [Pid]), {xmlelement, Name, Attrs, Els} = Packet, NewAttrs = jlib:replace_from_to_attrs(jlib:jid_to_string(From), jlib:jid_to_string(To), Attrs), #jid{lserver = MyServer} = From, ejabberd_hooks:run( s2s_send_packet, MyServer, [From, To, Packet]), send_element(Pid, {xmlelement, Name, NewAttrs, Els}), ok; {aborted, _Reason} -> case xml:get_tag_attr_s("type", Packet) of "error" -> ok; "result" -> ok; _ -> Err = jlib:make_error_reply( Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err) end, false end. find_connection(From, To) -> #jid{lserver = MyServer} = From, #jid{lserver = Server} = To, FromTo = {MyServer, Server}, MaxS2SConnectionsNumber = max_s2s_connections_number(FromTo), MaxS2SConnectionsNumberPerNode = max_s2s_connections_number_per_node(FromTo), ?DEBUG("Finding connection for ~p~n", [FromTo]), case catch mnesia:dirty_read(s2s, FromTo) of {'EXIT', Reason} -> {aborted, Reason}; [] -> %% We try to establish all the connections if the host is not a %% service and if the s2s host is not blacklisted or %% is in whitelist: case not is_service(From, To) andalso allow_host(MyServer, Server) of true -> NeededConnections = needed_connections_number( [], MaxS2SConnectionsNumber, MaxS2SConnectionsNumberPerNode), open_several_connections( NeededConnections, MyServer, Server, From, FromTo, MaxS2SConnectionsNumber, MaxS2SConnectionsNumberPerNode); false -> {aborted, error} end; L when is_list(L) -> NeededConnections = needed_connections_number( L, MaxS2SConnectionsNumber, MaxS2SConnectionsNumberPerNode), if NeededConnections > 0 -> %% We establish the missing connections for this pair. open_several_connections( NeededConnections, MyServer, Server, From, FromTo, MaxS2SConnectionsNumber, MaxS2SConnectionsNumberPerNode); true -> %% We choose a connexion from the pool of opened ones. {atomic, choose_connection(From, L)} end end. choose_connection(From, Connections) -> choose_pid(From, [C#s2s.pid || C <- Connections]). choose_pid(From, Pids) -> Pids1 = case [P || P <- Pids, node(P) == node()] of [] -> Pids; Ps -> Ps end, % Use sticky connections based on the JID of the sender (whithout % the resource to ensure that a muc room always uses the same % connection) Pid = lists:nth(erlang:phash(jlib:jid_remove_resource(From), length(Pids1)), Pids1), ?DEBUG("Using ejabberd_s2s_out ~p~n", [Pid]), Pid. open_several_connections(N, MyServer, Server, From, FromTo, MaxS2SConnectionsNumber, MaxS2SConnectionsNumberPerNode) -> ConnectionsResult = [new_connection(MyServer, Server, From, FromTo, MaxS2SConnectionsNumber, MaxS2SConnectionsNumberPerNode) || _N <- lists:seq(1, N)], case [PID || {atomic, PID} <- ConnectionsResult] of [] -> hd(ConnectionsResult); PIDs -> {atomic, choose_pid(From, PIDs)} end. new_connection(MyServer, Server, From, FromTo, MaxS2SConnectionsNumber, MaxS2SConnectionsNumberPerNode) -> Key = randoms:get_string(), {ok, Pid} = ejabberd_s2s_out:start( MyServer, Server, {new, Key}), F = fun() -> L = mnesia:read({s2s, FromTo}), NeededConnections = needed_connections_number( L, MaxS2SConnectionsNumber, MaxS2SConnectionsNumberPerNode), if NeededConnections > 0 -> mnesia:write(#s2s{fromto = FromTo, pid = Pid, key = Key}), ?INFO_MSG("New s2s connection started ~p", [Pid]), Pid; true -> choose_connection(From, L) end end, TRes = mnesia:transaction(F), case TRes of {atomic, Pid} -> ejabberd_s2s_out:start_connection(Pid); _ -> ejabberd_s2s_out:stop_connection(Pid) end, TRes. max_s2s_connections_number({From, To}) -> case acl:match_rule( From, max_s2s_connections, jlib:make_jid("", To, "")) of Max when is_integer(Max) -> Max; _ -> ?DEFAULT_MAX_S2S_CONNECTIONS_NUMBER end. max_s2s_connections_number_per_node({From, To}) -> case acl:match_rule( From, max_s2s_connections_per_node, jlib:make_jid("", To, "")) of Max when is_integer(Max) -> Max; _ -> ?DEFAULT_MAX_S2S_CONNECTIONS_NUMBER_PER_NODE end. needed_connections_number(Ls, MaxS2SConnectionsNumber, MaxS2SConnectionsNumberPerNode) -> LocalLs = [L || L <- Ls, node(L#s2s.pid) == node()], lists:min([MaxS2SConnectionsNumber - length(Ls), MaxS2SConnectionsNumberPerNode - length(LocalLs)]). %%-------------------------------------------------------------------- %% Function: is_service(From, To) -> true | false %% Description: Return true if the destination must be considered as a %% service. %% -------------------------------------------------------------------- is_service(From, To) -> LFromDomain = From#jid.lserver, case ejabberd_config:get_local_option({route_subdomains, LFromDomain}) of s2s -> % bypass RFC 3920 10.3 false; _ -> Hosts = ?MYHOSTS, P = fun(ParentDomain) -> lists:member(ParentDomain, Hosts) end, lists:any(P, parent_domains(To#jid.lserver)) end. parent_domains(Domain) -> lists:foldl( fun(Label, []) -> [Label]; (Label, [Head | Tail]) -> [Label ++ "." ++ Head, Head | Tail] end, [], lists:reverse(string:tokens(Domain, "."))). send_element(Pid, El) -> Pid ! {send_element, El}. %%%---------------------------------------------------------------------- %%% ejabberd commands commands() -> [ #ejabberd_commands{name = incoming_s2s_number, tags = [stats, s2s], desc = "Number of incoming s2s connections on the node", module = ?MODULE, function = incoming_s2s_number, args = [], result = {s2s_incoming, integer}}, #ejabberd_commands{name = outgoing_s2s_number, tags = [stats, s2s], desc = "Number of outgoing s2s connections on the node", module = ?MODULE, function = outgoing_s2s_number, args = [], result = {s2s_outgoing, integer}} ]. incoming_s2s_number() -> length(supervisor:which_children(ejabberd_s2s_in_sup)). outgoing_s2s_number() -> length(supervisor:which_children(ejabberd_s2s_out_sup)). %%%---------------------------------------------------------------------- %%% Update Mnesia tables update_tables() -> case catch mnesia:table_info(s2s, type) of bag -> ok; {'EXIT', _} -> ok; _ -> % XXX TODO convert it ? mnesia:delete_table(s2s) end, case catch mnesia:table_info(s2s, attributes) of [fromto, node, key] -> mnesia:transform_table(s2s, ignore, [fromto, pid, key]), mnesia:clear_table(s2s); [fromto, pid, key] -> ok; {'EXIT', _} -> ok end, case lists:member(local_s2s, mnesia:system_info(tables)) of true -> mnesia:delete_table(local_s2s); false -> ok end. %% Check if host is in blacklist or white list allow_host(MyServer, S2SHost) -> allow_host2(MyServer, S2SHost) andalso (not is_temporarly_blocked(S2SHost)). allow_host2(MyServer, S2SHost) -> Hosts = ?MYHOSTS, case lists:dropwhile( fun(ParentDomain) -> not lists:member(ParentDomain, Hosts) end, parent_domains(MyServer)) of [MyHost|_] -> allow_host1(MyHost, S2SHost); [] -> allow_host1(MyServer, S2SHost) end. allow_host1(MyHost, S2SHost) -> case ejabberd_config:get_local_option({{s2s_host, S2SHost}, MyHost}) of deny -> false; allow -> true; _ -> case ejabberd_config:get_local_option({s2s_default_policy, MyHost}) of deny -> false; _ -> case ejabberd_hooks:run_fold(s2s_allow_host, MyHost, allow, [MyHost, S2SHost]) of deny -> false; allow -> true; _ -> true end end end. %% Get information about S2S connections of the specified type. %% @spec (Type) -> [Info] %% where Type = in | out %% Info = [{InfoName::atom(), InfoValue::any()}] get_info_s2s_connections(Type) -> ChildType = case Type of in -> ejabberd_s2s_in_sup; out -> ejabberd_s2s_out_sup end, Connections = supervisor:which_children(ChildType), get_s2s_info(Connections,Type). get_s2s_info(Connections,Type)-> complete_s2s_info(Connections,Type,[]). complete_s2s_info([],_,Result)-> Result; complete_s2s_info([Connection|T],Type,Result)-> {_,PID,_,_}=Connection, State = get_s2s_state(PID), complete_s2s_info(T,Type,[State|Result]). get_s2s_state(S2sPid)-> Infos = case gen_fsm:sync_send_all_state_event(S2sPid,get_state_infos) of {state_infos, Is} -> [{status, open} | Is]; {noproc,_} -> [{status, closed}]; %% Connection closed {badrpc,_} -> [{status, error}] end, [{s2s_pid, S2sPid} | Infos]. ejabberd-2.1.11/src/cyrsasl_anonymous.erl0000664000000000000000000000365512240230175015312 0ustar %%%---------------------------------------------------------------------- %%% File : cyrsasl_anonymous.erl %%% Author : Magnus Henoch %%% Purpose : ANONYMOUS SASL mechanism %%% See http://www.ietf.org/internet-drafts/draft-ietf-sasl-anon-05.txt %%% Created : 23 Aug 2005 by Magnus Henoch %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(cyrsasl_anonymous). -export([start/1, stop/0, mech_new/4, mech_step/2]). -behaviour(cyrsasl). -record(state, {server}). start(_Opts) -> cyrsasl:register_mechanism("ANONYMOUS", ?MODULE, plain), ok. stop() -> ok. mech_new(Host, _GetPassword, _CheckPassword, _CheckPasswordDigest) -> {ok, #state{server = Host}}. mech_step(State, _ClientIn) -> %% We generate a random username: User = lists:concat([randoms:get_string() | tuple_to_list(now())]), Server = State#state.server, %% Checks that the username is available case ejabberd_auth:is_user_exists(User, Server) of true -> {error, "not-authorized"}; false -> {ok, [{username, User}, {auth_module, ejabberd_auth_anonymous}]} end. ejabberd-2.1.11/src/stun/0000775000000000000000000000000012240452476012010 5ustar ejabberd-2.1.11/src/stun/Makefile.win320000664000000000000000000000053012240230175014375 0ustar include ..\Makefile.inc EFLAGS = -I .. -pz .. OUTDIR = .. BEAMS = ..\stun_codec.beam ..\ejabberd_stun.beam ALL : $(BEAMS) CLEAN : -@erase $(BEAMS) $(OUTDIR)\stun_codec.beam : stun_codec.erl erlc -W $(EFLAGS) -o $(OUTDIR) stun_codec.erl $(OUTDIR)\ejabberd_stun.beam : ejabberd_stun.erl erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_stun.erl ejabberd-2.1.11/src/stun/Makefile.in0000664000000000000000000000114712240230175014046 0ustar # $Id: Makefile.in 1453 2008-07-16 16:58:42Z badlop $ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ EFLAGS += -I .. EFLAGS += -pz .. # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif OUTDIR = .. SOURCES = $(wildcard *.erl) BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) all: $(BEAMS) $(OUTDIR)/%.beam: %.erl @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< clean: rm -f $(BEAMS) distclean: clean rm -f Makefile TAGS: etags *.erl ejabberd-2.1.11/src/stun/stun.hrl0000664000000000000000000000513612240230175013503 0ustar %%%------------------------------------------------------------------- %%% File : stun.hrl %%% Author : Evgeniy Khramtsov %%% Description : STUN values %%% Created : 8 Aug 2009 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -define(STUN_MAGIC, 16#2112a442). %% I know, this is terrible. Refer to 'STUN Message Structure' of %% RFC5389 to understand this. -define(STUN_METHOD(Type), ((Type band 16#3e00) bsr 2) bor ((Type band 16#e0) bsr 1) bor (Type band 16#f)). -define(STUN_CLASS(Type), ((Type band 16#100) bsr 7) bor ((Type band 16#10) bsr 4)). -define(STUN_TYPE(C, M), (((M band 16#f80) bsl 2) bor ((M band 16#70) bsl 1) bor (M band 16#f) ) bor (((C band 16#2) bsl 7) bor ((C band 16#1) bsl 4))). -define(is_required(A), (A =< 16#7fff)). -define(STUN_METHOD_BINDING, 16#001). %% Comprehension-required range (0x0000-0x7FFF) -define(STUN_ATTR_MAPPED_ADDRESS, 16#0001). -define(STUN_ATTR_USERNAME, 16#0006). -define(STUN_ATTR_MESSAGE_INTEGRITY, 16#0008). -define(STUN_ATTR_ERROR_CODE, 16#0009). -define(STUN_ATTR_UNKNOWN_ATTRIBUTES, 16#000a). -define(STUN_ATTR_REALM, 16#0014). -define(STUN_ATTR_NONCE, 16#0015). -define(STUN_ATTR_XOR_MAPPED_ADDRESS, 16#0020). %% Comprehension-optional range (0x8000-0xFFFF) -define(STUN_ATTR_SOFTWARE, 16#8022). -define(STUN_ATTR_ALTERNATE_SERVER, 16#8023). -define(STUN_ATTR_FINGERPRINT, 16#8028). -record(stun, {class, method, magic = ?STUN_MAGIC, trid, unsupported = [], 'SOFTWARE', 'ALTERNATE-SERVER', 'MAPPED-ADDRESS', 'XOR-MAPPED-ADDRESS', 'USERNAME', 'REALM', 'NONCE', 'MESSAGE-INTEGRITY', 'ERROR-CODE', 'UNKNOWN-ATTRIBUTES' = []}). %% Workarounds. %%-define(NO_PADDING, true). ejabberd-2.1.11/src/stun/ejabberd_stun.erl0000664000000000000000000001742712240230175015324 0ustar %%%------------------------------------------------------------------- %%% File : ejabberd_stun.erl %%% Author : Evgeniy Khramtsov %%% Description : RFC5389 implementation. %%% Currently only Binding usage is supported. %%% %%% Created : 8 Aug 2009 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(ejabberd_stun). -behaviour(gen_fsm). %% API -export([start_link/2, start/2, socket_type/0, udp_recv/5]). %% gen_fsm callbacks -export([init/1, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, code_change/4]). %% gen_fsm states -export([wait_for_tls/2, session_established/2]). -include("ejabberd.hrl"). -include("stun.hrl"). -define(MAX_BUF_SIZE, 64*1024). %% 64kb -define(TIMEOUT, 10000). %% 10 sec -record(state, {sock, sock_mod = gen_tcp, certfile, peer, tref, buf = <<>>}). %%==================================================================== %% API %%==================================================================== start({gen_tcp, Sock}, Opts) -> supervisor:start_child(ejabberd_stun_sup, [Sock, Opts]). start_link(Sock, Opts) -> gen_fsm:start_link(?MODULE, [Sock, Opts], []). socket_type() -> raw. udp_recv(Sock, Addr, Port, Data, _Opts) -> case stun_codec:decode(Data) of {ok, Msg, <<>>} -> ?DEBUG("got:~n~p", [Msg]), case process(Addr, Port, Msg) of RespMsg when is_record(RespMsg, stun) -> ?DEBUG("sent:~n~p", [RespMsg]), Data1 = stun_codec:encode(RespMsg), gen_udp:send(Sock, Addr, Port, Data1); _ -> ok end; _ -> ok end. %%==================================================================== %% gen_fsm callbacks %%==================================================================== init([Sock, Opts]) -> case inet:peername(Sock) of {ok, Addr} -> inet:setopts(Sock, [{active, once}]), TRef = erlang:start_timer(?TIMEOUT, self(), stop), State = #state{sock = Sock, peer = Addr, tref = TRef}, case proplists:get_value(certfile, Opts) of undefined -> {ok, session_established, State}; CertFile -> {ok, wait_for_tls, State#state{certfile = CertFile}} end; Err -> Err end. wait_for_tls(Event, State) -> ?INFO_MSG("unexpected event in wait_for_tls: ~p", [Event]), {next_state, wait_for_tls, State}. session_established(Msg, State) when is_record(Msg, stun) -> ?DEBUG("got:~n~p", [Msg]), {Addr, Port} = State#state.peer, case process(Addr, Port, Msg) of Resp when is_record(Resp, stun) -> ?DEBUG("sent:~n~p", [Resp]), Data = stun_codec:encode(Resp), (State#state.sock_mod):send(State#state.sock, Data); _ -> ok end, {next_state, session_established, State}; session_established(Event, State) -> ?INFO_MSG("unexpected event in session_established: ~p", [Event]), {next_state, session_established, State}. handle_event(_Event, StateName, State) -> {next_state, StateName, State}. handle_sync_event(_Event, _From, StateName, State) -> {reply, {error, badarg}, StateName, State}. handle_info({tcp, Sock, TLSData}, wait_for_tls, State) -> Buf = <<(State#state.buf)/binary, TLSData/binary>>, %% Check if the initial message is a TLS handshake case Buf of _ when size(Buf) < 3 -> {next_state, wait_for_tls, update_state(State#state{buf = Buf})}; <<_:16, 1, _/binary>> -> TLSOpts = [{certfile, State#state.certfile}], {ok, TLSSock} = tls:tcp_to_tls(Sock, TLSOpts), NewState = State#state{sock = TLSSock, buf = <<>>, sock_mod = tls}, case tls:recv_data(TLSSock, Buf) of {ok, Data} -> process_data(session_established, NewState, Data); _Err -> {stop, normal, NewState} end; _ -> process_data(session_established, State, TLSData) end; handle_info({tcp, _Sock, TLSData}, StateName, #state{sock_mod = tls} = State) -> case tls:recv_data(State#state.sock, TLSData) of {ok, Data} -> process_data(StateName, State, Data); _Err -> {stop, normal, State} end; handle_info({tcp, _Sock, Data}, StateName, State) -> process_data(StateName, State, Data); handle_info({tcp_closed, _Sock}, _StateName, State) -> ?DEBUG("connection reset by peer", []), {stop, normal, State}; handle_info({tcp_error, _Sock, Reason}, _StateName, State) -> ?DEBUG("connection error: ~p", [Reason]), {stop, normal, State}; handle_info({timeout, TRef, stop}, _StateName, #state{tref = TRef} = State) -> {stop, normal, State}; handle_info(Info, StateName, State) -> ?INFO_MSG("unexpected info: ~p", [Info]), {next_state, StateName, State}. terminate(_Reason, _StateName, State) -> catch (State#state.sock_mod):close(State#state.sock), ok. code_change(_OldVsn, StateName, State, _Extra) -> {ok, StateName, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- process(Addr, Port, #stun{class = request, unsupported = []} = Msg) -> Resp = prepare_response(Msg), if Msg#stun.method == ?STUN_METHOD_BINDING -> case stun_codec:version(Msg) of old -> Resp#stun{class = response, 'MAPPED-ADDRESS' = {Addr, Port}}; new -> Resp#stun{class = response, 'XOR-MAPPED-ADDRESS' = {Addr, Port}} end; true -> Resp#stun{class = error, 'ERROR-CODE' = {405, <<"Method Not Allowed">>}} end; process(_Addr, _Port, #stun{class = request} = Msg) -> Resp = prepare_response(Msg), Resp#stun{class = error, 'UNKNOWN-ATTRIBUTES' = Msg#stun.unsupported, 'ERROR-CODE' = {420, stun_codec:reason(420)}}; process(_Addr, _Port, _Msg) -> pass. prepare_response(Msg) -> Version = list_to_binary("ejabberd " ++ ?VERSION), #stun{method = Msg#stun.method, magic = Msg#stun.magic, trid = Msg#stun.trid, 'SOFTWARE' = Version}. process_data(NextStateName, #state{buf = Buf} = State, Data) -> NewBuf = <>, case stun_codec:decode(NewBuf) of {ok, Msg, Tail} -> gen_fsm:send_event(self(), Msg), process_data(NextStateName, State#state{buf = <<>>}, Tail); empty -> NewState = State#state{buf = <<>>}, {next_state, NextStateName, update_state(NewState)}; more when size(NewBuf) < ?MAX_BUF_SIZE -> NewState = State#state{buf = NewBuf}, {next_state, NextStateName, update_state(NewState)}; _ -> {stop, normal, State} end. update_state(#state{sock = Sock} = State) -> case State#state.sock_mod of gen_tcp -> inet:setopts(Sock, [{active, once}]); SockMod -> SockMod:setopts(Sock, [{active, once}]) end, cancel_timer(State#state.tref), TRef = erlang:start_timer(?TIMEOUT, self(), stop), State#state{tref = TRef}. cancel_timer(TRef) -> case erlang:cancel_timer(TRef) of false -> receive {timeout, TRef, _} -> ok after 0 -> ok end; _ -> ok end. ejabberd-2.1.11/src/stun/stun_codec.erl0000664000000000000000000002406512240230175014637 0ustar %%%------------------------------------------------------------------- %%% File : stun_codec.erl %%% Author : Evgeniy Khramtsov %%% Description : STUN codec %%% Created : 7 Aug 2009 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(stun_codec). %% API -export([decode/1, encode/1, version/1, reason/1, pp/1]). %% Tests -export([test_udp/2, test_tcp/2, test_tls/2, test_public/0]). -include("stun.hrl"). %%==================================================================== %% API %%==================================================================== decode(<<0:2, Type:14, Len:16, Magic:32, TrID:96, Body:Len/binary, Tail/binary>>) -> case catch decode(Type, Magic, TrID, Body) of {'EXIT', _} -> {error, unparsed}; Res -> {ok, Res, Tail} end; decode(<<0:2, _/binary>>) -> more; decode(<<>>) -> empty; decode(_) -> {error, unparsed}. encode(#stun{class = Class, method = Method, magic = Magic, trid = TrID} = Msg) -> ClassCode = case Class of request -> 0; indication -> 1; response -> 2; error -> 3 end, Type = ?STUN_TYPE(ClassCode, Method), Attrs = enc_attrs(Msg), Len = size(Attrs), <<0:2, Type:14, Len:16, Magic:32, TrID:96, Attrs/binary>>. pp(Term) -> io_lib_pretty:print(Term, fun pp/2). version(#stun{magic = ?STUN_MAGIC}) -> new; version(#stun{}) -> old. reason(300) -> <<"Try Alternate">>; reason(400) -> <<"Bad Request">>; reason(401) -> <<"Unauthorized">>; reason(420) -> <<"Unknown Attribute">>; reason(438) -> <<"Stale Nonce">>; reason(500) -> <<"Server Error">>; reason(_) -> <<"Undefined Error">>. %%==================================================================== %% Internal functions %%==================================================================== decode(Type, Magic, TrID, Body) -> Method = ?STUN_METHOD(Type), Class = case ?STUN_CLASS(Type) of 0 -> request; 1 -> indication; 2 -> response; 3 -> error end, dec_attrs(Body, #stun{class = Class, method = Method, magic = Magic, trid = TrID}). dec_attrs(<>, Msg) -> PaddLen = padd_len(Len), <> = Rest, NewMsg = dec_attr(Type, Val, Msg), if Type == ?STUN_ATTR_MESSAGE_INTEGRITY -> NewMsg; true -> dec_attrs(Tail, NewMsg) end; dec_attrs(<<>>, Msg) -> Msg. enc_attrs(Msg) -> list_to_binary( [enc_attr(?STUN_ATTR_SOFTWARE, Msg#stun.'SOFTWARE'), enc_addr(?STUN_ATTR_MAPPED_ADDRESS, Msg#stun.'MAPPED-ADDRESS'), enc_xor_addr(?STUN_ATTR_XOR_MAPPED_ADDRESS, Msg#stun.magic, Msg#stun.trid, Msg#stun.'XOR-MAPPED-ADDRESS'), enc_addr(?STUN_ATTR_ALTERNATE_SERVER, Msg#stun.'ALTERNATE-SERVER'), enc_attr(?STUN_ATTR_USERNAME, Msg#stun.'USERNAME'), enc_attr(?STUN_ATTR_REALM, Msg#stun.'REALM'), enc_attr(?STUN_ATTR_NONCE, Msg#stun.'NONCE'), enc_error_code(Msg#stun.'ERROR-CODE'), enc_unknown_attrs(Msg#stun.'UNKNOWN-ATTRIBUTES')]). dec_attr(?STUN_ATTR_MAPPED_ADDRESS, Val, Msg) -> <<_, Family, Port:16, AddrBin/binary>> = Val, Addr = dec_addr(Family, AddrBin), Msg#stun{'MAPPED-ADDRESS' = {Addr, Port}}; dec_attr(?STUN_ATTR_XOR_MAPPED_ADDRESS, Val, Msg) -> <<_, Family, XPort:16, XAddr/binary>> = Val, Magic = Msg#stun.magic, Port = XPort bxor (Magic bsr 16), Addr = dec_xor_addr(Family, Magic, Msg#stun.trid, XAddr), Msg#stun{'XOR-MAPPED-ADDRESS' = {Addr, Port}}; dec_attr(?STUN_ATTR_SOFTWARE, Val, Msg) -> Msg#stun{'SOFTWARE' = Val}; dec_attr(?STUN_ATTR_USERNAME, Val, Msg) -> Msg#stun{'USERNAME' = Val}; dec_attr(?STUN_ATTR_REALM, Val, Msg) -> Msg#stun{'REALM' = Val}; dec_attr(?STUN_ATTR_NONCE, Val, Msg) -> Msg#stun{'NONCE' = Val}; dec_attr(?STUN_ATTR_MESSAGE_INTEGRITY, Val, Msg) -> Msg#stun{'MESSAGE-INTEGRITY' = Val}; dec_attr(?STUN_ATTR_ALTERNATE_SERVER, Val, Msg) -> <<_, Family, Port:16, Address/binary>> = Val, IP = dec_addr(Family, Address), Msg#stun{'ALTERNATE-SERVER' = {IP, Port}}; dec_attr(?STUN_ATTR_ERROR_CODE, Val, Msg) -> <<_:21, Class:3, Number:8, Reason/binary>> = Val, if Class >=3, Class =< 6, Number >=0, Number =< 99 -> Code = Class * 100 + Number, Msg#stun{'ERROR-CODE' = {Code, Reason}} end; dec_attr(?STUN_ATTR_UNKNOWN_ATTRIBUTES, Val, Msg) -> Attrs = dec_unknown_attrs(Val, []), Msg#stun{'UNKNOWN-ATTRIBUTES' = Attrs}; dec_attr(Attr, _Val, #stun{unsupported = Attrs} = Msg) when Attr =< 16#7fff -> Msg#stun{unsupported = [Attr|Attrs]}; dec_attr(_Attr, _Val, Msg) -> Msg. dec_addr(1, <>) -> {A1, A2, A3, A4}; dec_addr(2, <>) -> {A1, A2, A3, A4, A5, A6, A7, A8}. dec_xor_addr(1, Magic, _TrID, <>) -> Addr = XAddr bxor Magic, dec_addr(1, <>); dec_xor_addr(2, Magic, TrID, <>) -> Addr = XAddr bxor ((Magic bsl 96) bor TrID), dec_addr(2, <>). dec_unknown_attrs(<>, Acc) -> dec_unknown_attrs(Tail, [Attr|Acc]); dec_unknown_attrs(<<>>, Acc) -> lists:reverse(Acc). enc_attr(_Attr, undefined) -> <<>>; enc_attr(Attr, Val) -> Len = size(Val), PaddLen = padd_len(Len), <>. enc_addr(_Type, undefined) -> <<>>; enc_addr(Type, {{A1, A2, A3, A4}, Port}) -> enc_attr(Type, <<0, 1, Port:16, A1, A2, A3, A4>>); enc_addr(Type, {{A1, A2, A3, A4, A5, A6, A7, A8}, Port}) -> enc_attr(Type, <<0, 2, Port:16, A1:16, A2:16, A3:16, A4:16, A5:16, A6:16, A7:16, A8:16>>). enc_xor_addr(_Type, _Magic, _TrID, undefined) -> <<>>; enc_xor_addr(Type, Magic, _TrID, {{A1, A2, A3, A4}, Port}) -> XPort = Port bxor (Magic bsr 16), <> = <>, XAddr = Addr bxor Magic, enc_attr(Type, <<0, 1, XPort:16, XAddr:32>>); enc_xor_addr(Type, Magic, TrID, {{A1, A2, A3, A4, A5, A6, A7, A8}, Port}) -> XPort = Port bxor (Magic bsr 16), <> = <>, XAddr = Addr bxor ((Magic bsl 96) bor TrID), enc_attr(Type, <<0, 2, XPort:16, XAddr:128>>). enc_error_code(undefined) -> <<>>; enc_error_code({Code, Reason}) -> Class = Code div 100, Number = Code rem 100, enc_attr(?STUN_ATTR_ERROR_CODE, <<0:21, Class:3, Number:8, Reason/binary>>). enc_unknown_attrs([]) -> <<>>; enc_unknown_attrs(Attrs) -> enc_attr(?STUN_ATTR_UNKNOWN_ATTRIBUTES, list_to_binary([<> || Attr <- Attrs])). %%==================================================================== %% Auxiliary functions %%==================================================================== pp(Tag, N) -> try pp1(Tag, N) catch _:_ -> no end. pp1(stun, N) -> N = record_info(size, stun) - 1, record_info(fields, stun); pp1(_, _) -> no. %% Workaround for stupid clients. -ifdef(NO_PADDING). padd_len(_Len) -> 0. -else. padd_len(Len) -> case Len rem 4 of 0 -> 0; N -> 8*(4-N) end. -endif. %%==================================================================== %% Test functions %%==================================================================== bind_msg() -> Msg = #stun{method = ?STUN_METHOD_BINDING, class = request, trid = random:uniform(1 bsl 96), 'SOFTWARE' = <<"test">>}, encode(Msg). test_udp(Addr, Port) -> test(Addr, Port, gen_udp). test_tcp(Addr, Port) -> test(Addr, Port, gen_tcp). test_tls(Addr, Port) -> test(Addr, Port, ssl). test(Addr, Port, Mod) -> Res = case Mod of gen_udp -> Mod:open(0, [binary, {active, false}]); _ -> Mod:connect(Addr, Port, [binary, {active, false}], 1000) end, case Res of {ok, Sock} -> if Mod == gen_udp -> Mod:send(Sock, Addr, Port, bind_msg()); true -> Mod:send(Sock, bind_msg()) end, case Mod:recv(Sock, 0, 1000) of {ok, {_, _, Data}} -> try_dec(Data); {ok, Data} -> try_dec(Data); Err -> io:format("err: ~p~n", [Err]) end, Mod:close(Sock); Err -> io:format("err: ~p~n", [Err]) end. try_dec(Data) -> case decode(Data) of {ok, Msg, _} -> io:format("got:~n~s~n", [pp(Msg)]); Err -> io:format("err: ~p~n", [Err]) end. public_servers() -> [{"stun.ekiga.net", 3478, 3478, 5349}, {"stun.fwdnet.net", 3478, 3478, 5349}, {"stun.ideasip.com", 3478, 3478, 5349}, {"stun01.sipphone.com", 3478, 3478, 5349}, {"stun.softjoys.com", 3478, 3478, 5349}, {"stun.voipbuster.com", 3478, 3478, 5349}, {"stun.voxgratia.org", 3478, 3478, 5349}, {"stun.xten.com", 3478, 3478, 5349}, {"stunserver.org", 3478, 3478, 5349}, {"stun.sipgate.net", 10000, 10000, 5349}, {"numb.viagenie.ca", 3478, 3478, 5349}, {"stun.ipshka.com", 3478, 3478, 5349}, {"localhost", 3478, 5349, 5349}]. test_public() -> ssl:start(), lists:foreach( fun({Addr, UDPPort, TCPPort, TLSPort}) -> io:format("trying ~s:~p on UDP... ", [Addr, UDPPort]), test_udp(Addr, UDPPort), io:format("trying ~s:~p on TCP... ", [Addr, TCPPort]), test_tcp(Addr, TCPPort), io:format("trying ~s:~p on TLS... ", [Addr, TLSPort]), test_tls(Addr, TLSPort) end, public_servers()). ejabberd-2.1.11/src/pam/0000775000000000000000000000000012240452476011574 5ustar ejabberd-2.1.11/src/pam/epam.c0000664000000000000000000001520012240230175012646 0ustar /* * ejabberd, Copyright (C) 2002-2012 ProcessOne * * 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., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * */ #include #include #include #include #include #include #include #define dec_int16(s) ((((unsigned char*) (s))[0] << 8) | \ (((unsigned char*) (s))[1])) #define enc_int16(i, s) {((unsigned char*)(s))[0] = ((i) >> 8) & 0xff; \ ((unsigned char*)(s))[1] = (i) & 0xff;} #define BUFSIZE (1 << 16) #define CMD_AUTH 0 #define CMD_ACCT 1 typedef unsigned char byte; #ifdef PAM_FAIL_DELAY static void delay_fn(int retval, unsigned usec_delay, void *appdata_ptr) { /* No delay. However, looks like some PAM modules ignore this */ } #endif static int misc_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *password) { int msg_style; if (num_msg != 1) return PAM_CONV_ERR; msg_style = msg[0]->msg_style; if ((msg_style != PAM_PROMPT_ECHO_OFF) && (msg_style != PAM_PROMPT_ECHO_ON)) return PAM_CONV_ERR; *resp = malloc(sizeof(struct pam_response)); (*resp)[0].resp_retcode = 0; (*resp)[0].resp = strdup(password); return PAM_SUCCESS; } static int auth(char *service, char *user, char *password) { struct pam_conv conv = {misc_conv, password}; int retval; pam_handle_t *pamh = NULL; retval = pam_start(service, user, &conv, &pamh); if (retval == PAM_SUCCESS) retval = pam_set_item(pamh, PAM_RUSER, user); #ifdef PAM_FAIL_DELAY if (retval == PAM_SUCCESS) retval = pam_set_item(pamh, PAM_FAIL_DELAY, (void *)delay_fn); #endif if (retval == PAM_SUCCESS) retval = pam_authenticate(pamh, 0); if (retval == PAM_SUCCESS) retval = pam_acct_mgmt(pamh, 0); pam_end(pamh, retval); return retval; } static int acct_mgmt(char *service, char *user) { struct pam_conv conv = {misc_conv, NULL}; int retval; pam_handle_t *pamh = NULL; retval = pam_start(service, user, &conv, &pamh); if (retval == PAM_SUCCESS) retval = pam_set_item(pamh, PAM_RUSER, user); #ifdef PAM_FAIL_DELAY if (retval == PAM_SUCCESS) retval = pam_set_item(pamh, PAM_FAIL_DELAY, (void *)delay_fn); #endif if (retval == PAM_SUCCESS) retval = pam_acct_mgmt(pamh, 0); pam_end(pamh, retval); return retval; } static int read_buf(int fd, byte *buf, int len) { int i, got = 0; do { if ((i = read(fd, buf+got, len-got)) <= 0) { if (i == 0) return got; if (errno != EINTR) return got; i = 0; } got += i; } while (got < len); return (len); } static int read_cmd(byte *buf) { int len; if (read_buf(0, buf, 2) != 2) return 0; len = dec_int16(buf); if (read_buf(0, buf, len) != len) return 0; return 1; } static int write_buf(int fd, char *buf, int len) { int i, done = 0; do { if ((i = write(fd, buf+done, len-done)) < 0) { if (errno != EINTR) return (i); i = 0; } done += i; } while (done < len); return (len); } static int write_cmd(char *buf, int len) { byte hd[2]; enc_int16(len, hd); if (write_buf(1, (char *)hd, 2) != 2) return 0; if (write_buf(1, buf, len) != len) return 0; return 1; } static int process_reply(ETERM *pid, int cmd, int res) { ETERM *result; int len, retval; const char *errtxt; byte *buf; if (res == PAM_SUCCESS) result = erl_format("{~i, ~w, true}", cmd, pid); else { errtxt = pam_strerror(NULL, res); result = erl_format("{~i, ~w, {false, ~s}}", cmd, pid, errtxt); } len = erl_term_len(result); buf = erl_malloc(len); erl_encode(result, buf); retval = write_cmd((char *)buf, len); erl_free_term(result); erl_free(buf); return retval; } static int process_acct(ETERM *pid, ETERM *data) { int retval = 0; ETERM *pattern, *srv, *user; char *service, *username; pattern = erl_format("{Srv, User}"); if (erl_match(pattern, data)) { srv = erl_var_content(pattern, "Srv"); service = erl_iolist_to_string(srv); user = erl_var_content(pattern, "User"); username = erl_iolist_to_string(user); retval = process_reply(pid, CMD_ACCT, acct_mgmt(service, username)); erl_free_term(srv); erl_free_term(user); erl_free(service); erl_free(username); } erl_free_term(pattern); return retval; } static int process_auth(ETERM *pid, ETERM *data) { int retval = 0; ETERM *pattern, *srv, *user, *pass; char *service, *username, *password; pattern = erl_format("{Srv, User, Pass}"); if (erl_match(pattern, data)) { srv = erl_var_content(pattern, "Srv"); service = erl_iolist_to_string(srv); user = erl_var_content(pattern, "User"); username = erl_iolist_to_string(user); pass = erl_var_content(pattern, "Pass"); password = erl_iolist_to_string(pass); retval = process_reply(pid, CMD_AUTH, auth(service, username, password)); erl_free_term(srv); erl_free_term(user); erl_free_term(pass); erl_free(service); erl_free(username); erl_free(password); }; erl_free_term(pattern); return retval; } static int process_command(byte *buf) { int retval = 0; ETERM *pattern, *tuple, *cmd, *port, *data; pattern = erl_format("{Cmd, Port, Data}"); tuple = erl_decode(buf); if (erl_match(pattern, tuple)) { cmd = erl_var_content(pattern, "Cmd"); port = erl_var_content(pattern, "Port"); data = erl_var_content(pattern, "Data"); switch (ERL_INT_VALUE(cmd)) { case CMD_AUTH: retval = process_auth(port, data); break; case CMD_ACCT: retval = process_acct(port, data); break; }; erl_free_term(cmd); erl_free_term(port); erl_free_term(data); } erl_free_term(pattern); erl_free_term(tuple); return retval; } static void loop(void) { byte buf[BUFSIZE]; int retval = 0; do { if (read_cmd(buf) > 0) retval = process_command(buf); else retval = 0; } while (retval); } int main(int argc, char *argv[]) { erl_init(NULL, 0); loop(); return 0; } ejabberd-2.1.11/src/pam/epam.erl0000664000000000000000000001106712240230175013215 0ustar %%%------------------------------------------------------------------- %%% File : epam.erl %%% Author : Evgeniy Khramtsov %%% Purpose : PAM authentication and accounting management %%% Created : 5 Jul 2007 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(epam). -author('xram@jabber.ru'). -behaviour(gen_server). -include_lib("kernel/include/file.hrl"). -include("ejabberd.hrl"). %% API -export([start_link/0, start/0, stop/0]). -export([authenticate/3, acct_mgmt/2]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -define(WARNING, "File ~p is world-wide executable. " "This is a possible security hole in your system. " "This file must be setted root on execution " "and only ejabberd must be able to read/execute it. " "You have been warned :)"). -define(PROCNAME, ?MODULE). -define(CMD_AUTH, 0). -define(CMD_ACCT, 1). -record(state, {port}). %%==================================================================== %% API %%==================================================================== start() -> ChildSpec = { ?PROCNAME, {?MODULE, start_link, []}, transient, 1000, worker, [?MODULE] }, supervisor:start_child(ejabberd_sup, ChildSpec). stop() -> gen_server:call(?PROCNAME, stop), supervisor:terminate_child(ejabberd_sup, ?PROCNAME), supervisor:delete_child(ejabberd_sup, ?PROCNAME). start_link() -> gen_server:start_link({local, ?PROCNAME}, ?MODULE, [], []). authenticate(Srv, User, Pass) when is_list(Srv), is_list(User), is_list(Pass) -> gen_server:call(?PROCNAME, {authenticate, Srv, User, Pass}). acct_mgmt(Srv, User) when is_list(Srv), is_list(User) -> gen_server:call(?PROCNAME, {acct_mgmt, Srv, User}). %%==================================================================== %% gen_server callbacks %%==================================================================== init([]) -> FileName = filename:join(ejabberd:get_bin_path(), "epam"), case file:read_file_info(FileName) of {ok, Info} -> Mode = Info#file_info.mode band 16#801, if Mode == 16#801 -> ?WARNING_MSG(?WARNING, [FileName]); true -> ok end, Port = open_port({spawn, FileName}, [{packet, 2}, binary, exit_status]), {ok, #state{port = Port}}; {error, Reason} -> ?ERROR_MSG("Can't open file ~p: ~p", [FileName, Reason]), error end. terminate(_Reason, #state{port = Port}) -> catch port_close(Port), ok. handle_call({authenticate, Srv, User, Pass}, From, State) -> Port = State#state.port, Data = term_to_binary({?CMD_AUTH, From, {Srv, User, Pass}}), port_command(Port, Data), {noreply, State}; handle_call({acct_mgmt, Srv, User}, From, State) -> Port = State#state.port, Data = term_to_binary({?CMD_ACCT, From, {Srv, User}}), port_command(Port, Data), {noreply, State}; handle_call(stop, _From, State) -> {stop, normal, ok, State}; handle_call(_Request, _From, State) -> {reply, bad_request, State}. handle_info({Port, {data, Data}}, #state{port=Port} = State) -> case binary_to_term(Data) of {Cmd, To, Reply} when Cmd==?CMD_AUTH; Cmd==?CMD_ACCT -> gen_server:reply(To, Reply); Err -> ?ERROR_MSG("Got invalid reply from ~p: ~p", [Port, Err]) end, {noreply, State}; handle_info({Port, {exit_status, _}}, #state{port=Port} = State) -> %% We can restart the port here, but, I think, it is not a good idea, %% since we can run into infinity loop. So let the supervisor restart us. {stop, port_died, State}; handle_info(Msg, State) -> ?WARNING_MSG("Got unexpected message: ~p", [Msg]), {noreply, State}. handle_cast(_Msg, State) -> {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. ejabberd-2.1.11/src/pam/Makefile.in0000664000000000000000000000165412240230175013635 0ustar # $Id: Makefile.in 775 2007-05-29 14:31:12Z mremond $ CC = @CC@ CFLAGS = @CFLAGS@ @PAM_CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ @PAM_LIBS@ ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ EFLAGS += -I .. EFLAGS += -pz .. # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif ERLSHLIBS = ../epam OUTDIR = .. SOURCES = $(wildcard *.erl) BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) all: $(BEAMS) $(ERLSHLIBS) $(OUTDIR)/%.beam: %.erl @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< #all: $(ERLSHLIBS) # erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt $(ERLSHLIBS): ../%: %.c $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \ $(subst ../,,$(subst ,.c,$@)) $(LIBS) \ $(ERLANG_LIBS) $(ERLANG_CFLAGS) \ -o $@ -lpthread clean: rm -f $(BEAMS) $(ERLSHLIBS) distclean: clean rm -f Makefile TAGS: etags *.erl ejabberd-2.1.11/src/ejabberd_check.erl0000664000000000000000000000704412240230175014411 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_check.erl %%% Author : Mickael Remond %%% Purpose : Check ejabberd configuration and %%% Created : 27 Feb 2008 by Mickael Remond %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_check). -export([libs/0, config/0]). -include("ejabberd.hrl"). -include("ejabberd_config.hrl"). -compile([export_all]). %% TODO: %% We want to implement library checking at launch time to issue %% human readable user messages. libs() -> ok. %% @doc Consistency check on ejabberd configuration config() -> check_database_modules(). check_database_modules() -> [check_database_module(M)||M<-get_db_used()]. check_database_module(odbc) -> check_modules(odbc, [odbc, odbc_app, odbc_sup, ejabberd_odbc, ejabberd_odbc_sup, odbc_queries]); check_database_module(mysql) -> check_modules(mysql, [mysql, mysql_auth, mysql_conn, mysql_recv]); check_database_module(pgsql) -> check_modules(pgsql, [pgsql, pgsql_proto, pgsql_tcp, pgsql_util]). %% @doc Issue a critical error and throw an exit if needing module is %% missing. check_modules(DB, Modules) -> case get_missing_modules(Modules) of [] -> ok; MissingModules when is_list(MissingModules) -> ?CRITICAL_MSG("ejabberd is configured to use '~p', but the following Erlang modules are not installed: '~p'", [DB, MissingModules]), exit(database_module_missing) end. %% @doc Return the list of undefined modules get_missing_modules(Modules) -> lists:filter(fun(Module) -> case catch Module:module_info() of {'EXIT', {undef, _}} -> true; _ -> false end end, Modules). %% @doc Return the list of databases used get_db_used() -> %% Retrieve domains with a database configured: Domains = ets:match(local_config, #local_config{key={odbc_server, '$1'}, value='$2'}), %% Check that odbc is the auth method used for those domains: %% and return the database name DBs = lists:foldr( fun([Domain, DB], Acc) -> case check_odbc_option( ejabberd_config:get_local_option( {auth_method, Domain})) of true -> [get_db_type(DB)|Acc]; _ -> Acc end end, [], Domains), lists:usort(DBs). %% @doc Depending in the DB definition, return which type of DB this is. %% Note that MSSQL is detected as ODBC. %% @spec (DB) -> mysql | pgsql | odbc get_db_type(DB) when is_tuple(DB) -> element(1, DB); get_db_type(DB) when is_list(DB) -> odbc. %% @doc Return true if odbc option is used check_odbc_option(odbc) -> true; check_odbc_option(AuthMethods) when is_list(AuthMethods) -> lists:member(odbc, AuthMethods); check_odbc_option(_) -> false. ejabberd-2.1.11/src/mod_last_odbc.erl0000664000000000000000000001454412240230175014312 0ustar %%%---------------------------------------------------------------------- %%% File : mod_last_odbc.erl %%% Author : Alexey Shchepin %%% Purpose : jabber:iq:last support (XEP-0012) %%% Created : 24 Oct 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_last_odbc). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_local_iq/3, process_sm_iq/3, on_presence_update/4, store_last_info/4, get_last_info/2, remove_user/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_privacy.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST, ?MODULE, process_local_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST, ?MODULE, process_sm_iq, IQDisc), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:add(unset_presence_hook, Host, ?MODULE, on_presence_update, 50). stop(Host) -> ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(unset_presence_hook, Host, ?MODULE, on_presence_update, 50), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST). %%% %%% Uptime of ejabberd node %%% process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> Sec = get_node_uptime(), IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_LAST}, {"seconds", integer_to_list(Sec)}], []}]} end. %% @spec () -> integer() %% @doc Get the uptime of the ejabberd node, expressed in seconds. %% When ejabberd is starting, ejabberd_config:start/0 stores the datetime. get_node_uptime() -> case ejabberd_config:get_local_option(node_start) of {_, _, _} = StartNow -> now_to_seconds(now()) - now_to_seconds(StartNow); _undefined -> trunc(element(1, erlang:statistics(wall_clock))/1000) end. now_to_seconds({MegaSecs, Secs, _MicroSecs}) -> MegaSecs * 1000000 + Secs. %%% %%% Serve queries about user last online %%% process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> User = To#jid.luser, Server = To#jid.lserver, {Subscription, _Groups} = ejabberd_hooks:run_fold( roster_get_jid_info, Server, {none, []}, [User, Server, From]), if (Subscription == both) or (Subscription == from) -> UserListRecord = ejabberd_hooks:run_fold( privacy_get_user_list, Server, #userlist{}, [User, Server]), case ejabberd_hooks:run_fold( privacy_check_packet, Server, allow, [User, Server, UserListRecord, {To, From, {xmlelement, "presence", [], []}}, out]) of allow -> get_last_iq(IQ, SubEl, User, Server); deny -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]} end; true -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]} end end. %% @spec (LUser::string(), LServer::string()) -> %% {ok, TimeStamp::integer(), Status::string()} | not_found | {error, Reason} get_last(LUser, LServer) -> Username = ejabberd_odbc:escape(LUser), case catch odbc_queries:get_last(LServer, Username) of {selected, ["seconds","state"], []} -> not_found; {selected, ["seconds","state"], [{STimeStamp, Status}]} -> case catch list_to_integer(STimeStamp) of TimeStamp when is_integer(TimeStamp) -> {ok, TimeStamp, Status}; Reason -> {error, {invalid_timestamp, Reason}} end; Reason -> {error, {invalid_result, Reason}} end. get_last_iq(IQ, SubEl, LUser, LServer) -> case ejabberd_sm:get_user_resources(LUser, LServer) of [] -> case get_last(LUser, LServer) of {error, _Reason} -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; not_found -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]}; {ok, TimeStamp, Status} -> TimeStamp2 = now_to_seconds(now()), Sec = TimeStamp2 - TimeStamp, IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_LAST}, {"seconds", integer_to_list(Sec)}], [{xmlcdata, Status}]}]} end; _ -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_LAST}, {"seconds", "0"}], []}]} end. on_presence_update(User, Server, _Resource, Status) -> TimeStamp = now_to_seconds(now()), store_last_info(User, Server, TimeStamp, Status). store_last_info(User, Server, TimeStamp, Status) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), Username = ejabberd_odbc:escape(LUser), Seconds = ejabberd_odbc:escape(integer_to_list(TimeStamp)), State = ejabberd_odbc:escape(Status), odbc_queries:set_last_t(LServer, Username, Seconds, State). %% @spec (LUser::string(), LServer::string()) -> %% {ok, TimeStamp::integer(), Status::string()} | not_found get_last_info(LUser, LServer) -> case get_last(LUser, LServer) of {error, _Reason} -> not_found; Res -> Res end. remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), Username = ejabberd_odbc:escape(LUser), odbc_queries:del_last(LServer, Username). ejabberd-2.1.11/src/msgs/0000775000000000000000000000000012240452476011770 5ustar ejabberd-2.1.11/src/msgs/nl.msg0000664000000000000000000006651412240230175013113 0ustar {"Access Configuration","Toegangsinstellingen"}. {"Access Control List Configuration","Instellingen van access control lists"}. {"Access control lists","Access control lists"}. {"Access Control Lists","Access control lists"}. {"Access denied by service policy","De toegang werd geweigerd door het beleid van deze dienst"}. {"Access rules","Access rules"}. {"Access Rules","Access rules"}. {"Action on user","Actie op gebruiker"}. {"Add Jabber ID","Jabber ID toevoegen"}. {"Add New","Toevoegen"}. {"Add User","Gebruiker toevoegen"}. {"Administration","Beheer"}. {"Administration of ","Beheer van "}. {"Administrator privileges required","U hebt beheerdersprivileges nodig"}. {"A friendly name for the node","Bijnaam voor deze knoop"}. {"All activity","Alle activiteit"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Deze gebruiker toestaan te abonneren op deze pubsub node?"}. {"Allow users to change the subject","Sta gebruikers toe het onderwerp te veranderen"}. {"Allow users to query other users","Gebruikers mogen naar andere gebruikers verzoeken verzenden"}. {"Allow users to send invites","Gebruikers mogen uitnodigingen verzenden"}. {"Allow users to send private messages","Gebruikers mogen privéberichten verzenden"}. {"Allow visitors to change nickname","Sta bezoekers toe hun naam te veranderen"}. {"Allow visitors to send private messages to","Gebruikers mogen privéberichten verzenden aan"}. {"Allow visitors to send status text in presence updates","Sta bezoekers toe hun statusbericht in te stellen"}. {"Allow visitors to send voice requests","Gebruikers mogen stemaanvragen verzenden"}. {"All Users","Alle gebruikers"}. {"Announcements","Mededelingen"}. {"anyone","iedereen"}. {"A password is required to enter this room","U hebt een wachtwoord nodig om deze chatruimte te kunnen betreden"}. {"April","April"}. {"August","Augustus"}. {"Backup","Backup"}. {"Backup Management","Backup"}. {"Backup of ","Backup maken van "}. {"Backup to File at ","Binaire backup maken op "}. {"Bad format","Slecht formaat"}. {"Birthday","Geboortedatum"}. {"CAPTCHA web page","CAPTCHA webpagina."}. {"Change Password","Wachtwoord wijzigen"}. {"Change User Password","Verander Gebruikerswachtwoord"}. {"Characters not allowed:","Niet-toegestane karakters:"}. {"Chatroom configuration modified","De instellingen van de chatruimte werden veranderd"}. {"Chatroom is created","Gespreksruimte gecreëerd"}. {"Chatroom is destroyed","Gespreksruimte vernietigd"}. {"Chatroom is started","Gespreksruimte gestart"}. {"Chatroom is stopped","Gespreksruimte gestopt"}. {"Chatrooms","Groepsgesprekken"}. {"Choose a username and password to register with this server","Kies een gebruikersnaam en een wachtwoord om u te registreren op deze server"}. {"Choose modules to stop","Selecteer de modules die u wilt stoppen"}. {"Choose storage type of tables","Opslagmethode voor tabellen kiezen"}. {"Choose whether to approve this entity's subscription.","Beslis of dit verzoek tot abonneren zal worden goedgekeurd"}. {"City","Plaats"}. {"Commands","Commando's"}. {"Conference room does not exist","De chatruimte bestaat niet"}. {"Configuration","Instellingen"}. {"Configuration of room ~s","Instellingen van chatruimte ~s"}. {"Connected Resources:","Verbonden bronnen:"}. {"Connections parameters","Verbindingsparameters"}. {"Country","Land"}. {"CPU Time:","Processortijd:"}. {"Database","Database"}. {"Database Tables at ","Databasetabellen van "}. {"Database Tables Configuration at ","Instellingen van databasetabellen op "}. {"December","December"}. {"Default users as participants","Gebruikers standaard instellen als deelnemers"}. {"Delete message of the day","Bericht van de dag verwijderen"}. {"Delete message of the day on all hosts","Verwijder bericht-van-de-dag op alle hosts"}. {"Delete Selected","Geselecteerde verwijderen"}. {"Delete User","Verwijder Gebruiker"}. {"Delete","Verwijderen"}. {"Deliver event notifications","Gebeurtenisbevestigingen Sturen"}. {"Deliver payloads with event notifications","Berichten bezorgen samen met gebeurtenisnotificaties"}. {"Description:","Beschrijving:"}. {"Disc only copy","Harde schijf"}. {"Displayed Groups:","Weergegeven groepen:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Geef Uw wachtwoord aan niemand, zelfs niet aan de beheerders van deze Jabber-server."}. {"Dump Backup to Text File at ","Backup naar een tekstbestand schrijven op "}. {"Dump to Text File","Backup naar een tekstbestand schrijven"}. {"Edit Properties","Eigenschappen bewerken"}. {"Either approve or decline the voice request.","Keur stemaanvraag goed of af."}. {"ejabberd IRC module","ejabberd's IRC-module"}. {"ejabberd MUC module","ejabberd's MUC module"}. {"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe module"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}. {"ejabberd vCard module","ejabberd's vCard-module"}. {"ejabberd Web Admin","ejabberd Webbeheer"}. {"Elements","Elementen"}. {"Email","E-mail"}. {"Enable logging","Logs aanzetten"}. {"Encoding for server ~b","Karakterset voor server ~b"}. {"End User Session","Verwijder Gebruikers-sessie"}. {"Enter list of {Module, [Options]}","Voer lijst met op te starten modules als volgt in: {Module, [Opties]}"}. {"Enter nickname you want to register","Voer de bijnaam in die u wilt registreren"}. {"Enter path to backup file","Voer pad naar backupbestand in"}. {"Enter path to jabberd14 spool dir","Voer pad naar jabberd14-spool-directory in"}. {"Enter path to jabberd14 spool file","Voer pad naar jabberd14-spool-bestand in"}. {"Enter path to text file","Voer pad naar backupbestand in"}. {"Enter the text you see","Voer de getoonde tekst in"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Voer de gebruikersnaam en de coderingen in die u wilt gebruiken voor verbindingen met IRC-servers. Klik op 'Volgende' om meer velden aan te maken. Klik op \"Voltooi' om de instellingen op te slaan."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Voer de gebruikersnaam, coderingen, poorten en wachtwoorden in die U wilt gebruiken voor het verbinden met IRC-servers"}. {"Erlang Jabber Server","Erlang Jabber Server"}. {"Error","Fout"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Voorbeeld: [{\"irc.example.org\", \"koi8-r\", 6667, \"geheim\"}, {\"vendetta.example.net\", \"iso8859-1\", 7000}, {irc,testserver.nl\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Geen CAPTCHA test voor Jabber IDs"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exporteer data van alle gebruikers in de server naar PIEFXIS-bestanden (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Exporteer data van alle gebruikers van een host naar PIEXFIS-bestanden (XEP-0227):"}. {"Failed to extract JID from your voice request approval","Er kon geen JID worden ontleend uit deze stemaanvraag"}. {"Family Name","Achternaam"}. {"February","Februari"}. {"Fill in fields to search for any matching Jabber User","Vul de velden in om te zoeken naar Jabber-gebruikers op deze server"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Gebruik de velden om te zoeken (Voeg achteraan het teken * toe om te zoeken naar alles wat met het eerste deel begint.)."}. {"Friday","Vrijdag"}. {"From ~s","Van ~s"}. {"From","Van"}. {"Full Name","Volledige naam"}. {"Get Number of Online Users","Aantal Aanwezige Gebruikers Opvragen"}. {"Get Number of Registered Users","Aantal Geregistreerde Gebruikers Opvragen"}. {"Get User Last Login Time","Tijd van Laatste Aanmelding Opvragen"}. {"Get User Password","Gebruikerswachtwoord Opvragen"}. {"Get User Statistics","Gebruikers-statistieken Opvragen"}. {"Grant voice to this person?","Stemaanvraag honoreren voor deze persoon?"}. {"Group ","Groep "}. {"Groups","Groepen"}. {"has been banned","werd verbannen"}. {"has been kicked because of an affiliation change","is weggestuurd vanwege een affiliatieverandering"}. {"has been kicked because of a system shutdown","is weggestuurd omdat het systeem gestopt wordt"}. {"has been kicked because the room has been changed to members-only","is weggestuurd omdat de chatruimte vanaf heden alleen toegankelijk is voor leden"}. {"has been kicked","werd gekicked"}. {" has set the subject to: "," veranderde het onderwerp in: "}. {"Host","Host"}. {"If you don't see the CAPTCHA image here, visit the web page.","Als U het CAPTCHA-plaatje niet ziet, bezoek dan de webpagina."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Als u verschillende poorten, wachtwoorden en coderingen wilt opgeven voor elke IRC-server, vul dan deze lijst met het volgende formaat: '{\"IRC-server\", \"codering\", poort, \"wachtwoord\"}'. Standaard gebruikt deze service de codering \"~s\", poort ~p, leeg wachtwoord."}. {"Import Directory","Directory importeren"}. {"Import File","Bestand importeren"}. {"Import user data from jabberd14 spool file:","Importeer gebruikersdata via spool-bestanden van jabberd14"}. {"Import User from File at ","Importeer gebruiker via bestand op "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importeer gebruikersdata van een PIEFXIS-bestand (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Importeer gebruikersdata via spool-bestanden van jabberd14"}. {"Import Users from Dir at ","Gebruikers importeren vanaf directory op "}. {"Import Users From jabberd14 Spool Files","Importeer gebruikers via spool-bestanden van jabberd14"}. {"Improper message type","Onjuist berichttype"}. {"Incorrect password","Foutief wachtwoord"}. {"Invalid affiliation: ~s","Ongeldige affiliatie: ~s"}. {"Invalid role: ~s","Ongeldige rol: ~s"}. {"IP addresses","IP-adres"}. {"IP","IP"}. {"IRC channel (don't put the first #)","IRC kanaal (zonder eerste #)"}. {"IRC server","IRC-server"}. {"IRC settings","IRC instellingen"}. {"IRC Transport","IRC Transport"}. {"IRC username","Gebruikersnaam voor IRC"}. {"IRC Username","Gebruikersnaam voor IRC:"}. {"is now known as","heet nu"}. {"It is not allowed to send private messages","Het is niet toegestaan priveberichten te sturen"}. {"It is not allowed to send private messages of type \"groupchat\"","Er mogen geen privéberichten van het type \"groupchat\" worden verzonden"}. {"It is not allowed to send private messages to the conference","Er mogen geen privéberichten naar de chatruimte worden verzonden"}. {"Jabber Account Registration","Jabber-account registratie"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","De Jabber ID ~s is ongeldig"}. {"January","Januari"}. {"Join IRC channel","Ga IRC kanaal binnen"}. {"joins the room","betrad de chatruimte"}. {"Join the IRC channel here.","Ga het IRC kanaal binnen"}. {"Join the IRC channel in this Jabber ID: ~s","Ga het IRC kanaal van deze Jabber ID binnen: ~s"}. {"July","Juli"}. {"June","Juni"}. {"Last Activity","Laatste activiteit"}. {"Last login","Laatste Aanmelding"}. {"Last month","Afgelopen maand"}. {"Last year","Afgelopen jaar"}. {"leaves the room","verliet de chatruimte"}. {"Listened Ports at ","Openstaande poorten op "}. {"Listened Ports","Openstaande poorten"}. {"List of modules to start","Lijst met op te starten modules"}. {"Low level update script","Lowlevel script voor de opwaardering"}. {"Make participants list public","Deelnemerslijst publiek maken"}. {"Make room CAPTCHA protected","Chatruimte beveiligen met een geautomatiseerde Turing test"}. {"Make room members-only","Chatruimte enkel toegankelijk maken voor leden"}. {"Make room moderated","Chatruimte gemodereerd maken"}. {"Make room password protected","Chatruimte beveiligen met een wachtwoord"}. {"Make room persistent","Chatruimte blijvend maken"}. {"Make room public searchable","Chatruimte doorzoekbaar maken"}. {"March","Maart"}. {"Maximum Number of Occupants","Maximum aantal aanwezigen"}. {"Max # of items to persist","Maximum aantal in het geheugen te bewaren items"}. {"Max payload size in bytes","Maximumgrootte van bericht in bytes"}. {"May","Mei"}. {"Members:","Groepsleden:"}. {"Membership is required to enter this room","U moet lid zijn om deze chatruimte te kunnen betreden"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Onthou het wachtwoord, of schrijf het op en bewaar het op een veilige plaats. Met Jabber is er geen geautomatiseerde manier om het wachtwoord terug te halen als U het vergeet."}. {"Memory","Geheugen"}. {"Message body","Bericht"}. {"Middle Name","Tussennaam"}. {"Minimum interval between voice requests (in seconds)","Minimale interval tussen stemaanvragen (in seconden)"}. {"Moderator privileges required","U hebt moderatorprivileges nodig"}. {"moderators only","moderators"}. {"Modified modules","Gewijzigde modules"}. {"Module","Module"}. {"Modules at ","Modules op "}. {"Modules","Modules"}. {"Monday","Maandag"}. {"Name:","Naam:"}. {"Name","Naam"}. {"Never","Nooit"}. {"New Password:","Nieuw Wachtwoord:"}. {"Nickname","Bijnaam"}. {"Nickname Registration at ","Registratie van een bijnaam op "}. {"Nickname ~s does not exist in the room","De bijnaam ~s bestaat niet in deze chatruimte"}. {"nobody","niemand"}. {"No body provided for announce message","De mededeling bevat geen bericht"}. {"No Data","Geen gegevens"}. {"Node ID","Node ID"}. {"Node ","Node "}. {"Node not found","Node niet gevonden"}. {"Nodes","Nodes"}. {"No limit","Geen limiet"}. {"None","Geen"}. {"No resource provided","Geen bron opgegeven"}. {"Not Found","Niet gevonden"}. {"Notify subscribers when items are removed from the node","Abonnees informeren wanneer items verwijderd worden uit de node"}. {"Notify subscribers when the node configuration changes","Abonnees informeren wanneer de instellingen van de node veranderen"}. {"Notify subscribers when the node is deleted","Abonnees informeren wanneer de node verwijderd word"}. {"November","November"}. {"Number of occupants","Aantal aanwezigen"}. {"Number of online users","Aantal Aanwezige Gebruikers"}. {"Number of registered users","Aantal Geregistreerde Gebruikers"}. {"October","Oktober"}. {"Offline Messages:","Offline berichten:"}. {"Offline Messages","Offline berichten"}. {"OK","OK"}. {"Old Password:","Oud Wachtwoord:"}. {"Online","Online"}. {"Online Users:","Online gebruikers:"}. {"Online Users","Online gebruikers"}. {"Only deliver notifications to available users","Notificaties alleen verzenden naar online gebruikers"}. {"Only moderators and participants are allowed to change the subject in this room","Alleen moderators en deelnemers mogen het onderwerp van deze chatruimte veranderen"}. {"Only moderators are allowed to change the subject in this room","Alleen moderators mogen het onderwerp van deze chatruimte veranderen"}. {"Only moderators can approve voice requests","Alleen moderators kunnen stemaanvragen goedkeuren"}. {"Only occupants are allowed to send messages to the conference","Alleen aanwezigen mogen berichten naar de chatruimte verzenden"}. {"Only occupants are allowed to send queries to the conference","Alleen aanwezigen mogen verzoeken verzenden naar de chatruimte"}. {"Only service administrators are allowed to send service messages","Alleen beheerders van deze dienst mogen mededelingen verzenden naar alle chatruimtes"}. {"Options","Opties"}. {"Organization Name","Organisatie"}. {"Organization Unit","Afdeling"}. {"Outgoing s2s Connections:","Uitgaande s2s-verbindingen:"}. {"Outgoing s2s Connections","Uitgaande s2s-verbindingen"}. {"Outgoing s2s Servers:","Uitgaande s2s-verbindingen:"}. {"Owner privileges required","U hebt eigenaarsprivileges nodig"}. {"Packet","Pakket"}. {"Password ~b","Wachtwoord ~b"}. {"Password Verification:","Wachtwoord Bevestiging:"}. {"Password Verification","Wachtwoord Bevestiging"}. {"Password:","Wachtwoord:"}. {"Password","Wachtwoord"}. {"Path to Dir","Pad naar directory"}. {"Path to File","Pad naar bestand"}. {"Pending","Bezig"}. {"Period: ","Periode: "}. {"Persist items to storage","Items in het geheugen bewaren"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Merk op dat volgende opties enkel backups maken van de ingebouwde database Mnesia. Als U de ODBC module gebruikt dan moeten daarvan afzonderlijke backups gemaakt worden."}. {"Please, wait for a while before sending new voice request","Wacht s.v.p. met het maken van een nieuwe stemaanvraag."}. {"Pong","Pong"}. {"Port ~b","Poort ~b"}. {"Port","Poort"}. {"Present real Jabber IDs to","Jabber ID's kunnen achterhaald worden door"}. {"private, ","privé, "}. {"Protocol","Protocol"}. {"Publish-Subscribe","Publish-Subscribe"}. {"PubSub subscriber request","PubSub abonnee verzoek"}. {"Purge all items when the relevant publisher goes offline","Verwijder alle items wanneer de gerelateerde publiceerder offline gaat"}. {"Queries to the conference members are not allowed in this room","Er mogen geen verzoeken verzenden worden naar deelnemers in deze chatruimte"}. {"RAM and disc copy","RAM en harde schijf"}. {"RAM copy","RAM"}. {"Raw","Ruw"}. {"Really delete message of the day?","Wilt u het bericht van de dag verwijderen?"}. {"Recipient is not in the conference room","De ontvanger is niet in de chatruimte"}. {"Register a Jabber account","Registreer een Jabber-account"}. {"Registered Users:","Geregistreerde gebruikers:"}. {"Registered Users","Geregistreerde gebruikers"}. {"Register","Registreer"}. {"Registration in mod_irc for ","Registratie van "}. {"Remote copy","Op andere nodes in de cluster"}. {"Remove All Offline Messages","Verwijder alle offline berichten"}. {"Remove User","Gebruiker verwijderen"}. {"Remove","Verwijderen"}. {"Replaced by new connection","Vervangen door een nieuwe verbinding"}. {"Resources","Bronnen"}. {"Restart","Herstarten"}. {"Restart Service","Herstart Service"}. {"Restore Backup from File at ","Binaire backup direct herstellen op "}. {"Restore","Binaire backup direct herstellen"}. {"Restore binary backup after next ejabberd restart (requires less memory):","Binaire backup herstellen na herstart van ejabberd (vereist minder geheugen):"}. {"Restore binary backup immediately:","Binaire backup direct herstellen:"}. {"Restore plain text backup immediately:","Backup in een tekstbestand direct herstellen:"}. {"Room Configuration","Instellingen van de chatruimte"}. {"Room creation is denied by service policy","De aanmaak van de chatruimte is verhinderd door de instellingen van deze server"}. {"Room description","Beschrijving"}. {"Room Occupants","Aantal aanwezigen"}. {"Room title","Naam van de chatruimte"}. {"Roster groups allowed to subscribe","Contactlijst-groepen die mogen abonneren"}. {"Roster of ","Roster van "}. {"Roster","Roster"}. {"Roster size","Contactlijst Groote"}. {"RPC Call Error","RPC-oproepfout"}. {"Running Nodes","Draaiende nodes"}. {"~s access rule configuration","Access rules op ~s"}. {"Saturday","Zaterdag"}. {"Script check","Controle van script"}. {"Search Results for ","Zoekresultaten voor "}. {"Search users in ","Gebruikers zoeken in "}. {"Send announcement to all online users","Mededeling verzenden naar alle online gebruikers"}. {"Send announcement to all online users on all hosts","Mededeling verzenden naar alle online gebruikers op alle virtuele hosts"}. {"Send announcement to all users","Mededeling verzenden naar alle gebruikers"}. {"Send announcement to all users on all hosts","Stuur aankondiging aan alle gebruikers op alle hosts"}. {"September","September"}. {"Server ~b","Server ~b"}. {"Server:","Server:"}. {"Set message of the day and send to online users","Bericht van de dag instellen en verzenden naar online gebruikers"}. {"Set message of the day on all hosts and send to online users","Stel bericht-van-de-dag in op alle hosts en stuur naar aanwezige gebruikers"}. {"Shared Roster Groups","Gedeelde rostergroepen"}. {"Show Integral Table","Volledige tabel laten zien"}. {"Show Ordinary Table","Deel van tabel laten zien"}. {"Shut Down Service","Stop Service"}. {"~s invites you to the room ~s","~s nodigt je uit voor het groepsgesprek ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Sommige Jabber-clienten kunnen het wachtwoord opslaan op Uw computer. Gebruik deze mogelijkheid alleen als U vertrouwd dat Uw computer afdoende beveiligd is."}. {"Specify the access model","Geef toegangsmodel"}. {"Specify the event message type","Geef type van eventbericht"}. {"Specify the publisher model","Publicatietype opgeven"}. {"~s's Offline Messages Queue","offline berichten van ~s"}. {"Start Modules at ","Modules starten op "}. {"Start Modules","Modules starten"}. {"Start","Starten"}. {"Statistics of ~p","Statistieken van ~p"}. {"Statistics","Statistieken"}. {"Stop Modules at ","Modules stoppen op "}. {"Stop Modules","Modules stoppen"}. {"Stopped Nodes","Gestopte nodes"}. {"Stop","Stoppen"}. {"Storage Type","Opslagmethode"}. {"Store binary backup:","Binaire backup maken:"}. {"Store plain text backup:","Backup naar een tekstbestand schrijven:"}. {"Subject","Onderwerp"}. {"Submitted","Verzonden"}. {"Submit","Verzenden"}. {"Subscriber Address","Abonnee Adres"}. {"Subscription","Inschrijving"}. {"Sunday","Zondag"}. {"That nickname is already in use by another occupant","Deze bijnaam is al in gebruik door een andere aanwezige"}. {"That nickname is registered by another person","Deze bijnaam is al geregistreerd door iemand anders"}. {"The CAPTCHA is valid.","De geautomatiseerde Turing-test is geslaagd."}. {"The CAPTCHA verification has failed","De CAPTCHA-verificatie is mislukt"}. {"The collections with which a node is affiliated","De collecties waar een node mee is gerelateerd"}. {"the password is","het wachtwoord is"}. {"The password is too weak","Het wachtwoord is te zwak"}. {"The password of your Jabber account was successfully changed.","Het wachtwoord van Uw Jabber-account is succesvol veranderd."}. {"There was an error changing the password: ","Er was een fout bij het veranderen van het wachtwoord:"}. {"There was an error creating the account: ","Er was een fout bij het creeern van de account:"}. {"There was an error deleting the account: ","Er was een fout bij het verwijderen van de account."}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Dit is niet hoofdlettergevoelig: macbeth is hetzelfde als MacBeth en Macbeth."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Deze pagina maakt het mogelijk een Jabber-account te registreren op deze server. Uw JID (Jabber IDentiteit) zal er als volg uit zien: gebruikersnaam@server. Lees de instructies zorgvuldig teneinde de velden correct in te vullen."}. {"This page allows to unregister a Jabber account in this Jabber server.","Deze pagina maakt het mogelijk een Jabber-account op deze server op te heffen."}. {"This participant is kicked from the room because he sent an error message","Deze deelnemer wordt weggestuurd vanwege het sturen van een foutmeldingsbericht"}. {"This participant is kicked from the room because he sent an error message to another participant","Deze deelnemer wordt weggestuurd vanwege het sturen van een foutmeldingsbericht aan een andere deelnemer"}. {"This participant is kicked from the room because he sent an error presence","Deze deelnemer wordt weggestuurd vanwege het sturen van een foutmelding-aanwezigheid"}. {"This room is not anonymous","Deze chatruimte is niet anoniem"}. {"Thursday","Donderdag"}. {"Time delay","Vertraging"}. {"Time","Tijd"}. {"To","Aan"}. {"Too many CAPTCHA requests","Te veel CAPTCHA-aanvragen"}. {"To ~s","Naar ~s"}. {"Traffic rate limit is exceeded","Dataverkeerslimiet overschreden"}. {"Transactions Aborted:","Afgebroken transacties:"}. {"Transactions Committed:","Bevestigde transacties:"}. {"Transactions Logged:","Gelogde transacties:"}. {"Transactions Restarted:","Herstarte transacties:"}. {"Tuesday","Dinsdag"}. {"Unable to generate a CAPTCHA","Het generen van een CAPTCHA is mislukt"}. {"Unauthorized","Niet geautoriseerd"}. {"Unregister a Jabber account","Opheffen van Jabber-account"}. {"Unregister","Opheffen"}. {"Update","Bijwerken"}. {"Update message of the day (don't send)","Bericht van de dag bijwerken (niet verzenden)"}. {"Update message of the day on all hosts (don't send)","Verander bericht-van-de-dag op alle hosts (niet versturen)"}. {"Update ","Opwaarderen van "}. {"Update plan","Plan voor de opwaardering"}. {"Update script","Script voor de opwaardering"}. {"Uptime:","Uptime:"}. {"Use of STARTTLS required","Gebruik van STARTTLS is vereist"}. {"User ","Gebruiker "}. {"User","Gebruiker"}. {"User JID","JID Gebruiker"}. {"User Management","Gebruikersbeheer"}. {"Username:","Gebruikersnaam:"}. {"Users are not allowed to register accounts so quickly","Het is gebruikers niet toegestaan zo snel achter elkaar te registreren"}. {"Users","Gebruikers"}. {"Users Last Activity","Laatste activiteit van gebruikers"}. {"Validate","Bevestigen"}. {"vCard User Search","Gebruikers zoeken"}. {"Virtual Hosts","Virtuele hosts"}. {"Visitors are not allowed to change their nicknames in this room","Het is bezoekers niet toegestaan hun naam te veranderen in dit kanaal"}. {"Visitors are not allowed to send messages to all occupants","Bezoekers mogen geen berichten verzenden naar alle aanwezigen"}. {"Voice requests are disabled in this conference","Stemaanvragen zijn uitgeschakeld voor deze chatruimte"}. {"Voice request","Stemaanvraag"}. {"Wednesday","Woensdag"}. {"When to send the last published item","Wanneer het laatst gepubliceerde item verzonden moet worden"}. {"Whether to allow subscriptions","Abonnementsaanvraag toestaan"}. {"You can later change your password using a Jabber client.","U can het wachtwoord later veranderen met een Jabber-client."}. {"You have been banned from this room","U werd verbannen uit deze chatruimte"}. {"You must fill in field \"Nickname\" in the form","U moet het veld \"bijnaam\" invullen"}. {"You need a client that supports x:data and CAPTCHA to register","U hebt een client nodig die x:data en CAPTCHA ondersteunt om een bijnaam te registreren"}. {"You need a client that supports x:data to register the nickname","U hebt een client nodig die x:data ondersteunt om een bijnaam te registreren"}. {"You need an x:data capable client to configure mod_irc settings","U hebt een client nodig die x:data ondersteunt om dit IRC-transport in te stellen"}. {"You need an x:data capable client to configure room","U hebt een client nodig die x:data ondersteunt om deze chatruimte in te stellen"}. {"You need an x:data capable client to search","U hebt een client nodig die x:data ondersteunt om te zoeken"}. {"Your active privacy list has denied the routing of this stanza.","Uw actieve privacy-lijst verbied het routeren van dit stanza."}. {"Your contact offline message queue is full. The message has been discarded.","Te veel offline berichten voor dit contactpersoon. Het bericht is niet opgeslagen."}. {"Your Jabber account was successfully created.","Uw Jabber-account is succesvol gecreeerd."}. {"Your Jabber account was successfully deleted.","Uw Jabber-account is succesvol verwijderd."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Uw berichten aan ~s worden geblokkeerd. Om ze te deblokkeren, ga naar ~s"}. ejabberd-2.1.11/src/msgs/id.msg0000664000000000000000000006342012240230175013067 0ustar {"Access Configuration","Akses Konfigurasi"}. {"Access Control List Configuration","Konfigurasi Daftar Akses Pengendalian"}. {"Access Control Lists","Akses Daftar Pengendalian"}. {"Access control lists","Daftar Pengendalian Akses"}. {"Access denied by service policy","Akses ditolak oleh kebijakan layanan"}. {"Access rules","Akses peraturan"}. {"Access Rules","Aturan Akses"}. {"Action on user","Tindakan pada pengguna"}. {"Add Jabber ID","Tambah Jabber ID"}. {"Add New","Tambah Baru"}. {"Add User","Tambah Pengguna"}. {"Administration","Administrasi"}. {"Administration of ","Administrasi"}. {"Administrator privileges required","Hak istimewa Administrator dibutuhkan"}. {"A friendly name for the node","Nama yang dikenal untuk node"}. {"All activity","Semua aktifitas"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Izinkan ID Jabber ini untuk berlangganan pada node pubsub ini?"}. {"Allow users to change the subject","Perbolehkan pengguna untuk mengganti topik"}. {"Allow users to query other users","Perbolehkan pengguna untuk mengetahui pengguna lain"}. {"Allow users to send invites","Perbolehkan pengguna mengirimkan undangan"}. {"Allow users to send private messages","perbolehkan pengguna mengirimkan pesan ke pengguna lain secara pribadi"}. {"Allow visitors to change nickname","Perbolehkan visitor mengganti nama julukan"}. {"Allow visitors to send status text in presence updates","Izinkan pengunjung untuk mengirim teks status terbaru"}. {"All Users","Semua Pengguna"}. {"Announcements","Pengumuman"}. {"anyone","Siapapun"}. {"A password is required to enter this room","Diperlukan kata sandi untuk masuk ruangan ini"}. {"April","April"}. {"August","Agustus"}. {"Backup","Backup"}. {"Backup Management","Manajemen Backup"}. {"Backup of ","Cadangan dari"}. {"Backup to File at ","Backup ke File pada"}. {"Bad format","Format yang buruk"}. {"Birthday","Hari Lahir"}. {"CAPTCHA web page","CAPTCHA laman web"}. {"Change Password","Ubah Kata Sandi"}. {"Change User Password","Ubah User Password"}. {"Characters not allowed:","Karakter tidak diperbolehkan:"}. {"Chatroom configuration modified","Konfigurasi ruang chat diubah"}. {"Chatroom is created","Ruang chat telah dibuat"}. {"Chatroom is destroyed","Ruang chat dilenyapkan"}. {"Chatroom is started","Ruang chat dimulai"}. {"Chatroom is stopped","Ruang chat dihentikan"}. {"Chatrooms","Ruangan Chat"}. {"Choose a username and password to register with this server","Pilih nama pengguna dan kata sandi untuk mendaftar dengan layanan ini"}. {"Choose modules to stop","Pilih Modul untuk berhenti"}. {"Choose storage type of tables","Pilih jenis penyimpanan tabel"}. {"Choose whether to approve this entity's subscription.","Pilih apakah akan menyetujui hubungan pertemanan ini."}. {"City","Kota"}. {"Commands","Perintah"}. {"Conference room does not exist","Ruang Konferensi tidak ada"}. {"Configuration of room ~s","Pengaturan ruangan ~s"}. {"Configuration","Pengaturan"}. {"Connected Resources:","Sumber Daya Terhubung:"}. {"Connections parameters","Parameter Koneksi"}. {"Country","Negara"}. {"CPU Time:","Waktu CPU:"}. {"Database","Database"}. {"Database Tables at ","Tabel Database pada"}. {"Database Tables Configuration at ","Database Tabel Konfigurasi pada"}. {"December","Desember"}. {"Default users as participants","pengguna pertama kali masuk sebagai participant"}. {"Delete","Hapus"}. {"Delete message of the day","Hapus pesan harian"}. {"Delete message of the day on all hosts","Hapus pesan harian pada semua host"}. {"Delete Selected","Hapus Yang Terpilih"}. {"Delete User","Hapus Pengguna"}. {"Deliver event notifications","Memberikan pemberitahuan acara"}. {"Deliver payloads with event notifications","Memberikan muatan dengan pemberitahuan acara"}. {"Description:","Keterangan:"}. {"Disc only copy","Hanya salinan dari disc"}. {"Displayed Groups:","Tampilkan Grup:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Jangan memberitahukan kata sandi Anda ke siapapun, bahkan para administrator dari layanan Jabber."}. {"Dump Backup to Text File at ","Dump Backup ke File Teks di"}. {"Dump to Text File","Dump menjadi File Teks"}. {"Edit Properties","Ganti Properti"}. {"ejabberd IRC module","ejabberd IRC modul"}. {"ejabberd MUC module","ejabberd MUC Module"}. {"ejabberd Publish-Subscribe module","Modul ejabberd Setujui-Pertemanan"}. {"ejabberd SOCKS5 Bytestreams module","modul ejabberd SOCKS5 Bytestreams"}. {"ejabberd vCard module","Modul ejabberd vCard"}. {"ejabberd Web Admin","Admin Web ejabberd"}. {"Elements","Elemen-elemen"}. {"Email","Email"}. {"Enable logging","Aktifkan catatan"}. {"Encoding for server ~b","Pengkodean untuk layanan ~b"}. {"End User Session","Akhir Sesi Pengguna"}. {"Enter list of {Module, [Options]}","Masukkan daftar {Modul, [Options]}"}. {"Enter nickname you want to register","Masukkan nama julukan Anda jika ingin mendaftar"}. {"Enter path to backup file","Masukkan path untuk file cadangan"}. {"Enter path to jabberd14 spool dir","Masukkan path ke direktori spool jabberd14"}. {"Enter path to jabberd14 spool file","Masukkan path ke file jabberd14 spool"}. {"Enter path to text file","Masukkan path ke file teks"}. {"Enter the text you see","Masukkan teks yang Anda lihat"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Masukkan username dan pengkodean yang ingin Anda gunakan untuk menghubungkan ke layanan IRC. Tekan 'Selanjutnya' untuk mendapatkan lagi formulir kemudian Tekan 'Lengkap' untuk menyimpan pengaturan."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Masukkan username, pengkodean, port dan sandi yang ingin Anda gunakan untuk menghubungkan ke layanan IRC"}. {"Erlang Jabber Server","Layanan Erlang Jabber"}. {"Error","Kesalahan"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Contoh: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Ekspor data dari semua pengguna pada layanan ke berkas PIEFXIS (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Ekspor data pengguna pada sebuah host ke berkas PIEFXIS (XEP-0227):"}. {"Family Name","Nama Keluarga (marga)"}. {"February","Februari"}. {"Fill in fields to search for any matching Jabber User","Isi kolom untuk mencari pengguna Jabber yang sama"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Isi formulir untuk pencarian pengguna Jabber yang cocok (Tambahkan * ke mengakhiri pengisian untuk menyamakan kata)"}. {"Friday","Jumat"}. {"From","Dari"}. {"From ~s","Dari ~s"}. {"Full Name","Nama Lengkap"}. {"Get Number of Online Users","Dapatkan Jumlah User Yang Online"}. {"Get Number of Registered Users","Dapatkan Jumlah Pengguna Yang Terdaftar"}. {"Get User Last Login Time","Dapatkan Waktu Login Terakhir Pengguna "}. {"Get User Password","Dapatkan User Password"}. {"Get User Statistics","Dapatkan Statistik Pengguna"}. {"Group ","Grup"}. {"Groups","Grup"}. {"has been banned","telah dibanned"}. {"has been kicked because of an affiliation change","telah dikick karena perubahan afiliasi"}. {"has been kicked because of a system shutdown","telah dikick karena sistem shutdown"}. {"has been kicked because the room has been changed to members-only","telah dikick karena ruangan telah diubah menjadi hanya untuk member"}. {"has been kicked","telah dikick"}. {" has set the subject to: ","telah menetapkan topik yaitu:"}. {"Host","Host"}. {"If you don't see the CAPTCHA image here, visit the web page.","Jika Anda tidak melihat gambar CAPTCHA disini, silahkan kunjungi halaman web."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Jika Anda ingin menentukan port yang berbeda, sandi, pengkodean untuk layanan IRC, isi daftar ini dengan nilai-nilai dalam format '{\"server irc \", \"encoding \", port, \"sandi \"}'. Secara default ini menggunakan layanan \"~s \" pengkodean, port ~p, kata sandi kosong."}. {"Import Directory","Impor Direktori"}. {"Import File","Impor File"}. {"Import user data from jabberd14 spool file:","Impor data pengguna dari sekumpulan berkas jabberd14:"}. {"Import User from File at ","Impor Pengguna dari File pada"}. {"Import users data from a PIEFXIS file (XEP-0227):","impor data-data pengguna dari sebuah PIEFXIS (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Импорт пользовательских данных из буферной директории jabberd14:"}. {"Import Users from Dir at ","Impor Pengguna dari Dir di"}. {"Import Users From jabberd14 Spool Files","Impor Pengguna Dari jabberd14 Spool File"}. {"Improper message type","Jenis pesan yang tidak benar"}. {"Incorrect password","Kata sandi salah"}. {"Invalid affiliation: ~s","Afiliasi tidak valid: ~s"}. {"Invalid role: ~s","Peran tidak valid: ~s"}. {"IP addresses","Alamat IP"}. {"IP","IP"}. {"IRC channel (don't put the first #)","Channel IRC (tidak perlu menempatkan # sebelumnya)"}. {"IRC server","Layanan IRC"}. {"IRC settings","Pengaturan IRC"}. {"IRC Transport","IRC Transport"}. {"IRC username","Nama Pengguna IRC"}. {"IRC Username","Nama Pengguna IRC"}. {"is now known as","sekarang dikenal sebagai"}. {"It is not allowed to send private messages","Hal ini tidak diperbolehkan untuk mengirim pesan pribadi"}. {"It is not allowed to send private messages of type \"groupchat\"","Hal ini tidak diperbolehkan untuk mengirim pesan pribadi jenis \"groupchat \""}. {"It is not allowed to send private messages to the conference","Hal ini tidak diperbolehkan untuk mengirim pesan pribadi ke konferensi"}. {"Jabber Account Registration","Pendaftaran Akun Jabber"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Jabber ID ~s tidak valid"}. {"January","Januari"}. {"Join IRC channel","Gabung channel IRC"}. {"joins the room","bergabung ke ruangan"}. {"Join the IRC channel here.","Gabung ke channel IRC disini"}. {"Join the IRC channel in this Jabber ID: ~s","Gabung ke channel IRC dengan Jabber ID: ~s"}. {"July","Juli"}. {"June","Juni"}. {"Last Activity","Aktifitas Terakhir"}. {"Last login","Terakhir Login"}. {"Last month","Akhir bulan"}. {"Last year","Akhir tahun"}. {"leaves the room","meninggalkan ruangan"}. {"Listened Ports at ","Mendeteksi Port-port di"}. {"Listened Ports","Port Terdeteksi"}. {"List of modules to start","Daftar modul untuk memulai"}. {"Low level update script","Perbaruan naskah tingkat rendah"}. {"Make participants list public","Buat daftar participant diketahui oleh public"}. {"Make room CAPTCHA protected","Buat ruangan dilindungi dengan CAPTCHA"}. {"Make room members-only","Buat ruangan hanya untuk member saja"}. {"Make room moderated","Buat ruangan hanya untuk moderator saja"}. {"Make room password protected","Buat ruangan yang dilindungi dengan kata sandi"}. {"Make room persistent","Buat ruangan menjadi permanent"}. {"Make room public searchable","Buat ruangan dapat dicari"}. {"March","Maret"}. {"Maximum Number of Occupants","Maksimum Jumlah Penghuni"}. {"Max # of items to persist","Max item untuk bertahan"}. {"Max payload size in bytes","Max kapasitas ukuran dalam bytes"}. {"May","Mei"}. {"Members:","Anggota:"}. {"Membership is required to enter this room","Hanya Member yang dapat masuk ruangan ini"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Hafalkan kata sandi Anda, atau dicatat dan letakkan di tempat yang aman. Didalam Jabber tidak ada cara otomatis untuk mendapatkan kembali password Anda jika Anda lupa."}. {"Memory","Memori"}. {"Message body","Isi Pesan"}. {"Middle Name","Nama Tengah"}. {"Moderator privileges required","Hak istimewa moderator dibutuhkan"}. {"moderators only","Hanya moderator"}. {"Modified modules","Modifikasi modul-modul"}. {"Module","Modul"}. {"Modules at ","modul-modul di"}. {"Modules","Modul"}. {"Monday","Senin"}. {"Name:","Nama:"}. {"Name","Nama"}. {"Never","Tidak Pernah"}. {"New Password:","Password Baru:"}. {"Nickname","Nama Julukan"}. {"Nickname Registration at ","Pendaftaran Julukan pada"}. {"Nickname ~s does not exist in the room","Nama Julukan ~s tidak berada di dalam ruangan"}. {"No body provided for announce message","Tidak ada isi pesan yang disediakan untuk mengirimkan pesan"}. {"No Data","Tidak Ada Data"}. {"Node ID","ID Node"}. {"Node ","Node"}. {"Node not found","Node tidak ditemukan"}. {"Nodes","Node-node"}. {"No limit","Tidak terbatas"}. {"None","Tak satupun"}. {"No resource provided","Tidak ada sumber daya yang disediakan"}. {"Not Found","Tidak Ditemukan"}. {"Notify subscribers when items are removed from the node","Beritahu pelanggan ketika item tersebut dikeluarkan dari node"}. {"Notify subscribers when the node configuration changes","Beritahu pelanggan ketika ada perubahan konfigurasi node"}. {"Notify subscribers when the node is deleted","Beritahu pelanggan ketika node dihapus"}. {"November","Nopember"}. {"Number of occupants","Jumlah Penghuni"}. {"Number of online users","Jumlah pengguna online"}. {"Number of registered users","Jumlah pengguna terdaftar"}. {"October","Oktober"}. {"Offline Messages:","Pesan Offline:"}. {"Offline Messages","Pesan Offline"}. {"OK","YA"}. {"Old Password:","Password Lama:"}. {"Online","Online"}. {"Online Users:","Pengguna Online:"}. {"Online Users","Pengguna Yang Online"}. {"Only deliver notifications to available users","Hanya mengirimkan pemberitahuan kepada pengguna yang tersedia"}. {"Only moderators and participants are allowed to change the subject in this room","Hanya moderator dan peserta yang diizinkan untuk mengganti topik pembicaraan di ruangan ini"}. {"Only moderators are allowed to change the subject in this room","Hanya moderator yang diperbolehkan untuk mengubah topik dalam ruangan ini"}. {"Only occupants are allowed to send messages to the conference","Hanya penghuni yang diizinkan untuk mengirim pesan ke konferensi"}. {"Only occupants are allowed to send queries to the conference","Hanya penghuni diizinkan untuk mengirim permintaan ke konferensi"}. {"Only service administrators are allowed to send service messages","Layanan hanya diperuntukan kepada administrator yang diizinkan untuk mengirim layanan pesan"}. {"Options","Pilihan-pilihan"}. {"Organization Name","Nama Organisasi"}. {"Organization Unit","Unit Organisasi"}. {"Outgoing s2s Connections","Koneksi Keluar s2s"}. {"Outgoing s2s Connections:","Koneksi s2s yang keluar:"}. {"Outgoing s2s Servers:","Layanan s2s yang keluar:"}. {"Owner privileges required","Hak istimewa owner dibutuhkan"}. {"Packet","Paket"}. {"Password ~b","Kata Sandi ~b"}. {"Password:","Kata Sandi:"}. {"Password","Sandi"}. {"Password Verification:","Verifikasi Kata Sandi:"}. {"Password Verification","Verifikasi Sandi"}. {"Path to Dir","Jalur ke Dir"}. {"Path to File","Jalur ke File"}. {"Pending","Tertunda"}. {"Period: ","Periode:"}. {"Persist items to storage","Pertahankan item ke penyimpanan"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Harap dicatat bahwa pilihan ini hanya akan membuat cadangan builtin Mnesia database. Jika Anda menggunakan modul ODBC, anda juga perlu untuk membuat cadangan database SQL Anda secara terpisah."}. {"Pong","Pong"}. {"Port ~b","Port ~b"}. {"Port","Port"}. {"Present real Jabber IDs to","Tampilkan Jabber ID secara lengkap"}. {"private, ","pribadi, "}. {"Protocol","Protocol"}. {"Publish-Subscribe","Setujui-Pertemanan"}. {"PubSub subscriber request","Permintaan pertemanan PubSub"}. {"Purge all items when the relevant publisher goes offline","Bersihkan semua item ketika penerbit yang relevan telah offline"}. {"Queries to the conference members are not allowed in this room","Permintaan untuk para anggota konferensi tidak diperbolehkan di ruangan ini"}. {"RAM and disc copy","RAM dan disc salinan"}. {"RAM copy","Salinan RAM"}. {"Raw","mentah"}. {"Really delete message of the day?","Benar-benar ingin menghapus pesan harian?"}. {"Recipient is not in the conference room","Penerima tidak berada di ruangan konferensi"}. {"Register a Jabber account","Daftarkan sebuah akun jabber"}. {"Registered Users:","Pengguna Terdaftar:"}. {"Registered Users","Pengguna Terdaftar"}. {"Register","Mendaftar"}. {"Registration in mod_irc for ","Pendaftaran di mod_irc untuk"}. {"Remote copy","Salinan Remote"}. {"Remove All Offline Messages","Hapus Semua Pesan Offline"}. {"Remove","Menghapus"}. {"Remove User","Hapus Pengguna"}. {"Replaced by new connection","Diganti dengan koneksi baru"}. {"Resources","Sumber daya"}. {"Restart","Jalankan Ulang"}. {"Restart Service","Restart Layanan"}. {"Restore Backup from File at ","Kembalikan Backup dari File pada"}. {"Restore binary backup after next ejabberd restart (requires less memory):","Mengembalikan cadangan yang berpasanagn setelah ejabberd berikutnya dijalankan ulang (memerlukan memori lebih sedikit):"}. {"Restore binary backup immediately:","Segera mengembalikan cadangan yang berpasangan:"}. {"Restore","Mengembalikan"}. {"Restore plain text backup immediately:","Segera mengembalikan cadangan teks biasa:"}. {"Room Configuration","Konfigurasi Ruangan"}. {"Room creation is denied by service policy","Pembuatan Ruangan ditolak oleh kebijakan layanan"}. {"Room description","Keterangan ruangan"}. {"Room Occupants","Penghuni Ruangan"}. {"Room title","Nama Ruangan"}. {"Roster groups allowed to subscribe","Kelompok kontak yang diizinkan untuk berlangganan"}. {"Roster","Kontak"}. {"Roster of ","Kontak dari"}. {"Roster size","Ukuran Daftar Kontak"}. {"RPC Call Error","Panggilan Kesalahan RPC"}. {"Running Nodes","Menjalankan Node"}. {"~s access rule configuration","~s aturan akses konfigurasi"}. {"Saturday","Sabtu"}. {"Script check","Periksa naskah"}. {"Search Results for ","Hasil Pencarian untuk"}. {"Search users in ","Pencarian pengguna dalam"}. {"Send announcement to all online users","Kirim pengumuman untuk semua pengguna yang online"}. {"Send announcement to all online users on all hosts","Kirim pengumuman untuk semua pengguna yang online pada semua host"}. {"Send announcement to all users","Kirim pengumuman untuk semua pengguna"}. {"Send announcement to all users on all hosts","Kirim pengumuman untuk semua pengguna pada semua host"}. {"September","September"}. {"Server ~b","Layanan ~b"}. {"Server:","Layanan:"}. {"Set message of the day and send to online users","Mengatur pesan harian dan mengirimkan ke pengguna yang online"}. {"Set message of the day on all hosts and send to online users","Mengatur pesan harian pada semua host dan kirimkan ke pengguna yang online"}. {"Shared Roster Groups","Berbagi grup kontak"}. {"Show Integral Table","Tampilkan Tabel Terpisah"}. {"Show Ordinary Table","Tampilkan Tabel Normal"}. {"Shut Down Service","Shut Down Layanan"}. {"~s invites you to the room ~s","~s mengundang anda ke ruangan ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Beberapa klien Jabber dapat menyimpan password di komputer Anda. Gunakan fitur itu hanya jika Anda mempercayai komputer Anda aman."}. {"Specify the access model","Tentukan model akses"}. {"Specify the event message type","Tentukan jenis acara pesan"}. {"Specify the publisher model","Tentukan model penerbitan"}. {"~s's Offline Messages Queue","Antrian Pesan Offline ~s"}. {"Start Modules at ","Mulai Modul pada"}. {"Start Modules","Memulai Modul"}. {"Start","Mulai"}. {"Statistics of ~p","statistik dari ~p"}. {"Statistics","Statistik"}. {"Stop","Hentikan"}. {"Stop Modules at ","Hentikan Modul pada"}. {"Stop Modules","Hentikan Modul"}. {"Stopped Nodes","Menghentikan node"}. {"Storage Type","Jenis Penyimpanan"}. {"Store binary backup:","Penyimpanan cadangan yang berpasangan:"}. {"Store plain text backup:","Simpan cadangan teks biasa:"}. {"Subject","Subyek"}. {"Submit","Serahkan"}. {"Submitted","Ulangi masukan"}. {"Subscriber Address","Alamat Pertemanan"}. {"Subscription","Berlangganan"}. {"Sunday","Minggu"}. {"That nickname is already in use by another occupant","Julukan itu sudah digunakan oleh penghuni lain"}. {"That nickname is registered by another person","Julukan tersebut telah didaftarkan oleh orang lain"}. {"The CAPTCHA is valid.","Captcha ini benar."}. {"The CAPTCHA verification has failed","Verifikasi CAPTCHA telah gagal"}. {"The collections with which a node is affiliated","Koleksi dengan yang berafiliasi dengan sebuah node"}. {"the password is","kata sandi yaitu:"}. {"The password is too weak","Kata sandi terlalu lemah"}. {"The password of your Jabber account was successfully changed.","Kata sandi pada akun Jabber Anda telah berhasil diubah."}. {"There was an error changing the password: ","Ada kesalahan dalam mengubah password:"}. {"There was an error creating the account: ","Ada kesalahan saat membuat akun:"}. {"There was an error deleting the account: ","Ada kesalahan saat menghapus akun:"}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Pada bagian ini huruf besar dan kecil tidak dibedakan: Misalnya macbeth adalah sama dengan MacBeth juga Macbeth."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Halaman ini memungkinkan untuk membuat akun Jabber di layanan Jabber ini. JID Anda (Jabber Pengenal) akan berbentuk: namapengguna@layanan. Harap baca dengan seksama petunjuk-petunjuk untuk mengisi kolom dengan benar."}. {"This page allows to unregister a Jabber account in this Jabber server.","Pada bagian ini memungkinkan Anda untuk membatalkan pendaftaran akun Jabber pada layanan Jabber ini."}. {"This participant is kicked from the room because he sent an error message","Peserta ini dikick dari ruangan karena dia mengirim pesan kesalahan"}. {"This participant is kicked from the room because he sent an error message to another participant","Participant ini dikick dari ruangan karena ia mengirim pesan kesalahan ke participant lain"}. {"This participant is kicked from the room because he sent an error presence","Participant ini dikick dari ruangan karena ia mengirim kehadiran kesalahan"}. {"This room is not anonymous","Ruangan ini tidak dikenal"}. {"Thursday","Kamis"}. {"Time delay","Waktu tunda"}. {"Time","Waktu"}. {"To","Kepada"}. {"To ~s","Kepada ~s"}. {"Traffic rate limit is exceeded","Lalu lintas melebihi batas"}. {"Transactions Aborted:","Transaksi yang dibatalkan:"}. {"Transactions Committed:","Transaksi yang dilakukan:"}. {"Transactions Logged:","Transaksi yang ditempuh:"}. {"Transactions Restarted:","Transaksi yang dijalankan ulang:"}. {"Tuesday","Selasa"}. {"Unable to generate a CAPTCHA","Tidak dapat menghasilkan CAPTCHA"}. {"Unauthorized","Ditolak"}. {"Unregister a Jabber account","Nonaktifkan akun jabber"}. {"Unregister","Nonaktifkan"}. {"Update ","Memperbarui "}. {"Update","Memperbarui"}. {"Update message of the day (don't send)","Rubah pesan harian (tidak dikirim)"}. {"Update message of the day on all hosts (don't send)","Rubah pesan harian pada semua host (tidak dikirim)"}. {"Update plan","Rencana Perubahan"}. {"Update script","Perbarui naskah"}. {"Uptime:","Sampai saat:"}. {"Use of STARTTLS required","Penggunaan STARTTLS diperlukan"}. {"User Management","Manajemen Pengguna"}. {"Username:","Nama Pengguna:"}. {"User ","Pengguna"}. {"User","Pengguna"}. {"Users are not allowed to register accounts so quickly","Pengguna tidak diperkenankan untuk mendaftar akun begitu cepat"}. {"Users Last Activity","Aktifitas terakhir para pengguna"}. {"Users","Pengguna"}. {"Validate","Mengesahkan"}. {"vCard User Search","vCard Pencarian Pengguna"}. {"Virtual Hosts","Virtual Hosts"}. {"Visitors are not allowed to change their nicknames in this room","Visitor tidak diperbolehkan untuk mengubah nama julukan di ruangan ini"}. {"Visitors are not allowed to send messages to all occupants","Visitor tidak diperbolehkan untuk mengirim pesan ke semua penghuni"}. {"Wednesday","Rabu"}. {"When to send the last published item","Ketika untuk mengirim item terakhir yang dipublikasikan"}. {"Whether to allow subscriptions","Apakah diperbolehkan untuk berlangganan"}. {"You can later change your password using a Jabber client.","Anda dapat mengubah kata sandi anda dilain waktu dengan menggunakan klien Jabber."}. {"You have been banned from this room","Anda telah diblokir dari ruangan ini"}. {"You must fill in field \"Nickname\" in the form","Anda harus mengisi kolom \"Julukan\" dalam formulir"}. {"You need a client that supports x:data and CAPTCHA to register","Anda memerlukan klien yang mendukung x:data dan CAPTCHA untuk mendaftar"}. {"You need a client that supports x:data to register the nickname","Anda memerlukan klien yang mendukung x:data untuk mendaftar julukan"}. {"You need an x:data capable client to configure mod_irc settings","Anda memerlukan x:data klien untuk mampu mengkonfigurasi pengaturan mod_irc"}. {"You need an x:data capable client to configure room","Anda memerlukan x:data klien untuk dapat mengkonfigurasi ruangan"}. {"You need an x:data capable client to search","Anda memerlukan x:data klien untuk melakukan pencarian"}. {"Your active privacy list has denied the routing of this stanza.","Daftar privasi aktif Anda telah menolak routing ztanza ini"}. {"Your contact offline message queue is full. The message has been discarded.","Kontak offline Anda pada antrian pesan sudah penuh. Pesan telah dibuang."}. {"Your Jabber account was successfully created.","Jabber akun Anda telah sukses dibuat"}. {"Your Jabber account was successfully deleted.","Jabber akun Anda berhasil dihapus."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Pesan Anda untuk ~s sedang diblokir. Untuk membuka blokir tersebut, kunjungi ~s"}. ejabberd-2.1.11/src/msgs/pl.po0000664000000000000000000015534712240230175012750 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" "Last-Translator: Zbyszek Żółkiewski \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Polish (polski)\n" "X-Additional-Translator: Janusz B. Wiśniewski\n" "X-Additional-Translator: Marcin Owsiany\n" "X-Additional-Translator: Andrzej Smyk\n" "X-Additional-Translator: Mateusz Gajewski\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Wymagane jest użycie STARTTLS" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Nie podano zasobu" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Połączenie zostało zastąpione" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "Aktualna lista prywatności zabrania przesyłania tej stanzy" #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Przepisz tekst z obrazka" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "Twoje wiadomości do ~s są blokowane. Aby je odblokować, odwiedź ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "Jeśli nie widzisz obrazka CAPTCHA, odwiedź stronę internetową." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "Strona internetowa CAPTCHA" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "Captcha jest poprawna." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Polecenia" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Na pewno usunąć wiadomość dnia?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Temat" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Treść wiadomości" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Brak treści powiadomienia" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Powiadomienia" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Wyślij powiadomienie do wszystkich użytkowników" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Wyślij powiadomienie do wszystkich użytkowników na wszystkich hostach" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Wyślij powiadomienie do wszystkich zalogowanych użytkowników" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "" "Wyślij powiadomienie do wszystkich zalogowanych użytkowników na wszystkich " "hostach" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Wyślij wiadomość dnia do wszystkich zalogowanych użytkowników" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Ustaw wiadomość dnia dla wszystkich hostów i wyślij do zalogowanych " "uzytkowników" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Aktualizuj wiadomość dnia (bez wysyłania)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Aktualizuj wiadomość dnia na wszystkich hostach (bez wysyłania)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Usuń wiadomość dnia" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Usuń wiadomość dnia ze wszystkich hostów" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Konfiguracja" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Baza danych" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Uruchom moduły" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Zatrzymaj moduły" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Wykonaj kopie" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Przywróć z kopii" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Wykonaj kopie do pliku tekstowego" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Importuj plik" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Importuj katalog" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Restart usługi" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Wyłącz usługę" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Dodaj użytkownika" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Usuń użytkownika" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Zakończ sesję uzytkownika" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Pobierz hasło użytkownika" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Zmień hasło użytkownika" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Pokaż czas ostatniego zalogowania uzytkownika" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Pobierz statystyki użytkownika" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Pokaż liczbę zarejestrowanych użytkowników" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Pokaż liczbę zalogowanych użytkowników" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Lista dostępowa" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Zasady dostępu" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Zarządzanie użytkownikami" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Użytkownicy zalogowani" #: mod_configure.erl:501 msgid "All Users" msgstr "Wszyscy użytkownicy" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Wychodzące połączenia s2s" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Uruchomione węzły" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Zatrzymane węzły" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Moduły" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Zarządzanie kopiami zapasowymi" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importuj użytkowników z plików roboczych serwera jabberd14" #: mod_configure.erl:699 msgid "To ~s" msgstr "Do ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Od ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Konfiguracja tabel bazy na " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Wybierz typ bazy dla tablel" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Kopia tylko na dysku" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Kopia na dysku i w pamięci RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Kopia w pamięci RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Kopia zdalna" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Zatrzymaj moduły na " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Wybierz moduły do zatrzymania" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Uruchom moduły na " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Wprowadź listę {Moduł, [Opcje]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Lista modułów do uruchomienia" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Zapisz kopię w pliku na " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Wprowadź scieżkę do pliku kopii zapasowej" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Scieżka do pliku" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Odtwórz bazę danych z kopii zapasowej na " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Zapisz kopię zapasową w pliku tekstowym na " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Wprowadź scieżkę do pliku tekstowego" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importuj użytkownika z pliku na " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Wprowadź ścieżkę do roboczego pliku serwera jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importuj użytkowników z katalogu na " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Wprowadź ścieżkę do roboczego katalogu serwera jabberd14" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Ścieżka do katalogu" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Opóźnienie" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Konfiguracja listy dostępowej" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Listy dostępowe" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Konfiguracja dostępu" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Reguły dostępu" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Hasło" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Weryfikacja hasła" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Liczba zarejestrowanych użytkowników" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Liczba zalogowanych użytkowników" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Nigdy" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Dostępny" #: mod_configure.erl:1701 msgid "Last login" msgstr "Ostatnie logowanie" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Rozmiar listy kontaktów" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "Adresy IP" #: mod_configure.erl:1724 msgid "Resources" msgstr "Zasoby" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Zarządzanie " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Wykonaj na użytkowniku" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Edytuj właściwości" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Usuń użytkownika" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Dostęp zabroniony zgodnie z zasadami usługi" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "Transport IRC" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "Moduł IRC ejabberd" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "Potrzebujesz klienta obsługującego x:data aby skonfigurować mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Rejestracja w mod_irc dla " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Wprowadź nazwę użytkownika, port i kodowanie, których chcesz używać do " "łączenia z serwerami IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Nazwa użytkownika IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Jeśli chcesz ustawić inne hasła, porty lub kodowania dla poszczególnych " "serwerów IRC, wypełnij tą listę wartościami w formacie '{\"irc server\"," "\"encoding\", port, \"password\"}'. Domyślne ta usługa używa kodowania \"~s" "\", portu ~p, bez hasła." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Przykład: [{\"wroclaw.irc.pl\",\"utf-8\"}, {\"warszawa.irc.pl\", " "\"iso8859-2\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Parametry połączeń" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Dołącz do kanału IRC" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "Kanał IRC (nie używaj #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "Serwer IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Dołącz do kanału IRC." #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Dołącz do kanału IRC pod tym Jabber ID: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "Ustawienia IRC" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Wprowadź nazwę użytkownika i kodowania których chcesz używać do łączenia z " "serwerami IRC. Wciśnij \"Dalej\" aby ustawić więcej parametrów połączenia. " "Wciśnij \"Zakończ\" aby zapisać ustawienia." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "Nazwa użytkownika IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Hasło ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Port ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Kodowanie znaków dla serwera ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Serwer ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "Tylko administratorzy mogą wysyłać wiadomości" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Zasady serwera zabraniają tworzyć nowe pokoje" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Pokój konferencyjny nie istnieje" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Pokoje rozmów" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "Potrzebujesz klienta obsługującego x:data aby zarejestrować nick" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Rejestracja nazwy użytkownika na " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Wprowadz nazwę użytkownika którego chcesz zarejestrować" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Nazwa użytkownika" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Ta nazwa użytkownika jest już zarejestrowana przez inną osobę" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Musisz wypełnić pole \"Nazwa użytkownika\" w formularzu" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "Moduł MUC" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Konfiguracja pokoju zmodyfikowana" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "dołącza do pokoju" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "opuszcza pokój" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "został wykluczony" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "został wyrzucony" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "został wyrzucony z powodu zmiany przynależności" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "został wyrzucony z powodu zmiany pokoju na \"Tylko dla Członków\"" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "został wyrzucony z powodu wyłączenia systemu" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "jest teraz znany jako" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " zmienił temat na: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Pokój został stworzony" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Pokój został usunięty" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Pokój został uruchomiony" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Pokój został zatrzymany" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Poniedziałek" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Wtorek" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Środa" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Czwartek" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Piątek" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Sobota" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Niedziela" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Styczeń" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Luty" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Marzec" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "Kwiecień" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Maj" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Czerwiec" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Lipiec" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Sierpień" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "Wrzesień" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Październik" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "Listopad" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "Grudzień" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Konfiguracja pokoju" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Lista uczestników" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Limit transferu przekroczony" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Ten uczestnik został wyrzucony z pokoju ponieważ wysłał komunikat błędu" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Nie wolno wysyłac prywatnych wiadomości na konferencję" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "Proszę poczekać chwile, zanim wyślesz nowe żądanie głosowe" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "Głosowe żądania są wyłączone w tym pokoju" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "Nie udało się wydobyć JID-u z twojego żądania" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Tylko moderatorzy mogą zatwierdzać żądania głosowe" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Nieprawidłowy typ wiadomości" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Ten uczestnik został wyrzucony z pokoju ponieważ wysłał komunikat błędu do " "innego uczestnika" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "Nie można wysyłać prywatnych wiadomości typu \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Odbiorcy nie ma w pokoju" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Wysyłanie prywatnych wiadomości jest zabronione" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Tylko uczestnicy mogą wysyłać wiadomości na konferencję" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Tylko uczestnicy mogą wysyłać zapytania do konferencji" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "Informacje o członkach konferencji nie są dostępne w tym pokoju" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "Tylko moderatorzy i uczestnicy mogą zmienić temat tego pokoju" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Tylko moderatorzy mogą zmienić temat tego pokoju" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Odwiedzający nie mogą wysyłać wiadomości do wszystkich obecnych" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Ten uczestnik został wyrzucony z pokoju ponieważ jego informacja o statusie " "zawierała błędy" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Uczestnicy tego pokoju nie mogą zmieniać swoich nicków" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Ta nazwa użytkownika jest używana przez kogoś innego" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Zostałeś wykluczony z tego pokoju" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Musisz być na liście członków tego pokoju aby do niego wejść" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Ten pokój nie jest anonimowy" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Aby wejść do pokoju wymagane jest hasło" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Za dużo żądań CAPTCHA" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Nie można wygenerować CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Nieprawidłowe hasło" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Wymagane uprawnienia administratora" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Wymagane uprawnienia moderatora" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Jabber ID ~s jest niepoprawny" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Nie ma nicka ~s w tym pokoju" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Nieprawidłowa przynależność: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Nieprawidłowa rola: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Wymagane uprawnienia właściciela" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Konfiguracja pokoju ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Tytuł pokoju" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Opis pokoju" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Utwórz pokój na stałe" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Pozwól wyszukiwać pokój" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Upublicznij listę uczestników" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Pokój zabezpieczony hasłem" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Maksymalna liczba uczestników" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Bez limitu" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Prawdziwe Jabber ID widoczne dla" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "tylko moderatorzy" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "wszystkich" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Pokój tylko dla członków" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Pokój moderowany" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Domyślni użytkownicy jako uczestnicy" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Pozwól użytkownikom zmieniać temat" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Pozwól użytkownikom wysyłać prywatne wiadomości" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "Pozwól użytkownikom wysyłać prywatne wiadomości" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "nikt" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Pozwól użytkownikom pobierać informacje o innych użytkownikach" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Pozwól użytkownikom wysyłać zaproszenia" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "Pozwól uczestnikom na wysyłanie statusów opisowych" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Pozwól uczestnikom na zmianę nicka" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "Pozwól użytkownikom wysyłać zaproszenia" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "Minimalny odstęp między żądaniami głosowymi (w sekundach)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Pokój zabezpieczony captchą" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Pomiń Jabber ID z żądania CAPTCHA" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Włącz logowanie" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Potrzebujesz klienta obsługującego x:data aby skonfigurować pokój" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Liczba uczestników" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "prywatny, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Żądanie głosowe" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Zatwierdź lub odrzuć żądanie głosowe" #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "Użytkownik " #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "Udzielić głosu tej osobie?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s zaprasza Cię do pokoju ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "hasło to:" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "Kolejka wiadomości offline adresata jest pełna. Wiadomość została odrzucona." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "Kolejka wiadomości offline użytkownika ~s" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Wprowadzone" #: mod_offline.erl:571 msgid "Time" msgstr "Czas" #: mod_offline.erl:572 msgid "From" msgstr "Od" #: mod_offline.erl:573 msgid "To" msgstr "Do" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Pakiet" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Usuń zaznaczone" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Wiadomości offline:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Usuń wszystkie wiadomości typu 'Offline'" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "Moduł SOCKS5 Bytestreams" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "PubSub" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "Moduł Publish-Subscribe" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Żądanie subskrybcji PubSub" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Wybierz, czy akceptować subskrypcję tej jednostki" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ID węzła" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Adres subskrybenta" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Pozwól temu Jabber ID na zapisanie się do tego węzła PubSub" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Dostarczaj zawartość publikacji wraz z powiadomieniami o zdarzeniach" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Dostarczaj powiadomienia o zdarzeniach" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Informuj subskrybentów o zmianach konfiguracji węzła" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Informuj subskrybentów o usunięciu węzła" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Informuj subskrybentów o usunięciu elementów węzła" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Przechowuj na stałe dane PubSub" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Przyjazna nazwa węzła" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Maksymalna liczba przechowywanych przedmiotów" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Czy pozwolić na subskrypcje" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Określ model dostępu" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Grupy kontaktów uprawnione do subskrypcji" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Określ model publikującego" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "Usuń wszystkie elementy w momencie kiedy publikujący rozłączy się" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Określ typ wiadomości" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Maksymalna wielkość powiadomienia w bajtach" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Kiedy wysłać ostatnio opublikowaną rzecz" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Dostarczaj powiadomienia tylko dostępnym użytkownikom" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Grupy, do których należy węzeł" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "Weryfikacja CAPTCHA nie powiodła się." #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "Potrzebujesz klienta obsługującego x:data aby zarejestrować nick" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "" "Wybierz nazwę użytkownika i hasło aby zarejestrować się na tym serwerze" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Użytkownik" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "Hasło nie jest wystarczająco trudne" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Użytkowncy nie mogą tak szybko rejestrować nowych kont" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Brak" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Subskrypcja" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Oczekuje" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Grupy" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Potwierdź" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Usuń" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Lista kontaktów " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Błędny format" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Dodaj Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Lista kontaktów" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Wspólne grupy kontaktów" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Dodaj nowe" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Nazwa:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Opis:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Członkowie:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Wyświetlane grupy:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Grupa " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Wyślij" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Data urodzenia" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Miasto" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Państwo" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Email" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Nazwisko" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Wypełnij formularz aby wyszukać użytkowników Jabbera (dodaj * na koniec " "zapytania aby wyszukać po fragmencie)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Pełna nazwa" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Drugie imię" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Imię" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Nazwa organizacji" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Dział" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Wyszukaj użytkowników w " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Potrzebujesz klienta obsługującego x:data aby wyszukiwać" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Wyszukiwanie vCard użytkowników" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "Moduł vCard ejabberd" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Wyniki wyszukiwania dla " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Wypełnij pola aby znaleźć pasujących użytkowników Jabbera" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Nie autoryzowano" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd: Panel Administracyjny" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Administracja" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Żródło" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "~s konfiguracja zasad dostępu" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Wirtualne Hosty" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Użytkownicy" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Ostatnia aktywność użytkowników" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Przedział czasu: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Miniony miesiąc" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Miniony rok" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Cała aktywność" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Pokaż zwykłą tabelę" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Pokaż tabelę całkowitą" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Statystyki" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Nie znaleziono" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Węzeł nie został znaleziony" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Host" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Użytkownicy zarejestrowani" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Wiadomości offline" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Ostatnia aktywność" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Użytkownicy zarejestrowani:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Użytkownicy zalogowani:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Wychodzące połączenia s2s:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Serwery zewnętrzne s2s:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Zmień hasło" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Użytkownik " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Zasoby zalogowane:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Hasło:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Brak danych" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Węzły" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Węzeł " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Porty nasłuchujące" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Aktualizuj" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Uruchom ponownie" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Zatrzymaj" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Błąd żądania RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Tabele bazy na " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Typ bazy" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Elementy" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Pamięć" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Błąd" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Kopia zapasowa " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Te opcje kopii zapasowych dotyczą tylko wbudowanej bazy danych typu Mnesia. " "Jeśli korzystasz z modułu ODBC, musisz wykonać kopie bazy we własnym " "zakresie." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Zachowaj kopię binarną:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Natychmiast odtwórz kopię binarną:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Odtwórz kopię binarną podczas następnego uruchomienia ejabberd (wymaga mniej " "zasobów):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Zachowaj kopię w postaci tekstowej:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Natychmiast odtwórz kopię z postaci tekstowej:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Importuj dane użytkowników z pliku w formacie PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Eksportuj dane wszystkich użytkowników serwera do plików w formacie PIEFXIS " "(XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" "Eksportuj dane użytkowników z hosta do plików w formacie PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importuj dane użytkownika z pliku roboczego serwera jabberd14:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importuj użytkowników z katalogu roboczego serwera jabberd14" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Porty nasłuchujące na " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Moduły na " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Statystyki ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Czas pracy:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Czas CPU:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transakcje zakończone:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transakcje anulowane:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transakcje uruchomione ponownie:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transakcje zalogowane:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Uaktualnij " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Plan aktualizacji" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Zmodyfikowane moduły" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Skrypt aktualizacji" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Skrypt aktualizacji niskiego poziomu" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Sprawdź skrypt" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Port" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protokół" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Moduł" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Opcje" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Usuń" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Uruchom" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Twoje konto zostało stworzone." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Wystąpił błąd podczas tworzenia konta:" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Twoje konto zostało usunięte." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Podczas usuwania konta wystąpił błąd:" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Hasło do Twojego konta zostało zmienione." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Podczas próby zmiany hasła wystąpił błąd:" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Zakładanie konta Jabber" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Załóż konto Jabber" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Usuń konto Jabber" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Niniejsza strona pozwala na założenie konta Jabber na tym serwerze. Twój JID " "(Jabber IDentyfikator) będzie miał postać: nazwa_użytkownika@serwer. " "Przeczytaj dokładnie instrukcję i wypełnij pola." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Nazwa użytkownika:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Pole nie rozróżnia wielkości liter: słowo Hanna jest takie samo jak hAnna " "lub haNNa." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Te znaki są niedozwolone:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Serwer:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "Nie podawaj swojego hasła nikomu, nawet administratorowi serwera Jabber." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "Możesz później zmienić swoje hasło za pomocą dowolnego klienta Jabber." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Niektóre klienty Jabber mogą zapisywać Twoje hasło na komputerze. Używaj tej " "opcji tylko jeśli ufasz komputerowi na którym pracujesz." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Zapamiętaj swoje hasło lub zapisz je na kartce i zachowaj w bezpiecznym " "miejscu. Na Jabberze nie ma zautomatyzowanego systemu odzyskiwania haseł." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Weryfikacja hasła:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Zarejestruj" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Stare hasło:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Nowe hasło:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "Ta strona pozwala usunąć konto Jabber z tego serwera." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Wyrejestruj" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "Captcha jest poprawna." ejabberd-2.1.11/src/msgs/id.po0000664000000000000000000015406712240230175012727 0ustar # , 2010. msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "PO-Revision-Date: 2011-02-15 07:09+0800\n" "Last-Translator: Irfan Mahfudz Guntur \n" "Language-Team: SmartCommunity \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Indonesian (Bahasa Indonesia)\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Penggunaan STARTTLS diperlukan" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Tidak ada sumber daya yang disediakan" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Diganti dengan koneksi baru" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "Daftar privasi aktif Anda telah menolak routing ztanza ini" #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Masukkan teks yang Anda lihat" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "Pesan Anda untuk ~s sedang diblokir. Untuk membuka blokir tersebut, kunjungi " "~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" "Jika Anda tidak melihat gambar CAPTCHA disini, silahkan kunjungi halaman web." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "CAPTCHA laman web" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "Captcha ini benar." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Perintah" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Benar-benar ingin menghapus pesan harian?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Subyek" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Isi Pesan" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Tidak ada isi pesan yang disediakan untuk mengirimkan pesan" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Pengumuman" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Kirim pengumuman untuk semua pengguna" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Kirim pengumuman untuk semua pengguna pada semua host" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Kirim pengumuman untuk semua pengguna yang online" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Kirim pengumuman untuk semua pengguna yang online pada semua host" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Mengatur pesan harian dan mengirimkan ke pengguna yang online" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Mengatur pesan harian pada semua host dan kirimkan ke pengguna yang online" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Rubah pesan harian (tidak dikirim)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Rubah pesan harian pada semua host (tidak dikirim)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Hapus pesan harian" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Hapus pesan harian pada semua host" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Pengaturan" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Database" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Memulai Modul" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Hentikan Modul" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Backup" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Mengembalikan" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Dump menjadi File Teks" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Impor File" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Impor Direktori" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Restart Layanan" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Shut Down Layanan" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Tambah Pengguna" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Hapus Pengguna" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Akhir Sesi Pengguna" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Dapatkan User Password" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Ubah User Password" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Dapatkan Waktu Login Terakhir Pengguna " #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Dapatkan Statistik Pengguna" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Dapatkan Jumlah Pengguna Yang Terdaftar" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Dapatkan Jumlah User Yang Online" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Akses Daftar Pengendalian" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Aturan Akses" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Manajemen Pengguna" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Pengguna Yang Online" #: mod_configure.erl:501 msgid "All Users" msgstr "Semua Pengguna" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Koneksi Keluar s2s" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Menjalankan Node" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Menghentikan node" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Modul" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Manajemen Backup" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Impor Pengguna Dari jabberd14 Spool File" #: mod_configure.erl:699 msgid "To ~s" msgstr "Kepada ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Dari ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Database Tabel Konfigurasi pada" #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Pilih jenis penyimpanan tabel" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Hanya salinan dari disc" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "RAM dan disc salinan" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Salinan RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Salinan Remote" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Hentikan Modul pada" #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Pilih Modul untuk berhenti" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Mulai Modul pada" #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Masukkan daftar {Modul, [Options]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Daftar modul untuk memulai" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Backup ke File pada" #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Masukkan path untuk file cadangan" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Jalur ke File" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Kembalikan Backup dari File pada" #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Dump Backup ke File Teks di" #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Masukkan path ke file teks" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Impor Pengguna dari File pada" #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Masukkan path ke file jabberd14 spool" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Impor Pengguna dari Dir di" #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Masukkan path ke direktori spool jabberd14" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Jalur ke Dir" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Waktu tunda" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Konfigurasi Daftar Akses Pengendalian" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Daftar Pengendalian Akses" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Akses Konfigurasi" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Akses peraturan" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Sandi" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Verifikasi Sandi" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Jumlah pengguna terdaftar" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Jumlah pengguna online" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Tidak Pernah" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Online" #: mod_configure.erl:1701 msgid "Last login" msgstr "Terakhir Login" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Ukuran Daftar Kontak" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "Alamat IP" #: mod_configure.erl:1724 msgid "Resources" msgstr "Sumber daya" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Administrasi" #: mod_configure.erl:1853 msgid "Action on user" msgstr "Tindakan pada pengguna" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Ganti Properti" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Hapus Pengguna" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Akses ditolak oleh kebijakan layanan" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC Transport" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC modul" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "Anda memerlukan x:data klien untuk mampu mengkonfigurasi pengaturan mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Pendaftaran di mod_irc untuk" #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Masukkan username, pengkodean, port dan sandi yang ingin Anda gunakan untuk " "menghubungkan ke layanan IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Nama Pengguna IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Jika Anda ingin menentukan port yang berbeda, sandi, pengkodean untuk " "layanan IRC, isi daftar ini dengan nilai-nilai dalam format '{\"server irc " "\", \"encoding \", port, \"sandi \"}'. Secara default ini menggunakan " "layanan \"~s \" pengkodean, port ~p, kata sandi kosong." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Contoh: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Parameter Koneksi" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Gabung channel IRC" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "Channel IRC (tidak perlu menempatkan # sebelumnya)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "Layanan IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Gabung ke channel IRC disini" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Gabung ke channel IRC dengan Jabber ID: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "Pengaturan IRC" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Masukkan username dan pengkodean yang ingin Anda gunakan untuk menghubungkan " "ke layanan IRC. Tekan 'Selanjutnya' untuk mendapatkan lagi formulir kemudian " "Tekan 'Lengkap' untuk menyimpan pengaturan." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "Nama Pengguna IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Kata Sandi ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Port ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Pengkodean untuk layanan ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Layanan ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" "Layanan hanya diperuntukan kepada administrator yang diizinkan untuk " "mengirim layanan pesan" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Pembuatan Ruangan ditolak oleh kebijakan layanan" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Ruang Konferensi tidak ada" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Ruangan Chat" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "Anda memerlukan klien yang mendukung x:data untuk mendaftar julukan" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Pendaftaran Julukan pada" #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Masukkan nama julukan Anda jika ingin mendaftar" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Nama Julukan" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Julukan tersebut telah didaftarkan oleh orang lain" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Anda harus mengisi kolom \"Julukan\" dalam formulir" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC Module" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Konfigurasi ruang chat diubah" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "bergabung ke ruangan" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "meninggalkan ruangan" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "telah dibanned" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "telah dikick" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "telah dikick karena perubahan afiliasi" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "telah dikick karena ruangan telah diubah menjadi hanya untuk member" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "telah dikick karena sistem shutdown" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "sekarang dikenal sebagai" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr "telah menetapkan topik yaitu:" #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Ruang chat telah dibuat" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Ruang chat dilenyapkan" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Ruang chat dimulai" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Ruang chat dihentikan" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Senin" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Selasa" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Rabu" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Kamis" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Jumat" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Sabtu" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Minggu" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Januari" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Februari" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Maret" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "April" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Mei" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Juni" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Juli" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Agustus" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "September" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Oktober" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "Nopember" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "Desember" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Konfigurasi Ruangan" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Penghuni Ruangan" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Lalu lintas melebihi batas" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "Peserta ini dikick dari ruangan karena dia mengirim pesan kesalahan" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Hal ini tidak diperbolehkan untuk mengirim pesan pribadi ke konferensi" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Jenis pesan yang tidak benar" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Participant ini dikick dari ruangan karena ia mengirim pesan kesalahan ke " "participant lain" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "" "Hal ini tidak diperbolehkan untuk mengirim pesan pribadi jenis \"groupchat \"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Penerima tidak berada di ruangan konferensi" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Hal ini tidak diperbolehkan untuk mengirim pesan pribadi" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Hanya penghuni yang diizinkan untuk mengirim pesan ke konferensi" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Hanya penghuni diizinkan untuk mengirim permintaan ke konferensi" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "" "Permintaan untuk para anggota konferensi tidak diperbolehkan di ruangan ini" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Hanya moderator dan peserta yang diizinkan untuk mengganti topik pembicaraan " "di ruangan ini" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "" "Hanya moderator yang diperbolehkan untuk mengubah topik dalam ruangan ini" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Visitor tidak diperbolehkan untuk mengirim pesan ke semua penghuni" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Participant ini dikick dari ruangan karena ia mengirim kehadiran kesalahan" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Visitor tidak diperbolehkan untuk mengubah nama julukan di ruangan ini" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Julukan itu sudah digunakan oleh penghuni lain" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Anda telah diblokir dari ruangan ini" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Hanya Member yang dapat masuk ruangan ini" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Ruangan ini tidak dikenal" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Diperlukan kata sandi untuk masuk ruangan ini" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Tidak dapat menghasilkan CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Kata sandi salah" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Hak istimewa Administrator dibutuhkan" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Hak istimewa moderator dibutuhkan" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Jabber ID ~s tidak valid" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Nama Julukan ~s tidak berada di dalam ruangan" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Afiliasi tidak valid: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Peran tidak valid: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Hak istimewa owner dibutuhkan" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Pengaturan ruangan ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Nama Ruangan" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Keterangan ruangan" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Buat ruangan menjadi permanent" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Buat ruangan dapat dicari" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Buat daftar participant diketahui oleh public" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Buat ruangan yang dilindungi dengan kata sandi" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Maksimum Jumlah Penghuni" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Tidak terbatas" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Tampilkan Jabber ID secara lengkap" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "Hanya moderator" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "Siapapun" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Buat ruangan hanya untuk member saja" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Buat ruangan hanya untuk moderator saja" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "pengguna pertama kali masuk sebagai participant" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Perbolehkan pengguna untuk mengganti topik" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "perbolehkan pengguna mengirimkan pesan ke pengguna lain secara pribadi" #: mod_muc/mod_muc_room.erl:3279 #, fuzzy msgid "Allow visitors to send private messages to" msgstr "perbolehkan pengguna mengirimkan pesan ke pengguna lain secara pribadi" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Perbolehkan pengguna untuk mengetahui pengguna lain" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Perbolehkan pengguna mengirimkan undangan" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "Izinkan pengunjung untuk mengirim teks status terbaru" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Perbolehkan visitor mengganti nama julukan" #: mod_muc/mod_muc_room.erl:3308 #, fuzzy msgid "Allow visitors to send voice requests" msgstr "Perbolehkan pengguna mengirimkan undangan" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Buat ruangan dilindungi dengan CAPTCHA" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Aktifkan catatan" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Anda memerlukan x:data klien untuk dapat mengkonfigurasi ruangan" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Jumlah Penghuni" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "pribadi, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "" #: mod_muc/mod_muc_room.erl:3809 #, fuzzy msgid "User JID" msgstr "Pengguna" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s mengundang anda ke ruangan ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "kata sandi yaitu:" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "Kontak offline Anda pada antrian pesan sudah penuh. Pesan telah dibuang." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "Antrian Pesan Offline ~s" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Ulangi masukan" #: mod_offline.erl:571 msgid "Time" msgstr "Waktu" #: mod_offline.erl:572 msgid "From" msgstr "Dari" #: mod_offline.erl:573 msgid "To" msgstr "Kepada" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Paket" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Hapus Yang Terpilih" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Pesan Offline:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Hapus Semua Pesan Offline" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "modul ejabberd SOCKS5 Bytestreams" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Setujui-Pertemanan" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "Modul ejabberd Setujui-Pertemanan" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Permintaan pertemanan PubSub" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Pilih apakah akan menyetujui hubungan pertemanan ini." #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ID Node" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Alamat Pertemanan" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Izinkan ID Jabber ini untuk berlangganan pada node pubsub ini?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Memberikan muatan dengan pemberitahuan acara" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Memberikan pemberitahuan acara" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Beritahu pelanggan ketika ada perubahan konfigurasi node" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Beritahu pelanggan ketika node dihapus" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Beritahu pelanggan ketika item tersebut dikeluarkan dari node" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Pertahankan item ke penyimpanan" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Nama yang dikenal untuk node" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Max item untuk bertahan" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Apakah diperbolehkan untuk berlangganan" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Tentukan model akses" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Kelompok kontak yang diizinkan untuk berlangganan" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Tentukan model penerbitan" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "Bersihkan semua item ketika penerbit yang relevan telah offline" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Tentukan jenis acara pesan" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Max kapasitas ukuran dalam bytes" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Ketika untuk mengirim item terakhir yang dipublikasikan" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Hanya mengirimkan pemberitahuan kepada pengguna yang tersedia" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Koleksi dengan yang berafiliasi dengan sebuah node" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "Verifikasi CAPTCHA telah gagal" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "Anda memerlukan klien yang mendukung x:data dan CAPTCHA untuk mendaftar" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Pilih nama pengguna dan kata sandi untuk mendaftar dengan layanan ini" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Pengguna" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "Kata sandi terlalu lemah" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Pengguna tidak diperkenankan untuk mendaftar akun begitu cepat" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Tak satupun" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Berlangganan" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Tertunda" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Grup" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Mengesahkan" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Menghapus" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Kontak dari" #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Format yang buruk" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Tambah Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Kontak" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Berbagi grup kontak" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Tambah Baru" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Nama:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Keterangan:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Anggota:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Tampilkan Grup:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Grup" #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Serahkan" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Layanan Erlang Jabber" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Hari Lahir" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Kota" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Negara" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Email" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Nama Keluarga (marga)" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Isi formulir untuk pencarian pengguna Jabber yang cocok (Tambahkan * ke " "mengakhiri pengisian untuk menyamakan kata)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Nama Lengkap" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Nama Tengah" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Nama" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Nama Organisasi" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Unit Organisasi" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Pencarian pengguna dalam" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Anda memerlukan x:data klien untuk melakukan pencarian" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "vCard Pencarian Pengguna" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "Modul ejabberd vCard" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Hasil Pencarian untuk" #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Isi kolom untuk mencari pengguna Jabber yang sama" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Ditolak" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "Admin Web ejabberd" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Administrasi" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "mentah" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "~s aturan akses konfigurasi" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Virtual Hosts" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Pengguna" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Aktifitas terakhir para pengguna" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Periode:" #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Akhir bulan" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Akhir tahun" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Semua aktifitas" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Tampilkan Tabel Normal" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Tampilkan Tabel Terpisah" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Statistik" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Tidak Ditemukan" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Node tidak ditemukan" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Host" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Pengguna Terdaftar" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Pesan Offline" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Aktifitas Terakhir" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Pengguna Terdaftar:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Pengguna Online:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Koneksi s2s yang keluar:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Layanan s2s yang keluar:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Ubah Kata Sandi" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Pengguna" #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Sumber Daya Terhubung:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Kata Sandi:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Tidak Ada Data" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Node-node" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Node" #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Port Terdeteksi" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Memperbarui" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Jalankan Ulang" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Hentikan" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Panggilan Kesalahan RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Tabel Database pada" #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Jenis Penyimpanan" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Elemen-elemen" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Memori" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Kesalahan" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Cadangan dari" #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Harap dicatat bahwa pilihan ini hanya akan membuat cadangan builtin Mnesia " "database. Jika Anda menggunakan modul ODBC, anda juga perlu untuk membuat " "cadangan database SQL Anda secara terpisah." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Penyimpanan cadangan yang berpasangan:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "YA" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Segera mengembalikan cadangan yang berpasangan:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Mengembalikan cadangan yang berpasanagn setelah ejabberd berikutnya " "dijalankan ulang (memerlukan memori lebih sedikit):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Simpan cadangan teks biasa:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Segera mengembalikan cadangan teks biasa:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "impor data-data pengguna dari sebuah PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Ekspor data dari semua pengguna pada layanan ke berkas PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "Ekspor data pengguna pada sebuah host ke berkas PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Impor data pengguna dari sekumpulan berkas jabberd14:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Импорт пользовательских данных из буферной директории jabberd14:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Mendeteksi Port-port di" #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "modul-modul di" #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "statistik dari ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Sampai saat:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Waktu CPU:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transaksi yang dilakukan:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transaksi yang dibatalkan:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transaksi yang dijalankan ulang:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transaksi yang ditempuh:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Memperbarui " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Rencana Perubahan" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Modifikasi modul-modul" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Perbarui naskah" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Perbaruan naskah tingkat rendah" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Periksa naskah" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Port" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protocol" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Modul" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Pilihan-pilihan" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Hapus" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Mulai" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Jabber akun Anda telah sukses dibuat" #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Ada kesalahan saat membuat akun:" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Jabber akun Anda berhasil dihapus." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Ada kesalahan saat menghapus akun:" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Kata sandi pada akun Jabber Anda telah berhasil diubah." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Ada kesalahan dalam mengubah password:" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Pendaftaran Akun Jabber" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Daftarkan sebuah akun jabber" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Nonaktifkan akun jabber" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Halaman ini memungkinkan untuk membuat akun Jabber di layanan Jabber ini. " "JID Anda (Jabber Pengenal) akan berbentuk: namapengguna@layanan. Harap baca " "dengan seksama petunjuk-petunjuk untuk mengisi kolom dengan benar." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Nama Pengguna:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Pada bagian ini huruf besar dan kecil tidak dibedakan: Misalnya macbeth " "adalah sama dengan MacBeth juga Macbeth." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Karakter tidak diperbolehkan:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Layanan:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "Jangan memberitahukan kata sandi Anda ke siapapun, bahkan para administrator " "dari layanan Jabber." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" "Anda dapat mengubah kata sandi anda dilain waktu dengan menggunakan klien " "Jabber." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Beberapa klien Jabber dapat menyimpan password di komputer Anda. Gunakan " "fitur itu hanya jika Anda mempercayai komputer Anda aman." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Hafalkan kata sandi Anda, atau dicatat dan letakkan di tempat yang aman. " "Didalam Jabber tidak ada cara otomatis untuk mendapatkan kembali password " "Anda jika Anda lupa." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Verifikasi Kata Sandi:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Mendaftar" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Password Lama:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Password Baru:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" "Pada bagian ini memungkinkan Anda untuk membatalkan pendaftaran akun Jabber " "pada layanan Jabber ini." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Nonaktifkan" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "Проверка капчи прошла успешно." ejabberd-2.1.11/src/msgs/pl.msg0000664000000000000000000006617112240230175013114 0ustar {"Access Configuration","Konfiguracja dostępu"}. {"Access Control List Configuration","Konfiguracja listy dostępowej"}. {"Access Control Lists","Lista dostępowa"}. {"Access control lists","Listy dostępowe"}. {"Access denied by service policy","Dostęp zabroniony zgodnie z zasadami usługi"}. {"Access rules","Reguły dostępu"}. {"Access Rules","Zasady dostępu"}. {"Action on user","Wykonaj na użytkowniku"}. {"Add Jabber ID","Dodaj Jabber ID"}. {"Add New","Dodaj nowe"}. {"Add User","Dodaj użytkownika"}. {"Administration","Administracja"}. {"Administration of ","Zarządzanie "}. {"Administrator privileges required","Wymagane uprawnienia administratora"}. {"A friendly name for the node","Przyjazna nazwa węzła"}. {"All activity","Cała aktywność"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Pozwól temu Jabber ID na zapisanie się do tego węzła PubSub"}. {"Allow users to change the subject","Pozwól użytkownikom zmieniać temat"}. {"Allow users to query other users","Pozwól użytkownikom pobierać informacje o innych użytkownikach"}. {"Allow users to send invites","Pozwól użytkownikom wysyłać zaproszenia"}. {"Allow users to send private messages","Pozwól użytkownikom wysyłać prywatne wiadomości"}. {"Allow visitors to change nickname","Pozwól uczestnikom na zmianę nicka"}. {"Allow visitors to send private messages to","Pozwól użytkownikom wysyłać prywatne wiadomości"}. {"Allow visitors to send status text in presence updates","Pozwól uczestnikom na wysyłanie statusów opisowych"}. {"Allow visitors to send voice requests","Pozwól użytkownikom wysyłać zaproszenia"}. {"All Users","Wszyscy użytkownicy"}. {"Announcements","Powiadomienia"}. {"anyone","wszystkich"}. {"A password is required to enter this room","Aby wejść do pokoju wymagane jest hasło"}. {"April","Kwiecień"}. {"August","Sierpień"}. {"Backup Management","Zarządzanie kopiami zapasowymi"}. {"Backup of ","Kopia zapasowa "}. {"Backup to File at ","Zapisz kopię w pliku na "}. {"Backup","Wykonaj kopie"}. {"Bad format","Błędny format"}. {"Birthday","Data urodzenia"}. {"CAPTCHA web page","Strona internetowa CAPTCHA"}. {"Change Password","Zmień hasło"}. {"Change User Password","Zmień hasło użytkownika"}. {"Characters not allowed:","Te znaki są niedozwolone:"}. {"Chatroom configuration modified","Konfiguracja pokoju zmodyfikowana"}. {"Chatroom is created","Pokój został stworzony"}. {"Chatroom is destroyed","Pokój został usunięty"}. {"Chatroom is started","Pokój został uruchomiony"}. {"Chatroom is stopped","Pokój został zatrzymany"}. {"Chatrooms","Pokoje rozmów"}. {"Choose a username and password to register with this server","Wybierz nazwę użytkownika i hasło aby zarejestrować się na tym serwerze"}. {"Choose modules to stop","Wybierz moduły do zatrzymania"}. {"Choose storage type of tables","Wybierz typ bazy dla tablel"}. {"Choose whether to approve this entity's subscription.","Wybierz, czy akceptować subskrypcję tej jednostki"}. {"City","Miasto"}. {"Commands","Polecenia"}. {"Conference room does not exist","Pokój konferencyjny nie istnieje"}. {"Configuration","Konfiguracja"}. {"Configuration of room ~s","Konfiguracja pokoju ~s"}. {"Connected Resources:","Zasoby zalogowane:"}. {"Connections parameters","Parametry połączeń"}. {"Country","Państwo"}. {"CPU Time:","Czas CPU:"}. {"Database","Baza danych"}. {"Database Tables at ","Tabele bazy na "}. {"Database Tables Configuration at ","Konfiguracja tabel bazy na "}. {"December","Grudzień"}. {"Default users as participants","Domyślni użytkownicy jako uczestnicy"}. {"Delete message of the day on all hosts","Usuń wiadomość dnia ze wszystkich hostów"}. {"Delete message of the day","Usuń wiadomość dnia"}. {"Delete Selected","Usuń zaznaczone"}. {"Delete User","Usuń użytkownika"}. {"Delete","Usuń"}. {"Deliver event notifications","Dostarczaj powiadomienia o zdarzeniach"}. {"Deliver payloads with event notifications","Dostarczaj zawartość publikacji wraz z powiadomieniami o zdarzeniach"}. {"Description:","Opis:"}. {"Disc only copy","Kopia tylko na dysku"}. {"Displayed Groups:","Wyświetlane grupy:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Nie podawaj swojego hasła nikomu, nawet administratorowi serwera Jabber."}. {"Dump Backup to Text File at ","Zapisz kopię zapasową w pliku tekstowym na "}. {"Dump to Text File","Wykonaj kopie do pliku tekstowego"}. {"Edit Properties","Edytuj właściwości"}. {"Either approve or decline the voice request.","Zatwierdź lub odrzuć żądanie głosowe"}. {"ejabberd IRC module","Moduł IRC ejabberd"}. {"ejabberd MUC module","Moduł MUC"}. {"ejabberd Publish-Subscribe module","Moduł Publish-Subscribe"}. {"ejabberd SOCKS5 Bytestreams module","Moduł SOCKS5 Bytestreams"}. {"ejabberd vCard module","Moduł vCard ejabberd"}. {"ejabberd Web Admin","ejabberd: Panel Administracyjny"}. {"Elements","Elementy"}. {"Email","Email"}. {"Enable logging","Włącz logowanie"}. {"Encoding for server ~b","Kodowanie znaków dla serwera ~b"}. {"End User Session","Zakończ sesję uzytkownika"}. {"Enter list of {Module, [Options]}","Wprowadź listę {Moduł, [Opcje]}"}. {"Enter nickname you want to register","Wprowadz nazwę użytkownika którego chcesz zarejestrować"}. {"Enter path to backup file","Wprowadź scieżkę do pliku kopii zapasowej"}. {"Enter path to jabberd14 spool dir","Wprowadź ścieżkę do roboczego katalogu serwera jabberd14"}. {"Enter path to jabberd14 spool file","Wprowadź ścieżkę do roboczego pliku serwera jabberd14"}. {"Enter path to text file","Wprowadź scieżkę do pliku tekstowego"}. {"Enter the text you see","Przepisz tekst z obrazka"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Wprowadź nazwę użytkownika i kodowania których chcesz używać do łączenia z serwerami IRC. Wciśnij \"Dalej\" aby ustawić więcej parametrów połączenia. Wciśnij \"Zakończ\" aby zapisać ustawienia."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Wprowadź nazwę użytkownika, port i kodowanie, których chcesz używać do łączenia z serwerami IRC"}. {"Erlang Jabber Server","Erlang Jabber Server"}. {"Error","Błąd"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Przykład: [{\"wroclaw.irc.pl\",\"utf-8\"}, {\"warszawa.irc.pl\", \"iso8859-2\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Pomiń Jabber ID z żądania CAPTCHA"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Eksportuj dane wszystkich użytkowników serwera do plików w formacie PIEFXIS (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Eksportuj dane użytkowników z hosta do plików w formacie PIEFXIS (XEP-0227):"}. {"Failed to extract JID from your voice request approval","Nie udało się wydobyć JID-u z twojego żądania"}. {"Family Name","Nazwisko"}. {"February","Luty"}. {"Fill in fields to search for any matching Jabber User","Wypełnij pola aby znaleźć pasujących użytkowników Jabbera"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Wypełnij formularz aby wyszukać użytkowników Jabbera (dodaj * na koniec zapytania aby wyszukać po fragmencie)"}. {"Friday","Piątek"}. {"From","Od"}. {"From ~s","Od ~s"}. {"Full Name","Pełna nazwa"}. {"Get Number of Online Users","Pokaż liczbę zalogowanych użytkowników"}. {"Get Number of Registered Users","Pokaż liczbę zarejestrowanych użytkowników"}. {"Get User Last Login Time","Pokaż czas ostatniego zalogowania uzytkownika"}. {"Get User Password","Pobierz hasło użytkownika"}. {"Get User Statistics","Pobierz statystyki użytkownika"}. {"Grant voice to this person?","Udzielić głosu tej osobie?"}. {"Group ","Grupa "}. {"Groups","Grupy"}. {"has been banned","został wykluczony"}. {"has been kicked because of an affiliation change","został wyrzucony z powodu zmiany przynależności"}. {"has been kicked because of a system shutdown","został wyrzucony z powodu wyłączenia systemu"}. {"has been kicked because the room has been changed to members-only","został wyrzucony z powodu zmiany pokoju na \"Tylko dla Członków\""}. {"has been kicked","został wyrzucony"}. {" has set the subject to: "," zmienił temat na: "}. {"Host","Host"}. {"If you don't see the CAPTCHA image here, visit the web page.","Jeśli nie widzisz obrazka CAPTCHA, odwiedź stronę internetową."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Jeśli chcesz ustawić inne hasła, porty lub kodowania dla poszczególnych serwerów IRC, wypełnij tą listę wartościami w formacie '{\"irc server\",\"encoding\", port, \"password\"}'. Domyślne ta usługa używa kodowania \"~s\", portu ~p, bez hasła."}. {"Import Directory","Importuj katalog"}. {"Import File","Importuj plik"}. {"Import user data from jabberd14 spool file:","Importuj dane użytkownika z pliku roboczego serwera jabberd14:"}. {"Import User from File at ","Importuj użytkownika z pliku na "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importuj dane użytkowników z pliku w formacie PIEFXIS (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Importuj użytkowników z katalogu roboczego serwera jabberd14"}. {"Import Users from Dir at ","Importuj użytkowników z katalogu na "}. {"Import Users From jabberd14 Spool Files","Importuj użytkowników z plików roboczych serwera jabberd14"}. {"Improper message type","Nieprawidłowy typ wiadomości"}. {"Incorrect password","Nieprawidłowe hasło"}. {"Invalid affiliation: ~s","Nieprawidłowa przynależność: ~s"}. {"Invalid role: ~s","Nieprawidłowa rola: ~s"}. {"IP addresses","Adresy IP"}. {"IP","IP"}. {"IRC channel (don't put the first #)","Kanał IRC (nie używaj #)"}. {"IRC server","Serwer IRC"}. {"IRC settings","Ustawienia IRC"}. {"IRC Transport","Transport IRC"}. {"IRC username","Nazwa użytkownika IRC"}. {"IRC Username","Nazwa użytkownika IRC"}. {"is now known as","jest teraz znany jako"}. {"It is not allowed to send private messages of type \"groupchat\"","Nie można wysyłać prywatnych wiadomości typu \"groupchat\""}. {"It is not allowed to send private messages to the conference","Nie wolno wysyłac prywatnych wiadomości na konferencję"}. {"It is not allowed to send private messages","Wysyłanie prywatnych wiadomości jest zabronione"}. {"Jabber Account Registration","Zakładanie konta Jabber"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Jabber ID ~s jest niepoprawny"}. {"January","Styczeń"}. {"Join IRC channel","Dołącz do kanału IRC"}. {"joins the room","dołącza do pokoju"}. {"Join the IRC channel here.","Dołącz do kanału IRC."}. {"Join the IRC channel in this Jabber ID: ~s","Dołącz do kanału IRC pod tym Jabber ID: ~s"}. {"July","Lipiec"}. {"June","Czerwiec"}. {"Last Activity","Ostatnia aktywność"}. {"Last login","Ostatnie logowanie"}. {"Last month","Miniony miesiąc"}. {"Last year","Miniony rok"}. {"leaves the room","opuszcza pokój"}. {"Listened Ports at ","Porty nasłuchujące na "}. {"Listened Ports","Porty nasłuchujące"}. {"List of modules to start","Lista modułów do uruchomienia"}. {"Low level update script","Skrypt aktualizacji niskiego poziomu"}. {"Make participants list public","Upublicznij listę uczestników"}. {"Make room CAPTCHA protected","Pokój zabezpieczony captchą"}. {"Make room members-only","Pokój tylko dla członków"}. {"Make room moderated","Pokój moderowany"}. {"Make room password protected","Pokój zabezpieczony hasłem"}. {"Make room persistent","Utwórz pokój na stałe"}. {"Make room public searchable","Pozwól wyszukiwać pokój"}. {"March","Marzec"}. {"Maximum Number of Occupants","Maksymalna liczba uczestników"}. {"Max # of items to persist","Maksymalna liczba przechowywanych przedmiotów"}. {"Max payload size in bytes","Maksymalna wielkość powiadomienia w bajtach"}. {"May","Maj"}. {"Members:","Członkowie:"}. {"Membership is required to enter this room","Musisz być na liście członków tego pokoju aby do niego wejść"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Zapamiętaj swoje hasło lub zapisz je na kartce i zachowaj w bezpiecznym miejscu. Na Jabberze nie ma zautomatyzowanego systemu odzyskiwania haseł."}. {"Memory","Pamięć"}. {"Message body","Treść wiadomości"}. {"Middle Name","Drugie imię"}. {"Minimum interval between voice requests (in seconds)","Minimalny odstęp między żądaniami głosowymi (w sekundach)"}. {"Moderator privileges required","Wymagane uprawnienia moderatora"}. {"moderators only","tylko moderatorzy"}. {"Modified modules","Zmodyfikowane moduły"}. {"Module","Moduł"}. {"Modules at ","Moduły na "}. {"Modules","Moduły"}. {"Monday","Poniedziałek"}. {"Name","Imię"}. {"Name:","Nazwa:"}. {"Never","Nigdy"}. {"New Password:","Nowe hasło:"}. {"Nickname","Nazwa użytkownika"}. {"Nickname Registration at ","Rejestracja nazwy użytkownika na "}. {"Nickname ~s does not exist in the room","Nie ma nicka ~s w tym pokoju"}. {"nobody","nikt"}. {"No body provided for announce message","Brak treści powiadomienia"}. {"No Data","Brak danych"}. {"Node ID","ID węzła"}. {"Node not found","Węzeł nie został znaleziony"}. {"Nodes","Węzły"}. {"Node ","Węzeł "}. {"No limit","Bez limitu"}. {"None","Brak"}. {"No resource provided","Nie podano zasobu"}. {"Not Found","Nie znaleziono"}. {"Notify subscribers when items are removed from the node","Informuj subskrybentów o usunięciu elementów węzła"}. {"Notify subscribers when the node configuration changes","Informuj subskrybentów o zmianach konfiguracji węzła"}. {"Notify subscribers when the node is deleted","Informuj subskrybentów o usunięciu węzła"}. {"November","Listopad"}. {"Number of occupants","Liczba uczestników"}. {"Number of online users","Liczba zalogowanych użytkowników"}. {"Number of registered users","Liczba zarejestrowanych użytkowników"}. {"October","Październik"}. {"Offline Messages:","Wiadomości offline:"}. {"Offline Messages","Wiadomości offline"}. {"OK","OK"}. {"Old Password:","Stare hasło:"}. {"Online","Dostępny"}. {"Online Users:","Użytkownicy zalogowani:"}. {"Online Users","Użytkownicy zalogowani"}. {"Only deliver notifications to available users","Dostarczaj powiadomienia tylko dostępnym użytkownikom"}. {"Only moderators and participants are allowed to change the subject in this room","Tylko moderatorzy i uczestnicy mogą zmienić temat tego pokoju"}. {"Only moderators are allowed to change the subject in this room","Tylko moderatorzy mogą zmienić temat tego pokoju"}. {"Only moderators can approve voice requests","Tylko moderatorzy mogą zatwierdzać żądania głosowe"}. {"Only occupants are allowed to send messages to the conference","Tylko uczestnicy mogą wysyłać wiadomości na konferencję"}. {"Only occupants are allowed to send queries to the conference","Tylko uczestnicy mogą wysyłać zapytania do konferencji"}. {"Only service administrators are allowed to send service messages","Tylko administratorzy mogą wysyłać wiadomości"}. {"Options","Opcje"}. {"Organization Name","Nazwa organizacji"}. {"Organization Unit","Dział"}. {"Outgoing s2s Connections:","Wychodzące połączenia s2s:"}. {"Outgoing s2s Connections","Wychodzące połączenia s2s"}. {"Outgoing s2s Servers:","Serwery zewnętrzne s2s:"}. {"Owner privileges required","Wymagane uprawnienia właściciela"}. {"Packet","Pakiet"}. {"Password ~b","Hasło ~b"}. {"Password:","Hasło:"}. {"Password","Hasło"}. {"Password Verification:","Weryfikacja hasła:"}. {"Password Verification","Weryfikacja hasła"}. {"Path to Dir","Ścieżka do katalogu"}. {"Path to File","Scieżka do pliku"}. {"Pending","Oczekuje"}. {"Period: ","Przedział czasu: "}. {"Persist items to storage","Przechowuj na stałe dane PubSub"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Te opcje kopii zapasowych dotyczą tylko wbudowanej bazy danych typu Mnesia. Jeśli korzystasz z modułu ODBC, musisz wykonać kopie bazy we własnym zakresie."}. {"Please, wait for a while before sending new voice request","Proszę poczekać chwile, zanim wyślesz nowe żądanie głosowe"}. {"Pong","Pong"}. {"Port ~b","Port ~b"}. {"Port","Port"}. {"Present real Jabber IDs to","Prawdziwe Jabber ID widoczne dla"}. {"private, ","prywatny, "}. {"Protocol","Protokół"}. {"Publish-Subscribe","PubSub"}. {"PubSub subscriber request","Żądanie subskrybcji PubSub"}. {"Purge all items when the relevant publisher goes offline","Usuń wszystkie elementy w momencie kiedy publikujący rozłączy się"}. {"Queries to the conference members are not allowed in this room","Informacje o członkach konferencji nie są dostępne w tym pokoju"}. {"RAM and disc copy","Kopia na dysku i w pamięci RAM"}. {"RAM copy","Kopia w pamięci RAM"}. {"Raw","Żródło"}. {"Really delete message of the day?","Na pewno usunąć wiadomość dnia?"}. {"Recipient is not in the conference room","Odbiorcy nie ma w pokoju"}. {"Register a Jabber account","Załóż konto Jabber"}. {"Registered Users:","Użytkownicy zarejestrowani:"}. {"Registered Users","Użytkownicy zarejestrowani"}. {"Register","Zarejestruj"}. {"Registration in mod_irc for ","Rejestracja w mod_irc dla "}. {"Remote copy","Kopia zdalna"}. {"Remove All Offline Messages","Usuń wszystkie wiadomości typu 'Offline'"}. {"Remove User","Usuń użytkownika"}. {"Remove","Usuń"}. {"Replaced by new connection","Połączenie zostało zastąpione"}. {"Resources","Zasoby"}. {"Restart Service","Restart usługi"}. {"Restart","Uruchom ponownie"}. {"Restore Backup from File at ","Odtwórz bazę danych z kopii zapasowej na "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Odtwórz kopię binarną podczas następnego uruchomienia ejabberd (wymaga mniej zasobów):"}. {"Restore binary backup immediately:","Natychmiast odtwórz kopię binarną:"}. {"Restore plain text backup immediately:","Natychmiast odtwórz kopię z postaci tekstowej:"}. {"Restore","Przywróć z kopii"}. {"Room Configuration","Konfiguracja pokoju"}. {"Room creation is denied by service policy","Zasady serwera zabraniają tworzyć nowe pokoje"}. {"Room description","Opis pokoju"}. {"Room Occupants","Lista uczestników"}. {"Room title","Tytuł pokoju"}. {"Roster groups allowed to subscribe","Grupy kontaktów uprawnione do subskrypcji"}. {"Roster","Lista kontaktów"}. {"Roster of ","Lista kontaktów "}. {"Roster size","Rozmiar listy kontaktów"}. {"RPC Call Error","Błąd żądania RPC"}. {"Running Nodes","Uruchomione węzły"}. {"~s access rule configuration","~s konfiguracja zasad dostępu"}. {"Saturday","Sobota"}. {"Script check","Sprawdź skrypt"}. {"Search Results for ","Wyniki wyszukiwania dla "}. {"Search users in ","Wyszukaj użytkowników w "}. {"Send announcement to all online users on all hosts","Wyślij powiadomienie do wszystkich zalogowanych użytkowników na wszystkich hostach"}. {"Send announcement to all online users","Wyślij powiadomienie do wszystkich zalogowanych użytkowników"}. {"Send announcement to all users on all hosts","Wyślij powiadomienie do wszystkich użytkowników na wszystkich hostach"}. {"Send announcement to all users","Wyślij powiadomienie do wszystkich użytkowników"}. {"September","Wrzesień"}. {"Server ~b","Serwer ~b"}. {"Server:","Serwer:"}. {"Set message of the day and send to online users","Wyślij wiadomość dnia do wszystkich zalogowanych użytkowników"}. {"Set message of the day on all hosts and send to online users","Ustaw wiadomość dnia dla wszystkich hostów i wyślij do zalogowanych uzytkowników"}. {"Shared Roster Groups","Wspólne grupy kontaktów"}. {"Show Integral Table","Pokaż tabelę całkowitą"}. {"Show Ordinary Table","Pokaż zwykłą tabelę"}. {"Shut Down Service","Wyłącz usługę"}. {"~s invites you to the room ~s","~s zaprasza Cię do pokoju ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Niektóre klienty Jabber mogą zapisywać Twoje hasło na komputerze. Używaj tej opcji tylko jeśli ufasz komputerowi na którym pracujesz."}. {"Specify the access model","Określ model dostępu"}. {"Specify the event message type","Określ typ wiadomości"}. {"Specify the publisher model","Określ model publikującego"}. {"~s's Offline Messages Queue","Kolejka wiadomości offline użytkownika ~s"}. {"Start Modules at ","Uruchom moduły na "}. {"Start Modules","Uruchom moduły"}. {"Start","Uruchom"}. {"Statistics of ~p","Statystyki ~p"}. {"Statistics","Statystyki"}. {"Stop Modules at ","Zatrzymaj moduły na "}. {"Stop Modules","Zatrzymaj moduły"}. {"Stopped Nodes","Zatrzymane węzły"}. {"Stop","Zatrzymaj"}. {"Storage Type","Typ bazy"}. {"Store binary backup:","Zachowaj kopię binarną:"}. {"Store plain text backup:","Zachowaj kopię w postaci tekstowej:"}. {"Subject","Temat"}. {"Submitted","Wprowadzone"}. {"Submit","Wyślij"}. {"Subscriber Address","Adres subskrybenta"}. {"Subscription","Subskrypcja"}. {"Sunday","Niedziela"}. {"That nickname is already in use by another occupant","Ta nazwa użytkownika jest używana przez kogoś innego"}. {"That nickname is registered by another person","Ta nazwa użytkownika jest już zarejestrowana przez inną osobę"}. {"The CAPTCHA is valid.","Captcha jest poprawna."}. {"The CAPTCHA verification has failed","Weryfikacja CAPTCHA nie powiodła się."}. {"The collections with which a node is affiliated","Grupy, do których należy węzeł"}. {"the password is","hasło to:"}. {"The password is too weak","Hasło nie jest wystarczająco trudne"}. {"The password of your Jabber account was successfully changed.","Hasło do Twojego konta zostało zmienione."}. {"There was an error changing the password: ","Podczas próby zmiany hasła wystąpił błąd:"}. {"There was an error creating the account: ","Wystąpił błąd podczas tworzenia konta:"}. {"There was an error deleting the account: ","Podczas usuwania konta wystąpił błąd:"}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Pole nie rozróżnia wielkości liter: słowo Hanna jest takie samo jak hAnna lub haNNa."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Niniejsza strona pozwala na założenie konta Jabber na tym serwerze. Twój JID (Jabber IDentyfikator) będzie miał postać: nazwa_użytkownika@serwer. Przeczytaj dokładnie instrukcję i wypełnij pola."}. {"This page allows to unregister a Jabber account in this Jabber server.","Ta strona pozwala usunąć konto Jabber z tego serwera."}. {"This participant is kicked from the room because he sent an error message","Ten uczestnik został wyrzucony z pokoju ponieważ wysłał komunikat błędu"}. {"This participant is kicked from the room because he sent an error message to another participant","Ten uczestnik został wyrzucony z pokoju ponieważ wysłał komunikat błędu do innego uczestnika"}. {"This participant is kicked from the room because he sent an error presence","Ten uczestnik został wyrzucony z pokoju ponieważ jego informacja o statusie zawierała błędy"}. {"This room is not anonymous","Ten pokój nie jest anonimowy"}. {"Thursday","Czwartek"}. {"Time","Czas"}. {"Time delay","Opóźnienie"}. {"To","Do"}. {"Too many CAPTCHA requests","Za dużo żądań CAPTCHA"}. {"To ~s","Do ~s"}. {"Traffic rate limit is exceeded","Limit transferu przekroczony"}. {"Transactions Aborted:","Transakcje anulowane:"}. {"Transactions Committed:","Transakcje zakończone:"}. {"Transactions Logged:","Transakcje zalogowane:"}. {"Transactions Restarted:","Transakcje uruchomione ponownie:"}. {"Tuesday","Wtorek"}. {"Unable to generate a CAPTCHA","Nie można wygenerować CAPTCHA"}. {"Unauthorized","Nie autoryzowano"}. {"Unregister a Jabber account","Usuń konto Jabber"}. {"Unregister","Wyrejestruj"}. {"Update","Aktualizuj"}. {"Update message of the day (don't send)","Aktualizuj wiadomość dnia (bez wysyłania)"}. {"Update message of the day on all hosts (don't send)","Aktualizuj wiadomość dnia na wszystkich hostach (bez wysyłania)"}. {"Update plan","Plan aktualizacji"}. {"Update script","Skrypt aktualizacji"}. {"Update ","Uaktualnij "}. {"Uptime:","Czas pracy:"}. {"Use of STARTTLS required","Wymagane jest użycie STARTTLS"}. {"User JID","Użytkownik "}. {"User Management","Zarządzanie użytkownikami"}. {"Username:","Nazwa użytkownika:"}. {"Users are not allowed to register accounts so quickly","Użytkowncy nie mogą tak szybko rejestrować nowych kont"}. {"Users Last Activity","Ostatnia aktywność użytkowników"}. {"Users","Użytkownicy"}. {"User ","Użytkownik "}. {"User","Użytkownik"}. {"Validate","Potwierdź"}. {"vCard User Search","Wyszukiwanie vCard użytkowników"}. {"Virtual Hosts","Wirtualne Hosty"}. {"Visitors are not allowed to change their nicknames in this room","Uczestnicy tego pokoju nie mogą zmieniać swoich nicków"}. {"Visitors are not allowed to send messages to all occupants","Odwiedzający nie mogą wysyłać wiadomości do wszystkich obecnych"}. {"Voice requests are disabled in this conference","Głosowe żądania są wyłączone w tym pokoju"}. {"Voice request","Żądanie głosowe"}. {"Wednesday","Środa"}. {"When to send the last published item","Kiedy wysłać ostatnio opublikowaną rzecz"}. {"Whether to allow subscriptions","Czy pozwolić na subskrypcje"}. {"You can later change your password using a Jabber client.","Możesz później zmienić swoje hasło za pomocą dowolnego klienta Jabber."}. {"You have been banned from this room","Zostałeś wykluczony z tego pokoju"}. {"You must fill in field \"Nickname\" in the form","Musisz wypełnić pole \"Nazwa użytkownika\" w formularzu"}. {"You need a client that supports x:data and CAPTCHA to register","Potrzebujesz klienta obsługującego x:data aby zarejestrować nick"}. {"You need a client that supports x:data to register the nickname","Potrzebujesz klienta obsługującego x:data aby zarejestrować nick"}. {"You need an x:data capable client to configure mod_irc settings","Potrzebujesz klienta obsługującego x:data aby skonfigurować mod_irc"}. {"You need an x:data capable client to configure room","Potrzebujesz klienta obsługującego x:data aby skonfigurować pokój"}. {"You need an x:data capable client to search","Potrzebujesz klienta obsługującego x:data aby wyszukiwać"}. {"Your active privacy list has denied the routing of this stanza.","Aktualna lista prywatności zabrania przesyłania tej stanzy"}. {"Your contact offline message queue is full. The message has been discarded.","Kolejka wiadomości offline adresata jest pełna. Wiadomość została odrzucona."}. {"Your Jabber account was successfully created.","Twoje konto zostało stworzone."}. {"Your Jabber account was successfully deleted.","Twoje konto zostało usunięte."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Twoje wiadomości do ~s są blokowane. Aby je odblokować, odwiedź ~s"}. ejabberd-2.1.11/src/msgs/es.po0000664000000000000000000015632512240230175012741 0ustar # translation of es.po to # Badlop , 2009. msgid "" msgstr "" "Project-Id-Version: es\n" "POT-Creation-Date: \n" "PO-Revision-Date: 2012-04-15 00:10+0100\n" "Last-Translator: Badlop \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Spanish (castellano)\n" "X-Generator: KBabel 1.11.4\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Es obligatorio usar STARTTLS" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "No se ha proporcionado recurso" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Reemplazado por una nueva conexión" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "Tu lista de privacidad activa ha denegado el encío de este paquete." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Teclea el texto que ves" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "Tus mensajes a ~s están siendo bloqueados. Para desbloquearlos, visita ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "Si no ves la imagen CAPTCHA aquí, visita la página web." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "Página web de CAPTCHA" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "El CAPTCHA es válido." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Comandos" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "¿Está seguro de quere borrar el mensaje del dia?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Asunto" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Cuerpo del mensaje" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "No se ha proporcionado cuerpo de mensaje para el anuncio" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Anuncios" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Enviar anuncio a todos los usuarios" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Enviar anuncio a todos los usuarios en todos los dominios" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Enviar anuncio a todos los usuarios conectados" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Enviar anuncio a todos los usuarios conectados en todos los dominios" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Poner mensaje del dia y enviar a todos los usuarios conectados" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Poner mensaje del día en todos los dominios y enviar a los usuarios " "conectados" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Actualizar mensaje del dia, pero no enviarlo" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Actualizar el mensaje del día en todos los dominos (pero no enviarlo)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Borrar mensaje del dia" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Borrar el mensaje del día en todos los dominios" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Configuración" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Base de datos" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Iniciar módulos" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Detener módulos" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Guardar copia de seguridad" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Restaurar" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Exportar a fichero de texto" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Importar fichero" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Importar directorio" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Reiniciar el servicio" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Detener el servicio" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Añadir usuario" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Borrar usuario" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Cerrar sesión de usuario" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Ver contraseña de usuario" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Cambiar contraseña de usuario" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Ver fecha de la última conexión de usuario" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Ver estadísticas de usuario" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Ver número de usuarios registrados" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Ver número de usuarios conectados" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Listas de Control de Acceso" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Reglas de Acceso" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Administración de usuarios" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Usuarios conectados" #: mod_configure.erl:501 msgid "All Users" msgstr "Todos los usuarios" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Conexiones S2S salientes" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Nodos funcionando" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Nodos detenidos" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Módulos" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Gestión de copia de seguridad" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importar usuarios de ficheros spool de jabberd-1.4" #: mod_configure.erl:699 msgid "To ~s" msgstr "A ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "De ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Configuración de tablas de la base de datos en " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Selecciona tipo de almacenamiento de las tablas" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Copia en disco solamente" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Copia en RAM y disco" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Copia en RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Copia remota" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Detener módulos en " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Selecciona módulos a detener" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Iniciar módulos en " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Introduce lista de {módulo, [opciones]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Lista de módulos a iniciar" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Guardar copia de seguridad en fichero en " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Introduce ruta al fichero de copia de seguridad" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Ruta al fichero" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Restaura copia de seguridad desde el fichero en " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Exporta copia de seguridad a fichero de texto en " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Introduce ruta al fichero de texto" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importa usuario desde fichero en " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Introduce ruta al fichero jabberd14 spool" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importar usuarios desde el directorio en " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Introduce la ruta al directorio de jabberd14 spools" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Ruta al directorio" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Retraso temporal" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Configuración de la Lista de Control de Acceso" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Listas de Control de Acceso" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Configuración de accesos" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Reglas de acceso" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Contraseña" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Verificación de la contraseña" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Número de usuarios registrados" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Número de usuarios conectados" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Nunca" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Conectado" #: mod_configure.erl:1701 msgid "Last login" msgstr "Última conexión" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Tamaño de la lista de contactos" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "Direcciones IP" #: mod_configure.erl:1724 msgid "Resources" msgstr "Recursos" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Administración de " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Acción en el usuario" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Editar propiedades" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Eliminar usuario" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Acceso denegado por la política del servicio" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "Transporte de IRC" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "Módulo de IRC para ejabberd" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "Necesitas un cliente con soporte de x:data para configurar las opciones de " "mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Registro en mod_irc para" #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Introduce el nombre de usuario, codificaciones de carácteres, puertos y " "contraseñas que quieras usar al conectar en los servidores de IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Nombre de usuario en IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Si quieres especificar distintos codificaciones de carácteres, contraseñas o " "puertos para cada servidor IRC rellena esta lista con valores en el formato " "'{\"servidor irc\", \"codificación\", \"puerto\", \"contrasela\"}'. Este " "servicio usa por defecto la codificación \"~s\", puerto ~p, sin contraseña." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Ejemplo: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Parámetros de conexiones" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Entrar en canal IRC" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "Canal IRC (no pongas el # del principio)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "Servidor IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Entrar en el canal de IRC aquí" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Entra en el canal de IRC en esta dirección Jabber: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "Opciones de IRC" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Introduce el nombre de usuario y codificaciones de carácteres que quieras " "usar al conectar en los servidores de IRC. Pulsa Siguiente para conseguir " "más campos en el formulario. Pulsa Completar para guardar las opciones." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "Nombre de usuario en IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Contraseña ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Puerto ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Codificación del servidor ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Servidor ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" "Solo los administradores del servicio tienen permiso para enviar mensajes de " "servicio" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Se te ha denegado crear la sala por política del servicio" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "La sala de conferencias no existe" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Salas de charla" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "" "Necesitas un cliente con soporte de x:data para poder registrar el apodo" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Registro del apodo en " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Introduce el apodo que quieras registrar" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Apodo" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "El apodo ya está registrado por otra persona" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Debes rellenar el campo \"Apodo\" en el formulario" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "Módulo de MUC para ejabberd" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Configuración de la sala modificada" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "entra en la sala" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "sale de la sala" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "ha sido bloqueado" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "ha sido expulsado" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "ha sido expulsado por un cambio de su afiliación" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "ha sido expulsado porque la sala es ahora solo para miembros" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "ha sido expulsado porque el sistema se va a detener" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "se cambia el nombre a" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " ha puesto el asunto: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Se ha creado la sala" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Se ha destruido la sala" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Se ha iniciado la sala" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Se ha detenido la sala" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "lunes" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "martes" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "miércoles" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "jueves" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "viernes" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "sábado" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "domingo" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "enero" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "febrero" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "marzo" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "abril" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "mayo" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "junio" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "julio" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "agosto" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "septiembre" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "octubre" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "noviembre" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "diciembre" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Configuración de la sala" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Ocupantes de la sala" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Se ha exedido el límite de tráfico" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Este participante ha sido expulsado de la sala porque envió un mensaje de " "error" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Impedir el envio de mensajes privados a la sala" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "Por favor, espera un poco antes de enviar otra petición de voz" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "Las peticiones de voz están desactivadas en esta sala" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "Fallo al extraer el Jabber ID de tu aprobación de petición de voz" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Solo los moderadores pueden aprobar peticiones de voz" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Tipo de mensaje incorrecto" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Este participante ha sido expulsado de la sala porque envió un mensaje de " "error a otro participante" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "No está permitido enviar mensajes privados del tipo \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "El receptor no está en la sala de conferencia" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "No está permitido enviar mensajes privados" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Solo los ocupantes pueden enviar mensajes a la sala" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Solo los ocupantes pueden enviar solicitudes a la sala" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "En esta sala no se permiten solicitudes a los miembros de la sala" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Solo los moderadores y participantes pueden cambiar el asunto de esta sala" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Solo los moderadores pueden cambiar el asunto de esta sala" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Los visitantes no pueden enviar mensajes a todos los ocupantes" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Este participante ha sido expulsado de la sala porque envió una presencia de " "error" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Los visitantes no tienen permitido cambiar sus apodos en esta sala" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Ese apodo ya está siendo usado por otro ocupante" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Has sido bloqueado en esta sala" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Necesitas ser miembro de esta sala para poder entrar" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Sala no anónima" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Se necesita contraseña para entrar en esta sala" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Demasiadas peticiones de CAPTCHA" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "No se pudo generar un CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Contraseña incorrecta" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Se necesita privilegios de administrador" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Se necesita privilegios de moderador" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "El Jabber ID ~s no es válido" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "El apodo ~s no existe en la sala" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Afiliación no válida: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Rol no válido: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Se requieren privilegios de propietario de la sala" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Configuración para la sala ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Título de la sala" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Descripción de la sala" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Sala permanente" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Sala públicamente visible" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "La lista de participantes es pública" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Proteger la sala con contraseña" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Número máximo de ocupantes" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Sin límite" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Los Jabber ID reales pueden verlos" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "solo moderadores" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "cualquiera" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Sala sólo para miembros" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Sala moderada" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Los usuarios son participantes por defecto" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Permitir a los usuarios cambiar el asunto" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Permitir a los usuarios enviar mensajes privados" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "Permitir a los visitantes enviar mensajes privados a" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "nadie" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Permitir a los usuarios consultar a otros usuarios" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Permitir a los usuarios enviar invitaciones" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "" "Permitir a los visitantes enviar texto de estado en las actualizaciones de " "presencia" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Permitir a los visitantes cambiarse el apodo" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "Permitir a los visitantes enviar peticiones de voz" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "Intervalo mínimo entre peticiones de voz (en segundos)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Proteger la sala con CAPTCHA" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Excluir Jabber IDs de las pruebas de CAPTCHA" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Guardar históricos" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Necesitas un cliente con soporte de x:data para configurar la sala" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Número de ocupantes" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privado" #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Petición de voz" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Aprueba o rechaza la petición de voz." #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "Jabber ID del usuario" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "¿Conceder voz a esta persona?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s te invita a la sala ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "la contraseña es" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "Tu cola de mensajes diferidos de contactos está llena. El mensaje se ha " "descartado." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "Cola de mensajes diferidos de ~s" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Enviado" #: mod_offline.erl:571 msgid "Time" msgstr "Fecha" #: mod_offline.erl:572 msgid "From" msgstr "De" #: mod_offline.erl:573 msgid "To" msgstr "Para" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Paquete" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Eliminar los seleccionados" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Mensajes diferidos:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Borrar todos los mensajes diferidos" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "Módulo SOCKS5 Bytestreams para ejabberd" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Servicio de Publicar-Subscribir" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "Módulo de Publicar-Subscribir de ejabberd" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Petición de subscriptor de PubSub" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Decidir si aprobar la subscripción de esta entidad." #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "Nodo ID" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Dirección del subscriptor" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "¿Deseas permitir a este Jabber ID que se subscriba a este nodo PubSub?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Enviar contenidos junto con las notificaciones de eventos" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Entregar notificaciones de eventos" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Notificar subscriptores cuando cambia la configuración del nodo" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Notificar subscriptores cuando el nodo se borra" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Notificar subscriptores cuando los elementos se borran del nodo" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Persistir elementos al almacenar" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Un nombre sencillo para el nodo" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Máximo # de elementos que persisten" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Permitir subscripciones" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Especifica el modelo de acceso" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Grupos de contactos que pueden suscribirse" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Especificar el modelo del publicante" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "Borra todos los elementos cuando el publicador relevante se desconecta" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Especifica el tipo del mensaje de evento" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Máximo tamaño del contenido en bytes" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Cuando enviar el último elemento publicado" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Solo enviar notificaciones a los usuarios disponibles" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Las colecciones a las que un nodo está afiliado" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "La verificación de CAPTCHA ha fallado" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "Necesitas un cliente con soporte de x:data y CAPTCHA para registrarte" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "" "Escoge un nombre de usuario y contraseña para registrarte en este servidor" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Usuario" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "La contraseña es demasiado débil" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Los usuarios no tienen permitido crear cuentas con tanta rapidez" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Ninguno" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Subscripción" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Pendiente" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Grupos" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Validar" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Borrar" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Lista de contactos de " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Mal formato" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Añadir Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Lista de contactos" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Grupos Compartidos" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Añadir nuevo" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Nombre:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Descripción:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Miembros:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Mostrar grupos:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Grupo " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Enviar" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Servidor Jabber en Erlang" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Cumpleaños" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Ciudad" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "País" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "correo" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Apellido" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Rellena el formulario para buscar usuarios Jabber. Añade * al final de un " "campo para buscar subcadenas." #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Nombre completo" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Segundo nombre" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Nombre" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Nombre de la organización" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Unidad de la organización" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Buscar usuarios en " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Necesitas un cliente con soporte de x:data para poder buscar" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Buscar vCard de usuario" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "Módulo vCard para ejabberd" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Buscar resultados por " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Rellena campos para buscar usuarios Jabber que concuerden" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "No autorizado" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd Web Admin" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Administración" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Crudo" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Configuración de las Regla de Acceso ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Dominios Virtuales" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Usuarios" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Última actividad de los usuarios" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Periodo: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Último mes" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Último año" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Toda la actividad" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Mostrar Tabla Ordinaria" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Mostrar Tabla Integral" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Estadísticas" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "No encontrado" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Nodo no encontrado" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Dominio" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Usuarios registrados" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Mensajes diferidos" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Última actividad" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Usuarios registrados:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Usuarios conectados:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Conexiones S2S salientes:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Servidores S2S salientes:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Cambiar contraseña" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Usuario " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Recursos conectados:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Contraseña:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Sin datos" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Nodos" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Nodo " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Puertos de escucha" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Actualizar" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Reiniciar" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Detener" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Error en la llamada RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Tablas de la base de datos en " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Tipo de almacenamiento" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Elementos" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Memoria" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Error" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Copia de seguridad de " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Ten en cuenta que estas opciones solo harán copia de seguridad de la base de " "datos Mnesia embebida. Si estás usando ODBC tendrás que hacer también copia " "de seguridad de tu base de datos SQL." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Guardar copia de seguridad binaria:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "Aceptar" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Restaurar inmediatamente copia de seguridad binaria:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Restaurar copia de seguridad binaria en el siguiente reinicio de ejabberd " "(requiere menos memoria que si instantánea):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Guardar copia de seguridad en texto plano:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Restaurar copias de seguridad de texto plano inmediatamente:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Importar usuarios desde un fichero PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Exportar datos de todos los usuarios del servidor a ficheros PIEFXIS " "(XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" "Exportar datos de los usuarios de un dominio a ficheros PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importar usuario de fichero spool de jabberd14:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importar usuarios del directorio spool de jabberd14:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Puertos de escucha en " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Módulos en " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Estadísticas de ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Tiempo desde el inicio:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Tiempo consumido de CPU:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transacciones finalizadas:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transacciones abortadas:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transacciones reiniciadas:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transacciones registradas:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Actualizar " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Plan de actualización" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Módulos modificados" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Script de actualización" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Script de actualización a bajo nivel" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Comprobación de script" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Puerto" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protocolo" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Módulo" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Opciones" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Eliminar" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Iniciar" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Tu cuenta Jabber se ha creado correctamente." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Hubo uno error al crear la cuenta:" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Tu cuenta Jabber se ha borrado correctamente." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Hubo un error borrando la cuenta." #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "La contraseña de tu cuenta Jabber se ha cambiado correctamente." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Hubo un error cambiando la contraseña." #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Registro de Cuenta Jabber" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Registrar una cuenta Jabber" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Borrar una cuenta Jabber" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Esta página te permite crear una cuenta Jabber este servidor Jabber. Tu JID " "(Jabber IDentificador) será de la forma: nombredeusuario@servidor. Por favor " "lee detenidamente las instrucciones para rellenar correctamente los campos." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Nombre de usuario:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "No importa si usas mayúsculas: macbeth es lo mismo que MacBeth y Macbeth." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Caracteres no permitidos:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Servidor:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "No le digas tu contraseña a nadie, ni siquiera a los administradores del " "servidor Jabber." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "Puedes cambiar tu contraseña después, usando un cliente Jabber." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Algunos clientes Jabber pueden recordar tu contraseña en la máquina. Usa esa " "opción solo si confías en que la máquina que usas es segura." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Memoriza tu contraseña, o apúntala en un papel en un lugar seguro. En Jabber " "no hay un método automatizado para recuperar la contraseña si la olvidas." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Verificación de la contraseña:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Registrar" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Contraseña antigua:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Nueva contraseña:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" "Esta página te permite borrar tu cuenta Jabber en este servidor Jabber." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Borrar" ejabberd-2.1.11/src/msgs/el.po0000664000000000000000000020736412240230175012732 0ustar msgid "" msgstr "" "Project-Id-Version: el\n" "POT-Creation-Date: \n" "PO-Revision-Date: 2012-04-18 12:50-0000\n" "Last-Translator: James Iakovos Mandelis \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Greek (ελληνικά)\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Απαιτείται χρήση STARTTLS " #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Δεν προμηθεύτικε πόρος" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Αντικαταστάθικε από νέα σύνδεση" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" "Ο ενεργός κατάλογος απορρήτου, έχει αρνηθεί τη δρομολόγηση αυτής της στροφής " "(stanza)." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Πληκτρολογήστε το κείμενο που βλέπετε" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "Τα μηνύματά σας πρως ~s είναι αποκλεισμένα. Για αποδεσμεύση, επισκεφθείτε ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "Εάν δεν βλέπετε την εικόνα CAPTCHA εδώ, επισκεφθείτε την ιστοσελίδα." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "Ιστοσελίδα CAPTCHA " #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "Το CAPTCHA είναι έγκυρο." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Εντολές" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Πινγκ" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Πονγκ" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Πραγματικά να διαγράψετε το μήνυμα της ημέρας;" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Θέμα" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Περιεχόμενο μηνυμάτως" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Δεν προμηθεύτικε περιεχόμενο ανακοινώσης" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Ανακοινώσεις" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Αποστολή ανακοίνωσης σε όλους τους χρήστες" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "" "Αποστολή ανακοίνωσης σε όλους τους χρήστες σε όλους τους κεντρικούς " "υπολογιστές" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Αποστολή ανακοίνωσης σε όλους τους συνδεδεμένους χρήστες" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "" "Αποστολή ανακοίνωσης σε όλους τους συνδεδεμένους χρήστες σε όλους τους " "κεντρικούς υπολογιστές" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Ορίστε μήνυμα ημέρας και αποστολή στους συνδεδεμένους χρήστες" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Ορίστε μήνυμα ημέρας και άμεση αποστολή στους συνδεδεμένους χρήστες σε όλους " "τους κεντρικούς υπολογιστές" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Ενημέρωση μηνύματως ημέρας (χωρίς άμεση αποστολή)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "" "Ενημέρωση μηνύματως ημέρας σε όλους τους κεντρικούς υπολογιστές (χωρίς άμεση " "αποστολή)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Διαγράψτε το μήνυμα της ημέρας" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Διαγράψτε το μήνυμα της ημέρας σε όλους τους κεντρικούς υπολογιστές" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Διαμόρφωση" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Βάση δεδομένων" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Εκκίνηση Modules" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "ΠαύσηModules" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Αποθήκευση Αντιγράφου Ασφαλείας" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Επαναφορά Αντιγράφου Ασφαλείας" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Αποθήκευση σε αρχείο κειμένου" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Εισαγωγή αρχείων" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Εισαγωγή κατάλογου αρχείων" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Επανεκκίνηση Υπηρεσίας" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Κλείσιμο Υπηρεσίας" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Προσθήκη Χρήστη" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Διαγραφή Χρήστη" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Τερματισμός Συνεδρίας Χρήστη" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Έκθεση Κωδικού Πρόσβασης Χρήστη" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Αλλαγή Κωδικού Πρόσβασης Χρήστη" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Έκθεση Τελευταίας Ώρας Σύνδεσης Χρήστη" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Έκθεση Στατιστικών Χρήστη" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Έκθεση αριθμού εγγεγραμμένων χρηστών" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Έκθεση αριθμού συνδεδεμένων χρηστών" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Λίστες Ελέγχου Πρόσβασης" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Κανόνες Πρόσβασης" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Διαχείριση χρηστών" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Συνδεμένοι χρήστες" #: mod_configure.erl:501 msgid "All Users" msgstr "Όλοι οι χρήστες" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Εξερχόμενες S2S Συνδέσεις" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Ενεργοί Κόμβοι" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Σταματημένοι Κόμβοι" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Modules" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Διαχείριση Αντιγράφου Ασφαλείας" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Εισαγωγή Χρηστών από αρχεία σειράς jabberd14" #: mod_configure.erl:699 msgid "To ~s" msgstr "Πρώς ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Από ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Διαμόρφωση Πίνακων βάσης δεδομένων στο " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Επιλέξτε τύπο αποθήκευσης των πινάκων" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Αντίγραφο μόνο σε δίσκο" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Αντίγραφο μόνο σε RAM καί δίσκο" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Αντίγραφο σε RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Απομεμακρυσμένο αντίγραφο" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Παύση Modules στο " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Επιλέξτε modules για να σταματήσουν" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Εκκίνηση Modules στο " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Εισάγετε κατάλογο των (Module, [Επιλογές])" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Λίστα των Module για Εκκίνηση" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Αποθήκευση Αντιγράφου Ασφαλείας σε Αρχείο στο " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Εισάγετε τοποθεσία αρχείου αντιγράφου ασφαλείας" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Τοποθεσία Αρχείου" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Επαναφορά Αντιγράφου Ασφαλείας από αρχείο στο " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Αποθήκευση Αντιγράφου Ασφαλείας σε αρχείο κειμένου στο " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Εισάγετε Τοποθεσία Αρχείου Κειμένου" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Εισαγωγή χρηστών από αρχείο στο " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Εισάγετε τοποθεσία αρχείου σειράς jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Εισαγωγή χρηστών από κατάλογο αρχείων στο " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Εισάγετε κατάλογο αρχείων σειράς jabberd14" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Τοποθεσία κατάλογου αρχείων" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Χρόνος καθυστέρησης" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Διαχείριση στις Λίστες Ελέγχου Πρόσβασης" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Λίστες Ελέγχου Πρόσβασης" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Διαμόρφωση Πρόσβασης" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Κανόνες Πρόσβασης" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Ταυτότητα Jabber" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Κωδικός Πρόσβασης" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Επαλήθευση κωδικού πρόσβασης" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Αριθμός εγγεγραμμένων χρηστών" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Αριθμός συνδεδεμένων χρηστών" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Ποτέ" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Συνδεδεμένο" #: mod_configure.erl:1701 msgid "Last login" msgstr "Τελευταία σύνδεση" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Μέγεθος Καταλόγου Επαφών" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "Διευθύνσεις IP" #: mod_configure.erl:1724 msgid "Resources" msgstr "Πόροι" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Διαχείριση του" #: mod_configure.erl:1853 msgid "Action on user" msgstr "Eνέργεια για το χρήστη" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Επεξεργασία ιδιοτήτων" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Αφαίρεση χρήστη" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Άρνηση πρόσβασης, λόγω τακτικής παροχής υπηρεσιών" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC Διαβιβάσεις" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC module" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "Χρειάζεστε ένα x:data ικανό πελάτη για να ρυθμίσετε το mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Εγγραφή στο mod_irc για " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Εισάγετε το όνομα χρήστη, κωδικοποιήσεις, τις θύρες και τους κωδικούς " "πρόσβασης που θέλετε να χρησιμοποιήσετε για σύνδεση με IRC διακομιστή" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "IRC Όνομα χρήστη" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Εάν θέλετε να καθορίσετε διαφορετικές θύρες, κωδικούς πρόσβασης, " "κωδικοποιήσεις για IRC διακομιστές, εισάγετε πληροφορίες στη μορφή '{\"irc " "διακομιστής\", \"κωδικοποιήσεις\", θύρα, \"κωδικός πρόσβασης\"}'. " "Προεπιλεγμενα αυτή η υπηρεσία χρησιμοποιεί \"~s\" κωδικοποιήση, θύρα ~p, " "κενό κωδικό πρόσβασης." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Παράδειγμα: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta." "fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Παράμετροι Συνδέσης" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Είσοδος στο IRC κανάλι" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "IRC κανάλι (μην τεθεί το πρώτο #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "Διακομιστής IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Είσοδος στο κανάλι IRC εδώ." #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Είσοδος στο κανάλι IRC αυτής της Jabber Ταυτότητας: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "IRC Ρυθμίσεις" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Πληκτρολογήστε το όνομα χρήστη και κωδικοποιήσεις που θέλετε να " "χρησιμοποιήσετε για τη σύνδεση με διακομιστές IRC. Πατήστε 'Next' για να " "πάρετε περισσότερα πεδία να συμπληρώσετε. Πατήστε 'Complete' για να " "αποθηκεύσετε ρυθμίσεις." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "IRC όνομα χρήστη" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Κωδικός πρόσβασης ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Θύρα ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Κωδικοποίηση για διακομιστή ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Διακομιστής ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" "Μόνο οι διαχειριστές των υπηρεσιών επιτρέπεται να στείλουν υπηρεσιακά " "μηνύματα" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Άρνηση δημιουργίας αίθουσας , λόγω τακτικής παροχής υπηρεσιών" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Αίθουσα σύνεδριασης δεν υπάρχει" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Αίθουσες σύνεδριασης" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "Χρειάζεστε ένα x:data ικανό πελάτη για εγγραφή με ψευδώνυμο" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Εγγραφή με Ψευδώνυμο στο " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Πληκτρολογήστε το ψευδώνυμο που θέλετε να εγγραφείτε" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Ψευδώνυμο" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Αυτό το ψευδώνυμο είναι καταχωρημένο από άλλο πρόσωπο" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Θα πρέπει να συμπληρώσετε το πεδίο \"Ψευδώνυμο\" στη φόρμα" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC module" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Διαμόρφωση Αίθουσaς σύνεδριασης τροποποιηθηκε" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "συνδέετε στην αίθουσα" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "εγκαταλείπει την αίθουσα" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "έχει απαγορευθεί" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "αποβλήθηκε " #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "Έχει αποβληθεί λόγω αλλαγής υπαγωγής" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "αποβλήθηκε επειδή η αίθουσα αλλάξε γιά μέλη μόνο" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "αποβλήθηκε λόγω τερματισμού συστήματος" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "είναι τώρα γνωστή ως" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " έχει θέσει το θέμα σε: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Η αίθουσα σύνεδριασης δημιουργήθηκε" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Η αίθουσα σύνεδριασης διαγράφηκε" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Η αίθουσα σύνεδριασης έχει ξεκινήσει" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Η αίθουσα σύνεδριασης έχει σταματήσει" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Δευτέρα" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Τρίτη" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Τετάρτη" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Πέμπτη" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Παρασκευή" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Σάββατο" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Κυριακή" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Ιανουάριος" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Φεβρουάριος" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Μάρτιος" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "Απρίλιος" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Μάιος" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Ιούνιος" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Ιούλιος" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Αύγουστος" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "Σεπτέμβριος" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Οκτώβριος" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "Νοέμβριος" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "Δεκέμβριος" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Διαμόρφωση Αίθουσας σύνεδριασης" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Συμετεχόντες Αίθουσας σύνεδριασης" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Υπέρφορτωση" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Αυτός ο συμμετέχων αποβλήθηκε από την αίθουσα, επειδή έστειλε ένα μήνυμα " "σφάλματος" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Δεν επιτρέπεται να στείλει προσωπικά μηνύματα για τη διάσκεψη" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "Παρακαλώ, περιμένετε για λίγο πριν την αποστολή νέου αιτήματος φωνής" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "Τα αιτήματα φωνής είναι απενεργοποιημένα, σε αυτό το συνέδριο" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "Απέτυχε η εξαγωγή JID από την έγκριση του αιτήματος φωνής σας" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Μόνο οι συντονιστές μπορούν να εγκρίνουν τις αιτήσεις φωνής" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Ακατάλληλο είδος μηνύματος" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Αυτός ο συμμετέχων αποβλήθηκε από την αίθουσα, επειδή έστειλε ένα μήνυμα " "σφάλματος σε άλλον συμμετέχων" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "Δεν επιτρέπεται να στείλει προσωπικά μηνύματα του τύπου \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Παραλήπτης δεν είναι στην αίθουσα συνεδριάσεων" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Δεν επιτρέπεται η αποστολή προσωπικών μηνυμάτων" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Μόνο οι συμμετέχωντες μπορούν να στέλνουν μηνύματα στο συνέδριο" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Μόνο οι συμετεχόντες μπορούν να στείλουν ερωτήματα στη διάσκεψη" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "" "Ερωτήματα πρώς τα μέλη της διασκέψεως δεν επιτρέπονται σε αυτήν την αίθουσα" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Μόνο οι συντονιστές και οι συμμετέχοντες μπορούν να αλλάξουν το θέμα αυτής " "της αίθουσας" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Μόνο οι συντονιστές μπορούν να αλλάξουν το θέμα αυτής της αίθουσας" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "" "Οι επισκέπτες δεν επιτρέπεται να στείλουν μηνύματα σε όλους τους " "συμμετέχωντες" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Αυτός ο συμμετέχων αποβλήθηκε από την αίθουσα, επειδή έστειλε σφάλμα " "παρουσίας " #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "" "Οι επισκέπτες δεν επιτρέπεται να αλλάξουν τα ψευδώνυμα τους σε αυτή την " "αίθουσα" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Αυτό το ψευδώνυμο είναι ήδη σε χρήση από άλλον συμμετέχων" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Σας έχει απαγορευθεί η είσοδος σε αυτή την αίθουσα" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Απαιτείται αίτηση συμετοχής για είσοδο σε αυτή την αίθουσα" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Η αίθουσα αυτή δεν είναι ανώνυμη" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Απαιτείται κωδικός πρόσβασης για είσοδο σε αυτή την αίθουσα" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Πάρα πολλά αιτήματα CAPTCHA" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Αδήνατο να δημιουργηθεί CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Εσφαλμένος κωδικός πρόσβασης" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Aπαιτούνται προνόμια διαχειριστή" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Aπαιτούνται προνόμια συντονιστή" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Η Jabber Ταυτότητα ~s είναι άκυρη" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Ψευδώνυμο ~s δεν υπάρχει σε αυτή την αίθουσα" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Άκυρη υπαγωγή: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Άκυρος ρόλο: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Aπαιτούνται προνόμια ιδιοκτήτη" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Διαμόρφωση Αίθουσας σύνεδριασης ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Τίτλος Αίθουσας " #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Περιγραφή Αίθουσας" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Κάντε αίθουσα μόνιμη" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Κάντε την δημόσια αναζήτηση δυνατή για αυτή την αίθουσα" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Κάντε κοινό τον κατάλογο συμμετεχόντων" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Κάντε την αίθουσα προστατεύομενη με κωδικό πρόσβασης" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Μέγιστος αριθμός συμετεχόντων" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Χωρίς όριο" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Παρούσιαση πραγματικών ταυτοτήτων Jabber σε" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "συντονιστές μόνο" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "οποιοσδήποτε" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Κάντε την αίθουσα μόνο για μέλη" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Κάντε την αίθουσα εποπτεύονομενη" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Προεπιλογη χρήστων ως συμμετέχοντες" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Επιτρέψετε στους χρήστες να αλλάζουν το θέμα" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Επιτρέψετε στους χρήστες να αποστέλλουν ιδιωτικά μηνύματα" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "Επιτρέψετε στους χρήστες να αποστέλλουν ιδιωτικά μηνύματα σε" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "κανείς" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Επιτρέπστε στους χρήστες να ερωτούν άλλους χρήστες" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Επιτρέψετε στους χρήστες να αποστέλλουν προσκλήσεις" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "" "Επιτρέψτε στους επισκέπτες να αποστέλλουν κατάσταση στις ενημερώσεις " "παρουσίας" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Επιτρέψετε στους επισκέπτες να αλλάζου ψευδώνυμο" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "Επιτρέψτε στους επισκέπτες να στέλνουν αιτήματα φωνής" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "Ελάχιστο χρονικό διάστημα μεταξύ αιτημάτων φωνής (σε δευτερόλεπτα)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Κάντε την αίθουσα CAPTCHA προστατεύονομενη" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Εξαίρεση από τις ταυτότητες Jabber, ή CAPTCHA πρόκληση" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Ενεργοποίηση καταγραφής" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Χρειάζεστε ένα x:data ικανό πελάτη για να ρυθμίσετε την αίθουσα " #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Αριθμός συμετεχόντων" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "ιδιωτικό," #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Αίτημα φωνής" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Είτε εγκρίνετε ή απορρίψτε το αίτημα φωνής." #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "JID Χρήστη" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "Παραχώρηση φωνής σε αυτό το άτομο;" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s σας προσκαλεί στην αίθουσα ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "ο κωδικός πρόσβασης είναι" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "Η μνήμη χωρίς σύνδεση μήνυματών είναι πλήρης. Το μήνυμα έχει απορριφθεί." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "Η Σειρά Χωρίς Σύνδεση Μηνύματων τού ~s" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Υποβλήθηκε" #: mod_offline.erl:571 msgid "Time" msgstr "Χρόνος" #: mod_offline.erl:572 msgid "From" msgstr "Από" #: mod_offline.erl:573 msgid "To" msgstr "Πρώς" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Πακέτο" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Διαγραφή επιλεγμένων" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Χωρίς Σύνδεση Μηνύματα:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Αφαίρεση Όλων των Χωρίς Σύνδεση Μηνύματων" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestreams module" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Δημοσίευση-Εγγραφή" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "ejabberd module Δημοσίευσης-Εγγραφής" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Αίτηση συνδρομητή Δημοσίευσης-Εγγραφής" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Επιλέξτε αν θα εγκρίθεί η εγγραφή αυτής της οντότητας." #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "Ταυτότητα Κόμβου" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Διεύθυνση Συνδρομητή" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "" "Επιτρέπετε σε αυτή την Jabber Ταυτότητα να εγγραφεί σε αυτό τον κόμβο " "Δημοσίευσης-Εγγραφής;" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Κοινοποιήσεις με την παράδοση φορτίων" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Κοινοποιήσεις παράδοσης" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Ειδοποιηση στους συνδρομητές όταν αλλάζει η διαμόρφωση κόμβου" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Ειδοποιηση στους συνδρομητές όταν ο κόμβος διαγράφεται" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Ειδοποιηση στους συνδρομητές όταν αφαίρούντε στοιχεία από τον κόμβο" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Μονιμη αποθήκευση στοιχείων" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Ένα φιλικό όνομα για τον κόμβο" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Μέγιστος αριθμός μόνιμων στοιχείων" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Εάν επιτρέποντε συνδρομές" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Καθορίστε το μοντέλο πρόσβασης" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Ομάδες Καταλόγου Επαφών μπορούν να εγγραφούν" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Καθορίστε το μοντέλο εκδότη" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "Διαγραφή όλων των στοιχείων όταν ο σχετικός εκδότης αποσυνδέεται" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Καθορίστε τον τύπο μηνύματος συμβάντος" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Μέγιστο μέγεθος φορτίου σε bytes" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Πότε να αποσταλθεί το τελευταίο στοιχείο που δημοσιεύθηκε" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Παράδωση κοινοποιήσεων μόνο σε διαθέσιμους χρήστες" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Οι συλλογές με την οποία είναι ένας κόμβος συνδέεται" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "Η επαλήθευση της εικόνας CAPTCHA απέτυχε" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "Χρειάζεστε ένα x:data και CAPTCHA ικανό πελάτη για εγγραφή" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "" "Επιλέξτε ένα όνομα χρήστη και κωδικό πρόσβασης για να εγγραφείτε σε αυτό τον " "διακομιστή" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Χρήστης" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "Ο κωδικός πρόσβασης είναι πολύ ασθενές" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Οι χρήστες δεν επιτρέπεται να εγγραφούν λογαριασμούς τόσο γρήγορα" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Κανένα" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Συνδρομή" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Εκκρεμεί" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Ομάδες" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Επαληθεύστε" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Αφαίρεστε" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Καταλόγος Επαφών τού" #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Ακατάλληλη μορφή" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Προσθήκη Jabber Ταυτότητας" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Καταλόγος Επαφών" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Κοινές Ομάδες Καταλόγων Επαφών" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Προσθήκη νέου" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Όνομα:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Περιγραφή:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Μέλη:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Εμφανίσμενες Ομάδες:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Ομάδα" #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Υποβοβολή" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Διακομιστής" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Γενέθλια" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Πόλη" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Χώρα" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Email" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Επώνυμο" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Συμπληρώστε τη φόρμα για να αναζητήσετε οποιαδήποτε Jabber χρήστη που " "ταιριάζει (Προσθέστε * στο τέλος τού πεδίου για να ταιριάξει σε μεγαλύτερες " "γραμματοσηρές)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Ονοματεπώνυμο" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Πατρώνυμο" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Όνομα" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Όνομα Οργανισμού" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Μονάδα Οργανισμού" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Αναζήτηση χρηστών στο" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Χρειάζεστε ένα x:data ικανό πελάτη για αναζήτηση" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "vCard Αναζήτηση χρηστών" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard module" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Αποτελέσματα αναζήτησης για " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "" "Συμπληρώστε τα πεδία για να αναζητήσετε οποιαδήποτε ταιριάζοντα Jabber χρήστη" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Χορίς Εξουσιοδότηση" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd Web Admin" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Διαχείριση" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Ακατέργαστο" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "~s διαμόρφωση κανόνα πρόσβασης" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "εικονικοί κεντρικοί υπολογιστές" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Χρήστες" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Τελευταία Δραστηριότητα Χρήστη" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Περίοδος: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Περασμένο μήνα" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Πέρυσι" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Όλες οι δραστηριότητες" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Δείτε Κοινό Πίνακα" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Δείτε Ολοκληρωτικό Πίνακα" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Στατιστικές" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Δεν Βρέθηκε" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Κόμβος δεν βρέθηκε" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Κεντρικός Υπολογιστής" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Εγγεγραμμένοι Χρήστες" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Χωρίς Σύνδεση Μηνύματα" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Τελευταία Δραστηριότητα" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Εγγεγραμμένοι Χρήστες:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Online Χρήστες:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Εξερχόμενες S2S Συνδέσεις:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Εξερχόμενοι S2S διακομιστές:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Αλλαγή κωδικού" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Χρήστης" #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Συνδεδεμένοι Πόροι:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Κωδικός πρόσβασης:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Κανένα στοιχείο" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Κόμβοι" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Κόμβος" #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Παρακολουθούμενες Θύρες" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Ενημέρωση" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Επανεκκίνηση" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Σταμάτημα" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Σφάλμα RPC Κλήσης" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Πίνακες βάσης δεδομένων στο " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Τύπος Αποθήκευσης" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Στοιχεία" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Μνήμη" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Σφάλμα" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Αντιγράφο Ασφαλείας του " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Παρακαλώ σημειώστε ότι οι επιλογές αυτές θα αποθήκευσουν Αντιγράφο Ασφαλείας " "μόνο της ενσωματωμένης βάσης δεδομένων Mnesia. Εάν χρησιμοποιείτε το module " "ODBC, θα πρέπει επίσης να κάνετε χωριστά Αντιγράφο Ασφαλείας της SQL βάση " "δεδομένων σας ." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Αποθηκεύση δυαδικού αντιγράφου ασφαλείας:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "Όλλα Καλά" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Επαναφορά δυαδικού αντιγράφου ασφαλείας αμέσως:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Επαναφορά δυαδικού αντιγράφου ασφαλείας μετά την επόμενη επανεκκίνηση του " "ejabberd (απαιτεί λιγότερη μνήμη):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Αποθηκεύση αντιγράφου ασφαλείας σε αρχείο κειμένου:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Επαναφορά αντιγράφου ασφαλείας από αρχείο κειμένου αμέσως:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Εισαγωγή δεδομένων χρηστών από ένα αρχείο PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Εξαγωγή δεδομένων όλων των χρηστών του διακομιστή σε PIEFXIS αρχεία " "(XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" "Εξαγωγή δεδομένων των χρηστών κεντρικού υπολογιστή σε PIEFXIS αρχεία " "(XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Εισαγωγή δεδομένων χρήστη από το αρχείο σειράς jabberd14:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Εισαγωγή δεδομένων χρηστών από κατάλογο αρχείων σειράς jabberd14:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Παρακολουθούμενες Θύρες στο " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Modules στο " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Στατιστικές του ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Uptime:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Ώρα CPU:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Παραδοθείς συναλλαγές:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Αποτυχημένες συναλλαγές:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Επανειλημμένες συναλλαγές:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Καταγραμμένες συναλλαγές:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Ενημέρωση" #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Σχέδιο ενημέρωσης" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Τροποποιημένα modules" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Προγράμα ενημέρωσης" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Προγράμα ενημέρωσης χαμηλού επίπεδου " #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Script ελέγχου" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Θύρα" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Πρωτόκολλο" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Module" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Επιλογές" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Διαγραφή" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Εκκίνηση" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Ο Jabber λογαριασμός σας δημιουργήθηκε με επιτυχία." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Υπήρξε ένα σφάλμα κατά τη δημιουργία του λογαριασμού:" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Ο Jabber λογαριασμός σας διαγράφηκε με επιτυχία." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Υπήρξε ένα σφάλμα κατά τη διαγραφή του λογαριασμού:" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Ο κωδικός πρόσβασης του Jabber λογαριασμού σας έχει αλλάξει επιτυχώς." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Υπήρξε ένα σφάλμα κατά την αλλαγή του κωδικού πρόσβασης:" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Εγγραφή λογαριασμού Jabber" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Καταχωρήστε έναν λογαριασμό Jabber" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Καταργήστε την εγγραφή ενός λογαριασμού Jabber" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Αυτή η σελίδα σας επιτρέπει να δημιουργήσετε ένα λογαριασμό Jabber σε αυτόν " "το διακομιστή Jabber. JID σας (Jabber Identifier) θα είναι της μορφής: " "όνομα_χρήστη@διακομιστής_Jabber. Παρακαλώ διαβάστε προσεκτικά τις οδηγίες " "για να συμπληρώσετε σωστά τα πεδία." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Όνομα χρήστη" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Ανεξαρτήτως με πεζά ή κεφαλαία: 'μιαλεξη' είναι το ίδιο με 'ΜιαΛέξη' και " "'Μιαλέξη'." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Χαρακτήρες δεν επιτρέπονται:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Διακομιστής:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "Μην πείτε τον κωδικό πρόσβασής σας σε κανέναν, ακόμη και στους διαχειριστές " "του διακομιστή Jabber." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" "Μπορείτε αργότερα να αλλάξετε τον κωδικό πρόσβασής σας χρησιμοποιώντας έναν " "πελάτη Jabber." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Μερικοί πελάτες Jabber μπορεί να αποθηκεύσουν τον κωδικό πρόσβασής σας στον " "υπολογιστή σας. Χρησιμοποιήστε αυτό το χαρακτηριστικό μόνο εάν εμπιστεύεστε " "την ασφάλεια του υπολογιστή σας." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Απομνημονεύστε τον κωδικό πρόσβασής σας, ή γράψετε τον σε ένα χαρτί που είχε " "τοποθετηθεί σε ασφαλές μέρος. Στο Jabber δεν υπάρχει αυτοματοποιημένος " "τρόπος για να ανακτήσετε τον κωδικό σας αν τον ξεχάσετε." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Επαλήθευση κωδικού πρόσβασης:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Καταχωρήστε" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Παλαιός κωδικός πρόσβασης:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Νέος κωδικός πρόσβασης:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" "Η σελίδα αυτή δίνει τη δυνατότητα να καταργήσετε την καταχώρηση ενός " "λογαριασμό Jabber σε αυτόν το διακομιστή Jabber." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Καταργήση εγγραφής" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "Το CAPTCHA είναι έγκυρο." ejabberd-2.1.11/src/msgs/pt-br.msg0000664000000000000000000006454312240230175013526 0ustar {"Access Configuration","Configuração de Acesso"}. {"Access Control List Configuration","Configuração da Lista de Controle de Acesso"}. {"Access control lists","Listas de Controle de Acesso"}. {"Access Control Lists","Listas de Controle de Acesso"}. {"Access denied by service policy","Aceso denegado por la política do serviço"}. {"Access rules","Regras de acesso"}. {"Access Rules","Regras de Acesso"}. {"Action on user","Ação no usuário"}. {"Add Jabber ID","Adicionar ID jabber"}. {"Add New","Adicionar novo"}. {"Add User","Adicionar usuário"}. {"Administration","Administração"}. {"Administration of ","Administração de "}. {"Administrator privileges required","Se necessita privilégios de administrador"}. {"A friendly name for the node","Um nome familiar para o nó"}. {"All activity","Todas atividades"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Autorizar este Jabber ID para a inscrição neste tópico pubsub?"}. {"Allow users to change the subject","Permitir a usuários modificar o assunto"}. {"Allow users to query other users","Permitir a usuários pesquisar informações sobre os demais"}. {"Allow users to send invites","Permitir a usuários envio de convites"}. {"Allow users to send private messages","Permitir a usuários enviarem mensagens privadas"}. {"Allow visitors to change nickname","Permitir mudança de apelido aos visitantes"}. {"Allow visitors to send status text in presence updates","Permitir atualizações de status aos visitantes"}. {"All Users","Todos os usuários"}. {"Announcements","Anúncios"}. {"anyone","qualquer um"}. {"A password is required to enter this room","Se necessita senha para entrar em esta sala"}. {"April","Abril"}. {"August","Agosto"}. {"Backup Management","Gestão de Backup"}. {"Backup of ","Backup de "}. {"Backup","Salvar cópia de segurança"}. {"Backup to File at ","Salvar backup para arquivo em "}. {"Bad format","Formato incorreto"}. {"Birthday","Aniversário"}. {"Change Password","Mudar senha"}. {"Change User Password","Alterar Senha do Usuário"}. {"Characters not allowed:","Caracteres não aceitos:"}. {"Chatroom configuration modified","Configuração da sala de bate-papo modificada"}. {"Chatroom is created","A sala de chat está criada"}. {"Chatroom is destroyed","A sala de chat está destruída"}. {"Chatroom is started","A sala de chat está inciada"}. {"Chatroom is stopped","A sala de chat está parada"}. {"Chatrooms","Salas de Chat"}. {"Choose a username and password to register with this server","Escolha um nome de usuário e senha para registrar-se neste servidor"}. {"Choose modules to stop","Selecione módulos a parar"}. {"Choose storage type of tables","Selecione o tipo de armazenamento das tabelas"}. {"Choose whether to approve this entity's subscription.","Aprovar esta assinatura."}. {"City","Cidade"}. {"Commands","Comandos"}. {"Conference room does not exist","La sala de conferencias não existe"}. {"Configuration","Configuração"}. {"Configuration of room ~s","Configuração para ~s"}. {"Connected Resources:","Recursos conectados:"}. {"Connections parameters","Parâmetros para as Conexões"}. {"Country","País"}. {"CPU Time:","Tempo de CPU"}. {"Database","Base de dados"}. {"Database Tables at ","Tabelas de base de dados em "}. {"Database Tables Configuration at ","Configuração de Tabelas de Base de dados em "}. {"December","Dezembro"}. {"Default users as participants","Usuários padrões como participantes"}. {"Delete","Eliminar"}. {"Delete message of the day","Apagar mensagem do dia"}. {"Delete message of the day on all hosts","Apagar a mensagem do dia em todos os hosts"}. {"Delete Selected","Remover os selecionados"}. {"Delete User","Deletar Usuário"}. {"Deliver event notifications","Entregar as notificações de evento"}. {"Deliver payloads with event notifications","Enviar payloads junto com as notificações de eventos"}. {"Description:","Descrição:"}. {"Disc only copy","Somente copia em disco"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Não revele o seu computador a ninguém, mesmo para o administrador deste servidor Jabber."}. {"Dump Backup to Text File at ","Exportar backup para texto em "}. {"Dump to Text File","Exportar para arquivo de texto"}. {"Edit Properties","Editar propriedades"}. {"Either approve or decline the voice request.","Você deve aprovar/desaprovar a requisição de voz."}. {"ejabberd IRC module","Módulo de IRC para ejabberd"}. {"ejabberd MUC module","Módulo de MUC para ejabberd"}. {"ejabberd Publish-Subscribe module","Módulo para Publicar Tópicos do ejabberd"}. {"ejabberd SOCKS5 Bytestreams module","Modulo ejabberd SOCKS5 Bytestreams"}. {"ejabberd vCard module","Módulo vCard para ejabberd"}. {"ejabberd Web Admin","ejabberd Web Admin"}. {"Elements","Elementos"}. {"Email","Email"}. {"Enable logging","Permitir criação de logs"}. {"Encoding for server ~b","Codificação para o servidor ~b"}. {"End User Session","Terminar Sessão do Usuário"}. {"Enter list of {Module, [Options]}","Introduza lista de {módulo, [opções]}"}. {"Enter nickname you want to register","Introduza o apelido que quer registrar"}. {"Enter path to backup file","Introduza o caminho do arquivo de backup"}. {"Enter path to jabberd14 spool dir","Introduza o caminho para o diretório de fila do jabberd14"}. {"Enter path to jabberd14 spool file","Insira o caminho para a fila (arquivo) do jabberd14"}. {"Enter path to text file","Introduza caminho para o arquivo texto"}. {"Enter the text you see","Insira o texto que você vê"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Insira o nome de usuário e codificações que você deseja usar para conectar-se aos servidores de IRC. Depois, presione 'Next' ('Próximo') para exibir mais campos que devem ser preenchidos. Ao final, pressione 'Complete' ('Completar') para salvar a configuração."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Insira o nome de usuário, codificações, portas e senhas que vocêdeseja para usar nos servidores IRC"}. {"Erlang Jabber Server","Servidor Jabber em Erlang"}. {"Error","Erro"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Exemplo: [{\"irc.teste.net\", \"koi8-r\"}, 6667, \"senha\"}, {\"dominio.foo.net\", \"iso8859-1\", 7000}, {\"irc.servidordeteste.net\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Excluir IDs Jabber de serem submetidos ao CAPTCHA"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exportar todos os dados de todos os usuários no servidor, para arquivos formato PIEFXIS (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Exportar dados dos usuários em um host, para arquivos PIEFXIS (XEP-0227):"}. {"Failed to extract JID from your voice request approval","Não foi possível extrair o JID (Jabber ID) da requisição de voz"}. {"Family Name","Sobrenome"}. {"February","Fevereiro"}. {"Fill in fields to search for any matching Jabber User","Preencha campos para buscar usuários Jabber que concordem"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Preencha o formulário para buscar usuários Jabber. Agrega * ao final de um campo para buscar sub-palavras."}. {"Friday","Sexta"}. {"From","De"}. {"From ~s","De ~s"}. {"Full Name","Nome completo"}. {"Get Number of Online Users","Obter Número de Usuários Online"}. {"Get Number of Registered Users","Obter Número de Usuários Registrados"}. {"Get User Last Login Time","Obter a Data do Último Login"}. {"Get User Password","Obter Senha do Usuário"}. {"Get User Statistics","Obter Estatísticas do Usuário"}. {"Group ","Grupo "}. {"Groups","Grupos"}. {"has been banned","foi banido"}. {"has been kicked because of an affiliation change","foi desconectado porque por afiliação inválida"}. {"has been kicked because of a system shutdown","foi desconectado porque o sistema foi desligado"}. {"has been kicked because the room has been changed to members-only","foi desconectado porque a política da sala mudou, só membros são permitidos"}. {"has been kicked","foi removido"}. {" has set the subject to: "," a posto o assunto: "}. {"Host","Máquina"}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Se você deseja especificar portas diferentes, senhas ou codifações para servidores de IRC, complete esta lista com os valores no formato: '{\"servidor IRC\", \"codificação\", porta, \"senha\"}'. Por padrão, este serviço usa a codificação \"~s\", porta \"~p\", e senha em branco (vazia)"}. {"Import Directory","Importar diretório"}. {"Import File","Importar arquivo"}. {"Import user data from jabberd14 spool file:","Importar dados dos usuários de uma fila jabberd14:"}. {"Import User from File at ","Importar usuário a partir do arquivo em "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importar usuários de um arquivo PIEFXIS (XEP-0227): "}. {"Import users data from jabberd14 spool directory:","Importar dados dos usuários de um diretório-fila jabberd14:"}. {"Import Users from Dir at ","Importar usuários a partir do diretório em "}. {"Import Users From jabberd14 Spool Files","Importar usuários de arquivos jabberd14"}. {"Improper message type","Tipo de mensagem incorreto"}. {"Incorrect password","Senha incorreta"}. {"Invalid affiliation: ~s","Afiliação não válida: ~s"}. {"Invalid role: ~s","Cargo (role) é não válido: ~s"}. {"IP addresses","Endereços IP"}. {"IP","IP"}. {"IRC channel (don't put the first #)","Canal IRC (não coloque o #)"}. {"IRC server","Servidor IRC"}. {"IRC settings","Configurações do IRC"}. {"IRC Transport","Transporte IRC"}. {"IRC username","Usuário IRC"}. {"IRC Username","Usuário IRC"}. {"is now known as","é agora conhecido como"}. {"It is not allowed to send private messages","Não é permitido enviar mensagens privadas"}. {"It is not allowed to send private messages of type \"groupchat\"","No está permitido enviar mensagens privados do tipo \"groupchat\""}. {"It is not allowed to send private messages to the conference","Impedir o envio de mensagens privadas para a sala"}. {"Jabber Account Registration","Registros de Contas Jabber"}. {"Jabber ID","ID Jabber"}. {"Jabber ID ~s is invalid","O Jabber ID ~s não es válido"}. {"January","Janeiro"}. {"Join IRC channel","Juntar-se ao canal IRC"}. {"joins the room","Entrar na sala"}. {"Join the IRC channel here.","Aqui! Juntar-se ao canal IRC."}. {"Join the IRC channel in this Jabber ID: ~s","Entrar no canal IRC, neste ID Jabber: ~s"}. {"July","Julho"}. {"June","Junho"}. {"Last Activity","Última atividade"}. {"Last login","Último login"}. {"Last month","Último mês"}. {"Last year","Último ano"}. {"leaves the room","Sair da sala"}. {"Listened Ports at ","Portas ouvintes em "}. {"Listened Ports","Portas escutadas"}. {"List of modules to start","Listas de módulos para inicializar"}. {"Low level update script","Script de atualização low level"}. {"Make participants list public","Tornar pública a lista de participantes"}. {"Make room CAPTCHA protected","Tornar protegida a senha da sala"}. {"Make room members-only","Tornar sala apenas para membros"}. {"Make room moderated","Tornar a sala moderada"}. {"Make room password protected","Tornar protegida a senha da sala"}. {"Make room persistent","Tornar sala persistente"}. {"Make room public searchable","Tornar sala pública possível de ser encontrada"}. {"March","Março"}. {"Maximum Number of Occupants","Número máximo de participantes"}. {"Max # of items to persist","Máximo # de elementos que persistem"}. {"Max payload size in bytes","Máximo tamanho do payload em bytes"}. {"May","Maio"}. {"Membership is required to enter this room","Necessitas ser membro de esta sala para poder entrar"}. {"Members:","Miembros:"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Memorize a sua senha, ou escreva-a em um papel e guarde-o em um lugar seguro. Jabber não é uma maneira automatizada para recuperar a sua senha, se você a esquecer eventualmente."}. {"Memory","Memória"}. {"Message body","Corpo da mensagem"}. {"Middle Name","Nome do meio"}. {"Minimum interval between voice requests (in seconds)","O intervalo mínimo entre requisições de voz (em segundos)"}. {"Moderator privileges required","Se necessita privilégios de moderador"}. {"moderators only","apenas moderadores"}. {"Modified modules","Módulos atualizados"}. {"Module","Módulo"}. {"Modules at ","Módulos em "}. {"Modules","Módulos"}. {"Monday","Segunda"}. {"Name:","Nome:"}. {"Name","Nome"}. {"Never","Nunca"}. {"Nickname","Apelido"}. {"Nickname Registration at ","Registro do apelido em "}. {"Nickname ~s does not exist in the room","O nick ~s não existe em la sala"}. {"nobody","ninguém"}. {"No body provided for announce message","Nenhum corpo de texto fornecido para anunciar mensagem"}. {"No Data","Nenhum dado"}. {"Node ID","ID do Tópico"}. {"Node ","Nó"}. {"Node not found","Nó não encontrado"}. {"Nodes","Nós"}. {"No limit","Ilimitado"}. {"None","Nenhum"}. {"No resource provided","Nenhum recurso foi informado"}. {"Not Found","Não encontrado"}. {"Notify subscribers when items are removed from the node","Notificar subscritores quando os elementos se eliminem do nodo"}. {"Notify subscribers when the node configuration changes","Notificar subscritores quando cambia la configuração do nodo"}. {"Notify subscribers when the node is deleted","Notificar subscritores quando o nodo se elimine"}. {"November","Novembro"}. {"Number of occupants","Número de participantes"}. {"Number of online users","Número de usuários online"}. {"Number of registered users","Número de usuários registrados"}. {"October","Outubro"}. {"Offline Messages:","Mensagens offline"}. {"Offline Messages","Mensagens offline"}. {"OK","OK"}. {"Online","Conectado"}. {"Online Users","Usuários conectados"}. {"Online Users:","Usuários online"}. {"Only deliver notifications to available users","Solo enviar notificações aos usuários disponíveis"}. {"Only moderators and participants are allowed to change the subject in this room","Somente os moderadores e os participamentes podem alterar o assunto desta sala"}. {"Only moderators are allowed to change the subject in this room","Somente os moderadores podem alterar o assunto desta sala"}. {"Only moderators can approve voice requests","Somente moderadores podem aprovar requisições de voz"}. {"Only occupants are allowed to send messages to the conference","Solo os ocupantes podem enviar mensagens a la sala"}. {"Only occupants are allowed to send queries to the conference","Solo os ocupantes podem enviar consultas a la sala"}. {"Only service administrators are allowed to send service messages","Apenas administradores possuem permissão para enviar mensagens de serviço"}. {"Options","Opções"}. {"Organization Name","Nome da organização"}. {"Organization Unit","Departamento/Unidade"}. {"Outgoing s2s Connections","Conexões que partam de s2s"}. {"Outgoing s2s Connections:","Conexões que partem de s2s"}. {"Outgoing s2s Servers:","Servidores que partem de s2s"}. {"Owner privileges required","Se requere privilégios de proprietário da sala"}. {"Packet","Pacote"}. {"Password ~b","Senha ~b"}. {"Password:","Senha:"}. {"Password","Senha"}. {"Password Verification","Verificação de Senha"}. {"Path to Dir","Caminho para o diretório"}. {"Path to File","Caminho do arquivo"}. {"Pending","Pendente"}. {"Period: ","Período: "}. {"Persist items to storage","Persistir elementos ao armazenar"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Observe que tais opções farão backup apenas da base de dados Mnesia. Caso você esteja utilizando o modulo ODBC, você precisará fazer backup de sua base de dados SQL separadamente."}. {"Please, wait for a while before sending new voice request","Por favor, espere antes de enviar uma nova requisição de voz"}. {"Pong","Pong"}. {"Port ~b","Porta ~b"}. {"Port","Porta"}. {"Present real Jabber IDs to","Tornar o Jabber ID real visível por"}. {"private, ","privado, "}. {"Protocol","Porta"}. {"Publish-Subscribe","Publicação de Tópico"}. {"PubSub subscriber request","PubSub requisição de assinante"}. {"Purge all items when the relevant publisher goes offline","Descartar todos os itens quando o publicante principal estiver offline"}. {"Queries to the conference members are not allowed in this room","Nesta sala não se permite consultas aos membros da sala"}. {"RAM and disc copy","Copias na RAM e disco rígido"}. {"RAM copy","Copia em RAM"}. {"Raw","Intocado"}. {"Really delete message of the day?","Deletar realmente a mensagem do dia?"}. {"Recipient is not in the conference room","O receptor não está em la sala de conferencia"}. {"Register a Jabber account","Registrar uma conta Jabber"}. {"Registered Users:","Usuários registrados"}. {"Registered Users","Usuários Registrados"}. {"Registration in mod_irc for ","Registro em mod_irc para "}. {"Remote copy","Copia remota"}. {"Remove All Offline Messages","Remover Todas as Mensagens Offline"}. {"Remove","Remover"}. {"Remove User","Remover usuário"}. {"Replaced by new connection","Substituído por nova conexão"}. {"Resources","Recursos"}. {"Restart","Reiniciar"}. {"Restart Service","Reiniciar Serviço"}. {"Restore Backup from File at ","Restaurar backup a partir do arquivo em "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Restaurar backup binário após próximo reinicialização do ejabberd (requer menos memória):"}. {"Restore binary backup immediately:","Restaurar backup binário imediatamente"}. {"Restore plain text backup immediately:","Restaurar backup formato texto imediatamente:"}. {"Restore","Restaurar"}. {"Room Configuration","Configuração de salas"}. {"Room creation is denied by service policy","Se te a denegado criar la sala por política do serviço"}. {"Room description","Descrição da Sala"}. {"Room Occupants","Número de participantes"}. {"Room title","Título da sala"}. {"Roster groups allowed to subscribe","Listar grupos autorizados"}. {"Roster","Lista de contatos"}. {"Roster of ","Lista de contatos de "}. {"Roster size","Tamanho da Lista"}. {"RPC Call Error","Erro de chamada RPC"}. {"Running Nodes","Nos em execução"}. {"~s access rule configuration","Configuração da Regra de Acesso ~s"}. {"Saturday","Sábado"}. {"Script check","Verificação de Script"}. {"Search Results for ","Resultados de pesquisa para "}. {"Search users in ","Procurar usuários em "}. {"Send announcement to all online users","Enviar anúncio a todos os usuárions online"}. {"Send announcement to all online users on all hosts","Enviar anúncio a todos usuários online em todas as máquinas"}. {"Send announcement to all users","Enviar anúncio a todos os usuários"}. {"Send announcement to all users on all hosts","Enviar aviso para todos os usuários em todos os hosts"}. {"September","Setembro"}. {"Server ~b","Servidor ~b"}. {"Set message of the day and send to online users","Definir mensagem do dia e enviar a todos usuários online"}. {"Set message of the day on all hosts and send to online users","Definir mensagem do dia em todos os hosts e enviar para os usuários online"}. {"Shared Roster Groups","Grupos Shared Roster"}. {"Show Integral Table","Mostrar Tabela Integral"}. {"Show Ordinary Table","Mostrar Tabela Ordinária"}. {"Shut Down Service","Parar Serviço"}. {"~s invites you to the room ~s","~s convidou você para a sala ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Alguns clientes jabber podem salvar a sua senha no seu computador. Use recurso somente se você considera este computador seguro o suficiente."}. {"Specify the access model","Especificar os modelos de acesso"}. {"Specify the event message type","Especificar o tipo de mensagem para o evento"}. {"Specify the publisher model","Especificar o modelo do publicante"}. {"~s's Offline Messages Queue","~s's Fila de Mensagens Offline"}. {"Start","Iniciar"}. {"Start Modules at ","Iniciar módulos em "}. {"Start Modules","Iniciar módulos"}. {"Statistics","Estatísticas"}. {"Statistics of ~p","Estatísticas de ~p"}. {"Stop Modules at ","Parar módulos em "}. {"Stop Modules","Parar módulos"}. {"Stop","Parar"}. {"Stopped Nodes","Nos parados"}. {"Storage Type","Tipo de armazenamento"}. {"Store binary backup:","Armazenar backup binário:"}. {"Store plain text backup:","Armazenar backup em texto:"}. {"Subject","Assunto"}. {"Submit","Enviar"}. {"Submitted","Submetido"}. {"Subscriber Address","Endereço dos Assinantes"}. {"Subscription","Subscrição"}. {"Sunday","Domingo"}. {"That nickname is already in use by another occupant","O apelido (nick) já está sendo utilizado"}. {"That nickname is registered by another person","O nick já está registrado por outra pessoa"}. {"The CAPTCHA is valid.","O CAPTCHA é inválido."}. {"The CAPTCHA verification has failed","A verificação do CAPTCHA falhou"}. {"The collections with which a node is affiliated","As coleções com as quais o nó está relacionado"}. {"the password is","a senha é"}. {"The password of your Jabber account was successfully changed.","A senha da sua conta Jabber foi mudada com sucesso."}. {"There was an error changing the password: ","Houveram erros ao mudar a senha: "}. {"There was an error creating the account: ","Houveram erras ao criar esta conta: "}. {"There was an error deleting the account: ","Erro ao deletar esta conta: "}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Não é 'case insensitive': macbeth é o mesmo que MacBeth e ainda Macbeth. "}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Esta pagina aceita criações de novas contas Jabber neste servidor. A sua JID (Identificador Jabber) será da seguinte forma: 'usuário@servidor'. Por favor, leia cuidadosamente as instruções para preencher corretamente os campos."}. {"This page allows to unregister a Jabber account in this Jabber server.","Esta página aceita para deletar uma conta Jabber neste servidor."}. {"This participant is kicked from the room because he sent an error message","Este participante foi desconectado da sala de chat por ter enviado uma mensagem de erro."}. {"This participant is kicked from the room because he sent an error message to another participant","Este participante foi desconectado da sala de chat por ter enviado uma mensagem de erro para outro usuário."}. {"This participant is kicked from the room because he sent an error presence","Este participante foi desconectado da sala de chat por ter enviado uma notificação errônea de presença."}. {"This room is not anonymous","Essa sala não é anônima"}. {"Thursday","Quinta"}. {"Time delay","Intervalo (Tempo)"}. {"Time","Fecha"}. {"Too many CAPTCHA requests","Número excessivo de requisições para o CAPTCHA"}. {"To","Para"}. {"To ~s","Para ~s"}. {"Traffic rate limit is exceeded","Limite de banda excedido"}. {"Transactions Aborted:","Transações abortadas:"}. {"Transactions Committed:","Transações salvas:"}. {"Transactions Logged:","Transações de log:"}. {"Transactions Restarted:","Transações reiniciadas:"}. {"Tuesday","Terça"}. {"Unable to generate a CAPTCHA","Impossível gerar um CAPTCHA"}. {"Unauthorized","Não Autorizado"}. {"Unregister a Jabber account","Deletar conta Jabber"}. {"Unregister","Deletar registro"}. {"Update ","Atualizar "}. {"Update","Atualizar"}. {"Update message of the day (don't send)","Atualizar mensagem do dia (não enviar)"}. {"Update message of the day on all hosts (don't send)","Atualizar a mensagem do dia em todos os host (não enviar)"}. {"Update plan","Plano de Atualização"}. {"Update script","Script de atualização"}. {"Uptime:","Uptime:"}. {"Use of STARTTLS required","É obrigatório uso de STARTTLS"}. {"User Management","Gerenciamento de Usuários"}. {"Users are not allowed to register accounts so quickly","Usuários não estão autorizados a registrar contas imediatamente"}. {"Users Last Activity","Ultimas atividades dos usuários"}. {"Users","Usuários"}. {"User ","Usuário "}. {"User","Usuário"}. {"Validate","Validar"}. {"vCard User Search","Busca de Usuário vCard"}. {"Virtual Hosts","Hosts virtuais"}. {"Visitors are not allowed to change their nicknames in this room","Nesta sala, os visitantes não pode mudar seus apelidos"}. {"Visitors are not allowed to send messages to all occupants","Os visitantes não podem enviar mensagens a todos os ocupantes"}. {"Voice request","Requisição de voz"}. {"Voice requests are disabled in this conference","Requisições de voz estào desabilitadas nesta conferência"}. {"Wednesday","Quarta"}. {"When to send the last published item","Quando enviar o último tópico publicado"}. {"Whether to allow subscriptions","Permitir subscrições"}. {"You can later change your password using a Jabber client.","Mais tarde você pode alterar a sua senha usando um cliente Jabber."}. {"You have been banned from this room","As sido bloqueado em esta sala"}. {"You must fill in field \"Nickname\" in the form","Você deve completar o campo \"Apelido\" no formulário"}. {"You need an x:data capable client to configure mod_irc settings","Necessitas um cliente com suporte de x:data para configurar las opções de mod_irc"}. {"You need an x:data capable client to configure room","Necessitas um cliente com suporte de x:data para configurar la sala"}. {"You need an x:data capable client to search","Necessitas um cliente com suporte de x:data para poder buscar"}. {"Your active privacy list has denied the routing of this stanza.","Sua lista de privacidade ativa negou o roteamento deste."}. {"Your contact offline message queue is full. The message has been discarded.","Sua fila de mensagens offline esta cheia. Sua mensagem foi descartada"}. {"Your Jabber account was successfully created.","Sua conta jabber foi criada corretamente."}. {"Your Jabber account was successfully deleted.","Sua conta Jabber foi deletada com sucesso."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Suas mensagens para ~s estão bloqueadas. Para desbloquea-las, visite: ~s"}. ejabberd-2.1.11/src/msgs/it.msg0000664000000000000000000007012712240230175013111 0ustar {"Access Configuration","Configurazione dell'accesso"}. {"Access Control List Configuration","Configurazione dei diritti di accesso (ACL)"}. {"Access control lists","Diritti di accesso (ACL)"}. {"Access Control Lists","Diritti di accesso (ACL)"}. {"Access denied by service policy","Accesso impedito dalle politiche del servizio"}. {"Access rules","Regole di accesso"}. {"Access Rules","Regole di accesso"}. {"Action on user","Azione sull'utente"}. {"Add Jabber ID","Aggiungere un Jabber ID (Jabber ID)"}. {"Add New","Aggiungere nuovo"}. {"Add User","Aggiungere un utente"}. {"Administration","Amministrazione"}. {"Administration of ","Amministrazione di "}. {"Administrator privileges required","Necessari i privilegi di amministratore"}. {"A friendly name for the node","Un nome comodo per il nodo"}. {"All activity","Tutta l'attività"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Consentire a questo Jabber ID l'iscrizione a questo nodo pubsub?"}. {"Allow users to change the subject","Consentire agli utenti di cambiare l'oggetto"}. {"Allow users to query other users","Consentire agli utenti query verso altri utenti"}. {"Allow users to send invites","Consentire agli utenti l'invio di inviti"}. {"Allow users to send private messages","Consentire agli utenti l'invio di messaggi privati"}. {"Allow visitors to change nickname","Consentire ai visitatori di cambiare il nickname"}. {"Allow visitors to send private messages to","Consentire agli ospiti l'invio di messaggi privati a"}. {"Allow visitors to send status text in presence updates","Consentire ai visitatori l'invio di testo sullo stato in aggiornamenti sulla presenza"}. {"Allow visitors to send voice requests","Consentire agli ospiti l'invio di richieste di parola"}. {"All Users","Tutti gli utenti"}. {"Announcements","Annunci"}. {"anyone","tutti"}. {"A password is required to enter this room","Per entrare in questa stanza è prevista una password"}. {"April","Aprile"}. {"August","Agosto"}. {"Backup Management","Gestione dei salvataggi"}. {"Backup of ","Salvataggio di "}. {"Backup","Salvare"}. {"Backup to File at ","Salvataggio sul file "}. {"Bad format","Formato non valido"}. {"Birthday","Compleanno"}. {"CAPTCHA web page","Pagina web CAPTCHA"}. {"Change Password","Modificare la password"}. {"Change User Password","Cambiare la password dell'utente"}. {"Characters not allowed:","Caratteri non consentiti:"}. {"Chatroom configuration modified","Configurazione della stanza modificata"}. {"Chatroom is created","La stanza è creata"}. {"Chatroom is destroyed","La stanza è eliminata"}. {"Chatroom is started","La stanza è avviata"}. {"Chatroom is stopped","La stanza è arrestata"}. {"Chatrooms","Stanze"}. {"Choose a username and password to register with this server","Scegliere un nome utente e una password per la registrazione con questo server"}. {"Choose modules to stop","Selezionare i moduli da arrestare"}. {"Choose storage type of tables","Selezionare una modalità di conservazione delle tabelle"}. {"Choose whether to approve this entity's subscription.","Scegliere se approvare l'iscrizione per questa entità"}. {"City","Città"}. {"Commands","Comandi"}. {"Conference room does not exist","La stanza per conferenze non esiste"}. {"Configuration","Configurazione"}. {"Configuration of room ~s","Configurazione per la stanza ~s"}. {"Connected Resources:","Risorse connesse:"}. {"Connections parameters","Parametri delle connessioni"}. {"Country","Paese"}. {"CPU Time:","Tempo CPU:"}. {"Database","Database"}. {"Database Tables at ","Tabelle del database su "}. {"Database Tables Configuration at ","Configurazione delle tabelle del database su "}. {"December","Dicembre"}. {"Default users as participants","Definire per default gli utenti come partecipanti"}. {"Delete","Eliminare"}. {"Delete message of the day","Eliminare il messaggio del giorno (MOTD)"}. {"Delete message of the day on all hosts","Eliminare il messaggio del giorno (MOTD) su tutti gli host"}. {"Delete Selected","Eliminare gli elementi selezionati"}. {"Delete User","Eliminare l'utente"}. {"Deliver event notifications","Inviare notifiche degli eventi"}. {"Deliver payloads with event notifications","Inviare il contenuto del messaggio con la notifica dell'evento"}. {"Description:","Descrizione:"}. {"Disc only copy","Copia su disco soltanto"}. {"Displayed Groups:","Gruppi visualizzati:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Non comunicare la tua password a nessuno, neppure agli amministratori del server Jabber."}. {"Dump Backup to Text File at ","Trascrivere il salvataggio sul file di testo "}. {"Dump to Text File","Trascrivere su file di testo"}. {"Edit Properties","Modificare le proprietà"}. {"Either approve or decline the voice request.","Approva oppure respingi la richiesta di parola."}. {"ejabberd IRC module","Modulo IRC per ejabberd"}. {"ejabberd MUC module","Modulo MUC per ejabberd"}. {"ejabberd Publish-Subscribe module","Modulo Pubblicazione/Iscrizione (PubSub) per ejabberd"}. {"ejabberd SOCKS5 Bytestreams module","Modulo SOCKS5 Bytestreams per ejabberd"}. {"ejabberd vCard module","Modulo vCard per ejabberd"}. {"ejabberd Web Admin","Amministrazione web ejabberd"}. {"Elements","Elementi"}. {"Email","E-mail"}. {"Enable logging","Abilitare i log"}. {"Encoding for server ~b","Codifica per il server ~b"}. {"End User Session","Terminare la sessione dell'utente"}. {"Enter list of {Module, [Options]}","Immettere un elenco di {Modulo, [Opzioni]}"}. {"Enter nickname you want to register","Immettere il nickname che si vuole registrare"}. {"Enter path to backup file","Immettere il percorso del file di salvataggio"}. {"Enter path to jabberd14 spool dir","Immettere il percorso della directory di spool di jabberd14"}. {"Enter path to jabberd14 spool file","Immettere il percorso del file di spool di jabberd14"}. {"Enter path to text file","Immettere il percorso del file di testo"}. {"Enter the text you see","Immettere il testo visibile"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Immettere il nome utente e le codifiche che si desidera utilizzare per la connessione ai server IRC. Premere \"Avanti\" per vedere i successivi campi da compilare. Premere \"Fatto\" per salvare le impostazioni."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Immettere il nome utente, le codifiche, le porte e le password che si desidera utilizzare per la connessione ai server IRC"}. {"Erlang Jabber Server","Erlang Jabber Server"}. {"Error","Errore"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Esempio: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"segreto\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.serverdiprova.net\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Escludi degli ID Jabber dal passaggio CAPTCHA"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Esportare i dati di tutti gli utenti nel server in file PIEFXIS (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Esportare i dati degli utenti di un host in file PIEFXIS (XEP-0227):"}. {"Failed to extract JID from your voice request approval","Impossibile estrarre il JID dall'approvazione della richiesta di parola"}. {"Family Name","Cognome"}. {"February","Febbraio"}. {"Fill in fields to search for any matching Jabber User","Riempire i campi per la ricerca di utenti Jabber corrispondenti ai criteri"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Riempire il modulo per la ricerca di utenti Jabber corrispondenti ai criteri (Aggiungere * alla fine del campo per la ricerca di una sottostringa"}. {"Friday","Venerdì"}. {"From","Da"}. {"From ~s","Da ~s"}. {"Full Name","Nome completo"}. {"Get Number of Online Users","Ottenere il numero di utenti online"}. {"Get Number of Registered Users","Ottenere il numero di utenti registrati"}. {"Get User Last Login Time","Ottenere la data di ultimo accesso dell'utente"}. {"Get User Password","Ottenere la password dell'utente"}. {"Get User Statistics","Ottenere le statistiche dell'utente"}. {"Grant voice to this person?","Dare parola a questa persona?"}. {"Group ","Gruppo "}. {"Groups","Gruppi"}. {"has been banned","è stata/o bandita/o"}. {"has been kicked because of an affiliation change","è stato espulso a causa di un cambiamento di appartenenza"}. {"has been kicked because of a system shutdown","è stato espulso a causa dello spegnimento del sistema"}. {"has been kicked because the room has been changed to members-only","è stato espulso per la limitazione della stanza ai soli membri"}. {"has been kicked","è stata/o espulsa/o"}. {" has set the subject to: "," ha modificato l'oggetto in: "}. {"Host","Host"}. {"If you don't see the CAPTCHA image here, visit the web page.","Se qui non vedi l'immagine CAPTCHA, visita la pagina web."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Se si vogliono specificare differenti porte, password, codifiche per i server IRC, si riempia questo elenco con valori nel formato '{\"server IRC\", \"codifica\", porta, \"password\"}'. Per default questo servizio utilizza la codifica \"~s\", la porta ~p, la password vuota."}. {"Import Directory","Importare una directory"}. {"Import File","Importare un file"}. {"Import user data from jabberd14 spool file:","Importare i dati utente da file di spool di jabberd14:"}. {"Import User from File at ","Importare un utente dal file "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importare i dati utenti da un file PIEFXIS (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Importare i dati utenti da directory di spool di jabberd14:"}. {"Import Users from Dir at ","Importare utenti dalla directory "}. {"Import Users From jabberd14 Spool Files","Importare utenti da file di spool di jabberd14"}. {"Improper message type","Tipo di messaggio non corretto"}. {"Incorrect password","Password non esatta"}. {"Invalid affiliation: ~s","Affiliazione non valida: ~s"}. {"Invalid role: ~s","Ruolo non valido: ~s"}. {"IP addresses","Indirizzi IP"}. {"IP","IP"}. {"IRC channel (don't put the first #)","Canale IRC (senza il # iniziale)"}. {"IRC server","Server IRC"}. {"IRC settings","Impostazioni IRC"}. {"IRC Transport","Transport IRC"}. {"IRC username","Nome utente IRC"}. {"IRC Username","Nome utente IRC"}. {"is now known as","è ora conosciuta/o come"}. {"It is not allowed to send private messages","Non è consentito l'invio di messaggi privati"}. {"It is not allowed to send private messages of type \"groupchat\"","Non è consentito l'invio di messaggi privati di tipo \"groupchat\""}. {"It is not allowed to send private messages to the conference","Non è consentito l'invio di messaggi privati alla conferenza"}. {"Jabber Account Registration","Registrazione account Jabber"}. {"Jabber ID","Jabber ID (Jabber ID)"}. {"Jabber ID ~s is invalid","Il Jabber ID ~s non è valido"}. {"January","Gennaio"}. {"Join IRC channel","Entra nel canale IRC"}. {"joins the room","entra nella stanza"}. {"Join the IRC channel here.","Entra nel canale IRC qui."}. {"Join the IRC channel in this Jabber ID: ~s","Entra nel canale IRC in questo ID Jabber: ~s"}. {"July","Luglio"}. {"June","Giugno"}. {"Last Activity","Ultima attività"}. {"Last login","Ultimo accesso"}. {"Last month","Ultimo mese"}. {"Last year","Ultimo anno"}. {"leaves the room","esce dalla stanza"}. {"Listened Ports at ","Porte in ascolto su "}. {"Listened Ports","Porte in ascolto"}. {"List of modules to start","Elenco dei moduli da avviare"}. {"Low level update script","Script di aggiornamento di basso livello"}. {"Make participants list public","Rendere pubblica la lista dei partecipanti"}. {"Make room CAPTCHA protected","Rendere la stanza protetta da CAPTCHA"}. {"Make room members-only","Rendere la stanza riservata ai membri"}. {"Make room moderated","Rendere la stanza moderata"}. {"Make room password protected","Rendere la stanza protetta da password"}. {"Make room persistent","Rendere la stanza persistente"}. {"Make room public searchable","Rendere la sala visibile al pubblico"}. {"March","Marzo"}. {"Maximum Number of Occupants","Numero massimo di occupanti"}. {"Max # of items to persist","Numero massimo di elementi da conservare persistentemente"}. {"Max payload size in bytes","Dimensione massima del contenuto del messaggio in byte"}. {"May","Maggio"}. {"Membership is required to enter this room","Per entrare in questa stanza è necessario essere membro"}. {"Members:","Membri:"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Memorizza la password, o scrivila su un foglio di carta da conservare in un luogo sicuro. Jabber non prevede una modalità automatica per il recupero di una password dimenticata."}. {"Memory","Memoria"}. {"Message body","Corpo del messaggio"}. {"Middle Name","Altro nome"}. {"Minimum interval between voice requests (in seconds)","Intervallo minimo fra due richieste di parola (in secondi)"}. {"Moderator privileges required","Necessari i privilegi di moderatore"}. {"moderators only","moderatori soltanto"}. {"Modified modules","Moduli modificati"}. {"Module","Modulo"}. {"Modules at ","Moduli su "}. {"Modules","Moduli"}. {"Monday","Lunedì"}. {"Name:","Nome:"}. {"Name","Nome"}. {"Never","Mai"}. {"New Password:","Nuova password:"}. {"Nickname","Nickname"}. {"Nickname Registration at ","Registrazione di un nickname su "}. {"Nickname ~s does not exist in the room","Il nickname ~s non esiste nella stanza"}. {"nobody","nessuno"}. {"No body provided for announce message","Nessun corpo fornito per il messaggio di annuncio"}. {"No Data","Nessuna informazione"}. {"Node ID","ID del nodo"}. {"Node ","Nodo "}. {"Node not found","Nodo non trovato"}. {"Nodes","Nodi"}. {"No limit","Nessun limite"}. {"None","Nessuno"}. {"No resource provided","Nessuna risorsa fornita"}. {"Not Found","Non trovato"}. {"Notify subscribers when items are removed from the node","Notificare gli iscritti quando sono eliminati degli elementi dal nodo"}. {"Notify subscribers when the node configuration changes","Notificare gli iscritti quando la configurazione del nodo cambia"}. {"Notify subscribers when the node is deleted","Notificare gli iscritti quando il nodo è cancellato"}. {"November","Novembre"}. {"Number of occupants","Numero di presenti"}. {"Number of online users","Numero di utenti online"}. {"Number of registered users","Numero di utenti registrati"}. {"October","Ottobre"}. {"Offline Messages:","Messaggi offline:"}. {"Offline Messages","Messaggi offline"}. {"OK","OK"}. {"Old Password:","Vecchia password:"}. {"Online","Online"}. {"Online Users:","Utenti connessi:"}. {"Online Users","Utenti online"}. {"Only deliver notifications to available users","Inviare le notifiche solamente agli utenti disponibili"}. {"Only moderators and participants are allowed to change the subject in this room","La modifica dell'oggetto di questa stanza è consentita soltanto ai moderatori e ai partecipanti"}. {"Only moderators are allowed to change the subject in this room","La modifica dell'oggetto di questa stanza è consentita soltanto ai moderatori"}. {"Only moderators can approve voice requests","Soltanto i moderatori possono approvare richieste di parola"}. {"Only occupants are allowed to send messages to the conference","L'invio di messaggi alla conferenza è consentito soltanto ai presenti"}. {"Only occupants are allowed to send queries to the conference","L'invio di query alla conferenza è consentito ai soli presenti"}. {"Only service administrators are allowed to send service messages","L'invio di messaggi di servizio è consentito solamente agli amministratori del servizio"}. {"Options","Opzioni"}. {"Organization Name","Nome dell'organizzazione"}. {"Organization Unit","Unità dell'organizzazione"}. {"Outgoing s2s Connections:","Connessioni s2s in uscita:"}. {"Outgoing s2s Connections","Connessioni s2s in uscita"}. {"Outgoing s2s Servers:","Server s2s in uscita"}. {"Owner privileges required","Necessari i privilegi di proprietario"}. {"Packet","Pacchetto"}. {"Password ~b","Password ~b"}. {"Password:","Password:"}. {"Password","Password"}. {"Password Verification:","Verifica della password:"}. {"Password Verification","Verifica della password"}. {"Path to Dir","Percorso della directory"}. {"Path to File","Percorso del file"}. {"Pending","Pendente"}. {"Period: ","Periodo:"}. {"Persist items to storage","Conservazione persistente degli elementi"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","N.B.: Queste opzioni comportano il salvataggio solamente del database interno Mnesia. Se si sta utilizzando il modulo ODBC, è necessario salvare anche il proprio database SQL separatamente."}. {"Please, wait for a while before sending new voice request","Attendi qualche istante prima di inviare una nuova richiesta di parola"}. {"Pong","Pong"}. {"Port ~b","Porta ~b"}. {"Port","Porta"}. {"Present real Jabber IDs to","Rendere visibile il Jabber ID reale a"}. {"private, ","privato, "}. {"Protocol","Protocollo"}. {"Publish-Subscribe","Pubblicazione-Iscrizione"}. {"PubSub subscriber request","Richiesta di iscrizione per PubSub"}. {"Purge all items when the relevant publisher goes offline","Cancella tutti gli elementi quando chi li ha pubblicati non è più online"}. {"Queries to the conference members are not allowed in this room","In questa stanza non sono consentite query ai membri della conferenza"}. {"RAM and disc copy","Copia in memoria (RAM) e su disco"}. {"RAM copy","Copia in memoria (RAM)"}. {"Raw","Grezzo"}. {"Really delete message of the day?","Si conferma l'eliminazione del messaggio del giorno (MOTD)?"}. {"Recipient is not in the conference room","Il destinatario non è nella stanza per conferenze"}. {"Register a Jabber account","Registra un account Jabber"}. {"Registered Users:","Utenti registrati:"}. {"Registered Users","Utenti registrati"}. {"Register","Registra"}. {"Registration in mod_irc for ","Registrazione in mod_irc per "}. {"Remote copy","Copia remota"}. {"Remove All Offline Messages","Eliminare tutti i messaggi offline"}. {"Remove","Eliminare"}. {"Remove User","Eliminare l'utente"}. {"Replaced by new connection","Sostituito da una nuova connessione"}. {"Resources","Risorse"}. {"Restart","Riavviare"}. {"Restart Service","Riavviare il servizio"}. {"Restore Backup from File at ","Recuperare il salvataggio dal file "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Recuperare un salvataggio binario dopo il prossimo riavvio di ejabberd (necessita di meno memoria):"}. {"Restore binary backup immediately:","Recuperare un salvataggio binario adesso:"}. {"Restore plain text backup immediately:","Recuperare un salvataggio come semplice testo adesso:"}. {"Restore","Recuperare"}. {"Room Configuration","Configurazione della stanza"}. {"Room creation is denied by service policy","La creazione di stanze è impedita dalle politiche del servizio"}. {"Room description","Descrizione della stanza"}. {"Room Occupants","Presenti nella stanza"}. {"Room title","Titolo della stanza"}. {"Roster groups allowed to subscribe","Gruppi roster abilitati alla registrazione"}. {"Roster","Lista dei contatti"}. {"Roster of ","Lista dei contatti di "}. {"Roster size","Dimensione della lista dei contatti"}. {"RPC Call Error","Errore di chiamata RPC"}. {"Running Nodes","Nodi attivi"}. {"~s access rule configuration","Configurazione delle regole di accesso per ~s"}. {"Saturday","Sabato"}. {"Script check","Verifica dello script"}. {"Search Results for ","Risultati della ricerca per "}. {"Search users in ","Cercare utenti in "}. {"Send announcement to all online users","Inviare l'annuncio a tutti gli utenti online"}. {"Send announcement to all online users on all hosts","Inviare l'annuncio a tutti gli utenti online su tutti gli host"}. {"Send announcement to all users","Inviare l'annuncio a tutti gli utenti"}. {"Send announcement to all users on all hosts","Inviare l'annuncio a tutti gli utenti su tutti gli host"}. {"September","Settembre"}. {"Server ~b","Server ~b"}. {"Server:","Server:"}. {"Set message of the day and send to online users","Impostare il messaggio del giorno (MOTD) ed inviarlo agli utenti online"}. {"Set message of the day on all hosts and send to online users","Impostare il messaggio del giorno (MOTD) su tutti gli host e inviarlo agli utenti online"}. {"Shared Roster Groups","Gruppi di liste di contatti comuni"}. {"Show Integral Table","Mostrare la tabella integrale"}. {"Show Ordinary Table","Mostrare la tabella normale"}. {"Shut Down Service","Terminare il servizio"}. {"~s invites you to the room ~s","~s ti invita nella stanza ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Alcuni client Jabber possono conservare la password nel tuo computer. Utilizza tale funzione soltanto se ritieni che il tuo computer sia sicuro."}. {"Specify the access model","Specificare il modello di accesso"}. {"Specify the event message type","Specificare il tipo di messaggio di evento"}. {"Specify the publisher model","Definire il modello di pubblicazione"}. {"~s's Offline Messages Queue","Coda di ~s messaggi offline"}. {"Start","Avviare"}. {"Start Modules at ","Avviare moduli su "}. {"Start Modules","Avviare moduli"}. {"Statistics of ~p","Statistiche di ~p"}. {"Statistics","Statistiche"}. {"Stop","Arrestare"}. {"Stop Modules","Arrestare moduli"}. {"Stop Modules at ","Arrestare moduli su "}. {"Stopped Nodes","Nodi arrestati"}. {"Storage Type","Tipo di conservazione"}. {"Store binary backup:","Conservare un salvataggio binario:"}. {"Store plain text backup:","Conservare un salvataggio come semplice testo:"}. {"Subject","Oggetto"}. {"Submit","Inviare"}. {"Submitted","Inviato"}. {"Subscriber Address","Indirizzo dell'iscritta/o"}. {"Subscription","Iscrizione"}. {"Sunday","Domenica"}. {"That nickname is already in use by another occupant","Il nickname è già in uso all'interno della conferenza"}. {"That nickname is registered by another person","Questo nickname è registrato da un'altra persona"}. {"The CAPTCHA is valid.","Il CAPTCHA è valido."}. {"The CAPTCHA verification has failed","La verifica del CAPTCHA ha avuto esito negativo"}. {"The collections with which a node is affiliated","Le collezioni a cui è affiliato un nodo"}. {"the password is","la password è"}. {"The password is too weak","La password è troppo debole"}. {"The password of your Jabber account was successfully changed.","Il cambio di password del tuo account Jabber è andato a buon fine."}. {"There was an error changing the password: ","Si è verificato un errore nel cambio di password: "}. {"There was an error creating the account: ","Si è verificato un errore nella creazione dell'account: "}. {"There was an error deleting the account: ","Si è verificato un errore nella cancellazione dell'account: "}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Non fa differenza fra minuscolo e maiuscolo: macbeth, MacBeth e Macbeth si equivalgono."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Questa pagina consente di creare un account Jabber in questo server Jabber. Il tuo JID (Jabber IDentifier) avrà la forma: nome_utente@server. Leggi attentamente le istruzioni per compilare i campi correttamente."}. {"This page allows to unregister a Jabber account in this Jabber server.","Questa pagina consente di eliminare un account Jabber da questo server Jabber."}. {"This participant is kicked from the room because he sent an error message","Partecipante espulso dalla stanza perché ha inviato un messaggio non valido"}. {"This participant is kicked from the room because he sent an error message to another participant","Partecipante espulso dalla stanza perché ha inviato un messaggio non valido a un altro partecipante"}. {"This participant is kicked from the room because he sent an error presence","Partecipante espulso dalla stanza perché ha inviato una presenza non valido"}. {"This room is not anonymous","Questa stanza non è anonima"}. {"Thursday","Giovedì"}. {"Time delay","Ritardo"}. {"Time","Ora"}. {"To","A"}. {"Too many CAPTCHA requests","Troppe richieste CAPTCHA"}. {"To ~s","A ~s"}. {"Traffic rate limit is exceeded","Limite di traffico superato"}. {"Transactions Aborted:","Transazioni abortite:"}. {"Transactions Committed:","Transazioni avvenute:"}. {"Transactions Logged:","Transazioni con log:"}. {"Transactions Restarted:","Transazioni riavviate:"}. {"Tuesday","Martedì"}. {"Unable to generate a CAPTCHA","Impossibile generare un CAPTCHA"}. {"Unauthorized","Non autorizzato"}. {"Unregister a Jabber account","Elimina un account Jabber"}. {"Unregister","Elimina"}. {"Update ","Aggiornare "}. {"Update","Aggiornare"}. {"Update message of the day (don't send)","Aggiornare il messaggio del giorno (MOTD) (non inviarlo)"}. {"Update message of the day on all hosts (don't send)","Aggiornare il messaggio del giorno (MOTD) su tutti gli host (non inviarlo)"}. {"Update plan","Piano di aggiornamento"}. {"Update script","Script di aggiornamento"}. {"Uptime:","Tempo dall'avvio:"}. {"Use of STARTTLS required","Utilizzo di STARTTLS obbligatorio"}. {"User JID","JID utente"}. {"User Management","Gestione degli utenti"}. {"Username:","Nome utente:"}. {"Users are not allowed to register accounts so quickly","Non è consentito agli utenti registrare account così rapidamente"}. {"Users Last Activity","Ultima attività degli utenti"}. {"Users","Utenti"}. {"User ","Utente "}. {"User","Utente"}. {"Validate","Validare"}. {"vCard User Search","Ricerca di utenti per vCard"}. {"Virtual Hosts","Host Virtuali"}. {"Visitors are not allowed to change their nicknames in this room","Non è consentito ai visitatori cambiare il nickname in questa stanza"}. {"Visitors are not allowed to send messages to all occupants","Non è consentito ai visitatori l'invio di messaggi a tutti i presenti"}. {"Voice request","Richiesta di parola"}. {"Voice requests are disabled in this conference","In questa conferenza le richieste di parola sono escluse"}. {"Wednesday","Mercoledì"}. {"When to send the last published item","Quando inviare l'ultimo elemento pubblicato"}. {"Whether to allow subscriptions","Consentire iscrizioni?"}. {"You can later change your password using a Jabber client.","Potrai in seguito cambiare la password utilizzando un client Jabber."}. {"You have been banned from this room","Sei stata/o bandita/o da questa stanza"}. {"You must fill in field \"Nickname\" in the form","Si deve riempire il campo \"Nickname\" nel modulo"}. {"You need a client that supports x:data and CAPTCHA to register","La registrazione richiede un client che supporti x:data e CAPTCHA"}. {"You need a client that supports x:data to register the nickname","Per registrare il nickname è necessario un client che supporti x:data"}. {"You need an x:data capable client to configure mod_irc settings","Per la configurazione del modulo IRC è necessario un client che supporti x:data"}. {"You need an x:data capable client to configure room","Per la configurazione della stanza è necessario un client che supporti x:data"}. {"You need an x:data capable client to search","Per effettuare ricerche è necessario un client che supporti x:data"}. {"Your active privacy list has denied the routing of this stanza.","In base alla tua attuale lista privacy questa stanza è stata esclusa dalla navigazione."}. {"Your contact offline message queue is full. The message has been discarded.","La coda dei messaggi offline del contatto è piena. Il messaggio è stato scartato"}. {"Your Jabber account was successfully created.","La creazione del tuo account Jabber è andata a buon fine."}. {"Your Jabber account was successfully deleted.","La cancellazione del tuo account Jabber è andata a buon fine."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","I messaggi verso ~s sono bloccati. Per sbloccarli, visitare ~s"}. ejabberd-2.1.11/src/msgs/el.msg0000664000000000000000000012025712240230175013075 0ustar {"Access Configuration","Διαμόρφωση Πρόσβασης"}. {"Access Control List Configuration","Διαχείριση στις Λίστες Ελέγχου Πρόσβασης"}. {"Access control lists","Λίστες Ελέγχου Πρόσβασης"}. {"Access Control Lists","Λίστες Ελέγχου Πρόσβασης"}. {"Access denied by service policy","Άρνηση πρόσβασης, λόγω τακτικής παροχής υπηρεσιών"}. {"Access rules","Κανόνες Πρόσβασης"}. {"Access Rules","Κανόνες Πρόσβασης"}. {"Action on user","Eνέργεια για το χρήστη"}. {"Add Jabber ID","Προσθήκη Jabber Ταυτότητας"}. {"Add New","Προσθήκη νέου"}. {"Add User","Προσθήκη Χρήστη"}. {"Administration of ","Διαχείριση του"}. {"Administration","Διαχείριση"}. {"Administrator privileges required","Aπαιτούνται προνόμια διαχειριστή"}. {"A friendly name for the node","Ένα φιλικό όνομα για τον κόμβο"}. {"All activity","Όλες οι δραστηριότητες"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Επιτρέπετε σε αυτή την Jabber Ταυτότητα να εγγραφεί σε αυτό τον κόμβο Δημοσίευσης-Εγγραφής;"}. {"Allow users to change the subject","Επιτρέψετε στους χρήστες να αλλάζουν το θέμα"}. {"Allow users to query other users","Επιτρέπστε στους χρήστες να ερωτούν άλλους χρήστες"}. {"Allow users to send invites","Επιτρέψετε στους χρήστες να αποστέλλουν προσκλήσεις"}. {"Allow users to send private messages","Επιτρέψετε στους χρήστες να αποστέλλουν ιδιωτικά μηνύματα"}. {"Allow visitors to change nickname","Επιτρέψετε στους επισκέπτες να αλλάζου ψευδώνυμο"}. {"Allow visitors to send private messages to","Επιτρέψετε στους χρήστες να αποστέλλουν ιδιωτικά μηνύματα σε"}. {"Allow visitors to send status text in presence updates","Επιτρέψτε στους επισκέπτες να αποστέλλουν κατάσταση στις ενημερώσεις παρουσίας"}. {"Allow visitors to send voice requests","Επιτρέψτε στους επισκέπτες να στέλνουν αιτήματα φωνής"}. {"All Users","Όλοι οι χρήστες"}. {"Announcements","Ανακοινώσεις"}. {"anyone","οποιοσδήποτε"}. {"A password is required to enter this room","Απαιτείται κωδικός πρόσβασης για είσοδο σε αυτή την αίθουσα"}. {"April","Απρίλιος"}. {"August","Αύγουστος"}. {"Backup Management","Διαχείριση Αντιγράφου Ασφαλείας"}. {"Backup of ","Αντιγράφο Ασφαλείας του "}. {"Backup to File at ","Αποθήκευση Αντιγράφου Ασφαλείας σε Αρχείο στο "}. {"Backup","Αποθήκευση Αντιγράφου Ασφαλείας"}. {"Bad format","Ακατάλληλη μορφή"}. {"Birthday","Γενέθλια"}. {"CAPTCHA web page","Ιστοσελίδα CAPTCHA "}. {"Change Password","Αλλαγή κωδικού"}. {"Change User Password","Αλλαγή Κωδικού Πρόσβασης Χρήστη"}. {"Characters not allowed:","Χαρακτήρες δεν επιτρέπονται:"}. {"Chatroom configuration modified","Διαμόρφωση Αίθουσaς σύνεδριασης τροποποιηθηκε"}. {"Chatroom is created","Η αίθουσα σύνεδριασης δημιουργήθηκε"}. {"Chatroom is destroyed","Η αίθουσα σύνεδριασης διαγράφηκε"}. {"Chatroom is started","Η αίθουσα σύνεδριασης έχει ξεκινήσει"}. {"Chatroom is stopped","Η αίθουσα σύνεδριασης έχει σταματήσει"}. {"Chatrooms","Αίθουσες σύνεδριασης"}. {"Choose a username and password to register with this server","Επιλέξτε ένα όνομα χρήστη και κωδικό πρόσβασης για να εγγραφείτε σε αυτό τον διακομιστή"}. {"Choose modules to stop","Επιλέξτε modules για να σταματήσουν"}. {"Choose storage type of tables","Επιλέξτε τύπο αποθήκευσης των πινάκων"}. {"Choose whether to approve this entity's subscription.","Επιλέξτε αν θα εγκρίθεί η εγγραφή αυτής της οντότητας."}. {"City","Πόλη"}. {"Commands","Εντολές"}. {"Conference room does not exist","Αίθουσα σύνεδριασης δεν υπάρχει"}. {"Configuration of room ~s","Διαμόρφωση Αίθουσας σύνεδριασης ~s"}. {"Configuration","Διαμόρφωση"}. {"Connected Resources:","Συνδεδεμένοι Πόροι:"}. {"Connections parameters","Παράμετροι Συνδέσης"}. {"Country","Χώρα"}. {"CPU Time:","Ώρα CPU:"}. {"Database Tables at ","Πίνακες βάσης δεδομένων στο "}. {"Database Tables Configuration at ","Διαμόρφωση Πίνακων βάσης δεδομένων στο "}. {"Database","Βάση δεδομένων"}. {"December","Δεκέμβριος"}. {"Default users as participants","Προεπιλογη χρήστων ως συμμετέχοντες"}. {"Delete message of the day on all hosts","Διαγράψτε το μήνυμα της ημέρας σε όλους τους κεντρικούς υπολογιστές"}. {"Delete message of the day","Διαγράψτε το μήνυμα της ημέρας"}. {"Delete Selected","Διαγραφή επιλεγμένων"}. {"Delete User","Διαγραφή Χρήστη"}. {"Delete","Διαγραφή"}. {"Deliver event notifications","Κοινοποιήσεις παράδοσης"}. {"Deliver payloads with event notifications","Κοινοποιήσεις με την παράδοση φορτίων"}. {"Description:","Περιγραφή:"}. {"Disc only copy","Αντίγραφο μόνο σε δίσκο"}. {"Displayed Groups:","Εμφανίσμενες Ομάδες:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Μην πείτε τον κωδικό πρόσβασής σας σε κανέναν, ακόμη και στους διαχειριστές του διακομιστή Jabber."}. {"Dump Backup to Text File at ","Αποθήκευση Αντιγράφου Ασφαλείας σε αρχείο κειμένου στο "}. {"Dump to Text File","Αποθήκευση σε αρχείο κειμένου"}. {"Edit Properties","Επεξεργασία ιδιοτήτων"}. {"Either approve or decline the voice request.","Είτε εγκρίνετε ή απορρίψτε το αίτημα φωνής."}. {"ejabberd IRC module","ejabberd IRC module"}. {"ejabberd MUC module","ejabberd MUC module"}. {"ejabberd Publish-Subscribe module","ejabberd module Δημοσίευσης-Εγγραφής"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}. {"ejabberd vCard module","ejabberd vCard module"}. {"ejabberd Web Admin","ejabberd Web Admin"}. {"Elements","Στοιχεία"}. {"Email","Email"}. {"Enable logging","Ενεργοποίηση καταγραφής"}. {"Encoding for server ~b","Κωδικοποίηση για διακομιστή ~b"}. {"End User Session","Τερματισμός Συνεδρίας Χρήστη"}. {"Enter list of {Module, [Options]}","Εισάγετε κατάλογο των (Module, [Επιλογές])"}. {"Enter nickname you want to register","Πληκτρολογήστε το ψευδώνυμο που θέλετε να εγγραφείτε"}. {"Enter path to backup file","Εισάγετε τοποθεσία αρχείου αντιγράφου ασφαλείας"}. {"Enter path to jabberd14 spool dir","Εισάγετε κατάλογο αρχείων σειράς jabberd14"}. {"Enter path to jabberd14 spool file","Εισάγετε τοποθεσία αρχείου σειράς jabberd14"}. {"Enter path to text file","Εισάγετε Τοποθεσία Αρχείου Κειμένου"}. {"Enter the text you see","Πληκτρολογήστε το κείμενο που βλέπετε"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Πληκτρολογήστε το όνομα χρήστη και κωδικοποιήσεις που θέλετε να χρησιμοποιήσετε για τη σύνδεση με διακομιστές IRC. Πατήστε 'Next' για να πάρετε περισσότερα πεδία να συμπληρώσετε. Πατήστε 'Complete' για να αποθηκεύσετε ρυθμίσεις."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Εισάγετε το όνομα χρήστη, κωδικοποιήσεις, τις θύρες και τους κωδικούς πρόσβασης που θέλετε να χρησιμοποιήσετε για σύνδεση με IRC διακομιστή"}. {"Erlang Jabber Server","Erlang Jabber Διακομιστής"}. {"Error","Σφάλμα"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Παράδειγμα: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Εξαίρεση από τις ταυτότητες Jabber, ή CAPTCHA πρόκληση"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Εξαγωγή δεδομένων όλων των χρηστών του διακομιστή σε PIEFXIS αρχεία (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Εξαγωγή δεδομένων των χρηστών κεντρικού υπολογιστή σε PIEFXIS αρχεία (XEP-0227):"}. {"Failed to extract JID from your voice request approval","Απέτυχε η εξαγωγή JID από την έγκριση του αιτήματος φωνής σας"}. {"Family Name","Επώνυμο"}. {"February","Φεβρουάριος"}. {"Fill in fields to search for any matching Jabber User","Συμπληρώστε τα πεδία για να αναζητήσετε οποιαδήποτε ταιριάζοντα Jabber χρήστη"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Συμπληρώστε τη φόρμα για να αναζητήσετε οποιαδήποτε Jabber χρήστη που ταιριάζει (Προσθέστε * στο τέλος τού πεδίου για να ταιριάξει σε μεγαλύτερες γραμματοσηρές)"}. {"Friday","Παρασκευή"}. {"From ~s","Από ~s"}. {"From","Από"}. {"Full Name","Ονοματεπώνυμο"}. {"Get Number of Online Users","Έκθεση αριθμού συνδεδεμένων χρηστών"}. {"Get Number of Registered Users","Έκθεση αριθμού εγγεγραμμένων χρηστών"}. {"Get User Last Login Time","Έκθεση Τελευταίας Ώρας Σύνδεσης Χρήστη"}. {"Get User Password","Έκθεση Κωδικού Πρόσβασης Χρήστη"}. {"Get User Statistics","Έκθεση Στατιστικών Χρήστη"}. {"Grant voice to this person?","Παραχώρηση φωνής σε αυτό το άτομο;"}. {"Groups","Ομάδες"}. {"Group ","Ομάδα"}. {"has been banned","έχει απαγορευθεί"}. {"has been kicked because of an affiliation change","Έχει αποβληθεί λόγω αλλαγής υπαγωγής"}. {"has been kicked because of a system shutdown","αποβλήθηκε λόγω τερματισμού συστήματος"}. {"has been kicked because the room has been changed to members-only","αποβλήθηκε επειδή η αίθουσα αλλάξε γιά μέλη μόνο"}. {"has been kicked","αποβλήθηκε "}. {" has set the subject to: "," έχει θέσει το θέμα σε: "}. {"Host","Κεντρικός Υπολογιστής"}. {"If you don't see the CAPTCHA image here, visit the web page.","Εάν δεν βλέπετε την εικόνα CAPTCHA εδώ, επισκεφθείτε την ιστοσελίδα."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Εάν θέλετε να καθορίσετε διαφορετικές θύρες, κωδικούς πρόσβασης, κωδικοποιήσεις για IRC διακομιστές, εισάγετε πληροφορίες στη μορφή '{\"irc διακομιστής\", \"κωδικοποιήσεις\", θύρα, \"κωδικός πρόσβασης\"}'. Προεπιλεγμενα αυτή η υπηρεσία χρησιμοποιεί \"~s\" κωδικοποιήση, θύρα ~p, κενό κωδικό πρόσβασης."}. {"Import Directory","Εισαγωγή κατάλογου αρχείων"}. {"Import File","Εισαγωγή αρχείων"}. {"Import user data from jabberd14 spool file:","Εισαγωγή δεδομένων χρήστη από το αρχείο σειράς jabberd14:"}. {"Import User from File at ","Εισαγωγή χρηστών από αρχείο στο "}. {"Import users data from a PIEFXIS file (XEP-0227):","Εισαγωγή δεδομένων χρηστών από ένα αρχείο PIEFXIS (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Εισαγωγή δεδομένων χρηστών από κατάλογο αρχείων σειράς jabberd14:"}. {"Import Users from Dir at ","Εισαγωγή χρηστών από κατάλογο αρχείων στο "}. {"Import Users From jabberd14 Spool Files","Εισαγωγή Χρηστών από αρχεία σειράς jabberd14"}. {"Improper message type","Ακατάλληλο είδος μηνύματος"}. {"Incorrect password","Εσφαλμένος κωδικός πρόσβασης"}. {"Invalid affiliation: ~s","Άκυρη υπαγωγή: ~s"}. {"Invalid role: ~s","Άκυρος ρόλο: ~s"}. {"IP addresses","Διευθύνσεις IP"}. {"IP","IP"}. {"IRC channel (don't put the first #)","IRC κανάλι (μην τεθεί το πρώτο #)"}. {"IRC server","Διακομιστής IRC"}. {"IRC settings","IRC Ρυθμίσεις"}. {"IRC Transport","IRC Διαβιβάσεις"}. {"IRC username","IRC όνομα χρήστη"}. {"IRC Username","IRC Όνομα χρήστη"}. {"is now known as","είναι τώρα γνωστή ως"}. {"It is not allowed to send private messages of type \"groupchat\"","Δεν επιτρέπεται να στείλει προσωπικά μηνύματα του τύπου \"groupchat\""}. {"It is not allowed to send private messages to the conference","Δεν επιτρέπεται να στείλει προσωπικά μηνύματα για τη διάσκεψη"}. {"It is not allowed to send private messages","Δεν επιτρέπεται η αποστολή προσωπικών μηνυμάτων"}. {"Jabber Account Registration","Εγγραφή λογαριασμού Jabber"}. {"Jabber ID ~s is invalid","Η Jabber Ταυτότητα ~s είναι άκυρη"}. {"Jabber ID","Ταυτότητα Jabber"}. {"January","Ιανουάριος"}. {"Join IRC channel","Είσοδος στο IRC κανάλι"}. {"joins the room","συνδέετε στην αίθουσα"}. {"Join the IRC channel here.","Είσοδος στο κανάλι IRC εδώ."}. {"Join the IRC channel in this Jabber ID: ~s","Είσοδος στο κανάλι IRC αυτής της Jabber Ταυτότητας: ~s"}. {"July","Ιούλιος"}. {"June","Ιούνιος"}. {"Last Activity","Τελευταία Δραστηριότητα"}. {"Last login","Τελευταία σύνδεση"}. {"Last month","Περασμένο μήνα"}. {"Last year","Πέρυσι"}. {"leaves the room","εγκαταλείπει την αίθουσα"}. {"Listened Ports at ","Παρακολουθούμενες Θύρες στο "}. {"Listened Ports","Παρακολουθούμενες Θύρες"}. {"List of modules to start","Λίστα των Module για Εκκίνηση"}. {"Low level update script","Προγράμα ενημέρωσης χαμηλού επίπεδου "}. {"Make participants list public","Κάντε κοινό τον κατάλογο συμμετεχόντων"}. {"Make room CAPTCHA protected","Κάντε την αίθουσα CAPTCHA προστατεύονομενη"}. {"Make room members-only","Κάντε την αίθουσα μόνο για μέλη"}. {"Make room moderated","Κάντε την αίθουσα εποπτεύονομενη"}. {"Make room password protected","Κάντε την αίθουσα προστατεύομενη με κωδικό πρόσβασης"}. {"Make room persistent","Κάντε αίθουσα μόνιμη"}. {"Make room public searchable","Κάντε την δημόσια αναζήτηση δυνατή για αυτή την αίθουσα"}. {"March","Μάρτιος"}. {"Maximum Number of Occupants","Μέγιστος αριθμός συμετεχόντων"}. {"Max # of items to persist","Μέγιστος αριθμός μόνιμων στοιχείων"}. {"Max payload size in bytes","Μέγιστο μέγεθος φορτίου σε bytes"}. {"May","Μάιος"}. {"Membership is required to enter this room","Απαιτείται αίτηση συμετοχής για είσοδο σε αυτή την αίθουσα"}. {"Members:","Μέλη:"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Απομνημονεύστε τον κωδικό πρόσβασής σας, ή γράψετε τον σε ένα χαρτί που είχε τοποθετηθεί σε ασφαλές μέρος. Στο Jabber δεν υπάρχει αυτοματοποιημένος τρόπος για να ανακτήσετε τον κωδικό σας αν τον ξεχάσετε."}. {"Memory","Μνήμη"}. {"Message body","Περιεχόμενο μηνυμάτως"}. {"Middle Name","Πατρώνυμο"}. {"Minimum interval between voice requests (in seconds)","Ελάχιστο χρονικό διάστημα μεταξύ αιτημάτων φωνής (σε δευτερόλεπτα)"}. {"Moderator privileges required","Aπαιτούνται προνόμια συντονιστή"}. {"moderators only","συντονιστές μόνο"}. {"Modified modules","Τροποποιημένα modules"}. {"Module","Module"}. {"Modules at ","Modules στο "}. {"Modules","Modules"}. {"Monday","Δευτέρα"}. {"Name:","Όνομα:"}. {"Name","Όνομα"}. {"Never","Ποτέ"}. {"New Password:","Νέος κωδικός πρόσβασης:"}. {"Nickname Registration at ","Εγγραφή με Ψευδώνυμο στο "}. {"Nickname ~s does not exist in the room","Ψευδώνυμο ~s δεν υπάρχει σε αυτή την αίθουσα"}. {"Nickname","Ψευδώνυμο"}. {"No body provided for announce message","Δεν προμηθεύτικε περιεχόμενο ανακοινώσης"}. {"nobody","κανείς"}. {"No Data","Κανένα στοιχείο"}. {"Node ID","Ταυτότητα Κόμβου"}. {"Node not found","Κόμβος δεν βρέθηκε"}. {"Nodes","Κόμβοι"}. {"Node ","Κόμβος"}. {"No limit","Χωρίς όριο"}. {"None","Κανένα"}. {"No resource provided","Δεν προμηθεύτικε πόρος"}. {"Not Found","Δεν Βρέθηκε"}. {"Notify subscribers when items are removed from the node","Ειδοποιηση στους συνδρομητές όταν αφαίρούντε στοιχεία από τον κόμβο"}. {"Notify subscribers when the node configuration changes","Ειδοποιηση στους συνδρομητές όταν αλλάζει η διαμόρφωση κόμβου"}. {"Notify subscribers when the node is deleted","Ειδοποιηση στους συνδρομητές όταν ο κόμβος διαγράφεται"}. {"November","Νοέμβριος"}. {"Number of occupants","Αριθμός συμετεχόντων"}. {"Number of online users","Αριθμός συνδεδεμένων χρηστών"}. {"Number of registered users","Αριθμός εγγεγραμμένων χρηστών"}. {"October","Οκτώβριος"}. {"Offline Messages:","Χωρίς Σύνδεση Μηνύματα:"}. {"Offline Messages","Χωρίς Σύνδεση Μηνύματα"}. {"OK","Όλλα Καλά"}. {"Old Password:","Παλαιός κωδικός πρόσβασης:"}. {"Online Users:","Online Χρήστες:"}. {"Online Users","Συνδεμένοι χρήστες"}. {"Online","Συνδεδεμένο"}. {"Only deliver notifications to available users","Παράδωση κοινοποιήσεων μόνο σε διαθέσιμους χρήστες"}. {"Only moderators and participants are allowed to change the subject in this room","Μόνο οι συντονιστές και οι συμμετέχοντες μπορούν να αλλάξουν το θέμα αυτής της αίθουσας"}. {"Only moderators are allowed to change the subject in this room","Μόνο οι συντονιστές μπορούν να αλλάξουν το θέμα αυτής της αίθουσας"}. {"Only moderators can approve voice requests","Μόνο οι συντονιστές μπορούν να εγκρίνουν τις αιτήσεις φωνής"}. {"Only occupants are allowed to send messages to the conference","Μόνο οι συμμετέχωντες μπορούν να στέλνουν μηνύματα στο συνέδριο"}. {"Only occupants are allowed to send queries to the conference","Μόνο οι συμετεχόντες μπορούν να στείλουν ερωτήματα στη διάσκεψη"}. {"Only service administrators are allowed to send service messages","Μόνο οι διαχειριστές των υπηρεσιών επιτρέπεται να στείλουν υπηρεσιακά μηνύματα"}. {"Options","Επιλογές"}. {"Organization Name","Όνομα Οργανισμού"}. {"Organization Unit","Μονάδα Οργανισμού"}. {"Outgoing s2s Connections:","Εξερχόμενες S2S Συνδέσεις:"}. {"Outgoing s2s Connections","Εξερχόμενες S2S Συνδέσεις"}. {"Outgoing s2s Servers:","Εξερχόμενοι S2S διακομιστές:"}. {"Owner privileges required","Aπαιτούνται προνόμια ιδιοκτήτη"}. {"Packet","Πακέτο"}. {"Password ~b","Κωδικός πρόσβασης ~b"}. {"Password Verification:","Επαλήθευση κωδικού πρόσβασης:"}. {"Password Verification","Επαλήθευση κωδικού πρόσβασης"}. {"Password","Κωδικός Πρόσβασης"}. {"Password:","Κωδικός πρόσβασης:"}. {"Path to Dir","Τοποθεσία κατάλογου αρχείων"}. {"Path to File","Τοποθεσία Αρχείου"}. {"Pending","Εκκρεμεί"}. {"Period: ","Περίοδος: "}. {"Persist items to storage","Μονιμη αποθήκευση στοιχείων"}. {"Ping","Πινγκ"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Παρακαλώ σημειώστε ότι οι επιλογές αυτές θα αποθήκευσουν Αντιγράφο Ασφαλείας μόνο της ενσωματωμένης βάσης δεδομένων Mnesia. Εάν χρησιμοποιείτε το module ODBC, θα πρέπει επίσης να κάνετε χωριστά Αντιγράφο Ασφαλείας της SQL βάση δεδομένων σας ."}. {"Please, wait for a while before sending new voice request","Παρακαλώ, περιμένετε για λίγο πριν την αποστολή νέου αιτήματος φωνής"}. {"Pong","Πονγκ"}. {"Port ~b","Θύρα ~b"}. {"Port","Θύρα"}. {"Present real Jabber IDs to","Παρούσιαση πραγματικών ταυτοτήτων Jabber σε"}. {"private, ","ιδιωτικό,"}. {"Protocol","Πρωτόκολλο"}. {"Publish-Subscribe","Δημοσίευση-Εγγραφή"}. {"PubSub subscriber request","Αίτηση συνδρομητή Δημοσίευσης-Εγγραφής"}. {"Purge all items when the relevant publisher goes offline","Διαγραφή όλων των στοιχείων όταν ο σχετικός εκδότης αποσυνδέεται"}. {"Queries to the conference members are not allowed in this room","Ερωτήματα πρώς τα μέλη της διασκέψεως δεν επιτρέπονται σε αυτήν την αίθουσα"}. {"RAM and disc copy","Αντίγραφο μόνο σε RAM καί δίσκο"}. {"RAM copy","Αντίγραφο σε RAM"}. {"Raw","Ακατέργαστο"}. {"Really delete message of the day?","Πραγματικά να διαγράψετε το μήνυμα της ημέρας;"}. {"Recipient is not in the conference room","Παραλήπτης δεν είναι στην αίθουσα συνεδριάσεων"}. {"Register a Jabber account","Καταχωρήστε έναν λογαριασμό Jabber"}. {"Registered Users:","Εγγεγραμμένοι Χρήστες:"}. {"Registered Users","Εγγεγραμμένοι Χρήστες"}. {"Register","Καταχωρήστε"}. {"Registration in mod_irc for ","Εγγραφή στο mod_irc για "}. {"Remote copy","Απομεμακρυσμένο αντίγραφο"}. {"Remove All Offline Messages","Αφαίρεση Όλων των Χωρίς Σύνδεση Μηνύματων"}. {"Remove User","Αφαίρεση χρήστη"}. {"Remove","Αφαίρεστε"}. {"Replaced by new connection","Αντικαταστάθικε από νέα σύνδεση"}. {"Resources","Πόροι"}. {"Restart Service","Επανεκκίνηση Υπηρεσίας"}. {"Restart","Επανεκκίνηση"}. {"Restore Backup from File at ","Επαναφορά Αντιγράφου Ασφαλείας από αρχείο στο "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Επαναφορά δυαδικού αντιγράφου ασφαλείας μετά την επόμενη επανεκκίνηση του ejabberd (απαιτεί λιγότερη μνήμη):"}. {"Restore binary backup immediately:","Επαναφορά δυαδικού αντιγράφου ασφαλείας αμέσως:"}. {"Restore plain text backup immediately:","Επαναφορά αντιγράφου ασφαλείας από αρχείο κειμένου αμέσως:"}. {"Restore","Επαναφορά Αντιγράφου Ασφαλείας"}. {"Room Configuration","Διαμόρφωση Αίθουσας σύνεδριασης"}. {"Room creation is denied by service policy","Άρνηση δημιουργίας αίθουσας , λόγω τακτικής παροχής υπηρεσιών"}. {"Room description","Περιγραφή Αίθουσας"}. {"Room Occupants","Συμετεχόντες Αίθουσας σύνεδριασης"}. {"Room title","Τίτλος Αίθουσας "}. {"Roster groups allowed to subscribe","Ομάδες Καταλόγου Επαφών μπορούν να εγγραφούν"}. {"Roster of ","Καταλόγος Επαφών τού"}. {"Roster size","Μέγεθος Καταλόγου Επαφών"}. {"Roster","Καταλόγος Επαφών"}. {"RPC Call Error","Σφάλμα RPC Κλήσης"}. {"Running Nodes","Ενεργοί Κόμβοι"}. {"~s access rule configuration","~s διαμόρφωση κανόνα πρόσβασης"}. {"Saturday","Σάββατο"}. {"Script check","Script ελέγχου"}. {"Search Results for ","Αποτελέσματα αναζήτησης για "}. {"Search users in ","Αναζήτηση χρηστών στο"}. {"Send announcement to all online users on all hosts","Αποστολή ανακοίνωσης σε όλους τους συνδεδεμένους χρήστες σε όλους τους κεντρικούς υπολογιστές"}. {"Send announcement to all online users","Αποστολή ανακοίνωσης σε όλους τους συνδεδεμένους χρήστες"}. {"Send announcement to all users on all hosts","Αποστολή ανακοίνωσης σε όλους τους χρήστες σε όλους τους κεντρικούς υπολογιστές"}. {"Send announcement to all users","Αποστολή ανακοίνωσης σε όλους τους χρήστες"}. {"September","Σεπτέμβριος"}. {"Server ~b","Διακομιστής ~b"}. {"Server:","Διακομιστής:"}. {"Set message of the day and send to online users","Ορίστε μήνυμα ημέρας και αποστολή στους συνδεδεμένους χρήστες"}. {"Set message of the day on all hosts and send to online users","Ορίστε μήνυμα ημέρας και άμεση αποστολή στους συνδεδεμένους χρήστες σε όλους τους κεντρικούς υπολογιστές"}. {"Shared Roster Groups","Κοινές Ομάδες Καταλόγων Επαφών"}. {"Show Integral Table","Δείτε Ολοκληρωτικό Πίνακα"}. {"Show Ordinary Table","Δείτε Κοινό Πίνακα"}. {"Shut Down Service","Κλείσιμο Υπηρεσίας"}. {"~s invites you to the room ~s","~s σας προσκαλεί στην αίθουσα ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Μερικοί πελάτες Jabber μπορεί να αποθηκεύσουν τον κωδικό πρόσβασής σας στον υπολογιστή σας. Χρησιμοποιήστε αυτό το χαρακτηριστικό μόνο εάν εμπιστεύεστε την ασφάλεια του υπολογιστή σας."}. {"Specify the access model","Καθορίστε το μοντέλο πρόσβασης"}. {"Specify the event message type","Καθορίστε τον τύπο μηνύματος συμβάντος"}. {"Specify the publisher model","Καθορίστε το μοντέλο εκδότη"}. {"~s's Offline Messages Queue","Η Σειρά Χωρίς Σύνδεση Μηνύματων τού ~s"}. {"Start Modules at ","Εκκίνηση Modules στο "}. {"Start Modules","Εκκίνηση Modules"}. {"Start","Εκκίνηση"}. {"Statistics of ~p","Στατιστικές του ~p"}. {"Statistics","Στατιστικές"}. {"Stop Modules at ","Παύση Modules στο "}. {"Stop Modules","ΠαύσηModules"}. {"Stopped Nodes","Σταματημένοι Κόμβοι"}. {"Stop","Σταμάτημα"}. {"Storage Type","Τύπος Αποθήκευσης"}. {"Store binary backup:","Αποθηκεύση δυαδικού αντιγράφου ασφαλείας:"}. {"Store plain text backup:","Αποθηκεύση αντιγράφου ασφαλείας σε αρχείο κειμένου:"}. {"Subject","Θέμα"}. {"Submitted","Υποβλήθηκε"}. {"Submit","Υποβοβολή"}. {"Subscriber Address","Διεύθυνση Συνδρομητή"}. {"Subscription","Συνδρομή"}. {"Sunday","Κυριακή"}. {"That nickname is already in use by another occupant","Αυτό το ψευδώνυμο είναι ήδη σε χρήση από άλλον συμμετέχων"}. {"That nickname is registered by another person","Αυτό το ψευδώνυμο είναι καταχωρημένο από άλλο πρόσωπο"}. {"The CAPTCHA is valid.","Το CAPTCHA είναι έγκυρο."}. {"The CAPTCHA verification has failed","Η επαλήθευση της εικόνας CAPTCHA απέτυχε"}. {"The collections with which a node is affiliated","Οι συλλογές με την οποία είναι ένας κόμβος συνδέεται"}. {"The password is too weak","Ο κωδικός πρόσβασης είναι πολύ ασθενές"}. {"the password is","ο κωδικός πρόσβασης είναι"}. {"The password of your Jabber account was successfully changed.","Ο κωδικός πρόσβασης του Jabber λογαριασμού σας έχει αλλάξει επιτυχώς."}. {"There was an error changing the password: ","Υπήρξε ένα σφάλμα κατά την αλλαγή του κωδικού πρόσβασης:"}. {"There was an error creating the account: ","Υπήρξε ένα σφάλμα κατά τη δημιουργία του λογαριασμού:"}. {"There was an error deleting the account: ","Υπήρξε ένα σφάλμα κατά τη διαγραφή του λογαριασμού:"}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Ανεξαρτήτως με πεζά ή κεφαλαία: 'μιαλεξη' είναι το ίδιο με 'ΜιαΛέξη' και 'Μιαλέξη'."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Αυτή η σελίδα σας επιτρέπει να δημιουργήσετε ένα λογαριασμό Jabber σε αυτόν το διακομιστή Jabber. JID σας (Jabber Identifier) θα είναι της μορφής: όνομα_χρήστη@διακομιστής_Jabber. Παρακαλώ διαβάστε προσεκτικά τις οδηγίες για να συμπληρώσετε σωστά τα πεδία."}. {"This page allows to unregister a Jabber account in this Jabber server.","Η σελίδα αυτή δίνει τη δυνατότητα να καταργήσετε την καταχώρηση ενός λογαριασμό Jabber σε αυτόν το διακομιστή Jabber."}. {"This participant is kicked from the room because he sent an error message to another participant","Αυτός ο συμμετέχων αποβλήθηκε από την αίθουσα, επειδή έστειλε ένα μήνυμα σφάλματος σε άλλον συμμετέχων"}. {"This participant is kicked from the room because he sent an error message","Αυτός ο συμμετέχων αποβλήθηκε από την αίθουσα, επειδή έστειλε ένα μήνυμα σφάλματος"}. {"This participant is kicked from the room because he sent an error presence","Αυτός ο συμμετέχων αποβλήθηκε από την αίθουσα, επειδή έστειλε σφάλμα παρουσίας "}. {"This room is not anonymous","Η αίθουσα αυτή δεν είναι ανώνυμη"}. {"Thursday","Πέμπτη"}. {"Time delay","Χρόνος καθυστέρησης"}. {"Time","Χρόνος"}. {"Too many CAPTCHA requests","Πάρα πολλά αιτήματα CAPTCHA"}. {"To ~s","Πρώς ~s"}. {"To","Πρώς"}. {"Traffic rate limit is exceeded","Υπέρφορτωση"}. {"Transactions Aborted:","Αποτυχημένες συναλλαγές:"}. {"Transactions Committed:","Παραδοθείς συναλλαγές:"}. {"Transactions Logged:","Καταγραμμένες συναλλαγές:"}. {"Transactions Restarted:","Επανειλημμένες συναλλαγές:"}. {"Tuesday","Τρίτη"}. {"Unable to generate a CAPTCHA","Αδήνατο να δημιουργηθεί CAPTCHA"}. {"Unauthorized","Χορίς Εξουσιοδότηση"}. {"Unregister a Jabber account","Καταργήστε την εγγραφή ενός λογαριασμού Jabber"}. {"Unregister","Καταργήση εγγραφής"}. {"Update message of the day (don't send)","Ενημέρωση μηνύματως ημέρας (χωρίς άμεση αποστολή)"}. {"Update message of the day on all hosts (don't send)","Ενημέρωση μηνύματως ημέρας σε όλους τους κεντρικούς υπολογιστές (χωρίς άμεση αποστολή)"}. {"Update plan","Σχέδιο ενημέρωσης"}. {"Update script","Προγράμα ενημέρωσης"}. {"Update ","Ενημέρωση"}. {"Update","Ενημέρωση"}. {"Uptime:","Uptime:"}. {"Use of STARTTLS required","Απαιτείται χρήση STARTTLS "}. {"User JID","JID Χρήστη"}. {"User Management","Διαχείριση χρηστών"}. {"Username:","Όνομα χρήστη"}. {"Users are not allowed to register accounts so quickly","Οι χρήστες δεν επιτρέπεται να εγγραφούν λογαριασμούς τόσο γρήγορα"}. {"Users Last Activity","Τελευταία Δραστηριότητα Χρήστη"}. {"Users","Χρήστες"}. {"User ","Χρήστης"}. {"User","Χρήστης"}. {"Validate","Επαληθεύστε"}. {"vCard User Search","vCard Αναζήτηση χρηστών"}. {"Virtual Hosts","εικονικοί κεντρικοί υπολογιστές"}. {"Visitors are not allowed to change their nicknames in this room","Οι επισκέπτες δεν επιτρέπεται να αλλάξουν τα ψευδώνυμα τους σε αυτή την αίθουσα"}. {"Visitors are not allowed to send messages to all occupants","Οι επισκέπτες δεν επιτρέπεται να στείλουν μηνύματα σε όλους τους συμμετέχωντες"}. {"Voice requests are disabled in this conference","Τα αιτήματα φωνής είναι απενεργοποιημένα, σε αυτό το συνέδριο"}. {"Voice request","Αίτημα φωνής"}. {"Wednesday","Τετάρτη"}. {"When to send the last published item","Πότε να αποσταλθεί το τελευταίο στοιχείο που δημοσιεύθηκε"}. {"Whether to allow subscriptions","Εάν επιτρέποντε συνδρομές"}. {"You can later change your password using a Jabber client.","Μπορείτε αργότερα να αλλάξετε τον κωδικό πρόσβασής σας χρησιμοποιώντας έναν πελάτη Jabber."}. {"You have been banned from this room","Σας έχει απαγορευθεί η είσοδος σε αυτή την αίθουσα"}. {"You must fill in field \"Nickname\" in the form","Θα πρέπει να συμπληρώσετε το πεδίο \"Ψευδώνυμο\" στη φόρμα"}. {"You need a client that supports x:data and CAPTCHA to register","Χρειάζεστε ένα x:data και CAPTCHA ικανό πελάτη για εγγραφή"}. {"You need a client that supports x:data to register the nickname","Χρειάζεστε ένα x:data ικανό πελάτη για εγγραφή με ψευδώνυμο"}. {"You need an x:data capable client to configure mod_irc settings","Χρειάζεστε ένα x:data ικανό πελάτη για να ρυθμίσετε το mod_irc"}. {"You need an x:data capable client to configure room","Χρειάζεστε ένα x:data ικανό πελάτη για να ρυθμίσετε την αίθουσα "}. {"You need an x:data capable client to search","Χρειάζεστε ένα x:data ικανό πελάτη για αναζήτηση"}. {"Your active privacy list has denied the routing of this stanza.","Ο ενεργός κατάλογος απορρήτου, έχει αρνηθεί τη δρομολόγηση αυτής της στροφής (stanza)."}. {"Your contact offline message queue is full. The message has been discarded.","Η μνήμη χωρίς σύνδεση μήνυματών είναι πλήρης. Το μήνυμα έχει απορριφθεί."}. {"Your Jabber account was successfully created.","Ο Jabber λογαριασμός σας δημιουργήθηκε με επιτυχία."}. {"Your Jabber account was successfully deleted.","Ο Jabber λογαριασμός σας διαγράφηκε με επιτυχία."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Τα μηνύματά σας πρως ~s είναι αποκλεισμένα. Για αποδεσμεύση, επισκεφθείτε ~s"}. ejabberd-2.1.11/src/msgs/gl.po0000664000000000000000000015226012240230175012726 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "Last-Translator: Carlos E. Lopez - suso AT jabber-hispano.org\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Galician (galego)\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "É obrigatorio usar STARTTLS" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Non se proporcionou recurso" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Substituído por unha nova conexión" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Introduza o texto que ves" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "As súas mensaxes a ~s encóntranse bloqueadas. Para desbloquear, visite ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "O CAPTCHA é válido." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Comandos" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Está seguro de quere borrar a mensaxe do dia?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Asunto" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Corpo da mensaxe" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Non se proporcionou corpo de mensaxe para o anuncio" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Anuncios" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Enviar anuncio a todos os usuarios" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Enviar anuncio a todos os usuarios en todos os dominios" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Enviar anuncio a todos los usuarios conectados" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Enviar anuncio a todos os usuarios conectados en todos os dominios" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Pór mensaxe do dia e enviar a todos os usuarios conectados" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Pór mensaxe do día en todos os dominios e enviar aos usuarios conectados" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Actualizar mensaxe do dia, pero non envialo" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Actualizar a mensaxe do día en todos os dominos (pero non envialo)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Borrar mensaxe do dia" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Borrar a mensaxe do día en todos os dominios" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Configuración" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Base de datos" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Iniciar módulos" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Detener módulos" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Gardar copia de seguridade" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Restaurar" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Exportar a ficheiro de texto" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Importar ficheiro" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Importar directorio" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Reiniciar o servizo" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Deter o servizo" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Engadir usuario" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Borrar usuario" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Pechar sesión de usuario" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Ver contrasinal de usuario" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Cambiar contrasinal de usuario" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Ver data da última conexión de usuario" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Ver estatísticas de usuario" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Ver número de usuarios rexistrados" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Ver número de usuarios conectados" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Listas de Control de Acceso" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Regras de Acceso" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Administración de usuarios" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Usuarios conectados" #: mod_configure.erl:501 msgid "All Users" msgstr "Todos os usuarios" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Conexións S2S saíntes" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Nodos funcionando" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Nodos detidos" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Módulos" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Xestión de copia de seguridade" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importar usuarios de ficheiros spool de jabberd-1.4" #: mod_configure.erl:699 msgid "To ~s" msgstr "A ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "De ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Configuración de táboas da base de datos en " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Selecciona tipo de almacenamento das táboas" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Copia en disco soamente" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Copia en RAM e disco" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Copia en RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Copia remota" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Deter módulos en " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Selecciona módulos a deter" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Iniciar módulos en " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Introduce lista de {Módulo, [Opcións]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Lista de módulos a iniciar" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Copia de seguridade de arquivos en " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Introduce ruta ao ficheiro de copia de seguridade" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Ruta ao ficheiro" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Restaura copia de seguridade desde o ficheiro en " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Exporta copia de seguridade a ficheiro de texto en " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Introduce ruta ao ficheiro de texto" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importa usuario desde ficheiro en " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Introduce ruta ao ficheiro jabberd14 spool" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importar usuarios desde o directorio en " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Introduce a ruta ao directorio de jabberd14 spools" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Ruta ao directorio" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Atraso temporal" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Configuración da Lista de Control de Acceso" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Listas de Control de Acceso" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Configuración de accesos" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Regras de acceso" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Contrasinal" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Verificación da contrasinal" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Número de usuarios rexistrados" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Número de usuarios conectados" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Nunca" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Conectado" #: mod_configure.erl:1701 msgid "Last login" msgstr "Última conexión" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Tamaño da lista de contactos" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "Direccións IP" #: mod_configure.erl:1724 msgid "Resources" msgstr "Recursos" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Administración de " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Acción no usuario" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Editar propiedades" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Eliminar usuario" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Acceso denegado pola política do servizo" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "Transporte IRC" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "Módulo de IRC para ejabberd" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "Necesitas un cliente con soporte de x:data para configurar as opcións de " "mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Rexistro en mod_irc para" #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Introduza o nome de usuario, codificaciones de carácter, portos e " "contrasinal que pretende utilizar a conectar a servidores de IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Nome de usuario en IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Se quere especificar codificaciones de caracteres diferentes, contrasinal ou " "servidor IRC rechea esta lista con valores no formato '{\"servidor irc\", " "\"codificación\", \"porto\", \"contrasinal\"}'. Este servizo utiliza por " "defecto a codificación \"~s\", porto ~p, sen contrasinal." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Exemplo: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Parámetros de conexiones" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Entrar en canle IRC" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "Canle de IRC (non poñer o primeiro #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "Servidor IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Únete á canle de IRC aquí." #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Únete á canle de IRC con este IDE de Jabber: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "IRC axustes" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Introduce o nome de usuario e codificaciones de carácteres que queiras usar " "ao conectar nos servidores de IRC. Presione 'Siguiente' para obtener más " "campos para rellenar Presione 'completo' para guardar axustes." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "Nome de usuario en IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Contrasinal ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Porto ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Codificación de servidor ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Servidor ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" "Só os administradores do servizo teñen permiso para enviar mensaxes de " "servizo" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Denegar crear a sala por política do servizo" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "A sala de conferencias non existe" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Salas de charla" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 #, fuzzy msgid "You need a client that supports x:data to register the nickname" msgstr "" "Necesitas un cliente con soporte de x:data para poder rexistrar o alcume" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Rexistro do alcume en " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Introduce o alcume que queiras rexistrar" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Alcume" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "O alcume xa está rexistrado por outra persoa" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Debes encher o campo \"Alcumo\" no formulario" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "Módulo de MUC para ejabberd" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Configuración de la sala modificada" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "entra en la sala" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "sae da sala" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "foi bloqueado" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "foi expulsado" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "foi expulsado debido a un cambio de afiliación" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "foi expulsado, porque a sala cambiouse a só-membros" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "foi expulsado por mor dun sistema de peche" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "cámbiase o nome a" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " puxo o asunto: " #: mod_muc/mod_muc_log.erl:452 #, fuzzy msgid "Chatroom is created" msgstr "Salas de charla" #: mod_muc/mod_muc_log.erl:453 #, fuzzy msgid "Chatroom is destroyed" msgstr "Salas de charla" #: mod_muc/mod_muc_log.erl:454 #, fuzzy msgid "Chatroom is started" msgstr "Salas de charla" #: mod_muc/mod_muc_log.erl:455 #, fuzzy msgid "Chatroom is stopped" msgstr "Salas de charla" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Luns" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Martes" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Mércores" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Xoves" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Venres" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Sábado" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Domingo" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Xaneiro" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Febreiro" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Marzo" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "Abril" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Maio" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Xuño" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Xullo" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Agosto" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "Setembro" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Outubro" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "Novembro" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "Decembro" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Configuración da Sala" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Ocupantes da sala" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Hase exedido o límite de tráfico" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Este participante é expulsado da sala, xa que enviou unha mensaxe de erro" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Impedir o envio de mensaxes privadas á sala" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Tipo de mensaxe incorrecta" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Este participante é expulsado da sala, porque el enviou unha mensaxe de erro " "a outro participante" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "Non está permitido enviar mensaxes privadas do tipo \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "O receptor non está na sala de conferencia" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Non está permitido enviar mensaxes privadas" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Só os ocupantes poden enviar mensaxes á sala" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Só os ocupantes poden enviar solicitudes á sala" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "Nesta sala non se permiten solicitudes aos membros da sala" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Só os moderadores e os participantes se lles permite cambiar o tema nesta " "sala" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Só os moderadores están autorizados a cambiar o tema nesta sala" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Os visitantes non poden enviar mensaxes a todos os ocupantes" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Este participante é expulsado da sala, porque el enviou un erro de presenza" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "" "Os visitantes non están autorizados a cambiar os seus That alcumes nesta sala" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Ese alcume que xa está en uso por outro ocupante" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "fuches bloqueado nesta sala" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Necesitas ser membro desta sala para poder entrar" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Sala non anónima" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Necesítase contrasinal para entrar nesta sala" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 #, fuzzy msgid "Unable to generate a CAPTCHA" msgstr "Non se pode xerar un CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Contrasinal incorrecta" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Necesítase privilexios de administrador" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Necesítase privilexios de moderador" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "O Jabber ID ~s non é válido" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "O alcume ~s non existe na sala" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Afiliación non válida: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Rol non válido: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Requírense privilexios de propietario da sala" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Configuración para a sala ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Título da sala" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Descrición da sala" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Sala permanente" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Sala publicamente visible" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "A lista de participantes é pública" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Protexer a sala con contrasinal" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Número máximo de ocupantes" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Sen límite" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Os Jabber ID reais poden velos" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "só moderadores" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "calquera" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Sala só para membros" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Facer sala moderada" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Os usuarios son participantes por defecto" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Permitir aos usuarios cambiar o asunto" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Permitir aos usuarios enviar mensaxes privadas" #: mod_muc/mod_muc_room.erl:3279 #, fuzzy msgid "Allow visitors to send private messages to" msgstr "Permitir aos usuarios enviar mensaxes privadas" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Permitir aos usuarios consultar a outros usuarios" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Permitir aos usuarios enviar invitacións" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "" "Permitir aos visitantes enviar texto de estado nas actualizacións depresenza" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Permitir aos visitantes cambiarse o alcume" #: mod_muc/mod_muc_room.erl:3308 #, fuzzy msgid "Allow visitors to send voice requests" msgstr "Permitir aos usuarios enviar invitacións" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Protexer a sala con CAPTCHA" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Gardar históricos" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Necesitas un cliente con soporte de x:data para configurar a sala" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Número de ocupantes" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privado" #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "" #: mod_muc/mod_muc_room.erl:3809 #, fuzzy msgid "User JID" msgstr "Usuario " #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s invítache á sala ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "a contrasinal é" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "A túa cola de mensaxes diferidas de contactos está chea. A mensaxe " "descartouse." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "Cola de mensaxes diferidas de ~s" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Enviado" #: mod_offline.erl:571 msgid "Time" msgstr "Data" #: mod_offline.erl:572 msgid "From" msgstr "De" #: mod_offline.erl:573 msgid "To" msgstr "Para" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Paquete" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Eliminar os seleccionados" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Mensaxes sen conexión:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Borrar Todas as Mensaxes Sen conexión" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestreams module" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Publicar-Subscribir" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "Módulo de Publicar-Subscribir de ejabberd" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Petición de subscriptor de PubSub" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Decidir se aprobar a subscripción desta entidade." #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "Nodo IDE" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Dirección do subscriptor" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Desexas permitir a este JabberID que se subscriba a este nodo PubSub?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Enviar payloads xunto coas notificacións de eventos" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Entregar notificacións de eventos" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Notificar subscriptores cando cambia a configuración do nodo" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Notificar subscriptores cando o nodo bórrase" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Notificar subscriptores cando os elementos bórranse do nodo" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Persistir elementos ao almacenar" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Un nome para o nodo" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Máximo # de elementos que persisten" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Permitir subscripciones" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Especifica o modelo de acceso" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Lista de grupos autorizados a subscribir" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Especificar o modelo do publicante" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 #, fuzzy msgid "Specify the event message type" msgstr "Especifica o modelo de acceso" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Máximo tamaño do payload en bytes" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Cando enviar o último elemento publicado" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Só enviar notificacións aos usuarios dispoñibles" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "As coleccións coas que un nodo está afiliado" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "" #: mod_register.erl:220 #, fuzzy msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "Necesitas un cliente con soporte de x:data para poder rexistrar o alcume" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "" "Escolle un nome de usuario e contrasinal para rexistrarche neste servidor" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Usuario" #: mod_register.erl:316 mod_register.erl:361 #, fuzzy msgid "The password is too weak" msgstr "a contrasinal é" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Os usuarios non están autorizados a rexistrar contas con tanta rapidez" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Ningún" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Subscripción" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Pendente" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Grupos" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Validar" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Borrar" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Lista de contactos de " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Mal formato" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Engadir ID Jabber" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Lista de contactos" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Grupos Compartidos" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Engadir novo" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Nome:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Descrición:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Membros:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Mostrar grupos:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Grupo " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Enviar" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Servidor Jabber en Erlang" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Aniversario" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Cidade" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "País" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Email" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Apelido" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Enche o formulario para buscar usuarios Jabber. Engade * ao final dun campo " "para buscar subcadenas." #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Nome completo" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Segundo nome" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Nome" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Nome da organización" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Unidade da organización" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Buscar usuarios en " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Necesitas un cliente con soporte de x:data para poder buscar" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Procura de usuario en vCard" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "Módulo vCard para ejabberd" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Buscar resultados por " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Rechea campos para buscar usuarios Jabber que concuerden" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Non autorizado" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "Ejabberd Administrador Web" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Administración" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Cru" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Configuración das Regra de Acceso ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Hosts Virtuais" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Usuarios" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Última actividade dos usuarios" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Periodo: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Último mes" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Último ano" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Toda a actividade" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Mostrar Táboa Ordinaria" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Mostrar Táboa Integral" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Estatísticas" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Non atopado" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Nodo non atopado" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Host" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Usuarios rexistrados" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Mensaxes diferidas" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Última actividade" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Usuarios rexistrados:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Usuarios conectados:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Conexións S2S saíntes:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Servidores S2S saíntes:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Cambiar contrasinal" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Usuario " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Recursos conectados:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Contrasinal:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Sen datos" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Nodos" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Nodo " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Portos de escoita" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Actualizar" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Reiniciar" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Deter" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Erro na chamada RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Táboas da base de datos en " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Tipo de almacenamiento" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Elementos" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Memoria" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Erro" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Copia de seguridade de " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Ten en conta que estas opcións só farán copia de seguridade da base de datos " "Mnesia. Se está a utilizar o módulo de ODBC, tamén necesita unha copia de " "seguridade da súa base de datos SQL por separado." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Gardar copia de seguridade binaria:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "Aceptar" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Restaurar inmediatamente copia de seguridade binaria:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Restaurar copia de seguridade binaria no seguinte reinicio de ejabberd " "(require menos memoria que se instantánea):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Gardar copia de seguridade en texto plano:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Restaurar copias de seguridade de texto plano inmediatamente:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Importar usuarios desde un fichero PIEFXIS" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Exportar datos de todos os usuarios do servidor a ficheros PIEFXIS " "(XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" "Exportar datos de todos os usuarios do servidor a ficheros PIEFXIS " "(XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importar usuario de fichero spool de jabberd14:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importar usuarios do directorio spool de jabberd14:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Portos de escoita en " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Módulos en " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Estatísticas de ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Tempo desde o inicio:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Tempo consumido de CPU:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transaccións finalizadas:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transaccións abortadas:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transaccións reiniciadas:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transaccións rexistradas:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Actualizar" #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Plan de actualización" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Módulos Modificados" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Script de actualización" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Script de actualización a baixo nivel" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Comprobación de script" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Porto" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protocolo" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Módulo" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Opcións" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Eliminar" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Iniciar" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "" #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "" #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "" #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 #, fuzzy msgid "Username:" msgstr "Nome de usuario en IRC" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 #, fuzzy msgid "Server:" msgstr "Servidor ~b" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 #, fuzzy msgid "Password Verification:" msgstr "Verificación da contrasinal" #: web/mod_register_web.erl:250 #, fuzzy msgid "Register" msgstr "Lista de contactos" #: web/mod_register_web.erl:396 #, fuzzy msgid "Old Password:" msgstr "Contrasinal:" #: web/mod_register_web.erl:401 #, fuzzy msgid "New Password:" msgstr "Contrasinal:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "" #, fuzzy #~ msgid "CAPTCHA test failed" #~ msgstr "O CAPTCHA é válido." #~ msgid "Encodings" #~ msgstr "Codificaciones" #~ msgid "(Raw)" #~ msgstr "(Cru)" #~ msgid "Specified nickname is already registered" #~ msgstr "O alcume especificado xa está rexistrado, terás que buscar outro" #~ msgid "Size" #~ msgstr "Tamaño" ejabberd-2.1.11/src/msgs/uk.msg0000664000000000000000000010730612240230175013114 0ustar {"Access Configuration","Конфігурація доступу"}. {"Access Control List Configuration","Конфігурація списків керування доступом"}. {"Access control lists","Списки керування доступом"}. {"Access Control Lists","Списки керування доступом"}. {"Access denied by service policy","Доступ заборонений політикою служби"}. {"Access rules","Правила доступу"}. {"Access Rules","Правила доступу"}. {"Action on user","Дія над користувачем"}. {"Add Jabber ID","Додати Jabber ID"}. {"Add New","Додати"}. {"Add User","Додати користувача"}. {"Administration of ","Адміністрування "}. {"Administration","Адміністрування"}. {"Administrator privileges required","Необхідні права адміністратора"}. {"A friendly name for the node","Псевдонім для вузла"}. {"All activity","Вся статистика"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Чи дозволити цьому Jabber ID підписатись новини наданого вузла"}. {"Allow users to change the subject","Дозволити користувачам змінювати тему"}. {"Allow users to query other users","Дозволити iq-запити до користувачів"}. {"Allow users to send invites","Дозволити користувачам надсилати запрошення"}. {"Allow users to send private messages","Дозволити приватні повідомлення"}. {"Allow visitors to change nickname","Дозволити відвідувачам змінювати псевдонім"}. {"Allow visitors to send status text in presence updates","Дозволити відвідувачам відсилати текст статусу в оновленнях присутності"}. {"All Users","Всі користувачі"}. {"Announcements","Сповіщення"}. {"anyone","всім учасникам"}. {"A password is required to enter this room","Щоб зайти в цю конференцію, необхідно ввести пароль"}. {"April","квітня"}. {"August","серпня"}. {"Backup Management","Керування резервним копіюванням"}. {"Backup of ","Резервне копіювання "}. {"Backup to File at ","Резервне копіювання в файл на "}. {"Backup","Резервне копіювання"}. {"Bad format","Неправильний формат"}. {"Birthday","День народження"}. {"CAPTCHA web page","Адреса капчі"}. {"Change Password","Змінити пароль"}. {"Change User Password","Змінити Пароль Користувача"}. {"Characters not allowed:","Заборонені символи:"}. {"Chatroom configuration modified","Конфігурація кімнати змінилась"}. {"Chatroom is created","Створено кімнату"}. {"Chatroom is destroyed","Знищено кімнату"}. {"Chatroom is started","Запущено кімнату"}. {"Chatroom is stopped","Зупинено кімнату"}. {"Chatrooms","Кімнати"}. {"Choose a username and password to register with this server","Виберіть назву користувача та пароль для реєстрації на цьому сервері"}. {"Choose modules to stop","Виберіть модулі, які необхідно зупинити"}. {"Choose storage type of tables","Оберіть тип збереження таблиць"}. {"Choose whether to approve this entity's subscription.","Вирішіть, чи задовольнити запит цього об'єкту на підписку"}. {"City","Місто"}. {"Commands","Команди"}. {"Conference room does not exist","Конференція не існує"}. {"Configuration of room ~s","Конфігурація кімнати ~s"}. {"Configuration","Конфігурація"}. {"Connected Resources:","Підключені ресурси:"}. {"Connections parameters","Параметри з'єднання"}. {"Country","Країна"}. {"CPU Time:","Процесорний час:"}. {"Database Tables at ","Таблиці бази даних на "}. {"Database Tables Configuration at ","Конфігурація таблиць бази даних на "}. {"Database","База даних"}. {"December","грудня"}. {"Default users as participants","Зробити користувачів учасниками за замовчуванням"}. {"Delete message of the day on all hosts","Видалити повідомлення дня на усіх хостах"}. {"Delete message of the day","Видалити повідомлення дня"}. {"Delete Selected","Видалити виділені"}. {"Delete User","Видалити Користувача"}. {"Delete","Видалити"}. {"Deliver event notifications","Доставляти сповіщення про події"}. {"Deliver payloads with event notifications","Доставляти разом з повідомленнями про публікації самі публікації"}. {"Description:","Опис:"}. {"Disc only copy","Тільки диск"}. {"Displayed Groups:","Видимі групи:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Нікому не кажіть свій пароль, навіть адміністраторам сервера."}. {"Dump Backup to Text File at ","Копіювання в текстовий файл на "}. {"Dump to Text File","Копіювання в текстовий файл"}. {"Edit Properties","Змінити параметри"}. {"ejabberd IRC module","ejabberd IRC модуль"}. {"ejabberd MUC module","ejabberd MUC модуль"}. {"ejabberd Publish-Subscribe module","Модуль ejabberd Публікації-Підписки"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams модуль"}. {"ejabberd vCard module","ejabberd vCard модуль"}. {"ejabberd Web Admin","Веб-інтерфейс Адміністрування ejabberd"}. {"Elements","Елементи"}. {"Email","Електронна пошта"}. {"Enable logging","Включити журнал роботи"}. {"Encoding for server ~b","Кодування для сервера ~b"}. {"End User Session","Закінчити Сеанс Користувача"}. {"Enter list of {Module, [Options]}","Введіть перелік такого виду {Module, [Options]}"}. {"Enter nickname you want to register","Введіть псевдонім, який ви хочете зареєструвати"}. {"Enter path to backup file","Введіть шлях до резервного файла"}. {"Enter path to jabberd14 spool dir","Введіть шлях до директорії спула jabberd14"}. {"Enter path to jabberd14 spool file","Введіть шлях до файла зі спула jabberd14"}. {"Enter path to text file","Введіть шлях до текстового файла"}. {"Enter the text you see","Введіть текст, що ви бачите"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Введіть ім'я користувача та кодування, які будуть використовуватися при підключенні до IRC-серверів Натисніть 'Далі' для заповнення додаткових полів. Натисніть 'Завершити' для збереження параметрів."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Введіть ім'я користувача, кодування, порти та паролі, що будуть використовуватися при підключенні до IRC-серверів"}. {"Erlang Jabber Server","Erlang Jabber Server"}. {"Error","Помилка"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Приклад: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Пропускати ці Jabber ID без CAPTCHA-запиту"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Експорт даних всіх користувачів сервера до файлу PIEFXIS (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Експорт даних користувачів домена до файлу PIEFXIS (XEP-0227):"}. {"Family Name","Прізвище"}. {"February","лютого"}. {"Fill in fields to search for any matching Jabber User","Заповніть поля для пошуку користувача Jabber"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Заповніть поля для пошуку користувача Jabber (Додайте * в кінець поля для пошуку підрядка)"}. {"Friday","П'ятниця"}. {"From ~s","Від ~s"}. {"From","Від кого"}. {"Full Name","Повне ім'я"}. {"Get Number of Online Users","Отримати Кількість Підключених Користувачів"}. {"Get Number of Registered Users","Отримати Кількість Зареєстрованих Користувачів"}. {"Get User Last Login Time","Отримати Час Останнього Підключення Користувача"}. {"Get User Password","Отримати Пароль Користувача"}. {"Get User Statistics","Отримати Статистику по Користувачу"}. {"Groups","Групи"}. {"Group ","Група "}. {"has been banned","заборонили вхід в кімнату"}. {"has been kicked because of an affiliation change","вигнано з кімнати внаслідок зміни рангу"}. {"has been kicked because of a system shutdown","вигнано з кімнати внаслідок зупинки системи"}. {"has been kicked because the room has been changed to members-only","вигнано з кімнати тому, що вона стала тільки для учасників"}. {"has been kicked","вигнали з кімнати"}. {" has set the subject to: "," встановив(ла) тему: "}. {"Host","Хост"}. {"If you don't see the CAPTCHA image here, visit the web page.","Якщо ви не бачите зображення капчі, перейдіть за за цією адресою."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Щоб вказати різні порти, паролі та кодування для різних серверів IRC, заповніть список значеннями в форматі '{\"irc server\", \"encoding\", port, \"password\"}'. За замовчуванням ця служба використовує \"~s\" кодування, порт ~p, пустий пароль."}. {"Import Directory","Імпорт з директорії"}. {"Import File","Імпорт з файла"}. {"Import user data from jabberd14 spool file:","Імпорт користувачів з файла спула jabberd14:"}. {"Import User from File at ","Імпортування користувача з файла на "}. {"Import users data from a PIEFXIS file (XEP-0227):","Імпорт даних користовучів з файлу PIEFXIS (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Імпорт користувачів з діректорії спула jabberd14:"}. {"Import Users from Dir at ","Імпортування користувача з директорії на "}. {"Import Users From jabberd14 Spool Files","Імпорт користувачів зі спулу jabberd14"}. {"Improper message type","Неправильний тип повідомлення"}. {"Incorrect password","Неправильний пароль"}. {"Invalid affiliation: ~s","Недопустимий ранг: ~s"}. {"Invalid role: ~s","Недопустима роль: ~s"}. {"IP addresses","IP адреси"}. {"IP","IP"}. {"IRC channel (don't put the first #)","Канал IRC (не включаючи #)"}. {"IRC server","IRC-сервер"}. {"IRC settings","Парметри IRC"}. {"IRC Transport","IRC Транспорт"}. {"IRC username","Ім'я користувача IRC"}. {"IRC Username","Ім'я користувача IRC"}. {"is now known as","змінив(ла) псевдонім на"}. {"It is not allowed to send private messages of type \"groupchat\"","Не дозволяється надсилати приватні повідомлення типу \"groupchat\""}. {"It is not allowed to send private messages to the conference","Не дозволяється надсилати приватні повідомлення в конференцію"}. {"It is not allowed to send private messages","Приватні повідомлення не дозволені"}. {"Jabber Account Registration","Реєстрація Jabber-акаунту"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Jabber ID ~s недопустимий"}. {"January","січня"}. {"Join IRC channel","Приєднатися до каналу IRC"}. {"joins the room","увійшов(ла) в кімнату"}. {"Join the IRC channel here.","Приєднатися до каналу IRC"}. {"Join the IRC channel in this Jabber ID: ~s","Приєднатися до каналу IRC з Jabber ID: ~s"}. {"July","липня"}. {"June","червня"}. {"Last Activity","Останнє підключення"}. {"Last login","Останнє підключення"}. {"Last month","За останній місяць"}. {"Last year","За останній рік"}. {"leaves the room","вийшов(ла) з кімнати"}. {"Listened Ports at ","Відкриті порти на "}. {"Listened Ports","Відкриті порти"}. {"List of modules to start","Список завантажуваних модулів"}. {"Low level update script","Низькорівневий сценарій поновлення"}. {"Make participants list public","Зробити список учасників видимим всім"}. {"Make room CAPTCHA protected","Зробити кімнату захищеною капчею"}. {"Make room members-only","Кімната тільки для зареєтрованых учасників"}. {"Make room moderated","Зробити кімнату модерованою"}. {"Make room password protected","Зробити кімнату захищеною паролем"}. {"Make room persistent","Зробити кімнату постійною"}. {"Make room public searchable","Зробити кімнату видимою всім"}. {"March","березня"}. {"Maximum Number of Occupants","Максимальна кількість учасників"}. {"Max # of items to persist","Максимальне число збережених публікацій"}. {"Max payload size in bytes","Максимальний розмір корисного навантаження в байтах"}. {"May","травня"}. {"Membership is required to enter this room","В цю конференцію можуть входити тільки її члени"}. {"Members:","Члени:"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Запам'ятайте пароль, або запишіть його на папері, який треба зберегти у безпечному місці. У Jabber'і немає автоматизованих засобів відновлення пароля на той випадок, якщо ви його забудете."}. {"Memory","Пам'ять"}. {"Message body","Тіло повідомлення"}. {"Middle Name","По-батькові"}. {"Moderator privileges required","Необхідні права модератора"}. {"moderators only","тільки модераторам"}. {"Modified modules","Змінені модулі"}. {"Modules at ","Модулі на "}. {"Modules","Модулі"}. {"Module","Модуль"}. {"Monday","Понеділок"}. {"Name:","Назва:"}. {"Name","Назва"}. {"Never","Ніколи"}. {"New Password:","Новий Пароль:"}. {"Nickname Registration at ","Реєстрація псевдоніма на "}. {"Nickname ~s does not exist in the room","Псевдонім ~s в кімнаті відсутній"}. {"Nickname","Псевдонім"}. {"No body provided for announce message","Тіло оголошення має бути непустим"}. {"No Data","Немає даних"}. {"Node ID","ID вузла"}. {"Node not found","Вузол не знайдено"}. {"Nodes","Вузли"}. {"Node ","Вузол "}. {"No limit","Без обмежень"}. {"None","Немає"}. {"No resource provided","Не вказаний ресурс"}. {"Not Found","не знайдено"}. {"Notify subscribers when items are removed from the node","Повідомляти абонентів про видалення публікацій із збірника"}. {"Notify subscribers when the node configuration changes","Повідомляти абонентів про зміни в конфігурації збірника"}. {"Notify subscribers when the node is deleted","Повідомляти абонентів про видалення збірника"}. {"November","листопада"}. {"Number of occupants","Кількість присутніх"}. {"Number of online users","Кількість підключених користувачів"}. {"Number of registered users","Кількість зареєстрованих користувачів"}. {"October","грудня"}. {"Offline Messages:","Офлайнові повідомлення:"}. {"Offline Messages","Офлайнові повідомлення"}. {"OK","Продовжити"}. {"Old Password:","Старий пароль:"}. {"Online Users:","Підключені користувачі:"}. {"Online Users","Підключені користувачі"}. {"Online","Підключений"}. {"Only deliver notifications to available users","Доставляти повідомленнями тільки доступним користувачам"}. {"Only moderators and participants are allowed to change the subject in this room","Тільки модератори та учасники можуть змінювати тему в цій кімнаті"}. {"Only moderators are allowed to change the subject in this room","Тільки модератори можуть змінювати тему в цій кімнаті"}. {"Only occupants are allowed to send messages to the conference","Тільки присутнім дозволяється надсилати повідомленняя в конференцію"}. {"Only occupants are allowed to send queries to the conference","Тільки присутнім дозволяється відправляти запити в конференцію"}. {"Only service administrators are allowed to send service messages","Тільки адміністратор сервісу може надсилати службові повідомлення"}. {"Options","Параметри"}. {"Organization Name","Назва організації"}. {"Organization Unit","Відділ організації"}. {"Outgoing s2s Connections:","Вихідні s2s-з'єднання:"}. {"Outgoing s2s Connections","Вихідні s2s-з'єднання"}. {"Outgoing s2s Servers:","Вихідні s2s-сервери:"}. {"Owner privileges required","Необхідні права власника"}. {"Packet","Пакет"}. {"Password ~b","Пароль ~b"}. {"Password Verification:","Перевірка Пароля:"}. {"Password Verification","Перевірка Пароля"}. {"Password:","Пароль:"}. {"Password","Пароль"}. {"Path to Dir","Шлях до директорії"}. {"Path to File","Шлях до файла"}. {"Pending","Очікування"}. {"Period: ","Період"}. {"Persist items to storage","Зберегати публікації до сховища"}. {"Ping","Пінг"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Зауважте, що ця опція відповідає за резервне копіювання тільки вбудованної бази даних Mnesia. Якщо Ви також використовуєте інше сховище для даних (наприклад за допомогою модуля ODBC), то його резервне копіювання потрібно робити окремо."}. {"Pong","Понг"}. {"Port ~b","Порт ~b"}. {"Port","Порт"}. {"Present real Jabber IDs to","Зробити реальні Jabber ID учасників видимими"}. {"private, ","приватна, "}. {"Protocol","Протокол"}. {"Publish-Subscribe","Публікація-Підписка"}. {"PubSub subscriber request","Запит на підписку PubSub"}. {"Purge all items when the relevant publisher goes offline","Видалити всі елементи, коли особа, що їх опублікувала, вимикається від мережі"}. {"Queries to the conference members are not allowed in this room","Запити до користувачів в цій конференції заборонені"}. {"RAM and disc copy","ОЗП та диск"}. {"RAM copy","ОЗП"}. {"Raw","необроблений формат"}. {"Really delete message of the day?","Насправді видалити повідомлення дня?"}. {"Recipient is not in the conference room","Адресата немає в конференції"}. {"Register a Jabber account","Зареєструвати Jabber-акаунт"}. {"Registered Users:","Зареєстровані користувачі:"}. {"Registered Users","Зареєстровані користувачі"}. {"Register","Реєстрація"}. {"Registration in mod_irc for ","Реєстрація в mod_irc для "}. {"Remote copy","не зберігаеться локально"}. {"Remove All Offline Messages","Видалити всі офлайнові повідомлення"}. {"Remove User","Видалити користувача"}. {"Remove","Видалити"}. {"Replaced by new connection","Замінено новим з'єднанням"}. {"Resources","Ресурси"}. {"Restart Service","Перезапустити Сервіс"}. {"Restart","Перезапустити"}. {"Restore Backup from File at ","Відновлення з резервної копії на "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Відновити з бінарної резервної копії при наступному запуску (потребує менше пам'яті):"}. {"Restore binary backup immediately:","Відновити з бінарної резервної копії негайно:"}. {"Restore plain text backup immediately:","Відновити з текстової резервної копії негайно:"}. {"Restore","Відновлення з резервної копії"}. {"Room Configuration","Конфігурація кімнати"}. {"Room creation is denied by service policy","Створювати конференцію заборонено політикою служби"}. {"Room description","Опис кімнати"}. {"Room Occupants","Учасники кімнати"}. {"Room title","Назва кімнати"}. {"Roster groups allowed to subscribe","Дозволені для підписки групи ростера"}. {"Roster of ","Ростер користувача "}. {"Roster size","Кількість контактів"}. {"Roster","Ростер"}. {"RPC Call Error","Помилка виклику RPC"}. {"Running Nodes","Працюючі вузли"}. {"~s access rule configuration","Конфігурація правила доступу ~s"}. {"Saturday","Субота"}. {"Script check","Перевірка сценарію"}. {"Search Results for ","Результати пошуку в "}. {"Search users in ","Пошук користувачів в "}. {"Send announcement to all online users on all hosts","Надіслати сповіщення всім підключеним користувачам на всіх віртуальних серверах"}. {"Send announcement to all online users","Надіслати сповіщення всім підключеним користувачам"}. {"Send announcement to all users on all hosts","Надіслати сповіщення до усіх користувачів на усіх хостах"}. {"Send announcement to all users","Надіслати сповіщення всім користувачам"}. {"September","вересня"}. {"Server ~b","Сервер ~b"}. {"Server:","Сервер:"}. {"Set message of the day and send to online users","Встановити повідомлення дня та надіслати його підключеним користувачам"}. {"Set message of the day on all hosts and send to online users","Встановити повідомлення дня на всіх хостах та надійслати його підключеним користувачам"}. {"Shared Roster Groups","Спільні групи контактів"}. {"Show Integral Table","Показати інтегральну таблицю"}. {"Show Ordinary Table","Показати звичайну таблицю"}. {"Shut Down Service","Вимкнути Сервіс"}. {"~s invites you to the room ~s","~s запрошує вас до кімнати ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Деякі Jabber-клієнти можуть зберігати пароль на вашому комп'ютері. Користуйтесь цією функцією тільки у тому випадку, якщо вважаєте її безпечною."}. {"Specify the access model","Визначити модель доступу"}. {"Specify the event message type","Вкажіть тип повідомлень зі сповіщеннями про події"}. {"Specify the publisher model","Умови публікації"}. {"~s's Offline Messages Queue","Черга офлайнових повідомлень ~s"}. {"Start Modules at ","Запуск модулів на "}. {"Start Modules","Запуск модулів"}. {"Start","Запустити"}. {"Statistics of ~p","Статистика вузла ~p"}. {"Statistics","Статистика"}. {"Stop Modules at ","Зупинка модулів на "}. {"Stop Modules","Зупинка модулів"}. {"Stopped Nodes","Зупинені вузли"}. {"Stop","Зупинити"}. {"Storage Type","Тип таблиці"}. {"Store binary backup:","Зберегти бінарну резервну копію:"}. {"Store plain text backup:","Зберегти текстову резервну копію:"}. {"Subject","Тема"}. {"Submitted","Відправлено"}. {"Submit","Відправити"}. {"Subscriber Address","Адреса абонента"}. {"Subscription","Підписка"}. {"Sunday","Неділя"}. {"That nickname is already in use by another occupant","Псевдонім зайнято кимось з присутніх"}. {"That nickname is registered by another person","Псевдонім зареєстровано кимось іншим"}. {"The CAPTCHA is valid.","Перевірку капчею закінчено успішно"}. {"The CAPTCHA verification has failed","Перевірку капчею не пройдено"}. {"The collections with which a node is affiliated","Колекція, до якої входить вузол"}. {"The password is too weak","Пароль надто простий"}. {"the password is","пароль:"}. {"The password of your Jabber account was successfully changed.","Пароль вашого Jabber-акаунту був успішно змінений."}. {"There was an error changing the password: ","Помилка при зміні пароля: "}. {"There was an error creating the account: ","Помилка при створенні акаунту:"}. {"There was an error deleting the account: ","Помилка при видаленні акаунту: "}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Регістр не має значення: \"МАША\" та \"маша\" буде сприйматися як одне й те саме ім'я."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Тут ви можете зареєструвати обліковий запис Jabber на цьому сервері. Ваш JID (ідентифікатор Jabber) матиме вигляд \"користувач@сервер\". Щоб вірно заповнити поля нижче, будь ласка, уважно читайте інструкції до них."}. {"This page allows to unregister a Jabber account in this Jabber server.","Ця сторінка дозволяє видалити свій акаунт з Jabber-сервера."}. {"This participant is kicked from the room because he sent an error message to another participant","Цього учасника було відключено від кімнати через те, що він надіслав помилкове повідомлення іншому учаснику"}. {"This participant is kicked from the room because he sent an error message","Цього учасника було відключено від кімнати через те, що він надіслав помилкове повідомлення"}. {"This participant is kicked from the room because he sent an error presence","Цього учасника було відключено від кімнати через те, що він надіслав помилковий статус присутності"}. {"This room is not anonymous","Ця кімната не анонімна"}. {"Thursday","Четвер"}. {"Time delay","Час затримки"}. {"Time","Час"}. {"Too many CAPTCHA requests","Надто багато CAPTCHA-запитів"}. {"To ~s","До ~s"}. {"To","Кому"}. {"Traffic rate limit is exceeded","Швидкість передачі інформації було перевищено"}. {"Transactions Aborted:","Транзакції відмінені:"}. {"Transactions Committed:","Транзакції завершені:"}. {"Transactions Logged:","Транзакції запротокольовані:"}. {"Transactions Restarted:","Транзакції перезапущені:"}. {"Tuesday","Вівторок"}. {"Unable to generate a CAPTCHA","Нема можливості згенерувати капчу"}. {"Unauthorized","Не авторизовано"}. {"Unregister a Jabber account","Видалити Jabber-акаунт"}. {"Unregister","Видалити"}. {"Update message of the day (don't send)","Оновити повідомлення дня (не надсилати)"}. {"Update message of the day on all hosts (don't send)","Оновити повідомлення дня на всіх хостах (не надсилати)"}. {"Update plan","План поновлення"}. {"Update script","Сценарій поновлення"}. {"Update","Обновити"}. {"Update ","Поновлення "}. {"Uptime:","Час роботи:"}. {"Use of STARTTLS required","Ви мусите використовувати STARTTLS"}. {"User Management","Управління Користувачами"}. {"Username:","Ім'я користувача:"}. {"Users are not allowed to register accounts so quickly","Користувачам не дозволено так часто реєструвати облікові записи"}. {"Users Last Activity","Статистика останнього підключення користувачів"}. {"Users","Користувачі"}. {"User ","Користувач "}. {"User","Користувач"}. {"Validate","Затвердити"}. {"vCard User Search","Пошук користувачів по vCard"}. {"Virtual Hosts","віртуальні хости"}. {"Visitors are not allowed to change their nicknames in this room","Відвідувачам не дозволяється змінювати псевдонім в цій кімнаті"}. {"Visitors are not allowed to send messages to all occupants","Відвідувачам не дозволяється надсилати повідомлення всім присутнім"}. {"Wednesday","Середа"}. {"When to send the last published item","Коли надсилати останній опублікований елемент"}. {"Whether to allow subscriptions","Дозволяти підписку"}. {"You can later change your password using a Jabber client.","Пізніше можна змінити пароль через Jabber-клієнт."}. {"You have been banned from this room","Вам заборонено входити в цю конференцію"}. {"You must fill in field \"Nickname\" in the form","Вам необхідно заповнити поле \"Псевдонім\" у формі"}. {"You need a client that supports x:data and CAPTCHA to register","Для реєстрації псевдоніму необхідно використовувати клієнт з підтримкою x:data"}. {"You need a client that supports x:data to register the nickname","Для реєстрації псевдоніму необхідно використовувати клієнт з підтримкою x:data"}. {"You need an x:data capable client to configure mod_irc settings","Для налагодження параметрів mod_irc необхідно використовувати клієнт, що має підтримку x:data"}. {"You need an x:data capable client to configure room","Для конфігурування кімнати потрібно використовувати клієнт з підтримкою x:data"}. {"You need an x:data capable client to search","Для пошуку необхідний клієнт із підтримкою x:data"}. {"Your active privacy list has denied the routing of this stanza.","Маршрутизація цієї строфи була відмінена активним списком приватності."}. {"Your contact offline message queue is full. The message has been discarded.","Черга повідомлень, що не були доставлені, переповнена. Повідомлення не було збережено."}. {"Your Jabber account was successfully created.","Ваш Jabber-акаунт було успішно створено."}. {"Your Jabber account was successfully deleted.","Ваш Jabber-акаунт було успішно видалено."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Ваші повідомлення до ~s блокуються. Для розблокування відвідайте ~s"}. ejabberd-2.1.11/src/msgs/th.msg0000664000000000000000000006477012240230175013117 0ustar {"Access Configuration","การกำหนดค่าการเข้าถึง"}. {"Access Control List Configuration","การกำหนดค่ารายการควบคุมการเข้าถึง"}. {"Access control lists","รายการควบคุมการเข้าถึง"}. {"Access Control Lists","รายการควบคุมการเข้าถึง"}. {"Access denied by service policy","การเข้าถึงถูกปฏิเสธโดยนโยบายการบริการ"}. {"Access rules","กฎการเข้าถึง"}. {"Access Rules","กฎการเข้าถึง"}. {"Action on user","การดำเนินการกับผู้ใช้"}. {"Add Jabber ID","เพิ่ม Jabber ID"}. {"Add New","เพิ่มผู้ใช้ใหม่"}. {"Add User","เพิ่มผู้ใช้"}. {"Administration","การดูแล"}. {"Administration of ","การดูแล "}. {"Administrator privileges required","ต้องมีสิทธิพิเศษของผู้ดูแลระบบ"}. {"All activity","กิจกรรมทั้งหมด"}. {"Allow this Jabber ID to subscribe to this pubsub node?","อนุญาตให้ Jabber ID นี้เข้าร่วมเป็นสมาชิกของโหนด pubsub หรือไม่"}. {"Allow users to query other users","อนุญาตให้ผู้ใช้ถามคำถามกับผู้ใช้คนอื่นๆ ได้"}. {"Allow users to send invites","อนุญาตให้ผู้ใช้ส่งคำเชิญถึงกันได้"}. {"Allow users to send private messages","อนุญาตให้ผู้ใช้ส่งข้อความส่วนตัว"}. {"All Users","ผู้ใช้ทั้งหมด"}. {"Announcements","ประกาศ"}. {"anyone","ทุกคน"}. {"April","เมษายน"}. {"August","สิงหาคม"}. {"Backup","การสำรองข้อมูล "}. {"Backup Management","การจัดการข้อมูลสำรอง"}. {"Backup of ","การสำรองข้อมูล"}. {"Backup to File at ","สำรองไฟล์ข้อมูลที่"}. {"Bad format","รูปแบบที่ไม่ถูกต้อง"}. {"Birthday","วันเกิด"}. {"Change Password","เปลี่ยนรหัสผ่าน"}. {"Change User Password","เปลี่ยนรหัสผ่านของผู้ใช้"}. {"Chatroom configuration modified","มีการปรับเปลี่ยนการกำหนดค่าของห้องสนทนา"}. {"Chatrooms","ห้องสนทนา"}. {"Choose a username and password to register with this server","เลือกชื่อผู้ใช้และรหัสผ่านเพื่อลงทะเบียนกับเซิร์ฟเวอร์นี้"}. {"Choose modules to stop","เลือกโมดูลเพื่อหยุดการทำงาน"}. {"Choose storage type of tables","เลือกชนิดการจัดเก็บของตาราง"}. {"Choose whether to approve this entity's subscription.","เลือกว่าจะอนุมัติการสมัครเข้าใช้งานของเอนทิตี้นี้หรือไม่"}. {"City","เมือง"}. {"Commands","คำสั่ง"}. {"Conference room does not exist","ไม่มีห้องประชุม"}. {"Configuration","การกำหนดค่า"}. {"Connected Resources:","ทรัพยากรที่เชื่อมต่อ:"}. {"Country","ประเทศ"}. {"CPU Time:","เวลาการทำงานของ CPU:"}. {"Database","ฐานข้อมูล"}. {"Database Tables at ","ตารางฐานข้อมูลที่"}. {"Database Tables Configuration at ","การกำหนดค่าตารางฐานข้อมูลที่"}. {"December","ธันวาคม"}. {"Default users as participants","ผู้ใช้เริ่มต้นเป็นผู้เข้าร่วม"}. {"Delete","ลบ"}. {"Delete message of the day","ลบข้อความของวัน"}. {"Delete message of the day on all hosts","ลบข้อความของวันบนโฮสต์ทั้งหมด"}. {"Delete Selected","ลบข้อความที่เลือก"}. {"Delete User","ลบผู้ใช้"}. {"Deliver event notifications","ส่งการแจ้งเตือนเหตุการณ์"}. {"Deliver payloads with event notifications","ส่งส่วนของข้อมูล (payload) พร้อมกับการแจ้งเตือนเหตุการณ์"}. {"Description:","รายละเอียด:"}. {"Disc only copy","คัดลอกเฉพาะดิสก์"}. {"Displayed Groups:","กลุ่มที่แสดง:"}. {"Dump Backup to Text File at ","ถ่ายโอนการสำรองข้อมูลไปยังไฟล์ข้อความที่"}. {"Dump to Text File","ถ่ายโอนข้อมูลไปยังไฟล์ข้อความ"}. {"Edit Properties","แก้ไขคุณสมบัติ"}. {"ejabberd IRC module","ejabberd IRC module"}. {"ejabberd MUC module","ejabberd MUC module"}. {"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe module"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}. {"ejabberd vCard module","ejabberd vCard module"}. {"Email","อีเมล"}. {"Enable logging","เปิดใช้งานการบันทึก"}. {"End User Session","สิ้นสุดเซสชันของผู้ใช้"}. {"Enter list of {Module, [Options]}","ป้อนรายการของ {โมดูล, [ตัวเลือก]}"}. {"Enter nickname you want to register","ป้อนชื่อเล่นที่คุณต้องการลงทะเบียน"}. {"Enter path to backup file","ป้อนพาธเพื่อสำรองไฟล์ข้อมูล"}. {"Enter path to jabberd14 spool dir","ป้อนพาธไปยัง jabberd14 spool dir"}. {"Enter path to jabberd14 spool file","ป้อนพาธไปยังไฟล์เก็บพักข้อมูล jabberd14"}. {"Enter path to text file","ป้อนพาธของไฟล์ข้อความ"}. {"Erlang Jabber Server","Erlang Jabber Server"}. {"Family Name","นามสกุล"}. {"February","กุมภาพันธ์"}. {"Fill in fields to search for any matching Jabber User","กรอกข้อมูลลงในฟิลด์เพื่อค้นหาผู้ใช้ Jabber ที่ตรงกัน"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","กรอกข้อมูลในแบบฟอร์มเพื่อค้นหาผู้ใช้ Jabber ที่ตรงกัน (ใส่เครื่องหมาย * ที่ท้ายสุดของฟิลด์เพื่อจับคู่กับสตริงย่อย)"}. {"Friday","วันศุกร์"}. {"From","จาก"}. {"From ~s","จาก ~s"}. {"Full Name","ชื่อเต็ม"}. {"Get Number of Online Users","แสดงจำนวนผู้ใช้ออนไลน์"}. {"Get Number of Registered Users","แสดงจำนวนผู้ใช้ที่ลงทะเบียน"}. {"Get User Last Login Time","แสดงเวลาเข้าสู่ระบบครั้งล่าสุดของผู้ใช้"}. {"Get User Password","ขอรับรหัสผ่านของผู้ใช้"}. {"Get User Statistics","แสดงสถิติของผู้ใช้"}. {"Group ","กลุ่ม"}. {"Groups","กลุ่ม"}. {"has been banned","ถูกสั่งห้าม"}. {"has been kicked","ถูกไล่ออก"}. {" has set the subject to: "," ตั้งหัวข้อว่า: "}. {"Host","โฮสต์"}. {"Import Directory","อิมพอร์ตไดเร็กทอรี"}. {"Import File","อิมพอร์ตไฟล์"}. {"Import User from File at ","อิมพอร์ตผู้ใช้จากไฟล์ที่"}. {"Import Users from Dir at ","อิมพอร์ตผู้ใช้จาก Dir ที่"}. {"Import Users From jabberd14 Spool Files","อิมพอร์ตผู้ใช้จากไฟล์เก็บพักข้อมูล jabberd14"}. {"Improper message type","ประเภทข้อความไม่เหมาะสม"}. {"Incorrect password","รหัสผ่านไม่ถูกต้อง"}. {"Invalid affiliation: ~s","การเข้าร่วมที่ไม่ถูกต้อง: ~s"}. {"Invalid role: ~s","บทบาทไม่ถูกต้อง: ~s"}. {"IP addresses","ที่อยู่ IP"}. {"IRC Transport","การส่ง IRC"}. {"IRC Username","ชื่อผู้ใช้ IRC"}. {"is now known as","ซึ่งรู้จักกันในชื่อ"}. {"It is not allowed to send private messages of type \"groupchat\"","ไม่อนุญาตให้ส่งข้อความส่วนตัวไปยัง \"กลุ่มสนทนา\""}. {"It is not allowed to send private messages to the conference","ไม่อนุญาตให้ส่งข้อความส่วนตัวไปยังห้องประชุม"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Jabber ID ~s ไม่ถูกต้อง"}. {"January","มกราคม"}. {"joins the room","เข้าห้องสนทนานี้"}. {"July","กรกฎาคม"}. {"June","มิถุนายน"}. {"Last Activity","กิจกรรมล่าสุด"}. {"Last login","การเข้าสู่ระบบครั้งล่าสุด"}. {"Last month","เดือนที่แล้ว"}. {"Last year","ปีที่แล้ว"}. {"leaves the room","ออกจากห้อง"}. {"Listened Ports","พอร์ทฟัง"}. {"Listened Ports at ","พอร์ทฟังที่"}. {"List of modules to start","รายการของโมดูลที่จะเริ่มการทำงาน"}. {"Low level update script","อัพเดตสคริปต์ระดับต่ำ"}. {"Make participants list public","สร้างรายการผู้เข้าร่วมสำหรับใช้งานโดยบุคคลทั่วไป"}. {"Make room members-only","สร้างห้องสำหรับสมาชิกเท่านั้น"}. {"Make room password protected","สร้างห้องที่มีการป้องกันด้วยรหัสผ่าน"}. {"Make room persistent","สร้างเป็นห้องถาวร"}. {"Make room public searchable","สร้างเป็นห้องที่บุคคลทั่วไปสามารถค้นหาได้"}. {"March","มีนาคม"}. {"Maximum Number of Occupants","จำนวนผู้ครอบครองห้องสูงสุด"}. {"Max # of items to persist","จำนวนสูงสุดของรายการที่ยืนยัน"}. {"Max payload size in bytes","ขนาดสูงสุดของส่วนของข้อมูล (payload) มีหน่วยเป็นไบต์"}. {"May","พฤษภาคม"}. {"Members:","สมาชิก:"}. {"Memory","หน่วยความจำ"}. {"Message body","เนื้อหาของข้อความ"}. {"Middle Name","ชื่อกลาง"}. {"Moderator privileges required","ต้องมีสิทธิพิเศษของผู้ดูแลการสนทนา"}. {"moderators only","สำหรับผู้ดูแลการสนทนาเท่านั้น"}. {"Module","โมดูล"}. {"Modules","โมดูล"}. {"Modules at ","โมดูลที่ "}. {"Monday","วันจันทร์"}. {"Name:","ชื่อ:"}. {"Name","ชื่อ"}. {"Never","ไม่เคย"}. {"Nickname","ชื่อเล่น"}. {"Nickname Registration at ","การลงทะเบียนชื่อเล่นที่ "}. {"Nickname ~s does not exist in the room","ไม่มีชื่อเล่น ~s อยู่ในห้องนี้"}. {"No body provided for announce message","ไม่ได้ป้อนเนื้อหาสำหรับข้อความที่ประกาศ"}. {"No Data","ไม่มีข้อมูล"}. {"Node ","โหนด "}. {"Node ID","ID โหนด"}. {"Node not found","ไม่พบโหนด"}. {"Nodes","โหนด"}. {"No limit","ไม่จำกัด"}. {"None","ไม่มี"}. {"No resource provided","ไม่ได้ระบุข้อมูล"}. {"Notify subscribers when items are removed from the node","แจ้งเตือนผู้สมัครสมาชิกเมื่อรายการถูกลบออกจากโหนด"}. {"Notify subscribers when the node configuration changes","แจ้งเตือนผู้สมัครสมาชิกเมื่อการกำหนดค่าโหนดเปลี่ยนแปลง"}. {"Notify subscribers when the node is deleted","แจ้งเตือนผู้สมัครสมาชิกเมื่อโหนดถูกลบ"}. {"November","พฤศจิกายน"}. {"Number of occupants","จำนวนผู้ครอบครองห้อง"}. {"Number of online users","จำนวนผู้ใช้ออนไลน์"}. {"Number of registered users","จำนวนผู้ใช้ที่ลงทะเบียน"}. {"October","ตุลาคม"}. {"Offline Messages:","ข้อความออฟไลน์:"}. {"Offline Messages","ข้อความออฟไลน์"}. {"OK","ตกลง"}. {"Online","ออนไลน์"}. {"Online Users:","ผู้ใช้ออนไลน์:"}. {"Online Users","ผู้ใช้ออนไลน์"}. {"Only deliver notifications to available users","ส่งการแจ้งเตือนถึงผู้ใช้ที่สามารถติดต่อได้เท่านั้น"}. {"Only occupants are allowed to send messages to the conference","ผู้ครอบครองห้องเท่านั้นที่ได้รับอนุญาตให้ส่งข้อความไปยังห้องประชุม"}. {"Only occupants are allowed to send queries to the conference","ผู้ครอบครองห้องเท่านั้นที่ได้รับอนุญาตให้ส่งกระทู้ถามไปยังห้องประชุม"}. {"Only service administrators are allowed to send service messages","ผู้ดูแลด้านการบริการเท่านั้นที่ได้รับอนุญาตให้ส่งข้อความการบริการ"}. {"Options","ตัวเลือก"}. {"Organization Name","ชื่อองค์กร"}. {"Organization Unit","หน่วยขององค์กร"}. {"Outgoing s2s Connections:","การเชื่อมต่อ s2s ขาออก:"}. {"Outgoing s2s Connections","การเชื่อมต่อ s2s ขาออก"}. {"Outgoing s2s Servers:","เซิร์ฟเวอร์ s2s ขาออก:"}. {"Owner privileges required","ต้องมีสิทธิพิเศษของเจ้าของ"}. {"Packet","แพ็กเก็ต"}. {"Password:","รหัสผ่าน:"}. {"Password","รหัสผ่าน"}. {"Password Verification","การตรวจสอบรหัสผ่าน"}. {"Path to Dir","พาธไปยัง Dir"}. {"Path to File","พาธของไฟล์ข้อมูล"}. {"Pending","ค้างอยู่"}. {"Period: ","ระยะเวลา:"}. {"Persist items to storage","ยืนยันรายการที่จะจัดเก็บ"}. {"Ping","Ping"}. {"Pong","Pong"}. {"Port","พอร์ท"}. {"Present real Jabber IDs to","แสดง Jabber IDs ที่ถูกต้องแก่"}. {"private, ","ส่วนตัว, "}. {"Publish-Subscribe","เผยแพร่-สมัครเข้าใช้งาน"}. {"PubSub subscriber request","คำร้องขอของผู้สมัครเข้าใช้งาน PubSub"}. {"Queries to the conference members are not allowed in this room","ห้องนี้ไม่อนุญาตให้ส่งกระทู้ถามถึงสมาชิกในห้องประชุม"}. {"RAM and disc copy","คัดลอก RAM และดิสก์"}. {"RAM copy","คัดลอก RAM"}. {"Raw","ข้อมูลดิบ"}. {"Really delete message of the day?","แน่ใจว่าต้องการลบข้อความของวันหรือไม่"}. {"Recipient is not in the conference room","ผู้รับไม่ได้อยู่ในห้องประชุม"}. {"Registered Users:","ผู้ใช้ที่ลงทะเบียน:"}. {"Registered Users","ผู้ใช้ที่ลงทะเบียน"}. {"Registration in mod_irc for ","การลงทะเบียนใน mod_irc สำหรับ"}. {"Remote copy","คัดลอกระยะไกล"}. {"Remove","ลบ"}. {"Remove User","ลบผู้ใช้"}. {"Replaced by new connection","แทนที่ด้วยการเชื่อมต่อใหม่"}. {"Resources","ทรัพยากร"}. {"Restart","เริ่มต้นใหม่"}. {"Restart Service","เริ่มต้นการบริการใหม่อีกครั้ง"}. {"Restore","การคืนค่า"}. {"Restore Backup from File at ","คืนค่าการสำรองข้อมูลจากไฟล์ที่"}. {"Restore binary backup after next ejabberd restart (requires less memory):","คืนค่าข้อมูลสำรองแบบไบนารีหลังจากที่ ejabberd ถัดไปเริ่มการทำงานใหม่ (ใช้หน่วยความจำน้อยลง):"}. {"Restore binary backup immediately:","คืนค่าข้อมูลสำรองแบบไบนารีโดยทันที:"}. {"Restore plain text backup immediately:","คืนค่าข้อมูลสำรองที่เป็นข้อความธรรมดาโดยทันที:"}. {"Room Configuration","การกำหนดค่าห้องสนทนา"}. {"Room creation is denied by service policy","การสร้างห้องสนทนาถูกปฏิเสธโดยนโยบายการบริการ"}. {"Room title","ชื่อห้อง"}. {"Roster","บัญชีรายชื่อ"}. {"Roster of ","บัญชีรายชื่อของ "}. {"Roster size","ขนาดของบัญชีรายชื่อ"}. {"RPC Call Error","ข้อผิดพลาดจากการเรียกใช้ RPC"}. {"Running Nodes","โหนดที่ทำงาน"}. {"~s access rule configuration","~s การกำหนดค่ากฎการเข้าถึง"}. {"Saturday","วันเสาร์"}. {"Script check","ตรวจสอบคริปต์"}. {"Search Results for ","ผลการค้นหาสำหรับ "}. {"Search users in ","ค้นหาผู้ใช้ใน "}. {"Send announcement to all online users","ส่งประกาศถึงผู้ใช้ออนไลน์ทั้งหมด"}. {"Send announcement to all online users on all hosts","ส่งประกาศถึงผู้ใช้ออนไลน์ทั้งหมดบนโฮสต์ทั้งหมด"}. {"Send announcement to all users","ส่งประกาศถึงผู้ใช้ทั้งหมด"}. {"Send announcement to all users on all hosts","ส่งประกาศถึงผู้ใช้ทั้งหมดบนโฮสต์ทั้งหมด"}. {"September","กันยายน"}. {"Set message of the day and send to online users","ตั้งค่าข้อความของวันและส่งถึงผู้ใช้ออนไลน์"}. {"Set message of the day on all hosts and send to online users","ตั้งค่าข้อความของวันบนโฮสต์ทั้งหมดและส่งถึงผู้ใช้ออนไลน์"}. {"Shared Roster Groups","กลุ่มบัญชีรายชื่อที่ใช้งานร่วมกัน"}. {"Show Integral Table","แสดงตารางรวม"}. {"Show Ordinary Table","แสดงตารางทั่วไป"}. {"Shut Down Service","ปิดการบริการ"}. {"~s invites you to the room ~s","~s เชิญคุณเข้าร่วมสนทนาในห้อง ~s"}. {"Specify the access model","ระบุโมเดลการเข้าถึง"}. {"Specify the publisher model","ระบุโมเดลผู้เผยแพร่"}. {"~s's Offline Messages Queue","~s's ลำดับข้อความออฟไลน์"}. {"Start","เริ่ม"}. {"Start Modules","เริ่มโมดูล"}. {"Start Modules at ","เริ่มโมดูลที่"}. {"Statistics","สถิติ"}. {"Statistics of ~p","สถิติของ ~p"}. {"Stop","หยุด"}. {"Stop Modules","หยุดโมดูล"}. {"Stop Modules at ","หยุดโมดูลที่"}. {"Stopped Nodes","โหนดที่หยุด"}. {"Storage Type","ชนิดที่เก็บข้อมูล"}. {"Store binary backup:","จัดเก็บข้อมูลสำรองแบบไบนารี:"}. {"Store plain text backup:","จัดเก็บข้อมูลสำรองที่เป็นข้อความธรรมดา:"}. {"Subject","หัวเรื่อง"}. {"Submit","ส่ง"}. {"Submitted","ส่งแล้ว"}. {"Subscriber Address","ที่อยู่ของผู้สมัคร"}. {"Subscription","การสมัครสมาชิก"}. {"Sunday","วันอาทิตย์"}. {"the password is","รหัสผ่านคือ"}. {"This room is not anonymous","ห้องนี้ไม่ปิดบังชื่อ"}. {"Thursday","วันพฤหัสบดี"}. {"Time","เวลา"}. {"Time delay","การหน่วงเวลา"}. {"To","ถึง"}. {"To ~s","ถึง ~s"}. {"Traffic rate limit is exceeded","อัตราของปริมาณการเข้าใช้เกินขีดจำกัด"}. {"Transactions Aborted:","ทรานแซกชันที่ถูกยกเลิก:"}. {"Transactions Committed:","ทรานแซกชันที่ได้รับมอบหมาย:"}. {"Transactions Logged:","ทรานแซกชันที่บันทึก:"}. {"Transactions Restarted:","ทรานแซกชันที่เริ่มทำงานใหม่อีกครั้ง:"}. {"Tuesday","วันอังคาร"}. {"Update ","อัพเดต "}. {"Update","อัพเดต"}. {"Update message of the day (don't send)","อัพเดตข้อความของวัน (ไม่ต้องส่ง)"}. {"Update message of the day on all hosts (don't send)","อัพเดตข้อความของวันบนโฮสต์ทั้งหมด (ไม่ต้องส่ง) "}. {"Update plan","แผนการอัพเดต"}. {"Update script","อัพเดตสคริปต์"}. {"Uptime:","เวลาการทำงานต่อเนื่อง:"}. {"Use of STARTTLS required","ต้องใช้ STARTTLS"}. {"User ","ผู้ใช้"}. {"User","ผู้ใช้"}. {"User Management","การจัดการผู้ใช้"}. {"Users","ผู้ใช้"}. {"Users Last Activity","กิจกรรมล่าสุดของผู้ใช้"}. {"Validate","ตรวจสอบ"}. {"vCard User Search","ค้นหาผู้ใช้ vCard "}. {"Virtual Hosts","โฮสต์เสมือน"}. {"Visitors are not allowed to send messages to all occupants","ผู้เยี่ยมเยือนไม่ได้รับอนุญาตให้ส่งข้อความถึงผู้ครอบครองห้องทั้งหมด"}. {"Wednesday","วันพุธ"}. {"When to send the last published item","เวลาที่ส่งรายการที่เผยแพร่ครั้งล่าสุด"}. {"Whether to allow subscriptions","อนุญาตให้เข้าร่วมเป็นสมาชิกหรือไม่"}. {"You have been banned from this room","คุณถูกสั่งห้ามไมให้เข้าห้องนี้"}. {"You must fill in field \"Nickname\" in the form","คุณต้องกรอกฟิลด์ \"Nickname\" ในแบบฟอร์ม"}. {"You need an x:data capable client to configure mod_irc settings","คุณต้องใช้ไคลเอ็นต์ที่รองรับ x:data เพื่อกำหนดการตั้งค่า mod_irc"}. {"You need an x:data capable client to configure room","คุณต้องใช้ไคลเอ็นต์ที่รองรับ x:data เพื่อกำหนดค่าห้องสนทนา "}. {"You need an x:data capable client to search","คุณต้องใช้ไคลเอ็นต์ที่รองรับ x:data เพื่อค้นหา"}. {"Your contact offline message queue is full. The message has been discarded.","ลำดับข้อความออฟไลน์ของผู้ที่ติดต่อของคุณเต็มแล้ว ข้อความถูกลบทิ้งแล้ว"}. ejabberd-2.1.11/src/msgs/no.msg0000664000000000000000000006413612240230175013114 0ustar {"Access Configuration","Tilgangskonfigurasjon"}. {"Access Control List Configuration","Konfigurasjon for Tilgangskontroll lister"}. {"Access Control Lists","Tilgangskontrollister"}. {"Access control lists","Tilgangskontroll lister"}. {"Access denied by service policy","Tilgang nektes på grunn av en tjeneste regel"}. {"Access rules","Tilgangsregler"}. {"Access Rules","Tilgangsregler"}. {"Action on user","Handling på bruker"}. {"Add Jabber ID","Legg til Jabber ID"}. {"Add New","Legg til ny"}. {"Add User","Legg til Bruker"}. {"Administration","Administrasjon"}. {"Administration of ","Administrasjon av "}. {"Administrator privileges required","Administratorprivilegier kreves"}. {"A friendly name for the node","Et vennlig navn for noden"}. {"All activity","All aktivitet"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Tillat denne Jabber ID å abonnere på denne pubsub "}. {"Allow users to change the subject","Tillat brukere å endre emne"}. {"Allow users to query other users","Tillat brukere å sende forespørsel til andre brukere"}. {"Allow users to send invites","Tillat brukere å sende invitasjoner"}. {"Allow users to send private messages","Tillat brukere å sende private meldinger"}. {"Allow visitors to change nickname","Tillat besøkende å endre kallenavn"}. {"Allow visitors to send private messages to","Tillat brukere å sende private meldinger til"}. {"Allow visitors to send status text in presence updates","Tillat besøkende å sende status tekst i "}. {"Allow visitors to send voice requests","Tillat brukere å sende lyd forespørsler"}. {"All Users","Alle Brukere"}. {"Announcements","Kunngjøringer"}. {"anyone","hvem som helst"}. {"A password is required to enter this room","Et passord kreves for tilgang til samtalerommet"}. {"April","april"}. {"August","august"}. {"Backup Management","Håndtere Sikkerehetskopiering"}. {"Backup of ","Sikkerhetskopi av "}. {"Backup","Sikkerhetskopier"}. {"Backup to File at ","Sikkerhetskopiere til Fil på "}. {"Bad format","Feil format"}. {"Birthday","Fødselsdag"}. {"CAPTCHA web page","CAPTCHA web side"}. {"Change Password","Endre Passord"}. {"Change User Password","Endre Brukers Passord"}. {"Characters not allowed:","Ikke godtatte tegn:"}. {"Chatroom configuration modified","Samtalerommets konfigurasjon er endret"}. {"Chatroom is created","Samtalerom er opprettet"}. {"Chatroom is destroyed","Samtalerom er fjernet"}. {"Chatroom is started","Samtalerom er startet"}. {"Chatroom is stopped","Samtalerom er stoppet"}. {"Chatrooms","Samtalerom"}. {"Choose a username and password to register with this server","Velg et brukernavn og passord for å registrere på "}. {"Choose modules to stop","Velg hvilke moduler som skal stoppes"}. {"Choose storage type of tables","Velg lagringstype for tabeller"}. {"Choose whether to approve this entity's subscription.","Velg om du vil godkjenne denne eksistensens abonement"}. {"City","By"}. {"Commands","Kommandoer"}. {"Conference room does not exist","Konferanserommet finnes ikke"}. {"Configuration","Konfigurasjon"}. {"Configuration of room ~s","Konfigurasjon for rom ~s"}. {"Connected Resources:","Tilkoblede Ressurser:"}. {"Connections parameters","Tilkoblings parametere"}. {"Country","Land"}. {"CPU Time:","CPU Tid:"}. {"Database","Database"}. {"Database Tables at ","Database Tabeller på "}. {"Database Tables Configuration at ","Database Tabell Konfigurasjon på "}. {"December","desember"}. {"Default users as participants","Standard brukere som deltakere"}. {"Delete message of the day on all hosts","Slett melding for dagen på alle maskiner"}. {"Delete message of the day","Slett melding for dagen"}. {"Delete Selected","Slett valgte"}. {"Delete","Slett"}. {"Delete User","Slett Bruker"}. {"Deliver event notifications","Lever begivenhets kunngjøringer"}. {"Deliver payloads with event notifications","Send innhold sammen med kunngjøringer"}. {"Description:","Beskrivelse:"}. {"Disc only copy","Kun diskkopi"}. {"Displayed Groups:","Viste grupper:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Ikke fortell passordet til noen, ikke en gang til administratoren av Jabber serveren."}. {"Dump Backup to Text File at ","Dump Sikkerhetskopi til Tekstfil på "}. {"Dump to Text File","Dump til Tekstfil"}. {"Edit Properties","Redigere Egenskaper"}. {"Either approve or decline the voice request.","Enten godkjenn eller forby lyd forespørselen"}. {"ejabberd IRC module","ejabberd IRC modul"}. {"ejabberd MUC module","ejabberd MUC modul"}. {"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe modul"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams modul"}. {"ejabberd vCard module","ejabberd vCard modul"}. {"ejabberd Web Admin","ejabberd Web Admin"}. {"Elements","Elementer"}. {"Email","Epost"}. {"Enable logging","Slå på logging"}. {"Encoding for server ~b","Tekstkoding for server ~b"}. {"End User Session","Avslutt Bruker Sesjon"}. {"Enter list of {Module, [Options]}","Skriv inn en liste av {Module, [Options]}"}. {"Enter nickname you want to register","Skriv inn kallenavnet du ønsker å registrere"}. {"Enter path to backup file","Skriv inn sti til sikkerhetskopi filen"}. {"Enter path to jabberd14 spool dir","Skriv inn sti til jabberd14 spoolkatalog"}. {"Enter path to jabberd14 spool file","Skriv inn sti til jabberd14 spoolfil"}. {"Enter path to text file","Skriv inn sti til tekstfil"}. {"Enter the text you see","Skriv inn teksten du ser"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Angi brukernavn og kodinger du ønsker å bruke for å koble til IRC servere. Trykk 'Neste' for å få flere felt for å fylle i. Trykk 'Fullfør' for å lagre innstillingene."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Skriv brukernavn, tekstkoding, porter og passord du ønsker å bruke for tilkobling til IRC servere"}. {"Erlang Jabber Server","Erlang Jabber Server"}. {"Error","Feil"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Eksempel: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Ekskluder Jabber IDer fra CAPTCHA utfordring"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Eksporter data om alle brukere i en server til PIEFXIS filer"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Eksporter data om alle brukere i en host til PIEFXIS filer (XEP-0227):"}. {"Failed to extract JID from your voice request approval","Feilet i forsøk på å hente JID fra din lyd forespørsel godkjenning"}. {"Family Name","Etternavn"}. {"February","februar"}. {"Fill in fields to search for any matching Jabber User","Fyll inn felt for å søke etter Jabber brukere"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Fyll inn skjemaet for å søke etter Jabber bruker (Legg til * på slutten av feltet for å treffe alle som starter slik)"}. {"Friday","fredag"}. {"From","Fra"}. {"From ~s","Fra ~s"}. {"Full Name","Fullstendig Navn"}. {"Get Number of Online Users","Vis Antall Tilkoblede Brukere"}. {"Get Number of Registered Users","Vis Antall Registrerte Brukere"}. {"Get User Last Login Time","Vis Brukers Siste Påloggings Tidspunkt"}. {"Get User Password","Hent Brukers Passord"}. {"Get User Statistics","Vis Bruker Statistikk"}. {"Grant voice to this person?","Gi lyd til denne personen?"}. {"Group ","Gruppe "}. {"Groups","Grupper"}. {"has been banned","har blitt bannlyst"}. {"has been kicked because of an affiliation change","har blitt kastet ut på grunn av en tilknytnings endring"}. {"has been kicked because of a system shutdown","har blitt kastet ut på grunn av at systemet avslutter"}. {"has been kicked because the room has been changed to members-only","har blitt kastet ut på grunn av at rommet er endret til kun-for-medlemmer"}. {"has been kicked","har blitt kastet ut"}. {" has set the subject to: "," har satt emnet til: "}. {"Host","Maskin"}. {"If you don't see the CAPTCHA image here, visit the web page.","Dersom du ikke ser CAPTCHA bilde her, besøk web siden. "}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Om du ønsker å spesifisere tekstkoding for IRC tjenere, fyller du ut en liste med verdier i formatet '{\"irc server\", \"encoding\", port, \"password\"}'. Denne tjenesten bruker \"~s\" som standard, port ~p, empty password."}. {"Import Directory","Importer Katalog"}. {"Import File","Importer File"}. {"Import user data from jabberd14 spool file:","Importer bruker data fra jabberd14 spoolfiler:"}. {"Import User from File at ","Importer Bruker fra Fil på "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importer brukeres data fra en PIEFXIS fil (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Importer brukeres data fra jabberd14 spoolfil katalog:"}. {"Import Users from Dir at ","Importer Brukere fra Katalog på "}. {"Import Users From jabberd14 Spool Files","Importer Brukere Fra jabberd14 Spoolfiler"}. {"Improper message type","Feilaktig meldingstype"}. {"Incorrect password","Feil passord"}. {"Invalid affiliation: ~s","Ugyldig rang: ~s"}. {"Invalid role: ~s","Ugyldig rolle: ~s"}. {"IP addresses","IP adresser"}. {"IP","IP"}. {"IRC channel (don't put the first #)","IRC kanal (ikke skriv den første #)"}. {"IRC server","IRC server"}. {"IRC settings","IRC instillinger"}. {"IRC Transport","IRC Transport"}. {"IRC username","IRC brukernavn"}. {"IRC Username","IRC Brukernavn"}. {"is now known as","er nå kjent som"}. {"It is not allowed to send private messages","Det er ikke tillatt å sende private meldinger"}. {"It is not allowed to send private messages of type \"groupchat\"","Det er ikke tillatt å sende private meldinger med typen "}. {"It is not allowed to send private messages to the conference","Det er ikke tillatt å sende private meldinger til "}. {"Jabber Account Registration","Jabber Konto Registrering"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Ugyldig Jabber ID ~s"}. {"January","januar"}. {"Join IRC channel","Bli med i IRC kanal"}. {"joins the room","kommer inn i rommet"}. {"Join the IRC channel here.","Bli med i IRC kanalen her. "}. {"Join the IRC channel in this Jabber ID: ~s","Bli med i IRC kanalen med denne Jabber ID: ~s"}. {"July","juli"}. {"June","juni"}. {"Last Activity","Siste Aktivitet"}. {"Last login","Siste pålogging"}. {"Last month","Siste måned"}. {"Last year","Siste året"}. {"leaves the room","forlater rommet"}. {"Listened Ports at ","Lyttende Porter på "}. {"Listened Ports","Lyttende Porter"}. {"List of modules to start","Liste over moduler som skal startes"}. {"Low level update script","Lavnivå oppdaterings skript"}. {"Make participants list public","Gjør deltakerlisten offentlig"}. {"Make room CAPTCHA protected","Gjør rommet CAPTCHA beskyttet"}. {"Make room members-only","Gjør rommet tilgjengelig kun for medlemmer"}. {"Make room moderated","Gjør rommet redaktørstyrt"}. {"Make room password protected","Passordbeskytt rommet"}. {"Make room persistent","Gjør rommet permanent"}. {"Make room public searchable","Gjør rommet offentlig søkbart"}. {"March","mars"}. {"Maximum Number of Occupants","Maksimum Antall Deltakere"}. {"Max # of items to persist","Høyeste # elementer som skal lagres"}. {"Max payload size in bytes","Største innholdsstørrelse i byte"}. {"May","mai"}. {"Membership is required to enter this room","Medlemskap kreves for tilgang til samtalerommet"}. {"Members:","Medlemmer:"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Husk passordet, eller skriv det ned på et papir lagret på et trygt sted. I Jabber er det ingen automatisert måte å gjenskape passordet om du glemmer det. "}. {"Memory","Minne"}. {"Message body","Meldingskropp"}. {"Middle Name","Mellomnavn"}. {"Minimum interval between voice requests (in seconds)","Minimums interval mellom lyd forespørsler (i sekunder)"}. {"Moderator privileges required","Redaktørprivilegier kreves"}. {"moderators only","kun for redaktører"}. {"Modified modules","Endrede moduler"}. {"Module","Modul"}. {"Modules at ","Moduler på "}. {"Modules","Moduler"}. {"Monday","mandag"}. {"Name:","Navn:"}. {"Name","Navn"}. {"Never","Aldri"}. {"New Password:","Nytt Passord:"}. {"Nickname","Kallenavn"}. {"Nickname Registration at ","Registrer Kallenavn på "}. {"Nickname ~s does not exist in the room","Kallenavn ~s eksisterer ikke i dette rommet"}. {"nobody","ingen"}. {"No body provided for announce message","Ingen meldingskropp gitt for kunngjørings melding"}. {"No Data","Ingen Data"}. {"Node ID","Node ID"}. {"Node ","Node "}. {"Node not found","Noden finnes ikke"}. {"Nodes","Noder"}. {"No limit","Ingen grense"}. {"None","Ingen"}. {"No resource provided","Ingen ressurs angitt"}. {"Not Found","Finnes Ikke"}. {"Notify subscribers when items are removed from the node","Informer abonnenter når elementer fjernes fra noden"}. {"Notify subscribers when the node configuration changes","Informer abonnenter når node konfigurasjonen endres"}. {"Notify subscribers when the node is deleted","Informer abonnenter når noden slettes"}. {"November","november"}. {"Number of occupants","Antall deltakere"}. {"Number of online users","Antall tilkoblede brukere"}. {"Number of registered users","Antall registrerte brukere"}. {"October","oktober"}. {"Offline Messages:","Frakoblede Meldinger:"}. {"Offline Messages","Frakoblede Meldinger"}. {"OK","OK"}. {"Old Password:","Gammelt Passord:"}. {"Online","Tilkoblet"}. {"Online Users:","Tilkoblede Brukere:"}. {"Online Users","Tilkoblede Brukere"}. {"Only deliver notifications to available users","Send kunngjøringer bare til tilgjengelige brukere"}. {"Only moderators and participants are allowed to change the subject in this room","Bare redaktører og deltakere kan endre emnet i dette rommet"}. {"Only moderators are allowed to change the subject in this room","Bare ordstyrer tillates å endre emnet i dette rommet"}. {"Only moderators can approve voice requests","Bare ordstyrer kan godkjenne lyd forespørsler"}. {"Only occupants are allowed to send messages to the conference","Bare deltakere får sende normale meldinger til konferansen"}. {"Only occupants are allowed to send queries to the conference","Bare deltakere er tillatt å sende forespørsler til "}. {"Only service administrators are allowed to send service messages","Bare tjeneste administratorer er tilatt å sende tjeneste "}. {"Options","Alternativer"}. {"Organization Name","Organisasjonsnavn"}. {"Organization Unit","Organisasjonsenhet"}. {"Outgoing s2s Connections:","Utgående s2s Koblinger"}. {"Outgoing s2s Connections","Utgående s2s Koblinger"}. {"Outgoing s2s Servers:","Utgående s2s Tjenere"}. {"Owner privileges required","Eierprivilegier kreves"}. {"Packet","Pakke"}. {"Password ~b","Passord ~b"}. {"Password:","Passord:"}. {"Password","Passord"}. {"Password Verification:","Passord Bekreftelse:"}. {"Password Verification","Passord Bekreftelse"}. {"Path to Dir","Sti til Katalog"}. {"Path to File","Sti til Fil"}. {"Pending","Ventende"}. {"Period: ","Periode: "}. {"Persist items to storage","Vedvarende elementer til lagring"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Merk at disse valgene vil bare sikkerhetskopiere den innebygde Mnesia databasen. Dersom du bruker ODBC modulen må du også ta backup av din SQL database."}. {"Please, wait for a while before sending new voice request","Vennligst vent en stund før du sender en ny lyd forespørsel"}. {"Pong","Pong"}. {"Port ~b","Port ~b"}. {"Port","Port"}. {"Present real Jabber IDs to","Presenter ekte Jabber IDer til"}. {"private, ","privat, "}. {"Protocol","Protokoll"}. {"Publish-Subscribe","Publish-Subscribe"}. {"PubSub subscriber request","PubSub abonements forespørsel"}. {"Purge all items when the relevant publisher goes offline","Rydd alle elementer når den aktuelle utgiveren logger av"}. {"Queries to the conference members are not allowed in this room","Forespørsler til konferanse medlemmene er ikke tillat i dette rommet"}. {"RAM and disc copy","RAM og diskkopi"}. {"RAM copy","RAM kopi"}. {"Raw","Rå"}. {"Really delete message of the day?","Virkelig slette melding for dagen?"}. {"Recipient is not in the conference room","Mottakeren er ikke i konferanserommet"}. {"Register a Jabber account","Registrer en Jabber konto"}. {"Registered Users:","Registrerte Brukere:"}. {"Registered Users","Registrerte Brukere"}. {"Register","Registrer"}. {"Registration in mod_irc for ","Registrering i mod_irc for "}. {"Remote copy","Lagres ikke lokalt"}. {"Remove All Offline Messages","Fjern Alle Frakoblede Meldinger"}. {"Remove","Fjern"}. {"Remove User","Fjern Bruker"}. {"Replaced by new connection","Erstattet av en ny tilkobling"}. {"Resources","Ressurser"}. {"Restart Service","Start Tjeneste på Nytt"}. {"Restart","Starte på nytt"}. {"Restore Backup from File at ","Gjenopprett fra Sikkerhetsopifil på "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Gjenopprette binær backup etter neste ejabberd omstart (krever mindre minne):"}. {"Restore binary backup immediately:","Gjenopprette binær backup umiddelbart:"}. {"Restore","Gjenopprett"}. {"Restore plain text backup immediately:","Gjenopprette rentekst sikkerhetskopi umiddelbart:"}. {"Room Configuration","Rom Konfigurasjon"}. {"Room creation is denied by service policy","Oppretting av rom nektes av en tjenste regel"}. {"Room description","Rom beskrivelse"}. {"Room Occupants","Samtalerom Deltakere"}. {"Room title","Romtittel"}. {"Roster groups allowed to subscribe","Kontaktliste grupper som tillates å abonnere"}. {"Roster","Kontaktliste"}. {"Roster of ","Kontaktliste for "}. {"Roster size","Kontaktliste størrelse"}. {"RPC Call Error","RPC Kall Feil"}. {"Running Nodes","Kjørende Noder"}. {"~s access rule configuration","tilgangsregel konfigurasjon for ~s"}. {"Saturday","lørdag"}. {"Script check","Skript sjekk"}. {"Search Results for ","Søke Resultater for "}. {"Search users in ","Søk etter brukere i "}. {"Send announcement to all online users on all hosts","Send kunngjøring til alle tilkoblede brukere på alle "}. {"Send announcement to all online users","Send kunngjøring alle tilkoblede brukere"}. {"Send announcement to all users on all hosts","Send kunngjøring til alle brukere på alle maskiner"}. {"Send announcement to all users","Send kunngjøring til alle brukere"}. {"September","september"}. {"Server ~b","Server ~b"}. {"Server:","Server:"}. {"Set message of the day and send to online users","Angi melding for dagen og send til tilkoblede brukere"}. {"Set message of the day on all hosts and send to online users","Angi melding for dagen på alle maskiner og send til "}. {"Shared Roster Groups","Delte Kontaktgrupper"}. {"Show Integral Table","Vis Integral Tabell"}. {"Show Ordinary Table","Vis Ordinær Tabell"}. {"Shut Down Service","Avslutt Tjeneste"}. {"~s invites you to the room ~s","~s inviterer deg til rommet ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Noen Jabber klienter kan lagre passordet på datamaskinen. Bruk bare den funksjonen dersom du er sikker på at maskinen er trygg."}. {"Specify the access model","Spesifiser aksess modellen"}. {"Specify the event message type","Spesifiser hendelsesbeskjed type"}. {"Specify the publisher model","Angi publiserings modell"}. {"~s's Offline Messages Queue","~ss kø for Frakoblede Meldinger"}. {"Start Modules at ","Start Moduler på "}. {"Start Modules","Start Moduler"}. {"Start","Start"}. {"Statistics of ~p","Statistikk for ~p"}. {"Statistics","Statistikk"}. {"Stop Modules at ","Stopp Moduler på "}. {"Stop Modules","Stop Moduler"}. {"Stopped Nodes","Stoppede Noder"}. {"Stop","Stoppe"}. {"Storage Type","Lagringstype"}. {"Store binary backup:","Lagre binær sikkerhetskopi:"}. {"Store plain text backup:","Lagre rentekst sikkerhetskopi:"}. {"Subject","Tittel"}. {"Submit","Send"}. {"Submitted","Innsendt"}. {"Subscriber Address","Abonnements Adresse"}. {"Subscription","Abonnement"}. {"Sunday","søndag"}. {"That nickname is already in use by another occupant","Det kallenavnet er allerede i bruk av en annen deltaker"}. {"That nickname is registered by another person","Det kallenavnet er registrert av en annen person"}. {"The CAPTCHA is valid.","Captchaen er ikke gyldig"}. {"The CAPTCHA verification has failed","CAPTCHA godkjenningen har feilet"}. {"The collections with which a node is affiliated","Samlingene som en node er assosiert med"}. {"the password is","passordet er"}. {"The password is too weak","Passordet er for svakt"}. {"The password of your Jabber account was successfully changed.","Passordet for din Jabber konto ble endret."}. {"There was an error changing the password: ","En feil skjedde under endring av passordet:"}. {"There was an error creating the account: ","En feil skjedde under oppretting av kontoen:"}. {"There was an error deleting the account: ","En feil skjedde under sletting av kontoen: "}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Denne er ufølsom for små og store bokstaver: macbeth er det samme som MacBeth og Macbeth. "}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Denne siden lar deg lage en Jabber konto på denne Jabber serveren. Din JID (Jabber ID) vil være i formatet: brukernavn@server. Vennligst les instruksjonene nøye slik at du fyller ut skjemaet riktig."}. {"This page allows to unregister a Jabber account in this Jabber server.","Denne siden lar deg avregistrere en Jabber konto på denne Jabber serveren."}. {"This participant is kicked from the room because he sent an error message","Denne deltakeren er kastet ut av rommet fordi han sendte en feilmelding"}. {"This participant is kicked from the room because he sent an error message to another participant","Denne deltakeren er kastet ut av rommet fordi han sendte en feilmelding til en annen deltaker"}. {"This participant is kicked from the room because he sent an error presence","Denne deltakeren er kastet ut av rommet fordi han sendte feil tilstederværelse"}. {"This room is not anonymous","Dette rommet er ikke anonymt"}. {"Thursday","torsdag"}. {"Time delay","Tids forsinkelse"}. {"Time","Tid"}. {"Too many CAPTCHA requests","For mange CAPTCHA forespørsler"}. {"To ~s","Til ~s"}. {"To","Til"}. {"Traffic rate limit is exceeded","Trafikkmengde grense overskredet"}. {"Transactions Aborted:","Avbrutte Transasksjoner:"}. {"Transactions Committed:","Sendte Transaksjoner:"}. {"Transactions Logged:","Loggede Transasksjoner:"}. {"Transactions Restarted:","Omstartede Transasksjoner:"}. {"Tuesday","tirsdag"}. {"Unable to generate a CAPTCHA","Umulig å generere en CAPTCHA"}. {"Unauthorized","Uautorisert"}. {"Unregister a Jabber account","Avregistrer en Jabber konto"}. {"Unregister","Avregistrer"}. {"Update message of the day (don't send)","Oppdater melding for dagen (ikke send)"}. {"Update message of the day on all hosts (don't send)","Oppdater melding for dagen på alle maskiner (ikke send)"}. {"Update ","Oppdater "}. {"Update","Oppdatere"}. {"Update plan","Oppdaterings plan"}. {"Update script","Oppdaterings skript"}. {"Uptime:","Oppetid:"}. {"Use of STARTTLS required","Bruk av STARTTLS kreves"}. {"User ","Bruker "}. {"User","Bruker"}. {"User JID","Bruker JID"}. {"User Management","Bruker Behandling"}. {"Username:","Brukernavn:"}. {"Users are not allowed to register accounts so quickly","Brukere får ikke lov til registrere kontoer så fort"}. {"Users","Brukere"}. {"Users Last Activity","Brukers Siste Aktivitet"}. {"Validate","Bekrefte gyldighet"}. {"vCard User Search","vCard Bruker Søk"}. {"Virtual Hosts","Virtuella Maskiner"}. {"Visitors are not allowed to change their nicknames in this room","Besøkende får ikke lov å endre kallenavn i dette "}. {"Visitors are not allowed to send messages to all occupants","Besøkende får ikke sende meldinger til alle deltakere"}. {"Voice request","Lyd forespørsel"}. {"Voice requests are disabled in this conference","Lyd forespørsler er blokkert i denne konferansen"}. {"Wednesday","onsdag"}. {"When to send the last published item","Når skal siste publiserte artikkel sendes"}. {"Whether to allow subscriptions","Om man skal tillate abonnenter"}. {"You can later change your password using a Jabber client.","Du kan når som helst endre passordet via en Jabber klient."}. {"You have been banned from this room","Du har blitt bannlyst i dette rommet."}. {"You must fill in field \"Nickname\" in the form","Du må fylle inn feltet \"Nickname\" i skjemaet"}. {"You need a client that supports x:data and CAPTCHA to register","Du trenger en klient som støtter x:data og CAPTCHA for registrering "}. {"You need a client that supports x:data to register the nickname","Du trenger en klient som støtter x:data for å registrere kallenavnet"}. {"You need an x:data capable client to configure mod_irc settings","Du trenger en x:data kompatibel klient for å konfigurere mod_irc instillinger"}. {"You need an x:data capable client to configure room","Du trenger en klient som støtter x:data for å "}. {"You need an x:data capable client to search","Du tregner en klient som støtter x:data for å kunne "}. {"Your active privacy list has denied the routing of this stanza.","Din aktive privat liste har blokkert rutingen av denne strofen."}. {"Your contact offline message queue is full. The message has been discarded.","Kontaktens frakoblede meldingskø er full. Meldingen har blitt kassert."}. {"Your Jabber account was successfully created.","Din Jabber konto ble opprettet"}. {"Your Jabber account was successfully deleted.","Dni Jabber konto er blitt sltettet."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Dine meldinger til ~s blir blokkert. For å åpne igjen, besøk ~s"}. ejabberd-2.1.11/src/msgs/wa.po0000664000000000000000000015241612240230175012736 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "Last-Translator: Pablo Saratxaga\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Walon (Walloon)\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "L' eployaedje di STARTTL est oblidjî" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Nole rissoûce di dnêye" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Replaecî pa on novea raloyaedje" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 #, fuzzy msgid "Enter the text you see" msgstr "Dinez l' tchimin viè l' fitchî tecse" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "" #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Comandes" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Voloz vs vormint disfacer l' messaedje do djoû?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Sudjet" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Coir do messaedje" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "I n' a nou coir do messaedje po ciste anonce la" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Anonces" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Evoyî l' anonce a tos les uzeus" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Evoyî l' anonce a tos les uzeus so tos les lodjoes" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Evoyî l' anonce a tos les uzeus raloyîs" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Evoyî l' anonce a tos les uzeus raloyîs so tos les lodjoes" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Defini l' messaedje do djoû et l' evoyî åzès uzeus raloyîs" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Defini l' messaedje do djoû so tos les lodjoes et l' evoyî åzès uzeus raloyîs" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Mete a djoû l' messaedje do djoû (nén l' evoyî)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Mete a djoû l' messaedje do djoû so tos les lodjoes (nén l' evoyî)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Disfacer l' messaedje do djoû" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Disfacer l' messaedje do djoû so tos les lodjoes" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Apontiaedjes" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Båze di dnêyes" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Enonder des modules" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Arester des modules" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Copeye di såvrité" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Rapexhî" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Schaper en on fitchî tecse" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Sititchî d' on fitchî" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Sititchî d' on ridant" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Renonder siervice" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Arester siervice" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Radjouter èn uzeu" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Disfacer èn uzeu" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Fini l' session d' l' uzeu" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Riçure sicret d' l' uzeu" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Candjî l' sicret d' l' uzeu" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Riçure li date/eure do dierin elodjaedje di l' uzeu" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Riçure les statistikes di l' uzeu" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Riçure li nombe d' uzeus edjîstrés" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Riçure li nombe d' uzeus raloyîs" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Droets (ACL)" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Rîles d' accès" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Manaedjaedje des uzeus" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Uzeus raloyîs" #: mod_configure.erl:501 msgid "All Users" msgstr "Tos les uzeus" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Raloyaedjes s2s e rexhowe" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Nuks en alaedje" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Nuks essoctés" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Modules" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Manaedjaedje des copeyes di såvrité" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Sititchî des uzeus Jabberd 1.4" #: mod_configure.erl:699 msgid "To ~s" msgstr "Viè ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Dispoy ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Apontiaedje des tåves del båze di dnêyes so " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Tchoezi l' sôre di wårdaedje po les tåves" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Copeye seulmint sol deure plake" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Copeye e memwere (RAM) et sol deure plake" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Copeye e memwere (RAM)" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Copeye å lon" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Arester les modules so " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Tchoezixhoz les modules a-z arester" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Renonder les modules so " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Dinez ene djivêye del cogne {Module, [Tchuzes]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Djivêye di modules a-z enonder" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Fé ene copeye di såvrité dins on fitchî so " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Dinez l' tchimin viè l' fitchî copeye di såvrité" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Tchimin viè l' fitchî" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Rapexhî dispoy li fitchî copeye di såvrité so " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Copeye di såvritè viè on fitchî tecse so " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Dinez l' tchimin viè l' fitchî tecse" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Sititchî uzeu d' on fitchî so " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Dinez l' tchimin viè l' fitchî di spool jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Sitichî des uzeus d' on ridant so " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Dinez l' tchimin viè l' ridant di spool jabberd14" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Tchimin viè l' ridant" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Tårdjaedje" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Apontiaedje des droets (ACL)" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Droets (ACL)" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Apontiaedje des accès" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Rîles d' accès" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "ID Jabber" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Sicret" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Acertinaedje do scret" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Nombe d' uzeus edjîstrés" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Nombe d' uzeus raloyîs" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Måy" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Raloyî" #: mod_configure.erl:1701 msgid "Last login" msgstr "Dierin elodjaedje" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Grandeu del djivêye des soçons" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "Adresses IP" #: mod_configure.erl:1724 msgid "Resources" msgstr "Rissoûces" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Manaedjaedje di " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Accion so l' uzeu" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Candjî les prôpietés" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Disfacer l' uzeu" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "L' accès a stî rfuzé pal politike do siervice" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "Transpoirt IRC" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "Module IRC po ejabberd" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "Vos avoz mezåjhe d' on cliyint ki sopoite x:data po candjî ls apontiaedjes " "di mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Edjîstraedje dins mod_irc po " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 #, fuzzy msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Dinez les nos d' uzeu et ls ecôdaedjes ki vos vloz eployî po vs raloyî åzès " "sierveus IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "No d' uzeu IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 #, fuzzy msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Si vos vloz dner des ecôdaedjes diferins po les sierveus IRC, rimplixhoz " "cisse djivêye ci avou des valixhances del cogne «{\"sierveu irc\", " "\"ecôdaedje\"}». Li prémetou ecôdaedje do siervice c' est «~s»." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 #, fuzzy msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Egzimpe: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", " "\"iso8859-1\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 #, fuzzy msgid "IRC server" msgstr "No d' uzeu IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 #, fuzzy msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Dinez les nos d' uzeu et ls ecôdaedjes ki vos vloz eployî po vs raloyî åzès " "sierveus IRC" #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 #, fuzzy msgid "IRC username" msgstr "No d' uzeu IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 #, fuzzy msgid "Password ~b" msgstr "Sicret" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 #, fuzzy msgid "Port ~b" msgstr "Pôrt" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" "Seulmint les manaedjeus d' siervices polèt evoyî des messaedjes di siervice" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "L' ahivaedje del såle est rfuzé pal politike do siervice" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Li såle di conferince n' egzistêye nén" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Såles di berdelaedje" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 #, fuzzy msgid "You need a client that supports x:data to register the nickname" msgstr "" "Vos avoz mezåjhe d' on cliyint ki sopoite x:data po-z edjîstrer on metou no" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Edjîstraedje di metou no amon " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Dinez l' metou no ki vos vloz edjîstrer" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Metou no" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 #, fuzzy msgid "That nickname is registered by another person" msgstr "Li metou no est ddja edjîstré pa ene ôte sakî" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Vos dvoz rimpli l' tchamp «Metou no» dins l' formiulaire" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "Module MUC (såles di berdelaedje) po ejabberd" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "L' apontiaedje del såle di berdelaedje a candjî" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "arive sol såle" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "cwite li såle" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "a stî bani" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "a stî pité evoye" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "a stî pité evoye cåze d' on candjmint d' afiyaedje" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "" "a stî pité evoye cåze ki l' såle a stî ristrindowe åzès mimbes seulmint" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "a stî pité evoye cåze d' èn arestaedje do sistinme" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "est asteure kinoxhou come" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " a candjî l' tite a: " #: mod_muc/mod_muc_log.erl:452 #, fuzzy msgid "Chatroom is created" msgstr "Såles di berdelaedje" #: mod_muc/mod_muc_log.erl:453 #, fuzzy msgid "Chatroom is destroyed" msgstr "Såles di berdelaedje" #: mod_muc/mod_muc_log.erl:454 #, fuzzy msgid "Chatroom is started" msgstr "Såles di berdelaedje" #: mod_muc/mod_muc_log.erl:455 #, fuzzy msgid "Chatroom is stopped" msgstr "Såles di berdelaedje" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "londi" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "mårdi" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "mierkidi" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "djudi" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "vénrdi" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "semdi" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "dimegne" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "djanvî" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "fevrî" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "måss" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "avri" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "may" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "djun" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "djulete" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "awousse" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "setimbe" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "octôbe" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "nôvimbe" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "decimbe" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Apontiaedje del såle" #: mod_muc/mod_muc_log.erl:759 #, fuzzy msgid "Room Occupants" msgstr "Nombe di prezints" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Li limite pol volume di trafik a stî passêye" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Ci pårticipant ci a stî pité evoye del såle cåze k' il a-st evoyî on " "messaedje d' aroke" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "On n' pout nén evoyî des messaedjes privés dins cisse conferince ci" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Sôre di messaedje nén valide" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Ci pårticipant ci a stî pité evoye del såle cåze k' il a-st evoyî on " "messaedje d' aroke a èn ôte pårticipant" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "C' est nén possibe d' evoyî des messaedjes privés del sôre «groupchat»" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Li riçuveu n' est nén dins l' såle di conferince" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Ci n' est nén permetou d' evoyî des messaedjes privés" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Seulmint les prezints polèt evoyî des messaedjes al conferince" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Seulmint les prezints polèt evoyî des cweraedjes sol conferince" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "" "Les cweraedjes des mimbes del conferince ni sont nén permetous dins cisse " "såle ci" #: mod_muc/mod_muc_room.erl:932 #, fuzzy msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Seulmint les moderateus et les pårticipants polèt candjî l' sudjet dins " "cisse såle ci" #: mod_muc/mod_muc_room.erl:937 #, fuzzy msgid "Only moderators are allowed to change the subject in this room" msgstr "Seulmint les moderateus polèt candjî l' sudjet dins cisse såle ci" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Les viziteus n' polèt nén evoyî des messaedjes a tos les prezints" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Ci pårticipant ci a stî pité evoye del såle cåze k' il a-st evoyî ene aroke " "di prezince" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Les viziteus èn polèt nén candjî leus metous no po ç' såle ci" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 #, fuzzy msgid "That nickname is already in use by another occupant" msgstr "Li metou no est ddja eployî pa ene ôte sakî sol såle" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Vos avoz stî bani di cisse såle ci" #: mod_muc/mod_muc_room.erl:1771 #, fuzzy msgid "Membership is required to enter this room" msgstr "I fåt esse mimbe po poleur intrer dins cisse såle ci" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Cisse såle ci n' est nén anonime" #: mod_muc/mod_muc_room.erl:1833 #, fuzzy msgid "A password is required to enter this room" msgstr "I fåt dner on scret po poleur intrer dins cisse såle ci" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Sicret nén corek" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "I fåt des priviledjes di manaedjeu" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "I fåt des priviledjes di moderateu" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Li Jabber ID ~s n' est nén valide" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Li metou no ~s n' egzistêye nén dins l' såle" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Afiyaedje nén valide: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Role nén valide: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "I fåt des priviledjes di prôpietaire" #: mod_muc/mod_muc_room.erl:3195 #, fuzzy msgid "Configuration of room ~s" msgstr "Apontiaedje po " #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Tite del såle" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 #, fuzzy msgid "Room description" msgstr "Discrijhaedje:" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Rinde li såle permaninte" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Rinde li såle di berdelaedje cweråve publicmint" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Rinde publike li djivêye des pårticipants" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Rinde li såle di berdelaedje protedjeye pa scret" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Nombe macsimom di prezints" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Pont d' limite" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Mostrer les vraiys Jabber IDs a" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "les moderateus seulmint" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "tot l' minme kî" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Rinde li såle di berdelaedje ristrindowe ås mimbes seulmint" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Rinde li såle di berdelaedje moderêye" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Les uzeus sont des pårticipants come prémetowe dujhance" #: mod_muc/mod_muc_room.erl:3271 #, fuzzy msgid "Allow users to change the subject" msgstr "Les uzeus polèt candjî l' tite" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Les uzeus polèt evoyî des messaedjes privés" #: mod_muc/mod_muc_room.erl:3279 #, fuzzy msgid "Allow visitors to send private messages to" msgstr "Les uzeus polèt evoyî des messaedjes privés" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Les uzeus polèt cweri ls ôtes uzeus" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Les uzeus polèt evoyî priyaedjes" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "" "Permete ki les viziteus evoyexhe des tecse d' estat dins leus messaedjes di " "prezince" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Permete ki les viziteus candjexhe leus metous nos" #: mod_muc/mod_muc_room.erl:3308 #, fuzzy msgid "Allow visitors to send voice requests" msgstr "Les uzeus polèt evoyî priyaedjes" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "" #: mod_muc/mod_muc_room.erl:3317 #, fuzzy msgid "Make room CAPTCHA protected" msgstr "Rinde li såle di berdelaedje protedjeye pa scret" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Mete en alaedje li djournå" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "I vs fåt on cliyint ki sopoite x:data por vos poleur apontyî l' såle" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Nombe di prezints" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privé, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "" #: mod_muc/mod_muc_room.erl:3809 #, fuzzy msgid "User JID" msgstr "Uzeu " #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s vos preye sol såle ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "li scret est" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "Li cawêye di messaedjes e môde disraloyî di vosse soçon est plinne. Li " "messaedje a stî tapé å diale." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "messaedjes ki ratindèt el cawêye po ~s" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Candjmints evoyîs" #: mod_offline.erl:571 msgid "Time" msgstr "Date" #: mod_offline.erl:572 msgid "From" msgstr "Di" #: mod_offline.erl:573 msgid "To" msgstr "Po" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Paket" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Disfacer les elemints tchoezis" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Messaedjes ki ratindèt:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 #, fuzzy msgid "Remove All Offline Messages" msgstr "Messaedjes ki ratindèt" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "Module SOCKS5 Bytestreams po ejabberd" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Eplaidaedje-abounmint" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "Module d' eplaidaedje-abounmint po ejabberd" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Dimande d' eplaidaedje-abounmint d' èn abouné" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Tchoezi s' i fåt aprover ou nén l' abounmint di ciste intité." #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ID d' nuk" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Adresse di l' abouné" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "" "Permete ki ci Jabber ID ci si poye abouner a ç' nuk eplaidaedje-abounmint ci?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Evoyî l' contnou avou les notifiaedjes d' evenmints" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Evoyî des notifiaedjes d' evenmints" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Notifyî åzès abounés cwand l' apontiaedje do nuk candje" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Notifyî åzès abounés cwand l' nuk est disfacé" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Notifyî åzès abounés cwand des cayets sont oisté foû do nuk" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Cayets permanints a wårder" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "On no uzeu-ahessåve pol nuk" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Nombe macsimoms di cayets permanints" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Si on permete les abounmints" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Sipecifyî l' modele d' accès" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Pårtaedjîs groupes di soçons k' on s' î pout abouner" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Dinez l' modele d' eplaideu" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 #, fuzzy msgid "Specify the event message type" msgstr "Sipecifyî l' modele d' accès" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Contnou macsimom en octets" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Cwand evoyî l' dierin cayet eplaidî" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Seulmint evoyî des notifiaedje åzès uzeus disponibes" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "" #: mod_register.erl:220 #, fuzzy msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "Vos avoz mezåjhe d' on cliyint ki sopoite x:data po-z edjîstrer on metou no" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "" "Tchoezixhoz on no d' uzeu eyet on scret po vs edjîstrer so ç' sierveu ci" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Uzeu" #: mod_register.erl:316 mod_register.erl:361 #, fuzzy msgid "The password is too weak" msgstr "li scret est" #: mod_register.erl:365 #, fuzzy msgid "Users are not allowed to register accounts so quickly" msgstr "Les noveas uzeus n' si polèt nén edjîstrer si raddimint" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Nole" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Abounmimnt" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Ratindant" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Groupes" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Valider" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Oister" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Djivêye des soçons da " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Mwais fôrmat" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Radjouter èn ID Jabber" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Djivêye des soçons" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Pårtaedjîs groupes ezès djivêyes di soçons" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Radjouter" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Pitit no:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Discrijhaedje:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Mimbes:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Groupes håynés:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Groupe " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Evoyî" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Sierveu Jabber Erlang" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Date d' askepiaedje" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Veye" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Payis" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Emile" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "No d' famile" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Rimplixhoz les tchamps do formulaire po cweri èn uzeu Jabber (radjouter «*» " "al fén do tchamp po cweri tot l' minme kéne fén d' tchinne" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "No etir" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "No do mitan" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "No" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "No d' l' organizåcion" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Unité d' l' organizåcion" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Cweri des uzeus dins " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Vos avoz mezåjhe d' on cliyint ki sopoite x:data po fé on cweraedje" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Calpin des uzeus" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "Module vCard ejabberd" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Rizultats do cweraedje po " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Rimplixhoz les tchamps po cweri èn uzeu Jabber" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "Manaedjeu waibe ejabberd" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Manaedjaedje" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Dinêyes brutes" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Apontiaedje des rîles d' accès a ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Forveyous sierveus" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Uzeus" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Dierinne activité des uzeus" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Termene:" #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Dierin moes" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Dierinne anêye" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Dispoy todi" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Mostrer crexhince" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Mostrer totå" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Sitatistikes" #: web/ejabberd_web_admin.erl:1117 #, fuzzy msgid "Not Found" msgstr "Nuk nén trové" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Nuk nén trové" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Sierveu" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Uzeus edjistrés" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Messaedjes ki ratindèt" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Dierinne activité" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Uzeus edjistrés:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Uzeus raloyîs:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Raloyaedjes s2s e rexhowe:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Sierveus s2s e rexhowe:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Candjî l' sicret" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Uzeu " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Raloyî avou les rsoûces:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Sicret:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Nole dinêye disponibe" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Nuks" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Nuk " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Pôrts drovous" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Mete a djoû" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Renonder" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Arester" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Aroke di houcaedje RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Tåves del båze di dnêyes so " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Sôre di wårdaedje" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Memwere" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Copeye di såvrité po " #: web/ejabberd_web_admin.erl:2036 #, fuzzy msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Notez ki ces tchuzes la vont seulmint fé ene copeye di såvrité del båze di " "dnêyes Mnesia costrûte å dvins do programe. Si vos eployîz ene difoûtrinne " "båze di dnêyes avou l' module ODBC, vos dvoz fé ene copeye di såvrité del " "båze SQL da vosse sepårumint." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Copeye di såvrité binaire:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "'l est bon" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Rapexhî do côp foû d' ene copeye di såvrité binaire:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Rapexhî l' copeye di såvrité binaire après l' renondaedje ki vént " "d' ejabberd (çoula prind moens d' memwere del fé insi):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Copeye di såvrité tecse:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Rapexhî do côp foû d' ene copeye di såvrité tecse:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2099 #, fuzzy msgid "Import user data from jabberd14 spool file:" msgstr "Sititchî des uzeus Jabberd 1.4" #: web/ejabberd_web_admin.erl:2106 #, fuzzy msgid "Import users data from jabberd14 spool directory:" msgstr "Sititchî des uzeus Jabberd 1.4" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Pôrts drovous so " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Modules so " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Sitatistikes di ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Tins dispoy l' enondaedje:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Tins CPU:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transaccions evoyeyes:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transaccions arestêyes:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transaccions renondêyes:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transaccions wårdêyes e djournå:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Metaedje a djoû " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Plan d' metaedje a djoû" #: web/ejabberd_web_admin.erl:2255 #, fuzzy msgid "Modified modules" msgstr "Modules metous a djoû" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Sicripe di metaedje a djoû" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Sicripe di metaedje a djoû d' bas livea" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Acertinaedje do scripe" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Pôrt" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "" #: web/ejabberd_web_admin.erl:2428 #, fuzzy msgid "Protocol" msgstr "Pôrt" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Module" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Tchuzes" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Disfacer" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Enonder" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "" #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "" #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "" #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 #, fuzzy msgid "Username:" msgstr "No d' uzeu IRC" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 #, fuzzy msgid "Server:" msgstr "Måy" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 #, fuzzy msgid "Password Verification:" msgstr "Acertinaedje do scret" #: web/mod_register_web.erl:250 #, fuzzy msgid "Register" msgstr "Djivêye des soçons" #: web/mod_register_web.erl:396 #, fuzzy msgid "Old Password:" msgstr "Sicret:" #: web/mod_register_web.erl:401 #, fuzzy msgid "New Password:" msgstr "Sicret:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "" #~ msgid "Encodings" #~ msgstr "Ecôdaedjes" #~ msgid "(Raw)" #~ msgstr "(Dinêyes brutes)" #~ msgid "Specified nickname is already registered" #~ msgstr "Li no metou dné est ddja edjîstré" #~ msgid "Size" #~ msgstr "Grandeu" ejabberd-2.1.11/src/msgs/cs.msg0000664000000000000000000006601112240230175013077 0ustar {"Access Configuration","Konfigurace přístupů"}. {"Access Control List Configuration","Konfigurace seznamu přístupových práv (ACL)"}. {"Access control lists","Seznamy přístupových práv (ACL)"}. {"Access Control Lists","Seznamy přístupových práv (ACL)"}. {"Access denied by service policy","Přístup byl zamítnut nastavením služby"}. {"Access rules","Pravidla přístupů"}. {"Access Rules","Pravidla přístupů"}. {"Action on user","Akce aplikovaná na uživatele"}. {"Add Jabber ID","Přidat Jabber ID"}. {"Add New","Přidat nový"}. {"Add User","Přidat uživatele"}. {"Administration","Administrace"}. {"Administration of ","Administrace "}. {"Administrator privileges required","Potřebujete práva administrátora"}. {"A friendly name for the node","Přívětivé jméno pro uzel"}. {"All activity","Všechny aktivity"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Povolit tomuto Jabber ID odebírat tento pubsub uzel?"}. {"Allow users to change the subject","Povolit uživatelům měnit téma místnosti"}. {"Allow users to query other users","Povolit uživatelům odesílat požadavky (query) ostatním uživatelům"}. {"Allow users to send invites","Povolit uživatelům posílání pozvánek"}. {"Allow users to send private messages","Povolit uživatelům odesílat soukromé zprávy"}. {"Allow visitors to change nickname","Povolit návštěvníkům měnit přezdívku"}. {"Allow visitors to send private messages to","Povolit návštěvníkům odesílat soukromé zprávy"}. {"Allow visitors to send status text in presence updates","Povolit návštěvníkům posílat stavové zprávy ve statusu"}. {"Allow visitors to send voice requests","Povolit uživatelům posílat žádosti o voice práva"}. {"All Users","Všichni uživatelé"}. {"Announcements","Oznámení"}. {"anyone","každému"}. {"A password is required to enter this room","Pro vstup do místnosti musíte zadat heslo"}. {"April",". dubna"}. {"August",". srpna"}. {"Backup Management","Správa zálohování"}. {"Backup of ","Záloha na "}. {"Backup to File at ","Záloha do souboru na "}. {"Backup","Zálohovat"}. {"Bad format","Nesprávný formát"}. {"Birthday","Datum narození"}. {"CAPTCHA web page","Webová stránka CAPTCHA"}. {"Change Password","Změnit heslo"}. {"Change User Password","Změnit heslo uživatele"}. {"Characters not allowed:","Nepřípustné znaky:"}. {"Chatroom configuration modified","Nastavení diskuzní místnosti bylo změněno"}. {"Chatroom is created","Konference vytvořena"}. {"Chatroom is destroyed","Konference zrušena"}. {"Chatroom is started","Konference spuštěna"}. {"Chatroom is stopped","Konference zastavena"}. {"Chatrooms","Konference"}. {"Choose a username and password to register with this server","Zadejte jméno uživatele a heslo pro registraci na tomto serveru"}. {"Choose modules to stop","Vyberte moduly, které mají být zastaveny"}. {"Choose storage type of tables","Vyberte typ úložiště pro tabulky"}. {"Choose whether to approve this entity's subscription.","Zvolte, zda chcete schválit odebírání touto entitou"}. {"City","Město"}. {"Commands","Příkazy"}. {"Conference room does not exist","Konferenční místnost neexistuje"}. {"Configuration","Konfigurace"}. {"Configuration of room ~s","Konfigurace místnosti ~s"}. {"Connected Resources:","Připojené zdroje:"}. {"Connections parameters","Parametry spojení"}. {"Country","Země"}. {"CPU Time:","Čas procesoru"}. {"Database","Databáze"}. {"Database Tables at ","Databázové tabulky na "}. {"Database Tables Configuration at ","Konfigurace databázových tabulek "}. {"December",". prosince"}. {"Default users as participants","Uživatelé jsou implicitně členy"}. {"Delete message of the day on all hosts","Smazat zprávu dne na všech hostitelích"}. {"Delete message of the day","Smazat zprávu dne"}. {"Delete Selected","Smazat vybrané"}. {"Delete","Smazat"}. {"Delete User","Smazat uživatele"}. {"Deliver event notifications","Doručovat upozornění na události"}. {"Deliver payloads with event notifications","Doručovat náklad s upozorněním na událost"}. {"Description:","Popis:"}. {"Disc only copy","Jen kopie disku"}. {"Displayed Groups:","Zobrazené skupiny:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Nikdy nikomu nesdělujte své heslo, ani administrátorovi serveru Jabberu."}. {"Dump Backup to Text File at ","Uložit zálohu do textového souboru na "}. {"Dump to Text File","Uložit do textového souboru"}. {"Edit Properties","Upravit vlastnosti"}. {"Either approve or decline the voice request.","Povolit nebo odmítnout voice žádost."}. {"ejabberd IRC module","ejabberd IRC modul"}. {"ejabberd MUC module","ejabberd MUC modul"}. {"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe modul"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams modul"}. {"ejabberd vCard module","ejabberd vCard modul"}. {"ejabberd Web Admin","Webová administrace ejabberd"}. {"Elements","Položek"}. {"Email","E-mail"}. {"Enable logging","Zaznamenávat konverzace"}. {"Encoding for server ~b","Kódování pro server ~b"}. {"End User Session","Ukončit sezení uživatele"}. {"Enter list of {Module, [Options]}","Vložte seznam modulů {Modul, [Parametry]}"}. {"Enter nickname you want to register","Zadejte přezdívku, kterou chcete zaregistrovat"}. {"Enter path to backup file","Zadajte cestu k souboru se zálohou"}. {"Enter path to jabberd14 spool dir","Zadejte cestu k jabberd14 spool adresáři"}. {"Enter path to jabberd14 spool file","Zadejte cestu k spool souboru jabberd14"}. {"Enter path to text file","Zadajte cestu k textovému souboru"}. {"Enter the text you see","Zadejte text, který vidíte"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Zadejte přezdívku a kódování, které chcete používat pro připojení k serverům IRC. Stiskněte 'Další' pro více políček k vyplnění. Stiskněte 'Dokončit' pro uložení nastavení."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Zadejte přezdívku, kódování, porty a hesla, které chcete používat pro připojení k serverům IRC"}. {"Erlang Jabber Server","Erlang Jabber Server"}. {"Error","Chyba"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Příklad: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].2\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Vyloučit Jabber ID z procesu CAPTCHA ověřování"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exportovat všechny uživatele do souboru ve formátu PIEFXIS (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Exportovat uživatele na hostiteli do souboru ve formátu PIEFXIS (XEP-0227):"}. {"Failed to extract JID from your voice request approval","Došlo k chybě při získávání Jabber ID z vaší žádosti o voice práva"}. {"Family Name","Příjmení"}. {"February",". února"}. {"Fill in fields to search for any matching Jabber User","Vyplňte políčka pro vyhledání uživatele Jabberu"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Pro vyhledání uživatele Jabberu vyplňte formulář (na konec přidejte znak * pro vyhledání podřetězce)"}. {"Friday","Pátek"}. {"From","Od"}. {"From ~s","Od ~s"}. {"Full Name","Celé jméno"}. {"Get Number of Online Users","Získat počet online uživatelů"}. {"Get Number of Registered Users","Získat počet registrovaných uživatelů"}. {"Get User Last Login Time","Získat čas podleního přihlášení uživatele"}. {"Get User Password","Získat heslo uživatele"}. {"Get User Statistics","Získat statistiky uživatele"}. {"Grant voice to this person?","Udělit voice práva této osobě?"}. {"Group ","Skupina "}. {"Groups","Skupiny"}. {"has been banned","byl(a) zablokován(a)"}. {"has been kicked because of an affiliation change","byl(a) vyhozen(a) kvůli změně přiřazení"}. {"has been kicked because of a system shutdown","byl(a) vyhozen(a), protože dojde k vypnutí systému"}. {"has been kicked because the room has been changed to members-only","byl(a) vyhozen(a), protože mísnost je nyní pouze pro členy"}. {"has been kicked","byl(a) vyhozen(a) z místnosti"}. {" has set the subject to: "," změnil(a) téma na: "}. {"Host","Hostitel"}. {"If you don't see the CAPTCHA image here, visit the web page.","Pokud zde nevidíte obrázek CAPTCHA, přejděte na webovou stránku."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Pokud chcete zadat jiné kódování pro IRC servery, vyplňte seznam s hodnotami ve formátu '{\"irc server\",\"encoding\", port, \"password\"}'. Výchozí kódování pro tuto službu je \"~s\", port ~p, empty password."}. {"Import Directory","Import adresáře"}. {"Import File","Import souboru"}. {"Import user data from jabberd14 spool file:","Importovat uživatele z jabberd14 spool souborů:"}. {"Import User from File at ","Importovat uživatele ze souboru na "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importovat uživatele ze souboru ve formátu PIEFXIS (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Importovat uživatele z jabberd14 spool souborů:"}. {"Import Users from Dir at ","Importovat uživatele z adresáře na "}. {"Import Users From jabberd14 Spool Files","Importovat uživatele z jabberd14 spool souborů"}. {"Improper message type","Nesprávný typ zprávy"}. {"Incorrect password","Nesprávné heslo"}. {"Invalid affiliation: ~s","Neplatné přiřazení: ~s"}. {"Invalid role: ~s","Neplatná role: ~s"}. {"IP addresses","IP adresy"}. {"IP","IP"}. {"IRC channel (don't put the first #)","IRC kanál (bez počátečního #)"}. {"IRC server","IRC přezdívka"}. {"IRC settings","Nastavení IRC"}. {"IRC Transport","IRC transport"}. {"IRC username","IRC přezdívka"}. {"IRC Username","IRC přezdívka"}. {"is now known as","se přejmenoval(a) na"}. {"It is not allowed to send private messages","Je zakázáno posílat soukromé zprávy"}. {"It is not allowed to send private messages of type \"groupchat\"","Není dovoleno odeslání soukromé zprávy typu \"skupinová zpráva\" "}. {"It is not allowed to send private messages to the conference","Není povoleno odesílat soukromé zprávy do konference"}. {"Jabber Account Registration","Registrace účtu Jabberu"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Jabber ID ~s je neplatné"}. {"January",". ledna"}. {"Join IRC channel","Vstoupit do IRC kanálu"}. {"joins the room","vstoupil(a) do místnosti"}. {"Join the IRC channel here.","Vstoupit do tohoto IRC kanálu."}. {"Join the IRC channel in this Jabber ID: ~s","Vstupte do IRC kanálu s tímto Jabber ID: ~s"}. {"July",". července"}. {"June",". června"}. {"Last Activity","Poslední aktivita"}. {"Last login","Poslední přihlášení"}. {"Last month","Poslední měsíc"}. {"Last year","Poslední rok"}. {"leaves the room","opustil(a) místnost"}. {"Listened Ports at ","Otevřené porty na "}. {"Listened Ports","Otevřené porty"}. {"List of modules to start","Seznam modulů, které mají být spuštěné"}. {"Low level update script","Nízkoúrovňový aktualizační skript"}. {"Make participants list public","Nastavit seznam účastníků jako veřejný"}. {"Make room CAPTCHA protected","Chránit místnost pomocí CAPTCHA"}. {"Make room members-only","Zpřístupnit místnost jen členům"}. {"Make room moderated","Nastavit místnost jako moderovanou"}. {"Make room password protected","Chránit místnost heslem"}. {"Make room persistent","Nastavit místnost jako stálou"}. {"Make room public searchable","Nastavit místnost jako veřejnou"}. {"March",". března"}. {"Maximum Number of Occupants","Počet účastníků"}. {"Max # of items to persist","Maximální počet položek, které je možné natrvalo uložit"}. {"Max payload size in bytes","Maximální náklad v bajtech"}. {"May",". května"}. {"Members:","Členové:"}. {"Membership is required to enter this room","Pro vstup do místnosti musíte být členem"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Svoje heslo si zapamatujte, nebo si jej poznamenejte na papírek a ten uschovejte v bezpečí. Jabber nemá žádný automatizovaný způsob obnovy hesla."}. {"Memory","Paměť"}. {"Message body","Tělo zprávy"}. {"Middle Name","Druhé jméno"}. {"Minimum interval between voice requests (in seconds)","Minimální interval mezi žádostmi o voice práva (v sekundách)"}. {"Moderator privileges required","Potřebujete práva moderátora"}. {"moderators only","moderátorům"}. {"Modified modules","Aktualizované moduly"}. {"Module","Modul"}. {"Modules at ","Moduly na "}. {"Modules","Moduly"}. {"Monday","Pondělí"}. {"Name:","Jméno:"}. {"Name","Jméno"}. {"Never","Nikdy"}. {"New Password:","Nové heslo:"}. {"Nickname","Přezdívka"}. {"Nickname Registration at ","Registrace přezdívky na "}. {"Nickname ~s does not exist in the room","Přezdívka ~s v místnosti neexistuje"}. {"nobody","nikdo"}. {"No body provided for announce message","Zpráva neobsahuje text"}. {"No Data","Žádná data"}. {"Node ID","ID uzlu"}. {"Node not found","Uzel nenalezen"}. {"Nodes","Uzly"}. {"Node ","Uzel "}. {"No limit","Bez limitu"}. {"None","Nic"}. {"No resource provided","Nebyl poskytnut žádný zdroj"}. {"Not Found","Nenalezeno"}. {"Notify subscribers when items are removed from the node","Upozornit odběratele na odstranění položek z uzlu"}. {"Notify subscribers when the node configuration changes","Upozornit odběratele na změnu nastavení uzlu"}. {"Notify subscribers when the node is deleted","Upozornit odběratele na smazání uzlu"}. {"November",". listopadu"}. {"Number of occupants","Počet účastníků"}. {"Number of online users","Počet online uživatelů"}. {"Number of registered users","Počet registrovaných uživatelů"}. {"October",". října"}. {"Offline Messages:","Offline zprávy:"}. {"Offline Messages","Offline zprávy"}. {"OK","OK"}. {"Old Password:","Současné heslo:"}. {"Online","Online"}. {"Online Users:","Online uživatelé:"}. {"Online Users","Online uživatelé"}. {"Only deliver notifications to available users","Doručovat upozornění jen právě přihlášeným uživatelům"}. {"Only moderators and participants are allowed to change the subject in this room","Jen moderátoři a účastníci mají povoleno měnit téma této místnosti"}. {"Only moderators are allowed to change the subject in this room","Jen moderátoři mají povoleno měnit téma místnosti"}. {"Only moderators can approve voice requests","Pouze moderátoři mohou schválit žádosti o voice práva"}. {"Only occupants are allowed to send messages to the conference","Jen členové mají povolené zasílat zprávy do konference"}. {"Only occupants are allowed to send queries to the conference","Jen členové mohou odesílat požadavky (query) do konference"}. {"Only service administrators are allowed to send service messages","Pouze správci služby smí odesílat servisní zprávy"}. {"Options","Nastavení"}. {"Organization Name","Název firmy"}. {"Organization Unit","Oddělení"}. {"Outgoing s2s Connections:","Odchozí s2s spojení:"}. {"Outgoing s2s Connections","Odchozí s2s spojení"}. {"Outgoing s2s Servers:","Odchozí s2s servery:"}. {"Owner privileges required","Jsou vyžadována práva vlastníka"}. {"Packet","Paket"}. {"Password ~b","Heslo ~b"}. {"Password:","Heslo:"}. {"Password","Heslo"}. {"Password Verification:","Ověření hesla:"}. {"Password Verification","Ověření hesla"}. {"Path to Dir","Cesta k adresáři"}. {"Path to File","Cesta k souboru"}. {"Pending","Čekající"}. {"Period: ","Čas: "}. {"Persist items to storage","Uložit položky natrvalo do úložiště"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Podotýkáme, že tato nastavení budou zálohována do zabudované databáze Mnesia. Pokud používáte ODBC modul, musíte zálohovat svoji SQL databázi samostatně."}. {"Please, wait for a while before sending new voice request","Prosím, počkejte chvíli před posláním nové žádosti o voice práva"}. {"Pong","Pong"}. {"Port ~b","Port ~b"}. {"Port","Port"}. {"Present real Jabber IDs to","Odhalovat skutečná Jabber ID"}. {"private, ","soukromá, "}. {"Protocol","Protokol"}. {"Publish-Subscribe","Publish-Subscribe"}. {"PubSub subscriber request","Žádost odběratele PubSub"}. {"Purge all items when the relevant publisher goes offline","Smazat všechny položky, pokud se příslušný poskytovatel odpojí"}. {"Queries to the conference members are not allowed in this room","Požadavky (queries) na členy konference nejsou v této místnosti povolené"}. {"RAM and disc copy","Kopie RAM a disku"}. {"RAM copy","Kopie RAM"}. {"Raw","Zdroj"}. {"Really delete message of the day?","Skutečně smazat zprávu dne?"}. {"Recipient is not in the conference room","Příjemce se nenachází v konferenční místnosti"}. {"Register a Jabber account","Zaregistrujte si účet Jabberu"}. {"Registered Users","Registrovaní uživatelé"}. {"Registered Users:","Registrovaní živatelé:"}. {"Register","Zaregistrovat se"}. {"Registration in mod_irc for ","Registrace do mod_irc na "}. {"Remote copy","Vzdálená kopie"}. {"Remove All Offline Messages","Odstranit všechny offline zprávy"}. {"Remove","Odstranit"}. {"Remove User","Odstranit uživatele"}. {"Replaced by new connection","Nahrazeno novým spojením"}. {"Resources","Zdroje"}. {"Restart","Restart"}. {"Restart Service","Restartovat službu"}. {"Restore Backup from File at ","Obnovit zálohu ze souboru na "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Obnovit binární zálohu při následujícím restartu ejabberd (vyžaduje méně paměti)"}. {"Restore binary backup immediately:","Okamžitě obnovit binární zálohu:"}. {"Restore","Obnovit"}. {"Restore plain text backup immediately:","Okamžitě obnovit zálohu z textového souboru:"}. {"Room Configuration","Nastavení místnosti"}. {"Room creation is denied by service policy","Pravidla služby nepovolují vytvořit místnost"}. {"Room description","Popis místnosti"}. {"Room Occupants","Počet účastníků"}. {"Room title","Název místnosti"}. {"Roster groups allowed to subscribe","Skupiny kontaktů, které mohou odebírat"}. {"Roster of ","Seznam kontaktů "}. {"Roster","Seznam kontaktů"}. {"Roster size","Velikost seznamu kontaktů"}. {"RPC Call Error","Chyba RPC volání"}. {"Running Nodes","Běžící uzly"}. {"~s access rule configuration","~s konfigurace pravidla přístupu"}. {"Saturday","Sobota"}. {"Script check","Kontrola skriptu"}. {"Search Results for ","Výsledky hledání pro "}. {"Search users in ","Hledat uživatele v "}. {"Send announcement to all online users","Odeslat oznámení všem online uživatelům"}. {"Send announcement to all online users on all hosts","Odeslat oznámení všem online uživatelům na všech hostitelích"}. {"Send announcement to all users","Odeslat oznámení všem uživatelům"}. {"Send announcement to all users on all hosts","Odeslat oznámení všem uživatelům na všech hostitelích"}. {"September",". září"}. {"Server ~b","Server ~b"}. {"Server:","Server:"}. {"Set message of the day and send to online users","Nastavit zprávu dne a odeslat ji online uživatelům"}. {"Set message of the day on all hosts and send to online users","Nastavit zprávu dne a odeslat ji online uživatelům"}. {"Shared Roster Groups","Skupiny pro sdílený seznam kontaktů"}. {"Show Integral Table","Zobrazit kompletní tabulku"}. {"Show Ordinary Table","Zobrazit běžnou tabulku"}. {"Shut Down Service","Vypnout službu"}. {"~s invites you to the room ~s","~s vás zve do místnosti ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Někteří klienti umí uložit vaše heslo na disk počítače. Tuto funkci používejte, pouze pokud věříte zabezpečení svého počítače."}. {"Specify the access model","Uveďte přístupový model"}. {"Specify the event message type","Zvolte typ zpráv pro události"}. {"Specify the publisher model","Specifikovat model pro publikování"}. {"~s's Offline Messages Queue","Fronta offline zpráv uživatele ~s"}. {"Start Modules at ","Spustit moduly na "}. {"Start Modules","Spustit moduly"}. {"Start","Start"}. {"Statistics of ~p","Statistiky ~p"}. {"Statistics","Statistiky"}. {"Stop Modules at ","Zastavit moduly na "}. {"Stop Modules","Zastavit moduly"}. {"Stopped Nodes","Zastavené uzly"}. {"Stop","Stop"}. {"Storage Type","Typ úložiště"}. {"Store binary backup:","Uložit binární zálohu:"}. {"Store plain text backup:","Uložit zálohu do textového souboru:"}. {"Subject","Předmět"}. {"Submit","Odeslat"}. {"Submitted","Odeslané"}. {"Subscriber Address","Adresa odběratele"}. {"Subscription","Přihlášení"}. {"Sunday","Neděle"}. {"That nickname is already in use by another occupant","Přezdívka je již používána jiným členem"}. {"That nickname is registered by another person","Přezdívka je zaregistrována jinou osobou"}. {"The CAPTCHA is valid.","CAPTCHA souhlasí."}. {"The CAPTCHA verification has failed","Ověření CAPTCHA se nezdařilo"}. {"The collections with which a node is affiliated","Kolekce, se kterými je uzel spřízněn"}. {"the password is","heslo je"}. {"The password is too weak","Heslo je příliš slabé"}. {"The password of your Jabber account was successfully changed.","Heslo vašeho účtu Jabberu bylo úspěšně změněno."}. {"There was an error changing the password: ","Při změně hesla došlo k chybě: "}. {"There was an error creating the account: ","Při vytváření účtu došlo k chybě."}. {"There was an error deleting the account: ","Při mazání účtu došlo k chybě: "}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Zde nezáleží na velikosti písmen: macbeth je stejný jako MacBeth a Macbeth."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Na této stránce si můžete vytvořit účet na tomto serveru Jabberu. Vaše JID (Jabber IDentifikátor) bude mít tvar: uživatelskéjméno@server. Přečtěte si prosím pozorně instrukce pro vyplnění údajů."}. {"This page allows to unregister a Jabber account in this Jabber server.","Zde můžete zrušit registraci účtu na tomto serveru Jabberu."}. {"This participant is kicked from the room because he sent an error message","Tento účastník byl vyhozen, protože odeslal chybovou zprávu"}. {"This participant is kicked from the room because he sent an error message to another participant","Tento účastník byl vyhozen, protože odeslal chybovou zprávu jinému účastníkovi"}. {"This participant is kicked from the room because he sent an error presence","Tento účastník byl vyhozen, protože odeslal chybový status"}. {"This room is not anonymous","Tato místnost není anonymní"}. {"Thursday","Čtvrtek"}. {"Time","Čas"}. {"Time delay","Časový posun"}. {"Too many CAPTCHA requests","Přiliš mnoho CAPTCHA žádostí"}. {"To","Pro"}. {"To ~s","Pro ~s"}. {"Traffic rate limit is exceeded","Byl překročen limit"}. {"Transactions Aborted:","Transakce zrušena"}. {"Transactions Committed:","Transakce potvrzena"}. {"Transactions Logged:","Transakce zaznamenána"}. {"Transactions Restarted:","Transakce restartována"}. {"Tuesday","Úterý"}. {"Unable to generate a CAPTCHA","Nebylo možné vygenerovat CAPTCHA"}. {"Unauthorized","Nemáte oprávnění"}. {"Unregister a Jabber account","Zrušte registraci účtu Jabberu"}. {"Unregister","Zrušit registraci"}. {"Update ","Aktualizovat "}. {"Update","Aktualizovat"}. {"Update message of the day (don't send)","Aktualizovat zprávu dne (neodesílat)"}. {"Update message of the day on all hosts (don't send)","Aktualizovat zprávu dne pro všechny hostitele (neodesílat)"}. {"Update plan","Aktualizovat plán"}. {"Update script","Aktualizované skripty"}. {"Uptime:","Čas běhu:"}. {"Use of STARTTLS required","Je vyžadováno STARTTLS"}. {"User JID","Jabber ID uživatele"}. {"User Management","Správa uživatelů"}. {"Username:","Uživatelské jméno:"}. {"Users are not allowed to register accounts so quickly","Je zakázáno registrovat účty v tak rychlém sledu"}. {"Users Last Activity","Poslední aktivita uživatele"}. {"Users","Uživatelé"}. {"User ","Uživatel "}. {"User","Uživatel"}. {"Validate","Ověřit"}. {"vCard User Search","Hledání uživatelů podle vizitek"}. {"Virtual Hosts","Virtuální hostitelé"}. {"Visitors are not allowed to change their nicknames in this room","Návštěvníkům této místnosti je zakázáno měnit přezdívku"}. {"Visitors are not allowed to send messages to all occupants","Návštevníci nemají povoleno zasílat zprávy všem účastníkům konference"}. {"Voice requests are disabled in this conference","Voice žádosti jsou v této konferenci zakázány"}. {"Voice request","Žádost o voice práva"}. {"Wednesday","Středa"}. {"When to send the last published item","Kdy odeslat poslední publikovanou položku"}. {"Whether to allow subscriptions","Povolit odebírání"}. {"You can later change your password using a Jabber client.","Později můžete své heslo změnit pomocí klienta Jabberu."}. {"You have been banned from this room","Byl jste vyloučen z této místnosti"}. {"You must fill in field \"Nickname\" in the form","Musíte vyplnit políčko \"Přezdívka\" ve formuláři"}. {"You need a client that supports x:data and CAPTCHA to register","Pro registraci potřebujete klienta s podporou x:data a CAPTCHA"}. {"You need a client that supports x:data to register the nickname","Pro registraci přezdívky potřebujete klienta s podporou x:data"}. {"You need an x:data capable client to configure mod_irc settings","Pro konfiguraci mod_irc potřebujete klienta s podporou x:data"}. {"You need an x:data capable client to configure room","Ke konfiguraci místnosti potřebujete klienta podporujícího x:data"}. {"You need an x:data capable client to search","K vyhledávání potřebujete klienta podporujícího x:data"}. {"Your active privacy list has denied the routing of this stanza.","Vaše nastavení soukromí znemožnilo směrování této stance."}. {"Your contact offline message queue is full. The message has been discarded.","Fronta offline zpráv pro váš kontakt je plná. Zpráva byla zahozena."}. {"Your Jabber account was successfully created.","Váš účet Jabberu byl úspěšně vytvořen."}. {"Your Jabber account was successfully deleted.","Váš účet Jabberu byl úspěšně smazán."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Nesmíte posílat zprávy na ~s. Pro povolení navštivte ~s"}. ejabberd-2.1.11/src/msgs/sv.po0000664000000000000000000014775712240230175012773 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "Last-Translator: Gustaf Alströmer\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Swedish (svenska)\n" "X-Additional-Translator: Thore Alstromer\n" "X-Additional-Translator: Heysan\n" "X-Additional-Translator: Magnus Henoch\n" "X-Additional-Translator: Jonas Ådahl\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Du måste använda STARTTLS" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Ingen resurs angiven" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Ersatt av ny anslutning" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Skriv in sökväg till textfil" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "Dina meddelanden till ~s är blockerade. För att avblockera dem, gå till ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "Din CAPTCHA är godkänd." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Kommandon" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Verkligen ta bort dagens meddelanden?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Ämne" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Meddelande kropp" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Ingen kropp behövs för dessa meddelanden" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Meddelanden" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Sänd meddelanden till alla användare" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Sänd meddelanden till alla användare på alla värdar" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Sänd meddelanden till alla inloggade användare" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Sänd meddelanden till alla inloggade användare på alla värdar" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Sätt dagens status meddelande och skicka till alla användare" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Sätt dagens status meddelande pa alla värdar och skicka till alla användare" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Uppdatera dagens status meddelande (skicka inte)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Uppdatera dagens status meddelande på alla värdar (skicka inte)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Ta bort dagens meddelande" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Ta bort dagens meddelande på alla värdar" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Konfiguration" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Databas" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Starta moduler" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Stanna moduler" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Säkerhetskopiera" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Återställ" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Dumpa till textfil" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Importera fil" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Importera katalog" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Starta om servicen" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Stäng ner servicen" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Lägg till användare" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Ta bort användare" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Avsluta användarsession" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Hämta användarlösenord" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Andra användarlösenord" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Hämta användarens senast inloggade tid" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Hämta användarstatistik" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Hämta antal registrerade användare" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Hämta antal inloggade användare" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "ACL" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Åtkomstregler" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Användarmanagement" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Anslutna användare" #: mod_configure.erl:501 msgid "All Users" msgstr "Alla användare" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Utgaende s2s anslutning" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Körande noder" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Stannade noder" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Moduler" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Hantera säkerhetskopior" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importera användare från jabberd14 Spool filer" #: mod_configure.erl:699 msgid "To ~s" msgstr "Till ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Från ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Databastabellers konfiguration" #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Välj lagringstyp för tabeller" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Endast diskkopia" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "RAM- och diskkopia" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "RAM-kopia" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Sparas inte lokalt" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Stoppa moduler på " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Välj vilka moduler som skall stoppas" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Starta moduler på " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Skriv in en lista av {Module, [Options]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Lista av moduler som skall startas" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Säkerhetskopiera till fil på " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Skriv in sökväg till fil för säkerhetskopia" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Sökväg till fil" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Återställ säkerhetskopia från fil på " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Dumpa säkerhetskopia till textfil på " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Skriv in sökväg till textfil" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importera användare från fil på " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Skriv in sökväg till spoolfil från jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importera användare från katalog på " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Skriv in sökväg till spoolkatalog från jabberd14" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Sökväg till katalog" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Tidsförsening" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Konfiguera ACL" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "ACL" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Åtkomstkonfiguration" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Åtkomstregler" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Lösenord" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Lösenordsverifikation" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Antal registrerade användare" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Antal inloggade användare" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Aldrig" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Ansluten" #: mod_configure.erl:1701 msgid "Last login" msgstr "Senaste login" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Roster storlek" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "IP adresser" #: mod_configure.erl:1724 msgid "Resources" msgstr "Resurser" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Administration av " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Handling mot användare" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Redigera egenskaper" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Ta bort användare" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Åtkomst nekad enligt lokal policy" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC transport" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC-modul" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "Du behöer en klient som stöjer x:data för att konfigurera mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "mod_irc-registrering för " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Skriv in användarnamn och textkodning du vill använda för att ansluta till " "IRC-servrar" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "IRC-användarnamn" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Om du vill specifiera textkodning för IRC-servrar, fyll i listan med värden " "i formatet '{\"irc server\", \"encoding\", port, \"password\"}'. Som " "standard används \"~s\", port ~p, no password." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Exempel: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Uppkopplingsparametrar" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Lägg till IRC kanal" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "IRC kanal (skriv inte första #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "IRC-användarnamn" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Lägg till IRC kanal här." #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Lägg till IRC kanal till detta Jabber ID: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "IRC Inställningar" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 #, fuzzy msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Skriv in användarnamn och textkodning du vill använda för att ansluta till " "IRC-servrar" #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "IRC-användarnamn" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Lösenord ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Port ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Encoding för server ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Server ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "Endast administratörer får skicka tjänstmeddelanden" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Skapandet av rum är förbjudet enligt lokal policy" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Rummet finns inte" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Chattrum" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 #, fuzzy msgid "You need a client that supports x:data to register the nickname" msgstr "Du behöver en klient som stödjer x:data för att registrera smeknamn" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Registrera smeknamn på " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Skriv in smeknamnet du vill registrera" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Smeknamn" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Smeknamnet är reserverat" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Du måste fylla i fält \"smeknamn\" i formen" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC modul" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Chattrum konfiguration modifierad" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "joinar rummet" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "lämnar rummet" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "har blivit bannad" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "har blivit kickad" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "har blivit kickad p.g.a en ändring av tillhörighet" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "har blivit kickad p.g.a att rummet har ändrats till endast användare" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "har blivit kickad p.g.a en systemnerstängning" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "är känd som" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " har satt ämnet till: " #: mod_muc/mod_muc_log.erl:452 #, fuzzy msgid "Chatroom is created" msgstr "Chattrum" #: mod_muc/mod_muc_log.erl:453 #, fuzzy msgid "Chatroom is destroyed" msgstr "Chattrum" #: mod_muc/mod_muc_log.erl:454 #, fuzzy msgid "Chatroom is started" msgstr "Chattrum" #: mod_muc/mod_muc_log.erl:455 #, fuzzy msgid "Chatroom is stopped" msgstr "Chattrum" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Måndag" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Tisdag" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Onsdag" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Torsdag" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Fredag" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Lördag" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Söndag" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Januari" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Februari" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Mars" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "April" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Maj" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Juni" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Juli" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Augusti" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "September" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Oktober" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "November" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "December" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Rumkonfiguration" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Antal besökare" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Trafikgränsen har överstigits" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Deltagaren har blivit kickad fran rummet p.g.a att han skickade ett " "errormeddelande" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "" "Det är inte tillåtet att skicka privata medelanden till den här konferensen" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Felaktig medelandetyp" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Deltagaren har blivit kickad från rummet p.g.a att han skickade ett " "errormeddelande till en annan deltagare" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "" "Det är inte tillåtet att skicka privata medelanden med typen \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Mottagaren finns inte i rummet" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Det ar inte tillåtet att skicka privata meddelanden" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Utomstående får inte skicka medelanden till den här konferensen" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Utomstående får inte skicka iq-queries till den här konferensen" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "Det är förbjudet att skicka iq-queries till konferensdeltagare" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Endast moderatorer och deltagare har tillåtelse att ändra ämnet i det här " "rummet" #: mod_muc/mod_muc_room.erl:937 #, fuzzy msgid "Only moderators are allowed to change the subject in this room" msgstr "Endast moderatorer får ändra ämnet i det här rummet" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Besökare får inte skicka medelande till alla" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Denna deltagaren är kickad från rummet p.g.a att han skickade en errorstatus" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Det är inte tillåtet for gäster att ändra sina smeknamn i detta rummet" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 #, fuzzy msgid "That nickname is already in use by another occupant" msgstr "Smeknamnet används redan" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Du har blivit bannlyst från det här rummet" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Du måste vara medlem för att komma in i det här rummet" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Detta rum är inte anonymt" #: mod_muc/mod_muc_room.erl:1833 #, fuzzy msgid "A password is required to enter this room" msgstr "Lösenord erfordras" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 #, fuzzy msgid "Unable to generate a CAPTCHA" msgstr "Kunde inte generera ett CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Fel lösenord" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Administrationsprivilegier krävs" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Moderatorprivilegier krävs" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Otillåtet Jabber ID ~s" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Smeknamnet ~s existerar inte i det här rummet" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Ogiltlig rang: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Ogiltlig roll: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Ägarprivilegier krävs" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Konfiguration för ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Rumstitel" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 #, fuzzy msgid "Room description" msgstr "Beskrivning:" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Gör rummet permanent" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Gör rummet publikt sökbart" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Gör deltagarlistan publik" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Gör losenorden i rummet publika" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Maximalt antal av användare" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Ingen gräns" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Nuvarande äkta Jabber IDs till" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "endast moderatorer" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "Vemsomhelst" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Gör om rummet till endast medlemmar" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Gör rummet modererat" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Gör om användare till deltagare" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Tillåt användare att byta ämne" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Tillåt användare att skicka privata meddelanden" #: mod_muc/mod_muc_room.erl:3279 #, fuzzy msgid "Allow visitors to send private messages to" msgstr "Tillåt användare att skicka privata meddelanden" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Tillåt användare att söka efter andra användare" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Tillåt användare att skicka inbjudningar" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "Tillåt gäster att skicka statustext som uppdatering" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Tillåt gäster att kunna ändra smeknamn" #: mod_muc/mod_muc_room.erl:3308 #, fuzzy msgid "Allow visitors to send voice requests" msgstr "Tillåt användare att skicka inbjudningar" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "" #: mod_muc/mod_muc_room.erl:3317 #, fuzzy msgid "Make room CAPTCHA protected" msgstr "Gör losenorden i rummet publika" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Möjliggör login" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Du behöver en klient som stödjer x:data för att konfiguera detta rum" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Antal besökare" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privat, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "" #: mod_muc/mod_muc_room.erl:3809 #, fuzzy msgid "User JID" msgstr "Användare " #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s bjöd in dig till rummet ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "Lösenordet är" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "Din kontaktkö for offlinekontakter ar full" #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "~s's offline meddelandekö" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Skicka in" #: mod_offline.erl:571 msgid "Time" msgstr "Tid" #: mod_offline.erl:572 msgid "From" msgstr "Från" #: mod_offline.erl:573 msgid "To" msgstr "Till" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Paket" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Tabort valda" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Offline meddelanden:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 #, fuzzy msgid "Remove All Offline Messages" msgstr "Offline meddelanden" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestrem modul" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Publikprenumeration" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "ejabberd publikprenumerations modul" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Pubsub prenumerationsforfrågan" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Välj om du vill godkänna hela denna prenumertion." #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "Node ID" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Prenumerationsadress" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Tillåt denna Jabber ID att prenumerera på denna pubsub node" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Skicka innehåll tillsammans med notifikationer" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Skicka eventnotifikation" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Meddela prenumeranter när nodens konfiguration ändras" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Meddela prenumeranter när noden tas bort" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Meddela prenumeranter när dataposter tas bort från noden" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Spara dataposter permanent" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Ett vänligt namn for noden" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Högsta antal dataposter som sparas" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Tillåta prenumerationer?" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Specificera accessmodellen" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Rostergrupper tillåts att prenumerera" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Ange publiceringsmodell" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 #, fuzzy msgid "Specify the event message type" msgstr "Specificera accessmodellen" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Högsta innehållsstorlek i bytes" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "När att skicka senast publicerade ämne" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Skicka notifikationer bara till uppkopplade användare" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "" #: mod_register.erl:220 #, fuzzy msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "Du behöver en klient som stödjer x:data för att registrera smeknamn" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Välj ett användarnamn och lösenord för att registrera mot denna server" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Användarnamn" #: mod_register.erl:316 mod_register.erl:361 #, fuzzy msgid "The password is too weak" msgstr "Lösenordet är" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Det är inte tillåtet för användare att skapa konton så fort" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Inga" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Prenumeration" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Ännu inte godkända" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Grupper" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Validera" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Ta bort" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Kontaktlista för " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Dåligt format" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Lägg till Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Kontaktlista" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Delade Rostergrupper" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Lägg till ny" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Namn:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Beskrivning:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Medlemmar:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Visade grupper:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Grupp " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Skicka" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Födelsedag" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Stad" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Land" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Email" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Efternamn" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Fyll i formuläret för att söka efter en användare (lägg till * på slutet av " "fältet för att hitta alla som börjar så)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Fullständigt namn" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Mellannamn" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Namn" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Organisationsnamn" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Organisationsenhet" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Sök efter användare på " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Du behöver en klient som stödjer x:data, för att kunna söka" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "vCard användare sök" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard-modul" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Sökresultat för" #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Fyll i fält för att söka efter jabberanvändare" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Ej auktoriserad" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd Web Admin" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Administration" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Ra" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Åtkomstregelkonfiguration för ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Virtuella servrar" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Användare" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Användarens senaste aktivitet" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Period: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Senaste månaden" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Senaste året" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "All aktivitet" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Visa normal tabell" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Visa kumulativ tabell" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Statistik" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Noden finns inte" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Noden finns inte" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Server" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Registrerade användare" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Offline meddelanden" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Senast aktivitet" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Registrerade användare" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Inloggade användare" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Utgående s2s anslutning" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Utgående s2s server" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Ändra lösenord" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Användare " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Anslutna resurser:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Lösenord:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Ingen data" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Noder" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Nod " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Lyssnarport" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Uppdatera" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Omstart" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Stoppa" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "RPC Uppringningserror" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Databas tabell pa" #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Lagringstyp" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Elements" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Minne" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Fel" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Backup av" #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Kom ihåg att dessa inställningar endast tar backup pa builtin Mnesias " "databas. Om du använder ODBC modul så måste du ta backup på SQLs databas " "enskilt" #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Lagra den binära backupen" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "återställ den binära backupen omedelbart" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "återställ den binära backupen efter nästa ejabberd omstart" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Lagra textbackup" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "återställ textbackup omedelbart" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Importera användardata från en PIEFXIS fil (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Exportera data av alla användare i servern till en PIEFXIS fil (XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "Exportera data av användare i en host till PIEFXIS fil (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importera användare från jabberd14 Spool filer" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importera användare från jabberd14 Spool directory:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Lyssnande portar på " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Moduler på" #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Statistik på ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Tid upp" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "CPU tid" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transaktioner kommittade" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transaktioner borttagna" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transaktioner omstartade" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transaktioner loggade " #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Uppdatera" #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Uppdateringsplan" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Uppdaterade moduler" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Uppdatera skript" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Uppdaterade laglevel skript" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Skript kollat" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Port" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protocol" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Modul" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Parametrar" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Ta bort" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Starta" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "" #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "" #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "" #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 #, fuzzy msgid "Username:" msgstr "IRC-användarnamn" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 #, fuzzy msgid "Server:" msgstr "Server ~b" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 #, fuzzy msgid "Password Verification:" msgstr "Lösenordsverifikation" #: web/mod_register_web.erl:250 #, fuzzy msgid "Register" msgstr "Kontaktlista" #: web/mod_register_web.erl:396 #, fuzzy msgid "Old Password:" msgstr "Lösenord:" #: web/mod_register_web.erl:401 #, fuzzy msgid "New Password:" msgstr "Lösenord:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "Din CAPTCHA är godkänd." ejabberd-2.1.11/src/msgs/pt.msg0000664000000000000000000001577312240230175013126 0ustar {"Access Configuration","Configuração de acessos"}. {"Access Control List Configuration","Configuração da Lista de Controlo de Acesso"}. {"Access control lists","Listas de Controlo de Acesso"}. {"Access Control Lists","Listas de Controlo de Acesso"}. {"Access denied by service policy","Acesso negado pela política de serviço"}. {"Access rules","Regras de acesso"}. {"Access Rules","Regras de Acesso"}. {"Action on user","Acção no utilizador"}. {"Add New","Adicionar novo"}. {"Add User","Adicionar utilizador"}. {"Administration of ","Administração de "}. {"Administrator privileges required","São necessários privilégios de administrador"}. {"All Users","Todos os utilizadores"}. {"Backup","Guardar cópia de segurança"}. {"Backup Management","Gestão de cópias de segurança"}. {"Backup to File at ","Guardar cópia de segurança para ficheiro em "}. {"Birthday","Data de nascimento"}. {"Change Password","Mudar palavra-chave"}. {"Choose a username and password to register with this server","Escolha um nome de utilizador e palavra-chave para se registar neste servidor"}. {"Choose modules to stop","Seleccione os módulos a parar"}. {"Choose storage type of tables","Seleccione o tipo de armazenagem das tabelas"}. {"City","Cidade"}. {"Conference room does not exist","A sala não existe"}. {"Configuration","Configuração"}. {"Connected Resources:","Recursos conectados:"}. {"Country","País"}. {"Delete","Eliminar"}. {"Delete Selected","Eliminar os seleccionados"}. {"Disc only copy","Cópia apenas em disco"}. {"Dump Backup to Text File at ","Exporta cópia de segurança para ficheiro de texto em "}. {"Dump to Text File","Exportar para ficheiro de texto"}. {"Edit Properties","Editar propriedades"}. {"ejabberd IRC module","Módulo de IRC ejabberd"}. {"ejabberd MUC module","Módulo MUC de ejabberd"}. {"ejabberd vCard module","Módulo vCard de ejabberd"}. {"Enter list of {Module, [Options]}","Introduza lista de {módulos, [opções]}"}. {"Enter nickname you want to register","Introduza a alcunha que quer registar"}. {"Enter path to backup file","Introduza o caminho do ficheiro de cópia de segurança"}. {"Enter path to jabberd14 spool dir","Introduza o caminho para o directório de spools do jabberd14"}. {"Enter path to jabberd14 spool file","Introduza o caminho para o ficheiro de spool do jabberd14"}. {"Enter path to text file","Introduza caminho para o ficheiro de texto"}. {"Erlang Jabber Server","Servidor Jabber em Erlang"}. {"Family Name","Apelido"}. {"Fill in fields to search for any matching Jabber User","Preencha os campos para procurar utilizadores Jabber coincidentes"}. {"From","De"}. {"From ~s","De ~s"}. {"Full Name","Nome completo"}. {"Groups","Grupos"}. {" has set the subject to: "," colocou o tópico: "}. {"Import Directory","Importar directório"}. {"Import File","Importar ficheiro"}. {"Import User from File at ","Importar utilizador a partir do ficheiro em "}. {"Import Users from Dir at ","Importar utilizadores a partir do directório em "}. {"Improper message type","Tipo de mensagem incorrecto"}. {"Incorrect password","Palavra-chave incorrecta"}. {"Invalid affiliation: ~s","Afiliação inválida: ~s"}. {"Invalid role: ~s","Papel inválido: ~s"}. {"IRC Username","Nome do utilizador de IRC"}. {"It is not allowed to send private messages of type \"groupchat\"","Não é permitido enviar mensagens privadas do tipo \"groupchat\""}. {"It is not allowed to send private messages to the conference","Impedir o envio de mensagens privadas para a sala"}. {"Jabber ID ~s is invalid","O Jabber ID ~s não é válido"}. {"Last Activity","Última actividade"}. {"Listened Ports at ","Portas em escuta em "}. {"List of modules to start","Lista de módulos a iniciar"}. {"Make room moderated","Tornar a sala moderada"}. {"Memory","Memória"}. {"Middle Name","Segundo nome"}. {"Moderator privileges required","São necessários privilégios de moderador"}. {"Module","Módulo"}. {"Modules","Módulos"}. {"Name","Nome"}. {"Never","Nunca"}. {"Nickname","Alcunha"}. {"Nickname Registration at ","Registo da alcunha em "}. {"Nickname ~s does not exist in the room","A alcunha ~s não existe na sala"}. {"Node ","Nodo"}. {"Node not found","Nodo não encontrado"}. {"Nodes","Nodos"}. {"None","Nenhum"}. {"No resource provided","Não foi passado nenhum recurso"}. {"OK","OK"}. {"Online","Ligado"}. {"Online Users","Utilizadores ligados"}. {"Only occupants are allowed to send messages to the conference","Só os ocupantes podem enviar mensagens para a sala"}. {"Only occupants are allowed to send queries to the conference","Só os ocupantes podem enviar consultas para a sala"}. {"Only service administrators are allowed to send service messages","Só os administradores do serviço têm permissão para enviar mensagens de serviço"}. {"Options","Opções"}. {"Organization Name","Nome da organização"}. {"Organization Unit","Unidade da organização"}. {"Owner privileges required","São necessários privilégios de dono"}. {"Packet","Pacote"}. {"Password:","Palavra-chave:"}. {"Password","Palavra-chave"}. {"Path to Dir","Caminho para o directório"}. {"Path to File","Caminho do ficheiro"}. {"Pending","Pendente"}. {"Port","Porta"}. {"private, ","privado"}. {"Queries to the conference members are not allowed in this room","Nesta sala não são permitidas consultas aos seus membros"}. {"RAM and disc copy","Cópia em RAM e em disco"}. {"RAM copy","Cópia em RAM"}. {"Recipient is not in the conference room","O destinatário não está na sala"}. {"Registration in mod_irc for ","Registo no mod_irc para"}. {"Remote copy","Cópia remota"}. {"Remove","Remover"}. {"Remove User","Eliminar utilizador"}. {"Restart","Reiniciar"}. {"Restore Backup from File at ","Restaura cópia de segurança a partir do ficheiro em "}. {"Restore","Restaurar"}. {"Room title","Título da sala"}. {"Roster","Lista de contactos"}. {"Roster of ","Lista de contactos de "}. {"Running Nodes","Nodos a correr"}. {"~s access rule configuration","Configuração das Regra de Acesso ~s"}. {"Search users in ","Procurar utilizadores em "}. {"Start Modules at ","Iniciar os módulos em "}. {"Start Modules","Iniciar módulos"}. {"Statistics","Estatísticas"}. {"Stop Modules at ","Parar módulos em "}. {"Stop Modules","Parar módulos"}. {"Stop","Parar"}. {"Stopped Nodes","Nodos parados"}. {"Storage Type","Tipo de armazenagem"}. {"Submit","Enviar"}. {"Subscription","Subscrição"}. {"Time","Data"}. {"To","Para"}. {"To ~s","A ~s"}. {"Update","Actualizar"}. {"Users","Utilizadores"}. {"User ","Utilizador"}. {"User","Utilizador"}. {"Visitors are not allowed to send messages to all occupants","Os visitantes não podem enviar mensagens para todos os ocupantes"}. {"You have been banned from this room","Foi banido desta sala"}. {"You need an x:data capable client to configure mod_irc settings","É necessário um cliente com suporte de x:data para configurar as opções do mod_irc"}. {"You need an x:data capable client to configure room","É necessário um cliente com suporte de x:data para configurar a sala"}. {"You need an x:data capable client to search","É necessário um cliente com suporte de x:data para poder procurar"}. ejabberd-2.1.11/src/msgs/vi.po0000664000000000000000000015641612240230175012751 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "Last-Translator: EQHO Communications (Thailand) Ltd. - http://www.eqho.com\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Vietnamese (tiếng việt)\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Yêu cầu sử dụng STARTTLS" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Không có nguồn lực cung cấp" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Được thay thế bởi kết nối mới" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 #, fuzzy msgid "Enter the text you see" msgstr "Nhập đường dẫn đến tập tin văn bản" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "" #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Lệnh" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Có thực sự xóa thư trong ngày này không?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Tiêu đề" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Thân thư" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Không có nội dung trong thư thông báo" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Thông báo" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Gửi thông báo đến tất cả người sử dụng" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Gửi thông báo đến tất cả người sử dụng trên tất cả các máy chủ" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Gửi thông báo đến tất cả người sử dụng trực tuyến" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "" "Gửi thông báo đến tất cả người sử dụng trực tuyến trên tất cả các máy chủ" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Tạo lập thư trong ngày và gửi đến những người sử dụng trực tuyến" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Tạo lập thư trong ngày trên tất cả các máy chủ và gửi đến những người sử " "dụng trực tuyến" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Cập nhật thư trong ngày (không gửi)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Cập nhật thư trong ngày trên tất cả các máy chủ (không gửi)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Xóa thư trong ngày" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Xóa thư trong ngày trên tất cả các máy chủ" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Cấu hình" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Cơ sở dữ liệu" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Môđun Khởi Động" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Môđun Dừng" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Sao lưu dự phòng" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Khôi phục" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Kết xuất ra Tập Tin Văn Bản" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Nhập Tập Tin" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Nhập Thư Mục" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Khởi Động Lại Dịch Vụ" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Tắt Dịch Vụ" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Thêm Người Sử Dụng" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Xóa Người Sử Dụng" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Kết Thúc Phiên Giao Dịch Người Sử Dụng" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Nhận Mật Khẩu Người Sử Dụng" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Thay Đổi Mật Khẩu Người Sử Dụng" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Nhận Thời Gian Đăng Nhập Cuối Cùng Của Người Sử Dụng" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Nhận Thông Tin Thống Kê Người Sử Dụng" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Nhận Số Người Sử Dụng Đã Đăng Ký" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Nhận Số Người Sử Dụng Trực Tuyến" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Danh Sách Kiểm Soát Truy Cập" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Quy Tắc Truy Cập" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Quản Lý Người Sử Dụng" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Người Sử Dụng Trực Tuyến" #: mod_configure.erl:501 msgid "All Users" msgstr "Tất Cả Người Sử Dụng" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Kết Nối Bên Ngoài s2s" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Nút Hoạt Động" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Nút Dừng" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Môđun" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Quản lý Sao Lưu Dự Phòng" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Nhập Người Sử Dụng Từ Các Tập Tin Spool jabberd14" #: mod_configure.erl:699 msgid "To ~s" msgstr "Gửi đến ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Nhận từ ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Cấu Hình Bảng Cơ Sở Dữ Liệu tại" #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Chọn loại bảng lưu trữ" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Chỉ sao chép vào đĩa" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Sao chép vào RAM và đĩa" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Sao chép vào RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Sao chép từ xa" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Môđun Dừng tại" #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Chọn môđun để dừng" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Môđun Khởi Động tại " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Nhập danh sách {Môđun, [Các Tùy Chọn]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Danh sách các môđun khởi động" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Sao lưu dự phòng ra Tập Tin tại" #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Nhập đường dẫn đến tập tin sao lưu dự phòng" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Đường dẫn đến Tập Tin" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Phục hồi Sao Lưu từ Tập Tin tại " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Kết Xuất Sao Lưu ra Tập Tin Văn Bản tại" #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Nhập đường dẫn đến tập tin văn bản" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Nhập Người Sử Dụng từ Tập Tin tại" #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Nhập đường dẫn đến tập tin spool jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Nhập Người Sử Dụng từ Thư Mục tại" #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Nhập đường dẫn đến thư mục spool jabberd14" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Đường Dẫn đến Thư Mục" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Thời gian trì hoãn" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Cấu Hình Danh Sách Kiểm Soát Truy Cập" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Danh sách kiểm soát truy cập" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Cấu Hình Truy Cập" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Quy tắc Truy Cập" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Mật Khẩu" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Kiểm Tra Mật Khẩu" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Số người sử dụng đã đăng ký" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Số người sử dụng trực tuyến" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Không bao giờ" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Trực tuyến" #: mod_configure.erl:1701 msgid "Last login" msgstr "Đăng nhập lần cuối" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Kích thước bảng phân công" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "Địa chỉ IP" #: mod_configure.erl:1724 msgid "Resources" msgstr "Nguồn tài nguyên" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Quản trị về " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Hành động đối với người sử dụng" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Chỉnh Sửa Thuộc Tính" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Gỡ Bỏ Người Sử Dụng" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Sự truy cập bị chặn theo chính sách phục vụ" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "Truyền tải IRC" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "Môdun ejabberd IRC Bản quyền" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "Bạn cần có một trình ứng dụng khách hỗ trợ định dạng dữ liệu x: để xác định " "các thiết lập mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Đăng ký trong mod_irc cho " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 #, fuzzy msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Nhập tên truy cập và mã hóa mà bạn muốn sử dụng khi kết nối với các máy chủ " "IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Tên truy cập IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 #, fuzzy msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Nếu bạn muốn xác định các cách thức mã hóa khác nhau cho các máy chủ IRC, " "hãy điền vào danh sách này những giá trị theo định dạng '{\"máy chủ irc\", " "\"mã hóa\"}'. Dịch vụ này mặc định sử dụng định dạng mã hóa \"~s\"." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 #, fuzzy msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Ví dụ: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", " "\"iso8859-1\"}]" #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 #, fuzzy msgid "IRC server" msgstr "Tên truy cập IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 #, fuzzy msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Nhập tên truy cập và mã hóa mà bạn muốn sử dụng khi kết nối với các máy chủ " "IRC" #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 #, fuzzy msgid "IRC username" msgstr "Tên truy cập IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 #, fuzzy msgid "Password ~b" msgstr "Mật Khẩu" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 #, fuzzy msgid "Port ~b" msgstr "Cổng" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "Chỉ có người quản trị dịch vụ mới được phép gửi những thư dịch vụ" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Việc tạo phòng bị ngăn lại theo chính sách dịch vụ" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Phòng họp không tồn tại" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Phòng trò chuyện" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 #, fuzzy msgid "You need a client that supports x:data to register the nickname" msgstr "" "Bạn cần có một trình ứng dụng khách hỗ trợ định dạng dữ liệu x: để đăng ký " "bí danh" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Đăng Ký Bí Danh tại" #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Nhập bí danh bạn muốn đăng ký" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Bí danh" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 #, fuzzy msgid "That nickname is registered by another person" msgstr "Một người khác đã đăng ký bí danh này rồi" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Bạn phải điền thông tin vào ô \"Nickname\" trong biểu mẫu này" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "Môdun ejabberd MUC Bản quyền" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Cấu hình phòng trò chuyện được chỉnh sửa" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "tham gia phòng này" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "rời khỏi phòng này" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "đã bị cấm" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "đã bị đẩy ra khỏi" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "bây giờ được biết như" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " đã đặt chủ đề thành: " #: mod_muc/mod_muc_log.erl:452 #, fuzzy msgid "Chatroom is created" msgstr "Phòng trò chuyện" #: mod_muc/mod_muc_log.erl:453 #, fuzzy msgid "Chatroom is destroyed" msgstr "Phòng trò chuyện" #: mod_muc/mod_muc_log.erl:454 #, fuzzy msgid "Chatroom is started" msgstr "Phòng trò chuyện" #: mod_muc/mod_muc_log.erl:455 #, fuzzy msgid "Chatroom is stopped" msgstr "Phòng trò chuyện" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Thứ Hai" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Thứ Ba" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Thứ Tư" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Thứ Năm" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Thứ Sáu" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Thứ Bảy" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Chủ Nhật" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Tháng Một" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Tháng Hai" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Tháng Ba" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "Tháng Tư" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Tháng Năm" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Tháng Sáu" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Tháng Bảy" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Tháng Tám" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "Tháng Chín" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Tháng Mười" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "Tháng Mười Một" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "Tháng Mười Hai" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Cấu Hình Phòng" #: mod_muc/mod_muc_log.erl:759 #, fuzzy msgid "Room Occupants" msgstr "Số người tham dự" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Quá giới hạn tỷ lệ lưu lượng truyền tải" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Không được phép gửi những thư riêng đến phòng họp" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Loại thư không phù hợp" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "Không được phép gửi những thư riêng loại \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Người nhận không có trong phòng họp" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 #, fuzzy msgid "It is not allowed to send private messages" msgstr "Không được phép gửi những thư riêng đến phòng họp" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Chỉ có những đối tượng tham gia mới được phép gửi thư đến phòng họp" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "" "Chỉ có những đối tượng tham gia mới được phép gửi yêu cầu đến phòng họp" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "" "Không được phép gửi các yêu cầu gửi đến các thành viên trong phòng họp này" #: mod_muc/mod_muc_room.erl:932 #, fuzzy msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Chỉ có những người điều phối và những người tham gia được phép thay đổi chủ " "đề trong phòng này" #: mod_muc/mod_muc_room.erl:937 #, fuzzy msgid "Only moderators are allowed to change the subject in this room" msgstr "Chỉ có những người điều phối được phép thay đổi chủ đề trong phòng này" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Người ghé thăm không được phép gửi thư đến tất cả các người tham dự" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" #: mod_muc/mod_muc_room.erl:1040 #, fuzzy msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Chỉ có những người điều phối được phép thay đổi chủ đề trong phòng này" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 #, fuzzy msgid "That nickname is already in use by another occupant" msgstr "Bí danh đang do một người tham dự khác sử dụng" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Bạn bị cấm tham gia phòng này" #: mod_muc/mod_muc_room.erl:1771 #, fuzzy msgid "Membership is required to enter this room" msgstr "Yêu cầu tư cách thành viên khi tham gia vào phòng này" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Phòng này không nặc danh" #: mod_muc/mod_muc_room.erl:1833 #, fuzzy msgid "A password is required to enter this room" msgstr "Yêu cầu nhập mật khẩu để vào phòng này" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Mật khẩu sai" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Yêu cầu đặc quyền của nhà quản trị" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Yêu cầu đặc quyền của nhà điều phối" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Jabber ID ~s không hợp lệ" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Bí danh ~s không tồn tại trong phòng này" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Tư cách không hợp lệ: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Vai trò không hợp lệ: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Yêu cầu đặc quyền của người sở hữu" #: mod_muc/mod_muc_room.erl:3195 #, fuzzy msgid "Configuration of room ~s" msgstr "Cấu hình cho " #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Tên phòng" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 #, fuzzy msgid "Room description" msgstr "Miêu tả:" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Tạo phòng bền vững" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Tạo phòng có thể tìm kiếm công khai" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Tạo danh sách người tham dự công khai" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Tạo phòng được bảo vệ bằng mật khẩu" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Số Lượng Người Tham Dự Tối Đa" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Không giới hạn" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Jabber ID thực tế hiện hành đến" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "nhà điều phối duy nhất" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "bất kỳ ai" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Tạo phòng chỉ cho phép tư cách thành viên tham gia" #: mod_muc/mod_muc_room.erl:3265 #, fuzzy msgid "Make room moderated" msgstr "Tạo phòng bền vững" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Người sử dụng mặc định là người tham dự" #: mod_muc/mod_muc_room.erl:3271 #, fuzzy msgid "Allow users to change the subject" msgstr "Cho phép người sử dụng thay đổi chủ đề" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Cho phép người sử dụng gửi thư riêng" #: mod_muc/mod_muc_room.erl:3279 #, fuzzy msgid "Allow visitors to send private messages to" msgstr "Cho phép người sử dụng gửi thư riêng" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Cho phép người sử dụng hỏi người sử dụng khác" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Cho phép người sử dụng gửi lời mời" #: mod_muc/mod_muc_room.erl:3302 #, fuzzy msgid "Allow visitors to send status text in presence updates" msgstr "Cho phép người sử dụng gửi thư riêng" #: mod_muc/mod_muc_room.erl:3305 #, fuzzy msgid "Allow visitors to change nickname" msgstr "Cho phép người sử dụng thay đổi chủ đề" #: mod_muc/mod_muc_room.erl:3308 #, fuzzy msgid "Allow visitors to send voice requests" msgstr "Cho phép người sử dụng gửi lời mời" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "" #: mod_muc/mod_muc_room.erl:3317 #, fuzzy msgid "Make room CAPTCHA protected" msgstr "Tạo phòng được bảo vệ bằng mật khẩu" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Cho phép ghi nhật ký" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "" "Bạn cần có một trình ứng dụng khách hỗ trợ định dạng dữ liệu x: để xác định " "cấu hình phòng họp" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Số người tham dự" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "riêng," #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "" #: mod_muc/mod_muc_room.erl:3809 #, fuzzy msgid "User JID" msgstr "Người sử dụng " #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s mời bạn vào phòng ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "mật khẩu là" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "Danh sách chờ thư liên lạc ngoại tuyến của bạn đã đầy. Thư này đã bị loại bỏ." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "~s's Danh Sách Chờ Thư Ngoại Tuyến" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Đã gửi" #: mod_offline.erl:571 msgid "Time" msgstr "Thời Gian" #: mod_offline.erl:572 msgid "From" msgstr "Từ" #: mod_offline.erl:573 msgid "To" msgstr "Đến" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Gói thông tin" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Tùy chọn Xóa được Chọn" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Thư Ngoại Tuyến:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 #, fuzzy msgid "Remove All Offline Messages" msgstr "Thư Ngoại Tuyến" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "Môdun SOCKS5 Bytestreams Bản quyền" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Xuất Bản-Đăng Ký" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "Môdun ejabberd Xuất Bản-Đăng Ký Bản quyền" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Yêu cầu người đăng ký môđun Xuất Bản Đăng Ký" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Chọn có nên chấp nhận sự đăng ký của đối tượng này không" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ID Nút" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Địa Chỉ Người Đăng Ký" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Cho phép Jabber ID đăng ký nút môđun xuất bản đăng ký này không?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Đưa ra thông tin dung lượng với các thông báo sự kiện" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Đưa ra các thông báo sự kiện" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Thông báo cho người đăng ký khi nào cấu hình nút thay đổi" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Thông báo cho người đăng ký khi nào nút bị xóa bỏ" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Thông báo cho người đăng ký khi nào các mục chọn bị gỡ bỏ khỏi nút" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Những mục cần để lưu trữ" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Số mục tối đa để lưu trữ" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Xác định nên cho phép đăng ký không" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Xác định mô hình truy cập" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Xác định mô hình nhà xuất bản" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 #, fuzzy msgid "Specify the event message type" msgstr "Xác định mô hình truy cập" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Kích thước dung lượng byte tối đa" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Khi cần gửi mục được xuất bản cuối cùng" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Chỉ gửi thông báo đến những người sử dụng hiện có" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "" #: mod_register.erl:220 #, fuzzy msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "Bạn cần có một trình ứng dụng khách hỗ trợ định dạng dữ liệu x: để đăng ký " "bí danh" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Chọn một tên truy cập và mật khẩu để đăng ký với máy chủ này" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Người sử dụng" #: mod_register.erl:316 mod_register.erl:361 #, fuzzy msgid "The password is too weak" msgstr "mật khẩu là" #: mod_register.erl:365 #, fuzzy msgid "Users are not allowed to register accounts so quickly" msgstr "Người ghé thăm không được phép gửi thư đến tất cả các người tham dự" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Không có" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Đăng ký" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Chờ" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Nhóm" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Xác nhận hợp lệ" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Gỡ bỏ" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Bảng phân công của " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Định dạng hỏng" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Thêm Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Bảng phân công" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Nhóm Phân Công Chia Sẻ" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Thêm Mới" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Tên:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Miêu tả:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Thành viên:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Nhóm được hiển thị:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Nhóm " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Gửi" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server Bản quyền" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Ngày sinh" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Thành phố" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Quốc gia" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Email" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Họ" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Điền vào mẫu này để tìm kiếm bất kỳ thông tin nào khớp với Người sử dụng " "Jabber (Thêm dấu * vào cuối ô để thông tin khớp với chuỗi bên trong)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Tên Đầy Đủ" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Họ Đệm" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Tên" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Tên Tổ Chức" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Bộ Phận" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Tìm kiếm người sử dụng trong" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "" "Bạn cần có một trình ứng dụng khách hỗ trợ định dạng dữ liệu x: để tìm kiếm" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Tìm Kiếm Người Sử Dụng vCard" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "Môdun ejabberd vCard Bản quyền" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Kết Quả Tìm Kiếm cho " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "" "Điền vào các ô để tìm kiếm bất kỳ các thông tin nào khớp với Người sử dụng " "Jabber" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 #, fuzzy msgid "ejabberd Web Admin" msgstr "Giao diện Web ejabberd" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Quản trị" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Thô" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "~s cấu hình quy tắc truy cập" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Máy Chủ Ảo" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Người sử dụng" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Hoạt Động Cuối Cùng Của Người Sử Dụng" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Giai đoạn: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Tháng trước" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Năm trước" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Tất cả hoạt động" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Hiển Thị Bảng Thường" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Hiển Thị Bảng Đầy Đủ" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Số liệu thống kê" #: web/ejabberd_web_admin.erl:1117 #, fuzzy msgid "Not Found" msgstr "Nút không tìm thấy" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Nút không tìm thấy" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Máy chủ" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Người Sử Dụng Đã Đăng Ký" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Thư Ngoại Tuyến" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Hoạt Động Cuối Cùng" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Người Sử Dụng Đã Đăng Ký:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Người Sử Dụng Trực Tuyến:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Kết Nối Bên Ngoài s2s:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Máy chủ Bên Ngoài s2s:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Thay Đổi Mật Khẩu" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Người sử dụng " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Tài Nguyên Được Kết Nối:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Mật Khẩu:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Không Dữ Liệu" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Nút" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Nút " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Cổng Kết Nối" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Cập Nhật" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Khởi động lại" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Dừng" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Lỗi Gọi RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Bảng Cơ Sở Dữ Liệu tại" #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Loại Lưu Trữ" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Bộ Nhớ" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Sao lưu dự phòng về" #: web/ejabberd_web_admin.erl:2036 #, fuzzy msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Lưu ý rằng những tùy chọn này sẽ chỉ được sao lưu cơ sở dữ liệu bên trong " "Mnesia. Nếu bạn đang sử dụng môđun ODBC, bạn cũng cần sao lưu cơ sở dữ liệu " "SQL của bạn riêng biệt." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Lưu dữ liệu sao lưu dạng nhị phân:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Khôi phục bản sao lưu dự phòng dạng nhị phận ngay lập tức:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Khôi phục bản sao lưu dự phòng dạng nhị phân sau lần khởi động ejabberd kế " "tiếp (yêu cầu ít bộ nhớ hơn):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Khôi phục bản sao lưu dự phòng thuần văn bản" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Khôi phục bản sao lưu dự phòng thuần văn bản ngay lập tức:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2099 #, fuzzy msgid "Import user data from jabberd14 spool file:" msgstr "Nhập Người Sử Dụng Từ Các Tập Tin Spool jabberd14" #: web/ejabberd_web_admin.erl:2106 #, fuzzy msgid "Import users data from jabberd14 spool directory:" msgstr "Nhập Người Sử Dụng Từ Các Tập Tin Spool jabberd14" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Cổng Liên Lạc tại" #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Môđun tại " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Thống kê về ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Thời gian tải lên:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Thời Gian CPU:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Giao Dịch Được Cam Kết:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Giao Dịch Hủy Bỏ:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Giao Dịch Khởi Động Lại:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Giao Dịch Được Ghi Nhận:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Cập Nhật " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Kế hoạch cập nhật" #: web/ejabberd_web_admin.erl:2255 #, fuzzy msgid "Modified modules" msgstr "Môđun cập nhật" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Cập nhận lệnh" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Lệnh cập nhật mức độ thấp" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Lệnh kiểm tra" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Cổng" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "" #: web/ejabberd_web_admin.erl:2428 #, fuzzy msgid "Protocol" msgstr "Cổng" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Môđun" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Tùy chọn" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Xóa" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Khởi động" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "" #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "" #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "" #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 #, fuzzy msgid "Username:" msgstr "Tên truy cập IRC" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 #, fuzzy msgid "Server:" msgstr "Không bao giờ" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 #, fuzzy msgid "Password Verification:" msgstr "Kiểm Tra Mật Khẩu" #: web/mod_register_web.erl:250 #, fuzzy msgid "Register" msgstr "Bảng phân công" #: web/mod_register_web.erl:396 #, fuzzy msgid "Old Password:" msgstr "Mật Khẩu:" #: web/mod_register_web.erl:401 #, fuzzy msgid "New Password:" msgstr "Mật Khẩu:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "" #~ msgid "Encodings" #~ msgstr "Mã hóa" #~ msgid "(Raw)" #~ msgstr "(Thô)" #~ msgid "Specified nickname is already registered" #~ msgstr "Bí danh xác định đã đăng ký rồi" #~ msgid "Size" #~ msgstr "Kích thước" #~ msgid "Roster groups that may subscribe (if access model is roster)" #~ msgstr "" #~ "Các nhóm phân công có thể đăng ký (nếu mô hình truy cập là dạng phân công)" ejabberd-2.1.11/src/msgs/tr.msg0000664000000000000000000006735412240230175013132 0ustar {"Access Configuration","Erişim Ayarları"}. {"Access Control List Configuration","Erişim Kontrol Listelerinin Ayarlanması (ACL)"}. {"Access control lists","Erişim kontrol listeleri (ACL)"}. {"Access Control Lists","Erişim Kontrol Listeleri (ACL)"}. {"Access denied by service policy","Servis politikası gereği erişim engellendi"}. {"Access rules","Erişim kuralları"}. {"Access Rules","Erişim Kuralları"}. {"Action on user","Kullanıcıya uygulanacak eylem"}. {"Add Jabber ID","Jabber ID'si Ekle"}. {"Add New","Yeni Ekle"}. {"Add User","Kullanıcı Ekle"}. {"Administration of ","Yönetim : "}. {"Administration","Yönetim"}. {"Administrator privileges required","Yönetim yetkileri gerekli"}. {"A friendly name for the node","Düğüm için dostane bir isim"}. {"All activity","Tüm aktivite"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Bu Jabber ID bu pubsub düğümüne üye olmasına izin verilsin mi?"}. {"Allow users to change the subject","Kullanıcıların konu değiştirmesine izin ver"}. {"Allow users to query other users","Kullanıcıların diğer kullanıcıları sorgulamalarına izin ver"}. {"Allow users to send invites","Kullanıcıların davetiye göndermelerine izin ver"}. {"Allow users to send private messages","Kullanıcıların özel mesaj göndermelerine izin ver"}. {"Allow visitors to change nickname","Ziyaretçilerin takma isim değiştirmelerine izin ver"}. {"Allow visitors to send private messages to","Ziyaretçilerin özel mesaj göndermelerine izin ver"}. {"Allow visitors to send status text in presence updates","Ziyaretçilerin varlık (presence) güncellemelerinde durum metni göndermelerine izin ver"}. {"Allow visitors to send voice requests","Ziyaretçilerin ses isteğine göndermelerine izin ver"}. {"All Users","Tüm Kullanıcılar"}. {"Announcements","Duyurular"}. {"anyone","herkes"}. {"A password is required to enter this room","Bu odaya girmek için parola gerekiyor"}. {"April","Nisan"}. {"August","Ağustos"}. {"Backup Management","Yedek Yönetimi"}. {"Backup of ","Yedek : "}. {"Backup to File at ","Dosyaya Yedekle : "}. {"Backup","Yedekle"}. {"Bad format","Kötü biçem"}. {"Birthday","Doğumgünü"}. {"CAPTCHA web page","CAPTCHA web sayfası"}. {"Change Password","Parola Değiştir"}. {"Change User Password","Kullanıcı Parolasını Değiştir"}. {"Characters not allowed:","İzin verilmeyen karakterler:"}. {"Chatroom configuration modified","Sohbet odası ayarı değiştirildi"}. {"Chatroom is created","Sohbet odası oluşturuldu"}. {"Chatroom is destroyed","Sohbet odası kaldırıldı"}. {"Chatroom is started","Sohbet odası başlatıldı"}. {"Chatroom is stopped","Sohbet odası durduruldu"}. {"Chatrooms","Sohbet Odaları"}. {"Choose a username and password to register with this server","Bu sunucuya kayıt olmak için bir kullanıcı ismi ve parola seçiniz"}. {"Choose modules to stop","Durdurulacak modülleri seçiniz"}. {"Choose storage type of tables","Tabloların veri depolama tipini seçiniz"}. {"Choose whether to approve this entity's subscription.","Bu varlığın üyeliğini onaylayıp onaylamamayı seçiniz."}. {"City","İl"}. {"Commands","Komutlar"}. {"Conference room does not exist","Konferans odası bulunamadı"}. {"Configuration","Ayarlar"}. {"Configuration of room ~s","~s odasının ayarları"}. {"Connected Resources:","Bağlı Kaynaklar:"}. {"Connections parameters","Bağlantı parametreleri"}. {"Country","Ülke"}. {"CPU Time:","İşlemci Zamanı:"}. {"Database Tables at ","Veritabanı Tabloları : "}. {"Database Tables Configuration at ","Veritabanı Tablo Ayarları : "}. {"Database","Veritabanı"}. {"December","Aralık"}. {"Default users as participants","Kullanıcılar öntanımlı olarak katılımcı olsun"}. {"Delete message of the day","Günün mesajını sil"}. {"Delete message of the day on all hosts","Tüm sunuculardaki günün mesajını sil"}. {"Delete Selected","Seçilenleri Sil"}. {"Delete","Sil"}. {"Delete User","Kullanıcıyı Sil"}. {"Deliver event notifications","Olay uyarıları gönderilsin"}. {"Deliver payloads with event notifications","Yükleri (payload) olay uyarıları ile beraber gönder"}. {"Description:","Tanım:"}. {"Disc only copy","Sadece disk kopyala"}. {"Displayed Groups:","Gösterilen Gruplar:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Parolanızı kimseye söylemeyin, Jabber sunucusunun yöneticilerine bile."}. {"Dump Backup to Text File at ","Metin Dosyasına Döküm Alarak Yedekle : "}. {"Dump to Text File","Metin Dosyasına Döküm Al"}. {"Edit Properties","Özellikleri Düzenle"}. {"Either approve or decline the voice request.","Ses isteğini kabul edin ya da reddedin"}. {"ejabberd IRC module","ejabberd IRC modülü"}. {"ejabberd MUC module","ejabberd MUC modülü"}. {"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe modülü"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams modülü"}. {"ejabberd vCard module","ejabberd vCard modülü"}. {"ejabberd Web Admin","ejabberd Web Yöneticisi"}. {"Elements","Elementler"}. {"Email","E-posta"}. {"Enable logging","Kayıt tutma özelliğini aç"}. {"Encoding for server ~b","Sunucu için kodlama ~b"}. {"End User Session","Kullanıcı Oturumunu Kapat"}. {"Enter list of {Module, [Options]}","{Module, [Options]} listesi giriniz"}. {"Enter nickname you want to register","Kaydettirmek istediğiniz takma ismi giriniz"}. {"Enter path to backup file","Yedek dosyasının yolunu giriniz"}. {"Enter path to jabberd14 spool dir","jabberd14 spool dosyası için yol giriniz"}. {"Enter path to jabberd14 spool file","jabberd14 spool dosyası için yol giriniz"}. {"Enter path to text file","Metin dosyasının yolunu giriniz"}. {"Enter the text you see","Gördüğünüz metni giriniz"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","IRC sunuculara bağlanmak için kullanmak istediğiniz kullanıcı isimleri ve kodlamaları giriniz. 'İleri' tuşuna basınca karşınıza dolduracak daha fazla alan çıkacak. 'Tamamla' tuşuna basarak ayarları kaydedin."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","IRC sunuculara bağlanmak için kullanmak istediğiniz kullanıcı ismi, kodlamalar, kapılar (portlar) ve parolaları giriniz"}. {"Erlang Jabber Server","Erlang Jabber Sunucusu"}. {"Error","Hata"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Örnek: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"gizli\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}], {\"irc.sometestserver.net\", \"utf-8\"}]"}. {"Exclude Jabber IDs from CAPTCHA challenge","CAPTCHA doğrulamasını şu Jabber ID'ler için yapma"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Sunucudaki tüm kullanıcıların verisini PIEFXIS dosyalarına (XEP-0227) dışa aktar:"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Bir sunucudaki kullanıcıların verisini PIEFXIS dosyalarına (XEP-0227) dışa aktar:"}. {"Failed to extract JID from your voice request approval","Ses isteği onayınızdan JID bilginize ulaşılamadı"}. {"Family Name","Soyisim"}. {"February","Şubat"}. {"Fill in fields to search for any matching Jabber User","Eşleşen jabber kullanıcılarını aramak için alanları doldurunuz"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Eşleşen jabber kullanıcılarını aramak için formu doldurunuz (Alt dizgi eşlemek için alanın sonuna * ekleyin)"}. {"Friday","Cuma"}. {"From","Kimden"}. {"From ~s","Kimden ~s"}. {"Full Name","Tam İsim"}. {"Get Number of Online Users","Bağlı Kullanıcı Sayısını Al"}. {"Get Number of Registered Users","Kayıtlı Kullanıcı Sayısını Al"}. {"Get User Last Login Time","Kullanıcı Son Giriş Zamanınlarını Al"}. {"Get User Password","Kullanıcı Parolasını Al"}. {"Get User Statistics","Kullanıcı İstatistiklerini Al"}. {"Grant voice to this person?","Bu kişiye ses verelim mi?"}. {"Group ","Group "}. {"Groups","Gruplar"}. {"has been banned","odaya girmesi yasaklandı"}. {"has been kicked because of an affiliation change","ilişki değişikliğinden dolayı atıldı"}. {"has been kicked because of a system shutdown","sistem kapandığından dolayı atıldı"}. {"has been kicked because the room has been changed to members-only","oda üyelere-özel hale getirildiğinden dolayı atıldı"}. {"has been kicked","odadan atıldı"}. {" has set the subject to: "," konuyu değiştirdi: "}. {"Host","Sunucu"}. {"If you don't see the CAPTCHA image here, visit the web page.","Eğer burada CAPTCHA resmini göremiyorsanız, web sayfasını ziyaret edin."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","IRC sunucuları için farklı kapılar (portlar), parolalar, kodlamalar belirtmek istiyorsanız, '{\"irc sunucusu\", \"kodlama\",\"kapı\",\"parola\"}' biçeminde değerlerle bu listeyi doldurunuz. Öntanımlı olarak bu servis \"~s\" kodlamasını, ~p \"kapısını\", \"boş\" parolasını kullanıyor."}. {"Import Directory","Dizini İçe Aktar"}. {"Import File","Dosyayı İçe Aktar"}. {"Import user data from jabberd14 spool file:","Jabberd 1.4 Spool Dosyalarından Kullanıcıları İçe Aktar:"}. {"Import User from File at ","Dosyadan Kullanıcıları İçe Aktar : "}. {"Import users data from a PIEFXIS file (XEP-0227):","Kullanıcıları bir PIEFXIS dosyasından (XEP-0227) içe aktar:"}. {"Import users data from jabberd14 spool directory:","Jabberd 1.4 Spool Dizininden Kullanıcıları İçe Aktar:"}. {"Import Users from Dir at ","Dizinden Kullanıcıları İçe Aktar : "}. {"Import Users From jabberd14 Spool Files","Jabberd 1.4 Spool Dosyalarından Kullanıcıları İçeri Aktar"}. {"Improper message type","Uygunsuz mesaj tipi"}. {"Incorrect password","Yanlış parola"}. {"Invalid affiliation: ~s","Geçersiz ilişki: ~s"}. {"Invalid role: ~s","Geçersiz rol: ~s"}. {"IP addresses","IP adresleri"}. {"IP","IP"}. {"IRC channel (don't put the first #)","IRC kanalı (ilk # işaretini koymayın)"}. {"IRC server","IRC sunucusu"}. {"IRC settings","IRC ayarları"}. {"IRC Transport","IRC Nakli (Transport)"}. {"IRC username","IRC kullanıcı ismi"}. {"IRC Username","IRC Kullanıcı İsmi"}. {"is now known as","isim değiştirdi :"}. {"It is not allowed to send private messages of type \"groupchat\"","\"groupchat\" tipinde özel mesajlar gönderilmesine izin verilmiyor"}. {"It is not allowed to send private messages","Özel mesaj gönderilmesine izin verilmiyor"}. {"It is not allowed to send private messages to the conference","Konferansa özel mesajlar gönderilmesine izin verilmiyor"}. {"Jabber Account Registration","Jabber Hesap Kaydı"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Jabber ID ~s geçersiz"}. {"January","Ocak"}. {"Join IRC channel","IRC kanalına katıl"}. {"joins the room","odaya katıldı"}. {"Join the IRC channel here.","Buradaki IRC kanalına katıl."}. {"Join the IRC channel in this Jabber ID: ~s","IRC kanalına bu Jabber ID'si ile katıl: ~s"}. {"July","Temmuz"}. {"June","Haziran"}. {"Last Activity","Son Aktivite"}. {"Last login","Son giriş"}. {"Last month","Geçen ay"}. {"Last year","Geçen yıl"}. {"leaves the room","odadan ayrıldı"}. {"Listened Ports at ","Dinlenen Kapılar (Portlar) : "}. {"Listened Ports","Dinlenen Kapılar (Portlar)"}. {"List of modules to start","Başlatılacak modüllerin listesi"}. {"Low level update script","Düşük seviye güncelleme betiği"}. {"Make participants list public","Katılımcı listesini herkese açık hale getir"}. {"Make room CAPTCHA protected","Odayı insan doğrulaması (captcha) korumalı hale getir"}. {"Make room members-only","Odayı sadece üyelere açık hale getir"}. {"Make room moderated","Odayı moderasyonlu hale getir"}. {"Make room password protected","Odayı parola korumalı hale getir"}. {"Make room persistent","Odayı kalıcı hale getir"}. {"Make room public searchable","Odayı herkes tarafından aranabilir hale getir"}. {"March","Mart"}. {"Maximum Number of Occupants","Odada En Fazla Bulunabilecek Kişi Sayısı"}. {"Max # of items to persist","Kalıcı hale getirilecek en fazla öğe sayısı"}. {"Max payload size in bytes","En fazla yük (payload) boyutu (bayt olarak)"}. {"May","Mayıs"}. {"Membership is required to enter this room","Bu odaya girmek için üyelik gerekiyor"}. {"Members:","Üyeler:"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Parolanızı ezberleyin ya da bir kağıda yazarak güvenli bir yerde saklayın. Jabber'da parolanızı unutursanız, otomatik kurtarmak için bir yöntem bulunmuyor."}. {"Memory","Bellek"}. {"Message body","Mesajın gövdesi"}. {"Middle Name","Ortanca İsim"}. {"Minimum interval between voice requests (in seconds)","Ses istekleri arasında olabilecek en az aralık (saniye olarak)"}. {"Moderator privileges required","Moderatör yetkileri gerekli"}. {"moderators only","sadece moderatörler"}. {"Modified modules","Değişen modüller"}. {"Module","Modül"}. {"Modules at ","Modüller : "}. {"Modules","Modüller"}. {"Monday","Pazartesi"}. {"Name:","İsim:"}. {"Name","İsim"}. {"Never","Asla"}. {"New Password:","Yeni Parola:"}. {"Nickname Registration at ","Takma İsim Kaydı : "}. {"Nickname ~s does not exist in the room","~s takma ismi odada yok"}. {"Nickname","Takma isim"}. {"nobody","hiç kimse"}. {"No body provided for announce message","Duyuru mesajının gövdesi yok"}. {"No Data","Veri Yok"}. {"Node ","Düğüm "}. {"Node ID","Düğüm ID"}. {"Node not found","Düğüm bulunamadı"}. {"Nodes","Düğümler"}. {"No limit","Sınırsız"}. {"None","Hiçbiri"}. {"No resource provided","Hiç kaynak sağlanmadı"}. {"Not Found","Bulunamadı"}. {"Notify subscribers when items are removed from the node","Düğümden öğeler kaldırıldığında üyeleri uyar"}. {"Notify subscribers when the node configuration changes","Düğüm ayarları değiştiğinde üyeleri uyar"}. {"Notify subscribers when the node is deleted","Bir düğüm silindiğinde üyeleri uyar"}. {"November","Kasım"}. {"Number of occupants","Oda sakini sayısı"}. {"Number of online users","Bağlı kullanıcı sayısı"}. {"Number of registered users","Kayıtlı kullanıcı sayısı"}. {"October","Ekim"}. {"Offline Messages:","Çevirim-dışı Mesajlar:"}. {"Offline Messages","Çevirim-dışı Mesajlar"}. {"OK","Tamam"}. {"Old Password:","Eski Parola:"}. {"Online","Bağlı"}. {"Online Users:","Bağlı Kullanıcılar:"}. {"Online Users","Bağlı Kullanıcılar"}. {"Only deliver notifications to available users","Uyarıları sadece durumu uygun kullanıcılara ulaştır"}. {"Only moderators and participants are allowed to change the subject in this room","Sadece moderatörlerin ve katılımcıların bu odanın konusunu değiştirmesine izin veriliyor"}. {"Only moderators are allowed to change the subject in this room","Sadece moderatörlerin bu odanın konusunu değiştirmesine izin veriliyor"}. {"Only moderators can approve voice requests","Yalnız moderatörler ses isteklerini onaylayabilir"}. {"Only occupants are allowed to send messages to the conference","Sadece oda sakinlerinin konferansa mesaj göndermesine izin veriliyor"}. {"Only occupants are allowed to send queries to the conference","Sadece oda sakinlerinin konferansa sorgu göndermesine izin veriliyor"}. {"Only service administrators are allowed to send service messages","Sadece servis yöneticileri servis mesajı gönderebilirler"}. {"Options","Seçenekler"}. {"Organization Name","Kurum İsmi"}. {"Organization Unit","Kurumun İlgili Birimi"}. {"Outgoing s2s Connections:","Giden s2s Bağlantıları:"}. {"Outgoing s2s Connections","Giden s2s Bağlantıları"}. {"Outgoing s2s Servers:","Giden s2s Sunucuları"}. {"Owner privileges required","Sahip yetkileri gerekli"}. {"Packet","Paket"}. {"Password ~b","Parola ~b"}. {"Password:","Parola:"}. {"Password","Parola"}. {"Password Verification:","Parola Doğrulaması:"}. {"Password Verification","Parola Doğrulaması"}. {"Path to Dir","Dizinin Yolu"}. {"Path to File","Dosyanın Yolu"}. {"Pending","Sıra Bekleyen"}. {"Period: ","Periyot:"}. {"Persist items to storage","Öğeleri depoda kalıcı hale getir"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Bu seçeneklerin sadece gömülü Mnesia veritabanını yedekleyeceğine dikkat edin. Eğer ODBC modülünü kullanıyorsanız, SQL veritabanınızı da ayrıca yedeklemeniz gerekiyor."}. {"Please, wait for a while before sending new voice request","Lütfen yeni bir ses isteği göndermeden önce biraz bekleyin"}. {"Pong","Pong"}. {"Port ~b","Kapı (Port) ~b"}. {"Port","Kapı (Port)"}. {"Present real Jabber IDs to","Gerçek Jabber ID'lerini göster :"}. {"private, ","özel"}. {"Protocol","Protokol"}. {"Publish-Subscribe","Yayınla-Üye Ol"}. {"PubSub subscriber request","PubSub üye isteği"}. {"Purge all items when the relevant publisher goes offline","İlgili yayıncı çevirimdışı olunca tüm onunla ilgili olanları sil"}. {"Queries to the conference members are not allowed in this room","Bu odada konferans üyelerine sorgu yapılmasına izin verilmiyor"}. {"RAM and disc copy","RAM ve disk kopyala"}. {"RAM copy","RAM kopyala"}. {"Raw","Ham"}. {"Really delete message of the day?","Günün mesajını silmek istediğinize emin misiniz?"}. {"Recipient is not in the conference room","Alıcı konferans odasında değil"}. {"Register a Jabber account","Bir Jabber hesabı kaydet"}. {"Registered Users:","Kayıtlı Kullanıcılar:"}. {"Registered Users","Kayıtlı Kullanıcılar"}. {"Register","Kayıt Ol"}. {"Registration in mod_irc for ","mod_irc'ye kayıt : "}. {"Remote copy","Uzak kopyala"}. {"Remove All Offline Messages","Tüm Çevirim-dışı Mesajları Kaldır"}. {"Remove","Kaldır"}. {"Remove User","Kullanıcıyı Kaldır"}. {"Replaced by new connection","Eski bağlantı yenisi ile değiştirildi"}. {"Resources","Kaynaklar"}. {"Restart Service","Servisi Tekrar Başlat"}. {"Restart","Tekrar Başlat"}. {"Restore Backup from File at ","Dosyadaki Yedekten Geri Al : "}. {"Restore binary backup after next ejabberd restart (requires less memory):","ejabberd'nin bir sonraki tekrar başlatılışında ikili yedekten geri al (daha az bellek gerektirir)"}. {"Restore binary backup immediately:","Hemen ikili yedekten geri al:"}. {"Restore plain text backup immediately:","Hemen düz metin yedekten geri al"}. {"Restore","Yedekten Geri Al"}. {"Room Configuration","Oda Ayarları"}. {"Room creation is denied by service policy","Odanın oluşturulması servis politikası gereği reddedildi"}. {"Room description","Oda tanımı"}. {"Room Occupants","Oda Sakini Sayısı"}. {"Room title","Oda başlığı"}. {"Roster groups allowed to subscribe","Üye olunmasına izin verilen kontak listesi grupları"}. {"Roster","Kontak Listesi"}. {"Roster of ","Kontak Listesi : "}. {"Roster size","İsim listesi boyutu"}. {"RPC Call Error","RPC Çağrı Hatası"}. {"Running Nodes","Çalışan Düğümler"}. {"~s access rule configuration","~s erişim kuralları ayarları"}. {"Saturday","Cumartesi"}. {"Script check","Betik kontrolü"}. {"Search Results for ","Arama sonuçları : "}. {"Search users in ","Kullanıcılarda arama yap : "}. {"Send announcement to all online users","Duyuruyu tüm bağlı kullanıcılara yolla"}. {"Send announcement to all online users on all hosts","Duyuruyu tüm sunuculardaki tüm bağlı kullanıcılara yolla"}. {"Send announcement to all users","Duyuruyu tüm kullanıcılara yolla"}. {"Send announcement to all users on all hosts","Tüm sunuculardaki tüm kullanıcılara duyuru yolla"}. {"September","Eylül"}. {"Server ~b","Sunucu ~b"}. {"Server:","Sunucu:"}. {"Set message of the day and send to online users","Günün mesajını belirle"}. {"Set message of the day on all hosts and send to online users","Tüm sunucularda günün mesajını belirle ve bağlı tüm kullanıcılara gönder"}. {"Shared Roster Groups","Paylaşımlı Kontak Listesi Grupları"}. {"Show Integral Table","Önemli Tabloyu Göster"}. {"Show Ordinary Table","Sıradan Tabloyu Göster"}. {"Shut Down Service","Servisi Kapat"}. {"~s invites you to the room ~s","~s sizi ~s odasına davet ediyor"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Bazı Jabber istemcileri parolanızı bilgisayarınızda saklayabilir. Bu özelliği ancak bilgisayarın güvenli olduğuna güveniyorsanız kullanın."}. {"Specify the access model","Erişim modelini belirtiniz"}. {"Specify the event message type","Olay mesaj tipini belirtiniz"}. {"Specify the publisher model","Yayıncı modelini belirtiniz"}. {"~s's Offline Messages Queue","~s Kullanıcısının Mesaj Kuyruğu"}. {"Start","Başlat"}. {"Start Modules at ","Modülleri Başlat : "}. {"Start Modules","Modülleri Başlat"}. {"Statistics","İstatistikler"}. {"Statistics of ~p","~p istatistikleri"}. {"Stop","Durdur"}. {"Stop Modules at ","Modülleri Durdur : "}. {"Stop Modules","Modülleri Durdur"}. {"Stopped Nodes","Durdurulmuş Düğümler"}. {"Storage Type","Depolama Tipi"}. {"Store binary backup:","İkili yedeği sakla:"}. {"Store plain text backup:","Düz metin yedeği sakla:"}. {"Subject","Konu"}. {"Submit","Gönder"}. {"Submitted","Gönderilenler"}. {"Subscriber Address","Üye Olanın Adresi"}. {"Subscription","Üyelik"}. {"Sunday","Pazar"}. {"That nickname is already in use by another occupant","Takma isim odanın başka bir sakini tarafından halihazırda kullanımda"}. {"That nickname is registered by another person","O takma isim başka biri tarafından kaydettirilmiş"}. {"The CAPTCHA is valid.","İnsan doğrulaması (captcha) geçerli."}. {"The CAPTCHA verification has failed","CAPTCHA doğrulaması başarısız oldu"}. {"The collections with which a node is affiliated","Bir düğüm ile bağlantılı koleksiyonlar"}. {"the password is","parola :"}. {"The password is too weak","Parola çok zayıf"}. {"The password of your Jabber account was successfully changed.","Jabber hesabınızın parolası başarıyla değiştirildi."}. {"There was an error changing the password: ","Parolanın değiştirilmesi sırasında bir hata oluştu:"}. {"There was an error creating the account: ","Hesap oluşturulurken bir hata oluştu:"}. {"There was an error deleting the account: ","Hesabın silinmesi sırasında bir hata oluştu:"}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Burada büyük küçük harfi yapılmaz: macbeth ile MacBeth ve Macbeth aynıdır."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Bu sayfa bu Jabber sunucusunda bir Jabber hesabı oluşturulmasına olanak tanıyor. Sizin JID'iniz (Jabber Tanımlayıcısı) şu biçemde olacaktır: kullanici_adi@sunucu. Lütfen alanları doğru doldurabilmek için yönergeleri dikkatle okuyunuz."}. {"This page allows to unregister a Jabber account in this Jabber server.","Bu sayfa bu Jabber sunucusundan bir Jabber hesabının kaydını silmeye olanak tanıyor."}. {"This participant is kicked from the room because he sent an error message","Bu katılımcı bir hata mesajı gönderdiği için odadan atıldı"}. {"This participant is kicked from the room because he sent an error message to another participant","Bu katılımcı başka bir katılımcıya bir hata mesajı gönderdiği için odadan atıldı"}. {"This participant is kicked from the room because he sent an error presence","Bu katılımcı bir hata varlığı (presence) gönderdiği için odadan atıldı"}. {"This room is not anonymous","Bu oda anonim değil"}. {"Thursday","Perşembe"}. {"Time delay","Zaman gecikmesi"}. {"Time","Zaman"}. {"To","Kime"}. {"Too many CAPTCHA requests","Çok fazla CAPTCHA isteği"}. {"To ~s","Kime ~s"}. {"Traffic rate limit is exceeded","Trafik oran sınırı aşıldı"}. {"Transactions Aborted:","İptal Edilen Hareketler (Transactions):"}. {"Transactions Committed:","Tamamlanan Hareketler (Transactions Committed):"}. {"Transactions Logged:","Kaydı Tutulan Hareketler (Transactions):"}. {"Transactions Restarted:","Tekrar Başlatılan Hareketler (Transactions):"}. {"Tuesday","Salı"}. {"Unable to generate a CAPTCHA","İnsan doğrulaması (CAPTCHA) oluşturulamadı"}. {"Unauthorized","Yetkisiz"}. {"Unregister a Jabber account","Bir Jabber hesabı kaydı sil"}. {"Unregister","Kaydı Sil"}. {"Update ","Güncelle "}. {"Update","GÜncelle"}. {"Update message of the day (don't send)","Günün mesajını güncelle (gönderme)"}. {"Update message of the day on all hosts (don't send)","Tüm sunuculardaki günün mesajını güncelle (gönderme)"}. {"Update plan","Planı güncelle"}. {"Update script","Betiği Güncelle"}. {"Uptime:","Hizmet Süresi:"}. {"Use of STARTTLS required","STARTTLS kullanımı gereklidir"}. {"User JID","Kullanıcı JID"}. {"User ","Kullanıcı "}. {"User","Kullanıcı"}. {"User Management","Kullanıcı Yönetimi"}. {"Username:","Kullanıcı adı:"}. {"Users are not allowed to register accounts so quickly","Kullanıcıların bu kadar hızlı hesap açmalarına izin verilmiyor"}. {"Users","Kullanıcılar"}. {"Users Last Activity","Kullanıcıların Son Aktiviteleri"}. {"Validate","Geçerli"}. {"vCard User Search","vCard Kullanıcı Araması"}. {"Virtual Hosts","Sanal Sunucuları"}. {"Visitors are not allowed to change their nicknames in this room","Bu odada ziyaretçilerin takma isimlerini değiştirmesine izin verilmiyor"}. {"Visitors are not allowed to send messages to all occupants","Ziyaretçilerin odadaki tüm sakinlere mesaj göndermesine izin verilmiyor"}. {"Voice requests are disabled in this conference","Bu konferansta ses istekleri etkisizleştirilmiş durumda."}. {"Voice request","Ses isteği"}. {"Wednesday","Çarşamba"}. {"When to send the last published item","Son yayınlanan öğe ne zaman gönderilsin"}. {"Whether to allow subscriptions","Üyeliklere izin verilsin mi"}. {"You can later change your password using a Jabber client.","Parolanızı daha sonra bir Jabber istemci kullanarak değiştirebilirsiniz."}. {"You have been banned from this room","Bu odaya girmeniz yasaklandı"}. {"You must fill in field \"Nickname\" in the form","Formda \"Takma isim\" alanını doldurmanız gerekiyor"}. {"You need a client that supports x:data and CAPTCHA to register","Takma isminizi kaydettirmek için x:data ve CAPTCHA destekleyen bir istemciye gereksinimiz var"}. {"You need a client that supports x:data to register the nickname","Takma isminizi kaydettirmek için x:data destekleyen bir istemciye gereksinimiz var"}. {"You need an x:data capable client to configure mod_irc settings","mod_irc ayarlarını düzenlemek için x:data becerisine sahip bir istemciye gereksinimiz var"}. {"You need an x:data capable client to configure room","Odayı ayarlamak için x:data becerisine sahip bir istemciye gereksinimiz var"}. {"You need an x:data capable client to search","Arama yapabilmek için x:data becerisine sahip bir istemciye gereksinimiz var"}. {"Your active privacy list has denied the routing of this stanza.","Etkin mahremiyet listeniz bu bölümün yönlendirilmesini engelledi."}. {"Your contact offline message queue is full. The message has been discarded.","Çevirim-dışı mesaj kuyruğunuz dolu. Mesajını dikkate alınmadı."}. {"Your Jabber account was successfully created.","Jabber hesabınız başarıyla oluşturuldu."}. {"Your Jabber account was successfully deleted.","Jabber hesabınız başarıyla silindi."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","~s kullanıcısına mesajlarınız engelleniyor. Durumu düzeltmek için ~s adresini ziyaret ediniz."}. ejabberd-2.1.11/src/msgs/fr.msg0000664000000000000000000006646212240230175013113 0ustar {"Access Configuration","Configuration d'accès"}. {"Access Control List Configuration","Configuration des droits (ACL)"}. {"Access control lists","Droits (ACL)"}. {"Access Control Lists","Droits (ACL)"}. {"Access denied by service policy","L'accès au service est refusé"}. {"Access rules","Règles d'accès"}. {"Access Rules","Règles d'accès"}. {"Action on user","Action sur l'utilisateur"}. {"Add Jabber ID","Ajouter un Jabber ID"}. {"Add New","Ajouter"}. {"Add User","Ajouter un utilisateur"}. {"Administration","Administration"}. {"Administration of ","Administration de "}. {"Administrator privileges required","Les droits d'administrateur sont nécessaires"}. {"A friendly name for the node","Un nom convivial pour le noeud"}. {"All activity","Toute activité"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Autoriser ce Jabber ID à s'abonner à ce nœud PubSub"}. {"Allow users to change the subject","Autoriser les utilisateurs à changer le sujet"}. {"Allow users to query other users","Permettre aux utilisateurs d'envoyer des requêtes aux autres utilisateurs"}. {"Allow users to send invites","Permettre aux utilisateurs d'envoyer des invitations"}. {"Allow users to send private messages","Autoriser les utilisateurs à envoyer des messages privés"}. {"Allow visitors to change nickname","Autoriser les visiteurs à changer de pseudo"}. {"Allow visitors to send status text in presence updates","Autoriser les visiteurs à envoyer un message d'état avec leur présence"}. {"All Users","Tous les utilisateurs"}. {"Announcements","Annonces"}. {"anyone","tout le monde"}. {"A password is required to enter this room","Un mot de passe est nécessaire pour accèder à ce salon"}. {"April","Avril"}. {"August","Août"}. {"Backup Management","Gestion des sauvegardes"}. {"Backup of ","Sauvegarde de "}. {"Backup","Sauvegarde"}. {"Backup to File at ","Sauvegarde sur fichier sur "}. {"Bad format","Mauvais format"}. {"Birthday","Date d'anniversaire"}. {"CAPTCHA web page","Page web de CAPTCHA"}. {"Change Password","Modifier le mot de passe"}. {"Change User Password","Changer le mot de passe de l'utilisateur"}. {"Characters not allowed:","Caractères non-autorisés :"}. {"Chatroom configuration modified","Configuration du salon modifiée"}. {"Chatroom is created","Le salon de discussion est créé"}. {"Chatroom is destroyed","Le salon de discussion est détruit"}. {"Chatroom is started","Le salon de discussion a démarré"}. {"Chatroom is stopped","Le salon de discussion est stoppé"}. {"Chatrooms","Salons de discussion"}. {"Choose a username and password to register with this server","Choisissez un nom d'utilisateur et un mot de passe pour s'enregistrer sur ce serveur"}. {"Choose modules to stop","Sélectionnez les modules à arrêter"}. {"Choose storage type of tables","Choisissez un type de stockage pour les tables"}. {"Choose whether to approve this entity's subscription.","Accepter cet abonnement ?"}. {"City","Ville"}. {"Commands","Commandes"}. {"Conference room does not exist","La salle de conférence n'existe pas"}. {"Configuration","Configuration"}. {"Configuration of room ~s","Configuration pour le salon ~s"}. {"Connected Resources:","Ressources connectées:"}. {"Connections parameters","Paramètres de connexion"}. {"Country","Pays"}. {"CPU Time:","Temps CPU :"}. {"Database","Base de données"}. {"Database Tables at ","Tables de base de données sur "}. {"Database Tables Configuration at ","Configuration des tables de base de données sur "}. {"December","Décembre"}. {"Default users as participants","Les utilisateurs sont par défaut participant"}. {"Delete message of the day on all hosts","Supprimer le message du jour sur tous les domaines"}. {"Delete message of the day","Supprimer le message du jour"}. {"Delete Selected","Suppression des éléments sélectionnés"}. {"Delete","Supprimer"}. {"Delete User","Supprimer l'utilisateur"}. {"Deliver event notifications","Envoyer les notifications d'événement"}. {"Deliver payloads with event notifications","Inclure le contenu du message avec la notification"}. {"Description:","Description :"}. {"Disc only copy","Copie sur disque uniquement"}. {"Displayed Groups:","Groupes affichés :"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Ne révélez votre mot de passe à personne, pas même l'administrateur de ce serveur."}. {"Dump Backup to Text File at ","Enregistrer la sauvegarde dans un fichier texte sur "}. {"Dump to Text File","Sauvegarder dans un fichier texte"}. {"Edit Properties","Modifier les propriétés"}. {"ejabberd IRC module","Module IRC ejabberd"}. {"ejabberd MUC module","Module MUC ejabberd"}. {"ejabberd Publish-Subscribe module","Module Publish-Subscribe d'ejabberd"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}. {"ejabberd vCard module","Module vCard ejabberd"}. {"ejabberd Web Admin","Console Web d'administration de ejabberd"}. {"Elements","Éléments"}. {"Email","Email"}. {"Enable logging","Activer l'archivage"}. {"Encoding for server ~b","Codage pour le serveur ~b"}. {"End User Session","Terminer la session de l'utilisateur"}. {"Enter list of {Module, [Options]}","Entrez une liste de {Module, [Options]}"}. {"Enter nickname you want to register","Entrez le pseudo que vous souhaitez enregistrer"}. {"Enter path to backup file","Entrez le chemin vers le fichier de sauvegarde"}. {"Enter path to jabberd14 spool dir","Entrez le chemin vers le répertoire de spool jabberd14"}. {"Enter path to jabberd14 spool file","Entrez le chemin vers le fichier spool jabberd14"}. {"Enter path to text file","Entrez le chemin vers le fichier texte"}. {"Enter the text you see","Tapez le texte que vous voyez"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Entrez le nom d'utilisateur et les encodages que vous souhaitez utiliser pour vous connecter aux serveurs IRC. Appuyez sur 'Suivant' pour pour avoir d'autres champs à remplir. Appuyez sur 'Terminer' pour sauver les paramètres."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Entrez le nom d'utilisateur, les encodages, les ports et mots de passe que vous souhaitez utiliser pour vous connecter aux serveurs IRC"}. {"Erlang Jabber Server","Serveur Jabber Erlang"}. {"Error","Erreur"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Exemple: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exporter les données de tous les utilisateurs du serveur vers un fichier PIEFXIS (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Exporter les données utilisateurs d'un hôte vers un fichier PIEFXIS (XEP-0227):"}. {"Family Name","Nom de famille"}. {"February","Février"}. {"Fill in fields to search for any matching Jabber User","Remplissez les champs pour rechercher un utilisateur Jabber"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Remplissez le formulaire pour recherche un utilisateur Jabber (Ajouter * à la fin du champ pour chercher n'importe quelle fin de chaîne"}. {"Friday","Vendredi"}. {"From","De"}. {"From ~s","De ~s"}. {"Full Name","Nom complet"}. {"Get Number of Online Users","Récupérer le nombre d'utilisateurs en ligne"}. {"Get Number of Registered Users","Récupérer le nombre d'utilisateurs enregistrés"}. {"Get User Last Login Time","Récupérer la dernière date de connexion de l'utilisateur"}. {"Get User Password","Récupérer le mot de passe de l'utilisateur"}. {"Get User Statistics","Récupérer les statistiques de l'utilisateur"}. {"Group ","Groupe "}. {"Groups","Groupes"}. {"has been banned","a été banni"}. {"has been kicked","a été expulsé"}. {"has been kicked because of an affiliation change","a été éjecté à cause d'un changement d'autorisation"}. {"has been kicked because of a system shutdown","a été éjecté en raison de l'arrêt du système"}. {"has been kicked because the room has been changed to members-only","a été éjecté car la salle est désormais réservée aux membres"}. {" has set the subject to: "," a changé le sujet pour: "}. {"Host","Serveur"}. {"If you don't see the CAPTCHA image here, visit the web page.","SI vous ne voyez pas l'image CAPTCHA ici, visitez la page web."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Si vous voulez préciser différents ports, mots de passe, et encodages pour les serveurs IRC, remplissez cette liste avec des valeurs dans le format '{\"serveur irc\", \"encodage\", port, \"mot de passe\"}'. Par défaut ce service utilise l'encodage \"~s\", port ~p, mot de passe vide."}. {"Import Directory","Importer une répertoire"}. {"Import File","Importer un fichier"}. {"Import user data from jabberd14 spool file:","Importer des utilisateurs depuis un fichier spool Jabberd 1.4:"}. {"Import User from File at ","Importer un utilisateur depuis le fichier sur "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importer les données utilisateurs à partir d'un fichier PIEFXIS (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Importer des utilisateurs depuis un fichier spool Jabberd 1.4:"}. {"Import Users from Dir at ","Importer des utilisateurs depuis le répertoire sur "}. {"Import Users From jabberd14 Spool Files","Importer des utilisateurs depuis un fichier spool Jabberd 1.4"}. {"Improper message type","Mauvais type de message"}. {"Incorrect password","Mot de passe incorrect"}. {"Invalid affiliation: ~s","Affiliation invalide : ~s"}. {"Invalid role: ~s","Role invalide : ~s"}. {"IP addresses","Adresses IP"}. {"IP","IP"}. {"IRC channel (don't put the first #)","Canal IRC (ne pas insérer le premier caractère #)"}. {"IRC server","Serveur IRC"}. {"IRC settings","Configuration IRC"}. {"IRC Transport","Passerelle IRC"}. {"IRC username","Nom d'utilisateur IRC"}. {"IRC Username","Nom d'utilisateur IRC"}. {"is now known as","est maintenant connu comme"}. {"It is not allowed to send private messages","L'envoi de messages privés n'est pas autorisé"}. {"It is not allowed to send private messages of type \"groupchat\"","Il n'est pas permis d'envoyer des messages privés de type \"groupchat\""}. {"It is not allowed to send private messages to the conference","Il n'est pas permis d'envoyer des messages \"normaux\" à la conférence"}. {"Jabber Account Registration","Enregistrement du Compte Jabber"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Le Jabber ID ~s n'est pas valide"}. {"January","Janvier"}. {"Join IRC channel","Rejoindre un canal IRC"}. {"joins the room","rejoint le salon"}. {"Join the IRC channel here.","Rejoindre un canal IRC ici"}. {"Join the IRC channel in this Jabber ID: ~s","Rejoindre un canal IRC avec ce Jabber ID: ~s"}. {"July","Juillet"}. {"June","Juin"}. {"Last Activity","Dernière Activité"}. {"Last login","Dernière connexion"}. {"Last month","Dernier mois"}. {"Last year","Dernière année"}. {"leaves the room","quitte le salon"}. {"Listened Ports at ","Ports ouverts sur "}. {"Listened Ports","Ports ouverts"}. {"List of modules to start","Liste des modules à démarrer"}. {"Low level update script","Script de mise à jour de bas-niveau"}. {"Make participants list public","Rendre la liste des participants publique"}. {"Make room CAPTCHA protected","Protéger le salon par un CAPTCHA"}. {"Make room members-only","Réserver le salon aux membres uniquement"}. {"Make room moderated","Rendre le salon modéré"}. {"Make room password protected","Protéger le salon par mot de passe"}. {"Make room persistent","Rendre le salon persistant"}. {"Make room public searchable","Rendre le salon public"}. {"March","Mars"}. {"Maximum Number of Occupants","Nombre maximum d'occupants"}. {"Max # of items to persist","Nombre maximum d'éléments à stocker"}. {"Max payload size in bytes","Taille maximum pour le contenu du message en octet"}. {"May","Mai"}. {"Membership is required to enter this room","Vous devez être membre pour accèder à ce salon"}. {"Members:","Membres :"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Mémorisez votre mot de passe, ou écrivez-le sur un papier conservé dans un endroit secret. Dans Jabber il n'y a pas de mécanisme pour retrouver votre mot de passe si vous l'avez oublié."}. {"Memory","Mémoire"}. {"Message body","Corps du message"}. {"Middle Name","Autre nom"}. {"Moderator privileges required","Les droits de modérateur sont nécessaires"}. {"moderators only","modérateurs seulement"}. {"Modified modules","Modules mis à jour"}. {"Module","Module"}. {"Modules at ","Modules sur "}. {"Modules","Modules"}. {"Monday","Lundi"}. {"Name:","Nom :"}. {"Name","Nom"}. {"Never","Jamais"}. {"New Password:","Nouveau mot de passe:"}. {"Nickname","Pseudo"}. {"Nickname Registration at ","Enregistrement d'un pseudo sur "}. {"Nickname ~s does not exist in the room","Le pseudo ~s n'existe pas dans ce salon"}. {"No body provided for announce message","Pas de corps de message pour l'annonce"}. {"No Data","Aucune information disponible"}. {"Node ID","Identifiant du nœud"}. {"Node ","Noeud "}. {"Node not found","Noeud non trouvé"}. {"Nodes","Noeuds"}. {"No limit","Pas de limite"}. {"None","Aucun"}. {"No resource provided","Aucune ressource fournie"}. {"Not Found","Nœud non trouvé"}. {"Notify subscribers when items are removed from the node","Avertir les abonnés lorsque des éléments sont supprimés sur le nœud"}. {"Notify subscribers when the node configuration changes","Avertir les abonnés lorsque la configuration du nœud change"}. {"Notify subscribers when the node is deleted","Avertir les abonnés lorsque le nœud est supprimé"}. {"November","Novembre"}. {"Number of occupants","Nombre d'occupants"}. {"Number of online users","Nombre d'utilisateurs en ligne"}. {"Number of registered users","Nombre d'utilisateurs enregistrés"}. {"October","Octobre"}. {"Offline Messages:","Messages en attente :"}. {"Offline Messages","Messages en attente"}. {"OK","OK"}. {"Old Password:","Ancien mot de passe:"}. {"Online","En ligne"}. {"Online Users:","Utilisateurs connectés:"}. {"Online Users","Utilisateurs en ligne"}. {"Only deliver notifications to available users","Envoyer les notifications uniquement aux utilisateurs disponibles"}. {"Only moderators and participants are allowed to change the subject in this room","Seuls les modérateurs et les participants peuvent changer le sujet dans ce salon"}. {"Only moderators are allowed to change the subject in this room","Seuls les modérateurs peuvent changer le sujet dans ce salon"}. {"Only occupants are allowed to send messages to the conference","Seuls les occupants peuvent envoyer des messages à la conférence"}. {"Only occupants are allowed to send queries to the conference","Seuls les occupants sont autorisés à envoyer des requêtes à la conférence"}. {"Only service administrators are allowed to send service messages","Seuls les administrateurs du service sont autoriser à envoyer des messages de service"}. {"Options","Options"}. {"Organization Name","Nom de l'organisation"}. {"Organization Unit","Unité de l'organisation"}. {"Outgoing s2s Connections:","Connexions s2s sortantes:"}. {"Outgoing s2s Connections","Connexions s2s sortantes"}. {"Outgoing s2s Servers:","Serveurs s2s sortants"}. {"Owner privileges required","Les droits de propriétaire sont nécessaires"}. {"Packet","Paquet"}. {"Password ~b","Mot de passe ~b"}. {"Password:","Mot de passe:"}. {"Password","Mot de passe"}. {"Password Verification:","Vérification du mot de passe :"}. {"Password Verification","Vérification du mot de passe"}. {"Path to Dir","Chemin vers le répertoire"}. {"Path to File","Chemin vers le fichier"}. {"Pending","En suspens"}. {"Period: ","Période :"}. {"Persist items to storage","Stockage persistant des éléments"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Ces options sauvegardent uniquement la base de données interne Mnesia. Si vous utilisez le module ODBC vous devez sauvegarde votre base SQL séparément."}. {"Pong","Pong"}. {"Port ~b","Port ~b"}. {"Port","Port"}. {"Present real Jabber IDs to","Rendre le Jabber ID réel visible pour"}. {"private, ","privé"}. {"Protocol","Protocole"}. {"Publish-Subscribe","Publication-Abonnement"}. {"PubSub subscriber request","Demande d'abonnement PubSub"}. {"Purge all items when the relevant publisher goes offline","Purger tous les items lorsque publieur est hors-ligne"}. {"Queries to the conference members are not allowed in this room","Les requêtes sur les membres de la conférence ne sont pas autorisé dans ce salon"}. {"RAM and disc copy","Copie en mémoire vive (RAM) et sur disque"}. {"RAM copy","Copie en mémoire vive (RAM)"}. {"Raw","Brut"}. {"Really delete message of the day?","Confirmer la suppression du message du jour ?"}. {"Recipient is not in the conference room","Le destinataire n'est pas dans la conférence"}. {"Register a Jabber account","Enregistrer un compte Jabber"}. {"Registered Users:","Utilisateurs enregistrés:"}. {"Registered Users","Utilisateurs enregistrés"}. {"Register","Enregistrer"}. {"Registration in mod_irc for ","Enregistrement du mod_irc pour "}. {"Remote copy","Copie distante"}. {"Remove All Offline Messages","Effacer tous les messages hors ligne"}. {"Remove","Enlever"}. {"Remove User","Supprimer l'utilisateur"}. {"Replaced by new connection","Remplacé par une nouvelle connexion"}. {"Resources","Ressources"}. {"Restart","Redémarrer"}. {"Restart Service","Redémarrer le service"}. {"Restore Backup from File at ","Restaurer la sauvegarde depuis le fichier sur "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Restauration de la sauvegarde binaire après redémarrage (nécessite moins de mémoire):"}. {"Restore binary backup immediately:","Restauration immédiate d'une sauvegarde binaire:"}. {"Restore plain text backup immediately:","Restauration immédiate d'une sauvegarde texte:"}. {"Restore","Restauration"}. {"Room Configuration","Configuration du salon"}. {"Room creation is denied by service policy","La création de salons est interdite par le service"}. {"Room description","Description :"}. {"Room Occupants","Occupants du salon"}. {"Room title","Titre du salon"}. {"Roster groups allowed to subscribe","Groupes de liste de contact autorisés à s'abonner"}. {"Roster","Liste de contacts"}. {"Roster of ","Liste de contact de "}. {"Roster size","Taille de la liste de contacts"}. {"RPC Call Error","Erreur d'appel RPC"}. {"Running Nodes","Noeuds actifs"}. {"~s access rule configuration","Configuration des règles d'accès ~s"}. {"Saturday","Samedi"}. {"Script check","Validation du script"}. {"Search Results for ","Résultats de recherche pour "}. {"Search users in ","Rechercher des utilisateurs "}. {"Send announcement to all online users","Envoyer l'annonce à tous les utilisateurs en ligne"}. {"Send announcement to all online users on all hosts","Envoyer l'annonce à tous les utilisateurs en ligne sur tous les serveurs"}. {"Send announcement to all users","Envoyer l'annonce à tous les utilisateurs"}. {"Send announcement to all users on all hosts","Envoyer une annonce à tous les utilisateurs de tous les domaines"}. {"September","Septembre"}. {"Server ~b","Serveur ~b"}. {"Server:","Serveur :"}. {"Set message of the day and send to online users","Définir le message du jour et l'envoyer aux utilisateurs en ligne"}. {"Set message of the day on all hosts and send to online users","Définir le message du jour pour tous domaines et l'envoyer aux utilisateurs en ligne"}. {"Shared Roster Groups","Groupes de liste de contacts partagée"}. {"Show Integral Table","Montrer la table intégralement"}. {"Show Ordinary Table","Montrer la table ordinaire"}. {"Shut Down Service","Arrêter le service"}. {"~s invites you to the room ~s","~s vous a invité dans la salle de discussion ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Certains clients Jabber peuvent stocker votre mot de passe sur votre ordinateur. N'utilisez cette fonctionnalité que si vous avez confiance en la sécurité de votre ordinateur."}. {"Specify the access model","Définir le modèle d'accès"}. {"Specify the event message type","Définir le type de message d'événement"}. {"Specify the publisher model","Définir le modèle de publication"}. {"~s's Offline Messages Queue","~s messages en file d'attente"}. {"Start","Démarrer"}. {"Start Modules at ","Démarrer les modules sur "}. {"Start Modules","Modules de démarrage"}. {"Statistics of ~p","Statistiques de ~p"}. {"Statistics","Statistiques"}. {"Stop","Arrêter"}. {"Stop Modules at ","Arrêter les modules sur "}. {"Stop Modules","Modules d'arrêt"}. {"Stopped Nodes","Noeuds arrêtés"}. {"Storage Type","Type de stockage"}. {"Store binary backup:","Sauvegarde binaire:"}. {"Store plain text backup:","Sauvegarde texte:"}. {"Subject","Sujet"}. {"Submit","Soumettre"}. {"Submitted","Soumis"}. {"Subscriber Address","Adresse de l'abonné"}. {"Subscription","Abonnement"}. {"Sunday","Dimanche"}. {"That nickname is already in use by another occupant","Le pseudo est déjà utilisé par un autre occupant"}. {"That nickname is registered by another person","Le pseudo est enregistré par une autre personne"}. {"The CAPTCHA is valid.","Le CAPTCHA est valide"}. {"The CAPTCHA verification has failed","La vérification du CAPTCHA a échoué"}. {"The collections with which a node is affiliated","Les collections avec lesquelle un nœud est affilié"}. {"the password is","le mot de passe est"}. {"The password is too weak","Le mot de passe est trop faible"}. {"The password of your Jabber account was successfully changed.","Le mot de passe de votre compte Jabber a été changé avec succès."}. {"There was an error changing the password: ","Il y a eu une erreur en changeant le mot de passe :"}. {"There was an error creating the account: ","Il y a eu une erreur en créant le compte :"}. {"There was an error deleting the account: ","Il y a eu une erreur en effaçant le compte :"}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","C'est insensible à la casse : macbeth est identique à MacBeth et Macbeth."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Cette page permet de créer un compte Jabber sur ce serveur Jabber. Votre JID (Jabber IDentifier, identifiant Jabber) sera de la forme : nom@serveur. Prière de lire avec attention les instructions pour remplir correctement ces champs."}. {"This page allows to unregister a Jabber account in this Jabber server.","Cette page permet d'effacer un compte Jabber sur ce serveur Jabber."}. {"This participant is kicked from the room because he sent an error message","Ce participant est expulsé du salon pour avoir envoyé un message erronée"}. {"This participant is kicked from the room because he sent an error message to another participant","Ce participant est expulsé du salon pour avoir envoyé un message erronée à un autre participant"}. {"This participant is kicked from the room because he sent an error presence","Ce participant est expulsé du salon pour avoir envoyé une présence erronée"}. {"This room is not anonymous","Ce salon n'est pas anonyme"}. {"Thursday","Jeudi"}. {"Time delay","Délais"}. {"Time","Heure"}. {"To","A"}. {"To ~s","A ~s"}. {"Traffic rate limit is exceeded","La limite de trafic a été dépassée"}. {"Transactions Aborted:","Transactions annulées :"}. {"Transactions Committed:","Transactions commitées :"}. {"Transactions Logged:","Transactions journalisées :"}. {"Transactions Restarted:","Transactions redémarrées :"}. {"Tuesday","Mardi"}. {"Unable to generate a CAPTCHA","Impossible de générer le CAPTCHA"}. {"Unauthorized","Non autorisé"}. {"Unregister a Jabber account","Effacer un compte Jabber"}. {"Unregister","Effacer"}. {"Update message of the day (don't send)","Mise à jour du message du jour (pas d'envoi)"}. {"Update message of the day on all hosts (don't send)","Mettre à jour le message du jour sur tous les domaines (ne pas envoyer)"}. {"Update","Mettre à jour"}. {"Update ","Mise à jour "}. {"Update plan","Plan de mise à jour"}. {"Update script","Script de mise à jour"}. {"Uptime:","Temps depuis le démarrage :"}. {"Use of STARTTLS required","L'utilisation de STARTTLS est impérative"}. {"User Management","Gestion des utilisateurs"}. {"Username:","Nom d'utilisateur :"}. {"Users are not allowed to register accounts so quickly","Les utilisateurs ne sont pas autorisés à enregistrer des comptes si rapidement"}. {"Users Last Activity","Dernière activité des utilisateurs"}. {"Users","Utilisateurs"}. {"User ","Utilisateur "}. {"User","Utilisateur"}. {"Validate","Valider"}. {"vCard User Search","Recherche dans l'annnuaire"}. {"Virtual Hosts","Serveurs virtuels"}. {"Visitors are not allowed to change their nicknames in this room","Les visiteurs ne sont pas autorisés à changer de pseudo dans ce salon"}. {"Visitors are not allowed to send messages to all occupants","Les visiteurs ne sont pas autorisés à envoyer des messages à tout les occupants"}. {"Wednesday","Mercredi"}. {"When to send the last published item","A quel moment envoyer le dernier élément publié"}. {"Whether to allow subscriptions","Autoriser l'abonnement ?"}. {"You can later change your password using a Jabber client.","Vous pouvez changer votre mot de passe plus tard en utilisant un client Jabber."}. {"You have been banned from this room","Vous avez été exclus de ce salon"}. {"You must fill in field \"Nickname\" in the form","Vous devez préciser le champ \"pseudo\" dans le formulaire"}. {"You need a client that supports x:data and CAPTCHA to register","Vous avez besoin d'un client prenant en charge x:data et CAPTCHA pour enregistrer un pseudo"}. {"You need a client that supports x:data to register the nickname","Vous avez besoin d'un client prenant en charge x:data pour enregistrer un pseudo"}. {"You need an x:data capable client to configure mod_irc settings","Vous avez besoin d'un client supportant x:data pour configurer le module IRC"}. {"You need an x:data capable client to configure room","Vous avez besoin d'un client supportant x:data pour configurer le salon"}. {"You need an x:data capable client to search","Vous avez besoin d'un client supportant x:data pour faire une recherche"}. {"Your active privacy list has denied the routing of this stanza.","Votre règle de flitrage active a empêché le routage de ce stanza."}. {"Your contact offline message queue is full. The message has been discarded.","La file d'attente de message de votre contact est pleine. Votre message a été détruit."}. {"Your Jabber account was successfully created.","Votre compte Jabber a été créé avec succès."}. {"Your Jabber account was successfully deleted.","Votre compte Jabber a été effacé avec succès."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Vos messages pour ~s sont bloqués. Pour les débloquer, veuillez visiter ~s"}. ejabberd-2.1.11/src/msgs/de.msg0000664000000000000000000006717312240230175013074 0ustar {"Access Configuration","Zugangskonfiguration"}. {"Access Control List Configuration","Konfiguration der Zugangskontrolllisten"}. {"Access control lists","Zugangskontroll-Listen (ACL)"}. {"Access Control Lists","Zugangskontroll-Listen (ACL)"}. {"Access denied by service policy","Zugang aufgrund der Dienstrichtlinien verweigert"}. {"Access rules","Zugangsregeln"}. {"Access Rules","Zugangsregeln"}. {"Action on user","Aktion auf Benutzer"}. {"Add Jabber ID","Jabber-ID hinzufügen"}. {"Add New","Neue hinzufügen"}. {"Add User","Benutzer hinzufügen"}. {"Administration of ","Administration von "}. {"Administration","Verwaltung"}. {"Administrator privileges required","Administratorenrechte benötigt"}. {"A friendly name for the node","Ein merkbarer Name für den Knoten"}. {"All activity","Alle Aktivitäten"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Dieser Jabber-ID das Abonnement dieses pubsub-Knotens erlauben?"}. {"Allow users to change the subject","Erlaube Benutzern das Thema zu ändern"}. {"Allow users to query other users","Erlaube Benutzern Informationen über andere Benutzer abzufragen"}. {"Allow users to send invites","Erlaube Benutzern Einladungen zu senden"}. {"Allow users to send private messages","Erlaube Benutzern private Nachrichten zu senden"}. {"Allow visitors to change nickname","Erlaube Besuchern ihren Spitznamen zu ändern"}. {"Allow visitors to send private messages to","Erlaube Besuchern das Senden von privaten Nachrichten an"}. {"Allow visitors to send status text in presence updates","Erlaube Besuchern einen Text bei Statusänderung zu senden"}. {"Allow visitors to send voice requests","Anfragen von Sprachrechten für Benutzer erlauben"}. {"All Users","Alle Benutzer"}. {"Announcements","Ankündigungen"}. {"anyone","jeden"}. {"A password is required to enter this room","Sie brauchen ein Passwort um diesen Raum zu betreten"}. {"April","April"}. {"August","August"}. {"Backup","Datensicherung"}. {"Backup Management","Datensicherungsverwaltung"}. {"Backup of ","Sicherung von "}. {"Backup to File at ","Datensicherung in die Datei "}. {"Bad format","Ungültiges Format"}. {"Birthday","Geburtsdatum"}. {"CAPTCHA web page","CAPTCHA Webseite"}. {"Change Password","Passwort ändern"}. {"Change User Password","Benutzer-Passwort ändern"}. {"Characters not allowed:","Nicht erlaubte Zeichen:"}. {"Chatroom configuration modified","Chatraum-Konfiguration geändert"}. {"Chatroom is created","Chatraum wurde erstellt"}. {"Chatroom is destroyed","Chatraum wurde entfernt"}. {"Chatroom is started","Chatraum wurde gestartet"}. {"Chatroom is stopped","Chatraum wurde beendet"}. {"Chatrooms","Chaträume"}. {"Choose a username and password to register with this server","Wählen sie zum Registrieren einen Benutzernamen und ein Passwort"}. {"Choose modules to stop","Wähle zu stoppende Module"}. {"Choose storage type of tables","Wähle Speichertyp der Tabellen"}. {"Choose whether to approve this entity's subscription.","Wähle Sie, ob dieses Abonnement akzeptiert werden soll."}. {"City","Stadt"}. {"Commands","Befehle"}. {"Conference room does not exist","Konferenzraum existiert nicht"}. {"Configuration","Konfiguration"}. {"Configuration of room ~s","Konfiguration für Raum ~s"}. {"Connected Resources:","Verbundene Ressourcen:"}. {"Connections parameters","Verbindungsparameter"}. {"Country","Land"}. {"CPU Time:","CPU-Zeit:"}. {"Database","Datenbank"}. {"Database Tables at ","Datenbanktabellen auf "}. {"Database Tables Configuration at ","Datenbanktabellen-Konfiguration auf "}. {"December","Dezember"}. {"Default users as participants","Standardbenutzer als Teilnehmer"}. {"Delete","Löschen"}. {"Delete message of the day","Lösche Nachricht des Tages"}. {"Delete message of the day on all hosts","Lösche Nachricht des Tages auf allen Hosts"}. {"Delete Selected","Markierte löschen"}. {"Delete User","Benutzer löschen"}. {"Deliver event notifications","Ereignisbenachrichtigung zustellen"}. {"Deliver payloads with event notifications","Nachrichten mit Ereignis-Benachrichtigungen zustellen"}. {"Description:","Beschreibung:"}. {"Disc only copy","Nur auf Festplatte"}. {"Displayed Groups:","Angezeigte Gruppen:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Geben sie niemandem ihr Passwort, auch nicht den Administratoren des Jabber Servers."}. {"Dump Backup to Text File at ","Ausgabe der Sicherung in diese Textdatei "}. {"Dump to Text File","Ausgabe in Textdatei"}. {"Edit Properties","Einstellungen ändern"}. {"Either approve or decline the voice request.","Diese Anfrage für Sprachrechte bestätigen oder ablehnen."}. {"ejabberd IRC module","ejabberd IRC-Modul"}. {"ejabberd MUC module","ejabberd MUC-Modul"}. {"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe-Modul"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5-Bytestreams-Modul"}. {"ejabberd vCard module","ejabberd vCard-Modul"}. {"ejabberd Web Admin","ejabberd Web-Admin"}. {"Elements","Elemente"}. {"Email","E-Mail"}. {"Enable logging","Protokollierung aktivieren"}. {"Encoding for server ~b","Kodierung für Server ~b"}. {"End User Session","Benutzer-Sitzung beenden"}. {"Enter list of {Module, [Options]}","Geben sie eine Liste bestehend aus {Modul, [Optionen]} ein"}. {"Enter nickname you want to register","Geben sie den zu registrierenden Benutzernamen ein"}. {"Enter path to backup file","Geben sie den Pfad zur Datensicherung ein"}. {"Enter path to jabberd14 spool dir","Geben Sie den Pfad zum jabberd14-Spool-Verzeichnis ein"}. {"Enter path to jabberd14 spool file","Geben Sie den Pfad zur jabberd14-Spool-Datei ein"}. {"Enter path to text file","Geben sie den Pfad zur Textdatei ein"}. {"Enter the text you see","Geben sie den Text den sie sehen ein"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Geben sie Benutzernamen und Kodierung für Verbindungen zu IRC Servern an. Drücken sie 'Mehr' um leere Felder hinzuzufügen. Drücken sie 'Beenden' um die Einstellungen zu speichern."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Geben Sie Benutzernamen und Zeichenkodierung für die Verbindung zum IRC-Server an"}. {"Erlang Jabber Server","Erlang Jabber Server"}. {"Error","Fehler"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Beispiel: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Von CAPTCHA Überprüfung ausgeschlossene Jabber IDs"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Alle Benutzerdaten des Servers in PIEFXIS Dateien (XEP-0227) exportieren:"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Alle Benutzerdaten des Hosts in PIEFXIS Dateien (XEP-0227) exportieren:"}. {"Failed to extract JID from your voice request approval","Fehler beim Auslesen der JID aus der Anfragenbestätigung für Sprachrechte"}. {"Family Name","Nachname"}. {"February","Februar"}. {"Fill in fields to search for any matching Jabber User","Füllen Sie die Felder aus, um nach passenden Jabber-Benutzern zu suchen"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Füllen Sie die Felder aus, um nach passenden Jabber-Benutzern zu suchen (beenden Sie ein Feld mit *, um auch nach Teilzeichenketten zu suchen)"}. {"Friday","Freitag"}. {"From ~s","Von ~s"}. {"From","Von"}. {"Full Name","Vollständiger Name"}. {"Get Number of Online Users","Anzahl der angemeldeten Benutzer abrufen"}. {"Get Number of Registered Users","Anzahl der registrierten Benutzer abrufen"}. {"Get User Last Login Time","letzte Anmeldezeit abrufen"}. {"Get User Password","Benutzer-Passwort abrufen"}. {"Get User Statistics","Benutzer-Statistiken abrufen"}. {"Grant voice to this person?","Sprachrechte dieser Person erteilen?"}. {"Group ","Gruppe "}. {"Groups","Gruppen"}. {"has been banned","wurde gebannt"}. {"has been kicked because of an affiliation change","wurde wegen Änderung des Mitgliederstatus gekickt"}. {"has been kicked because of a system shutdown","wurde wegen Systemabschaltung gekickt"}. {"has been kicked because the room has been changed to members-only","wurde gekickt weil der Raum auf Nur-Mitglieder umgestellt wurde"}. {"has been kicked","wurde gekickt"}. {" has set the subject to: "," hat das Thema geändert auf: "}. {"Host","Host"}. {"If you don't see the CAPTCHA image here, visit the web page.","Wenn sie das CAPTCHA Bild nicht sehen, besuchen sie bitte die Webseite."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Wenn sie verschiedene Ports, Passwörter und Kodierungen für IRC Server angeben wollen, erstellen sie die Liste mit folgendem Format '{\"IRC Server\", \"Kodierung\", Port, \"Passwort\"}'. Standardmäßig benutzt dieser Dienst die \"~s\" Kodierung, den Port ~p und kein Passwort."}. {"Import Directory","Verzeichnis importieren"}. {"Import File","Datei importieren"}. {"Import user data from jabberd14 spool file:","Importiere Benutzer von jabberd14 Spool Datei:"}. {"Import User from File at ","Benutzer aus dieser Datei importieren "}. {"Import users data from a PIEFXIS file (XEP-0227):","Benutzerdaten von einer PIEFXIS Datei (XEP-0227) importieren:"}. {"Import users data from jabberd14 spool directory:","Importiere Benutzer von jabberd14 Spool Verzeichnis:"}. {"Import Users from Dir at ","Benutzer importieren aus dem Verzeichnis "}. {"Import Users From jabberd14 Spool Files","Importiere Benutzer aus jabberd14-Spool-Dateien"}. {"Improper message type","Unzulässiger Nachrichtentyp"}. {"Incorrect password","Falsches Passwort"}. {"Invalid affiliation: ~s","Ungültige Mitgliedschaft: ~s"}. {"Invalid role: ~s","Ungültige Rolle: ~s"}. {"IP addresses","IP Adressen"}. {"IP","IP"}. {"IRC channel (don't put the first #)","IRC Channel (ohne dem ersten #)"}. {"IRC server","IRC Server"}. {"IRC settings","IRC Einstellungen"}. {"IRC Transport","IRC Transport"}. {"IRC username","IRC Benutzername"}. {"IRC Username","IRC-Benutzername"}. {"is now known as","ist nun bekannt als"}. {"It is not allowed to send private messages","Es ist nicht erlaubt private Nachrichten zu senden"}. {"It is not allowed to send private messages of type \"groupchat\"","Es ist nicht erlaubt private Nachrichten des Typs \"Gruppenchat\" zu senden"}. {"It is not allowed to send private messages to the conference","Es ist nicht erlaubt private Nachrichten an den Raum zu schicken"}. {"Jabber Account Registration","Jabber Konto Anmeldung"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Die Jabber-ID ~s ist ungültig"}. {"January","Januar"}. {"Join IRC channel","IRC Channel beitreten"}. {"joins the room","betretet den Raum"}. {"Join the IRC channel here.","Hier den IRC Channel beitreten."}. {"Join the IRC channel in this Jabber ID: ~s","Den IRC Channel mit dieser Jabber ID beitreten: ~s"}. {"July","Juli"}. {"June","Juni"}. {"Last Activity","Letzte Aktivität"}. {"Last login","Letzte Anmeldung"}. {"Last month","Letzter Monat"}. {"Last year","Letztes Jahr"}. {"leaves the room","verlässt den Raum"}. {"Listened Ports","Aktive Ports"}. {"Listened Ports at ","Aktive Ports bei"}. {"List of modules to start","Liste der zu startenden Module"}. {"Low level update script","Low level Aktualisierungsscript"}. {"Make participants list public","Teilnehmerliste öffentlich machen"}. {"Make room CAPTCHA protected","Raum mit Verifizierung (Captcha) versehen"}. {"Make room members-only","Raum nur für Mitglieder zugänglich machen"}. {"Make room moderated","Raum moderiert machen"}. {"Make room password protected","Raum mit Passwort schützen"}. {"Make room persistent","Raum persistent machen"}. {"Make room public searchable","Raum öffentlich suchbar machen"}. {"March","März"}. {"Maximum Number of Occupants","Maximale Anzahl von Teilnehmern"}. {"Max # of items to persist","Maximale Anzahl dauerhaft zu speichernder Einträge"}. {"Max payload size in bytes","Maximale Nutzlastgrösse in Bytes"}. {"May","Mai"}. {"Membership is required to enter this room","Um diesen Raum zu betreten müssen sie Mitglied sein"}. {"Members:","Mitglieder:"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Merken sie sich ihr Passwort, oder schreiben sie es auf einen Zettel den sie sicher verwahren. Bei Jabber gibt es keine automatische Möglichkeit, das Passwort wiederherzustellen."}. {"Memory","Speicher"}. {"Message body","Nachrichtentext"}. {"Middle Name","Zweiter Vorname"}. {"Minimum interval between voice requests (in seconds)","Mindestdauer zwischen Anfragen für Sprachrechte (in Sekunden)"}. {"Moderator privileges required","Moderatorrechte benötigt"}. {"moderators only","ausschliesslich Moderatoren"}. {"Modified modules","Geänderte Module"}. {"Module","Modul"}. {"Modules at ","Module bei "}. {"Modules","Module"}. {"Monday","Montag"}. {"Name:","Name:"}. {"Name","Vorname"}. {"Never","Nie"}. {"New Password:","Neues Passwort:"}. {"Nickname","Benutzername"}. {"Nickname Registration at ","Registrieren des Benutzernames auf"}. {"Nickname ~s does not exist in the room","Der Benutzername ~s existiert im Raum nicht"}. {"nobody","niemanden"}. {"No body provided for announce message","Kein Text für die Ankündigung angegeben"}. {"No Data","Keine Daten"}. {"Node ID","Knoten-ID"}. {"Node ","Knoten "}. {"Node not found","Knoten nicht gefunden"}. {"Nodes","Knoten"}. {"No limit","Keine Begrenzung"}. {"None","Keine"}. {"No resource provided","Keine Ressource angegeben"}. {"Not Found","Nicht gefunden"}. {"Notify subscribers when items are removed from the node","Abonnenten benachrichtigen, wenn Einträge vom Knoten entfernt werden"}. {"Notify subscribers when the node configuration changes","Abonnenten benachrichtigen, wenn sich die Knotenkonfiguration ändert"}. {"Notify subscribers when the node is deleted","Abonnenten benachrichtigen, wenn der Knoten gelöscht wird"}. {"November","November"}. {"Number of occupants","Anzahl der Teilnehmer"}. {"Number of online users","Anzahl der angemeldeten Benutzer"}. {"Number of registered users","Anzahl der registrierten Benutzer"}. {"October","Oktober"}. {"Offline Messages:","Offline-Nachrichten:"}. {"Offline Messages","Offline-Nachrichten"}. {"OK","OK"}. {"Old Password:","Aktuelles Passwort:"}. {"Online","Angemeldet"}. {"Online Users:","Angemeldete Benutzer:"}. {"Online Users","Angemeldete Benutzer"}. {"Only deliver notifications to available users","Benachrichtigungen nur an verfügbare Benutzer schicken"}. {"Only moderators and participants are allowed to change the subject in this room","Nur Moderatoren und Mitglieder dürfen das Thema in diesem Raum ändern"}. {"Only moderators are allowed to change the subject in this room","Nur Moderatoren dürfen das Thema in diesem Raum ändern"}. {"Only moderators can approve voice requests","Nur Moderatoren können Anfragen für Sprachrechte bestätigen"}. {"Only occupants are allowed to send messages to the conference","Nur Teilnehmer dürfen Nachrichten an den Raum schicken"}. {"Only occupants are allowed to send queries to the conference","Nur Teilnehmer sind berechtigt Anfragen an die Konferenz zu senden"}. {"Only service administrators are allowed to send service messages","Nur Service-Administratoren sind berechtigt, Servicenachrichten zu versenden"}. {"Options","Optionen"}. {"Organization Name","Organisation"}. {"Organization Unit","Abteilung"}. {"Outgoing s2s Connections:","Ausgehende s2s-Verbindungen:"}. {"Outgoing s2s Connections","Ausgehende s2s-Verbindungen"}. {"Outgoing s2s Servers:","Ausgehende s2s-Server:"}. {"Owner privileges required","Besitzerrechte benötigt"}. {"Packet","Paket"}. {"Password ~b","Passwort ~b"}. {"Password:","Passwort:"}. {"Password","Passwort"}. {"Password Verification:","Passwort bestätigen:"}. {"Password Verification","Passwort bestätigen"}. {"Path to Dir","Pfad zum Verzeichnis"}. {"Path to File","Pfad zur Datei"}. {"Pending","anhängig"}. {"Period: ","Zeitraum: "}. {"Persist items to storage","Einträge dauerhaft speichern"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Beachten sie, das diese Optionen nur die eingebaute Mnesia-Datenbank sichern. Wenn sie das ODBC-Modul verwenden, müssen sie die SQL-Datenbank manuell sichern."}. {"Please, wait for a while before sending new voice request","Bitte warten sie ein wenig, bevor sie eine weitere Anfrage für Sprachrechte senden"}. {"Pong","Pong"}. {"Port ~b","Port ~b"}. {"Port","Port"}. {"Present real Jabber IDs to","Echte Jabber-IDs anzeigen für"}. {"private, ","privat, "}. {"Protocol","Protokoll"}. {"Publish-Subscribe","Publish-Subscribe"}. {"PubSub subscriber request","PubSub-Abonnenten-Anfrage"}. {"Purge all items when the relevant publisher goes offline","Alle Einträge entfernen, wenn der relevante Veröffentlicher offline geht"}. {"Queries to the conference members are not allowed in this room","Anfragen an die Teilnehmer sind in diesem Raum nicht erlaubt"}. {"RAM and disc copy","RAM und Festplatte"}. {"RAM copy","Nur RAM"}. {"Raw","Unformatiert"}. {"Really delete message of the day?","Die Nachricht des Tages wirklich löschen?"}. {"Recipient is not in the conference room","Der Empfänger ist nicht im Raum"}. {"Register a Jabber account","Jabber Konto registrieren"}. {"Register","Anmelden"}. {"Registered Users:","Registrierte Benutzer:"}. {"Registered Users","Registrierte Benutzer"}. {"Registration in mod_irc for ","Registrierung in mod_irc für "}. {"Remote copy","Fernkopie"}. {"Remove All Offline Messages","Alle Offline Nachrichten löschen"}. {"Remove","Entfernen"}. {"Remove User","Benutzer löschen"}. {"Replaced by new connection","Durch neue Verbindung ersetzt"}. {"Resources","Ressourcen"}. {"Restart","Neustart"}. {"Restart Service","Dienst neustarten"}. {"Restore Backup from File at ","Datenwiederherstellung aus der Datei "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Stelle binäre Sicherung beim nächsten ejabberd-Neustart wieder her (benötigt weniger Speicher):"}. {"Restore binary backup immediately:","Stelle binäre Sicherung sofort wieder her:"}. {"Restore plain text backup immediately:","Stelle Klartext-Sicherung sofort wieder her:"}. {"Restore","Wiederherstellung"}. {"Room Configuration","Raum-Konfiguration"}. {"Room creation is denied by service policy","Anlegen des Raumes aufgrund der Dienstrichtlinien verweigert"}. {"Room description","Raum Beschreibung"}. {"Room Occupants","Teilnehmer in diesem Raum"}. {"Room title","Raumname"}. {"Roster groups allowed to subscribe","Kontaktlisten-Gruppen die abonnieren dürfen"}. {"Roster","Kontaktliste"}. {"Roster of ","Kontaktliste von "}. {"Roster size","Kontaktlistengröße"}. {"RPC Call Error","Fehler bei RPC-Aufruf"}. {"Running Nodes","Aktive Knoten"}. {"~s access rule configuration","~s Zugangsregel-Konfiguration"}. {"Saturday","Samstag"}. {"Script check","Script-Überprüfung"}. {"Search Results for ","Suchergebnisse für "}. {"Search users in ","Benutzer suchen in "}. {"Send announcement to all online users on all hosts","Sende Ankündigung an alle angemeldeten Benutzer auf allen Hosts"}. {"Send announcement to all online users","Sende Ankündigung an alle angemeldeten Benutzer"}. {"Send announcement to all users on all hosts","Sende Ankündigung an alle Benutzer auf allen Hosts"}. {"Send announcement to all users","Sende Ankündigung an alle Benutzer"}. {"September","September"}. {"Server ~b","Server ~b"}. {"Server:","Server:"}. {"Set message of the day and send to online users","Setze Nachricht des Tages und sende sie an alle angemeldeten Benutzer"}. {"Set message of the day on all hosts and send to online users","Setze Nachricht des Tages auf allen Hosts und sende sie an alle angemeldeten Benutzer"}. {"Shared Roster Groups","Gruppen der gemeinsamen Kontaktliste"}. {"Show Integral Table","Vollständige Tabelle anzeigen"}. {"Show Ordinary Table","Normale Tabelle anzeigen"}. {"Shut Down Service","Dienst herunterfahren"}. {"~s invites you to the room ~s","~s lädt Sie in den Raum ~s ein"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Einige Jabber Client Programme speichern ihr Passwort auf ihrem Computer. Verwenden sie diese Möglichkeit nur auf Computern, die sie als sicher einstufen."}. {"Specify the access model","Geben sie das Zugangsmodell an"}. {"Specify the event message type","Geben sie den Ereignis-Nachrichtentyp an"}. {"Specify the publisher model","Geben sie das Publikationsmodell an"}. {"~s's Offline Messages Queue","~s's Offline-Nachrichten-Warteschlange"}. {"Start Modules at ","Starte Module auf "}. {"Start Modules","Module starten"}. {"Start","Starten"}. {"Statistics of ~p","Statistiken von ~p"}. {"Statistics","Statistik"}. {"Stop Modules at ","Stoppe Module auf "}. {"Stop Modules","Module stoppen"}. {"Stopped Nodes","Inaktive Knoten"}. {"Stop","Stoppen"}. {"Storage Type","Speichertyp"}. {"Store binary backup:","Speichere binäre Sicherung:"}. {"Store plain text backup:","Speichere Klartext-Sicherung:"}. {"Subject","Betreff"}. {"Submit","Senden"}. {"Submitted","Gesendet"}. {"Subscriber Address","Abonnenten-Adresse"}. {"Subscription","Abonnement"}. {"Sunday","Sonntag"}. {"That nickname is already in use by another occupant","Dieser Benutzername wird bereits von einem Teilnehmer genutzt"}. {"That nickname is registered by another person","Dieser Benutzername wurde bereits von jemand anderem registriert"}. {"The CAPTCHA is valid.","Die Verifizierung ist gültig."}. {"The CAPTCHA verification has failed","Die CAPTCHA Verifizierung schlug fehl"}. {"The collections with which a node is affiliated","Sammlungen, mit denen ein Knoten verknüpft ist"}. {"the password is","das Passwort lautet"}. {"The password is too weak","Das Passwort ist zu einfach"}. {"The password of your Jabber account was successfully changed.","Das Passwort von ihrem Jabber Konto wurde geändert."}. {"There was an error changing the password: ","Es trat ein Fehler beim Ändern des Passworts auf:"}. {"There was an error creating the account: ","Es trat ein Fehler beim erstellen des Kontos auf:"}. {"There was an error deleting the account: ","Es trat ein Fehler beim Löschen des Kontos auf:"}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Groß/Klein-Schreibung spielt hierbei keine Rolle: macbeth ist gleich MacBeth und Macbeth."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Diese Seite erlaubt das anlegen eines Jabber Kontos auf diesem Jabber Server. Ihre JID (Jabber IDentifier) setzt sich folgend zusammen: benutzername@server. Bitte lesen sie die Hinweise genau durch, um die Felder korrekt auszufüllen."}. {"This page allows to unregister a Jabber account in this Jabber server.","Diese Seite erlaubt es, ein Jabber Konto von diesem Server zu entfernen."}. {"This participant is kicked from the room because he sent an error message","Dieser Teilnehmer wurde aus dem Raum geworfen, da er eine fehlerhafte Nachricht gesendet hat"}. {"This participant is kicked from the room because he sent an error message to another participant","Dieser Teilnehmer wurde aus dem Raum geworfen, da er eine fehlerhafte Nachricht an einen anderen Teilnehmer gesendet hat"}. {"This participant is kicked from the room because he sent an error presence","Dieser Teilnehmer wurde aus dem Raum gekickt, da er einen fehlerhaften Status gesendet hat"}. {"This room is not anonymous","Dieser Raum ist nicht anonym"}. {"Thursday","Donnerstag"}. {"Time delay","Zeitverzögerung"}. {"Time","Zeit"}. {"To","An"}. {"Too many CAPTCHA requests","Zu viele CAPTCHA Anfragen"}. {"To ~s","An ~s"}. {"Traffic rate limit is exceeded","Datenratenlimit wurde überschritten"}. {"Transactions Aborted:","Abgebrochene Transaktionen:"}. {"Transactions Committed:","Durchgeführte Transaktionen:"}. {"Transactions Logged:","Protokollierte Transaktionen:"}. {"Transactions Restarted:","Neu gestartete Transaktionen:"}. {"Tuesday","Dienstag"}. {"Unable to generate a CAPTCHA","Konnte CAPTCHA nicht erstellen"}. {"Unauthorized","Nicht berechtigt"}. {"Unregister","Abmelden"}. {"Unregister a Jabber account","Jabber Konto entfernen"}. {"Update","Aktualisieren"}. {"Update ","Aktualisierung "}. {"Update message of the day (don't send)","Aktualisiere Nachricht des Tages (nicht senden)"}. {"Update message of the day on all hosts (don't send)","Aktualisiere Nachricht des Tages auf allen Hosts (nicht senden)"}. {"Update plan","Aktualisierungsplan"}. {"Update script","Aktualisierungsscript"}. {"Uptime:","Betriebszeit:"}. {"Use of STARTTLS required","Verwendung von STARTTLS erforderlich"}. {"User ","Benutzer "}. {"User","Benutzer"}. {"User JID","Benutzer JID"}. {"User Management","Benutzerverwaltung"}. {"Username:","Benutzername:"}. {"Users are not allowed to register accounts so quickly","Benutzer dürfen Konten nicht so schnell registrieren"}. {"Users","Benutzer"}. {"Users Last Activity","Letzte Benutzeraktivität"}. {"Validate","Validieren"}. {"vCard User Search","vCard-Benutzer-Suche"}. {"Virtual Hosts","Virtuelle Hosts"}. {"Visitors are not allowed to change their nicknames in this room","Besucher dürfen in diesem Raum ihren Benutzernamen nicht ändern"}. {"Visitors are not allowed to send messages to all occupants","Besucher dürfen nicht an alle Teilnehmer Nachrichten verschicken"}. {"Voice request","Anfrage für Sprachrechte"}. {"Voice requests are disabled in this conference","Anfragen für Sprachrechte sind in diesem Raum deaktiviert"}. {"Wednesday","Mittwoch"}. {"When to send the last published item","Wann soll das letzte veröffentlichte Objekt gesendet werden"}. {"Whether to allow subscriptions","Ob Abonnements erlaubt sind"}. {"You can later change your password using a Jabber client.","Sie können das Passwort später mit einem Jabber Client Programm ändern."}. {"You have been banned from this room","Sie wurden aus diesem Raum verbannt"}. {"You must fill in field \"Nickname\" in the form","Sie müssen das Feld \"Benutzername\" ausfüllen"}. {"You need a client that supports x:data and CAPTCHA to register","Sie benötigen einen Client, der x:data und CAPTCHA unterstützt, um Ihren Benutzernamen zu registrieren"}. {"You need a client that supports x:data to register the nickname","Sie benötigen einen Client, der x:data unterstützt, um Ihren Benutzernamen zu registrieren"}. {"You need an x:data capable client to configure mod_irc settings","Sie benötigen einen Client, der x:data unterstützt, um die mod_irc-Einstellungen zu konfigurieren"}. {"You need an x:data capable client to configure room","Sie benötigen einen Client, der x:data unterstützt, um den Raum zu konfigurieren"}. {"You need an x:data capable client to search","Sie benötigen einen Client, der x:data unterstützt, um die Suche verwenden zu können"}. {"Your active privacy list has denied the routing of this stanza.","Ihre aktive Privacy Liste hat die Weiterleitung des Stanzas unterbunden."}. {"Your contact offline message queue is full. The message has been discarded.","Ihre Offline-Nachrichten-Warteschlange ist voll. Die Nachricht wurde verworfen."}. {"Your Jabber account was successfully created.","Ihr Jabber Konto wurde erfolgreich erstellt."}. {"Your Jabber account was successfully deleted.","Ihr Jabber Konto wurde erfolgreich gelöscht."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Ihre Nachrichten an ~s werden blockiert. Um dies zu ändern, besuchen sie ~s"}. ejabberd-2.1.11/src/msgs/ejabberd.pot0000664000000000000000000012325012240230175014243 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.x\n" "X-Language: Language Name\n" "Last-Translator: Translator name and contact method\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "" #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "" #: mod_adhoc.erl:260 msgid "Pong" msgstr "" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "" #: mod_configure.erl:501 msgid "All Users" msgstr "" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "" #: mod_configure.erl:578 msgid "Backup Management" msgstr "" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "" #: mod_configure.erl:699 msgid "To ~s" msgstr "" #: mod_configure.erl:717 msgid "From ~s" msgstr "" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "" #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "" #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "" #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "" #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "" #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "" #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "" #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "" #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "" #: mod_configure.erl:1175 msgid "Access rules" msgstr "" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "" #: mod_configure.erl:1701 msgid "Last login" msgstr "" #: mod_configure.erl:1722 msgid "Roster size" msgstr "" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "" #: mod_configure.erl:1724 msgid "Resources" msgstr "" #: mod_configure.erl:1850 msgid "Administration of " msgstr "" #: mod_configure.erl:1853 msgid "Action on user" msgstr "" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "" #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "" #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr "" #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "" #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "" #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "" #: mod_offline.erl:571 msgid "Time" msgstr "" #: mod_offline.erl:572 msgid "From" msgstr "" #: mod_offline.erl:573 msgid "To" msgstr "" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "" #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "" #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "" #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "" #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "" #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "" #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "" #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "" #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "" #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "" #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "" #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "" #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "" #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "" #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "" #: web/mod_register_web.erl:250 msgid "Register" msgstr "" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "" ejabberd-2.1.11/src/msgs/ca.msg0000664000000000000000000006710412240230175013061 0ustar {"Access Configuration","Configuració d'accesos"}. {"Access Control List Configuration","Configuració de la Llista de Control d'Accés"}. {"Access Control Lists","Llista de Control d'Accés"}. {"Access control lists","Llistes de Control de Accés"}. {"Access denied by service policy","Accés denegat per la política del servei"}. {"Access rules","Regles d'accés"}. {"Access Rules","Regles d'Accés"}. {"Action on user","Acció en l'usuari"}. {"Add Jabber ID","Afegir Jabber ID"}. {"Add New","Afegir nou"}. {"Add User","Afegir usuari"}. {"Administration","Administració"}. {"Administration of ","Administració de "}. {"Administrator privileges required","Es necessita tenir privilegis d'administrador"}. {"A friendly name for the node","Un nom per al node"}. {"All activity","Tota l'activitat"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Permetre que aquesta Jabber ID es puga subscriure a aquest node pubsub"}. {"Allow users to change the subject","Permetre que els usuaris canviin el tema"}. {"Allow users to query other users","Permetre que els usuaris fagen peticions a altres usuaris"}. {"Allow users to send invites","Permetre que els usuaris envien invitacions"}. {"Allow users to send private messages","Permetre que els usuaris envien missatges privats"}. {"Allow visitors to change nickname","Permetre als visitants canviar el Nickname"}. {"Allow visitors to send private messages to","Permetre als visitants enviar missatges privats a"}. {"Allow visitors to send status text in presence updates","Permetre als visitants enviar text d'estat en les actualitzacions de presència"}. {"Allow visitors to send voice requests","Permetre als visitants enviar peticions de veu"}. {"All Users","Tots els usuaris"}. {"Announcements","Anuncis"}. {"anyone","qualsevol"}. {"A password is required to enter this room","Es necessita contrasenya per a entrar en aquesta sala"}. {"April","Abril"}. {"August","Agost"}. {"Backup","Guardar còpia de seguretat"}. {"Backup Management","Gestió de còpia de seguretat"}. {"Backup of ","Còpia de seguretat de "}. {"Backup to File at ","Desar còpia de seguretat a fitxer en "}. {"Bad format","Format erroni"}. {"Birthday","Aniversari"}. {"CAPTCHA web page","Pàgina web del CAPTCHA"}. {"Change Password","Canviar Contrasenya"}. {"Change User Password","Canviar Contrasenya d'Usuari"}. {"Characters not allowed:","Caràcters no permesos:"}. {"Chatroom configuration modified","Configuració de la sala de xat modificada"}. {"Chatroom is created","La sala s'ha creat"}. {"Chatroom is destroyed","La sala s'ha destruït"}. {"Chatroom is started","La sala s'ha iniciat"}. {"Chatroom is stopped","La sala s'ha aturat"}. {"Chatrooms","Sales de xat"}. {"Choose a username and password to register with this server","Tria nom d'usuari i contrasenya per a registrar-te en aquest servidor"}. {"Choose modules to stop","Selecciona mòduls a detindre"}. {"Choose storage type of tables","Selecciona el tipus d'almacenament de les taules"}. {"Choose whether to approve this entity's subscription.","Tria si aprova aquesta entitat de subscripció"}. {"City","Ciutat"}. {"Commands","Comandaments"}. {"Conference room does not exist","La sala de conferències no existeix"}. {"Configuration","Configuració"}. {"Configuration of room ~s","Configuració de la sala ~s"}. {"Connected Resources:","Recursos connectats:"}. {"Connections parameters","Paràmetres de connexió"}. {"Country","Pais"}. {"CPU Time:","Temps de CPU"}. {"Database","Base de dades"}. {"Database Tables at ","Taules de la base de dades en "}. {"Database Tables Configuration at ","Configuració de la base de dades en "}. {"December","Decembre"}. {"Default users as participants","Els usuaris són participants per defecte"}. {"Delete","Eliminar"}. {"Delete message of the day","Eliminar el missatge del dia"}. {"Delete message of the day on all hosts","Elimina el missatge del dis de tots els hosts"}. {"Delete Selected","Eliminar els seleccionats"}. {"Delete User","Eliminar Usuari"}. {"Deliver event notifications","Entrega de notificacions d'events"}. {"Deliver payloads with event notifications","Enviar payloads junt a les notificacions d'events"}. {"Description:","Descripció:"}. {"Disc only copy","Còpia sols en disc"}. {"Displayed Groups:","Mostrar grups:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","No li donis la teva contrasenya a ningú, ni tan sols als administradors del servidor Jabber."}. {"Dump Backup to Text File at ","Exporta còpia de seguretat a fitxer de text en "}. {"Dump to Text File","Exportar a fitxer de text"}. {"Edit Properties","Editar propietats"}. {"Either approve or decline the voice request.","Aprova o denega la petició de veu"}. {"ejabberd IRC module","mòdul ejabberd IRC"}. {"ejabberd MUC module","mòdul ejabberd MUC"}. {"ejabberd Publish-Subscribe module","Mòdul ejabberd Publicar-Subscriure"}. {"ejabberd SOCKS5 Bytestreams module","mòdul ejabberd SOCKS5 Bytestreams"}. {"ejabberd vCard module","Mòdul ejabberd vCard"}. {"ejabberd Web Admin","Web d'administració del ejabberd"}. {"Elements","Elements"}. {"Email","Email"}. {"Enable logging","Habilitar el registre de la conversa"}. {"Encoding for server ~b","Codificació pel servidor ~b"}. {"End User Session","Finalitzar Sesió d'Usuari"}. {"Enter list of {Module, [Options]}","Introdueix llista de {mòdul, [opcions]}"}. {"Enter nickname you want to register","Introdueix el nickname que vols registrar"}. {"Enter path to backup file","Introdueix ruta al fitxer de còpia de seguretat"}. {"Enter path to jabberd14 spool dir","Introdueix la ruta al directori de jabberd14 spools"}. {"Enter path to jabberd14 spool file","Introdueix ruta al fitxer jabberd14 spool"}. {"Enter path to text file","Introdueix ruta al fitxer de text"}. {"Enter the text you see","Introdueix el text que veus"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Introdueix el nom d'usuari i les codificacions de caràcters per a utilitzar als servidors de IRC. Apreta \"Seguent\" per veure més caps per omplir. Apreta \"Completar\" per guardar la configuració. "}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Introdueix el nom d'usuari, les codificacions de caràcters, els ports i contrasenyes per a utilitzar al connectar als servidors de IRC"}. {"Erlang Jabber Server","Servidor Erlang Jabber"}. {"Error","Error"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Exemple: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Excloure Jabber IDs de la comprovació CAPTCHA"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exportar dades de tots els usuaris del servidor a arxius PIEFXIS (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Exportar dades d'usuaris d'un host a arxius PIEFXIS (XEP-0227):"}. {"Failed to extract JID from your voice request approval","No s'ha pogut extraure el JID de la teva aprovació de petició de veu"}. {"Family Name","Cognom"}. {"February","Febrer"}. {"Fill in fields to search for any matching Jabber User","Emplena camps per a buscar usuaris Jabber que concorden"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Emplena el formulari per a buscar usuaris Jabber. Afegix * al final d'un camp per a buscar subcadenes."}. {"Friday","Divendres"}. {"From","De"}. {"From ~s","De ~s"}. {"Full Name","Nom complet"}. {"Get Number of Online Users","Obtenir Número d'Usuaris Connectats"}. {"Get Number of Registered Users","Obtenir Número d'Usuaris Registrats"}. {"Get User Last Login Time","Obtenir la última connexió d'Usuari"}. {"Get User Password","Obtenir Contrasenya d'usuari"}. {"Get User Statistics","Obtenir Estadístiques d'Usuari"}. {"Grant voice to this person?","Concedir veu a aquesta persona?"}. {"Group ","Grup "}. {"Groups","Grups"}. {"has been banned","Has sigut banejat"}. {"has been kicked because of an affiliation change","Has sigut expulsat a causa d'un canvi d'afiliació"}. {"has been kicked because of a system shutdown","Has sigut expulsat perquè el sistema s'ha apagat"}. {"has been kicked because the room has been changed to members-only","Has sigut expulsat perquè la sala ha canviat a sols membres"}. {"has been kicked","Has sigut expulsat"}. {" has set the subject to: "," ha posat l'assumpte: "}. {"Host","Host"}. {"If you don't see the CAPTCHA image here, visit the web page.","Si no veus la imatge CAPTCHA açí, visita la pàgina web."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Si vols especificar codificacions de caràcters diferents per a cada servidor IRC emplena aquesta llista amb els valors amb el format '{\"servidor irc\", \"codificació\", port, \"contrasenya\"}'. Aquest servei utilitza per defecte la codificació \"~s\", port ~p, no contrasenya."}. {"Import Directory","Importar directori"}. {"Import File","Importar fitxer"}. {"Import user data from jabberd14 spool file:","Importar dades d'usuaris de l'arxiu de spool de jabberd14"}. {"Import User from File at ","Importa usuari des de fitxer en "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importar dades d'usuaris des d'un arxiu PIEFXIS (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Importar dades d'usuaris del directori de spool de jabberd14:"}. {"Import Users from Dir at ","Importar usuaris des del directori en "}. {"Import Users From jabberd14 Spool Files","Importar usuaris de jabberd14"}. {"Improper message type","Tipus de missatge incorrecte"}. {"Incorrect password","Contrasenya incorrecta"}. {"Invalid affiliation: ~s","Afiliació invàlida: ~s"}. {"Invalid role: ~s","Rol invàlid: ~s"}. {"IP addresses","Adreça IP"}. {"IP","IP"}. {"IRC channel (don't put the first #)","Canal d'IRC (no posis la primera #)"}. {"IRC server","Servidor d'IRC"}. {"IRC settings","Configuració d'IRC."}. {"IRC Transport","Transport a IRC"}. {"IRC username","Nom d'usuari al IRC"}. {"IRC Username","Nom d'usuari al IRC"}. {"is now known as","ara es conegut com"}. {"It is not allowed to send private messages","No està permés enviar missatges privats"}. {"It is not allowed to send private messages of type \"groupchat\"","No està permés enviar missatges del tipus \"groupchat\""}. {"It is not allowed to send private messages to the conference","No està permès l'enviament de missatges privats a la sala"}. {"Jabber Account Registration","Registre de compte Jabber"}. {"Jabber ID","ID Jabber"}. {"Jabber ID ~s is invalid","El Jabber ID ~s no és vàlid"}. {"January","Gener"}. {"Join IRC channel","Entra a canal d'IRC"}. {"joins the room","Entrar a la sala"}. {"Join the IRC channel here.","Entra al canal d'IRC aquí."}. {"Join the IRC channel in this Jabber ID: ~s","Entra al canal d'IRC en aquesta Jabber ID: ~s"}. {"July","Juliol"}. {"June","Juny"}. {"Last Activity","Última activitat"}. {"Last login","Últim login"}. {"Last month","Últim mes"}. {"Last year","Últim any"}. {"leaves the room","Deixar la sala"}. {"Listened Ports at ","Ports a la escolta en "}. {"Listened Ports","Ports a l'escolta"}. {"List of modules to start","Llista de mòduls a iniciar"}. {"Low level update script","Script d'actualització de baix nivell"}. {"Make participants list public","Crear una llista de participants pública"}. {"Make room CAPTCHA protected","Crear una sala protegida per CAPTCHA"}. {"Make room members-only","Crear una sala de \"només membres\""}. {"Make room moderated","Crear una sala moderada"}. {"Make room password protected","Crear una sala amb contrasenya"}. {"Make room persistent","Crear una sala persistent"}. {"Make room public searchable","Crear una sala pública"}. {"March","Març"}. {"Maximum Number of Occupants","Número màxim d'ocupants"}. {"Max # of items to persist","Màxim # d'elements que persistixen"}. {"Max payload size in bytes","Màxim tamany del payload en bytes"}. {"May","Maig"}. {"Membership is required to enter this room","Necessites ser membre d'aquesta sala per a poder entrar"}. {"Members:","Membre:"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Memoritza la teva contrasenya, o escriu-la en un paper guardat a un lloc segur.A Jabber no hi ha una forma automatitzada de recuperar la teva contrasenya si la oblides."}. {"Memory","Memòria"}. {"Message body","Missatge"}. {"Middle Name","Segon nom"}. {"Minimum interval between voice requests (in seconds)","Interval mínim entre peticions de veu (en segons)"}. {"Moderator privileges required","Es necessita tenir privilegis de moderador"}. {"moderators only","només moderadors"}. {"Modified modules","Mòduls modificats"}. {"Module","Mòdul"}. {"Modules at ","Mòduls en "}. {"Modules","Mòduls"}. {"Monday","Dilluns"}. {"Name:","Nom:"}. {"Name","Nom"}. {"Never","Mai"}. {"New Password:","Nova Contrasenya:"}. {"Nickname","Nickname"}. {"Nickname Registration at ","Registre del Nickname en "}. {"Nickname ~s does not exist in the room","El Nickname ~s no existeix a la sala"}. {"nobody","ningú"}. {"No body provided for announce message","No hi ha proveedor per al missatge anunci"}. {"No Data","No hi ha dades"}. {"Node ID","ID del Node"}. {"Node ","Node "}. {"Node not found","Node no trobat"}. {"Nodes","Nodes"}. {"No limit","Sense Llímit"}. {"None","Cap"}. {"No resource provided","Recurs no disponible"}. {"Not Found","No Trobat"}. {"Notify subscribers when items are removed from the node","Notificar subscriptors quan els elements són eliminats del node"}. {"Notify subscribers when the node configuration changes","Notificar subscriptors quan canvia la configuració del node"}. {"Notify subscribers when the node is deleted","Notificar subscriptors quan el node és eliminat"}. {"November","Novembre"}. {"Number of occupants","Número d'ocupants"}. {"Number of online users","Número d'usuaris connectats"}. {"Number of registered users","Número d'Usuaris Registrats"}. {"October","Octubre"}. {"Offline Messages:","Missatges fora de línia:"}. {"Offline Messages","Missatges offline"}. {"OK","Acceptar"}. {"Old Password:","Antiga contrasenya:"}. {"Online","Connectat"}. {"Online Users","Usuaris conectats"}. {"Online Users:","Usuaris en línia:"}. {"Only deliver notifications to available users","Sols enviar notificacions als usuaris disponibles"}. {"Only moderators and participants are allowed to change the subject in this room","Només els moderadors i participants poden canviar l'assumpte d'aquesta sala"}. {"Only moderators are allowed to change the subject in this room","Només els moderadors poden canviar l'assumpte d'aquesta sala"}. {"Only moderators can approve voice requests","Només els moderadors poden aprovar les peticions de veu"}. {"Only occupants are allowed to send messages to the conference","Sols els ocupants poden enviar missatges a la sala"}. {"Only occupants are allowed to send queries to the conference","Sols els ocupants poden enviar sol·licituds a la sala"}. {"Only service administrators are allowed to send service messages","Sols els administradors del servei tenen permís per a enviar missatges de servei"}. {"Options","Opcions"}. {"Organization Name","Nom de la organizació"}. {"Organization Unit","Unitat de la organizació"}. {"Outgoing s2s Connections:","Connexions d'eixida s2s"}. {"Outgoing s2s Connections","Connexions s2s d'eixida"}. {"Outgoing s2s Servers:","Servidors d'eixida de s2s"}. {"Owner privileges required","Es requerixen privilegis de propietari de la sala"}. {"Packet","Paquet"}. {"Password ~b","Contrasenya ~b"}. {"Password:","Contrasenya:"}. {"Password","Contrasenya"}. {"Password Verification:","Verificació de la Contrasenya:"}. {"Password Verification","Verificació de la Contrasenya"}. {"Path to Dir","Ruta al directori"}. {"Path to File","Ruta al fitxer"}. {"Pending","Pendent"}. {"Period: ","Període: "}. {"Persist items to storage","Persistir elements al guardar"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Recorda que aquestes opcions només fan còpia de seguretat de la base de dades Mnesia. Si estàs utilitzant el mòdul d'ODBC també deus de fer una còpia de seguretat de la base de dades de SQL a part."}. {"Please, wait for a while before sending new voice request","Si us plau, espera una mica abans d'enviar una nova petició de veu"}. {"Pong","Pong"}. {"Port ~b","Port ~b"}. {"Port","Port"}. {"Present real Jabber IDs to","Presentar Jabber ID's reals a"}. {"private, ","privat"}. {"Protocol","Protocol"}. {"Publish-Subscribe","Publicar-subscriure't"}. {"PubSub subscriber request","Petició de subscriptor PubSub"}. {"Purge all items when the relevant publisher goes offline","Eliminar tots els elements quan el publicant relevant es desconnecti"}. {"Queries to the conference members are not allowed in this room"," En aquesta sala no es permeten sol·licituds als membres de la conferència"}. {"RAM and disc copy","Còpia en RAM i disc"}. {"RAM copy","Còpia en RAM"}. {"Raw","en format text"}. {"Really delete message of the day?","Segur que vols eliminar el missatge del dia?"}. {"Recipient is not in the conference room","El receptor no està en la sala de conferència"}. {"Register a Jabber account","Registrar un compte Jabber"}. {"Registered Users:","Usuaris registrats:"}. {"Registered Users","Usuaris registrats"}. {"Register","Registrar"}. {"Registration in mod_irc for ","Registre en mod_irc per a"}. {"Remote copy","Còpia remota"}. {"Remove All Offline Messages","Eliminar tots els missatges offline"}. {"Remove","Borrar"}. {"Remove User","Eliminar usuari"}. {"Replaced by new connection","Reemplaçat per una nova connexió"}. {"Resources","Recursos"}. {"Restart","Reiniciar"}. {"Restart Service","Reiniciar el Servei"}. {"Restore Backup from File at ","Restaura còpia de seguretat des del fitxer en "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Restaurar una còpia de seguretat binària després de reiniciar el ejabberd (requereix menys memòria:"}. {"Restore binary backup immediately:","Restaurar una còpia de seguretat binària ara mateix."}. {"Restore plain text backup immediately:","Restaurar una còpia de seguretat en format de text pla ara mateix:"}. {"Restore","Restaurar"}. {"Room Configuration","Configuració de la sala"}. {"Room creation is denied by service policy","Se t'ha denegat el crear la sala per política del servei"}. {"Room description","Descripció de la sala:"}. {"Room Occupants","Nombre d'ocupants"}. {"Room title","Títol de la sala"}. {"Roster groups allowed to subscribe","Llista de grups que tenen permés subscriures"}. {"Roster","Llista de contactes"}. {"Roster of ","Llista de contactes de "}. {"Roster size","Tamany de la llista"}. {"RPC Call Error","Error de cridada RPC"}. {"Running Nodes","Nodes funcionant"}. {"~s access rule configuration","Configuració de les Regles d'Accés ~s"}. {"Saturday","Dissabte"}. {"Script check","Comprovar script"}. {"Search Results for ","Resultat de la búsqueda"}. {"Search users in ","Cerca usuaris en "}. {"Send announcement to all online users","Enviar anunci a tots els usuaris connectats"}. {"Send announcement to all online users on all hosts","Enviar anunci a tots els usuaris connectats a tots els hosts"}. {"Send announcement to all users","Enviar anunci a tots els usuaris"}. {"Send announcement to all users on all hosts","Enviar anunci a tots els usuaris de tots els hosts"}. {"September","Setembre"}. {"Server ~b","Servidor ~b"}. {"Server:","Servidor:"}. {"Set message of the day and send to online users","Configurar el missatge del dia i enviar a tots els usuaris"}. {"Set message of the day on all hosts and send to online users","Escriure missatge del dia en tots els hosts i enviar-ho als usuaris connectats"}. {"Shared Roster Groups","Grups de contactes compartits"}. {"Show Integral Table","Mostrar Taula Integral"}. {"Show Ordinary Table","Mostrar Taula Ordinaria"}. {"Shut Down Service","Apager el Servei"}. {"~s invites you to the room ~s","~s et convida a la sala ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Alguns clients Jabber poden emmagatzemar la teva contrasenya al teu ordinador. Fes servir aquesta característica només si saps que el teu ordinador és segur."}. {"Specify the access model","Especificar el model d'accés"}. {"Specify the event message type","Especifica el tipus de missatge d'event"}. {"Specify the publisher model","Especificar el model del publicant"}. {"~s's Offline Messages Queue","~s's cua de missatges offline"}. {"Start","Iniciar"}. {"Start Modules at ","Iniciar mòduls en "}. {"Start Modules","Iniciar mòduls"}. {"Statistics","Estadístiques"}. {"Statistics of ~p","Estadístiques de ~p"}. {"Stop","Detindre"}. {"Stop Modules at ","Detindre mòduls en "}. {"Stop Modules","Parar mòduls"}. {"Stopped Nodes","Nodes parats"}. {"Storage Type","Tipus d'emmagatzematge"}. {"Store binary backup:","Guardar una còpia de seguretat binària:"}. {"Store plain text backup:","Guardar una còpia de seguretat en format de text pla:"}. {"Subject","Assumpte"}. {"Submit","Enviar"}. {"Submitted","Enviat"}. {"Subscriber Address","Adreça del Subscriptor"}. {"Subscription","Subscripció"}. {"Sunday","Diumenge"}. {"That nickname is already in use by another occupant","El Nickname està siguent utilitzat per una altra persona"}. {"That nickname is registered by another person","El nickname ja està registrat per una altra persona"}. {"The CAPTCHA is valid.","El CAPTCHA es vàlid."}. {"The CAPTCHA verification has failed","La verificació CAPTCHA ha fallat"}. {"The collections with which a node is affiliated","Les col.leccions amb les que un node està afiliat"}. {"the password is","la contrasenya és"}. {"The password is too weak","La contrasenya és massa simple"}. {"The password of your Jabber account was successfully changed.","La contrasenya del teu compte Jabber s'ha canviat correctament."}. {"There was an error changing the password: ","Hi ha hagut un error canviant la contrasenya: "}. {"There was an error creating the account: ","Hi ha hagut un error creant el compte: "}. {"There was an error deleting the account: ","Hi ha hagut un error esborrant el compte: "}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Això no distingeix majúscules de minúscules: macbeth es el mateix que MacBeth i Macbeth."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Aquesta pàgina permet crear un compte Jabber en aquest servidor Jabber. El teu JID (Jabber IDentifier; Identificador Jabber) tindrà aquesta forma: usuari@servidor. Si us plau, llegeix amb cura les instruccions per emplenar correctament els camps."}. {"This page allows to unregister a Jabber account in this Jabber server.","Aquesta pàgina permet anul·lar el registre d'un compte Jabber en aquest servidor Jabber."}. {"This participant is kicked from the room because he sent an error message","Aquest participant ha sigut expulsat de la sala perque ha enviat un missatge d'error"}. {"This participant is kicked from the room because he sent an error message to another participant","Aquest participant ha sigut expulsat de la sala perque ha enviat un missatge erroni a un altre participant"}. {"This participant is kicked from the room because he sent an error presence","Aquest participant ha sigut expulsat de la sala perque ha enviat un error de presencia"}. {"This room is not anonymous","Aquesta sala no és anònima"}. {"Thursday","Dijous"}. {"Time","Data"}. {"Time delay","Temps de retard"}. {"Too many CAPTCHA requests","Massa peticions de CAPTCHA"}. {"To","Per a"}. {"To ~s","A ~s"}. {"Traffic rate limit is exceeded","El llímit de tràfic ha sigut sobrepassat"}. {"Transactions Aborted:","Transaccions Avortades"}. {"Transactions Committed:","Transaccions Realitzades:"}. {"Transactions Logged:","Transaccions registrades"}. {"Transactions Restarted:","Transaccions reiniciades"}. {"Tuesday","Dimarts"}. {"Unable to generate a CAPTCHA","No s'ha pogut generar un CAPTCHA"}. {"Unauthorized","No autoritzat"}. {"Unregister a Jabber account","Anul·lar el registre d'un compte Jabber"}. {"Unregister","Anul·lar el registre"}. {"Update ","Actualitzar"}. {"Update","Actualitzar"}. {"Update message of the day (don't send)","Actualitzar el missatge del dia (no enviar)"}. {"Update message of the day on all hosts (don't send)","Actualitza el missatge del dia en tots els hosts (no enviar)"}. {"Update plan","Pla d'actualització"}. {"Update script","Script d'actualització"}. {"Uptime:","Temps en marxa"}. {"Use of STARTTLS required","És obligatori utilitzar STARTTLS"}. {"User JID","JID del usuari "}. {"User Management","Gestió d'Usuaris"}. {"Username:","Nom d'usuari:"}. {"Users are not allowed to register accounts so quickly","Els usuaris no tenen permís per a crear comptes tan depresa"}. {"Users Last Activity","Última activitat d'usuari"}. {"Users","Usuaris"}. {"User ","Usuari "}. {"User","Usuari"}. {"Validate","Validar"}. {"vCard User Search","Recerca de vCard d'usuari"}. {"Virtual Hosts","Hosts virtuals"}. {"Visitors are not allowed to change their nicknames in this room","Els visitants no tenen permés canviar el seus Nicknames en esta sala"}. {"Visitors are not allowed to send messages to all occupants","Els visitants no poden enviar missatges a tots els ocupants"}. {"Voice request","Petició de veu"}. {"Voice requests are disabled in this conference","Les peticions de veu es troben desactivades en aquesta conferència"}. {"Wednesday","Dimecres"}. {"When to send the last published item","Quan s'ha enviat l'última publicació"}. {"Whether to allow subscriptions","Permetre subscripcions"}. {"You can later change your password using a Jabber client.","Podràs canviar la teva contrasenya més endavant utilitzant un client Jabber."}. {"You have been banned from this room","Has sigut bloquejat en aquesta sala"}. {"You must fill in field \"Nickname\" in the form","Deus d'omplir el camp \"Nickname\" al formulari"}. {"You need a client that supports x:data and CAPTCHA to register","Necessites un client amb suport x:data i de CAPTCHA para poder registrar-te"}. {"You need a client that supports x:data to register the nickname","Necessites un client amb suport x:data per a poder registrar el Nickname"}. {"You need an x:data capable client to configure mod_irc settings","Necessites un client amb suport x:data per a configurar les opcions de mod_irc"}. {"You need an x:data capable client to configure room","Necessites un client amb suport x:data per a configurar la sala"}. {"You need an x:data capable client to search","Necessites un client amb suport x:data per a poder buscar"}. {"Your active privacy list has denied the routing of this stanza.","La teva llista de privacitat activa ha denegat l'encaminament d'aquesta stanza."}. {"Your contact offline message queue is full. The message has been discarded.","La cua de missatges offline és plena. El missatge ha sigut descartat"}. {"Your Jabber account was successfully created.","El teu compte Jabber ha sigut creat correctament."}. {"Your Jabber account was successfully deleted.","El teu compte Jabber ha sigut esborrat correctament."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Els teus missatges per ~s s'estan bloquejant. Per desbloquejar-los, visita ~s"}. ejabberd-2.1.11/src/msgs/uk.po0000664000000000000000000020004612240230175012737 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" "Last-Translator: Konstantin Khomoutov \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Ukrainian (українська)\n" "X-Additional-Translator: Ruslan Rakhmanin\n" "X-Additional-Translator: Stoune\n" "X-Additional-Translator: Sergei Golovan\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Ви мусите використовувати STARTTLS" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Не вказаний ресурс" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Замінено новим з'єднанням" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "Маршрутизація цієї строфи була відмінена активним списком приватності." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Введіть текст, що ви бачите" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "Ваші повідомлення до ~s блокуються. Для розблокування відвідайте ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "Якщо ви не бачите зображення капчі, перейдіть за за цією адресою." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "Адреса капчі" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "Перевірку капчею закінчено успішно" #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Команди" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Пінг" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Понг" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Насправді видалити повідомлення дня?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Тема" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Тіло повідомлення" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Тіло оголошення має бути непустим" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Сповіщення" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Надіслати сповіщення всім користувачам" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Надіслати сповіщення до усіх користувачів на усіх хостах" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Надіслати сповіщення всім підключеним користувачам" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "" "Надіслати сповіщення всім підключеним користувачам на всіх віртуальних " "серверах" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Встановити повідомлення дня та надіслати його підключеним користувачам" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Встановити повідомлення дня на всіх хостах та надійслати його підключеним " "користувачам" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Оновити повідомлення дня (не надсилати)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Оновити повідомлення дня на всіх хостах (не надсилати)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Видалити повідомлення дня" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Видалити повідомлення дня на усіх хостах" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Конфігурація" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "База даних" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Запуск модулів" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Зупинка модулів" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Резервне копіювання" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Відновлення з резервної копії" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Копіювання в текстовий файл" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Імпорт з файла" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Імпорт з директорії" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Перезапустити Сервіс" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Вимкнути Сервіс" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Додати користувача" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Видалити Користувача" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Закінчити Сеанс Користувача" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Отримати Пароль Користувача" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Змінити Пароль Користувача" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Отримати Час Останнього Підключення Користувача" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Отримати Статистику по Користувачу" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Отримати Кількість Зареєстрованих Користувачів" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Отримати Кількість Підключених Користувачів" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Списки керування доступом" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Правила доступу" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Управління Користувачами" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Підключені користувачі" #: mod_configure.erl:501 msgid "All Users" msgstr "Всі користувачі" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Вихідні s2s-з'єднання" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Працюючі вузли" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Зупинені вузли" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Модулі" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Керування резервним копіюванням" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Імпорт користувачів зі спулу jabberd14" #: mod_configure.erl:699 msgid "To ~s" msgstr "До ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Від ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Конфігурація таблиць бази даних на " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Оберіть тип збереження таблиць" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Тільки диск" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "ОЗП та диск" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "ОЗП" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "не зберігаеться локально" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Зупинка модулів на " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Виберіть модулі, які необхідно зупинити" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Запуск модулів на " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Введіть перелік такого виду {Module, [Options]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Список завантажуваних модулів" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Резервне копіювання в файл на " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Введіть шлях до резервного файла" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Шлях до файла" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Відновлення з резервної копії на " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Копіювання в текстовий файл на " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Введіть шлях до текстового файла" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Імпортування користувача з файла на " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Введіть шлях до файла зі спула jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Імпортування користувача з директорії на " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Введіть шлях до директорії спула jabberd14" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Шлях до директорії" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Час затримки" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Конфігурація списків керування доступом" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Списки керування доступом" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Конфігурація доступу" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Правила доступу" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Пароль" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Перевірка Пароля" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Кількість зареєстрованих користувачів" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Кількість підключених користувачів" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Ніколи" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Підключений" #: mod_configure.erl:1701 msgid "Last login" msgstr "Останнє підключення" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Кількість контактів" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "IP адреси" #: mod_configure.erl:1724 msgid "Resources" msgstr "Ресурси" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Адміністрування " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Дія над користувачем" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Змінити параметри" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Видалити користувача" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Доступ заборонений політикою служби" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC Транспорт" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC модуль" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "Для налагодження параметрів mod_irc необхідно використовувати клієнт, що має " "підтримку x:data" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Реєстрація в mod_irc для " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Введіть ім'я користувача, кодування, порти та паролі, що будуть " "використовуватися при підключенні до IRC-серверів" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Ім'я користувача IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Щоб вказати різні порти, паролі та кодування для різних серверів IRC, " "заповніть список значеннями в форматі '{\"irc server\", \"encoding\", port, " "\"password\"}'. За замовчуванням ця служба використовує \"~s\" кодування, " "порт ~p, пустий пароль." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Приклад: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta." "fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Параметри з'єднання" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Приєднатися до каналу IRC" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "Канал IRC (не включаючи #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "IRC-сервер" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Приєднатися до каналу IRC" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Приєднатися до каналу IRC з Jabber ID: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "Парметри IRC" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Введіть ім'я користувача та кодування, які будуть використовуватися при " "підключенні до IRC-серверів Натисніть 'Далі' для заповнення додаткових " "полів. Натисніть 'Завершити' для збереження параметрів." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "Ім'я користувача IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Пароль ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Порт ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Кодування для сервера ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Сервер ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "Тільки адміністратор сервісу може надсилати службові повідомлення" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Створювати конференцію заборонено політикою служби" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Конференція не існує" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Кімнати" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "" "Для реєстрації псевдоніму необхідно використовувати клієнт з підтримкою x:" "data" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Реєстрація псевдоніма на " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Введіть псевдонім, який ви хочете зареєструвати" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Псевдонім" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Псевдонім зареєстровано кимось іншим" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Вам необхідно заповнити поле \"Псевдонім\" у формі" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC модуль" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Конфігурація кімнати змінилась" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "увійшов(ла) в кімнату" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "вийшов(ла) з кімнати" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "заборонили вхід в кімнату" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "вигнали з кімнати" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "вигнано з кімнати внаслідок зміни рангу" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "вигнано з кімнати тому, що вона стала тільки для учасників" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "вигнано з кімнати внаслідок зупинки системи" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "змінив(ла) псевдонім на" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " встановив(ла) тему: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Створено кімнату" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Знищено кімнату" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Запущено кімнату" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Зупинено кімнату" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Понеділок" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Вівторок" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Середа" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Четвер" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "П'ятниця" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Субота" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Неділя" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "січня" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "лютого" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "березня" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "квітня" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "травня" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "червня" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "липня" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "серпня" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "вересня" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "грудня" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "листопада" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "грудня" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Конфігурація кімнати" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Учасники кімнати" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Швидкість передачі інформації було перевищено" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Цього учасника було відключено від кімнати через те, що він надіслав " "помилкове повідомлення" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Не дозволяється надсилати приватні повідомлення в конференцію" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Неправильний тип повідомлення" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Цього учасника було відключено від кімнати через те, що він надіслав " "помилкове повідомлення іншому учаснику" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "Не дозволяється надсилати приватні повідомлення типу \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Адресата немає в конференції" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Приватні повідомлення не дозволені" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Тільки присутнім дозволяється надсилати повідомленняя в конференцію" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Тільки присутнім дозволяється відправляти запити в конференцію" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "Запити до користувачів в цій конференції заборонені" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "Тільки модератори та учасники можуть змінювати тему в цій кімнаті" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Тільки модератори можуть змінювати тему в цій кімнаті" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Відвідувачам не дозволяється надсилати повідомлення всім присутнім" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Цього учасника було відключено від кімнати через те, що він надіслав " "помилковий статус присутності" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Відвідувачам не дозволяється змінювати псевдонім в цій кімнаті" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Псевдонім зайнято кимось з присутніх" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Вам заборонено входити в цю конференцію" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "В цю конференцію можуть входити тільки її члени" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Ця кімната не анонімна" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Щоб зайти в цю конференцію, необхідно ввести пароль" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Надто багато CAPTCHA-запитів" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Нема можливості згенерувати капчу" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Неправильний пароль" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Необхідні права адміністратора" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Необхідні права модератора" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Jabber ID ~s недопустимий" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Псевдонім ~s в кімнаті відсутній" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Недопустимий ранг: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Недопустима роль: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Необхідні права власника" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Конфігурація кімнати ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Назва кімнати" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Опис кімнати" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Зробити кімнату постійною" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Зробити кімнату видимою всім" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Зробити список учасників видимим всім" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Зробити кімнату захищеною паролем" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Максимальна кількість учасників" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Без обмежень" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Зробити реальні Jabber ID учасників видимими" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "тільки модераторам" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "всім учасникам" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Кімната тільки для зареєтрованых учасників" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Зробити кімнату модерованою" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Зробити користувачів учасниками за замовчуванням" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Дозволити користувачам змінювати тему" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Дозволити приватні повідомлення" #: mod_muc/mod_muc_room.erl:3279 #, fuzzy msgid "Allow visitors to send private messages to" msgstr "Дозволити приватні повідомлення" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Дозволити iq-запити до користувачів" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Дозволити користувачам надсилати запрошення" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "" "Дозволити відвідувачам відсилати текст статусу в оновленнях присутності" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Дозволити відвідувачам змінювати псевдонім" #: mod_muc/mod_muc_room.erl:3308 #, fuzzy msgid "Allow visitors to send voice requests" msgstr "Дозволити користувачам надсилати запрошення" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Зробити кімнату захищеною капчею" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Пропускати ці Jabber ID без CAPTCHA-запиту" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Включити журнал роботи" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "" "Для конфігурування кімнати потрібно використовувати клієнт з підтримкою x:" "data" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Кількість присутніх" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "приватна, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "" #: mod_muc/mod_muc_room.erl:3809 #, fuzzy msgid "User JID" msgstr "Користувач " #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s запрошує вас до кімнати ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "пароль:" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "Черга повідомлень, що не були доставлені, переповнена. Повідомлення не було " "збережено." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "Черга офлайнових повідомлень ~s" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Відправлено" #: mod_offline.erl:571 msgid "Time" msgstr "Час" #: mod_offline.erl:572 msgid "From" msgstr "Від кого" #: mod_offline.erl:573 msgid "To" msgstr "Кому" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Пакет" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Видалити виділені" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Офлайнові повідомлення:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Видалити всі офлайнові повідомлення" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestreams модуль" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Публікація-Підписка" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "Модуль ejabberd Публікації-Підписки" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Запит на підписку PubSub" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Вирішіть, чи задовольнити запит цього об'єкту на підписку" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ID вузла" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Адреса абонента" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Чи дозволити цьому Jabber ID підписатись новини наданого вузла" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Доставляти разом з повідомленнями про публікації самі публікації" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Доставляти сповіщення про події" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Повідомляти абонентів про зміни в конфігурації збірника" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Повідомляти абонентів про видалення збірника" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Повідомляти абонентів про видалення публікацій із збірника" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Зберегати публікації до сховища" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Псевдонім для вузла" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Максимальне число збережених публікацій" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Дозволяти підписку" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Визначити модель доступу" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Дозволені для підписки групи ростера" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Умови публікації" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "" "Видалити всі елементи, коли особа, що їх опублікувала, вимикається від мережі" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Вкажіть тип повідомлень зі сповіщеннями про події" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Максимальний розмір корисного навантаження в байтах" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Коли надсилати останній опублікований елемент" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Доставляти повідомленнями тільки доступним користувачам" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Колекція, до якої входить вузол" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "Перевірку капчею не пройдено" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "Для реєстрації псевдоніму необхідно використовувати клієнт з підтримкою x:" "data" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Виберіть назву користувача та пароль для реєстрації на цьому сервері" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Користувач" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "Пароль надто простий" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Користувачам не дозволено так часто реєструвати облікові записи" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Немає" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Підписка" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Очікування" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Групи" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Затвердити" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Видалити" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Ростер користувача " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Неправильний формат" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Додати Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Ростер" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Спільні групи контактів" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Додати" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Назва:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Опис:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Члени:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Видимі групи:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Група " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Відправити" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "День народження" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Місто" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Країна" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Електронна пошта" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Прізвище" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Заповніть поля для пошуку користувача Jabber (Додайте * в кінець поля для " "пошуку підрядка)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Повне ім'я" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "По-батькові" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Назва" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Назва організації" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Відділ організації" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Пошук користувачів в " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Для пошуку необхідний клієнт із підтримкою x:data" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Пошук користувачів по vCard" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard модуль" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Результати пошуку в " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Заповніть поля для пошуку користувача Jabber" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Не авторизовано" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "Веб-інтерфейс Адміністрування ejabberd" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Адміністрування" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "необроблений формат" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Конфігурація правила доступу ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "віртуальні хости" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Користувачі" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Статистика останнього підключення користувачів" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Період" #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "За останній місяць" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "За останній рік" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Вся статистика" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Показати звичайну таблицю" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Показати інтегральну таблицю" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Статистика" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "не знайдено" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Вузол не знайдено" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Хост" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Зареєстровані користувачі" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Офлайнові повідомлення" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Останнє підключення" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Зареєстровані користувачі:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Підключені користувачі:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Вихідні s2s-з'єднання:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Вихідні s2s-сервери:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Змінити пароль" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Користувач " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Підключені ресурси:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Пароль:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Немає даних" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Вузли" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Вузол " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Відкриті порти" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Обновити" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Перезапустити" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Зупинити" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Помилка виклику RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Таблиці бази даних на " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Тип таблиці" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Елементи" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Пам'ять" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Помилка" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Резервне копіювання " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Зауважте, що ця опція відповідає за резервне копіювання тільки вбудованної " "бази даних Mnesia. Якщо Ви також використовуєте інше сховище для даних " "(наприклад за допомогою модуля ODBC), то його резервне копіювання потрібно " "робити окремо." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Зберегти бінарну резервну копію:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "Продовжити" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Відновити з бінарної резервної копії негайно:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Відновити з бінарної резервної копії при наступному запуску (потребує менше " "пам'яті):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Зберегти текстову резервну копію:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Відновити з текстової резервної копії негайно:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Імпорт даних користовучів з файлу PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "Експорт даних всіх користувачів сервера до файлу PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "Експорт даних користувачів домена до файлу PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Імпорт користувачів з файла спула jabberd14:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Імпорт користувачів з діректорії спула jabberd14:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Відкриті порти на " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Модулі на " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Статистика вузла ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Час роботи:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Процесорний час:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Транзакції завершені:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Транзакції відмінені:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Транзакції перезапущені:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Транзакції запротокольовані:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Поновлення " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "План поновлення" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Змінені модулі" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Сценарій поновлення" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Низькорівневий сценарій поновлення" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Перевірка сценарію" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Порт" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Протокол" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Модуль" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Параметри" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Видалити" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Запустити" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Ваш Jabber-акаунт було успішно створено." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Помилка при створенні акаунту:" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Ваш Jabber-акаунт було успішно видалено." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Помилка при видаленні акаунту: " #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Пароль вашого Jabber-акаунту був успішно змінений." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Помилка при зміні пароля: " #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Реєстрація Jabber-акаунту" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Зареєструвати Jabber-акаунт" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Видалити Jabber-акаунт" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Тут ви можете зареєструвати обліковий запис Jabber на цьому сервері. Ваш JID " "(ідентифікатор Jabber) матиме вигляд \"користувач@сервер\". Щоб вірно " "заповнити поля нижче, будь ласка, уважно читайте інструкції до них." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Ім'я користувача:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Регістр не має значення: \"МАША\" та \"маша\" буде сприйматися як одне й те " "саме ім'я." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Заборонені символи:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Сервер:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "Нікому не кажіть свій пароль, навіть адміністраторам сервера." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "Пізніше можна змінити пароль через Jabber-клієнт." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Деякі Jabber-клієнти можуть зберігати пароль на вашому комп'ютері. " "Користуйтесь цією функцією тільки у тому випадку, якщо вважаєте її безпечною." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Запам'ятайте пароль, або запишіть його на папері, який треба зберегти у " "безпечному місці. У Jabber'і немає автоматизованих засобів відновлення " "пароля на той випадок, якщо ви його забудете." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Перевірка Пароля:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Реєстрація" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Старий пароль:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Новий Пароль:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "Ця сторінка дозволяє видалити свій акаунт з Jabber-сервера." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Видалити" #~ msgid "Captcha test failed" #~ msgstr "Перевірка капчею закінчилась невдало" ejabberd-2.1.11/src/msgs/es.msg0000664000000000000000000006735512240230175013115 0ustar {"Access Configuration","Configuración de accesos"}. {"Access Control List Configuration","Configuración de la Lista de Control de Acceso"}. {"Access control lists","Listas de Control de Acceso"}. {"Access Control Lists","Listas de Control de Acceso"}. {"Access denied by service policy","Acceso denegado por la política del servicio"}. {"Access rules","Reglas de acceso"}. {"Access Rules","Reglas de Acceso"}. {"Action on user","Acción en el usuario"}. {"Add Jabber ID","Añadir Jabber ID"}. {"Add New","Añadir nuevo"}. {"Add User","Añadir usuario"}. {"Administration","Administración"}. {"Administration of ","Administración de "}. {"Administrator privileges required","Se necesita privilegios de administrador"}. {"A friendly name for the node","Un nombre sencillo para el nodo"}. {"All activity","Toda la actividad"}. {"Allow this Jabber ID to subscribe to this pubsub node?","¿Deseas permitir a este Jabber ID que se subscriba a este nodo PubSub?"}. {"Allow users to change the subject","Permitir a los usuarios cambiar el asunto"}. {"Allow users to query other users","Permitir a los usuarios consultar a otros usuarios"}. {"Allow users to send invites","Permitir a los usuarios enviar invitaciones"}. {"Allow users to send private messages","Permitir a los usuarios enviar mensajes privados"}. {"Allow visitors to change nickname","Permitir a los visitantes cambiarse el apodo"}. {"Allow visitors to send private messages to","Permitir a los visitantes enviar mensajes privados a"}. {"Allow visitors to send status text in presence updates","Permitir a los visitantes enviar texto de estado en las actualizaciones de presencia"}. {"Allow visitors to send voice requests","Permitir a los visitantes enviar peticiones de voz"}. {"All Users","Todos los usuarios"}. {"Announcements","Anuncios"}. {"anyone","cualquiera"}. {"A password is required to enter this room","Se necesita contraseña para entrar en esta sala"}. {"April","abril"}. {"August","agosto"}. {"Backup","Guardar copia de seguridad"}. {"Backup Management","Gestión de copia de seguridad"}. {"Backup of ","Copia de seguridad de "}. {"Backup to File at ","Guardar copia de seguridad en fichero en "}. {"Bad format","Mal formato"}. {"Birthday","Cumpleaños"}. {"CAPTCHA web page","Página web de CAPTCHA"}. {"Change Password","Cambiar contraseña"}. {"Change User Password","Cambiar contraseña de usuario"}. {"Characters not allowed:","Caracteres no permitidos:"}. {"Chatroom configuration modified","Configuración de la sala modificada"}. {"Chatroom is created","Se ha creado la sala"}. {"Chatroom is destroyed","Se ha destruido la sala"}. {"Chatroom is started","Se ha iniciado la sala"}. {"Chatroom is stopped","Se ha detenido la sala"}. {"Chatrooms","Salas de charla"}. {"Choose a username and password to register with this server","Escoge un nombre de usuario y contraseña para registrarte en este servidor"}. {"Choose modules to stop","Selecciona módulos a detener"}. {"Choose storage type of tables","Selecciona tipo de almacenamiento de las tablas"}. {"Choose whether to approve this entity's subscription.","Decidir si aprobar la subscripción de esta entidad."}. {"City","Ciudad"}. {"Commands","Comandos"}. {"Conference room does not exist","La sala de conferencias no existe"}. {"Configuration","Configuración"}. {"Configuration of room ~s","Configuración para la sala ~s"}. {"Connected Resources:","Recursos conectados:"}. {"Connections parameters","Parámetros de conexiones"}. {"Country","País"}. {"CPU Time:","Tiempo consumido de CPU:"}. {"Database","Base de datos"}. {"Database Tables at ","Tablas de la base de datos en "}. {"Database Tables Configuration at ","Configuración de tablas de la base de datos en "}. {"December","diciembre"}. {"Default users as participants","Los usuarios son participantes por defecto"}. {"Delete","Eliminar"}. {"Delete message of the day","Borrar mensaje del dia"}. {"Delete message of the day on all hosts","Borrar el mensaje del día en todos los dominios"}. {"Delete Selected","Eliminar los seleccionados"}. {"Delete User","Borrar usuario"}. {"Deliver event notifications","Entregar notificaciones de eventos"}. {"Deliver payloads with event notifications","Enviar contenidos junto con las notificaciones de eventos"}. {"Description:","Descripción:"}. {"Disc only copy","Copia en disco solamente"}. {"Displayed Groups:","Mostrar grupos:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","No le digas tu contraseña a nadie, ni siquiera a los administradores del servidor Jabber."}. {"Dump Backup to Text File at ","Exporta copia de seguridad a fichero de texto en "}. {"Dump to Text File","Exportar a fichero de texto"}. {"Edit Properties","Editar propiedades"}. {"Either approve or decline the voice request.","Aprueba o rechaza la petición de voz."}. {"ejabberd IRC module","Módulo de IRC para ejabberd"}. {"ejabberd MUC module","Módulo de MUC para ejabberd"}. {"ejabberd Publish-Subscribe module","Módulo de Publicar-Subscribir de ejabberd"}. {"ejabberd SOCKS5 Bytestreams module","Módulo SOCKS5 Bytestreams para ejabberd"}. {"ejabberd vCard module","Módulo vCard para ejabberd"}. {"ejabberd Web Admin","ejabberd Web Admin"}. {"Elements","Elementos"}. {"Email","correo"}. {"Enable logging","Guardar históricos"}. {"Encoding for server ~b","Codificación del servidor ~b"}. {"End User Session","Cerrar sesión de usuario"}. {"Enter list of {Module, [Options]}","Introduce lista de {módulo, [opciones]}"}. {"Enter nickname you want to register","Introduce el apodo que quieras registrar"}. {"Enter path to backup file","Introduce ruta al fichero de copia de seguridad"}. {"Enter path to jabberd14 spool dir","Introduce la ruta al directorio de jabberd14 spools"}. {"Enter path to jabberd14 spool file","Introduce ruta al fichero jabberd14 spool"}. {"Enter path to text file","Introduce ruta al fichero de texto"}. {"Enter the text you see","Teclea el texto que ves"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Introduce el nombre de usuario y codificaciones de carácteres que quieras usar al conectar en los servidores de IRC. Pulsa Siguiente para conseguir más campos en el formulario. Pulsa Completar para guardar las opciones."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Introduce el nombre de usuario, codificaciones de carácteres, puertos y contraseñas que quieras usar al conectar en los servidores de IRC"}. {"Erlang Jabber Server","Servidor Jabber en Erlang"}. {"Error","Error"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Ejemplo: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Excluir Jabber IDs de las pruebas de CAPTCHA"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exportar datos de todos los usuarios del servidor a ficheros PIEFXIS (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Exportar datos de los usuarios de un dominio a ficheros PIEFXIS (XEP-0227):"}. {"Failed to extract JID from your voice request approval","Fallo al extraer el Jabber ID de tu aprobación de petición de voz"}. {"Family Name","Apellido"}. {"February","febrero"}. {"Fill in fields to search for any matching Jabber User","Rellena campos para buscar usuarios Jabber que concuerden"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Rellena el formulario para buscar usuarios Jabber. Añade * al final de un campo para buscar subcadenas."}. {"Friday","viernes"}. {"From","De"}. {"From ~s","De ~s"}. {"Full Name","Nombre completo"}. {"Get Number of Online Users","Ver número de usuarios conectados"}. {"Get Number of Registered Users","Ver número de usuarios registrados"}. {"Get User Last Login Time","Ver fecha de la última conexión de usuario"}. {"Get User Password","Ver contraseña de usuario"}. {"Get User Statistics","Ver estadísticas de usuario"}. {"Grant voice to this person?","¿Conceder voz a esta persona?"}. {"Group ","Grupo "}. {"Groups","Grupos"}. {"has been banned","ha sido bloqueado"}. {"has been kicked because of an affiliation change","ha sido expulsado por un cambio de su afiliación"}. {"has been kicked because of a system shutdown","ha sido expulsado porque el sistema se va a detener"}. {"has been kicked because the room has been changed to members-only","ha sido expulsado porque la sala es ahora solo para miembros"}. {"has been kicked","ha sido expulsado"}. {" has set the subject to: "," ha puesto el asunto: "}. {"Host","Dominio"}. {"If you don't see the CAPTCHA image here, visit the web page.","Si no ves la imagen CAPTCHA aquí, visita la página web."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Si quieres especificar distintos codificaciones de carácteres, contraseñas o puertos para cada servidor IRC rellena esta lista con valores en el formato '{\"servidor irc\", \"codificación\", \"puerto\", \"contrasela\"}'. Este servicio usa por defecto la codificación \"~s\", puerto ~p, sin contraseña."}. {"Import Directory","Importar directorio"}. {"Import File","Importar fichero"}. {"Import user data from jabberd14 spool file:","Importar usuario de fichero spool de jabberd14:"}. {"Import User from File at ","Importa usuario desde fichero en "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importar usuarios desde un fichero PIEFXIS (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Importar usuarios del directorio spool de jabberd14:"}. {"Import Users from Dir at ","Importar usuarios desde el directorio en "}. {"Import Users From jabberd14 Spool Files","Importar usuarios de ficheros spool de jabberd-1.4"}. {"Improper message type","Tipo de mensaje incorrecto"}. {"Incorrect password","Contraseña incorrecta"}. {"Invalid affiliation: ~s","Afiliación no válida: ~s"}. {"Invalid role: ~s","Rol no válido: ~s"}. {"IP addresses","Direcciones IP"}. {"IP","IP"}. {"IRC channel (don't put the first #)","Canal IRC (no pongas el # del principio)"}. {"IRC server","Servidor IRC"}. {"IRC settings","Opciones de IRC"}. {"IRC Transport","Transporte de IRC"}. {"IRC username","Nombre de usuario en IRC"}. {"IRC Username","Nombre de usuario en IRC"}. {"is now known as","se cambia el nombre a"}. {"It is not allowed to send private messages","No está permitido enviar mensajes privados"}. {"It is not allowed to send private messages of type \"groupchat\"","No está permitido enviar mensajes privados del tipo \"groupchat\""}. {"It is not allowed to send private messages to the conference","Impedir el envio de mensajes privados a la sala"}. {"Jabber Account Registration","Registro de Cuenta Jabber"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","El Jabber ID ~s no es válido"}. {"January","enero"}. {"Join IRC channel","Entrar en canal IRC"}. {"joins the room","entra en la sala"}. {"Join the IRC channel here.","Entrar en el canal de IRC aquí"}. {"Join the IRC channel in this Jabber ID: ~s","Entra en el canal de IRC en esta dirección Jabber: ~s"}. {"July","julio"}. {"June","junio"}. {"Last Activity","Última actividad"}. {"Last login","Última conexión"}. {"Last month","Último mes"}. {"Last year","Último año"}. {"leaves the room","sale de la sala"}. {"Listened Ports at ","Puertos de escucha en "}. {"Listened Ports","Puertos de escucha"}. {"List of modules to start","Lista de módulos a iniciar"}. {"Low level update script","Script de actualización a bajo nivel"}. {"Make participants list public","La lista de participantes es pública"}. {"Make room CAPTCHA protected","Proteger la sala con CAPTCHA"}. {"Make room members-only","Sala sólo para miembros"}. {"Make room moderated","Sala moderada"}. {"Make room password protected","Proteger la sala con contraseña"}. {"Make room persistent","Sala permanente"}. {"Make room public searchable","Sala públicamente visible"}. {"March","marzo"}. {"Maximum Number of Occupants","Número máximo de ocupantes"}. {"Max # of items to persist","Máximo # de elementos que persisten"}. {"Max payload size in bytes","Máximo tamaño del contenido en bytes"}. {"May","mayo"}. {"Membership is required to enter this room","Necesitas ser miembro de esta sala para poder entrar"}. {"Members:","Miembros:"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Memoriza tu contraseña, o apúntala en un papel en un lugar seguro. En Jabber no hay un método automatizado para recuperar la contraseña si la olvidas."}. {"Memory","Memoria"}. {"Message body","Cuerpo del mensaje"}. {"Middle Name","Segundo nombre"}. {"Minimum interval between voice requests (in seconds)","Intervalo mínimo entre peticiones de voz (en segundos)"}. {"Moderator privileges required","Se necesita privilegios de moderador"}. {"moderators only","solo moderadores"}. {"Modified modules","Módulos modificados"}. {"Module","Módulo"}. {"Modules at ","Módulos en "}. {"Modules","Módulos"}. {"Monday","lunes"}. {"Name:","Nombre:"}. {"Name","Nombre"}. {"Never","Nunca"}. {"New Password:","Nueva contraseña:"}. {"Nickname","Apodo"}. {"Nickname Registration at ","Registro del apodo en "}. {"Nickname ~s does not exist in the room","El apodo ~s no existe en la sala"}. {"nobody","nadie"}. {"No body provided for announce message","No se ha proporcionado cuerpo de mensaje para el anuncio"}. {"No Data","Sin datos"}. {"Node ID","Nodo ID"}. {"Node ","Nodo "}. {"Node not found","Nodo no encontrado"}. {"Nodes","Nodos"}. {"No limit","Sin límite"}. {"None","Ninguno"}. {"No resource provided","No se ha proporcionado recurso"}. {"Not Found","No encontrado"}. {"Notify subscribers when items are removed from the node","Notificar subscriptores cuando los elementos se borran del nodo"}. {"Notify subscribers when the node configuration changes","Notificar subscriptores cuando cambia la configuración del nodo"}. {"Notify subscribers when the node is deleted","Notificar subscriptores cuando el nodo se borra"}. {"November","noviembre"}. {"Number of occupants","Número de ocupantes"}. {"Number of online users","Número de usuarios conectados"}. {"Number of registered users","Número de usuarios registrados"}. {"October","octubre"}. {"Offline Messages:","Mensajes diferidos:"}. {"Offline Messages","Mensajes diferidos"}. {"OK","Aceptar"}. {"Old Password:","Contraseña antigua:"}. {"Online","Conectado"}. {"Online Users:","Usuarios conectados:"}. {"Online Users","Usuarios conectados"}. {"Only deliver notifications to available users","Solo enviar notificaciones a los usuarios disponibles"}. {"Only moderators and participants are allowed to change the subject in this room","Solo los moderadores y participantes pueden cambiar el asunto de esta sala"}. {"Only moderators are allowed to change the subject in this room","Solo los moderadores pueden cambiar el asunto de esta sala"}. {"Only moderators can approve voice requests","Solo los moderadores pueden aprobar peticiones de voz"}. {"Only occupants are allowed to send messages to the conference","Solo los ocupantes pueden enviar mensajes a la sala"}. {"Only occupants are allowed to send queries to the conference","Solo los ocupantes pueden enviar solicitudes a la sala"}. {"Only service administrators are allowed to send service messages","Solo los administradores del servicio tienen permiso para enviar mensajes de servicio"}. {"Options","Opciones"}. {"Organization Name","Nombre de la organización"}. {"Organization Unit","Unidad de la organización"}. {"Outgoing s2s Connections:","Conexiones S2S salientes:"}. {"Outgoing s2s Connections","Conexiones S2S salientes"}. {"Outgoing s2s Servers:","Servidores S2S salientes:"}. {"Owner privileges required","Se requieren privilegios de propietario de la sala"}. {"Packet","Paquete"}. {"Password ~b","Contraseña ~b"}. {"Password:","Contraseña:"}. {"Password","Contraseña"}. {"Password Verification:","Verificación de la contraseña:"}. {"Password Verification","Verificación de la contraseña"}. {"Path to Dir","Ruta al directorio"}. {"Path to File","Ruta al fichero"}. {"Pending","Pendiente"}. {"Period: ","Periodo: "}. {"Persist items to storage","Persistir elementos al almacenar"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Ten en cuenta que estas opciones solo harán copia de seguridad de la base de datos Mnesia embebida. Si estás usando ODBC tendrás que hacer también copia de seguridad de tu base de datos SQL."}. {"Please, wait for a while before sending new voice request","Por favor, espera un poco antes de enviar otra petición de voz"}. {"Pong","Pong"}. {"Port ~b","Puerto ~b"}. {"Port","Puerto"}. {"Present real Jabber IDs to","Los Jabber ID reales pueden verlos"}. {"private, ","privado"}. {"Protocol","Protocolo"}. {"Publish-Subscribe","Servicio de Publicar-Subscribir"}. {"PubSub subscriber request","Petición de subscriptor de PubSub"}. {"Purge all items when the relevant publisher goes offline","Borra todos los elementos cuando el publicador relevante se desconecta"}. {"Queries to the conference members are not allowed in this room","En esta sala no se permiten solicitudes a los miembros de la sala"}. {"RAM and disc copy","Copia en RAM y disco"}. {"RAM copy","Copia en RAM"}. {"Raw","Crudo"}. {"Really delete message of the day?","¿Está seguro de quere borrar el mensaje del dia?"}. {"Recipient is not in the conference room","El receptor no está en la sala de conferencia"}. {"Register a Jabber account","Registrar una cuenta Jabber"}. {"Registered Users:","Usuarios registrados:"}. {"Registered Users","Usuarios registrados"}. {"Register","Registrar"}. {"Registration in mod_irc for ","Registro en mod_irc para"}. {"Remote copy","Copia remota"}. {"Remove All Offline Messages","Borrar todos los mensajes diferidos"}. {"Remove","Borrar"}. {"Remove User","Eliminar usuario"}. {"Replaced by new connection","Reemplazado por una nueva conexión"}. {"Resources","Recursos"}. {"Restart","Reiniciar"}. {"Restart Service","Reiniciar el servicio"}. {"Restore Backup from File at ","Restaura copia de seguridad desde el fichero en "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Restaurar copia de seguridad binaria en el siguiente reinicio de ejabberd (requiere menos memoria que si instantánea):"}. {"Restore binary backup immediately:","Restaurar inmediatamente copia de seguridad binaria:"}. {"Restore plain text backup immediately:","Restaurar copias de seguridad de texto plano inmediatamente:"}. {"Restore","Restaurar"}. {"Room Configuration","Configuración de la sala"}. {"Room creation is denied by service policy","Se te ha denegado crear la sala por política del servicio"}. {"Room description","Descripción de la sala"}. {"Room Occupants","Ocupantes de la sala"}. {"Room title","Título de la sala"}. {"Roster groups allowed to subscribe","Grupos de contactos que pueden suscribirse"}. {"Roster","Lista de contactos"}. {"Roster of ","Lista de contactos de "}. {"Roster size","Tamaño de la lista de contactos"}. {"RPC Call Error","Error en la llamada RPC"}. {"Running Nodes","Nodos funcionando"}. {"~s access rule configuration","Configuración de las Regla de Acceso ~s"}. {"Saturday","sábado"}. {"Script check","Comprobación de script"}. {"Search Results for ","Buscar resultados por "}. {"Search users in ","Buscar usuarios en "}. {"Send announcement to all online users","Enviar anuncio a todos los usuarios conectados"}. {"Send announcement to all online users on all hosts","Enviar anuncio a todos los usuarios conectados en todos los dominios"}. {"Send announcement to all users","Enviar anuncio a todos los usuarios"}. {"Send announcement to all users on all hosts","Enviar anuncio a todos los usuarios en todos los dominios"}. {"September","septiembre"}. {"Server ~b","Servidor ~b"}. {"Server:","Servidor:"}. {"Set message of the day and send to online users","Poner mensaje del dia y enviar a todos los usuarios conectados"}. {"Set message of the day on all hosts and send to online users","Poner mensaje del día en todos los dominios y enviar a los usuarios conectados"}. {"Shared Roster Groups","Grupos Compartidos"}. {"Show Integral Table","Mostrar Tabla Integral"}. {"Show Ordinary Table","Mostrar Tabla Ordinaria"}. {"Shut Down Service","Detener el servicio"}. {"~s invites you to the room ~s","~s te invita a la sala ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Algunos clientes Jabber pueden recordar tu contraseña en la máquina. Usa esa opción solo si confías en que la máquina que usas es segura."}. {"Specify the access model","Especifica el modelo de acceso"}. {"Specify the event message type","Especifica el tipo del mensaje de evento"}. {"Specify the publisher model","Especificar el modelo del publicante"}. {"~s's Offline Messages Queue","Cola de mensajes diferidos de ~s"}. {"Start","Iniciar"}. {"Start Modules at ","Iniciar módulos en "}. {"Start Modules","Iniciar módulos"}. {"Statistics","Estadísticas"}. {"Statistics of ~p","Estadísticas de ~p"}. {"Stop","Detener"}. {"Stop Modules at ","Detener módulos en "}. {"Stop Modules","Detener módulos"}. {"Stopped Nodes","Nodos detenidos"}. {"Storage Type","Tipo de almacenamiento"}. {"Store binary backup:","Guardar copia de seguridad binaria:"}. {"Store plain text backup:","Guardar copia de seguridad en texto plano:"}. {"Subject","Asunto"}. {"Submit","Enviar"}. {"Submitted","Enviado"}. {"Subscriber Address","Dirección del subscriptor"}. {"Subscription","Subscripción"}. {"Sunday","domingo"}. {"That nickname is already in use by another occupant","Ese apodo ya está siendo usado por otro ocupante"}. {"That nickname is registered by another person","El apodo ya está registrado por otra persona"}. {"The CAPTCHA is valid.","El CAPTCHA es válido."}. {"The CAPTCHA verification has failed","La verificación de CAPTCHA ha fallado"}. {"The collections with which a node is affiliated","Las colecciones a las que un nodo está afiliado"}. {"the password is","la contraseña es"}. {"The password is too weak","La contraseña es demasiado débil"}. {"The password of your Jabber account was successfully changed.","La contraseña de tu cuenta Jabber se ha cambiado correctamente."}. {"There was an error changing the password: ","Hubo un error cambiando la contraseña."}. {"There was an error creating the account: ","Hubo uno error al crear la cuenta:"}. {"There was an error deleting the account: ","Hubo un error borrando la cuenta."}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","No importa si usas mayúsculas: macbeth es lo mismo que MacBeth y Macbeth."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Esta página te permite crear una cuenta Jabber este servidor Jabber. Tu JID (Jabber IDentificador) será de la forma: nombredeusuario@servidor. Por favor lee detenidamente las instrucciones para rellenar correctamente los campos."}. {"This page allows to unregister a Jabber account in this Jabber server.","Esta página te permite borrar tu cuenta Jabber en este servidor Jabber."}. {"This participant is kicked from the room because he sent an error message","Este participante ha sido expulsado de la sala porque envió un mensaje de error"}. {"This participant is kicked from the room because he sent an error message to another participant","Este participante ha sido expulsado de la sala porque envió un mensaje de error a otro participante"}. {"This participant is kicked from the room because he sent an error presence","Este participante ha sido expulsado de la sala porque envió una presencia de error"}. {"This room is not anonymous","Sala no anónima"}. {"Thursday","jueves"}. {"Time delay","Retraso temporal"}. {"Time","Fecha"}. {"Too many CAPTCHA requests","Demasiadas peticiones de CAPTCHA"}. {"To","Para"}. {"To ~s","A ~s"}. {"Traffic rate limit is exceeded","Se ha exedido el límite de tráfico"}. {"Transactions Aborted:","Transacciones abortadas:"}. {"Transactions Committed:","Transacciones finalizadas:"}. {"Transactions Logged:","Transacciones registradas:"}. {"Transactions Restarted:","Transacciones reiniciadas:"}. {"Tuesday","martes"}. {"Unable to generate a CAPTCHA","No se pudo generar un CAPTCHA"}. {"Unauthorized","No autorizado"}. {"Unregister a Jabber account","Borrar una cuenta Jabber"}. {"Unregister","Borrar"}. {"Update ","Actualizar "}. {"Update","Actualizar"}. {"Update message of the day (don't send)","Actualizar mensaje del dia, pero no enviarlo"}. {"Update message of the day on all hosts (don't send)","Actualizar el mensaje del día en todos los dominos (pero no enviarlo)"}. {"Update plan","Plan de actualización"}. {"Update script","Script de actualización"}. {"Uptime:","Tiempo desde el inicio:"}. {"Use of STARTTLS required","Es obligatorio usar STARTTLS"}. {"User JID","Jabber ID del usuario"}. {"User Management","Administración de usuarios"}. {"Username:","Nombre de usuario:"}. {"Users are not allowed to register accounts so quickly","Los usuarios no tienen permitido crear cuentas con tanta rapidez"}. {"Users Last Activity","Última actividad de los usuarios"}. {"Users","Usuarios"}. {"User ","Usuario "}. {"User","Usuario"}. {"Validate","Validar"}. {"vCard User Search","Buscar vCard de usuario"}. {"Virtual Hosts","Dominios Virtuales"}. {"Visitors are not allowed to change their nicknames in this room","Los visitantes no tienen permitido cambiar sus apodos en esta sala"}. {"Visitors are not allowed to send messages to all occupants","Los visitantes no pueden enviar mensajes a todos los ocupantes"}. {"Voice request","Petición de voz"}. {"Voice requests are disabled in this conference","Las peticiones de voz están desactivadas en esta sala"}. {"Wednesday","miércoles"}. {"When to send the last published item","Cuando enviar el último elemento publicado"}. {"Whether to allow subscriptions","Permitir subscripciones"}. {"You can later change your password using a Jabber client.","Puedes cambiar tu contraseña después, usando un cliente Jabber."}. {"You have been banned from this room","Has sido bloqueado en esta sala"}. {"You must fill in field \"Nickname\" in the form","Debes rellenar el campo \"Apodo\" en el formulario"}. {"You need a client that supports x:data and CAPTCHA to register","Necesitas un cliente con soporte de x:data y CAPTCHA para registrarte"}. {"You need a client that supports x:data to register the nickname","Necesitas un cliente con soporte de x:data para poder registrar el apodo"}. {"You need an x:data capable client to configure mod_irc settings","Necesitas un cliente con soporte de x:data para configurar las opciones de mod_irc"}. {"You need an x:data capable client to configure room","Necesitas un cliente con soporte de x:data para configurar la sala"}. {"You need an x:data capable client to search","Necesitas un cliente con soporte de x:data para poder buscar"}. {"Your active privacy list has denied the routing of this stanza.","Tu lista de privacidad activa ha denegado el encío de este paquete."}. {"Your contact offline message queue is full. The message has been discarded.","Tu cola de mensajes diferidos de contactos está llena. El mensaje se ha descartado."}. {"Your Jabber account was successfully created.","Tu cuenta Jabber se ha creado correctamente."}. {"Your Jabber account was successfully deleted.","Tu cuenta Jabber se ha borrado correctamente."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Tus mensajes a ~s están siendo bloqueados. Para desbloquearlos, visita ~s"}. ejabberd-2.1.11/src/msgs/sk.msg0000664000000000000000000005535512240230175013120 0ustar {"Access Configuration","Konfigurácia prístupu"}. {"Access Control List Configuration","Konfigurácia zoznamu prístupových oprávnení (ACL)"}. {"Access control lists","Zoznamy prístupových oprávnení (ACL)"}. {"Access Control Lists","Zoznamy prístupových oprávnení (ACL)"}. {"Access denied by service policy","Prístup bol zamietnutý nastavením služby"}. {"Access rules","Prístupové pravidlá"}. {"Access Rules","Prístupové pravidlá"}. {"Action on user","Operácia aplikovaná na užívateľa"}. {"Add Jabber ID","Pridať Jabber ID"}. {"Add New","Pridať nový"}. {"Add User","Pridať používateľa"}. {"Administration","Administrácia"}. {"Administration of ","Administrácia "}. {"Administrator privileges required","Sú potrebné práva administrátora"}. {"A friendly name for the node","Prístupný názov pre uzol"}. {"All activity","Všetky aktivity"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Dovoliť tomuto Jabber ID odoberať PubSub uzol?"}. {"Allow users to change the subject","Povoliť užívateľom meniť tému"}. {"Allow users to query other users","Povoliť užívateľom dotazovať sa informácie o iných užívateľoch"}. {"Allow users to send invites","Povoliť používateľom posielanie pozvánok"}. {"Allow users to send private messages","Povoliť užívateľom odosielať súkromné správy"}. {"Allow visitors to change nickname","Návštevníci môžu meniť prezývky"}. {"Allow visitors to send status text in presence updates","Návštevníci môžu posielať textové informácie v stavových správach"}. {"All Users","Všetci užívatelia"}. {"Announcements","Oznámenia"}. {"anyone","všetkým"}. {"A password is required to enter this room","Pre vstup do miestnosti je potrebné heslo"}. {"April","Apríl"}. {"August","August"}. {"Backup Management","Správa zálohovania"}. {"Backup of ","Záloha "}. {"Backup to File at ","Záloha do súboru na "}. {"Backup","Zálohovať"}. {"Bad format","Zlý formát"}. {"Birthday","Dátum narodenia"}. {"Change Password","Zmeniť heslo"}. {"Change User Password","Zmeniť heslo užívateľa"}. {"Chatroom configuration modified","Nastavenie diskusnej miestnosti bolo zmenené"}. {"Chatroom is created","Diskusná miestnosť je vytvorená"}. {"Chatroom is destroyed","Diskusná miestnosť je zrušená"}. {"Chatroom is started","Diskusná miestnosť je obnovená"}. {"Chatroom is stopped","Diskusná miestnosť je pozastavená"}. {"Chatrooms","Diskusné miestnosti"}. {"Choose a username and password to register with this server","Zvolte meno užívateľa a heslo pre registráciu na tomto servere"}. {"Choose modules to stop","Vyberte moduly, ktoré majú byť zastavené"}. {"Choose storage type of tables","Vyberte typ úložiska pre tabuľky"}. {"Choose whether to approve this entity's subscription.","Zvolte, či chcete povoliť toto odoberanie"}. {"City","Mesto"}. {"Commands","Príkazy"}. {"Conference room does not exist","Diskusná miestnosť neexistuje"}. {"Configuration","Konfigurácia"}. {"Configuration of room ~s","Konfigurácia miestnosti ~s"}. {"Connected Resources:","Pripojené zdroje:"}. {"Connections parameters","Parametre spojenia"}. {"Country","Krajina"}. {"CPU Time:","Čas procesoru"}. {"Database","Databáza"}. {"Database Tables at ","Databázové tabuľky na "}. {"Database Tables Configuration at ","Konfigurácia databázových tabuliek "}. {"December","December"}. {"Default users as participants","Užívatelia sú implicitne členmi"}. {"Delete message of the day on all hosts","Zmazať správu dňa na všetkých serveroch"}. {"Delete message of the day","Zmazať správu dňa"}. {"Delete Selected","Zmazať vybrané"}. {"Delete User","Vymazať užívateľa"}. {"Delete","Zmazať"}. {"Deliver event notifications","Doručiť oznamy o udalosti"}. {"Deliver payloads with event notifications","Doručiť náklad s upozornením na udalosť"}. {"Description:","Popis:"}. {"Disc only copy","Len kópia disku"}. {"Displayed Groups:","Zobrazené skupiny:"}. {"Dump Backup to Text File at ","Uložiť zálohu do textového súboru na "}. {"Dump to Text File","Uložiť do textového súboru"}. {"Edit Properties","Editovať vlastnosti"}. {"ejabberd IRC module","ejabberd IRC modul"}. {"ejabberd MUC module","ejabberd MUC modul"}. {"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe modul"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams modul"}. {"ejabberd vCard module","ejabberd vCard modul"}. {"ejabberd Web Admin","ejabberd Web Admin"}. {"Elements","Prvky"}. {"Email","E-mail"}. {"Enable logging","Zapnúť zaznamenávanie histórie"}. {"Encoding for server ~b","Kódovanie pre server ~b"}. {"End User Session","Ukončiť reláciu užívateľa"}. {"Enter list of {Module, [Options]}","Vložte zoznam modulov {Modul, [Parametre]}"}. {"Enter nickname you want to register","Zadajte prezývku, ktorú chcete registrovať"}. {"Enter path to backup file","Zadajte cestu k súboru so zálohou"}. {"Enter path to jabberd14 spool dir","Zadajte cestu k jabberd14 spool adresáru"}. {"Enter path to jabberd14 spool file","Zadajte cestu k spool súboru jabberd14"}. {"Enter path to text file","Zadajte cestu k textovému súboru"}. {"Enter the text you see","Zadajte zobrazený text"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Vložte meno používateľa a kódovanie, ktoré chcete používať pri pripojení na IRC servery. Kliknutím na tlačítko 'Ďalej' môžete zadať niektoré ďalšie hodnoty. Pomocou 'Ukončiť ' uložíte nastavenia."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Vložte meno používateľa, kódovanie, porty a heslo ktoré chcete používať pri pripojení na IRC server"}. {"Erlang Jabber Server","Erlang Jabber Server"}. {"Error","Chyba"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Príklad: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exportovať dáta všetkých uživateľov na serveri do súborov PIEFXIS (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Exportovať dáta uživateľov na hostitelovi do súborov PIEFXIS (XEP-0227):"}. {"Family Name","Priezvisko"}. {"February","Február"}. {"Fill in fields to search for any matching Jabber User","Vyplnte políčka pre vyhľadávanie Jabber užívateľa"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Pre vyhľadanie Jabber používateľa vyplňte formulár (pridajte znak * na koniec, pre vyhľadanie podreťazca)"}. {"Friday","Piatok"}. {"From","Od"}. {"From ~s","Od ~s"}. {"Full Name","Celé meno: "}. {"Get Number of Online Users","Zobraziť počet pripojených užívateľov"}. {"Get Number of Registered Users","Zobraziť počet registrovaných užívateľov"}. {"Get User Last Login Time","Zobraziť čas posledného prihlásenia"}. {"Get User Password","Zobraziť heslo užívateľa"}. {"Get User Statistics","Zobraziť štatistiku užívateľa"}. {"Group ","Skupina "}. {"Groups","Skupiny"}. {"has been banned","bol(a) zablokovaný(á)"}. {"has been kicked because of an affiliation change","bol vyhodený(á) kvôli zmene priradenia"}. {"has been kicked because of a system shutdown","bol vyhodený(á) kvôli reštartu systému"}. {"has been kicked because the room has been changed to members-only","bol vyhodený(á), pretože miestnosť bola vyhradená len pre členov"}. {"has been kicked","bol(a) vyhodený(á) z miestnosti"}. {" has set the subject to: ","zmenil(a) tému na: "}. {"Host","Server"}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Ak chcete zadať iné porty, heslá a kódovania pre IRC servery, vyplnte zoznam s hodnotami vo formáte '{\"irc server\",\"kódovanie\", \"port\", \"heslo\"}'. Predvolenéi hodnoty pre túto službu sú: kódovanie \"~s\", port ~p a žiadne heslo."}. {"Import Directory","Import adresára"}. {"Import File","Import súboru"}. {"Import user data from jabberd14 spool file:","Importovať dáta užívateľov z jabberd14 spool súboru:"}. {"Import User from File at ","Importovať užívateľa zo súboru na "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importovat dáta užívateľov zo súboru PIEFXIS (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Importovať dáta užívateľov z jabberd14 spool adresára:"}. {"Import Users from Dir at ","Importovať užívateľov z adresára na "}. {"Import Users From jabberd14 Spool Files","Importovať užívateľov z jabberd14 spool súborov"}. {"Improper message type","Nesprávny typ správy"}. {"Incorrect password","Nesprávne heslo"}. {"Invalid affiliation: ~s","Neplatné priradenie: ~s"}. {"Invalid role: ~s","Neplatná rola: ~s"}. {"IP addresses","IP adresa"}. {"IP","IP"}. {"IRC channel (don't put the first #)","IRC kanál (bez počiatočnej #)"}. {"IRC server","IRC server"}. {"IRC settings","Nastavania IRC"}. {"IRC Transport","IRC Transport"}. {"IRC username","IRC prezývka"}. {"IRC Username","IRC prezývka"}. {"is now known as","sa premenoval(a) na"}. {"It is not allowed to send private messages","Nieje povolené posielať súkromné správy"}. {"It is not allowed to send private messages of type \"groupchat\"","Nie je dovolené odoslanie súkromnej správy typu \"Skupinová správa\" "}. {"It is not allowed to send private messages to the conference","Nie je povolené odosielať súkromné správy do konferencie"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Jabber ID ~s je neplatné"}. {"January","Január"}. {"Join IRC channel","Pripojit IRC kanál"}. {"joins the room","vstúpil(a) do miestnosti"}. {"Join the IRC channel here.","Propojiť IRC kanál sem."}. {"Join the IRC channel in this Jabber ID: ~s","Pripojit IRC kanál k tomuto Jabber ID: ~s"}. {"July","Júl"}. {"June","Jún"}. {"Last Activity","Posledná aktivita"}. {"Last login","Posledné prihlásenie"}. {"Last month","Posledný mesiac"}. {"Last year","Posledný rok"}. {"leaves the room","odišiel(a) z miestnosti"}. {"Listened Ports at ","Otvorené porty na "}. {"Listened Ports","Otvorené portov"}. {"List of modules to start","Zoznam modulov, ktoré majú byť spustené"}. {"Low level update script","Nízkoúrovňový aktualizačný skript"}. {"Make participants list public","Nastaviť zoznam zúčastnených ako verejný"}. {"Make room CAPTCHA protected","Chrániť miestnosť systémom CAPTCHA"}. {"Make room members-only","Nastaviť miestnosť len pre členov"}. {"Make room moderated","Nastaviť miestnosť ako moderovanú"}. {"Make room password protected","Chrániť miestnosť heslom"}. {"Make room persistent","Nastaviť miestnosť ako trvalú"}. {"Make room public searchable","Nastaviť miestnosť ako verejne prehľadávateľnú"}. {"March","Marec"}. {"Maximum Number of Occupants","Počet účastníkov"}. {"Max # of items to persist","Maximálny počet položiek, ktoré je možné natrvalo uložiť"}. {"Max payload size in bytes","Maximálny náklad v bajtoch"}. {"May","Máj"}. {"Members:","Členovia:"}. {"Membership is required to enter this room","Pre vstup do miestnosti je potrebné byť členom"}. {"Memory","Pamäť"}. {"Message body","Telo správy"}. {"Middle Name","Prostredné meno: "}. {"Moderator privileges required","Sú potrebné práva moderátora"}. {"moderators only","moderátorom"}. {"Modified modules","Modifikované moduly"}. {"Module","Modul"}. {"Modules at ","Moduly na "}. {"Modules","Moduly"}. {"Monday","Pondelok"}. {"Name:","Meno:"}. {"Name","Meno"}. {"Never","Nikdy"}. {"Nickname","Prezývka"}. {"Nickname Registration at ","Registrácia prezývky na "}. {"Nickname ~s does not exist in the room","Prezývka ~s v miestnosti neexistuje"}. {"No body provided for announce message","Správa neobsahuje text"}. {"No Data","Žiadne dáta"}. {"Node ID","ID uzlu"}. {"Node not found","Uzol nenájdený"}. {"Nodes","Uzly"}. {"Node ","Uzol "}. {"No limit","Bez limitu"}. {"None","Nič"}. {"No resource provided","Nebol poskytnutý žiadny zdroj"}. {"Not Found","Nebol nájdený"}. {"Notify subscribers when items are removed from the node","Upozorniť prihlásených používateľov na odstránenie položiek z uzlu"}. {"Notify subscribers when the node configuration changes","Upozorniť prihlásených používateľov na zmenu nastavenia uzlu"}. {"Notify subscribers when the node is deleted","Upozorniť prihlásených používateľov na zmazanie uzlu"}. {"November","November"}. {"Number of occupants","Počet zúčastnených"}. {"Number of online users","Počet online užívateľov"}. {"Number of registered users","Počet registrovaných užívateľov"}. {"October","Október"}. {"Offline Messages:","Offline správy"}. {"Offline Messages","Offline správy"}. {"OK","OK"}. {"Online","Online"}. {"Online Users:","Online používatelia:"}. {"Online Users","Online užívatelia"}. {"Only deliver notifications to available users","Doručovať upozornenia len aktuálne prihláseným používateľom"}. {"Only moderators and participants are allowed to change the subject in this room","Len moderátori a zúčastnený majú povolené meniť tému tejto miestnosti"}. {"Only moderators are allowed to change the subject in this room","Len moderátori majú povolené meniť tému miestnosti"}. {"Only occupants are allowed to send messages to the conference","Len členovia majú povolené zasielať správy do konferencie"}. {"Only occupants are allowed to send queries to the conference","Len členovia majú povolené dotazovať sa o konferencii"}. {"Only service administrators are allowed to send service messages","Iba správcovia služby majú povolené odosielanie servisných správ"}. {"Options","Nastavenia"}. {"Organization Name","Meno organizácie: "}. {"Organization Unit","Organizačná jednotka: "}. {"Outgoing s2s Connections:","Odchádzajúce s2s spojenia:"}. {"Outgoing s2s Connections","Odchádzajúce s2s spojenia"}. {"Outgoing s2s Servers:","Odchádzajúce s2s servery:"}. {"Owner privileges required","Sú vyžadované práva vlastníka"}. {"Packet","Paket"}. {"Password ~b","Heslo ~b"}. {"Password:","Heslo:"}. {"Password","Heslo"}. {"Password Verification","Overenie hesla"}. {"Path to Dir","Cesta k adresáru"}. {"Path to File","Cesta k súboru"}. {"Pending","Čakajúce"}. {"Period: ","Čas:"}. {"Persist items to storage","Uložiť položky natrvalo do úložiska"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Prosím, berte na vedomie, že tieto nastavenia zázálohujú iba zabudovnú Mnesia databázu. Ak používate ODBC modul, musíte zálohovať vašu SQL databázu separátne."}. {"Pong","Pong"}. {"Port ~b","Port ~b"}. {"Port","Port"}. {"Present real Jabber IDs to","Zobrazovať skutočné Jabber ID"}. {"private, ","súkromná, "}. {"Protocol","Protokol"}. {"Publish-Subscribe","Publish-Subscribe"}. {"PubSub subscriber request","Žiadosť odberateľa PubSub"}. {"Purge all items when the relevant publisher goes offline","Odstrániť všetky relevantné položky, keď užívateľ prejde do módu offline"}. {"Queries to the conference members are not allowed in this room","Dotazovať sa o členoch nie je v tejto miestnosti povolené"}. {"RAM and disc copy","Kópia RAM a disku"}. {"RAM copy","Kópia RAM"}. {"Raw","Raw"}. {"Really delete message of the day?","Skutočne zmazať správu dňa?"}. {"Recipient is not in the conference room","Príjemca sa nenachádza v konferenčnej miestnosti"}. {"Registered Users:","Registrovaní používatelia:"}. {"Registered Users","Registrovaní používatelia"}. {"Registration in mod_irc for ","Registrácia do mod_irc na "}. {"Remote copy","Vzdialená kópia"}. {"Remove All Offline Messages","Odstrániť všetky offline správy"}. {"Remove","Odstrániť"}. {"Remove User","Odstrániť užívateľa"}. {"Replaced by new connection","Nahradené novým spojením"}. {"Resources","Zdroje"}. {"Restart","Reštart"}. {"Restart Service","Reštartovať službu"}. {"Restore Backup from File at ","Obnoviť zálohu zo súboru na "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Obnoviť binárnu zálohu pri nasledujúcom reštarte ejabberd (vyžaduje menej pamäte)"}. {"Restore binary backup immediately:","Okamžite obnoviť binárnu zálohu:"}. {"Restore","Obnoviť"}. {"Restore plain text backup immediately:","Okamžite obnoviť zálohu z textového súboru:"}. {"Room Configuration","Nastavenia miestnosti"}. {"Room creation is denied by service policy","Vytváranie miestnosti nie je povolené"}. {"Room description","Popis miestnosti"}. {"Room Occupants","Ľudí v miestnosti"}. {"Room title","Názov miestnosti"}. {"Roster groups allowed to subscribe","Skupiny kontaktov, ktoré môžu odoberať"}. {"Roster of ","Zoznam kontaktov "}. {"Roster size","Počet kontaktov v zozname"}. {"Roster","Zoznam kontaktov"}. {"RPC Call Error","Chyba RPC volania"}. {"Running Nodes","Bežiace uzly"}. {"~s access rule configuration","~s konfigurácia prístupového pravidla"}. {"Saturday","Sobota"}. {"Script check","Kontrola skriptu"}. {"Search Results for ","Hľadať výsledky pre "}. {"Search users in ","Hľadať užívateľov v "}. {"Send announcement to all online users","Odoslať zoznam všetkým online používateľom"}. {"Send announcement to all online users on all hosts","Odoslať oznam všetkým online používateľom na všetkých serveroch"}. {"Send announcement to all users","Odoslať oznam všetkým používateľom"}. {"Send announcement to all users on all hosts","Poslať oznámenie všetkým užívateľom na všetkých serveroch"}. {"September","September"}. {"Server ~b","Server ~b"}. {"Set message of the day and send to online users","Nastaviť správu dňa a odoslať ju online používateľom"}. {"Set message of the day on all hosts and send to online users","Nastaviť správu dňa na všetkých serveroch a poslať ju online užívateľom"}. {"Shared Roster Groups","Skupiny pre zdieľaný zoznam kontaktov"}. {"Show Integral Table","Zobraziť kompletnú tabuľku"}. {"Show Ordinary Table","Zobraziť bežnú tabuľku"}. {"Shut Down Service","Vypnúť službu"}. {"~s invites you to the room ~s","~s Vás pozýva do miestnosti ~s"}. {"Specify the access model","Uveďte model prístupu"}. {"Specify the event message type","Uveďte typ pre správu o udalosti"}. {"Specify the publisher model","Špecifikovať model publikovania"}. {"~s's Offline Messages Queue","~s Offline správy"}. {"Start Modules at ","Spustiť moduly na "}. {"Start Modules","Spustiť moduly"}. {"Start","Štart"}. {"Statistics of ~p","Štatistiky ~p"}. {"Statistics","Štatistiky"}. {"Stop Modules at ","Zastaviť moduly na "}. {"Stop Modules","Zastaviť moduly"}. {"Stopped Nodes","Zastavené uzly"}. {"Stop","Zastaviť"}. {"Storage Type","Typ úložiska"}. {"Store binary backup:","Uložiť binárnu zálohu:"}. {"Store plain text backup:","Uložiť zálohu do textového súboru:"}. {"Subject","Predmet"}. {"Submit","Odoslať"}. {"Submitted","Odoslané"}. {"Subscriber Address","Adresa odberateľa"}. {"Subscription","Prihlásenie"}. {"Sunday","Nedeľa"}. {"That nickname is already in use by another occupant","Prezývka je už používaná iným členom"}. {"That nickname is registered by another person","Prezývka je už zaregistrovaná inou osobou"}. {"The CAPTCHA is valid.","Platná CAPTCHA."}. {"The collections with which a node is affiliated","Kolekcie asociované s uzlom"}. {"the password is","heslo je"}. {"This participant is kicked from the room because he sent an error message to another participant","Účastník bol vyhodený z miestnosti, pretože poslal chybovú správu inému účastníkovi"}. {"This participant is kicked from the room because he sent an error message","Účastník bol vyhodený z miestnosti, pretože poslal chybovú správu"}. {"This participant is kicked from the room because he sent an error presence","Účastník bol vyhodený z miestnosti, pretože poslal chybovú správu o stave"}. {"This room is not anonymous","Táto miestnosť nie je anonymná"}. {"Thursday","Štvrtok"}. {"Time","Čas"}. {"Time delay","Časový posun"}. {"To","Pre"}. {"To ~s","Pre ~s"}. {"Traffic rate limit is exceeded","Bol prekročený prenosový limit"}. {"Transactions Aborted:","Transakcie zrušená"}. {"Transactions Committed:","Transakcie potvrdená"}. {"Transactions Logged:","Transakcie zaznamenaná"}. {"Transactions Restarted:","Transakcie reštartovaná"}. {"Tuesday","Utorok"}. {"Unauthorized","Neautorizovaný"}. {"Update ","Aktualizovať "}. {"Update","Aktualizovať"}. {"Update message of the day (don't send)","Aktualizovať správu dňa (neodosielať)"}. {"Update message of the day on all hosts (don't send)","Upraviť správu dňa na všetkých serveroch"}. {"Update plan","Aktualizovať plán"}. {"Update script","Aktualizované skripty"}. {"Uptime:","Uptime:"}. {"Use of STARTTLS required","Použitie STARTTLS je vyžadované"}. {"User Management","Správa užívateľov"}. {"User ","Používateľ "}. {"Users are not allowed to register accounts so quickly","Nieje dovolené vytvárať účty tak rýchlo po sebe"}. {"Users Last Activity","Posledná aktivita používateľa"}. {"Users","Používatelia"}. {"User","Užívateľ"}. {"Validate","Overiť"}. {"vCard User Search","Hľadať užívateľov vo vCard"}. {"Virtual Hosts","Virtuálne servery"}. {"Visitors are not allowed to change their nicknames in this room","V tejto miestnosti nieje povolené meniť prezývky"}. {"Visitors are not allowed to send messages to all occupants","Návštevníci nemajú povolené zasielať správy všetkým prihláseným do konferencie"}. {"Wednesday","Streda"}. {"When to send the last published item","Kedy odoslať posledne publikovanú položku"}. {"Whether to allow subscriptions","Povoliť prihlasovanie"}. {"You have been banned from this room","Boli ste vylúčený z tejto miestnosti"}. {"You must fill in field \"Nickname\" in the form","Musíte vyplniť políčko \"Prezývka\" vo formulári"}. {"You need an x:data capable client to configure mod_irc settings","Pre konfiguráciu mod_irc potrebujete klienta podporujúceho x:data"}. {"You need an x:data capable client to configure room","Na konfiguráciu miestnosti potrebujete klienta podporujúceho x:data"}. {"You need an x:data capable client to search","Na vyhľadávanie potrebujete klienta podporujúceho x:data"}. {"Your contact offline message queue is full. The message has been discarded.","Fronta offline správ tohoto kontaktu je plná. Správa bola zahodená."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Správa určená pre ~s bola zablokovaná. Oblokovať ju môžete na ~s"}. ejabberd-2.1.11/src/msgs/th.po0000664000000000000000000020251012240230175012731 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "Last-Translator: EQHO Communications (Thailand) Ltd. - http://www.eqho.com\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Thai (ภาษาไทย)\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "ต้องใช้ STARTTLS" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "ไม่ได้ระบุข้อมูล" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "แทนที่ด้วยการเชื่อมต่อใหม่" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 #, fuzzy msgid "Enter the text you see" msgstr "ป้อนพาธของไฟล์ข้อความ" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "" #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "คำสั่ง" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "แน่ใจว่าต้องการลบข้อความของวันหรือไม่" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "หัวเรื่อง" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "เนื้อหาของข้อความ" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "ไม่ได้ป้อนเนื้อหาสำหรับข้อความที่ประกาศ" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "ประกาศ" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "ส่งประกาศถึงผู้ใช้ทั้งหมด" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "ส่งประกาศถึงผู้ใช้ทั้งหมดบนโฮสต์ทั้งหมด" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "ส่งประกาศถึงผู้ใช้ออนไลน์ทั้งหมด" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "ส่งประกาศถึงผู้ใช้ออนไลน์ทั้งหมดบนโฮสต์ทั้งหมด" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "ตั้งค่าข้อความของวันและส่งถึงผู้ใช้ออนไลน์" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "ตั้งค่าข้อความของวันบนโฮสต์ทั้งหมดและส่งถึงผู้ใช้ออนไลน์" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "อัพเดตข้อความของวัน (ไม่ต้องส่ง)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "อัพเดตข้อความของวันบนโฮสต์ทั้งหมด (ไม่ต้องส่ง) " #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "ลบข้อความของวัน" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "ลบข้อความของวันบนโฮสต์ทั้งหมด" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "การกำหนดค่า" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "ฐานข้อมูล" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "เริ่มโมดูล" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "หยุดโมดูล" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "การสำรองข้อมูล " #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "การคืนค่า" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "ถ่ายโอนข้อมูลไปยังไฟล์ข้อความ" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "อิมพอร์ตไฟล์" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "อิมพอร์ตไดเร็กทอรี" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "เริ่มต้นการบริการใหม่อีกครั้ง" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "ปิดการบริการ" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "เพิ่มผู้ใช้" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "ลบผู้ใช้" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "สิ้นสุดเซสชันของผู้ใช้" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "ขอรับรหัสผ่านของผู้ใช้" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "เปลี่ยนรหัสผ่านของผู้ใช้" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "แสดงเวลาเข้าสู่ระบบครั้งล่าสุดของผู้ใช้" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "แสดงสถิติของผู้ใช้" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "แสดงจำนวนผู้ใช้ที่ลงทะเบียน" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "แสดงจำนวนผู้ใช้ออนไลน์" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "รายการควบคุมการเข้าถึง" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "กฎการเข้าถึง" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "การจัดการผู้ใช้" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "ผู้ใช้ออนไลน์" #: mod_configure.erl:501 msgid "All Users" msgstr "ผู้ใช้ทั้งหมด" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "การเชื่อมต่อ s2s ขาออก" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "โหนดที่ทำงาน" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "โหนดที่หยุด" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "โมดูล" #: mod_configure.erl:578 msgid "Backup Management" msgstr "การจัดการข้อมูลสำรอง" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "อิมพอร์ตผู้ใช้จากไฟล์เก็บพักข้อมูล jabberd14" #: mod_configure.erl:699 msgid "To ~s" msgstr "ถึง ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "จาก ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "การกำหนดค่าตารางฐานข้อมูลที่" #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "เลือกชนิดการจัดเก็บของตาราง" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "คัดลอกเฉพาะดิสก์" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "คัดลอก RAM และดิสก์" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "คัดลอก RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "คัดลอกระยะไกล" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "หยุดโมดูลที่" #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "เลือกโมดูลเพื่อหยุดการทำงาน" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "เริ่มโมดูลที่" #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "ป้อนรายการของ {โมดูล, [ตัวเลือก]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "รายการของโมดูลที่จะเริ่มการทำงาน" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "สำรองไฟล์ข้อมูลที่" #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "ป้อนพาธเพื่อสำรองไฟล์ข้อมูล" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "พาธของไฟล์ข้อมูล" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "คืนค่าการสำรองข้อมูลจากไฟล์ที่" #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "ถ่ายโอนการสำรองข้อมูลไปยังไฟล์ข้อความที่" #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "ป้อนพาธของไฟล์ข้อความ" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "อิมพอร์ตผู้ใช้จากไฟล์ที่" #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "ป้อนพาธไปยังไฟล์เก็บพักข้อมูล jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "อิมพอร์ตผู้ใช้จาก Dir ที่" #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "ป้อนพาธไปยัง jabberd14 spool dir" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "พาธไปยัง Dir" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "การหน่วงเวลา" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "การกำหนดค่ารายการควบคุมการเข้าถึง" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "รายการควบคุมการเข้าถึง" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "การกำหนดค่าการเข้าถึง" #: mod_configure.erl:1175 msgid "Access rules" msgstr "กฎการเข้าถึง" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "รหัสผ่าน" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "การตรวจสอบรหัสผ่าน" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "จำนวนผู้ใช้ที่ลงทะเบียน" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "จำนวนผู้ใช้ออนไลน์" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "ไม่เคย" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "ออนไลน์" #: mod_configure.erl:1701 msgid "Last login" msgstr "การเข้าสู่ระบบครั้งล่าสุด" #: mod_configure.erl:1722 msgid "Roster size" msgstr "ขนาดของบัญชีรายชื่อ" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "ที่อยู่ IP" #: mod_configure.erl:1724 msgid "Resources" msgstr "ทรัพยากร" #: mod_configure.erl:1850 msgid "Administration of " msgstr "การดูแล " #: mod_configure.erl:1853 msgid "Action on user" msgstr "การดำเนินการกับผู้ใช้" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "แก้ไขคุณสมบัติ" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "ลบผู้ใช้" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "การเข้าถึงถูกปฏิเสธโดยนโยบายการบริการ" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "การส่ง IRC" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC module" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "คุณต้องใช้ไคลเอ็นต์ที่รองรับ x:data เพื่อกำหนดการตั้งค่า mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "การลงทะเบียนใน mod_irc สำหรับ" #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 #, fuzzy msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "ป้อนชื่อผู้ใช้และการเข้ารหัสที่คุณต้องการใช้สำหรับเชื่อมต่อกับเซิร์ฟเวอร์ IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "ชื่อผู้ใช้ IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 #, fuzzy msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "ถ้าคุณต้องการระบุการเข้ารหัสที่ต่างกันสำหรับเซิร์ฟเวอร์ IRC ให้กรอกค่าโดยใช้รูปแบบ '{\"irc " "server\", \"encoding\"}' ลงในรายการ การบริการนี้ใช้การเข้ารหัสในรูปแบบ \"~s\" " "โดยค่าดีฟอลต์ " #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 #, fuzzy msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "ตัวอย่าง: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", " "\"iso8859-1\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 #, fuzzy msgid "IRC server" msgstr "ชื่อผู้ใช้ IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 #, fuzzy msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "ป้อนชื่อผู้ใช้และการเข้ารหัสที่คุณต้องการใช้สำหรับเชื่อมต่อกับเซิร์ฟเวอร์ IRC" #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 #, fuzzy msgid "IRC username" msgstr "ชื่อผู้ใช้ IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 #, fuzzy msgid "Password ~b" msgstr "รหัสผ่าน" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 #, fuzzy msgid "Port ~b" msgstr "พอร์ท" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "ผู้ดูแลด้านการบริการเท่านั้นที่ได้รับอนุญาตให้ส่งข้อความการบริการ" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "การสร้างห้องสนทนาถูกปฏิเสธโดยนโยบายการบริการ" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "ไม่มีห้องประชุม" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "ห้องสนทนา" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 #, fuzzy msgid "You need a client that supports x:data to register the nickname" msgstr "คุณต้องใช้ไคลเอ็นต์ที่รองรับ x:data เพื่อลงทะเบียนชื่อเล่น" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "การลงทะเบียนชื่อเล่นที่ " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "ป้อนชื่อเล่นที่คุณต้องการลงทะเบียน" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "ชื่อเล่น" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 #, fuzzy msgid "That nickname is registered by another person" msgstr "ชื่อเล่นถูกลงทะเบียนใช้งานโดยบุคคลอื่น" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "คุณต้องกรอกฟิลด์ \"Nickname\" ในแบบฟอร์ม" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC module" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "มีการปรับเปลี่ยนการกำหนดค่าของห้องสนทนา" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "เข้าห้องสนทนานี้" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "ออกจากห้อง" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "ถูกสั่งห้าม" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "ถูกไล่ออก" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "ซึ่งรู้จักกันในชื่อ" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " ตั้งหัวข้อว่า: " #: mod_muc/mod_muc_log.erl:452 #, fuzzy msgid "Chatroom is created" msgstr "ห้องสนทนา" #: mod_muc/mod_muc_log.erl:453 #, fuzzy msgid "Chatroom is destroyed" msgstr "ห้องสนทนา" #: mod_muc/mod_muc_log.erl:454 #, fuzzy msgid "Chatroom is started" msgstr "ห้องสนทนา" #: mod_muc/mod_muc_log.erl:455 #, fuzzy msgid "Chatroom is stopped" msgstr "ห้องสนทนา" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "วันจันทร์" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "วันอังคาร" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "วันพุธ" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "วันพฤหัสบดี" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "วันศุกร์" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "วันเสาร์" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "วันอาทิตย์" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "มกราคม" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "กุมภาพันธ์" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "มีนาคม" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "เมษายน" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "พฤษภาคม" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "มิถุนายน" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "กรกฎาคม" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "สิงหาคม" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "กันยายน" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "ตุลาคม" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "พฤศจิกายน" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "ธันวาคม" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "การกำหนดค่าห้องสนทนา" #: mod_muc/mod_muc_log.erl:759 #, fuzzy msgid "Room Occupants" msgstr "จำนวนผู้ครอบครองห้อง" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "อัตราของปริมาณการเข้าใช้เกินขีดจำกัด" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "ไม่อนุญาตให้ส่งข้อความส่วนตัวไปยังห้องประชุม" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "ประเภทข้อความไม่เหมาะสม" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "ไม่อนุญาตให้ส่งข้อความส่วนตัวไปยัง \"กลุ่มสนทนา\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "ผู้รับไม่ได้อยู่ในห้องประชุม" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 #, fuzzy msgid "It is not allowed to send private messages" msgstr "ไม่อนุญาตให้ส่งข้อความส่วนตัวไปยังห้องประชุม" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "ผู้ครอบครองห้องเท่านั้นที่ได้รับอนุญาตให้ส่งข้อความไปยังห้องประชุม" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "ผู้ครอบครองห้องเท่านั้นที่ได้รับอนุญาตให้ส่งกระทู้ถามไปยังห้องประชุม" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "ห้องนี้ไม่อนุญาตให้ส่งกระทู้ถามถึงสมาชิกในห้องประชุม" #: mod_muc/mod_muc_room.erl:932 #, fuzzy msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "ผู้ดูแลการสนทนาและผู้เข้าร่วมเท่านั้นที่ได้รับอนุญาตให้เปลี่ยนหัวข้อในห้องนี้" #: mod_muc/mod_muc_room.erl:937 #, fuzzy msgid "Only moderators are allowed to change the subject in this room" msgstr "ผู้ดูแลการสนทนาเท่านั้นที่ได้รับอนุญาตให้เปลี่ยนหัวข้อในห้องนี้" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "ผู้เยี่ยมเยือนไม่ได้รับอนุญาตให้ส่งข้อความถึงผู้ครอบครองห้องทั้งหมด" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" #: mod_muc/mod_muc_room.erl:1040 #, fuzzy msgid "Visitors are not allowed to change their nicknames in this room" msgstr "ผู้ดูแลการสนทนาเท่านั้นที่ได้รับอนุญาตให้เปลี่ยนหัวข้อในห้องนี้" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 #, fuzzy msgid "That nickname is already in use by another occupant" msgstr "ชื่อเล่นถูกใช้งานอยู่โดยผู้ครอบครองห้อง" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "คุณถูกสั่งห้ามไมให้เข้าห้องนี้" #: mod_muc/mod_muc_room.erl:1771 #, fuzzy msgid "Membership is required to enter this room" msgstr "ต้องเป็นสมาชิกจึงจะสามารถเข้าห้องนี้ได้" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "ห้องนี้ไม่ปิดบังชื่อ" #: mod_muc/mod_muc_room.erl:1833 #, fuzzy msgid "A password is required to enter this room" msgstr "ต้องใส่รหัสผ่านเพื่อเข้าห้องนี้" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "รหัสผ่านไม่ถูกต้อง" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "ต้องมีสิทธิพิเศษของผู้ดูแลระบบ" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "ต้องมีสิทธิพิเศษของผู้ดูแลการสนทนา" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Jabber ID ~s ไม่ถูกต้อง" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "ไม่มีชื่อเล่น ~s อยู่ในห้องนี้" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "การเข้าร่วมที่ไม่ถูกต้อง: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "บทบาทไม่ถูกต้อง: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "ต้องมีสิทธิพิเศษของเจ้าของ" #: mod_muc/mod_muc_room.erl:3195 #, fuzzy msgid "Configuration of room ~s" msgstr "การกำหนดค่าสำหรับ " #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "ชื่อห้อง" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 #, fuzzy msgid "Room description" msgstr "รายละเอียด:" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "สร้างเป็นห้องถาวร" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "สร้างเป็นห้องที่บุคคลทั่วไปสามารถค้นหาได้" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "สร้างรายการผู้เข้าร่วมสำหรับใช้งานโดยบุคคลทั่วไป" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "สร้างห้องที่มีการป้องกันด้วยรหัสผ่าน" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "จำนวนผู้ครอบครองห้องสูงสุด" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "ไม่จำกัด" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "แสดง Jabber IDs ที่ถูกต้องแก่" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "สำหรับผู้ดูแลการสนทนาเท่านั้น" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "ทุกคน" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "สร้างห้องสำหรับสมาชิกเท่านั้น" #: mod_muc/mod_muc_room.erl:3265 #, fuzzy msgid "Make room moderated" msgstr "สร้างเป็นห้องถาวร" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "ผู้ใช้เริ่มต้นเป็นผู้เข้าร่วม" #: mod_muc/mod_muc_room.erl:3271 #, fuzzy msgid "Allow users to change the subject" msgstr "อนุญาตให้ผู้ใช้เปลี่ยนหัวข้อได้" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "อนุญาตให้ผู้ใช้ส่งข้อความส่วนตัว" #: mod_muc/mod_muc_room.erl:3279 #, fuzzy msgid "Allow visitors to send private messages to" msgstr "อนุญาตให้ผู้ใช้ส่งข้อความส่วนตัว" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "อนุญาตให้ผู้ใช้ถามคำถามกับผู้ใช้คนอื่นๆ ได้" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "อนุญาตให้ผู้ใช้ส่งคำเชิญถึงกันได้" #: mod_muc/mod_muc_room.erl:3302 #, fuzzy msgid "Allow visitors to send status text in presence updates" msgstr "อนุญาตให้ผู้ใช้ส่งข้อความส่วนตัว" #: mod_muc/mod_muc_room.erl:3305 #, fuzzy msgid "Allow visitors to change nickname" msgstr "อนุญาตให้ผู้ใช้เปลี่ยนหัวข้อได้" #: mod_muc/mod_muc_room.erl:3308 #, fuzzy msgid "Allow visitors to send voice requests" msgstr "อนุญาตให้ผู้ใช้ส่งคำเชิญถึงกันได้" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "" #: mod_muc/mod_muc_room.erl:3317 #, fuzzy msgid "Make room CAPTCHA protected" msgstr "สร้างห้องที่มีการป้องกันด้วยรหัสผ่าน" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "เปิดใช้งานการบันทึก" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "คุณต้องใช้ไคลเอ็นต์ที่รองรับ x:data เพื่อกำหนดค่าห้องสนทนา " #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "จำนวนผู้ครอบครองห้อง" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "ส่วนตัว, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "" #: mod_muc/mod_muc_room.erl:3809 #, fuzzy msgid "User JID" msgstr "ผู้ใช้" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s เชิญคุณเข้าร่วมสนทนาในห้อง ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "รหัสผ่านคือ" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "ลำดับข้อความออฟไลน์ของผู้ที่ติดต่อของคุณเต็มแล้ว ข้อความถูกลบทิ้งแล้ว" #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "~s's ลำดับข้อความออฟไลน์" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "ส่งแล้ว" #: mod_offline.erl:571 msgid "Time" msgstr "เวลา" #: mod_offline.erl:572 msgid "From" msgstr "จาก" #: mod_offline.erl:573 msgid "To" msgstr "ถึง" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "แพ็กเก็ต" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "ลบข้อความที่เลือก" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "ข้อความออฟไลน์:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 #, fuzzy msgid "Remove All Offline Messages" msgstr "ข้อความออฟไลน์" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestreams module" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "เผยแพร่-สมัครเข้าใช้งาน" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "ejabberd Publish-Subscribe module" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "คำร้องขอของผู้สมัครเข้าใช้งาน PubSub" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "เลือกว่าจะอนุมัติการสมัครเข้าใช้งานของเอนทิตี้นี้หรือไม่" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ID โหนด" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "ที่อยู่ของผู้สมัคร" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "อนุญาตให้ Jabber ID นี้เข้าร่วมเป็นสมาชิกของโหนด pubsub หรือไม่" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "ส่งส่วนของข้อมูล (payload) พร้อมกับการแจ้งเตือนเหตุการณ์" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "ส่งการแจ้งเตือนเหตุการณ์" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "แจ้งเตือนผู้สมัครสมาชิกเมื่อการกำหนดค่าโหนดเปลี่ยนแปลง" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "แจ้งเตือนผู้สมัครสมาชิกเมื่อโหนดถูกลบ" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "แจ้งเตือนผู้สมัครสมาชิกเมื่อรายการถูกลบออกจากโหนด" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "ยืนยันรายการที่จะจัดเก็บ" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "จำนวนสูงสุดของรายการที่ยืนยัน" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "อนุญาตให้เข้าร่วมเป็นสมาชิกหรือไม่" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "ระบุโมเดลการเข้าถึง" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "ระบุโมเดลผู้เผยแพร่" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 #, fuzzy msgid "Specify the event message type" msgstr "ระบุโมเดลการเข้าถึง" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "ขนาดสูงสุดของส่วนของข้อมูล (payload) มีหน่วยเป็นไบต์" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "เวลาที่ส่งรายการที่เผยแพร่ครั้งล่าสุด" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "ส่งการแจ้งเตือนถึงผู้ใช้ที่สามารถติดต่อได้เท่านั้น" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "" #: mod_register.erl:220 #, fuzzy msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "คุณต้องใช้ไคลเอ็นต์ที่รองรับ x:data เพื่อลงทะเบียนชื่อเล่น" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "เลือกชื่อผู้ใช้และรหัสผ่านเพื่อลงทะเบียนกับเซิร์ฟเวอร์นี้" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "ผู้ใช้" #: mod_register.erl:316 mod_register.erl:361 #, fuzzy msgid "The password is too weak" msgstr "รหัสผ่านคือ" #: mod_register.erl:365 #, fuzzy msgid "Users are not allowed to register accounts so quickly" msgstr "ผู้เยี่ยมเยือนไม่ได้รับอนุญาตให้ส่งข้อความถึงผู้ครอบครองห้องทั้งหมด" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "ไม่มี" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "การสมัครสมาชิก" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "ค้างอยู่" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "กลุ่ม" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "ตรวจสอบ" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "ลบ" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "บัญชีรายชื่อของ " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "รูปแบบที่ไม่ถูกต้อง" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "เพิ่ม Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "บัญชีรายชื่อ" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "กลุ่มบัญชีรายชื่อที่ใช้งานร่วมกัน" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "เพิ่มผู้ใช้ใหม่" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "ชื่อ:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "รายละเอียด:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "สมาชิก:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "กลุ่มที่แสดง:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "กลุ่ม" #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "ส่ง" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "วันเกิด" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "เมือง" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "ประเทศ" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "อีเมล" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "นามสกุล" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "กรอกข้อมูลในแบบฟอร์มเพื่อค้นหาผู้ใช้ Jabber ที่ตรงกัน (ใส่เครื่องหมาย * " "ที่ท้ายสุดของฟิลด์เพื่อจับคู่กับสตริงย่อย)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "ชื่อเต็ม" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "ชื่อกลาง" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "ชื่อ" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "ชื่อองค์กร" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "หน่วยขององค์กร" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "ค้นหาผู้ใช้ใน " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "คุณต้องใช้ไคลเอ็นต์ที่รองรับ x:data เพื่อค้นหา" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "ค้นหาผู้ใช้ vCard " #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard module" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "ผลการค้นหาสำหรับ " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "กรอกข้อมูลลงในฟิลด์เพื่อค้นหาผู้ใช้ Jabber ที่ตรงกัน" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 #, fuzzy msgid "ejabberd Web Admin" msgstr "เว็บอินเทอร์เฟซของ ejabberd" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "การดูแล" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "ข้อมูลดิบ" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "~s การกำหนดค่ากฎการเข้าถึง" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "โฮสต์เสมือน" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "ผู้ใช้" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "กิจกรรมล่าสุดของผู้ใช้" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "ระยะเวลา:" #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "เดือนที่แล้ว" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "ปีที่แล้ว" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "กิจกรรมทั้งหมด" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "แสดงตารางทั่วไป" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "แสดงตารางรวม" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "สถิติ" #: web/ejabberd_web_admin.erl:1117 #, fuzzy msgid "Not Found" msgstr "ไม่พบโหนด" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "ไม่พบโหนด" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "โฮสต์" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "ผู้ใช้ที่ลงทะเบียน" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "ข้อความออฟไลน์" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "กิจกรรมล่าสุด" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "ผู้ใช้ที่ลงทะเบียน:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "ผู้ใช้ออนไลน์:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "การเชื่อมต่อ s2s ขาออก:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "เซิร์ฟเวอร์ s2s ขาออก:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "เปลี่ยนรหัสผ่าน" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "ผู้ใช้" #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "ทรัพยากรที่เชื่อมต่อ:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "รหัสผ่าน:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "ไม่มีข้อมูล" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "โหนด" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "โหนด " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "พอร์ทฟัง" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "อัพเดต" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "เริ่มต้นใหม่" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "หยุด" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "ข้อผิดพลาดจากการเรียกใช้ RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "ตารางฐานข้อมูลที่" #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "ชนิดที่เก็บข้อมูล" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "หน่วยความจำ" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "การสำรองข้อมูล" #: web/ejabberd_web_admin.erl:2036 #, fuzzy msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "โปรดทราบว่าตัวเลือกเหล่านี้จะสำรองข้อมูลในฐานข้อมูล builtin Mnesia เท่านั้น หากคุณใช้โมดูล " "ODBC คุณต้องสำรองข้อมูลของฐานข้อมูล SQL แยกต่างหากด้วย" #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "จัดเก็บข้อมูลสำรองแบบไบนารี:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "ตกลง" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "คืนค่าข้อมูลสำรองแบบไบนารีโดยทันที:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "คืนค่าข้อมูลสำรองแบบไบนารีหลังจากที่ ejabberd ถัดไปเริ่มการทำงานใหม่ (ใช้หน่วยความจำน้อยลง):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "จัดเก็บข้อมูลสำรองที่เป็นข้อความธรรมดา:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "คืนค่าข้อมูลสำรองที่เป็นข้อความธรรมดาโดยทันที:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2099 #, fuzzy msgid "Import user data from jabberd14 spool file:" msgstr "อิมพอร์ตผู้ใช้จากไฟล์เก็บพักข้อมูล jabberd14" #: web/ejabberd_web_admin.erl:2106 #, fuzzy msgid "Import users data from jabberd14 spool directory:" msgstr "อิมพอร์ตผู้ใช้จากไฟล์เก็บพักข้อมูล jabberd14" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "พอร์ทฟังที่" #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "โมดูลที่ " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "สถิติของ ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "เวลาการทำงานต่อเนื่อง:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "เวลาการทำงานของ CPU:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "ทรานแซกชันที่ได้รับมอบหมาย:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "ทรานแซกชันที่ถูกยกเลิก:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "ทรานแซกชันที่เริ่มทำงานใหม่อีกครั้ง:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "ทรานแซกชันที่บันทึก:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "อัพเดต " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "แผนการอัพเดต" #: web/ejabberd_web_admin.erl:2255 #, fuzzy msgid "Modified modules" msgstr "โมดูลที่อัพเดต" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "อัพเดตสคริปต์" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "อัพเดตสคริปต์ระดับต่ำ" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "ตรวจสอบคริปต์" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "พอร์ท" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "" #: web/ejabberd_web_admin.erl:2428 #, fuzzy msgid "Protocol" msgstr "พอร์ท" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "โมดูล" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "ตัวเลือก" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "ลบ" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "เริ่ม" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "" #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "" #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "" #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 #, fuzzy msgid "Username:" msgstr "ชื่อผู้ใช้ IRC" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 #, fuzzy msgid "Server:" msgstr "ไม่เคย" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 #, fuzzy msgid "Password Verification:" msgstr "การตรวจสอบรหัสผ่าน" #: web/mod_register_web.erl:250 #, fuzzy msgid "Register" msgstr "บัญชีรายชื่อ" #: web/mod_register_web.erl:396 #, fuzzy msgid "Old Password:" msgstr "รหัสผ่าน:" #: web/mod_register_web.erl:401 #, fuzzy msgid "New Password:" msgstr "รหัสผ่าน:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "" #~ msgid "Encodings" #~ msgstr "การเข้ารหัส" #~ msgid "(Raw)" #~ msgstr "(ข้อมูลดิบ)" #~ msgid "Specified nickname is already registered" #~ msgstr "ชื่อเล่นที่ระบุได้รับการลงได้ทะเบียนแล้ว" #~ msgid "Size" #~ msgstr "ขนาด" #~ msgid "Roster groups that may subscribe (if access model is roster)" #~ msgstr "กลุ่มบัญชีรายชื่อที่อาจจะสมัครเป็นสมาชิก (ถ้าโมเดลการเข้าถึงคือบัญชีรายชื่อ)" ejabberd-2.1.11/src/msgs/fr.po0000664000000000000000000015742312240230175012741 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" "Last-Translator: Nicolas Vérité \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: French (française)\n" "X-Additional-Translator: Christophe Romain\n" "X-Additional-Translator: Mickaël Rémond\n" "X-Additional-Translator: Vincent Ricard\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "L'utilisation de STARTTLS est impérative" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Aucune ressource fournie" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Remplacé par une nouvelle connexion" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "Votre règle de flitrage active a empêché le routage de ce stanza." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Tapez le texte que vous voyez" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "Vos messages pour ~s sont bloqués. Pour les débloquer, veuillez visiter ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "SI vous ne voyez pas l'image CAPTCHA ici, visitez la page web." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "Page web de CAPTCHA" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "Le CAPTCHA est valide" #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Commandes" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Confirmer la suppression du message du jour ?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Sujet" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Corps du message" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Pas de corps de message pour l'annonce" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Annonces" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Envoyer l'annonce à tous les utilisateurs" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Envoyer une annonce à tous les utilisateurs de tous les domaines" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Envoyer l'annonce à tous les utilisateurs en ligne" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "" "Envoyer l'annonce à tous les utilisateurs en ligne sur tous les serveurs" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Définir le message du jour et l'envoyer aux utilisateurs en ligne" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Définir le message du jour pour tous domaines et l'envoyer aux utilisateurs " "en ligne" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Mise à jour du message du jour (pas d'envoi)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "" "Mettre à jour le message du jour sur tous les domaines (ne pas envoyer)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Supprimer le message du jour" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Supprimer le message du jour sur tous les domaines" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Configuration" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Base de données" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Modules de démarrage" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Modules d'arrêt" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Sauvegarde" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Restauration" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Sauvegarder dans un fichier texte" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Importer un fichier" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Importer une répertoire" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Redémarrer le service" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Arrêter le service" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Ajouter un utilisateur" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Supprimer l'utilisateur" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Terminer la session de l'utilisateur" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Récupérer le mot de passe de l'utilisateur" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Changer le mot de passe de l'utilisateur" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Récupérer la dernière date de connexion de l'utilisateur" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Récupérer les statistiques de l'utilisateur" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Récupérer le nombre d'utilisateurs enregistrés" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Récupérer le nombre d'utilisateurs en ligne" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Droits (ACL)" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Règles d'accès" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Gestion des utilisateurs" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Utilisateurs en ligne" #: mod_configure.erl:501 msgid "All Users" msgstr "Tous les utilisateurs" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Connexions s2s sortantes" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Noeuds actifs" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Noeuds arrêtés" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Modules" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Gestion des sauvegardes" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importer des utilisateurs depuis un fichier spool Jabberd 1.4" #: mod_configure.erl:699 msgid "To ~s" msgstr "A ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "De ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Configuration des tables de base de données sur " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Choisissez un type de stockage pour les tables" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Copie sur disque uniquement" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Copie en mémoire vive (RAM) et sur disque" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Copie en mémoire vive (RAM)" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Copie distante" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Arrêter les modules sur " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Sélectionnez les modules à arrêter" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Démarrer les modules sur " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Entrez une liste de {Module, [Options]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Liste des modules à démarrer" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Sauvegarde sur fichier sur " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Entrez le chemin vers le fichier de sauvegarde" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Chemin vers le fichier" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Restaurer la sauvegarde depuis le fichier sur " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Enregistrer la sauvegarde dans un fichier texte sur " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Entrez le chemin vers le fichier texte" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importer un utilisateur depuis le fichier sur " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Entrez le chemin vers le fichier spool jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importer des utilisateurs depuis le répertoire sur " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Entrez le chemin vers le répertoire de spool jabberd14" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Chemin vers le répertoire" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Délais" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Configuration des droits (ACL)" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Droits (ACL)" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Configuration d'accès" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Règles d'accès" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Mot de passe" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Vérification du mot de passe" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Nombre d'utilisateurs enregistrés" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Nombre d'utilisateurs en ligne" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Jamais" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "En ligne" #: mod_configure.erl:1701 msgid "Last login" msgstr "Dernière connexion" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Taille de la liste de contacts" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "Adresses IP" #: mod_configure.erl:1724 msgid "Resources" msgstr "Ressources" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Administration de " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Action sur l'utilisateur" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Modifier les propriétés" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Supprimer l'utilisateur" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "L'accès au service est refusé" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "Passerelle IRC" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "Module IRC ejabberd" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "Vous avez besoin d'un client supportant x:data pour configurer le module IRC" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Enregistrement du mod_irc pour " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Entrez le nom d'utilisateur, les encodages, les ports et mots de passe que " "vous souhaitez utiliser pour vous connecter aux serveurs IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Nom d'utilisateur IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Si vous voulez préciser différents ports, mots de passe, et encodages pour " "les serveurs IRC, remplissez cette liste avec des valeurs dans le format " "'{\"serveur irc\", \"encodage\", port, \"mot de passe\"}'. Par défaut ce " "service utilise l'encodage \"~s\", port ~p, mot de passe vide." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Exemple: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Paramètres de connexion" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Rejoindre un canal IRC" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "Canal IRC (ne pas insérer le premier caractère #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "Serveur IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Rejoindre un canal IRC ici" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Rejoindre un canal IRC avec ce Jabber ID: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "Configuration IRC" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Entrez le nom d'utilisateur et les encodages que vous souhaitez utiliser " "pour vous connecter aux serveurs IRC. Appuyez sur 'Suivant' pour pour avoir " "d'autres champs à remplir. Appuyez sur 'Terminer' pour sauver les paramètres." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "Nom d'utilisateur IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Mot de passe ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Port ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Codage pour le serveur ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Serveur ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" "Seuls les administrateurs du service sont autoriser à envoyer des messages " "de service" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "La création de salons est interdite par le service" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "La salle de conférence n'existe pas" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Salons de discussion" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "" "Vous avez besoin d'un client prenant en charge x:data pour enregistrer un " "pseudo" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Enregistrement d'un pseudo sur " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Entrez le pseudo que vous souhaitez enregistrer" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Pseudo" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Le pseudo est enregistré par une autre personne" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Vous devez préciser le champ \"pseudo\" dans le formulaire" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "Module MUC ejabberd" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Configuration du salon modifiée" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "rejoint le salon" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "quitte le salon" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "a été banni" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "a été expulsé" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "a été éjecté à cause d'un changement d'autorisation" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "a été éjecté car la salle est désormais réservée aux membres" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "a été éjecté en raison de l'arrêt du système" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "est maintenant connu comme" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " a changé le sujet pour: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Le salon de discussion est créé" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Le salon de discussion est détruit" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Le salon de discussion a démarré" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Le salon de discussion est stoppé" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Lundi" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Mardi" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Mercredi" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Jeudi" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Vendredi" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Samedi" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Dimanche" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Janvier" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Février" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Mars" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "Avril" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Mai" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Juin" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Juillet" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Août" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "Septembre" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Octobre" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "Novembre" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "Décembre" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Configuration du salon" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Occupants du salon" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "La limite de trafic a été dépassée" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Ce participant est expulsé du salon pour avoir envoyé un message erronée" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Il n'est pas permis d'envoyer des messages \"normaux\" à la conférence" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Mauvais type de message" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Ce participant est expulsé du salon pour avoir envoyé un message erronée à " "un autre participant" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "" "Il n'est pas permis d'envoyer des messages privés de type \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Le destinataire n'est pas dans la conférence" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "L'envoi de messages privés n'est pas autorisé" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Seuls les occupants peuvent envoyer des messages à la conférence" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "" "Seuls les occupants sont autorisés à envoyer des requêtes à la conférence" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "" "Les requêtes sur les membres de la conférence ne sont pas autorisé dans ce " "salon" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Seuls les modérateurs et les participants peuvent changer le sujet dans ce " "salon" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Seuls les modérateurs peuvent changer le sujet dans ce salon" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "" "Les visiteurs ne sont pas autorisés à envoyer des messages à tout les " "occupants" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Ce participant est expulsé du salon pour avoir envoyé une présence erronée" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Les visiteurs ne sont pas autorisés à changer de pseudo dans ce salon" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Le pseudo est déjà utilisé par un autre occupant" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Vous avez été exclus de ce salon" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Vous devez être membre pour accèder à ce salon" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Ce salon n'est pas anonyme" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Un mot de passe est nécessaire pour accèder à ce salon" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Impossible de générer le CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Mot de passe incorrect" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Les droits d'administrateur sont nécessaires" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Les droits de modérateur sont nécessaires" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Le Jabber ID ~s n'est pas valide" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Le pseudo ~s n'existe pas dans ce salon" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Affiliation invalide : ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Role invalide : ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Les droits de propriétaire sont nécessaires" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Configuration pour le salon ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Titre du salon" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Description :" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Rendre le salon persistant" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Rendre le salon public" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Rendre la liste des participants publique" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Protéger le salon par mot de passe" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Nombre maximum d'occupants" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Pas de limite" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Rendre le Jabber ID réel visible pour" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "modérateurs seulement" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "tout le monde" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Réserver le salon aux membres uniquement" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Rendre le salon modéré" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Les utilisateurs sont par défaut participant" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Autoriser les utilisateurs à changer le sujet" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Autoriser les utilisateurs à envoyer des messages privés" #: mod_muc/mod_muc_room.erl:3279 #, fuzzy msgid "Allow visitors to send private messages to" msgstr "Autoriser les utilisateurs à envoyer des messages privés" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "" "Permettre aux utilisateurs d'envoyer des requêtes aux autres utilisateurs" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Permettre aux utilisateurs d'envoyer des invitations" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "Autoriser les visiteurs à envoyer un message d'état avec leur présence" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Autoriser les visiteurs à changer de pseudo" #: mod_muc/mod_muc_room.erl:3308 #, fuzzy msgid "Allow visitors to send voice requests" msgstr "Permettre aux utilisateurs d'envoyer des invitations" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Protéger le salon par un CAPTCHA" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Activer l'archivage" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "" "Vous avez besoin d'un client supportant x:data pour configurer le salon" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Nombre d'occupants" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privé" #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "" #: mod_muc/mod_muc_room.erl:3809 #, fuzzy msgid "User JID" msgstr "Utilisateur " #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s vous a invité dans la salle de discussion ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "le mot de passe est" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "La file d'attente de message de votre contact est pleine. Votre message a " "été détruit." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "~s messages en file d'attente" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Soumis" #: mod_offline.erl:571 msgid "Time" msgstr "Heure" #: mod_offline.erl:572 msgid "From" msgstr "De" #: mod_offline.erl:573 msgid "To" msgstr "A" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Paquet" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Suppression des éléments sélectionnés" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Messages en attente :" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Effacer tous les messages hors ligne" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestreams module" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Publication-Abonnement" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "Module Publish-Subscribe d'ejabberd" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Demande d'abonnement PubSub" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Accepter cet abonnement ?" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "Identifiant du nœud" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Adresse de l'abonné" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Autoriser ce Jabber ID à s'abonner à ce nœud PubSub" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Inclure le contenu du message avec la notification" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Envoyer les notifications d'événement" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Avertir les abonnés lorsque la configuration du nœud change" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Avertir les abonnés lorsque le nœud est supprimé" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Avertir les abonnés lorsque des éléments sont supprimés sur le nœud" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Stockage persistant des éléments" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Un nom convivial pour le noeud" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Nombre maximum d'éléments à stocker" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Autoriser l'abonnement ?" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Définir le modèle d'accès" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Groupes de liste de contact autorisés à s'abonner" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Définir le modèle de publication" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "Purger tous les items lorsque publieur est hors-ligne" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Définir le type de message d'événement" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Taille maximum pour le contenu du message en octet" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "A quel moment envoyer le dernier élément publié" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Envoyer les notifications uniquement aux utilisateurs disponibles" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Les collections avec lesquelle un nœud est affilié" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "La vérification du CAPTCHA a échoué" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "Vous avez besoin d'un client prenant en charge x:data et CAPTCHA pour " "enregistrer un pseudo" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "" "Choisissez un nom d'utilisateur et un mot de passe pour s'enregistrer sur ce " "serveur" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Utilisateur" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "Le mot de passe est trop faible" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "" "Les utilisateurs ne sont pas autorisés à enregistrer des comptes si " "rapidement" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Aucun" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Abonnement" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "En suspens" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Groupes" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Valider" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Enlever" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Liste de contact de " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Mauvais format" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Ajouter un Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Liste de contacts" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Groupes de liste de contacts partagée" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Ajouter" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Nom :" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Description :" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Membres :" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Groupes affichés :" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Groupe " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Soumettre" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Serveur Jabber Erlang" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Date d'anniversaire" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Ville" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Pays" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Email" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Nom de famille" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Remplissez le formulaire pour recherche un utilisateur Jabber (Ajouter * à " "la fin du champ pour chercher n'importe quelle fin de chaîne" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Nom complet" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Autre nom" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Nom" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Nom de l'organisation" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Unité de l'organisation" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Rechercher des utilisateurs " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "" "Vous avez besoin d'un client supportant x:data pour faire une recherche" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Recherche dans l'annnuaire" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "Module vCard ejabberd" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Résultats de recherche pour " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Remplissez les champs pour rechercher un utilisateur Jabber" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Non autorisé" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "Console Web d'administration de ejabberd" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Administration" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Brut" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Configuration des règles d'accès ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Serveurs virtuels" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Utilisateurs" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Dernière activité des utilisateurs" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Période :" #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Dernier mois" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Dernière année" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Toute activité" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Montrer la table ordinaire" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Montrer la table intégralement" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Statistiques" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Nœud non trouvé" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Noeud non trouvé" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Serveur" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Utilisateurs enregistrés" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Messages en attente" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Dernière Activité" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Utilisateurs enregistrés:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Utilisateurs connectés:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Connexions s2s sortantes:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Serveurs s2s sortants" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Modifier le mot de passe" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Utilisateur " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Ressources connectées:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Mot de passe:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Aucune information disponible" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Noeuds" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Noeud " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Ports ouverts" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Mettre à jour" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Redémarrer" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Arrêter" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Erreur d'appel RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Tables de base de données sur " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Type de stockage" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Éléments" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Mémoire" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Erreur" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Sauvegarde de " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Ces options sauvegardent uniquement la base de données interne Mnesia. Si " "vous utilisez le module ODBC vous devez sauvegarde votre base SQL séparément." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Sauvegarde binaire:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Restauration immédiate d'une sauvegarde binaire:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Restauration de la sauvegarde binaire après redémarrage (nécessite moins de " "mémoire):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Sauvegarde texte:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Restauration immédiate d'une sauvegarde texte:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "" "Importer les données utilisateurs à partir d'un fichier PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Exporter les données de tous les utilisateurs du serveur vers un fichier " "PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" "Exporter les données utilisateurs d'un hôte vers un fichier PIEFXIS " "(XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importer des utilisateurs depuis un fichier spool Jabberd 1.4:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importer des utilisateurs depuis un fichier spool Jabberd 1.4:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Ports ouverts sur " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Modules sur " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Statistiques de ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Temps depuis le démarrage :" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Temps CPU :" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transactions commitées :" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transactions annulées :" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transactions redémarrées :" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transactions journalisées :" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Mise à jour " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Plan de mise à jour" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Modules mis à jour" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Script de mise à jour" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Script de mise à jour de bas-niveau" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Validation du script" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Port" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protocole" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Module" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Options" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Supprimer" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Démarrer" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Votre compte Jabber a été créé avec succès." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Il y a eu une erreur en créant le compte :" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Votre compte Jabber a été effacé avec succès." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Il y a eu une erreur en effaçant le compte :" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Le mot de passe de votre compte Jabber a été changé avec succès." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Il y a eu une erreur en changeant le mot de passe :" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Enregistrement du Compte Jabber" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Enregistrer un compte Jabber" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Effacer un compte Jabber" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Cette page permet de créer un compte Jabber sur ce serveur Jabber. Votre JID " "(Jabber IDentifier, identifiant Jabber) sera de la forme : nom@serveur. " "Prière de lire avec attention les instructions pour remplir correctement ces " "champs." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Nom d'utilisateur :" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "C'est insensible à la casse : macbeth est identique à MacBeth et Macbeth." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Caractères non-autorisés :" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Serveur :" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "Ne révélez votre mot de passe à personne, pas même l'administrateur de ce " "serveur." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" "Vous pouvez changer votre mot de passe plus tard en utilisant un client " "Jabber." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Certains clients Jabber peuvent stocker votre mot de passe sur votre " "ordinateur. N'utilisez cette fonctionnalité que si vous avez confiance en la " "sécurité de votre ordinateur." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Mémorisez votre mot de passe, ou écrivez-le sur un papier conservé dans un " "endroit secret. Dans Jabber il n'y a pas de mécanisme pour retrouver votre " "mot de passe si vous l'avez oublié." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Vérification du mot de passe :" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Enregistrer" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Ancien mot de passe:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Nouveau mot de passe:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "Cette page permet d'effacer un compte Jabber sur ce serveur Jabber." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Effacer" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "Le CAPTCHA est valide" #~ msgid "Encodings" #~ msgstr "Encodages" #~ msgid "(Raw)" #~ msgstr "(Brut)" ejabberd-2.1.11/src/msgs/sk.po0000664000000000000000000015245212240230175012744 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "Last-Translator: Marek Bečka\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Slovak (slovenčina)\n" "X-Additional-Translator: Juraj Michalek\n" "X-Additional-Translator: SkLUG\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Použitie STARTTLS je vyžadované" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Nebol poskytnutý žiadny zdroj" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Nahradené novým spojením" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Zadajte zobrazený text" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "Správa určená pre ~s bola zablokovaná. Oblokovať ju môžete na ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "Platná CAPTCHA." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Príkazy" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Skutočne zmazať správu dňa?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Predmet" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Telo správy" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Správa neobsahuje text" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Oznámenia" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Odoslať oznam všetkým používateľom" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Poslať oznámenie všetkým užívateľom na všetkých serveroch" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Odoslať zoznam všetkým online používateľom" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Odoslať oznam všetkým online používateľom na všetkých serveroch" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Nastaviť správu dňa a odoslať ju online používateľom" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Nastaviť správu dňa na všetkých serveroch a poslať ju online užívateľom" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Aktualizovať správu dňa (neodosielať)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Upraviť správu dňa na všetkých serveroch" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Zmazať správu dňa" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Zmazať správu dňa na všetkých serveroch" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Konfigurácia" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Databáza" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Spustiť moduly" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Zastaviť moduly" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Zálohovať" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Obnoviť" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Uložiť do textového súboru" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Import súboru" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Import adresára" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Reštartovať službu" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Vypnúť službu" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Pridať používateľa" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Vymazať užívateľa" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Ukončiť reláciu užívateľa" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Zobraziť heslo užívateľa" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Zmeniť heslo užívateľa" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Zobraziť čas posledného prihlásenia" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Zobraziť štatistiku užívateľa" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Zobraziť počet registrovaných užívateľov" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Zobraziť počet pripojených užívateľov" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Zoznamy prístupových oprávnení (ACL)" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Prístupové pravidlá" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Správa užívateľov" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Online užívatelia" #: mod_configure.erl:501 msgid "All Users" msgstr "Všetci užívatelia" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Odchádzajúce s2s spojenia" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Bežiace uzly" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Zastavené uzly" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Moduly" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Správa zálohovania" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importovať užívateľov z jabberd14 spool súborov" #: mod_configure.erl:699 msgid "To ~s" msgstr "Pre ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Od ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Konfigurácia databázových tabuliek " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Vyberte typ úložiska pre tabuľky" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Len kópia disku" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Kópia RAM a disku" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Kópia RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Vzdialená kópia" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Zastaviť moduly na " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Vyberte moduly, ktoré majú byť zastavené" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Spustiť moduly na " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Vložte zoznam modulov {Modul, [Parametre]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Zoznam modulov, ktoré majú byť spustené" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Záloha do súboru na " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Zadajte cestu k súboru so zálohou" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Cesta k súboru" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Obnoviť zálohu zo súboru na " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Uložiť zálohu do textového súboru na " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Zadajte cestu k textovému súboru" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importovať užívateľa zo súboru na " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Zadajte cestu k spool súboru jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importovať užívateľov z adresára na " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Zadajte cestu k jabberd14 spool adresáru" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Cesta k adresáru" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Časový posun" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Konfigurácia zoznamu prístupových oprávnení (ACL)" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Zoznamy prístupových oprávnení (ACL)" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Konfigurácia prístupu" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Prístupové pravidlá" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Heslo" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Overenie hesla" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Počet registrovaných užívateľov" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Počet online užívateľov" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Nikdy" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Online" #: mod_configure.erl:1701 msgid "Last login" msgstr "Posledné prihlásenie" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Počet kontaktov v zozname" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "IP adresa" #: mod_configure.erl:1724 msgid "Resources" msgstr "Zdroje" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Administrácia " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Operácia aplikovaná na užívateľa" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Editovať vlastnosti" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Odstrániť užívateľa" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Prístup bol zamietnutý nastavením služby" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC Transport" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC modul" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "Pre konfiguráciu mod_irc potrebujete klienta podporujúceho x:data" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Registrácia do mod_irc na " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Vložte meno používateľa, kódovanie, porty a heslo ktoré chcete používať pri " "pripojení na IRC server" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "IRC prezývka" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Ak chcete zadať iné porty, heslá a kódovania pre IRC servery, vyplnte zoznam " "s hodnotami vo formáte '{\"irc server\",\"kódovanie\", \"port\", \"heslo" "\"}'. Predvolenéi hodnoty pre túto službu sú: kódovanie \"~s\", port ~p a " "žiadne heslo." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Príklad: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Parametre spojenia" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Pripojit IRC kanál" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "IRC kanál (bez počiatočnej #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "IRC server" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Propojiť IRC kanál sem." #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Pripojit IRC kanál k tomuto Jabber ID: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "Nastavania IRC" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Vložte meno používateľa a kódovanie, ktoré chcete používať pri pripojení na " "IRC servery. Kliknutím na tlačítko 'Ďalej' môžete zadať niektoré ďalšie " "hodnoty. Pomocou 'Ukončiť ' uložíte nastavenia." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "IRC prezývka" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Heslo ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Port ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Kódovanie pre server ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Server ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "Iba správcovia služby majú povolené odosielanie servisných správ" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Vytváranie miestnosti nie je povolené" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Diskusná miestnosť neexistuje" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Diskusné miestnosti" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 #, fuzzy msgid "You need a client that supports x:data to register the nickname" msgstr "Na registráciu prezývky potrebujete klienta podporujúceho z x:data" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Registrácia prezývky na " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Zadajte prezývku, ktorú chcete registrovať" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Prezývka" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Prezývka je už zaregistrovaná inou osobou" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Musíte vyplniť políčko \"Prezývka\" vo formulári" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC modul" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Nastavenie diskusnej miestnosti bolo zmenené" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "vstúpil(a) do miestnosti" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "odišiel(a) z miestnosti" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "bol(a) zablokovaný(á)" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "bol(a) vyhodený(á) z miestnosti" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "bol vyhodený(á) kvôli zmene priradenia" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "bol vyhodený(á), pretože miestnosť bola vyhradená len pre členov" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "bol vyhodený(á) kvôli reštartu systému" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "sa premenoval(a) na" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr "zmenil(a) tému na: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Diskusná miestnosť je vytvorená" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Diskusná miestnosť je zrušená" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Diskusná miestnosť je obnovená" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Diskusná miestnosť je pozastavená" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Pondelok" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Utorok" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Streda" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Štvrtok" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Piatok" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Sobota" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Nedeľa" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Január" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Február" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Marec" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "Apríl" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Máj" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Jún" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Júl" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "August" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "September" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Október" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "November" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "December" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Nastavenia miestnosti" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Ľudí v miestnosti" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Bol prekročený prenosový limit" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "Účastník bol vyhodený z miestnosti, pretože poslal chybovú správu" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Nie je povolené odosielať súkromné správy do konferencie" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Nesprávny typ správy" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Účastník bol vyhodený z miestnosti, pretože poslal chybovú správu inému " "účastníkovi" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "Nie je dovolené odoslanie súkromnej správy typu \"Skupinová správa\" " #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Príjemca sa nenachádza v konferenčnej miestnosti" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Nieje povolené posielať súkromné správy" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Len členovia majú povolené zasielať správy do konferencie" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Len členovia majú povolené dotazovať sa o konferencii" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "Dotazovať sa o členoch nie je v tejto miestnosti povolené" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "Len moderátori a zúčastnený majú povolené meniť tému tejto miestnosti" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Len moderátori majú povolené meniť tému miestnosti" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "" "Návštevníci nemajú povolené zasielať správy všetkým prihláseným do " "konferencie" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Účastník bol vyhodený z miestnosti, pretože poslal chybovú správu o stave" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "V tejto miestnosti nieje povolené meniť prezývky" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Prezývka je už používaná iným členom" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Boli ste vylúčený z tejto miestnosti" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Pre vstup do miestnosti je potrebné byť členom" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Táto miestnosť nie je anonymná" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Pre vstup do miestnosti je potrebné heslo" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 #, fuzzy msgid "Unable to generate a CAPTCHA" msgstr "Nepodarilo sa vygenerovat CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Nesprávne heslo" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Sú potrebné práva administrátora" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Sú potrebné práva moderátora" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Jabber ID ~s je neplatné" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Prezývka ~s v miestnosti neexistuje" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Neplatné priradenie: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Neplatná rola: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Sú vyžadované práva vlastníka" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Konfigurácia miestnosti ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Názov miestnosti" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Popis miestnosti" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Nastaviť miestnosť ako trvalú" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Nastaviť miestnosť ako verejne prehľadávateľnú" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Nastaviť zoznam zúčastnených ako verejný" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Chrániť miestnosť heslom" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Počet účastníkov" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Bez limitu" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Zobrazovať skutočné Jabber ID" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "moderátorom" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "všetkým" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Nastaviť miestnosť len pre členov" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Nastaviť miestnosť ako moderovanú" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Užívatelia sú implicitne členmi" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Povoliť užívateľom meniť tému" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Povoliť užívateľom odosielať súkromné správy" #: mod_muc/mod_muc_room.erl:3279 #, fuzzy msgid "Allow visitors to send private messages to" msgstr "Povoliť užívateľom odosielať súkromné správy" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Povoliť užívateľom dotazovať sa informácie o iných užívateľoch" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Povoliť používateľom posielanie pozvánok" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "Návštevníci môžu posielať textové informácie v stavových správach" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Návštevníci môžu meniť prezývky" #: mod_muc/mod_muc_room.erl:3308 #, fuzzy msgid "Allow visitors to send voice requests" msgstr "Povoliť používateľom posielanie pozvánok" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Chrániť miestnosť systémom CAPTCHA" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Zapnúť zaznamenávanie histórie" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Na konfiguráciu miestnosti potrebujete klienta podporujúceho x:data" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Počet zúčastnených" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "súkromná, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "" #: mod_muc/mod_muc_room.erl:3809 #, fuzzy msgid "User JID" msgstr "Používateľ " #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s Vás pozýva do miestnosti ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "heslo je" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "Fronta offline správ tohoto kontaktu je plná. Správa bola zahodená." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "~s Offline správy" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Odoslané" #: mod_offline.erl:571 msgid "Time" msgstr "Čas" #: mod_offline.erl:572 msgid "From" msgstr "Od" #: mod_offline.erl:573 msgid "To" msgstr "Pre" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Paket" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Zmazať vybrané" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Offline správy" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Odstrániť všetky offline správy" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestreams modul" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Publish-Subscribe" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "ejabberd Publish-Subscribe modul" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Žiadosť odberateľa PubSub" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Zvolte, či chcete povoliť toto odoberanie" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ID uzlu" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Adresa odberateľa" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Dovoliť tomuto Jabber ID odoberať PubSub uzol?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Doručiť náklad s upozornením na udalosť" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Doručiť oznamy o udalosti" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Upozorniť prihlásených používateľov na zmenu nastavenia uzlu" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Upozorniť prihlásených používateľov na zmazanie uzlu" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Upozorniť prihlásených používateľov na odstránenie položiek z uzlu" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Uložiť položky natrvalo do úložiska" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Prístupný názov pre uzol" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Maximálny počet položiek, ktoré je možné natrvalo uložiť" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Povoliť prihlasovanie" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Uveďte model prístupu" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Skupiny kontaktov, ktoré môžu odoberať" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Špecifikovať model publikovania" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "" "Odstrániť všetky relevantné položky, keď užívateľ prejde do módu offline" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Uveďte typ pre správu o udalosti" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Maximálny náklad v bajtoch" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Kedy odoslať posledne publikovanú položku" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Doručovať upozornenia len aktuálne prihláseným používateľom" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Kolekcie asociované s uzlom" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "" #: mod_register.erl:220 #, fuzzy msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "Na registráciu prezývky potrebujete klienta podporujúceho z x:data" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Zvolte meno užívateľa a heslo pre registráciu na tomto servere" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Užívateľ" #: mod_register.erl:316 mod_register.erl:361 #, fuzzy msgid "The password is too weak" msgstr "heslo je" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Nieje dovolené vytvárať účty tak rýchlo po sebe" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Nič" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Prihlásenie" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Čakajúce" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Skupiny" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Overiť" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Odstrániť" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Zoznam kontaktov " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Zlý formát" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Pridať Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Zoznam kontaktov" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Skupiny pre zdieľaný zoznam kontaktov" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Pridať nový" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Meno:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Popis:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Členovia:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Zobrazené skupiny:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Skupina " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Odoslať" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Dátum narodenia" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Mesto" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Krajina" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "E-mail" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Priezvisko" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Pre vyhľadanie Jabber používateľa vyplňte formulár (pridajte znak * na " "koniec, pre vyhľadanie podreťazca)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Celé meno: " #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Prostredné meno: " #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Meno" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Meno organizácie: " #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Organizačná jednotka: " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Hľadať užívateľov v " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Na vyhľadávanie potrebujete klienta podporujúceho x:data" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Hľadať užívateľov vo vCard" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard modul" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Hľadať výsledky pre " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Vyplnte políčka pre vyhľadávanie Jabber užívateľa" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Neautorizovaný" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd Web Admin" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Administrácia" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Raw" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "~s konfigurácia prístupového pravidla" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Virtuálne servery" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Používatelia" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Posledná aktivita používateľa" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Čas:" #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Posledný mesiac" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Posledný rok" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Všetky aktivity" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Zobraziť bežnú tabuľku" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Zobraziť kompletnú tabuľku" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Štatistiky" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Nebol nájdený" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Uzol nenájdený" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Server" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Registrovaní používatelia" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Offline správy" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Posledná aktivita" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Registrovaní používatelia:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Online používatelia:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Odchádzajúce s2s spojenia:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Odchádzajúce s2s servery:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Zmeniť heslo" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Používateľ " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Pripojené zdroje:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Heslo:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Žiadne dáta" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Uzly" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Uzol " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Otvorené portov" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Aktualizovať" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Reštart" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Zastaviť" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Chyba RPC volania" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Databázové tabuľky na " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Typ úložiska" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Prvky" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Pamäť" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Chyba" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Záloha " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Prosím, berte na vedomie, že tieto nastavenia zázálohujú iba zabudovnú " "Mnesia databázu. Ak používate ODBC modul, musíte zálohovať vašu SQL databázu " "separátne." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Uložiť binárnu zálohu:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Okamžite obnoviť binárnu zálohu:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Obnoviť binárnu zálohu pri nasledujúcom reštarte ejabberd (vyžaduje menej " "pamäte)" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Uložiť zálohu do textového súboru:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Okamžite obnoviť zálohu z textového súboru:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Importovat dáta užívateľov zo súboru PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Exportovať dáta všetkých uživateľov na serveri do súborov PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" "Exportovať dáta uživateľov na hostitelovi do súborov PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importovať dáta užívateľov z jabberd14 spool súboru:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importovať dáta užívateľov z jabberd14 spool adresára:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Otvorené porty na " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Moduly na " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Štatistiky ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Uptime:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Čas procesoru" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transakcie potvrdená" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transakcie zrušená" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transakcie reštartovaná" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transakcie zaznamenaná" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Aktualizovať " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Aktualizovať plán" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Modifikované moduly" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Aktualizované skripty" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Nízkoúrovňový aktualizačný skript" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Kontrola skriptu" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Port" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protokol" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Modul" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Nastavenia" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Zmazať" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Štart" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "" #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "" #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "" #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 #, fuzzy msgid "Username:" msgstr "IRC prezývka" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 #, fuzzy msgid "Server:" msgstr "Server ~b" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 #, fuzzy msgid "Password Verification:" msgstr "Overenie hesla" #: web/mod_register_web.erl:250 #, fuzzy msgid "Register" msgstr "Zoznam kontaktov" #: web/mod_register_web.erl:396 #, fuzzy msgid "Old Password:" msgstr "Heslo:" #: web/mod_register_web.erl:401 #, fuzzy msgid "New Password:" msgstr "Heslo:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "Platná CAPTCHA." #~ msgid "Encodings" #~ msgstr "Kódovania" #~ msgid "(Raw)" #~ msgstr "(Raw)" #~ msgid "Specified nickname is already registered" #~ msgstr "Zadaná prezývka je už registrovaná" #~ msgid "Size" #~ msgstr "Veľkosť" #~ msgid "You must fill in field \"nick\" in the form" #~ msgstr "Musíte vyplniť políčko \"prezývka\" vo formulári" ejabberd-2.1.11/src/msgs/de.po0000664000000000000000000015657012240230175012724 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" "Last-Translator: Nikolaus Polak \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: German (deutsch)\n" "X-Additional-Translator: Florian Zumbiehl\n" "X-Additional-Translator: Cord Beermann\n" "X-Additional-Translator: Marvin Preuss\n" "X-Additional-Translator: Patrick Dreker\n" "X-Additional-Translator: Torsten Werner\n" "X-Additional-Translator: Marina Hahn\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Verwendung von STARTTLS erforderlich" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Keine Ressource angegeben" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Durch neue Verbindung ersetzt" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" "Ihre aktive Privacy Liste hat die Weiterleitung des Stanzas unterbunden." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Geben sie den Text den sie sehen ein" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "Ihre Nachrichten an ~s werden blockiert. Um dies zu ändern, besuchen sie ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" "Wenn sie das CAPTCHA Bild nicht sehen, besuchen sie bitte die Webseite." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "CAPTCHA Webseite" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "Die Verifizierung ist gültig." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Befehle" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Die Nachricht des Tages wirklich löschen?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Betreff" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Nachrichtentext" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Kein Text für die Ankündigung angegeben" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Ankündigungen" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Sende Ankündigung an alle Benutzer" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Sende Ankündigung an alle Benutzer auf allen Hosts" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Sende Ankündigung an alle angemeldeten Benutzer" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Sende Ankündigung an alle angemeldeten Benutzer auf allen Hosts" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Setze Nachricht des Tages und sende sie an alle angemeldeten Benutzer" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Setze Nachricht des Tages auf allen Hosts und sende sie an alle angemeldeten " "Benutzer" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Aktualisiere Nachricht des Tages (nicht senden)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Aktualisiere Nachricht des Tages auf allen Hosts (nicht senden)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Lösche Nachricht des Tages" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Lösche Nachricht des Tages auf allen Hosts" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Konfiguration" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Datenbank" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Module starten" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Module stoppen" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Datensicherung" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Wiederherstellung" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Ausgabe in Textdatei" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Datei importieren" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Verzeichnis importieren" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Dienst neustarten" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Dienst herunterfahren" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Benutzer hinzufügen" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Benutzer löschen" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Benutzer-Sitzung beenden" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Benutzer-Passwort abrufen" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Benutzer-Passwort ändern" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "letzte Anmeldezeit abrufen" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Benutzer-Statistiken abrufen" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Anzahl der registrierten Benutzer abrufen" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Anzahl der angemeldeten Benutzer abrufen" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Zugangskontroll-Listen (ACL)" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Zugangsregeln" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Benutzerverwaltung" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Angemeldete Benutzer" #: mod_configure.erl:501 msgid "All Users" msgstr "Alle Benutzer" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Ausgehende s2s-Verbindungen" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Aktive Knoten" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Inaktive Knoten" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Module" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Datensicherungsverwaltung" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importiere Benutzer aus jabberd14-Spool-Dateien" #: mod_configure.erl:699 msgid "To ~s" msgstr "An ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Von ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Datenbanktabellen-Konfiguration auf " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Wähle Speichertyp der Tabellen" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Nur auf Festplatte" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "RAM und Festplatte" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Nur RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Fernkopie" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Stoppe Module auf " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Wähle zu stoppende Module" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Starte Module auf " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Geben sie eine Liste bestehend aus {Modul, [Optionen]} ein" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Liste der zu startenden Module" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Datensicherung in die Datei " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Geben sie den Pfad zur Datensicherung ein" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Pfad zur Datei" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Datenwiederherstellung aus der Datei " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Ausgabe der Sicherung in diese Textdatei " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Geben sie den Pfad zur Textdatei ein" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Benutzer aus dieser Datei importieren " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Geben Sie den Pfad zur jabberd14-Spool-Datei ein" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Benutzer importieren aus dem Verzeichnis " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Geben Sie den Pfad zum jabberd14-Spool-Verzeichnis ein" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Pfad zum Verzeichnis" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Zeitverzögerung" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Konfiguration der Zugangskontrolllisten" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Zugangskontroll-Listen (ACL)" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Zugangskonfiguration" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Zugangsregeln" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Passwort" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Passwort bestätigen" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Anzahl der registrierten Benutzer" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Anzahl der angemeldeten Benutzer" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Nie" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Angemeldet" #: mod_configure.erl:1701 msgid "Last login" msgstr "Letzte Anmeldung" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Kontaktlistengröße" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "IP Adressen" #: mod_configure.erl:1724 msgid "Resources" msgstr "Ressourcen" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Administration von " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Aktion auf Benutzer" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Einstellungen ändern" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Benutzer löschen" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Zugang aufgrund der Dienstrichtlinien verweigert" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC Transport" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC-Modul" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "Sie benötigen einen Client, der x:data unterstützt, um die mod_irc-" "Einstellungen zu konfigurieren" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Registrierung in mod_irc für " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Geben Sie Benutzernamen und Zeichenkodierung für die Verbindung zum IRC-" "Server an" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "IRC-Benutzername" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Wenn sie verschiedene Ports, Passwörter und Kodierungen für IRC Server " "angeben wollen, erstellen sie die Liste mit folgendem Format '{\"IRC Server" "\", \"Kodierung\", Port, \"Passwort\"}'. Standardmäßig benutzt dieser " "Dienst die \"~s\" Kodierung, den Port ~p und kein Passwort." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Beispiel: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta." "fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Verbindungsparameter" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "IRC Channel beitreten" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "IRC Channel (ohne dem ersten #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "IRC Server" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Hier den IRC Channel beitreten." #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Den IRC Channel mit dieser Jabber ID beitreten: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "IRC Einstellungen" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Geben sie Benutzernamen und Kodierung für Verbindungen zu IRC Servern an. " "Drücken sie 'Mehr' um leere Felder hinzuzufügen. Drücken sie 'Beenden' um " "die Einstellungen zu speichern." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "IRC Benutzername" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Passwort ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Port ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Kodierung für Server ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Server ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" "Nur Service-Administratoren sind berechtigt, Servicenachrichten zu versenden" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Anlegen des Raumes aufgrund der Dienstrichtlinien verweigert" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Konferenzraum existiert nicht" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Chaträume" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "" "Sie benötigen einen Client, der x:data unterstützt, um Ihren Benutzernamen " "zu registrieren" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Registrieren des Benutzernames auf" #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Geben sie den zu registrierenden Benutzernamen ein" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Benutzername" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Dieser Benutzername wurde bereits von jemand anderem registriert" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Sie müssen das Feld \"Benutzername\" ausfüllen" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC-Modul" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Chatraum-Konfiguration geändert" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "betretet den Raum" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "verlässt den Raum" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "wurde gebannt" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "wurde gekickt" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "wurde wegen Änderung des Mitgliederstatus gekickt" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "wurde gekickt weil der Raum auf Nur-Mitglieder umgestellt wurde" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "wurde wegen Systemabschaltung gekickt" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "ist nun bekannt als" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " hat das Thema geändert auf: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Chatraum wurde erstellt" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Chatraum wurde entfernt" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Chatraum wurde gestartet" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Chatraum wurde beendet" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Montag" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Dienstag" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Mittwoch" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Donnerstag" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Freitag" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Samstag" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Sonntag" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Januar" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Februar" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "März" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "April" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Mai" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Juni" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Juli" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "August" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "September" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Oktober" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "November" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "Dezember" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Raum-Konfiguration" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Teilnehmer in diesem Raum" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Datenratenlimit wurde überschritten" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Dieser Teilnehmer wurde aus dem Raum geworfen, da er eine fehlerhafte " "Nachricht gesendet hat" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Es ist nicht erlaubt private Nachrichten an den Raum zu schicken" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" "Bitte warten sie ein wenig, bevor sie eine weitere Anfrage für Sprachrechte " "senden" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "Anfragen für Sprachrechte sind in diesem Raum deaktiviert" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" "Fehler beim Auslesen der JID aus der Anfragenbestätigung für Sprachrechte" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Nur Moderatoren können Anfragen für Sprachrechte bestätigen" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Unzulässiger Nachrichtentyp" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Dieser Teilnehmer wurde aus dem Raum geworfen, da er eine fehlerhafte " "Nachricht an einen anderen Teilnehmer gesendet hat" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "" "Es ist nicht erlaubt private Nachrichten des Typs \"Gruppenchat\" zu senden" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Der Empfänger ist nicht im Raum" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Es ist nicht erlaubt private Nachrichten zu senden" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Nur Teilnehmer dürfen Nachrichten an den Raum schicken" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Nur Teilnehmer sind berechtigt Anfragen an die Konferenz zu senden" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "Anfragen an die Teilnehmer sind in diesem Raum nicht erlaubt" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "Nur Moderatoren und Mitglieder dürfen das Thema in diesem Raum ändern" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Nur Moderatoren dürfen das Thema in diesem Raum ändern" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Besucher dürfen nicht an alle Teilnehmer Nachrichten verschicken" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Dieser Teilnehmer wurde aus dem Raum gekickt, da er einen fehlerhaften " "Status gesendet hat" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Besucher dürfen in diesem Raum ihren Benutzernamen nicht ändern" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Dieser Benutzername wird bereits von einem Teilnehmer genutzt" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Sie wurden aus diesem Raum verbannt" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Um diesen Raum zu betreten müssen sie Mitglied sein" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Dieser Raum ist nicht anonym" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Sie brauchen ein Passwort um diesen Raum zu betreten" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Zu viele CAPTCHA Anfragen" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Konnte CAPTCHA nicht erstellen" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Falsches Passwort" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Administratorenrechte benötigt" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Moderatorrechte benötigt" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Die Jabber-ID ~s ist ungültig" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Der Benutzername ~s existiert im Raum nicht" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Ungültige Mitgliedschaft: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Ungültige Rolle: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Besitzerrechte benötigt" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Konfiguration für Raum ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Raumname" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Raum Beschreibung" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Raum persistent machen" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Raum öffentlich suchbar machen" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Teilnehmerliste öffentlich machen" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Raum mit Passwort schützen" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Maximale Anzahl von Teilnehmern" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Keine Begrenzung" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Echte Jabber-IDs anzeigen für" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "ausschliesslich Moderatoren" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "jeden" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Raum nur für Mitglieder zugänglich machen" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Raum moderiert machen" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Standardbenutzer als Teilnehmer" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Erlaube Benutzern das Thema zu ändern" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Erlaube Benutzern private Nachrichten zu senden" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "Erlaube Besuchern das Senden von privaten Nachrichten an" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "niemanden" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Erlaube Benutzern Informationen über andere Benutzer abzufragen" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Erlaube Benutzern Einladungen zu senden" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "Erlaube Besuchern einen Text bei Statusänderung zu senden" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Erlaube Besuchern ihren Spitznamen zu ändern" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "Anfragen von Sprachrechten für Benutzer erlauben" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "Mindestdauer zwischen Anfragen für Sprachrechte (in Sekunden)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Raum mit Verifizierung (Captcha) versehen" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Von CAPTCHA Überprüfung ausgeschlossene Jabber IDs" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Protokollierung aktivieren" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "" "Sie benötigen einen Client, der x:data unterstützt, um den Raum zu " "konfigurieren" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Anzahl der Teilnehmer" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privat, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Anfrage für Sprachrechte" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Diese Anfrage für Sprachrechte bestätigen oder ablehnen." #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "Benutzer JID" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "Sprachrechte dieser Person erteilen?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s lädt Sie in den Raum ~s ein" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "das Passwort lautet" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "Ihre Offline-Nachrichten-Warteschlange ist voll. Die Nachricht wurde " "verworfen." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "~s's Offline-Nachrichten-Warteschlange" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Gesendet" #: mod_offline.erl:571 msgid "Time" msgstr "Zeit" #: mod_offline.erl:572 msgid "From" msgstr "Von" #: mod_offline.erl:573 msgid "To" msgstr "An" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Paket" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Markierte löschen" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Offline-Nachrichten:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Alle Offline Nachrichten löschen" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5-Bytestreams-Modul" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Publish-Subscribe" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "ejabberd Publish-Subscribe-Modul" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "PubSub-Abonnenten-Anfrage" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Wähle Sie, ob dieses Abonnement akzeptiert werden soll." #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "Knoten-ID" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Abonnenten-Adresse" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Dieser Jabber-ID das Abonnement dieses pubsub-Knotens erlauben?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Nachrichten mit Ereignis-Benachrichtigungen zustellen" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Ereignisbenachrichtigung zustellen" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Abonnenten benachrichtigen, wenn sich die Knotenkonfiguration ändert" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Abonnenten benachrichtigen, wenn der Knoten gelöscht wird" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Abonnenten benachrichtigen, wenn Einträge vom Knoten entfernt werden" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Einträge dauerhaft speichern" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Ein merkbarer Name für den Knoten" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Maximale Anzahl dauerhaft zu speichernder Einträge" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Ob Abonnements erlaubt sind" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Geben sie das Zugangsmodell an" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Kontaktlisten-Gruppen die abonnieren dürfen" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Geben sie das Publikationsmodell an" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "" "Alle Einträge entfernen, wenn der relevante Veröffentlicher offline geht" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Geben sie den Ereignis-Nachrichtentyp an" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Maximale Nutzlastgrösse in Bytes" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Wann soll das letzte veröffentlichte Objekt gesendet werden" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Benachrichtigungen nur an verfügbare Benutzer schicken" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Sammlungen, mit denen ein Knoten verknüpft ist" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "Die CAPTCHA Verifizierung schlug fehl" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "Sie benötigen einen Client, der x:data und CAPTCHA unterstützt, um Ihren " "Benutzernamen zu registrieren" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Wählen sie zum Registrieren einen Benutzernamen und ein Passwort" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Benutzer" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "Das Passwort ist zu einfach" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Benutzer dürfen Konten nicht so schnell registrieren" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Keine" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Abonnement" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "anhängig" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Gruppen" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Validieren" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Entfernen" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Kontaktliste von " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Ungültiges Format" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Jabber-ID hinzufügen" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Kontaktliste" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Gruppen der gemeinsamen Kontaktliste" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Neue hinzufügen" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Name:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Beschreibung:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Mitglieder:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Angezeigte Gruppen:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Gruppe " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Senden" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Geburtsdatum" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Stadt" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Land" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "E-Mail" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Nachname" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Füllen Sie die Felder aus, um nach passenden Jabber-Benutzern zu suchen " "(beenden Sie ein Feld mit *, um auch nach Teilzeichenketten zu suchen)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Vollständiger Name" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Zweiter Vorname" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Vorname" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Organisation" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Abteilung" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Benutzer suchen in " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "" "Sie benötigen einen Client, der x:data unterstützt, um die Suche verwenden " "zu können" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "vCard-Benutzer-Suche" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard-Modul" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Suchergebnisse für " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "" "Füllen Sie die Felder aus, um nach passenden Jabber-Benutzern zu suchen" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Nicht berechtigt" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd Web-Admin" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Verwaltung" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Unformatiert" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "~s Zugangsregel-Konfiguration" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Virtuelle Hosts" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Benutzer" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Letzte Benutzeraktivität" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Zeitraum: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Letzter Monat" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Letztes Jahr" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Alle Aktivitäten" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Normale Tabelle anzeigen" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Vollständige Tabelle anzeigen" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Statistik" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Nicht gefunden" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Knoten nicht gefunden" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Host" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Registrierte Benutzer" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Offline-Nachrichten" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Letzte Aktivität" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Registrierte Benutzer:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Angemeldete Benutzer:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Ausgehende s2s-Verbindungen:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Ausgehende s2s-Server:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Passwort ändern" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Benutzer " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Verbundene Ressourcen:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Passwort:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Keine Daten" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Knoten" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Knoten " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Aktive Ports" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Aktualisieren" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Neustart" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Stoppen" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Fehler bei RPC-Aufruf" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Datenbanktabellen auf " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Speichertyp" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Elemente" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Speicher" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Fehler" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Sicherung von " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Beachten sie, das diese Optionen nur die eingebaute Mnesia-Datenbank " "sichern. Wenn sie das ODBC-Modul verwenden, müssen sie die SQL-Datenbank " "manuell sichern." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Speichere binäre Sicherung:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Stelle binäre Sicherung sofort wieder her:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Stelle binäre Sicherung beim nächsten ejabberd-Neustart wieder her (benötigt " "weniger Speicher):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Speichere Klartext-Sicherung:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Stelle Klartext-Sicherung sofort wieder her:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Benutzerdaten von einer PIEFXIS Datei (XEP-0227) importieren:" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Alle Benutzerdaten des Servers in PIEFXIS Dateien (XEP-0227) exportieren:" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" "Alle Benutzerdaten des Hosts in PIEFXIS Dateien (XEP-0227) exportieren:" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importiere Benutzer von jabberd14 Spool Datei:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importiere Benutzer von jabberd14 Spool Verzeichnis:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Aktive Ports bei" #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Module bei " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Statistiken von ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Betriebszeit:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "CPU-Zeit:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Durchgeführte Transaktionen:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Abgebrochene Transaktionen:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Neu gestartete Transaktionen:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Protokollierte Transaktionen:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Aktualisierung " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Aktualisierungsplan" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Geänderte Module" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Aktualisierungsscript" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Low level Aktualisierungsscript" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Script-Überprüfung" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Port" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protokoll" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Modul" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Optionen" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Löschen" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Starten" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Ihr Jabber Konto wurde erfolgreich erstellt." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Es trat ein Fehler beim erstellen des Kontos auf:" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Ihr Jabber Konto wurde erfolgreich gelöscht." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Es trat ein Fehler beim Löschen des Kontos auf:" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Das Passwort von ihrem Jabber Konto wurde geändert." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Es trat ein Fehler beim Ändern des Passworts auf:" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Jabber Konto Anmeldung" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Jabber Konto registrieren" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Jabber Konto entfernen" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Diese Seite erlaubt das anlegen eines Jabber Kontos auf diesem Jabber " "Server. Ihre JID (Jabber IDentifier) setzt sich folgend zusammen: " "benutzername@server. Bitte lesen sie die Hinweise genau durch, um die Felder " "korrekt auszufüllen." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Benutzername:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Groß/Klein-Schreibung spielt hierbei keine Rolle: macbeth ist gleich MacBeth " "und Macbeth." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Nicht erlaubte Zeichen:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Server:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "Geben sie niemandem ihr Passwort, auch nicht den Administratoren des Jabber " "Servers." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" "Sie können das Passwort später mit einem Jabber Client Programm ändern." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Einige Jabber Client Programme speichern ihr Passwort auf ihrem Computer. " "Verwenden sie diese Möglichkeit nur auf Computern, die sie als sicher " "einstufen." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Merken sie sich ihr Passwort, oder schreiben sie es auf einen Zettel den sie " "sicher verwahren. Bei Jabber gibt es keine automatische Möglichkeit, das " "Passwort wiederherzustellen." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Passwort bestätigen:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Anmelden" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Aktuelles Passwort:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Neues Passwort:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" "Diese Seite erlaubt es, ein Jabber Konto von diesem Server zu entfernen." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Abmelden" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "Die Verifizierung ist gültig." ejabberd-2.1.11/src/msgs/gl.msg0000664000000000000000000005452412240230175013102 0ustar {"Access Configuration","Configuración de accesos"}. {"Access Control List Configuration","Configuración da Lista de Control de Acceso"}. {"Access control lists","Listas de Control de Acceso"}. {"Access Control Lists","Listas de Control de Acceso"}. {"Access denied by service policy","Acceso denegado pola política do servizo"}. {"Access rules","Regras de acceso"}. {"Access Rules","Regras de Acceso"}. {"Action on user","Acción no usuario"}. {"Add Jabber ID","Engadir ID Jabber"}. {"Add New","Engadir novo"}. {"Add User","Engadir usuario"}. {"Administration","Administración"}. {"Administration of ","Administración de "}. {"Administrator privileges required","Necesítase privilexios de administrador"}. {"A friendly name for the node","Un nome para o nodo"}. {"All activity","Toda a actividade"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Desexas permitir a este JabberID que se subscriba a este nodo PubSub?"}. {"Allow users to change the subject","Permitir aos usuarios cambiar o asunto"}. {"Allow users to query other users","Permitir aos usuarios consultar a outros usuarios"}. {"Allow users to send invites","Permitir aos usuarios enviar invitacións"}. {"Allow users to send private messages","Permitir aos usuarios enviar mensaxes privadas"}. {"Allow visitors to change nickname","Permitir aos visitantes cambiarse o alcume"}. {"Allow visitors to send status text in presence updates","Permitir aos visitantes enviar texto de estado nas actualizacións depresenza"}. {"All Users","Todos os usuarios"}. {"Announcements","Anuncios"}. {"anyone","calquera"}. {"A password is required to enter this room","Necesítase contrasinal para entrar nesta sala"}. {"April","Abril"}. {"August","Agosto"}. {"Backup","Gardar copia de seguridade"}. {"Backup Management","Xestión de copia de seguridade"}. {"Backup of ","Copia de seguridade de "}. {"Backup to File at ","Copia de seguridade de arquivos en "}. {"Bad format","Mal formato"}. {"Birthday","Aniversario"}. {"Change Password","Cambiar contrasinal"}. {"Change User Password","Cambiar contrasinal de usuario"}. {"Chatroom configuration modified","Configuración de la sala modificada"}. {"Chatrooms","Salas de charla"}. {"Choose a username and password to register with this server","Escolle un nome de usuario e contrasinal para rexistrarche neste servidor"}. {"Choose modules to stop","Selecciona módulos a deter"}. {"Choose storage type of tables","Selecciona tipo de almacenamento das táboas"}. {"Choose whether to approve this entity's subscription.","Decidir se aprobar a subscripción desta entidade."}. {"City","Cidade"}. {"Commands","Comandos"}. {"Conference room does not exist","A sala de conferencias non existe"}. {"Configuration","Configuración"}. {"Configuration of room ~s","Configuración para a sala ~s"}. {"Connected Resources:","Recursos conectados:"}. {"Connections parameters","Parámetros de conexiones"}. {"Country","País"}. {"CPU Time:","Tempo consumido de CPU:"}. {"Database","Base de datos"}. {"Database Tables at ","Táboas da base de datos en "}. {"Database Tables Configuration at ","Configuración de táboas da base de datos en "}. {"December","Decembro"}. {"Default users as participants","Os usuarios son participantes por defecto"}. {"Delete","Eliminar"}. {"Delete message of the day","Borrar mensaxe do dia"}. {"Delete message of the day on all hosts","Borrar a mensaxe do día en todos os dominios"}. {"Delete Selected","Eliminar os seleccionados"}. {"Delete User","Borrar usuario"}. {"Deliver event notifications","Entregar notificacións de eventos"}. {"Deliver payloads with event notifications","Enviar payloads xunto coas notificacións de eventos"}. {"Description:","Descrición:"}. {"Disc only copy","Copia en disco soamente"}. {"Displayed Groups:","Mostrar grupos:"}. {"Dump Backup to Text File at ","Exporta copia de seguridade a ficheiro de texto en "}. {"Dump to Text File","Exportar a ficheiro de texto"}. {"Edit Properties","Editar propiedades"}. {"ejabberd IRC module","Módulo de IRC para ejabberd"}. {"ejabberd MUC module","Módulo de MUC para ejabberd"}. {"ejabberd Publish-Subscribe module","Módulo de Publicar-Subscribir de ejabberd"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}. {"ejabberd vCard module","Módulo vCard para ejabberd"}. {"ejabberd Web Admin","Ejabberd Administrador Web"}. {"Elements","Elementos"}. {"Email","Email"}. {"Enable logging","Gardar históricos"}. {"Encoding for server ~b","Codificación de servidor ~b"}. {"End User Session","Pechar sesión de usuario"}. {"Enter list of {Module, [Options]}","Introduce lista de {Módulo, [Opcións]}"}. {"Enter nickname you want to register","Introduce o alcume que queiras rexistrar"}. {"Enter path to backup file","Introduce ruta ao ficheiro de copia de seguridade"}. {"Enter path to jabberd14 spool dir","Introduce a ruta ao directorio de jabberd14 spools"}. {"Enter path to jabberd14 spool file","Introduce ruta ao ficheiro jabberd14 spool"}. {"Enter path to text file","Introduce ruta ao ficheiro de texto"}. {"Enter the text you see","Introduza o texto que ves"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Introduce o nome de usuario e codificaciones de carácteres que queiras usar ao conectar nos servidores de IRC. Presione 'Siguiente' para obtener más campos para rellenar Presione 'completo' para guardar axustes."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Introduza o nome de usuario, codificaciones de carácter, portos e contrasinal que pretende utilizar a conectar a servidores de IRC"}. {"Erlang Jabber Server","Servidor Jabber en Erlang"}. {"Error","Erro"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Exemplo: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exportar datos de todos os usuarios do servidor a ficheros PIEFXIS (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Exportar datos de todos os usuarios do servidor a ficheros PIEFXIS (XEP-0227):"}. {"Family Name","Apelido"}. {"February","Febreiro"}. {"Fill in fields to search for any matching Jabber User","Rechea campos para buscar usuarios Jabber que concuerden"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Enche o formulario para buscar usuarios Jabber. Engade * ao final dun campo para buscar subcadenas."}. {"Friday","Venres"}. {"From","De"}. {"From ~s","De ~s"}. {"Full Name","Nome completo"}. {"Get Number of Online Users","Ver número de usuarios conectados"}. {"Get Number of Registered Users","Ver número de usuarios rexistrados"}. {"Get User Last Login Time","Ver data da última conexión de usuario"}. {"Get User Password","Ver contrasinal de usuario"}. {"Get User Statistics","Ver estatísticas de usuario"}. {"Group ","Grupo "}. {"Groups","Grupos"}. {"has been banned","foi bloqueado"}. {"has been kicked because of an affiliation change","foi expulsado debido a un cambio de afiliación"}. {"has been kicked because of a system shutdown","foi expulsado por mor dun sistema de peche"}. {"has been kicked because the room has been changed to members-only","foi expulsado, porque a sala cambiouse a só-membros"}. {"has been kicked","foi expulsado"}. {" has set the subject to: "," puxo o asunto: "}. {"Host","Host"}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Se quere especificar codificaciones de caracteres diferentes, contrasinal ou servidor IRC rechea esta lista con valores no formato '{\"servidor irc\", \"codificación\", \"porto\", \"contrasinal\"}'. Este servizo utiliza por defecto a codificación \"~s\", porto ~p, sen contrasinal."}. {"Import Directory","Importar directorio"}. {"Import File","Importar ficheiro"}. {"Import user data from jabberd14 spool file:","Importar usuario de fichero spool de jabberd14:"}. {"Import User from File at ","Importa usuario desde ficheiro en "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importar usuarios desde un fichero PIEFXIS"}. {"Import users data from jabberd14 spool directory:","Importar usuarios do directorio spool de jabberd14:"}. {"Import Users from Dir at ","Importar usuarios desde o directorio en "}. {"Import Users From jabberd14 Spool Files","Importar usuarios de ficheiros spool de jabberd-1.4"}. {"Improper message type","Tipo de mensaxe incorrecta"}. {"Incorrect password","Contrasinal incorrecta"}. {"Invalid affiliation: ~s","Afiliación non válida: ~s"}. {"Invalid role: ~s","Rol non válido: ~s"}. {"IP addresses","Direccións IP"}. {"IP","IP"}. {"IRC channel (don't put the first #)","Canle de IRC (non poñer o primeiro #)"}. {"IRC server","Servidor IRC"}. {"IRC settings","IRC axustes"}. {"IRC Transport","Transporte IRC"}. {"IRC username","Nome de usuario en IRC"}. {"IRC Username","Nome de usuario en IRC"}. {"is now known as","cámbiase o nome a"}. {"It is not allowed to send private messages","Non está permitido enviar mensaxes privadas"}. {"It is not allowed to send private messages of type \"groupchat\"","Non está permitido enviar mensaxes privadas do tipo \"groupchat\""}. {"It is not allowed to send private messages to the conference","Impedir o envio de mensaxes privadas á sala"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","O Jabber ID ~s non é válido"}. {"January","Xaneiro"}. {"Join IRC channel","Entrar en canle IRC"}. {"joins the room","entra en la sala"}. {"Join the IRC channel here.","Únete á canle de IRC aquí."}. {"Join the IRC channel in this Jabber ID: ~s","Únete á canle de IRC con este IDE de Jabber: ~s"}. {"July","Xullo"}. {"June","Xuño"}. {"Last Activity","Última actividade"}. {"Last login","Última conexión"}. {"Last month","Último mes"}. {"Last year","Último ano"}. {"leaves the room","sae da sala"}. {"Listened Ports at ","Portos de escoita en "}. {"Listened Ports","Portos de escoita"}. {"List of modules to start","Lista de módulos a iniciar"}. {"Low level update script","Script de actualización a baixo nivel"}. {"Make participants list public","A lista de participantes é pública"}. {"Make room CAPTCHA protected","Protexer a sala con CAPTCHA"}. {"Make room members-only","Sala só para membros"}. {"Make room moderated","Facer sala moderada"}. {"Make room password protected","Protexer a sala con contrasinal"}. {"Make room persistent","Sala permanente"}. {"Make room public searchable","Sala publicamente visible"}. {"March","Marzo"}. {"Maximum Number of Occupants","Número máximo de ocupantes"}. {"Max # of items to persist","Máximo # de elementos que persisten"}. {"Max payload size in bytes","Máximo tamaño do payload en bytes"}. {"May","Maio"}. {"Membership is required to enter this room","Necesitas ser membro desta sala para poder entrar"}. {"Members:","Membros:"}. {"Memory","Memoria"}. {"Message body","Corpo da mensaxe"}. {"Middle Name","Segundo nome"}. {"Moderator privileges required","Necesítase privilexios de moderador"}. {"moderators only","só moderadores"}. {"Modified modules","Módulos Modificados"}. {"Module","Módulo"}. {"Modules at ","Módulos en "}. {"Modules","Módulos"}. {"Monday","Luns"}. {"Name:","Nome:"}. {"Name","Nome"}. {"Never","Nunca"}. {"Nickname","Alcume"}. {"Nickname Registration at ","Rexistro do alcume en "}. {"Nickname ~s does not exist in the room","O alcume ~s non existe na sala"}. {"No body provided for announce message","Non se proporcionou corpo de mensaxe para o anuncio"}. {"No Data","Sen datos"}. {"Node ID","Nodo IDE"}. {"Node ","Nodo "}. {"Node not found","Nodo non atopado"}. {"Nodes","Nodos"}. {"No limit","Sen límite"}. {"None","Ningún"}. {"No resource provided","Non se proporcionou recurso"}. {"Not Found","Non atopado"}. {"Notify subscribers when items are removed from the node","Notificar subscriptores cando os elementos bórranse do nodo"}. {"Notify subscribers when the node configuration changes","Notificar subscriptores cando cambia a configuración do nodo"}. {"Notify subscribers when the node is deleted","Notificar subscriptores cando o nodo bórrase"}. {"November","Novembro"}. {"Number of occupants","Número de ocupantes"}. {"Number of online users","Número de usuarios conectados"}. {"Number of registered users","Número de usuarios rexistrados"}. {"October","Outubro"}. {"Offline Messages","Mensaxes diferidas"}. {"Offline Messages:","Mensaxes sen conexión:"}. {"OK","Aceptar"}. {"Online","Conectado"}. {"Online Users:","Usuarios conectados:"}. {"Online Users","Usuarios conectados"}. {"Only deliver notifications to available users","Só enviar notificacións aos usuarios dispoñibles"}. {"Only moderators and participants are allowed to change the subject in this room","Só os moderadores e os participantes se lles permite cambiar o tema nesta sala"}. {"Only moderators are allowed to change the subject in this room","Só os moderadores están autorizados a cambiar o tema nesta sala"}. {"Only occupants are allowed to send messages to the conference","Só os ocupantes poden enviar mensaxes á sala"}. {"Only occupants are allowed to send queries to the conference","Só os ocupantes poden enviar solicitudes á sala"}. {"Only service administrators are allowed to send service messages","Só os administradores do servizo teñen permiso para enviar mensaxes de servizo"}. {"Options","Opcións"}. {"Organization Name","Nome da organización"}. {"Organization Unit","Unidade da organización"}. {"Outgoing s2s Connections:","Conexións S2S saíntes:"}. {"Outgoing s2s Connections","Conexións S2S saíntes"}. {"Outgoing s2s Servers:","Servidores S2S saíntes:"}. {"Owner privileges required","Requírense privilexios de propietario da sala"}. {"Packet","Paquete"}. {"Password ~b","Contrasinal ~b"}. {"Password:","Contrasinal:"}. {"Password","Contrasinal"}. {"Password Verification","Verificación da contrasinal"}. {"Path to Dir","Ruta ao directorio"}. {"Path to File","Ruta ao ficheiro"}. {"Pending","Pendente"}. {"Period: ","Periodo: "}. {"Persist items to storage","Persistir elementos ao almacenar"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Ten en conta que estas opcións só farán copia de seguridade da base de datos Mnesia. Se está a utilizar o módulo de ODBC, tamén necesita unha copia de seguridade da súa base de datos SQL por separado."}. {"Pong","Pong"}. {"Port ~b","Porto ~b"}. {"Port","Porto"}. {"Present real Jabber IDs to","Os Jabber ID reais poden velos"}. {"private, ","privado"}. {"Protocol","Protocolo"}. {"Publish-Subscribe","Publicar-Subscribir"}. {"PubSub subscriber request","Petición de subscriptor de PubSub"}. {"Queries to the conference members are not allowed in this room","Nesta sala non se permiten solicitudes aos membros da sala"}. {"RAM and disc copy","Copia en RAM e disco"}. {"RAM copy","Copia en RAM"}. {"Raw","Cru"}. {"Really delete message of the day?","Está seguro de quere borrar a mensaxe do dia?"}. {"Recipient is not in the conference room","O receptor non está na sala de conferencia"}. {"Registered Users:","Usuarios rexistrados:"}. {"Registered Users","Usuarios rexistrados"}. {"Registration in mod_irc for ","Rexistro en mod_irc para"}. {"Remote copy","Copia remota"}. {"Remove All Offline Messages","Borrar Todas as Mensaxes Sen conexión"}. {"Remove","Borrar"}. {"Remove User","Eliminar usuario"}. {"Replaced by new connection","Substituído por unha nova conexión"}. {"Resources","Recursos"}. {"Restart","Reiniciar"}. {"Restart Service","Reiniciar o servizo"}. {"Restore Backup from File at ","Restaura copia de seguridade desde o ficheiro en "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Restaurar copia de seguridade binaria no seguinte reinicio de ejabberd (require menos memoria que se instantánea):"}. {"Restore binary backup immediately:","Restaurar inmediatamente copia de seguridade binaria:"}. {"Restore plain text backup immediately:","Restaurar copias de seguridade de texto plano inmediatamente:"}. {"Restore","Restaurar"}. {"Room Configuration","Configuración da Sala"}. {"Room creation is denied by service policy","Denegar crear a sala por política do servizo"}. {"Room description","Descrición da sala"}. {"Room Occupants","Ocupantes da sala"}. {"Room title","Título da sala"}. {"Roster groups allowed to subscribe","Lista de grupos autorizados a subscribir"}. {"Roster","Lista de contactos"}. {"Roster of ","Lista de contactos de "}. {"Roster size","Tamaño da lista de contactos"}. {"RPC Call Error","Erro na chamada RPC"}. {"Running Nodes","Nodos funcionando"}. {"~s access rule configuration","Configuración das Regra de Acceso ~s"}. {"Saturday","Sábado"}. {"Script check","Comprobación de script"}. {"Search Results for ","Buscar resultados por "}. {"Search users in ","Buscar usuarios en "}. {"Send announcement to all online users","Enviar anuncio a todos los usuarios conectados"}. {"Send announcement to all online users on all hosts","Enviar anuncio a todos os usuarios conectados en todos os dominios"}. {"Send announcement to all users","Enviar anuncio a todos os usuarios"}. {"Send announcement to all users on all hosts","Enviar anuncio a todos os usuarios en todos os dominios"}. {"September","Setembro"}. {"Server ~b","Servidor ~b"}. {"Set message of the day and send to online users","Pór mensaxe do dia e enviar a todos os usuarios conectados"}. {"Set message of the day on all hosts and send to online users","Pór mensaxe do día en todos os dominios e enviar aos usuarios conectados"}. {"Shared Roster Groups","Grupos Compartidos"}. {"Show Integral Table","Mostrar Táboa Integral"}. {"Show Ordinary Table","Mostrar Táboa Ordinaria"}. {"Shut Down Service","Deter o servizo"}. {"~s invites you to the room ~s","~s invítache á sala ~s"}. {"Specify the access model","Especifica o modelo de acceso"}. {"Specify the publisher model","Especificar o modelo do publicante"}. {"~s's Offline Messages Queue","Cola de mensaxes diferidas de ~s"}. {"Start","Iniciar"}. {"Start Modules at ","Iniciar módulos en "}. {"Start Modules","Iniciar módulos"}. {"Statistics","Estatísticas"}. {"Statistics of ~p","Estatísticas de ~p"}. {"Stop","Deter"}. {"Stop Modules at ","Deter módulos en "}. {"Stop Modules","Detener módulos"}. {"Stopped Nodes","Nodos detidos"}. {"Storage Type","Tipo de almacenamiento"}. {"Store binary backup:","Gardar copia de seguridade binaria:"}. {"Store plain text backup:","Gardar copia de seguridade en texto plano:"}. {"Subject","Asunto"}. {"Submit","Enviar"}. {"Submitted","Enviado"}. {"Subscriber Address","Dirección do subscriptor"}. {"Subscription","Subscripción"}. {"Sunday","Domingo"}. {"That nickname is already in use by another occupant","Ese alcume que xa está en uso por outro ocupante"}. {"That nickname is registered by another person","O alcume xa está rexistrado por outra persoa"}. {"The CAPTCHA is valid.","O CAPTCHA é válido."}. {"The collections with which a node is affiliated","As coleccións coas que un nodo está afiliado"}. {"the password is","a contrasinal é"}. {"This participant is kicked from the room because he sent an error message","Este participante é expulsado da sala, xa que enviou unha mensaxe de erro"}. {"This participant is kicked from the room because he sent an error message to another participant","Este participante é expulsado da sala, porque el enviou unha mensaxe de erro a outro participante"}. {"This participant is kicked from the room because he sent an error presence","Este participante é expulsado da sala, porque el enviou un erro de presenza"}. {"This room is not anonymous","Sala non anónima"}. {"Thursday","Xoves"}. {"Time","Data"}. {"Time delay","Atraso temporal"}. {"To","Para"}. {"To ~s","A ~s"}. {"Traffic rate limit is exceeded","Hase exedido o límite de tráfico"}. {"Transactions Aborted:","Transaccións abortadas:"}. {"Transactions Committed:","Transaccións finalizadas:"}. {"Transactions Logged:","Transaccións rexistradas:"}. {"Transactions Restarted:","Transaccións reiniciadas:"}. {"Tuesday","Martes"}. {"Unauthorized","Non autorizado"}. {"Update ","Actualizar"}. {"Update","Actualizar"}. {"Update message of the day (don't send)","Actualizar mensaxe do dia, pero non envialo"}. {"Update message of the day on all hosts (don't send)","Actualizar a mensaxe do día en todos os dominos (pero non envialo)"}. {"Update plan","Plan de actualización"}. {"Update script","Script de actualización"}. {"Uptime:","Tempo desde o inicio:"}. {"Use of STARTTLS required","É obrigatorio usar STARTTLS"}. {"User Management","Administración de usuarios"}. {"Users are not allowed to register accounts so quickly","Os usuarios non están autorizados a rexistrar contas con tanta rapidez"}. {"Users Last Activity","Última actividade dos usuarios"}. {"Users","Usuarios"}. {"User ","Usuario "}. {"User","Usuario"}. {"Validate","Validar"}. {"vCard User Search","Procura de usuario en vCard"}. {"Virtual Hosts","Hosts Virtuais"}. {"Visitors are not allowed to change their nicknames in this room","Os visitantes non están autorizados a cambiar os seus That alcumes nesta sala"}. {"Visitors are not allowed to send messages to all occupants","Os visitantes non poden enviar mensaxes a todos os ocupantes"}. {"Wednesday","Mércores"}. {"When to send the last published item","Cando enviar o último elemento publicado"}. {"Whether to allow subscriptions","Permitir subscripciones"}. {"You have been banned from this room","fuches bloqueado nesta sala"}. {"You must fill in field \"Nickname\" in the form","Debes encher o campo \"Alcumo\" no formulario"}. {"You need an x:data capable client to configure mod_irc settings","Necesitas un cliente con soporte de x:data para configurar as opcións de mod_irc"}. {"You need an x:data capable client to configure room","Necesitas un cliente con soporte de x:data para configurar a sala"}. {"You need an x:data capable client to search","Necesitas un cliente con soporte de x:data para poder buscar"}. {"Your contact offline message queue is full. The message has been discarded.","A túa cola de mensaxes diferidas de contactos está chea. A mensaxe descartouse."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","As súas mensaxes a ~s encóntranse bloqueadas. Para desbloquear, visite ~s"}. ejabberd-2.1.11/src/msgs/it.po0000664000000000000000000015745412240230175012752 0ustar # Luca Brivio , 2012. msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "PO-Revision-Date: 2012-04-24 16:48+0200\n" "Last-Translator: Luca Brivio \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Italian (italiano)\n" "X-Additional-Translator: Gabriele Stilli \n" "X-Additional-Translator: Smart2128\n" "X-Generator: Lokalize 1.2\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Utilizzo di STARTTLS obbligatorio" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Nessuna risorsa fornita" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Sostituito da una nuova connessione" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" "In base alla tua attuale lista privacy questa stanza è stata esclusa dalla " "navigazione." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Immettere il testo visibile" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "I messaggi verso ~s sono bloccati. Per sbloccarli, visitare ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "Se qui non vedi l'immagine CAPTCHA, visita la pagina web." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "Pagina web CAPTCHA" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "Il CAPTCHA è valido." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Comandi" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Si conferma l'eliminazione del messaggio del giorno (MOTD)?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Oggetto" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Corpo del messaggio" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Nessun corpo fornito per il messaggio di annuncio" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Annunci" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Inviare l'annuncio a tutti gli utenti" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Inviare l'annuncio a tutti gli utenti su tutti gli host" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Inviare l'annuncio a tutti gli utenti online" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Inviare l'annuncio a tutti gli utenti online su tutti gli host" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "" "Impostare il messaggio del giorno (MOTD) ed inviarlo agli utenti online" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Impostare il messaggio del giorno (MOTD) su tutti gli host e inviarlo agli " "utenti online" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Aggiornare il messaggio del giorno (MOTD) (non inviarlo)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "" "Aggiornare il messaggio del giorno (MOTD) su tutti gli host (non inviarlo)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Eliminare il messaggio del giorno (MOTD)" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Eliminare il messaggio del giorno (MOTD) su tutti gli host" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Configurazione" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Database" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Avviare moduli" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Arrestare moduli" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Salvare" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Recuperare" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Trascrivere su file di testo" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Importare un file" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Importare una directory" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Riavviare il servizio" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Terminare il servizio" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Aggiungere un utente" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Eliminare l'utente" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Terminare la sessione dell'utente" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Ottenere la password dell'utente" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Cambiare la password dell'utente" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Ottenere la data di ultimo accesso dell'utente" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Ottenere le statistiche dell'utente" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Ottenere il numero di utenti registrati" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Ottenere il numero di utenti online" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Diritti di accesso (ACL)" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Regole di accesso" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Gestione degli utenti" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Utenti online" #: mod_configure.erl:501 msgid "All Users" msgstr "Tutti gli utenti" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Connessioni s2s in uscita" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Nodi attivi" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Nodi arrestati" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Moduli" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Gestione dei salvataggi" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importare utenti da file di spool di jabberd14" #: mod_configure.erl:699 msgid "To ~s" msgstr "A ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Da ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Configurazione delle tabelle del database su " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Selezionare una modalità di conservazione delle tabelle" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Copia su disco soltanto" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Copia in memoria (RAM) e su disco" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Copia in memoria (RAM)" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Copia remota" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Arrestare moduli su " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Selezionare i moduli da arrestare" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Avviare moduli su " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Immettere un elenco di {Modulo, [Opzioni]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Elenco dei moduli da avviare" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Salvataggio sul file " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Immettere il percorso del file di salvataggio" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Percorso del file" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Recuperare il salvataggio dal file " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Trascrivere il salvataggio sul file di testo " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Immettere il percorso del file di testo" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importare un utente dal file " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Immettere il percorso del file di spool di jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importare utenti dalla directory " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Immettere il percorso della directory di spool di jabberd14" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Percorso della directory" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Ritardo" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Configurazione dei diritti di accesso (ACL)" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Diritti di accesso (ACL)" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Configurazione dell'accesso" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Regole di accesso" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID (Jabber ID)" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Password" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Verifica della password" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Numero di utenti registrati" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Numero di utenti online" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Mai" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Online" #: mod_configure.erl:1701 msgid "Last login" msgstr "Ultimo accesso" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Dimensione della lista dei contatti" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "Indirizzi IP" #: mod_configure.erl:1724 msgid "Resources" msgstr "Risorse" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Amministrazione di " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Azione sull'utente" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Modificare le proprietà" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Eliminare l'utente" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Accesso impedito dalle politiche del servizio" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "Transport IRC" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "Modulo IRC per ejabberd" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "Per la configurazione del modulo IRC è necessario un client che supporti x:" "data" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Registrazione in mod_irc per " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Immettere il nome utente, le codifiche, le porte e le password che si " "desidera utilizzare per la connessione ai server IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Nome utente IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Se si vogliono specificare differenti porte, password, codifiche per i " "server IRC, si riempia questo elenco con valori nel formato '{\"server IRC" "\", \"codifica\", porta, \"password\"}'. Per default questo servizio " "utilizza la codifica \"~s\", la porta ~p, la password vuota." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Esempio: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"segreto\"}, {\"vendetta." "fef.net\", \"iso8859-1\", 7000}, {\"irc.serverdiprova.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Parametri delle connessioni" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Entra nel canale IRC" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "Canale IRC (senza il # iniziale)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "Server IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Entra nel canale IRC qui." #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Entra nel canale IRC in questo ID Jabber: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "Impostazioni IRC" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Immettere il nome utente e le codifiche che si desidera utilizzare per la " "connessione ai server IRC. Premere \"Avanti\" per vedere i successivi campi " "da compilare. Premere \"Fatto\" per salvare le impostazioni." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "Nome utente IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Password ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Porta ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Codifica per il server ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Server ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" "L'invio di messaggi di servizio è consentito solamente agli amministratori " "del servizio" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "La creazione di stanze è impedita dalle politiche del servizio" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "La stanza per conferenze non esiste" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Stanze" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "Per registrare il nickname è necessario un client che supporti x:data" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Registrazione di un nickname su " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Immettere il nickname che si vuole registrare" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Nickname" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Questo nickname è registrato da un'altra persona" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Si deve riempire il campo \"Nickname\" nel modulo" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "Modulo MUC per ejabberd" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Configurazione della stanza modificata" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "entra nella stanza" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "esce dalla stanza" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "è stata/o bandita/o" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "è stata/o espulsa/o" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "è stato espulso a causa di un cambiamento di appartenenza" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "è stato espulso per la limitazione della stanza ai soli membri" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "è stato espulso a causa dello spegnimento del sistema" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "è ora conosciuta/o come" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " ha modificato l'oggetto in: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "La stanza è creata" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "La stanza è eliminata" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "La stanza è avviata" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "La stanza è arrestata" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Lunedì" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Martedì" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Mercoledì" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Giovedì" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Venerdì" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Sabato" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Domenica" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Gennaio" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Febbraio" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Marzo" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "Aprile" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Maggio" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Giugno" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Luglio" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Agosto" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "Settembre" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Ottobre" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "Novembre" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "Dicembre" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Configurazione della stanza" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Presenti nella stanza" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Limite di traffico superato" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Partecipante espulso dalla stanza perché ha inviato un messaggio non valido" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Non è consentito l'invio di messaggi privati alla conferenza" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "Attendi qualche istante prima di inviare una nuova richiesta di parola" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "In questa conferenza le richieste di parola sono escluse" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" "Impossibile estrarre il JID dall'approvazione della richiesta di parola" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Soltanto i moderatori possono approvare richieste di parola" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Tipo di messaggio non corretto" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Partecipante espulso dalla stanza perché ha inviato un messaggio non valido " "a un altro partecipante" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "Non è consentito l'invio di messaggi privati di tipo \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Il destinatario non è nella stanza per conferenze" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Non è consentito l'invio di messaggi privati" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "L'invio di messaggi alla conferenza è consentito soltanto ai presenti" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "L'invio di query alla conferenza è consentito ai soli presenti" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "In questa stanza non sono consentite query ai membri della conferenza" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "La modifica dell'oggetto di questa stanza è consentita soltanto ai " "moderatori e ai partecipanti" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "" "La modifica dell'oggetto di questa stanza è consentita soltanto ai moderatori" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Non è consentito ai visitatori l'invio di messaggi a tutti i presenti" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Partecipante espulso dalla stanza perché ha inviato una presenza non valido" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Non è consentito ai visitatori cambiare il nickname in questa stanza" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Il nickname è già in uso all'interno della conferenza" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Sei stata/o bandita/o da questa stanza" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Per entrare in questa stanza è necessario essere membro" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Questa stanza non è anonima" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Per entrare in questa stanza è prevista una password" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Troppe richieste CAPTCHA" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Impossibile generare un CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Password non esatta" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Necessari i privilegi di amministratore" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Necessari i privilegi di moderatore" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Il Jabber ID ~s non è valido" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Il nickname ~s non esiste nella stanza" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Affiliazione non valida: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Ruolo non valido: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Necessari i privilegi di proprietario" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Configurazione per la stanza ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Titolo della stanza" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Descrizione della stanza" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Rendere la stanza persistente" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Rendere la sala visibile al pubblico" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Rendere pubblica la lista dei partecipanti" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Rendere la stanza protetta da password" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Numero massimo di occupanti" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Nessun limite" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Rendere visibile il Jabber ID reale a" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "moderatori soltanto" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "tutti" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Rendere la stanza riservata ai membri" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Rendere la stanza moderata" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Definire per default gli utenti come partecipanti" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Consentire agli utenti di cambiare l'oggetto" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Consentire agli utenti l'invio di messaggi privati" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "Consentire agli ospiti l'invio di messaggi privati a" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "nessuno" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Consentire agli utenti query verso altri utenti" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Consentire agli utenti l'invio di inviti" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "" "Consentire ai visitatori l'invio di testo sullo stato in aggiornamenti sulla " "presenza" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Consentire ai visitatori di cambiare il nickname" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "Consentire agli ospiti l'invio di richieste di parola" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "Intervallo minimo fra due richieste di parola (in secondi)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Rendere la stanza protetta da CAPTCHA" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Escludi degli ID Jabber dal passaggio CAPTCHA" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Abilitare i log" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "" "Per la configurazione della stanza è necessario un client che supporti x:data" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Numero di presenti" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privato, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Richiesta di parola" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Approva oppure respingi la richiesta di parola." #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "JID utente" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "Dare parola a questa persona?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s ti invita nella stanza ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "la password è" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "La coda dei messaggi offline del contatto è piena. Il messaggio è stato " "scartato" #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "Coda di ~s messaggi offline" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Inviato" #: mod_offline.erl:571 msgid "Time" msgstr "Ora" #: mod_offline.erl:572 msgid "From" msgstr "Da" #: mod_offline.erl:573 msgid "To" msgstr "A" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Pacchetto" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Eliminare gli elementi selezionati" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Messaggi offline:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Eliminare tutti i messaggi offline" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "Modulo SOCKS5 Bytestreams per ejabberd" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Pubblicazione-Iscrizione" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "Modulo Pubblicazione/Iscrizione (PubSub) per ejabberd" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Richiesta di iscrizione per PubSub" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Scegliere se approvare l'iscrizione per questa entità" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ID del nodo" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Indirizzo dell'iscritta/o" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Consentire a questo Jabber ID l'iscrizione a questo nodo pubsub?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Inviare il contenuto del messaggio con la notifica dell'evento" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Inviare notifiche degli eventi" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Notificare gli iscritti quando la configurazione del nodo cambia" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Notificare gli iscritti quando il nodo è cancellato" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Notificare gli iscritti quando sono eliminati degli elementi dal nodo" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Conservazione persistente degli elementi" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Un nome comodo per il nodo" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Numero massimo di elementi da conservare persistentemente" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Consentire iscrizioni?" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Specificare il modello di accesso" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Gruppi roster abilitati alla registrazione" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Definire il modello di pubblicazione" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "" "Cancella tutti gli elementi quando chi li ha pubblicati non è più online" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Specificare il tipo di messaggio di evento" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Dimensione massima del contenuto del messaggio in byte" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Quando inviare l'ultimo elemento pubblicato" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Inviare le notifiche solamente agli utenti disponibili" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Le collezioni a cui è affiliato un nodo" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "La verifica del CAPTCHA ha avuto esito negativo" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "La registrazione richiede un client che supporti x:data e CAPTCHA" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "" "Scegliere un nome utente e una password per la registrazione con questo " "server" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Utente" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "La password è troppo debole" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Non è consentito agli utenti registrare account così rapidamente" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Nessuno" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Iscrizione" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Pendente" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Gruppi" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Validare" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Eliminare" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Lista dei contatti di " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Formato non valido" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Aggiungere un Jabber ID (Jabber ID)" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Lista dei contatti" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Gruppi di liste di contatti comuni" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Aggiungere nuovo" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Nome:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Descrizione:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Membri:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Gruppi visualizzati:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Gruppo " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Inviare" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Compleanno" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Città" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Paese" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "E-mail" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Cognome" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Riempire il modulo per la ricerca di utenti Jabber corrispondenti ai criteri " "(Aggiungere * alla fine del campo per la ricerca di una sottostringa" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Nome completo" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Altro nome" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Nome" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Nome dell'organizzazione" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Unità dell'organizzazione" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Cercare utenti in " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Per effettuare ricerche è necessario un client che supporti x:data" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Ricerca di utenti per vCard" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "Modulo vCard per ejabberd" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Risultati della ricerca per " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "" "Riempire i campi per la ricerca di utenti Jabber corrispondenti ai criteri" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Non autorizzato" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "Amministrazione web ejabberd" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Amministrazione" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Grezzo" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Configurazione delle regole di accesso per ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Host Virtuali" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Utenti" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Ultima attività degli utenti" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Periodo:" #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Ultimo mese" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Ultimo anno" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Tutta l'attività" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Mostrare la tabella normale" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Mostrare la tabella integrale" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Statistiche" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Non trovato" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Nodo non trovato" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Host" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Utenti registrati" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Messaggi offline" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Ultima attività" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Utenti registrati:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Utenti connessi:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Connessioni s2s in uscita:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Server s2s in uscita" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Modificare la password" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Utente " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Risorse connesse:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Password:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Nessuna informazione" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Nodi" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Nodo " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Porte in ascolto" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Aggiornare" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Riavviare" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Arrestare" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Errore di chiamata RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Tabelle del database su " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Tipo di conservazione" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Elementi" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Memoria" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Errore" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Salvataggio di " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "N.B.: Queste opzioni comportano il salvataggio solamente del database " "interno Mnesia. Se si sta utilizzando il modulo ODBC, è necessario salvare " "anche il proprio database SQL separatamente." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Conservare un salvataggio binario:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Recuperare un salvataggio binario adesso:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Recuperare un salvataggio binario dopo il prossimo riavvio di ejabberd " "(necessita di meno memoria):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Conservare un salvataggio come semplice testo:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Recuperare un salvataggio come semplice testo adesso:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Importare i dati utenti da un file PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Esportare i dati di tutti gli utenti nel server in file PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "Esportare i dati degli utenti di un host in file PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importare i dati utente da file di spool di jabberd14:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importare i dati utenti da directory di spool di jabberd14:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Porte in ascolto su " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Moduli su " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Statistiche di ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Tempo dall'avvio:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Tempo CPU:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transazioni avvenute:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transazioni abortite:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transazioni riavviate:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transazioni con log:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Aggiornare " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Piano di aggiornamento" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Moduli modificati" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Script di aggiornamento" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Script di aggiornamento di basso livello" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Verifica dello script" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Porta" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protocollo" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Modulo" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Opzioni" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Eliminare" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Avviare" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "La creazione del tuo account Jabber è andata a buon fine." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Si è verificato un errore nella creazione dell'account: " #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "La cancellazione del tuo account Jabber è andata a buon fine." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Si è verificato un errore nella cancellazione dell'account: " #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Il cambio di password del tuo account Jabber è andato a buon fine." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Si è verificato un errore nel cambio di password: " #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Registrazione account Jabber" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Registra un account Jabber" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Elimina un account Jabber" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Questa pagina consente di creare un account Jabber in questo server Jabber. " "Il tuo JID (Jabber IDentifier) avrà la forma: nome_utente@server. Leggi " "attentamente le istruzioni per compilare i campi correttamente." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Nome utente:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Non fa differenza fra minuscolo e maiuscolo: macbeth, MacBeth e Macbeth si " "equivalgono." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Caratteri non consentiti:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Server:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "Non comunicare la tua password a nessuno, neppure agli amministratori del " "server Jabber." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "Potrai in seguito cambiare la password utilizzando un client Jabber." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Alcuni client Jabber possono conservare la password nel tuo computer. " "Utilizza tale funzione soltanto se ritieni che il tuo computer sia sicuro." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Memorizza la password, o scrivila su un foglio di carta da conservare in un " "luogo sicuro. Jabber non prevede una modalità automatica per il recupero di " "una password dimenticata." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Verifica della password:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Registra" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Vecchia password:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Nuova password:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" "Questa pagina consente di eliminare un account Jabber da questo server " "Jabber." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Elimina" #, fuzzy #~ msgid "CAPTCHA test failed" #~ msgstr "Il CAPTCHA è valido." ejabberd-2.1.11/src/msgs/ja.po0000664000000000000000000016377212240230175012730 0ustar msgid "" msgstr "" "Project-Id-Version: ejabberd 2.1.x\n" "PO-Revision-Date: 2012-04-16 15:48+0900\n" "Last-Translator: Mako N \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Japanese (日本語)\n" "X-Additional-Translator: Tsukasa Hamano \n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "STARTTLS の使用が必要です" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "リソースが提供されませんでした" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "新しいコネクションによって置き換えられました" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "あなたのプライバシーリストはこのスタンザのルーティングを拒否しました。" #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "見えているテキストを入力してください" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "~s 宛のメッセージはブロックされています。解除するにはこちらを見てください ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" "ここに CAPTCHA 画像が表示されない場合、ウェブページを参照してください。" #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "CAPTCHA ウェブページ" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "CAPTCHA は有効です。" #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "コマンド" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "本当にお知らせメッセージを削除しますか ?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "題" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "本文" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "アナウンスメッセージはありませんでした" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "アナウンス" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "すべてのユーザーにアナウンスを送信" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "全ホストのユーザーにアナウンスを送信" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "すべてのオンラインユーザーにアナウンスを送信" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "全ホストのオンラインユーザーにアナウンスを送信" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "お知らせメッセージを設定し、オンラインユーザーに送信" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "全ホストのお知らせメッセージを設定し、オンラインユーザーに送信" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "お知らせメッセージを更新 (送信しない)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "全ホストのお知らせメッセージを更新 (送信しない)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "お知らせメッセージを削除" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "全ホストのお知らせメッセージを削除" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "設定" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "データーベース" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "モジュールを起動" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "モジュールを停止" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "バックアップ" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "リストア" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "テキストファイルに出力" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "ファイルからインポート" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "ディレクトリインポート" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "サービスを再起動" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "サービスを停止" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "ユーザーを追加" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "ユーザーを削除" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "エンドユーザーセッション" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "パスワードを取得" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "パスワードを変更" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "最終ログイン時間を取得" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "ユーザー統計を取得" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "登録ユーザー数を取得" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "オンラインユーザー数を取得" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "アクセスコントロールリスト" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "アクセスルール" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "ユーザー管理" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "オンラインユーザー" #: mod_configure.erl:501 msgid "All Users" msgstr "全ユーザー" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "外向き s2s コネクション" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "起動ノード" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "停止ノード" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "モジュール" #: mod_configure.erl:578 msgid "Backup Management" msgstr "バックアップ管理" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "jabberd14 Spool ファイルからユーザーをインポート" #: mod_configure.erl:699 msgid "To ~s" msgstr "宛先 ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "差出人 ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "データーベーステーブル設定 " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "テーブルのストレージタイプを選択" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "ディスクだけのコピー" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "RAM, ディスクコピー" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "RAM コピー" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "リモートコピー" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "モジュールを停止: " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "停止するモジュールを選択" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "モジュールを開始: " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "{モジュール, [オプション]}のリストを入力してください" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "起動モジュールの一覧" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "ファイルにバックアップ: " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "バックアップファイルのパスを入力してください" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "ファイルのパス" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "ファイルからバックアップをリストア: " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "テキストファイルにバックアップ: " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "テキストファイルのパスを入力してください" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "ファイルからユーザーをインポート: " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "jabberd14 spool ファイルのパスを入力してください" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "ディレクトリからユーザーをインポート: " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "jabberd14 spool ディレクトリのディレクトリを入力してください" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "ディレクトリのパス" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "遅延時間" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "アクセスコントロールリスト設定" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "アクセスコントロールリスト" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "アクセス設定" #: mod_configure.erl:1175 msgid "Access rules" msgstr "アクセスルール" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "パスワード" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "パスワード (確認)" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "登録ユーザー数" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "オンラインユーザー数" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "なし" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "オンライン" #: mod_configure.erl:1701 msgid "Last login" msgstr "最終ログイン" #: mod_configure.erl:1722 msgid "Roster size" msgstr "名簿サイズ" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "IP アドレス" #: mod_configure.erl:1724 msgid "Resources" msgstr "リソース" #: mod_configure.erl:1850 msgid "Administration of " msgstr "管理: " #: mod_configure.erl:1853 msgid "Action on user" msgstr "ユーザー操作" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "プロパティを編集" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "ユーザーを削除" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "サービスポリシーによってアクセスが禁止されました" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC トランスポート" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC module" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "mod_irc の設定には x:data をサポートするクライアントが必要です" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "mod_irc での登録: " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "IRC サーバーに接続先するために使用するユーザー名、文字エンコーディング、ポー" "ト、パスワードを入力してください" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "IRC ユーザー名" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "別のポートやパスワード、文字エンコーディングを使用したい場合、'{\"irc server" "\", \"encoding\", port, \"password\"}' という形式のリストを入力してください。" "デフォルトでエンコーディングは \"~s\" を使用し、ポートは ~p、パスワードは空に" "なっています。" #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "例: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net" "\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "接続パラメーター" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "IRC チャンネルに参加" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "IRC チャンネル (先頭に#は不要)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "IRC サーバー" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "この IRC チャンネルに参加します。" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Jabber ID: ~s でこの IRC チャンネルに参加" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "IRC 設定" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "IRC サーバーに接続先するためのユーザー名と文字エンコーディングを入力してくだ" "さい。'Next' を押して次の項目に進みます。'Complete' を押すと設定が保存されま" "す。" #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "IRC ユーザー名" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "パスワード ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "ポート ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "サーバーのエンコーディング ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "サーバー ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "サービス管理者のみがサービスメッセージを送信できます" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "サービスポリシーによって談話室の作成が禁止されています" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "会議室は存在しません" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "談話室" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "ニックネームを登録するには x:data をサポートするクライアントが必要です" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "ニックネーム登録: " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "登録するニックネームを入力してください" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "ニックネーム" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "ニックネームはほかの人によって登録されています" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "フォームの\"ニックネーム\"欄を入力する必要があります" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC module" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "談話室の設定が変更されました" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "が談話室に参加しました" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "が談話室から退出しました" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "はバンされました" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "はキックされました" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "は分掌が変更されたためキックされました" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "は談話室がメンバー制に変更されたためキックされました" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "はシステムシャットダウンのためキックされました" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "は名前を変更しました: " #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " は題を設定しました: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "談話室を作りました" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "談話室を削除しました" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "談話室を開始しました" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "談話室を停止しました" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "月曜日" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "火曜日" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "水曜日" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "木曜日" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "金曜日" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "土曜日" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "日曜日" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "1月" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "2月" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "3月" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "4月" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "5月" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "6月" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "7月" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "8月" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "9月" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "10月" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "11月" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "12月" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "談話室の設定" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "在室者" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "トラフィックレートの制限を超えました" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "エラーメッセージを送信したため、この参加者はキックされました" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "この会議にプライベートメッセージを送信することはできません" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "新しい発言権の要求を送るまで少し間をおいてください" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "この会議では、発言権の要求はできません" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "発言権要求の承認から JID を取り出すことに失敗しました" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "モデレーターだけが発言権の要求を承認できます" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "誤ったメッセージタイプです" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "他の参加者にエラーメッセージを送信したため、この参加者はキックされました" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "" "種別が\"groupchat\" であるプライベートメッセージを送信することはできません" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "受信者はこの会議室にいません" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "プライベートメッセージを送信することはできません" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "在室者のみがこの会議にメッセージを送ることができます" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "在室者のみが会議にクエリーを送信することができます" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "この談話室では、会議のメンバーへのクエリーは禁止されています" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "モデレーターと参加者のみが談話室の題を変更できます" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "モデレーターのみが談話室の題を変更できます" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "傍聴者はすべての在室者にメッセージを送信することはできません" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "エラープレゼンスを送信したため、この参加者はキックされました" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "傍聴者はこの談話室でニックネームを変更することはできません" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "そのニックネームは既にほかの在室者によって使用されています" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "あなたはこの談話室からバンされています" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "この談話室に入るにはメンバーでなければなりません" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "この談話室は非匿名です" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "この談話室に入るにはパスワードが必要です" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "CAPTCHA 要求が多すぎます" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "CAPTCHA を生成できません" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "パスワードが違います" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "管理者権限が必要です" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "モデレーター権限が必要です" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Jabber ID ~s は無効です" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "ニックネーム ~s はこの談話室にいません" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "無効な分掌です: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "無効な役です: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "主宰者の権限が必要です" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "談話室 ~s の設定" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "談話室のタイトル" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "談話室の説明" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "談話室を永続化" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "談話室を検索可" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "参加者一覧を公開" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "談話室をパスワードで保護" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "最大在室者数" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "制限なし" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "本当の Jabber ID を公開" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "モデレーターにのみ" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "誰にでも" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "談話室をメンバーのみに制限" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "談話室をモデレート化" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "デフォルトのユーザーは参加者" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "ユーザーによる題の変更を許可" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "ユーザーによるプライベートメッセージの送信を許可" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "傍聴者によるプライベートメッセージの送信を次の相手に許可" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "誰にも許可しない" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "ユーザーによる他のユーザーへのクエリーを許可" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "ユーザーによる招待を許可" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "傍聴者によるプレゼンス更新のステータス文の送信を許可" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "傍聴者のニックネームの変更を許可" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "傍聴者による発言権の要求を許可" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "発言権の要求の最小時間間隔 (秒)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "談話室を CAPTCHA で保護" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "CAPTCHA 試験を免除する Jabber ID" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "ロギングを有効" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "談話室を設定するには x:data をサポートするクライアントが必要です" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "在室者の数" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "プライベート、" #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "発言権を要求" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "発言権の要求を承認または却下します。" #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "ユーザー JID" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "この人に発言権を与えますか ?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s はあなたを談話室 ~s に招待しています" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "パスワードは" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "相手先のオフラインメッセージキューが一杯です。このメッセージは破棄されます。" #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "~s' のオフラインメッセージキュー" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "送信完了" #: mod_offline.erl:571 msgid "Time" msgstr "時間" #: mod_offline.erl:572 msgid "From" msgstr "差出人" #: mod_offline.erl:573 msgid "To" msgstr "宛先" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "パケット" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "選択した項目を削除" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "オフラインメッセージ:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "すべてのオフラインメッセージを削除" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestreams モジュール" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Publish-Subscribe" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "ejabberd Publish-Subscribe モジュール" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "PubSub 購読者のリクエスト" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "このエントリを承認するかどうかを選択してください" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ノードID" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "購読者のアドレス" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "この Jabber ID に、この pubsubノードの購読を許可しますか ?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "イベント通知と同時にペイロードを配送する" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "イベント通知を配送する" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "ノード設定に変更があった時に購読者へ通知する" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "ノードが削除された時に購読者へ通知する" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "アイテムがノードから消された時に購読者へ通知する" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "アイテムをストレージに保存する" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "ノードのフレンドリネーム" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "アイテムの最大保存数" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "購読を許可するかどうか" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "アクセスモデルを設定する" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "名簿グループは購読を許可しました" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "公開モデルを指定する" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "公開者がオフラインになるときに、すべてのアイテムを削除" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "イベントメッセージ種別を設定" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "最大ぺイロードサイズ (byte)" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "最後の公開アイテムを送信するタイミングで" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "有効なユーザーにのみ告知を送信する" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "提携されたノードの集合です" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "CAPTCHA 検証は失敗しました" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "登録を行うには x:data と CAPTCHA をサポートするクライアントが必要です" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "サーバーに登録するユーザー名とパスワードを選択してください" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "ユーザー" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "このパスワードは単純過ぎます" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "それほど速くアカウントを登録することはできません" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "なし" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "認可" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "保留" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "グループ" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "検証" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "削除" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "名簿: " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "不正なフォーマット" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Jabber ID を追加" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "名簿" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "共有名簿グループ" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "新規追加" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "名前:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "説明:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "メンバー:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "表示グループ" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "グループ" #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "送信" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "誕生日" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "都道府県" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "国" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "メールアドレス" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "姓" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "欄を埋めて Jabber User を検索してください (* を使用すると部分文字列にマッチし" "ます)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "氏名" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "ミドルネーム" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "名" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "会社名" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "部署名" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "ユーザーの検索: " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "検索を行うためには x:data をサポートするクライアントが必要です" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "vCard ユーザー検索" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard モジュール" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "検索結果: " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "欄を埋めて Jabber User を検索してください" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "認証されていません" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd ウェブ管理" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "管理" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Raw" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "~s アクセスルール設定" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "ヴァーチャルホスト" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "ユーザー" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "ユーザーの活動履歴" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "期間: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "先月" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "去年" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "すべて" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "通常の表を表示" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "累積の表を表示" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "統計" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "見つかりません" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "ノードが見つかりません" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "ホスト" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "登録ユーザー" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "オフラインメッセージ" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "活動履歴" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "登録ユーザー:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "オンラインユーザー:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "外向き s2s コネクション:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "外向き s2s サービス:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "パスワードを変更" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "ユーザー " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "接続リソース:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "パスワード" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "データなし" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "ノード" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "ノード " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Listen ポート" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "更新" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "再起動" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "停止" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "RPC 呼び出しエラー" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "データーベーステーブル: " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "ストレージタイプ" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "要素" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "メモリ" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "エラー" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "バックアップ: " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "これらのオプションは組み込みの Mnesia データーベースのバックアップのみを行う" "ことに注意してください。もし ODBC モジュールを使用している場合は、SQL デー" "ターベースのバックアップを別に行う必要があります。" #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "バイナリバックアップを保存:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "直ちにバイナリバックアップからリストア:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "ejabberd の再起動時にバイナリバックアップからリストア (メモリ少):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "プレーンテキストバックアップを保存:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "直ちにプレーンテキストバックアップからリストア:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "ユーザーデータを PIEFXIS ファイルからインポート (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "サーバーにあるすべてのユーザーデータを PIEFXIS ファイルにエクスポート " "(XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "ホストのユーザーデータを PIEFXIS ファイルにエクスポート (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "ユーザーデータを jabberd14 Spool ファイルからインポート:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "ユーザーデータを jabberd14 Spool ディレクトリからインポート:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Listen ポート " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "モジュール " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "~p の統計" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "起動時間:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "CPU時間:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "トランザクションのコミット:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "トランザクションの失敗:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "トランザクションの再起動:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "トランザクションのログ: " #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "更新 " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "更新計画" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "変更されたモジュール" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "スクリプトの更新" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "低レベル更新スクリプト" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "スクリプトチェック" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "ポート" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "プロトコル" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "モジュール" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "オプション" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "削除" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "開始" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Jabber アカウントの作成に成功しました。" #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "アカウントの作成中にエラーが発生しました: " #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Jabber アカウントの削除に成功しました。" #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "アカウントの削除中にエラーが発生しました: " #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Jabber アカウントのパスワード変更に成功しました。" #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "パスワードの変更中にエラーが発生しました: " #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Jabber アカウント登録" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Jabber アカウントを登録" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Jabber アカウントを削除" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "ここはこの Jabber サーバーにアカウントを作成するページです。あなたの JID " "(JabberID) は username@server のような形式になります。注意事項どおり、正しく" "項目を記入してください。" #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "ユーザー名:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "大文字と小文字は区別しません: macbeth は MacBeth や Macbeth と同じです。" #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "使用できない文字:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "サーバー:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "パスワードは誰にも教えないようにしてください。Jabber サーバーの管理者があなた" "にパスワードを尋ねることはありません。" #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "あなたは後で Jabber クライアントを使用してパスワードを変更できます。" #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Jabber クライアントはコンピューターにパスワードを記憶できます。コンピューター" "が安全であると信頼できる場合にのみ、この機能を使用してください。" #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "パスワードは記憶するか、紙に書いて安全な場所に保管してください。もしあなたが" "パスワードを忘れてしまった場合、Jabber ではパスワードのリカバリを自動的に行う" "ことはできません。" #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "パスワード (確認):" #: web/mod_register_web.erl:250 msgid "Register" msgstr "登録" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "古いパスワード:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "新しいパスワード:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "ここはこの Jabber サーバーのアカウントを削除するページです。" #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "削除" #~ msgid "ejabberd virtual hosts" #~ msgstr "ejabberd ヴァーチャルホスト" #~ msgid "Captcha test failed" #~ msgstr "キャプチャのテストに失敗しました" #~ msgid "Encodings" #~ msgstr "エンコーディング" #~ msgid "(Raw)" #~ msgstr "(Raw)" #~ msgid "Specified nickname is already registered" #~ msgstr "指定されたニックネームは既に登録されています" #~ msgid "Size" #~ msgstr "サイズ" ejabberd-2.1.11/src/msgs/pt-br.po0000664000000000000000000015567112240230175013361 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "Last-Translator: Otávio Fernandes\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Portuguese (Brazil)\n" "X-Additional-Translator: Renato Botelho\n" "X-Additional-Translator: Lucius Curado\n" "X-Additional-Translator: Felipe Brito Vasconcellos\n" "X-Additional-Translator: Victor Hugo dos Santos\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "É obrigatório uso de STARTTLS" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Nenhum recurso foi informado" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Substituído por nova conexão" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "Sua lista de privacidade ativa negou o roteamento deste." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Insira o texto que você vê" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "Suas mensagens para ~s estão bloqueadas. Para desbloquea-las, visite: ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "O CAPTCHA é inválido." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Comandos" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Deletar realmente a mensagem do dia?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Assunto" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Corpo da mensagem" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Nenhum corpo de texto fornecido para anunciar mensagem" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Anúncios" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Enviar anúncio a todos os usuários" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Enviar aviso para todos os usuários em todos os hosts" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Enviar anúncio a todos os usuárions online" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Enviar anúncio a todos usuários online em todas as máquinas" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Definir mensagem do dia e enviar a todos usuários online" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Definir mensagem do dia em todos os hosts e enviar para os usuários online" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Atualizar mensagem do dia (não enviar)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Atualizar a mensagem do dia em todos os host (não enviar)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Apagar mensagem do dia" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Apagar a mensagem do dia em todos os hosts" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Configuração" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Base de dados" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Iniciar módulos" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Parar módulos" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Salvar cópia de segurança" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Restaurar" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Exportar para arquivo de texto" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Importar arquivo" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Importar diretório" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Reiniciar Serviço" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Parar Serviço" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Adicionar usuário" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Deletar Usuário" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Terminar Sessão do Usuário" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Obter Senha do Usuário" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Alterar Senha do Usuário" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Obter a Data do Último Login" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Obter Estatísticas do Usuário" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Obter Número de Usuários Registrados" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Obter Número de Usuários Online" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Listas de Controle de Acesso" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Regras de Acesso" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Gerenciamento de Usuários" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Usuários conectados" #: mod_configure.erl:501 msgid "All Users" msgstr "Todos os usuários" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Conexões que partam de s2s" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Nos em execução" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Nos parados" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Módulos" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Gestão de Backup" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importar usuários de arquivos jabberd14" #: mod_configure.erl:699 msgid "To ~s" msgstr "Para ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "De ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Configuração de Tabelas de Base de dados em " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Selecione o tipo de armazenamento das tabelas" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Somente copia em disco" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Copias na RAM e disco rígido" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Copia em RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Copia remota" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Parar módulos em " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Selecione módulos a parar" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Iniciar módulos em " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Introduza lista de {módulo, [opções]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Listas de módulos para inicializar" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Salvar backup para arquivo em " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Introduza o caminho do arquivo de backup" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Caminho do arquivo" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Restaurar backup a partir do arquivo em " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Exportar backup para texto em " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Introduza caminho para o arquivo texto" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importar usuário a partir do arquivo em " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Insira o caminho para a fila (arquivo) do jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importar usuários a partir do diretório em " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Introduza o caminho para o diretório de fila do jabberd14" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Caminho para o diretório" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Intervalo (Tempo)" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Configuração da Lista de Controle de Acesso" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Listas de Controle de Acesso" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Configuração de Acesso" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Regras de acesso" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "ID Jabber" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Senha" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Verificação de Senha" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Número de usuários registrados" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Número de usuários online" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Nunca" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Conectado" #: mod_configure.erl:1701 msgid "Last login" msgstr "Último login" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Tamanho da Lista" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "Endereços IP" #: mod_configure.erl:1724 msgid "Resources" msgstr "Recursos" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Administração de " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Ação no usuário" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Editar propriedades" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Remover usuário" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Aceso denegado por la política do serviço" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "Transporte IRC" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "Módulo de IRC para ejabberd" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "Necessitas um cliente com suporte de x:data para configurar las opções de " "mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Registro em mod_irc para " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Insira o nome de usuário, codificações, portas e senhas que vocêdeseja para " "usar nos servidores IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Usuário IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Se você deseja especificar portas diferentes, senhas ou codifações para " "servidores de IRC, complete esta lista com os valores no formato: " "'{\"servidor IRC\", \"codificação\", porta, \"senha\"}'. Por padrão, este " "serviço usa a codificação \"~s\", porta \"~p\", e senha em branco (vazia)" #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Exemplo: [{\"irc.teste.net\", \"koi8-r\"}, 6667, \"senha\"}, {\"dominio.foo." "net\", \"iso8859-1\", 7000}, {\"irc.servidordeteste.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Parâmetros para as Conexões" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Juntar-se ao canal IRC" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "Canal IRC (não coloque o #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "Servidor IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Aqui! Juntar-se ao canal IRC." #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Entrar no canal IRC, neste ID Jabber: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "Configurações do IRC" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Insira o nome de usuário e codificações que você deseja usar para conectar-" "se aos servidores de IRC. Depois, presione 'Next' ('Próximo') para exibir " "mais campos que devem ser preenchidos. Ao final, pressione " "'Complete' ('Completar') para salvar a configuração." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "Usuário IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Senha ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Porta ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Codificação para o servidor ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Servidor ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" "Apenas administradores possuem permissão para enviar mensagens de serviço" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Se te a denegado criar la sala por política do serviço" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "La sala de conferencias não existe" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Salas de Chat" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 #, fuzzy msgid "You need a client that supports x:data to register the nickname" msgstr "" "Você precisa de um cliente com suporte de x:data para poder registrar o nick" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Registro do apelido em " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Introduza o apelido que quer registrar" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Apelido" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "O nick já está registrado por outra pessoa" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Você deve completar o campo \"Apelido\" no formulário" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "Módulo de MUC para ejabberd" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Configuração da sala de bate-papo modificada" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "Entrar na sala" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "Sair da sala" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "foi banido" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "foi removido" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "foi desconectado porque por afiliação inválida" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "" "foi desconectado porque a política da sala mudou, só membros são permitidos" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "foi desconectado porque o sistema foi desligado" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "é agora conhecido como" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " a posto o assunto: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "A sala de chat está criada" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "A sala de chat está destruída" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "A sala de chat está inciada" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "A sala de chat está parada" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Segunda" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Terça" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Quarta" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Quinta" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Sexta" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Sábado" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Domingo" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Janeiro" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Fevereiro" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Março" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "Abril" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Maio" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Junho" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Julho" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Agosto" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "Setembro" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Outubro" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "Novembro" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "Dezembro" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Configuração de salas" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Número de participantes" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Limite de banda excedido" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Este participante foi desconectado da sala de chat por ter enviado uma " "mensagem de erro." #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Impedir o envio de mensagens privadas para a sala" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "Por favor, espere antes de enviar uma nova requisição de voz" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "Requisições de voz estào desabilitadas nesta conferência" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "Não foi possível extrair o JID (Jabber ID) da requisição de voz" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Somente moderadores podem aprovar requisições de voz" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Tipo de mensagem incorreto" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Este participante foi desconectado da sala de chat por ter enviado uma " "mensagem de erro para outro usuário." #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "No está permitido enviar mensagens privados do tipo \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "O receptor não está em la sala de conferencia" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Não é permitido enviar mensagens privadas" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Solo os ocupantes podem enviar mensagens a la sala" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Solo os ocupantes podem enviar consultas a la sala" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "Nesta sala não se permite consultas aos membros da sala" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Somente os moderadores e os participamentes podem alterar o assunto desta " "sala" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Somente os moderadores podem alterar o assunto desta sala" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Os visitantes não podem enviar mensagens a todos os ocupantes" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Este participante foi desconectado da sala de chat por ter enviado uma " "notificação errônea de presença." #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Nesta sala, os visitantes não pode mudar seus apelidos" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "O apelido (nick) já está sendo utilizado" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "As sido bloqueado em esta sala" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Necessitas ser membro de esta sala para poder entrar" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Essa sala não é anônima" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Se necessita senha para entrar em esta sala" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Número excessivo de requisições para o CAPTCHA" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Impossível gerar um CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Senha incorreta" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Se necessita privilégios de administrador" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Se necessita privilégios de moderador" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "O Jabber ID ~s não es válido" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "O nick ~s não existe em la sala" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Afiliação não válida: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Cargo (role) é não válido: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Se requere privilégios de proprietário da sala" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Configuração para ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Título da sala" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Descrição da Sala" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Tornar sala persistente" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Tornar sala pública possível de ser encontrada" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Tornar pública a lista de participantes" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Tornar protegida a senha da sala" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Número máximo de participantes" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Ilimitado" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Tornar o Jabber ID real visível por" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "apenas moderadores" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "qualquer um" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Tornar sala apenas para membros" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Tornar a sala moderada" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Usuários padrões como participantes" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Permitir a usuários modificar o assunto" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Permitir a usuários enviarem mensagens privadas" #: mod_muc/mod_muc_room.erl:3279 #, fuzzy msgid "Allow visitors to send private messages to" msgstr "Permitir a usuários enviarem mensagens privadas" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "ninguém" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Permitir a usuários pesquisar informações sobre os demais" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Permitir a usuários envio de convites" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "Permitir atualizações de status aos visitantes" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Permitir mudança de apelido aos visitantes" #: mod_muc/mod_muc_room.erl:3308 #, fuzzy msgid "Allow visitors to send voice requests" msgstr "Permitir a usuários envio de convites" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "O intervalo mínimo entre requisições de voz (em segundos)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Tornar protegida a senha da sala" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Excluir IDs Jabber de serem submetidos ao CAPTCHA" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Permitir criação de logs" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Necessitas um cliente com suporte de x:data para configurar la sala" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Número de participantes" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privado, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Requisição de voz" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Você deve aprovar/desaprovar a requisição de voz." #: mod_muc/mod_muc_room.erl:3809 #, fuzzy msgid "User JID" msgstr "Usuário " #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s convidou você para a sala ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "a senha é" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "Sua fila de mensagens offline esta cheia. Sua mensagem foi descartada" #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "~s's Fila de Mensagens Offline" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Submetido" #: mod_offline.erl:571 msgid "Time" msgstr "Fecha" #: mod_offline.erl:572 msgid "From" msgstr "De" #: mod_offline.erl:573 msgid "To" msgstr "Para" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Pacote" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Remover os selecionados" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Mensagens offline" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Remover Todas as Mensagens Offline" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "Modulo ejabberd SOCKS5 Bytestreams" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Publicação de Tópico" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "Módulo para Publicar Tópicos do ejabberd" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "PubSub requisição de assinante" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Aprovar esta assinatura." #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ID do Tópico" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Endereço dos Assinantes" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Autorizar este Jabber ID para a inscrição neste tópico pubsub?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Enviar payloads junto com as notificações de eventos" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Entregar as notificações de evento" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Notificar subscritores quando cambia la configuração do nodo" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Notificar subscritores quando o nodo se elimine" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Notificar subscritores quando os elementos se eliminem do nodo" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Persistir elementos ao armazenar" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Um nome familiar para o nó" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Máximo # de elementos que persistem" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Permitir subscrições" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Especificar os modelos de acesso" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Listar grupos autorizados" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Especificar o modelo do publicante" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "Descartar todos os itens quando o publicante principal estiver offline" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Especificar o tipo de mensagem para o evento" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Máximo tamanho do payload em bytes" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Quando enviar o último tópico publicado" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Solo enviar notificações aos usuários disponíveis" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "As coleções com as quais o nó está relacionado" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "A verificação do CAPTCHA falhou" #: mod_register.erl:220 #, fuzzy msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "Você precisa de um cliente com suporte de x:data para poder registrar o nick" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Escolha um nome de usuário e senha para registrar-se neste servidor" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Usuário" #: mod_register.erl:316 mod_register.erl:361 #, fuzzy msgid "The password is too weak" msgstr "Senha considerada fraca'" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Usuários não estão autorizados a registrar contas imediatamente" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Nenhum" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Subscrição" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Pendente" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Grupos" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Validar" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Remover" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Lista de contatos de " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Formato incorreto" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Adicionar ID jabber" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Lista de contatos" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Grupos Shared Roster" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Adicionar novo" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Nome:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Descrição:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Miembros:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 #, fuzzy msgid "Displayed Groups:" msgstr "Grupos Indicados:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Grupo " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Enviar" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Servidor Jabber em Erlang" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Aniversário" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Cidade" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "País" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Email" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Sobrenome" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Preencha o formulário para buscar usuários Jabber. Agrega * ao final de um " "campo para buscar sub-palavras." #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Nome completo" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Nome do meio" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Nome" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Nome da organização" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Departamento/Unidade" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Procurar usuários em " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Necessitas um cliente com suporte de x:data para poder buscar" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Busca de Usuário vCard" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "Módulo vCard para ejabberd" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Resultados de pesquisa para " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Preencha campos para buscar usuários Jabber que concordem" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Não Autorizado" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd Web Admin" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Administração" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Intocado" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Configuração da Regra de Acesso ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Hosts virtuais" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Usuários" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Ultimas atividades dos usuários" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Período: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Último mês" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Último ano" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Todas atividades" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Mostrar Tabela Ordinária" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Mostrar Tabela Integral" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Estatísticas" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Não encontrado" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Nó não encontrado" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Máquina" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Usuários Registrados" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Mensagens offline" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Última atividade" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Usuários registrados" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Usuários online" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Conexões que partem de s2s" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Servidores que partem de s2s" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Mudar senha" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Usuário " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Recursos conectados:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Senha:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Nenhum dado" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Nós" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Nó" #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Portas escutadas" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Atualizar" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Reiniciar" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Parar" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Erro de chamada RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Tabelas de base de dados em " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Tipo de armazenamento" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Elementos" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Memória" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Erro" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Backup de " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Observe que tais opções farão backup apenas da base de dados Mnesia. Caso " "você esteja utilizando o modulo ODBC, você precisará fazer backup de sua " "base de dados SQL separadamente." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Armazenar backup binário:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Restaurar backup binário imediatamente" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Restaurar backup binário após próximo reinicialização do ejabberd (requer " "menos memória):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Armazenar backup em texto:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Restaurar backup formato texto imediatamente:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Importar usuários de um arquivo PIEFXIS (XEP-0227): " #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Exportar todos os dados de todos os usuários no servidor, para arquivos " "formato PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" "Exportar dados dos usuários em um host, para arquivos PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importar dados dos usuários de uma fila jabberd14:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importar dados dos usuários de um diretório-fila jabberd14:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Portas ouvintes em " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Módulos em " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Estatísticas de ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Uptime:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Tempo de CPU" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transações salvas:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transações abortadas:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transações reiniciadas:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transações de log:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Atualizar " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Plano de Atualização" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Módulos atualizados" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Script de atualização" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Script de atualização low level" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Verificação de Script" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Porta" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Porta" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Módulo" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Opções" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Eliminar" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Iniciar" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Sua conta jabber foi criada corretamente." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Houveram erras ao criar esta conta: " #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Sua conta Jabber foi deletada com sucesso." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Erro ao deletar esta conta: " #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "A senha da sua conta Jabber foi mudada com sucesso." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Houveram erros ao mudar a senha: " #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Registros de Contas Jabber" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Registrar uma conta Jabber" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Deletar conta Jabber" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Esta pagina aceita criações de novas contas Jabber neste servidor. A sua JID " "(Identificador Jabber) será da seguinte forma: 'usuário@servidor'. Por " "favor, leia cuidadosamente as instruções para preencher corretamente os " "campos." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 #, fuzzy msgid "Username:" msgstr "Nome de usuário no IRC" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Não é 'case insensitive': macbeth é o mesmo que MacBeth e ainda Macbeth. " #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Caracteres não aceitos:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 #, fuzzy msgid "Server:" msgstr "Servidor ~b" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "Não revele o seu computador a ninguém, mesmo para o administrador deste " "servidor Jabber." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "Mais tarde você pode alterar a sua senha usando um cliente Jabber." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Alguns clientes jabber podem salvar a sua senha no seu computador. Use " "recurso somente se você considera este computador seguro o suficiente." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Memorize a sua senha, ou escreva-a em um papel e guarde-o em um lugar " "seguro. Jabber não é uma maneira automatizada para recuperar a sua senha, se " "você a esquecer eventualmente." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 #, fuzzy msgid "Password Verification:" msgstr "Verificação de Senha" #: web/mod_register_web.erl:250 #, fuzzy msgid "Register" msgstr "Lista de contatos" #: web/mod_register_web.erl:396 #, fuzzy msgid "Old Password:" msgstr "Senha Antiga:" #: web/mod_register_web.erl:401 #, fuzzy msgid "New Password:" msgstr "Nova Senha:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "Esta página aceita para deletar uma conta Jabber neste servidor." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Deletar registro" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "O CAPTCHA é inválido." ejabberd-2.1.11/src/msgs/eo.msg0000664000000000000000000006321312240230175013076 0ustar {"Access Configuration","Agordo de atingo"}. {"Access Control List Configuration","Agordo de atingokontrolo"}. {"Access control lists","Atingokontrol-listoj"}. {"Access Control Lists","Atingokontrol-listoj"}. {"Access denied by service policy","Atingo rifuzita de serv-politiko"}. {"Access rules","Atingo-reguloj"}. {"Access Rules","Atingo-reguloj"}. {"Action on user","Ago je uzanto"}. {"Add Jabber ID","Aldonu Jabber ID"}. {"Add New","Aldonu novan"}. {"Add User","Aldonu Uzanton"}. {"Administration","Administro"}. {"Administration of ","Mastrumado de "}. {"Administrator privileges required","Administrantaj rajtoj bezonata"}. {"A friendly name for the node","Kromnomo por ĉi tiu nodo"}. {"All activity","Ĉiu aktiveco"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Ĉu permesi ĉi tiun Jabber ID aboni al la jena PubAbo-nodo"}. {"Allow users to change the subject","Permesu uzantojn ŝanĝi la temon"}. {"Allow users to query other users","Permesu uzantojn informpeti aliajn uzantojn"}. {"Allow users to send invites","Permesu uzantojn sendi invitojn"}. {"Allow users to send private messages","Permesu uzantojn sendi privatajn mesaĝojn"}. {"Allow visitors to change nickname","Permesu al vizitantoj ŝanĝi siajn kaŝnomojn"}. {"Allow visitors to send private messages to","Permesu uzantojn sendi privatajn mesaĝojn al"}. {"Allow visitors to send status text in presence updates","Permesu al vizitantoj sendi statmesaĝon en ĉeest-sciigoj"}. {"Allow visitors to send voice requests","Permesu uzantojn sendi voĉ-petojn"}. {"All Users","Ĉiuj Uzantoj"}. {"Announcements","Anoncoj"}. {"anyone","iu ajn"}. {"A password is required to enter this room","Pasvorto estas bezonata por eniri ĉi tiun babilejon"}. {"April","Aprilo"}. {"August","Aŭgusto"}. {"Backup","Faru Sekurkopion"}. {"Backup Management","Mastrumado de sekurkopioj"}. {"Backup of ","Sekurkopio de "}. {"Backup to File at ","Faru sekurkopion je "}. {"Bad format","Malĝusta formo"}. {"Birthday","Naskiĝtago"}. {"CAPTCHA web page","CAPTCHA teksaĵ-paĝo"}. {"Change Password","Ŝanĝu pasvorton"}. {"Change User Password","Ŝanĝu pasvorton de uzanto"}. {"Characters not allowed:","Karaktroj ne permesata:"}. {"Chatroom configuration modified","Agordo de babilejo ŝanĝita"}. {"Chatroom is created","Babilejo kreita"}. {"Chatroom is destroyed","Babilejo neniigita"}. {"Chatroom is started","Babilejo lanĉita"}. {"Chatroom is stopped","Babilejo haltita"}. {"Chatrooms","Babilejoj"}. {"Choose a username and password to register with this server","Elektu uzantnomon kaj pasvorton por registri je ĉi tiu servilo"}. {"Choose modules to stop","Elektu modulojn por fini"}. {"Choose storage type of tables","Elektu konserv-tipon de tabeloj"}. {"Choose whether to approve this entity's subscription.","Elektu ĉu permesi la abonon de ĉi tiu ento"}. {"City","Urbo"}. {"Commands","Ordonoj"}. {"Conference room does not exist","Babilejo ne ekzistas"}. {"Configuration","Agordo"}. {"Configuration of room ~s","Agordo de babilejo ~s"}. {"Connected Resources:","Konektataj risurcoj:"}. {"Connections parameters","Konekto-parametroj"}. {"Country","Lando"}. {"CPU Time:","CPU-tempo"}. {"Database","Datumbazo"}. {"Database Tables at ","Datumbaz-tabeloj je "}. {"Database Tables Configuration at ","Agordo de datumbaz-tabeloj je "}. {"December","Decembro"}. {"Default users as participants","Kutime farigu uzantojn kiel partpoprenantoj"}. {"Delete","Forigu"}. {"Delete message of the day","Forigu mesaĝo de la tago"}. {"Delete message of the day on all hosts","Forigu mesaĝo de la tago je ĉiu gastigo"}. {"Delete Selected","Forigu elektata(j)n"}. {"Delete User","Forigu Uzanton"}. {"Deliver event notifications","Liveru event-sciigojn"}. {"Deliver payloads with event notifications","Liveru aĵojn de event-sciigoj"}. {"Description:","Priskribo:"}. {"Disc only copy","Nur disk-kopio"}. {"Displayed Groups:","Montrataj grupoj:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Ne donu vian pasvorton al iun ajn, eĉ ne al la administrantoj de la Ĵabber-servilo."}. {"Dump Backup to Text File at ","Skribu sekurkopion en plata teksto al "}. {"Dump to Text File","Skribu en plata tekst-dosiero"}. {"Edit Properties","Redaktu atributojn"}. {"Either approve or decline the voice request.","Ĉu aprobu, aŭ malaprobu la voĉ-peton."}. {"ejabberd IRC module","ejabberd IRC-modulo"}. {"ejabberd MUC module","ejabberd MUC-modulo"}. {"ejabberd Publish-Subscribe module","ejabberd Public-Abonada modulo"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bajtfluo modulo"}. {"ejabberd vCard module","ejabberd vCard-modulo"}. {"ejabberd Web Admin","ejabberd Teksaĵa Administro"}. {"Elements","Eroj"}. {"Email","Retpoŝto"}. {"Enable logging","Ŝaltu protokoladon"}. {"Encoding for server ~b","Enkodigo por servilo ~b"}. {"End User Session","Haltigu Uzant-seancon"}. {"Enter list of {Module, [Options]}","Enmetu liston de {Modulo, [Elektebloj]}"}. {"Enter nickname you want to register","Enmetu kaŝnomon kiun vi volas registri"}. {"Enter path to backup file","Enmetu vojon por sekurkopio"}. {"Enter path to jabberd14 spool dir","Enmetu vojon al jabberd14-uzantdosierujo"}. {"Enter path to jabberd14 spool file","Enmetu vojon al jabberd14-uzantdosiero"}. {"Enter path to text file","Enmetu vojon al plata teksto"}. {"Enter the text you see","Enmetu montrita teksto"}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Enmetu uzantnomon,j enkodigojn, pordojn kaj pasvortojn kiujn vi volas uzi por konektoj al IRC-serviloj"}. {"Erlang Jabber Server","Erlang-a Jabber-Servilo"}. {"Error","Eraro"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Ekzemplo: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"sekreto\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.iutestservilo.net\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Esceptu Ĵabber-identigilojn je CAPTCHA-defio"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Eksportu datumojn de ĉiuj uzantoj en servilo al PIEFXIS dosieroj (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Eksportu datumoj de uzantoj en gastigo al PIEFXIS dosieroj (XEP-0227):"}. {"Failed to extract JID from your voice request approval","Malsukcesis ekstrakti JID-on de via voĉ-pet-aprobo"}. {"Family Name","Lasta Nomo"}. {"February","Februaro"}. {"Fill in fields to search for any matching Jabber User","Kompletigu la formon por serĉi rekonata Jabber-uzanto"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Kompletigu la formon por serĉi rekonata Jabber-uzanto (Aldonu * je la fino de la kampo por rekoni subĉenon"}. {"Friday","Vendredo"}. {"From","De"}. {"From ~s","De ~s"}. {"Full Name","Plena Nomo"}. {"Get Number of Online Users","Montru nombron de konektataj uzantoj"}. {"Get Number of Registered Users","Montru nombron de registritaj uzantoj"}. {"Get User Last Login Time","Montru tempon de lasta ensaluto"}. {"Get User Password","Montru pasvorton de uzanto"}. {"Get User Statistics","Montru statistikojn de uzanto"}. {"Grant voice to this person?","Koncedu voĉon al ĉi-persono?"}. {"Group ","Grupo "}. {"Groups","Grupoj"}. {"has been banned","estas forbarita"}. {"has been kicked because of an affiliation change","estas forpelita pro aparteneca ŝanĝo"}. {"has been kicked because of a system shutdown","estas forpelita pro sistem-haltigo"}. {"has been kicked because the room has been changed to members-only","estas forpelita ĉar la babilejo fariĝis sole por membroj"}. {"has been kicked","estas forpelita"}. {" has set the subject to: "," ŝanĝis la temon al: "}. {"Host","Gastigo"}. {"If you don't see the CAPTCHA image here, visit the web page.","Se vi ne vidas la CAPTCHA-imagon jene, vizitu la teksaĵ-paĝon."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Se vi volas specifi diversajn pordojn, pasvortojn, enkodigojn por IRC-serviloj, kompletigu la jenan liston kun la formo '{\"irc-servilo\", \"enkodigo\", porto, \"pasvorto\"}'. Se ne specifita, ĉi tiu servilo uzas la enkodigo \"~s\", porto ~p, malplena pasvorto."}. {"Import Directory","Importu dosierujo"}. {"Import File","Importu dosieron"}. {"Import user data from jabberd14 spool file:","Importu uzantojn de jabberd14-uzantdosieroj"}. {"Import User from File at ","Importu uzanton de dosiero el "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importu uzanto-datumojn de PIEFXIS dosiero (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Importu uzantojn de jabberd14-uzantdosieroj"}. {"Import Users from Dir at ","Importu uzantojn de dosierujo ĉe "}. {"Import Users From jabberd14 Spool Files","Importu uzantojn de jabberd14-uzantdosieroj"}. {"Improper message type","Malĝusta mesaĝo-tipo"}. {"Incorrect password","Nekorekta pasvorto"}. {"Invalid affiliation: ~s","Nevalida aparteneco: ~s"}. {"Invalid role: ~s","Nevalida rolo: ~s"}. {"IP addresses","IP-adresoj"}. {"IP","IP"}. {"IRC channel (don't put the first #)","IRC-babilejo (ne aldonu #-prefikson)"}. {"IRC server","IRC-servilo"}. {"IRC settings","IRC agordoj"}. {"IRC Transport","IRC-transportilo"}. {"IRC Username","IRC-kaŝnomo"}. {"IRC username","IRC-uzantnomo"}. {"is now known as","nun nomiĝas"}. {"It is not allowed to send private messages","Ne estas permesata sendi privatajn mesaĝojn"}. {"It is not allowed to send private messages of type \"groupchat\"","Malpermesas sendi mesaĝojn de tipo \"groupchat\""}. {"It is not allowed to send private messages to the conference","Nur partoprenantoj rajtas sendi privatajn mesaĝojn al la babilejo"}. {"Jabber Account Registration","Ĵabber-konto registrado"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Jabber ID ~s estas nevalida"}. {"January","Januaro"}. {"Join IRC channel","Eniras IRC-babilejon"}. {"joins the room","eniras la babilejo"}. {"Join the IRC channel here.","Eniru IRC-babilejon jen"}. {"Join the IRC channel in this Jabber ID: ~s","Eniru IRC-babilejon en ĉi Jabber-ID: ~s"}. {"July","Julio"}. {"June","Junio"}. {"Last Activity","Lasta aktiveco"}. {"Last login","Lasta ensaluto"}. {"Last month","Lasta monato"}. {"Last year","Lasta jaro"}. {"leaves the room","eliras la babilejo"}. {"Listened Ports at ","Atentataj pordoj je "}. {"Listened Ports","Atentataj pordoj"}. {"List of modules to start","Listo de moduloj por starti"}. {"Low level update script","Bazanivela ĝisdatigo-skripto"}. {"Make participants list public","Farigu partoprento-liston publika"}. {"Make room CAPTCHA protected","Farigu babilejon protektata per CAPTCHA"}. {"Make room members-only","Farigu babilejon sole por membroj"}. {"Make room moderated","Farigu babilejon moderigata"}. {"Make room password protected","Farigu babilejon protektata per pasvorto"}. {"Make room persistent","Farigu babilejon daŭra"}. {"Make room public searchable","Farigu babilejon publike trovebla"}. {"March","Marĉo"}. {"Maximum Number of Occupants","Limigo de nombro de partoprenantoj"}. {"Max # of items to persist","Maksimuma kiomo de eroj en konservado"}. {"Max payload size in bytes","Maksimuma aĵo-grando je bajtoj"}. {"May","Majo"}. {"Membership is required to enter this room","Membreco estas bezonata por eniri ĉi tiun babilejon"}. {"Members:","Membroj:"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Memoru vian pasvorton, aŭ skribu ĝin sur papero formetata je sekura loko. Je Ĵabber ne ekzistas aŭtomata metodo por reakiri vian pasvorton se vi forgesas ĝin."}. {"Memory","Memoro"}. {"Message body","Teksto de mesaĝo"}. {"Middle Name","Meza Nomo"}. {"Minimum interval between voice requests (in seconds)","Minimuma intervalo inter voĉ-petoj (je sekundoj)"}. {"Moderator privileges required","Moderantaj rajtoj bezonata"}. {"moderators only","moderantoj sole"}. {"Modified modules","Ĝisdatigitaj moduloj"}. {"Module","Modulo"}. {"Modules at ","Moduloj je "}. {"Modules","Moduloj"}. {"Monday","Lundo"}. {"Name:","Nomo:"}. {"Name","Nomo"}. {"Never","Neniam"}. {"New Password:","Nova Pasvorto:"}. {"Nickname","Kaŝnomo"}. {"Nickname Registration at ","Kaŝnomo-registrado je "}. {"Nickname ~s does not exist in the room","Kaŝnomo ~s ne ekzistas en la babilejo"}. {"nobody","neniu"}. {"No body provided for announce message","Neniu teksto donita por anonc-mesaĝo"}. {"No Data","Neniu datumo"}. {"Node ID","Nodo ID"}. {"Node ","Nodo "}. {"Node not found","Nodo ne trovita"}. {"Nodes","Nodoj"}. {"No limit","Neniu limigo"}. {"None","Nenio"}. {"No resource provided","Neniu risurco donita"}. {"Not Found","Ne trovita"}. {"Notify subscribers when items are removed from the node","Sciigu abonantoj kiam eroj estas forigita de la nodo"}. {"Notify subscribers when the node configuration changes","Sciigu abonantoj kiam la agordo de la nodo ŝanĝas"}. {"Notify subscribers when the node is deleted","Sciigu abonantoj kiam la nodo estas forigita"}. {"November","Novembro"}. {"Number of occupants","Nombro de ĉeestantoj"}. {"Number of online users","Nombro de konektataj uzantoj"}. {"Number of registered users","Nombro de registritaj uzantoj"}. {"October","Oktobro"}. {"Offline Messages:","Liverontaj mesaĝoj"}. {"Offline Messages","Liverontaj mesaĝoj"}. {"OK","Bone"}. {"Old Password:","Malnova Pasvorto:"}. {"Online","Konektata"}. {"Online Users:","Konektataj uzantoj:"}. {"Online Users","Konektataj Uzantoj"}. {"Only deliver notifications to available users","Nur liveru sciigojn al konektataj uzantoj"}. {"Only moderators and participants are allowed to change the subject in this room","Nur moderigantoj kaj partoprenantoj rajtas ŝanĝi la temon en ĉi tiu babilejo"}. {"Only moderators are allowed to change the subject in this room","Nur moderigantoj rajtas ŝanĝi la temon en ĉi tiu babilejo"}. {"Only moderators can approve voice requests","Nur moderigantoj povas aprobi voĉ-petojn"}. {"Only occupants are allowed to send messages to the conference","Nur partoprenantoj rajtas sendi mesaĝojn al la babilejo"}. {"Only occupants are allowed to send queries to the conference","Nur partoprenantoj rajtas sendi informmendojn al la babilejoj"}. {"Only service administrators are allowed to send service messages","Nur servo-administrantoj rajtas sendi serv-mesaĝojn"}. {"Options","Elektebloj"}. {"Organization Name","Organiz-nomo"}. {"Organization Unit","Organiz-parto"}. {"Outgoing s2s Connections:","Elirantaj s-al-s-konektoj:"}. {"Outgoing s2s Connections","Elirantaj s-al-s-konektoj"}. {"Outgoing s2s Servers:","Elirantaj s-al-s-serviloj"}. {"Owner privileges required","Mastraj rajtoj bezonata"}. {"Packet","Pakaĵo"}. {"Password ~b","Pasvorto ~b"}. {"Password:","Pasvorto:"}. {"Password","Pasvorto"}. {"Password Verification:","Pasvortkontrolo:"}. {"Password Verification","Pasvortkontrolo"}. {"Path to Dir","Vojo al dosierujo"}. {"Path to File","Voje de dosiero"}. {"Pending","Atendanta"}. {"Period: ","Periodo: "}. {"Persist items to storage","Savu erojn en konservado"}. {"Ping","Sondaĵo"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Rimarku ke ĉi tiuj elektebloj nur sekurkopias la propran Mnesia-datumbazon. Se vi uzas la ODBC-modulon, vi ankaŭ devas sekurkopii tiujn SQL-datumbazoj aparte."}. {"Please, wait for a while before sending new voice request","Bonvolu atendi iomete antaŭ ol sendi plian voĉ-peton"}. {"Pong","Resondaĵo"}. {"Port ~b","Pordo ~b"}. {"Port","Pordo"}. {"Present real Jabber IDs to","Montru verajn Jabber ID-ojn al"}. {"private, ","privata, "}. {"Protocol","Protokolo"}. {"Publish-Subscribe","Public-Abonado"}. {"PubSub subscriber request","PubAbo abonpeto"}. {"Purge all items when the relevant publisher goes offline","Forigu ĉiujn erojn kiam la rilata publikanto malkonektiĝas"}. {"Queries to the conference members are not allowed in this room","Malpermesas informmendoj al partoprenantoj en ĉi tiu babilejo"}. {"RAM and disc copy","RAM- kaj disk-kopio"}. {"RAM copy","RAM-kopio"}. {"Raw","Kruda"}. {"Really delete message of the day?","Ĉu vere forigi mesaĝon de la tago?"}. {"Recipient is not in the conference room","Ricevanto ne ĉeestas en la babilejo "}. {"Register a Jabber account","Registru Ĵabber-konton"}. {"Registered Users:","Registritaj uzantoj:"}. {"Registered Users","Registritaj uzantoj"}. {"Register","Registru"}. {"Registration in mod_irc for ","Registraĵo en mod_irc de "}. {"Remote copy","Fora kopio"}. {"Remove All Offline Messages","Forigu ĉiujn liverontajn mesaĝojn"}. {"Remove","Forigu"}. {"Remove User","Forigu uzanton"}. {"Replaced by new connection","Anstataŭigita je nova konekto"}. {"Resources","Risurcoj"}. {"Restart","Restartu"}. {"Restart Service","Restartu Servon"}. {"Restore Backup from File at ","Restaŭrigu de dosiero el "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Restaŭrigu duuman sekurkopion post sekvonta ejabberd-restarto"}. {"Restore binary backup immediately:","Restaŭrigu duuman sekurkopion tuj:"}. {"Restore plain text backup immediately:","Restaŭrigu sekurkopion el plata tekstdosiero tuj"}. {"Restore","Restaŭru"}. {"Room Configuration","Babilejo-agordo"}. {"Room creation is denied by service policy","Ĉi tiu serv-politiko ne permesas babilejo-kreadon"}. {"Room description","Babilejo-priskribo"}. {"Room Occupants","Nombro de ĉeestantoj"}. {"Room title","Babilejo-nomo"}. {"Roster groups allowed to subscribe","Kontaktlist-grupoj kiuj rajtas aboni"}. {"Roster","Kontaktlisto"}. {"Roster of ","Kontaktlisto de "}. {"Roster size","Kontaktlist-grando"}. {"RPC Call Error","Eraro de RPC-alvoko"}. {"Running Nodes","Funkciantaj Nodoj"}. {"~s access rule configuration","Agordo de atingo-reguloj de ~s"}. {"Saturday","Sabato"}. {"Script check","Skript-kontrolo"}. {"Search Results for ","Serĉ-rezultoj de "}. {"Search users in ","Serĉu uzantojn en "}. {"Send announcement to all online users on all hosts","Sendu anoncon al ĉiu konektata uzanto de ĉiu gastigo"}. {"Send announcement to all online users","Sendu anoncon al ĉiu konektata uzanto"}. {"Send announcement to all users on all hosts","Sendu anoncon al ĉiu uzanto de ĉiu gastigo"}. {"Send announcement to all users","Sendu anoncon al ĉiu uzanto"}. {"September","Septembro"}. {"Server ~b","Servilo ~b"}. {"Server:","Servilo:"}. {"Set message of the day and send to online users","Enmetu mesaĝon de la tago kaj sendu al konektataj uzantoj"}. {"Set message of the day on all hosts and send to online users","Enmetu mesaĝon de la tago je ĉiu gastigo kaj sendu al konektataj uzantoj"}. {"Shared Roster Groups","Komuna Kontaktlist-grupo"}. {"Show Integral Table","Montru integran tabelon"}. {"Show Ordinary Table","Montru ordinaran tabelon"}. {"Shut Down Service","Haltigu Servon"}. {"~s invites you to the room ~s","~s invitas vin al la babilejo ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Kelkaj Ĵabber-klientoj povas memori vian pasvorton je via komputilo. Nur uzu tiun eblon se vi fidas ke via komputilo estas sekura."}. {"Specify the access model","Specifu atingo-modelon"}. {"Specify the event message type","Specifu tipo de event-mesaĝo"}. {"Specify the publisher model","Enmetu publikadan modelon"}. {"~s's Offline Messages Queue","Mesaĝo-atendovico de ~s"}. {"Start Modules at ","Startu modulojn je "}. {"Start Modules","Startu Modulojn"}. {"Start","Startu"}. {"Statistics of ~p","Statistikoj de ~p"}. {"Statistics","Statistikoj"}. {"Stop","Haltigu"}. {"Stop Modules at ","Haltigu modulojn je "}. {"Stop Modules","Haltigu Modulojn"}. {"Stopped Nodes","Neaktivaj Nodoj"}. {"Storage Type","Konserv-tipo"}. {"Store binary backup:","Konservu duuman sekurkopion:"}. {"Store plain text backup:","Skribu sekurkopion en plata tekstdosiero"}. {"Subject","Temo"}. {"Submit","Sendu"}. {"Submitted","Sendita"}. {"Subscriber Address","Abonanta adreso"}. {"Subscription","Abono"}. {"Sunday","Dimanĉo"}. {"That nickname is already in use by another occupant","Tiu kaŝnomo jam estas uzata de alia partoprenanto"}. {"That nickname is registered by another person","Kaŝnomo estas registrita de alia persono"}. {"The CAPTCHA is valid.","La CAPTCHA ĝustas"}. {"The CAPTCHA verification has failed","La CAPTCHA-kontrolado malsukcesis"}. {"The collections with which a node is affiliated","Aro kun kiu nodo estas filigita"}. {"the password is","la pasvorto estas"}. {"The password is too weak","La pasvorto estas ne sufiĉe forta"}. {"The password of your Jabber account was successfully changed.","La pasvorto de via Ĵabber-konto estas sukcese ŝanĝata."}. {"There was an error changing the password: ","Estis eraro dum ŝanĝi de la pasvortro:"}. {"There was an error creating the account: ","Estis eraro dum kreado de la konto:"}. {"There was an error deleting the account: ","Estis eraro dum forigado de la konto:"}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Uskleco ne signifas: macbeth estas la sama ol MacBeth kaj Macbeth."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Jena paĝo ebligas kreadon de Ĵabber-konto je ĉi-Ĵabber-servilo. Via JID (Ĵabber-IDentigilo) estos ĉi-tiel: uzantnomo@servilo. Bonvolu legu bone la instrukciojn por korekta enmetigo de la kampoj. "}. {"This page allows to unregister a Jabber account in this Jabber server.","Jena pagxo ebligas malregistri Jxabber-konton je ĉi-servilo."}. {"This participant is kicked from the room because he sent an error message","Ĉi tiu partoprenanta estas forpelata de la babilejo pro sendado de erar-mesaĝo"}. {"This participant is kicked from the room because he sent an error message to another participant","Ĉi tiu partoprenanto estas forpelata de la babilejo pro sendo de erar-mesaĝo al alia partoprenanto"}. {"This participant is kicked from the room because he sent an error presence","Ĉi tiu partoprenanto estas forpelata de la babilejo pro sendo de erar-ĉeesto"}. {"This room is not anonymous","Ĉi tiu babilejo ne estas anonima"}. {"Thursday","Ĵaŭdo"}. {"Time delay","Prokrasto"}. {"Time","Tempo"}. {"To","Ĝis"}. {"Too many CAPTCHA requests","Tro multaj CAPTCHA-petoj"}. {"To ~s","Al ~s"}. {"Traffic rate limit is exceeded","Trafikrapida limigo superita"}. {"Transactions Aborted:","Transakcioj nuligitaj"}. {"Transactions Committed:","Transakcioj enmetitaj"}. {"Transactions Logged:","Transakcioj protokolitaj"}. {"Transactions Restarted:","Transakcioj restartitaj"}. {"Tuesday","Mardo"}. {"Unable to generate a CAPTCHA","Ne eblis krei CAPTCHA"}. {"Unauthorized","Nepermesita"}. {"Unregister a Jabber account","Malregistru Ĵabber-konton"}. {"Unregister","Malregistru"}. {"Update ","Ĝisdatigu "}. {"Update","Ĝisdatigu"}. {"Update message of the day (don't send)","Ŝanĝu mesaĝon de la tago (ne sendu)"}. {"Update message of the day on all hosts (don't send)","Ŝanĝu mesaĝon de la tago je ĉiu gastigo (ne sendu)"}. {"Update plan","Ĝisdatigo-plano"}. {"Update script","Ĝisdatigo-skripto"}. {"Uptime:","Daŭro de funkciado"}. {"Use of STARTTLS required","Uzo de STARTTLS bezonata"}. {"User JID","Uzant-JID"}. {"User Management","Uzanto-administrado"}. {"Username:","Uzantnomo"}. {"Users are not allowed to register accounts so quickly","Ne estas permesata al uzantoj registri tiel rapide"}. {"Users Last Activity","Lasta aktiveco de uzanto"}. {"Users","Uzantoj"}. {"User ","Uzanto "}. {"User","Uzanto"}. {"Validate","Validigu"}. {"vCard User Search","Serĉado de vizitkartoj"}. {"Virtual Hosts","Virtual-gastigoj"}. {"Visitors are not allowed to change their nicknames in this room","Ne estas permesata al vizitantoj ŝanĝi siajn kaŝnomojn en ĉi tiu ĉambro"}. {"Visitors are not allowed to send messages to all occupants","Vizitantoj ne rajtas sendi mesaĝojn al ĉiuj partoprenantoj"}. {"Voice requests are disabled in this conference","Voĉ-petoj estas malebligita en jena babilejo"}. {"Voice request","Voĉ-peto"}. {"Wednesday","Merkredo"}. {"When to send the last published item","Kiam sendi la laste publicitan eron"}. {"Whether to allow subscriptions","Ĉu permesi aboni"}. {"You can later change your password using a Jabber client.","Poste vi povas ŝanĝi vian pasvorton per Ĵabber-kliento."}. {"You have been banned from this room","Vi estas malpermesata en ĉi tiu babilejo"}. {"You must fill in field \"Nickname\" in the form","Vi devas kompletigi la \"Kaŝnomo\" kampon"}. {"You need a client that supports x:data and CAPTCHA to register","Vi bezonas klienton subtenante x:data-funkcio kaj CAPTCHA por registri kaŝnomon"}. {"You need a client that supports x:data to register the nickname","Vi bezonas klienton subtenante x:data-funkcio por registri kaŝnomon"}. {"You need an x:data capable client to configure mod_irc settings","Vi bezonas klienton kun x:data-funkcio por agordi mod_irc"}. {"You need an x:data capable client to configure room","Vi bezonas klienton kun x:data-funkcio por agordi la babilejon"}. {"You need an x:data capable client to search","Vi bezonas klienton kun x:data-funkcio por serĉado"}. {"Your active privacy list has denied the routing of this stanza.","Via aktiva privatec-listo malpermesas enkursigi ĉi-tiun pakaĵon"}. {"Your contact offline message queue is full. The message has been discarded.","Mesaĝo-atendovico de la senkonekta kontakto estas plena. La mesaĝo estas forĵetita"}. {"Your Jabber account was successfully created.","Via Ĵabber-konto estis sukcese kreata."}. {"Your Jabber account was successfully deleted.","Via Ĵabber-konto estas sukcese forigita."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Viaj mesaĝoj al ~s estas blokata. Por malbloki ilin, iru al ~s"}. ejabberd-2.1.11/src/msgs/ru.msg0000664000000000000000000011275712240230175013131 0ustar {"Access Configuration","Конфигурация доступа"}. {"Access Control List Configuration","Конфигурация списков управления доступом"}. {"Access control lists","Списки управления доступом"}. {"Access Control Lists","Списки управления доступом"}. {"Access denied by service policy","Доступ запрещён политикой службы"}. {"Access rules","Правила доступа"}. {"Access Rules","Правила доступа"}. {"Action on user","Действие над пользователем"}. {"Add Jabber ID","Добавить Jabber ID"}. {"Add New","Добавить"}. {"Add User","Добавить пользователя"}. {"Administration of ","Администрирование "}. {"Administration","Администрирование"}. {"Administrator privileges required","Требуются права администратора"}. {"A friendly name for the node","Легко запоминаемое имя для узла"}. {"All activity","Вся статистика"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Разрешить этому Jabber ID подписаться на данный узел?"}. {"Allow users to change the subject","Разрешить пользователям изменять тему"}. {"Allow users to query other users","Разрешить iq-запросы к пользователям"}. {"Allow users to send invites","Разрешить пользователям посылать приглашения"}. {"Allow users to send private messages","Разрешить приватные сообщения"}. {"Allow visitors to change nickname","Разрешить посетителям изменять псевдоним"}. {"Allow visitors to send private messages to","Разрешить посетителям посылать приватные сообщения"}. {"Allow visitors to send status text in presence updates","Разрешить посетителям вставлять текcт статуса в сообщения о присутствии"}. {"Allow visitors to send voice requests","Разрешить посетителям запрашивать право голоса"}. {"All Users","Все пользователи"}. {"Announcements","Объявления"}. {"anyone","всем участникам"}. {"A password is required to enter this room","Чтобы войти в эту конференцию, нужен пароль"}. {"April","апреля"}. {"August","августа"}. {"Backup Management","Управление резервным копированием"}. {"Backup of ","Резервное копирование "}. {"Backup to File at ","Резервное копирование в файл на "}. {"Backup","Резервное копирование"}. {"Bad format","Неправильный формат"}. {"Birthday","День рождения"}. {"CAPTCHA web page","Ссылка на капчу"}. {"Change Password","Сменить пароль"}. {"Change User Password","Изменить пароль пользователя"}. {"Characters not allowed:","Недопустимые символы:"}. {"Chatroom configuration modified","Конфигурация комнаты изменилась"}. {"Chatroom is created","Комната создана"}. {"Chatroom is destroyed","Комната уничтожена"}. {"Chatroom is started","Комната запущена"}. {"Chatroom is stopped","Комната остановлена"}. {"Chatrooms","Комнаты"}. {"Choose a username and password to register with this server","Выберите имя пользователя и пароль для регистрации на этом сервере"}. {"Choose modules to stop","Выберите модули, которые следует остановить"}. {"Choose storage type of tables","Выберите тип хранения таблиц"}. {"Choose whether to approve this entity's subscription.","Решите: предоставить ли подписку этому объекту."}. {"City","Город"}. {"Commands","Команды"}. {"Conference room does not exist","Конференция не существует"}. {"Configuration of room ~s","Конфигурация комнаты ~s"}. {"Configuration","Конфигурация"}. {"Connected Resources:","Подключённые ресурсы:"}. {"Connections parameters","Параметры соединения"}. {"Country","Страна"}. {"CPU Time:","Процессорное время:"}. {"Database Tables at ","Таблицы базы данных на "}. {"Database Tables Configuration at ","Конфигурация таблиц базы данных на "}. {"Database","База данных"}. {"December","декабря"}. {"Default users as participants","Сделать пользователей участниками по умолчанию"}. {"Delete message of the day on all hosts","Удалить сообщение дня со всех виртуальных серверов"}. {"Delete message of the day","Удалить сообщение дня"}. {"Delete Selected","Удалить выделенные"}. {"Delete User","Удалить пользователя"}. {"Delete","Удалить"}. {"Deliver event notifications","Доставлять уведомления о событиях"}. {"Deliver payloads with event notifications","Доставлять вместе с уведомлениями o публикациях сами публикации"}. {"Description:","Описание:"}. {"Disc only copy","только диск"}. {"Displayed Groups:","Видимые группы:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","Не говорите никому свой пароль, даже администраторам сервера."}. {"Dump Backup to Text File at ","Копирование в текстовый файл на "}. {"Dump to Text File","Копирование в текстовый файл"}. {"Edit Properties","Изменить параметры"}. {"Either approve or decline the voice request.","Подтвердите или отклоните право голоса."}. {"ejabberd IRC module","ejabberd IRC модуль"}. {"ejabberd MUC module","ejabberd MUC модуль"}. {"ejabberd Publish-Subscribe module","Модуль ejabberd Публикации-Подписки"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams модуль"}. {"ejabberd vCard module","ejabberd vCard модуль"}. {"ejabberd Web Admin","Web-интерфейс администрирования ejabberd"}. {"Elements","Элементы"}. {"Email","Электронная почта"}. {"Enable logging","Включить журналирование"}. {"Encoding for server ~b","Кодировка сервера ~b"}. {"End User Session","Завершить сеанс пользователя"}. {"Enter list of {Module, [Options]}","Введите список вида {Module, [Options]}"}. {"Enter nickname you want to register","Введите псевдоним, который Вы хотели бы зарегистрировать"}. {"Enter path to backup file","Введите путь к резервному файлу"}. {"Enter path to jabberd14 spool dir","Введите путь к директории спула jabberd14"}. {"Enter path to jabberd14 spool file","Введите путь к файлу из спула jabberd14"}. {"Enter path to text file","Введите путь к текстовому файлу"}. {"Enter the text you see","Введите увиденный текст"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Введите имя пользователя и кодировки, которые будут использоваться при подключении к IRC-серверам. Нажмите 'Далее' для получения дополнительных полей для заполнения. Нажмите 'Завершить' для сохранения настроек."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Введите имя пользователя, кодировки, порты и пароли, которые будут использоваться при подключении к IRC-серверам"}. {"Erlang Jabber Server","Erlang Jabber Server"}. {"Error","Ошибка"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Пример: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","Исключить показ капчи для списка Jabber ID"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Экспорт данных всех пользователей сервера в файлы формата PIEFXIS (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Экспорт пользовательских данных домена в файлы формата PIEFXIS (XEP-0227):"}. {"Failed to extract JID from your voice request approval","Ошибка обработки JID из вашего запроса на право голоса"}. {"Family Name","Фамилия"}. {"February","февраля"}. {"Fill in fields to search for any matching Jabber User","Заполните форму для поиска пользователя Jabber"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Заполните форму для поиска пользователя Jabber (Если добавить * в конец поля, то происходит поиск подстроки)"}. {"Friday","Пятница"}. {"From ~s","От ~s"}. {"From","От кого"}. {"Full Name","Полное имя"}. {"Get Number of Online Users","Получить количество подключённых пользователей"}. {"Get Number of Registered Users","Получить количество зарегистрированных пользователей"}. {"Get User Last Login Time","Получить время последнего подключения пользователя"}. {"Get User Password","Получить пароль пользователя"}. {"Get User Statistics","Получить статистику по пользователю"}. {"Grant voice to this person?","Предоставить голос?"}. {"Groups","Группы"}. {"Group ","Группа "}. {"has been banned","запретили входить в комнату"}. {"has been kicked because of an affiliation change","выгнали из комнаты вследствие смены ранга"}. {"has been kicked because of a system shutdown","выгнали из комнаты из-за останова системы"}. {"has been kicked because the room has been changed to members-only","выгнали из комнаты потому что она стала только для членов"}. {"has been kicked","выгнали из комнаты"}. {" has set the subject to: "," установил(а) тему: "}. {"Host","Хост"}. {"If you don't see the CAPTCHA image here, visit the web page.","Если вы не видите изображение капчи, перейдите по ссылке."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Чтобы указать различные порты, пароли, кодировки для разных серверов IRC, заполните список значениями в формате '{\"сервер IRC\", \"кодировка\", порт, \"пароль\"}'. По умолчанию сервис использует кодировку \"~s\", порт ~p, пустой пароль."}. {"Import Directory","Импорт из директории"}. {"Import File","Импорт из файла"}. {"Import user data from jabberd14 spool file:","Импорт пользовательских данных из буферного файла jabberd14:"}. {"Import User from File at ","Импорт пользователя из файла на "}. {"Import users data from a PIEFXIS file (XEP-0227):","Импорт пользовательских данных из файла формата PIEFXIS (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Импорт пользовательских данных из буферной директории jabberd14:"}. {"Import Users from Dir at ","Импорт пользователей из директории на "}. {"Import Users From jabberd14 Spool Files","Импорт пользователей из спула jabberd14"}. {"Improper message type","Неправильный тип сообщения"}. {"Incorrect password","Неправильный пароль"}. {"Invalid affiliation: ~s","Недопустимый ранг: ~s"}. {"Invalid role: ~s","Недопустимая роль: ~s"}. {"IP addresses","IP адреса"}. {"IP","IP"}. {"IRC channel (don't put the first #)","Канал IRC (без символа #)"}. {"IRC server","Сервер IRC"}. {"IRC settings","Настройки IRC"}. {"IRC Transport","IRC Транспорт"}. {"IRC username","Имя пользователя IRC"}. {"IRC Username","Имя пользователя IRC"}. {"is now known as","изменил(а) имя на"}. {"It is not allowed to send private messages of type \"groupchat\"","Нельзя посылать частные сообщения типа \"groupchat\""}. {"It is not allowed to send private messages to the conference","Не разрешается посылать частные сообщения прямо в конференцию"}. {"It is not allowed to send private messages","Запрещено посылать приватные сообщения"}. {"Jabber Account Registration","Регистрация Jabber-аккаунта"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Jabber ID ~s недопустимый"}. {"January","января"}. {"Join IRC channel","Присоединиться к каналу IRC"}. {"joins the room","вошёл(а) в комнату"}. {"Join the IRC channel here.","Присоединяйтесь к каналу IRC"}. {"Join the IRC channel in this Jabber ID: ~s","Присоединиться к каналу IRC с Jabber ID: ~s"}. {"July","июля"}. {"June","июня"}. {"Last Activity","Последнее подключение"}. {"Last login","Время последнего подключения"}. {"Last month","За последний месяц"}. {"Last year","За последний год"}. {"leaves the room","вышел(а) из комнаты"}. {"Listened Ports at ","Прослушиваемые порты на "}. {"Listened Ports","Прослушиваемые порты"}. {"List of modules to start","Список запускаемых модулей"}. {"Low level update script","Низкоуровневый сценарий обновления"}. {"Make participants list public","Сделать список участников видимым всем"}. {"Make room CAPTCHA protected","Сделать комнату защищённой капчей"}. {"Make room members-only","Комната только для зарегистрированных участников"}. {"Make room moderated","Сделать комнату модерируемой"}. {"Make room password protected","Сделать комнату защищённой паролем"}. {"Make room persistent","Сделать комнату постоянной"}. {"Make room public searchable","Сделать комнату видимой всем"}. {"March","марта"}. {"Maximum Number of Occupants","Максимальное количество участников"}. {"Max # of items to persist","Максимальное число сохраняемых публикаций"}. {"Max payload size in bytes","Максимальный размер полезной нагрузки в байтах"}. {"May","мая"}. {"Membership is required to enter this room","В эту конференцию могут входить только её члены"}. {"Members:","Члены:"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Запомните пароль или запишите его на бумаге, которую сохраните в безопасном месте. В Jabber'е нет автоматизированного средства восстановления пароля в том случае, если Вы его забудете."}. {"Memory","Память"}. {"Message body","Тело сообщения"}. {"Middle Name","Отчество"}. {"Minimum interval between voice requests (in seconds)","Минимальный интервал между запросами на право голоса"}. {"Moderator privileges required","Требуются права модератора"}. {"moderators only","только модераторам"}. {"Modified modules","Изменённые модули"}. {"Modules at ","Модули на "}. {"Modules","Модули"}. {"Module","Модуль"}. {"Monday","Понедельник"}. {"Name:","Название:"}. {"Name","Название"}. {"Never","Никогда"}. {"New Password:","Новый пароль:"}. {"Nickname Registration at ","Регистрация псевдонима на "}. {"Nickname ~s does not exist in the room","Псевдоним ~s в комнате отсутствует"}. {"Nickname","Псевдоним"}. {"No body provided for announce message","Тело объявления не должно быть пустым"}. {"nobody","никто"}. {"No Data","Нет данных"}. {"Node ID","ID узла"}. {"Node not found","Узел не найден"}. {"Nodes","Узлы"}. {"Node ","Узел "}. {"No limit","Не ограничено"}. {"None","Нет"}. {"No resource provided","Не указан ресурс"}. {"Not Found","Не Найдено"}. {"Notify subscribers when items are removed from the node","Уведомлять подписчиков об удалении публикаций из сборника"}. {"Notify subscribers when the node configuration changes","Уведомлять подписчиков об изменении конфигурации сборника"}. {"Notify subscribers when the node is deleted","Уведомлять подписчиков об удалении сборника"}. {"November","ноября"}. {"Number of occupants","Число присутствующих"}. {"Number of online users","Количество подключённых пользователей"}. {"Number of registered users","Количество зарегистрированных пользователей"}. {"October","октября"}. {"Offline Messages:","Офлайновые сообщения:"}. {"Offline Messages","Офлайновые сообщения"}. {"OK","Продолжить"}. {"Old Password:","Старый пароль:"}. {"Online Users:","Подключённые пользователи:"}. {"Online Users","Подключённые пользователи"}. {"Online","Подключён"}. {"Only deliver notifications to available users","Доставлять уведомления только доступным пользователям"}. {"Only moderators and participants are allowed to change the subject in this room","Только модераторы и участники могут изменять тему в этой комнате"}. {"Only moderators are allowed to change the subject in this room","Только модераторы могут изменять тему в этой комнате"}. {"Only moderators can approve voice requests","Только модераторы могут утверждать запросы на право голоса"}. {"Only occupants are allowed to send messages to the conference","Только присутствующим разрешается посылать сообщения в конференцию"}. {"Only occupants are allowed to send queries to the conference","Только присутствующим разрешается посылать запросы в конференцию"}. {"Only service administrators are allowed to send service messages","Только администратор службы может посылать служебные сообщения"}. {"Options","Параметры"}. {"Organization Name","Название организации"}. {"Organization Unit","Отдел организации"}. {"Outgoing s2s Connections:","Исходящие s2s-серверы:"}. {"Outgoing s2s Connections","Исходящие s2s-соединения"}. {"Outgoing s2s Servers:","Исходящие s2s-серверы:"}. {"Owner privileges required","Требуются права владельца"}. {"Packet","Пакет"}. {"Password ~b","Пароль ~b"}. {"Password Verification:","Проверка пароля:"}. {"Password Verification","Проверка пароля"}. {"Password:","Пароль:"}. {"Password","Пароль"}. {"Path to Dir","Путь к директории"}. {"Path to File","Путь к файлу"}. {"Pending","Ожидание"}. {"Period: ","Период"}. {"Persist items to storage","Сохранять публикации в хранилище"}. {"Ping","Пинг"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Заметьте, что здесь производится резервное копирование только встроенной базы данных Mnesia. Если Вы также используете другое хранилище данных (например с помощью модуля ODBC), то его резервное копирование следует осуществлять отдельно."}. {"Please, wait for a while before sending new voice request","Пожалуйста, подождите перед тем как подать новый запрос на право голоса"}. {"Pong","Понг"}. {"Port ~b","Порт ~b"}. {"Port","Порт"}. {"Present real Jabber IDs to","Сделать реальные Jabber ID участников видимыми"}. {"private, ","приватная, "}. {"Protocol","Протокол"}. {"Publish-Subscribe","Публикация-Подписка"}. {"PubSub subscriber request","Запрос подписчика PubSub"}. {"Purge all items when the relevant publisher goes offline","Очищать все записи автора публикации когда он отключается"}. {"Queries to the conference members are not allowed in this room","Запросы к пользователям в этой конференции запрещены"}. {"RAM and disc copy","ОЗУ и диск"}. {"RAM copy","ОЗУ"}. {"Raw","Необработанный формат"}. {"Really delete message of the day?","Действительно удалить сообщение дня?"}. {"Recipient is not in the conference room","Адресата нет в конференции"}. {"Register a Jabber account","Зарегистрировать Jabber-аккаунт"}. {"Registered Users:","Зарегистрированные пользователи:"}. {"Registered Users","Зарегистрированные пользователи"}. {"Register","Зарегистрировать"}. {"Registration in mod_irc for ","Регистрация в mod_irc для "}. {"Remote copy","не хранится локально"}. {"Remove All Offline Messages","Удалить все офлайновые сообщения"}. {"Remove User","Удалить пользователя"}. {"Remove","Удалить"}. {"Replaced by new connection","Заменено новым соединением"}. {"Resources","Ресурсы"}. {"Restart Service","Перезапустить службу"}. {"Restart","Перезапустить"}. {"Restore Backup from File at ","Восстановление из резервной копии на "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Восстановить из бинарной резервной копии при следующем запуске (требует меньше памяти):"}. {"Restore binary backup immediately:","Восстановить из бинарной резервной копии немедленно:"}. {"Restore plain text backup immediately:","Восстановить из текстовой резервной копии немедленно:"}. {"Restore","Восстановление из резервной копии"}. {"Room Configuration","Конфигурация комнаты"}. {"Room creation is denied by service policy","Cоздавать конференцию запрещено политикой службы"}. {"Room description","Описание комнаты"}. {"Room Occupants","Участники комнаты"}. {"Room title","Название комнаты"}. {"Roster groups allowed to subscribe","Группы списка контактов, которым разрешена подписка"}. {"Roster of ","Ростер пользователя "}. {"Roster size","Размер списка контактов"}. {"Roster","Ростер"}. {"RPC Call Error","Ошибка вызова RPC"}. {"Running Nodes","Работающие узлы"}. {"~s access rule configuration","Конфигурация правила доступа ~s"}. {"Saturday","Суббота"}. {"Script check","Проверка сценария"}. {"Search Results for ","Результаты поиска в "}. {"Search users in ","Поиск пользователей в "}. {"Send announcement to all online users on all hosts","Разослать объявление всем подключённым пользователям на всех виртуальных серверах"}. {"Send announcement to all online users","Разослать объявление всем подключённым пользователям"}. {"Send announcement to all users on all hosts","Разослать объявление всем пользователям на всех виртуальных серверах"}. {"Send announcement to all users","Разослать объявление всем пользователям"}. {"September","сентября"}. {"Server ~b","Сервер ~b"}. {"Server:","Сервер:"}. {"Set message of the day and send to online users","Установить сообщение дня и разослать его подключённым пользователям"}. {"Set message of the day on all hosts and send to online users","Установить сообщение дня на всех виртуальных серверах и разослать его подключённым пользователям"}. {"Shared Roster Groups","Группы общих контактов"}. {"Show Integral Table","Показать интегральную таблицу"}. {"Show Ordinary Table","Показать обычную таблицу"}. {"Shut Down Service","Остановить службу"}. {"~s invites you to the room ~s","~s приглашает вас в комнату ~s"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Некоторые Jabber-клиенты могут сохранять пароль на Вашем компьютере. Используйте эту функцию только в том случае, если считаете это безопасным."}. {"Specify the access model","Укажите механизм управления доступом"}. {"Specify the event message type","Укажите тип сообщения о событии"}. {"Specify the publisher model","Условия публикации"}. {"~s's Offline Messages Queue","Oчередь офлайновых сообщений ~s"}. {"Start Modules at ","Запуск модулей на "}. {"Start Modules","Запуск модулей"}. {"Start","Запустить"}. {"Statistics of ~p","статистика узла ~p"}. {"Statistics","Статистика"}. {"Stop Modules at ","Остановка модулей на "}. {"Stop Modules","Остановка модулей"}. {"Stopped Nodes","Остановленные узлы"}. {"Stop","Остановить"}. {"Storage Type","Тип таблицы"}. {"Store binary backup:","Сохранить бинарную резервную копию:"}. {"Store plain text backup:","Сохранить текстовую резервную копию:"}. {"Subject","Тема"}. {"Submitted","Отправлено"}. {"Submit","Отправить"}. {"Subscriber Address","Адрес подписчика"}. {"Subscription","Подписка"}. {"Sunday","Воскресенье"}. {"That nickname is already in use by another occupant","Этот псевдоним уже занят другим участником"}. {"That nickname is registered by another person","Этот псевдоним зарегистрирован кем-то другим"}. {"The CAPTCHA is valid.","Проверка капчи прошла успешно."}. {"The CAPTCHA verification has failed","Проверка капчи не пройдена"}. {"The collections with which a node is affiliated","Имя коллекции, в которую входит узел"}. {"The password is too weak","Слишком слабый пароль"}. {"the password is","пароль:"}. {"The password of your Jabber account was successfully changed.","Пароль Вашего Jabber-аккаунта был успешно изменен."}. {"There was an error changing the password: ","Ошибка при смене пароля:"}. {"There was an error creating the account: ","Ошибка при создании аккаунта:"}. {"There was an error deleting the account: ","Ошибка при удалении аккаунта:"}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Регистр не имеет значения: \"маша\" и \"МАША\" будет считаться одним и тем же именем."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Здесь Вы можете создать Jabber-аккаунт на этом Jabber-сервере. Ваш JID (Jabber-идентификатор) будет в виде: \"пользователь@сервер\". Пожалуйста, внимательно читайте инструкции для правильного заполнения полей."}. {"This page allows to unregister a Jabber account in this Jabber server.","Здесь Вы можете удалить Jabber-аккаунт с этого сервера."}. {"This participant is kicked from the room because he sent an error message to another participant","Этого участника выгнали из комнаты за то, что он послал сообщение об ошибке другому участнику"}. {"This participant is kicked from the room because he sent an error message","Этого участника выгнали из комнаты за то, что он послал сообщение об ошибке"}. {"This participant is kicked from the room because he sent an error presence","Этого участника выгнали из комнаты за то, что он послал присутствие с ошибкой"}. {"This room is not anonymous","Эта комната не анонимная"}. {"Thursday","Четверг"}. {"Time delay","По истечение"}. {"Time","Время"}. {"Too many CAPTCHA requests","Слишком много запросов капчи"}. {"To ~s","К ~s"}. {"To","Кому"}. {"Traffic rate limit is exceeded","Превышен лимит скорости посылки информации"}. {"Transactions Aborted:","Транзакции отмененные:"}. {"Transactions Committed:","Транзакции завершенные:"}. {"Transactions Logged:","Транзакции запротоколированные:"}. {"Transactions Restarted:","Транзакции перезапущенные:"}. {"Tuesday","Вторник"}. {"Unable to generate a CAPTCHA","Не получилось создать капчу"}. {"Unauthorized","Не авторизован"}. {"Unregister a Jabber account","Удалить Jabber-аккаунт"}. {"Unregister","Удалить"}. {"Update message of the day (don't send)","Обновить сообщение дня (не рассылать)"}. {"Update message of the day on all hosts (don't send)","Обновить сообщение дня на всех виртуальных серверах (не рассылать)"}. {"Update plan","План обновления"}. {"Update script","Сценарий обновления"}. {"Update","Обновить"}. {"Update ","Обновление "}. {"Uptime:","Время работы:"}. {"Use of STARTTLS required","Вы обязаны использовать STARTTLS"}. {"User JID","JID пользователя"}. {"User Management","Управление пользователями"}. {"Username:","Имя пользователя:"}. {"Users are not allowed to register accounts so quickly","Пользователи не могут регистрировать учётные записи так быстро"}. {"Users Last Activity","Статистика последнего подключения пользователей"}. {"Users","Пользователи"}. {"User ","Пользователь "}. {"User","Пользователь"}. {"Validate","Утвердить"}. {"vCard User Search","Поиск пользователей по vCard"}. {"Virtual Hosts","Виртуальные хосты"}. {"Visitors are not allowed to change their nicknames in this room","Посетителям запрещено изменять свои псевдонимы в этой комнате"}. {"Visitors are not allowed to send messages to all occupants","Посетителям не разрешается посылать сообщения всем присутствующим"}. {"Voice requests are disabled in this conference","Запросы на право голоса отключены в этой конференции"}. {"Voice request","Запрос на право голоса"}. {"Wednesday","Среда"}. {"When to send the last published item","Когда посылать последний опубликованный элемент"}. {"Whether to allow subscriptions","Разрешить подписку"}. {"You can later change your password using a Jabber client.","Позже Вы можете изменить пароль через Jabber-клиент."}. {"You have been banned from this room","Вам запрещено входить в эту конференцию"}. {"You must fill in field \"Nickname\" in the form","Вы должны заполнить поле \"Псевдоним\" в форме"}. {"You need a client that supports x:data and CAPTCHA to register","Чтобы зарегистрироваться, требуется x:data-совместимый клиент"}. {"You need a client that supports x:data to register the nickname","Чтобы зарегистрировать псевдоним, требуется x:data-совместимый клиент"}. {"You need an x:data capable client to configure mod_irc settings","Чтобы настроить параметры mod_irc, требуется x:data-совместимый клиент"}. {"You need an x:data capable client to configure room","Чтобы сконфигурировать комнату, требуется x:data-совместимый клиент"}. {"You need an x:data capable client to search","Чтобы воспользоваться поиском, требуется x:data-совместимый клиент"}. {"Your active privacy list has denied the routing of this stanza.","Маршрутизация этой строфы запрещена вашим активным списком приватности."}. {"Your contact offline message queue is full. The message has been discarded.","Очередь недоставленных сообщений Вашего адресата переполнена. Сообщение не было сохранено."}. {"Your Jabber account was successfully created.","Ваш Jabber-аккаунт был успешно создан."}. {"Your Jabber account was successfully deleted.","Ваш Jabber-аккаунт был успешно удален."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Ваши сообщения к ~s блокируются. Для снятия блокировки перейдите по ссылке ~s"}. ejabberd-2.1.11/src/msgs/ja.msg0000664000000000000000000007435012240230175013071 0ustar {"Access Configuration","アクセス設定"}. {"Access Control List Configuration","アクセスコントロールリスト設定"}. {"Access control lists","アクセスコントロールリスト"}. {"Access Control Lists","アクセスコントロールリスト"}. {"Access denied by service policy","サービスポリシーによってアクセスが禁止されました"}. {"Access rules","アクセスルール"}. {"Access Rules","アクセスルール"}. {"Action on user","ユーザー操作"}. {"Add Jabber ID","Jabber ID を追加"}. {"Add New","新規追加"}. {"Add User","ユーザーを追加"}. {"Administration of ","管理: "}. {"Administration","管理"}. {"Administrator privileges required","管理者権限が必要です"}. {"A friendly name for the node","ノードのフレンドリネーム"}. {"All activity","すべて"}. {"Allow this Jabber ID to subscribe to this pubsub node?","この Jabber ID に、この pubsubノードの購読を許可しますか ?"}. {"Allow users to change the subject","ユーザーによる題の変更を許可"}. {"Allow users to query other users","ユーザーによる他のユーザーへのクエリーを許可"}. {"Allow users to send invites","ユーザーによる招待を許可"}. {"Allow users to send private messages","ユーザーによるプライベートメッセージの送信を許可"}. {"Allow visitors to change nickname","傍聴者のニックネームの変更を許可"}. {"Allow visitors to send private messages to","傍聴者によるプライベートメッセージの送信を次の相手に許可"}. {"Allow visitors to send status text in presence updates","傍聴者によるプレゼンス更新のステータス文の送信を許可"}. {"Allow visitors to send voice requests","傍聴者による発言権の要求を許可"}. {"All Users","全ユーザー"}. {"Announcements","アナウンス"}. {"anyone","誰にでも"}. {"A password is required to enter this room","この談話室に入るにはパスワードが必要です"}. {"April","4月"}. {"August","8月"}. {"Backup","バックアップ"}. {"Backup Management","バックアップ管理"}. {"Backup of ","バックアップ: "}. {"Backup to File at ","ファイルにバックアップ: "}. {"Bad format","不正なフォーマット"}. {"Birthday","誕生日"}. {"CAPTCHA web page","CAPTCHA ウェブページ"}. {"Change Password","パスワードを変更"}. {"Change User Password","パスワードを変更"}. {"Characters not allowed:","使用できない文字:"}. {"Chatroom configuration modified","談話室の設定が変更されました"}. {"Chatroom is created","談話室を作りました"}. {"Chatroom is destroyed","談話室を削除しました"}. {"Chatroom is started","談話室を開始しました"}. {"Chatroom is stopped","談話室を停止しました"}. {"Chatrooms","談話室"}. {"Choose a username and password to register with this server","サーバーに登録するユーザー名とパスワードを選択してください"}. {"Choose modules to stop","停止するモジュールを選択"}. {"Choose storage type of tables","テーブルのストレージタイプを選択"}. {"Choose whether to approve this entity's subscription.","このエントリを承認するかどうかを選択してください"}. {"City","都道府県"}. {"Commands","コマンド"}. {"Conference room does not exist","会議室は存在しません"}. {"Configuration of room ~s","談話室 ~s の設定"}. {"Configuration","設定"}. {"Connected Resources:","接続リソース:"}. {"Connections parameters","接続パラメーター"}. {"Country","国"}. {"CPU Time:","CPU時間:"}. {"Database","データーベース"}. {"Database Tables at ","データーベーステーブル: "}. {"Database Tables Configuration at ","データーベーステーブル設定 "}. {"December","12月"}. {"Default users as participants","デフォルトのユーザーは参加者"}. {"Delete message of the day on all hosts","全ホストのお知らせメッセージを削除"}. {"Delete message of the day","お知らせメッセージを削除"}. {"Delete Selected","選択した項目を削除"}. {"Delete User","ユーザーを削除"}. {"Delete","削除"}. {"Deliver event notifications","イベント通知を配送する"}. {"Deliver payloads with event notifications","イベント通知と同時にペイロードを配送する"}. {"Description:","説明:"}. {"Disc only copy","ディスクだけのコピー"}. {"Displayed Groups:","表示グループ"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","パスワードは誰にも教えないようにしてください。Jabber サーバーの管理者があなたにパスワードを尋ねることはありません。"}. {"Dump Backup to Text File at ","テキストファイルにバックアップ: "}. {"Dump to Text File","テキストファイルに出力"}. {"Edit Properties","プロパティを編集"}. {"Either approve or decline the voice request.","発言権の要求を承認または却下します。"}. {"ejabberd IRC module","ejabberd IRC module"}. {"ejabberd MUC module","ejabberd MUC module"}. {"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe モジュール"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams モジュール"}. {"ejabberd vCard module","ejabberd vCard モジュール"}. {"ejabberd Web Admin","ejabberd ウェブ管理"}. {"Elements","要素"}. {"Email","メールアドレス"}. {"Enable logging","ロギングを有効"}. {"Encoding for server ~b","サーバーのエンコーディング ~b"}. {"End User Session","エンドユーザーセッション"}. {"Enter list of {Module, [Options]}","{モジュール, [オプション]}のリストを入力してください"}. {"Enter nickname you want to register","登録するニックネームを入力してください"}. {"Enter path to backup file","バックアップファイルのパスを入力してください"}. {"Enter path to jabberd14 spool dir","jabberd14 spool ディレクトリのディレクトリを入力してください"}. {"Enter path to jabberd14 spool file","jabberd14 spool ファイルのパスを入力してください"}. {"Enter path to text file","テキストファイルのパスを入力してください"}. {"Enter the text you see","見えているテキストを入力してください"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","IRC サーバーに接続先するためのユーザー名と文字エンコーディングを入力してください。'Next' を押して次の項目に進みます。'Complete' を押すと設定が保存されます。"}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","IRC サーバーに接続先するために使用するユーザー名、文字エンコーディング、ポート、パスワードを入力してください"}. {"Erlang Jabber Server","Erlang Jabber Server"}. {"Error","エラー"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","例: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","CAPTCHA 試験を免除する Jabber ID"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","サーバーにあるすべてのユーザーデータを PIEFXIS ファイルにエクスポート (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","ホストのユーザーデータを PIEFXIS ファイルにエクスポート (XEP-0227):"}. {"Failed to extract JID from your voice request approval","発言権要求の承認から JID を取り出すことに失敗しました"}. {"Family Name","姓"}. {"February","2月"}. {"Fill in fields to search for any matching Jabber User","欄を埋めて Jabber User を検索してください"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","欄を埋めて Jabber User を検索してください (* を使用すると部分文字列にマッチします)"}. {"Friday","金曜日"}. {"From ~s","差出人 ~s"}. {"From","差出人"}. {"Full Name","氏名"}. {"Get Number of Online Users","オンラインユーザー数を取得"}. {"Get Number of Registered Users","登録ユーザー数を取得"}. {"Get User Last Login Time","最終ログイン時間を取得"}. {"Get User Password","パスワードを取得"}. {"Get User Statistics","ユーザー統計を取得"}. {"Grant voice to this person?","この人に発言権を与えますか ?"}. {"Group ","グループ"}. {"Groups","グループ"}. {"has been banned","はバンされました"}. {"has been kicked","はキックされました"}. {"has been kicked because of an affiliation change","は分掌が変更されたためキックされました"}. {"has been kicked because of a system shutdown","はシステムシャットダウンのためキックされました"}. {"has been kicked because the room has been changed to members-only","は談話室がメンバー制に変更されたためキックされました"}. {" has set the subject to: "," は題を設定しました: "}. {"Host","ホスト"}. {"If you don't see the CAPTCHA image here, visit the web page.","ここに CAPTCHA 画像が表示されない場合、ウェブページを参照してください。"}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","別のポートやパスワード、文字エンコーディングを使用したい場合、'{\"irc server\", \"encoding\", port, \"password\"}' という形式のリストを入力してください。デフォルトでエンコーディングは \"~s\" を使用し、ポートは ~p、パスワードは空になっています。"}. {"Import Directory","ディレクトリインポート"}. {"Import File","ファイルからインポート"}. {"Import user data from jabberd14 spool file:","ユーザーデータを jabberd14 Spool ファイルからインポート:"}. {"Import User from File at ","ファイルからユーザーをインポート: "}. {"Import users data from a PIEFXIS file (XEP-0227):","ユーザーデータを PIEFXIS ファイルからインポート (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","ユーザーデータを jabberd14 Spool ディレクトリからインポート:"}. {"Import Users from Dir at ","ディレクトリからユーザーをインポート: "}. {"Import Users From jabberd14 Spool Files","jabberd14 Spool ファイルからユーザーをインポート"}. {"Improper message type","誤ったメッセージタイプです"}. {"Incorrect password","パスワードが違います"}. {"Invalid affiliation: ~s","無効な分掌です: ~s"}. {"Invalid role: ~s","無効な役です: ~s"}. {"IP addresses","IP アドレス"}. {"IP","IP"}. {"IRC channel (don't put the first #)","IRC チャンネル (先頭に#は不要)"}. {"IRC server","IRC サーバー"}. {"IRC settings","IRC 設定"}. {"IRC Transport","IRC トランスポート"}. {"IRC username","IRC ユーザー名"}. {"IRC Username","IRC ユーザー名"}. {"is now known as","は名前を変更しました: "}. {"It is not allowed to send private messages of type \"groupchat\"","種別が\"groupchat\" であるプライベートメッセージを送信することはできません"}. {"It is not allowed to send private messages to the conference","この会議にプライベートメッセージを送信することはできません"}. {"It is not allowed to send private messages","プライベートメッセージを送信することはできません"}. {"Jabber Account Registration","Jabber アカウント登録"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Jabber ID ~s は無効です"}. {"January","1月"}. {"Join IRC channel","IRC チャンネルに参加"}. {"joins the room","が談話室に参加しました"}. {"Join the IRC channel here.","この IRC チャンネルに参加します。"}. {"Join the IRC channel in this Jabber ID: ~s","Jabber ID: ~s でこの IRC チャンネルに参加"}. {"July","7月"}. {"June","6月"}. {"Last Activity","活動履歴"}. {"Last login","最終ログイン"}. {"Last month","先月"}. {"Last year","去年"}. {"leaves the room","が談話室から退出しました"}. {"Listened Ports at ","Listen ポート "}. {"Listened Ports","Listen ポート"}. {"List of modules to start","起動モジュールの一覧"}. {"Low level update script","低レベル更新スクリプト"}. {"Make participants list public","参加者一覧を公開"}. {"Make room CAPTCHA protected","談話室を CAPTCHA で保護"}. {"Make room members-only","談話室をメンバーのみに制限"}. {"Make room moderated","談話室をモデレート化"}. {"Make room password protected","談話室をパスワードで保護"}. {"Make room persistent","談話室を永続化"}. {"Make room public searchable","談話室を検索可"}. {"March","3月"}. {"Maximum Number of Occupants","最大在室者数"}. {"Max # of items to persist","アイテムの最大保存数"}. {"Max payload size in bytes","最大ぺイロードサイズ (byte)"}. {"May","5月"}. {"Members:","メンバー:"}. {"Membership is required to enter this room","この談話室に入るにはメンバーでなければなりません"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","パスワードは記憶するか、紙に書いて安全な場所に保管してください。もしあなたがパスワードを忘れてしまった場合、Jabber ではパスワードのリカバリを自動的に行うことはできません。"}. {"Memory","メモリ"}. {"Message body","本文"}. {"Middle Name","ミドルネーム"}. {"Minimum interval between voice requests (in seconds)","発言権の要求の最小時間間隔 (秒)"}. {"Moderator privileges required","モデレーター権限が必要です"}. {"moderators only","モデレーターにのみ"}. {"Modified modules","変更されたモジュール"}. {"Module","モジュール"}. {"Modules","モジュール"}. {"Modules at ","モジュール "}. {"Monday","月曜日"}. {"Name","名"}. {"Name:","名前:"}. {"Never","なし"}. {"New Password:","新しいパスワード:"}. {"Nickname","ニックネーム"}. {"Nickname Registration at ","ニックネーム登録: "}. {"Nickname ~s does not exist in the room","ニックネーム ~s はこの談話室にいません"}. {"No body provided for announce message","アナウンスメッセージはありませんでした"}. {"nobody","誰にも許可しない"}. {"No Data","データなし"}. {"Node ","ノード "}. {"Node ID","ノードID"}. {"Node not found","ノードが見つかりません"}. {"Nodes","ノード"}. {"No limit","制限なし"}. {"None","なし"}. {"No resource provided","リソースが提供されませんでした"}. {"Not Found","見つかりません"}. {"Notify subscribers when items are removed from the node","アイテムがノードから消された時に購読者へ通知する"}. {"Notify subscribers when the node configuration changes","ノード設定に変更があった時に購読者へ通知する"}. {"Notify subscribers when the node is deleted","ノードが削除された時に購読者へ通知する"}. {"November","11月"}. {"Number of occupants","在室者の数"}. {"Number of online users","オンラインユーザー数"}. {"Number of registered users","登録ユーザー数"}. {"October","10月"}. {"Offline Messages:","オフラインメッセージ:"}. {"Offline Messages","オフラインメッセージ"}. {"OK","OK"}. {"Old Password:","古いパスワード:"}. {"Online","オンライン"}. {"Online Users:","オンラインユーザー:"}. {"Online Users","オンラインユーザー"}. {"Only deliver notifications to available users","有効なユーザーにのみ告知を送信する"}. {"Only moderators and participants are allowed to change the subject in this room","モデレーターと参加者のみが談話室の題を変更できます"}. {"Only moderators are allowed to change the subject in this room","モデレーターのみが談話室の題を変更できます"}. {"Only moderators can approve voice requests","モデレーターだけが発言権の要求を承認できます"}. {"Only occupants are allowed to send messages to the conference","在室者のみがこの会議にメッセージを送ることができます"}. {"Only occupants are allowed to send queries to the conference","在室者のみが会議にクエリーを送信することができます"}. {"Only service administrators are allowed to send service messages","サービス管理者のみがサービスメッセージを送信できます"}. {"Options","オプション"}. {"Organization Name","会社名"}. {"Organization Unit","部署名"}. {"Outgoing s2s Connections:","外向き s2s コネクション:"}. {"Outgoing s2s Connections","外向き s2s コネクション"}. {"Outgoing s2s Servers:","外向き s2s サービス:"}. {"Owner privileges required","主宰者の権限が必要です"}. {"Packet","パケット"}. {"Password:","パスワード"}. {"Password","パスワード"}. {"Password ~b","パスワード ~b"}. {"Password Verification:","パスワード (確認):"}. {"Password Verification","パスワード (確認)"}. {"Path to Dir","ディレクトリのパス"}. {"Path to File","ファイルのパス"}. {"Pending","保留"}. {"Period: ","期間: "}. {"Persist items to storage","アイテムをストレージに保存する"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","これらのオプションは組み込みの Mnesia データーベースのバックアップのみを行うことに注意してください。もし ODBC モジュールを使用している場合は、SQL データーベースのバックアップを別に行う必要があります。"}. {"Please, wait for a while before sending new voice request","新しい発言権の要求を送るまで少し間をおいてください"}. {"Pong","Pong"}. {"Port","ポート"}. {"Port ~b","ポート ~b"}. {"Present real Jabber IDs to","本当の Jabber ID を公開"}. {"private, ","プライベート、"}. {"Protocol","プロトコル"}. {"Publish-Subscribe","Publish-Subscribe"}. {"PubSub subscriber request","PubSub 購読者のリクエスト"}. {"Purge all items when the relevant publisher goes offline","公開者がオフラインになるときに、すべてのアイテムを削除"}. {"Queries to the conference members are not allowed in this room","この談話室では、会議のメンバーへのクエリーは禁止されています"}. {"RAM and disc copy","RAM, ディスクコピー"}. {"RAM copy","RAM コピー"}. {"Raw","Raw"}. {"Really delete message of the day?","本当にお知らせメッセージを削除しますか ?"}. {"Recipient is not in the conference room","受信者はこの会議室にいません"}. {"Register a Jabber account","Jabber アカウントを登録"}. {"Registered Users:","登録ユーザー:"}. {"Registered Users","登録ユーザー"}. {"Register","登録"}. {"Registration in mod_irc for ","mod_irc での登録: "}. {"Remote copy","リモートコピー"}. {"Remove All Offline Messages","すべてのオフラインメッセージを削除"}. {"Remove User","ユーザーを削除"}. {"Remove","削除"}. {"Replaced by new connection","新しいコネクションによって置き換えられました"}. {"Resources","リソース"}. {"Restart Service","サービスを再起動"}. {"Restart","再起動"}. {"Restore","リストア"}. {"Restore Backup from File at ","ファイルからバックアップをリストア: "}. {"Restore binary backup after next ejabberd restart (requires less memory):","ejabberd の再起動時にバイナリバックアップからリストア (メモリ少):"}. {"Restore binary backup immediately:","直ちにバイナリバックアップからリストア:"}. {"Restore plain text backup immediately:","直ちにプレーンテキストバックアップからリストア:"}. {"Room Configuration","談話室の設定"}. {"Room creation is denied by service policy","サービスポリシーによって談話室の作成が禁止されています"}. {"Room description","談話室の説明"}. {"Room Occupants","在室者"}. {"Room title","談話室のタイトル"}. {"Roster groups allowed to subscribe","名簿グループは購読を許可しました"}. {"Roster of ","名簿: "}. {"Roster size","名簿サイズ"}. {"Roster","名簿"}. {"RPC Call Error","RPC 呼び出しエラー"}. {"Running Nodes","起動ノード"}. {"~s access rule configuration","~s アクセスルール設定"}. {"Saturday","土曜日"}. {"Script check","スクリプトチェック"}. {"Search Results for ","検索結果: "}. {"Search users in ","ユーザーの検索: "}. {"Send announcement to all online users on all hosts","全ホストのオンラインユーザーにアナウンスを送信"}. {"Send announcement to all online users","すべてのオンラインユーザーにアナウンスを送信"}. {"Send announcement to all users on all hosts","全ホストのユーザーにアナウンスを送信"}. {"Send announcement to all users","すべてのユーザーにアナウンスを送信"}. {"September","9月"}. {"Server:","サーバー:"}. {"Server ~b","サーバー ~b"}. {"Set message of the day and send to online users","お知らせメッセージを設定し、オンラインユーザーに送信"}. {"Set message of the day on all hosts and send to online users","全ホストのお知らせメッセージを設定し、オンラインユーザーに送信"}. {"Shared Roster Groups","共有名簿グループ"}. {"Show Integral Table","累積の表を表示"}. {"Show Ordinary Table","通常の表を表示"}. {"Shut Down Service","サービスを停止"}. {"~s invites you to the room ~s","~s はあなたを談話室 ~s に招待しています"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Jabber クライアントはコンピューターにパスワードを記憶できます。コンピューターが安全であると信頼できる場合にのみ、この機能を使用してください。"}. {"Specify the access model","アクセスモデルを設定する"}. {"Specify the event message type","イベントメッセージ種別を設定"}. {"Specify the publisher model","公開モデルを指定する"}. {"~s's Offline Messages Queue","~s' のオフラインメッセージキュー"}. {"Start Modules at ","モジュールを開始: "}. {"Start Modules","モジュールを起動"}. {"Start","開始"}. {"Statistics of ~p","~p の統計"}. {"Statistics","統計"}. {"Stop Modules at ","モジュールを停止: "}. {"Stop Modules","モジュールを停止"}. {"Stopped Nodes","停止ノード"}. {"Stop","停止"}. {"Storage Type","ストレージタイプ"}. {"Store binary backup:","バイナリバックアップを保存:"}. {"Store plain text backup:","プレーンテキストバックアップを保存:"}. {"Subject","題"}. {"Submitted","送信完了"}. {"Submit","送信"}. {"Subscriber Address","購読者のアドレス"}. {"Subscription","認可"}. {"Sunday","日曜日"}. {"That nickname is already in use by another occupant","そのニックネームは既にほかの在室者によって使用されています"}. {"That nickname is registered by another person","ニックネームはほかの人によって登録されています"}. {"The CAPTCHA is valid.","CAPTCHA は有効です。"}. {"The CAPTCHA verification has failed","CAPTCHA 検証は失敗しました"}. {"The collections with which a node is affiliated","提携されたノードの集合です"}. {"the password is","パスワードは"}. {"The password is too weak","このパスワードは単純過ぎます"}. {"The password of your Jabber account was successfully changed.","Jabber アカウントのパスワード変更に成功しました。"}. {"There was an error changing the password: ","パスワードの変更中にエラーが発生しました: "}. {"There was an error creating the account: ","アカウントの作成中にエラーが発生しました: "}. {"There was an error deleting the account: ","アカウントの削除中にエラーが発生しました: "}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","大文字と小文字は区別しません: macbeth は MacBeth や Macbeth と同じです。"}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","ここはこの Jabber サーバーにアカウントを作成するページです。あなたの JID (JabberID) は username@server のような形式になります。注意事項どおり、正しく項目を記入してください。"}. {"This page allows to unregister a Jabber account in this Jabber server.","ここはこの Jabber サーバーのアカウントを削除するページです。"}. {"This participant is kicked from the room because he sent an error message to another participant","他の参加者にエラーメッセージを送信したため、この参加者はキックされました"}. {"This participant is kicked from the room because he sent an error message","エラーメッセージを送信したため、この参加者はキックされました"}. {"This participant is kicked from the room because he sent an error presence","エラープレゼンスを送信したため、この参加者はキックされました"}. {"This room is not anonymous","この談話室は非匿名です"}. {"Thursday","木曜日"}. {"Time delay","遅延時間"}. {"Time","時間"}. {"Too many CAPTCHA requests","CAPTCHA 要求が多すぎます"}. {"To ~s","宛先 ~s"}. {"To","宛先"}. {"Traffic rate limit is exceeded","トラフィックレートの制限を超えました"}. {"Transactions Aborted:","トランザクションの失敗:"}. {"Transactions Committed:","トランザクションのコミット:"}. {"Transactions Logged:","トランザクションのログ: "}. {"Transactions Restarted:","トランザクションの再起動:"}. {"Tuesday","火曜日"}. {"Unable to generate a CAPTCHA","CAPTCHA を生成できません"}. {"Unauthorized","認証されていません"}. {"Unregister a Jabber account","Jabber アカウントを削除"}. {"Unregister","削除"}. {"Update message of the day (don't send)","お知らせメッセージを更新 (送信しない)"}. {"Update message of the day on all hosts (don't send)","全ホストのお知らせメッセージを更新 (送信しない)"}. {"Update plan","更新計画"}. {"Update script","スクリプトの更新"}. {"Update ","更新 "}. {"Update","更新"}. {"Uptime:","起動時間:"}. {"Use of STARTTLS required","STARTTLS の使用が必要です"}. {"User ","ユーザー "}. {"User","ユーザー"}. {"User JID","ユーザー JID"}. {"User Management","ユーザー管理"}. {"Username:","ユーザー名:"}. {"Users","ユーザー"}. {"Users are not allowed to register accounts so quickly","それほど速くアカウントを登録することはできません"}. {"Users Last Activity","ユーザーの活動履歴"}. {"Validate","検証"}. {"vCard User Search","vCard ユーザー検索"}. {"Virtual Hosts","ヴァーチャルホスト"}. {"Visitors are not allowed to change their nicknames in this room","傍聴者はこの談話室でニックネームを変更することはできません"}. {"Visitors are not allowed to send messages to all occupants","傍聴者はすべての在室者にメッセージを送信することはできません"}. {"Voice requests are disabled in this conference","この会議では、発言権の要求はできません"}. {"Voice request","発言権を要求"}. {"Wednesday","水曜日"}. {"When to send the last published item","最後の公開アイテムを送信するタイミングで"}. {"Whether to allow subscriptions","購読を許可するかどうか"}. {"You can later change your password using a Jabber client.","あなたは後で Jabber クライアントを使用してパスワードを変更できます。"}. {"You have been banned from this room","あなたはこの談話室からバンされています"}. {"You must fill in field \"Nickname\" in the form","フォームの\"ニックネーム\"欄を入力する必要があります"}. {"You need a client that supports x:data and CAPTCHA to register","登録を行うには x:data と CAPTCHA をサポートするクライアントが必要です"}. {"You need a client that supports x:data to register the nickname","ニックネームを登録するには x:data をサポートするクライアントが必要です"}. {"You need an x:data capable client to configure mod_irc settings","mod_irc の設定には x:data をサポートするクライアントが必要です"}. {"You need an x:data capable client to configure room","談話室を設定するには x:data をサポートするクライアントが必要です"}. {"You need an x:data capable client to search","検索を行うためには x:data をサポートするクライアントが必要です"}. {"Your active privacy list has denied the routing of this stanza.","あなたのプライバシーリストはこのスタンザのルーティングを拒否しました。"}. {"Your contact offline message queue is full. The message has been discarded.","相手先のオフラインメッセージキューが一杯です。このメッセージは破棄されます。"}. {"Your Jabber account was successfully created.","Jabber アカウントの作成に成功しました。"}. {"Your Jabber account was successfully deleted.","Jabber アカウントの削除に成功しました。"}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","~s 宛のメッセージはブロックされています。解除するにはこちらを見てください ~s"}. ejabberd-2.1.11/src/msgs/eo.po0000664000000000000000000015332612240230175012733 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" "Last-Translator: Andreas van Cranenburgh \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Esperanto\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Uzo de STARTTLS bezonata" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Neniu risurco donita" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Anstataŭigita je nova konekto" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "Via aktiva privatec-listo malpermesas enkursigi ĉi-tiun pakaĵon" #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Enmetu montrita teksto" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "Viaj mesaĝoj al ~s estas blokata. Por malbloki ilin, iru al ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "Se vi ne vidas la CAPTCHA-imagon jene, vizitu la teksaĵ-paĝon." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "CAPTCHA teksaĵ-paĝo" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "La CAPTCHA ĝustas" #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Ordonoj" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Sondaĵo" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Resondaĵo" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Ĉu vere forigi mesaĝon de la tago?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Temo" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Teksto de mesaĝo" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Neniu teksto donita por anonc-mesaĝo" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Anoncoj" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Sendu anoncon al ĉiu uzanto" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Sendu anoncon al ĉiu uzanto de ĉiu gastigo" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Sendu anoncon al ĉiu konektata uzanto" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Sendu anoncon al ĉiu konektata uzanto de ĉiu gastigo" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Enmetu mesaĝon de la tago kaj sendu al konektataj uzantoj" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Enmetu mesaĝon de la tago je ĉiu gastigo kaj sendu al konektataj uzantoj" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Ŝanĝu mesaĝon de la tago (ne sendu)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Ŝanĝu mesaĝon de la tago je ĉiu gastigo (ne sendu)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Forigu mesaĝo de la tago" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Forigu mesaĝo de la tago je ĉiu gastigo" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Agordo" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Datumbazo" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Startu Modulojn" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Haltigu Modulojn" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Faru Sekurkopion" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Restaŭru" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Skribu en plata tekst-dosiero" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Importu dosieron" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Importu dosierujo" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Restartu Servon" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Haltigu Servon" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Aldonu Uzanton" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Forigu Uzanton" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Haltigu Uzant-seancon" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Montru pasvorton de uzanto" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Ŝanĝu pasvorton de uzanto" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Montru tempon de lasta ensaluto" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Montru statistikojn de uzanto" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Montru nombron de registritaj uzantoj" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Montru nombron de konektataj uzantoj" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Atingokontrol-listoj" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Atingo-reguloj" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Uzanto-administrado" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Konektataj Uzantoj" #: mod_configure.erl:501 msgid "All Users" msgstr "Ĉiuj Uzantoj" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Elirantaj s-al-s-konektoj" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Funkciantaj Nodoj" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Neaktivaj Nodoj" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Moduloj" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Mastrumado de sekurkopioj" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importu uzantojn de jabberd14-uzantdosieroj" #: mod_configure.erl:699 msgid "To ~s" msgstr "Al ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "De ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Agordo de datumbaz-tabeloj je " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Elektu konserv-tipon de tabeloj" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Nur disk-kopio" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "RAM- kaj disk-kopio" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "RAM-kopio" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Fora kopio" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Haltigu modulojn je " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Elektu modulojn por fini" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Startu modulojn je " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Enmetu liston de {Modulo, [Elektebloj]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Listo de moduloj por starti" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Faru sekurkopion je " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Enmetu vojon por sekurkopio" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Voje de dosiero" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Restaŭrigu de dosiero el " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Skribu sekurkopion en plata teksto al " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Enmetu vojon al plata teksto" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importu uzanton de dosiero el " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Enmetu vojon al jabberd14-uzantdosiero" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importu uzantojn de dosierujo ĉe " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Enmetu vojon al jabberd14-uzantdosierujo" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Vojo al dosierujo" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Prokrasto" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Agordo de atingokontrolo" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Atingokontrol-listoj" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Agordo de atingo" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Atingo-reguloj" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Pasvorto" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Pasvortkontrolo" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Nombro de registritaj uzantoj" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Nombro de konektataj uzantoj" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Neniam" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Konektata" #: mod_configure.erl:1701 msgid "Last login" msgstr "Lasta ensaluto" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Kontaktlist-grando" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "IP-adresoj" #: mod_configure.erl:1724 msgid "Resources" msgstr "Risurcoj" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Mastrumado de " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Ago je uzanto" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Redaktu atributojn" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Forigu uzanton" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Atingo rifuzita de serv-politiko" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC-transportilo" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC-modulo" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "Vi bezonas klienton kun x:data-funkcio por agordi mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Registraĵo en mod_irc de " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Enmetu uzantnomon,j enkodigojn, pordojn kaj pasvortojn kiujn vi volas uzi " "por konektoj al IRC-serviloj" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "IRC-kaŝnomo" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Se vi volas specifi diversajn pordojn, pasvortojn, enkodigojn por IRC-" "serviloj, kompletigu la jenan liston kun la formo '{\"irc-servilo\", " "\"enkodigo\", porto, \"pasvorto\"}'. Se ne specifita, ĉi tiu servilo uzas la " "enkodigo \"~s\", porto ~p, malplena pasvorto." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Ekzemplo: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"sekreto\"}, {\"vendetta." "fef.net\", \"iso8859-1\", 7000}, {\"irc.iutestservilo.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Konekto-parametroj" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Eniras IRC-babilejon" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "IRC-babilejo (ne aldonu #-prefikson)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "IRC-servilo" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Eniru IRC-babilejon jen" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Eniru IRC-babilejon en ĉi Jabber-ID: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "IRC agordoj" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 #, fuzzy msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Enmetu uzantnomon kaj enkodigoj kiujn vi volas uzi por konektoj al IRC-" "serviloj. Elektu \"Sekvonto\" por ekhavi pliajn kampojn. Elektu \"Kompletigu" "\" por savi agordojn." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "IRC-uzantnomo" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Pasvorto ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Pordo ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Enkodigo por servilo ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Servilo ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "Nur servo-administrantoj rajtas sendi serv-mesaĝojn" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Ĉi tiu serv-politiko ne permesas babilejo-kreadon" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Babilejo ne ekzistas" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Babilejoj" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "Vi bezonas klienton subtenante x:data-funkcio por registri kaŝnomon" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Kaŝnomo-registrado je " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Enmetu kaŝnomon kiun vi volas registri" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Kaŝnomo" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Kaŝnomo estas registrita de alia persono" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Vi devas kompletigi la \"Kaŝnomo\" kampon" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC-modulo" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Agordo de babilejo ŝanĝita" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "eniras la babilejo" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "eliras la babilejo" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "estas forbarita" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "estas forpelita" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "estas forpelita pro aparteneca ŝanĝo" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "estas forpelita ĉar la babilejo fariĝis sole por membroj" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "estas forpelita pro sistem-haltigo" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "nun nomiĝas" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " ŝanĝis la temon al: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Babilejo kreita" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Babilejo neniigita" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Babilejo lanĉita" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Babilejo haltita" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Lundo" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Mardo" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Merkredo" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Ĵaŭdo" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Vendredo" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Sabato" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Dimanĉo" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Januaro" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Februaro" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Marĉo" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "Aprilo" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Majo" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Junio" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Julio" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Aŭgusto" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "Septembro" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Oktobro" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "Novembro" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "Decembro" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Babilejo-agordo" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Nombro de ĉeestantoj" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Trafikrapida limigo superita" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Ĉi tiu partoprenanta estas forpelata de la babilejo pro sendado de erar-" "mesaĝo" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Nur partoprenantoj rajtas sendi privatajn mesaĝojn al la babilejo" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "Bonvolu atendi iomete antaŭ ol sendi plian voĉ-peton" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "Voĉ-petoj estas malebligita en jena babilejo" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "Malsukcesis ekstrakti JID-on de via voĉ-pet-aprobo" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Nur moderigantoj povas aprobi voĉ-petojn" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Malĝusta mesaĝo-tipo" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Ĉi tiu partoprenanto estas forpelata de la babilejo pro sendo de erar-mesaĝo " "al alia partoprenanto" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "Malpermesas sendi mesaĝojn de tipo \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Ricevanto ne ĉeestas en la babilejo " #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Ne estas permesata sendi privatajn mesaĝojn" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Nur partoprenantoj rajtas sendi mesaĝojn al la babilejo" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Nur partoprenantoj rajtas sendi informmendojn al la babilejoj" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "Malpermesas informmendoj al partoprenantoj en ĉi tiu babilejo" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Nur moderigantoj kaj partoprenantoj rajtas ŝanĝi la temon en ĉi tiu babilejo" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Nur moderigantoj rajtas ŝanĝi la temon en ĉi tiu babilejo" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Vizitantoj ne rajtas sendi mesaĝojn al ĉiuj partoprenantoj" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Ĉi tiu partoprenanto estas forpelata de la babilejo pro sendo de erar-ĉeesto" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "" "Ne estas permesata al vizitantoj ŝanĝi siajn kaŝnomojn en ĉi tiu ĉambro" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Tiu kaŝnomo jam estas uzata de alia partoprenanto" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Vi estas malpermesata en ĉi tiu babilejo" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Membreco estas bezonata por eniri ĉi tiun babilejon" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Ĉi tiu babilejo ne estas anonima" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Pasvorto estas bezonata por eniri ĉi tiun babilejon" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Tro multaj CAPTCHA-petoj" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Ne eblis krei CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Nekorekta pasvorto" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Administrantaj rajtoj bezonata" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Moderantaj rajtoj bezonata" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Jabber ID ~s estas nevalida" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Kaŝnomo ~s ne ekzistas en la babilejo" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Nevalida aparteneco: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Nevalida rolo: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Mastraj rajtoj bezonata" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Agordo de babilejo ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Babilejo-nomo" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Babilejo-priskribo" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Farigu babilejon daŭra" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Farigu babilejon publike trovebla" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Farigu partoprento-liston publika" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Farigu babilejon protektata per pasvorto" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Limigo de nombro de partoprenantoj" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Neniu limigo" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Montru verajn Jabber ID-ojn al" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "moderantoj sole" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "iu ajn" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Farigu babilejon sole por membroj" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Farigu babilejon moderigata" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Kutime farigu uzantojn kiel partpoprenantoj" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Permesu uzantojn ŝanĝi la temon" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Permesu uzantojn sendi privatajn mesaĝojn" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "Permesu uzantojn sendi privatajn mesaĝojn al" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "neniu" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Permesu uzantojn informpeti aliajn uzantojn" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Permesu uzantojn sendi invitojn" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "Permesu al vizitantoj sendi statmesaĝon en ĉeest-sciigoj" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Permesu al vizitantoj ŝanĝi siajn kaŝnomojn" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "Permesu uzantojn sendi voĉ-petojn" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "Minimuma intervalo inter voĉ-petoj (je sekundoj)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Farigu babilejon protektata per CAPTCHA" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Esceptu Ĵabber-identigilojn je CAPTCHA-defio" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Ŝaltu protokoladon" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Vi bezonas klienton kun x:data-funkcio por agordi la babilejon" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Nombro de ĉeestantoj" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privata, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Voĉ-peto" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Ĉu aprobu, aŭ malaprobu la voĉ-peton." #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "Uzant-JID" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "Koncedu voĉon al ĉi-persono?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s invitas vin al la babilejo ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "la pasvorto estas" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "Mesaĝo-atendovico de la senkonekta kontakto estas plena. La mesaĝo estas " "forĵetita" #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "Mesaĝo-atendovico de ~s" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Sendita" #: mod_offline.erl:571 msgid "Time" msgstr "Tempo" #: mod_offline.erl:572 msgid "From" msgstr "De" #: mod_offline.erl:573 msgid "To" msgstr "Ĝis" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Pakaĵo" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Forigu elektata(j)n" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Liverontaj mesaĝoj" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Forigu ĉiujn liverontajn mesaĝojn" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bajtfluo modulo" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Public-Abonado" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "ejabberd Public-Abonada modulo" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "PubAbo abonpeto" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Elektu ĉu permesi la abonon de ĉi tiu ento" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "Nodo ID" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Abonanta adreso" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Ĉu permesi ĉi tiun Jabber ID aboni al la jena PubAbo-nodo" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Liveru aĵojn de event-sciigoj" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Liveru event-sciigojn" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Sciigu abonantoj kiam la agordo de la nodo ŝanĝas" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Sciigu abonantoj kiam la nodo estas forigita" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Sciigu abonantoj kiam eroj estas forigita de la nodo" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Savu erojn en konservado" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Kromnomo por ĉi tiu nodo" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Maksimuma kiomo de eroj en konservado" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Ĉu permesi aboni" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Specifu atingo-modelon" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Kontaktlist-grupoj kiuj rajtas aboni" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Enmetu publikadan modelon" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "Forigu ĉiujn erojn kiam la rilata publikanto malkonektiĝas" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Specifu tipo de event-mesaĝo" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Maksimuma aĵo-grando je bajtoj" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Kiam sendi la laste publicitan eron" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Nur liveru sciigojn al konektataj uzantoj" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Aro kun kiu nodo estas filigita" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "La CAPTCHA-kontrolado malsukcesis" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "Vi bezonas klienton subtenante x:data-funkcio kaj CAPTCHA por registri " "kaŝnomon" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Elektu uzantnomon kaj pasvorton por registri je ĉi tiu servilo" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Uzanto" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "La pasvorto estas ne sufiĉe forta" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Ne estas permesata al uzantoj registri tiel rapide" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Nenio" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Abono" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Atendanta" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Grupoj" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Validigu" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Forigu" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Kontaktlisto de " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Malĝusta formo" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Aldonu Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Kontaktlisto" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Komuna Kontaktlist-grupo" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Aldonu novan" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Nomo:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Priskribo:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Membroj:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Montrataj grupoj:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Grupo " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Sendu" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang-a Jabber-Servilo" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Naskiĝtago" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Urbo" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Lando" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Retpoŝto" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Lasta Nomo" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Kompletigu la formon por serĉi rekonata Jabber-uzanto (Aldonu * je la fino " "de la kampo por rekoni subĉenon" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Plena Nomo" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Meza Nomo" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Nomo" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Organiz-nomo" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Organiz-parto" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Serĉu uzantojn en " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Vi bezonas klienton kun x:data-funkcio por serĉado" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Serĉado de vizitkartoj" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard-modulo" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Serĉ-rezultoj de " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Kompletigu la formon por serĉi rekonata Jabber-uzanto" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Nepermesita" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd Teksaĵa Administro" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Administro" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Kruda" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Agordo de atingo-reguloj de ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Virtual-gastigoj" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Uzantoj" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Lasta aktiveco de uzanto" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Periodo: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Lasta monato" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Lasta jaro" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Ĉiu aktiveco" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Montru ordinaran tabelon" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Montru integran tabelon" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Statistikoj" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Ne trovita" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Nodo ne trovita" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Gastigo" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Registritaj uzantoj" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Liverontaj mesaĝoj" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Lasta aktiveco" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Registritaj uzantoj:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Konektataj uzantoj:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Elirantaj s-al-s-konektoj:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Elirantaj s-al-s-serviloj" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Ŝanĝu pasvorton" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Uzanto " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Konektataj risurcoj:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Pasvorto:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Neniu datumo" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Nodoj" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Nodo " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Atentataj pordoj" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Ĝisdatigu" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Restartu" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Haltigu" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Eraro de RPC-alvoko" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Datumbaz-tabeloj je " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Konserv-tipo" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Eroj" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Memoro" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Eraro" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Sekurkopio de " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Rimarku ke ĉi tiuj elektebloj nur sekurkopias la propran Mnesia-datumbazon. " "Se vi uzas la ODBC-modulon, vi ankaŭ devas sekurkopii tiujn SQL-datumbazoj " "aparte." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Konservu duuman sekurkopion:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "Bone" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Restaŭrigu duuman sekurkopion tuj:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "Restaŭrigu duuman sekurkopion post sekvonta ejabberd-restarto" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Skribu sekurkopion en plata tekstdosiero" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Restaŭrigu sekurkopion el plata tekstdosiero tuj" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Importu uzanto-datumojn de PIEFXIS dosiero (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Eksportu datumojn de ĉiuj uzantoj en servilo al PIEFXIS dosieroj (XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "Eksportu datumoj de uzantoj en gastigo al PIEFXIS dosieroj (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importu uzantojn de jabberd14-uzantdosieroj" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importu uzantojn de jabberd14-uzantdosieroj" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Atentataj pordoj je " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Moduloj je " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Statistikoj de ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Daŭro de funkciado" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "CPU-tempo" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transakcioj enmetitaj" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transakcioj nuligitaj" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transakcioj restartitaj" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transakcioj protokolitaj" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Ĝisdatigu " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Ĝisdatigo-plano" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Ĝisdatigitaj moduloj" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Ĝisdatigo-skripto" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Bazanivela ĝisdatigo-skripto" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Skript-kontrolo" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Pordo" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protokolo" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Modulo" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Elektebloj" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Forigu" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Startu" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Via Ĵabber-konto estis sukcese kreata." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Estis eraro dum kreado de la konto:" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Via Ĵabber-konto estas sukcese forigita." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Estis eraro dum forigado de la konto:" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "La pasvorto de via Ĵabber-konto estas sukcese ŝanĝata." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Estis eraro dum ŝanĝi de la pasvortro:" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Ĵabber-konto registrado" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Registru Ĵabber-konton" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Malregistru Ĵabber-konton" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Jena paĝo ebligas kreadon de Ĵabber-konto je ĉi-Ĵabber-servilo. Via JID " "(Ĵabber-IDentigilo) estos ĉi-tiel: uzantnomo@servilo. Bonvolu legu bone la " "instrukciojn por korekta enmetigo de la kampoj. " #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Uzantnomo" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "Uskleco ne signifas: macbeth estas la sama ol MacBeth kaj Macbeth." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Karaktroj ne permesata:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Servilo:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "Ne donu vian pasvorton al iun ajn, eĉ ne al la administrantoj de la Ĵabber-" "servilo." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "Poste vi povas ŝanĝi vian pasvorton per Ĵabber-kliento." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Kelkaj Ĵabber-klientoj povas memori vian pasvorton je via komputilo. Nur uzu " "tiun eblon se vi fidas ke via komputilo estas sekura." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Memoru vian pasvorton, aŭ skribu ĝin sur papero formetata je sekura loko. Je " "Ĵabber ne ekzistas aŭtomata metodo por reakiri vian pasvorton se vi forgesas " "ĝin." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Pasvortkontrolo:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Registru" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Malnova Pasvorto:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Nova Pasvorto:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "Jena pagxo ebligas malregistri Jxabber-konton je ĉi-servilo." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Malregistru" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "La aŭtomata Turingtesto estas ĝusta" #~ msgid "Encodings" #~ msgstr "Enkodigoj" #~ msgid "(Raw)" #~ msgstr "(Kruda)" #~ msgid "Specified nickname is already registered" #~ msgstr "Donita kaŝnomo jam estas registrita" #~ msgid "Size" #~ msgstr "Grando" #~ msgid "You must fill in field \"nick\" in the form" #~ msgstr "Vi devas enmeti kampon \"kaŝnomo\"" ejabberd-2.1.11/src/msgs/cs.po0000664000000000000000000015463012240230175012734 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "Last-Translator: Lukáš Polívka [spike411] xmpp:spike411@jabber.cz\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Czech (čeština)\n" "X-Additional-Translator: Milos Svasek [DuxforD] from openheads.net\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Je vyžadováno STARTTLS" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Nebyl poskytnut žádný zdroj" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Nahrazeno novým spojením" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "Vaše nastavení soukromí znemožnilo směrování této stance." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Zadejte text, který vidíte" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "Nesmíte posílat zprávy na ~s. Pro povolení navštivte ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "Pokud zde nevidíte obrázek CAPTCHA, přejděte na webovou stránku." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "Webová stránka CAPTCHA" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "CAPTCHA souhlasí." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Příkazy" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Skutečně smazat zprávu dne?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Předmět" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Tělo zprávy" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Zpráva neobsahuje text" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Oznámení" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Odeslat oznámení všem uživatelům" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Odeslat oznámení všem uživatelům na všech hostitelích" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Odeslat oznámení všem online uživatelům" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Odeslat oznámení všem online uživatelům na všech hostitelích" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Nastavit zprávu dne a odeslat ji online uživatelům" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "Nastavit zprávu dne a odeslat ji online uživatelům" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Aktualizovat zprávu dne (neodesílat)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Aktualizovat zprávu dne pro všechny hostitele (neodesílat)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Smazat zprávu dne" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Smazat zprávu dne na všech hostitelích" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Konfigurace" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Databáze" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Spustit moduly" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Zastavit moduly" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Zálohovat" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Obnovit" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Uložit do textového souboru" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Import souboru" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Import adresáře" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Restartovat službu" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Vypnout službu" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Přidat uživatele" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Smazat uživatele" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Ukončit sezení uživatele" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Získat heslo uživatele" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Změnit heslo uživatele" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Získat čas podleního přihlášení uživatele" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Získat statistiky uživatele" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Získat počet registrovaných uživatelů" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Získat počet online uživatelů" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Seznamy přístupových práv (ACL)" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Pravidla přístupů" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Správa uživatelů" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Online uživatelé" #: mod_configure.erl:501 msgid "All Users" msgstr "Všichni uživatelé" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Odchozí s2s spojení" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Běžící uzly" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Zastavené uzly" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Moduly" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Správa zálohování" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importovat uživatele z jabberd14 spool souborů" #: mod_configure.erl:699 msgid "To ~s" msgstr "Pro ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Od ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Konfigurace databázových tabulek " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Vyberte typ úložiště pro tabulky" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Jen kopie disku" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Kopie RAM a disku" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Kopie RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Vzdálená kopie" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Zastavit moduly na " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Vyberte moduly, které mají být zastaveny" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Spustit moduly na " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Vložte seznam modulů {Modul, [Parametry]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Seznam modulů, které mají být spuštěné" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Záloha do souboru na " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Zadajte cestu k souboru se zálohou" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Cesta k souboru" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Obnovit zálohu ze souboru na " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Uložit zálohu do textového souboru na " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Zadajte cestu k textovému souboru" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importovat uživatele ze souboru na " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Zadejte cestu k spool souboru jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importovat uživatele z adresáře na " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Zadejte cestu k jabberd14 spool adresáři" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Cesta k adresáři" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Časový posun" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Konfigurace seznamu přístupových práv (ACL)" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Seznamy přístupových práv (ACL)" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Konfigurace přístupů" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Pravidla přístupů" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Heslo" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Ověření hesla" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Počet registrovaných uživatelů" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Počet online uživatelů" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Nikdy" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Online" #: mod_configure.erl:1701 msgid "Last login" msgstr "Poslední přihlášení" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Velikost seznamu kontaktů" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "IP adresy" #: mod_configure.erl:1724 msgid "Resources" msgstr "Zdroje" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Administrace " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Akce aplikovaná na uživatele" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Upravit vlastnosti" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Odstranit uživatele" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Přístup byl zamítnut nastavením služby" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC transport" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC modul" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "Pro konfiguraci mod_irc potřebujete klienta s podporou x:data" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Registrace do mod_irc na " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Zadejte přezdívku, kódování, porty a hesla, které chcete používat pro " "připojení k serverům IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "IRC přezdívka" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Pokud chcete zadat jiné kódování pro IRC servery, vyplňte seznam s hodnotami " "ve formátu '{\"irc server\",\"encoding\", port, \"password\"}'. Výchozí " "kódování pro tuto službu je \"~s\", port ~p, empty password." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Příklad: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].2\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Parametry spojení" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Vstoupit do IRC kanálu" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "IRC kanál (bez počátečního #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "IRC přezdívka" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Vstoupit do tohoto IRC kanálu." #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Vstupte do IRC kanálu s tímto Jabber ID: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "Nastavení IRC" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Zadejte přezdívku a kódování, které chcete používat pro připojení k serverům " "IRC. Stiskněte 'Další' pro více políček k vyplnění. Stiskněte 'Dokončit' pro " "uložení nastavení." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "IRC přezdívka" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Heslo ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Port ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Kódování pro server ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Server ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "Pouze správci služby smí odesílat servisní zprávy" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Pravidla služby nepovolují vytvořit místnost" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Konferenční místnost neexistuje" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Konference" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "Pro registraci přezdívky potřebujete klienta s podporou x:data" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Registrace přezdívky na " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Zadejte přezdívku, kterou chcete zaregistrovat" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Přezdívka" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Přezdívka je zaregistrována jinou osobou" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Musíte vyplnit políčko \"Přezdívka\" ve formuláři" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC modul" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Nastavení diskuzní místnosti bylo změněno" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "vstoupil(a) do místnosti" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "opustil(a) místnost" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "byl(a) zablokován(a)" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "byl(a) vyhozen(a) z místnosti" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "byl(a) vyhozen(a) kvůli změně přiřazení" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "byl(a) vyhozen(a), protože mísnost je nyní pouze pro členy" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "byl(a) vyhozen(a), protože dojde k vypnutí systému" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "se přejmenoval(a) na" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " změnil(a) téma na: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Konference vytvořena" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Konference zrušena" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Konference spuštěna" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Konference zastavena" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Pondělí" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Úterý" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Středa" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Čtvrtek" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Pátek" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Sobota" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Neděle" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr ". ledna" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr ". února" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr ". března" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr ". dubna" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr ". května" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr ". června" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr ". července" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr ". srpna" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr ". září" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr ". října" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr ". listopadu" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr ". prosince" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Nastavení místnosti" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Počet účastníků" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Byl překročen limit" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "Tento účastník byl vyhozen, protože odeslal chybovou zprávu" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Není povoleno odesílat soukromé zprávy do konference" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "Prosím, počkejte chvíli před posláním nové žádosti o voice práva" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "Voice žádosti jsou v této konferenci zakázány" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "Došlo k chybě při získávání Jabber ID z vaší žádosti o voice práva" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Pouze moderátoři mohou schválit žádosti o voice práva" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Nesprávný typ zprávy" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Tento účastník byl vyhozen, protože odeslal chybovou zprávu jinému " "účastníkovi" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "Není dovoleno odeslání soukromé zprávy typu \"skupinová zpráva\" " #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Příjemce se nenachází v konferenční místnosti" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Je zakázáno posílat soukromé zprávy" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Jen členové mají povolené zasílat zprávy do konference" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Jen členové mohou odesílat požadavky (query) do konference" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "" "Požadavky (queries) na členy konference nejsou v této místnosti povolené" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "Jen moderátoři a účastníci mají povoleno měnit téma této místnosti" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Jen moderátoři mají povoleno měnit téma místnosti" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Návštevníci nemají povoleno zasílat zprávy všem účastníkům konference" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "Tento účastník byl vyhozen, protože odeslal chybový status" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Návštěvníkům této místnosti je zakázáno měnit přezdívku" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Přezdívka je již používána jiným členem" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Byl jste vyloučen z této místnosti" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Pro vstup do místnosti musíte být členem" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Tato místnost není anonymní" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Pro vstup do místnosti musíte zadat heslo" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Přiliš mnoho CAPTCHA žádostí" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Nebylo možné vygenerovat CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Nesprávné heslo" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Potřebujete práva administrátora" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Potřebujete práva moderátora" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Jabber ID ~s je neplatné" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Přezdívka ~s v místnosti neexistuje" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Neplatné přiřazení: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Neplatná role: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Jsou vyžadována práva vlastníka" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Konfigurace místnosti ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Název místnosti" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Popis místnosti" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Nastavit místnost jako stálou" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Nastavit místnost jako veřejnou" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Nastavit seznam účastníků jako veřejný" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Chránit místnost heslem" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Počet účastníků" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Bez limitu" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Odhalovat skutečná Jabber ID" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "moderátorům" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "každému" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Zpřístupnit místnost jen členům" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Nastavit místnost jako moderovanou" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Uživatelé jsou implicitně členy" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Povolit uživatelům měnit téma místnosti" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Povolit uživatelům odesílat soukromé zprávy" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "Povolit návštěvníkům odesílat soukromé zprávy" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "nikdo" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Povolit uživatelům odesílat požadavky (query) ostatním uživatelům" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Povolit uživatelům posílání pozvánek" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "Povolit návštěvníkům posílat stavové zprávy ve statusu" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Povolit návštěvníkům měnit přezdívku" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "Povolit uživatelům posílat žádosti o voice práva" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "Minimální interval mezi žádostmi o voice práva (v sekundách)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Chránit místnost pomocí CAPTCHA" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Vyloučit Jabber ID z procesu CAPTCHA ověřování" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Zaznamenávat konverzace" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Ke konfiguraci místnosti potřebujete klienta podporujícího x:data" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Počet účastníků" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "soukromá, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Žádost o voice práva" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Povolit nebo odmítnout voice žádost." #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "Jabber ID uživatele" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "Udělit voice práva této osobě?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s vás zve do místnosti ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "heslo je" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "Fronta offline zpráv pro váš kontakt je plná. Zpráva byla zahozena." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "Fronta offline zpráv uživatele ~s" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Odeslané" #: mod_offline.erl:571 msgid "Time" msgstr "Čas" #: mod_offline.erl:572 msgid "From" msgstr "Od" #: mod_offline.erl:573 msgid "To" msgstr "Pro" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Paket" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Smazat vybrané" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Offline zprávy:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Odstranit všechny offline zprávy" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestreams modul" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Publish-Subscribe" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "ejabberd Publish-Subscribe modul" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Žádost odběratele PubSub" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Zvolte, zda chcete schválit odebírání touto entitou" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ID uzlu" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Adresa odběratele" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Povolit tomuto Jabber ID odebírat tento pubsub uzel?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Doručovat náklad s upozorněním na událost" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Doručovat upozornění na události" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Upozornit odběratele na změnu nastavení uzlu" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Upozornit odběratele na smazání uzlu" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Upozornit odběratele na odstranění položek z uzlu" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Uložit položky natrvalo do úložiště" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Přívětivé jméno pro uzel" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Maximální počet položek, které je možné natrvalo uložit" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Povolit odebírání" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Uveďte přístupový model" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Skupiny kontaktů, které mohou odebírat" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Specifikovat model pro publikování" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "Smazat všechny položky, pokud se příslušný poskytovatel odpojí" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Zvolte typ zpráv pro události" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Maximální náklad v bajtech" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Kdy odeslat poslední publikovanou položku" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Doručovat upozornění jen právě přihlášeným uživatelům" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Kolekce, se kterými je uzel spřízněn" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "Ověření CAPTCHA se nezdařilo" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "Pro registraci potřebujete klienta s podporou x:data a CAPTCHA" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Zadejte jméno uživatele a heslo pro registraci na tomto serveru" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Uživatel" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "Heslo je příliš slabé" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Je zakázáno registrovat účty v tak rychlém sledu" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Nic" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Přihlášení" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Čekající" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Skupiny" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Ověřit" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Odstranit" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Seznam kontaktů " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Nesprávný formát" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Přidat Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Seznam kontaktů" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Skupiny pro sdílený seznam kontaktů" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Přidat nový" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Jméno:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Popis:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Členové:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Zobrazené skupiny:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Skupina " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Odeslat" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Datum narození" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Město" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Země" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "E-mail" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Příjmení" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Pro vyhledání uživatele Jabberu vyplňte formulář (na konec přidejte znak * " "pro vyhledání podřetězce)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Celé jméno" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Druhé jméno" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Jméno" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Název firmy" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Oddělení" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Hledat uživatele v " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "K vyhledávání potřebujete klienta podporujícího x:data" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Hledání uživatelů podle vizitek" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard modul" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Výsledky hledání pro " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Vyplňte políčka pro vyhledání uživatele Jabberu" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Nemáte oprávnění" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "Webová administrace ejabberd" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Administrace" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Zdroj" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "~s konfigurace pravidla přístupu" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Virtuální hostitelé" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Uživatelé" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Poslední aktivita uživatele" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Čas: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Poslední měsíc" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Poslední rok" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Všechny aktivity" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Zobrazit běžnou tabulku" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Zobrazit kompletní tabulku" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Statistiky" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Nenalezeno" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Uzel nenalezen" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Hostitel" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Registrovaní uživatelé" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Offline zprávy" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Poslední aktivita" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Registrovaní živatelé:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Online uživatelé:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Odchozí s2s spojení:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Odchozí s2s servery:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Změnit heslo" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Uživatel " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Připojené zdroje:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Heslo:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Žádná data" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Uzly" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Uzel " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Otevřené porty" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Aktualizovat" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Restart" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Stop" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Chyba RPC volání" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Databázové tabulky na " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Typ úložiště" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Položek" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Paměť" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Chyba" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Záloha na " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Podotýkáme, že tato nastavení budou zálohována do zabudované databáze " "Mnesia. Pokud používáte ODBC modul, musíte zálohovat svoji SQL databázi " "samostatně." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Uložit binární zálohu:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Okamžitě obnovit binární zálohu:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Obnovit binární zálohu při následujícím restartu ejabberd (vyžaduje méně " "paměti)" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Uložit zálohu do textového souboru:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Okamžitě obnovit zálohu z textového souboru:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Importovat uživatele ze souboru ve formátu PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "Exportovat všechny uživatele do souboru ve formátu PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" "Exportovat uživatele na hostiteli do souboru ve formátu PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importovat uživatele z jabberd14 spool souborů:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importovat uživatele z jabberd14 spool souborů:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Otevřené porty na " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Moduly na " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Statistiky ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Čas běhu:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Čas procesoru" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transakce potvrzena" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transakce zrušena" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transakce restartována" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transakce zaznamenána" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Aktualizovat " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Aktualizovat plán" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Aktualizované moduly" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Aktualizované skripty" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Nízkoúrovňový aktualizační skript" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Kontrola skriptu" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Port" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protokol" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Modul" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Nastavení" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Smazat" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Start" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Váš účet Jabberu byl úspěšně vytvořen." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Při vytváření účtu došlo k chybě." #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Váš účet Jabberu byl úspěšně smazán." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Při mazání účtu došlo k chybě: " #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Heslo vašeho účtu Jabberu bylo úspěšně změněno." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Při změně hesla došlo k chybě: " #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Registrace účtu Jabberu" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Zaregistrujte si účet Jabberu" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Zrušte registraci účtu Jabberu" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Na této stránce si můžete vytvořit účet na tomto serveru Jabberu. Vaše JID " "(Jabber IDentifikátor) bude mít tvar: uživatelskéjméno@server. Přečtěte si " "prosím pozorně instrukce pro vyplnění údajů." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Uživatelské jméno:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Zde nezáleží na velikosti písmen: macbeth je stejný jako MacBeth a Macbeth." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Nepřípustné znaky:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Server:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "Nikdy nikomu nesdělujte své heslo, ani administrátorovi serveru Jabberu." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "Později můžete své heslo změnit pomocí klienta Jabberu." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Někteří klienti umí uložit vaše heslo na disk počítače. Tuto funkci " "používejte, pouze pokud věříte zabezpečení svého počítače." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Svoje heslo si zapamatujte, nebo si jej poznamenejte na papírek a ten " "uschovejte v bezpečí. Jabber nemá žádný automatizovaný způsob obnovy hesla." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Ověření hesla:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Zaregistrovat se" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Současné heslo:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Nové heslo:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "Zde můžete zrušit registraci účtu na tomto serveru Jabberu." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Zrušit registraci" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "Zkouška CAPTCHA neprošla." ejabberd-2.1.11/src/msgs/pt.po0000664000000000000000000014672412240230175012757 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "Last-Translator: Iceburn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Portuguese (português)\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Não foi passado nenhum recurso" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 #, fuzzy msgid "Enter the text you see" msgstr "Introduza caminho para o ficheiro de texto" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "" #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "" #: mod_adhoc.erl:149 mod_adhoc.erl:243 #, fuzzy msgid "Ping" msgstr "Pendente" #: mod_adhoc.erl:260 msgid "Pong" msgstr "" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 #, fuzzy msgid "Subject" msgstr "Enviar" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "" #: mod_announce.erl:653 mod_announce_odbc.erl:645 #, fuzzy msgid "Delete message of the day" msgstr "Eliminar os seleccionados" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Configuração" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Iniciar módulos" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Parar módulos" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Guardar cópia de segurança" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Restaurar" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Exportar para ficheiro de texto" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Importar ficheiro" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Importar directório" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 #, fuzzy msgid "Restart Service" msgstr "Reiniciar" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Adicionar utilizador" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 #, fuzzy msgid "Delete User" msgstr "Eliminar" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 #, fuzzy msgid "Get User Password" msgstr "Palavra-chave" #: mod_configure.erl:153 mod_configure.erl:522 #, fuzzy msgid "Change User Password" msgstr "Mudar palavra-chave" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 #, fuzzy msgid "Get User Statistics" msgstr "Estatísticas" #: mod_configure.erl:159 mod_configure.erl:525 #, fuzzy msgid "Get Number of Registered Users" msgstr "Utilizadores registados" #: mod_configure.erl:161 mod_configure.erl:526 #, fuzzy msgid "Get Number of Online Users" msgstr "Utilizadores ligados" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Listas de Controlo de Acesso" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Regras de Acesso" #: mod_configure.erl:297 mod_configure.erl:499 #, fuzzy msgid "User Management" msgstr "Gestão da BD" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Utilizadores ligados" #: mod_configure.erl:501 msgid "All Users" msgstr "Todos os utilizadores" #: mod_configure.erl:502 #, fuzzy msgid "Outgoing s2s Connections" msgstr "Conexões S2S para fora" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Nodos a correr" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Nodos parados" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Módulos" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Gestão de cópias de segurança" #: mod_configure.erl:579 #, fuzzy msgid "Import Users From jabberd14 Spool Files" msgstr "Importar utilizadores a partir de ficheiros da spool do jabberd14" #: mod_configure.erl:699 msgid "To ~s" msgstr "A ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "De ~s" #: mod_configure.erl:913 #, fuzzy msgid "Database Tables Configuration at " msgstr "Configuração de tabelas da BD em " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Seleccione o tipo de armazenagem das tabelas" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Cópia apenas em disco" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Cópia em RAM e em disco" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Cópia em RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Cópia remota" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Parar módulos em " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Seleccione os módulos a parar" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Iniciar os módulos em " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Introduza lista de {módulos, [opções]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Lista de módulos a iniciar" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Guardar cópia de segurança para ficheiro em " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Introduza o caminho do ficheiro de cópia de segurança" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Caminho do ficheiro" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Restaura cópia de segurança a partir do ficheiro em " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Exporta cópia de segurança para ficheiro de texto em " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Introduza caminho para o ficheiro de texto" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importar utilizador a partir do ficheiro em " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Introduza o caminho para o ficheiro de spool do jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importar utilizadores a partir do directório em " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Introduza o caminho para o directório de spools do jabberd14" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Caminho para o directório" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Configuração da Lista de Controlo de Acesso" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Listas de Controlo de Acesso" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Configuração de acessos" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Regras de acesso" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Palavra-chave" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "" #: mod_configure.erl:1301 #, fuzzy msgid "Number of registered users" msgstr "Utilizadores registados" #: mod_configure.erl:1315 #, fuzzy msgid "Number of online users" msgstr "Utilizadores ligados" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Nunca" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Ligado" #: mod_configure.erl:1701 msgid "Last login" msgstr "" #: mod_configure.erl:1722 #, fuzzy msgid "Roster size" msgstr "Lista de contactos" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "" #: mod_configure.erl:1724 #, fuzzy msgid "Resources" msgstr "Restaurar" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Administração de " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Acção no utilizador" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Editar propriedades" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Eliminar utilizador" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Acesso negado pela política de serviço" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "Módulo de IRC ejabberd" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "É necessário um cliente com suporte de x:data para configurar as opções do " "mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Registo no mod_irc para" #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 #, fuzzy msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Introduza o nome de utilizador e codificações de caracteres que quer usar ao " "conectar-se aos servidores de IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Nome do utilizador de IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 #, fuzzy msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Se deseja especificar codificações de caracteres diferentes para cada " "servidor IRC preencha esta lista con valores no formato '{\"servidor irc\", " "\"codificação\"}'. Este serviço usa por omissão a codificação \"~s\"." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 #, fuzzy msgid "IRC server" msgstr "Nome do utilizador de IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 #, fuzzy msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Introduza o nome de utilizador e codificações de caracteres que quer usar ao " "conectar-se aos servidores de IRC" #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 #, fuzzy msgid "IRC username" msgstr "Nome do utilizador de IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 #, fuzzy msgid "Password ~b" msgstr "Palavra-chave" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 #, fuzzy msgid "Port ~b" msgstr "Porta" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" "Só os administradores do serviço têm permissão para enviar mensagens de " "serviço" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 #, fuzzy msgid "Room creation is denied by service policy" msgstr "Acesso negado pela política de serviço" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "A sala não existe" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 #, fuzzy msgid "You need a client that supports x:data to register the nickname" msgstr "" "É necessário um cliente com suporte de x:data para poder registar a alcunha" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Registo da alcunha em " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Introduza a alcunha que quer registar" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Alcunha" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 #, fuzzy msgid "That nickname is registered by another person" msgstr "A alcunha já está registada por outra pessoa" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 #, fuzzy msgid "You must fill in field \"Nickname\" in the form" msgstr "Deve preencher o campo \"alcunha\" no formulário" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "Módulo MUC de ejabberd" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 #, fuzzy msgid "Chatroom configuration modified" msgstr "Configuração para " #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " colocou o tópico: " #: mod_muc/mod_muc_log.erl:452 #, fuzzy msgid "Chatroom is created" msgstr "Configuração para " #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "" #: mod_muc/mod_muc_log.erl:479 #, fuzzy msgid "November" msgstr "Nunca" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "" #: mod_muc/mod_muc_log.erl:750 #, fuzzy msgid "Room Configuration" msgstr "Configuração" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Impedir o envio de mensagens privadas para a sala" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Tipo de mensagem incorrecto" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "Não é permitido enviar mensagens privadas do tipo \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "O destinatário não está na sala" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 #, fuzzy msgid "It is not allowed to send private messages" msgstr "Impedir o envio de mensagens privadas para a sala" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Só os ocupantes podem enviar mensagens para a sala" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Só os ocupantes podem enviar consultas para a sala" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "Nesta sala não são permitidas consultas aos seus membros" #: mod_muc/mod_muc_room.erl:932 #, fuzzy msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "Só os moderadores e os participantes podem mudar o tópico desta sala" #: mod_muc/mod_muc_room.erl:937 #, fuzzy msgid "Only moderators are allowed to change the subject in this room" msgstr "Só os moderadores podem mudar o tópico desta sala" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Os visitantes não podem enviar mensagens para todos os ocupantes" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" #: mod_muc/mod_muc_room.erl:1040 #, fuzzy msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Só os moderadores podem mudar o tópico desta sala" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 #, fuzzy msgid "That nickname is already in use by another occupant" msgstr "A alcunha já está a ser usado por outro ocupante" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Foi banido desta sala" #: mod_muc/mod_muc_room.erl:1771 #, fuzzy msgid "Membership is required to enter this room" msgstr "É necessário ser membro desta sala para poder entrar" #: mod_muc/mod_muc_room.erl:1807 #, fuzzy msgid "This room is not anonymous" msgstr "Tornar a sala anónima?" #: mod_muc/mod_muc_room.erl:1833 #, fuzzy msgid "A password is required to enter this room" msgstr "É necessária a palavra-chave para poder entrar nesta sala" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Palavra-chave incorrecta" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "São necessários privilégios de administrador" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "São necessários privilégios de moderador" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "O Jabber ID ~s não é válido" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "A alcunha ~s não existe na sala" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Afiliação inválida: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Papel inválido: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "São necessários privilégios de dono" #: mod_muc/mod_muc_room.erl:3195 #, fuzzy msgid "Configuration of room ~s" msgstr "Configuração para " #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Título da sala" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 #, fuzzy msgid "Room description" msgstr "Subscrição" #: mod_muc/mod_muc_room.erl:3210 #, fuzzy msgid "Make room persistent" msgstr "Tornar a sala permanente?" #: mod_muc/mod_muc_room.erl:3215 #, fuzzy msgid "Make room public searchable" msgstr "Tornar a sala publicamente visível?" #: mod_muc/mod_muc_room.erl:3218 #, fuzzy msgid "Make participants list public" msgstr "Tornar pública a lista de participantes?" #: mod_muc/mod_muc_room.erl:3221 #, fuzzy msgid "Make room password protected" msgstr "Proteger a sala com palavra-chave?" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 #, fuzzy msgid "anyone" msgstr "Nenhum" #: mod_muc/mod_muc_room.erl:3262 #, fuzzy msgid "Make room members-only" msgstr "Tornar a sala exclusiva a membros?" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Tornar a sala moderada" #: mod_muc/mod_muc_room.erl:3268 #, fuzzy msgid "Default users as participants" msgstr "Os utilizadores são membros por omissão?" #: mod_muc/mod_muc_room.erl:3271 #, fuzzy msgid "Allow users to change the subject" msgstr "Permitir aos utilizadores mudar o tópico?" #: mod_muc/mod_muc_room.erl:3274 #, fuzzy msgid "Allow users to send private messages" msgstr "Permitir que os utilizadores enviem mensagens privadas?" #: mod_muc/mod_muc_room.erl:3279 #, fuzzy msgid "Allow visitors to send private messages to" msgstr "Permitir que os utilizadores enviem mensagens privadas?" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "" #: mod_muc/mod_muc_room.erl:3296 #, fuzzy msgid "Allow users to query other users" msgstr "Permitir aos utilizadores consultar outros utilizadores?" #: mod_muc/mod_muc_room.erl:3299 #, fuzzy msgid "Allow users to send invites" msgstr "Permitir que os utilizadores enviem convites?" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "" #: mod_muc/mod_muc_room.erl:3305 #, fuzzy msgid "Allow visitors to change nickname" msgstr "Permitir aos utilizadores mudar o tópico?" #: mod_muc/mod_muc_room.erl:3308 #, fuzzy msgid "Allow visitors to send voice requests" msgstr "Permitir que os utilizadores enviem convites?" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "" #: mod_muc/mod_muc_room.erl:3317 #, fuzzy msgid "Make room CAPTCHA protected" msgstr "Proteger a sala com palavra-chave?" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "" #: mod_muc/mod_muc_room.erl:3329 #, fuzzy msgid "Enable logging" msgstr "Guardar históricos?" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "É necessário um cliente com suporte de x:data para configurar a sala" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privado" #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "" #: mod_muc/mod_muc_room.erl:3809 #, fuzzy msgid "User JID" msgstr "Utilizador" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "" #: mod_muc/mod_muc_room.erl:3969 #, fuzzy msgid "the password is" msgstr "Mudar palavra-chave" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" #: mod_offline.erl:560 mod_offline_odbc.erl:408 #, fuzzy msgid "~s's Offline Messages Queue" msgstr "~s fila de mensagens diferidas" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 #, fuzzy msgid "Submitted" msgstr "enviado" #: mod_offline.erl:571 msgid "Time" msgstr "Data" #: mod_offline.erl:572 msgid "From" msgstr "De" #: mod_offline.erl:573 msgid "To" msgstr "Para" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Pacote" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Eliminar os seleccionados" #: mod_offline.erl:645 mod_offline_odbc.erl:519 #, fuzzy msgid "Offline Messages:" msgstr "Mensagens diferidas:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 #, fuzzy msgid "Remove All Offline Messages" msgstr "Mensagens diferidas" #: mod_proxy65/mod_proxy65_service.erl:213 #, fuzzy msgid "ejabberd SOCKS5 Bytestreams module" msgstr "Módulo vCard de ejabberd" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 #, fuzzy msgid "ejabberd Publish-Subscribe module" msgstr "Módulo pub/sub de ejabberd" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 #, fuzzy msgid "Node ID" msgstr "Nodo" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "" #: mod_register.erl:220 #, fuzzy msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "É necessário um cliente com suporte de x:data para poder registar a alcunha" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "" "Escolha um nome de utilizador e palavra-chave para se registar neste servidor" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Utilizador" #: mod_register.erl:316 mod_register.erl:361 #, fuzzy msgid "The password is too weak" msgstr "Mudar palavra-chave" #: mod_register.erl:365 #, fuzzy msgid "Users are not allowed to register accounts so quickly" msgstr "Os visitantes não podem enviar mensagens para todos os ocupantes" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Nenhum" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Subscrição" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Pendente" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Grupos" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Remover" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Lista de contactos de " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 #, fuzzy msgid "Bad format" msgstr "formato inválido" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 #, fuzzy msgid "Add Jabber ID" msgstr "Adicionar Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Lista de contactos" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 #, fuzzy msgid "Shared Roster Groups" msgstr "Lista de contactos partilhada" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Adicionar novo" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 #, fuzzy msgid "Name:" msgstr "Nome" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 #, fuzzy msgid "Description:" msgstr "Subscrição" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 #, fuzzy msgid "Group " msgstr "Grupos" #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Enviar" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Servidor Jabber em Erlang" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Data de nascimento" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Cidade" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "País" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 #, fuzzy msgid "Email" msgstr "email" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Apelido" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 #, fuzzy msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "Preencha os campos para procurar utilizadores Jabber coincidentes" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Nome completo" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Segundo nome" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Nome" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Nome da organização" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Unidade da organização" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Procurar utilizadores em " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "É necessário um cliente com suporte de x:data para poder procurar" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "Módulo vCard de ejabberd" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 #, fuzzy msgid "Search Results for " msgstr "Procurar utilizadores em " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Preencha os campos para procurar utilizadores Jabber coincidentes" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 #, fuzzy msgid "ejabberd Web Admin" msgstr "Administração do ejabberd" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 #, fuzzy msgid "Administration" msgstr "Administração de " #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 #, fuzzy msgid "Raw" msgstr "modo texto" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Configuração das Regra de Acesso ~s" #: web/ejabberd_web_admin.erl:1035 #, fuzzy msgid "Virtual Hosts" msgstr "Servidores virtuales" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Utilizadores" #: web/ejabberd_web_admin.erl:1078 #, fuzzy msgid "Users Last Activity" msgstr "Última actividade" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "" #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "" #: web/ejabberd_web_admin.erl:1092 #, fuzzy msgid "All activity" msgstr "Última actividade" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Estatísticas" #: web/ejabberd_web_admin.erl:1117 #, fuzzy msgid "Not Found" msgstr "Nodo não encontrado" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Nodo não encontrado" #: web/ejabberd_web_admin.erl:1460 #, fuzzy msgid "Host" msgstr "Nome do servidor" #: web/ejabberd_web_admin.erl:1461 #, fuzzy msgid "Registered Users" msgstr "Utilizadores registados" #: web/ejabberd_web_admin.erl:1573 #, fuzzy msgid "Offline Messages" msgstr "Mensagens diferidas" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Última actividade" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 #, fuzzy msgid "Registered Users:" msgstr "Utilizadores registados" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 #, fuzzy msgid "Online Users:" msgstr "Utilizadores ligados" #: web/ejabberd_web_admin.erl:1663 #, fuzzy msgid "Outgoing s2s Connections:" msgstr "Conexões S2S para fora" #: web/ejabberd_web_admin.erl:1665 #, fuzzy msgid "Outgoing s2s Servers:" msgstr "Servidores S2S de saída" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Mudar palavra-chave" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Utilizador" #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Recursos conectados:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Palavra-chave:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Nodos" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Nodo" #: web/ejabberd_web_admin.erl:1938 #, fuzzy msgid "Listened Ports" msgstr "Portas em escuta em " #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Actualizar" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Reiniciar" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Parar" #: web/ejabberd_web_admin.erl:1959 #, fuzzy msgid "RPC Call Error" msgstr "Erro na chamada RPC" #: web/ejabberd_web_admin.erl:2000 #, fuzzy msgid "Database Tables at " msgstr "Tabelas da BD em " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Tipo de armazenagem" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Memória" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "" #: web/ejabberd_web_admin.erl:2034 #, fuzzy msgid "Backup of " msgstr "Guardar cópia de segurança" #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" #: web/ejabberd_web_admin.erl:2041 #, fuzzy msgid "Store binary backup:" msgstr "Armazenar uma cópia de segurança no ficheiro" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 #, fuzzy msgid "Restore binary backup immediately:" msgstr "Recuperar uma cópia de segurança a partir de ficheiro" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "" #: web/ejabberd_web_admin.erl:2070 #, fuzzy msgid "Restore plain text backup immediately:" msgstr "Recuperar uma cópia de segurança a partir de ficheiro" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" #: web/ejabberd_web_admin.erl:2099 #, fuzzy msgid "Import user data from jabberd14 spool file:" msgstr "Importar utilizadores a partir de ficheiros da spool do jabberd14" #: web/ejabberd_web_admin.erl:2106 #, fuzzy msgid "Import users data from jabberd14 spool directory:" msgstr "Importar utilizadores a partir de ficheiros da spool do jabberd14" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Portas em escuta em " #: web/ejabberd_web_admin.erl:2157 #, fuzzy msgid "Modules at " msgstr "Parar módulos em " #: web/ejabberd_web_admin.erl:2183 #, fuzzy msgid "Statistics of ~p" msgstr "Estatísticas" #: web/ejabberd_web_admin.erl:2186 #, fuzzy msgid "Uptime:" msgstr "Tempo de funcionamento" #: web/ejabberd_web_admin.erl:2189 #, fuzzy msgid "CPU Time:" msgstr "Tempo de processador consumido" #: web/ejabberd_web_admin.erl:2195 #, fuzzy msgid "Transactions Committed:" msgstr "Transacções realizadas" #: web/ejabberd_web_admin.erl:2198 #, fuzzy msgid "Transactions Aborted:" msgstr "Transacções abortadas" #: web/ejabberd_web_admin.erl:2201 #, fuzzy msgid "Transactions Restarted:" msgstr "Transacções reiniciadas" #: web/ejabberd_web_admin.erl:2204 #, fuzzy msgid "Transactions Logged:" msgstr "Transacções armazenadas" #: web/ejabberd_web_admin.erl:2246 #, fuzzy msgid "Update " msgstr "Actualizar" #: web/ejabberd_web_admin.erl:2254 #, fuzzy msgid "Update plan" msgstr "Actualizar" #: web/ejabberd_web_admin.erl:2255 #, fuzzy msgid "Modified modules" msgstr "Iniciar módulos" #: web/ejabberd_web_admin.erl:2256 #, fuzzy msgid "Update script" msgstr "Actualizar" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Porta" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "" #: web/ejabberd_web_admin.erl:2428 #, fuzzy msgid "Protocol" msgstr "Porta" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Módulo" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Opções" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Eliminar" #: web/ejabberd_web_admin.erl:2579 #, fuzzy msgid "Start" msgstr "Reiniciar" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "" #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "" #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "" #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 #, fuzzy msgid "Jabber Account Registration" msgstr "Configuração das Listas de Controlo de Acesso do ejabberd" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 #, fuzzy msgid "Username:" msgstr "Nome do utilizador de IRC" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 #, fuzzy msgid "Server:" msgstr "Nunca" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "" #: web/mod_register_web.erl:250 #, fuzzy msgid "Register" msgstr "Lista de contactos" #: web/mod_register_web.erl:396 #, fuzzy msgid "Old Password:" msgstr "Palavra-chave:" #: web/mod_register_web.erl:401 #, fuzzy msgid "New Password:" msgstr "Palavra-chave:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "" #~ msgid "Encodings" #~ msgstr "Codificações" #, fuzzy #~ msgid "(Raw)" #~ msgstr "(modo texto)" #~ msgid "Specified nickname is already registered" #~ msgstr "A alcunha especificada já está registada" #~ msgid "Size" #~ msgstr "Tamanho" #~ msgid "Backup Management at " #~ msgstr "Gestão da cópia de segurança em " #~ msgid "Choose host name" #~ msgstr "Introduza o nome do servidor" #~ msgid "Choose users to remove" #~ msgstr "Seleccione utilizadores a eliminar" #~ msgid "DB" #~ msgstr "BD" #~ msgid "Dump a database in a text file" #~ msgstr "Exportar uma Base de Dados para um ficheiro de texto" #~ msgid "Host name" #~ msgstr "Nome do servidor" #~ msgid "Hostname Configuration" #~ msgstr "Configuração do nome do servidor" #~ msgid "Install a database fallback from a file" #~ msgstr "Instalar uma recuperação de BD desde um ficheiro" #~ msgid "It is not allowed to send normal messages to the conference" #~ msgstr "Impedir o envio de mensagens normais para a sala" #~ msgid "Listened Ports Management" #~ msgstr "Gestão das portas em escuta" #~ msgid "Make room moderated?" #~ msgstr "Tornar a sala moderada?" #~ msgid "Remove Users" #~ msgstr "Eliminar utilizadores" #~ msgid "Restore a database from a text file" #~ msgstr "Restaurar uma Base de Dados a partir de ficheiro de texto" #~ msgid "Results of search in " #~ msgstr "Resultados da procura em " #~ msgid "ejabberd (c) 2002-2005 Alexey Shchepin, 2005 Process One" #~ msgstr "ejabberd (c) 2002-2005 Alexey Shchepin, 2005 Process One" #~ msgid "ejabberd access rules configuration" #~ msgstr "Configuração das Regras de Acesso do ejabberd" #~ msgid "ejabberd users" #~ msgstr "Utilizadores do ejabberd" #~ msgid "~p statistics" #~ msgstr "Estatísticas de ~p" ejabberd-2.1.11/src/msgs/wa.msg0000664000000000000000000004476012240230175013110 0ustar {"Access Configuration","Apontiaedje des accès"}. {"Access Control List Configuration","Apontiaedje des droets (ACL)"}. {"Access control lists","Droets (ACL)"}. {"Access Control Lists","Droets (ACL)"}. {"Access denied by service policy","L' accès a stî rfuzé pal politike do siervice"}. {"Access rules","Rîles d' accès"}. {"Access Rules","Rîles d' accès"}. {"Action on user","Accion so l' uzeu"}. {"Add Jabber ID","Radjouter èn ID Jabber"}. {"Add New","Radjouter"}. {"Add User","Radjouter èn uzeu"}. {"Administration","Manaedjaedje"}. {"Administration of ","Manaedjaedje di "}. {"Administrator privileges required","I fåt des priviledjes di manaedjeu"}. {"A friendly name for the node","On no uzeu-ahessåve pol nuk"}. {"All activity","Dispoy todi"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Permete ki ci Jabber ID ci si poye abouner a ç' nuk eplaidaedje-abounmint ci?"}. {"Allow users to query other users","Les uzeus polèt cweri ls ôtes uzeus"}. {"Allow users to send invites","Les uzeus polèt evoyî priyaedjes"}. {"Allow users to send private messages","Les uzeus polèt evoyî des messaedjes privés"}. {"Allow visitors to change nickname","Permete ki les viziteus candjexhe leus metous nos"}. {"Allow visitors to send status text in presence updates","Permete ki les viziteus evoyexhe des tecse d' estat dins leus messaedjes di prezince"}. {"All Users","Tos les uzeus"}. {"Announcements","Anonces"}. {"anyone","tot l' minme kî"}. {"April","avri"}. {"August","awousse"}. {"Backup","Copeye di såvrité"}. {"Backup Management","Manaedjaedje des copeyes di såvrité"}. {"Backup of ","Copeye di såvrité po "}. {"Backup to File at ","Fé ene copeye di såvrité dins on fitchî so "}. {"Bad format","Mwais fôrmat"}. {"Birthday","Date d' askepiaedje"}. {"Change Password","Candjî l' sicret"}. {"Change User Password","Candjî l' sicret d' l' uzeu"}. {"Chatroom configuration modified","L' apontiaedje del såle di berdelaedje a candjî"}. {"Chatrooms","Såles di berdelaedje"}. {"Choose a username and password to register with this server","Tchoezixhoz on no d' uzeu eyet on scret po vs edjîstrer so ç' sierveu ci"}. {"Choose modules to stop","Tchoezixhoz les modules a-z arester"}. {"Choose storage type of tables","Tchoezi l' sôre di wårdaedje po les tåves"}. {"Choose whether to approve this entity's subscription.","Tchoezi s' i fåt aprover ou nén l' abounmint di ciste intité."}. {"City","Veye"}. {"Commands","Comandes"}. {"Conference room does not exist","Li såle di conferince n' egzistêye nén"}. {"Configuration","Apontiaedjes"}. {"Connected Resources:","Raloyî avou les rsoûces:"}. {"Country","Payis"}. {"CPU Time:","Tins CPU:"}. {"Database","Båze di dnêyes"}. {"Database Tables at ","Tåves del båze di dnêyes so "}. {"Database Tables Configuration at ","Apontiaedje des tåves del båze di dnêyes so "}. {"December","decimbe"}. {"Default users as participants","Les uzeus sont des pårticipants come prémetowe dujhance"}. {"Delete","Disfacer"}. {"Delete message of the day","Disfacer l' messaedje do djoû"}. {"Delete message of the day on all hosts","Disfacer l' messaedje do djoû so tos les lodjoes"}. {"Delete Selected","Disfacer les elemints tchoezis"}. {"Delete User","Disfacer èn uzeu"}. {"Deliver event notifications","Evoyî des notifiaedjes d' evenmints"}. {"Deliver payloads with event notifications","Evoyî l' contnou avou les notifiaedjes d' evenmints"}. {"Description:","Discrijhaedje:"}. {"Disc only copy","Copeye seulmint sol deure plake"}. {"Displayed Groups:","Groupes håynés:"}. {"Dump Backup to Text File at ","Copeye di såvritè viè on fitchî tecse so "}. {"Dump to Text File","Schaper en on fitchî tecse"}. {"Edit Properties","Candjî les prôpietés"}. {"ejabberd IRC module","Module IRC po ejabberd"}. {"ejabberd MUC module","Module MUC (såles di berdelaedje) po ejabberd"}. {"ejabberd Publish-Subscribe module","Module d' eplaidaedje-abounmint po ejabberd"}. {"ejabberd SOCKS5 Bytestreams module","Module SOCKS5 Bytestreams po ejabberd"}. {"ejabberd vCard module","Module vCard ejabberd"}. {"ejabberd Web Admin","Manaedjeu waibe ejabberd"}. {"Email","Emile"}. {"Enable logging","Mete en alaedje li djournå"}. {"End User Session","Fini l' session d' l' uzeu"}. {"Enter list of {Module, [Options]}","Dinez ene djivêye del cogne {Module, [Tchuzes]}"}. {"Enter nickname you want to register","Dinez l' metou no ki vos vloz edjîstrer"}. {"Enter path to backup file","Dinez l' tchimin viè l' fitchî copeye di såvrité"}. {"Enter path to jabberd14 spool dir","Dinez l' tchimin viè l' ridant di spool jabberd14"}. {"Enter path to jabberd14 spool file","Dinez l' tchimin viè l' fitchî di spool jabberd14"}. {"Enter path to text file","Dinez l' tchimin viè l' fitchî tecse"}. {"Erlang Jabber Server","Sierveu Jabber Erlang"}. {"Family Name","No d' famile"}. {"February","fevrî"}. {"Fill in fields to search for any matching Jabber User","Rimplixhoz les tchamps po cweri èn uzeu Jabber"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Rimplixhoz les tchamps do formulaire po cweri èn uzeu Jabber (radjouter «*» al fén do tchamp po cweri tot l' minme kéne fén d' tchinne"}. {"Friday","vénrdi"}. {"From","Di"}. {"From ~s","Dispoy ~s"}. {"Full Name","No etir"}. {"Get Number of Online Users","Riçure li nombe d' uzeus raloyîs"}. {"Get Number of Registered Users","Riçure li nombe d' uzeus edjîstrés"}. {"Get User Last Login Time","Riçure li date/eure do dierin elodjaedje di l' uzeu"}. {"Get User Password","Riçure sicret d' l' uzeu"}. {"Get User Statistics","Riçure les statistikes di l' uzeu"}. {"Group ","Groupe "}. {"Groups","Groupes"}. {"has been banned","a stî bani"}. {"has been kicked","a stî pité evoye"}. {"has been kicked because of an affiliation change","a stî pité evoye cåze d' on candjmint d' afiyaedje"}. {"has been kicked because of a system shutdown","a stî pité evoye cåze d' èn arestaedje do sistinme"}. {"has been kicked because the room has been changed to members-only","a stî pité evoye cåze ki l' såle a stî ristrindowe åzès mimbes seulmint"}. {" has set the subject to: "," a candjî l' tite a: "}. {"Host","Sierveu"}. {"Import Directory","Sititchî d' on ridant"}. {"Import File","Sititchî d' on fitchî"}. {"Import User from File at ","Sititchî uzeu d' on fitchî so "}. {"Import Users from Dir at ","Sitichî des uzeus d' on ridant so "}. {"Import Users From jabberd14 Spool Files","Sititchî des uzeus Jabberd 1.4"}. {"Improper message type","Sôre di messaedje nén valide"}. {"Incorrect password","Sicret nén corek"}. {"Invalid affiliation: ~s","Afiyaedje nén valide: ~s"}. {"Invalid role: ~s","Role nén valide: ~s"}. {"IP addresses","Adresses IP"}. {"IRC Transport","Transpoirt IRC"}. {"IRC Username","No d' uzeu IRC"}. {"is now known as","est asteure kinoxhou come"}. {"It is not allowed to send private messages","Ci n' est nén permetou d' evoyî des messaedjes privés"}. {"It is not allowed to send private messages of type \"groupchat\"","C' est nén possibe d' evoyî des messaedjes privés del sôre «groupchat»"}. {"It is not allowed to send private messages to the conference","On n' pout nén evoyî des messaedjes privés dins cisse conferince ci"}. {"Jabber ID","ID Jabber"}. {"Jabber ID ~s is invalid","Li Jabber ID ~s n' est nén valide"}. {"January","djanvî"}. {"joins the room","arive sol såle"}. {"July","djulete"}. {"June","djun"}. {"Last Activity","Dierinne activité"}. {"Last login","Dierin elodjaedje"}. {"Last month","Dierin moes"}. {"Last year","Dierinne anêye"}. {"leaves the room","cwite li såle"}. {"Listened Ports at ","Pôrts drovous so "}. {"Listened Ports","Pôrts drovous"}. {"List of modules to start","Djivêye di modules a-z enonder"}. {"Low level update script","Sicripe di metaedje a djoû d' bas livea"}. {"Make participants list public","Rinde publike li djivêye des pårticipants"}. {"Make room members-only","Rinde li såle di berdelaedje ristrindowe ås mimbes seulmint"}. {"Make room moderated","Rinde li såle di berdelaedje moderêye"}. {"Make room password protected","Rinde li såle di berdelaedje protedjeye pa scret"}. {"Make room persistent","Rinde li såle permaninte"}. {"Make room public searchable","Rinde li såle di berdelaedje cweråve publicmint"}. {"March","måss"}. {"Maximum Number of Occupants","Nombe macsimom di prezints"}. {"Max # of items to persist","Nombe macsimoms di cayets permanints"}. {"Max payload size in bytes","Contnou macsimom en octets"}. {"May","may"}. {"Members:","Mimbes:"}. {"Memory","Memwere"}. {"Message body","Coir do messaedje"}. {"Middle Name","No do mitan"}. {"Moderator privileges required","I fåt des priviledjes di moderateu"}. {"moderators only","les moderateus seulmint"}. {"Module","Module"}. {"Modules at ","Modules so "}. {"Modules","Modules"}. {"Monday","londi"}. {"Name","No"}. {"Name:","Pitit no:"}. {"Never","Måy"}. {"Nickname","Metou no"}. {"Nickname Registration at ","Edjîstraedje di metou no amon "}. {"Nickname ~s does not exist in the room","Li metou no ~s n' egzistêye nén dins l' såle"}. {"No body provided for announce message","I n' a nou coir do messaedje po ciste anonce la"}. {"No Data","Nole dinêye disponibe"}. {"Node ID","ID d' nuk"}. {"Node not found","Nuk nén trové"}. {"Node ","Nuk "}. {"Nodes","Nuks"}. {"No limit","Pont d' limite"}. {"None","Nole"}. {"No resource provided","Nole rissoûce di dnêye"}. {"Notify subscribers when items are removed from the node","Notifyî åzès abounés cwand des cayets sont oisté foû do nuk"}. {"Notify subscribers when the node configuration changes","Notifyî åzès abounés cwand l' apontiaedje do nuk candje"}. {"Notify subscribers when the node is deleted","Notifyî åzès abounés cwand l' nuk est disfacé"}. {"November","nôvimbe"}. {"Number of occupants","Nombe di prezints"}. {"Number of online users","Nombe d' uzeus raloyîs"}. {"Number of registered users","Nombe d' uzeus edjîstrés"}. {"October","octôbe"}. {"Offline Messages:","Messaedjes ki ratindèt:"}. {"Offline Messages","Messaedjes ki ratindèt"}. {"OK","'l est bon"}. {"Online","Raloyî"}. {"Online Users:","Uzeus raloyîs:"}. {"Online Users","Uzeus raloyîs"}. {"Only deliver notifications to available users","Seulmint evoyî des notifiaedje åzès uzeus disponibes"}. {"Only occupants are allowed to send messages to the conference","Seulmint les prezints polèt evoyî des messaedjes al conferince"}. {"Only occupants are allowed to send queries to the conference","Seulmint les prezints polèt evoyî des cweraedjes sol conferince"}. {"Only service administrators are allowed to send service messages","Seulmint les manaedjeus d' siervices polèt evoyî des messaedjes di siervice"}. {"Options","Tchuzes"}. {"Organization Name","No d' l' organizåcion"}. {"Organization Unit","Unité d' l' organizåcion"}. {"Outgoing s2s Connections:","Raloyaedjes s2s e rexhowe:"}. {"Outgoing s2s Connections","Raloyaedjes s2s e rexhowe"}. {"Outgoing s2s Servers:","Sierveus s2s e rexhowe:"}. {"Owner privileges required","I fåt des priviledjes di prôpietaire"}. {"Packet","Paket"}. {"Password:","Sicret:"}. {"Password","Sicret"}. {"Password Verification","Acertinaedje do scret"}. {"Path to Dir","Tchimin viè l' ridant"}. {"Path to File","Tchimin viè l' fitchî"}. {"Pending","Ratindant"}. {"Period: ","Termene:"}. {"Persist items to storage","Cayets permanints a wårder"}. {"Ping","Ping"}. {"Pong","Pong"}. {"Port","Pôrt"}. {"Present real Jabber IDs to","Mostrer les vraiys Jabber IDs a"}. {"private, ","privé, "}. {"Publish-Subscribe","Eplaidaedje-abounmint"}. {"PubSub subscriber request","Dimande d' eplaidaedje-abounmint d' èn abouné"}. {"Queries to the conference members are not allowed in this room","Les cweraedjes des mimbes del conferince ni sont nén permetous dins cisse såle ci"}. {"RAM and disc copy","Copeye e memwere (RAM) et sol deure plake"}. {"RAM copy","Copeye e memwere (RAM)"}. {"Raw","Dinêyes brutes"}. {"Really delete message of the day?","Voloz vs vormint disfacer l' messaedje do djoû?"}. {"Recipient is not in the conference room","Li riçuveu n' est nén dins l' såle di conferince"}. {"Registered Users:","Uzeus edjistrés:"}. {"Registered Users","Uzeus edjistrés"}. {"Registration in mod_irc for ","Edjîstraedje dins mod_irc po "}. {"Remote copy","Copeye å lon"}. {"Remove","Oister"}. {"Remove User","Disfacer l' uzeu"}. {"Replaced by new connection","Replaecî pa on novea raloyaedje"}. {"Resources","Rissoûces"}. {"Restart","Renonder"}. {"Restart Service","Renonder siervice"}. {"Restore Backup from File at ","Rapexhî dispoy li fitchî copeye di såvrité so "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Rapexhî l' copeye di såvrité binaire après l' renondaedje ki vént d' ejabberd (çoula prind moens d' memwere del fé insi):"}. {"Restore binary backup immediately:","Rapexhî do côp foû d' ene copeye di såvrité binaire:"}. {"Restore plain text backup immediately:","Rapexhî do côp foû d' ene copeye di såvrité tecse:"}. {"Restore","Rapexhî"}. {"Room Configuration","Apontiaedje del såle"}. {"Room creation is denied by service policy","L' ahivaedje del såle est rfuzé pal politike do siervice"}. {"Room title","Tite del såle"}. {"Roster","Djivêye des soçons"}. {"Roster groups allowed to subscribe","Pårtaedjîs groupes di soçons k' on s' î pout abouner"}. {"Roster of ","Djivêye des soçons da "}. {"Roster size","Grandeu del djivêye des soçons"}. {"RPC Call Error","Aroke di houcaedje RPC"}. {"Running Nodes","Nuks en alaedje"}. {"~s access rule configuration","Apontiaedje des rîles d' accès a ~s"}. {"Saturday","semdi"}. {"Script check","Acertinaedje do scripe"}. {"Search Results for ","Rizultats do cweraedje po "}. {"Search users in ","Cweri des uzeus dins "}. {"Send announcement to all online users","Evoyî l' anonce a tos les uzeus raloyîs"}. {"Send announcement to all online users on all hosts","Evoyî l' anonce a tos les uzeus raloyîs so tos les lodjoes"}. {"Send announcement to all users","Evoyî l' anonce a tos les uzeus"}. {"Send announcement to all users on all hosts","Evoyî l' anonce a tos les uzeus so tos les lodjoes"}. {"September","setimbe"}. {"Set message of the day and send to online users","Defini l' messaedje do djoû et l' evoyî åzès uzeus raloyîs"}. {"Set message of the day on all hosts and send to online users","Defini l' messaedje do djoû so tos les lodjoes et l' evoyî åzès uzeus raloyîs"}. {"Shared Roster Groups","Pårtaedjîs groupes ezès djivêyes di soçons"}. {"Show Integral Table","Mostrer totå"}. {"Show Ordinary Table","Mostrer crexhince"}. {"Shut Down Service","Arester siervice"}. {"~s invites you to the room ~s","~s vos preye sol såle ~s"}. {"Specify the access model","Sipecifyî l' modele d' accès"}. {"Specify the publisher model","Dinez l' modele d' eplaideu"}. {"~s's Offline Messages Queue","messaedjes ki ratindèt el cawêye po ~s"}. {"Start","Enonder"}. {"Start Modules at ","Renonder les modules so "}. {"Start Modules","Enonder des modules"}. {"Statistics of ~p","Sitatistikes di ~p"}. {"Statistics","Sitatistikes"}. {"Stop","Arester"}. {"Stop Modules","Arester des modules"}. {"Stop Modules at ","Arester les modules so "}. {"Stopped Nodes","Nuks essoctés"}. {"Storage Type","Sôre di wårdaedje"}. {"Store binary backup:","Copeye di såvrité binaire:"}. {"Store plain text backup:","Copeye di såvrité tecse:"}. {"Subject","Sudjet"}. {"Submit","Evoyî"}. {"Submitted","Candjmints evoyîs"}. {"Subscriber Address","Adresse di l' abouné"}. {"Subscription","Abounmimnt"}. {"Sunday","dimegne"}. {"the password is","li scret est"}. {"This participant is kicked from the room because he sent an error message","Ci pårticipant ci a stî pité evoye del såle cåze k' il a-st evoyî on messaedje d' aroke"}. {"This participant is kicked from the room because he sent an error message to another participant","Ci pårticipant ci a stî pité evoye del såle cåze k' il a-st evoyî on messaedje d' aroke a èn ôte pårticipant"}. {"This participant is kicked from the room because he sent an error presence","Ci pårticipant ci a stî pité evoye del såle cåze k' il a-st evoyî ene aroke di prezince"}. {"This room is not anonymous","Cisse såle ci n' est nén anonime"}. {"Thursday","djudi"}. {"Time","Date"}. {"Time delay","Tårdjaedje"}. {"To","Po"}. {"To ~s","Viè ~s"}. {"Traffic rate limit is exceeded","Li limite pol volume di trafik a stî passêye"}. {"Transactions Aborted:","Transaccions arestêyes:"}. {"Transactions Committed:","Transaccions evoyeyes:"}. {"Transactions Logged:","Transaccions wårdêyes e djournå:"}. {"Transactions Restarted:","Transaccions renondêyes:"}. {"Tuesday","mårdi"}. {"Update message of the day (don't send)","Mete a djoû l' messaedje do djoû (nén l' evoyî)"}. {"Update message of the day on all hosts (don't send)","Mete a djoû l' messaedje do djoû so tos les lodjoes (nén l' evoyî)"}. {"Update ","Metaedje a djoû "}. {"Update","Mete a djoû"}. {"Update plan","Plan d' metaedje a djoû"}. {"Update script","Sicripe di metaedje a djoû"}. {"Uptime:","Tins dispoy l' enondaedje:"}. {"Use of STARTTLS required","L' eployaedje di STARTTL est oblidjî"}. {"User Management","Manaedjaedje des uzeus"}. {"Users Last Activity","Dierinne activité des uzeus"}. {"Users","Uzeus"}. {"User ","Uzeu "}. {"User","Uzeu"}. {"Validate","Valider"}. {"vCard User Search","Calpin des uzeus"}. {"Virtual Hosts","Forveyous sierveus"}. {"Visitors are not allowed to change their nicknames in this room","Les viziteus èn polèt nén candjî leus metous no po ç' såle ci"}. {"Visitors are not allowed to send messages to all occupants","Les viziteus n' polèt nén evoyî des messaedjes a tos les prezints"}. {"Wednesday","mierkidi"}. {"When to send the last published item","Cwand evoyî l' dierin cayet eplaidî"}. {"Whether to allow subscriptions","Si on permete les abounmints"}. {"You have been banned from this room","Vos avoz stî bani di cisse såle ci"}. {"You must fill in field \"Nickname\" in the form","Vos dvoz rimpli l' tchamp «Metou no» dins l' formiulaire"}. {"You need an x:data capable client to configure mod_irc settings","Vos avoz mezåjhe d' on cliyint ki sopoite x:data po candjî ls apontiaedjes di mod_irc"}. {"You need an x:data capable client to configure room","I vs fåt on cliyint ki sopoite x:data por vos poleur apontyî l' såle"}. {"You need an x:data capable client to search","Vos avoz mezåjhe d' on cliyint ki sopoite x:data po fé on cweraedje"}. {"Your contact offline message queue is full. The message has been discarded.","Li cawêye di messaedjes e môde disraloyî di vosse soçon est plinne. Li messaedje a stî tapé å diale."}. ejabberd-2.1.11/src/msgs/ca.po0000664000000000000000000015631712240230175012716 0ustar # Jan, 2012. msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "POT-Creation-Date: \n" "PO-Revision-Date: 2012-04-22 00:19+0200\n" "Last-Translator: JanKusanagi\n" "Language-Team: American English \n" "Language: en_US\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Catalan (català)\n" "X-Additional-Translator: Vicent Alberola Canet\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Lokalize 1.4\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "És obligatori utilitzar STARTTLS" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Recurs no disponible" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Reemplaçat per una nova connexió" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" "La teva llista de privacitat activa ha denegat l'encaminament d'aquesta " "stanza." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Introdueix el text que veus" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "Els teus missatges per ~s s'estan bloquejant. Per desbloquejar-los, visita ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "Si no veus la imatge CAPTCHA açí, visita la pàgina web." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "Pàgina web del CAPTCHA" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "El CAPTCHA es vàlid." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Comandaments" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Segur que vols eliminar el missatge del dia?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Assumpte" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Missatge" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "No hi ha proveedor per al missatge anunci" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Anuncis" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Enviar anunci a tots els usuaris" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Enviar anunci a tots els usuaris de tots els hosts" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Enviar anunci a tots els usuaris connectats" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Enviar anunci a tots els usuaris connectats a tots els hosts" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Configurar el missatge del dia i enviar a tots els usuaris" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Escriure missatge del dia en tots els hosts i enviar-ho als usuaris " "connectats" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Actualitzar el missatge del dia (no enviar)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Actualitza el missatge del dia en tots els hosts (no enviar)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Eliminar el missatge del dia" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Elimina el missatge del dis de tots els hosts" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Configuració" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Base de dades" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Iniciar mòduls" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Parar mòduls" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Guardar còpia de seguretat" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Restaurar" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Exportar a fitxer de text" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Importar fitxer" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Importar directori" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Reiniciar el Servei" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Apager el Servei" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Afegir usuari" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Eliminar Usuari" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Finalitzar Sesió d'Usuari" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Obtenir Contrasenya d'usuari" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Canviar Contrasenya d'Usuari" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Obtenir la última connexió d'Usuari" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Obtenir Estadístiques d'Usuari" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Obtenir Número d'Usuaris Registrats" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Obtenir Número d'Usuaris Connectats" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Llista de Control d'Accés" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Regles d'Accés" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Gestió d'Usuaris" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Usuaris conectats" #: mod_configure.erl:501 msgid "All Users" msgstr "Tots els usuaris" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Connexions s2s d'eixida" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Nodes funcionant" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Nodes parats" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Mòduls" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Gestió de còpia de seguretat" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importar usuaris de jabberd14" #: mod_configure.erl:699 msgid "To ~s" msgstr "A ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "De ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Configuració de la base de dades en " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Selecciona el tipus d'almacenament de les taules" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Còpia sols en disc" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "Còpia en RAM i disc" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "Còpia en RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Còpia remota" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Detindre mòduls en " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Selecciona mòduls a detindre" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Iniciar mòduls en " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Introdueix llista de {mòdul, [opcions]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Llista de mòduls a iniciar" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Desar còpia de seguretat a fitxer en " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Introdueix ruta al fitxer de còpia de seguretat" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Ruta al fitxer" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Restaura còpia de seguretat des del fitxer en " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Exporta còpia de seguretat a fitxer de text en " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Introdueix ruta al fitxer de text" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importa usuari des de fitxer en " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Introdueix ruta al fitxer jabberd14 spool" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importar usuaris des del directori en " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Introdueix la ruta al directori de jabberd14 spools" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Ruta al directori" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Temps de retard" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Configuració de la Llista de Control d'Accés" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Llistes de Control de Accés" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Configuració d'accesos" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Regles d'accés" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "ID Jabber" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Contrasenya" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Verificació de la Contrasenya" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Número d'Usuaris Registrats" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Número d'usuaris connectats" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Mai" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Connectat" #: mod_configure.erl:1701 msgid "Last login" msgstr "Últim login" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Tamany de la llista" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "Adreça IP" #: mod_configure.erl:1724 msgid "Resources" msgstr "Recursos" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Administració de " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Acció en l'usuari" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Editar propietats" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Eliminar usuari" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Accés denegat per la política del servei" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "Transport a IRC" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "mòdul ejabberd IRC" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "Necessites un client amb suport x:data per a configurar les opcions de " "mod_irc" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Registre en mod_irc per a" #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Introdueix el nom d'usuari, les codificacions de caràcters, els ports i " "contrasenyes per a utilitzar al connectar als servidors de IRC" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Nom d'usuari al IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Si vols especificar codificacions de caràcters diferents per a cada servidor " "IRC emplena aquesta llista amb els valors amb el format '{\"servidor irc\", " "\"codificació\", port, \"contrasenya\"}'. Aquest servei utilitza per " "defecte la codificació \"~s\", port ~p, no contrasenya." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Exemple: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Paràmetres de connexió" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Entra a canal d'IRC" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "Canal d'IRC (no posis la primera #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "Servidor d'IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Entra al canal d'IRC aquí." #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Entra al canal d'IRC en aquesta Jabber ID: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "Configuració d'IRC." #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Introdueix el nom d'usuari i les codificacions de caràcters per a utilitzar " "als servidors de IRC. Apreta \"Seguent\" per veure més caps per omplir. " "Apreta \"Completar\" per guardar la configuració. " #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "Nom d'usuari al IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Contrasenya ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Port ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Codificació pel servidor ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Servidor ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" "Sols els administradors del servei tenen permís per a enviar missatges de " "servei" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Se t'ha denegat el crear la sala per política del servei" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "La sala de conferències no existeix" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Sales de xat" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "" "Necessites un client amb suport x:data per a poder registrar el Nickname" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Registre del Nickname en " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Introdueix el nickname que vols registrar" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Nickname" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "El nickname ja està registrat per una altra persona" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Deus d'omplir el camp \"Nickname\" al formulari" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "mòdul ejabberd MUC" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Configuració de la sala de xat modificada" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "Entrar a la sala" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "Deixar la sala" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "Has sigut banejat" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "Has sigut expulsat" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "Has sigut expulsat a causa d'un canvi d'afiliació" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "Has sigut expulsat perquè la sala ha canviat a sols membres" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "Has sigut expulsat perquè el sistema s'ha apagat" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "ara es conegut com" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " ha posat l'assumpte: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "La sala s'ha creat" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "La sala s'ha destruït" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "La sala s'ha iniciat" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "La sala s'ha aturat" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Dilluns" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Dimarts" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Dimecres" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Dijous" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Divendres" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Dissabte" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Diumenge" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Gener" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Febrer" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Març" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "Abril" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Maig" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Juny" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Juliol" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Agost" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "Setembre" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Octubre" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "Novembre" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "Decembre" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Configuració de la sala" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Nombre d'ocupants" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "El llímit de tràfic ha sigut sobrepassat" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Aquest participant ha sigut expulsat de la sala perque ha enviat un missatge " "d'error" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "No està permès l'enviament de missatges privats a la sala" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "Si us plau, espera una mica abans d'enviar una nova petició de veu" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "Les peticions de veu es troben desactivades en aquesta conferència" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "No s'ha pogut extraure el JID de la teva aprovació de petició de veu" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Només els moderadors poden aprovar les peticions de veu" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Tipus de missatge incorrecte" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Aquest participant ha sigut expulsat de la sala perque ha enviat un missatge " "erroni a un altre participant" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "No està permés enviar missatges del tipus \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "El receptor no està en la sala de conferència" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "No està permés enviar missatges privats" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Sols els ocupants poden enviar missatges a la sala" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Sols els ocupants poden enviar sol·licituds a la sala" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "" " En aquesta sala no es permeten sol·licituds als membres de la conferència" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Només els moderadors i participants poden canviar l'assumpte d'aquesta sala" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Només els moderadors poden canviar l'assumpte d'aquesta sala" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Els visitants no poden enviar missatges a tots els ocupants" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Aquest participant ha sigut expulsat de la sala perque ha enviat un error de " "presencia" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Els visitants no tenen permés canviar el seus Nicknames en esta sala" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "El Nickname està siguent utilitzat per una altra persona" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Has sigut bloquejat en aquesta sala" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Necessites ser membre d'aquesta sala per a poder entrar" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Aquesta sala no és anònima" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Es necessita contrasenya per a entrar en aquesta sala" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Massa peticions de CAPTCHA" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "No s'ha pogut generar un CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Contrasenya incorrecta" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Es necessita tenir privilegis d'administrador" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Es necessita tenir privilegis de moderador" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "El Jabber ID ~s no és vàlid" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "El Nickname ~s no existeix a la sala" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Afiliació invàlida: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Rol invàlid: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Es requerixen privilegis de propietari de la sala" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Configuració de la sala ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Títol de la sala" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Descripció de la sala:" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Crear una sala persistent" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Crear una sala pública" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Crear una llista de participants pública" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Crear una sala amb contrasenya" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Número màxim d'ocupants" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Sense Llímit" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Presentar Jabber ID's reals a" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "només moderadors" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "qualsevol" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Crear una sala de \"només membres\"" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Crear una sala moderada" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Els usuaris són participants per defecte" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Permetre que els usuaris canviin el tema" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Permetre que els usuaris envien missatges privats" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "Permetre als visitants enviar missatges privats a" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "ningú" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Permetre que els usuaris fagen peticions a altres usuaris" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Permetre que els usuaris envien invitacions" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "" "Permetre als visitants enviar text d'estat en les actualitzacions de " "presència" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Permetre als visitants canviar el Nickname" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "Permetre als visitants enviar peticions de veu" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "Interval mínim entre peticions de veu (en segons)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Crear una sala protegida per CAPTCHA" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Excloure Jabber IDs de la comprovació CAPTCHA" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Habilitar el registre de la conversa" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Necessites un client amb suport x:data per a configurar la sala" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Número d'ocupants" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privat" #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Petició de veu" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Aprova o denega la petició de veu" #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "JID del usuari " #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "Concedir veu a aquesta persona?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s et convida a la sala ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "la contrasenya és" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "La cua de missatges offline és plena. El missatge ha sigut descartat" #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "~s's cua de missatges offline" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Enviat" #: mod_offline.erl:571 msgid "Time" msgstr "Data" #: mod_offline.erl:572 msgid "From" msgstr "De" #: mod_offline.erl:573 msgid "To" msgstr "Per a" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Paquet" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Eliminar els seleccionats" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Missatges fora de línia:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Eliminar tots els missatges offline" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "mòdul ejabberd SOCKS5 Bytestreams" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Publicar-subscriure't" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "Mòdul ejabberd Publicar-Subscriure" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Petició de subscriptor PubSub" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Tria si aprova aquesta entitat de subscripció" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ID del Node" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Adreça del Subscriptor" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Permetre que aquesta Jabber ID es puga subscriure a aquest node pubsub" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Enviar payloads junt a les notificacions d'events" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Entrega de notificacions d'events" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Notificar subscriptors quan canvia la configuració del node" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Notificar subscriptors quan el node és eliminat" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Notificar subscriptors quan els elements són eliminats del node" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Persistir elements al guardar" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Un nom per al node" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Màxim # d'elements que persistixen" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Permetre subscripcions" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Especificar el model d'accés" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Llista de grups que tenen permés subscriures" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Especificar el model del publicant" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "Eliminar tots els elements quan el publicant relevant es desconnecti" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Especifica el tipus de missatge d'event" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Màxim tamany del payload en bytes" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Quan s'ha enviat l'última publicació" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Sols enviar notificacions als usuaris disponibles" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Les col.leccions amb les que un node està afiliat" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "La verificació CAPTCHA ha fallat" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "Necessites un client amb suport x:data i de CAPTCHA para poder registrar-te" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Tria nom d'usuari i contrasenya per a registrar-te en aquest servidor" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Usuari" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "La contrasenya és massa simple" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Els usuaris no tenen permís per a crear comptes tan depresa" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Cap" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Subscripció" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Pendent" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Grups" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Validar" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Borrar" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Llista de contactes de " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Format erroni" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Afegir Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Llista de contactes" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Grups de contactes compartits" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Afegir nou" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Nom:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Descripció:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Membre:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Mostrar grups:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Grup " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Enviar" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Servidor Erlang Jabber" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Aniversari" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Ciutat" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Pais" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Email" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Cognom" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Emplena el formulari per a buscar usuaris Jabber. Afegix * al final d'un " "camp per a buscar subcadenes." #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Nom complet" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Segon nom" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Nom" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Nom de la organizació" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Unitat de la organizació" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Cerca usuaris en " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Necessites un client amb suport x:data per a poder buscar" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Recerca de vCard d'usuari" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "Mòdul ejabberd vCard" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Resultat de la búsqueda" #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Emplena camps per a buscar usuaris Jabber que concorden" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "No autoritzat" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "Web d'administració del ejabberd" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Administració" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "en format text" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Configuració de les Regles d'Accés ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Hosts virtuals" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Usuaris" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Última activitat d'usuari" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Període: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Últim mes" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Últim any" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Tota l'activitat" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Mostrar Taula Ordinaria" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Mostrar Taula Integral" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Estadístiques" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "No Trobat" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Node no trobat" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Host" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Usuaris registrats" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Missatges offline" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Última activitat" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Usuaris registrats:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Usuaris en línia:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Connexions d'eixida s2s" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Servidors d'eixida de s2s" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Canviar Contrasenya" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Usuari " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Recursos connectats:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Contrasenya:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "No hi ha dades" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Nodes" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Node " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Ports a l'escolta" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Actualitzar" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Reiniciar" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Detindre" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Error de cridada RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Taules de la base de dades en " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Tipus d'emmagatzematge" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Elements" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Memòria" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Error" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Còpia de seguretat de " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Recorda que aquestes opcions només fan còpia de seguretat de la base de " "dades Mnesia. Si estàs utilitzant el mòdul d'ODBC també deus de fer una " "còpia de seguretat de la base de dades de SQL a part." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Guardar una còpia de seguretat binària:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "Acceptar" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Restaurar una còpia de seguretat binària ara mateix." #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Restaurar una còpia de seguretat binària després de reiniciar el ejabberd " "(requereix menys memòria:" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Guardar una còpia de seguretat en format de text pla:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Restaurar una còpia de seguretat en format de text pla ara mateix:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Importar dades d'usuaris des d'un arxiu PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Exportar dades de tots els usuaris del servidor a arxius PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "Exportar dades d'usuaris d'un host a arxius PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importar dades d'usuaris de l'arxiu de spool de jabberd14" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importar dades d'usuaris del directori de spool de jabberd14:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Ports a la escolta en " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Mòduls en " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Estadístiques de ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Temps en marxa" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Temps de CPU" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Transaccions Realitzades:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Transaccions Avortades" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Transaccions reiniciades" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Transaccions registrades" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Actualitzar" #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Pla d'actualització" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Mòduls modificats" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Script d'actualització" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Script d'actualització de baix nivell" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Comprovar script" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Port" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protocol" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Mòdul" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Opcions" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Eliminar" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Iniciar" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "El teu compte Jabber ha sigut creat correctament." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Hi ha hagut un error creant el compte: " #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "El teu compte Jabber ha sigut esborrat correctament." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Hi ha hagut un error esborrant el compte: " #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "La contrasenya del teu compte Jabber s'ha canviat correctament." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Hi ha hagut un error canviant la contrasenya: " #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Registre de compte Jabber" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Registrar un compte Jabber" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Anul·lar el registre d'un compte Jabber" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Aquesta pàgina permet crear un compte Jabber en aquest servidor Jabber. El " "teu JID (Jabber IDentifier; Identificador Jabber) tindrà aquesta forma: " "usuari@servidor. Si us plau, llegeix amb cura les instruccions per emplenar " "correctament els camps." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Nom d'usuari:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Això no distingeix majúscules de minúscules: macbeth es el mateix que " "MacBeth i Macbeth." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Caràcters no permesos:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Servidor:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "No li donis la teva contrasenya a ningú, ni tan sols als administradors del " "servidor Jabber." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" "Podràs canviar la teva contrasenya més endavant utilitzant un client Jabber." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Alguns clients Jabber poden emmagatzemar la teva contrasenya al teu " "ordinador. Fes servir aquesta característica només si saps que el teu " "ordinador és segur." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Memoritza la teva contrasenya, o escriu-la en un paper guardat a un lloc " "segur.A Jabber no hi ha una forma automatitzada de recuperar la teva " "contrasenya si la oblides." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Verificació de la Contrasenya:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Registrar" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Antiga contrasenya:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Nova Contrasenya:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" "Aquesta pàgina permet anul·lar el registre d'un compte Jabber en aquest " "servidor Jabber." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Anul·lar el registre" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "El CAPTCHA es vàlid." ejabberd-2.1.11/src/msgs/tr.po0000664000000000000000000015642012240230175012753 0ustar # translation of tr.po to Turkish # Doruk Fisek , 2009, 2012. msgid "" msgstr "" "Project-Id-Version: tr\n" "PO-Revision-Date: 2012-04-17 11:18+0300\n" "Last-Translator: Doruk Fisek \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Turkish (türkçe)\n" "X-Generator: KBabel 1.11.4\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "STARTTLS kullanımı gereklidir" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Hiç kaynak sağlanmadı" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Eski bağlantı yenisi ile değiştirildi" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "Etkin mahremiyet listeniz bu bölümün yönlendirilmesini engelledi." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Gördüğünüz metni giriniz" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "~s kullanıcısına mesajlarınız engelleniyor. Durumu düzeltmek için ~s " "adresini ziyaret ediniz." #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "" "Eğer burada CAPTCHA resmini göremiyorsanız, web sayfasını ziyaret edin." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "CAPTCHA web sayfası" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "İnsan doğrulaması (captcha) geçerli." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Komutlar" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Günün mesajını silmek istediğinize emin misiniz?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Konu" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Mesajın gövdesi" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Duyuru mesajının gövdesi yok" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Duyurular" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Duyuruyu tüm kullanıcılara yolla" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Tüm sunuculardaki tüm kullanıcılara duyuru yolla" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Duyuruyu tüm bağlı kullanıcılara yolla" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Duyuruyu tüm sunuculardaki tüm bağlı kullanıcılara yolla" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Günün mesajını belirle" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Tüm sunucularda günün mesajını belirle ve bağlı tüm kullanıcılara gönder" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Günün mesajını güncelle (gönderme)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Tüm sunuculardaki günün mesajını güncelle (gönderme)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Günün mesajını sil" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Tüm sunuculardaki günün mesajını sil" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Ayarlar" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Veritabanı" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Modülleri Başlat" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Modülleri Durdur" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Yedekle" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Yedekten Geri Al" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Metin Dosyasına Döküm Al" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Dosyayı İçe Aktar" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Dizini İçe Aktar" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Servisi Tekrar Başlat" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Servisi Kapat" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Kullanıcı Ekle" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Kullanıcıyı Sil" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Kullanıcı Oturumunu Kapat" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Kullanıcı Parolasını Al" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Kullanıcı Parolasını Değiştir" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Kullanıcı Son Giriş Zamanınlarını Al" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Kullanıcı İstatistiklerini Al" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Kayıtlı Kullanıcı Sayısını Al" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Bağlı Kullanıcı Sayısını Al" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Erişim Kontrol Listeleri (ACL)" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Erişim Kuralları" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Kullanıcı Yönetimi" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Bağlı Kullanıcılar" #: mod_configure.erl:501 msgid "All Users" msgstr "Tüm Kullanıcılar" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Giden s2s Bağlantıları" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Çalışan Düğümler" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Durdurulmuş Düğümler" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Modüller" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Yedek Yönetimi" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Jabberd 1.4 Spool Dosyalarından Kullanıcıları İçeri Aktar" #: mod_configure.erl:699 msgid "To ~s" msgstr "Kime ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Kimden ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Veritabanı Tablo Ayarları : " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Tabloların veri depolama tipini seçiniz" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Sadece disk kopyala" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "RAM ve disk kopyala" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "RAM kopyala" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Uzak kopyala" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Modülleri Durdur : " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Durdurulacak modülleri seçiniz" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Modülleri Başlat : " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "{Module, [Options]} listesi giriniz" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Başlatılacak modüllerin listesi" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Dosyaya Yedekle : " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Yedek dosyasının yolunu giriniz" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Dosyanın Yolu" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Dosyadaki Yedekten Geri Al : " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Metin Dosyasına Döküm Alarak Yedekle : " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Metin dosyasının yolunu giriniz" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Dosyadan Kullanıcıları İçe Aktar : " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "jabberd14 spool dosyası için yol giriniz" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Dizinden Kullanıcıları İçe Aktar : " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "jabberd14 spool dosyası için yol giriniz" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Dizinin Yolu" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Zaman gecikmesi" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Erişim Kontrol Listelerinin Ayarlanması (ACL)" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Erişim kontrol listeleri (ACL)" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Erişim Ayarları" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Erişim kuralları" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Parola" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Parola Doğrulaması" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Kayıtlı kullanıcı sayısı" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Bağlı kullanıcı sayısı" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Asla" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Bağlı" #: mod_configure.erl:1701 msgid "Last login" msgstr "Son giriş" #: mod_configure.erl:1722 msgid "Roster size" msgstr "İsim listesi boyutu" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "IP adresleri" #: mod_configure.erl:1724 msgid "Resources" msgstr "Kaynaklar" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Yönetim : " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Kullanıcıya uygulanacak eylem" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Özellikleri Düzenle" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Kullanıcıyı Kaldır" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Servis politikası gereği erişim engellendi" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC Nakli (Transport)" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC modülü" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "mod_irc ayarlarını düzenlemek için x:data becerisine sahip bir istemciye " "gereksinimiz var" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "mod_irc'ye kayıt : " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "IRC sunuculara bağlanmak için kullanmak istediğiniz kullanıcı ismi, " "kodlamalar, kapılar (portlar) ve parolaları giriniz" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "IRC Kullanıcı İsmi" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "IRC sunucuları için farklı kapılar (portlar), parolalar, kodlamalar " "belirtmek istiyorsanız, '{\"irc sunucusu\", \"kodlama\",\"kapı\",\"parola" "\"}' biçeminde değerlerle bu listeyi doldurunuz. Öntanımlı olarak bu servis " "\"~s\" kodlamasını, ~p \"kapısını\", \"boş\" parolasını kullanıyor." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Örnek: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"gizli\"}, {\"vendetta.fef.net" "\", \"iso8859-1\", 7000}], {\"irc.sometestserver.net\", \"utf-8\"}]" #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Bağlantı parametreleri" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "IRC kanalına katıl" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "IRC kanalı (ilk # işaretini koymayın)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "IRC sunucusu" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Buradaki IRC kanalına katıl." #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "IRC kanalına bu Jabber ID'si ile katıl: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "IRC ayarları" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "IRC sunuculara bağlanmak için kullanmak istediğiniz kullanıcı isimleri ve " "kodlamaları giriniz. 'İleri' tuşuna basınca karşınıza dolduracak daha fazla " "alan çıkacak. 'Tamamla' tuşuna basarak ayarları kaydedin." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "IRC kullanıcı ismi" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Parola ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Kapı (Port) ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Sunucu için kodlama ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Sunucu ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "Sadece servis yöneticileri servis mesajı gönderebilirler" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Odanın oluşturulması servis politikası gereği reddedildi" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Konferans odası bulunamadı" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Sohbet Odaları" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "" "Takma isminizi kaydettirmek için x:data destekleyen bir istemciye " "gereksinimiz var" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Takma İsim Kaydı : " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Kaydettirmek istediğiniz takma ismi giriniz" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Takma isim" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "O takma isim başka biri tarafından kaydettirilmiş" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Formda \"Takma isim\" alanını doldurmanız gerekiyor" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC modülü" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Sohbet odası ayarı değiştirildi" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "odaya katıldı" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "odadan ayrıldı" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "odaya girmesi yasaklandı" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "odadan atıldı" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "ilişki değişikliğinden dolayı atıldı" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "oda üyelere-özel hale getirildiğinden dolayı atıldı" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "sistem kapandığından dolayı atıldı" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "isim değiştirdi :" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " konuyu değiştirdi: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Sohbet odası oluşturuldu" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Sohbet odası kaldırıldı" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Sohbet odası başlatıldı" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Sohbet odası durduruldu" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Pazartesi" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Salı" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Çarşamba" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Perşembe" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Cuma" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Cumartesi" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Pazar" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Ocak" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Şubat" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Mart" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "Nisan" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Mayıs" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Haziran" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Temmuz" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Ağustos" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "Eylül" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Ekim" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "Kasım" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "Aralık" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Oda Ayarları" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Oda Sakini Sayısı" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Trafik oran sınırı aşıldı" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "Bu katılımcı bir hata mesajı gönderdiği için odadan atıldı" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Konferansa özel mesajlar gönderilmesine izin verilmiyor" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "Lütfen yeni bir ses isteği göndermeden önce biraz bekleyin" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "Bu konferansta ses istekleri etkisizleştirilmiş durumda." #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "Ses isteği onayınızdan JID bilginize ulaşılamadı" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Yalnız moderatörler ses isteklerini onaylayabilir" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Uygunsuz mesaj tipi" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Bu katılımcı başka bir katılımcıya bir hata mesajı gönderdiği için odadan " "atıldı" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "\"groupchat\" tipinde özel mesajlar gönderilmesine izin verilmiyor" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Alıcı konferans odasında değil" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Özel mesaj gönderilmesine izin verilmiyor" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Sadece oda sakinlerinin konferansa mesaj göndermesine izin veriliyor" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Sadece oda sakinlerinin konferansa sorgu göndermesine izin veriliyor" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "Bu odada konferans üyelerine sorgu yapılmasına izin verilmiyor" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Sadece moderatörlerin ve katılımcıların bu odanın konusunu değiştirmesine " "izin veriliyor" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Sadece moderatörlerin bu odanın konusunu değiştirmesine izin veriliyor" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "" "Ziyaretçilerin odadaki tüm sakinlere mesaj göndermesine izin verilmiyor" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "Bu katılımcı bir hata varlığı (presence) gönderdiği için odadan atıldı" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "" "Bu odada ziyaretçilerin takma isimlerini değiştirmesine izin verilmiyor" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Takma isim odanın başka bir sakini tarafından halihazırda kullanımda" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Bu odaya girmeniz yasaklandı" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Bu odaya girmek için üyelik gerekiyor" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Bu oda anonim değil" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Bu odaya girmek için parola gerekiyor" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Çok fazla CAPTCHA isteği" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "İnsan doğrulaması (CAPTCHA) oluşturulamadı" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Yanlış parola" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Yönetim yetkileri gerekli" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Moderatör yetkileri gerekli" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Jabber ID ~s geçersiz" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "~s takma ismi odada yok" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Geçersiz ilişki: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Geçersiz rol: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Sahip yetkileri gerekli" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "~s odasının ayarları" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Oda başlığı" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Oda tanımı" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Odayı kalıcı hale getir" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Odayı herkes tarafından aranabilir hale getir" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Katılımcı listesini herkese açık hale getir" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Odayı parola korumalı hale getir" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Odada En Fazla Bulunabilecek Kişi Sayısı" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Sınırsız" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Gerçek Jabber ID'lerini göster :" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "sadece moderatörler" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "herkes" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Odayı sadece üyelere açık hale getir" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Odayı moderasyonlu hale getir" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Kullanıcılar öntanımlı olarak katılımcı olsun" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Kullanıcıların konu değiştirmesine izin ver" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Kullanıcıların özel mesaj göndermelerine izin ver" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "Ziyaretçilerin özel mesaj göndermelerine izin ver" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "hiç kimse" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Kullanıcıların diğer kullanıcıları sorgulamalarına izin ver" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Kullanıcıların davetiye göndermelerine izin ver" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "" "Ziyaretçilerin varlık (presence) güncellemelerinde durum metni " "göndermelerine izin ver" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Ziyaretçilerin takma isim değiştirmelerine izin ver" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "Ziyaretçilerin ses isteğine göndermelerine izin ver" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "Ses istekleri arasında olabilecek en az aralık (saniye olarak)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Odayı insan doğrulaması (captcha) korumalı hale getir" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "CAPTCHA doğrulamasını şu Jabber ID'ler için yapma" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Kayıt tutma özelliğini aç" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "" "Odayı ayarlamak için x:data becerisine sahip bir istemciye gereksinimiz var" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Oda sakini sayısı" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "özel" #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Ses isteği" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Ses isteğini kabul edin ya da reddedin" #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "Kullanıcı JID" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "Bu kişiye ses verelim mi?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s sizi ~s odasına davet ediyor" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "parola :" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "Çevirim-dışı mesaj kuyruğunuz dolu. Mesajını dikkate alınmadı." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "~s Kullanıcısının Mesaj Kuyruğu" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Gönderilenler" #: mod_offline.erl:571 msgid "Time" msgstr "Zaman" #: mod_offline.erl:572 msgid "From" msgstr "Kimden" #: mod_offline.erl:573 msgid "To" msgstr "Kime" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Paket" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Seçilenleri Sil" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Çevirim-dışı Mesajlar:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Tüm Çevirim-dışı Mesajları Kaldır" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestreams modülü" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Yayınla-Üye Ol" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "ejabberd Publish-Subscribe modülü" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "PubSub üye isteği" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Bu varlığın üyeliğini onaylayıp onaylamamayı seçiniz." #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "Düğüm ID" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Üye Olanın Adresi" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Bu Jabber ID bu pubsub düğümüne üye olmasına izin verilsin mi?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Yükleri (payload) olay uyarıları ile beraber gönder" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Olay uyarıları gönderilsin" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Düğüm ayarları değiştiğinde üyeleri uyar" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Bir düğüm silindiğinde üyeleri uyar" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Düğümden öğeler kaldırıldığında üyeleri uyar" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Öğeleri depoda kalıcı hale getir" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Düğüm için dostane bir isim" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Kalıcı hale getirilecek en fazla öğe sayısı" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Üyeliklere izin verilsin mi" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Erişim modelini belirtiniz" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Üye olunmasına izin verilen kontak listesi grupları" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Yayıncı modelini belirtiniz" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "İlgili yayıncı çevirimdışı olunca tüm onunla ilgili olanları sil" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Olay mesaj tipini belirtiniz" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "En fazla yük (payload) boyutu (bayt olarak)" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Son yayınlanan öğe ne zaman gönderilsin" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Uyarıları sadece durumu uygun kullanıcılara ulaştır" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Bir düğüm ile bağlantılı koleksiyonlar" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "CAPTCHA doğrulaması başarısız oldu" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "Takma isminizi kaydettirmek için x:data ve CAPTCHA destekleyen bir istemciye " "gereksinimiz var" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Bu sunucuya kayıt olmak için bir kullanıcı ismi ve parola seçiniz" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Kullanıcı" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "Parola çok zayıf" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Kullanıcıların bu kadar hızlı hesap açmalarına izin verilmiyor" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Hiçbiri" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Üyelik" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Sıra Bekleyen" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Gruplar" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Geçerli" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Kaldır" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Kontak Listesi : " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Kötü biçem" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Jabber ID'si Ekle" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Kontak Listesi" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Paylaşımlı Kontak Listesi Grupları" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Yeni Ekle" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "İsim:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Tanım:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Üyeler:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Gösterilen Gruplar:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Group " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Gönder" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Sunucusu" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Doğumgünü" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "İl" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Ülke" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "E-posta" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Soyisim" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Eşleşen jabber kullanıcılarını aramak için formu doldurunuz (Alt dizgi " "eşlemek için alanın sonuna * ekleyin)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Tam İsim" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Ortanca İsim" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "İsim" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Kurum İsmi" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Kurumun İlgili Birimi" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Kullanıcılarda arama yap : " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "" "Arama yapabilmek için x:data becerisine sahip bir istemciye gereksinimiz var" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "vCard Kullanıcı Araması" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard modülü" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Arama sonuçları : " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Eşleşen jabber kullanıcılarını aramak için alanları doldurunuz" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Yetkisiz" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd Web Yöneticisi" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Yönetim" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Ham" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "~s erişim kuralları ayarları" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Sanal Sunucuları" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Kullanıcılar" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Kullanıcıların Son Aktiviteleri" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Periyot:" #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Geçen ay" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Geçen yıl" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Tüm aktivite" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Sıradan Tabloyu Göster" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Önemli Tabloyu Göster" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "İstatistikler" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Bulunamadı" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Düğüm bulunamadı" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Sunucu" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Kayıtlı Kullanıcılar" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Çevirim-dışı Mesajlar" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Son Aktivite" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Kayıtlı Kullanıcılar:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Bağlı Kullanıcılar:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Giden s2s Bağlantıları:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Giden s2s Sunucuları" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Parola Değiştir" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Kullanıcı " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Bağlı Kaynaklar:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Parola:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Veri Yok" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Düğümler" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Düğüm " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Dinlenen Kapılar (Portlar)" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "GÜncelle" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Tekrar Başlat" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Durdur" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "RPC Çağrı Hatası" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Veritabanı Tabloları : " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Depolama Tipi" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Elementler" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Bellek" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Hata" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Yedek : " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Bu seçeneklerin sadece gömülü Mnesia veritabanını yedekleyeceğine dikkat " "edin. Eğer ODBC modülünü kullanıyorsanız, SQL veritabanınızı da ayrıca " "yedeklemeniz gerekiyor." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "İkili yedeği sakla:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "Tamam" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Hemen ikili yedekten geri al:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "ejabberd'nin bir sonraki tekrar başlatılışında ikili yedekten geri al (daha " "az bellek gerektirir)" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Düz metin yedeği sakla:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Hemen düz metin yedekten geri al" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Kullanıcıları bir PIEFXIS dosyasından (XEP-0227) içe aktar:" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Sunucudaki tüm kullanıcıların verisini PIEFXIS dosyalarına (XEP-0227) dışa " "aktar:" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" "Bir sunucudaki kullanıcıların verisini PIEFXIS dosyalarına (XEP-0227) dışa " "aktar:" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Jabberd 1.4 Spool Dosyalarından Kullanıcıları İçe Aktar:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Jabberd 1.4 Spool Dizininden Kullanıcıları İçe Aktar:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Dinlenen Kapılar (Portlar) : " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Modüller : " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "~p istatistikleri" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Hizmet Süresi:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "İşlemci Zamanı:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Tamamlanan Hareketler (Transactions Committed):" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "İptal Edilen Hareketler (Transactions):" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Tekrar Başlatılan Hareketler (Transactions):" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Kaydı Tutulan Hareketler (Transactions):" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Güncelle " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Planı güncelle" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Değişen modüller" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Betiği Güncelle" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Düşük seviye güncelleme betiği" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Betik kontrolü" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Kapı (Port)" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protokol" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Modül" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Seçenekler" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Sil" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Başlat" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Jabber hesabınız başarıyla oluşturuldu." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Hesap oluşturulurken bir hata oluştu:" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Jabber hesabınız başarıyla silindi." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Hesabın silinmesi sırasında bir hata oluştu:" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Jabber hesabınızın parolası başarıyla değiştirildi." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Parolanın değiştirilmesi sırasında bir hata oluştu:" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Jabber Hesap Kaydı" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Bir Jabber hesabı kaydet" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Bir Jabber hesabı kaydı sil" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Bu sayfa bu Jabber sunucusunda bir Jabber hesabı oluşturulmasına olanak " "tanıyor. Sizin JID'iniz (Jabber Tanımlayıcısı) şu biçemde olacaktır: " "kullanici_adi@sunucu. Lütfen alanları doğru doldurabilmek için yönergeleri " "dikkatle okuyunuz." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Kullanıcı adı:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Burada büyük küçük harfi yapılmaz: macbeth ile MacBeth ve Macbeth aynıdır." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "İzin verilmeyen karakterler:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Sunucu:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "Parolanızı kimseye söylemeyin, Jabber sunucusunun yöneticilerine bile." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "" "Parolanızı daha sonra bir Jabber istemci kullanarak değiştirebilirsiniz." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Bazı Jabber istemcileri parolanızı bilgisayarınızda saklayabilir. Bu " "özelliği ancak bilgisayarın güvenli olduğuna güveniyorsanız kullanın." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Parolanızı ezberleyin ya da bir kağıda yazarak güvenli bir yerde saklayın. " "Jabber'da parolanızı unutursanız, otomatik kurtarmak için bir yöntem " "bulunmuyor." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Parola Doğrulaması:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Kayıt Ol" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Eski Parola:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Yeni Parola:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" "Bu sayfa bu Jabber sunucusundan bir Jabber hesabının kaydını silmeye olanak " "tanıyor." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Kaydı Sil" ejabberd-2.1.11/src/msgs/zh.po0000664000000000000000000014766712240230175012764 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "Last-Translator: Shelley Shyan - shelleyshyan AT gmail DOT com\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Chinese (中文)\n" "X-Additional-Translator: Zhan Caibao - zhancaibao AT gmail DOT com\n" "X-Additional-Translator: Mike Wang\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "要求使用 STARTTLS" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "无资源提供" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "被新的连接替换" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "你的活跃私聊列表拒绝了在此房间进行路由分发." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "请输入您所看到的文本" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "您发送给 ~s 的消息已被阻止. 要解除阻止, 请访问 ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "如果您在这里没有看到验证码图片, 请访问网页." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "验证码网页" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "验证码有效." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "命令" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "确实要删除每日消息吗?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "标题" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "消息主体" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "通知消息无正文内容" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "通知" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "发送通知给所有用户" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "发送通知给所有主机上的所有用户" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "发送通知给所有在线用户" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "发送通知给所有主机的在线用户" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "设定每日消息并发送给所有在线用户" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "设置所有主机上的每日消息并发送给在线用户" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "更新每日消息(不发送)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "更新所有主机上的每日消息(不发送)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "删除每日消息" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "删除所有主机上的每日消息" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "配置" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "数据库" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "启动模块" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "停止模块" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "备份" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "恢复" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "转储到文本文件" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "导入文件" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "导入目录" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "重启服务" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "关闭服务" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "添加用户" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "删除用户" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "结束用户会话" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "获取用户密码" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "更改用户密码" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "获取用户上次登陆时间" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "获取用户统计" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "获取注册用户数" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "获取在线用户数" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "访问控制列表(ACL)" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "访问规则" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "用户管理" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "在线用户" #: mod_configure.erl:501 msgid "All Users" msgstr "所有用户" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "出站 s2s 连接" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "运行中的节点" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "已经停止的节点" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "模块" #: mod_configure.erl:578 msgid "Backup Management" msgstr "备份管理" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "从 jabberd14 Spool 文件导入用户" #: mod_configure.erl:699 msgid "To ~s" msgstr "发送给~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "来自~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "数据库表格配置位于" #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "请选择表格的存储类型" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "仅磁盘复制" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "内存与磁盘复制" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "内存(RAM)复制" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "远程复制" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "要停止的模块位于 " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "请选择要停止的模块" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "要启动的模块位于 " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "请输入{模块, [选项]}列表" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "要启动的模块列表" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "备份文件位于" #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "请输入备份文件的路径" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "文件路径" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "要恢复的备份文件位于" #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "转储备份到文本文件于" #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "请输入文本文件的路径" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "导入用户的文件位于 " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "请输入 jabberd14 spool 文件的路径" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "导入用户的目录位于 " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "请输入 jabberd14 spool 目录的路径" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "目录的路径" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "时间延迟" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "访问控制列表(ACL)配置" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "访问控制列表(ACL)" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "访问配置" #: mod_configure.erl:1175 msgid "Access rules" msgstr "访问规则" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "密码" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "确认密码" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "注册用户数" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "在线用户数" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "从未" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "在线" #: mod_configure.erl:1701 msgid "Last login" msgstr "上次登陆" #: mod_configure.erl:1722 msgid "Roster size" msgstr "花名册大小" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "IP 地址" #: mod_configure.erl:1724 msgid "Resources" msgstr "资源" #: mod_configure.erl:1850 msgid "Administration of " msgstr "管理" #: mod_configure.erl:1853 msgid "Action on user" msgstr "对用户的动作" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "编辑属性" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "删除用户" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "访问被服务策略拒绝" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC 传输" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC 模块" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "您需要一个兼容 x:data 的客户端来配置 mod_irc 设置" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "mod_irc 中的注册是为 " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "请输入您想使用的用来连接到IRC服务器的用户名, 编码, 端口和密码." #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "IRC 用户名" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "如果您想为 IRC 服务器指定不同的端口, 密码, 编码, 请用 '{\"irc 服务器\", \"编" "码\", 端口, \"密码\"}' 格式的值填充此表单. 默认情况下此服务使用\"~s\"编码, " "~p 端口, 密码为空." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "例如: [{\"irc.lucky.net\", \"koi8-r\"}, 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "连接参数" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "加入 IRC 频道" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "IRC 频道 (不要输入第一个#号)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "IRC 服务器" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "在这里加入 IRC 频道." #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "用此 Jabber ID: ~s 加入 IRC 频道" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "IRC 设置" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "请输入您想使用的用来连接到 IRC 服务器的用户名和编码. 按 '下一步' 获取更多待填" "字段. 按 '完成' 保存设置." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "IRC 用户名" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "~b 的密码" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "~b 的端口" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "服务器 ~b 的编码" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "服务器 ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "只有服务管理员可以发送服务消息" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "创建房间被服务策略拒绝" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "会议室不存在" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "聊天室" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "您需要一个支持 x:data 的客户端来注册昵称" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "昵称注册于 " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "请输入您想要注册的昵称" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "昵称" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "该昵称已被另一个人注册了" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "您必须填充表单中\"昵称\"项" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC 模块" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "聊天室配置已修改" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "加入房间" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "离开房间" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "已被禁止" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "已被踢出" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "因联属关系改变而被踢出" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "因该房间改为只对会员开放而被踢出" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "因系统关机而被踢出" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "现在称呼为" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr "已将标题设置为: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "聊天室已被创建" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "聊天室已被销毁" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "聊天室已被启动" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "聊天室已被停用" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "星期一" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "星期二" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "星期三" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "星期四" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "星期五" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "星期六" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "星期天" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "一月" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "二月" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "三月" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "四月" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "五月" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "六月" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "七月" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "八月" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "九月" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "十月" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "十一月" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "十二月" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "房间配置" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "房间人数" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "已经超过传输率限制" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "该参与人由于发送了错误消息而被踢出了聊天室" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "不允许向会议发送私聊消息" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "请稍后再发送新的声音请求" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "该会议的声音请求以被禁用" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "无法从你的声音请求确认信息中提取JID" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "仅主持人能确认声音请求" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "不恰当的消息类型" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "该参与人由于给其他人发送了出错消息而被踢出了聊天室" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "\"群组聊天\"类型不允许发送私聊消息" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "接收人不在会议室" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "不可以发送私聊消息" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "只有与会人可以向大会发送消息" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "只有与会人可以向大会发出查询请求" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "本房间不可以查询会议成员信息" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "只有主持人和参与人可以在此房间里更改主题" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "只有主持人可以在此房间里更改主题" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "不允许访客给所有占有者发送消息" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "该用户由于发送了错误状态而被踢出了聊天室" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "此房间不允许用户更改昵称" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "该昵称已被另一用户使用" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "您已被禁止进入该房间" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "进入此房间需要会员身份" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "此房间不是匿名房间" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "进入此房间需要密码" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "验证码请求太多" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "无法生成验证码" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "密码不正确" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "需要管理员权限" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "需要主持人权限" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Jabber ID ~s 无效" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "昵称 ~s 不在该房间" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "无效加入: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "无效角色: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "需要持有人权限" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "房间 ~s 的配置 " #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "房间标题" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "房间描述" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "永久保存该房间" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "使房间可被公开搜索" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "公开参与人列表" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "进入此房间需要密码" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "允许的与会人最大数" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "不限" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "将真实 Jabber ID 显示给" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "仅主持人" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "任何人" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "设置房间只接收会员" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "设置房间只接收主持人" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "用户默认被视为参与人" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "允许用户更改主题" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "允许用户发送私聊消息" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "允许访客发送私聊消息至" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "没有人" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "允许用户查询其它用户" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "允许用户发送邀请" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "更新在线状态时允许用户发送状态文本" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "允许用户更改昵称" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "允许访客发送声音请求" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "声音请求的最小间隔(以秒为单位)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "保护房间验证码" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "从验证码挑战中排除 Jabber ID" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "启用服务器端聊天记录" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "您需要一个兼容 x:data 的客户端来配置房间" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "驻留人数" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "保密, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "声音请求" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "接受或拒绝声音请求" #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "用户 JID" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "为此人授权声音?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s 邀请你到 ~s 房间" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "密码是" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "您的联系人离线消息队列已满. 消息已被丢弃" #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "~s 的离线消息队列" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "已提交" #: mod_offline.erl:571 msgid "Time" msgstr "时间" #: mod_offline.erl:572 msgid "From" msgstr "从" #: mod_offline.erl:573 msgid "To" msgstr "到" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "数据包" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "删除已选内容" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "离线消息:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "移除所有离线消息" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 字节流模块" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "发行-订阅" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "ejabberd 发行-订阅模块" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "PubSub 订阅人请求" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "选择是否允许该实体的订阅" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "节点 ID" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "订阅人地址" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "允许该 Jabber ID 订阅该 pubsub 节点?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "用事件通告传输有效负载" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "传递事件通知" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "当节点设置改变时通知订阅人" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "当节点被删除时通知订阅人" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "当从节点删除内容条目时通知订阅人" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "持久化内容条目" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "该节点的友好名称" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "允许持久化的最大内容条目数" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "是否允许订阅" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "指定访问范例" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "允许订阅的花名册组" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "指定发布人范例" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "相关发布人离线后清除所有选项" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "指定事件消息类型" # bytes was translated as 'bits'. It's corrected now. #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "最大有效负载字节数" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "何时发送最新发布的内容条目" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "仅将通知发送给可发送的用户" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "加入结点的集合" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "验证码检查失败" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "您需要一个支持 x:data 和验证码的客户端进行注册" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "请选择在此服务器上注册所需的用户名和密码" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "用户" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "密码强度太弱" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "不允许用户太频繁地注册帐户" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "无" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "订阅" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "挂起" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "组" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "确认" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "移除" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "花名册属于 " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "格式错误" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "添加 Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "花名册" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "共享的花名册组群" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "添加新用户" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "姓名:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "描述:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "会员:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "已显示的组:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "组" #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "提交" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber 服务器" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "出生日期" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "城市" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "国家" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "电子邮件" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "姓氏" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "填充表单以搜索任何匹配的 Jabber 用户(在字段末添加*来匹配子串)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "全名" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "中间名" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "姓名" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "组织名称" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "组织单位" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "搜索用户于 " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "您需要一个兼容 x:data 的客户端来搜索" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "vCard 用户搜索" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard 模块" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "搜索结果属于关键词 " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "填充字段以搜索任何匹配的 Jabber 用户" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "未认证的" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd 网页管理" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "管理" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "原始格式" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "~s 访问规则配置" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "虚拟主机" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "用户" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "用户上次活动" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "持续时间: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "上个月" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "上一年" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "所有活动" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "显示普通列表" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "显示完整列表" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "统计" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "没有找到" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "没有找到节点" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "主机" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "注册用户" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "离线消息" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "上次活动" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "注册用户:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "在线用户:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "出站 s2s 连接:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "出站 s2s 服务器" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "更改密码" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "用户 " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "已连接资源:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "密码:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "没有数据" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "节点" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "节点 " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "被监听的端口" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "更新" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "重启" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "停止" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "RPC 调用错误" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "数据库列表位于 " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "存储类型" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "元素" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "内存" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "错误" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "备份来源 " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "注意:这些选项仅将备份内置的 Mnesia 数据库. 如果您正在使用 ODBC 模块, 您还需" "要分别备份您的数据库." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "存储为二进制备份:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "确定" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "立即恢复二进制备份:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "在下次 ejabberd 重启后恢复二进制备份(需要的内存更少):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "存储为普通文本备份:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "立即恢复普通文本备份:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "从 PIEFXIS 文件 (XEP-0227) 导入用户数据:" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "将服务器上所有用户的数据导出到 PIEFXIS 文件 (XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "将某主机的用户数据导出到 PIEFXIS 文件 (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "从 jabberd14 Spool 文件导入用户数据:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "从 jabberd14 Spool 目录导入用户数据:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "监听的端口位于 " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "模块位于 " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "~p 的统计" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "正常运行时间:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "CPU 时间:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "提交的事务:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "取消的事务:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "重启的事务:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "记入日志的事务:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "更新 " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "更新计划" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "被修改模块" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "更新脚本" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "低级别更新脚本" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "脚本检查" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "端口" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "协议" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "模块" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "选项" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "删除" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "开始" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "你的 Jabber 帐户已成功创建." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "帐户创建出错: " #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "你的 Jabber 帐户已成功删除." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "帐户删除失败: " #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "你的 Jabber 帐户密码已成功更新." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "修改密码出错: " #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Jabber 帐户注册" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "注册 Jabber 帐户" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "注销 Jabber 帐户" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "本页面允许在此服务器上创建 Jabber 帐户. 你的 JID (Jabber ID) 的形式如下: 用户" "名@服务器. 请仔细阅读说明并正确填写相应字段." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "用户名:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "此处不区分大小写: macbeth 与 MacBeth 和 Macbeth 是一样的." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "禁用字符:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "服务器:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "不要将密码告诉任何人, 就算是 Jabber 服务器的管理员也不可以." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "你可以稍后用 Jabber 客户端修改你的密码." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "某些 Jabber 客户端可以在你的计算机里存储密码. 请仅在你确认你的计算机安全的情" "况下使用该功能." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "记住你的密码, 或将其记到纸上并放于安全位置. 如果你忘记了密码, Jabber 也没有自" "动恢复密码的方式." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "密码确认:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "注册" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "旧密码: " #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "新密码: " #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "此页面允许在此 Jabber 服务器上注销 Jabber 帐户" #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "取消注册" #~ msgid "Captcha test failed" #~ msgstr "验证码检测失败." #~ msgid "Encodings" #~ msgstr "编码" #~ msgid "(Raw)" #~ msgstr "(原始格式)" #~ msgid "Specified nickname is already registered" #~ msgstr "指定的昵称已被注册" #~ msgid "Size" #~ msgstr "大小" ejabberd-2.1.11/src/msgs/vi.msg0000664000000000000000000004530112240230175013107 0ustar {"Access Configuration","Cấu Hình Truy Cập"}. {"Access Control List Configuration","Cấu Hình Danh Sách Kiểm Soát Truy Cập"}. {"Access control lists","Danh sách kiểm soát truy cập"}. {"Access Control Lists","Danh Sách Kiểm Soát Truy Cập"}. {"Access denied by service policy","Sự truy cập bị chặn theo chính sách phục vụ"}. {"Access rules","Quy tắc Truy Cập"}. {"Access Rules","Quy Tắc Truy Cập"}. {"Action on user","Hành động đối với người sử dụng"}. {"Add Jabber ID","Thêm Jabber ID"}. {"Add New","Thêm Mới"}. {"Add User","Thêm Người Sử Dụng"}. {"Administration of ","Quản trị về "}. {"Administration","Quản trị"}. {"Administrator privileges required","Yêu cầu đặc quyền của nhà quản trị"}. {"All activity","Tất cả hoạt động"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Cho phép Jabber ID đăng ký nút môđun xuất bản đăng ký này không?"}. {"Allow users to query other users","Cho phép người sử dụng hỏi người sử dụng khác"}. {"Allow users to send invites","Cho phép người sử dụng gửi lời mời"}. {"Allow users to send private messages","Cho phép người sử dụng gửi thư riêng"}. {"All Users","Tất Cả Người Sử Dụng"}. {"Announcements","Thông báo"}. {"anyone","bất kỳ ai"}. {"April","Tháng Tư"}. {"August","Tháng Tám"}. {"Backup Management","Quản lý Sao Lưu Dự Phòng"}. {"Backup of ","Sao lưu dự phòng về"}. {"Backup","Sao lưu dự phòng"}. {"Backup to File at ","Sao lưu dự phòng ra Tập Tin tại"}. {"Bad format","Định dạng hỏng"}. {"Birthday","Ngày sinh"}. {"Change Password","Thay Đổi Mật Khẩu"}. {"Change User Password","Thay Đổi Mật Khẩu Người Sử Dụng"}. {"Chatroom configuration modified","Cấu hình phòng trò chuyện được chỉnh sửa"}. {"Chatrooms","Phòng trò chuyện"}. {"Choose a username and password to register with this server","Chọn một tên truy cập và mật khẩu để đăng ký với máy chủ này"}. {"Choose modules to stop","Chọn môđun để dừng"}. {"Choose storage type of tables","Chọn loại bảng lưu trữ"}. {"Choose whether to approve this entity's subscription.","Chọn có nên chấp nhận sự đăng ký của đối tượng này không"}. {"City","Thành phố"}. {"Commands","Lệnh"}. {"Conference room does not exist","Phòng họp không tồn tại"}. {"Configuration","Cấu hình"}. {"Connected Resources:","Tài Nguyên Được Kết Nối:"}. {"Country","Quốc gia"}. {"CPU Time:","Thời Gian CPU:"}. {"Database","Cơ sở dữ liệu"}. {"Database Tables at ","Bảng Cơ Sở Dữ Liệu tại"}. {"Database Tables Configuration at ","Cấu Hình Bảng Cơ Sở Dữ Liệu tại"}. {"December","Tháng Mười Hai"}. {"Default users as participants","Người sử dụng mặc định là người tham dự"}. {"Delete message of the day on all hosts","Xóa thư trong ngày trên tất cả các máy chủ"}. {"Delete message of the day","Xóa thư trong ngày"}. {"Delete Selected","Tùy chọn Xóa được Chọn"}. {"Delete User","Xóa Người Sử Dụng"}. {"Delete","Xóa"}. {"Deliver event notifications","Đưa ra các thông báo sự kiện"}. {"Deliver payloads with event notifications","Đưa ra thông tin dung lượng với các thông báo sự kiện"}. {"Description:","Miêu tả:"}. {"Disc only copy","Chỉ sao chép vào đĩa"}. {"Displayed Groups:","Nhóm được hiển thị:"}. {"Dump Backup to Text File at ","Kết Xuất Sao Lưu ra Tập Tin Văn Bản tại"}. {"Dump to Text File","Kết xuất ra Tập Tin Văn Bản"}. {"Edit Properties","Chỉnh Sửa Thuộc Tính"}. {"ejabberd IRC module","Môdun ejabberd IRC Bản quyền"}. {"ejabberd MUC module","Môdun ejabberd MUC Bản quyền"}. {"ejabberd Publish-Subscribe module","Môdun ejabberd Xuất Bản-Đăng Ký Bản quyền"}. {"ejabberd SOCKS5 Bytestreams module","Môdun SOCKS5 Bytestreams Bản quyền"}. {"ejabberd vCard module","Môdun ejabberd vCard Bản quyền"}. {"Email","Email"}. {"Enable logging","Cho phép ghi nhật ký"}. {"End User Session","Kết Thúc Phiên Giao Dịch Người Sử Dụng"}. {"Enter list of {Module, [Options]}","Nhập danh sách {Môđun, [Các Tùy Chọn]}"}. {"Enter nickname you want to register","Nhập bí danh bạn muốn đăng ký"}. {"Enter path to backup file","Nhập đường dẫn đến tập tin sao lưu dự phòng"}. {"Enter path to jabberd14 spool dir","Nhập đường dẫn đến thư mục spool jabberd14"}. {"Enter path to jabberd14 spool file","Nhập đường dẫn đến tập tin spool jabberd14"}. {"Enter path to text file","Nhập đường dẫn đến tập tin văn bản"}. {"Erlang Jabber Server","Erlang Jabber Server Bản quyền"}. {"Family Name","Họ"}. {"February","Tháng Hai"}. {"Fill in fields to search for any matching Jabber User","Điền vào các ô để tìm kiếm bất kỳ các thông tin nào khớp với Người sử dụng Jabber"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Điền vào mẫu này để tìm kiếm bất kỳ thông tin nào khớp với Người sử dụng Jabber (Thêm dấu * vào cuối ô để thông tin khớp với chuỗi bên trong)"}. {"Friday","Thứ Sáu"}. {"From ~s","Nhận từ ~s"}. {"From","Từ"}. {"Full Name","Tên Đầy Đủ"}. {"Get Number of Online Users","Nhận Số Người Sử Dụng Trực Tuyến"}. {"Get Number of Registered Users","Nhận Số Người Sử Dụng Đã Đăng Ký"}. {"Get User Last Login Time","Nhận Thời Gian Đăng Nhập Cuối Cùng Của Người Sử Dụng"}. {"Get User Password","Nhận Mật Khẩu Người Sử Dụng"}. {"Get User Statistics","Nhận Thông Tin Thống Kê Người Sử Dụng"}. {"Group ","Nhóm "}. {"Groups","Nhóm"}. {"has been banned","đã bị cấm"}. {"has been kicked","đã bị đẩy ra khỏi"}. {" has set the subject to: "," đã đặt chủ đề thành: "}. {"Host","Máy chủ"}. {"Import Directory","Nhập Thư Mục"}. {"Import File","Nhập Tập Tin"}. {"Import User from File at ","Nhập Người Sử Dụng từ Tập Tin tại"}. {"Import Users from Dir at ","Nhập Người Sử Dụng từ Thư Mục tại"}. {"Import Users From jabberd14 Spool Files","Nhập Người Sử Dụng Từ Các Tập Tin Spool jabberd14"}. {"Improper message type","Loại thư không phù hợp"}. {"Incorrect password","Mật khẩu sai"}. {"Invalid affiliation: ~s","Tư cách không hợp lệ: ~s"}. {"Invalid role: ~s","Vai trò không hợp lệ: ~s"}. {"IP addresses","Địa chỉ IP"}. {"IRC Transport","Truyền tải IRC"}. {"IRC Username","Tên truy cập IRC"}. {"is now known as","bây giờ được biết như"}. {"It is not allowed to send private messages of type \"groupchat\"","Không được phép gửi những thư riêng loại \"groupchat\""}. {"It is not allowed to send private messages to the conference","Không được phép gửi những thư riêng đến phòng họp"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Jabber ID ~s không hợp lệ"}. {"January","Tháng Một"}. {"joins the room","tham gia phòng này"}. {"July","Tháng Bảy"}. {"June","Tháng Sáu"}. {"Last Activity","Hoạt Động Cuối Cùng"}. {"Last login","Đăng nhập lần cuối"}. {"Last month","Tháng trước"}. {"Last year","Năm trước"}. {"leaves the room","rời khỏi phòng này"}. {"Listened Ports at ","Cổng Liên Lạc tại"}. {"Listened Ports","Cổng Kết Nối"}. {"List of modules to start","Danh sách các môđun khởi động"}. {"Low level update script","Lệnh cập nhật mức độ thấp"}. {"Make participants list public","Tạo danh sách người tham dự công khai"}. {"Make room members-only","Tạo phòng chỉ cho phép tư cách thành viên tham gia"}. {"Make room password protected","Tạo phòng được bảo vệ bằng mật khẩu"}. {"Make room persistent","Tạo phòng bền vững"}. {"Make room public searchable","Tạo phòng có thể tìm kiếm công khai"}. {"March","Tháng Ba"}. {"Maximum Number of Occupants","Số Lượng Người Tham Dự Tối Đa"}. {"Max # of items to persist","Số mục tối đa để lưu trữ"}. {"Max payload size in bytes","Kích thước dung lượng byte tối đa"}. {"May","Tháng Năm"}. {"Members:","Thành viên:"}. {"Memory","Bộ Nhớ"}. {"Message body","Thân thư"}. {"Middle Name","Họ Đệm"}. {"Moderator privileges required","Yêu cầu đặc quyền của nhà điều phối"}. {"moderators only","nhà điều phối duy nhất"}. {"Module","Môđun"}. {"Modules at ","Môđun tại "}. {"Modules","Môđun"}. {"Monday","Thứ Hai"}. {"Name:","Tên:"}. {"Name","Tên"}. {"Never","Không bao giờ"}. {"Nickname","Bí danh"}. {"Nickname Registration at ","Đăng Ký Bí Danh tại"}. {"Nickname ~s does not exist in the room","Bí danh ~s không tồn tại trong phòng này"}. {"No body provided for announce message","Không có nội dung trong thư thông báo"}. {"No Data","Không Dữ Liệu"}. {"Node ID","ID Nút"}. {"Node not found","Nút không tìm thấy"}. {"Node ","Nút "}. {"Nodes","Nút"}. {"No limit","Không giới hạn"}. {"None","Không có"}. {"No resource provided","Không có nguồn lực cung cấp"}. {"Notify subscribers when items are removed from the node","Thông báo cho người đăng ký khi nào các mục chọn bị gỡ bỏ khỏi nút"}. {"Notify subscribers when the node configuration changes","Thông báo cho người đăng ký khi nào cấu hình nút thay đổi"}. {"Notify subscribers when the node is deleted","Thông báo cho người đăng ký khi nào nút bị xóa bỏ"}. {"November","Tháng Mười Một"}. {"Number of occupants","Số người tham dự"}. {"Number of online users","Số người sử dụng trực tuyến"}. {"Number of registered users","Số người sử dụng đã đăng ký"}. {"October","Tháng Mười"}. {"Offline Messages:","Thư Ngoại Tuyến:"}. {"Offline Messages","Thư Ngoại Tuyến"}. {"OK","OK"}. {"Online","Trực tuyến"}. {"Online Users:","Người Sử Dụng Trực Tuyến:"}. {"Online Users","Người Sử Dụng Trực Tuyến"}. {"Only deliver notifications to available users","Chỉ gửi thông báo đến những người sử dụng hiện có"}. {"Only occupants are allowed to send messages to the conference","Chỉ có những đối tượng tham gia mới được phép gửi thư đến phòng họp"}. {"Only occupants are allowed to send queries to the conference","Chỉ có những đối tượng tham gia mới được phép gửi yêu cầu đến phòng họp"}. {"Only service administrators are allowed to send service messages","Chỉ có người quản trị dịch vụ mới được phép gửi những thư dịch vụ"}. {"Options","Tùy chọn"}. {"Organization Name","Tên Tổ Chức"}. {"Organization Unit","Bộ Phận"}. {"Outgoing s2s Connections:","Kết Nối Bên Ngoài s2s:"}. {"Outgoing s2s Connections","Kết Nối Bên Ngoài s2s"}. {"Outgoing s2s Servers:","Máy chủ Bên Ngoài s2s:"}. {"Owner privileges required","Yêu cầu đặc quyền của người sở hữu"}. {"Packet","Gói thông tin"}. {"Password:","Mật Khẩu:"}. {"Password","Mật Khẩu"}. {"Password Verification","Kiểm Tra Mật Khẩu"}. {"Path to Dir","Đường Dẫn đến Thư Mục"}. {"Path to File","Đường dẫn đến Tập Tin"}. {"Pending","Chờ"}. {"Period: ","Giai đoạn: "}. {"Persist items to storage","Những mục cần để lưu trữ"}. {"Ping","Ping"}. {"Pong","Pong"}. {"Port","Cổng"}. {"Present real Jabber IDs to","Jabber ID thực tế hiện hành đến"}. {"private, ","riêng,"}. {"Publish-Subscribe","Xuất Bản-Đăng Ký"}. {"PubSub subscriber request","Yêu cầu người đăng ký môđun Xuất Bản Đăng Ký"}. {"Queries to the conference members are not allowed in this room","Không được phép gửi các yêu cầu gửi đến các thành viên trong phòng họp này"}. {"RAM and disc copy","Sao chép vào RAM và đĩa"}. {"RAM copy","Sao chép vào RAM"}. {"Raw","Thô"}. {"Really delete message of the day?","Có thực sự xóa thư trong ngày này không?"}. {"Recipient is not in the conference room","Người nhận không có trong phòng họp"}. {"Registered Users:","Người Sử Dụng Đã Đăng Ký:"}. {"Registered Users","Người Sử Dụng Đã Đăng Ký"}. {"Registration in mod_irc for ","Đăng ký trong mod_irc cho "}. {"Remote copy","Sao chép từ xa"}. {"Remove","Gỡ bỏ"}. {"Remove User","Gỡ Bỏ Người Sử Dụng"}. {"Replaced by new connection","Được thay thế bởi kết nối mới"}. {"Resources","Nguồn tài nguyên"}. {"Restart","Khởi động lại"}. {"Restart Service","Khởi Động Lại Dịch Vụ"}. {"Restore Backup from File at ","Phục hồi Sao Lưu từ Tập Tin tại "}. {"Restore binary backup after next ejabberd restart (requires less memory):","Khôi phục bản sao lưu dự phòng dạng nhị phân sau lần khởi động ejabberd kế tiếp (yêu cầu ít bộ nhớ hơn):"}. {"Restore binary backup immediately:","Khôi phục bản sao lưu dự phòng dạng nhị phận ngay lập tức:"}. {"Restore","Khôi phục"}. {"Restore plain text backup immediately:","Khôi phục bản sao lưu dự phòng thuần văn bản ngay lập tức:"}. {"Room Configuration","Cấu Hình Phòng"}. {"Room creation is denied by service policy","Việc tạo phòng bị ngăn lại theo chính sách dịch vụ"}. {"Room title","Tên phòng"}. {"Roster","Bảng phân công"}. {"Roster of ","Bảng phân công của "}. {"Roster size","Kích thước bảng phân công"}. {"RPC Call Error","Lỗi Gọi RPC"}. {"Running Nodes","Nút Hoạt Động"}. {"~s access rule configuration","~s cấu hình quy tắc truy cập"}. {"Saturday","Thứ Bảy"}. {"Script check","Lệnh kiểm tra"}. {"Search Results for ","Kết Quả Tìm Kiếm cho "}. {"Search users in ","Tìm kiếm người sử dụng trong"}. {"Send announcement to all online users","Gửi thông báo đến tất cả người sử dụng trực tuyến"}. {"Send announcement to all online users on all hosts","Gửi thông báo đến tất cả người sử dụng trực tuyến trên tất cả các máy chủ"}. {"Send announcement to all users","Gửi thông báo đến tất cả người sử dụng"}. {"Send announcement to all users on all hosts","Gửi thông báo đến tất cả người sử dụng trên tất cả các máy chủ"}. {"September","Tháng Chín"}. {"Set message of the day and send to online users","Tạo lập thư trong ngày và gửi đến những người sử dụng trực tuyến"}. {"Set message of the day on all hosts and send to online users","Tạo lập thư trong ngày trên tất cả các máy chủ và gửi đến những người sử dụng trực tuyến"}. {"Shared Roster Groups","Nhóm Phân Công Chia Sẻ"}. {"Show Integral Table","Hiển Thị Bảng Đầy Đủ"}. {"Show Ordinary Table","Hiển Thị Bảng Thường"}. {"Shut Down Service","Tắt Dịch Vụ"}. {"~s invites you to the room ~s","~s mời bạn vào phòng ~s"}. {"Specify the access model","Xác định mô hình truy cập"}. {"Specify the publisher model","Xác định mô hình nhà xuất bản"}. {"~s's Offline Messages Queue","~s's Danh Sách Chờ Thư Ngoại Tuyến"}. {"Start","Khởi động"}. {"Start Modules at ","Môđun Khởi Động tại "}. {"Start Modules","Môđun Khởi Động"}. {"Statistics of ~p","Thống kê về ~p"}. {"Statistics","Số liệu thống kê"}. {"Stop","Dừng"}. {"Stop Modules at ","Môđun Dừng tại"}. {"Stop Modules","Môđun Dừng"}. {"Stopped Nodes","Nút Dừng"}. {"Storage Type","Loại Lưu Trữ"}. {"Store binary backup:","Lưu dữ liệu sao lưu dạng nhị phân:"}. {"Store plain text backup:","Khôi phục bản sao lưu dự phòng thuần văn bản"}. {"Subject","Tiêu đề"}. {"Submit","Gửi"}. {"Submitted","Đã gửi"}. {"Subscriber Address","Địa Chỉ Người Đăng Ký"}. {"Subscription","Đăng ký"}. {"Sunday","Chủ Nhật"}. {"the password is","mật khẩu là"}. {"This room is not anonymous","Phòng này không nặc danh"}. {"Thursday","Thứ Năm"}. {"Time delay","Thời gian trì hoãn"}. {"Time","Thời Gian"}. {"To","Đến"}. {"To ~s","Gửi đến ~s"}. {"Traffic rate limit is exceeded","Quá giới hạn tỷ lệ lưu lượng truyền tải"}. {"Transactions Aborted:","Giao Dịch Hủy Bỏ:"}. {"Transactions Committed:","Giao Dịch Được Cam Kết:"}. {"Transactions Logged:","Giao Dịch Được Ghi Nhận:"}. {"Transactions Restarted:","Giao Dịch Khởi Động Lại:"}. {"Tuesday","Thứ Ba"}. {"Update ","Cập Nhật "}. {"Update","Cập Nhật"}. {"Update message of the day (don't send)","Cập nhật thư trong ngày (không gửi)"}. {"Update message of the day on all hosts (don't send)","Cập nhật thư trong ngày trên tất cả các máy chủ (không gửi)"}. {"Update plan","Kế hoạch cập nhật"}. {"Update script","Cập nhận lệnh"}. {"Uptime:","Thời gian tải lên:"}. {"Use of STARTTLS required","Yêu cầu sử dụng STARTTLS"}. {"User Management","Quản Lý Người Sử Dụng"}. {"User ","Người sử dụng "}. {"User","Người sử dụng"}. {"Users Last Activity","Hoạt Động Cuối Cùng Của Người Sử Dụng"}. {"Users","Người sử dụng"}. {"Validate","Xác nhận hợp lệ"}. {"vCard User Search","Tìm Kiếm Người Sử Dụng vCard"}. {"Virtual Hosts","Máy Chủ Ảo"}. {"Visitors are not allowed to send messages to all occupants","Người ghé thăm không được phép gửi thư đến tất cả các người tham dự"}. {"Wednesday","Thứ Tư"}. {"When to send the last published item","Khi cần gửi mục được xuất bản cuối cùng"}. {"Whether to allow subscriptions","Xác định nên cho phép đăng ký không"}. {"You have been banned from this room","Bạn bị cấm tham gia phòng này"}. {"You must fill in field \"Nickname\" in the form","Bạn phải điền thông tin vào ô \"Nickname\" trong biểu mẫu này"}. {"You need an x:data capable client to configure mod_irc settings","Bạn cần có một trình ứng dụng khách hỗ trợ định dạng dữ liệu x: để xác định các thiết lập mod_irc"}. {"You need an x:data capable client to configure room","Bạn cần có một trình ứng dụng khách hỗ trợ định dạng dữ liệu x: để xác định cấu hình phòng họp"}. {"You need an x:data capable client to search","Bạn cần có một trình ứng dụng khách hỗ trợ định dạng dữ liệu x: để tìm kiếm"}. {"Your contact offline message queue is full. The message has been discarded.","Danh sách chờ thư liên lạc ngoại tuyến của bạn đã đầy. Thư này đã bị loại bỏ."}. ejabberd-2.1.11/src/msgs/ru.po0000664000000000000000000020242012240230175012744 0ustar # , 2010. msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "POT-Creation-Date: \n" "PO-Revision-Date: 2012-04-15 13:38+0900\n" "Last-Translator: Evgeniy Khramtsov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Russian (русский)\n" "X-Additional-Translator: Konstantin Khomoutov\n" "X-Additional-Translator: Sergei Golovan\n" "X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Вы обязаны использовать STARTTLS" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Не указан ресурс" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Заменено новым соединением" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "" "Маршрутизация этой строфы запрещена вашим активным списком приватности." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Введите увиденный текст" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "Ваши сообщения к ~s блокируются. Для снятия блокировки перейдите по ссылке ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "Если вы не видите изображение капчи, перейдите по ссылке." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "Ссылка на капчу" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "Проверка капчи прошла успешно." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Команды" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Пинг" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Понг" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Действительно удалить сообщение дня?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Тема" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Тело сообщения" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Тело объявления не должно быть пустым" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Объявления" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Разослать объявление всем пользователям" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Разослать объявление всем пользователям на всех виртуальных серверах" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Разослать объявление всем подключённым пользователям" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "" "Разослать объявление всем подключённым пользователям на всех виртуальных " "серверах" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Установить сообщение дня и разослать его подключённым пользователям" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Установить сообщение дня на всех виртуальных серверах и разослать его " "подключённым пользователям" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Обновить сообщение дня (не рассылать)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Обновить сообщение дня на всех виртуальных серверах (не рассылать)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Удалить сообщение дня" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Удалить сообщение дня со всех виртуальных серверов" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Конфигурация" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "База данных" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Запуск модулей" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Остановка модулей" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Резервное копирование" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Восстановление из резервной копии" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Копирование в текстовый файл" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Импорт из файла" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Импорт из директории" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Перезапустить службу" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Остановить службу" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Добавить пользователя" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Удалить пользователя" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Завершить сеанс пользователя" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Получить пароль пользователя" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Изменить пароль пользователя" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Получить время последнего подключения пользователя" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Получить статистику по пользователю" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Получить количество зарегистрированных пользователей" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Получить количество подключённых пользователей" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Списки управления доступом" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Правила доступа" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Управление пользователями" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Подключённые пользователи" #: mod_configure.erl:501 msgid "All Users" msgstr "Все пользователи" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Исходящие s2s-соединения" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Работающие узлы" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Остановленные узлы" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Модули" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Управление резервным копированием" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Импорт пользователей из спула jabberd14" #: mod_configure.erl:699 msgid "To ~s" msgstr "К ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "От ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Конфигурация таблиц базы данных на " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Выберите тип хранения таблиц" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "только диск" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "ОЗУ и диск" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "ОЗУ" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "не хранится локально" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Остановка модулей на " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Выберите модули, которые следует остановить" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Запуск модулей на " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Введите список вида {Module, [Options]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Список запускаемых модулей" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Резервное копирование в файл на " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Введите путь к резервному файлу" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Путь к файлу" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Восстановление из резервной копии на " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Копирование в текстовый файл на " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Введите путь к текстовому файлу" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Импорт пользователя из файла на " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Введите путь к файлу из спула jabberd14" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Импорт пользователей из директории на " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Введите путь к директории спула jabberd14" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Путь к директории" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "По истечение" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Конфигурация списков управления доступом" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Списки управления доступом" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Конфигурация доступа" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Правила доступа" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Пароль" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Проверка пароля" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Количество зарегистрированных пользователей" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Количество подключённых пользователей" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Никогда" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Подключён" #: mod_configure.erl:1701 msgid "Last login" msgstr "Время последнего подключения" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Размер списка контактов" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "IP адреса" #: mod_configure.erl:1724 msgid "Resources" msgstr "Ресурсы" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Администрирование " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Действие над пользователем" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Изменить параметры" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Удалить пользователя" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Доступ запрещён политикой службы" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC Транспорт" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC модуль" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "Чтобы настроить параметры mod_irc, требуется x:data-совместимый клиент" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Регистрация в mod_irc для " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Введите имя пользователя, кодировки, порты и пароли, которые будут " "использоваться при подключении к IRC-серверам" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Имя пользователя IRC" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Чтобы указать различные порты, пароли, кодировки для разных серверов IRC, " "заполните список значениями в формате '{\"сервер IRC\", \"кодировка\", порт, " "\"пароль\"}'. По умолчанию сервис использует кодировку \"~s\", порт ~p, " "пустой пароль." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Пример: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Параметры соединения" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Присоединиться к каналу IRC" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "Канал IRC (без символа #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "Сервер IRC" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Присоединяйтесь к каналу IRC" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Присоединиться к каналу IRC с Jabber ID: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "Настройки IRC" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Введите имя пользователя и кодировки, которые будут использоваться при " "подключении к IRC-серверам. Нажмите 'Далее' для получения дополнительных " "полей для заполнения. Нажмите 'Завершить' для сохранения настроек." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "Имя пользователя IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Пароль ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Порт ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Кодировка сервера ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Сервер ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "Только администратор службы может посылать служебные сообщения" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Cоздавать конференцию запрещено политикой службы" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Конференция не существует" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Комнаты" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "Чтобы зарегистрировать псевдоним, требуется x:data-совместимый клиент" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Регистрация псевдонима на " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Введите псевдоним, который Вы хотели бы зарегистрировать" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Псевдоним" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Этот псевдоним зарегистрирован кем-то другим" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Вы должны заполнить поле \"Псевдоним\" в форме" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC модуль" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Конфигурация комнаты изменилась" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "вошёл(а) в комнату" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "вышел(а) из комнаты" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "запретили входить в комнату" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "выгнали из комнаты" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "выгнали из комнаты вследствие смены ранга" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "выгнали из комнаты потому что она стала только для членов" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "выгнали из комнаты из-за останова системы" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "изменил(а) имя на" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " установил(а) тему: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Комната создана" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Комната уничтожена" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Комната запущена" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Комната остановлена" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Понедельник" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Вторник" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Среда" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Четверг" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Пятница" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Суббота" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Воскресенье" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "января" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "февраля" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "марта" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "апреля" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "мая" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "июня" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "июля" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "августа" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "сентября" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "октября" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "ноября" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "декабря" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Конфигурация комнаты" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Участники комнаты" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Превышен лимит скорости посылки информации" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Этого участника выгнали из комнаты за то, что он послал сообщение об ошибке" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Не разрешается посылать частные сообщения прямо в конференцию" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "" "Пожалуйста, подождите перед тем как подать новый запрос на право голоса" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "Запросы на право голоса отключены в этой конференции" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "Ошибка обработки JID из вашего запроса на право голоса" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Только модераторы могут утверждать запросы на право голоса" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Неправильный тип сообщения" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Этого участника выгнали из комнаты за то, что он послал сообщение об ошибке " "другому участнику" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "Нельзя посылать частные сообщения типа \"groupchat\"" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Адресата нет в конференции" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Запрещено посылать приватные сообщения" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Только присутствующим разрешается посылать сообщения в конференцию" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Только присутствующим разрешается посылать запросы в конференцию" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "Запросы к пользователям в этой конференции запрещены" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "Только модераторы и участники могут изменять тему в этой комнате" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Только модераторы могут изменять тему в этой комнате" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Посетителям не разрешается посылать сообщения всем присутствующим" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Этого участника выгнали из комнаты за то, что он послал присутствие с ошибкой" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Посетителям запрещено изменять свои псевдонимы в этой комнате" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Этот псевдоним уже занят другим участником" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Вам запрещено входить в эту конференцию" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "В эту конференцию могут входить только её члены" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Эта комната не анонимная" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Чтобы войти в эту конференцию, нужен пароль" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Слишком много запросов капчи" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Не получилось создать капчу" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Неправильный пароль" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Требуются права администратора" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Требуются права модератора" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Jabber ID ~s недопустимый" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Псевдоним ~s в комнате отсутствует" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Недопустимый ранг: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Недопустимая роль: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Требуются права владельца" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Конфигурация комнаты ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Название комнаты" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Описание комнаты" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Сделать комнату постоянной" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Сделать комнату видимой всем" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Сделать список участников видимым всем" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Сделать комнату защищённой паролем" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Максимальное количество участников" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Не ограничено" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Сделать реальные Jabber ID участников видимыми" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "только модераторам" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "всем участникам" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Комната только для зарегистрированных участников" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Сделать комнату модерируемой" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Сделать пользователей участниками по умолчанию" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Разрешить пользователям изменять тему" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Разрешить приватные сообщения" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "Разрешить посетителям посылать приватные сообщения" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "никто" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Разрешить iq-запросы к пользователям" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Разрешить пользователям посылать приглашения" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "" "Разрешить посетителям вставлять текcт статуса в сообщения о присутствии" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Разрешить посетителям изменять псевдоним" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "Разрешить посетителям запрашивать право голоса" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "Минимальный интервал между запросами на право голоса" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Сделать комнату защищённой капчей" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Исключить показ капчи для списка Jabber ID" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Включить журналирование" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Чтобы сконфигурировать комнату, требуется x:data-совместимый клиент" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Число присутствующих" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "приватная, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Запрос на право голоса" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Подтвердите или отклоните право голоса." #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "JID пользователя" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "Предоставить голос?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s приглашает вас в комнату ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "пароль:" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "Очередь недоставленных сообщений Вашего адресата переполнена. Сообщение не " "было сохранено." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "Oчередь офлайновых сообщений ~s" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Отправлено" #: mod_offline.erl:571 msgid "Time" msgstr "Время" #: mod_offline.erl:572 msgid "From" msgstr "От кого" #: mod_offline.erl:573 msgid "To" msgstr "Кому" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Пакет" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Удалить выделенные" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Офлайновые сообщения:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Удалить все офлайновые сообщения" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestreams модуль" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Публикация-Подписка" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "Модуль ejabberd Публикации-Подписки" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "Запрос подписчика PubSub" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Решите: предоставить ли подписку этому объекту." #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "ID узла" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Адрес подписчика" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Разрешить этому Jabber ID подписаться на данный узел?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Доставлять вместе с уведомлениями o публикациях сами публикации" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Доставлять уведомления о событиях" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Уведомлять подписчиков об изменении конфигурации сборника" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Уведомлять подписчиков об удалении сборника" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Уведомлять подписчиков об удалении публикаций из сборника" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Сохранять публикации в хранилище" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Легко запоминаемое имя для узла" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Максимальное число сохраняемых публикаций" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Разрешить подписку" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Укажите механизм управления доступом" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Группы списка контактов, которым разрешена подписка" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Условия публикации" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "Очищать все записи автора публикации когда он отключается" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Укажите тип сообщения о событии" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Максимальный размер полезной нагрузки в байтах" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Когда посылать последний опубликованный элемент" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Доставлять уведомления только доступным пользователям" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Имя коллекции, в которую входит узел" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "Проверка капчи не пройдена" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "Чтобы зарегистрироваться, требуется x:data-совместимый клиент" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Выберите имя пользователя и пароль для регистрации на этом сервере" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Пользователь" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "Слишком слабый пароль" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Пользователи не могут регистрировать учётные записи так быстро" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Нет" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Подписка" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Ожидание" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Группы" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Утвердить" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Удалить" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Ростер пользователя " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Неправильный формат" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Добавить Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Ростер" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Группы общих контактов" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Добавить" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Название:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Описание:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Члены:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Видимые группы:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Группа " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Отправить" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "День рождения" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Город" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Страна" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Электронная почта" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Фамилия" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Заполните форму для поиска пользователя Jabber (Если добавить * в конец " "поля, то происходит поиск подстроки)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Полное имя" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Отчество" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Название" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Название организации" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Отдел организации" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Поиск пользователей в " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Чтобы воспользоваться поиском, требуется x:data-совместимый клиент" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Поиск пользователей по vCard" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard модуль" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Результаты поиска в " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Заполните форму для поиска пользователя Jabber" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Не авторизован" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "Web-интерфейс администрирования ejabberd" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Администрирование" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Необработанный формат" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Конфигурация правила доступа ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Виртуальные хосты" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Пользователи" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Статистика последнего подключения пользователей" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Период" #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "За последний месяц" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "За последний год" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Вся статистика" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Показать обычную таблицу" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Показать интегральную таблицу" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Статистика" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Не Найдено" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Узел не найден" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Хост" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Зарегистрированные пользователи" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Офлайновые сообщения" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Последнее подключение" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Зарегистрированные пользователи:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Подключённые пользователи:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Исходящие s2s-серверы:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Исходящие s2s-серверы:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Сменить пароль" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Пользователь " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Подключённые ресурсы:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Пароль:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Нет данных" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Узлы" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Узел " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Прослушиваемые порты" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Обновить" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Перезапустить" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Остановить" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "Ошибка вызова RPC" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Таблицы базы данных на " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Тип таблицы" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Элементы" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Память" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Ошибка" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Резервное копирование " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Заметьте, что здесь производится резервное копирование только встроенной " "базы данных Mnesia. Если Вы также используете другое хранилище данных " "(например с помощью модуля ODBC), то его резервное копирование следует " "осуществлять отдельно." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Сохранить бинарную резервную копию:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "Продолжить" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Восстановить из бинарной резервной копии немедленно:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Восстановить из бинарной резервной копии при следующем запуске (требует " "меньше памяти):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Сохранить текстовую резервную копию:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Восстановить из текстовой резервной копии немедленно:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Импорт пользовательских данных из файла формата PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Экспорт данных всех пользователей сервера в файлы формата PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" "Экспорт пользовательских данных домена в файлы формата PIEFXIS (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Импорт пользовательских данных из буферного файла jabberd14:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Импорт пользовательских данных из буферной директории jabberd14:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Прослушиваемые порты на " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Модули на " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "статистика узла ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Время работы:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Процессорное время:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Транзакции завершенные:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Транзакции отмененные:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Транзакции перезапущенные:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Транзакции запротоколированные:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Обновление " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "План обновления" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Изменённые модули" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Сценарий обновления" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Низкоуровневый сценарий обновления" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Проверка сценария" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Порт" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Протокол" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Модуль" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Параметры" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Удалить" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Запустить" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Ваш Jabber-аккаунт был успешно создан." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Ошибка при создании аккаунта:" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Ваш Jabber-аккаунт был успешно удален." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Ошибка при удалении аккаунта:" #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Пароль Вашего Jabber-аккаунта был успешно изменен." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Ошибка при смене пароля:" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Регистрация Jabber-аккаунта" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Зарегистрировать Jabber-аккаунт" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Удалить Jabber-аккаунт" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Здесь Вы можете создать Jabber-аккаунт на этом Jabber-сервере. Ваш JID " "(Jabber-идентификатор) будет в виде: \"пользователь@сервер\". Пожалуйста, " "внимательно читайте инструкции для правильного заполнения полей." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Имя пользователя:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Регистр не имеет значения: \"маша\" и \"МАША\" будет считаться одним и тем " "же именем." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Недопустимые символы:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Сервер:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "Не говорите никому свой пароль, даже администраторам сервера." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "Позже Вы можете изменить пароль через Jabber-клиент." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Некоторые Jabber-клиенты могут сохранять пароль на Вашем компьютере. " "Используйте эту функцию только в том случае, если считаете это безопасным." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Запомните пароль или запишите его на бумаге, которую сохраните в безопасном " "месте. В Jabber'е нет автоматизированного средства восстановления пароля в " "том случае, если Вы его забудете." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Проверка пароля:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Зарегистрировать" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Старый пароль:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Новый пароль:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "Здесь Вы можете удалить Jabber-аккаунт с этого сервера." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Удалить" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "Проверка капчи прошла успешно." ejabberd-2.1.11/src/msgs/zh.msg0000664000000000000000000006046612240230175013123 0ustar {"Access Configuration","访问配置"}. {"Access Control List Configuration","访问控制列表(ACL)配置"}. {"Access control lists","访问控制列表(ACL)"}. {"Access Control Lists","访问控制列表(ACL)"}. {"Access denied by service policy","访问被服务策略拒绝"}. {"Access rules","访问规则"}. {"Access Rules","访问规则"}. {"Action on user","对用户的动作"}. {"Add Jabber ID","添加 Jabber ID"}. {"Add New","添加新用户"}. {"Add User","添加用户"}. {"Administration of ","管理"}. {"Administration","管理"}. {"Administrator privileges required","需要管理员权限"}. {"A friendly name for the node","该节点的友好名称"}. {"All activity","所有活动"}. {"Allow this Jabber ID to subscribe to this pubsub node?","允许该 Jabber ID 订阅该 pubsub 节点?"}. {"Allow users to change the subject","允许用户更改主题"}. {"Allow users to query other users","允许用户查询其它用户"}. {"Allow users to send invites","允许用户发送邀请"}. {"Allow users to send private messages","允许用户发送私聊消息"}. {"Allow visitors to change nickname","允许用户更改昵称"}. {"Allow visitors to send private messages to","允许访客发送私聊消息至"}. {"Allow visitors to send status text in presence updates","更新在线状态时允许用户发送状态文本"}. {"Allow visitors to send voice requests","允许访客发送声音请求"}. {"All Users","所有用户"}. {"Announcements","通知"}. {"anyone","任何人"}. {"A password is required to enter this room","进入此房间需要密码"}. {"April","四月"}. {"August","八月"}. {"Backup Management","备份管理"}. {"Backup of ","备份来源 "}. {"Backup to File at ","备份文件位于"}. {"Backup","备份"}. {"Bad format","格式错误"}. {"Birthday","出生日期"}. {"CAPTCHA web page","验证码网页"}. {"Change Password","更改密码"}. {"Change User Password","更改用户密码"}. {"Characters not allowed:","禁用字符:"}. {"Chatroom configuration modified","聊天室配置已修改"}. {"Chatroom is created","聊天室已被创建"}. {"Chatroom is destroyed","聊天室已被销毁"}. {"Chatroom is started","聊天室已被启动"}. {"Chatroom is stopped","聊天室已被停用"}. {"Chatrooms","聊天室"}. {"Choose a username and password to register with this server","请选择在此服务器上注册所需的用户名和密码"}. {"Choose modules to stop","请选择要停止的模块"}. {"Choose storage type of tables","请选择表格的存储类型"}. {"Choose whether to approve this entity's subscription.","选择是否允许该实体的订阅"}. {"City","城市"}. {"Commands","命令"}. {"Conference room does not exist","会议室不存在"}. {"Configuration of room ~s","房间 ~s 的配置 "}. {"Configuration","配置"}. {"Connected Resources:","已连接资源:"}. {"Connections parameters","连接参数"}. {"Country","国家"}. {"CPU Time:","CPU 时间:"}. {"Database Tables at ","数据库列表位于 "}. {"Database Tables Configuration at ","数据库表格配置位于"}. {"Database","数据库"}. {"December","十二月"}. {"Default users as participants","用户默认被视为参与人"}. {"Delete message of the day on all hosts","删除所有主机上的每日消息"}. {"Delete message of the day","删除每日消息"}. {"Delete Selected","删除已选内容"}. {"Delete User","删除用户"}. {"Delete","删除"}. {"Deliver event notifications","传递事件通知"}. {"Deliver payloads with event notifications","用事件通告传输有效负载"}. {"Description:","描述:"}. {"Disc only copy","仅磁盘复制"}. {"Displayed Groups:","已显示的组:"}. {"Don't tell your password to anybody, not even the administrators of the Jabber server.","不要将密码告诉任何人, 就算是 Jabber 服务器的管理员也不可以."}. {"Dump Backup to Text File at ","转储备份到文本文件于"}. {"Dump to Text File","转储到文本文件"}. {"Edit Properties","编辑属性"}. {"Either approve or decline the voice request.","接受或拒绝声音请求"}. {"ejabberd IRC module","ejabberd IRC 模块"}. {"ejabberd MUC module","ejabberd MUC 模块"}. {"ejabberd Publish-Subscribe module","ejabberd 发行-订阅模块"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 字节流模块"}. {"ejabberd vCard module","ejabberd vCard 模块"}. {"ejabberd Web Admin","ejabberd 网页管理"}. {"Elements","元素"}. {"Email","电子邮件"}. {"Enable logging","启用服务器端聊天记录"}. {"Encoding for server ~b","服务器 ~b 的编码"}. {"End User Session","结束用户会话"}. {"Enter list of {Module, [Options]}","请输入{模块, [选项]}列表"}. {"Enter nickname you want to register","请输入您想要注册的昵称"}. {"Enter path to backup file","请输入备份文件的路径"}. {"Enter path to jabberd14 spool dir","请输入 jabberd14 spool 目录的路径"}. {"Enter path to jabberd14 spool file","请输入 jabberd14 spool 文件的路径"}. {"Enter path to text file","请输入文本文件的路径"}. {"Enter the text you see","请输入您所看到的文本"}. {"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","请输入您想使用的用来连接到 IRC 服务器的用户名和编码. 按 '下一步' 获取更多待填字段. 按 '完成' 保存设置."}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","请输入您想使用的用来连接到IRC服务器的用户名, 编码, 端口和密码."}. {"Erlang Jabber Server","Erlang Jabber 服务器"}. {"Error","错误"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","例如: [{\"irc.lucky.net\", \"koi8-r\"}, 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Exclude Jabber IDs from CAPTCHA challenge","从验证码挑战中排除 Jabber ID"}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","将服务器上所有用户的数据导出到 PIEFXIS 文件 (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","将某主机的用户数据导出到 PIEFXIS 文件 (XEP-0227):"}. {"Failed to extract JID from your voice request approval","无法从你的声音请求确认信息中提取JID"}. {"Family Name","姓氏"}. {"February","二月"}. {"Fill in fields to search for any matching Jabber User","填充字段以搜索任何匹配的 Jabber 用户"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","填充表单以搜索任何匹配的 Jabber 用户(在字段末添加*来匹配子串)"}. {"Friday","星期五"}. {"From ~s","来自~s"}. {"From","从"}. {"Full Name","全名"}. {"Get Number of Online Users","获取在线用户数"}. {"Get Number of Registered Users","获取注册用户数"}. {"Get User Last Login Time","获取用户上次登陆时间"}. {"Get User Password","获取用户密码"}. {"Get User Statistics","获取用户统计"}. {"Grant voice to this person?","为此人授权声音?"}. {"Groups","组"}. {"Group ","组"}. {"has been banned","已被禁止"}. {"has been kicked because of an affiliation change","因联属关系改变而被踢出"}. {"has been kicked because of a system shutdown","因系统关机而被踢出"}. {"has been kicked because the room has been changed to members-only","因该房间改为只对会员开放而被踢出"}. {"has been kicked","已被踢出"}. {" has set the subject to: ","已将标题设置为: "}. {"Host","主机"}. {"If you don't see the CAPTCHA image here, visit the web page.","如果您在这里没有看到验证码图片, 请访问网页."}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","如果您想为 IRC 服务器指定不同的端口, 密码, 编码, 请用 '{\"irc 服务器\", \"编码\", 端口, \"密码\"}' 格式的值填充此表单. 默认情况下此服务使用\"~s\"编码, ~p 端口, 密码为空."}. {"Import Directory","导入目录"}. {"Import File","导入文件"}. {"Import user data from jabberd14 spool file:","从 jabberd14 Spool 文件导入用户数据:"}. {"Import User from File at ","导入用户的文件位于 "}. {"Import users data from a PIEFXIS file (XEP-0227):","从 PIEFXIS 文件 (XEP-0227) 导入用户数据:"}. {"Import users data from jabberd14 spool directory:","从 jabberd14 Spool 目录导入用户数据:"}. {"Import Users from Dir at ","导入用户的目录位于 "}. {"Import Users From jabberd14 Spool Files","从 jabberd14 Spool 文件导入用户"}. {"Improper message type","不恰当的消息类型"}. {"Incorrect password","密码不正确"}. {"Invalid affiliation: ~s","无效加入: ~s"}. {"Invalid role: ~s","无效角色: ~s"}. {"IP addresses","IP 地址"}. {"IP","IP"}. {"IRC channel (don't put the first #)","IRC 频道 (不要输入第一个#号)"}. {"IRC server","IRC 服务器"}. {"IRC settings","IRC 设置"}. {"IRC Transport","IRC 传输"}. {"IRC username","IRC 用户名"}. {"IRC Username","IRC 用户名"}. {"is now known as","现在称呼为"}. {"It is not allowed to send private messages of type \"groupchat\"","\"群组聊天\"类型不允许发送私聊消息"}. {"It is not allowed to send private messages to the conference","不允许向会议发送私聊消息"}. {"It is not allowed to send private messages","不可以发送私聊消息"}. {"Jabber Account Registration","Jabber 帐户注册"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Jabber ID ~s 无效"}. {"January","一月"}. {"Join IRC channel","加入 IRC 频道"}. {"joins the room","加入房间"}. {"Join the IRC channel here.","在这里加入 IRC 频道."}. {"Join the IRC channel in this Jabber ID: ~s","用此 Jabber ID: ~s 加入 IRC 频道"}. {"July","七月"}. {"June","六月"}. {"Last Activity","上次活动"}. {"Last login","上次登陆"}. {"Last month","上个月"}. {"Last year","上一年"}. {"leaves the room","离开房间"}. {"Listened Ports at ","监听的端口位于 "}. {"Listened Ports","被监听的端口"}. {"List of modules to start","要启动的模块列表"}. {"Low level update script","低级别更新脚本"}. {"Make participants list public","公开参与人列表"}. {"Make room CAPTCHA protected","保护房间验证码"}. {"Make room members-only","设置房间只接收会员"}. {"Make room moderated","设置房间只接收主持人"}. {"Make room password protected","进入此房间需要密码"}. {"Make room persistent","永久保存该房间"}. {"Make room public searchable","使房间可被公开搜索"}. {"March","三月"}. {"Maximum Number of Occupants","允许的与会人最大数"}. {"Max # of items to persist","允许持久化的最大内容条目数"}. {"Max payload size in bytes","最大有效负载字节数"}. {"May","五月"}. {"Membership is required to enter this room","进入此房间需要会员身份"}. {"Members:","会员:"}. {"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","记住你的密码, 或将其记到纸上并放于安全位置. 如果你忘记了密码, Jabber 也没有自动恢复密码的方式."}. {"Memory","内存"}. {"Message body","消息主体"}. {"Middle Name","中间名"}. {"Minimum interval between voice requests (in seconds)","声音请求的最小间隔(以秒为单位)"}. {"Moderator privileges required","需要主持人权限"}. {"moderators only","仅主持人"}. {"Modified modules","被修改模块"}. {"Modules at ","模块位于 "}. {"Modules","模块"}. {"Module","模块"}. {"Monday","星期一"}. {"Name:","姓名:"}. {"Name","姓名"}. {"Never","从未"}. {"New Password:","新密码: "}. {"Nickname Registration at ","昵称注册于 "}. {"Nickname ~s does not exist in the room","昵称 ~s 不在该房间"}. {"Nickname","昵称"}. {"No body provided for announce message","通知消息无正文内容"}. {"nobody","没有人"}. {"No Data","没有数据"}. {"Node ID","节点 ID"}. {"Node not found","没有找到节点"}. {"Nodes","节点"}. {"Node ","节点 "}. {"No limit","不限"}. {"None","无"}. {"No resource provided","无资源提供"}. {"Not Found","没有找到"}. {"Notify subscribers when items are removed from the node","当从节点删除内容条目时通知订阅人"}. {"Notify subscribers when the node configuration changes","当节点设置改变时通知订阅人"}. {"Notify subscribers when the node is deleted","当节点被删除时通知订阅人"}. {"November","十一月"}. {"Number of occupants","驻留人数"}. {"Number of online users","在线用户数"}. {"Number of registered users","注册用户数"}. {"October","十月"}. {"Offline Messages:","离线消息:"}. {"Offline Messages","离线消息"}. {"OK","确定"}. {"Old Password:","旧密码: "}. {"Online Users:","在线用户:"}. {"Online Users","在线用户"}. {"Online","在线"}. {"Only deliver notifications to available users","仅将通知发送给可发送的用户"}. {"Only moderators and participants are allowed to change the subject in this room","只有主持人和参与人可以在此房间里更改主题"}. {"Only moderators are allowed to change the subject in this room","只有主持人可以在此房间里更改主题"}. {"Only moderators can approve voice requests","仅主持人能确认声音请求"}. {"Only occupants are allowed to send messages to the conference","只有与会人可以向大会发送消息"}. {"Only occupants are allowed to send queries to the conference","只有与会人可以向大会发出查询请求"}. {"Only service administrators are allowed to send service messages","只有服务管理员可以发送服务消息"}. {"Options","选项"}. {"Organization Name","组织名称"}. {"Organization Unit","组织单位"}. {"Outgoing s2s Connections:","出站 s2s 连接:"}. {"Outgoing s2s Connections","出站 s2s 连接"}. {"Outgoing s2s Servers:","出站 s2s 服务器"}. {"Owner privileges required","需要持有人权限"}. {"Packet","数据包"}. {"Password ~b","~b 的密码"}. {"Password Verification:","密码确认:"}. {"Password Verification","确认密码"}. {"Password:","密码:"}. {"Password","密码"}. {"Path to Dir","目录的路径"}. {"Path to File","文件路径"}. {"Pending","挂起"}. {"Period: ","持续时间: "}. {"Persist items to storage","持久化内容条目"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","注意:这些选项仅将备份内置的 Mnesia 数据库. 如果您正在使用 ODBC 模块, 您还需要分别备份您的数据库."}. {"Please, wait for a while before sending new voice request","请稍后再发送新的声音请求"}. {"Pong","Pong"}. {"Port ~b","~b 的端口"}. {"Port","端口"}. {"Present real Jabber IDs to","将真实 Jabber ID 显示给"}. {"private, ","保密, "}. {"Protocol","协议"}. {"Publish-Subscribe","发行-订阅"}. {"PubSub subscriber request","PubSub 订阅人请求"}. {"Purge all items when the relevant publisher goes offline","相关发布人离线后清除所有选项"}. {"Queries to the conference members are not allowed in this room","本房间不可以查询会议成员信息"}. {"RAM and disc copy","内存与磁盘复制"}. {"RAM copy","内存(RAM)复制"}. {"Raw","原始格式"}. {"Really delete message of the day?","确实要删除每日消息吗?"}. {"Recipient is not in the conference room","接收人不在会议室"}. {"Register a Jabber account","注册 Jabber 帐户"}. {"Registered Users:","注册用户:"}. {"Registered Users","注册用户"}. {"Register","注册"}. {"Registration in mod_irc for ","mod_irc 中的注册是为 "}. {"Remote copy","远程复制"}. {"Remove All Offline Messages","移除所有离线消息"}. {"Remove User","删除用户"}. {"Remove","移除"}. {"Replaced by new connection","被新的连接替换"}. {"Resources","资源"}. {"Restart Service","重启服务"}. {"Restart","重启"}. {"Restore Backup from File at ","要恢复的备份文件位于"}. {"Restore binary backup after next ejabberd restart (requires less memory):","在下次 ejabberd 重启后恢复二进制备份(需要的内存更少):"}. {"Restore binary backup immediately:","立即恢复二进制备份:"}. {"Restore plain text backup immediately:","立即恢复普通文本备份:"}. {"Restore","恢复"}. {"Room Configuration","房间配置"}. {"Room creation is denied by service policy","创建房间被服务策略拒绝"}. {"Room description","房间描述"}. {"Room Occupants","房间人数"}. {"Room title","房间标题"}. {"Roster groups allowed to subscribe","允许订阅的花名册组"}. {"Roster of ","花名册属于 "}. {"Roster size","花名册大小"}. {"Roster","花名册"}. {"RPC Call Error","RPC 调用错误"}. {"Running Nodes","运行中的节点"}. {"~s access rule configuration","~s 访问规则配置"}. {"Saturday","星期六"}. {"Script check","脚本检查"}. {"Search Results for ","搜索结果属于关键词 "}. {"Search users in ","搜索用户于 "}. {"Send announcement to all online users on all hosts","发送通知给所有主机的在线用户"}. {"Send announcement to all online users","发送通知给所有在线用户"}. {"Send announcement to all users on all hosts","发送通知给所有主机上的所有用户"}. {"Send announcement to all users","发送通知给所有用户"}. {"September","九月"}. {"Server ~b","服务器 ~b"}. {"Server:","服务器:"}. {"Set message of the day and send to online users","设定每日消息并发送给所有在线用户"}. {"Set message of the day on all hosts and send to online users","设置所有主机上的每日消息并发送给在线用户"}. {"Shared Roster Groups","共享的花名册组群"}. {"Show Integral Table","显示完整列表"}. {"Show Ordinary Table","显示普通列表"}. {"Shut Down Service","关闭服务"}. {"~s invites you to the room ~s","~s 邀请你到 ~s 房间"}. {"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","某些 Jabber 客户端可以在你的计算机里存储密码. 请仅在你确认你的计算机安全的情况下使用该功能."}. {"Specify the access model","指定访问范例"}. {"Specify the event message type","指定事件消息类型"}. {"Specify the publisher model","指定发布人范例"}. {"~s's Offline Messages Queue","~s 的离线消息队列"}. {"Start Modules at ","要启动的模块位于 "}. {"Start Modules","启动模块"}. {"Start","开始"}. {"Statistics of ~p","~p 的统计"}. {"Statistics","统计"}. {"Stop Modules at ","要停止的模块位于 "}. {"Stop Modules","停止模块"}. {"Stopped Nodes","已经停止的节点"}. {"Stop","停止"}. {"Storage Type","存储类型"}. {"Store binary backup:","存储为二进制备份:"}. {"Store plain text backup:","存储为普通文本备份:"}. {"Subject","标题"}. {"Submitted","已提交"}. {"Submit","提交"}. {"Subscriber Address","订阅人地址"}. {"Subscription","订阅"}. {"Sunday","星期天"}. {"That nickname is already in use by another occupant","该昵称已被另一用户使用"}. {"That nickname is registered by another person","该昵称已被另一个人注册了"}. {"The CAPTCHA is valid.","验证码有效."}. {"The CAPTCHA verification has failed","验证码检查失败"}. {"The collections with which a node is affiliated","加入结点的集合"}. {"The password is too weak","密码强度太弱"}. {"the password is","密码是"}. {"The password of your Jabber account was successfully changed.","你的 Jabber 帐户密码已成功更新."}. {"There was an error changing the password: ","修改密码出错: "}. {"There was an error creating the account: ","帐户创建出错: "}. {"There was an error deleting the account: ","帐户删除失败: "}. {"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","此处不区分大小写: macbeth 与 MacBeth 和 Macbeth 是一样的."}. {"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","本页面允许在此服务器上创建 Jabber 帐户. 你的 JID (Jabber ID) 的形式如下: 用户名@服务器. 请仔细阅读说明并正确填写相应字段."}. {"This page allows to unregister a Jabber account in this Jabber server.","此页面允许在此 Jabber 服务器上注销 Jabber 帐户"}. {"This participant is kicked from the room because he sent an error message to another participant","该参与人由于给其他人发送了出错消息而被踢出了聊天室"}. {"This participant is kicked from the room because he sent an error message","该参与人由于发送了错误消息而被踢出了聊天室"}. {"This participant is kicked from the room because he sent an error presence","该用户由于发送了错误状态而被踢出了聊天室"}. {"This room is not anonymous","此房间不是匿名房间"}. {"Thursday","星期四"}. {"Time delay","时间延迟"}. {"Time","时间"}. {"Too many CAPTCHA requests","验证码请求太多"}. {"To ~s","发送给~s"}. {"To","到"}. {"Traffic rate limit is exceeded","已经超过传输率限制"}. {"Transactions Aborted:","取消的事务:"}. {"Transactions Committed:","提交的事务:"}. {"Transactions Logged:","记入日志的事务:"}. {"Transactions Restarted:","重启的事务:"}. {"Tuesday","星期二"}. {"Unable to generate a CAPTCHA","无法生成验证码"}. {"Unauthorized","未认证的"}. {"Unregister a Jabber account","注销 Jabber 帐户"}. {"Unregister","取消注册"}. {"Update message of the day (don't send)","更新每日消息(不发送)"}. {"Update message of the day on all hosts (don't send)","更新所有主机上的每日消息(不发送)"}. {"Update plan","更新计划"}. {"Update script","更新脚本"}. {"Update ","更新 "}. {"Update","更新"}. {"Uptime:","正常运行时间:"}. {"Use of STARTTLS required","要求使用 STARTTLS"}. {"User JID","用户 JID"}. {"User Management","用户管理"}. {"Username:","用户名:"}. {"Users are not allowed to register accounts so quickly","不允许用户太频繁地注册帐户"}. {"Users Last Activity","用户上次活动"}. {"Users","用户"}. {"User ","用户 "}. {"User","用户"}. {"Validate","确认"}. {"vCard User Search","vCard 用户搜索"}. {"Virtual Hosts","虚拟主机"}. {"Visitors are not allowed to change their nicknames in this room","此房间不允许用户更改昵称"}. {"Visitors are not allowed to send messages to all occupants","不允许访客给所有占有者发送消息"}. {"Voice requests are disabled in this conference","该会议的声音请求以被禁用"}. {"Voice request","声音请求"}. {"Wednesday","星期三"}. {"When to send the last published item","何时发送最新发布的内容条目"}. {"Whether to allow subscriptions","是否允许订阅"}. {"You can later change your password using a Jabber client.","你可以稍后用 Jabber 客户端修改你的密码."}. {"You have been banned from this room","您已被禁止进入该房间"}. {"You must fill in field \"Nickname\" in the form","您必须填充表单中\"昵称\"项"}. {"You need a client that supports x:data and CAPTCHA to register","您需要一个支持 x:data 和验证码的客户端进行注册"}. {"You need a client that supports x:data to register the nickname","您需要一个支持 x:data 的客户端来注册昵称"}. {"You need an x:data capable client to configure mod_irc settings","您需要一个兼容 x:data 的客户端来配置 mod_irc 设置"}. {"You need an x:data capable client to configure room","您需要一个兼容 x:data 的客户端来配置房间"}. {"You need an x:data capable client to search","您需要一个兼容 x:data 的客户端来搜索"}. {"Your active privacy list has denied the routing of this stanza.","你的活跃私聊列表拒绝了在此房间进行路由分发."}. {"Your contact offline message queue is full. The message has been discarded.","您的联系人离线消息队列已满. 消息已被丢弃"}. {"Your Jabber account was successfully created.","你的 Jabber 帐户已成功创建."}. {"Your Jabber account was successfully deleted.","你的 Jabber 帐户已成功删除."}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","您发送给 ~s 的消息已被阻止. 要解除阻止, 请访问 ~s"}. ejabberd-2.1.11/src/msgs/no.po0000664000000000000000000015276712240230175012754 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" "Last-Translator: Stian B. Barmen \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Norwegian (bokmål)\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Bruk av STARTTLS kreves" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Ingen ressurs angitt" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Erstattet av en ny tilkobling" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "Din aktive privat liste har blokkert rutingen av denne strofen." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Skriv inn teksten du ser" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "Dine meldinger til ~s blir blokkert. For å åpne igjen, besøk ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "Dersom du ikke ser CAPTCHA bilde her, besøk web siden. " #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "CAPTCHA web side" #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "Captchaen er ikke gyldig" #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Kommandoer" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Virkelig slette melding for dagen?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Tittel" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Meldingskropp" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "Ingen meldingskropp gitt for kunngjørings melding" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Kunngjøringer" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Send kunngjøring til alle brukere" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Send kunngjøring til alle brukere på alle maskiner" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Send kunngjøring alle tilkoblede brukere" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "Send kunngjøring til alle tilkoblede brukere på alle " #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Angi melding for dagen og send til tilkoblede brukere" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "Angi melding for dagen på alle maskiner og send til " #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Oppdater melding for dagen (ikke send)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Oppdater melding for dagen på alle maskiner (ikke send)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Slett melding for dagen" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Slett melding for dagen på alle maskiner" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Konfigurasjon" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Database" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Start Moduler" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Stop Moduler" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Sikkerhetskopier" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Gjenopprett" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Dump til Tekstfil" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Importer File" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Importer Katalog" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Start Tjeneste på Nytt" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Avslutt Tjeneste" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Legg til Bruker" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Slett Bruker" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Avslutt Bruker Sesjon" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Hent Brukers Passord" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Endre Brukers Passord" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Vis Brukers Siste Påloggings Tidspunkt" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Vis Bruker Statistikk" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Vis Antall Registrerte Brukere" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Vis Antall Tilkoblede Brukere" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Tilgangskontrollister" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Tilgangsregler" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Bruker Behandling" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Tilkoblede Brukere" #: mod_configure.erl:501 msgid "All Users" msgstr "Alle Brukere" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Utgående s2s Koblinger" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Kjørende Noder" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Stoppede Noder" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Moduler" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Håndtere Sikkerehetskopiering" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importer Brukere Fra jabberd14 Spoolfiler" #: mod_configure.erl:699 msgid "To ~s" msgstr "Til ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Fra ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Database Tabell Konfigurasjon på " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Velg lagringstype for tabeller" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Kun diskkopi" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "RAM og diskkopi" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "RAM kopi" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Lagres ikke lokalt" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Stopp Moduler på " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Velg hvilke moduler som skal stoppes" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Start Moduler på " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Skriv inn en liste av {Module, [Options]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Liste over moduler som skal startes" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Sikkerhetskopiere til Fil på " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Skriv inn sti til sikkerhetskopi filen" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Sti til Fil" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Gjenopprett fra Sikkerhetsopifil på " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Dump Sikkerhetskopi til Tekstfil på " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Skriv inn sti til tekstfil" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importer Bruker fra Fil på " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Skriv inn sti til jabberd14 spoolfil" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Importer Brukere fra Katalog på " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Skriv inn sti til jabberd14 spoolkatalog" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Sti til Katalog" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Tids forsinkelse" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Konfigurasjon for Tilgangskontroll lister" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Tilgangskontroll lister" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Tilgangskonfigurasjon" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Tilgangsregler" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Passord" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Passord Bekreftelse" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Antall registrerte brukere" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Antall tilkoblede brukere" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Aldri" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Tilkoblet" #: mod_configure.erl:1701 msgid "Last login" msgstr "Siste pålogging" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Kontaktliste størrelse" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "IP adresser" #: mod_configure.erl:1724 msgid "Resources" msgstr "Ressurser" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Administrasjon av " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Handling på bruker" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Redigere Egenskaper" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Fjern Bruker" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "Tilgang nektes på grunn av en tjeneste regel" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC Transport" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd IRC modul" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "Du trenger en x:data kompatibel klient for å konfigurere mod_irc instillinger" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Registrering i mod_irc for " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Skriv brukernavn, tekstkoding, porter og passord du ønsker å bruke for " "tilkobling til IRC servere" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "IRC Brukernavn" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Om du ønsker å spesifisere tekstkoding for IRC tjenere, fyller du ut en " "liste med verdier i formatet '{\"irc server\", \"encoding\", port, \"password" "\"}'. Denne tjenesten bruker \"~s\" som standard, port ~p, empty password." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Eksempel: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta." "fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Tilkoblings parametere" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Bli med i IRC kanal" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "IRC kanal (ikke skriv den første #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "IRC server" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Bli med i IRC kanalen her. " #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Bli med i IRC kanalen med denne Jabber ID: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "IRC instillinger" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Angi brukernavn og kodinger du ønsker å bruke for å koble til IRC servere. " "Trykk 'Neste' for å få flere felt for å fylle i. Trykk 'Fullfør' for å lagre " "innstillingene." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "IRC brukernavn" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Passord ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Port ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Tekstkoding for server ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Server ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "Bare tjeneste administratorer er tilatt å sende tjeneste " #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "Oppretting av rom nektes av en tjenste regel" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "Konferanserommet finnes ikke" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Samtalerom" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "Du trenger en klient som støtter x:data for å registrere kallenavnet" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Registrer Kallenavn på " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Skriv inn kallenavnet du ønsker å registrere" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Kallenavn" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Det kallenavnet er registrert av en annen person" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "Du må fylle inn feltet \"Nickname\" i skjemaet" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd MUC modul" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "Samtalerommets konfigurasjon er endret" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "kommer inn i rommet" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "forlater rommet" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "har blitt bannlyst" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "har blitt kastet ut" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "har blitt kastet ut på grunn av en tilknytnings endring" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "" "har blitt kastet ut på grunn av at rommet er endret til kun-for-medlemmer" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "har blitt kastet ut på grunn av at systemet avslutter" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "er nå kjent som" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " har satt emnet til: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Samtalerom er opprettet" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Samtalerom er fjernet" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Samtalerom er startet" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Samtalerom er stoppet" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "mandag" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "tirsdag" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "onsdag" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "torsdag" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "fredag" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "lørdag" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "søndag" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "januar" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "februar" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "mars" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "april" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "mai" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "juni" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "juli" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "august" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "september" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "oktober" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "november" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "desember" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Rom Konfigurasjon" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Samtalerom Deltakere" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Trafikkmengde grense overskredet" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Denne deltakeren er kastet ut av rommet fordi han sendte en feilmelding" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Det er ikke tillatt å sende private meldinger til " #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "Vennligst vent en stund før du sender en ny lyd forespørsel" #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "Lyd forespørsler er blokkert i denne konferansen" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "Feilet i forsøk på å hente JID fra din lyd forespørsel godkjenning" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Bare ordstyrer kan godkjenne lyd forespørsler" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Feilaktig meldingstype" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Denne deltakeren er kastet ut av rommet fordi han sendte en feilmelding til " "en annen deltaker" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "Det er ikke tillatt å sende private meldinger med typen " #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "Mottakeren er ikke i konferanserommet" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Det er ikke tillatt å sende private meldinger" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Bare deltakere får sende normale meldinger til konferansen" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Bare deltakere er tillatt å sende forespørsler til " #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "Forespørsler til konferanse medlemmene er ikke tillat i dette rommet" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "Bare redaktører og deltakere kan endre emnet i dette rommet" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Bare ordstyrer tillates å endre emnet i dette rommet" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Besøkende får ikke sende meldinger til alle deltakere" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Denne deltakeren er kastet ut av rommet fordi han sendte feil " "tilstederværelse" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Besøkende får ikke lov å endre kallenavn i dette " #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Det kallenavnet er allerede i bruk av en annen deltaker" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "Du har blitt bannlyst i dette rommet." #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "Medlemskap kreves for tilgang til samtalerommet" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Dette rommet er ikke anonymt" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "Et passord kreves for tilgang til samtalerommet" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "For mange CAPTCHA forespørsler" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Umulig å generere en CAPTCHA" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Feil passord" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "Administratorprivilegier kreves" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "Redaktørprivilegier kreves" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "Ugyldig Jabber ID ~s" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "Kallenavn ~s eksisterer ikke i dette rommet" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Ugyldig rang: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Ugyldig rolle: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "Eierprivilegier kreves" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Konfigurasjon for rom ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Romtittel" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Rom beskrivelse" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Gjør rommet permanent" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Gjør rommet offentlig søkbart" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Gjør deltakerlisten offentlig" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Passordbeskytt rommet" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Maksimum Antall Deltakere" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Ingen grense" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Presenter ekte Jabber IDer til" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "kun for redaktører" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "hvem som helst" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Gjør rommet tilgjengelig kun for medlemmer" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Gjør rommet redaktørstyrt" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Standard brukere som deltakere" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Tillat brukere å endre emne" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Tillat brukere å sende private meldinger" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "Tillat brukere å sende private meldinger til" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "ingen" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Tillat brukere å sende forespørsel til andre brukere" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Tillat brukere å sende invitasjoner" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "Tillat besøkende å sende status tekst i " #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Tillat besøkende å endre kallenavn" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "Tillat brukere å sende lyd forespørsler" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "Minimums interval mellom lyd forespørsler (i sekunder)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Gjør rommet CAPTCHA beskyttet" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Ekskluder Jabber IDer fra CAPTCHA utfordring" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Slå på logging" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "Du trenger en klient som støtter x:data for å " #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Antall deltakere" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privat, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Lyd forespørsel" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Enten godkjenn eller forby lyd forespørselen" #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "Bruker JID" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "Gi lyd til denne personen?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s inviterer deg til rommet ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "passordet er" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "Kontaktens frakoblede meldingskø er full. Meldingen har blitt kassert." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "~ss kø for Frakoblede Meldinger" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Innsendt" #: mod_offline.erl:571 msgid "Time" msgstr "Tid" #: mod_offline.erl:572 msgid "From" msgstr "Fra" #: mod_offline.erl:573 msgid "To" msgstr "Til" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Pakke" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Slett valgte" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Frakoblede Meldinger:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Fjern Alle Frakoblede Meldinger" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestreams modul" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Publish-Subscribe" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "ejabberd Publish-Subscribe modul" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "PubSub abonements forespørsel" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Velg om du vil godkjenne denne eksistensens abonement" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "Node ID" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Abonnements Adresse" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Tillat denne Jabber ID å abonnere på denne pubsub " #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Send innhold sammen med kunngjøringer" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Lever begivenhets kunngjøringer" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Informer abonnenter når node konfigurasjonen endres" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Informer abonnenter når noden slettes" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Informer abonnenter når elementer fjernes fra noden" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Vedvarende elementer til lagring" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Et vennlig navn for noden" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Høyeste # elementer som skal lagres" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Om man skal tillate abonnenter" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Spesifiser aksess modellen" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Kontaktliste grupper som tillates å abonnere" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Angi publiserings modell" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "Rydd alle elementer når den aktuelle utgiveren logger av" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Spesifiser hendelsesbeskjed type" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Største innholdsstørrelse i byte" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Når skal siste publiserte artikkel sendes" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Send kunngjøringer bare til tilgjengelige brukere" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "Samlingene som en node er assosiert med" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "CAPTCHA godkjenningen har feilet" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "Du trenger en klient som støtter x:data og CAPTCHA for registrering " #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "Velg et brukernavn og passord for å registrere på " #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Bruker" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "Passordet er for svakt" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Brukere får ikke lov til registrere kontoer så fort" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Ingen" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Abonnement" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Ventende" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Grupper" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Bekrefte gyldighet" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Fjern" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Kontaktliste for " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Feil format" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Legg til Jabber ID" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Kontaktliste" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Delte Kontaktgrupper" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Legg til ny" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Navn:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Beskrivelse:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Medlemmer:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Viste grupper:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Gruppe " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Send" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Fødselsdag" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "By" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Land" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "Epost" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Etternavn" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Fyll inn skjemaet for å søke etter Jabber bruker (Legg til * på slutten av " "feltet for å treffe alle som starter slik)" #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Fullstendig Navn" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Mellomnavn" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Navn" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Organisasjonsnavn" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Organisasjonsenhet" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Søk etter brukere i " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "Du tregner en klient som støtter x:data for å kunne " #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "vCard Bruker Søk" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd vCard modul" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Søke Resultater for " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Fyll inn felt for å søke etter Jabber brukere" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Uautorisert" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd Web Admin" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Administrasjon" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Rå" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "tilgangsregel konfigurasjon for ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Virtuella Maskiner" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Brukere" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Brukers Siste Aktivitet" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Periode: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Siste måned" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Siste året" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "All aktivitet" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Vis Ordinær Tabell" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Vis Integral Tabell" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Statistikk" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Finnes Ikke" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Noden finnes ikke" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Maskin" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Registrerte Brukere" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Frakoblede Meldinger" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Siste Aktivitet" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Registrerte Brukere:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Tilkoblede Brukere:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Utgående s2s Koblinger" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Utgående s2s Tjenere" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Endre Passord" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Bruker " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Tilkoblede Ressurser:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Passord:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Ingen Data" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Noder" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Node " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Lyttende Porter" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Oppdatere" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Starte på nytt" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Stoppe" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "RPC Kall Feil" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Database Tabeller på " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Lagringstype" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Elementer" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Minne" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Feil" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Sikkerhetskopi av " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Merk at disse valgene vil bare sikkerhetskopiere den innebygde Mnesia " "databasen. Dersom du bruker ODBC modulen må du også ta backup av din SQL " "database." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Lagre binær sikkerhetskopi:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Gjenopprette binær backup umiddelbart:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Gjenopprette binær backup etter neste ejabberd omstart (krever mindre minne):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Lagre rentekst sikkerhetskopi:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Gjenopprette rentekst sikkerhetskopi umiddelbart:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Importer brukeres data fra en PIEFXIS fil (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "Eksporter data om alle brukere i en server til PIEFXIS filer" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "Eksporter data om alle brukere i en host til PIEFXIS filer (XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importer bruker data fra jabberd14 spoolfiler:" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importer brukeres data fra jabberd14 spoolfil katalog:" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Lyttende Porter på " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Moduler på " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Statistikk for ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Oppetid:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "CPU Tid:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Sendte Transaksjoner:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Avbrutte Transasksjoner:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Omstartede Transasksjoner:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Loggede Transasksjoner:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Oppdater " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Oppdaterings plan" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Endrede moduler" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Oppdaterings skript" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Lavnivå oppdaterings skript" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Skript sjekk" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Port" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protokoll" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Modul" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Alternativer" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Slett" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Start" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Din Jabber konto ble opprettet" #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "En feil skjedde under oppretting av kontoen:" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Dni Jabber konto er blitt sltettet." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "En feil skjedde under sletting av kontoen: " #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Passordet for din Jabber konto ble endret." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "En feil skjedde under endring av passordet:" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Jabber Konto Registrering" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Registrer en Jabber konto" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Avregistrer en Jabber konto" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Denne siden lar deg lage en Jabber konto på denne Jabber serveren. Din JID " "(Jabber ID) vil være i formatet: brukernavn@server. Vennligst les " "instruksjonene nøye slik at du fyller ut skjemaet riktig." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Brukernavn:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Denne er ufølsom for små og store bokstaver: macbeth er det samme som " "MacBeth og Macbeth. " #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Ikke godtatte tegn:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Server:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "Ikke fortell passordet til noen, ikke en gang til administratoren av Jabber " "serveren." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "Du kan når som helst endre passordet via en Jabber klient." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Noen Jabber klienter kan lagre passordet på datamaskinen. Bruk bare den " "funksjonen dersom du er sikker på at maskinen er trygg." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Husk passordet, eller skriv det ned på et papir lagret på et trygt sted. I " "Jabber er det ingen automatisert måte å gjenskape passordet om du glemmer " "det. " #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Passord Bekreftelse:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Registrer" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Gammelt Passord:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Nytt Passord:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" "Denne siden lar deg avregistrere en Jabber konto på denne Jabber serveren." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Avregistrer" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "Captchaen er ikke gyldig" ejabberd-2.1.11/src/msgs/sv.msg0000664000000000000000000005106312240230175013123 0ustar {"Access Configuration","Åtkomstkonfiguration"}. {"Access Control List Configuration","Konfiguera ACL"}. {"Access control lists","ACL"}. {"Access Control Lists","ACL"}. {"Access denied by service policy","Åtkomst nekad enligt lokal policy"}. {"Access rules","Åtkomstregler"}. {"Access Rules","Åtkomstregler"}. {"Action on user","Handling mot användare"}. {"Add Jabber ID","Lägg till Jabber ID"}. {"Add New","Lägg till ny"}. {"Add User","Lägg till användare"}. {"Administration","Administration"}. {"Administration of ","Administration av "}. {"Administrator privileges required","Administrationsprivilegier krävs"}. {"A friendly name for the node","Ett vänligt namn for noden"}. {"All activity","All aktivitet"}. {"Allow this Jabber ID to subscribe to this pubsub node?","Tillåt denna Jabber ID att prenumerera på denna pubsub node"}. {"Allow users to change the subject","Tillåt användare att byta ämne"}. {"Allow users to query other users","Tillåt användare att söka efter andra användare"}. {"Allow users to send invites","Tillåt användare att skicka inbjudningar"}. {"Allow users to send private messages","Tillåt användare att skicka privata meddelanden"}. {"Allow visitors to change nickname","Tillåt gäster att kunna ändra smeknamn"}. {"Allow visitors to send status text in presence updates","Tillåt gäster att skicka statustext som uppdatering"}. {"All Users","Alla användare"}. {"Announcements","Meddelanden"}. {"anyone","Vemsomhelst"}. {"April","April"}. {"August","Augusti"}. {"Backup Management","Hantera säkerhetskopior"}. {"Backup of ","Backup av"}. {"Backup","Säkerhetskopiera"}. {"Backup to File at ","Säkerhetskopiera till fil på "}. {"Bad format","Dåligt format"}. {"Birthday","Födelsedag"}. {"Change Password","Ändra lösenord"}. {"Change User Password","Andra användarlösenord"}. {"Chatroom configuration modified","Chattrum konfiguration modifierad"}. {"Chatrooms","Chattrum"}. {"Choose a username and password to register with this server","Välj ett användarnamn och lösenord för att registrera mot denna server"}. {"Choose modules to stop","Välj vilka moduler som skall stoppas"}. {"Choose storage type of tables","Välj lagringstyp för tabeller"}. {"Choose whether to approve this entity's subscription.","Välj om du vill godkänna hela denna prenumertion."}. {"City","Stad"}. {"Commands","Kommandon"}. {"Conference room does not exist","Rummet finns inte"}. {"Configuration","Konfiguration"}. {"Configuration of room ~s","Konfiguration för ~s"}. {"Connected Resources:","Anslutna resurser:"}. {"Connections parameters","Uppkopplingsparametrar"}. {"Country","Land"}. {"CPU Time:","CPU tid"}. {"Database","Databas"}. {"Database Tables at ","Databas tabell pa"}. {"Database Tables Configuration at ","Databastabellers konfiguration"}. {"December","December"}. {"Default users as participants","Gör om användare till deltagare"}. {"Delete message of the day on all hosts","Ta bort dagens meddelande på alla värdar"}. {"Delete message of the day","Ta bort dagens meddelande"}. {"Delete Selected","Tabort valda"}. {"Delete","Ta bort"}. {"Delete User","Ta bort användare"}. {"Deliver event notifications","Skicka eventnotifikation"}. {"Deliver payloads with event notifications","Skicka innehåll tillsammans med notifikationer"}. {"Description:","Beskrivning:"}. {"Disc only copy","Endast diskkopia"}. {"Displayed Groups:","Visade grupper:"}. {"Dump Backup to Text File at ","Dumpa säkerhetskopia till textfil på "}. {"Dump to Text File","Dumpa till textfil"}. {"Edit Properties","Redigera egenskaper"}. {"ejabberd IRC module","ejabberd IRC-modul"}. {"ejabberd MUC module","ejabberd MUC modul"}. {"ejabberd Publish-Subscribe module","ejabberd publikprenumerations modul"}. {"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestrem modul"}. {"ejabberd vCard module","ejabberd vCard-modul"}. {"ejabberd Web Admin","ejabberd Web Admin"}. {"Elements","Elements"}. {"Email","Email"}. {"Enable logging","Möjliggör login"}. {"Encoding for server ~b","Encoding för server ~b"}. {"End User Session","Avsluta användarsession"}. {"Enter list of {Module, [Options]}","Skriv in en lista av {Module, [Options]}"}. {"Enter nickname you want to register","Skriv in smeknamnet du vill registrera"}. {"Enter path to backup file","Skriv in sökväg till fil för säkerhetskopia"}. {"Enter path to jabberd14 spool dir","Skriv in sökväg till spoolkatalog från jabberd14"}. {"Enter path to jabberd14 spool file","Skriv in sökväg till spoolfil från jabberd14"}. {"Enter path to text file","Skriv in sökväg till textfil"}. {"Enter the text you see","Skriv in sökväg till textfil"}. {"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Skriv in användarnamn och textkodning du vill använda för att ansluta till IRC-servrar"}. {"Erlang Jabber Server","Erlang Jabber Server"}. {"Error","Fel"}. {"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Exempel: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}. {"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exportera data av alla användare i servern till en PIEFXIS fil (XEP-0227):"}. {"Export data of users in a host to PIEFXIS files (XEP-0227):","Exportera data av användare i en host till PIEFXIS fil (XEP-0227):"}. {"Family Name","Efternamn"}. {"February","Februari"}. {"Fill in fields to search for any matching Jabber User","Fyll i fält för att söka efter jabberanvändare"}. {"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Fyll i formuläret för att söka efter en användare (lägg till * på slutet av fältet för att hitta alla som börjar så)"}. {"Friday","Fredag"}. {"From","Från"}. {"From ~s","Från ~s"}. {"Full Name","Fullständigt namn"}. {"Get Number of Online Users","Hämta antal inloggade användare"}. {"Get Number of Registered Users","Hämta antal registrerade användare"}. {"Get User Last Login Time","Hämta användarens senast inloggade tid"}. {"Get User Password","Hämta användarlösenord"}. {"Get User Statistics","Hämta användarstatistik"}. {"Group ","Grupp "}. {"Groups","Grupper"}. {"has been banned","har blivit bannad"}. {"has been kicked because of an affiliation change","har blivit kickad p.g.a en ändring av tillhörighet"}. {"has been kicked because of a system shutdown","har blivit kickad p.g.a en systemnerstängning"}. {"has been kicked because the room has been changed to members-only","har blivit kickad p.g.a att rummet har ändrats till endast användare"}. {"has been kicked","har blivit kickad"}. {" has set the subject to: "," har satt ämnet till: "}. {"Host","Server"}. {"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Om du vill specifiera textkodning för IRC-servrar, fyll i listan med värden i formatet '{\"irc server\", \"encoding\", port, \"password\"}'. Som standard används \"~s\", port ~p, no password."}. {"Import Directory","Importera katalog"}. {"Import File","Importera fil"}. {"Import user data from jabberd14 spool file:","Importera användare från jabberd14 Spool filer"}. {"Import User from File at ","Importera användare från fil på "}. {"Import users data from a PIEFXIS file (XEP-0227):","Importera användardata från en PIEFXIS fil (XEP-0227):"}. {"Import users data from jabberd14 spool directory:","Importera användare från jabberd14 Spool directory:"}. {"Import Users from Dir at ","Importera användare från katalog på "}. {"Import Users From jabberd14 Spool Files","Importera användare från jabberd14 Spool filer"}. {"Improper message type","Felaktig medelandetyp"}. {"Incorrect password","Fel lösenord"}. {"Invalid affiliation: ~s","Ogiltlig rang: ~s"}. {"Invalid role: ~s","Ogiltlig roll: ~s"}. {"IP addresses","IP adresser"}. {"IP","IP"}. {"IRC channel (don't put the first #)","IRC kanal (skriv inte första #)"}. {"IRC server","IRC-användarnamn"}. {"IRC settings","IRC Inställningar"}. {"IRC Transport","IRC transport"}. {"IRC username","IRC-användarnamn"}. {"IRC Username","IRC-användarnamn"}. {"is now known as","är känd som"}. {"It is not allowed to send private messages","Det ar inte tillåtet att skicka privata meddelanden"}. {"It is not allowed to send private messages of type \"groupchat\"","Det är inte tillåtet att skicka privata medelanden med typen \"groupchat\""}. {"It is not allowed to send private messages to the conference","Det är inte tillåtet att skicka privata medelanden till den här konferensen"}. {"Jabber ID","Jabber ID"}. {"Jabber ID ~s is invalid","Otillåtet Jabber ID ~s"}. {"January","Januari"}. {"Join IRC channel","Lägg till IRC kanal"}. {"joins the room","joinar rummet"}. {"Join the IRC channel here.","Lägg till IRC kanal här."}. {"Join the IRC channel in this Jabber ID: ~s","Lägg till IRC kanal till detta Jabber ID: ~s"}. {"July","Juli"}. {"June","Juni"}. {"Last Activity","Senast aktivitet"}. {"Last login","Senaste login"}. {"Last month","Senaste månaden"}. {"Last year","Senaste året"}. {"leaves the room","lämnar rummet"}. {"Listened Ports at ","Lyssnande portar på "}. {"Listened Ports","Lyssnarport"}. {"List of modules to start","Lista av moduler som skall startas"}. {"Low level update script","Uppdaterade laglevel skript"}. {"Make participants list public","Gör deltagarlistan publik"}. {"Make room members-only","Gör om rummet till endast medlemmar"}. {"Make room moderated","Gör rummet modererat"}. {"Make room password protected","Gör losenorden i rummet publika"}. {"Make room persistent","Gör rummet permanent"}. {"Make room public searchable","Gör rummet publikt sökbart"}. {"March","Mars"}. {"Maximum Number of Occupants","Maximalt antal av användare"}. {"Max # of items to persist","Högsta antal dataposter som sparas"}. {"Max payload size in bytes","Högsta innehållsstorlek i bytes"}. {"May","Maj"}. {"Membership is required to enter this room","Du måste vara medlem för att komma in i det här rummet"}. {"Members:","Medlemmar:"}. {"Memory","Minne"}. {"Message body","Meddelande kropp"}. {"Middle Name","Mellannamn"}. {"Moderator privileges required","Moderatorprivilegier krävs"}. {"moderators only","endast moderatorer"}. {"Modified modules","Uppdaterade moduler"}. {"Module","Modul"}. {"Modules at ","Moduler på"}. {"Modules","Moduler"}. {"Monday","Måndag"}. {"Name:","Namn:"}. {"Name","Namn"}. {"Never","Aldrig"}. {"Nickname Registration at ","Registrera smeknamn på "}. {"Nickname ~s does not exist in the room","Smeknamnet ~s existerar inte i det här rummet"}. {"Nickname","Smeknamn"}. {"No body provided for announce message","Ingen kropp behövs för dessa meddelanden"}. {"No Data","Ingen data"}. {"Node ID","Node ID"}. {"Node ","Nod "}. {"Node not found","Noden finns inte"}. {"Nodes","Noder"}. {"No limit","Ingen gräns"}. {"None","Inga"}. {"No resource provided","Ingen resurs angiven"}. {"Not Found","Noden finns inte"}. {"Notify subscribers when items are removed from the node","Meddela prenumeranter när dataposter tas bort från noden"}. {"Notify subscribers when the node configuration changes","Meddela prenumeranter när nodens konfiguration ändras"}. {"Notify subscribers when the node is deleted","Meddela prenumeranter när noden tas bort"}. {"November","November"}. {"Number of occupants","Antal besökare"}. {"Number of online users","Antal inloggade användare"}. {"Number of registered users","Antal registrerade användare"}. {"October","Oktober"}. {"Offline Messages:","Offline meddelanden:"}. {"Offline Messages","Offline meddelanden"}. {"OK","OK"}. {"Online","Ansluten"}. {"Online Users","Anslutna användare"}. {"Online Users:","Inloggade användare"}. {"Only deliver notifications to available users","Skicka notifikationer bara till uppkopplade användare"}. {"Only moderators and participants are allowed to change the subject in this room","Endast moderatorer och deltagare har tillåtelse att ändra ämnet i det här rummet"}. {"Only occupants are allowed to send messages to the conference","Utomstående får inte skicka medelanden till den här konferensen"}. {"Only occupants are allowed to send queries to the conference","Utomstående får inte skicka iq-queries till den här konferensen"}. {"Only service administrators are allowed to send service messages","Endast administratörer får skicka tjänstmeddelanden"}. {"Options","Parametrar"}. {"Organization Name","Organisationsnamn"}. {"Organization Unit","Organisationsenhet"}. {"Outgoing s2s Connections","Utgaende s2s anslutning"}. {"Outgoing s2s Connections:","Utgående s2s anslutning"}. {"Outgoing s2s Servers:","Utgående s2s server"}. {"Owner privileges required","Ägarprivilegier krävs"}. {"Packet","Paket"}. {"Password ~b","Lösenord ~b"}. {"Password:","Lösenord:"}. {"Password","Lösenord"}. {"Password Verification","Lösenordsverifikation"}. {"Path to Dir","Sökväg till katalog"}. {"Path to File","Sökväg till fil"}. {"Pending","Ännu inte godkända"}. {"Period: ","Period: "}. {"Persist items to storage","Spara dataposter permanent"}. {"Ping","Ping"}. {"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Kom ihåg att dessa inställningar endast tar backup pa builtin Mnesias databas. Om du använder ODBC modul så måste du ta backup på SQLs databas enskilt"}. {"Pong","Pong"}. {"Port ~b","Port ~b"}. {"Port","Port"}. {"Present real Jabber IDs to","Nuvarande äkta Jabber IDs till"}. {"private, ","privat, "}. {"Protocol","Protocol"}. {"Publish-Subscribe","Publikprenumeration"}. {"PubSub subscriber request","Pubsub prenumerationsforfrågan"}. {"Queries to the conference members are not allowed in this room","Det är förbjudet att skicka iq-queries till konferensdeltagare"}. {"RAM and disc copy","RAM- och diskkopia"}. {"RAM copy","RAM-kopia"}. {"Raw","Ra"}. {"Really delete message of the day?","Verkligen ta bort dagens meddelanden?"}. {"Recipient is not in the conference room","Mottagaren finns inte i rummet"}. {"Registered Users:","Registrerade användare"}. {"Registered Users","Registrerade användare"}. {"Registration in mod_irc for ","mod_irc-registrering för "}. {"Remote copy","Sparas inte lokalt"}. {"Remove","Ta bort"}. {"Remove User","Ta bort användare"}. {"Replaced by new connection","Ersatt av ny anslutning"}. {"Resources","Resurser"}. {"Restart","Omstart"}. {"Restart Service","Starta om servicen"}. {"Restore","Återställ"}. {"Restore Backup from File at ","Återställ säkerhetskopia från fil på "}. {"Restore binary backup after next ejabberd restart (requires less memory):","återställ den binära backupen efter nästa ejabberd omstart"}. {"Restore binary backup immediately:","återställ den binära backupen omedelbart"}. {"Restore plain text backup immediately:","återställ textbackup omedelbart"}. {"Room Configuration","Rumkonfiguration"}. {"Room creation is denied by service policy","Skapandet av rum är förbjudet enligt lokal policy"}. {"Room Occupants","Antal besökare"}. {"Room title","Rumstitel"}. {"Roster groups allowed to subscribe","Rostergrupper tillåts att prenumerera"}. {"Roster","Kontaktlista"}. {"Roster of ","Kontaktlista för "}. {"Roster size","Roster storlek"}. {"RPC Call Error","RPC Uppringningserror"}. {"Running Nodes","Körande noder"}. {"~s access rule configuration","Åtkomstregelkonfiguration för ~s"}. {"Saturday","Lördag"}. {"Script check","Skript kollat"}. {"Search Results for ","Sökresultat för"}. {"Search users in ","Sök efter användare på "}. {"Send announcement to all online users on all hosts","Sänd meddelanden till alla inloggade användare på alla värdar"}. {"Send announcement to all online users","Sänd meddelanden till alla inloggade användare"}. {"Send announcement to all users on all hosts","Sänd meddelanden till alla användare på alla värdar"}. {"Send announcement to all users","Sänd meddelanden till alla användare"}. {"September","September"}. {"Server ~b","Server ~b"}. {"Set message of the day and send to online users","Sätt dagens status meddelande och skicka till alla användare"}. {"Set message of the day on all hosts and send to online users","Sätt dagens status meddelande pa alla värdar och skicka till alla användare"}. {"Shared Roster Groups","Delade Rostergrupper"}. {"Show Integral Table","Visa kumulativ tabell"}. {"Show Ordinary Table","Visa normal tabell"}. {"Shut Down Service","Stäng ner servicen"}. {"~s invites you to the room ~s","~s bjöd in dig till rummet ~s"}. {"Specify the access model","Specificera accessmodellen"}. {"Specify the publisher model","Ange publiceringsmodell"}. {"~s's Offline Messages Queue","~s's offline meddelandekö"}. {"Start Modules at ","Starta moduler på "}. {"Start Modules","Starta moduler"}. {"Start","Starta"}. {"Statistics of ~p","Statistik på ~p"}. {"Statistics","Statistik"}. {"Stop Modules at ","Stoppa moduler på "}. {"Stop Modules","Stanna moduler"}. {"Stopped Nodes","Stannade noder"}. {"Stop","Stoppa"}. {"Storage Type","Lagringstyp"}. {"Store binary backup:","Lagra den binära backupen"}. {"Store plain text backup:","Lagra textbackup"}. {"Subject","Ämne"}. {"Submit","Skicka"}. {"Submitted","Skicka in"}. {"Subscriber Address","Prenumerationsadress"}. {"Subscription","Prenumeration"}. {"Sunday","Söndag"}. {"That nickname is registered by another person","Smeknamnet är reserverat"}. {"The CAPTCHA is valid.","Din CAPTCHA är godkänd."}. {"the password is","Lösenordet är"}. {"This participant is kicked from the room because he sent an error message","Deltagaren har blivit kickad fran rummet p.g.a att han skickade ett errormeddelande"}. {"This participant is kicked from the room because he sent an error message to another participant","Deltagaren har blivit kickad från rummet p.g.a att han skickade ett errormeddelande till en annan deltagare"}. {"This participant is kicked from the room because he sent an error presence","Denna deltagaren är kickad från rummet p.g.a att han skickade en errorstatus"}. {"This room is not anonymous","Detta rum är inte anonymt"}. {"Thursday","Torsdag"}. {"Time delay","Tidsförsening"}. {"Time","Tid"}. {"To ~s","Till ~s"}. {"To","Till"}. {"Traffic rate limit is exceeded","Trafikgränsen har överstigits"}. {"Transactions Aborted:","Transaktioner borttagna"}. {"Transactions Committed:","Transaktioner kommittade"}. {"Transactions Logged:","Transaktioner loggade "}. {"Transactions Restarted:","Transaktioner omstartade"}. {"Tuesday","Tisdag"}. {"Unauthorized","Ej auktoriserad"}. {"Update message of the day (don't send)","Uppdatera dagens status meddelande (skicka inte)"}. {"Update message of the day on all hosts (don't send)","Uppdatera dagens status meddelande på alla värdar (skicka inte)"}. {"Update plan","Uppdateringsplan"}. {"Update script","Uppdatera skript"}. {"Update ","Uppdatera"}. {"Update","Uppdatera"}. {"Uptime:","Tid upp"}. {"Use of STARTTLS required","Du måste använda STARTTLS"}. {"User ","Användare "}. {"User","Användarnamn"}. {"User Management","Användarmanagement"}. {"Users","Användare"}. {"Users are not allowed to register accounts so quickly","Det är inte tillåtet för användare att skapa konton så fort"}. {"Users Last Activity","Användarens senaste aktivitet"}. {"Validate","Validera"}. {"vCard User Search","vCard användare sök"}. {"Virtual Hosts","Virtuella servrar"}. {"Visitors are not allowed to change their nicknames in this room","Det är inte tillåtet for gäster att ändra sina smeknamn i detta rummet"}. {"Visitors are not allowed to send messages to all occupants","Besökare får inte skicka medelande till alla"}. {"Wednesday","Onsdag"}. {"When to send the last published item","När att skicka senast publicerade ämne"}. {"Whether to allow subscriptions","Tillåta prenumerationer?"}. {"You have been banned from this room","Du har blivit bannlyst från det här rummet"}. {"You must fill in field \"Nickname\" in the form","Du måste fylla i fält \"smeknamn\" i formen"}. {"You need an x:data capable client to configure mod_irc settings","Du behöer en klient som stöjer x:data för att konfigurera mod_irc"}. {"You need an x:data capable client to configure room","Du behöver en klient som stödjer x:data för att konfiguera detta rum"}. {"You need an x:data capable client to search","Du behöver en klient som stödjer x:data, för att kunna söka"}. {"Your contact offline message queue is full. The message has been discarded.","Din kontaktkö for offlinekontakter ar full"}. {"Your messages to ~s are being blocked. To unblock them, visit ~s","Dina meddelanden till ~s är blockerade. För att avblockera dem, gå till ~s"}. ejabberd-2.1.11/src/msgs/nl.po0000664000000000000000000015561012240230175012737 0ustar msgid "" msgstr "" "Project-Id-Version: 2.1.0-alpha\n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" "Last-Translator: Andreas van Cranenburgh \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Language: Dutch (nederlands)\n" "X-Additional-Translator: Sander Devrieze\n" #: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 msgid "Use of STARTTLS required" msgstr "Gebruik van STARTTLS is vereist" #: ejabberd_c2s.erl:503 msgid "No resource provided" msgstr "Geen bron opgegeven" #: ejabberd_c2s.erl:1197 msgid "Replaced by new connection" msgstr "Vervangen door een nieuwe verbinding" #: ejabberd_c2s.erl:1885 msgid "Your active privacy list has denied the routing of this stanza." msgstr "Uw actieve privacy-lijst verbied het routeren van dit stanza." #: ejabberd_captcha.erl:96 ejabberd_captcha.erl:152 ejabberd_captcha.erl:178 msgid "Enter the text you see" msgstr "Voer de getoonde tekst in" #: ejabberd_captcha.erl:101 msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" msgstr "" "Uw berichten aan ~s worden geblokkeerd. Om ze te deblokkeren, ga naar ~s" #: ejabberd_captcha.erl:134 msgid "If you don't see the CAPTCHA image here, visit the web page." msgstr "Als U het CAPTCHA-plaatje niet ziet, bezoek dan de webpagina." #: ejabberd_captcha.erl:146 msgid "CAPTCHA web page" msgstr "CAPTCHA webpagina." #: ejabberd_captcha.erl:307 msgid "The CAPTCHA is valid." msgstr "De geautomatiseerde Turing-test is geslaagd." #: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 msgid "Commands" msgstr "Commando's" #: mod_adhoc.erl:149 mod_adhoc.erl:243 msgid "Ping" msgstr "Ping" #: mod_adhoc.erl:260 msgid "Pong" msgstr "Pong" #: mod_announce.erl:507 mod_announce_odbc.erl:499 msgid "Really delete message of the day?" msgstr "Wilt u het bericht van de dag verwijderen?" #: mod_announce.erl:515 mod_announce_odbc.erl:507 mod_configure.erl:1083 #: mod_configure.erl:1128 msgid "Subject" msgstr "Onderwerp" #: mod_announce.erl:520 mod_announce_odbc.erl:512 mod_configure.erl:1088 #: mod_configure.erl:1133 msgid "Message body" msgstr "Bericht" #: mod_announce.erl:600 mod_announce_odbc.erl:592 msgid "No body provided for announce message" msgstr "De mededeling bevat geen bericht" #: mod_announce.erl:635 mod_announce_odbc.erl:627 msgid "Announcements" msgstr "Mededelingen" #: mod_announce.erl:637 mod_announce_odbc.erl:629 msgid "Send announcement to all users" msgstr "Mededeling verzenden naar alle gebruikers" #: mod_announce.erl:639 mod_announce_odbc.erl:631 msgid "Send announcement to all users on all hosts" msgstr "Stuur aankondiging aan alle gebruikers op alle hosts" #: mod_announce.erl:641 mod_announce_odbc.erl:633 msgid "Send announcement to all online users" msgstr "Mededeling verzenden naar alle online gebruikers" #: mod_announce.erl:643 mod_announce_odbc.erl:635 mod_configure.erl:1078 #: mod_configure.erl:1123 msgid "Send announcement to all online users on all hosts" msgstr "" "Mededeling verzenden naar alle online gebruikers op alle virtuele hosts" #: mod_announce.erl:645 mod_announce_odbc.erl:637 msgid "Set message of the day and send to online users" msgstr "Bericht van de dag instellen en verzenden naar online gebruikers" #: mod_announce.erl:647 mod_announce_odbc.erl:639 msgid "Set message of the day on all hosts and send to online users" msgstr "" "Stel bericht-van-de-dag in op alle hosts en stuur naar aanwezige gebruikers" #: mod_announce.erl:649 mod_announce_odbc.erl:641 msgid "Update message of the day (don't send)" msgstr "Bericht van de dag bijwerken (niet verzenden)" #: mod_announce.erl:651 mod_announce_odbc.erl:643 msgid "Update message of the day on all hosts (don't send)" msgstr "Verander bericht-van-de-dag op alle hosts (niet versturen)" #: mod_announce.erl:653 mod_announce_odbc.erl:645 msgid "Delete message of the day" msgstr "Bericht van de dag verwijderen" #: mod_announce.erl:655 mod_announce_odbc.erl:647 msgid "Delete message of the day on all hosts" msgstr "Verwijder bericht-van-de-dag op alle hosts" #: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 #: mod_configure.erl:498 msgid "Configuration" msgstr "Instellingen" #: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1936 msgid "Database" msgstr "Database" #: mod_configure.erl:127 mod_configure.erl:595 msgid "Start Modules" msgstr "Modules starten" #: mod_configure.erl:129 mod_configure.erl:596 msgid "Stop Modules" msgstr "Modules stoppen" #: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1937 msgid "Backup" msgstr "Backup" #: mod_configure.erl:133 mod_configure.erl:605 msgid "Restore" msgstr "Binaire backup direct herstellen" #: mod_configure.erl:135 mod_configure.erl:606 msgid "Dump to Text File" msgstr "Backup naar een tekstbestand schrijven" #: mod_configure.erl:137 mod_configure.erl:615 msgid "Import File" msgstr "Bestand importeren" #: mod_configure.erl:139 mod_configure.erl:616 msgid "Import Directory" msgstr "Directory importeren" #: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 msgid "Restart Service" msgstr "Herstart Service" #: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 msgid "Shut Down Service" msgstr "Stop Service" #: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 #: web/ejabberd_web_admin.erl:1527 msgid "Add User" msgstr "Gebruiker toevoegen" #: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 msgid "Delete User" msgstr "Verwijder Gebruiker" #: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 msgid "End User Session" msgstr "Verwijder Gebruikers-sessie" #: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 #: mod_configure.erl:1255 msgid "Get User Password" msgstr "Gebruikerswachtwoord Opvragen" #: mod_configure.erl:153 mod_configure.erl:522 msgid "Change User Password" msgstr "Verander Gebruikerswachtwoord" #: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 msgid "Get User Last Login Time" msgstr "Tijd van Laatste Aanmelding Opvragen" #: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 msgid "Get User Statistics" msgstr "Gebruikers-statistieken Opvragen" #: mod_configure.erl:159 mod_configure.erl:525 msgid "Get Number of Registered Users" msgstr "Aantal Geregistreerde Gebruikers Opvragen" #: mod_configure.erl:161 mod_configure.erl:526 msgid "Get Number of Online Users" msgstr "Aantal Aanwezige Gebruikers Opvragen" #: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:831 #: web/ejabberd_web_admin.erl:872 msgid "Access Control Lists" msgstr "Access control lists" #: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:940 #: web/ejabberd_web_admin.erl:976 msgid "Access Rules" msgstr "Access rules" #: mod_configure.erl:297 mod_configure.erl:499 msgid "User Management" msgstr "Gebruikersbeheer" #: mod_configure.erl:500 web/ejabberd_web_admin.erl:1058 #: web/ejabberd_web_admin.erl:1462 msgid "Online Users" msgstr "Online gebruikers" #: mod_configure.erl:501 msgid "All Users" msgstr "Alle gebruikers" #: mod_configure.erl:502 msgid "Outgoing s2s Connections" msgstr "Uitgaande s2s-verbindingen" #: mod_configure.erl:503 web/ejabberd_web_admin.erl:1907 msgid "Running Nodes" msgstr "Draaiende nodes" #: mod_configure.erl:504 web/ejabberd_web_admin.erl:1909 msgid "Stopped Nodes" msgstr "Gestopte nodes" #: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1953 msgid "Modules" msgstr "Modules" #: mod_configure.erl:578 msgid "Backup Management" msgstr "Backup" #: mod_configure.erl:579 msgid "Import Users From jabberd14 Spool Files" msgstr "Importeer gebruikers via spool-bestanden van jabberd14" #: mod_configure.erl:699 msgid "To ~s" msgstr "Naar ~s" #: mod_configure.erl:717 msgid "From ~s" msgstr "Van ~s" #: mod_configure.erl:913 msgid "Database Tables Configuration at " msgstr "Instellingen van databasetabellen op " #: mod_configure.erl:918 msgid "Choose storage type of tables" msgstr "Opslagmethode voor tabellen kiezen" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Disc only copy" msgstr "Harde schijf" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM and disc copy" msgstr "RAM en harde schijf" #: mod_configure.erl:926 mod_configure.erl:928 msgid "RAM copy" msgstr "RAM" #: mod_configure.erl:926 mod_configure.erl:928 msgid "Remote copy" msgstr "Op andere nodes in de cluster" #: mod_configure.erl:950 msgid "Stop Modules at " msgstr "Modules stoppen op " #: mod_configure.erl:954 msgid "Choose modules to stop" msgstr "Selecteer de modules die u wilt stoppen" #: mod_configure.erl:969 msgid "Start Modules at " msgstr "Modules starten op " #: mod_configure.erl:973 msgid "Enter list of {Module, [Options]}" msgstr "Voer lijst met op te starten modules als volgt in: {Module, [Opties]}" #: mod_configure.erl:974 msgid "List of modules to start" msgstr "Lijst met op te starten modules" #: mod_configure.erl:983 msgid "Backup to File at " msgstr "Binaire backup maken op " #: mod_configure.erl:987 mod_configure.erl:1001 msgid "Enter path to backup file" msgstr "Voer pad naar backupbestand in" #: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 #: mod_configure.erl:1030 msgid "Path to File" msgstr "Pad naar bestand" #: mod_configure.erl:997 msgid "Restore Backup from File at " msgstr "Binaire backup direct herstellen op " #: mod_configure.erl:1011 msgid "Dump Backup to Text File at " msgstr "Backup naar een tekstbestand schrijven op " #: mod_configure.erl:1015 msgid "Enter path to text file" msgstr "Voer pad naar backupbestand in" #: mod_configure.erl:1025 msgid "Import User from File at " msgstr "Importeer gebruiker via bestand op " #: mod_configure.erl:1029 msgid "Enter path to jabberd14 spool file" msgstr "Voer pad naar jabberd14-spool-bestand in" #: mod_configure.erl:1039 msgid "Import Users from Dir at " msgstr "Gebruikers importeren vanaf directory op " #: mod_configure.erl:1043 msgid "Enter path to jabberd14 spool dir" msgstr "Voer pad naar jabberd14-spool-directory in" #: mod_configure.erl:1044 msgid "Path to Dir" msgstr "Pad naar directory" #: mod_configure.erl:1060 mod_configure.erl:1105 msgid "Time delay" msgstr "Vertraging" #: mod_configure.erl:1143 msgid "Access Control List Configuration" msgstr "Instellingen van access control lists" #: mod_configure.erl:1147 msgid "Access control lists" msgstr "Access control lists" #: mod_configure.erl:1171 msgid "Access Configuration" msgstr "Toegangsinstellingen" #: mod_configure.erl:1175 msgid "Access rules" msgstr "Access rules" #: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 #: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 #: mod_configure.erl:1287 mod_configure.erl:1650 mod_configure.erl:1700 #: mod_configure.erl:1721 mod_roster.erl:943 mod_roster_odbc.erl:1060 #: mod_vcard.erl:472 mod_vcard_ldap.erl:554 mod_vcard_odbc.erl:448 msgid "Jabber ID" msgstr "Jabber ID" #: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1651 #: mod_configure.erl:1863 mod_muc/mod_muc_room.erl:3224 mod_register.erl:235 #: web/ejabberd_web_admin.erl:1520 msgid "Password" msgstr "Wachtwoord" #: mod_configure.erl:1210 msgid "Password Verification" msgstr "Wachtwoord Bevestiging" #: mod_configure.erl:1301 msgid "Number of registered users" msgstr "Aantal Geregistreerde Gebruikers" #: mod_configure.erl:1315 msgid "Number of online users" msgstr "Aantal Aanwezige Gebruikers" #: mod_configure.erl:1682 web/ejabberd_web_admin.erl:1588 #: web/ejabberd_web_admin.erl:1743 msgid "Never" msgstr "Nooit" #: mod_configure.erl:1696 web/ejabberd_web_admin.erl:1601 #: web/ejabberd_web_admin.erl:1756 msgid "Online" msgstr "Online" #: mod_configure.erl:1701 msgid "Last login" msgstr "Laatste Aanmelding" #: mod_configure.erl:1722 msgid "Roster size" msgstr "Contactlijst Groote" #: mod_configure.erl:1723 msgid "IP addresses" msgstr "IP-adres" #: mod_configure.erl:1724 msgid "Resources" msgstr "Bronnen" #: mod_configure.erl:1850 msgid "Administration of " msgstr "Beheer van " #: mod_configure.erl:1853 msgid "Action on user" msgstr "Actie op gebruiker" #: mod_configure.erl:1857 msgid "Edit Properties" msgstr "Eigenschappen bewerken" #: mod_configure.erl:1860 web/ejabberd_web_admin.erl:1769 msgid "Remove User" msgstr "Gebruiker verwijderen" #: mod_irc/mod_irc.erl:201 mod_irc/mod_irc_odbc.erl:196 #: mod_muc/mod_muc.erl:336 mod_muc/mod_muc_odbc.erl:342 msgid "Access denied by service policy" msgstr "De toegang werd geweigerd door het beleid van deze dienst" #: mod_irc/mod_irc.erl:401 mod_irc/mod_irc_odbc.erl:398 msgid "IRC Transport" msgstr "IRC Transport" #: mod_irc/mod_irc.erl:428 mod_irc/mod_irc_odbc.erl:425 msgid "ejabberd IRC module" msgstr "ejabberd's IRC-module" #: mod_irc/mod_irc.erl:559 mod_irc/mod_irc_odbc.erl:568 msgid "You need an x:data capable client to configure mod_irc settings" msgstr "" "U hebt een client nodig die x:data ondersteunt om dit IRC-transport in te " "stellen" #: mod_irc/mod_irc.erl:566 mod_irc/mod_irc_odbc.erl:575 msgid "Registration in mod_irc for " msgstr "Registratie van " #: mod_irc/mod_irc.erl:571 mod_irc/mod_irc_odbc.erl:580 msgid "" "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers" msgstr "" "Voer de gebruikersnaam, coderingen, poorten en wachtwoorden in die U wilt " "gebruiken voor het verbinden met IRC-servers" #: mod_irc/mod_irc.erl:576 mod_irc/mod_irc_odbc.erl:585 msgid "IRC Username" msgstr "Gebruikersnaam voor IRC:" #: mod_irc/mod_irc.erl:586 mod_irc/mod_irc_odbc.erl:595 msgid "" "If you want to specify different ports, passwords, encodings for IRC " "servers, fill this list with values in format '{\"irc server\", \"encoding" "\", port, \"password\"}'. By default this service use \"~s\" encoding, port " "~p, empty password." msgstr "" "Als u verschillende poorten, wachtwoorden en coderingen wilt opgeven voor " "elke IRC-server, vul dan deze lijst met het volgende formaat: '{\"IRC-server" "\", \"codering\", poort, \"wachtwoord\"}'. Standaard gebruikt deze service " "de codering \"~s\", poort ~p, leeg wachtwoord." #: mod_irc/mod_irc.erl:598 mod_irc/mod_irc_odbc.erl:607 msgid "" "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." "net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." msgstr "" "Voorbeeld: [{\"irc.example.org\", \"koi8-r\", 6667, \"geheim\"}, {\"vendetta." "example.net\", \"iso8859-1\", 7000}, {irc,testserver.nl\", \"utf-8\"}]." #: mod_irc/mod_irc.erl:603 mod_irc/mod_irc_odbc.erl:612 msgid "Connections parameters" msgstr "Verbindingsparameters" #: mod_irc/mod_irc.erl:728 mod_irc/mod_irc_odbc.erl:757 msgid "Join IRC channel" msgstr "Ga IRC kanaal binnen" #: mod_irc/mod_irc.erl:732 mod_irc/mod_irc_odbc.erl:761 msgid "IRC channel (don't put the first #)" msgstr "IRC kanaal (zonder eerste #)" #: mod_irc/mod_irc.erl:737 mod_irc/mod_irc_odbc.erl:766 msgid "IRC server" msgstr "IRC-server" #: mod_irc/mod_irc.erl:770 mod_irc/mod_irc.erl:774 #: mod_irc/mod_irc_odbc.erl:799 mod_irc/mod_irc_odbc.erl:803 msgid "Join the IRC channel here." msgstr "Ga het IRC kanaal binnen" #: mod_irc/mod_irc.erl:778 mod_irc/mod_irc_odbc.erl:807 msgid "Join the IRC channel in this Jabber ID: ~s" msgstr "Ga het IRC kanaal van deze Jabber ID binnen: ~s" #: mod_irc/mod_irc.erl:863 mod_irc/mod_irc_odbc.erl:904 msgid "IRC settings" msgstr "IRC instellingen" #: mod_irc/mod_irc.erl:868 mod_irc/mod_irc_odbc.erl:909 msgid "" "Enter username and encodings you wish to use for connecting to IRC servers. " "Press 'Next' to get more fields to fill in. Press 'Complete' to save " "settings." msgstr "" "Voer de gebruikersnaam en de coderingen in die u wilt gebruiken voor " "verbindingen met IRC-servers. Klik op 'Volgende' om meer velden aan te " "maken. Klik op \"Voltooi' om de instellingen op te slaan." #: mod_irc/mod_irc.erl:874 mod_irc/mod_irc_odbc.erl:915 msgid "IRC username" msgstr "Gebruikersnaam voor IRC" #: mod_irc/mod_irc.erl:923 mod_irc/mod_irc_odbc.erl:964 msgid "Password ~b" msgstr "Wachtwoord ~b" #: mod_irc/mod_irc.erl:928 mod_irc/mod_irc_odbc.erl:969 msgid "Port ~b" msgstr "Poort ~b" #: mod_irc/mod_irc.erl:933 mod_irc/mod_irc_odbc.erl:974 msgid "Encoding for server ~b" msgstr "Karakterset voor server ~b" #: mod_irc/mod_irc.erl:942 mod_irc/mod_irc_odbc.erl:983 msgid "Server ~b" msgstr "Server ~b" #: mod_muc/mod_muc.erl:449 mod_muc/mod_muc_odbc.erl:456 msgid "Only service administrators are allowed to send service messages" msgstr "" "Alleen beheerders van deze dienst mogen mededelingen verzenden naar alle " "chatruimtes" #: mod_muc/mod_muc.erl:493 mod_muc/mod_muc_odbc.erl:500 msgid "Room creation is denied by service policy" msgstr "" "De aanmaak van de chatruimte is verhinderd door de instellingen van deze " "server" #: mod_muc/mod_muc.erl:500 mod_muc/mod_muc_odbc.erl:507 msgid "Conference room does not exist" msgstr "De chatruimte bestaat niet" #: mod_muc/mod_muc.erl:582 mod_muc/mod_muc_odbc.erl:595 msgid "Chatrooms" msgstr "Groepsgesprekken" #: mod_muc/mod_muc.erl:712 mod_muc/mod_muc_odbc.erl:729 msgid "You need a client that supports x:data to register the nickname" msgstr "" "U hebt een client nodig die x:data ondersteunt om een bijnaam te registreren" #: mod_muc/mod_muc.erl:718 mod_muc/mod_muc_odbc.erl:735 msgid "Nickname Registration at " msgstr "Registratie van een bijnaam op " #: mod_muc/mod_muc.erl:722 mod_muc/mod_muc_odbc.erl:739 msgid "Enter nickname you want to register" msgstr "Voer de bijnaam in die u wilt registreren" #: mod_muc/mod_muc.erl:723 mod_muc/mod_muc_odbc.erl:740 #: mod_muc/mod_muc_room.erl:3810 mod_roster.erl:944 mod_roster_odbc.erl:1061 #: mod_vcard.erl:364 mod_vcard.erl:477 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:453 msgid "Nickname" msgstr "Bijnaam" #: mod_muc/mod_muc.erl:762 mod_muc/mod_muc_odbc.erl:784 #: mod_muc/mod_muc_room.erl:1064 mod_muc/mod_muc_room.erl:1787 msgid "That nickname is registered by another person" msgstr "Deze bijnaam is al geregistreerd door iemand anders" #: mod_muc/mod_muc.erl:788 mod_muc/mod_muc_odbc.erl:811 msgid "You must fill in field \"Nickname\" in the form" msgstr "U moet het veld \"bijnaam\" invullen" #: mod_muc/mod_muc.erl:808 mod_muc/mod_muc_odbc.erl:831 msgid "ejabberd MUC module" msgstr "ejabberd's MUC module" #: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 msgid "Chatroom configuration modified" msgstr "De instellingen van de chatruimte werden veranderd" #: mod_muc/mod_muc_log.erl:384 msgid "joins the room" msgstr "betrad de chatruimte" #: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 msgid "leaves the room" msgstr "verliet de chatruimte" #: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 msgid "has been banned" msgstr "werd verbannen" #: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 msgid "has been kicked" msgstr "werd gekicked" #: mod_muc/mod_muc_log.erl:405 msgid "has been kicked because of an affiliation change" msgstr "is weggestuurd vanwege een affiliatieverandering" #: mod_muc/mod_muc_log.erl:408 msgid "has been kicked because the room has been changed to members-only" msgstr "" "is weggestuurd omdat de chatruimte vanaf heden alleen toegankelijk is voor " "leden" #: mod_muc/mod_muc_log.erl:411 msgid "has been kicked because of a system shutdown" msgstr "is weggestuurd omdat het systeem gestopt wordt" #: mod_muc/mod_muc_log.erl:414 msgid "is now known as" msgstr "heet nu" #: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:688 #: mod_muc/mod_muc_room.erl:2393 msgid " has set the subject to: " msgstr " veranderde het onderwerp in: " #: mod_muc/mod_muc_log.erl:452 msgid "Chatroom is created" msgstr "Gespreksruimte gecreëerd" #: mod_muc/mod_muc_log.erl:453 msgid "Chatroom is destroyed" msgstr "Gespreksruimte vernietigd" #: mod_muc/mod_muc_log.erl:454 msgid "Chatroom is started" msgstr "Gespreksruimte gestart" #: mod_muc/mod_muc_log.erl:455 msgid "Chatroom is stopped" msgstr "Gespreksruimte gestopt" #: mod_muc/mod_muc_log.erl:459 msgid "Monday" msgstr "Maandag" #: mod_muc/mod_muc_log.erl:460 msgid "Tuesday" msgstr "Dinsdag" #: mod_muc/mod_muc_log.erl:461 msgid "Wednesday" msgstr "Woensdag" #: mod_muc/mod_muc_log.erl:462 msgid "Thursday" msgstr "Donderdag" #: mod_muc/mod_muc_log.erl:463 msgid "Friday" msgstr "Vrijdag" #: mod_muc/mod_muc_log.erl:464 msgid "Saturday" msgstr "Zaterdag" #: mod_muc/mod_muc_log.erl:465 msgid "Sunday" msgstr "Zondag" #: mod_muc/mod_muc_log.erl:469 msgid "January" msgstr "Januari" #: mod_muc/mod_muc_log.erl:470 msgid "February" msgstr "Februari" #: mod_muc/mod_muc_log.erl:471 msgid "March" msgstr "Maart" #: mod_muc/mod_muc_log.erl:472 msgid "April" msgstr "April" #: mod_muc/mod_muc_log.erl:473 msgid "May" msgstr "Mei" #: mod_muc/mod_muc_log.erl:474 msgid "June" msgstr "Juni" #: mod_muc/mod_muc_log.erl:475 msgid "July" msgstr "Juli" #: mod_muc/mod_muc_log.erl:476 msgid "August" msgstr "Augustus" #: mod_muc/mod_muc_log.erl:477 msgid "September" msgstr "September" #: mod_muc/mod_muc_log.erl:478 msgid "October" msgstr "Oktober" #: mod_muc/mod_muc_log.erl:479 msgid "November" msgstr "November" #: mod_muc/mod_muc_log.erl:480 msgid "December" msgstr "December" #: mod_muc/mod_muc_log.erl:750 msgid "Room Configuration" msgstr "Instellingen van de chatruimte" #: mod_muc/mod_muc_log.erl:759 msgid "Room Occupants" msgstr "Aantal aanwezigen" #: mod_muc/mod_muc_room.erl:174 msgid "Traffic rate limit is exceeded" msgstr "Dataverkeerslimiet overschreden" #: mod_muc/mod_muc_room.erl:246 msgid "" "This participant is kicked from the room because he sent an error message" msgstr "" "Deze deelnemer wordt weggestuurd vanwege het sturen van een " "foutmeldingsbericht" #: mod_muc/mod_muc_room.erl:255 msgid "It is not allowed to send private messages to the conference" msgstr "Er mogen geen privéberichten naar de chatruimte worden verzonden" #: mod_muc/mod_muc_room.erl:332 msgid "Please, wait for a while before sending new voice request" msgstr "Wacht s.v.p. met het maken van een nieuwe stemaanvraag." #: mod_muc/mod_muc_room.erl:347 msgid "Voice requests are disabled in this conference" msgstr "Stemaanvragen zijn uitgeschakeld voor deze chatruimte" #: mod_muc/mod_muc_room.erl:364 msgid "Failed to extract JID from your voice request approval" msgstr "Er kon geen JID worden ontleend uit deze stemaanvraag" #: mod_muc/mod_muc_room.erl:393 msgid "Only moderators can approve voice requests" msgstr "Alleen moderators kunnen stemaanvragen goedkeuren" #: mod_muc/mod_muc_room.erl:408 msgid "Improper message type" msgstr "Onjuist berichttype" #: mod_muc/mod_muc_room.erl:518 msgid "" "This participant is kicked from the room because he sent an error message to " "another participant" msgstr "" "Deze deelnemer wordt weggestuurd vanwege het sturen van een " "foutmeldingsbericht aan een andere deelnemer" #: mod_muc/mod_muc_room.erl:531 msgid "It is not allowed to send private messages of type \"groupchat\"" msgstr "" "Er mogen geen privéberichten van het type \"groupchat\" worden verzonden" #: mod_muc/mod_muc_room.erl:543 mod_muc/mod_muc_room.erl:611 msgid "Recipient is not in the conference room" msgstr "De ontvanger is niet in de chatruimte" #: mod_muc/mod_muc_room.erl:564 mod_muc/mod_muc_room.erl:585 msgid "It is not allowed to send private messages" msgstr "Het is niet toegestaan priveberichten te sturen" #: mod_muc/mod_muc_room.erl:576 mod_muc/mod_muc_room.erl:956 #: mod_muc/mod_muc_room.erl:4040 msgid "Only occupants are allowed to send messages to the conference" msgstr "Alleen aanwezigen mogen berichten naar de chatruimte verzenden" #: mod_muc/mod_muc_room.erl:634 msgid "Only occupants are allowed to send queries to the conference" msgstr "Alleen aanwezigen mogen verzoeken verzenden naar de chatruimte" #: mod_muc/mod_muc_room.erl:646 msgid "Queries to the conference members are not allowed in this room" msgstr "" "Er mogen geen verzoeken verzenden worden naar deelnemers in deze chatruimte" #: mod_muc/mod_muc_room.erl:932 msgid "" "Only moderators and participants are allowed to change the subject in this " "room" msgstr "" "Alleen moderators en deelnemers mogen het onderwerp van deze chatruimte " "veranderen" #: mod_muc/mod_muc_room.erl:937 msgid "Only moderators are allowed to change the subject in this room" msgstr "Alleen moderators mogen het onderwerp van deze chatruimte veranderen" #: mod_muc/mod_muc_room.erl:947 msgid "Visitors are not allowed to send messages to all occupants" msgstr "Bezoekers mogen geen berichten verzenden naar alle aanwezigen" #: mod_muc/mod_muc_room.erl:1021 msgid "" "This participant is kicked from the room because he sent an error presence" msgstr "" "Deze deelnemer wordt weggestuurd vanwege het sturen van een foutmelding-" "aanwezigheid" #: mod_muc/mod_muc_room.erl:1040 msgid "Visitors are not allowed to change their nicknames in this room" msgstr "Het is bezoekers niet toegestaan hun naam te veranderen in dit kanaal" #: mod_muc/mod_muc_room.erl:1053 mod_muc/mod_muc_room.erl:1779 msgid "That nickname is already in use by another occupant" msgstr "Deze bijnaam is al in gebruik door een andere aanwezige" #: mod_muc/mod_muc_room.erl:1768 msgid "You have been banned from this room" msgstr "U werd verbannen uit deze chatruimte" #: mod_muc/mod_muc_room.erl:1771 msgid "Membership is required to enter this room" msgstr "U moet lid zijn om deze chatruimte te kunnen betreden" #: mod_muc/mod_muc_room.erl:1807 msgid "This room is not anonymous" msgstr "Deze chatruimte is niet anoniem" #: mod_muc/mod_muc_room.erl:1833 msgid "A password is required to enter this room" msgstr "U hebt een wachtwoord nodig om deze chatruimte te kunnen betreden" #: mod_muc/mod_muc_room.erl:1855 mod_register.erl:246 msgid "Too many CAPTCHA requests" msgstr "Te veel CAPTCHA-aanvragen" #: mod_muc/mod_muc_room.erl:1864 mod_register.erl:251 msgid "Unable to generate a CAPTCHA" msgstr "Het generen van een CAPTCHA is mislukt" #: mod_muc/mod_muc_room.erl:1874 msgid "Incorrect password" msgstr "Foutief wachtwoord" #: mod_muc/mod_muc_room.erl:2448 msgid "Administrator privileges required" msgstr "U hebt beheerdersprivileges nodig" #: mod_muc/mod_muc_room.erl:2463 msgid "Moderator privileges required" msgstr "U hebt moderatorprivileges nodig" #: mod_muc/mod_muc_room.erl:2619 msgid "Jabber ID ~s is invalid" msgstr "De Jabber ID ~s is ongeldig" #: mod_muc/mod_muc_room.erl:2633 msgid "Nickname ~s does not exist in the room" msgstr "De bijnaam ~s bestaat niet in deze chatruimte" #: mod_muc/mod_muc_room.erl:2659 mod_muc/mod_muc_room.erl:3049 msgid "Invalid affiliation: ~s" msgstr "Ongeldige affiliatie: ~s" #: mod_muc/mod_muc_room.erl:2713 msgid "Invalid role: ~s" msgstr "Ongeldige rol: ~s" #: mod_muc/mod_muc_room.erl:3026 mod_muc/mod_muc_room.erl:3062 msgid "Owner privileges required" msgstr "U hebt eigenaarsprivileges nodig" #: mod_muc/mod_muc_room.erl:3195 msgid "Configuration of room ~s" msgstr "Instellingen van chatruimte ~s" #: mod_muc/mod_muc_room.erl:3200 msgid "Room title" msgstr "Naam van de chatruimte" #: mod_muc/mod_muc_room.erl:3203 mod_muc/mod_muc_room.erl:3692 msgid "Room description" msgstr "Beschrijving" #: mod_muc/mod_muc_room.erl:3210 msgid "Make room persistent" msgstr "Chatruimte blijvend maken" #: mod_muc/mod_muc_room.erl:3215 msgid "Make room public searchable" msgstr "Chatruimte doorzoekbaar maken" #: mod_muc/mod_muc_room.erl:3218 msgid "Make participants list public" msgstr "Deelnemerslijst publiek maken" #: mod_muc/mod_muc_room.erl:3221 msgid "Make room password protected" msgstr "Chatruimte beveiligen met een wachtwoord" #: mod_muc/mod_muc_room.erl:3232 msgid "Maximum Number of Occupants" msgstr "Maximum aantal aanwezigen" #: mod_muc/mod_muc_room.erl:3239 msgid "No limit" msgstr "Geen limiet" #: mod_muc/mod_muc_room.erl:3250 msgid "Present real Jabber IDs to" msgstr "Jabber ID's kunnen achterhaald worden door" #: mod_muc/mod_muc_room.erl:3258 mod_muc/mod_muc_room.erl:3292 msgid "moderators only" msgstr "moderators" #: mod_muc/mod_muc_room.erl:3260 mod_muc/mod_muc_room.erl:3294 msgid "anyone" msgstr "iedereen" #: mod_muc/mod_muc_room.erl:3262 msgid "Make room members-only" msgstr "Chatruimte enkel toegankelijk maken voor leden" #: mod_muc/mod_muc_room.erl:3265 msgid "Make room moderated" msgstr "Chatruimte gemodereerd maken" #: mod_muc/mod_muc_room.erl:3268 msgid "Default users as participants" msgstr "Gebruikers standaard instellen als deelnemers" #: mod_muc/mod_muc_room.erl:3271 msgid "Allow users to change the subject" msgstr "Sta gebruikers toe het onderwerp te veranderen" #: mod_muc/mod_muc_room.erl:3274 msgid "Allow users to send private messages" msgstr "Gebruikers mogen privéberichten verzenden" #: mod_muc/mod_muc_room.erl:3279 msgid "Allow visitors to send private messages to" msgstr "Gebruikers mogen privéberichten verzenden aan" #: mod_muc/mod_muc_room.erl:3290 msgid "nobody" msgstr "niemand" #: mod_muc/mod_muc_room.erl:3296 msgid "Allow users to query other users" msgstr "Gebruikers mogen naar andere gebruikers verzoeken verzenden" #: mod_muc/mod_muc_room.erl:3299 msgid "Allow users to send invites" msgstr "Gebruikers mogen uitnodigingen verzenden" #: mod_muc/mod_muc_room.erl:3302 msgid "Allow visitors to send status text in presence updates" msgstr "Sta bezoekers toe hun statusbericht in te stellen" #: mod_muc/mod_muc_room.erl:3305 msgid "Allow visitors to change nickname" msgstr "Sta bezoekers toe hun naam te veranderen" #: mod_muc/mod_muc_room.erl:3308 msgid "Allow visitors to send voice requests" msgstr "Gebruikers mogen stemaanvragen verzenden" #: mod_muc/mod_muc_room.erl:3311 msgid "Minimum interval between voice requests (in seconds)" msgstr "Minimale interval tussen stemaanvragen (in seconden)" #: mod_muc/mod_muc_room.erl:3317 msgid "Make room CAPTCHA protected" msgstr "Chatruimte beveiligen met een geautomatiseerde Turing test" #: mod_muc/mod_muc_room.erl:3322 msgid "Exclude Jabber IDs from CAPTCHA challenge" msgstr "Geen CAPTCHA test voor Jabber IDs" #: mod_muc/mod_muc_room.erl:3329 msgid "Enable logging" msgstr "Logs aanzetten" #: mod_muc/mod_muc_room.erl:3337 msgid "You need an x:data capable client to configure room" msgstr "" "U hebt een client nodig die x:data ondersteunt om deze chatruimte in te " "stellen" #: mod_muc/mod_muc_room.erl:3694 msgid "Number of occupants" msgstr "Aantal aanwezigen" #: mod_muc/mod_muc_room.erl:3750 msgid "private, " msgstr "privé, " #: mod_muc/mod_muc_room.erl:3799 msgid "Voice request" msgstr "Stemaanvraag" #: mod_muc/mod_muc_room.erl:3803 msgid "Either approve or decline the voice request." msgstr "Keur stemaanvraag goed of af." #: mod_muc/mod_muc_room.erl:3809 msgid "User JID" msgstr "JID Gebruiker" #: mod_muc/mod_muc_room.erl:3811 msgid "Grant voice to this person?" msgstr "Stemaanvraag honoreren voor deze persoon?" #: mod_muc/mod_muc_room.erl:3960 msgid "~s invites you to the room ~s" msgstr "~s nodigt je uit voor het groepsgesprek ~s" #: mod_muc/mod_muc_room.erl:3969 msgid "the password is" msgstr "het wachtwoord is" #: mod_offline.erl:510 mod_offline_odbc.erl:352 msgid "" "Your contact offline message queue is full. The message has been discarded." msgstr "" "Te veel offline berichten voor dit contactpersoon. Het bericht is niet " "opgeslagen." #: mod_offline.erl:560 mod_offline_odbc.erl:408 msgid "~s's Offline Messages Queue" msgstr "offline berichten van ~s" #: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:987 #: mod_roster_odbc.erl:1104 mod_shared_roster.erl:901 #: mod_shared_roster.erl:1010 mod_shared_roster_odbc.erl:930 #: mod_shared_roster_odbc.erl:1039 web/ejabberd_web_admin.erl:833 #: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:942 #: web/ejabberd_web_admin.erl:978 web/ejabberd_web_admin.erl:1019 #: web/ejabberd_web_admin.erl:1508 web/ejabberd_web_admin.erl:1760 #: web/ejabberd_web_admin.erl:1931 web/ejabberd_web_admin.erl:1963 #: web/ejabberd_web_admin.erl:2031 web/ejabberd_web_admin.erl:2135 #: web/ejabberd_web_admin.erl:2160 web/ejabberd_web_admin.erl:2248 msgid "Submitted" msgstr "Verzonden" #: mod_offline.erl:571 msgid "Time" msgstr "Tijd" #: mod_offline.erl:572 msgid "From" msgstr "Van" #: mod_offline.erl:573 msgid "To" msgstr "Aan" #: mod_offline.erl:574 mod_offline_odbc.erl:419 msgid "Packet" msgstr "Pakket" #: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:908 #: mod_shared_roster_odbc.erl:937 web/ejabberd_web_admin.erl:882 #: web/ejabberd_web_admin.erl:986 msgid "Delete Selected" msgstr "Geselecteerde verwijderen" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Offline Messages:" msgstr "Offline berichten:" #: mod_offline.erl:645 mod_offline_odbc.erl:519 msgid "Remove All Offline Messages" msgstr "Verwijder alle offline berichten" #: mod_proxy65/mod_proxy65_service.erl:213 msgid "ejabberd SOCKS5 Bytestreams module" msgstr "ejabberd SOCKS5 Bytestreams module" #: mod_pubsub/mod_pubsub.erl:1120 mod_pubsub/mod_pubsub_odbc.erl:929 msgid "Publish-Subscribe" msgstr "Publish-Subscribe" #: mod_pubsub/mod_pubsub.erl:1214 mod_pubsub/mod_pubsub_odbc.erl:1025 msgid "ejabberd Publish-Subscribe module" msgstr "ejabberd Publish-Subscribe module" #: mod_pubsub/mod_pubsub.erl:1497 mod_pubsub/mod_pubsub_odbc.erl:1312 msgid "PubSub subscriber request" msgstr "PubSub abonnee verzoek" #: mod_pubsub/mod_pubsub.erl:1499 mod_pubsub/mod_pubsub_odbc.erl:1314 msgid "Choose whether to approve this entity's subscription." msgstr "Beslis of dit verzoek tot abonneren zal worden goedgekeurd" #: mod_pubsub/mod_pubsub.erl:1505 mod_pubsub/mod_pubsub_odbc.erl:1320 msgid "Node ID" msgstr "Node ID" #: mod_pubsub/mod_pubsub.erl:1510 mod_pubsub/mod_pubsub_odbc.erl:1325 msgid "Subscriber Address" msgstr "Abonnee Adres" #: mod_pubsub/mod_pubsub.erl:1516 mod_pubsub/mod_pubsub_odbc.erl:1331 msgid "Allow this Jabber ID to subscribe to this pubsub node?" msgstr "Deze gebruiker toestaan te abonneren op deze pubsub node?" #: mod_pubsub/mod_pubsub.erl:3474 mod_pubsub/mod_pubsub_odbc.erl:3287 msgid "Deliver payloads with event notifications" msgstr "Berichten bezorgen samen met gebeurtenisnotificaties" #: mod_pubsub/mod_pubsub.erl:3475 mod_pubsub/mod_pubsub_odbc.erl:3288 msgid "Deliver event notifications" msgstr "Gebeurtenisbevestigingen Sturen" #: mod_pubsub/mod_pubsub.erl:3476 mod_pubsub/mod_pubsub_odbc.erl:3289 msgid "Notify subscribers when the node configuration changes" msgstr "Abonnees informeren wanneer de instellingen van de node veranderen" #: mod_pubsub/mod_pubsub.erl:3477 mod_pubsub/mod_pubsub_odbc.erl:3290 msgid "Notify subscribers when the node is deleted" msgstr "Abonnees informeren wanneer de node verwijderd word" #: mod_pubsub/mod_pubsub.erl:3478 mod_pubsub/mod_pubsub_odbc.erl:3291 msgid "Notify subscribers when items are removed from the node" msgstr "Abonnees informeren wanneer items verwijderd worden uit de node" #: mod_pubsub/mod_pubsub.erl:3479 mod_pubsub/mod_pubsub_odbc.erl:3292 msgid "Persist items to storage" msgstr "Items in het geheugen bewaren" #: mod_pubsub/mod_pubsub.erl:3480 mod_pubsub/mod_pubsub_odbc.erl:3293 msgid "A friendly name for the node" msgstr "Bijnaam voor deze knoop" #: mod_pubsub/mod_pubsub.erl:3481 mod_pubsub/mod_pubsub_odbc.erl:3294 msgid "Max # of items to persist" msgstr "Maximum aantal in het geheugen te bewaren items" #: mod_pubsub/mod_pubsub.erl:3482 mod_pubsub/mod_pubsub_odbc.erl:3295 msgid "Whether to allow subscriptions" msgstr "Abonnementsaanvraag toestaan" #: mod_pubsub/mod_pubsub.erl:3483 mod_pubsub/mod_pubsub_odbc.erl:3296 msgid "Specify the access model" msgstr "Geef toegangsmodel" #: mod_pubsub/mod_pubsub.erl:3486 mod_pubsub/mod_pubsub_odbc.erl:3299 msgid "Roster groups allowed to subscribe" msgstr "Contactlijst-groepen die mogen abonneren" #: mod_pubsub/mod_pubsub.erl:3487 mod_pubsub/mod_pubsub_odbc.erl:3300 msgid "Specify the publisher model" msgstr "Publicatietype opgeven" #: mod_pubsub/mod_pubsub.erl:3489 mod_pubsub/mod_pubsub_odbc.erl:3302 msgid "Purge all items when the relevant publisher goes offline" msgstr "Verwijder alle items wanneer de gerelateerde publiceerder offline gaat" #: mod_pubsub/mod_pubsub.erl:3490 mod_pubsub/mod_pubsub_odbc.erl:3303 msgid "Specify the event message type" msgstr "Geef type van eventbericht" #: mod_pubsub/mod_pubsub.erl:3492 mod_pubsub/mod_pubsub_odbc.erl:3305 msgid "Max payload size in bytes" msgstr "Maximumgrootte van bericht in bytes" #: mod_pubsub/mod_pubsub.erl:3493 mod_pubsub/mod_pubsub_odbc.erl:3306 msgid "When to send the last published item" msgstr "Wanneer het laatst gepubliceerde item verzonden moet worden" #: mod_pubsub/mod_pubsub.erl:3495 mod_pubsub/mod_pubsub_odbc.erl:3308 msgid "Only deliver notifications to available users" msgstr "Notificaties alleen verzenden naar online gebruikers" #: mod_pubsub/mod_pubsub.erl:3496 mod_pubsub/mod_pubsub_odbc.erl:3309 msgid "The collections with which a node is affiliated" msgstr "De collecties waar een node mee is gerelateerd" #: mod_register.erl:193 msgid "The CAPTCHA verification has failed" msgstr "De CAPTCHA-verificatie is mislukt" #: mod_register.erl:220 msgid "You need a client that supports x:data and CAPTCHA to register" msgstr "" "U hebt een client nodig die x:data en CAPTCHA ondersteunt om een bijnaam te " "registreren" #: mod_register.erl:226 mod_register.erl:265 msgid "Choose a username and password to register with this server" msgstr "" "Kies een gebruikersnaam en een wachtwoord om u te registreren op deze server" #: mod_register.erl:230 mod_vcard.erl:364 mod_vcard_odbc.erl:342 #: web/ejabberd_web_admin.erl:1515 web/ejabberd_web_admin.erl:1572 msgid "User" msgstr "Gebruiker" #: mod_register.erl:316 mod_register.erl:361 msgid "The password is too weak" msgstr "Het wachtwoord is te zwak" #: mod_register.erl:365 msgid "Users are not allowed to register accounts so quickly" msgstr "Het is gebruikers niet toegestaan zo snel achter elkaar te registreren" #: mod_roster.erl:938 mod_roster_odbc.erl:1055 web/ejabberd_web_admin.erl:1701 #: web/ejabberd_web_admin.erl:1886 web/ejabberd_web_admin.erl:1897 #: web/ejabberd_web_admin.erl:2219 msgid "None" msgstr "Geen" #: mod_roster.erl:945 mod_roster_odbc.erl:1062 msgid "Subscription" msgstr "Inschrijving" #: mod_roster.erl:946 mod_roster_odbc.erl:1063 msgid "Pending" msgstr "Bezig" #: mod_roster.erl:947 mod_roster_odbc.erl:1064 msgid "Groups" msgstr "Groepen" #: mod_roster.erl:974 mod_roster_odbc.erl:1091 msgid "Validate" msgstr "Bevestigen" #: mod_roster.erl:982 mod_roster_odbc.erl:1099 msgid "Remove" msgstr "Verwijderen" #: mod_roster.erl:985 mod_roster_odbc.erl:1102 msgid "Roster of " msgstr "Roster van " #: mod_roster.erl:988 mod_roster_odbc.erl:1105 mod_shared_roster.erl:902 #: mod_shared_roster.erl:1011 mod_shared_roster_odbc.erl:931 #: mod_shared_roster_odbc.erl:1040 web/ejabberd_web_admin.erl:834 #: web/ejabberd_web_admin.erl:875 web/ejabberd_web_admin.erl:943 #: web/ejabberd_web_admin.erl:979 web/ejabberd_web_admin.erl:1020 #: web/ejabberd_web_admin.erl:1509 web/ejabberd_web_admin.erl:1761 #: web/ejabberd_web_admin.erl:1932 web/ejabberd_web_admin.erl:2136 #: web/ejabberd_web_admin.erl:2161 msgid "Bad format" msgstr "Slecht formaat" #: mod_roster.erl:995 mod_roster_odbc.erl:1112 msgid "Add Jabber ID" msgstr "Jabber ID toevoegen" #: mod_roster.erl:1094 mod_roster_odbc.erl:1211 msgid "Roster" msgstr "Roster" #: mod_shared_roster.erl:857 mod_shared_roster.erl:899 #: mod_shared_roster.erl:1007 mod_shared_roster_odbc.erl:886 #: mod_shared_roster_odbc.erl:928 mod_shared_roster_odbc.erl:1036 msgid "Shared Roster Groups" msgstr "Gedeelde rostergroepen" #: mod_shared_roster.erl:895 mod_shared_roster_odbc.erl:924 #: web/ejabberd_web_admin.erl:1365 web/ejabberd_web_admin.erl:2461 msgid "Add New" msgstr "Toevoegen" #: mod_shared_roster.erl:978 mod_shared_roster_odbc.erl:1007 msgid "Name:" msgstr "Naam:" #: mod_shared_roster.erl:983 mod_shared_roster_odbc.erl:1012 msgid "Description:" msgstr "Beschrijving:" #: mod_shared_roster.erl:991 mod_shared_roster_odbc.erl:1020 msgid "Members:" msgstr "Groepsleden:" #: mod_shared_roster.erl:999 mod_shared_roster_odbc.erl:1028 msgid "Displayed Groups:" msgstr "Weergegeven groepen:" #: mod_shared_roster.erl:1008 mod_shared_roster_odbc.erl:1037 msgid "Group " msgstr "Groep " #: mod_shared_roster.erl:1017 mod_shared_roster_odbc.erl:1046 #: web/ejabberd_web_admin.erl:840 web/ejabberd_web_admin.erl:884 #: web/ejabberd_web_admin.erl:949 web/ejabberd_web_admin.erl:1026 #: web/ejabberd_web_admin.erl:2017 msgid "Submit" msgstr "Verzenden" #: mod_vcard.erl:165 mod_vcard_ldap.erl:238 mod_vcard_odbc.erl:129 msgid "Erlang Jabber Server" msgstr "Erlang Jabber Server" #: mod_vcard.erl:364 mod_vcard.erl:478 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:454 msgid "Birthday" msgstr "Geboortedatum" #: mod_vcard.erl:364 mod_vcard.erl:480 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:456 msgid "City" msgstr "Plaats" #: mod_vcard.erl:364 mod_vcard.erl:479 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:455 msgid "Country" msgstr "Land" #: mod_vcard.erl:364 mod_vcard.erl:481 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:457 msgid "Email" msgstr "E-mail" #: mod_vcard.erl:364 mod_vcard.erl:476 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:452 msgid "Family Name" msgstr "Achternaam" #: mod_vcard.erl:364 mod_vcard_odbc.erl:342 msgid "" "Fill in the form to search for any matching Jabber User (Add * to the end of " "field to match substring)" msgstr "" "Gebruik de velden om te zoeken (Voeg achteraan het teken * toe om te zoeken " "naar alles wat met het eerste deel begint.)." #: mod_vcard.erl:364 mod_vcard.erl:473 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:449 msgid "Full Name" msgstr "Volledige naam" #: mod_vcard.erl:364 mod_vcard.erl:475 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:451 msgid "Middle Name" msgstr "Tussennaam" #: mod_vcard.erl:364 mod_vcard.erl:474 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:450 web/ejabberd_web_admin.erl:2006 msgid "Name" msgstr "Naam" #: mod_vcard.erl:364 mod_vcard.erl:482 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:458 msgid "Organization Name" msgstr "Organisatie" #: mod_vcard.erl:364 mod_vcard.erl:483 mod_vcard_odbc.erl:342 #: mod_vcard_odbc.erl:459 msgid "Organization Unit" msgstr "Afdeling" #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "Search users in " msgstr "Gebruikers zoeken in " #: mod_vcard.erl:364 mod_vcard_ldap.erl:462 mod_vcard_odbc.erl:342 msgid "You need an x:data capable client to search" msgstr "U hebt een client nodig die x:data ondersteunt om te zoeken" #: mod_vcard.erl:389 mod_vcard_ldap.erl:487 mod_vcard_odbc.erl:367 msgid "vCard User Search" msgstr "Gebruikers zoeken" #: mod_vcard.erl:445 mod_vcard_ldap.erl:541 mod_vcard_odbc.erl:421 msgid "ejabberd vCard module" msgstr "ejabberd's vCard-module" #: mod_vcard.erl:469 mod_vcard_ldap.erl:551 mod_vcard_odbc.erl:445 msgid "Search Results for " msgstr "Zoekresultaten voor " #: mod_vcard_ldap.erl:462 msgid "Fill in fields to search for any matching Jabber User" msgstr "Vul de velden in om te zoeken naar Jabber-gebruikers op deze server" #: web/ejabberd_web_admin.erl:193 web/ejabberd_web_admin.erl:203 #: web/ejabberd_web_admin.erl:219 web/ejabberd_web_admin.erl:229 msgid "Unauthorized" msgstr "Niet geautoriseerd" #: web/ejabberd_web_admin.erl:286 web/ejabberd_web_admin.erl:303 msgid "ejabberd Web Admin" msgstr "ejabberd Webbeheer" #: web/ejabberd_web_admin.erl:769 web/ejabberd_web_admin.erl:780 msgid "Administration" msgstr "Beheer" #: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 msgid "Raw" msgstr "Ruw" #: web/ejabberd_web_admin.erl:1017 msgid "~s access rule configuration" msgstr "Access rules op ~s" #: web/ejabberd_web_admin.erl:1035 msgid "Virtual Hosts" msgstr "Virtuele hosts" #: web/ejabberd_web_admin.erl:1043 web/ejabberd_web_admin.erl:1050 msgid "Users" msgstr "Gebruikers" #: web/ejabberd_web_admin.erl:1078 msgid "Users Last Activity" msgstr "Laatste activiteit van gebruikers" #: web/ejabberd_web_admin.erl:1080 msgid "Period: " msgstr "Periode: " #: web/ejabberd_web_admin.erl:1090 msgid "Last month" msgstr "Afgelopen maand" #: web/ejabberd_web_admin.erl:1091 msgid "Last year" msgstr "Afgelopen jaar" #: web/ejabberd_web_admin.erl:1092 msgid "All activity" msgstr "Alle activiteit" #: web/ejabberd_web_admin.erl:1094 msgid "Show Ordinary Table" msgstr "Deel van tabel laten zien" #: web/ejabberd_web_admin.erl:1096 msgid "Show Integral Table" msgstr "Volledige tabel laten zien" #: web/ejabberd_web_admin.erl:1105 web/ejabberd_web_admin.erl:1939 msgid "Statistics" msgstr "Statistieken" #: web/ejabberd_web_admin.erl:1117 msgid "Not Found" msgstr "Niet gevonden" #: web/ejabberd_web_admin.erl:1134 msgid "Node not found" msgstr "Node niet gevonden" #: web/ejabberd_web_admin.erl:1460 msgid "Host" msgstr "Host" #: web/ejabberd_web_admin.erl:1461 msgid "Registered Users" msgstr "Geregistreerde gebruikers" #: web/ejabberd_web_admin.erl:1573 msgid "Offline Messages" msgstr "Offline berichten" #: web/ejabberd_web_admin.erl:1574 web/ejabberd_web_admin.erl:1767 msgid "Last Activity" msgstr "Laatste activiteit" #: web/ejabberd_web_admin.erl:1659 web/ejabberd_web_admin.erl:1675 msgid "Registered Users:" msgstr "Geregistreerde gebruikers:" #: web/ejabberd_web_admin.erl:1661 web/ejabberd_web_admin.erl:1677 #: web/ejabberd_web_admin.erl:2192 msgid "Online Users:" msgstr "Online gebruikers:" #: web/ejabberd_web_admin.erl:1663 msgid "Outgoing s2s Connections:" msgstr "Uitgaande s2s-verbindingen:" #: web/ejabberd_web_admin.erl:1665 msgid "Outgoing s2s Servers:" msgstr "Uitgaande s2s-verbindingen:" #: web/ejabberd_web_admin.erl:1734 web/mod_register_web.erl:175 #: web/mod_register_web.erl:372 web/mod_register_web.erl:381 #: web/mod_register_web.erl:411 msgid "Change Password" msgstr "Wachtwoord wijzigen" #: web/ejabberd_web_admin.erl:1758 msgid "User " msgstr "Gebruiker " #: web/ejabberd_web_admin.erl:1765 msgid "Connected Resources:" msgstr "Verbonden bronnen:" #: web/ejabberd_web_admin.erl:1766 web/mod_register_web.erl:227 #: web/mod_register_web.erl:519 msgid "Password:" msgstr "Wachtwoord:" #: web/ejabberd_web_admin.erl:1828 msgid "No Data" msgstr "Geen gegevens" #: web/ejabberd_web_admin.erl:1906 msgid "Nodes" msgstr "Nodes" #: web/ejabberd_web_admin.erl:1929 web/ejabberd_web_admin.erl:1951 msgid "Node " msgstr "Node " #: web/ejabberd_web_admin.erl:1938 msgid "Listened Ports" msgstr "Openstaande poorten" #: web/ejabberd_web_admin.erl:1940 web/ejabberd_web_admin.erl:2260 #: web/ejabberd_web_admin.erl:2448 msgid "Update" msgstr "Bijwerken" #: web/ejabberd_web_admin.erl:1943 web/ejabberd_web_admin.erl:2569 msgid "Restart" msgstr "Herstarten" #: web/ejabberd_web_admin.erl:1945 web/ejabberd_web_admin.erl:2571 msgid "Stop" msgstr "Stoppen" #: web/ejabberd_web_admin.erl:1959 msgid "RPC Call Error" msgstr "RPC-oproepfout" #: web/ejabberd_web_admin.erl:2000 msgid "Database Tables at " msgstr "Databasetabellen van " #: web/ejabberd_web_admin.erl:2007 msgid "Storage Type" msgstr "Opslagmethode" #: web/ejabberd_web_admin.erl:2008 msgid "Elements" msgstr "Elementen" #: web/ejabberd_web_admin.erl:2009 msgid "Memory" msgstr "Geheugen" #: web/ejabberd_web_admin.erl:2032 web/ejabberd_web_admin.erl:2137 msgid "Error" msgstr "Fout" #: web/ejabberd_web_admin.erl:2034 msgid "Backup of " msgstr "Backup maken van " #: web/ejabberd_web_admin.erl:2036 msgid "" "Please note that these options will only backup the builtin Mnesia database. " "If you are using the ODBC module, you also need to backup your SQL database " "separately." msgstr "" "Merk op dat volgende opties enkel backups maken van de ingebouwde database " "Mnesia. Als U de ODBC module gebruikt dan moeten daarvan afzonderlijke " "backups gemaakt worden." #: web/ejabberd_web_admin.erl:2041 msgid "Store binary backup:" msgstr "Binaire backup maken:" #: web/ejabberd_web_admin.erl:2045 web/ejabberd_web_admin.erl:2052 #: web/ejabberd_web_admin.erl:2060 web/ejabberd_web_admin.erl:2067 #: web/ejabberd_web_admin.erl:2074 web/ejabberd_web_admin.erl:2081 #: web/ejabberd_web_admin.erl:2088 web/ejabberd_web_admin.erl:2096 #: web/ejabberd_web_admin.erl:2103 web/ejabberd_web_admin.erl:2110 msgid "OK" msgstr "OK" #: web/ejabberd_web_admin.erl:2048 msgid "Restore binary backup immediately:" msgstr "Binaire backup direct herstellen:" #: web/ejabberd_web_admin.erl:2056 msgid "" "Restore binary backup after next ejabberd restart (requires less memory):" msgstr "" "Binaire backup herstellen na herstart van ejabberd (vereist minder geheugen):" #: web/ejabberd_web_admin.erl:2063 msgid "Store plain text backup:" msgstr "Backup naar een tekstbestand schrijven:" #: web/ejabberd_web_admin.erl:2070 msgid "Restore plain text backup immediately:" msgstr "Backup in een tekstbestand direct herstellen:" #: web/ejabberd_web_admin.erl:2077 msgid "Import users data from a PIEFXIS file (XEP-0227):" msgstr "Importeer gebruikersdata van een PIEFXIS-bestand (XEP-0227):" #: web/ejabberd_web_admin.erl:2084 msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" msgstr "" "Exporteer data van alle gebruikers in de server naar PIEFXIS-bestanden " "(XEP-0227):" #: web/ejabberd_web_admin.erl:2091 msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" msgstr "" "Exporteer data van alle gebruikers van een host naar PIEXFIS-bestanden " "(XEP-0227):" #: web/ejabberd_web_admin.erl:2099 msgid "Import user data from jabberd14 spool file:" msgstr "Importeer gebruikersdata via spool-bestanden van jabberd14" #: web/ejabberd_web_admin.erl:2106 msgid "Import users data from jabberd14 spool directory:" msgstr "Importeer gebruikersdata via spool-bestanden van jabberd14" #: web/ejabberd_web_admin.erl:2132 msgid "Listened Ports at " msgstr "Openstaande poorten op " #: web/ejabberd_web_admin.erl:2157 msgid "Modules at " msgstr "Modules op " #: web/ejabberd_web_admin.erl:2183 msgid "Statistics of ~p" msgstr "Statistieken van ~p" #: web/ejabberd_web_admin.erl:2186 msgid "Uptime:" msgstr "Uptime:" #: web/ejabberd_web_admin.erl:2189 msgid "CPU Time:" msgstr "Processortijd:" #: web/ejabberd_web_admin.erl:2195 msgid "Transactions Committed:" msgstr "Bevestigde transacties:" #: web/ejabberd_web_admin.erl:2198 msgid "Transactions Aborted:" msgstr "Afgebroken transacties:" #: web/ejabberd_web_admin.erl:2201 msgid "Transactions Restarted:" msgstr "Herstarte transacties:" #: web/ejabberd_web_admin.erl:2204 msgid "Transactions Logged:" msgstr "Gelogde transacties:" #: web/ejabberd_web_admin.erl:2246 msgid "Update " msgstr "Opwaarderen van " #: web/ejabberd_web_admin.erl:2254 msgid "Update plan" msgstr "Plan voor de opwaardering" #: web/ejabberd_web_admin.erl:2255 msgid "Modified modules" msgstr "Gewijzigde modules" #: web/ejabberd_web_admin.erl:2256 msgid "Update script" msgstr "Script voor de opwaardering" #: web/ejabberd_web_admin.erl:2257 msgid "Low level update script" msgstr "Lowlevel script voor de opwaardering" #: web/ejabberd_web_admin.erl:2258 msgid "Script check" msgstr "Controle van script" #: web/ejabberd_web_admin.erl:2426 msgid "Port" msgstr "Poort" #: web/ejabberd_web_admin.erl:2427 msgid "IP" msgstr "IP" #: web/ejabberd_web_admin.erl:2428 msgid "Protocol" msgstr "Protocol" #: web/ejabberd_web_admin.erl:2429 web/ejabberd_web_admin.erl:2556 msgid "Module" msgstr "Module" #: web/ejabberd_web_admin.erl:2430 web/ejabberd_web_admin.erl:2557 msgid "Options" msgstr "Opties" #: web/ejabberd_web_admin.erl:2450 msgid "Delete" msgstr "Verwijderen" #: web/ejabberd_web_admin.erl:2579 msgid "Start" msgstr "Starten" #: web/mod_register_web.erl:104 msgid "Your Jabber account was successfully created." msgstr "Uw Jabber-account is succesvol gecreeerd." #: web/mod_register_web.erl:107 msgid "There was an error creating the account: " msgstr "Er was een fout bij het creeern van de account:" #: web/mod_register_web.erl:115 msgid "Your Jabber account was successfully deleted." msgstr "Uw Jabber-account is succesvol verwijderd." #: web/mod_register_web.erl:118 msgid "There was an error deleting the account: " msgstr "Er was een fout bij het verwijderen van de account." #: web/mod_register_web.erl:128 msgid "The password of your Jabber account was successfully changed." msgstr "Het wachtwoord van Uw Jabber-account is succesvol veranderd." #: web/mod_register_web.erl:131 msgid "There was an error changing the password: " msgstr "Er was een fout bij het veranderen van het wachtwoord:" #: web/mod_register_web.erl:163 web/mod_register_web.erl:172 msgid "Jabber Account Registration" msgstr "Jabber-account registratie" #: web/mod_register_web.erl:174 web/mod_register_web.erl:192 #: web/mod_register_web.erl:201 msgid "Register a Jabber account" msgstr "Registreer een Jabber-account" #: web/mod_register_web.erl:176 web/mod_register_web.erl:493 #: web/mod_register_web.erl:502 msgid "Unregister a Jabber account" msgstr "Opheffen van Jabber-account" #: web/mod_register_web.erl:203 msgid "" "This page allows to create a Jabber account in this Jabber server. Your JID " "(Jabber IDentifier) will be of the form: username@server. Please read " "carefully the instructions to fill correctly the fields." msgstr "" "Deze pagina maakt het mogelijk een Jabber-account te registreren op deze " "server. Uw JID (Jabber IDentiteit) zal er als volg uit zien: " "gebruikersnaam@server. Lees de instructies zorgvuldig teneinde de velden " "correct in te vullen." #: web/mod_register_web.erl:212 web/mod_register_web.erl:386 #: web/mod_register_web.erl:509 msgid "Username:" msgstr "Gebruikersnaam:" #: web/mod_register_web.erl:217 msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." msgstr "" "Dit is niet hoofdlettergevoelig: macbeth is hetzelfde als MacBeth en Macbeth." #: web/mod_register_web.erl:218 msgid "Characters not allowed:" msgstr "Niet-toegestane karakters:" #: web/mod_register_web.erl:222 web/mod_register_web.erl:391 #: web/mod_register_web.erl:514 msgid "Server:" msgstr "Server:" #: web/mod_register_web.erl:232 msgid "" "Don't tell your password to anybody, not even the administrators of the " "Jabber server." msgstr "" "Geef Uw wachtwoord aan niemand, zelfs niet aan de beheerders van deze Jabber-" "server." #: web/mod_register_web.erl:234 msgid "You can later change your password using a Jabber client." msgstr "U can het wachtwoord later veranderen met een Jabber-client." #: web/mod_register_web.erl:235 msgid "" "Some Jabber clients can store your password in your computer. Use that " "feature only if you trust your computer is safe." msgstr "" "Sommige Jabber-clienten kunnen het wachtwoord opslaan op Uw computer. " "Gebruik deze mogelijkheid alleen als U vertrouwd dat Uw computer afdoende " "beveiligd is." #: web/mod_register_web.erl:237 msgid "" "Memorize your password, or write it in a paper placed in a safe place. In " "Jabber there isn't an automated way to recover your password if you forget " "it." msgstr "" "Onthou het wachtwoord, of schrijf het op en bewaar het op een veilige " "plaats. Met Jabber is er geen geautomatiseerde manier om het wachtwoord " "terug te halen als U het vergeet." #: web/mod_register_web.erl:242 web/mod_register_web.erl:406 msgid "Password Verification:" msgstr "Wachtwoord Bevestiging:" #: web/mod_register_web.erl:250 msgid "Register" msgstr "Registreer" #: web/mod_register_web.erl:396 msgid "Old Password:" msgstr "Oud Wachtwoord:" #: web/mod_register_web.erl:401 msgid "New Password:" msgstr "Nieuw Wachtwoord:" #: web/mod_register_web.erl:504 msgid "This page allows to unregister a Jabber account in this Jabber server." msgstr "" "Deze pagina maakt het mogelijk een Jabber-account op deze server op te " "heffen." #: web/mod_register_web.erl:524 msgid "Unregister" msgstr "Opheffen" #, fuzzy #~ msgid "Captcha test failed" #~ msgstr "De geautomatiseerde Turing-test is geslaagd." ejabberd-2.1.11/src/ejabberd_loglevel.erl0000664000000000000000000001635512240230175015152 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_loglevel.erl %%% Author : Mickael Remond %%% Purpose : Loglevel switcher. %%% Be careful: you should not have any ejabberd_logger module %%% as ejabberd_loglevel switcher is compiling and loading %%% dynamically a "virtual" ejabberd_logger module (Described %%% in a string at the end of this module). %%% Created : 29 Nov 2006 by Mickael Remond %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_loglevel). -author('mickael.remond@process-one.net'). -export([set/1, get/0, set_custom/2, clear_custom/0, clear_custom/1]). -include("ejabberd.hrl"). -define(LOGMODULE, "error_logger"). %% Error levels: -record(loglevel, {ordinal, name, description, function = no_log, event_type = no_log, msg_prefix = no_log}). -define(LOG_LEVELS, [#loglevel{ordinal = 0, name = no_log, description = "No log"}, #loglevel{ordinal = 1, name = critical, description = "Critical", function = critical_msg, event_type = error, msg_prefix = "C"}, #loglevel{ordinal = 2, name = error, description = "Error", function = error_msg, event_type = error, msg_prefix = "E"}, #loglevel{ordinal = 3, name = warning, description = "Warning", function = warning_msg, event_type = warning_msg, msg_prefix = "W"}, #loglevel{ordinal = 4, name = info, description = "Info", function = info_msg, event_type = info_msg, msg_prefix = "I"}, #loglevel{ordinal = 5, name = debug, description = "Debug", function = debug_msg, event_type = info_msg, msg_prefix = "D"}]). %% @type level() = integer() | atom(). %% @spec () -> {DefaultLevelOrdinal::integer(), [{Module::atom(), LevelOrdinal::integer()}]} %% @doc Get the default and all custom levels get() -> {DefaultLevel, _CustomLevels} = ejabberd_logger:get(), case lists:keysearch(DefaultLevel, #loglevel.ordinal, ?LOG_LEVELS) of {value, Result = #loglevel{}} -> {Result#loglevel.ordinal, Result#loglevel.name, Result#loglevel.description}; _ -> erlang:error({no_such_loglevel, DefaultLevel}) end. %% @spec (DefaultLevel::level() | {DefaultLevel::level(), [{Module::atom(), Level::level()}]}) -> %% {module, ejabberd_logger} %% @doc Set the default and all custom levels set(DefaultLevel) when is_atom(DefaultLevel) orelse is_integer(DefaultLevel) -> set({DefaultLevel, []}); set({DefaultLevel, CustomLevels}) when is_list(CustomLevels) -> DefaultInt = level_to_integer(DefaultLevel), CustomInts = [level_to_integer(C) || C <- CustomLevels], Loglevel = {DefaultInt, CustomInts}, try {Mod,Code} = dynamic_compile:from_string(ejabberd_logger_src(Loglevel)), code:load_binary(Mod, ?LOGMODULE ++ ".erl", Code) catch Type:Error -> ?CRITICAL_MSG("Error compiling logger (~p): ~p~n", [Type, Error]) end; set(_) -> exit("Invalid loglevel format"). %% @spec (Module::atom(), CustomLevel::level()) -> ok %% @doc Set a custom level set_custom(Module, Level) -> {DefaultLevel, CustomLevels} = ejabberd_logger:get(), case lists:keysearch(Module, 1, CustomLevels) of {value, {Module, Level}} -> ok; {value, _} -> set({DefaultLevel, lists:keyreplace(Module, 1, CustomLevels, {Module, Level})}); _ -> set({DefaultLevel, [{Module, Level} | CustomLevels]}) end. %% @spec () -> ok %% @doc Clear all custom levels clear_custom() -> {DefaultLevel, _CustomLevels} = ejabberd_logger:get(), set({DefaultLevel, []}). %% @spec (Module::atom()) -> ok %% @doc Clear a custom level clear_custom(Module) -> {DefaultLevel, CustomLevels} = ejabberd_logger:get(), case lists:keysearch(Module, 1, CustomLevels) of {value, _} -> set({DefaultLevel, lists:keydelete(Module, 1, CustomLevels)}); _ -> ok end. level_to_integer(Level) when is_integer(Level) -> Level; level_to_integer({Module, Level}) -> {Module, level_to_integer(Level)}; level_to_integer(Level) -> case lists:keysearch(Level, #loglevel.name, ?LOG_LEVELS) of {value, #loglevel{ordinal = Int}} -> Int; _ -> erlang:error({no_such_loglevel, Level}) end. %% -------------------------------------------------------------- %% Code of the ejabberd logger, dynamically compiled and loaded %% This allows to dynamically change log level while keeping a %% very efficient code. ejabberd_logger_src(Loglevel) -> lists:flatten([header_src(), get_src(Loglevel), [log_src(Loglevel, LevelSpec) || LevelSpec <- ?LOG_LEVELS], notify_src()]). header_src() -> "-module(ejabberd_logger). -author('mickael.remond@process-one.net'). -export([debug_msg/4, info_msg/4, warning_msg/4, error_msg/4, critical_msg/4, get/0]). ". get_src(Loglevel) -> io_lib:format("get() -> ~w. ", [Loglevel]). log_src(_Loglevel, #loglevel{function = no_log}) -> []; log_src({DefaultLevel, [{Module, Level} | Tail]}, Spec = #loglevel{ordinal = MinLevel}) when Level < MinLevel andalso MinLevel =< DefaultLevel -> [atom_to_list(Spec#loglevel.function), "(", atom_to_list(Module), ", _, _, _) -> ok; ", log_src({DefaultLevel, Tail}, Spec)]; log_src({DefaultLevel, [{Module, Level} | Tail]}, Spec = #loglevel{ordinal = MinLevel}) when DefaultLevel < MinLevel andalso MinLevel =< Level -> [atom_to_list(Spec#loglevel.function), "(", atom_to_list(Module), " = Module, Line, Format, Args) ->", log_notify_src(Spec), "; ", log_src({DefaultLevel, Tail}, Spec)]; log_src({DefaultLevel, [_Head | Tail]}, Spec = #loglevel{}) -> log_src({DefaultLevel, Tail}, Spec); log_src({DefaultLevel, []}, Spec = #loglevel{ordinal = MinLevel}) when DefaultLevel < MinLevel -> [atom_to_list(Spec#loglevel.function), "(_, _, _, _) -> ok. "]; log_src({_DefaultLevel, []}, Spec = #loglevel{}) -> [atom_to_list(Spec#loglevel.function), "(Module, Line, Format, Args) ->", log_notify_src(Spec), ". "]. log_notify_src(Spec = #loglevel{}) -> ["notify(", atom_to_list(Spec#loglevel.event_type), ", \"", Spec#loglevel.msg_prefix, "(~p:~p:~p) : \"++Format++\"~n\", [self(), Module, Line | Args])"]. notify_src() -> %% Distribute the message to the Erlang error logger "notify(Type, Format, Args) -> LoggerMsg = {Type, group_leader(), {self(), Format, Args}}, gen_event:notify(error_logger, LoggerMsg). ". ejabberd-2.1.11/src/mod_blocking.erl0000664000000000000000000002337012240230175014145 0ustar %%%---------------------------------------------------------------------- %%% File : mod_blocking.erl %%% Author : Stephan Maka %%% Purpose : XEP-0191: Simple Communications Blocking %%% Created : 24 Aug 2008 by Stephan Maka %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_blocking). -behaviour(gen_mod). -export([start/2, stop/1, process_iq/3, process_iq_set/4, process_iq_get/5]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_privacy.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), ejabberd_hooks:add(privacy_iq_get, Host, ?MODULE, process_iq_get, 40), ejabberd_hooks:add(privacy_iq_set, Host, ?MODULE, process_iq_set, 40), mod_disco:register_feature(Host, ?NS_BLOCKING), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING, ?MODULE, process_iq, IQDisc). stop(Host) -> ejabberd_hooks:delete(privacy_iq_get, Host, ?MODULE, process_iq_get, 40), ejabberd_hooks:delete(privacy_iq_set, Host, ?MODULE, process_iq_set, 40), mod_disco:unregister_feature(Host, ?NS_BLOCKING), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING). process_iq(_From, _To, IQ) -> SubEl = IQ#iq.sub_el, IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}. process_iq_get(_, From, _To, #iq{xmlns = ?NS_BLOCKING, sub_el = {xmlelement, "blocklist", _, _}}, _) -> #jid{luser = LUser, lserver = LServer} = From, {stop, process_blocklist_get(LUser, LServer)}; process_iq_get(Acc, _, _, _, _) -> Acc. process_iq_set(_, From, _To, #iq{xmlns = ?NS_BLOCKING, sub_el = {xmlelement, SubElName, _, SubEls}}) -> #jid{luser = LUser, lserver = LServer} = From, Res = case {SubElName, xml:remove_cdata(SubEls)} of {"block", []} -> {error, ?ERR_BAD_REQUEST}; {"block", Els} -> JIDs = parse_blocklist_items(Els, []), process_blocklist_block(LUser, LServer, JIDs); {"unblock", []} -> process_blocklist_unblock_all(LUser, LServer); {"unblock", Els} -> JIDs = parse_blocklist_items(Els, []), process_blocklist_unblock(LUser, LServer, JIDs); _ -> {error, ?ERR_BAD_REQUEST} end, {stop, Res}; process_iq_set(Acc, _, _, _) -> Acc. is_list_needdb(Items) -> lists:any( fun(X) -> case X#listitem.type of subscription -> true; group -> true; _ -> false end end, Items). list_to_blocklist_jids([], JIDs) -> JIDs; list_to_blocklist_jids([#listitem{type = jid, action = deny, value = JID} = Item | Items], JIDs) -> case Item of #listitem{match_all = true} -> Match = true; #listitem{match_iq = true, match_message = true, match_presence_in = true, match_presence_out = true} -> Match = true; _ -> Match = false end, if Match -> list_to_blocklist_jids(Items, [JID | JIDs]); true -> list_to_blocklist_jids(Items, JIDs) end; % Skip Privacy List items than cannot be mapped to Blocking items list_to_blocklist_jids([_ | Items], JIDs) -> list_to_blocklist_jids(Items, JIDs). parse_blocklist_items([], JIDs) -> JIDs; parse_blocklist_items([{xmlelement, "item", Attrs, _} | Els], JIDs) -> case xml:get_attr("jid", Attrs) of {value, JID1} -> JID = jlib:jid_tolower(jlib:string_to_jid(JID1)), parse_blocklist_items(Els, [JID | JIDs]); false -> % Tolerate missing jid attribute parse_blocklist_items(Els, JIDs) end; parse_blocklist_items([_ | Els], JIDs) -> % Tolerate unknown elements parse_blocklist_items(Els, JIDs). process_blocklist_block(LUser, LServer, JIDs) -> F = fun() -> case mnesia:wread({privacy, {LUser, LServer}}) of [] -> % No lists yet P = #privacy{us = {LUser, LServer}}, % TODO: i18n here: NewDefault = "Blocked contacts", NewLists1 = [], List = []; [#privacy{default = Default, lists = Lists} = P] -> case lists:keysearch(Default, 1, Lists) of {value, {_, List}} -> % Default list exists NewDefault = Default, NewLists1 = lists:keydelete(Default, 1, Lists); false -> % No default list yet, create one % TODO: i18n here: NewDefault = "Blocked contacts", NewLists1 = Lists, List = [] end end, AlreadyBlocked = list_to_blocklist_jids(List, []), NewList = lists:foldr(fun(JID, List1) -> case lists:member(JID, AlreadyBlocked) of true -> List1; false -> [#listitem{type = jid, value = JID, action = deny, order = 0, match_all = true } | List1] end end, List, JIDs), NewLists = [{NewDefault, NewList} | NewLists1], mnesia:write(P#privacy{default = NewDefault, lists = NewLists}), {ok, NewDefault, NewList} end, case mnesia:transaction(F) of {atomic, {error, _} = Error} -> Error; {atomic, {ok, Default, List}} -> UserList = make_userlist(Default, List), broadcast_list_update(LUser, LServer, Default, UserList), broadcast_blocklist_event(LUser, LServer, {block, JIDs}), {result, [], UserList}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. process_blocklist_unblock_all(LUser, LServer) -> F = fun() -> case mnesia:read({privacy, {LUser, LServer}}) of [] -> % No lists, nothing to unblock ok; [#privacy{default = Default, lists = Lists} = P] -> case lists:keysearch(Default, 1, Lists) of {value, {_, List}} -> % Default list, remove all deny items NewList = lists:filter( fun(#listitem{action = A}) -> A =/= deny end, List), NewLists1 = lists:keydelete(Default, 1, Lists), NewLists = [{Default, NewList} | NewLists1], mnesia:write(P#privacy{lists = NewLists}), {ok, Default, NewList}; false -> % No default list, nothing to unblock ok end end end, case mnesia:transaction(F) of {atomic, {error, _} = Error} -> Error; {atomic, ok} -> {result, []}; {atomic, {ok, Default, List}} -> UserList = make_userlist(Default, List), broadcast_list_update(LUser, LServer, Default, UserList), broadcast_blocklist_event(LUser, LServer, unblock_all), {result, [], UserList}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. process_blocklist_unblock(LUser, LServer, JIDs) -> F = fun() -> case mnesia:read({privacy, {LUser, LServer}}) of [] -> % No lists, nothing to unblock ok; [#privacy{default = Default, lists = Lists} = P] -> case lists:keysearch(Default, 1, Lists) of {value, {_, List}} -> % Default list, remove matching deny items NewList = lists:filter( fun(#listitem{action = deny, type = jid, value = JID}) -> not(lists:member(JID, JIDs)); (_) -> true end, List), NewLists1 = lists:keydelete(Default, 1, Lists), NewLists = [{Default, NewList} | NewLists1], mnesia:write(P#privacy{lists = NewLists}), {ok, Default, NewList}; false -> % No default list, nothing to unblock ok end end end, case mnesia:transaction(F) of {atomic, {error, _} = Error} -> Error; {atomic, ok} -> {result, []}; {atomic, {ok, Default, List}} -> UserList = make_userlist(Default, List), broadcast_list_update(LUser, LServer, Default, UserList), broadcast_blocklist_event(LUser, LServer, {unblock, JIDs}), {result, [], UserList}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. make_userlist(Name, List) -> NeedDb = is_list_needdb(List), #userlist{name = Name, list = List, needdb = NeedDb}. broadcast_list_update(LUser, LServer, Name, UserList) -> ejabberd_router:route( jlib:make_jid(LUser, LServer, ""), jlib:make_jid(LUser, LServer, ""), {xmlelement, "broadcast", [], [{privacy_list, UserList, Name}]}). broadcast_blocklist_event(LUser, LServer, Event) -> JID = jlib:make_jid(LUser, LServer, ""), ejabberd_router:route( JID, JID, {xmlelement, "broadcast", [], [{blocking, Event}]}). process_blocklist_get(LUser, LServer) -> case catch mnesia:dirty_read(privacy, {LUser, LServer}) of {'EXIT', _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; [] -> {result, [{xmlelement, "blocklist", [{"xmlns", ?NS_BLOCKING}], []}]}; [#privacy{default = Default, lists = Lists}] -> case lists:keysearch(Default, 1, Lists) of {value, {_, List}} -> JIDs = list_to_blocklist_jids(List, []), Items = lists:map( fun(JID) -> ?DEBUG("JID: ~p",[JID]), {xmlelement, "item", [{"jid", jlib:jid_to_string(JID)}], []} end, JIDs), {result, [{xmlelement, "blocklist", [{"xmlns", ?NS_BLOCKING}], Items}]}; _ -> {result, [{xmlelement, "blocklist", [{"xmlns", ?NS_BLOCKING}], []}]} end end. ejabberd-2.1.11/src/dynamic_compile.erl0000664000000000000000000003304612240230175014653 0ustar %% Copyright (c) 2007 %% Mats Cronqvist %% Chris Newcombe %% Jacob Vorreuter %% %% Permission is hereby granted, free of charge, to any person %% obtaining a copy of this software and associated documentation %% files (the "Software"), to deal in the Software without %% restriction, including without limitation the rights to use, %% copy, modify, merge, publish, distribute, sublicense, and/or sell %% copies of the Software, and to permit persons to whom the %% Software is furnished to do so, subject to the following %% conditions: %% %% The above copyright notice and this permission notice shall be %% included in all copies or substantial portions of the Software. %% %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, %% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES %% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND %% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT %% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, %% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING %% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR %% OTHER DEALINGS IN THE SOFTWARE. %%%------------------------------------------------------------------- %%% File : dynamic_compile.erl %%% Description : %%% Authors : Mats Cronqvist %%% Chris Newcombe %%% Jacob Vorreuter %%% TODO : %%% - add support for limit include-file depth (and prevent circular references) %%% prevent circular macro expansion set FILE correctly when -module() is found %%% -include_lib support $ENVVAR in include filenames %%% substitute-stringize (??MACRO) %%% -undef/-ifdef/-ifndef/-else/-endif %%% -file(File, Line) %%%------------------------------------------------------------------- -module(dynamic_compile). %% API -export([from_string/1, from_string/2]). -import(lists, [reverse/1, keyreplace/4]). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: %% Description: %% Returns a binary that can be used with %% code:load_binary(Module, ModuleFilenameForInternalRecords, Binary). %%-------------------------------------------------------------------- from_string(CodeStr) -> from_string(CodeStr, []). % takes Options as for compile:forms/2 from_string(CodeStr, CompileFormsOptions) -> %% Initialise the macro dictionary with the default predefined macros, %% (adapted from epp.erl:predef_macros/1 Filename = "compiled_from_string", %%Machine = list_to_atom(erlang:system_info(machine)), Ms0 = dict:new(), % Ms1 = dict:store('FILE', {[], "compiled_from_string"}, Ms0), % Ms2 = dict:store('LINE', {[], 1}, Ms1), % actually we might add special code for this % Ms3 = dict:store('MODULE', {[], undefined}, Ms2), % Ms4 = dict:store('MODULE_STRING', {[], undefined}, Ms3), % Ms5 = dict:store('MACHINE', {[], Machine}, Ms4), % InitMD = dict:store(Machine, {[], true}, Ms5), InitMD = Ms0, %% From the docs for compile:forms: %% When encountering an -include or -include_dir directive, the compiler searches for header files in the following directories: %% 1. ".", the current working directory of the file server; %% 2. the base name of the compiled file; %% 3. the directories specified using the i option. The directory specified last is searched first. %% In this case, #2 is meaningless. IncludeSearchPath = ["." | reverse([Dir || {i, Dir} <- CompileFormsOptions])], {RevForms, _OutMacroDict} = scan_and_parse(CodeStr, Filename, 1, [], InitMD, IncludeSearchPath), Forms = reverse(RevForms), %% note: 'binary' is forced as an implicit option, whether it is provided or not. case compile:forms(Forms, CompileFormsOptions) of {ok, ModuleName, CompiledCodeBinary} when is_binary(CompiledCodeBinary) -> {ModuleName, CompiledCodeBinary}; {ok, ModuleName, CompiledCodeBinary, []} when is_binary(CompiledCodeBinary) -> % empty warnings list {ModuleName, CompiledCodeBinary}; {ok, _ModuleName, _CompiledCodeBinary, Warnings} -> throw({?MODULE, warnings, Warnings}); Other -> throw({?MODULE, compile_forms, Other}) end. %%==================================================================== %% Internal functions %%==================================================================== %%% Code from Mats Cronqvist %%% See http://www.erlang.org/pipermail/erlang-questions/2007-March/025507.html %%%## 'scan_and_parse' %%% %%% basically we call the OTP scanner and parser (erl_scan and %%% erl_parse) line-by-line, but check each scanned line for (or %%% definitions of) macros before parsing. %% returns {ReverseForms, FinalMacroDict} scan_and_parse([], _CurrFilename, _CurrLine, RevForms, MacroDict, _IncludeSearchPath) -> {RevForms, MacroDict}; scan_and_parse(RemainingText, CurrFilename, CurrLine, RevForms, MacroDict, IncludeSearchPath) -> case scanner(RemainingText, CurrLine, MacroDict) of {tokens, NLine, NRemainingText, Toks} -> {ok, Form} = erl_parse:parse_form(Toks), scan_and_parse(NRemainingText, CurrFilename, NLine, [Form | RevForms], MacroDict, IncludeSearchPath); {macro, NLine, NRemainingText, NMacroDict} -> scan_and_parse(NRemainingText, CurrFilename, NLine, RevForms,NMacroDict, IncludeSearchPath); {include, NLine, NRemainingText, IncludeFilename} -> IncludeFileRemainingTextents = read_include_file(IncludeFilename, IncludeSearchPath), %%io:format("include file ~p contents: ~n~p~nRemainingText = ~p~n", [IncludeFilename,IncludeFileRemainingTextents, RemainingText]), %% Modify the FILE macro to reflect the filename %%IncludeMacroDict = dict:store('FILE', {[],IncludeFilename}, MacroDict), IncludeMacroDict = MacroDict, %% Process the header file (inc. any nested header files) {RevIncludeForms, IncludedMacroDict} = scan_and_parse(IncludeFileRemainingTextents, IncludeFilename, 1, [], IncludeMacroDict, IncludeSearchPath), %io:format("include file results = ~p~n", [R]), %% Restore the FILE macro in the NEW MacroDict (so we keep any macros defined in the header file) %%NMacroDict = dict:store('FILE', {[],CurrFilename}, IncludedMacroDict), NMacroDict = IncludedMacroDict, %% Continue with the original file scan_and_parse(NRemainingText, CurrFilename, NLine, RevIncludeForms ++ RevForms, NMacroDict, IncludeSearchPath); done -> scan_and_parse([], CurrFilename, CurrLine, RevForms, MacroDict, IncludeSearchPath) end. scanner(Text, Line, MacroDict) -> case erl_scan:tokens([],Text,Line) of {done, {ok,Toks,NLine}, LeftOverChars} -> case pre_proc(Toks, MacroDict) of {tokens, NToks} -> {tokens, NLine, LeftOverChars, NToks}; {macro, NMacroDict} -> {macro, NLine, LeftOverChars, NMacroDict}; {include, Filename} -> {include, NLine, LeftOverChars, Filename} end; {more, _Continuation} -> %% This is supposed to mean "term is not yet complete" (i.e. a '.' has %% not been reached yet). %% However, for some bizarre reason we also get this if there is a comment after the final '.' in a file. %% So we check to see if Text only consists of comments. case is_only_comments(Text) of true -> done; false -> throw({incomplete_term, Text, Line}) end end. is_only_comments(Text) -> is_only_comments(Text, not_in_comment). is_only_comments([], _) -> true; is_only_comments([$ |T], not_in_comment) -> is_only_comments(T, not_in_comment); % skipping whitspace outside of comment is_only_comments([$\t |T], not_in_comment) -> is_only_comments(T, not_in_comment); % skipping whitspace outside of comment is_only_comments([$\n |T], not_in_comment) -> is_only_comments(T, not_in_comment); % skipping whitspace outside of comment is_only_comments([$% |T], not_in_comment) -> is_only_comments(T, in_comment); % found start of a comment is_only_comments(_, not_in_comment) -> false; % found any significant char NOT in a comment is_only_comments([$\n |T], in_comment) -> is_only_comments(T, not_in_comment); % found end of a comment is_only_comments([_ |T], in_comment) -> is_only_comments(T, in_comment). % skipping over in-comment chars %%%## 'pre-proc' %%% %%% have to implement a subset of the pre-processor, since epp insists %%% on running on a file. %%% only handles 2 cases; %% -define(MACRO, something). %% -define(MACRO(VAR1,VARN),{stuff,VAR1,more,stuff,VARN,extra,stuff}). pre_proc([{'-',_},{atom,_,define},{'(',_},{_,_,Name}|DefToks],MacroDict) -> false = dict:is_key(Name, MacroDict), case DefToks of [{',',_} | Macro] -> {macro, dict:store(Name, {[], macro_body_def(Macro, [])}, MacroDict)}; [{'(',_} | Macro] -> {macro, dict:store(Name, macro_params_body_def(Macro, []), MacroDict)} end; pre_proc([{'-',_}, {atom,_,include}, {'(',_}, {string,_,Filename}, {')',_}, {dot,_}], _MacroDict) -> {include, Filename}; pre_proc(Toks,MacroDict) -> {tokens, subst_macros(Toks, MacroDict)}. macro_params_body_def([{')',_},{',',_} | Toks], RevParams) -> {reverse(RevParams), macro_body_def(Toks, [])}; macro_params_body_def([{var,_,Param} | Toks], RevParams) -> macro_params_body_def(Toks, [Param | RevParams]); macro_params_body_def([{',',_}, {var,_,Param} | Toks], RevParams) -> macro_params_body_def(Toks, [Param | RevParams]). macro_body_def([{')',_}, {dot,_}], RevMacroBodyToks) -> reverse(RevMacroBodyToks); macro_body_def([Tok|Toks], RevMacroBodyToks) -> macro_body_def(Toks, [Tok | RevMacroBodyToks]). subst_macros(Toks, MacroDict) -> reverse(subst_macros_rev(Toks, MacroDict, [])). %% returns a reversed list of tokes subst_macros_rev([{'?',_}, {_,LineNum,'LINE'} | Toks], MacroDict, RevOutToks) -> %% special-case for ?LINE, to avoid creating a new MacroDict for every line in the source file subst_macros_rev(Toks, MacroDict, [{integer,LineNum,LineNum}] ++ RevOutToks); subst_macros_rev([{'?',_}, {_,_,Name}, {'(',_} = Paren | Toks], MacroDict, RevOutToks) -> case dict:fetch(Name, MacroDict) of {[], MacroValue} -> %% This macro does not have any vars, so ignore the fact that the invocation is followed by "(...stuff" %% Recursively expand any macro calls inside this macro's value %% TODO: avoid infinite expansion due to circular references (even indirect ones) RevExpandedOtherMacrosToks = subst_macros_rev(MacroValue, MacroDict, []), subst_macros_rev([Paren|Toks], MacroDict, RevExpandedOtherMacrosToks ++ RevOutToks); ParamsAndBody -> %% This macro does have vars. %% Collect all of the passe arguments, in an ordered list {NToks, Arguments} = subst_macros_get_args(Toks, []), %% Expand the varibles ExpandedParamsToks = subst_macros_subst_args_for_vars(ParamsAndBody, Arguments), %% Recursively expand any macro calls inside this macro's value %% TODO: avoid infinite expansion due to circular references (even indirect ones) RevExpandedOtherMacrosToks = subst_macros_rev(ExpandedParamsToks, MacroDict, []), subst_macros_rev(NToks, MacroDict, RevExpandedOtherMacrosToks ++ RevOutToks) end; subst_macros_rev([{'?',_}, {_,_,Name} | Toks], MacroDict, RevOutToks) -> %% This macro invocation does not have arguments. %% Therefore the definition should not have parameters {[], MacroValue} = dict:fetch(Name, MacroDict), %% Recursively expand any macro calls inside this macro's value %% TODO: avoid infinite expansion due to circular references (even indirect ones) RevExpandedOtherMacrosToks = subst_macros_rev(MacroValue, MacroDict, []), subst_macros_rev(Toks, MacroDict, RevExpandedOtherMacrosToks ++ RevOutToks); subst_macros_rev([Tok|Toks], MacroDict, RevOutToks) -> subst_macros_rev(Toks, MacroDict, [Tok|RevOutToks]); subst_macros_rev([], _MacroDict, RevOutToks) -> RevOutToks. subst_macros_get_args([{')',_} | Toks], RevArgs) -> {Toks, reverse(RevArgs)}; subst_macros_get_args([{',',_}, {var,_,ArgName} | Toks], RevArgs) -> subst_macros_get_args(Toks, [ArgName| RevArgs]); subst_macros_get_args([{var,_,ArgName} | Toks], RevArgs) -> subst_macros_get_args(Toks, [ArgName | RevArgs]). subst_macros_subst_args_for_vars({[], BodyToks}, []) -> BodyToks; subst_macros_subst_args_for_vars({[Param | Params], BodyToks}, [Arg|Args]) -> NBodyToks = keyreplace(Param, 3, BodyToks, {var,1,Arg}), subst_macros_subst_args_for_vars({Params, NBodyToks}, Args). read_include_file(Filename, IncludeSearchPath) -> case file:path_open(IncludeSearchPath, Filename, [read, raw, binary]) of {ok, IoDevice, FullName} -> {ok, Data} = file:read(IoDevice, filelib:file_size(FullName)), file:close(IoDevice), binary_to_list(Data); {error, Reason} -> throw({failed_to_read_include_file, Reason, Filename, IncludeSearchPath}) end.ejabberd-2.1.11/src/mod_sic.erl0000664000000000000000000000575312240230175013140 0ustar %%%---------------------------------------------------------------------- %%% File : mod_sic.erl %%% Author : Karim Gemayel %%% Purpose : XEP-0279 Server IP Check %%% Created : 6 Mar 2010 by Karim Gemayel %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_sic). -author('karim.gemayel@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_local_iq/3, process_sm_iq/3 ]). -include("ejabberd.hrl"). -include("jlib.hrl"). -define(NS_SIC, "urn:xmpp:sic:0"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC, ?MODULE, process_local_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_SIC, ?MODULE, process_sm_iq, IQDisc). stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_SIC), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_SIC). process_local_iq(#jid{user = User, server = Server, resource = Resource}, _To, #iq{type = 'get', sub_el = _SubEl} = IQ) -> get_ip({User, Server, Resource}, IQ); process_local_iq(_From, _To, #iq{type = 'set', sub_el = SubEl} = IQ) -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}. process_sm_iq(#jid{user = User, server = Server, resource = Resource}, #jid{user = User, server = Server}, #iq{type = 'get', sub_el = _SubEl} = IQ) -> get_ip({User, Server, Resource}, IQ); process_sm_iq(_From, _To, #iq{type = 'get', sub_el = SubEl} = IQ) -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}; process_sm_iq(_From, _To, #iq{type = 'set', sub_el = SubEl} = IQ) -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}. get_ip({User, Server, Resource}, #iq{sub_el = {xmlelement, Name, Attrs, _} = SubEl} = IQ) -> case ejabberd_sm:get_user_ip(User, Server, Resource) of {IP, _} when is_tuple(IP) -> IQ#iq{ type = 'result', sub_el = [ {xmlelement, Name, Attrs, [{xmlcdata, list_to_binary(inet_parse:ntoa(IP))}]} ] }; _ -> IQ#iq{ type = 'error', sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR] } end. ejabberd-2.1.11/src/ejabberd_auth_anonymous.erl0000664000000000000000000001730612240230175016407 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_auth_anonymous.erl %%% Author : Mickael Remond %%% Purpose : Anonymous feature support in ejabberd %%% Created : 17 Feb 2006 by Mickael Remond %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_auth_anonymous). -author('mickael.remond@process-one.net'). -export([start/1, allow_anonymous/1, is_sasl_anonymous_enabled/1, is_login_anonymous_enabled/1, anonymous_user_exist/2, allow_multiple_connections/1, register_connection/3, unregister_connection/3 ]). %% Function used by ejabberd_auth: -export([login/2, set_password/3, check_password/3, check_password/5, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_password/2, get_password/3, is_user_exists/2, remove_user/2, remove_user/3, store_type/0, plain_password_required/0]). -include("ejabberd.hrl"). -include("jlib.hrl"). -record(anonymous, {us, sid}). %% Create the anonymous table if at least one virtual host has anonymous features enabled %% Register to login / logout events start(Host) -> %% TODO: Check cluster mode mnesia:create_table(anonymous, [{ram_copies, [node()]}, {type, bag}, {attributes, record_info(fields, anonymous)}]), %% The hooks are needed to add / remove users from the anonymous tables ejabberd_hooks:add(sm_register_connection_hook, Host, ?MODULE, register_connection, 100), ejabberd_hooks:add(sm_remove_connection_hook, Host, ?MODULE, unregister_connection, 100), ok. %% Return true if anonymous is allowed for host or false otherwise allow_anonymous(Host) -> lists:member(?MODULE, ejabberd_auth:auth_modules(Host)). %% Return true if anonymous mode is enabled and if anonymous protocol is SASL %% anonymous protocol can be: sasl_anon|login_anon|both is_sasl_anonymous_enabled(Host) -> case allow_anonymous(Host) of false -> false; true -> case anonymous_protocol(Host) of sasl_anon -> true; both -> true; _Other -> false end end. %% Return true if anonymous login is enabled on the server %% anonymous login can be use using standard authentication method (i.e. with %% clients that do not support anonymous login) is_login_anonymous_enabled(Host) -> case allow_anonymous(Host) of false -> false; true -> case anonymous_protocol(Host) of login_anon -> true; both -> true; _Other -> false end end. %% Return the anonymous protocol to use: sasl_anon|login_anon|both %% defaults to login_anon anonymous_protocol(Host) -> case ejabberd_config:get_local_option({anonymous_protocol, Host}) of sasl_anon -> sasl_anon; login_anon -> login_anon; both -> both; _Other -> sasl_anon end. %% Return true if multiple connections have been allowed in the config file %% defaults to false allow_multiple_connections(Host) -> ejabberd_config:get_local_option( {allow_multiple_connections, Host}) =:= true. %% Check if user exist in the anonymus database anonymous_user_exist(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, case catch mnesia:dirty_read({anonymous, US}) of [] -> false; [_H|_T] -> true end. %% Remove connection from Mnesia tables remove_connection(SID, LUser, LServer) -> US = {LUser, LServer}, F = fun() -> mnesia:delete_object({anonymous, US, SID}) end, mnesia:transaction(F). %% Register connection register_connection(SID, #jid{luser = LUser, lserver = LServer}, Info) -> AuthModule = xml:get_attr_s(auth_module, Info), case AuthModule == ?MODULE of true -> ejabberd_hooks:run(register_user, LServer, [LUser, LServer]), US = {LUser, LServer}, mnesia:sync_dirty( fun() -> mnesia:write(#anonymous{us = US, sid=SID}) end); false -> ok end. %% Remove an anonymous user from the anonymous users table unregister_connection(SID, #jid{luser = LUser, lserver = LServer}, _) -> purge_hook(anonymous_user_exist(LUser, LServer), LUser, LServer), remove_connection(SID, LUser, LServer). %% Launch the hook to purge user data only for anonymous users purge_hook(false, _LUser, _LServer) -> ok; purge_hook(true, LUser, LServer) -> ejabberd_hooks:run(anonymous_purge_hook, LServer, [LUser, LServer]). %% --------------------------------- %% Specific anonymous auth functions %% --------------------------------- %% When anonymous login is enabled, check the password for permenant users %% before allowing access check_password(User, Server, Password) -> check_password(User, Server, Password, undefined, undefined). check_password(User, Server, _Password, _Digest, _DigestGen) -> %% We refuse login for registered accounts (They cannot logged but %% they however are "reserved") case ejabberd_auth:is_user_exists_in_other_modules(?MODULE, User, Server) of %% If user exists in other module, reject anonnymous authentication true -> false; %% If we are not sure whether the user exists in other module, reject anon auth maybe -> false; false -> login(User, Server) end. login(User, Server) -> case is_login_anonymous_enabled(Server) of false -> false; true -> case anonymous_user_exist(User, Server) of %% Reject the login if an anonymous user with the same login %% is already logged and if multiple login has not been enable %% in the config file. true -> allow_multiple_connections(Server); %% Accept login and add user to the anonymous table false -> true end end. %% When anonymous login is enabled, check that the user is permanent before %% changing its password set_password(User, Server, _Password) -> case anonymous_user_exist(User, Server) of true -> ok; false -> {error, not_allowed} end. %% When anonymous login is enabled, check if permanent users are allowed on %% the server: try_register(_User, _Server, _Password) -> {error, not_allowed}. dirty_get_registered_users() -> []. get_vh_registered_users(Server) -> [{U, S} || {U, S, _R} <- ejabberd_sm:get_vh_session_list(Server)]. %% Return password of permanent user or false for anonymous users get_password(User, Server) -> get_password(User, Server, ""). get_password(User, Server, DefaultValue) -> case anonymous_user_exist(User, Server) or login(User, Server) of %% We return the default value if the user is anonymous true -> DefaultValue; %% We return the permanent user password otherwise false -> false end. %% Returns true if the user exists in the DB or if an anonymous user is logged %% under the given name is_user_exists(User, Server) -> anonymous_user_exist(User, Server). remove_user(_User, _Server) -> {error, not_allowed}. remove_user(_User, _Server, _Password) -> not_allowed. plain_password_required() -> false. store_type() -> plain. ejabberd-2.1.11/src/configure.ac0000664000000000000000000001217212240230175013276 0ustar # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.53) AC_INIT(ejabberd, m4_esyscmd([grep -o -E "\{vsn,.\".*\"\}" ejabberd.app | cut -d \" -f 2 | tr -d '\n']), [ejabberd@process-one.net], [ejabberd]) # Checks for programs. AC_PROG_CC AC_PROG_MAKE_SET if test "x$GCC" = "xyes"; then CFLAGS="$CFLAGS -Wall" fi #locating erlang AM_WITH_ERLANG #locating iconv AM_ICONV #locating libexpat AM_WITH_EXPAT # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST # Check Erlang headers are installed #AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])]) # Change default prefix AC_PREFIX_DEFAULT(/) # Checks for library functions. AC_FUNC_MALLOC AC_HEADER_STDC AC_MOD_ENABLE(mod_irc, yes) AC_MOD_ENABLE(mod_muc, yes) AC_MOD_ENABLE(mod_proxy65, yes) AC_MOD_ENABLE(mod_pubsub, yes) AC_MOD_ENABLE(eldap, yes) AC_MOD_ENABLE(odbc, no) AC_MOD_ENABLE(tls, yes) AC_MOD_ENABLE(web, yes) AC_MOD_ENABLE(ejabberd_zlib, yes) #locating zlib AM_WITH_ZLIB AC_MOD_ENABLE(pam, no) #locating PAM AM_WITH_PAM AC_ARG_ENABLE(hipe, [AC_HELP_STRING([--enable-hipe], [compile natively with HiPE, not recommended (default: no)])], [case "${enableval}" in yes) hipe=true ;; no) hipe=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-hipe) ;; esac],[hipe=false]) AC_SUBST(hipe) AC_ARG_ENABLE(roster_gateway_workaround, [AC_HELP_STRING([--enable-roster-gateway-workaround], [turn on workaround for processing gateway subscriptions (default: no)])], [case "${enableval}" in yes) roster_gateway_workaround=true ;; no) roster_gateway_workaround=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-roster-gateway-workaround) ;; esac],[roster_gateway_workaround=false]) AC_SUBST(roster_gateway_workaround) AC_ARG_ENABLE(mssql, [AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])], [case "${enableval}" in yes) db_type=mssql ;; no) db_type=generic ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-mssql) ;; esac],[db_type=generic]) AC_SUBST(db_type) AC_ARG_ENABLE(transient_supervisors, [AC_HELP_STRING([--enable-transient_supervisors], [use Erlang supervision for transient process (default: yes)])], [case "${enableval}" in yes) transient_supervisors=true ;; no) transient_supervisors=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-transient_supervisors) ;; esac],[transient_supervisors=true]) AC_SUBST(transient_supervisors) AC_ARG_ENABLE(full_xml, [AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])], [case "${enableval}" in yes) full_xml=true ;; no) full_xml=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-full-xml) ;; esac],[full_xml=false]) AC_SUBST(full_xml) AC_ARG_ENABLE(nif, [AC_HELP_STRING([--enable-nif], [replace some functions with C equivalents. Requires Erlang R13B04 or higher (default: no)])], [case "${enableval}" in yes) nif=true ;; no) nif=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-nif) ;; esac],[nif=false]) AC_SUBST(nif) AC_CONFIG_FILES([Makefile $make_mod_irc $make_mod_muc $make_mod_pubsub $make_mod_proxy65 $make_eldap $make_pam $make_web stringprep/Makefile stun/Makefile $make_tls $make_odbc $make_ejabberd_zlib]) #openssl AM_WITH_OPENSSL # If ssl is kerberized it need krb5.h # On RedHat and OpenBSD, krb5.h is in an unsual place: KRB5_INCLUDE="`krb5-config --cflags 2>/dev/null`" if test -n "$KRB5_INCLUDE" ; then CPPFLAGS="$CPPFLAGS $KRB5_INCLUDE" else # For RedHat For BSD for D in /usr/kerberos/include /usr/include/kerberos /usr/include/kerberosV do if test -d $D ; then CPPFLAGS="$CPPFLAGS -I$D" fi done fi AC_CHECK_HEADER(krb5.h,,) ENABLEUSER="" AC_ARG_ENABLE(user, [AS_HELP_STRING([--enable-user[[[[=USER]]]]], [allow this system user to start ejabberd (default: no)])], [case "${enableval}" in yes) ENABLEUSER=`whoami` ;; no) ENABLEUSER="" ;; *) ENABLEUSER=$enableval esac], []) if test "$ENABLEUSER" != ""; then echo "allow this system user to start ejabberd: $ENABLEUSER" AC_SUBST([INSTALLUSER], [$ENABLEUSER]) fi AC_CHECK_HEADER(openssl/md2.h, md2=true, md2=false) AC_SUBST(md2) AC_CANONICAL_SYSTEM #AC_DEFINE_UNQUOTED(CPU_VENDOR_OS, "$target") #AC_SUBST(target_os) case "$target_os" in *darwin10*) echo "Target OS is 'Darwin10'" AC_LANG(Erlang) AC_RUN_IFELSE( [AC_LANG_PROGRAM([],[dnl halt(case erlang:system_info(wordsize) of 8 -> 0; 4 -> 1 end)])], [AC_MSG_NOTICE(found 64-bit Erlang) CBIT=-m64], [AC_MSG_NOTICE(found 32-bit Erlang) CBIT=-m32]) ;; *) echo "Target OS is '$target_os'" CBIT="" ;; esac CFLAGS="$CFLAGS $CBIT" LD_SHARED="$LD_SHARED $CBIT" echo "CBIT is set to '$CBIT'" AC_OUTPUT ejabberd-2.1.11/src/gen_mod.erl0000664000000000000000000001551612240230175013131 0ustar %%%---------------------------------------------------------------------- %%% File : gen_mod.erl %%% Author : Alexey Shchepin %%% Purpose : %%% Created : 24 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(gen_mod). -author('alexey@process-one.net'). -export([start/0, start_module/3, stop_module/2, stop_module_keep_config/2, get_opt/2, get_opt/3, get_opt_host/3, get_module_opt/4, get_module_opt_host/3, loaded_modules/1, loaded_modules_with_opts/1, get_hosts/2, get_module_proc/2, is_loaded/2]). -export([behaviour_info/1]). -include("ejabberd.hrl"). -record(ejabberd_module, {module_host, opts}). behaviour_info(callbacks) -> [{start, 2}, {stop, 1}]; behaviour_info(_Other) -> undefined. start() -> ets:new(ejabberd_modules, [named_table, public, {keypos, #ejabberd_module.module_host}]), ok. start_module(Host, Module, Opts) -> set_module_opts_mnesia(Host, Module, Opts), ets:insert(ejabberd_modules, #ejabberd_module{module_host = {Module, Host}, opts = Opts}), try Module:start(Host, Opts) catch Class:Reason -> del_module_mnesia(Host, Module), ets:delete(ejabberd_modules, {Module, Host}), ErrorText = io_lib:format("Problem starting the module ~p for host ~p ~n options: ~p~n ~p: ~p", [Module, Host, Opts, Class, Reason]), ?CRITICAL_MSG(ErrorText, []), case is_app_running(ejabberd) of true -> erlang:raise(Class, Reason, erlang:get_stacktrace()); false -> ?CRITICAL_MSG("ejabberd initialization was aborted because a module start failed.", []), timer:sleep(3000), erlang:halt(string:substr(lists:flatten(ErrorText), 1, 199)) end end. is_app_running(AppName) -> %% Use a high timeout to prevent a false positive in a high load system Timeout = 15000, lists:keymember(AppName, 1, application:which_applications(Timeout)). %% @doc Stop the module in a host, and forget its configuration. stop_module(Host, Module) -> case stop_module_keep_config(Host, Module) of error -> error; ok -> del_module_mnesia(Host, Module) end. %% @doc Stop the module in a host, but keep its configuration. %% As the module configuration is kept in the Mnesia local_config table, %% when ejabberd is restarted the module will be started again. %% This function is useful when ejabberd is being stopped %% and it stops all modules. stop_module_keep_config(Host, Module) -> case catch Module:stop(Host) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]), error; {wait, ProcList} when is_list(ProcList) -> lists:foreach(fun wait_for_process/1, ProcList), ets:delete(ejabberd_modules, {Module, Host}), ok; {wait, Process} -> wait_for_process(Process), ets:delete(ejabberd_modules, {Module, Host}), ok; _ -> ets:delete(ejabberd_modules, {Module, Host}), ok end. wait_for_process(Process) -> MonitorReference = erlang:monitor(process, Process), wait_for_stop(Process, MonitorReference). wait_for_stop(Process, MonitorReference) -> receive {'DOWN', MonitorReference, _Type, _Object, _Info} -> ok after 5000 -> catch exit(whereis(Process), kill), wait_for_stop1(MonitorReference) end. wait_for_stop1(MonitorReference) -> receive {'DOWN', MonitorReference, _Type, _Object, _Info} -> ok after 5000 -> ok end. get_opt(Opt, Opts) -> case lists:keysearch(Opt, 1, Opts) of false -> % TODO: replace with more appropriate function throw({undefined_option, Opt}); {value, {_, Val}} -> Val end. get_opt(Opt, Opts, Default) -> case lists:keysearch(Opt, 1, Opts) of false -> Default; {value, {_, Val}} -> Val end. get_module_opt(global, Module, Opt, Default) -> Hosts = ?MYHOSTS, [Value | Values] = lists:map( fun(Host) -> get_module_opt(Host, Module, Opt, Default) end, Hosts), Same_all = lists:all( fun(Other_value) -> Other_value == Value end, Values), case Same_all of true -> Value; false -> Default end; get_module_opt(Host, Module, Opt, Default) -> OptsList = ets:lookup(ejabberd_modules, {Module, Host}), case OptsList of [] -> Default; [#ejabberd_module{opts = Opts} | _] -> get_opt(Opt, Opts, Default) end. get_module_opt_host(Host, Module, Default) -> Val = get_module_opt(Host, Module, host, Default), ejabberd_regexp:greplace(Val, "@HOST@", Host). get_opt_host(Host, Opts, Default) -> Val = get_opt(host, Opts, Default), ejabberd_regexp:greplace(Val, "@HOST@", Host). loaded_modules(Host) -> ets:select(ejabberd_modules, [{#ejabberd_module{_ = '_', module_host = {'$1', Host}}, [], ['$1']}]). loaded_modules_with_opts(Host) -> ets:select(ejabberd_modules, [{#ejabberd_module{_ = '_', module_host = {'$1', Host}, opts = '$2'}, [], [{{'$1', '$2'}}]}]). set_module_opts_mnesia(Host, Module, Opts) -> Modules = case ejabberd_config:get_local_option({modules, Host}) of undefined -> []; Ls -> Ls end, Modules1 = lists:keydelete(Module, 1, Modules), Modules2 = [{Module, Opts} | Modules1], ejabberd_config:add_local_option({modules, Host}, Modules2). del_module_mnesia(Host, Module) -> Modules = case ejabberd_config:get_local_option({modules, Host}) of undefined -> []; Ls -> Ls end, Modules1 = lists:keydelete(Module, 1, Modules), ejabberd_config:add_local_option({modules, Host}, Modules1). get_hosts(Opts, Prefix) -> case catch gen_mod:get_opt(hosts, Opts) of {'EXIT', _Error1} -> case catch gen_mod:get_opt(host, Opts) of {'EXIT', _Error2} -> [Prefix ++ Host || Host <- ?MYHOSTS]; Host -> [Host] end; Hosts -> Hosts end. get_module_proc(Host, {frontend, Base}) -> get_module_proc("frontend_" ++ Host, Base); get_module_proc(Host, Base) -> list_to_atom(atom_to_list(Base) ++ "_" ++ Host). is_loaded(Host, Module) -> ets:member(ejabberd_modules, {Module, Host}). ejabberd-2.1.11/src/mod_irc/0000775000000000000000000000000012240452476012433 5ustar ejabberd-2.1.11/src/mod_irc/Makefile.win320000664000000000000000000000233012240230175015020 0ustar include ..\Makefile.inc EFLAGS = -I .. -pz .. OUTDIR = .. BEAMS = ..\iconv.beam ..\mod_irc.beam ..\mod_irc_odbc.beam ..\mod_irc_connection.beam SOURCE = iconv_erl.c OBJECT = iconv_erl.o DLL = $(OUTDIR)\iconv_erl.dll ALL : $(DLL) $(BEAMS) CLEAN : -@erase $(DLL) -@erase $(OUTDIR)\iconv_erl.exp -@erase $(OUTDIR)\iconv_erl.lib -@erase $(OBJECT) -@erase $(BEAMS) $(OUTDIR)\iconv.beam : iconv.erl erlc -W $(EFLAGS) -o $(OUTDIR) iconv.erl $(OUTDIR)\mod_irc.beam : mod_irc.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_irc.erl $(OUTDIR)\mod_irc_odbc.beam : mod_irc_odbc.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_irc_odbc.erl $(OUTDIR)\mod_irc_connection.beam : mod_irc_connection.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_irc_connection.erl CC=cl.exe CC_FLAGS=-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -MD -Ox -I"$(ERLANG_DIR)\usr\include" -I"$(EI_DIR)\include" -I"$(ICONV_DIR)\include" LD=link.exe LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" "$(ICONV_LIB)" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib $(DLL) : $(OBJECT) $(LD) $(LD_FLAGS) -out:$@ $< $(OBJECT) : $(SOURCE) $(CC) $(CC_FLAGS) -c -Fo$@ $< ejabberd-2.1.11/src/mod_irc/iconv_erl.c0000664000000000000000000001212412240230175014545 0ustar /* * ejabberd, Copyright (C) 2002-2012 ProcessOne * * 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., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * */ #include #include #include #include #include /* * R15B changed several driver callbacks to use ErlDrvSizeT and * ErlDrvSSizeT typedefs instead of int. * This provides missing typedefs on older OTP versions. */ #if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 typedef int ErlDrvSizeT; typedef int ErlDrvSSizeT; #endif typedef struct { ErlDrvPort port; iconv_t cd; } iconv_data; static ErlDrvData iconv_erl_start(ErlDrvPort port, char *buff) { iconv_data* d = (iconv_data*)driver_alloc(sizeof(iconv_data)); d->port = port; d->cd = NULL; set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); return (ErlDrvData)d; } static void iconv_erl_stop(ErlDrvData handle) { driver_free((char*)handle); } static ErlDrvSSizeT iconv_erl_control(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { int i; int size; int index = 0; int avail; size_t inleft, outleft; ErlDrvBinary *b; char *from, *to, *string, *stmp, *rstring, *rtmp; iconv_t cd; int invalid_utf8_as_latin1 = 0; ei_decode_version(buf, &index, &i); ei_decode_tuple_header(buf, &index, &i); ei_get_type(buf, &index, &i, &size); from = driver_alloc(size + 1); ei_decode_string(buf, &index, from); ei_get_type(buf, &index, &i, &size); to = driver_alloc(size + 1); ei_decode_string(buf, &index, to); ei_get_type(buf, &index, &i, &size); stmp = string = driver_alloc(size + 1); ei_decode_string(buf, &index, string); /* Special mode: parse as UTF-8 if possible; otherwise assume it's Latin-1. Makes no difference when encoding. */ if (strcmp(from, "utf-8+latin-1") == 0) { from[5] = '\0'; invalid_utf8_as_latin1 = 1; } if (strcmp(to, "utf-8+latin-1") == 0) { to[5] = '\0'; } cd = iconv_open(to, from); if (cd == (iconv_t) -1) { cd = iconv_open("ascii", "ascii"); if (cd == (iconv_t) -1) { *rbuf = (char*)(b = driver_alloc_binary(size)); memcpy(b->orig_bytes, string, size); driver_free(from); driver_free(to); driver_free(string); return size; } } outleft = avail = 4*size; inleft = size; rtmp = rstring = driver_alloc(avail); while (inleft > 0) { if (iconv(cd, &stmp, &inleft, &rtmp, &outleft) == (size_t) -1) { if (invalid_utf8_as_latin1 && (*stmp & 0x80) && outleft >= 2) { /* Encode one byte of (assumed) Latin-1 into two bytes of UTF-8 */ *rtmp++ = 0xc0 | ((*stmp & 0xc0) >> 6); *rtmp++ = 0x80 | (*stmp & 0x3f); outleft -= 2; } stmp++; inleft--; } } size = rtmp - rstring; *rbuf = (char*)(b = driver_alloc_binary(size)); memcpy(b->orig_bytes, rstring, size); driver_free(from); driver_free(to); driver_free(string); driver_free(rstring); iconv_close(cd); return size; } ErlDrvEntry iconv_driver_entry = { NULL, /* F_PTR init, N/A */ iconv_erl_start, /* L_PTR start, called when port is opened */ iconv_erl_stop, /* F_PTR stop, called when port is closed */ NULL, /* F_PTR output, called when erlang has sent */ NULL, /* F_PTR ready_input, called when input descriptor ready */ NULL, /* F_PTR ready_output, called when output descriptor ready */ "iconv_erl", /* char *driver_name, the argument to open_port */ NULL, /* F_PTR finish, called when unloaded */ NULL, /* handle */ iconv_erl_control, /* F_PTR control, port_command callback */ NULL, /* F_PTR timeout, reserved */ NULL, /* F_PTR outputv, reserved */ /* Added in Erlang/OTP R15B: */ NULL, /* ready_async */ NULL, /* flush */ NULL, /* call */ NULL, /* event */ ERL_DRV_EXTENDED_MARKER, /* extended_marker */ ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ 0, /* driver_flags */ NULL, /* handle2 */ NULL, /* process_exit */ NULL /* stop_select */ }; DRIVER_INIT(iconv_erl) /* must match name in driver_entry */ { return &iconv_driver_entry; } ejabberd-2.1.11/src/mod_irc/mod_irc.erl0000664000000000000000000010361512240230175014547 0ustar %%%---------------------------------------------------------------------- %%% File : mod_irc.erl %%% Author : Alexey Shchepin %%% Purpose : IRC transport %%% Created : 15 Feb 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_irc). -author('alexey@process-one.net'). -behaviour(gen_server). -behaviour(gen_mod). %% API -export([start_link/2, start/2, stop/1, closed_connection/3, get_connection_params/3]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("adhoc.hrl"). -define(DEFAULT_IRC_ENCODING, "iso8859-1"). -define(DEFAULT_IRC_PORT, 6667). -define(POSSIBLE_ENCODINGS, ["koi8-r", "iso8859-1", "iso8859-2", "utf-8", "utf-8+latin-1"]). -record(irc_connection, {jid_server_host, pid}). -record(irc_custom, {us_host, data}). -record(state, {host, server_host, access}). -define(PROCNAME, ejabberd_mod_irc). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host, Opts) -> start_supervisor(Host), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, temporary, 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> stop_supervisor(Host), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:call(Proc, stop), supervisor:delete_child(ejabberd_sup, Proc). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([Host, Opts]) -> iconv:start(), mnesia:create_table(irc_custom, [{disc_copies, [node()]}, {attributes, record_info(fields, irc_custom)}]), MyHost = gen_mod:get_opt_host(Host, Opts, "irc.@HOST@"), update_table(MyHost), Access = gen_mod:get_opt(access, Opts, all), catch ets:new(irc_connection, [named_table, public, {keypos, #irc_connection.jid_server_host}]), ejabberd_router:register_route(MyHost), {ok, #state{host = MyHost, server_host = Host, access = Access}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call(stop, _From, State) -> {stop, normal, ok, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({route, From, To, Packet}, #state{host = Host, server_host = ServerHost, access = Access} = State) -> case catch do_route(Host, ServerHost, Access, From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); _ -> ok end, {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, State) -> ejabberd_router:unregister_route(State#state.host), ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- start_supervisor(Host) -> Proc = gen_mod:get_module_proc(Host, ejabberd_mod_irc_sup), ChildSpec = {Proc, {ejabberd_tmp_sup, start_link, [Proc, mod_irc_connection]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop_supervisor(Host) -> Proc = gen_mod:get_module_proc(Host, ejabberd_mod_irc_sup), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). do_route(Host, ServerHost, Access, From, To, Packet) -> case acl:match_rule(ServerHost, Access, From) of allow -> do_route1(Host, ServerHost, From, To, Packet); _ -> {xmlelement, _Name, Attrs, _Els} = Packet, Lang = xml:get_attr_s("xml:lang", Attrs), ErrText = "Access denied by service policy", Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, ErrText)), ejabberd_router:route(To, From, Err) end. do_route1(Host, ServerHost, From, To, Packet) -> #jid{user = ChanServ, resource = Resource} = To, {xmlelement, _Name, _Attrs, _Els} = Packet, case ChanServ of "" -> case Resource of "" -> case jlib:iq_query_info(Packet) of #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS, sub_el = SubEl, lang = Lang} = IQ -> Node = xml:get_tag_attr_s("node", SubEl), Info = ejabberd_hooks:run_fold( disco_info, ServerHost, [], [ServerHost, ?MODULE, "", ""]), case iq_disco(Node, Lang) of [] -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], []}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); DiscoInfo -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], DiscoInfo ++ Info}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)) end; #iq{type = get, xmlns = ?NS_DISCO_ITEMS = XMLNS, sub_el = SubEl, lang = Lang} = IQ -> Node = xml:get_tag_attr_s("node", SubEl), case Node of [] -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], []}]}, Res = jlib:iq_to_xml(ResIQ); "join" -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], []}]}, Res = jlib:iq_to_xml(ResIQ); "register" -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], []}]}, Res = jlib:iq_to_xml(ResIQ); ?NS_COMMANDS -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}, {"node", Node}], command_items(Host, Lang)}]}, Res = jlib:iq_to_xml(ResIQ); _ -> Res = jlib:make_error_reply( Packet, ?ERR_ITEM_NOT_FOUND) end, ejabberd_router:route(To, From, Res); #iq{xmlns = ?NS_REGISTER} = IQ -> process_register(Host, From, To, IQ); #iq{type = get, xmlns = ?NS_VCARD = XMLNS, lang = Lang} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", XMLNS}], iq_get_vcard(Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{type = set, xmlns = ?NS_COMMANDS, lang = _Lang, sub_el = SubEl} = IQ -> Request = adhoc:parse_request(IQ), case lists:keysearch(Request#adhoc_request.node, 1, commands()) of {value, {_, _, Function}} -> case catch Function(From, To, Request) of {'EXIT', Reason} -> ?ERROR_MSG("~p~nfor ad-hoc handler of ~p", [Reason, {From, To, IQ}]), Res = IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; ignore -> Res = ignore; {error, Error} -> Res = IQ#iq{type = error, sub_el = [SubEl, Error]}; Command -> Res = IQ#iq{type = result, sub_el = [Command]} end, if Res /= ignore -> ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); true -> ok end; _ -> Err = jlib:make_error_reply( Packet, ?ERR_ITEM_NOT_FOUND), ejabberd_router:route(To, From, Err) end; #iq{} = _IQ -> Err = jlib:make_error_reply( Packet, ?ERR_FEATURE_NOT_IMPLEMENTED), ejabberd_router:route(To, From, Err); _ -> ok end; _ -> Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST), ejabberd_router:route(To, From, Err) end; _ -> case string:tokens(ChanServ, "%") of [[_ | _] = Channel, [_ | _] = Server] -> case ets:lookup(irc_connection, {From, Server, Host}) of [] -> ?DEBUG("open new connection~n", []), {Username, Encoding, Port, Password} = get_connection_params( Host, ServerHost, From, Server), ConnectionUsername = case Packet of %% If the user tries to join a %% chatroom, the packet for sure %% contains the desired username. {xmlelement, "presence", _, _} -> Resource; %% Otherwise, there is no firm %% conclusion from the packet. %% Better to use the configured %% username (which defaults to the %% username part of the JID). _ -> Username end, {ok, Pid} = mod_irc_connection:start( From, Host, ServerHost, Server, ConnectionUsername, Encoding, Port, Password, ?MODULE), ets:insert( irc_connection, #irc_connection{jid_server_host = {From, Server, Host}, pid = Pid}), mod_irc_connection:route_chan( Pid, Channel, Resource, Packet), ok; [R] -> Pid = R#irc_connection.pid, ?DEBUG("send to process ~p~n", [Pid]), mod_irc_connection:route_chan( Pid, Channel, Resource, Packet), ok end; _ -> case string:tokens(ChanServ, "!") of [[_ | _] = Nick, [_ | _] = Server] -> case ets:lookup(irc_connection, {From, Server, Host}) of [] -> Err = jlib:make_error_reply( Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err); [R] -> Pid = R#irc_connection.pid, ?DEBUG("send to process ~p~n", [Pid]), mod_irc_connection:route_nick( Pid, Nick, Packet), ok end; _ -> Err = jlib:make_error_reply( Packet, ?ERR_BAD_REQUEST), ejabberd_router:route(To, From, Err) end end end. closed_connection(Host, From, Server) -> ets:delete(irc_connection, {From, Server, Host}). iq_disco([], Lang) -> [{xmlelement, "identity", [{"category", "conference"}, {"type", "irc"}, {"name", translate:translate(Lang, "IRC Transport")}], []}, {xmlelement, "feature", [{"var", ?NS_DISCO_INFO}], []}, {xmlelement, "feature", [{"var", ?NS_MUC}], []}, {xmlelement, "feature", [{"var", ?NS_REGISTER}], []}, {xmlelement, "feature", [{"var", ?NS_VCARD}], []}, {xmlelement, "feature", [{"var", ?NS_COMMANDS}], []}]; iq_disco(Node, Lang) -> case lists:keysearch(Node, 1, commands()) of {value, {_, Name, _}} -> [{xmlelement, "identity", [{"category", "automation"}, {"type", "command-node"}, {"name", translate:translate(Lang, Name)}], []}, {xmlelement, "feature", [{"var", ?NS_COMMANDS}], []}, {xmlelement, "feature", [{"var", ?NS_XDATA}], []}]; _ -> [] end. iq_get_vcard(Lang) -> [{xmlelement, "FN", [], [{xmlcdata, "ejabberd/mod_irc"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate(Lang, "ejabberd IRC module") ++ "\nCopyright (c) 2003-2012 ProcessOne"}]}]. command_items(Host, Lang) -> lists:map(fun({Node, Name, _Function}) -> {xmlelement, "item", [{"jid", Host}, {"node", Node}, {"name", translate:translate(Lang, Name)}], []} end, commands()). commands() -> [{"join", "Join channel", fun adhoc_join/3}, {"register", "Configure username, encoding, port and password", fun adhoc_register/3}]. process_register(Host, From, To, #iq{} = IQ) -> case catch process_irc_register(Host, From, To, IQ) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); ResIQ -> if ResIQ /= ignore -> ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); true -> ok end end. find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) -> find_xdata_el1(SubEls). find_xdata_el1([]) -> false; find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_XDATA -> {xmlelement, Name, Attrs, SubEls}; _ -> find_xdata_el1(Els) end; find_xdata_el1([_ | Els]) -> find_xdata_el1(Els). process_irc_register(Host, From, _To, #iq{type = Type, xmlns = XMLNS, lang = Lang, sub_el = SubEl} = IQ) -> case Type of set -> XDataEl = find_xdata_el(SubEl), case XDataEl of false -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ACCEPTABLE]}; {xmlelement, _Name, Attrs, _SubEls} -> case xml:get_attr_s("type", Attrs) of "cancel" -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], []}]}; "submit" -> XData = jlib:parse_xdata_submit(XDataEl), case XData of invalid -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}; _ -> Node = string:tokens( xml:get_tag_attr_s("node", SubEl), "/"), case set_form( Host, From, Node, Lang, XData) of {result, Res} -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], Res }]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end end; _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]} end end; get -> Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"), case get_form(Host, From, Node, Lang) of {result, Res} -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], Res }]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end end. get_form(Host, From, [], Lang) -> #jid{user = User, server = Server, luser = LUser, lserver = LServer} = From, US = {LUser, LServer}, DefaultEncoding = get_default_encoding(Host), Customs = case catch mnesia:dirty_read({irc_custom, {US, Host}}) of {'EXIT', _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; [] -> {User, []}; [#irc_custom{data = Data}] -> {xml:get_attr_s(username, Data), xml:get_attr_s(connections_params, Data)} end, case Customs of {error, _Error} -> Customs; {Username, ConnectionsParams} -> {result, [{xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "You need an x:data capable client " "to configure mod_irc settings")}]}, {xmlelement, "x", [{"xmlns", ?NS_XDATA}], [{xmlelement, "title", [], [{xmlcdata, translate:translate( Lang, "Registration in mod_irc for ") ++ User ++ "@" ++ Server}]}, {xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers")}]}, {xmlelement, "field", [{"type", "text-single"}, {"label", translate:translate( Lang, "IRC Username")}, {"var", "username"}], [{xmlelement, "value", [], [{xmlcdata, Username}]}]}, {xmlelement, "field", [{"type", "fixed"}], [{xmlelement, "value", [], [{xmlcdata, lists:flatten( io_lib:format( translate:translate( Lang, "If you want to specify different ports, " "passwords, encodings for IRC servers, fill " "this list with values in format " "'{\"irc server\", \"encoding\", port, \"password\"}'. " "By default this service use \"~s\" encoding, port ~p, " "empty password."), [DefaultEncoding, ?DEFAULT_IRC_PORT]))}]}]}, {xmlelement, "field", [{"type", "fixed"}], [{xmlelement, "value", [], [{xmlcdata, translate:translate( Lang, "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, " "{\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." )}]}]}, {xmlelement, "field", [{"type", "text-multi"}, {"label", translate:translate(Lang, "Connections parameters")}, {"var", "connections_params"}], lists:map( fun(S) -> {xmlelement, "value", [], [{xmlcdata, S}]} end, string:tokens( lists:flatten( io_lib:format("~p.", [ConnectionsParams])), "\n")) } ]}]} end; get_form(_Host, _, _, _Lang) -> {error, ?ERR_SERVICE_UNAVAILABLE}. set_form(Host, From, [], _Lang, XData) -> {LUser, LServer, _} = jlib:jid_tolower(From), US = {LUser, LServer}, case {lists:keysearch("username", 1, XData), lists:keysearch("connections_params", 1, XData)} of {{value, {_, [Username]}}, {value, {_, Strings}}} -> EncString = lists:foldl(fun(S, Res) -> Res ++ S ++ "\n" end, "", Strings), case erl_scan:string(EncString) of {ok, Tokens, _} -> case erl_parse:parse_term(Tokens) of {ok, ConnectionsParams} -> case mnesia:transaction( fun() -> mnesia:write( #irc_custom{us_host = {US, Host}, data = [{username, Username}, {connections_params, ConnectionsParams}]}) end) of {atomic, _} -> {result, []}; _ -> {error, ?ERR_NOT_ACCEPTABLE} end; _ -> {error, ?ERR_NOT_ACCEPTABLE} end; _ -> {error, ?ERR_NOT_ACCEPTABLE} end; _ -> {error, ?ERR_NOT_ACCEPTABLE} end; set_form(_Host, _, _, _Lang, _XData) -> {error, ?ERR_SERVICE_UNAVAILABLE}. %% Host = "irc.example.com" %% ServerHost = "example.com" get_connection_params(Host, From, IRCServer) -> [_ | HostTail] = string:tokens(Host, "."), ServerHost = string:join(HostTail, "."), get_connection_params(Host, ServerHost, From, IRCServer). get_default_encoding(ServerHost) -> Result = gen_mod:get_module_opt( ServerHost, ?MODULE, default_encoding, ?DEFAULT_IRC_ENCODING), ?INFO_MSG("The default_encoding configured for host ~p is: ~p~n", [ServerHost, Result]), Result. get_connection_params(Host, ServerHost, From, IRCServer) -> #jid{user = User, server = _Server, luser = LUser, lserver = LServer} = From, US = {LUser, LServer}, DefaultEncoding = get_default_encoding(ServerHost), case catch mnesia:dirty_read({irc_custom, {US, Host}}) of {'EXIT', _Reason} -> {User, DefaultEncoding, ?DEFAULT_IRC_PORT, ""}; [] -> {User, DefaultEncoding, ?DEFAULT_IRC_PORT, ""}; [#irc_custom{data = Data}] -> Username = xml:get_attr_s(username, Data), {NewUsername, NewEncoding, NewPort, NewPassword} = case lists:keysearch(IRCServer, 1, xml:get_attr_s(connections_params, Data)) of {value, {_, Encoding, Port, Password}} -> {Username, Encoding, Port, Password}; {value, {_, Encoding, Port}} -> {Username, Encoding, Port, ""}; {value, {_, Encoding}} -> {Username, Encoding, ?DEFAULT_IRC_PORT, ""}; _ -> {Username, DefaultEncoding, ?DEFAULT_IRC_PORT, ""} end, {NewUsername, NewEncoding, if NewPort >= 0 andalso NewPort =< 65535 -> NewPort; true -> ?DEFAULT_IRC_PORT end, NewPassword} end. adhoc_join(_From, _To, #adhoc_request{action = "cancel"} = Request) -> adhoc:produce_response(Request, #adhoc_response{status = canceled}); adhoc_join(From, To, #adhoc_request{lang = Lang, node = _Node, action = _Action, xdata = XData} = Request) -> %% Access control has already been taken care of in do_route. if XData == false -> Form = {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "Join IRC channel")}]}, {xmlelement, "field", [{"var", "channel"}, {"type", "text-single"}, {"label", translate:translate(Lang, "IRC channel (don't put the first #)")}], [{xmlelement, "required", [], []}]}, {xmlelement, "field", [{"var", "server"}, {"type", "text-single"}, {"label", translate:translate(Lang, "IRC server")}], [{xmlelement, "required", [], []}]}]}, adhoc:produce_response(Request, #adhoc_response{status = executing, elements = [Form]}); true -> case jlib:parse_xdata_submit(XData) of invalid -> {error, ?ERR_BAD_REQUEST}; Fields -> Channel = case lists:keysearch("channel", 1, Fields) of {value, {"channel", C}} -> C; _ -> false end, Server = case lists:keysearch("server", 1, Fields) of {value, {"server", S}} -> S; _ -> false end, if Channel /= false, Server /= false -> RoomJID = Channel ++ "%" ++ Server ++ "@" ++ To#jid.server, Invite = {xmlelement, "message", [], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "invite", [{"from", jlib:jid_to_string(From)}], [{xmlelement, "reason", [], [{xmlcdata, translate:translate(Lang, "Join the IRC channel here.")}]}]}]}, {xmlelement, "x", [{"xmlns", ?NS_XCONFERENCE}], [{xmlcdata, translate:translate(Lang, "Join the IRC channel here.")}]}, {xmlelement, "body", [], [{xmlcdata, io_lib:format( translate:translate(Lang, "Join the IRC channel in this Jabber ID: ~s"), [RoomJID])}]}]}, ejabberd_router:route(jlib:string_to_jid(RoomJID), From, Invite), adhoc:produce_response(Request, #adhoc_response{status = completed}); true -> {error, ?ERR_BAD_REQUEST} end end end. adhoc_register(_From, _To, #adhoc_request{action = "cancel"} = Request) -> adhoc:produce_response(Request, #adhoc_response{status = canceled}); adhoc_register(From, To, #adhoc_request{lang = Lang, node = _Node, xdata = XData, action = Action} = Request) -> #jid{user = User, luser = LUser, lserver = LServer} = From, #jid{lserver = Host} = To, US = {LUser, LServer}, %% Generate form for setting username and encodings. If the user %% hasn't begun to fill out the form, generate an initial form %% based on current values. if XData == false -> case catch mnesia:dirty_read({irc_custom, {US, Host}}) of {'EXIT', _Reason} -> Username = User, ConnectionsParams = []; [] -> Username = User, ConnectionsParams = []; [#irc_custom{data = Data}] -> Username = xml:get_attr_s(username, Data), ConnectionsParams = xml:get_attr_s(connections_params, Data) end, Error = false; true -> case jlib:parse_xdata_submit(XData) of invalid -> Error = {error, ?ERR_BAD_REQUEST}, Username = false, ConnectionsParams = false; Fields -> Username = case lists:keysearch("username", 1, Fields) of {value, {"username", U}} -> U; _ -> User end, ConnectionsParams = parse_connections_params(Fields), Error = false end end, if Error /= false -> Error; Action == "complete" -> case mnesia:transaction( fun () -> mnesia:write( #irc_custom{us_host = {US, Host}, data = [{username, Username}, {connections_params, ConnectionsParams}]}) end) of {atomic, _} -> adhoc:produce_response(Request, #adhoc_response{status = completed}); _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end; true -> Form = generate_adhoc_register_form(Lang, Username, ConnectionsParams), adhoc:produce_response(Request, #adhoc_response{status = executing, elements = [Form], actions = ["next", "complete"]}) end. generate_adhoc_register_form(Lang, Username, ConnectionsParams) -> {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "IRC settings")}]}, {xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "Enter username and encodings you wish to use for " "connecting to IRC servers. Press 'Next' to get more fields " "to fill in. Press 'Complete' to save settings.")}]}, {xmlelement, "field", [{"var", "username"}, {"type", "text-single"}, {"label", translate:translate(Lang, "IRC username")}], [{xmlelement, "required", [], []}, {xmlelement, "value", [], [{xmlcdata, Username}]}]}] ++ generate_connection_params_fields(Lang, ConnectionsParams, 1, [])}. generate_connection_params_fields(Lang, [], Number, Acc) -> Field = generate_connection_params_field(Lang, "", "", -1, "", Number), lists:reverse(Field ++ Acc); generate_connection_params_fields(Lang, [ConnectionParams | ConnectionsParams], Number, Acc) -> case ConnectionParams of {Server, Encoding, Port, Password} -> Field = generate_connection_params_field(Lang, Server, Encoding, Port, Password, Number), generate_connection_params_fields(Lang, ConnectionsParams, Number + 1, Field ++ Acc); {Server, Encoding, Port} -> Field = generate_connection_params_field(Lang, Server, Encoding, Port, [], Number), generate_connection_params_fields(Lang, ConnectionsParams, Number + 1, Field ++ Acc); {Server, Encoding} -> Field = generate_connection_params_field(Lang, Server, Encoding, [], [], Number), generate_connection_params_fields(Lang, ConnectionsParams, Number + 1, Field ++ Acc); _ -> [] end. generate_connection_params_field(Lang, Server, Encoding, Port, Password, Number) -> EncodingUsed = case Encoding of [] -> get_default_encoding(Server); _ -> Encoding end, PortUsedInt = if Port >= 0 andalso Port =< 65535 -> Port; true -> ?DEFAULT_IRC_PORT end, PortUsed = integer_to_list(PortUsedInt), PasswordUsed = case Password of [] -> ""; _ -> Password end, NumberString = integer_to_list(Number), %% Fields are in reverse order, as they will be reversed again later. [{xmlelement, "field", [{"var", "password" ++ NumberString}, {"type", "text-single"}, {"label", io_lib:format(translate:translate(Lang, "Password ~b"), [Number])}], [{xmlelement, "value", [], [{xmlcdata, PasswordUsed}]}]}, {xmlelement, "field", [{"var", "port" ++ NumberString}, {"type", "text-single"}, {"label", io_lib:format(translate:translate(Lang, "Port ~b"), [Number])}], [{xmlelement, "value", [], [{xmlcdata, PortUsed}]}]}, {xmlelement, "field", [{"var", "encoding" ++ NumberString}, {"type", "list-single"}, {"label", io_lib:format(translate:translate(Lang, "Encoding for server ~b"), [Number])}], [{xmlelement, "value", [], [{xmlcdata, EncodingUsed}]} | lists:map(fun(E) -> {xmlelement, "option", [{"label", E}], [{xmlelement, "value", [], [{xmlcdata, E}]}]} end, ?POSSIBLE_ENCODINGS)]}, {xmlelement, "field", [{"var", "server" ++ NumberString}, {"type", "text-single"}, {"label", io_lib:format(translate:translate(Lang, "Server ~b"), [Number])}], [{xmlelement, "value", [], [{xmlcdata, Server}]}]}]. parse_connections_params(Fields) -> %% Find all fields staring with serverN, encodingN, portN and passwordN for any values %% of N, and generate lists of {"N", Value}. Servers = lists:sort( [{lists:nthtail(6, Var), lists:flatten(Value)} || {Var, Value} <- Fields, lists:prefix("server", Var)]), Encodings = lists:sort( [{lists:nthtail(8, Var), lists:flatten(Value)} || {Var, Value} <- Fields, lists:prefix("encoding", Var)]), Ports = lists:sort( [{lists:nthtail(4, Var), lists:flatten(Value)} || {Var, Value} <- Fields, lists:prefix("port", Var)]), Passwords = lists:sort( [{lists:nthtail(8, Var), lists:flatten(Value)} || {Var, Value} <- Fields, lists:prefix("password", Var)]), %% Now sort the lists, and find the corresponding pairs. parse_connections_params(Servers, Encodings, Ports, Passwords). retrieve_connections_params(ConnectionParams, ServerN) -> case ConnectionParams of [{ConnectionParamN, ConnectionParam} | ConnectionParamsTail] -> if ServerN == ConnectionParamN -> {ConnectionParam, ConnectionParamsTail}; ServerN < ConnectionParamN -> {[], [{ConnectionParamN, ConnectionParam} | ConnectionParamsTail]}; ServerN > ConnectionParamN -> {[], ConnectionParamsTail} end; _ -> {[], []} end. parse_connections_params([], _, _, _) -> []; parse_connections_params(_, [], [], []) -> []; parse_connections_params([{ServerN, Server} | Servers], Encodings, Ports, Passwords) -> %% Try to match matches of servers, ports, passwords and encodings, no matter what fields %% the client might have left out. {NewEncoding, NewEncodings} = retrieve_connections_params(Encodings, ServerN), {NewPort, NewPorts} = retrieve_connections_params(Ports, ServerN), {NewPassword, NewPasswords} = retrieve_connections_params(Passwords, ServerN), [{Server, NewEncoding, NewPort, NewPassword} | parse_connections_params(Servers, NewEncodings, NewPorts, NewPasswords)]. update_table(Host) -> Fields = record_info(fields, irc_custom), case mnesia:table_info(irc_custom, attributes) of Fields -> ok; [userserver, data] -> ?INFO_MSG("Converting irc_custom table from " "{userserver, data} format", []), {atomic, ok} = mnesia:create_table( mod_irc_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, irc_custom}, {attributes, record_info(fields, irc_custom)}]), mnesia:transform_table(irc_custom, ignore, Fields), F1 = fun() -> mnesia:write_lock_table(mod_irc_tmp_table), mnesia:foldl( fun(#irc_custom{us_host = US} = R, _) -> mnesia:dirty_write( mod_irc_tmp_table, R#irc_custom{us_host = {US, Host}}) end, ok, irc_custom) end, mnesia:transaction(F1), mnesia:clear_table(irc_custom), F2 = fun() -> mnesia:write_lock_table(irc_custom), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, mod_irc_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(mod_irc_tmp_table); _ -> ?INFO_MSG("Recreating irc_custom table", []), mnesia:transform_table(irc_custom, ignore, Fields) end. ejabberd-2.1.11/src/mod_irc/Makefile.in0000664000000000000000000000223312240230175014466 0ustar # $Id$ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ @LIBICONV@ ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ # Assume Linux-style dynamic library flags DYNAMIC_LIB_CFLAGS = -fpic -shared ifeq ($(shell uname),Darwin) DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress endif ifeq ($(shell uname),SunOs) DYNAMIC_LIB_CFLAGS = -KPIC -G -z text endif EFLAGS += -I .. EFLAGS += -pz .. # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif ERLSHLIBS = ../iconv_erl.so OUTDIR = .. SOURCES = $(wildcard *.erl) BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) all: $(BEAMS) $(ERLSHLIBS) $(OUTDIR)/%.beam: %.erl @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< #all: $(ERLSHLIBS) # erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt $(ERLSHLIBS): ../%.so: %.c $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) \ $(subst ../,,$(subst .so,.c,$@)) \ $(LIBS) \ $(ERLANG_CFLAGS) \ $(ERLANG_LIBS) \ -o $@ \ $(DYNAMIC_LIB_CFLAGS) clean: rm -f $(BEAMS) $(ERLSHLIBS) distclean: clean rm -f Makefile TAGS: etags *.erl ejabberd-2.1.11/src/mod_irc/mod_irc_connection.erl0000664000000000000000000012324212240230175016764 0ustar %%%---------------------------------------------------------------------- %%% File : mod_irc_connection.erl %%% Author : Alexey Shchepin %%% Purpose : %%% Created : 15 Feb 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_irc_connection). -author('alexey@process-one.net'). -behaviour(gen_fsm). %% External exports -export([start_link/8, start/9, route_chan/4, route_nick/3]). %% gen_fsm callbacks -export([init/1, open_socket/2, wait_for_registration/2, stream_established/2, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, code_change/4]). -include("ejabberd.hrl"). -include("jlib.hrl"). -define(SETS, gb_sets). -record(state, {socket, encoding, port, password, queue, user, host, server, nick, channels = dict:new(), nickchannel, mod, inbuf = "", outbuf = ""}). %-define(DBGFSM, true). -ifdef(DBGFSM). -define(FSMOPTS, [{debug, [trace]}]). -else. -define(FSMOPTS, []). -endif. %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start(From, Host, ServerHost, Server, Username, Encoding, Port, Password, Mod) -> Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_irc_sup), supervisor:start_child( Supervisor, [From, Host, Server, Username, Encoding, Port, Password, Mod]). start_link(From, Host, Server, Username, Encoding, Port, Password, Mod) -> gen_fsm:start_link(?MODULE, [From, Host, Server, Username, Encoding, Port, Password, Mod], ?FSMOPTS). %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, StateName, StateData} | %% {ok, StateName, StateData, Timeout} | %% ignore | %% {stop, StopReason} %%---------------------------------------------------------------------- init([From, Host, Server, Username, Encoding, Port, Password, Mod]) -> gen_fsm:send_event(self(), init), {ok, open_socket, #state{queue = queue:new(), mod = Mod, encoding = Encoding, port = Port, password = Password, user = From, nick = Username, host = Host, server = Server}}. %%---------------------------------------------------------------------- %% Func: StateName/2 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- open_socket(init, StateData) -> Addr = StateData#state.server, Port = StateData#state.port, ?DEBUG("Connecting with IPv6 to ~s:~p", [Addr, Port]), Connect6 = gen_tcp:connect(Addr, Port, [inet6, binary, {packet, 0}]), Connect = case Connect6 of {error, _} -> ?DEBUG("Connection with IPv6 to ~s:~p failed. Now using IPv4.", [Addr, Port]), gen_tcp:connect(Addr, Port, [inet, binary, {packet, 0}]); _ -> Connect6 end, case Connect of {ok, Socket} -> NewStateData = StateData#state{socket = Socket}, if StateData#state.password /= "" -> send_text(NewStateData, io_lib:format("PASS ~s\r\n", [StateData#state.password])); true -> true end, send_text(NewStateData, io_lib:format("NICK ~s\r\n", [StateData#state.nick])), send_text(NewStateData, io_lib:format( "USER ~s ~s ~s :~s\r\n", [StateData#state.nick, StateData#state.nick, StateData#state.host, StateData#state.nick])), {next_state, wait_for_registration, NewStateData}; {error, Reason} -> ?DEBUG("connect return ~p~n", [Reason]), Text = case Reason of timeout -> "Server Connect Timeout"; _ -> "Server Connect Failed" end, bounce_messages(Text), {stop, normal, StateData} end. wait_for_registration(closed, StateData) -> {stop, normal, StateData}. stream_established({xmlstreamend, _Name}, StateData) -> {stop, normal, StateData}; stream_established(timeout, StateData) -> {stop, normal, StateData}; stream_established(closed, StateData) -> {stop, normal, StateData}. %%---------------------------------------------------------------------- %% Func: StateName/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- %state_name(Event, From, StateData) -> % Reply = ok, % {reply, Reply, state_name, StateData}. %%---------------------------------------------------------------------- %% Func: handle_event/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- handle_sync_event(_Event, _From, StateName, StateData) -> Reply = ok, {reply, Reply, StateName, StateData}. code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. -define(SEND(S), if StateName == stream_established -> send_text(StateData, S), StateData; true -> StateData#state{outbuf = StateData#state.outbuf ++ S} end). get_password_from_presence({xmlelement, "presence", _Attrs, Els}) -> case lists:filter(fun(El) -> case El of {xmlelement, "x", Attrs, _Els} -> case xml:get_attr_s("xmlns", Attrs) of ?NS_MUC -> true; _ -> false end; _ -> false end end, Els) of [ElXMUC | _] -> case xml:get_subtag(ElXMUC, "password") of {xmlelement, "password", _, _} = PasswordTag -> {true, xml:get_tag_cdata(PasswordTag)}; _ -> false end; _ -> false end. %%---------------------------------------------------------------------- %% Func: handle_info/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_info({route_chan, Channel, Resource, {xmlelement, "presence", Attrs, _Els} = Presence}, StateName, StateData) -> NewStateData = case xml:get_attr_s("type", Attrs) of "unavailable" -> send_stanza_unavailable(Channel, StateData), S1 = ?SEND(io_lib:format("PART #~s\r\n", [Channel])), S1#state{channels = dict:erase(Channel, S1#state.channels)}; "subscribe" -> StateData; "subscribed" -> StateData; "unsubscribe" -> StateData; "unsubscribed" -> StateData; "error" -> stop; _ -> Nick = case Resource of "" -> StateData#state.nick; _ -> Resource end, S1 = if Nick /= StateData#state.nick -> S11 = ?SEND(io_lib:format("NICK ~s\r\n", [Nick])), % The server reply will change the copy of the % nick in the state (or indicate a clash). S11#state{nickchannel = Channel}; true -> StateData end, case dict:is_key(Channel, S1#state.channels) of true -> S1; _ -> case get_password_from_presence(Presence) of {true, Password} -> S2 = ?SEND(io_lib:format("JOIN #~s ~s\r\n", [Channel, Password])); _ -> S2 = ?SEND(io_lib:format("JOIN #~s\r\n", [Channel])) end, S2#state{channels = dict:store(Channel, ?SETS:new(), S1#state.channels)} end end, if NewStateData == stop -> {stop, normal, StateData}; true -> case dict:fetch_keys(NewStateData#state.channels) of [] -> {stop, normal, NewStateData}; _ -> {next_state, StateName, NewStateData} end end; handle_info({route_chan, Channel, Resource, {xmlelement, "message", Attrs, _Els} = El}, StateName, StateData) -> NewStateData = case xml:get_attr_s("type", Attrs) of "groupchat" -> case xml:get_path_s(El, [{elem, "subject"}, cdata]) of "" -> ejabberd_router:route( jlib:make_jid( lists:concat( [Channel, "%", StateData#state.server]), StateData#state.host, StateData#state.nick), StateData#state.user, El), Body = xml:get_path_s(El, [{elem, "body"}, cdata]), case Body of "/quote " ++ Rest -> ?SEND(Rest ++ "\r\n"); "/msg " ++ Rest -> ?SEND("PRIVMSG " ++ Rest ++ "\r\n"); "/me " ++ Rest -> Strings = string:tokens(Rest, "\n"), Res = lists:concat( lists:map( fun(S) -> io_lib:format( "PRIVMSG #~s :\001ACTION ~s\001\r\n", [Channel, S]) end, Strings)), ?SEND(Res); "/ctcp " ++ Rest -> Words = string:tokens(Rest, " "), case Words of [CtcpDest | _] -> CtcpCmd = toupper( string:substr( Rest, string:str(Rest, " ") + 1)), Res = io_lib:format( "PRIVMSG ~s :\001~s\001\r\n", [CtcpDest, CtcpCmd]), ?SEND(Res); _ -> ok end; _ -> Strings = string:tokens(Body, "\n"), Res = lists:concat( lists:map( fun(S) -> io_lib:format( "PRIVMSG #~s :~s\r\n", [Channel, S]) end, Strings)), ?SEND(Res) end; Subject -> Strings = string:tokens(Subject, "\n"), Res = lists:concat( lists:map( fun(S) -> io_lib:format("TOPIC #~s :~s\r\n", [Channel, S]) end, Strings)), ?SEND(Res) end; Type when Type == "chat"; Type == ""; Type == "normal" -> Body = xml:get_path_s(El, [{elem, "body"}, cdata]), case Body of "/quote " ++ Rest -> ?SEND(Rest ++ "\r\n"); "/msg " ++ Rest -> ?SEND("PRIVMSG " ++ Rest ++ "\r\n"); "/me " ++ Rest -> Strings = string:tokens(Rest, "\n"), Res = lists:concat( lists:map( fun(S) -> io_lib:format( "PRIVMSG ~s :\001ACTION ~s\001\r\n", [Resource, S]) end, Strings)), ?SEND(Res); "/ctcp " ++ Rest -> Words = string:tokens(Rest, " "), case Words of [CtcpDest | _ ] -> CtcpCmd = toupper( string:substr( Rest, string:str(Rest, " ") + 1)), Res = io_lib:format( "PRIVMSG ~s :~s\r\n", [CtcpDest, "\001" ++ CtcpCmd ++ "\001"]), ?SEND(Res); _ -> ok end; _ -> Strings = string:tokens(Body, "\n"), Res = lists:concat( lists:map( fun(S) -> io_lib:format("PRIVMSG ~s :~s\r\n", [Resource, S]) end, Strings)), ?SEND(Res) end; "error" -> stop; _ -> StateData end, if NewStateData == stop -> {stop, normal, StateData}; true -> {next_state, StateName, NewStateData} end; handle_info({route_chan, Channel, Resource, {xmlelement, "iq", _Attrs, _Els} = El}, StateName, StateData) -> From = StateData#state.user, To = jlib:make_jid(lists:concat([Channel, "%", StateData#state.server]), StateData#state.host, StateData#state.nick), _ = case jlib:iq_query_info(El) of #iq{xmlns = ?NS_MUC_ADMIN} = IQ -> iq_admin(StateData, Channel, From, To, IQ); #iq{xmlns = ?NS_VERSION} -> Res = io_lib:format("PRIVMSG ~s :\001VERSION\001\r\n", [Resource]), _ = ?SEND(Res), Err = jlib:make_error_reply( El, ?ERR_FEATURE_NOT_IMPLEMENTED), ejabberd_router:route(To, From, Err); #iq{xmlns = ?NS_TIME} -> Res = io_lib:format("PRIVMSG ~s :\001TIME\001\r\n", [Resource]), _ = ?SEND(Res), Err = jlib:make_error_reply( El, ?ERR_FEATURE_NOT_IMPLEMENTED), ejabberd_router:route(To, From, Err); #iq{xmlns = ?NS_VCARD} -> Res = io_lib:format("WHOIS ~s \r\n", [Resource]), _ = ?SEND(Res), Err = jlib:make_error_reply( El, ?ERR_FEATURE_NOT_IMPLEMENTED), ejabberd_router:route(To, From, Err); #iq{} -> Err = jlib:make_error_reply( El, ?ERR_FEATURE_NOT_IMPLEMENTED), ejabberd_router:route(To, From, Err); _ -> ok end, {next_state, StateName, StateData}; handle_info({route_chan, _Channel, _Resource, _Packet}, StateName, StateData) -> {next_state, StateName, StateData}; handle_info({route_nick, Nick, {xmlelement, "message", Attrs, _Els} = El}, StateName, StateData) -> NewStateData = case xml:get_attr_s("type", Attrs) of "chat" -> Body = xml:get_path_s(El, [{elem, "body"}, cdata]), case Body of "/quote " ++ Rest -> ?SEND(Rest ++ "\r\n"); "/msg " ++ Rest -> ?SEND("PRIVMSG " ++ Rest ++ "\r\n"); "/me " ++ Rest -> Strings = string:tokens(Rest, "\n"), Res = lists:concat( lists:map( fun(S) -> io_lib:format( "PRIVMSG ~s :\001ACTION ~s\001\r\n", [Nick, S]) end, Strings)), ?SEND(Res); "/ctcp " ++ Rest -> Words = string:tokens(Rest, " "), case Words of [CtcpDest | _ ] -> CtcpCmd = toupper(string:substr(Rest, string:str(Rest, " ")+1 )), Res = io_lib:format( "PRIVMSG ~s :~s\r\n", [CtcpDest, "\001" ++ CtcpCmd ++ "\001"]), ?SEND(Res); _ -> ok end; _ -> Strings = string:tokens(Body, "\n"), Res = lists:concat( lists:map( fun(S) -> io_lib:format("PRIVMSG ~s :~s\r\n", [Nick, S]) end, Strings)), ?SEND(Res) end; "error" -> stop; _ -> StateData end, if NewStateData == stop -> {stop, normal, StateData}; true -> {next_state, StateName, NewStateData} end; handle_info({route_nick, _Nick, _Packet}, StateName, StateData) -> {next_state, StateName, StateData}; handle_info({ircstring, [$P, $I, $N, $G, $ | ID]}, StateName, StateData) -> send_text(StateData, "PONG " ++ ID ++ "\r\n"), {next_state, StateName, StateData}; handle_info({ircstring, [$: | String]}, wait_for_registration, StateData) -> Words = string:tokens(String, " "), {NewState, NewStateData} = case Words of [_, "001" | _] -> send_text(StateData, io_lib:format("CODEPAGE ~s\r\n", [StateData#state.encoding])), {stream_established, StateData}; [_, "433" | _] -> {error, {error, error_nick_in_use(StateData, String), StateData}}; [_, [$4, _, _] | _] -> {error, {error, error_unknown_num(StateData, String, "cancel"), StateData}}; [_, [$5, _, _] | _] -> {error, {error, error_unknown_num(StateData, String, "cancel"), StateData}}; _ -> ?DEBUG("unknown irc command '~s'~n", [String]), {wait_for_registration, StateData} end, % Note that we don't send any data at this stage. if NewState == error -> {stop, normal, NewStateData}; true -> {next_state, NewState, NewStateData} end; handle_info({ircstring, [$: | String]}, _StateName, StateData) -> Words = string:tokens(String, " "), NewStateData = case Words of [_, "353" | Items] -> process_channel_list(StateData, Items); [_, "332", _Nick, [$# | Chan] | _] -> process_channel_topic(StateData, Chan, String), StateData; [_, "333", _Nick, [$# | Chan] | _] -> process_channel_topic_who(StateData, Chan, String), StateData; [_, "318", _, Nick | _] -> process_endofwhois(StateData, String, Nick), StateData; [_, "311", _, Nick, Ident, Irchost | _ ] -> process_whois311(StateData, String, Nick, Ident, Irchost), StateData; [_, "312", _, Nick, Ircserver | _ ] -> process_whois312(StateData, String, Nick, Ircserver), StateData; [_, "319", _, Nick | _ ] -> process_whois319(StateData, String, Nick), StateData; [_, "433" | _] -> process_nick_in_use(StateData, String); % CODEPAGE isn't standard, so don't complain if it's not there. [_, "421", _, "CODEPAGE" | _] -> StateData; [_, [$4, _, _] | _] -> process_num_error(StateData, String); [_, [$5, _, _] | _] -> process_num_error(StateData, String); [From, "PRIVMSG", [$# | Chan] | _] -> process_chanprivmsg(StateData, Chan, From, String), StateData; [From, "NOTICE", [$# | Chan] | _] -> process_channotice(StateData, Chan, From, String), StateData; [From, "PRIVMSG", Nick, ":\001VERSION\001" | _] -> process_version(StateData, Nick, From), StateData; [From, "PRIVMSG", Nick, ":\001USERINFO\001" | _] -> process_userinfo(StateData, Nick, From), StateData; [From, "PRIVMSG", Nick | _] -> process_privmsg(StateData, Nick, From, String), StateData; [From, "NOTICE", Nick | _] -> process_notice(StateData, Nick, From, String), StateData; [From, "TOPIC", [$# | Chan] | _] -> process_topic(StateData, Chan, From, String), StateData; [From, "PART", [$# | Chan] | _] -> process_part(StateData, Chan, From, String); [From, "QUIT" | _] -> process_quit(StateData, From, String); [From, "JOIN", Chan | _] -> process_join(StateData, Chan, From, String); [From, "MODE", [$# | Chan], "+o", Nick | _] -> process_mode_o(StateData, Chan, From, Nick, "admin", "moderator"), StateData; [From, "MODE", [$# | Chan], "-o", Nick | _] -> process_mode_o(StateData, Chan, From, Nick, "member", "participant"), StateData; [From, "KICK", [$# | Chan], Nick | _] -> process_kick(StateData, Chan, From, Nick, String), StateData; [From, "NICK", Nick | _] -> process_nick(StateData, From, Nick); _ -> ?DEBUG("unknown irc command '~s'~n", [String]), StateData end, NewStateData1 = case StateData#state.outbuf of "" -> NewStateData; Data -> send_text(NewStateData, Data), NewStateData#state{outbuf = ""} end, {next_state, stream_established, NewStateData1}; handle_info({ircstring, [$E, $R, $R, $O, $R | _] = String}, StateName, StateData) -> process_error(StateData, String), {next_state, StateName, StateData}; handle_info({ircstring, String}, StateName, StateData) -> ?DEBUG("unknown irc command '~s'~n", [String]), {next_state, StateName, StateData}; handle_info({send_text, Text}, StateName, StateData) -> send_text(StateData, Text), {next_state, StateName, StateData}; handle_info({tcp, _Socket, Data}, StateName, StateData) -> Buf = StateData#state.inbuf ++ binary_to_list(Data), Strings = ejabberd_regexp:split([C || C <- Buf, C /= $\r], "\n"), ?DEBUG("strings=~p~n", [Strings]), NewBuf = process_lines(StateData#state.encoding, Strings), {next_state, StateName, StateData#state{inbuf = NewBuf}}; handle_info({tcp_closed, _Socket}, StateName, StateData) -> gen_fsm:send_event(self(), closed), {next_state, StateName, StateData}; handle_info({tcp_error, _Socket, _Reason}, StateName, StateData) -> gen_fsm:send_event(self(), closed), {next_state, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: terminate/3 %% Purpose: Shutdown the fsm %% Returns: any %%---------------------------------------------------------------------- terminate(_Reason, _StateName, FullStateData) -> % Extract error message if there was one. {Error, StateData} = case FullStateData of {error, SError, SStateData} -> {SError, SStateData}; _ -> {{xmlelement, "error", [{"code", "502"}], [{xmlcdata, "Server Connect Failed"}]}, FullStateData} end, (FullStateData#state.mod):closed_connection(StateData#state.host, StateData#state.user, StateData#state.server), bounce_messages("Server Connect Failed"), lists:foreach( fun(Chan) -> Stanza = {xmlelement, "presence", [{"type", "error"}], [Error]}, send_stanza(Chan, StateData, Stanza) end, dict:fetch_keys(StateData#state.channels)), case StateData#state.socket of undefined -> ok; Socket -> gen_tcp:close(Socket) end, ok. send_stanza(Chan, StateData, Stanza) -> ejabberd_router:route( jlib:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, StateData#state.nick), StateData#state.user, Stanza). send_stanza_unavailable(Chan, StateData) -> Affiliation = "member", % this is a simplification Role = "none", Stanza = {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", [{"affiliation", Affiliation}, {"role", Role}], []}, {xmlelement, "status", [{"code", "110"}], []} ]}]}, send_stanza(Chan, StateData, Stanza). %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- send_text(#state{socket = Socket, encoding = Encoding}, Text) -> CText = iconv:convert("utf-8", Encoding, lists:flatten(Text)), %?DEBUG("IRC OUTu: ~s~nIRC OUTk: ~s~n", [Text, CText]), gen_tcp:send(Socket, CText). %send_queue(Socket, Q) -> % case queue:out(Q) of % {{value, El}, Q1} -> % send_element(Socket, El), % send_queue(Socket, Q1); % {empty, Q1} -> % ok % end. bounce_messages(Reason) -> receive {send_element, El} -> {xmlelement, _Name, Attrs, _SubTags} = El, case xml:get_attr_s("type", Attrs) of "error" -> ok; _ -> Err = jlib:make_error_reply(El, "502", Reason), From = jlib:string_to_jid(xml:get_attr_s("from", Attrs)), To = jlib:string_to_jid(xml:get_attr_s("to", Attrs)), ejabberd_router:route(To, From, Err) end, bounce_messages(Reason) after 0 -> ok end. route_chan(Pid, Channel, Resource, Packet) -> Pid ! {route_chan, Channel, Resource, Packet}. route_nick(Pid, Nick, Packet) -> Pid ! {route_nick, Nick, Packet}. process_lines(_Encoding, [S]) -> S; process_lines(Encoding, [S | Ss]) -> self() ! {ircstring, iconv:convert(Encoding, "utf-8", S)}, process_lines(Encoding, Ss). process_channel_list(StateData, Items) -> process_channel_list_find_chan(StateData, Items). process_channel_list_find_chan(StateData, []) -> StateData; process_channel_list_find_chan(StateData, [[$# | Chan] | Items]) -> process_channel_list_users(StateData, Chan, Items); process_channel_list_find_chan(StateData, [_ | Items]) -> process_channel_list_find_chan(StateData, Items). process_channel_list_users(StateData, _Chan, []) -> StateData; process_channel_list_users(StateData, Chan, [User | Items]) -> NewStateData = process_channel_list_user(StateData, Chan, User), process_channel_list_users(NewStateData, Chan, Items). process_channel_list_user(StateData, Chan, User) -> User1 = case User of [$: | U1] -> U1; _ -> User end, {User2, Affiliation, Role} = case User1 of [$@ | U2] -> {U2, "admin", "moderator"}; [$+ | U2] -> {U2, "member", "participant"}; [$\% | U2] -> {U2, "admin", "moderator"}; [$& | U2] -> {U2, "admin", "moderator"}; [$~ | U2] -> {U2, "admin", "moderator"}; _ -> {User1, "member", "participant"} end, ejabberd_router:route( jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, User2), StateData#state.user, {xmlelement, "presence", [], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", [{"affiliation", Affiliation}, {"role", Role}], []}]}]}), case catch dict:update(Chan, fun(Ps) -> ?SETS:add_element(User2, Ps) end, StateData#state.channels) of {'EXIT', _} -> StateData; NS -> StateData#state{channels = NS} end. process_channel_topic(StateData, Chan, String) -> Msg = ejabberd_regexp:replace(String, ".*332[^:]*:", ""), Msg1 = filter_message(Msg), ejabberd_router:route( jlib:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, ""), StateData#state.user, {xmlelement, "message", [{"type", "groupchat"}], [{xmlelement, "subject", [], [{xmlcdata, Msg1}]}, {xmlelement, "body", [], [{xmlcdata, "Topic for #" ++ Chan ++ ": " ++ Msg1}]} ]}). process_channel_topic_who(StateData, Chan, String) -> Words = string:tokens(String, " "), Msg1 = case Words of [_, "333", _, _Chan, Whoset , Timeset] -> {Unixtimeset, _Rest} = string:to_integer(Timeset), "Topic for #" ++ Chan ++ " set by " ++ Whoset ++ " at " ++ unixtime2string(Unixtimeset); [_, "333", _, _Chan, Whoset | _] -> "Topic for #" ++ Chan ++ " set by " ++ Whoset; _ -> String end, Msg2 = filter_message(Msg1), ejabberd_router:route( jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, ""), StateData#state.user, {xmlelement, "message", [{"type", "groupchat"}], [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}). error_nick_in_use(_StateData, String) -> Msg = ejabberd_regexp:replace(String, ".*433 +[^ ]* +", ""), Msg1 = filter_message(Msg), {xmlelement, "error", [{"code", "409"}, {"type", "cancel"}], [{xmlelement, "conflict", [{"xmlns", ?NS_STANZAS}], []}, {xmlelement, "text", [{"xmlns", ?NS_STANZAS}], [{xmlcdata, Msg1}]}]}. process_nick_in_use(StateData, String) -> % We can't use the jlib macro because we don't know the language of the % message. Error = error_nick_in_use(StateData, String), case StateData#state.nickchannel of undefined -> % Shouldn't happen with a well behaved server StateData; Chan -> ejabberd_router:route( jlib:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, StateData#state.nick), StateData#state.user, {xmlelement, "presence", [{"type", "error"}], [Error]}), StateData#state{nickchannel = undefined} end. process_num_error(StateData, String) -> Error = error_unknown_num(StateData, String, "continue"), lists:foreach( fun(Chan) -> ejabberd_router:route( jlib:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, StateData#state.nick), StateData#state.user, {xmlelement, "message", [{"type", "error"}], [Error]}) end, dict:fetch_keys(StateData#state.channels)), StateData. process_endofwhois(StateData, _String, Nick) -> ejabberd_router:route( jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]), StateData#state.host, ""), StateData#state.user, {xmlelement, "message", [{"type", "chat"}], [{xmlelement, "body", [], [{xmlcdata, "End of WHOIS"}]}]}). process_whois311(StateData, String, Nick, Ident, Irchost) -> Fullname = ejabberd_regexp:replace(String, ".*311[^:]*:", ""), ejabberd_router:route( jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]), StateData#state.host, ""), StateData#state.user, {xmlelement, "message", [{"type", "chat"}], [{xmlelement, "body", [], [{xmlcdata, lists:concat( ["WHOIS: ", Nick, " is ", Ident, "@" , Irchost, " : " , Fullname])}]}]}). process_whois312(StateData, String, Nick, Ircserver) -> Ircserverdesc = ejabberd_regexp:replace(String, ".*312[^:]*:", ""), ejabberd_router:route( jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]), StateData#state.host, ""), StateData#state.user, {xmlelement, "message", [{"type", "chat"}], [{xmlelement, "body", [], [{xmlcdata, lists:concat(["WHOIS: ", Nick, " use ", Ircserver, " : ", Ircserverdesc])}]}]}). process_whois319(StateData, String, Nick) -> Chanlist = ejabberd_regexp:replace(String, ".*319[^:]*:", ""), ejabberd_router:route( jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]), StateData#state.host, ""), StateData#state.user, {xmlelement, "message", [{"type", "chat"}], [{xmlelement, "body", [], [{xmlcdata, lists:concat(["WHOIS: ", Nick, " is on ", Chanlist])}]}]}). process_chanprivmsg(StateData, Chan, From, String) -> [FromUser | _] = string:tokens(From, "!"), Msg = ejabberd_regexp:replace(String, ".*PRIVMSG[^:]*:", ""), Msg1 = case Msg of [1, $A, $C, $T, $I, $O, $N, $ | Rest] -> "/me " ++ Rest; _ -> Msg end, Msg2 = filter_message(Msg1), ejabberd_router:route( jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, {xmlelement, "message", [{"type", "groupchat"}], [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}). process_channotice(StateData, Chan, From, String) -> [FromUser | _] = string:tokens(From, "!"), Msg = ejabberd_regexp:replace(String, ".*NOTICE[^:]*:", ""), Msg1 = case Msg of [1, $A, $C, $T, $I, $O, $N, $ | Rest] -> "/me " ++ Rest; _ -> "/me NOTICE: " ++ Msg end, Msg2 = filter_message(Msg1), ejabberd_router:route( jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, {xmlelement, "message", [{"type", "groupchat"}], [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}). process_privmsg(StateData, _Nick, From, String) -> [FromUser | _] = string:tokens(From, "!"), Msg = ejabberd_regexp:replace(String, ".*PRIVMSG[^:]*:", ""), Msg1 = case Msg of [1, $A, $C, $T, $I, $O, $N, $ | Rest] -> "/me " ++ Rest; _ -> Msg end, Msg2 = filter_message(Msg1), ejabberd_router:route( jlib:make_jid(lists:concat([FromUser, "!", StateData#state.server]), StateData#state.host, ""), StateData#state.user, {xmlelement, "message", [{"type", "chat"}], [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}). process_notice(StateData, _Nick, From, String) -> [FromUser | _] = string:tokens(From, "!"), Msg = ejabberd_regexp:replace(String, ".*NOTICE[^:]*:", ""), Msg1 = case Msg of [1, $A, $C, $T, $I, $O, $N, $ | Rest] -> "/me " ++ Rest; _ -> "/me NOTICE: " ++ Msg end, Msg2 = filter_message(Msg1), ejabberd_router:route( jlib:make_jid(lists:concat([FromUser, "!", StateData#state.server]), StateData#state.host, ""), StateData#state.user, {xmlelement, "message", [{"type", "chat"}], [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}). process_version(StateData, _Nick, From) -> [FromUser | _] = string:tokens(From, "!"), send_text( StateData, io_lib:format("NOTICE ~s :\001VERSION " "ejabberd IRC transport ~s (c) Alexey Shchepin" "\001\r\n", [FromUser, ?VERSION]) ++ io_lib:format("NOTICE ~s :\001VERSION " "http://ejabberd.jabberstudio.org/" "\001\r\n", [FromUser])). process_userinfo(StateData, _Nick, From) -> [FromUser | _] = string:tokens(From, "!"), send_text( StateData, io_lib:format("NOTICE ~s :\001USERINFO " "xmpp:~s" "\001\r\n", [FromUser, jlib:jid_to_string(StateData#state.user)])). process_topic(StateData, Chan, From, String) -> [FromUser | _] = string:tokens(From, "!"), Msg = ejabberd_regexp:replace(String, ".*TOPIC[^:]*:", ""), Msg1 = filter_message(Msg), ejabberd_router:route( jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, {xmlelement, "message", [{"type", "groupchat"}], [{xmlelement, "subject", [], [{xmlcdata, Msg1}]}, {xmlelement, "body", [], [{xmlcdata, "/me has changed the subject to: " ++ Msg1}]}]}). process_part(StateData, Chan, From, String) -> [FromUser | FromIdent] = string:tokens(From, "!"), Msg = ejabberd_regexp:replace(String, ".*PART[^:]*:", ""), Msg1 = filter_message(Msg), ejabberd_router:route( jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", [{"affiliation", "member"}, {"role", "none"}], []}]}, {xmlelement, "status", [], [{xmlcdata, Msg1 ++ " (" ++ FromIdent ++ ")"}]}] }), case catch dict:update(Chan, fun(Ps) -> remove_element(FromUser, Ps) end, StateData#state.channels) of {'EXIT', _} -> StateData; NS -> StateData#state{channels = NS} end. process_quit(StateData, From, String) -> [FromUser | FromIdent] = string:tokens(From, "!"), Msg = ejabberd_regexp:replace(String, ".*QUIT[^:]*:", ""), Msg1 = filter_message(Msg), %%NewChans = dict:map( fun(Chan, Ps) -> case ?SETS:is_member(FromUser, Ps) of true -> ejabberd_router:route( jlib:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", [{"affiliation", "member"}, {"role", "none"}], []}]}, {xmlelement, "status", [], [{xmlcdata, Msg1 ++ " (" ++ FromIdent ++ ")"}]} ]}), remove_element(FromUser, Ps); _ -> Ps end end, StateData#state.channels), StateData. process_join(StateData, Channel, From, _String) -> [FromUser | FromIdent] = string:tokens(From, "!"), Chan = lists:subtract(Channel, ":#"), ejabberd_router:route( jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, {xmlelement, "presence", [], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", [{"affiliation", "member"}, {"role", "participant"}], []}]}, {xmlelement, "status", [], [{xmlcdata, FromIdent}]}]}), case catch dict:update(Chan, fun(Ps) -> ?SETS:add_element(FromUser, Ps) end, StateData#state.channels) of {'EXIT', _} -> StateData; NS -> StateData#state{channels = NS} end. process_mode_o(StateData, Chan, _From, Nick, Affiliation, Role) -> %Msg = lists:last(string:tokens(String, ":")), ejabberd_router:route( jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, Nick), StateData#state.user, {xmlelement, "presence", [], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", [{"affiliation", Affiliation}, {"role", Role}], []}]}]}). process_kick(StateData, Chan, From, Nick, String) -> Msg = lists:last(string:tokens(String, ":")), Msg2 = Nick ++ " kicked by " ++ From ++ " (" ++ filter_message(Msg) ++ ")", ejabberd_router:route( jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, ""), StateData#state.user, {xmlelement, "message", [{"type", "groupchat"}], [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}), ejabberd_router:route( jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, Nick), StateData#state.user, {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", [{"affiliation", "none"}, {"role", "none"}], []}, {xmlelement, "status", [{"code", "307"}], []} ]}]}). process_nick(StateData, From, NewNick) -> [FromUser | _] = string:tokens(From, "!"), Nick = lists:subtract(NewNick, ":"), NewChans = dict:map( fun(Chan, Ps) -> case ?SETS:is_member(FromUser, Ps) of true -> ejabberd_router:route( jlib:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, FromUser), StateData#state.user, {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", [{"affiliation", "member"}, {"role", "participant"}, {"nick", Nick}], []}, {xmlelement, "status", [{"code", "303"}], []} ]}]}), ejabberd_router:route( jlib:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, Nick), StateData#state.user, {xmlelement, "presence", [], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", [{"affiliation", "member"}, {"role", "participant"}], []} ]}]}), ?SETS:add_element(Nick, remove_element(FromUser, Ps)); _ -> Ps end end, StateData#state.channels), if FromUser == StateData#state.nick -> StateData#state{nick = Nick, nickchannel = undefined, channels = NewChans}; true -> StateData#state{channels = NewChans} end. process_error(StateData, String) -> lists:foreach( fun(Chan) -> ejabberd_router:route( jlib:make_jid( lists:concat([Chan, "%", StateData#state.server]), StateData#state.host, StateData#state.nick), StateData#state.user, {xmlelement, "presence", [{"type", "error"}], [{xmlelement, "error", [{"code", "502"}], [{xmlcdata, String}]}]}) end, dict:fetch_keys(StateData#state.channels)). error_unknown_num(_StateData, String, Type) -> Msg = ejabberd_regexp:replace(String, ".*[45][0-9][0-9] +[^ ]* +", ""), Msg1 = filter_message(Msg), {xmlelement, "error", [{"code", "500"}, {"type", Type}], [{xmlelement, "undefined-condition", [{"xmlns", ?NS_STANZAS}], []}, {xmlelement, "text", [{"xmlns", ?NS_STANZAS}], [{xmlcdata, Msg1}]}]}. remove_element(E, Set) -> case ?SETS:is_element(E, Set) of true -> ?SETS:del_element(E, Set); _ -> Set end. iq_admin(StateData, Channel, From, To, #iq{type = Type, xmlns = XMLNS, sub_el = SubEl} = IQ) -> case catch process_iq_admin(StateData, Channel, Type, SubEl) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); Res -> if Res /= ignore -> ResIQ = case Res of {result, ResEls} -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], ResEls }]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); true -> ok end end. process_iq_admin(StateData, Channel, set, SubEl) -> case xml:get_subtag(SubEl, "item") of false -> {error, ?ERR_BAD_REQUEST}; ItemEl -> Nick = xml:get_tag_attr_s("nick", ItemEl), Affiliation = xml:get_tag_attr_s("affiliation", ItemEl), Role = xml:get_tag_attr_s("role", ItemEl), Reason = xml:get_path_s(ItemEl, [{elem, "reason"}, cdata]), process_admin(StateData, Channel, Nick, Affiliation, Role, Reason) end; process_iq_admin(_StateData, _Channel, get, _SubEl) -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED}. process_admin(_StateData, _Channel, "", _Affiliation, _Role, _Reason) -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED}; process_admin(StateData, Channel, Nick, _Affiliation, "none", Reason) -> case Reason of "" -> send_text(StateData, io_lib:format("KICK #~s ~s\r\n", [Channel, Nick])); _ -> send_text(StateData, io_lib:format("KICK #~s ~s :~s\r\n", [Channel, Nick, Reason])) end, {result, []}; process_admin(_StateData, _Channel, _Nick, _Affiliation, _Role, _Reason) -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED}. filter_message(Msg) -> lists:filter( fun(C) -> if (C < 32) and (C /= 9) and (C /= 10) and (C /= 13) -> false; true -> true end end, filter_mirc_colors(Msg)). filter_mirc_colors(Msg) -> ejabberd_regexp:greplace(Msg, "(\\003[0-9]+)(,[0-9]+)?", ""). unixtime2string(Unixtime) -> Secs = Unixtime + calendar:datetime_to_gregorian_seconds( {{1970, 1, 1}, {0,0,0}}), {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:universal_time_to_local_time( calendar:gregorian_seconds_to_datetime(Secs)), lists:flatten( io_lib:format("~4..0w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w", [Year, Month, Day, Hour, Minute, Second])). toupper([C | Cs]) -> if C >= $a, C =< $z -> [C - 32 | toupper(Cs)]; true -> [C | toupper(Cs)] end; toupper([]) -> []. ejabberd-2.1.11/src/mod_irc/mod_irc_odbc.erl0000664000000000000000000010733512240230175015541 0ustar %%%---------------------------------------------------------------------- %%% File : mod_irc_odbc.erl %%% Author : Alexey Shchepin %%% Purpose : IRC transport %%% Created : 15 Feb 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_irc_odbc). -author('alexey@process-one.net'). -behaviour(gen_server). -behaviour(gen_mod). %% API -export([start_link/2, start/2, stop/1, closed_connection/3, get_connection_params/3]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("adhoc.hrl"). -define(DEFAULT_IRC_ENCODING, "iso8859-1"). -define(DEFAULT_IRC_PORT, 6667). -define(POSSIBLE_ENCODINGS, ["koi8-r", "iso8859-1", "iso8859-2", "utf-8", "utf-8+latin-1"]). -record(irc_connection, {jid_server_host, pid}). -record(state, {host, server_host, access}). -define(PROCNAME, ejabberd_mod_irc). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host, Opts) -> start_supervisor(Host), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, temporary, 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> stop_supervisor(Host), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:call(Proc, stop), supervisor:delete_child(ejabberd_sup, Proc). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([Host, Opts]) -> iconv:start(), MyHost = gen_mod:get_opt_host(Host, Opts, "irc.@HOST@"), Access = gen_mod:get_opt(access, Opts, all), catch ets:new(irc_connection, [named_table, public, {keypos, #irc_connection.jid_server_host}]), ejabberd_router:register_route(MyHost), {ok, #state{host = MyHost, server_host = Host, access = Access}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call(stop, _From, State) -> {stop, normal, ok, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({route, From, To, Packet}, #state{host = Host, server_host = ServerHost, access = Access} = State) -> case catch do_route(Host, ServerHost, Access, From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); _ -> ok end, {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, State) -> ejabberd_router:unregister_route(State#state.host), ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- start_supervisor(Host) -> Proc = gen_mod:get_module_proc(Host, ejabberd_mod_irc_sup), ChildSpec = {Proc, {ejabberd_tmp_sup, start_link, [Proc, mod_irc_connection]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop_supervisor(Host) -> Proc = gen_mod:get_module_proc(Host, ejabberd_mod_irc_sup), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). do_route(Host, ServerHost, Access, From, To, Packet) -> case acl:match_rule(ServerHost, Access, From) of allow -> do_route1(Host, ServerHost, From, To, Packet); _ -> {xmlelement, _Name, Attrs, _Els} = Packet, Lang = xml:get_attr_s("xml:lang", Attrs), ErrText = "Access denied by service policy", Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, ErrText)), ejabberd_router:route(To, From, Err) end. do_route1(Host, ServerHost, From, To, Packet) -> #jid{user = ChanServ, resource = Resource} = To, {xmlelement, _Name, _Attrs, _Els} = Packet, case ChanServ of "" -> case Resource of "" -> case jlib:iq_query_info(Packet) of #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS, sub_el = SubEl, lang = Lang} = IQ -> Node = xml:get_tag_attr_s("node", SubEl), Info = ejabberd_hooks:run_fold( disco_info, ServerHost, [], [ServerHost, ?MODULE, "", ""]), case iq_disco(ServerHost, Node, Lang) of [] -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], []}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); DiscoInfo -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], DiscoInfo ++ Info}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)) end; #iq{type = get, xmlns = ?NS_DISCO_ITEMS = XMLNS, sub_el = SubEl, lang = Lang} = IQ -> Node = xml:get_tag_attr_s("node", SubEl), case Node of [] -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], []}]}, Res = jlib:iq_to_xml(ResIQ); "join" -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], []}]}, Res = jlib:iq_to_xml(ResIQ); "register" -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], []}]}, Res = jlib:iq_to_xml(ResIQ); ?NS_COMMANDS -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}, {"node", Node}], command_items(ServerHost, Host, Lang)}]}, Res = jlib:iq_to_xml(ResIQ); _ -> Res = jlib:make_error_reply( Packet, ?ERR_ITEM_NOT_FOUND) end, ejabberd_router:route(To, From, Res); #iq{xmlns = ?NS_REGISTER} = IQ -> process_register(ServerHost, Host, From, To, IQ); #iq{type = get, xmlns = ?NS_VCARD = XMLNS, lang = Lang} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", XMLNS}], iq_get_vcard(Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{type = set, xmlns = ?NS_COMMANDS, lang = _Lang, sub_el = SubEl} = IQ -> Request = adhoc:parse_request(IQ), case lists:keysearch(Request#adhoc_request.node, 1, commands(ServerHost)) of {value, {_, _, Function}} -> case catch Function(From, To, Request) of {'EXIT', Reason} -> ?ERROR_MSG("~p~nfor ad-hoc handler of ~p", [Reason, {From, To, IQ}]), Res = IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; ignore -> Res = ignore; {error, Error} -> Res = IQ#iq{type = error, sub_el = [SubEl, Error]}; Command -> Res = IQ#iq{type = result, sub_el = [Command]} end, if Res /= ignore -> ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); true -> ok end; _ -> Err = jlib:make_error_reply( Packet, ?ERR_ITEM_NOT_FOUND), ejabberd_router:route(To, From, Err) end; #iq{} = _IQ -> Err = jlib:make_error_reply( Packet, ?ERR_FEATURE_NOT_IMPLEMENTED), ejabberd_router:route(To, From, Err); _ -> ok end; _ -> Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST), ejabberd_router:route(To, From, Err) end; _ -> case string:tokens(ChanServ, "%") of [[_ | _] = Channel, [_ | _] = Server] -> case ets:lookup(irc_connection, {From, Server, Host}) of [] -> ?DEBUG("open new connection~n", []), {Username, Encoding, Port, Password} = get_connection_params( Host, ServerHost, From, Server), ConnectionUsername = case Packet of %% If the user tries to join a %% chatroom, the packet for sure %% contains the desired username. {xmlelement, "presence", _, _} -> Resource; %% Otherwise, there is no firm %% conclusion from the packet. %% Better to use the configured %% username (which defaults to the %% username part of the JID). _ -> Username end, {ok, Pid} = mod_irc_connection:start( From, Host, ServerHost, Server, ConnectionUsername, Encoding, Port, Password, ?MODULE), ets:insert( irc_connection, #irc_connection{jid_server_host = {From, Server, Host}, pid = Pid}), mod_irc_connection:route_chan( Pid, Channel, Resource, Packet), ok; [R] -> Pid = R#irc_connection.pid, ?DEBUG("send to process ~p~n", [Pid]), mod_irc_connection:route_chan( Pid, Channel, Resource, Packet), ok end; _ -> case string:tokens(ChanServ, "!") of [[_ | _] = Nick, [_ | _] = Server] -> case ets:lookup(irc_connection, {From, Server, Host}) of [] -> Err = jlib:make_error_reply( Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err); [R] -> Pid = R#irc_connection.pid, ?DEBUG("send to process ~p~n", [Pid]), mod_irc_connection:route_nick( Pid, Nick, Packet), ok end; _ -> Err = jlib:make_error_reply( Packet, ?ERR_BAD_REQUEST), ejabberd_router:route(To, From, Err) end end end. closed_connection(Host, From, Server) -> ets:delete(irc_connection, {From, Server, Host}). iq_disco(_ServerHost, [], Lang) -> [{xmlelement, "identity", [{"category", "conference"}, {"type", "irc"}, {"name", translate:translate(Lang, "IRC Transport")}], []}, {xmlelement, "feature", [{"var", ?NS_DISCO_INFO}], []}, {xmlelement, "feature", [{"var", ?NS_MUC}], []}, {xmlelement, "feature", [{"var", ?NS_REGISTER}], []}, {xmlelement, "feature", [{"var", ?NS_VCARD}], []}, {xmlelement, "feature", [{"var", ?NS_COMMANDS}], []}]; iq_disco(ServerHost, Node, Lang) -> case lists:keysearch(Node, 1, commands(ServerHost)) of {value, {_, Name, _}} -> [{xmlelement, "identity", [{"category", "automation"}, {"type", "command-node"}, {"name", translate:translate(Lang, Name)}], []}, {xmlelement, "feature", [{"var", ?NS_COMMANDS}], []}, {xmlelement, "feature", [{"var", ?NS_XDATA}], []}]; _ -> [] end. iq_get_vcard(Lang) -> [{xmlelement, "FN", [], [{xmlcdata, "ejabberd/mod_irc"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate(Lang, "ejabberd IRC module") ++ "\nCopyright (c) 2003-2012 ProcessOne"}]}]. command_items(ServerHost, Host, Lang) -> lists:map(fun({Node, Name, _Function}) -> {xmlelement, "item", [{"jid", Host}, {"node", Node}, {"name", translate:translate(Lang, Name)}], []} end, commands(ServerHost)). commands(ServerHost) -> [{"join", "Join channel", fun adhoc_join/3}, {"register", "Configure username, encoding, port and password", fun(From, To, Request) -> adhoc_register(ServerHost, From, To, Request) end}]. process_register(ServerHost, Host, From, To, #iq{} = IQ) -> case catch process_irc_register(ServerHost, Host, From, To, IQ) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); ResIQ -> if ResIQ /= ignore -> ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); true -> ok end end. find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) -> find_xdata_el1(SubEls). find_xdata_el1([]) -> false; find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_XDATA -> {xmlelement, Name, Attrs, SubEls}; _ -> find_xdata_el1(Els) end; find_xdata_el1([_ | Els]) -> find_xdata_el1(Els). process_irc_register(ServerHost, Host, From, _To, #iq{type = Type, xmlns = XMLNS, lang = Lang, sub_el = SubEl} = IQ) -> case Type of set -> XDataEl = find_xdata_el(SubEl), case XDataEl of false -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ACCEPTABLE]}; {xmlelement, _Name, Attrs, _SubEls} -> case xml:get_attr_s("type", Attrs) of "cancel" -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], []}]}; "submit" -> XData = jlib:parse_xdata_submit(XDataEl), case XData of invalid -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}; _ -> Node = string:tokens( xml:get_tag_attr_s("node", SubEl), "/"), case set_form( ServerHost, Host, From, Node, Lang, XData) of {result, Res} -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], Res }]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end end; _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]} end end; get -> Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"), case get_form(ServerHost, Host, From, Node, Lang) of {result, Res} -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], Res }]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end end. get_form(ServerHost, Host, From, [], Lang) -> #jid{user = User, server = Server} = From, LServer = jlib:nameprep(ServerHost), SJID = ejabberd_odbc:escape( jlib:jid_to_string( jlib:jid_tolower( jlib:jid_remove_resource(From)))), SHost = ejabberd_odbc:escape(Host), DefaultEncoding = get_default_encoding(Host), Customs = case catch ejabberd_odbc:sql_query( LServer, ["select data from irc_custom where " "jid='", SJID, "' and host='", SHost, "';"]) of {selected, ["data"], [{SData}]} -> Data = ejabberd_odbc:decode_term(SData), {xml:get_attr_s(username, Data), xml:get_attr_s(connections_params, Data)}; {'EXIT', _} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; {selected, _, _} -> {User, []} end, case Customs of {error, _Error} -> Customs; {Username, ConnectionsParams} -> {result, [{xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "You need an x:data capable client " "to configure mod_irc settings")}]}, {xmlelement, "x", [{"xmlns", ?NS_XDATA}], [{xmlelement, "title", [], [{xmlcdata, translate:translate( Lang, "Registration in mod_irc for ") ++ User ++ "@" ++ Server}]}, {xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "Enter username, encodings, ports and passwords you wish to use for " "connecting to IRC servers")}]}, {xmlelement, "field", [{"type", "text-single"}, {"label", translate:translate( Lang, "IRC Username")}, {"var", "username"}], [{xmlelement, "value", [], [{xmlcdata, Username}]}]}, {xmlelement, "field", [{"type", "fixed"}], [{xmlelement, "value", [], [{xmlcdata, lists:flatten( io_lib:format( translate:translate( Lang, "If you want to specify different ports, " "passwords, encodings for IRC servers, fill " "this list with values in format " "'{\"irc server\", \"encoding\", port, \"password\"}'. " "By default this service use \"~s\" encoding, port ~p, " "empty password."), [DefaultEncoding, ?DEFAULT_IRC_PORT]))}]}]}, {xmlelement, "field", [{"type", "fixed"}], [{xmlelement, "value", [], [{xmlcdata, translate:translate( Lang, "Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, " "{\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." )}]}]}, {xmlelement, "field", [{"type", "text-multi"}, {"label", translate:translate(Lang, "Connections parameters")}, {"var", "connections_params"}], lists:map( fun(S) -> {xmlelement, "value", [], [{xmlcdata, S}]} end, string:tokens( lists:flatten( io_lib:format("~p.", [ConnectionsParams])), "\n")) } ]}]} end; get_form(_ServerHost, _Host, _, _, _Lang) -> {error, ?ERR_SERVICE_UNAVAILABLE}. set_form(ServerHost, Host, From, [], _Lang, XData) -> LServer = jlib:nameprep(ServerHost), SJID = ejabberd_odbc:escape( jlib:jid_to_string( jlib:jid_tolower( jlib:jid_remove_resource(From)))), SHost = ejabberd_odbc:escape(Host), case {lists:keysearch("username", 1, XData), lists:keysearch("connections_params", 1, XData)} of {{value, {_, [Username]}}, {value, {_, Strings}}} -> EncString = lists:foldl(fun(S, Res) -> Res ++ S ++ "\n" end, "", Strings), case erl_scan:string(EncString) of {ok, Tokens, _} -> case erl_parse:parse_term(Tokens) of {ok, ConnectionsParams} -> SData = ejabberd_odbc:encode_term( [{username, Username}, {connections_params, ConnectionsParams}]), case ejabberd_odbc:sql_transaction( LServer, fun() -> odbc_queries:update_t( "irc_custom", ["jid", "host", "data"], [SJID, SHost, SData], ["jid='", SJID, "' and host='", SHost, "'"]), ok end) of {atomic, _} -> {result, []}; _ -> {error, ?ERR_NOT_ACCEPTABLE} end; _ -> {error, ?ERR_NOT_ACCEPTABLE} end; _ -> {error, ?ERR_NOT_ACCEPTABLE} end; _ -> {error, ?ERR_NOT_ACCEPTABLE} end; set_form(_ServerHost, _Host, _, _, _Lang, _XData) -> {error, ?ERR_SERVICE_UNAVAILABLE}. %% Host = "irc.example.com" %% ServerHost = "example.com" get_connection_params(Host, From, IRCServer) -> [_ | HostTail] = string:tokens(Host, "."), ServerHost = string:join(HostTail, "."), get_connection_params(Host, ServerHost, From, IRCServer). get_default_encoding(ServerHost) -> Result = gen_mod:get_module_opt( ServerHost, ?MODULE, default_encoding, ?DEFAULT_IRC_ENCODING), ?INFO_MSG("The default_encoding configured for host ~p is: ~p~n", [ServerHost, Result]), Result. get_connection_params(Host, ServerHost, From, IRCServer) -> #jid{user = User, server = _Server} = From, LServer = jlib:nameprep(ServerHost), SJID = ejabberd_odbc:escape( jlib:jid_to_string( jlib:jid_tolower( jlib:jid_remove_resource(From)))), SHost = ejabberd_odbc:escape(Host), DefaultEncoding = get_default_encoding(ServerHost), case catch ejabberd_odbc:sql_query( LServer, ["select data from irc_custom where " "jid='", SJID, "' and host='", SHost, "';"]) of {'EXIT', _Reason} -> {User, DefaultEncoding, ?DEFAULT_IRC_PORT, ""}; {selected, ["data"], []} -> {User, DefaultEncoding, ?DEFAULT_IRC_PORT, ""}; {selected, ["data"], [{SData}]} -> Data = ejabberd_odbc:decode_term(SData), Username = xml:get_attr_s(username, Data), {NewUsername, NewEncoding, NewPort, NewPassword} = case lists:keysearch( IRCServer, 1, xml:get_attr_s(connections_params, Data)) of {value, {_, Encoding, Port, Password}} -> {Username, Encoding, Port, Password}; {value, {_, Encoding, Port}} -> {Username, Encoding, Port, ""}; {value, {_, Encoding}} -> {Username, Encoding, ?DEFAULT_IRC_PORT, ""}; _ -> {Username, DefaultEncoding, ?DEFAULT_IRC_PORT, ""} end, {NewUsername, NewEncoding, if NewPort >= 0 andalso NewPort =< 65535 -> NewPort; true -> ?DEFAULT_IRC_PORT end, NewPassword} end. adhoc_join(_From, _To, #adhoc_request{action = "cancel"} = Request) -> adhoc:produce_response(Request, #adhoc_response{status = canceled}); adhoc_join(From, To, #adhoc_request{lang = Lang, node = _Node, action = _Action, xdata = XData} = Request) -> %% Access control has already been taken care of in do_route. if XData == false -> Form = {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "Join IRC channel")}]}, {xmlelement, "field", [{"var", "channel"}, {"type", "text-single"}, {"label", translate:translate(Lang, "IRC channel (don't put the first #)")}], [{xmlelement, "required", [], []}]}, {xmlelement, "field", [{"var", "server"}, {"type", "text-single"}, {"label", translate:translate(Lang, "IRC server")}], [{xmlelement, "required", [], []}]}]}, adhoc:produce_response(Request, #adhoc_response{status = executing, elements = [Form]}); true -> case jlib:parse_xdata_submit(XData) of invalid -> {error, ?ERR_BAD_REQUEST}; Fields -> Channel = case lists:keysearch("channel", 1, Fields) of {value, {"channel", C}} -> C; _ -> false end, Server = case lists:keysearch("server", 1, Fields) of {value, {"server", S}} -> S; _ -> false end, if Channel /= false, Server /= false -> RoomJID = Channel ++ "%" ++ Server ++ "@" ++ To#jid.server, Invite = {xmlelement, "message", [], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "invite", [{"from", jlib:jid_to_string(From)}], [{xmlelement, "reason", [], [{xmlcdata, translate:translate(Lang, "Join the IRC channel here.")}]}]}]}, {xmlelement, "x", [{"xmlns", ?NS_XCONFERENCE}], [{xmlcdata, translate:translate(Lang, "Join the IRC channel here.")}]}, {xmlelement, "body", [], [{xmlcdata, io_lib:format( translate:translate(Lang, "Join the IRC channel in this Jabber ID: ~s"), [RoomJID])}]}]}, ejabberd_router:route(jlib:string_to_jid(RoomJID), From, Invite), adhoc:produce_response(Request, #adhoc_response{status = completed}); true -> {error, ?ERR_BAD_REQUEST} end end end. adhoc_register(_ServerHost, _From, _To, #adhoc_request{action = "cancel"} = Request) -> adhoc:produce_response(Request, #adhoc_response{status = canceled}); adhoc_register(ServerHost, From, To, #adhoc_request{lang = Lang, node = _Node, xdata = XData, action = Action} = Request) -> #jid{user = User} = From, #jid{lserver = Host} = To, LServer = jlib:nameprep(ServerHost), SHost = ejabberd_odbc:escape(Host), SJID = ejabberd_odbc:escape( jlib:jid_to_string( jlib:jid_tolower( jlib:jid_remove_resource(From)))), %% Generate form for setting username and encodings. If the user %% hasn't begun to fill out the form, generate an initial form %% based on current values. if XData == false -> case catch ejabberd_odbc:sql_query( LServer, ["select data from irc_custom where " "jid='", SJID, "' and host='", SHost, "';"]) of {'EXIT', _Reason} -> Username = User, ConnectionsParams = []; {selected, ["data"], []} -> Username = User, ConnectionsParams = []; {selected, ["data"], [{Data1}]} -> Data = ejabberd_odbc:decode_term(Data1), Username = xml:get_attr_s(username, Data), ConnectionsParams = xml:get_attr_s(connections_params, Data) end, Error = false; true -> case jlib:parse_xdata_submit(XData) of invalid -> Error = {error, ?ERR_BAD_REQUEST}, Username = false, ConnectionsParams = false; Fields -> Username = case lists:keysearch("username", 1, Fields) of {value, {"username", U}} -> U; _ -> User end, ConnectionsParams = parse_connections_params(Fields), Error = false end end, if Error /= false -> Error; Action == "complete" -> SData = ejabberd_odbc:encode_term( [{username, Username}, {connections_params, ConnectionsParams}]), case catch ejabberd_odbc:sql_transaction( LServer, fun() -> odbc_queries:update_t( "irc_custom", ["jid", "host", "data"], [SJID, SHost, SData], ["jid='", SJID, "' and host='", SHost, "'"]), ok end) of {atomic, ok} -> adhoc:produce_response(Request, #adhoc_response{status = completed}); _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end; true -> Form = generate_adhoc_register_form(Lang, Username, ConnectionsParams), adhoc:produce_response(Request, #adhoc_response{status = executing, elements = [Form], actions = ["next", "complete"]}) end. generate_adhoc_register_form(Lang, Username, ConnectionsParams) -> {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "IRC settings")}]}, {xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "Enter username and encodings you wish to use for " "connecting to IRC servers. Press 'Next' to get more fields " "to fill in. Press 'Complete' to save settings.")}]}, {xmlelement, "field", [{"var", "username"}, {"type", "text-single"}, {"label", translate:translate(Lang, "IRC username")}], [{xmlelement, "required", [], []}, {xmlelement, "value", [], [{xmlcdata, Username}]}]}] ++ generate_connection_params_fields(Lang, ConnectionsParams, 1, [])}. generate_connection_params_fields(Lang, [], Number, Acc) -> Field = generate_connection_params_field(Lang, "", "", -1, "", Number), lists:reverse(Field ++ Acc); generate_connection_params_fields(Lang, [ConnectionParams | ConnectionsParams], Number, Acc) -> case ConnectionParams of {Server, Encoding, Port, Password} -> Field = generate_connection_params_field(Lang, Server, Encoding, Port, Password, Number), generate_connection_params_fields(Lang, ConnectionsParams, Number + 1, Field ++ Acc); {Server, Encoding, Port} -> Field = generate_connection_params_field(Lang, Server, Encoding, Port, [], Number), generate_connection_params_fields(Lang, ConnectionsParams, Number + 1, Field ++ Acc); {Server, Encoding} -> Field = generate_connection_params_field(Lang, Server, Encoding, [], [], Number), generate_connection_params_fields(Lang, ConnectionsParams, Number + 1, Field ++ Acc); _ -> [] end. generate_connection_params_field(Lang, Server, Encoding, Port, Password, Number) -> EncodingUsed = case Encoding of [] -> get_default_encoding(Server); _ -> Encoding end, PortUsedInt = if Port >= 0 andalso Port =< 65535 -> Port; true -> ?DEFAULT_IRC_PORT end, PortUsed = integer_to_list(PortUsedInt), PasswordUsed = case Password of [] -> ""; _ -> Password end, NumberString = integer_to_list(Number), %% Fields are in reverse order, as they will be reversed again later. [{xmlelement, "field", [{"var", "password" ++ NumberString}, {"type", "text-single"}, {"label", io_lib:format(translate:translate(Lang, "Password ~b"), [Number])}], [{xmlelement, "value", [], [{xmlcdata, PasswordUsed}]}]}, {xmlelement, "field", [{"var", "port" ++ NumberString}, {"type", "text-single"}, {"label", io_lib:format(translate:translate(Lang, "Port ~b"), [Number])}], [{xmlelement, "value", [], [{xmlcdata, PortUsed}]}]}, {xmlelement, "field", [{"var", "encoding" ++ NumberString}, {"type", "list-single"}, {"label", io_lib:format(translate:translate(Lang, "Encoding for server ~b"), [Number])}], [{xmlelement, "value", [], [{xmlcdata, EncodingUsed}]} | lists:map(fun(E) -> {xmlelement, "option", [{"label", E}], [{xmlelement, "value", [], [{xmlcdata, E}]}]} end, ?POSSIBLE_ENCODINGS)]}, {xmlelement, "field", [{"var", "server" ++ NumberString}, {"type", "text-single"}, {"label", io_lib:format(translate:translate(Lang, "Server ~b"), [Number])}], [{xmlelement, "value", [], [{xmlcdata, Server}]}]}]. parse_connections_params(Fields) -> %% Find all fields staring with serverN, encodingN, portN and passwordN for any values %% of N, and generate lists of {"N", Value}. Servers = lists:sort( [{lists:nthtail(6, Var), lists:flatten(Value)} || {Var, Value} <- Fields, lists:prefix("server", Var)]), Encodings = lists:sort( [{lists:nthtail(8, Var), lists:flatten(Value)} || {Var, Value} <- Fields, lists:prefix("encoding", Var)]), Ports = lists:sort( [{lists:nthtail(4, Var), lists:flatten(Value)} || {Var, Value} <- Fields, lists:prefix("port", Var)]), Passwords = lists:sort( [{lists:nthtail(8, Var), lists:flatten(Value)} || {Var, Value} <- Fields, lists:prefix("password", Var)]), %% Now sort the lists, and find the corresponding pairs. parse_connections_params(Servers, Encodings, Ports, Passwords). retrieve_connections_params(ConnectionParams, ServerN) -> case ConnectionParams of [{ConnectionParamN, ConnectionParam} | ConnectionParamsTail] -> if ServerN == ConnectionParamN -> {ConnectionParam, ConnectionParamsTail}; ServerN < ConnectionParamN -> {[], [{ConnectionParamN, ConnectionParam} | ConnectionParamsTail]}; ServerN > ConnectionParamN -> {[], ConnectionParamsTail} end; _ -> {[], []} end. parse_connections_params([], _, _, _) -> []; parse_connections_params(_, [], [], []) -> []; parse_connections_params([{ServerN, Server} | Servers], Encodings, Ports, Passwords) -> %% Try to match matches of servers, ports, passwords and encodings, no matter what fields %% the client might have left out. {NewEncoding, NewEncodings} = retrieve_connections_params(Encodings, ServerN), {NewPort, NewPorts} = retrieve_connections_params(Ports, ServerN), {NewPassword, NewPasswords} = retrieve_connections_params(Passwords, ServerN), [{Server, NewEncoding, NewPort, NewPassword} | parse_connections_params(Servers, NewEncodings, NewPorts, NewPasswords)]. ejabberd-2.1.11/src/mod_irc/iconv.erl0000664000000000000000000000506412240230175014250 0ustar %%%---------------------------------------------------------------------- %%% File : iconv.erl %%% Author : Alexey Shchepin %%% Purpose : Interface to libiconv %%% Created : 16 Feb 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(iconv). -author('alexey@process-one.net'). -behaviour(gen_server). -export([start/0, start_link/0, convert/3]). %% Internal exports, call-back functions. -export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]). start() -> gen_server:start({local, ?MODULE}, ?MODULE, [], []). start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). init([]) -> case erl_ddll:load_driver(ejabberd:get_so_path(), iconv_erl) of ok -> ok; {error, already_loaded} -> ok end, Port = open_port({spawn, "iconv_erl"}, []), ets:new(iconv_table, [set, public, named_table]), ets:insert(iconv_table, {port, Port}), {ok, Port}. %%% -------------------------------------------------------- %%% The call-back functions. %%% -------------------------------------------------------- handle_call(_, _, State) -> {noreply, State}. handle_cast(_, State) -> {noreply, State}. handle_info({'EXIT', Port, Reason}, Port) -> {stop, {port_died, Reason}, Port}; handle_info({'EXIT', _Pid, _Reason}, Port) -> {noreply, Port}; handle_info(_, State) -> {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. terminate(_Reason, Port) -> Port ! {self, close}, ok. convert(From, To, String) -> [{port, Port} | _] = ets:lookup(iconv_table, port), Bin = term_to_binary({From, To, String}), BRes = port_control(Port, 1, Bin), binary_to_list(BRes). ejabberd-2.1.11/src/ejabberd_s2s_out.erl0000664000000000000000000012420012240230175014724 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_s2s_out.erl %%% Author : Alexey Shchepin %%% Purpose : Manage outgoing server-to-server connections %%% Created : 6 Dec 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_s2s_out). -author('alexey@process-one.net'). -behaviour(p1_fsm). %% External exports -export([start/3, start_link/3, start_connection/1, terminate_if_waiting_delay/2, stop_connection/1]). %% p1_fsm callbacks (same as gen_fsm) -export([init/1, open_socket/2, wait_for_stream/2, wait_for_validation/2, wait_for_features/2, wait_for_auth_result/2, wait_for_starttls_proceed/2, relay_to_bridge/2, reopen_socket/2, wait_before_retry/2, stream_established/2, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, print_state/1, code_change/4, test_get_addr_port/1, get_addr_port/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). -record(state, {socket, streamid, use_v10, tls = false, tls_required = false, tls_enabled = false, tls_options = [connect], authenticated = false, db_enabled = true, try_auth = true, myname, server, queue, delay_to_retry = undefined_delay, new = false, verify = false, bridge, timer}). %%-define(DBGFSM, true). -ifdef(DBGFSM). -define(FSMOPTS, [{debug, [trace]}]). -else. -define(FSMOPTS, []). -endif. %% Module start with or without supervisor: -ifdef(NO_TRANSIENT_SUPERVISORS). -define(SUPERVISOR_START, p1_fsm:start(ejabberd_s2s_out, [From, Host, Type], fsm_limit_opts() ++ ?FSMOPTS)). -else. -define(SUPERVISOR_START, supervisor:start_child(ejabberd_s2s_out_sup, [From, Host, Type])). -endif. -define(FSMTIMEOUT, 30000). %% We do not block on send anymore. -define(TCP_SEND_TIMEOUT, 15000). %% Maximum delay to wait before retrying to connect after a failed attempt. %% Specified in miliseconds. Default value is 5 minutes. -define(MAX_RETRY_DELAY, 300000). -define(STREAM_HEADER, "" "" ). -define(STREAM_TRAILER, ""). -define(INVALID_NAMESPACE_ERR, xml:element_to_string(?SERR_INVALID_NAMESPACE)). -define(HOST_UNKNOWN_ERR, xml:element_to_string(?SERR_HOST_UNKNOWN)). -define(INVALID_XML_ERR, xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)). -define(SOCKET_DEFAULT_RESULT, {error, badarg}). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start(From, Host, Type) -> ?SUPERVISOR_START. start_link(From, Host, Type) -> p1_fsm:start_link(ejabberd_s2s_out, [From, Host, Type], fsm_limit_opts() ++ ?FSMOPTS). start_connection(Pid) -> p1_fsm:send_event(Pid, init). stop_connection(Pid) -> p1_fsm:send_event(Pid, closed). %%%---------------------------------------------------------------------- %%% Callback functions from p1_fsm %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, StateName, StateData} | %% {ok, StateName, StateData, Timeout} | %% ignore | %% {stop, StopReason} %%---------------------------------------------------------------------- init([From, Server, Type]) -> process_flag(trap_exit, true), ?DEBUG("started: ~p", [{From, Server, Type}]), {TLS, TLSRequired} = case ejabberd_config:get_local_option(s2s_use_starttls) of UseTls when (UseTls==undefined) or (UseTls==false) -> {false, false}; UseTls when (UseTls==true) or (UseTls==optional) -> {true, false}; UseTls when (UseTls==required) or (UseTls==required_trusted) -> {true, true} end, UseV10 = TLS, TLSOpts = case ejabberd_config:get_local_option(s2s_certfile) of undefined -> [connect]; CertFile -> [{certfile, CertFile}, connect] end, {New, Verify} = case Type of {new, Key} -> {Key, false}; {verify, Pid, Key, SID} -> start_connection(self()), {false, {Pid, Key, SID}} end, Timer = erlang:start_timer(?S2STIMEOUT, self(), []), {ok, open_socket, #state{use_v10 = UseV10, tls = TLS, tls_required = TLSRequired, tls_options = TLSOpts, queue = queue:new(), myname = From, server = Server, new = New, verify = Verify, timer = Timer}}. %%---------------------------------------------------------------------- %% Func: StateName/2 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- open_socket(init, StateData) -> log_s2s_out(StateData#state.new, StateData#state.myname, StateData#state.server, StateData#state.tls), ?DEBUG("open_socket: ~p", [{StateData#state.myname, StateData#state.server, StateData#state.new, StateData#state.verify}]), AddrList = case idna:domain_utf8_to_ascii(StateData#state.server) of false -> []; ASCIIAddr -> get_addr_port(ASCIIAddr) end, case lists:foldl(fun({Addr, Port}, Acc) -> case Acc of {ok, Socket} -> {ok, Socket}; _ -> open_socket1(Addr, Port) end end, ?SOCKET_DEFAULT_RESULT, AddrList) of {ok, Socket} -> Version = if StateData#state.use_v10 -> " version='1.0'"; true -> "" end, NewStateData = StateData#state{socket = Socket, tls_enabled = false, streamid = new_id()}, send_text(NewStateData, io_lib:format(?STREAM_HEADER, [StateData#state.myname, StateData#state.server, Version])), {next_state, wait_for_stream, NewStateData, ?FSMTIMEOUT}; {error, _Reason} -> ?INFO_MSG("s2s connection: ~s -> ~s (remote server not found)", [StateData#state.myname, StateData#state.server]), case ejabberd_hooks:run_fold(find_s2s_bridge, undefined, [StateData#state.myname, StateData#state.server]) of {Mod, Fun, Type} -> ?INFO_MSG("found a bridge to ~s for: ~s -> ~s", [Type, StateData#state.myname, StateData#state.server]), NewStateData = StateData#state{bridge={Mod, Fun}}, {next_state, relay_to_bridge, NewStateData}; _ -> wait_before_reconnect(StateData) end end; open_socket(closed, StateData) -> ?INFO_MSG("s2s connection: ~s -> ~s (stopped in open socket)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; open_socket(timeout, StateData) -> ?INFO_MSG("s2s connection: ~s -> ~s (timeout in open socket)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; open_socket(_, StateData) -> {next_state, open_socket, StateData}. %%---------------------------------------------------------------------- %% IPv4 open_socket1({_,_,_,_} = Addr, Port) -> open_socket2(inet, Addr, Port); %% IPv6 open_socket1({_,_,_,_,_,_,_,_} = Addr, Port) -> open_socket2(inet6, Addr, Port); %% Hostname open_socket1(Host, Port) -> lists:foldl(fun(_Family, {ok, _Socket} = R) -> R; (Family, _) -> Addrs = get_addrs(Host, Family), lists:foldl(fun(_Addr, {ok, _Socket} = R) -> R; (Addr, _) -> open_socket1(Addr, Port) end, ?SOCKET_DEFAULT_RESULT, Addrs) end, ?SOCKET_DEFAULT_RESULT, outgoing_s2s_families()). open_socket2(Type, Addr, Port) -> ?DEBUG("s2s_out: connecting to ~p:~p~n", [Addr, Port]), Timeout = outgoing_s2s_timeout(), SockOpts = try erlang:system_info(otp_release) >= "R13B" of true -> [{send_timeout_close, true}]; false -> [] catch _:_ -> [] end, case (catch ejabberd_socket:connect(Addr, Port, [binary, {packet, 0}, {send_timeout, ?TCP_SEND_TIMEOUT}, {active, false}, Type | SockOpts], Timeout)) of {ok, _Socket} = R -> R; {error, Reason} = R -> ?DEBUG("s2s_out: connect return ~p~n", [Reason]), R; {'EXIT', Reason} -> ?DEBUG("s2s_out: connect crashed ~p~n", [Reason]), {error, Reason} end. %%---------------------------------------------------------------------- wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> case {xml:get_attr_s("xmlns", Attrs), xml:get_attr_s("xmlns:db", Attrs), xml:get_attr_s("version", Attrs) == "1.0"} of {"jabber:server", "jabber:server:dialback", false} -> send_db_request(StateData); {"jabber:server", "jabber:server:dialback", true} when StateData#state.use_v10 -> {next_state, wait_for_features, StateData, ?FSMTIMEOUT}; %% Clause added to handle Tigase's workaround for an old ejabberd bug: {"jabber:server", "jabber:server:dialback", true} when not StateData#state.use_v10 -> send_db_request(StateData); {"jabber:server", "", true} when StateData#state.use_v10 -> {next_state, wait_for_features, StateData#state{db_enabled = false}, ?FSMTIMEOUT}; {NSProvided, DB, _} -> send_text(StateData, ?INVALID_NAMESPACE_ERR), ?INFO_MSG("Closing s2s connection: ~s -> ~s (invalid namespace).~n" "Namespace provided: ~p~nNamespace expected: \"jabber:server\"~n" "xmlns:db provided: ~p~nAll attributes: ~p", [StateData#state.myname, StateData#state.server, NSProvided, DB, Attrs]), {stop, normal, StateData} end; wait_for_stream({xmlstreamerror, _}, StateData) -> send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), ?INFO_MSG("Closing s2s connection: ~s -> ~s (invalid xml)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; wait_for_stream({xmlstreamend,_Name}, StateData) -> ?INFO_MSG("Closing s2s connection: ~s -> ~s (xmlstreamend)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; wait_for_stream(timeout, StateData) -> ?INFO_MSG("Closing s2s connection: ~s -> ~s (timeout in wait_for_stream)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; wait_for_stream(closed, StateData) -> ?INFO_MSG("Closing s2s connection: ~s -> ~s (close in wait_for_stream)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}. wait_for_validation({xmlstreamelement, El}, StateData) -> case is_verify_res(El) of {result, To, From, Id, Type} -> ?DEBUG("recv result: ~p", [{From, To, Id, Type}]), case {Type, StateData#state.tls_enabled, StateData#state.tls_required} of {"valid", Enabled, Required} when (Enabled==true) or (Required==false) -> send_queue(StateData, StateData#state.queue), ?INFO_MSG("Connection established: ~s -> ~s with TLS=~p", [StateData#state.myname, StateData#state.server, StateData#state.tls_enabled]), ejabberd_hooks:run(s2s_connect_hook, [StateData#state.myname, StateData#state.server]), {next_state, stream_established, StateData#state{queue = queue:new()}}; {"valid", Enabled, Required} when (Enabled==false) and (Required==true) -> %% TODO: bounce packets ?INFO_MSG("Closing s2s connection: ~s -> ~s (TLS is required but unavailable)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; _ -> %% TODO: bounce packets ?INFO_MSG("Closing s2s connection: ~s -> ~s (invalid dialback key)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData} end; {verify, To, From, Id, Type} -> ?DEBUG("recv verify: ~p", [{From, To, Id, Type}]), case StateData#state.verify of false -> NextState = wait_for_validation, %% TODO: Should'nt we close the connection here ? {next_state, NextState, StateData, get_timeout_interval(NextState)}; {Pid, _Key, _SID} -> case Type of "valid" -> p1_fsm:send_event( Pid, {valid, StateData#state.server, StateData#state.myname}); _ -> p1_fsm:send_event( Pid, {invalid, StateData#state.server, StateData#state.myname}) end, if StateData#state.verify == false -> {stop, normal, StateData}; true -> NextState = wait_for_validation, {next_state, NextState, StateData, get_timeout_interval(NextState)} end end; _ -> {next_state, wait_for_validation, StateData, ?FSMTIMEOUT*3} end; wait_for_validation({xmlstreamend, _Name}, StateData) -> ?INFO_MSG("wait for validation: ~s -> ~s (xmlstreamend)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; wait_for_validation({xmlstreamerror, _}, StateData) -> ?INFO_MSG("wait for validation: ~s -> ~s (xmlstreamerror)", [StateData#state.myname, StateData#state.server]), send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), {stop, normal, StateData}; wait_for_validation(timeout, #state{verify = {VPid, VKey, SID}} = StateData) when is_pid(VPid) and is_list(VKey) and is_list(SID) -> %% This is an auxiliary s2s connection for dialback. %% This timeout is normal and doesn't represent a problem. ?DEBUG("wait_for_validation: ~s -> ~s (timeout in verify connection)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; wait_for_validation(timeout, StateData) -> ?INFO_MSG("wait_for_validation: ~s -> ~s (connect timeout)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; wait_for_validation(closed, StateData) -> ?INFO_MSG("wait for validation: ~s -> ~s (closed)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}. wait_for_features({xmlstreamelement, El}, StateData) -> case El of {xmlelement, "stream:features", _Attrs, Els} -> {SASLEXT, StartTLS, StartTLSRequired} = lists:foldl( fun({xmlelement, "mechanisms", Attrs1, Els1} = _El1, {_SEXT, STLS, STLSReq} = Acc) -> case xml:get_attr_s("xmlns", Attrs1) of ?NS_SASL -> NewSEXT = lists:any( fun({xmlelement, "mechanism", _, Els2}) -> case xml:get_cdata(Els2) of "EXTERNAL" -> true; _ -> false end; (_) -> false end, Els1), {NewSEXT, STLS, STLSReq}; _ -> Acc end; ({xmlelement, "starttls", Attrs1, _Els1} = El1, {SEXT, _STLS, _STLSReq} = Acc) -> case xml:get_attr_s("xmlns", Attrs1) of ?NS_TLS -> Req = case xml:get_subtag(El1, "required") of {xmlelement, _, _, _} -> true; false -> false end, {SEXT, true, Req}; _ -> Acc end; (_, Acc) -> Acc end, {false, false, false}, Els), if (not SASLEXT) and (not StartTLS) and StateData#state.authenticated -> send_queue(StateData, StateData#state.queue), ?INFO_MSG("Connection established: ~s -> ~s", [StateData#state.myname, StateData#state.server]), ejabberd_hooks:run(s2s_connect_hook, [StateData#state.myname, StateData#state.server]), {next_state, stream_established, StateData#state{queue = queue:new()}}; SASLEXT and StateData#state.try_auth and (StateData#state.new /= false) -> send_element(StateData, {xmlelement, "auth", [{"xmlns", ?NS_SASL}, {"mechanism", "EXTERNAL"}], [{xmlcdata, jlib:encode_base64( StateData#state.myname)}]}), {next_state, wait_for_auth_result, StateData#state{try_auth = false}, ?FSMTIMEOUT}; StartTLS and StateData#state.tls and (not StateData#state.tls_enabled) -> send_element(StateData, {xmlelement, "starttls", [{"xmlns", ?NS_TLS}], []}), {next_state, wait_for_starttls_proceed, StateData, ?FSMTIMEOUT}; StartTLSRequired and (not StateData#state.tls) -> ?DEBUG("restarted: ~p", [{StateData#state.myname, StateData#state.server}]), ejabberd_socket:close(StateData#state.socket), {next_state, reopen_socket, StateData#state{socket = undefined, use_v10 = false}, ?FSMTIMEOUT}; StateData#state.db_enabled -> send_db_request(StateData); true -> ?DEBUG("restarted: ~p", [{StateData#state.myname, StateData#state.server}]), % TODO: clear message queue ejabberd_socket:close(StateData#state.socket), {next_state, reopen_socket, StateData#state{socket = undefined, use_v10 = false}, ?FSMTIMEOUT} end; _ -> send_text(StateData, xml:element_to_string(?SERR_BAD_FORMAT) ++ ?STREAM_TRAILER), ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad format)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData} end; wait_for_features({xmlstreamend, _Name}, StateData) -> ?INFO_MSG("wait_for_features: xmlstreamend", []), {stop, normal, StateData}; wait_for_features({xmlstreamerror, _}, StateData) -> send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), ?INFO_MSG("wait for features: xmlstreamerror", []), {stop, normal, StateData}; wait_for_features(timeout, StateData) -> ?INFO_MSG("wait for features: timeout", []), {stop, normal, StateData}; wait_for_features(closed, StateData) -> ?INFO_MSG("wait for features: closed", []), {stop, normal, StateData}. wait_for_auth_result({xmlstreamelement, El}, StateData) -> case El of {xmlelement, "success", Attrs, _Els} -> case xml:get_attr_s("xmlns", Attrs) of ?NS_SASL -> ?DEBUG("auth: ~p", [{StateData#state.myname, StateData#state.server}]), ejabberd_socket:reset_stream(StateData#state.socket), send_text(StateData, io_lib:format(?STREAM_HEADER, [StateData#state.myname, StateData#state.server, " version='1.0'"])), {next_state, wait_for_stream, StateData#state{streamid = new_id(), authenticated = true }, ?FSMTIMEOUT}; _ -> send_text(StateData, xml:element_to_string(?SERR_BAD_FORMAT) ++ ?STREAM_TRAILER), ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad format)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData} end; {xmlelement, "failure", Attrs, _Els} -> case xml:get_attr_s("xmlns", Attrs) of ?NS_SASL -> ?DEBUG("restarted: ~p", [{StateData#state.myname, StateData#state.server}]), ejabberd_socket:close(StateData#state.socket), {next_state, reopen_socket, StateData#state{socket = undefined}, ?FSMTIMEOUT}; _ -> send_text(StateData, xml:element_to_string(?SERR_BAD_FORMAT) ++ ?STREAM_TRAILER), ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad format)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData} end; _ -> send_text(StateData, xml:element_to_string(?SERR_BAD_FORMAT) ++ ?STREAM_TRAILER), ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad format)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData} end; wait_for_auth_result({xmlstreamend, _Name}, StateData) -> ?INFO_MSG("wait for auth result: xmlstreamend", []), {stop, normal, StateData}; wait_for_auth_result({xmlstreamerror, _}, StateData) -> send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), ?INFO_MSG("wait for auth result: xmlstreamerror", []), {stop, normal, StateData}; wait_for_auth_result(timeout, StateData) -> ?INFO_MSG("wait for auth result: timeout", []), {stop, normal, StateData}; wait_for_auth_result(closed, StateData) -> ?INFO_MSG("wait for auth result: closed", []), {stop, normal, StateData}. wait_for_starttls_proceed({xmlstreamelement, El}, StateData) -> case El of {xmlelement, "proceed", Attrs, _Els} -> case xml:get_attr_s("xmlns", Attrs) of ?NS_TLS -> ?DEBUG("starttls: ~p", [{StateData#state.myname, StateData#state.server}]), Socket = StateData#state.socket, TLSOpts = case ejabberd_config:get_local_option( {domain_certfile, StateData#state.myname}) of undefined -> StateData#state.tls_options; CertFile -> [{certfile, CertFile} | lists:keydelete( certfile, 1, StateData#state.tls_options)] end, TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts), NewStateData = StateData#state{socket = TLSSocket, streamid = new_id(), tls_enabled = true, tls_options = TLSOpts }, send_text(NewStateData, io_lib:format(?STREAM_HEADER, [StateData#state.myname, StateData#state.server, " version='1.0'"])), {next_state, wait_for_stream, NewStateData, ?FSMTIMEOUT}; _ -> send_text(StateData, xml:element_to_string(?SERR_BAD_FORMAT) ++ ?STREAM_TRAILER), ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad format)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData} end; _ -> ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad format)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData} end; wait_for_starttls_proceed({xmlstreamend, _Name}, StateData) -> ?INFO_MSG("wait for starttls proceed: xmlstreamend", []), {stop, normal, StateData}; wait_for_starttls_proceed({xmlstreamerror, _}, StateData) -> send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), ?INFO_MSG("wait for starttls proceed: xmlstreamerror", []), {stop, normal, StateData}; wait_for_starttls_proceed(timeout, StateData) -> ?INFO_MSG("wait for starttls proceed: timeout", []), {stop, normal, StateData}; wait_for_starttls_proceed(closed, StateData) -> ?INFO_MSG("wait for starttls proceed: closed", []), {stop, normal, StateData}. reopen_socket({xmlstreamelement, _El}, StateData) -> {next_state, reopen_socket, StateData, ?FSMTIMEOUT}; reopen_socket({xmlstreamend, _Name}, StateData) -> {next_state, reopen_socket, StateData, ?FSMTIMEOUT}; reopen_socket({xmlstreamerror, _}, StateData) -> {next_state, reopen_socket, StateData, ?FSMTIMEOUT}; reopen_socket(timeout, StateData) -> ?INFO_MSG("reopen socket: timeout", []), {stop, normal, StateData}; reopen_socket(closed, StateData) -> p1_fsm:send_event(self(), init), {next_state, open_socket, StateData, ?FSMTIMEOUT}. %% This state is use to avoid reconnecting to often to bad sockets wait_before_retry(_Event, StateData) -> {next_state, wait_before_retry, StateData, ?FSMTIMEOUT}. relay_to_bridge(stop, StateData) -> wait_before_reconnect(StateData); relay_to_bridge(closed, StateData) -> ?INFO_MSG("relay to bridge: ~s -> ~s (closed)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; relay_to_bridge(_Event, StateData) -> {next_state, relay_to_bridge, StateData}. stream_established({xmlstreamelement, El}, StateData) -> ?DEBUG("s2S stream established", []), case is_verify_res(El) of {verify, VTo, VFrom, VId, VType} -> ?DEBUG("recv verify: ~p", [{VFrom, VTo, VId, VType}]), case StateData#state.verify of {VPid, _VKey, _SID} -> case VType of "valid" -> p1_fsm:send_event( VPid, {valid, StateData#state.server, StateData#state.myname}); _ -> p1_fsm:send_event( VPid, {invalid, StateData#state.server, StateData#state.myname}) end; _ -> ok end; _ -> ok end, {next_state, stream_established, StateData}; stream_established({xmlstreamend, _Name}, StateData) -> ?INFO_MSG("Connection closed in stream established: ~s -> ~s (xmlstreamend)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; stream_established({xmlstreamerror, _}, StateData) -> send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), ?INFO_MSG("stream established: ~s -> ~s (xmlstreamerror)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; stream_established(timeout, StateData) -> ?INFO_MSG("stream established: ~s -> ~s (timeout)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}; stream_established(closed, StateData) -> ?INFO_MSG("stream established: ~s -> ~s (closed)", [StateData#state.myname, StateData#state.server]), {stop, normal, StateData}. %%---------------------------------------------------------------------- %% Func: StateName/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- %%state_name(Event, From, StateData) -> %% Reply = ok, %% {reply, Reply, state_name, StateData}. %%---------------------------------------------------------------------- %% Func: handle_event/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData, get_timeout_interval(StateName)}. %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 %% Returns: The associated StateData for this connection %% {reply, Reply, NextStateName, NextStateData} %% Reply = {state_infos, [{InfoName::atom(), InfoValue::any()] %%---------------------------------------------------------------------- handle_sync_event(get_state_infos, _From, StateName, StateData) -> {Addr,Port} = try ejabberd_socket:peername(StateData#state.socket) of {ok, {A,P}} -> {A,P}; {error, _} -> {unknown,unknown} catch _:_ -> {unknown,unknown} end, Infos = [ {direction, out}, {statename, StateName}, {addr, Addr}, {port, Port}, {streamid, StateData#state.streamid}, {use_v10, StateData#state.use_v10}, {tls, StateData#state.tls}, {tls_required, StateData#state.tls_required}, {tls_enabled, StateData#state.tls_enabled}, {tls_options, StateData#state.tls_options}, {authenticated, StateData#state.authenticated}, {db_enabled, StateData#state.db_enabled}, {try_auth, StateData#state.try_auth}, {myname, StateData#state.myname}, {server, StateData#state.server}, {delay_to_retry, StateData#state.delay_to_retry}, {verify, StateData#state.verify} ], Reply = {state_infos, Infos}, {reply,Reply,StateName,StateData}; %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- handle_sync_event(_Event, _From, StateName, StateData) -> Reply = ok, {reply, Reply, StateName, StateData, get_timeout_interval(StateName)}. code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_info/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_info({send_text, Text}, StateName, StateData) -> send_text(StateData, Text), cancel_timer(StateData#state.timer), Timer = erlang:start_timer(?S2STIMEOUT, self(), []), {next_state, StateName, StateData#state{timer = Timer}, get_timeout_interval(StateName)}; handle_info({send_element, El}, StateName, StateData) -> case StateName of stream_established -> cancel_timer(StateData#state.timer), Timer = erlang:start_timer(?S2STIMEOUT, self(), []), send_element(StateData, El), {next_state, StateName, StateData#state{timer = Timer}}; %% In this state we bounce all message: We are waiting before %% trying to reconnect wait_before_retry -> bounce_element(El, ?ERR_REMOTE_SERVER_NOT_FOUND), {next_state, StateName, StateData}; relay_to_bridge -> %% In this state we relay all outbound messages %% to a foreign protocol bridge such as SMTP, SIP, etc. {Mod, Fun} = StateData#state.bridge, ?DEBUG("relaying stanza via ~p:~p/1", [Mod, Fun]), case catch Mod:Fun(El) of {'EXIT', Reason} -> ?ERROR_MSG("Error while relaying to bridge: ~p", [Reason]), bounce_element(El, ?ERR_INTERNAL_SERVER_ERROR), wait_before_reconnect(StateData); _ -> {next_state, StateName, StateData} end; _ -> Q = queue:in(El, StateData#state.queue), {next_state, StateName, StateData#state{queue = Q}, get_timeout_interval(StateName)} end; handle_info({timeout, Timer, _}, wait_before_retry, #state{timer = Timer} = StateData) -> ?INFO_MSG("Reconnect delay expired: Will now retry to connect to ~s when needed.", [StateData#state.server]), {stop, normal, StateData}; handle_info({timeout, Timer, _}, _StateName, #state{timer = Timer} = StateData) -> ?INFO_MSG("Closing connection with ~s: timeout", [StateData#state.server]), {stop, normal, StateData}; handle_info(terminate_if_waiting_before_retry, wait_before_retry, StateData) -> {stop, normal, StateData}; handle_info(terminate_if_waiting_before_retry, StateName, StateData) -> {next_state, StateName, StateData, get_timeout_interval(StateName)}; handle_info(_, StateName, StateData) -> {next_state, StateName, StateData, get_timeout_interval(StateName)}. %%---------------------------------------------------------------------- %% Func: terminate/3 %% Purpose: Shutdown the fsm %% Returns: any %%---------------------------------------------------------------------- terminate(Reason, StateName, StateData) -> ?DEBUG("terminated: ~p", [{Reason, StateName}]), case StateData#state.new of false -> ok; Key -> ejabberd_s2s:remove_connection( {StateData#state.myname, StateData#state.server}, self(), Key) end, %% bounce queue manage by process and Erlang message queue bounce_queue(StateData#state.queue, ?ERR_REMOTE_SERVER_NOT_FOUND), bounce_messages(?ERR_REMOTE_SERVER_NOT_FOUND), case StateData#state.socket of undefined -> ok; _Socket -> ejabberd_socket:close(StateData#state.socket) end, ok. %%---------------------------------------------------------------------- %% Func: print_state/1 %% Purpose: Prepare the state to be printed on error log %% Returns: State to print %%---------------------------------------------------------------------- print_state(State) -> State. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- send_text(StateData, Text) -> ejabberd_socket:send(StateData#state.socket, Text). send_element(StateData, El) -> send_text(StateData, xml:element_to_binary(El)). send_queue(StateData, Q) -> case queue:out(Q) of {{value, El}, Q1} -> send_element(StateData, El), send_queue(StateData, Q1); {empty, _Q1} -> ok end. %% Bounce a single message (xmlelement) bounce_element(El, Error) -> {xmlelement, _Name, Attrs, _SubTags} = El, case xml:get_attr_s("type", Attrs) of "error" -> ok; "result" -> ok; _ -> Err = jlib:make_error_reply(El, Error), From = jlib:string_to_jid(xml:get_tag_attr_s("from", El)), To = jlib:string_to_jid(xml:get_tag_attr_s("to", El)), ejabberd_router:route(To, From, Err) end. bounce_queue(Q, Error) -> case queue:out(Q) of {{value, El}, Q1} -> bounce_element(El, Error), bounce_queue(Q1, Error); {empty, _} -> ok end. new_id() -> randoms:get_string(). cancel_timer(Timer) -> erlang:cancel_timer(Timer), receive {timeout, Timer, _} -> ok after 0 -> ok end. bounce_messages(Error) -> receive {send_element, El} -> bounce_element(El, Error), bounce_messages(Error) after 0 -> ok end. send_db_request(StateData) -> Server = StateData#state.server, New = case StateData#state.new of false -> case ejabberd_s2s:try_register( {StateData#state.myname, Server}) of {key, Key} -> Key; false -> false end; Key -> Key end, NewStateData = StateData#state{new = New}, try case New of false -> ok; Key1 -> send_element(StateData, {xmlelement, "db:result", [{"from", StateData#state.myname}, {"to", Server}], [{xmlcdata, Key1}]}) end, case StateData#state.verify of false -> ok; {_Pid, Key2, SID} -> send_element(StateData, {xmlelement, "db:verify", [{"from", StateData#state.myname}, {"to", StateData#state.server}, {"id", SID}], [{xmlcdata, Key2}]}) end, {next_state, wait_for_validation, NewStateData, ?FSMTIMEOUT*6} catch _:_ -> {stop, normal, NewStateData} end. is_verify_res({xmlelement, Name, Attrs, _Els}) when Name == "db:result" -> {result, xml:get_attr_s("to", Attrs), xml:get_attr_s("from", Attrs), xml:get_attr_s("id", Attrs), xml:get_attr_s("type", Attrs)}; is_verify_res({xmlelement, Name, Attrs, _Els}) when Name == "db:verify" -> {verify, xml:get_attr_s("to", Attrs), xml:get_attr_s("from", Attrs), xml:get_attr_s("id", Attrs), xml:get_attr_s("type", Attrs)}; is_verify_res(_) -> false. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% SRV support -include_lib("kernel/include/inet.hrl"). get_addr_port(Server) -> Res = srv_lookup(Server), case Res of {error, Reason} -> ?DEBUG("srv lookup of '~s' failed: ~p~n", [Server, Reason]), [{Server, outgoing_s2s_port()}]; {ok, HEnt} -> ?DEBUG("srv lookup of '~s': ~p~n", [Server, HEnt#hostent.h_addr_list]), AddrList = HEnt#hostent.h_addr_list, %% Probabilities are not exactly proportional to weights %% for simplicity (higher weigths are overvalued) {A1, A2, A3} = now(), random:seed(A1, A2, A3), case (catch lists:map( fun({Priority, Weight, Port, Host}) -> N = case Weight of 0 -> 0; _ -> (Weight + 1) * random:uniform() end, {Priority * 65536 - N, Host, Port} end, AddrList)) of SortedList = [_|_] -> List = lists:map( fun({_, Host, Port}) -> {Host, Port} end, lists:keysort(1, SortedList)), ?DEBUG("srv lookup of '~s': ~p~n", [Server, List]), List; _ -> [{Server, outgoing_s2s_port()}] end end. srv_lookup(Server) -> Options = case ejabberd_config:get_local_option(s2s_dns_options) of L when is_list(L) -> L; _ -> [] end, TimeoutMs = timer:seconds(proplists:get_value(timeout, Options, 10)), Retries = proplists:get_value(retries, Options, 2), srv_lookup(Server, TimeoutMs, Retries). %% XXX - this behaviour is suboptimal in the case that the domain %% has a "_xmpp-server._tcp." but not a "_jabber._tcp." record and %% we don't get a DNS reply for the "_xmpp-server._tcp." lookup. In this %% case we'll give up when we get the "_jabber._tcp." nxdomain reply. srv_lookup(_Server, _Timeout, Retries) when Retries < 1 -> {error, timeout}; srv_lookup(Server, Timeout, Retries) -> case inet_res:getbyname("_xmpp-server._tcp." ++ Server, srv, Timeout) of {error, _Reason} -> case inet_res:getbyname("_jabber._tcp." ++ Server, srv, Timeout) of {error, timeout} -> ?ERROR_MSG("The DNS servers~n ~p~ntimed out on request" " for ~p IN SRV." " You should check your DNS configuration.", [inet_db:res_option(nameserver), Server]), srv_lookup(Server, Timeout, Retries - 1); R -> R end; {ok, _HEnt} = R -> R end. test_get_addr_port(Server) -> lists:foldl( fun(_, Acc) -> [HostPort | _] = get_addr_port(Server), case lists:keysearch(HostPort, 1, Acc) of false -> [{HostPort, 1} | Acc]; {value, {_, Num}} -> lists:keyreplace(HostPort, 1, Acc, {HostPort, Num + 1}) end end, [], lists:seq(1, 100000)). get_addrs(Host, Family) -> Type = case Family of inet4 -> inet; ipv4 -> inet; inet6 -> inet6; ipv6 -> inet6 end, case inet:gethostbyname(Host, Type) of {ok, #hostent{h_addr_list = Addrs}} -> ?DEBUG("~s of ~s resolved to: ~p~n", [Type, Host, Addrs]), Addrs; {error, Reason} -> ?DEBUG("~s lookup of '~s' failed: ~p~n", [Type, Host, Reason]), [] end. outgoing_s2s_port() -> case ejabberd_config:get_local_option(outgoing_s2s_port) of Port when is_integer(Port) -> Port; undefined -> 5269 end. outgoing_s2s_families() -> case ejabberd_config:get_local_option(outgoing_s2s_options) of {Families, _} when is_list(Families) -> Families; undefined -> %% DISCUSSION: Why prefer IPv4 first? %% %% IPv4 connectivity will be available for everyone for %% many years to come. So, there's absolutely no benefit %% in preferring IPv6 connections which are flaky at best %% nowadays. %% %% On the other hand content providers hesitate putting up %% AAAA records for their sites due to the mentioned %% quality of current IPv6 connectivity. Making IPv6 the a %% `fallback' may avoid these problems elegantly. [ipv4, ipv6] end. outgoing_s2s_timeout() -> case ejabberd_config:get_local_option(outgoing_s2s_options) of {_, Timeout} when is_integer(Timeout) -> Timeout; {_, infinity} -> infinity; undefined -> %% 10 seconds 10000 end. %% Human readable S2S logging: Log only new outgoing connections as INFO %% Do not log dialback log_s2s_out(false, _, _, _) -> ok; %% Log new outgoing connections: log_s2s_out(_, Myname, Server, Tls) -> ?INFO_MSG("Trying to open s2s connection: ~s -> ~s with TLS=~p", [Myname, Server, Tls]). %% Calculate timeout depending on which state we are in: %% Can return integer > 0 | infinity get_timeout_interval(StateName) -> case StateName of %% Validation implies dialback: Networking can take longer: wait_for_validation -> ?FSMTIMEOUT*6; %% When stream is established, we only rely on S2S Timeout timer: stream_established -> infinity; _ -> ?FSMTIMEOUT end. %% This function is intended to be called at the end of a state %% function that want to wait for a reconnect delay before stopping. wait_before_reconnect(StateData) -> %% bounce queue manage by process and Erlang message queue bounce_queue(StateData#state.queue, ?ERR_REMOTE_SERVER_NOT_FOUND), bounce_messages(?ERR_REMOTE_SERVER_NOT_FOUND), cancel_timer(StateData#state.timer), Delay = case StateData#state.delay_to_retry of undefined_delay -> %% The initial delay is random between 1 and 15 seconds %% Return a random integer between 1000 and 15000 {_, _, MicroSecs} = now(), (MicroSecs rem 14000) + 1000; D1 -> %% Duplicate the delay with each successive failed %% reconnection attempt, but don't exceed the max lists:min([D1 * 2, get_max_retry_delay()]) end, Timer = erlang:start_timer(Delay, self(), []), {next_state, wait_before_retry, StateData#state{timer=Timer, delay_to_retry = Delay, queue = queue:new()}}. %% @doc Get the maximum allowed delay for retry to reconnect (in miliseconds). %% The default value is 5 minutes. %% The option {s2s_max_retry_delay, Seconds} can be used (in seconds). %% @spec () -> integer() get_max_retry_delay() -> case ejabberd_config:get_local_option(s2s_max_retry_delay) of Seconds when is_integer(Seconds) -> Seconds*1000; _ -> ?MAX_RETRY_DELAY end. %% Terminate s2s_out connections that are in state wait_before_retry terminate_if_waiting_delay(From, To) -> FromTo = {From, To}, Pids = ejabberd_s2s:get_connections_pids(FromTo), lists:foreach( fun(Pid) -> Pid ! terminate_if_waiting_before_retry end, Pids). fsm_limit_opts() -> case ejabberd_config:get_local_option(max_fsm_queue) of N when is_integer(N) -> [{max_queue, N}]; _ -> [] end. ejabberd-2.1.11/src/mod_stats.erl0000664000000000000000000001645012240230175013514 0ustar %%%---------------------------------------------------------------------- %%% File : mod_stats.erl %%% Author : Alexey Shchepin %%% Purpose : Basic statistics. %%% Created : 11 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_stats). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_local_iq/3]). -include("jlib.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_STATS, ?MODULE, process_local_iq, IQDisc). stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_STATS). process_local_iq(_From, To, #iq{id = _ID, type = Type, xmlns = XMLNS, sub_el = SubEl} = IQ) -> %%Lang = xml:get_tag_attr_s("xml:lang", SubEl), case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> {xmlelement, _, _Attrs, Els} = SubEl, Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"), Names = get_names(Els, []), case get_local_stats(To#jid.server, Node, Names) of {result, Res} -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], Res}]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end end. get_names([], Res) -> Res; get_names([{xmlelement, "stat", Attrs, _} | Els], Res) -> Name = xml:get_attr_s("name", Attrs), case Name of "" -> get_names(Els, Res); _ -> get_names(Els, [Name | Res]) end; get_names([_ | Els], Res) -> get_names(Els, Res). -define(STAT(Name), {xmlelement, "stat", [{"name", Name}], []}). get_local_stats(_Server, [], []) -> {result, [?STAT("users/online"), ?STAT("users/total"), ?STAT("users/all-hosts/online"), ?STAT("users/all-hosts/total") ]}; get_local_stats(Server, [], Names) -> {result, lists:map(fun(Name) -> get_local_stat(Server, [], Name) end, Names)}; get_local_stats(_Server, ["running nodes", _], []) -> {result, [?STAT("time/uptime"), ?STAT("time/cputime"), ?STAT("users/online"), ?STAT("transactions/committed"), ?STAT("transactions/aborted"), ?STAT("transactions/restarted"), ?STAT("transactions/logged") ]}; get_local_stats(_Server, ["running nodes", ENode], Names) -> case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> {result, lists:map(fun(Name) -> get_node_stat(Node, Name) end, Names)} end; get_local_stats(_Server, _, _) -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED}. -define(STATVAL(Val, Unit), {xmlelement, "stat", [{"name", Name}, {"units", Unit}, {"value", Val} ], []}). -define(STATERR(Code, Desc), {xmlelement, "stat", [{"name", Name}], [{xmlelement, "error", [{"code", Code}], [{xmlcdata, Desc}]}]}). get_local_stat(Server, [], Name) when Name == "users/online" -> case catch ejabberd_sm:get_vh_session_list(Server) of {'EXIT', _Reason} -> ?STATERR("500", "Internal Server Error"); Users -> ?STATVAL(integer_to_list(length(Users)), "users") end; get_local_stat(Server, [], Name) when Name == "users/total" -> %%LServer = jlib:nameprep(Server), case catch ejabberd_auth:get_vh_registered_users_number(Server) of {'EXIT', _Reason} -> ?STATERR("500", "Internal Server Error"); NUsers -> ?STATVAL(integer_to_list(NUsers), "users") end; get_local_stat(_Server, [], Name) when Name == "users/all-hosts/online" -> case catch mnesia:table_info(session, size) of {'EXIT', _Reason} -> ?STATERR("500", "Internal Server Error"); Users -> ?STATVAL(integer_to_list(Users), "users") end; get_local_stat(_Server, [], Name) when Name == "users/all-hosts/total" -> NumUsers = lists:foldl( fun(Host, Total) -> ejabberd_auth:get_vh_registered_users_number(Host) + Total end, 0, ejabberd_config:get_global_option(hosts)), ?STATVAL(integer_to_list(NumUsers), "users"); get_local_stat(_Server, _, Name) -> ?STATERR("404", "Not Found"). get_node_stat(Node, Name) when Name == "time/uptime" -> case catch rpc:call(Node, erlang, statistics, [wall_clock]) of {badrpc, _Reason} -> ?STATERR("500", "Internal Server Error"); CPUTime -> ?STATVAL( io_lib:format("~.3f", [element(1, CPUTime)/1000]), "seconds") end; get_node_stat(Node, Name) when Name == "time/cputime" -> case catch rpc:call(Node, erlang, statistics, [runtime]) of {badrpc, _Reason} -> ?STATERR("500", "Internal Server Error"); RunTime -> ?STATVAL( io_lib:format("~.3f", [element(1, RunTime)/1000]), "seconds") end; get_node_stat(Node, Name) when Name == "users/online" -> case catch rpc:call(Node, ejabberd_sm, dirty_get_my_sessions_list, []) of {badrpc, _Reason} -> ?STATERR("500", "Internal Server Error"); Users -> ?STATVAL(integer_to_list(length(Users)), "users") end; get_node_stat(Node, Name) when Name == "transactions/committed" -> case catch rpc:call(Node, mnesia, system_info, [transaction_commits]) of {badrpc, _Reason} -> ?STATERR("500", "Internal Server Error"); Transactions -> ?STATVAL(integer_to_list(Transactions), "transactions") end; get_node_stat(Node, Name) when Name == "transactions/aborted" -> case catch rpc:call(Node, mnesia, system_info, [transaction_failures]) of {badrpc, _Reason} -> ?STATERR("500", "Internal Server Error"); Transactions -> ?STATVAL(integer_to_list(Transactions), "transactions") end; get_node_stat(Node, Name) when Name == "transactions/restarted" -> case catch rpc:call(Node, mnesia, system_info, [transaction_restarts]) of {badrpc, _Reason} -> ?STATERR("500", "Internal Server Error"); Transactions -> ?STATVAL(integer_to_list(Transactions), "transactions") end; get_node_stat(Node, Name) when Name == "transactions/logged" -> case catch rpc:call(Node, mnesia, system_info, [transaction_log_writes]) of {badrpc, _Reason} -> ?STATERR("500", "Internal Server Error"); Transactions -> ?STATVAL(integer_to_list(Transactions), "transactions") end; get_node_stat(_, Name) -> ?STATERR("404", "Not Found"). search_running_node(SNode) -> search_running_node(SNode, mnesia:system_info(running_db_nodes)). search_running_node(_, []) -> false; search_running_node(SNode, [Node | Nodes]) -> case atom_to_list(Node) of SNode -> Node; _ -> search_running_node(SNode, Nodes) end. ejabberd-2.1.11/src/Makefile.in0000664000000000000000000001721712240230175013062 0ustar # $Id$ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ EXPAT_CFLAGS = @EXPAT_CFLAGS@ ERLANG_CFLAGS= @ERLANG_CFLAGS@ EXPAT_LIBS = @EXPAT_LIBS@ ERLANG_LIBS = @ERLANG_LIBS@ ASN_FLAGS = -bber_bin +der +compact_bit_string +optimize +noobj INSTALLUSER=@INSTALLUSER@ # if no user was enabled, don't set privileges or ownership ifeq ($(INSTALLUSER),) O_USER= G_USER= CHOWN_COMMAND=echo CHOWN_OUTPUT=/dev/null INIT_USER=root else O_USER=-o $(INSTALLUSER) G_USER=-g $(INSTALLUSER) CHOWN_COMMAND=chown CHOWN_OUTPUT=&1 INIT_USER=$(INSTALLUSER) endif EFLAGS += @ERLANG_SSLVER@ -pa . ERLANG_CFLAGS += @ERLANG_SSLVER@ # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif DEBUGTOOLS = p1_prof.erl ifdef debugtools SOURCES+=$(DEBUGTOOLS) endif ifeq (@hipe@, true) EFLAGS+=+native endif ifeq (@roster_gateway_workaround@, true) EFLAGS+=-DROSTER_GATEWAY_WORKAROUND endif ifeq (@full_xml@, true) EFLAGS+=-DFULL_XML_SUPPORT endif ifeq (@nif@, true) EFLAGS+=-DNIF ERLSHLIBS=xml.so endif ifeq (@transient_supervisors@, false) EFLAGS+=-DNO_TRANSIENT_SUPERVISORS endif ifeq (@md2@, true) EFLAGS+=-DHAVE_MD2 ERLANG_CFLAGS += -DHAVE_MD2 endif INSTALL_EPAM= ifeq (@pam@, pam) INSTALL_EPAM=install -m 750 $(O_USER) epam $(PBINDIR) endif prefix = @prefix@ exec_prefix = @exec_prefix@ SUBDIRS = @mod_irc@ @mod_pubsub@ @mod_muc@ @mod_proxy65@ @eldap@ @pam@ @web@ stringprep stun @tls@ @odbc@ @ejabberd_zlib@ ERLSHLIBS += expat_erl.so ERLBEHAVS = cyrsasl.erl gen_mod.erl p1_fsm.erl SOURCES_ALL = $(wildcard *.erl) SOURCES_MISC = $(ERLBEHAVS) $(DEBUGTOOLS) SOURCES += $(filter-out $(SOURCES_MISC),$(SOURCES_ALL)) ERLBEHAVBEAMS = $(ERLBEHAVS:.erl=.beam) BEAMS = $(SOURCES:.erl=.beam) DESTDIR = # /etc/ejabberd/ ETCDIR = $(DESTDIR)@sysconfdir@/ejabberd # /sbin/ SBINDIR = $(DESTDIR)@sbindir@ # /lib/ejabberd/ EJABBERDDIR = $(DESTDIR)@libdir@/ejabberd # /share/doc/ejabberd PACKAGE_TARNAME = @PACKAGE_TARNAME@ datarootdir = @datarootdir@ DOCDIR = $(DESTDIR)@docdir@ # /usr/lib/ejabberd/ebin/ BEAMDIR = $(EJABBERDDIR)/ebin # /usr/lib/ejabberd/include/ INCLUDEDIR = $(EJABBERDDIR)/include # /usr/lib/ejabberd/priv/ PRIVDIR = $(EJABBERDDIR)/priv # /usr/lib/ejabberd/priv/bin PBINDIR = $(PRIVDIR)/bin # /usr/lib/ejabberd/priv/lib SODIR = $(PRIVDIR)/lib # /usr/lib/ejabberd/priv/msgs MSGSDIR = $(PRIVDIR)/msgs # /var/lib/ejabberd/ SPOOLDIR = $(DESTDIR)@localstatedir@/lib/ejabberd # /var/lock/ejabberdctl CTLLOCKDIR = $(DESTDIR)@localstatedir@/lock/ejabberdctl # /var/lib/ejabberd/.erlang.cookie COOKIEFILE = $(SPOOLDIR)/.erlang.cookie # /var/log/ejabberd/ LOGDIR = $(DESTDIR)@localstatedir@/log/ejabberd # Assume Linux-style dynamic library flags DYNAMIC_LIB_CFLAGS = -fpic -shared ifeq ($(shell uname),Darwin) DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress endif ifeq ($(shell uname),SunOs) DYNAMIC_LIB_CFLAGS = -KPIC -G -z text endif all: $(ERLSHLIBS) compile-beam all-recursive compile-beam: XmppAddr.hrl $(ERLBEHAVBEAMS) $(BEAMS) $(BEAMS): $(ERLBEHAVBEAMS) all-recursive: $(ERLBEHAVBEAMS) %.beam: %.erl @ERLC@ -W $(EFLAGS) $< all-recursive install-recursive uninstall-recursive \ clean-recursive distclean-recursive \ mostlyclean-recursive maintainer-clean-recursive: @subdirs="$(SUBDIRS)"; for subdir in $$subdirs; do \ target=`echo $@|sed 's,-recursive,,'`; \ echo making $$target in $$subdir; \ (cd $$subdir && $(MAKE) $$target) || exit 1; \ done %.hrl: %.asn1 @ERLC@ $(ASN_FLAGS) $< @ERLC@ -W $(EFLAGS) $*.erl $(ERLSHLIBS): %.so: %.c $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) \ $(subst ../,,$(subst .so,.c,$@)) \ $(EXPAT_LIBS) \ $(EXPAT_CFLAGS) \ $(ERLANG_LIBS) \ $(ERLANG_CFLAGS) \ -o $@ \ $(DYNAMIC_LIB_CFLAGS) translations: ../contrib/extract_translations/prepare-translation.sh -updateall install: all # # Configuration files install -d -m 750 $(G_USER) $(ETCDIR) [ -f $(ETCDIR)/ejabberd.cfg ] \ && install -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg-new \ || install -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg sed -e "s*@rootdir@*@prefix@*" \ -e "s*@installuser@*@INSTALLUSER@*" \ -e "s*@LIBDIR@*@libdir@*" \ -e "s*@SYSCONFDIR@*@sysconfdir@*" \ -e "s*@LOCALSTATEDIR@*@localstatedir@*" \ -e "s*@DOCDIR@*@docdir@*" \ -e "s*@erl@*@ERL@*" ejabberdctl.template \ > ejabberdctl.example [ -f $(ETCDIR)/ejabberdctl.cfg ] \ && install -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg-new \ || install -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg install -b -m 644 $(G_USER) inetrc $(ETCDIR)/inetrc # # Administration script [ -d $(SBINDIR) ] || install -d -m 755 $(SBINDIR) install -m 550 $(G_USER) ejabberdctl.example $(SBINDIR)/ejabberdctl # # Init script sed -e "s*@ctlscriptpath@*$(SBINDIR)*" \ -e "s*@installuser@*$(INIT_USER)*" ejabberd.init.template \ > ejabberd.init chmod 755 ejabberd.init # # Binary Erlang files install -d $(BEAMDIR) install -m 644 *.app $(BEAMDIR) install -m 644 *.beam $(BEAMDIR) rm -f $(BEAMDIR)/configure.beam # # ejabberd header files install -d $(INCLUDEDIR) install -m 644 *.hrl $(INCLUDEDIR) install -d $(INCLUDEDIR)/eldap/ install -m 644 eldap/*.hrl $(INCLUDEDIR)/eldap/ install -d $(INCLUDEDIR)/mod_muc/ install -m 644 mod_muc/*.hrl $(INCLUDEDIR)/mod_muc/ install -d $(INCLUDEDIR)/mod_proxy65/ install -m 644 mod_proxy65/*.hrl $(INCLUDEDIR)/mod_proxy65/ install -d $(INCLUDEDIR)/mod_pubsub/ install -m 644 mod_pubsub/*.hrl $(INCLUDEDIR)/mod_pubsub/ install -d $(INCLUDEDIR)/web/ install -m 644 web/*.hrl $(INCLUDEDIR)/web/ # # Binary C programs install -d $(PBINDIR) install -m 750 $(O_USER) ../tools/captcha.sh $(PBINDIR) $(INSTALL_EPAM) # # Binary system libraries install -d $(SODIR) install -m 644 *.so $(SODIR) # # Translated strings install -d $(MSGSDIR) install -m 644 msgs/*.msg $(MSGSDIR) # # Spool directory install -d -m 750 $(O_USER) $(SPOOLDIR) $(CHOWN_COMMAND) -R @INSTALLUSER@ $(SPOOLDIR) >$(CHOWN_OUTPUT) chmod -R 750 $(SPOOLDIR) [ ! -f $(COOKIEFILE) ] || { $(CHOWN_COMMAND) @INSTALLUSER@ $(COOKIEFILE) >$(CHOWN_OUTPUT) ; chmod 400 $(COOKIEFILE) ; } # # ejabberdctl lock directory install -d -m 750 $(O_USER) $(CTLLOCKDIR) $(CHOWN_COMMAND) -R @INSTALLUSER@ $(CTLLOCKDIR) >$(CHOWN_OUTPUT) chmod -R 750 $(CTLLOCKDIR) # # Log directory install -d -m 750 $(O_USER) $(LOGDIR) $(CHOWN_COMMAND) -R @INSTALLUSER@ $(LOGDIR) >$(CHOWN_OUTPUT) chmod -R 750 $(LOGDIR) # # Documentation install -d $(DOCDIR) install -m 644 ../doc/dev.html $(DOCDIR) install -m 644 ../doc/guide.html $(DOCDIR) install -m 644 ../doc/*.png $(DOCDIR) install -m 644 ../doc/*.txt $(DOCDIR) [ -f ../doc/guide.pdf ] \ && install -m 644 ../doc/guide.pdf $(DOCDIR) \ || echo "No ../doc/guide.pdf was built" install -m 644 ../COPYING $(DOCDIR) uninstall: uninstall-binary uninstall-binary: rm -f $(SBINDIR)/ejabberdctl rm -fr $(DOCDIR) rm -f $(BEAMDIR)/*.beam rm -f $(BEAMDIR)/*.app rm -fr $(BEAMDIR) rm -f $(INCLUDEDIR)/*.hrl rm -fr $(INCLUDEDIR) rm -fr $(PBINDIR) rm -f $(SODIR)/*.so rm -fr $(SODIR) rm -f $(MSGSDIR)/*.msgs rm -fr $(MSGSDIR) rm -fr $(PRIVDIR) rm -fr $(EJABBERDDIR) uninstall-all: uninstall-binary rm -rf $(ETCDIR) rm -rf $(EJABBERDDIR) rm -rf $(SPOOLDIR) rm -rf $(CTLLOCKDIR) rm -rf $(LOGDIR) clean: clean-recursive clean-local clean-local: rm -f *.beam $(ERLSHLIBS) epam ejabberdctl.example rm -f XmppAddr.asn1db XmppAddr.erl XmppAddr.hrl distclean: distclean-recursive clean-local rm -f config.status rm -f config.log rm -f Makefile [ ! -f ../ChangeLog ] || rm -f ../ChangeLog TAGS: etags *.erl Makefile: Makefile.in dialyzer: $(BEAMS) @dialyzer -c . ejabberd-2.1.11/src/ejabberd_listener.erl0000664000000000000000000003644512240230175015170 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_listener.erl %%% Author : Alexey Shchepin %%% Purpose : Manage socket listener %%% Created : 16 Nov 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_listener). -author('alexey@process-one.net'). -export([start_link/0, init/1, start/3, init/3, start_listeners/0, start_listener/3, stop_listeners/0, stop_listener/2, parse_listener_portip/2, add_listener/3, delete_listener/2 ]). -include("ejabberd.hrl"). %% We do not block on send anymore. -define(TCP_SEND_TIMEOUT, 15000). start_link() -> supervisor:start_link({local, ejabberd_listeners}, ?MODULE, []). init(_) -> ets:new(listen_sockets, [named_table, public]), bind_tcp_ports(), {ok, {{one_for_one, 10, 1}, []}}. bind_tcp_ports() -> case ejabberd_config:get_local_option(listen) of undefined -> ignore; Ls -> lists:foreach( fun({Port, Module, Opts}) -> ModuleRaw = strip_frontend(Module), case ModuleRaw:socket_type() of independent -> ok; _ -> bind_tcp_port(Port, Module, Opts) end end, Ls) end. bind_tcp_port(PortIP, Module, RawOpts) -> try check_listener_options(RawOpts) of ok -> {Port, IPT, IPS, IPV, Proto, OptsClean} = parse_listener_portip(PortIP, RawOpts), {_Opts, SockOpts} = prepare_opts(IPT, IPV, OptsClean), case Proto of udp -> ok; _ -> ListenSocket = listen_tcp(PortIP, Module, SockOpts, Port, IPS), ets:insert(listen_sockets, {PortIP, ListenSocket}) end catch throw:{error, Error} -> ?ERROR_MSG(Error, []) end. start_listeners() -> case ejabberd_config:get_local_option(listen) of undefined -> ignore; Ls -> Ls2 = lists:map( fun({Port, Module, Opts}) -> case start_listener(Port, Module, Opts) of {ok, _Pid} = R -> R; {error, Error} -> throw(Error) end end, Ls), report_duplicated_portips(Ls), {ok, {{one_for_one, 10, 1}, Ls2}} end. report_duplicated_portips(L) -> LKeys = [Port || {Port, _, _} <- L], LNoDupsKeys = proplists:get_keys(L), case LKeys -- LNoDupsKeys of [] -> ok; Dups -> ?CRITICAL_MSG("In the ejabberd configuration there are duplicated " "Port number + IP address:~n ~p", [Dups]) end. start(Port, Module, Opts) -> %% Check if the module is an ejabberd listener or an independent listener ModuleRaw = strip_frontend(Module), case ModuleRaw:socket_type() of independent -> ModuleRaw:start_listener(Port, Opts); _ -> start_dependent(Port, Module, Opts) end. %% @spec(Port, Module, Opts) -> {ok, Pid} | {error, ErrorMessage} start_dependent(Port, Module, Opts) -> try check_listener_options(Opts) of ok -> proc_lib:start_link(?MODULE, init, [Port, Module, Opts]) catch throw:{error, Error} -> ?ERROR_MSG(Error, []), {error, Error} end. init(PortIP, Module, RawOpts) -> {Port, IPT, IPS, IPV, Proto, OptsClean} = parse_listener_portip(PortIP, RawOpts), {Opts, SockOpts} = prepare_opts(IPT, IPV, OptsClean), if Proto == udp -> init_udp(PortIP, Module, Opts, SockOpts, Port, IPS); true -> init_tcp(PortIP, Module, Opts, SockOpts, Port, IPS) end. init_udp(PortIP, Module, Opts, SockOpts, Port, IPS) -> case gen_udp:open(Port, [binary, {active, false}, {reuseaddr, true} | SockOpts]) of {ok, Socket} -> %% Inform my parent that this port was opened succesfully proc_lib:init_ack({ok, self()}), udp_recv(Socket, Module, Opts); {error, Reason} -> socket_error(Reason, PortIP, Module, SockOpts, Port, IPS) end. init_tcp(PortIP, Module, Opts, SockOpts, Port, IPS) -> ListenSocket = listen_tcp(PortIP, Module, SockOpts, Port, IPS), %% Inform my parent that this port was opened succesfully proc_lib:init_ack({ok, self()}), %% And now start accepting connection attempts accept(ListenSocket, Module, Opts). listen_tcp(PortIP, Module, SockOpts, Port, IPS) -> case ets:lookup(listen_sockets, PortIP) of [{PortIP, ListenSocket}] -> ?INFO_MSG("Reusing listening port for ~p", [Port]), ets:delete(listen_sockets, Port), ListenSocket; _ -> SockOpts2 = try erlang:system_info(otp_release) >= "R13B" of true -> [{send_timeout_close, true} | SockOpts]; false -> SockOpts catch _:_ -> [] end, Res = gen_tcp:listen(Port, [binary, {packet, 0}, {active, false}, {reuseaddr, true}, {nodelay, true}, {send_timeout, ?TCP_SEND_TIMEOUT}, {keepalive, true} | SockOpts2]), case Res of {ok, ListenSocket} -> ListenSocket; {error, Reason} -> socket_error(Reason, PortIP, Module, SockOpts, Port, IPS) end end. %% @spec (PortIP, Opts) -> {Port, IPT, IPS, IPV, OptsClean} %% where %% PortIP = Port | {Port, IPT | IPS} %% Port = integer() %% IPT = tuple() %% IPS = string() %% IPV = inet | inet6 %% Opts = [IPV | {ip, IPT} | atom() | tuple()] %% OptsClean = [atom() | tuple()] %% @doc Parse any kind of ejabberd listener specification. %% The parsed options are returned in several formats. %% OptsClean does not include inet/inet6 or ip options. %% Opts can include the options inet6 and {ip, Tuple}, %% but they are only used when no IP address was specified in the PortIP. %% The IP version (either IPv4 or IPv6) is inferred from the IP address type, %% so the option inet/inet6 is only used when no IP is specified at all. parse_listener_portip(PortIP, Opts) -> {IPOpt, Opts2} = strip_ip_option(Opts), {IPVOpt, OptsClean} = case lists:member(inet6, Opts2) of true -> {inet6, Opts2 -- [inet6]}; false -> {inet, Opts2} end, {Port, IPT, IPS, Proto} = case add_proto(PortIP, Opts) of {P, Prot} -> T = get_ip_tuple(IPOpt, IPVOpt), S = inet_parse:ntoa(T), {P, T, S, Prot}; {P, T, Prot} when is_integer(P) and is_tuple(T) -> S = inet_parse:ntoa(T), {P, T, S, Prot}; {P, S, Prot} when is_integer(P) and is_list(S) -> [S | _] = string:tokens(S, "/"), {ok, T} = inet_parse:address(S), {P, T, S, Prot} end, IPV = case size(IPT) of 4 -> inet; 8 -> inet6 end, {Port, IPT, IPS, IPV, Proto, OptsClean}. prepare_opts(IPT, IPV, OptsClean) -> %% The first inet|inet6 and the last {ip, _} work, %% so overriding those in Opts Opts = [IPV | OptsClean] ++ [{ip, IPT}], SockOpts = lists:filter(fun({ip, _}) -> true; (inet6) -> true; (inet) -> true; ({backlog, _}) -> true; (_) -> false end, Opts), {Opts, SockOpts}. add_proto(Port, Opts) when is_integer(Port) -> {Port, get_proto(Opts)}; add_proto({Port, Proto}, _Opts) when is_atom(Proto) -> {Port, normalize_proto(Proto)}; add_proto({Port, Addr}, Opts) -> {Port, Addr, get_proto(Opts)}; add_proto({Port, Addr, Proto}, _Opts) -> {Port, Addr, normalize_proto(Proto)}. strip_ip_option(Opts) -> {IPL, OptsNoIP} = lists:partition( fun({ip, _}) -> true; (_) -> false end, Opts), case IPL of %% Only the first ip option is considered [{ip, T1} | _] when is_tuple(T1) -> {T1, OptsNoIP}; [] -> {no_ip_option, OptsNoIP} end. get_ip_tuple(no_ip_option, inet) -> {0, 0, 0, 0}; get_ip_tuple(no_ip_option, inet6) -> {0, 0, 0, 0, 0, 0, 0, 0}; get_ip_tuple(IPOpt, _IPVOpt) -> IPOpt. accept(ListenSocket, Module, Opts) -> case gen_tcp:accept(ListenSocket) of {ok, Socket} -> case {inet:sockname(Socket), inet:peername(Socket)} of {{ok, Addr}, {ok, PAddr}} -> ?INFO_MSG("(~w) Accepted connection ~w -> ~w", [Socket, PAddr, Addr]); _ -> ok end, CallMod = case is_frontend(Module) of true -> ejabberd_frontend_socket; false -> ejabberd_socket end, CallMod:start(strip_frontend(Module), gen_tcp, Socket, Opts), accept(ListenSocket, Module, Opts); {error, Reason} -> ?ERROR_MSG("(~w) Failed TCP accept: ~w", [ListenSocket, Reason]), accept(ListenSocket, Module, Opts) end. udp_recv(Socket, Module, Opts) -> case gen_udp:recv(Socket, 0) of {ok, {Addr, Port, Packet}} -> case catch Module:udp_recv(Socket, Addr, Port, Packet, Opts) of {'EXIT', Reason} -> ?ERROR_MSG("failed to process UDP packet:~n" "** Source: {~p, ~p}~n" "** Reason: ~p~n** Packet: ~p", [Addr, Port, Reason, Packet]); _ -> ok end, udp_recv(Socket, Module, Opts); {error, Reason} -> ?ERROR_MSG("unexpected UDP error: ~s", [format_error(Reason)]), throw({error, Reason}) end. %% @spec (Port, Module, Opts) -> {ok, Pid} | {error, Error} start_listener(Port, Module, Opts) -> case start_listener2(Port, Module, Opts) of {ok, _Pid} = R -> R; {error, {{'EXIT', {undef, [{M, _F, _A}|_]}}, _} = Error} -> ?ERROR_MSG("Error starting the ejabberd listener: ~p.~n" "It could not be loaded or is not an ejabberd listener.~n" "Error: ~p~n", [Module, Error]), {error, {module_not_available, M}}; {error, {already_started, Pid}} -> {ok, Pid}; {error, Error} -> {error, Error} end. %% @spec (Port, Module, Opts) -> {ok, Pid} | {error, Error} start_listener2(Port, Module, Opts) -> %% It is only required to start the supervisor in some cases. %% But it doesn't hurt to attempt to start it for any listener. %% So, it's normal (and harmless) that in most cases this call returns: {error, {already_started, pid()}} start_module_sup(Port, Module), start_listener_sup(Port, Module, Opts). start_module_sup(_Port, Module) -> Proc1 = gen_mod:get_module_proc("sup", Module), ChildSpec1 = {Proc1, {ejabberd_tmp_sup, start_link, [Proc1, strip_frontend(Module)]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, supervisor:start_child(ejabberd_sup, ChildSpec1). start_listener_sup(Port, Module, Opts) -> ChildSpec = {Port, {?MODULE, start, [Port, Module, Opts]}, transient, brutal_kill, worker, [?MODULE]}, supervisor:start_child(ejabberd_listeners, ChildSpec). stop_listeners() -> Ports = ejabberd_config:get_local_option(listen), lists:foreach( fun({PortIpNetp, Module, _Opts}) -> delete_listener(PortIpNetp, Module) end, Ports). %% @spec (PortIP, Module) -> ok %% where %% PortIP = {Port, IPT | IPS} %% Port = integer() %% IPT = tuple() %% IPS = string() %% Module = atom() stop_listener(PortIP, _Module) -> supervisor:terminate_child(ejabberd_listeners, PortIP), supervisor:delete_child(ejabberd_listeners, PortIP). %% @spec (PortIP, Module, Opts) -> {ok, Pid} | {error, Error} %% where %% PortIP = {Port, IPT | IPS} %% Port = integer() %% IPT = tuple() %% IPS = string() %% IPV = inet | inet6 %% Module = atom() %% Opts = [IPV | {ip, IPT} | atom() | tuple()] %% @doc Add a listener and store in config if success add_listener(PortIP, Module, Opts) -> {Port, IPT, _, _, Proto, _} = parse_listener_portip(PortIP, Opts), PortIP1 = {Port, IPT, Proto}, case start_listener(PortIP1, Module, Opts) of {ok, _Pid} -> Ports = case ejabberd_config:get_local_option(listen) of undefined -> []; Ls -> Ls end, Ports1 = lists:keydelete(PortIP1, 1, Ports), Ports2 = [{PortIP1, Module, Opts} | Ports1], ejabberd_config:add_local_option(listen, Ports2), ok; {error, {already_started, _Pid}} -> {error, {already_started, PortIP}}; {error, Error} -> {error, Error} end. delete_listener(PortIP, Module) -> delete_listener(PortIP, Module, []). %% @spec (PortIP, Module, Opts) -> ok %% where %% PortIP = {Port, IPT | IPS} %% Port = integer() %% IPT = tuple() %% IPS = string() %% Module = atom() %% Opts = [term()] delete_listener(PortIP, Module, Opts) -> {Port, IPT, _, _, Proto, _} = parse_listener_portip(PortIP, Opts), PortIP1 = {Port, IPT, Proto}, Ports = case ejabberd_config:get_local_option(listen) of undefined -> []; Ls -> Ls end, Ports1 = lists:keydelete(PortIP1, 1, Ports), ejabberd_config:add_local_option(listen, Ports1), stop_listener(PortIP1, Module). is_frontend({frontend, _Module}) -> true; is_frontend(_) -> false. %% @doc(FrontMod) -> atom() %% where FrontMod = atom() | {frontend, atom()} strip_frontend({frontend, Module}) -> Module; strip_frontend(Module) when is_atom(Module) -> Module. %%% %%% Check options %%% check_listener_options(Opts) -> case includes_deprecated_ssl_option(Opts) of false -> ok; true -> Error = "There is a problem with your ejabberd configuration file: " "the option 'ssl' for listening sockets is no longer available." " To get SSL encryption use the option 'tls'.", throw({error, Error}) end, case certfile_readable(Opts) of true -> ok; {false, Path} -> ErrorText = "There is a problem in the configuration: " "the specified file is not readable: ", throw({error, ErrorText ++ Path}) end, ok. %% Parse the options of the socket, %% and return if the deprecated option 'ssl' is included %% @spec (Opts) -> true | false includes_deprecated_ssl_option(Opts) -> case lists:keysearch(ssl, 1, Opts) of {value, {ssl, _SSLOpts}} -> true; _ -> lists:member(ssl, Opts) end. %% @spec (Opts) -> true | {false, Path::string()} certfile_readable(Opts) -> case proplists:lookup(certfile, Opts) of none -> true; {certfile, Path} -> case ejabberd_config:is_file_readable(Path) of true -> true; false -> {false, Path} end end. get_proto(Opts) -> case proplists:get_value(proto, Opts) of undefined -> tcp; Proto -> normalize_proto(Proto) end. normalize_proto(tcp) -> tcp; normalize_proto(udp) -> udp; normalize_proto(UnknownProto) -> ?WARNING_MSG("There is a problem in the configuration: " "~p is an unknown IP protocol. Using tcp as fallback", [UnknownProto]), tcp. socket_error(Reason, PortIP, Module, SockOpts, Port, IPS) -> ReasonT = case Reason of eaddrnotavail -> "IP address not available: " ++ IPS; eaddrinuse -> "IP address and port number already used: " ++IPS++" "++integer_to_list(Port); _ -> format_error(Reason) end, ?ERROR_MSG("Failed to open socket:~n ~p~nReason: ~s", [{Port, Module, SockOpts}, ReasonT]), throw({Reason, PortIP}). format_error(Reason) -> case inet:format_error(Reason) of "unknown POSIX error" -> atom_to_list(Reason); ReasonStr -> ReasonStr end. ejabberd-2.1.11/src/mod_adhoc.erl0000664000000000000000000002103212240230175013424 0ustar %%%---------------------------------------------------------------------- %%% File : mod_adhoc.erl %%% Author : Magnus Henoch %%% Purpose : Handle incoming ad-doc requests (XEP-0050) %%% Created : 15 Nov 2005 by Magnus Henoch %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_adhoc). -author('henoch@dtek.chalmers.se'). -behaviour(gen_mod). -export([start/2, stop/1, process_local_iq/3, process_sm_iq/3, get_local_commands/5, get_local_identity/5, get_local_features/5, get_sm_commands/5, get_sm_identity/5, get_sm_features/5, ping_item/4, ping_command/4]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("adhoc.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS, ?MODULE, process_local_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS, ?MODULE, process_sm_iq, IQDisc), ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 99), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 99), ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_commands, 99), ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 99), ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 99), ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_commands, 99), ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, ping_item, 100), ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, ping_command, 100). stop(Host) -> ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, ping_command, 100), ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, ping_item, 100), ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_commands, 99), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 99), ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 99), ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_commands, 99), ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 99), ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 99), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS). %------------------------------------------------------------------------- get_local_commands(Acc, _From, #jid{server = Server, lserver = LServer} = _To, "", Lang) -> Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false), case Display of false -> Acc; _ -> Items = case Acc of {result, I} -> I; _ -> [] end, Nodes = [{xmlelement, "item", [{"jid", Server}, {"node", ?NS_COMMANDS}, {"name", translate:translate(Lang, "Commands")}], []}], {result, Items ++ Nodes} end; get_local_commands(_Acc, From, #jid{lserver = LServer} = To, ?NS_COMMANDS, Lang) -> ejabberd_hooks:run_fold(adhoc_local_items, LServer, {result, []}, [From, To, Lang]); get_local_commands(_Acc, _From, _To, "ping", _Lang) -> {result, []}; get_local_commands(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- get_sm_commands(Acc, _From, #jid{lserver = LServer} = To, "", Lang) -> Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false), case Display of false -> Acc; _ -> Items = case Acc of {result, I} -> I; _ -> [] end, Nodes = [{xmlelement, "item", [{"jid", jlib:jid_to_string(To)}, {"node", ?NS_COMMANDS}, {"name", translate:translate(Lang, "Commands")}], []}], {result, Items ++ Nodes} end; get_sm_commands(_Acc, From, #jid{lserver = LServer} = To, ?NS_COMMANDS, Lang) -> ejabberd_hooks:run_fold(adhoc_sm_items, LServer, {result, []}, [From, To, Lang]); get_sm_commands(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- %% On disco info request to the ad-hoc node, return automation/command-list. get_local_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) -> [{xmlelement, "identity", [{"category", "automation"}, {"type", "command-list"}, {"name", translate:translate(Lang, "Commands")}], []} | Acc]; get_local_identity(Acc, _From, _To, "ping", Lang) -> [{xmlelement, "identity", [{"category", "automation"}, {"type", "command-node"}, {"name", translate:translate(Lang, "Ping")}], []} | Acc]; get_local_identity(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- %% On disco info request to the ad-hoc node, return automation/command-list. get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) -> [{xmlelement, "identity", [{"category", "automation"}, {"type", "command-list"}, {"name", translate:translate(Lang, "Commands")}], []} | Acc]; get_sm_identity(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- get_local_features(Acc, _From, _To, "", _Lang) -> Feats = case Acc of {result, I} -> I; _ -> [] end, {result, Feats ++ [?NS_COMMANDS]}; get_local_features(_Acc, _From, _To, ?NS_COMMANDS, _Lang) -> %% override all lesser features... {result, []}; get_local_features(_Acc, _From, _To, "ping", _Lang) -> %% override all lesser features... {result, [?NS_COMMANDS]}; get_local_features(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- get_sm_features(Acc, _From, _To, "", _Lang) -> Feats = case Acc of {result, I} -> I; _ -> [] end, {result, Feats ++ [?NS_COMMANDS]}; get_sm_features(_Acc, _From, _To, ?NS_COMMANDS, _Lang) -> %% override all lesser features... {result, []}; get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. %------------------------------------------------------------------------- process_local_iq(From, To, IQ) -> process_adhoc_request(From, To, IQ, adhoc_local_commands). process_sm_iq(From, To, IQ) -> process_adhoc_request(From, To, IQ, adhoc_sm_commands). process_adhoc_request(From, To, #iq{sub_el = SubEl} = IQ, Hook) -> ?DEBUG("About to parse ~p...", [IQ]), case adhoc:parse_request(IQ) of {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]}; #adhoc_request{} = AdhocRequest -> Host = To#jid.lserver, case ejabberd_hooks:run_fold(Hook, Host, empty, [From, To, AdhocRequest]) of ignore -> ignore; empty -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]}; Command -> IQ#iq{type = result, sub_el = [Command]} end end. ping_item(Acc, _From, #jid{server = Server} = _To, Lang) -> Items = case Acc of {result, I} -> I; _ -> [] end, Nodes = [{xmlelement, "item", [{"jid", Server}, {"node", "ping"}, {"name", translate:translate(Lang, "Ping")}], []}], {result, Items ++ Nodes}. ping_command(_Acc, _From, _To, #adhoc_request{lang = Lang, node = "ping", sessionid = _Sessionid, action = Action} = Request) -> if Action == ""; Action == "execute" -> adhoc:produce_response( Request, #adhoc_response{status = completed, notes = [{"info", translate:translate( Lang, "Pong")}]}); true -> {error, ?ERR_BAD_REQUEST} end; ping_command(Acc, _From, _To, _Request) -> Acc. ejabberd-2.1.11/src/inetrc0000664000000000000000000000015712240230175012217 0ustar {lookup,["file","native"]}. {host,{127,0,0,1}, ["localhost","hostalias"]}. {file, resolv, "/etc/resolv.conf"}. ejabberd-2.1.11/src/ejabberd.init.template0000664000000000000000000000252112240230175015242 0ustar #! /bin/sh ### BEGIN INIT INFO # Provides: ejabberd # Required-Start: $remote_fs $network $named $time # Required-Stop: $remote_fs $network $named $time # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Starts ejabberd jabber server # Description: Starts ejabberd jabber server, an XMPP # compliant server written in Erlang. ### END INIT INFO # chkconfig: 2345 90 10 # description: ejabberd XMPP server set -o errexit DIR=@ctlscriptpath@ CTL="$DIR"/ejabberdctl USER=@installuser@ test -x "$CTL" || { echo "ERROR: ejabberd not found: $DIR" exit 1 } grep ^"$USER": /etc/passwd >/dev/null || { echo "ERROR: System user not found: $USER" exit 2 } export PATH="${PATH:+$PATH:}/usr/sbin:/sbin" case "$1" in start) test -x "$CTL" || exit 0 echo "Starting ejabberd..." su - $USER -c "$CTL start" su - $USER -c "$CTL started" echo "done." ;; stop) test -x "$CTL" || exit 0 echo "Stopping ejabberd..." su - $USER -c "$CTL stop" su - $USER -c "$CTL stopped" echo "done." ;; status) test -x "$CTL" || exit 0 echo "Getting ejabberd status..." su - $USER -c "$CTL status" ;; force-reload|restart) "$0" stop "$0" start ;; *) echo "Usage: $0 {start|stop|restart|force-reload|status}" exit 1 esac exit 0 ejabberd-2.1.11/src/randoms.erl0000664000000000000000000000320112240230175013150 0ustar %%%---------------------------------------------------------------------- %%% File : randoms.erl %%% Author : Alexey Shchepin %%% Purpose : Random generation number wrapper %%% Created : 13 Dec 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(randoms). -author('alexey@process-one.net'). -export([get_string/0]). -export([start/0, init/0]). start() -> register(random_generator, spawn(randoms, init, [])). init() -> {A1, A2, A3} = now(), random:seed(A1,A2,A3), loop(). loop() -> receive {From, get_random, N} -> From ! {random, random:uniform(N)}, loop(); _ -> loop() end. get_string() -> random_generator ! {self(), get_random, 65536*65536}, receive {random, R} -> integer_to_list(R) end. ejabberd-2.1.11/src/mod_muc/0000775000000000000000000000000012240452476012442 5ustar ejabberd-2.1.11/src/mod_muc/Makefile.win320000664000000000000000000000106012240230175015026 0ustar include ..\Makefile.inc EFLAGS = -I .. -pz .. OUTDIR = .. BEAMS = ..\mod_muc.beam ..\mod_muc_odbc.beam ..\mod_muc_log.beam ..\mod_muc_room.beam ALL : $(BEAMS) CLEAN : -@erase $(BEAMS) $(OUTDIR)\mod_muc.beam : mod_muc.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_muc.erl $(OUTDIR)\mod_muc_odbc.beam : mod_muc_odbc.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_muc_odbc.erl $(OUTDIR)\mod_muc_log.beam : mod_muc_log.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_muc_log.erl $(OUTDIR)\mod_muc_room.beam : mod_muc_room.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_muc_room.erl ejabberd-2.1.11/src/mod_muc/mod_muc_room.erl0000664000000000000000000041317512240230175015626 0ustar %%%---------------------------------------------------------------------- %%% File : mod_muc_room.erl %%% Author : Alexey Shchepin %%% Purpose : MUC room stuff %%% Created : 19 Mar 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_muc_room). -author('alexey@process-one.net'). -behaviour(gen_fsm). %% External exports -export([start_link/10, start_link/8, start/10, start/8, route/4]). %% gen_fsm callbacks -export([init/1, normal_state/2, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, code_change/4]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_muc_room.hrl"). -define(MAX_USERS_DEFAULT_LIST, [5, 10, 20, 30, 50, 100, 200, 500, 1000, 2000, 5000]). %-define(DBGFSM, true). -ifdef(DBGFSM). -define(FSMOPTS, [{debug, [trace]}]). -else. -define(FSMOPTS, []). -endif. %% Module start with or without supervisor: -ifdef(NO_TRANSIENT_SUPERVISORS). -define(SUPERVISOR_START, gen_fsm:start(?MODULE, [Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, Nick, DefRoomOpts, Mod], ?FSMOPTS)). -else. -define(SUPERVISOR_START, Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_muc_sup), supervisor:start_child( Supervisor, [Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, Nick, DefRoomOpts, Mod])). -endif. %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, Nick, DefRoomOpts, Mod) -> ?SUPERVISOR_START. start(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, Mod) -> Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_muc_sup), supervisor:start_child( Supervisor, [Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, Mod]). start_link(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, Nick, DefRoomOpts, Mod) -> gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, Nick, DefRoomOpts, Mod], ?FSMOPTS). start_link(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, Mod) -> gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, Mod], ?FSMOPTS). %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, StateName, StateData} | %% {ok, StateName, StateData, Timeout} | %% ignore | %% {stop, StopReason} %%---------------------------------------------------------------------- init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, _Nick, DefRoomOpts, Mod]) -> process_flag(trap_exit, true), Shaper = shaper:new(RoomShaper), State = set_affiliation(Creator, owner, #state{host = Host, server_host = ServerHost, mod = Mod, access = Access, room = Room, history = lqueue_new(HistorySize), jid = jlib:make_jid(Room, Host, ""), just_created = true, room_shaper = Shaper}), State1 = set_opts(DefRoomOpts, State), ?INFO_MSG("Created MUC room ~s@~s by ~s", [Room, Host, jlib:jid_to_string(Creator)]), add_to_log(room_existence, created, State1), add_to_log(room_existence, started, State1), {ok, normal_state, State1}; init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, Mod]) -> process_flag(trap_exit, true), Shaper = shaper:new(RoomShaper), State = set_opts(Opts, #state{host = Host, server_host = ServerHost, mod = Mod, access = Access, room = Room, history = lqueue_new(HistorySize), jid = jlib:make_jid(Room, Host, ""), room_shaper = Shaper}), add_to_log(room_existence, started, State), {ok, normal_state, State}. %%---------------------------------------------------------------------- %% Func: StateName/2 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- normal_state({route, From, "", {xmlelement, "message", Attrs, Els} = Packet}, StateData) -> Lang = xml:get_attr_s("xml:lang", Attrs), case is_user_online(From, StateData) orelse is_user_allowed_message_nonparticipant(From, StateData) of true -> case xml:get_attr_s("type", Attrs) of "groupchat" -> Activity = get_user_activity(From, StateData), Now = now_to_usec(now()), MinMessageInterval = trunc(gen_mod:get_module_opt( StateData#state.server_host, StateData#state.mod, min_message_interval, 0) * 1000000), Size = element_size(Packet), {MessageShaper, MessageShaperInterval} = shaper:update(Activity#activity.message_shaper, Size), if Activity#activity.message /= undefined -> ErrText = "Traffic rate limit is exceeded", Err = jlib:make_error_reply( Packet, ?ERRT_RESOURCE_CONSTRAINT(Lang, ErrText)), ejabberd_router:route( StateData#state.jid, From, Err), {next_state, normal_state, StateData}; Now >= Activity#activity.message_time + MinMessageInterval, MessageShaperInterval == 0 -> {RoomShaper, RoomShaperInterval} = shaper:update(StateData#state.room_shaper, Size), RoomQueueEmpty = queue:is_empty( StateData#state.room_queue), if RoomShaperInterval == 0, RoomQueueEmpty -> NewActivity = Activity#activity{ message_time = Now, message_shaper = MessageShaper}, StateData1 = store_user_activity( From, NewActivity, StateData), StateData2 = StateData1#state{ room_shaper = RoomShaper}, process_groupchat_message(From, Packet, StateData2); true -> StateData1 = if RoomQueueEmpty -> erlang:send_after( RoomShaperInterval, self(), process_room_queue), StateData#state{ room_shaper = RoomShaper}; true -> StateData end, NewActivity = Activity#activity{ message_time = Now, message_shaper = MessageShaper, message = Packet}, RoomQueue = queue:in( {message, From}, StateData#state.room_queue), StateData2 = store_user_activity( From, NewActivity, StateData1), StateData3 = StateData2#state{ room_queue = RoomQueue}, {next_state, normal_state, StateData3} end; true -> MessageInterval = (Activity#activity.message_time + MinMessageInterval - Now) div 1000, Interval = lists:max([MessageInterval, MessageShaperInterval]), erlang:send_after( Interval, self(), {process_user_message, From}), NewActivity = Activity#activity{ message = Packet, message_shaper = MessageShaper}, StateData1 = store_user_activity( From, NewActivity, StateData), {next_state, normal_state, StateData1} end; "error" -> case is_user_online(From, StateData) of true -> ErrorText = "This participant is kicked from the room because " "he sent an error message", NewState = expulse_participant(Packet, From, StateData, translate:translate(Lang, ErrorText)), {next_state, normal_state, NewState}; _ -> {next_state, normal_state, StateData} end; "chat" -> ErrText = "It is not allowed to send private messages to the conference", Err = jlib:make_error_reply( Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)), ejabberd_router:route( StateData#state.jid, From, Err), {next_state, normal_state, StateData}; Type when (Type == "") or (Type == "normal") -> IsInvitation = is_invitation(Els), IsVoiceRequest = is_voice_request(Els) and is_visitor(From, StateData), IsVoiceApprovement = is_voice_approvement(Els) and not is_visitor(From, StateData), if IsInvitation -> case catch check_invitation(From, Els, Lang, StateData) of {error, Error} -> Err = jlib:make_error_reply( Packet, Error), ejabberd_router:route( StateData#state.jid, From, Err), {next_state, normal_state, StateData}; IJID -> Config = StateData#state.config, case Config#config.members_only of true -> case get_affiliation(IJID, StateData) of none -> NSD = set_affiliation( IJID, member, StateData), case (NSD#state.config)#config.persistent of true -> (NSD#state.mod):store_room( NSD#state.server_host, NSD#state.host, NSD#state.room, make_opts(NSD)); _ -> ok end, {next_state, normal_state, NSD}; _ -> {next_state, normal_state, StateData} end; false -> {next_state, normal_state, StateData} end end; IsVoiceRequest -> NewStateData = case (StateData#state.config)#config.allow_voice_requests of true -> MinInterval = (StateData#state.config) #config.voice_request_min_interval, BareFrom = jlib:jid_remove_resource( jlib:jid_tolower(From)), NowPriority = -now_to_usec(now()), CleanPriority = NowPriority + MinInterval*1000000, Times = clean_treap( StateData#state.last_voice_request_time, CleanPriority), case treap:lookup(BareFrom, Times) of error -> Times1 = treap:insert( BareFrom, NowPriority, true, Times), NSD = StateData#state{ last_voice_request_time = Times1}, send_voice_request(From, NSD), NSD; {ok, _, _} -> ErrText = "Please, wait for " "a while before sending " "new voice request", Err = jlib:make_error_reply( Packet, ?ERRT_NOT_ACCEPTABLE( Lang, ErrText)), ejabberd_router:route( StateData#state.jid, From, Err), StateData#state{ last_voice_request_time = Times} end; false -> ErrText = "Voice requests are " "disabled in this conference", Err = jlib:make_error_reply( Packet, ?ERRT_FORBIDDEN( Lang, ErrText)), ejabberd_router:route( StateData#state.jid, From, Err), StateData end, {next_state, normal_state, NewStateData}; IsVoiceApprovement -> NewStateData = case is_moderator(From, StateData) of true -> case extract_jid_from_voice_approvement(Els) of error -> ErrText = "Failed to extract " "JID from your voice " "request approval", Err = jlib:make_error_reply( Packet, ?ERRT_BAD_REQUEST( Lang, ErrText)), ejabberd_router:route( StateData#state.jid, From, Err), StateData; {ok, TargetJid} -> case is_visitor( TargetJid, StateData) of true -> Reason = [], NSD = set_role( TargetJid, participant, StateData), catch send_new_presence( TargetJid, Reason, NSD), NSD; _ -> StateData end end; _ -> ErrText = "Only moderators can " "approve voice requests", Err = jlib:make_error_reply( Packet, ?ERRT_NOT_ALLOWED( Lang, ErrText)), ejabberd_router:route( StateData#state.jid, From, Err), StateData end, {next_state, normal_state, NewStateData}; true -> {next_state, normal_state, StateData} end; _ -> ErrText = "Improper message type", Err = jlib:make_error_reply( Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)), ejabberd_router:route( StateData#state.jid, From, Err), {next_state, normal_state, StateData} end; _ -> case xml:get_attr_s("type", Attrs) of "error" -> ok; _ -> handle_roommessage_from_nonparticipant(Packet, Lang, StateData, From) end, {next_state, normal_state, StateData} end; normal_state({route, From, "", {xmlelement, "iq", _Attrs, _Els} = Packet}, StateData) -> case jlib:iq_query_info(Packet) of #iq{type = Type, xmlns = XMLNS, lang = Lang, sub_el = SubEl} = IQ when (XMLNS == ?NS_MUC_ADMIN) or (XMLNS == ?NS_MUC_OWNER) or (XMLNS == ?NS_DISCO_INFO) or (XMLNS == ?NS_DISCO_ITEMS) or (XMLNS == ?NS_CAPTCHA) -> Res1 = case XMLNS of ?NS_MUC_ADMIN -> process_iq_admin(From, Type, Lang, SubEl, StateData); ?NS_MUC_OWNER -> process_iq_owner(From, Type, Lang, SubEl, StateData); ?NS_DISCO_INFO -> process_iq_disco_info(From, Type, Lang, StateData); ?NS_DISCO_ITEMS -> process_iq_disco_items(From, Type, Lang, StateData); ?NS_CAPTCHA -> process_iq_captcha(From, Type, Lang, SubEl, StateData) end, {IQRes, NewStateData} = case Res1 of {result, Res, SD} -> {IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], Res }]}, SD}; {error, Error} -> {IQ#iq{type = error, sub_el = [SubEl, Error]}, StateData} end, ejabberd_router:route(StateData#state.jid, From, jlib:iq_to_xml(IQRes)), case NewStateData of stop -> {stop, normal, StateData}; _ -> {next_state, normal_state, NewStateData} end; reply -> {next_state, normal_state, StateData}; _ -> Err = jlib:make_error_reply( Packet, ?ERR_FEATURE_NOT_IMPLEMENTED), ejabberd_router:route(StateData#state.jid, From, Err), {next_state, normal_state, StateData} end; normal_state({route, From, Nick, {xmlelement, "presence", _Attrs, _Els} = Packet}, StateData) -> Activity = get_user_activity(From, StateData), Now = now_to_usec(now()), MinPresenceInterval = trunc(gen_mod:get_module_opt( StateData#state.server_host, StateData#state.mod, min_presence_interval, 0) * 1000000), if (Now >= Activity#activity.presence_time + MinPresenceInterval) and (Activity#activity.presence == undefined) -> NewActivity = Activity#activity{presence_time = Now}, StateData1 = store_user_activity(From, NewActivity, StateData), process_presence(From, Nick, Packet, StateData1); true -> if Activity#activity.presence == undefined -> Interval = (Activity#activity.presence_time + MinPresenceInterval - Now) div 1000, erlang:send_after( Interval, self(), {process_user_presence, From}); true -> ok end, NewActivity = Activity#activity{presence = {Nick, Packet}}, StateData1 = store_user_activity(From, NewActivity, StateData), {next_state, normal_state, StateData1} end; normal_state({route, From, ToNick, {xmlelement, "message", Attrs, _} = Packet}, StateData) -> Type = xml:get_attr_s("type", Attrs), Lang = xml:get_attr_s("xml:lang", Attrs), case decide_fate_message(Type, Packet, From, StateData) of {expulse_sender, Reason} -> ?DEBUG(Reason, []), ErrorText = "This participant is kicked from the room because " "he sent an error message to another participant", NewState = expulse_participant(Packet, From, StateData, translate:translate(Lang, ErrorText)), {next_state, normal_state, NewState}; forget_message -> {next_state, normal_state, StateData}; continue_delivery -> case {(StateData#state.config)#config.allow_private_messages, is_user_online(From, StateData)} of {true, true} -> case Type of "groupchat" -> ErrText = "It is not allowed to send private " "messages of type \"groupchat\"", Err = jlib:make_error_reply( Packet, ?ERRT_BAD_REQUEST(Lang, ErrText)), ejabberd_router:route( jlib:jid_replace_resource( StateData#state.jid, ToNick), From, Err); _ -> case find_jids_by_nick(ToNick, StateData) of false -> ErrText = "Recipient is not in the conference room", Err = jlib:make_error_reply( Packet, ?ERRT_ITEM_NOT_FOUND(Lang, ErrText)), ejabberd_router:route( jlib:jid_replace_resource( StateData#state.jid, ToNick), From, Err); ToJIDs -> SrcIsVisitor = is_visitor(From, StateData), DstIsModerator = is_moderator(hd(ToJIDs), StateData), PmFromVisitors = (StateData#state.config)#config.allow_private_messages_from_visitors, if SrcIsVisitor == false; PmFromVisitors == anyone; (PmFromVisitors == moderators) and (DstIsModerator) -> {ok, #user{nick = FromNick}} = ?DICT:find(jlib:jid_tolower(From), StateData#state.users), FromNickJID = jlib:jid_replace_resource(StateData#state.jid, FromNick), [ejabberd_router:route(FromNickJID, ToJID, Packet) || ToJID <- ToJIDs]; true -> ErrText = "It is not allowed to send private messages", Err = jlib:make_error_reply( Packet, ?ERRT_FORBIDDEN(Lang, ErrText)), ejabberd_router:route( jlib:jid_replace_resource( StateData#state.jid, ToNick), From, Err) end end end; {true, false} -> ErrText = "Only occupants are allowed to send messages to the conference", Err = jlib:make_error_reply( Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)), ejabberd_router:route( jlib:jid_replace_resource( StateData#state.jid, ToNick), From, Err); {false, _} -> ErrText = "It is not allowed to send private messages", Err = jlib:make_error_reply( Packet, ?ERRT_FORBIDDEN(Lang, ErrText)), ejabberd_router:route( jlib:jid_replace_resource( StateData#state.jid, ToNick), From, Err) end, {next_state, normal_state, StateData} end; normal_state({route, From, ToNick, {xmlelement, "iq", Attrs, _Els} = Packet}, StateData) -> Lang = xml:get_attr_s("xml:lang", Attrs), StanzaId = xml:get_attr_s("id", Attrs), case {(StateData#state.config)#config.allow_query_users, is_user_online_iq(StanzaId, From, StateData)} of {true, {true, NewId, FromFull}} -> case find_jid_by_nick(ToNick, StateData) of false -> case jlib:iq_query_info(Packet) of reply -> ok; _ -> ErrText = "Recipient is not in the conference room", Err = jlib:make_error_reply( Packet, ?ERRT_ITEM_NOT_FOUND(Lang, ErrText)), ejabberd_router:route( jlib:jid_replace_resource( StateData#state.jid, ToNick), From, Err) end; ToJID -> {ok, #user{nick = FromNick}} = ?DICT:find(jlib:jid_tolower(FromFull), StateData#state.users), {ToJID2, Packet2} = handle_iq_vcard(FromFull, ToJID, StanzaId, NewId,Packet), ejabberd_router:route( jlib:jid_replace_resource(StateData#state.jid, FromNick), ToJID2, Packet2) end; {_, {false, _, _}} -> case jlib:iq_query_info(Packet) of reply -> ok; _ -> ErrText = "Only occupants are allowed to send queries to the conference", Err = jlib:make_error_reply( Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)), ejabberd_router:route( jlib:jid_replace_resource(StateData#state.jid, ToNick), From, Err) end; _ -> case jlib:iq_query_info(Packet) of reply -> ok; _ -> ErrText = "Queries to the conference members are not allowed in this room", Err = jlib:make_error_reply( Packet, ?ERRT_NOT_ALLOWED(Lang, ErrText)), ejabberd_router:route( jlib:jid_replace_resource(StateData#state.jid, ToNick), From, Err) end end, {next_state, normal_state, StateData}; normal_state(_Event, StateData) -> {next_state, normal_state, StateData}. %%---------------------------------------------------------------------- %% Func: handle_event/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_event({service_message, Msg}, _StateName, StateData) -> MessagePkt = {xmlelement, "message", [{"type", "groupchat"}], [{xmlelement, "body", [], [{xmlcdata, Msg}]}]}, lists:foreach( fun({_LJID, Info}) -> ejabberd_router:route( StateData#state.jid, Info#user.jid, MessagePkt) end, ?DICT:to_list(StateData#state.users)), NSD = add_message_to_history("", StateData#state.jid, MessagePkt, StateData), {next_state, normal_state, NSD}; handle_event({destroy, Reason}, _StateName, StateData) -> {result, [], stop} = destroy_room( {xmlelement, "destroy", [{"xmlns", ?NS_MUC_OWNER}], case Reason of none -> []; _Else -> [{xmlelement, "reason", [], [{xmlcdata, Reason}]}] end}, StateData), ?INFO_MSG("Destroyed MUC room ~s with reason: ~p", [jlib:jid_to_string(StateData#state.jid), Reason]), add_to_log(room_existence, destroyed, StateData), {stop, shutdown, StateData}; handle_event(destroy, StateName, StateData) -> ?INFO_MSG("Destroyed MUC room ~s", [jlib:jid_to_string(StateData#state.jid)]), handle_event({destroy, none}, StateName, StateData); handle_event({set_affiliations, Affiliations}, StateName, StateData) -> {next_state, StateName, StateData#state{affiliations = Affiliations}}; handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- handle_sync_event({get_disco_item, JID, Lang}, _From, StateName, StateData) -> Reply = get_roomdesc_reply(JID, StateData, get_roomdesc_tail(StateData, Lang)), {reply, Reply, StateName, StateData}; handle_sync_event(get_config, _From, StateName, StateData) -> {reply, {ok, StateData#state.config}, StateName, StateData}; handle_sync_event(get_state, _From, StateName, StateData) -> {reply, {ok, StateData}, StateName, StateData}; handle_sync_event({change_config, Config}, _From, StateName, StateData) -> {result, [], NSD} = change_config(Config, StateData), {reply, {ok, NSD#state.config}, StateName, NSD}; handle_sync_event({change_state, NewStateData}, _From, StateName, _StateData) -> {reply, {ok, NewStateData}, StateName, NewStateData}; handle_sync_event(_Event, _From, StateName, StateData) -> Reply = ok, {reply, Reply, StateName, StateData}. code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_info/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_info({process_user_presence, From}, normal_state = _StateName, StateData) -> RoomQueueEmpty = queue:is_empty(StateData#state.room_queue), RoomQueue = queue:in({presence, From}, StateData#state.room_queue), StateData1 = StateData#state{room_queue = RoomQueue}, if RoomQueueEmpty -> StateData2 = prepare_room_queue(StateData1), {next_state, normal_state, StateData2}; true -> {next_state, normal_state, StateData1} end; handle_info({process_user_message, From}, normal_state = _StateName, StateData) -> RoomQueueEmpty = queue:is_empty(StateData#state.room_queue), RoomQueue = queue:in({message, From}, StateData#state.room_queue), StateData1 = StateData#state{room_queue = RoomQueue}, if RoomQueueEmpty -> StateData2 = prepare_room_queue(StateData1), {next_state, normal_state, StateData2}; true -> {next_state, normal_state, StateData1} end; handle_info(process_room_queue, normal_state = StateName, StateData) -> case queue:out(StateData#state.room_queue) of {{value, {message, From}}, RoomQueue} -> Activity = get_user_activity(From, StateData), Packet = Activity#activity.message, NewActivity = Activity#activity{message = undefined}, StateData1 = store_user_activity( From, NewActivity, StateData), StateData2 = StateData1#state{ room_queue = RoomQueue}, StateData3 = prepare_room_queue(StateData2), process_groupchat_message(From, Packet, StateData3); {{value, {presence, From}}, RoomQueue} -> Activity = get_user_activity(From, StateData), {Nick, Packet} = Activity#activity.presence, NewActivity = Activity#activity{presence = undefined}, StateData1 = store_user_activity( From, NewActivity, StateData), StateData2 = StateData1#state{ room_queue = RoomQueue}, StateData3 = prepare_room_queue(StateData2), process_presence(From, Nick, Packet, StateData3); {empty, _} -> {next_state, StateName, StateData} end; handle_info({captcha_succeed, From}, normal_state, StateData) -> NewState = case ?DICT:find(From, StateData#state.robots) of {ok, {Nick, Packet}} -> Robots = ?DICT:store(From, passed, StateData#state.robots), add_new_user(From, Nick, Packet, StateData#state{robots=Robots}); _ -> StateData end, {next_state, normal_state, NewState}; handle_info({captcha_failed, From}, normal_state, StateData) -> NewState = case ?DICT:find(From, StateData#state.robots) of {ok, {Nick, Packet}} -> Robots = ?DICT:erase(From, StateData#state.robots), Err = jlib:make_error_reply( Packet, ?ERR_NOT_AUTHORIZED), ejabberd_router:route( % TODO: s/Nick/""/ jlib:jid_replace_resource( StateData#state.jid, Nick), From, Err), StateData#state{robots=Robots}; _ -> StateData end, {next_state, normal_state, NewState}; handle_info(_Info, StateName, StateData) -> {next_state, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: terminate/3 %% Purpose: Shutdown the fsm %% Returns: any %%---------------------------------------------------------------------- terminate(Reason, _StateName, StateData) -> ?INFO_MSG("Stopping MUC room ~s@~s", [StateData#state.room, StateData#state.host]), ReasonT = case Reason of shutdown -> "You are being removed from the room because" " of a system shutdown"; _ -> "Room terminates" end, ItemAttrs = [{"affiliation", "none"}, {"role", "none"}], ReasonEl = {xmlelement, "reason", [], [{xmlcdata, ReasonT}]}, Packet = {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", ItemAttrs, [ReasonEl]}, {xmlelement, "status", [{"code", "332"}], []} ]}]}, ?DICT:fold( fun(LJID, Info, _) -> Nick = Info#user.nick, case Reason of shutdown -> ejabberd_router:route( jlib:jid_replace_resource(StateData#state.jid, Nick), Info#user.jid, Packet); _ -> ok end, tab_remove_online_user(LJID, StateData) end, [], StateData#state.users), add_to_log(room_existence, stopped, StateData), (StateData#state.mod):room_destroyed( StateData#state.host, StateData#state.room, self(), StateData#state.server_host), ok. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- route(Pid, From, ToNick, Packet) -> gen_fsm:send_event(Pid, {route, From, ToNick, Packet}). process_groupchat_message(From, {xmlelement, "message", Attrs, _Els} = Packet, StateData) -> Lang = xml:get_attr_s("xml:lang", Attrs), case is_user_online(From, StateData) orelse is_user_allowed_message_nonparticipant(From, StateData) of true -> {FromNick, Role} = get_participant_data(From, StateData), if (Role == moderator) or (Role == participant) or ((StateData#state.config)#config.moderated == false) -> {NewStateData1, IsAllowed} = case check_subject(Packet) of false -> {StateData, true}; Subject -> case can_change_subject(Role, StateData) of true -> NSD = StateData#state{ subject = Subject, subject_author = FromNick}, case (NSD#state.config)#config.persistent of true -> (NSD#state.mod):store_room( NSD#state.server_host, NSD#state.host, NSD#state.room, make_opts(NSD)); _ -> ok end, {NSD, true}; _ -> {StateData, false} end end, case IsAllowed of true -> lists:foreach( fun({_LJID, Info}) -> ejabberd_router:route( jlib:jid_replace_resource( StateData#state.jid, FromNick), Info#user.jid, Packet) end, ?DICT:to_list(StateData#state.users)), NewStateData2 = add_message_to_history(FromNick, From, Packet, NewStateData1), {next_state, normal_state, NewStateData2}; _ -> Err = case (StateData#state.config)#config.allow_change_subj of true -> ?ERRT_FORBIDDEN( Lang, "Only moderators and participants " "are allowed to change the subject in this room"); _ -> ?ERRT_FORBIDDEN( Lang, "Only moderators " "are allowed to change the subject in this room") end, ejabberd_router:route( StateData#state.jid, From, jlib:make_error_reply(Packet, Err)), {next_state, normal_state, StateData} end; true -> ErrText = "Visitors are not allowed to send messages to all occupants", Err = jlib:make_error_reply( Packet, ?ERRT_FORBIDDEN(Lang, ErrText)), ejabberd_router:route( StateData#state.jid, From, Err), {next_state, normal_state, StateData} end; false -> ErrText = "Only occupants are allowed to send messages to the conference", Err = jlib:make_error_reply( Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)), ejabberd_router:route(StateData#state.jid, From, Err), {next_state, normal_state, StateData} end. %% @doc Check if this non participant can send message to room. %% %% XEP-0045 v1.23: %% 7.9 Sending a Message to All Occupants %% an implementation MAY allow users with certain privileges %% (e.g., a room owner, room admin, or service-level admin) %% to send messages to the room even if those users are not occupants. is_user_allowed_message_nonparticipant(JID, StateData) -> case get_service_affiliation(JID, StateData) of owner -> true; _ -> false end. %% @doc Get information of this participant, or default values. %% If the JID is not a participant, return values for a service message. get_participant_data(From, StateData) -> case ?DICT:find(jlib:jid_tolower(From), StateData#state.users) of {ok, #user{nick = FromNick, role = Role}} -> {FromNick, Role}; error -> {"", moderator} end. process_presence(From, Nick, {xmlelement, "presence", Attrs, _Els} = Packet, StateData) -> Type = xml:get_attr_s("type", Attrs), Lang = xml:get_attr_s("xml:lang", Attrs), StateData1 = case Type of "unavailable" -> case is_user_online(From, StateData) of true -> NewPacket = case {(StateData#state.config)#config.allow_visitor_status, is_visitor(From, StateData)} of {false, true} -> strip_status(Packet); _ -> Packet end, NewState = add_user_presence_un(From, NewPacket, StateData), case ?DICT:find(Nick, StateData#state.nicks) of {ok, [_, _ | _]} -> ok; _ -> send_new_presence(From, NewState) end, Reason = case xml:get_subtag(NewPacket, "status") of false -> ""; Status_el -> xml:get_tag_cdata(Status_el) end, remove_online_user(From, NewState, Reason); _ -> StateData end; "error" -> case is_user_online(From, StateData) of true -> ErrorText = "This participant is kicked from the room because " "he sent an error presence", expulse_participant(Packet, From, StateData, translate:translate(Lang, ErrorText)); _ -> StateData end; "" -> case is_user_online(From, StateData) of true -> case is_nick_change(From, Nick, StateData) of true -> case {nick_collision(From, Nick, StateData), (StateData#state.mod):can_use_nick( StateData#state.server_host, StateData#state.host, From, Nick), {(StateData#state.config)#config.allow_visitor_nickchange, is_visitor(From, StateData)}} of {_, _, {false, true}} -> ErrText = "Visitors are not allowed to change their nicknames in this room", Err = jlib:make_error_reply( Packet, ?ERRT_NOT_ALLOWED(Lang, ErrText)), ejabberd_router:route( % TODO: s/Nick/""/ jlib:jid_replace_resource( StateData#state.jid, Nick), From, Err), StateData; {true, _, _} -> Lang = xml:get_attr_s("xml:lang", Attrs), ErrText = "That nickname is already in use by another occupant", Err = jlib:make_error_reply( Packet, ?ERRT_CONFLICT(Lang, ErrText)), ejabberd_router:route( jlib:jid_replace_resource( StateData#state.jid, Nick), % TODO: s/Nick/""/ From, Err), StateData; {_, false, _} -> ErrText = "That nickname is registered by another person", Err = jlib:make_error_reply( Packet, ?ERRT_CONFLICT(Lang, ErrText)), ejabberd_router:route( % TODO: s/Nick/""/ jlib:jid_replace_resource( StateData#state.jid, Nick), From, Err), StateData; _ -> change_nick(From, Nick, StateData) end; _NotNickChange -> Stanza = case {(StateData#state.config)#config.allow_visitor_status, is_visitor(From, StateData)} of {false, true} -> strip_status(Packet); _Allowed -> Packet end, NewState = add_user_presence(From, Stanza, StateData), send_new_presence(From, NewState), NewState end; _ -> add_new_user(From, Nick, Packet, StateData) end; _ -> StateData end, case (not (StateData1#state.config)#config.persistent) andalso (?DICT:to_list(StateData1#state.users) == []) of true -> ?INFO_MSG("Destroyed MUC room ~s because it's temporary and empty", [jlib:jid_to_string(StateData#state.jid)]), add_to_log(room_existence, destroyed, StateData), {stop, normal, StateData1}; _ -> {next_state, normal_state, StateData1} end. is_user_online(JID, StateData) -> LJID = jlib:jid_tolower(JID), ?DICT:is_key(LJID, StateData#state.users). %% Check if the user is occupant of the room, or at least is an admin or owner. is_occupant_or_admin(JID, StateData) -> FAffiliation = get_affiliation(JID, StateData), FRole = get_role(JID, StateData), case (FRole /= none) orelse (FAffiliation == admin) orelse (FAffiliation == owner) of true -> true; _ -> false end. %%% %%% Handle IQ queries of vCard %%% is_user_online_iq(StanzaId, JID, StateData) when JID#jid.lresource /= "" -> {is_user_online(JID, StateData), StanzaId, JID}; is_user_online_iq(StanzaId, JID, StateData) when JID#jid.lresource == "" -> try stanzaid_unpack(StanzaId) of {OriginalId, Resource} -> JIDWithResource = jlib:jid_replace_resource(JID, Resource), {is_user_online(JIDWithResource, StateData), OriginalId, JIDWithResource} catch _:_ -> {is_user_online(JID, StateData), StanzaId, JID} end. handle_iq_vcard(FromFull, ToJID, StanzaId, NewId, Packet) -> ToBareJID = jlib:jid_remove_resource(ToJID), IQ = jlib:iq_query_info(Packet), handle_iq_vcard2(FromFull, ToJID, ToBareJID, StanzaId, NewId, IQ, Packet). handle_iq_vcard2(_FromFull, ToJID, ToBareJID, StanzaId, _NewId, #iq{type = get, xmlns = ?NS_VCARD}, Packet) when ToBareJID /= ToJID -> {ToBareJID, change_stanzaid(StanzaId, ToJID, Packet)}; handle_iq_vcard2(_FromFull, ToJID, _ToBareJID, _StanzaId, NewId, _IQ, Packet) -> {ToJID, change_stanzaid(NewId, Packet)}. stanzaid_pack(OriginalId, Resource) -> "berd"++base64:encode_to_string("ejab\0" ++ OriginalId ++ "\0" ++ Resource). stanzaid_unpack("berd"++StanzaIdBase64) -> StanzaId = base64:decode_to_string(StanzaIdBase64), ["ejab", OriginalId, Resource] = string:tokens(StanzaId, "\0"), {OriginalId, Resource}. change_stanzaid(NewId, Packet) -> {xmlelement, Name, Attrs, Els} = jlib:remove_attr("id", Packet), {xmlelement, Name, [{"id", NewId} | Attrs], Els}. change_stanzaid(PreviousId, ToJID, Packet) -> NewId = stanzaid_pack(PreviousId, ToJID#jid.lresource), change_stanzaid(NewId, Packet). %%% %%% role_to_list(Role) -> case Role of moderator -> "moderator"; participant -> "participant"; visitor -> "visitor"; none -> "none" end. affiliation_to_list(Affiliation) -> case Affiliation of owner -> "owner"; admin -> "admin"; member -> "member"; outcast -> "outcast"; none -> "none" end. list_to_role(Role) -> case Role of "moderator" -> moderator; "participant" -> participant; "visitor" -> visitor; "none" -> none end. list_to_affiliation(Affiliation) -> case Affiliation of "owner" -> owner; "admin" -> admin; "member" -> member; "outcast" -> outcast; "none" -> none end. %% Decide the fate of the message and its sender %% Returns: continue_delivery | forget_message | {expulse_sender, Reason} decide_fate_message("error", Packet, From, StateData) -> %% Make a preliminary decision PD = case check_error_kick(Packet) of %% If this is an error stanza and its condition matches a criteria true -> Reason = io_lib:format("This participant is considered a ghost and is expulsed: ~s", [jlib:jid_to_string(From)]), {expulse_sender, Reason}; false -> continue_delivery end, case PD of {expulse_sender, R} -> case is_user_online(From, StateData) of true -> {expulse_sender, R}; false -> forget_message end; Other -> Other end; decide_fate_message(_, _, _, _) -> continue_delivery. %% Check if the elements of this error stanza indicate %% that the sender is a dead participant. %% If so, return true to kick the participant. check_error_kick(Packet) -> case get_error_condition(Packet) of "gone" -> true; "internal-server-error" -> true; "item-not-found" -> true; "jid-malformed" -> true; "recipient-unavailable" -> true; "redirect" -> true; "remote-server-not-found" -> true; "remote-server-timeout" -> true; "service-unavailable" -> true; _ -> false end. get_error_condition(Packet) -> case catch get_error_condition2(Packet) of {condition, ErrorCondition} -> ErrorCondition; {'EXIT', _} -> "badformed error stanza" end. get_error_condition2(Packet) -> {xmlelement, _, _, EEls} = xml:get_subtag(Packet, "error"), [Condition] = [Name || {xmlelement, Name, [{"xmlns", ?NS_STANZAS}], []} <- EEls], {condition, Condition}. expulse_participant(Packet, From, StateData, Reason1) -> ErrorCondition = get_error_condition(Packet), Reason2 = io_lib:format(Reason1 ++ ": " ++ "~s", [ErrorCondition]), NewState = add_user_presence_un( From, {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "status", [], [{xmlcdata, Reason2}] }]}, StateData), send_new_presence(From, NewState), remove_online_user(From, NewState). set_affiliation(JID, Affiliation, StateData) -> set_affiliation(JID, Affiliation, StateData, ""). set_affiliation(JID, Affiliation, StateData, Reason) -> LJID = jlib:jid_remove_resource(jlib:jid_tolower(JID)), Affiliations = case Affiliation of none -> ?DICT:erase(LJID, StateData#state.affiliations); _ -> ?DICT:store(LJID, {Affiliation, Reason}, StateData#state.affiliations) end, StateData#state{affiliations = Affiliations}. get_affiliation(JID, StateData) -> {_AccessRoute, _AccessCreate, AccessAdmin, _AccessPersistent} = StateData#state.access, Res = case acl:match_rule(StateData#state.server_host, AccessAdmin, JID) of allow -> owner; _ -> LJID = jlib:jid_tolower(JID), case ?DICT:find(LJID, StateData#state.affiliations) of {ok, Affiliation} -> Affiliation; _ -> LJID1 = jlib:jid_remove_resource(LJID), case ?DICT:find(LJID1, StateData#state.affiliations) of {ok, Affiliation} -> Affiliation; _ -> LJID2 = setelement(1, LJID, ""), case ?DICT:find(LJID2, StateData#state.affiliations) of {ok, Affiliation} -> Affiliation; _ -> LJID3 = jlib:jid_remove_resource(LJID2), case ?DICT:find(LJID3, StateData#state.affiliations) of {ok, Affiliation} -> Affiliation; _ -> none end end end end end, case Res of {A, _Reason} -> A; _ -> Res end. get_service_affiliation(JID, StateData) -> {_AccessRoute, _AccessCreate, AccessAdmin, _AccessPersistent} = StateData#state.access, case acl:match_rule(StateData#state.server_host, AccessAdmin, JID) of allow -> owner; _ -> none end. set_role(JID, Role, StateData) -> LJID = jlib:jid_tolower(JID), LJIDs = case LJID of {U, S, ""} -> ?DICT:fold( fun(J, _, Js) -> case J of {U, S, _} -> [J | Js]; _ -> Js end end, [], StateData#state.users); _ -> case ?DICT:is_key(LJID, StateData#state.users) of true -> [LJID]; _ -> [] end end, {Users, Nicks} = case Role of none -> lists:foldl(fun(J, {Us, Ns}) -> NewNs = case ?DICT:find(J, Us) of {ok, #user{nick = Nick}} -> ?DICT:erase(Nick, Ns); _ -> Ns end, {?DICT:erase(J, Us), NewNs} end, {StateData#state.users, StateData#state.nicks}, LJIDs); _ -> {lists:foldl(fun(J, Us) -> {ok, User} = ?DICT:find(J, Us), ?DICT:store(J, User#user{role = Role}, Us) end, StateData#state.users, LJIDs), StateData#state.nicks} end, StateData#state{users = Users, nicks = Nicks}. get_role(JID, StateData) -> LJID = jlib:jid_tolower(JID), case ?DICT:find(LJID, StateData#state.users) of {ok, #user{role = Role}} -> Role; _ -> none end. get_default_role(Affiliation, StateData) -> case Affiliation of owner -> moderator; admin -> moderator; member -> participant; outcast -> none; none -> case (StateData#state.config)#config.members_only of true -> none; _ -> case (StateData#state.config)#config.members_by_default of true -> participant; _ -> visitor end end end. is_visitor(Jid, StateData) -> get_role(Jid, StateData) =:= visitor. is_moderator(Jid, StateData) -> get_role(Jid, StateData) =:= moderator. get_max_users(StateData) -> MaxUsers = (StateData#state.config)#config.max_users, ServiceMaxUsers = get_service_max_users(StateData), if MaxUsers =< ServiceMaxUsers -> MaxUsers; true -> ServiceMaxUsers end. get_service_max_users(StateData) -> gen_mod:get_module_opt(StateData#state.server_host, StateData#state.mod, max_users, ?MAX_USERS_DEFAULT). get_max_users_admin_threshold(StateData) -> gen_mod:get_module_opt(StateData#state.server_host, StateData#state.mod, max_users_admin_threshold, 5). get_user_activity(JID, StateData) -> case treap:lookup(jlib:jid_tolower(JID), StateData#state.activity) of {ok, _P, A} -> A; error -> MessageShaper = shaper:new(gen_mod:get_module_opt( StateData#state.server_host, StateData#state.mod, user_message_shaper, none)), PresenceShaper = shaper:new(gen_mod:get_module_opt( StateData#state.server_host, StateData#state.mod, user_presence_shaper, none)), #activity{message_shaper = MessageShaper, presence_shaper = PresenceShaper} end. store_user_activity(JID, UserActivity, StateData) -> MinMessageInterval = gen_mod:get_module_opt( StateData#state.server_host, StateData#state.mod, min_message_interval, 0), MinPresenceInterval = gen_mod:get_module_opt( StateData#state.server_host, StateData#state.mod, min_presence_interval, 0), Key = jlib:jid_tolower(JID), Now = now_to_usec(now()), Activity1 = clean_treap(StateData#state.activity, {1, -Now}), Activity = case treap:lookup(Key, Activity1) of {ok, _P, _A} -> treap:delete(Key, Activity1); error -> Activity1 end, StateData1 = case (MinMessageInterval == 0) andalso (MinPresenceInterval == 0) andalso (UserActivity#activity.message_shaper == none) andalso (UserActivity#activity.presence_shaper == none) andalso (UserActivity#activity.message == undefined) andalso (UserActivity#activity.presence == undefined) of true -> StateData#state{activity = Activity}; false -> case (UserActivity#activity.message == undefined) andalso (UserActivity#activity.presence == undefined) of true -> {_, MessageShaperInterval} = shaper:update(UserActivity#activity.message_shaper, 100000), {_, PresenceShaperInterval} = shaper:update(UserActivity#activity.presence_shaper, 100000), Delay = lists:max([MessageShaperInterval, PresenceShaperInterval, MinMessageInterval * 1000, MinPresenceInterval * 1000]) * 1000, Priority = {1, -(Now + Delay)}, StateData#state{ activity = treap:insert( Key, Priority, UserActivity, Activity)}; false -> Priority = {0, 0}, StateData#state{ activity = treap:insert( Key, Priority, UserActivity, Activity)} end end, StateData1. clean_treap(Treap, CleanPriority) -> case treap:is_empty(Treap) of true -> Treap; false -> {_Key, Priority, _Value} = treap:get_root(Treap), if Priority > CleanPriority -> clean_treap(treap:delete_root(Treap), CleanPriority); true -> Treap end end. prepare_room_queue(StateData) -> case queue:out(StateData#state.room_queue) of {{value, {message, From}}, _RoomQueue} -> Activity = get_user_activity(From, StateData), Packet = Activity#activity.message, Size = element_size(Packet), {RoomShaper, RoomShaperInterval} = shaper:update(StateData#state.room_shaper, Size), erlang:send_after( RoomShaperInterval, self(), process_room_queue), StateData#state{ room_shaper = RoomShaper}; {{value, {presence, From}}, _RoomQueue} -> Activity = get_user_activity(From, StateData), {_Nick, Packet} = Activity#activity.presence, Size = element_size(Packet), {RoomShaper, RoomShaperInterval} = shaper:update(StateData#state.room_shaper, Size), erlang:send_after( RoomShaperInterval, self(), process_room_queue), StateData#state{ room_shaper = RoomShaper}; {empty, _} -> StateData end. add_online_user(JID, Nick, Role, StateData) -> LJID = jlib:jid_tolower(JID), Users = ?DICT:store(LJID, #user{jid = JID, nick = Nick, role = Role}, StateData#state.users), add_to_log(join, Nick, StateData), Nicks = ?DICT:update(Nick, fun(Entry) -> case lists:member(LJID, Entry) of true -> Entry; false -> [LJID|Entry] end end, [LJID], StateData#state.nicks), tab_add_online_user(JID, StateData), StateData#state{users = Users, nicks = Nicks}. remove_online_user(JID, StateData) -> remove_online_user(JID, StateData, ""). remove_online_user(JID, StateData, Reason) -> LJID = jlib:jid_tolower(JID), {ok, #user{nick = Nick}} = ?DICT:find(LJID, StateData#state.users), add_to_log(leave, {Nick, Reason}, StateData), tab_remove_online_user(JID, StateData), Users = ?DICT:erase(LJID, StateData#state.users), Nicks = case ?DICT:find(Nick, StateData#state.nicks) of {ok, [LJID]} -> ?DICT:erase(Nick, StateData#state.nicks); {ok, U} -> ?DICT:store(Nick, U -- [LJID], StateData#state.nicks); error -> StateData#state.nicks end, StateData#state{users = Users, nicks = Nicks}. filter_presence({xmlelement, "presence", Attrs, Els}) -> FEls = lists:filter( fun(El) -> case El of {xmlcdata, _} -> false; {xmlelement, _Name1, Attrs1, _Els1} -> XMLNS = xml:get_attr_s("xmlns", Attrs1), case XMLNS of ?NS_MUC ++ _ -> false; _ -> true end end end, Els), {xmlelement, "presence", Attrs, FEls}. strip_status({xmlelement, "presence", Attrs, Els}) -> FEls = lists:filter( fun({xmlelement, "status", _Attrs1, _Els1}) -> false; (_) -> true end, Els), {xmlelement, "presence", Attrs, FEls}. add_user_presence(JID, Presence, StateData) -> LJID = jlib:jid_tolower(JID), FPresence = filter_presence(Presence), Users = ?DICT:update( LJID, fun(#user{} = User) -> User#user{last_presence = FPresence} end, StateData#state.users), StateData#state{users = Users}. add_user_presence_un(JID, Presence, StateData) -> LJID = jlib:jid_tolower(JID), FPresence = filter_presence(Presence), Users = ?DICT:update( LJID, fun(#user{} = User) -> User#user{last_presence = FPresence, role = none} end, StateData#state.users), StateData#state{users = Users}. %% Find and return a list of the full JIDs of the users of Nick. %% Return jid record. find_jids_by_nick(Nick, StateData) -> case ?DICT:find(Nick, StateData#state.nicks) of {ok, [User]} -> [jlib:make_jid(User)]; {ok, Users} -> [jlib:make_jid(LJID) || LJID <- Users]; error -> false end. %% Find and return the full JID of the user of Nick with %% highest-priority presence. Return jid record. find_jid_by_nick(Nick, StateData) -> case ?DICT:find(Nick, StateData#state.nicks) of {ok, [User]} -> jlib:make_jid(User); {ok, [FirstUser|Users]} -> #user{last_presence = FirstPresence} = ?DICT:fetch(FirstUser, StateData#state.users), {LJID, _} = lists:foldl(fun(Compare, {HighestUser, HighestPresence}) -> #user{last_presence = P1} = ?DICT:fetch(Compare, StateData#state.users), case higher_presence(P1, HighestPresence) of true -> {Compare, P1}; false -> {HighestUser, HighestPresence} end end, {FirstUser, FirstPresence}, Users), jlib:make_jid(LJID); error -> false end. higher_presence(Pres1, Pres2) -> Pri1 = get_priority_from_presence(Pres1), Pri2 = get_priority_from_presence(Pres2), Pri1 > Pri2. get_priority_from_presence(PresencePacket) -> case xml:get_subtag(PresencePacket, "priority") of false -> 0; SubEl -> case catch list_to_integer(xml:get_tag_cdata(SubEl)) of P when is_integer(P) -> P; _ -> 0 end end. find_nick_by_jid(Jid, StateData) -> [{_, #user{nick = Nick}}] = lists:filter( fun({_, #user{jid = FJid}}) -> FJid == Jid end, ?DICT:to_list(StateData#state.users)), Nick. is_nick_change(JID, Nick, StateData) -> LJID = jlib:jid_tolower(JID), case Nick of "" -> false; _ -> {ok, #user{nick = OldNick}} = ?DICT:find(LJID, StateData#state.users), Nick /= OldNick end. nick_collision(User, Nick, StateData) -> UserOfNick = find_jid_by_nick(Nick, StateData), %% if nick is not used, or is used by another resource of the same %% user, it's ok. UserOfNick /= false andalso jlib:jid_remove_resource(jlib:jid_tolower(UserOfNick)) /= jlib:jid_remove_resource(jlib:jid_tolower(User)). add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) -> Lang = xml:get_attr_s("xml:lang", Attrs), MaxUsers = get_max_users(StateData), MaxAdminUsers = MaxUsers + get_max_users_admin_threshold(StateData), NUsers = dict:fold(fun(_, _, Acc) -> Acc + 1 end, 0, StateData#state.users), Affiliation = get_affiliation(From, StateData), ServiceAffiliation = get_service_affiliation(From, StateData), NConferences = tab_count_user(From), MaxConferences = gen_mod:get_module_opt( StateData#state.server_host, StateData#state.mod, max_user_conferences, 10), Collision = nick_collision(From, Nick, StateData), case {(ServiceAffiliation == owner orelse ((Affiliation == admin orelse Affiliation == owner) andalso NUsers < MaxAdminUsers) orelse NUsers < MaxUsers) andalso NConferences < MaxConferences, Collision, (StateData#state.mod):can_use_nick(StateData#state.server_host, StateData#state.host, From, Nick), get_default_role(Affiliation, StateData)} of {false, _, _, _} -> % max user reached and user is not admin or owner Err = jlib:make_error_reply( Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route( % TODO: s/Nick/""/ jlib:jid_replace_resource(StateData#state.jid, Nick), From, Err), StateData; {_, _, _, none} -> Err = jlib:make_error_reply( Packet, case Affiliation of outcast -> ErrText = "You have been banned from this room", ?ERRT_FORBIDDEN(Lang, ErrText); _ -> ErrText = "Membership is required to enter this room", ?ERRT_REGISTRATION_REQUIRED(Lang, ErrText) end), ejabberd_router:route( % TODO: s/Nick/""/ jlib:jid_replace_resource(StateData#state.jid, Nick), From, Err), StateData; {_, true, _, _} -> ErrText = "That nickname is already in use by another occupant", Err = jlib:make_error_reply(Packet, ?ERRT_CONFLICT(Lang, ErrText)), ejabberd_router:route( % TODO: s/Nick/""/ jlib:jid_replace_resource(StateData#state.jid, Nick), From, Err), StateData; {_, _, false, _} -> ErrText = "That nickname is registered by another person", Err = jlib:make_error_reply(Packet, ?ERRT_CONFLICT(Lang, ErrText)), ejabberd_router:route( % TODO: s/Nick/""/ jlib:jid_replace_resource(StateData#state.jid, Nick), From, Err), StateData; {_, _, _, Role} -> case check_password(ServiceAffiliation, Affiliation, Els, From, StateData) of true -> NewState = add_user_presence( From, Packet, add_online_user(From, Nick, Role, StateData)), if not (NewState#state.config)#config.anonymous -> WPacket = {xmlelement, "message", [{"type", "groupchat"}], [{xmlelement, "body", [], [{xmlcdata, translate:translate( Lang, "This room is not anonymous")}]}, {xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "status", [{"code", "100"}], []}]}]}, ejabberd_router:route( StateData#state.jid, From, WPacket); true -> ok end, send_existing_presences(From, NewState), send_new_presence(From, NewState), Shift = count_stanza_shift(Nick, Els, NewState), case send_history(From, Shift, NewState) of true -> ok; _ -> send_subject(From, Lang, StateData) end, case NewState#state.just_created of true -> NewState#state{just_created = false}; false -> Robots = ?DICT:erase(From, StateData#state.robots), NewState#state{robots = Robots} end; nopass -> ErrText = "A password is required to enter this room", Err = jlib:make_error_reply( Packet, ?ERRT_NOT_AUTHORIZED(Lang, ErrText)), ejabberd_router:route( % TODO: s/Nick/""/ jlib:jid_replace_resource( StateData#state.jid, Nick), From, Err), StateData; captcha_required -> SID = xml:get_attr_s("id", Attrs), RoomJID = StateData#state.jid, To = jlib:jid_replace_resource(RoomJID, Nick), Limiter = {From#jid.luser, From#jid.lserver}, case ejabberd_captcha:create_captcha( SID, RoomJID, To, Lang, Limiter, From) of {ok, ID, CaptchaEls} -> MsgPkt = {xmlelement, "message", [{"id", ID}], CaptchaEls}, Robots = ?DICT:store(From, {Nick, Packet}, StateData#state.robots), ejabberd_router:route(RoomJID, From, MsgPkt), StateData#state{robots = Robots}; {error, limit} -> ErrText = "Too many CAPTCHA requests", Err = jlib:make_error_reply( Packet, ?ERRT_RESOURCE_CONSTRAINT(Lang, ErrText)), ejabberd_router:route( % TODO: s/Nick/""/ jlib:jid_replace_resource( StateData#state.jid, Nick), From, Err), StateData; _ -> ErrText = "Unable to generate a CAPTCHA", Err = jlib:make_error_reply( Packet, ?ERRT_INTERNAL_SERVER_ERROR(Lang, ErrText)), ejabberd_router:route( % TODO: s/Nick/""/ jlib:jid_replace_resource( StateData#state.jid, Nick), From, Err), StateData end; _ -> ErrText = "Incorrect password", Err = jlib:make_error_reply( Packet, ?ERRT_NOT_AUTHORIZED(Lang, ErrText)), ejabberd_router:route( % TODO: s/Nick/""/ jlib:jid_replace_resource( StateData#state.jid, Nick), From, Err), StateData end end. check_password(owner, _Affiliation, _Els, _From, _StateData) -> %% Don't check pass if user is owner in MUC service (access_admin option) true; check_password(_ServiceAffiliation, Affiliation, Els, From, StateData) -> case (StateData#state.config)#config.password_protected of false -> check_captcha(Affiliation, From, StateData); true -> Pass = extract_password(Els), case Pass of false -> nopass; _ -> case (StateData#state.config)#config.password of Pass -> true; _ -> false end end end. check_captcha(Affiliation, From, StateData) -> case (StateData#state.config)#config.captcha_protected andalso ejabberd_captcha:is_feature_available() of true when Affiliation == none -> case ?DICT:find(From, StateData#state.robots) of {ok, passed} -> true; _ -> WList = (StateData#state.config)#config.captcha_whitelist, #jid{luser = U, lserver = S, lresource = R} = From, case ?SETS:is_element({U, S, R}, WList) of true -> true; false -> case ?SETS:is_element({U, S, ""}, WList) of true -> true; false -> case ?SETS:is_element({"", S, ""}, WList) of true -> true; false -> captcha_required end end end end; _ -> true end. extract_password([]) -> false; extract_password([{xmlelement, _Name, Attrs, _SubEls} = El | Els]) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_MUC -> case xml:get_subtag(El, "password") of false -> false; SubEl -> xml:get_tag_cdata(SubEl) end; _ -> extract_password(Els) end; extract_password([_ | Els]) -> extract_password(Els). count_stanza_shift(Nick, Els, StateData) -> HL = lqueue_to_list(StateData#state.history), Since = extract_history(Els, "since"), Shift0 = case Since of false -> 0; _ -> Sin = calendar:datetime_to_gregorian_seconds(Since), count_seconds_shift(Sin, HL) end, Seconds = extract_history(Els, "seconds"), Shift1 = case Seconds of false -> 0; _ -> Sec = calendar:datetime_to_gregorian_seconds( calendar:now_to_universal_time(now())) - Seconds, count_seconds_shift(Sec, HL) end, MaxStanzas = extract_history(Els, "maxstanzas"), Shift2 = case MaxStanzas of false -> 0; _ -> count_maxstanzas_shift(MaxStanzas, HL) end, MaxChars = extract_history(Els, "maxchars"), Shift3 = case MaxChars of false -> 0; _ -> count_maxchars_shift(Nick, MaxChars, HL) end, lists:max([Shift0, Shift1, Shift2, Shift3]). count_seconds_shift(Seconds, HistoryList) -> lists:sum( lists:map( fun({_Nick, _Packet, _HaveSubject, TimeStamp, _Size}) -> T = calendar:datetime_to_gregorian_seconds(TimeStamp), if T < Seconds -> 1; true -> 0 end end, HistoryList)). count_maxstanzas_shift(MaxStanzas, HistoryList) -> S = length(HistoryList) - MaxStanzas, if S =< 0 -> 0; true -> S end. count_maxchars_shift(Nick, MaxSize, HistoryList) -> NLen = string:len(Nick) + 1, Sizes = lists:map( fun({_Nick, _Packet, _HaveSubject, _TimeStamp, Size}) -> Size + NLen end, HistoryList), calc_shift(MaxSize, Sizes). calc_shift(MaxSize, Sizes) -> Total = lists:sum(Sizes), calc_shift(MaxSize, Total, 0, Sizes). calc_shift(_MaxSize, _Size, Shift, []) -> Shift; calc_shift(MaxSize, Size, Shift, [S | TSizes]) -> if MaxSize >= Size -> Shift; true -> calc_shift(MaxSize, Size - S, Shift + 1, TSizes) end. extract_history([], _Type) -> false; extract_history([{xmlelement, _Name, Attrs, _SubEls} = El | Els], Type) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_MUC -> AttrVal = xml:get_path_s(El, [{elem, "history"}, {attr, Type}]), case Type of "since" -> case jlib:datetime_string_to_timestamp(AttrVal) of undefined -> false; TS -> calendar:now_to_universal_time(TS) end; _ -> case catch list_to_integer(AttrVal) of IntVal when is_integer(IntVal) and (IntVal >= 0) -> IntVal; _ -> false end end; _ -> extract_history(Els, Type) end; extract_history([_ | Els], Type) -> extract_history(Els, Type). send_update_presence(JID, StateData) -> send_update_presence(JID, "", StateData). send_update_presence(JID, Reason, StateData) -> LJID = jlib:jid_tolower(JID), LJIDs = case LJID of {U, S, ""} -> ?DICT:fold( fun(J, _, Js) -> case J of {U, S, _} -> [J | Js]; _ -> Js end end, [], StateData#state.users); _ -> case ?DICT:is_key(LJID, StateData#state.users) of true -> [LJID]; _ -> [] end end, lists:foreach(fun(J) -> send_new_presence(J, Reason, StateData) end, LJIDs). send_new_presence(NJID, StateData) -> send_new_presence(NJID, "", StateData). send_new_presence(NJID, Reason, StateData) -> %% First, find the nick associated with this JID. #user{nick = Nick} = ?DICT:fetch(jlib:jid_tolower(NJID), StateData#state.users), %% Then find the JID using this nick with highest priority. LJID = find_jid_by_nick(Nick, StateData), %% Then we get the presence data we're supposed to send. {ok, #user{jid = RealJID, role = Role, last_presence = Presence}} = ?DICT:find(jlib:jid_tolower(LJID), StateData#state.users), Affiliation = get_affiliation(LJID, StateData), SAffiliation = affiliation_to_list(Affiliation), SRole = role_to_list(Role), lists:foreach( fun({_LJID, Info}) -> ItemAttrs = case (Info#user.role == moderator) orelse ((StateData#state.config)#config.anonymous == false) of true -> [{"jid", jlib:jid_to_string(RealJID)}, {"affiliation", SAffiliation}, {"role", SRole}]; _ -> [{"affiliation", SAffiliation}, {"role", SRole}] end, ItemEls = case Reason of "" -> []; _ -> [{xmlelement, "reason", [], [{xmlcdata, Reason}]}] end, Status = case StateData#state.just_created of true -> [{xmlelement, "status", [{"code", "201"}], []}]; false -> [] end, Status2 = case ((StateData#state.config)#config.anonymous==false) andalso (NJID == Info#user.jid) of true -> [{xmlelement, "status", [{"code", "100"}], []} | Status]; false -> Status end, Status3 = case NJID == Info#user.jid of true -> [{xmlelement, "status", [{"code", "110"}], []} | Status2]; false -> Status2 end, Packet = xml:append_subtags( Presence, [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", ItemAttrs, ItemEls} | Status3]}]), ejabberd_router:route( jlib:jid_replace_resource(StateData#state.jid, Nick), Info#user.jid, Packet) end, ?DICT:to_list(StateData#state.users)). send_existing_presences(ToJID, StateData) -> LToJID = jlib:jid_tolower(ToJID), {ok, #user{jid = RealToJID, role = Role}} = ?DICT:find(LToJID, StateData#state.users), lists:foreach( fun({FromNick, _Users}) -> LJID = find_jid_by_nick(FromNick, StateData), #user{jid = FromJID, role = FromRole, last_presence = Presence } = ?DICT:fetch(jlib:jid_tolower(LJID), StateData#state.users), case RealToJID of FromJID -> ok; _ -> FromAffiliation = get_affiliation(LJID, StateData), ItemAttrs = case (Role == moderator) orelse ((StateData#state.config)#config.anonymous == false) of true -> [{"jid", jlib:jid_to_string(FromJID)}, {"affiliation", affiliation_to_list(FromAffiliation)}, {"role", role_to_list(FromRole)}]; _ -> [{"affiliation", affiliation_to_list(FromAffiliation)}, {"role", role_to_list(FromRole)}] end, Packet = xml:append_subtags( Presence, [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", ItemAttrs, []}]}]), ejabberd_router:route( jlib:jid_replace_resource( StateData#state.jid, FromNick), RealToJID, Packet) end end, ?DICT:to_list(StateData#state.nicks)). now_to_usec({MSec, Sec, USec}) -> (MSec*1000000 + Sec)*1000000 + USec. change_nick(JID, Nick, StateData) -> LJID = jlib:jid_tolower(JID), {ok, #user{nick = OldNick}} = ?DICT:find(LJID, StateData#state.users), Users = ?DICT:update( LJID, fun(#user{} = User) -> User#user{nick = Nick} end, StateData#state.users), OldNickUsers = ?DICT:fetch(OldNick, StateData#state.nicks), NewNickUsers = case ?DICT:find(Nick, StateData#state.nicks) of {ok, U} -> U; error -> [] end, %% Send unavailable presence from the old nick if it's no longer %% used. SendOldUnavailable = length(OldNickUsers) == 1, %% If we send unavailable presence from the old nick, we should %% probably send presence from the new nick, in order not to %% confuse clients. Otherwise, do it only if the new nick was %% unused. SendNewAvailable = SendOldUnavailable orelse NewNickUsers == [], Nicks = case OldNickUsers of [LJID] -> ?DICT:store(Nick, [LJID|NewNickUsers], ?DICT:erase(OldNick, StateData#state.nicks)); [_|_] -> ?DICT:store(Nick, [LJID|NewNickUsers], ?DICT:store(OldNick, OldNickUsers -- [LJID], StateData#state.nicks)) end, NewStateData = StateData#state{users = Users, nicks = Nicks}, send_nick_changing(JID, OldNick, NewStateData, SendOldUnavailable, SendNewAvailable), add_to_log(nickchange, {OldNick, Nick}, StateData), NewStateData. send_nick_changing(JID, OldNick, StateData, SendOldUnavailable, SendNewAvailable) -> {ok, #user{jid = RealJID, nick = Nick, role = Role, last_presence = Presence}} = ?DICT:find(jlib:jid_tolower(JID), StateData#state.users), Affiliation = get_affiliation(JID, StateData), SAffiliation = affiliation_to_list(Affiliation), SRole = role_to_list(Role), lists:foreach( fun({_LJID, Info}) -> ItemAttrs1 = case (Info#user.role == moderator) orelse ((StateData#state.config)#config.anonymous == false) of true -> [{"jid", jlib:jid_to_string(RealJID)}, {"affiliation", SAffiliation}, {"role", SRole}, {"nick", Nick}]; _ -> [{"affiliation", SAffiliation}, {"role", SRole}, {"nick", Nick}] end, ItemAttrs2 = case (Info#user.role == moderator) orelse ((StateData#state.config)#config.anonymous == false) of true -> [{"jid", jlib:jid_to_string(RealJID)}, {"affiliation", SAffiliation}, {"role", SRole}]; _ -> [{"affiliation", SAffiliation}, {"role", SRole}] end, Packet1 = {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", ItemAttrs1, []}, {xmlelement, "status", [{"code", "303"}], []}]}]}, Packet2 = xml:append_subtags( Presence, [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", ItemAttrs2, []}]}]), if SendOldUnavailable -> ejabberd_router:route( jlib:jid_replace_resource(StateData#state.jid, OldNick), Info#user.jid, Packet1); true -> ok end, if SendNewAvailable -> ejabberd_router:route( jlib:jid_replace_resource(StateData#state.jid, Nick), Info#user.jid, Packet2); true -> ok end end, ?DICT:to_list(StateData#state.users)). lqueue_new(Max) -> #lqueue{queue = queue:new(), len = 0, max = Max}. %% If the message queue limit is set to 0, do not store messages. lqueue_in(_Item, LQ = #lqueue{max = 0}) -> LQ; %% Otherwise, rotate messages in the queue store. lqueue_in(Item, #lqueue{queue = Q1, len = Len, max = Max}) -> Q2 = queue:in(Item, Q1), if Len >= Max -> Q3 = lqueue_cut(Q2, Len - Max + 1), #lqueue{queue = Q3, len = Max, max = Max}; true -> #lqueue{queue = Q2, len = Len + 1, max = Max} end. lqueue_cut(Q, 0) -> Q; lqueue_cut(Q, N) -> {_, Q1} = queue:out(Q), lqueue_cut(Q1, N - 1). lqueue_to_list(#lqueue{queue = Q1}) -> queue:to_list(Q1). add_message_to_history(FromNick, FromJID, Packet, StateData) -> HaveSubject = case xml:get_subtag(Packet, "subject") of false -> false; _ -> true end, TimeStamp = calendar:now_to_universal_time(now()), %% Chatroom history is stored as XMPP packets, so %% the decision to include the original sender's JID or not is based on the %% chatroom configuration when the message was originally sent. %% Also, if the chatroom is anonymous, even moderators will not get the real JID SenderJid = case ((StateData#state.config)#config.anonymous) of true -> StateData#state.jid; false -> FromJID end, TSPacket = xml:append_subtags(Packet, [jlib:timestamp_to_xml(TimeStamp, utc, SenderJid, ""), %% TODO: Delete the next line once XEP-0091 is Obsolete jlib:timestamp_to_xml(TimeStamp)]), SPacket = jlib:replace_from_to( jlib:jid_replace_resource(StateData#state.jid, FromNick), StateData#state.jid, TSPacket), Size = element_size(SPacket), Q1 = lqueue_in({FromNick, TSPacket, HaveSubject, TimeStamp, Size}, StateData#state.history), add_to_log(text, {FromNick, Packet}, StateData), StateData#state{history = Q1}. send_history(JID, Shift, StateData) -> lists:foldl( fun({Nick, Packet, HaveSubject, _TimeStamp, _Size}, B) -> ejabberd_router:route( jlib:jid_replace_resource(StateData#state.jid, Nick), JID, Packet), B or HaveSubject end, false, lists:nthtail(Shift, lqueue_to_list(StateData#state.history))). send_subject(JID, Lang, StateData) -> case StateData#state.subject_author of "" -> ok; Nick -> Subject = StateData#state.subject, Packet = {xmlelement, "message", [{"type", "groupchat"}], [{xmlelement, "subject", [], [{xmlcdata, Subject}]}, {xmlelement, "body", [], [{xmlcdata, Nick ++ translate:translate(Lang, " has set the subject to: ") ++ Subject}]}]}, ejabberd_router:route( StateData#state.jid, JID, Packet) end. check_subject(Packet) -> case xml:get_subtag(Packet, "subject") of false -> false; SubjEl -> xml:get_tag_cdata(SubjEl) end. can_change_subject(Role, StateData) -> case (StateData#state.config)#config.allow_change_subj of true -> (Role == moderator) orelse (Role == participant); _ -> Role == moderator end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Admin stuff process_iq_admin(From, set, Lang, SubEl, StateData) -> {xmlelement, _, _, Items} = SubEl, process_admin_items_set(From, Items, Lang, StateData); process_iq_admin(From, get, Lang, SubEl, StateData) -> case xml:get_subtag(SubEl, "item") of false -> {error, ?ERR_BAD_REQUEST}; Item -> FAffiliation = get_affiliation(From, StateData), FRole = get_role(From, StateData), case xml:get_tag_attr("role", Item) of false -> case xml:get_tag_attr("affiliation", Item) of false -> {error, ?ERR_BAD_REQUEST}; {value, StrAffiliation} -> case catch list_to_affiliation(StrAffiliation) of {'EXIT', _} -> {error, ?ERR_BAD_REQUEST}; SAffiliation -> if (FAffiliation == owner) or (FAffiliation == admin) -> Items = items_with_affiliation( SAffiliation, StateData), {result, Items, StateData}; true -> ErrText = "Administrator privileges required", {error, ?ERRT_FORBIDDEN(Lang, ErrText)} end end end; {value, StrRole} -> case catch list_to_role(StrRole) of {'EXIT', _} -> {error, ?ERR_BAD_REQUEST}; SRole -> if FRole == moderator -> Items = items_with_role(SRole, StateData), {result, Items, StateData}; true -> ErrText = "Moderator privileges required", {error, ?ERRT_FORBIDDEN(Lang, ErrText)} end end end end. items_with_role(SRole, StateData) -> lists:map( fun({_, U}) -> user_to_item(U, StateData) end, search_role(SRole, StateData)). items_with_affiliation(SAffiliation, StateData) -> lists:map( fun({JID, {Affiliation, Reason}}) -> {xmlelement, "item", [{"affiliation", affiliation_to_list(Affiliation)}, {"jid", jlib:jid_to_string(JID)}], [{xmlelement, "reason", [], [{xmlcdata, Reason}]}]}; ({JID, Affiliation}) -> {xmlelement, "item", [{"affiliation", affiliation_to_list(Affiliation)}, {"jid", jlib:jid_to_string(JID)}], []} end, search_affiliation(SAffiliation, StateData)). user_to_item(#user{role = Role, nick = Nick, jid = JID }, StateData) -> Affiliation = get_affiliation(JID, StateData), {xmlelement, "item", [{"role", role_to_list(Role)}, {"affiliation", affiliation_to_list(Affiliation)}, {"nick", Nick}, {"jid", jlib:jid_to_string(JID)}], []}. search_role(Role, StateData) -> lists:filter( fun({_, #user{role = R}}) -> Role == R end, ?DICT:to_list(StateData#state.users)). search_affiliation(Affiliation, StateData) -> lists:filter( fun({_, A}) -> case A of {A1, _Reason} -> Affiliation == A1; _ -> Affiliation == A end end, ?DICT:to_list(StateData#state.affiliations)). process_admin_items_set(UJID, Items, Lang, StateData) -> UAffiliation = get_affiliation(UJID, StateData), URole = get_role(UJID, StateData), case find_changed_items(UJID, UAffiliation, URole, Items, Lang, StateData, []) of {result, Res} -> ?INFO_MSG("Processing MUC admin query from ~s in room ~s:~n ~p", [jlib:jid_to_string(UJID), jlib:jid_to_string(StateData#state.jid), Res]), NSD = lists:foldl( fun(E, SD) -> case catch ( case E of {JID, affiliation, owner, _} when (JID#jid.luser == "") -> %% If the provided JID does not have username, %% forget the affiliation completely SD; {JID, role, none, Reason} -> catch send_kickban_presence( JID, Reason, "307", SD), set_role(JID, none, SD); {JID, affiliation, none, Reason} -> case (SD#state.config)#config.members_only of true -> catch send_kickban_presence( JID, Reason, "321", none, SD), SD1 = set_affiliation(JID, none, SD), set_role(JID, none, SD1); _ -> SD1 = set_affiliation(JID, none, SD), send_update_presence(JID, SD1), SD1 end; {JID, affiliation, outcast, Reason} -> catch send_kickban_presence( JID, Reason, "301", outcast, SD), set_affiliation( JID, outcast, set_role(JID, none, SD), Reason); {JID, affiliation, A, Reason} when (A == admin) or (A == owner) -> SD1 = set_affiliation(JID, A, SD, Reason), SD2 = set_role(JID, moderator, SD1), send_update_presence(JID, Reason, SD2), SD2; {JID, affiliation, member, Reason} -> SD1 = set_affiliation( JID, member, SD, Reason), SD2 = set_role(JID, participant, SD1), send_update_presence(JID, Reason, SD2), SD2; {JID, role, Role, Reason} -> SD1 = set_role(JID, Role, SD), catch send_new_presence(JID, Reason, SD1), SD1; {JID, affiliation, A, _Reason} -> SD1 = set_affiliation(JID, A, SD), send_update_presence(JID, SD1), SD1 end ) of {'EXIT', ErrReason} -> ?ERROR_MSG("MUC ITEMS SET ERR: ~p~n", [ErrReason]), SD; NSD -> NSD end end, StateData, lists:flatten(Res)), case (NSD#state.config)#config.persistent of true -> (NSD#state.mod):store_room(NSD#state.server_host, NSD#state.host, NSD#state.room, make_opts(NSD)); _ -> ok end, {result, [], NSD}; Err -> Err end. find_changed_items(_UJID, _UAffiliation, _URole, [], _Lang, _StateData, Res) -> {result, Res}; find_changed_items(UJID, UAffiliation, URole, [{xmlcdata, _} | Items], Lang, StateData, Res) -> find_changed_items(UJID, UAffiliation, URole, Items, Lang, StateData, Res); find_changed_items(UJID, UAffiliation, URole, [{xmlelement, "item", Attrs, _Els} = Item | Items], Lang, StateData, Res) -> TJID = case xml:get_attr("jid", Attrs) of {value, S} -> case jlib:string_to_jid(S) of error -> ErrText = io_lib:format( translate:translate( Lang, "Jabber ID ~s is invalid"), [S]), {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)}; J -> {value, [J]} end; _ -> case xml:get_attr("nick", Attrs) of {value, N} -> case find_jids_by_nick(N, StateData) of false -> ErrText = io_lib:format( translate:translate( Lang, "Nickname ~s does not exist in the room"), [N]), {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)}; J -> {value, J} end; _ -> {error, ?ERR_BAD_REQUEST} end end, case TJID of {value, [JID|_]=JIDs} -> TAffiliation = get_affiliation(JID, StateData), TRole = get_role(JID, StateData), case xml:get_attr("role", Attrs) of false -> case xml:get_attr("affiliation", Attrs) of false -> {error, ?ERR_BAD_REQUEST}; {value, StrAffiliation} -> case catch list_to_affiliation(StrAffiliation) of {'EXIT', _} -> ErrText1 = io_lib:format( translate:translate( Lang, "Invalid affiliation: ~s"), [StrAffiliation]), {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText1)}; SAffiliation -> ServiceAf = get_service_affiliation(JID, StateData), CanChangeRA = case can_change_ra( UAffiliation, URole, TAffiliation, TRole, affiliation, SAffiliation, ServiceAf) of nothing -> nothing; true -> true; check_owner -> case search_affiliation( owner, StateData) of [{OJID, _}] -> jlib:jid_remove_resource(OJID) /= jlib:jid_tolower(jlib:jid_remove_resource(UJID)); _ -> true end; _ -> false end, case CanChangeRA of nothing -> find_changed_items( UJID, UAffiliation, URole, Items, Lang, StateData, Res); true -> Reason = xml:get_path_s(Item, [{elem, "reason"}, cdata]), MoreRes = [{jlib:jid_remove_resource(Jidx), affiliation, SAffiliation, Reason} || Jidx <- JIDs], find_changed_items( UJID, UAffiliation, URole, Items, Lang, StateData, [MoreRes | Res]); false -> {error, ?ERR_NOT_ALLOWED} end end end; {value, StrRole} -> case catch list_to_role(StrRole) of {'EXIT', _} -> ErrText1 = io_lib:format( translate:translate( Lang, "Invalid role: ~s"), [StrRole]), {error, ?ERRT_BAD_REQUEST(Lang, ErrText1)}; SRole -> ServiceAf = get_service_affiliation(JID, StateData), CanChangeRA = case can_change_ra( UAffiliation, URole, TAffiliation, TRole, role, SRole, ServiceAf) of nothing -> nothing; true -> true; check_owner -> case search_affiliation( owner, StateData) of [{OJID, _}] -> jlib:jid_remove_resource(OJID) /= jlib:jid_tolower(jlib:jid_remove_resource(UJID)); _ -> true end; _ -> false end, case CanChangeRA of nothing -> find_changed_items( UJID, UAffiliation, URole, Items, Lang, StateData, Res); true -> Reason = xml:get_path_s(Item, [{elem, "reason"}, cdata]), MoreRes = [{Jidx, role, SRole, Reason} || Jidx <- JIDs], find_changed_items( UJID, UAffiliation, URole, Items, Lang, StateData, [MoreRes | Res]); _ -> {error, ?ERR_NOT_ALLOWED} end end end; Err -> Err end; find_changed_items(_UJID, _UAffiliation, _URole, _Items, _Lang, _StateData, _Res) -> {error, ?ERR_BAD_REQUEST}. can_change_ra(_FAffiliation, _FRole, owner, _TRole, affiliation, owner, owner) -> %% A room owner tries to add as persistent owner a %% participant that is already owner because he is MUC admin true; can_change_ra(_FAffiliation, _FRole, _TAffiliation, _TRole, _RoleorAffiliation, _Value, owner) -> %% Nobody can decrease MUC admin's role/affiliation false; can_change_ra(_FAffiliation, _FRole, TAffiliation, _TRole, affiliation, Value, _ServiceAf) when (TAffiliation == Value) -> nothing; can_change_ra(_FAffiliation, _FRole, _TAffiliation, TRole, role, Value, _ServiceAf) when (TRole == Value) -> nothing; can_change_ra(FAffiliation, _FRole, outcast, _TRole, affiliation, none, _ServiceAf) when (FAffiliation == owner) or (FAffiliation == admin) -> true; can_change_ra(FAffiliation, _FRole, outcast, _TRole, affiliation, member, _ServiceAf) when (FAffiliation == owner) or (FAffiliation == admin) -> true; can_change_ra(owner, _FRole, outcast, _TRole, affiliation, admin, _ServiceAf) -> true; can_change_ra(owner, _FRole, outcast, _TRole, affiliation, owner, _ServiceAf) -> true; can_change_ra(FAffiliation, _FRole, none, _TRole, affiliation, outcast, _ServiceAf) when (FAffiliation == owner) or (FAffiliation == admin) -> true; can_change_ra(FAffiliation, _FRole, none, _TRole, affiliation, member, _ServiceAf) when (FAffiliation == owner) or (FAffiliation == admin) -> true; can_change_ra(owner, _FRole, none, _TRole, affiliation, admin, _ServiceAf) -> true; can_change_ra(owner, _FRole, none, _TRole, affiliation, owner, _ServiceAf) -> true; can_change_ra(FAffiliation, _FRole, member, _TRole, affiliation, outcast, _ServiceAf) when (FAffiliation == owner) or (FAffiliation == admin) -> true; can_change_ra(FAffiliation, _FRole, member, _TRole, affiliation, none, _ServiceAf) when (FAffiliation == owner) or (FAffiliation == admin) -> true; can_change_ra(owner, _FRole, member, _TRole, affiliation, admin, _ServiceAf) -> true; can_change_ra(owner, _FRole, member, _TRole, affiliation, owner, _ServiceAf) -> true; can_change_ra(owner, _FRole, admin, _TRole, affiliation, _Affiliation, _ServiceAf) -> true; can_change_ra(owner, _FRole, owner, _TRole, affiliation, _Affiliation, _ServiceAf) -> check_owner; can_change_ra(_FAffiliation, _FRole, _TAffiliation, _TRole, affiliation, _Value, _ServiceAf) -> false; can_change_ra(_FAffiliation, moderator, _TAffiliation, visitor, role, none, _ServiceAf) -> true; can_change_ra(_FAffiliation, moderator, _TAffiliation, visitor, role, participant, _ServiceAf) -> true; can_change_ra(FAffiliation, _FRole, _TAffiliation, visitor, role, moderator, _ServiceAf) when (FAffiliation == owner) or (FAffiliation == admin) -> true; can_change_ra(_FAffiliation, moderator, _TAffiliation, participant, role, none, _ServiceAf) -> true; can_change_ra(_FAffiliation, moderator, _TAffiliation, participant, role, visitor, _ServiceAf) -> true; can_change_ra(FAffiliation, _FRole, _TAffiliation, participant, role, moderator, _ServiceAf) when (FAffiliation == owner) or (FAffiliation == admin) -> true; can_change_ra(_FAffiliation, _FRole, owner, moderator, role, visitor, _ServiceAf) -> false; can_change_ra(owner, _FRole, _TAffiliation, moderator, role, visitor, _ServiceAf) -> true; can_change_ra(_FAffiliation, _FRole, admin, moderator, role, visitor, _ServiceAf) -> false; can_change_ra(admin, _FRole, _TAffiliation, moderator, role, visitor, _ServiceAf) -> true; can_change_ra(_FAffiliation, _FRole, owner, moderator, role, participant, _ServiceAf) -> false; can_change_ra(owner, _FRole, _TAffiliation, moderator, role, participant, _ServiceAf) -> true; can_change_ra(_FAffiliation, _FRole, admin, moderator, role, participant, _ServiceAf) -> false; can_change_ra(admin, _FRole, _TAffiliation, moderator, role, participant, _ServiceAf) -> true; can_change_ra(_FAffiliation, _FRole, _TAffiliation, _TRole, role, _Value, _ServiceAf) -> false. send_kickban_presence(JID, Reason, Code, StateData) -> NewAffiliation = get_affiliation(JID, StateData), send_kickban_presence(JID, Reason, Code, NewAffiliation, StateData). send_kickban_presence(JID, Reason, Code, NewAffiliation, StateData) -> LJID = jlib:jid_tolower(JID), LJIDs = case LJID of {U, S, ""} -> ?DICT:fold( fun(J, _, Js) -> case J of {U, S, _} -> [J | Js]; _ -> Js end end, [], StateData#state.users); _ -> case ?DICT:is_key(LJID, StateData#state.users) of true -> [LJID]; _ -> [] end end, lists:foreach(fun(J) -> {ok, #user{nick = Nick}} = ?DICT:find(J, StateData#state.users), add_to_log(kickban, {Nick, Reason, Code}, StateData), tab_remove_online_user(J, StateData), send_kickban_presence1(J, Reason, Code, NewAffiliation, StateData) end, LJIDs). send_kickban_presence1(UJID, Reason, Code, Affiliation, StateData) -> {ok, #user{jid = RealJID, nick = Nick}} = ?DICT:find(jlib:jid_tolower(UJID), StateData#state.users), SAffiliation = affiliation_to_list(Affiliation), BannedJIDString = jlib:jid_to_string(RealJID), lists:foreach( fun({_LJID, Info}) -> JidAttrList = case (Info#user.role == moderator) orelse ((StateData#state.config)#config.anonymous == false) of true -> [{"jid", BannedJIDString}]; false -> [] end, ItemAttrs = [{"affiliation", SAffiliation}, {"role", "none"}] ++ JidAttrList, ItemEls = case Reason of "" -> []; _ -> [{xmlelement, "reason", [], [{xmlcdata, Reason}]}] end, Packet = {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", ItemAttrs, ItemEls}, {xmlelement, "status", [{"code", Code}], []}]}]}, ejabberd_router:route( jlib:jid_replace_resource(StateData#state.jid, Nick), Info#user.jid, Packet) end, ?DICT:to_list(StateData#state.users)). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Owner stuff process_iq_owner(From, set, Lang, SubEl, StateData) -> FAffiliation = get_affiliation(From, StateData), case FAffiliation of owner -> {xmlelement, _Name, _Attrs, Els} = SubEl, case xml:remove_cdata(Els) of [{xmlelement, "x", _Attrs1, _Els1} = XEl] -> case {xml:get_tag_attr_s("xmlns", XEl), xml:get_tag_attr_s("type", XEl)} of {?NS_XDATA, "cancel"} -> {result, [], StateData}; {?NS_XDATA, "submit"} -> case is_allowed_log_change(XEl, StateData, From) andalso is_allowed_persistent_change(XEl, StateData, From) andalso is_allowed_room_name_desc_limits(XEl, StateData) andalso is_password_settings_correct(XEl, StateData) of true -> set_config(XEl, StateData); false -> {error, ?ERR_NOT_ACCEPTABLE} end; _ -> {error, ?ERR_BAD_REQUEST} end; [{xmlelement, "destroy", _Attrs1, _Els1} = SubEl1] -> ?INFO_MSG("Destroyed MUC room ~s by the owner ~s", [jlib:jid_to_string(StateData#state.jid), jlib:jid_to_string(From)]), add_to_log(room_existence, destroyed, StateData), destroy_room(SubEl1, StateData); Items -> process_admin_items_set(From, Items, Lang, StateData) end; _ -> ErrText = "Owner privileges required", {error, ?ERRT_FORBIDDEN(Lang, ErrText)} end; process_iq_owner(From, get, Lang, SubEl, StateData) -> FAffiliation = get_affiliation(From, StateData), case FAffiliation of owner -> {xmlelement, _Name, _Attrs, Els} = SubEl, case xml:remove_cdata(Els) of [] -> get_config(Lang, StateData, From); [Item] -> case xml:get_tag_attr("affiliation", Item) of false -> {error, ?ERR_BAD_REQUEST}; {value, StrAffiliation} -> case catch list_to_affiliation(StrAffiliation) of {'EXIT', _} -> ErrText = io_lib:format( translate:translate( Lang, "Invalid affiliation: ~s"), [StrAffiliation]), {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)}; SAffiliation -> Items = items_with_affiliation( SAffiliation, StateData), {result, Items, StateData} end end; _ -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED} end; _ -> ErrText = "Owner privileges required", {error, ?ERRT_FORBIDDEN(Lang, ErrText)} end. is_allowed_log_change(XEl, StateData, From) -> case lists:keymember("muc#roomconfig_enablelogging", 1, jlib:parse_xdata_submit(XEl)) of false -> true; true -> (allow == mod_muc_log:check_access_log( StateData#state.server_host, From)) end. is_allowed_persistent_change(XEl, StateData, From) -> case lists:keymember("muc#roomconfig_persistentroom", 1, jlib:parse_xdata_submit(XEl)) of false -> true; true -> {_AccessRoute, _AccessCreate, _AccessAdmin, AccessPersistent} = StateData#state.access, (allow == acl:match_rule(StateData#state.server_host, AccessPersistent, From)) end. %% Check if the Room Name and Room Description defined in the Data Form %% are conformant to the configured limits is_allowed_room_name_desc_limits(XEl, StateData) -> IsNameAccepted = case lists:keysearch("muc#roomconfig_roomname", 1, jlib:parse_xdata_submit(XEl)) of {value, {_, [N]}} -> length(N) =< gen_mod:get_module_opt(StateData#state.server_host, StateData#state.mod, max_room_name, infinite); _ -> true end, IsDescAccepted = case lists:keysearch("muc#roomconfig_roomdesc", 1, jlib:parse_xdata_submit(XEl)) of {value, {_, [D]}} -> length(D) =< gen_mod:get_module_opt(StateData#state.server_host, StateData#state.mod, max_room_desc, infinite); _ -> true end, IsNameAccepted and IsDescAccepted. %% Return false if: %% "the password for a password-protected room is blank" is_password_settings_correct(XEl, StateData) -> Config = StateData#state.config, OldProtected = Config#config.password_protected, OldPassword = Config#config.password, NewProtected = case lists:keysearch("muc#roomconfig_passwordprotectedroom", 1, jlib:parse_xdata_submit(XEl)) of {value, {_, ["1"]}} -> true; {value, {_, ["0"]}} -> false; _ -> undefined end, NewPassword = case lists:keysearch("muc#roomconfig_roomsecret", 1, jlib:parse_xdata_submit(XEl)) of {value, {_, [P]}} -> P; _ -> undefined end, case {OldProtected, NewProtected, OldPassword, NewPassword} of {true, undefined, "", undefined} -> false; {true, undefined, _, ""} -> false; {_, true , "", undefined} -> false; {_, true, _, ""} -> false; _ -> true end. -define(XFIELD(Type, Label, Var, Val), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). -define(BOOLXFIELD(Label, Var, Val), ?XFIELD("boolean", Label, Var, case Val of true -> "1"; _ -> "0" end)). -define(STRINGXFIELD(Label, Var, Val), ?XFIELD("text-single", Label, Var, Val)). -define(PRIVATEXFIELD(Label, Var, Val), ?XFIELD("text-private", Label, Var, Val)). -define(JIDMULTIXFIELD(Label, Var, JIDList), {xmlelement, "field", [{"type", "jid-multi"}, {"label", translate:translate(Lang, Label)}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, jlib:jid_to_string(JID)}]} || JID <- JIDList]}). get_default_room_maxusers(RoomState) -> DefRoomOpts = gen_mod:get_module_opt( RoomState#state.server_host, RoomState#state.mod, default_room_options, []), RoomState2 = set_opts(DefRoomOpts, RoomState), (RoomState2#state.config)#config.max_users. get_config(Lang, StateData, From) -> {_AccessRoute, _AccessCreate, _AccessAdmin, AccessPersistent} = StateData#state.access, ServiceMaxUsers = get_service_max_users(StateData), DefaultRoomMaxUsers = get_default_room_maxusers(StateData), Config = StateData#state.config, {MaxUsersRoomInteger, MaxUsersRoomString} = case get_max_users(StateData) of N when is_integer(N) -> {N, erlang:integer_to_list(N)}; _ -> {0, "none"} end, Res = [{xmlelement, "title", [], [{xmlcdata, io_lib:format(translate:translate(Lang, "Configuration of room ~s"), [jlib:jid_to_string(StateData#state.jid)])}]}, {xmlelement, "field", [{"type", "hidden"}, {"var", "FORM_TYPE"}], [{xmlelement, "value", [], [{xmlcdata, "http://jabber.org/protocol/muc#roomconfig"}]}]}, ?STRINGXFIELD("Room title", "muc#roomconfig_roomname", Config#config.title), ?STRINGXFIELD("Room description", "muc#roomconfig_roomdesc", Config#config.description) ] ++ case acl:match_rule(StateData#state.server_host, AccessPersistent, From) of allow -> [?BOOLXFIELD( "Make room persistent", "muc#roomconfig_persistentroom", Config#config.persistent)]; _ -> [] end ++ [ ?BOOLXFIELD("Make room public searchable", "muc#roomconfig_publicroom", Config#config.public), ?BOOLXFIELD("Make participants list public", "public_list", Config#config.public_list), ?BOOLXFIELD("Make room password protected", "muc#roomconfig_passwordprotectedroom", Config#config.password_protected), ?PRIVATEXFIELD("Password", "muc#roomconfig_roomsecret", case Config#config.password_protected of true -> Config#config.password; false -> "" end), {xmlelement, "field", [{"type", "list-single"}, {"label", translate:translate(Lang, "Maximum Number of Occupants")}, {"var", "muc#roomconfig_maxusers"}], [{xmlelement, "value", [], [{xmlcdata, MaxUsersRoomString}]}] ++ if is_integer(ServiceMaxUsers) -> []; true -> [{xmlelement, "option", [{"label", translate:translate(Lang, "No limit")}], [{xmlelement, "value", [], [{xmlcdata, "none"}]}]}] end ++ [{xmlelement, "option", [{"label", erlang:integer_to_list(N)}], [{xmlelement, "value", [], [{xmlcdata, erlang:integer_to_list(N)}]}]} || N <- lists:usort([ServiceMaxUsers, DefaultRoomMaxUsers, MaxUsersRoomInteger | ?MAX_USERS_DEFAULT_LIST]), N =< ServiceMaxUsers] }, {xmlelement, "field", [{"type", "list-single"}, {"label", translate:translate(Lang, "Present real Jabber IDs to")}, {"var", "muc#roomconfig_whois"}], [{xmlelement, "value", [], [{xmlcdata, if Config#config.anonymous -> "moderators"; true -> "anyone" end}]}, {xmlelement, "option", [{"label", translate:translate(Lang, "moderators only")}], [{xmlelement, "value", [], [{xmlcdata, "moderators"}]}]}, {xmlelement, "option", [{"label", translate:translate(Lang, "anyone")}], [{xmlelement, "value", [], [{xmlcdata, "anyone"}]}]}]}, ?BOOLXFIELD("Make room members-only", "muc#roomconfig_membersonly", Config#config.members_only), ?BOOLXFIELD("Make room moderated", "muc#roomconfig_moderatedroom", Config#config.moderated), ?BOOLXFIELD("Default users as participants", "members_by_default", Config#config.members_by_default), ?BOOLXFIELD("Allow users to change the subject", "muc#roomconfig_changesubject", Config#config.allow_change_subj), ?BOOLXFIELD("Allow users to send private messages", "allow_private_messages", Config#config.allow_private_messages), {xmlelement, "field", [{"type", "list-single"}, {"label", translate:translate(Lang, "Allow visitors to send private messages to")}, {"var", "allow_private_messages_from_visitors"}], [{xmlelement, "value", [], [{xmlcdata, case Config#config.allow_private_messages_from_visitors of anyone -> "anyone"; moderators -> "moderators"; nobody -> "nobody" end}]}, {xmlelement, "option", [{"label", translate:translate(Lang, "nobody")}], [{xmlelement, "value", [], [{xmlcdata, "nobody"}]}]}, {xmlelement, "option", [{"label", translate:translate(Lang, "moderators only")}], [{xmlelement, "value", [], [{xmlcdata, "moderators"}]}]}, {xmlelement, "option", [{"label", translate:translate(Lang, "anyone")}], [{xmlelement, "value", [], [{xmlcdata, "anyone"}]}]}]}, ?BOOLXFIELD("Allow users to query other users", "allow_query_users", Config#config.allow_query_users), ?BOOLXFIELD("Allow users to send invites", "muc#roomconfig_allowinvites", Config#config.allow_user_invites), ?BOOLXFIELD("Allow visitors to send status text in presence updates", "muc#roomconfig_allowvisitorstatus", Config#config.allow_visitor_status), ?BOOLXFIELD("Allow visitors to change nickname", "muc#roomconfig_allowvisitornickchange", Config#config.allow_visitor_nickchange), ?BOOLXFIELD("Allow visitors to send voice requests", "muc#roomconfig_allowvoicerequests", Config#config.allow_voice_requests), ?STRINGXFIELD("Minimum interval between voice requests (in seconds)", "muc#roomconfig_voicerequestmininterval", erlang:integer_to_list(Config#config.voice_request_min_interval)) ] ++ case ejabberd_captcha:is_feature_available() of true -> [?BOOLXFIELD("Make room CAPTCHA protected", "captcha_protected", Config#config.captcha_protected)]; false -> [] end ++ [?JIDMULTIXFIELD("Exclude Jabber IDs from CAPTCHA challenge", "muc#roomconfig_captcha_whitelist", ?SETS:to_list(Config#config.captcha_whitelist))] ++ case mod_muc_log:check_access_log( StateData#state.server_host, From) of allow -> [?BOOLXFIELD( "Enable logging", "muc#roomconfig_enablelogging", Config#config.logging)]; _ -> [] end, {result, [{xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "You need an x:data capable client to configure room")}]}, {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], Res}], StateData}. set_config(XEl, StateData) -> XData = jlib:parse_xdata_submit(XEl), case XData of invalid -> {error, ?ERR_BAD_REQUEST}; _ -> case set_xoption(XData, StateData#state.config) of #config{} = Config -> Res = change_config(Config, StateData), {result, _, NSD} = Res, Type = case {(StateData#state.config)#config.logging, Config#config.logging} of {true, false} -> roomconfig_change_disabledlogging; {false, true} -> roomconfig_change_enabledlogging; {_, _} -> roomconfig_change end, Users = [{U#user.jid, U#user.nick, U#user.role} || {_, U} <- ?DICT:to_list(StateData#state.users)], add_to_log(Type, Users, NSD), Res; Err -> Err end end. -define(SET_BOOL_XOPT(Opt, Val), case Val of "0" -> set_xoption(Opts, Config#config{Opt = false}); "false" -> set_xoption(Opts, Config#config{Opt = false}); "1" -> set_xoption(Opts, Config#config{Opt = true}); "true" -> set_xoption(Opts, Config#config{Opt = true}); _ -> {error, ?ERR_BAD_REQUEST} end). -define(SET_NAT_XOPT(Opt, Val), case catch list_to_integer(Val) of I when is_integer(I), I > 0 -> set_xoption(Opts, Config#config{Opt = I}); _ -> {error, ?ERR_BAD_REQUEST} end). -define(SET_STRING_XOPT(Opt, Val), set_xoption(Opts, Config#config{Opt = Val})). -define(SET_JIDMULTI_XOPT(Opt, Vals), begin Set = lists:foldl( fun({U, S, R}, Set1) -> ?SETS:add_element({U, S, R}, Set1); (#jid{luser = U, lserver = S, lresource = R}, Set1) -> ?SETS:add_element({U, S, R}, Set1); (_, Set1) -> Set1 end, ?SETS:empty(), Vals), set_xoption(Opts, Config#config{Opt = Set}) end). set_xoption([], Config) -> Config; set_xoption([{"muc#roomconfig_roomname", [Val]} | Opts], Config) -> ?SET_STRING_XOPT(title, Val); set_xoption([{"muc#roomconfig_roomdesc", [Val]} | Opts], Config) -> ?SET_STRING_XOPT(description, Val); set_xoption([{"muc#roomconfig_changesubject", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(allow_change_subj, Val); set_xoption([{"allow_query_users", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(allow_query_users, Val); set_xoption([{"allow_private_messages", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(allow_private_messages, Val); set_xoption([{"allow_private_messages_from_visitors", [Val]} | Opts], Config) -> case Val of "anyone" -> ?SET_STRING_XOPT(allow_private_messages_from_visitors, anyone); "moderators" -> ?SET_STRING_XOPT(allow_private_messages_from_visitors, moderators); "nobody" -> ?SET_STRING_XOPT(allow_private_messages_from_visitors, nobody); _ -> {error, ?ERR_BAD_REQUEST} end; set_xoption([{"muc#roomconfig_allowvisitorstatus", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(allow_visitor_status, Val); set_xoption([{"muc#roomconfig_allowvisitornickchange", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(allow_visitor_nickchange, Val); set_xoption([{"muc#roomconfig_publicroom", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(public, Val); set_xoption([{"public_list", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(public_list, Val); set_xoption([{"muc#roomconfig_persistentroom", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(persistent, Val); set_xoption([{"muc#roomconfig_moderatedroom", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(moderated, Val); set_xoption([{"members_by_default", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(members_by_default, Val); set_xoption([{"muc#roomconfig_membersonly", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(members_only, Val); set_xoption([{"captcha_protected", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(captcha_protected, Val); set_xoption([{"muc#roomconfig_allowinvites", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(allow_user_invites, Val); set_xoption([{"muc#roomconfig_passwordprotectedroom", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(password_protected, Val); set_xoption([{"muc#roomconfig_roomsecret", [Val]} | Opts], Config) -> ?SET_STRING_XOPT(password, Val); set_xoption([{"anonymous", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(anonymous, Val); set_xoption([{"muc#roomconfig_allowvoicerequests", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(allow_voice_requests, Val); set_xoption([{"muc#roomconfig_voicerequestmininterval", [Val]} | Opts], Config) -> ?SET_NAT_XOPT(voice_request_min_interval, Val); set_xoption([{"muc#roomconfig_whois", [Val]} | Opts], Config) -> case Val of "moderators" -> ?SET_BOOL_XOPT(anonymous, integer_to_list(1)); "anyone" -> ?SET_BOOL_XOPT(anonymous, integer_to_list(0)); _ -> {error, ?ERR_BAD_REQUEST} end; set_xoption([{"muc#roomconfig_maxusers", [Val]} | Opts], Config) -> case Val of "none" -> ?SET_STRING_XOPT(max_users, none); _ -> ?SET_NAT_XOPT(max_users, Val) end; set_xoption([{"muc#roomconfig_enablelogging", [Val]} | Opts], Config) -> ?SET_BOOL_XOPT(logging, Val); set_xoption([{"muc#roomconfig_captcha_whitelist", Vals} | Opts], Config) -> JIDs = [jlib:string_to_jid(Val) || Val <- Vals], ?SET_JIDMULTI_XOPT(captcha_whitelist, JIDs); set_xoption([{"FORM_TYPE", _} | Opts], Config) -> %% Ignore our FORM_TYPE set_xoption(Opts, Config); set_xoption([_ | _Opts], _Config) -> {error, ?ERR_BAD_REQUEST}. change_config(Config, StateData) -> NSD = StateData#state{config = Config}, Mod = StateData#state.mod, case {(StateData#state.config)#config.persistent, Config#config.persistent} of {_, true} -> Mod:store_room(NSD#state.server_host, NSD#state.host, NSD#state.room, make_opts(NSD)); {true, false} -> Mod:forget_room(NSD#state.server_host, NSD#state.host, NSD#state.room); {false, false} -> ok end, case {(StateData#state.config)#config.members_only, Config#config.members_only} of {false, true} -> NSD1 = remove_nonmembers(NSD), {result, [], NSD1}; _ -> {result, [], NSD} end. remove_nonmembers(StateData) -> lists:foldl( fun({_LJID, #user{jid = JID}}, SD) -> Affiliation = get_affiliation(JID, SD), case Affiliation of none -> catch send_kickban_presence( JID, "", "322", SD), set_role(JID, none, SD); _ -> SD end end, StateData, ?DICT:to_list(StateData#state.users)). -define(CASE_CONFIG_OPT(Opt), Opt -> StateData#state{ config = (StateData#state.config)#config{Opt = Val}}). set_opts([], StateData) -> StateData; set_opts([{Opt, Val} | Opts], StateData) -> NSD = case Opt of title -> StateData#state{config = (StateData#state.config)#config{title = Val}}; description -> StateData#state{config = (StateData#state.config)#config{description = Val}}; allow_change_subj -> StateData#state{config = (StateData#state.config)#config{allow_change_subj = Val}}; allow_query_users -> StateData#state{config = (StateData#state.config)#config{allow_query_users = Val}}; allow_private_messages -> StateData#state{config = (StateData#state.config)#config{allow_private_messages = Val}}; allow_private_messages_from_visitors -> StateData#state{config = (StateData#state.config)#config{allow_private_messages_from_visitors = Val}}; allow_visitor_nickchange -> StateData#state{config = (StateData#state.config)#config{allow_visitor_nickchange = Val}}; allow_visitor_status -> StateData#state{config = (StateData#state.config)#config{allow_visitor_status = Val}}; public -> StateData#state{config = (StateData#state.config)#config{public = Val}}; public_list -> StateData#state{config = (StateData#state.config)#config{public_list = Val}}; persistent -> StateData#state{config = (StateData#state.config)#config{persistent = Val}}; moderated -> StateData#state{config = (StateData#state.config)#config{moderated = Val}}; members_by_default -> StateData#state{config = (StateData#state.config)#config{members_by_default = Val}}; members_only -> StateData#state{config = (StateData#state.config)#config{members_only = Val}}; allow_user_invites -> StateData#state{config = (StateData#state.config)#config{allow_user_invites = Val}}; password_protected -> StateData#state{config = (StateData#state.config)#config{password_protected = Val}}; captcha_protected -> StateData#state{config = (StateData#state.config)#config{captcha_protected = Val}}; password -> StateData#state{config = (StateData#state.config)#config{password = Val}}; anonymous -> StateData#state{config = (StateData#state.config)#config{anonymous = Val}}; logging -> StateData#state{config = (StateData#state.config)#config{logging = Val}}; captcha_whitelist -> StateData#state{config = (StateData#state.config)#config{captcha_whitelist = ?SETS:from_list(Val)}}; allow_voice_requests -> StateData#state{config = (StateData#state.config)#config{allow_voice_requests = Val}}; voice_request_min_interval -> StateData#state{config = (StateData#state.config)#config{voice_request_min_interval = Val}}; max_users -> ServiceMaxUsers = get_service_max_users(StateData), MaxUsers = if Val =< ServiceMaxUsers -> Val; true -> ServiceMaxUsers end, StateData#state{ config = (StateData#state.config)#config{ max_users = MaxUsers}}; affiliations -> StateData#state{affiliations = ?DICT:from_list(Val)}; subject -> StateData#state{subject = Val}; subject_author -> StateData#state{subject_author = Val}; _ -> StateData end, set_opts(Opts, NSD). -define(MAKE_CONFIG_OPT(Opt), {Opt, Config#config.Opt}). make_opts(StateData) -> Config = StateData#state.config, [ ?MAKE_CONFIG_OPT(title), ?MAKE_CONFIG_OPT(description), ?MAKE_CONFIG_OPT(allow_change_subj), ?MAKE_CONFIG_OPT(allow_query_users), ?MAKE_CONFIG_OPT(allow_private_messages), ?MAKE_CONFIG_OPT(allow_private_messages_from_visitors), ?MAKE_CONFIG_OPT(allow_visitor_status), ?MAKE_CONFIG_OPT(allow_visitor_nickchange), ?MAKE_CONFIG_OPT(public), ?MAKE_CONFIG_OPT(public_list), ?MAKE_CONFIG_OPT(persistent), ?MAKE_CONFIG_OPT(moderated), ?MAKE_CONFIG_OPT(members_by_default), ?MAKE_CONFIG_OPT(members_only), ?MAKE_CONFIG_OPT(allow_user_invites), ?MAKE_CONFIG_OPT(password_protected), ?MAKE_CONFIG_OPT(captcha_protected), ?MAKE_CONFIG_OPT(password), ?MAKE_CONFIG_OPT(anonymous), ?MAKE_CONFIG_OPT(logging), ?MAKE_CONFIG_OPT(max_users), ?MAKE_CONFIG_OPT(allow_voice_requests), ?MAKE_CONFIG_OPT(voice_request_min_interval), {captcha_whitelist, ?SETS:to_list((StateData#state.config)#config.captcha_whitelist)}, {affiliations, ?DICT:to_list(StateData#state.affiliations)}, {subject, StateData#state.subject}, {subject_author, StateData#state.subject_author} ]. destroy_room(DEl, StateData) -> lists:foreach( fun({_LJID, Info}) -> Nick = Info#user.nick, ItemAttrs = [{"affiliation", "none"}, {"role", "none"}], Packet = {xmlelement, "presence", [{"type", "unavailable"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "item", ItemAttrs, []}, DEl]}]}, ejabberd_router:route( jlib:jid_replace_resource(StateData#state.jid, Nick), Info#user.jid, Packet) end, ?DICT:to_list(StateData#state.users)), case (StateData#state.config)#config.persistent of true -> (StateData#state.mod):forget_room( StateData#state.server_host, StateData#state.host, StateData#state.room); false -> ok end, {result, [], stop}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Disco -define(FEATURE(Var), {xmlelement, "feature", [{"var", Var}], []}). -define(CONFIG_OPT_TO_FEATURE(Opt, Fiftrue, Fiffalse), case Opt of true -> ?FEATURE(Fiftrue); false -> ?FEATURE(Fiffalse) end). process_iq_disco_info(_From, set, _Lang, _StateData) -> {error, ?ERR_NOT_ALLOWED}; process_iq_disco_info(_From, get, Lang, StateData) -> Config = StateData#state.config, {result, [{xmlelement, "identity", [{"category", "conference"}, {"type", "text"}, {"name", get_title(StateData)}], []}, {xmlelement, "feature", [{"var", ?NS_MUC}], []}, ?CONFIG_OPT_TO_FEATURE(Config#config.public, "muc_public", "muc_hidden"), ?CONFIG_OPT_TO_FEATURE(Config#config.persistent, "muc_persistent", "muc_temporary"), ?CONFIG_OPT_TO_FEATURE(Config#config.members_only, "muc_membersonly", "muc_open"), ?CONFIG_OPT_TO_FEATURE(Config#config.anonymous, "muc_semianonymous", "muc_nonanonymous"), ?CONFIG_OPT_TO_FEATURE(Config#config.moderated, "muc_moderated", "muc_unmoderated"), ?CONFIG_OPT_TO_FEATURE(Config#config.password_protected, "muc_passwordprotected", "muc_unsecured") ] ++ iq_disco_info_extras(Lang, StateData), StateData}. -define(RFIELDT(Type, Var, Val), {xmlelement, "field", [{"type", Type}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). -define(RFIELD(Label, Var, Val), {xmlelement, "field", [{"label", translate:translate(Lang, Label)}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). iq_disco_info_extras(Lang, StateData) -> Len = ?DICT:size(StateData#state.users), RoomDescription = (StateData#state.config)#config.description, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}], [?RFIELDT("hidden", "FORM_TYPE", "http://jabber.org/protocol/muc#roominfo"), ?RFIELD("Room description", "muc#roominfo_description", RoomDescription), ?RFIELD("Number of occupants", "muc#roominfo_occupants", integer_to_list(Len)) ]}]. process_iq_disco_items(_From, set, _Lang, _StateData) -> {error, ?ERR_NOT_ALLOWED}; process_iq_disco_items(From, get, _Lang, StateData) -> case (StateData#state.config)#config.public_list of true -> {result, get_mucroom_disco_items(StateData), StateData}; _ -> case is_occupant_or_admin(From, StateData) of true -> {result, get_mucroom_disco_items(StateData), StateData}; _ -> {error, ?ERR_FORBIDDEN} end end. process_iq_captcha(_From, get, _Lang, _SubEl, _StateData) -> {error, ?ERR_NOT_ALLOWED}; process_iq_captcha(_From, set, _Lang, SubEl, StateData) -> case ejabberd_captcha:process_reply(SubEl) of ok -> {result, [], StateData}; _ -> {error, ?ERR_NOT_ACCEPTABLE} end. get_title(StateData) -> case (StateData#state.config)#config.title of "" -> StateData#state.room; Name -> Name end. get_roomdesc_reply(JID, StateData, Tail) -> IsOccupantOrAdmin = is_occupant_or_admin(JID, StateData), if (StateData#state.config)#config.public or IsOccupantOrAdmin -> if (StateData#state.config)#config.public_list or IsOccupantOrAdmin -> {item, get_title(StateData) ++ Tail}; true -> {item, get_title(StateData)} end; true -> false end. get_roomdesc_tail(StateData, Lang) -> Desc = case (StateData#state.config)#config.public of true -> ""; _ -> translate:translate(Lang, "private, ") end, Len = ?DICT:fold(fun(_, _, Acc) -> Acc + 1 end, 0, StateData#state.users), " (" ++ Desc ++ integer_to_list(Len) ++ ")". get_mucroom_disco_items(StateData) -> lists:map( fun({_LJID, Info}) -> Nick = Info#user.nick, {xmlelement, "item", [{"jid", jlib:jid_to_string({StateData#state.room, StateData#state.host, Nick})}, {"name", Nick}], []} end, ?DICT:to_list(StateData#state.users)). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Voice request support is_voice_request(Els) -> lists:foldl( fun({xmlelement, "x", Attrs, _} = El, false) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_XDATA -> case jlib:parse_xdata_submit(El) of [_|_] = Fields -> case {lists:keysearch("FORM_TYPE", 1, Fields), lists:keysearch("muc#role", 1, Fields)} of {{value, {_, ["http://jabber.org/protocol/muc#request"]}}, {value, {_, ["participant"]}}} -> true; _ -> false end; _ -> false end; _ -> false end; (_, Acc) -> Acc end, false, Els). prepare_request_form(Requester, Nick, Lang) -> {xmlelement, "message", [{"type", "normal"}], [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "Voice request")}]}, {xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "Either approve or decline the voice request.")}]}, {xmlelement, "field", [{"var", "FORM_TYPE"}, {"type", "hidden"}], [{xmlelement, "value", [], [{xmlcdata, "http://jabber.org/protocol/muc#request"}]}]}, {xmlelement, "field", [{"var", "muc#role"}, {"type", "hidden"}], [{xmlelement, "value", [], [{xmlcdata, "participant"}]}]}, ?STRINGXFIELD("User JID", "muc#jid", jlib:jid_to_string(Requester)), ?STRINGXFIELD("Nickname", "muc#roomnick", Nick), ?BOOLXFIELD("Grant voice to this person?", "muc#request_allow", list_to_atom("false")) ]}]}. send_voice_request(From, StateData) -> Moderators = search_role(moderator, StateData), FromNick = find_nick_by_jid(From, StateData), lists:foreach( fun({_, User}) -> ejabberd_router:route( StateData#state.jid, User#user.jid, prepare_request_form(From, FromNick, "")) end, Moderators). is_voice_approvement(Els) -> lists:foldl( fun({xmlelement, "x", Attrs, _} = El, false) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_XDATA -> case jlib:parse_xdata_submit(El) of [_|_] = Fs -> case {lists:keysearch("FORM_TYPE", 1, Fs), lists:keysearch("muc#role", 1, Fs), lists:keysearch("muc#request_allow", 1, Fs)} of {{value, {_, ["http://jabber.org/protocol/muc#request"]}}, {value, {_, ["participant"]}}, {value, {_, [Flag]}}} when Flag == "true"; Flag == "1" -> true; _ -> false end; _ -> false end; _ -> false end; (_, Acc) -> Acc end, false, Els). extract_jid_from_voice_approvement(Els) -> lists:foldl( fun({xmlelement, "x", _, _} = El, error) -> Fields = case jlib:parse_xdata_submit(El) of invalid -> []; Res -> Res end, lists:foldl( fun({"muc#jid", [JIDStr]}, error) -> case jlib:string_to_jid(JIDStr) of error -> error; J -> {ok, J} end; (_, Acc) -> Acc end, error, Fields); (_, Acc) -> Acc end, error, Els). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Invitation support is_invitation(Els) -> lists:foldl( fun({xmlelement, "x", Attrs, _} = El, false) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_MUC_USER -> case xml:get_subtag(El, "invite") of false -> false; _ -> true end; _ -> false end; (_, Acc) -> Acc end, false, Els). check_invitation(From, Els, Lang, StateData) -> FAffiliation = get_affiliation(From, StateData), CanInvite = (StateData#state.config)#config.allow_user_invites orelse (FAffiliation == admin) orelse (FAffiliation == owner), InviteEl = case xml:remove_cdata(Els) of [{xmlelement, "x", _Attrs1, Els1} = XEl] -> case xml:get_tag_attr_s("xmlns", XEl) of ?NS_MUC_USER -> ok; _ -> throw({error, ?ERR_BAD_REQUEST}) end, case xml:remove_cdata(Els1) of [{xmlelement, "invite", _Attrs2, _Els2} = InviteEl1] -> InviteEl1; _ -> throw({error, ?ERR_BAD_REQUEST}) end; _ -> throw({error, ?ERR_BAD_REQUEST}) end, JID = case jlib:string_to_jid( xml:get_tag_attr_s("to", InviteEl)) of error -> throw({error, ?ERR_JID_MALFORMED}); JID1 -> JID1 end, case CanInvite of false -> throw({error, ?ERR_NOT_ALLOWED}); true -> Reason = xml:get_path_s( InviteEl, [{elem, "reason"}, cdata]), ContinueEl = case xml:get_path_s( InviteEl, [{elem, "continue"}]) of [] -> []; Continue1 -> [Continue1] end, IEl = [{xmlelement, "invite", [{"from", jlib:jid_to_string(From)}], [{xmlelement, "reason", [], [{xmlcdata, Reason}]}] ++ ContinueEl}], PasswdEl = case (StateData#state.config)#config.password_protected of true -> [{xmlelement, "password", [], [{xmlcdata, (StateData#state.config)#config.password}]}]; _ -> [] end, Body = {xmlelement, "body", [], [{xmlcdata, lists:flatten( io_lib:format( translate:translate( Lang, "~s invites you to the room ~s"), [jlib:jid_to_string(From), jlib:jid_to_string({StateData#state.room, StateData#state.host, ""}) ])) ++ case (StateData#state.config)#config.password_protected of true -> ", " ++ translate:translate(Lang, "the password is") ++ " '" ++ (StateData#state.config)#config.password ++ "'"; _ -> "" end ++ case Reason of "" -> ""; _ -> " (" ++ Reason ++ ") " end }]}, Msg = {xmlelement, "message", [{"type", "normal"}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], IEl ++ PasswdEl}, {xmlelement, "x", [{"xmlns", ?NS_XCONFERENCE}, {"jid", jlib:jid_to_string( {StateData#state.room, StateData#state.host, ""})}], [{xmlcdata, Reason}]}, Body]}, ejabberd_router:route(StateData#state.jid, JID, Msg), JID end. %% Handle a message sent to the room by a non-participant. %% If it is a decline, send to the inviter. %% Otherwise, an error message is sent to the sender. handle_roommessage_from_nonparticipant(Packet, Lang, StateData, From) -> case catch check_decline_invitation(Packet) of {true, Decline_data} -> send_decline_invitation(Decline_data, StateData#state.jid, From); _ -> send_error_only_occupants(Packet, Lang, StateData#state.jid, From) end. %% Check in the packet is a decline. %% If so, also returns the splitted packet. %% This function must be catched, %% because it crashes when the packet is not a decline message. check_decline_invitation(Packet) -> {xmlelement, "message", _, _} = Packet, XEl = xml:get_subtag(Packet, "x"), ?NS_MUC_USER = xml:get_tag_attr_s("xmlns", XEl), DEl = xml:get_subtag(XEl, "decline"), ToString = xml:get_tag_attr_s("to", DEl), ToJID = jlib:string_to_jid(ToString), {true, {Packet, XEl, DEl, ToJID}}. %% Send the decline to the inviter user. %% The original stanza must be slightly modified. send_decline_invitation({Packet, XEl, DEl, ToJID}, RoomJID, FromJID) -> FromString = jlib:jid_to_string(jlib:jid_remove_resource(FromJID)), {xmlelement, "decline", DAttrs, DEls} = DEl, DAttrs2 = lists:keydelete("to", 1, DAttrs), DAttrs3 = [{"from", FromString} | DAttrs2], DEl2 = {xmlelement, "decline", DAttrs3, DEls}, XEl2 = replace_subelement(XEl, DEl2), Packet2 = replace_subelement(Packet, XEl2), ejabberd_router:route(RoomJID, ToJID, Packet2). %% Given an element and a new subelement, %% replace the instance of the subelement in element with the new subelement. replace_subelement({xmlelement, Name, Attrs, SubEls}, NewSubEl) -> {_, NameNewSubEl, _, _} = NewSubEl, SubEls2 = lists:keyreplace(NameNewSubEl, 2, SubEls, NewSubEl), {xmlelement, Name, Attrs, SubEls2}. send_error_only_occupants(Packet, Lang, RoomJID, From) -> ErrText = "Only occupants are allowed to send messages to the conference", Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)), ejabberd_router:route(RoomJID, From, Err). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Logging add_to_log(Type, Data, StateData) when Type == roomconfig_change_disabledlogging -> %% When logging is disabled, the config change message must be logged: mod_muc_log:add_to_log( StateData#state.server_host, roomconfig_change, Data, StateData#state.jid, make_opts(StateData)); add_to_log(Type, Data, StateData) -> case (StateData#state.config)#config.logging of true -> mod_muc_log:add_to_log( StateData#state.server_host, Type, Data, StateData#state.jid, make_opts(StateData)); false -> ok end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Users number checking tab_add_online_user(JID, StateData) -> {LUser, LServer, LResource} = jlib:jid_tolower(JID), US = {LUser, LServer}, Room = StateData#state.room, Host = StateData#state.host, catch ets:insert( muc_online_users, #muc_online_users{us = US, resource = LResource, room = Room, host = Host}). tab_remove_online_user(JID, StateData) -> {LUser, LServer, LResource} = jlib:jid_tolower(JID), US = {LUser, LServer}, Room = StateData#state.room, Host = StateData#state.host, catch ets:delete_object( muc_online_users, #muc_online_users{us = US, resource = LResource, room = Room, host = Host}). tab_count_user(JID) -> {LUser, LServer, _} = jlib:jid_tolower(JID), US = {LUser, LServer}, case catch ets:select( muc_online_users, [{#muc_online_users{us = US, _ = '_'}, [], [[]]}]) of Res when is_list(Res) -> length(Res); _ -> 0 end. element_size(El) -> size(xml:element_to_binary(El)). ejabberd-2.1.11/src/mod_muc/mod_muc_log.erl0000664000000000000000000011714012240230175015424 0ustar %%%---------------------------------------------------------------------- %%% File : mod_muc_log.erl %%% Author : Badlop@process-one.net %%% Purpose : MUC room logging %%% Created : 12 Mar 2006 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_muc_log). -author('badlop@process-one.net'). -behaviour(gen_server). -behaviour(gen_mod). %% API -export([start_link/2, start/2, stop/1, check_access_log/2, add_to_log/5]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_muc_room.hrl"). %% Copied from mod_muc/mod_muc.erl -record(muc_online_room, {name_host, pid}). -define(T(Text), translate:translate(Lang, Text)). -define(PROCNAME, ejabberd_mod_muc_log). -record(room, {jid, title, subject, subject_author, config}). -record(logstate, {host, out_dir, dir_type, dir_name, file_format, css_file, access, lang, timezone, spam_prevention, top_link}). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, temporary, 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:call(Proc, stop), supervisor:delete_child(ejabberd_sup, Proc). add_to_log(Host, Type, Data, Room, Opts) -> gen_server:cast(get_proc_name(Host), {add_to_log, Type, Data, Room, Opts}). check_access_log(Host, From) -> case catch gen_server:call(get_proc_name(Host), {check_access_log, Host, From}) of {'EXIT', _Error} -> deny; Res -> Res end. %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([Host, Opts]) -> OutDir = gen_mod:get_opt(outdir, Opts, "www/muc"), DirType = gen_mod:get_opt(dirtype, Opts, subdirs), DirName = gen_mod:get_opt(dirname, Opts, room_jid), FileFormat = gen_mod:get_opt(file_format, Opts, html), % Allowed values: html|plaintext CSSFile = gen_mod:get_opt(cssfile, Opts, false), AccessLog = gen_mod:get_opt(access_log, Opts, muc_admin), Timezone = gen_mod:get_opt(timezone, Opts, local), Top_link = gen_mod:get_opt(top_link, Opts, {"/", "Home"}), NoFollow = gen_mod:get_opt(spam_prevention, Opts, true), Lang = case ejabberd_config:get_local_option({language, Host}) of undefined -> case ejabberd_config:get_global_option(language) of undefined -> "en"; L -> L end; L -> L end, {ok, #logstate{host = Host, out_dir = OutDir, dir_type = DirType, dir_name = DirName, file_format = FileFormat, css_file = CSSFile, access = AccessLog, lang = Lang, timezone = Timezone, spam_prevention = NoFollow, top_link = Top_link}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call({check_access_log, ServerHost, FromJID}, _From, State) -> Reply = acl:match_rule(ServerHost, State#logstate.access, FromJID), {reply, Reply, State}; handle_call(stop, _From, State) -> {stop, normal, ok, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast({add_to_log, Type, Data, Room, Opts}, State) -> case catch add_to_log2(Type, Data, Room, Opts, State) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); _ -> ok end, {noreply, State}; handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- add_to_log2(text, {Nick, Packet}, Room, Opts, State) -> case {xml:get_subtag(Packet, "subject"), xml:get_subtag(Packet, "body")} of {false, false} -> ok; {false, SubEl} -> Message = {body, xml:get_tag_cdata(SubEl)}, add_message_to_log(Nick, Message, Room, Opts, State); {SubEl, _} -> Message = {subject, xml:get_tag_cdata(SubEl)}, add_message_to_log(Nick, Message, Room, Opts, State) end; add_to_log2(roomconfig_change, _Occupants, Room, Opts, State) -> add_message_to_log("", roomconfig_change, Room, Opts, State); add_to_log2(roomconfig_change_enabledlogging, Occupants, Room, Opts, State) -> add_message_to_log("", {roomconfig_change, Occupants}, Room, Opts, State); add_to_log2(room_existence, NewStatus, Room, Opts, State) -> add_message_to_log("", {room_existence, NewStatus}, Room, Opts, State); add_to_log2(nickchange, {OldNick, NewNick}, Room, Opts, State) -> add_message_to_log(NewNick, {nickchange, OldNick}, Room, Opts, State); add_to_log2(join, Nick, Room, Opts, State) -> add_message_to_log(Nick, join, Room, Opts, State); add_to_log2(leave, {Nick, Reason}, Room, Opts, State) -> case Reason of "" -> add_message_to_log(Nick, leave, Room, Opts, State); _ -> add_message_to_log(Nick, {leave, Reason}, Room, Opts, State) end; add_to_log2(kickban, {Nick, Reason, Code}, Room, Opts, State) -> add_message_to_log(Nick, {kickban, Code, Reason}, Room, Opts, State). %%---------------------------------------------------------------------- %% Core build_filename_string(TimeStamp, OutDir, RoomJID, DirType, DirName, FileFormat) -> {{Year, Month, Day}, _Time} = TimeStamp, %% Directory and file names {Dir, Filename, Rel} = case DirType of subdirs -> SYear = lists:flatten(io_lib:format("~4..0w", [Year])), SMonth = lists:flatten(io_lib:format("~2..0w", [Month])), SDay = lists:flatten(io_lib:format("~2..0w", [Day])), {filename:join(SYear, SMonth), SDay, "../.."}; plain -> Date = lists:flatten( io_lib:format("~4..0w-~2..0w-~2..0w", [Year, Month, Day])), {"", Date, "."} end, RoomString = case DirName of room_jid -> RoomJID; room_name -> get_room_name(RoomJID) end, Extension = case FileFormat of html -> ".html"; plaintext -> ".txt" end, Fd = filename:join([OutDir, RoomString, Dir]), Fn = filename:join([Fd, Filename ++ Extension]), Fnrel = filename:join([Rel, Dir, Filename ++ Extension]), {Fd, Fn, Fnrel}. get_room_name(RoomJID) -> JID = jlib:string_to_jid(RoomJID), JID#jid.user. %% calculate day before get_timestamp_daydiff(TimeStamp, Daydiff) -> {Date1, HMS} = TimeStamp, Date2 = calendar:gregorian_days_to_date( calendar:date_to_gregorian_days(Date1) + Daydiff), {Date2, HMS}. %% Try to close the previous day log, if it exists close_previous_log(Fn, Images_dir, FileFormat) -> case file:read_file_info(Fn) of {ok, _} -> {ok, F} = file:open(Fn, [append]), write_last_lines(F, Images_dir, FileFormat), file:close(F); _ -> ok end. write_last_lines(_, _, plaintext) -> ok; write_last_lines(F, Images_dir, _FileFormat) -> %%fw(F, "

io??0'&X,EŎf{Z#]OKJ\ɶYsսUڢ^>ϋ=A>{ZaiAs~>9xONIܭ{yntom CWc DḺc?Ʈ߿ȱ\Gjz ԰U:z[FSV?k*9?QZJe,zl$'aZɢ4K1oʞQ"/<pÅN|DC5/ W? +MXb:]3KGJI'_u$γVP^p\/ZvUеu@H){}N{9D R4E/I*/q4|4_3Ss+рbc+Qe-pǍuWhX9O{=[kQwG3:ޘX6҄_-g/{s/m}4.ɦyʶp~(2W`ZȟIC c3/Vju9 rmZ/:#fFBAi!OY $ E}O=k2rQ1;Yafݞ8,ڃCi e'7?Nd7/J9yiZ"DR著5 +O$^.=\L5ڜVt%c! suc̗s\.x|RxsϙrW[Nŭ\{Bc^\i8Ai; ĢU^,}p?~ j5 rYt<,Ղ5GEZwZWt H'%t;ʬp/!pyz R^OqrjDh1iHJQ'?.& -r)_oT-d}Z^ ՈT92#ghps;v ܮ6+<“IouܥذzQg /TU+Wr/6l]Pj[_qGYBTHGvvbdNܥ[.@|C̠(uAע&1{QMܷSYjx%6qHү|x5s+ 4$y%`ІO_+qjsۜ ,U./a>ȣwd(\|pRYL>x,rF=a^E1Go{ &fŗ y/D£<ғ܌D5☛K7Xcn:fLS:@>K,Vt/tnUcihܐUA*òD= s9NGTHYN{P4(d:$HϻJpyvXcuyDRt<3o9| yGɼ(aޜqky.?9{?”&}'Ӥ\_&M?G ?ܜFs܌'" ae?2dw%R:[Q8ûO,XBf<5fsQ;J/wR sU7N/5X}Oo(w {x=ylnXM8Q_DVw&:㔛X%R#^*]*"AP:+1PU?͖D?rcf#eg<DԵKK=_Nݰˇ%sQ[;쓩>*Ͳ)>T>zt눙aw&c38=wڇgEWn1W ~O*8}ᭀwuyOD ο,N= Pؗpzg#I3+C µ6+96ẒneJ2m2qul'5r3];/S;u34r/ړHеӣWltl+*GhdGxq:*qȓH&eusx9p=fl=wU;2|Q-$v$JLӷs 5 飘އUO,ow>(d/wxki[F/bXZBQ/볥21uX4P)B!7=Lf9X*\iZSsIo? GdzJݝ/!pT1 ]z~B_t9NT#l Z1Ԟ)Z4*bm?SΈТQN8---Dez#-!S$*3sT?dvLG c*uhdQI ],2fcnzෙOrތ"ܯ3 =JW{Q> Pv]\!B[c{TմWce{ݗSH\BetQWͲ]@:::uG8.*MH$Z<ӱd58>:P57\.,Ͷ)'܉NhV۷Mts1cv)@K:& W~]yGq[Dt1056ޯ{|A~+>@=8E @?@@` NQ P As0xXQ p)" C'`"`B?5!85> ((&OQ%h@~r*33p?0@qT`x8؀b -4x- ~ ]0;~@@ `R0p{wz@I%ŭ0V$l~o@o:-i<Ŧ"mn"ܦ[mI@n~Amx!"} n-w+nK{4 Q2WPPS}2$b\~Ml> 52y8![ mbHa<>8HH((ZU)$v[nAY#6 u \gH¶S-(jRBn}W y!8R4Ƕ҆} j_(b؊9\gl"9xUⷍoFld7r'≠ 8,'*ơխָ@ъ[!cAgk#o3ѿ }(bsj5vd(ne;ͨH$ [n5aO>ao~84эEo}DUPSHGo2~E{P5 U}nqm86Z?vk=Ѹy}[G oz6>D+[^urܭT;|"*7(`ۓ}mOwvhg2Kw]ģsDFgȡX@ 'ua5@ɃG@#(0 m1`=9;;9CZ5PQ )(uB/z:$ AXCJn,R @{IHG~F *@cvIrP4_瑰hhn#J!YRRHiTnzK)m(/xv]pp;G;NY. dmL)D(r( `VN(8E4XSeOWN*@a X$8Rˁ}he4_ @,Yn;;k :V@JA jETIѽՃ݅ mN>D6řHrYvƀ%ŀ5#22V ~kd`6] M` /A@r'< vT?;\5? bU,x?UٸP;7^'2Ey" o, fo,#OfOX,F͊ CÀĖX(p§/N^ܿ]%'@I)( SY ? "^-HH Cpx?#X+@y$+PEج.#(i% (II-Q 4UO8 "u\YwkE<\[&Aau~4OxR|8$H|چ;H @6mw:(5<(Њ^=Or p H?>1AByG `t VH( 8eQ$-!n{Y;9m`[\ vBU۬4l X0% f^[r^[?dŁ V eIp2V٠+@xawSAq"wÐX,,K\`@@k吐.3 u :(pH]sb$NgHk I {XԦy9<@hhB[Nk$ԋUvIQBG@`4_ zvbzE m]H0rC(lT#!` _n+4xw[ldME,\ء~?AZS+(0$?&-`?7=8_|g[B\޲so,a֑$9^z/=2ʼns.~šS_9 J_ݻ{Z O.9̩&6?^|f-W}2U}ԩs>ԧeXm-~m T$~/A}=(^aߋ_> }a(s{K3T&~u56K#tPhǬ K293:gUSe40CiTRrIJagd*}XDUSC=5M{ИTuKQ4C=K7 a$UZ|ץ4BUCE~^J!hMɆ( sq9 wfӈ5R,1قī-țV#js>Q_tPf7d1B!bc"ձN݊0/"6zrq˔o \mKiO 2k}z }}1*{KԱI$vL??:Nm\?#dQ-}+Lg4m3ˣ4[K3?$k8AoN\ش@,!t>ҤjRzLnvam=oT4 *O\͉zVl 6u;ئti@}u%9~끏 uE'AsA 4WPl|tp#SUa6l%R$UFH h,.ظHWIDIzUBkm۲J5.A%'0>JCF_]$$gA3Xv}6 ֶՁғ$i&MƖg>L|g)CgxIhtv ̳f`FOUC`< :4j^w&Oiڷ,8Mu):aLD6 0l}4LdvZ@Vf0cHwdeDŽ [sٱUXE紥DQV_ஶYrtY+!Ɇב8B9mU>4렜ڞE}Ԗ,Vaec.,ah 'g^EdT\~^Zm{% /*ǯa~ȍ`6g1~b~̶ǒCc/ǧ?>`<4xϏ'Ȃ~aԩ ͤl*K`76$&l,XZ'_T3]n+FM$׾=2-/Ӽ)N `n9gmʍ`Z¬ށi>$"Fk΂@E6t!h7(MYs^T#e5Gg5z!o=$Һ+ďj5qM)6tK7Ka.k-MIwzU} Lr5v[{-k+R>0z-DGG `A`>EMiV嚁YtEfq|I:1XѐVY)XNvcmRXY)mԔVA `MtXu"`Ia:g+܉#^iv@"ʉA/uoR Q\2{>Z2-;тz=iML3yKDHW':QIIFAe|ˮyC9 H# 촎Er"dױ676 U;nJiKh15m4DmmfўY{mZG'!N=:`7wAmѸWgO(ت}Ԡ y49A ~=w ;~U CFl)D"n)ۖGEN\4ګY[$¬ yyWW`fE'cZdZ3J 7vQ=a$<г%ibvzNBe$q/V`hI氞ɇzHL`IMM4ZćaIӟtM8Y^J$Yb |j{`"'f4) e$~_ps_IRI%`1Fb(;)XUtMf-&2@U2i.Mwʆ)7JT9"LBOd;B,<"`ȂFg0`rƔ%V0q MI@ي(XÍ)9Zc4%7(rT C)^\KX$Z%~Pcص 8XRI:pkBdh+\rAgиe>YV!Dh̄Tme:-ƙR*bf 4uI&DgƑ1h7x,^HX_#[HU+-2򽼄,lP3k:NMDfK1EĠ/?N6r;/]2)]:-zĂY2sјҔANwx͸𾤉mrkȹ^H%f y:{G:r^;9 3(a"¬x,*R_94_u @; ؞V %,zqHŎPp;O,?<9X H;>a h3 |JΓhqSࣛ~!}ǐ?RR^-Pa0g%aF ˀcTOi-( mk dLBi~ GLJ1[T&J),pQ}V3ٲj IB(rw<0]Bdy#0oa $d}L 6q^+0bz}o@:.qVMFRks ܎AnAŤ 6`tXJA0kj)h!XJAphJ04u]2i0!:ʔG$Ū/~km@gpJ'%iV;̀Hvq%h3 X 0:`6:[*R@Bj[K P0F2~whU;X ס3F 1sϦFt?Mg6*iܞԖ)sڈkMeJ#ught# 46(0Xh62וc480HI'Ag91וlZDYP޶D/9Z9١Mk`"􎬕 )z H 7G趬% [D~dsratR6ըDy:| ErDIQpPw(i- KzKTrM;$BǺM52|X'LicbUX)twrVcD#2%%HVRh50|v\RJ XXBa{( [UmWYnF ^3OWYJ:V[.'ѼYݶ) 3-~MGt)X%A "itzI tX%D|{ NoR!%!@YJ^H8+ d%ܖA#N#=JW)9?O#RtBwƤL]7Љ+{}1L|ks5Ϭ"I RPB0_~䏧O8>p+efqYCQ ]k'X|{7# &5!X M:(\Ȓ7AK+7-~Ow$-Dls\-1>l-s#υ d(,@$j^AgI:_86,Tp$KY{\̡u 9AKYpN2q7(jocn-Y:V?bo,/FObb,t" ZFK1K#%UۥwӭRS䄻C,RlL#Bg<7@kh>3_,he F!o~`3Z S<jr:rm89PX\JfCA2x'4FGJ0g;o FIM_3ncϦÍ'oYsc (B2UǛZA\=7q /)rTE"I_؀r^Gs%@}= ZAc+]_UTr;v5Ц[$S +JwM=! 9$z5.N~AĉJ $P( US/|ٝG=zW_isK/||>^::f{Byϝ<ZP!)xV@&&Bծ|Lʲ@*WW8܌Sۏj@\c wbQ3rnf4Z (xsQH` ߊq*9{90qHe5_ endstream endrCrCrCb76*ms۸_L{L /t2Sr5MC'I)xHI\,R$EN~X,vϾfM~<{y}v:D,BOW3%$Ђ)MS"y>3U\Jf28_RCM~5bz_x\ʸN|v!Tj""ogDЛ?dbs7YۛTNnDѺlog;=#g #w߳e=d# xT.:dit(Oӯ?gk<>vfWPF}RphArK{h{ tdSMc:m alwUf běH4p3zu'w[&_bWewX"^^R̘r|fqUv=$Wu;bjHS|m .ROWBIЁdJ@"%@ZEGc 42+`$20חX(6 s0h1zbn,pm$q^?6]m`v̂p?DAuTSiDu S6ۢ\:sc?2bCkfLK+^xSjQ(qTՈ|x go?;lyP/=ϛ^HO_v4*L()+79 IJ`u~xS8cn"8orbYl4mxΫdQ&[җ@4o!mj-vetQS/%lsj4, %[][iȇ?O "p5 E,9ߑ""dy\Ǯ[FD:7nate!$lJD̒ Mq>$pe&6xнJKJEyG;Kwe2( h4dU&,)H ev%l% aC{IEPWjbQ쬊R7h7SL~aq`_jH1<떐W}.[?5(a‑˯9ʅ0p!|6rACKNRqF6quT0UQn;G'8Ȥd㮭FuVneR-`>̶tqMr^UexP-݃x<`!&rc'BCJԁ.?#َ^v{Vvm-[*OeS!]ڟ&2j:h:Ul{s0Lr~auW7R!<0jhQ3wD ;}:<ƚ F7ߡ{чkS0KLVKV7q5 j"4;'85{{p<ՆY)>`A0{8bmP"7I0\6!ء,7cEnL|u5%+v{8J-2 )rm& V0;OmhPĀ571AB|?P)ڎ>˙(C[T=@(NKXڂtA.8dH<1%oy^?E; 6DمٯM7_m|3}.o`[K'9PӔtw*ؼs;jCǕmӍ|P$=+ "{_<#)&,:^WX# zƼ6"ES-:% Qئ)Sxv>.PelP_Ŷ k,#'\E#w5K"WYUزB~|XG.xx9L\}3c'W']L'< REJ?"[ac!NQ0/b|m%[C)yܿi]f0UuZE3R#8i;F ^H8GТP~ h*a9DCr`Z`v}]痗uQdDҤ^g\כ\-:YJ'8e$N83)x< IJGk]R7EFb#Ax;j!SM /~[\|zA(%1r{q}z9lB"d 4&KH}QJd<$sIbJԂPnsb R3Դr*&GBфXM\+c"\X]jUsSH^ḱŦhgoTz,fg߻5vk8mJJ$ɋ#Ԛ jp,SP:``R_ʘӁ#*ȗ^6u=Y:9>Lʉ=`^Zvus Gz gx!`!a2Bf˥j۲^T&NWLN8@70۷:qx6[XoTPbm֑Y x9e}(GwMr+ NZWZUw;,}Uy 27x&CH~̋!X<8McNr .X^rN!7O k)봕eו~¶nV>-8nř( (Ձ^YS$8 +abQJ!:Vv?[MݕJg*s0I>UdStt K8v*q^Hރ..mc~uut#R8_$k,M^5FHD4@6F7MZ)=RruԨnTj#~uc] ngNUΒ8njK/ c7hokm/6@ 37 K&R?[$mFp1Ku:92cP綎:{mےRgM WWWZXr|=Q}ٝɋBQ/41DҰ i74.Nᤔ?b)ql^ -vDf`O-08 .;Twڅ^>V:Tǀ(J*ٙqAS;JqE@B-J]A6dꂶ"v P1ԁPj;!s[F$a[kY}879@i3Ϛp8mxE: 6 "%F[ܚ*bi8Yj~*MS< D@]ichAIkm8""Jz}F@ Kw'8Y'a$>,5\?w0#Am9(0.MK]؃wV|S|\?TK)xM&~ds-fwa{.tM,cfӥ ˯g 3|~̑cL4ϗ3ɦۖmVTznsrI z&>/^L P%`36[^\RG4{7'~n[o8I:(scǙA#( +⩨4&ŝ5k2.o2H)OA07"k+~LU?Q':[8tU/?c&}8 endst>991Q(X[oܶ~P xҢHRNr=8- WWͮ%俟H+ e 9f|󽟎~X>D$QyKHLoygJ'A2C ZrP,k7Vfw_꫶J,D"ly= cI孶G^s<_$`5Jp?G*l/!3q'BuXR$aH+gk:-0g|3^9Mw1?N:`ޮf2?ꃭ>}?SEx*74$BMu]Ho)p1> Iњo4H?$bSf(.P qlHQ#>F .g5VaL,"%Xz`>r#Еc} =K <4TiQ0fe:mHtխp:Ya[ی%KYp5Mb.Q\6r:bt"MV$G͗eua]JvO-Ac,),ֵ+e0WZ yCSyֻlw]+ _[jVaHyiܯb wpu'ChVWџƋDbTgTQ"H""%Ǩ{|΃X $-}B86 uV 쬢nuA0Q׊? uֱ3|鑏;byAM-5k-^Q{?&:)p`;4L$" HQYclr#!ӇkRH:lhI/Σgu_! {nw+nv$i8-_P!$$勦b܍D9_['vnB?'p ǣ"#Ve[ն3ciհun29Ÿs(BA@}fnl5Xu7T*=n|F+r0Z]0Rdpg/O~.K ;AĔ;C^\@1sӠ t(4\8zlջs!{!¨ƄSw$0,`CNؤ%f?@'d|ñٗ܉KA<犙=OKf0Q]n}Te0 UJrIoၡ} 3׸$`QmG7[aJkkWg*h-sDrL}4Uom]730 bgnҊ&nܤ| M0ut󫶢 *8S,ZWq^j|.jtn^FND`]n ɀ,X>pRۼFAy)g@CgeE׏nG汞c/bG#brS`G,~ OED cQ)`[nYGS² G}?E%5˽ ~9G*&v (k(xu@78iJm3q-IhZ=8T ۸cis?UӦ()v䮲~7+pPA2$EqH+1ç/Y><+ۤ+2=jwt8dyu[nQD}0~LW^x:_ '"~2 .5acСz{|]W57F_4;kUKhf/S M#7}0Ki_RȐr| SEI0=v`C{2F I(T1`׊O$"Glw;:7-j̯7v>5Ժn1ׂ71& mO^WG82.594 475.438 495.18/7HW331.805 371.188 344 (p- H84.691JBW+XKo6WT"skwE]C4H[Օ%G@%nz25j曡ipOwUpq0 ,Њ86< UA}i$ƧeݦKl-_AHzOXhiƖrV!]HrWIX<&]?g4B"EvX)O7 Z! (ev0*Luv{1$3|ʓ>N$ kߴٳgOrUdVl,ڈc*} v9u^B K,uӺ̹ `͑i UM1#y1eazSOTegNҴ(93nֵ{zvaQ5-7Ǽ]l!1bt #zhSr&|pH M8\`^V͒aZbϘ̜]',l+'Y7`udxjI @xM,B{c(0ӡM!(o$&b@(]_Cbj[ppٿ ! w %Ͳ񏀔W(z^h׭Wrૄ17.yXfO-sb\4*=$+1!PqTb/F4\m^MaV71 J"jIukB /?@-Tt-1(.^"(!*eT<;4baqb+m9TWݸeu5}a U}D>c< r=Uߛ=`UdZo)O`C]U*}bZBvrB^N2>?&6V~ b9`E͆z2pe@ xL/R{ }ÞhVyN4)4$@f,VA ?FP;~!=03+M gf͑984j6{H/RrG#.Mx~Z}:Wz5@r[nKxя6[O'("Jw>4- <0133@Jl:NXvHs,-6̈́p %o`$Mҿ>.2=uxnvoYf~ OrwV`i I5Ȩq◲r>y(vP+a % =t^`/B;-6O`Kw~h0 ~ :.(U/3'ҿL3nuncTZ6^4!H_xZUsWS[X"/5Cxo8vœr\2/u#lj(V[sp5tTs knh$ D߽]zOTἿ[ke(71:'Rd]G'xأd>C8 >-Q F/ezYEMZGce(GZ!J$aíevXf4"-DHo-I3;6%Y$9Ԗnqpۧ7fnI#wFҝ0_|Ȁ0%"q-o큍 G̶=d؃͒h5v5Mլm2vtra~I#u\2EA9hEzChN"4Ⱦ9WYo;"jȻvR̥IO7lS$~| ߡ}_[lcHgG S8O5, ޮMi`5em-\m @SwFݪX(u3)j(P UT iԼ,}wMZ5qEcꀷm7U߻^7>Kd2> OojxyhgP%em\MTZ.W ET bK@817)ck4 ב,4? JPjI1k;F’qht8KUupiҸq[4Ft0WIMyŦ_+=3n$=9[%T]btr#ŭy6x 1 ;C,`XߝG׿;16.563 336.827 329!( #V92.653 129.024 305.24!09C762Q)ksF_BX4@C^:Nq3x2=ZJT8۽w_HYv/D`ޥ'j?\\}<̓(ܬ&Z$M|rd6$Q|{M6at&7d PPeG]wvfdȱ MxlKDx{s˅%5GJ,L,vod NThlrOI丱p %WC6 \qW<#u 3„d= g#2ݹmݮ9s)=\0j.g8'³l IP{7&:`EiIwgYj^V|@+Z-=c6mUl FN8sxv/]髢+ cLaAQv6*UPQnlR%/G} r߂Z:$@HU!7ԐvtI9̰€Wbψe:9f88.)kj4P|⺦7$g]: IW`/; BzH[Dr08%ohkvEȪx z~][Hx R9f°\R7Y YBQ 5Մ*_K(@&=}Y(G4+Edgx 1mfIBӮy=C$v dI1Vg2H!J?IK/jGj[#H"g2Zq]1LnYOY8knfBȢ1Tj 8p(9o&e5V/2Xu~ ǝ`U ǩ,Re2_[W3YI>ٱN i|1!7ZJRZ-[-)AYRu/ȭPT[1hC* fNڢ>lv۹]Ub.uG!#b!"iu?:B<l(_GYet8@ǿG L5%FFE:(惖! }} u(3TTyY@BrK$NM\]߮WPYբ*`NitĦ6fPդ@[]8FjeineR=88v ^V4 ?VaQ׎Nv.1!-Nk:JrX/׺'J  bry &Qb|{ 8i9mAj*pOv(Β񏮬ר{xXd}vu23ֆܬ述Eg-h}W b57{TUIx7ɳvWYm`Մw^ʮ_f/`RF;Q)y3Ut}2_V3 A&$mܥ;kc׌1vJaꂨ)a"|܃]{X7ARS&)_MrdnSAA}ļ[@LR7,(-2wWQqpyЬYs5Z"nǛky7^o`WD8۲\ХHỴW&v&.'뺻Vm+j<=VC&]~RU;eB`ڃlk=a)d4H(lv)cSyFAxzTK:XBļ\= xߖyOO\ W+rPYyrB4u퇶Fid4/4wv2x7L1iTG3h!!v"le, uХZ :cH>E0r̢qaWPOaaםr('PI(J%jJ0;Jn!0fOEiC4c~z@A ؂G{ F-pG KC6ˑSPZKCGQ8H~qqbHT 5M] !6G`,,'w PHt5i;4'h M;$xzY&; $ 1))> Y@C%bu$~)HO',!֗\Pog A_2ge$ >y0j2Jm?b=ݦM˪" ޑ\7K14lKj}wycb˭/;n̯Q~)n|ȼax'%KSpH%o-!\!*0f̛f`8&f0ثgv{k[T 2ݞeJΟFWۡ Fxg6%rq|t;q$y8vmmh A<$ U[,Dc4]WmV!^D`<:C5ĝh=\KeXd1Qʨ1zUF&SzZHBCu(#hW]x45WuW?oѵ7#ºꊹ_zOh {-ϰbQڨ(Td /8=[ZȈX=ĝ'"2\oi "Z"ncQ@фP!RAΰ_^9t2P򩜭(w*7;U:[/=ߑ/Şg0A:ξh^EtήO['^ !@L|41B.zwj拏Eldngh;w(>YzUep"gahtu]V 0|BZt&bI83#^ɣ/",Myls"Cf*:,R\,=KM./.ju{spioHXq&_Ig527.97 362.179 540.56/X261.979 219.296 273.93L,80.577976D)V_o6 ϧЂpF,ۮ\W8xs̲-|Iڭ}^l("A[DOǁ$ԧ( \y1ZehbA@Y]_|;uq2eb`@%$;Lm܂GʾtdUg?fϨD<#Pl}CP׈`/PkTȣb@~{}2 ap]Lb(aPnƏn8׋%cPpC%v&%\URMqgU}Xɝ$MES.б2sy9rQ<%hG^IZ/}mȮɫm!613?MJqXyi&3ggҡ1ƔcH/~_=ݝ/`;. ,ݥR.yrIsc$|ݡ=u٫û"k .]Fֽ`x:EKL^Qyv>e|ytZRӘN.WU㹮֋f*K/l&$X.2o]hZ=xRs /xmuu9 Ѧ*T%[J߫# 퀼Ej.)i]Hjo)[<泂x-H5HF'cyKLjfd+T z sה^%E^d?\* iHc%S1Xւ:NTv2nU?pR7(1qE*VkۦZ7=cbI W/1%λB PF$Re>W闚+EluXT_ Н L0 Hw #-% "RRt HK;z9s͹Zk}s:gGl^XqYtsqcU cV; 'S``B+Wp+psx(k^VR~]V7ﲋ8xӈ{Id>S\\x죩gRqpG ofF.֗̌/RrxSō|Q?U#]?>bcbBljݗ/WXҏ'lO,)S6ce3o~NY>~(t7&H|A hN=XB_ZBDmWW`,l+!tt%ˤoZ]`9ZqmyAعS#p2Y\/ܧh? 0S52v&6ܢ:6v-8dT^LivHn7PBu:|CarbQIK_n|UCO=WsBgPswbWFS?MM(C% jW\'|]_K0&X[h5w9ddswBRm]m)䐲__dgq[3G`/ީhMOE)bEj7Zި֛ m`WJWTΙ:y7>w~Orhֈ⸻>}#Ԕ$Uzŵp 8H[gaH 3)۰Kxl6UJ{a8Hd-]Jd_4qN_1׸Bvtyj-Q[Úh}Wd)=Tnn_[Z- ;^ CtDUN5b T0rs|9 p-͛_lL0r8/*&9O~._ d8ci-?0#ܹϳbeRWY|>f0Acq鶆RFĭF֢UאLmx .Ldp2:z<Y9|kb'썁GVu`%v< Gen>bmL@/ sIzOV 'G xCNRͧƹ|yo^Q wZ췯k>sbkO^ɪw$yq\%J[Ay=\^C|"IE/_;IEL֮,ÊZ4 m W3?vH9Ba{əI^A7حԶu3X#M#8DTV6%80 mU-< B]?2o?n^0%H`: Bu%}5Dg;M(N9!mQ˝3Yq$ry?'Iݑep* ]<,.ĜRH+;/VL02>{D KJ`?6T% F(XfiTh~^ ѺƇysNEHwh"I~?)-1K?y1nkFs5=AF Xf)}{< Yiy=oG{јHG/7ܢ8o3F 4_cRY5#[ bL ʞSqہj>Oz s&eȓ#׳IT^vdn SݵqcѦ%o::20  T£XAnuk|C%փ*2 kM9_Sea'U'~ѧ?4w(#6lsy9͸/,o4&{䅶[?-qCإ~h_p lE3c0v-cp<Ό.{TrFmWḬ\ :;v%@I V(CGp8 N`L@bbȉ`"ֿEp.:-HR0\QtZN=/+@)p8,& KDh…A8* Q11<!b2dՊm`7jG*+ռK>(DhqMH#mt .s :I])3콀IYSShXjeӴS >ג@Ez,(S*T  +}6+f8k{X'w=^=CC:7kVdk7y s6WfZ'^?#HuP6KƸ=hOM$j_1M "drixN)El=8XP(?OgNHoy6_j1ϪD̿>ll-۫yy; a&cT%Tiܳ ʂ)o9ğlA7}VKV$W*Pm,m=hSvQ+!Y"Ζjv Nh`W~RIKYO lo xag<*KҀoc[ 1KaNpvλW U$0]F V'Wta8=Oc62FE_ⓔy6^Ϝm1ymؕ6wiGdb}[*I:M:}:y9/-΢Ą o>ʏVlB ݊ ȏm]%f`Az|[}(9FObD6&3W<99W 5LC/*a) Z?cu7~RO 6l\Y VE2?XΉgƥ7\g?nfU/ *㑶պ%rǷ*m%{Z 3;6BS)E#Xg5ёt9?_h.1VP`YNPМddȡD$,v+P>lIGԀW} ;J7ѤsAmxQI=uJCo̩5DK"[1vG6NRf}fxsRXȰeV>/@JCmKTŖ|gJ8vܩJqE|$D ͦK%g"w#NK?ǙP1T*'ďǣmZ ߚh%t\^y}c(7'lWs,o*PAss0/10yǗi q)ʣwʧ3XgE L͚u BQ/sf6#\t}.5n%N3DGn\xXOgHhL5eHXyH,t*Sү q~[{!ܱ'REs$.D'A bD3#XNOnuƺcbuʯX {Dbp<] I@1tw^%XW7toT@TV#џRQ.dd5k_gT_ Vp%c ׺WX)Il'/m#^پRU +[gمJȃ AK;i % bH%u^9*KБіy8n~d fQ5萸DV??j)h{sI~IQPn-1f]}Ȳ?* UefQq.Y0LOMɴcv"'ݚ#-]k,r´EgN⧃K %SHsO$j\qBC>ZhT>rKz ^9n' ΁AU";nSA^_YQB]S}Yk|U'`3sXnՋ}vux+s!&M7S? \8qt>j"`^b h8EXM*+NO˶ܳg1f\2f XYI *㌴}PEqo)}.VկmZm#OmlЏ1.kX8ډyQ3ܞqZL/ 㞶eagoy!+<{[?>IZDdMb|yF (cnp"z9LSG5#Sj]%V" )bLGÇ[&>]̧pmlBvHL:8ȑ"[p]l 9sO;>{5Ë#r%2>;*k+=߭+V^WmU.aouZ778Xg.VU3-|ݐ?] gv%y}0PtvM;ͣ"/w)$sœe XEXNP@aj(QXTP1( !`QN}΍*8w$J X P:lLq0&ڼF+b`BQﰩ0o#M<֬OKk&<$޸? y|Է]K=YSؖœ:P ++өCj1&8@J~5c$eGU"L7>OSڊH5bk!wO-_vx@5|uD0+oT`Lv &:"cqY-s4x]v:-ěZ. oM7#GqV6G*rnұ>2REC1$WϨIm uEyQ'\BEŋZ 7YToUrmv):)??>4 c~5 |6D90:'AF/)t˷ ߮FE]#բ-OXBՒ˔",~ /U$צ(]?&S0 a+#nc k=3 ||@IV@D]]9dnڠ 5h0 'o{Jw=kȍ$lü_W'o-Z揞?-!DL[g%3[ 1LQI+mqj 2I%}+ g5Od?&>r8~!uȲu Y!g?4떍XTdd8Y#߹wl_8q5׿`4C%v+Ƌiƛ_]],ppF9}[Qh+9x᡽w'U_I_޼EJt4aQ{\ڹVaW\;N߅!᪜Ey -~ :VLٗ/=$fpeWwjPqCIu e$c[y'gruPމϽZh8 >|1=~ D-֚$j0f2 2vg%sT[T&`)oԛ{9, DP`M(A@00&! pTQC (*&B`0?FfԢ EDSf zԨU!C*$7*`bqCCH` LJ&?jM@E=b`V #`("0<& `RrjLHjo%j P{aĥJ`(/%A9ata?@U@8mV i:?/e7^`2 8Y[#)M}#i|_ne]ù&|~&0B Klz;S$2گf[,`-w1ʝӛPg'SM/ݑ&RSOoKtA?qS[ vԄ~Z2M^a>SO[nEW>qѓ!^z ۮqSU dkpYy+UMYHdh{{1UӐ]{bd| fl"W7Ql$6Dit=n(^g&bUaVkxxfy ߹FJ!~DFdk'/0 =ΞKGVޘpM˿lZ\ټp:DL+z"$Ż{@~Fc 5?Z9fw44ec <>)*^ٵbzh87)B2)WT8S6]qѧd˹jVb'M OEw5,h< iѶ"1CJUbDȯf e:4 [TßQ@FW d%XL>{ 7ϲ-> lחǜ[~Ycv>tpRalsw(3 RYZ)UK2aS8\8t„R*m86H.bnbACjB\!˷$i[aLKxƞv,G$qbXsnӌ4_sݶPn΍L)Hj,Y?˖!%VgkG+95R%|'HB-9~gjdl,26Dj3EƋyh3[^,}Wy-f?t\UԢ߻dA`cMMQp2AlGW:k-1EAmrd{!6;Uxb. }otHXOjanhR0 C-*?v5{~K>Ђ}"Fd#H;Gtyیҡ.w.q6N,x8`$mںһ t|,&RL#pD[ؤiٜBOm%~H=f*Y0cmU>6|%=ȐB)")\魁ec i-,nUȪ^5@lgi)y%%G I5m/7hn Z Q{7#IGoR?=PCg$(`>?y #0֭InaoߚJOXL!XR\'akpj-Yawk=r=r\2S%4 -X3dċ\-͵p3%t^I^Po *HqgU8Y(~$赝tL#1n2u_UmPA@&P9k]hdM+𭟐`ǰnSOojbRITʵێ4ſ9 [,;-Z8;c@' FO?n9 Ѻeߦv2zj!@60,p(ttq'z25e4;YP8]sޗg(NJNы'mηD8"J! Ec"=>ؗNdܻH/Mko^K颓3˹{J>|Yª{`؋ab V\?)2|ʍ "Ci4)J4U Ix0%S1%GY01$tyS]W̌I ýt-Ne" itvў>"٦ ,;2^ {obV*we'D.Yۺ\2@sKOAqdѽ˟ װ 6awAl%^%%gSq'b̾=XGJ3_PQ>xܔq+-`~*|X =J}}f{]FI-٪s=$`crHIj0a% Ut(CN4'Ja 6/+vvܯF{#ei|Xqn(r2l8q[(m -&>+]g&Ƒ[Au&jA__TCE1vg84O"ձB^uu_^>K'كU ElS.uhTHQ,w5\~^G%i ㉸\s Ġq<M(\@S<MawcGN6}"JZ%$(u~2(s*ji0쨡OU"{ViB?ٯ~779fE9cpq3O).5EkZ@1ʞyzN !H# ׂJvyʈ^\A f[J+Q%(M./ux'|_dC@*2:Q-9a׬mE~w@%b>G% \{a^Ǝ1ȄGN˵O'~mvuݛ-I0U S*8kXՒDV;IөĒiZZ9$KY3ӏ_cl Fc G%~@J3S Tlca9s6da׉S`Kl)=k=}Ym*_Q}tPN!G#{ ̮7,gFN>#NTrT+4{4CNcf ,ڜE9-|7f}RH_s4&I ‚`@+KJqn~Yh˟nL;um}}E?8or-@i,0*Cy1^J6>&VM!i8MeSO?jgZESP˓rNFxp?TyŒ72d~umCeC*o#,ud rT5Ѻ2Vy;g[:rxBXw,49Zc;.ɪt;x`_ӏ6eC4ڕ=/0`ֵ5U:>Nid-5'z%(]FfÛLlwHP]-j\ΐؤ27R$1B'@Wn㕾`p(׊&NQ>vڜv;+ej?c eej *+*9߽R  c b "'C̳"FY;NŬZ"C~<[)@.Q)T[XWߔ3L.h_ :1kMv@(˴P`8i4+/؞S&&m-({ED<([ tځL{ *FۘrSc?P .%6e5ܺWNmuL=ᅥYBҚݭ' ^P$p+*W{Y}L}=9ggx1aAHh'B[oɲ#mx ̭hmˀ'K?B3sY9&*/sP"I;yr3  ST]S#S#٬[4an}sa]ӽ.[LtA#sD?âX&5D omc ~~(rɀ,D: Ň@_l<'-H EY0(&g 1QT'"R%ҨdI >5 Ya`)0"6< 8 (DEQdN) .5\D p^0F@)Q@ic`0VѿzL_B_BD4Dc q1i P E# aA"bbb裨 EEJeEYEE q_LtdT(e4^Gv8X_UE+ЖlPeҴ01(AEnt18E LR|d倸H m"v9JGcnCОėC;%+FKm(UHvU1E-wPQTg"@Q`' ]H o (.AbS@kE*Q @Ԥ" pX BC(" (VY h^+unvַh} F&*/:qC=\݀*@|ʿk]ev/ߖ ͂B! !#(hqдWAB;O D *5 1D 2TPT: M@+ +mVԁ00 =SFB`-@"Ձ40teе>0*"h֩-9 @ԁҌ*we4Er}KC D␣4LPt7j<&ؾᠯ!hAh#EAtE<ŦZNinI- .@ME_AНAM[ пLB_m4B9' C_aA@0a<y %nm_C *nMr3A:$A^R"M@A"]:z?^HQEi"}{Mg7ϙ MZƚ5Vn>L#!EyaƁdžćTx]Dr}A~#4 zyՌ(`BIB%Mrzd@ǚ`57UI/c@hZ'}c>glԩ+&4 U^5H]m+l^Ns dv2h,ۛ%VIPteƮt(m|%TUI`5aVC3b|: *I4e&CR#j^%kP[uh@ V6ҽ6i"T9Ԁih. C kU yi#MS lVۦ-at G&к-wąi|WwT4?7Yils+ 9Fk>'jY:oԙܡtxt/vMJ+sX4t~,v?`VǸ(Zhb.yG|*R{R{o`ꭒ]Lfzs+_8]ύngD+S=][g5pvIun{~:%ξ[OXsm/m;ClW;iAR6/i;Jzjtys|ՆR=8t3?5._4!JLmԝve|ZvQ\&%zF׸noQnJ;me;.7dw_#co|6u_XuD%)_=rym-f-;־yLP/G]+U^mz`Otֿem~lԎϮu?١Lٓ[_yojjcnmLu2ZfDݹ3@7Λq3S&ly?Jיw~~M)_#OKUJhSוc85}4ߤ :vT N`w(v-p&.?hT9!4QHV^Zԍz1n(1uSe^*8Bʺ~95q*MfRqm?Ի6z~P6]J&~bLXڡ>vpf4_1Ԕ?gNkϬʝ=~7W^ZvOwns<}?ʟߘW]Z5hסasGWzV~KQ]v7k7 fbu{on*ݸn_/2W^,uUi=N>\u%.w{O_5PT62}6]vz,hӺ͎?] ƕ$84]_Y9˳?ˎ;W%>upϵh˷yH= śE/}{?էuj?Ѕyv t6ύ߫zbLKjT/,{?]=yM_j39GM5wmM>|5U *lWg~|s?ySo2jض˿ݎs졅w5ߵeW}EVïhUzkvLwY>R۟ԾIF{l]P\JK@;TC)TӦ۹*N]|:ƙw>{ӓ7ynGz,i%of*xti嵳ļwZ7oɺ`ȫW*}(凗gޮhw;u֑lխaoh%Qͺ'61/k{Y~4GuV]vjSY~E|sGZY{@e_,'NܨG=%s^eb՞5pۖFLݵ߸!kٷ7/Tkw~ou}Z^Zʃ'5zmV}S̎{{_qz/W̑*ʳx6I΍]qGfg+{կ>,|wmϛQfo$!/n{< WkS._wklr1g emsw4|īv )tΥj6lU C_A wR !uS WAnUS 8 wgkJ!xf2}ȱu#Nɀ]w7ds]ïꢨK!{QnJ4f%X [wK#;2qAtc$= 0A Mk8 [T"ʹӓSifULa+6PUѦG(.O$ItԣHO/v ,RS.%D7r$Dg6Ur0bˈ=:{ 6+ҋp"Ss+/EѽزbwL楞 -ᚖ)G `@Eh5$nr iȬtt7u=3R0眽C:,tIqꆃ:i)G]/77"mQ+ DYOr>ͦ 8SZNqs@&R%8ur8g %o-78XT栚榧:sb7b+'^h%-I,A>%;ù`&x2 ZD6fU)B;>ٌ4D񺖞K4?֠=ˣφQi9 Tv1(Nih0;&I  )y"I@,=^bAVi־} $4r$W>LWdPjlwZORwROǂh t<F|)K&$dup8ukf@`,LQNLI 0^͜[1"(-`p2P^U^;3 ?{Sy%~J"vJ5Ms=JZ5K#NVi.ɵ*~j(2<" ]:P?F2a`N(]LlN@TUY$m#A2 6 ,BʢP|4SggSg %3cC=J鞄R < ,x>u1H[uzױz 0<"n|JyzH8`_Z K Rt1HFg ')C ad@p"bb஻P>aȵ% pk'hJ8W_u,;]V'`eI5l( !6p~w 'N U.'iV`$(x0bы1Tm2NL&L lTvԣހϪ;@@V]n>Z udmS`ati%7&AAɡ* SˉW7pTf0d 5|da m( ɴO囊N g7)4 ~ ,&VŰfh6n~fjthǞzȹq[͟A, u҃mH%™6oe6`n六Vލ53qa&ZbZ@0Lh 5C{yblYsc }(^Eث_dujKY+@`6ZIKF o\l,zҙK'G57rHuY%k zJ298 b>w摥%I, 7bO (עh:z@."%6Hc>pH= E;lVCAqGE$S ,.j8.83:^`,( mDkPZY]^ VC'g DEl \I /(\k~0 :|kW6ףѯD*FO;yԚ=Xa+p|fz XƧ'"*5&OmL\rFng?e=|R5ojr(Of/XZ0L);Ǐ;[9ݍ?Y"sM=1tVÖ =cu:Vno\O*52٢APVWƩu~:^Dfcm0෡>צ61ӕ;3שJGW=Ψ}/GeKꜯRs| %ߑ7_񟚞po-|' Yl٢̼)wڜ_>w\LE8/N<5RT$?۽8i~ʐ:eV55*>{$O6../ REbZ*%(`eH /G+._<0ho-2aF AJ5n[F45X+ȁmW4]!۱VM#.8Av@x塪`"(Aѥ< W@"Mb(a"#6@WzނJCRۆBTöq ńf=ɻiVgj(_֖lZUJP9*]H [rpvNwc&%J f}5EZyZa( WrC=Pt5Xnka-Ě4( UM꣋hiu7s-l:%6(QSϐ9g؜ nH-K/G c5Fڨ]$JQF>}*XuR6"XoktAޣMC9 h'-vt"e(}vVÍRT~ ߦ (mqqh/IiJ3tU6Fe _X @N=NmUnJ.t(H f$*+^=#44PPl{ڥܩhvf `a{kՍdhv)( R,f7u[aUm->Iɽ@sS'#mdɿ <)d.="9;v+l%2`j#bjm#ϛ>= c𼭡JI#/7fӅvN8Rj\t!S{so ~5j@MI[h= +~X=ȝׅx;r,鶉~LYuUD*:aghL)V R +S? EG9GfDBYR GJ,:*-p(k>=G  eҨ)GBjgOhOO]4/:H-w<48:L]v2?J=Q2T,*Ns*4 ˓: 19$3S[ƥD1 UM_VhqR/qUĬP\̸kbWNL$q%SKW_KKqq"*JGÌ-8+ۓ]83ʋjL^SVw1(+m;*~_Vw1ȱ`qDŽ1Tjʾ!Qx/:wP$CuHܕd0(wId=UEʧ)ԌE}}^8:X[^US9.ԊJԶ_ˋ5rz*[K)쥼,XJ9Qj fao%Y RE"Gc.zQʁ!>ꣴ(Db_% @l_K[4ө67OyYCb~!,7$fmJM3pRHl-4o u ZZ,bPPq*УV Q;HeL_ ycH-|+}Si2??ְg~X&Qi^yRp,AX=Z^8"J/( %!.kZ4 EZJ)/DP%یJvQa8*f=.SG*S8ST-F*E5M,-0J)*NGG)ٓpn-RF+v4߯G+ѯ9&M2Fy% *E3S!DōB*dI#*clODJ b搴QQ.?ZJ-TOV(yuJgҸ`x^ԭ[zuKŕUJ~艶 Eߕh^*5hYRZeȿkزN(>_:1{ހR(U؈U7i&͹S}Gũ6nBfeR-r3J3PmlEmVqu+Z^]I[4jJLݎ٩yJv*3S) >2^ l.(SsQZحݨ^e<^SſTz?S]@~e#R#(%!$+Jaí:T&mCQ J[Tj9ae9jFTjwD)G1(?GQ*P IC(_vϷPI?:oG ,Q'TV|KIL),t/QzxJY)BiW`3TtZY,> Lkeyo@g/}VҲooP0ևb >}:-Πs`YEsIa._:ϝW)D W"y_^,GT-1 *fo 2=WE~J!%Ow%2T,cPT iblDO%wMB 7֔j9xLWUM[EͲgaCqŶ]Kw(B &E!X!c }A=^N!'CMCU;IUz/KǨS NJnU\[~C!]8#G=6^1M1SkRUonYx/]5}=x G~1g3~|Q-*d>WglŐxO;lΞ Ex7FjIO!cͅ"f;DzHfCzhA5RV`Dg-LHO'셦'ddXk~ft?a.=L>`K,=&Ś(ŢXֽX얦21:Eڐ!PbN_CʈM|8zElLѕ#T3xj.+ b!CւĪ'JſPs>-q< :f|9nP)Y"ࡦ C-.C͒0HQ)ԽKC07(\bXM׃+ @3)&?mq2+:N4w[i-X}6]Z-~n5vYU^1),"tm3_.֒ ͠'7-0ʆ8?|;`L įo*ԋcb4Is3-/ ކmƯ [EOUSߓ9FTbѨnD?>zщ9Egc[0O-` K+s7T L癲*9ѧ~FB]geD\$ Fs5ݒ;q5U8k ݀P ʃquSԅ+,j. XƔі-j/ܮkbIPOװDx*p\3~`¯hv|N}PV 7U5E>Д]Oi0w 'VAC_q'u1_4gȻ׀ӇdL»eghav\"Ռˆ4y_iLtCl-u?'Tu9G&9l&AĖ%WɆ0YB LLYH:|&iR=< /l7B?q3彣 !Β Bǒ}ZJ{Xl0 1\6@l0sҚfsl.}^OyAݑ6dMt #B#WV{T=!+}]5U Жc)В,.9m !3!0kCh KN:4,,j1 u@ ([T]uu8k2fAדY 8 H*۲Eqa2ojfinx̲3Q夁.NnʺmXl.tYuLy]&2 MWfg  r*12T2KC5G;!m@| Q8*[OV1m&nBRe͘fl<4vASek5Y{y&<VP=> _e.TYvyt6 m'Tl6u  45BeC0-ᰴ[#U&W311na¬c%LϭX^jxLLȝ&=k٠"㫠3+gyLdMKc´)~ *۲Le6ܤ/orTmg?sMFg3EHqs?1czBL"ѮŔD v`䱻{<%6:@'܃ & 2Is53E`,f\rebk|&˄uRh.vJ<Öڅngtw]J|cuu9][.t Y]'nSAkZriU|J|I_ <&,c gL~BWNf'(;2eAOј[aa,ef@J5,=0KY`b'`tt۩e|q`J1 R\`03\"yJ6(E8LQ*O-sè:6wb{rFQ/+4h򂺮,X<%-(*k2OKN(/)oUfh,6;bsģH1? zltʇU1&;N%j/1&;gD>Ƃ'`,Mu# `1A6 X $!cU6;6Hmn2: /2&' C g Pgɧ)$3Fe9u)![0f=n8ru5$6@hUM&9Wߠ;`LrN)9ţ}3,)\>JˠTLg:,GΦttZ`fȷQQ!z1!@ό]%S+7i`(A#Mwr0 , z4G-1aN]dMU>Mh$;,f(w)clG)=Д"Ġ=!(\ yjTdQe9=hl&gL{$ T4qSL3xǞ̂, ylU0Js٣5s.1;c0y5JSd$؋Lvm^ʖOMaU>c0w[c~܇ /CVήرIfgcf0nicG&c3~kd7 ekg*&*N4Mn^=eeM(ȁgv;`Tr/ZK֪45K%d{ ,ù0[sd ̓ IA93:_˖ew%M:cKcWLrV ^%Д-00s@ ~W\Wٓ(cn4c~4?2GgBk&Sޗ,`c30 `(M+  ;^MI͖2?R|l/G0KnR5NR/ta6ӠKzmx>ٛg q?MFq#[@yYîSʓas辒|P]]60r6u2h0HLщ!ǜ'yr¤队r!0) *T^-CeLy 0ȀyLQbA1ԌgC[9jI=[bp%ai/s )Vqa&*@.ӢB#F'Edɴ#ܱ,('lCHüQ]n Y̰^# {!Kc%2%,EHʹ("{GgEptJFq1i~[#aK^g/x XbB ZSy>7mv,6-_nuֱcyOWlӵPy<[>X101N~'V|} D&s+05ݣ("ώBvyvWvǿjd1(0}}vq5P(_YFO`Σ .sc잕E/ȝ8*3cA؇|GcYlK͖T`.$Wx{r9[8!;'4}q o)u1d9>|3KdL0v\vn96;سllvŊVhbэF0v(o1Ou,mE|=&.qU4=G;=.̱e0 %S `O 7ϥ ^F &2 W@Q@ 8%?;,(XA 0ǯ8xmAAtl@[>!܂X$$=M4``HإIt XAD $ʃdQ~u @T Xq|QA*F bJ[ 8 bvຘ2b C\PV Do) >66MREQBK(J~4(.I.`$) \TRࣤ: )%XR]I$@%|N$e] &*MHATч +hB/q& `@Fm(12$-+ d!4'=%/ AVhq BN ɩ:9n`.?Śs9Sp^al7" HP"wN|ǀKp @SD l\ R|Sei`LE(E-܀Ux*I*H*a)EhIFX5%},ԕ[e.६4xU|Ca7fFA x n5TeSnFU0VUa')cqU@WUG~5&VtAN`Lm;SJ2/}H$5VcȓLOjb> ha]Z& 9y8&BG&A6p\hn BsMA&hYf(Zpal<8?a bDhA"cX{D,KavX) r ǝ*ANq"-u-b Ns6x', p_A !p{@Ф,6Ah]Mi"Yl pcD}`K93I DH Ds%FI$Z`_dd BdK;3Ф:f*  _$BDZ/( =p͠,jAZJ; jB-][Xj12 uΆ uh=QW|`AV<aRp@rzd¥h`\Wqq=AТgDJ_ W /0d}9؋@!1/8zw w[r ؐa$bpi$ 2Cʓ`atEmqǕm[=ߦ{RV8Xe3;R31?\r7WS6GUl?}jl>2|@>VfE'F #+Eip(젏g-LM1sA4Fbs($^CH<aBx zrx4.SH6M J" kQf!,eh"X !of0D8CUz<dA]a>p)[.M+ f]+:<qE CB,\P#;dp>Xe-|dMTٖ>yf~j}`VY-#e5ïK/ar~- )r&d|-/xV5ShC6clPC bE5䗧_ڮE3B^{gnEs;)"[]1H^~o}R:EzFB=>s.s׺'5wrwtD^wYƨA4v"zׂR(Ne#ħsb>Py;bx0vγvų1` .^G:?s;@kR}Y[rHew9րwşoބ3]}bO$-\ch\`&գ$Q2KEKS$M,6Q{{?To?VY ơ+nf~q"5+և_ӺdT}}P%7??1`Zs3ΨNl掤ONŝ}ub #ܜy$tRВ̉2Tr6QY[1a抐z#>CK5<|‡b*Ic.Szw"",&&*$ϖ'Z9δ1HzԙO`_  kgLp/^zq,3FY m̾Nay} c ,!a.&T<"H,HPkc1$< GȰd CZ2`0Xd`:?ך *ɴ찪D 28<0 X8B\n!lfȰ6Ӹu<^SaPNrT Q,/Ý;ޟTvUűsVT8!w9q5q1uDjB_'_Q8¢%/eFU8k !y&+wY&;jxebvצSDe PċZFS$rK`9@#_WuD ?\q9~;]wz2P2 J6_Z׸ cu^uxQDf ',Pn6zIn9r^<to岚RջƖh2Ls{s:z~F` 9D[fW' 6 9izN3k) ]Xte֠| Ʉ@CɑԡF/9׏SWS'Wfsts,9ݞwD dNdz!_P\/nyWBX8{evvD2)oVv+a%pUx@$ha܏$OcgJ}xD4Sc2sfE) L{s$u_[Tx==#*OϾF#&sNf c~FT}VvYGaEV㒉Sѓ}Sv?ɔ"ޮ'кSi_ji"XVx[y_]o~BkS)}j9k{n Ufj=r򮯷:;t&_Zl<7N\Qz8|5/ЃUzDW/p1Zz4[ݝG+&<<&v*WQF[09QE"gO^M2\y5*? iqЂ0h,~~#.  2d`vښ= N16w c 3wl}X u#X;Op#':J^>UFC,r]`@3Xs7n{]A1S=Ocp yw>n@lκG|&8z .diz p]9`?cо p8=@0QM/g`* vwa*RsnlxO @v"D) ZQ@AFzF&@6UjgyU ~&I܀Z')CGBoR&ZВ6#iBhv,꬧_v6҇#[@ f(t]G];xWzsG *(iQn1s9L@Ly]e (LwR]c`R]qp.<)60j.%pz%vc \Lu됢'Į*q L &8 ;}3mrP:9htvl#~EnE'Md0m.{!?fܿgVЧ]߅@O:>|;.}#^a sx?H"L'Daau^r4v]:S+~AsI-v1Ly=;GDJȭvm/ؓv&Zc[>7'+w@.Thyspq\`lNl-ψcBjնaσɭV۩~eLGe& k9zz|WǦ0C5卣qS|C?.%Zt oM-H")ꣾ^"{mqL{= ˖ Շw4nݲ@bwx0yz=o=anR&%oҍNب S (< wԟ<+t J80G4AF*SveilzV#&ASvIi1s`n.t, 8Wi g?z5!䦛L@#%&@raL3w+`jÃG0;Xh~y{\As @\9@=\hnn. ҊaXO2raӄ`CЃIlQ%>Q$U~cp BIJCUF ] 8@A> `^@d8 abT. zFÿCIHm_5ppn3eGR#&BFI )D `~3n R V wƎHC1j B38] u}`2glKl$ Y?Fh[~|6  $ҫ\9/myѩڛ\Ly+AKlL%D$70ۑ_'PdUX;KiR@$lڑ*xGA*SwT8s_tq(.fq: 0X yӟt$ /s 0=SnJtqsA.3b3P~h %o~z_ BhSaǺ)h1P,ݼ tFw8tm:EXwuH&A0DbXjoRHjIͩFٌPFޜk4=DрE^W:2WdJ `3 . tIN~+*!+Q7`߯LW:?]bED y= ^,)dZO8)Fna/$1??GλcӴ>8:b`=􂎉@!x7.Os;/6C-jbcJtxN)Xc/P'e'ukLm\ƑP-Kbiѓ+(4RF}1Vӛ搙*/dޫvpYi[Ar@)H}&YNz89.c0 3^vubRAYOƏڸ>[9E{Y'20ΎW퇞K_Y}%o;>Tڒn6%%: [u9p|񱐵8kyfG.o%8]_R٥:H,-{(O=TnK~-&P蘗¨ F߃ޒhM4j:Y-(p,K_xqDG2~jY,Wx}x (!d6l=t"<S`Rt@b.["2 6>mG/T9Y~wJ{SsE)?P;mS_l<У|zaLRA1!_Loist1Z2tuomxA-j)Ya- Fm@+WwIhDfIwIa1k!ur=7,\xz%ߍ򱴼KMKtn9rJ}mm3c,%c,nV[N)mC4g.;?\c:78SnxXS+ B 2,$[(y0bʛ#≮VA/eO/Sk+k_RjtnرDw^;G Y*e]*o9#CIWJɥo]+PYa{`=LB-2l//3(m mOo锐a#_vaػ;筞X܄ &}<٢:;iT}ht8g F;7ٴ]ՏF%ǥUC/Qt4*3UZ\)KjH١N,\7/kv{ڳŖ $%׊8'o{/癉k Oɒ&ԇg\oB/ c!}宦Wx}c8}UsDʁ2:#؂ݗhSOcmJr]Vx.!l}/so}Ϫg.<H}w!~?Ї%ŦhOm3kCo=}=*'|E]557bZ]@˚T$s@T;^ZN13nQ~g)ݝ=SIޯ&D WKiJjjEd杙iaRSȖX-3OK*Nֱ\rYa!D, g@~ BDo8]Ǚߑ v`71+0 И;} "` Cۏû;B&5q}<EqKF,lSkAa&]Iګm<"`& w Yhϰ.TWu~LD8,`!*:4A?6P2lBQ(B: hCh~g/l{#Ϝ3={yK+N8aSU/Dzf^ڛVfwz Vs)[]^+TW{!~T`roWoJM2͸rj *^{Ԡ} cɧ#z6` )<6ƾSJ`N{a rN_U#f^|K^RB,jRC垓.6 Z5:3leG>)Rv:5kxƖ􏭇}W8p(2-I{v~guzc{>nz*c%Ր_B|n5*&/TZPO+`Qe\;P*BV[aA%=QaIWOԫ]N1ҋ5Zr* z>egQʑ蛙OӎTpmwi՗]ZsZ,ĽO sՠŅ'sܬj䴻Ab (?ûEz ͯ-&,li"˘|[Z))],$N @īTa`d&7yC_XcTz!3(AZ䨒W3=F;Bu7Exx}BA,CRmQ[bdҳB[c.0(JO!OxO)F.]&qE* 8靿XdT.^ضDTx睭,@{p`=rb@=~oF tK2ح(A_GROl ?=2(Y-D׾SQI5 R?f<(6(S6ϙmh $$>DY {Y :}q~z}q;yCܺ:ݏtBOUs?:n(pI/tpFeEcGYߚW{|xV& WSs\;<S\an> d]6e9K'+ = KtLgq\qQ*g =hܻju:xʍ`[fY:u0#pQQ*]TS^7jKmr!H#Ir,C{3ܭWO@kjh0Eej{pE(#ŝw2Noa?^Z_;ޙ{6.G\ܦWF758 t#v Z_0ar˒GFV;8rgr,Tܮ8"2He~w!ca|j|nSw;cQ<;N8VFj'VNDޖza_w+i^졾#AJB/;{,e][éCp'*ҥNӭ4UӬY:ƐCK}g` -+&tZJY_nE0O'E 8Ԣ]ŮL$) k̵|Jc:1}6λ%&:\p^2)tW+\Qj`mOU M⟈ޒNk,3 }3sn8#nMOo+u˂NX<ڑߟse=s(@ < qM;mltg 8s;K`$I02"#qXjH"^o%h@!F9F$"0x;=)I{Go<$πAU 2E`FA_R`EAp WGOt84wOzG'0Dz(J{z 4a!4!6: ;,5(bnIf@piNjP1,Fv;9#I0ℭ'Ph4v(1ף Gd&p/ u.Q[72l,.H =@#$2@2z#pc_D1aQq…J/.&X%0u OCl6}, $Eܵ/;K=2dO Nj16PH.8:}"9)˳nʠW12w 8^*[.%Qc谅isl̖qX#DB S ";'{O'9*kנ#bxjqO+5)!F3l/T!&s-~|Ո#QO/P4sҭU{kِTr?C2M^\/"rVꌯɷc.~sGS)z) >cKZnS2'&:j',ߜdk,?["sHO|^ģZt0YmUXk/kZ]%W](-LK~<1hu%(ƩL.fSFpR?]t_3JZgJ PBgV38jKwpjXQ;^Ӿ+$LYa ΚΗkBw7 'xzD_Ô%/q{.y^Ϫgz9>Д>?[F \zgx4hz}odDS廊3|ю2;S>2IΏh +ẏyjyk\Ԟ{6-@Uy_7b/6NQL'w/OSv^'.{=dc9ۭX"ɷ.zkZݐ7}^osR.'m_7Q!]wKd?F@|ߺT/P_\J-=5 [P-2In1Yg0~FNSzKy bF?'s rL>*CKJ^{E"o3AM3q Ջg>/[F3\| 2Cժf9FElZBp[chїlj)%٭Z(6Y@#:dpX2-!~83J̱jAv zG2U 3mP|[ĮG>E[q-EG-R%Q)1,Aĝ43V(u ׵Ų)ݝV bv߄ qq&< n n 7ȓ =@HaЁnPD"v"Eld2|ЋX,E} Ek=!ln~ iJz"8CbIX  H,iaRIؠ;ܒ<( 4#,rȰ"h[ `PQîbH0J bQy]5@맮(V&8CK`mf!ءRp JB)4NbiAQ$3"` $$ A0@h&CnFHmFAܛ29I+ڹE@'$鴠1idƋMYL_D3z #`!*+Ax_솽u,TX3X.4T;BWLf:w2 N(-t\h31vZ$ Sajw^"/M밾,HϺ @yc2" KMvZWu>"%d XQ`}nZϬf^ (2$r9| ]cn ~4i%+=1v^ 7ks\ ex>~]~Jfuvql>jx.v (T\m=ȓqsZQ| '+]9M>T5wz}J=Gl^=8a|.bKD:{ ҏT0˗Os+?SA1vcW6w~W>"@XNU #N~n-PFB^RU2wY#^)E'%dR͵9zx}nt =6c'!v}fot_Xx~射a[~Pk)We-ԓr{G'ev?{WO5iGklAˤ\Re5=H=[h&*0RF`d+ Yl|Mݩ8Ul+9όᮠ*k%y!zj͈ѳ/N~q@Rzg̯{y?m+/}(Ǯ{)M5S'*T!U,wt?+PM[ռk?a';Zm##nܙ$UX?j ߠ5؞OF([TGxpc2qr'X75DWF=ڴ6 g_dZ 8oK,~]^?c {J@H0Vϥ6Q']լΦsmv=I4ƻ;eW/_8{ސY$Lq]/8:2OƄdm`S#.aU8U(tO !bml=߶D|vDCO뇊0,$H Lç0ǯd 9b[9cTR`=~N>? ;#`\ټ9 3#xCۆfЗ/G.d1-gV_ ;aqP}EvMdSIG)3 oz8FB7k>b7jľ w:47⒊Rԏ:.:{Zf~q䥢=XpG*'ʋ-k}lrO(`?RHI~kF07xq2朝W^™E*VO6TFދNq[TDl榵 7: ٘>rYH\RJʍ=g$N؏kbhmj2^܈OlZkL4YtDD *96i}R}{WU:%ϕKS63R%lh /䌳kII>ϕBn$h|(8 bmJE1! җXD]O8;&ǭ$?YÄ כЅ80 `Av}zn!SAXAdoY DpHi `)I1n@<7 -xM,q 苃뿁IHD@LKPx!E(= mb ~`;G l6ɀh [_AWtxztg 7ehL[S:VpQu1Jo:QWEY.i# "oVa; kv="*aWP2&HjL%=`\PR_K() u */_'LӦ?QB ć6IT$Aν}&(}wǯЁp]ng%Kb ߷&*|l睑iluѕ<_Ui0H:5 E޸Y]LԻhc~X9zт򴌫׵, ݇.y3 74/f@f\&q:Yޏ׈ }/–A%Ia-b3zD2b,\0qq}7m!bz KUfy$|,KE%Z{pPȪVd$vrc<.==|x5.dlQ}WhjT^S,_L]RpL24^7 C{!DVl`ʬ@v1G,]6qxO>]}#;*'hj"z׿{SsN~FS&[xM᥵N} FDi1eOWXlnlzj1(a193G{`|WG)՛uP6rZǔv&DS+>KXZ&3'.YLrz[4ZLGқ&W-qH䠓@-6}{Yv.V |bCkkSkgzum] rOpQ"/vQj[DOaQ0)ȟxUj8o1=8v0khe|5`|s1wE!1>|xś LzOU"9Z-Ay'ıtRbU_P+4I)d}-9q!Jⱟ|$23Cg}F[&>CJs"xTΪ}t,q E$V+]Ip%h0 2TDĝdGQ!VYS֘`hi(]^w?q伭y1H9jεUnKԲ0pwŔ P语{ ~QS8 WYQF?${IM47*H?VveuCrbQ+~YptRL"_$ IֱZW`{y;7O8~d WtN4GԪU"[pAJW>l<2(t}1 PtL>gѷB;% ?HlbՙU;4Zܷy-mT1Iv͙I|LUmWM:85jvZAV0:ف_Mj& :tEO#2/~ُ73|`zmQ\PajL<Ȥ=oo23 kd]ඹxr$] ˒}ȏ=`F%^Rn[po,]JSj<}~G+]zJ1x1|o.UuuL4?x>-ŔܙIY9>1wte(1w.jX>(bיT{J0xуV.VXQ׹yYǭn&`g5Lk OѪ(3GQxʦ^PksUI<H|t=C[1CV\B{ f9_Ύ;;Hf" TD0 8dL=hJw'P gQc,2D,z ܱAۓ8L4XK 9HnKc-= um`LK%>M,܄;{?rdQz0vɩ4ċo0K2-rj@K`ͮmR Z!}8Q:x"rLWdNLSƲN6sQh%[DUC̋1řH7[;Euyv^@xy*UbU_+b%<S$\N{,Nٌ6O|7&C*ì upR5"5kP!{\=Yk#k]zL/ްٺSOL)xV.Ni&iG)̞}"T|zqz8 Dw:lvG7sxv-ʞ0N42~ Y5Ff=? zȕA}Y"h b:?)NIDE_̵Ίط$E:%VZ0e6kk^-tAlpIke]:َ.umgܯ ݹHQ J`9 )(a(~x.6@2]U 6MM@xKahmbOjOtW*%̦[4Ս;F.!qL^`)YdFܫ0}Rr80g5KFvhuUPf3m2 /}LŪۼ=wdG sw#B)CgfA³&߂~&?Wgg̈́$Ǵss}+Qb@3?A ӭes娒 _buD_Hа'ACڭ6a6$OtŴґ:Ɩsoo7<i4I:5:W=>"5y[9/NTC}Vf׽j=b#;YpVzK?{濨/Z'8J4~4AL@ G ymo#hѰ2P R wk_Sz3o<%)ުf ) 9nB7k]_s~ j!D ,7n-T@ܼ~q adbtL{o*U`B;3hdhP8ƍ|Cc6kEl]``Z-~ѰV~XUܭ˰nT(S" ` !}iwEՑ^g$?y!yX4叭X-È#L) >F,ޱ6r=t~RSP0;"(9r"{n㊆rTX9[0"AK=c K_ХjgRj؋UjTg! c!$C}˲s: υ=zneXTESsFpۗ4k=3xt&yAY.Tȥc}l}w h/zǴNB'lB]#ri_l.ܺB{h(<_$]$ >R| F*r58ɢr$]G W1WE^ \΋#B ߬~EN%W0FoWȐ27R<o+ŗeN6lH]+3I'G@vh8ȏ؎ F_s5l=_;s?8}D<1Ivq e"i@.|T- 2S Ká6G~wZ@5tN[* `aUPZCc! Z;0(R[[E7dCO2 URĕFkٛx1\*B8k L˸WwexN aDfJpj%L.îCTވiK,rw( DB ($, X_o&s`(#V$0!*zxbޯԀ@.$220'?ܧ, }JAޱޓLKγ@Fۭ]:XTM>m[-hUB>Ve_Nw$ FU-3۲PV5hŹ,SOkOED?Jۙ7qu|((z]`%(sYE5** _!mfQy;9qy'x(hI%V:֎{6%=Xzd>]{NL?]CeM )D0UDL~ ,IN}X24frtWdriX}<ѺA qf|c׻|3p<Dؙx y |ƿs(o2\^N%hEzgOK#Bu.6@5 iT|긪]ԧc;.R <wˠS{fc奔ߤ?0.+$T^/ ܻhEj(p`ib~=A>&i mSXkO ٣F&k>!|DLϽ ⦡QcQNnUA÷GQ Kuw-[%C&[5J;h+>Z'W!^DY4TA^Ʊ}͜G/z$ К-%Nqy/K6ss8fB W(oX]*u}]MY\%=Yk;~c {Uܻmq3sSo$(&*F5W7+e28e%#9%Qͼ-<>EWbFzM5x4w7'p7v<&Q##M/x4L2o&)HNL"BKqփO1b/vCs U/$Tel>bY?EPN@Ian9ײ l/<G*vೢ:ĴMDDž^BL}[27r$2AxvO\/5 zwZ/"Xc ^ ̎Fag+/jX}|&0Cc~Z,kܶ r:^O>wLcXWfᯢB@sK;v FHCWI1RPeTp$1c= ⣦?gU.]R{cYZ wЧY,x(,OoK}<5VSWxr}~_0`nZ 1ճۭTT>9-٤RdR4ʥ(T*P+R"M=[yS;s|;nbw\K)&ޖ}P:; +yDp>PCП]{0Ss0|̴j~;Qס;Gꬅ32DDYaS ݏO:}vMoHO@$͗|'{_$D 7_w KRjP1:ʷQpU|\Vu~q6AEC' _`yF8I ("dhhMyr?0Jl185X/&J\I, IyYoHbMHZ-@S WH+׃1>+f#|?,v5 !1}Q&?\X۷m߉b@@71MɥH"%qJ +ŸgG-VY]֍/r|"PvLJY:6˻&UQQm1S4"Xa HtLܡ( KA/}ކ뤘']lT6PdrWh4{-Ns v-gMdYmF|S|y cxOjOưm}i?ox+›B\=0pT*>XL2b&gM\rPM~I)EOtv]74J2`%. CM5#{D 4[ -F"|.M6.AulE9vŠ^VxWl \5!zbLcrߘuEw{nc.ɖbጒLO Dg9gYrvОfj-5  ϕQ>}!Sha%ѻ*3l ҊEWEN[/D_Yp%]P $jH.ߌaΤ= 0 `9nX[d2#gАގ1 ϶}ds&7{*+0>VjciI5NxooM!ᔄ _<{" M,M}$= .]H+Ht_+2<$֚)-LS3d^#aAPpAsDɋ"9z,~{!I"Xt<1f6#~PuݓBo?fӵ`!WϮN؍$ p[eNZ$d2c"?g?eR^ɋCIVI ~?kdzCT\|)uɽkūFv oǙON>1ߠmC  uw;/lnV'M&>9_3|Aͫ^Bi.unC#X̗ItJOíQ0Muc8@sQ q r.;)%}«`:G+P[sWə۽7rm nu@EEch>bZY, ȃύZ||N)d3Nֻoi7·4}B#ō<9zE du=QlL'4PmV\?rMTqڤqc*mT7qq pބ/ͧȖGNg&{i\C_">mZ5VnUm xIJy}<0KRLyX\sk>wn]m64f ,Vor?UJuӽKꦿͺ|Ӯz0 0- qSXD 2ZT{oQW]?;/tg8 4 '2RH FߟTda^n#ޜ{+$u-fDȉFkyϫ76ͣmE=/.6\PI.»NmY?p[OP7ҥ 2Y,,"2W*RH'BW/CQdX"Y_j{5;5M`v>۱ 0e? 썟*37uGk5kv#ʹ('󾑈wd{ce! 3%w%/`j#5Ii]\>u˝T|mlY$;lJ2PEunڂQ?@&Lc{s$0-vH%h׵Q=YOC peP"fDԭ}3`>?7 +65vthy> Zͻ*5wI#gxCU5;i|ҡ|\{N<oD%o6*cIR[A)l/_]yM9d!D3߾4Yg4y͐U"6fΐ np᥆dݭLg[U1bcI|P9[6EIj u|}"9L$(4LLmX'6O$*d6.Nೳ(bAܾbn&]\<=\k&s$L`˖?=o&Ms!-<OW,HVJt٣I䫐AEN覜dБҍki 00bQpz',dyco[BKM7ݣK:c&!36Pr7"B|&Y|YdᣑCs\IF*M+#?!jc}k$BVI<@ylׯNk}bѥ, }iۓ`2=6 y{NTQp0Ě<%()UDhNNXQI1- 28{$}/p_fDv)~ "W)V3t}]Imjp0R4(1)1fr >ڒ\Lˇ"\L_<O@1w !T>C43O+⢚:ig)oS~o/* CLN-,}NsBt&-CVֻN76Ev'OvSrOѧ+HIf3>.0ghhAP7UT5DLf!zs]E!i+al5b&~eD*HqG"LJ78B ":"$_` XBDL!./0 YC!& XPz lt> Dt\?V &/-Cáp&u u~CdAyXϽΧ!tQ_xMߊzD7FD=j *ݥߚîXB{hڛv7v7*xw`D '`pMd=ɺ<ִvzczQܜ ,(|yHǃiX׏ͫ$*W b!RQA!`!Э:0Ul xcJԃ%|SL0XW6S=̻8CePoD4HHE""CW6mW`zǍ! P`(K*)ȟ~Fq% aۖ^ MTdo_U԰%J>hvxo4 4 =0ϊJ˜QwmsԦ26eQV{X.L=3}kǬkuW!S8H^śA[Fŵ6[4h=wHp h ww{pw ݹ3}VOWwO՜`ó6-ҬH5Mg; }?c\cУ+~X=ܾ]KNmJdRYњv뉁g eW(E=ԷʕO|JRVm(?w۰5HBen]Tf.LX >lVJ?Z V@0|/2GJKŸwK>[ۙ]K rHԪ. 8Q`iGHڗgf PpOªum:Ѥ$oLĵ`b,R.ZU |JW$*h nAq*Khހ#ʻw1璂* >``KKq>}0 l%tHãĴYW=QFtUǾ7[yW=\Nc8|׺U QTf-D_H0@Я䮡[luE ) DrQ#E. \$L+;1M~cR4-|7ı6_"9HŲc-1$&3St<56Wܤ#BIZkU}.oh~%Y? NV*c@<e(FBVͻ;,}i/Q x"GL60;y/뢼/׼#0lUDp˗Pe_ 0}^QԄ5RoD'jZ?[tV"fo^9cY@?bL}0c?'y Ĩodt^|/jR[&=P򆨩?rdIy4pHC}umNΘ6gwD#ʦϞ,S֣\'R>\TVZYg Σu5=h S~gW΃|[(6ܦH7ܾ}WRN!OݹxTzPl^C(M1_I\LNGxGr:4Oz4IFpe$8& ]l>{:ljE>ORl? l<^NagrVyX~d\EKG9X_ž= V7#sq0b0^B8~c1v  ouiRdk'܂[ڴLl $}S.b\ѓR}uVC(y_=éC ;v z"^S REEW rܵpLĕJAv o^pըAwzR9)+_QtD԰*B0 SםL,0VfZxzx:GJ _ho|L{c4v:4@|g5hiH}s}?~KQcNCWLZ=.5?vڥahאvB>n:}P½U.~i9pB9{j f_穜3ÏKtM?yY{SjE%oӉIV+_Cu&."E=$zr˟sR8^сѥ`j98z:j&;A7~y;i۟8R,n<- JNPkކb&fO&:V-" Ú߈>SʓSNt%=;}$짇 o]8V_q_`(>x*v>OcK P%XOckAml _ad+NU[z[4 [ )\q6sRSA׏V2 ?ڪ#tPGN jK7~>,~<d$>D=9]Vp ,U?vWJCw`|< ]X9qmڟʑB] p@3M$@M<7=58Ta9R9EZO-L۲(./p6=~G-zbLfץ~DT9hsU<%?};-jB!L24HYxt$ضξ֢g1OPHgrA S]U0᷽,N;Al7梇4(֩+᭎V[G\9Ŷ^EܯtVxDR!L"B!}GT-U,Aö#.DGI8up0qiubkoBH$ JvMcvs`4b7mt"no20}D߄¾R9%<)-U +)V~".oߟ #Jp䆐ΆLcH(m bC_,uzBԮ~}3o"D:4&_{ss[@1"u9Pr%Jm{Q\l| ٣K:K̛f3-޽ |"$t:r'ltGsH,M&;!hGdh̰,ȿy%̐raX*ϴ+ *TNjRwy(jϓե!i=0CLo6VJ,  eu"roCi~2w_([%D}"Ђ < 4[Đ9UB߯ 3^c*1o#(jI9bi6$҉N)|SE黎prʸwN×+oDI3>ǂ<8B8lj tY,«WbI]muPtA_Y&\̂TObv?Cs4R.[QԄR2U[h<[syp79/;i}8ַnQ %/EtJࠅ:f_2ens}:'@t[')>E\*c"Q-0w]WcWDSm~v!% q\/YTpRV{',lYٍgpGIۗ(ѨUmwRȀeT*iH[ϸC[nd]2G0Wf8h{ʔ8S;<'̣](sZ kPn$+kS6UZs| ƤL*@]1,=jh>$z7n7X~ˏ?>;7ZO,WD$~1 sk:[?iL#8b>x7NL[s:[r ^ Jl+뎙K^0Lm_h7#ȕmBrDޯNž]rSzWO)Qf t]%4KkB9AuIVҖȁT]c8:9e\,<p HcrApg Ɓ H99y,C7%-T/igc߻ .H'q '7j2 ?<Gܿ \\Kq;! =OXl[ r4rDr#*2`urﵶjcQhiWճeEU.1I.jPEZҙaSBOr:ʐk*i;ܻ{&rJ$x,Y_OCdF^燡!Nt X?DzvDo?:L x[zw+ jov!^6+ߦp,8Mb<0쀯>kIff~+ w{'=}  Q@u\лb9*P?3ZF2ʇ"3J 邑YӾ=y5#W2Z@o}'%T|n.E\ic;6]Đ,YXfh4^tڐ_$f1 qeΈJ+ʩG}Z9A4Mhs0R_/Ɠ8%-բ˅߼wT>K_T-փ#/rj>8.ѮV UΈ_Q 8^82+~4!ӂ ~%K8J)s:Bi*!=)t_?g9TVȁH1TCƠfp~IP)`Ɋ;@?u1.] Q_5 {@DwdVb:\r RRILҥ*Ɂť&~[ӝ6#V3T A@r"ֆygT T&e={,hE=n?ϐ&͒ P oX%TQ^.ne0e/+aKۈ(;5+w(#~)8Yl!,F6F.!{5\6 VK#¼$3`abF,f)2O۪8\QFn lbа^cղUf]?]9i(wP`K-kѠ"`MW| cl[8vpkilkY2\Êx'ٺW md 8jW/ Tz*}uB4!;l@C/k˙sq}5i"T$xe>,K8.;:tI{9&txDxZ) )YC>-)^ҷ|ySCg1 &; =+cT?(?F<@\QQ4PLo eNLO&BzUƱGq&4ZL(TEQ/tHcBUS޻谢/shRM }* q/dO0 y듩F].vy)*KO!SJg3\O`:|)IS°B~]n_'`Tڀg7=,(TI/ Kyg_{٠Jvwج0[$(% v'n& N&ahlM6"0b FHM~M!*uP9aPU607m#Mȁ 6 pl&'}Ϲ\KDsN*7q%EbdiY7h֤>ɐO U^ zv!Cas"PCWs Z0 gTo+DeƊ1M _m B0t0=VLihS0T%B<T L{;u ^+= zۖJV|eIW?v~?5Y5n66#>v 䦱IO=(#UB-yn]͖*=! HtR8a{(וJ(zwI_6نeȔ< |{#77#n|ۀg= Gv"H TbE!N[_[$y"Ep@G|`\ۙlA~6 ֽRNbs<(p֐X7B\݇pUn+RE}q}mŃ{ 3T?T4mjH4A{b]*K3]e-zjd\|a#|'0N+cq7X#=<\ZE#uFWIM=.4NUk.aG"BEBm+] p"{#^$Mb0 &Pkur*8O9TU**-ٳXNvƔvnAz uu9XUF~JJĥė!VOeW-L(R &'gR3ǝ8ڇDvozEZ2xkV߾|̷3vO.?% սy? n9445.7C</a 18@XX^&I@8(xlKH yiAsRBBv^׋oUʪ'+bϏ̾7|Ȏ[+#-Az'|v,9*Ӵ0+!6j42b7$ۘe3cZs'(K;'u<eUN*Ltgy3.v) _^W)1p X `T&kW.jfP֪RU$JZ[B{ECek 9A)׃m g |׏Aw+51Z0Mf=D tfȞ3'd8SO~6#7P*Q!ٔI9X&MU>VX᠁7%&u9nvu1<<2c% jmm~K 7g @,0kXFK`^:\^ (GfG i'dB]23~T#4OCO4I\7xV9qly|Q=k6&V7M(@f>T!l$Veڬ.ߦiz m􈾏vN 5OG:-gR> XU{15Pޅ"t?5+-"qN7׹x҃>We3L;e9m_亃wex0_=гe~~}`uOi*8 mGM?-={Sp'9q }&K>wc橄4w}/AB{êBOe \ap%r77 Y多m7mk!e]fX ,u@f yβ,  V7)Dv'~JVS! P+s"q< `]tiM"WN"{]&VRty f =TS^YآpZ#ԋۯ3cͺC6TIeo ÇӇXd[M!}7+B%cg]9<ݏ}Y/, L :3SKlGPMH# AD/KAWeD|vtM!p?kgY oScd$hB'ʶKݗs- }$rlSƐhxfgot!}N[?twbr|=z. @b }QdĊ3M}#t+i {GDÜ;f^!7/(TjoS#NJ 0%HA]w #n˭]Xj[3Mi=*OvRBEʧ%z %3#ĉX 6.;,kRj8Z ݈aяu Ɋn|h&ϯy̔i;KY2]g;;xz&Aӈ\lܣF[(|EcC3;?[,K' lT~jkNU¤C""=" 1<'i3MCl\9 x:4mGF5+|9=Ef%j'C, ,X,ɳ&[C#4d iu[Cb}@sGxx`KJ+pSyyG=psZxb+':tܴtzvyёF,"֠TG ; htƂ%CLMFDpLy4¥_[6tڴ y!~(/1dn"锰lhro)x 9j?] n 9._IήFҁY|O(Yz8HF6&쪁4lsVqsy K) _Jfhib:IyU6J¹f;v.V\}z=is6xXC`HCԠA4} 440mDi ٯMڤ/ͮ(SsDimfx o{H2eM"VYQ-7yy՚  b-܂UgB vQ&/،NT䐏!U*߉DxO$+* Y)5Mo^U-ZǶDd[o1Yl u4NaTqŚ>hL ePC*3>ͱW/mGEn3ZEuz^ɏ |rv0sPz9ryl;jx 9H+uKʖzRHn R4.ސ[q1kIOb+^d+P?#]#_DaWLZ{S8e@Jqub[Ny4bqU9E7妣!έ0+6qY=Lm>LYY8gISO$،0SČ՛`2Glp?F6;m/IANahoRa>-dn.¬,,v3 Z \5xl12F]8p/n9Y[Pc%lylf}҈K2.Z@ro˛S[Kz{_uVd$gf--4׬5Gx^k_W2Fۭ+W+F=kCx7t%{Cq__qjfE 8rO_{RFn1-Fy^q?'"4?b2U{ E϶H`,!}D4] rv }@󇸞{@c bĿƁ\0 D'\on;E&)YT&$Ez1>xo9ލG[D Sz@+ > Q[ 8o&Eo׳8BVFeܧ%o7j_7"A!XhMyn3_[<3^^)Ŭ;Wo>ӌ !O=?P~d 2?gQ8zdXGd1%swBAS V΅mm] 3q0S;Q |v5 5KW0ƃ_9$7KU*յLLB,Vn+(uPorx|q/N@"aSuZe [l?OguhU47MXB`vw`Bb6增JP076ℛ9[B1%h3T`ҴQLvw&w_R: `:iM HWɁɆ I"%ɾ\VfpbG|6 b3^'#Ͻ󳀍LU=xqhAWeiSN @BmHdgQho :zI! D k̨/ n8ʍbE ϷY^ާoȄ5?B/-,dai+aq;QH%3keS ;c@PFF~ b[lgs`\Ip$k4v9wSa0WC{+.` k$]sVU.JBX*԰ra#=LIu~/b r՝-𡩐ZIE"܋jA}$ԚVO;?Xie`Jk޹k})T Ą eeWyݖU\o*V!)\IYaYb\ra D'&lroj>NUvhm~.*Ē &4az2XU<\W7<uVHplΡVXYXQ3/k^p@t-E՟jQΗxzЕV-27͐JR4ΰrPs Z3I&ݚJ@(ŋ.;=TRE6<|{E&l$3 jjUzh&JX,̝_/,:6Bb:ܵXqO[d.jx|8rD@SƥG}  dg ?PcyEGQ&3uGK&$sD#1f戴Ε}NFb9F>>piJ`GADOoP0?5*iR.گ ފ٬7WGc^G(ֿh*W%* -a h@R/$E*& '//w5FB'bd a0!qC3C6`q cg$?( *+0{*blRF y Fċ,Qm<.>1}1||g;SV܆f ]kqF!* װ2ThHtuXYʌq=pl2;A _PaK(ئwZ{V FE{8y8nQOWN~`lAtkD:'${`hsqvfeGhgD7t>J˱uQJ-TT[7pwŋ{~,0- y15h|]u1zv+w"NjPg>7>(),3SJ O957*~Wo7\i#x}t@*p[Q=:]h:mQmq+^-(&гjF.a})^쑭a?[/cm֩FIWv$YF9 =RWbʻkUHR媖<9oeW{pw3CvSJA|߷%U%цz/$9ޥMvo9wxfIۂ"{] 66´B8CK)67"BŒg~cvl8׾9"e688@*d#v\H"c4.fP܎@C驎PS(JEt613i]*6|`,<-4m࢔r=;2yS[VBf\h^+aL) :8ѻ!mԨ{`e*ͱC_H |aQ0 )-ݒ3 ݂tII#%%C4ҝ%-HHHHw+곿~c!Yk-yyPaJYICFu:U BP"'cߐjaUn0p{WFl}UJhݰMtzFh*ߚ5jǧNC ѳXbSO=!Ҫ|.0qcy 8Q5]\QxIʳiY3a9,'12$o' h5w}9U ۈY4 ӷBG\SzQxEJ}:,nV˲=bwk3h@1v K\cՐZE+ɷXч?4LPNY8<'Jo|u`Nd)CF~;⢑xLk)R< %m,23Jĵs^7e7ׄw2!`+"w k?ߓuWz|ʹNJRʄ5[@ \|.rMzgC{Uӵ{:@1B.v¥z>Nȃ:cVK{^,fE4#E> ''̅/x |OٔWaHbMƂi]C5ĉcё@0c`|VI/Hm(/! U2z8Q#Vn| gA-|I$!:>(|uww)32uiL FB 8 :woh6wӦCe=/c okx_4wa[݌@gJ,"id$[3:B?P!Ĩ]<C0d9A;tN4dMhig'r~|_èAL_ _yG؏]%5b$PC5RkڬdIgܸ8 P3bA+ RA&MYrap1[j`LO놤8y˥._y|FW#N<:}rN'FI1?6ފVFwW@ET0sfPpe;l|2,mEgS/=\׫,'"]Rd7IK$W? 2.+vS^9F6W8"^ RyVQ<3I'}dSxn?YuX&dmK브ܐj]EΆ[|Uc#h𫝯JuU)oiux2(N/q8p`.WiKּ}ӏ ~ -|턭]9(kaZJ,%ghǺzԵsp(O EKL2}m%jƼ&]X3HEB?-!I3n=ثuc-Jx_9e1ArF(ʆHg0KRP8Q)߯K쵍J<x޷nGFOAL4| 8f Y CmQ|ն#Es!>pqGZdnMR:Rlo!GGTޱSyW^([sS|:HE؛.|"I/wHؐ=7rߏj~VvQٛ2S)m^[U v iIƓ ćEXxĊJ}ƨ#--?R]wn\^%T%@C6/I&Z#>6epXH)$#C#(":}ӌ`p'͹Zif%Fa iqx5'oFF͓W=G糢4¯U2_gMwgY+X9-F0yMa g@' Aw͕%3,QL4TZ 2Lsu u NUNЩއ6Q"c LbkG:]6&'ۖlFQOl>Kv ȘH &8V򴊈sKWs}Ia J>dE\F2,*vu}N Îe=cRgXǼnL& Dl* q1F ˶D 8ǖbaۘT+Po6SO̲wf~g66-~ŭ%uCaQ_z\5RFUU[*/6E<Ҡ6nsEW{Fil ɚ mde%el(Fq] 9;ںE;evTܮ!VF驝(ʮd (piQ$"w|,$7Zm\IZhyc}T/=S޻½qEO1]T KL`Uyz{>Y+Y y~W!ZvPJ_ "rdZ$Z$񚄫5x< 8#dD`!3@r LxAB x UHR5/-[xw';{ ,p;5ƋPߞ>l=-Xa[h#ihwvGBmBinCn{%T?f etwcjop4#>o> ; A$dH8n^?; ":ۧ*Kyz`L.DҜ(m@^hGA ܦljL|>d<ODaF 3fLtvXq=&=?r}i~~z_J9~!->1"XMCY%}.َIce+[>  ZݔcU]sD׵R-M3;Y>#(XOBThdp9ԗȺ!= "5MO^T'(&]<%= :|LEU0s!EK0H<зI"DHi̥Jޮ q`|:D$[%#ȇ!|L\p/"V/~|/:YWAֈ1h*lwM>z>!Y꺷ьXn6-xKXt%*SC~}yDY4]><$;a6x1MLS)Ds^i$EضUJYIb{Kh{G9_xN);%sJgEwgńZsań_0I*(.3K Pt-H?k9xJr: VfJ?2O2c6r(t;zK0-<lNoFnog$1ed2qK\!bc?Vy"ސY>NnpZeX\f`x+˽Ƹr=3类.yP -)UcRɘ 6-]vܹzbO7YdlȐ.+{SpW7:&kiȄ_=Ò3z_q9-umԕO.`t/?+^t{'ϔ Lp-3a*-(}peX 9!Xф%5 M*^y#M]0:=8r#zPѣRlo}"~g|TYEYTyⲇ{=4}\Qhڹ')ѵoz:`B8dkGG16!k,` whipdyHD4Eh4 D +6v)'цr t3Gtqj;<`^~M#^+5inqCyV7%A?$ž"_̎ XNi6n}f#*Web+!5"+BKh^Yg==[9+xa7-PĄ .NмJ xLK Fl"wwLoK(/HHȴ'$W:8.n+Ɯ$W\mpVc+pL/k!C8E&F*0FPP߫R[djb₀;⡍E~6fքUau P*<;e<75X9TB+f*x^!SILy8O9D#p{jIhA"ym"Kúš/EY~J!|gNlGVy,:);wtq=@HpnRnuc9X 6mqϗyGjRk3'N2AV\dPm|ӷ&}[G[1&zZ]hvɖDYD%+?㊉q97[M;#rO-X*X`!%N-ܕyŎ?Lc+N֎*Cҹ' abG0|CeA=ޢJy3 MUsģE'ק92_e<2u`OI~LoXEqR%gMsnËg4K y7Su Wi6 PQKsRTJNt5u{-v)]N尬tp޽ӞIx Qwy#jٻ|ޜ\(n{EԽ)z2cz79nP斫OgF)]`D7۹3UrJ?)~r"+8n,'3Y&"]W0|{=Em:Ƴ(h,FǝYv'_ZiXTe=d:VJWuݴtifn;b >>v%h{o0r;I@,TN7+Z^r,F,P|r)s'ݦ6N|ڢT9E̮ni!Z{4 [^Q-3te/c'OܽIDX\~7FW&/v2n?;(m*C U8 S l̟!ڽ%%1y0N^x":JqHR.mhP.%qG.\y'͵jc?lX1FMF8=ŋT_Knӗ[Do&zEJʇH9lj\Rct'fQԴ\Ru24R0D#6jՄ㑐”׆,6x?^6p֔xsq]q CJf7zޯw)v%yMzk<ɝ ?谒1'[Tqzr0.Q21U,j-X\ȌʞeZ0@\^2:ɹIiBR["raKNI뫭Kӄ-GƩņR(hL{#nZuwUjIY3YeNKR oOgY',׍n8?>S=/ 'J[`I}>ֽ 9P28BK·F5}QWtaD)UiE@pIdnw1{m\}9^ԦQTM=Š}{hO!Ԙ^j8N=n{jGTU9X@i'/R? w+C6\zc7 ܆h̸B!tGfHVǣ}}IqQF %r~,s.7Ahd=6<,ZhViU%{:g4p-6V":` Z_nH">'/~BE'34M^zē+v jוjʰN)%_ە mM+8c݁,Nx][> C=B[Og⸖-c1F ?~;)9șԑU+joyBB.8k8pVsPpFuvcJ_t 6qu)wxf+qIySWtO6DV?`~6=|ޛ gKNkđ%`gO$K@ z?1ߍMMck%?lw@݃oi6H.~~Ha@v!E+7QkGyKf a$%*&wY >O,SŐzZ 0T]JQNuhM~ԘyN'Rz )d׃gχ?_מ#nbTyx%븒ZxRu(bInq-i]A^W dpXCy~K%8Y$`c0Rx0G Hxw, ^(c;h0À0 _f\< N nANw;1@@PG^$0$ᗇ0 Coa  Bnx p"w҉;]x)*r, IC#IwH?wFH.3CB@0e!Tn8n2w~F_eEfxwRM r{S0>; 4@  (2\ G}'}w-?Z~/7UwIgOv֣wT{p8XT#QI|~xD36ofA?#*:Kl?HZa ߚߖ`_sHj5RZ @\uI:t Atj+ kм(NzFӣ‘w{Cot{F@9Y#;v_Ͽ&t0  `8bп٥y|B*8?RwGHH@%vpA@zK;;@NÝm?CoC$ޅJ "3MThp0o6 C$RH /='6O5ze"K0Hө4\.QeEJ%.229kH!kNQ4y4"KIDȉQQny%-n/jsAL4eNm°68uz0@X M+)mWLenyxwdH1@kCD+><V~VXSU)e2_s\V9Ӎ/r|3 P~9Y]W& v̌=ݯ1!RZ(C%{fhw*盽pQonJ,= 5 n_/l.I>pÒժO'FO'u$9kȞ+ ZZZϏ 85L#m?L_4?|-)jSS;.EM2Hp2Hv48@c,\Rs-&JMHݡϦB>>H/0LD%)b&J#DmSy 1~QҏDF^z \: o8. UÔd]`QК>U=-yD1]GLfZjvm\~(x#aGE7K#2V:NqCCy)>MK(_Фҟ$HKA2ښ>*}zI7#e+92i[gfdz[ĦY|;AXM<06r( N/>L9s*7D3͗/0l`T٭/Xx$zGtHD{QfO(G<&DߋG$?7k3ܥZ+>w.;T];$}EDNBప*(.n@HռAăR{!12QQLd0iʨZzjW59PB;RZN!-m/@22REY)4G^c V[J?e'4~68TRL(B'dvxty!^4Jox1?YK2~ gR:seMNqq `ɨ!>p*=:U\.,}ҥUU+p7W찛mecrP?HF#Խ՟q>6)jB ,& )W*If(I. |uD?Zr4ކ`3g`%}a`gGUzŚN\XFY}&8LU>6Ğ\|̀da@`Bwi\ʓsA?\s6OzDk^6}/'G5@~1h -ӜO@]L % _٪'JH۳r#~,Gu <;ې [l$BK5;]'m]VÄ-Y-|@X=jN8{7.D_G2~m8_{PIHMo7&x%> LGnް𾃵&LX f{\t."n]*m{&^znw{Uk fog;`WhP,n#0wC@n8,qERŦw<'kH-٨[EjIȺ[HwNm ;P߂YF){f{?16G9Ժl콝޲bwOȥ:TR$=9CvGN$\n{ E_nOǖ0WGuvno fpS9INe &1Z/wR~Y 7]( ao1hhk{ ቚi,ϝ 0(Y~Xxy$a'CUo`5)Im?8W'هwcÝEMi$9LUуGfʯ;+E'$00s/e*'ǿֺ<f(-0IpA〞\ebiriӳ\j[/=JWwym*V_HG+-=K"Plq+o1*T>,a <XJ =B}сl&z͘USdGLcZnч2~]Ÿ[w& &">=1 me4 mo($wY p̒rk6 b: yJ]kz{wuYݬӶ֯CɵZB~ ZPN-mkN .<|+WG)ë$Xl*o$J]7~inWF^s slSy'a&:^\4"8%Xq5i]diĕIAX+D v2zÅ))a,A Yf^g'b;=*W+-_}0,zrOδfZ_V;sVPkW2Q Y7{[$^맗Kno.YG"٦ /MzH.4t]=Q'[rؘ%q(%|o&`鯒 ̙}c'kcB>X$:b(GN 镌ık9PDa@ӗ́_7XsdEҔ̳)jj!LB a $!kٷů;u%Ê&9MP7o)-Jq?^xkY<)w*"pxg=9oaOGJ.l&7~}Q%ˆW@~TBSn@c )MΝѡǚASߌo^r,.R@ 6dRu5@E~\ ;580e_R~F0J|š&=a&BeAu>.bl !iH%33́Q ?U@PE5AC]Al?kHU8emf( $+^=@a>֟pϽi/ϱǎ֕_|䀚h'W=Nu9,gҿvصRW(0pkC^Jl-Т{'Vdr-H,i$5FuN^^jfeŬpJU#pq. }]lIՊvOA3R*ׅ[rh9j5.g}?sn <|Jh+ c̊!0KEaQU۫Y<-b4od)(~3kc%nskyfw{8 Lg8!T s!<4p ݲ^ݭ)7$<@phbz<F fS]`KxA<;l^'v|¡T]3mi)Adˊ3\fׄJN3)niw7 *b2Ĥ/S><z∏TkUxV[U_՛I$=u<]ñ_y&LL;_[xOBIvє|de8\0LSgiI:N: qϙ2 g($WxRŀSZ6ISe}URZ8 ?;2jִ_%52z&'IiB:7%OXjAd䟒;, 9TV<[D<>qzsYY)NwM2W'qo(vK:?BDzP1VO,P9}X!߲So4"fb W2{gPO)FHA3Gԥhe4)OS+gJF% fh>nq|+V+j.ajv0 fF/`-sK$w)3LV#cɴ 3hl |2bP (2OXdm2D6QMMGt%r<YI}t_a*l?hd͗` xd/d(w="ލ +_":X9O=R3}aЦZf _B8]G5=sS>0}/HY:I0ej3ymϯ WK?t[ˎ:جt5^g)?u8QTf7wj$J* o;llfg?g`c0`|83_3P!ϖL"/^J%JnN( %q7ߵyfe=ln(o,٭4uW+A*l 26Kk}Hqc3Ϟ+,5@pKI^JýCW4٬WBX%EG%Gq1mZ$JA_r)q4O׃Y[ѼɒP-wn‚|D1P# ȶP˜Dײxg]ȫUNL9׾|ԡΒJ 6]nJ='"ᯭ/Yx?U  v9tA;j#0[vJGx1)~$q+y4R?4Ji|?6+p}}Z"UtTy#e}ܢŭBP Ն,cMӧ}t:A Jу0% s@YۅR < U־ XoPv1F,bZ?uN`8q1E=Nxa^ ̝p=~_inA"C|]hM`˧Q .Ãnv/IM Qzm/k4L,'b=a{[ e" ݵ㩷cc |ED?zkl?sU2Z۠jWˊҁW`§7 \ݳUS=p.S.)*0JM6y&.l5gʟG#BF-j;cӮ+N};P:oj"w:* :sc׼` ^S =oІ9f4 gyx/ */ɵyϖB ϐd>5.1;Br7\2ФA2?B9TU@[ $ C.?|(HP Btwz[0~^j` 0 10 t'B`=@d7Er׹G"9H#]o[)Y`-m)BHJ *5"tt^(t6F%A;H>p"va\x :.%ʋxOH%K7/ /t-67+OHP\V:*c6DN֟s Q{}ν6?ǿ?__{=4ɪY# (upLO&ȱը9jk/1ȦADѶͧk!r5ˁk$CnW(I~ guڭFms35hgq'#AMkqsJ1}y`I m-x*0:tԠj+`w)qC8xV{ɃE|(G/mlAJ;VM )SO64e5OMSR$lxEposj&σҘp C.r̅E+9Zioǧz!.Dq*}Ag$>)'o[Ir$! ι3w]`Z(29+J{dq1ѬO7r mo{ !{pݭ݃;7gs\ѽfUV_9ga\`|s\ 'Zr[^ז݌x?$j0\}lxH"ṶdLgaQȂ:i! .bW:M]QBya^ 2QWS YgerNnZ>@ } NᇳgŹxZywvT:oL,!)Wtb|' `7?b#ouR~! bl.qx ;Pm?];(7̂ /oʘGh'Bps3. 5 R.69g[m}ZV?c×C9Hl?Rs}veqKDRm"*(eYp"<d R(r۶+jc.a&2EhɭMϪAov Bph>,˧i7d(D|Yz( D 2%lʋԅ4N[ty[ca̘ B2s@n뵽I9O&1jvV%fɦUV;.m!hإ4;.=m^2$Ȇʰ앆ЂNm6C?}u)`A[J= e'nc1Y2SbJiEKڰ]l?3KZz|nm~}$&D*3`Zlu%+&%Ak .pJI>;Y&NX+b8 .evlqf;>Ԫ,!fWs8w9w>FGeJx4VJ:s~_iWeYHZ:>ɓ(eM ?W-KL/q lcM(5T?&Rѓ.(\uk3{Jv![lTp@b?YLJgou73%#6;9yM˂,=p.:D߁FrviC@>6v~b05\-XYHT9!r}uEE?Q^7Ǔu݁$ Bs4['!5l>a|ۈ݅"9Gbik*$)8yĘ!N~B24_O*f>X(0ϐ4Z2<"O}{NX.q#xg_N{whhR8Pܤ/[.W};X(Q#4{}͐05Vo gq]31, '8!/gP4m#7a]YazR؄zˡvF7 ݴBx%.㻩5ּ!ӨB\Vښ]L¾\5^"|b`Kr[G{l 4p򭙮xWM[`٢Ow.y` T!Ro" [CD%`_`3jD'8==q̚=QiϬ)||/G͏Оniѵ.i`-徦޾%'3΍p_eks~S@i ̽ϱz6YtRKvб?'%wҷ}ҎV/fS>TKhbh=̧'FD )_ ZE l*4"d\EGVy|>c/r?폃B~EqUU46UG}G,X8j *V\|PYU FI^=!kCmiMU FK%yў-Jl`"&|tqd2Լ9my[} \Eѕc$;7%q6X}[c~B4VrqK%c9F 3e`dY*Y|R˨ /ެ&]ߵ sl 04˼/H 7膿?xޕ&f5AE kLO';/J?frԱezR5{|ɫwg=,M _? GR;6 nn}m >^.a<]+І@cD1Ul;zv6@y$tiRIm1Bmϋ΂a$֠ .RB$tCc# ͵⅏(0QZH jF 5Ha1sAVd6iڸaE- Hbi }&5 #X'*WϓL =6 [7ercI\0$g͇.VB0RB%A#`rV,H|Ls;B)X?4-*~4m\[]@LX@ENG8z!RBUaJrCaoz:CH}Xֶ0J3qҦZ]d5iymf]A&p8P//5g*4CVz- OlF%x~40#u̙\bB7|?2ԚԠn0y6_t:}͟ .=+ Eɗ)IO )}O|g{3eyʿSﱝ,Be[sNԕ3u.vLtNEga ~b*lenXh{ TgH>Z}>CNٟ(d~\ Cib't& g8(n*H+=܁G)g;8hD4/6p`@v m"YnTO߼U_5u/w:(ER,sn;χ6dΎb!mFFC]xUMX'Xl @ke8$F C8^ \f]~eOPQ7E5:'6 $|5倽!l-d 'hJjʯ4v]\Ed}UFO._Bn$.RR#s$sK=|羑 D#J[NG`zs)㌻Dv`aEZ~\t~-3_qP9AHV_ CP,Y9sD}9_ă l֩Z/st Z$;E6|QKQx?՞zFa.tu F!өpv3VddX4?ĹVkn+LB ыAKn\2 瞦3Qa(7vrwo}!eHF'eUƠ|ZHxζJ6tWosC-I)Q6txT3BCL T6Y  8AZ.aLhYR~g%ߦ94W-0bb?ԷB.+fpFui+_!yzZY^|[KSǧ}iʹiг:3bi >ka~VOu^ `O'4{lH0kOR_07>e<"LuBCUXVcaL%xZ8`izwEor {;~λ*cI7ZZ:KK;z '<="I՞\ZFH o#5&Ohijsw\mоa'`~1BW1 H[r&9}9N["N爗ZJCn '6;ltJ$DXʛt~~.|hlxJ.JMScLkBz248?sW0nB`Ø{,5N E?r*TҊU"]!de"lsL)O>?M7`c5n;Ehjח6~wdNpk٫~)o \N&vņT cc_'Pi^6ΆP@hc(_F|. YrMFC͢(+^NMe'FVNP6cyZS+OⱣ9Wv\n`pL#sRK8PeQ׀vJ˪T该}y5*u b}q;G+)/!Y"_Cqj^fJ֕br(,sgR>,D\xX&gЃ`7Wx?:[⡮9B<*`]uFǫu~xc;eRčYGm]"afhFe`HO͊OꞠ]qGb`ByrE@P-}+#P|~+xw FC/18$Bؾ<:dYmh6=Q=jeN!cfX!Uds㎃qmͤYŸL݄<#B`U g}g(*g L˺LAN.7rV+VCXE uȥKV~cYS4`h:4Ő|g@DB}^@N;A/%(`ϑ/a;DTE6{qrWݐoy5;$[Nө*řIt1B^B"RǃnSG?5\9Gз?e2V'ԝڇ ZUT$h?·3q6``HM@lJW/l5Bj|\l۟]TV c!ɀ.GO~{U{7')3ol~,.qi5-Ѻj2"V׆'\ I|!zgmYQWZHݍZ/x)[? NN8 8S7hc$ %?r 8.W_IDA&xt^VF 'Sw X ֙js d`RX>U8K(5^=gM7aQkĢ9;OPēR  @x m\aۧmJܜǬp;#{K;G/'3'1';n߻\ \lޕ`8f&fgcab&fd`f+ې5|1MW(x@`РuXHL" څALA _}~0vqrÐ @s>&nοv?yדÞg6gv, PW / W#סqq+F=ߢ;A,Lϒ[Gi?@)GWsSeX.ŗ2 " rSr[s`q摻ϯBj0w5Z%&m1*s#摝P*z[5Cyhܟ,;T%RLEU}oƁ0Jm 7F2pKA*keeZcb`g}ujA)oIce9Z!څᣕ<Ͼ# sDbKzU 3bi ͏~W:=vgA-!+%HNE&cL~V ܜK 84~eO{Cjso'^i?ξ5Tb9v)u fBJ(;)B/>=@c S?#ɶy<+UXέbf4TNg5pVh_/to؞58}לe3eI+Jс`Es1yʻ !JN]-bjҵO-x2%7'BͅMOt0l|) E:6<)sY~:clE1DogsnpObp{B[F{ a8{d@>e%j7ukJk+(_Isk?rLrOja: [q.٤hE#s4LS&faJ=u -ZY]̥/"`DVE:(iq#!}G-J?9> i9 7B:q7=EΖlgr,aU4kIV3N"h+sP(dlq'Zֱgv?! VaQag`쀮 " ЍZH rgWvy/?̀Sv8:x9T}2=}I~2Q[z?\>  >+5V\QL[h<]6zQπsP'^mz\R$zK.EҨ2 853BKubŏ% ;N)T%ZѢewi~5x$T8Uv`6SWjwUCtlC(G&B0 &B ިȄr _Xx HlAR$٤3#4TևێyBst\3ύٞu9Xml*2 (zrf0XgZ9x#th!_lnjݙS"_ 1A}MN ?ZBss1zuzGlܪL1\xmojEm'I&mEh,ez+!yLIxwғ'Xqj󽳎cpG&ݟ2C=!96Y&6IA  ȫ?#6ƾNWj]=0,Fт|ޚFA#S,_mW'Dڒ1̐ #eoD*! ^R,AHD.$˽N#F- ~teCRPA=bJٯ'GcqhޓTu0J j>CL0Ϯ=p@ϚhޛׂJd#drМÑ*W8IIIb'1JtmnZo=g1-SUL:8H~>&1K;/< bV ZLi!$/)a qPbi}/:$ЦIWܚ>[je 1k%4dhfidK\ך 2Vǟֵ34[k~dA;RWM*AJ7ܺ}|%v)#˹߀q<| u7)K/w8+/ń{Ugǩ]%W7ƯC՛4 HE};}OWɡ7Ǔᚣ0)*#r[-9Vo)9R̶-5'۴ %7'7S;!`ս4{L(<-״=n,ʳwW5D͎yw%ŲҜN:o4qOX ;|w)UO=&epIz?w1h*(<'A즺B!E,N/k-Wդn-)XFV;/STꇩ]KB7&Uy%/޴R'cwOT%RLe'݋%cMC4_s/?6~ކ\ X~RH/f2ւ2>uJ_6ѳ3?'Tw{F%ĤCd;bCXA5<$w|J$kT 8W;"2jgz9α?ī vԗw>aq.U8?Y,@˳7Q | `JG2RG\J#I'`Pr!#}Q%Q(ofϤP'D+J7f+8OϏ:a0\%ݿic,=XD3L0@2Z}Qف|9WYr`v\OCZY f)jLagq-}2++R\- :)<9UUJ |<5mf3\6 1 φ.;r Dgpm~ڲН(aܹHI$3Ōyw"Lk!kB jUbJ7 әo:Zv_{lXd$b t<0mBgVOGc3鏈!1VmUSQ0\ጐTG w";sG. F.p#p S^2njY'TQ e/#&l=_}rU=QlCH1#&kB+0(f}m3x|4A>BOI۱O]_suVz^,s"#|V$M0u~@%Yd!* qk81Z3@8=E4U$n3DUnOAoY0+үZI~eIN1H\W Xl"FX]ƅRX4;QAV o0\>"wIE>;9Ō|)3yp + ~ z4+h_[.zr 4동C<6Vp;.11*Pȋ4ul` Y]Qx9(ΊƁAi̦iq!,Ixnv5 }K UPOcE Ewܔ(G ό~wfd]V۾Q>WPC=.Q,?N'V4s66kBTԶ ATKXΟ8QVrߌ`nsHߦ.fquW9mG@Dh+? jâB1ɗ/ S2lSTff]Uc gN{)o~?\NTdn8c1c<ْkO ^SN!98%z'-15g'[W$.SKfiI]PkbD< mխ߶Y\j˺?LfUD, 5(PPP|(fH"?>4w^-0<5H,jI._ ]Y%8?~\{Py琟Ta FS Y (iM*Oإ$-:.t`p$jzW&ݲ:,%R$уs}b_ ҂ p_Nҕ>l8=9ߔNLWJYVVvk OWP~5 _SB2(;w*ӿ:Azh39 I%H5E9V/ez-D2-W6aX@4Vȯ6ԍYlC00.DHd^a[;OWH wYμJwdQ|ӅH9b+HZIwVcSۥV_lg%[Є˴+ZfjSlp)ݍ-Tk&;GR)}|'Hw04~,bŅ6J)xȿYhP]M$ۅo6cGN`Ⴚ \ Yp}1 qw?* Y.K"n3qINw8{{қLYXLUIϱMTR3RHзWگ/JsL$ ޮ'sF&KUy!Onƺn>Gnƫr-|r?@4= Fz辝Y6Tm=Z\]:5vFfPbERU ܴ%v;UfyIYxzEd@{Y.ޭ[G3!? JV| ~5kss}~@IW?NJ.먤yŨd ٲijXz?~(&d-egJ-gKu -H_N`.m XK)ɣv^n\f40@Dz@Q6-|4\|Ք%3F i.UfQ+كR}gMD]fxHwXMDbYJ~MmJ$}Z3W"2XҐ+22B+AE Vr+_4lC5l(%}P\'h)UHu]4R6`8lӢUFHe,_n8|5AuR#v(6܆~pH%Ql1[Av fB IRTN8p| d`㋨,rt4-m w%f[R5=0wOxgD0U{u%Bq-dz=ͅ鐻 4$ tМC e>諲B@"eLwp9&6ae <ۺh7w#*o *yI%':#1<5gd᱂.Fr7'K֩P%8ژjb,d`]j2iI.qp!m|suԟWs0;NjG:O[Iyq5:SwBs+}"nդ^6ݡwCfJys{nn%jV,4²|LyOmRnטW>!ȫ'&xK.Q51aUZ7˨=sZyNL Fh(9SmV+QO;w:&br}zRnpnazD{h)f<(۸w&j+Y~8c#ʙT\7/q8t?$yx@И px,&D3315C=j`AЈPf_Vy ׬,Vsޯ9?~N_,h si 2 ]4ҷc1 jesE5 ƷgVmQ mw ߉m'{dfqH4܆*[R]S5%=?4N;yRW^]!p` 0u{){CuB팚!(2!z!L@"wGb#p\zRc#6\ȌvEOu&ǐ[P6p[Vj2̀\MNoEu&lO̢̳?TjBH+S-"YIO5vM` B + ?ew|ƪ(T(%ױlG >Z|3K U6k3u y7KL.^y6=}ta# tX,[Ӥ]9G*r8`Ex ŵBo5a RJB8Ws5IVf왞LL=ؤ@wߏ/ȟy{9THeJ[Jec2Nj*eϬAry~.UP?5}OՏWv2lۂh:͠~Ą{yxmo&gpf _b=죱SQ>l :m}N]P)08ʂ;GsMќ|Hr)p4ˏJb9km 6W7zub]QȴU쉍px×?ϫS*cwb0Q,yb>m^ǘ*O:5X8cxJvb| [8dJ[[>CGŧ~tgF:I-۟=զ3g6=" +1fiAo0VJ]+aAS3Ű Â(d[LL'X8qen?طY%YF ܦEs|)3 p@f\殠WÐ>6Oe~a Řdxڍ "cW/W0\#{SVq<3.o>eCVؕmw4`p!3aJEވdȂ` zzVxJ*[w-y[ӚP-bWCIDw 1%Wp:VBuLK" mUN~"é] 8ڡ7+fb(3|NZXzN˙[*@]p-b9Bze>}}{]J_5#_1aZ@ ӂ(x |>*_C.#d aN k]!'1;ͨ|I:A^^ 5&lj3uht_%ȟtܹݞ"h.NgpnK{SToYt+qF{9Kczњ [o̐;1S8]/uIE?r^ك GBM ZĎsNH~dilUi1M5L/»ȑ@n &Zkc{kZ{rwo,x[6g1 6ٺ-3-HyXi%(nst( Z~?cwꧠ~f|հW8S<ފ DO\5Pz-š[KGv)vf^ (]&K+ذH>wƷ͇Ptҹ#Z#,D?=so8LcLPƹ_Dq%:!g=e;oX#:.XP:7TyJְbFQKOaѷC]L~G3]NǓWNOhlCh~RgEDނj$/!qCŮ{İԧ!N TD,S$=ٞ1 ʱ(;4޾*?÷ZeE>HM/>@CʇSSHsV&v\Sٴ ~] t AIi#Fy13h<-AnB=LH$J+2!ypŕ*x F`6H8S| G֘$qJSW:e=Y@VFɡJjd*u*3^7E|g*=,-,խ *8.<é,+[ck=ס$@af;G:6{oT#~`?>7c&zed"82ZZ6Vetȿfd@%%ߐW9i4sܦ Li9r s\9AĵK,QeɥG3|wǀJ6E4p䛉vYx+_Q9)a@^x/Eؗ/jcMBB"ɀ-fAs.EnNedOþ:6k*NidLJю(tN 5.3 {5?}M9e"XeSq= iBe8jkL@i -O?HʰnM݃{!;!Hp4![܂ !''̝jﵪv]UoZ*\G-<":C4*&ɓ'KQB1>d7[*aT%?0lBφHP}|cMEA!^s^L?B]~Y\n}hכRk-<V/WX ɱe'ZDtڠ9,e$R:ɛ RCK02RuNcR}>Y~ϋc$HU ve;)\vږ=1jWih1%|LS{ lt/%y+ Mzs`KOBLC*rWDO')p٘c\{i=MCNF{_ s~=Ex[*Ta?Da`!x%dW (A|-U~Q xP_Bnz/[fnDrf7sh±Q8 0Զ{Ejz^m#;%0lr.W 9DYIc;c *] AMg/{Y=kf%|mlLG2ި74LU\1ʃgxr8wRC.RmsZtQryVp Ҫ.yKqx'#KNgZa8gQh׊hykͿ,&(YqQ[|Hwr׉C3 rE3MkS' n}ݺx||>kV,c̍7xיw6s2gY\"8.&Jyڽ,uBBW,`ZGLFW gt0#|o- q]db{>17?0_~P@i@+btBv kfϠp:^bQ}tU6OLpPP-JU](9 C]{^mj+K.>kㆆ+{.@ǫmQon*"lG\X:og ;"},oCQ )MDt!f9O Bp"CɥZbnj"Q PYa7sUUr`8A*oOLf&e5ˉoHeI`ceUxmx1oeEik|q)٪JB%V V4 ^N͇`,w8oR,2AV)1-\w4 xco4Yʄ߭PaXl2FwbCgQ!t1^pҫJ~m"=VEW37KCT?oR+`0;)F~JFڢưE2`qK}Hu"b}-K~q -_Z(kn\p:쇞*ʹa^)7ط7d߫;I۳QBh:xRR &mƸޖ4HKfNހz?3?!Z1ʿL5#ѓ$1x|V3!JyfY{zyL> 6pveڕ󷸼-j$ eR30/!"p=1SWh3oUpu3+lrCU?sG/+ڏᅜD')c#|~)xy`n Np  \ _a,*d9#&b mz&T&JʝZ/&[5A,`g8Ц]0Ge MKx;ɳ>1Օ=ӶhePM/5ۚT2љJ0՗ ]16LS,z=ϕހ1zL.i#XLJ>qu޽[v{>GzmQZ#S鶐x(bRbdE>\blFg83.If" Z36 @xNR0YpuF! (+u)*_̙Q=vL۝i@%F$=_ONqVsΩVFb=(4R-6. dU"(>d$K -O0=ԶCPm]h@)Wm9ZaxiiqWby>r\@X(oge:*ƩߧGC>IR })Z5-y=H0]_y:~Zj-|#cWBno2cyH^Jp;jl]!9:zuP3s۫xM.#^Hc_7.Y,T 75KW8 tWQ~֒R(^רT}l A|S+<v ǚlH± ZܵJJ0#_U BX8mvbcs}_U{NgT 9jDFG ihW9$!B/@|O Ovuy$8/bB3;mFSR V[=S͛-ty7xxM~-,'`)Z',>oBm;8}`E=ӧS#ЯYs%.OB>^8Et/zyʣUQhƔl[=W %N'n #:;0ҕ1>Q&o&'yb"5 hJ<쏘RN"t%ԑUldA'=,K)x =>D,*h|\"p :Zp #Z vȰoR@aSm FXdK a *՚{uoX~bH(Û .4[c;>0w7B05.#(R[=+\sgni:T}BĔzɻy#^ԟugIj- iYM}3r6*d{>תny X2Q/;]5N] J0C'usίmIZLjVkZP>* o-:Ԫ)&T%o Y5po/cx ȰA7-(x<4I4Y~mmfa4CT*;]\QZKP[Tu%}fK2֙!*Ο/^a7']qש $fCoxWF޾>MOv"ac"0ﶿ?#kȊxL+jq8t. ՏE+ ĬwK/bk c~gw(m8fN[XF헢(;n34@l]r-TE8aK+$֮-P~C$e&OȫZ~1 S8R`7,^LWLâJ6+EWU,5kw=Clkjgo c\o͍uW}{L$g?FwR՚4?`oәM' dͅ2k8gar,|%=Q]/0R U7~UzP,u*CYcrsyA׃H×v Q5/['}yWּFY1pY Ok.zqYZ.`Z,i'{ѾN bխN@%Q207K]39SYsӡ-z\oJ d$~3y9neW, lG:`5j%auB2LVgzXMTŪ# 6X󶩜zeM7-Cß!㒳n<@bp%+jY;MJ%.1ti>/.1v Pv{O+;7)w ? ? ??ʜ9(sQGoW'6m?\G2e?<y(ozA ] S 0 ~`A(65I|U k` 9gT $@VH:І笘dЂ-"&@bzl ` GJRc4m=B C4М/pߙ#vbXw t>Pz~ ! \˿z\ {ON:z. B#TпGjqP!ǓgA>d@B X<cۖm df\p &)bMعI Ñ^bz0CaY~{ %<0௫{36QC|xq`!п9w=;Q Exv|'#v=( .@G\Av!@ s/9a &а*Q!,G@~ο9캿Xհ4 m}gmi8?]ۃ /Ny }E$HApjŗ`Ztc.Վ֓])e0ǔ=*nӪ } .~uoA\c"=z6߭"yGc*L/ӛc w`;D(5Z SUqVdžg{Utr~C-oo0ht=w|13Ch Egk&`bˡXgw{.]@.^hRۍa*~WRE+`\J|mrW1*j g7@]vNU?ܳ]5&Xp"a֓!6P58|Y[ƣ||";77U$ H _[V\@1swl936@3֭;%vlY ?Ydp'ݤ!B,(pQ]y\OX}_]KȿՈ1|?+=njoT~2X7|̜!c=w1 B{b7poG'h1.I#6;3Αa lnc KUOLl ›9XDazN]:!fQV[ODr ǘ?lZ|9Ꮪ R }}oL?RvuvpUX<(1Ա=莻߻d zNy¥B _Ӧ㚬) g}@a&W~mJ%/{;Q-/)fBC7I+̷e%=to. .B ̵ k0\y0 )[(Ct#ß1 %^)(h!Lr:uSٕ3cIRT{&"C7fS@ ͐%ua3mSqW1bl@ voѼZ ,2Ei͂bs [;j3>P1 r3aSd[R@}~Fh|fCij)edtD'F*h]v(l€NՂџWEu^ f]δXiӐ&1~uLCVo䋙.:0WhAzN!$y1nV;6A'Cf cAGaV/.lf2TMҋ1R:MW81s1TvI!m=+E㳜4xCFJiVOL aU Ƶ઎ګ;M4#?D M2ZW^ c%U.4eQwn8mX!aG#0LM#,}8|at&"v7 4A)FUK0Hoᖽh^ gY}p{넕c"mt?4*>s״$HyPK\cINܸÎ'~Q2W?6|!'4vmoc?cRo)?& 3'QN 2o3<'e˼Ec㪹Tq<˴7ɀЏCWݨUlSFLًa"EQhחa0IfXA|d+‭C(Yi?B(I&ڝ5O| r:Jzg^45iQg["\\`T>ѻQ7>[҆OwVNLݟ@3 &>kW'x^ð$ Npkh!G0X3j !=cбFXBs4DuxO`?P1 . I//*i(Ba 56xcM< 2L5\\N?}G׳j܎(c<\l-^OR'8 9OA. J&+hl{ѦS/&gVXk.x8ZMB,}-ADk.(ZUʴ'Me;zZ/ҜR\}Ƨ}tQq   fuZí#ǃxN .n`?6);]H ܝK[>W#[t(tvLY9劃+>B W|'Kk8*jS!kkGٯ@'J?dUG{ޝ_[ DT1U΅E֜*1EϻkN\./6|9Gq["m!hҔ#aJJӅ{_Z$|] } Ԏ]YwDͿ,"wNG4fwBo:ijKv'z"$E~ OIlK?QOݕ"%,_<NX( -$IԔJZ7m?T)Z~F۷'%p`fbGoo'߶]84WQ isS(%/Ws7c-見Ȯ9"cmR;JVYHڎk팩D -y3."|/޳Wx 7ꪊ7 !;W9t -͸Tx&L^e,hQIpxGB\E7_⩻C^Ows~/wGǤ??루o}l~u$#rT +ڄqh Ʒ]NuF ^ivvo7.ZSDp4H7#ƖX eTo^v1HQRzYoNhooXɄQEV͚OEz[ǎzy*w&x\BQDMqfש 3F[t!tM:f^jYÙuPk/vב2SF{q33ƵyWh)Lr /.=M5G iԼ$ UU"S$߭ҤOdBd^nǮFMt:,}#(cdiA" qx zKLD5hs>vdEѠ] k8|o7<{ሼy*1  zU,ۘ:at-2c:%Al7ߢ*Tm" y&T^U^A szm xXXX^k$hbuw%#bD?=~F (<0PO|'T9|]Uxc8& u"TU+i&EM3I~u-Є>_ d)H:1)Io1ļMuLdV?}Ku e'p3sgk7{wm~alK,ƽOQ&֞ͤA!TPĞXҭ7oܖ{yt?k]{;kO <,}(y|ꊪu U" !ήLh?(^.? KA*Ga #-Ap(rYj+& tuvW]A9ݘY>v#1@l)W AKHR)/U^_# mW/YR͆PJ6eedklstSs^ϓYT5<8ȰdָH)NUu 8uˊ*6;iBU9].]gn{o-McwT0me@e10$/C!fed:*v.V΂ľR: /:g魳vk?|DݞVniY< UǞ N{x%^Ed] 7k^p>D=cn;Q!J.䁘g1--Z7"!%y%?xF^L .r638מ%ۂ6+a~?`a-׎צLt4CtPɓ7  8q5kcпZOA,?_/O TM Npx윬<\`'+/%xױ(\\gM^ ܬ2!Y &04"PRH4iL""BР_& m5Т5  9cV 4>$kb@H1P ^agсlgKDM  2haY&+8x;*!YzQݵؠ-D `|Ŝ-GS!Oa#HDW` ^d@{nx N~q~xDĐ{ ס|Z>$PajGOVT~ž֥MFMlc">2GEH~h{Ԁx9lλwuqȣwek4n0+t+4 ndj4sjȼnTCc֌t5j =!s #qǃqǺģ Z@-pa-#6jS Ə /F j $oD}ܱfRȜ[ш'!y}Saّ^?i86{yiIieVQ; r‡ J[/-{> Gͥ"Ke!Ngˉ2,YyT('劌4I͠YMlC)v$cZGDtrb'B8,˃w%6hR:PQ A q~q>WHUܝPdpd%yD+&I PSp{nx~ǿf%(HDm57L![摝aIWr8$2QQL_O5r'5h⋱SmD`an뗢Ryv\S?d'/..^4("@Ln10x?8m`Q WOث"ߡxq}D%2Mg bv\m#s,K&l& &hYUF,--gWwnL]MI#eQU[2RP1]m R[L6\ĺsDp:~v/Us>w(ǧY +Ong݉~Mc&4`I HOifkDc)v.(ӗ]QE" rm)6W̰|o>a@e-'Jr>pZih*]ݖFv$}}Sor/<|Ex --S|zqu$Lnjz}ֆlWU3%ġ򦥳1|#crȂhi5:5V?)IԸ;tU]9(q' B.=O\'̡G0`hfP7n/щA^uH@h?Jt|$ȶaFg5\*ey1&Ͽ|<||VD"}?/`;~"q8̿1\&k8 ?HϾ3D<l @H"3b-aeChuX!sxS3ׯ g\A !NXM|'b/ba!vl@|4a{Y ga_R/XC `F'$65ggK %$kǎ<%!zO^ %I&%>V5+{MAa8`6i0Rk/6 *dI°x}d7RTQD 0ڑ"D`fPj8XLV!c@l;l%,t?E<:9Hޅ >S\vM &ҍڲU.T<.kpK-AUqF];WU:Y% kv wr:6CSIIkҁNP|8AD$(kp0_sj*~jρlXp$IPu^.ݦG^VEL%S cbHwYz pf6WH.pK՞ VHL#(ߝU# D pO&_OaP&k<3Ѭ8(!NU<0W=Q2Lrzg"k֫SHO /dgX2e\6J.hgnˢ<_(Xđ[/šhu,iXvǨnGq}8w'.zt1oK&9?Ǯf, ]ji`MNM6SnB_ }8u*pnN6;5iLFT7V`ev}=\"\ԥ{1Y?peby@]ͶAl/>ꏨ̢FDo+ Xhu 'P>-yAO+ ?}Gv1Ek|TV1Osm=0׸Mq#`W4(6ؿH" RD+v"';'"F뽶"7Dw $Tל2h *ܸ6qqJq:@Z|6㇪6x^k<l̫dLʼo-V|h"ͺ_S,U8k`<(dl տJʘa|sEJO)R|oz.Aeq@?Ee ^tg]w祂Η'!;Ny+qjU.fS5Ό~Y y&sBΘ1 C7.^c]z~\nU65j==>0aېTR\߰deH?'oO{6qLL 'ˋJ'`>w5`<j, P[+/R4aM/RͥiQ {g@ )G`*#pnZʐvAn Xo//b@Sni8)ؓGDg㭆yYe}IL.O~K_,YnR@rs.f 0=Chme=MH@Z_ͧw)ixO=i$)Ct> &(8#MT|Bש;_ͫ P&Gޛn;pXh5HYp%łG}#ë@@X9ЭeaUhxɾa>r&aY6fH/V1m 1uǜ뷶Yl<bל${ES]#pBR l&;GG=P@0w(ЛVƧNUCGovᯓ:Pɮy4hL>ۇ&M~qnPipsjvI疬;Pڍz9:ν>)/˪|%_Mlq=e%IMT"ټAs%n3ĝ,;K[$B<󡲂[# F"Z g}- ',W N{ĺ%g&obX wx,/QQ֨bG RL7@QmU&V͑OO|=p~]wILhؘ? M@#[Wz)pj̆otGz #03 d41Cx 8)!!!C$ 8|e#=t3ts"' @fbQB#,h/?aҳ*+vz,fCAk.J<1" S!cHY|\X6GgA4cQj} V..,`3GFCo9 j_0WoKp,&ANkixmtY:Yusa;h4DFnB4G(ŀf J]*}KG޻t/xq]R_`bgv0mmq=oI9 ~$d}q!ǰA {W뿑Je{ǔ䧤)JrN`S58Dm~^q2jE"&eS̈́?g % /VÄfVܸMXi6:g[}5)۰x ~M gZzՂ3c%ﴵ3Xr2Vk(_' !Һ|NyRlvƝq7;,;mB}-VCT8wuڄsSJii*Y4I+M|V wU#;{o7Ǐ_d,bgщWS7"j׸ 脵1B8S K$p8 Dȓ"Y̿ V@ē]TMr,¼Fb$`&t{; OOF5}92^'ûsBeM 9$Q :W]HkR_X/KM>`eۧz4l k0M%(h۶[Ni6qm.xU4+`Z׮fD--#Gp NhBf+F-| L7r IXMRY?^թC&]c5wzRU-)侰4NL4/Uf.@`ѝ0RGH|KB.+'kV$|a?]G/&Z(#xs9t %LLNzQs,]{YF * f@,;xGVۂq"^b1=Sx+W[K'?B WbMoS;{n=+fvG.\/'9?w^F#f=Y$\*tѢB |l])F/8v>]JAr(g !U===Lw ̭72p^&Oj]` vSx)1)`N{ Eߋ`ZsL @Y<8aV|ǚlu/zIƐnk ;^Yu:x)p1%5r> T5}v'O;oW^1iJŹ-?'ʺ#*N=W#\~WvЮ#qwyzәbC* 3~.r_(RW 7riMU7ߣVLzk֫ebA&ϵlm]ͷw?ݙEst`ռ(7|g_XRȷmQQPir4&*1E5C {"cX5!ך2]jks$$_7 hYj6IpŵSYły7>W3\ $ ֬eB#[w\)Ż{f#ҋj\S(C6 V5sJ譻Y$ޟk6|9T^:lo;wq_6?_Pc5b:iMZ~7Ztf?yK1;5=7'<#_<#6=am!(ll.D-DIEC W yCM bc z|$UpG 2dJ9Bؓ$vy#4 `!0)g`(D{faK@66?< vCĪ_+kArBaDͿ,'pT!8.x5ͩ\rid.b~,:zqp!{IͶq[WŏX !tt"f/Ag#Ԁ)cӖ!%idQG*.PzgjC`WQbRr6|^^]aٞ-5\ԹW)=R*C!@xh-7n%LKGsL 45r3_uˌÜME+v|d9/UNRkޤjgaJþI9gŒ>Cy:=Bd\XAT]$: 'zYI(E쉌Jn8 &N"Xj [[Fűk@c]w\w- IVg}9OU]ks߀'K vL$kHX?2RE>71yX&Dv17[FqMS9iS )!ϊJ/vscoeusK&p~f3KcU.S‹.};tv_O(@GjP.41$hCNK'/2 [ɼzFvuL *&Pn21j<6y_T&"z+2×ұd)'sJ1mO0 LCO&f%9sZśxC9|:gk|@f9ݱw4zdA7I|LYruKٗ|<,^Z5O&Pz9CSȋTMX9??k5LE*aOChtC Gf@eV rb3A]#9@$`yͤ!g4,F3WXG2 V(%SA.B44FFAU:?镍 !I 5GLsZt;\:1N >*G'g~ @Ґp=!OF4;3ƒxn *~OuoAN椑G% !+|vC+sAV/QB2>ssRZ0E%"鱞ԟ|Nd-cQ rjgb*w䢕M" m(pJ[OؚK?g)o.QEkܠQ]eZ:P}=Qβ0j^ 昰@7il17rvܿ ^-31o~. {t* |ChDU86כ,r\uswԶh\OEP.r{hiZ h9.p/NˆmLf#V1fre #yY+862̝WʼV3,Vڐ/3Y n[:P52p:A$pD ڤa%k=8gcMo8}8y%[F = 7M;y.kWxu׶7[VTH3[ߞ_ `vzuWlBN_HyG}^VyykANNdoTIa}pCeϏ#oOiY|VBH0Zfs 26v2c]swviҫu~8ݐyͼCN]{ ɶp@P<V}yZeeW'eO') w1 ,<|du4 #Vp #cegKNtdp.+, kS$Jx^ΐ`i/@ 7 .1s_+V~օA+DB1t׹q ɿS-%PPyrP7+77knO@z9ZГyĕ:>?Ny1;>P~otMmZ$3>ˑb gդAt3_6H:M]hkTu"U$#́ROz⣻u[N]Օ.g'Tn P]tQ1PpҾP[=RTnr/:Y bk4<)D(t%8aL:pNʙ:*oNRX.yf>TRK1`2Մ,dՊ֚YwLXU5YQdӠɟ~yaACLtiqcmG{%<ѼީJuU:T:])k^[IS׃jL^I|7n>>6ÍV%U~),(7oJĶ&1ԖSdر#yb40]{LGVצq3Fu^)F:z[/U(Aa]vv(o_D(}@Xi37T;- ;_1<+L|L_l=E&| }kyRmвU@•9fF|6єb̸ijRpSm+$,`Å3SxMH(jp3%\xh`m$ⰽ E89mŮbT V'*x^ϴ5إAxSR7:zK)>8-bU`|Gwh0-NsChej<s dA ip袳7 s /⚜ώjOTؒ^uʈ.X6&5ůegaO Nc +B[#EV'Rݨ (a 1C"l=Wje$7p˩ӛG!sLk\7ᦨALCN|DپQJ,322X.t-(v!!UXPȴ0Y\!BQ>uaR]u)8EtFAu#6 iWӏbbTc &F "{x9C vnt 9CPջghDx ufIq8| RDXGvԧ@˞-㮇FDиeNkU<~]4nY%GwM՗'o9γQ57>e.oO1" +o7Au߫h/9syXh}3'7z5dxgф `7=JZnûr:#O 0ppm>%\ ٢9?ӷŐ{SGAxPfX LұF)m2=5. JM[;P v, ,h ;sDc ehBc\%hO*[A "k{ґ)%a=2)aj_fa'- -c{k3^"ŅTT:Co;u'_Ѣcv.T:E3ǹXEJ{u*3$bhIc~a9s >\TLqfUy'f4[gf ,f°JAr[Wd=ޚ$ǽ4k;>M?R\|yQ|x TQ1_Q16v˛p$d?d \0&,9g/Q lW{U뿇c {U̩۟OD~˅᬴bt{pPCjci{ybY=hFC첟,[mk;j}iHW㋭yTۨDJqdZΥIqFe8݄ÕD,#~-jF/K:Ns.DͫeREa+jHUvk}dH,˿hf+XX*F=QnԬq,aܷ6^nivNhw2HoAP.v %?.O哥vNKZ.$iYؾxv:GE;O'LJ*Ӑ (DiW>7VT}=$l 2դMw켸} - 0'=u & RgCOkU"[EUI|"$nCQ Ie]?z ۆO9IIaY@A/j RvcE"߂bzٹ?b$~r!QQcH t=>߹@y\\"uTF)xR) &g> s93`s0I0utCpү$ ȲѰܤ}K4k;s4KԃnfN؟nm<,^_.o_V^z`k7D/`r)~V)|Ģ!e(>͏Kna,̎B?ZPWW&V@@2&CD^*Rd jnp FWen|`cy Њs7ׇ&ҨB Svuq3n(cXYs.?iaxg{jͺpuWsEnohȚBfM)B]P$ch"Ee,JTVj] ?q )~Fx#]EY,mH~_=ԡ$jg/Pmo7 i$ K!yB*&\o݈ H(PM4?!mg)o׳CbX DG1Oknǀ fDH~vnRIk*4w;2mxe4klFGtHNppҤ~(4 a iΏ%ci.yėw7ꌧN"?WlߑH D<7E Sx}3oCj/vU5"᎝(N!VgfEpu4GB/vV6Z۪Y.<5GU\BT.>d)U qߘ_4L cG]R+FLn*y/rZAMR򆗥#]8]L6 f4RuX{2e-RaTV*+wεsT9uJ}}6m\|NՂM۞e D̻]s9}~(ngfeDnOM#boILarMŗ9ATC3VܷT(|3[OMbӵ(j Ξ;:x=tO e!v1  {4M@Y0[>eso[Eȡ(É+Nut%EmH!sL-Amsڢ*K,[Fs= ;}TsL q{BPZ_DQSlHT˒ 3cF:E Kp}93@Ok@bQ))Axwh.mŌiX7pPZrlPMi` Bpفz*#= UWtb&9nR ?m|D~>cTn\6vvY]VU 9Z#/m K̠,J2ςC.dׁ(a)^`.%5qr|hr1g0ku$|1fp,/:юoB"5Ϳvǫ| }%\F A!ḧW)!}:&bpV 4FcNwU孷_ȢPr H N& gwgW%I+faf@"+~7t/j2qJ?Ǝ(Ntqa qG :=x̍*vFwQOs  3#/wM0` h,'7= Ҏ_E-OFS6N}|MC˲sJY!@O3yV4ķj 8Sq "g05 ]f, "U2P8 i\rc#~;E}Ӆ) S(E5,;kbF^G#UG(gYtdLV /@-Bc9tւ/_'B}f|Jt 3jO,6IDġ#iWIHrɅȓ/G$`@zIf2<֦RRpctt$JUAki)gr. *ޟz,:AfkA %V!LHgd&HZSJoj z#E6A^Dwf_)`tCĝmE'z۔P;hW+jEL;W[Թr\)Gj3`\l\YYoۼK"jkk|.EGLꃣμE \y2ͼ8etҷze狧 M5?RR0d_憷|t&cg]πS>xWQb4~)kr.nec׎~{BN ei$DLjlIscra:UN!G!xb2yQ}o]6Q,Dx:VX#ôك6!%K J7a*njHGSAGad}$ǺK*J'kfMo +Mn- g45ֈfZX{mw*5B2<}< is*GԒ_'Ԫᄺ4mZڑHNdoɃOҞ+E& Mmj5a{GXp0$ +!bI(Hx6/ ʢ~ KH3Q[CkoV7H"ׁȏ+jZj~P|y:F [~߫~<BrD)s7߶e)уKŪ:趋*+:釨vUi$-WdYv6N U__9@l3rWJƠV`gچ&e4Pޓ%mw#8P(gEˉ&4 xw#^e@'p.THFdi9,rDZ1p#cfʺ )c<º縼य़tKaT P!g_Ӳ8b0OƹcxE^h5[E^l>線Ӭ@)Jq]wC6 h(.5op_җ[aJ22\C[i2C c{(QB n㐆e}7\~nQM/BX[4Ԏo[yr&A[No*L{OgWhonu*" fAsψb/nfC97<~8l\X*S.JWKL,/W*&ͧ-0C2ό hF!(a+[-1Dn+Y)9qX^y "&IK. _SǏq " P2Oe#LKX '0TTщMK@mG1ԪG-C3S_^G @ߓgNߟg%t}>SUM=QXRnNܛ"ILW~-Dd1= #"mbmo2pr Zp酛C1ؖ!~0>rJ6k!ТA.2SӽL܋M-ZFoIi"/R vpΜEp`3'.J?DEb"F]=^4 FȿMx o,_-hy0 3*ҏhJp,x +Xotov95E$< Ƌ`dc:Mak? b8ǐh2;}2NWs<x,)} elMPi`G35g<f`=eemT15~bL'ZcLFCd4 j`Q2♅t2;4 Oj\c l(ĥ;1.J>+sdhT&8cJB+Cxӻ$'9_ܘDD$Sڣe؉ui' 4!A:82O^L rWcoꮏ~u!o&GO鋂I[mIWhUeO= R9ILX_gep/u!מS@;ڡnu䳈V:t %W36!SKWz1u' [QMW$v[uTFX$=Μ<9ru\۟]Ȱa.J9ԏ鈐Ft|zwqA[svvک\+}G4>1-{Vg38Nzx)mc\}vCș. rEi㈬ !mؔ3*=r !D9L7;2PE}!!h$ 9:,EQ:h1,֒jNЊ}g72Gib70v/ҼZ(vӉe%Y@$% :u:,֏gK+QA*ywiƩ)M3ʊ,AR-lFgĞ 0_DvYbmuK?/ R9%ʜ kbSO4< '*t;k޸}In5`)CF~YGkm%'4ߪ#ke1c[1qV.3W'׋IV> 4ǶZj,=B1̈́@zuqȆU]Ev`QF-60V \癐øQh?t5>+uFp/62113 (֙-OFqȂ$F A@4ZvҌtgf֏93T! HCQU@v+=B(.k{ eÏu!XpdfM$ +!p #4~0?^Uڦђ͘z !Qу'y͏tX@ה6p#3%R=օiW,n=ARneW븮P9e\. |3o]?Y*i;$ގ}{TMH"48TESAgK0N_+-3rt[N}K>oamE0nC}Q/aN Hij#_3jr'#_ae53c+PīP'?318 N5׭S?kשr7zbOrrNe/[.H8%`3kd ;X L` ? CvOAagz h +IyH7:ջpZRj2rAbW&HHC\= g.pO`_'?b C z8`.4zC6boc? e/ ܊d\z Lȿ%ـ he6 W_~rC`'K{wW!6b"<PX@+ɿweڼCMWv,@>qK:a ,1Ȏh빉SӻOo"Her?MTFkg>E{j d:mo7 NLu4H>Ǎ΂#iqb0ݵ'_5sDGLL]Ŵt=I7=EWe.H:\h0ngXH8|0RNDž6jhTNTxs}I' M:4:#]ؼFq{T_aP7#؎Y@h|'KRd^_wP@1JԴXrMNyȇn̈́πNZ2("J *86kkiϧꢙyF?` Լ\dʭ/a5b$pesб.WtF^vcI2"AFl{G*i,&nSz”X9[ݱ~+ߋ!:'O mf? P}Hѽ4l' ɓKU"v#D[^#gvղ/s#ԖfG * |wVb6 ۅJirA'R2RIʟ>H`bعIq F3񗸚̎H-*K^Y_ҙ4#G0Eȇ.(r URF/%KTDj=VL^~8JA1B*K@rJ!ysӤ_%yV S[W'uo9GPcNf[1u$ 'l@(5]{յEE[Hڪ]Q7=]5IKa,_}jO}LF9!=$zSuu}Piji4@Sq*T*a/tz5 T8#)#3t=ݶ7f{1o7##=DUCsbKe0{SFu>D/kRwy Nw1Z)4>p>-MKR@=Xۛ7ݎ*a疋͟+?PɆ 3qOht8aE!1QBUuTfOƬ+ Pqa Ҿٕ:gJO.oTiH_n9o-:O\<'ΥDd o˶T+W06\D v<\D 3{Ś:3REx0N7)HJtaK[OOb]Ry]l;}*hhA>L0D; ?xnf}kWn0Gޜ!'+,竣'۽[h1B`ϿoB7?+cmYݯqHFA `^&_GQ n`Ar\qq1ɿa L`i;~Gm};0 Chǘ$48$?C5먡 K=Q+pYH`7?߳&No[B(꤀{6ĿuԳ(z8y B>1M A*&xi۫=~~e \h3M 'yZ%\c>dJc[^uaS`HK BL8< 6Deʯdу*qْ`Cvh64Ɇzk.LD=N"ZlXCL\ċqajE-67CU uMZTgsO*iuָS=眜3]~z w ' &T֦C2=HitɁ٧`*DLvP0'aYRrulg8{/g.JfnBqɬ\I`!?(%@FN)3Doqi'˖(]2[#m$ vi D(TqɹQƹXFs4GkA̓:bܜ7]N:+۹Yrlgz?'ZMdXr5 @dSVěѣaQi&-Oaɭǐ$X=avl *%SNLR/3d`)V/~2?"K[nE]$Xk0zqx:i\:w:n$vߒcݑR~bCNWB߫S\5{.HAP7m(U_%{$0LdXV^1c(-$\^ިK$>Zge~5|@ΖLZ9T%9_SǗ0Z?8}xRTkI-fpBG"?H@Rx_LTcuj+7e2`'kKD4XsZ̸v,.qk݇s_E_;i]Za [~8S:su7k]乍cQKj*ΑstSg eUt1\4Mhau95-dtv&RB,I<-Wg(pj"P-oϻPԽ]14-/bx%vSA((@~<l+Q E 5zWL=c$E8ޡ!$`O8nc J׏6g93֕\Ow#<`-BÝN \k8Y]+KGPaQ9&M+WPgdmrYFLvߺ<)z7ij ͉>l?(0uF~mw>i,Ƿ2IӀKBm)֏i b둟l_vO!2窠_PG 7`(lO`k6+ Χ)KjBa]5tȾT0kAz4uRŏ2<˪Fr*x>Mlғ>ss[ X&UY>6|q,0''[ 'O@ggH2 ]>Vjk×oO"SPX1&^S Gh\+[dBX\w}X0*QVɐ0ƴQU% B vn~RL޵Gòo/޺zd׀L  H+VM,zM}Ku ƚ8ZēN?A }BM*0[:cCr~}CW]#f03]-#ƣtw~9oSS2̲:3A5=UXuEa4!=^3pXVRHwLx|O4ZX8+_V5\Éށ?8} 'ddO DMuq>Ӷ5%6ʴ&-pd蝕b}5u-ٳ1K{Arں^;+op}'q;9;Xt4%f?L-,e5v0ˬW Wz~I1q J?n:`"oo!I@[*ae&Ҹ1[9UA9'/݋谵xI5#$"(vJ|]ݳԃ:61ζ[:O'${?I[ {'Ҳ}_R0f+wŊ?j𰁜"Zq_l&IB҂rƂd5ki;K_eX[m-+nkq KpwhqPhqwwww+߻k}k_:+3O?s?(am^C'x"2Mrl(/V*rdd5s|j{IV?z]9d<ǹ[6j.b*A皕.0,{`n!^KP)SD!}PKAz zVdѱf&̴N~#;.8~@3AN)P]}h$˪?Hͮ2={t ;8ir|p<ޑ٬`CQ æNb|8q_൤C?~ffi;94Dpc[# z? qx\齶fcЏ輏}][wK~utaJTh̄?( Z絢*YY uhWyBT挜P R;.xsTH^.Fu}`y/GH(3%VB.[I>22bhM,Zu觇%UX<>\\::(9~8#AF˄L*g!>;N* LLaKb Xl0`?8)4ϰ[5"fͽ^X$Qj kH\k(BeϝGY̳Xݶ!1N#dk:L~ ^Dp ]I]UyXVܸXi8Afʯ⿈NKj6;.,r5s=xݓ'FNX᥮]$|d*B ,o0=H̪)kPLA"U8W >]ojL. ҃uɴolU0:GSk d vQSH _F9a+F0SRԠb^~: h>mK/`lFIf= VrBJԖ/W%˵>ҹsjK_tjLj-$#~VwcY*Zm,Oz ڵ+C})i ٲ4NxW6U)\xߔuY/5D(e f GAuB– +@ꠐP4CSX>mC|MjL\]kXA+ gV;99aTR>ƯGo`Q*a[D:tb>Zd^mbH( &Ҷh,}I]✞'U,U1(M)4jTiWqZto-  ?\R2 qyX9A\ V.D<|@?nDmؠП$| > 3cZgJDTԉGoŇFf]˟Opm_I\\yeT<Dž#,0BEO~XcPN( 5lMwޕn{ubW!pB_ 0eJxlAw/ >mhu+J*T'^^CmTϬEтmG'/ZJ+)#ow>*B&8f'u&4}gӲY9OӻףПixWYD~> 796gtާs[q#3GR>]ZW0 p.VzKKiJėвsa,^Wilw )'D|s NT^QM;%쟳f|)Ix]ŸuM~'poXW4 X,`z"ٟ@Ah2/^NfZ & P20Na# oQ?u5/v&֞/R'gPd03O5dCmIkel ѷ{c֡!aAf0jO,G:؇RM&u G!tQ}l+7|>&!9)Q-#M\4k%={`~;ZNG^H%h{ kވpXzh[; Hӂ|ҋUY͗b7'xd3W^:^i!G Xub\ l"r?bH 1"Ri!Tst3Z1qҶ&k{pͤ,>KD w s[){2HAFûx~h3 Q-6dĖSWf!"}@|1aD$cc^{fճ%pf1eg)}*kG\Yc5k JqՃ86^L.Dq*q@GYXVuO!}st m`8TXLWTAC [=1R oM+YİsɅS;vD?R}a]ʔV+ȶctulMK`2iwFv;,,qaF~ BhwkuhZ)Ʉ.K)r>K wKJ(. w$>.tC]5_r`vX535l$6| t= eX#7S97MCfa2,1RnKXM(OJ#8LVߵ%2iapf12;Hrݏ}G3-eN^\Pgr:+m|gUW8_/*?Ɗ ;CVz.vZY /Ιh,<뽩?첈gt/LoVbrZֿ֯γP r URM\(^-d*܇Čl͐ ?B gms@_MyF4"bP:D%qCGvL+8\f)$Ռ>>9_X(P saFmLu:hI+n'O^ Jxy⎒|V8H," %ɣ⡈IՒy@.䉽FۑqZCtlr0t\&"j& {ե#Q 6UG$rxṫHEd89(tlnZ۸h3ZNE&rʹD?\wGz-?ulC(PpCl?"H ~rSp_К3;;tp9C.XKY3>A?oͤ;`R. r |8?| ɦ /e^d e'{,s6U-5o+'#{p8ǔs%:96`Dk팳JC:eUg9yZ Eka9Q6Kyirn45s<@ʥ@ıPF#f)6zIY B:T.H/Z?ח' ;8 /%N~Qz/4JsU$7N,"갅 6ɯ: 5S?@2SjDJ-1t^g(J_'E<>r iȋgY,[O׹8\ޯO_ wZXp`$7iʿvEa`z_TO͌։F8BȝQAWi*ސqkww0~kj)3̬b/')I Ek/P=/+JMLߊ12Gh~. A~v> []~KfmS]DӅ?ֽ%TErQF* dI8Y]irp` Ȧ*2rGf{C <$R-%+/IczqͯWh! 6CA>OI\MռB_mq V^Fv'ސF.B潢[PZqݬR _n*#B7صFGܸo#>ܟkVL6/,%j [f~h?P*$­6=:^&pATfaL#u:Xэr$Ta Νe?7dY{S揃^DOT&Io&!]=ƒ߀^j^ÏOjF|fYMeQ1>G +'mls:n*"TEN*!WEB֕G]i! p?r]ݟo"PSƧ = kwAMg z+4gn[#G_9c5*z%J!x AdZSC3aveD\`~ +^Lfyz ,w/k؟NO'R𗐪ݝM&ĹcFV$y2;ʏ y8YL5`KhmЧhʷj1qq{F '`6D%iqD; n#M$dN28 ('!h0-E]k;GÉ g2bkJ[FHƽCN.^S&aH}m ,n)X+hl!WZ*m?Z6Vp~|(ooZ3r` oCq_vf!UUgYM*mMW{<T5(,η1uE6C-OQ9~0wUe77ߜ1ש/-2D=ͥD'%}8\&̶/L[*n;ߓI tC-fwA-tX.w{{LprY +-~GhK7KkGwmKZ$W k{:&x!;0ݶAjLC96t4FoAٿ9<4y7񠤇h}:99Xy~a"Vv{^7/zvGOф=Ǎ7z+Gz qZ rX  NvnVn3yf <>2<4O:I EAqErpB˪qqxsh:J4H lioA;B /tUf. N`$dJsdp1)nk"nɖgV3vQ]7 PGUBdkiƥSmG1ڀ ,4؟ٟ7` J0";՚E!6q`:t!E1炨-Vg1~ʕ&{jPiGŕ^_RcQN`An+!{!5{9k+O2K`8b!?3S㩨'BL.iWvM h6qITSIJcl>yp)e_[׼0ƢR3<#1uA}Y0 > 6"(7L*.T9ZRN|\ OmU.i6 bL,ar;|ʴ}aR:\EUK<_ɶo]BQ E@vs)5Ɍ?F0û8`t٣cy2uV9QKmYf-==ςN]RXrb6{*=:㘿2;2f:'T2 .RcLjG)zrC0]'h(U{-z$`ca)R$O 41/Ң7Ok˚C ]Ca{]gxdrol9\p0~%8=޶qŷdjޟn܆8S8BS5dZLutQ`%8UO=Cpѧf[K ,Y;,1%n ^DZm^U˫08sHT?|i(>2SIf!s2ľPp D::AgMXdZ'7;(^moš 3͖3,ʟrs}dvv&3[d$;Ъf,̗T] GH&ɛsYs8gn7US9cL tk`ng6Fu\]p?WuxWU {d.vD 𕅥fn:o_ 9^w,>&U'JSdGnx .W8 rG2Q0k],/ E$M)t㥐*8e/xꓱh>@T%( oͼ*pp|**CGc3H㮲&n uTO 4U//zq!>RD;d'bIਟ7Puzb D")T'Ng9,墦5io1}Z"dH i|dM g*hNGWGK,my0ֶ=ˑXE#5߿<ِ",Bl3dH.F7tmckc^aT!1+ $い"RsL2bH~k໘q^4"YLŀ^(9 k|km&>Kt'ՉCgJWT4Y[cn&ͬI\oh{mV+?93,T T[1u/̽{WWWq١^ƦMd#z}pjLXηdY 2^owH"xޑ%KY1:)Aw|s1;-s3dBKu1e5ZmAh{6qaU͋تɍ94 6 ߗVozЗDbSE6IF߇ow2:%Y/_F@Jv;9 t[9oI-sJMm73:L25gbzoRXa^~[]B,k~:5!{ZGnjay|>B*Px*x _|gbE_?0yg>3 ?d^޿#kl"$2> r"t<1Ŀ 8Gڱr:QRY~Qߛƫ(חDrF '+?8#'/_3S& B!(E@ ^nVV.V^ЯVrO$K( ߌDP!T!t x Dxi2/``&\%Wa+" 7;7M$e(x&osV]s:7U.QTcA*aq棞)a(;~AJ$,[6:A`b}E`s~MbX-D͹p<%u&+yA6WRr>SaTrhZhXɊp0HTU^8"0!RLA)+`f#mT'6$f}AP\L/ÄkzuU+,3(%Q:_X[=Ό*drX Q "Sf—kXxys/#6Ң?¸Q |]WiO23c%NQm`s>ӻz _w#Kɇ5Rp)_?TpCc {GVOHit 8FeE+,dT"BI ^UI 6[j؅߇aOg_nMI 6No}}]!п<ٵC= q+Ŕg+&IMӘkbȷ)y†/W[7!ߢ&ܧiSr0{?rQ+:b812Z:C xW'N"FmP;q+,ܮPfW,>0)-LF@a (m B:8 FaҰg^O/đhm0Q^ l ol0#ڻpF$uܖ;B:|-T¯7/%u=w:8;pB#1<Ԙ=W8 ˏyZyT|^9|ıN݊̒f4JF%$tQl뭟.wjrS̷c*jȠbo;.2~aV =Yx^_7'WW[+EtTNph`aE JEkG8q!H#:[ kxɧn|v<8_ 1DL$6ָC˶ eb4Eu}ǐGCn՜Zf?.ˤ[G+xF2nJ?^y%WVKHWx[x!N.&En"Fud(ϩK*mDPA:L e]r2cھ jJc%@V< _jU`E`KQJ\6& TO+J۠c7;a$,zՅK,Wζ6ʗzYO~nXe2Ն},4Ϊ0_:EXyFD+5e$mŃLT og}ҝ!4cdtKlcĢ6e뜛~Jl圕޺#~]_U3n&pRB|+~󕾷m0Rbj5^˦j|ZcTN ]k@=a'T+2,H#q~p$b:s0Mq[j ٿ=IP8lO+W,A4`7&Tqr~Il㿪L|3| W/H}2Axp9<е{8\+4o?Rz-D2-D!saMRxP{yM/?}M~})\K1X]Q1oyI06%@rzFW|q[#ߋ_6LnQ `%?71\9] g>5E\-l<-tnf;]@3YBl}ǥSn4JZFn0CA*f #$!w+{N*M؃_8JV56KH_@&KxF7yF1<ʧ̬`"GHCj ̿do <|nKgC`>b5IĬgs/.8i8BB~@(9rd}Nc_İ$NYTcVw/$Kd'hj vow "\Nۼ >$ij&?0x|t,VaTO ּ1u^l" 2?dT^kpTRm*b✿ìN;f5hoI96Z`ѭ XӀ3]$ُq5Lrjal'20#NS}CY:G3 n!XўUfíozkyg&xC-k&pN&9!Zyfa1G6^@B᳀ǫ!9 7pJ\FduV P%6U(p~5udq]kh^{|hzÙ*ov \]lAzK##^yW+fF3%[jN萓ٯuvR۴y`ׅSZV5k됇@a*|Zb|FSih'LEl<^kfk""b $XG]9ּ3ݼeLg-6ؖИ}90 »:(gڊT@5́" e3H-h4Fwnۂ ~!xʕ%YQ\h0:gD$j 9돁 =.4{VNkawW*.hkNf}4B"es[9˞@IuY ,O gAK1q (*L C^*b6ҶK-BaDzˉ";wT>ANx'keNI&Ծ. s vGТfiqeVNRq-F{Exp7kʊ%)k*xySв8^$+ȵ,]ĩJw,a;©SOP)/rR!.L"ZA @rsSSWݮ^>J2B~QKPZv? ,dZ$Qȟsb٭6HrᲬY i|VҦo>e3Ntm>Bki'ldaA/\i<[qQ+ D(#6&}6Ѳ,S$(s 7a:36Ks1xlX;aWn)W`}.RB[/a uLo[;Vߡ.izY,u0:ֻ^;1} p!e\kE)7o fx(wC heS,le: uASe4QwYM\Xns-G>^U;By+jo4BPh(>7,޷Yd6m=# ɼFpp8p@okW!S3G_ 2.bzJ@cgef H)9B\(U(_5>= '7+geC‚n^PpxYyaVNV?JvVN  kꗿ c"/t0>%%Z Fqrg`x @ Eb`Kb⯎u{ mՖ rs@~[S.1C_g~rk$  s+vK{!jq Dx/@ ?3dރzhCaj$gop[x_k\>&8 x3=45DWM X8$O[.#K&# x ďa|2 }aFꎯ$)`ZO-W9Oݭ_`vƗ|nUD3%'Em[sӝ!bf}L$lDz8;7v\%vR'jBAhy# .\zG&PW}y1;9c|e T]tk")~!^bQE=T1V) /! S!,k<$;~e/c&ɲGK(hSw7ZnTs&zILQg2u$Yڸr8iPw,3,˝AکDC^ںA}mXl2Bgݑa0%PM,-)Rm,?h{˰8[i] - ]w%;{OϹW=UjU1sL9tȴgk,4>LEffkv+638M촂o͙wna{zy'cvDecMa}X]Ξb}Kt1-DT i.)Jre"ŒB&K̮!Gqٝj0Y/~AZ)?\?ÅxhȐ@&^wF/N0;ݝ3H~;G嵐mDJ_*b'S?*hzYnܜu9ҔBK4p `t_m~_< D'Tt7SKF9?52cߔg$1\T?D)(bT0nXkdDދF3|`e)t勰mXPK7pl@tj`bqm tQхpL9حLdaoib&9ڞ6S6G$DrU]F>A|wAb5vPګJnכ\0iWL.WXگh'TM4/P ;kO?  ;+9?;+77?9`fe(`=WTۉ BWL$r'tRFnl0_1&7+_ɢ-X`Z6[BOLB '+ey|<䜜\-w JG"f 8 w#W׻{JPߛp !`˪1o+ _~ 6a_]0DDsZ M,iH1/&!Rbs=hx-ټQC)^Ln/-"p&ܯniݗ{ed3ԻS(pnWK9kǙcsA_Kwn'}WS-6N4LAٴ8׾؞?H1mnd]b4`v`+ڽ[Jc4&Qڟqi@جw-_VUJsɵ,J}/ ( ~&.?Z/}X0@g;+qD)n"W -yA|*Hcq%*z?<:z9 {;;Q{l C2)QIک`ԣLh8yyY"X;/tY(~Ll3l LX@w߈yϠ4ǫHB? `uNF2MV?~b=k0ŋ^>l֮Jkd5BX}oK_ LF-K1vHCj]R4m**֭^s#< LA>>mWY\Qp8|T.sqIca簻V+ _eTC`KZAW ;g!` D}':݌(I]Q#f~4%QF> ۛ wSGEzǑBr-M)F4j֛ᐤxb 61Ӝn}Z :ttqC4*0&9g($->g9% sT8~SPB3boP@[RaaF,'ńn-qu_>6f(Zn*YxrhK[-ϚnD7EdbL-%mq# i;8qr&8lA8d=iq6)zIdO۰g2as9o*-&nB9}LoŴHfvsݯ*J_zSO͹wC@\eb qkj\ࠂQdۨK)G5~~-~ qOeXH)fmmܛ?iٱ_ݙ Wb ?w6f}짾5I Vc6Iԓ \`0QX@SeaR֞btKҝŨ8x#uzb^аT4 7/XW BVe@3{DG\WJP [[ DN8<[61xjE` >üQ_'d_vlp>eCm&Sي qNÚ{/]zOɟ^E4ш 2We\ob dBG6gh^o]^lҫ;7p4Q_ᮟןcM >?+^b@;ljh5yOsLgetP?qOL[+w\8?iBQKl?"BnL?"Ud4O$fM[)OaIer9N{`h=DVU=n9bĶ_A_6 t^8fK:-ŴY'{čAo%5Mϩܙa@a(BQL_="2EeC_i| u룹P<ve61 KVs*C, 3aRq*XZ"X48~}S]i{C*Nu5v4枹4RY4e&Oj@qoQ/b=/T!?# ;P)o@#+H3^+9+'rY-_.$l|qrs!Q^\&OŢo9YN |<\u1*ё,Ǿ9?,(:%ܘ4. )81)yna.XoPmlD]kh5mj94^e+"={$ /Uwp`dh5g#cyaTN3MǛ/8˂JƛܸMjsGw{xM>n7݉y?||/~FjwIKHߙzQd6u8l? G]9(̌N=pN.ѣQ. \Cve(D6}Ӿ<ۤնIlVVD5ȺpapWvCyCHSەO-QHTc#UA ӕEm%_DMKL,9,yaX g(Kk_mzm73oFy["HZzֆet:!:E2:W;IǤ#WKtv&p X|!gf&iK,7w?3UU4HA4F5pM¯huBM=MIkぐSH2*ׂ#ÒKxAOibv;#B\F5MLZEu@EsxoVQ ,)IHVMMS0ꌤAͶDg#di^,+~\M$[ (TƓDtcXrEBG0mkq7 cw<s2sK#oZΕ%I'b${S6 dChby4sX GEaTpbpvҝc<9[%*b# AKFE _~G2 hwHT2\6O2„JIϦ1,Sz^'oX&_ ~E3fgӳ; پB:96( g/D5spWrH=)N"^cMo7% M;lK} M+8lAYlgx[.o]GeUoh%fBGz%Y>=r%'σ3mz\}t1dKZe΁x$|(@RZ˓xZ$]S8,~چ6eQI5N~x#^t-aycrz}`MyUGU-y;U>ئq" /KJ>B,p"D>T)a-޽.DWoSRS~&5h)wATe~L=?# 0Q\/@/MvkYnJXitILWn !Ȇǜ. 3f=enoLzOR3eץU1ccnADqll;8QIWxom89VE *f&ٽM0([EĨ) 'qhuqZC>s_aʀƻjE(-&S0; JI۟yi&]jnM'6U6Sb( 9_]̉=Kz_3~sri |.WjAA[= _ D.NփiU5{:@c`HxU'zqq (GgYTS52P y:cY@|B,tnl-x:3Id^oN)uT]j.w HdFQ\jH¬QQͽBJ(AmI6h c!hy:3@QgXZY[pnYjuyr=kq]d='c-onVgymc9ۓqF4 2v}PWr&c0Li6}4t82R lZ4 5ǶyKF3}ez;99[$|iv468OgDQK:KVK,̭ÈΝ_QS8)<,}mz3g0B[#ޒ1C&w !-%^DPĦ<;ό9f:~/R!]\Q30DА?u;R4*5uyE/ X<`ѷXv31C(,Q6$%kMvt"vpG90;]vR@<^8y=vt/Ov[?||\G]=LA?ໂ6\;Н*ƈ+%PbJ:q|}r&Dc +kR4b٨efqycX>4K0)3&)ewaQML1zP$Rm_wfYM̜d]w:} i@S/)ՐG=YwάIq_;So!ۗv}{k ȶ3nK93"Q<#>8u|ˏX}I{7f9*Z~mC_NoA?T ,88jlSXymw@>asrsr윬`(ؿA$rF7 jq,471ݯq  +'/7 pr쬼|&_CNoUTXaqr3A a9͜KHܿ$BpUsiw6\5z }Pr{tFQ(Իc;Hrl<g(pQBHZߌa+-1b;L,<Q&8>Y'`~u4c=5ΰ AIk=K|~6'/m gmŖ辷p4 n71Tc(pgzcc/{+Idv9ON_|ğI9$H=x 8Ѫ},]!Ґ^qV_Q"?TmGů=Ջum{a/ti^񊚲\[?8Y>MA26p{~t` OK4#]_ٵ;1lDFH&atU@yWkDhHں'|my[! H>۬gV!TUOD˺EgoԤ7[0Q{$V0+IAX"]#@o'没DdOOoaGoɶ0ob LihiS1P8E4bYiI'- yB.MpĮ-5ۤVh/쉄h680H<1@bi1/RP>zj""u/;g&2W;@857S#r1@UqH9:j]#S *[dI SMwx =#^:MY%dq}BƦj S[Sz7**[pqk g>,xb(Q8cL.Ƴ,`訮Jlpя/eQ%` wȊ.; ^BD*VB ~"D/fTG3~kof_uL#=N,jrq@W*ޗP`O'4)23.~D&3,vbl\/xa$K>*GU1812j e}>qi)\[CƃB.K. &vVIs\_!O!d dU?çn1nWh2+!đ[a~`]N(FrF wRAc:zzWB" Jm#|1#sD)uc4{۲ʘYED&!LU1{W>UjOU]7\VYyNcK & cCa=\(ٺ Ojo%̔jyQ/|xolY;cv,ī(X| ;&g-NYJ߾:\s=9[Io4vhĞag&HCĔNN>XQHZ׷UNzӓjwDL@@=]Z֔^>97nqtϴCwqOqF=2w- L-Rֱ:ޟk# QyEP{SYvWUC+/U@Hsw7o"9j0x&Ȭ '-e0fVaѫK:Q&?G)/ O46`hC"Flc U{`;Py+WQcU2OhG3j4dZSs3rwBȓ{ݒu?UՂl}HDJ\N:"}S.eG^䢬;!a8Wۺ? p?Ś,J&01$9^ v@K2 ԱϗQaڵdxd}DC'j;.m{$Ǿs/ Re~T$GrjL w}BݲL+㚩Lŧӡӹ0t<eqUoQa~S7t[{L|3,^"OssprkqEnw{K bNP˳{)?XSxץ|u,Fyb/ >UHI'X7osuϿQ{ Rn0|ˇNlE$GQT7{*V[s%||eR"qd9 4OWf#ԉ{WefFVJh> "07[0/ԥh٨~_#x@X,JW~= GOxK9r .$c)Wt,Β,]? eqJPcd+ AcKQЎ$F `K'sJYp] mq"b}I!.Ø#Kgh'"\ҏv %kU7BŰDM\8K6U[meɬ"N` \I 粙(ng^CP9T ˅ZSN\k-vaf 1 s 9jNT+pAuYco)S @QS) ]n6l&Ī $4geI'?iQRi^]Rh:Iwx ND&,H]*@(λ'qc' E콙7;^;AYFMKOt}Mλ4>vtvkMP:\ ЛR•9Z O1ɨvXA89Y`1Nr7ǖ:*'{ү\ @w#flSxb؜h 񂓽9iuf~Gfjm=G%ǵ'i) I hǐC}zY~ڣëArqmM4zI6p^+O*=/y/~έ6V,wpF-ujzZkN7F;My kio v6e}+n#u}3]Dʽ:;Do&N@$[!;>]*VG@jgVr w܃[vH:?N̚5"`~!0nCǕɛCgۺBR%&=}@=cL*2X`$',zTf삓<KY{~ pRXFGrpKk[ P9XHZ\،|Vn[c$I]*9m6C+' N mb\@p B|ޅ:DMa{>o; aKfg/,x^j@<3m\hDZݨQwe{>@&R9G$wpX,E\*c|lZ@UVsy:|^9÷G1L7NEA!#G$ Iiq#z#cLU-! *Y Q 2eF􊄴6D75ᐢ4vc`6ٿ^cmN4|&Ñ>1F%33cq&߆lS\mzwc1V5j]8]AIg76XVJ*=ΝmeÍ_DP0eNg #ږ9V $$:?W{cQ{/Cm[;a;RE3kѓ=̵yu -dyqowAo@_t6r&bӞtT?y}w}JRIWHÇB[U,w>u 6 ,'-k12L[1 9y"e6N}P K㰺 LLE%H,g)>$Jv*ˮ¨ԚbYN!UvD|1<,y+Jp8ljΫqٗ [>9M xsRaBQHIys?GْCvtě1k( o Ū!pJD܋Ԧ'Dmڢ҉'; >9":@pvv]E jτ3P)q#_(A;ϱVg|5z6-2"պ<ΐ㹵O *L3[ؠ13V?z^#(B~԰WVùlyH(ڏգ\qxUy K gQ72gC4!dkF!}y03z- }x-E[ѳZQqQ\OuZnɚͲBrQǥO5*b{M,e!Sǂ:l?)C2ݾ5r@!^&9Oc?_**1~]X[!(L\E&EFrP:0RsL6^l%U70͘ "CpѧQ%9y WqL[uP4l"yn5N>-FLd͸-Zpo%f;/(/14|`a#dy S@ &&X?hLMyyYRIcO[|@mCQ6,g%O%&?vSr)s+*Y+0=aS4Q- Eڿs֪e WSMUl5}tԱBԽ!_iZpJޣ8_rNlmkd +R-m퉐L)F?sr[7% A9_B#ԯb.m$[\k%lCa|MV0"WCȕ) Lo2k@L> u#oԱ\ {Lsٹur3CaafWD൥ׁ+C\a׹ r6 ; `/97Qu jc%_纱>e; 8w_d@!13|_ I=p΀h".~ @n#Hr xǰ*gt|F@."g?_ 䀿 "2@^i _~ 4p85^4&7ߣ~P9kU R@{u:Cnܘ<'+vRGUƫ!wk*ɡګ_;]jĩ9QA1Glό*G ?l&5ĵ zqo_<4,,X;:?=;ٽ+ާdjn{ld2`3e-9<`MK--[mFPE Y.U .]ݛ=kc' LSݸB7cښu,(3vR t3n  ׅ:.RK#ɤ[0GRYeF\tJu܉l98}נU-\K >N~I}b]Dr}YR؅ Ѐdq3tAA28Nc1,f*/SuCW@ 1ŽnaRB;Aׯevl=dW2VEһUhlg2s m'(?AkP 9n}M&+yk lJ@; ʶ17pozqC cHeVHV秝$R8` =Te)_p3q>iY#%ƅ6ƀ}nɍ4Q/,<hH!"j#jrв: 2s=-|tXwN tCwRE5 Q'i\G^-j̈́XT]]8P\o,&G-t&C~=<:|8S3c"("y\Pٸ?qM gPӛH /W4WϤ|{2Ro'x 7*֒5i6(!_A2$R3pgR߁,glBdhoٿ^2ZCYA1 ?(-aτclt͖<BUI?4͟ZK"( IȀܽ5iR30]7ZkvC.'_V1D˻c( Waw>!с80+jc^d'~fo,Zb{~; d;5wnQP1`lamFK;0p${=vU6q009ӧ:d3-SoW0Ȏ1-QG1+ς^4W@hY:9!k{otL=Dh#nm7ϷY`މL)ǖjږ0/E9~6/"C:<|,>O#oF4=}tի廀_Y'8yQCHE4栗.!b;JAqQ]lS7AMn0m:nW{\CcynztqݑaFT+͒їKUu7R hhM?>[4*D-E*t*>~`¦gIF++"#ߋc=O$wIRJbR!҇v=u`{HACLͿ.c,O y4"xrش[zOuhF ]Tv$!!,$+~-qtC:]qJn gMʞ䑕,%頪 LQ"-7pP "<]|Ԫ_UT~e{O|_[̮J& B'\+dHvB"I3j tR˻ jNoV*a_דMd3\=V+M|`=_1 { E>s)g79ڢ_EFսi!#>,̻#I:u6$ rl\zev\y~&P0yӅ;1Fjpe_a*/%h@Rt s>%b>`7]b0 >5:h{P2ˍ;q9ƯL~ Mh|`SF'_Gg9G7V%h=yyԾ6B>G|ceEXo. y%h5( e3z*ޱ"٦S&.oz^~)-m_~wrB[* EJ=#duC*?ĶUU+?=vӘA(,тyL{MX [SڑGY,_xmmdMC]-=c bZOQi>#'ONEH!L*t=+1gL#9tHD]0j݈6D?ݹhWJzwUR- v@QY^J:)\^.hNdLGv! N ؋A rEECjٌ랔ҋI]GYs`PtB SC#We„*%6]yt&m 57h<*fMP~ai;(L7 5vDO%$ԞC?l9w?C 0Hk #ǘQBqAy]Ygs>Rk7ѫV Ne&s*\(>^Ij=TIтb&.2ٰk⣋#CkEpʨ-g,) Tz ̃ % !,Ms}0\Cod?LE*ίz!iF@UjI)sAlD+Ȋ-9hF&cSm} 6\GQwde uPD=1Oyе#GT5bNZrOqWdFODxGv%/ ΜD/и/ |⥇}췍f^>TNhDpֳg=ѩ ڛ vi%qW9xנEfK OtDa:V+A)%m(ܙ 8-t(11/ ޱ[I"ldKTg[$,D:~(7X} CƢI.7cj.QiLmye.ŦOX&%HBӁ&ЃM/SەT3<H;( RR 4Kn~tSb-3/_OmA>N}j~ 5|XiXDwڢg9|( 1𒊁•ś:"~FJ E)`In0'`BGz<;繳wi TQြf<Ŋ{pl$\9p#'nޙx%mI!p^ڷR_eTM. n݂w @7,4kpG3gY`QTWn.YӇ䁴U*DxXbR' ̴(Us(^(H8Q}}HnJ?AԸLJte(HC#>#ȍ-El2y̰b5wv˓n@4QDzOP7sZ޹@)Y u@&ջ-܆ҚUڎEDCPn&!KLuLrK:;Z>JAh?Rbk:uv?/ak᱉t/BX+TqueCq0[4惪&bMᡢW;I&\o m{̷CǐOQ!չix`c0qrsCGM7 <<(@Rp>f?iX~j> 8P֓DCf5kCghDž,Il<"'+/07'.Oz4}GR GxpO/oY> J M!Ipw( <ろo8;+ߌy\)϶~AO|aq`A, #v5%= =ᒽYoF&2ⵖE, MjtfiAN o}hӋ򦡶Ætͤ>$HJPtj#ؒ34(SQ͑ qw{y!:]SLդPaT{zc%9f8<6}e8Ֆè͓^Ugj4kϞ3}Qfq@c ו`scBi^r#&ٹj8<"/PlYNAhcIw\ӗx݁<~1wJ-j1{x2&DzugG޺S A[Sere٦Bٶ?bR אG+|oO VoթkU5TDϴJGy r2-6g&wAdzkNMJCi۩)`ig`0NGB}CT!~>s ^OV|9\S' &1qkڴQ{qfW==]])ݳHz\؜rthѼAv4m^LDBjVdWQM ) Q`gm"`BI!]\Yڱ y10oЈ״ѸM ip+ i]^HxO-ϠP~9ITk6mf2>~ fڀR>#7ŰTH!rG@ ŮaߧV +uKXdQ2N ^rm9$JMkNXicyG+A2|Aːq&z,޿5^(/ x!hYG bߦl>T=)!"Tp̟p 0믤.VГ2}DWHM'w_Tx'u r/o?=9%~P2kفxGf0gY\8p,'@PLH$A@$*S%^M7].T6TɗL^Ά4(H b/ '$yȊc600fvjo&.|f,z`J+?LA.GZKo$%/+K>=l;N }hC/5[ t̸y>x = W>Kl\^jãklۋL➜{P |Cey(j>+T!IQ"8xpa#`cbC%^D[WQ`ҏri#6>T6L0:Rpq*CH$!lQk otyuNvTZߗjrCyHwz='0K!1|q(ʴ{%Pl!hYqIc{ ѳ+'psHvT &7M)/vs-|F$LF3eȘ`na<8/V7_67a'jmp^«Hj9Fg"3_9=Lֲ1SA`ǰ9:|gCF-%=z8(uZ,]4V|Un.X^H B "$urI #LBsI?J+1+0 T*&ﴔR㿞pOLj)wv ^+n}C4GGT,H0hYZ}xhx[Yu8'W3hѓ܁M 5ߩVR1FfV2ygn$(dKx2c v'G #9;04˾{F shxA=Xo8Iq+M.qT [|+ Zj$) p6o@'cCX%[- Zq`T@gڐݰbO8Dz)rC8׬b>/s|O\F[h~xItҟ3n%%c@ CR|Zߦ 1F*Ӄ/D6*Dl%Q{| dm Uװ]"SeYXkJj%stGʞl&r J`ZNqL˿B ,^d[N@X8t#dF+~c6$Lw.E\ʜ%'2XXRE 3 e|d u ]b^a֌.1 "f7 WXn>M[D--W:KSM =R/p%º3*q=2x|ԄFbMhkM ˕՟-ˊE_`j'hT}fqv-Cp䆳e. D<vЭ=T\ K+!2[zq2x ÁlKͼ"'TC8!7yq̘oYM vJZy:dER[ZŞP{|I%ݫPQ<$^Dvc|!/r2Hb}b.2}8b< ,6ąs쁕͜pȩ>ourUu<+yH$1)Drv4W[pdhrw1s)'qbv9Зڂd \?PuіB 4K! RI(y Y|%=Ȓf]Pp1h@20nȅU ãggT J’~ z&Gz\ .nx[uHNLJNCR$Vh ^6Y(_E Y:.}N()|mnBW&-X_&{C'Crzo!J_RVt%->s{T(Eb>D̳id\Mo:־VbV"-g awVrgdYGq4ZEryd(,,_2!KA*}nӡs{#=--uyگIb}8S&ʯbHQ\Z s?waq.ܑ;-4W*&k^'`g?/X ti{,TbV" 78BJفh6%$]LHkv&pW m>^ [mSx1N<)1J E="RBh2|X O)0GLat;VKRڦYmg%x*, xS6ḣ@v̛=^~&HHM3u!.-]1=ߟ['mH: nqrmɪ'wrׯ\qŕp/wŌ޾8phfw_ FLGTao' !;h!o*GӜ@=$-'JG5_aN0_.P3)Ŗp8C0NV. 6:'^|  fsb+^^6{ĨP,/g$#YSvsTv uXCg[B₩KC k zܟCօW:H]sl9 =~FbK8C#\+5C,hBK5WMHGRq>jh4R9YC #08CQ_VeMHIpqN k䧘.IL_2ɇ6GSXZ)[~l]8)rlJìG*֚f;k&Xq*RE'PpWZYB/)' ~/sZ|[k#}%yI&Ne Zx7mskn7'ucL$/ȵ?P++H0ZO^Ewo܊:_<+q^Clc(0SrZ*3CB*Q*&Ba/ oHi/jqWKR86ff)Օ>ߜW_. |Σ,gޗ )v!: %dSڏ:|y{;ɘ%۩B:H) ~E}ˣqVܗ7<j"9:=#(IUz'RShh4<`(R^.$찄—M&]b%1pBތ~K }ji%^޼/j&ifnw4.ju2YGrԐРee~n MmXY5Tj)^*=82w\+?lQR7(by@&B\.^VN(LӊNOc:YE.ݧ2b3x ߃ @<Е_K5 -p<ye/Q:ϝö@!Խ8C/p9]pl@Vx@egzC1}ya B]kxsޞ,%9npt+:R Cwuz2<Jy 0BXXЖk~|>9  +dG P[Sj~ `$}f78ç1 \UwbE  s Ʉ  TUC9T؅֯BdU/S2pҢQ. w zNA$~$ ̑? ]v*d"ޘ_xJ67^ϵaMsObh.PyIJ(EZĆZaD:y^z?G?S'ɬ57͟=Ty kf1L2#}_,E IH蟛uPxWy!Z_SY%?`H{Z`xY#/S&H3"GYRMo%u;`i-<0(|l#OF[1GfK续^NǚC!t7 6!g/*ζE | ԍv0'ʻQ{8"w/ 9¯rrbNS4 ndh>)Jg=^0W6vIcC2vv"cSڸYQ+"A ]o*0!GrgzZq5o\ "4ͥv Y-YZ]V*y5P%slahaYg$qFѿC>}뀛5%.-H6@x0ӳ@y&=CAiB꒷̗NҞzǩ՛.N̲bٺIݨ,ۼ%|AG{4^ ;_=v+{uR4E~5aW"K]&ARW6 VR0H˶ڃHgʸ7#a'?Þ]G.yߎבK#RcY@#l*DNuCeF!?d2ux@l_?Ydpy4^TFbVYQDZڧ _D!fO5`,2Ѐ}rW6qM\x3պ.Ń$骯f^͗rNDm:B{\/Bwj\L!s0a~A0|ڎUԔz;b >vJD+P\%oI`b^}x=Z>N*,#ۖ-6X`"2iF ׂ5zO/ŬsU4}gq2 )#Ԑᱎh%!q9ܻu繢o\FƮ}p! <4,B.Ŧqy%t#LPyVWm"y0Ym7Dq ͕ jo[eGbHqϜjSl04#IltR҉t),чhb- Y2S`3(]$x{ E-1Z@w䑞vQh%pKBh?ڛ1;J=bMSO|D61tdYPW&^B#5Ѻ'cʲ:2[O:lwL? _Ha^D[5CuǏc*84&FP%l{*>FdLV3K^f]bp?D_wEY7?ciWݖx,1*cKs;Jb3o G#C+!G+je4=/9i]3ᩐoi/&TH w}ɘlwՄдȆGXwh&i!w{<"xm4ur M-dpάl(a⽤T~3 G^Mc42V 2na Iy3 8UY~ I[(v_{r!xW4Zs1ԅC{$ɨRY [a9dCsgX伂^Ϳ0% `qCawfn?ϳej;>Y!2>,AhO?F R'OQG󒙚+a}דjޯ,՟7 EvT1'=5AsgTHYTwڲ, 0=+5W!%yĖ4Es]Mߡ8t{?dfPBR*1m)D Yyk<; g>_?4j=*{A9^"7IGo% r!&mB85kWIjwR1OQ^g2Ϣ=,bvJb%@S8!Nʔ'y>"oI/}'hw5ǂɸX{<0I h퓚Bv# @lJғ DAX@b(doͲ`C1@鑀hged݄y%)p2XD0ޮ01|Cf~Mȗ`.0KmRR8 e> fcƆ>xKY\q)7s25rEmtZGZS>F.{ $DJx$U R2/AUX*G_–1UeNf0@>'$hȬcwY2SԨ 0g)0@Vb_"3=$:HVy͊Ͷc$D}Zx("~V[xta.(`ʞ&ZW~9#s~HAȮjw/D/"dkG])a48k4,/k/.HbRZܜM#տr"tnXBd#hPz3d U>DI K E2#s];Rpe!'Ռ*W̏y `![~_p!*{e?ȹ^OSmlA/u"44V&0Zf;C[R"aܼ.6IڇN ݄雥[-T7[2eǡ"!;2ϔY8/hH E0 MO~[Bu ͯr } p5:%'7.D!_vYI{.6FC([eܲ)/҆ (RC!ڏrFY0k0~w+܌rΒyE6jsn==O2-C~A^~_C?'DHSS|< -g!0_0mf F혞1>#nV+%8RR /W/UcC?B_k:XP%}.ỡ̄To-7T-H h5Aq   }\(3:@ ہ  ӕ Z D v_y.`nyVҬƍ]kcD3"{jrZ1#A0mWÛ=V?XݧY_lP9)BZ7eP,}–,ՅXVzXzJjBkk!w%̃Z6ǥ`~R^)}=Jia[:dJht Zج}/bD]=S1WH_wP-^ hox.tC ɪv7hD}".{ͅU쁛adʭ{#@R/O' x8Pn N1i<PY+[vXmlhִH}b늭j?v{Y hQg6$@ae}FX.YiNsxpnݴkB 仝зk(o?l_cbFQOү; I\ex xz,Jn%(|2Ckz\.4aƗӓ୻7-0s5uMUW!kgtq%if%|:t&8CW7 MCG-_l5ՙk 1ސkAJTb9G,Ϯ8E7 1zgv#:oklBr_ ʋwB)(׌Jϰ,ʌ 8&䘥O2]3+gk'Z*^Blk*y>[=`yzId$"nJ_X$F1 26V aP{'6 |BqC/"a~#O#  ?N1u:F LOST8xP ~Od?RGo^] x^ތ⍤jv1c`0|*_ED)-7@'a_\μ޳okTw?wjՑJ$q ڠ┣mʄwm_}ˎhЈe[SeW}Ð$^i:| l};|[,4f I4NpcM0nMxGQFz^]d"1e.Q|,l8ѸbFXp? "n/B!h1ƂKZZ:8(Nt[ֱѓyn\ h+ȉ|+oN&@x;s&IK5d[Ž״ll7oxn>rŸؽsG勠o3vSs2zTb<'tqC9E#ӵgkn;0,O)VB%E1d"߆jXٟ3.H !*$Na^ @(iLk[h"H A$VS~^ ( z$ObCOP2cJ%!F6 o:j! ߏW?Igtc t! e=T`X~I `osCb @:7t8GCb燸P'I |dΛxR9_8zjoj[SQp= :4)?>_(?i9@h ;*xwm07K!~$AU`OWgztzOKznpqJpP|>% dF)|@x#rh ?1K[ 8@ Xj,جp#*HM60r%5@zGdآܟh6e ? ·88Ç8\dcQ jtSʍdo/&#Rԋ5U|RN]GwΛOA+n:FtD;y!sՃCa8"%:B h?g(}i2i!;n+̣r碚 Z{x{Bg8H)d rINVdކ:[5!BC2 G.E MﵣYjm'ߡv,=ç/J ?mk1zU[ń}r\[arb,Q+,_Q{2PJ*%L杗I|0ze WF08/eMn@:;ag=/Jtu"+~Zk‘}[~p`pJ b&96E溈8b{xnYFwHHQHBFwg=?QEnp\'+nRSCNM|@CRmoTD݅qWAH:*7TkО.Q$ZWW(R_S` ]? pK75)q)kzȉX(FZ^4I,n%`NViQ}"g7M .rgWkĀBc)ߝ`y%izޱȋYC|-l!ިfP^HL(EVl%#F @?]"C(+պᾱ&|tWD:ft/G'lYj\U$"HU,AW w#&|\X2rSNJ?H \K;H2 9{٥0A'JVk!-f5Y g~$<['+pA;qAd. C kʓ&1>&>(]@e-YD>p/U,^ N{|.C_ONͺQ%y\M?tO4*iv=܁FJ$2`jF)"RP$CȐ(HdzTDH>~?9>{5}>Iס?*%jݚyZ,%av֍Wytl:sի>v{}6t}VĢ 첎5>;UTܺM]["oi U?;_]"X8jIgĎ, 7LMɽ=-|g0Z^V`~.FlpQ!C/s~Һ'JYSTsnhD3YD:f`cαl"s.\QZ&kkŻdc=+*cj7K*]ϙ{}`|7\f79tn߾m l϶SrM"`6MxC8)mf}{ȍأnT^zFm\l֡s9&2Qz//9Z.q$M'/y!Sj%K4Lxp|aMʸBR¹ܻ^/џruw^}1Ly4ŋ&JP:$>}uќ͊7]S$9qJUοrÇoaCl{a[4ƻWZFX%/ \o5ktdV:%'-(W}{s_έ\on/l}pPyջ}Ǭ( ?vsDk@G!IGNca)s" >K1+*fOF.c0kݑGwY;'%I(%H'-%Av@O?efr5$ 7{Tk?s?I.pmн4V lylw"1+x͗܎xת) ӼH GrZO)"ez=QEr\xJ q3iJ}CC/ɄbʤE1 2nMߑ'vuE!7=hme^|ab0T-8 hEɿ.BvaXF!`ݛja ]*I0ؿ'e'3B+0 8 ?\őW=a<4+1oM?A08BwMXO"\ϫEdh!-Prx#{S'Է5V_LAgF/!X,1~'m=qQ7羪H%z,|5{ nWuYMsZƽ:ʩW{Wp,8Zs%GThXBӧ.P+h}ck_5?»h=CaTwW/̜| q9>X^)/u|1k~?ڌO|r,y}nFv\~`ӖSq7\Isj:Zn^p>][{WWiAKgʘA vX髴ZC;oK1\:i8S6'UJJy[CRJ0 ηqrNsISd'2YkNe_9Jyo;5?^wNn?4hݐNvO݊:lL Kwnx9Li/+mIVVxoGc;RpS_9yFŵ.HS)ʡ&3Vslӡx>?o}E\ֹ~L׫X}镃Fv [5 xe*JtݶT["_y=cwJrK֙ٻ==YPJ3OrG#NNҰ΋i^>ctUꆳ77D|ҺQ[ ~ywҲJ!|~wN/!JUrWWE3hpڀk3*r2:Z]C{aT9V?Jj}!E;Q\ݮF}3nҋ}(D)׼vu7MZ;*; ~t߇ ξXU.8ft>ْ}cB⣺\Ƈ\)ZQCfɊ#%"nYUie|W%sw._^97۵$1UTcIBBnK6WFcc]_?TwG,!ȴ/Vު+%%X%6Egعs{cߝZCl#a W?u堯8|Gpzxq/<ŋд,12iӥ&@dM=@m)D[[?&#""> gL[HoR6 4GXKic"rEmBs""9D!-Ц3aJf 4f^ O?eS+[W۟U{F[Ln{tWn+]n{=p^>_U^ QymHہsIڵ~mB_d %_/bW$2^ó<%<Uj+:4G8I~]{pOq( {_o;Z'ܾZ 8yHخ H’aO!\@Wn fYEӅ|:\@<=ZCgq.z8Gg0YIq)i O4)UAGq>#JCgq'?e&`}lP2Yt'4S23P~& B `K0̂, %@/LPp\.jbql>Jg~'|D:&_!mL\01C24^s88Gga,HЏ9)A!% -zir8xޣ=lҲN gX} 1t.]5AsvpzhMZuÓ^} FâPs y.Db#ԩz31urWhuTMZGyr&sԨ6I+9ԛy6uVLTEl  5ȤMG:kVBCLDzgH3dC([U2VbA|,\/aH5`i$;~ 4e2<P8t1]p;+p e3tG)8$C H[#И>`O-@ q2od{g>6zaHCX 'z,># EL]{0)5Gg>0&OgBRf@3HM|Ñ2l6u@ Yl63Ez{a6 | Ьu0iUEu,<oA4 t9b~qߪ}FOwO5k) j,@L,62F@KhʓzlW&/fny, /'fN: R&aHYr"}yqkMCEPGÐ1:-)ì1ls(LPBK# qLshˊ8u&?ӆ vy&GCY\6.^♫pJ{Qdz%hżټNoK}\;F⧪fMmn+uWYVj%o*O0y 僯 Bf}8yu]& 5ji. bRMTIGS'4|k.ק2զh߳I7lIV&fe'.V3?ɶrRb$A/fi "/u^TQ^k1c Ca;Fu;Rd}--ɠ0q\^Kv1";f:mKjCfZ,22%Ͳ&lInksY%aǃ]2 _-55HIӵdk;;a^%Ƞ97'9mf+Mͩԥ9️e [箽w'_T?as!O [\[c<0i:I媜}v,ҍgx&P}53KU;+ig݋oH$QnbHyN;ͻQ69Z57ѓ:hjճrtaDaKkWN3켵pbߤfzU&5G݂-t N֝،IE."}&w=>OӚc$si]fcH0W-Ȩ)0x'dGcGe-=zqC^ݎq_!4wUz z2SJK[e}>! {93Sjˡzkro;u_t5Mr=)]}Ng/=.vY?wvX%gms:^ޏXTH KY_+<oq˜ХSEB:g]ױ:?KƊGB҂=j%xeC.<+f*Omab{q>̢Ef ֯:;5TAX .߻0IRbLή.gjy>5tVIYjewqWhM[45sEZJ^ X"=rW}^[.W7Yrٙq)J}+g{ RzhU܎b7Y72S}ErYY!6ffN=-[iwuʌ63~L|?F.PmnPJLWI~UvAZn ןKңzs6Jץ;.F^#x|]n{/lxP'̺;UQ&޻wsIv$sκ?\72B yt_,R 驏.ӚTꈀ+? l5~Ȍu$[$:\w/kF$u9gaNJLvm>&E1m+ϷpE4N\: Lu*D5y~.WOSQj@0yfb-fG_ܚss.}M(Nul[tM/yWmW=n\wVN?IqIx3|m0SsBoFLW!'g8tEh8=xomW;,lh\i8QˊIZ-]R4,k}Wdo;4?[g}S Dk.-MTkEPLw6bߦ';a-H\ 8,"EE1'2^T">.O,)Y!{T1)9&7 syl2T܆xLQrCVLdy<=8< Ad70R!Tg03-&婸 N G< 6\&B?[ 4YRn%yVgI&#N8i mp. p8$C.rLgr&k@cU1+4 I9Ky(HI%4yQ!q8 dq80a7XG5Zm(B#&4anQlT1m\?c }u̚ I` FZqW D~/<\_F4N|:M:Fx"p 4/Gptc0He S!՚X-Fˤ\J9<·1΢6J"A@\ĪXt.fʝ]G֒jA( QzH `7a,BZ[ bc߳G12q0:,LJa6"wtMK0ѷť˃'ux#f=q9>AOCV }wBԚu]E&Fr&\&fyį"ԆIZM$,`(LKXbN4+5fF 7P[Mb8Bp0ia؂ ak`ϸ\J m,e p_x,&bv! [LachzKqPu(): 5j9a¡0 B ,a9DH0 0`p hi0'e "f"3(#aC7W]`Q1Pa8F =BgKz (Zyo  >Z`8Hl-0h,ET~<0Vt T \jzdG-ICx``B zh]PsL à8<4DF"d5 h"-E hhR 0Nmk)׀r,%sPQ€@B`x ʵ4s$O TG ",@:'')HqJpj0'Ko  88 352!|X(7m8(U "fQȆ` J jЂ\ Lb= 'Re̖I*S|`L>av~5 ppPb[ZˡP!,F)%mzr\t Sab,%ecs4t}a()dzߘIPd+i-߄>`OƼI* AаdY(*uc2f3xjN>62El<%H(j<߄P:x l2Ib=Lu;S%Sh0d$(J1PR `Z)Z3`YGJdp"}7l3[BӜQirPoќF hHD3)o ҿȂ#ǣ0͟Vί~F :-ZQQ?FhsL*J{1y2rX>ГF* hQ:i)0 dYP >2Ȇ'H11AE޿-L cB?Ug°f{/g} `:{p>ܣ)h̞b:5{\`9qGFp3Bœ-#n䊬)A%BT!\AG!8: WΧ&@3gJ;a(؝ MsH7*ݳP7a9RM ʴED7X,! 9]&P] h}G}&`lX_XBPV1iUa@P ii2" ^)5P&@,F `'DYk:)TQ'E``\$7!~D<TTP22d̮ܹX.U|.@78U;zhB< /YFK1 EEj oFy#@!G=ǍJVq)1.#yAڈZkٕ-&K~L=.dqq~\ճ<7͊_VuUׄ "WNLH/˟<%)')˥'~PBo7-pTaﺟ6 Z.hڰKӃCwyaq}\[6nlͺ˾Zh.R5$SIKvWHۺmӛ{Mxyj߫W=:TAϧ1j&S;}ױ+9/ O\{runu|rI<yb?|xz滔DCSϭ|<7WgQ7ұogumuA-BIm}xbjf]ԇ3.K5Q=//aG)*Ӓ5=Mm}²FEig])i%G9>)}REc=.ޥe\ϢX*[-J{ߖ  )E+.뺢Tiۏ6j i.J/l}R^=5Wyrko<{{w(k_mT\X-){3]xez|mb-;0M'-ZIm2ycCK8NmFkzt6V>| KFDIL7IoztS䅗xoQ]1 ?XR٭7D$IWwրOr]Ã㖦/lyI?Kjž'',9PSyKpb$E"-%n}2Cx+6F7?Zp3s,JJJSo، o`jߧuU!CuV1+ ƞpWs;ᅵ~9KSfP+; 1>F^k,M]3#1;d2tc厍W&!FEiOUǓ{ީy:)m |dkM*ԏ;zT.U‚fh mM,Y5uOqߒQ6sOz+_~索1OINc+:rHiЌY){RRͩ-X E ]W/ s_iј2uBHgQE;En 79"ߥU,3-|nBZguыļ}|_V9&?3~|$0) Plqc ?gUG彳ʂ{̑kg-ZpFY[o'W$E|Qht\W7^.5.=ΌXldW1LF҉2Wz-mvҺ8DE٭x)yQܿC-W}Pk3Z(?wi3Ε ]53$ׯ/e}n53]5ӼewG|q؝v8M:r3ѯ?K4懮<7ÓZsׇJkL{v`C9 }XT^:up9 ©t;o:mA:~?o a?k 0i;" QER´:%ԟ E(UeRjb,J48" :izq \6f\B*z4f?& g^38*EePLM5#_ Kna fJ$q.cX=@q!HY'm=ϧ(fGI}gZt7 6v$/L<A bȂ -iKHaH;7V:!9b?dJ9\}c%Sڃ(;asٖ0A6!AM'܊GѱQ~[dRk2EEX dRj$֯d&J} {wVb.ڈêAf.3ڠe߀V k%pk)SP6w톆Bbp!ţϑ$͜:4 g 4ђUCM G01!LA AT܀ жAj) $ArxkAn`Rl@%,𨽣#bMT2H7p]z,jwމF4h6{J Zs|j_v8TFeJ٩|j*K+Mًc AcLZ&4ز%ѧZt٨)VeX:7hS*"DGsx9xT4JOPb%ɲ&UDlf0к6B *ICR&Bh 2T]{f: $dXt%L4h~`E>GGa4Mbt$ޠ?̆z.fS9)1{MN[|0}TwWu(%kѪ]EN>JgSLX{T  .]V&=0;Mt"68dtaV&e 嚐=A80 5JE9B,L9  hDġj~݉a0ЦU6c S7lO;;,AP#P1)B#)HBCi:,q x@A`è'p3SX=Bߛg=dGe@;ʼn \DžEmֶa> f#UqWEJ(8V[Gdzcy!,M1hbl-㕴Ž_TwrW}Uᙅr]^cnpPT߫Ͼ[R#4(=?̀yˏ!GJ?8~̽jx'FUl_sƐ)Xv(E!-amXrF:K\ȥۜ&dRӗk=iWz΋?i{I@sUJL8vZGEB{sNlrdDp ͬ9sJ/Azqԋ{ηZ ׺byi*._齢3TBձ﯄D4g+bƸ2JUv9E=OO|OS(|Y芳Mb38YLSAN'j#V>tceAϡɆw_0K}m"}MM~N^-CtkjEE]\/+xCDwfaS6QozJ[u/5V+S1x,-=ROWq/1/x7tPfòF-=]y:dIofeڤ"6쟵{aLG掖w7==[sx8r[Aģy-\6>&sg\5]+"'P"Ti# o>l`\# .x{-EZƂW`+td„um%2@x'1di&E tހT))+s19*oSy|.e>8T982ި?\kD-I_zc)sp)bY|aM{1LcNPSu*10%Y.6*Z#o0U(ť P!ip ҂5}hCa &UT!&U٩D7{@lj=XBp  @92Qy&oT @ ~>P!Nzphvy_`vc늪: yY6̼Q:9,Tbv®0Y/~%@H&) v=Ra>3x$UhL&m2`ZZ3 r߫=i߄E}ӻR(ہiuuB;{Ƴ1SMO3kݽXSc:ѥ29DԦΞ2c({ꧮO*iգ||ib.e--%'YFqꞖ=_J,[,uJ7,+eDs@F*ob?fmTȮ]gOVw+RW@>xZwok}I{9$:6.-s@Pţ!:J˗jd5dVQߴ7n\ɉ??YL454ZhiVu{ X-闢wB-58-lH)-ȕl^ \baOr>Dci4j\ggi~7pζ% o$ _*?YJԹvq!yv7ƕePx"f?b-R6΂v7^s<盜@[`cg? oEaCvZ5k繖ވ|x24_Ip[jIQTƛh䷁Qef\ `ƱLW~h/ly>>DF>R\ĥ}gFCjz=1" O9FlIsR4zlJAP?O|;=g\ϏSV?ڿxwvin_w>6֙%y7w)9{[p;Ƅ:gX\{N4օwm/q:,py[ AxZy1VH0na㗸{݌ ڑ(7hRТ%~ *U}}^ݷu}Uַ/ty: l,My]ѥ1֡>rc}$X%ysv lѲ;!ha`tѽe//&wCoǨv[عM27EPtPvs|H>gFIt7`V=?{9qJGe,-wYו;\\g5ӷttŏ]Fmu8n(?.2wMigS~7>?)eW,% Umi`cu+Ɛvz(vvݎ'W6:7uQtR$.8gҡ>] q#@4CC3񷬩 {܏9w ?a-Ujҷ7.{ Wck :@ſ4p|urj= U=+뭊):fnN7,ub <ڟT@ p5mIi\[&_;Xh=Ѯas̮8n3<ОO<6$!~*|']O>7ѯt>U;l!~rh+s9H{Z0$)P˟^z%M]X/9K/|KwѧY>]R^C-qkM ̐ :> HLWXG-W}|:Ul*e%oLb,Y(p: )yU"ހ}\2^p@I9)SKw  }:,,xPcƝ;T¯`eX(-(Qs1 ?x"BǐhЃ]Ingf5b'5-\\.Ec=!8dM55`woN]%q ](FP0t4&>= <3xͻ5Zp#Z%'nS^J/OLb^<`Ii,J| (N TP {rJ&HBٱ gˏj#puU6kZޯ=[͸iӉ5b*'U4m/DҐ#Ӟ$K~&+^Lɽ;=R'yNػkqs*0vY7[I D"4ߓԣ eĉ&/* xd&3%ұITvFώN7}ZKϰ</KG wH M@Ä{RM UM.'!'ۻ F'ӂK93sUJ i0=E9Ŷ>|B+7A PS-.TJnSAOt3,9W +Xb [TM:TEٙ{ùm ~"ƻ("0Ci6 )5W,T6gJϤD^]\)mY{Rj1N>ٝ"du6 V޽2{qTgLRru*j ppEd>vG;u T៩(O;ۢ?`۵%`Sfw\Ϊ=ۊo0k'zHMq\a9=mu^55/ýGH >LX^zmJ&Ƞ% kk?N0ҨaGo|U}uu_Y|? FS|+#.Ya 4'ʿBTK,_C,_4[Ru'j!}Pkϒ7EGRDZ:ќbB-cŗ{+u'7. ~η$ϦrBWe{)iMY2zuu(0Y^wq lޯl\d@H;݉T2)Pt6l[({k>nY֛ͫMG5D=7ْ3 H{ٚB`rFJ\j i4h 2Eo7`iwX@kj(c†ikZ";^ӴdB"fhc[fob{nL&쏜 2ZLȎpo#rA\B Z?R|WCF* Ga4ɏ˵_p+ T*3ޭX8s#[@M/f ezXSn;_ hY.pR4âM>EVeBpX8VdW=vO'1l*v&4`:Tapa}=5Gf)*Cv8VG|\%ԆGc xпK|B4GIkB[-/(t!;^RL t`=d}V9Y]-$orQ׶Nt6yK9[M7E>γ"ۆ 4 n|ɣ ?N#6j?{o}Re(Կ}S, >8i-.M3 ?Ƚtbw,xN2M\/Gk#B%uuEl.%cwRև[>%Ol0l>EX2P8"9Bv}sM{ZH!װ9)OZ'g'yN=kT:/l'w'Q>{BaXZSH]qM?V|a=V(5zzjC= j]ڗbH9~g'aٕ`DvIBzJQMrw\Q׉}’5 Hr,NW*G+,W E|Ɯ=aasi!Ӹ9Ӆ9C.jguC(ufI沎agЕ_PY4+ecvRg' u@dT p}܃yەڡҌ^ Bl\?(/pTu\axBR6"z=Mlp 61]la yS3^80nt@}U\w~o&;mqNB>}#SaNui I%tf~~3iJ믩`(5FAq$ o4mKqr[kNmhKk+<>.4}$ZI8ֻ@'34~@>[7ϟ7L1Hөmne9÷ ~P p̋J^q]w_I 6$7|V#BI0fKTU 1{tbۤ0 "e\vM"2Mĩ8#3~Va*(ؘ']z{d(+Œ Yt;ʼLW!a[8`.(t\mxuoBa1`0ZKCa%>(?\bG}=LZ-ZeXv;{rn^<[Fvgq/"T^Pk>paAM %`|aBn=J*gaX.tScR9,imUeS0S7`L*ͻ L1M#qRJO]~2`w/\\g?'r}W&qW ޾L=etޓ)a2rhvk7,[aYl r[bBTD ŏ$ɵC:2\l\r+z,_{,8?2tP][%7ٞ*SWLSڀGL$ʡ\ ^UW_`S/s`${!5I+x9+DyK7+aUUtUgAO=+"dk]$;ݲH氏' [/ eK]e dHȌbk!lAe b?F/h(I# Vg'6mDb'-J| txa;Ʊ\C.41KWBGXؓJ}k^C{9m#Dժ2>%^BȔ:%aJ,~3fmKRSa3 'Ro(fS&: _Ơھwq+ʼno_6'N~^to vCT'lj㠶B][l?n}1 M&`D 6M(@#;Ҥ3ILA5(&\77gL]0oUT[!$b=l˷!1nlg.G1ݭHXzM)yQvƪ{&xe**ş~)vC3SoTRe^mq"MCkPU auC"=q u9ڑpu]chB;C ɖhmi4]p/8IGW{:7[籅>(?@')xvv2W[&]eۄ8H~cIk&٧: a8^i{^a>,IhG%RRq̵.S Qo9nY)@XVgj׭\Q. t{h C= pVɻT/of(MȪ0 3eҔ rD8ɄUʟG8%" KH⺽x6TSCv >M5[Q>F.%EY I! Nfǡ|* Ņ=5XԈb;3 jci+W%|q^Ie#%KMjy#ӻΖVIa4wd,BZ2>ŪyT6Y|nd9sÍk˃tx{x{+)nIDBH2sFz91#Q6] I*2@{\x8lxÅh #Vn Amj`3LLYSKM_W#4ٽ|uCYb <穐]+3WX8Ofa~N_<&T~ Bu<6j5EJVo:%5#yI?Y~z<1坩*Cd#%uPrQ攧y>\/mbg΂FĚ/mkm_: $ 15ᭇAvjUDkW ɓS:ƋezIXZd 0 rI{O$- M|0vǐ54F{4vǹpW /{n1M5V8C HXV)k`X*Qzd?qC)m0ZUnE`& k+W( nqō5,g!Ϧqo9.I0Y^9U6fb ; @MpY MkIbx ðZk L _N:ǡ#>*b+҂F)ʋ]}A$NdrB U-#qĠ|uj ;beaFNBn,|c/!|H_qLxSs f4 ~}9 eѝI.%5RR:J|g36nWg G|_cP^X ?My*yOE!P/*Nj=Xk[ ID軘 Np烪Q03(AzRͲt d gS-4?>πԬd,%&zz(}܇W paشgVq0!nX𮍿blų;M8r ??)?Ps"Q3 z(. AX6%3AEOtT\,lj=bv:xQW"y?0d(w@bd9@S~{[p7:duyyQH2QӗJ 3UdNo}ߍO NOo1#`1(o>#/DТӣT]t{hO选1署K>FAcV]["N(&JmB 3yΉ@`CJVޠL!ECMEt{}">HT6! (' ;86f+(0%iS]#UQ5p+hL4`@ܙ~ \q273K8ӷnr%j3+D䥽td-`tT1`?fW'Qs%p!,ǀxFr4b<:!uLKy~k Iq.~rCןv5E\3p*C_$~{f970GB K)y~j}[L_p[ɏ3ShL" *|WlybwRBJ2-?_:V+WrO*"HUVn=<(% BU ?\* YZ+Rn(kϜ}{pA2T^djFN74MVttr#kEw6BJ.1ѝ~&2o0D4;kઃq+sߗwc5aO9|_I ?l};l$O r|?BSvX^N4OGdEe_'oat?: ;Lq"߶. 4!Xb[}p:&U'HmW^cvbh;}e:#|Ox Ǿqr"y}(,(PC;yșYᰁxBbp)Tpzt9s{_jPbc"*݌Klqݔߥ:00pDU?@k P7r"#t%vXdO}:q 1YktǩPq9[\5+ӿ+kf"ړtw2fcӮi}K~)zWs# 8|89ĝ@A?(D܍{5L %t@}ؘ.+<V@=5߳!E7 Ya[@I?lǡ2]C,1!384ݼ891!vN OVYFUI+CMBXO~J/L/M/N/O/P/R/S/T/W0 0 R >> endobj 189211641 /Length2 1016011065(UX͚w@q&Xpww NpwwwנA n{l23'}W=SHڑY@Ff a{# t20\XX(6nf&ja8V {3C}k) \PdchrtcZZp(@ #F `df0Y#0He#'r;E"i`F6֖n#1 ]\RV׷2t+['G=@doC@'dcH:[ ZX^2s3sɛ9-@ZYo K 6ͬlS1ӱ7sh1323ZY/;@^ |3̬@+X1#8dg0 ob0 qD3I? `{#}0I+K˼8`Rx#7kQz#7kQy#7kQ1X fc| 5~-?Wm`AVCS7[S_5,/; V-BW7UfZYyN`3o`!BNC 翬[MAM%< l寣gՌ\/u3 w ٸz0O<:ۃL_fc3 m ̿7xMBB4uv /BXJѮժ?bB<8{*L$|uMuo!PHq۱%?Dmk:bY+I8<̑Qރ]!yף\ߓΡ.jXKD-ٮ$5x-!ꤿy0\3MC\v.фޭIC-F-l'tED%vJeʹ|{98|R/fa$*jb(}&VsM4eo M_Bܹ7gQZHd@JC*4/E+}RbjPTwʓ b\kX<K\@`5͏QE;҃E+Gȃ_/3| 4bGh?m-ORsWhoY>ejg|^[(MlXKX[+|'>#p74>Em*?O+{R X9tThbc,(m{&BQ0}>y:6DZMt3j?;,eE@p3c4S+Nc+zSbj]?9"o.')hx\#;>| Gy牻2v|_Ġ4fĪw47nώҧ?[1U<TndWE$ tFQal>b=@!j Ʊܗn4#-b|uuepNN-rH0FI7YVO>>2a*XUgwvahOvߒav2oBËNV,ٍHT;čս")!?5w諹1Y#BL>1/w&)DrHrppbX <@1 Hh'kVE)G4jB&<7\2Αa֕>hBg3aetEyT[C)P|',usO1|Dp_ܗ_>9A8!! ZQI{tWΜe$:!:[VVX\M#["T0 ?SjQ.u'C+ BU3JB2O$sgK5V" ]h[ĝe\&8.Z[y (xmQXwZs=[6haE%J"DWT.&mPk ?_0[iW4QMO}EhS!ZD%g?y˼V@ezԘ{EN1h ^(¡?]h4.[}H_r67[[oᾴebuY)CnUlɹu?D !ZNa5H5+u!]mq|Or\17W Cref|Zw+)h֫,+/-*QK*)2=/48݄"b&M]" L{}=Vb_pd/,j#`D{U~r(֞Njue 댦w6jjtJ{" S3D! T U^UwܧȩܓI^THh zz.f38 0)GU62?99v|B{OYR"H5,=6){C+\Gö vꍃ d ЪhYx(dAIz s7~w:*6Kz24Sɖ]sЄ> iHYfg MiM&XK:Dqr{/헼?9/]5JSZ?Md"fzzgJ9l^ -U*o ^.C3}j'PgW443ؤ|1fT"얫diT zgJy]p'$AۯV;\kû||0s+ /uX{nqc |gQ X8t08 2{y?ҥaLj*7V x⬰9c _|\{ގgy呐f6g5N{ ;`橯/5Dn%dGHAuv\᡽QJf!2ϘIA:?iXd x戼)Ʃ`kGBEU†#AL\͐_B6.ůX),[IcҔ'_A 9¾tE`(jh w܅‚]9y񩊿WӦ%x=,Y7!ȉVzh2H<]B9IXDgkNz8blޞX6wd\=V6Cj鍷=jT :Q~DžR|]بmpNziɁ]jvűd^sH%@GJg_:Nn0rAj},T{ .؇$a9) oO.E:뜠2it{.Y#i/ ͟驃Xjm=;ZQs@ +9ܓEºrb7[+gSp L>н+^FW}Qu~0 zæ-F-6(rپW#.5+L [?E2ˁ ᎾI3^V$8>OO\צG>JD3{q1,keX:~i*9~%. sZo;hYJM|%X=eH?dS|s(MϷi`E*Ă]Bxoy; ?Bﱥ(ĜE3ʾ"F:&D]˔R$X?F:I츒ܒwI"9ͤ Ajꓦo/C~Uck~a<mI`"]nSWt-҅Ȣ]\yf6dL~@U$ov.!XlKV.7&}Bq'B6YU>"!Ƕ$Sͳlj)shk7eU#k=KmOs?+OFJThKKO .{ Wwa lk/ 9 ֩SY\S' *"O>HlW2ETYB&9v#~20#rʔA.RD'uaJf%.9ﲘQ-P{gPsDiYP1T>+-v3hHXń"y%^' Q:{AcFa]c5-p3mm''xkƑK5/YPv}O<Aҳ__tUj–{$vYAn{qՇ=esi6WD_(t\/@eS4rfĊ2|qPGyWN/x= [Y3$|f$O#9$jup`J;ua︊ASI2%TƝ*,dfBMOq eeIneyvbAnk<2d``8rJ@KCվ b J<'#{'t`/6w؍t7f>VfBGT1:۵{6cͣ>=X<ҕ}A7VB4NދWbg<͘ a@xk T'`QBBU0_U\^1ܚ˝ZrJy<"wak0QMK'G`to}6ݸ{S|>&] VW~ȵ8n_d- 4{zF7AoTr ͔Ċ\8?*j8_ xS(8" MږZ Ugr|NVb@'L ih%gg Pg[2:ttIhX؟=븢DOPce5'dHN0z.".x-EYHJ J˻Zϟli(Y@C נ0Qe49bt>= G&mi|'bhN)MIc.ǂpTU篌1O'Tka{;WvNwӭF7djᕖB.v[̙{<&{(&HD|8q%G?Venҩq CAaAbc隘qO]V޳|uX=JF"q97KgSНSWxbo+|kh!(d<pVCK!!b>˞[Y1 [L&uK ߎ=G~KyabB2ŬmFm]q8lT <HQ}*ʞ% o XO7+ˊJk5Jni6} gՓ6;?J߭#SC8~1TUE:j],U'A^no=djBѷѰ'PUeE%j$-,ץpR,_nP̔xKxe^Yr}/L 5bJV<Amf5mt[_`m5y^o%Q`q 4 G4g4x$a {Jz4F4fo`Kw &n o3\_r!ږe裫ɕ88X K+_q;dl~0s@\9*Bk~;`H t 2 i \֦$GВg`1463a -KvhͶo'#}#EC `)ϲ蔃7w3RLSjPiiQ!; dce|hlJuuAc}+O(RJsIEM 1_ nt8"Qʜ|LM_hH +𰫲޶~` {?'DBHvSAd,\;'w:FXwMIow~d) ^gv,)Rf"229Mf~u P0}Vp?u:F+^B>d8Psc8rcH@'=Y,4iq/ D>"ɯ WdrTZD"EM DS6J[enaˑ%”y,AR ՠdV"Ѧ;U~_HKVJt fʗ|PƤ+( ݪ #O#p\ Vu}{5[<\u ;r tEJ}1^V,q'cQ8QE~7yD场&=]7 3n\G4N>EBa 7m@,y=gW +YEU$g+BQOBp܀y2:OzP`A Žs=R5OJ/=߷KN+"o,odD62[swIyc[n^0E2h['S{>2Qu)OPrd:0?#y3Eԑ1.gj^)ll,ˍψ;&Z6ӍSA@<1d"jon=Z[bSռj#YW,lWĕd|i:h޴Dk@c{|gvS)&׫8\M z!"osRJYk׹lE#tj G~.B-.?r4.>ܾ^a=Mc^H0Ls3 .(_mbmCʎ"%̗oNЉBÀ(xwE< mޏ4C?-ļԞAȳ+֊`3y@:5ĩQg W P % ^ mW۷f->jW\Kӵq$\ڶ*Kig_bvs hetkV7? <\K;O*-{#?Rnu 6ˍ[:ٷ\SXƦhRr).Nm=iʳ&2LM9m8sxM.Z'Jl10NΧ5)W?+=RHpHP&4@E0$o&.jipVՋ+e,:b~NLbƒߨ`!ql=3sў&KǮ[TLhQWsE-E3ۥ ]%Yw\[y`a 8hymgZ,)(nć8g73z./<-wL9j?nۙT JKEMK¡҇&mޟ}mO_8'?Uu Mn](rq)*CI.mhwr:̉㘭U:g#=/I Zw OyţIȳ٭V%#TSBŇQ/[e n;\z t%K@ 6P`AY݁\ nLg]2Tfbp9jQ.aU@ Bx`_U ZsHPaWLz[Xg˭ ۣ(iVɂ+t^LUX rgw'{%P/0@ VUm4;׮y+vOF B [hGEd;\ BխY/PGV _Q~AU8̽zJ-)"tۣÄv߱W&rogӑ_@`u3 .L-|G&W\[4.8|aLٰl:U@ΉuW5tQLHFU>L5j65Z.ZCBbTϽőPiH LVٶIovmuMA֯ݵ7o&>,c'ed7E؊ 24F]!X~Q;M~&yKM YKj3nF9*t*kg'm/9ǎ%n KNyf/4ٰ7]jspv '?o8oXhOTf_^|2ǚh©[bS5Nu6T7ȋnhնk8 .{f#fD־rLeX钇-.z TșrroKeL- O‡c~{9 \ԱGB8DtC6?38G-Gw][^K<0%{@t1{ýǀ ΅OvEɅ3.-1ww 兑wf;d)bb]PIũ]q 倗B^#CO,~_ߪC#K+CCLLi9H&`, Q?C tKc)cs<v8~h/HN?žݾ/E~@ Fq?@]@w>= p"yA6C4%H eEEkE_AVE$H:iv(?e} V*H'``ckfWSu_×1H$ͱfDyi]YDhݭ2 ?I^&΀U;YzvQTn)PQB(Gdۜeh< ?bg` uc{۾߶' ^>GFP쿶'gk\ޥ^nyr=67ySz,.I=DHg{\>@ύha{%~lkP(\r*!E}}HY2;-~:2fz&Byx3[KaT#4EUF j+%ḧ bk9^] m5s#4s?Y'm+mq@pCqGw:) A˷rÍathq-Tl2od+G:T _mlۓ :!H4̌duDcд`=j[,`~_ `mSt1燪9TK\k TuSVZ8m(->?&.C?cxT-DsrnV,h+LY N@_̢A`/-΁U)gG+0܂Y=K9%vԹƆȓ4݌0;PcJkfUD}SA߄c72ISo˂VČx1<}B9@ tixA.(ۋABA],AvR:E'?";x 3$Wlx:fB4@j(oO :NH~H/gD{T6fMYY^ڳʯ>! H2߮w,q\<{4uM xWL "f7 Pʳ~Z\ ޸یy(ĩ\ /l"ZBxǛ dbY [;h($X4Ȅ4=7n%&j|+~uOl 0Mg,-[NCXMp #T 峺!mcY*= I dz-K`~iA:.*ؽ +"m_)J{}KTm 6|bS HO\&lMMu3v$CNilD5%OrKcL׬EL_dL@|.N]QCy>$_[,/68YZOC,20,=}NMQ/%iEhFZ}UuBʊKWM&g(t'w,A( : ֫p!2gIxGΥ<6qp/(>Jۺ^%rtIAS\ >M= %YB1GrVK'KELj ;B#cV&6Uj%GmF dǖ}kIgQӴ+cgy`@2=Y˥]l]dQ7>_s6 !(||Č}׀L@/J;dKb[Ҏ^Y[É/+oZ {9{19F E1A{s4̠gek=UP!Ѹ l =s׉nҘzeG>.ʻ.Jl NCThm \]BXGK5[7HG›ȪʹvM'ъ٭~.h̩/#Hx5Acp/0 t3'|Up'X3*hnz?>gQ]Aݕ/!cǸ7 xp_sImn) :\$cٲʥ9fN0&sxqXe m:}Rj/rmx6w{i6om;@?MC=4 _K٧oXLR=œX.e'\-<^;J# $UQSf@'M45nF%jh3Oiڛ}9dp-#Ǯ;Ks%kpq;T$삨Sx3wǓ~w  @DfD)V#˸K-\LҺ։햒x&Ju%ڴK%BǼoɕR'`b" ,; koɛ۾Ic\k@7<}2m$K3!('@|[E=$ɶBUvQ ~Mu :s| mGֆjY(GrXTS,~źv,(Lcc*^)V/3d,tDdChGdN^YS500cP*EG BtmyqɄxG8ku LC~\ZOt۹|N|Yw.Mj=KUaQRa*Dxkoa>nD VQp!Jh޻w) $.Jw{WNNUm`47x$'RjբEk}.XNSl;;x(g.R<'&?Pr)CTKaF5h )!!Xb՛i @iHmTn_\;kuK+O<ٜ) :y} ंtމܥ\)rzg]]iM#Z F{[y"TLL.kY(q̷l X^?@#kY"h9D,,0bBS%I1EtRdEs`ۘwzZ*F饍s5eZZ V"b%`o&$k`:! {hڨϽe+~መT{;=>g|:JW0RqR}IPBמJW7DUV&ƭ/W>y GP]i(,&4th t,>6'U@h^[X]S8^j Y :WDKw mRr)*!@]\Ǘ S[hҋ\0b9SC{o`k|S!0A{e^͛ckHdN0ȑc+K^{o.Кċz) %/,B1I-@G/?_t>v_7A vJ8{ ܄zT$ˬĖ6 ՜bBםpa8RMVi*S uaWpG}?}$ 1̬+F a3@W> ĥ}J.{ҷHکٱ3[+/н+n25EָGH\0%h]VN`DOic30ZQMlixJku1YA*k[kv.=}/QɀA™+;y=aں{H԰-VE]͂nSsM`1aôes{4?Fݜ`B#`׶b: ώ[2 *f[ŕKxj[I֏&6b(~٠@űb V$|Vd͉|>ǡOg“AL)į*3Hsp"'p(P7y|tp!ӾX[~v&A䖔> z&h{;eFa$%l̄*:1V1,Nڰt# .a 6 .<- 5)z}F~u-btpK2onVĄMU}=JmZGj݄YbJ/:_t1 "/LKdgetC3ynHB9yŬaaNAMG:.9]שtq4،37w]B);w.OS:.;+[~896ih83E.{'#VbڏΉ"Aw5?@/'/2H_[!a|NRǐ&- Xy^KvMKwʱ.E۠𷥨~^}2[❷Zby@;>;σT"nhZ[*ImrSÕY/a`wn~?E!;l*) å Kg/CL? /f!XHqMXf ^UvL`8Li%ZXB`cn[kFBY̓9oY UI:?|m*Ql>fW۸m AB<&S^IDzUQN{nt00 ]u:;c8eJmNRVD+97բA8Q U-R&ҤJv2=W^Hlї}וY{gљ4jQm0`9c ᳇:w c.Vk5nPVE R‘1 sV܀'4)^1j.InEt@J 5byD[|>{w-K@t[qq`T0 Zt70PHh6+½Y"" 6ߺ|/L*+L򆆳T{eUfڤQ 6Yaum14{M6r i?Iluc H4B3 )+GXdl79Ic2i`Z#?b.nšĭ܇Gpc݃@G**#IXGrz!Xf05v^F˩J80\mpɻ)M Ek+>[m,LwLtԷxTdʄM%ǴvZƆޯ͞CX8+$dzF~DEi^ 2h[YvqJd{B Ӳ{t?fASO_"D1gԔHsTo`Q"X{XDߴx)$'+ Kc= Y"Wgz~9ϗpq ;O4Oٹ߹^9mTGxM6%A&M?o摉@~C@Cq6UA`3>?G3Ʊ#r`6^P,,#1AO@),/G"dlcIdC:t2]Ozκ'6vkzْFzs>7ߙZNنY\GЯlҽ:Ȯn~96AVmũN:j&wD;S$WCfo;)*1"VkB}LL2FRjU!9z{AN:/]< #4g-BaK ?yTpS^Q6Rw牠`FBRnGA0wfuH9!eA g"ꇩGBcr:4CE>A,B!bdu*$5("Tޚ|ŗ.Ad)e&˔v`f6R;˹C{Ki5{ŐoVNWKM tþڅ WO>|CX|3~,=$<#kBdoٔf?۩79`\ð.;07]^qGˑ*j~B3}XR9EoJ  1lؗ,if"Fl8fxҽj'N5D|&:- ̺uc]>)KG,C}lA#'KQRXB>d 9??wγC3>=5iD#5' vC/_p&"ӒB3CY@=rLe+}_߱7oL,V>b`~(n )x*˂RdS0G_p єt* >R,&lmbZ)}YAӗo/.?[C(I@)UD4$NfL2Wx9SMeGh,/P  {%Z>SpقQ:!̅k`e"W<#~~vh"mn}!b}{~LʐVJ`xrUށ9u㍭g0%<*UFYQtVY C|#ɾgߝ+K[ ҷ<_SO y e=-b&h*;1;pitY]Qa;OlԌ&@=1Kɵ"7RSBG.tHF:]ײh/74*Şj\2L)`e{s> dk5='wM vytxu'Olc"8T|mG?"Y&KUzvPp)tiODff8}NZ(lSkk)~"<qp$+ݦzrLCFOmǗP)_<JDUܟ됷Tstwydy:>;uPQ؞]q(5*.΂%=ux jH t;*]y6mqaPyIV7 uSwY=Z`pk1X*w09gv?7_;#zbuw33|SPfw`>$>rvKk ]Q XdCv2~#[VS# NqA, H̨b?y0俊חstݼA)Fw|w@͔3Co6 9:;ӾDsf4I1FylQ삠DdRKIi1K䣔(7xbڦtݦa!Iq9mU% BZS(.㴴 VS{C;?w^Y[ <=h;O^ y6}cǰo;:} >N,PÛf wj*r4"E"gBW<[_m)y+Aq@ԇ!l|_͖[T1Uql;*/w Lrgۛ35C܍2xeݧ &r< 2Gz0vUV#F*=АITe7 ~"g@e2۵&=}-.ikEY>"ac6JvCpmnx^ݦꑶ OrsmVxe4+S^sar3"Z*Qn?7-ESeRɫM@9<~fW3䖠}@(l|ĺAL8 ltѳ0KhL5v6KQдs$Ygv_r1-eo,5"KtRVT%( ykEŢ\8hfkEJNxقðXx* *Us̼JӑܜfT)4'X8H Fu5&r!tUj&FzmH &_3j%S_ 0Gèh}||%별oBKgH g5 $I7rQw# ՉOȶLt?d{߹$Dx๙؄ wդOLas+,_S Xt[jRρP2p.[#S$2`~@&MwĚsKQT+̻7~q1`l'DѴ!i1ka::dT]\<$.ݞ_4Jؖ#s IE<$$ΦpZ@~Rv TG*IauVEV0Gldwԡhɞ|H"a5P:FS9GjY$0rj3°|06/Jy *+t0AWʔ`Tr㧪Ü*jxC?*m_,emYt"] :y4"[J| j[>?\N7JOd4h=farA4.~[Qq(DED;2uC D/C?ӟf䓐j1bS7Huy@?ƳΙc{/XIkȩJWvӠeKׂXV^NU!Z>r&*~2|3[hCp(^sK?{~c0Vs`>/G0ާ) }|yoOf6<I`OIs& =;t?r"9{c0t/d(8@Ts%)ӛԷZH E%ᘃ֤"m+ϸRG,Q\_3"j<> Z/G)FhOpp%PYCd,K/ov2dr4̔k-Zcǰ B3+AE`HqXm̄vW@W !5!v3mX>J'iY0XzKdkyZx{=Rc|9_(4VaYVaF nr}M[]K5u,cLcꏓ ڦsm^ܞWЮJiW-U:mR!'Weߞ4ܑfNDYdocW"Gm33nV.8S64uDs2Gg);`+cܼu.D<ܴ%'ㅻ)zatnnZ.dP\8-6X*<1rZa=\}Ұ uv -pGcKQj|׽7Nc9 ﱻ_Γ802|{:/%64^~Ԥ)K^UD˩m@620T^@ Ž<p/zhq{{^xqݝ;8fLuLd,$nf˳?3=&ǣu߽_Uޜơ;ϱkMQ_Sw=s~zƇkW/k9?+v8[6sչX6n Z8Ì#.:[(  =Qci"z@f}ycyӎZ{7MJpJSN,RݽR9jkgf*OĻ);4|ĥkVnAofVN3os>$뷷y8z|!־ҤMBF|_W}:;BX3Y>3E*zg_4on;5_~Q+ ~ФhUMWՁ %U95|BJ_rkZ|'OIP%~ vpw=XVdgİLݓF^WE&Kχj\?g6K6u a2>&}ҳw}i-?7ǹbƼxfޕd_ߤ\*.{ˍc4aAoNfn^Q%69x#l#5?,q˥?4\3Wh]bC~]~S~oLUoeu|ofú[֬Ixv<9\zuĢ{Ξ^ |Wn_ZI;"YJj3 iߨb6)= ,h '/docFnSc tgV9h.ۂzW0(ϜKF6\]* ٟSKWʣMj:=M <:ɏ?/ۧڇL[k;uCk~%=ta˟?3qb9̆e/P.*G []+M; >Umx(cqk~q؆QzVՊ}?Ϧ b/P !} HuA w|'wB{KQ)kd^p{һJ5J_V(]վfGr\u'R+kuz \s6ڋMFPW2([羽ѩR=&>Ǯ F^~uy}g5|pTs~qz5ox+ת̦Q=OgO}R`Z*g/ewFKBڻǬ%OjϘ*ǻ)wJ/ҊU??!k[F)FRsWj\k]7ctIaO=w/oWgCMi3h仧#[ߞ|?溜yǗh|I7>MYa楑yZϻ|:Fcܲ ^;PѨgS]W邹q~=/` c= sK~_u,3*}˜kKs8oqZUϚ΅-Qx rNgj=CB_9F[/۶TJ8Q:^v;>_ҷGj~ P((YsU긒º&Wܲʴoj{/KN 7˯(}6y>醬3}V䭵i%o/})ylBe]/wɈbu5>ͳ2`_/R3-6oW|O|'^t^sƱVg/})ko8E:uO%6VYU~U4Y>O}gsO>_J/T =lBd-#g5^_o[Rp9\; ~@>/4+o`~5Uo1IdF5=Ǜ#ͧZwfcŘyթ$:5g]VT,bPeL[;;_=RS߳x)_QG?pzsf7\ټmy*fw&lZhj,YK5?׮_-.Ox?n9~RZ1?lکFV\W߯oҠځ-ʜɿYB쉀u]mw rtDhϏӺy 3{& =dߩz||q;K P֞(.3w2u*7EF_ͮ;f_| \[ƶf {Qwr@ז-go:pJMWZ^^{F>|ޒiS^X|?G.M?kMO5_lAꅁfז'_&T\7$ǜ})W;y֭VŲ>߻A& hSmW__iѷGa}}C9Svyw{iO?<7'jʖ!+wws,6 'k>|75[p׺޹mLi[?,ds˱/^a:<ݶu&M>| X)릗7_1&S):/sUިW%3W.M~32 ݛ&(s*T#C[۬yW?ﳤdcc]mȳtV=~:7l78iV9l깭EQsZ5HX +,jOt|?KO{"3DZ}ξڲԂMŭ|^eI_}ޝ̬o|Tnm<g|5-6kܛ,ĥ}f'JA|y\"?]n`wdKLk\\￟W4)g:ݴòRCGsuߖ=gUTbd]nXo۴#cgivl^95/į`XL?%* C^m]5]ZBi~:zGYr{Le~K^e=ige1Uriז8{PH_|}ݵ.<%OweL;qFd8yMuc>~˯o3lҺoVXb݇.3uYǏk=^K~~ףּ{NO&Wg2U=g:0YL䷸%qm~}r _:ko͙IP ?y1[l~rv=n:|U߬5qB\F|ޡ,?<4Cv/[=i/sExZ v~1_ŌޱxYuՇN{H+/ؿǵK/kZV&m-#]jULz|e~t1%g\a Hy蛺q۹Zޒɩ%Mڑ›fVqnc8`ﴏ3_,u\O;}M g?K 仕Byg :ݍBB~fq͜xao;x{a}g|wLn{yվhѰż=%ZqnjDVzu]6^ܢ)kΩܻA !3jzz,fށ3ļwZkjR?dn^̑0wi[UvyoTUZdAȯV埶ٿ[ϚUݬfĺ-v4eF~zkjt6b͍]oss^.3>fWjt2c`ȨeFcghXRo+*?c'_!jsbբ3O};J^{Wi־q#+ M߾K(]SRױ%K}ZȞ> [,^Vr?vL+MwiU/InozUWmvح{>=4蘣ٻ1KXM7P 9_UޱfNj18%EWIбa{ښ*U˝'(6?"͢-g{^M_l#:ˍYdWu7GpѼlg*2`O87c vu5sӢŇL~˙R5/;cV0fV[I-_lQf{>ڼ|럴e["\}@w;磯gٓ1JiU5Rtڳ1\'+\-Zζ)28b2J*ϻ [ńaJrwnLyuu!g2ЗM澕7Ttȝs>>M] ۘ}m؏C3M\)f֑ɾ t^ߐ.2Ϧִ;jRukxoK=,w%_s~~M?F߿UDΛkc>G3P)ѷJM'O^|EФnPn9b:9Ϫ{gi\_̱3Ŋ 2^xwhcˍ^]/pNGj [xg;(]kr]]CںG=?g+߲5m)_ ߽dat~H yo:|[?S]זtۍ|la3[v/vuο|{\o9o|x1rf 9W~~[N/?:z̜:Yt8ݑ~nR\ڜgwv𙛕?qs[A-gO頉æu+ b N@Cϫo(?0ЙM:{5gIIww/=Ú״AZ㲣jOZ6*6uyrtLj];9%r:mG6_t >'0OXƒƇS}F}]hwM[7{b(Ӗg3/p8WE/)% UcĭXtF6խ־ތ.cc̻kܰQܱ=}; OotX|r@#q+p/mۣY\/ f # :ѳ|Bj䖒3/~ؚꙗR{Y K-mC=uron|?a飞i.|9 _+g8+݇[k:c.sݛrdUhrߌu,RR3-j󄭳1N=T`6m秬G{VT[N<щKhtM˚1e-6FNY`y[羐ֽ+Jx‘B5 N`;øE~'.7/rabFrۤ+q wⷜZ!34NLK6m,`虿>l6w|DKwn4a耑WQ/f)f6*>ԯs״-5.ܵg+W ]~b^~uo>XG=\ ڳ04B7g?itj-u>'aQҢ zM,hroǟ:[޽b[w_ݭg}#}8%S@u4(XF]|428}nzɾ=Xt^Uf/\gB;[Ű6%[i^?/U%*'}oQnN+Лw*t(O.1x5TITLVCByr;^M?V\j+|2 lmNߏk<;W|?[o q3[e pOB$~~nmu,ϝ ( =-+p [ʭq\GK9~+[؏mR7+ɓ!kX?%@k@.C|ٻ!6Zn_.ھPO_`FMc;`q׏++we~s ۏφegk hP+dEy󂕯?|J5粴V>ssW;st͗F9>GxcU3\7Ye4.lpV<?S?bP*'XLoGv YSa6[gYn .XQ`ٷ;rZUp0ojE7k&Z%W8F"ٸMb+ V0.AH;jDj8Tx;VD ]Iu_g#@c<;o0{%ή&8Zd߳M)R:Pi@NTFjr :'N]tEN]ra! YoGq::@u"ѝSqm8rGhXex9zU!9cD οH sEyC\?\C#l(,}0Ti 9~h!! "XFqʳegŅOuZpr;pdI+.U5N#Åpb~N.Im+'DECvSUgEG?ReF8{HPju&É[r2 .hb}E$UErByg%y%Y&dV\ꭤ~8 jYJkt(~VQ\DH {%Õ]ԗ]cUVY7`'JȮEN+E8E E8OkM*L*8h+<@3w`= *wHQ.+9ES:3@ F\Wd ux*%FM Ӹfǟ'\P9eM-tש\%Ey5VY@9>X]l Q3ɔ\..Y||t;qѪn'u깓 #h]n^Ήz $.[.N()wJk6DKw.@u fimXQwdt$Zsfu 4nrna9˻$V=0QG*J^{钠oWsT&$2{Rb{)}{H!HXd^E RudWwlW4zTfdk+, j79 XN5F׊p@P+:ÑN*D` Gppca:=JzuF"{{Jn3.m~-ϥi%9Q 7@-*6jGQq'lҴ܉J[}H[ͽ2cl Gm}Z  7S&0fRĆR@Y<2[z5b_Q$O =`UAc\p>O8:]. lh25gl_ţA۱3NB<&$<Wx9@0Vsg*:,{lOm'w &yЁ۷(}}ٝ-QNjG/d<@k8W*wȉD݃`.a(uP {$%Zh"K +Ԋ9|hkgi!F_W z ̡k=Vo\+{ШkQXƁ;1T ɽQ4 Ys4:$L_#\D+YA 5h;dS89Bf0)hQ.b;))`Xmѩ QѶԶySh6VqydD;Ɇ~wڢ 7,;t]t Ɗ4N<֬*֞BJu;fk>R[΀SfjNw'bvq!޽3LG˯?BlAX zTȎxyhM`\8 "X5;A.rYt'wy,-۫ 鎈h9h aHc/q`Q &y\;6q`1x<a#G5{`װǤ;uyL OrlD2<3ׅa[ʰ-ѝ mD6ct ~B\lޝw+`[k]w)_P2)k xdK*E."t+bR"P.5 +& E@ai;0A /X_Bm(ls % jmNEE ;xت44qٱH-}TY7 %PL)U.~w Rx^]B+9Ζ)[/qV+0A;[r+ij<G`…d& l\69GU*|ϠMňv[s# BmA`@Z7^z ?ϻ:tDG4xA+e0(ئīV\hu` UL-H֒Jp)1PX HI!PlMIfHU.JeUb4KyFG"^}o5 i'N.9 BS:qˍe8KYmoq}P>Xoqa>h8Zp!;gmEfl/O7nQFd)*} {V\mw8Q_n4#ZosBTNyNvjq2wm 9XPV|Q'`(:x 0 e~5.0o\H\~V].KrCEмfpQ.fыְ[\(XP=P?M0_utl}ʉ2?{N[9x(FJsQ;}.@0 ,(zz݉K j~8c }`?.kU7#:䏯S(تzAԾ )`nr( ^hn+!=33& }d)k4?[ya8?\jyą":dx#:Vļ+ ǧ{ŋ''NA?$CqpeZpk&.a-y̅2/ Wޛ5.n3\ CѱpMW!$W#1i{Kg|&E\LUvCvᔝRp>%x*xE[z{\:?Gk^)WzvKg5fjE=uTȀyjkiuօ(|Ǯ.Te?䬲YEsNsNsI\H6B :.ix̅] P.ԮEÕHD.Z}!+ŊY<Z2s6pWzD nx]<)ʮb' Ɓ %E"HW^r9s9s'k{nqn5[w+kVW\~_GJ3 v^)SWf: O)1d>5E#V/:SƎG`YZhA()ta1?:Klll'ɕv$yEhh@^KNȔMI U2ĚhPhu[M*N ]VX%M.F5)kZ- ZKXQ%?"d:ԋ1va 13П\:/ Zқ„B 30]+"X|q L2 ~BEJjh GOH.&geiHOaЁ%&QsxEMxVF+0@o#M^$B)6EMQY|uǺ*(|,`~*qU`Eb;:˄OQj^nqNeJIjD$BvKe'}=U@pVejdr@խBX#0(9St(0b%vYjoİ^x塳Ug}3EӉB2Q`\&Et "$r*D֭|)D'B芨(G%5BoATX`*6!>A !A211Xa*m;DL'<t:꒨j)X"6(ԥLB(Hd+ Z+XP 1 RT4UdmK*kwI`C '\ xtn BfTY  VXU~U3A) $`3ԥ K"(d9V`&Yg58)pgSN)/I8Y OU"Ԓd^֜b;#XXS!A#@S謏evad6˙t0pL:  4h#(޸@ʬ\RI&uT% a #T]4tJdJ-Udch51%9)t>Ą4A!KYG#!e1YRQrCTD2VXtܚH8x"xAgl7ۧ!ʆD(da*H7[ &k NB-vkd[C䓃LbQv7XdLhFQ`J0頉@e$]VPma›itjt„*Yb5ZWM& 28E )NV' &QUh3YNUY&$ʬd ߺ'u48%TI&kRЭ2ARia'0t7(L%P fd3F!cBa2a1I !%0& ~YZ!pDX",`hɺĤ  X?pD΂OؠIv"a9էЀŽ& QxW\d0M3yd *] B<b`tiñRyjՃNbdE(L\U%T04`@D SA`Pё, ^xɫd>U^'s0.4/Lȶxm۰ -1="^*Fن%p:XKdU# D4(q f:++)$ QU4TU)0)L"mh R!.ħg)dAn5e$ʑSH+i`lZ?p9LMpM d"Ua7 kxG7+5ǝ lL%`4[ ɭ<[84H+ G Є"0,M{L?pd,jA櫱 `$LSDb+fk4iFB(pVL`5 $Z"xT%vX^wiH9E$@cc l#|Y `$_gTeVUVy)fs@iF)VB)Zu5ƺR9$@w5VcG\N,0%daɀ 5|-?7oeU>\ENBvNU%+KUQ2tTəa(50̴!̥Mw Nx?>{ +I fs0 ^O䣄a H$ɄZUcDSfIíAvq/3N%r&jQj1ޥ ᄑPOϝtn{C]X{ *[#^?XS [g\@ա2,;+@6rLU/ `f( v6dXo6fPP`y_ PV$bɠ}Hgw/tUv ($c{2:`IHʚDɥ)C0:uL"4ikzO.X=<N5+9-B^KfC"hN͑ڍK3ԆNnESt')Vcfb: x@X P6ĂĘP㗑`&$Gb&޲N0VTX*O SFHd+2I3F.& $PH0DU4I9i^:鈤B|SRNUTU%gE^' ^z"ftbM▒KX*d z(P9 $GDzMvrr"+Erbr +;!"^L Nl" "输 VDi*E-G낿Z`Afd*]< eD2d0ީe(hA5ID<Dz0+X A V&jO:Icq D3FbQǺ`KT6dkIp 譴XFT.)H6D; #y.D­rOe3 HAirTbL`38ӳ* c3IhgzfI O+C$_@&nsEdJ0~Mb2+0"%iDKLS#Èu3$c*:[A%tr TPSW'wLaw&$j$&jQ'I"M@`FHx͏{e*R0PKk]I#zcvmc)#F׻$=QֲܒحGbw$&gU/5M;\`g:! r Mm8 ud= #/yIxFZ\B,dej@9\ 'nCGOIVA&Y'$SIAzS #z^l1mǽIg#Pl-f$&wJB{ πBf"$&da!X̎cA="*,EM&LS-v!7‚_ho.)2N Jh5&"4)V62YJRy6(Tr(f #iap-L$[!xϚ`$'TJ}cGα.K#;#$&*R`jѓ߼pĶ]5 *ה.$/ d#gsi]\vDLv]&Ė3&V#JbF$+v>FmIDv`6&'bI2(:`$ꄲgLP%)E_#y2IAX8US@p 򘄮@:Evj-鄇t c1Su~&SIdLDA@]t vX@gH"Ȇ`ӄ9|y`$^2h4R\Ә]@H džJn£)b@CU.7@Su M %G4M7 `d__%uZ(=`"\ 007,an0H)QIH*Sd rAR 1Wtɾ^Ȟo/ e\ W|MŻؤ[L˧08)=*7ʘIF|Fs=,PbFb=##;2Fl&2i2dۄ'0r:M^X}4q Xu,㕫F$W03L0F1@۽іK Pw#FnN )4+۷EYNț12O.)#7~L8 _B6<}`PNDlQ@A1"㽤; rjbC2c7d 2bG(;:|~#QfZ X[,F*o&3EZuxY܀, 4سoS4 sT#s2^AaD}B"JM(-ӧ z~_Ea\&tJtr#:x" DZjORa`vF x䅝@N?K]S0_;46[o0rGYȃ~22Rcf II?Ȧ%N@RHW1un8"MBy[6EC%c1!S &rMybI- Oh2@rE78e%QbS$mL%v3j)fZYc"ȍ Ka¦WJd0чc}SՉW éc2ȍiyg=4gEwXj<}Xɩ&0&'.H+6,4<0&L}a#, P' V]1n0 hdc 2ZtЌ1zC97K ue%<)"Liî/ʿO*Z >aT`NqP6L{xNtPè5mս}ĉRFhކ<$̕0pEM,CPÔ$Ԗ,lXzP+CNFJHRwCl}?]yY瓉|ME>F,*Y>hZK>ʱn ԂOeޑgg3;Q[EkKC!ɖV CGs|8 0=oT9^ݽrBjd'бƩ8D~/wJӑN= K+;:-r1G49qOU 8CG` i:ߓ@T]#IxI/3LȦu>RY6.), $|<5uap^xUK+bެOh1&x%u=`8[\†>WmWZQҒJ}#LW顽Gk6;ڰGSIZy.|Z:ɶG"zyP di =T3~\ZgyM+tD(Ot@mPy`FIpAixY?:f"TtC`R!} 9''YJ7JmU`j\Ngt.3Ϲ"Tt7CDʣ*F YkG?Olyd%7syWTjq_eeEI2hv֦(cCe |9Y@+(kFTU._Lޣ5}1h}D[m$c5>VN)]}3.0̅m,|s`zۧI]߰>xR]k0}~ŅQHW$n% mЎq #׮Z[24YVѭl0v_9JZ+Y'y%zlP@ Kr߲GLk Ud L5p4A# jU0ij!U"F!]'QTrB#e UՔ 2YDyQc:fQ ',c"fSN29Qi)dک  w-uP2z?SB iEd'J%*y5-؟gx]恊QAzm5W!d;mdR-M7=a$/FVdvEW=+5Mk;mOtvU\5ij.;^ }c%+\)52ǖ `T]]ht;{:tH{kuoc'N~A]3&x}Qj0}b%8xe{u܄mn[P{/w1/i:_egdkUt8ow3h7.gV>Km:t42wlq>_ q.EX.jL(+3|!_%\0?:d6'&HvI˃>XGetR 9+N8]Z6Aے8AP@M:@|(EA` eBEr;y; Uλ&"qZ;8Dttb{B@tj$c>6?^<&7vQ xmA 1 E%(+-&!-x{ԝ%_Rx{Ӯ%t:{p,R)Yx6jDj,P5Blye0>JFt%:U}-Y`z,\Χ>9Ufx{xq5 )e%x{X7xf5x{ŸqN GfFx{8q< Wx{8?/_7%54] $9 _cyx{8qBDQNb^n~Innqq^AbIr x8P%81)'U71'G75$R7 183?X$#1/H:VVg$g$$gpkxYoFY+ wss.(8@ZZI)Rv%EJ4plٙy|3;X&Z(Ӕ-5q6H/TM)uR* )V_~$?I֩% m9J5-b;2%n4[!- S_*E,K]ptB?<__tG`J,dA˕Z$ae3R5I:k 2DES+7[EfAvχ d'%7󶲪uu:.WQiX?OnW2q^{G :CAWoZ_dpH:(^e^]I$l˩#XTq4t2UJFo Cu^ʼ$UZEeqy a*?Sf ,uV=ƄORo7zONE_e)5&gWo^stk?;y9wq,Q_6!JC="jR9a.\[Qq:={e!kx6 C~< U=} %L0U%OvW_%UU'޾kȏHOYLV6(vROLJQ̂h圻tť YH8djvؓMj`\8͜ѧ+.g\5,.<Pzps׉ ĕkԝZ(t.ah4CdYR8Cޑ(30~s9W a ^\ Z:[QS-FSjLݲy Q21 `R|"Fh6$* K<ю`x}ۈAb#TŠ[p4c&puJJ(Y9ԉl0YDsi\/p &_/"T]}/&7S,~+v2(p[GAQVZɀ G!;7+8IF4^O` TZ6'Ȃ[;4. tg t ^Xap~﷯U.:)'If@!\UGi /MY SC+r]>۟?)YNdț!^z0KK1~XXm/PE%KF >ywFDc0SЙ=Dqdx}&k@5y<.J\c1&>`mwlnW(,L`U^WFW]^F:Ǻ/ /."j1ScX>D*m`/Eөk ' dbY)vTap=X7D8F= s9gs7x_+K &wsx#3j#]`Ze~20(TGR轾 ZaL`i1^gYe`(畼fs52 yF.% 1$ M NF lj\ 0e#qSb@a/Xrs%g.#9gjW #%HtO4/9gh`hyLFNc|#D:C: fo=6BxenQ3/%J ;]75+1))(erT-KWWdtF VFVz0m`l`*Yy6cacmbi9̈́ 35#cr0|nɭՓpXp 6e01L-7'r2rZ$ 6 7Kd4p,6Rc(6442Q!obyFf]j,xe̚wեx[f=պ3/%J!5+1))(EH@T(Y?7?%8#(5%($H/(˖r j^~Qfm& FFVVFz0m`d`TiO6lbu+6ii&2}8,˚)"tq°n;8GQ7ݕ`'nj1̻G8 )qPI [ 0c@&"Mx( ~DV謮o<^{N7 8-\i_Ϝ@!8KMxZs5UrJquďFmńokvԘc{eˮ<O]hO-S_]/kO^9,n3e%F w ^vVmJpJȷB&j/ri=`Y`59egPr׃1t|mNsE8XvfKB$xo@4mcSRT"|Iq S*UGtr#8MbFB{b`Bbaf FM1`ɖ~{s뫣ny h`,$ e-}iyLNAC hkz]2zF C ޚbny47}ݲ`h À. s}B!̓Cd|;R䅸 ASkSbYOVLz@PEv{jd`p!]maG~ f7K'T>9]~3L'r%.sҡEX?:il`ՂFID_dz w3*g߲_+ó~mC\ԇ-" DQQ@AoJ ^*ʏ6䲆.4 -Lac@Y`{DQ|`̽ X'> .Vsרu]^3B0|0t[XVK&S!2s\QK|D&/ DcqN1ly)-gU]. {sP:[T?֪%GLfWZ~? UO7 xj}R\WWW!5+1))(EH@X/(3})a.mmm49f)>NSs3m3Y9 \ v铗IOg?eba 650lǑi`coil 533i 6`s FNSc0|G.c b2AnS CC`M=4sxl9RHWWW!5+1))(EH@h!F _x]jA#"k]Y"p2u Iϐ:+X[Z]o]~Dk-6off^~QJOJtXUB/H9!2 IN!ug? r, UukT`9B!@-"f 1Dzq>8ޚH,L"l؝^sѲl"~i[ %qEQEBxXsFl۴L,;?&J'@KڙΘFYRu'B&=ْcCB!n۷剚SEGiXXUP\deN:}/zq-_"{ƶ1զژhSY,* ]M3c+2i,Xڧ(6^V.,Mt(ͮzwM͇[[WR0Yˊx+ζ /.TOt-.HO&Re,Z\"O4Rh//{`wwp@;ۃ=~βt>k舺{CO=be y rsNOs<IX&v=j~&abOҨ"Y9D^knJ3el8Ays>gJiRd3hm>"ġi^9,^: 1(: F%ķ{ՙGgl`ϕqY^K8gK=.2~GL&?p;`O}"Ps+S *ƓO?ޏHv:䨼"0#0k'tS+MQ*F~QWNuPcVJi9C%0dp'eھ9e>u9j8CS5.DjN8ViơQf&>r bL{& */&"&9;, |dYbg2:F׸6\2 @2C1G/]z(Dnb, 0E kuHc'yCK0e)ٌu/,TX*]c8 ʬ}RCs)Nk&+DɥЃZ~E%?JkPJ{7Opi"[sYЀ ;Ftyh? i 9ap 8>-5iohn(`@0N8U R\kTꃾO}go~1)oBLWńFHeR@"L ,&zyJL][Xr{$g D@ 3*1wJF81UhID W"B,Wo1uc^"1! TW5D{wgF%!b$A==98 Ҭ4#%&0BJ9 hNO˱2B^ sO e߲^-EV޸6{ /eLd<&Ok7U!@Tp [C׶ݠ9Xnn"G.Ã}ikaaT7ݚRtE~}qc4v"6yf7Ta=$yI1_/ 1L2Pgn&]=URc(BvFk/3viCSUvpg5$3tؼ KN*&9`v98&b!g(v'nZ(#&_.~S3TLCAWjx/ b?j'Kx[vJeaϼ +tԬĤԢol)\(eM742045052P0024203mc.mmmtgyk42ࠠkbbch ͌8%5-4d9F>v>SsmSSC2yb&: !-n F>c3m Pl"O#%HTk_#1H%Xd1:@Gdf#[6x[vZeaϼ +tԬĤԢol)\(eM742045050S042523m.mmmtgy`j41ࠠkbnch ͌8%5-4d9F^v~ smScC2M f: A-n F>SK3mKCsPl"O##H9Tw_=PHXd1ff: AE`rL ]B$x[vBeaϼ +tԬĤԢol)\(eM742045054V002253mc.mmmtgYi4224ࠠkbbT ͌6bb31W65014p>b5X5y-u-,́2@ƙkTp sϼ՟%}th,͓M=B ~BR&R?R]^nM0绬ECk H/Ҽ>"ay0Vׅe^/ uDxXq\HT7 <\Wg ,&~/AP.KkgT-I( J=/~`᳂cЄ&Nft۝+!h/ʇqKKv=uP]Gu;tԉHً͑tUkEf4~{q\~W]~gBk=n -Xmmçxx BxۧԤ(Zkgg_>06PXAADXAHobg71r-t M&WM#$aj`ىKLAlsw+oa01in46whojٔ ]+xpKAHWWW!5+1))(EH@h!F1 Kmx{sKGD71;5-3'U/3|g wUSdD΍i;_FTc)KS֕79|LGsr[Y}=59CW0z0Z,bxf;%odLfa2 <盛m]&HL_Wr235S;ٽ&[Kl(ck&]'_fy,re[ô7g,f"qobROf2o˺>rOK1|1ٝfF0yt׮UҵsՁg{!Z_lT_ZZð5?=8Ut Eeɩ`{*mDW56H rjO~S^JA9cכp2|m_#]fOo_:pjv S}ֶ pSSFԬQ]鳌]Ov15[Ny3C4d"̀Ғ ~i'WEYݤ)N7` ~K>Wi||¥q|곣ԗOvq>xnߑPsSs!!zyk7&Эonn|}M]<ebGXZxė8L gb` bxEdMX1gݓ&_wa[kWU.?O%uO'߾:x{wEeX'a;hz]dsAsvj0+5іmuW\Y\Zv+SyN gC'嬔#"%" >=tcg^Y"~V̢J}~Z*3ˢ! 7m2KKG4!dc*rsQ*Xe-9AůO Jgx{ӯnh``fb+ }.]M_>utZp?eD6Ij;.MID?^s<2iYL>l!;لW=)W,nڗ/&H8:wu'KxSZj kRRRKK2Rr=ܟW/Z;4Hs Kclx4,!"S1n3CRl/" %VO}gWrgk.g[IDC.Xf _J=>ő,d^O^uWdF̷Oͪ4? Nk/P`EEW㌗0h+hӋSxDVjeϞ"GR&M<Ҍ" WhW1%, yEEN9:y a"+|??AdR >du/-J}4{ $E^TkuvRю&w94t_$d.{۩Ob_M~W{߫'ܱm" X\ m) &^d@PGM 64៚ΗDZsE@_՚kOK̃E_r7gtX)xчI>t{5o3tgi(s6hk “ ~y<oB8'O՝C(ɹw[s:ߗ^U'dzYr"0sR a Ҵ!sK+qiʙ63%X:ixmISS|Q}cvk̚|Yt{S[_x]Sy8ya3 S$G15Mm OD+4fCRl;GU4R&))MY.[}v?N22ŅJ9 p3-ŗzjR1R9'3s8cI`rű9bo`TuLfsPvI~tv&3ȈJojծڦ:aR _iB1,/Ou-j<4`!M6b qoI\z0 %q Ӹjo Tf^$ֳuSW*7:bLH|.:r͋DG[7k[OQj E,&0rY\9ԕJumx9o\vըt \;a0 ݚ7mE_'kM&?ς͘[ ^'Y< Ǽ  Vaz"tf> 6V=[3kULC+Z`wwf;IVwr|(uAxy]ÕCh8zZRJŠ̕Zd&$+ܩk㝱mKrYX}2$l\" R]3Jan%{T2dFy15w{dA= 2Woy&M5/T-G:^T'}p;FXv}dˌbVK8j:) X4cDmOl tL=߻J7TH%r}G3Yn?M]sF8,!v xU^a5Vq'ʑ^[AA#W*s%UVaA']~2s 1tBN OQ//RZ$T4nc8@jeۍSVȊsn|ϋqB[3Y?4Q*͛,9թSK͟$\o(|x1Eܸ|{cxo^#%L1:zOBCf/\wt(b.SHw 4.(:xdzR/YyVԒ_(C=]ƒɓ꧴RM#!Y[w.[pHO%qtIBxm6i_&XuD&|?\c Bډ{vlX;bt=l0}S7oxbvcY3-\z;VcG㯲SbLTF]c;uAH__xǴg/18>O0L8=m_5;klQCP3^8.">:"lgu\9+|E9\EnJ3g Bd=#M' `9 kRu$yzIxxynh``fb`\͚C=ls/̘ߧQ$DMB\dԬĤԢtԊ܂TVNeoHr1m!d9"9\ִ7yLѫnN~B$L2}cM}7'?`(}dy`٨Zտ<Κ&r)T)n慬|"]27yϱYW|]ĭ]{rP[f߲d,~QD{qj׉%%N(kk?J^5 ̫<}ٷ9%DhoɶkwtSr]\|Bݦr~׆uF-MN~,.{r.)Q_Tvs9+Ֆw[ޒ˔'Ow^"OU/ń-n.RE T`'2pJ(hduzx&"o<[η:EL=y\->DZ19_<7D @L(a`OaiwOWz@֡€K{gM)ϡs_fފpdSW"A)]rT;qYW]Ul̟,SӹIiCv {n ټ~ƛ-'澮sojP{rS JK=7=#w*>>MZ"Te?ƂyYqrU6|':wcЏbłU^U?b,?\G$od!i\.:+d6<靷_1Hzm䮧]mW86#r+)I Nl]I5O961Z!x(4OsD« PxΗ|pd;j;H2fx Yn9Ah¦sƢ /x]Sր ;C"K[xƅVo C'kxۡwNhKBk4xX*/o!ǡZ푮h0ax9SΟafAx[˴i,0nR&~M,ڦEu 9x턗v耱cB+7.fx!'*Bjx[qZĭzxy~6H\k_{wYdsf8x#/ٙ!Wl% lx$/6d=wWvLj8l5S !x[/1,rlang-otp-r14-ssl.patch`U T5uE56B6npuqdpW}-100644 seriesSdT:xe" {S7/V .Y0sb"@6&bZ ^WWM]E+5x&0d庫+wcKMYtn_@Wbjxi)[x,V턻m։/6+xo0d_#no-debug.patchPj4a־"Rq6XeN">r :M100644 seriesWp%'g'3IKir+@WtM*%(xI7ֈoV<]Vxi˹VXVl{Ģc%/xiȅ<~^0{'м1V .xM0d_#no-debug.patch;N0~}>z뼑:Wp%'g'3IKir+@WK!,_x{i)5m'otV\Z;^| _+x{tiBĝOwWx{tiBĝOwW# kpx{i)Tn}9<^U +xȹ` IȪ, m xMF/;'XSL/9w٩V100644 mod_irc_connection.erl9j)G:5~56ڀR1e{xG'100644 Makefile.in p֝_'9 'bV@nn}+yX8Y9SxqBȼ06+yyjW믌%lH_ /x6de.BW0zFxCJxZx.E9fJte,!.x!h Tu=AӪQY`xH'100644 Makefile.inQ'4Og?PÑ'T\|L,3Pvކ ` 3x^ Dd߄d343G FIǃCGގ@ AAxZn߻c( F:aJV(Fw`_w8EJqtoϪ>tQiʓGs2GfȾ8K?QI H&exɵKD71;5-3'U/3y]pox/\{lЭT_~1UE< űk+ƭ/^o{e:G&}.i˹ݺsMɟg (7nvo2?͆]_Hغ(Ɣ&dB I>ef|X [=+=Ew|VD*jљ/]m2,"~]ɞ3c=B M7Ofd% P x^ uSFdh4ӫΌu:E,}v\ѕLTų Ai!*AA n˰aaxΨrAҸ@2ѳ:Z7[iӾ-D2Gsm&h 8X1QNL9xU •5R,^cNaPxscӶ)H~V&w mb׿aamn(FQ_sup.erl|"Q'朠(⑯c@–;|]!m`(Vd100644 odbc_queries.erl²sZ7yh$Ũ:R"9#xTjdhls64đQ_sup.erl(D {b=D'΋?츨A2|~v5$U|'%ex6jhnw4s&QjE잢% *\"; dx@j7mP?Ss1⭺Q6q5А"}6& L*kQ_poll.erlv"c6,h>ثJt4B?8;Nfa+Q_poll.erl{e̐~nSHJcRd..y%;+DcL&/mtlhkAݝ͈?2J.Ko'Q]~j/S ]xO'100644 Makefile.in|e;_vVU'CWR-& Ie}‘Q6C=Q^J$pYYQ_poll.erlTpA2_oB&mod_http_bind.erl@l{O&43M xoop> 4*VZ1o,-Q_poll.erl (urb8<%J82sk/ jCmd-M_i6r?q-fBxۊ0NzXh]]ue9M6ޑd`g|sݕeLyFV|/e.Y>tn?iINoּb,;ЋkW7Wx۱+Vr`5tB"F Iyn+vM#Y8wE$]N Ȕ9-Jշ8uV1jнUkR~<|Y\RQqTŐL iwlӵN)k*\AK20mR]=,JR+]1.1`gˏTÅlKHqpƘ8=u/iDQ6q|͞d G8R:W8!0B&sτfqONt~tUrnH ZfqdF | t21sBd4r"H&jFLֆ1&X;ӲKN3h< &1 ZšnVSGff,70 60ݯmG:Mbgyt!-;C_@D}s-viW`F2y,S7}4Nðm6I m)d=Z.yT2`A,EGU+nCi^jbY: [gj=&8ςM/<8k5)V1c%tSgP1-Q6(?dY!3b;7sSȈ bhf)Dl*B)Wv=UkwϰvV//~QuNNC*)]l`y4'wrLIKj^+(m"앰[F8o@w۹/om3Mwq.'1%*1L=tFn*=Vlbo;Z0;'<R y]c8җ,]"),K*vXLytIANKli4!ob\ˑ`]#'Kf䛗i@1>b`sd'-]13щr ;Vq LJe-"_ݮx䑬x5K=ᘸ)p^Wʛ㶰P"1a?>ts~%!ڑ XILdZ:R?0U(]RM1{V1]^Q8b%XA\ki!dDj*>Jxwj~Ԓ!ulkQd%* 9uN^; 'JU3`Էoپ'SeozҗI T$DE~xBҥW}/C' %Jr)c>۠"RV'sU9,lwG({npUÍZۋ:ֻ݄eH蒯j!+z }GRyM,6tk:a .-R@Vv9I4eYs!h~jZ}R *s| Iv-[$ XTn]Ӆd26%Tue,n$txMr?Q_-2eoe{@UӼE$ ů`,b5,^ 2Ώu ]t@`^;>E98;z3:C Fe,DR\O>a' Psݓg=@hCV0HV΂VV6QFZSϏȂw0zp!%0oM6,o R{K+$S\AIT+ QYqB7 #H|IfG7Y,0;u]s z'=7Z~vkO_glY߬*/Գē{?847gztzyMxp|x8b~yWA0 Þa5j`̈\?bX)baA[4o5uVf5ʘg̦Y| UX3=0g?7XgvV<ܶ; `|%xmO=OPM!BZS$Ҽb $.~Z@w|'/w[į3{N9׹{LE0TZd$&ktȬ&Ke_S^V&NHndD#@:~ 'ұi@$!?5CuļhnfeX9ܨygFD(2gzл8ӊ"`f>8}^\(BbUMXĹ[p|. ym\fK.eMIGj08 SL^7=3 66g덎۳m&npPKS4^xv1;4AlI~V0xn@ާq‚8Q[W(ǜOQDvbh`,RwM[) `柙 A|Uj[; v @KPu{唷XTUYӕo]&|$ 4Nc`QˁC"ĆQU 4*0nB9|n>.&g@WiJ&靭HZAVNӡc3EE8unb{So!RrWp' v:_(|b)kg鵂Z0{_ ϢXLV:kEͲ<rq֐{7-'3UE}hGB o ELҢ>p nc(~gՎ2<cǏ"rB{ObhfxT]O0}ƿZ8M@JZ"1!@=DNr[F7vJX<Ď=HQeCI%EJc>"urLw PJ!Ai2` $V xih?OQ /s>RZ"+)j]q,s}3;$(d9/rA*2`Q`l/lQ?h48 ^w@xBU%i)~(  KRs]?azyz[jxJ2ŧb=쏢h>@tc5.ʂxɛO#{ 0<%mo>v{9eL&nv8r-`8 Co*{b0蚢ךi1L; wEKv\~lj}_]7|֡wWa4klH5;ke@a=tiMQp5:%ެ(fuc-FM]?Tkڟs Yz&P"OW-OXzoⓋl~>c|ISv3ٖC C xm̱ J !. e{HN7|n̒& G?#ׇW6d iJo2o>mSEW*ڷhrir1/>xVoF9#TtF1䥶9)D(:Y=m̮^'iά1sVjj ɞ|7h4Zord@)b2ANiM^v p% qUIu2iPX"I&"|SנO0 8><|E~ RV}tatf6rLf@S#@ALI<Ή̬"H BE8JH 6*Bv`3б{t} P I2DErAlf$e=f1Z&d'sh2x,Q}2y2y:ex ɽmjN5N)RO2I`g0HCtަS|KΩ-(WRev?Oc?,zh!t` 0"X2R١tLhsm"B&:;*qF f!G' N*"jr%6:և'#uvd5¶?1TD(gC>jU9Nۑ3MvCVk#mfNT#MPdV{@G~%C*06|&>x 9iSy 5F3ZCyƇgv~`{BVB 3 fI8, g@{-xIA ®R&I3o?cȉ*̐^ UhbAq';Udw~T\o*uMQeвPy@CPdV]FqRT0qt}_HaI_EY6Jt$ʤ^xҬl<错0__q[uf[Gu*NlF /^l۬(we[TgHl+;ϮD%;Ԏ)fi6:?"A#!Sl6y枫gHM4yۖ_L̦jd=9Kģx Y7W7"q\SYilmt:s7*$;/lFi>aS/oؾ}ΏDGym4f.>2Oy.!`?iG%9 ':N^Կ*V7E%(#]:eD4.8f θ3َGt{q 'c>TQ#gٕ18}{)ҥYa߸Ji_0YcZY„6ⴟ:h9Γ޿=tucq㽣ruPNujýݓsVZSۓ{(-ntK*q %d jy {WfC1q^e}%9FKT 3u[+| /Yq,oT|o >'JpTetwB,?W:~-`c8q c"Y̳<DqLA2Ek3&e`ۆP"R0$AD%,Ę$Z!!  e\檗3Ouz@HboV~v2t~Wwm b4NVCGaFX-|N GayYH&K+-ZJ3y&oRaɠKv )X\^S-բqJ!І尀&Yg-_3[z)Yɮt1;px^zu}7჆ яQ&ʦ pm>dGFh p C2\Ͳi%bW r,}`+3Y@%1(KS9'X%W"#`\p::9$B<Hy8[F|炸x'ƽ2LbbP&ix<3x;O@o353@~8~T"Ap bBEXfa?5,}+#/՟8u˝emll#58V\wdmV FF}VCPÎC!Zs8$ұ/ͨ%0/uc#gY3QPmM[TEt<`m[%'2ab 1AV{OV -uU:on 8s^ve`LiI4 t,NA~2Oqrp$M%p07Lp>i"ˁ}'Bqz?$] TL)zh|O2@̥ 6yݐJD)^uPp4>XcYQCp-k7.#=횃eʺ<2cVu68ի+s9PsP1&˯WR`Ԣ"4`5, !#k6Q@gᄋ4k[gPO!*`[^Lhi61ZS6Z晜gq eŽdql1}T|>X 4KR{sRtd+7϶%.FTar: v1*jIVΏﰈp*%{ۧ ڒJIcUY?C ǘp Jed2Kc2D_w$7A%A5ESod4>*<1`5a0LՄ hi)Pj`DsuN*e~irK+ N Mcq1gEHKa,!zhkm7CZHv fKdHs @ (տXslC2f{-]T,g6%d#,*32sYWXovǿer~hɔs @fbv!>Cbiزe R^4ҋHOY]y;y3RK2^mhgdL ;Tk輾2?Z-j 4%Z'}Z.[{Q ,wVOR4a,֖ťք!8\VD$2EYO(:f r O,upF=7CY_nVy.,*~?rG"F`R(xɛsqPBIiQke;g&&Ej`_N肗jG% [ ApҦ>֦7B]^%ki'zA(F_M=LnC5&}6c~(ZgMB 1™Nt"<_mkŋmYF;V>ҲVDA 7[_|3 f =z1m\&n!-zoX\p0 LT(E3@Lnf Ze~_ g_3P7`yh"kHVw guY˪]_;<sO(ڈm2%oKJq]dnLᤤN![1w\({jL3z>F¢X wu fKR j[[Ete](| %[^|!l 0I( ٌ%&+ ChhP9"ȱUV1QTGxy<z ?u:c0֜e敬LPodBwX6z8mkˎ$;ol e2y+@4\J! no 5^ /ӼcK|bM]ѭ'Xϊ|dI;zzJm'#@,>9`7.HdYT`d6YȲQz:AYȍ1˶4 ,V~\8,V!#0 SnZQ"H 7ǼBh{1!#D,fcy9ּ.4o`q2w6 _A&ۃ_So+x^b'#foFk9Ex^q|'#foFAfF1,a|D򳭹8'kL"y)EYD7oֈc,Vgo f7KǰpV]xSKOQmyHh HhLXJ` B6C{KЙff qʜ]5&ƨɬ $&$nq.{{9y|gn~;z䜆gƻF_qdq填ukPT#Wg\^E8x@,ș$nqɠc.wRGg}bif %Hxk9sA|j⡮%+<]}P?a2nw&p~NBO CDqؓ-$-uPKR#E ?CrC&F Vb5JR(4iT,''//zPLIN5 aUFs(0i[;,XzyXZsXXb=*d5Q")άu[䂘ʹY!D-^vi-xջ|ID^[ƺ''&I 7|X``m]\Ys L.U.)YI)r1f%balx`/}ctXHPL{t;ꪌ4=*l:^el~־d9^2zXήMI3'(4ަdUV~E(T;~eaBfnq:Q#7ƹt ř1i2V3f[\\K5A:kuap7I<>Z_6[nR|̸vxu"UcI1>RcdqF[ʓ9,?u`ǖ،9s'zpx{31fC+dE]ybL)i9%{ٙ&wYBtB=]j5Ӹ8KS EEɩA v\xe%51TBL('9dMV_P k.x8/:v3"ub D}az5kc7}`3φWhPU˩T(./JU*VYt䙲m0f(؂]PcT2+5/EgG1nr1 Xx{b70.9y d^~Ij|rbABzjI|ZjbIi@V+Y&e϶⌟[gZ]~n^/ 1%%$1)hF~A bT M\|fjVtɟO&y\F@:YOAF3'*-?'%G:4JArAAxk?!E7?/ur BF1E6IoU1d rxkopȢ:9Irs!{l"z:\ @P\ZZTY_dU\_ZQ(O?kruҗ'sۻk()x*(M(S6y͡*3(XxT]@}_qd6UYv?6Y 0qk3Is?4>XY"&d 68Nq.$! 2a; {Lx2d #yJbhIav bhu3`Оh0fͭv SǙ n<U 4%Ϝ|4#\6K,jyDw~8~:eF+̰;P7K#ȵA53v{, 2##@wPӑO̵?_v:BY~AkueRkd _o|74[6!)MD@]*R1K:ҫ2v+׊rmWH( ϨF-x%mo rL"k yURWTʼzb*R79ϹrI[ ba9'az瘉]b w T-o'T[Ux@2敮m-h8qH}T…hՐy +Ѕbؚ>6uxV Wq Jxn>ѿ88gㅃiy%y %E%\\ @Zy1!lJjRi:Bv3I,bp%9HXsSRRRX'f)-NLO,Z24}xk~5]&)8V)!%(/17UAE<#39CAI@Isc? ^ ;l2x{ȵkͧ3$=xo0_O1ݲuӂ*woDmIHRWٝCJy& ~eV@,gp:-OٱUWP"x 5 Z0Ve+U RZ1^-+5FB3>al7[8 #JnRB3tlQ h"$B`ZbÿK $v$;b; h0'+A( 7ֆ~p lJZ! }2/N.sM>)!a[@i"P/£CQp9*jا,1dCXqEm}r2DOKċ|MsiSgtqc-{qRXI-8[ŋk*/I6 g,cIo{ft´m=80n6wow.prC!հJ sϷY4qg5HPd"7PlbO 1Ї=?8:>i x~y37FPS x~mԢ"bҜT܂ԼbJK jKꁪK&'0ZKRՋj6s2]cX&qxK:ɸ݊"Ř}N;~)hkjwp@H28>VJ pBNj&xZ y__ z:x~3`5},kd֬䏵i100644 ru.poe`N;4fTP ^j(*~xV /NyJ^Q"L6C//*I&$)~7WF[/<oJ"ئTRp100644 ejabberd.pot]!}_6֢3/T_o,1ڜ%O$4/hوzIy9Pw/帡Mj@vzʓ/T5k_3g1IüL u= /WY̎1E}:100644 pl.msg5 f9V-P100644 pl.poY x|{g\ќ't03t2UH~n."4&z8L60EsO8:g͕1}4dQVqْLxFwhvwonz8`n8''9[('zs- r_#޾HQ)6+ATCJ-I L᫪-kWCy Zʡ h[ͼf`s&f;^9 Wi"%vk0Z^ghcSMJP Rye]Jze[.+|?P( d-IPVlx/# &l8b( tOB:9ʄ|(Pqh|@~;5a`!ާOZN8A~:9>-g Q EYح_&Ax|0ϸ_Tؕs4zwsfG򐫞0{j^᪝N ْ_7=M7vknS`;&3g~ @tDkRJ<0|9 _]F蟄XƼkWU]@T 5JZWvL(J i{몵)Iuk2K/wKzv " aV̠_jBU{'2Z*0:[㫌"ԉH0d!)5f wblsMÉV ZC]Æ`Rao$;d) !%۲Tc /k<Jc>&w/X|ʠw݀+p]*mf~Om\x.l} tɁ.Xu3FNl͚H͇!wo U8;w<œ*#̩ZFqt\ɤػIC3R{zad#ظ#Qwq"Gnx6dLLTQډfc.>đxC؏!|V T ,'mx[˴i,`ؕkw+ xedՂ8EEXi Ժ Ix[˴i,x|O)JOnvЉx vx[˴i,r} &)I_sOCu V#x[˴i,Su7Y2.~.ԢpvzL Px[˴i,bN&'5-|'xܳQ̀;&;$HVxM]7@Mqr@τ x[˴i,7N/\N=~jEruU2x[˴i,zk(nu@kF¯\ _xs(WXCih? ؑx-0|Z!~=x[˴i, ^K-3.Ċͥ?CT jx ծHVx¼w Q5Jv]v /x[˴i,›xLhɛ5ӮYx̼Jo.#sz<Qxg !`^Ǟ^[_2x[˴i,aKȯw olߟYsݴ ]x;?Q5)9rfϭ x[˴i,ӅNIipku K5xx6>{ bHWjbx[qZĭz&x[˴i,:YKUbp}A  Sx[˴i,{9lZ/?xpu xuwzBl~둮:/x[˴i,hOWzfiΉr-xre;idW,T{),x[˴i,Hfƾ]~|q!{RVxBgע/Ԓ5~RY a %x[˴i,GKwp2]ߓu"rĨ-x6Eܬ,@۟jTl*jڡyZxi!Kg)󪾧R"ڀ6x[˴i,%ʋC.?puD {2xhb)K? y7Cnd_x\\FG[kz x7'-1RQX/x[˴i,A3^]UFwO{Zx5kcewG-^R͑%dxA^zH3xd.| =>$Y-`x[˴i,ri*}x*wuT x[˴i,S{\ {WDg HYD+}ܹu_ g6xx5[ĵf#jC[3$)cxX~3먽q?_.qe`xeGcdA:t=x[˴i,wJ- M4J hx[˴i,eۤ;d9֚gfٴ[ "x[˴i,ѭ{W=C>~_Jgiuu r>x˕Mm}X/ˠ[ۅg:kx[˴i,y o~z>5z Sx[˴i,Z6IqH]"cu 3AxIywqʦ4޹ViKxmKn! Ds%df cVN4RY_}|8.쩼YaE:̡A_4zJ,+;1Bsx!N\.$5Z;/=%2t>k&6DOS12Ɍ6#AH]4Wi 2;UDZ7yh4x;;!J8-">"1 'X $9 9 zYx;8!I=$G7#5@7%8#X $9+٨XP78*px;qB߉&+1=:mm+x;qBĞJr)iCx;4!jb~iWx;iB'gkx;i# :g}x;˴ Gfx;q{ ^2f x;tqM f1x;tqa fBx;qrfSx;8oledx;T<9exdP dxlhx{X1!jr9Nix{8!jD5i+x{̸qBf?x{xqQ Ydzx+ =x;˴iB)lgIS#}4wć9 <kx;tiY)lgIS#}4wć9\ gx6,09 Jpaxz~k(,XoV wc4Fbafx[˴i,y CS,-'> x[˴i,/=&L_U_ 7xTO&z0ő^dx[˴i,'_˛ $:x[˴i,ILt4=w= (N9q]=S ex̃|b qȑx[˴i,b?Mt&`rߠ=x[˴i,;}stu6+>_l1q]= hx[˴i,k՚pN}6\k/,+}z? x рX>NY$ @xșC/}S7M+Zmxsךhyײ[Tά<iV&mx[˴i,#]Lkvs%0y}*~8q]=e ExV bO6}OgۥrxV6ң p x[˴i,א[bYr*[K,Օ16xx%3K΄j_%=}yn(x[˴i,Ŝn+lWTg(1q]= Sx[˴i,5,c[.^u -~x $Dh h|x+x[˴i, ulC3o\]a~91Vx[˴i,|'_J9zWvfu x[˴i,k_]A,/tuNC,x{IA蘿ݺ<5CYxqg̅0>yIx[˴i,scTΞkPCdN 1x:^@ږZ xptޒyʦu^x[˴i,!U.6\J74rKxO\W 4xXR4C*Ę&z~tzjax[qZĭzˎxKsH.~,{ʒ"V\Tv(B-*3kCI'P F~~D/f5feM9/wAztםf]!p8q<._y$A75ɦ5R~6OTj4Ce4Vlnx^ ޫ~_%Ö?Ꮓ's^nmnvtW<xF=F7y}UoOU(ՋAK%!|f?P?^o{OA6'im>0QSՋL=F+Qc7*ʰAe}DC/e4Ssmf>{~H ;o)=R\/!Ts'/Lԇ[h8QtC?y2U$ bhG~ ,Q7.PqA̲V>{*''q M4~TTUć⫼,ۜ覥o`!, 3Ta?ySh/g. ҉J|2|X~(-5Sǥwo/xwҕ'ϯNl.0]N+W%Ix(S zҥQ 3" NQ=)@_ `P؛,A>ǝ?'cm{#(Hp6&|6Q<<&&q3OaqgL%nݧ0D۰L gFx7=1-~0}lwf1l>!EdG<+hq8C.*ٶ^^B^mۗ)/ 5KcS.?: Rr=M`X9[Љ m,IՌ~f :ieͯ2g4uzm?|k2>i ༌vQtT-L,4Gߦq4ܖ{ى}osн?ԅ!=dɢ S=ͻ99+]Rro3. =-c(cupzl@'CﻫϗߡhqW` QkzhՉn:Z+ iyX5d!<4M0S~hQCY Lӑvci¿`ţ~|omi -19Hݿco#'YYw qUZztC s/5bYXzd /^KO-tXgIy0&3>pSwT\*)xCͩv AIG?.xb/g ^G2>°qƺ/9S3T @i iTVب Rḝ+kԏ(Ut`kU̢ן?~tAAdX/s,@dpVQZ7%0ȠH_*՛JR>oI|l̛}$+s6?`xSz#XOLVKDg~N%hFaoz-OQF ^RTue%XkPl Pvjd7BRqBAzIZlp>"k?ŽW6>co.]t^ɃÂ|`yܲl@Ni9~4+rrciy{@y z:ͼp5}>o "4L'1inoo.w//﮺]R@Htd Æ $/ 5 n˻V .4N'O$a4x!lQ?2) YEh<\ia^Ԡ6inヿ~kBNDC N4'>)rxJI|Tx!"|視E+)j z 5 FXDZb~\GoquW%GeG8,S,Zڮ˰PTΊfofj'gҗ%= uܠ@CUZls} g^ɼܓǠpOսbVm/;,;f Bж$"!h(]}m7 AHHxs҄m *KyWԉFXH> W篢6׻o79N8n?~o-Gk斴O8sY,>wQq/YR/_pTKQA sgj?ee8p˄Ц>dc*6IpXUyʏOoX.,'Z"/? MbT%cs]ޟ.iQ{F/-+ϾVd& '4(K._؏*֋C9t2H,[;!Z$?,xT^?+¤DGrZDj =`gB+b Gs[0Ob 9l~'~Sq̤-cYgOtOs ~=r^nH͈@Y,v ӳ]Ԍܞ؀EPYa zf/ ut7#js\j\0B_G{)3.FAA>.?0X+ZS}g[AH G?}wl8t(1H1̌߂e_+, 4-tMC݉ CS-|]~\5[xckt`VyDAT9ҭS&e-۷(VSmǟ{/S+䲉 |!NϱF'u0*1QQ~9 $o :E`.`J:m;suT =<)定7W^hRr?T* C2(\MUvh*Á[+@4U4&C^6l-tF+F7?kH'/X=HHe=&"3S^Ja؂8Mޓku3947YXԃ"o@d)9orp0lyӋvOfհOWaO3#0b8w%*_.o1@Tn>f-XWOiyTٴ0T~rkJxoXOo~y*+ɩs[v4C&0C_vǡg 2'PID)̓`؇Q>;XT]fW?s+32ܶ5#ͣ 3;ّ95 ֻ<¯ ?s,y Uz:M8p9 ӏ,]9Ub+e?1K77w'?wW7WMLZ{V؟nw:cO,N[m{19:6j(-TJze}7Ó Mx! [x8H)(hԇ:\٥k;oUpS0(:+Ad,驝R,ؤ k+;+˖ۡ_/?=\qE( S~j"WSƋx&ڴ".&Ư A&:,'q<z4LsaHG* dREqsm;ݴdI2NuTZ^r<).ti jV?Jl TZX?Pص$c匊r-fbgAXC,9מy? XyaŻ!Td-8=hzackxt9)#8 ӹB!#@ꇃyHgp)`ywt@y]uߠ$Co™ б@g18*Zk#m._~0TBm}#xO'#OD٪kӌv($Ln1z.tQsQN?e 'EǣTO5c;$?6"b]_DP @G{K3V.26A+ ,>3Y؈%`Q "aFЗЕl=Xi]SCq Sİs@䩀#o%Ch 8i^_ѓ3FˆъF|laZ^,R @Rd3WZ7tnX>dmo@5L)p6؛&o 'QT-s&9_0nbc ߄LR".{ OB)(i@6 V}L10yVJmdpVLn1N).6k"IgSX^^%9cx >AߓQP~{NˌFonZSt`ϱPl}e-Oal) 4ۂRucXy}=DP TODw{uk+Y1@Mqb3e zH˂lݰ >]ߢ 쒹#т#f"k4 |b1o;FeѝY,Nd԰EL^-Ncjcj+wB"HneqrHl-'q`_+6[!F14_%<亐A>.U>,!Ia劓2RLmbDiI<-i5 Lqp|Rx@I(eKnJŨ?&C?1vĐ~0K;1a|6EK ;/l23KgnWn}`VAygOk;qg0*鴔+ϕd[œlCUe0Zy%=;Om2l ףC{]Y뿤߰tHlwٮ$P9pV~nKh ~3Z|cx$uvHؗ R3:}0f;DU_ { :)M:ugHᔾ$+aηzshPIw?S Q`YW?u%{DRVEY(=93Ą4 )t1嵞yeƧ$%Tͅ,/z0y6@ `Nj۫[n>+U[ ȏ2KlbW[Շ<!+%!gppbwNevDWa"BL8 !ȉڱ})҂F4Р)XiR;n"'syh뿬8.}m_Iǻ k;Iw`]E?>8F`FdA&ԉ֠;ȍ{G(bQ$ߜrv;+<4Q]s2ڻi/D*[V.?)9}0gj7Fo"H@wEcH*#VsON?ti{[Yn5} J7 ʟ y'OC@5Rk|̯p][̢n>ID>py,5ȝYgWj*%e}`9mEg.f)9.ue8kgR=˗G!]ZZ0:\(pGlR~ "sgl Uh# 864"`-ICxbM8-w1Ea[AGN6qA0%}Ɇ;os*Wժqn/հj2nMuOqMJD{B:1e$)b3mWåDa+d6Hm3  t#\AF@p-Heдn xV(cPW^ k 00L]sh2m3@Q)e@JTԳúby.,q~?U9j6jwmz `'rɝEݏ ^Z#?9>m?=D(yP~T%jܮR|!c%ޖ2lB`6&n@Y fr~uN1*SMf[y߁ (6ClgUvZK`VӅQu# "p܀RgE %2ޢӗ(@knGB@6?YN[) F/1N8/,-5BLev8S1+z>Eb &(38fsclVCIGw"j40gmkl8bUuGt܉kҤx`"z\yE7}_E:|a됭jBU]*gh#zL#gr؆-zɃd`90!x:̲x^ ٶ3riC1L7LKRc_ٵ!M Q2Y|eW뉘I(1 }߄q}bcD!|7íA'/>I`,y9 NbaYqb6.lPxAz2y?Q6x< ³,=0L@ Lۀ>5,XK(N llb5˫h M5%x '%eib#?I/8%D1$q53U6ײ'1:5@ gKCGbb>D} F`_u&F8|XO5dm jSA*ۤ؍em}p2 b %ʘFa3 OE|+m[$s+wѤ|4#>s絾_{V؏gKP9jmi^ipt2쮀Ǜ5ZFO = c' ^IdI$lβ& 3ɯp>22G;H*sgW EubrwXxyic 7:V$D<Yo$._So.04_⏾/)$/ITHzw8N"&XȼAŤ:1'RD5@ڈ{4[j(dzi⾥xnuYVdŜ=4K\rPu.RCD?8E~Hz(NQe:WeݞG8wL>&<ћ9鼚D0+[x=1w%^4yQji廒)ҤI15+޵;sLw`'5nE>i{] USwmU;YSH c5bvj}W3?*#CMT#|wE6s\ň<{#O񲮾+p%eR#uTmLtBJBIP`Zv?bAh+ @=֠YJ~݉'>Ic/nl9Ԃq4OT&.uyzaQTh5.`W6b V1}ŧ\adKkԙAOmHǕ3/Vc89,/Y:+L /M9Nʨ>|3# r9qKv\,o鿒^ so(ڬ-I[D[yP!BكU GUTd+ac׷(P̹f̿rEF)F\W]*tO0ać<"eHR? aD 2O_a洲O2PG9? ֹ@Y_)ZbABD-)%SQU<u|J^7CTA8(p-d Nj^}ڟPQgJTǵXuMAWV 96Ǟ 0 UͶDDFӑ#v ! /#c$UP( vʥb_ XmWqU:g*VNMpkL+&;*kuF*Jn˵mJ+M^e^$迧貸-$a:WkKb#FOjAWK+Qn?Z @!j*,8C2[5LJړvhn*;3 bL8;wO{vV2mGXad;c6a)1߬g70z}?'<umB,pLeCfK~m 7!554]'k弣{"׹Ks۟(\YHPUkzzWn3;&'K{H+ָ&/BܦXErJ5R~xswSZ8|#DDCvg` qoKskֹlQ %}2 o ֭rYj21|0 $q[0_L)&Qp`cR-&e—.'+iĊ\!1/FOAA=JS x'a}lϭY^|q )Qc?G99[e9sLj(9cf N Ky钑Uq@?L9MIeT1@ZKB&Т:{-?F"`q,iv]_Gb:}A~w^;4Ⓕw`C,^uע ۻ OPE;yę_?I*~h:]`2~$u \U<(:s>\G(,x[%Jz@*n.,GK4 Q&xGpH>!LadpG Pf@ kQfpuuTft$߱K>W0)1; sUV {x",aS|)OH@)f=٤gզp'*F%ըh,~)+Ѕ0D :>[kqL"E V8/d  BgP}nfW}c P> .W,謾ۄVjbܜ3:àC+oѱw;sJʂb80XAnp^hlDssLQ!]x ^c-hz9d_ W/ڽ0irόmNJ_p ֋vG'34B^4+ԡń g'mn$R1zA,t9G0-Y}]Ԙ(XzϰS3߅yArrXp`#jY@yN.zR Sy 'TU}}+qu*F>ɞB9/F gyX@mSk6j"5;]ZFQڅ;uf*:uE#^C?c?++[ >M v:8|1KQ' < nn@L2N LEɳaF+R*У&oo}DC4~9n2t<k~r"H*&rxeUCTI9vHJl~VX^ K15ˮO'Rw.aLaLÌ40?y q>naM=GúșP2ZńKg 0<ln 'IQpzsғ.kP2ׇM/|onh*{\wMN&14B2O_0H<3QRVoVxSU䈬&3]8h?c}%l̔6VuIy3zF PҘ7[U*n"e"*MXn3 ` ip=y<y'tQRO$TH%ۺ,q:,Wk*D(ޝ ẕЕk:@E%v`a#SY`r(6`RzsgV)W$7/~Ńu |{RQUfחRpĖΙ庯K~Sʋhl|b(V߱$cegX_'z*)ÿP rcnu aPm-wisdaЎ0}א !%uZ{V5A͹%o'_3U WS= iH2NNӓύxE  "N+imnmT{҂*7 leX]gmGt@iR]$%U'rC Lhwi`F-c)smO}BBIADM1;z @jPwuu2O&pU:=mp>$\F*fW0%Ks P1c*^ךܸ=畠  O:6x! jRnp[R,ዥlYUџeմ0>2`3W2p,,(= 2E7clW0a`}j{'?6b*;u67 -38ڲz,/;98s ^]8DcrҒЧ1ᣲVaꒁ! Q r%?Cky؛9PI0AiZʞH4wH&AXi+O5&X>sgGwQ­3%r/*qDS&Q^/O|Op㓉jC;yj}pts\\cEs}GOǵ<tf t"F#mf#utXܺ< cOjz}ryd G.sQfJg4RՆ~5S^'[ K&6ugBT86ɲh>`$K!6b4 8[ ioGs,2ApQj'vjpC6ymYc``5rqm7w"LYM|sCgJ A󎩈VK*sOTӳ;eWƣqD o S&ڻ&,s+UdG9 bӏYS*:(/!4<8>Ȧ,扲.RGw{AR'~d&Ka\].\nJv5n–Bz^+ɦrSBlF~D{F܌6vcI9GĹ)'oܡXtsR?1zN@LҠC?ٮoa & 8\(ϧw-T3\,'F0 cgcGE]=lGe'7x"7H`awe?3qt/Z]J9u=ZrFjwH>@E?T_@@ko~ziLAmݫ(TZ}|$yh6P.@7JͰã P!YrÒ}#X}E#/z(ʱz;HkBھn'Ԯe_7T 1AcTN&GHi3ʧ{gzw}憖^??H ~b_kf)V{ O e@2{5ʑr{y~1{QYEOhWnr8ު6`3ց) pWx^[*$KB1S.iG04JޚL~y9Z87"]9);W[>rϝ 5 vXgU "[t+e9Sx-hv+W7X~X4\f9z᭫{]2:u3ts/4PB?~@BG1v5ۘ$TrPS`⡤3yoA{\SR&6Y2jJ3}3,P] 'clmpBb$-5x[9._FE' 8.BS`JCZˢ-O(D#E5HXHIcE)gdRDD/af.`u-f4 {T|I }YaU_rIYT]|U]>G?-4|'Ӳ)w m l{=N t{y0Ԝnh O wExc0ϝĚ(*O ;cJ{ID~V6Vwrh`)ZoApJ5?{.αMusdg26Ap&#x F"ERumF}Oxjc߱s3Zw95r]ds Iח5(|ōD*όYѷIeĬ?E9(+?Ql!Zx!~X/١BijŕI&8wLkv q'*㚩g\⢮T .O轛YdTd*i4Ղٶ{ɼg'J,d|ǤV"(..]kNw }ZEf<-%ض)w'5xQLǃG*w35$ t`UW"H:Y ,Ou?]ç+0ba#xo(,V3ZN WHaIeO̺И6dڮ됭^b ɇ@*]RFœBFΓ d ;ti`8_ĺΡSpq2H LP!\Dfԃ aK=\N"60|bSK'7 #} i# OfW^0)8ݷ MSQP\:OS|K!k/g@,zYWt@='?vض:m.Wr<ݟV& &٢,Ti72~Ie{N81 qJ盕V#ť],MHS6.;R Yw>.^CݮHvI-.n/߷C[GM JC$g Pj\)173+7m9-TF%ha2uLRH);!*G#V;ȱa1z,腮Խڹ9j bwܰ sA ;S'aY?[FbyUDK0{A_,3Ub3V\V[ n)G7#pQ¡a{<>8uJaģQebPF'<{4ZuM: w aQyi龜emaJ̷^UvX.ѐ<2ɥ $u Er}&|څ忢kfd%B8}dעZϥ|xr.[llhL ԘNi`s!mLwCŽ['R/kN,c60ѮʊjCMLL`BEAA F7 )̵^?Nn(" ;ض 7%*kJ";}P v$m_BӺ$TPǜ;;@4+TP߂U5eW@?džpVq\.p0y60{K^CHG Pz[t`,L~YP碆yyxU?:2奠gC$D% V p! X0 0B~0BW I= gs~BZ'Us{. #C`xw0̖5/̠wD:m z C8GgBbiJR(++)Fdr&=?1kqDiH>^!8`cr;RE?Jz_NP{1s,~P{af܎'^Xrh!b{eq{% !4: }[8 +67?v< =Tܶ6 u>"UXd^~23uz-]k~ӎj166R'>3he3b}==-OĦs?Ji?Pr`Pα=/9EL?a+m{gQ.ע| dX/\qPXiY\/c>dN)TC$ws ]$!~c4͍-Z Z]t X ?p@H?PV"ӒCM-i*Y|iS$;QxyB)E@: xEoA䉶pٔNq&7p[Zhw-QGw}IX +D8KKZtYNk]?;dysd*,$;|tz*+m+wنŪ73 s[$4,hx?^ ~WD5*]+y,]fL6AjP>4 Y mJnCƘy&=OcfU6>9I%Qs7Lb,|ipmݭ3krhY<%j7Hl^$av6Ow`NO6OkohY~ZdHٔ C-rȣE~l#TYkYWxI2o!_0&:][X9+L8PN -dLS*JDl0;w< XښZ%y Š0[ʄwJF#Z<*[冺$kSPę{[z[c'S8Sc6c=[r_?MO!S=GkptM '#cy-c,t`8WnT}k4#4j+c-~g+VLHAG/uz7]^opUTO/!=NU~#q!l (E @:Lk'&kqtߗ& [ ^_SraQ<!xns})8]nj1h+&V}`PNMO8 ~!/*)$Y/¤ӏ8mQbesqл!?0EafwA-XC[o|+VW eeu㢚$Ƣ/ M77ܥsHp"N d ywz14v)BͧѥA{Ɍ@J'R5sをK5-?>) Puj5J:pN=>jdUȯzPY[Io8iU٥6k9QRh+ADyy'.ӊ*4*daܔk_ 7=#!VdI`EHqKރR31$tvZVFTEmpm-IjJȦ8x `"gNC<`%=HS \ a( "nφ1/1%'-4խc}r KL:ZH~3Rō&ɟ򈺋cR̯ͅ 3:[GQEc}Uxr, cjiO[`1}O]֎ccwܼjN#@<=D^g=Ip6I;l,k$o XZ1|*~m_+@x\y3Hko4 w} tSG|/<_VշQR{{Is %_511g~~~Tx,?d& h!sE ?C҇`nU<%CE#Ѱ߹<տ2NhSUy x7uywdە;[0 ǧ@U1QaH9B;q?ib|H'V?M AHUB c0)gzj)e+,Zx!:D(2{-6Nb}P+;[bC kؔڳ8oTׇ ފK=anj )c Wf?4q4uS9 pYGtpͰH>~5c;Sj8q࿤8M1WbdP_½JLb:DenyU/f%a]&AHHIGkn_.{ȡ8Cjp >ݦZ`q9Tjɏja wVΪ$LLu\*\S@ ;%,-@ζIDI! IW^+p+8 NEe$sW9dǭZE7j?at >r9y" d='IӍ1L+#c4mEkuljXe=p (#H0U!H9,Щy?2a!wK\@˝vEz]3;lv_ݸ%3.B~40)tJȣnڌjM/瘜ޢ g wc% -w^ Μm*Qo+"ϲg9'_ϊ#1A2m:+uzl8v;"D*FCFyŋ0e&%*=F퓇I)~\+^"1z8 ;="E:vޏn^()y1{~?2L`ܵ;Unq GBb]Fh݁Et%Џ ^FcD&ln>X ZC%2 mpUVfT'vPvaU*kіx p> ))yJB-hE֌*G~K^k.w֝y)޶k*Fj,' LW ̪ qZ w+00'3ҝz 8[Y%?~{2,b/͹Jt\sdB^Roጎ!fh6eh=@n8j27x̬뎫LҊ{YYj\xW/%>1Wj?%,] U?Z`atj(ђE~@Қ#fydEW5@YQ.vCLSmzl7GDm1}e2ϮQӨҁQ֧U߃>D*&& 5w%sy_+ F % &>W`QAcm}y\R@q7-o@F{[Vd[Nj^uN奝a(}8ڭ /_!RŒnMV&ejkUV֝XF/Ϫ:N^߁Ч ~* reB4u8:D~ĥ Z v-$Q$-E]򒥌:HBtɁ(˜Ne |z@hKuh(H2$.x{Nn$*8#xHdrO*R=Q#nWDR׊zi ^. DZ2+c񩔿ȚlO7/wמϜK\U ?nn}*;/UY4qgڙ[F8D 7(jWtV~rǼ0dfFw>|&5GzBE.Ua~i+ζƉ/#3L9L^ʙ_X;JJwoblhFJn9"#m4 (E bcb*DMfuPFKB'܁ߧ)VS0/۳^nj8[5=ܨiQ%L;tށ.ob+6(۸ ZMO<8)H>+,&h˄8?)s +=+*l9 -N/]yźUiHAs_JNi≏ݛ뛫/`Nejud>[L[4d0q$sxzp1:N9KGqGVI/[0Cw4*k^zBE%̸D/w~8myIng|es/QiZԽ V zEGw޻ r;FD Wqy*U텘 >z~“QG>QJ{9I Ceq0tćFŜ5vĬvR Ϣv_f|ni_&pq-A Q&єa R+V{֩\tu2&%]9uݣ"NT2n 67qaWOS5 |B|boC5~B@67a[=0eDžK TBh١{tɚ[F粯'1@Kʘ000]Kόu ?2G̏ȾT5BO8K@*Xyv R8!`[դH/QS$ vvU=D>$r{oBkʰM ABkD) lλg,ڽ> Ǭg}h[4䭚B Kí0ETk) {$?/J ˂)NJ?&5yV]^gx8:.=m2u,{L}{'4G<:;H3 ^'>g|rqKq9evqB:.BnqVI[sVC+#kGwLbR‰+D $\a)`A&pzɹXzR}Jyp%I:D=IGw墠 |!j Piq}(f,HPۇdpaC\‘v@2GJmkZ7"a\y;H ^ՂLA7t)d[:|QoHtg:4K esC$]LKѷba ?^@z8 FqKՃk**+k~"gKD7eiHyss%骓t=ee*t1[:x(c#^\ASGM5x#|:-i߲AuP#R3[Xghۃ3ʴ@s9O)96Jar.vzr6 S,JhH:-C,r"-@B8$~j~Az0Xz 4+|nah(GF=C"\QgSwp#2G|^7WN0NSڴиd@ZMײMF]MY[SW[Fׅp~oQ!Gr6{zXn! qբ(,yx\L0nU=Www_zX#W~)k=?>;313*,)_6/a.4J=7HcMs%4B\9Ș^'S|=OS5Pn*+}o*hs0ΒL?2Z|R6tӁ wu"V{~sb-G&X㙗Vd*o<%]=ёzvwן}ΓqͦmqAxϳw[Zyrutت~L@KF&kajA t67@`z~O/_[ II(&2*_h  )9Zx]{o6~~7zK,mlE;99łHHD(NaMHyVݛ:gEyG#c$7E =0:x*Re2좇d>\!f[9M!o[X 1$Ͼti_A&Lcoٚ}KbRfbynnۗ۫mF=ح4;= 'WK!'aemb|R(L}T"= Zڭj8 Lʹs H#A'iqqUI819psn93?:Q-ȅܦzlyلyh{gL[@~wGܫRUM0~K.+S/GM,'=a/^i}fSe;ւP܆ttb:!ѷioLAZy6^;V|ށ8VrqY{鬌iyhqR@ uwr S! OGr7H&ҽ0p +9TI۩ܤ2`NgDGP2NE\EtT2T ˶X2.a`>Uzƿ!}m1s`.d*55 )5~`+qd{ýwfK*f;dL}QM [e 5aP:=B/u3-jJXc̜% ! ;EI9Nz*?ߦ\<&/WZw ^o`b;ٲr$W@{ޯxD?3|fS^ٶB3$ (")<0䚺9J傎'~2Sl]˪ w\CEBQˈ4֔]/_mr9& 16힫1c0V#;2.$Nv . OTF f@7z@ F 6Mi"@.Mn'u\k@[ S+&#qNY,>|@.kn߅ jXS'l{ X֤`SA#\Ӆ \<$TEthS^_'PlRCbQ:rWfL*;RXF"o}'qA6a[jFS;eSY9pp`D{ɕ;J"BD)̣nn/O=2FB3h)t"7 Zzd/V|C#^,$/3ymO.XT2K4,E] (aRcU=poh:'ށvKB\3-)YŬ!k> ĸK ~Rvd.)ib1 |[˒X\ȫ L-yq`CbK3U&  7|aS>BlUXߕ"@s_2;N1fJ$ 'foеbp5%T\ R%7bWޘ [yCFo'YxIa9bCXuOSe:G7QMѰܠTN5]dz` qw۟-##krcqu>3όrH-{ы%T+~aYUPrm mSt %TgR~ b7`)OWvUP^y Nq%ط1ʁOhdotMVS-qcy*6` eW9:Ǡ%DҰ<' >p>Y3 $nTjy}x1,IesOPKrHp7剹z;W~ݬj6+a4 *?83n }jZZ$|fƍf2~r.ÂYc3ՌJ8—p,lcm̛H%L)d&"~T*ÊR#o2"o6gw59D ,t1H"\K{Pdj axsy+S~; L[x3ߢ1ZyaLUbM/|Oia~٨$?ʻ5G@Y-eD -CfZ¨c<0#x%E"9_=qװ=L+t"Xrib[_/.n~;;=\=CѡiOsU ĚX&Ve!RK1\W>`-ǥ -afD b0/H8I#doD+UZ6Td2 ;z ' 6sL%^'FgkI!뵺[HؓR~XS !dD0o{N-W63SD*,'~$fFǷg?k,QvC?GYS~MdmT j!+{ Pw+Iĵ\g7HR eD汖qiMCnU:@᧮}A/KƅUoQߎo#&P=໔2Ya$bR4Q)e>9yޚkadr6P-I$窶[)$h鑀+ʓQT,$thE7Hgq,I%vRn(vfY$T3yٳbWB$35kCf-tH- WV8O YA6 m >pS`K-J=-AkWhϷX~dObef7rtf{V)_ EDӗމ8 k67j7@<{֡$"F؆_O1N%8 a=nrk<%@\O]I IZ Džd ?͛͊ hi:d͢"(b1G w]q>podZX^[>Һ*_" ?X cnM@BKȔd8s bqaŽ D4)$$ƛmHe]P 2ܲUJ^-Ȩ  ^o$A6[ia cDl8 հzD# ,d5X\pwIO5Laeomt&*|0 B#8N r- $oF "'C!*x%N%ԚW8,Y # RojK|/.7w=>>/0f$ $(pTj(ݑ:\j,[q*l@ md"wRjƇtj[)nWfшT 4`̷}(33S/Fytu ]cTNh2+0OF'mYj.̌Y :fٜiZXi |ҕҲ^=%w2-MA|.3YVk~dUP7 1JW92gπS:OnEh:5X,67%' K s2H/?VZ޶@D!Ez֯KPY0bh9Bk> Ѫb#@t>\+M;8Cd%nQ$zsHw$ 7V `T5V(ENڋ$I `q箼 ‹G4;̍sRݖ\U᩸0BUR{J.rDɥ`\cGR$K.Fe:6gTyنT2a=1$#V6l S/DF ҩŘ `Q!Zxϲz*cU4Q23>$#%v-ײ'xx]jbjw]]e̅kv4XM*j>*2VȄV{[ZsP >"$åGPo)od'4yij U"+Jo%ԝ DRR8@94C"Ru僶i d|A?E}>{h%c`[(w^*!YX^?G*icNJa4;H8?İbUu r+Sh~h-P\u䧊_0hI`*-QliZSr ֡?ʓ8jY*+\}@4TS!z[ѓd$ nCdSrP>>M]EΘa撄卾^_@m'#=|kMHqa&YZc)Yh\SStI*,5O4Km /)(>!43b`wz9`Fg@:~?цEFt Ԁ8@Po@4n0F|d1g]xO61%[&'#EYA\L#6F>b2Ѽ[Yhob[8R% o"AjӒK|HzRXwռÿ:99ϐ\hmϯ7]`jFkrp(WoKʯK_k`eeU+axBOa^afF2ttJk'Yp"\ (wd/#`O?dd} 7:/)^Y! 3qT>gS^ @atx/ uᢤ42J(qQ ي(V MQ8ϱІi5y4oUg ]Z~"-'B)nJ;VIPnז9-̓gĉ.?XYET2S਒ FI(-⥒7 DN9̦_9UC]Pህ>@EJ)F=әMJ>WgB6n<]P#)ndֳ"`o%!gF+-)9łh9/a_nRPh,iYvU3\^GZ+wFiVZaa"Grq 2^A}zE?f!D5`ܢdKxrb)[Sp | k(ԃnIZWSEo7zJ=fk?dQ`b? |*!+!pNKWjIL'% s4ȩ*A]f_q~+f^_Ra&τYl{5'qhC.NU$佢T.Pyʛ{mr;Ņ3K(1ST%xV# 6zzu!-훲U=Z̰n] A" c'$,0nG.ZbF$_r8D0Zh;v`^"4G4HqqVJ<0X&_0"I]XNS{3}? zVBWẎh< :U*URyUd\Җ'Ga}e5Fp^]N? !5JT~T}δ+p5t9=ɬ8܋\]j Nn9w啬/#a}WWNp 5I I,9m} )`B4Dq,i?)OJN:rF" VG=V}` GI޻#`@`M=&+8NEZͳ@]]a,6kIP+O\`(¼HQ`b" Q'dJjS ! dܩ%KHp8l׍eU?"9it6eᦊ=)Q<:OZOD*P;JJ'j'JD;CWȑo?ߌ~a7$q3L`ٍvR%2]"eRdJ"ޭ0~I\%wtMI5; ?[G@5͟zדBB޷#Șr32w$AYczX2LTncE&9D! [7W^C-Gơ8hLRLjg4JGY}q Xcl- k0tR[]KH$ZB-bK܈ RS-IJ$Wʂ;0c'qDV.5Z좑wnP KrOAM؃πB ݹTb s^jD>poSZ~FOƀO/t &2bK̛B.n5J4n2ڧy+hszwE tYVnN+YXW6Rj:`UȥH¨as-ދamk A1!\!$])j{[>ܬ|۲,i_JwĐIoa0qI* jy[ eҁ=1Cպrg39 G%)yqz|NҩlˠLd ) }r}93PJTNn*[>N48K1a4C|OLu96͉& _]b'S(&-2tYP+a9e\sT?b.W ~"! /mnC$Hle Dw7K;r;!39+a~6Oʿa:U7W~ۃMgg*6zE,ȾS` Zbe^}>U!Ֆ~ȋI!66*YՔ$ԑMb4g<<wYa o]6 z0y W8 +[G9 HDKITjnV|"?9s"î{Cq@bA!GYjJ1e '9wfg`=m<3ɪeB8𬻫p-ئ *WW^y t/S")3'l'6ȴ-qR :L_FGNW)}Pd8"%?Q`8I@ j5bElPy)'v,:$F:v` ,q_h`ϑw ( CPFQ8} 0Pvmw94+3l9T6cIt5bY(ƋL >~(u9MMK$l 2xkpɺ Q [ܧ&A3F5^n(Ib44Vws~Oa5j 8ڧ[9-6N;~}BdF-qUv,pqy*i;Yo^Y9{] PxN`X]ʫ<`XC+oSag)ԩUz^%(JƑ-؆y=F𘝯?g妄ԓ[׋ ~0-TޙYh1$ U>T}{_ooi3+/EHht0Šsٗ+1WOpkbĪ\0K:jPN(7"VoT<.xm?Q S}3d^U\0j7u"G^E^^H pīcq-7ascɈX06)]||Y_0VDb?pW Otigs3189$GLc# ϲ=dЀSlc,X#˷{Er$(?"(ȉ<":ca DMssuK9ixlNU7БDm9I΀u&#+QWN\} K",8X"u)ڿ ɔڨFɉDk8Jeswf U[äXX J157mY%$Q0bǧ>0PrX\ %@iI춷/&HDLrH/ xmzr *'-r1pG hz4VnaT؇,v 1<@$86jݽȎ370 E%"_nVwL|Ǐi/ T'XGÑ Jd8),ߣU@]u7VK /@Ǒ*X[xbs|YSt|Ro 6"B$\/nјsdaF(1B`4b-DH[;Xwrvh1pqʌ4֖gpܣȲ4A-,H E=$-GTVX/ⴖ٢sY/Ps\/ъ:(DnbIs2LUXt9:%RW5]";p6/NNo=!T \T]{'k/[oz-[y~)|Qifh˖|LG8[(BD2^8:gpzfat0<1NeԦ% m K j),wօD<8G讁q`5_S? 4቏$xc}ܠ% pݭ2Y|,~16̆I@!h< \3ދ, avB(wM<3)NzozQ E|z 5%_DA]#]م W^!^U`'W;粀Fԉ~o1 ^FFMd9‚Z5Qf 8HЋ;n{aNE+Hh6!4C6^KYe|%|U??tvt- S\^k.&̃~1MbOI@SC{kyydq\֊fBw DaPtDI9Rxuh֔80& tU:|FpKe!np&Jv`$@>%2;P8@B H#ݦ],Q؀k0e>,J0g0h@G#ar1u$blw6z]6iJZA$5#&bSaώdVx]Rq] ٯ 9# 7lϕ<\sYÀԅ h&o*fd7g%3/`jt|7kO(q!YJ#/@j^f3Q\6$Y,pk{~$8|W*DJOx(;ȵ+U?%DZ H(`i/a)ח7b `0UaݛpUCt?Cm7H1PAwb ; +ܙB`Hצ 0z[:'ܱؕl/rQGqWO0kbm+r@86/!i!/B)( Ə8V&])cӐc~4!z j!ݝhJ_VP.ZøJie6bJ qdiajBl52vzOV;o f-dSK1;MNV-X ^Bad@Y%F *r_cZ ihSЌű`8z'=.W\;?GXAq,.٨-g$Ll10mEc03`z$(87]$ 4 *avK)׭Xs,Xt3 u>cN-񌶒-ف[w"[ro˒yRG]* OP =~}# RI<<{U2ם+>CsM#&)*Ś5&Y] cWқTOIЗ}Xbs]RcklE?+Mey )L@uM-ap"Փr=\XYY>%A_vfi 8 ;f%) {oۻٟ^L(sb!n  2E}Ӻ_Ae:D"-*N gwG{h) 4oc`(̚TL[E1c* ^@>[pa5f\b# J~q]w0{?Mev /[DtAs, y9y&/\<bU>*r g ȦiPvQѓgz, gOM%+Na<[ N⁚WWH{@dʓZ ]zےOM,4Udd/HGs3\qEzCj(H nSP$$JGPe%YG:/bjvғ̦8\Ar)~O U`kȑ'L% #I|wӓ}!V Q2BXDWm̉\Lń(QvUUZu]HE/M沍"lݒ2 uzu[˜x&iw1+z˱/$KKA(!I%-f!8-,CfMQf)^^rƱecls!2tر%OW6WfQɑN p$U=2 HLJf.0Vm6ʈ!) `>""/ye4b\%O[a;uuk.zzzq .`0Ɋ# RoNd7ʾK :&w BMC7Aef+ZLJJ\#,u;!J[vrgpKfKb(H/oᵷ5 4{X`Rm۩m)rp kDJC6*VAPNQ( AX@DxQJ )CqJR?5aihfd>AQkA|&{>%g@EBv_gM ߽iFYu+ ?∸G|<"F|#LDFV+!~FO,Þ`w5%Maݵ("Dl:' E((Y #Wa3{/ጜ|Hy{3%7v&-;t #%¯AԞSmgN9Phq݊@o?StN(1ڣy\(BTLZlRerrm"=-5zym!Bּ9^@Kn#DFe U@7pGQe?0 #teѷԟY ~ygk׏3A~:+_ii4$1ʍdR޴!qb "wRxvZeɉ=@684>.[f,_%ƞcRh=&v(|[d@N8]Mk39"Ӓ1Zƺ1g]0KihG.VĮ9۔01">W:0ъ*,rR'pe@2R"SD{VsKԳC ?s{iU޺L@.De]vXO9" y C)XfQ`7\m )|[/6Gnd>;><[XGR8s)@y%Z9RF52~G0,eRսHe@T&p p0lś6&p^; &lv 3eOG/wkm/r8H9vvxrs;&r)'5ᄬ\4oP zj#DMl>?K`ϪIlF$$]gd0KM&-з!JS ,6LJ^Eӎ]MyMK+"){s%NpNTCkawl^hb4^n<$5w w&* &z 1(G^&AE[(Ojqؐ!4'eC=)hj<"{P&Q"*x{O#J<| !mcg_~y%]~ZMM{a3xɊn[?c;d@܈x3in*IELZ5Q@t¾zͅI< t3QB^1F5dVVr]*Yn$$\AҐ )w"L h#gX^k ɇDrv߭q@0PڮMzu6)B>+ϰB!ZbP(8lcnP{&&|O1%μc˯iQE-v6yȕFrCiXonS++b?#4=j?hmwT8F@QNH@D~EyoJE Zh.c㑙Ƙc#uNޮh өŵ%ZD Z`$eU<͛˚Fq1'4-cP4Fkqƹr GbJ.\pl ]hm;AF8Rx"oXL /dF _no&E7lDq<ٚ Jo]ᶉ)H):&Jt`:] (aUǡTsjoznPF WIff&Sn.NaE8W`zJB!3"CI$Büj.(.rgc\rPVDhҪ{H5v6*.bc eט"XoUrWlFK~ 9}D!ҰrsF4%ts Y6_q0MPevcv*,%_1qتִ`RnQSPH0JS@ayʁumc3S`I S* v2%_TEE]#eS'73ww?a^Fp7ȾeF =H0:1 Ne@643[̈vAMbVZqM|Xl.A&bl@94%z+8_8KFrͶ iշmPISmTx岷!5=h`"i!;Zji?ɼs>W⿮iH2|Q|;Jw+n~7z9} 7֥/HT,4(׸%+e)>aMs˻|rwj* ykeE0 -Ή bRY6ͩ"ݲ[|`'C$IjE nCW?lB@N)t:ҩWKTM=Yberj< ;>&AdI Kw\kퟨh ߐ-"P"-H}3Nq"0Y$6_go ;I l $!;gY XKYDh¦_0_u:DFb?lb͓8#|] 8 *\ےqR;[n.w/3xe@ Tyk\l:eu Gll \4*ܽ$Jf5Ac4&cu+jN!U}[G7=C Ň[5t#e|aVzDGADըRvGs14J^NYnƉ@Л~`wFyUޱ]@w?H) &91LJbpRj(FZVa3Ş).&r䜟ѩik20E2lr~QHOb)z:p.1n#I*:I:VF}f0LTݝl,`}h!LJ7'aES&22ceL`Wb2}y'?.Vw@!sqWORYMc̙+>o\+hP3oNYf34bY V"By6D4oJX&4n 6J^jLo6{5o38:z6*%R(=1ib81/6ۜX#yX.D02wN0.$S$bf+:6Ǿ˿yA$s?Kbysq* ÀKeI 7TyTH6VeL48Vj3Kаd5[ĩB( _tIS)L5wH|o2Ua>v;a^fx*y9h&U&:Ȼ &”Zbu< 6Oo<э=Qjw aEwdl! [tB4ןAI!1 e qCn ΀X̔=8Bbd?&m"]+X$R0鍍6lv*G{iyJ>&w)􏌭LENd<͚|3Vps{l) n$XE` D0<7_43k\IU+BUvT_9-@wV,{;dFjb_k%b!9[aN˜j64`;2:W.0j%29X̼Uo%&K}ҧ;ڄppZLOuֆ*?F7D06`G5'WpL uSt_Ƥ{SSEL}$xǩf޲ ):>HaWq;-t- e❋zyEl\v.tHf!.\ gvE'X}orMR%v.H;>-6/^qM0_1HnDgx{#0 xʮ_GEM_tBغ:A/d .Fu. ɤYpoKL B$jT > _Q'ƒZ'=qkR*a1'?xF/SצTStgYqCG#3~&qX'1_d7T=?;^f9=yUlvZYVs#%?p:vt`=W8ha89OSޤ/.<)ETZ9k@䲞HUwDxRWRO}a,</=|J4L Ns T$|dY "@|= X?5,wHGRI~lfqHSL,OLb"$b&lZ{t-;NM[\P69KYluI-.;O3K"nj*#fA\s|§(]1\[QY}1%*]8@CHW RaMV&X0{-II>~'1n(Lbb%-7Ӣw=1LaVQFi" _ Pl+=uN9mO;!U*j 0O֚Ѡ:jAL5*|^S[ 0έ=a3=ʌ9$|b5Op)kKs]OZ1MGmTSN۩ű7j-ܦ(SBG#?F$ذܱ, p]~^79z\R8ws7v;ΖČ\a TݻojwXAͣX$OF6D^cQzGd>.CBFCB9Vs2%\_M ȝ"-L pۓ+cm\.gօO Ab)U _Aۭn:82 -F у#h0b.H$5c\8dh O֘EI z}:?5"=Bp71-Aȯp 0WbNllvAW*vh]1UZl̟JEy==@m 3,Og cb}o8[ݔx݋ si/!_'ߠOHm#Z)~(ko :M$~&\,Hy\⯎T4@+. k N -zؽ@*E#x7zX{e ?mn)f!l 0ȰS燆](nj%Ru&4agUkNy6 hxd1fK6i%=W]ۨG}kU[XZHǙ"7Ԇ M?=-MHF*<7 koyC 6HE_xQHLa̟09F}g$ e :=6'D/1Qi&3H-IjDe1O`ww|hzBtnsC+|.H:{Qhlkޝ#@p#@$# )㎄*PviqqĜ ?xĜY*-IYҞؿi?7d$42I47R"ne!:;f zӍ$7+o񐁰d&E5O>v;9 &] V;~"u&AWCe(P=K k,!o|E#g.e_BN 98')\n@]߆Vc^0ɢ!xB3~xuQ2 횊:Xo>^Υ1^zVv*idE|t(L^j(e;wW4D,R Ț--97NEC5&윗6^f:YFۀ3\^#P8R!{e^I O&P9uP|]܉p˧ +9v<{ 歈$tXt"`YjlЯ)_hŇ~Jp WCc)IV;) eם ̤"$?V[F>& ЍrrdbQ/g3Z|z#L 0nݶ>~ -ZaqLj@#QtpBn"$F!8@:8REFs}FoF&UBy ^:f3? !*OKSIW&D2edfve$ɋ7[C pC3߹q5󚽎Iߟ+H BOP r1]u+_lTa=DEOIۓW(@9Dg#O_= `f˗}5uskN4ݙ ElwWm S6U/YZ,ZfJYb$[ 1#뮩V{)v8cIZOVk|rŤ'} 6~9i{P*.-ݺSB͘(NHSN0e4nhkz-Wk/GaB5[q%fs %z${zV4Q1I84FޡMy 4SuRYb |Rįp(PlL%A<wRJP07 m9'S!mB>0b^`(qI` zҩ.^ٝp3@eDælO%",%T C'Cs4ǔC?`ug*4hOU٣]{M0]Fpʩ'קVb*8~}xz\s*VS&Gкj],#k l0rE:Pc)$r/*y^N[񁹚$ m63/AV]] U3~C3ۚ:z .=^y=<_$"=Iu 637b i`y_^%88ڗ帤~ֽ s 슠 ɧơ9 $'m6unj3/OQotMZ*$@fŋ۟wo06ݩ܂poMI'q pͫ 0' |]91kd&mx8f= E~Hh~$<ψ6$`QjJW_]}NN\<5{ prhtq!$?ZWOOJ_C b>-b1)Yngn}iWe+_wRlp- z4|%EyFϰ;Pn)|/jS|47:[ n9mlL_'.*el#v؞S$,6m*N-axp`XUE&wn"V7vGS? (TB&ar,o@/Vnd55@:5hO؞Q$D"~Zd6ir9ĮgZC B ڃ5i='!'sDk9%$^|SCIEѝ~SIϐI5N(JDTrRs7}X1N~ AqB*ok]fvC~K>؋8l_\2{jćۘ9)6pV(s62ngLg+@K!Y810Ex/c RۻPvQfmq`!^=W*&cnˊ{x42?kr>`?nk>͎= rӜ~{va~lM `HU&rlkvRE=׻hIeklvX}{L$u3NYG\8Lf#X:RF#ZPSӚŦJF1v`z:5> <-. oe4o)Ŕ6A3⨔}q w%Iɤe܎ؕE9,"X!X8#ī] L۵u')j1DaZK摳/whE yh*T%}(d,/" D6IBaHͤb֔s`JjgG…G_) ,` ib )D:ի0X͟3f,|pL(z2v3gvpT!F!weK3&MeoKfsixX%#bv7&C'67kZ[cT2E߲¾7 V]Uim=9>t?Y[olΞEbSa{&z͸y'\UЮ=+OeA4E  ;Tj33\`E,D84Uշ&rJJiJrQz+%@Úr-9M+}!Jpo#D AwLǟL¤߼澽.P>8G90GW2u+V&-o/hC=&|I !HUa")\7OCWb(J((7ڱP*4b$ tg7z2Gb-5X-Z'p`uKzO:>@L& 7i "f"czifDa*zϖU &`[tΜoASl`bR)1זAt W=xg*QY@pnN)ϖ\` g2TB> HBaЦ`Nђn**!ST42HPj@P2 1j! 42 GXU ? UF ˮY`:1:б[:@uyA-fzsv}*ssۆ*;.o\"-gl3 ?2Qߴu0 1%}ϼTf\YatCDu7+>FGJ=<EAFO!ti !RdSDZph#6]gZN.qBaċrQ!kbq"#c_5ki ;z>qؾ/{`GaSr]xąb-zB3դi"U,$<-j!>fMeq06lL Hӛ6A(E wƇ f>qD (r[C6FI.'R},yj/8$pi̶=w*<cZ`fQx VE(%;Nٻ,|e.r;6L^"{#-neҠp;ަnQ"_ci;~Zd@>0"]YSQ"Z;^twɻ@BH Dp7:ZT,! jzi3q0麫15 9!fjV~(DqiOOBqG *_j2d0:[ޖAOd,"zv2ԷUU Whi *Kf_~ס%=s mb .)S2538C^f1 T+r2Q?@%,07zoWmGS;< :|euÈ3zfv=Kx53s-YY氽\LDAJց /D: ԢnJ+{  a \wOdxBaqYv(oޭ4@]nA'*7YN ReL3'q|9盛 kK{? !eNCjTYpGy(q?Vy ~')M?BL"NJl5 >ag hG|y_pjig/upy:8َk!4&ɿ]_nQ[}3 ]?|ag༅43ȊKuѺXܭlu]QXf,\j$+Ϻ>hF3"[!![ {"f#`]R^Ku(2-o|S٦K"4̩q2m;ڀ|?+$ E CGYkٖ6/_csti8ʽM6HA#ؑtYL}aFI-PO~r[1nlƠһx6,z *Tr閬iB%h * 2'*ۨK(0M՗[1A?^AufY,MȄlwStyh*P~‰N2Q?AO Q#tM˃'3P|7`0GCO~?+WՉhoD]6s[X7(QQg~B& Zr-25O€ýA r82]}jj3u55/J1TL~aGsHz!Iv"֦F`Z6l; Bd\51>2(\3$79o.?LX8;æu%s);Nʤ{ԛ0[Z!Nxd cЅ-ƽM g }qZ2m{?P&t0Tm AIᓭԬV8B^zao*/oFg__qyw+V[#Y'pW;-6GU>ӆLtmq͓ s;d[b,b& ]5iNu8f"[7 xuxG*nG;bQ=1C;ݥ&Yq*Rh& 'T`0"'Gvۚ<h^ sLTJs)C|1j l!´2m*V*Uĵ{M>"UQr N96$gL*U: ]\TW/k#qpd'bA[ΨAe]"J^J@sD<>QQTZ=8]"5M@)cwUIŖv͍OZQlf--?پA dDMqf6 VMuҺݑq:e6UvW1(z֪2\6*]NXjn[)WgL,l Qjly.䬲JS h)xYdgC>Z4Eig%18 &5Kw%8Ѓcoċm<1=Fyށ_%|=EOD[rZA抄86{ |-k@Uj3p$vG|m:W];wvNW+k|F~"@ u.jsvSvQ7nQ&h{s{"UPkGE%3kQVqg$DWԖ`>&~ 8<`ɮI)@# 2өN?}^ʬ,hB l 4L8<z \:vZdǒ  ߔ)gG b$tr~6S1h\%h&^]_q8z#ۨz`gP QW nH]fNt ՜]>ՂԎOQ.S&?G˪rߪ67zH^v,]/UUOc7{V2 yh4 ӥ8 ʌM%A3LVX* ![[A]&m^[$b!ZV ]D oT$\Rm5U򊍮)A^`{ġXk"Ϛ:N8AXfI',jͻd$I/ZQa ;W22coU\QejC] X #CaY3IҼg'ė%e}OuD zIJl'~i:){5T1٭uu*2OׁNAXT_*Lfgk7V[%?`4p @qjުDsg¥o$  BXG:kέR3P,~j?-@σaUef'3='G/(Xeb%*05Yŭ$:r/fbqA|,P!5ƂmRS3$ތ4^Uw/5[sJ06PRLP_8ǹ #buhfҐ(yqU)Q ?k2CYJ4F! 4a1STg9@B%lfnzzS f縩!jj!ɰA,Z:+:l8eY>O_]8;EL~HmRFa9=Y*oݓ w.۰ w}Uh&0P,KF7ooy}MuUdp W֖a9lU'ɠ|5&k`B2՟TEnA`KHf>2rpT9f`T(hvyǭX\ʗ7CީCh$eD}n'#9c'VLeĖB۶KqYu(|2l&k>{2lEmt'H>Ɵmkr*Th+͓*iw{]]m5p6%JT"!ѲK xȮdj4`0zWy\ゕ*7>OToo\|| >p mJ~[ي ~!LLJgrl15^w ]kQ۟/<ݳ{gbR\3Y`.|a_]P]]iЪDY::QDTq'ef O$ȩ j-߇uZm]F7H $ڥ~5M~{&JASXٛ ;U2=&s ,̤]r9 JkT f5'gLςSUpgdnm~A# Lb /s#p2fCc44@7^Td$)f'Nbu"nC?k ᡹k ۡHf`Fj7M1*@XBbpolLT=w,-fԳh/tdj|DSޙ]^TfuHEw-2 ZQoݹ#р>|E^sRM:8spb\]ր`]*\IW8nنnὢ*֠ Ga)qLߏf:.XH>1Le|]tIȎHbmaq(˩={0Z6Y%uF<[ i{ڀ[P>%#;^0i`֣yES;L bxϗɆG+AO0?*Au%`:]q *#hT9y|b _w/L~J>ב}^ E"d$t[?!FwT$ H@CTٱA]Xs^^)ƌ8eDb{'Iux>qk[f cMgu(jԌ\{TC!]w)oJ$2RF GVwgp⾫SyPJr!6( 5brSdѝQZB>!=%VpV)$jO<ʹwA`d/;h}gAYO<$7 oKz1UE 7~J}u] ç"[6֕F^ v2]}Ҧ{T SiOXMhr'8}, 6$U/Ijqf0?-FXzZ%m/ӣcs}|<6Ŝpk=/:xzpv9%Kn?E&}B,^!Xy#^8NwzxEg]j/̼GVcFRHm,%,Yk23WS)ufGJ[D,g6S%cJG8"л$sc^~Lb i_\IB:sKX̓՝@2S)%7`d26f0X`ϰdzfj֍)R\;'dl[Çⱌ(=#縉]uoi0۴Jxm:F7y_HkphI >>D^GD NakՅըTvC"FE;?e,_{֬ǎ1Ix4;f:QwvU)O9+@" Mn?֦Ƌ$X0qry7#!|Y`b%ҍ_./uʏ}d?; Qdc ?Yzc$`֏,u %m8NU~=2#,Z:.&?D~7eV)KVF>U12U!PܟuCN(ITC^)XlC 3([TcLSSwL51!ǙVlnn@)/$]q_4>]:{q"ӣ⮷ fbi{S3&JWOY_C5_nbUq3Z{A7s[|d8&u5ѹkFLVI%U#? ܇ɇ/9Ӟ}937E 8Ϣr&I>NY Eg*$9ęH0myZ`vϕ o2yx" ꦈ`GT ;sOT|PfJdeOb!;fCpza6=OHi 6ۚe0MDEP&񨋡)I Z笼yxC ^$(⛛4KY2NP;e}!9n{VvHLqy00'+!~Ma20R.18l8浽YxQ DGhp4feCAٖn)CqQ7COMSB%[<1gX9k^bw{.Ub\vګ!sm%jq@ gF ho0Nj϶L1lsP|+\~ӿN-j-J)afq7Ɣ'NZAwuf6}W;t؎̒ssf`6ࡒAA?' L?_?O ܴyQEܹ^-A#bAl'Xlf!RĎ Xa5%<^\g̒*ULz6kǪX׾In}`@4DZR,Tj4,{X~/qE6"PI-ݾ߃w,[Jni)518Ӥ.A8I̍l.]_bXth֫B!9JǍnt(4 WO7k0S@W`xh.|sYFiMxSsayD(p TAWXLM.DF޲tp.F dZ^إD"T f[nu%}<t̽=!V5?cӳ#v֙ʺy'htBCM*jg8-< hEJ!jmj[!J%hnؙ3g{;S &kU]`7_)T GѩW]KWBAQ_$1ǒS-`F+F=-ʶ-S\pz =^!f/⣮ U4?tId\($%AW@ޫgp}H8vX>,\3{ͩlXRs^:>6Ib[-'_| E2hO q\IvbAa$SO(VXf !3HCz>;wLH[v UXrpPa!]<ߌB}~3OB>Pyr2kt ={: 9P S[,vd_|1`/6!HW<6f? go\h`1~ GC51Tɯ/eQq*/NYLIT@AZ](jh`=4_Il7޼TlM2c@V5_3;} ֍W1 D"( 9po]=õ`aq(E6XؽHlWk-i[vBQ m,(4.,ܒg)p' J:L5Ie@U*q8NIgR}K+Ɠ`~uKUY ETl_oO hiuuUqGtY9)fSEfO-q 2w2K⩐w sc4q2-D*|&$R2VAYd?rc[K ui%s;?ծw5w~GM֖S?9̼pv(ADo}mvZ *𒏻åZ!to\jmض;~GZi ?#dz ,x}K ݣ1߈ΒR M槓,cw7A ?=jL5qsp୉$NͺKs}ďmŎKQucZ>V8m N ]?*nґ&M⍧A9\ B óжxK3탟u xl?l' a܋~||K+Rz4+tC ^G"}EG`5Qþ.bABʇ8> }tG#HFǐ@v™vXパ$?IVH0*O+i٪Y>(7*J"?L!*~U;M b3t6d|"Ts i7aӗPn BI65@ftcscUU,/x;gafIvI F f.)FgQx;K]Ey8 ,t uL&7n~@Qw8;&2*lNpebT=qd&kk:yxMQ_HSQw6oR4Ndw4, Cּ3i.ՃJ(EYJ"B ouy8|?gq)++wmqyueEl=5!? ΃BF }`Rmhj7ucjX h0/vy=^{'%2cDʔ9UJK$Ф&ᎀF5ް/"pQ7WY#)F )R<2he'38+ .sZOSw&Sme޽X#zµܙukG&K 5X$CQj?( AIXfB_sXB9(a;$c[bwB|Z"^(I15dǐ8ocX01-B u,S28@#qH\kU4GаG]g,t _!t(Vd@oA?Yrvb҃l]mINڐGnxhKu}HÁ4F>I "M,a Lpěe}R$}bѭ* G xStC`+f.R }rG[TndnWg86,87ʊ63szɜRq]Qs֝񄤺jAϵ1$ [Jj۔ NxT1iz>7nkSH)y"H5_R*<šugaSHp8#y'!Y>"(>@( Vl;=3/O aIUuU\_U@}9?Pe7 V8\y =rP֗os`j-a!o%w~7Oe3Cr.UKk&7yNMx;5!qDۉ7'1>`DEjkx;ĵk¹2Xzx;s2#d5F[ֈ`Ɍ>10+x;uk2#f5F*Lnzxkj0X/i,#6mxkj08i,kwxsͼ#3 xs)f]M&2J0MNblQ=1%8h8C&=.6Jxs)f]M&2^Q=1%8h8C&a : x{ŹsBĉrIũ 5 E9yEy%D^~`qQ2\pŘ '/ekJ5D% 5/6dF&ɒL84|Kr*571?adQR,h&IxʹsC;#FF͓@YRx{9s$#匮, z\ mQ4#xycBĉFN\Ψ Z{jDxcBƉ|,XxycBĉF϶la4fYyxycBĉ5oa4fCIxcBĉrIũ 5 E9y nFfAL$/NI-xY% 5/VG!1%8HG1cs"3 lVx{c+foFyf lx{cu̜W 'f/H+.(  j/x{qc:WCx{qcj47`GxqcB/[Qi^IfƩDxNIQ(J-)QPO-IևҔj [jxʲQǂQ$Ek~VĿ=;B0xke9໌۳>;b^x&V`2Ѓ5bLNWBΓLs!Px&Vn>Ί ?r Ż?Ls!Q&GxkeyQdfْ^xڳ:v۬cc';x%,~-JIZ:a!W!gNxtiC8#>xRMk@=[G$%&T)vMPX]#+'"Կ+N9efDg_X,VbpFrsHD )DE)0rJͳ%!4%{K%Jq#YZ,ud3Q/\7QxM?l-۶7O)ЀD g6{ fF#F<8 +{Q(=VTn{ P!HM^vmז;@YVVl9A]inbǞ?8rGS;wC&:"eUnq\0h/SKIg%# oDv/Я&vNm'E?$Ղ+V hw%Kc-b%)1 &]Ψ"d0x{ϾmBjVbRRjQ^~Qf~qQ~n~J|rbA^jQ6BL5 : @js,#9ghy.S#"`xömBD ECdĂbԢ.]# sm q#kfc#(xömBD E#dĂbԢ.]#Ssm q# kfc#SqxöuBD 5dĂbԢ.]#S#Km09Qi1=u.]N w  vPr-*/R T(J-+N2'3iUN~$1S.J-.)QUеbg^YbNf ȸԼbVEa.NUY(pƃU+VUUpNS/QHWH̫,KWHL/-QH9.? ZLK@Tx[źu"CKm#SÅ5_sxUmk00jvv.AX BPKŖ !;Ɏ:0I{ѽw<7LP~/;:9"eHg2k|߇N2{9.=yv-u +?KnG Gw nnZxi_B*{%?ᘋ^,H XIf k=*JO5]pdK>h҂F*©9S3 g8>) ?`3rk O:r *^Bz2,^5-TvO5,# &tb v -̲VrJ3g%-!m(yOL* (|\xR%qma(YN>OuV㴈'gjeTU-S(,[eY+p[+e51ݪYJ.avK.3\6AHL^ Ĝ*'1 .߱nQUbk4PGr̝:" ׽p"WȔ>қl=4䪔Ul@?e aZKBC%"OX4[P.m]0Ę?VYx\WWWA?%L?4'K[[[!5+1))(EH@@(Y?7/831>9?,D/(gu $&ocdTl Y0fcx 3 œE6@ l.xgŎDx+h~w!&Koދb&Gw"DdN,1bs9 ,+l0X2x o3/nPʨ 'O\L`>(ƑA ⨻1,tqN3БSd@,-#%PXr0xGh60& #>c2\+kő Y#1;2c( "ɼ5E0廱P`c$/V*AȻ7|Qaٹv7FiS7׋1Z&#`F`\ini}XKv15 AN[TPNhf`أ,)m;P(+zA )ۀM+Z|yB)c7uz +l1 *]OxΘM"u>S+fZ of 6 #p<^OYg\#HøX9ć@SMJkVPC< e/5%N~U{#C . $(tr A*n&XԳ3 $MPBk3J(F33cK(11h/^,-/azSr F!)X3t%Q8afR6u,rllxh &VJ3NLQ`*Oۄ>IA^?j.XJh=~#e@FfHU(#83}7r*k®GWc>9"4|֊j,8p;dߣ158cE889l"*D3_7GH=/bjJ NAhYGh%tg q0On~͝ϳiQwxg.|v ?NBzXsy0Ql 1h|9B$,A: @,1C BU欶';gx8d?'ܭWNrVƦWNJ#^m}+3D?a>MGfq`SʷNqo=2O8dzZFS?_ךa>Goib/5zܥbé=}8b5r2*ɕ=<9>۽Sf!o!!|9jpvFJҪ*vЂ*<ԫ|prˡhghlHX2@LE2!KnR,B(`Yv=0a0}ƽQ( _f_ h Y`X 0#JK ܔx$K3soVT%f U<A1Q49B2(dȊ|(ožRMⷙKN!{;&R.g4/s r*4OT(Ghg[j?gJAm*i<@jȬ6.qw,@P%UX¼z\aGݲ~,DJ0 Ptu}_D&S̋w*..u)uwɺ OE$G _('Mm'3XX%} ]>9Rq?ܝ+$cF:0,keB-b_P.db-$0Cǚ#|G'[A3Wn]{Sz"i @$k܌QY }Y=7zfgg'pZLXbLnWxDZeIrWm;,=d:2KuWѲڋPL9&]HwREU~vځJG6N`<ۀ^omҩ^DX$a\ΉG- /,u*YwCRVz 찯Qk ~256 V+Qzp/?oςs-@iކr@c/Uz"22RZK;EyuxGHg§ŷb۾!i> uSXhoﶤ}8 YsܪQVE)kA;ٕ'3k$5['lQ4_cR'Wm8-yo#^O7ŗt0Pw $]0b {&|mI1.=hp}oO]#L~ TVEH$t4))'?m:j#K;/3'|GQa gj\ &ngs$q>5i7NC:ĠesAg]T'&kmjb}T]?Fv2Z=;>CzR/.3N3pP"0Fo,r?p~Ee=zOh,{@>N6@ jeTaO?*&m04Iosmڠ,%+L׬h]4ܴIqtTmr~V[ <ߑg/S# >z RM3 s*kAKR$t-Zp&I>MNHX-pTkYu z T*m.:jWېۤoqPeS{=ruЮ-%Fs_AvpvqޜUQX4פF>^ 3{lL!G]ؖLv}8Lmy.{xORÖ䍕t~ؠrP8 W m`'i^hрJÁTƜ[@1i@zRz@g(i!&va'_D?E#."Ԏ0sʼMX64zwu.Cʼ?8"GN,X?ơI9unYt[woS,>^{Euր᡹EMBʓ#Mvr&[ !U:֖Ku+z[뭄853L$ofIwv8 u/jZݞ4Tf!LM)')qJ ]`ddch 7Gs1z>i&7ۛ0NifcmlfYY YD޼UA>W%$@HlEd[g.#rS˒R="d x]>;|S 7*nfL>)2d?N>\`>1 >f2o_b7aN-7on *+0PLB4&2xuRMhAfMQIckJoE̡xPȡ)5`add&n&m!ē9xT GzWAI {wdYx۬ױgY%hMrjo[X!x?$I))B eM2HB?xHˏR=Ԅ8$4;nv;I˵B bD3*U5075o)_rc]zb.W*#3q@z"j<coY6v;9`=8r(vXs̀ ɶBJPʗˡ C }R%&k&1ܰ!Oş>L,qgaa:rq#n`u1'y!PP`Sq= @M^.|)#Q67>RdP? dQ\wg]Cp{q TmeOjAX=E9~+C?KOJv-caz1΂=]/f+BxVMl%)eX)^z+wIXvՐ",!6K.e ,AO-rȴP%%A 6HQ$REK.VPܝyޛݮg;: 'kj cS)q\gJ,ITv\,Ꚗ) OkȈe(ȺYQF%ohH`:*i`ٶO<l7eÎ3puuߦ~WOSڀi("kPQ}@rꄛ RڎOkHm9MDCk3~u ggp$z}}=41'/ roVl{~H@WU}W" };,s"=~|BGݲu,I5۶c{%~{/ ShW%T:5V`O!JH* %- vj&!~a ѷ?:zttl.6_ UUtI*4R~(7[O%Dtn*@CkZq ݠW61ۆmZw{^k\ⶭPcUTz6 mڎۈd V9vnlm)ŢQC],%ism3yy5Ŀ9V DlT4< |vdJgL 5[SeO|F ͼ4s5"W:ͭf ls},|.F+H+1liTbw3W VUt"9X:Ԍ&pZ9~l:uulC{zd -;-u];)`~a{v jM/6EdVG'g2Mfpsv+{9KPxsOI37yqQ·8/2pW"3}8 ӛ͸8 -\0;k&MIkLEVEU!:kvj1YHFXP9Qm!MxXoV$D jH hZyVh _hQ4Hza, ,b1d؇QAdk١uCBUuMcmHBֶxy9|Cd(Dq,Q?D })ӐqQj[+=(O$[}uG7/MMjmH [ls2tHQ,P|,HW}+D&{L3^ѷ2%v+kUW5YTBUkت~iz©p5ݬt'j1B.¶T#TlYvM7!fьiGCŜD;8gϮ|AGyUxprpWFsuUUU@o~JfZfjBRc^JGbQcFnbcR~.H! G//8Q/=7$_<([<$C!5+1))(EH@πKRLb7,da9ɕt2,f:ƛ=m2R l KSKS'WqC&͵H]dfltm^2XL֕&Dl3/sqqdCqB% M6ed2ج-k L:Zbx=kw۶_6TL9U86v\޳-6cTI*WQ~#=릶 f`0ϓ|?Mxz*Iap6_:NfE5bknwnO~ mvB.|/}@2wkx<b(<'~MI0gYt>dؿa|_d:q[pQ4J&+G&)É|0Z?va ps]= Un=]>~b/Eij((偨Eap3)|&8,%mO&9ʤi"5A b'a!'QWoqzu= hIg?"P}l7=oķ_T6:xP =+&/^ UpzrQ,TgOsl*zB:MYֶ 7삆& j9l cU5a6PPr{-q6O|#CU1ja(bkn{WN.lpl^(14{ШĐ ܒ?ikpxyd_sMpkD)$Wjy8:.!ҥ/*x&abQ GW!jjR B4Up? NQd$MAđrj} /:Xg" fpac_~. /Ű|g|PfƣyM9i%nCAT>sz0c|I@WW괚uВ))ITkL} T$TR!#ۗ黉hjQH[`D x9xMP֣ix)(YζZqu^(4嚁^\hź`Y@c9b!55jp;! MNd8o_IeA3ls<&S|(x j&7+1g!l7oqII_2#%ײp-V /z{--tEbT3S6Ü?/2nnnG`u0Z Ro9p0D i4z{%$y[ǠP|M߹26)$JIցЯ"qr)eYϥv[9[ɺ-<*.-3 j-#4Waf҅Ui ~eM.N:1=ښ(4<'0L6 mǙ9pOkkx0+JfQB*ڏKj >K@ݺՄAŅg]RL£`z<>n@w3*BSFm>dkdQA&G 1{՚ބ&عϤ JV.Xs C`4Ibrc;J%yt2دQlGZF%"ga&Nbŭ][w[6Lo1L| 3Փ8kKhv_6}$ ;fT٩vʻ=EP[ݼP2a;l‚`&ƠZؽގQ}ڐ'sfOg9aڂSxY[HD8 A+QA@({­?߆krw1%(-Hu]7l=˩|3 S4νwJ8_{nn@ !`WY[%)*:3Cmߠ?1it٧ɅBIWt)ZF.)*GY ]^̥ͣ~,>48ګzӏlXW*y[4S}Vy)U#80KsE oE:8?1f"G2I)L vxDNj!TaO\Z6>,O/p}G 9eNֿâ,˯N' Q $v4{K>?!bu`|Ì/(9pl5yͭM4AkJ˦NgWt*\JqM^kqP8DGUR}8 wv^:8t(ϖˉk#ޛ%pnD Z`O` {p2Ў hff ,bA"kbqɲCк*;Xp[zSKQ7NPr(v::[GtO`*)qH"7Mצe¿:3,`2Kqg^Gޥ _/\w#oe31\=IV1Ig {sC'kwA"վcIk}q4Pk'dtt!Pw%؃ݍ^ybqy`rq9xӞZ֧쯺,!Q }36 iWjj 5^1sıfÃ^,3 T!$ 5K?T6#u׽O /„J_udvs)Ƴ3дb]=QT񎞫pf"ma]tU+3p)V`Tւ4DF:Jw$y jĹйz?ᶏbyr{<+<ĕ_Y}N<5cs=譠&WȐ}Tzr5:tn 8 w=w2' 91hC籁wBԨ'kPku0ACgݫb"%J<̠qX9'nb:5$`.Y$PW#j7ʅb_yv-۱yg8&N2x ^`fbUcoXD,ztT3z~}g7o^M! kFO诂_Z`$Ѯ錖bSjM|:~f: |x WzVlc  T8XA4,pgtx"GuIkmE>: =.g|E-sKiT›Z U.NӉh0g{q 嵏kGDi O+Eٷ$ܕ,}buԚ=u$|Cwi77/=*WP:Ն@c:Rêx zO0 U=ugZ?;ɋ љ0x?Lw(lLY9|ӗQr|cmljrq/N=.r?s/ $.4 ɿEgE""_V5=e*Ow>t,˱Е$ݡ o-<}y4=a"U]H(&ujLA5Q6ŢjփuN7_b|pu]srUC]ẞ9SCI KDGt,{~~N 5j7~_lZHMI^@r3 Y۲ q۶ZGY(K+ԵLkMGO 6FeCwo*tJ<<&s|.Ĵ2`OGq|u{%5f.).Yb$U=ϥ-|3_JmBo۳K) I#p=&uhݡu[IST"GX+ʷFح!C 0"^tStG.:n fsjObp"Q޵gSC׈<ģpp%G̫D.4^2ӊ-[F\Qg`IN:R%ƤevYj0hdM+[%&z$sֲ&-ˍe>? C;=9j0I,%7jvCh6eCO\E*Jq.xyxBjVbRRjQ^~Qf~qQ>L\/K[[M!+OI-+ir .|F?2X`rF!܍z9!s \ڜ _PW_P_Y\0YO'QH9ִIWhy@;`r{D9@&?`ߜ5(9 Hu$۰Rϳd\f  Xq/PMp%#bj&x9mhIv-{za4Uk<3%{lٖoK,LfZw͎' lqr!%,!ȑ]H G{csMBޫI{DկwzU5U1'9f-ÙT&f1h5LJLJ3,3ˤsS'F3c 6ΤӝCCC^XJժM|t*;v2͌%sHZcCgu2mEk|wQ~>s] ][9ڛɍdS#LLlZ%2Hxt0OmsV|z,8Cge2Edshxٯ`l8ۤ&;?0XV[=ԫ[|_LgJW`j-)sw7PGmB[׺eEeԂeoozQ Yhm,.,8vBx~?UN 'Y~`yDCf;I|VrLvxqǽHQJD7w p\+HN°as/V~ lZIB5h1XKx X Qe;Xa.bHVÄԎzOR< X1lG~+TK/;zg|3~?3dؾXؠm%s+s-5>~F% ^j7hCܜchwPqR_&&8ZqzyݚMeYa0@Wn6mSTx=^yY򕮳.twʬw19n=^@6i b=C#٪M |=v'63s_)?IvPMx#[hp'3W6<ʶЙ}GNn~>C@u)s|?:Д%A0֐30`?@F|[(,S' Vn`8b˯_*&Pv%"drUH!B*+@lʮ#ii,[޲VVV0TiӪe?JQ.P ?#j8 \`h A)ifbb{f(÷L``Eئ$=>(l/XXXr{<}lF3#O'cP_L6>|nO,َc|ts}d-g 2 |>=1ggf'Oz 66O޼wqb(_m˵A ~Y lGRɃpN~= q𬢍e2yXO0_oC9ldߝ8TM7;ucѿ(Ӗ0|F—`Z3GAqv&>E^={XBYUIGgI613HճoiMaN]Eަw/`qiO##FIb{.RR4?Ϳskbٯ!{yC-.ڦ߲ KkI)72ywXo_( E2W.^o֪Z4Wo?Q.sѥA`3J'ȂHI)^z kw9-4I+IXQª[8QwN^6~Yצ.jSw5m„LAVb7'ϬUG\X: _BEn^{VCk;| NY!IHBI {Lu¢/Z71FQmr>)*q@ۊB4!3 :׎/پ96lb³£U'tyg.Į@1&o]hаiA@01.P:Y3Whǚf#@]XT'mH"H8^D%DP u8VVEcoEA&}42O߆R!.t5" s,n'XS8SiJ=W5ڣY:'t+*DRvkNpb%{`V~8KMq<ңQHc-`;Af[` @7|z L4DҺע{,ZW]tܼ 58/*ēd4IH-&yE'5 @cR. (:v^PCv*&=LgHb+%!%ƿLtm "5 yR^ Š0pc)B1Ps"P뫨R * ]JAL92UjBLWXC#ʭdwh/T>$;D?\#ĆD\8 ="l?8{Wޞڧ2!n7oec0y[pN)X;QhZj=a9 ZxFOuܐh!2M*dIJ3CU5!2spR1p+׈#MQpS2g^*G-4y@dL-TJ4P;1ix9`ذ(xTm U7ы):ׯзjK$,gU+T/<Ǜy" b P $<5;qgqy׉PG &̛r \Z?Ut=ۨ.0}U.$aPPIjԠ7 cJk\&^y_^E! KirQTJ δ4[ggΡՊ-빵_ү(QS+m3RG&|'m@9갑kIA)9`em!d6ݑR}^y3I:tE1=Mn$݉ UhºDxϊ]U9jT2lא}ls*j:ǶƂ_+?`x<[FiVpYeHWi8/P1oxy͸BjVbRRjQ^~Qf~qQ>L\/K[[M!+OI-+ir .&bʹ) !x;68]]]ԬĤԢ]#= /L/.Jև%pikk)Tࠠknc $&11Mcv())OK٩ZW䒜ԊDԢL>Q, 8fxx--- ejabberd-2.0.1(1;1 T, info_A .&k& 0No0 >xB!BQBQxX$XY>YN,Knx{6 ̛S5}x[q F!]]]ԬĤԢ]#==BF3mf/K 1ZxTQo0~n~ũC"2ѵll0TUB(2&vd;9$xD|D+Xp^%X)-נ0OYBDK\<42\<0gJcO. Wr}`2~nC5{hpV^-kߊdFaD#`Ql@R~Pv:;9<+՘k&%p4 ˋS4jd`1H݉30׸mUop}$kj3~7yeMаӠgI z?Sx.x[}PJjrQjbqjBAQ~E\z楤VX)f%&%N/79+̖rn/eF& VFVz0m8NvS##^+#t3C@x[̽mPJjrQjbqjBAQ~E\Z0O<9k _ns3'Dx[mB;; ѫ%LPbx[mB;; ѫ%LR{xU[o0~&R tkm֋z`C5YfS;NhKojIC>|_θM`8>1 8Ti X*-G}2$Di-B7̅,,z f|C3DYY58BIb>%PZpHyVh(-[E QEfW20,0&|:Ei /\ib3Є*Wx c\7dW1/>N¨nu7m^o1&d u}ax/]Ki1~*g-jw۰݁vm] ^lk6/l Qw;q~ V7 Yvw=X_-cej&X8*ow cMcN?q"1ZF,Q9ұK?yaN1!wE&R6 9f%/ nV+r};үV."tyoY+vR=n~KdI/$/]%}W3r-:l c$M -$-B)UR*y?$T*=LD|; O狜_:RR1s<\dl>f|2B+j0HZ @s9w غrO R[!DNͥ@}+BPs :5U!7*+0UL7W>9>'1;,C-cCLCqUX c4:s,T4P >?1+[r|/b>*P7P-x'fA>+1!xgBjVbRRjQ9\ %60Ī'ExoX0 ixmJ@Ekm #mak$od$u+?b[A,'Յs9p{q2Z(5gƮ^L)'MչMO:w~6AOm~ 5冞kTi$`״cp&.#EnAp$+P\/0`R XjU5;}#!.?qĝ<fsaT`xg&#d]fɎ@>bƝA |t"K$< Cxc&#d]fFq2FJjUxɳc&#d]f ,ncmi0nJjZf^FpHok}EnBYjQqf~6|0L`W!Qxc#f>̺7J6kx1yfQxF7xmK1DƅafR@4Mpݏ\:ugZ>lV5puwr欠L\/ER$Oc>ۋrzvEr'0-I6$T"oqLe6f xb8 )fxb8/xb8V9'%X $9+2/1739>9? 3'5>'?=',5*lT[`V mWxøqBrNJbA^AbIrWJe^bnfr|r~nAfNj|N~zNjYjT)xfxxq! gJx[Ǹq" rix[˜8Gb'f$x[˜3'e4x[X1=&fCx[8Adx;8W9'%X $9 Jfx;8qfx;ĸq2f%x;8q6x;x;?%)Y $9k%[iAJbID# ւ L- i4x;qdfGx;q 2exTkO0+&Ty<-c&T4-r[jpvUMZ ͕surCT2xHG'A`?sLPJ"@ %JErcBJ Ӓ!PmLr(R |} {A_rA{R$P0uݭF#'hdY4JWiQNk9#MoʥԳ7HE}3b?+"Q$IOy04,_y>9j7sc3#9{'pPħ}{~Uv |dO»fO(B>0,}NvwYQTW:Cs?j=5J%S}Z3R850-+}R1OVP ܦOYkyG/ɔ"My;uH|zbk^[iЅ|jmc:UуEebDUYZ*Iƹ zM8#UW]S_N:A=41w[&4)LԘ&F *Z>KT,r5Cay_E۵xeBacBn~JiNByfNBqIbQBqqBfIqjNg^JjBjVbRRjQ~qQ>L(>@/(kAFY&1ՃecUid``k`k``hnedle  @y.mmmbEe`ddejhed aīSY~(>OMxijyBcBn~JiNByfNBqIbQBqqBfIqjNBFÉm:ʆEYIIE)zE9\ &&: &&|/kg4xϼ Fx3AB5-"X!(X$_<([<$C!I!18_+1/exjL odbdrEx̼yJF㉫tzo*$hhp)@IQb^qNbI\|x̼yJFtzoI n"xk`1q[:,'h,xPN0xc$ZKPQ10,ENҘve;MQ%N"@ x|w~w+>m{4kf*h*i.W`+m,–[-1Odebjt>=>Һ8A-Eh4_ߑ"!pWx0:pqM1$p$&.(k߫8ҋFتuCx}ȷÁ?6ěJ,ψYmѐU펉f;#MtpS!? 2Mz,ta^$ursq֥dZSOҨex;eBjVbRRjQeO|')&mF ux;re2xK?O="[eBZ^A>$m3>'Vޘg~j["íU*ӄ|v2pBcI׉oDLw̖j{:}?'3Ni^\ 38G|LZmRق>F\>YIGl8x;IJe(f3FFJ)kx[yC8je_c,x#4lf,jiH{BJjj1x|yčjEx˼yčmYx U@"sR3nA9 R"eDyHt"oyymi%!7Q|tmVQ",i8 Bd] 8H3<=5rj +B1k)kvZ+{+7;dTcO?p8lhx]դKv3EX NA80ӻMgI2]=9գKmx$>»uG}Q\ _VXh%@`wUzy`F5R2' -l5Jz An{p?_FRIt4b=3:a@VruVWbadQRL'2M~ ޚhuKRPbY-' DH%cW2;sa8gv&wK#(^wo28|:]=|)ŇH K6dr) >QFqo \1Jֲb 8H4vL9ێd0%s$u^E} p)]))g ~BwΨױ1.qzޑpݵY>:9 kp8ʙšKk.qYzދCO420Ƴ(\=~B j| ̉^ y?#l['2'C121KsaZIγd=].S 3߮s͘~4FZQQS]^}4gzsBDaxŻwXos$Wqqx5x;Ad&ɝ,"g*M^Ȣ2ՃOII,(ʙ5cr[EkxxŻwX xŻwFݬ7+I,K q6xŻwFݬMN`F5l x˳!qs18+27x³!qs1##^& ΢ļt̤ l0U2n`1b 5x=ƗE%% aEřy  E9yy 5 ũ) ŊqP%V 1zZ1eV.y)ŶP]Iũ v 1@Hp)#dk vv )IyYIIE)zťI%eEY/cA[Tx³gC={VbRRjQLR7jtx³gɍ/YYTxk~Ĺ7('1/]7% 5/efpi slyxkƵf&Fo5xk~)<4 8$7>5(OVAE8#5'G! ;] 859#1/=5'?]F85EA7/UX1.,83?J!FCO+FSWOK1P@]kr'UBAyJ~JjRfb~jVbRRjQB kg-VECMѝ S~jId?L,-Gg3x{Ϲ jEx{uc´'3?9[x{c´'L'3MNgG5_zx{u´''1N3}6c9{g}9#KYU G3l(}È!`fv0=050e)ct'~Y ЋA/Ћrz1'ՖW'߭niaGR@XB/>]UI0"; #,5$ g =g'r{?TO;C2,Xτ: Ǝ}3ҋ%  * qEQ0 v(f)1%@!v _1OcD9/h'By3Y4dӷ;isRV.RۓZSQ)ԟ, ̜%(A/*˴=&=$'#){H+ԥac4'E1ddIL!AiT-WW[&[ŃRHJ,FMP*׋ԛ39#QDk(S"Hs[]Ϋ]R2o%f^C%UCx{;ZPbgv*5ڤ'[_9LM;S&=vx {H*D]=(̖R <SՃ'֢lleI"&}MN$k@63ޔBYpTSlV`LaLg }B͹IO@|'gȁ#ؒ͊f@?;e }Q5,$ׂG?%FO*H[_)f%T "7wGB_fgxDR)Y N TUWn$HSdΘ2U/ CUeѤlEi fpnEXDPhcY#Y\! . %.0l] !'3 %K h~_iCYiN( :ۤLŊ3q)M84 0A)SJR\IvؕIӾ<4ŬfSTuf:! G w5? ES'*rjd$}A3@R'vQ M9̢>~ RY:I$Y$a+Y,pM vAaVԉo̖+.(':aEzH2M>Vi a:Ű;g4-3 $糍GaKVR#g٧:8RPH3DzϒP J}I88@ 8d< ͬ0@S)y:!IJ~͌44(Ôu&/,?_M_ g&'3X cec2qǛ%zf;O$5g:4?w<;b?{EƐUiK7)(EzO^-bFךBUZ/ 7K'QxLqzb=cS&/UϲI(ezOېi0)P%_i [o%?le(!ϻl YC-C3b>]! "ƒ? <.{&7'Qo#ǚd$Yn`$M<۴S! yyR]O~HwszĦR$(U |kA1+} 'tR[7"&Ѝ x;\}֩PgUu#Nl~f av,{-rxض񬑏m9IԛR7wfVƙc+wކF]WП8%1Ҳ5Ut퇚0pp<l lL:H3!!2 a80H0cQ0CF7p317 U pi&Ezm"` (x2ܜXz k " kYH_R`R:zB[ t`MBm,$sw\T8į~ /:Wp'*vcAwYt}v;֧QsUZp~odwS <b%aY7FrA^p^!"kn9ng2p {a:=RyjNǟ޽Pp2J>+|+4>>Tql6W[q}hu1Nny.lӢlWiJ>4Z[d&6DLn+~;*cح,t@OwPS:))b v3ʨ&?CibN)DmQX):`r+M殷3z|AChDa_W0Ro;,A|V')6F$XtbwTROAJL}p`p.{{^?ɹzi)ᙃ 9/wX)լJT:3 04dhT4l e$AwڹcҬĝrE+9ʃO3cwY1f9e~ӉTu1)KNZmvB,M߃) ⯇.8Z=ڶ/n֮>yo*swdYQ38X\+Ϩw&Wv&A@Ǖ IyZ歆Vl"Fr4}u(_Iw7mjbPKwZ+ۦ,k֤mwJ@196%( gL^l=}kiNOdsj c77FZ{Zv\;O}T_ _1W6;kmizTR,n _Nۭ>wyVzP1 vs1ad["|yi1irWi$s\x&+yuk>=́AlG#R5Kڶ3U#^] AkmFD]zϼ{GMN5=kjzm՘K앞f-"% QWkE2[Gyi$йL`lOCsӌ/w ={Am[oηWwfZuh*_+׈DlG1P) rG95yw7^?<&],;m30e3\3.kv)@i}mWEN<0FO[at`lCgiv2[޾}qO7Yss'vUff,qpay O8lѴ^$ZF q-Ym+K+ekx;T-V\1aO|~n S^ Jٗf}݇?JӶx/WjzrALn$&twM@Qprr[6_tW4E+xwW$xEhCbWb{Hb{Hb{ڣt9C2 QFmYF22e#@cF8pa,9H A08"o9d1ݢ=8 }LTGǀh0 `q &8B`>a 쿩["0$N I1aP0N,jyDp A4'\TK.p1X88\< Lph #0;bC@€r!@z)]fCM Zxtݍ$7:4\i˰rm.o OXJX=4QKɰZoiy#??mxQ&_jw]]]u8/ty VN`\pYTWEcLemMƢGy;.׏6h: [_'={Z2nDwvCvGݞ&1s#OHo^_^{Չ,qt3-7}:9qb7S kg|9'K/F{^l :[].AG>Bu<Khꍶ{۽v5[DʱY"U+MB_#wx:f7Pr()'hV_[5 }{]Ӗ C{ӔN~F1\ki?m|M⵴F,}O8~H]/\տ esƭ_/37(yc `uus+j:Vnjz:BQwu]C6mөH^-G+N / TIp3n{c՞Jz39{:~#Qk^۽.Ocoq41}5C\5BM[xrH2?ea:,3~P=a/C]#~1ƽDܢtxMs^tר{r-۹:WVS >ػ~/ގ}I.`<؇9Sw+;'SPAxdABk䋓yvkWX/ (s{vڷZ7Z}U;7ͼ,! ʁh{/Nktvj:u%u]pzso$[`wOten[Wr ^9K=ۋe__p^VN>*_oM`mi:*_Oq ڍU'-]ea=ڭ58dxï$i&~p7]}35b*eq?vn80p[C[fҾOh-*n e},EPV1@@,7y2ZR`sCI2{b|~H*Z%s>أvwZcٽ=LV=k|1jG^SyU[5jFӛSq-q&ڽL-?>2OLhv*ƃfw $NZ(((v1W 8 KmofI_Ou_H3-A Q:P>JUk+b`rݼG ;PY2Jo~ z}_0*^(=:@u ( 9M6K':45ܾk zzo fun6DDd܆{'u:Ɛ5`=[ v 7u|B\w βEpl"%$:?'bEf:W7i&{{ rR^(94ՈV/ I2m8o.FB-bu0ZNlK@QsɀYF՚2F b F b F bH8D p3@l 00096 Gb,c B2 fZJ.B<  d@- 8$,./2T`X<No `A-Qa80JAx` J_CQp$T(4 bPppj'̀,!'C43MA8`$Z,B>o&!@["podo,%@l7C!Qp<Ϳ@7?F¡:( 41X ћßKnxPaQ1pж,Y`)>!8$x#B) "XiY^Ԟ=7Mun{NYKtlϒw]{$K"wY4uSz"î$ٔ^תkڢEA3vEXgNxAwF`ȨdHXxLz@~+A܇l522sԌCPաK"lS5wv=ߖ݇{V?Zf?}iS$2Ulݸl%͐v :؂GN,UL?KS`S$ҟ>fc+WY|OSzlN{՚>mYY)YX~,4^c}J[R: aۂ.g}"vR!8i"S/xѳ2]P e2Q5ZpebIoni)%^Zeb 8g0GYŽ?2/ƭ6V6 :?6qRV짛0mV~ISIt?59.msYQm:i.wSvEVٛggn8A<ZP2v$ pcaF.0<޴n|N?ŊW|dK쳹ݥ8pᮿaFI o/^zb|ZsO6T +q8ǘT e 6ښV==ED9ߺ^ɣ/zj7aw Q~^-O,{l玼.,QR;%/u{tu WB:3Q!;m_zC;CG2|~>7[t!\F )o~6orK`52aMe=#b?K/z'e^s[=o u=ͼ^r~z_AsdXd-B߉;k|Qc=[D:+d _lJGp|>UVŭ5J8r#fnf=܈)7b%1XwXbK,a@,%r X#n~Fܡqpxb{x*E?X$tybVq @!1pon6G  !ȿJz)إ䴿ap,*`qHPs:7iZ <43.pՃg'@>Oo2Fv;`P-C!qP) Eᨿ"js(?&!Jef->? z!!4 ᯪɤg0@f8PFQs8?D/2,jyx 0]MoP8'y+B5{P9Rfћ0Akvh8VwA(. k ^ mMG=Ǡ/j#q7C!ОBpbhj pbkZ^xi& k+~op,DcASFT `ZOFeK!n N70ha;@ .[w CAA jGC8~KH 9NBA1b\[Ҡy#8`z[(PEPQ˥{CkZ!# ZBLĢa=~ 7PhhA͑{?[` a)3w#UM=- D},SI_;27IwiQ<ݮQx[d/5A [w]cN)Yw F5~6~{֟dyGu(vV |CGвH uaqgq`NOw^G$RwSv}y"x?lÜ9^ Cǭ$/ŵ? ,Q._ e+;׷:|.m~6!c'o'UwTlPA{gՒݝk?as">WP]Hg'BM{ψV@Ӟ2zSR4$̴>0K .>ڲ4i/mET ^IQ^2{CJ /кP&Z)Ÿe+w )s=\Ba+FQb cl^kj[jF+sY} ζ"9q/CY_{>6v{?W˅8.찅oEB\xF{u ǻ׿On(Ԙ풖2M;JmxNF67)묾}x Pٴ7[cY6ş׼3FRQ=ǬV+Vs^dy[Jk9{^ l䓚O.[Qb!2$r}Ŷ.XY>1 Dc&?:WVpo5S֞b4Ƙc6UD+߬wT,09h㝷ˤ } r1V%SƋlK>خ˃CQVÇ,ĤwV [aG3B^nyRѡvhLUЪUZ.)ZV{l/8%>̖;\,O;Q|=|?VKDF#>m`y.Mtlk՞"}U-CZ= y \ruw֝c[ků3O)Ajg*HD]WzXm PUhnyz*ڶ3h+Qбo\7^t-8-1Iin>/ڞ$ĉ,8z QshoTKNc&}4<}9[C?^ON/ؓR?,&g)!%U3?WTQ:"͎ImvMmxaۂ>8ٶMz.{>l^{҃2swמm TI^?-M?8\2quX/!TFKKSJIiVk硋[- wojZFlz9\i=-j}EQfq7+N(T0_mUAG7`Y{s]NU,?T}E\'gȰpʩf1lR[/'Rx"ŏ'R"Othd@͏&Kbɀ@,B>‹_{xE( ^+fn)$2SF0RJsHfRH N%C,0)C)3pXhe#@NoEBݢWcRrn5S:7}` X$2(,i{l\3 *VfRTչ3/`p 1yP^l%{(3e=á`(p*lpY1HVt+{l)꺻IHm;2!k ӭO6^yJ6oOԋӚ5N7zyd]wKF}F`'Ymq-s؇bJn{˃#lq6ss^\/صn?.\gϚ`Ö(SbuX*%Sw5omrmQc_d8WImkɹU'6Ul1IYu=Sg_ NO;ri/a=kuboG[aIgD6\x53Q{V&]MHvȭ~U(S%zܛ1 W4A&<]m<:A~g޳Xj97h ww[ΏkKe͎=ͮ&>x% w[+7(q"e{n3Sq'?x߉)Ep>ps4uoi !aiy_qC;HF{m.LjUlc9C8/][FNVO ür{BAXmvŋ?4 v|TQTѦ‡ txRCl+2nL.+TG}`ggzgP{Gex͎SIUS/B uե 2g\Ws?_P] E&flJθY}V =HI6Q/zU9ijjԓډbh'ƪ$c!|6(y~8Wu,B &ƣ]ܫdF=:P9xS e?0(,C<8C<,_4tmB~)hq [!nvg97JZyY NW}ZxfY؛% +;݁t!GFWg;f///5ZF|G#P: T uP:f<q 0(G`,UEy%EYVϻTEa#N>j1.Emnr uv̀w>:w{žh;c5!f_pXI=b_ܛg=?iZiv}|GF`k4q{KdGρ&ro н)G/"OZɎ`w7ƎJuߵLMZxwp~M_Lҁ ;e5  }Żr&t٭c[e%g=l)E1]S_!H+q.:SGU,s T=6ks\xM7\~qkƥ;=ɤjm+; (2YG{sVƪmaUZ7>X&ќ&N%$֞f7)Z޼wG(2Q lQZ_^e1WtiyVbhOYtܔBqfkMِH_< ;  9AР0}Fb rL^s[&\?S`OڋM@+nV81M-=O'Yj7cwtx9]E>-ᅴ6:nOõ'c%eH9-QM.b8]knm;wU)5*2z~0[:?_{J _un te-2ѻQm4|_poYc{y'kus1:6e{rr͛w4}V/Gn߹ب_Yɜ߁pEh+6o}*ϩ7[u;qfb#Qڼ밝cChJ'[ZWOԵ h@{CC96nfXBTE^nTā$ǪfSk%}sѢ|[[^D{e ,zﲞqXo&Z.c<.#lSQUAB W0ސ!3&~qn ֽc'kQ7/x1ʅx8m-3YAssr;)dn\n[C@? a%}Fo(~2w4io1Gi[nksxøvbmg}=\q"!^>˧bc0;}pL_sRbsi"R.4D<8$^e _N^{FMt5R=Ƽ0_,OJ` 2җ;R>,BqNbVpd `zqMǺ̈́h'[ .۰\Js} {QcmIl_D!wc:j׊'7eOo~ٴ7ugu[΋~2T~xܱQW+ķ<{Đ-;{ :g]iq Dʝo2RO`?;6ChsU.7IJ>rOxD˻9мu}xe͹cl۬',]~Ĵ9[޼V _Tئqz/ReV:hMee(:45q7B?F R|rNݯIYZ_#O#|$ȟ#\e ѵMR޿L!nSO_v&!,UO}; #LH'6;1Hl4E';*Y&f)Me&.q O֮fl]nZCMȃPA hj"!n7>'{4\zC:vJmZfxj-r Y"wwOJ>Lmȱ0G)?#ό}z0u]/祀)ذ!,,yK5{N90NoQ̪]:~N`^qvlEfl`TZQ!"nOɯdzeldT,_O~nE~NMDM6Eōr22nlZ5|GHQEh^nk}!4%O-IOyMҢ60[dW:0FЀ6R] ;2DzBkW1\UbQŐJ * -y?M{79偑d>9Ʊ[Zx9pe넏VϹ#w}(D|yh#Dڈ 6DѨ܆MxR9*yulg>nF^vw[tFwh g&zg:?X̭uFԊ"='5b;u2W._zdrp\;Ew?Ѭȓ~ч%HtߣUuOg4?U}!jk7Ay%?L.yxڐU^PVOzUoصAM Vmښ$e VXKNOir8зԫ_WiyLj>g 6w꾚<|r]VXq ʫZX]:VA1vS8LM~ 7g"wg6O1TQ>4!}಴LʍbkY3xӾ ϒLޯszidTd?ظ}`?RabvznWׇS0w>ף X^,v~w]toOO]R\A$#ľ~8*}g01v$} Xrws\2VJ=jnx25H*9,z >x(x(x(. W8ӷ;{~|WBoO/( f밸;i*yx 5 6$ \ܭ䉜Y PɯtǼjm[:~xV\x&s/Sb[ԋɟvOM]eBîعོ_Yʻ*.ij^(fTU?E8qp oKY-Jr>=[~eȍ[z m o:<>Û3+5m/o;ׂXmỘw0ې#^/nu-}U] m|<.2‘.;67E6ihx^tG <>9x'g}/; 'r% 3s*H3N¥<ɀfz!L};s-~݁~=:?N8~s]ь SMۦ'opE]?ujE9ax oy~_Vp%ӡ(˫Mxc T+>~EAGrenk7lzDR(GXN> nYKBEX MBv8$~LwF,w{uy ܾx:ʜ ŶWdpQÐpY8_>cGԮe~u{Kzu&lqy&@1(!êjq "$..ID@$AR@<;WZ\{^{{u_s1Br֛!' ӝ7/m5~i.hr4 C, ʭfo%Kq` 1;T-S UEE#eP4-b4*G֜$ED2ˁ 9.ѿ 6>I3kQՒ*fԗ!D[5tWc+h]:PHф9v D5E{sDK#sw6D;j cB*!O=hFpOü^}LJ®X& 4x H<̫EFub 8OOcIL%~%[VEXaj("y^TS#rWn N, i 8NT,!&`I&68]ޘJڌ%E5'͹RV;<1wwB|h+G?S>|&pdsAE1<1&nb-/6^;1sYBIF5fƼ2GUa0 .mQ?,ra{VX:2T#%]`858,A$B{z*}K(Uǂ羖"J?YGlk$R\sO&^Uel|-r1{dO%}rpպmű{EM}c5Xۓ>՞:UiJvwO].>~|neՌ\FdY!L0QPqPf4H]ܻ3نZ(mjQc;{D  :d듺:N6(uǘ{׋x׋ܒ TiJVQj <(b_tFUSK*tYXyTZl.n(#$19Y<|jOqKoz'W"IIp2ȥ]ԧ锷W\5L\˴8[gCZ>]a 1HW|rYF$%[cˍgbNhhx 7e@gZQ8˵2SMeZQ?6hF`>sK,SQ&J*W]]FK!$I,pc'@EC>׊9 قgHSz[(z1д/Њ s@8=7>{~Ц:]O䤿~>jE E E E E E E |E ooq ߄  ߄ &^R(5F/ v yyZQ,fȟ, Ƴ\7ԠčO.Ӗ?Xq:@ܐq073~Gי8A_77Ҷ7C~63 ae0ީ2!~PO2^c'@ y3M~s Oh A{R?܌sXT o7G-W+[ۯ9]s&\ wU.oy?g7%LBsxo??O O\܀},+ك!?vgq#oUy7?~G˫,Sdy*>;o)wT6'wHpWx\__Ļ!s~g0'r'y}7g*^c0ϯs8`ۋ‚m+/;ͺeY\._PF-փ^:m a}>ImĠPLx;o@)ELFŤQNbhD;ًp`-#2#( rްWjYLXt\x#!T<ςns qUтes,?SK{"+&#=9ظW(6#xU8Gj9b,nNV H\bN?? PB?J(?z}6/ G/s|x=U׈^ףY1)4~kHiTg6uXTw+$=y :'~&_kq^ZH )̐gO/4䔟,6Ic ̷xy7 *aBJxřBZSV0>l|-0QV" -ó.M}fth(qi;=-d$zi(b o:؛1=ɑxvE$ HٚsH0w}YwlӒgd ⷒ$wDvdyɟe.ͻ) t1ja}CzK$n)т̵ Ә7>:U~-jꎀ鰍m,1#]6& V&լQ :Ar/)F{:ss]^F/0jYJ.[AA+@q罆\&Gl+P\R?" xv>#lne7vDZxņq/uHH`eJ**݌j3&>K&:}̏U&_%&>)"X~آpahΗW:W!GHt7R0vgR+zZD%|-aw"ueN/-3 n]t p#D}9L;]i&5<ȶYК:p5|$оcߜ*ظMl(4Qz+sOfl|ϝj6ٵIݣ,Eg1M#Yɢ ouj_svBOҺD_sw=YRɫ:dK_.x>%wrBZ@9"fTN$/j #һZ>]tiJVXP܌R5#YJx!sl@#SFi54,1-`R//ӝ(hYkOr͙Ntqm%~TrB1/Q8_;'J,y-7{Ox>&vKae龃)ufh`Xok)E'櫱&)$M-7ٝ,b9}ՒƢjG$kzޕn[%ҭx6gu{U[3D%K/ K{srM,^H%dUfNuMqWrY!-߮Nb$G*K jb ޥދ/R&T YDbG.' ,QՍo$ 7>3H}l5uEKVp/ETգ-X T< @{-J7 .Eҥ-(u^|R%Xtc^'UG\5S#z}3n&3D/w{' 1 ~j ZF/liԧv+Zm'N lSЧbzRk]әnǫMtH~  ,yN!vӾ3z,|g2^]0?8^I[{(G6|FmO7.oe2(T4y'xwRAwʈo9Pdض.ypLŧ˦OqpҨSpng;=̲'Hr0%DOjF!Dl1_ŕWIT4E_j NB{^x ڌZb ^pRyqQ +O<]N6v./6S>DJɱ%jsE=\l=PVV';D@(ë0S΢g &`z▰>Szȗ%7ϕX{rS8S2z>-"Yn[2CX6դt~ZGJoLeBA(A\:&JIs2uĨ]'^LEܲvo9/_a$.E3^LMh$ܐ֥ibַebΧُH-40J l%{E:y9j;hgH$wGe]NN!]¸ Tsx/j쟣:E.24>PC(4 DTԮw&.ӥftЍSkwjl,n]ĩvS'kHiM4dǽ9LloEbg}*TvyƖ_]dӺY;w+>Op(02j%8d q;E]ʧ+C9DDqpRO< ؉੥$_}gh9~Qy&YmaW_c{IٌX'lT2B%Xs:73I'h,GqcxuI4q;+u0H3{AỳAYYWaAQl~v{`}4+ Y(,t/7˫O>uۊ3E(V@G4>CBA6Ĕ:e3ꗩ6"sEē @CO}@V$-{A& Xy?-}[=Y(bCPBay{$ 40D0G9&*Y3R`ʰPL O n5݆_ט1S=aגfEE Vh PG8LCWhL%-oCӐ+.+U',\M,BmHZ* a;]Gw|q \ERֱxX_Bِg^d_)qR.Eq~ZHz@3!GCǀ@hFa\R3a$cl9Rds5> 't2qޤBw6gYenB17oY~Kﭧ=rI='Z )i5tYIKq]Xٲ1h[ɠP !w^JNtS&dFqquzB*E㐑̢)D.$旿Ln~ZrNI2$lty9)'I܃P@YǪ 5ߪaV=r hxESv2/93PX0(Nhڦ%*Иi8;of:2Mx";Hy#2|z:E`%8' O`% '4| E ^vʂAD O {X@,9q a&}&#JE_Th 9BK;tjW(Z!i{a%2UFSjۍ#M9%Zg/E;-BŻi2)&!TJHt*'?FAeqc 1áݧTX*fL얗 8}sm_0y93YB{ F[ULz_B,^R2ױѥFj] ;@3ә:j5HDp73Y>G!C%bŇV漏Jō*ǩW؍F< 倒 Ѝ YnW̿Hf|49Tnֹ_>=QQn9=\ԣt8Ȏw,UUJHLOJX% z$&[qd~|}Zz昻J#H&TD^ױ)Z6ُ.P`T.J1n^)e'4cfYWb$0yO`U76䀾m1Rosk\. *{ؾm@ighfHnUmow_Sklb4|<?h+L5L߀;M!}6 l L1:zwߌpW b9TӎNMl8m΅k&:g*6빒v6)By%iȻ'KwKٱ<1;Sمq|]v.h{|cdk#F-X+7`ȹbc9$Tg \F K$D(3?~]OR0HliZzքgD?+ͽryo53c0 +z''cj^w05Lssssss46qnTo_Dy_~Q_R+NQ psCn ?6O 6Λ⍷ (ҳh o_kXr.佾` ;[5 gFns xox8oWcW~W\CS0 jn׃Ƴ;{n#_lbn?1/+@ 1Ă'?q8 h1/Ig]Ub>gj/KkEz-޻Sذ$)S$nձNطxS\*ex6 WkZM14441e=L%K'hPrI8fSkp˵2v\E29%epDKU`7ʖOM#Rt(!y]`PBs=/v̫"7g^; 7"z}Ym%vv8y@~dp[N|-brJ }jkcCۙ4IYj萡jA-TrׯxiMt8H!c:4b%]JI#$lQoB)PyY+iHf=^K(mEf`G&N /F{Ip*I"aw,l][8Zɢ1/ӳw22fU륇9GDVv}50Gi0;L`NuCt^:eWB|McĘ0Ți8 Oآ&Oj4?)y D&IKcpjz#g嬵`:Pg'8)SGQq?(k>sXc~P_ $Ëݾ.47H^#qJ#Z)ŗ4%4y,!:vC w~q^1^˸Oʉ`;""JzGN%+jv8' !2w[\sz }Sڮ 6ĵT8/X</]g:DjWJ2T&w&nx\EXe`WGRi9Ĵ{& 2kP32e P. {ŃRh &?8%#S U^ws=3ӅYnS[n=m 8'gy[=^~~+H1"jrP5(N!mіD;oc 59U~娦a ^Ǵf{,Afg~Zɛ&Bљ!lCjdu(txe9O!6.5u$n (/!"t54O:>?eHGz?8a`:iɪу4H*$>Cm. 4V@9 iZȇ/ . q;!9HgxH#3`^%=VQ,*e<*2e-n=fTHK(5zF -j6UVY'E] Q)vT 6AGyG>$\Ut KL?Teҭ,HF =9)bJY\d9gE.fJ89G(}0S)>uoTtK>6'-21?_%kmB:E?E% '4*&t;1= |Xw3e+MdpvQ@8"păEA| daᤕEyS$Xm\KCFR|j{͉.=z3-Χ1+\r {x#33ceVi|rz[̗TO%zrm(8kNR&^ e8L ӏ,mq~ȵcJ ɕI*z.q2i9 '\ƺ~mJ#0 .1#c^RDN%':ެIy wQՇ"f J,!1Y ;YT&P*p@Ziʗ̻9Br=Ɛ ME*8tg\y,}NH+[sCFI! ˏ<5R /} <6/zЍ&PakW: P Pɸm@Eubi)b͏qwщ:4<` 0rl:=Z; O\e7/E2c`h{YG MQn,V& M3KPU<ݏ[:Kg84lfIaJR|abYX;B\j-at["g?L곊?Ԍ0gMcI,2$sf^!)U;oM zt?Je)e8{v>p_J>J5!.x.QryNBHa@ 㕃zj+ 0i#T{UUQb9I3(2fCRxsvk#3)SC l)\ XG+gP.[JY"cJXCjuGܵ!O?EL=*s_.ܗ"i=CbkUqc=maZ zGT9B\ڞZ}DҢ%S.cn bњf `e#rwyL"1tjjpێǥ8ܗ7KqN)j}:KȌ wy*z7TJX=Y8@&Z=qOmahkH,k-3s5q[ʔХ /pa2c~RQLBLu4X!0!1SБbP>aIV@iSlK4z~E'N%i ޵:wv.[ rLkQWGўsxg2ַBh@5y LQ((t4|.* eEP 8,(U*uT'bQ 1I1_ï睊==;Jv}!S-9\ˊm$Xg3C@}w 9Hw8cdIsץ\9׳,QO_JĈT5> Yk-#-:ֿTeOGLx.؂a+!oOAS1-'xfx)x x[C nOLyG"Q$w#ysƿ9M! 0\# TU_t^ -4yA_YG34ppt1p6&b?64^ 맱 @ R,z'c,׿ _fx+M^疞aq p2h_D%J=Tםҷ4Y}CK Ni*)n_-rCFzn8u<9*4/nT~7+1 =|rHkSC)wݰhIU+U4&)гzd, ;T'k@jI}6}J8ѵO"Բ:Rv<0-\ݔpo\x>߷0=ͫ ðˁ/ΥԦE}2I+{a7Iyɐg0N ףǔ9*W5~h99.Šo)-S;dLe?ru$&~EHkdJ۳O77:{+r*Kp5O^RԲO6.'iZxdTvx_Ö̑fYxKq9b%&[޺nH裸Eai@X|NyƏE ǎQ dA` zxӖZ/!|ٽX~Y.z CB:w9(%۾rt%Uz€8g^:oXl<+DpX###sv4ASؑ%u$' c?q/;X)d1 B5b4|.YbZ(XXgx gOg#XbqweUB6hFvh.Sn^~1ONAwZ[עOR@b- >);̣hjs Ӹ7`7qwgUX->w"pV4[Yc*  }r$iOitҀ'g^~~\ȖM65$AGD PH]VChOez~|#cߨ g= Rw| #JvJ..Sw)$UFsiRa7$['Rۢ;WCY:ĞfaS*<-SWwDJfb|7C@H䙐 Þf5+$"A.l$LB$dFW.C_ӗn Ҭ# ٺ赯uk,f2VV>1ʈalߪjOddx 㻇,?Oeۣ4icPBrۓ+{0Y-ZQ $ ݃wwwwBd}'ܛ}/`6j֜5F>z7Nb/ D~9zWwYyɼW2R|9eO '^]k7V}+nֱ)ݲՎ{2^h) E8}4!BᎮn4 a=ft3*'`}qYf;S9 i]mV'K:28/<`!&hݤ#mV>}! `OW6եm* ?D#H )b%/iWؤu_e@loLלZ'1ߟu(xuͰ\{2eN]#<6$siF+]k-JuBUV$lĶ c#eS׸%N~][m{|uj? WfF%^ah+ ΪkއH D-T2+ _ P/QTAa8f/jtS^Z% 0>S閸rӋK-k} C7y#Bd`=BpD?dv؞cSafw?>yFփDD Rvgo$r> ͼ_yK#n?{)F9rJΚV)F&5F5¢̊)x4>f#_Fz&Hd?C53?~Ц9sG쌿,x[{bt0q164rؚھ4q13cfbfЦ3p}z&Plg7 5X_3X<w o 5t2pt`T7fe5VVyvyT`Cg-rb= Y8~##7ٸ3?C?TfhvϪ_gXY)cIL`gn$ghI?3x% ƒsƓ?~ޔsFy?[ڰƏgEND6ҽA.jzk$zk0Eh*;Vngcn6"J̰.jr -/u"Nr:M*Oi [\4밸"[=w::rtǑ€{Jj&lK|ᚖGۦPn#St̏?۬ur-tQG,˻GtvO9b7T Nw ' 2M_L5Q?o,B$!2~UV>}J%bRXT B"퀍I]i ^"-eG`hbk>58\Cw78 Os @,7By3Gxf 8@~2Xty ,T` 8VnL@WfΫZ[]XGُcWݶ}xW~z8%3:c@Ϛ.-.,9o`'KQ?#bTߞrw m{yO;Z7qLK; kN4Vs\^K}$%3+l,BU2όs6VaI& \o .@`Ap}7@`7nˍN6JGӽcM}'J:ﰮ+s)ZZ x֫!j: ׋ +K #+",uZg'+7ؚWʼn|q*RB[ 34c`dpoBWpp7&gQtmҧ =01|ZD**B ߆Fߏ#,{o)dI*ROW;EP]ҟKynnoyʷ㔡 m̠"xa*=uLpD#u-gAFPz&̊Leo* ō<4zBW# 6~_5WII(8g t}`z%t ΈhZԿR|h Ã鏿ɜ:2Pv MxYZ4i }& G]Ɠcf^c'Pp7.)}}А9WmgYј2QK×,6[!(R=jg30[DQYzt6簺~LUP=Dj99DqU:~+VW! ļTa;Զ:dte.h[Yt=SL@6_`;/&e̯xX`rUj73vM8̧&k<;=\9|jAEd/'!{-;8U19HY98{N*@4"daSŸ8b#\ w~˫Ze6NھHkv9CyZCp>DM:Pf`Mj5b]6sf T>O <Fn>[]^2u8@ÁnM |cL٨ȶNY!b\rg%eY"-1*]im} lv+oƘ|#! oRYjt+JbfBԞA`-BT  7݊,A(AeDGs? 15fWPjU!]qz}R}MvpRPzPoIsfЂ7 ;`rn\\ro#]rߡW\>)N:I\ \-Gn9QjWӡ={^ycF|fƖn>4DS;<,ܢ~D.095Ӝ.51Vv5Hj~ƫ +TTEd[;ȓҷۋQ9;Wq'y<[P!{TB.8ER&5 w(nz/eQ'q|Q3TfqtcV@oUSw_>>Y< <\cn4r2^ DKb,(FAڂ*艭8s#7TN!p7|9ZgZ"MAt\I\k()8NzU0cnhچV,e{yŝV^5ee5ycꠞ͵_M5pK ? h{L6* "1Ζ}wht66ej bm,`+8E$^>|>Hr?u(J ΀^9E!,KSߜcKxy33?#Ht OCh WI_3dzq2Xr `eM_ >"#?6[XOBb?/\-. ffЩ5jS`~.TL3rL0;29_XpZ~4!ưـ,6g `6:KG/'3e?7+ 0}/c7M߫߁4|-ɏ]L.^J )9p,N`WWtd8p '8EPP\Ll$*~ a$Xgsp{$ 2ędW  JRWfv_2SO0}I{[>.@U4~vZ튈mcwfBy " |<,5EwTwWkKj]ʶXg |-1X0 Chzgf3gΐʐG ~~~<+cϓE2{_'54#?RIYEC I_SdS̗ %hKF||juBS߽ڦ 𱏕&$)c^! =$/E2B.'H%y[G|ZtIT+Bē8BҰa/&g7irPmˢf"mF Yjp{Z^oUXy'C+~)`rsf۟J[0"`"$$:EP3kkS2Ws <%Hvԫ^$V tK3V)B 5wp鄋z+ܕUZs5n6g_y>}Fkp- U JUh/q`Gܫ37>eW^T ȳ}W*L~:OFbe~-΃/)aRc0J\(8GDh|jWmM#:oDz)Tr_YvqԠDiӼ4n8AQg &/lhDKҁ rɸ+t>OYǦ1(u<7cq9(:c)Ki:/K@8~^7o\a +gEbY,U1?&v>KЊCؒHp|Z4WNbs({4eⰣcw*ѝpYȣb$T$jV ֪|F2O^Vܧn W$dB+3&# 3?}t650 Qĩ! &NL.x\z:le\CTȇ|vV3>gnk^MØ~/Q舑 nkA[&n S&řbiG1|Qy yL6pJ]se Z8GOpjKl(i>tN뱁+xg]>4DQc #"}R9'},7CYI><ôdFN<^.HoKXs7U_ uP>LԹ4b 2?_ļa \rWԗkXoF)F nz Ȩo8Pqլgr(nDu]^F)5V]bA<}iGYkPN +z!<Ψ,-;}Urj9Գ^OnPniY<@)י*ɨLq3֧_K5(f7!OS'z%D{FkIHS`0^>H A ;@x JqSs?2qԥ'?`jQM%tXOZsZod:{#as+ :Tk8쇱5-fpZP+Wr"&Og9,,P3Z8KtL+UnWmlgXu*m;ZmRҖi _O.?}1f]n{&as|SQ(n>JInkSMx?&%}C;# U8Ju0vV[,ɷGs bLRUh3KWiW.@%a^ՐFST_oPk&m>\ G*X zظ }wpc|2^vFD)zꝒY3ZKPٵKdx٧\+9<K ?:(R3\-3ڿrJ/cխ,693t`^ ^XpaZ'.n,}ڶ:VX#ۨ | [Ɗ;z9D$ 'G80i{#=9roR>,G8fPjwǛHμBNP]¢ ul鰛QtI,D4ƑNZ ;'1g}=&XbevGz l"H biq/Q{uL"P Yw[! ! [^f`?dLS q!Dd+Q FO+[P D HWhw τ%oYyLˬ^GB!|OR<~RCUQ6(Uxr@05Y^8V2Y;a $X;`Z[{׾~uG"@%)@ "Z:xA(7¡rufcfJ 6-6ڒ =zޱj,*NJ|&4"fm{:X!’E00D9}{F{IY#mOQ(-+ay2pG.mI.| 6jռZ~NƏIu3*e Iz]3HK=wDN71۴,}>͜ waaFL:~ګ(/\'@ zh\Tj#qk׋bga$2"1it @yS@W뺧GI{K[uV_ɞNV'֌D*9޽8MTP?<ţlWгR#triZkHprHθ:B%BW1!~eev sٯg?ofLnfs3YsbWP$n^&y:1e%\K0'IwGi& 8|$@MU]}v>' qgjrJucW *+c R0HIIelkWt墶Q(Ūk߹K9 zl==4nl&j|nXZm-,>](|Q> r4qid~1.չ~c+A/ B̐br|",pv=H^`C,A"$rW}441e8d8wnQXb{nNlv>u ^t%>2ow )p11c  9Noag ` @7dטq㊖I Jxj醙}jI2dDtRu{tRqo<֣u`G*G%2'g_aQV=ї&IT!M 7ie%AM1RÜ>*-50NQݜO=42]p~t>LƌhW#B8oMtWCvF&%JPG eK8`⮅u-msdșENH2+j͚f88~tbT*drPnXn=jqSa'xU""Tm0 r[{[ŗSgW /mrt@I|@yۈEk4t9~^4bW—g R7-e7}~ PjBQ2q0anb{NC8+N wѢ}S@S-|c+>ot4qpV,BmWqVT_@ :ɥ}SNJ2e dđHߦr(B|a=Ә=hoP )!H{q WVu ʿ[f]ƤtnpP .&P;f |9QnAВMsyOCVZDcok-t" /Khv,W2ݼHj; %0XiWǾQ5ً)(h/F02ռ<@UX3j`=ѹ|KRrs^rʊ,hC@ q{r%>2݄ Dٲa0(c7unza|P|3XjucD\hl e^Uh%L)ePwaMW^x:ZuV-s4[^VY9 ts1lsx)g/5$Kdq_ƃ-G웫GtDgX3QDNX L6;`9YkOgIocxp%OɓPt%eI G^ [Oٝ%@ ,TꬥݐL'ʆ$My&l5vVӋttm؞ēbwS:W-Ĺ%{ \WU]v3g,Vmyڠxj*ٌ)FE 菕(Ӷ7rdlǢpl]I-XS*lSpܕ|)уβ  Jz?$FFB b[t$skES^l,-4hFPw$`ǥx7wp=ɡ~ Sg:d iu V9QMVp h}\<;fK~tewvg*L/PY$`-<G7qNݎ (j'|=^ܹ~Ӳ!.25x|`˱7E\,,Ba.4‘*‡H)(^fMڇf K%5~%țGuk'Cyh+^H2ZovUqSIPL:禭<4s=5TF&5&q 1vD[k1\,O4$`ޜRxRxs'SsA0?>TSу_)zAwN`f^L3=mWEg>3p4daA fYYXؿ돡r &8P9a`!AE _\~;?؀Kօ3+FG'G{3=KG{=k[{ǟ BL?lK2='qTg#3/F~6ߵpK/[G:#g]G0nՑ ǢMDfK~Vţ=n4c+P`oyq >?7¤hzv*7ղFRQUWwpO Q+uf._4 lf=t ʛ{6j蔰EDxCUb> m,%GieJj^ R}}9e<,<,e]8cK.yU/ hتkNܞJNlOJi@5ERFLIh-s%B[I@_ o2.iC$.oK.!$;a6*e:)T rҡ ك,ɩTBʷT9hAdmM]T]tRGmen0'>UfVkBĬ.eHE;V!*\$rʏњڲ")05Y7Hȹ U=''A1{bbte#ԯ zO}N\BBP},ڷDX?_4GYEY|\kVKۇ`Pզ`s]j[;liF$`Pg l0#́ԃZF>,k|-j>WJ&F^"AL୘+g“5rSޫ`$zHǯ7L}_d4B7Aj;a_~W sTB:~{;GڒmcӝIz!*ڻ78aPeAa>sd8 !+r˭Ct.[$-ۚqAɑW}Qg=q"1"7/bfêvŝK|?֙S]Sb_yR!.nDY4xrqNPN!' eH j@œ}-q;%k[S3za0 ;,hRѓV1"IXɞ1qGQ+uMOrj|EII} .t(;Eln]lx^ڰxB )U;ۍ"fbx9xfij|Vzy^:? EҽPe6Z޿Enκ֖V> _9ЇWmlBc&# Ӥqm);UƁ'LN$$DE:jE!tg|[ N# m~K tߊ̲rdžʜ$$~dJh OPEL!^:*ZI?^hfEA{8 $E(AZ`v[[b,J~ \6랴)hU8#wD]lYIJ=xB~Yxl<ugma \+YDŽuYetp#s @LU`;6jDOYoy>k^HBz[ kᑷɎ>uTת~k,ۙ-\v ;ba^'m"M5AҌܐOQ L}=S]G|g1܀>܈BI_ >.}evXHu crc v<]#U4ĐJ*,VnF:VfTc ;29VT+1A8wMA$MH;K/fqpL^ t;Bdtd-Z8פnaicf̆x_@ٷ5PsHSӹ&0ne>)ֆ=*mHX.o T>tCJe!~ mE#K.dD3 RB\SCbSa!'Yf4j"6̋~׹:r5Ol-\q%kv/Ojxˉtyq+òniS.ix7AFi).nPANNIkڮz|=9qcP5N'qZƗw<֏g,:ت{]wZ|ш|@^dL)_%++-zzŰtx&# Hd#=a؍Ѳ'L?NJs^ŬI{a]0ڣ*^Wy |u#I`!rcXuV2mxmwcN&,TدxԎ)g"OQn!weܡ"9u^6lWߜ-J’Ӄ25i6tvR0 {VVS?jzI(ҫu74+WS Of{gJ܅q6+$07sp`1 KGA l__ClAI?-Ĉx/y YWj](ѤyFr>IwS}yfFsֻOa$>,lj6C="Oh,53m~eYvzv+_Aφ)Od8I(?#% ;^=f r'A.ohz0Z;ƨ(nT"<ߋ=Iߓt0NίOO' ~}¾>Ѱ;ןs_m`_Sxu޿8 a08y@d99!y֋io9N/`8Iطn7pHs@P5uPNY&KW n]A.&⹂vTC\\2PojU9=V]A64 xZL п ~H߾kry9Ux "=H^0pxW1B61}o])0 \;T 9?jq_- y6]3WFFPzQzt~U'WO?9@n=L:u&/x (%?g75}oп?v1.Nmuu __WT< 缊p׊?[s D.Lo5x~6 jA :^ Q|7f p~𗹾`N,me[Q w&?'&j:`,?g[/j?P<]6FklY-}mcAJ<7G$Վr.,8m{/ jOxuz&&{({b >w=GSJ\E9KP.RQGmARq )']ճ/' =/NV̳ř3y!0Fu<챷}բ -hJ3"(\R[i({؂Ѷ*ile#-f {r@,Om=-a]n)FMY}}Fs7V5JAmRq>e|T_ƛS_\n~HgiEU@RY=UkIN✪ k=cwD !GL]S6jk,/߿."R-;[$ohxmu)!e[𔱴8Eso 7qxxTniSj9U:PFl?SvJ|@a[u f˜ͤtj&CLob2;hu[G"簟GJE=z4"`Do*c}FV /򧯒.,c>EUI˓껏OkYĴK8v7yt)ɷse|moȪ9wȮT&-&8.k~ʼcv7rT4ύ1oZT-amRR\N*Yd\R> $8LرNZM8Ά;r=8cfJcHm{TaK^[|V]PhOL){:wH=e;nCBdC^[n:u0hͯK[Or\c5rz1ׁ.IHgF $Nx:6\+ ,.x.tZLcMVp2ԢòHL7, ?IjR[BS>~c| A`M7rͫ[wXiJA7ڴ2OQ"IzfZ;yb`П򑦿_3:cJ}G X) / 1Ζc쫻 vZi ^4=e؃n(( q'^}/Lq.DO'8~yk܉xw1Np(9tu0g(ycwUylK4H :t>~8=ý wlϠc@|-asKzxpx@ hi"¤k ^\OyxAxj%)p94oZk=Err)#1^%ߞIn5 ܫyJD:~g!9dwJ4N@(0f$nޔaQo&|Md&U2u-S$f[c;#h:mfqQr&,y"7&Ρ-bՎi?T3Y_S\{}t 3/CRLG;7 VftStߧodN—Fx  OeB^ m[>^Gs^mp9/Lxk8pk)Le&@K7bN-Gۮ-=eg#-3/ %Ѯ{r=۸ȱ\HY0mݔev6jk`\yA0F 6#߳)P0`*Tmt^@"/$/s8.MGcgV>/}Q|+@JӕA+ؑV5>ʇބWǝkbtA'm2ṃ52"6ydhcwX(nqqeU_iؼawv!$ę3F& +%w-1g& m'Z1s|Ȓ -S 6hXظmK}ceIN=;ŘS[=UR|^~R$7}~,˒9ݔdr>Y%SWErG(]4(B\|UGQqf OqѝY-%dp7$*!?]/qJJTDl |ˮhb)&f,}{}JvO͕ib![dv=s6>,-7J%7@W9(tT=Kj%[W'Y{aX<,ѬJFC%]z&aG2_4~;*?S`Nt#K^%!%JAg>Hqýɂְ<^πϙ!nCsBLi87L[ʎ鴾msX)pwlRdaxӴ^K|Ng.sJB/Ynm0P`Lʁ83<}X,*H3TW1Bv2$,V }Oc_q7X {exɥ*JAcpYJS~}lf$9VqXl(0 56ľ'[v̼X/Vه;IAnx'7O0& β["&] 3lsj#DKMXDχ+/jjLHnXRpܡ3#뚑`~Rg3 Bl"Ε5Q͇ڑ~%BzI;ܙa۹YCώ役Vȴ b]<|y wS09 /\`N DŽ@}뚗k Oǵێxط??~xK&诔p AxmSSxiŊ:%k}f0|'>)6mgz%aJϧ sHxo`$-><i\gXUk${7`#7#7#:ө,-.9eߣYy>n{?9X:EmKS,}pH>{,_ΜJ !F$zn\8/mئny$7syVQ\wR D=ʘ[z, =v#J}$ُ/ 6HVt>Ze C_nHp"~UO#&ѷ̵zRjǣOrEb:';/6!o ;&`ɕ/Ĝ ?/4|~X;tPp!R\ff+v̓a7dI[-9zP1Xŷ(dqtΥ;zjYւM `딄_$~2'J|\j"ʙ~%dka+\ft[;b:&XlԬf|1\xYiYxėܰݖw2p/1>s_*3BXEDukFwS4 ŵp/zf<)<<{z_;򛃒]*?I7}AdP҈kX>ي \PVav6]@&;(/-Q볹ZK S dB3:^ 5gx3mלEhME½PW}ewnN bw {`GfIa/Yd5ON=RCz\( ~DZR}O`7oW3s05o"Ѧ|R/Km:!0hƖ-0^9&,%F7-9bCHdC%ﳇwn-4Bђ( t%,^z,#]RATTi/dW'l> l- zdqejv|؞9;Ǭ—c>XnB:x'K.YF#_UYhĮA8=[n6dót8ECEo)b$Y3ClXsViAfnvk59IL<}ҁzj8?XCTPhE̓ .CPJ`B%'1,q؃nj7=5y K*_@nȐҵ a6L}*[yQnϖDݗ*/D}*}}3]{QCM4N.ײ9 CzII f(ƈ 5 4@Uю;2|m'xe0<,m4&:.)8T:[ 6C3'J ޙ7_+9e><4Rh-Iwz}F*vJۨu=%ݚF6jNUZvoƀ"_T8Y`X0PM1WMi4s(J:O:!Mh}C56Oy\\vɉOUс,n \)owOXQ>1Lx5'!;i5NV.Yn>Է%Bc6!Kڵk?;hEtsoSӬ  ߡ,O;w0zfPXpuk>,ce]أ?Ŀn>tkj/ޱ}[DC!w2lq "c =MT+fp;c@1"8)nMAUSG"%&HG7mMw-(o+_Od!ci۔C ,J9E /q(v$s}٢M(cKEV:}>فO+ 614">'3LF% nx;1)|:.\c )"vwa$e9ʋ'vhvcG+0+ $ ȇxJp;Myחqy*$Tq胺@oFU[a:QL}WXy?!V䷞:*oqn[mG,Wޫt@|htp:mNH2zY I7ʳ+*__nvW/d_i|Y#[Ag PyJ4%%w>}P:]D{<_?`xMB@|y WzF <0 xu800纽 \Q__g2W B  &f/4  F ^\:j("7@u&eVྮ)\ Mh& 8n,8դ];$/!s>@WXo膂* "m=6Y*OP9**v?GQU VTgκVV#!?! ՚࿵1Ov#-t;]0_" 7hTh~"Y-Ao.-AUQ*M@~f_Q??gj~ڄ iϕB,赝0]aTHSrTA UJ=(DkT!/qtd. Qzc _v¡%+O)d+im(,WhZ6qI3-䴌Ë j e>>3}z1cR]MZ[R~hȊ%3a;]mƈ@WM0NfH`Dq# [r ,&7x٪y`gena!rǟ |dJ3>^(܊OW21;j=JzL,ޕq=1=Y|1 -l@.  } Q|~F>y!;_:3\$hVrϧM1*Q &7ޕf^ĒfʼVfN_;=;,Nc+4iQg1Gs8LC_Bkg5! -NP50/A'v3Ƌvk#qZár>ʚ\NJ{Fv1 8QĤ&5t!jId2q)66ztf;jL-.^xDi?7xN_%t'5 vȇ3Z QRy0b7C^`(RŃ0 ,1Rt }|f +4{-#q/_8X򢖍1*tr} яxTFqir)SO*2v~ MGKǴ.kf,Q0}+&PE_S?ӎTuR`d)8w+?xI=6QCSt:/ͣFGoqq(,w6#פe |H߉)p@iAf'P \!" " .\~~!'f ?fw֯6>u?}x˹+u-)ݡtIùhZ['W#(L"UkCpY"fjJ?񳴟G5gT%cqG҉8^l}>BNDKluH &K‰0MZn49{zP(\P7lV&`K? IeȹO׋q+*=I鑤'̹M4g*o)K>#B Ck@HΕnh,~1*[\Oq)#z =B!,W򱽸X^ٵ* fK}>ހ^j}Q̿=7Q;x:G׋Rgj /WY9?[63 a5YrcEh노tNIQC%,"o1cҐuޯ,a'av>I|eid[f}yBxSN?w{JS)>;\uwϹ]}Rli+e2 MGdߛ3FC`E۠5@Q&iM`,w)st*K0on暾HIyT1ଣk'EA>)]B*RS۩w7Ժ-"]Ei'*xD"=;!#7>CEf 4871΢\qtu|q0@)2Z: -H1FiG=!O3z̒\g\TD <_t@MܘؕPl8-Z x;rЖF+:h vG++ФnKD2clNu/K xnFהmLB`dγ&ȧg4Zs|}Mܷ"8 ν:=xP{6|}G^ꭽ=.w,T)!~3`uF. @y1&9+,\@T  gcIK$A(g} M`5-?[IN[~YW;埆&U݃H:aI~kibES"z,$)s!Ǡ6 u Tuhś(;)ڔ--fdnߦmJ=C\ ?]Y1#ݣv,,Ṽ/++:c# E7<3D:J-VEzjZ>3|ZtJ[du/D.%)@E:4z7QRצ*\K-%={dOJIv^ zýYyEc3KVb#gqb uQN&$cw^JAt,^5_?۞l\C;&;tЗe! d6;R**/iBmD]:#ͺJUįN-> utcaîT~azBqXyFJGY+ \Kd?_USfQi5 @G%0.b>+~v6P: N'Ǎ 1b106w8"\I#^8GGU!3gP:c6ݽxni34LxVYz{ǹf#drp/ E euBh^٧Pn»w- 1bEK|g$}l|]RfH(|ExISwniz`Q*iMb͟5^uIѨ`صvۡq@&N"NKfiV> n״AC/E]-)sywWTI)i(_ aɮw5)Mboݟ-ėyQ z@aYmFmeK&R-:R#[갩[5|^F+1q$]{$+㨌TKCՄH(ff"(_\; vuMaiŐ 'kA0M]2F#-r- qxR .G͢!*wg/=a{ՖUۚRWGbl*&Ri9ܷ{+a^Aq`bl̊Eg&=F-5F|#b2Oq>K+ )J=eܻˇPˉH0M q>%G 7g'征FV k?ϔݸQco}JχU4}!s,O22pҚjiD$rTĚPEE?-ͧ7y&(\ sUvؖb><8T켒KscpN+ H72Yʣ ğ9J++N޸^&?oTwm \##ѭzZڢ~a<‘/XPųx*)2g_, D*f;b$xu{tQX>bVΜ&p2D-+CX}|@$|Im9 䶬tOi1w6i%njt5DW8qGn11T Bz(ː \999v#G@EQ {d-WIToǮRs 0nr巍aހj'}< 熻Gg7R)cMt4}q+`K U~HVݸ^[b!mTUy}SC'u*fS]@93>aRxauS&ΆV]U%'@>  M_J Okr;z1 *L h<􃽸)kk Wg7"d#ٻ9>HN [ o( FBb-ށڱU8M'0Ken]x6oդ@!BkHd+~]!o'`yyPjh[nϸ^!lТ}mf,H3FMh?olӛvWY@"iAG6 {SÇO_mGN`ҍ@q5,="VGLu^,gUf(3W6_'kKVŖAqjUIh/3L;ٟodasSi(e 9SCVoM(^3+ƸeҩF0$UiJh6jJ}}7t@9.ͿN0.+ " 'G|N$|2:E=eg<]=M$*Nh\"p";jJ7eD^> 6N* XSW(Tg_Hr02tRCrdTX CO,vUu#21)&=Adw=K1Qャlo@1_i"Z-ęt?]ҕO+V9Z6ZJ*%tY:|B{K>7:$M¿RNܠeypf"S$Ifd2(#%k<7@G1yoU%W>N[k,=Dd2{(2p#(KbCFj~XĒ fw;SPX=[Uj݌R֝Q[ȪԨ m٭t9oҌE1. Ȁ^o\ o1r ;ڬ5VQCgIrvp*M|%ŴN"\K<׬;٥=7և4XL#0g2Qe֔lT%X^Qx-6IH^4ӅE@pF%a:_LtON.f[=uq 'vv|yD b!Cžu@[/iwm~Q ŝ]ϩQp* @oLLg|ڳ;"eǁ]7g[Lkpb zIhyƠawCw0T &ã!z(` ta0୍h0 L/ŅՈUzƦ5%:gnl`Aߟb ;,qzW.V:65S7 [5 3;lx/JY,MOK @0ta&FaӬ[{0aeb$zʋե+c#L !q(&4x|, 3b%uUNh5ȶ `hWh?`l{n"}d-syU[3oDzV<>II}n0Z̡!s l,GMbʜ:ƓOBk$k]r 3bZ<3M,uq*bqMS:(l G#?XTK=MMX`j0]~>9-bDt_f4^۽な,2| gX$]>Pe Gܨ#*7 "V#yb,2{vOB';=?ۚVի.7T%hVzKa7x;p =^lG?IhdB8X爫sY$]YH^ܓ :̪be$ߏ< c\Ac 'ω9Yـ_6raZٱmR/_b"H)>KLle$G1,ވx Nܜ'os7$I9kS7ss3 1*3M>uԯrsߪay4Sŋ){? <>R:QF+nEEwD?~]lb6Ywb:Yq:[S No<2ٹ#i0Ψtr/+hOx7c`xPB.WVhJ[JtoUJE;,=RfL%Zzym|$z,uZca$ !A$oxR࿍w:jY3FͅvW-XbA 2z3湧gSZEB_I2mY Li)^*}YђKEdh# lP7MMZ[ Wb$#>>8} *`9RБ](l3䜶:GL/&Fx1HJ$k]>K.gg?;UM;BʵWeI#JF2%cX;:Pe]cEs*tl8j΁u3desylAtj%քǩ (,=Xyzwq ݐLEǺ׈FhbY#`#Cuڛ6gz0KZWXp)D_0※tבiNO^I:ticzm z$]>~֕Bt'iwoDCW4LN%>3`+r#+0'Rtu?vPxZ Ժ/Oǿ\PטQDg;,T&Ph/VZ02M7PIbC[)R)Y1"۸CK7^aҒSޜ5d=#Aa"]:%4<ݨ3 9vֻg<*HxQ9Y3EB|KٻU/:\ͮǻT4K2P=Q7! PuE`7] Q(7@%l{ EhUxB]mE6DhCR@ĥ92`25V^$zg=5!4.<WTPSیSk⎦vGQ1u+Yv6x0OZ3o͇6TL3 )d]5w,YoʮQ$AV6ꎊA*6W㠧(|Uw46\G([5i|>F ʡ0Sw0NʓȏP0}o'A~*JB!ai 22ӓUG7M-kN*ݡ*Op$XL|"koʶD\9,t+xiӼ,S?q]"nv%ܾk=E:A eR1pu}VL;䍁ȉ5/zU2D) ]%:́R/ubZއ4F#~Az9jM ѿĚA1׸u:MGCP"N>Y̐S*`1{x0)̊DK3n; LS72}u/=1V=5Tu0"Q:vrs#5/ip񀤽Yz.&鯌ɚ-F6{qH+PK NA0ڛYph7;""_ F\O'C_ ;AOiq-Ggu*M2/xOT=wO)Tg,ks%WC.z>DH]+""R^891~$lR2ioŜW.!.hdO>P5Ϧм7S/ԧd3ϓ7 sXC XޘB&`_` _&bF~1,ֲMX-#1)R SHUp]KPpA]fQ?5ك\(@e-2'LzAB-0}K!S!YN2Rw$ pk>5Kvd=aϽܚ[A2%c {dqݭ{qO eQ/i2 Qiai-}T]]SaUarGd..|T7qaww/V<.o*O8L˱ Rwy)CfJ F%i.uqp/Ui3FJbtrܴR\ZY/DHЈMxf!C`qu] HڷIh.O~-WD娦Vu\ /Uܗ>^O}L)Piz gvy*e**ޏ b$L+BW~.q {pÆP8jo{Cek3/M']Q b_"m64AZ>:Ga4Ԧ:/!.]^;* ƉzF!H/"D-LU_ [kfIP8G88Ε)B8zl6pV =̠b J^ .)/ư`/Q%s҄3w'*n LZ|b?2;k)joQV7z';2Hgs}|%.-s9P9=/%wvLl)V~5ۮ{ݪBשSxKipB /\2ݵN[mKDW>wlk_vL g+(ʖ)DT& rFY;<,/_Dɺ k2@q;ydo F#!cLeN[û[NoSwYީⱵc`Y3*i@!Vw lhgH|ehxʐzI::a& O\LI.G [",kܧ&I[-Z{=~9<4w-cg3Q^] o&,y~oErtuyKQŖ<Nl_ymOM?eSTܗlM'hCVT|`C;jsXD4:^'MpP !CR{{ʣē D۽ -<3㥉? ݇ѢퟠfIw.-r1ʛJxaQ ~n6h*XN<1 ڗ]ݸàq.C1#)FwIŀ.\t~(3G#?*7sbA*/f]sc!BCm$O KQ4J j_mijz oshudCQDۓvE _ҧ@-uz2 vzRciŗ!+ }e,{YLܙz?UR]8\w7"[]y>ks'9dfG%1[?޸%xp T-X13_i4!wJG:D5G{j/}h_X7saQPO\I/YD]^10ڲ7;|2fYSgff-M[t[d0P}a#yjL Ug!6p|^ޟGH#9o8.)cQW{zVڤ!8nkX[ - vAv}7l[c$7U[+7Іs3uvV7m\GNiDpmZ6 DCé^)UXx'1Tb's,_°iD19а]ڶVzu8ϻPL5ldFb̙NCa[T6n_|S"Ͳ=f߹& ǴGE˧/K=R*1C Ng=_umbV[\P"DnMq{OYgɯGRd\R% @tc[.PS6 33Im᱆ܑ_m1mck)68F/e _9Џ|&`Fm9HN\iZbB7Nl`Qfg Ӽ{1˅pi+qqi#\I%\9l9(iM}Y5EZ~^/en;t׶ԧkVJN돝 LeFa*cK;3#ߘIK]ۿk+vMB?وg}72ӌ{_!LS3rF,wԏZrL@Bo6@FGx7{Y3tt\@xzo<7$Ҳú<""0 `N/2WgCfą++v#fcjFu8aa, 塌J(y?xWuOaȧQ[EJBo9JTk2Zm6u:g͎xp}7t#za&Q^;xh3|_DXf -;/ԻүAA̻F1zrzz| Ea(zj Cҝo,y \JzLjk\k:*nړҬ.aq/Ir9Ƶ3'awV&o{Wލigʅ.Zw٫/&jUE?+kV{C0  )\*j'dN,rib Y` hEmh -o x_ ʋaqi"3%OR*~@{tƔ*@+bNc:s7ŗoW9Tt3A}cd|:bL~gN+O/1I$L6)6@FQwcC $f8DψFLtŏ>`6z1)Ǎ95(aޒbCmL0{R&bZRAmsB,`j Sqg<|;wt "{V Qqt81sVT/^]}UTF&T}T[~hGy]A5VF..Fs'/r"p<]uH6=Xꐍ)aQDfH[cz$Z)=<1C@!~ѧpjmTa#3$tw\L j{FT}:t? :+}a0F\+QhJ d"@ NJ_E#6E$\i _Lba`yCHpDv;CVT9\x@TcuaƬP]g>=*j)0[_ [,""VX=@ڎiVf}B.NlɆs߸%~b/B^fIM7Pn$Zalr<XU#yIey.ngeqNCi*lxĈnnשSsRsg[Ȓ[C;#;*mՇ8]]%RN3_73O߫YL!lEz-+'BFFB&?/ wF3S((2VmdWBӞƗo 8Mb!1,dpg!fsYFWRDP{NIL)A[V'd ɍfUأZ)Ѝ]hv,SzwbhTW8T+ޚ Ȉz_+=N_&.q2|h׀<+#_01CڰV>!0YGV*CٲF[8Tmū=C%oՒ  I! @U"ITDkfn08%٪BKab=.vU"`DcݣX{+d΅,+AX"ʥ*"ޑĘU&9 {Wyz<_Z %+QmAJ$z`|m4 1Fs^ݘM%̼ 5Bn[p[ZT<2zRqRGLn> bCgu+E6twt 6?:kF"ʔ@8@6|/.*x'ڤO]M UJ+>5w؉uĆ9V,̾~BQ뮵 9m!_GP?&|I݋5=b`Xyi"t.יjLd#vF9UhԱaqh˦pb MݎyNԿa1L촴"f%'{ĎOEPV몬GTP=joͣ1D=0Ww0UeZRA!lpS9$S6VBPHAQ^T)=wxҿo1&sgЦHWTh(z6wo zY;7&* Qk~PEE:y?ٺm{9.!f҈b=zE@-[-Wuwy7[h/KN 9=OGTИR;ݬW >&tsm1tx>NE-\z>ovHpC #,Pڜo%Famܲ0h@5qK3{dpKyu E{iSE]]Cc5BNr`@~yfP>NwqP5O!McY| F;ƪI)Pu7boÇ昩9 &zV2[W+DL IbD4%Swx5ZLR0B`I3^$lOmK_r7<~U|95>sXe;ّcATwe'3[ݫ O5 G4IM 2sk!^-M0Gs3m$CI s˻r]xwAl\3*[qfoXa~Q=hs9 !;=0U¥f$"ϊs^8}l^'#Ksݹբֈnz:펀)̭ YԔ~Cސ»#{ '\@EMé |9>2o? KyʗmO?X?as cv03ןֿIſ eeZ~rKV4X')7=k''/&/]Dcܓ)q(B//kj/5nvd8Lg9϶Oq3|\ΎMxfk=k/^S`h,`*Li=]c*HmnTFcĿgQ6lBqB\-=mmSf"w+v;=]] Boߛes 9)]ȈzrEsа-TQ|x3:y^r,-C\XrTí5@Hy >VJtݜ~mO(/0cnT po{wtNr'aZWXN>p9񮐮I"xBmB)r$Yl(@%a۽\~EK"~,xnWs{S'_{"QOK 5ֵaLwd0MH4ê !a$>Pu@gXKDA3^ӯ G\߇p^p{,AdJRk";7hjyopm B|UWg[eJw1*K^jA+=JP/~b/uoKRĈKvsm W<$fTKB燀:GB-)C,x"+ UaN {:F,i '! HRo_]~r*q{Eߏ]@ u[Cih {Λh×iMM_ibw=;!nX\<[EyӸ ϛ?-1]8#w|Ete,tTԝ8"O_JÔK4 3s5|DBҦyzHlLdBvmj\Zt\x, 5:uR4q;D0o[i$%Pϳiq@uB"JEF2}&}W-/.cS 'ϙ ->cKe{ ys^ )QUDutK*gke #&-:_F~3ppWt #w7*)8hԈY,)Qgq맖!/(۟`Ȅ!`nK:W$- F4tc"$f&(o跥c{H5"N2i+{he8.M8hc>]7,Ki}z3--}=zs֕c? (1%5hϼ۰*yh/u>]tB o~(IH2|_fɋ3|py}k [Y%W?X? Ja$E`^g5i[{l[C3&@Fg<! jhsdivΡZJW_&fȽ+^e"8iZ {#(t("c5I`3EVrCxk9,s~Sfaz(di*5D >۔A:@o|+*6Ur6ըk˔s*g"Hr̯.^7Y{̖lZ"B/#_5;zٶ}tP}Et!Q3G e-tMW?=җEwƏ fHؿ̥J-* TI/6G #GGG?Q>CifO?;vldOz{XcZ'37wW؀? ?603;\cgk#Zd@3w~ rA&9&KgwJ'(:9̜x? \̜\aѕ+o,.V߄@A2sݨ}}qr1@8@2ld03_c7~ `A/võ6 Ӎ'$vNfNwY.&^6\dCr\W7)H'3࿇o`pm-\mYmXo=~D } kdchgldҐԃS[O_:?9HG{On2G@ߟX>ԎG["`j/jbhdl=,]<>~}&J~?ѕtwv1w2|A!$ GB Ep<wGHmïѥ֧?e?~_N_L(w+ ?e byl&  Z4 43A w{7IEm$@V_LRNΉ㗣1"2'N#R#J,j}**.z9Ś]"V.AgZWhKckqMM1ϛin@ֈh.7Ֆ,N&罡ARTo=֟wF:.I[QCqgz2آU O )&cwQ7^,?y(c6w?;a]yŭXTcH0K.F@oDz J_x;eyݷ,^ d>h?`eu1֫l5K!V&S1%NN=c98{p,gc_k~4\עyN l߬T*c?/]6H7IW15 tjkgᏻC,Lf".zi~q`̂^Dr+~7Љ0.<+j|Ճd ȒkB]i* C,J#ah[jP/mvj ǫ׺lw `') }w0'KpvB'$ka븀|ߠw(h+"g_ fCQ*Cu#WOnM>Ay*-}]`{]Ƕ oyۿ#Ҷ;{r6J ddѽr3l{4@s١y1g)BK\|N^.O/)ㆁ4ɮ/>jex uj^fV!zQ;] {qùf@CzlPz^lY75K@q%y=Է(hV㓙g( g]\xHVY4o]%¢xxx MRgÊUl,"s O5wcBC]KݾHůYC p|Uo0e,q+;[t0ae^JRq0]qsncefྲ|Ś&VGS~lsH+;y2*y?*8v:詔q˻n}Z%n8B^+nA7g*/e+3=?D`TtItFEhuClE |5F(W6 PLJDpW@&}a[?JBܝu&49GJ}4st>J7DPP 댎. 88(sZ̞>|uK ?Jd:tR sֽ;% j@u /ƒ t/VxnJ_韍kOs+#b@Ө =%O׶#/T0,Zr6+I3ALeֺJ0*,2fAF #Gh!R2͟Hu@,QJ𭣙Ք%G; C5x Y v_$c=iM" e*YfʫDZU6usB0imv5aD'#p$ wg*$dᘛòi` lL̗1Arϲf|bSm%u@khKy'kGZv7pjJɨS5_4Hsp29? $|i#B hM+} -eY VS5 5-[*XlYþ`#:ĪvG1'X.꣞Oe7o%5BcFN^OԐWڱz~t5 ;Dۗؿ/CH|} Ĉ3\@Etɧdj 5 s 5 {˨t[w \ (*%A;@pwn!Hp}νw0?sԻZs癏~EږD]bw 0Vв:܈6Пz TS78(,Y<`^B$\B g=E)ԇGo>hwQ~-6oMesD~K9,Hˁ cyY[D+?}n4*sqaW9eb͇$edR!TMb ^ML̤B}7"|÷n^ .WcԱ >C, f1n52e9Sϐx+_! P 5R8n4I!d.#dJjX$KOa`@f(99y]X.K:W敫ZK?\`V R>DO? |v TijYVB|;/H7$k6zBhؘ,hisXI"nc 60XXx9sD-o/VD"H8`BZ@2+]}BƜWr ב vʐi/$g&`~S2mi-p7_٦89Q)hPp0$9q&0F&~Pj+sO;є [=Iԉ+Νv~\ <WJ_b97wF+&Wqyla#ыV0AM!eۓ2q?'dNv85_I n#*hEx&4\q_M.'^Cq9UCm&%u e $ۺFKe}-gn'FlY7CF3A<#sFk2$2aCi};?c̐+FFV>gM">ectԼԀ]~'>H ʲ2oswĄ_^9EaM:'Y;7וybq]+|55iUo<QA6,5[O#2¾Av! -,f^U).s#( Uթ xA 7EBo\" . ]".7K?TD  AI/*2/sظ3;,.s@J7,YAl<,~#L}?FVy?\G %# ~asYkq8Cw>zUgK;scvt`TV|lgC%d6q'ݍ/H?"r*JR? gY MVBYN9UxK ې_)ϲ\<l_Ig\D7dB g1Hq/|Q=hh/^Un5&g5.5ZLJQR+@RIZ!RgSpN`3I|Sh-p1Ҳ3w/Zxi&z1z1Z.Z´R_س/>FӺtT䳝ɨS&fg[rҷ/;/t]M*ZĩDr|4O2{@NFr?FrMsv ԮP=5;ؙ-rӀ !Koh wȿˤyCd˭ڢCmycV6{*ˏ'Ox# ѭѧyPv(:觃uU\4m$y"EV!U<W %۠ Dۢ5j͛6I*Ft"iH B7P_0>$k cHQD׏.tʤ0;HWUq΂K 8'aϼ7}+E]qaEoSokۥ/Z QPK7ERFBUܣaF j=7Dֵj~gX)݌nUxLV|BGXMv4b%4$'"Kr"'n|Q*2+|ZIpDN::QՅYteo>m),;s_ $|9oh4MD =F " l3mKQ1 9ZuU{ͦAf1`@N-yIjC&koH8_8`#c%Paz}-l~N쎢"Yzؙ+8Ggt4rn`*X+>sB>6P_ǿٺ7`Nj;pz(q桨PSyYwc{"!o}CD yZ0$ 41TŻwqD46,S\3_.>f Rs&G_bYy.ziE?Ww;%D/ 96gg-q^l\ IVb+V*dJIYγvO\~yML"-=<K8:u=xjrʫ?pE1c8myirtPRL"8\.]EaU<"+MInɠ6焯|^N*cVԦ̟ר;I&{N&ɸ3V)Ȥ1'6&F>ˤgr`5Z- Wvl0ƒkT6@Zc OҸZ3U|XuZV$ڿ0=* -jt pUq=*̱.JBUFhpBf/4= M'TU"4' ~j2=rFbçxʛU2.W|mV7R\q‹Գs?(JX`ԅ׏/-\ Đ2"HvMm^em{ʃ\K9 4ogGvrhgAF*jL!4&PTp\XZ牪OAvuqRR 80XT L_>J ]H|S|%:PBp@FS5˕+p+r| b0+'/q{LH ȳ%ţ;njhC"qtۀt ,щtXbT{60K R%{zCB7pKI=qT"MnĕJ#%CƼ&=M _ _~oI4GBb!a U4 vvW0UA&ZԥA;".ZÊG?Y.TNk_WÔw<Ɓ p]4JH k=?M/+X\~2mޢ:A3obI Y'eF%քffpxzBw2y}2~m|pٻ@7kG̑<Td7:&Diq#ωD$N X(hS!'M[ fViKO "/Ke?kӋB*Y_tSG N |&5v[OG+Gl 5%{R0|[}"ώ `Px7(&gJ^hҨo,,xU^7;4S Gu+Rq/ Nc_)SX\PGD+ހm>ڌ0U_;k9@I#ӧtDe2œ Ļ)ke tys\ 5( :&7 dͰ/s7fQyMO#ƨIX oƺٮ.x4ƤW;4HZ% zXTTW)eipZ?S{g؛Lzb}(9K( mھMMR\^s|`[e$?Zzg2RTry]MhE>{՗Ag3Zo= L$}5sjg&̞M* 4kR9 2bNԱJZ{גlUdMM R_i(9ᙓ䠉99,j[vEshevդ\+:ʩ[I13`$Cgzi ;\S ;F=,{kyR 9Х3h@C:ľO,hF-K!QvތOWMSfK|bg-rFC @b{渟f{a0Ek9y\ ${FQj%Y(U yu~kͰf0t\#%Gtxxz=>,ecZE= g ] ρ_{t45J 8Uޜ>D|9Q®(VRT|oկjrex82<GL3`yh ,?|hȿם_<5_-?oV [;7)yx؀?\<󿬫+c3gӅ7|`ף>" ~VGs#ի{mò5oj-B(7_Wh N6kG6~bfJO}>$f`ί ۥeBkDZ%s4`T k^FhX 9˾w(Ӛ㸚gTL13OCdBols$CiVlUﱞyi'[PYdb0n='1† #N]nBUj< 5Yu$hyXCd~VIxHZn·Dpν  8+VZާCx=q 1k7P#c&#Xr`O#I M(s8x? 2,>Z$M8ԧ4ï8IJI][OF׆b}K 1[ǔ# @e?yS#XMhv^YLo.U6HtH@cIJT.H,G(@,ʤT9lߡk˜EűWI̟+-NX.rh`R RXlrxxpc}R2y3-f692 Q3zUdVV-b 0-q 2H5ufBv)!r7 NJ{t/TB5_\!eb_g+:@ K14Zǯٹx_;ƺx47(2bԞ=sÎWS?:ybhO:9@c5, ȷ8| tFV"\C : c2rS|ĉu27/> O-Lx"_ o¹j_ʁRঠpMN;$9ڮ^q[x=<ҡϰDl}w-\# =5vEw8VนXhyZ "O-S@(;d:$l'{{EOA$Jfx3aM$Δ'1F0"ljbH^_4ۈṼC8#4EמȼuPLƌ@k4 ?P5|~~+4 HtxvjETFV1A?7FkBƾI2kR𹣑㲆HZg3VԹP얝@̽,v.Q3^CAD`&_?a&5sf)c޳UVWP(,9D5 e%=d笩RsA۫ F +_W)>Ww,L{~{*05YxdD#&[;<7M(mMJ1 +s:?KeM&Jn<ŦkPKʨp%NMtK[a]M`~'ºݸi8Li{} dQUqc$efwmx7oZ=2>M3*({8Vt3!#Yzm=t,k>Ulѣ'3)*N>*Ur 3N# 4%xk}6XheyG(ja[KW_'d0^Izp:ֱYRƨ ;,@B|-M3㉮LƁ{u SJ^B\E2VŇ{qR U BI5m'x\ۏRs)z{|v݆iCwx'/AIQ7ųV){h6j:n{82k,gę<7zTl &Vcдd'aT5, ק4"$UN/q==r`VNTJz9uPC=2*'ޙաЧBz@q}Uk TS֋v:mhsw^=&jo пHSQ&@P$E8G2WW"hyظ@J0., _y@@kb)y88x |7Z /y~42 N=ylRJ%U?˹~p-b!q@l?KrOwi@Џ ?o  z6K[jkojcsgy '&.~CGvo!o<\`6N_{9~$ _{oʘ?) p;0Go? WnU$̷?AyD] 8f,'l}bXxN C#W}. :?eZ4WLb*kgR}zUSnIW18=Ÿ rXgSrQ;ws_yoQ쉽~3pHS҅@ttvzvFhV+p%?6)m:S$wTqN7/,ło|hfBs/M,w["78L0u]]\~% TQ<Q{誈@&?rD5M-ܴE{&;&c ;1nɴtPcV1C-lj -.[YVEMd$R * M2+̶`lZ8ZBWk_Ó:UD OYxch4Y0D^G⌵>{Rq1Ƭ[|  zpOat}z2mӾk6*lYlVWK6U]i^|.AvE.~>mM4W45SkH;H,kc׹m8 :3 )Ɖ#f!˜"2`DAM[ va7<-veHE>k $ێǙ@fn.N>^)26_jMD`!}~(J*׎LW7S!d2kr]y]e9 27l'dgRqJ|ʋmeN[R'!aX bS^r=Lsrem_Ml~ӢK8mD:p oOjkOy=Tn5ݎ>ۛ=ndO& Y=R{rQTkݫ6Lq8px(B_RSzAlimKi0\gVfxBDډڝ/ܔ)f9I<B}4L8]6!xh |~j쵸-t祣mSA& tZIS:ʹE)ez.X20\*!:$~z2vB3gFV <& 8pP)Gq-âYv *4ok8奾e:Ƹy۾&rΐ[2@ĽчrvwU=LHs\@%])Ia7>2 ֵb 1IH{1/FOckoe%EʄsA6:͉ig;+o*Kpc$L w1ã@.޹fT㽡a}qH2X2zR,Q!%"MSW|$:P4Cu= ft z.1bɒ3j] k%nBԐr=MṾf^!=3ME@* &^Sh *Pn_D=RӹiA7݆3a| %YS}.PI33/Z<(í_ JTxjz 3+ MY,]]¸É- 22SC7>jXi1҃7}KmMAXQq |/P3,nK0C臨z}鄡ȹ8Agz}5iKJ=T,ucM4=ΫMqZa4{5ʑpŨz J JܳT1[MW6k:E ˹NPIdf?RBY z9,C+%uB"!TUFhstS)kj)^"j) Mu|sexHU8٘*^7=oH?W"3~!`_,< 23oќ@6A~>t#j7G0si!d㄀NCeqǓyL֐` N!R+ }d?yhH :6=>֌1 8guIQ_a3F$ȉY͚9c0K`_Zefѧ Vd4T`$ET[W5)FG'loT~!٥M郄mT݂^pmT@ҚO=ǜ膞nm X4/IU'd t!*gD{ʳ7y_ eST fm]!<'!Ԗzp6uaj^'ÑH,KJ(T/ȣr]7-`c1gsF@Y / }6oe$SިAl9NKo7{:$ZQ|{uZr~S͏b]Iol<$5{!'O(ݍڔf8񼒧yCziI*6t%NQw {׎Bz &k&L0R>æQUB6aO[BO;~&PUul 2'_1qi81=IM~Qe^iDԍ~5יxp9Nn&rH hF6+A^(.Z~=jyG^zXnW2f O򕘍ϻŬo#9*`8le1tRޱCp0C}Fev^qMR*R\x):erDym]D}?#p9sbKMc`ke^pӌ?@aDxu[vFH&`B˘րս;[KˬBXNEa3 k»Qkd^*=6V96Q-d/h6qs vK{!)&FDDS^ /J'J4XME\#Oh 0@A<*/?R \D"ag۪xPRbsb#cDyw\ݶ}\W҃pmܼd׏,F[aWH L8*O iAO*-A:f_D#N0m8k(6.Y6&;ŖKlgXKK]6ÊҭnrcQ,cH܍RP՚#d2X8ѕ;C,$&aIm<6{|=޹x؇JfI-V19Y:Nmi SHqNu&Y!A, SU G1-vջ/d'M>ث~!z X&8!̒UP$\2]u7G1c+1 Xz7DɄmGFۍ(u@Sʛ~7۪:LLrl9@E_V;0m}zF>$+~+l`P:5e?GG3vR!Vo:b[A7sm\%"^q=F`/#ic϶w';&qq>IUnwfQc'*0"k1mŊ|M6#a11\#lY1+#Ƈu>;_'00ˁ>;UDSY1BF<=OX|TQ;Rc+c͢]ME׈w+Za6.b/;DLa$HdVkmWFB I.|pV]i IbHLlEԵJň1 <%j0NJ-}Jm,\jsrLdJvo!\oߴ sw."$( ~.Q`q[MFr tWqX&Ljۣ8eՓ(v_ON{=C''1U0j;'/뼖hc{~g:a2GY<c҇V/fl=]N0jih@r NJn*L6z>󃛩pGye&Q|t+ KSSIqÖu_w4~nQe\׀F&LuOFލH}5~)|2mۡ+:6 Z9=yp[[[ ')X̸,F_i2Bj0 렅MaKS yeW^75z.5?jlr8Y+i" ?0@{Cڪ4ƫHh_m h&!cvҧn!z8v o6?[ O=ovU,l1V܎r[ɜG͸_}x6;,bRއ8#uMNN{~5-뻠|0f+=f]}}̟dUR*OTjh|iگ+?&G>;y {~9lz<^؋lik(.0 /bkyq3@j82u MXȯY߉ ' "c%Ϊ~s'~'8@l.%nJn.6ߊ'{ו-߷0axr}4+ 7'?0L6nnr ??w{ a~~~~A  ;_l߁ ُ 7/ٳ N(mտrB!y)'xnvB5x}-p̢Pز=-~A3MNDr0胙uYI öl}2TːjVzKw,v;ZjzfxHm_߾+YTdWLƵTu9R[:+^tք֡D7Bk3k4RWxV f|U}Q(V*ts~ߔO{y9zؐhE%U_F3{L7a{ib%R C,qFm?b"i슫Wʝobʼn*6uYy:l5G3)y}k_H3ջ1 ۍJy㙆 )-<)a3L UV6rlM:pȼ !olLXBͿ]d 5 g՜ ^Um[\#zn3.t8-@bmF+ %kyF C=uZћݣƯ 3lꎉ(/^"[^ppQZW&c~x%Ot$hRcҔء5M˕okŃG!qLqI;peSEZf}[0V6}j-;INҩ`]λO0ͳLi;oaL%-t˜߆-nˉIO1u22^$Q~d>=F]|h01s:=oXܜMRޝ_`}AZ%MOⒺ5K詨̉饈5"t#mȋMd*-wIi/#{Iԧ)7ȋ>>hluڦ2yIIlu .m"s?fG΍BpӅC&NTͯ_9ِ0 ze6ɽWd(/Ӈ 3-5S ArĦp=]B7QF)䱢/Hsv8wI(B6$ STZ(sl"!#u5C>ΡS qkZs5^=;醨,1C 7Yc&Ni<.B08w^ĨPIDb %}>CFld*,v}Hzƹ2KN)V)!u[~d-6ώN(cf]L˕#2^~ܧ Z3$3Ub@+%XJzڬη Ybk5^9eoĩ1.;vX xuF2o s~ څwrd?Wotˌδ_L8 WLqXF~BRtPG'G3tk*涓cNG N5WB7]$i`>cn^#4rvҁ"TXGSˎh/ݕ'/U=3]3=PzCӬNJ#WQTnN`Rca o5s0sRSә v?Z!0ò޲aZ.IIiCBJAn_sf㹮9yv[kuycCAآk`ﴯu׋wV/Em'~Pu>T ф#zu IT94 =u`ZJ!Eςpzj4"D@dXGI*ai +8{? ,5'x."gQZ84hb8ݹ[.d.gw' ?Vm Ph9n{w}{mg ܯ UfOJpL[tQ'N޲:;-.$k{gw׬`5ɀo3 l9I-HIcN(kRiIf`^4Y<3bO_߬#$H͞]w|~rKx]*ԂAQinH3%)+-+.?#*Z 7y"&Qw 7Ś dq?Z ^շz_ ϣy!OGC?I;^h0a?"?^R?_@+_JiƮ~o 1LXCa{.= MI+`"-D4E"GVI@5sLhr 6]pR"*'UI]'۳Phi$Bw.1qsd4dž 6ũ{Wx>Z&,,8kl;>n?s]sq˒Ҭ7|dތG]{kȖ =l{>n'|0rxOh.+BV@e<)nInqiUa"<,kw8"a&^Eɲ̙$hfhO>1Oz*A>х/Ծ 9&]$ƲQ <(@__Bfs2^nMZ>o*#Q~з>xR8B|@-<ղ<*JK*fGW 13+IQI 6c0ԃٍk'm+Ү ݻARի}[C-atf.-'L &e iq5bVܔzV6$Wcܻa=pf>M߱Y.H4^{Mal|*/ x~PK%ұ RH#1/pXykBFXqz0tǮ%J,H]lHe~-e8 y\)`@>dGPc!i۫^LJIÞ ;c^$k[P@3,ѐo NjS3 /oiy:Bށ;TiA-Ԣo;2SHojCa*vkEtq4 IT;8RKKwG6uzV[mո ?30}y׉oɞIm.PJ'pLGF,ARݛϝ#~~ttѤju$zm%FHqZD 3>F~sY/2ԃSIM NSK_+y9P!ջR\𸛵 2I5<5ݢ)TivOoj:ƮI,` jY.Be2=ĘհׯF$x-}ęOfP,Lqi* .xn>0Z X;AresJ&KJTgLZխ1$[WRxpst6"BRWEAɍ4uj0dTK&I'n0jJ!>*vHya<Đ7 ɵX ߚ.ȝ)p)ޢUb5AbX JF+&ռGdv&2wK`VS' ӪwvǴ.+۫<&=TO‡p2* $R4LɧTшttԫ2 k{v: V.trAm|#W7I']F!cG+.@Okʛ{I(^W.t<=J2" |W=O灣cYʵCOK~h8kF5@4/CP-L[_FHRn֕GQ9^/vҭ!%, /&(A6/]2aÄd.gN<˯%ݱmCʙ]с}FQmd,rSW -)6ުy.ߊ}3>ydeϙ /o9WQ+(H1@_#L78yWA^mk&yyl],nefmp2oJw yizRN#Sodi$i6XK SBxŮ`&nq,~[h8d)N7x{ENvE53OmM.3Vr4Ě+sZt= ;;9cs.M}E\{9*𹬻CXXfTXA0d ŷ8aYīTs G[= c?\@Heؐp'{Rm:chy*aEI1Z!GԵ/CqkZtG!:S\7$"~2,Qz c', [y&oЩ^'w,Q+^~Ce7s +=v7й8:@t''X馏A*(uߣ4>,8w1pQXrr3>8s_Ȉ#]ni_eMBc1gy+6MǬUр#pԇPzUC&P!+Z{]e'~9e>y0pj9t|}s#ro[{ch&Yxx͙YΠ+,/z$B7Dvݜf!E2Ob.蝘nw멂jy[2fuvW'Ln@f+ߢjy,>B /V l ,t[Y= 7ӿ>qXI7Bm'dE.}㏚ז!SOqĔU97epp)]'8]HɎ6AAg{>;R@ŋ´lPc)m&#nAsv wn~8m͂aW\Vy,sO1ޟc_!!!?? tߧ?0/vG_gE1)o9:ss0Wt^ @ )oc˳o}6]ٗGQDRgٱ~bSJ±eЌtqtأ[F\_cqɆ:j;k=D0{F9/>|͖6ʗS,R?i"飀67~i6Fo)3HDNTU*p~}&%|P9Փ:ft=; >1+z0;%WK١`WkRmғ}|F],atWiDlCpBʠ0RBӂ.b;n⠶sՆێV]&{ū0q7H.Oe)1Cw/8w kx+X0'Pnٙot-PYoreslXqKơj ZfPfSmR$Tyj)dA<^^>!MKL`¢ o/Up%([EP>WBnuh$JZW%HlxnIR_k)(6 Fz`stǪ'txF.̔΋fQۚRˮr%VV7Yɜ]uDb\9!8(H dGzdPUB)2bu`J'g,F=I4M_St1_*({HeKYr#LzVIyyfnj\4až>oCzBʅ=Ŵq͘N :!'`23i.<*e3}CY)i0i[k6:x!B>G;UCfTOJW8r >ҡ+.ovVSlZvwG KoF5 񲧩/':xxU(IXEhKq2OLٝfaO$WoiqiSX}b gGBz'RuVݺ/D<; tNt7i^?gj\T؟ 2ape*c8:/lf5eO~'{1Kն6ܬzp(/PS -E϶./|ga9PiUo*H4Ԕȝ@ʻ2!->H wODC \E&^l# i<[Ee{W p?̵N7/ N,k~rjd{A|:mqj,0۩22`xYxV#tv5"[ Ht~< _,FpBb!:g07$3F:afR]噎Sڙ 7BuGhl33;VVM`w=~"-Rvv51tx(ƓHh&ߔGrh g_ ɯB=?/>41GPs ~/_Bynw4lg8w$4ĸlN&ɵX$*3OP$nemy*D/(=1}P_[#K-,On0 VH<` t2'LSښLxUEB't#,*'MJ&(Xq.e{5}%2 'kQGi[阊c57+i a(~}HxDQŪKϻYgLeyzƒZ㝕=CcXѲ`?bԢdc,Gq5eY7sp|Y֩Ra>3`LRGK9bQm:Đk6*MPjsa)H:\'[cwT)3,9le-v*"nx$5H;%;@TԬr)W9v!Pol`7ldNtK| @_UJRF:D!Ye P%m~00AhXL̡u#ּ1#D<9_" sӱW pjF1_d_>{!bd*͐ʨBX*~FC iqӴsRUQtq*E3hu}],l%904qf[{%nb&$x׳7gA+ imRjؘ6 :UߝH_8%XM+_z=0;`_(.. (D GE̳K!Hy}g5Bݓĕ~JGki/&Y4jwY/aڹk mH轸Dt8OH+|@ PM?ץNՉS&:jqtt@Au_7UGSG3XP`-9앢rN&ZAu:IXjLZKjK>> [|T |gF-FHmuX#c Ǿ"BwGF½1gO^+WߪĩW\}؍/MziGoy3g' 8䏌  ddR @<}o? _Ep) owޢ>Dp}ﰏJA3տGova6Z.,;ﯔ(̐m8"Xu{=,.[B'hiKgE ^>X܉MδԈӗpTiٜ;׃._>pQ~ B(EZnfrv{-^!+_bB~2O[ wC!S o>y h ʋOGn6M+N֜Qؽ7 4/>k V&7+=K!.1ba/+K)+KWZL5ٛBl_ȹШ5Cn 2ھA\k&gI>&n9ݷrF+/IXf ֻa^cmr3&;Gu/mJ@MiÂ[F=a'fjS.[^B-joΔ`n?"1@\o%RP|F))P|mk1Qm;0Se!sWkh2K"#JWu}a]S~e^07$žEAp$=(qVoI};q|6,gߐɮ iX$~y S'g*帨YY]֯\ѽvFЩ $*H";#:g&( 9xΏ""] {zbrK }9*Obڂ{R:Bu;/yGc ^H0:y̦gD7J]jB!c+X;߱=9ۿ Q).julPF7NZ<=zb "]`60ӫ>g>sd1@3K_YLu5fo R5IZ,k…_Ϫ/&Ͽ#,&ޯrY!;J doVV l碍.Q@`*(2Mq/\-_pڶ<~tDJ^n+Z=|G\R&4<2!jtlHH pMbN )}f ˆk&>@$YPx遖e5+ށ֕]yP5҆wx56~)7sZ[Oҭǡ'7c`Yu\O\]a -X nG8OWƅ=[[,e_W>Ed\^i^OȂa?aj=s~Nv k,}o֠~|ݻ5wk/ܭ?SH'l4?^, |U_׳%{"F}|6)w5.FyTҭ^^.{Sc]g].'7\SGXeuz:KyR^N+7 4I9$ʒ?}tm#u˭c ܔS%-l+ӯ=l5FŃala-:5-4է}YoW}?fFzݜ=kߚ~74u]ݶgwj^t$п]DR[hr20tw2?"fb''4Om;OskԎdD Ew,ע/  iJ/!dI ˺!zV0YV=*#Ǟ߽^k1GUN\{XJ+?LjJ2|)6)"ɴ6+L'pS',Q@$L6:10Ʋ&k+2$ 1OwEa3XG@D$ulq,CUUlP7S_,pU ~2RxUCp7%%hUV6ޜ^lϒ=:BY$LM* y#Y5~ۦ2'zTX$hU(vNӐتvYhbDpF|#񵧟WOJ0]H#1)q+k](`{@U,FDBL{_r"Qi/#Kl&ͽWO B|-6ftcB=̓FvfDy f~|Y{d8k6T}#њ}.OKro+oξH"ϟesW!VX#Z$A;1 gOa([+E49=I!W U+f7vw1zޒӢԂ[hOZPńWUf_3>źSVo:ͺoq}9{bWx쮧 SWƖqtF1Wb?Oڂҙ2Zq!m%ᇊإIRFHj=W)q.s%P(Lgsj$@n#7=sC0Wx[^HSS15F ǙQHˈ:@WNma7tnZ7]Q-˱WA6VxO1T<3փݼX^H֫Eb#|l.|6N*#7ZY.EI sd5hm}> c?OV?n=n @>`Od9OKYk TsՇէTÍTrF^zicыU;]T:`D^Vڥ@t)_\\dx(6fD |soHz̶94%%\Nd_oȒLob?^wE#K{bBuTkNV'⵨h׆yҁZCI$c|3QPϊ\g8\;MڞeΡtۍ"A)>ʅ\>sΆpqs\}v݃tNGS"CL-bl}`5+WeϨGqŷCdд% w-fy}%Ip)Y?"xMEL5>79ݬPZP aA0ԩXXE #9D;}Jʛ(X^ &Pt SMkȠJNprB٥! c(SMr7(a eܮ|=*!՞|#ǒuݏW1-ZjqyΠ%x "A*\%'n2Rź5oyĄ1vZ]8` #\k1ZxT.nHhKv*OkPR1IҁS3Y?>'b.L>pk"hӣͫ]UaN9THc{MM>}9EՊ̄^q&N҅XAUAӈ./^3]lAM4R2ܷ >DQSZqkl Qہ @CbBLȫbJ6w|1 N(1Yt0iMxE㐔 LRNUړn|#{/Rd"rf%GpqT 0.cB$SQ8BW`{sk`QkԀ ?=IXRt$~ytU6bѺaVL>;܋'/̼@1E3.,#w<4!6rg0&wsY܌(fA>H1u46Jr̎'wL!̚[V{ꆇu^,TY7?!PĵZ4Z"oYP*e%G>S3,JU 0$z,gG.kl&z5nF:It9hmbH<\I}Pbbi)̔{ӈUEºʁөE/H$L#ijb Ycha9+y>U']7Uo*\RνWb,_pɫiV&$2ZvH@292U]D.b /,vM2]@J@I@B9HF3.q:R{FLdj&:֙u*vPnH|*_>A--M@dU+.N#zG1$ =xe>oqjGO}biN$p,j@pfnլgdmxb:o5?=C RYQ?N 1>& ,3˚#/QuS{I#Q !bĩx{q6zʼn屻yI{E|e2Hm<2e7X1q3=H"R 궸WP 奰"&cIL W.c\NO̥UR_>ޟN,1W=67]:ujjL}ɵ,<>G&i]J8\CBb~/A5tr%sG(7X.57?r҅}|kk|` 峳GG# T!]vDe}r!S'zM#ɷzN. ,[)͂Y|/XV9_} @}h'4/\ ?Il w)<0￿KA~̃~=i }>A~|g4/dp/e\g288aߒr?&F; ApB؁ m ={HrB?B@_D /A( Bhy^Oꅰ~wJ/h<@Nد5 AJ / H )ԉߐo6=i?zҀA~@ 珂0Ed?jMd  b>OjQрǚqsr4 ^=ůJ&ox ~]%S {"Ce  G?>ޟyϽIш)/Eh?~߸~" l gzh{Ec  @'X$A~_A@/" `~E/yx= ~ 잿y  {hNfx7x_ T@{vEH?ݟ7/xwy h?H%X ?{=t%Ůiu4}0 '?j:YiCr&r՚6K}97cX(Ui5kkwZn_xM! DO0ˤYv%1_5, ηD bVBqdO4zA~{BnsX˂A)o_F-‰g=#o.4 99- I:Sl(?^jhh\'+΁ot`(. ;#z%ղcd0ZtJֻ%;2ԊܣGd ~"] {>tSe"W͆m YW)o\Sw V}EwC.֣Yxx^ՙT= W22֡ǎ|Agx2Dĥ!*k88J $ϞTi- +,SiHƎxx7Xk4u:ٹ[{6mY#/hJNҤ8>Tn<"1ffL1S1p+T/8=`Ĵ/EtI3FqYK/Q{~Mw^ GbQPMUYT/^- , yHMLLҺz+W ݘKp}"-\[_J09@=8!^ ǏQ?rU%i"?\k~f59I 'y<2=xԐ`Sicr T+Y >IHItQHrnQ7%a-W߶uZX'KwmH«DU4[껇W"YZɰE`E{t6D]cY11VU:Ѱv5 4LプG ׏b"…w )@'vܣȉ@r Z|d A܏oDu !E0\|3>֤Łz}`Cj 6knoT+уO,O^>K +LD,Ġ)Y9V=W|T=i7 1K`@ v&sxaI2tCFʹ:MpꍂZ ;7)1nL(thb'ijH @yGZGuCkesh%^3nFV9~ 7sz(x׈z9'҃궞!餐?_M64y?ќ@1ZD3M4G8vvZύ 4<)(Og 47-ECϬk|9scIx bOZnz)17)vlfK5(Ѽu[f;y;$Uwh|̮a[G/_G'+q(>@RlFWPvF߄խF"5b)Iru׳,Q^lv:גSqw[繰#-RR, ttYOyM&S 7^Dvj8h*4N? r 0D wʌ=+]=*Q 9*벛ѡw3a"{ 2)fyS?[*l$E,-mMRݼѰgD(S6t,TV@Ah`ǧ1Z$ i,DReٛG/8Ȭ̅Tb*xjfØs&24jͨ9ѺEm fm5dP\ bZ1R[± 9`Y(? !C۱Uq֗fޘ[{˨k.E5@H{ [p[pd{=I~qW-Nq}>S1.[py+"ciȻRzg3}]lI%Z! HⰩѹZ.$d0 !#Y :=w;\5p_эd`5r/O~~鍥4xa$5RBn@hԓ\plJhs2Tw ;9S4Z.!{Zh\٢8t? Pf}[ :ES4{O=tg|!3CM3GQ@LȆUx6~`A,TڝJb.e_f~M?Ős!%!%o)s2mXP[1 dfs j}bǠE dG W{:?RO珻XXYgywZ^Ko p}W<_l,~rr"Ǟ/bvW+-Wakb@duhMb͗-,uةe DbVc-_[c7:Iij'{H=2\FqMҥiBF/8UFM+Qz4MQxֵ:?Tg~Z2/i%Lw!Gulud]_\ze7gkmzՔ"LUUgpXc3?D.®q_CI j)SθrfpܫO.р<_;4&Pk^~{ȌyF;WB DAsn@"FXo)l1W D2r\"G5Dxֵr@6%nPlvB~A@ i,|d)0*,Fz*. "Mc" s rNUnvPN2G9fr{K(Qh'8p+N .RJ.. %Db˓\D=nn۽Q;#`dfM]&^RJWv@(+.ݯfuӮ$D.W+控]c;!LUR)L3RxSGɧ\r+!_wJ x#CQv?NmFw+.NzʐD8IjK^&F+qP=u jc~zR5b{pWg*krpi[7_ajSLh[}vg_W]AJS82K,b-G. A?kӭnk |N)Ơ;`Gr'YЉhʕvbO6`1Gs`@OH5[+ә~CvV\<&^bp {p0e e؀x7IŬ*7ʔ̛[YZh/ЍPAճNhD]BOFmW%CvM"x%!6CA7oRח%Uz4JzFX)B* |#yL9𞪉t1>tyO-+&,9Uh|aKvPLT܁6`x4>Tֻ\?[r5];~U07 }J7Ų?$1'N,̿r+V'V@LϱMlHkY5J:Q0--O.׭52dIO"bA`Pj3~L#)B9~xt$@ >J[X#,JtbNBS@ g"(ffTPTsk#%PI6'9oj6\7 g PS)QRͭvSSzX3dWJv~_tDD U3|-"UK|H-)X1|6͎ Re۠| |<0k׻V}ZR%QN+&ok5?ƸC7/Ms/"cݭIHi͋\ ?I̠Y셴A|8nճa9I%I0hg]Wr Hn&_{Knhz )YBx?PJLxDCZȂuP:#A"V6Nez dX8^7gc C}9A~a v"qʽyQXLu^ "BQpN*< "d-+ :ڇ- aN@IM$Aqi`&IymM!f@9xCecΑ[R]|!lRE/<ޅے'[c ùCfiˉɭAEw1 y0ix2]ߝA+i W7v J (ec|Pu% GLV>F5◅ҿ]pd"rKHx[AMD8p28s̆Ƌ􃎗o>{,/ g~ԫK<rH(Ո#v ^Xgq3B:`0iNR"Rcn`4ir=6p.+hA2q({ rf^0J !|$4,&7ymIt\uD,D4v:QM]K|Ni]uOeq\JjPʾ$vĤkg{ծ9HZ;Gń*:ne(F2)>p$|V DFy.RzS~eHvEJE⼎|GDz,Px̫&qړkVbc<tYsp$Ld ϮY+K#vwHѓQ@TЯ6_npDvxr&Wv2>kROPM9uxHo1v Vv=$v#Q@Z WWXmsV4m/N y!1egrS[ j9zɜ {cr6{7l]@/lb]{ ɑ|mWhT]ȣebL/h,XaIͅAq( :AY}ZFX0^ 9gD.†G|xu2ܝ#M ˏGO(A*ylU33g[ DM gt tG9okMwYۋ6!;# ?}9AP O<R-n?ےy/|okZD-6< E^ԍch3 1`MQ$_D>:-ƪ"FKYN!IpWG1SGƭ\'nzLbhzDLCuNR.(erΞ,p"k[3JyNwZ|WuAwF"8LKBuAbmmG$h4; cQ5 <:R斫a7 aԁ ×r@djݬuksZj^t}x%M[ > 㘪+lhs6OqiEwB(OCB TV/U^! h2A M͢Bba08EYeJh.pX6}$)ȏ !?ꅪ`k$<^.hC\ ѹܷFii|p88orEL/X"%T(/׺ʞVV7#`,ůRﻑ>aB2 ܖQaҚj "] \xMZ %1YXzn )oM] 1]y/WÒ=s-Ė(zZ%F?3䝂kK"54]>B?WR.ӔI[12RN1ܡ|o-U2 &k*Ov[cMqAgS"B6!gct-O!vr]uh *w`9R1ljZae?Z &Ʈ+ >L$%YP j"aF;EFQF`vW]lS5DUd Bo e7=֘9||@ 'rY". !oR!dEjƟ*-.)~"; Xֲ3UX<n9E6g##u2h`c$%\LєMDXU3~h'iY'upR|S;BH/u ugB @X؉9*ۯ1%]lӑ.'r4M;Ӹ~o)l;,PT$6iQ}r<' H zSb6w}:^> Q>M StWc% iLljx0U<$V^wgpX| shM.ap=p>ixûj@)CxHgPxƱTT.#?oevė~vbz < YYtPnXl+B.'ӨYm׍lf,Fw ݽGm0(e'":UHvQqº!D\8Mi{kO ԉ$X!ɽq( MOh vZᗠ?K~g?F0'?`:Ivela.;d~T}K[@m1w Goa2r|K|YXY!"*S][b;񄝍 ;j" s#' ?\߭׾}* g k}L,3wM̿_oLO #'39}_dw?ׯ,ݫ~v ?ȯ]43ndfdfy.D,?sC[$_0J/񋪒V8uj'u4L G73`5/ p7ɹ'.f$OŌT˒RJyUѯ *{bJf /}K\b1,YɅ]- K=BMA< SeBmf[ί# iE /ߖ^g[[6w,ްҞ:@zHg9_0pc&X45[Y"d }qclFKAdiPN"&d8TWapl..txZ P0t:AzEX]H;,:j&RF=uݼԧ4$N"h,/1#Ds@r> > \'[%]lWpKPˠ`3VD[] #_ܒmM>5T*] FW4ʮL֮r,DRF 41# )j:@B4._[|գǀSb"bR|3]BYA7XʲJ(ӹ(LH#dAI DF/bObK;%^ 0=bp0Kt h_dMq`g@x'k`fo"#ooF.Yr( 0.!H=fJ Q9&QF CJޘ cNs\ 8W쨍d7vy*(7轆CĜ!Òb2cG^o Gڮꅺ)H)˜F4m;܂>;<}*RƷ o97tzn D>ُF?lhfQAqçpBIF:Hw_x?utS27]8 $#q:sk0}&0ڃ=^cEPZE|": qˉrqu#z?Y9Gە2q XzYR} |E`MުL,UN hWL~J  NᏅ77\*)+rdJb81㡼KN#L`ZƬI;(\ZrI p2r&4Tz 0Gfnxc" 0(x~j\bN0Rl q[P!(69;朱Yr S׵ 4t h[Љc܉Fjk/a僮.gO~,.$$7 %(eKƐ"b'GP+\=c@#!}EWJ1/F9UR%Y'1)Dh.s`a#yzoa[78Mxg69W _$yX$W=;9Ku;֓h]P!bʸl>,`[^|"Y&g66NCZ{3BƧB a%^,U#J-\pYo(cPc,WDkXfBUV@?RJÌHe=h--T*m_y|5WB @вjNj߬" *EaNKl؏eOFM(=Q gD}lzվF_짪O?V{p^V J.~ cm l>`03~ ~\z[%ețK#de 29XoE8O k,?`af !?~tWv[?GT5[[9Z*|)1uD'LCcgXm=$Xjs֭7Nq>dܩ:z}Sz2J) lyɽb6XTQOlÛ>B(=ܟD­a*!Ih][oc2T8K(k=Ԏ@@5Kڽj+Obku%Ƥ5D*ҏTvhq3]~KimY%C#9Ҥr_b' ZMkr)Kx-R},obT,gDjmxqҪ7ۂxϴ> [fimlGDH&d]Ln\ҹ(]i 4P\AL1I`:ϳܫ>ζ "qfq/%j@fD1`w`O%&%U cB0逬T 4v&ELT7'[Z2/A.0K =-2۾9ǬTqB=b_i;aCidh;]+gkiVAso`k:|ǿQ3~x"p}d"VC;> J-nI:>(](ĥ B+$踊(^B,,li1i 6rǑ,P hVۍ PYQw,Q9"9e*ʭ+vgW$b&]5C#P]~ɋhVad]kʠwu[`GۄJ_I*;c[gwB0,l"zzcgӸNJNP-ɉq1[_z s%qUTR?KtQғ0 qkԜÛI)Ӕ#RtP&5'y [-nSfطV(ƕ uZCP-[]*]neQ|10HQ[(}3\Q""ޅ0׃|"Cp 1 `Dep#rq~gZSxq5L4;]1j?los\/4k=RZO3NIɅ*iW^M%f˰Lmʫ0C7 Tųj Bq>繱\eޣfp[UƗ΀I)mg#u;&Gfʽjg 3 Os>#fz Htvg S"鴇_Zoh)q ucV5%V@e\om-ӇM! g=VR=ǵ .U;sZtgyV X>zyY5(hE!GYejg Z3z̎̍gkAy PʦCW/ yGJk]BbLGovGv %;F&+Y [ BchfI4-{DgY"?`z",V6&`p'e;!2HH]WeBWuyY*n8-,VRtfߞXE[o<1y2 Gw\U]I؆kk6^d*%aB:?YPKp&=-aӋ;2 L%~ꍺ CjI 2GNq:~ZfxȪi#6D:V;%X܁y:3*pǹcuPN9)DaGӌ(+*J_! p̉un3\Sn ZcǼh&"zk$:I@[Cȝ`E{w |,7fczZAH8XOq EGܟu; Rc{u}QD2u$Oz.@[um .ڙR_™@ɣNÚ)6wѹrE8q=t?3RWXE]j]4:>"+{(Br+&Ww?AeoSi~ggr0331+e{[r7t`few_as2pV ;#;?{lo#.={\~7D}_.yN>u6 }x:;6C|,'MN{p+3bl.Yf4fUf%*PG ,1_O<ڹ/q i$ϟHbϿkz†jXmCi-ڀ`ur'5?~m(F1y$ w<сC_<=DPǹ^e=I,@u}Q+fz<o=WKyqF+M竷3b"<?(}j9EFUc 96[:*2멶.Ϩ[u :7y vx " Ć@euV2vZ+G aYڠ)!~suk&Ji9%{R;mމBUOe L1 Q3Zdy7E%it|!}nH(EڢEVY|瞱ZI KbvOB&jȎZό;:;~#2w|b `=`j@=B>ۘ(%0_a1k )I;GG}oT?ͺ"r ׺ _z5, I ;B}bRڇ.zF5Qz>4;׉KS٩0O:䬰0כY6hl)HKgѶiz! "Yfszާ7;ا&C$f=Ωr`9'iom~ľE֊`]ؐ^O6ȁKg.yT2uͱs8EBrkB.إ/RrƫZ?wü5k[h˿)<>ƧI^+TF;Cu\m%fvF8xӑLD iX%YWgyࡢ݀ o@ 8:l58IvfjA;mWG{)j'Fr"EW[ˠЫɹѓuJ5} T~ Ѫf3 fP:ܒDm lơ =^7[1`x:?A/g_~pd}D 2ޮd'k3RtqO! i!S:ž!UgKKlY?T) bCMXذS` >_Č!u +>}㋎0vY| *;5{r /=es m26{襅nZGJ>mA)Ax]bJLqdy}? ˭+|&gp +=r*pDs^/~N~!=C^Z1\.9q_DXI^"wIV~&,\q+ ?7  B $rӟEZVKLϛ K0R Z.ÒhϞc#pPEB\y9 5+HoԹ/iel޴0_1D #]N߈W:qZ .9qHN13NCopZINTI#88{LU0:r m?iԷC_>C3Bc{  D̆_ޭvЊ$ |Cxk_ q!,+hKAC ,gń!OWfbY]چuTsJ~؜o |bqc m-+?tIi)%v,' &nV 펈D o TruZ+Z $^@ tF=k\F`n Q2Hzyݠ"qgMYjDnۂôc)YlدbRxUszpTT&{mQ>[JV̫OՆuKzb'Au/WOa@^ط>#&UvzyuDdE_:M2nkkJ֪c\T|o0P&8]dN}Җ>G8zH]YG8& hAH{H$[3,XJ13333+RRL)fHfTsY3/f2m?,_ҞP Y0Wf伬S0L {v#+v|+رI0:o}&%GmoBa\ @CH(F"C{u=3-k ""K0QG |. Bnb*%֒*4i.HW0 )A&q0 Z- " 0d\zrQ5 hnICIP$$h/eN~ZNU'vQppY^QAO7=DX^%Xæ anݰL e=h߶) ႍ,Mj!7l 8UFR&&uA0<0w AS uTaX* o z=5:?D<K @h~]Y]3T^SsWK2ض xbuu5"i-\MzUkhG=ϪAv$GjyJ24]m=tրA5 5n@+y:AEJ+RTPs5^Z8=e. 9}j7F1fn6RU(i88VpdDhˢ1A {ygDa&W˘ Z0 4OZ (SPUA?'ki,k1˄F>ӀabmXJFҚj]T}((.4.UݽR Xz+(.Dh2=e_#Pg}+Hs9$}]܇[*F2e}o%a1$]C12;F`AuS3 NExffMF6k{D[sP54.}_ U OIu'wGC8x.j З6;=1 'LOҢBbxЧ24/)f8r`Fu1P* WIg Jz,9t-N-el|4z茲U`|6I~fS쮿/YE@"xr9:~{/[ʩ8&EKͲCw/hE[AEr]HZnQ-5+>^PEޗ'kӦ39$+n)^d٩$dž3~xdm&i&!.H/:&ff/۰.+Ն/6MɩpQHRemv6RGQ$7l/ cv'62x-U,У!־h&$ݘcH7u,eA{@ŽQսL0&IV)aֿx|癿\?^;3KP)V?#+>,7ImfyrAydaXUmj|Ux@eM{mԄE*ȞC u^QodZ`jc"=-&w|dpq0,E!N""H$O -~}hlNyh-g,͌o'f菮w{(KZŬ"9/m g?$?\͝lӯs/IX!@yXz"g|*gcMPQ7w{ˆKda|`KSghGQ ǓMJ" )uM+6t&<փwm9WQZ":NGI`DXd65"xƊKVzk6`m Xt!xG㦌*BXh+-VKAH$8w? yw "9+@\~3f*+ Ifp2&.KoX@ԃҦ}@v0j(]\QG9Y o1}=Lk~}i5Kk#2n8l\T}ʋDK/<,7pV(O\-'rbW3:ɩL霈AE4$?5Y%u.e%՘ƽªnчzih*,?.E FvXEg\}4mO- ۾8lHaЍ3ګOn p. @fHHRr&SpG?p"J uy b4$5tYHTϥ>K ۷"K3DpX'18?}x Gװ b$޳Q_R=ZGþHcnkd}KPNV*!EL qBCY-\"Yׅ8OӒX$VŬuACFT=2EE[I?6H 5zGl,4 &!PPaVvSɰsN-o:koze֮ٴjY}̛BLh"(? uv.-YH7JRq!u?bD;1*ެ5 '>A=Xi.9WkE{rDJ!!}*GNv ;x+m"R*Jچv a"K뭊ENGZþSx&)DtfF9~Aj` SZ2!gA~Gg&DRCVSk"S4Th҇9P% [<$K % *r=vgu%]M;ıtV=3}8.aWϼ28:?X3:[Xl]_ɛAޤ š.9qsHǭ4/ ;֦_\v. vz߻vFꃻVALjԸn /&5>m_g%?.|\$Q׺6A{(^K+ċW*+WI38c_LxLì8,08 gxd"MQHQl\_]Fk[ӓdX)$z—pS|]:&i 9w#FاfVS߫1$X7*U.Az^w׿<}@;K>>W| pV ӳXE=k B s2m#Qi 2-$#wHP4gW(&2=!ic~@:b Go8N" ;{}n!Ȃ1؜ A&Lc*Ё|-ъm6 G1E?.b4|V#Z"H)4SnA[}k@3/#VwODzmbrB A=Pt~ /F4z^ǡ&d'&j$+/Rl[QEDS&e˜#([aK{K1"i,$bE8Is[_:#do=vS\!h2ehَ/~[I&JzMlGrG>ڿF[o k@=2! K>:F}삅uHy~P|g9;6io' @opiƻ'7Y5W#:)Ԝ*ڗV9[mL}Frk~oǷb&FV@ U Hz-2MF*N%j9zdWhom7hIunJB#$aVek7t~.jx~B ?%ׇ:[8owO.MzE(yr#ki/|@@1k9y%[OG{8 ~0Q3 ̳M|& M p{{lB/`FYï)up®m..RǍZWN} > A"OML$d>QF2b+uP]Qڶ"l`X?Z'Wmx6bq[bB'`1ɬ_^Rq4-Qă{胢Q"%(,'Qr>-⢘`vyJ)pp|بLkH7rDg4, C2 JieCzQil Il ibP]Z!K:},gN=؎-"ݦkQ/2K;^Too f6*̄\QE^nኊ}sC]]ef8$(ly"ĝTfKHSisv"&@p "zo@uٟ ӴYbq^⧵PdA;o$XC#R~ˮ(6?7B]@ G#5kî^Ґ8SFG{YrO{DP`;\pc}mT.?n jxG¯Kbӟ߲i/ݑ5)O_*gl۔с 6_?xO#EgObM^>b3R}mBT~_R ,& F<+qPoUE>&萭|:+8RjWuX3YLcAVzFȅdws۶t\OmdPojd˭3g5F~Il~}14B Қ%% {}{Ϭ/garfy!a8cV]kӃ'2=fY=y: F w*&.8hdR/ؤS9\nI΍)DB1Ok:2d!)i.w֊L9=嬅\az;̂`M͙`l ' 2\y6r˼J>~s]Ε`jQS.*f^hgԃQ&Ȉт>JQ%2Px~+ac\ƿj&Do V3_#Qtme*s˨ 6V9V-٠[yզAAsG=X 78q<]LyZcoN^i8Ii%kt<_bSӠ_5nz_UEx=$ltjGRGm;0Ar1Ky4 ɬDaß3#q V7.+yv uN0N ^`k7m;dQf5Z4SJ=$B0*kOcnZ (:!xv>楳%xa2pȸu[%%|RQv a/<1:}$5 #gLSu _ &0ppsjւR~Ċ;<ܝm;+E"EC';x83C J A| k/mw8U~9\6r)2ɘm g@M=іOdݛyE 2#M!䡤]n؁C2pg]y?..C<y]P@q‰Uez# g/^:|= D@K3mW,jOP ؎*}a4h~ĸ/>ؕ֨~YEfMk"F)JI䭏V?\ru 텇r CSV9GPDޏj|Ze 1C,/UO$+TU(kinC.+OH ^E c~Xڜ@CUsAp)}cd X禮]H}kQKe{k\j6320(#Ъl+gOTY~ ^ݒld"Zjg<6y_W~2lb,Ox+[\ -)Ħ BGٛ/T2 :OV˓ _pcw+=ӊ-+3XX3q0u uQD[EhF KKH =\*9Udp9O~Jek@~B 'hCPw|W ]ld7~W9aGVq_]5xt{/t̨~{-/\Lw%K * r4[oQ.@"r~F ~x~:yl",NҜ/&~יMˊP5Um!09ԙ~ƣpK¤vRHs HٳTm۷݅ U/8`RQ~DN,6KjiYGu Xٌ նz=^L A2Y(DpD-7ΨXƪtkM龅fU`I?>BRA[)6/K7_}StN}?BZyڤﭠȶ t|w=IT6f`v뷶yqC^)t4TDTԒ]]?1ZNW ڧ,=8Yu{7 0 ‚+f^\46cJ ;2 2,Bl1]ԗyD>2~hЭAї{\R'$cMa! aGϔlيn;[6C&T9ZOF%$m\;l^rTҘCLM%))4ӫ@!*(`}Uћ-6ecpl٩^<Xˁa[%kwJvNՅt$T3Aa-jXתD+)I P%+Qb!XSD:LJCl>L?D!FUpZYM<;\aݎ&A ]mHjI> 9z5)PҤm$n Yh"`Pzϔش7^n+#FfdBP3}h2 &AC!P,ׯq-}qAtx H;,X8tgLx8"Ċk3'\r(aaaa q\lz#, 3ӖХ;czW?癝D18CDbE4' vccI (ٸn^U3qqw`x s[+M˂+y]jR*,*b4EO_d.BQҋ|HF2H0v@~}|f76]y^@۬cv)&hf^TḶ4,H7^$B< @=hT:y:sȅoG*ç~,ӧr5ˆeDI8*ՇxDЅC40qK2zv<-`q>L+yS_=n;!kXjV7s9.a44^+۩"Eͭru /y%+"hG5q3=ܣ5Yw{]:NpS:CΦޯJ-j;`qZktQ+KlrW\S-^8g'#\/0tO$tSX_g˚g(n:N=$Q_4tbIZ%n^!6L|('s4 =zO.P'U hE&QQPzg#2T]B),C"_i/3|C RjG-Ym{ O`<&# *GcTAK_E-ʼnϑffOEn8b{c1'pW^1zR0Hx۩/(`GMc/}N9#S_Ol$;DZfx-=g~-Er0VVGU#O~qذ<<$ϰ05\Vw8O\$T81As_|D߁2!)^V3"xDB᪑@e<Жo9r'|'ۑp3EJ8"B[]UcsR'ՠ ~DmKT4$d3ޒaJՌF"=>*\Aʹϓ= , āefDvFYԖbrvozꋙ<t @VA/ϲ* &qet*>P%!W=~3FKRVس?\M>yLgtH9<Ų0& gOjݟFd4tA }W@uFo~fu%S-O+o#;51EK3ZCn@z Nv$<%aZ}6Ԁ_EsW$*RMh_),vpyB@ ËFa{P;\3 uulmqG%ĥ*Ѐ}ͳ2iEr h)<.ۗ\}^3d--x{fEw `6 0vn]oޅ54Z="' f,EZ0ӖxW)Af9"HC$keᶿ/2."@Z\_!OwC|ƴe`˨<9ܹ]o49PS(~yi<_ۉ"ЫT 6*Z L$onXG:9Kܣwꌨfb?f~眆 u*jOQW={]@b}:}5:(Nͧ%iB8$&"ԲYY Pr DG |.hg2_)Lݨ+BMIqBN$mؓS!ĭs N"s ="pP-H]W2煪uLrhcM H L$*CFc03<\CXR_p䍎 9P%zUQAMl,]&'4[Օv@hB>]OmAQh h.s+]"ǂL8TCILɄ&#K4Z/X}> @hUB]UqV#.$L`HÔ9Е5VILYnP;!L?m/N̦I3_qLu=?I7I q 4!["-wNo20 |+̞kM|@c('WGp@iUiB#4,0{{~a>v_Z~ϷnRc>`iks+'IjH+{%ԃfxN w^хc"(i^r6U̮P?H,\\GXEulO+%p:-`q0|sdUGβ:gL: Cڹg4'f@~:oi!&Oӿd&ۿS$?xLbtd7NοݱIN8H`Kf_P=oױys45r ߌ[fvc݌?v% ggb⏗vS6cs ru {嫃c>|kl[jEnw 5UcHۡ^u+\$0uٝO!vrSO_5tJ?Cmtę}?87T-gf2Mr:jrqP\J!ޞeu4û]cgq[ny~fb[̡aVR{ aq\&oGDʏ1CW?|J;C}2Co|].9)B픬 8 cG/7GU֚SA}t\iH5oJƾ[6˚n k`Rs-ں`0Md賅uOD\f%>hAF!vn_! F͌. \eM,̅=4#yUQn睫cC2nUKI|B7-Ds\}Fyehl3зk$KB,ZiЕy=~-=q*t!)"߲ `U8U:C_\kÏ0q->~Тےѡޒ3Epif<SWlr"|TDK|ryfWwB k*3|MdS. e@C*?4p:z~4MVUYiv5j ŗ{7sr#ǻiW :,c N ލfP&~ @=Cp '_*; lmmܫȖkJYK.[%222&׀u[{ܰTnt̫P+q97_2\-Sb7INjXب֥iP2*h]kI 4 jEAW:MmGtkO8覰KیP&(3]R_f:rkܚd7xëx\ᗭ;x}uE[{}% 5^!\9֢kg90B7vǃԮ#;E̪O\ʛľDÈ+ҷ%z~ $A'}n1[\j]'9~AUmdzdS>$P[!czQWd6D GChhSjr4[q#]*w˫[ōX;E&wg4hdq΍I[աh2w(! īdn,!2L蛃.H;7BI_JB\H+_;Z55޸* uD$=cHjfG) t#vΗAZT39r׊@aZ nפo91|Q^wI  sNw ;?,ѻbtPּ꾐竀eҗ7fѦ҆)¹Fc܉BaIg JjT֘1dҏwY)xPg\kbb?䝦|[ǚrnj#J~+4JʄWnB;~k07UlŦ(?)'4|_w|ߵ>?EU2/:4Z.*KYrAֳ$&yc0˥/0To:p8d ?;LR\ 9P9x: }پ6z4sg0?:Y®R<n[i:t)qlB6eΗԘ/Q fÌMv|:)Hp_huRmI 粟m VD2uhEE# 24ijm1ؔ1j*e[z$<424$"#.2mc^>:$AjYzpvb;s٦7`[ h|`~ߋ0+]ӲP%0)57<əD~\ ǞFiߣ)!dw'˸8 #"5Հ:zkxLBpy_;ɗj;ۻm1jswܞzd;ij^$ S#J}X/E}k&bnjN횆Ԥl(ω_(HVl*h8ֳ,|OI^$- wrPKA"wP$X69pwcƾ6a}4huPx5?J; C+'~CaB7># !Sn>A9GvY%o K_8=ťl넒bqf34Sxy/}G;AnᇁnFd'T!⣸黾(BM7 "ip=?_T;5涡ډ96 uoؙpz߄M>[|)<IFN1d` qnkoW[ B~je)-gp6;y@I*!>Z0x|PRbcm=&qNK)Fųdwh8)RˏR߹`E-2_f0 pj+eZ}vcaN~= ct%psm ")LY2x5a?'%EA%ܖG5}9z7zBZR%|@(O&An>Tn7 4#'mg?s*e_Yl@\#J74f&U_+Wty/`߂.5:hG]sQUfi^IF=I1J(Lbh{NFi_g+y)¶#Tu;u:gC̊|aG2-:vulJ .I- 1%kz܋7 *: ׫]o HYlVEZ/NUipn Wۻ3~9\>ѥ4f5Ie~E\6R&2$9s=i'Cl*ѦpIc_-#z i NfV%燒o8b˓q̮'l% Aw$IIڛƯimܤq<|#Ei]4S]fĕU˔.kt`/,gxO>Ovvʹ<\,aL=iY.)fΦ}JkT+\0nS(UFrpQO_!<.ڪQ3ausg@zj|@.DjڭIY=Dy*2lyoiZTi'4仅4CdH٪&T2o#oiJ%duP4uJ3blyvø%\er+NwH/^OKzcOA6=*ң*s*d*_^BR? hA#Dj%E}%v[۷nhe״$805<]Ό'32\N z)ru^d&>3IF\ic;>B楹!_9WQhYzFdX!hkP%~DpD / C]^Sr*%|=[|S?E 5vyQ[ɭ>;S}ea;ցs#3P_XJ}'.#¹Q@z9~Qj7"í%WK|MbuOѮ>'~IO죜G*REVl"51 SNehżᔔ4^ipYN7M׹"&ԸzOϯ&7̣ϋ_Yp+oAt6{EyH d"tprW^lScƷWeCRа0M11fÀHh^.6Kַ*e /paPtME|ew`zX:U5sQ_~1@A [!>Gk8nj>gB\;j<ϯ?$Ϻ}yKS_AH/Z&;x99Z{6"mn'yٍhζe+ 扐kLnەS뜗QKiVSéJ(m%r޼bviЄ}ux0TvY"|vz7Cߏ-gN}٣y~ӦܾXaKN"!{͈׆< L'2N&QpĖ% *VCztRѝ܉4=̙juX4@yiΞa:Sr{p[z$ [>P"X,.V\c}sD}nW_3NiFfZE(-lI^N]-{(?xTK s~jiW)O˾(b-%@.@7ЄqZ&vM'f4\@9Y/F&>lkg1f 2x .ЩI {*WRwR@@JÚ耘Gh%>WKć ip vT!'ԫ"5%<5щ ?p!Ƹ+5)é왠:ћ.WB2dx-[ă=~+|*npx!@^޿`88Z'K7Ccn/#u : qժ ~GFyȌHvGϩLGr` MqO(z~?zBAN~dU(v:[]?g?A~*?2w4z/?/_r ?y3c8Z;@@$?I:aG-WŒ6o6pLPzN:lw3}#k:J0@t;6ID! ţ̘t n'1Ϩ)HB*K4Jl`KMZ}tJ~EAh<̏ydH'3 #w>n8hqSnN)h.Ol;$#u/0u:W1cr9h]5'f]>=3A~ J)Ibt&WL5b ^~lʱY+ (S4ID$ed4a-0]$54<)KV/?H9Q Hq㼝_5Ey3GP4;_kHYp M-D. a:;FlI6sȄl6I޻CsԴ3C~]cf\\Jf#e c(Eoi;5M&z,*e?")'9 OꬼF * (dHGlOB2 iPT賵u,7 ِwc"Q0-I;j5 `C3'[ѧ{nC.n 9pToְȂc9ԋtOl^ĠsaԽ-(<ҀpLFʍG >h6A>}*XhxU$v}UiBC E:3\CZ~3]^弛E't˞7^Qm0}APAnHEWd"?I(Xr->5`t@i1jt61ASP\؉{:," ֛|d$nPs^ͼ= T KSʸ1&YPImʼnW8SxlplTV!I:) /gxuEU9ބ&]a 6-F!:xކCBdiUFn!UfvvgB&HEG ۇJ9UL0Z ᯗ!^ZZ0˞I(]_z./nv03 "pxTݒCF Z\}tQ4II2Y8"',#V˓~ u{A*)Ɨu8XIf7(ʞFF2Ьθh!= `Bc/OQ㮿M>Bhc !1$j!%A?E~kLS[ǘUo9KY5y6!F@f@8Ex3j46P,Xʫ/ g/Ě {w]W1E" Ygf ;G[8+,i*:ɒrx]f=QTfu~cp}< :CsuguѓnLċPDr b`6c$4rsF( KjA x!Lnf^WV`sAsQl myL =D(t"SE Sˎr s. ɥ X( ǣ\ E 2ZЛFX#H1R7#?.$po/xXBQZ_,_ +JK%秸 Ff\ru9`ei* Vpsj=A?qo[[xL)' 1a fK'eGwHx_!=ϲʛ0%航Ub!-{Db¾}i# vw LW\w61o3ގ-#K8et#Uw@‘\r]g,^F(FI}4 fel >"Z\?gѫ5| Uo m)e;}թ&+[vvzl#ۜ9=2+ry R&`"V@N@R 1vex1tɬdL$͔ OctoQ~fӧ'1o2II%T؂ T j?+oB%WN>-Jp3GbeXt'\1PYoG[`ze6hɬM:5&1~V_\끼i2rW%OV+>BG|t{ʽR;w()Vh ++l;qٽOC \]fQDa^]7.,swϘFUO9LR:?r1c1zˆ˓IPsvCa Fy x^!'? W ϹJ4K8-$|wDY{~oյJӠ]{ Q7Z~ppz-:8L2%{s_;n66vTYdUW@D%$T*3 !ʯ(> ۢ?ZRG-pUf8C#JumHФCyZa+BͭD*<=PHڣ,$9y+ P[ѹjmeO7Y"\@# 0S{+>GVʴ]硻fyW'rvXGEk?=:]yzj@OmfY䈟.Kûh~s >Ijߣ1'r1!J- ңtvduIdw(pm>ݛDIUU|HMfUvj\G^p4Os>G*(tc%V\C%{Et=Zp*fޒh%^ ].ld[t\8i|ڎF>{]qLx s9[֫]#2 )J}Oֲ}W8Z|= CbbOgg /|!~1/҇Wڬ5u:#sY0%e!Q/ !gp[$B`Q>F,ofR8kVV>nLQVܙmz텺Y+ g_omu KX>sQ@[j%gf\dQDqPDb24e~KxF^hhADK9e^~aO"Wp _zuc6w<ŪFX{Iy*,WfϐS Q*IS 7sMiQ`ԃ\BN~ ^%-ȰsPU$]0LwfrxWF6dJZ:Jԍ~ol񑦟]_/+ #n"h5'UP (^c8s 2wTۓ9a7$ bRĹ (I](hqPHtY~:F*qBKfͼZx)&NFd*mnJ6^@ӂƓ-BI50"O8%^g.@I=0t xKW#.4Fw+zwT#^W%A37\c'DԶ녲 %'{άɔ+&JU hz/o|=O00hλ{,^Oϓoz^LJnF73bDo ʷr'}Ft5sʧTBGBQyɞ0LkueX ɝ% wq0O==,񿒄\Z$d%a#7/߾x @8x@~ ``?0##7t )ϩ)N-۝@~?? {7=;I Wޏo?e/8wҎ[n7d#@ˤ*knhOXsϽ_ud"ٺ xz`]C6󲟋8M;O#y|=RGWV?[aŪ!~<$Ћf2J _ߋ{dsKr@I8(>UqoGZp!p圆%J](٧mcѰӌ<{aKsV}>wF*!t)]z}*Y-?>SB9C`}XޥT"%y?.]IryW%kzS~ +%5 yDh|9;`=Z\ h4cQFѹ/GU*K$sD܆ęWv-6}.سVˌ8=_1zUҋ G0Mu>Wΰ(d5Xm.EjX+ to kx 8oAe 2ׄ \›/āadMvLWxvRh ~u KUM,LGo8::On>AW>UqIjb7A-,$tghdp% }0u*L)Ҩ %Nzjo]P $ܢrٗƃ񓠬]i3޿ׁ?O# s[LL%mv'$!D=\" Gwq@?6̬{3ha& qpƿў@6<}ubX X*G,5a{io 4' dy'&h0ɝ+1ԯF!))S.,hjFA[ ȍ^<[ҟ:V =Clw'A:X d}+=wcL;ap[ t¦­p *eÙ i{AUWjV&YK >jG7v-6|yeЬFDTu5--6@Q6c@4#y7J7IS̍p5ȹΎ HSn2h'9 &* 6Ҭ&o4iCH1̠RX5'N@P{CW7.O2x5B%P׊8;CY@'T `چA'""tp^5]#U( O jӬh)vRT8+(zxjHo }# >qnǻVBP}5ሉ! jjg)?%p)R;ZNbXDHRdFWyD\ BI83$iREr'u2'M3g= ItTBU)ZgY}dp򡞱Q54#ran=k3`B?] G<-+6po䡞FmFB KJ!9lQR=XE͈v؝ZEsjz{51[|H_;㱊\p^`f90Z_IRU[ٲM͖ʟ3S,>1*:L "w;O\Ga8  ^Q2uA:;S@o!,>L)g!B4ަl'u{c59ꛎWmg8wXiqP#hzY ~C?avg^c0pZ>(a_)[a_{<*8m.A/CgUDx>f۬ 6!+ʚ@ Sg2򥭲ueOÃ!O!+jw5ZUxܳi⡱ "(J>wQSH= rI%5ɩNƵ ^2OAaG,ps|6_܂IaϽVc_Te)'T܏MĹ C݁:j|2^id* v,x? x)á$^Qѝ|dK$hj'%{]]?i]P&N)iP~&iDJ4X~;ZҐyVs| Btk :VBAT3''R\ P, ktzNc> 6qvtP!u\vL[k[MܗEgyF߭r3jw:vMm,ѵ_f’VרMq>.Hq+[ttw<2(.+4e)O޹NSgڰjeZGj;2kϤ|]xph4vW%7Fp7;ZrX'Wn`]e\*F"T{.jg{+&ڋ LVDr׺u̽mIOo!d/f=Ô6.hx>^z*_%K-s7XTc7X["(x5龫p>~.CzI|iD( Z_06A~3k;Yz R/ ?2 !fo~ʃ 3Wҷ]/zఏA1*TW#Yf\aSi+²mŰq?;Iv,|;8%k+}1EM&P{t03f1}Ø9۞#[MY T{6 \MlO?4upu;oWr~Ur_/~/~/ J ֨ ￉|?+ڀP<@*Z~\nnnjQ\g~]H+}ϓͿYOT+}o>083ߩǝlyN7M`i{d/-ر'a\DI"kl>w颥Kv4+|zqA{{Ѱ+gg /z(\e==ˢ&>3&pvUW]ŭsFgSk2=eب&xCiY m>%DoB3h9dg j nxtcW!ك<Ouی!U%(w}ُ ]CwG%I<؎tcNc014Wet4(W+W._fj@lU^%@x Ch蕈]"$6)͚$Lhh%fL#RZfQXcA}RV>?!=o$caW`[fpnb&8[5T˙K`Ļc)Lfk'JMgȁ}Qi \sfn9EGP!N+A\  AIO=jr6gB}$*S MSpleƎ" Y̲9-miayJ 0ẎN\$nTX_}DI< !flK4 PA|k 2[T$dll6m)GFC*3POrM<ƠE%<5 31  f~z83^:~ qAaI~l Q[[U{S ,cg UCZ=*67^gEܰv^^i}N}\HcCp3VGU n}3oQש!|mP^494?  ^xiЄo!:}؉bnw|We"%5 dǐ>K\~{1;k4򭍜ϭudQ9? a*gz-?DN1\m6]Ӌ+ٺ17 ˅lYk 'gσӭ֐xj+tSH}гID{pU$Iv@ sB~; ?ķ6$ФP-2t͘5lPUA [&较`|e?EB 6m䎗vWtH(V:*62C9}+|6lG؂lҼ-V.!!Ttk#2n<%_вYmƒ^89<'RPq_2oxAGC@.Z{1, wQޓm[%ROث8XwGTkᛢiʟBx>=ޕ[me?k<$`׵;oשB*:6f5 HƱKdǽoƗo$ 7h==fңz3{ JV3_X_s4Η;*OD^h,h0!(1j,DdGjJ !ËQF^<~5Fi%kfyDӳ"|TT:>;NJYOav!BM6yi(k[Qc{iM< N~B@H< <l?y,A<<`* 758  <GnM??ee$S$_(b` _1d 3dIb?R t\\_pO<.?~~<#~vO9@.zא CHyFNɬ_Kl@BEjSxD\ eK(3YP ۹7M Bv4㎦^/D*a32zawP@Iȫ?OUIQLp/׆%#Һ~1p [?2gNmAV#R_ 5u W5E|Kxάj-m@Fu>T(v!U]W8C=Ռ⥱Q|B4DvFܴE BUUI^O\e6NU#T$OQ+|VG G䆎t(lpmUp<ߎM7}mZ''`]rzF-qX&E0BNa@!LK%:z ͏Gp[Pha5qk,4D!%,o x]M"+c,{2dc41e*d"IBʠm[]k]!w'Hp'KssOr=WZ]]=鹾fƘcFaė 9}0-ly'eأe8FIrn|(dd poVu~yM}A~Rmi@V׆b˧5V5DOoɿ/uιǔ4>EH؋`>CU}*y!ҎKJ2ywT=:WCN4,+t>79+b' @/ps˛}urނ"}bxh1-tyXtQD=޽qs1w{Pųs#=V4(ɿ]:޺a%H/(Խ' 4"ϑΨ)hlӐ,Jde{mM&Z@ߠ+[Fi(Iڷ#f!4T.5l*S94<37QnD3zu7A-Mujܨ: *aNqtuf1ӭ,TWu{.:]Fw쇭]J5ze/F.d'怃o5 Ց)5:Z F/C`&5G$ّQm"^):WD>"Kn<)\Azl /5HJޢ7QnKIhnHx,&h3uB#.;B;9AZ^qPf;&{dabEh𦼮؉ÞGw~v^g|Wsx5[ցz*I*FAPKr% [o`dS(>.+~~$qimpNe"S)רɚuGc`(wT͊V`wdfI4@c2JY k'&w8Ѹ p_@nL ZOԨ$ vnj(5Zl Q*wP@%6@% !!Z ,rpq~?6?k q3B@/ l쀟mZx-Ԏ1؜韱/;6?QU`U_ g aY`-4  ǿ46oeq[58&[J.Cj | l1c5Ya+VIK #0Lr[m4\!W3zSmhEw'nBâ>4آKDRT~zώۄ%,"LϞAbPe=ȷopY7EW Ŷ"xWUŬy K'Xp]hmCRieOP[g +Ҩ}=K |\fBQ嬷W# Nq7 :5p)ʹ v3/hR oݸi 2{N0wGWz=eX 0s\G+dBG\1U(h"}qk y2D6&k (z8$SeR `ELӻFI՞,#1v|61Xų^32cGKB |ǘwbar&ccB9I*aH5$](j<+>7$5írM{?i#X/0uej:6x x ɛsCM Ҩro3*(+bY5&95" 7Up^k4A)QԉaTǏPoie)hH0|"}s7elHGǧ6 a.Vom6s/</(I2;[Z~iP‘[U2IÛn؝/AX=yA p9Ct"ZGy^(hR|\DU=<-*  XoqGٕޱ13JG͜ qe,,(N=v#+Tt"W꺳 ׭^pQ|/o#Gčͨzix V>XGJ.p{Nfi:y|ڮMd7\qĖ*,I2Bw{QaD:YVTe;yg +5_);j~]_}ij ʮ3!4xj0DH5\\Y'aQ!ʒ(q=EMGT4\@ճB(㌨ls8C$p|DZ$:l,{]'QL_Zu_XpKŊ;".|M&}jsw1,7fj#qhAy\=ExQDN<z,.VZ2J fZ"]Ӌ.d ~\ejSB* tV#+ nSO&d8fcrщN-{K[?[፜7z#ePN#[Rɉ9)J# ?&)3W/L> &\0p㱧ȇ+@F&8`<Ŵ&["4~_\Xg-h3jwrc ^f0LVGXGٓ1S%"$x۳h,Zhd cCbp&n㶈&,:^VÂ$=QˆmnGr5W^-qO#R,'ŗ5t+2evJj~ыU\MAw 5|euYv([ǼM(՟aBh2M|7#M:xÚ7L^U2ʣ,,-M¼_DžZ.c[f Qf,_πw9^Q!4Nf-ܐPLc{s/Q1?O.~'J)>-w^=_u0~ؠ^iN4cms(xcUn168l!v!R{Lt&_TbJnud+PhЉL+3HNt62 (Oh r4s\FVj+1/-~]>+3j ;`˄cF&~J~&*N 9~Xooq`5PT֌HĽX?|yz,i|-kWW/ d SLـ mMH\@.Xc'LMsEO_i_Y9|?Oeѓ4v*z%XYvsLS;vzryPH,|-bA|0O{KXHs|{vpһ叠}UUĨ0URbQ&jm5qd7bq|=Jt{=N%| yO[q _(Hv@W:_L=_/vg&?jdcSH['MkLH^G/&svz_V&q6(4Sv? ؙ svUk8xzѥ$\@MZphXWfgS_,}~ʅPbCvJ ݤ)y_I'slxo%6'X .Z v}Vz"޹+WpmlGp>\w>foZFd>ʝ_vwyh) 8=J'"bDxtv J$8\*a:(ԣ5ڄù'ڟ|-ҒCU f lUN *l9"EUn mAqR\->y0Eاg{%oY*?ylciVMM6nJi΁u0эDqƻ M_F 4s] Iu݀X_L>~6Yv2=#!4_̽W hl߭)u/kCd3:&$b7+ H4_f"u.crx Zv`~G@F(j Yei1MR D>Nƥ*bM4rhޏrGqXc[+Җ %{AJ6 fyW}6z "3;VojF2ݞ#B_x/y}&; g /} E R#P Ҵq6493CwZx!ĪŐ#luHW  1ʷ@e67j<@ڍO[nBb5 Cq!)!לz2t"$a& (cྙ-!\u=Yw8>]AB- ɻxGxj>m4LduS_b:= ,>C*8h7 Lm* 1E:4tNP50 ;A)]5~l ziE YK݂LNS2ӺfV ƑQ3MZ*83مtׅ{gz_|K46UJJk9b9.rT.ئt̲yU~80yX^|.+UF~RauAYb>GP׷X'դWw%; jpGUDRF_ G\eź;i_c15*~d<)?(f)dP,7qG`op #Lj4X7*T4} ۰}!%8=GC5vWD ٸQϻVrSjgֻL'zEzڭ]ϤfҮTHNmV~z~hϨA ΚE'JK*{(_puiSRI*>7v|Fio&[lR7%";e9)%\Nm.\=Ex\3D ja䣊BݺLLd!#,y$)wcQbQ bH_ŅK7G>JeqHo :3PH^֙Ҹ'hh~tS$I-__IӼ`iAn#fV [^RHt!W)߉-c!՚ғVگ"zPF7Wae5uP'3?6py Ojղ8HI0\S6ZeW=9-w\TB89C)1O:̺5Bu8$Uwinu 2򜤨uvg큮y{0я"a}X`Y SuMI+/7mCNMzTݽZ{H^HD'gzn6-_D90&L:Ï~/8nw7_Txh0d.!Lョ + %c@3AGs'"}o\s|k9d^D-˺l333t} i>B{ ;-L&d: J42p)2r/t-PAr4plfMCr8gE(X%WDCqKT7OIc ;, U8N ow[[,GE>/6ŪG{ڍbGq[[cHx[{B FAb"iId"&bH$&Ɛoi{1ȋn-CDxDlTN/>qHe 4tF_4GQIm<2O{<[j>zaJDAj2$p$ΐVZln9.l4#Y&>ue'E-D g?;<( Ik\>.|}T U\xf4E-!aQ#t"3qRMSbcury nXUG :;  urTEZ1\t=iCTGn%T-*$m%vA??7uWʰV X4alj\SJLv5Ù s4DPX9>vDXP &N$Җ5J1b |U<)x/}!6*o9\=H2e j]/Y;`%&A Q=ͫ4r@O  20 d'CzҹHա(Y%y?#OKO#yVA&x!-PEPPSCyγ{M8S$#l]b?ٷ Iv nЄ97EpEK7Eܾ,|>]nS= 2ffiQbs.QtG>4Y#mbܸQtk:}HEb*I-5/H7P D~'bюfZ T$"sYj]vw45Q]mY"7U52)FOBdQI\זvZ ՙnT=PU[PHwgm:.aH KΕx{/H ߰Js60 pH&u)p016hA60 I 2QI}S㍼3{უoW>Ig:5OoXܠ6,eZjC5w"*C?9A |*=Z1=>J|.eZ"e)="љDEݺw"HDzeą.f$3]$֥Edx0<4}M:994*<3p{' UOydX@.P${<G)ڴͽ !%fYsajUUn/;an>"+|>Iqք3M<ssQ wrƿ䠬/ DǾ82d!4kC.x׏L=Y 5VNma#w1Mq])qLG.(d$j^MX'̏ǰYϘ z$gKJ2r V;q$v.q%wSzvKJؑv&JVY ;>F0(QQh ^,C6fTO&Ô-ĮI j_S0 r~cDdOr^[K;ͣ4>wa3% K$`<5Zś*8C[@+D M$ߌrA"<ėzꯪ\$LAH |Wcoz4޴'Sh`~iW#@'i&-* mO0M֤RB1TVdΕ'Kz;l]Nڡ҉6pClIV=^G0~,Id˫OoӉv.azТWO+rR"nG5^ZKlcclcs1#88~Wg " b'a8ف*-$3@66v o\,E qo Kk3?9=Kmf# r].%¬(fhE<;g#ѯâ\%hه(~2GsyߔJgcls22=*Ao,-`S2oƪ~_z͡U"*W}"*we#򈬾dE-p[#L1T\LR.̣w:Cw*Y aXGDn-?Dh~vS<1l%x΢W!|^[']"neJ,~5ϥ-lFl _pM<Tl>EXo*νp6.ubNCRI< Wb zOt-%_2'*OOObm=VstTw1/i\,Y.Ԗ! J+z-^ըNz.i(^ċ=u#ȂF*k9Z*@'OH@H#=m`~DLhLF`6λcȨ 7@71eUiLx`۶M#8#TSBc`{";<)Toj!.7lx.60 65\oQmri7Jh566=uvtthp}*)BOQAm1Wx!NܥFc`5v?)aFj.}ZxFQ>6qցso/p\e7zMk$bPq3pckH UͽΐTkiqOI }Zv [-v0l|pL_v^ɣ i(Ivv(A̟9 UX\0C)uO1򅠖rj-TkƱyOCI2<,m?y5&I vƇGq);'5vRNPC s»Oz Dxphպh9 D~E[hE=eiJ =wN ь)R$^4w9x 0 ܿFr ) {e i‚(߾I\63)TARNN`Q'낋pRy˕)Uxgw89Fah(U@\D?U)ݻĕ7Ꭸ&6iTdʓxV<:136p(^xJ<1Dq/NKb.n[L^c:tH;dyN,j!&'` fX[WPF!QZeiQE ڥD]\DQ(,rԳmɨ_g" q%Yi.ra}8IФ9qcRc!xf5/h+lj`8`_8le$DStj'rs2+YwNA4Xv|f);r,έɣ|R 7 LjO[BJ'N&vAmM+;k܀,hWx}ն(nSx@n{5)[m񚵻y%w=4"YpBW^A3qAUGlA[.}Ύ`*L.Shyʂ({I_7VY_ 34X0qQձ?T){A66D͖[(x5Hac:e2pkF TT|p|1IX7-*'X\pE4L+\PEn?=uwBq9Ⱦ@CښC =֙)%;3ɂ =`3sR]m/3w&ðg"ݷKi7w{Oњ&!%WW:bás?ѦŗByA,d@8-X#\Om<i^ڟO9eS *b눾+.M 3#*&#i RGAxz%f,rU%K9YFV3Jr<WY[53́ˏA._h+"lM~6Bɔ9| IEv³<^PƗ̂TیPZ'Z#BLKn+ViXO{[% F*˴R O(1]EΓ&}Fic3̠*mά+~G,k{f}Yg "\^Zl;#K[^AZ 2dkTYf{`DC_$L-S̑tж琤^ Btf|Շ/3ѿ} 1i"wyeDİе3OLiTwg5}+/2v@DlLUVT]<_Y AYw oD{J Z3T+t8 1# *uh.bH}/!h?+-b&fw>c}ĥ@-MJy%)C4 ;cX  HT_dA* +E$!e]>b:Eku^pGa%$b$Э.eXr7#l{ {`F) x]bq "1YziBep7fFP6.:Ƒ5j妷^(ZO[ *S=c:~ 6q4>&/!<>d o5hԛa'_W'So&ږ^Sf=T=L J\o`%6qdIF Y$GRcK#@!MD@k [Ku=Gl3f9 s[z"oFȓ eC+sve\<^h1p8*;a,Ѵ3!.Sԥpg̎Eک6k!NyQ ܓq,?VES9a1dRrFnf:ܪTJЌt`wwM'Έ<Y(e06]b "#hHRZ푠cdA0J";Qa"6Bi$825R$w h[d2(b pqOC9~\?7r6g2w8${x=߉N{ڦ0vW(*쳀W~j#r}KЌᲓs39 ]Em3q`doqBy3W\ΏԘ8U)n=lQې-.\kކn~|G ;SŲ -aEx=՜3c 7PXdoK=~G:DI#=Hx(ݼ a.` }|Ȼug҅.NI3dztѱ+N,[U76Wh)#geBPov xnUCq, 3G>7bfeUY΋O{0fD-rqw3[kZ;8geY=uG@m]7$qu??$𒜿%9#CNVvvf7 ; O֏?_'sO93+ ʟz"n; Ǒω_`s\?R acg9Iؙ9,$l@/3`d YqeYqn?T~_bs-LM:|X~?8^y1 `qsSz7oz2ߐ,,Ms._ NP6g 4!0xqlyp\ !\9|<$;U`6Ab E |ҾFFco]v\&~a"+ ?`sd5 H/qR943(^yUyq^uQZm_/b+.scieMxqsv;Ug"9׈__ou82[95?U]/((&CR"Q"  _" ѿ{zW8'j>jxg3L({qR]Hz`8ؔ.EZnD1$J$ApO'@&hˈtpNm @x۟I!Qx>zvuj!r~ߋ_16{saOe 3~JDXf HiqcVjbOWCZ &{2(r#|/cH[j.{HO~+ vPO^LGuP)RpVohQl_5inKBC@tH:ܶ7O#H|l8y OFlD Mkҳ?~v٘,0ri+:^s~!U^&nj6!䀬nh^ w>E#o^suϦzNq∪h>CĶSھKI n-&R: )A(-څ4Qi ^mRtGȺ v| N'XUvIEX{}JXl /d}1 L8/,i'2Vڰ=y/&KJƲS&bS5$=ź~c[j>Tu> F1n`a%@G&:VX5,Զ.,Ν޹|}8%NzM۹pnŁaimdǥs䰩1u5$68Jgkiɢ,'s, 7K@5GKަqYBgF5B= *4h|hK+!;Hc_i:H{Ӯ}WFjLmuCG[m-Gdf)GR`G{ҫϚz$ EH2꜁|/~:)VMW?}~3 Kjƒ0ijQK/ ҎC;FW֦QŶm;+ضSq6+m۶]A6**ΩscOkswo'=Xj~jmDlW#5k7p W} Gb@5M u?`]`ZR 7Zf&|#1p) n*lϮ ;)X+[ٳ/#i6|:zg͊dh&R@*[֮pZtU&%<4B݂W[$fyM O5!Uu1CM?BA /W hG$"͑Y۱k֎+@׵}B`X2K=eJF)DZDnN,{yY{m\-&z5T*IU_!.j]#{129":0\yI2mVjSlZ֟J4~'oPRm5DߠHU]4;vY= qnrX4.x-B~A'DoM"K/X{|[-9śOV,sg;]OuB ~˸8ei`Ҙ9HAG_(0ߤa ?:߱˟W~bڄ~݇( n ;zm\"Qm 0\"Jb;A2d-/+YxeYK6/"'XwD QfYa 0 iK3)lUGs-]=`tMϞl{C!B)ĭQHh}WܪRףKo~u)Լ0˖&6GBLm 1|zH臭3)Xl_\VXu H? lp_~u×`t1!oJΈ6a;xYV@IjJ|}3sbt>y6|hchw*HQRƔ7ĺcsM\ 9el}r4χ~ҺQGIPg( @} SR;Xq^Vf@ :ظ3=VKrdx8BPlKAK;s? RK'Z+v;!: ucC3AnRk*Z&q\˚FpU`P]L:{&:6; ( LsOł =&O_2iC U,'ȦltYlJ( VE~ m%R)MW^6)>AUgH@ 8SN lŽ5Na>{4.fV{e,](:v`JK-Aj1:#"]XĤgc?Ws%\n'}Qu iBH*9Vxq{-*fK _U@WQ5faD0* - ))BOG\oslR 4s^2j= vrSNjs pY=?zN +y#-UeC_-]h4Iu&VEyZ5?qH '=>9ن؎$ۓYd3`1h#D#4œ#,h1\L{:jcvR;tS*a96nV mp4M0/j"θ{/XQGzM{+h唸NI CS9/OBݾx:o緟ڤeĕ!)OUm\R8O~^w5\RI5ARrB D'c(^P#$X 22=8+;G#2Map%[\ ban1 #N6E 9 pA ݆_4hGi˃sXU-e] k!(Z)iR)$ʾ57f,$*I_NT@]_fNF7>Y|IHqBǤĵױręiX?ƨXoe5<#ID FA<].zS?j!vN탎ƙ.ʬ#LsSoT_Y׬Uuw᳏O=Vc #: Ap5L{wG'gQ4Re"e,#u8;Vu,7Xbz!];_x7Ȟq:ttmT'BﱭnhzB9R S0UUE[_}~>ߠ?F/$? #HTg7I&=YKdvӴ\|v[g}&[P.<ͯ`ۀy8bkƭ؟/7;N%g0E}|GɈ.dKD({3E~zx)m}Q$a'z3@/ES7L.}Cdw[ %3<4'NL?U#{jOx{~Zؙv6Zf\ހ'nƊ yc>Nta 4:Lg UQ |ҸnAƈKkS{4|﫭†g+֢[?f╒-*?x'ҵϑtMHmyW m_?dޏH2"\)%$;{OE&4U4>SUbWL]4"I*Nf CJ8_;ٕ&Ѽ@h Klq797k$ۘYX]ؽst\>uc +V3) =J^ W\"YR/N z3A0(TyU{ԠSgEE*@27!6!9 fsUj,ãMБ~ϼ ىBgz2=7m Ӫ-v:bDhT^J2y葁ݑ+l,uӓy[U@י<ͱx3Ou9F O9d!1nĆȆ_xעl E)CzT9?\iF(3Qq |"А{>#bwKHc)_l 7 V9*,8[FTk*_DZOO(qR+/]z4mr^m.ī΅F#O;oX!qAy=Ԯg&j)V*AuY9 kET 1M7괟 c;/w`J y0b;(F WM-1%XE p13=1M{ٸJ،ؘy*)q8?rn(}-g+{1pJ 4Avʙ|nE;\9}epY#> ` M= Vu P/ܴ}H>@HSe$u H\DC\&8Cb#/H) Z i{C '9Pl~h=t} '%;-60@\y0BX!9(jp'5ߞ=(X _oFm=`TǬwQןiYSS͊A$M޺4d;`Ց\7\ER0ҡ-S׫(xϧ0RoI/t")rߦpÖnұ? 5 uT|r*Jn?XͧaO~o ZgʸR& 8 I(\G@İKrylC&LAB^fImsRś*Ѽr+"4weZ+3`sK/ E7r+rZЙq| W3q\rȻcUniJhV^n=q UV cѭzɼ)6||.CS(̋g}.ŷ7~WGE߾[o& Ozy h.3='Z8YXY~+d_\|=?TR ٙ,,i_):q_i>/8_gd|ò 0ӽrRѫ]jĪ!q ⾟>zXUUґ?_p-W |܄zJ3/k\:e@rv0 "%bcX7p%$@j]%Kpw͒!g1i1 GZKY~Q/kׇxW!a"&FL\NCU[Y}x; %Y͊iojԑbh˄4.CY|:#[J ƌsO@w˄2ezy {R .uDb kMMsV f2a[ ZQ}uGpHMN`s_}R}6x\|-𞪏6zĬa=bۈo0X-QBmvjJe@" ƜyH(XUJX΄MX쇧hZ/]y_0dCk*M1ɢ7g |lw죗--pSt%AQP@iBt z@=cZeH~zώ0 O_k9bgfnIs]㨦g=@/$Yree(/?&gK vj!ΞpZa6>~gZh"Y+kBi^WvU!!-Zd hp1x x=LL&V5n.?!,/* G›Bq}A .ݲ=&H@}0?e3%!'WenfRPe0$4[^߹r <-txPUE%ԝW 8oz ]9u;68P^2 *2W!~`\,I9 ^ii4Ct-%ẙ&<3~>Y 4M^@hs{VL~edhwE/‘!cֳj"'"' h/ ؕ)6?ӽ$i|kw= dLs. nKAl1Q6>,-ڏ,K=_#B:%͊C1ֿޚޫ}HP5^&ke5u\ ',Sd)"͈G78?^=֑h~A?,ٍ/߁x>2<'Pss?ns''  ul: n+X߬fXK6\F7fYK3Z74*̌gaiJM)Ur׳aZn {9!ӅS\и\a8Mo_0{VEX~÷ꓞ&+r QC&)OG0_fq'›(?iҟRyRm1!Nq M.xQǶǨR-gjޔݷKyֱ 4ZejsSek_7Fu8(qnquaNaae`za9ҍ/dGY+8vxR 3R87Ʃ:cE{G>C4?d!Xr~a eBa*$[Bj؋-kc+x$&FKFȚ"#y=x 58ޣyxz5oXEǐ=ZwAk$иx+jfzY ppiPaM\SuQr@~a Ⓔ]<QW2nH6.?NE@v}K"}#VBH j}ZJhDt{khtY*܌xXl]Uf9 ѱtJ|c& JMCФm ijg&SK$ r57:ZDnMea3u疮pϻ'aM /; se[aO\UlD!a>BoOv 3zN}ݣ3+66E{#ZAR_IXb,ϫojrq8ө$E 67YhU?n@qaDCDg=O(XT#t }[{zK\TmSl.j̫|/P#r!^%AX1* t JG공|2HO 9y=@ޖn! + u)ڃ!_]׻`fxTSqD@L EU6&؆{:+)y?Q1QC>\Qcݙ:Tl ')I1f8x}sАZ`}HFMii>D ]3Rp^{O.&$?XA19<, A%QՔ246c\ubv &FQwo>`}b*DZgśBZ_jon"KjhsyG4-J\f*սKy$3 E$tJIމQڴe\{yېY]5U&1DK7C>j]cXiM2Y:с)v3rFbjut1B 3+sE-,)u [Uo.o\,mEQ+ٹ|1O¦_KhgFvo@f)/?༩"Wݓ)swL<BWU=0BG֏%X!̨dLA_r5c8RԶ&_crc|AČĜf+K.&NuR(!ɕ5$ň$!^SDzŪ;|DtD;8i?OڟsQ.Ōچ3HR?W-3NiK eE "@-3ayKōϤ;2 ;-Bnu27O+N?I1},sCu\ }n;f#\ n1gyYųf65kɻ_\^Uwl7 d"Be;߰O[[9vZZ^>ZK# 4hN)ŪBe69gx M8"X_ؿ]ӫ8nyq1WA0Rꐹ̻_kّbs⫞@^}c|M713㯉 Sװ`f{Zۯ4 iD`9i\%!S?Hӆ.HU.i{??n2Ƴ(|[ljÚb"fX*Wj|Ъ`^sx? VP62aJO`Mj`ȾD.m!M@9gVځ.O]Ⱇ&}'ϰ>nlGC#2`yu8KPιX#F9gc9sD&O7a P hS{ 79ejA)V _`lal&bq!U4K{H5Fѥ ^*5 €F~Z1P K9hX7$k}ML9J8 K=ړi~TT;ޡx,32-pZf4 L,G<&~u'Z nGKi2X\)?cζ"Y/$B}_@(2%Sd RGLl"f=X g*xI;`,&tE/4-(9h+҂fӋX1nx{ &GRQ󋎺 Wr'ZtPamjt໡9^SP巾`բcĄdzG"D2$="⺲Q$73$?۸Rǥ;V>*gA|N 3 YܨSf4܀6#)ljvDX['biq(FnQ\WTcFc Wg?824T;=cOS{t;2rd:dz Ք+ES[MlP2"{p #rt射[ˣfAp}X}H-4F'Ƣ%F-CKWq w)rN!rpBi /BYU|W* #C. |ՐǶQ6nc"hZ"2GEԧ|#HJ3.E#tbp#WLDBjrNnV~yx=39IȐC5W 6 OQ _#Y Tb5bx 'bT~ Zs]%3*o;4lt$nEUAVk?;X1x%%@bxs,^Þ?@ѵԦݒ&Pĝ C&C05\j,Q_1]pr\ozc^O}1#S"gW0\k-;-Nmy."RWpeoB$xMZ(P@Cޗ+r`W?7bW,IІ}$H D>YN+#JȕY3ZJ#'E$bU347:K/y1VaHr7 #TutT/֍K$WSU0AGEhjYl" 2E2"}xfN X "a˵}+UukḫQj&HeZS)bwQV\Z!yOmn9fd)$d`]úE Q 5 cG CtW`$nOD[$I6DdYL&%!z ?xKH ɾTI^C~LǔVW0Xd¦80a}+7s~YP12iJRBe]eٚ.# Դ1 Ҵҕ}K,PV{М+"r>FIs#Q+brjo_lyfM|{Gr]ȓXlѩ?XƂ.t* T{`5?ua0~US>Gi, 6|a^2wG9ljW!9uxB'if?uCIG)sFħah3@VNj!~ {I!7Q\B1:mqYGmr9Qᔑf:}VΜ/QJ Y HV3_#VYy#E.zkOΜ=,r|/N|Vx]+E J=%a,EwRpq];{/iE=+xlz/3})MFޫWǻjM"ˎݺtd^3}Q@BEDi2FM"~ 8 XZBOF' ҴucSdΒB {]\ȉ҂|prYk?1gOjF!fl,P7\鞏E נ?LZćtp؛҆tE8b/3I&5Hn|т x*dx 'rN8*M l;Ӎ4:V(jCJ8yPc̝OQ[G|$/ ődfbf{ݘ?w M?{ mI?7=g̜L$zu齪ۯ"ygww?U<&IS2=2~NV*.|-3s$/F4Eđ*5\yz0Z_2%.Y]W94SG x,# "=3FדLr~" CXZQj~m~Iub!Q™Ϗ LxFsS}U x%ď FL.O‚Bbd2ya=~]JY(Y.M9EP#XjL/C9.e+o]P/D,ճ@Hh)`?% aowEnw-! 6TsH J\{zJ1ENKFPeoIJR}O;ڳLf%_u.EX-b>+h,*~&(Ah/ hdAgK dᒸV^&tmidiF퐍0uyAxeҘyQ]U^O,YTD`kͶLBG7a73dȯȕShjԄP{"ˊS+Xhș- {0Sⱁ435$&_GNB[y[;JF2W*VԁhaYܜA˔j}XC(ZFٰCAw? σ#@sʱa*ˑ[M$3xWb|ɴPAw^Y=mO!X#"N4RvhWEQNps+ՅWk1*!k 0[Pk Apvì,jYJdOi5s]eT=L={ aj+"Skzy7i"(,s;;xΖu} Z+ΡkTVx$1BڣK8q{J*&Aw,shhSf |򳍲>-+4gbc-A[ d,{vw OΒ&iJ y _v`,H01}Y_csQKV*.g`nlO ٪ffYčLL Y١llm0ϲW74&b62v56"d6v634V$dfcâQKl쌀3%?N+A6yvde]獶y m r eZY #섓f*K܇$Kk!#)~SEB&+nQ#\wUlͨ1+!) PjhT(4a-aT*檯g`gqpy~f2>u()8 L Eif*o'NHϗDܟPDazzw1e?;-eH &%L, \,hT0Cu q dxh8ϹA j^ oM`"b' +#^ST}fP,+A~[PUcPgTk)sEk /0oX݉/Kr5* !.KYՈnM i'+ Bp4#"Dr7O}nO Ĩ%:f3dK1x!] ,!]+A3TMDkN 9'Poe?%ۧ &8ʾۇzfUr"*,O:%ŏadI?|! ]|J_b_R *J:vx3|NI^O$H|Ȟj? +{0 Z mEm .S7O@ns,v-R#s We4wݛgfN:U9Ue%Sx<%!c``p[pe4gahx:^[7x>usꟹ%]zm8#qh4] Z=G mH }LUGz0Jk 2NMkDR22+ޫdz/" Gιu, "M$Ƕc,gRvOd PiB2)l iUUDGÏc "n?yNp~)J5LM-q$*ih\x j8ϒ\@@/ ;-mxb軰w.cb~!U=Md~ç%AlF㫓 wWn6L->WRF+>lovȤ:[d}%zŷP]NWv9ՓB`#}%"G"[ezM=Nׯ%"ceId,cYL`hĪ2\0+ *;7% /w%A  nٿZ*H7 Uϧ齸K(:eG7~XZTKxAv:5kt{0AL˂rۀa#|>:j+ho@KZ͇iV^k趧{3焠MJ8\.n^4EG^i4-YqP )ً0 JFۈRkfEHh0xz<"=x9>-;B-HsHd: 3#i&EG/vza̭'+>o̵d)#|[Nn|] .|fi۽iE*sb3UJdN`eE-}t2i_~cѫu:`f>MGX<|j~KmSn'‚Ug.Nz9 %Mx#[_G<-ˍ4++ـ= ?.U?ĭO4|n̰˻,Uk.iejN$ܽ%x:Y8]M$k$شXQ I͒otMeTZۮwзVMh-dIMɊV}(mŞ#UW@;3piϯ Df,FHlx[&0_VeG@[ۥ}U"@p~}N4a]lQ!B̻!wӪr]ǷKӊƵ k0(.^**zv,4~2uʙ;-ȀaHfnbұJ\hjGuvU`^êތ7p{˂l5Jh]ADx^Kv^I/^Gbe㮤Ч`DԡFyN #)BݢXd̞p!V`4) 2X5\Z@&&HPy2ij*W# 8GRTD< %L"rW+z1v,K?8c19:`_`K??EZx16etmB*k3Myg޵*=Ii = (sL5sh~:/{%s1tgxL Ó 5h;W(+){,ՁlPt7Ԩk$O}l#OO.<צQ:Y[{t'MREP_ jo %cu1;@5tI. Gp.¾(I4䉀2#`Cvb%t<sb}VZ^R_u$Z C[zY=X *d>:]{clUg( jʗ7upx''cYUb]l{9l1r4BPP|DIRz|*'~[2u~bw*(wjTS ek'blÏ=$xR$ОXP I9xv1\G W]1u<<|+IhKHnղ.g 6%[X NcJJzaVܗއg%sױ!2$D2=ՅJWNLqz @-:\w2nvHZ{&9ndit_b",DPC=V|{OVGX{ W 2 |,S h"r&I9z*3a{)C`GOKRA>wNZ#l8#i@"bwbufL/Zjxq'j7YHvavH‚#&)gLU;. ـۣrXlҟV~tC>Z+!"ϓoWX':0) a=%t84 x(J.ndj(|fcON70':3Nb/#VfEf={iQo+ 4x,y~/Qp%#D.*G'.Ɂ$,5/ofX߬p/lz z % 2*:&+,<|\BbBR2d( *r:zZf&Nv. A!W%HIJՌRRQdҍ3dԏ֋b$jik2f11}34YX鳿/.rP![TYݡ}ss5{[G'mW7Ogwd&7q׷n |qpqmIA!aΠi=p;WHOȬD79D}n#by ϔ3@(bqF2b)[[9jDt5Ix`1oxń9qBm &I@"clC?s_HdRkY9}RO q :Y[*evc.V9S9kOEجԓhX};I _ M}ITP4R߳Q=s3\5hQٽwpl`kLoSCGatסѡoA 3SOIߦw-_MVl,]m?mo]ߞ?;qxswuttXu[u>g-j M3"'ɳ0;d20b2H8@Zq@L@g@E=sSG;c&_;@, b;~s?^XKyόl$l n&6_;?/mFoXH/mS70 f{BnB=\ERs憙/~`,g,7C?EU251ھ&6b 6H'c֧Jp4,H_@G6XfHR6ΕHTa6jI!eYY@l]ڠ$|`KJwt`Tkv}cdFRZpvȎKjh?kgZ``2 eWoLje;)JNä(}X,N`8NEZ o#lrp Vu'U=IK_d5, u,lRKjxO Zf#5kv^ / V#G*VG &@;pĢOT }})B,ɺH?$ N NAʃ X,r.hR@;Q"UE0(G^|6U!>J: z$IjxMd'vnSS`EHvPę풛h1_) 'ݼX>n.\lEiv;_gI*fxHq#dtboqQkXMTyEqlAGjqD6-œA B&rt>nVijCSjBlrʻcqa^2[Hm\L B#2>uU_$M$ww~ 'J$ՌI5 VW_φX͖7pVO AQ](I>aZ9ntD_$63>'|>*=grN󥣥M`^C1jsd9}FJ,PdJZhO%C@\9ir f|wn?BIR'r!=3t-|dKF6qdfl6 V0wޓ"#T@h .+Y?,>.Hf}PM-G<qnДim0ȢU=I_Q)LMS +`ȁZ)LTV |({&kP]'6Ŋ,;{Q> *7qi0|vlD]n3aE)B)Ƚ|NY&K64ɾ(Ȼd.a {#4NoECd7H8b +NȆ#&2f iAt]x fO%= ' wgB ~m&"5k lJތ7hN*_j/! Xz؏ L!> pF4+2Zo B~ _be 5`3ܗċ"i̛:0%*HةU(=#@bˢϵ/<ëk!Nl6 >%ᅎRGv! 'RuLtZG*F.嘿29C1s ~{[ӔVv'r{ |9zR稰#]w<-P(yx0VoN7|6i/ֲblyh NcKuFIlxQS?٪Ti~VLbRe ÓEYG;cMOqĮKXtY꺭㗟YY-ᅣ n/"Ygϟbr?\L VVgոjؙ~_Bό\L\,ӜX 7m1BH|.1wҬl?@E٦~+\I=|ov^g+cdX) j-&7V+?AԀa[}\F44#7j2t꾵PȻZV>h~^'OL~exmz:&Cl:"/G|䶕7Ft+LLa5"EF8ΏyM͋LL) %c,^^}{Ȫb{(x"UJeQFnRNi!Lx1# *b^v2/Uج L>r)j⇏K|U0KfW*I.M2 /cv%@?d .gQ;I41ZG,<ϚB:D,՘H'^ח K/3d٤HI."QP0TTTE>cgXkℭd 8/:v t;P"lm}'M࡛vwkOk iO0|  !:}yHLSo\BTkQ@㸔a:RA{f+%tQ px]D`Â!6Z? ޶c֖lM.GEL7}H}H _"oD-s Cc{xsJ~*X4F,j *4LȲiMwQ8ӗM6 R4w&t,RM'rDi{ٌscE;CD DXY(R Kz# U-٘_?)D.4F\쨚u^f7gJ.:H C mxj:v/yشQ;NjHsb~&U1Bܜq a<*)jsAQQ(tX=/5p{pdXߛ~Xy愾y{'rU OJ6&0е4hp%yM_,Ct!~RCRutA2sd6׺QLcǹIO>l3]Igx]Er_0R;AQMuυ|'ӣEs3[9]%g*F:[KU$26J΂@Tr-4 #j:v5oV|w/CjQ&O(-N{I$2F'{j׋y釾-.5hqEi_+2*-f2g&ɃzD@W-FS.Pyq[z,5,su-Cϊk~[Ϝ8Ra_muRODg@'`rrԽ`^,*tzhKc;lWރi2,㳆Yu\Dwl=-O lםG90A2ঃO8b}ˌȏE`U{xQ/m3q)蕗R nd&LAO2^>6U 187`RB5x9qȅcF ~4yiҪ(~C=ś#WO2Ϊָ i5>X7((LߕOY#71#>7&x7`^N3T.Ԫ[L}mE&8}mY I~C7TY;&6F]e·onC!ʌ]N0ʅ|OETa]) Z>S!T9O@^"cˋ-MC|͔E@Ӽ_V6dtX=2mlU(jr+UtY&yDIVUǣ/\Mݬ1qq)56x H=ݬ,}`WWv;f0l-ce9[ !'iڌZ>ViS*P8[7iV .ڐ]r~0 ⸻vX"UYEٽr$nS9ˇ :&SG~,Ӱ|DP'Y'ywvQ >iSi55dE09D}`Ozxk hq9sUNxtۆvoFtVvnl!~JϞc "$hA$!x"=Z\s2=`T/2 Qf7JWCɢc\bsKƯ뗒ɐPM3(Pu 4[-=inL#'Wϕip H"$2? SO(U4McQhxW^A MakXsԾa0z_(L^Vy{Гlܯu㺡W1jp>61<mމJWm*щD ģ [3H*B(rld|iD4ы,]̗k:m$gwp} &> ,r@HKYњ r)z%X#}C܋ͥR Tč [~Iv/c\P/F?9pp%sS%sbm< ,ߠA?sYI#64?D$slK9{j?I6T[}fQ;eCV<` fSs%ÝGi*;B˯O̜~e1eSd V(H~; zL~-' GZA&0&@\akmENTZD{([b 9kybOXi 3>[zG5!;E]瑸8}6 c3|"FIfb{/ '盂͠k: E<?Fu=ck$Ϫ6qe;Ι{iflzBUL-]ӂkĖoh^+<(d+'Quٮp0Q.q0'iX;;Sfȩ5QGRu:lq3#g3 jRݏ ş0?tl @^O'Үl7>ЦgSh񑛒rmMC]1cZ R+ Fx4E1 -V W`bI̛۷֨>/2kz,d@g]sK).'N4F6׏p=s6=GK Rտ+QuSҲ"Q-\ {(…K,K j+B:-}5:זDykKr (9;|輥%^|@!u/Q><Ǧͱ/@1TL |vVMI?/h"7e9?"]K% u w%3۲W C 1ͭv?_9gOkK=k~)݈U6`.jN%)Y0z=G8n%˃q5]C:z97۽2U8RmrS0I,t 'Q2_>9̂,K8 |Iuq.ABݘzKV;zw ~I,FW(lAte=iߓT1gx &#=cSbzH*[1;,,IK`D:~oUsA`eY-cn}&?tI8wچ-&fzRp{ fGIb[k==~ 8q\YpdFiW7s=` -=%>YYzю8%dLؒu7D>s)g+Rj ^3y:@\uaTyTC}aQ~N&9DBhnӀ~7: 1yЌP]%Jf8pF;'T)̅<uĭwU…ɲp}Aޟ5s"@!C::x뽯DVQ B=`O|}[ 5ZDnw5? |[!7I :I-i!va!fRX 9Z;3 z" DMWi&*8Ѽ@ƛFFFGT}l@!љY2ݓ.T׹K2cxڻ%VQ%4" pKPoGlm>~)Q1Fd |< )ٟ9XWi-ЄsPϞŅV#4'w #d9zYmLX7D5 tLK4A$} %lW+e z {=#got[GzUkP^nHz*{\9Bk ׅ Gx\]^sGNZ7aHo_,:rfe[v/m6Ĵٸ/E2q"Nг? r1؟&V&VC_)_«l90gϖqwM__d͂&!{R(X=X֗]9LRr2AS{0a-AU>Ӹ*I4顓1WMe=MjQu_d\MkEdɝ ֵUa ^iE @p =t85tqG9tpw%YXo~AAy&#~H`.)+ ˊImF;kd/~q5WOڶ~qe2O89ߗu e_`6'STƉRV#! Ra8IK0ڬ awdiIeY<s^ta}7ok(%|B*OaRHv^ȣi#˯t >rKΑvݿuZoZM3k8cj͊EŨ2al@hCb_^gN50OmTa.sCnN>f}O`cBaeGyHby ϓ Y` : $$eȇji|8܍Vmu$2 RHEk8LVM⇯ Jvnq}v=6 ߙ!DJ.*7 BEDu6C 9hef5؁h}rjst/&~}bT]Ǎkci!ru;;Re] *{{ӕ掅$k,^e;$ ]YUZcUJ{ K@F(j >b3y邙_(`-UV;+F?3 ߸v *f˩ݏ$ʗxR*M'^!W;hJL"yD[Q0SQ372@եvQتOÖ͕'񼁾8ECu1 Kcπy#E]0]]\(bFʶźRlTthD3Jw6"CnRmtc(1Rq)dc;(hɈK ,ʰ{sב'#lT[P&ϲ {˰EZػ}| #o.@Ne:N+[4w"t`oSat6>2p}0Vu͍{qS-x3}_l yx[KT/Gp Ѝ^govE{}T]-wwhBpww \;];<23ݙw[g}j>ѹP*\F6Ytoɥ):i?gdbm7'ERLm'VDlDOWTR0 ~d(}6pSv ֵn =)x^ψRPLVe&o%LR'`޴uK敡oJFӑS/0(J5#+ۤAUaTހkze]ez rѝ"o>w =U6!ۏPsxTKбvð"F5ha5>xR>,=zWχQ)!d=4Hݡ`)0H*<&w#x ocw$ʄT oڟ -{wz 2h.8xyᾋ'\j\1y۲mYw_oXϱ#`8dlVVzߌ7|A0`bK*:DIӰ"`8DEj y8ԄHՎ 8u-$EF):d-j !W"𠇝-qP}4%I1fѐwgVMq 2e^!GW}t P&O_֠W >ONR\n1u֝.5jOXe/gve'<5ܟ~,M8X@]P Xjh7h3ۊ ,륬ח GN2@_)r3@ AJka%|~޳Ԧ"{]DoZ"oeq>ټB8wou['+^N"l4_kAaOh_qyaV ꆢ s;'H6i†HLD;xejm h/yJ0g>xmW,t0aMjK"*3  0Tn!JKoDq\ .gcxQehR;MdWMa-情5  ڰC . Ɏ \ȃTn gtk }{W3ce._˖w F7ڒRKV)r˔0 $ vz 6g;!י;;,m|i*¼͸M%7ahjeNG{D~ۋo C6T GcB+'R^/k * Nۜ,Mb)x PnjgvB(x341EFD=Ww[.YL vyjp͟=&U}ea FSzx0QV@g$d-,5Є4"2o,YQdPX#Єe듻GY P&/\Yy%իkm>zk/JeIm; 5/ P2OrQ(&_@0r^!=p}ϗ .jjvr7IgԱ9.%Au+Xy&ކ"#ǯ,yJzd^bTgۏ9QHG)ΛGrVtt?SS(mscg5OBur=0}3,ިWixU1.CraG{VPFcWdCHܨѕW%Pxӥ oX,sҳ N#hIrQWKO/Dy'c`Šb A~?˜ԖqǡR 245V*Mj -AD0\Gŷ'*[R'hXw!͍N0e~AVL4AFYMr dYDtMx"y2D# 9O*H=CN+vWuӟD\Hy]|н™]m*GEq gb,p[aߧ0㤋z+; 0&":VC0c&<Á&9)tۆB˷6LjNahWxd|]v` qٜ];+++%,dg";Ds&wGՈZGxumGETvCwϺAӝn g0WbyfIѨak'c2h r\dr9~*aVXv> k|V9wMVH@8_ A¼g&6]=-RKCHwcPXLx7c_Ɠ0cߒrZבPXkzPlT2T\ r9iϞ~ge"+DֿL|f{=E $bfгqlLD̬,,L~rlދUq~W^3gc{1g|%k欬2l@_3gac^ѳB{VHh!y-t6ޣF"mo}mB -uJ¶ˋqytzŻx3'G4Zq#JfOf>P:yha!CUҎP@@CL;bw<_X,͵ńo/Jz&`uYXHTn:<9X5n\(؊#!ǸυO}j6!W`[6}U]V~9 >n'ϬIgl"ShdHrèpy'\c_?}f;]@t*+!rȍrQF֩ ^\ϖ4N(Y7.-іa  Z$ǚ,)FSg2vʄXAޞg';`G?2A(bs.GT튽B3;Lv@/}P}]wCV@W <>%wb:m@o BCD)", $8+6>R=#à62+B-F5=t#kNF( w|4qw`"[2eS7(ez| h ugV$*g>a0@ EL*rl 5:6䰩hun,%HadI$>+֕<rW*B0p, TַA~OaL4sZpTgq$5\'\72?MxryoD`04ʻ`WjX iڞG:g%*q /HSS>@i 9Ae2)7OYugVӿnI=@E,M+h\N笃7Rs> lKnv ~C@7/Uxlx_em*U$..Ҿ`;D@c?q;,F^s6 G]8stB0{E1w< H7ylcǒtkߺ:VO_ya|'CV7Wgcf9i$懞ApmP7Mr\Bs=чYmh,9vڸ_B?H$Jw|ՔFS[wN:T1*5ߤ5γCeV4]\|Q[^XH6~snƐc#waBn$APH_+{׳Ѡ4":ܷٞHY~+^M[fWNR0I[p&J$GfvP1(i겷Sأ&ޘʋg (ڂoPxf\*[ K"T!7-YgZ_zR}x-ʼn4 UjLҭ8Y0sR q+OU$S 8k9س額7zD! 9@Y d7P73voCc)dгBP_Ϡw錮պ6y,ګNFj:NԹ:^VͤW.ViDUtj̑~N\D`D^-_ulqf"7Ђ4e7 |S` RzY1WCk)`+f$~:Xeqح}Yص'N75=cĦ/M""?Z*̀Jtq|CmkdzDcPW;)L@,\&Ͱ1 p$|dBdi?ތΜܓc-m{5fTc`jeLu*"1DʐE-ÿ"_DӬRi9U[nAfh٦?;$NJ~l~Z0qp^ F⍖c Šؖ^}k H } lÂO*%9!c$V}O\c!a1x{"#t'J0V1(u`,2ak$[G7U0E깳πۑ-XYf o{SfXFm2Abgc ۠)΋ɒH"`{Xt NՆT#,Ѵ?p]/+hs4ZO||r5(dQKZb٨bzw~szA& T?HX$caLU}guBw smڑҬ:m<|&DФ*xoDI._~GNpNס~#u<;#=˯`H!DRޘn7"/0 6zKQcmm`ai`g -=ckֿ J; 9{L`r/^Wg&~7gp3:+ ,̌Y %^98^e2ӳr/'[A6lW K&WC9+L +ϛ?ID̋+CGk.M*m>`CfF7KtE;[=]#d{ЛIѓ۰# Fxr@9J YsXEDLmv=u'B|2NvzyCHl OiAEAHRS'_e]+mtR;#~UV*:{?{\IFʠGn#I*bx=P/Q\ VuڳAHi'a>tm/_ }(v%&mXi"1$B`O}`0-޲2wv#Hp}c-q^CdwQwxIi*sTcɩƄUTYv7z+@pqe.z;[nB&mVtƘ44qy%'De]nnmTVjʛ_|Zఽ 3C rk|O NB`7/JCg~Hv w Qeg ֯F|M>,%xoنFƦ}۠ Y&,TC۠ "G-9rֵF Urk孷 Yy 2.p/XlΙM'2m †GԚOhd-ͧCv_O'RhBtdE 5ʊ8ch"}M 1Gx&zukބ@iӢI~'PN.Բw4wP 90 e( 8':&0L볪Z*Nr>w2 @R= *m\oL`(Q [f4f,N&(%Y@kNAtYw7|*ϑG 1zJ6Y7f'%b2 ZH\yj^pPXjy Oy ^-ba!yOdHN9V=G%}pT_}lʤgt3O m"; PD"#4g%`7uR -Q鴩?.94 u蛋,"m@>b]zA ;#C: ivwtӳ]3g.+h^H\y Πc!cux=-ޱێ#zf;!€3p<}I_Jexqp2q<6 sᵋ]JӺ*Jaa]&c;JX<.8D0|Gܜ)LLOa8/㨝#tUL0l(Y3}X7τ]}FӴ} { J{:T4Q L]p3i T5$ #] rўZߣɪnWԟ &ݤ`S5DCؾ&K)( p(Η0PehuCCoǥh7&P~+<﨡9 B_ʶÀ:09zJ7[3G4P/ib* [^ 4磚u=2gs[~nԌɃ[ 7lW0TsEsW]MR)q< f&N$MjS+jO`S*m(ZdH̺ ]7;B"ಮ^ֻj#<Ó< VԔQfxX`Ew4.u:*#N{O0v}'򠪦Ф|:8EYաZeEz8Bm1bG}M48bs(:U;[m-L3k$dRLY|CxMVy{8da{/{1p(F 3ˍ}9O?@Rc=quWة>Pds`yX s2k[ cQf*6VEG7?Xٔ:,B&iX&z> C%O"iF*l* ẆrìϖhZقQ+3`J i͌Qm. ɔe:tz[/ም\^cIRcL˲uG xXPŜ?`D`#ZΈ:V m -8ЄdSD* ,YJ6}RBE,ӧJ:#:O]z/jg"e\{$algMГJP\ UbQ)AY5\s^(Y-X~cMwCv%Mm gWE[RA˹R ^L*Vx $-l6Lx4ݰ Uk~1+1_Ԏ~e&= s/M^"u?_X^Pw׬]~ oT+֬,z k "ץv5rF'_W&ȻR~y7X fEQʹǩћz1oЍ~OHr}_>B١5mt*!0SK{ dB E;dLSkQq./ƅA+) I4B .>GөA*ԜƛUH6qKC:!6NLXC\gK||$eaXll ˱ЎQ)u'rJt([s=?vVrcr;"Ҫ =*_lZ]fjS*1調ݿP#Sg 6@d{ґ[Aԭt62Ck ?b8_#dg-k֐w)!ƙױV4;wg$TC٬>]qu!V'&zg˚3 jNh!jxi u5 89[u<s5F| |O_ o3H:G l,;HAY>cks`3-x$'?A+?CڐO1f+CJ &U+~v4-6& 3V!vdIrBhIDggl6b"ANq:7]F# =b/rPU%~n\XX2&޺8J5~cKY˖ֆ'?AzО7E5:A'H_?AO<ZkA$:^}~vF'ڦr!ii9@$ p]fXMlS*qD#ph!b)V2ִ(~dm jmG:ь\A6)~y,Ow,lX{D=Kfx@:.\E6?{cHl`7T>PK<'Go٦1.66}ճ|֜5` k׫kl,M߱?3v?!}ݩE+S뮤ä>RV^ -7>kC*aR.Ϩ*HǻE3AcSu\=REXqi|tjCC9h/zI>=ca3l~>.Z:7UGѹ¶ƃ~3H_p @8|;qquc:e=S wKhPrV͛<272"دBd㘭Ġ24j{KtG6aUf(R31 L1>oK3%J>b~*T?CQPl]s*eDHJƽ:Yٔy("#{HR B9Ϩ~ڧP҂]'Oc>h|kTľ`}s^ub[(\zTsAs4f|?dFZ rV[$\wNy:6%IX1^21F}xdi웭{!QO"~4z/w_M o 8QWjb"(xVHgo=9.]0f4?2X;xCvv4' "E?9l2YpFDZx ykei WnaE$/~ObK_~KӯŇg,н!"ٵF@#%=mѥ»GDE{=o?Zpށ=ɡu9,ˌ f`bdlOLd l,,u6V :z/B&zw`>04,6mGvDs5>+c\Gۗkgoe2ݹu(UF{&ż2$\Hn*ߋZ9[˗& ̅|2ݩh5PO}H&~ ę7-Ѯ YzY^m_Y}X[*tC?W^z=mٿn} Ah=N=;.[o>\ȃB7! |oiix>1CQE ֏OaC=0ܘ'&#{SgU[y|Uə!g,G۔Rz5qZUn>_1eS l(SUsM+х;Gr! ꈌz |Nv\iwH φs;uKA[ׂ͏[4|.ϗ3Ae,0>ra[Fim3Ї|qIFSr ^܇xy2 =y?Bt& ].8x?o.^==T[khvɦ'ck=?^ujꌋxۋm/t[,+t@|wW ϧK"㲦z3dpaa`#@ {y񴪳>ǡef]\-3uќ6.CEu}_I ~iv2(?W T6*BN{gyEWpOE]B>9Dr#DX_ZfD\kYef>z^NK;:(yzzS]\uC! bypIV:ȵ T⻨3r`8^iUs߮kq, '咧,$C5X8ϧB0mdldte8Z17@ںmpuZ9!57ӠӣGu677S@  {6A>Eۢ5e!2Ji~Bޘ]uq0 -7pj+(jˎm3pAv,^KP̝`&@俞?, ic:&V-jO"I_P+A1t(2CVsBNV~'|"B'ɝ}pzy5{N Y͒Kvm&bqmqY-fvn-#3{L^`I7P1SoDe5{ٽ&q/a0iSqϮI}w) #UEw?Sv+*kKE\Ө(V{ #OCv FBPBkmت849W8q}eH8Y2;`q l7qH-Nډڵ8~G@-4ȐwtKMu2^8Gݡ`1(;T.T5!k*"DPkuP]mj1gL<z{tĦd:ε@$%& M)" ab/VΒ> R|t&Mۄχ53"T6, j7L/zTGb@ľy/l`-6rXqc;~}d>э]x6.[A?6v/[? X3N\,#A'jLޥ;Yj2Nu/),eO*:_'5EEŘ)jKTQ:\> ɰ4d3cM"z`0{ny8DM ^e_f_k.޾Ka`yM5534]<"=TXB:67Tn r(S&eBFCc&.ka>`M$ΑKM\` {fQg&U[4`hHlӮfY]1% eH4v'd=Bnes }EN98-'P'~ );A=,M^% ˘c#G $A,r>\{]dtӈT4nF8*ΐO\JU?IÄչ;8Lvɨ[-5ѫ)gܺi+[u!S"lIz_ޢlys X:0%ƒbA#N?N"Ɂ1{q1fw+#>d==*\M KfP֝ PNGW8^|pV- "IҺOcX.Lf4@KIqFN:$'Xi9i>MZr:Օ)D'H3{y6Yz/zHq6kQ؍O.ϝ}"*DhIOq, w8pqAv dB#g v?8u F62 l^@p/`YGЊ9b/ tPL76Ƹ%n?0ç{~}4E!̪^lV+-ppr!a[) :99bF壷գ|hODJI9z{i GG}'>B'N#~u_{h|3'VH?f= #3ov+Y"\ÇES$q+Vo)ۃ)?ZB h^^b>J){l RAsg'._p8 N#GNSfo5.Ʒj'K+\/~N 1ai&Il@֐mA&˳*~D9d%&k/3v1ا9I1h^=Jzgf l8V^wht]x/ČA4R9$TVi|\(?f *ȝ ]lښJbJ?-kf?o } IeCl+u1Az@SM=J,H ˾W;s'mm0aLŭSm2LU!F/^4wMʮ"@a=sᬳup'0;_ܺ_DM`=}S/dO ZຮEzy!e0< %h:Gh&T}RjvUxC44v˫d_鿏2aUf8m$CPA_\y=JvE,x(jٺvx4IǘKJR2,nYA'w !{]]{!{}=1]UVuZݶl~A||rOii Hz*/nENOqymZ]`>mZNq%(8秫|s@c/u7WjurW~]R9ޯ 5[5Nj~|_%C^j:0_񫿒ZˇlKݠũеbA4 @h0P,zb/"9ǒL炿tR=2%^0%$?YG:IڿTͬNW-uއ7Џ 4,$ \`bIM*7 c6%Nj6Q6i8^2^sh*mTU 3UVCBx-WIXR;!ye#T@9lJ[YbR3 2+caHGgĘ;7-eRvpxXְd^Z֮)Sg45n _tYfs["2,Y"zKtkښ</`.LǛgq/RW+FĒ˞ (yE02(mZS4*9SM3pXs!GzjgBFJ +Iw A~2C=Ȍ@9}\KvmVX)y>腵Uec%.;RZQ Q1dob-T/%e G}_qZ'Sl) %c<؃zf.'..Rؖ͵y*]} /O[$Ht) ]†OaF#钇,] +bzvtezP?eFԚ%Hf 1Y{nq'ja?5ϮiKzj_M]O>)5:E Ԥnzݥ@5MA>&p5i|Yd*͗STTgTk=$Tt^5̧BDO&R 6Y: *@Q:VI"؏sxS}xQpNDI_LZLl#'!h%bu.b`4[ 4mw` ARW70Lj~`X:DILb'W.օ=UGOV=H 1^!|S+^ d %҅;K'WG veA^8W-wH:]d"`#TcГ csv(ӇX/$Іԡ Kw4AQY"j'L-z"ː-)ޒ i8AVr0WDfyH-y!?ssogPbHl%& "pfde5hM#IsvܳȒ;0]]=6:}Kml[r\BeND$R$?dI< St:\V,>*¯pm9੃FXgyc9?_,p} ~cyVU(.L١`%ϘX̹7TjC1~vI"޺c鱓uR ZO=8dXskf ϾH%:54I)AOUqYϠ*R J[PlPڥ/{0*&xEδ=iÛp.6ԡ tNSS=EwΞe5fKF8(‘_L}oMsPu[;1q8KϋQ2ZSjĹM,pWMr`# ]\oP*;җ102҉O^tOĠAiUae!xb3.XDZr Ͳ ~@ bQEV="K~L+Z[q BcUen,!Ӕ_GM"WS -K jLtrfUXoѣM8GIRq>f>Eehm4۰ǕD&6F*SiRN">$gPׅVXOJ^8u,6 bs"ZRqx-vxkCGh6 !u\F [ZyÂO, Ϳ_64Ru,x:F.g"F}"ecctN"D'o^&OPQl[qP#ǖ5bzzI˴ͪU?j;6٘;GlOKy5ӱc9d$-;35X1lM$K~{ڴsHImXfZ\e= Ko,sA5zve/O2 *ɥh|,[seZ ݿ/&[Չv )(z1KڧNJβl͍b`0͝n;xΥY6NzVN3_ ^%t uyT5OT6_82.[(߳irq̎PR ٯ+'//qo nv`$hi͈ diRd *7Z֋Ejh+o7hV?jZx$pbi.]a:ǭq= 2Nv)9}JkPv]cY%:~[pn&/LrvA\&f0vHS07_a.oR(KT YecZ{fTop{OԄ5{_꺚S-rcw5%q2J_fgTӗ'$KPk8 м!=1^;(yf/R3)YFneJ^PPvb~ZU^)CM>N.ϛ84yHGHt1yD\vHeR4 ,sdl]bT;Jft Vx4{>N}Q2t(15o_Rp+QFSx&T eY5g䏃qhdN; QPL9E0!.w M9ӫD b=%˶! pWpCH7\>M],3TДyA-d5wA!M6|Ƀkd`ՇwyMWn  kSzMSmu\?eR'DߙGmO̽VEPؽ0i)/Pz̡?U^2QťdEGu(vL&9h/mٚYC{l^ ;dLfPR(\4Xzs[7RE;TŭC:~j}Ж8coqS?êQ¨9%t|0KdqM~(g 2PXkWp !*5>*8 HH B~H +W47/N/{ߏ E;L$V/V濾t/t-sekײ_>I ,YڙW;3(~Gu6è,ĩo8t)"y[ӼCM)64faﴡmʼ#y-4WvexdM_X)wtЛON9=Kt]E:!˜D*o-ϡ~cXX9 _'ր x#FVa P83V J\_Nnt反Nf99//(dybw0M,f0Ib!mAfᔡqg0: 8 .`'WxmZEi`xWw(N-mu3(J9i8o)d$Me0՜N;tXYf }^< XEu wyݛhILϖt>Y&x;ʳsg],ķT4ң/t̏&6"AtCϝ7cPkfBJ:"/[23<=m=m]C."8AVyGKZ]}??m~Bpةfӎ9w1,LNQFE;?W"nxܒ&w8٫b8OJ=5n -FLH7z0џV~TJemT<%ws$(oŘ C(f6mźT_j>{%$Azm: z3EJxm< `WR% =ŎUgY{Yi]B+)'= C[2Swۚ,M@ɱՈQ Mb?|z@e&r|T HLD&i;MnїۙdeiyuO +j[~Vq6}g'V x{LQ1VH UQ4Q>1#d~s#{0g~cSlj&o&s25Ο%ivi75Զ})fTT9&ML禇&agF ]F>Zfӟ%UjgmK Epgi_cU8R[}yOf"hvw,4?7\aBt^g?m!#It捞RPP>}%~io硏L:C(ÆMj|i~S|T QVAȬwӢ0;cȸҮ#Q}qZ F #;o@9pTk">uV">}1PCK̋g/XYMUT#mOo:0̉9-Di@m;Uڗ|4~;?v@Wx?c\@;|QTCaY Rkb!B@bŷFfi\Yb>Eա'- 1B߄Z$"D7n{tt ϸwKs1+h9u$Ep=!p+*dZǴGQUUĠ0?fI]ƚi +"?Cxfx yE ~NCl맩XC7vRhJONwPjRFl[4Q/#W CyYiUŕ]81aweGTW>\M(u1@]@k24 [{Y"B)XgUe" k,$!=ztv8xDJ2/_% JZоh Zy99!xs`üJ!tlA&L_}Q]X!/1* 2΋3ў'" %eٽD+:&`Cga!~N 3[Ng(݁ז:(zhvyIHD/4<,|?I18g?@c~⯁{B4LOn>KT+!7gjeW'~űāR&Axm-Z " @vߕQ_e ?~D\(PuA ql>'hBo"T}`$~O3p3xp CLd*WЛG񹎼._ GBCH?(tb_YvEV@/ |X74f}h1.ZY dR`R;;}$̲}z&Y-cmmj].'8?CuRSyʟH" ɨ'8o6 Re\  q-[ dꬅ„qfgE $Pk *$Zh['%yi6 !jLk_K_3άt&-g_D.>(ֵ$7tN5샵i&҇&@ #Vyi0&s_d;,Ge"d`+it@6g]*d0;CB^~09L =nٍ_D ]+6Ivz'TccrR'GAgnV2YlRٶ˙fFV-/uxK `.j50D%Z2Ik! 1ק޺-mʡ:EXfmHN)BA'd&IQ>nu*8:+ÕJ ՟^eqK);_$b_r~SP 5sL=߻_uy׹JJ{Abb&+T MDkI>6ڴn,`"FTK@|j?-kS'Pȳ.k|vjL{`;A›]-7&pϓ$RiC!c "Һ( O["tQɥ02י Ž690E]Zh\x>:i Q/S\X#Tu1 ќlhQajnT_Sѐeu3p;Z99J՝6gK <;N?ۊ}6)Nh:pOvv޳ѬֽuAАwVW&SE2exS8T_qf"QD)S VzƤ5&^lV0dDT8bdOI=9tE1FR(yW NcB):{1XnчFHŃՇP 1=ؿ :u.:yް2Y7Ɋlji{nm vwO*l.BClH 1s<>ޣKS|}0*#{ be!hR晋P ,VC>*ilϝ|g 5_8i:V{&6z|ܩr*w8s~^6C׎p~|~)-Ek.>EdtPv_Hrƍ5\0ULLDI:]ҧc7u-tIV필wfy.uۄ R֑8H@#W|D"~ϑ-frXӍ[57 w|o"Dt柳勖ʺJ1Y0iX*XZ,X1GS]E ]rF!mT }ĤelLg,jH 5Lö t$^x|=>{ש ȷy{hfjT+Yר(_Ol-Q&7kۼNWGOA)ִ:(k ƵެZ!J$ڵD} y'5n#ND]꓈ט=[0 kI=T/ވwK~[1}(>. C2/fѣYJ 1HwQo2p[G6#.7==y3:(q˸ɫ ;oo᷈" fcY 9įj؋j>w^bذzˮH{I9ǵqu/M8npz }Ʉ-cS_Hpܩ^y> |_v^ Ys[; m$9sqyLTX~Kzp؆MJ/7\ێ4re3IW K'{.q喉F. :an=ZROp PZcAa0}H={]-lc c2N'HU@Ff[y7#Z9U#Pgֹ91Ng;qUY/R/RuL!}gStJ!&9u}"\L3>bYH\[1 M*)]Q^scid i\S^QƉnKiL|[X,T!؀D`ۡI`ʋN( ׸>̴j,ٰ}1Ȯa wR2{t I46K橉׬->1oRGLǀBk_=U(b#elh*҂7CWpG9c187S$D<>5K n" _3NR8=Ȣp fG%,z%ʝ4}pE68u넇|Ey ՅߤTN-hn `GsxYG-Ӏ\A $QݎxvAaec•d82ch V`q)|KS?| 1]KQCe;#-0$6+?  S1;y>iNfS(GBW\^^veNج$Oʤ/ijN>yLL?Me:9al3cn6Mª>e \ڄ6U2`&;lG6n u 2oU6+[;ϩP[uQK+FN20䚫:@x=ѹb\$҇/H9j+'U;#sgnlDL]4jiԻIWZj-i(RãC(/S)3[dTVf tC*B>5 7w_ҚNޤcpd=hJ.]5/I,lj45=f&[ XO"MӗoGe` 7"Mʮ:{ָXb~LjԌ tKiI9(*8. "["X(͚x8(ʛtQBm@ =%S֏ ェdRɱ~O9X?[θC)1t&20_n-O"0TdtN\0J ze |u:k3Ōi& xyIQfgynd2!puM5 i6>-88Bv ~ )e/pίd{1sӐ63 I7 du߂_‹ߩAXNO!?pkc3s,!ܡ쓲EE/hOV*pŝV@ŝv/D`ّԐ@2-NYIeq`UR*- {<ږ-y\1:2%!+@Tv*gb*_Wlmm˵nxeo!%,d Ea.P[eJ?!)}JKΓmJ/ X%4.>7N4ew׆v+hX8\/)U YHGqNy&jj.P܃F\ZE=s'l._qYsƎM/}G7pѨsI/Bʋ_X#F}',-4j\Xw8Z0E)iɂ 8sIKEUFyRT}n&fVN<V!"r9]3beyP5̷+{˯AeesBfclHE(d7P{dDބl !&dEf({Uٲ.>y?u8_83A~tY>k?g}`vV^ }WŸr,ɽzU4)VBj͈rzy^$>"g[1_ٮ w{Q=kj3)s[N};%`JZ,?5xlsos#}gܩ]&|L(4#mݥW:B>Vcx2}R枛69.elmOşRGsD hξq0~|ؿ}-w'o 6 xdQ_?d:"eO}«<7j6 ~w}K.MQ9^ѩ^? Z:0dԽzf_]r>'iĭuZ=cIZ ~KFze`m^<{ɴc5H2wO@ԙ Ԕ>NXO*! pW 8ś]*[:K~NKZ"/ײoW3"rՏTjµ,KX-B˛PjS OJ.$7'`xrf_.t.V>Le$AuG 'wWu@2)Y$(wkWsȑ_V'FQt핑TɌw vC4߫.Kx }: _;#NTM,%&6[{EôƔAd yWă]>gLMw092 c"\!cԩ*:o 'xߛL%K+&OX*)ocm4>œ1/nsxH{?ͦR +9Sat||UyNYL8"eqgAfcN:,Zƒ7^Z?&%8 э7jhٻ AxcǎNQ}^/_Q~}^a|~z9fo;C###fV?zy8 ; =^?cϟsf7~/-.,YZgs{{s}k{CG}_{n0:cp,Ì>X~߇`onC0c~?t<(x6AI9lߒ( ~oӓ`$[y'>I1t*-AZ.GBBZOQ4qBUk?Z;-ţI[lnkh0-!T]ऋj  xfy<%!e[~oZF D #w#DcB[&ڲq-rgB??QTg ]X;gŌVEEiZJj҉/(㽽Ntι e#* AD/dg0 N/Ď?ET'=W,Jv^IEI_";p9ǹbo|a(M|Zߴ#I/xZ&e]E9 P3VU|KMA,}zG63u:&JqVF'qnOQ;q[`}avȽ)f h$He@C0ha濈o¢:wAW.`QFłX beɭe̽./ns-C-5 -^,FMo@t_=0X4ϯآZ>۲>l<zR]yl \ G,wfr.Xѩv 02^ =W/^ԇԸ7Co!'0 i3O1}\rL.؜fs\o/X9ҫG~Ŀ+d , 5J!1:vS )?*qe4Xߣf?@0Cu0'i-֋208EC7%o=lO9qH\!v`M:/ 0fFh1]~BqZ 4c?1+f^]TxrF7 foqx s`^-|{vrs:i o]%)iRo@rWۗI5(9[Om#"6,R9$fr}T rZSMxnAN#(=`]!V4XoܻRRgQx>R%ӆ{kRofKaF}')n b{HrsyXS@s̠ XfCGzN4r=ܼuOz!L1S(E5Ǽlz>"TBLQ a']j˙9 vFy>͹UKM͢RLJ%ߟ&V!xȢ=`wZo 'btsh98N(ԛCX˚䍙^_6,0X}6=cA*)u6,znNɴYheTo .jS!p+?__lZ:=)P~.n}YN)A^1]v߂ |4{H/U G* z{ݽs^𣼱 qpf$x7X3Ppf؃ ?[#SS5C- -;2bnoe?Dyp4i$T!iTbb= p0Gz x49$X[s5SC?sf8A $H48 Mw ڃs;'O8%$ 3#,ޮCLMMleo>E3 R*8H10аz\XS_I{CF@@#$W 7DzZZ:Fjz Eꐰ'Ȫ 218C0#cаâ114V34` Cv+ D, ,0,nвi_/0{Fs_/ Ɍ^^ UAWMy8,@Ej~[4$F ^jB:@ѩ{ES N"`:yЩդC+Յ ک "^9eXc^o0ιG J~Zj9AgDGbO&|QU% Vq&[m]glMtSF_i_\c7I ,y 3?VO4'{=+oC.@&E y/7`0(d$6Y˷O5 {`#W.H3~va/BI/o.wkhЊc3(r[a,%K6֯HIhCW8 J؋LKm}>{mA'A~iTLOݪ)]ӵkp8.PJh&#`\a5s{y:;Pp-l+f*_;F>i={˛Ӽ/)'[ނ ak-_{̷uzWeH? #uV/^f@PڠD(#?MI |!Y?U2D`=.ԴڲK)tl8e\ƥ ?&Іm\|;,Qn1gʡ7Pմ9S7^LЭbu(y*CEOaz34.߿Cס)kIdžagtҚBr['cLzzN <{\vҝ=Ԫq4c,Itc𾀉>y[WQOlv%nm] ]T6-i;^Jxw)vڠfH&r~-wB=lsRӔB[/R_M<;eT_Q"Sof{U-59o?YyvBL5y$ 9yEKjՋsU=Njx}ųkr2ʜ9K"5< _BO*s _f\o8"KLְ,vd=ȼbwZ.|mF[VAnE֕~,u}.t ![bwe1pJزk2S&>kӂU6&[Ư1Ov>~%UdO*%c`׭h_jo &i0SQ#_ղHaXkExtmle}m^Sq*t31K-Iv%bSǒŨ0vU{kk)o,럥\yT.ξf=ڤYkb+%Qpk/STDg .f}si3@"9[rrTn9D'򦼥! (2-8wĸ5ΰ_wOZFC>R4y))r4bC,`OPhzlӹ$ ,9N"'<St}X,aX@<=)V/҂33ƭU~hYwpUW/CYidP9MԾTfIu+6ҙW;7(ʿI$cG{7Yv^*`L&7M cƌRQ KZ7|ZU^cq?^)Qw9Ámeqʱ׼q ]ǍGM?Ui1>_Ć]Vc@7%?s\>(.өj42/.9FHwL| }5p{SJzꨒvsJV3OlC%51.5ۄ7WȐU> `#΅5[lU&@Γ/,2dƈ𘜍FW$җ7%ܷѸ70bO?l u_%RI>5 ςQ.\])$_walN\W@&0Wb$:b<1t$D!jwumJ Y;4q)vw[J -$i"F {;Mh^9ETzЇ:*Buic:`j ٞHr;ՑFhV͹MXʧ`x(ފzvrdP}퉝ذWc<._Ln],vmvFM\(i4PyY%H|Фn<ݨs Y۸S buTГ%j6d .*KROڂegs恵W;yD2Z ul7xXHD-Yx\'p4wNɮC Ůd }Tjnx<6"2V>_%`>TH='W 272us) ^+czucܵqCU7&pNa$rkZx[F0T1j}qgyٻ iMNG;%+<W-/8"$:i'bb!Q: FEay% ]l{]~&O@l+blLZ\:I}>"OU4chFs%Slmy~z*OBt?[bnl^zgjڻb99B%3_{tv-vZ4-q:/&VSd 㱴fpe0z)\:{NbD 6VHs"deOu\hVi")"I{d[p_Vc'-Sb (bĠ6ĚX?ىf>"}'`- .vE ,k&L*yzRm ]nzaX&a@E -R%|sҸA QMݹűY+cj5ۧ(Z$Q!X8hprLjUSztY::d*SR;UUbC\C[n x2ߺCNHv-L,I8Oxj=%]DJ[y^c}>kنc<י?Y<$?X1i^wCsl֋M`I=h7wd/Hf[(0nS:yf)+,FWOp৚OUHLjRWsp?|hS\afn$z@,O}2>wBQ֨*s 9/x4 ݪY3N?E,#BȐH1l_b> %vzrs[3+߫oӲ LG эqEv_.%B&[X>72/1$HTEADo>y&NʏYۧ_H>m m4{T2Yi~HW&Yc|&ʝꔉ59hZKI4S%/̖\yy iAMI'a TrK ԳBsu5_d}xφ׵ܷLQ׳yt?;;u% {C6LAN_uР_m W9:D-B?8ɍ6?!!.h/a_H髒;O}jF\xMdRCg)(#\?{$8Uj1kVHIez Q)ͽ6v\P~pT=R[:4W{}̽LOudd<%FqiwɢNRl-%'Îd6y/EcFjB)ih㬈3p9{ ̟Pp !fV7 Sj l) -cҵ:M@E49"%6m? Yc].ORL^MuBOfy *Ǟ倣jM<9c>Pz 8IZbKbag<^f%rqggϴ;=JJ[[A6;2682 _QQ;du[ɰ''űߨ1dfx' צ&m|b9l:$%Po.Z.Uv5C6.S:h(D* {< H0P  {GBa;_H F_wO@H 5}p 8ۧ|;Ƀ8;^DP v(k(, +݃Ee(9w>BP"ynܯ \ T󝽬;ǃCKl4SxG @]a,8&f^~*q~EI@ma;VR߶:N  =\8#У; s4 OX4o-Wq'8t/#x ga=. ( # QT9ΎC ➅ =s (xy)GxC9X@nY;~K G`xpgeH9>HX l8 #0 .0Q{Q8dp$XDBE]9H;#/i+ |$01x(-*6;B~H`HQ993>v:ɇ*f$uvjB ;RH_ykcS!(>YESF2p)nq;#=r#V;:JS"~@ x,تuHXR_*H)VKJS??uS?7{=:L>o\ѡsC_7|W*-1(>x`0ŊR"eL+/?58-~׼"=^X=#7Vg.wNfܫ7` 40-,h{& ZTo#YLJKz= q1aO0YҘ,22Ʃ%Kw mRu/?~%5U&TZ% A{vBVފAQRd'Ҫ4r\aڷ0d6l'm0+LP Rl^ך49X\4c+q6_pOGHĎb@cҝz!1/&^GuD_wb A cQ.N|<5D6UJg(pP 5݀UBjrJhX <8qɶO5erfc/A5ZDd߂ tPm*MʯS]8R|t͌)G ߑҷR|USRrlz$˱!kןluK ȩ])0]1[q(0|WpucZ78U˕Ui%y+)6Uv>h\.5br=}&EWxi֯c3B˯R߿VM#tW݄ o>˲ MdSilOcn|1g֞ˋ&>ԠQL+(^Tzx]ڦwA>ai!> 7{1EzL|΋fI+j ;pRw(CT#Ti$޷{"1`AK?mpB&v[_ t5[/{>1zKYL"Z<~AŐ` 䌹ҋW2ȒT^| 5Iyfᖃ|$_oa%Ld ^M"%\'3y,OA\ %hmiؙ;i$X l.9CROm]xg( Dm)]~e!j_c,UΌh=njST,Ұe}{bk~DMw_5^B_y[]Z=^,mtjܞieu2:\cmZ3%P=U ﹄zsa5-7SlQO[==!AF\4+W/jL ()d紟=7wR94k2[`O:_m-j(Č2I'/?_J!mdFTFylY#n%umGN>}6\þP{j2.etᛝ˕2דZn}Cv t\}tB }WTx)XqJ +(~#Sl+((,-"&2rd*YW:Ι4e 00EEs<5"VziO 01ծ0|6m^ Ԅ& bj{ۿgNO\LR{C[$i ɷB:.RL)ϨCdlsyG6=4.t%Z r`I /Jc13a %fN2NEx7|E,?l2dž!Td۾F͝54l~B%I;4 N蘒V}+Mɔ( ԟR ^"! <媟h|kH톻tKE13kM7tSŠHƑ0qdEN~71~:PR:3 ;vUWo冻t+d I&]08w:CaJϿ#b9 5G±E}WWi]H&ɰ;! {IO1JfϐW3`5*jkY*<ߒ{Cb޲߲n$gVgɽs&g_d֜kr;-|DvP 4K`͸Ӭ*P1x*a~ZTIކDwO$)^ ;r@lYiVex4-~rkQ G*w.;c-o5j: 9yήʖky ,rXY)*W~01GJۭ-֯>eMy%Jr#9V#$ ^P>!;;1(=tr %P YJ Н(_1{1#9O$oKI>x8v75]#YVT#D9Pk MJZa݃*8-m ?unq/\߸/閫a ~V}yH[*ED\E@29RxdS4 .7X^E-tF0Us4iQ4{)f95}-ƾ5*Q$Mlߢrڸ J) qR^)s$V쟵ˢ#ee%&Bg&|%"ںGm~I'\t)hB |ѕMH<&na?n+>ƱzsJuW~n'E`Y$qSHB`J0.eJ_LhƒIjxW}3zN 5Z8w+ _PjyW9W蓤@ 5"E'f 5mJ9@c5W|/Fy{0̰ƍ_At19E6%/jPdžk9J/|I)I"}.MQuA1z/u}CGe`})zR }3ke2y玳J4* ^qyR[ 4d;tܚ3z⥒6󭙙[&hóx˅Зmi>'4"+.b4AR\L{B;SaJҟm\-ۙ|e(y0SX<i뺁m^,}ۿ̽MD>](p=OIS'Z堣 Curbj09Lu1چ^nEzf*v奈$H:~UDB%N*RLݫڦ~ /aNL6@!{ίk 5IkYKgi.Ꞛ:s<jvk6G}MZ\fW~ffGRJ[E8!?u&#ËaaC/4&[2*_1L]ۚIzfR!?]]9>;!lI_ލϘc?`-Ḫ"Mz]ը[Oo:asVʢtR\Gkz6lq~T9͊EZkQW?v[dP'K/ *XY׷@6kUF*=Q20).C֧j\rfý$i M>tmrc=v.ܽ^fmR?!':Esqu`wDxq񇛆u6}!!H:Wڴ.6[h'!x9߻e͕ӵǎkn " Ƌ`ܡ9zZ{fpiuNtPC_3'D^/RP@N' _y'Y~7RZ>$%jsIOp93낦SFOaW0nc=wveUk&r4^!կ^p#/-u/wLT~.hҦ;#gnI8opjύT]8AoY*%lXјҜ`;5ԗ$L]ޥw[~V~'7-X)C_^MY0ףLq&HNKsf@OYKOlxuzjƆc0Q~ `.URe.URe.UQq;Qq;Qqd*T'C'C'C'C'C'2A8 ae+pX V2A8 ae+pX V2A8 ae+pX V2A8 ae+pX V2A8 ae+pX V2A8 ae+pX V2A8 ae+pX`V28 ae0+qX`V28 aen/qXdV2*oOa\.a|=ݐa|0a|={ A߃0a|={ {K=xBM2֝ 6 S\jĞZb(|6 #yh P3LԈ=IDG Eb]Xl(bfOv IA TPB#QIl3c9 S@.DdoKF$ɓ( a6gOM"I?sGߗ-"POD`+$#u@PF"O@,:o3b!`Q J6:F1c?UixFe*"S[IFr z hV1P qh44XDHcah!a6PB]H ɀ fM ajSD Ae6utԿ@yh yFU"x4=DӍNu Re6hq̇4!1! Ո<Cm:[yBc-Ld*t?Q P@8؈DV`\ z-ՇBe1D\<`XR FҠǐ1 C? t؁뱲0,͜#S:rq,".5 Qw@0u+gci1ǥ$IRA:"O:|2'sH `<1 (g#b@P߇Mxz#"(A!6kћAtYZdXA"*!>cK HpsMYESk NtBFm,@Mvb!D1xf,0&F¶Q̯@ƀSE{t `Ø ' Įa cOܰb pO#:hťDBB$c#2jj`T0j ),pYP44 ct![46SXDHhVHB7taF\T lBX!>4J ``zDӰ`1;-B c4&eT *)`bVG-x+Ǣ*bK,8 sCc ЛX(=P.6CXph`@(B@"B1${Rn 6H;1B,4n';f(#D1|sf(fNbLCDk79a%B12(hw 4ʦY,"Bc=x6ʮY,&G#xc@l"X&B1Pw^=höU,!$+ZQm7!1I`> 9=2$def-˜B] m.Lb7@H%5PX EBӅG> l2'hN*`LtA0c`H>(2́QBa|e(P[&0i,P)069P: ͢ѱ(vb g`"cM7Fis .L` ?f]˶ỴE` j/h`fQʾYLL` p4q &D̮Y̥0!1Њ @AaL` JY42&D0}5@ +DeV@t%1e 'K0N )X(D@<],N,Bw4@4>],аT'bITfM/bI 1t,=i0wK +d#Xf 1 P&s|`YDbx OWK`*MB9PcmD"1<(_ѱBa0V $IESOÞMƂ@&UKD"N]Ӏ d#&b8y~ lh7$ "$60V-`j7n!"sUKҁa4XF.HK+tzLӀGN*!D:Z&|J8ɘ(VIc㡕9E$ kc 0Z2D:Z'QZ}VC"g5ұl72H=L+iHRD9%2 "f60nw2@M i GDZZy@"xjJ6*`"=*6]Xб|ِ*g.'.JXA$mBEDk TrMPɀ: dYDZI6Axr?*-mHPД L됐iVGga5XDnj@.L!Dcų2E<&B;:pGL$qHԇ ̢c'Vj)ӂtN'MрUVkGe[@en# c*Z;dڑd5iI}PxG dMmŚ@"cdUl i?`WN߂@08 X& gx+ѱq.c@m)3yޗ|'FB_k-8nxp {fNi~81T2i9sC|# ތ(\2ҹjg9._S?:e-7I,J>q׍&޽?nύg7=3RWY{tlӮ\NQ^M=2Zܷ+awY P# agd3gY= #nnoY̹Q1)4|)#nW؜1 KS:DtAK-߷O`ɕ =`xQ{XZƣ,zP ץuםKn]1$$ڬw-_thkEMK[(MЖ*(ceh携ݒ]mZfj7&ȚگnqX_UU?R׹3WL0<*b? lie߮dBnphX2e@f曝q5 mq=-kVת`mۖ& y0Ǫp $*1*9Ws,${ժl6}=yO>e#xx_AתCe9J*Ak%ZLRS,ݺُ+{lwyK<<U<cI6I2-H9Bǀ觍 ׶U;Sʜ_Udtju|HYl ka^Kqqp]1c?grt8+NzܸWj(/|Iōd%}ZcN9~Z*#ta/9^3|cRM.Nv,40(ВPmT~_9Mm1tVp~Aik -Y(k[FBۇJ%4WL{@YHxsW>]b rǎE5=Z7gsmV}X&T%TvPZ%u1wqV4R56.IF'GKɫ1S1]xtJ%7(Ue /|'~?em1v92.>I>j4o||_|M@…U>=%{r䭃H[6iqB2y0suh^ʇGJI|~q栀ci.{o$MX="ݐg᚞yjƋ؀󜛻Ӗl.A[97>rsQ|!뿹^Vlu܎h}om?jg9cԔVQa{kQW;~6t[Tߊ~5vf퓾6.eyX]rrۧvCm9:{a7f{r"NΨ<~AM S/~N]qٙSjof.ٗ{lM2n/?n*bX,Q hi_sKg߭x#/pe9y%/Jdv\:U*QD۹0BSb{5o0j.|)N4o`U5gExKS7VV*+'к[lV:_mcY6#O.ݺ ]ZQv >[:iYGp ob{[ EfqqGԔuXw-%x\M{69?W8v^ݧk8].߉fۻ_q}c$/`:rhvD?6bOvo~}Ѽg%D]qE qIIꭸOe1bˠy`jHꦕ7uCz6Fk䟈}$]\8`!7<|P\*zrZ<.~x&olP>,qE]rzo:m8 DԻp>l>O=ѿjD@t u'-]ɯm\v۱X :L<(ԫa[ܷ2J"ꜶH^̫/Kݾ?򘇕}/c2~Q# Ӈkz.+m!Mv+\!U`\4/6vN\z CM266yeF`)"ٚՙe4] 5ȽF[ 7ȺД1|tR3>-x$J:U,En^Z5=IhyfFoc9Zid\\^j 8XqKо|WT~|^PcCJu?c7/.|a͵Ns/Ԟ8rIE몯︚HN@_C#u~'cIre13Ri50U[*a*1v,,x߲_z7We Ϙs8,xBtp砋C1{pϤngFI  { D-=fe~Bc[y2z& 9:h#-KʔlgwQ75\MK><>!&~!9f]ZUZϖswI{sn銝t'˺2ޒ9c2kv旆d-9`A%Ω]—x.a }67!~ MHr=:㠵mavr_R!?RoT1Wo4j ;$}!++JGڔ 6r;2ДZۗF1qBEvQ-M*)y+(_pz1Ej3"?^*Bu<⦗>{%^|.T8h7ͮ55Jʮ.Mv;pGjzQg߭L {V?n\oˬ,Tṣ(~i*׮CuCm󾖚r3/=ֳ{#5IVŜt+5-qz}RkKD:/ޏK+>|d슖5tڭ/ CڦZgGgs*a%nJ'>o07{];-zڥ8oyp]Ua A1$GH]3Ȁ9mI2nkvI٪ܣM5/$t{4?.|>W4KqĹ_:[.eQPpWma۵ ?8f'>MeN"/J}el+J j{}1R:'o2l+z,=`oyxZՂ^^^^^^^^^^^^^^^^^^^^^^^^^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [p|@%<~Li6~E!',OFb- s;>LIPiçP O`eH 0Xit YE3IVO5"b YL,8iٍNc\pG`Lz#HB&3PT6ʏX # "Ol)݆P ҿ+`!1*aLdD8ik(YF7EU!'faAY,JD8 hCB072 !QPâ#1Ts ,Ec^ BQ¼ 8t" ci 28(1e1\˃% y1Ю Qb9Aha@NG~ݚT6oXYE(~5A h9d9AFZ@R6! "'8A:#j1I\}#C v(0#>! i%B@*PG8}4^  9F4DhfB3@GТ7gCh9(3ks'&8(T&,֍3{w"4N8n?)蕦 w3 B<"B㤀v_6M=ћ#lu EqlЌ@f,4 rFIPfP@6bmAƒHI}hZfY"߁d s@::@y>s@  0a2T*1nddW|%k׺$5o)s9Ou;$T ^-GGMsxr4afj(3O\ٜ3uɄn:}[k}yrwH|H"|brG࿼G%Ψqrdt'5BcIlKzW`دkN>zbՔT\r9njҹ=κsRq4ՑBj'2v '^嗤ԏf7ROϞAر-? Oo;J9U#~Wgd/?spW@בM_/<:{fkJ'U'=P#(=a֥UKJ|גz9tcx$CңЈ߼ۅ8ĿȔtq@KdqqE 2CMS14DF⥚'6!; DU(\|A\$C2;:>>P$cyª`]n+=\ȟe_JUrPr{ZKd 8Rc?f%ӈpw h@\Ri?|,ݑw7Z%Mb-',R>~g2[5XVxaq~EA9 kvEVm~%ˎG^|7YpiխyoU">D2z|OeN|ABR#Ϩ啗lRx[jWC3_&XV)2Zv,/YjoxqNPڣͳ]&JZU:rOnAmo.E?egݮ "5rLQy= OxAYDGLk-};.75Oޏ4.F,+0};`x]kgi:BΩumyO란JAz͔~ᥴWXr9}/-MEb5Oi}<&wp?Ϡgwc)J6۷zf2$ă rR%E8%~t|z6cb*~0g2ZCnh=ʯCXO{2~+]<c&tqlVSǿ(RZ>7&!&J`RC{䑪7.UΜORN{Vg]ò!id򧗇[oZd kO<74/_zZޖ@ +YT9dҀwy"dR|HՕL>[bT|v 5b_YoNIvJ]ٴU_^ݖ`QT& f;$ Txo<»I+jr=KFubsqޗͮ_5=5M]?w SoQ1.-?mκuA);ޥ4ݫ} 粪bSyW,6ᗑ g2I/Ҳ2?l]{:Wi򐻅fG]j k Fύwk;z5YqƢgյ~r2O_bydSurZ$5ɠ'!7 >^PZRɎۧ)-⧪*~JO^a1[4#lcK{JDܧ|fH>*A$?q˫>WNrf&I<*=75G`q ^fVGHQfy6fG@bn ɠQ?a c'sG?#CG,Rzp:kUVs8N[;=o{xl:]uˆwʵD_Wؐ$OL& Y4zBo}O+X/FB.ʱuW?f.WԛhxiVyK%'ils+tZum%QߩE+q27.W7,y1$gO SGwv.p[%7hIW{A򸓧?|= pmst~sb߈q=Yf4'ǼrQũwyLӿpX5ICCC'96Kqu/e,-uvTI]iXsfϵG]3+rzqy{G>JuwYe=>G6gﬨlU:0{T)Mb:w~\6%nSȓFΖdetV\][xb\vٔ} NV\uZ|}WS:כmE&%Ce9Q n2['_fFgG$LݒxROJ?T2{ȃm狷>/`ɵW_E/~Uu+M`{j4>ĝ>v V܏[4i~rYp{'>=)XQE4-+9zkmDE2囤nSvd..rKey{DŽB·{iܲCݯTC޼XP=XWzsžpmVm7+[pn<.q$y x|s+i).yt:эp}>[2oNEw\ %QYMyLTAs;mw\-)PĶGղ(Pf+ k:?ux;cmv"a٣/=UMOj乽jړfzu}mwY_ty瘊mB* LlseE6 WvD_}킽|:^{f?[&=áoO=ec3?u[a-'^w'räwzp^9=g([Z~"E($Q0GFӸ][<{$NnT,[CƋ=qYr+ֳtC>4O L-6+V^)緒S(֕i%qaP')oQd)߈R,mw Fem㮊Kf/U﬽V)B+@!{6[f)m/ؿ4A#Z @ٓ}{ vO'8Q`#'ܟ$ g.Z}ʌ{W?P68:,ie==&%}ZR&ei}fKON+@Bn{r,c'=εp$^`OW=<,L/k׫=sd5)_s&^2iJy]{5C|7O\ X@>nS:cAD)Z$>)ze'ކwmyjF.޹NSERnۡRfe66W=)+,םAj!0`yrШفjRGyzVJ?Yn tpR+G;Θ@wGZx_P"e5e(\5nK6>ۼ4&˕+$a!cyZo#wֻM%j<W(J;&aϊM tG=ֆ1tma'  %B7~*FP,i y=227ܨ7Q9ӀɬJI ?iu[E4vaa|kMtaDI2iN?D[0mݳY;V|)Qߴ7B}f[`B\jT-$g/&T^۳;heg2*V~ې|7OVjn4y<vMPp.->#ſ.W?u {~ 2޻7sNWk!ZbTj_`BwKH#획AǓ,6w>duaXW1w? N6CueCgՁX!!/=y>G^Zbh-8r,%E^~WA.ondWW^{vMM>Rm_ yصbsU2T< O9-/ay[: y~Yͷ֩nЯtپ~w[҇ ;*4pL]Swo?Zwm"G3V wKYT멢ղc]cCŞ}HUX,[~_<KtgK:ByB5p3 ՍS^ՐD2-14Qٔ@f[nrR"U!AQ9`\O 0<(^4B/ډekC-[NYC<% @(j^gi0UujRl@~Lz:ljJv{Ş\ڎK,&gIq}੪aNWqjɠs`}p!&̗0ٔiLYLV7U Zz6K7'^iA:߲Üq2-*[ew=>7.!.NsN^=r'[h07 W*` ȶb4fU҄:c.g1pYBli4u82^0e'X">J {b|r)Fatoa8v?zI[H3,XA?lN5sH 4iGܟlWjr0hcIa ̙dNNgy   ޲яNMPȌnU)N&#f5 b.^*=w?uNoُeL9W2"YR¤Ւ{ar@b)=ҕI%Ea+qb{]AIBMlRX@ߺ`!`xH/d)edu >wkP|ߧ)E,&p|olvlįC=ދty1@e 2TZڠ ͥ6c %Uw;R*xDQB#2ʳn ;!SY{=3y'm w{p,}(˟Do:Psc{s4Lc;YʑfJꄯthlȑBS`cM.^gW{:uוET]dm߹r?tՙ[__ o|uoNFo.X) `X6;=p\bGj`qj_?ms(!E(c/9 וu0+k!ƿœAc= :d i!(D6 >S%&=M5 8lAz# R f؉&~S>(KAj@r4 L9o }\wts.9B,Od97+? \ҙoygu@ޯ.Kș 3±YM\Ntu3ݛ|FMJIKҗ&ozB,[|!W_9&5" <Ѻ9MȽ8(:sR?l h;Zohv!CospEFrPҜ} 94`4jMA6.;ݲƏ-n{@bx}  `[JK3|jf"5@A熂?<"5 B:ek|xI_ǚs5FR컼z(۾_1ӈsdq[BJb[K+IU{/w0AtR<]}\cdlS]h z/PGYPOJ)攪5Шԯ\+|Ż;lڀVTgXwW E~릧aMLQGtnZ5LfHNS;~%mʑ!p5癕=N-`o UaY^*';S/Ya`,`3® xw{u%lqq|{y&u[6gEV ׀4-\ȍsHGfVGlkFgJhXGUS>/;y֮atUgӳywEc鹠JXda&LX((ORKg. &zuN_u{GH46t&bb jFp995y]}I%LA.~#R*@͂˂-!HQY')C mչJ m=GdR_4$!{sN0n`O9/s,&y 5x[~^prnL3& &FݧaxnT“D߫T\: +ƽ&ӡ'E#/DBj,DE\tlo A^bUH'ݓ$b>DUT?xuW(T5g謱@PyXs}pe^u=[{/?+ꎡ3[Z#&?ǔ/|yf ?~Y[5p-NPD^[iLG *])8Ǽ R,EuآޞD$4f&^wz`jƣs]ĹǦ/ d\<.dض^j'NU5gOUOmvsk`̇ eTɖrDخ'N4!/ x?;/ǿy*"$k G!%~~_:NA 2 GVfG6? Gzv? 9Q%Πggeo7;_Bhaakgg`dad%?pz?[1P^X_(_σK?<^db/'gߩA6_z͓p[.C>8>`Z"Nt@NBLJӹ#'Z<]؛^ mt?ۼMؗ;bp,T Сr˂b{q99 |oQZ! Qey{ rot)N%j_k+?ogyw aȍ{)pg{xgu d2f Я:#p-ki 6oX6ֈa6A4Qa.>?+8ߔ/ߢ=ܛ5V*@'d ;G}d~|*7fmBvv{/wgsܟǠi7a^8~gX}Xm}ي!1!Vq BOxtv} >95Hc}+^;"w4} NU~8pm>?7s: Pt[kDw O|އaG^>c_ߥ?}]{\(~rGi|l/s@|px~1}h ὄ:| e۴&x/x]o.6yEdz?#"\BBA?t sij鍟{t^=v.Ϳ{A@c=Nb4qw+_LXwW|cǪ#Bf;SCGyӠX9˃I!<#*n[bu>M@k;muk9\G"Nh Ucb?x4<`JSAtU7&55;F ^>ݡx:c\y-+qQDE7RzTYq?FyWf=sQ<\9cIGs(7$q1UgNQaqsh0DmLDd5,8_航G0ޔaklym;[4'F08Y˻Of8Q,/P xXlZFW$I%tzxxKK5V%/-D kW3;t$YGxi0g:<6e$:|\kRξ8Z!^Lj5!cT҅KVX2 &/V`Rي#d:xyGΘ83[Erf)r/ r^\F3\gLwZuti/"W#BN E>nX?,\K &f|dl nsAfSY2_57g_;=Bm u`AѬkӕ2[6S}O= Q`q<`؂{Q~f LLd |NjwҩͲ+^v/ qج_v>Ѣ#*ib~2+SQ1](`G-wu`fR(ai `15G& S((2̆Jwgp] :so$-_TKzrC%>~l탞R0h}̯+f%P']7~Ԑ`gOwOtGU~,nz1ooZ8HK{HM6}:3kaVnVP\z]Z7QUxՅ SO(}{4oځkwFzJ![0+3#QhlvE(_FFnH8y.O;À'Z̹_F<8f&bdʜ@!.*@i-'t"kEa!锵wj8k+fA)e"d:.3 Ô\NQ [{d}%OJƢx}6 zgQy*D| yJSOZ)#㟮\Nebny$lIyyeQ{ cW|'y]Ÿ fnhZgm7pcƃd'YƜ3U aդUȚ e4ɬ4X:=*&{Z~ Xi'P^qXs]l1.B﷈zb$2~B &`TՙXx#K(RL\u4׼C+H<-?x2U?z\֮4AFPvzm4kJ90kfOoL0fTdO;었Tɏm,VRh=jDϵ0]X9&O}tj ]"z}%#ƂxU"ilusSܛn%f (O); Jyxk8Zk,c@ [V#;yتW}3.E{DQ았ES ae6mL}w) RfgƉŬl(DE٤h 0 $ >nF%fKYQVuKp$|pgFHg GJW0D>\HsKװ E?ǑouWTQWbd#- ]A'4:Vsy!\,@ %586rGZޤ!ϐ]x&-^W^Wr .6ExWzȊuxI#Ĉ"/|h„t4lD#:%<3#7OR^bLi־NUb #fF :[A_p&v;6%qEݕ91Sjҽpqސj{E3u]H-~9'ۖb(٭kd?l &J}005A/&ۀ7,ot#Gne{Xhr׷V7#cX>;w#s"(GoPzHV|is"բ—g_O6zR5b62 :,'eN@RbUm?=0Z@pO(bLSz7,w@LR=P[7.WJ֙- _,Vj%OGW Ep!#I Hqhb1,pTmW;&2h&^%9#r\Mƫ+L *jx8qOG`- $Ybx lcDž6-9݇pJ#cty  EwIή ĤQ+2e7Αia oDa-g6-D0 ~Ζ6W=C5Sa;NndS[̠ngDJm?p{i"@O/-ӫȱ|*glz ց"~ `1QJ ּ44`e]p`sMI7 {c2TJWr ~)x9z|cL>f{z-a {\?0Qot0!M?-1s =CQ=p`<h'3!i". 1T|e@5@EA꽀~])!WRB:h>l5uDIvulHx\6- tr|VR9pFo:rqQykQ"&o#Ux6-J +Gwmc& z|)vcm >oy+=V=w p7hc&s$F\ I:8D$6Ӥf&E)kjTo"Hair*6uA!܀fz ѳu}CusaOInhu~.*/Dlz(k~ l$뤰xݼR>`~2Fy7޲U/.i_Az9M^bؓ{m)\(*>GYಬ nAl7nO3m$=iy({56/6= jJaRZrP*'VyPYZI֚+n[4](^Qy.u6XT3Ь􊈞,49 _G"7#؂M;:?`WR[x;7ۅ>~0]{4]40 kQOR4ֆCN lfIeXg(xiE4`kA[$>zzy< ;:tai|CgDE˟U=MCdQ禤|7XP]=#s g$iÐ̹zZM]|)4%E im@ 普Tj+Tnxmu| kY%/|FTWD_oLMF9E*"s1 L'ڋu/ѐ7q ջe\VXukـjXWנ-F[luk;l ?O_|J" ģ#T$(smՄا $TR4_3hNfY mјufjf_nL)ߊ%Wf2Gv$Qڞ ygƶŶmMq|7+oju)W ]RAk_d܉#4b[[DʴL"/+6`31>IjK¨lp0b2*2<&*Wؗ"iY4=[ eU&i¼;W䙯 1K:sZ8E"(xj[bR96ǣ'ꁃR9"7Fzئ%ZSa. D95!}ewI\RzĽ>z|L\eY\G:Cc2;ᘲ2pohWge3}oU#C+䄆3=!uQ %Qa,`$PXLpzu0$ϳ3Kw~AH '__U4I94-fԬX5D*KQUk+uV~3hRCC^|ǥ)R%X0Ees \nQKҜ, -\[V&칽}+i)+O+ojw&ze\pN =Dr*~:3=6TԮnZ Ex##hjpN({be_R xS dޗ9 YA`y?t rڑVJ#eF| QMc P7\d f3 b7.H@IRN7-w\rA_@ol-l7ĂGܿ| @ H >t'` pb`wZ&/dGX8?v??{פ??f+vWbsQ~2103N?;I/hـ7(ï'$k9}kZ `a(OsΌ] QPi4i(}8fK|%G`UUI |{gb8P[n@.\~~ @BjqǞeN#B509ao1S-K #mM>c}Uտ*J:] ?#"3zGwv ]Dm# 9 DoMo{kSzjG97"~89Oۍlb.ܨCs[ !v>eL]g χ:z1sޜ]O(jxL<2םzwo6>;݆8˺/_!t` ^]tɨbXvaz6 T4٥xx|۹X1q~x'itispg4߭͢elϺ‹C+ - X\{e gD͟cx31P&TBE7Dȧ R&O^HNW@o71=b.dżo45.OJmx~ /z.RcYyx~Γǯo^ݗͣ}p݌4\ :6i&/h=o]\NC @Ov[1V{h: ^~ux]}Sߔy8x~ i OF{ׄNC}lz 絀 |oC2?*y]\ #VnB¾MmQ$WપzApUkVK]{9>y@Kv fU_svAe\DBt#G7a^mpxѩF"-!~V6SERJ44Z)7(4/; )Zh6A)7&]߀s ױ dL$v]Є/pʽmjQ$7,Ȧ11RI$6yԞ|U4pUE;s2%V Cf̆Dsaumٵkk%vˆM"d*c}Ow.jIMrǑzk2y'^d-]JM:$cPr롆 D.Ȅ #ۇA`m>0ԪPAEpY1c*QuC;eq 5'FWkXac*q++tis6 _u@ zh6ud4!H篣xS=~|"-Z3,;e]j7ũ&KMsВ`/ƙT90,:%ʗ܇䩄{\*F)}$mN5QV-+`>6Ijq8b!+fsQ{0"(p?Ex3Ю%c>z>O~sEEQ [ߑyӋ#L ;'w<nXOѲϬ@h"Gy,g;$h}O0[TT.IN39Ks2 b2Rl(oD vpNrxgZmU9W`};~vzLpKkÏՇBAoZJ [:-ñV!Un=.!&EO}eZUa&VA,3=:09ZOD*cK֔abqemn,M\bIsߏ>槶s: ]W0*.*_\PI,F10+-ub D ߪ7uV.+jZj*ø))&,ULHJ L E)4]np[ͭGidΖׁ857|,9hIBb$.4mn_Eo&)g5u9W(k-͆s5>.sE Fj*]f,ER{]wqB}e[Ǯ7i'uFjdדKSp9}e/l~7F4Ů'$ `nɇ4Աޣ%D:]KO'7zP<^E(3Ed kf[Jse )2_?Pҷo-s+pԙT^$DF:S@C+֧i_{AsiQ/4,=yf<3VY9],T\_fhSPL5)z1N"P K%`.R#AƠQȤ1 H܂3pD9<ܸE[\k=q"R3Y--FwځNǶԤ'7kO` l@]Xind]\_a׻JbG׋x%͇tV3d%JtLܭ'cgsok9|VDX/W`!RY!7B42Tll56WN/}y88ݲS[l@{ǙW`*QT#&X_ȸl-M)5Q /49Zzh| ]xESW Y ^caess ڞ R Jʑ=qLsΩMfM%ef2 H +5ܥ~n *K۷BᗞPmo i ?C ApX!z~ 1V/ VL2|닕=ֶ`\Yv5v$1#>^#0@jvLL8=}QP ϫ7+rL$ c[>:+CFHhn|CY9F"4} "Ďӧ&0TTO7TnELW00b )LS.RreZGG VϮP?3>cEENn;Ɖ<5$[-\eUbR !.9[x'rrÃY쏹&cnElJ&3V&doQxJf ˁc~vҫ!qVSRq]ok1w{DMQC5X_0$eq%5 ؞%j32~豸C(.R_QybsC4֎Tpf[Vu h|׏d^"ҩPuG+Zj6+X19 mx^P ^w;j9MtD4\&Ro`ջ$`e]ط^9<݉et3Mʽ":Ȉ&ޚSJ{\BwƜސSNYݪO/kD&&y>1V$1E%}s%9F(8S ?7ɢa8B@G$5p}'ǗJxQȖ-M.Tm۶yʶm۶m)Nٶm퉙{7=iG3W+7cdWU8I#-u$hUUC|/ vzhlND‰7_WC7ݚ`UM\ 9n@ydE}N|S8FebCI7d*sWP+/͉#x/)xhxqabPoAm Zp<"ʇQeTǹvw/Z3A[W_֚ۺYݔ#}%G]1COVE` )qȓЛj걠`jaqMA`ଘ.ɣ1Rcjɹ@gIxY (yCCjCz oyyVB- { \; ʮ?L/Jitr;1*%{=]ZwGRkF}P}(q6^ʱ6 q.޵N._ݱ0_3􂙣E#`n̳'MD<ɭ"+z{>{s .ėŪR0b̷Bq/vFBY"U&_B(C\,jF6nٗ̚yQԢ|1,& '}gaIiv7SCl4*˒ZMm t26o!+1o^*D/]kaT4EvMt_E "ȝ8F qt4x)^d򔰲W*uA-:N Q!p=jKAͭS:TYiRܦ&7Zqib6#9Y!6[wIn0sOr8j%&k0/jw@|G.FJ&{=3O󂦎GBgے)¯cZ[qJ'\ߊ0:B|^ն=6P4]N0+H9ƤZt$,\փZġJk=G ~.F6Pz@x]uE:WQYi;AhXzoB:7t׈,Ի9U;)⃠nۈ{$F$X;I3'&}-E M_$gիsJ,BK6xpHΊ<ʂ[mK`Hރ#n@[peeh%{Q$"Sf(YgEu|8d~"}GZA*nf6(?B$T뉊x 4GDpwdK"CH_ N;zҏ<@ɝʒ*{ @b+&cu9@#ӪmT}heKA A+7qc8z]>:o!߻*OFB59&gpI 01Cs_u2?$r{Rc KMmPBj̒Eؖ#3ozά̀/K :$0`0NNTZ]1kq s9RJHgIcF6;kEŁW0Q®e$$JI0.D%͹4j <BُgOE 3$B$}=XBZi#*筢4Yj D:P t h C9&#1X'7R  y$3AQKYȧ9M G;@r,sBhqWfTJ50vnWUÚGˢD|Ku˳[bmIq`9])kApwe(|k.4n ܿ ǣ11t@8?gaCͻxrwb1 x٬yiSRiNRVIm\ƺ#Vb|-i%Y#<ˎ޾'PX4rm! ]|WX N vnt4q]ޠO<~^>I tG.DV7Rϻ4 .ZWBBb8,DQl2-^0k9d.FCFM$\?);4~L7ddѯdꁒk/WUQY9`uzw\7}5L0,H.#BǃIj3MÍm'EUK1$Nw-7s'Rڂ0vZN*beVWhodŊS6m\>S[҆ºYe<^r ކ#z7xRFjgi+]n2I攙/2yc^ (IQK?UO091pN“w`7iuWEObѷT>~wOh.JbB$ͻ"qa慬𾯄ui=l+F.&Ǔ$ش[Sc(N/a坈2AMk]&_u KUږܪDkQ DՀnR^u g TOE* _|4klgݒ+*J;ˤСZA8x|BΘFa h^,n\_ =ʫxW]/j IwĹ \EMܸi7< Z 3FOA hn߳,yQ:=Z׋cRi-h`K^~Z1QgHg]h9ec?yBO%X߉(y"Zuofj~z$h+=ᴔ_Q.kjhCi7{  #M4+ʿWA[qNzqLa@e֊O2)5iu!1R7eh}r={?x*GwCq0{~;}=ߓH2 _hpKly&5 N3V?9#Ϫ-B͚$! V]À$דPlWbtkȃS11S|aL <&"TаƬ=MN-5݃dNAXĈ^Iy^llWQLxb5jAC*KWS/0]Kf$d},^,H׻¶6i6@kn 8kPT?r-fYrn~5i4 $$w99 V{vdƤ}Gxl흖dpD#W\eȧ 7SŔ a}`/,_ bP'`Jx.իBCsΧ=]ʋ4R͚ w 2XHN sdha'M%n[=MPڜfk3=+˝PU%F?FF(WJ,X( yX ۦR?ʩ[4Z1 vzU Ec‹]ԠqISr*Q% *N့|vD[3Cp56QwִMW4~p(x9x7-q4 ?[f*a|2ۍ>&Q]-G8q`T׆LB{֥p8<*\̗'"rF xkT0Evb\7Rm/+ج1tϗA[p+cEuWj>`iن=4ς:z8to'N-Lڅ#zy:%K뭊n4'{TEbPt3 {d|{+h$,htU"U )ۆpL**7VRd3#gux((5q/G}Bv4dDqV@`)YڙL#`7?qJM(U<ߩ 'Ĉh(~p@}fB &g_@)79|اr_=P$= :$Mz }!'KOx8p~E.1* l)sm;#x~{ٖϖPv3j<UOd/O_,֥}$f) >!IDuGoڳ7Tڍ D,]58rqQ !~;3tB#5IZsDB21J~N.Zq#}*os[zRSgЄB-_3Tl4于 xͯ~'G_E>?ҧ!ī 3$ Yrjޒ=2y[Ƃ?C7$ӂ~6Qn/4 ž7\p>oFh~ͬ|_[87 TJe4VْJKz9?x"96K`~8>Y3ܓs{\vXWz&Г[0qNJ5OiÙ+f3$ՙtEN1jU5 7AWbPA̋)5٬(&k)68 @JȜ]8~ùMiy9F \{B0Z4gA|'yym`WQ4?J 7ibTm_͑&I9l麒L@M.&5↟ JG6 wƾ-#>(xגe |f1>!džV H`4Xy d%xU)dw~m-NB$ޥDind1nʀaBO7Z)eSmhY_SBho-nŠ•aSFYoAU R#-k 7߷xd}{<`ﯨ~l2=鿢2ʐUR[}2ʠ38eVc0_NVFf&ִzVmYZ:9КٚYgfcH``JndoCkcmDbChjodDkldG#th~h`ci[%o?iEHDBE,Tv&C a/2?8cM#q~?f̊0Eo"3{r m}@^.v%~&bq#~Fa MÞ"t(B VBV9)jR^RY'dJp[6I3n K)nhylݤTNNh]cIuuA`wet.ZR NˁbrqHCVlXم"oYn*Jj{LJ||dx9I|A ՅZS kil U7Zj-s\ANK̊[4yLˉx$&׻=-l (sU"}k6~},(8^Z\0]Xzg8jclnYm|gbHڋT of冿)Q)2tpFM(;*-k$|?1Rw5R x;R fgsǓv5LjY/j*=M9ae-%rED`@ 6i9\͝4,_v{mيaN98;KW/O1*—3 LjFd#6RZ0fbfCu2ApʷzYZRWuĜjFsp9b1كoPV#kU6қ$!Gh/eBץ>0G O/WP1ҴYu]tײՔ^OWh] IOPBnlqz&KxJ%cɚ'CӸX!-7)K {YE5/x"$0x^93z-6 t !Lv ۨó.Yև%6p꿛pOULIQaHP,\ϼ[F@|HЀp/%x}.\>C:Tӫc^S9?C܂\y6/j\ʹZSu@-w%܏ ]n+y]=憼 %BT^>;i(ָZMpj㺥#0CCkJ°%<5٦.2#lp%Wu?P>JI+Fmևi{|~aNIh"9& 5jv[7\UqgAAvibcT7bT竿:T<Ԛ)Ns:vp4}?2 \C!^ ұt*th2KmWñlP6]I]5֘<ϓgħPwmN\~&sk`xBJw|0?:{Iq 056RYn:SGn󀽆6AG:=Sf`_ z zΗWZ!4J@Co}uoB`PS,ӄkWFXt#hw( ^pZCtczhU:0Fց/FQzkW;c[t0ޏȧVarsș9B0kKm;A56{:r֯b 3c̛iږ_K0IgYZ{ fXJ< #YUN,FyV+=CAD$:[^!mpv:vǔdc~2-tvnJ#~ D" z 41'F?Mbb?,31犗_Lŀ3;﵈h ssaO7i17>k1f7T(ony77tbrҝ@GsCH5~)`z{8jzEbzYpoe#? 8^6{.xѥK@ a 8C!h NWt}+/-x.3Ou'̰28$ٛOa2zH1^}"w >=Ydx/ۧ$|Ȑ6IͶPS x{3 |U/w)3Odw;CP+)r4ryc-̬ 7Ow`GNAv jσʕ.X6Y!T=29'`wk~l'qQ <Z8C+w@%S"Ca65GOt nn^E"4g7p +/ٟ7^΍ΦF궺=y~+faD7ݘM'őVAդf<maYӜp/' yp΋gP b،+`y34s\dxSLדHV]_BD`"OQ_eHO6V?] CZ- Z6R`k39P*f>CD슓w%q+EĒT D)"/ GW7[𿃤!wN󭷎~Xܠ+'!HYoCS sc#epQЁeCR-T% Ȱ/&y۹02.uLCj-NF=QfwueI < _kGhM)ysUc\G0fMҤet}Lj8C&3OL/uO gٌd@&'Bfya_8݆B?/vGƸi Q<*v@71{|6V[$wѼAjRfKd0jsuz:t7sm-nuğ혿.\&2̕IKkvnWv bZDL9;:||_k=8YiG*p N8xcAi9vXLLמfwJlfIT.w(LBT$)%zTԁe{%裶7iw_Qnln5Fk5*æFM \e'#=sL}X&'ӋJ8s$ɋ{P^tQB쒢ټ8fkK8nKg|m7d)[y$%AeL_WZTE:y=Ut ^OoʝcT(ܔVhH] uu8流]J|mU<̱:jwH a&TOb*m;g 9;~pMmrÑƪۥ=FߕHN9*Ѿƍ:%1׻!3>kD FvUx0-k6=j2sf\&%<7eaK.:k_QuT,򈏔?D93﹘3B~.j+(%ZV~HVĔ^n]NqKA`ꤍ> 2i?5w@ EEK0sm pK(E.-[boagFBLQqg_v=8rmw)½"Ļ⑭%cc90[g4?(1 Y 䈋[{VCy<#p{mA\\ ~*(y =iCHB$u-dLo*A.Ejts8We1+"=jM]fO?1 z5}?8 e%_u,5OTQAku.ه[BVn W+ csr&4]o2+5Z) 4T`%x -'۔N5mhsnW Ep²?/dj.Z\QX ewwGl$ڋcH0FM"_P:pMਲg{WD['"V.2ע鯪J_Yhg5\Q4:Bֽ&E;ij/ ӡ&va"{bwO6 Gjw=.ҩ|yՁ`q/0et% \ JMھgJt^tD7?n5yy5U0_,K=wDg;/D7nD7?nz}fYt3խn6?qdbLBV%fۈ_x pvVXۗٿ5 |'O6i@t%`pֲ.zͩ -_)y9Ȭ(i tu:Ɩ{0غ;0NQ6בV6>yG>I(W5 dgp)4GdX;LL&l[`6@jggID߶"l3^Q/Jk^j\DK{C_ȻNu.`k um_ nz8 9p@{Y|Wd_>5Zz4,3"|Y{k|DTL`fFdw ?H!"rL%HE|r_T]T>'"tv}'n\pv|qj<gt[Vp~e,h7 (^P}켙L>ffLv//4`38&7wOәxgaV!|$_$,3iA_5=9{ר_:P># +Ax F]jI:P_+ ̤߻_\w_j0>:X_WO>V &s__^ bq23w1$4|3+/:[|-;_iǧ $P$ʣEk.w$m2 \VV`*j3ӝXlJy lZg3Y8 ɻCpM,ߞƺ'AqiH?'0 X &ٚb0l 7y1Ծ(ݗ_Ηt,d)hR7m:Ю]A=n.ErrPG XBDx#?kMׯ,6) jEB_s\I?.EщPV@peIA+q*US-I41*\/ՕA/?[6|P}@+g~8mjz }Z G﮴; gǡۚ;I|ֹb;NKJ!JKI-s%*Xؚ9ܕه'7}e}S6a+I{PmDO 8>ҭk' fB}߶H׀T[햏NPhOa)  tI4,VX)CcǵG^p>g!W"ʧmAح`]5E''i֥ ʺ:{wn18߫.^ԪFs6ܵkѧ)!9 K ?iWy$K,,̸1=v$+PֱdfThAp`YUC;Ҭ m۶mcm۶mvjݫm۶mwo}9scܸ?*"+߬z332#<t.㧍rYQ Z`ib sNW gbo.+`LukTLbQTSHg6q=91:+ЗAwC=Ў?ÜYC-7D0(…K4 J;n?_M>Ɲ$+LGʷ|5sxBoң~2x 4IU;!'3f*;5kGm>a\Pg}Sǒ]A6/Pk/& Ծ%g1 ̐h?V;fmtȣ9q{H {K>lЙSsЧ>pS[m҃G).%4N+7v yfLx41!4` D@ .{mWS6D*ᣈiebU> -jثϼ tprvKU RRF+R*FPjQ mԄ}GlAIMdW֪z-E8|Qr"6K^R&PK_y)1%xؓ)5ۂаfdѫ E&hhfHO ޘB=LcC ůLtsLtIYgk.abZI碔i7U~춼"vkC+o't7y9&&!lImu|oٲ`!/o;kyb5+xJGk+M$Q^G˫\&RLm˛ RkI!2ѾM6صUo\HQo y\X{@ljW~bcE5t(7)] .Wi#"ANL:lckTd~"\Gc*@mW0kZRWLtQ-􃔟 Upa("FFNgQ[嘥@3PgY~SYG2 Wi-v\BRgU u>vD^xN&})oC IpK%|( +!{"Њ?Uk5/q8:V2CF1wCJ<3sS=n2m/]^dED0)^F?Iy0 {;SxM%aW`I(I(ؙ ,"ʛociDʕR*CW[>Hm{>J.sUv .!3~U ~b [ Y]){]ot^ BD\ 9NNȲȗ꓁1W›caaC^S|$?{*HC^F[uRo'bc̕r} LWE8q]J:[ Y:q TC2ܜk|FMܕyoZ>fWL-{5 ]5S~A簎$TVUR Z'& 7ZӦ[lM% Z|2ʟ'";vpRBˢϮ_;Dh*+hI*q>fu}I%wOjWJ[Z9BЈ+pCEO-.XFDj7AOU&u>m6~*Q$mHz7dr|fsb%]$pe(puS L6)#5Fl("kd叵zGoIM!L-hU!'^e'7 ¾cMvvஎLC Hr{C]$6Yy D岫(Y\Q\KFnz!M3ɘ°dM?xrl{b#5gSO|B7rκ[n̛kaN-U6(hjkN%3Rt~*6-6?_Den;L3 &+$Y ]ovDEnѾrRjCNxu.f3f[ӻMMm%0۱`F"ֻ!=vjz}xZwb$Xz{-x,#`[׺dGܢ ŕ<8n9bMs9uzs^1n{6uĂVtR"Ag Q}I&ՌB*։dh2eä<δi7_ʍ ᳥NB!)M\aALZ3Ux״uw#&je_` ;x"4[k'А91Iހt/o ?-2AEy6Xp{yόZol9w;mCbuivwL/.o/+,6kJs!PDFpsc.G_$;Hӿ+n]ӈAz jqK^ttO%ڕoN L^Zr$D8SI})\ѱ'kQŅ0G+ŖOn蹈4DuxhҊfA*ajI)IH􋿪?FEcvpC;pC!vg̈́Ɣ4#uk?^.Y$Y&UUׂS%Qu 3Pe_2pxb:2,2. Al ]{{I؂1aOgPyUIpt&ez kqf܋Oťf}SZ]$!rqqmsCMPBW+';r7@~ 7dn0q nvVc2eTl Ḵ6 uy:$=WNb:D x/1Qx}{]a?3ӯu5=cRHHS\Xp~G@v/۬*nv3/̙J ݋m7] F_KY;S"J)YT'{.Kqh'Mr8٪e8A '2}@ZGއ)q楛N5\w&V}T{ cWhy6#Pyf!#T}?hF οF[Eot"yn3dڢ֟˝wx,~ryTF/dy੃7 9+"rD .K\-xG :3VRd`lJ'2m={>%5'˶Y¨fL톶a1皞 ҔuYm-ʍW R{}7UM讣cֽRhYeyޚb$ F*X \~* iD??׋SY>+60CIAMG%>eOl#Y!h>8<#xr55(s*Qu+@N,T部0_3(E?^W39{ek o_d7 ~}c*|W-BǮ(QcjӁ ZG F^XFY{$,ѐST\zy3v}Ҟ =7&Q3x5iźO<4)*?;Yc7z1}YC0Hh_z=Z|Xy8 Nbd!XPD?Iid\O=71aߏP͐m}gXYi;[x2K6{GS3K`:|KCd'h hx};ΤgMKa$iG$&ʡa" a3e% o؏gZMz Պb34 {] j%w0@p~Aa@ e]R]p-!$_~ 8,+8.%Lm]JَU & #P Yۏ'bBe!Tt 6-UP\q7ݹ0٪*u78<){@+CJzjՕ̆{t!9ǁ# sf`:66ކmжe &CއHcW?t ZR?VKW'Q \iauNf}}xWc فNTNg\@yow 2@VMY6uyGd߆?._ĄRaS㽣.EFg[f4s,Kn% $t?")ĕ^`CdUuH`7v`%-#$r. $$ Y2=2awDdk.{;1_@.ܫkO}:nfU%B^{NLТj绚]SNawIyrlfדUGeyY됏N3:_!4hL\܉0V38.K.{4MK7@We 7mto;]^8xMYb>d?=3M{3 Z%4toC^dM- 2݁poбG3 ]r'FD9#X+0J,KFX c>kn_LѣwjѐE-ߪڜ&q~p@O?H)M?RUc,>^4'Yp\>Æ@[@]_nueOCk(ݴfԷ0 fą?\W<&YS},A0<8)Vi,(;x筦zqTN,W VH]u൚;Ҏ˄ScPע6y2y)=U^ut\DU 79FsMQYyxrjl ͍MD46Þ^8>0HK[\GedZxn+Z sp x*eMC{"GN"̭Ztp8:ZUH[ÞVHiozD6+MPA>8 A \}ez8XCţMC_YH#XG LÖz z7ޡ)T}țӸ馿_ž&U[Sw)\+(sT _2@eja,MBd_^k A-n3IH];#n@/<rW+d5'׋x 6 CjΡ?(mG6S_裬d~yĬ5RvoqG(Qeh>e4%&<*hbg)e8eh^ycv27]9HQCBAĥ ,BJ3[_՛H/[,ĭ9ܪ&J]I<౑ LhL 98zFﲹF6ۑ5&mZќzǍFs|}Yݔ% : S|0]~3ϻ`}VWmhgYJDXR?hǞ?H~E83-T#^xCS-jݎ.Jʒ,ƑNMD*T_ Gd9UFM&⏼*o"fO=OJeGE:JLbxKW['z,ggsmj(# YW ` jbkb6E,Sձ.#,ldMe 7<@bT܄vQ ZBψ]Qļǻ|aJ4c%-1ZA<ݟ jx@/D)*@6Um!RKY<$!v"0`;oqXUzoj\%!ۄy P2a[]E6UɍH|y#T=g;^xNR~#EW|.Ȧy,z<W94NB|:ZVHLUr9q~7-bfY߻")- 8Bi\&uKI;(!rԄI k6-@$M,Gd|\_(mkţRK3Ϊ@{"}x ՓS>k\Sf O # <֌Q x|hlq $9lߑ<-{gAjҮX1ZW)o߷+,J!3@W]m#q9wzU&W\35lAX"Ul%us F3o4sxOnU` <׎*J=zX'ހyb#.L@>:FeSK3)R;*CƼ,\Kbwb)w푌?4]i)ît`m}ܙ@pc:p4fz+-G3+ŏ<סozቛP*sT"OC.$i̯٠;d#D3޲6̢q1P&z."ㅸ8Keq+ l*8}jY0T  k`)zWS3q&R6M ӑ;epXsvDϾ\z{G ݧY&G`w&픖laj˷+)vѹ̶ m_fTe*+)c۱fec^2-J;AleN8"XsPiJUq+#ցS7x!*ue"_bE0r߆m\NF(q5уH[~wgyNJUl8qRd>ö郮"e_Kַ 9[.i*Mꇆ Rr^'cBjXFۊU"hɮr}VC̺`j;e_:p+Iŭ.ɹFYptV-ާ/08=hM ^0z#!ux:Ԫg1D3:p b) 3@7Oެ QVdjӔ>fuފ˄\zo9hR =f; \p;7 Mk$=3:},G߃e$9 ,?#`߰@XyDX+4pﲰu#kS)'*/zΞUw"m$+/>+p\K Qa)':HuA'FUY Q{kr^g2H8rϐJ,!FlŨ`d>1vZIjT5D~Y܉&L2N|qD՝p XQ/ @\4BMIjܽDq^/bM' *^&|',nmLmkA;'Bu&qŀAQ,??DSʜN[~ܬ$ȩ2}C?2_/01͗@_ }?l܈}{xΰNxǥu+@IĄP4lv & &FSJD~9i}[}{jcǹrq?K4& :]]?Ͼ)+ lْ' @@A~zֶKsNm'TumkE[8tR4B Blkz-RX1O pN9!BB(DB1 Vb2uyYylǔl{H-m*A'8 Rؓhpz +@kw̉RfwV~ӧMLr挼BAi; gPiӈa;[i+}jM/~{'zXKDOٳ&$@P>KK O 2tM Wq_2F=%0hCu[#d7#X/'Tja,Sp657UCIl8 Qp93?Ke %6Ĵșu6h r zHq}Q _= FSk@KxuΩ sL"ra8SBXl.Vj(%ы0L;pӝI1RЏ|.Ma#{~p3x >pOw"#}4 h;Řމ1Vx\6~s1ӡtW$L挆 ի+b(]^-]1\?r,i[ĒGgeKB mv>>^PSkͭ<׳em\*nalB|o$Tw#jU-ZIڮlgktǷtX2;gw=Cɳ8w@;"6ؽrln ke~[)G'cxPº` Eh  pߩ蹱*tJ'N9Bɱv[v_!)VێeCڌSoﱿ !^b[H 8JDwDzGCSo0=JDd(A,b$g5Q޲.X_4H(DoNM&E(w:i1|,^уI`)Y5Mcfph\5"J4Ǩ!1Ʋhy8 22yǁz Ys}6syqz؉iTLQ3GyD= >UMIpiqiyG-'9",IrdY#QO&*lp2?k ˀUGVIϩ;&';|%:y wƭj:rj#*о*Rg\y8?6*vP> ^E99,c&_3߻j&AkmCPse ꅩrX+pEF4lz`cWЃߵ# ꁅ_xK{`ȃῃz0q76wps616g߼ ?y>{G[k+ +d!R-?J&NNf 1ky80D^^^^^!.QWWנ7t402qx *Vņ1s4ǔbL-?) lG _ l0b_ϴ;oNז0w_gNa2 Dacbddؙ 2UN9[-mIF-XEF֕6117'ϗ;=;).G/Ff4"J^Fm]9мe32 {'{I`dAXZY5㹲Ṣq8w&@KΎ6} B:@$xc8q`gK*>L~ž~濧 /nO#C%þ-][<`547}xi#F95~)Ky|oM0wyy` 3CC@oj&//IquZFb)ntw7x?呱yG=, `UNQYY\{֓UI)n|p;Q};"nf/6?ǃI̩o#|_Yrz?yqq?|xnXtfȽL_y?YÏ M_&y~~}oy? 89? |җ661|lF{gMi]gya͍1 CysЧ?^ܻ~_C_3aQ!ȷ~7r[[㯳.m}io@|77~j_n +HW`_Az_̿~F~:QN[>Vόznz{n6^}/??Ws^{z2^}ſxbGj vOYOs;0hK|U<W'K[I|_?;z`^vqlwqgy {;?IskO? G#3,Zuo8)(*`TIJ^-|x% E*AdGQ1wigϥyΠ/%9[wi2kqTНgY I]x ޣqSȭ .DK@kkĂ41yO4o 1hunF5+JV85=T3:pE(E| #H6u[ظk.( W/8_W e>?Ff%דBעTnu33?"B7#ؘOQ`84 Dπ!|4jk\ĵ, gʙ%$i4Hw3UyRBNuHPtex12WSpg\~7(cLhlM̼wmG/# Qѯ}9,4q#5EXU%rݍcB$`S_ YB(yn:SVLt]ʴ zj^θxFz`(#<@9[-vIU]u;#};7)B>12 їYTy[zCUWU5oy 1Cb80Fq53*S V:BY1HV!v0J`n7a{ZcǼ$ȋ=q <: jI jǹ,E ʜ`.)"]1 &op|# H2Cm11},. Rp|W) : zڎs,V0c }5j!/a}єUVKZ;=*|B8-طZ' !WqG527Zl~Wœn._ELA")[A} I=F)H!ZsI)KjEZʋSMVc'iL>%q\ڲea6$y}e0 :oAy8?յ}py& Unc%e1S5p6>6ux~GlY8'$?ژY[!) A" fspeFDմ ˕CG//BoF,63T~&*^!ғtJ$C< T입󖔏I 5J]- a]! O L;3#LNWh!/}N،)Y$,_E9|0gjܥ٘Sf&afj~^P_>g`E/6h3_^tXK6"qB|0UU/g%e' ޮwk*޶ҀiCC+-Nc#j.'$/ / t*eNjQ[*`褌Ps':Fǿ!m|| jX-r8M$(Y2;$8#&3H~1^zH[l. LW^p&TI㙯md\>FnҞ_?۲*Ф(dA.*tZ[iO8윗1\}Cĉ49:P@PmL34m삓B^%s9cVUb.k)aWL0 l"vSx~{kj_@opj]c>:cM K,>EW y!?$^O8-]a,gԎPngɭN[&tV;ikCӛOJ9,䬍xSSeCR l!,/:aĮvgU~D.H~ (">ug9&%7HtK૗^{(ӹ KV1fTqz*7H\q04yYu@)o4I:@]L2kHRE74r4x0JMP9Ak+Q+fuR+n[9~7~JIV*Jjiw67Il>bUzݖqqr,fzgQH/<]|Eа3R#QkAjK > ==a֏Gj\J4\UvNb\DMؑ&mqj}aOʏg'0Kv2aE/wqJrU5swB!o nT"o*bs#Kulv2}w 뛿~q>1 wu@wOm5Э fM6K`'Q#E p9n$Ç$F^QC~ HuIWۇzDC_k)Tt;UjI1T`1TY#'&ANR9M88cotjZ"ͫKʖLݗcqؽ^mN'؞ĸY*&ҭ`NwGP«ĤPn]$0s# &TI;eg:P\S䩍],fX[nĺ>FD@;}VP R=rV1FI~#Vqm7-M\0jОG /sm'.4Gܱ bwA^Kx灂傘B, k; vn-D\wxOr)$a\$HZ%#KK9cxa-{\I.!=HTNq@g^4+7"ƞWTu~4\HiUbqɧ"Re&Ze5$|F$L7?&{vnIr]'a$TOp} ٰ6m&xnYdkYz͑!W>/Bh?誩вs7e+̤ {&s yi1EGlNX!) 8 0CXUnN+6No~X≟7@L x_+czr;++JrM:h%Uɥx`=4𜱁糞if|af1`w  ܻ _]B_PH%*Rkk;5(_ -^J\/was3;ob_K+DЍ1ß߰`\) X965r`ahA~0@%E ӨIIAӲCڣU&u 7#UMЈ ht*5U5;.L8O^{c} |~((+m_GǪy,S㚙M%рWU0UJі[>DQt%*3\; rNk?\{ZbFG( N͠i(yWT>v]՘=VTسw='{w69ЇSoՋq6sR Nq7}.Ƣ*k-0m:rF&jdA W&w|~a5ۖUJ<}8I۬Rh·R0TY$/BK) Uu~kc'< f呭GL0>r}+Mj>t(Ͱ fs7Ϯ2b.B-?u:8rAeWDoyϷp)k<z׋D$2"lK8jP$]q_ KʕM'XTHn3˸b]d7k?.e~GJVZH s/J4wt(m.xP?:1MW0,⎮73.6`PZf{e1<oϤDߝv\[m4٧ 'K6dsg]j4Uxsl/qV// Z<"Q=(@DN: |W'Zx('vszH5c_^K3^~u[ϓ)jZ8wSg~o*l_!)l yf%QFnQ.|qo3s e,kw,eXrsGr1GO@ ]3P-mѭG%`.}m͑ b Q,YNuvCx A@D_`<螼úHKUA oPY {USftgbtC"8f7¨ԱՕJS,iG?b>%{mQߜDtfDzԣ3 F:?@dp>QucuP h,+utiPoZ@fœ]HeF%dӏUPwz`ۅXSa9ɇ:& a%n#=Ɯசp%p;HBmAdA"L6ģ&?b,P1_cYmT. xh}f*h}qi޾1#ɣ9Y`V[U_p|Gh=:k@Uɗn\{E x⧓Qڐ{/@ Uޕۺ̭*8$xgQow@ VKPk辚nH[`[E7K$RWrE`s9@M%)nђF ع,3s8lDFA3$OۯmdjS-U0H13l):[9x}Yqw׎&qBZL/q;$o"B*Š:!}:o!p cI^Vn=V'gl wmbi2%$;BP^9O< IH=7Su T~x7QAIuf%̡ 5[%JH }갈}*VяCsmVTe|F{EBSݤX} |'ط,Ţ ym3:uJ㸒=ՄI4ImsWf̺X< 鋂lr2^rUy˂b9?{(.>ƅ'UPu#F yAЖw& zfK i\ɣzU$^CR -B3n8%}@kvckwFN:QhB1IJl|0D1BI`O"~ @c1/_x"G>ylm,TVsol]xPߎa(׋rΡ!MBfF1e=.ٍ߈ka{T&3q@pXF NbXwK rXKjZ^X5 YIȋɃ(b4I@O%-zɫ@w7 {ಙHsvc{GaBPEfEǒMVFx&p\]OK%K`:SipfTfl# Ț9xg7J2YKa6,\p3.A *j>hMj< eZ&eBJ-) $_iO]!%VCs3; g%BF؍n8d.[)؋,X:R`ıA򾓺\@wIͺ=҉ho#;2ϲb稆P(a1QnWjA:ٲ_8*uWH+ n"i  (NyeÌev{t9t;Ezctً6nIߊJdlo"%OJYSߋlxGww#ݎ=DYVyP;w.fߴbarjd5>}Yr6޳Ӗ3 };uq{Aw>=ǯvX"J/C+Z֬I^X`Ҹөא汍Z?dB`lw:%\@RLz4zQ[H7Νݽ1@zp5G by2 nj.-BʕYn?z sA0W{LYas٠wZdQqC=ǑiX($ [DaW>QסMUչЂŸ*wP[5$˰= % }giIۘO0Lb_q{l_$v|=|6mx>ptb(ЅgJ*t؁" VxDzRWC{\&\8%f|V*GBT^V.OrX{F0MN GAby0 3sQf[ye>Wwvuw~g2t6l ző3w&"2pG3E$3o.8ؔL '% S qڋW)ZAWQ"KH@AKzt-BWl8lҋcT4. 7H38WtEC͸˜.zd\>F8pVשiD./\5IN'Z1zlZ7H^3su43OXq3#Ɩզx#vH!ߍ5oԤ@my BLsra,I=aQ }.JFFqgѰ&X Uiڧ<1? ݘ\u`5YP(Toݷ: ]GGDEpM<@rW%<:<&,z?왊 [!*[DϬBFK`@q_x뷬r3vGyݹ㍮#h qNM`B+OOcA옦|V3RWutE ; Rʭ/[dmYgPtk ,a?S\(%TkaP 2~PPR j89ee 6MtT ֤c> 1fHHՍS-6\2)JM0#!jKbYyt%)\2Y-0$ʁ,2T;JTni#YXٗ4hرPd$` cR`4= " 6n$_)9țL3!.\NCkg҂8M 9uzgē]Ñr++J#C᪏2`/EA.qc)XqbL_<<2nP7dɯ4h&>'hL𗳥3'kt=&o1>(Z9YO'gV#&ݥpuISHTX`[+r!R%"sY"$.lt,X@3dV:Q.Μ'ݺF"ߴFA]Ҧ?m~u~QjJCn ':6E.48waWk8B6;cfiAR? ;IXt~A6 @T5^fӞWџZ3@)6M Rf-(&tpR@$ӷ:5MX Q(!E p8%jxd+p#LnG )1c=q'e;OԥFijUa-e.u |c^y],j h dGӔBiѼu@rȡf fn͠W09X1[]t̉mpE-v\C”ޓǠ3%PD$r-=PޢGq]sBɕR1 eSDv |R ~dxi|dlLrcVyQrۆǁ/u\h[-t3+I 65ehZj^:7BY|WP wkYM"=vU q6f0-rj/5g>ʹϷS]77< Gj~50W~7x)T%PRϕCiڴC6G (vYZTk;,EPݬ@"F菷n-c/Jb#B԰TQ ,|"7=ױY.Ztp?@is1D>EεZ# (a=FQ%D|a%RBCVΙNmPfp0kߎI8QSkX=UVYmRYGe%hn"*`+θ>^§̾:ܙ uiLV߇^I^DVW\v\2:(ND" P<ςei4ցKV%^7@H焝@vӣN[1O^NAgʨFVFSە0XISsQZy5>Mf,XŽT3.q(G@mWr>HnXq1NR%0ڔ|ڬ|=rÿļ2a~PãP'Zi's ̯7h ɤޔzƧE1zOo:ތQ|K 6E:xʭmцEY0)vq/RXр FAqLIC'Q ]]O?$StIVYM /uu a3 :Hc k ֏\c"/穜[yPsOEBK>O*Kɱ}uL jc`?G|Dϧ:C:4dF;Jvs7UD j5D]/fZ7yTwtW&v$ 'à}(2l $1BxjoؤF*#O̝du+hpk\3/ٹ[P19,Oз t] pA7#CAɅ`)x.() #%UTL BZNDXû^*DF8p Wl 5i`X9^ ?Zq r/ŭ H4k&ů /^CxrԽ*lyi-wlDU_D-]V-JiLE In2 ]r\~\I$?o-!Vqn1%,0)}׽aݻ{غDXu T;6dzK&ެȨ?/ߟ'ÝJOOivsClVg,89cà]֬=q9 }zſt"n: 4 irLDėVAF؍<9&VunMAhZ@x:r8PfztU -@3m{Y^>ŊQǞ@Wqr[tfg^<zxgc̃oTFp3A ͡z`l3ߩ H6Uvqf bC鰅k.q[ iGq,q(ȭSǩQæNOD@Թ6D$8rVɛ纽5,AgTb"gyg#9jt4>5k['{x ԭÉy6s4sJh0ur4N)@큭@E3-Bj^s\6m8B¢5糪S*䩇;@d_>g^cJ)Ul /o R013`rMkonSH>T@Ret>H8*UQ4`v6k9@^-@=Pq8?m>źqaM ŭftA eTÇ;B{~q?iM䫅mwwH#Ҭ7'A-g$:W_u _SP6hJ` )8!,ӀnNlM_BJKϲ9:"KS.녓~̊wٵu5cO͕2!0a~@ 0L7̦srLlOMF3 7Iwi4% RzG4jGhel0$Bp0" lqjYܡ ٤Jg2 QTBo47\0y&zϕ~Z,y>a&WVId}Vןy>~KU *ǴGN4#zV"5A< Cr4YzrCF:Y,r #RZ]<I+'<䄶[*?+V 5]hp\*Iou"am sZs n?[Y ҁ# Y:)tw&< :iݭzx(*5{901'hEry.&GCϋ~/QZJJ5O & n obo4ZRxx61C_Cȸ4+݌oJ>¼4$_4?'L횴6,mHikCdxKTcFZq\Av ۆh0#BmJUp$k`]7F/nַG۾+iX*LoٲWSטg+ij4ExmӐ}O y[ф>ϲU-4M6x(5j*JKu; Br+֪2t~--7Cځjss rSfE` '|pzE[G N0HٷxG |S^sA8IRVav5tڳώ"P,ZHM[ #v'=Dr$.%ws?Je9osЕ>[Jr2xAXPjzLA24gw-&i)o/O#Φ) 5AJL^;v׿",ߔQnh:wu.YspY["`+?.fW56"_~W%U4NGbf&Q.v M<}lcT~{ݿdzqq3I-O,Wnd,S* ]Ǿo_1u^Y6<~WN109oɺ~f{k iїeJM?5hl8 9UO˙JKzmys&ryn҄t<-6aTzfj}S90B|kA(ƗM|if /~ܾ'cvkL߰>[tƠj&}Z%[|=mn\;ȥYߞjG ˚)[պ^5vVEw`ZjXkꖳ+ĖκnyB `5ܒfjs;*]EtSF(zIJSE WʌЬ~zMj'{!MƺX*J匦4QOɱ }\'58m3^۹䕾\|&,WV%O8v cGrh`$%eifdiƏܚ#[ bc(@TQXL%,( B-,OHX̜ O&aq#a17H狁󟳰,l\QB h_(I V!@s?Sp,[R4PcB' #Ͼʾ]VǗzM@6ghw{D+"#ꪒBhzn%sH{7W!_js־UYhƵ`JKmlLo*nsE#־ lbF{z0?b {1`؞2 +/rSaҀ ?l.М+2uФs?s 0{B4iW`>sosۿP *_a~;jN<_yU&|!D|~#"}:|#  ~#|(BA( ?* <.~ r :J-|#`SC}Rh&ƨj~!vCp<? | C|}gA=A0:C M7 hBOTУ}scnN'Jo4 {tC$kuߓk=u p " S/WOG&-OVW|뽉o)duRbӈBNTrF87^2CFtc3qA]\>X/4r!⦟>AmBx*L]9¨+wFq@"2DND ݀;=("ԁ$2 Vn}Zv{q]V3@BajBߐ3@˸&܁OT*%b] 0_gK:ZUנj%QEdJ 6ߞgnQZw&+,>H",P>PQإg:hEc&^;y֥!4q q +\Rİ(3 :ұS eJ-ok5.Z=w(#u7 LNHGӕF 926TnTK8aMsE lV-ha5ageI.lw˶m.۶eum۶mmOϼ3:ߜredȈ{׊˭EzNN{*BџQ//&&KO怄r@\[lHhq]& 葬"F]=Q2?14 D ~ԽGJrTE&cjHtq8.b[hi&DRXe]ss vٱo;qK I_kz1p-rWW"to1u2 9Ѯwv8)kd⬅؋"8p)}¦Rñ59xAĺ_;G*l 8@ӄŢ$W#.mD3-oTٻ`Ȗ8_Ê .G=5[ :6J\iKe߬PUH'`Hܗ #pWCcrEnKf3BXV3ht5@Ab0lE Vr{k.2@kf_ z؁op ViQ?jJd}EsƥV -# EF 2jKq.f'x>L* z2Y.P7IJdVStvڭ3͵t" 5cV*;:T(Po jj$RPY0u1y 񭯴["-ɢ5 y|$VV(^#Ὸ]ﵓ#Wn)_}5(hLfP# bX/%1xtEPD~8 !\FB du< sb!76g\۔YL'IA?4bIc*uV6h.VNT)w`Zq#>IQuvbX1\L Bc׎id%̙{Z" d %F;6G"1k W]-sg'3"Dtw)BR__2ko91({WE銐Sv=qS-{o\%=@;p A[Θwz$R 賘{$@(L}I$B{U 61 UEk6Gyƥ#)GY D\$ M4R%=Jh TFo'Y9"Ԑa[\I/_F2'<؈ʼn.Vl񭄍-O]h([s7L] x7`G7ť 91n\ï l?غj^Һg)+eb={4ܜ\ɏF eVad)Lka3:R_q|Xmu opa(T3 qnpFQ1kiSnvBp]b^a:6yx8~XNiQeRUH7tH{N{/cW:YZzj3O _$?ʪ -Sr4u=owӶFYYը%T+~|QV25D/l*-;o;%~žy}ycQs(Lv$8lՔ]q%Ӡ&OhO8SqDR{(IYFR(ǂ9W6 x@gâ|k8 @H!y&`)ʱیU,),324 \#Y;!1Z f͈_rXCbL[P^gE2y$;x$A68s읈:G dyhk0 ;`r϶ |k!4>'sc }\ V+/AC',#EvJ$#29bB f(<7r %Ը7KsI4 0]SRKߴ93V;g{IO[.7x3i Y!Yӫ|#pBcpeBcI} \G‹-K׵$u[tx|kYOqVk!+Cی nNv C()HbF-qKXG彙dG (s ׂ H8p n@rsA2lvb{t'B/za"Kw @ʂN)Kv=[_A\CQ8.IXѓDlC 9I -x> O+zm͕Z!Nz Ha4w+iFÑZ2Z(;LMsHPvRN %l. /TِܢstʡvɑIEQ\YA-ӏme}qWӥn%)/Y3N >oD?H ʮ2:8ٽyJv,:|E6yE6Ci9 6ES)"ԤNAfD̚xD4X̎hjKp_Y\9N1H#\;O'us(tg^@4|i8[ "vx+g .V|r,H|)ۿ/B)L_9YuSp7#S(9lJ. m  &xCs-sQf,70R&|QFac\H\nox C &{OD~h*rЕt#\eH)0 c9`݀cϮ?8[cu( OQl}1oc?YϚĒ]w]Z`;pkfˑBE~ǻuOɘtDtGh!&LY=K)oYM% n}0A2_ṫG/EqY,0 }5u^9)_lO,patXTykʉI< kthİ?=kԔ}>/ ?ux4z ,4P!&}!_ґnI[šb0M)?pe9S¾qƌE9ڹBhͫe ;^mTA!DE̚vl*~hml]LȤi6ȸ|<&w__PH}Z{Dmt{ialz::";uޛnM09I4@TUw?^Ч[$~[gdIin >gs N"noi g\!g6qUN[hk3 },kXDq<ߜBqj US)IEuTޏL3:D{M}Χ*WʁltVM- S+فݸ@[2\m8(rK+j;w[:))|x$%{=}M5 ,ƹͻs?>gkFpL~ =n1yҐlG A"%(E"/HBJa5+Þn# ėAT` ~ߖۭKE:N|g7NfRR@dW&`2NѢR0"wz^9yjjx?qqI⹆dg)ŢPLN T?Vؖ3:UwZ5 Sn T}v6K 8 .زcug%-A!Wb:˷8xmQPo`-ګ·LPV]Cn$*B9f]N0S`Nz1J:1VabL{4!q{5UD|❞1A[fh=}Aڬ\{j?p.jb{JAZbb5w4?5Jd9'#8xljrT?&j[1M,t%=N%mKrhX~ܓ XovSu|V:Cp Z ^)S-fj֋诠z%שtEAahg |k27$ ^ 0| խ2 R1hZ ;|OlG?hakuVrmPf=MЈ>;}4<|ʚҾM JAIھgyw*yi f[vP>ӎǣ OcN#u$>e#_Cul%+Ԑt 8:ܨ iF/+Or]Z –llǟyMaztODouP]6Ƈa$D7 1l-۲3,j!ȠA-F #qiKF4 dFN2#v])o7pF 4IrhT-Rsph%pD*NJl/ހW2ZĦg$ʖ8 {h&YK,ϤEl70SxFg7[G6cC:OD?fBuNuy޽9,.x]qwys~-Ta{ay1HwޒbNo=`'D@ۍB84낏^v}L]--\Xg@>*̌4F8s˶I!2-0 (q$X.["^saD(PϼUhF zͥg>) [K Tqn U:cβ#vMX"KYx[^x<:)F+ϼW!8O3+,IT|63tm8D|+{%\F*/$YTM:_Hs~qf{$Li`3Fߔ SqD>7o>7PXQmL 9AWAp*t&؉-ʲ0Rާ!iC7Hh) ΥHFAaDX$Ϭy=eP|ՂN5=tf3m:pw\;s*8?wa~(j?^HTu{FRk̙h%GDVE=ll^_T| ?<%ٶt%jH`۰=agA}[>G_T6iV|Sn}1a!иp }uI(M#neIN\׉/_LYdBWvAq]P7 5ҵl3kwyI'jv8s%7^:aeޑR|c;>-" BLyz9ui[;" ,D +1C%1dXƳ*?9S|es90YJGgA9b_ߚ€`sOo; ~34v(Q0 =$ #*{FhwuDP8İN[~ISU^wyvW~ w} ySvcȫֵ$'UgR,A> @UJ;?Rf);|ޅޑH.N^%ZZӇ6Q;֧w: X4 -J~C&t]eE #Ǯ P`g )k&O2 P\/A Ȅ/IYNȥ֟dYpю졅V }v{gG ɉE(zɫUqypY{ '6c0 +=ٿOb=ٟ ς!D}^ZqC*pɣ;uT~dzw1{0iZ4+Cq,rZԤr<^\djŭ7v-nT OIUbI菂I䋞dOI R9K25il%d)Da2S.8sFs5Yٲ(dR) INQ=Xw|9*o~Q.+dA.%tҚ2@jp 69l;qm"fE/m}Z\.2hZhĨMtNAkg95;G.Je/o=8O*EɅbPlvMBf![>%6~}vo̍9ԟpre0uqeFeܳ1L|x^c -eR\1eM̃,$ba9}x[I^*/\T1ڻ7(iM{nWw QeB,Ϛ&-`LA_8apA Ώcr5,@Ǩ? ^B|?UKgPIPr iUΜs|^ LXCųn^I( QU ~O4{f冄HMgg»j`J^tR<_c%Y4;}q_COoi5zAPn:5OvV,K4Ϭ}]d(Ly1Yn>Z.riRfhø("AuPd?(']{< !(\o ҝvZgDE\y6*Yw`ŤlXؽ4R4Tդ,5]5+k1t$\-h>}kăU̠G>\o[*W ȑej] eG_5uYҷ,ŏoӘhC<|XQO>rK({@|JL#e|>>pڑ_0<g /G&(}hjiF$ zd!uIz/L)ܬ_b獚u)]t_֢A\LyL~ X1%4{5-B*x85Jwi٣Șbj2ɦ=VD(\Ad|"u鍺VbKj ȟWb-.TG_NQ* ] xb2paM yw]ld{zتM:g#E% FUHgp]7έZ;,1Ё{lO@x!i]\fM24tߕ+˙b9ǵLV R y{h26$指,3ׅUA'1ӡٝSLfKw)K>V>'JGZ^41(o@ez(gqqMC{-@yC[J.J|B€~ub (S#ѷ̂;ўvJ=22T6ؠܶpXHG .6m,͗qJsiQys&&Bƻ{a +(&}"la LK=#<jIc[!%DFz9=0Ɉ,yxp8Įdُ[4{<:f/vkm5bI@ao*$ )M1dDG25xnzS7| beZmc$ڮ[K'= {b8}^YY^淊hyѷbيgfpo;fZt_dZDl3sD' "u`|#dARJ;jp9\(D ))OJʞ}q.o#@e  @"m\%<peѢ(qZNg4ٗ45?X/}0o]>yIwLn#]L_n?T0э(^?|O@3Iw`_"/|׵N򲻌i6!3u&NjI5"EU D{5MJwreO\VhEE$/dp5l(q+Ml whǴ ,ŕV+w*']PY:Z^YQlFw2jKl#DeDsE$,N$>Lki S,QONP:+\c۱IHFG_:.E<dcȚ`ؘ_ZlJؓ3:>l8ƴhND4# 3BlO_?~ܙGw"t;7(*PǫUU:q+#o{Hv;۳N\ORřɈnv?u9=C*Fa[]nVY&am8A+̔19`{p©&VHb|qZӽָhϛ"ڻ9s,O6B5>HC] 4V zsW"h#~ 1S"< f7]a+tN2{̭v')aUuUti唷U7~= }ON1&Rs/D9A~n`vVq`I㎷ᢥM/(33?CID(;]3DK+=ax?|V̾,RiR \WHKZ ڒ@KLa`$:^IzȲԔ'XS,mHj( ۗ@Rl wp"+!ĩjAI{ByzP_umg8wYY~RUY#֨xzDNϷ("5A84v?٣p:!p %G\VzaJ+~yaRMb3,4EڞmP$} A HamҭÙ=t-h3sG E{7ext%DATk7RmU+zgJUR`yrZw٣qL[]{rβ,\N|跈8{,cOwUg6Zx^ 5gV\'.)KE25'fFsLB>pBux6Sk; \iЖߧ8եm,\ۆ؋%~ i4RI%/xjzk\&,7sz˔7o†a(p6AuQy49&nnzRI ?qP3B? 5:@7u nvtwq1,ʪ4[v{VJui 4vOE&~TϋY?7DvGJ ֝A'4T&tAxbj f}S|h zs06\ Y I6[~Q`yTkfeK 6ۗSqk[B%sg oY![$iѢB$-BI!B(KѢEDwf;3?y^~3={if)wOT+pR|GUOd}b7Ceًb'^>cN+k?y[z啲W[vj-'{h]voiYm1fo>x|Յ;ygh9v֬l1rsx|־ [J-ltM^r^ 9nw'm{ %^AZڡFJ6#Zpֲ$[s]t%> 2]W-I$s|hm^͹s.t=ΣQJb37#T9?*nFg~q^b4UWCQA>ǃ ]k2QvTFI|LLܢF5>)ݵr~O/S.+\յKCvKʕZo ܔ.&:ݔ]Q5>]s5n81[\DCfiѻ:2r)KSxy&Ok'=G>J#¡Z[r*9.5|!$b)0_ yGκ, sO>p =S࣫j%7_RMח7<ȺTA}nݻm7;[wō) /nl{6:[lY{นToNco{g+RQ4%($s8cU\] wz~{x+EȜB]UmݒfYսfهx1a(N)fFDn^{WeNzNK,_ox)!Y^VkцLw%n |6>ʛUҍχ-zf}cyޜ#\GQWS3KT_^=IvS|u[gG_wCТ=&=߭pp'U,HU-2W챆P3sowХgz'f?M>gyʽZxmv)ϗ29yqOQG[eg&)yIhvg%cF]γr>J4 U$7ƽWod(K"6 /r[wgj~8sT޴&N"⓪H^hBdE]htB*( AX.Q v! SDh8XXC^K^O]r nx,&]4"kBȼD-YdĞ(doDZ0(;V(d# ڿYEǦfI!?,Qۊ0%?-M]bCePAI$$9XJbv茉Uuf\B)|rO~07kU_WW6(m`خkz=VSk;5-K˯۔\ZxqV>AEϕl4qSo=/[xlݝQIe[)rC$S" ||6ݛilu挃 3KyK--xjqלQ`wL,6_% I,ӡ_gǘL5 9zg[luI/x;ߴٍ"\&БÿkƢyG_m#=L+^9 O-1h 5'r%]yӶ3fus2>_lߟ}gmgZe;9.z4Ϲmfׅ1TXb>ѓ쭇K?6x2%?e+՛{apR#MsmmiJ>Y}_;;g(IuOF ?p>g͛Qk9<6}V6PHA[gojB;NF??::b+MphrBϕ [ٷc\GIkdQ]*q^#| Cz\4?ZqʳF|1)|l6$#Q㟅' ~ȹ;/g?sct'i'aMuㇼ۲,;*jqZ#|m{,cOrV7nePjA0t}.϶1Ѥ#'>2k\aQcy h..i_9 z,:4t H ~J*Gj;̓WVj~p^Tp=~qUz|]7*,.?:sXuA¦UF+=n*{{^$dhque9eK3E"6udOuC jCَ'V(Ro/y (c \>S3/Ҳyy)=_iHxޯ~d}"ҍ'$NkR_$M1m]XUid$ӲKq 4,F&Xm?:tv]Z|lѰ3ywOpD:rSjwIֻZ2iO$4e3z,bŶo5g:YR]ވgy@fQM|eBxuJj_z#q'IU[>u97uJ~>B_7 H%w3lY@ji_zYKX~ Ε^|i컠,|bm펤hڙ(5~ 9z1(WfJ̪]cT]GgiZy4g @o^Œ9 o_<\hqo{e ڰE3KS(Kn[OjrF:Fq !UPҜu_r+?N'KɽxuqvG?N'GEA/;nTz$A9K2/>p{y0{:p7,.|{ޏ-B'w89R0~^4:~Idmһ*+yj)EWWzLDꥹ4 Ξ=ۼ'yÞV]ףl9|q; -O1_t^_Nq1ά( l挙)/弛Z>_ueotɳemRN9J\c]\B+L bUR{[#yc<>>9]ϽYZ %b=X+,sWmٖ^552g9e7hm4yWsScRE޾9ChM%r\pVmiG+.\%]g˯K:ۏI'&}۸ŏkF~X_dv|CQ2iWRmEcx꬜LI땮_HkcvӎOܩ>$-WXݠeS;H)Evdx~};("8R=4"S*I3(j2޶|1e$cۅ#;}!=iViƾ+{ojտRÑ+n;fms|noE*~D#46jaC#ޚY*/Vuk><\`5r$/9m_@=J6?ĂZu[WU]g; ]n5g-LKVBTFeE#;>Ý_&@5o@e]"M4~ =~?.+H끹-PHieZ{dHڮ9 7~5+i>z4Kz_2&u=[5>x6.6Q/֫8ʫzq}̴ˆ [Myݰ{pݰN ߛg==9/4|-rh9iG=I/mWyFY%Cul*)8om*yps[_ڞKa3%}1 !UrԦxE_]NΙ2<#[m!o$*W![jh@roO}xD03#ekbX5ףE^>P"oS}9}4]Ք-ٻ+?# 4**o9}Feȳ\JCg]\uh=Y{> dU-`J/_gڮ=tk2v]3şBo@R_Mw|S1i੣s3f-7t'-k^>Oպ)yw jdI]O=(KLK=r\b~o;j+e+ j)m\e>prY>  ڝ37Iv660XޣZͱCe'Φt4Qx3Me 5F )MTuJNԂf7&W ᫛xw?:;9,-+)4Nu\m^ze׎Jj8ưorԭs)Uo'cUﻝgrp1FXEj''?_]J.۳?l&4kX!.W7ȇi㼿#sZEwul|7Rn`^2]KIJ]\>&ucö_S/V,lpk(%WSًhg!H*ndctXwaKfO{9|aah9G3y#[WROq5}!k4{앮dhX6\;6FH񙊫7}_d0gswi jxۭ[0L}EL۪˭F 7k\:cɭ/$Yi︩ PSWgq^ #)+(BdcSߵM5}//9b߻a=hB:x|OȈ/ïa3ܚnJwvC [L3 x*[Ğ\޲_GtWo`x;_|T?(P+zy-V;n:lۣCAڹ_6}&^fFB$5~w$Egwl:9c[گ]vXťޝxsevUHd]K;kw:IOޣb/~{vcEV>zſ(h(\c27O9z&K,Z~7:_2|b9ƹGqq?$Hay kt]饺#2ÝVnQ_4ŭqZ"[sumR6]_c߼ ^=9zN7d47Wwo઄}QêVoTp6 Wծ\zڔğ9XVNc2)M% X4ݹ=<{a# y^1o020RK5l[F )< Xx{G %Oݻ]'R)h+e-mcr=W]c_Mr}BFUW}_V7=WHWz+zX3a:r%T]nMZ:+Sz_*-S˿ɽCǿGN) kT&^KweKT:[oFs[6޾yFp[ע+&yEq*cgwv)FCQ< wowux''Q!ng\|ao.oؙQ-rʰRN#[yD#lk&Œ77Q/{2f}Ff|t;Pj#/PSdyGT9|oM3]*ė^;hόx:^;ofZ tg_ެ5:SGKm2{~@@jg)ˆJ}{*j̛;r=%r804fDD=)HQl#;S{* (UuȨͺ+'dc = ܱɈ<1TkٱSiX-e#/*tkri˕◲C> dl._:aD]hB,gcG]#ܜ9 -Q:uj!Kؖj Oٯۥ34B$3b1ВGDW:j]|U{*T>eg|7R \ͺ-1gܚduAKJ~WFsSCnI@$CxgdiP->"VPruhSk[{ò<;d$&Ώ_L}|rfWG2}ϼzc<*Mg 5㷽Q>}"J۞)6}c׶~ka|Xs:iHx9 [r``QsbKG?KyWuH^5`Y.Jo)[gFW9Vf+oU߳{dެ.7Qhk-5IV &qd9 _ܲC U?)޽8YUwF9b}JI}k!쭧~4`ɶkNXU{]8l—2ސ:uk?ɱG{V?NҴSHZCGY]!G#-8"yƩ϶K :=ż g[6,Tw%&ٳ/ʿ&,8#S$ ,"@s6N?ż/q L_t.cq=쀾Ҟ;z.uэ8s؎RWѡ}vImՕ*b_H}}ffFbhx%QY㝦u!~D^ I'L6<m#\c'>!'Z|bt%͍UipV_.=JqN-s:t8-so{m"b6O\hƵy`ܪRGdkI-/N!;E<1v/sRG|A^gb */R.hx=N[d奋yC\:K}˦5 }WٙRݷz鞊-‰M̋9p{Qpn#œom6[ U#w89*=yfY!+ WTp85lX÷jOaK^: l;-'cQO_ΚݵG ~,mjѮν<7 IvI \;E}[C?1j`a_[v>KPa=nKwGmo0w-Kʒ.|vl\EX^H\SoZ qؾQc5%5g^zms:}K$[]jxÓ[ \]Pl c}kk^o \6ye}{q͢6rϲ.?4;O͜Їm6U.DެFP-3?v YmŚ+~*Η#-xpZ= fѹʡ+%襼+am%ĺ}\Vт}e-av:3L[N׌u߅ TRͫ~p\9|U8S}'ў{)˃be+yHOrq䍟;>yYyvRትٿBm6soi`-]ZhHiƙ.6M i;}w鳶$_M=]#.p>ɾKʔs@QF ќcUw26\_eW~w߲ʒ3 \ oI^=0v1_}iNDx=egz|ni<nyDl.A,Җc\1vկmgnz+d٫cnpƮz֠EK.˽cMqu5Ž/?\y kY$9jžRUy9#:r 6Xoa8(Q޿䦦|aYf塣}׶p}s'~R9zgvo:Y4imDpk@Q!#>-3/EjzhYpm]xO󸮻w\(I2x}5ՒCR@TA7]/%&=5ȇ3E=Y,I]GCZߔ֯cfg :䤑 ^̶?~F2&̀,!:\|Z9ڂptK5Y[9l$Rj SOr g4ͣKWen64>'*/f`wyǥ֐$z݋t"IW])pЫWcǶQ<,[/7,/>ۜw-`ܝq@mIB+ᗮrY;V+k#VLϾzѪCC?[|>빾.G$/UȩyUO3V޵Xȿ|CRIheZv;1W)=תΕ5i籩+s%~08Ydiۅbnl|[/H9M}kIcio(oh]K7=IEҭd&O|Жc9)5^X3HjYjMW x%^GZ<'A8=B-zsɹʴŻ ^|J"ڟ8m3m3G_+?0<~BP)kr^O&gp`\SO=;SYm.~皂vҾD}נ{f6RY9تUg1~}3yBOyk{5 nSҩe_Kv(K羛%zlPR5ZV)w`aAչ_|l9>z+ogQt8]JnL=W;dH;?4o. w1a\Ŷu6>~`svoYؤ[j-3tLQoR(G$?/mmKwQȃ984'\TmetT:;~C.mw^\6ʻ-Nln6]˱XquPSRCg__j՚AN {oe;ާ%y=Iy$lTaw7] >CFԹ"4r .=iQ+=4S;jdSN#lRW84 aS9wQY5JbQh||IN>n^jG0:j;j"o*oGv*ak;4 Q$ ~p'R8Q9H'OVI"d!B#g"TDRBRP@ nGo$ɨV߈ 2;:"G63hd;c3og>!9'B8d>uNU8.=?g.rz1CG/۹8>HM{y7GثD]Гjwz~')w CV) o[ l(B') -(w,cZ}y҆y;0a3uR *eA0VigV'+?=)Q2&=* ViDrS&ߩI-ht:Uƿo1ΘhN''&lOěU:X UU:e³tDV'N3&3aZescVM p"4>7yBM ƿ1i @"SP'IS&$2Pm> L&,/S& `7@/k6&m)d L$qpDeyeJ *V ύCiS-LvZOi1 е`c'. 2&8 p 48$6N!~]ncTAɈ@1!CSSLj'"ZP B/C̭O dx'.81.!ehDwNHI, T*v>i[dE|*)S6ɍ&o?p/idrS_I<`^;9:32ل=:d35~/L}y#yn8'bGG2:N̈́%?)t BFat% Nf`M y:pd_ ,H"` >Gb6tؠ d`Fa>qڒLd2e!, MGF!Lp .X'Hc6 ",, N# '8N?``bJˤ,:8uV'ycHh 8&Ib &@&E4I$Q -QsؒcKW A# $!mR;l0} *1 :_+/85ɜL PbWA'@:.ZЁN$I8G+s'4Âi9Bs1@th`5m:45"hQAgf4sb09f%X(pD8 <di8C@YP(pB8 '0Y0(pA8nRsBL4eq _A L 4 -+SLc"9(bZei.ʈ]u3L@fA,W &` a"H' *NS)Gp z4 bN+GpbBs &V X1 AY N,Gp& ߲`S4eY)pM_ ` ʂ[ $5nȂ[ $5nȂ[ $-i`Z4 (]Sv0 L*OpP`(trE8> L&h6Ӵ 5Z h6Ӵ 5h6Ӵ 5kcAiI (a[01ʂ*T /7a1T P%U_mcJJ LS%؄ N4q (FQ4 (T`K4[l V&>0Yi-*N#Ϗfxӌ3",F`D4#&QsfDa1 0"#gD8q L`3мp faAiyf fL3#njph`AibCj`E4+‘",0&JĂM"2Zb/  bIu&bAy`M;S2i!O]hN\~\e^c'1b`AYamSXi>C{$&?8A0a{i`a&h˂L2@auS5fX !,g?]2wGao s50!#~F lC6D)_9Jؕ*yĭS1۞^(K~FX$`Xg/xXV {`xR%pxTd82qU\ }=+IǏ?U\19g6j/y}b6![}E,%Td|$3EBID9$9C' r Pvf11$ nALœXL&MEDi:"&*@![@]ɽbv*6"b@v"l;  R1H F4DL0#bb4$NH!LP1%l;LAl'Fl!S)@TD1l;$8VB!xLBn& b[ɰt!bdDLTM¶Y(HCDlv:n2b;W b;NA"G1%vHlA%bS1 9E!bbtDLΠHEl'JBn&%FF0N,TvbRi۩4Tvv*b;`;NNhN'NCll!SN'NCl'.4vx!PQ9W4*'xFGMc rbY# 8$b#C#XH"BNFkHrArb5c @'Fx zr 9bc^ G`9-1r k"Z~N;D2tB g*U&$ ? mք5TY0*-Oѓ RɘrNǴVru2|Bct370I̭#,|J ؁0XBc3   $Č8bGG'DafPR=0g o@ՃnBtPNPNb:y9H! 1B4$taM8 pN`gSgJd2%S{%\}`J ~+݈J'w1I9mN;hN #AJ 4'eH]S22UB&d삆 }j I$_ bLA3 3S @t[й4l:C3t;*pcbٍl`j4!A0#Ax0B1@H2~3 0է0 L! Se̦C(e imMAa f;Q`F8;`&Ye3@tBH:b6 sBdar! >00œq((!1QP2;y@,zaR.2upaB&((¤ E3?FE)*j=*j3 "PP8*ʜ@f?PQ1;%LLƌ+4%-¬ FT](-aD(#KQN 1J`e _L D/zAP b|E` *4T}dfנ`BYƁ('X9Â4B+Hgne ءur}̮A)1T5Qn A̞Gi)4}ܼ<є>´PJ´SӖi)R9-ETO"yj잖"J@@jT"uF@@FM5d hRn FFQ:22Hx!)WQtH-"|jmZtR!|0QV7im4de0"܀@!g Da-rIx!Ѱ*Ɂȝ wTa)$"`"vDVɡ+yx!Z "5 <_&)?p/X((.^] K. K'"s7T5\ R)|hDL"xPL_{`0tW@ޱi{YeIfyYd2?`:O \&t?uC ErqDK(cJX)v?kHK,/&Ў @BQV`v2X#$@Љ6+%!tXBLe` tXBOel tYBRet tDֺU5$2, c,2:҂, -2:YdYuhԲ%$,z.r \B\B !Vk4.PY(:NA|}v9&AIDBU$L$PD7V3St0vuE9GFM1x( UW" "fNm{:ىy3%e 4,Cgi\p02BF"ʐT9)#$dYFW$ ưxTq8<dw12 ~ ۅuFWxT{2t:CJSJBO!ܱ2r>.-0F voJF/%N!T2DC? "xGRFe8ţS NA\#=Dųdoƣq,BãYiDӪc%xd*WGhƃ5~J{:$bJa`<:Y*:A$`=d 2@pzOaہ ft?Ϣdd|}@#2X_5l|_hzJFBd4w(1#[LCc ! Qy㑉R ;8>`<" q&`4 1w)db P( #mP2 i脱I?BNx4º(r|>QFe_ľRYăFp<  G܅,#_d=QЏK!CpH#;9C /,2 a]#ΏgOaҲqD+0؂2d Eȯ9Q;3}Un9-^Zqpս!rHJ"ѳUCg^V9Wo6Ė2Ϡ>Jdr>QeR%쵱t%l$<Īk\s"k'ȧhø_Њæ֒#% 渣A'KE]չ&}D^`I$"veT,NǺ3c(#F<;xHv`O탪󴔻AN",>w_rMry4UXK0%;[wӮsF=ze&?Yk2K +] {׶%;N[< %+:J{̇33Ob}b5c|X$.y,N~=`7Ŧ6?AɵY'=v@KPd"gӑ"Fю1lcw{< TĮ!1t1 [YWFXO3d_!k-`=& sNOZ}T*l?r$MtxƥM=npw"_=.:-[XA`Vnl7l}!WyqTD㐗!>7x(56ڑ{9 /MnJmDߺ1(!՞\5n./ WlA 9s75z,cVVdl 1b_` qCvT`͎!Oq]Y:u}ZBvΎl'v "GӉ5g?tfz= )9ߛ) [s r4[^}97]W"g.b#ZGLf%MS=r\#aKiG–BI~^1 /R1s 0Ubk|e[|i<Ƀذi2࡬C^:rib^Ky}YK933.;34#䟦qeUMρM~ݓ1Sbp_b}g뽙Ovȹzl'^4:^‡{ A>{q(Oq9m!&mq:|OH:N<3oqCRfr`_ 0/lB/٪NV@}L"g8n]`gmVgvya^>=zh`~9g9y5]}cA^ ƅ\9ǀ~8ضwVx\Cuots1-5 {/0r_^6ޣW]fdV’h7a`jL7څ 7oqu5~cwMNXྻ.#a>Ԟu-U̝N>ps5{bkR3ʃ.pnZpbNueKLoc]swIqiA>p'-?Ӈ,#99P|wr<*_֫K7#<6mUvV̆_W`=6-/,j;aXXU9[Vm8G<*8,*u m]pMfU޻!lsZzVMeC0&=v^u`f#yyUzwY0_1^z@,2g1E#G\1aؒ~j\5t|C]1Lv{spM\te4z@Gb}fȃ szs+<5qkw0 Xqh@NI.{ksy/x7.2;䳤dq:p 7f A-0ě;-B&k=.CݒCW7j;^oYGfR~}ef 3o&xbsE 5j~ $o{xCi5pULA<]˼ydj؍ky5P!`^>ˊ3}uZƪtY;9Uu[S֢|Y{p,kɺOwwzP{hsdڗ{cքk>:sz`~˶uQ; đCTƞ C0Ӈ/dž,h܁Rc}{v+GO}^QNz[coݷ l#w1_avTӡA0YM_8VΎZq0[/70Ƒd ft.drX`X}_ajfl2V1p]ƺզ6V偱z~Bc3V冰]KcȓXK7pøD0KnΪk29thfrX#ӳǥ=XOҡCj\ ]{ a!ǫ·wxypkl{ZK7OЏ"^JCng$ n)凞67 t-pNaƌW2 _\ wpD\QV8VܺO= ' ±fаUqV;Ƶ{3C8:Zp尗fŅ!$ 0p#8F4詣qEhs̲k8{uh4q'Ul5nU;5r6ޗk48`@go% =mq=fvza]{۪RyCt9a97:,q} \b8 {€\k)'TC|5-b2h8.7ESSaQ#aWA{W}5ЗS7Ts;fۢL# )g΋V=D`oaM-}07tos:jK]=txf>bO3I`7p |)r_s//zqIvwKrڔk}CÄ29Ǜ)==pLkƑ9<2a :osVe_|>ui@oJ {ۀ-&)w[ұTT.f uf_=< zb3JU7*7x܉9uDk9gQcA_BMKٻ}D;|>RF0݂΋qy=ׄV=jEw4v\݁>cnT*s40tB_0/{Ypu}5еlƴ{cõut+BFaE+w-V?G!yžs[}nk9:egLxz5g0 fKΩK`^rQ|6g(!ҵ}QYW}5|pfcM~rgSg}xn0_c.=wC!]HuM~2>~*y:հ$:k )9Ⱥ}JvE"0!k sCk IеZZ5,ޔqf6t Đ[= sϼN\VAόK1V*ZE ~4͇qCV%+{ޏoyu-$<b WC$n{g >@a%%lB]EM868.jMn7@|a60䢳.kNC_xn] &CO4o ;=1 qHc8yY9u _9M^l80re00.0=]r {(UXx;If"(^ѐw0ԪN0Cgaoء0(Hth ~v#h8iH 5gd *Uү9RUXƁ.;`Ms_K_ʞ tLlcA9`]0*,- #==h6 %Ě$G{^^utz!Do τkB9e/q{E2͡qsĂ߷py|^a:d\$" Dr_~o>o_޿V?A&>~^L4㧏?˿>mGL曟? UVxœM0^)V+P{@ Z*;$*g[ raf<ljkK2Y}-κgUwXQQ^]8Nl]Jc9ȪVXY<[Jx;M;^H]e0WRcb#n~3l=B^;T[92Eh/Cjt.rYtR%0R Jr!Urx%C_Եv;L9 ݒ#yn0RQrpEoqpےT$juSuwu&'OE7S-NEx{K;&71;485$3?:7?% )3/:W]QϑDzl|x{s5$qXxR0+fs BBB{[ !NMU91vZVmlqt{oCQe͡lCѣۡ;#4QQG.Hj^#L z3h  A*yV0=j*sS82*AZ #$v-UzQ9ro3;IHcą@ݞq"`j+C <\F'`]CP_&^i 5 NՐielߣPBY Io֧`'O kOfq NzɣcGLq)qe9,޿muɝhcVRͼg;@7hxMUxYfd&Ȗ^N2:pZn^F+DHM1f]}M81(|uB_}k.͜x6MN-.M*NM.ϫO())HI-N-*K-h AxxOHg+'iò)-'J ׫r5'l~͇=NJTgyŋ 8 # < _N 'b:O8NH'J!;S@ģM 琊av~s1IKxYf0D"1LD48@6dʗ.o7E(Ap;zFcu尌O@L !By͍2(X #R>"p|8\Wç7]h_~OeFY~p2BD%,ȂD=´ߞ_w?gN>^C󓛋5\\_}6:)K,$=Dl x(-*N(1jwH-i-J,,H qA8Xd.'!N&0ױ tǟQT"V;3 oEm xpp8x7 g)D6gwPo6 j|Kva*KWZT4īz f /#M'/&t74<7xӗJoD5qmJ:4~٥342b57X{,&"G>8u}Г Ea\,ҦW]v}u  T؋\K~S+t[`tݛ*QtJĠy(s$14cWkRXS8ѭc)]JwaD%nMQեR eӦ\MPb&DBJ|lBNX2˷"]ѕUdm)5*=(V>w#Kzڊb?Rj& ; &1OCRKZP1J0P6C!ǦbTao0 *y_- wwU٧63?_`f@ *a(ZX%WŔ=GZD_DXQu*uZzm.1¶hp2hF2 0]SR% W|ӄXI"rH g + c%JDji W}x:W;Kq(A#3E1x"k|Rc]W<]FogrɏRR)Yy,U! Ta͒T-Cu 韯((M>u+):6o5o{\#)םc!nV2!Q {ȄU=Mme;NfdZl nr~eK}a.3^!R|C9V5Cͫt[d[TkbUBb=xp[0r.@/i21bI' J#YtC* ߤ&ն$k bjfUT!36 eL0(NtFqQ.^m,Ti 2o DF!XQgհB& \CU*Ƃ˹s79$ Q_qyM!aA,A5^UO@*4zK&Mj*: X2B$P}5Actp`>֖}1>! Y¤]_}VcƸZ0ٰ=84й>mU}K+zeþQ ܴc#="aZ_B*`JB=}`t!jPXG!34ħͪ&W44E2" .*!/We&26}T- Uҟ^ߥ9c_ PbcVQϩp*A!ԁG۟ޙ|wRjWet֮8ԃ6,4" ꮬ[tx:ƅ5LswΖ~]6HE s+[Zg#i#G[~탤n8BuA B~+Smgr:zTL8WZwV)%K5 ߤ=vXt s =)n5 ֊2A`ʛn+ԱPHjjCa_P*q%7yC!el@8p$6G"E[nG%4^,2c 8˝zYyZ+ 腟gW%0 )'NwQL9H;Rk&5"ų@R:Kd"qj,E:.&ZCH*{c H4XTׂ!v7˵W@ݵLhywӑ71db&iz!0Ѩjri^` )xۙ*`B?[qjYr~YQ9z^^jgX)xX)f%&%'(*+ZYE)(pMˢ0Y]SK8OC]%(,83? l%,_<,.9ْ=33*-(7dBd΃Hx\iHJ'/A{SH '6#>"iFA['!dD'; L^)&j+R)WDeMѓP,!lf= x!RHzuH*~GD$eQ Yc# I2W]os#l.W\uTgv'x+c^485 H= #, Yx{0sdƞɏWo^=YW]($(U# $CG!:%5-4$>@G!;5 $1)'6VS!?mUu8E7 |bl%&yFh]ݼT_PW;9M6αت.OK RRRKr@nH,*)1}]Y#&^6 +s0rNT/xV[oEV[wsMԎ͍4JZHu;v6]vMIyBBZ@ Q <BBo]_^'&ofΙ_מ3/ASW/gn#^{xæ+  g=#+Jxb*=vecΊ2$n-J&Drqq9I-olEMƒeѶH3=)둛hAcw[3 o`z ^a(ij&%ɆhDQ'%2[@PđLPE.N=Qa>`:Yt}q !=C] ̟eۭ#0ɎU*jC)U] O?|u >xQ0ѯ 1X7p wH2b9&)Sx5#ָm*/\u h)7ubbJ,>8l ohsn`(~xLsxtV!vR\?l)0׍ea*Vƌ_=Y]tSFJ`.>S#!JIFtsgT{.e|Y]4~\vD>e J<[o2qw;* Kmhgّ*$hx-'?wum#ӣhg}50| Qo1!~KyT෮O$) ]5^D e e]<[)yh WxG yU Αzކ_kn8i'8v2 j?]nQ`9bğŪ29a 5Qj!:&)D`IĀ<8zd6|QɊm M XqA=:(y S+Ge|RTCTd= QwM+֗ 4&VQ-A/(.awQPD=<#zi&f?D*뻊&Сv7m1QpfuAS%6kJ\C}H2cE, AJVo@S%`?eUB;:E񿐙La+O*,@^?wuW~O')ll2u_$S?Nӫ=H`X/{U,-^}@%SN2Q 2Ov9TYI@A> pOs3HO0T ~LzfȀ %4m:@/@I-4 Hf5PR9#&Zj!|ϬluɐsY*/Le# 3g/z9)3Q4}`"',ceE|M-l1HpS9)-3(BG `ĩZ#g-Sd燳Q}ꘑj \UX}l^ZcC"v{)l6pP:en&Z+xnV9h~3l[z2+R%YeX)?)H` SH`? z6Iͼܽ&;`|U <{a<@6NhEw`č1-`"9 nNlO@'NA7;o!)op~^Ugh`L3: C #?Yd6㧾qH٤jp!S؊>}X}؟0x!2i1MWqcun5mr站%XD~[vIn~3o7}j*K,o :f ?cTa&E5^~KU T18% fP0Ao 5쓄Z[t⹫^4KtD"w;,Rt~q= Jw4g54c:죈%Jεcг$C8j#[j~EZ`|06ȩ/ -*b^-D77s1eGJ%h*D}v)d>B1FUH>#qu%j"g(Z:o݁Rt] 3N-H)ƯJ?Q#/i!5p1~4_ӈA?+`g%eUڦgoW{TzCT} Yb8=qvc|!m$ItgϺ N6?em>jdsL-kz"3> Eu6y -+^m*Y s*iAٔXg!{UAaPC)(/E&Lt8[} URRg=p"R3?2 C\)D@(dJx/c ~L70i XkS}}2#B1> 6  b60Q\vJIރJ7c~'D9ЏS?ff-a;尀Ww&C~dG{t@+V# X͂ȶ`Љi5JfYi<n?O(MjPCcy{!Hb@:lP+ 8:}O0nKI{&h/jn9'Slyy!% mڸޟ$SPf}ZWԧ"vC$غ*8 /!V" &rN,԰F^пK@ b|2mŸ*AIdK)Nk9m &_v传C䮅 {eaDoZ'\*PA >zKܬݺu-^ok&;9)tBg\:>BS!G# V'i*ZLeGXK8ijtl4Ӻ}F//^sb^{5 2#;eaX.O"pA.xoKkI IR'VQ/[-EbBKov3}ťēXWF˿;UƀTBi"p?KbT(Uc3"tk GBd(GF/Fouېb*?)Ԑ% >/"K4e!Ag}CGfg=C9HVtPi-f+g]3k +x܏DB'wԉ*c[rF0 W̠Bd9Fy8DMbvJ% *j5=qH"*SZ'N|- c)p%x~Va DxHe2$ٖ#FM!ntE ȉ>ҋ5i." 4`,8MÅ b(0jbrvt,ԔFtKrp1"?e(,4#ռX 䣿DPĉEn[XҮ]Z W%Alzz_ 2r+q֯'@a۵u!hTUA5K_ R=uTIeJ<nlih 9Ѫdp\-:.cftn_r#=7:v, EhJ|=*u~XéKAIP1sh(Fe;tOb+lırYLD\ ? I*0Bk塙Kr|ٽcFzvsdYAk${ \ C@fzIgn%N .MlTur=NGU|{wwe!,OB-iXmeJ=8ݟ'ݓ&Cۇ啇 QPLapZBٱP3b8r J0T3z''S~,XD@cNwuW?]=0'KPT(/i!!ĮEV['-v*ӅMS|F'6ۺ @g`ZZiU|#(NBQ=VPBXA9 (K@8FL4ktrtزޝD%3"vˌ؆#`O/ܟӾA|D/8MU :;p;^]tO$A NiRdLVgp0G0۩uU(MTԸ*dWBL~LQEawu kNo1FPətҘÔ?5IWlk*+D `9i%QZ\kMl_uY&jD:Q\.צ!wu%Ky;1Ɔ|Aź =z'ЈUd_w 7 H$oԉR>4vR[G{8+;5^,1>Oh=aKɜsnSeYֹ Z7Ҿ˥ǧN2ArXLy[M>5j?v>ᄒ%R55,=g &K"B,&C ̱/yd A8s_k7co$tR}f&Uw]&$ʹw܄ƪhØ3r`"8KI81E $e?^lq]JST,9qټ J[?H'Ϲci&UIeϢX:bԡa_8c^U$5g,s-Ƃ[tF%|q|'хQwϼK!9ʔޣdwLҸ6]s|eye-t~53vZ^_"2Dw_.9nW7&2]Ur+n]؅Tn^$;_9Cb޵V lٗO6vˤЏ6=]l^1^#2jK/8ڬU%8K[T7jR~=?0$, ?8v n9xRs܂ Bَ.Lәfm燃 ʂͨ+phyOb,@GWc^6sX433 OgQAN}qp0:OVWEMHP7jD;.XU﫚'{s\|'md/cmtii$<7W ![ZũU{jLJ *؃"*ȋ1KGG:Q%k^;(h2Ձ 97VʐᴘM <H'Q>vFi~$Hy{;CCG#&/*gՁ#N@q|)"(qֽUgS>.iR[4 vMTࡩW.ک\_C˖yԀg*ks+~X.hk9Čyz4AaskOޒb[uJ5iDmeOf*Kݫ:koJ|.dYRzȷUi)TW[=5ӻ9lzS5:f$J Ն"} UM," 8z}݃1)Z$o,RieM.{\ eU_԰A[b!3{qy׿^{чogͤg>qi>d((6d[<ßYm4Tl-/4(k)Xpc FLI1t\Z"tl\cZ,J_ǰBBQ1Mჺv-.NyTj#+Ιrt{1GKxXTDg,:={j."zڣtERumZx\[3!,B/7N}[}5\*%@-F.rq_ר>:@%{lxա$i(}X_a o-)+%}`tvY ;Ȋ ~%Z[|-\%qWh&Ȣ{XVշ|m6_}ܷ.NOY߻!씄,*$ iӏ:wxVOLgϲ+0DXdsaÎ *ZY4 Fqe-+̂zhҤ i;bR^zfz'4Mkl64iҘ~cw5av{{}O~w"  ԘlLK >Vd;$ xMPAO@N-A=lH5ybV `FDJ`Y;-K 0yɛkx2`xL7}|}RW,azrU ߛGgi[4#MʯXq>!IwH "F:dEݶj"ʢ@xC<]GtM_D]",ıIx} =[4tajrS쮭RL[Vչ׽Qa4a%H t°' I$agO̳{ gLw.kuy{H{X%'*se=}[|7?}s=D$3z=k]BNDQ"Tdj΋n'V>8[p}+pWjrc[s)Y]NM~r:}ToN]yk2ګ7xXoTT\. MHR½S^Mw!wfvm센ܓR#>ݻwyѯ,5"5)0P 䛈 7tU3'ೌDE9,Y Z?h~u"\CȵHOX)s2a XI3gM"=$y(@HGCk`>{0p1Ft65+4 )i SX.J%Ix!J_Bscǫժ-Xh;S6;'b$7/OcS%@O;0In/~ + ?W-h2OK%4S$ wU:ͬz)"9EOy80J%KS#LcHB`5zaElʫ^* B&im`Le;Y̦ߪ,BˁH2YW89/1#KJČ:ICkPh0Cb%H Z{_s3G/_F7[l΢rxbY s+9xl<\0O U]>%,Sly3ts Ú/RAIu8BDX.D!BґzžPl7!EsANi43tP U4?( ؅_(U"HK*CWѸۤ 9&lBF+Sq iOHb\kg$ OȊpDHLqZ)<[L홈|a;쁪1Ss׸t{hU)󳇏 >`ނ|ৢ@Z^=5z*Ra1 { rf +LlB50{h{% mS"T1Wqi\DZ@g*:䲩wmRͣT&F1av\Srw2@Cl&Y-Tdu+D l&z=+K 5Ԥ1' [. }򈶅OdfMq sn]?HE0* y۽9^gy'N s)T(6R"hǪ缭O5Dn'"J>4yc=9ދĮ k۫uגj1C0o;c;,e+axکP y~JFr93E/"%Y ݍQoǗ~ Wko l ($%XڨgTSEeeѹJ6Imt+CІnjYS{.')eHzz0[zEȸU񣃻x/Y]ן{kCeL؏gX׵ KC}ٷvleb0sM*+m?Ha%q 8{k{ x;n`&FURR *23J tB@Q~rjqd fWnd~%2%y9V!Ԣ"1LOr5NN+ړW`P Q䗟:y͢F&2ol*x;nS%v<%j%%xf`3dif ͬhy&>͙g r xHɑ,R IYu\d.ϸUǟᷔ߬슒;4wc ~(,_/}&|_o\ܹ3O_oT#~GDyѷ{F0U)J*޻%r%bS2Z6B0_G kB_VW`aLDQ\^*Q6Br>oZ-Z-L-T!oNd NdZ xҽi,b]D1\WB)V>A&MBե G)"XhpVL}Y %˼mr6.K9}ۧ%eƾzrTFHCJS ;ˀdp!8*fy熮Q*@Uܠ͇sPp YkE*Mc8,PJpnXbԔB}($4 Ҡf *ׄRl~(nk:G"׆?PcP63Wmuc=몠(ScR>) uٚ\@j.<`ph%Y"}XcK"\ND'&h%@4_xfZFZ@, /> [X]C<ꆼ 43k ONy+ (#;dAM9%{o^!4txD ^z%GD50`  )j"Suw*7s~x( rYtlܦ"r}%NDߺQ\+˛Z^ v#U1,j$ޤ&i洰J.wYG:mVp2#a*bBz H(y &Y恜З*FoICu!GV?Cn6?a5{[h{  i&n.+)ZaL\ˆdRm%tȒNl7re Zymb^csYG>_Hsst80Q,=fr\80{}u4kt DT /1mIZ@i.A#>-._ ;%0QTh٧1p/䀓9e>q5&.ʕYvBt=BTdEiH@PN4`:Qv)imcNCe@S֏*T="G\+0DAJJGS+Rq老sgP թu!sv/Gω]nQ)͏|XU˽Tfr/`キ*Ey+fFYtk]dN̵#IGfrZv:(-ճ`Ccє:N|uj{Y5Q":I֔J 邎B^*ދ9Wa'4nnFcpGBgtU ÜZn~u{&/1%ʬKqu0bE`{1AmHUo½^"Ԋ]~x(}U oǏ 824>]'d@~D ̉ ydffyM^g"y_n:Uo'WE{ kC"PVESR9l%҅~v2Ƙ%8foZNYi8=ÔJv!Uz]&Fl9ˢ *31C^G6{j8 65v5(̴. ,fV}fQeuo:CǷ/*Z5cs lo/%`8'.10'}>@.WP1s%fܫʋ۟[!e>zڣtH klk5˕E_lͭ_,dZx`gʓ7+\aE ( d(x(un=}˒}, n.cIZN?5@'T'j^<:0]u<r x=gOdX+$G Z?'6-鮁(_m;􃁘CkȪ\*=F5/Z׹cqjMr S]^su=/BVO<)C/'j^TVA[0_!>@4_`wpj> n̖` Ĭ<9x.)0sLIaS\@U]vWt.[er>xbrsX*8EĪhuPܴZO_e>yLUNΩa&"߯$ R߹ _h0 X j'Q,@ڞ20ҷ*{EE^˞_ReA$Oum1-8!8Ѐ`%u0.4 !¤u=hȃ?cZvڡȘ` [5R4]gxef.<].y.Br[ (56/2h.xUIrx9ȴJP'NY0GsZb<)&ٌS]&/-}LSqke7P#!2*+ڮ?-7pHl.ƞӋ 2]žK>~o9CBTW\{njާ\MX]2n!60P)kcD-#GYl;w;vVi.WZbz׳-۞_9G)\g߫ɺ.s/'J+WY=-]!NW}mǵtB6\ٯ?o^&&AԽ Tˬ/dYkpxwz;ǡPy51Qr̛"3+]zɘ/>|,)'R&Ԗh͂Yl';Q6;D2 IEYUhPF</;%& xJ5w =}%"._JsA|d4og )_y#'Vgwx`'5зx]ı!ƞQ l5 +;| ځɉ9Q,+HPC&\˃7Cw2=0YE)nD7ɝ𿿈{|l-TIA}Vö6\kK@ G3h%g4KY̛,|EgTk-qhucaͿo(o/^L糭@.}i|#SXN"?9ےD (n/".7L!V +pdF(6c$Raȥm fea~?H^@0z+LI_]g`x-I  ԔBGnH5zwaE.'oX)+^P.L0i_cgb7!IzXSI/b$`.i.=s@e~m;X|56nmK6aq 6%U-ƚkL|%W|] KVڛ "ڱ 8IH~gٝl"b ]H~#e] UѬNp / EScw?aƵ».Hkk$ZMB~ % wHU9N[,fHtDr\R>oJ۝݁Ԡt8 xU.=I=lMZ/ޛnI{N:{, _}0]ڶ)2fT9jLm3wT2 i%w՟ e 5>̟߫6i%[YeZHc]CLE#  AM ݶjuYtLwddR)j* Hvp̗{}/}rnW  g//^y,-h_Q`HP&+oڥݪ%C1>"V74B|cIR]z e`!5V<.b?q9F PArw#r*<ի}[*8pQggl3wD}%sM⌉fBQ?#IU,Z}Rظ? +LujL{;/F+6O]$Jv/[R^>2^+\el'*ksI/a͉ dw$qbbצk]J#礱RF,rlr<PM7ö?\Q*_f=P&fM7`aF!ljU5gَ pUֶڂFxIU4k,,t! -` Y hI㧪A |xU:/>\ښ1ts f>m|Z=ֽ㒖&VVGKЛa`j]yGluluWT.PZaue< zFW/N}k`76^g:K(0]\%PB<ܓԍw 8+ӈwN_QuOUz_Sb*4v?l׮S0{g0왅mXv m?5>{FI */ 5˂ʓqm Q.|; + O] @M4:5CB%JH(hN Yb7# μI Q u0 b*F?=[:) v#IQL%gp$O@ʁWR9pN -7<ʤfmb*I7-`'s)hm4љf1(zbMEda~_˵ /"^Nq G\@ݲO4sRED [}fH1"I5kcw;2"!"nm>s.tOlBEr`\fVt're6?mpYe8iW˩ksNd&E=5 ']JԳeN͏1..zP,@]@Rj'n߬ΰLъc1WN61> 1l.kA OdIw2!HGMe0sAEf ݯE}.[(y RTO o}v؊qkE@E~ ݟ@7jB"{"XR`={Gf?Wq_lYprŔ0n|&*/zK:&T.Ӏn z j7O*W:O`k!'rι}Yku9#^Hz\ n*EX]V\:*:g*+χH=ݻQi/2O 3MRDZǹ'w5ɏMִkpL|o2v Aq.˗7 ]4q?kuq,XѬG xf'7z:fG ?p%XDǺqUz-B' 6O鶣hsySpL 6X(6BBH=$m_6W~C;tj/~@C ~=LRaZ/掏?\g>)Z6w1c* y wv.GceWKxSKlU%UT%MƎƮPq|~@{<}3a&T 6JHUE;$: V XÂO] !? H9|s7@1(鑢(ĢD8z&KXةPȌa?j??;nn< S]ƃG{PFhSpJtIO`2"Q&Sa^V-3DLE%]FQWцCB=bAAÀ]/23ڒ88v^AIWֈ Je  \fC=4JMvA`-;AJaT(8sHyv]Cāf%EUUfpŹ MMMq&m\t4C|բR_ҁUƋNgCT..V! F@ 4_]n3n& cRD]&#B.(fqKB_-Y߸V|Bיy-9}]nցZMMXfLt(:5Ҋk)ab]MTOl W_tRqYpNuNuKYbQ0U/[,GT7o`h84V:>!I ^t:B"wxX]lWcҤi'4q7[%n6۴.;l'nVݙ޻sL VBA(B<BS[RPZRTB {g!=|w],.:"|0:| % BM[x^2Aň.6j'( D*I2^l-[pk){fx>IC)u%gaAH2pGcD/7],֢<9W.)s9[{|,@ &9 oA2pQrZTP_L4 --P M oԴp槤Fֲ Qk5lh7lAH&"wwjHi@&oI-EL]N?~cxr#$AX&`DNḚEg>Q : H+YNb:tʗJU8e)sxVy<4okts!&iSRVy9*7 :OΨSU~gY߷i-ZWV^\㧼X[ک(wjӛ[*6U!βH 2 `FQT7HN}iBMӇRf~Nt" n}p˯lol|&o=!y孷l wo EwB CDn@*Gg#Z3hZ$H2yX J,`Zs InEy@Kc7v]0 &DsK;02<[|Veҵcrߕ{\ă Q7$5[CfPἀs%O(=7\P EI|id7!)hAb2cHMw95 'O $,QWy_khkNLAi+Qy8|.^uv X ,l}R{P5>.I'n(wwT 591DYBУPqӥ~9"Eg3 FBB RfU}}ÈC_^n1Y`^A5hqy&ЬYj^ DΥLXT-D!"jʛY͜73#Ʌu qn1*LW2We L߄z ̇;|a'h^Nt. ÈJ `^ j#I/*x!t$zܮ8RϧAJI{f;p@@ /_)\I<8^0NJ{ۂޱSdǤ\y%_/>%;UFۛ_uK|` >(Ke귩'g juB6J NN=8% Ә*Hf U,0abT1`k]ȳ: ťi Carf9XE,'3P:KVCT }0WhcE6먙=ԌMh#>{6b{̤+T68y@PrMXq툋|Ԇ'woʴ/W ے РT ux-[CMƹ5 `suXQ*)ã&֘;` w,!Q*&'Ō:ALu瑆>aKT^p0C${վ ~RjdE2W[}ծif]7 YfݢؖG/ Vok-HuL`1NhQXq^K8%*,L<(#2 ޣ6'.xqZgBA^nqFg FZı&<9x;*F5U+tC C#K]C]C##c+s+jK7? gCſvp $srj(4EwBv[1OO׳-7&lbE*݋-3b<7Ξ8O.PwIBP~UU)̱àJ!:4LRݰg `;[K!lVEPhwa= ;mׇ|24Y_]S(HJ<ҿQumu.sH9?>/D9u2&06-rI͵y'Xĺz oƵLLg*c;:wRA/feKkGW&{&a?BV(JN?$5,IaG39R_LcHN֌oʲKuY8T!]VH-񗃼&+ !$ff0 e!SU g !@ҷm6HF:GOt<1痉)rYp?byʪc?4bF0 !w`l&8n@V<-LB`:r .[hy^U- ω ȥw`ҺinhaSH@)7o󫉬ԇd!t 菥CofpW7"\;2m6,(ƺpa];1PgԟMYD(JR葪tP]D6F@ Pis8=`O%bPбʠ<rE0$wW`:4uf ĩI9-`fL<3RFx}2au gSlP<RYE#!c% x(9_}xÁPg &:=ZSa̅}(zEYH*@IB(/c^Jj+S^fOYpzR9J}yF˛i\7 ATHJԳtso6 Fy*fE4(PYӪڝf0,հh:I,*x BG(>=Ed,>`A&3Y8:6"q8:/Lb,@\hЇ<S|х,3MSSkqFj+1gg>5FTuH!濂K |dA)~8cR^=b~f -d lu :%:mOh%ݵ_REѦw &j"eZ e&`# Lzd`dLZ#0" a9Z+z?!~h#x`6FxZ#NށLna\8] 3tGh8qHsڹ~f rvĒX8c;p4e9'[N^mgɫ0t4=tq Q_2J-hED,&8+LV/7B-dW :t@;tF]L j7ƍ}ۨ;?\$ IN;B=nuXW:tpG NS}l9oFkAIvx1ᢂ'@zDu=D lz( ^xXs$h-R̖ܳ{Xo.,ś- P`Su%1LS;4Li>Aԃ > Z((%S J[MQ >n ۧuL4M凰L zo;޶cb'%Y0Yu<`VS4[XH&T6c.2R5=lmf~5fZܢې˭0 ¿I4Q)O:ȗ2>m}tHrӠALڌ.ZPvOpn̵rT6cti?u'q R^nopπ} ρν6qSzNP{&?? at/L ;<.KS=?_j{T.H|DϯtEw yozʊ%;N eL)IN,{rJde|4fOM 'V;$U r1.~L Xih·t.TM G9PE~ .`);lY Q!:cȲ:-S!/c$EžF6GgQ< :k[%o)=L 583=&5( s ?r;VvI֭{kՠ |nbț(FxٕTzј 3g|Mr?TSpVz,)H= * c|Fӡ|֦ P+k2Tuw]E k@~qj'S "5S0#V'*˞9v8eVחKfVJ,MU3ӗ+q4ĉE,չ(纘9"8j fAu7õY9W?8=%<MlqE F䘞:_IMzOq60P+̦oŐO\_M`لh,%gWE^[9}4xL6}*<sn1Odƕ2E)wRB.YX>&-~6zI+rCI^X?(8,s68Cg;>o[ճ.qHnFַ0.$<]B=I ,㝑z,-b4EӚn!WQLlK(@*S(](3Uh)WZQ#$wFB?A2k$:=I4p!2zf: ]\l:,2{8D[ҕQ Դ'mw(>ľ;g܌ǭ7=SvQwDTFf6*$떰']jq~ovL>-٨wM]Wjxp--Iׯf%1E *˶`` "M~zD^DQbK1,QÄVV ~1Hnvߪ?S\>;/H㓇G''ώ[)B¦e\"l1&SA'u[FHjʽ4`G\M@.Y޴cy?iB˜wJtc!{n& ރǟt-;޿yN05N'Ķon@?Pqih%,3>Ց.n^3unfM$`c{|EcMIRbcr}Ⴗ͟hۥT)pn¢36o@cSzG, ~4R :Im~kE[/|AʆC5ȭAv#?[Jyj1Qv=J;mHF+MllFU :>[}|4oujF.HQ'P~2\g G޼kcS'm)gG-Vr =a?ˈQ$?VUB@.3C*&1(30UբqOI[MĞHPƧ V3)HOv G!5(P*d6ݲ%[j2zF69XiR+-|ꐲ 8ھGX@ƒ ӴU{үKm~X{1m]27UP0C/(m~^*IS[!&lC|nKI<ֈ̗|-#d}?cʽx]Xl۴,?jYfVL[Xe]1 j.Ʈ砩/~\.ogO=*q~1&9;CGvq+Ƃ?3O/dX"PxWŽIսDġ(Yp>)&ScEDqD?f#`$}\44]L @H='LLS±tŘCΟѿ['>YsɞSCwe"hʮ8TnE|wg C8u=941)NOR-0͒)3,%6v<s2֟e˴b$QF:*ݠYt ,?o g>t K`FI2V=,A])Եuڴ`,"$)zmo;>hͅZD{;!+p3SJ-(W$B]ާCkX5~ 7F< 1}6e L[%&Y[R0nez!-[HZ-ESh O`Ó#8l?:h=j~tdC#X_&Kb߼+\ۻT? /^k X0fZ  ohPt.jcA?ʡf90Tg>Nd.(]^yi"v>\s#v>cGW({#b &LW[9-j0u(h憵N*q2΍m4f뒺Ha#mIilms(r츪fH2YmE_=/Zj9Meu 7uNl \{e7 u;ڎU-CGe;ƞg3B~v5Z8$OY8ΥX0Lnr/\?(ߺWcE$0ѥ3M1{,yPSOn斅vu:FnRVvuW8 so}ۮ@ ,.EX/rCTC)[Lj.tAT` /D-L{CON#Cw+gO`ÎN 1@EUR?Ho2kJ\IJ~t{81RpNFuឃʜZ)OХ+vOeUPWq+Zn^ 6a^of^}ծBqsCf|H@JyF6߹:I@ZlQe_웉s"ookkZ1;,q2|4{0%'%'=w"Z=ݘg”;@k]Rc ցKǔPSfP,^Ȋ;7ˮh^ƍd~қJ l_i)% 0ܽ+ p߹#$k\jխ5Nw#rpSκouOm'jlռي:q};:mfR#bܐ##8qSU% xmRKhQ,4֘Lg74؏LDE'͘C~JPM+.n\scEܸܸTVeTpsssg|Oψ^YFB4`b0&F")V2ZJy@'rdU&JK)u7ee@'FRfM)BNE813jHFؽan#u݀K,a–z]{PN IR%԰e4߅vJfwkAγ1l_x]-|Hcr CC65GTe|tᇇޏ ΆS }Xzs]" : l޷8ڷ  ^,0IH Cn>b:>҉۲wP[;ygFx,9ܬ}[p%x!9ضxoyfX<1캳^'e /Qb^SUURkPF*DO xX[lTr k@cSsQmPRv MJfϙ3s]OU":JQR(xh7*TPӵU^MPJU_ZEiҤ}hTB"~7v۱Kf2]7E&u{zo<,uY1#Co]+3ϧO :H83ҹ7gsAK]%ҁO%V\.glG{ RRޣm/Pc*90y\8(?u .J3iikQykti5̳j'ԙҮUm[B4_-:VnZXR-xL{4. < I^jG⃣ 7k4LR _~ཥeˁ`yuŧjB._+~Y~cHL$dUջϫ ]rBdSgB COl[9?,͸8ץ;KcIF~B(,@1Au޺͍WSdaWb2״Vol [娟{'mb Aab>4^ZFg5; .MA.&OGe1)@4˸XcSV idrgdNM&~t$A !3a+\Ȋ)PA|p:C@K Sݞ'6|ށPZHeL? sn߈/L[k]޳τC]@uSdP\>-ҲIw_V@'15- O/80,?!mCp <]tOIis"9Qp}t7tZ7fT]^#Q+c5Ϩ +`=P A>G@Bِ1*zDfBUR Gۚoo{a|GSml-p=pK>pp;D%zd*#P|~pU[KM[V_ӓYIџ*k,ڑy$JzR~kl8$v_vKuJ=\92̐羸K^8Co?ścw办;~<#Xqep~V.u+|зp,NsF*"l4bx@L~vchLIpyRGw`f`-"Js]oL3ƒXDAR@N (~).µcKE"RH46 @Q]S 0$LwV0T'A*?jr"])9Hg?AV9Ul@XQW\@kh&p"_`'r@S+G #W- )"гੜRcm&+dO@Q +G(&Vt9Kd,wrUBA.n> $hϧSYET>;.Uu9TbhL fԻZ3rzg'&2(X2"/\GqI\չ7仃2;%P$L*gWJ DO5-G[cMόFBK3zU#kf!:)F9sL`l:vRj-ݦpv*{4>4DƜ{ʿߏon'լ_Y J+IdP aHEsm[[GvfLXz$Ia0sY}S/vDAmۊC͐/y,pi +"()J3M<5r0 6ҁoKc#v 2d88mtr@ٚ/zhkբwbP"Nr@G|u|/&qnǿ/T ۩pΈny^5q*!5OE&OD3`]1S)MU #x [ZP.TNW'Ou"gM`[x{ZF5U+ltCCKC# ]#]C rhI Tx3u#6?;F$:<󠔕eQA{̋Ͽx=msHҟ*J.űzv/(v%^nrT2Z@v`,۹UItO4\,H`gyAۄ''_~H=Bǰq'u/s: B:3 X0 &"D`z+?`V\7MnD$X_/ X0p,̐X_b 9TLp#f3r|-pKk1 C#aF5D5tqx\ Rq]X؄z:{g< "tt]rK8.gvD# Ņ1~1Arq֟Fceg3k^J¡@ 7 /DLm 05>M1.:6 *{pϹ}X ¨^ W&psm(S ZG-M^%72:N,ݣ@7E!m}{:,de:N:~XRxP q"W!sۼW݋+{ʍ#.sYSS( צUy1 nhk(#ҀTDCBP"0{?0 |hҵ̦y] +s. I)D5h rkRx|״x]pva"Y7sӥ`JL &!*gmo"t^A(0Q!@GÃT'dэf&JP&X«1jXYoP<3 Xj~NEw4LWPp l Ni[`pNGc, ~=ll^ڴWO4="CAܒb "A|R%y\ Q'|Þ R% Q)eΦ;c;盆>=3L$l3 vx72Z2yLI8!Ze z&t@tSrmOfRuT*2qg#I2Wme`>xMmt;Yb\J ߂}U:$7qg橚(1)?h MR5d{i9\ɸjK,_Ovs/9iK.w G@U { -ߊWG^``T4wG7Xzmz DuNħzFIM B_G0Ӆ .}?'Ǝd.L6'ږƯ7xoa"AZ;.[HhM0i?c!M߱5`_8ݭc uCG'#"ˀa=gNh, B<rxC i0 e!'R{9;3:CԱzwװd8؉&lU.Feh_ ۦ}H / (<.Lr<PIw3abb-6eXA~O0t D:橸 塅{|kdba@#GIY[RL=9L=BMP TqQ\p Ņ PmGc01J?)3FC9rhzEI_fn&@D4/ f$e֤A*Rͩ(U/עscS+oCNNbDϦJK$>zR'Pe=iq‘)$*SPzO?r,i.گV2c{@TC!.{ocBL%EIAP('~RǡؿDžh'Gf79\  I{(q}k#aא)`͆S$M Ct (JIjSz /ߴܘ_Msh.6i@?'t >mh S$ӕݻK XѶ,xs)XLO$IEh짨+JK - C(6_嗭dURiaK&K ; [ͱuޓ] -jӫOmf:j 1CKUCVŎ==a&mx5iD~bd"WJWY n*-dUZȌP%wiGRŮ+Raqʚ dzrl8\Sg.~t &ד:f>폐_Ӯ[Ѣv9V Dqbab?g0(%(BaDzz("qPE M5/p!]blVw@W垤C;Ipcc2-mzXMj1^u扭b˽Ta!:g5:hJkN42I=>=uyfg2ƒc q$ 9Y%~$SgXVՈ >W r`;Mᒼ0Ԟw7~ušq#qzWm,v?C5C5|3҃wF;b~exImҎcn|fr\|NVB1ۂ*?,MHxЧd j_R!բޓrCoJ,K=pAf/圽96oDzeY*},?!]uG> [a7*ӊXޖQ{jſC0߮&rS6_,,T-2=AS4V.]U@@%_-+UⲞ=+u7;&(=Tg$Ye]=ȒQĽDZ& 1a?ePXv+;<@Nϒz58 x{i:B@Q~rjqFy nEx{iF. xA7 q#PW  qb[ 9X ^id{# %ve%,?UA&c]@cE@ X2D:RB~/M .M/:RpUTKg[=s7@Uds "CxSxM/'&]q2&!s`K.Ȓ+q}o-`Lc'O& FYY 'q8a lāg0ON$x҂'O,/,v`}0 8 a_Gl!N (Β8LG 1 6|B$'LK9EٕZ.!L2|""ʸ 11Ca0Hr8,i/dC9L8,m&hng6mE@d9Gl4b+ /.*x@o ".|w3{z}wo}`(e_g9+А9ĤKmÀ \LP(yxm6Y4OWnBAŤrIЋ3JYV" ~Yg: yjCa o,6}i,C3C2xt4`~zGH&=Ak<rlO{_YIq{<gceu+"b?b)>5?F6bʯ\ֳ1#B:S8p٫*cu$0 b$a75Ir6 JL&\"Ql-l Cen[8+nͿW-$Ôc`\%Nu֡E Dl7Yƥ0=Xk(<Wʧے-TwGn,wXjY"h iSiEe$8jX:m1t\ƃ8U9t[VHepPf\h''*۬YvM |I뗚YFqAR!KJoXWP5OIdă&l1o* aewS*(.ߕ$[V'N9;gǾEPߘ'*ҹd1KbGd]~̭r wJ98BIvEjz: zȇ 3x>#X$ளV*rL2eXX@3*xGCNBW ;hWJ> ;V1Ӽp.3Pݵ /߹Sh6Hui02zh 0.[ !,hx{Ԇ /\6%:|}FOS{LϏ&Ësx%)\%\NGc;? FCr2\~TtdOq}IW(N"sZ3=ħΫbIe>d<;/I":K."x::0Uē$(DJٕA|fdZ}S~4F&W9ɬnjȻ$MfB~ָ]Y*1gx_U>)YlaJ9<k,z]_CjQ#.Kt-ʹ6aBp{h|+Mm}zlaڃAyx ܃%rcI(^\AncCEPGq]RZ֦YfN_*3!X؁NȘPN$D@p<Lcg<=:AZ3+y7`Z7 O"#F1)خ |B 3 p;"G+֒o.дut <~Ah|9i !2]&ߌcy&'а cŐ?s7K!{*,]L}x `*64¿ɊZ]#e-cd2ܟb&>k5EbFjURF 3R5l+RH6n4ƺ#9ꯇp tA 깄Ft݀0,NX)^>C#!WΨAg[oސ=!=ݘݾA^WP2WFӧOdrq|A$p0ߕ FT`3&8)X&!&!A*&ؒ i0P[)R3ec?V3#fQ>_ ȨPmRgֹSO *O:;IDIuLCD{a'зEfAz<,+^G+O^6]Gle 9puy? p]_O(P)ey[ݫvS/ ~@#hY [&}/﷤^SQCuMoiq E*$j;j\/R%f>E T5FT!Я5뵆ohU&kfFM 0&H@h?xT1ѝ=S_z R %-W}7ԂMm-פvmϚ,gĨai8y 0aengS{)۞[0pf#9r9M96hLm%+hB;&aTpJ mȔvlEeIaF wWO?/#r48=}?8׎?#ea-kGe}~zB0@TN *VP!/al. #dw֗\;z777+9mr)Y$T k}kh7nЩ7kŔ5YQg+u)=EblkEBMGmVyID1KJĬ}e0:M )/_( )DA)CP掋'RBIϡ`leFeϺ/ Մ}I©>!YTݫOPI**X@Hz9Fvxڤ|Y.*}#ʶn&?mxo1S?R#iai 3I=]3uND%#z9G̚p ]foM.Z7BR$=3cVOBWG7ZGzΏ}ŋph%~\0UT?7ninXxnztcfv B)qxnzt*n"Y7?? D 'xT5/4-define(ejabberd_debug, true). -compile([export_all]HfstringqH0qz[{"reopen-weblog", ' +8)G(+3ef: x29׎#:M&⇔100644 changeloge l+NS: .7 0`ϗh100644 control.in>$*4J֖Q1sJ4ͽB| ]@3$r#o4O~~ t]PK5$fg9"ςhh@Z qx29׎#:M&⇔100644 changelogD%ѳpw2`pXɑNS: .7 0`ϗh100644 control.in>$*4J֖Q1sJ4ͽB| ]@3$r#t 5:8W t]PK5$fg9"ςhZ Oxo:vK-͞6NS:u CcBR9mO"Z100644 control.inz])ی p;770x(}^V |"yG;a `>Mpxw:U2cu琦)NS: .7 0`ϗh100644 control.in>$*4J֖Q1sJ˭a4k3aPk bX5exkh`%%tGtOm=o33߰hx9:D%ѳpw2`pXɱNAṦ ) @##dds axkh`%Ek>4gKN~p,xkhpQD|^g2&Le,Qf܃Wu-xkh`%r^K,t-lm5o33@ x9:#v~iH8@"N(-$R$[  Ӓ!xu_K0şOq[tn2΁ >HRQne<{~ܛWE7mQ³Qkh:Fs%P|HB"=]5ȆO 6V5 *u!6-jt^XNC dYv_#6_@ʒdK3SWmR蟲ƽZL%߱}gVR)x; XOfZBlGE;GOJvޭJSzR-Mij]SxXnԞ:!ʱ) 507!bC2_/lՌ9ɓ'p<0kf"yy~/ZFff]NFz=ǃ!Tdg3;{|lܲbĺ|h߻$d=S^GA19h(nF\{>„a0E@aB LE]:InvAumd*f-prAD&EØ12]aH CB~d? Yd)ﻃIhGn{;tI\7000)ddt])0<0Ddɢt;w{/7xUZ35Y[mA 6Zy껇!G͛*KyrXݞD 4707|=6 t<22_;zuäkՀhgCC?0Oƍ0zkG(ѡ?1#"; ]Y͂v&eΎl]#q+<׿3wXjGQBvRMWT^PHF !jR#iHRRc,ЕGV4s'%=3۬><4[*rT@!Ag3Cd!'ЋDٰ=WDsgaohdd-ޠ=}Lv>+G|C\ G$Ȝo_}+yL'FpC{A],7y鸥e[ (#X_=Ki NE576 "o`љE=8I;6>!4o&u%ޟ=rFS׃FP]|Ym&C(GN\^SOjTDLA) "f}[.E4p9ԯ"=mF!/JD(MG.v:Jي~jD {4 }l6pamк8 R@υ#Fs 3; 4 f1enH_ Bcq@lBCn~1AhLdW81gAmk6ĐdTCh?(o@<&y̚,y2%m3BNcv>N.4G^k:R872=qCX"kAI@_%vEw}U/t*dn~){'R[W<=̀Q*@!)`4G3iyn:[&*r0k!lcA|▭P[\> ^X%4U+$搇\r[BAgT]0X07{f W~V~PCl˱tqTh@9塐~:#Np**QqP|^ʞW J@aَFAȕZzC޻fC:R6²J`䶆R8OG YNΦi]Jt *,(q;()ņ6Ų.4靏FɲJl&icZ+ln+QeGH(U5 i\DkjNWEt,!7/IzV"+m-.~+74c[rp+8 ]nnz+yXOfAO'Z)Ԓ ,@Γ(EfӜŬ(:9Zo6Mb"m$45G$>#n.ds0~@>ߛc&.蓎D1z3w7]'r̓@=;櫵/$4)Y.8t0Xյ!:gLMnz}6 2޽y^jRKd}ox1#.eJ(1z,N\G'3z甩T:BqгESL/򆶵 8@}3˯lLGy\xJbfz~WMzQ;]F!tT2I@k l&x½#jOc:[Jw<6Yw'9%syhKK ܪ _E vMߺlo. +^RHx%#|-Nu^߱~kEY6ޯuRœo-7=8lљ!^Qt:S]|*HTp-Ϣ^4 ܱSR+MHNᲔ1o+`VZpjq'R~J2 A29)"IȿXϞzg iAhuGK|;)6Kz+kda,!JFBRb[-"Ko*^0 `]է`cV#C7тЀ*DSl)܀V O$[cs볝fDV7~ 4]m-CG5c<w%?|OQ`;5d177K\kWԛmH >eWȭZy\_6!]0UUeuj_XחoϯNOίOO.?^]\R4Kn[Wo/uə,2B@(٘&/>^_ej*Wo|)+$Tp{5}eE_L.ѡ`Bӡ+cx5`-\|-څߦ'Z^\|Q:Z3UpϞ&v#}<M8cZH̷Yv Ԏ"< K%jǘ| SYj'%RI*12eŸE:jw̓C,.QKYnB5f-i4_'Ш(=̮鮨 ZM~%ڽŽk'cGdZjbpV1F3Fz.qcT2ޡtw%횄q3DK5ش_=&v9:?6*5Y5n2NIc{FG!oIשL>1ދ%hR&M9< F|+:;Jbf&Y+c,է@ M5c#HTNߙ0XoRbU?*b|G :aKS3c<05{7L#Y{pŬkq% w^oY纴MU$i^#{nq| 7kk0WRiBi&fD&& k9raVngRo˷٨ixXYoF~yR䴉ԩsح> $W.m ;{PZR40hbfv>3 98߇Y#*DRF$Y4_ao0{o1C $ms ^QȈf0e,%L.<42$y"ILa'+BQt$ E9b@R)$I# t0H/f1@!y9M%ӈ;{srsw4"`vzvB=AX?03)31Eհ s~//# ` (0 wXgo|n dWCO.ujm*N$.2c|9J%*766Q:J(dco,Ԝ\eH81(ڄ0v_\)OWtVSBv2O`dxcmWb)Xi6b"תMYTJϪN%Ǒ[_ #MiVin길O^8Y$u'8U-jQNk܀DcZ -Vŗ::yRo \&0T ֫ %W"WX8ѫi}ઔtfN`5<51Nqs1rY~5] ڹpq`B*)vu~,B1M(BԴ9VUGl2nf23vrnGpUf7nr;9NxxC#iǠZRNޮӼvl&zc󪖡mh3M"a?0g%ow+WDʜT*SFj,: +1^me\Y[aC0h.q1S߬|KI&~wCIPEa۽o5hm9 6u5dUIb8=!#>u\`x:j n>~qBQ_drv.c<,k0I =Kx3)2j~*xiBzj.2oދJzBqIQf^zAQjA|JQ^2CCf~WȂꂞM@/(Nl^o8U]XxRQwɪ(X'kx[ôiLzG- v}_vk x^Je{_ TgCx[ôiL]s>]u}o!眉k Fnx[ôiLpQ\ɭXhSzs%cĵ x38c" w_# Fx7>)&k\˖˖ sx[ôiLl5LuP]8ĵ [xP](8Kx[ôiLZ w]p}ݰpAĵ rvx[ôiL|qwWot$PRcLĵK !x[ôiLmGcXy҂6E7\?4emĵ Lx[ôiL&q*_4.cЉk w+x0Ɯ&AJ] *  -x gF.jtäG Yx[ôiLTRif/~Rĵ>x[ôiLnk",xmu8lX`z1 .xp8„,DŁAvqx'Exѩ.yW<=A i)x{:~cF&aR|?:#smCdG& L'C6xke2dN.,s~mqr{exKV ldaps.patchHV>2jKy)5 'g,?HRp.y8@B3巓Ӝ!xx#2,:w>/徿U*Y+r)2xHV>2jKy)zt-xy:w]#|Ru{O.d1 hxb8 AìxzvU|qx;|yBF{-bLIe!ocY(# @Bx;|yBy'X_usģL*X;~,\b#Eu_? #! 2tip1Wr*fr4q|/8H wf7b\(+=& HW2;2/ډ! 8 ~ Bgt)]Gq(=y܌y06apÿjD6se8"W]F;H?_GSԲ1Tj%wJY1EBzJl0?N0yE3^EQׁYIE+i(ś~\oJ`" g x|P H'2yQ2@t"C9!,Aq(%BZFa>|Ͽ '* JpCy0pb&y&x"Z1W:Smb 6ⲠhpELǔWEg oIÜ/S/Xg$(c BITh)Qȱѿ郾 6^`&H!G1>A`: azfZ3 $b`Y 33!3>@X1DvăA C?wO蜊~c@O%>u{zNtx;^_tO:t>t=sA*tSHQ{snwAmq:}q;=6v@;ux&?q}tD$`$}sw{B!p;:d0vL}\O1mNCu}jS~X&= b!!c)tNO 1pp>^OV #ޡn]9Ydj?(洸[eB0&#-0AO3_ 5"zXC3 qH< G-!بj }fAsǧy0M5*UIw{ ^<~,j&&# /!ТRT޾=n{P͚7VBT`ƪ"zXevNJE@|0Ư6gi 9ԼwG8auFrs\S;Hfhᓷfge f2A81|'A5mܳh+[qmkS]-OiEqڼ +U۳skK ћ%5 ,9xqdOa LsYJyq;Q"ˉ34x`log0{n{QSSdžS|Y| 2$|q(AF^h| 6= Ww!ޘV>Kf? 'B`]wDj&8h"D:.rnz\%$c=td' O@rRɊAqr$iY#="Җ/31}%SJ&U4F (L{!KQ$0S/ 7ĕusC9 Y3L ⸳<ٻFI΋ 7dhC8m)OmZg BƜ{x,<_L^d iɞxAxɉ>g#Ui&KAo>dʕDAkDA0vHe+jZl/KvY-(Hv`i ~Z-G?v52 FA_@]z9O8;#08\id)A%SQd9p PrtN ᒼS$4d`|B rƦj+$ljYM APn ̻3 w^&_FsQ Mtm!l"bx%}Ɂ_yJ NU*pjaT!ҹh(K*ڔMu3ς3z8+ Nkd0~8*\"K_^I>vFnoxX%QGRHu 8ʉ5;(B%=D2!Ax4)lz~tA>@rDn#+ HFﮌ2sxבyׂ~ oz^'\/٭-ȻM7b "JΚF(#ZJPkSpHIHyݢί^OQIH * ʧek.ڈ97u1܇Eaɜt /Z9(E WȰˋAyA~l(C>q݃\ޮ/#W22x,cڢЃ6=x>nXS^7@cmCEMMa)̐xFZy{6]EJM1&LeZАx~ĔQZ$h|-if&Kd̝jR2ϒ3:C)&+/(w%) E)uZ:B^%r n7Z&IDp@(8o¨Ѹ/{1%tyU7cV+blzO ߨ 1qÿ}@wr4y/ Ƚ_L"N H0}D7Eub }#n97ӳAE~9^>&,T9x*T)4u; Q;F[ʑŠFIxJ4PlȾ:.:cd»-|'=&Ŕ|ʗIITWNp[JT= X( ҢHjFH h?I  DisL l{ 黰 8L;׾%VIy!0D)/l)ocΩ.M_R4>O\2S~֗h\B ' !Q!Pv_aOq*Sl/SF}8.rd|sL }>e@%L\ߪ޺rG5&F_$c዆8_̀P,[o֢T8͗B۶5r?(j>] JMޓ^x@otTU迤P~G[o bjT2ނ˄14 J"E(v }knS/xEos-q:Т5 c㐴zAuO<0科9shl(xZkotqݰQ\*'Pߔ%YNL# LJi Jr%P AfmP@HB57KԌqOɑNS͢F M2ءjl&רI^ٷxtv0[)j6Ũ@{-`v)iDS!BњxΈ şJ ʀlKA@xWQZ`@1$:<0WjAupwh@ZwlP޹i9 CBݧV%?S|%!{t{9wK1p^s4nKrآ'&{7gZޠW@`l۽8Z断Y?#YJ5T5*ajJ w4KmHIJӵzj O8T)nN5G. 0rG7Q`Q(wl|L3ȶd$VNN9 /pF +|8//EQ ZNJ1&>C5DI4Ml*s9-ڷL0ύ0,f$`QK}CR}ت.[H9qWMAE4u6{cju^6% 2)|PX<v󳒠{*bG0ckU݈~^˘r$:ҬZ |vKƀ3GMM2B01ޛ1Kz''d4wW d2,Y&b,]7q:yw-bZ% cV&fr])zb+iI& ĔR$,)UBە!) &1tmsDti%=,m!c9z/u#$0fU< .Yo"KPSw0Mn$g%BJGuH^S۪@ RmSu,.̌wJ`2T"H֐ȃI )B]J0N/cSvA+}JJXzIq擇T9)jP7o =t##坷F*cj}rTV.Zʠ$%5LEŢ4V!ZNA$3a]é-h] Vv`COˊ Qs?m,){uiطfܱ6MM]X o9g NĀVK,KmI9`Sֲ;|مnf.>=k7B;Vθ₧ _B27ŀIQd:GY :)E((dqyˣK=۸Y"xQ;gT!nP8 kb{[bc*wOoUpFAPLOPY},l+H@.ea"c{;iK{AH!f, 9s*'Hj!{Rsru7+1y1BhyQwVxoƶmh5yW%aSDBy6fU*$?2JʧV{{*u ";vFm|[P!N Ag] Y*%(ARJ"_z Aß=dx۪&֚q`6x!F,mBb & # hxңn[s !1q2ax-019seriesu/13*|~/lƐx;ziğg2)fr=zOx&01qbࡼ@%Ƌӧ`nF\ lx;ȺyğxHqxp"1/7єrL4VG7x#0|hNcJQ4T%?ix#0BL( [oɆ2D׮x;zeE"ږc7fxh}-#?Yi1| 7Kx#0d6͒ʨ2 EءV@xRaseries Jpaxz~k(,"% OdF9#g+"oV wc4Fy#}x:aseries Jpaxz~k(,XoV wc4FNIxbɶTizAx;Aqr2r5gᯚn6p(o=pbJ Ox&bcO=Dv׹pb&]'x*bc77(ΟʊF=x*1c77r{ўUFiUvx-1c6seriesq25^c^dM430 77M&ͳYY}+vעi+*X sfQ40000 odbcZJ49N"& 100644 p1_fsm.erl-uq-eøÓ3mMϮMZ!^US13%Bh t('}ɇ^=40000 stunٕ]O PNHva W̱[3k RXiQvl{?E *_b&i~xq#k|͏Sߧ,/ɘf~ dx6d1- SmՑ]Z#nkJОw{ ,L%[ԵEYQC(3+x21aYŃZ tՓsbvx;xqBw%DS|VXZWx'炉u~Px~jN SfU)־9O{yQhfvr̕K=JItՐ1;+o}xUmK=F_ ~DQ K\:rju>6 ,xUjŠ̗Ҩ/1}~Q6 F:{](HL}۱‘Qh{I| %~m/)2+xRn0 =G_K18% !۰6Xz0LZ$ܦqX"ўѶo[ ,1: N>ԢS:0wT=؀5XCwd?ȧ.\w A.WK4`d^x8>&(mZvHpu|=(A%aru*hgZh|NG$ʼ!* ycMba,!Jp8SrLD7HϡG9'(ˆ@H%Q}8 Zp% JB)$H.).-1jpڍ80ff4u4S^,$<# \0Jz@8|hz$+QW8%re[u0] Y[I]MZKXICYR^k^ZI.GL4̺=QdFh cr`911*:9_QK}z}x_$ҶGaj%2:>jGF4y@S b|d/KxWo8OTӁi[[Tczv'$}m|"݂ƤޢxT-՘QA[F"P!Ss3(GuxU}RQ&&$LWK-@Z7o<>G ]`MȦ۩O" &؟Ȑk0 t aVsGMCq@~IygK)=:[f8 61t^1qZJI` A۔vH+q䠑~,0"8hAhwzdJ;ll< U'Vd-x l dDЍ tg9#{b8IDjY}ZvSwKz{gLg 5` ?ί-x־]-sllYuJAKʫx9ho2^4y6;|iB&-Y2i[ԝXm'KEݽ<,+$*&O3L7wr)z9euznLKt$^8M49i)"cLW^ɏdB6lM%d\O(VМ-n9vHf\ L>:6WpW 64 T.Vc##;0Dq:ul7_)|C=$l&bD  ]ul#xN",U؎Pwrtkk@aJliINfOګ_o59H;ua3ųu:p~]1>ˤVM3tM$pK5n;;KQzGMNcV;jF7Lh/'t(/Zޏ]O~}q<I~ 9OF|?N/kW1Q6f;Z 6.w`EQo\gj kn Zt`yHT6B\/B-x`♪<]OB2nM%cKgu%Jو^x{}^6#sKgn2l^mwxmOH_Oqҍ2rj\$]ck;ӝkϾg پ2=9+nj3IKBSN$mG nNZga?!LA25ְ8 R&AÔ38i$QחgBt|@Ňq,8a=+c0MLTvY!ʷgNK!EX0 1ruk+YmI96W*)&RtX˙*_f2(g,#A7Uk-ؠ!y4 GraTvC֞u)e2Z+L[)Z@{)'h67J^ ^xjRzOS.}اG{S6JB=;|`-x2#8aqB&l/}XK_,UEݙ1y00“d1 =,u :Uhy<,a8m8]TeF‘fqx.Sށ?M0%j! 3XznJ&8o_m2WGNvk_wYN <[^kW'95GQص[Nvi'L-w;ϯvE=_|ӋK^2ǿCxRo0~^SC& R"'4flT眬[8ټ`9`3!*2MEii,Kk&Y}h)vV.Ur/K(ԊUD*B 6ϸ:% F-[jv璹Fv435J[,P8'MC[9yEhhŽo*ڼWq Wx2En?%?/LRg*kijġD+&}('K<Bɵ!Ɩea#2.(=U5"qKΓfO)]RV\QHXyzI ѻI4Al[(K<ؠM%M617D]ƿG!kt/vW/\\d5N%~ey]>敂WW7_~F>me{ #opRavT${"(E@&`@l?[Az]Z:$%L qy>>8y}#$^J{sb&{ Őz,wYYe8҆i7T7Љ3Tro/3}/Wl[R__RV7txmBpbNBIBQjzjEUqiډ u&2*$O^dn0 dF&aFbLeuJmx;4aME-&5x8\z_=j8:őBxvД!%~ElDU"2oxm]`ˢ9C@BߴLxPe-rδ&Ix[ŴitNS;[[azU Ltx[ŴituYW֟~x(2|zZ xbV/Ư d2:[SLx3~hx)v>1xx7;g[JF$]OfSع"g2C6º>6axF(R hs|ΘّBx< AQ0ݑy ;xQʂ_J89]ᑫhx Z!40>B<`@xՒNǕ0>BJ^ӑvmx7vA~aCfg$W[\<l:O8եMm#mKtj+N>Fx ՘D_$p\9rx75qOd힘Ѳ84 OƟBTy5ƺWѓ>TbEx;ti/ Eﴮ|:QhgDs\tpx7iu*6P0XV3ҖOTn}\7;}wj5 >{5x7evfQzA~ TJOKG< qӂ>^ xPEҷB.=8.{ӈ8xMoQ͋?>)БոexV;x羝둫&x;titfy׆y3mY\k\~w  u=x7=}24E/4EZOhL.v.>nkߓ>>FxK#'A$iIAJӬ,xg4=mVA}ZoH.V֊N7;m}`+z7Q]sdJzΑOHZ(Eɭ-^, 0ux7ke_ib~7䲑O^FuDIY3>? ExΓͽݸ7U=3/zqx̯>G`;Pٱ5xؑyxGQpkNC-Z*&{JxuJm^~D'I$wwxohQgX>RP_L~$x;titLskt#iڞd>k Ox+Zަl<|xzK&8=ަ-Ǒh)x]n#UTe=H Vx7cG6Vϵ"OhL.v.>nkߓ>x;tit=lҢJS*M_|\i3qBʠ lGx(wrI׈G ߑץtx(Ae7҆a]Ω !x;titۻqĤU.N7ܔ0qB Lx;titi6IVYK3M d Kwx;tit6^k?*i֧L<]7 "xY_d&i=Oxȅ1/.4W&|x;titI;>=z,^rLn p u'x0X,X7(3Tx;titDy/W˜Ը#ڬXx xC>Zg!f^,xUYAksza7%ߑ[Yx;tit$ugCp>ͮv;?qBq x%eϋq`@͑)1x;tit j6h6*^w K\xOOmx[|iĠiu%icx8nbdxVmk9_1Q n{75dkq8 TޕJz=8CM7:HuR $._=y Lef'|y%euP2˭;ܟ 8_U O9{ E%e藐J3BBfûne-?`ͣC'Bn 8F%`+Ǹ\HPszV_\a5vP|q _{w8>YaaѺ} kLy+QQiҼJC*>G|QwztT`Q "lFD2A󢷢fU`,nMZRkh'5w!75r^XL5k4}Y+eiư7.eMvܭxUjuLŒ\xkhذYDxUjff ̙=n ,x9:+E˜qR6VN|Xo/>Vo@WGx9!Nw ` 1Kr\Ó50֭4;o1HLxyUGxkh`%s+י;ݿ7A~iϐ~[jrx9:C:/:pN@5p>B99˳+Gx8:qoV޵ǂ/mUeN|5i"5͓ xkh`%27J֨K4ҶU[o rx9:MVZ&ܩ||TNB#M(+XkNK`f9xkh`%uCJ^SKCVӏm跅 sxkh`%".DZ HA%eGWm Z xQ:瞷f X_£ N#yyՒD~k<(?a>vn!'`xkh`%ojvѼ;X=_w_Ȭe+6h,>SĭQ"1.Z+Z=-nr}J'+3,KJK ssw2(f%&%%3\dwA-cV:MM]rIC5OmWXi*'c55]E-91?b^vc2Ԅ̼KwL5)t+2HvOfWc cW퇀ɦ"LV%x~r%H~*Ҁ2CC+:o a'xkhpI$ijΈ@w߭^qe"n{&aF/ux8:uWlh[$y%N|q|&F)oӏJG dZm.|S Zh3,HI-B2Y$ ^Ќ\QƼEYEKfa/huɥ(9^l8;;7,dq7h՗ҭj*_r, ln~FK8.?%v?w.5C:B Kxh\ MucBu+!v@ljxe?Ō x= 0 {GELP۠+HVo0xo6ATk3kRzFa#Q`8e)j]}͎M)ݷoТ ! )?x}zTSnD@:H(z"M@)A:"%@( . 5$?z9u&kg=d)c_hߤ`75>"ubt{p %*Q;Z ve}Hd. R↡$,2^{+. 0ko5Xx?G_'`fDNq(T#j~3{{m^t[PIC3,ox܃_E͈^|U^4:p600h]Y#GJK B0#*\GA H -3*FWkIk*݋Q#/ʄ$C= {ʼըx(YwY CSsؑc3Rj /_9}J[9Yk{WWCtX}Z1wӄel$]Ta/~HZʦ? ;ZXpzy"lEV&g~XUk+< Yj5$4*|ZVu8 roE9]Ud[YWv4ba< ^^˙t}vUYY-LHv! bs:sif^[Qˉ oVY_͟-e:aőp4Kyohh ;uϴI)tl)[{/=á/PDH0}a{6+"p^,Oϴ~.qH J][a/}F1wMe rOGF\:ۚϿ.-[,/GJ=ǣIA>uEG#)]&_z_6,tİգ>1MRuEgy):[FЗ)9šu/d׈BBr:YKߩ=情ã5myXNj~O%."tjϽ$rɌwdyQIC%˝RV+X.<06TTX| -Ǵ靋]-lPYiCGڷYgE҂21bdoz{,RGR5QrO҄CRD "#1ZOp; `&п8*8'o!o>Nv*-;a46&ߩ: V0uc~hJwLtIra@E(zJ[C 7ɑ֮6zǓܑg16aw_'ɜlֳ)i|zҺ,/Rw!ycc֩$:zq8VF8"bbh'nmvg'xt,**Q~]*J+jJ#3뚙훻% Ühҫߚ2[-3K59NbdAݹf͹ciK<{[Ѧ"9ѹJ#n* mq*WK.q='d>viwHfѰ/rO!NkƕLCb$%ļ%)*l. 受tGʃ /ՙG ^Kb '52,h(!*bVjS*r$f{2IxoJ= >fV#L4Vb\J.o=HyxWydHwDMX?0聊tPxOy\r[S,)[FCԤ㴰at4/zꐜo}1'Il,fH3[ XS٫Tב 3~>vO 5tC #X- !D l7\WeW͞JpP')!Zm29djŴ㫯!Zl8cug2nC< bNՃ=0^Gbu_5ZwjI򖫪 ?2^!z&[ϴ\B"_p|6²/(0y*$K[펗1dv")i\=DE؜㚳7ap&q 1PkCoMJg7] \J@[>A{<"|D*@pkRuz5Pe/] Yɚ\l۳z#,&)h_!5f }_$)M)QmAdMbWXh\~PSܳgU0Δ"ü ȡh(@P =3;X'XpL$ aV&i$?%܊r #48 "hZge6Tr.cli$G!q‚gn(ܙKte26 a7\VÃ˩;|ʞ\#϶եz. ?>gٮQY כohHʌF JxE;ifD0r\ /biG'Of~QWd's2t\Bq1 ~^rvꊅ)『*"a>N?o@|ycsDr%:c^OT}DŽ>\*MmQ{j;_W;|BǑ9NCS{ ب `wj:~E mCn?O!Ztlv}m-18ԨX:W b|l)֊zZ@vc o1h5 ^3KI򀚅m[_IHx@OML\)Zwڠ8pC!^vȧ(>)1`ѢPMV1u8n6]0$V)QSПkn )Vҭt#/!vvBFoz+QIwsYxu0#L^МMW6͈V&8wV:lVms5BǀbV+dһkS Cu`\;noT0]'qfI)na}YVUIo\4< .Oȃx- >p^!v0Ȗ2N^) a*ie6 G(\@%aCT`i] /)fU3[-p~w=+O 7?dG:HjڻJFqB|[q[bU =?tA3=wAVlFzev]^D g3@ @?\}( w;P`N٫!#ָh$Clj }f. ǁl lJ'` gr׍]̳3.ȓO' ~c H8K6:1d]k,!g?-'|AV} FNMquZb1!KHVwp07ܕBFqfFӹj!`w-uQ ȧ"*3MiGxDrErJ!O,uRœ+ Kጣ`kcmPj6%-1#xi 8j 6H͆P /ΝW6A7=48-Eך@-$-~̓jI 2PC|:*a.DC$:|tq&vaBÜQ؋L8T^JM8Jpl~"$4TK'̀Mjf"^љ 4PT[؁$ͅ/V4JTd 1 '>5kKc `ӷ+(LWw09S(L֐5UM{>䵉(LwXxݖ;j #>|#ff)!HNVa݋É5'w :{{(cHpSWf#_qy;SYa=ǃ@W)^?ٻRIBzIN%fxKHzlj% : $kJ)݇ejM6 S< u8g&o֊H;aw%It?R3jQՀ%~ e ;?I|wCAjz%)y56o Q}Tsc tS9T"pMs%<-(ޫȌU9)GL-&"UiO2QD<(Jӓ| \:(!_*N+K0ɸNlqf ^֏Ƙwҿ}Xa?lo1֬U:Ğ2ū;971߉xXE(^o`;gTհ\.<ǐ_^4; g}حcaY1~ Vղل:[@J/='N޼'\8o~~g#d%\;?Juer)-6q~$$лz3Ҷ1K5=w1J9~Rqnۇ?%+C}\qŊ?m+p>2$f!VWV*oW=2jwEڲs5:n=hoB l y8aD'w,sj^*1`xD$T7㽩?ˎf ct`tIp`U*ġPr.q.dEM'm@T,Dzvܖ&YK eNTNgV9[Np>%֞J~uR%d5혽fם̯zy/f_.LՒS=4vg#[NASt.#zk*ZauehF! [rAށqp:`JdyMkC .!w8phq~%+6;0F#7q0,B㘾lϼi\)-65*D[eIhq~_A6RSLRu-)P^oh'ȭ*E0Q%t2 x<*3gg_d5 w.6&pc۬|ͮFsX2}í!p@?\IH=u z8Reɢm] ~݌])e]@}oAP\e˙L?yz)F}waxTO-&a㴻(@ոe_!# =S'),@.A"ρR€YS{ʉC, HO͏z=;2lζYJ't-=j l7;g݌x1w!V@ujԬtXv@m2ID%y]4")/ δG>$R "mؗv'^Se0{ڂo7T;+Mi5mvj+򘳫؞T}#†>r ?j+75S"ڶݫHOLꊀ6˱x Q漢.[QW_\2hU 4UaJ\.@9xd\}Nӑ-h4/ӝF'=-Q" W@F1٩OM1(5g㵎1Ix4c5+fBOl:d̯*tWPE"flc=_"}~o B*ו[+^PZ]7ynn&ʄMO$ 1BmF 8l"%B\~{# *z}H)gw4α9ill4yyf ~_?v E;ZZ7 ӞewCWZnq1}~09=aV4΍st?e ػpr0Y]=؃PPje`p_.Z9hwI Bƙߡ7R Ֆ$[kq,c S蟗YλC~τ#pWg»2-JZOî$F,Ev@Y}CLj+6=U 4TTXE)j0xxSUpIMKUHJLJJ-JQ(K-*SH-JK-OMKJVrhBx`lT hx`lX i$x`bgP Qx8a?*Ֆ]TުCQt((j&FҖRբQ[)jƪ[ $'s]'H7w^zlv{ 'rJqoiχ>ao0w_d3 ls3xQ uZGWItfk-_Ck_)%oK&6"mrXE;h6T̋5kH*;U:9jVͤI_}3*%yz͜}w!S)Ӭ V_U/Ru;uدiYKnWpV.ױ̖O(#S;51ov_xS+I_;;??0M3ժe#3p9rS+uz>x~F7y>#O+9TQ4\xA(߭. n =nNj.(@ŤtHp2DK1Ky̘,A-gLkf6ٸ܆dRt޹SJ%Pz8NZ6(^ %]I9hPdF{1[r(.ڨyM[bo}O>o5eXeҹKtTwL<]am4|ߵ[E*]DIQtFT`5!s (qN8@c%$O]^.Cs ;ON6 {iAٸonʎȽ$˭~Ϥ;{ suNv|4%'>\,&!V*0?J`: םc8"d6Lz<>!Z 되r N]!-@zf<[yx ׶tbW~HUD&IwٝΠQ]' 5Ki #bsM RI%ivRT1jb*l4NJt1='wxޡ.%_0@)o,v4(GiVLV/nj]f%wt1 9w̮q*\v10 dR"\S}nNUkMNх[ @(4t`^*O(MZb SU:>9?x >a8*f#z$k~lըd)-4<-~;uYVBW@lzʇV8D"Z^5VpshZ(9wIiZ9w84T.G{HƐ1"hLbhA%LZf@VG/@=Kf\Je"sMҽtĤ$2jA]F`0oK5ʴ<)Xu_bo)?l_.Fm(pM3$la(c;$FZhxxԴ'VjQgXY_As݇\9n,[f}^2w49CW⍌LVZW@<.4"x}7̦D< "L3K`2,mihl9,>cJD>i6+hӹ@f6a{jG|sGUӕ؜(6]mmCٽ;[uV|Y~zHu)meFmݹ=r;GgD>Af|||GFrt-3xKlgqPtHNAkQSw4!ӵؕDPq'DtSު0N[&:~-gh(`1aWc 1=0]g54Ȓ@l"EAɆ`bL?DݾR('V%\c<dU~l/^$s[i:=f1gg4> w/M}|XHkd6|qA!dXRh:ސ> ^:lJk&XC'_xz!ShoK x<?ף/(k1\fۺ*Xv'T~Fp{N`螢辮9 ~i yN/f-r˭Lׂ9JP.??6(2r7s/D٦乐뤠\9֜Iǩ AЃN0GGGM Ĩ:pcmaa P zĔz} H5:b92㓉t]i q+wUMFҜ2aC+ӧcl?^g,_R3Z^5M7x>h<(p)<?7Vb1PR"6,^oa8&]|?#mMNgiffU$T]~U߽)Z$wiɪ$gޜ)r#o֨\4KidkԖ^sSs,&'3vv4c-64]EOFFj_FSՒ{RQHqg \ja2m 5/tm K(8ώ74'&T.8>kb?6nX'4_/8DOzߵIX{y,0GiL= L"ly\::QQ8YX?T%3PW'[z :yQi)ggkc[ul3*@. E`ᖮ n-~hsgX'ogYsEN_M2:ܩV! &5>e<t`yEQL^BP2_XͷߌWB2AzB7C2_lۚU:^!vCOހy1u(y@J~ZfcjpW.ɅWlRVRVM)˦Ih6GqjD= pzǽӼbiG>}:)[$GcCm{&i޽kY\`nNoM#+nu]Ԃ5cؖmZ*! q#9vݧA_A_ʆ?44LZn(ԤMד|b3u+xՖbRBνSǵYӍk4^?F罈9cggg}w[zSs:Vќ!XAichT[m_v7<$&^L|?!7KiaB.*1Cz(#Xr#cTPfdrŀOpX9qyRaQDm!ɿ2諾4_;^Zq?sGg۷oA6?w=aSd%תX,6`seu[<#a?}l&!M# cBc'R[A+xdCd7^ -P3:X GLӉ`)z򘩥@P꧛K>UK{37 HW!VG8Ev/d:dNOH?Κl.R2秥ҳ0cVeN֔t T#-1^:vh!킿UshQqMx*qTw@ Txv_b/ ٶ7.e+Ƈ@%6 v4eTxXi)O"m*+mPLHv ((E]zaN!Ѣ02Cɥ孝BU@)EݨҙPp.5͕.ȗK^dl[u DW&gS4fJZe(x@M0U= sVJɆͼb=j˹6;>}Hy!:H/,g֏oZ] :cN?~ q$^D4LVX,5w0&}z vH*@QofbP#sr- L脝C,!!)9'iDk\Bs bX o'[y|FB1]5 ;):kjgZ*g`gF*!i^9**sYu gTSS@*[KY sP?.i:,~1kxoG7\/ ]޿tLMLMH{uJ-ef*- q;ݸH(q =AL]k3XRI|)zMl7M٬K4"֧]':#Wwᦥ ^q;r m諟`5hLkobIOlFJ:%:XO)<3lq܇Owz=*w_Z&넇˿ o?a_NoL^06VL\Y3u8fu "g{ 0A/v(=`@\1\JI+A2+n^$Dvv쥦.2?9-N?8=.he>K!WǿB53K!eFsKt{Sz)6?_Wu54&bвQ).ᚥΐJʝi KW?TXZ&w{^(3IH?+U\a3Mok,_ 沪:q uN# N{w+_';?/vNyX5 2m\yyC%eRgI ƒDGpX"RN?z*R!1Mѣ# vΣ#zkM9>9t\%s`Ki|`EL8߸~131SBTVbp:9lpoYN椙!.M Sǔp `%P~7| }ѿ]Lz_+ȃ.?~|. :"WK&"'03ì1;8OO ZN.'s @a\L,YsdK?;oGc:q|'+Rs\۔1*0q!ZM>B^]ϡ6Bde mέbMmA {#J &G2{B7;{tbg:E~P5u44/{ܪ7bkpoUj7 Fs̟)2(Ug Q˓T-Yc".<OgY*Rܥdv@l]Ҫ2$:r4קOҺSxVtQv,e!h}VlJhh/ΤehjިaUk;̥Xh%T0caYoU}寧=So,]*R te|>TRO[g$Y۝`1@h8+15M_c8ܵ?%cvcM#*eѯ*<6/ >3M4+4$u\,x >wqL}3/u;Ld Q5|;%))C'}~sG~w}h[?_>%K[HTtm؈jGڵA*.偫fKơ7[X ,*T lt&8n*gp~ b>:یH"1̓8UeGc_w@]]cc阍T$ѹXġRƊ*KQFRc٭ל\RŊKi>Rm 7S+ÿj=?῜?u֬< >cٗM`Țڝ˶/yEob PC61DK̆ĉ_ӍȅR %8"{^9go_<L|_{׌=D >fڜCH|uP\F}}۶-0{J򷃕>nf@@6#Fǁ6:jZ;r29s@_0(t7& wx2Ͻva&xs gvO]8du,S2~JP7WX?8l6_=Fݩ} $PGjo,DIsuԗ1dב[tq2PxFf[!g@磯tRfKVWea1ȍh?mo~bbf| S_8@ rJy~,8[?G5slF4Ɔ=T{pP)u&#⫧}>aaQB>ڊ-J8Oqߑ}MMW{n=bk4 HPGUg02st}]Z,g*Yf.;YDᦁh*RSmT<ţܶ״ݎ,kfgr:^LRfg-؜wqA0&o2+B)/zG U<^:tZr~]8xƧzjI֯. +%'Nc7RB Z59L([mu;=)9S~RV&20`CJz0?'3dk#M Rn,~[[19]pP݉蟳;V>/KeJR^f<9֡Ip0##H#oX ੅OhYU ۾yܾ,ZGS?3b;#pV[_ɸs[Jk d%4u4fnpX k`Mww?u\z]9wxbN;=pK㋐DLi"r8XMHZNen|^$R`*Z.\jKİ7oz4V^ψqmE' /m \8v1Z`(/#GyLXߟGzwDFO*pYMCu>Awab~I/sON-cv%>&w¡,Qv\5]H9u*|T<3uVMYߊO?h:JlݵV1~ Ƒ%* Wfr#Os1iʿƱ*ӛKc ~b>5{7#L㎍ p>Aco[q}uX4T9_NdjTqjsߕrƭ)N]&հ78☆shz%|W0ERF+:a;Ng3~/#( 7_{Uq7|XOY^vWFT|o')-a63!S*uTXv"B /M k{د2w4kowq.P$-AVRX,وr7*t!CDA3\. WK/=b=>}K Z/Bge,& ̏D3tz3^\:Ԙ9F~-;q!•_농/ )9$i$ϝPQ%QPV[@5?4 AyVNOKeI~ű7kFuN6z/r 4|[X"=`kx:.pwgNun[.еkXy;-=ebr]kj'Jrp՛&G*)9Ҫrʱp[+W/"ON1< VOqsrR5ώ*~\Tv@-G9|g`'/S='uN^|E&ܜtʢW`oW `n"ZZ2Vea8Mfe'UKN0X{'̟Mt43㉬FΜq04PKnՍ 9IȓL>>$9^[bZ% Uѽn %tEI^|&%&6ս\HݚC:|[腊(IDx1fdzU h*/!LbW250x@s:G=u?f~]Rpp"87200= &#chk~`<0:JvD9YN`6-!F@gQ`aH AFfߞ8yp8kc1CGݧ (0ޣ&N7 iv;U{v.Vw͹b=cfPQWx*tyg8U\nxhKmwu0%G{KCkpLw?^XhI =)6ty%$TL\ }ĜZ2^'Odutu#XFLE"AUEEFo{rme@*"Pf5'#TH;SxC\/ڸnYN:>rq'E ?]RH!,f0 0i wFy%'V$JQӈӊVKX0O <@E~R`J&!>ed.\̭UX&B`UáK;y?AL8~=gdfY񵸌9G ?撚՗ȏ1(k3ErOx0[ I^!<(yv秅JfzX!yEOpZV$=GĈC*ESQ_ީRNd[-}QSiFg}vP$ +7f9m|ȥN\=;,G ɸD Z/Ϳc؎'=y-s~{ !'8z|Rx{XS]nJRHG@"]h@5@b T^CDB"5 ! {y~=k֬wډo)p@8` ̠ W ӡpd A|'qWw(5y#{ |ԗf*10R.ou >m )HN DNDBg9G>C*&#oh'zvFھp/ĿfC#+Cy ~m/-;$7 hD2#4ܛڼ@xGL@0u>*αɨ O!ƫt=.򗗝T;/'vʲ@4i`)!~l2:% d%b[fe'|ƹ0R+$&KaF}Y5㦊hګs=1`Y)rER _Tr:vuptE'Ф|ɳ,pȇniܷVGaY%u?6MdRwZX]S}ӛSYМ 9b+x/9׌1Yc)Y3ALSJ n8"TT@mUm-G 6YV`[A&>˓Xx;z5jM䴞LS-\>7`' ӢcO?n~޼Vgq ӋMר17{ .:g:~7|. x82sw4nMCEZFs2E6eRiP\є[yhOsԆ࿔qpf6M),ʒQȠr %Ӓ&!U3q1DgHӎ'óȘ m}Y.v.9H'3cI ͭ  K{D,O0p:EMGR!7|0)gh{|b"!X&?UOqI|pUi 1阡e"+gʙ2x23i$BDD)deq mXZ93E}uŏ\u('"ɍ5,b&k"ri Ljǥ1j/* lZɑ\73-F>B_N{|"6_luuĞkGHm<.Y~#ٸF heg 6 ,'o:1ݐy$pL炩^T)`:lrF2A%BIɼK1z#w0<, "o1?){,-R />``م&jn :"o~UWW}6+k@,%9Y0e;(v v˶G.892 ‡߱I mJ]2HyWuM;W\RrN;l_Y^.gȦ78pzhbw_DNO֪K--/83nk"KsizR?1jwtlhtWV~:D)Uݕ$oC M2G;K4Ҫo6d:@5s&«[ZE&|̰X-٬ ~fje~>>; ⲲA?)?$Ғ :lpkD*A!~PCAU(P` Fo]5Rt~A*0m}VgemZccT߭"y}g貯}6!f;te W =I<~,;\ȧ8Fp H50y;[ٕKi68DAp^bV퍑6LU# ")"pSPťXnv$@!{5 T}k?f{jCIIoSKJ9(8et1<&,cdl tlrX*W_Q[ 뢨NT "vk* ͻq/h~s,f+ k6'\iR*=b ҄M]uwZF@gk70L}ŵrQ4OO7n i@Tp9?wWW'qx4Tee<CMIo~sftI^=)pܦDxHw6~&&4f檏4:&҃Rf >w5riӹub(e|=srM4 q-Sfݥj[t`ө/zV=v`9hc:a;aFlيO=^22v|]L?ݲ3l>J 8љx` _]PD¤JPP+YcZPm&c/[-G#apFܛ)>69*Rń. ] Ylo*j4{,8ySN}t^SGL+zc"( ۷[2z!Dc+?4?șpN}viBS@*Yqaf U|(,иcc ]9I xaJ:?TKNzh>RI**,X }lS]Sg~?.yN~ W^Z\޶ErU{S`a\4߿?B20::=5AeyODLWnJmH(yʽ/g`uV[{d}9SP پiYTzSw^xq(uT)lpjp ><սu(#z QpʼFxJw_*9eNKRV[v0PLWeLֱwܖCMyY"R7uko'9l؆W5 Q60&#ԗ@Uζ\SvVDksE۔a5-%wv<3#S>-5Ġ6䦭K`Җ/ׂrn*Y0]gre0FrHDÇɺjX=p]5<䵳P ױ`lǫ6*pėjE/<-#?5z߆}9ҤP'؆/&+3d7@;ڨnG[6O4  /2ԙG,JJk+<̇xcNCժof`1{W.:#HrٓQ2u7 5B'̈́!x=[ QOKY<`ľ|ZPeK'+c%Tb8O&PX!D P/fQzO,yJw=nMj[P=׌&?QCj5zOxo? $Ƽ|YF_ΕޗzC-x}nc VSF6Y?l3I _!}H-=dK?Immmt`\d"`:.ejbjh*u#)$@svd]VXm8Upf/#h]ZZb~ ixy,]6ҳ+!=: .](O"=hd Ճj3L/t~ĪT~P`:8ec#%W%fh2FYiL?R~wyafs+{< ZCp(&rO#ݝ(pIR[M 'dnpW%2)bQڟrk> jppmPpHٺ7\P$N̷=dZ[[3As,OT\p+?.Y=g%8s< ^dݣH.N!|fd{[r yg*`:zWeGȅrMѧ9@㷘 @R7862X]I;ЬJܝ-[Ll]GƏ'@FDf0m^޲Dv|+WRZZ4;cavuZWxb ,LLC(9m.^5*OEb.(2^k-A0)^: cV @#I`Bn+UA5dt5p_jB|lA;#v<.{& rhLj䨃a{ɉo}4J-r2!a t塎U)zYwȒ9y&!T}5#mppsw?vEDcRRRTj RIɒ^>R۷H//b*$"O~IC׶'.{`J]Hir^?] Bmf#k/) *[6!]a܆'L4܂mFN}~ ~W;tFu',u/nf-LmfIw:D *̾~)sdUiG%8)U B`|/E.4Ծx0o+Qͦ%=J[6;dǯ,[2;<3`mZ >tr8bї*+h{>l偬NcUx=C:㍌JFfl(Sp^?;5f]5aah2*fd],Sur&brnẼfΖo|2ypGad[^+=ՁJOVJOWC*31Tu1O@ R<Gam/Ŝ3cq%%ֈJ~ea)1wqaFC۝F6vu G+^?!}9mb5c4rLPWD!l-?#\=zUi$E,z;Bh8ͮK"qPJh>KAE@U,{0 ˙) Fd)mןMBR`|n^&]EgB2xޥE7c׽Bph &$맧 2\=[[k]qI&Q|Vp3oEzܝl0`Vyz)ajwM@X7SZ;%lĤFS67#CTf蘞Kzs> mv&˸ צiw'32}N}GGt1fBj Y#/\c+tDM' o}p& T}nE:T~ 0)1ƬCQ/iPt/v?sx=y[=G<|@9ܦÖ^3g cJ Y fOߩiz 8+: Q\4졪AD;oH@ggFbX$!!J HG>=VǰteJ'.ôyhєoq}RPT^ʱwCxS/-j;icǣm0a`t!Xȼ2lFT3| @(tP 3Zg|bN %|ܟBXQ|@JRZJ*\')aAQ\-tmkkkeeddԦ *GQlԎT )aӰuWazrZbUKkȳfX5esr:7U3]{C.tx>ws[ '= t17LIo^@jQIeX"YXtFo9d7$ lKHƴ9zV0O;t/Ģiٮ (9! ݘЙIqy#}Q)ܧ:TL5=ù8Mjf@~3:m FD3tpK&2''xcT 8\t|X @Ωd(SUZn0a37IWM{{Nusld0emYm z{TO1+ObWMžb +*kC]>˳f0|MUR lq):OL@@@T)Hwwg<4|cK:9E羷hY.&\C8+֦>[wn΄7^gmNuʊSf]0=[|q\cj,x J7"`ecvp5:"NޱВu}T}I!7ʼn.I[a(ޚO8LINg[|,DFY;%+$PO2"2h!T}sG.=Cujqhx!#A?:"Ie>G3b^/leH0%36ࠋAeJW,LQ|[q77}?l +SpJYĆi_yOǚt̵Հ1Kz=WŝATCFNBE\e\8`b!Kwy>pcOHt)~UYSXѨQ>8hd-haΡ=xU ? D{wG}_ߴ 1C}Of s1mwYƃ-?R&L 0w 'FPrMDPQ,1Iss>q8 8d0b9w:{SDgE'">i)jZDu.8.?e<f[@l8ݯ g7@g"DAwC\63 >̒_s*gb9}+6ķs-%M:υ>OoJ-/=ZhYкo3pGdޥf -AQ@ ȴ]jq߬]U Ԛ:(-`Q"k]%/rj@X l5^5cnr72tޤ/q)wqP~#bʄ)0_ۿm7ֈg-es?:8 RYQ8jΆ:q|QGJɬ"(&V< .&` @?HYl yQ EbԲy^ZCgWʲrOeܢVMf_Z;uE bV723? d6{M;&BT؏uώĮfE6tA,ORdwF:)hĆbr| P:ۏ ?]ń{* lDz m#x˞d6R%D Qg,= K2KYDtYv:o>߿HA_1bCZ` CPQN6 b|O_ep_ QLԂÆRO\4` @L޼8aĸ:I,qoL : (qOyێyPku E|/>qc c-^#rVw[S1bhNV&BX\n],44B)}I#2v4: $\eO59*^+9X4VUlJ GglcGt1'zRx('ف'C?e+D:4T+1[qm\݉UCcJӟDvO@q`)wQu7ORk eJ=`ΨzJ 9 nT&|-j΃qU{c^vd6+05UYtDn:48sCʺ zi&[0`H{%sƜ*3dϲQ$ Q͵.(FHik$3Tu(žK .( };bL3 }uMYڃ1u %l7eFpas)D"AI}SѠ!j텕7z6j=ޏ)tVn8g~{OT[/μQDD?r,~laAv)Yb,<;86IԚaa>4fcs'In[V3 @饨U@k>;BVW־!Jͫ6T@ !(7K/ aۙj<y?p\.ͩz&"N}U2ߡ!K:#[+}Ryu2{gOHknq}p(gӞr$[rv2~tF:$k$Dg$ J~Hvi-Z73]^?hZ e[ ^"ۓq$PyC\!*]iFONh[N.`P/;QG:[I[z^u꺻?$*b_GM??eZKf!7%>eD3r.`yCfoϠ3V aOKla%#wˤF"7@xtO2WSm5E Iα;HT%YvE 5pˣ69~#"@y~>|6joqW65 |#\?ؽꔓ+;t{UDKo j( h=<(Eʊĉ.IH|B: Nr:5Zb跧(;)q$`D#I0y(%k ?Y%)?0bsxC0\uPlVn%Na۲佾 3]ّo JFv[ #S{4DHg{q6 c34̉EkQսx`A1h-ߨ?M4MA)# V ԝG8ĩ!.r9vCO1cҌgpIb\B>^ hjefiN_iaNuynO sPe͢s/$(0 lXjDټ?*Xu;4k@PԺqD߳ษ1趻y5lA@#4, ZBLl-591@asv^'E xoE c ٷN?:-ou4Lo/'^`9"RjiE5*3`U""v aVsuwOx(? MbM_Ks%ğ?DsA/r{`㷿5$Թ6R;byn`f;rx;)NƛD[K>,ûTFJ}^c蔧O>h[7;Z3K$ky\?1T*{9% K+plW\ZnR$}(b-c >\alHŘ>NC.?=>$Jiц;5`IT')n(s HHqŰ֬Us+SV,9C`;~?͒\ED;,ڝ8V-*[I%Hp%EDr+$%_D&纼P pRQxmw w6Xll>l-ёjsR㥲`|mxi(V ϑ.=f's$"UWA"h,ocdNQ {ʌp}wtc(-<1hX6lݰkkT{P&ɍs(j^>0Wh"E&W]a <{weu7+B̹?M&!jL`KԜ*f&:'( ˋw[i8 FaCPOLHmt^v7~ iCR=A`wU sG*eO$sr$TlA'_Oհerђ lǮ V_9\806ou+9H;+\=!,Qp~M7{tLvWͩĵ%$siEC]V.A~?HKȗz;Ki>:*x=_^Un:`eFNjNr~L92zʌwT=yVDӘawe3u7!s\ٝX 8'WrTV+"M;pwV̅W.K|59YV4].]`x> ayҮ6r_``b|+{@< #xVg)X'[WX@w޼x~0vj,׉I ΕcS;q{dA#/7d!A#pU% vWV@RXE^>:}ߎsg\˯c_n_$IEswCF7JY_}m2=Z 7/x/u,U>ncQ 边-NE酦3BϢ;1*}@tCk,r~=fUȈ±nXbb„gLhvLJԨ"7 ]gǝҙe+#έOY5OA$K<40UzLTWus.b<ash,b N6+8P&i6VM&轘Z9"e4cYHYsg `JGYšmF3+>U5;4-oKD2sW0Ș )} eSZ6Ie> ~]8u"&&OiLͯtp/o]>E}YܮL.)*avZޗ;CKD.9LG·Eعչ;Ho<:)?E?9w`mtts,AH[^_nX}st0V=:2EkyhIJzqHol]07 0Fאk7LO,澪Y n =@=CpKh \q0"2BXۧ$eWO9wly#hL%ZЃBlU=@T} g*RVCLpx|f(0y/gj#;3ٱ0Za'tЯbE఻{ne3>0IR>8-p)<ۘ앗)btD@lWz/i R@.>wRU poe*:1 jɯ?SYFM-F ~@M}KD7~*E<_ڟI|=Uzr=xMjVO;EVwwF-&|uz  롁H.99]l\blddL&b-ZOщ#/7j ğ(ZQ-3@ECZ0p_RpOu0r\ (aBzUVytTh9 Գg篗DmP2I j E qV" fiqziyH0i8oN ;gǸKgB|2X.{h27T( & f򚚢Qu`5Mջ+[Bbݧ # bd3q(G;ze΍HcFo墨 ; 5.;|JPs)jw'hpL9zc6C"Az89UT*O*`Oz k8uO:}q5dX93tzșjgG*Y`j7J&"xK'&T 1?a)釜 _?_8,NA(uTT}v(YS#m9 :&S.eQt>lc?u=`` -zC%k1Ecm?s ?#MiLO2Sx(ԡAbQh46&D䍈/H#jGav g?f|@pZD )'Eh9w蔨ASi+r[wi$Ēӛ*\(V7u_w!d;YWt$E8ձ3kY"=<8DT7p\h xkdļQ#4xR]o0}&⾕(q)k30n4ENr$Cǿ=>L}-|u>4EC7mYPJ!D}xl \J_ޢJUurJ*zQ}XKQ%Jh}!ļ3lhk3$u,-p-/PXpG>_.!!I%q*J&d72 ڙU<{Yvx[!92AL8'p+|i4mv:G*sBΤ!-eHtнzau axϩzQhjNh@<V‡=nlTJǂQv4'ű dh'_i0b0g-脎W1MWt9]'QVڼYɶqlrqf\x;uCTVt KG[[[!5+1))($ࠠkjjc &'1=PiAx{Ǻy7bF ="xj0EW d@Jۦ@CKAƑ7)!^٢B観Hkɚ mMaW)Q90F %d Q]]]]Wb:u<䐽t럱h6ajNwΦN<v|3i/߹_l~󔇞om*OO%x7bPC/n|N^ZT9 u-gt[YC|3n~X;F[ѹ30I|_XR ʎbݱ#wnA˝B@&6Xld]SM\+5JV~#xN;sg8Qdyfo΃(~CÔŪ$2I6u2GXCWd+@޹cF2Mf6;OŽL>}qQe냣z+5dۧܙ/m AŚE GP226Iz8P_AReG6.;ֈi3ϫt?lѿȴ3Xn[c=nܻwy'boݐ=V@?*b!*DY8 "55__܉w; t^H<;%F9 F3זV߆\U*BrJ}>.C)?w,qG`P+$`ŷZ4@E \ߍ[z#ۀv̤]J#n!Yǁ 80#di_C04 PޫBb's6TIPksLO ؇߽; X]`= )= ` y`41fidbڈ CdC>_@: Ći8^:9Zl 6Q )!s<NDy49 yr=h`÷&R"7GՅ9d/_VW'zV}8_Gzp}L&m vTAբu1C,;lU[yj&L-H`eCէ !Ū4؍@Uޖ;k:Q?KhoK:dP-,έֳ ~c BR j%ѹӃk#;6Z}r#6g-V'GtecփV\P g0ѲㆊF\=HL|a0{YIJ `?Py"=~UB}7ưLhsD4gqX|Vu-TQb_ 0("1'K2Z͉9%$_ mcchIKD5{ ~&daɣЩR0I@OU6b_) mŢ75.U`PSiA`c/n$%%s6Tĩ3={X!:d Zpfq1HRM/9-5%i*}aPzQ2ʠ骋 '01 )F74@BF %,{h TjXNՒ},0DW{ Yåye{gA@nD﷒XS#'D#>x7i iL &Vh<5U]i [PO00Rg&%3t! 0\f/(Sb PS0CRWcÚ abܧ%U=wp4a^$S&&$P9E 4HDLDZ9Lh,[6%}]詖;$Ց"(o"MDq5 Rd"KUa F|ѴX(U GA#Euܯ~Zr*C#qm\r."[VUF8n+6]D:-B\Dz:}xw*!tbL)z \*i>G)UfPҷBtVP!v)ttpwK+)߉0$j P_`zj lraVDkI~ZWCURSDK`X]j$Ek c"FRCnS 9Exit@u\(qkeWR5?deKtsc(-HK(E}a.lobMjH:]؛j-i"HXc\!rhL[`[O=]O=xXvJ ̓5n8zsV•*zVq(#7/IӴ,C>ئ]25n o|qҢ'x$^*&]'A̛BHh 1tDar0#YXg^Q'* .W O1Jqĝ{p%qpQ}p&\~m RV؉;x)[=ɍOԅ<q' EN$R7ǿԪ]WsY89 Ķzv||Qn@ˍzY}؍ \0m{{[ba0:zÚhG gUst2ǽ IWcp!WyMŲUj]; pϯb[ v?WpyY\/YX/ k'N aH{% rLFh;}߀3Ŀ5!ćL2f%'G92IT)ycc\yOA">Cj1LQLal#_%@壤dZΨ5'&}H_4@?#iJ@dȋ$EDT/@3Q!^9 3_<NsWq;2w \u n<=27c獉`xR#"68?Ks ͕6j{ђ` 'BߥXspd1g_ϕ;zyZ@TrDeu6Ƌ/ U=oQ=hsDG, Ь"N6ddƢ5,ghZ9Y/ LG5SFqt{Ou8HH\߬)*};)a,Lqh">,e 9y3+a-3H1"VtNiNJqYfw!b ;p )WlUMH.m^O^z?P0t: ,η?lQ-zٳ2@CWʯ*'9 P%ޒH=41 L{{72|k*$/CPG3}'m2ܼ| ]*,˼r)V y{?lqb?{Paxh Rn5抾l2u=J8U7XHdQhYE8)+AEKn'@^;J#*O!ZQ[2P^deiPGD~'eL |NL={Uism jvobǑ yޕAA qj(^a 7KA,9rE45cj8 ,hUЄh$)ZNޑC{ ȳepDFRk2"XTأτm4K&O|9GAlO%ٲdh-}CM "Xw0!sY@r{r}$ԍ)ϡRf< N%r TQHeb9!;N+ge~.H7 W'9$]+q9Z[-`,ڇ)۶TRS3/ |D+U͕z1poֳ*mCWrڻـUVIdŘz`4 #@192*8*R7EjC5G=R3k²czUxkPxn<*Hn7?`|۱ډSTθNEOL#:=gM $}qݭf60BC/iKW<)mM^ţoLLEVbO c#qi[4$̽DS0qHP ݕPaDVJa.ׂ]QL+IȦ{GFrN`Mhi $b,A[7Ü.sZ(>7X.,BiȒ.9dܳq e9`ZtƊ 縍X$=rc iÎPN֓`Pt[3=E}yU~~ޱ!VDˆgi+ҕmM,krڭ(uof_hkMoDth]0U9VƁ4& FPe &'_4.|"4._X@UXQ߽UY(_KeUoeV]WŠa_S]ڌ3UlzDG~oĻ,ݠz'O^I/?cx }FGPfT mk:x;B# q5@ ߼[?&n~>Z}P_l(X.kc9HI:}u}^ {c e%EV[y<K`C;\8[^pY' 5~"[ |?'7},[#o}k, Aݷ3fːpM^b+T wQwYq<.|u.Bom=` P3S⍀39U* ,3#GsS9t?XG}xض:Ya^ŔymH~"o})J57ȣ̨!7.?}!k4rqi87ڵLI2TgA7lǗֽFx{ "+ 2h\ׅ'VWsg5->"hcv ڗyY2)`lorI 4 T[Oc<ݔPLWtz_T^(Ʃ_N5t&&ٯH* el(Us $[f+_X*$ZM5qzczbov4ܸ Nq4VInCvvh(4PuKJ7H껙˜n/ ŇRk$rTXÊrd%m|b]DPuWْ'w!{}Hq?yHRCO.Srʰ̝[yi/ӻyPhɊ-#RFZ23Z,ėBҍmLP2^~AC1s.ᙴ`Xȃ$@aM [id̊p b"ͤ.\gudldhƈ.{F0 th"֊$4,c2iXp;Z8>2JHQbz^ JE!w~:FC~`n"4y5Le>ugl_nc+HxV*Pg0d1u x:m !YVP2> 4 CeQ)>Tl)Ⱦ32c a?OůJo3 LYˋGa4F;bE>Gi!~OhKb n)C=hVx[|ic#" ix[ ϧ\QR"3!\xela(QRR[`U\ZX Ah3xka̜61Q UeExka,Pd!x˴`vd/x  d=x4`^CxR]K0}n[nM&}؃AEK&k]$e7p)={NakkiuE/[!5Jʒ ^1h(m0D̩аr Hbl"~x$,~,ˎ'IrsFW5$ydъĐ݅k4)`HOV`i,.LՍK`I1&'AoiM@\pr1^;Џ5@Ɨ $] aLJc{all-E-.4ٔORxHغgMd5J bxto̴j=W =S2H:;"[~=SZux+{?_Jhxq}c]fLxݒ]K0ͯ8ԋn4\N&Uw3qS)^~t6I7n?"}O9I? _aV} 3&88A*"O DB(s RdQ12pL @u ;DvBF?4]KH1 &Lv{`)8#ʼm]2Dt%FWj6Fa]\UϱUG))S>k-ZkJH-sPp.J6/fQZx}snSЋem"@ b1W^& 6ئMN- 'YO،)-FL,:e;6Ӫ Z! ̴'\W!ѭb"ui!5C[k *G 100644 ejabberd_config.erlS&)h 0kgtot]uʯ:g4Mz*$؅j%40000 eldapw[oʹ.t1m0.4?ߺ?x&b< AuCPh=']A y7zk>x+T{ Jt)(Kz-N`\9t%8y%9]]e+40000 stringprepɰb'CߜhiyQԀ(gǰ.xvZmu:O[x;.?S~Hյ*'ۉL6鉾I"5?Yv\<ҷN.AcW}?b_IxXD]qr47. s'xGGˢYD'dǶ[{FEO/t$9TwEݲdjk1/x Iֹցz=5+1))(%>٨X/(Ar߁k떟G|sw'-Vܽ|Q.C셝lWeovb5cZٱ'Y+3kMap縗ُ]j+cY-6*[▹'3vS=Ry(70!n-Z8sE •wGt"1œ-]j;1W u$%my {Sx(#o($0j1h4pMZxIl'r)K-ݬkK>SO\9Idv.T=mv9%M+'aò]3w:(c}|}_#֭,7&3Xͻ3W9[h \M@}R ]If*՛-1SgEam:Ux4InttζgNe=JIE%E`SVwTtXII've}#6"hD:GAuW(cZ2o ]>ϙO˷LmP\`hSyyȻoT j1}*Bn.M|7ڿpzEN;o3m*$A1,^{j{suRԟ7NNk4Z~sɺΕ-ѭpV=bKſ^\QDܿzN7gz^7j]9˟Tş y5!Opx;.?S~Hյ*'ۉL6鉾I"5?Yv\<ҷN.AcW}?b_IxXD]qr47. s'xGGˢYD'dǶ[{FEO/t$9TwEݲdjk1/x Iֹցz=5+1))(%>٨X/(Ar߁k떟G|sw t~fyNXEeyvit0>r{${$9e|X=Fykt{3Vw**X>n=Fl=ǦHu? ) VUs{B`P߀䧥d楂=dk!hWa%@붙Jsf uLYqQXCU+Mn<;ݡ♓f3djcO;RdRQjzfqIjU;/.|%VRR/3v"v00X,T.;dE)"=շ7ZL߰K'M11t^;|SΣzL m  Wq^59\獓\yseKt.$Uw$Rp|,;EfW}ZWU'Gx !=I8FwQ ߮ mDxe{G9l3贍^4ckLԁ=Sߴ j.fFƃ$ܐ=78B>짂;e +2N}9,-K0<ѝ6}UW@SGBz5"J{76 B֯ g2a }qKfg >;_ uPX#؝ Y1 b!ѵk ̞::%)7-/KʷUmY I_];ZU?go03谯Y#gIqWJzwvכQ:<]|lp + ^S `*lfx{*[ffvMvK}x>927(6hG͙LMpG:"Lʅ Jb<)?C7xKJMxX}o{WFS Ŧ!iiq"kUU}^ȣ%7&~5׫c-Ž-qPp#4"1!v_>=_>Կ]b$f?uEF9)mɪM$GvԨI TDPgAc(*(0NVjS$XU[ײX` sa#F2Ō)~3 -t4Њ24AqIlGi'*d_¨tڠ=@ٶL29C"âw`Jb➨P0q=n[lpdb 3j5nz벎rIsZ&2m.Ǿݵ2t>HV^?0$0(}?}E{"k{E T\.fMglLNS??Aq_ wUjlz|L`_+ V~fYzT7\y:GB?|.bݝlg]щE\6p3sw3ܰe>} E`F s=~ V^Cϥ?& SGL@47* jix۠{E{QBbNjEjFsJ97Ll,V $-x۠ۡ6AFBTHL J!1'"rLli_sT3mNlbrq`nE Y=gr2߼Jg3n~$P4BX`|E#DrEsS JKt@ zX-r)GOx]k@m,۵BԠI[x]F-ۛjv^͜3ϼH$IBf!"5aY-UP +M4G?:񫀗 ݪ9?EvQ/' "C_аkyVŠ r?o#4i+m8 4~79%"-HR쪂 |A`T xAOfo7y\ƅ޸[dmXb3Rt1JYo;"QQ""Px* .jn۹ϊR﷧OPXZΣ4Vz$:eAF ۂȢq<tZ6c_yLV;/o{_qJ4e@2ʔrBs趁QɭOl]-1l\wfm0'UHWnL-_[!Li͂jR719K[xփ>y bz{h xs;.i`ielie`2Y1hsc3 S5xs;d9\F=y Vjxs;EBbNjEj %z{VڶxAK@_(]PhšREz,l[It+ś7o1 <9K095GzeIF]M5NXJSop+C㡧= L7>Gx9ӿV NV3,y"D fE(_ 1l2Z. v)NZ#1KֲyqD% 8e0Iv kx{yB"srInCc$#G\䁢zE9 f`1]#]+S+C)iy!!ή: z\rAAA: r 9#L9'Gg1Py1rx{/ܦ8`ϲ^[?+&Lvi:xߝ.,wAϛv`eF%Rr={"0[&4aR0\dFKDoeq-HPO;?& 8I)uC ZŵPq9@ӯZPÖr#.f;<*%xHmв٦=G7 S%{>"uN;GC^Bu OXр4T/ӡ Gx{rAYA3J71;5-3'U/3O\LXD4J!1'"RAYVAad\.N  M}L|N~:٢ɺ)Ur+PQ-9'51j;@5cx{rXYA3J71;5-3'U/3OTDP42426RHI.Nh`-#M8BgxͼPYA3J71;5-3'U/3OTDP42426RHI.h`Z iHxǼyDMlIťIEWQx=w۸?Kl^Wʼnӻ;ۜ+ٖk9hФJR}Z~׀)#6[$0 ӧ_ӧ]aW_,VrwY\܍ÛM.g"J؟|_yx=K38Zf4y " {?/gouH޳<=8(Mvo>? /(]f003c?AkXQyxtE~%^t; VSC5qX~TW/"*0oD6Iy(p$LY,: 49.p*a&fAOA4J]3I?<hav%]x;ay C`|Vq_5`nxpDoK"OG{|+*gtࢹ,p{Ga<)R0ԅPIrw0OC\ 乜U0wyxcǔp](TdeG/Eb`ѕkk37Yx7WY=D`mlלS]WȚ;r'wι,2}l \ !B>6\ł{a2 ]OQ$ %FC' ZoM' ]C0ze D6 ՜PYoA%6hm t=qox@_DTv ]*L~!$A~a1?o^4._l8u|<]<"ajQVQ ً/hHh`O8厸],ҜG|z;" 8, a0H-1 e#=t>Gť\-s[n:!`-—cگ.ͅl]g7ܱCsqp=Q*_$<>ժM(v MM* w P4T (T~`IVNk2vx?<藰vv+UΓvb|8śÉ7wcDD ^~QX c:@*MʉkEC;`0TǾn}%9mq-:שd#$128 "dZ\ 3_EsD`Z(B2d-)4W+J$cʡ%N6]IUmu'bZ_ &6RI >>IiݍM "Pf怣|]F"oZR[-"+' x8<,E-}O?'aӤ`UWGeצ!x{5~dsjANWbu&btw3&k29Nzy2A#v! wO>?:8 O{LJ8^z*IeskI"}e\Q P I+'@Ul!#a Ց~UW0m&@_)OEc(-GAb3ePL?zYX+Td6>)@\r!]dM\KV0+xHȩ4waQ=G3*xh۳vX@&`[ N'\Y"Ytq' ؟Q:hr"&h$b@ө^~ȓ{f<HwRXZg+0fKwGD~{kЍmDÀГ#pdcmUO4FԒd71%>pE]0\Iy;؝dZG N6x0ڔarvB 0`^i0J<]EԁuWWq\3# x @9Ϛz-ƅzB@.Q ?IoX,`2=b0rpƵREfdIElţC8Odreel}‡ x>DMcB!}&@:ͅþ!MSIP5e 3u 9U4/;aSv6B&gZ>Cfo>K)@t+tSHא BB%Sf5>ݮk% kSzdUc6oXஜҹ22e7B|^+uRZ,Hwr%(ҫh6QH'}4{MbRxjYB_Rcvֶy,M'*95O<(N/LV՗p_.b.\?b9ҭ4xQ wo8y[!w![OJw=˸". urQvS%Z͗29Vbspݪ`!5Dc.2'jDOC^>(̂lvy[,b mL[[[n A74omݳ\I_DW֗ǟq9zlu*ެ+ǾTNDU&d~cdӫM#KpM[c۹HHۧ_$GBISe۪S)U@78YS@.(q*.( "a}-Q:uW 2K8I`g^ɺ?GnTjN3JPq6 q9/8uiH2{"v/JgSPtaC*#I9 L}&.[PBL-ʵ [\rRNt!P'? u&l!*1ݝ+0c=ԴhLCB5}x4MdEEB~|iuUpSP[_-VK$^L%65B+a vH8:&=*—i)ɸ QH A7&8Pg wp+m컖:.ś򠆞`܉ѳ ܝx?Ws)myoQ v$nb Ѓq`( ۞b0דpkp\Bs3ĢhoSja5Me8=A?1Iyk26Eȑliώm#UrovrLe6Ը6Ӡܛ[S>ubXKj˚j{1jn̅&E\%b@oڣr}תLIUdKH{S7"6rNl]ZZ̕Lx; nmZcV1g=AC"#0Y9)փI{pf~tY+33\{hR@Vތ&t9!]k=+"BdY{ X*V!t+)Qay:cYp|nVjC9d!ڇuGe-D[ }aw W vL쭈{^'H^R„/8Y@1V2#j6u<= ]zj8Ăjҵ- [CE"Ф yj5(U,SҬ2@i9j16ss3LGrt>xI>nG' 85m]6Ю %.FAІNBz(lfy]V[@|1U{=ۯ; n\`zFq8i`|A2(EH&ؙBac眘694lot! ʧ6EG7rO=Wv8$RVc$Q]/ i}?O:(E'fY`Ӑ@|S?$JrgZBhK7b}IL&l%&{g*2TI3G eɕG򑝆7"yٙⲊ"(}%O1w%.:;Ǐ!2c"3J7k 626+r J *LtVŊH*8#RVj+Ο9-CfX5`E=yNyЩxus$\Wj@yĥ_Auݜk8kgI`!hǑ1 R$޴BO)E ɐDq9RbkT`aL^94SrUZd GvNM[Tyz;ʕA*' Q[Ɨ/@n舾wri~я1hmCk&ijF''.Gݼ\&LB:1wߜ^T݀K>l-}gϠ׾_x N&%"ݔ^3*d)q ʲ) l6h 0I׮&r~!5bxsڛg梫jx[Ӌ6:j3xdh虬#+qFɼ6 BBN O-cW+iWv}4Ҥ&)bBqLʫCi>h/}yte fmRcqqHJO?n6Zd6rSdo a8~Sos^i;/]Uۿ1Tzd[Sxp\) yr\`b$NTX5c!3 tE0q3irO,( vW-C#ϛXrnLsE9 ?oan'S4_,6b8q/ b*q%Vb4S]>l0k7q|v%HwZ9[o.TV]dKy[yGmrT*„k47>v:3sc"mI>W&}A\ җ&GQlf] tU3LGM֬4N?mxlslV*cF 4)6d ^RcPKF~ѭr]}Ҧ }o5R)c>bfҬAtJah* |Pw/V@4Xޡ1][DhYNK:-|vUd[[TeDc%%`m$QԘ:>[PQTνECNU|Z P)IOSpkspna({R%AH9r-!£xp؃f˺7ZݯfZE-CXD3 #G aEPŠ%H0vvu8QqwMiCȎ)0P d4y .2|B1G;yÅa6[+謎&v~JdοCa vn_~qޠJZ1 t &OzeWt#iTe;}!^:c/?"/~HE:KbieK8~kz\' $(%5mZ -77bD_ y]mB.!Ê\C^fTSGq3?=G4v4m&`upq⏏NFcaOl < ]od B[Y$ȃ慮Ke l]W&[s7cʱ襛#7#{ kd#R&n`fSu4+ĵy_ [\m]m{SuB=TX>G%==FStU2 pQkxE<| .T\b)\~i+ ǂ,79wh^ea#!&w@2C$4liV0~wܰ' ۣ݀Ǐa%f28\ og@3C,Il*`ې ƚ ;mAPUB @t\]KW, ||/>l7N[%|Pʩd|]^X v-JKikXeD{ Hvpȩjka9'gֻw\>憸#vۀaL'@*T:kAg]d *19D[Ӥ_Յ**.ojXZmzP> k dy߆o>T5eIvJ&>qVSQA p/'xDh%A7᪅FNaB\|!)f^`h)u95Y*:g-~ J~?L99wKa[Gb Ni:?·{9v{)Ά҉I*7ޚICݦ3վXbnVfOIf*0>~pM_luDsRhZTDRloP|Ap҆)vDtT3zLwPJ  aff|U.:9ey]::TpeE)-G|T H*G%36 j (U7}RުHz#aZTʰjEr]]kZ^ e}K 5 .^Wmr5xZqe5yxz2D/Dҟrn24K$Inc u7/"Ú$#89G},&8{-c֞4o^}^ظīç&EvF]W#YAwrЛW &S-.0.#4ˤs(.j2骠h=h$7va[b]} wљQ? 7v9*[c ɓak^/7΄ɤ+!=t6 ˢoqP֠FSĝ7g(y!3M#&p,9t'~Jg[Wc0Т54ҺY#aF yWYTEDegD=߇0n?e1ej{sf Qk-DS9=]?/)Ɛs,´DW-xsdSˣ2HgB gjo[@ ׮4ϝU!ނn -yIpH>s(q@ E'Z#55قOJOWaH5 !=Me(.S{*vmcN}48}x"_r -(D!3e6E#s?GBrB'l%/  Xmvo3Έ4e~ ])t2tN/; vFOhvk.OHznM*?:BLP~:pBtBn"}2"jq: >W^c|,Gv7rM#WWn߅JKbOE{Ï܏0k sfbe4f@_kYi6ª>y%C^/}p}F[jpd y-W(;OH?<6f׃>n<8}`?7:p LpUK1*@OiKHxUFqS#K#3]]sCc+cK+6ro1dܼYkfYm' Glae .I,IpdCqq{Y6,br+Q,H]ܭĸbm5FKO.0\0i*dm}ɡ:I% \ 뼘.8h"=z O ΃{^HԔ10&Itz,t\F%#T!)(>q jqѤl'f%twuTW :ʺyOrT)޳ThW~.]ܘ,k"#k;\&\ Q!sZ˙,؎&ZJ k(1 oʥ)@?Pο [>Š\±V(9Qδʘ J 3 }o"3N\a.- ݻKZ<soޝK& (osYs!7Y(M4}|">V:*pMef4-KT Ph6幼%]UGH-޽k2UL0wqrs Zu!Lg7XWXO/&> 6܎t[#g IIdq{]/4NJV 44PQR=X1jRS`18gb݌ꊸ2ȦU~.^iS\Rϑ71آjZ+~e=epAKdjP q\_I#9!ouT3<-JHrqJo<*8+:Z/[急r%SLb>u (H!2Glw]et(VҠ 8݆tMFfH^U_ѣnvn޸wv^]wvp4Z\Gu\.IGhKa;;߯յM):t'،PUoDle\X[%ĥ{Z ڹ\6#}<А $#aDdJwhÈ=vbSx;xqnujgp^ttU8 [Nx[X=!]0DSϛ_С R)x.ϳuID x;tiBHJԖ)/ epDD(2qV ?xt)D71;5-3'U/3>SߙnǗHxSM@2܃w^͑vtxp8„,DŁAv x[ôiLq)%]OOpĵӟKxy&$smN4X Jdxx[ôiLoF&7/NPkӝ$#xŽʡ6X+,/L>+Ȕ޽PxQVU;]=f|ꑭ}xKn`]%غdI"*x7m9шVH*|vbO_cK#KHeiӱ,,  NFx[ôiL|}~r虸~ ipx[ôiL]2>ܙ;=k# x(~e*WSo &1Gx[ôiL(D CbD' rx[ôiL;W+؜8>kG /!k x[ôiLbž _v^w9)؜Ɖkʀ Hx2OڴW;n󧺩GvgA{LuxKA2+S@4yܑߨ7"x"ڧ^]2EQ8Nx[ôiLo]o=(>R-곅nĵ7 yx[ôiLu\1>Fwf˞;p )9։kȿ $xD49xH1av Qx[ôiL5ݑ:_1R?.rzʽ |x䱣Gib֐bG& C)x[ôiL_n.0Zb\ku Txi:Pb8x[ôiLFFWN-{b3KI(ÃkĔ ,x[ôiLMx<9][ހڂkTfWxu;THz/sTf?>rӠMtЎWyQ.x9:jo:[Uwb3}NbQPp@I! w^[0Gx[±cH2!M6leO=(oJƉ~ט Vx[±c&fEIyŪv7od x9:Bv?B|&++OӳNj8?O)rF?bt0)JLxS:h*2Y2kEin#MͱNsaVW7Iґdݟxa7 vo5[2.f2ٳ0C"bxQ:PLpr}!<(bN\oZL]k0X &rxp:זA8vo-;>H84I\fyc0}5 iGN29pò;[X5}cC?BA>æx`2:O/&k?Md'!{Ǿ+Q+&籯̢xx: 5mV5y³1ܱN .x!aVW7Iґdݟxa7O /x9:s54 ;넋*Nį Gh0Qjɳ0Gx:pP0lB۱Njtx[±cH/cc3&I?NLxFkG x[±cHCy)—wqQ#("^!c5f@ @xR:lK+aV)zCpNK*9֓^۷=8hDs[u^e˰&t?(aax9:ٔizd9i>']Ns$뉉FMD Ow/Gxv::LE7JxȮNS:S4zJ~Kh¾100644 control.inh|NW؆Q-;됑x=[ktvG8`#g5Yx8:Z@=j31%擱NjmO㑀u+ CǺ[W[`Gx[±c? =g렩k+[S3˙ rx^9YFB%d0[f100644 changelogLvM}ngc.Npd;2s҅,E0F'lxR:2°XOtNKG$-PehV*==@N(XR04 &f'{`xR:W>c3Mb`ݑN\8D*{!ګ^h]Ca߫40000 scripts/%PUAUxvR%F̝82}x[±c)f㉢WھEtҮzUF>;x[±czu2g.zYV-f&& % ;r|kx&oo?u][̬pC|b]@у)K:Js2~&rxBk/4xۓl6S x[±cSM*S,3 5x8:>]ң Tɬ-%\Y[-NZ Yo>N<1<h;]|xQ: N<1<h%`x4:x-a&}f)|>%h2N\9G s:fm s "x59U}#W@plT100644 changelog ^R8J3`ⷎ;ۑNS:{D+1`iŸXh100644 control.in?V9iLWʰA StRsиvvU^;H sw%[1%Ap\9G s:fm|:Z{xN:+UDQo|ѱN9a'꼏ԓmhó\9G s:fm_%6x8: $ t|6#ܷNZѐC1T:ٯ$uhGx]:T8gj NՑNS:?YSDe i"\HH100644 control.in{9Eط6b50jI2&kx:s8lt߭NUx7:dleW}:u/NS%F:A I8mU8]:orFx[±cmt]ah)xcIFkJ qx:Ԛ` d*S;N'QxQ:,Nh.w*sQN XMeQ)z2MNk'0>yW#`xQ:^IKY*q}Ng`yOTw5Rh@e!p;%NJ?!_xR:| u hK0NdEgNK}8mV;7%Mt %=~=Xˀ y&%@`x !Θ:k|ow5 _x8:^OXDO,;Z\gN5hdMuXEd5kUxQ:dbӻjG=NTn}\7;}wj5 -5hdMuXEd5#a`xS:Iw\y_/(]3.ȟXkcJ%,axQ:81}a*\PSN|q|&F)oӏJ51AC<.D7U}ל"zK$_x9: \8Kّ̃ѪNKG\bdJ* I6w'\x}QMK1=7b.ŖTA*xQf56YRJI &IMޛ7yD/_Âܳq Qk uZIy~M-jqC0ފwe֠ NQ9_1{H,pX m/2+#e}גKk<̓ GxAF ce//RR\\(Qdqؾ [^F%{8Xqz~٭~C,||y`M[͉t [4ͫOv`6y33ݮ5(VB;Qf.nv i+q'LH?5ս Iub ?Ѭ]8R!ENj"_*HCkIX5p:+|T e4}:3@5"Do>ʁy\Ax@\(Ramxc`\(߷SQ?+@;;4o*\F1LcD;cxҞLIl "nC{i[(}Oʽ>vudR,ƍCK"/˘=ҥ<$OF@4ҁiHj&m)ע Gd&g͸Ѡ5N CKjH3U)K+{6 J5S(Z.Z424_{Qי-'UT[27J%4%CH{ވIďPn "sR2T3A=(i|(gR 4PWrTC媿OL9ɝTݣ7Ft+դX>oL߬|2mi'da8*hiP(bH{_;Z|& CpG`h &ϝV)SNjZ㊣{ n>Go! 2a@pܐЀdi֥ gm8zZHdƔN9 dwS1t4bHb,: 4L"|.!11t4N49N-:YHLW1bjѤ:ocHO}hv1*_a5`hM.cG0c @0+4&` vK1aZS]jH&\J$Hh*LG$`Vvi+)No?Y9Z|ZS1TO)(sFKdϘZ*K<8c7 j,Fk|wݧ"~N׸z  "T Le;<&}t ZxSh:BEM5Q9`R*; O;F9cR:fpbտ]f"`&AfjШUZa`B@4<HYfH{?uʓn)ͬ}nk0} UU);cg )׶z۸inA`wY8Qfpf&vrHF*tNR@MQW&.2Z{z_1)m|h- c.IyR5?2&@ŸZ31Ket3N$&g˜S؍"xq7Z@tj2gO7Jq49-UƄ9@ԤE\'%0&lXMzqw?/N|RZhjM=uMӕNP 1;5܊ 8 Pa2 ӯ9cnՔ.=MS(@xOcKM˟evҩөqǓ{sMCJFeA(99.{wG_'~ ۬}m=}|ݸZb6+Q,#\M)8.3 UUeZE>Y3/Vlp$[~i.щ˵+,OZx)qg-Re&Va+#'"LXK:$njyk.:ZuUeMEMA~M!b9wξ vYm:җm?g Y9n֠"~\;+!"Wݚ]:)[^:R=?Uk0[E1Pb2/.iOWdhCd` o G[;sɨzڻ~̓!vo[{#ܯ69[x9H0#'bD|%o(3uиێS3q Ds۶YМgd3ɸq'kBDR"s28ōK h2JM%>w &- 0-PS ^m~UkשO/[7c.drCS6+vQܛ$]O*fgy5c/f|o֤;樼4q*W MGAW}K汫^6էqTFI}N+㌪܏dr[Z  \lKRY[n ]Wx(J5DZKkyxkr|k|5R o%UͲYZ S5WN>ecnQƇ~@hUKd.9qc߳.o*]Y/t<Ȟ3KJW,?P=ܗ`iTN>e[5KדaC"LZC"͑Qvwh3 8|$?n,#@>G|G#G"_Dh-~PQ{F:-UsdTlaFΐX4h,AC B>&6n+<0Q!42DaŠ@sX] #N.8Q45``Ezph$01h !$2P1.$ a$7 5&N#;}\2Zh<,pX=aj&hh`;A$bA Y}o:0n)&@5! L 8"Y)2aQc9e 1ڷ?l1`!5/MiXh)pxxxx`=I0LxcNOmn΀qR`$DI44\lXXgr"zx/ᑦ~"aƜ9¨)xxwXD@""X&L+i.T0fR! v\v!Db:b? AD6N$]Qs [cp߀S8 ,Yl`g> :V(~|F,oFfs,.ϹWJ {+[GK`Gȩ'Ex*y 0G(Obp.W UjZC|h[R27;1WrX읡XV>f]Տ7vs!XagnNPhSssk=E1Ow̗v|w@bkآFjtIRxRdO^{([+w-UΆ jӬ[ύ/^Qĭ(hrT,E5v;1? jWXXVk[j姬id~NK: Q ג/=QoޯҜ=CwЮqخiij -CÞ}kӗ j|fHVWUu{nB>ergilĝR\\ZAt@ûh!ē)JWrvXCC-1 BV_N٢YN[3qU v$htaGk2g@fӔ֭%\'=V͔S]aݦkVөgÜA8gޮ& ,?ămh m/,p{2¯\ĝr6;ԭ Ŷ=\궈}2J͕:\t{[rEc|4ݗʝ<~BOti/:Υ{;gT_).;Swn݅'C<#!@g( AMHm}[,W#~ťdY!Ԟ~z:3t֦ڨ6Ģj^d^Z6,k\B |ۊeeocƼi;z8gjE)d +b6N +Fv S>2Ʌrd#6Z X 3dxx`r!${@c`光 <n"£O`GAxd%oDiCDXa McIiضL/5݁HND J11˭NH¢IH d0C2XxZaeN])&]Atox >Q,_)t"02M' @2= ʀdǒ;oN]uD( ,z 4yG)`p4"q0S!~Gbó &eI-1#{vx$#1 /, Q]#W[8r^ڨf:8 &1C!_?pIVq( B2pȂMQ- H~ǣ)/HP݌G#(p@A̙;FMmh*zpSw{ߌK= n7G3?p" ` +07ii*!Ƹ DW>mU^1Y+i\V3ZV@ZA1pǻUNLffH\w$cGưzn>CZQΩwX=yeТr?7{ޖ{v63%b z>Ϝ/&Rl.فEQg gk/jR_StbP{=pgIE9Q >_lٛ[x"dVx[8*:rpݍǗ̾vl#ӏy溺pSO#Ѡ fNMA=#;ùM?|16_/'Wz' }MѻQ#éj|yn/G瞰-E4g}d΋#>ssug% ޑT7A's:NG_lq|yyY&VlWc*/קm=xoqV-/QݹCf_,0tڐUc5XI|3m_5Ovwpeع泞lgI QQKgd͢{|œJqކwE6xDwɦ󞔈}،-? R>}%ĈKʂv>[o5gIOcVx~c[ə7y},3\% ޜ Xr|v^'1tA[FA`|oWqI9Yme9qSQ^nm\dם\,l!uUgܸRC4WHw{;y-ߘhǻK/^x^wtmmpɁv: 9gU~ft5'T-И1^9e6=eV}l7FBslcsdWⷑ 4/ISzeaR,d県;6HRJ_H3/6I~;t.jUSB Ly0b|٣֖gWĸ{sȔZna<pXdNCSmT>JdXly-$vٜW}%a\y ;7+4Ȝzk_4 1X,^?q? 'rrGNw9#'q||׃׃׃׃׃׃׃@^@J(E߅*O<(BcVk"7ޙ< sEHM AP4h?"yZ y:Hޠ7X&hZA30?Q wrSteJa2L('#DBԅD40(< iHNNӫJ&k &gxR<Ք_6\"}H(a >_)a*ϑ(fEpxFEh*Y#0FҪF~ ɎL+(&N?USڱjn$[YOQU'?PUU &rnj;q@[! ' lhX!oMUtҟrd$ S[$L M <@"EH}j~kša:Iߥx4h)OoH?";U\"˚0R@Ey/`#a#0i-2 ?r,lG@ Ly. G_nvJqM+IƅԴJE쁰 1zo6020 W G!(&eJ-o Hނ5r6<,gc2W1~ɹ |;nҎoEum=vOgWD?+ϗ.VXlRd—Ok?80#kmk#0ڄOTjjֶ#¸k x`$zm[7|ˀS9938Df47.#o:lAoDzW:Kj~(mIuqAń;|}_Jz? }`Tw"pnq 3X≝3s4ߥ|9|aώ;>V6?#ef"ҏ"83;KFYNn2c[f򿄓Z6kwGj:$zK`:_gI:˂$?N&"=Ȑ&BpLDsghi;PsӴl,ea3ࠄ4ѴsCYt}l/rTztF w%gjS0*i❙ ˂>0{,}ՔiU8q?Hֺj$Xʙ@bc3,-"qU 8)^oi xҩk6~%8(cLBsW 2'.qnD0JGRnh[];Zʭbu\$Ir WUO- G<}V*w)+лw۶_nb@h,U_t`8W\7k![<.%8%Fgn.Ju}2'ɟ0+3V |Olvfa[Û Ғ@}d=LT{Hl]QYdT@?yL5Ҵ^n}:$󌶕J=\hQ32m9O iuկ*%ReKs9o4rP-)R5 ]WbD;I'>qRU,޳P fB{]YMykwTiVum'*+wi+~~w/|K]GG){w<"r૫ Gu\,V_/+9deqtI d2*]q0Ie%JkVhx8-sU?iyF{\BsU@tIW= 5tJʚs)oE1d-D)(N1*g~k͝#";uO$_z_HP{'k%3 dJJRS#% =-~ۋ\_}Y`j 9ݪoS0km^WW7/zMpmaYҺ|o%}GS*zq( N(%D汝}?94F-O>#M፵'K aФdp#']lx1u0 ~RfAy - zȅ(q=nIɿOβ|I̱ϲXs]L1u3 8zPVoީԲc.\w;JH-S+x?Pz:[«8\=O H6k]4/_Bk^%Cq6 /+\}}rkFCWqbE}Fb5?iEoeI'ӫJ#~߸wk  aY|Q#za7~]4{pp@aq+)w(ԟxK8?7%n퐝/iN}e+u}q;hyKw^?Ȍ/'HY^cg^ n9"Nm=]LZa?9!}g^:ـ̏ 3ڨdPWqܳ.]M[p!2YioF=zײʄ c l+m~v^Pb2ښ.u"޹wi2هqh?.SZvKּ*?N g!(-={r:w% ZY`KeGC|{\ Sd^61h:3 E#sɭ--_i4A_HC i}$fnIOȫM ' bINHd7}T~jBRmjsh)Cb! GcDڪ)Pg{_1`do/_ M)5 j2^si1k{o;6Z}7_dnɤ'OBs _g<%`l<3gOƒh3){fr.Eڕ~h(D%Sզ>D'TWQ +{]p_mmlkj/ 7_\aA|n/<{}MݣʺwG_}1oM)l8E9uBQo[;gkQ}UaM璦- b$:R͹ﲹUfoO~^Kxcłu]\x yު=鬽χZG_ݎ-k`V<5Iؤㆃc}_%8ypvJl\we;f[ jGu6|s`G7 Ͳ"~ Y/y¸,Liƾ"SE<Ůz)*ۈb~-:9e&ۀ(Pu4fnX۶Ng-?lMwJzV=ïgI =/D.-28+7/]?bJ]".gvk|u5ϊxyB^X$_eL3\b~_%r9ȯf!NY[O/W~_|oߝ(Nu;#J6ܞ"G-cDo^@"hmjN[{Nxtk-_35gs,-*uUF K:䀫ҝ6^>j5=?c6:>75Cuw?ރu1l=$Tb|W#opiSF^3rQdZyy }JsAHCۉaϒe Mt5̥ &lfVV^9[[ݫ]Wk-6\d[H\oW´?6xV{{69J(ZqrkCܚ'I-P5U:x1\U _BCC-,"8'-B}RjfHADq>(zNq}uU8źoT)؄,rvd7ߌ^~,{zyp꾘ʣ)QO{8^^tAtDͲS]Knż}pP@t?[E2״ g\;-@ȧ=af7GRE׻Τ ]XvtqwDﭳ( ?oFaI]7.w[5mNG_m ,>_vf~ڣwG p[%Aw2Pewކe(l/W!!Ws+k,6F _gr@ӳe}. 5TZwXӢJ[=ÎL@Uޙ%UP< ԰& uC2ibKyVGd)8x_,/L3sA^8GC{Ɔ49o:s({d;p޵#w=9*ai@9Gyhz 'w=o}ZsXFU KK,/v\r-9eCf;Z*E: ؔe}>= w~OyЀ: emhH G^ص:sg+nC=MR9m{Aڗѵ*?mܙGA͠ } L S;1=!rO"Ƚ2j~*4[ g@AVlBhj]-.lM@#TE<=X+'}{`qD6:*8ޒT^e-| Ç";_r-c^,do~m |0?oB; Do=X.OzDXԈ쿖ʨ9?k(޿o'EҾocypFG.]}|* nˮ d9@`^-7a mLBϝ'z+rXpk\2Md4 밟;dӓD܄pߐN8kW-fN*hPt6yӸV|+wc"e T_,=CPZ]}rgw.屵'\T';ɕjoL;њJZ,L2z  J5{2+#[ؗQ}{gJΏp <33='L31Q:IR_(f 1gSUOǶK&Ik'<~|uu@k|I(ii(8,j}PʤRl,J|צ~`Ѷ\SjE;on;G H2Mms rm)ZIbr #BX+oRyp^ۏ_ՍqOcOH jF.{+m9)>[nΉ}7`0-`V1-NKK_3UPgugEJ^+k`#ʊ9}(nL++ҟBEn.>畄|3;ᗞ?ٛfc_Bo1Ķ,#vjl wmӧv]\ Ɯ 6xPo@ (yZɅE`' E=(W}r!Ga,(aFvOXu!_l԰mH[z{߆gT ɾ6ao<;K/e}tYo{yrɿZY(v٥Wig+^<߹u힏`m=Gq-JA<.nϋw4n*Y^]*3-3jZvI90q^kj^X׷f./Pzې6 Ȥ6e*7MPaJ Ln&46w I&a}NVi8TE7U zw{|;mv+1HH$Hp, Mjb.A }c"\ѹ;c{# 3?4I`&NDӖR- ♮6ыo-(v5 6y)Vv?\p⬔v+}s" ޮ^ZCnEP?[_~jͰ!0_##A9U/|F&s&Ex~<륥ٯdqG2WTU"T9_>>Aqsoϯ/yy;CSB *4xl\[|߆lZ%ޣ]qosg{x)o߶R]W?\B0r?3'NҼ?:nqW*#<ͅYn;wʝV%@5Gw.*ǜy˥~*7[yrLJ]f?Fh%$vх'~{2Tl$)k c~4mUfCb\~{č](QX&RGpG1QgsΝ4;{nԘ +>['VBU:T}ǡ7# FZ| {ľ9쳗#K 5Z;?1gג;j;S ϗs}ql["Nū<2hVLQ+F??/ P^m*)-c®~|Vڙ$\ mWG9OޠɢpJ]on8T̒ u~v7zMo~^4cGEho}BvH{cto~kk_؎@yy.~iwz@vO||hX!-GjOg&8$ b/Hu%Ǟ` dJJ{Ҙs?^H{dKtd=;Z'F jo<0q;;C\s]jCT3_~:&{({MC[EQtwHJ3Lt7ҍtt#HHҍJtwH g#=yy~뎵Tyi'5uvO1 {LNZ-|[8J1^ynt=2gZJSA9G+s_g3Pq ,q]8?0ɹ2>GF#&T_}S7wtw"ߙs|CKp|lKiKKa_.W?-5.?>1xoW!wjy06o/թ/%.~:.|Igg>3E~EcWw~z˄_Vބ/ECU?Ydd[s==,KR*{ %5>K$r9_;'ECu;kWl*gq8l6̙C+!aQ"vq6 [u-Xuϛd6'ް mnbQkIj'EJ39l%xX=*HKvW F\}7Ӱ㑱hBoB}D:k7WFòHt\I 룺.|q^vdSܶzRz^@M(O\"7\a^U#uiYuC%J}l~d79/)xwѕ!c?wı:J>[ ZP40A:eS^k[IG-w<|Rx&;px:F#, }m;w`hfk0yLHES 2m'dImT$`Du2 S@ C`ɽGhk |3*LH[M8.K(!MRg;2G{}JkJ$-.(MzC9ѣќT]ětM'hRo@`gUefM%Z#rR/AS;3M1QҒmxqi?{|VLxJ+PhgyT ̑%rde&M7 [\Bij9y8̋v2GQj~ nղ0n&-(?`>|VIlkxuLiǪ"Y`×\LIڲ7thO}w54άNDm56LΥbUXe?9 _r<+"l2V*)Ħ_ Q,1hza&.JtT8Y&,j*7 |jwoJJ6W(4[-h1Cӌ+?^΍Ǻp%O6^tA 0xALB}&sj53_~p6a^1 ɦ_^3aao1>;a/3CI*wcSIϔ'59і8tosg09 ,Vm8_$4bǢuFTT.1u!}sP6`BkQ*ötʧ]p\gqߘlDy cVv )ղךմAq+ xa1cGp|{C{DB\4)m|ngWߖhqlQ]rAZU(phaۅ"B3+P[*n.3/LCRR) CT'!giL0yWf}fiksJ5>R!9}qBgg2_ A'&뼗/5I/XcjY]ᎵE MLsO~¥:nUoOa6 BsDG#8zD%JT>hȚ< @i! aK}[{ F*@~_*_ " @A?)/ׅǿ |yn a:sN99Q@bI?||Mz%G |M@׬EAQz1 x+}>x cec|`: R/h~b;Z_BG)|YI$aJ|sqV5+N.ӏӉd֗ia>/f7gc{IZ&7[* 5AQ>d+=L_6 Ct1z77R=֓I ?{;SwFߔ}:=χ/}& Bi4K^\OjF_&Aʺ9iɗqn+6)iBT/U4+@otj>"n{OӅ>Ւ+J1qPϤj#'m~Xjf6qc*i"F4{T>m-VNHwiߐrġ\>H.מ\N.}xLh2p]N˂B67 0&&k:[3vQTYB N VLYiK?q4Pg.lUu|c14u=fB\-`/aؘҩcF-*j&TJoXٺuK fv۴!$ >CA3 UHu/ȒT|A 0A}hK!gMifD`45CF=w‘%4t9E9 ck6>q|Fr+ rY-B#G{BƢBP`xskmjYe{YJHoƄmWcϰc UOVe3 !'t}u~d@lJE鄣!O6x6Y-ZWI&TKvR`_VqXWoq:%QAin-ѻy{}<2T]SB5ω|(n%ZQn,>v-xD9NzsXGŕ z#+`Q MT9U\md `-il˫?T'g2A'S7 8aWy M,s=R8 +w:t{߅8cFDBqp7Ls=Osǎ(f,eySí5")J *>0m37$g ^sYM1yJ}h|LOB:AV7sùχ45V,>m3dh9eҰֱIi-;l:sR)kg6}̦>*^`G 1,zE#^[DiE; ~ ȸB ]/w.hqi{vohï'/p#V߽^#~ ?W7+;K ; +  仛 ;4|w|w|w+( !K8(br@@v?@?%d/opr@}Äl L x՞5z:7?_\vD\s/ y)tygD*.hܜWy `࿣qs;?Ѹb0S4Ѹqq4#SqKÊEZYX7x̞@#MmͽjsW#Ώc~! F= \5Oy*̠l&=ֲC PqA9:oUaJW]I j_F^XrC=-m_iLeE7'ޭ\ F m> zk>gvðxLډ*۩I$p* b;cK6 gIux[Nl_d+-%5['[sOu ˫[pNL_Y3c`eԘ5q5z[MmmވMbzYV^;FM\!/Ӻ%cYSGXXSO:zRu!Xѣ"q=]s*b }O;G ldoHwCh"%q#xtx wsn!j>kLJc?2"7͋0/F :dGGj`9$dʙV2gS?倣ŵbf_`@\ğ>u=4דʛ2Hic3Zqw'NU:B"ё`*wWIX~דhERYtz>NG*/z9^lt{ ؼUAۂϰ7+n_" ic,N,?ݢ ̪?Swޜz̲Nd1/|7Sk!Kxo LJuS~b ZuzD_2ď1):7>$,5+14ɰH?~4JdaY^<=,ԐΎ@W}I4η:݄h+Ca`1HCUx>rYÉpd9˶ѷ$>FΪ >tɄ"ifD|3h7;jrnPw=~zV3U!B!y=xsq&B [$}qxL{HAr>Hg`62f1u+j6ŏ Oj,,ͧI%SņH*ytI)BwzZw=>]<7r/bdxMSZ?2=m-I^9LܚAKIB_2I i|T~iVT9"O~xUQQe,ϛ:e{$T'Vg_[߰Y>~Ͷ1{k+d!w = O)|G\?~w4yhF×jm#aoOoE5>7B%p)V%s~b88Nƪ?h/r]\2# ޯ!1U~m4q\S8p]ECa*s5U~me]uD6༮jZ#^ ׈fAcC؁j~¼.Z ~ļ.Wkk=?^0(ܨZ0gnT[u]4 ^#r?[g2j:(5nPN/Uʄ-wEj=WkDejA."\4Ǘ"M )$.WY: lSwXz2"2#Khґ-m-,ܡSeeF-|fV1/"!$(8RBUC=5*ed8]A2WE]u6Q e;a P3;/q&yȹ\=]r[&iq<`vg4pw6 Vem`ڌNŏAU#$#xq'MC&="}sMo5QhziY:,u@80=dVj35G/r̼bJ,HE;)_LAM`x8mОTctk"ӶNa䄩A1hv1,Y^\Fg0JH Uw[8ZQtϸeh8,'aKeFۭ>r@!aWE}jܲHNSԪiSrVSug-rIflv|ǯ Y ~8!-Z ,׫ϣݮƟ9>\:b ݊urT4?[1dGbSWxLz dr$8-ޠHEB^Tc:##]sL#f^d} f5?0˿A̽w&'A(őO4 s8qhgҋdrS6ffO5XfuIupuV,H\s]~ .er^Bѡuv ߟeJC w2Ză]>G#zk=fKK;B#U@pQϑ:RBG|M%iSr<`Lzct0c@[W:O3ՋF  † ֪j)ej #J:7A1h02f +GhgfGS 2\LOHei A3+x~ yEڑj]ʈY6{l=ZoHk+4$Eer*E"(J "r*ҠE:ͬ)з K#FIPm81!Lq`l͡)6VP|:_"/E3ȳ;&b \9;ɂ~=/_鉳`-hQрڐ XrBy`m:'.Kl,cDVt\\d'Tf p ܐ\^;QY=?sA򷩏 nrL۱|H@ٸbpWdDާG%j)b4P؃Lb$tN S/ŨyA&Ŕɒ@cAPL+[CeJ |Dnn 4*f;#^B:R1m*opZbyHHS.['j#Ti1T༧#LH#)SX)0]J{EDqJ"}܁פ0riPg7ћ]dDc9Yhy9BVS ›,N2qYix)gxwt:'՞QL?z7nlM-lQdhL^h/{3DodhNuui"0NLxs;cȹw'%S#'E4<Y F 4Pl=^vVLؑ.Pc geͱOd&Zo5pE462Qw-ű 2pP(*[ÈO(&6tHwZƢnڧ(ww!ZQ! os4}λxh uX\jVatd_SG,a)Q [9<&Cmb/Z-*u,!&~F,pykZfBYn &L "=Μ]}(@W+ @ I~mWDOk_R:ؾ1MX<-)CY WUGΖ}4 BB{pTNo1# [5,E[I[QЧ9'y{2PMG·63ynz*mp(fٹI+=KBuρK{$nLس~x;7V؈0gv*2_81F29 ,L9l0Q[mSTdHT.:]p;bןG̕#؂]=b~ Dߠb!Wł?o*~Z5xQu*8ԥ9@1ץ,(v?Tl,K?R@LjuE+w:='3&-S>#M-:~hсH޴=-㜌?mO(7MK)D‹/=$%,i9t˾+,GR?اris @$)7.NmP'"5mD`V"}l+Y hF;s<&H+MZ /x1LTj㜔X^ \ʥb|Bf(/NhxuRPB)pȨ#3AtG+- m9x>.wXRVB؛FP?>2+T.)xwG2rk v޽ԏDe^c4#aʛ!NAJup1_S]1vxx3-9ü|5F~7\"3l1nb0I*kytK<5 (4n+-_SsCH7`8*>j'`Y j (UmMg~wiڳip %˝33@ւR#:kDL'q¼tz>l(.͘;[wnyRse:e3xt6=XJ9;raR~=/GԂ6X3I$_%d"2 ]*n='-4{@ӳv 6t<#{׶C+ZuU[An`)qX̙i4suv8mggBJCx>j[w;CgaKfh`\S꼩s B ]]טV\=a!G/^st],̵;v;e'YRK8<;z)bJ`}ijvy~ti۴;XT2E"r-n-΁(Oݴ-Jof6=$".sOږkbq8%g&̱x(t]'Ύ[e@o+mA e#{szr[T˞IFM=V&a93O[:mHƋqQ1VN˜,O+5u΋|`nr38:A'Gޣ?aᛯH7_~-j&،C)HˏYP`+IZ=H>$]۶w ݣ+pABX N ԨIꉅp4"˰_gL?WV?I֠٦ Œ)H{Ai goQ9^ V8(J钸'zs#Gatp=,[EaH]§x A(|oA UGݽljc, *R|6̘bo<%#j5"bwyָ %+Œo(<gMK Ic>}\ m-M41фV3}Cl`o|/'WrwCՁ' * P)p4vٛ/(_I2JxNZrxP {GЩ9gyKE98a_=dʹʼnJp>z3sa275ҔM dVlI3uXX7hZ(e&Y}3z٧IQembOͼ{< ,{ P ӟi)v>@* 廍Hm#qM?E ֞v9Zq+4}7eJ27>Q[_>l>n Fq_мí{7햽s'^}f#;cpSc)Bf3k /fȅk)VgȻ6~Yh=EA)f6Oʤ#oy,.yE!{GGa/&Cd;~8K~^ՄjX|i7y͆o$P5  i#k |p꥽ >Q^~_Hx:|aVhZ ydVa+o&do@|8BͅcǛJ [5~z Ʒ=ȥSQ43$W(7yf y*CEY Ѳ̿=}n eA0a]g ,s+ 8msw&_RUdBS+mʦۂU*+y^E+r bn+. P˓OVQuQjE2hR*M>Sr6g1Zn=٥TaW˪9+x knN_Rn,l)jN ̾IlXyNQjcY< $LLׇrZ]ox;D4 s7d2bxeFo`'+SD DNl1kv4g"hDӁY;2|95^Ȟ`p&?g ]ID&I_D85jIYqta#'=> u0Hݙn{WDN,-MԲYt%dbU04ED4*/4'uJ-䮧~x^({З3ܸ[n^<6X]^nlٗ/#論0 v;|&3ږʢd7K#Vhb"KN ¹ybL9}/0rbsͬwPCNB1zY@ )/̨bʫโIX4ޟwAgG" ~"X=ZNSn/ 3m$Xq$,Zh'{0(J~W;Az~G< ]ǐMh+J$=j_:q7 v|./8t͛fϨyo}b'd2=̼LTZFꨀ(oڏ菙SH=I(y[/t%jcuWMԸ1˻vۜT O fm /ךuq[6pTU9 /m2lpPI(74x*ٔ˚8VRMO%7Eۅ0 8[g| H|vcA^(T!;r\*݅+G̒y #} uZ;֓,f{@5"Qۛ:7SCd(O\6 f^J"gj*]9JN2nPPksԷ~9{wB7)b!&$s6YصnU4*'0۱c(֢$ e6xEKhQp.B}"AZE䈤(M|ͣA,.EB]w:ZR4Tw]BXz Zw[_ ҟ Y>ʪ@Su,/޶ N/UK:1H{JRB$)RL(+y8^%{r ľY![=.S%B˻h2 ϵQ7T]68'R^أ5GWUlB0$, Uw%{ $OBBJkCͥ(&Z#<j f z~R2u&I(U :~Z"fT6%1,qzАi 5b³ŏfߙ@FSE@Z/e7C+Wh٧)ҪPE~g r,?=[+u]&HsbR>yQS[5-udMp1}ҩ2ϻ<"gv&OnL!b U-* 5?|` Z9FE™H.jE#{i.u2Yଳ9xɠ~!-w'npOQ\%ޟS+]] S1,$/ru6j`ԅvb <B=KP] Z{Y' +QHڢ'a-}c#_(NϏ7ȐZ9Xhs+׶q00B,zO_V_ ,5߂x2?sN!ӗlqsL>ҋ6 5G(pZEp0h9~hɣД=P0+tup-3R~W蠧*9xvJ}#1k c2lK_A2z*#h|D4p ؠNj9ڇQ{(Ab3}/+o4f&}lPbo33*ڸ8F`8`GCXbK҃aXΤo[u{znK{s} &~T}du^v/if9+ <-&;E.r0EL(j m oUR PM.Lڨe_U"B]CQj-{)&p8Nu ]âWY$==1O!FΞn~)r{bݶN?Ι/- hQ}M0|A'iTvn$)E$4wMu:'?OL GD F$/fQ41i3}G@} .%7Þ$v"xpJحaj+ /)`w&6\T[7:G^T1)Rlg&%g_aܛcN6Љ!~I g;7 ѸVfrK,;gAAP-*ZJS,0#[)0)5DuJƈb;)9|K)ͣ][Ǔ:6έS4GF9oLO?Z 32="cXgg'o૛G_/*z}h%@!(Ft^?SNEs}O/-kGW_:$L+Zc_âҤh1gNzGYz']!kmR1{ض{[[l羬NXz>vY9XsJ䥼ֻ"FeNiߪ؈K]֎#(37:8P$'{)v\X/.Jszgsr&Ԩ-꺑Tϣ3eCWTn] " 7F:AnPBKnIiI.i$?8~}=ZZk1cڱ)@^5$LGskցP>::#zMz|?-V6'HcLYj8AYX_ l8~.StR56}Vf͑E8@ܥd}٨sh%>̔F bʉZi Vϩܞ4C9j \pEF Hsbwe:435ŗCLg鞹\o. &\^xoV%m~Q ,1je4ΞU$䀦z0\RPRSBe/d4n*xS `|ER7 YwI߬ ٗ ?17_C;be͌ǭ0[䪭[vrcR_zMmFʌ8ZJ@dNV/-wMj Gg'J򴗱GyXo'V߉ Ifێ8;r, Uw|s]˦ny9GB.UO14hɝyIvMqyNZ915d8l)H^rYMP%o_bI-etg9R12}2[8"̄veGS}㠓d߁=FD؞R9 SCA`,VR80VEpZm?ݍf&zB7ؠF/(427t7Vn/hMU'A, hTc[իrB#2ardc/ :)`\e.Zp^/Lc B:fSEaq-.{N'ez0ޞ 0#xPr?CYJ}#60{+y L'K6;uqq~]qɢ (B6ʧ:/}M/P<)+D  -[xd) 6+3V{/ xu8|}k"/d-`F6Ho3/{ks#Wr*zap&Oٲ-,TA͘VCѝ<#^S6sqMr\Fj|s؃ojxeH!9,MxlQO,sg6{uc_dס/r4J|xuTnxc#Z6< ڲYu@}öya Ǵ(GU\ 9[eG*-^:G[z2\v?:ݧ- ŀeHX}O:pf4;w;y2a9kyɥNuA2! 5 btp>,~Y3>!, ;h!Z}Z{=HEE3 NI91z_H}+hd7R6S4YHr`| P'qeAmjvM1v?N? c\7135﷞Gda?C: k`B @ds"|V 0L 8{r\fҹ XljѷcPy>9,#a^%!א0>,R4m$SE%g,kAg1"PU(֠dMJqqgGᙿ3r֯([*څ"dP9ٌtիu l}ّWxPi𙷮dZ$c&0a+{C|gC?_w /ij/sBkHC> "r;P% MO7LY(I)h7̕2Yڍ܌k$uyg0)&e;8檿߰I۫QЊ'p ) 肰8lh(L&(_K&$e3&7;fg<9u R&۵vWe73A LNkYR*hԈ  !\/|a17b>A|8C#-,t2i!9)2͞{d0(*vEP3:ĭK$([jGa- q14WS {t ksWL$xzZk5~LṢX}D}T˼7Al2W~A~s ?}{D *MЮh-C&Gx/.=X+\3Z%nh(UYAċH dxMӶoGO=3&XhT/ڲ@\: .ޱJ o\cH5B5,q-bT{¼9a6D˒e#mw6,'&K0 L6T[t~IzrD1կ'7 ?!i@?"ߓ4 H7Io717- - ۀi bX$bcEf 4'~Y(aE 47D?o@. '9 ?B@~1uAq{9n)ǝ$֝4j.ߒ~b @Nq{~^ z;=j qx 3xخ]op{actۜop/(]^no4J4.MBWwrLEZ7|bHj5)z>>Ȧg@(+ @F\񲳯ؙ7o F'Jǔהqa*qkG*$=+;6ߝ WKBor*i?k&%|nRICL%s0"/@$e!gJH=s!Ĭ"P/|wSc0*7οCPY|*y ?"DɐpJU-'@kl4uCӍ_CL⡂%+.V|؇R֦Dg2F1fk] #tܝ8ƀ, 4fD=s*rwM8pJ]F^B]I(gXY8c.0A#UBgN{ܪA5)ٶJZ 1yf-0Uٷ+ AP+2XH,By q}&X-:3gkj1.7zAܴ K9, sӱPG GyA,@h̩cU7+~{-5BG0 f9}ɾ:LYz_M\ ۦŸm}y{.0ٴO0Dec 4!/YgWAr<9<ߑ0ְjcR/˶|eL{SbPPWշ"s@*h#- -KYk$35r RBxU>2ONuG?(@ TU%`']vg'yc,"8"zк:%abOb^ Œ}zipv{Sa 9zͮ+ΥV+DKr"8WqEVzؗBZ p+ u_8YY!Hׁ? "*AOiI7demc&-o-g.\.EK~\u#ڀAT?q(%iTdAff]}VvН ~{E(Я^ +B^QO'}!?ޥ%wZMrXPy~%u@-8LkX=*(iSpfT8a~!f_ڇPіYJ'p@# H^a?tϛfƇfcjLT.@ؾU`V% 'I MdĆuA/g%jYq!̒:A+JlFӭakvq9z6MILi񣹞;Cg+/>tJ'[$ӴX+});=-Q-w>D^N\%c+l6h[2/Dl?gsڻxnϢ&"+-B|#mԚ7Z0oPEAfv|=dYͼMQ?T}V=.InIFtLZI]߱[ /;i$lɤ`I빖 gSäD'<`V&R8 wIHvoB{!+8Cw9h*>쫮5u᫕tW%&%q: Je2d>XW>(IGg0KpzRrSTZsP֘z O+t.dBdX_à?c wYQ+hq  h#.g">1>N3PR8 눶dC sOlB]vc{X[FIx7?cWO Q1ac_Vl(CKne9)NRj 4&YP; eƉ!GH#4Ym f@"|C*B\!SEo{`o~N84>vHL~oSjb&CMgӵr}8]%"˓zlX&]$G(H:b'-x(J`!MXQ~r^:)jkvZqc{Z+B\εv$W _\q(_(&5HC'57i.taCW_`ΌzYz*ϲKK-RgfcHu: BC#PkL҇?WZ5)h>dQ kJn\go|7@ؾo)o# x ȏΝ o0N `a3T. r; ?\ǸupsX)/rY88 a;\ mzr5KCn EΆ /#vԙ#$ &gXn/7;7yKo,QcbENku7(?kg$I{$3p(k?_t?glilggakeic .r/+EFOf#=8o3| /|4k ?$~~_P+\lVWE@~. &~&=UTNu`i#j r<ͭнcrQp4u}w{uz)hcbV nIF}wB4^,gPF \\cgͬWMϕ^zΚO4z@+TMRGw䞝]Ifd_0Xsm@pϺK_\ >9yf_JyoUb/]2 gJB޻]"A:7 Tw (Qڗٶ"Ħq,*(er REu=pnmy'@I Ղe ,(fXF)r(F)&|ϼզ:JfGym~c;j,VOwҍ[^*Y&HuX"Aȑ^N^-v&D%cAAśowɦn|Xz:%5Ni?(&bLh01Eoٱ80EEqu!VCE3{Q6JVrHW.vtq$ "kށE(F>ܿIG.`dʌ6 dmEӲDP<7X';㷬Yej윱"I4x#`7z~mS\d 7ޝXdo6M"-BK|}B#u@X}7S*98|:0'j8zv"KCyFsq^oq# kdicϼu?SQYyGvoA8[ u*s1e0fs5F ;_CQ>kcHSVF\,){i˥u'_Y' 41i(N&9NxgO6|lpXf3X2"4WiT'c-(6ZkWU.f ) fOS2 ioO*>_qXqG? rߢ\?^`O`-$vZ+e's]a0Cp6U@iV" rKH"40Je`Bڙݑ ;КtKfU103HF,>xJ^5@`SWEݧ A;&yND >hr7hx l軻-xd=TyjWprdeV KE [4Op]Fc s,Oa!/!+&,-er~t8>}\HEhը9l5FmpL}.~9pt yr|l0do_N|MEYLi),s~W£i *WR d*ښ``>ByCصV~>&알I} wֈ&/$#&Ѹg`& bd *lIM>IAuS] vxRj1X}@ezlޝKjHFdWE`Ȁ<؀wz๗1Lj,ЧLFMLi!{X%͒\~:wo C5[(Ǖ 6PtQ|FT]$.0:P&c#GWܪ-mqk1 9!uӴ!L~ ndw){ 1hH'% />ɾ2J>D=D2K1 B A 8O_|㏝q0#JXw APIj+}:_%lH_Wطa(FD`[&jSLwmV=^ҽ=ɘ8QtQ׏j䛟z hI,I>;V^>`W܉'8VoP@(4Y*VjŸ]TUÁ,ZQDO@Twh:U m4J/_u72K%\"nMAx|vo4L-k @hKlT-tGmNMn/C>*k}0@c;Y)mUeDӡoXc@ ZYgՖͶŗ;O%Ⱥ¼nJI})fIwaviycZ8u<4( o:(R%EHT׎dj&4TI%B^u$VGHefNi_e"<Ձ{p_N>YNޮ VrMPC$ń{7DLY~I⊖z4 E[炋c4@| {/nWnH}ټAi)'JróNд}].J#EbR}"u<_ Z/QI$"hcyѲXKr*< 1+ %q ڕ铣m \VJ3\Ś^?4e<Àh=, \9/!^"%awV͔XzC/e"\#yM8+ ,T /x=۰s5ꭊ:x [Z S*@B,*ʭs֊{G &jx jUb"#rMq{*xO#/_;qXdp.@?ߊ&شBy|,^/"ƢyCl)BQ# =Irt:sveٌGJj:?:9GNK'{aL@$jyG- EEef;Y"4& QSt032sbUT},p-s+MM> w,~_ew73 ?7.j6¹nhE+Ɠ_/v9ƧwI*#UX/z*ctYYi2 !h!ՍN ğ]NMY"?\ ,I޼:T8b3A =|z>44){[ٳ%RVV5kr ѤiF=0YD}AE'Emo`2Ļ'xӐ|e{,̋T)o&s6œʋ9wV>8ߩ;P xeҿmf<'0RTY)09usb$pgهOdH, T&siϗ 7k|-kydݓ]x I+QI܏{uLS**Q\SmQ}5:S]* 5W.N[ahGmR:'sXs} ~VkYcnb[LiYUsR0Kl2Sqk7”dƏK&NPt?U؁Q];0 `dSn16LÚ4͜~,Ry@xJPK>cӨ/B++wWYe4P7Q pOu*jJ,nwQ#drPdcTKJ2 u8Bi]e~z$#^t`5W"\UQR4h5N-`G oQ<6Q- L{bJ:PzLkux1K{CO}ilZw"p$SN&# +/k] PbSahs^MG#6|7CY&T5I0HTcGVr@Q99Flzծ᪣0 1$~1RgvSx ͗/˸-֏Hp:+8,e!OvƲͷwi٤F G\>"AxUgn?W>Tݬu]1C81&FgӶe:&A4'|б=#v$j,rel&زOsR!}OztFƔaeQ Sf'8s6 B;RrOuR0z(x[)kji>p09cQ޴y)EbSF, DJ# ej dh6VBd8Ģb"S-Ü\U0'N1)K ԵySQɮCs>qΐlAUI;m f|;qVԯ%",N tӹ*]D9=LT)NY@gS nfԪlD!Ӫ"@mHLzn31x{u EJjVg805ܨga'P˪%h>@c>;l-̷.9 ţͲ!QdygtqۭV%y[Z!\8'ޕ],x$?vXwi|j,iɺf On+Ոe0_c'7 `i% 5x2zdKUFnЋw=0EJBɭ U0}08. 7k#(/i5g aT[qJRe"XƢkаt]J<;8%eLTcV*%3!8 <'8=3A!?}A(m Alm?fa?~ceQ1GA~!ENѡ $5^(ʽMWyO#}mZM7Yxe$Ȥ#Ϭ؂h!5'OhҎo|uC-/d͎$8U8,Jv!a&M^;%YCF2%owL8}i(I=8hGިj+JzhK!g;[zD>d~"}=*UEI9L3ۈR$k QT1B]Q(Ԫr8XC-W:$Im7 (, ݽH~ڮ.oIeWtq>Jt/M{=+J*_ۤ-6~Gu}Gp#lK[ Hͧ<6ޏIPՌY JD f!k?eLda%R+;Җpa1)TD-CzgQ $"q1#9B-$4dxNڲg4zA^ >umm: Z*HA+{XeJa8TɍhK7™Y}|4%T`+Kd=(bKC&@ UKҜ$eQ Uzh.`_oҵ杫`ePt޻VxO5e?-hlBX 9ڐ=YQκV`O o2Pj飐X ,yj xcEC>6c%cDIJ sGog$Փ*: ü?`nxnShR~q=L>o]Bv6[K u6ZԳ6tM\ y^K p? p 3VX?}紡jZ3Ʒ#2b3̫Ed|X쌽 yZk!26=yL[.~{,D!kn#b1&HH\ʚ} jbA~<£Q"UU5#s:6^Uk1]l{Frc׵|^J7PK*ļf_q1=S1&=&`Vo;Ώ=3aseH)C܏{R.햤g 2ݙNC9Z4;i>/n){$5(0=S2{ˠ?އJѻ5vBM*b0ڧV"m'\d0ʭґ D.DƆvsr59 t! eYS̴VO#s|- U>,.πu\#poN ;)9Cj1Ku6Uv {L$?xr%NGByOȈ[^^2cW/SN]E{7x:'P;܇7sno"X\>? &A߃g?}gfYjP`MI kbJ u\DC޷fU0R" $x10& 9SZR(EbZD(; nſШ'5̙_.,YcJjö"(t ܇z,q*躄aW&MsDT:)¦Hk},G#[V&&g̒GHlktձ5w@|=<ؚW1s >ݰJ0+gs ;Cާ_soWu \/" .Aw ݃;݂wt;MMOϽ ucu^{ZM4 pP-{v#|Tk c>Զj1V-=zC,UYv'S{0G@;}tT-%Y17g2o,_i}xY&0Ό$DJ yY1BЄ|U&0F2Iʣ\ R 9湾]*$GYzQODt1<֋ߨ?:UI(1{9` yS2 QB.?|C%CwʴۏQLFVX>oEV'C=tzS}SsOSl6v rl8  ky$ZV.+d~D",BJ {ϲ<ҷ0 _o$!o`4ui'b Q6XCBO;iͦ3ySd?˼n`F_O1.s+~译|0` "41W=]>h .6fJGl"s(5.&e7-,wϹݓqZjEj^%K) #lGI݂{Yl*D'T< BK3sSjR)u7/!fi3\ݧe4j&$$Bn@cٱ#c%a Q &W$>rI1\q>~Mv̯s cXSlRG 66pu>~YVKyP#c CNjpi\8 p'bjjy@%k}y<$M8 N\宅NrA#%f^05>ˆ+*Kv Y^fDWG2%ӵv|uBn{ZRط;|;Ykvv䘯l(>+RQo8ԡbޤew( h`,ܺbKX߅kú 5W~۲-5š:`pu 8"u<NUjvUav'x=~/^z]z2n305B˔Jn%:٢{-^YU7s ̖G( @76QcH×Gna`LV|$T9ڦ"yD=huĔ7L]J@1ge.cرߪbͯ YFTg? 0a%׽܄9πq{YVg1=kK"܆<\k5m{_E!XVʈ^&3MueO+?fOOs?<wXCc0+ 'uTSM_UlT(eGr*9%LYOUn_/;05y:՘JbwTVg&`tZ C@Ԉ5vYO0UV@4ܦ>X>E1aaMKČK6B¸;Fv5Z&:NH $")jcxG脥5ATOm,ԘN k*.ʇÀYġ%og!bU[Q|BrP͍ 剣>%Ī~F)s4$O'QJ{7aK4 n5W**ZX5)C$_ I{aGSJ^w6lmp?˵.s{, bSq9Nk|Π'|U\M0ADT ண`Jܨ,%AlAn RZ*$s›U% [`lŹ6wW܀C( E:W.^SAڊB\Ֆ6Q>)6TOF<˨Yw{>:elS§X; dYѸΧS3o6֔Nǫa& /#:ѓ*2¾ʻr-O,"?ՅdnFlN gUy{GpBhy"b\[=M58kOi#@_zk bM/iVq䂣 O^&!xMԚ!t!y 2v- ƖE8 lT:7{h !H#F*F^h,ެ)_Q8j%QK$7Br١W5.$Kkw9ܩ˶*@Ѽ=8V\ V)x4l+b0YIGO)Jّ={186`81IT|1P47!d.ͩO SSwaTeapsv_vin*uCZsU3|նy}lKs"&eDU֭g]'Ocsʌť̼]`HffS{*~Uڶ$LIxI`J(I]Sr% 璆ݭiWi(qעMvFS[`l:]G7_kӁsf|2^;_+myw/~ _W4.-͛.7 exbgl U(Y0.03nVzЊ_&X-4 ~1=_W{O=K8la+]nz %GE*0J~xQI *p%ep[6#8ڰ,/.Dž%Jv^0)v3oi훹#9nݾMSN*3}Z$/_\: 9{ ٝs.){Zm- |$WZEhz/>J*?nI"njˎ3;Xl0m7ьRzpefFBdI[1e'1z(mZ"9*X1|WOгҷclo2n6drBۿC3Opvb)Vn7Hȳ2@=LxWL()+ҥF{B(zl:=Et~2Ws-gӅnYbAZYv8wJz{=Da.!1߷<~ !䎐Sd?@iM)[Bcd%[&mY:+EO#x[Φ#l/R]MbֻU>8mQE!.װ_Ee1CD=ˏ]5T&KuVҿCDQEƢ=c%aPDEv7`o/AV$ Htєڎ&KwT;ك=ȗqV+|6Pxb$ߨY~o۝kW=#h,ΜI1*" c< ϧ1) GCDOhw{J#w8^yn @M0t#9Zã8C]!,xT;Βm( O0|9C^IRp4J*0->Sr/}:7GUg#N~},鋣MU\+}ǭ1|ͧH;*?By퀉+t.J`r[ = qJH*x,Q;,U/1Y<‡ʁr-0!;[G;XIШKj1Ijrv;ӻJW_JG?t?w#/8(̶i:M^I3rV<6y®R+Kc* ];x@0jz~V$jh)˶ߡwP{R1drZF~#W7" 60?Mw wu}U'nU'v'6>H>7oB%l "6+ˏ#p~{P``a{pMc~0o/n!1 ;D@|첲 `E7X5 `>hY9,,v(ئLހR|:<0 @``?ʿI/ꂚY[XY1X>2 7." 617?z lhjhfn`c| ǟ Oƃjtq/ń:A o->q~b40Աձ1к7:=ړ?X=o 9`v G=x: dJ8XmWHr?sQs? Qs? 30~`WSBw,iI,%SE$6Z)I||}2HOTp n hϳ-L.2 [`]s=_{Ѫj0FllCe6G_p"f{(F0*aTƴS,)Ryͫ; O!@T(3z TwTA/D ,i ù7hsH,)~ 0h/حk]%b"&%I ;o/jy`fCV"rA(3'F:@8W;5):)0m]iuaFIlt0܇`4[5>'nܓ* YϨ(}*I՞[Q5yϖbݣpt[PߩCH &gqP1T^2!bGҫ @ŧC$3O1u6336NCY%a/*EIʣNI{;e Yҳ 䎖T-v\٣&sld++n4^(aAHVڧy~7$/d=]eS;Js05 u*vD x!ʅmXGff@` '솒'~U?\E-.%^Y% 3-.<|c|6$>)i9Zn۶h%" 'MifQ8\֫w}ӻ;/^O㾀o_=:%)5}(JI2.z*q)d bg, G4YE{j3Z_jz a^4XFPSXS,(dZ4=!oXQ z a/*}ηw[>a( rs,c~Ꟃpz:@}{x2݂3K6X̞Gm+ lM?)N0bz+Lqmf2]b]30pxyI|(i޸_ֲHZ1lxph>t~2v[`J_\|I Z;M٨Ո Lw wR[0F] si mh }coW4(x>dw_ߵqCl|{vdxYܼri䥸ؒJ} lGsImΚ :_=BESD#ۃA˩ػQ(^w7ݵ(L#z-1)btC 3U\/i>C?mLli[[U(W#@2 ĞKzW3Uc =tvixqh KEC=#7֨HVܓiY)!RTa]ft2z}u_&B5rN`Wx5EM˘!WXS}LUe ),&p5M M`yu`I*.5j}33lĝKyzw:z^ Nn 6KxX&ˑi3ܔ!i8MݼY{h=x{1c 6`>d߀O{x keI!rvNlO8jkP=,!O<$d,EyHSB4,]yvI l}ݓނrP[Ih^1rl-!2 q, 3l˲ڴbxz ҡFt>tbw\߀$s8wUVlY'6ʳ-jwhg,ްz F*"%ב# BjDEh58;#qMxe?rhbQ |I쵻8AEsy][;l`[C>[)O+]c|7Gppppq߄ ~.3Ͽ )p? 3Q鯚^#2 UsQ|5)c[2?sVAv&LDŽcs]~V}7g|Fg 0jhߥ8y:mOxiyK~8 7D$ahi'pʑaU;LS<ԉ+Kvt1SI,<>A?Ң)[0lLdd-Jb,9DjS8ۗ4ssfc0 Oq{VKEXݛ_ݖȅ"5{ `{VcgMhƯHH(^SHLÎ ýPA)KP,HRq66T׽L(A1=9뀯yCD I^!ڇcfhXH[bݏ{P#SWPn4H75 O|$Kb媳+hrR$ /Gkm_{D@J}+^zS5P }2KM4|sV {H`p&ۺmz?X0TYrtVH,uuywK9J'dJ1sCSCov# ڗ~h 86ӷ4|KZ "]z嚱Oys} MҎ2b>t4p^b 3giBpʨ،voljX]QuKc&Fs ]~'}>RcKc;D=ys9'!fu?3|rw~.ZKdloYлYAAfR[贖SȾ?*̀wrgԸ`/> QZt6oH[VycNR;W7C5=INCs9-ob}[R(K*P%bkp*[W-{}m]8g̩cV,RFyk2ۏ_H?m#׾@r7rP{E6͉B~NJ0(6{ºr67[t-܎iːk kDv}Z i7=AeU!Tם4z*3ܐE۔8Wr5Zaovf_b{3P OIaȫN*wl!'GV՘sm\BW<*n&tv(dv!&xiƐ( zBBj{rŀx"E9̢Rsgm]d8*ͷS؁4N=SOGdl_Myt`GEǡOB0|euߪ5jv]=@3Dx'p2a4H#xq8&OKGp/GJp+;)33+_X c_$=vi0Og? fgc{g'cU6DA\("Y~Y(Yu\%ۢ2J ~ }'v^n\UQ #;&H!1]!\ĝ{bwb|ghg Q)1/YЂW]g?NX|y1hCBl [+р?CxW%){Z'RҼvޞ۔/lUp^H#/ʙe xRXlWY򸻠X_GgDɁW0Fg oL\x6j6vnKcҶ0U;`e&*o9D{GDXm:V}֖I_, r+ƽ9tu=*B%[f{DxARL}2?М\Z3^p2$Ĝ5^YvYJPZl>tNq?/N*Ո^Ʉ")FM@\RP,soG\R%y$EI*JR2X$H%諃vaSB~v]kp3 Sa!ՆHx)B13JA'E):i:y-=IHG({4YGff( +ѯ&uR,VI<..[ׁ Vj E}Ql ajlsH2|\jI,% vi2`nfq`Z&jZ{ׅ~ѵ~;y)g!wp4b䏳gp¼ngS2 X9n ͩ~M't!U)e5lBv0y賵Jjt,f7//di vg2qàtgevp؂_i`-zm1dNXe{z I|uW'lr :<4^X.x*sv1YJ=b7'\2Hb(Y؈Fy,紗ђٛ!;p(I<+%<|o=&#ЯyUF V!y,&̍]+uڣ bLŜ.r>'#6zǧU|eZ\@}M-i?fNcv\=v%C}g;ʯ5A yhx/$,"'3i^qw-č^Xo}컥@ߑ\a#8$ r/ N5$ȰbJa HdУ;dl0v_S/-dys#}77b΃|a_[]g`-̳}G`z%b fswLSHwUV`l'IN#8Snc甿5s9kւc'>|@33YJ6&_ #}h(> 2/>asC_zFF#Ocd㯴?lY4+cbz\h,m?4?\-(Aߡt6_ғ"gfթP%suՠ,Zz,zf6pD[K|)S6iC%.~{ CC%*N'$$ײ2/a;"" R-HΠp8~U9PZ][Pͩ;#B^ w/!HG›-h>?F8(1sKč {.ruzܙ94V[EsXmCk‚?Y`!cF^YHLOzCVϾ:QQkQH +xy8/۔!1"sT&nӽDo|'z \GbzZz*"cuQن]%vDΔ24L7mR'!C XK l)VQk|E8GkL'_v,Ey;g,rg2?6 ;P<ƙz3#6R$e8US\p b+RAUb}L,x&ct+f$̂9!p융ɆDvfˊQ_KRWn%1D/)sl@h10"jjk7hv9))-N_g`(Q;C /Mȃ@+ me fvm >u@$@7kK|tf)eb 1F2,]gq:9>>T^+TQTRWsH3LF/:,"N1O䎒}n/rboZ\hR`iN;>ErpA}pif9S`1$XqfOD֘cwy;p=4B$*k}5_]s:\F>{} Yq,SDphM ՜:dYMWuކuts~dpu/sːGYXPNb)ݵ[sqeEG.C!0yGqK~"YYUV2ly)wuSri2lv&ڸR(sZk%6!zUY_4-7j83 mHm NXD]BKk X DZ}gғ=Vv;m' :ʎF᫳^z|EZ&+Z*<\|@*Ebqnvqi! fu ͼG< ,#jrE%'i(+dc [U/I }(A @S#s3"aM%bǝ4Qz3s.p,\~GZZ'4iyB+%*3 1PNh{VaE@ޝG |c.;N$+{ :{`r]|1ڍἸT}>ű?7~d]D"$ )ԳEE6Փ'Em5FU^|ǹ$l";S 5DХi=%ˏSI]bf& ]0B[ -bKS}s\ɷ27|DٕUcH]|ũ(4o::y2 /99~fOq co`0W0EMM]8aPdYijU'8R(XL:N7L!Vݑ>'Ag1m7|>Cft=_[#0G[k^Pߢ:v Rpzώ3}vV68ygBRCMX`Ƭhv2R;'#zhUI[LKfaja&5sjV!On1 V j\,w#2LdKZ|(kq-{l<2Ty/XlW7P3 T{ %! 2٢9K`Q­¦&͟`M1 INZ./&}u}IZHSJ>IS~p tF ~6QBjeH֕ԎXܬ6Tu !/$Vx`bn#O .;Laeriw2ho{_dS`2O-<7O*eCB3C8&b++󹷋-ϕy!ᭋթTT!΀B]7d&AEqRp&=>]6[<gKWͫKxo)W;wqCN*E ' m6]k:]3C,kh#DC觥`fWX}b;d``B :y=1.w}fKj#ѫWx.(¨8"DEU/fFI"0{>5cUvSB}2RI96fE2:\$,=2FӪia:/6^_CڛsPS:(kbTyrnwX'r+)r;Ez-&wov(z5ژK⟵IFt}1:I<{yh\BuAv8M!WTv{JdPgy)Uԟ7.Wt2Ъ'h_cI1Vm{9_?\i&-io45Um+'a˳l RY0eB0y&5۹H/$oKmjjJA($x~\ 9/@: @Ϛ06XX l 8 fݠ7ଐK5`e+,ck64hp)La(TyW=)Xq\ 8oU2ghm\h8*, \u6[|9^#I[ u}XkhxٲShFF FHJz~d")lT'KX/quB*q&Yϊ*|-&kw?ݞ`o,] pW)ּ%|G[ŵ-kA!'8 醦w' ]/kܽrֹ?`>dWM$j*Frv@˕=S늾KDG]H~kD'@݊ځ bclq0?0~1:4L_-n: /T)Zub %0=S6v`ɤ39&{eX <诡m0r.JLנ?'{O9_Gވח4f9>_'TNW2[95lQpn/|]# nZ"E36$l^x*eQNDaWT"i4;ݡ-Q&;zJ5OyXewX]7%s{@QI7 ƓX#O Ď@sOLN&.S4srU짒=aݳ$!gX}{_ul>] ]gxfR*X$VH2"]ldǓgArfw~k9+AȴYR۵]x߲^A^Ho};M:܇I=24jC˳P~l 'Sa%(g3,,9O[FU25/*LO`oU`pME6-4b<B{0iO;Tj({#i$Y'\ ֓>h3rWUloQ/g55qL #U3c 3`Tt:\(eeOThEYyZ(alGʊ |I&"f s4?=e:IVR~=JqkV~::by[8w:})Yȳ9bbBI#3&J <c`(qNvԎ| %~GպSUA]!S428Vfh'o`tr}ʛB!"+6QիlGY/6_~|x^Q @7բ )(]HsY(բHcn ooECm/ĉQi:Xnfdɢ VbY7%[5TRp!UQ%dBu Ab FJjAfz=jPQZc32a'EkZ Ͳ7d`d͎g:Ᶎk;B(1!{6U98]/{*SZstt)>|(^4~bþ0@#P,V$`M%+y6"MmV jSܒ֓ŗDZЬu >ؑtO+imWZhoWn{#aN32.pO9}K51u"!;X?j',aiao&<.vuw#MF(&tg,wMr P2ZkrKvpN9QP#޷`.ӝ-;ΰ 4޵)_epVܘ" a ʇA>ҏGwYqwQ|7K_[[bFoVŀbqLÌ[e'b)LÆ3Ռ:: (ɑN̄rC%k^Z;U;ˢ[~vδ% [,8kK &q;@J;vOhW F |zp`:Ȱi|5ذ$~pdLx\q$, C׈J υI.0F(%eK֔:Q~;#}t4~45)&7@yH3q ȆFu$`ncf/88~_醱Y4aƠV8\#W[!d9.$|{O]tkb:wAv'vf!E)D'8Dq2yE!3wVVzÕY@Y 0$e 3 z&Z a#0  oXՊc}5_ wmS_3A73f"Œ of a `iM?UU UU/TUh%/WUAG\-/Q1M #v)b _u'{fc߻Ս Є IRA/!.G(*N5";,ݞ 0e0!/>]|Rj vZr=ʒEu ֝o֍Ln_"crb@WT+up5u?=Ky* uܗ> {#< XHxtԲ0!;_ XG2]=Xhȝ#^b&<;dvr|'bu&/Ru xrބS 9x%ʛ5?Nh3(r&'ʜ+e@$o|N_ysb<_/ BIR v/x<ƘM5wE!j$ļ@^b!T!Dg]) LL|U2Jf<נ'M0)3bB[?K:HϾ"VOK 0p\;jW}&>O?Eec{TyCҧ;Jh 9Z{w\u (OSLQ &IH.h~RLa+zs-4mTd%)RPc&3&{Sբ6x ]@C>ŋS cؤXܦFm՛ee|ec6kIsq̮<1!9_޸e5WⱟIXa)V-h"EtmV>?jD|TTd2+ĺ8:C˖d%`7i[!}IO`DN(\ZuHK2:%<0\%ϕp=ƗUwڜ kWlvR<|z8hQCFxبMD9VwLh1Nc *EC%qR(ƫ?vDı X9w KIg~?56AΠiMr4~z!<zz42+ C?U5O#}%`3roԉ&Np+ɒcSS;qqKU;iʕHN7xYcqq·wvol##aUH 8,䂄 k=c ל`1vt-%RRKV0T%0!Jj[jM[}cŀ 6lH}WZ/,Kc}F#3Jp~1%s;;'q Ba:7thifWe^h+q%0fDŽ!rX9=mDx_*-TYSWuR1lmsęPW N&swh_)wA#pl5PaK I6u}澜9*%aCmk @kʈ9489'<9#1K§ccvk0@,}{u!;N_M6x/π}5xm.K,C~4;Pgww&)H3g<"2F `dg|@Dx@o_~dsG_KwL2V& /`?0~Em2U 0/G*fswM|Py\ki+6/AO}d&1Hi4Dzv^|&?730sJtWih1*BY!"o]TcnEϺΑ{_sBd^vzңO rRƼ@+;OX"6 fG%EQ ogX Fލ]F s&Z .zP"4m~'PI< &~Hfߎb?ͪb:&20's) 0B4ȼOpYQX)_Y-:<)jڋS{A#ǎB'2YSzwHj&eo'G>5 4ծtڍ*c<yL=66v4*9$ Kk/x3kxtegy @_[;Rtppq&VORs`m?]a];vj_KU4k,$jLdCJtnJzI\:q_E1 yџuÚ9ƈ y.DB tU{~BE E7Ec$W%('/CG"_N Vxv&.0Dt象Xױ7MTsg9I`6Vxe_mf&9lQWL6*DJ@m]dєBkF𞜾g@GWL.~nO;VRPމn3gJ߼nZ2$oiw6l: v䂿 l!f HBl7v)9t*u|-x{zj]#a D­mRI9r3Ӥ네]\6^~D#޵n8~3(#3<9mUhg߻j|{b;gρʯ FI.'uLKmW Z# j8+Z??O<;CrysF7bg]lKY+K*YRP>5x&_ߓ {I+K=_nzYPJ=vxiyvQgFD=@+/g˾T yQT ":#[*Ǣ'sô i"mp #S_(,J2#н, 8Q& ]RA;m+_8A=yS\FB m5 d~ܼ)hd~iž3&Jƈk۠ӭ|::rX+ l0#2ڬʓł6D@!ծm7^/f\ +׸IDl\)DO5 Vד+x+LMx713<,c-|+o1;Ųc8}DUv\3&%n}p)j9>3[)>Su"x?V{G^୵i Oq^ȤpCiF`ƚ sYyxM1? U3>[f< {MVBUc}Js7YejLvԠєms[7+ Ι<ڮP w|]ٯӌb X-dQW\Pʽdg2=m?|?xeMpM`?x 'E}Zr.h lܓk5k0/my7D9?F [TvƋspR9Rǧu ǚ٫J;wH5`ٳO܁Vil)p#;7`n,X=.Z*gg`>rcOJ8$bxT3 ^fOI4LC/}>( qrEM-F̸kdG fB1N[n :{H;Iߪ/ʟJDG'X8 o0M}{u+}[T޲Yֽ>/_~0~Bf'(OOY&+3= a!@&0Y̗[I! E5dmexk]ff?X~/wBB f1-O#J݁'ה+A_)VT~3.MEy_d3'f;Ƞ,;svI T;!FlY͟ }5xŨ.{̉1{;]N =5"ڣoJ~\LXm5TyYқCOt_,\c菎Ͻ͝ƀ c%HYu{GF&2\5-[y'lQIj4^vQ{t!$hy;q2@ɋXnxt62g/hsDq>9XZ# F(PH/`3[VTTT=6[0ߪDz~ǡI1U#ZKHh&ԵaP lO5P%>/{-mRXl@߉W<3%(f'^;Z5lv;-T[>T N90c/M~ *;bCI"1xWq]ؔ"lo&zLZ&&d`D9 $sԠY?eF#+$"BZ`6m,Y @Vzb37_د!d4Bw/Xb.b!ǁ )gzy 3b,t=UW zr=psUnbZϭ8.'"et`uGzf r WNcCߦp=H 6yN4F(EroARjiC %P i6Q/kROTNpx1^cg+ɽf (f}rtih'Vj+÷Cy16LFrgϲ*/Vr2KxGpVLXh+s"QG_*Nxm ,zDdy蔢ind=8~~ 6Kʱe񍛱i|HXQ~WaTQc.U̠*ׁ#e%cw3FNnS<{iһۊwJq)TPRP60Bآ)^c^%\t1\t^0NY{9Nw r%F9Hj@Mtو_iٙLYkWuaXiD>¬<g6j1*?)'D!Ʉ*Vl3hf;nZwr7dWZipJT0xҞ@8cQ2y-IL$lG@m@=EGO l17՘o-MM}*bEW Kd:X{t ` 7;rr̟4Gm+Qm FFv$ ׿Gtl1Lyj63>]w(m"^y$CKhU,?ǁY~ ?ҿz[X~փ_95ߞOٿj?Fgus1UĔ$~nyWG@425/]. M*1={R}۸\, &8ʬ~="uZ4T>n 7݇jm ,brQuCL*0hWRI6uI|n}g**~|ʏ;ʵ,Œ%qa:D_9{nOǩ9Hțz1K7X<~!<Ⱦ:jbkKnu')58a:jl FJ mhVjZI[RD>T+lo EiNx-Oq 63uSqiu n5>$w) epQ2z+6vwUfE, 1ǰ>PMt1Y#> T$Ф;j1/83ҳ{P<_ZaU$rY\ z[M2 ʹ8qek'W o H ӽk^$r=TܢOiWc{V*xkvȴi=tmn {3Td9'r VQXӒpp4ِ; ?>7bymn5L5CV9lKB}Q;HS1h{d^;/_DiUb}QKV%%᥷L͑,6}vI6^ zU'gR"o:]rX%eɱ 0+#V50oH JS(۝ub5{)naJ,{\ŧ-mTWϨu3GӼl,} RG )j="} B?(/l\eN?bXPl:i>D=Jb+.o!ԘQޔ$I- [b /4lPaa>,|5_v?{IxkZXzx;09}nU8}OBBY`UK54^xcԙ=x+ͮaH/LeB4mw<|A^'!Dc|^\(a1YkՌ3~m8Iw ATF ٷxLsL,$U#mB.-\cզ{h'_Aؿmiۆ0pǮ_K7L?v R n0$_NǁQWF3êU$z:]"ѝv._`8ćR ݻ=h@BfÀ[yz~f}&B4wbXŗKwؼ1OFdl?C5. CDA57·WKYpDQo뾣yZhHLT:]UWqr|q秼}KnS6Oh$ȨQO^ѵ^53p+Ї fOO^@6-=!%S%*mWscٍv\פ6n/jLԩ/17P݆]Ω޳8磠;h(PগÒ2aZHpU飥NEncoi4+%9_ކ=>jq>\z7͖'w.*휟Z5';ղ5ќuT Ӟ+Uvِ'hPeȌQw^I)Jp3LфtRzLx^<kxmzuX~~>5\}zS˹rSR4Ɏ+x̅)bOAy:f[{xQAbj/@QW=cES{ o:>6#i+=7@Q\]\RD)ue[GbQyYtzpz ȋ̡ ̼j=1 ӫAZZ[r}6uJj7fZ5uBvHo ].XdŕzGSFbNJD6 ςk9c]eǼx [AdwdxNO;ׯFD.u<ܮFk-' ,78zf2f˻kEr owC< M֥%d%^Wױ"P-[EfJՌ Y<;Nհ]၂,ai`˳Ls 5X(+?{l y)'g6IےI!iK照p-WJ@,֫Z^=L#yu.~b܁uag6`&#HX x3O .֤R:Y'jR/.Y}+nSɢ׋&> eVg@X}= :|mo,=9K}[īA <S7=yeBw$55:t*SM"ͼі(L9"]6ʒ)i$zVSZIȴt1*xjN?'lmOTm/yۢZg]94eW-N9<8@7"JzB鵐%^ Rr n _~ĢM <՚2k%/auF^,}L@DP2ܒk\[xh>Y㧌X:ؽtO9aKވpC1/EA_ :eD?EI  '"TK| dhusQ3+zxr0/[j@nh:$ hkEhtwX`*Ӓ;kA*AВv?w~O7JVSII05ɋei|.];4ӁoOj ;aVnnģ"9]VОj XUɜ.q%.`SܔIU !JJ6&|w/K _轫 _Z†f@HxZ_9._A(lHO~ehI'>>$^hhS*4H ,=fXuV&ɔ5|uv&:W&{ .V5%<Á_r ܣn-։U@hf<'yppw*Q 9"`[vy'B &[铂;2+;#4kH+{:[d!Yܦe+DshpdW2I-mFPzxMup}OǾpѻa:F#:2c9<'x|>iE{:dl{b'hJ,'NP5 7#1YTRV"Á +nYƧ "v,nfe4Hm&_s Q#9GGuOxj[ǒ:JǷ(&"pDޠ%y{%Z$87=ȹ6<€#* 6Ղb.gjqD0*яъxcf xY,q3A!y%cHkG!L .XUbJ loR 4`$]]0B~KJt0x]FcwχyH FI7,C.[4>v~u]AGE[|e:?%vE͍>OE Q;ǴU T =xx~ XBo'\Knr3h1 8Sv^[N2w4(E/#%5/I cZ3g:)(Z%кF+ɐvA>qnא5`hm2 QCVH [t'6[.vݛΝY Sݟ_oD+?Ħpya^.^;~Uh2Smx6ӗǂS[ 'n@}C4-zz9ըJ82-JrV|zaٶ'6W^5Ŧimt5 n + +o}:'^ {Gα񔏧>dq]kf;\ل d$&qrSq9Msvgvчc(ʕ+ [ZR23^j /AOOxι(.Mo#'e ٰ MaN Q^Ly\Nl\Yu_̇Aaz}5`u1-Ro^HdQ CB&f;~r5L!,aFt bs(D0>;h`-k|\y*)!k$}iS[!.`:/*QWܧNxf0zߜ 4O||3w{H?1o^IroTGf!lQ&Q0&iP1k3<qH|"O7"&4n_Oؕ] (W߮ѻuW!T h[}˒)azbr~8־6廌K{+_G?N~8-KO?9?N>CIz}>IylU'?`AD0L^2 w( + saiVw$k&cг!$ 0;<#Õ7X~ > #w ҳ~byfeA GX 050%@ ԘAjg @iHO5P>B2b?a۳`3156@^|߾5 ۞?U{X%C/,i_T 7,;5=b󰻲0=lh< >~>Yӳ2mԶ1?, '[g}'N;1p o - J*3]A _4@ `ޯkL{w75@`e3~=Oj?9_\8T3=ӿׂ~r e}XXA_ E Ld~0+wLwz~9 ʏڌ,3>4Oa~x B3? io7Vo/;J]%v2 7}Blqgs| " bu<1o~ì2W/fxKӹ2u DICy \ovd5q#œ#C[8juu0PqҚ=(zk/\$\J8jU++lS32U{caloCdgut(C,׈h|c-!p$J]ൊͬ=q8@Y4B<3rS9Y(P[f$[j젂pe෎/Zzvfr_57]G$7N2^oo#W`#fd/YH n\ۻC\ M/Ό<:Qүҙ2}a|=h06;M9|jj !_A=JKLtEGK;RCzSD-{3 40=XzNzd6H$j 6WQQ"/r]k/)l|~2N/2w5})H3S磥*i)[(Az6֏)ihSع*[?yTf%#9$<2`Fi&%09JUp{S3AzݝWdއ=!pXGY˞TN =e R_N L_ Y#Eۓͼ2U ޢDxgF;+vt%2_wE֟m1S2IJjThS;?sJti/@L hI@x{>)seW?,MLY^}~JoZ`rX CοkA|9m4uFrLrXY9j}7G'Eb3r9=hpЪFe%=(^ J$p2CtT)ԭnO p`_ri9]1%b ׸Uyl5Z քT mzNyzOpa}&⓸͖(j$^ޡeڢ@d(ren6jGIb=WW%6^;Q%Cʺ%,}t9GIOYː}Ygc pc`oײami1LDpr-AGm)R~MʦZ5F2jXri^ 6F`/yW251^ i(nk Xz^M--\9ʝ.U.I6r>kM9u ids\szQ7٠apq鴅5a-AFV0WxE}QxGZuM /i>!ck+L_Y*r;Ë߁`HvǔNgN!=_Ŝ(1h"G0aTYO @Ci>24ҵYkҳGBN$i@19̓*[dR7rB汙JR#I<&˝R#-DˮrwރW*x\ܨ~rAI\'! Ge$aOs`PPkB$ uwz0G ]*yEHfBv\0J+\}Xa8Cz&vOyt(pޜܹzJfGD=!Q3^ ϏJa<-(4%e@!x ,sAEq.P1_'Yf } 't}P6N!G}/wHXuwrH:蘆8ѨA75j {z*q%(eG*)W:HQ({ mWjX/ R?hbbPz>N$p(BRsTjEJiNJߤTyxww%'=;G==wp-Ѩnmg tONH"%~4hOb_C~q|M꾕8,_/Wvan&o~Mot4ٛ;}kKW<!kBD6{O@e  =~̿խp,CHwy_VYbGi;@y= NE,ʗȴ0tE)7>v6u%eZE"&}=Θrly~nwNm#¿UzKE$XR݅zYIqְnȭ3wrp J6 ZXak%X;mw"ls t70*;({?L"Rzw;j孼&ċ(rEc_wg U%fQn;܃rsILQBJ $T ڵA] KtjMbIc w{ v^Q: x{G2ӹ'Hw- :vuVDE'IUQ q\a=E91 XF E[ U&0[UY&o48 \SxLF Vg\| @uqåNC<*>Dm4uI#tTA%L,}=@-V`EMu"-uk8ӹ-gB:%x%y20%W#80GOE9u`kN)AQҰ2!tSBtK!Нkvs=1H[^ȨfэмN8w`e_v/no[`E/X@@xgcڃ}(< QG4-%&@LհxIz$mTWI4Y} )!.p?7 ΠpbLp>"UZ-{'24Ӎ@ [@vkv=${e5LpgffB5KՊWKc'g6.jx6i!mt=_L׶Gm6{ hX~_3=*8~:)Srt'뾁?ßf@cT`VfzvYkYALUUq6"m^8!DXժY_~S [# vhX:xB}v' gzKG?ry,&O4Uj vZORVQCA +A 陈D_';BcŐaGdb܋L/VTc~ [fD2ѧX .JWݞI2g(&,#Xw9'9c%:+gj4I%7ݲt52gwZ𥞻Ef$_ˆ2;q04rMI& ىe "vE'zg*^j "/ɝ1  3#ڟ*D+E@%ou(Y2^`H * %rWaO)Kh_ap)pwԜ@x ;Kf^ZAEc6P禱r5"Ho/kɍ.Ns!Fo5~ZZ;ju_֒*qLLZƫ\şe+ !=P7Y;#텀NjgrK #zK9XjH;ƨrW/<\P[=)&R窙V@!팪\s[pKK$Rԭ:$Q-_0NofxG0NA{GWa0Օq8鬪U1X SX(m>ո eAl`}Cސ3#9nTԪ|k:n)3XiT&)rj!`|ғdTr^Fmf7{@)z@35$-Y-&-DWjwד{n]/[) N&k_'lmYlv"$D| *VkU {jIKyPKy&Ƌ)Fn1$1M|xhdu)3Ԣ/̷)"TFahv5#-fR-ˣy#k [.{[.:V* 1AEˣuq-g7RTHnJ+?.DTaD( k*g4 ~$?3=#L oSrND/~Wֳ-&;5psҷO`nK?q  E2#߳}owˍqsu1]EE9xHU:3z1H|,}fqavD4fOyRX)]ܝSۤh7֎ a 9f`œ*SF}m>lSݦ;;VҒs!"9 KG)^M8{Ut!֏3:K:)q:,aպk Ӆ)N"foc5aZPS=$M.n*UhjפI+xμQ˧ڃ(t}FkNBٹe " H!kYz!S:U*WPL8-5ñ#Fr ,6,<,USA6_*Fx/xRAމ{,<<{>9T4jޤGV{}43_*K Z1:M]m,1$VpOol}ƴ,$c3}83wdb+B>7tz@i3:h񸝏45A0^(l4rbTg/7-2R̆R8e0ʤg( XiݵX ~ W%vt:݅5j[>8WmE[]"F$7\w :U?_@;0վxCHA ٌFEzY~6u%gK¬zEXzPܢ9:V7L{)Xw&y M tVpт6vg" ѵ1⤟t!ja ı@HS'MU4 ^m a6[jjjS *IָrOlh@PՂQrw L`?B̫Cp8PfWgR$'KbC {ks!9TpYV MC"c#ʀEh㫔 Vs)>b/T.g`AӠDl8vf0pR*1vM}42vZ|q+*Mu&zyL"aǔ/t,!wc5C:Y:6t&-GXc] Cke8ĬO lX$ϭxݵ;p#H{+&jE0' ?6S inKpr'xs^+wP?%ڟ^ e^_s1ܛx:^(,ሇgdF|u4cyۼb`ǏG8Ļ=54ڙ`wP5דe-eIOƑOntqEJmVƎ\. Hٽr=*W6N 8l/=1^kR!$eJ)$R0J?5zbвnO:!6j;5;Cc[U UBlZay_:E*(t 7?[/-16om }~;;W` ;Y/?nD ?'+I|e_ q23[m/˷I /6~Yuɾ_ ̿h [c&= v Hmό{;0oLo 3̈́mĿjᑱ~d喃*ɯ%jek"4v־cp5cdda Kn?駧/uA}_qң? V{VѿlO'PPOa?&o+r0VHFM~t}܏acPb'3LmJ7Cf{FTeNDfTt&6REGX#0qFBX5DrLԧTlU&W`;">< ~ܨҦN`s3C[TDcj/;VaprSCM25WMaTPə%s[DcrX\*WݧHQQ^KJ:W:iECrhZjE! GT,ι!UuH6IȨrs*LqǫS\|DEV**-)= !4ŀ@i$#ul^* ARTVͺ66 vu>,YO˯6UDhZ5[`oMukatk,IW-@Hآޕ/V]xqzrB4)'FDuVXˊsMPms0uU\L̈́Q>m飏Q9M1Ee$}m 8jP[cDHQjKm|g'<<}DbZj P mMJeQө(ʡ.`.K2xuvݣ 1pf^1Z,:..J.l%_ : PQh[pyI"ͤM [>P;FnFcH~"c.Vv͂7ëPuFr:Y c|d0s/ çۮ:{^?ՀV )pشe"?ؓ%H+3We?I{DbK|}Zt`]ق|ez@3|:8xpwN3ַSVn 6*zp6VxzJ;E'A>kdxoiǠ¼ +Ї18\`nVZYA@Hz&q]{EsycZYi8+sekF#FeaƩ__p 38FNztsgB3YAFpւ'XFW}@׼1]֯"'8~h!θocO':fF:ui?u}DA,B!sy.,r /_Zb8b|Kdh_ v5{r6V)~ap@`&M{ԧMvp@8~eUF4Zg :T8 *gɇFOAҸ(cofTF穒IN0^(MU'3R=KlNL]ΐ%ݖqO^.~_)*4)sPE_JJw{N'115Y/Q}zlf3um(>r1jj%y‹2 7h#\u;%"GK`TnęvON^f)daEWO#F(Vip|5@T ~|5]d@y5'1[U1t[aḿwRiu}8/ܾF:e|'Ȓ!&~>o~/x>K>"5eQ(C-{Kt Fb&ƻ*. J5YW%E [jFeqUZΕ)撓KTS>2[ڋi9ŝ;g?y3F4l KԎgH2ɫhXd!]g!Q|AP;ס>5~^@‚=%#B2'/S!wInEM<^xiZ+7-+e* V/3 g(8"$8.9Ʒ5FǖG>=kᢙ*P=S^$Y-(V^{y. ooj˚<2~,콎Wx֬q'ԑ&q Vѣq`Fr '9Zf`\[t2uRQK]I3-HѹvDorCs_X4>4^m9B>cu v ʑ ΍dHP5xf>Y%;3:P YOM38h9vpNea򷬛& c$^S.>6zȗ'&jvBtˀ7W̫KS/ v Oǟy9~lR_߿ordL!a,{VOF6Khx8UxC3ΛٺE+֫ cMkRQQolv˦ƞKZOѶ|(r]m|1։c杷m6q80e{ꛖc[B(0g~vG&g7(0omd҅fLbo45X].&OM54kmɿ-TYy{vD>7]؛` 4otTjyO" [>G.pp!DlbjI3\$\lB |a| U)Cp9H%0VFQ#DR( O5weESLo鸡a8J-H*|9napL<2$U~ǧЁցٍ=-.7b"w yZB(T3B]aEʶ Uw<\ay y) T(!Iucsˢ> RuK|=vv~5]eD[Oփo!;܄#dR"rǀ$v#ױƖ˚:<9#&˭GS|^%֟a'}N$1b}>bZ3wF<:Wtmxv"-B`! 6 f å7DU?BB*dp`ԍk3@B A1K-j{A\ V/lozSYu'Fw=orL+} { 7*XJ#T ᛮyg9GP^>{rz'v4r3ƭOlű6#`b /!v?r$t6{5"0@WYv6@N~Ǚ+wvR״Y/HaYlN[&MJȲn.*ʄa®QXYDʮg]mҰ(4B0g{L!8&`S(P 鷓w8[t}Gcbl/q3`V,.OySHޢ>c pțc'қ C.aB!Y'׭e9\oGAptܲ5.'K ێȋ W~8+?e"sus`dQgZzũXZ R G]`qBD\"W*WD\vR k5OuV3*&nS^"0^ʴJ>XQZ\)vX&f&gn<Eh1d_v}o5D04`c Lh3xēci~OxDR'"M/R6OQշ t ËvF 4:`lpm$pAuDjb'߻5<`yi69vl8w4.Yw=l=O+ 3BגfmXkrppD!f d\En Dp:aXGTc+l &>G|)sIܼXԷd^Ȏoj`XW\JR2evV%MalʵKpQ̝+n$zL^rcwH܅S :xԁ!3t#=1ƉQ6j4Q1]cIsˑR ɴR#>>:O2JPt"7s`jIjld-gȆJ/^± WWkK¼ô4K>D|e1FdDʍ)h)L@@s`BcȁETK.-i"R(t<χյQ)J>A6MnD~λAb>*#*}v]7zEJ<^W,b(fwJ)ôx  E +?EcYhr$7.S"S>% >N OTڦRʂC#(tB?pí1'Țnj ٥HQ6C~AHqi;oؤyĄ{pWt= z2:{мL4I/'g-^jFʷ쑍 db?;D}HJ&EWݻzvqۏvyTEx..&ŷe| #c#N$ξ+u tHDžIM*YqJԬhf|%Kӻ/U??'O?ns U{@ ;= 3)Eo"W(qi@fF~d*1r gf_c?11LǀӨVS`FVJy ^{쟙?{_= VjfVԬp_J%RKzg{+Q>%ռnRy諾gTfw? apKwp< kϽ U1򸚫Phɬh껝N85XZn?=n7[ Ĥb8T鳠~g8kXh*n$# Q`򦱶TY]< 8'J"DrZa $cx,p`c˾.-V(_xʋY%ˑ8[];ͪ^ ͸.1Z`"FUGIrpY2HA'P؇*ܫ4+k+(rȗ5\3x5vgn~ױi˙Vlq$.+:W~ܝ]>LjK.AŨaId9fХ-(Z"I}A<4(QGm K<4+@,16)L-$QZ񗪓 6V3rfvfWz!L#@l?\u\5p-fY[1\dh pf-I@l4G2 mʼnw.:mf0]|T,FDlp`YQ^-._ gC;ؑȾuƖ"[?1!-   #ׂA}z WܛU!(K/Kfn՛T`4+ 4xl{@G\_qPG;ќtZFC̰M#C + fJ:(!ZFBQ6Q)-R@{ߓvEn;ɔhs_u5͠+ПMJVw5@r\}y!U/2ص[L}xP 4u-;p}]^τY6Er=cVٝ߻3TbrzneVqodGF^ yL7e*2D@ uFvϋ= 5znl}6VOE퇳F|PZI͹IG{g4O!+*!{Y$KHA'f)vce|U:o:=#i 3O}%m U&rx{(ZCYX0U}2WyjwqoӢ 7u4Aٙ2#I`kcCl'I[*G5*GY sYx6b+ 'G_OBp9 `E/+߫}zEٔЗ)ձ@<=& 5W;o0$k"<< ֨#3L ]DsߋF41rRozNo;۩TM};yKI7 jG%RU$C]tujț\0O%雚uE޵ܘuX:1e?p3:0R`2\otp_|o@bGuov&YZ,ǻ'\S|#}m C _ja|n맦L뫳͕RU;+N2mD 01Rg= 7$'${\Jt֠SkC`+lg~a[ 0"q:N}>q])_郿t)O 0fU޾@ ~ULIll@ƿeIl``cTfesp0}=/9 ~[f/Z[AGC>g- OӢw^ _Oc?djn@N~.+jK2b3OXE54ʂuzUҾym4qަMiީU}#{Ŕ o+B#3lE90q[ңb+m- fi#3U+E1"2)#'m |\x6w#,ipFK8xu={.kE(*3GrU}']J|$P Qȗ`ym6lɡeͷ҈Ԟb쪘,5{*NgI/NƬ}(1[IFs[aM i ү$,JH6F,$V)}'~ fd1WP"$}^Jshj5lRCLh/%H]ЌuvO׌ӽֺ.5Z=RsƜ6Axg^AKq%i;t }G'a[.@%WQJv2G0 e و45jԩz-PXy S ]!!)'Z #a3ruSVg{MX&P,dNVo6i.U/uo׺e)pww  n ^NセIwsoGGjSUkεӟ8%/55[Bf\+"]fi y֚B^n%lᮌO.w}+E2vj)j^ Ț7}+$Ym%AY~pEy9PҏLw>åpS>5zaQYyK'}<2nⲌ4{a3)g(j_ǪЂ )rb7k. ׄ}6U 7MU0S*S6Hgv ᠈*5~Z%őՂe9"&& S!s2V vE!;}}RaO I0 l*KV 8L1J ͣ4V.F6Πj;@1@@wvl+SH^FHaB׏f !}畟Сxg@OR9${_ϪIq.rnf6J(P ʂ.EaO.qHÇ8G'V۲2 :F7\qԳW^jI y\&m`Ӱ;&)Hm צijf@My~*hGЗUo%)I\(o`1eJ9Dq!u2\R)_"CXbnՉn^~& h?PK>RnN~n+*BQ2rFb蛫e؍҃/AჟFG*u2zt<2`7Jᩏ~@ U:+5AZL;r)BDe~ywedQw|Wz=!ꎵԾ53 3c8V?_珋AB%e:BYY@CzΧDExh$AZ+=i1eB-Xv~z[8G.,F` >4%"I]eF#_-S(#Pg-P4NNӸ?NO[)7~--CFmԝ3Nn=J7pICzE)%cfKR4C ZQ5^;Yȴ_v; lUGf4D~xܺpwD!U4l{XEȰOfXy/7,<,ΓnEjj]-TpWs)[eʼnBNDG^îuɻ"ƀtE!q4$@z'$t4 :y(bmzhR/y:vKM@  +!?7_bIaͺ>1M? ݲ&g-P>VoOJQą_`H)b#W tWU? Ipa}PT")8V7-[>椻=݋Ν#W>lJ&lV\Sc(f':A|+X+~n/ ˕gT!o sO|UrlHYƜSOx0%rR.(ʄ"qyg@E&PG .Ro&c\^;zk-rvWT&ώ[b&R3p2 3Os5hU܂䩍iOnN4D֕Hr.ۑv\o4{'Hm:J*.wJ36O!SakWᴷʻyYM^F';,$i0thA]uV֓+}WɠaT.% ȣů{Ge4Һ\9T!koO%Xp"넸l~g)҆#7 %F;$+cԪ #"Pw?TC栋:Tŀ %sj(R)At)awwvi9Qi W,)?? ѻcA! DJ`~K6t9ǭ)w1- T.3O.vݭ]^|C$_luUid:&etV*YZ3C΋̪iY]Sw{yDGhx*&q3UXP$GO:rqޜ|_3i؋pj- k t4 c:u'Q(VH;7K`/+ P4ﭕHrdmf$zQWVH6 ,f5z̛Ϯۑ'#E9X>Dka %Lt(pY q߂F"`!](EF&8[W} g1(@x nlzJ=M_ [6,rgqY\8 )wM~uk\2^C?Y3)eauc2+mQG/ՐÒʳPB\1]IߒcmBÂ04=QU핛w[@XayP/PI3eqn5bݪgrx> *}~X6;-lX!@$Y?4\n2wm#Rv(A_:ԖK;g^U+Rvy cYBKmc2x8't}S|ՁWOޫ>}xv ML8&6I\rOd6x[ ߩڲrD\Rٞ`Wta4mlt$@fu_#.9sB(%Ϝucnq[\[Z \(iWա>8[m 1d nDEa£^".\!©Z4q,岸#?{n#4$>y Pv("r#& 7 ؎TFbtNZYjr|Fb\#n7e4ۚ??Tˌc3z 8ss`hMN֙/ O3G= ΐAvRC:n#Ju~A:'e1(xK~r݄6Йf=gdSW:KH='=MV$]kΦrvgLՂrAc݌bY L1y5^g63ɾObXzt/*~O1^,M~Em%꧕8m Gw`Rdg4)OYߨ:(ZUBJ/+Wn|bvX`K+&Qd><`r2 D]ma8)k84ˑ~a%Uk5߶"YMH ɟ;?o3&ךYB{p!G A8K-00# w1O3J}l;Ҡ1MFA/Q&6AǔxNQ'LPAF[bwv& vvߜs-+Qsŗ랷5GM7!W_r@&s5Ii#)]آCbW5r wvٖ^!HAbrx2J+Z)2iJ2)GຖֱK=rʧ_ͅڈط6|&˄ЅVX\)ژv_q~^' A{c5 "ĩ롆٬66D㗔ҫ8 k OJf=#flO6@`~lBZv2ڰ: 0w^o;F~WZ魯ix}NJm\2F2x'-=؇Yvܞ+w+8obL.ٰpIVZܚy{+%0ט5Uȑfښ3^[WDzձѕCAAW?J5uV[lM& ZaT-;ʏ hM1;;ۈh8$PI ׊@&≆i(YX:{6if>3F#1$L nk-"Gg_dW{}Ď=fxIya"8^ç(R #m, G:Fl&_9Y{Ttd} w~$]Pd/'nJG>akWu4zE y@T#{/46LXA&>u)H2ݝ*A^Bic"jE`AkcOnli(4<:J)Tj&KK-s>EeV*y_6T T>ظi9OUg3:^7+65* yYP `]^rj/%i V6yn5GmâvV^U%˥jPyξFQ]ߡҦ0_QvIiIDH#{WkUjvctS0nE!;U 9' 4[hA tͨ(lM0!XSme>.3uq)[L.9>*,G?V!F$pjkE9স^$}`]fdmg&9Tc|+5N&7bwp|e|7=Yc dxĜˏ/8;ϯ %mlt|IxBǭ=j'ڏ%~Dr;T%Ȣg5~ (q]7wnY7ܪ+ ]J`u63'G^rJ23iڵv$Kq^Xϐ6?~TJm""G ?d(O,l..bU\ND ~UK.+kl 1\󥕯^˛w:P6FEXCu1F >ンb'DDN)D"#^9T˼뿵,jx! Vv`{ʇ( kRJUAnsUky"bmF+{-99xLW9bSZHy W;'dӇFw=O9SEDn|BHwZ+Zu/Ou f|QTf3@DwrȠnտv<Υkw_>s#\Ի>X*/-txF}+EMtSG@FF8h +ruYKzfK]&WYةf pK u;qʉ3K7]zxaFލXk֌Bb1 O%;Q#)E}a6eAUA뇺q^0" 2֕T!iȠ7jF2Eq/D.*BX›n:(la[rtAJAȚwY˒Ic'%X==}LVL{4]QFyUU ,Q'TLP`K%TcO+J'ъ{)|ugR>gm4q>&.$pf,c wPǢuP+`ipZ:(XUe+Z@n˻~Ic5۟IO`Tj >@=ϔ4z ErS;&\edDǹdz27K`=C(")lwtM逝&Q# IymvcƠ|=Rs>2L4VYveQcuр&w0_^HD73+ZEpJH=T82RkٍiCjDp=c[]ytqI7m"a՛!|}Vkv䭳>ݓ/ ?uڥe/" U*%1 .ՠYDXS](};i{]33q,RR y6Lu8ο,[INkBe1n4h:iD[DAzeaӭGەInsxaU38/a=jh{E"U9՘z3 >ca r3c3/ļn"o8H8""'aC>\u婁84gJ zuf1a d `c/,N.L{ o\/݀޾n=vu S)H{%l81nE;.cHKz)PQQ?fWEL(ʸ,.s[M qcu-)Rγށ!(8{b4AJ(-jWm|hnwv!Z][m@MHUSI?ueXyR7Q+헨]lYei%yk{SA` (L1FXcJrG3rP,'ljE(d~`7(ndy'\v.?֔OXUg[u#gO 'h´GԬ{[Pgs!e8 BKږ~ k90z&lפD]LaizPoS)6zKwh{G'?>ٴ.y9uPqYr=Rd9 IuuM'H BUvwc^?HwAdږ.8Jy~5P͘k(!5x[#0M>ʕr*V5sI=7i,?$+nzǥ+J{UC1?n"5^!"$ֱ8]%4ُȞg>4P*ߡT`. ,?S-l]^UseuY]Qc}N ]qrjjs'a 9/zQx));7 R20~7Q^df <> R4KxL9e0=ވ}!P"90]}->8HUpe{!7&նY'-|bM$4v6}FX'~z4(8 D ~RCon/uT00\"r^i\& U bpkѪ`O 8Rt^L_)ok CR]:DwfFx^8MڦNX*3w_TyLԘ1n@>axs)嚜 }$ꪘYIPZ"s$W$Y5 7NxTK85*|ֳ?HE~CzzxQmAe4Y2,B 3+#'3fvv?l\O1~˲,Or2X[7Vd-f?7y5HLiT&P^-$X!MyE mjJU#zJc6RoHyL=+ap"BCK-6ƶKhM(ь`x+ORGKqܳ>*wU/wl=)|P:s#kN' P0u>džU{=xW!0A8kMջ,^:-j؁܊+S@j[dj]eg/[d>EZODwOG+8cXz< #s$~2قZҴ!h+764>X.'/!DFEtQO\ޏ*Ƃ3CR|_$vo< SqkXD~ur'IeӮJAYi[FF<q+exvL*ԎtγrFDlU > u_Lh6)'WwߦjStS38F 3jp۬R̸5~2s׬&>(BgJp@NͅD;k/m@a}tezs[{LJeoodU:f2-<*9o!vDI-̸cyM4 Ҭ9XF*ZVc%4u*rD7p"Qᾉ^p;hm w <;Ez*O)(R' PU>wa\UkqP OE Ŵs@v:f"?x6Kl&4W"}76oZ_y DmR'Aj-5naFhKCvɂ76AZb>貸`J˓N^SI@ y5mWWθe%EQ<ًVE[zZן a\j*E&v_ .>Q֙ Bmݬ1sIv~xU3/n|4"=uݕUp81RSxI_.Ekˌ+\( O&|jL|W +E}OUf5ȉQ"Wǻ6RIaq~6B l '<"Mb _W?^!aԯY8eSdj-*d&ډIB({ruq IQ֢h!j=32={F\|`"lEHxZ%o)D7#E q~Cq"N翊82Xr)/Ol[d)3n|Ĭ\l1U+Z2{G WCc{?)x'#? GSW֌Ed@?ZY?/*l/jI~AOdC #pq1U_?Dx|H<27#pO `E4 ].?GI=,?_6\,w`Ov{]^پssYj\)쳠[U7: ym V 1E 9OJէ gp8pmƖkv{sVV{x{Zn;]|0Z7]S"g֭:@q.3ÛI"ժBgs R#jGGGY|i]c9(ǝ0}Y,teؑ'6>=)itm_3oD`4ozvbb )h_lR Zf,ҋPZi_\ɋrRn hʾG%p7?@*Ij˽:dgce06 V!>'Lw<:mT$Z0gjkO#TСw H2_4ktCl!c"wP)tgFuL |A-sL k߸` BOFPtܘK@f\O'ƭ3_wV3d5>RtU4k)<\ڨ.+"̐4Q'~h< a|l.-I@OT4*) g &T-#6 PoBZ' )l 4` u<#VRuߟq Wػbi.f2h.F>S"=&E̮V!W$pA . Y%CPOE̞fE>c^BUgCj0\;7+N51([OnmM'{54!p sNn^XSRԅK1_7 U'|OjM੊50&>3˽#M 1]NnB!GzWX{@ՓNؠ(͏gn y٦v Icr Ycmȝ>pYә߸Eh6L ?+O[+bjJxZlU-il\`MEwX5L8~d^hhd~oɅ|xG5m?$V1]7xwV J7 OϾLKuž5Ŵ1fܹkK9Y.w*"8Qt{Jl/c[i*NliM!UJg+:m*: quw-L[G! k/7pqh.֛/rpJ> ]8h'~~ 47bbSؼ6NHl[ ehި3nֶ..#7ه]L&+}#pNs%nH^Ue6Z3GݗKczo\j"3YDvA '"vߵV7/9*֞[?y @_QLzgVJm)Ÿ6z3m@vRmrr-ʤ/ɐF@=i[g\5ǚr8}4|]E8wQ0V*ebR=΁ڰqMtf6_&߉$3J_M kpA~~wO 搃W|_0\de .Ԑ'y89X*rSz9./:}ֿ`C]dbfegQ⿈~˹4.oДGx@ =sK'qY`C'Isݩ[($KAy!/y.,mO}:xhs/wO#&@:157|(K9掇$OMw-> I0^:2tΜAcstyh?GGۖJi)Je5k{s cC,<60]E/q !T1UDTدyd;pTui~wP/qNN#貸:2Jfa& 1,u"KC6`qVJdWp&tK.p<ϹH M%ǁ lۧk5iʯ3T':tc#C93 F @;ǽڊaksxv t)Å~'ld} sX+~X7.ӓLknXdT57CJ%fD;N({`o{ ZAwFއ'i%]|0ZCQM_QMMjɴ8@ ybz9nQ4pqdӐTVGBoGg>:drrZg=L; ?nOOΣ_ƤtDOh<^bњɅž6I{Fx۝r6ؼȎh/6 I^=41h؉JR0jN{L:7"IKV*rw8^wn)aȼ!сh~ވiCO4~;[5[^fw|j\\5 DDE"Ѻ.j%+'@k{$ӍJN:TmYַcs䮞d30!9vFxиu+'$ZP O6 ZN!Τ40\ڵaJ=GprL!6Tbf39`1ju-IZϸ<- ntqzpKEg &܅|o0+ 4ⲔrPvL"m.W rG7:'--p2&հ!4  X@|n w,yRAHԐCP5ᾙAyf 7ͣ1?!97/Rτd /a ׷x)?")2#t'55 N" lHd,LJRk91:?݆عHAo5NTFPUjJ=t͗[*8/HJ<:M#I|LE-qA}+Mo gf;+Y{9="56%R]u>r ~q37\ jN:c^}A|IbZ?d>֢"zw sԙ vy+\u* 6f '/YqK$CbH%rrlҒsY;.*(krZ C_c TDūhwp/rkٗ`7~۷]!Y 7sg` Ayky~eL=Ǝ-pM~/R(|!{p\[t`O]"91^=d+Nx]5gm)hs-4WӬ>_^_6 lM BcHhR!fAJ" Y$6-uk@gHaF*"7z9n/gb 6_0%B G>Y@*4r _ԽeXۖ;wPPENpHpn$-Kp 8w>;ku;?^~0/foQ3|Fs&<rPqh{ޗ wq<6G<~wL\Q;ןvGG1|r '<\~*~ӿ_7d@2 O(~A?_گT\aQ<\I|s>~\eLX{|A<̉}_cbaKPpo@?|i=m7 O HL:y[OjsqID #f%rX.+- NjЃ#„"uQ:CǬ 7BXzdt#NM㬥僊IMM-̅K /Pcvڧ)c*+o\SRP{dvv5d]fQN6|mWkSaGKΏO% Da5> utUԸRV\Vo ;wءm/TrֆJoۤtYE"%mr_|\nk0KEI(${)"AUݖbkjZeVw };g$=ڋOz+}D! _0 TVztrG;(;ߕ犮'I먅5R.lϖAFe!4OHhz!2"Tj+V*P'tJE'Q4sbqQ%< _/Vث3QTMSzPNٖ*`I/`DAs^ho+xnN{Ln2\Fm61B>^u! SҜRh>M)`LwޙZa Jt%TGk"- I7 ~}_Y=C xWw[T 9# /,KRLG+(yeR*7 Uahc| U(n8-I)ujo1QcłUΛ|Be>u۲Sn1'a+KV#RI&5;4IܮO71 PE ʪ:rN k:vY5kfxofUluPdԛMHRV/b/Q^U쁖oOϸ.@vv*x}A^TSர.'r+T9>hX$,P{ DBB#t)@ h 򒱱Qp&zcgWٷfq,M#.{! &kWI?z6U؃~mA_`A=σ~A ~?Os>_afW 89R [)܏0$x /0sqޘ/,{)~^nvɨK@QorU-CEDh@@ђf}A_w-ǂvW;l͡&l~{dq>)_" u >ű7'L}n܇MAؑo_ *z)QX5_uPܢi2zgJũr}nzNMمӦbNe9OjқаGl?{~M:KvD?AXӦS$DW}Vsm> ucsp2)´v֢ilLhD.uϰ)ףaeؚeU(:؟c^OU/5?LASi<2*[y=*N;UuH֒-D S|Nti_B5+k.&6i}1X!Z3hF6$4S>YU]}~Ő<0WR!Nih:ÇNȍ zϚuOF֜&,3nܾ1/-_Zo&s\ 9A#Q55駪 I56k#TpOuu=dVLjrR7/ZFO-|۟{b!T`2Ѫ+zc "e 1ɧFx7h7p+SH/-?Ck*ş<8`Lm1_l UĀRσJ>aDS9#~R/o6K>vih }r>jNs[yzimi\lE~p]% &h;-vyBk $Y6qy;Ԏ70Jw,tP?nf.e'Mh=N6;fL6,>ǮnRl͜l?45KmQכQev(tfU9X;m>"ŪI<wjzͥ3sCS|s:uHkZb~gˑIQ;wP'A7%N&z .DhoY&WƇe==Lj [;KQ:@C0@~PϿ|_sgsL[^*:JH"DydTms8Y;4e8="Aii>^.4٣ŐbRYC?0ГaGn**8r0n@ :n9yynge_yJ @iAVRZŎj4GskW)* W j(I?>=+Rv(>}uϔw8yĭc@{YDja7F/k_ F2 3XM6bs>j@@kb1 1|5{R)?!d!kW䖼UX<%vbY&iH[O1Ȫ䟉C(~6{_$/6yPLBk߬WQHMfϼ;OlĩIm J~cSƕqnfC|MXG N57j5[$g<2Od鹡a蜛}}ol Ӹu(B}&6QCDϬU3I lؒPxdFmWSUc\Oopnn#Ӗm댬"[e|1hǚ=ۨv)3L^b_Kۚ77$:;+!gϲʾ 26M[~>;_ kA=U(Zs:BF7r5mi ,^L00S='yZdWiݰ#ac9- _#qe0&% Mp5v.Ϸ*El~48l}h>9N'RlFIw]GލTO+>Fܿ/$I6Ihps>8@@J0o?@p(D+:D{.bTS[5s< ٌ mdkll_ ېϛ&u?L]Fj·?IW:ep/%Eٟ,cOp2*}' NQe h`#}L9keܾd1N )|Ak2 y+1Z )0tH'\5sWMZzG.j\[OpN[o; }flN  _t F/aK,\?]`SVb: 0|r^)#wvVHCaV:'-t /\ppIb@[v/9q8pImqkwe.m\ |g?%!ЀQKHI^R'%:+ddnayKReƉkȑ_5V))gljbQwpZ&pZQ8>M.H4xvogh!&aRy>P=ϷlU`VB$?JMTo\1]Lq@/-N~7gMm A#ffo[ JED#EhLg.jA)\QPPoOk?7׵q0 {y #XE *o0`uCZ 4'}=eR^鴉:KhPīVI6~2"ejL#s>W1Ɗ>U 0<ִbXu#v:.$ & |DN>u-2zL\I˱}<4#Ҥ=$b:Mḇzt0E>jƑOwh[v;rY6'N =WmO+1r"Nf%ÛX[ED)G:FOʅXQmI}I?LG7AdhBbӪz.ӆp$>B u8T؀ǭ艹k]\s*>99"x'7|رqEZnzG/vKnUAJ4"^j6 !)ޠuVC% o _LdBcv"L^`Ζ^7*8j42&nr$jUݕLJ}1R6_)=iB\]@F [R_QUՌo88my&Ppf.0)Kc1rO뙶ѳyer0/ P_RnQEcҡEtG}~UOBwF:hXw}T ߾-2j:\Ys%㳤PG^cn%޻xcxM z.K1v1uA&qDȸ(N8Pf$?#P>mu6妪FAKI~4̛}B'o\ 5סL"wM,ţL/gKJWደKfՉ3C+!lf(qIezf0@ Q5ʠ?~o\`(vM}GdG#Ȼel>g꩚mGz{CX5D\KKyn<̼:a'bT 1T'`nG)Yƌ4 SbCe5CVJG 1ak:<]H5wAC[7f:Q[WXǏSH#sBLfTZ#)xlKXa|lE]q-&1uGVw͌wwO)^Yy*㌬^׀.m_h|[!YgHؖy&uڬPV]Xπ5$ZҠ* DhrfjͱV-O/=KN L8o 5fSM1A~qeUR!Rj'I0,/+_劐E43>YcFi D}߈Jo}FBXklhS'{7w)ҮH5W.~.4FzuHp)2t~5Q]_vLy[M@'޽kV"6]yCշ_G(Mnj+5P ~WqD`N#6_&rR:bܷB"7n!tޢlXv&agյјXyϊ>sn^gZp7^e鰙3K!L\beq}L(k]ۓ\ZSIp %.+ffiVe[3+rlŌo(!O@.O"baMcnj՞k('w]T}D6czYqR[Ss5zko-YvΦCNwx'O$Mlp1vtɬYa`dlrl!N)4&oY]ʌ;;EZll?,Tq4,g $dYJx)Tᤈޑ1e6YșCkso_}ṯ "*p/+eH1]띒fܮ_?]vol?46$G@{ xUUV=tós?F 7C;oGO[pq; pAܜ4`A@nHm& ?쉓x; 7^m=r~'A =19!..<NhvȓC?8`"Qh(44\; yw4ix.៣c+Oc)NM *u"a<y5KrmԆ]kQ>`$H-"hX公͒Ra+DLeD3\JN;GpU^=!.2LI ""To` *P:މщ>3!y:UܴesN*v&FfUע0IF Ij*)-5_Mm <5s[ )JX&'އ/kgbvs'v* 1hmy9xZt:MBw:*K 8FUq5@&pۅ/@>>'(;JeViT/8J4tƘp J_lT"o y2 3#7nry #U˸LK\[W7~c+ʍ[ "Հ96}|x7Jc/^~'\}4\+ſbf[Qhhr|/옍5a@B;[sGkW",J  u&Ts7;Dڃ™10^+T];L\9EgsaP̤AWk"exC|>dQ}-v-wgt"L)F"f=ՇD@¾u=9M[SL 7vKzGdo;6n[[o2^5uv*5wGPJd lԠhT6Ms{ <3 yFӺތ0ڽrM)rFmmg4HQKƮvg "ةjx(D ği(uw#Ơ=+uJ&yW )gcot- |\Ď*oEA#Al{kt7))HEfs q'XBɮB~9F9QˑJAy+ =N=}RrZEPF]b%4'H i'G.'ϑq#,[^$&5WVKS&Јp0sWv|-Peng5d3g8>˦a p}Kib:& e^0@I)/f>gKHda_)F SLmEJJS|:^j́|j:HB=+Emc)eoO*QVȂiǙl/$(<xvJ&3<_6 L!~S޿ \ibOy( -b8kJRLr{r'Ri;ªA$u+EjPI4xAQoWp`yyKŔYIQeF%^3eq(NT΀r?20DQޜz7wfmx]\0)ͣ!Q~N0inr~o@b;w ӌ]n! li > ֨2q͝J>69]BU6:z lHID_/o^/-g }N27SxYw\J"MJIT(TZ0OlXH |z=5}vΌeJUPsNPԟuEGw١ P(w#4]YnZ0>t̖ N8gDc)!vJeqq+ o/(4!b*~H{p}9=QCsGSJ$ĸ1S髝ҷqeYI 2.X^zM$|_CۻO]PYE`;m߈.yz42ǏIǞ֑ kKݎNBRz}?7}V'd'=nṮpt{ܩ޻,8uIf-̩TUxI xF~(nw)UX?v1a)]pWPr2VϳXϓn;u˅kܡʊuFt`뙋3Do|gPd[*h냤 B/΍~y{Z@;Zϳ03E3_P34u'z6V΍&>X]Zd3Ѳ:g$Sڊ?2oMK[ǛzebG} Pv43( 7 k|z^#AעTDcUn!x)il ~y6pr 죳>S8}gxz&@<y\ԋ5{]iQ:hf2oXoK/@VßhaVecYw}D$Zk6gB2<3GǛ!j"A;wFUCt ="ںs@ph֌oP`Os-AM mɕ 3lAʅƼf k,b ;Ak]˯-`æ@ʠկبٳPᩉwn$`Asj5`o0Kƒ5mk/AԱ\=64,uӮLb[:$]5\ |?eyg*ˑZַӫcUP{C* O\xҐ̽XVČ_v.j1NI"Ï#Q|e?:މ("rxV9?$FXstȈ~$߹ٻ$4y-\f(Wa"؇6瀒CDrN>ms#7d0o f[qU4U8# F))R_?)OF)*SmH[!]q$ 2)/.(s beJq9ݨY{}y3[l]UQz2Of?\%Mm.hZHVi_O mQ%a(>.K }t߂2=1'u5@~=*Ј37}?Ø=;֤dZt_aST)[?U2,jmp$6& ȗ0MNqPl42'?iN|oj#By=fU`,TmN yB9ڂ5%^,~YH>7_;% YB -|bdh>|"'"d`@/p~h@yb3 Y,*si,Ej2CRw.byː&bMb'F$gPܹ0w7 p?>C'V±g;E?SvYtnꙜ#qb2BX">` ?ۖwV&)=x)pu;\ZN#A^|rN>ĚrqRYB(<<Ӈ ͝hh_ 9AΖ牑Fe a {ˋP`#]]U]$h>xGKWV.tRmD^Q?P $o`:As<[+FGQhqaSH?+^4fF;<^]fBKlUk0E͙ ~Wr1o:ME[@XxJmDpmc>%^}Gῳ :;@F: q!"g[|ߘ/FI5H{ky3G"zøbБ&TGj ;NqD=Mٜ8f<@'8ߦ8[G^ۏtʞK Nv]_<_fH!dߓ.Y!qr \6we\E:=VDqN*s=d>~ƣ C_&|{$lMacB89bY/c)nǧͷd/Vwm4w~Z~U>g0=XYfdGQ/ruDPk3z9m3đLW>=>pi/->#! 0pcWPfC5f:TbYjQQέ8TX غ}(x]^].8{V4s7ݍ=pwQ o[3E pqP;_K ^|WQ8xpؑ~끋SCmf(7gS97o5 s& '.NMp#@+h`߲,LM&r45YFG_|4dXm{\ETP0v,26b}@(VbگSgnЂZoѶI3 =/CD6k;fMұujG",HF7jp%>9[U9P20|N%FSrm_'v_wﻟZsޔ<3@~YZKSEu:f-rsKK9ηtv9c-l|AwͥKgo F>d~iPhU+cQLlV(0mwY$\yokc]oeHN|"s|:l] ۢKO U L~5uڣ=mbP.lDc_R5nVo݁a&i%;-3/:|ʆj7Q|/)SU;^&4~rf)>]]uDW$5ʊm=K2Eph^Vw86JVMm΢Q?)XQBvf&F Sjri{3%PE,) ^>6ٲhX,Iah$Aeခ 5 ߒ9t QRgv+$"QgAʛP b'kCgVұ Әj],R Mmk?1 [>58Z2?2bNFi0G[_"PA `|L" {a|^Onr)l e a d:~4r_Uizzm92m9xr5hr@3-V3,sAW\_g rEWiֿ}dy<^n0f3Wpqg aqAt"r(Կ@O]?+AxEKbiդ¤,wH\*+`[T5ݨz}) l es)s/`Т Syݞpw RWJ7Yh.d}氎icoaCܛ)$QQ\W; ҇$R%tĥG2:} Ēa%5zm|CWdPoGm@++A_%\xr#gg`g`_,yOAS4+B/]&~/"3|ͪV ¨mtSBr8!%UGqmd4S'糌'bӅũUBavie!iuc͙u.2܂ӴDcq8Yr[ɑĈe(6 }piB''D#gkKű<r5PAh_%>=&''O!R/n֣&| u#!  x?'n‹p2_l1]qaҒо>G_фc{a-4G3&ٟ܄I8~.3C[H+*QӜ=&·`\\ VYŒ.{ pe^-SMg߆T\~6ҺdB"KR'~N"V`,{0MOiFگ=zjfgvR;؄rrHG=7q=UwrK~"e@+aNZAJ8L b$?>,W6')3M2nIA`GQ\gK+vLB6::V~PkŜpVkD4|Yi5™z$od)LWLn_%0griTKT.#6l ӨcpƮ $QD6D8<)v_x8c{sI8#l''ᙱ uikˏ- O:S mDb;61 GVHoor&Oc`u뱯O]> u2`Ӣb@򌬶q݋+Ëi+R*| {EW~">߅>Np/#>f, gCPly=ޗgq>#cU4jo:҃ݝnHrps^ƃNP㦔 I|^-lkFDɂ#B-2K;XiClW1po@=w~p;-;cDk7kb"jq1Ʈ‚neZg7ds:hljɌ.Dĥų [Α 4VCJTl!nHuR!Vw"Mh*0b>Rl+5>ScvV7nJqUQ^Sya65q^V=Zcda63k)BSm 6|}"ו_z,݌ ! Ɏ#8IԥaoDi 0.~h^]sYaVթF:,S O۝p#5; 23 遮tX|]֩ gXZHTdQ53I'c@3)@?+hA)ɯ7|M5`l7s-,z t̬H)ū5x7e]fMQ2B~Zȡim{`Ӟ*,(,|Cf.wm+.څLrw^|-A?;~Eo;`jw[^b 3ީ (Fa@5$#b%4SANJ |Ns~BҔl>1S}B KrZ>x̫Mp6J]3 1XQj(R)s03ZE& iL$pdvf:}?" /LOU#_AFsV1Ȥ g/ rcܶhۂ(|7PҴ8AZ-^Jܮ b[BmG~ Fmq/` ec*q=GKd w{vσR^ [%ئ3Pv9=EզxڢŚyDK+s </<߲Od⍁a4fg|70R銙 3f)7b(F_ɃUVc ֏Kf|"J1 ~xx]"[+(˝Y P 7i6*:x{u#L[Cbon|QM-@*ꂑEY164?gxK{!tIږpD.z ˉy.ad#:. :kW䎼R%OYRmp`~0=?(T_1n1vbc?a˒Vs@|rLZdHSHP 7V{c%]]{g>4A!|I& 캅NQ'DN&^I׳?lIr$k*6,GKQ##dO 3:H-֏RȉxjR=a,OkbݲC e(Ƃ 7 JN2)u\Sv&}TPqWj2[F8;jzBZnB}R1S MDl^#SMɝsʚrLu}ۏdž`302 tR_ Z>.gx@Δ|=@.(.zȀɑ'0fxtUqr30JCr6??(d%7!>o3:ŕEy gA*]C gۗtK{aN艴Ϸ"Nvh&Sw<<fsh'hkc}`GfFF\ Y;[ך|Lz5*$!+[|lPڳ$'_.><% }<HOlh{ig[0D*GS޴:$K:X:rP;;+ѹ4v;v)w(ɒW,3%={n+(^L ysi UeTXdYqp6mm9".CA?OLa0|j497BWm$g5ƴS59QM1ޠ+v/m-İ,7) (i"|-~vF󯰍NsU+=_a_hwkʒSg:7hlB_gi(7 oAsnrU'!0@'L`뻹y B,{Ǐw3#}SBlgAmCF[RڭZښ^kĄ15e aDrv..P23w6m[U;'4/^`_VzuwޑڛFp5$1sŴ\SJ-Vy9ayӠlRv~Y[kųBK>MU$'$冧Zѯ[86xP0;&~(P+\*6?\W_ EGi"DDaܽ'2E %,TLzvfU=DN,w)!5460vB 5(@Lϙ)7<#3D'cmgX\8pv@'DGf窱,NXz#Oϕ;CЭS]YYceQy|&"T͚݀chwsO@l(AP{2P`DtA$2*ڴͻV-TLv w+/5RUى:P{!`-J*Hw( _1P̜2 d)me s\G^H[J!)XC%ͼaBF}9&*@<(yZeLBUH:?&(r]&|Ec9*d'.oM7pBF%' z=.^mSΨf # дˍ D_gqPC|PW>Huw1XL8yژrvIOSӯ(ԩf$3Ѣ:ۢo9 '#fHSGFBdWeq~ԝZ7УrǠg(b}IX_dR PP:!/ѷv,)+!wg[ ;Øvհf~,h="+xa3b= 7-u3xIuЩ,w)˙?q(-M uąd1as&ۭp|B( b 9a>Fqnk_†~x,#=!5KFq% 7"47Wԫ r OBaV؋5->!jF`::5G:q wQd!qOdaL-mAR6{  +?ڠ 4@ g I)yjr#[jHGÂ3R]%-3 \~ECY8|[Tΐ;G("Цµ[pGSjA!-A^%("$ߜՂ-E) vVUDNU~hWSTޭzs`{@U[$c@ad40ΐ?} etB]wA;Oy "΢ c qgLNn@rd%LJDXx`mDGsglpo֙+nw*pY"`6'Jb_=*Z9ZYi2P4̌HanZ`Qc=.ѾxD<_Nb<,M;DdGR04GGs{V{Ç"E-'U;Zұ[ ̓T݄G,eӍ*##+סzdAX@ΊDȭɖ;{G U萶xx?έΓ}Z2r3ᵥԐЊWR`4 QN;‡p`@cl^Saf7akQ;eAtL-Ӆ'76qӺy)ri+ 8Fz!&Q[x\Pk=-2QC,6-ؠG:K$F־" F[Ltmᡆ ia$:cB`1}~oÅ`N*\kYwEn;,$DkmkxU-* ,0܌"a2 ˞YcɪiG1ɕUY`^w\&v;-IgɻQ5pmԗ#(bw?\i"& eFP*7rBҎU|gPmZP 'sNؒXH7^_uBVcf&0@:sy GʦI YܢCKH۾[R"=WB_ 1݂_e' /o}gg`gfc>#;-W'g'G%ݻO`Mk>qWY8h98~c)yG"3kC4Qu/$ HR؇8- flyY|27Z.⌚$zw/q(SONέukwMRS&Ӛ .N_J1v(a[9TwWJ$bB5Z bvÍ GD֟Gr1eZ#@[Y’Gk\YlX6*bT1{Q"zWk/)"]Uf>-;%&S0 muAWOщ.]/fY!i`7NlѸPm\4xxm'N Ft4=S3G0~ABT|yI,18lU 3QZZi%4{yԢU!' $%l%f鱟ߙ}1ۭ&|m6D!J]̼ZfHO 4|ZucS~ ,L[4K NJRJ=s]/4 VIMu$H5s ( rǘ/bI#g]IQs%ԲhS-QiF6У-^# (Y?üVP]yإY5Jv dy%9l7S T1?JV=wb[q݃q6C})ϯ!-)o"C ns~TA 68M(yq/o|yXڝ-R^KRHwد )nq'rA Nw)eⓘgŗ 2'/fKl̾aEIEېWZ?xp>rcW D2RYoy hi[LN.E۰=b\/ "ԢS[Y,3w!LU˵5%Ācgi㑃f24ۑ*'бmb,1:]&3 46F,!#Eaev]8+ΖڃLy!q\MQVґgD3E1GtP}@Af'\JRZDAE|o $寥tQ6hݦv*HEA:悡d E`r?%Y?lX>b NR \^u5Lrd_Rw*@׋8 >Lgb3 WH:2;d+܂\m!D! )z o,k9Ѕ &VEWT(7-Q4]}(p  '+IX߉8% x<:Ka,l!,ĕV0=[0,Iػ@̛|N$&\Y8GgfZ#;>qEHKv>>`QRam71oMQlTx>Rc8"xF3N7UۙP GOGdKӪ|[[kZɨY_L/5-e-WN/`$b08**hLj[r1&pB7O =\.%WO;:gӯyͮP>Пah4$ Q:;T2;V2H?1&'n lƂ> >g+uOUj*An,JTQnI'=K#uK_Oᵱj]_=q,\,ppfؓ]9V715qHGpRAQD~yĤ>>.=<QMH{\WJxG[GG.ʂ(*."Q맸aP/F733dpwzb(3gD7`wq#,ྜ kн-1jS ޞzzY q0Q` 4Pzu)1vd׭R{QӿkuTι[pETvRdC"ըF4S~ʾVԵicٙqZ+q $u ӘkdUmJƢIjSw.≋Ns*b*vطs+ؠxJ9VzӑJ'AL¯IHIb%9FvȲ /ٳocZz~lƉ->M09;=V-9]2ulđ{=SQݸ{?ӡ*c>ߎӫ"3Ҳ{,,9+U01ѻ wYCDw1\1ӲQ'A~#gaL ii1Y~*da|of~~Oϐ3ULf07ۥ,a > FM,dHִ;M XL$'18dY=p_ L9ȹ o11 @%_!va #񶥴t@cOP񃷤ZI,_x opA% )3:[cnD$+9="G2$*Bt aT!I1=6ݬ񑞰\uE"QU$IGtG7Mʻ; -0<,Xk~qSg{-0檌&re=7^vEK!eiYs Ga(>S)ѴfR.h Tjm+%Z)'~DeUVQU2{IIiq`Qiv`ͥx87jm5 Fv'agc/{{dQk{嗘2nILwfM|l~OAհ(9.bHIX;A|3=2] /Ɔ_)YNڿ5jL[mh|?QF&c'mٜ@| =&eУ& bN«iNsFm>< ٿ*Sd[;kk&>궾jVG-g"ii~EK{y W,wqH9!J=ԁ fqB*W\@~k.%ysЂ}mkf43˼m1M܆XNe˦dZj('fK7$oN9JJkZ9(]i$ryL:wmEu:kE7:p<tB6]!I |8x\Uyz^[MmzC ;XFr`,3}ؠ+!ɼMAft?:ar>oӲWN/U=wo$niTL ++ûg|GBS{YC֖6V-ltG :ʋ 76z_[g?_Eqhie8ٽσ>x_tpk؉-}`ёڸ`_hApzPt|Nt7Pie`?@>e@@| ?ƙrqq,ZhZfz,sOC f$_>ڐi0{8߄)кȂp=N/8]/)'ޤ I`[I >p>Y-rUGbm"c*ަh  [&+t ۺ˽k4TGRTDGTFK r %y'IS[sxJE iEvvW\4x l _kP˚`P4~FYM7wyVv`Z@n2_ؽGJx^Ot_+SGkt.C&x=taf񻦱#lil,VTM|KQA[lnGq|D׀ߟw_Nퟔ4AAPW$)NS44]5o , v\,"s'h] Y81R>j9( @m?|jWV9d@zXvMWЀͲY(FUVHp3MOZlG$jLm^UMCpHu|,bGڀ1">mS$:!VPT*c07~+jw}yGNsƒ6oٓ֨E2APA{:7 ~5w+6UFU>5)\^3[|0#O\CҽOŽmne2E9 h,WY./Af9K(K|˅S 9.^^h&TxΆS/ 1 \_n$AlqhAB?oERTpnaAb_hِkk(8jH9 r޿n B%:~xW [ rL+fޠ\ ʵhfsuUv ,Veff瀓9/>fhY63wO=f H 3=[7B<XM9ܵ8Y(fm^ic5նss)]x4SCȩkǦ++'&&bB˷#d4x-߸i\x<TH%ⶁ729]jg\x"@PRRDhǧnu!DIq:d}!X8qMc-Qq"isyh ᩁxc۶o\#!o>Sp>Ktv{mqVM*b< ǫf:Eūd:8k:RO4)-z$i `}ןL솭􍝈fPeklQJ#u/hiAUtxF ܞ1=TȰ d?v)?_Ϝ|ZQ14ACr)44%}\TA S͂70TԌ5/pxƀqwYSWI͡TMZy*Ht2Rkv_Gvqxl?n;jpfXQc-="ꮝzm&qMpU~ž ljWmϙ#SE%ެkl9+Gһ߫yt^.?~ }W[;Leio`0;ԗkeWW]<@ L<=??w\ 2lSl2O|i<㮦ˍ{sHw\w3UwwAOCini1o[t2<,VNӶQ-â~1x `M#z;X_zMaʓZ[iZ[zЉ<]3>kfBaVZ{nf׏61:L8{rz-3~+D[-y:O%i{w&MZz>-/Ыc}@* nF1[||<ʽ4B,uZUoZPTy&:_IVij+CF9GL N8 wyژSvrWB%ҥ/tlB'VEN\m(?kv8+a…;S+վ #CJȗki]NѼ_ֽ^&̭Rlz'>dhkF4ʨ޽&xq0uFV;KӻI$Q]NgLS]鸜42h4XN(2)]_>d>FξOr07A6!IMQOb܂Tӑc\h* x[,)BĤƮx^㸺pʈ׿t s4m2چRi)shS:Db.D ikjO|{=za{<*UOwTlF o59Yx6d-5aٍ׋w::5M%f˅ vql8=8#qXI㊃>,9BѾ>>&u[ *!zxm>P8yEu)ZՑDTi;ǘOoo5k)FC`&ijMcd/;dA/gR&+o~?>l9)& wyZ.N74 U@άDL5[6j-7L'p#i2bp P.;+ [b5oWNrr3@0u˱;iሞ{z%)fKp&\0aWabb`Ҫ\(0-Y N&DsqUIF 4'HJS=1x{5l%y 9'r8Q#/bTd'GLM:N?eѥ(Gk}kd3`AFv2S4Ȱ~pR t[jN|Sj=r$aCnZ9L\h uCý#(-ucΠ<%bt!&t|j.`V%݈ېZ%[{HcE{޲u>덞< -O7Vڲ4kX½FZr} $-koH.gdDJemLLL7%(%iJ?7RE`s5戥irDs냺Fre*kNw~쳊N$XlHu "8u1q v#O4PG L"33SK]]ɂW!WjOo&Z7um'tO diy|Y|:xWzri#J Lr~f-2omB(EZq(]ZJ29-׌(#F;1׃?$OQom ^۞D(vsb6sďCJF#F'4$/@{NPKlh6!kŹwޭPr]SH7U5 y[pUL`Q ZŞ KJ^UݯYQJ\!b/)+0zfĬ:Mr]q@?D`W5%g;,"! '&A{,ESGV&""sg!$ɛ ' Eeb&&~s{'nMFu=Q+8S/Mv%a5g4L UK0fԮs{To/+2geeOה+襲r*z1Mzxcpup;PD. zjI>Ppoܹ#w5n> YV3~fmmP~AbgY>lk0>XiKj^$T45T RKIsDQsK1 nr4+Pepv6:z/#%v9z߬s)(*97' zmSq/Q|A J` si[kL3Û;p:AOLs7^0C1=y"zm9Jq.p׻t `ā,0Ş||9 G@TXF?I x[VG+i~Ѹ#Rw)(%zDV9Q47 g0_א0'~;TͰ +R6֎QpΧ34';RDT t`@ |1&FioXP^:M\2^ވULnM +c0=b(XksK}/ 'SeYNn.HhI_ֽe*|.\_χԯM%w4"Z"ǂf鏌C織TU‰}ٵ6%; .&Ut (7i~+r= fU5g<UjuyϢQ~L7KZUAS7fk+߱zs+ .o,ʬ=6i`>HVlb_#JO U%s?Ze孭-W'a7OMa.l޷nJ_މ*uaǖM|$(+]Tucc1](y<{k=V.Erǹ!W~)\AI3WE'Hv%۷T 2(IP;ȸOt8"- z2trr sE񒂮c&W)I:]҅}'tvSNS>:(U?ew!{zԽ/_ JyùCVarZMLhrkǒx9%3]eDw:e qAaL75"$Ǔ&z0+-jzJXR~!%" 6;|\2 I*]!S\咧q YJ/"q/m7dX2wX;y|nH^~bJޕnln"- skϖ򪬢ɴɊ]ޖ-<zZ &v/|qKyv=D%^D+{UZvck2"qqHRcO<~:Ym^W3)S,Ma.?4!<;;*OV^\2"cPz-Ȕ*/RUށ[;3Ar#9 |׽$y\B)>f+$תC y0؎ӳP)??1o?S y&9exr5 A\|-)y5r]7+Jh]ML ؃z 1BG)2[P>.`?KvXi-//Î!b#dxdh#~Ҷ\ 7ۥ\q[_-d7ו~l,o%fnȑ(cz tbyz+t߹ ިܖ"I'l`4&nƏucK!X?6u?~\F"<.&c5?DRtLw` o_T:BR#r}J|,{P'jEgȧ=;[:S,G*$o/͈οʦ ||6UaQ8p"sSѣrz#mU.0M]28c-,xu_UBx51*봼Cː~0Ku;RcT'?ۓ_*1v=Jd2}x/U?xCc)?r:r :(J/dR^uUr-0|4ƚ:AOH`#AGf7aM fbY E4 4L?6J8I[~v= b㰒_ Cidѯ1>U.1MXEE*mT\ͧkeuc=y SΟ"6wonՆE|/0%LVk1m g皨uTZ BG00\F/Oo)vGRakbe~sgu=:yGeh'y`N]Zt݇RDQG%{JbݴĘ*. K(~<=뜨.423-O[ZKEIeo-KNTWP{ħ8fQS~p//} w_76)>$#~ɥЕ/YEQkcbJgfϕޓ ub$JN'|vbRDyrDnR"ni8z~=|7/t1tw$j%ǪIc3!ɷNOԒ78:9AtHIWf*aGAWC"A>˥}DbBrR6ɯ8fքL6 [# 4Y .on |}*t~ ۤ)wXr8ү>#yz/PTw"JQ55r㱈|iH˾i:.)cz~L=(9l׿ ꞽ7W/M7i!<91%'b;U !dP{%k&3uåә[Wt9 -hw)Xۭm+R[W Ja BD_x_.//+_+ל| N!;XᓥXrJ@cX[[p.N--[*r?e +~5)~-$'-$ ֖&rmVEq1sLS@y\+:VuK7~clUya_OR{Xsbx bof^}}dPksf产f+Vc WQ˦WMv>iØڣ?*t0G 1xs1\ A9:җ )dm!ٌg0"_`u{Q/Y7i!$SP),7L_ M Af#S{sɄRMDeZπi=* o})a0~W&UVRqTǭL]~T @ēR*Z!y+L)"h-_,93L 2c4ژ )"&?.sR] 0R_o*Nkiww|ǰٍa֒k,ikwؔq@qzUplW8=?ŠEJ NCB̫*6,(6Y;xC2zs%큍qč*qtpw U~O4 VfbvTXL2nR9$Tr"H)&C|^ D&EXHƃvEBAE5]ۚ3ܳ,k7-LfT^CA΀dKa5UXQb Ve#l_d!LNd,:R3t'p=e (X_妊&wEQ"Pc^j./4P{RⷳAL*CځLs{;Q_JTw*J.Y?e/O}!59_^>;--n*|:c2H2ݷ BR̞jbǘɢ3cQ  Z}X)q-6Y|K@|44sΘh,$N=484YUi~$ |1&i u6hHkX|T~v %@uRNҼdK+y82}弻V8j|Z%^*|l֓8HkJ&Lb9=ɝ*-= FltêvžJےMÄOa 庍J4(y~&Qp|)4剨p]4]_ZdCz9|Q('*e% "C@3|4r@] c<]8 R^8g6o}p4`?dSQ>b m1ѪeoA~V SJKY*e[GshCNRD@c!`?3ܐ3l3Hv&g}WQ}[TG(R:zی)['MDtD`s3s 'R%Gh{`XaYtZ: %,in3yvjS $Z Ao$D'knkWtMga*sϢҕ˚E,.X]XBG0uɐU wBd7e4RMsԗ_B귨nx*H1hhc.||ӟ?2h\`tHH3u-Ş1ZqߠS e9S Ɇ9gˀlL{g:ӤYFwX o4C? 3*U(O=/JXIX\E.[TwAVps@Te{K; oP7u&8h0WAxu5Ix9*rHFsv#wO<phL _sSM ntw؈zO;В 't$#'H!S:xw'QsL9~?_KTO;b狔U'ZTSK7ݻ_ G̤yFc6ו+*o 䵴A{>Xkl-\B`dQ~eͳA5ZO??T@F:o/NUmeB;oDZ߅|qB*aV^Q}Fƒ 3 Nd( WgTSe0qMoOi!/᰸PBY:dzbC uCnN[~ 7c=Mϱ=HӁ8zװ"PH mrmMK<>T'<4))Qd2ɠ*c$ C%2 T/d]xcb2Z.z&M飼q!l ^ΐ߂.#`9/0kPrϨ &ieIX"  @P nj[^YBm`?m-rylaJdSOVl#Zp[SiF .h'sg,R(wμX%[X<( Oƣ}(4]#z"[TnD|:kzw Mvٴ!*ªG 0 M~ s_iuF*o/]M ZVsV2UJ6L"M&}p_YΠT׹6ӪsVs!{[[$Q*1毛<>d4XP>\fLzq<Y .eoĊ)\h3-р;'??ԟ؊" 0^`'0*\Yayg~jeK؏vb2"*2xXj r!@pqkn!WF:]S|q%eJ.tġ %?`1> :̦`E=:^ə5|FlmU۽!VyuV%~NʌXރ2K璘a+i/R Hzv`W?J1n{݀~u~å3 #^pJXFjOHg!R/) r\Yr´+''p$om .62EBv(t 4?J k2בii9>+V@;-_PEuh~b #l0Bd!_ ͪ|7:&Ǚ*AMզ]bJUtӧ=GGd|p#,jv|㙮.(ַ}s/_{>2zܿ.>}ze>\kC(·g2a"G?Eqppܱ%kDač,-qd ._gJg^owuM+mg5!uZT(Qf5&Mdg]@@(Iٲd}qO2d O&o1aR+PQwJ~n2i÷+%wcen1ǎ CI ܲ7%3ifbWkrq"1h~u2`*1԰qa<=vr0*H@p7]WB-P=@#pEI/n3IN j]Ӛu:k3(Ƿ->%en>8̒Ze 9yO!*H&~H5N >L_/~K TAZZG6vֲ!f_漻_z:x֒_"X3⺽].(i/"r!qSQZW,hW Zn>ufuy+!>jJRՕ3~0Z^8Uk/g9>y/Ng< \PYys>9=V$Nū=qnvG׋/.=_xA gԋ0EEeK+xheoN+ttt78bǺi4g|D0x| wTɻwc?J5xp4jCne>k/'oIK@.ǥew"j2ZsH~[s]+9V#aT{KMڨƞoMs̗g6=[RM#112t9lR=]?^L5tG;% j6,QF_cgJ{J +<ɑTW]ßnW;8zˣ- s0 }E ǯ }g@EqнCxΑH{O?鑎35zܼ?JkkKT b^ZXGd,$ X>/X>h FJ&o"g?'4z:WT = ~DB]T] Fy'oǙ~+DuCr~Xy4?LߌA]tw|F-y%QD~n- (Pǵq@Iga-`8Vvbxܛs̚noXzCt~$q+HQ)X!+Q^uE8r`Gu#` +J6ǓT``$AFt4q$FMo OU,C!OP*y B:J'A?DhE~Uj2})4^';uIoMπ͜ZyOh:=sOD+qW}ԙ'"%@a?*,M*:14w阯syz*MͤwaY7d6G3Xj趃dKIu#?{M$Zs=0HxS5o$R'DY6S4I83V'M_$P˝,rMHX9Mbq$rHyTT-% 5"iRKcvn$Ĺ>īHd%Xb FƨgK@%}AzЁjR?<לֶ]墻;e`NxૢҒ397-V<<]H>24Y;- ~UU|Lnz*~i#d5E˜e7wv :fj:kB[#^_)Sq_X;0TgGɃ$ޖfyg\_Ml;ԟ$@2.Ũg@X9ǔcbe~*_:] HzЋ&RZsOHqAу[S?;&nԛ@Dg}" a8X!2w?mn[F ŷW3TF>QKt2L1 V:Wlb/4 oݚ\T\.hRr/j(uf_mqh$Ѯf̲*]!ڷ\Ǣ0>:Gu-`M(DX5_q^BpGJ_Ace]% 5PF=E5I Ct Sɨ膳oY_ѳP6c|{8OiH );coX5AR3,w2f©*^Ɠյ;,y~z {2#Ӽd)k< Lp2]!߿; "(횀h]m`>u 'rB@Z~A>Nn!@N^4.f?Rg p l^ 0)s l9SHo?+<߁vM}Ͼʹz#h e.@6]}މJ E]\;XK•)?A,W~Nl0efOtϱ?=%4kRiذw!q&dsN(ghyR7ĝ-ɶ f7y`P)nb8Ns]遇A$!ᄈI7tDL77G͖C^]$,.iۣ"|PC.:y۞%/G +(w_6ih[&%U $/o[zm4+}./[%1`5O(`ąRJ|Ae'SUX2/Sp?uξR*~ή?xӓ(OhL ]H -駉`߬, ʗE X Q'935mۥ ONhByEߐ7J?ld~f |k}7 o뻯B{D4'GdeONhI4a?'$Ӟʌ yu\(94'I7b-Zh:Fz )+BMvsR`DeU^_QA WhjGCo.8vwz%X7:K ԖZXPbciϤ*@cZ83&F#XDѾ2L2&No\_E^<>bނU=-tсtlV^eαgr'\XdF/Wu8gReʂP_eҞ^7gf縧z _*AU4h|vF5UfnޫS{e F}}&cvͳ%6Nc46ǭT!ϸLC.6dia}ikzE(2l3hcԂE*Gk編u{pccW (x!D)mKdS ~ }rL,^q^3kO⧒272%S`Vw?6llTSR,g~]`n>dD&ʀ3o4mJ{ Gf}򡠉Ogh*CWb1ڿ )<-fukȐQ6m4 zhﱂݥb о|f2[WP 6^6[S-=#glX%NI;z^ <Çkչ@t_a=zJ8޹S,X}vB E1Uj7J.uwvOĜܝ욺l[BbɏB F.#rwhheu ~LPB07"SG0WH|BN9yC;7P?3x/H ȜԞ!&PCQޟj+ -j 5/ڿю67篔Bm#D 1\2WTt;(OxQWz5Npn#VA)yC7OBcGG!G@Inu._iPi>n(=5_i~ҕމ`^1 ZT24QpQc⣉!FikWytxqW1ӌ/u,A'xԀl~B'Ac—e3 x852_~ m/g?H;U#]b|\1W^Ny\{[^u ~)wMva* V݁0 tC5G @o*ouⱼ] ySDL7[!U:l>[Tl܀Y!YA.{RK_é )<,|CZK˽jg3c+ ,^Ֆ[zEոIwwo0i='q0{8tk z|x|j7g6S7mjL^|(qtߘi]?롹-Ԝ=d2ζĦ.Eu0!f ]]>\AB0c}#QRi4u]#L!kҳ'PQ`Y"~H)BiA6s|!Z7[I/͖pFq wl CZ6?U؈j[q6V{ʓn9ob, iM6Pd#.T\w\ $TS`UHLhipHR䏼l(|]ߩ9VsIB۸m@?NQ+ t2 GT' tE?P)2EAhs%a" \а$΢O+½-n|iT޶>ֶa3A*<#r5 Ļ<3:C<UyYnM+X"+HCtZp%]&.5`>AݳղԡUFBʊ)0Р֊#*k^"V2lu+it͍ꉙ5(&Z_ٙ)"S(W亚B4M韄+m " 7mJiK}% |jjČ4л|]T)R o'm*A,l&E8)^' a;,vNZ.?byr㘈YJ~} k.'Y1>rTvKX4 9I[ q>rkgIοb/)e9q'8/-ω2X@ p>ο7:W bm ڨƎ8V 29_!9Z ~J/?s{?nDk)~zO6xO%U:oMh&/,0vkS~y5Z4=(yD@zCSdD'aH?@ ã;1Cvm`p"bAlnVDifW}>W`6+1)WADAk+z{S̛S;G`Q(J K4ecMGʈ[;>BGnB#|a 7Uɼm7:~|h*ӣ@PbW`!IӚo9m2eJ){Чţ{ B?^v~3wކ垿rD0VJhu)$L}CC f[3(ҺtnAO&T+D#й4TG!k ݸN +hH`Ռ,A &5C6FROswlRyH9UlnƏX5 mhDZ#śtg_`eWdd}/ i6V6+3¿2_A,`" w^XunG ߀m03o{,1?7 @y=`irT]٘9L|1RaPx^V\05m1Ὀ(mq(Q%O~zǘM哬Sfgɠ&@bjˉN"V]HV~aJoo܎܊8mw6brSɤ;p'4 ,v%jqL47&ԌLY7dT4sM:^,ԡDU~ $tF5*ҿev7#sT{5(pw8bUaXLy8=H8'ϠJe߆(IPB˹Փ{ {\Q4/w̐M> Vrv|u&Z8%g:U=J(ap8;J4rӘ*F1 |Y - k6LxA@Vwy >q%H&i8>/?FƄHgQ'9hF#+;ǽAQVwK 4BhFbuӟdrt_r}~qkKxAz)初:6ºnc1C?nr ?t&v.E~ZJ 'th0n[穾oM_{CJ e5XFJM%Җ>GBZ 5p MsfBW:2^ȶA .:JU([ K|)Q!U SO$G}V]X"TD`D^u9bI 18чdVf>G1Xہ=z4eF z"BIF LFDeEbtrpB0 0*PBYtV9 _C,at|$NqiPOLL՘]9 z5d X9^s ..N ɨj˭RwQ#8^@WRxq ubjώZXv˲e2zT:КkQ.v..ړ_cGRKHkYGZG5cL.}3[:áX);R$lDbu'r\/2ow\d  Ϲ 3Ny#iBe#{>wh+e"-HC'\.- zYi h8!nOG;*= tV7,e%pӳ CC0K礪4k2b颰 _YǞo^8~('25'ϴwtr[x_P; !ETv÷|T NO'Vm e"K)9/^\V.@(]GC.5GxLHӌ9CIquRv2XnWF{Uf@2/h. eT E͞kTbn N>l(.i8X:9*1ؐ uR]4eAdNZ ޔA=C;e G8Iw w];#t;$XۖP3a88r#b+sQ#H".7χ522) Z^w{ZP;-Xov]Zty)Aܤkҷ3Yʉ:蕾+. Jb Ǜ0Tem;=𐳂-Mހ׆t g!#y#o_UY!oKxE@̿'O8;; +g#=' `}^</YOS,=?i=B d~f3e S.TA8&+`_#'2Y]} *<Ǡ\6-7wÇN't 2qUr&_qP&wVy=45."E ġ7?X☻7Q{P1ޝ+(gYBV,~ZIE[#6X%8^c|CC|߽`mm_gP~LJQi X QX2k25Nư|8vkQ .'Axմ1q}TA B]К*jZw.U~蜔լ IWaE18Me Pƒ=]i`k $DH(} ^h, *WIi*Yo_\guFBzDn-"Vy7At 3ٕ]m+V$AZW^^2DχcԀRc&G,O3MfF75:ҍ PfeͧDfQU3p.KWm`\@z .U8=QSMh24Qj]9j`@ZS7 Il:%UFRpZjOF,E+\Hvɚ$1tm ֏ V>V=F~,wx]c%y&ӬWܷRD-r~8=*a=KkiR1f!̅XeŧA<&tĂ[~kbECE'QuQz÷] SZ!6b: uZС I[=C,}w3,=askޭYqF4NG_Vǡs̬ ap%Ҕbt8vH@6p6d?eLE 1e`xk{>b>G9<2T!Aay`zӒ(c'>0b&N 6}Oa ~sTLuD+Ae6$yCn>< ,3kpWn{;1"/>d;X0v5{_y~%e6@vLyբxmOG(lZ&X=!ׄV}alS}yɾV5֋#ɨ5FbiGo1kQߊ*TȞb}HghT$gJ\!}(_bq+[ Kx,?ga 7fa8O3'8`prI؁,L_cfa@'SAtOlVTTG,WMtm %g!J࿭4/9'lg,E 3O=%;Ҭ Q/$ gN>Y̠g&/ϯO76zFs\oc^cGkUFpMXHeA|6~@a"' 0Q!' Pfʄ >L6^ޚprte4X+ 7k{+QOΩ潸#H), I=j[I i֋榪?NwBvn"N dSAʯBN5|@2Exl]ӍCŧ1 05/vlGLC=m/ۖ U >:Y碒N肁AM46mɨ|"% m\ d'k1BUmښ9J7qoY5 \sYe&;ܗ*cf8v:?fB%jjŷ'}cѴM\"Gi#Tʯ?H2zxپk!FG%f}U ncGq!n[ㄙan{p'-*)ߠ *zmgE/AN}?z;FS4pTDvxgr? f S9.^pv2up+&Bczx| 'iawR"cBhA#_$.\12z0e>XzqQ= Đ("!kgUA͕&ӐjqC vsq˺o"ņ[ľN&0谁JLFHm4gAAxGucE.e?&1KgTH84]ae1̇قCv<N29UKdLh/GTa j̴ u(=t- VЖN.DCF $3:>ҽb0aHn-y?d*xT8dw/r?.J_9U2ɵxk&WGsSEL6Cs%ذIn\\VU;*ѭbd?Ӟ-\a6t0x38 @֜ڋ|j&҄wsff>Ks "9rP{zDzUijl1~sk 38-}燪ƏWĭ^o_@f_į 2su/2p?:gb4dz`{)^Y&OkWi So4$]F:AsXFm(: >y"oG[e ^d9Yz+ֈ: m7!kmqbh-EaYإދ&oyohs+R%vB jeSiSG; SGKtZVڼ ֈ1:UR | ̩Ծ#ƨƊ9t0YO1d=a ~^b$wAG`!Uo,$u(QsFN胯Kx[Jyl`^ !2؅Y9ٿ}2(>X.֢< ~?5[6-QR;eR{Ugiǹ\p 5t[`۶]]vm%ל>j8\`Ω2jeZrxei  ߌĄR~>o8~f(ы|F|UBUV{2 $L7_* K!!B'+g@ˣ|.a=-F]Së}m%q#'$ӹPnbŤBk{g_:!UxFU Jȷb9,7&݅_*.i)pKc'޳. Fa}xiЛLDzbힽ"je`FH1J8:VW;<I]j_V7eN沲()ms1 8Z2dw1{\0zfyrG_]?zsjBLAǻ܂[h|s(RS,8gQ2{v <'CA6+~&" GK9?F#;ݿwdo0]`yXyv!#Vt1/Q>΁U–-iDh1 NlYx׶3xx dh`e T8bCtLDL`wMPlg-FKamc{zk]%)Z>PE )f{7K4(a2)5rM6^ [ӳlV~NU ezX7DbB.o2#iT\F7\:=[Ƅ߿0K.xGzk! !>0ʉҒ:_(f@{L):nM \>I7M4o*xE9hV~ުkʶzck:}FR{͈V¶=6Ŝ?!6 &b^!Y'[ ' TS7M.'*Lk*LC˘vb(E+>t#w3ן>X<T$yCa)Y<KM b h"Ҷ{aF$I*0jhDa›̿,^#TvZ*C-J:))bv>PϜ'\q|Ăj]A O"5NDyG@8/WW"7Bv' uS@ڀqjEu˜K~=\ܪ&RE˴Y<"N$ɿ`V1~_,췡?s5/!n7eCM[\fhO\ ~Tثܶ?]I6S[ ޯ@T$#zflZ@l i#@JoW2!зp]2\]2GI^ȵ~p,&Q).,)~@J٫NUήand1MpS*UJ/ܯ7B%O?SWU`.8@lzp̛3L4@߇ D7}ڈLʦOIāI=:ؿ3#u?NFWIZTY0|oe5,T?>Ȟ癣+3:3/:\0sJHo(D&' 圠 Їy{9ͅ".ϛq+.ݭW&xulMv|=8mh{6@i`MSS]Tu9lK|-ͫ8V޻1T h9wWe|+A8n2oy\x2OF7"|&nv_kmV"mϔed{a!ȺU3ə'8jCajeHk-7^XlԒ䤳=1w[ڍ*֣v{b0Lq&=ߝT0M1+?./NgNzzz=l78rݳq(d?{z6+9gd5Pwv3mg:Npƥ{ᄆp91T`.}k>GKَ?p8s-C; K׺ѾxJx>((Xu0p.qXpXqbv>¶6j~c8Ęh8;N~ܗ~]'>'V~Rث}?t[n)gf.#rs\f(mr(n~\T}*X8u>z <#- !RTP-JP FgmYlto<~kJVP{K_,^o-!?Z>Zium0MkHmIa +d =qCX7(2rc1%fu$ϭ&cs${R w|۳rb"CVqc`/|'"qgA*H2#+g[KwWyrO ?*>{/oߛ>G֭ӳݳc!&w-W󅳽m޶qԦ54!ޗKwK+|g<J~3Q^gnmkcJ[l?+UlѶovޗn{Gy\š'^{>,8~d6ƣ2:a!][ oN ?M@j[jgւ̽-K>A3‡,+T#uD拏Cy:ChD8tBf2wX ;UQu/21;wt,4>(9s\[uөʄ^ȷ5KܒlN8͙aߴhl}ّ٩i{i  5b brEQYu j*!t4;vuvw#lLꝹI*ϿN+)-*utsHp$Z 2~}@;VQe`k^L\3%&y@ fo61v,P)GX:RibO/#WUl9f'\QLn<$qGLvUk{2nm"<#ӫ,ۜz(m۞%PFҹ#+睽:⽝x˦{u!=cPB}me@%(Ͱ]c-BxXаӼ=U=-~BO iNC;z*3[/=i8Gf'#"le$uQF%qxPTn Ua?KZH5~/Ž0= qyU&RW .[U\A,ZhmsO al7Vڊ! "`q.eoP/}rJ֖ B=S)I!0 z.ޟ"(:Fb,spaZsb8}Afx|b1:_2m]Y`dV( ;QBeq΅Q;FQlJLtŁ)wtX?)4"eRXTu"}ǵāU j'?\%1 eY28zhv=^X@oM1Bgٗy]&!r-ډD|hjvs\ #`~Xa]rً w=o#lz|zo]}&>4[Qh]4 .!8fv&Iw2US80w`}]PC=~zP$.@*4u;xejF:p?=<׋쭙ﱼrTPx{S:8[! Y!R:V:QJ+;;)Jģ%b{VZ%Z-M$ऴ |H$nN-Ȉ8ߣ['Jo7j=Si$zr:|' CΤ EƸV xƼչV],#6r4^FSqP۳I963 3JbyG0K(oPGY]ō :YH!`!LUN?O΄"A1Y\BOTslW\W(FthA^vfI:shzg_TaWr$)+[|y|cYh?7vQ~D ҋP v PjRB8Xp*``:IMɱYwU?gbH98W{G"GUF 6 -RKF &$pwrL½Meh"ِa+x!As,ieu\#Lؽ7fI&slNB/#>MBf}oRU?Ƀfm&-D@e5i6XaPdREi,){_ *G5V%Ђ ~O.VENԊٕOxBc/@c xj>cSD1%puEq)h=='Hji ,u/ ^"ʾcC2l"??}Q*Rnd nI叙c?XK/I:l G>gߪ8Q4 Z@0W[aTk0JU"|UTڵa&ޱ[RvJWj;7MO"Ӆ3ϟh$:;7rq1$GaT+jgʔ\s_V>5[ oTq78+8`cs- VrW(5`cN>ODթݦ[G/°/.I|>H3wv9D-y;F;Ӷy/*(FE)VރUoٶ*1/2iŬyϮ;/4#s{BXNWØъO'_ʿ.5>'!4j?|-XH,ֹkCuJg>lS1od |:{.m+Ŕl_xX'LɂL#~~J[pT. SY>mWVv6jim"< Sjn$mԼ p(\/lB*7rtS@EqB AqN2u)NvFbP r %fϴ H#l Z'؆Q6i_#μFm5Qu8.эp49'$1[#79ljS?#/3""ס}R#tn񶊃J**w$/J69p Uƞz6ڱ&FU" T5 Ɂ q2j usu})"7tIzCt8n632'/e rCZ+f?"'6_70)Q mDsa䔉C b/˶`n%$ ˋDc5ZSIrH,`3kE@|_$xKHCW |V:R!槝zXmhUW{VPn9LyXTmi`oW9Iϖ%mE4-JMnvt(ٙTmxY]~Ls,cD "WLvo|16%1;LtOΊ[mLb?H\~fRymr⩙D׍<:b~üz1L<WU4=ұy`ZY07|RTf"s2d-xJZradG1vR J L3ٱ<>ޔךŎPBA"4۟.*,lJ.{Z,&!ދNJ?Hf' "v_϶ F4}N/vЯ?=aQof9ã@ '4YaE`#EIC FXQFq/TFyڬߑJ b> %yUUdZ{c[4RCvƘI)+S 7k[cEEEwRk'M!*J @ s{ι߽.֞5L!J&2iPN6lPRJ_V O)׫_)~snj -{&2aPaCY>['֓E KY*fg J%{*k?ky2tR8z³-aWdo?`;p_]z^+0h~&gXe9؎+PI0wB*홑 ;&Q2g΋H˿Eaq-pri?HGE٪ m꜒r<0odmf#8-4ĦjΔrhm 3fOS,:9bo*/?窄z*{5_q^_*-_ҵe<OP\Zܳ:=$`Vm j2ᄁ`Ug(2n[y6*4g00x8eK7I۰좌͙ }zC'&Au+Ze`nV%xhhs}λaO3a<4ֳT~eĕQ"N.*r 8(zhf|qḤKvg,bM_J? &S->ĺ)XdߍU{↎+ҭ-QqĆ֗d(q/w3JwE⯜-xÛC.zt0OӯVUo9J(RJlPQ sS.}"2=H3'yUa_Z7u9^pɃ g }Up2u%^qiI{!G#[ڻ+dj/t 4unSCJl]RuWOy[wͪJ̺_U4%3+hJrdB?*/]k8v n*K["7%J3Q+Hh:C濚*.%b~,,a?白apѭ3fqM/Ue?zM׭BJhFC2WP(z.GFc t]K>7П/*ծ? \fe"%k.:]c4;-3If};?^'B]O\ol yfM\=-=ܣ HzIR^z^8OQ7qOՋB3ue214”DrM6KUNnNJ/W |u=bEcER^l/BZu9ƪ'[aSΖ,,Vbb,aWHixUVD!'tlͿؑ1kZߕ}B|X3Gt?b 2>ȏ:J]{hNK2y@y CRkjykBnCvN^g RJ}h*df0_d.\)vpJcZ)UZ`I ԺS_"ߧηA3Qϫ8>J 2bRYy֯]m{⻬=D$z,:k--nL?qZ q7q찐Q3b ؃,9J1 .qwC!ochZ|>);5󫏤LPOs~~;s׸i IiXԺ +אoUg#NfWtx2e|b3exc}^+/{w9pkq">M^"tQ|Z&:fwԯ(>,9.Ftwbo;;Qџ#:FdO}}㟂[ sf/nYy5J_)o>S0k;V[/1z.*Fe$P 8L[3]]wF7<<+ʩjlfx3[b:mRq6NX!TTD0 *@Gџu<xL[wr,8-6 a+P\f@zkTGΑy_Tz:L iB!7EG=PeH&`t܇?GJ ,bJ`4#4O|B,n,ݑ%5__ʞ\fvJ9]44zuv:1}'Jk}xۃy9Ղai<澊. 8^ | ?#y+}=͑ڻ|fS[}2o$I~Ӊ~G%aǴ8hvCFِ rtTIC.>R$ՁNyMSd~U} &pkMt?5&m2"vifvh|'Vc?{Nڄ=Mz\/ צ'<͊XdF Q߇DD Wf B7+`W$3Ip -uآE-HJMѠS)WV{]ouaS$Zv>Q`fwptn1 ?ِhI*F;^I"MfrNbmHOZosΌk8o:oZ٭MZ]}])]8mgcQЗwpVw{:)b~j:07]1006ڞeș*qjM_rpϗ č 0_y˩!ÍI:ѝDl !o;easٸȰusQa"s% TjEAC~thvkPVAS55]ɜZ&_l\W[̰L 6r'`j "/v܂Y e`أfH6tE K4(HtJ}?S z瓺Ku1F>^9d;P^Wzp?٩ܜ7f_ E&J Ǡuڶc Cj7͠+m_;DX0po/c" E}8#1};YbT?$҂m9Vvմ'8r)OQd0ĤmÑ3cN10tk*i L-_gx_\aiIIvqQaI ?$ed'oG'|D >~5ZBXῥV{j䗧PΨ"MQ.Q.U:K)P>ps]+^`aЏTÊ?`zdYu,WSH,'+>5˕ghL o t}{ZNǥ'}X*#Y3D @:ii9%{ZI *2Cĥ v.gfG%EZFڗQk4PCӧoyLu䨇s,޺=1m9v"A2D6woMն/\Y~(6+ 6A9G*$Q R A52QѕeUrJy#%͘m[3pdzzr r~f+Rwr ܀GA k[od!&\ycʝ lH_w/>/CUEWذv2tO)&ƩZXQ6L`Ȇ ;v nηugr$ҽ$"ݭ榳|2gĠ#{}SØ~*c72Nvtʩ27\G !츈諩+˃"k0Bò+X/}$~w3q`Cᎃ8B[U)Yw(y?Oq̗wtgO^\r GCx5xArnx&߮RyL3Q1QhZnKx'XkztAɟM3CEP/" N2l YUQ6gב_:WN3խ,k~ߌ1̕ YoB=#Z1O[z!&$)qa&_?jŪ&˭ G*6ώ=FuΗ+u_}v0Dl_A\FgzE`Y6ℭh|Mo}^ _ϩ9sZAӮ1يzgak偂aD_xaa/|J0ԍÂ4TxWо#bǾ/zGa.ES,IVlqԲlGMI):O^$2g YpnFՅ~Yu;ܥsE{9 8݆3s&+Jv&v8D@Ճjᘗomy[鍅rԑ ea:">P`hO6Mpg8-ȣ2q+0⧕Hn 9wxIma(F^?S` 7#~0>_s+98Ie"oGGU/?gI9 ΤJ+p"ڀs@1nX }9N &6F,3cZMbk~TsY ]G@<7>?IQ.oU\[0 i3_L\`i1 :iӣzrut(e+6kϾjxBauuh}gv9@qK0NȢ_1x\Fxr @Dn{J*rI*"L/e4 @D(LBF d{=+iXHwltojPP6w|[U?,x#rkŔo"kS(|J^` NXwۺ؊b 21.st |i67`_zi&9G ~=ņIeϞbuGb(}#[CBtAAct 5khJ]_ſ{xN{DMJ(wSF.kk D)m 2;u/͆Q/䚿 -Q=Oε&4007vϩfaԴ4bڬ ; mgjqg~S} > |2uΟ.>CQlDVb%f6xY}$lj'>%uqE]+YI#}1#0:ǫ^S>I⺾C$5I.}cr?xb*3F@ucU9~zccÇYYO84wc뜧;Lo?p{Et?&cE~LʓnzKRb݌(e*Y.ECns@/]|mc|Y+Ƕz?zԼC#Dbh48KP`ԗYg'L)'Mp̓BZpe`0=V7#@l-45rwðH7s=S/TJLlLZ_&܅Twsʱ2Qwgj:< MN 26L^SIifIYߟ~$<4ElDlH}E5#ԍP0'|+| 2δRbl@-wyuC6XbU,x,G0 1}TroD8xgcTYKPZ+噕=Ez+>',=|vЪd jB={O3hh0#x q&&/slN' P\͟6jGG lJ)v'`C^W{ fL4kw0Bx0c%kew?ppg7NLB%&6r.^WmheQ"0r\4,PA^m8?5Ν{CEֲ[EfK2Wɋa@SSiFEր XL^`/.*zbZ]SCwo6m0 }wMd;MmC?:-x?n<]gӧGYzCS_2beVwDL;YD1IϞX.'fR>[)h3 M3ڏ];viM X<-7"TKT\BꞽjK:Z)MB#ɧjjjn*p1|1t0K72cceUNLkP(?]͓8/eea`PfĀS:.CM&s[K WFbaqb#_);8!?L@}>m~4\_\gTco)[Y-z-6V2vVvcrˆ{瀊$R{ƹyOPzdB:jM ; DީuḺ&0b'a^,z-δA<'T/X98:.==}Y7Ssv[W.䋖 E1 s_1'j3x *IӐ/+|r̯];/0Ԕg?LHܳ`(LX2iR?~Ue[lVPPW 2Q?Qiiv{5w$W-sB8Q5GtUU^q~rr,ƌVaoV(t M1}lfZi]At*fqn*m@Փ蓙cxI=l蒨h: ib!\|BR꧝N6lNB!ǛԎ"ﵓs uw,'] S2!^փ%6""~bDpB\@ۂlCR89~  ^ G[IƗ9JKKSEl WҜmOD lVRE|@ Z+M߳~>_d i1!},)+jR(#,Ƶ=ʸay A[![[7ng&K,@Tȷi~{1\$ΊxѩDs+y]7 \X:hio>8ս5Wgۘr >MkzZfgf|qZ\.;!mv<ϣ晹k5k.cPa'=}*(qoC1˘*W[5$ tPSqEnXƆ?ylDA e bblVé_""J!%,͹H}nJTsOBw8'`<]#`/~L J 9S}ssU ޡ! ˥2eBtɑD gg7 њ8OܻG|K;˕BrȞG6u K0V %ȋ Y }]Iw>eՎ׆K,l at_amr[?4/?G^/ʥnTga*6,oxo%({R |HU5p=HӮFDQJ:|1YrT%i}q( ?]h9tw ن5^n"EtUqD强ZlMI!I8q.L$^|W[[g0ú&&&h&ڙ(IlDݼyzE1Y}hsuo=<^UTimcp=}<}b=)\lwo9o5E^qz@ÓPZEl2e #Pc %p>۸I@e?޼_z?m=[L6;ZJlQPʽ\r }ZAii0 g k#}cCr:2=SKi{EbJO3%o22jp&xy\Juc2'tS IopOίOr1rb芓R}?KMf5fq`0?~RK*p }YSuԮrhѥ'Nδh+!BGfש* וCF4 u(67Q;K8V/IP75*a쎳 TJꉲYO4#hYa p L*] D0ZV۵;nlB̂7M̈́,R$׷q5^CS:800M>E<'&6FTI@}6脒C9eܨ yꩫjUWYz%.u&:Ҭ1,|9Pm<Bԥ[?|Q?t[&l\Y*ē eyZO6ly9rfҡRն4Y'%Ӹ7=x\RwLNrGGkk4芣@s\Jb=VCAF=¤p{6tJj#RAycF}WD j#DGjıj] q8oPȝ ch8-d8 m oLi 7;B!\B3NoYI11/VEQKO>L;j=h7R}^XhW()TX/2Kw稕zL=ʲ64r̚m¼SA'> ,{)A9Lŋsq5)5줛g?o,^H0־M։| x&>ZvE[?2WR≔̍K_&ԉ5á2`uwB]\A]涱 KK]o<>ENԪ1ή"O+Y8TCh:+Zhɼ`x 6:zF=|R#Q{)O哑  ֘w,%UKteG~))9ͥDB5{ԙ4rC/xӎC^Ϋw[j:"Js1}kՀ y]_c oEU-فaJt007ya@3Q.SB>rS:*.-2J%ph ߿v"1w$H(y\L;i`l^yiMɀ:j]5F|Gū>ϑ?*bVEuLi)=(ĜI%R=*wUtٖfZhڡJd'40Dޜn Bp3f }n)7zNN e$حE`) =Ph1Ia_9?%]N^O>x|8ucRn 766VdOKPxu5}7ZVɛv9I&l~7Rۤ*On-}Im|}UV.bQC볛y`oPnTVwU o^ * Wﳬ%2<˒LyC 5+J{dkZ ~+Z`6?Uxʬ(g7f5N(yzҭVBwd" 6We}-q5eSDľ.\GzsQ{ykE(E*%Fl~F#JSЪ€W[- NI(rƣ[ v ěІ@\ZfY+ZIzX-yW~?:è,&e.]Z{%gO()V*ഇtD.5\(k>Z*ub{' _ǔ<Q JT}{ؼ%e(ej]_}R֨wc㡿X_ jHhٰmr!F1ߥf.$?M$Oӳg)EVq6>RdcVw~՗@؛Ze\A< %K倠ZGQ[R1&| oCΚR.E@u`>|L4"7Ԣ"(j ~F/Nzq}(Cqz`T |Tє!㑋@IrLW vHLsH|ltɜY ZRGǹ䞧gqst/ bcrXrA5x3`V6R!n5uWCѓtqzn;4UV[IZrAX q+΅I*qBN4X.8y7S+ba_e }꿯`dw-#f~>%-QZSqi+.بN'7_X`*$_p[LbzVy6vY.5E͕Aeub;$S|b\$p~zc m&虵@ׯw˒h[7;\;ܔm6In=Keg `S,Zf_'ja NWCY-nֱ YYλ ݚu!Fȃ!R&o!-y7*Vf NtyfW2CD被:VD@!oY ƫN)1Kji%0w 97V Q]_,)fL7oqo$X%EAO_rt3s97(=G_20>-nYu`\k 3Kp??P* 0d ?:Y[8M 5! 7מ>NLXK{ȖVJWS~W3/Gnt@ t~FX7Ԟ% {8K'$MTTi|f뚬m=b])9F܎{FP |7C0e Z wCkő.T!)ETV4x#J`=er}V^3Pk5po*Q9D^R%}CN+/<]IB_ ?k`"ێ"vW0{~"ֲJ'󌠾DKRfb2c`M 0۶R\]ٜހyUÖ[5ƢT/‰J"p ?('@|9M@9#l7;R|3}8$]nՍH0(A0 m oHdL'(U+f9Xa>` )֒HsDAtrk.-8ݖ{/vk%ڕe[ѐ4|e 4㐨NcnCwU~+~<@m;{:7U#Ёa\˺i[ע͒@=v.;>VV{< isI *&˝;tyLl/;^np,ŋ&1)6-,/vkiaM;2<fj1!7uυ+> ?+&H{ /JUߩeSUgans/~RU٠a\46Hþ{@y+bRo;FNĜꢢ\gм.=vo;M߆Qw e߭`?eהBi0W>C z[̀P/3H/P wl$r?\,!խc냝Kq2-EX_[ t,~eg$ cG;vڎ$ɇ\>a6HkocO EHP\s-3CBQR66KDZdB$vJe+lR hisΌ|뾞ӧ?畗Q/Wܢ[tC?}Ӟl蛛Ilvkݓtom׏cZ mߝKbo/_}1T5Y/׶J/9]}k/3Kaլyg|Wqhog␵];aСג0#ޫޘj^(7bauMWyf1rײVLQ~[ZhՓ-C)xQhԊጂ{5Ü{VE*xoFGآ ernmOy3ďf),_ 3gq`6cj>x7|jOr?xe>3sȢ;knՆ#|WkfPSV?ѵH;W7sDݻYO~ߋ(n63BL76ɍ5s2w- W6kJ_6TE~b⭼obĶkyӓnE=M`ίSn:P1PU!b߷[`Jz HUb(ƊJL'|j oGK9<5;uRK3o'+>t!'QoTߖ-c,߿#[&2L㜿g5uz:+V6*.j1Fk^f~*]b[a88oznf 5Kzk>{9o>fA.*bGl Љl{6HC1 4QsjٽFdn2Jn>r >qʧSQ1 z2u#:rFTv^%&sqy&޺RĽK9۪v싘buo/K2@3giR D9>W9MڽR!~W_Zvf>T|2fYu -y3!i֜%k&=ZYglW,CqO`iU=.[uj //Vwn,Q}ԉl+3ⳛ}zW`g>(ڢ9#j8'+;L[Z8 \頜dcg2O [e[4yEk׊PKzjwrM] ۽zJhPaŕw]u"؅a Aʌ sNg C\bsI~_Qu#|714[C|pxsޜϹg.m ~tR₫cLpUST7E4}傥Uv5h%PCEhpUzC`o8zDw{xVb7^*2ރ4m6tŌ{&VWT<ʝ{.Vǔc.qX;jxՇZwLmV\y5AkUf}-&˫DiŅܗfTJW0kȒ TJgtJ׮jdՌ0y핝izWuW~J?F3tŔ IkFfo]|rד@;/;_Plۣzβeoz=>{YŔ'F><ټ3t'|06BƳIUojT>D:ndhSU=EV1>3j;M%S@0VT,y⌃S"_{^-2 jDe хD5o#UARJ齑; 'LK\e^ҹL9FN&6Z^wI?p}e/7]wԮex>.]YQP;h%VMVq!U|[ zqC)g_w{˘˶Շ=;'ŗ@Ou-sbSzx-x:Oãޗf|_'s&V!%ssٝZEh-tK֤u׼݇?.VQ8mfUY+gE{ިrfofN?1Eg9%oN]lKlwmLY6JqeW^n>zx̒Nb|yU+x. pmy΁-';Z\~Ȩs0kuZfp":vC}S*2['JO7֫/in97̃`=wʗ(ko6v~EF]n]jeޖ+~}\AgK>ԽAUڝ^c3ˊv噫+{soz]|%@\Gow[CL>-/d43~5gf9n݋=QseòKcfy5?r)y4Tu9I1suzmE0ގ ~~]Y^9o\P_8>WA7=ŗ.igVڒcVqnXÇ+2]۞ѰVIaᓇ% lxrݏ&b~|ݣ*cy^d0zUd(q;xUܩК_}5|ᣘa˃(%SZg}jjzRҒW-앬﫺#6TjnҬZgejah!y?Sg{.%mPޛ]LqڵA7>[pᢎ7nSQQe0ϥLOLq5jӒt\cm ϳ/IrENOgQH>bOTas[}s]KukQL<K5I*SCfr]k0\luR__;S:uw⌷Rf}g5?CW1pVQK]KuC$?}Vt+@~i5QjVӯ{:/*uDJWFzxθAmyu1Xm>'֭Ւoi8{̡){v mӌ\8\b.k|2ie0N3< Tx0(;kbvy.)=2'ϴ/5|<; E )~B>/mИ0 <;ۥd}eLc~'ƩPvxJ D9*.9*9Ig_0]I[&xYF\;5. cdǾ깋gxc{GusV;1Xl/;锒R` ui62Nl!#B/b07=T FCۆ1QP9L a+,)O($nazWerq`31`\&ᑖR %||ο~bb\"f_E<[rGEetP et0DXF>_l,1.Ε)GB̲mMg&/04r 7*.(f6sS w\(7;*y]A=ݍ4pÒxqB>:4ل'{TqmUEvkIH[THޥϬ=M[:_˛:Vr͇iâLJWD?2ϸ) zSeb]ܕ彝o,i`6mc18Á7,ZSj4ۆg-+H:Yޯm*66bN is֗nZ^IҬ!6HZy_/6>G&$j)TrZQ}ZŨAu'FŖbs3k;aF7.)%+"$7?srM^Ql0D )٠J6(W P&Ƙ6WEXLǎ`rO/ !(i^LY`x^^vGCŎbuL1vNvv1PXÅ$DL _Fy"j2DXD]2A=!n>8kTNo>ďni m6⅏[*deŗ&?!^~kBa#UWsޓ8x8*ެb?B.ZP?zKWa+ة;GWNLs,>m:_QtscO03ֺ+kNK3V*މTvy>O $>o3$cEn3>`3`UFǶm;mk}zx桽N'E޾8l ˊEq'آjGNp(mw7_y4ʻ̊]F]lY}ٮeKLfNz_=,?ePcڋYx݄nqKnh݉Zbq}I?n⛗իm%l_{a|8ӒSWv_NyHEV,Y^o{g\ݻtNZ:VplEUIQ=w4~ٓ~9tS҇Q:uңn*K$zy?QFoGѡN:ɮW__ޞ u0pҳ\߂_,^nl}uJ#Zf]7㲯k[O1Ƒ! @p7_siGwM~@GD ]xl_Exw 7b(P88k֊Cr@H!jcvLWB"4_ oiBh<r(eR)&3+9 #F)i]_;!;u,)' `@rn(tv@N6 YL!|x`FQppQ c PXgw;gW vN.5A smѻRoQ& *arP2l@J%(a~;/wv >.\D,fxx" Nl7@ r~!Tme0AQ'= .$e?8j\zyyS7o\ tq| O| !s?&J֢KKE/#W$>rխc@N}VfczIWT MR3&mvS[~(92NR =m!C2?cʳ3v:T<+~y,noTS+x[4 9vY؆yk\jtfjlinԷMA~0&*!LP &(Hr&AIrd Wx6q6_Q’\c*-5U..xFE<qUVJYf]/knX?R>ݼCZ6XGBAOӎOP_}ARt ٙ=]ea$=K[4fG;I - {2o=~Yz2qk:+Wh߸{1uĹwRM8ֵݮi¢iŲH*c S=u};WT6HAng-Nhgqvl2]~r~[yyb ˯h6;vՆɥFx7{Z7?m2b{5 W7vLO5It~jN>{26yoG*LorN$ Kdܙ9jz]"'r(!:qoC4luƽWz``<9K_zgN"MyN+ҩ.~ /n.N}Li#'sv_en| n7;7vXqdG~w^/<ٔ&j.'6ny]/3ނa^ v_mwG+v>]k ׏B&d7}"]14j|%ў;|i,쌞cGOK7c/R8JRYz)GyocfЯ]B,oˋZl~~p%zM;7n yH׃|qe s }$OFlH,vX}, a!*8| ?;)AP_ Yie8:q9/sͼxQSOqQ13.,^-oVu<=uu=wz_,1Է{O2nPcOj(6T0'KxYوu:{wZWrB:'gZ+ewVG]HZ_CF=rR3umڕ燙;dŽs:[dyEo \gxX9S.lo|fg![mlK}nؚsa Zu%{Gk/橿ʻ鞌rkKN5:&%5Դ&p2>9bX;~66D o"/^\6'2K<: Tp^ *kddXq޶YU% nܲ2hY]glZzq_96%Tm\42gVuܝ+gDo7xvKKՁZ*Ǿ͞xu]r8k>b =?+y v'KֺȠ]{DǗ~jLcRQp^t2}C ߚ}qsk본!ǂO^/0w\uOW9:Ө*v΀T-gvZG0dܽ?ᳺDe[꛼!e^YaT<%IRۤ,y6[/n0 ft~F?7,-OF<տ+}],j̱o/xrg"፨o/վƼ*U ʘW{ݧzl~3CVħ< 9[ypz٬ F 99>7_q^7 n^ki3q 6eFfqMʴfWǬVם:rmBtû*;0:rςڇ +W#o9xFSlw ^nrʾ__z\wD Fw2lmQJ5k9VaԨ;m,Gw{׶KkG%xm`ȵL;V黙"j2<~YSc2R=0hd;jnsċAD9TDYo?'@9! ! ! ! Z%?R.92K%G#sɑ\rd.92G#G#ȑyH0Y8\T*d``__)(@<0D7BE,:`E< ,! ,:;AxU\ F1T pm#(XF*:;2BuD~h#-K!jY8"vB`3Y_ H*\Wp6+\~+Ə%PR-B#AcW8 q LP\%Jr?WNϏK0NBOt?,;vXgނq*0>UwM-8 Qh%J^*!D9Wa0; op,!xt΃=?Gx2 FY` !hy%`tBxD` yDJyf. 4~] ^ց\qφ]ml٢S[~7<vDQ4K9 `~p~ (:[6~F  )i[| -?n2QLa՛RՋݫrFڊa1Z_#O);"a:U;|8t4ije|VG9tf0!Qne_&:ms<Ԭke:z@x3k=UEÚU_C_K0ի6tyg̔x{ž)PIB_˒oz:hJSRTWV{q!N':(&9MO6-\&>׏JׇZ 䍽:&/>pmY=jj{74^`vqCyk/Jйe3r*F,jHiBn?rEj,i܆ S𝑲;;f'^0yL42x^ b=g\辞E:]b맍<?LMs3Ҁ QoNBVd\n!O\BO pDW5?N<]}6#Bv IIEE~ͪ=;/]+I+LMN!mѵl{%'jඳRjT%<+VTk_U=YLߞӁ-g(~qh9ǾNM Tpq.+~n>°VLO3Wxpi mu3c:ţ=0zEP7͖pBx`f7.XT[qQ|[ -!;QHx~_+FNY'ͩ't|ټ$cQFS=<<"W.k0fFyRxͰk1nq)}jcq>,}=[_(XӞYPV}G iFS9P?9Dq郟D贲6nP,〞dm#~IJo:(s?d}#r!-\ZVibьWW/4ZZtȖ]0c?Y3QS`&Ω@R=0Fod8ЋGGO_Z/f1hEՍtnL9HVّ+,9:9UTrI1P\ό/jS޾'yӋI]vMMe_,wf*\5bzIE7)]Y~~kEkn M a&^wF/1z_eB9Ǔwݬf0z *Lu:m6%IQ'xs 9lXߴj=!C4x<:6]gϼ{8.;EI}%P^8I\'Qq&E kU_vi٨5իC/5tfkۭz+?"3|ݥrIڼ'ѭ6`=j6olX{%U㵴b?[2As«Fdǎ[ZCWoi`Zgvrbmn"ePrڮS$vI,^jrKL)u_u8F>*kkGߎX}u-/T,wZ~ꓳ篒U \Xaj*4&x7Zi qy3qBhl!6sKpXm7A!K5?"Pf ûFJ]q˧#|[ͣ0[NЁ+)YBl d }xQwc`c]oǬYa|%c?l6瓝y Q6X#CG -g"  (eM %7b<3yPC sxLB(ha;%8dAp; xAYw=Y [D^ 9Z"J,._% 6 D0YH!PC/ȄE& 0)行ɢ׌/bC ৠe&9P„;1| ޛǥ'<[t46G@B(P}Gw",:_m0W¸W1*‹HKD א#h9.Q V"zi( !ká+jQP,"$1[t@Vqp( Ca&%aQ<{h(AcS GtTJXM1 *aY"tzâf Q6KnByB B D\(%" *4pfUא8:<0hP<.b I)S|H慹%G2Vͯ@חH@)6ZRJqc%o_@Yl U-\)A_\MJ3W :HZkH q&Tab_u~EB[:ЁxOP z̈Y, oŠ(-5%6WcJ5)%bh)A].ȏ@狣BJMhclA j`ij4 PёS! > _9nOR) !FKP LW#1HY P,ġ_Dh$` DE,i(`PT+ΧKTGw<0952*tzJ$4EA%ah *Y>[Y>-Rp<A%Xf [ ~1 #} FKO ZH[aBcz@DJ@rLZ_/Ǐ, B9>FKN Ji5_saa"l>Rh7-5%6poQ+AjAx)gcF" Q4KQSrkS8N(kWY\.nSH H\Afhh))pfA2/|ЃY"1 |qu4-5%Y vV C)-5%f" 恍|MFi*Ň/   D^E)0nQS`){L_!(%[Ԕ8YA{ ]Lo["_C@/dؿ(KKQHjyi_跼4c+/}ժXcB<N?+YݴpŋQ+4$wK"gZ+)MM(z {.裣-˿?Or5}{?Xqu2K'ݎ{ﳟWݦ޾$9Mkc*+q؜=K/lںn[x3{gDî8My}Kl_ 'ש-nطC6Q69 Xy|o͛w[QO#җ9qj> 6|`VswUX kUG*O+yWwmM/LHA>Urn;&wT4wU,(R_j0D0Or1)eh;_ɞѧe}l W272~ԮIϤUKpv˨/TK#oqxiv*4`gK>+ONJjQCdfPwGtGDd-HHԕ߹7rΌ +y۾e^)gpҮr CU&}Y]Qf~w|Sͤ\㽚#u& ]>mT|D'[Rbm>;HWtlH籱3“I  -rNuh~L)W6D?t%/4 {tuS1nW? |@sA؏}zGijaal S~d[hr843uKou':|a*]węEihxQ[flѽCϷ3ԥ>|qz{X] vw}5q{ӬReY`}+΢2mfMY5U.Soފ-w '{R2K__Jr7>:FqΥ[Ondԍiٿq;Cz^GNꕙ;nhHicgO(Si~VϝcS Xu3UmYmS뾯g^ϩ)H]m_州E.CЋ;bă"5f4DL0䳥3.FsvjÚǺ!= \0=rɦo2+{xHEemgx/)(&jnծ$+>fZI82nWY+iSlpN]:W֝S@z{;U_t2,9q|NGF_|ҳ̑iFK~w:/Oq*rFhLc0kfJ.P?~l$^cu$=6?#ocGT|)Nޣ_>bgo≯#fqD"ڿem߲@-Fb+F b+F b?L _B)䊑B)䊑B)䊑B)䊑B)䊑B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓B8)䊓Bo!׿"rZbdl&qU)X_(5t;,[|HXPHy5-XG2 R\!Ɂπ@*Lǧ@!|`d@ C[]gV(6kHgcTç8@&T H=(ǵEJ7ahOq\R.v I@5W4J& ?PǔP{|6gX \>cn%6:QB6ԷCǑg(<'bobGl&@H򋂐M#(ܝ0I0ƒEvS,5[4 bz'/ :)ԙE\Б` M:q Q̢ہ,e: GGpn `S' 7ª-/:e|Q>f <[q~wuB.6 ɦ@U*iڇHA$9IafrIsΒ$YrH΂((IDdx >}~x=]*p;,|3U'RyG3t A<L< |l`(8@jt& t`;m0( ЄPXLpxQ@!`(B==>oj; =lK;> {@z0Xlm n`"g3Hx YP~drv= n0  P@Bg|z Pe[28`#%ϋ_9,`/,0%Ho0%/,g x%C/ے]ͯZ),`I?B*_,`@BЙ,+гvd c gX} = p0G`ds,`~0'Y|A֯,`0N! kY;,`~84+7>Yg|ӀXB/~,W+$Yp;'Q0^'op8 n IXIn $!Hc@YBg@fG $1Vz`DG 8"Ag= nBB~vH;$&,8гv 8B @" ~ = n3O=@"c8)gB+`:~`0#ؖJz`iDDhV@=`px+(gPU:B!Py#!Ug 4w j WLHFWp8pba g<`u76~g ^d&7!CHYg@Z"?3 ]@<1>( [гw!:@C %Z. lQʯYp;/ pYty0BvFgj, =n@( \ zD(YG#Yp;gM(p?p#| =n {I|gqۣ0:(bR>@ǣߐZς P؟EJ,Яx&n b"g^8p@QT;+/d 8נHiP 1#=p;3"?OZ30.U#G(tP^Җ<@ЋXJ,=j <„*0B!q)4WYzxG7 bvNx@@3u{P"?QJ7d! ?7/X  |ߐu&Ϗ 4+`G8ZA l˟vJ  <$8CGg3vг81F0U<lrI,8 >Y.! *y<`y<7vɅ `q Ïп/Io";"c}`"8D(w!hX@A$DAGZA 8M, *G с8g>:n!?W%A<n`!*1o!{d8 p`r0D¹@1 Ug`@áHe>1Hi_EY`;c["  CD(~e`;sj! YCzL~Z8H!H;Q ݔA1+B~п~?k˸ar g9?(r?q@??A{0o?;8wm Y/ezz~zǏPRd?o`stmU0 Y?Iy gNW<~<`aU&a3tpPsl8"I@tGq1hKf~0KTAmB&=Sz@C6х J>`](ER80եvHGAҌ4o:yDw$<:ӥgky*=~:WO'| 8P#G=`#TK㉼ +<&2 ;t~+!篓y=;9/#v=| !y8@bÎ˟U_LOOt{?e 7`+?W @Dp$!SO= {j.=DN^BN'ʟ)P1NBnSyGBq~D B?ﱺπi !@='!Tn_C{:wI>ܩ.@6v2Fy/c q >  c@Nq8'4\=2|"Q0?0< >_3(R@ dUD"Y@Z$E>t 8wRqB-B=WЫA P(N&/9"@! =G-?x#IÁH6>~0tf8#rة|+`9#tj4cyrx,NY4B96K8p_ϵ??E"I , ! ( c$ǁ4 ;8=^ g-a?@Z)iXG_@3&T, }yC~``%u|ZeHV$0*$Tn\ mGlds!@d |Dr H=\DAn'hOjP=>+-C Kid:'_Gr~ nYz!7!'ydaxV)s~:S8#rp9E*YXy@6AkAqNIOZ@ c c_a?`$95Г<XF0@}dSϱBzfx%yj|G+ǣgrA,;I)~\Z t?K?1@[ $;[/kkU+l +&P Y5/eLf9~@?vUacK}Oڱb%"9y3,C8..ܪҢ\go::Ј)^sٱqC3 Nm eT!{" a5j/mB%S0C? Yq֜< T #e|^4Ay7^ >fJJw SPjs<yK#sT^ԴWw+Q%tv:n=Q^P^^Nz{Wʁwj< ֓Z׈ C4XY80s-jyIwUFhqJ)7ɫR&}͍dXM8{E^RsQ],RFMGalʃZ>}=}N.bX󹣬Αz7:*3EBȀ$[]_BF#)'T8y\t*6/'Z:^:X8& r 褷_ei2"1|k_nm:[Ӣ$ X_/`xD-TF4W4NѳKNqh6RZƁJmFZ?t3 tO$suH-dޖ0yۍ^( 쒩 yA4h{sc k {-N\;y%,N+))*j Ch=WlYj3"H|^U+lqPpAGOyPz@J!~KŁdOfØQ*.TNkǛw+㋲Ui>̖iz$cj'6n=_ u~*(ңpQJ3thSw\< '9ފ"oF}y-밥81$W:="WyrK}:P3.VL0/IXCTR -]RY9W-ק,VCW }]cR ]u;kg${UҊd(c4/N[ ެp#Ja=oqi#D6[+|A<xnVm˛G+!LtW),.8ݙ&1ws 1D3o˻b~Q =f E1t./r偵ۦ!A,_FVV{:45wG~<8ԫW^[ÓK W߈AS?>J5_f.FJ+2h.s1jZFu{9UM 2Ŕ?ǣPV01gNrR%wtֱof~*z]{g~D)ojXԓ/j9Mv8cym-{+fջK$h">wn:9 ԺEHuʕK#Wӄ i/avMJTn芹c6 f]TYW׼Z<@vav"]yD{)sɖ%XLulyQ)v]*ˍA{ۇ.DRwjq=5/[K+2)i`vӂm y}f؜8WkcoĢNgg0s$W^a!{- *ZNj dj~ޣ6 ϠF˪nQ .fM(ȉ+F*P"j1iN޽/E#io.\-ۋ@FUqo&lu\< jUҳ:>ƫ6Hf hpCpW1d5iTZBWN~MQ;wt>3;|R.؊5K.[8CM%CO~NŢE+7 jAIV ›.~O #o'5\MiL/yg,jGPz6*M;chsפּ>|WO%]Ӄ$tXjauN<"z%J~ H iM[Uʾ .֙m&SJۤScK07+E{9 (.Bs4ͭhIE=jS{}^[W[w0=^fWְ_}cVX_F\o-y=m~{N R)&S{,oøĮp4E[j#B[n;19JĭyJ0\[pWDPyƇ'0( yOiEevs34d-I~Rż+eRTix_{<~=ϯd#uTVZH6t Oh9c=`\?Ԗȭ\.v{y%O70x0Gj Wv4-04S}0~ai[}O01 쌣aB8rKtor]BCؠp()?ZINB+t/q8:Ž?^QEI};].~_x+ӆ]f zǑSrSXO74 oVa @DLJU0Oa$x5"ԚW{ďq:39r 呤f+/ ~t*DZxqAYdYdD,)9˝v`cf o~6QLVQpS4UpEZan̤(Q|u TY,~]ZprHL)Aj_|*xrVl+hPzBfj`Rh*Uz-H6z J%[J(kC%c"}d_c|WLZs'TB5A)|MJT*Oȍ1}痎J!AZ'QRl`>F|q uL?]fL GdU\:RKb7o1K}9іr2ڞ}x$ {Dj{RG*PI;:4B4ZԔA7[^eq/%Fq+fۺ%=Y\S1/J9w}:[e%פ{#W}~<|#2Zpukq3{5\4r-=k(BǽMJP߅:8QqfXoeV.Q`rsӪx\憏ӣzm7S#݌..mAH$-GiG v6bEeq}!aWAi=`),(b\kA`>uKOԛď0*jgs$wtGj{q )5|4 c$Ziȴdsv uq3E6.#d/V%.1rWU8k *BotK- x2Smܸ#r!gL}aL1>yO+ =?}`YMGt[F6͚zt+=ZL\W;d ]wJA$^ h}[;A9`k(UQbzk^`"WexurfTC?l.]1? ]t1ЍiSJ:l')یy´NlhKo䐀[Qվzhqp]cOo&(.א̨<1$bI T:ӆndWoѝ}"$]PeJ[( Z8/hi/W`侎~H~nŦ-u(V&o#s2_Wh+TR[--6{Ͽ2 fnK͐~낵Vm{j͈EAP ^Q7!lr}8$*_(#s K]BqFsB2͕@)SDAEqj`o߬ 7/k\2$?5͚>- +^078h-k6֮ceVEڄ~{|)-V%Y|\Tб>mj`ˋx I|TCPbӵx5/C06Xzl]ЖxҰĕ^3 Q-eS8+^HohqʢnwֵZ]|&V얨D؄sox$1vA{ʄrɬX%.-i̶c?+@x/妹j_{BJ4x%9hl%>{G*6>ЗPL1H#B{^R0^ LX12gq[bT4"?en157֠zVaZ(EQ" .Vi5?t.O%Q\2tQCyt>j1?"&^;ێ-L-Gy14w{8-\|#7бcZ6xJf? {9s{ߤ ֆe\˝[uzKʋ?7T|XtcGcK)жÖmxgd]}n|s9S3Y2<`KQImmH}[+|ԫ&qBvq?ĕ=#{|(b1e]kɞpůjѯKT0V_xB7C¶ qk&w 5'c? ovjr_lcypiϤb]۲#k"& ٔkL(y}S!H-[~e=M(.SZNb)ܗ(ޮ9S3˂`ab5{)`&_6yK]{eԨ7/TO_Z~kƖN)ڲd0,ŊW{֒hR +!2׸\\IgLnJ=G.wvgG=c\#a;~l拺͍xd> |%VÛyRݓ֌>7ð b1)h:;g˹t S!/FmkMQC~'/h+u-maRhOfeK]B" X!ue&̼elp( x=Rb{)O?%}[:!tǩ1G@Co1v+O(Z||Ooa=;jCNOUn%Htz!h0ԕ Ml~OƾZL"34cZp.Υ5_m|U|f[eNjmlKޜhg2^sZʬhV X@cVFI ="xGdUP%b%-6h8h-98?ѰvyaQFYczX~:+ ua}cg>V)9pϥmGV̈d0:c}\3Aٹx^8a[Z(ꔳ,6wJr3Ƨ>K׺_]ޭ$`AΕ_~Ghp{Bm>> a"])!܅}g/}T9j6րd*X?/ܰHY}[]TA2OUB5`_pO~rUa {K] XFpX]ڦGxh~݃˗ 9of;lFxNWUO2-:RV`6TG2nr_>W_]MZʝ0)vՃoteGm>wOx:qy~1{4SQa%C2:||M}5m?PY;/^N ,%eYMz]4Ho'}Ċ>[w`LJ}Bjc8|+Fɱ;X<)1o hn&JXn)I兖o%%p ZtWSN]+SK'c w4DV|dM=\WIUztiܔ]ר7D *f3}<6:ϨWu:k8nٵ΍.}{E +g4Mµٲ!Ryc\Ԏ!OA."Gfpa^JAs#zo$.Is(H[M/mGS2#oyP}jK(u>BeZ[^+aFY 5Eb-_J1uUJIZEǒ٘7g/߱!]sSQYZ{/<AĪ#yE$AHNwoFdԈ,MP5VD 󏰻8BԷͿ0{tJbwܵ^tâީ O!>L,PU[~WGLeo +J=ػ|>W+x^EJR /9ٴ31PIeS|. UmnHeNЌ>yMӂԐ q*>dzxuoLXN8ޛ^dܹn-BOdY^':9n?d3fƢњ+vsMS(zF˙F?ͿGzDVwVd=c8T˾.Z[oz1Pðߋ j!>z˻Eglzr1žH/ [riGVo 2O#RO-!9(KӸiY-K|xeYw[ӈ%~i6w Ϳ.N[f!kt\\[ͺsM<͞6c04H$jWi%܀E-z+0ð :gUDbOD:9Qe;߈JIU퉐q#2hYҋsS|ߕ"dY?8d4)Wk>dP#^0`> fTmZ>dn}L} %+ aYVz#5}>׻{"ُkM1&t{;(SՕ([VBV1z,+/ QX>0 x Zr .<ΣqOAdۇz{lC7kӴXI*,{}2bXދN37y7woy/*9X"=뎴sSE" x[ɽl;d'p);.L$ ̫P>.3{di?lI3yyi̧* a:QzܯmM>L7ѮsKo` Q[PYHKNb Le kՖI.SZj)t&y#fO_r$Յgf))XK>XTk7v*3hTnWdDSP]ob9TvYܳMt[KVY /j{<#aM1.~즓HEBg^^B;l"=<7½H< ;Q:'YͭqXQ$/:s(%9QF)3\SI6;] LD7;'zc_pMt,s4x RlcKތo`Vg'a`$?ݾ@iްYCeAS D~J7:Ny(dz7N4yQ4r\^Z! vh١x{&2lxMs8Af{ +&g* D6IBv.% s4K 6Z5FS ||X'擳THW׊#\u5$3еY~ӡ[.rZ&lCJᑄ%fO3A$6\"o>E\2/g"f 14YYh{Ƀ+i@W4SXU3|)CT 8Sx[%_}v MH޲_iPCbG&R*9>2k᥌Vi\]T1Es Ulu>)e`U=6"-:MvKb׫I.}V]{H ޏNϻν,}>?QEEe`#VOA`ZE7rZgubԼjI̞$1㑑"N6f=KpN@߭2r^2l&d9,򸙫)q1bM%_Nwѡjj轤Q8]e-Z[ XFb<\U2u6vtpw:YQ4E((h\帪 ͝ 5$0\`e  1$0Dի2p. p1431U]Lm5o\  C'ЅGG*45<< <<7yxTxTyy4y yxyLxLy ^قnj)9%5 -)=="uqqt5uvqqq6uCubdjnsǃǓɞcY"B^/P6 Yh6A`o4 [SɴZGwEw2wwɈMW-y2H٣ىw.-[}S)(NM:Syy>ˮW5 MtJ*M( 64L(ok5]|m[g]qbwuJ7ЁCv)(d %wP^wI'|Kf8/}y%͛I3q*ly?nA-A63_7t/kư0q0=k{KeZ-eᄱD!0>ʞ:vz+WŒŷO_\PuPnQVf۩WoRi Q9+csMT`.P;[?|ɱ$qą 1wHAW.z6(%9KSO/s gP<8Z(OQybX+@?{.݁x܁v} 5YT^fRu4$OVJ ө0g[9_׿a,"2@fyuDY=q LĘVҢyO~6>ӁQDa=w44EkB4vkQ' s{ =2Ė=LM.@hSTِ-0oNaczQ֗[,60<%"{ wӭ7>hK4n,XHŸMV+cAsi`b5WG!I3z$ aIq50 UDƅB/AzAD\B;UO4O;„"C^/luO֧3 %F5Rk&9j==^9ܡVTk`IVFy~Uw8\Ta#.5\éգ6iaPMbTfrLT+^ k`obP&\)\fTM0HuT+r\o#S$ފA'"cu` ήS/xv0`_p"TZXݍ'+QIrɂRe⺟I e2~qvv Y_4*濱("F{hlZo41y"WEsx;'ХkkͼB.l5u#teМ^CMykO^f\}n3efG_!<}z?V$RoKއ]' ,Ip4^ky~{@^zcg=;c/K ,%W$5=?fF3M&-2v >_@+H}+WMP,o+q uHYJaCwYDkl\-ϻ p8Ԇ *?,sd0IӚd'@—|/f] *H:]Ioǥ~ókq+dIY[Za11!u;-h'boO2c.Hj:vq{KpƳq&c(TzIX>xzcҤyĮVχv! }FkAVɍ;s%-X_hoIwQ; >O~x9@$݊* Dūr&in3:\,\5ܑpG }!m0{hyAm;" 7]se_I#fu|WVc߰B=h(l|vEYUΕ~7O$K80B]Mj_yI$r1;wu1Ƕ^KD.Jm>{!}nsdbQB$Mey _;Ďbj[y`\msmƆdlKYر-1>UE_Lx?T>CX0cFΓDy7p G#1f[\Y uc|)r6xn? K1,z0껆8e5t;P>cc2/s5É*4__֪Zmkvz_Xb~}e< a䞵3Z2QV9 b@c[t.p/8VG\r[OB"+( JҊDjCRI;W#5:ZeM%<~ƉL'DmNU֚7bYOxKsí/]CBM0X=roAdq"u@Ɓά&=OfۃIdn4ŧ&V;BS#o^V?AA37.C~:9gvR$g܆̳Q6z"42#A / ΨJr>ı!u `Y8Z n1U<"Q2'ѡAףdAW{/]痈y>Ez8IVbEXNe~EF[9Og7=y Ys&D X8e!ҩ ˏƙeZ `~0rLUAB<ǕbVI;by-&gF04nbg9lښ8KɶGVч(XHJ9ٰ"G<9nl)& WV,q"lbs?6­ axlxh+q _tInHҘu[g!ZW8xMc`|+أ0+K,\ʒ\Lu˾F)X:{9_ϒF'+FuMΤi4W%Vva⠧2wiKU}.sK N 41J%VgTSQ]𖑥>nUV4XYj1(jl*~[: '+e@A>:?w$wM݃{ о歯٦7nGFIV R%Lk~,e DJM|J+Cp0BA bEÆfS|WuESKt´-KhlR(cʹ0ڰӈAW~'Ykݤ%*C_EMl+hH;iRa*,]*ӉTS|=-}#yuIE> k?az ];H\nXP@Cz? ;rvU =Jֵ@7UT d8#&].+(iK;`LZ,У]Nok X 2c43ؑr|O" inW|w(b+۩3u)jjrwV+m5iLm]θjM!{-a({T{[oBfHU=SwҴnFi(1C> jmx26$cnyTք?}rL[TgbD!SU’q  7\Fo !G4uS5~h##zCG9yB9g')zӹ %۔ fy?9iH9=hNy ;!9p5ƴ22F/> QΤ$j>*x5 2{ifAϐ ՘]q0h2%hkU!SMhs7T՜3 6V3ւ lEe?NnM<,!4:rrHÍ 1,SU I'p%>P <X$$N][6Ew=OV ~{f2hl7Mƨcm|nj=^8h6J@? q]m Frp4Bt!U&H1hu"n+£'j5Ef!TSY(@춐DcB| dz`]Ym H%Y m~S"!ս7? pBcd]\4!!{Sb+i>r:ȉC{[FÚuq`B֕k0aYzƠ!?a4is`˔,w}k]m)P^?ܖ+ طqh d'~̾}%<ٙ?p|gvhN kg;IzD:!Itgo/ђ">/^ꈍNXp~ka32kY:WVn; IBΜIrmsh.VوZyoxnB66,15`૽S UG_>2B&'?N /}S |佅dyph!9 Z,CA#Gq0tMwgM<9ݬK.mrcΛ8{;zZF_L1I~ ̿5:<$j>1Bo<[`2}S2QCP[,iݾc =Q7Eq.FSֺ^Ԫ"rcmyGQw]@'úOo&@c*xk{."U&ȏV*'N9% Bud̯U V$!,y|\[j:✉wMIajV dcm+D>7O\31aPC”Չ﬩nsװ*7]{vl%da_9ф}qXܯG8bH='@䉧oV_jC$9A .,ȎC?J|+Yq:Zhh5by 8ׯV"kkx-26N&eLrY jjotV>z(`"ѯe'("ut@8ܹ`6%]%!we+r7NH2J_.07,CH}IYYFJfg`ن ~J3@GCFen秈@(e{wts;,"U_WcBV3ys0ЅY}[م+p_K9_m3?(&o#<E̐<_@pQb.I5'CE,/0}FmݚA bm1zx_]ў.D(=b,1y)EE  QڼC眉bͮ?6R= pM%6h%Q9 I ~0BڗeNB ?g@[vDR3ֵ%+QQ*ΟX6Xn.^+1l't*1yo' Jd7?|c{u€d%9ͥ"+g:D.$fҮ&tze|'ވ=J)1"-<@jLFPS|~v)8w:M/vRqf㍼ li^ÝwQ ^ `Pai D۱ X*ך5KXݘ)g}'|YvZ+'Is-B$ 9"v̗ Oyvsח'[ `LqGBj-?J`D3|OSfT3|ْVm{bK"B^FOh YLqȚQ u='Spz,MW1pDˑX9DJؓf*--!*Vnni׉Dpp fH#c!'B&AN(>l+cAe]@S@?ũpJ` )7,h6I;݊^B&b R1B?2삌[иz]saf=Lq0h^a~ӛC]{$ hC$6Uzk:!![-uE!A7?7tǐ/B,SH3YˊV6l;kR~: iTQF!@,PcFAM1K6.U22IkE5j%~3 OkDAmF?4QYwŵDߛRz|pmj+Hu'1?15LR! 8}>NپtF@bpGF46DL p*O$̉Qr5ف, QIPdO&-m7bu zUX4FӅƙ y,h`6gaSX"Ȁ7,uh8 Mju$|ZY*$ǡ;𢔚Mdd\}+L>.Wp/kF NMμ[z)g3;[.3ḑb Xϕ~BUJ ხ墳&+ʼn mMfmBr7Pꉲc,/F>H*C6tefx )X."kk7sB΀ܭpMi '"0\`v^-=2$M$dcC 3Z&"=EPI4" h@i[.&ا`ezΈ =NW[ӣ>55놏$~Zh66~?`}óؽW54.rzB'ը"Z4΢ EcѤ hqԌ*jnJhw< _bGXB T{FReXw#SVȒ1 ltؓDPg7;:wJ|3CY}hT[z-fgT O^`VQs=~45N fzw$[3nWx$Q<:D(ƄƝ_`(H{AZHTFDYi,H2G302?+?ȏg˧YҊ'?Mic{[[DiJ;:Yڛ;Y(DiF9&_Oh ^ftN^䟶邼&D(ݔ/$VC=m ;_~|:zj$,n#"~5ane%v%>.f&e'-Hn}ު\Nb2mcj(Z*9%|Jr.m[b\eˉLW"NL}8&zJcH/%gےJ,tFS|F/'^9GS=vV?ƉgP5WPWۋx[-]BܔŢ%6:?/:^юC >ռ:Jd=Ui|48/G|xZ:e*5 ŃG=?_>7'*u5 {1ߧܼZÒ\W0DP|JlXJ،kͭKtaj/ \lZlX=25^Hnc>QkCO2 ߓM g)c7]OGiƭ+N<nvQ7>sĭE2Z!i5\Bx63wg5vONonڌm1eyݓA`_}0 5q<'_}6W Bsi^G\Vm'F$U$kNy!0.5Oh̪䵘c8HGcRi lVF.YIxˊRQF%mC'ĵke«e#_k5_'j5$+ʊ~]Ek5˟7zKRy<aM~NӥQf״ӔD^u}G$j}B`8/ƀm~ɓӠ֥L#7gěhә[z7tio6v0=(Rȫ~hmEjL¼Wm*j܀]uŬW:}Ql*W;܂YL&t_Cuc]J,˂g ^<盀5tԈyBYOu/NP}vd4<~mXT2c7TPE@bSO*ltZ2_6Ӑ ]Io90Jv3o[x-i8OlZ1(߇ۃ<WFb8r,rB>nh,uEI-{ -~"n jo_Z"촏nNFbCR &ͭ7^[{7>+sZ2П3|9ĐEE:*n>D?C N66ͰDrmIW>Xc ز3NXT4[4_Qmhu(4?Cy"N'!z:g\j-WM O8ޮ,RrT53}7I.,p ~%Q~,,X{sLX^M%/.CqSB=Hs7}G] H;p^mysbhf\"Yi@htǢ/Q$>ZONWYg[JIؒC{[J hcր!lcYU;-k}kJC%ѕH X81!hgߪƿ=y TCkZ~KFg]W잚3tGl>:@4IpQTG8ju=Vl>׆zީ@ڮ(Es%yaڍ <^/.9Ǥn9:?я!Uf F>|:J{*&*C.SD"T2Y>Oo_wIl+7L G=q8Y_2$F ֿ-`"\2kgIzFsmU].6>d'lN |M4YUBa9\5CbXo1ȍdd!Ӵi2sI0#!$x'mkDevໂ6 ƍ=,XSOK{y~/Y|n.Ѥ2aD.<*j* ؏$vu1erm,.xg#x u"y{+"Tk(0㖖x_IVDa;G/H\,`棊j̗H0pc2|`H]PmW"zs[ E8|1hHg,ۂc5&<"\!+ϡ*5~eT {S %{y9_eQ"x!*a9=SO J'E HvJfP m7g:}ʩ("axo< ze yMRi,NecȪ|ܷVyklUI`͙zHOI\-)[X A'hiJu/k 44n("ME#Yx:P|NV{Л?JCosZ&`79BjΞ&:o ؕg'j !̴ep# Pxf)b-bG{SX avZ#Q3\o]S-Wf Jc;2:cz SYG[?r Lc*oEH ^[|o,R:,KwnKd'ё@X# 76qgh֬Q ɥpDf$#i ]kVP"F )ZViiV<J+V ge?%瓭i-:6WRyw-ƒ }H,^<# f nO+LoeXDz={֟t6% ^ҽ*3f!jOr՝ ?X,=|k1lYxV뤹*Źi9Kl6vۛؑ9w< èWņįm<%Ga2V7tFfeGK@LfV9eM:EXwI !n!M66 ?EEW)&St.,R}zq12мo:;IS8MyDR5>%A݆Z!f: ~wb߀"qcb?؃wp!\R?.._e^eQhǡZϱZfߥ}A94!ݚU@kqQR<_J2&py*HXUvx6$/#;Nm8՗+![x_.L3zDe׈m^}? yq1L]$5Y~KX)3$z;-mׯV4e yl9 B-;[A//g-Qr{@ߣ ^DGPTub2{c-LBH}$p_?j}qa-1! Hyr" Ătt'FvP*̓һ.=:ᎦEN W73ӃtkgƤH-q8wX垆~4fK|WIH!>0XPuNN)FGc54yTΔ- ,qÎ/9ʩu3ion:xJijk UE=P >>2q5JgRi>'$Ӝ 9+&ig,! a (Ru9g:AFP$О}zWs٭!̆)$rm[ij <<*A qs;l&6ɱ| XnQ[*#G^ &ѓ|ji@ZyH=|-3!==H#D%S@X H_NQGJ)>3wϙ n#~ꙖC!?6226FCFŴ*))5 '* -o%%\E`o98,Jx>넟u磮:Y[>xM ԩ_e`M4'.W ]Mۡ{=q[m y/ r\y( @ uh,Dt{Aa`w` 'd (m#/=+㌝5KLszgI>S 3F=M.`oU%g53xw=zsDJ(b|]51pcvX$llƏeE%O50)-RlQ/]ܨB3/ıqUQ[kiQrk}61i{ewqfr0l539;ڀ^kw^5SNӹW]ַđA4#3AndX!I[P\sK#GIԌ 찾AjR/QZ⺝w{h᧔l_`x̆M#vY]WEmlc}%bw 6gSuc < /h)56꠨̯m;{VwA\kn|ƥdHQiw$"FI]!?ߌe"ֿ+tq|>r}cpdzla'PQ6j@d'W]0r)<$ `9ƾAL%Jb(=?\fE*@uy>Oϕagׯ0 q2븑n%O53}E}?a?f\Ѐq$>44#/^`e/h˘&\kٔBv{lHc*|?9yeI-r=ЬUZ9 6. [2i wV+[{3 0xo=qTlka'VVQ{pĔp:^}0(s5#*&TiӘeW<:P \s#䙍+C.,Vx{n7FD@cvp!r9#r!V F!i~1VI]7-.m|0jG*/s(+m.4G܉ bO:g~ +7"澊һ :pX?.*R\ s1)W {e Vxy- :`'3ӭ;'YRa7.I^ǃ) !֖T /4ABo9HB}p"w0] ZςqPޖ=dT.$/9}pL]Tk集Qy @3:T2j;H更veIH$aOq~WjW.A;i۶m۶m6ٶm۶m۶o;3UYz+kX^Uk{)`J=# ՝Nk 4F.;4A$[T]XPB0LdQZu \ Awod_9LP F_67cfTBI/3~MIf Bͥ-!j1#N\V T@,&Md(M ]^]v +HY&E$W ُM:Ԥ[;\׈#A`(8i[ }:VծG``Z׬ʨ FJQM5OƟZ4qkQ亙,>:uBs6:~B4pj-NCOm˄mןa"cik: 1-6`_kɰ8asQeӄW J 49(Kk!2* ߣ)"E/byvUR_JY$E8h>) +m= ћ;iRỀ%ieY7uS&vyPsUj鳩<9wim!so5nޗ.oyʻjHں92_9YXD^:&Q=,DDN> TH$Z| vsJ3cYXY O7^ywȗ-n^<pSglh.Xϔ6^άh'۬NSV|\{"CϞ\P u2кz) x2%,: Vܸ+~Vҷ]|$կ̖m$o `8nI`$;IIBsTA=wf'-SC*LG)gf)6 WO-ғh[V_&M7(EM}{~>ە mր0 $V,tZFݛTrvfA5ѥKyz:~(OZ,on1Xj꾋g ץ<dk@!mVm3\ cK6*N%;n7AqUlu I59Ш9Ut**'-׺ᝅExFrܯ#Hp2goLvحol1ш `fYYo&ބD"K6q ֏"@vzF7kR"R!]}h8Yv= TU\ ><ԾOE3zGFb@AUIvے~lb587V4`FHB6;&_k]uwkOHב`e?0;')P?PQ|֔Q5{av$[Ȱ9Їr:-Z9g[{hK)E!ICDMս5|)VWMF㑫eLe@Z^:\>j%$w\±)"PUTg}θ 0$nP ?zbDY 7u Յ̾iujjk'ʢЅyGmůttL[jP"76Sճ$&i'Nbb|LX?Gc}rOX8k{^<} qۣ)LVbUTɗk:y9LMݗq_v5*H8)r5yA|DrSii2aooE z{5Qx$}^;`=A1WdNaN>a4-εgp"R],*Ov^PqkYݣ+QM4(a4vwZn+h̥ChhʞxfG!eW۷0l(P_FWAqYKCNX.]!Oam,[b kmgbHsv X;ag+|HUz EٱMc7z'~.)N$RXDi(0ڇu,j,yB8UIqw˫Co'UX%.2$}Ő`Z*|{vP7T;t ^e˭c;0 ̂/'#dTY+ [V/tJ,P!޼ذ\f. )o<34'*5Dʐb`Ӹbs2c}Pwnc@_bGܙ騉~lm,T6 ol]0Eah aMŎ"f&q}V.޹{Ē}`*Y{bkԋxm 8,L'1Sim!8Ze{b8oͧp`^5#UPTz|bp-JD4Ғ'^ڗYhأt$[@*-2+J\H[ n^i [ )xereBt8#tɻDcuً73H?Kdlﴴ"wڛ$OJ/X>Kmx>vCv #S܎=EYxQr^SJ?`je5}sYsGz7?sW K|jtp@w='vY.gBo[׭I>X`ҹ3בھd"(?b„2 u59Kz3Zjrqo^8{cEjFKI-d^ 8Z:V(ǰ]ax'0ʩ=ٳA(Ȣ&>ƓiX($6XDcWPף<Ԡ׻Ђ[̊*wR[5Ȱ % }VdkI>ژL2'oԂ=M_D:F91d³R%9qoBv`+cOt߃#ت06 *$v.ObP4 f=Tiw j..+ԣn1R^C!]ýeA&"_<0W`LRĐ")< l"$f:4éik-'pnofE=mց'M'qCBtAINQjb-?-G4+rβ$e7)j1A Vd_xXLJoPjt˛)' O?zD"c'QQA,.3`*? _ذ d{Q~e ާXGDPpm]ɋA@5_]/v+y Ek><ga>kMK^C6(R%x:Wf}n^5ߠ0 [R~DI;)ZܩC۹ض;`2`]b9}Qе|s1_NS[- 'c` LN/!Q%aIΥvm>ʅJ!zg4%]qбԹ9`IAvN<)]7#[DslT9sJ<` v꛰2t;lI=zPu#152k vRl.37x\s#GfI"M(BϥHHmg6AWHB 8yZ MVGiÎG/6 Sb{A*o[_-  56W\ |s^eC,z hdWӔBiɼm@rءfv~͠O(9D1G]t܉mhU=nBS”ޓǠ;5PD4J-=PޒGI@b鵹r261 USDv &B0RATxY|T\LJSVyqJǡX:ZYzQ 6K|bN'B𵂤BϺ24-5Ph;(ߧ{yMs;369B u+HA]?|(ǙLbOaOQW]3S ?:+mB]^*8 f)TASkIΗkD6m0|ƯqU1 ]'3ne?ȡ҃hrS(eܕWi@?.{̕JP1V腗P'MJC!Jc!rE: )G ꈐtL!/ -I ZLLJ]j Y+Nlq_gvtyirV/RIUylUȆ;zD12=3򸬾ͣPW_.f5ąlUu2Q PDSG9wx"1h" &u'Oko);@maݖGc8$δQmYW`/ 4+a #解*ZB<8YЛ{~W\#RәQH?+(OD.s:0s܈U9;> ,wĠөXLwrFGV膦Si=BL"s%1FgfMxIm]sesGub GSn-/#{ q^ؿT`XN̺9l@J8x nibG1oR^ozbopm$U:5.Ruk(l^fG #oȦ&Tr\){'췾a2/ڣ]Նm-: U׭g|ު |Ų ̥LjSQs}d.lx{&D<#.<ę-'cnUv}$o uƙ$.üw4~}d`ϛÉGP㈳9[v&jvy >^gUPIxSC]*iڼʯޣ|Yy۞7G00Fn+K/قuw:2[Xk$CDC=f&MȌBEn^+"'-u]DSX%eb?Qe2rG}wE2O*`'xZ:-W{TgucphMx9TUezqk~<2bm^uVdȾ#g̈I`b4jBdVN7Ĺo@y׈~P+;!s篁4rV G\I]ϛ;3ot݀ tnXCx:rzT"ʔ<p"Q^*58y.IbmVYnYI= "UsCa.pPG]u('Qآ}"7oqjiV:gI}KDz6<=ɐIE8qByRZ݀x@gQ܀OWZoOal2z`mbJp3YCĠɬQsHc`aVs[@uGwE`bG{1X< >Y]/ʡxH#{HJ)K~kr6̼M!.:ذ σ?W+S>7_q9.: "}.;Q.63"`t88,ue%Uqji`Q[Hˉskd/k\ȨA^k!z↭dBӸ6r + >xOt>nqޕUp!ɇfQ]d54{O޶WU; '/宭sćH ˚HJ` +a'np~7T$$wIősف'U6}h8 Z(=K#;r[]gV'?ZtŸb}7IP-J@;>.5[s"cVNT~FTUa}{͔H _Y簬(jgꏀ~St[^D?:=FFjv8TkG'7R p( /⃖4y&?!'rL?$X۳ݙJ* ѴVtY+rU_C4qi X{c E_%/$u/B_ڗ42NXgZ#ٸ=ǔ߱A+L}̚,rU#d"F☿>,^`Il\Yy?)bXWGtM{ki7 = K~K{}D9Ztе:9lJrT54yE~z5?aʼn(cOk89Z-9݁x,KS}n~2W1B4)#zjjbR}fCiC:=+O=2m}Tֈ<9su9-4EVj Vm"h晞ԊN!5O9!>)aQ]4J"y,&z8R)nc8~˛T/L *-hӖ} YXxs{/A*S G*2xGm)+9jCK tZ {.l0-$ -{w&Pj|pe[%H6_9b3Z(T׿ELJn@-|SGD䛗f%j%35й3+yz@+0mLB~rx\j}p:Nk/|o8Z/>2$,QKBI2>5*kc_1*<=^o#Z"=~,heR!齓[_QRsl6{1FTkH)sC 2s6h-[S.O:g\*?4(@/BIUFUn{𯾿gzr x޺mRgt#wc[FM Zܙ֢O{AF# R,rB9! nx;uY̆}y-WqBNПgXj(gEH{Y4#!J[=IXHœU܅۩Utbr%bC֯Nߪ❋Nm}x1p<JBxNLlK3km^ni Ҡ /o$?Jm`+DgxuvR-xŀ H[Z'"O}R1'OI-BwIՀ\1gs#455uw%xj"-<^!|,5NJ{I">`k֤TڨT[XI<U_2o+˦>e/˻&hRDYڡ%vViP.ʶc.-IdwVxv< 9ԍՋ;Ѷ/ƊC-J'[l5+&Ϫ7Un\3f~K+"ꓨUJ) pHl#phI~Te0v\~ƪp]j`!0HsGuъjJ=| tHoڦܬS3 \ζڐ5[J &pn' -ODZe{`~.֐k@_@b @Guǝ<Q7 f5Ҏ6]B^> :+nts8+NZX%dMIɯ-Gf#]/t F8\h \9%©n& k\Wwc%z25 m!R*! x=c^lmnTjTl]s}poEP_VS%d@:y+0Cڅnss vWaCd |rzGX+@ I4H=D5c((enW[Jg=G(uɢԼ@. 2dqJK$G2V:Ek8P$AD; -(\Z:4ɣ DRw=m짱0g5EKywň}ux>(RODd i F/,Ga'Q!5.tEloRd4"[b+ӟ}!Ylυ)"1)W0ءBAHHYg4oP0 vz2XcCWrV]Y\Qw)Ek$+DܖɨW 11?8xdC3l:Ԉ%w*ߐQ">*eEAiϓۖ/e".THmQm+k#( ҨcSB(ӕGk L+g5P4 3ŗѪ,x?١usMƘz*n&jCY*J(iNCzyC[Wt<>4s#(UҮEn8nH"~S%Y{xXdz ]6&|H] !yT*mU(sB :KF ),$[q@d^/,ikUȺEm:r@eQ5rx#sTN{bn8[W<ÝaIQRUU"i'w;''FQ(HRgC(TK&!5x m{#􏱍?\,Cphdjgcjӿ.`χl\xGW{S#_w[hkq?oO_2 \eX3 3;>уgutpLi%YP2~)H&T:91u|'dLXd*:>xvN$;Ay{\+fX"V2&#ެtqw eq8qbLXjQ_kq={+U#V'sq-aO[{ց9g7|7S=Xr2ӖN4XRTJ$LPJ4@%r RP">!.H>X!KaMBr7{xBv危t2]mYPluҫdq\!z8x !#J:L5@C> j~P2]:R;rT3\nr0~"iPKNeD 7L ^}#U?F3-Í~1H85#ȯ~w;\aА3v+"ȹ+sJRGrh4}+ T,!9t)L ð:r2z5DR}M)c{2+vtD. ëvN+w;öBI@>2sw*&S\ /#8xI Ȇon)uV+ Lr.e &Mp?3:qCZN./ ,0;_G?@E\F(2B3*e튿&:# OuVɓWS4t.GAs\S#nf4|˘Ɩ>(XR9Y&H8y Xo|]pqLZ[+$2n"AՉ׀R`D:ѽ W$k+.^.;|.lsKԥ{^oT?1缨)+ƪL^WjX-]D66HZpX렻HUw'bԛ]ȖfZo98ΪQe%W ڠΗkgڔI٬]:7C0V{FF^p2#ij6. wKd$"Y,V٠̻[>LFڔYi-h|X%'tfRxgu0q[|鸲дbJgIYhқh8TS6VS1OK?&u&uINPU.PX7w@,:-TW'?{xdw5v֬D,9^M>fN/kYLm03dGhQ!(wYNIne Eϸ[ olO=}&x[ q(0}Ωkޥ2D]+*%]6Mhhj%<36a"-BFuExsV gplvmU=4H;o}Uv/WOC,V﵊SqNJ.AV 6mMx(;{"Ŏ_Ti %QCEE[pv[q^d,fvA HRbg6Y[)QQq~7/LI1_AuQI31oSfcBj2;tr~~Q4~ }T~PY>pؐUܓ9aGOD$,P6A9 '~Fkc[*UGdǜG7*<ъ0tj$qtg`ODh'aqW>7LSq岄4ts-v"FcU7g ͙nwzԇLC֠djeYi*3~T"v3v=Ieb9;Y|sH–Qrڍһ$3W7Nn|ٓWܑʫYJWavl)+s6%rp~tB866blmxLW7zAa^[0og$7o>f@b ]|y};ȶ&e^3奸]j}lʢ_ݗQ{A(LmܸTBˮO0YݦA.PHЖ k?1:6z,47cbx?k!$Ex`LO6iݔHr[65yZ\~>.fkPV'O/PEeO3[cv eݜ&a/7V`An*ʝ”쮩mZ7 ++q >'ɶ2e:~VB H& c;&ҾWMϲC:b6VhwZz-VCLQ\IYex21f1!9u[!`W[_yP™rjM̧g={s\t/{-2@,5:uaY:ips=_퇀E[ܙ%˵MgG+?;B>՟"C_̎0D"<ǒf E96P9Ʋsahu!7ʢkZIYUMmt`5\K9 )#^\(kؾ ]RWi<roksZ+5DN 2񫙭 _JI?ߑM_[1{r DH< ixѭ1-['͓A7eejѯcPm &F4'J-*3ѱי]ycoڥ c{oeY9W&aiy~kz!u_κB/7=܎qEkɹ~F""l~" [.N\UU\/YbHD+%ZW&N.n_h/BLGhB߀I1Uь+4#SC!/ tD)qr)c==nR*? AI"SXa'0`Ai"PU du7 Y9)Rj|+pODE}j,0x#_dV4݃ xI (Py Dn}{gv﹆I,&P(hpVZHK|WFfv{{ aV>fnDX @nrw`):o5y"+q,!K 0ۢ:9n$?  @UV~g993: ?M\ 0H|~׿^R 㒁@2c\0I@B- @I߀[A:n/BosI`~HA[$%>@% bD*(ߠ< R<@O K(}@ܣv#vkhaHKA15 -@O\`~"> (V('1!W1:cK=C1R^@/GuheKwr}Ӗy7}ܞ%0y޻iwUQw<1nNGg/#3HEn_Ӎ#1$TaX$3TtU[gjɋ۰ |wbS[ &0j}fb -*j sieoMzRF1}<P!zN1X:ɛY3M8Dž`5-u(+ YNߓBZ/۴a N_t}OZjҼڶʩԷ+MʙvsYO[raZ!T=jȗb[_58\a;h.)tr~A>\d>o51gtV^='ղhZn wh秈/ %۬p]cr:C[~P?E X(J_/!^K=ٺi*ZGk]lKcʟ+Zqzl3M)ckʼ hld'1J:-:Hlɲ6T-óNo$q;KѱNxQOBe~ 60;Hsj|ty_gSLt{6t)/t/6;~.G;,Y0)v4A*HJK)a>nʶ燸C70n;hJIke۱rjN ]e %_0z%oJЌ#7+ }AB[ MˤNz Sߤb`AO;bXl\:p V tW%aT?ZKƧ vBEtge1BM0~3<&'RmYSP lYP6Ny{I a })y&g$$.7~&L\=v#пK^h鈷*<4mβ][+Pg2|}YC!&N,ƎA>{繢4:p?ZpvBي% j0bk&Km@ \H !2^3 ZC1ܔsZiBGM\,C^nƅGu) vKQ+ CYEaxd6OݟV㢮Fۺ '+r0˞1•JP svOGy*";LНXmQr.YB龍Ń^ఠY5- .*5&VR~䤏'ӽC`?q>.@C_a("t7Ӛ)]S'׻wuU4mЦZ<7 \4$pTjPΟyS5Afz|1Nb o ?nA?[)e/x`{GAQ/vF]c}ZMIE!6qPP)njV#s6nrdW=;F(-*GF4'& }/_Fe&IlHwckeX"ع茊kYp(Vb !:oqa?PII%oIJw=5=Ɲ{bطQY}ֱǪ.j؟i|׏fSKuJq @3e֢A5m'\u/5#;67'u4s L}C$uNP׊иgz"qv&,R-Y l0WZoG6 х+5 tK;3,L$W9 \~Jb6'#:I5xtƆnHLR׈Lٸc 녵Wlw=b'1IK\H((=]-g`0m|PE$՚PKrE\T\e*}kd2,mI 1'?LB.N#un$1c3COI.HDNK4z?EUZ|~|K~wtqZ;~M:2Y\$?'LUV/ɫx?T=<VJhnZ՞վ,zJ!I?7N.W5#ja6g^50`Ynkq{r5/rhښo 5yuȋa4*I#~]ś-"ݍ2۝!)"B_@޳mCʧYr&{>.OߡôiO|c@PŊГVTf>,|HO+8h<3&9Ղ* ?Op~/6ks]#+|Gyw8R-o1ykEa%[ Ÿɤe?tKZfz1sm*OGō6mvlcK2\ *F(_6 ś\Yvg< &,lR=UA)]NNQ/ԟer ҝ|jIӭ zxړRv؞뻪8`7i;j< ?I~9%8a[%n0=!"X64duBft<9GX>g}PRM7WAj\^ \$װn[cm%Fc.uķp*ci,57'Tۋ+ ޛ`fgck,,Lbttrt/;e#{ǿl?lm320S32%2,zF|d &#ꩊ)iD*e;KHZ%8''[awgo//i,)lǪ{dG -܅:y9p8:?0As ȥeT`zNv f~f|*7hbONf{Gn$ظR_44j|`S|(6?r8rX\'}1>1X8< y !B~E`@ L/|#Vg`>0 ÿuȈXg #=|KCq& u*0_xqw&'++Q܊<BTPS~fNGL\ICjv? XqiۚbGY&iH#%NS]e<)<9fc8EknbU$1]+}l^RL -oyXTm-@ ƖjՄRKMª@c:uۖ@ = }"ue5&a5}:W/Vu^W*u,A!"$D%]*#GPdwY_`n&uOx4:\m-^48c)fq׻pG#+=5yo#d艋%d(]3Kx_̂R 4qÔC 7VbN~Y I- y51vB3sN|YŨB3MOd;^Xo 2kw*an5 ؞Z*^~?a2n^*;-;_,k [ _ $Y.ԲA\4v1SR'C)3i8Җ{sUDu v E/UYLFXLU'TaЖ؄"dV'oEX}X> |UT|S+W ޡF\ gi5D]2^,1:^f({N4%ĒmT$źl_&Jv37#j}S=v#<ϣ.j]D"6y WG}^3Ť 觏_g}'EG)Mf$2 &\CaU KEB<&ǻ+J.Rv#(6$.71̚c(k]o$C+S9.u;E CE!]S6Bp(W fKu 7cPqP6Y=bi ]OA^ >0$6 O'7UlF9w?]Z &I ԫZRUs"zFZw]dڌR[u H_\RȎ cPD;( K%2XpT+A|w)5BIBX+|G+ϱ:YeӰoVak*qxqis,H˚;>f nbF&] [4HEzi;/gV.ѯW4=[-'|5HTS<8/sD' $o`ñqXV,DP^/+^"DΊrwp"hy{]^!}o[oˍjxhYQTakMjǰZ GwNbc*C#e!A lN'ܐ ~\'nıc&_]qSF Nkٯ[nK|o Fei=#3OG=oBfB7?v K'~qJF;c5pfAZ|Z%_uÕba VZ.ɅB%":RUIՓ+8ف>sYFHeІ4N!]o;3Ao?" LT6J*p5P3z"7[Λ)`EEغto(Haʆkj֒> cH{k\ 븘gn;{u)hkGkn. ҵ2M1+LY+{ )漽GiL|Ѿ8y ܺ]/)&j. T6` g6i6qu.g=^_9ejh)·iJЙcm*t1nH9I #T)]#,ߣӻl^3qpUlE֭m uF>0txPe&Rb9jw!H͟J8O*}nϸuXSuuͳzzVu՗ëq;eڑ YW ٩<|J:5q8E};.g6"*젨?4u`[zפ ^["'sՃI=,DL]ኟA0u GtݕzB|݊K.RιF!ha QQ"t %qqJrxnɤj| /b\-刣.M>c igՌ&HzCq8c6,'5 M|;۞8mbV?eM4%ߪqOM_Ћж üAɞ& 8mD|Nnaޖя.=(^k*uL70qбGw 'o|Ԛ~W24P/Y,?*xWd#n @YA2W|ⱋ}C I QA"0o̓>Ҷ%=EG#QY`=)6G:D ƿ0 };ESܠP>?0Y!!)R$aHX&?3<*F0!6b*(~1',n'G!΅&OIc.!4@Q`et}p gO0_ `[(s`*pάhg7(f PS C}Ƣ{),0CsvGfq0nPygr_SFSk]܅dybeޙUChx)g.9M /©鶫DY D_&TxZFuA3j(!Xf8ixj@IÌ6]6u;,4eFSQ.;u0X՞WuɷCk-'U~+x\u '^Gm}f"h0*Ra.?M:d)LHMBp(hUqXI4."RC*ŹH{ƚ_C̵Gg]mx>xkc]s3 G+Į։=$rU޸ɜ2YkwgSA_eWzt/C69$S|ЃEaŤ6:]Ts?C#Gov/;$oL`}wEDwj,5?19'UTt6„.BX m-)+%Y[/,Bt\eKn3ON0[2u d:K!NE%_9:3Ѩpj}G= 2'Fю(Iԃf[LlXa5ZU}xR-ؠq"0Fm6NJsfS{9@\& 'd,֘}6I.nev?IB çޚVIh`u4)7Q :=>D*v]wdgZH)!e(Yc]̾ŶCm`q뭧hO숣WMMvgYh81+,9uqcKĭQ)iMt-i":YZHA<B"q4e%|h0zs^PBxzYuHӬ]ORNPZO%%%碬xLI4}O\l{SketLdr,FpmGО)miCS;dP(\m RHd%fJ,;xU("SGf+'m%o 8U.5JqoZtciLHJR+f|ɖD"SQP>!qOJum 0Lox% i޴۷A:Uc(aa) c$],P0|X*{P~Lu0GPڗhw9!B Zl fFN ?fBlٞbZ*фػq"2nwwޓ#3ԀO$O"Of6PXD̂U*Eu|۽n !;(ϻ}#a]VDh fM`IndDeW (?uvIpXj?'̻0Z~HsE3yO]3t~Gp$/^rqi*[]u4>UR^ &^oo9%To,Sjc  [m2۾{\wK?݈e|n[x`6 l.[[D\ēeLԪYO;5&:Qj+Y% IGӣsi]nvmQ \SI5h.:]X,o5T,=QuICuoZ鿞!rbl[,cP3t>,<7dz#EXMu!xD_pJG.n{Qn>StU0#WjwMeU :`\}F;Xl*GoSwP'iOd-? ЉyěV ꑊm DFBF^oS8TͺMn+{]| ; NFFmKӊd;$ J,!|1 6/ piBY9$*X7Jc2ecԼ<ȩ*rl/Wɥpc[v'^jI{=P:g3L[m.̯}2trګHfth/>[_K]dGų#6D|lְx^9}V2#"mxwn0=&o}8%.l-oFz<㔛D&OAviSFPo2w|Yд)"FEV,>H9ML23N=R*mձS6omYRQC& փ%%W:, h̭nͮ*oѓ't+^ !nS}"Ujy1(d3ۈ:g13!AMݹ-)Lwܯy㷥 dMb3œ:ojtqRe =#Ǽܕ~d/E1S6pirDFjzaZ_١sYL* *id㽞E4殠 %%ZZVB˳yl1ˡULؔU@w[DDwgHV,d=IKN$sS .q? v}]pGU?S1)[MQ<$@FSZu؞t=AdT<+ .Z摧fN\۞2V7>e*=v+/)ޛ`ýlncrP+L6r=^*w,[}bF)Mc@f|_X|fP[!#\MI^5U+$C1͆tʝ+QB>!YIRӫf[H9ݭc\괁/<+9q(nXǰ$ nߥxtk%V_"3Znm԰vߍ`5QsbPH@]SQ/20}o v SB#^wokG#rJt2͘X;^zڮ#;$}pccEZu؜⎎%WK]HSUz[ ?r4bR—850iw , ic<Ǿν:C|OCf&aˆK~(!S̛*`Fʻ]J},~&:M2\MT ] 'd8}@rEWni%CS ];4Xw%JAv-cjܨu˵lҼ_g>(ruK[̖ؐMMN&D'l;7E Uv8눺96流lP> k*40cb#4*<3-\x wcuZ\yS+hbZ;%N|/H)vJםF]XN8Un\ޅmڲlh)WGSbx1C?.} F}VՌWNt<okvWٮ6&0@FOKwP0e{HzE420BKƙ#npvh65kGm+먃h/I=4n&v %&@eZMv~pk h+v?jPMj%z#%)dY4z9;Q<]bB7J[ԭr .~ rn]eqL2g/. S܇:' 86/GXAJb$hL[: ǒQ!ux*kk]q!4uE<<nb"M$C~Nn涟yIءGÝBYX/Cƶkk͓>̀,#V>>I9+_{4G7W*S*Rc9yFu'\&zCn`=0_Yp5YCt3KTڑz%H,ɂO%/:MOGJÒ Ruy? qYWý䑋IT:,ue1(fkv3ޟ3\RmEy?Wӯa'b`J&[F|Ԇ=#㶓AbNPXк.xLZXhr uX*zA6<>cPHDRZ,o[3؀YM/*LUh˴ צOh$jW T;#jM_eNC<2&.n2.`B[%|OE@ʥ0CLTk ?LldVxrSX:T"L Rַh9"J!C(vr3-(4$gbm)Ғ lA*#&Ǿ ?]V7' +D!M~1jA5^f/faA:'pqgtP~)Un8r&6e{?J=9T7 `ff.x-t*1D1T/Ô=`V?}Vw2NSW*\;pMǓ^R\PMWqM۵18$z-%o^,Zb4q[!xHDc - H iHif_j=v-Bgbz:rAgV+O3YrаNحDxh?Ѫ|IP]w cjwdJNa+߷֥xj%X>ȃ:fc鬒nٮ4.Fn 5F=ei/|m@wE5|mc?;rTV݀g_#0l<~m(_.U_?[yQ7s5gDn;СIOZ!(R/$.%aM@#(>KЏ:rug 9Ϝiivے3SkdhQf#a0kWp.ݑf1Nm) 0H[[f],|O:a.XcwfU1'~u=Z9ESsl,@nǤmaR%U;뜪УL3~vnذ 4ݾl1+/M_L]V-Ԍn:2rߋs|_V"m+\#6u"ד DI!KW }@JRj:JZ<OBMTsܫ$knC֧~96*Er/t~fҭYd<. (<| erX<o**Qj]MWK`Ź6T!Ag vf5 p%] qaMd s$')mK${dGW璾Hjo2/ByQ={lf^,eo rn°8xޗv[>>?A5m<|X-LC[.?N( ]=єɉcTctҾ'SYѧ4yClĽN}j/!sByX2"ɳ-Q~4{d)lY 8(&PHoK/C3.$ɼ*)?+=/OT/&r=d(ͶFs_;&~ȒRJwa/'[wuH2҂+H47 QZ;Y>#1$ ][Cυ@dNҌwhCyԓbɚxxq\ȻAġ^1˒WCa% tx(gæ"GU`q3ԗCz\hzbDCGSQnd؏*Ll%k&5 e3#jQgXӻ5eiye.4-Klɺ}v B70NՆ alj5M,: /QRWe p;{jїv&%Um3CEn,:Hf=oL+`N^mS U60UI,xNs0>Bw$9J9m۶m۶m۶msoiʹiӿoNvvrzdʏR ; 5eF%P~  WOwgWǢuL&*T+͝Nz7lƒt7+bCS/lҊR sa%> ϗ$gSlQGezښZ*oсA!~9ԩ7~]h'ֺKD4g5W7"dh`^V4IklE;׏YM bGωd xS0:PĥX*2>յF͂ ƍ}/L_uɒFzQVP?OޗÕ+nƶ3z>)b1  5OtQZԈv3wMןa)FYhA{ɇ;*Shi4VA;ӒVz>m6u`;n^5HYۂ9#M.SdYy255 ^rh56KoK^yW6D =00&44:ÂםS'g&9*~#], )fūL鐘Hnj֒(WDQfJ1(P3=43XQ- ӈ::!*)QZjC3SKIl 1AkŦ"rD߀z9=erjץV+iYV*Y8 9\Yì"T3˛twB+cf sNTs~^mM:f ǧk0-Aw3-8mڙQ\WAn\ͦBu4P޶59_ k'U 5"0B| ks>B[jgˆ+VQ_XK;<Zé>D]YMMC'\8]iQȴ_XFr;;3}z1mI?S1@z'ʕ~&)Hn}bԮ-+g;]1X*4X[:F$7q^e-HgFCD?#ڐw+bص~²PbMISlF 6FRS3{hXWz :kSqEY?{p<"Ճ(FB)ś*S{6Mt?w+v +ڇ nEvu=8ˊHx!F]oo\^unִm / `t6lhNAL\(" ԣQ}Y6; TŹ'ʇNaNEJD]>S t"j|C?K}\B !JH׃ain540ۧDo6pV/z@LtjE$XwX$h('+4vg`|k# \(1*8h%Th0eOV]`RZ>C8;Hf* @$gBp^s9A|A,5:ǼF]xWgǼxmZVyJa3mLFL6tw ~ \`=mzhx\5AyJd=HXI!dϒ=%䆶'0BqsgLln|[&Duy{+g5*dw=}Wyj'.M=%sYk9P̵7׮Y@k;4t7`xqkKA:DWoQ%—֠^A!r5C;N)e~0>}HH 86V-T{CyoK6v`?t*)kP (K߱ldac6ws$w[yr JaLmcFo8lG;x{ !X&&ed_v2-Үd&`ONx>r F&`a-2SPd9F΂REd G& '蟜XJ* X K@N FpX 8/: _X-s(9J*mdT:?J``-w,{8`ZJ‹ k͟p C.^SCc;\z P GҢEӗ=ښa_ g*z '# inzbַF7ڪZ*':ۨ'B$=N<{k!Y'bD.#7C?tWr{GIfdwojb|$0+H? s԰П0+ 'OvO^K OnG? `}K` 5rZԯK~1nU ʿ韖 #p/#ο恿cp{ϑcP~ﰮ }o,O db7?;/s7 OiCk"Z{swel?/kq?cdv![{h{so H rQ;]]]Lk͏eMO=?c?Uᗝ>&zg_xVoW-/# ~那7h?#*Ugc|cynmAz#{A{ G?{ ?ߏݯ81ofM_54 _ooTu_埦=*TS e:UIpr;ZsiGxJKCH`@@ Tx.m /@wgEK6%F-FU`^j-ΦN4#.,!A!'iSZfTpIcOrz [B[L&}uyCp׮(;s.dL V Rh J7Y4oz$fTxBG @R)Yyϓi7sXZX uW&':wn$ Z_4 ͗#g}彬r<fU8A];G&'E4NQ($6"X1n~s#~Z#髇/[ANɲKSWUt ᝆ<~~_9˼|H aT8Eh42#s8N2Jo ҹɫQ m]}o:0V~T8^BHd &WOo8uGuBĕ~B^*dy;(!CףS@KM "_$̃*<l"\<]8){ 󸯨˹8/MgŲm/ ,"A߭Y1>$ZވO~\!s)V0##HfY/=dH-^F#Wȉ?㎯*#1FXSiGj VSClޝ6+ۢ]VKX ,ۊ~RR0:l}IʅJ2l^\ h8*l@yT eb w߂"UB͆uzJˬ%BaPdE{V2~ 5\0}ԸOh&c6jU=n~ 멆_`؏C+qPxAr'8vOp؀lӴG/DD8.<՟tCKIAt~0•2_[,%"pb+e. gA?X.쾄q^"UDj`` T7j6L꽨(f<7kg\'D:Y-GܖMYTƃF^m!4*qvg<.vʲ.VtTLY|^n*þǦ( 5nzJ-ݛa""wA_U]Uԋ/+kO1;6t> "|r בvdtZp[Ȑ5D7$ 1P$ba+ oP SJbwh}Jw$~X%YȮP* 4ah~ͺTyL- <Z~ֿX;@]5O2_a|h%=pmu.̭ cloŌ7g=wK-.qi 3R@ξ-Yn?_7U{ȑmiel*C=@}9L)vq!_6>uܑ+͑ebJqLx1+='& S6Z4WY2ϣ j ڍ번|Zg25c-g 9nï.ȗC6/ 47k L/SPF͊0.WٰH5 v4J}$\OMfgNQ=(zh@%5Gu+ʳ9TCcC_] =%F'y0S2Ǜ]ͮ>[ITw0,z3wI-3ZbBqWFtKfw`~iHKL$T7?ftf6]Ԕɸ`YUۧW'X`gF՘ 0ji $7V U/q;O)$_4GPUgN$Ovz<4 {C;F>2Xӏ!"߷k֙gd[jw\UzfiI&*V P+sma ըAlE')@l~6./y&3rpkNR"k> h s<*Ue-cMiO .ar3cJ5ZЈ+׈ KmG328^H <FD QaPu& !z2IɊTÃT@ DsZLd,]X+lʎn% .3=vwd<[\VhsZ/2 ސ1aPYSj6)ih5wxBVqpUӚp>^g\d?.tḧ殧U1O(zP۪tCdda,em];fS`\S396nb{7'sM{pJeK" HgnB\HhE;f*l?qZ4*ʶDrK@U֝> ǐ}'`鄂Cz7.եkXW,2 F 1HE"ci"vuE7A`Lx5sΊC7aTpwKd5ڣ֍Nqڵ.E@roqam yfJ n*(a&pS+ ԝ BMSFUEOơR϶x8\.͛PeLEu_S(6$+ncmB,P{Y@IzHC"hئ GBD_WIf7PJm<|{}lml..CIKdS#^;MI>]*qi]9k7:?"ø1%g8 ՠ!|qC}AYLdv5'I3{j;F?H%?7q dv,(r-^MI3#+YDqMZs{X$L>E5}L?"`- .v;Nɋ…-<`p'JgO+u-Vnw3@5]a SO}-8Ӎ!E7(Xǟ6Fs30QA;\3sV)$4=>:Av]GrS~,[tM6ţDJ?d5 2vǓ{ lkH9Ԥc,ȡ#^V; :.,r!qqb!0?d4="aMm iɫ?Q}(ؠ˳6$q8'6_4Z g0=L͟;/~Xxĸe{Z/xyCC89., D:O%h\# |B_yi[8|>-7߸*Gb2ԘtH(/vh GI _gtOI >KK0{,.iPЧ>aܴD u;.i"JC}gzDjݝւ/zQK0d.!"FGǨl"cڗDO=?)[9P_;v"SY G5PsB" ^E,Ox#CۡR*Nw otM٧U ΅%3Hs͒aY3,PqQ Fk!%VPc$5}mxٓpԎ.v\C+}I)WMSZe4܃8NW!V *J!Ѫ9 M'T&~ Ux ZG 43q]迣 ~"H«W)"5+rwn잂Ծ5Hl\Ąw_Y ӪOJԓ0T1Mȅș OcW#CrObB4C=as`7㺲r{XW»g9q%X8 y҈LaF*xކ_OQQ)n0~%8R*9d{Hv4W ;>lE'݂5lل۶q3>~ǵXYLaÛbC} maR,c~;)O:7$;C|+W f^w.u(꩟%mp+NZZ^^r`K![JCgi*:(x wYoRJ/KѰp_[48:--m ®Vzn[:@U+\+1 E \ȋi{oj'*FC 8r)m&PFJ"1XB3uj:#`쯯#Q/nqS`e;< [&ŇKH;;C wOΙѝkQf_&82e*uS%xS_%gF`&,|Qa /5݇N ]*GJ|μ)ˊ|L۷W &v\: W-RgĽy3'fk3KS=76;4t}* b MmIg96I戜=X.#'3EiRd^8v7~%)u;Vs;at]mMїNH^MM- h}G"9m JKu6 PbtRނ_PJ6@Ì!rRSw`DjM_O _!QZD.N)ڌ+\ 5-TJ%M@ BT=s.UR.6 /We˘ę333'@e0"Т!D4*GoeaVw6pMqhL"Ib!IlY6S:olvX S7m.>B5P"FD2|f-:mT#)ϸAїUP'e]_)$bob}"P!b1fR?‡o&~w ꓹ5)ke:٘ۘ_//HN _zg f2Vu%xcEƥ4' (CmΈұgLf6U@xnx&>ucH>XSNTt[SGῢ\'B\3i(~{c9+}*=}ɩhċ/C-xR5Yum.u@RdWv{VضA ዐѽMe hNwO 3p ˯iH;y.sNU']-)RQ0'ݖCOo@K=LO&NJV[rUEZ٭)\΋-wt{T.G+-gn'ϼpQ)U@d::; O<=TT0An-uxPHZb;טJCz$RcZ[=Br(۩8wULpL0 (7+ CM{5s]2Zh|7 +c;[{W&r('c޵$VkimHE} $tie*OYAHV*&dGi?y+EJ0^dy#? ,˃ fd1:~gQE 9a7jQ4&w32?W3h3%IelH4y+P6jF4!q4 9` sMҍjjNk WduےH!C`qe]^B;{#D;Goqt98" Pd!= 9'L37,Cx]+ܹ1!p".r(slm&Dekm0[(S)oM9nD h_+Tk,! bؕVE4Ljv%HLep@X V V<9d 9"B^$ļٙAlp`Xȗ3Lfܗhzwhᛑ& +ȺΜv/eh ըur~tѷJ.%£DTzbܓi-]lv c 2"Tz+ҶGd)JrU0~ܭPxhJyQ8:QJ\\H&B Ȯvyu 'Q:wLc*(PxB_KuŔH pmgxoQrdNR3~_|Tv— IO{ 爤!k}eɵtA%&OBm"_SjA4 Ǭ]_iֹiˈzS7*qcQ 3^rgZa4x`ьK `պpx ul BJ"l^'ð%԰3Wjr) j(n6nP^&eݤem|] W;Ava״ <{O_`KM*lpY6Z&:*LKYmm_,\[8:H(5]̧4*b[)<_d2*翈f-ҫ98eJ'M֯&~;ziN/Bifl_SR_p}YB$ ikKW m ~xI*CfcVAER+R/7;t,Ϋ=% o_l0 vjNF6˒KI6חaNj8`\ٽΟIe/׈ӣ"~5M}?xF7+ۚA" OFSdjv.QkέX?&"Z_e4X\ K$qSr9[9/zIz`N2 Ҿr|&H2t\@"tm;F4^ &DB 3gaH3.B*mk * Ẅ́GHpNa`#e8CДy!AϜZ('T,fǝܛ,(*̝qz.salXht+xUiw Yb"xZmFYѭ6s[hp9*P0Tnp69~KUB:a7 r5WQuT& y<iwӻ1&˜mtq6S@6Y)AF+,5';^~WvMP:Raj>Kp=GV;2 ef^&y̗xS JfW7Ynp:p\u5MKXI{=vwa,\h= G,}ZזuWͺ03wcRm8w6)K\Ʊ+x_Mx'5.Oĺ(?^HϚ>Lv5ZZl ݎW\R'K߸Iө2d "M5"ȠX}9m8+a L}'IBevhԫdtG2@HJʓK;Q~EK=J׈=y^j Wjvb\UZf6mǐ_W(7s v 0'ʭeHbKt3<]:B#`Qb+mGE(tUuBxr^Wyg SgK(єKAJ4}v*Qvq:Z ȂW;LsMp $:`vFU19FgI˔c0V {sX.YJfߍbZbgibu}/ >*tyVԅI(Q#$NY?CX)כY ؛6~tQ6!4Jb`3|q zaTww=*p~*AOQջW yr(JX~ a߽rFJ s'j]ʌKpBRa"p?\!n5;{5ӮIuc#@{h\`hc8H>! 2h~vݮ٫xd2~r9U%c=N|~ ,یg|}P!%j'voJ`SPPz.H5q6̌Xjj3! I4X@6p%_726smk 333N̜ 3V*̜ܽ瓺usٲ5ײ,Y1~|Xd|yYݷ{G.&WVM %vnyHBcb¾|*rw7 b]>Q]>yk }og-pV.qeL0srQr0=l?4t)%%Ub+X~dMSAf+yy {NH6&Sngdi1|qB6䩲f,wy(?( s^)VHΕLdV H&>mj*vI!ҕ zA  ;S'5! F-D,:yO*$Uׇ=qZ` Wі/piE̓ X9e1fR -Sꦖ̩ 3t |[fpO8OQm*…6ׇN{kf:mS;maa_ u%Yup!Bˆy[S= #g-wu@%~F7I[K8o60 QD].% aCUXOcph"OL sn Ikc\9bx3k}[[skqԟ"Q_Tcv:|xid oÆ:BwQ덵l /2"f! ,$bMG7֯yL}kwSqmϠ /G'qf4ڄuTx4Dֵpt6Uᅥv w\k77&lUmrMk$i +֛FZ% &hvjz?}ߝUL?!Yψ+ԺtNzcLzL2>FV #sN1>åZ9y'LD*`jdl7//ӂw;q>]w&,g]:dž0gG}hH 3OLTz+Sh:͆ǮG<>+}td?j5I4xUlTLz[i_sH>Nzm2SCrv(FK`| `(C"pee3O@Y|;c XRrqkH IyU"R'[}ǑK ݁a5 ZMz^PxAТ c3Ds.?7Ӈf+J`cS6 +{VIʠʇdu72f<Sѩl$Uݏ?I̕m4ǗD0O,?N<@') Y jǦ\*dW^I*= |^l mRaEg tE 2rM*dx'#& %"\;RS_J:|[>j@RmP-r (X8=[6i2M heN1-o^$/mUs'2 x*bf%1 tgk蒆0F_y 8zu L]&<-o X߰VJDFDUoT?:{G @R(@ HE-(C.P &`h`lhg0t6dj`0[;:[U97NJkSy_'6vmmm &{nb_f-SGWC?P!2|`t0X-ؘ:;\Gejkd,f0mr8:?տk{K{3jbW.&F6*_vp6\_׿V`W;1w27 W !X$߉l . 1D%D\n,3p»hXԆxN Tt"@6?Kvys|][ײrd0?&A2GU D@,PD V *Z(H' z{HCFJDEJ$:!EWIxu2TG<{X@ԡ"Hm\5Aί~|owW|Kc8~^U}3؏Q~h~3FRA9 3"E4z"aO3L,ܕ+Y`'dr! "x!l@M,寨%.1;3 $%'D4vל <VHC: X^Dٛ6r掹'@,7yo?+9W҂6K} 9Jb ikPv!Wl2K|$_R8 4RfvueRВ`(ڦc'vҽ[)!3Oōc$6({_fʼ(M[kUOY˳m5Ѳr=npx w:;m䈚b>X$g;ҶP I3pGD lgoX hC^l%F`}UQmKQm)o-Krqw a:3[%P~DFQw4=˩عtH pHĊ:fE^1j`/ q)"{Pss^K)E m;Q= ~~r'c0zL_\9,:U=F:ﱍh2g֓4fk*{'~>X+'2Gu'[?aO!(67kd!Sف܏gI'tasYQ踈C[cVSz)G`x 'љքD);J -Q[*cX쳏2[ЊgEHd`Bf \Ppv}MDJʧ LYcϯ<`Cē* n^wL?;pqЎ!s~ *# :2o&b%>Y Nm0 H% DRq^hԄ6wVҭ_"5gpwCHmS \ t}%E)͝ZȮǐ}* N&]77_wF@w7z}9/EK`(򹧒ީcsthfm61*dTvvF^[_Z mZjn!&؋"Dx'[RԽ {'uLkqP.l3?yij_a@XIId4ݟ_QۗUbgS;ѥ71KGG2VK{)l솄lZ4?r/o]pX: JAŐI طr?bS&ur/e%Fa%'֤۰lOỳr9VX^W9vU٩eG@c$#s9M꾘z.i' K:̯ Q{t1?}5WH+1j7 W}W/f'-CU)ZIu>ҔW-QL-]1NUɒ35ee]fT/9};m}dE8jot&kЗ6'"e~uH16G7[aNrp }cχ/^_=U(CKLU>-^JdAQn}'eV;{tz? P~ӈڵEvcN$>HJDVe-CtZ]>I%W8,fsJtqpuڦp8=HYh%y/-YWsYFdŭns)>?x1֕SjYı0wũ`|pe픈̈Vs#%Y1mx`;i[% 5">;͘^EZ?&|YTfT>> y +fG1ͯzUB=MTľK˲ :aZmiB RI9]Y԰n5 eԲIV-:{Cbn: ~ْmKVuZ-fR'~8 Z֪9ORGC\q\t|;NZȜ~jRFY!  -?[/@UnIc&Ŭωl(|e[q8|CzX!k7MtcR:K_aثRԲ5_vG:t[:!{h4[ǁ )yȽ~}omC~T{A;8m&Z gvUQtŨEvy@uO+'ch(Rc>>rC]ɕ 2zO?RF%G͗m dS^+&*]M_g1X"ΌL Xvtgٻ? '[.Yb`dxD2с/΀M{QA01+5b# K7lonznV;0)JJa\& E nW&,̓TAMyeB ~wn*hE-ϱfI+Z M?NIJe(Vs6k00<5@fWX',= *s"1k4C%/sՇWϵYkXʣZl,%/iq,)H ީy, ,.~H9g [Ͳл"2t&l7T- t(I'|g@<I DUNeݤ4$|J$כ-c2_LrUEI=$̉=mzcg?mMڎR´"6ؽ4p4+ȷ"6*O,,pͱ;Qʊ* 9&3'Ju]Ȕ](ޡt7rsHuΜBjF_X́d'4Z n uox+ۤ Bf'|rO~õ`h5I2>y,d# *bV1X9LL^e?W5J0$mߌ rD=o S]ϔqQ=2^^;^2(=zEHY<-{b'ٻRm1q<g쏓og"5bȶ yV9Qӗ{0s,)sI Jn>lF!rʈDd`,YHcBۆnf-5!)<{,,n XdҮ{[a_%aS5|bXsw_v;\ ׅ;5[CYurW7ւy?!A{^  ԧ\o9)@iP8T, DLLO}!&B]ѓUsѱ^7NYUf=x+qfyI\'Lv TV0~>pm2Y__WbSGɱq'at]n97ǭfy!?c<2B0A@RK FH(>"ϰĺl'ف)YG `ryq.mL7%j aW,WӛW=% ZuAq?:5?gy:O6p 9eb:/X›0b}ȞΛqZD6b ^; p+VqvoGdscfZ3'Ciz6$THl6?L?Vx/EHM )%

ejabberd/mod_muc log"), fw(F, "
"), fw(F, " \"Powered", [Images_dir]), fw(F, " \"Powered", [Images_dir]), fw(F, ""), fw(F, " \"Valid", [Images_dir]), fw(F, " \"Valid", [Images_dir]), fw(F, "
"). add_message_to_log(Nick1, Message, RoomJID, Opts, State) -> #logstate{out_dir = OutDir, dir_type = DirType, dir_name = DirName, file_format = FileFormat, css_file = CSSFile, lang = Lang, timezone = Timezone, spam_prevention = NoFollow, top_link = TopLink} = State, Room = get_room_info(RoomJID, Opts), Nick = htmlize(Nick1, FileFormat), Nick2 = htmlize("<"++Nick1++">", FileFormat), Now = now(), TimeStamp = case Timezone of local -> calendar:now_to_local_time(Now); universal -> calendar:now_to_universal_time(Now) end, {Fd, Fn, _Dir} = build_filename_string(TimeStamp, OutDir, Room#room.jid, DirType, DirName, FileFormat), {Date, Time} = TimeStamp, %% Open file, create if it does not exist, create parent dirs if needed case file:read_file_info(Fn) of {ok, _} -> {ok, F} = file:open(Fn, [append]); {error, enoent} -> make_dir_rec(Fd), {ok, F} = file:open(Fn, [append]), Datestring = get_dateweek(Date, Lang), TimeStampYesterday = get_timestamp_daydiff(TimeStamp, -1), {_FdYesterday, FnYesterday, DatePrev} = build_filename_string( TimeStampYesterday, OutDir, Room#room.jid, DirType, DirName, FileFormat), TimeStampTomorrow = get_timestamp_daydiff(TimeStamp, 1), {_FdTomorrow, _FnTomorrow, DateNext} = build_filename_string( TimeStampTomorrow, OutDir, Room#room.jid, DirType, DirName, FileFormat), HourOffset = calc_hour_offset(TimeStamp), put_header(F, Room, Datestring, CSSFile, Lang, HourOffset, DatePrev, DateNext, TopLink, FileFormat), Images_dir = filename:join([OutDir, "images"]), file:make_dir(Images_dir), create_image_files(Images_dir), Images_url = case DirType of subdirs -> "../../../images"; plain -> "../images" end, close_previous_log(FnYesterday, Images_url, FileFormat) end, %% Build message Text = case Message of roomconfig_change -> RoomConfig = roomconfig_to_string(Room#room.config, Lang, FileFormat), put_room_config(F, RoomConfig, Lang, FileFormat), io_lib:format("~s
", [?T("Chatroom configuration modified")]); {roomconfig_change, Occupants} -> RoomConfig = roomconfig_to_string(Room#room.config, Lang, FileFormat), put_room_config(F, RoomConfig, Lang, FileFormat), RoomOccupants = roomoccupants_to_string(Occupants, FileFormat), put_room_occupants(F, RoomOccupants, Lang, FileFormat), io_lib:format("~s
", [?T("Chatroom configuration modified")]); join -> io_lib:format("~s ~s
", [Nick, ?T("joins the room")]); leave -> io_lib:format("~s ~s
", [Nick, ?T("leaves the room")]); {leave, Reason} -> io_lib:format("~s ~s: ~s
", [Nick, ?T("leaves the room"), htmlize(Reason,NoFollow,FileFormat)]); {kickban, "301", ""} -> io_lib:format("~s ~s
", [Nick, ?T("has been banned")]); {kickban, "301", Reason} -> io_lib:format("~s ~s: ~s
", [Nick, ?T("has been banned"), htmlize(Reason,FileFormat)]); {kickban, "307", ""} -> io_lib:format("~s ~s
", [Nick, ?T("has been kicked")]); {kickban, "307", Reason} -> io_lib:format("~s ~s: ~s
", [Nick, ?T("has been kicked"), htmlize(Reason,FileFormat)]); {kickban, "321", ""} -> io_lib:format("~s ~s
", [Nick, ?T("has been kicked because of an affiliation change")]); {kickban, "322", ""} -> io_lib:format("~s ~s
", [Nick, ?T("has been kicked because the room has been changed to members-only")]); {kickban, "332", ""} -> io_lib:format("~s ~s
", [Nick, ?T("has been kicked because of a system shutdown")]); {nickchange, OldNick} -> io_lib:format("~s ~s ~s
", [htmlize(OldNick,FileFormat), ?T("is now known as"), Nick]); {subject, T} -> io_lib:format("~s~s~s
", [Nick, ?T(" has set the subject to: "), htmlize(T,NoFollow,FileFormat)]); {body, T} -> case {ejabberd_regexp:run(T, "^/me\s"), Nick} of {_, ""} -> io_lib:format("~s
", [htmlize(T,NoFollow,FileFormat)]); {match, _} -> io_lib:format("~s ~s
", [Nick, string:substr(htmlize(T,FileFormat), 5)]); {nomatch, _} -> io_lib:format("~s ~s
", [Nick2, htmlize(T,NoFollow,FileFormat)]) end; {room_existence, RoomNewExistence} -> io_lib:format("~s
", [get_room_existence_string(RoomNewExistence, Lang)]) end, {Hour, Minute, Second} = Time, STime = lists:flatten( io_lib:format("~2..0w:~2..0w:~2..0w", [Hour, Minute, Second])), {_, _, Microsecs} = Now, STimeUnique = io_lib:format("~s.~w", [STime, Microsecs]), %% Write message fw(F, io_lib:format("[~s] ", [STimeUnique, STimeUnique, STimeUnique, STime]) ++ Text, FileFormat), %% Close file file:close(F), ok. %%---------------------------------------------------------------------- %% Utilities get_room_existence_string(created, Lang) -> ?T("Chatroom is created"); get_room_existence_string(destroyed, Lang) -> ?T("Chatroom is destroyed"); get_room_existence_string(started, Lang) -> ?T("Chatroom is started"); get_room_existence_string(stopped, Lang) -> ?T("Chatroom is stopped"). get_dateweek(Date, Lang) -> Weekday = case calendar:day_of_the_week(Date) of 1 -> ?T("Monday"); 2 -> ?T("Tuesday"); 3 -> ?T("Wednesday"); 4 -> ?T("Thursday"); 5 -> ?T("Friday"); 6 -> ?T("Saturday"); 7 -> ?T("Sunday") end, {Y, M, D} = Date, Month = case M of 1 -> ?T("January"); 2 -> ?T("February"); 3 -> ?T("March"); 4 -> ?T("April"); 5 -> ?T("May"); 6 -> ?T("June"); 7 -> ?T("July"); 8 -> ?T("August"); 9 -> ?T("September"); 10 -> ?T("October"); 11 -> ?T("November"); 12 -> ?T("December") end, case Lang of "en" -> io_lib:format("~s, ~s ~w, ~w", [Weekday, Month, D, Y]); "es" -> io_lib:format("~s ~w de ~s de ~w", [Weekday, D, Month, Y]); _ -> io_lib:format("~s, ~w ~s ~w", [Weekday, D, Month, Y]) end. make_dir_rec(Dir) -> case file:read_file_info(Dir) of {ok, _} -> ok; {error, enoent} -> DirS = filename:split(Dir), DirR = lists:sublist(DirS, length(DirS)-1), make_dir_rec(filename:join(DirR)), file:make_dir(Dir) end. %% {ok, F1}=file:open("valid-xhtml10.png", [read]). %% {ok, F1b}=file:read(F1, 1000000). %% c("../../ejabberd/src/jlib.erl"). %% jlib:encode_base64(F1b). image_base64("powered-by-erlang.png") -> "iVBORw0KGgoAAAANSUhEUgAAAGUAAAAfCAYAAAD+xQNoAAADN0lEQVRo3u1a" "P0waURz+rjGRRQ+nUyRCYmJyDPTapDARaSIbTUjt1gVSh8ZW69aBAR0cWLSx" "CXWp59LR1jbdqKnGxoQuRZZrSYyHEVM6iZMbHewROA7u3fHvkr5vOn737vcu" "33ffu9/vcQz+gef5Cij6CkmSGABgFEH29r5SVvqIsTEOHo8HkiQxDBXEOjg9" "PcHc3BxuUSqsI8jR0REAUFGsCCoKFYWCBAN6AxyO0Z7cyMXFb6oGqSgAsIrJ" "ut9hMQlvdNbUhKWshLd3HtTF4jihShgVpRaBxKKmIGX5HL920/hz/BM2+zAm" "pn2YioQaxnECj0BiEYcrG0Tzzc8/rfudSm02jaVSm9Vr1MdG8rSKKXlJ7lHr" "fjouCut2IrC82BDPbe/gc+xlXez7KxEz63H4lmIN473Rh8Si1BKhRY6aEJI8" "pLmbjSPN0xOnBBILmg5RC6Lg28preKOzsNmHG8R1Bf0o7GdMucUslDy1pJLG" "2sndVVG0lq3c9vum4zmBR1kuwiYMN5ybmCYXxQg57ThFOTYznzpPO+IQi+IK" "+jXjg/YhuIJ+cIIHg+wQJoJ+2N3jYN3Olvk4ge/IU98spne+FfGtlslm16nn" "a8fduntfDscoVjGJqUgIjz686ViFUdjP4N39x9Xq638viZVtlq2tLXKncLf5" "ticuZSWU5XOUshJKxxKtfdtdvs4OyNb/68urKvlluYizgwwu5SLK8jllu1t9" "ihYOlzdwdpBBKSvh+vKKzHkCj1JW3y1m+hSj13WjqOiJKK0qpXKhSFxJAYBv" "KYaZ9TjWRu4SiWi2LyDtb6wghGmn5HfTml16ILGA/G5al2DW7URYTFYrOU7g" "icQ020sYqYDM9CbdgqFd4vzHL03JfvLjk6ZgADAVCSEsJvHsdL+utNYrm2uf" "ZDVZSkzPKaQkW8kthpyS297BvRdRzR6DdTurJbPy9Ov1K6xr3HBPQuIMowR3" "asegUyDuU9SuUG+dmIGyZ0b7FBN9St3WunyC5yMsrVv7uXzRP58s/qKn6C4q" "lQoVxVIvd4YBwzBUFKs6ZaD27U9hEdcAN98Sx2IxykafIYrizbfESoB+dd9/" "KF/d/wX3cJvREzl1vAAAAABJRU5ErkJggg=="; image_base64("valid-xhtml10.png") -> "iVBORw0KGgoAAAANSUhEUgAAAFgAAAAfCAMAAAEjEcpEAAACiFBMVEUAAADe" "5+fOezmtra3ejEKlhELvvWO9WlrehELOe3vepaWclHvetVLGc3PerVKcCAj3" "vVqUjHOUe1JjlL0xOUpjjL2UAAC91ueMrc7vrVKlvdbW3u+EpcbO3ufO1ucY" "WpSMKQi9SiF7e3taWkoQEAiMczkQSoxaUkpzc3O1lEoICACEazEhGAgIAACE" "YzFra2utjELWcznGnEr/7+9jY2POazHOYzGta2NShLVrlL05OUqctdacCADG" "a2ucAADGpVqUtc61ORg5OTmlUikYGAiUezl7YzEYEAiUczkxMTG9nEqtIRDe" "3t4AMXu9lEoQCACMazEAKXspKSmljFrW1ta1jELOzs7n7/fGxsa9pVqEOSkp" "Y5xznL29tZxahLXOpVr/99ZrY1L/79ZjUiljSikAOYTvxmMAMYScezmchFqU" "czGtlFp7c2utjFqUlJStxt73///39/9Ce61CSkq9xsZznMbW5+9Cc62MjIxC" "Qkrv9/fv7/fOzsbnlErWjIz/3mtCORhza1IpIRBzWjH/1mtCMRhzY1L/zmvn" "vVpSQiHOpVJrUinntVr3zmOEc1L3xmNaWlq1nFo5QkrGWim1lFoISpRSUlK1" "zt4hWpwASoz///////8xa6WUaykAQoxKe61KSkp7nMbWtWPe5+9jWlL39/f3" "9/fWrWNCQkLera3nvWPv7+85MRjntWPetVp7c1IxKRCUlHtKORh7a1IxIRCU" "jHtaSiHWrVIpIQhzWinvvVpaQiH/1mPWpVKMe1L/zmP/xmNrUiGErc4YGBj/" "73PG1ucQWpT/53O9nFoQUpS1SiEQEBC9zt69vb05c6UISoxSUko5a6UICAhS" "SkohUpS1tbXetWMAQoSUgD+kAAAA2HRSTlP/////////iP9sSf//dP//////" "//////////////////////////////////////////8M////////////ef//" "////////////////////////////////////////////////////////////" "//////////////////////9d////////////////////////////////////" "AP//////////////CP//RP//////////////////////////////////////" "//////////////////////9xPp1gAAAFvUlEQVR42pVWi18URRwfy7vsYUba" "iqBRBFmICUQGVKcZckQeaRJQUCLeycMSfKGH0uo5NELpIvGQGzokvTTA85VH" "KTpbRoeJnPno/p1+M7t3txj20e/Nzu7Ofve7v/k9Zg4Vc+wRQMW0eyLx1ZSA" "NeBDxVmxZZSwEUYkGAewm1eIBOMRvhv1UA+q8KXIVuxGdCelFYwxAnxOrxgb" "Y8Ti1t4VA0QHYz4x3FnVC8OVLXv9fkKGSWDoW/4lG6VbdtBblesOs+MjmEmz" "JKNIJWFEfEQTCWNPFKvcKEymjLO1b8bwYQd1hCiiDCl5KsrDCIlhj4fSuvcp" "fSpgJmyv6dzeZv+nMPx3dhbt94II07/JZliEtm1N2RIYPkTYshwYm245a/zk" "WjJwcyFh6ZIcYxxmqiaDSYxhOhFUsqngi3Fzcj3ljdYDNE9uzA1YD/5MhnzW" "1KRqF7mYG8jFYXLcfLpjOe2LA0fuGqQrQHl10sdK0sFcFSOSlzF0BgXQH9h3" "QZDBI0ccNEhftjXuippBDD2/eMRiETmwwNEYHyqhdDyo22w+3QHuNbdve5a7" "eOkHmDVJ0ixNmfbz1h0qo/Q6GuSB2wQJQbpOjOQAl7woWSRJ0m2ewhvAOUiY" "YtZtaZL0CZZmtmVOQttLfr/dbveLZodrfrL7W75wG/JjqkQxoNTtNsTKELQp" "QL6/D5loaSmyTT8TUhsmi8iFA0hZiyltf7OiNKdarRm5w2So2lTNdPLuIzR+" "AiLj8VTRJaj0LmX4VhJ27f/VJV/yycilWPOrk8NkXi7Qqmj5bHqVZlJKZIRk" "1wFzKrt0WUbnXMPJ1fk4TJ5oWBA61p1V76DeIs0MX+s3GxRlA1vtw83KhgNp" "hc1nyErLO5zcvbOsrq+scbZnpzc6QVFPenLwGxmC+BOfYI+DN55QYddh4Q/N" "E/yGYYj4TOGNngQavAZnzzTovEA+kcMJ+247uYexNA+4Fsvjmuv662jsWxPZ" "x2xg890bYMYnTgya7bjmCiEY0qgJ0vMF3c+NoFdPyzxz6V3Uxs3AOWCDchRv" "OsQtBrbFsrT2fhHEc7ByGzu/dA4IO0A3HdfeP9yMqAwP6NPEb6cbwn0PWVU1" "7/FDBQh/CPIrbfcg027IZrsAT/Bf3FNWyn9RSR4cvvwn3e4HFmYPDl/thYcR" "Vi8qPEoXVUWBl6FTBFTtnqmKKg5wnlF4wZ1yeLv7TiwXKektE+iDBNicWEyL" "pnFhfDkpJc3q2khSPyQBbE0dMJnOoDzTwGsI7cdyMkL5gWqUjCF6Txst/twx" "Cv1WzzHoy21ZDQ1xnuDzdPDWR4knr14v0tYn3IxaMFFdiMOlEOJHw1jOQ4sW" "t5rQopRkXZhMEi7pmeDCVWBlfUKwhMZ7rsF6elKsvbwiKxgxIdewa3ErsaYo" "mCVZFYJb0GUu3JqGUNoplBxYiYby8vLBFWef+Cri4/I1sbQ/1OtYTrNtdXS+" "rSe7kQ52eSObL99/iErCWUjCy5W4JLygmCouGfG9x9fmx17XhBuDCaOerbt5" "38erta7TFktLvdHghZcCbcPQO33zIJG9kxF5hoVXnzTzRz0r5js8oTj6uyPk" "GRf346HOLcasgFexueNUWFPtuFKzjoSFYYedhwVlhsRVYWWJpltv1XPQT1Rl" "0bjZIBlb1XujVDzY/Kj4k6Ku3+Z0jo1owjVzDpFTXe1juvBSWNFmNWGZy8Lv" "zUl5PN4JCwyNDzbQ0aAj4Zrjz0FatGJJYhvq4j7mGSpvytGFlZtHf2C4o/28" "Zu8z7wo7eYPfXysnF0i9NnPh1t1zR7VBb9GqaOXhtTmHQdgMFXE+Z608cnpO" "DdZdjL+TuDY44Q38kJXHhccWLoOd9uv1AwwvO+48uu+faCSJPJ1bmy6Thyvp" "ivBmYWgjxPDPAp7JTemY/yGKFEiRt/jG/2P79s8KCwoLCgoLC/khUBA5F0Sf" "QZ+RYfpNE/4Xosmq7jsZAJsAAAAASUVORK5CYII="; image_base64("vcss.png") -> "iVBORw0KGgoAAAANSUhEUgAAAFgAAAAfCAMAAABUFvrSAAABKVBMVEUAAAAj" "Ix8MR51ZVUqAdlmdnZ3ejEWLDAuNjY1kiMG0n2d9fX19Ghfrp1FtbW3y39+3" "Ph6lIRNdXV2qJBFcVUhcVUhPT0/dsmpUfLr57+/u7u4/PDWZAACZAADOp1Gd" "GxG+SyTgvnNdSySzk16+mkuxw+BOS0BOS0DOzs7MzMy4T09RRDwsJBG+vr73" "wV6fkG6eCQRFcLSurq6/X1+ht9nXfz5sepHuwV59ZTHetFjQ2+wMCQQ2ZK5t" "WCsmWajsz8+Sq9NMPh4hVaY8MRj///////////////////////9MTEyOp9Lu" "8vhXU1A8PDyjOSTBz+YLRJ2rLy8sLCwXTaKujEUcHByDn82dfz7/zGafDw+f" "Dw+zRSlzlMcMDAyNcji1tbXf5vIcFgvATJOjAAAAY3RSTlP/8///////////" "//////8A//////P/////ov//8//////////////z///T//////////+i////" "//////////8w/////6IA/xAgMP//////////8/////////8w0/////////+z" "ehebAAACkUlEQVR42u2VfVPTQBDG19VqC6LY+lKrRIxFQaFSBPuSvhBPF8SI" "UZK2J5Yav/+HcO8uZdLqTCsU/nKnyWwvk1/unnt2D9ZmH+8/cMAaTRFy+ng6" "9/yiwC/+gy8R3McGv5zHvGJEGAdR4eBgi1IbZwevIEZE24pFtBtzG1Q4AoD5" "zvw5pEDcJvIQV/TE3/l+H9GnNJwcdABS5wAbFQLMqI98/UReoAaOTlaJsp0z" "aHx7LwZvY0BUR2xpWTzqam0gzY8KGzG4MhBCNGucha4QbpETy+Yk/BP85nt7" "34AjpQLTsE4ZFpf/dnkUCglXVNYB+OfUZJHvAqAoa45OeuPgm4+Xjtv7xm4N" "7PMV4C61+Mrz3H2WImm3ATiWrAiwZRWcUA5Ej4dgIEMxDv6yxHHcNuAutnjv" "2HZ1NeuycoVPh0mwC834zZC9Ao5dkZZKwLVGwT+WdLw0YOZ1saEkUDoT+QGW" "KZ0E2xpcrPakVW2KXwyUtYEtlEAj3GXD/fYwrryAdeiyGqidQSw1eqtJcA8c" "Zq4zXqhPuCBYE1fKJjh/5X6MwRm9c2xf7WVdLf5oSdt64esVIwVAKC1HJ2ol" "i8vj3L0YzC4zjkMagt+arDAs6bApbL1RVlWIqrJbreqKZmh4y6VR7rAJeUYD" "VRj9VqRXkErpJ9lbEwtE83KlIfeG4p52t7zWIMO1XcaGz54uUyet+hBM7BXX" "DS8Xc5+8Gmmbu1xwSoGIokA3oTptQecQ4Iimm/Ew7jwbPfMi3TM91T9XVIGo" "+W9xC8oWpugVCXLuwXijjxJ3r/6PjX7nlFua8QmyM+TO/Gja2TTc2Z95C5ua" "ewGH6cJi6bJO6Z+TY276eH3tbgy+/3ly3Js+rj66osG/AV5htgaQ9SeRAAAA" "AElFTkSuQmCC"; image_base64("powered-by-ejabberd.png") -> "iVBORw0KGgoAAAANSUhEUgAAAGUAAAAfCAMAAADJG/NaAAAAw1BMVEUAAAAj" "BgYtBAM5AwFCAAAYGAJNAABcAABIDQ5qAAAoJRV7AACFAAAoKSdJHByLAAAw" "Lwk1NQA1MzFJKyo4NxtDQQBEQT5KSCxSTgBSUBlgQ0JYSEpZWQJPUU5hYABb" "W0ZiYClcW1poaCVwbQRpaDhzYWNsakhuZ2VrbFZ8dwCEgAB3dnd4d2+OjACD" "hYKcmACJi4iQkpWspgCYmJm5swCmqazEwACwsbS4ub3X0QLExsPLyszW1Nnc" "3ODm5ugMBwAWAwPHm1IFAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJ" "cEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfVCRQOBA7VBkCMAAACcElEQVRI" "x72WjXKiMBSFQalIFbNiy1pdrJZaRVYR5deGwPs/VRNBSBB2OjvQO0oYjPfj" "5J6bCcdx8i2UldxKcDhk1HbIPwFBF/kHKJfjPSVAyIRHF9rRZ4sUX3EDdWOv" "1+u2tESaavpnYTbv9zvd0WwDy3/QcGQXlH5uTxB1l07MJlRpsUei0JF6Qi+O" "HyGK7ijXxPklHe/umIllim3iUBMJDIEULxxPP0TVWhhKJoN9fUpdmQLteV8a" "DgEAg9gIcTjL4F4L+r4WVKEF+rbJdwYYAoQHY+oQjnGootyKwxapoi73WkyF" "FySQBv988naEEp4+YMMec5VUCQDJTscEy7Kc0HsLmqNE7rovDjMpIHHGYeid" "Xn4TQcaxMYqP3RV3C8oCl2WvrlSPaNpGZadRnmPGCk8ylM2okAJ4i9TEe1Ke" "rsXxSl6jUt5uayiIodirtcKLOaWblj50wiyMv1F9lm9TUDArGAD0FmEpvCUs" "VoZy6dW81Fg0aDaHogQa36ekAPG5DDGsbdZrGsrzZUnzvBo1I2tLmuL69kSi" "tAweyHKN9b3leDfQMnu3nIIKWfmXnqGVKedJT6QpICbJvf2f8aOsvn68v+k7" "/cwUQdPoxaMoRTnKFHNlKsKQphCTOa84u64vpi8bH31CqsbF6lSONRTkTyQG" "Arq49/fEvjBwz4eDS2/JpaXRNOoXRD/VmOrDVTJJRIZCTLav3VrqbPvP3vdd" "uGEhQJzilncbpSA4F3vsihErO+dayv/sY5/yRE0GDEXCu2VoNiMlo5i+P2Kl" "gMEvTNk2eYa5XEyh12Ex17Z8vzQUR3KEPbYd6XG87eC4Ly75RneS5ZYHAAAA" "AElFTkSuQmCC". create_image_files(Images_dir) -> Filenames = ["powered-by-ejabberd.png", "powered-by-erlang.png", "valid-xhtml10.png", "vcss.png" ], lists:foreach( fun(Filename) -> Filename_full = filename:join([Images_dir, Filename]), {ok, F} = file:open(Filename_full, [write]), Image = jlib:decode_base64(image_base64(Filename)), io:format(F, "~s", [Image]), file:close(F) end, Filenames), ok. fw(F, S) -> fw(F, S, [], html). fw(F, S, O) when is_list(O) -> fw(F, S, O, html); fw(F, S, FileFormat) when is_atom(FileFormat) -> fw(F, S, [], FileFormat). fw(F, S, O, FileFormat) -> S1 = io_lib:format(S ++ "~n", O), S2 = case FileFormat of html -> S1; plaintext -> ejabberd_regexp:greplace(S1, "<[^>]*>", "") end, io:format(F, S2, []). put_header(_, _, _, _, _, _, _, _, _, plaintext) -> ok; put_header(F, Room, Date, CSSFile, Lang, Hour_offset, Date_prev, Date_next, Top_link, FileFormat) -> fw(F, ""), fw(F, "", [Lang, Lang]), fw(F, ""), fw(F, ""), fw(F, "~s - ~s", [htmlize(Room#room.title), Date]), put_header_css(F, CSSFile), put_header_script(F), fw(F, ""), fw(F, ""), {Top_url, Top_text} = Top_link, fw(F, "", [Top_url, Top_text]), fw(F, "
~s
", [htmlize(Room#room.title)]), fw(F, "~s", [Room#room.jid, Room#room.jid]), fw(F, "
~s< ^ >
", [Date, Date_prev, Date_next]), case {htmlize(Room#room.subject_author), htmlize(Room#room.subject)} of {"", ""} -> ok; {SuA, Su} -> fw(F, "
~s~s~s
", [SuA, ?T(" has set the subject to: "), Su]) end, RoomConfig = roomconfig_to_string(Room#room.config, Lang, FileFormat), put_room_config(F, RoomConfig, Lang, FileFormat), Occupants = get_room_occupants(Room#room.jid), RoomOccupants = roomoccupants_to_string(Occupants, FileFormat), put_room_occupants(F, RoomOccupants, Lang, FileFormat), Time_offset_str = case Hour_offset<0 of true -> io_lib:format("~p", [Hour_offset]); false -> io_lib:format("+~p", [Hour_offset]) end, fw(F, "
GMT~s
", [Time_offset_str]). put_header_css(F, false) -> fw(F, ""); put_header_css(F, CSSFile) -> fw(F, "", [CSSFile]). put_header_script(F) -> fw(F, ""). put_room_config(_F, _RoomConfig, _Lang, plaintext) -> ok; put_room_config(F, RoomConfig, Lang, _FileFormat) -> {_, Now2, _} = now(), fw(F, "
"), fw(F, "
~s
", [Now2, ?T("Room Configuration")]), fw(F, "

~s
", [Now2, RoomConfig]), fw(F, "
"). put_room_occupants(_F, _RoomOccupants, _Lang, plaintext) -> ok; put_room_occupants(F, RoomOccupants, Lang, _FileFormat) -> {_, Now2, _} = now(), fw(F, "
"), fw(F, "
~s
", [Now2, ?T("Room Occupants")]), fw(F, "

~s
", [Now2, RoomOccupants]), fw(F, "
"). %% htmlize %% The default behaviour is to ignore the nofollow spam prevention on links %% (NoFollow=false) htmlize(S1) -> htmlize(S1, html). htmlize(S1, plaintext) -> S1; htmlize(S1, FileFormat) -> htmlize(S1, false, FileFormat). %% The NoFollow parameter tell if the spam prevention should be applied to the link found %% true means 'apply nofollow on links'. htmlize(S1, _NoFollow, plaintext) -> S1; htmlize(S1, NoFollow, _FileFormat) -> S2_list = string:tokens(S1, "\n"), lists:foldl( fun(Si, Res) -> Si2 = htmlize2(Si, NoFollow), case Res of "" -> Si2; _ -> Res ++ "
" ++ Si2 end end, "", S2_list). htmlize2(S1, NoFollow) -> S2 = ejabberd_regexp:greplace(S1, "\\&", "\\&"), S3 = ejabberd_regexp:greplace(S2, "<", "\\<"), S4 = ejabberd_regexp:greplace(S3, ">", "\\>"), S5 = ejabberd_regexp:greplace(S4, "((http|https|ftp)://|(mailto|xmpp):)[^] )\'\"}]+", link_regexp(NoFollow)), %% Remove 'right-to-left override' unicode character 0x202e S6 = ejabberd_regexp:greplace(S5, " ", "\\ \\ "), S7 = ejabberd_regexp:greplace(S6, "\\t", "\\ \\ \\ \\ "), ejabberd_regexp:greplace(S7, [226,128,174], "[RLO]"). %% Regexp link %% Add the nofollow rel attribute when required link_regexp(false) -> "&"; link_regexp(true) -> "&". get_room_info(RoomJID, Opts) -> Title = case lists:keysearch(title, 1, Opts) of {value, {_, T}} -> T; false -> "" end, Subject = case lists:keysearch(subject, 1, Opts) of {value, {_, S}} -> S; false -> "" end, SubjectAuthor = case lists:keysearch(subject_author, 1, Opts) of {value, {_, SA}} -> SA; false -> "" end, #room{jid = jlib:jid_to_string(RoomJID), title = Title, subject = Subject, subject_author = SubjectAuthor, config = Opts }. roomconfig_to_string(Options, Lang, FileFormat) -> %% Get title, if available Title = case lists:keysearch(title, 1, Options) of {value, Tuple} -> [Tuple]; false -> [] end, %% Remove title from list Os1 = lists:keydelete(title, 1, Options), %% Order list Os2 = lists:sort(Os1), %% Add title to ordered list Options2 = Title ++ Os2, lists:foldl( fun({Opt, Val}, R) -> case get_roomconfig_text(Opt) of undefined -> R; OptT -> OptText = ?T(OptT), R2 = case Val of false -> "
" ++ OptText ++ "
"; true -> "
" ++ OptText ++ "
"; "" -> "
" ++ OptText ++ "
"; T -> case Opt of password -> "
" ++ OptText ++ "
"; max_users -> "
" ++ OptText ++ ": \"" ++ htmlize(integer_to_list(T), FileFormat) ++ "\"
"; title -> "
" ++ OptText ++ ": \"" ++ htmlize(T, FileFormat) ++ "\"
"; description -> "
" ++ OptText ++ ": \"" ++ htmlize(T, FileFormat) ++ "\"
"; allow_private_messages_from_visitors -> "
" ++ OptText ++ ": \"" ++ htmlize(?T(atom_to_list(T)), FileFormat) ++ "\"
"; _ -> "\"" ++ T ++ "\"" end end, R ++ R2 end end, "", Options2). get_roomconfig_text(title) -> "Room title"; get_roomconfig_text(persistent) -> "Make room persistent"; get_roomconfig_text(public) -> "Make room public searchable"; get_roomconfig_text(public_list) -> "Make participants list public"; get_roomconfig_text(password_protected) -> "Make room password protected"; get_roomconfig_text(password) -> "Password"; get_roomconfig_text(anonymous) -> "This room is not anonymous"; get_roomconfig_text(members_only) -> "Make room members-only"; get_roomconfig_text(moderated) -> "Make room moderated"; get_roomconfig_text(members_by_default) -> "Default users as participants"; get_roomconfig_text(allow_change_subj) -> "Allow users to change the subject"; get_roomconfig_text(allow_private_messages) -> "Allow users to send private messages"; get_roomconfig_text(allow_private_messages_from_visitors) -> "Allow visitors to send private messages to"; get_roomconfig_text(allow_query_users) -> "Allow users to query other users"; get_roomconfig_text(allow_user_invites) -> "Allow users to send invites"; get_roomconfig_text(logging) -> "Enable logging"; get_roomconfig_text(allow_visitor_nickchange) -> "Allow visitors to change nickname"; get_roomconfig_text(allow_visitor_status) -> "Allow visitors to send status text in presence updates"; get_roomconfig_text(captcha_protected) -> "Make room captcha protected"; get_roomconfig_text(description) -> "Room description"; %% get_roomconfig_text(subject) -> "Subject"; %% get_roomconfig_text(subject_author) -> "Subject author"; get_roomconfig_text(max_users) -> "Maximum Number of Occupants"; get_roomconfig_text(_) -> undefined. %% Users = [{JID, Nick, Role}] roomoccupants_to_string(Users, _FileFormat) -> Res = [role_users_to_string(RoleS, Users1) || {RoleS, Users1} <- group_by_role(Users), Users1 /= []], lists:flatten(["
", Res, "
"]). %% Users = [{JID, Nick, Role}] group_by_role(Users) -> {Ms, Ps, Vs, Ns} = lists:foldl( fun({JID, Nick, moderator}, {Mod, Par, Vis, Non}) -> {[{JID, Nick}]++Mod, Par, Vis, Non}; ({JID, Nick, participant}, {Mod, Par, Vis, Non}) -> {Mod, [{JID, Nick}]++Par, Vis, Non}; ({JID, Nick, visitor}, {Mod, Par, Vis, Non}) -> {Mod, Par, [{JID, Nick}]++Vis, Non}; ({JID, Nick, none}, {Mod, Par, Vis, Non}) -> {Mod, Par, Vis, [{JID, Nick}]++Non} end, {[], [], [], []}, Users), case Ms of [] -> []; _ -> [{"Moderator", Ms}] end ++ case Ms of [] -> []; _ -> [{"Participant", Ps}] end ++ case Ms of [] -> []; _ -> [{"Visitor", Vs}] end ++ case Ms of [] -> []; _ -> [{"None", Ns}] end. %% Role = atom() %% Users = [{JID, Nick}] role_users_to_string(RoleS, Users) -> SortedUsers = lists:keysort(2, Users), UsersString = [[Nick, "
"] || {_JID, Nick} <- SortedUsers], [RoleS, ": ", UsersString]. get_room_occupants(RoomJIDString) -> RoomJID = jlib:string_to_jid(RoomJIDString), RoomName = RoomJID#jid.luser, MucService = RoomJID#jid.lserver, StateData = get_room_state(RoomName, MucService), [{U#user.jid, U#user.nick, U#user.role} || {_, U} <- ?DICT:to_list(StateData#state.users)]. get_room_state(RoomName, MucService) -> case mnesia:dirty_read(muc_online_room, {RoomName, MucService}) of [R] -> RoomPid = R#muc_online_room.pid, get_room_state(RoomPid); [] -> #state{} end. get_room_state(RoomPid) -> {ok, R} = gen_fsm:sync_send_all_state_event(RoomPid, get_state), R. get_proc_name(Host) -> gen_mod:get_module_proc(Host, ?PROCNAME). calc_hour_offset(TimeHere) -> TimeZero = calendar:now_to_universal_time(now()), TimeHereHour = calendar:datetime_to_gregorian_seconds(TimeHere) div 3600, TimeZeroHour = calendar:datetime_to_gregorian_seconds(TimeZero) div 3600, TimeHereHour - TimeZeroHour. ejabberd-2.1.11/src/mod_muc/mod_muc.erl0000664000000000000000000007212612240230175014567 0ustar %%%---------------------------------------------------------------------- %%% File : mod_muc.erl %%% Author : Alexey Shchepin %%% Purpose : MUC support (XEP-0045) %%% Created : 19 Mar 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_muc). -author('alexey@process-one.net'). -behaviour(gen_server). -behaviour(gen_mod). %% API -export([start_link/2, start/2, stop/1, room_destroyed/4, store_room/4, restore_room/3, forget_room/3, create_room/5, process_iq_disco_items/4, broadcast_service_message/2, can_use_nick/4]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -record(muc_room, {name_host, opts}). -record(muc_online_room, {name_host, pid}). -record(muc_registered, {us_host, nick}). -record(state, {host, server_host, access, history_size, default_room_opts, room_shaper}). -define(PROCNAME, ejabberd_mod_muc). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host, Opts) -> start_supervisor(Host), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, temporary, 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> stop_supervisor(Host), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:call(Proc, stop), supervisor:delete_child(ejabberd_sup, Proc). %% This function is called by a room in three situations: %% A) The owner of the room destroyed it %% B) The only participant of a temporary room leaves it %% C) mod_muc:stop was called, and each room is being terminated %% In this case, the mod_muc process died before the room processes %% So the message sending must be catched room_destroyed(Host, Room, Pid, ServerHost) -> catch gen_mod:get_module_proc(ServerHost, ?PROCNAME) ! {room_destroyed, {Room, Host}, Pid}, ok. %% @doc Create a room. %% If Opts = default, the default room options are used. %% Else use the passed options as defined in mod_muc_room. create_room(Host, Name, From, Nick, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:call(Proc, {create, Name, From, Nick, Opts}). store_room(_ServerHost, Host, Name, Opts) -> F = fun() -> mnesia:write(#muc_room{name_host = {Name, Host}, opts = Opts}) end, mnesia:transaction(F). restore_room(_ServerHost, Host, Name) -> case catch mnesia:dirty_read(muc_room, {Name, Host}) of [#muc_room{opts = Opts}] -> Opts; _ -> error end. forget_room(_ServerHost, Host, Name) -> F = fun() -> mnesia:delete({muc_room, {Name, Host}}) end, mnesia:transaction(F). process_iq_disco_items(Host, From, To, #iq{lang = Lang} = IQ) -> Rsm = jlib:rsm_decode(IQ), Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}], iq_disco_items(Host, From, Lang, Rsm)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)). can_use_nick(_ServerHost, _Host, _JID, "") -> false; can_use_nick(_ServerHost, Host, JID, Nick) -> {LUser, LServer, _} = jlib:jid_tolower(JID), LUS = {LUser, LServer}, case catch mnesia:dirty_select( muc_registered, [{#muc_registered{us_host = '$1', nick = Nick, _ = '_'}, [{'==', {element, 2, '$1'}, Host}], ['$_']}]) of {'EXIT', _Reason} -> true; [] -> true; [#muc_registered{us_host = {U, _Host}}] -> U == LUS end. %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([Host, Opts]) -> mnesia:create_table(muc_room, [{disc_copies, [node()]}, {attributes, record_info(fields, muc_room)}]), mnesia:create_table(muc_registered, [{disc_copies, [node()]}, {attributes, record_info(fields, muc_registered)}]), mnesia:create_table(muc_online_room, [{ram_copies, [node()]}, {attributes, record_info(fields, muc_online_room)}]), mnesia:add_table_copy(muc_online_room, node(), ram_copies), catch ets:new(muc_online_users, [bag, named_table, public, {keypos, 2}]), MyHost = gen_mod:get_opt_host(Host, Opts, "conference.@HOST@"), update_tables(MyHost), clean_table_from_bad_node(node(), MyHost), mnesia:add_table_index(muc_registered, nick), mnesia:subscribe(system), Access = gen_mod:get_opt(access, Opts, all), AccessCreate = gen_mod:get_opt(access_create, Opts, all), AccessAdmin = gen_mod:get_opt(access_admin, Opts, none), AccessPersistent = gen_mod:get_opt(access_persistent, Opts, all), HistorySize = gen_mod:get_opt(history_size, Opts, 20), DefRoomOpts = gen_mod:get_opt(default_room_options, Opts, []), RoomShaper = gen_mod:get_opt(room_shaper, Opts, none), ejabberd_router:register_route(MyHost), load_permanent_rooms(MyHost, Host, {Access, AccessCreate, AccessAdmin, AccessPersistent}, HistorySize, RoomShaper), {ok, #state{host = MyHost, server_host = Host, access = {Access, AccessCreate, AccessAdmin, AccessPersistent}, default_room_opts = DefRoomOpts, history_size = HistorySize, room_shaper = RoomShaper}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call(stop, _From, State) -> {stop, normal, ok, State}; handle_call({create, Room, From, Nick, Opts}, _From, #state{host = Host, server_host = ServerHost, access = Access, default_room_opts = DefOpts, history_size = HistorySize, room_shaper = RoomShaper} = State) -> ?DEBUG("MUC: create new room '~s'~n", [Room]), NewOpts = case Opts of default -> DefOpts; _ -> Opts end, {ok, Pid} = mod_muc_room:start( Host, ServerHost, Access, Room, HistorySize, RoomShaper, From, Nick, NewOpts, ?MODULE), register_room(Host, Room, Pid), {reply, ok, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({route, From, To, Packet}, #state{host = Host, server_host = ServerHost, access = Access, default_room_opts = DefRoomOpts, history_size = HistorySize, room_shaper = RoomShaper} = State) -> case catch do_route(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); _ -> ok end, {noreply, State}; handle_info({room_destroyed, RoomHost, Pid}, State) -> F = fun() -> mnesia:delete_object(#muc_online_room{name_host = RoomHost, pid = Pid}) end, mnesia:transaction(F), {noreply, State}; handle_info({mnesia_system_event, {mnesia_down, Node}}, State) -> clean_table_from_bad_node(Node), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, State) -> ejabberd_router:unregister_route(State#state.host), ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- start_supervisor(Host) -> Proc = gen_mod:get_module_proc(Host, ejabberd_mod_muc_sup), ChildSpec = {Proc, {ejabberd_tmp_sup, start_link, [Proc, mod_muc_room]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop_supervisor(Host) -> Proc = gen_mod:get_module_proc(Host, ejabberd_mod_muc_sup), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). do_route(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts) -> {AccessRoute, _AccessCreate, _AccessAdmin, _AccessPersistent} = Access, case acl:match_rule(ServerHost, AccessRoute, From) of allow -> do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts); _ -> {xmlelement, _Name, Attrs, _Els} = Packet, Lang = xml:get_attr_s("xml:lang", Attrs), ErrText = "Access denied by service policy", Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, ErrText)), ejabberd_router:route_error(To, From, Err, Packet) end. do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts) -> {_AccessRoute, AccessCreate, AccessAdmin, _AccessPersistent} = Access, {Room, _, Nick} = jlib:jid_tolower(To), {xmlelement, Name, Attrs, _Els} = Packet, case Room of "" -> case Nick of "" -> case Name of "iq" -> case jlib:iq_query_info(Packet) of #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS, sub_el = _SubEl, lang = Lang} = IQ -> Info = ejabberd_hooks:run_fold( disco_info, ServerHost, [], [ServerHost, ?MODULE, "", ""]), Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], iq_disco_info(Lang) ++Info}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{type = get, xmlns = ?NS_DISCO_ITEMS} = IQ -> spawn(?MODULE, process_iq_disco_items, [Host, From, To, IQ]); #iq{type = get, xmlns = ?NS_REGISTER = XMLNS, lang = Lang, sub_el = _SubEl} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], iq_get_register_info( Host, From, Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{type = set, xmlns = ?NS_REGISTER = XMLNS, lang = Lang, sub_el = SubEl} = IQ -> case process_iq_register_set(Host, From, SubEl, Lang) of {result, IQRes} -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], IQRes}]}, ejabberd_router:route( To, From, jlib:iq_to_xml(Res)); {error, Error} -> Err = jlib:make_error_reply( Packet, Error), ejabberd_router:route( To, From, Err) end; #iq{type = get, xmlns = ?NS_VCARD = XMLNS, lang = Lang, sub_el = _SubEl} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", XMLNS}], iq_get_vcard(Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{type = get, xmlns = ?NS_MUC_UNIQUE } = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "unique", [{"xmlns", ?NS_MUC_UNIQUE}], [iq_get_unique(From)]}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{} -> Err = jlib:make_error_reply( Packet, ?ERR_FEATURE_NOT_IMPLEMENTED), ejabberd_router:route(To, From, Err); _ -> ok end; "message" -> case xml:get_attr_s("type", Attrs) of "error" -> ok; _ -> case acl:match_rule(ServerHost, AccessAdmin, From) of allow -> Msg = xml:get_path_s( Packet, [{elem, "body"}, cdata]), broadcast_service_message(Host, Msg); _ -> Lang = xml:get_attr_s("xml:lang", Attrs), ErrText = "Only service administrators " "are allowed to send service messages", Err = jlib:make_error_reply( Packet, ?ERRT_FORBIDDEN(Lang, ErrText)), ejabberd_router:route( To, From, Err) end end; "presence" -> ok end; _ -> case xml:get_attr_s("type", Attrs) of "error" -> ok; "result" -> ok; _ -> Err = jlib:make_error_reply( Packet, ?ERR_ITEM_NOT_FOUND), ejabberd_router:route(To, From, Err) end end; _ -> case mnesia:dirty_read(muc_online_room, {Room, Host}) of [] -> Type = xml:get_attr_s("type", Attrs), case {Name, Type} of {"presence", ""} -> case check_user_can_create_room(ServerHost, AccessCreate, From, Room) of true -> {ok, Pid} = start_new_room( Host, ServerHost, Access, Room, HistorySize, RoomShaper, From, Nick, DefRoomOpts), register_room(Host, Room, Pid), mod_muc_room:route(Pid, From, Nick, Packet), ok; false -> Lang = xml:get_attr_s("xml:lang", Attrs), ErrText = "Room creation is denied by service policy", Err = jlib:make_error_reply( Packet, ?ERRT_FORBIDDEN(Lang, ErrText)), ejabberd_router:route(To, From, Err) end; _ -> Lang = xml:get_attr_s("xml:lang", Attrs), ErrText = "Conference room does not exist", Err = jlib:make_error_reply( Packet, ?ERRT_ITEM_NOT_FOUND(Lang, ErrText)), ejabberd_router:route(To, From, Err) end; [R] -> Pid = R#muc_online_room.pid, ?DEBUG("MUC: send to process ~p~n", [Pid]), mod_muc_room:route(Pid, From, Nick, Packet), ok end end. check_user_can_create_room(ServerHost, AccessCreate, From, RoomID) -> case acl:match_rule(ServerHost, AccessCreate, From) of allow -> (length(RoomID) =< gen_mod:get_module_opt(ServerHost, ?MODULE, max_room_id, infinite)); _ -> false end. load_permanent_rooms(Host, ServerHost, Access, HistorySize, RoomShaper) -> case catch mnesia:dirty_select( muc_room, [{#muc_room{name_host = {'_', Host}, _ = '_'}, [], ['$_']}]) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]), ok; Rs -> lists:foreach( fun(R) -> {Room, Host} = R#muc_room.name_host, case mnesia:dirty_read(muc_online_room, {Room, Host}) of [] -> {ok, Pid} = mod_muc_room:start( Host, ServerHost, Access, Room, HistorySize, RoomShaper, R#muc_room.opts, ?MODULE), register_room(Host, Room, Pid); _ -> ok end end, Rs) end. start_new_room(Host, ServerHost, Access, Room, HistorySize, RoomShaper, From, Nick, DefRoomOpts) -> case mnesia:dirty_read(muc_room, {Room, Host}) of [] -> ?DEBUG("MUC: open new room '~s'~n", [Room]), mod_muc_room:start(Host, ServerHost, Access, Room, HistorySize, RoomShaper, From, Nick, DefRoomOpts, ?MODULE); [#muc_room{opts = Opts}|_] -> ?DEBUG("MUC: restore room '~s'~n", [Room]), mod_muc_room:start(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts, ?MODULE) end. register_room(Host, Room, Pid) -> F = fun() -> mnesia:write(#muc_online_room{name_host = {Room, Host}, pid = Pid}) end, mnesia:transaction(F). iq_disco_info(Lang) -> [{xmlelement, "identity", [{"category", "conference"}, {"type", "text"}, {"name", translate:translate(Lang, "Chatrooms")}], []}, {xmlelement, "feature", [{"var", ?NS_DISCO_INFO}], []}, {xmlelement, "feature", [{"var", ?NS_DISCO_ITEMS}], []}, {xmlelement, "feature", [{"var", ?NS_MUC}], []}, {xmlelement, "feature", [{"var", ?NS_MUC_UNIQUE}], []}, {xmlelement, "feature", [{"var", ?NS_REGISTER}], []}, {xmlelement, "feature", [{"var", ?NS_RSM}], []}, {xmlelement, "feature", [{"var", ?NS_VCARD}], []}]. iq_disco_items(Host, From, Lang, none) -> lists:zf(fun(#muc_online_room{name_host = {Name, _Host}, pid = Pid}) -> case catch gen_fsm:sync_send_all_state_event( Pid, {get_disco_item, From, Lang}, 100) of {item, Desc} -> flush(), {true, {xmlelement, "item", [{"jid", jlib:jid_to_string({Name, Host, ""})}, {"name", Desc}], []}}; _ -> false end end, get_vh_rooms(Host)); iq_disco_items(Host, From, Lang, Rsm) -> {Rooms, RsmO} = get_vh_rooms(Host, Rsm), RsmOut = jlib:rsm_encode(RsmO), lists:zf(fun(#muc_online_room{name_host = {Name, _Host}, pid = Pid}) -> case catch gen_fsm:sync_send_all_state_event( Pid, {get_disco_item, From, Lang}, 100) of {item, Desc} -> flush(), {true, {xmlelement, "item", [{"jid", jlib:jid_to_string({Name, Host, ""})}, {"name", Desc}], []}}; _ -> false end end, Rooms) ++ RsmOut. get_vh_rooms(Host, #rsm_in{max=M, direction=Direction, id=I, index=Index})-> AllRooms = lists:sort(get_vh_rooms(Host)), Count = erlang:length(AllRooms), Guard = case Direction of _ when Index =/= undefined -> [{'==', {element, 2, '$1'}, Host}]; aft -> [{'==', {element, 2, '$1'}, Host}, {'>=',{element, 1, '$1'} ,I}]; before when I =/= []-> [{'==', {element, 2, '$1'}, Host}, {'=<',{element, 1, '$1'} ,I}]; _ -> [{'==', {element, 2, '$1'}, Host}] end, L = lists:sort( mnesia:dirty_select(muc_online_room, [{#muc_online_room{name_host = '$1', _ = '_'}, Guard, ['$_']}])), L2 = if Index == undefined andalso Direction == before -> lists:reverse(lists:sublist(lists:reverse(L), 1, M)); Index == undefined -> lists:sublist(L, 1, M); Index > Count orelse Index < 0 -> []; true -> lists:sublist(L, Index+1, M) end, if L2 == [] -> {L2, #rsm_out{count=Count}}; true -> H = hd(L2), NewIndex = get_room_pos(H, AllRooms), T=lists:last(L2), {F, _}=H#muc_online_room.name_host, {Last, _}=T#muc_online_room.name_host, {L2, #rsm_out{first=F, last=Last, count=Count, index=NewIndex}} end. %% @doc Return the position of desired room in the list of rooms. %% The room must exist in the list. The count starts in 0. %% @spec (Desired::muc_online_room(), Rooms::[muc_online_room()]) -> integer() get_room_pos(Desired, Rooms) -> get_room_pos(Desired, Rooms, 0). get_room_pos(Desired, [HeadRoom | _], HeadPosition) when (Desired#muc_online_room.name_host == HeadRoom#muc_online_room.name_host) -> HeadPosition; get_room_pos(Desired, [_ | Rooms], HeadPosition) -> get_room_pos(Desired, Rooms, HeadPosition + 1). flush() -> receive _ -> flush() after 0 -> ok end. -define(XFIELD(Type, Label, Var, Val), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). %% @doc Get a pseudo unique Room Name. The Room Name is generated as a hash of %% the requester JID, the local time and a random salt. %% %% "pseudo" because we don't verify that there is not a room %% with the returned Name already created, nor mark the generated Name %% as "already used". But in practice, it is unique enough. See %% http://xmpp.org/extensions/xep-0045.html#createroom-unique iq_get_unique(From) -> {xmlcdata, sha:sha(term_to_binary([From, now(), randoms:get_string()]))}. iq_get_register_info(Host, From, Lang) -> {LUser, LServer, _} = jlib:jid_tolower(From), LUS = {LUser, LServer}, {Nick, Registered} = case catch mnesia:dirty_read(muc_registered, {LUS, Host}) of {'EXIT', _Reason} -> {"", []}; [] -> {"", []}; [#muc_registered{nick = N}] -> {N, [{xmlelement, "registered", [], []}]} end, Registered ++ [{xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "You need a client that supports x:data to register the nickname")}]}, {xmlelement, "x", [{"xmlns", ?NS_XDATA}], [{xmlelement, "title", [], [{xmlcdata, translate:translate( Lang, "Nickname Registration at ") ++ Host}]}, {xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "Enter nickname you want to register")}]}, ?XFIELD("text-single", "Nickname", "nick", Nick)]}]. iq_set_register_info(Host, From, Nick, Lang) -> {LUser, LServer, _} = jlib:jid_tolower(From), LUS = {LUser, LServer}, F = fun() -> case Nick of "" -> mnesia:delete({muc_registered, {LUS, Host}}), ok; _ -> Allow = case mnesia:select( muc_registered, [{#muc_registered{us_host = '$1', nick = Nick, _ = '_'}, [{'==', {element, 2, '$1'}, Host}], ['$_']}]) of [] -> true; [#muc_registered{us_host = {U, _Host}}] -> U == LUS end, if Allow -> mnesia:write( #muc_registered{us_host = {LUS, Host}, nick = Nick}), ok; true -> false end end end, case mnesia:transaction(F) of {atomic, ok} -> {result, []}; {atomic, false} -> ErrText = "That nickname is registered by another person", {error, ?ERRT_CONFLICT(Lang, ErrText)}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. process_iq_register_set(Host, From, SubEl, Lang) -> {xmlelement, _Name, _Attrs, Els} = SubEl, case xml:get_subtag(SubEl, "remove") of false -> case xml:remove_cdata(Els) of [{xmlelement, "x", _Attrs1, _Els1} = XEl] -> case {xml:get_tag_attr_s("xmlns", XEl), xml:get_tag_attr_s("type", XEl)} of {?NS_XDATA, "cancel"} -> {result, []}; {?NS_XDATA, "submit"} -> XData = jlib:parse_xdata_submit(XEl), case XData of invalid -> {error, ?ERR_BAD_REQUEST}; _ -> case lists:keysearch("nick", 1, XData) of {value, {_, [Nick]}} when Nick /= "" -> iq_set_register_info(Host, From, Nick, Lang); _ -> ErrText = "You must fill in field \"Nickname\" in the form", {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)} end end; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> iq_set_register_info(Host, From, "", Lang) end. iq_get_vcard(Lang) -> [{xmlelement, "FN", [], [{xmlcdata, "ejabberd/mod_muc"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate(Lang, "ejabberd MUC module") ++ "\nCopyright (c) 2003-2012 ProcessOne"}]}]. broadcast_service_message(Host, Msg) -> lists:foreach( fun(#muc_online_room{pid = Pid}) -> gen_fsm:send_all_state_event( Pid, {service_message, Msg}) end, get_vh_rooms(Host)). get_vh_rooms(Host) -> mnesia:dirty_select(muc_online_room, [{#muc_online_room{name_host = '$1', _ = '_'}, [{'==', {element, 2, '$1'}, Host}], ['$_']}]). clean_table_from_bad_node(Node) -> F = fun() -> Es = mnesia:select( muc_online_room, [{#muc_online_room{pid = '$1', _ = '_'}, [{'==', {node, '$1'}, Node}], ['$_']}]), lists:foreach(fun(E) -> mnesia:delete_object(E) end, Es) end, mnesia:async_dirty(F). clean_table_from_bad_node(Node, Host) -> F = fun() -> Es = mnesia:select( muc_online_room, [{#muc_online_room{pid = '$1', name_host = {'_', Host}, _ = '_'}, [{'==', {node, '$1'}, Node}], ['$_']}]), lists:foreach(fun(E) -> mnesia:delete_object(E) end, Es) end, mnesia:async_dirty(F). update_tables(Host) -> update_muc_room_table(Host), update_muc_registered_table(Host). update_muc_room_table(Host) -> Fields = record_info(fields, muc_room), case mnesia:table_info(muc_room, attributes) of Fields -> ok; [name, opts] -> ?INFO_MSG("Converting muc_room table from " "{name, opts} format", []), {atomic, ok} = mnesia:create_table( mod_muc_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, muc_room}, {attributes, record_info(fields, muc_room)}]), mnesia:transform_table(muc_room, ignore, Fields), F1 = fun() -> mnesia:write_lock_table(mod_muc_tmp_table), mnesia:foldl( fun(#muc_room{name_host = Name} = R, _) -> mnesia:dirty_write( mod_muc_tmp_table, R#muc_room{name_host = {Name, Host}}) end, ok, muc_room) end, mnesia:transaction(F1), mnesia:clear_table(muc_room), F2 = fun() -> mnesia:write_lock_table(muc_room), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, mod_muc_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(mod_muc_tmp_table); _ -> ?INFO_MSG("Recreating muc_room table", []), mnesia:transform_table(muc_room, ignore, Fields) end. update_muc_registered_table(Host) -> Fields = record_info(fields, muc_registered), case mnesia:table_info(muc_registered, attributes) of Fields -> ok; [user, nick] -> ?INFO_MSG("Converting muc_registered table from " "{user, nick} format", []), {atomic, ok} = mnesia:create_table( mod_muc_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, muc_registered}, {attributes, record_info(fields, muc_registered)}]), mnesia:del_table_index(muc_registered, nick), mnesia:transform_table(muc_registered, ignore, Fields), F1 = fun() -> mnesia:write_lock_table(mod_muc_tmp_table), mnesia:foldl( fun(#muc_registered{us_host = US} = R, _) -> mnesia:dirty_write( mod_muc_tmp_table, R#muc_registered{us_host = {US, Host}}) end, ok, muc_registered) end, mnesia:transaction(F1), mnesia:clear_table(muc_registered), F2 = fun() -> mnesia:write_lock_table(muc_registered), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, mod_muc_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(mod_muc_tmp_table); _ -> ?INFO_MSG("Recreating muc_registered table", []), mnesia:transform_table(muc_registered, ignore, Fields) end. ejabberd-2.1.11/src/mod_muc/mod_muc_room.hrl0000664000000000000000000000462212240230175015622 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -define(MAX_USERS_DEFAULT, 200). -define(SETS, gb_sets). -define(DICT, dict). -record(lqueue, {queue, len, max}). -record(config, {title = "", description = "", allow_change_subj = true, allow_query_users = true, allow_private_messages = true, allow_private_messages_from_visitors = anyone, allow_visitor_status = true, allow_visitor_nickchange = true, public = true, public_list = true, persistent = false, moderated = true, captcha_protected = false, members_by_default = true, members_only = false, allow_user_invites = false, password_protected = false, password = "", anonymous = true, allow_voice_requests = true, voice_request_min_interval = 1800, max_users = ?MAX_USERS_DEFAULT, logging = false, captcha_whitelist = ?SETS:empty() }). -record(user, {jid, nick, role, last_presence}). -record(activity, {message_time = 0, presence_time = 0, message_shaper, presence_shaper, message, presence}). -record(state, {room, host, server_host, mod, access, jid, config = #config{}, users = ?DICT:new(), last_voice_request_time = treap:empty(), robots = ?DICT:new(), nicks = ?DICT:new(), affiliations = ?DICT:new(), history, subject = "", subject_author = "", just_created = false, activity = treap:empty(), room_shaper, room_queue = queue:new()}). -record(muc_online_users, {us, resource, room, host}). ejabberd-2.1.11/src/mod_muc/Makefile.in0000664000000000000000000000121112240230175014470 0ustar # $Id$ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ EFLAGS += -I .. EFLAGS += -pz .. # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif ifeq (@transient_supervisors@, false) EFLAGS+=-DNO_TRANSIENT_SUPERVISORS endif OUTDIR = .. SOURCES = $(wildcard *.erl) BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) all: $(BEAMS) $(OUTDIR)/%.beam: %.erl @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< clean: rm -f $(BEAMS) distclean: clean rm -f Makefile TAGS: etags *.erl ejabberd-2.1.11/src/mod_muc/mod_muc_odbc.erl0000664000000000000000000007200612240230175015553 0ustar %%%---------------------------------------------------------------------- %%% File : mod_muc_odbc.erl %%% Author : Alexey Shchepin %%% Purpose : MUC support (XEP-0045) %%% Created : 19 Mar 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_muc_odbc). -author('alexey@process-one.net'). -behaviour(gen_server). -behaviour(gen_mod). %% API -export([start_link/2, start/2, stop/1, room_destroyed/4, store_room/4, restore_room/3, forget_room/3, create_room/5, process_iq_disco_items/4, broadcast_service_message/2, can_use_nick/4]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -record(muc_online_room, {name_host, pid}). -record(state, {host, server_host, access, history_size, default_room_opts, room_shaper}). -define(PROCNAME, ejabberd_mod_muc). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host, Opts) -> start_supervisor(Host), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, temporary, 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> stop_supervisor(Host), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:call(Proc, stop), supervisor:delete_child(ejabberd_sup, Proc). %% This function is called by a room in three situations: %% A) The owner of the room destroyed it %% B) The only participant of a temporary room leaves it %% C) mod_muc_odbc:stop was called, and each room is being terminated %% In this case, the mod_muc_odbc process died before the room processes %% So the message sending must be catched room_destroyed(Host, Room, Pid, ServerHost) -> catch gen_mod:get_module_proc(ServerHost, ?PROCNAME) ! {room_destroyed, {Room, Host}, Pid}, ok. %% @doc Create a room. %% If Opts = default, the default room options are used. %% Else use the passed options as defined in mod_muc_room. create_room(Host, Name, From, Nick, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:call(Proc, {create, Name, From, Nick, Opts}). store_room(ServerHost, Host, Name, Opts) -> SName = ejabberd_odbc:escape(Name), SHost = ejabberd_odbc:escape(Host), LServer = jlib:nameprep(ServerHost), SOpts = ejabberd_odbc:encode_term(Opts), F = fun() -> odbc_queries:update_t( "muc_room", ["name", "host", "opts"], [SName, SHost, SOpts], ["name='", SName, "' and host='", SHost, "'"]) end, ejabberd_odbc:sql_transaction(LServer, F). restore_room(ServerHost, Host, Name) -> SName = ejabberd_odbc:escape(Name), SHost = ejabberd_odbc:escape(Host), LServer = jlib:nameprep(ServerHost), case catch ejabberd_odbc:sql_query( LServer, ["select opts from muc_room where name='", SName, "' and host='", SHost, "';"]) of {selected, ["opts"], [{Opts}]} -> ejabberd_odbc:decode_term(Opts); _ -> error end. forget_room(ServerHost, Host, Name) -> SName = ejabberd_odbc:escape(Name), SHost = ejabberd_odbc:escape(Host), LServer = jlib:nameprep(ServerHost), F = fun() -> ejabberd_odbc:sql_query_t( ["delete from muc_room where name='", SName, "' and host='", SHost, "';"]) end, ejabberd_odbc:sql_transaction(LServer, F). process_iq_disco_items(Host, From, To, #iq{lang = Lang} = IQ) -> Rsm = jlib:rsm_decode(IQ), Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}], iq_disco_items(Host, From, Lang, Rsm)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)). can_use_nick(_ServerHost, _Host, _JID, "") -> false; can_use_nick(ServerHost, Host, JID, Nick) -> SJID = jlib:jid_to_string( jlib:jid_tolower( jlib:jid_remove_resource(JID))), SNick = ejabberd_odbc:escape(Nick), SHost = ejabberd_odbc:escape(Host), LServer = jlib:nameprep(ServerHost), case catch ejabberd_odbc:sql_query( LServer, ["select jid from muc_registered ", "where nick='", SNick, "' and host='", SHost, "';"]) of {selected, ["jid"], [{SJID1}]} -> SJID == SJID1; _ -> true end. %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([Host, Opts]) -> mnesia:create_table(muc_online_room, [{ram_copies, [node()]}, {attributes, record_info(fields, muc_online_room)}]), mnesia:add_table_copy(muc_online_room, node(), ram_copies), catch ets:new(muc_online_users, [bag, named_table, public, {keypos, 2}]), MyHost = gen_mod:get_opt_host(Host, Opts, "conference.@HOST@"), clean_table_from_bad_node(node(), MyHost), mnesia:subscribe(system), Access = gen_mod:get_opt(access, Opts, all), AccessCreate = gen_mod:get_opt(access_create, Opts, all), AccessAdmin = gen_mod:get_opt(access_admin, Opts, none), AccessPersistent = gen_mod:get_opt(access_persistent, Opts, all), HistorySize = gen_mod:get_opt(history_size, Opts, 20), DefRoomOpts = gen_mod:get_opt(default_room_options, Opts, []), RoomShaper = gen_mod:get_opt(room_shaper, Opts, none), ejabberd_router:register_route(MyHost), load_permanent_rooms(MyHost, Host, {Access, AccessCreate, AccessAdmin, AccessPersistent}, HistorySize, RoomShaper), {ok, #state{host = MyHost, server_host = Host, access = {Access, AccessCreate, AccessAdmin, AccessPersistent}, default_room_opts = DefRoomOpts, history_size = HistorySize, room_shaper = RoomShaper}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call(stop, _From, State) -> {stop, normal, ok, State}; handle_call({create, Room, From, Nick, Opts}, _From, #state{host = Host, server_host = ServerHost, access = Access, default_room_opts = DefOpts, history_size = HistorySize, room_shaper = RoomShaper} = State) -> ?DEBUG("MUC: create new room '~s'~n", [Room]), NewOpts = case Opts of default -> DefOpts; _ -> Opts end, {ok, Pid} = mod_muc_room:start( Host, ServerHost, Access, Room, HistorySize, RoomShaper, From, Nick, NewOpts, ?MODULE), register_room(Host, Room, Pid), {reply, ok, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({route, From, To, Packet}, #state{host = Host, server_host = ServerHost, access = Access, default_room_opts = DefRoomOpts, history_size = HistorySize, room_shaper = RoomShaper} = State) -> case catch do_route(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); _ -> ok end, {noreply, State}; handle_info({room_destroyed, RoomHost, Pid}, State) -> F = fun() -> mnesia:delete_object(#muc_online_room{name_host = RoomHost, pid = Pid}) end, mnesia:transaction(F), {noreply, State}; handle_info({mnesia_system_event, {mnesia_down, Node}}, State) -> clean_table_from_bad_node(Node), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, State) -> ejabberd_router:unregister_route(State#state.host), ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- start_supervisor(Host) -> Proc = gen_mod:get_module_proc(Host, ejabberd_mod_muc_sup), ChildSpec = {Proc, {ejabberd_tmp_sup, start_link, [Proc, mod_muc_room]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop_supervisor(Host) -> Proc = gen_mod:get_module_proc(Host, ejabberd_mod_muc_sup), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). do_route(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts) -> {AccessRoute, _AccessCreate, _AccessAdmin, _AccessPersistent} = Access, case acl:match_rule(ServerHost, AccessRoute, From) of allow -> do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts); _ -> {xmlelement, _Name, Attrs, _Els} = Packet, Lang = xml:get_attr_s("xml:lang", Attrs), ErrText = "Access denied by service policy", Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, ErrText)), ejabberd_router:route_error(To, From, Err, Packet) end. do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, From, To, Packet, DefRoomOpts) -> {_AccessRoute, AccessCreate, AccessAdmin, _AccessPersistent} = Access, {Room, _, Nick} = jlib:jid_tolower(To), {xmlelement, Name, Attrs, _Els} = Packet, case Room of "" -> case Nick of "" -> case Name of "iq" -> case jlib:iq_query_info(Packet) of #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS, sub_el = _SubEl, lang = Lang} = IQ -> Info = ejabberd_hooks:run_fold( disco_info, ServerHost, [], [ServerHost, ?MODULE, "", ""]), Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], iq_disco_info(Lang) ++Info}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{type = get, xmlns = ?NS_DISCO_ITEMS} = IQ -> spawn(?MODULE, process_iq_disco_items, [Host, From, To, IQ]); #iq{type = get, xmlns = ?NS_REGISTER = XMLNS, lang = Lang, sub_el = _SubEl} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], iq_get_register_info( ServerHost, Host, From, Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{type = set, xmlns = ?NS_REGISTER = XMLNS, lang = Lang, sub_el = SubEl} = IQ -> case process_iq_register_set( ServerHost, Host, From, SubEl, Lang) of {result, IQRes} -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}], IQRes}]}, ejabberd_router:route( To, From, jlib:iq_to_xml(Res)); {error, Error} -> Err = jlib:make_error_reply( Packet, Error), ejabberd_router:route( To, From, Err) end; #iq{type = get, xmlns = ?NS_VCARD = XMLNS, lang = Lang, sub_el = _SubEl} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", XMLNS}], iq_get_vcard(Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{type = get, xmlns = ?NS_MUC_UNIQUE } = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "unique", [{"xmlns", ?NS_MUC_UNIQUE}], [iq_get_unique(From)]}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{} -> Err = jlib:make_error_reply( Packet, ?ERR_FEATURE_NOT_IMPLEMENTED), ejabberd_router:route(To, From, Err); _ -> ok end; "message" -> case xml:get_attr_s("type", Attrs) of "error" -> ok; _ -> case acl:match_rule(ServerHost, AccessAdmin, From) of allow -> Msg = xml:get_path_s( Packet, [{elem, "body"}, cdata]), broadcast_service_message(Host, Msg); _ -> Lang = xml:get_attr_s("xml:lang", Attrs), ErrText = "Only service administrators " "are allowed to send service messages", Err = jlib:make_error_reply( Packet, ?ERRT_FORBIDDEN(Lang, ErrText)), ejabberd_router:route( To, From, Err) end end; "presence" -> ok end; _ -> case xml:get_attr_s("type", Attrs) of "error" -> ok; "result" -> ok; _ -> Err = jlib:make_error_reply( Packet, ?ERR_ITEM_NOT_FOUND), ejabberd_router:route(To, From, Err) end end; _ -> case mnesia:dirty_read(muc_online_room, {Room, Host}) of [] -> Type = xml:get_attr_s("type", Attrs), case {Name, Type} of {"presence", ""} -> case check_user_can_create_room(ServerHost, AccessCreate, From, Room) of true -> {ok, Pid} = start_new_room( Host, ServerHost, Access, Room, HistorySize, RoomShaper, From, Nick, DefRoomOpts), register_room(Host, Room, Pid), mod_muc_room:route(Pid, From, Nick, Packet), ok; false -> Lang = xml:get_attr_s("xml:lang", Attrs), ErrText = "Room creation is denied by service policy", Err = jlib:make_error_reply( Packet, ?ERRT_FORBIDDEN(Lang, ErrText)), ejabberd_router:route(To, From, Err) end; _ -> Lang = xml:get_attr_s("xml:lang", Attrs), ErrText = "Conference room does not exist", Err = jlib:make_error_reply( Packet, ?ERRT_ITEM_NOT_FOUND(Lang, ErrText)), ejabberd_router:route(To, From, Err) end; [R] -> Pid = R#muc_online_room.pid, ?DEBUG("MUC: send to process ~p~n", [Pid]), mod_muc_room:route(Pid, From, Nick, Packet), ok end end. check_user_can_create_room(ServerHost, AccessCreate, From, RoomID) -> case acl:match_rule(ServerHost, AccessCreate, From) of allow -> (length(RoomID) =< gen_mod:get_module_opt(ServerHost, ?MODULE, max_room_id, infinite)); _ -> false end. load_permanent_rooms(Host, ServerHost, Access, HistorySize, RoomShaper) -> SHost = ejabberd_odbc:escape(Host), LServer = jlib:nameprep(ServerHost), case catch ejabberd_odbc:sql_query( LServer, ["select name, opts from muc_room ", "where host='", SHost, "';"]) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]), ok; {selected, ["name", "opts"], RoomOpts} -> lists:foreach( fun({Room, Opts}) -> case mnesia:dirty_read(muc_online_room, {Room, Host}) of [] -> {ok, Pid} = mod_muc_room:start( Host, ServerHost, Access, Room, HistorySize, RoomShaper, ejabberd_odbc:decode_term(Opts), ?MODULE), register_room(Host, Room, Pid); _ -> ok end end, RoomOpts) end. start_new_room(Host, ServerHost, Access, Room, HistorySize, RoomShaper, From, Nick, DefRoomOpts) -> SHost = ejabberd_odbc:escape(Host), LServer = jlib:nameprep(ServerHost), SRoom = ejabberd_odbc:escape(Room), case ejabberd_odbc:sql_query( LServer, ["select opts from muc_room where name='", SRoom, "' and host='", SHost, "';"]) of {selected, ["opts"], []} -> ?DEBUG("MUC: open new room '~s'~n", [Room]), mod_muc_room:start(Host, ServerHost, Access, Room, HistorySize, RoomShaper, From, Nick, DefRoomOpts, ?MODULE); {selected, ["opts"], [{Opts}|_]} -> ?DEBUG("MUC: restore room '~s'~n", [Room]), mod_muc_room:start(Host, ServerHost, Access, Room, HistorySize, RoomShaper, ejabberd_odbc:decode_term(Opts), ?MODULE) end. register_room(Host, Room, Pid) -> F = fun() -> mnesia:write(#muc_online_room{name_host = {Room, Host}, pid = Pid}) end, mnesia:transaction(F). iq_disco_info(Lang) -> [{xmlelement, "identity", [{"category", "conference"}, {"type", "text"}, {"name", translate:translate(Lang, "Chatrooms")}], []}, {xmlelement, "feature", [{"var", ?NS_DISCO_INFO}], []}, {xmlelement, "feature", [{"var", ?NS_DISCO_ITEMS}], []}, {xmlelement, "feature", [{"var", ?NS_MUC}], []}, {xmlelement, "feature", [{"var", ?NS_MUC_UNIQUE}], []}, {xmlelement, "feature", [{"var", ?NS_REGISTER}], []}, {xmlelement, "feature", [{"var", ?NS_RSM}], []}, {xmlelement, "feature", [{"var", ?NS_VCARD}], []}]. iq_disco_items(Host, From, Lang, none) -> lists:zf(fun(#muc_online_room{name_host = {Name, _Host}, pid = Pid}) -> case catch gen_fsm:sync_send_all_state_event( Pid, {get_disco_item, From, Lang}, 100) of {item, Desc} -> flush(), {true, {xmlelement, "item", [{"jid", jlib:jid_to_string({Name, Host, ""})}, {"name", Desc}], []}}; _ -> false end end, get_vh_rooms(Host)); iq_disco_items(Host, From, Lang, Rsm) -> {Rooms, RsmO} = get_vh_rooms(Host, Rsm), RsmOut = jlib:rsm_encode(RsmO), lists:zf(fun(#muc_online_room{name_host = {Name, _Host}, pid = Pid}) -> case catch gen_fsm:sync_send_all_state_event( Pid, {get_disco_item, From, Lang}, 100) of {item, Desc} -> flush(), {true, {xmlelement, "item", [{"jid", jlib:jid_to_string({Name, Host, ""})}, {"name", Desc}], []}}; _ -> false end end, Rooms) ++ RsmOut. get_vh_rooms(Host, #rsm_in{max=M, direction=Direction, id=I, index=Index})-> AllRooms = lists:sort(get_vh_rooms(Host)), Count = erlang:length(AllRooms), Guard = case Direction of _ when Index =/= undefined -> [{'==', {element, 2, '$1'}, Host}]; aft -> [{'==', {element, 2, '$1'}, Host}, {'>=',{element, 1, '$1'} ,I}]; before when I =/= []-> [{'==', {element, 2, '$1'}, Host}, {'=<',{element, 1, '$1'} ,I}]; _ -> [{'==', {element, 2, '$1'}, Host}] end, L = lists:sort( mnesia:dirty_select(muc_online_room, [{#muc_online_room{name_host = '$1', _ = '_'}, Guard, ['$_']}])), L2 = if Index == undefined andalso Direction == before -> lists:reverse(lists:sublist(lists:reverse(L), 1, M)); Index == undefined -> lists:sublist(L, 1, M); Index > Count orelse Index < 0 -> []; true -> lists:sublist(L, Index+1, M) end, if L2 == [] -> {L2, #rsm_out{count=Count}}; true -> H = hd(L2), NewIndex = get_room_pos(H, AllRooms), T=lists:last(L2), {F, _}=H#muc_online_room.name_host, {Last, _}=T#muc_online_room.name_host, {L2, #rsm_out{first=F, last=Last, count=Count, index=NewIndex}} end. %% @doc Return the position of desired room in the list of rooms. %% The room must exist in the list. The count starts in 0. %% @spec (Desired::muc_online_room(), Rooms::[muc_online_room()]) -> integer() get_room_pos(Desired, Rooms) -> get_room_pos(Desired, Rooms, 0). get_room_pos(Desired, [HeadRoom | _], HeadPosition) when (Desired#muc_online_room.name_host == HeadRoom#muc_online_room.name_host) -> HeadPosition; get_room_pos(Desired, [_ | Rooms], HeadPosition) -> get_room_pos(Desired, Rooms, HeadPosition + 1). flush() -> receive _ -> flush() after 0 -> ok end. -define(XFIELD(Type, Label, Var, Val), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). %% @doc Get a pseudo unique Room Name. The Room Name is generated as a hash of %% the requester JID, the local time and a random salt. %% %% "pseudo" because we don't verify that there is not a room %% with the returned Name already created, nor mark the generated Name %% as "already used". But in practice, it is unique enough. See %% http://xmpp.org/extensions/xep-0045.html#createroom-unique iq_get_unique(From) -> {xmlcdata, sha:sha(term_to_binary([From, now(), randoms:get_string()]))}. iq_get_register_info(ServerHost, Host, From, Lang) -> SJID = ejabberd_odbc:escape( jlib:jid_to_string( jlib:jid_tolower( jlib:jid_remove_resource(From)))), SHost = ejabberd_odbc:escape(Host), LServer = jlib:nameprep(ServerHost), {Nick, Registered} = case catch ejabberd_odbc:sql_query( LServer, ["select nick from muc_registered where " "jid='", SJID, "' and host='", SHost, "';"]) of {selected, ["nick"], [{N}]} -> {N, [{xmlelement, "registered", [], []}]}; _ -> {"", []} end, Registered ++ [{xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "You need a client that supports x:data to register the nickname")}]}, {xmlelement, "x", [{"xmlns", ?NS_XDATA}], [{xmlelement, "title", [], [{xmlcdata, translate:translate( Lang, "Nickname Registration at ") ++ Host}]}, {xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "Enter nickname you want to register")}]}, ?XFIELD("text-single", "Nickname", "nick", Nick)]}]. iq_set_register_info(ServerHost, Host, From, Nick, Lang) -> JID = jlib:jid_to_string( jlib:jid_tolower( jlib:jid_remove_resource(From))), SJID = ejabberd_odbc:escape(JID), SNick = ejabberd_odbc:escape(Nick), SHost = ejabberd_odbc:escape(Host), LServer = jlib:nameprep(ServerHost), F = fun() -> case Nick of "" -> ejabberd_odbc:sql_query_t( ["delete from muc_registered where ", "jid='", SJID, "' and host='", Host, "';"]), ok; _ -> Allow = case ejabberd_odbc:sql_query_t( ["select jid from muc_registered ", "where nick='", SNick, "' and host='", SHost, "';"]) of {selected, ["jid"], [{J}]} -> J == JID; _ -> true end, if Allow -> odbc_queries:update_t( "muc_registered", ["jid", "host", "nick"], [SJID, SHost, SNick], ["jid='", SJID, "' and host='", SHost, "'"]), ok; true -> false end end end, case catch ejabberd_odbc:sql_transaction(LServer, F) of {atomic, ok} -> {result, []}; {atomic, false} -> ErrText = "That nickname is registered by another person", {error, ?ERRT_CONFLICT(Lang, ErrText)}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. process_iq_register_set(ServerHost, Host, From, SubEl, Lang) -> {xmlelement, _Name, _Attrs, Els} = SubEl, case xml:get_subtag(SubEl, "remove") of false -> case xml:remove_cdata(Els) of [{xmlelement, "x", _Attrs1, _Els1} = XEl] -> case {xml:get_tag_attr_s("xmlns", XEl), xml:get_tag_attr_s("type", XEl)} of {?NS_XDATA, "cancel"} -> {result, []}; {?NS_XDATA, "submit"} -> XData = jlib:parse_xdata_submit(XEl), case XData of invalid -> {error, ?ERR_BAD_REQUEST}; _ -> case lists:keysearch("nick", 1, XData) of {value, {_, [Nick]}} when Nick /= "" -> iq_set_register_info(ServerHost, Host, From, Nick, Lang); _ -> ErrText = "You must fill in field \"Nickname\" in the form", {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)} end end; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> iq_set_register_info(ServerHost, Host, From, "", Lang) end. iq_get_vcard(Lang) -> [{xmlelement, "FN", [], [{xmlcdata, "ejabberd/mod_muc"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate(Lang, "ejabberd MUC module") ++ "\nCopyright (c) 2003-2012 ProcessOne"}]}]. broadcast_service_message(Host, Msg) -> lists:foreach( fun(#muc_online_room{pid = Pid}) -> gen_fsm:send_all_state_event( Pid, {service_message, Msg}) end, get_vh_rooms(Host)). get_vh_rooms(Host) -> mnesia:dirty_select(muc_online_room, [{#muc_online_room{name_host = '$1', _ = '_'}, [{'==', {element, 2, '$1'}, Host}], ['$_']}]). clean_table_from_bad_node(Node) -> F = fun() -> Es = mnesia:select( muc_online_room, [{#muc_online_room{pid = '$1', _ = '_'}, [{'==', {node, '$1'}, Node}], ['$_']}]), lists:foreach(fun(E) -> mnesia:delete_object(E) end, Es) end, mnesia:async_dirty(F). clean_table_from_bad_node(Node, Host) -> F = fun() -> Es = mnesia:select( muc_online_room, [{#muc_online_room{pid = '$1', name_host = {'_', Host}, _ = '_'}, [{'==', {node, '$1'}, Node}], ['$_']}]), lists:foreach(fun(E) -> mnesia:delete_object(E) end, Es) end, mnesia:async_dirty(F). ejabberd-2.1.11/src/mod_announce_odbc.erl0000664000000000000000000007226312240230175015157 0ustar %%%---------------------------------------------------------------------- %%% File : mod_announce_odbc.erl %%% Author : Alexey Shchepin %%% Purpose : Manage announce messages %%% Created : 11 Aug 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %%% Implements a small subset of XEP-0133: Service Administration %%% Version 1.1 (2005-08-19) -module(mod_announce_odbc). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, init/0, stop/1, announce/3, send_motd/1, disco_identity/5, disco_features/5, disco_items/5, send_announcement_to_all/3, announce_commands/4, announce_items/4]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("adhoc.hrl"). -define(PROCNAME, ejabberd_announce). -define(NS_ADMINL(Sub), ["http:","jabber.org","protocol","admin", Sub]). tokenize(Node) -> string:tokens(Node, "/#"). start(Host, _Opts) -> ejabberd_hooks:add(local_send_to_resource_hook, Host, ?MODULE, announce, 50), ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, disco_identity, 50), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50), ejabberd_hooks:add(disco_local_items, Host, ?MODULE, disco_items, 50), ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, announce_items, 50), ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, announce_commands, 50), ejabberd_hooks:add(user_available_hook, Host, ?MODULE, send_motd, 50), register(gen_mod:get_module_proc(Host, ?PROCNAME), proc_lib:spawn(?MODULE, init, [])). init() -> loop(). loop() -> receive {announce_all, From, To, Packet} -> announce_all(From, To, Packet), loop(); {announce_all_hosts_all, From, To, Packet} -> announce_all_hosts_all(From, To, Packet), loop(); {announce_online, From, To, Packet} -> announce_online(From, To, Packet), loop(); {announce_all_hosts_online, From, To, Packet} -> announce_all_hosts_online(From, To, Packet), loop(); {announce_motd, From, To, Packet} -> announce_motd(From, To, Packet), loop(); {announce_all_hosts_motd, From, To, Packet} -> announce_all_hosts_motd(From, To, Packet), loop(); {announce_motd_update, From, To, Packet} -> announce_motd_update(From, To, Packet), loop(); {announce_all_hosts_motd_update, From, To, Packet} -> announce_all_hosts_motd_update(From, To, Packet), loop(); {announce_motd_delete, From, To, Packet} -> announce_motd_delete(From, To, Packet), loop(); {announce_all_hosts_motd_delete, From, To, Packet} -> announce_all_hosts_motd_delete(From, To, Packet), loop(); _ -> loop() end. stop(Host) -> ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, announce_commands, 50), ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, announce_items, 50), ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 50), ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 50), ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 50), ejabberd_hooks:delete(local_send_to_resource_hook, Host, ?MODULE, announce, 50), ejabberd_hooks:delete(user_available_hook, Host, ?MODULE, send_motd, 50), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), exit(whereis(Proc), stop), {wait, Proc}. %% Announcing via messages to a custom resource announce(From, To, Packet) -> case To of #jid{luser = "", lresource = Res} -> {xmlelement, Name, _Attrs, _Els} = Packet, Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME), case {Res, Name} of {"announce/all", "message"} -> Proc ! {announce_all, From, To, Packet}, stop; {"announce/all-hosts/all", "message"} -> Proc ! {announce_all_hosts_all, From, To, Packet}, stop; {"announce/online", "message"} -> Proc ! {announce_online, From, To, Packet}, stop; {"announce/all-hosts/online", "message"} -> Proc ! {announce_all_hosts_online, From, To, Packet}, stop; {"announce/motd", "message"} -> Proc ! {announce_motd, From, To, Packet}, stop; {"announce/all-hosts/motd", "message"} -> Proc ! {announce_all_hosts_motd, From, To, Packet}, stop; {"announce/motd/update", "message"} -> Proc ! {announce_motd_update, From, To, Packet}, stop; {"announce/all-hosts/motd/update", "message"} -> Proc ! {announce_all_hosts_motd_update, From, To, Packet}, stop; {"announce/motd/delete", "message"} -> Proc ! {announce_motd_delete, From, To, Packet}, stop; {"announce/all-hosts/motd/delete", "message"} -> Proc ! {announce_all_hosts_motd_delete, From, To, Packet}, stop; _ -> ok end; _ -> ok end. %%------------------------------------------------------------------------- %% Announcing via ad-hoc commands -define(INFO_COMMAND(Lang, Node), [{xmlelement, "identity", [{"category", "automation"}, {"type", "command-node"}, {"name", get_title(Lang, Node)}], []}]). disco_identity(Acc, _From, _To, Node, Lang) -> LNode = tokenize(Node), case LNode of ?NS_ADMINL("announce") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("announce-allhosts") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("announce-all") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("announce-all-allhosts") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("set-motd") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("set-motd-allhosts") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("edit-motd") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("edit-motd-allhosts") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("delete-motd") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("delete-motd-allhosts") -> ?INFO_COMMAND(Lang, Node); _ -> Acc end. %%------------------------------------------------------------------------- -define(INFO_RESULT(Allow, Feats), case Allow of deny -> {error, ?ERR_FORBIDDEN}; allow -> {result, Feats} end). disco_features(Acc, From, #jid{lserver = LServer} = _To, "announce", _Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none), Access2 = gen_mod:get_module_opt(global, ?MODULE, access, none), case {acl:match_rule(LServer, Access1, From), acl:match_rule(global, Access2, From)} of {deny, deny} -> {error, ?ERR_FORBIDDEN}; _ -> {result, []} end end; disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none), Allow = acl:match_rule(LServer, Access, From), AccessGlobal = gen_mod:get_module_opt(global, ?MODULE, access, none), AllowGlobal = acl:match_rule(global, AccessGlobal, From), case Node of ?NS_ADMIN ++ "#announce" -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMIN ++ "#announce-all" -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMIN ++ "#set-motd" -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMIN ++ "#edit-motd" -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMIN ++ "#delete-motd" -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMIN ++ "#announce-allhosts" -> ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?NS_ADMIN ++ "#announce-all-allhosts" -> ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?NS_ADMIN ++ "#set-motd-allhosts" -> ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?NS_ADMIN ++ "#edit-motd-allhosts" -> ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?NS_ADMIN ++ "#delete-motd-allhosts" -> ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); _ -> Acc end end. %%------------------------------------------------------------------------- -define(NODE_TO_ITEM(Lang, Server, Node), {xmlelement, "item", [{"jid", Server}, {"node", Node}, {"name", get_title(Lang, Node)}], []}). -define(ITEMS_RESULT(Allow, Items), case Allow of deny -> {error, ?ERR_FORBIDDEN}; allow -> {result, Items} end). disco_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, "", Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none), Access2 = gen_mod:get_module_opt(global, ?MODULE, access, none), case {acl:match_rule(LServer, Access1, From), acl:match_rule(global, Access2, From)} of {deny, deny} -> Acc; _ -> Items = case Acc of {result, I} -> I; _ -> [] end, Nodes = [?NODE_TO_ITEM(Lang, Server, "announce")], {result, Items ++ Nodes} end end; disco_items(Acc, From, #jid{lserver = LServer} = To, "announce", Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> announce_items(Acc, From, To, Lang) end; disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none), Allow = acl:match_rule(LServer, Access, From), AccessGlobal = gen_mod:get_module_opt(global, ?MODULE, access, none), AllowGlobal = acl:match_rule(global, AccessGlobal, From), case Node of ?NS_ADMIN ++ "#announce" -> ?ITEMS_RESULT(Allow, []); ?NS_ADMIN ++ "#announce-all" -> ?ITEMS_RESULT(Allow, []); ?NS_ADMIN ++ "#set-motd" -> ?ITEMS_RESULT(Allow, []); ?NS_ADMIN ++ "#edit-motd" -> ?ITEMS_RESULT(Allow, []); ?NS_ADMIN ++ "#delete-motd" -> ?ITEMS_RESULT(Allow, []); ?NS_ADMIN ++ "#announce-allhosts" -> ?ITEMS_RESULT(AllowGlobal, []); ?NS_ADMIN ++ "#announce-all-allhosts" -> ?ITEMS_RESULT(AllowGlobal, []); ?NS_ADMIN ++ "#set-motd-allhosts" -> ?ITEMS_RESULT(AllowGlobal, []); ?NS_ADMIN ++ "#edit-motd-allhosts" -> ?ITEMS_RESULT(AllowGlobal, []); ?NS_ADMIN ++ "#delete-motd-allhosts" -> ?ITEMS_RESULT(AllowGlobal, []); _ -> Acc end end. %%------------------------------------------------------------------------- announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang) -> Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none), Nodes1 = case acl:match_rule(LServer, Access1, From) of allow -> [?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce-all"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#set-motd"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#edit-motd"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#delete-motd")]; deny -> [] end, Access2 = gen_mod:get_module_opt(global, ?MODULE, access, none), Nodes2 = case acl:match_rule(global, Access2, From) of allow -> [?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce-allhosts"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce-all-allhosts"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#set-motd-allhosts"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#edit-motd-allhosts"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#delete-motd-allhosts")]; deny -> [] end, case {Nodes1, Nodes2} of {[], []} -> Acc; _ -> Items = case Acc of {result, I} -> I; _ -> [] end, {result, Items ++ Nodes1 ++ Nodes2} end. %%------------------------------------------------------------------------- commands_result(Allow, From, To, Request) -> case Allow of deny -> {error, ?ERR_FORBIDDEN}; allow -> announce_commands(From, To, Request) end. announce_commands(Acc, From, #jid{lserver = LServer} = To, #adhoc_request{ node = Node} = Request) -> LNode = tokenize(Node), F = fun() -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), Allow = acl:match_rule(global, Access, From), commands_result(Allow, From, To, Request) end, R = case LNode of ?NS_ADMINL("announce-allhosts") -> F(); ?NS_ADMINL("announce-all-allhosts") -> F(); ?NS_ADMINL("set-motd-allhosts") -> F(); ?NS_ADMINL("edit-motd-allhosts") -> F(); ?NS_ADMINL("delete-motd-allhosts") -> F(); _ -> Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none), Allow = acl:match_rule(LServer, Access, From), case LNode of ?NS_ADMINL("announce") -> commands_result(Allow, From, To, Request); ?NS_ADMINL("announce-all") -> commands_result(Allow, From, To, Request); ?NS_ADMINL("set-motd") -> commands_result(Allow, From, To, Request); ?NS_ADMINL("edit-motd") -> commands_result(Allow, From, To, Request); ?NS_ADMINL("delete-motd") -> commands_result(Allow, From, To, Request); _ -> unknown end end, case R of unknown -> Acc; _ -> {stop, R} end. %%------------------------------------------------------------------------- announce_commands(From, To, #adhoc_request{lang = Lang, node = Node, action = Action, xdata = XData} = Request) -> %% If the "action" attribute is not present, it is %% understood as "execute". If there was no %% element in the first response (which there isn't in our %% case), "execute" and "complete" are equivalent. ActionIsExecute = lists:member(Action, ["", "execute", "complete"]), if Action == "cancel" -> %% User cancels request adhoc:produce_response(Request, #adhoc_response{status = canceled}); XData == false, ActionIsExecute -> %% User requests form Elements = generate_adhoc_form(Lang, Node, To#jid.lserver), adhoc:produce_response( Request, #adhoc_response{status = executing, elements = [Elements]}); XData /= false, ActionIsExecute -> %% User returns form. case jlib:parse_xdata_submit(XData) of invalid -> {error, ?ERR_BAD_REQUEST}; Fields -> handle_adhoc_form(From, To, Request, Fields) end; true -> {error, ?ERR_BAD_REQUEST} end. -define(VVALUE(Val), {xmlelement, "value", [], [{xmlcdata, Val}]}). -define(TVFIELD(Type, Var, Val), {xmlelement, "field", [{"type", Type}, {"var", Var}], vvaluel(Val)}). -define(HFIELD(), ?TVFIELD("hidden", "FORM_TYPE", ?NS_ADMIN)). vvaluel(Val) -> case Val of "" -> []; _ -> [?VVALUE(Val)] end. generate_adhoc_form(Lang, Node, ServerHost) -> LNode = tokenize(Node), {OldSubject, OldBody} = if (LNode == ?NS_ADMINL("edit-motd")) or (LNode == ?NS_ADMINL("edit-motd-allhosts")) -> get_stored_motd(ServerHost); true -> {[], []} end, {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, get_title(Lang, Node)}]}] ++ if (LNode == ?NS_ADMINL("delete-motd")) or (LNode == ?NS_ADMINL("delete-motd-allhosts")) -> [{xmlelement, "field", [{"var", "confirm"}, {"type", "boolean"}, {"label", translate:translate(Lang, "Really delete message of the day?")}], [{xmlelement, "value", [], [{xmlcdata, "true"}]}]}]; true -> [{xmlelement, "field", [{"var", "subject"}, {"type", "text-single"}, {"label", translate:translate(Lang, "Subject")}], vvaluel(OldSubject)}, {xmlelement, "field", [{"var", "body"}, {"type", "text-multi"}, {"label", translate:translate(Lang, "Message body")}], vvaluel(OldBody)}] end}. join_lines([]) -> []; join_lines(Lines) -> join_lines(Lines, []). join_lines([Line|Lines], Acc) -> join_lines(Lines, ["\n",Line|Acc]); join_lines([], Acc) -> %% Remove last newline lists:flatten(lists:reverse(tl(Acc))). handle_adhoc_form(From, #jid{lserver = LServer} = To, #adhoc_request{lang = Lang, node = Node, sessionid = SessionID}, Fields) -> Confirm = case lists:keysearch("confirm", 1, Fields) of {value, {"confirm", ["true"]}} -> true; {value, {"confirm", ["1"]}} -> true; _ -> false end, Subject = case lists:keysearch("subject", 1, Fields) of {value, {"subject", SubjectLines}} -> %% There really shouldn't be more than one %% subject line, but can we stop them? join_lines(SubjectLines); _ -> [] end, Body = case lists:keysearch("body", 1, Fields) of {value, {"body", BodyLines}} -> join_lines(BodyLines); _ -> [] end, Response = #adhoc_response{lang = Lang, node = Node, sessionid = SessionID, status = completed}, Packet = {xmlelement, "message", [{"type", "normal"}], if Subject /= [] -> [{xmlelement, "subject", [], [{xmlcdata, Subject}]}]; true -> [] end ++ if Body /= [] -> [{xmlelement, "body", [], [{xmlcdata, Body}]}]; true -> [] end}, Proc = gen_mod:get_module_proc(LServer, ?PROCNAME), case {Node, Body} of {?NS_ADMIN ++ "#delete-motd", _} -> if Confirm -> Proc ! {announce_motd_delete, From, To, Packet}, adhoc:produce_response(Response); true -> adhoc:produce_response(Response) end; {?NS_ADMIN ++ "#delete-motd-allhosts", _} -> if Confirm -> Proc ! {announce_all_hosts_motd_delete, From, To, Packet}, adhoc:produce_response(Response); true -> adhoc:produce_response(Response) end; {_, []} -> %% An announce message with no body is definitely an operator error. %% Throw an error and give him/her a chance to send message again. {error, ?ERRT_NOT_ACCEPTABLE( Lang, "No body provided for announce message")}; %% Now send the packet to ?PROCNAME. %% We don't use direct announce_* functions because it %% leads to large delay in response and queries processing {?NS_ADMIN ++ "#announce", _} -> Proc ! {announce_online, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#announce-allhosts", _} -> Proc ! {announce_all_hosts_online, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#announce-all", _} -> Proc ! {announce_all, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#announce-all-allhosts", _} -> Proc ! {announce_all_hosts_all, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#set-motd", _} -> Proc ! {announce_motd, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#set-motd-allhosts", _} -> Proc ! {announce_all_hosts_motd, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#edit-motd", _} -> Proc ! {announce_motd_update, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#edit-motd-allhosts", _} -> Proc ! {announce_all_hosts_motd_update, From, To, Packet}, adhoc:produce_response(Response); _ -> %% This can't happen, as we haven't registered any other %% command nodes. {error, ?ERR_INTERNAL_SERVER_ERROR} end. get_title(Lang, "announce") -> translate:translate(Lang, "Announcements"); get_title(Lang, ?NS_ADMIN ++ "#announce-all") -> translate:translate(Lang, "Send announcement to all users"); get_title(Lang, ?NS_ADMIN ++ "#announce-all-allhosts") -> translate:translate(Lang, "Send announcement to all users on all hosts"); get_title(Lang, ?NS_ADMIN ++ "#announce") -> translate:translate(Lang, "Send announcement to all online users"); get_title(Lang, ?NS_ADMIN ++ "#announce-allhosts") -> translate:translate(Lang, "Send announcement to all online users on all hosts"); get_title(Lang, ?NS_ADMIN ++ "#set-motd") -> translate:translate(Lang, "Set message of the day and send to online users"); get_title(Lang, ?NS_ADMIN ++ "#set-motd-allhosts") -> translate:translate(Lang, "Set message of the day on all hosts and send to online users"); get_title(Lang, ?NS_ADMIN ++ "#edit-motd") -> translate:translate(Lang, "Update message of the day (don't send)"); get_title(Lang, ?NS_ADMIN ++ "#edit-motd-allhosts") -> translate:translate(Lang, "Update message of the day on all hosts (don't send)"); get_title(Lang, ?NS_ADMIN ++ "#delete-motd") -> translate:translate(Lang, "Delete message of the day"); get_title(Lang, ?NS_ADMIN ++ "#delete-motd-allhosts") -> translate:translate(Lang, "Delete message of the day on all hosts"). %%------------------------------------------------------------------------- announce_all(From, To, Packet) -> Host = To#jid.lserver, Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), case acl:match_rule(Host, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> Local = jlib:make_jid("", To#jid.server, ""), lists:foreach( fun({User, Server}) -> Dest = jlib:make_jid(User, Server, ""), ejabberd_router:route(Local, Dest, Packet) end, ejabberd_auth:get_vh_registered_users(Host)) end. announce_all_hosts_all(From, To, Packet) -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), case acl:match_rule(global, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> Local = jlib:make_jid("", To#jid.server, ""), lists:foreach( fun({User, Server}) -> Dest = jlib:make_jid(User, Server, ""), ejabberd_router:route(Local, Dest, Packet) end, ejabberd_auth:dirty_get_registered_users()) end. announce_online(From, To, Packet) -> Host = To#jid.lserver, Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), case acl:match_rule(Host, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> announce_online1(ejabberd_sm:get_vh_session_list(Host), To#jid.server, Packet) end. announce_all_hosts_online(From, To, Packet) -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), case acl:match_rule(global, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> announce_online1(ejabberd_sm:dirty_get_sessions_list(), To#jid.server, Packet) end. announce_online1(Sessions, Server, Packet) -> Local = jlib:make_jid("", Server, ""), lists:foreach( fun({U, S, R}) -> Dest = jlib:make_jid(U, S, R), ejabberd_router:route(Local, Dest, Packet) end, Sessions). announce_motd(From, To, Packet) -> Host = To#jid.lserver, Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), case acl:match_rule(Host, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> announce_motd(Host, Packet) end. announce_all_hosts_motd(From, To, Packet) -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), case acl:match_rule(global, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> Hosts = ?MYHOSTS, [announce_motd(Host, Packet) || Host <- Hosts] end. announce_motd(Host, Packet) -> announce_motd_update(Host, Packet), Sessions = ejabberd_sm:get_vh_session_list(Host), announce_online1(Sessions, Host, Packet), F = fun() -> lists:foreach( fun({U, _S, _R}) -> Username = ejabberd_odbc:escape(U), odbc_queries:update_t( "motd", ["username", "xml"], [Username, ""], ["username='", Username, "'"]) end, Sessions) end, LServer = jlib:nameprep(Host), ejabberd_odbc:sql_transaction(LServer, F). announce_motd_update(From, To, Packet) -> Host = To#jid.lserver, Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), case acl:match_rule(Host, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> announce_motd_update(Host, Packet) end. announce_all_hosts_motd_update(From, To, Packet) -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), case acl:match_rule(global, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> Hosts = ?MYHOSTS, [announce_motd_update(Host, Packet) || Host <- Hosts] end. announce_motd_update(LServer, Packet) -> announce_motd_delete(LServer), XML = ejabberd_odbc:escape(xml:element_to_binary(Packet)), F = fun() -> odbc_queries:update_t( "motd", ["username", "xml"], ["", XML], ["username=''"]) end, ejabberd_odbc:sql_transaction(LServer, F). announce_motd_delete(From, To, Packet) -> Host = To#jid.lserver, Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), case acl:match_rule(Host, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> announce_motd_delete(Host) end. announce_all_hosts_motd_delete(From, To, Packet) -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), case acl:match_rule(global, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> Hosts = ?MYHOSTS, [announce_motd_delete(Host) || Host <- Hosts] end. announce_motd_delete(LServer) -> F = fun() -> ejabberd_odbc:sql_query_t(["delete from motd;"]) end, ejabberd_odbc:sql_transaction(LServer, F). send_motd(#jid{luser = LUser, lserver = LServer} = JID) when LUser /= "" -> case catch ejabberd_odbc:sql_query( LServer, ["select xml from motd where username='';"]) of {selected, ["xml"], [{XML}]} -> case xml_stream:parse_element(XML) of {error, _} -> ok; Packet -> Username = ejabberd_odbc:escape(LUser), case catch ejabberd_odbc:sql_query( LServer, ["select username from motd " "where username='", Username, "';"]) of {selected, ["username"], []} -> Local = jlib:make_jid("", LServer, ""), ejabberd_router:route(Local, JID, Packet), F = fun() -> odbc_queries:update_t( "motd", ["username", "xml"], [Username, ""], ["username='", Username, "'"]) end, ejabberd_odbc:sql_transaction(LServer, F); _ -> ok end end; _ -> ok end; send_motd(_) -> ok. get_stored_motd(LServer) -> case catch ejabberd_odbc:sql_query( LServer, ["select xml from motd where username='';"]) of {selected, ["xml"], [{XML}]} -> case xml_stream:parse_element(XML) of {error, _} -> {"", ""}; Packet -> {xml:get_subtag_cdata(Packet, "subject"), xml:get_subtag_cdata(Packet, "body")} end; _ -> {"", ""} end. %% This function is similar to others, but doesn't perform any ACL verification send_announcement_to_all(Host, SubjectS, BodyS) -> SubjectEls = if SubjectS /= [] -> [{xmlelement, "subject", [], [{xmlcdata, SubjectS}]}]; true -> [] end, BodyEls = if BodyS /= [] -> [{xmlelement, "body", [], [{xmlcdata, BodyS}]}]; true -> [] end, Packet = {xmlelement, "message", [{"type", "normal"}], SubjectEls ++ BodyEls}, Sessions = ejabberd_sm:dirty_get_sessions_list(), Local = jlib:make_jid("", Host, ""), lists:foreach( fun({U, S, R}) -> Dest = jlib:make_jid(U, S, R), ejabberd_router:route(Local, Dest, Packet) end, Sessions). ejabberd-2.1.11/src/win32_dns.erl0000664000000000000000000001062512240230175013323 0ustar %%%---------------------------------------------------------------------- %%% File : win32_dns.erl %%% Author : Geoff Cant %%% Purpose : Get name servers in a Windows machine %%% Created : 5 Mar 2009 by Geoff Cant %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(win32_dns). -export([get_nameservers/0]). -include("ejabberd.hrl"). -define(IF_KEY, "\\hklm\\system\\CurrentControlSet\\Services\\TcpIp\\Parameters\\Interfaces"). -define(TOP_KEY, "\\hklm\\system\\CurrentControlSet\\Services\\TcpIp\\Parameters"). get_nameservers() -> {_, Config} = pick_config(), IPTs = get_value(["NameServer"], Config), lists:filter(fun(IPTuple) -> is_good_ns(IPTuple) end, IPTs). is_good_ns(Addr) -> element(1, inet_res:nnslookup("a.root-servers.net", in, any, [{Addr,53}], timer:seconds(5) ) ) =:= ok. reg() -> {ok, R} = win32reg:open([read]), R. interfaces(R) -> ok = win32reg:change_key(R, ?IF_KEY), {ok, I} = win32reg:sub_keys(R), I. config_keys(R, Key) -> ok = win32reg:change_key(R, Key), [ {K, case win32reg:value(R, K) of {ok, V} -> try_translate(K, V); _ -> undefined end } || K <- ["Domain", "DhcpDomain", "NameServer", "DhcpNameServer", "SearchList"]]. try_translate(K, V) -> try translate(K, V) of Res -> Res catch A:B -> ?ERROR_MSG("Error '~p' translating Win32 registry~n" "K: ~p~nV: ~p~nError: ~p", [A, K, V, B]), undefined end. translate(NS, V) when NS =:= "NameServer"; NS =:= "DhcpNameServer" -> %% The IPs may be separated by commas ',' or by spaces " " %% The parts of an IP are separated by dots '.' IPsStrings = [string:tokens(IP, ".") || IP <- string:tokens(V, " ,")], [ list_to_tuple([list_to_integer(String) || String <- IpStrings]) || IpStrings <- IPsStrings]; translate(_, V) -> V. interface_configs(R) -> [{If, config_keys(R, ?IF_KEY ++ "\\" ++ If)} || If <- interfaces(R)]. sort_configs(Configs) -> lists:sort(fun ({_, A}, {_, B}) -> ANS = proplists:get_value("NameServer", A), BNS = proplists:get_value("NameServer", B), if ANS =/= undefined, BNS =:= undefined -> false; true -> count_undef(A) < count_undef(B) end end, Configs). count_undef(L) when is_list(L) -> lists:foldl(fun ({_K, undefined}, Acc) -> Acc +1; ({_K, []}, Acc) -> Acc +1; (_, Acc) -> Acc end, 0, L). all_configs() -> R = reg(), TopConfig = config_keys(R, ?TOP_KEY), Configs = [{top, TopConfig} | interface_configs(R)], win32reg:close(R), {TopConfig, Configs}. pick_config() -> {TopConfig, Configs} = all_configs(), NSConfigs = [{If, C} || {If, C} <- Configs, get_value(["DhcpNameServer","NameServer"], C) =/= undefined], case get_value(["DhcpNameServer","NameServer"], TopConfig) of %% No top level nameserver to pick interface with undefined -> hd(sort_configs(NSConfigs)); %% Top level has a nameserver - use this to select an interface. NS -> Cs = [ {If, C} || {If, C} <- Configs, lists:member(NS, [get_value(["NameServer"], C), get_value(["DhcpNameServer"], C)])], hd(sort_configs(Cs)) end. get_value([], _Config) -> undefined; get_value([K|Keys], Config) -> case proplists:get_value(K, Config) of undefined -> get_value(Keys, Config); V -> V end. ejabberd-2.1.11/src/mod_vcard.erl0000664000000000000000000006432412240230175013460 0ustar %%%---------------------------------------------------------------------- %%% File : mod_vcard.erl %%% Author : Alexey Shchepin %%% Purpose : Vcard management in Mnesia %%% Created : 2 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_vcard). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, init/3, stop/1, get_sm_features/5, process_local_iq/3, process_sm_iq/3, reindex_vcards/0, remove_user/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). -define(JUD_MATCHES, 30). -record(vcard_search, {us, user, luser, fn, lfn, family, lfamily, given, lgiven, middle, lmiddle, nickname, lnickname, bday, lbday, ctry, lctry, locality, llocality, email, lemail, orgname, lorgname, orgunit, lorgunit }). -record(vcard, {us, vcard}). -define(PROCNAME, ejabberd_mod_vcard). start(Host, Opts) -> mnesia:create_table(vcard, [{disc_only_copies, [node()]}, {attributes, record_info(fields, vcard)}]), mnesia:create_table(vcard_search, [{disc_copies, [node()]}, {attributes, record_info(fields, vcard_search)}]), update_tables(), mnesia:add_table_index(vcard_search, luser), mnesia:add_table_index(vcard_search, lfn), mnesia:add_table_index(vcard_search, lfamily), mnesia:add_table_index(vcard_search, lgiven), mnesia:add_table_index(vcard_search, lmiddle), mnesia:add_table_index(vcard_search, lnickname), mnesia:add_table_index(vcard_search, lbday), mnesia:add_table_index(vcard_search, lctry), mnesia:add_table_index(vcard_search, llocality), mnesia:add_table_index(vcard_search, lemail), mnesia:add_table_index(vcard_search, lorgname), mnesia:add_table_index(vcard_search, lorgunit), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD, ?MODULE, process_local_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD, ?MODULE, process_sm_iq, IQDisc), ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50), MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"), Search = gen_mod:get_opt(search, Opts, true), register(gen_mod:get_module_proc(Host, ?PROCNAME), spawn(?MODULE, init, [MyHost, Host, Search])). init(Host, ServerHost, Search) -> case Search of false -> loop(Host, ServerHost); _ -> ejabberd_router:register_route(Host), loop(Host, ServerHost) end. loop(Host, ServerHost) -> receive {route, From, To, Packet} -> case catch do_route(ServerHost, From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); _ -> ok end, loop(Host, ServerHost); stop -> ejabberd_router:unregister_route(Host), ok; _ -> loop(Host, ServerHost) end. stop(Host) -> ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), Proc ! stop, {wait, Proc}. get_sm_features({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; get_sm_features(Acc, _From, _To, Node, _Lang) -> case Node of [] -> case Acc of {result, Features} -> {result, [?NS_DISCO_INFO, ?NS_VCARD | Features]}; empty -> {result, [?NS_DISCO_INFO, ?NS_VCARD]} end; _ -> Acc end. process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", ?NS_VCARD}], [{xmlelement, "FN", [], [{xmlcdata, "ejabberd"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate( Lang, "Erlang Jabber Server") ++ "\nCopyright (c) 2002-2012 ProcessOne"}]}, {xmlelement, "BDAY", [], [{xmlcdata, "2002-11-16"}]} ]}]} end. process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) -> case Type of set -> #jid{user = User, lserver = LServer} = From, case lists:member(LServer, ?MYHOSTS) of true -> set_vcard(User, LServer, SubEl), IQ#iq{type = result, sub_el = []}; false -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} end; get -> #jid{luser = LUser, lserver = LServer} = To, US = {LUser, LServer}, F = fun() -> mnesia:read({vcard, US}) end, Els = case mnesia:transaction(F) of {atomic, Rs} -> lists:map(fun(R) -> R#vcard.vcard end, Rs); {aborted, _Reason} -> [] end, IQ#iq{type = result, sub_el = Els} end. set_vcard(User, LServer, VCARD) -> FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]), Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]), Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]), Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]), Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]), BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]), CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]), Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]), EMail1 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, {elem, "USERID"},cdata]), EMail2 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]), OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]), OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]), EMail = case EMail1 of "" -> EMail2; _ -> EMail1 end, LUser = jlib:nodeprep(User), LFN = string2lower(FN), LFamily = string2lower(Family), LGiven = string2lower(Given), LMiddle = string2lower(Middle), LNickname = string2lower(Nickname), LBDay = string2lower(BDay), LCTRY = string2lower(CTRY), LLocality = string2lower(Locality), LEMail = string2lower(EMail), LOrgName = string2lower(OrgName), LOrgUnit = string2lower(OrgUnit), US = {LUser, LServer}, if (LUser == error) or (LFN == error) or (LFamily == error) or (LGiven == error) or (LMiddle == error) or (LNickname == error) or (LBDay == error) or (LCTRY == error) or (LLocality == error) or (LEMail == error) or (LOrgName == error) or (LOrgUnit == error) -> {error, badarg}; true -> F = fun() -> mnesia:write(#vcard{us = US, vcard = VCARD}), mnesia:write( #vcard_search{us = US, user = {User, LServer}, luser = LUser, fn = FN, lfn = LFN, family = Family, lfamily = LFamily, given = Given, lgiven = LGiven, middle = Middle, lmiddle = LMiddle, nickname = Nickname, lnickname = LNickname, bday = BDay, lbday = LBDay, ctry = CTRY, lctry = LCTRY, locality = Locality, llocality = LLocality, email = EMail, lemail = LEMail, orgname = OrgName, lorgname = LOrgName, orgunit = OrgUnit, lorgunit = LOrgUnit }) end, mnesia:transaction(F), ejabberd_hooks:run(vcard_set, LServer, [LUser, LServer, VCARD]) end. string2lower(String) -> case stringprep:tolower(String) of Lower when is_list(Lower) -> Lower; error -> string:to_lower(String) end. -define(TLFIELD(Type, Label, Var), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, {"var", Var}], []}). -define(FORM(JID), [{xmlelement, "instructions", [], [{xmlcdata, translate:translate(Lang, "You need an x:data capable client to search")}]}, {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "Search users in ") ++ jlib:jid_to_string(JID)}]}, {xmlelement, "instructions", [], [{xmlcdata, translate:translate(Lang, "Fill in the form to search " "for any matching Jabber User " "(Add * to the end of field to " "match substring)")}]}, ?TLFIELD("text-single", "User", "user"), ?TLFIELD("text-single", "Full Name", "fn"), ?TLFIELD("text-single", "Name", "first"), ?TLFIELD("text-single", "Middle Name", "middle"), ?TLFIELD("text-single", "Family Name", "last"), ?TLFIELD("text-single", "Nickname", "nick"), ?TLFIELD("text-single", "Birthday", "bday"), ?TLFIELD("text-single", "Country", "ctry"), ?TLFIELD("text-single", "City", "locality"), ?TLFIELD("text-single", "Email", "email"), ?TLFIELD("text-single", "Organization Name", "orgname"), ?TLFIELD("text-single", "Organization Unit", "orgunit") ]}]). do_route(ServerHost, From, To, Packet) -> #jid{user = User, resource = Resource} = To, if (User /= "") or (Resource /= "") -> Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err); true -> IQ = jlib:iq_query_info(Packet), case IQ of #iq{type = Type, xmlns = ?NS_SEARCH, lang = Lang, sub_el = SubEl} -> case Type of set -> XDataEl = find_xdata_el(SubEl), case XDataEl of false -> Err = jlib:make_error_reply( Packet, ?ERR_BAD_REQUEST), ejabberd_router:route(To, From, Err); _ -> XData = jlib:parse_xdata_submit(XDataEl), case XData of invalid -> Err = jlib:make_error_reply( Packet, ?ERR_BAD_REQUEST), ejabberd_router:route(To, From, Err); _ -> ResIQ = IQ#iq{ type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_SEARCH}], [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}], search_result(Lang, To, ServerHost, XData) }]}]}, ejabberd_router:route( To, From, jlib:iq_to_xml(ResIQ)) end end; get -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_SEARCH}], ?FORM(To) }]}, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) end; #iq{type = Type, xmlns = ?NS_DISCO_INFO, lang = Lang} -> case Type of set -> Err = jlib:make_error_reply( Packet, ?ERR_NOT_ALLOWED), ejabberd_router:route(To, From, Err); get -> Info = ejabberd_hooks:run_fold( disco_info, ServerHost, [], [ServerHost, ?MODULE, "", ""]), ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_INFO}], [{xmlelement, "identity", [{"category", "directory"}, {"type", "user"}, {"name", translate:translate(Lang, "vCard User Search")}], []}, {xmlelement, "feature", [{"var", ?NS_DISCO_INFO}], []}, {xmlelement, "feature", [{"var", ?NS_SEARCH}], []}, {xmlelement, "feature", [{"var", ?NS_VCARD}], []} ] ++ Info }]}, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) end; #iq{type = Type, xmlns = ?NS_DISCO_ITEMS} -> case Type of set -> Err = jlib:make_error_reply( Packet, ?ERR_NOT_ALLOWED), ejabberd_router:route(To, From, Err); get -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}], []}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)) end; #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} -> ResIQ = IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", ?NS_VCARD}], iq_get_vcard(Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); _ -> Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err) end end. iq_get_vcard(Lang) -> [{xmlelement, "FN", [], [{xmlcdata, "ejabberd/mod_vcard"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate( Lang, "ejabberd vCard module") ++ "\nCopyright (c) 2003-2012 ProcessOne"}]}]. find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) -> find_xdata_el1(SubEls). find_xdata_el1([]) -> false; find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) -> case xml:get_attr_s("xmlns", Attrs) of ?NS_XDATA -> {xmlelement, Name, Attrs, SubEls}; _ -> find_xdata_el1(Els) end; find_xdata_el1([_ | Els]) -> find_xdata_el1(Els). -define(LFIELD(Label, Var), {xmlelement, "field", [{"label", translate:translate(Lang, Label)}, {"var", Var}], []}). search_result(Lang, JID, ServerHost, Data) -> [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "Search Results for ") ++ jlib:jid_to_string(JID)}]}, {xmlelement, "reported", [], [?TLFIELD("text-single", "Jabber ID", "jid"), ?TLFIELD("text-single", "Full Name", "fn"), ?TLFIELD("text-single", "Name", "first"), ?TLFIELD("text-single", "Middle Name", "middle"), ?TLFIELD("text-single", "Family Name", "last"), ?TLFIELD("text-single", "Nickname", "nick"), ?TLFIELD("text-single", "Birthday", "bday"), ?TLFIELD("text-single", "Country", "ctry"), ?TLFIELD("text-single", "City", "locality"), ?TLFIELD("text-single", "Email", "email"), ?TLFIELD("text-single", "Organization Name", "orgname"), ?TLFIELD("text-single", "Organization Unit", "orgunit") ]}] ++ lists:map(fun record_to_item/1, search(ServerHost, Data)). -define(FIELD(Var, Val), {xmlelement, "field", [{"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). record_to_item(R) -> {User, Server} = R#vcard_search.user, {xmlelement, "item", [], [ ?FIELD("jid", User ++ "@" ++ Server), ?FIELD("fn", R#vcard_search.fn), ?FIELD("last", R#vcard_search.family), ?FIELD("first", R#vcard_search.given), ?FIELD("middle", R#vcard_search.middle), ?FIELD("nick", R#vcard_search.nickname), ?FIELD("bday", R#vcard_search.bday), ?FIELD("ctry", R#vcard_search.ctry), ?FIELD("locality", R#vcard_search.locality), ?FIELD("email", R#vcard_search.email), ?FIELD("orgname", R#vcard_search.orgname), ?FIELD("orgunit", R#vcard_search.orgunit) ] }. search(LServer, Data) -> MatchSpec = make_matchspec(LServer, Data), AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE, allow_return_all, false), if (MatchSpec == #vcard_search{_ = '_'}) and (not AllowReturnAll) -> []; true -> case catch mnesia:dirty_select(vcard_search, [{MatchSpec, [], ['$_']}]) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]), []; Rs -> case gen_mod:get_module_opt(LServer, ?MODULE, matches, ?JUD_MATCHES) of infinity -> Rs; Val when is_integer(Val) and (Val > 0) -> lists:sublist(Rs, Val); Val -> ?ERROR_MSG("Illegal option value ~p. " "Default value ~p substituted.", [{matches, Val}, ?JUD_MATCHES]), lists:sublist(Rs, ?JUD_MATCHES) end end end. make_matchspec(LServer, Data) -> GlobMatch = #vcard_search{_ = '_'}, Match = filter_fields(Data, GlobMatch, LServer), Match. filter_fields([], Match, _LServer) -> Match; filter_fields([{SVar, [Val]} | Ds], Match, LServer) when is_list(Val) and (Val /= "") -> LVal = string2lower(Val), NewMatch = case SVar of "user" -> case gen_mod:get_module_opt(LServer, ?MODULE, search_all_hosts, true) of true -> Match#vcard_search{luser = make_val(LVal)}; false -> Host = find_my_host(LServer), Match#vcard_search{us = {make_val(LVal), Host}} end; "fn" -> Match#vcard_search{lfn = make_val(LVal)}; "last" -> Match#vcard_search{lfamily = make_val(LVal)}; "first" -> Match#vcard_search{lgiven = make_val(LVal)}; "middle" -> Match#vcard_search{lmiddle = make_val(LVal)}; "nick" -> Match#vcard_search{lnickname = make_val(LVal)}; "bday" -> Match#vcard_search{lbday = make_val(LVal)}; "ctry" -> Match#vcard_search{lctry = make_val(LVal)}; "locality" -> Match#vcard_search{llocality = make_val(LVal)}; "email" -> Match#vcard_search{lemail = make_val(LVal)}; "orgname" -> Match#vcard_search{lorgname = make_val(LVal)}; "orgunit" -> Match#vcard_search{lorgunit = make_val(LVal)}; _ -> Match end, filter_fields(Ds, NewMatch, LServer); filter_fields([_ | Ds], Match, LServer) -> filter_fields(Ds, Match, LServer). make_val(Val) -> case lists:suffix("*", Val) of true -> lists:sublist(Val, length(Val) - 1) ++ '_'; _ -> Val end. find_my_host(LServer) -> Parts = string:tokens(LServer, "."), find_my_host(Parts, ?MYHOSTS). find_my_host([], _Hosts) -> ?MYNAME; find_my_host([_ | Tail] = Parts, Hosts) -> Domain = parts_to_string(Parts), case lists:member(Domain, Hosts) of true -> Domain; false -> find_my_host(Tail, Hosts) end. parts_to_string(Parts) -> string:strip(lists:flatten(lists:map(fun(S) -> [S, $.] end, Parts)), right, $.). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% set_vcard_t(R, _) -> US = R#vcard.us, User = US, VCARD = R#vcard.vcard, FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]), Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]), Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]), Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]), Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]), BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]), CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]), Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]), EMail = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]), OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]), OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]), {LUser, _LServer} = US, LFN = string2lower(FN), LFamily = string2lower(Family), LGiven = string2lower(Given), LMiddle = string2lower(Middle), LNickname = string2lower(Nickname), LBDay = string2lower(BDay), LCTRY = string2lower(CTRY), LLocality = string2lower(Locality), LEMail = string2lower(EMail), LOrgName = string2lower(OrgName), LOrgUnit = string2lower(OrgUnit), if (LUser == error) or (LFN == error) or (LFamily == error) or (LGiven == error) or (LMiddle == error) or (LNickname == error) or (LBDay == error) or (LCTRY == error) or (LLocality == error) or (LEMail == error) or (LOrgName == error) or (LOrgUnit == error) -> {error, badarg}; true -> mnesia:write( #vcard_search{us = US, user = User, luser = LUser, fn = FN, lfn = LFN, family = Family, lfamily = LFamily, given = Given, lgiven = LGiven, middle = Middle, lmiddle = LMiddle, nickname = Nickname, lnickname = LNickname, bday = BDay, lbday = LBDay, ctry = CTRY, lctry = LCTRY, locality = Locality, llocality = LLocality, email = EMail, lemail = LEMail, orgname = OrgName, lorgname = LOrgName, orgunit = OrgUnit, lorgunit = LOrgUnit }) end. reindex_vcards() -> F = fun() -> mnesia:foldl(fun set_vcard_t/2, [], vcard) end, mnesia:transaction(F). remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, F = fun() -> mnesia:delete({vcard, US}), mnesia:delete({vcard_search, US}) end, mnesia:transaction(F). update_tables() -> update_vcard_table(), update_vcard_search_table(). update_vcard_table() -> Fields = record_info(fields, vcard), case mnesia:table_info(vcard, attributes) of Fields -> ok; [user, vcard] -> ?INFO_MSG("Converting vcard table from " "{user, vcard} format", []), Host = ?MYNAME, {atomic, ok} = mnesia:create_table( mod_vcard_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, vcard}, {attributes, record_info(fields, vcard)}]), mnesia:transform_table(vcard, ignore, Fields), F1 = fun() -> mnesia:write_lock_table(mod_vcard_tmp_table), mnesia:foldl( fun(#vcard{us = U} = R, _) -> mnesia:dirty_write( mod_vcard_tmp_table, R#vcard{us = {U, Host}}) end, ok, vcard) end, mnesia:transaction(F1), mnesia:clear_table(vcard), F2 = fun() -> mnesia:write_lock_table(vcard), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, mod_vcard_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(mod_vcard_tmp_table); _ -> ?INFO_MSG("Recreating vcard table", []), mnesia:transform_table(vcard, ignore, Fields) end. update_vcard_search_table() -> Fields = record_info(fields, vcard_search), case mnesia:table_info(vcard_search, attributes) of Fields -> ok; [user, luser, fn, lfn, family, lfamily, given, lgiven, middle, lmiddle, nickname, lnickname, bday, lbday, ctry, lctry, locality, llocality, email, lemail, orgname, lorgname, orgunit, lorgunit] -> ?INFO_MSG("Converting vcard_search table from " "{user, luser, fn, lfn, family, lfamily, given, lgiven, middle, lmiddle, nickname, lnickname, bday, lbday, ctry, lctry, locality, llocality, email, lemail, orgname, lorgname, orgunit, lorgunit} format", []), Host = ?MYNAME, {atomic, ok} = mnesia:create_table( mod_vcard_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, vcard_search}, {attributes, record_info(fields, vcard_search)}]), F1 = fun() -> mnesia:write_lock_table(mod_vcard_tmp_table), mnesia:foldl( fun({vcard_search, User, LUser, FN, LFN, Family, LFamily, Given, LGiven, Middle, LMiddle, Nickname, LNickname, BDay, LBDay, CTRY, LCTRY, Locality, LLocality, EMail, LEMail, OrgName, LOrgName, OrgUnit, LOrgUnit }, _) -> mnesia:dirty_write( mod_vcard_tmp_table, #vcard_search{ us = {LUser, Host}, user = {User, Host}, luser = LUser, fn = FN, lfn = LFN, family = Family, lfamily = LFamily, given = Given, lgiven = LGiven, middle = Middle, lmiddle = LMiddle, nickname = Nickname, lnickname = LNickname, bday = BDay, lbday = LBDay, ctry = CTRY, lctry = LCTRY, locality = Locality, llocality = LLocality, email = EMail, lemail = LEMail, orgname = OrgName, lorgname = LOrgName, orgunit = OrgUnit, lorgunit = LOrgUnit }) end, ok, vcard_search) end, mnesia:transaction(F1), lists:foreach(fun(I) -> mnesia:del_table_index( vcard_search, element(I, {vcard_search, user, luser, fn, lfn, family, lfamily, given, lgiven, middle, lmiddle, nickname, lnickname, bday, lbday, ctry, lctry, locality, llocality, email, lemail, orgname, lorgname, orgunit, lorgunit})) end, mnesia:table_info(vcard_search, index)), mnesia:clear_table(vcard_search), mnesia:transform_table(vcard_search, ignore, Fields), F2 = fun() -> mnesia:write_lock_table(vcard_search), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, mod_vcard_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(mod_vcard_tmp_table); _ -> ?INFO_MSG("Recreating vcard_search table", []), mnesia:transform_table(vcard_search, ignore, Fields) end. ejabberd-2.1.11/src/ejd2odbc.erl0000664000000000000000000004746312240230175013203 0ustar %%%---------------------------------------------------------------------- %%% File : ejd2odbc.erl %%% Author : Alexey Shchepin %%% Purpose : Export some mnesia tables to SQL DB %%% Created : 22 Aug 2005 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejd2odbc). -author('alexey@process-one.net'). %% External exports -export([export_passwd/2, export_roster/2, export_offline/2, export_last/2, export_vcard/2, export_vcard_search/2, export_vcard_xupdate/2, export_private_storage/2, export_privacy/2, export_motd/2, export_motd_users/2, export_irc_custom/2, export_sr_group/2, export_sr_user/2, export_muc_room/2, export_muc_registered/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_roster.hrl"). -include("mod_privacy.hrl"). -record(offline_msg, {us, timestamp, expire, from, to, packet}). -record(last_activity, {us, timestamp, status}). -record(vcard, {us, vcard}). -record(vcard_xupdate, {us, hash}). -record(vcard_search, {us, user, luser, fn, lfn, family, lfamily, given, lgiven, middle, lmiddle, nickname, lnickname, bday, lbday, ctry, lctry, locality, llocality, email, lemail, orgname, lorgname, orgunit, lorgunit }). -record(private_storage, {usns, xml}). -record(irc_custom, {us_host, data}). -record(muc_room, {name_host, opts}). -record(muc_registered, {us_host, nick}). -record(sr_group, {group_host, opts}). -record(sr_user, {us, group_host}). -record(motd, {server, packet}). -record(motd_users, {us, dummy = []}). -define(MAX_RECORDS_PER_TRANSACTION, 1000). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- %%% How to use: %%% A table can be converted from Mnesia to an ODBC database by calling %%% one of the API function with the following parameters: %%% - Server is the server domain you want to convert %%% - Output can be either odbc to export to the configured relational %%% database or "Filename" to export to text file. export_passwd(Server, Output) -> export_common( Server, passwd, Output, fun(Host, {passwd, {LUser, LServer}, Password} = _R) when LServer == Host -> Username = ejabberd_odbc:escape(LUser), Pass = ejabberd_odbc:escape(Password), ["delete from users where username='", Username ,"';" "insert into users(username, password) " "values ('", Username, "', '", Pass, "');"]; (_Host, _R) -> [] end). export_roster(Server, Output) -> export_common( Server, roster, Output, fun(Host, #roster{usj = {LUser, LServer, LJID}} = R) when LServer == Host -> Username = ejabberd_odbc:escape(LUser), SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)), ItemVals = record_to_string(R), ItemGroups = groups_to_string(R), ["delete from rosterusers " " where username='", Username, "' " " and jid='", SJID, "';" "insert into rosterusers(" " username, jid, nick, " " subscription, ask, askmessage, " " server, subscribe, type) " " values ", ItemVals, ";" "delete from rostergroups " " where username='", Username, "' " " and jid='", SJID, "';", [["insert into rostergroups(" " username, jid, grp) " " values ", ItemGroup, ";"] || ItemGroup <- ItemGroups]]; (_Host, _R) -> [] end). export_offline(Server, Output) -> export_common( Server, offline_msg, Output, fun(Host, #offline_msg{us = {LUser, LServer}, timestamp = TimeStamp, from = From, to = To, packet = Packet}) when LServer == Host -> Username = ejabberd_odbc:escape(LUser), {xmlelement, Name, Attrs, Els} = Packet, Attrs2 = jlib:replace_from_to_attrs( jlib:jid_to_string(From), jlib:jid_to_string(To), Attrs), NewPacket = {xmlelement, Name, Attrs2, Els ++ [jlib:timestamp_to_xml( calendar:now_to_universal_time(TimeStamp), utc, jlib:make_jid("", Server, ""), "Offline Storage"), %% TODO: Delete the next three lines once XEP-0091 is Obsolete jlib:timestamp_to_xml( calendar:now_to_universal_time( TimeStamp))]}, XML = ejabberd_odbc:escape( xml:element_to_binary(NewPacket)), ["insert into spool(username, xml) " "values ('", Username, "', '", XML, "');"]; (_Host, _R) -> [] end). export_last(Server, Output) -> export_common( Server, last_activity, Output, fun(Host, #last_activity{us = {LUser, LServer}, timestamp = TimeStamp, status = Status}) when LServer == Host -> Username = ejabberd_odbc:escape(LUser), Seconds = ejabberd_odbc:escape(integer_to_list(TimeStamp)), State = ejabberd_odbc:escape(Status), ["delete from last where username='", Username, "';" "insert into last(username, seconds, state) " "values ('", Username, "', '", Seconds, "', '", State, "');"]; (_Host, _R) -> [] end). export_vcard(Server, Output) -> export_common( Server, vcard, Output, fun(Host, #vcard{us = {LUser, LServer}, vcard = VCARD}) when LServer == Host -> Username = ejabberd_odbc:escape(LUser), SVCARD = ejabberd_odbc:escape( xml:element_to_binary(VCARD)), ["delete from vcard where username='", Username, "';" "insert into vcard(username, vcard) " "values ('", Username, "', '", SVCARD, "');"]; (_Host, _R) -> [] end). export_vcard_search(Server, Output) -> export_common( Server, vcard_search, Output, fun(Host, #vcard_search{user = {User, LServer}, luser = LUser, fn = FN, lfn = LFN, family = Family, lfamily = LFamily, given = Given, lgiven = LGiven, middle = Middle, lmiddle = LMiddle, nickname = Nickname, lnickname = LNickname, bday = BDay, lbday = LBDay, ctry = CTRY, lctry = LCTRY, locality = Locality, llocality = LLocality, email = EMail, lemail = LEMail, orgname = OrgName, lorgname = LOrgName, orgunit = OrgUnit, lorgunit = LOrgUnit }) when LServer == Host -> Username = ejabberd_odbc:escape(User), LUsername = ejabberd_odbc:escape(LUser), SFN = ejabberd_odbc:escape(FN), SLFN = ejabberd_odbc:escape(LFN), SFamily = ejabberd_odbc:escape(Family), SLFamily = ejabberd_odbc:escape(LFamily), SGiven = ejabberd_odbc:escape(Given), SLGiven = ejabberd_odbc:escape(LGiven), SMiddle = ejabberd_odbc:escape(Middle), SLMiddle = ejabberd_odbc:escape(LMiddle), SNickname = ejabberd_odbc:escape(Nickname), SLNickname = ejabberd_odbc:escape(LNickname), SBDay = ejabberd_odbc:escape(BDay), SLBDay = ejabberd_odbc:escape(LBDay), SCTRY = ejabberd_odbc:escape(CTRY), SLCTRY = ejabberd_odbc:escape(LCTRY), SLocality = ejabberd_odbc:escape(Locality), SLLocality = ejabberd_odbc:escape(LLocality), SEMail = ejabberd_odbc:escape(EMail), SLEMail = ejabberd_odbc:escape(LEMail), SOrgName = ejabberd_odbc:escape(OrgName), SLOrgName = ejabberd_odbc:escape(LOrgName), SOrgUnit = ejabberd_odbc:escape(OrgUnit), SLOrgUnit = ejabberd_odbc:escape(LOrgUnit), ["delete from vcard_search where lusername='", LUsername, "';" "insert into vcard_search(" " username, lusername, fn, lfn, family, lfamily," " given, lgiven, middle, lmiddle, nickname, lnickname," " bday, lbday, ctry, lctry, locality, llocality," " email, lemail, orgname, lorgname, orgunit, lorgunit)" "values (", " '", Username, "', '", LUsername, "'," " '", SFN, "', '", SLFN, "'," " '", SFamily, "', '", SLFamily, "'," " '", SGiven, "', '", SLGiven, "'," " '", SMiddle, "', '", SLMiddle, "'," " '", SNickname, "', '", SLNickname, "'," " '", SBDay, "', '", SLBDay, "'," " '", SCTRY, "', '", SLCTRY, "'," " '", SLocality, "', '", SLLocality, "'," " '", SEMail, "', '", SLEMail, "'," " '", SOrgName, "', '", SLOrgName, "'," " '", SOrgUnit, "', '", SLOrgUnit, "');"]; (_Host, _R) -> [] end). export_vcard_xupdate(Server, Output) -> export_common( Server, vcard_xupdate, Output, fun(Host, #vcard_xupdate{us = {LUser, LServer}, hash = Hash}) when LServer == Host -> Username = ejabberd_odbc:escape(LUser), SHash = ejabberd_odbc:escape(Hash), ["delete from vcard_xupdate where username='", Username, "';" "insert into vcard_xupdate(username, hash) " "values ('", Username, "', '", SHash, "');"]; (_Host, _R) -> [] end). export_private_storage(Server, Output) -> export_common( Server, private_storage, Output, fun(Host, #private_storage{usns = {LUser, LServer, XMLNS}, xml = Data}) when LServer == Host -> Username = ejabberd_odbc:escape(LUser), LXMLNS = ejabberd_odbc:escape(XMLNS), SData = ejabberd_odbc:escape( xml:element_to_binary(Data)), odbc_queries:set_private_data_sql(Username, LXMLNS, SData); (_Host, _R) -> [] end). export_muc_room(Server, Output) -> export_common( Server, muc_room, Output, fun(Host, #muc_room{name_host = {Name, RoomHost}, opts = Opts}) -> case lists:suffix(Host, RoomHost) of true -> SName = ejabberd_odbc:escape(Name), SRoomHost = ejabberd_odbc:escape(RoomHost), SOpts = ejabberd_odbc:encode_term(Opts), ["delete from muc_room where name='", SName, "' and host='", SRoomHost, "';", "insert into muc_room(name, host, opts) values (", "'", SName, "', '", SRoomHost, "', '", SOpts, "');"]; false -> [] end end). export_muc_registered(Server, Output) -> export_common( Server, muc_registered, Output, fun(Host, #muc_registered{us_host = {{U, S}, RoomHost}, nick = Nick}) -> case lists:suffix(Host, RoomHost) of true -> SJID = ejabberd_odbc:escape( jlib:jid_to_string( jlib:make_jid(U, S, ""))), SNick = ejabberd_odbc:escape(Nick), SRoomHost = ejabberd_odbc:escape(RoomHost), ["delete from muc_registered where jid='", SJID, "' and host='", SRoomHost, "';" "insert into muc_registered(jid, host, nick) values (" "'", SJID, "', '", SRoomHost, "', '", SNick, "');"]; false -> [] end end). export_irc_custom(Server, Output) -> export_common( Server, irc_custom, Output, fun(Host, #irc_custom{us_host = {{U, S}, IRCHost}, data = Data}) -> case lists:suffix(Host, IRCHost) of true -> SJID = ejabberd_odbc:escape( jlib:jid_to_string( jlib:make_jid(U, S, ""))), SIRCHost = ejabberd_odbc:escape(IRCHost), SData = ejabberd_odbc:encode_term(Data), ["delete from irc_custom where jid='", SJID, "' and host='", SIRCHost, "';" "insert into irc_custom(jid, host, data) values (" "'", SJID, "', '", SIRCHost, "', '", SData, "');"]; false -> [] end end). export_privacy(Server, Output) -> case ejabberd_odbc:sql_query( jlib:nameprep(Server), ["select id from privacy_list order by id desc limit 1;"]) of {selected, ["id"], [{I}]} -> put(id, list_to_integer(I)); _ -> put(id, 0) end, export_common( Server, privacy, Output, fun(Host, #privacy{us = {LUser, LServer}, lists = Lists, default = Default}) when LServer == Host -> Username = ejabberd_odbc:escape(LUser), if Default /= none -> SDefault = ejabberd_odbc:escape(Default), ["delete from privacy_default_list where ", "username='", Username, "';", "insert into privacy_default_list(username, name) ", "values ('", Username, "', '", SDefault, "');"]; true -> [] end ++ lists:flatmap( fun({Name, List}) -> SName = ejabberd_odbc:escape(Name), RItems = lists:map( fun mod_privacy_odbc:item_to_raw/1, List), ID = integer_to_list(get_id()), ["delete from privacy_list " "where username='", Username, "' and name='", SName, "';" "insert into privacy_list(username, name, id) " "values ('", Username, "', '", SName, "', '", ID, "');", "delete from privacy_list_data where id='", ID, "';" |[["insert into privacy_list_data(" "id, t, value, action, ord, match_all, match_iq, " "match_message, match_presence_in, " "match_presence_out) values ('", ID, "', '", string:join(Items, "', '"), "');"] || Items <- RItems]] end, Lists); (_Host, _R) -> [] end). export_sr_group(Server, Output) -> export_common( Server, sr_group, Output, fun(Host, #sr_group{group_host = {Group, LServer}, opts = Opts}) when LServer == Host -> SGroup = ejabberd_odbc:escape(Group), SOpts = ejabberd_odbc:encode_term(Opts), ["delete from sr_group where name='", Group, "';" "insert into sr_group(name, opts) values ('", SGroup, "', '", SOpts, "');"]; (_Host, _R) -> [] end). export_sr_user(Server, Output) -> export_common( Server, sr_user, Output, fun(Host, #sr_user{us = {U, S}, group_host = {Group, LServer}}) when LServer == Host -> SGroup = ejabberd_odbc:escape(Group), SJID = ejabberd_odbc:escape( jlib:jid_to_string( jlib:jid_tolower( jlib:make_jid(U, S, "")))), ["delete from sr_user where jid='", SJID, "'and grp='", Group, "';" "insert into sr_user(jid, grp) values ('", SJID, "', '", SGroup, "');"]; (_Host, _R) -> [] end). export_motd(Server, Output) -> export_common( Server, motd, Output, fun(Host, #motd{server = LServer, packet = El}) when LServer == Host -> ["delete from motd where username='';" "insert into motd(username, xml) values ('', '", ejabberd_odbc:escape(xml:element_to_binary(El)), "');"]; (_Host, _R) -> [] end). export_motd_users(Server, Output) -> export_common( Server, motd_users, Output, fun(Host, #motd_users{us = {LUser, LServer}}) when LServer == Host, LUser /= "" -> Username = ejabberd_odbc:escape(LUser), ["delete from motd where username='", Username, "';" "insert into motd(username, xml) values ('", Username, "', '');"]; (_Host, _R) -> [] end). %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- export_common(Server, Table, Output, ConvertFun) -> IO = case Output of odbc -> odbc; _ -> {ok, IODevice} = file:open(Output, [write, raw]), IODevice end, mnesia:transaction( fun() -> mnesia:read_lock_table(Table), LServer = jlib:nameprep(Server), {_N, SQLs} = mnesia:foldl( fun(R, {N, SQLs} = Acc) -> case ConvertFun(LServer, R) of [] -> Acc; SQL -> if N < ?MAX_RECORDS_PER_TRANSACTION - 1 -> {N + 1, [SQL | SQLs]}; true -> %% Execute full SQL transaction output(LServer, IO, ["begin;", lists:reverse([SQL | SQLs]), "commit"]), {0, []} end end end, {0, []}, Table), %% Execute SQL transaction with remaining records output(LServer, IO, ["begin;", lists:reverse(SQLs), "commit"]) end). output(LServer, IO, SQL) -> case IO of odbc -> catch ejabberd_odbc:sql_query(LServer, SQL); _ -> file:write(IO, [SQL, $;, $\n]) end. record_to_string(#roster{usj = {User, _Server, JID}, name = Name, subscription = Subscription, ask = Ask, askmessage = AskMessage}) -> Username = ejabberd_odbc:escape(User), SJID = ejabberd_odbc:escape(jlib:jid_to_string(JID)), Nick = ejabberd_odbc:escape(Name), SSubscription = case Subscription of both -> "B"; to -> "T"; from -> "F"; none -> "N" end, SAsk = case Ask of subscribe -> "S"; unsubscribe -> "U"; both -> "B"; out -> "O"; in -> "I"; none -> "N" end, SAskMessage = case catch ejabberd_odbc:escape( binary_to_list(list_to_binary([AskMessage]))) of {'EXIT', _Reason} -> []; SAM -> SAM end, ["(" "'", Username, "'," "'", SJID, "'," "'", Nick, "'," "'", SSubscription, "'," "'", SAsk, "'," "'", SAskMessage, "'," "'N', '', 'item')"]. groups_to_string(#roster{usj = {User, _Server, JID}, groups = Groups}) -> Username = ejabberd_odbc:escape(User), SJID = ejabberd_odbc:escape(jlib:jid_to_string(JID)), [["(" "'", Username, "'," "'", SJID, "'," "'", ejabberd_odbc:escape(Group), "')"] || Group <- Groups]. get_id() -> ID = get(id), put(id, ID+1), ID+1. ejabberd-2.1.11/src/cyrsasl.erl0000664000000000000000000001221312240230175013170 0ustar %%%---------------------------------------------------------------------- %%% File : cyrsasl.erl %%% Author : Alexey Shchepin %%% Purpose : Cyrus SASL-like library %%% Created : 8 Mar 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(cyrsasl). -author('alexey@process-one.net'). -export([start/0, register_mechanism/3, listmech/1, server_new/7, server_start/3, server_step/2]). -include("ejabberd.hrl"). -record(sasl_mechanism, {mechanism, module, password_type}). -record(sasl_state, {service, myname, realm, get_password, check_password, check_password_digest, mech_mod, mech_state}). -export([behaviour_info/1]). behaviour_info(callbacks) -> [{mech_new, 4}, {mech_step, 2}]; behaviour_info(_Other) -> undefined. start() -> ets:new(sasl_mechanism, [named_table, public, {keypos, #sasl_mechanism.mechanism}]), cyrsasl_plain:start([]), cyrsasl_digest:start([]), cyrsasl_scram:start([]), cyrsasl_anonymous:start([]), ok. register_mechanism(Mechanism, Module, PasswordType) -> ets:insert(sasl_mechanism, #sasl_mechanism{mechanism = Mechanism, module = Module, password_type = PasswordType}). %%% TODO: use callbacks %%-include("ejabberd.hrl"). %%-include("jlib.hrl"). %%check_authzid(_State, Props) -> %% AuthzId = xml:get_attr_s(authzid, Props), %% case jlib:string_to_jid(AuthzId) of %% error -> %% {error, "invalid-authzid"}; %% JID -> %% LUser = jlib:nodeprep(xml:get_attr_s(username, Props)), %% {U, S, R} = jlib:jid_tolower(JID), %% case R of %% "" -> %% {error, "invalid-authzid"}; %% _ -> %% case {LUser, ?MYNAME} of %% {U, S} -> %% ok; %% _ -> %% {error, "invalid-authzid"} %% end %% end %% end. check_credentials(_State, Props) -> User = xml:get_attr_s(username, Props), case jlib:nodeprep(User) of error -> {error, "not-authorized"}; "" -> {error, "not-authorized"}; _LUser -> ok end. listmech(Host) -> Mechs = ets:select(sasl_mechanism, [{#sasl_mechanism{mechanism = '$1', password_type = '$2', _ = '_'}, case catch ejabberd_auth:store_type(Host) of external -> [{'==', '$2', plain}]; scram -> [{'/=', '$2', digest}]; {'EXIT',{undef,[{Module,store_type,[]} | _]}} -> ?WARNING_MSG("~p doesn't implement the function store_type/0", [Module]), []; _Else -> [] end, ['$1']}]), filter_anonymous(Host, Mechs). server_new(Service, ServerFQDN, UserRealm, _SecFlags, GetPassword, CheckPassword, CheckPasswordDigest) -> #sasl_state{service = Service, myname = ServerFQDN, realm = UserRealm, get_password = GetPassword, check_password = CheckPassword, check_password_digest= CheckPasswordDigest}. server_start(State, Mech, ClientIn) -> case lists:member(Mech, listmech(State#sasl_state.myname)) of true -> case ets:lookup(sasl_mechanism, Mech) of [#sasl_mechanism{module = Module}] -> {ok, MechState} = Module:mech_new( State#sasl_state.myname, State#sasl_state.get_password, State#sasl_state.check_password, State#sasl_state.check_password_digest), server_step(State#sasl_state{mech_mod = Module, mech_state = MechState}, ClientIn); _ -> {error, "no-mechanism"} end; false -> {error, "no-mechanism"} end. server_step(State, ClientIn) -> Module = State#sasl_state.mech_mod, MechState = State#sasl_state.mech_state, case Module:mech_step(MechState, ClientIn) of {ok, Props} -> case check_credentials(State, Props) of ok -> {ok, Props}; {error, Error} -> {error, Error} end; {ok, Props, ServerOut} -> case check_credentials(State, Props) of ok -> {ok, Props, ServerOut}; {error, Error} -> {error, Error} end; {continue, ServerOut, NewMechState} -> {continue, ServerOut, State#sasl_state{mech_state = NewMechState}}; {error, Error, Username} -> {error, Error, Username}; {error, Error} -> {error, Error} end. %% Remove the anonymous mechanism from the list if not enabled for the given %% host filter_anonymous(Host, Mechs) -> case ejabberd_auth_anonymous:is_sasl_anonymous_enabled(Host) of true -> Mechs; false -> Mechs -- ["ANONYMOUS"] end. ejabberd-2.1.11/src/mod_announce.erl0000664000000000000000000007503712240230175014172 0ustar %%%---------------------------------------------------------------------- %%% File : mod_announce.erl %%% Author : Alexey Shchepin %%% Purpose : Manage announce messages %%% Created : 11 Aug 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %%% Implements a small subset of XEP-0133: Service Administration %%% Version 1.1 (2005-08-19) -module(mod_announce). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, init/0, stop/1, announce/3, send_motd/1, disco_identity/5, disco_features/5, disco_items/5, send_announcement_to_all/3, announce_commands/4, announce_items/4]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("adhoc.hrl"). -record(motd, {server, packet}). -record(motd_users, {us, dummy = []}). -define(PROCNAME, ejabberd_announce). -define(NS_ADMINL(Sub), ["http:","jabber.org","protocol","admin", Sub]). tokenize(Node) -> string:tokens(Node, "/#"). start(Host, _Opts) -> mnesia:create_table(motd, [{disc_copies, [node()]}, {attributes, record_info(fields, motd)}]), mnesia:create_table(motd_users, [{disc_copies, [node()]}, {attributes, record_info(fields, motd_users)}]), update_tables(), ejabberd_hooks:add(local_send_to_resource_hook, Host, ?MODULE, announce, 50), ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, disco_identity, 50), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50), ejabberd_hooks:add(disco_local_items, Host, ?MODULE, disco_items, 50), ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, announce_items, 50), ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, announce_commands, 50), ejabberd_hooks:add(user_available_hook, Host, ?MODULE, send_motd, 50), register(gen_mod:get_module_proc(Host, ?PROCNAME), proc_lib:spawn(?MODULE, init, [])). init() -> loop(). loop() -> receive {announce_all, From, To, Packet} -> announce_all(From, To, Packet), loop(); {announce_all_hosts_all, From, To, Packet} -> announce_all_hosts_all(From, To, Packet), loop(); {announce_online, From, To, Packet} -> announce_online(From, To, Packet), loop(); {announce_all_hosts_online, From, To, Packet} -> announce_all_hosts_online(From, To, Packet), loop(); {announce_motd, From, To, Packet} -> announce_motd(From, To, Packet), loop(); {announce_all_hosts_motd, From, To, Packet} -> announce_all_hosts_motd(From, To, Packet), loop(); {announce_motd_update, From, To, Packet} -> announce_motd_update(From, To, Packet), loop(); {announce_all_hosts_motd_update, From, To, Packet} -> announce_all_hosts_motd_update(From, To, Packet), loop(); {announce_motd_delete, From, To, Packet} -> announce_motd_delete(From, To, Packet), loop(); {announce_all_hosts_motd_delete, From, To, Packet} -> announce_all_hosts_motd_delete(From, To, Packet), loop(); _ -> loop() end. stop(Host) -> ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, announce_commands, 50), ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, announce_items, 50), ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 50), ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 50), ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 50), ejabberd_hooks:delete(local_send_to_resource_hook, Host, ?MODULE, announce, 50), ejabberd_hooks:delete(user_available_hook, Host, ?MODULE, send_motd, 50), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), exit(whereis(Proc), stop), {wait, Proc}. %% Announcing via messages to a custom resource announce(From, To, Packet) -> case To of #jid{luser = "", lresource = Res} -> {xmlelement, Name, _Attrs, _Els} = Packet, Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME), case {Res, Name} of {"announce/all", "message"} -> Proc ! {announce_all, From, To, Packet}, stop; {"announce/all-hosts/all", "message"} -> Proc ! {announce_all_hosts_all, From, To, Packet}, stop; {"announce/online", "message"} -> Proc ! {announce_online, From, To, Packet}, stop; {"announce/all-hosts/online", "message"} -> Proc ! {announce_all_hosts_online, From, To, Packet}, stop; {"announce/motd", "message"} -> Proc ! {announce_motd, From, To, Packet}, stop; {"announce/all-hosts/motd", "message"} -> Proc ! {announce_all_hosts_motd, From, To, Packet}, stop; {"announce/motd/update", "message"} -> Proc ! {announce_motd_update, From, To, Packet}, stop; {"announce/all-hosts/motd/update", "message"} -> Proc ! {announce_all_hosts_motd_update, From, To, Packet}, stop; {"announce/motd/delete", "message"} -> Proc ! {announce_motd_delete, From, To, Packet}, stop; {"announce/all-hosts/motd/delete", "message"} -> Proc ! {announce_all_hosts_motd_delete, From, To, Packet}, stop; _ -> ok end; _ -> ok end. %%------------------------------------------------------------------------- %% Announcing via ad-hoc commands -define(INFO_COMMAND(Lang, Node), [{xmlelement, "identity", [{"category", "automation"}, {"type", "command-node"}, {"name", get_title(Lang, Node)}], []}]). disco_identity(Acc, _From, _To, Node, Lang) -> LNode = tokenize(Node), case LNode of ?NS_ADMINL("announce") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("announce-allhosts") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("announce-all") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("announce-all-allhosts") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("set-motd") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("set-motd-allhosts") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("edit-motd") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("edit-motd-allhosts") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("delete-motd") -> ?INFO_COMMAND(Lang, Node); ?NS_ADMINL("delete-motd-allhosts") -> ?INFO_COMMAND(Lang, Node); _ -> Acc end. %%------------------------------------------------------------------------- -define(INFO_RESULT(Allow, Feats), case Allow of deny -> {error, ?ERR_FORBIDDEN}; allow -> {result, Feats} end). disco_features(Acc, From, #jid{lserver = LServer} = _To, "announce", _Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none), Access2 = gen_mod:get_module_opt(global, ?MODULE, access, none), case {acl:match_rule(LServer, Access1, From), acl:match_rule(global, Access2, From)} of {deny, deny} -> {error, ?ERR_FORBIDDEN}; _ -> {result, []} end end; disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none), Allow = acl:match_rule(LServer, Access, From), AccessGlobal = gen_mod:get_module_opt(global, ?MODULE, access, none), AllowGlobal = acl:match_rule(global, AccessGlobal, From), case Node of ?NS_ADMIN ++ "#announce" -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMIN ++ "#announce-all" -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMIN ++ "#set-motd" -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMIN ++ "#edit-motd" -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMIN ++ "#delete-motd" -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMIN ++ "#announce-allhosts" -> ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?NS_ADMIN ++ "#announce-all-allhosts" -> ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?NS_ADMIN ++ "#set-motd-allhosts" -> ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?NS_ADMIN ++ "#edit-motd-allhosts" -> ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?NS_ADMIN ++ "#delete-motd-allhosts" -> ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); _ -> Acc end end. %%------------------------------------------------------------------------- -define(NODE_TO_ITEM(Lang, Server, Node), {xmlelement, "item", [{"jid", Server}, {"node", Node}, {"name", get_title(Lang, Node)}], []}). -define(ITEMS_RESULT(Allow, Items), case Allow of deny -> {error, ?ERR_FORBIDDEN}; allow -> {result, Items} end). disco_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, "", Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none), Access2 = gen_mod:get_module_opt(global, ?MODULE, access, none), case {acl:match_rule(LServer, Access1, From), acl:match_rule(global, Access2, From)} of {deny, deny} -> Acc; _ -> Items = case Acc of {result, I} -> I; _ -> [] end, Nodes = [?NODE_TO_ITEM(Lang, Server, "announce")], {result, Items ++ Nodes} end end; disco_items(Acc, From, #jid{lserver = LServer} = To, "announce", Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> announce_items(Acc, From, To, Lang) end; disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none), Allow = acl:match_rule(LServer, Access, From), AccessGlobal = gen_mod:get_module_opt(global, ?MODULE, access, none), AllowGlobal = acl:match_rule(global, AccessGlobal, From), case Node of ?NS_ADMIN ++ "#announce" -> ?ITEMS_RESULT(Allow, []); ?NS_ADMIN ++ "#announce-all" -> ?ITEMS_RESULT(Allow, []); ?NS_ADMIN ++ "#set-motd" -> ?ITEMS_RESULT(Allow, []); ?NS_ADMIN ++ "#edit-motd" -> ?ITEMS_RESULT(Allow, []); ?NS_ADMIN ++ "#delete-motd" -> ?ITEMS_RESULT(Allow, []); ?NS_ADMIN ++ "#announce-allhosts" -> ?ITEMS_RESULT(AllowGlobal, []); ?NS_ADMIN ++ "#announce-all-allhosts" -> ?ITEMS_RESULT(AllowGlobal, []); ?NS_ADMIN ++ "#set-motd-allhosts" -> ?ITEMS_RESULT(AllowGlobal, []); ?NS_ADMIN ++ "#edit-motd-allhosts" -> ?ITEMS_RESULT(AllowGlobal, []); ?NS_ADMIN ++ "#delete-motd-allhosts" -> ?ITEMS_RESULT(AllowGlobal, []); _ -> Acc end end. %%------------------------------------------------------------------------- announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang) -> Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none), Nodes1 = case acl:match_rule(LServer, Access1, From) of allow -> [?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce-all"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#set-motd"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#edit-motd"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#delete-motd")]; deny -> [] end, Access2 = gen_mod:get_module_opt(global, ?MODULE, access, none), Nodes2 = case acl:match_rule(global, Access2, From) of allow -> [?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce-allhosts"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce-all-allhosts"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#set-motd-allhosts"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#edit-motd-allhosts"), ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#delete-motd-allhosts")]; deny -> [] end, case {Nodes1, Nodes2} of {[], []} -> Acc; _ -> Items = case Acc of {result, I} -> I; _ -> [] end, {result, Items ++ Nodes1 ++ Nodes2} end. %%------------------------------------------------------------------------- commands_result(Allow, From, To, Request) -> case Allow of deny -> {error, ?ERR_FORBIDDEN}; allow -> announce_commands(From, To, Request) end. announce_commands(Acc, From, #jid{lserver = LServer} = To, #adhoc_request{ node = Node} = Request) -> LNode = tokenize(Node), F = fun() -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), Allow = acl:match_rule(global, Access, From), commands_result(Allow, From, To, Request) end, R = case LNode of ?NS_ADMINL("announce-allhosts") -> F(); ?NS_ADMINL("announce-all-allhosts") -> F(); ?NS_ADMINL("set-motd-allhosts") -> F(); ?NS_ADMINL("edit-motd-allhosts") -> F(); ?NS_ADMINL("delete-motd-allhosts") -> F(); _ -> Access = gen_mod:get_module_opt(LServer, ?MODULE, access, none), Allow = acl:match_rule(LServer, Access, From), case LNode of ?NS_ADMINL("announce") -> commands_result(Allow, From, To, Request); ?NS_ADMINL("announce-all") -> commands_result(Allow, From, To, Request); ?NS_ADMINL("set-motd") -> commands_result(Allow, From, To, Request); ?NS_ADMINL("edit-motd") -> commands_result(Allow, From, To, Request); ?NS_ADMINL("delete-motd") -> commands_result(Allow, From, To, Request); _ -> unknown end end, case R of unknown -> Acc; _ -> {stop, R} end. %%------------------------------------------------------------------------- announce_commands(From, To, #adhoc_request{lang = Lang, node = Node, action = Action, xdata = XData} = Request) -> %% If the "action" attribute is not present, it is %% understood as "execute". If there was no %% element in the first response (which there isn't in our %% case), "execute" and "complete" are equivalent. ActionIsExecute = lists:member(Action, ["", "execute", "complete"]), if Action == "cancel" -> %% User cancels request adhoc:produce_response(Request, #adhoc_response{status = canceled}); XData == false, ActionIsExecute -> %% User requests form Elements = generate_adhoc_form(Lang, Node, To#jid.lserver), adhoc:produce_response( Request, #adhoc_response{status = executing, elements = [Elements]}); XData /= false, ActionIsExecute -> %% User returns form. case jlib:parse_xdata_submit(XData) of invalid -> {error, ?ERR_BAD_REQUEST}; Fields -> handle_adhoc_form(From, To, Request, Fields) end; true -> {error, ?ERR_BAD_REQUEST} end. -define(VVALUE(Val), {xmlelement, "value", [], [{xmlcdata, Val}]}). -define(TVFIELD(Type, Var, Val), {xmlelement, "field", [{"type", Type}, {"var", Var}], vvaluel(Val)}). -define(HFIELD(), ?TVFIELD("hidden", "FORM_TYPE", ?NS_ADMIN)). vvaluel(Val) -> case Val of "" -> []; _ -> [?VVALUE(Val)] end. generate_adhoc_form(Lang, Node, ServerHost) -> LNode = tokenize(Node), {OldSubject, OldBody} = if (LNode == ?NS_ADMINL("edit-motd")) or (LNode == ?NS_ADMINL("edit-motd-allhosts")) -> get_stored_motd(ServerHost); true -> {[], []} end, {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, get_title(Lang, Node)}]}] ++ if (LNode == ?NS_ADMINL("delete-motd")) or (LNode == ?NS_ADMINL("delete-motd-allhosts")) -> [{xmlelement, "field", [{"var", "confirm"}, {"type", "boolean"}, {"label", translate:translate(Lang, "Really delete message of the day?")}], [{xmlelement, "value", [], [{xmlcdata, "true"}]}]}]; true -> [{xmlelement, "field", [{"var", "subject"}, {"type", "text-single"}, {"label", translate:translate(Lang, "Subject")}], vvaluel(OldSubject)}, {xmlelement, "field", [{"var", "body"}, {"type", "text-multi"}, {"label", translate:translate(Lang, "Message body")}], vvaluel(OldBody)}] end}. join_lines([]) -> []; join_lines(Lines) -> join_lines(Lines, []). join_lines([Line|Lines], Acc) -> join_lines(Lines, ["\n",Line|Acc]); join_lines([], Acc) -> %% Remove last newline lists:flatten(lists:reverse(tl(Acc))). handle_adhoc_form(From, #jid{lserver = LServer} = To, #adhoc_request{lang = Lang, node = Node, sessionid = SessionID}, Fields) -> Confirm = case lists:keysearch("confirm", 1, Fields) of {value, {"confirm", ["true"]}} -> true; {value, {"confirm", ["1"]}} -> true; _ -> false end, Subject = case lists:keysearch("subject", 1, Fields) of {value, {"subject", SubjectLines}} -> %% There really shouldn't be more than one %% subject line, but can we stop them? join_lines(SubjectLines); _ -> [] end, Body = case lists:keysearch("body", 1, Fields) of {value, {"body", BodyLines}} -> join_lines(BodyLines); _ -> [] end, Response = #adhoc_response{lang = Lang, node = Node, sessionid = SessionID, status = completed}, Packet = {xmlelement, "message", [{"type", "normal"}], if Subject /= [] -> [{xmlelement, "subject", [], [{xmlcdata, Subject}]}]; true -> [] end ++ if Body /= [] -> [{xmlelement, "body", [], [{xmlcdata, Body}]}]; true -> [] end}, Proc = gen_mod:get_module_proc(LServer, ?PROCNAME), case {Node, Body} of {?NS_ADMIN ++ "#delete-motd", _} -> if Confirm -> Proc ! {announce_motd_delete, From, To, Packet}, adhoc:produce_response(Response); true -> adhoc:produce_response(Response) end; {?NS_ADMIN ++ "#delete-motd-allhosts", _} -> if Confirm -> Proc ! {announce_all_hosts_motd_delete, From, To, Packet}, adhoc:produce_response(Response); true -> adhoc:produce_response(Response) end; {_, []} -> %% An announce message with no body is definitely an operator error. %% Throw an error and give him/her a chance to send message again. {error, ?ERRT_NOT_ACCEPTABLE( Lang, "No body provided for announce message")}; %% Now send the packet to ?PROCNAME. %% We don't use direct announce_* functions because it %% leads to large delay in response and queries processing {?NS_ADMIN ++ "#announce", _} -> Proc ! {announce_online, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#announce-allhosts", _} -> Proc ! {announce_all_hosts_online, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#announce-all", _} -> Proc ! {announce_all, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#announce-all-allhosts", _} -> Proc ! {announce_all_hosts_all, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#set-motd", _} -> Proc ! {announce_motd, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#set-motd-allhosts", _} -> Proc ! {announce_all_hosts_motd, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#edit-motd", _} -> Proc ! {announce_motd_update, From, To, Packet}, adhoc:produce_response(Response); {?NS_ADMIN ++ "#edit-motd-allhosts", _} -> Proc ! {announce_all_hosts_motd_update, From, To, Packet}, adhoc:produce_response(Response); _ -> %% This can't happen, as we haven't registered any other %% command nodes. {error, ?ERR_INTERNAL_SERVER_ERROR} end. get_title(Lang, "announce") -> translate:translate(Lang, "Announcements"); get_title(Lang, ?NS_ADMIN ++ "#announce-all") -> translate:translate(Lang, "Send announcement to all users"); get_title(Lang, ?NS_ADMIN ++ "#announce-all-allhosts") -> translate:translate(Lang, "Send announcement to all users on all hosts"); get_title(Lang, ?NS_ADMIN ++ "#announce") -> translate:translate(Lang, "Send announcement to all online users"); get_title(Lang, ?NS_ADMIN ++ "#announce-allhosts") -> translate:translate(Lang, "Send announcement to all online users on all hosts"); get_title(Lang, ?NS_ADMIN ++ "#set-motd") -> translate:translate(Lang, "Set message of the day and send to online users"); get_title(Lang, ?NS_ADMIN ++ "#set-motd-allhosts") -> translate:translate(Lang, "Set message of the day on all hosts and send to online users"); get_title(Lang, ?NS_ADMIN ++ "#edit-motd") -> translate:translate(Lang, "Update message of the day (don't send)"); get_title(Lang, ?NS_ADMIN ++ "#edit-motd-allhosts") -> translate:translate(Lang, "Update message of the day on all hosts (don't send)"); get_title(Lang, ?NS_ADMIN ++ "#delete-motd") -> translate:translate(Lang, "Delete message of the day"); get_title(Lang, ?NS_ADMIN ++ "#delete-motd-allhosts") -> translate:translate(Lang, "Delete message of the day on all hosts"). %%------------------------------------------------------------------------- announce_all(From, To, Packet) -> Host = To#jid.lserver, Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), case acl:match_rule(Host, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> Local = jlib:make_jid("", To#jid.server, ""), lists:foreach( fun({User, Server}) -> Dest = jlib:make_jid(User, Server, ""), ejabberd_router:route(Local, Dest, Packet) end, ejabberd_auth:get_vh_registered_users(Host)) end. announce_all_hosts_all(From, To, Packet) -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), case acl:match_rule(global, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> Local = jlib:make_jid("", To#jid.server, ""), lists:foreach( fun({User, Server}) -> Dest = jlib:make_jid(User, Server, ""), ejabberd_router:route(Local, Dest, Packet) end, ejabberd_auth:dirty_get_registered_users()) end. announce_online(From, To, Packet) -> Host = To#jid.lserver, Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), case acl:match_rule(Host, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> announce_online1(ejabberd_sm:get_vh_session_list(Host), To#jid.server, Packet) end. announce_all_hosts_online(From, To, Packet) -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), case acl:match_rule(global, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> announce_online1(ejabberd_sm:dirty_get_sessions_list(), To#jid.server, Packet) end. announce_online1(Sessions, Server, Packet) -> Local = jlib:make_jid("", Server, ""), lists:foreach( fun({U, S, R}) -> Dest = jlib:make_jid(U, S, R), ejabberd_router:route(Local, Dest, Packet) end, Sessions). announce_motd(From, To, Packet) -> Host = To#jid.lserver, Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), case acl:match_rule(Host, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> announce_motd(Host, Packet) end. announce_all_hosts_motd(From, To, Packet) -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), case acl:match_rule(global, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> Hosts = ?MYHOSTS, [announce_motd(Host, Packet) || Host <- Hosts] end. announce_motd(Host, Packet) -> announce_motd_update(Host, Packet), Sessions = ejabberd_sm:get_vh_session_list(Host), announce_online1(Sessions, Host, Packet), F = fun() -> lists:foreach( fun({U, S, _R}) -> mnesia:write(#motd_users{us = {U, S}}) end, Sessions) end, mnesia:transaction(F). announce_motd_update(From, To, Packet) -> Host = To#jid.lserver, Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), case acl:match_rule(Host, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> announce_motd_update(Host, Packet) end. announce_all_hosts_motd_update(From, To, Packet) -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), case acl:match_rule(global, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> Hosts = ?MYHOSTS, [announce_motd_update(Host, Packet) || Host <- Hosts] end. announce_motd_update(LServer, Packet) -> announce_motd_delete(LServer), F = fun() -> mnesia:write(#motd{server = LServer, packet = Packet}) end, mnesia:transaction(F). announce_motd_delete(From, To, Packet) -> Host = To#jid.lserver, Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), case acl:match_rule(Host, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> announce_motd_delete(Host) end. announce_all_hosts_motd_delete(From, To, Packet) -> Access = gen_mod:get_module_opt(global, ?MODULE, access, none), case acl:match_rule(global, Access, From) of deny -> Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), ejabberd_router:route(To, From, Err); allow -> Hosts = ?MYHOSTS, [announce_motd_delete(Host) || Host <- Hosts] end. announce_motd_delete(LServer) -> F = fun() -> mnesia:delete({motd, LServer}), mnesia:write_lock_table(motd_users), Users = mnesia:select( motd_users, [{#motd_users{us = '$1', _ = '_'}, [{'==', {element, 2, '$1'}, LServer}], ['$1']}]), lists:foreach(fun(US) -> mnesia:delete({motd_users, US}) end, Users) end, mnesia:transaction(F). send_motd(#jid{luser = LUser, lserver = LServer} = JID) -> case catch mnesia:dirty_read({motd, LServer}) of [#motd{packet = Packet}] -> US = {LUser, LServer}, case catch mnesia:dirty_read({motd_users, US}) of [#motd_users{}] -> ok; _ -> Local = jlib:make_jid("", LServer, ""), ejabberd_router:route(Local, JID, Packet), F = fun() -> mnesia:write(#motd_users{us = US}) end, mnesia:transaction(F) end; _ -> ok end. get_stored_motd(LServer) -> case catch mnesia:dirty_read({motd, LServer}) of [#motd{packet = Packet}] -> {xml:get_subtag_cdata(Packet, "subject"), xml:get_subtag_cdata(Packet, "body")}; _ -> {"", ""} end. %% This function is similar to others, but doesn't perform any ACL verification send_announcement_to_all(Host, SubjectS, BodyS) -> SubjectEls = if SubjectS /= [] -> [{xmlelement, "subject", [], [{xmlcdata, SubjectS}]}]; true -> [] end, BodyEls = if BodyS /= [] -> [{xmlelement, "body", [], [{xmlcdata, BodyS}]}]; true -> [] end, Packet = {xmlelement, "message", [{"type", "normal"}], SubjectEls ++ BodyEls}, Sessions = ejabberd_sm:dirty_get_sessions_list(), Local = jlib:make_jid("", Host, ""), lists:foreach( fun({U, S, R}) -> Dest = jlib:make_jid(U, S, R), ejabberd_router:route(Local, Dest, Packet) end, Sessions). %%------------------------------------------------------------------------- update_tables() -> update_motd_table(), update_motd_users_table(). update_motd_table() -> Fields = record_info(fields, motd), case mnesia:table_info(motd, attributes) of Fields -> ok; [id, packet] -> ?INFO_MSG("Converting motd table from " "{id, packet} format", []), Host = ?MYNAME, {atomic, ok} = mnesia:create_table( mod_announce_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, motd}, {attributes, record_info(fields, motd)}]), mnesia:transform_table(motd, ignore, Fields), F1 = fun() -> mnesia:write_lock_table(mod_announce_tmp_table), mnesia:foldl( fun(#motd{server = _} = R, _) -> mnesia:dirty_write( mod_announce_tmp_table, R#motd{server = Host}) end, ok, motd) end, mnesia:transaction(F1), mnesia:clear_table(motd), F2 = fun() -> mnesia:write_lock_table(motd), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, mod_announce_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(mod_announce_tmp_table); _ -> ?INFO_MSG("Recreating motd table", []), mnesia:transform_table(motd, ignore, Fields) end. update_motd_users_table() -> Fields = record_info(fields, motd_users), case mnesia:table_info(motd_users, attributes) of Fields -> ok; [luser, dummy] -> ?INFO_MSG("Converting motd_users table from " "{luser, dummy} format", []), Host = ?MYNAME, {atomic, ok} = mnesia:create_table( mod_announce_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, motd_users}, {attributes, record_info(fields, motd_users)}]), mnesia:transform_table(motd_users, ignore, Fields), F1 = fun() -> mnesia:write_lock_table(mod_announce_tmp_table), mnesia:foldl( fun(#motd_users{us = U} = R, _) -> mnesia:dirty_write( mod_announce_tmp_table, R#motd_users{us = {U, Host}}) end, ok, motd_users) end, mnesia:transaction(F1), mnesia:clear_table(motd_users), F2 = fun() -> mnesia:write_lock_table(motd_users), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, mod_announce_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(mod_announce_tmp_table); _ -> ?INFO_MSG("Recreating motd_users table", []), mnesia:transform_table(motd_users, ignore, Fields) end. ejabberd-2.1.11/src/ejabberd_auth.erl0000664000000000000000000002716312240230175014301 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_auth.erl %%% Author : Alexey Shchepin %%% Purpose : Authentification %%% Created : 23 Nov 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %% TODO: Use the functions in ejabberd auth to add and remove users. -module(ejabberd_auth). -author('alexey@process-one.net'). %% External exports -export([start/0, set_password/3, check_password/3, check_password/5, check_password_with_authmodule/3, check_password_with_authmodule/5, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, get_vh_registered_users_number/1, get_vh_registered_users_number/2, get_password/2, get_password_s/2, get_password_with_authmodule/2, is_user_exists/2, is_user_exists_in_other_modules/3, remove_user/2, remove_user/3, plain_password_required/1, store_type/1, entropy/1 ]). -export([auth_modules/1]). -include("ejabberd.hrl"). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start() -> lists:foreach( fun(Host) -> lists:foreach( fun(M) -> M:start(Host) end, auth_modules(Host)) end, ?MYHOSTS). %% This is only executed by ejabberd_c2s for non-SASL auth client plain_password_required(Server) -> lists:any( fun(M) -> M:plain_password_required() end, auth_modules(Server)). store_type(Server) -> lists:foldl( fun(_, external) -> external; (M, scram) -> case M:store_type() of external -> external; _Else -> scram end; (M, plain) -> M:store_type() end, plain, auth_modules(Server)). %% @doc Check if the user and password can login in server. %% @spec (User::string(), Server::string(), Password::string()) -> %% true | false check_password(User, Server, Password) -> case check_password_with_authmodule(User, Server, Password) of {true, _AuthModule} -> true; false -> false end. %% @doc Check if the user and password can login in server. %% @spec (User::string(), Server::string(), Password::string(), %% Digest::string(), DigestGen::function()) -> %% true | false check_password(User, Server, Password, Digest, DigestGen) -> case check_password_with_authmodule(User, Server, Password, Digest, DigestGen) of {true, _AuthModule} -> true; false -> false end. %% @doc Check if the user and password can login in server. %% The user can login if at least an authentication method accepts the user %% and the password. %% The first authentication method that accepts the credentials is returned. %% @spec (User::string(), Server::string(), Password::string()) -> %% {true, AuthModule} | false %% where %% AuthModule = ejabberd_auth_anonymous | ejabberd_auth_external %% | ejabberd_auth_internal | ejabberd_auth_ldap %% | ejabberd_auth_odbc | ejabberd_auth_pam check_password_with_authmodule(User, Server, Password) -> check_password_loop(auth_modules(Server), [User, Server, Password]). check_password_with_authmodule(User, Server, Password, Digest, DigestGen) -> check_password_loop(auth_modules(Server), [User, Server, Password, Digest, DigestGen]). check_password_loop([], _Args) -> false; check_password_loop([AuthModule | AuthModules], Args) -> case apply(AuthModule, check_password, Args) of true -> {true, AuthModule}; false -> check_password_loop(AuthModules, Args) end. %% @spec (User::string(), Server::string(), Password::string()) -> %% ok | {error, ErrorType} %% where ErrorType = empty_password | not_allowed | invalid_jid set_password(_User, _Server, "") -> %% We do not allow empty password {error, empty_password}; set_password(User, Server, Password) -> lists:foldl( fun(M, {error, _}) -> M:set_password(User, Server, Password); (_M, Res) -> Res end, {error, not_allowed}, auth_modules(Server)). %% @spec (User, Server, Password) -> {atomic, ok} | {atomic, exists} | {error, not_allowed} try_register(_User, _Server, "") -> %% We do not allow empty password {error, not_allowed}; try_register(User, Server, Password) -> case is_user_exists(User,Server) of true -> {atomic, exists}; false -> case lists:member(jlib:nameprep(Server), ?MYHOSTS) of true -> Res = lists:foldl( fun(_M, {atomic, ok} = Res) -> Res; (M, _) -> M:try_register(User, Server, Password) end, {error, not_allowed}, auth_modules(Server)), case Res of {atomic, ok} -> ejabberd_hooks:run(register_user, Server, [User, Server]), {atomic, ok}; _ -> Res end; false -> {error, not_allowed} end end. %% Registered users list do not include anonymous users logged dirty_get_registered_users() -> lists:flatmap( fun(M) -> M:dirty_get_registered_users() end, auth_modules()). %% Registered users list do not include anonymous users logged get_vh_registered_users(Server) -> lists:flatmap( fun(M) -> M:get_vh_registered_users(Server) end, auth_modules(Server)). get_vh_registered_users(Server, Opts) -> lists:flatmap( fun(M) -> case erlang:function_exported( M, get_vh_registered_users, 2) of true -> M:get_vh_registered_users(Server, Opts); false -> M:get_vh_registered_users(Server) end end, auth_modules(Server)). get_vh_registered_users_number(Server) -> lists:sum( lists:map( fun(M) -> case erlang:function_exported( M, get_vh_registered_users_number, 1) of true -> M:get_vh_registered_users_number(Server); false -> length(M:get_vh_registered_users(Server)) end end, auth_modules(Server))). get_vh_registered_users_number(Server, Opts) -> lists:sum( lists:map( fun(M) -> case erlang:function_exported( M, get_vh_registered_users_number, 2) of true -> M:get_vh_registered_users_number(Server, Opts); false -> length(M:get_vh_registered_users(Server)) end end, auth_modules(Server))). %% @doc Get the password of the user. %% @spec (User::string(), Server::string()) -> Password::string() get_password(User, Server) -> lists:foldl( fun(M, false) -> M:get_password(User, Server); (_M, Password) -> Password end, false, auth_modules(Server)). get_password_s(User, Server) -> case get_password(User, Server) of false -> ""; Password when is_list(Password) -> Password; _ -> "" end. %% @doc Get the password of the user and the auth module. %% @spec (User::string(), Server::string()) -> %% {Password::string(), AuthModule::atom()} | {false, none} get_password_with_authmodule(User, Server) -> lists:foldl( fun(M, {false, _}) -> {M:get_password(User, Server), M}; (_M, {Password, AuthModule}) -> {Password, AuthModule} end, {false, none}, auth_modules(Server)). %% Returns true if the user exists in the DB or if an anonymous user is logged %% under the given name is_user_exists(User, Server) -> lists:any( fun(M) -> case M:is_user_exists(User, Server) of {error, Error} -> ?ERROR_MSG("The authentication module ~p returned an " "error~nwhen checking user ~p in server ~p~n" "Error message: ~p", [M, User, Server, Error]), false; Else -> Else end end, auth_modules(Server)). %% Check if the user exists in all authentications module except the module %% passed as parameter %% @spec (Module::atom(), User, Server) -> true | false | maybe is_user_exists_in_other_modules(Module, User, Server) -> is_user_exists_in_other_modules_loop( auth_modules(Server)--[Module], User, Server). is_user_exists_in_other_modules_loop([], _User, _Server) -> false; is_user_exists_in_other_modules_loop([AuthModule|AuthModules], User, Server) -> case AuthModule:is_user_exists(User, Server) of true -> true; false -> is_user_exists_in_other_modules_loop(AuthModules, User, Server); {error, Error} -> ?DEBUG("The authentication module ~p returned an error~nwhen " "checking user ~p in server ~p~nError message: ~p", [AuthModule, User, Server, Error]), maybe end. %% @spec (User, Server) -> ok %% @doc Remove user. %% Note: it may return ok even if there was some problem removing the user. remove_user(User, Server) -> lists:foreach( fun(M) -> M:remove_user(User, Server) end, auth_modules(Server)), ejabberd_hooks:run(remove_user, jlib:nameprep(Server), [User, Server]), ok. %% @spec (User, Server, Password) -> ok | not_exists | not_allowed | bad_request | error %% @doc Try to remove user if the provided password is correct. %% The removal is attempted in each auth method provided: %% when one returns 'ok' the loop stops; %% if no method returns 'ok' then it returns the error message indicated by the last method attempted. remove_user(User, Server, Password) -> R = lists:foldl( fun(_M, ok = Res) -> Res; (M, _) -> M:remove_user(User, Server, Password) end, error, auth_modules(Server)), case R of ok -> ejabberd_hooks:run(remove_user, jlib:nameprep(Server), [User, Server]); _ -> none end, R. %% @spec (IOList) -> non_negative_float() %% @doc Calculate informational entropy. entropy(IOList) -> case binary_to_list(iolist_to_binary(IOList)) of "" -> 0.0; S -> Set = lists:foldl( fun(C, [Digit, Printable, LowLetter, HiLetter, Other]) -> if C >= $a, C =< $z -> [Digit, Printable, 26, HiLetter, Other]; C >= $0, C =< $9 -> [9, Printable, LowLetter, HiLetter, Other]; C >= $A, C =< $Z -> [Digit, Printable, LowLetter, 26, Other]; C >= 16#21, C =< 16#7e -> [Digit, 33, LowLetter, HiLetter, Other]; true -> [Digit, Printable, LowLetter, HiLetter, 128] end end, [0, 0, 0, 0, 0], S), length(S) * math:log(lists:sum(Set))/math:log(2) end. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- %% Return the lists of all the auth modules actually used in the %% configuration auth_modules() -> lists:usort( lists:flatmap( fun(Server) -> auth_modules(Server) end, ?MYHOSTS)). %% Return the list of authenticated modules for a given host auth_modules(Server) -> LServer = jlib:nameprep(Server), Method = ejabberd_config:get_local_option({auth_method, LServer}), Methods = if Method == undefined -> []; is_list(Method) -> Method; is_atom(Method) -> [Method] end, [list_to_atom("ejabberd_auth_" ++ atom_to_list(M)) || M <- Methods]. ejabberd-2.1.11/src/ejabberd_router.erl0000664000000000000000000002754212240230175014661 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_router.erl %%% Author : Alexey Shchepin %%% Purpose : Main router %%% Created : 27 Nov 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_router). -author('alexey@process-one.net'). -behaviour(gen_server). %% API -export([route/3, route_error/4, register_route/1, register_route/2, register_routes/1, unregister_route/1, unregister_routes/1, dirty_get_all_routes/0, dirty_get_all_domains/0 ]). -export([start_link/0]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -record(route, {domain, pid, local_hint}). -record(state, {}). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). route(From, To, Packet) -> case catch do_route(From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p~nwhen processing: ~p", [Reason, {From, To, Packet}]); _ -> ok end. %% Route the error packet only if the originating packet is not an error itself. %% RFC3920 9.3.1 route_error(From, To, ErrPacket, OrigPacket) -> {xmlelement, _Name, Attrs, _Els} = OrigPacket, case "error" == xml:get_attr_s("type", Attrs) of false -> route(From, To, ErrPacket); true -> ok end. register_route(Domain) -> register_route(Domain, undefined). register_route(Domain, LocalHint) -> case jlib:nameprep(Domain) of error -> erlang:error({invalid_domain, Domain}); LDomain -> Pid = self(), case get_component_number(LDomain) of undefined -> F = fun() -> mnesia:write(#route{domain = LDomain, pid = Pid, local_hint = LocalHint}) end, mnesia:transaction(F); N -> F = fun() -> case mnesia:wread({route, LDomain}) of [] -> mnesia:write( #route{domain = LDomain, pid = Pid, local_hint = 1}), lists:foreach( fun(I) -> mnesia:write( #route{domain = LDomain, pid = undefined, local_hint = I}) end, lists:seq(2, N)); Rs -> lists:any( fun(#route{pid = undefined, local_hint = I} = R) -> mnesia:write( #route{domain = LDomain, pid = Pid, local_hint = I}), mnesia:delete_object(R), true; (_) -> false end, Rs) end end, mnesia:transaction(F) end end. register_routes(Domains) -> lists:foreach(fun(Domain) -> register_route(Domain) end, Domains). unregister_route(Domain) -> case jlib:nameprep(Domain) of error -> erlang:error({invalid_domain, Domain}); LDomain -> Pid = self(), case get_component_number(LDomain) of undefined -> F = fun() -> case mnesia:match_object( #route{domain = LDomain, pid = Pid, _ = '_'}) of [R] -> mnesia:delete_object(R); _ -> ok end end, mnesia:transaction(F); _ -> F = fun() -> case mnesia:match_object(#route{domain=LDomain, pid = Pid, _ = '_'}) of [R] -> I = R#route.local_hint, mnesia:write( #route{domain = LDomain, pid = undefined, local_hint = I}), mnesia:delete_object(R); _ -> ok end end, mnesia:transaction(F) end end. unregister_routes(Domains) -> lists:foreach(fun(Domain) -> unregister_route(Domain) end, Domains). dirty_get_all_routes() -> lists:usort(mnesia:dirty_all_keys(route)) -- ?MYHOSTS. dirty_get_all_domains() -> lists:usort(mnesia:dirty_all_keys(route)). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([]) -> update_tables(), mnesia:create_table(route, [{ram_copies, [node()]}, {type, bag}, {attributes, record_info(fields, route)}]), mnesia:add_table_copy(route, node(), ram_copies), mnesia:subscribe({table, route, simple}), lists:foreach( fun(Pid) -> erlang:monitor(process, Pid) end, mnesia:dirty_select(route, [{{route, '_', '$1', '_'}, [], ['$1']}])), {ok, #state{}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({route, From, To, Packet}, State) -> case catch do_route(From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p~nwhen processing: ~p", [Reason, {From, To, Packet}]); _ -> ok end, {noreply, State}; handle_info({mnesia_table_event, {write, #route{pid = Pid}, _ActivityId}}, State) -> erlang:monitor(process, Pid), {noreply, State}; handle_info({'DOWN', _Ref, _Type, Pid, _Info}, State) -> F = fun() -> Es = mnesia:select( route, [{#route{pid = Pid, _ = '_'}, [], ['$_']}]), lists:foreach( fun(E) -> if is_integer(E#route.local_hint) -> LDomain = E#route.domain, I = E#route.local_hint, mnesia:write( #route{domain = LDomain, pid = undefined, local_hint = I}), mnesia:delete_object(E); true -> mnesia:delete_object(E) end end, Es) end, mnesia:transaction(F), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- do_route(OrigFrom, OrigTo, OrigPacket) -> ?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n", [OrigFrom, OrigTo, OrigPacket]), case ejabberd_hooks:run_fold(filter_packet, {OrigFrom, OrigTo, OrigPacket}, []) of {From, To, Packet} -> LDstDomain = To#jid.lserver, case mnesia:dirty_read(route, LDstDomain) of [] -> ejabberd_s2s:route(From, To, Packet); [R] -> Pid = R#route.pid, if node(Pid) == node() -> case R#route.local_hint of {apply, Module, Function} -> Module:Function(From, To, Packet); _ -> Pid ! {route, From, To, Packet} end; is_pid(Pid) -> Pid ! {route, From, To, Packet}; true -> drop end; Rs -> Value = case ejabberd_config:get_local_option( {domain_balancing, LDstDomain}) of undefined -> now(); random -> now(); source -> jlib:jid_tolower(From); destination -> jlib:jid_tolower(To); bare_source -> jlib:jid_remove_resource( jlib:jid_tolower(From)); bare_destination -> jlib:jid_remove_resource( jlib:jid_tolower(To)) end, case get_component_number(LDstDomain) of undefined -> case [R || R <- Rs, node(R#route.pid) == node()] of [] -> R = lists:nth(erlang:phash(Value, length(Rs)), Rs), Pid = R#route.pid, if is_pid(Pid) -> Pid ! {route, From, To, Packet}; true -> drop end; LRs -> R = lists:nth(erlang:phash(Value, length(LRs)), LRs), Pid = R#route.pid, case R#route.local_hint of {apply, Module, Function} -> Module:Function(From, To, Packet); _ -> Pid ! {route, From, To, Packet} end end; _ -> SRs = lists:ukeysort(#route.local_hint, Rs), R = lists:nth(erlang:phash(Value, length(SRs)), SRs), Pid = R#route.pid, if is_pid(Pid) -> Pid ! {route, From, To, Packet}; true -> drop end end end; drop -> ok end. get_component_number(LDomain) -> case ejabberd_config:get_local_option( {domain_balancing_component_number, LDomain}) of N when is_integer(N), N > 1 -> N; _ -> undefined end. update_tables() -> case catch mnesia:table_info(route, attributes) of [domain, node, pid] -> mnesia:delete_table(route); [domain, pid] -> mnesia:delete_table(route); [domain, pid, local_hint] -> ok; {'EXIT', _} -> ok end, case lists:member(local_route, mnesia:system_info(tables)) of true -> mnesia:delete_table(local_route); false -> ok end. ejabberd-2.1.11/src/acl.erl0000664000000000000000000001506612240230175012260 0ustar %%%---------------------------------------------------------------------- %%% File : acl.erl %%% Author : Alexey Shchepin %%% Purpose : ACL support %%% Created : 18 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(acl). -author('alexey@process-one.net'). -export([start/0, to_record/3, add/3, add_list/3, match_rule/3, % for debugging only match_acl/3]). -include("ejabberd.hrl"). -record(acl, {aclname, aclspec}). start() -> mnesia:create_table(acl, [{disc_copies, [node()]}, {type, bag}, {attributes, record_info(fields, acl)}]), mnesia:add_table_copy(acl, node(), ram_copies), ok. to_record(Host, ACLName, ACLSpec) -> #acl{aclname = {ACLName, Host}, aclspec = normalize_spec(ACLSpec)}. add(Host, ACLName, ACLSpec) -> F = fun() -> mnesia:write(#acl{aclname = {ACLName, Host}, aclspec = normalize_spec(ACLSpec)}) end, mnesia:transaction(F). add_list(Host, ACLs, Clear) -> F = fun() -> if Clear -> Ks = mnesia:select( acl, [{{acl, {'$1', Host}, '$2'}, [], ['$1']}]), lists:foreach(fun(K) -> mnesia:delete({acl, {K, Host}}) end, Ks); true -> ok end, lists:foreach(fun(ACL) -> case ACL of #acl{aclname = ACLName, aclspec = ACLSpec} -> mnesia:write( #acl{aclname = {ACLName, Host}, aclspec = normalize_spec(ACLSpec)}) end end, ACLs) end, case mnesia:transaction(F) of {atomic, _} -> ok; _ -> false end. normalize(A) -> jlib:nodeprep(A). normalize_spec({A, B}) -> {A, normalize(B)}; normalize_spec({A, B, C}) -> {A, normalize(B), normalize(C)}; normalize_spec(all) -> all; normalize_spec(none) -> none. match_rule(global, Rule, JID) -> case Rule of all -> allow; none -> deny; _ -> case ejabberd_config:get_global_option({access, Rule, global}) of undefined -> deny; GACLs -> match_acls(GACLs, JID, global) end end; match_rule(Host, Rule, JID) -> case Rule of all -> allow; none -> deny; _ -> case ejabberd_config:get_global_option({access, Rule, global}) of undefined -> case ejabberd_config:get_global_option({access, Rule, Host}) of undefined -> deny; ACLs -> match_acls(ACLs, JID, Host) end; GACLs -> case ejabberd_config:get_global_option({access, Rule, Host}) of undefined -> match_acls(GACLs, JID, Host); ACLs -> case lists:reverse(GACLs) of [{allow, all} | Rest] -> match_acls( lists:reverse(Rest) ++ ACLs ++ [{allow, all}], JID, Host); _ -> match_acls(GACLs ++ ACLs, JID, Host) end end end end. match_acls([], _, _Host) -> deny; match_acls([{Access, ACL} | ACLs], JID, Host) -> case match_acl(ACL, JID, Host) of true -> Access; _ -> match_acls(ACLs, JID, Host) end. match_acl(ACL, JID, Host) -> case ACL of all -> true; none -> false; _ -> {User, Server, Resource} = jlib:jid_tolower(JID), lists:any(fun(#acl{aclspec = Spec}) -> case Spec of all -> true; {user, U} -> (U == User) andalso ((Host == Server) orelse ((Host == global) andalso lists:member(Server, ?MYHOSTS))); {user, U, S} -> (U == User) andalso (S == Server); {server, S} -> S == Server; {resource, R} -> R == Resource; {user_regexp, UR} -> ((Host == Server) orelse ((Host == global) andalso lists:member(Server, ?MYHOSTS))) andalso is_regexp_match(User, UR); {shared_group, G} -> Mod = loaded_shared_roster_module(Host), Mod:is_user_in_group({User, Server}, G, Host); {shared_group, G, H} -> Mod = loaded_shared_roster_module(H), Mod:is_user_in_group({User, Server}, G, H); {user_regexp, UR, S} -> (S == Server) andalso is_regexp_match(User, UR); {server_regexp, SR} -> is_regexp_match(Server, SR); {resource_regexp, RR} -> is_regexp_match(Resource, RR); {node_regexp, UR, SR} -> is_regexp_match(Server, SR) andalso is_regexp_match(User, UR); {user_glob, UR} -> ((Host == Server) orelse ((Host == global) andalso lists:member(Server, ?MYHOSTS))) andalso is_glob_match(User, UR); {user_glob, UR, S} -> (S == Server) andalso is_glob_match(User, UR); {server_glob, SR} -> is_glob_match(Server, SR); {resource_glob, RR} -> is_glob_match(Resource, RR); {node_glob, UR, SR} -> is_glob_match(Server, SR) andalso is_glob_match(User, UR); WrongSpec -> ?ERROR_MSG( "Wrong ACL expression: ~p~n" "Check your config file and reload it with the override_acls option enabled", [WrongSpec]), false end end, ets:lookup(acl, {ACL, global}) ++ ets:lookup(acl, {ACL, Host})) end. is_regexp_match(String, RegExp) -> case ejabberd_regexp:run(String, RegExp) of nomatch -> false; match -> true; {error, ErrDesc} -> ?ERROR_MSG( "Wrong regexp ~p in ACL: ~p", [RegExp, ErrDesc]), false end. is_glob_match(String, Glob) -> is_regexp_match(String, ejabberd_regexp:sh_to_awk(Glob)). loaded_shared_roster_module(Host) -> case {gen_mod:is_loaded(Host, mod_shared_roster_odbc), gen_mod:is_loaded(Host, mod_shared_roster_ldap)} of {true, _} -> mod_shared_roster_odbc; {_, true} -> mod_shared_roster_ldap; _ -> mod_shared_roster end. ejabberd-2.1.11/src/ejabberd_receiver.erl0000664000000000000000000003023512240230175015136 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_receiver.erl %%% Author : Alexey Shchepin %%% Purpose : Socket receiver for C2S and S2S connections %%% Created : 10 Nov 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_receiver). -author('alexey@process-one.net'). -behaviour(gen_server). %% API -export([start_link/4, start/3, start/4, change_shaper/2, reset_stream/1, starttls/2, compress/2, become_controller/2, close/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -record(state, {socket, sock_mod, shaper_state, c2s_pid, max_stanza_size, xml_stream_state, timeout}). -define(HIBERNATE_TIMEOUT, 90000). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Socket, SockMod, Shaper, MaxStanzaSize) -> gen_server:start_link( ?MODULE, [Socket, SockMod, Shaper, MaxStanzaSize], []). %%-------------------------------------------------------------------- %% Function: start() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start(Socket, SockMod, Shaper) -> start(Socket, SockMod, Shaper, infinity). start(Socket, SockMod, Shaper, MaxStanzaSize) -> {ok, Pid} = supervisor:start_child( ejabberd_receiver_sup, [Socket, SockMod, Shaper, MaxStanzaSize]), Pid. change_shaper(Pid, Shaper) -> gen_server:cast(Pid, {change_shaper, Shaper}). reset_stream(Pid) -> do_call(Pid, reset_stream). starttls(Pid, TLSSocket) -> do_call(Pid, {starttls, TLSSocket}). compress(Pid, ZlibSocket) -> do_call(Pid, {compress, ZlibSocket}). become_controller(Pid, C2SPid) -> do_call(Pid, {become_controller, C2SPid}). close(Pid) -> gen_server:cast(Pid, close). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([Socket, SockMod, Shaper, MaxStanzaSize]) -> ShaperState = shaper:new(Shaper), Timeout = case SockMod of ssl -> 20; _ -> infinity end, {ok, #state{socket = Socket, sock_mod = SockMod, shaper_state = ShaperState, max_stanza_size = MaxStanzaSize, timeout = Timeout}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call({starttls, TLSSocket}, _From, #state{xml_stream_state = XMLStreamState, c2s_pid = C2SPid, max_stanza_size = MaxStanzaSize} = State) -> close_stream(XMLStreamState), NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize), NewState = State#state{socket = TLSSocket, sock_mod = tls, xml_stream_state = NewXMLStreamState}, case tls:recv_data(TLSSocket, "") of {ok, TLSData} -> {reply, ok, process_data(TLSData, NewState), ?HIBERNATE_TIMEOUT}; {error, _Reason} -> {stop, normal, ok, NewState} end; handle_call({compress, ZlibSocket}, _From, #state{xml_stream_state = XMLStreamState, c2s_pid = C2SPid, max_stanza_size = MaxStanzaSize} = State) -> close_stream(XMLStreamState), NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize), NewState = State#state{socket = ZlibSocket, sock_mod = ejabberd_zlib, xml_stream_state = NewXMLStreamState}, case ejabberd_zlib:recv_data(ZlibSocket, "") of {ok, ZlibData} -> {reply, ok, process_data(ZlibData, NewState), ?HIBERNATE_TIMEOUT}; {error, _Reason} -> {stop, normal, ok, NewState} end; handle_call(reset_stream, _From, #state{xml_stream_state = XMLStreamState, c2s_pid = C2SPid, max_stanza_size = MaxStanzaSize} = State) -> close_stream(XMLStreamState), NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize), Reply = ok, {reply, Reply, State#state{xml_stream_state = NewXMLStreamState}, ?HIBERNATE_TIMEOUT}; handle_call({become_controller, C2SPid}, _From, State) -> XMLStreamState = xml_stream:new(C2SPid, State#state.max_stanza_size), NewState = State#state{c2s_pid = C2SPid, xml_stream_state = XMLStreamState}, activate_socket(NewState), Reply = ok, {reply, Reply, NewState, ?HIBERNATE_TIMEOUT}; handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State, ?HIBERNATE_TIMEOUT}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast({change_shaper, Shaper}, State) -> NewShaperState = shaper:new(Shaper), {noreply, State#state{shaper_state = NewShaperState}, ?HIBERNATE_TIMEOUT}; handle_cast(close, State) -> {stop, normal, State}; handle_cast(_Msg, State) -> {noreply, State, ?HIBERNATE_TIMEOUT}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({Tag, _TCPSocket, Data}, #state{socket = Socket, sock_mod = SockMod} = State) when (Tag == tcp) or (Tag == ssl) or (Tag == ejabberd_xml) -> case SockMod of tls -> case tls:recv_data(Socket, Data) of {ok, TLSData} -> {noreply, process_data(TLSData, State), ?HIBERNATE_TIMEOUT}; {error, _Reason} -> {stop, normal, State} end; ejabberd_zlib -> case ejabberd_zlib:recv_data(Socket, Data) of {ok, ZlibData} -> {noreply, process_data(ZlibData, State), ?HIBERNATE_TIMEOUT}; {error, _Reason} -> {stop, normal, State} end; _ -> {noreply, process_data(Data, State), ?HIBERNATE_TIMEOUT} end; handle_info({Tag, _TCPSocket}, State) when (Tag == tcp_closed) or (Tag == ssl_closed) -> {stop, normal, State}; handle_info({Tag, _TCPSocket, Reason}, State) when (Tag == tcp_error) or (Tag == ssl_error) -> case Reason of timeout -> {noreply, State, ?HIBERNATE_TIMEOUT}; _ -> {stop, normal, State} end; handle_info({timeout, _Ref, activate}, State) -> activate_socket(State), {noreply, State, ?HIBERNATE_TIMEOUT}; handle_info(timeout, State) -> proc_lib:hibernate(gen_server, enter_loop, [?MODULE, [], State]), {noreply, State, ?HIBERNATE_TIMEOUT}; handle_info(_Info, State) -> {noreply, State, ?HIBERNATE_TIMEOUT}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, #state{xml_stream_state = XMLStreamState, c2s_pid = C2SPid} = State) -> close_stream(XMLStreamState), if C2SPid /= undefined -> gen_fsm:send_event(C2SPid, closed); true -> ok end, catch (State#state.sock_mod):close(State#state.socket), ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- activate_socket(#state{socket = Socket, sock_mod = SockMod}) -> PeerName = case SockMod of gen_tcp -> inet:setopts(Socket, [{active, once}]), inet:peername(Socket); _ -> SockMod:setopts(Socket, [{active, once}]), SockMod:peername(Socket) end, case PeerName of {error, _Reason} -> self() ! {tcp_closed, Socket}; {ok, _} -> ok end. %% Data processing for connectors directly generating xmlelement in %% Erlang data structure. %% WARNING: Shaper does not work with Erlang data structure. process_data([], State) -> activate_socket(State), State; process_data([Element|Els], #state{c2s_pid = C2SPid} = State) when element(1, Element) == xmlelement; element(1, Element) == xmlstreamstart; element(1, Element) == xmlstreamelement; element(1, Element) == xmlstreamend -> if C2SPid == undefined -> State; true -> catch gen_fsm:send_event(C2SPid, element_wrapper(Element)), process_data(Els, State) end; %% Data processing for connectors receivind data as string. process_data(Data, #state{xml_stream_state = XMLStreamState, shaper_state = ShaperState, c2s_pid = C2SPid} = State) -> ?DEBUG("Received XML on stream = ~p", [binary_to_list(Data)]), XMLStreamState1 = xml_stream:parse(XMLStreamState, Data), {NewShaperState, Pause} = shaper:update(ShaperState, size(Data)), if C2SPid == undefined -> ok; Pause > 0 -> erlang:start_timer(Pause, self(), activate); true -> activate_socket(State) end, State#state{xml_stream_state = XMLStreamState1, shaper_state = NewShaperState}. %% Element coming from XML parser are wrapped inside xmlstreamelement %% When we receive directly xmlelement tuple (from a socket module %% speaking directly Erlang XML), we wrap it inside the same %% xmlstreamelement coming from the XML parser. element_wrapper(XMLElement) when element(1, XMLElement) == xmlelement -> {xmlstreamelement, XMLElement}; element_wrapper(Element) -> Element. close_stream(undefined) -> ok; close_stream(XMLStreamState) -> xml_stream:close(XMLStreamState). do_call(Pid, Msg) -> case catch gen_server:call(Pid, Msg) of {'EXIT', Why} -> {error, Why}; Res -> Res end. ejabberd-2.1.11/src/mod_private_odbc.erl0000664000000000000000000001011612240230175015010 0ustar %%%---------------------------------------------------------------------- %%% File : mod_private_odbc.erl %%% Author : Alexey Shchepin %%% Purpose : Private storage support %%% Created : 5 Oct 2006 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_private_odbc). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_sm_iq/3, remove_user/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE, ?MODULE, process_sm_iq, IQDisc). stop(Host) -> ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE). process_sm_iq(From, _To, #iq{type = Type, sub_el = SubEl} = IQ) -> #jid{luser = LUser, lserver = LServer} = From, case lists:member(LServer, ?MYHOSTS) of true -> {xmlelement, Name, Attrs, Els} = SubEl, case Type of set -> F = fun() -> lists:foreach( fun(El) -> set_data(LUser, LServer, El) end, Els) end, odbc_queries:sql_transaction(LServer, F), IQ#iq{type = result, sub_el = [{xmlelement, Name, Attrs, []}]}; get -> case catch get_data(LUser, LServer, Els) of {'EXIT', _Reason} -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; Res -> IQ#iq{type = result, sub_el = [{xmlelement, Name, Attrs, Res}]} end end; false -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} end. set_data(LUser, LServer, El) -> case El of {xmlelement, _Name, Attrs, _Els} -> XMLNS = xml:get_attr_s("xmlns", Attrs), case XMLNS of "" -> ignore; _ -> Username = ejabberd_odbc:escape(LUser), LXMLNS = ejabberd_odbc:escape(XMLNS), SData = ejabberd_odbc:escape( xml:element_to_binary(El)), odbc_queries:set_private_data(LServer, Username, LXMLNS, SData) end; _ -> ignore end. get_data(LUser, LServer, Els) -> get_data(LUser, LServer, Els, []). get_data(_LUser, _LServer, [], Res) -> lists:reverse(Res); get_data(LUser, LServer, [El | Els], Res) -> case El of {xmlelement, _Name, Attrs, _} -> XMLNS = xml:get_attr_s("xmlns", Attrs), Username = ejabberd_odbc:escape(LUser), LXMLNS = ejabberd_odbc:escape(XMLNS), case catch odbc_queries:get_private_data(LServer, Username, LXMLNS) of {selected, ["data"], [{SData}]} -> case xml_stream:parse_element(SData) of Data when element(1, Data) == xmlelement -> get_data(LUser, LServer, Els, [Data | Res]) end; %% MREMOND: I wonder when the query could return a vcard ? {selected, ["vcard"], []} -> get_data(LUser, LServer, Els, [El | Res]); _ -> get_data(LUser, LServer, Els,[El | Res]) end; _ -> get_data(LUser, LServer, Els, Res) end. remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), Username = ejabberd_odbc:escape(LUser), odbc_queries:del_user_private_storage(LServer, Username). ejabberd-2.1.11/src/ejabberd_piefxis.erl0000664000000000000000000005447212240230175015012 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_piefxis.erl %%% Author : Pablo Polvorin, Vidal Santiago Martinez %%% Purpose : XEP-0227: Portable Import/Export Format for XMPP-IM Servers %%% Created : 17 Jul 2008 by Pablo Polvorin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %%% Not implemented: %%% - write mod_piefxis with ejabberdctl commands %%% - Export from mod_offline_odbc.erl %%% - Export from mod_private_odbc.erl %%% - XEP-227: 6. Security Considerations %%% - Other schemas of XInclude are not tested, and may not be imported correctly. %%% - If a host has many users, split that host in XML files with 50 users each. %%%% Headers -module(ejabberd_piefxis). -export([import_file/1, export_server/1, export_host/2]). -record(parsing_state, {parser, host, dir}). -include("ejabberd.hrl"). %%-include_lib("exmpp/include/exmpp.hrl"). %%-include_lib("exmpp/include/exmpp_client.hrl"). %% Copied from exmpp header files: -define(NS_ROSTER, "jabber:iq:roster"). -define(NS_VCARD, "vcard-temp"). -record(xmlcdata, { cdata = <<>> }). -record(xmlattr, { ns = undefined, name, value }). -record(xmlel, { ns = undefined, declared_ns = [], name, attrs = [], children = [] }). -record(iq, { kind, type, id, ns, payload, error, lang, iq_ns }). -record(xmlendtag, { ns = undefined, name }). %% Copied from mod_private.erl -record(private_storage, {usns, xml}). %%-define(ERROR_MSG(M,Args),io:format(M,Args)). %%-define(INFO_MSG(M,Args),ok). -define(CHUNK_SIZE,1024*20). %20k -define(BTL, binary_to_list). -define(LTB, list_to_binary). -define(NS_XINCLUDE, 'http://www.w3.org/2001/XInclude'). %%%================================== %%%% Import file import_file(FileName) -> _ = #xmlattr{}, %% this stupid line is only to prevent compilation warning about "recod xmlattr is unused" import_file(FileName, 2). import_file(FileName, RootDepth) -> try_start_exmpp(), Dir = filename:dirname(FileName), {ok, IO} = try_open_file(FileName), Parser = exmpp_xml:start_parser([{max_size,infinity}, {root_depth, RootDepth}, {emit_endtag,true}]), read_chunks(IO, #parsing_state{parser=Parser, dir=Dir}), file:close(IO), exmpp_xml:stop_parser(Parser). try_start_exmpp() -> try exmpp:start() catch error:{already_started, exmpp} -> ok; error:undef -> throw({error, exmpp_not_installed}) end. try_open_file(FileName) -> case file:open(FileName,[read,binary]) of {ok, IO} -> {ok, IO}; {error, enoent} -> throw({error, {file_not_found, FileName}}) end. %%File could be large.. we read it in chunks read_chunks(IO,State) -> case file:read(IO,?CHUNK_SIZE) of {ok,Chunk} -> NewState = process_chunk(Chunk,State), read_chunks(IO,NewState); eof -> ok end. process_chunk(Chunk,S =#parsing_state{parser=Parser}) -> case exmpp_xml:parse(Parser,Chunk) of continue -> S; XMLElements -> process_elements(XMLElements,S) end. %%%================================== %%%% Process Elements process_elements(Elements,State) -> lists:foldl(fun process_element/2,State,Elements). %%%================================== %%%% Process Element process_element(El=#xmlel{name=user, ns=_XMLNS}, State=#parsing_state{host=Host}) -> case add_user(El,Host) of ok -> ok; {error, _Other} -> error end, State; process_element(H=#xmlel{name=host},State) -> State#parsing_state{host=?BTL(exmpp_xml:get_attribute(H, <<"jid">>, none))}; process_element(#xmlel{name='server-data'},State) -> State; process_element(El=#xmlel{name=include, ns=?NS_XINCLUDE}, State=#parsing_state{dir=Dir}) -> case exmpp_xml:get_attribute(El, <<"href">>, none) of none -> ok; HrefB -> Href = binary_to_list(HrefB), %%?INFO_MSG("Parse also this file: ~n~p", [Href]), FileName = filename:join([Dir, Href]), import_file(FileName, 1), Href end, State; process_element(#xmlcdata{cdata = _CData},State) -> State; process_element(#xmlendtag{ns = _NS, name='server-data'},State) -> State; process_element(#xmlendtag{ns = _NS, name=_Name},State) -> State; process_element(El,State) -> io:format("Warning!: unknown element found: ~p ~n",[El]), State. %%%================================== %%%% Add user add_user(El, Domain) -> User = exmpp_xml:get_attribute(El, <<"name">>, none), PasswordFormat = exmpp_xml:get_attribute(El, <<"password-format">>, <<"plaintext">>), Password = exmpp_xml:get_attribute(El, <<"password">>, none), add_user(El, Domain, User, PasswordFormat, Password). %% @spec (El::xmlel(), Domain::string(), User::binary(), Password::binary() | none) %% -> ok | {error, ErrorText::string()} %% @doc Add a new user to the database. %% If user already exists, it will be only updated. add_user(El, Domain, UserBinary, <<"plaintext">>, none) -> User = ?BTL(UserBinary), io:format("Account ~s@~s will not be created, updating it...~n", [User, Domain]), io:format(""), populate_user_with_elements(El, Domain, User), ok; add_user(El, Domain, UserBinary, PasswordFormat, PasswordBinary) -> User = ?BTL(UserBinary), Password2 = prepare_password(PasswordFormat, PasswordBinary, El), case create_user(User,Password2,Domain) of ok -> populate_user_with_elements(El, Domain, User), ok; {atomic, exists} -> io:format("Account ~s@~s already exists, updating it...~n", [User, Domain]), io:format(""), populate_user_with_elements(El, Domain, User), ok; {error, Other} -> ?ERROR_MSG("Error adding user ~s@~s: ~p~n", [User, Domain, Other]), {error, Other} end. prepare_password(<<"plaintext">>, PasswordBinary, _El) -> ?BTL(PasswordBinary); prepare_password(<<"scram">>, none, El) -> ScramEl = exmpp_xml:get_element(El, 'scram-hash'), #scram{storedkey = base64:decode(exmpp_xml:get_attribute( ScramEl, <<"stored-key">>, none)), serverkey = base64:decode(exmpp_xml:get_attribute( ScramEl, <<"server-key">>, none)), salt = base64:decode(exmpp_xml:get_attribute( ScramEl, <<"salt">>, none)), iterationcount = list_to_integer(exmpp_xml:get_attribute_as_list( ScramEl, <<"iteration-count">>, ?SCRAM_DEFAULT_ITERATION_COUNT)) }. populate_user_with_elements(El, Domain, User) -> exmpp_xml:foreach( fun (_,Child) -> populate_user(User,Domain,Child) end, El). %% @spec (User::string(), Password::string(), Domain::string()) %% -> ok | {atomic, exists} | {error, not_allowed} %% @doc Create a new user create_user(User,Password,Domain) -> case ejabberd_auth:try_register(User,Domain,Password) of {atomic,ok} -> ok; {atomic, exists} -> {atomic, exists}; {error, not_allowed} -> {error, not_allowed}; Other -> {error, Other} end. %%%================================== %%%% Populate user %% @spec (User::string(), Domain::string(), El::xml()) %% -> ok | {error, not_found} %% %% @doc Add a new user from a XML file with a roster list. %% %% Example of a file: %% ``` %% %% %% %% %% %% %% Friends %% %% %% %% %% %% ''' populate_user(User,Domain,El=#xmlel{name='query', ns='jabber:iq:roster'}) -> io:format("Trying to add/update roster list...",[]), case loaded_module(Domain,[mod_roster_odbc,mod_roster]) of {ok, M} -> case M:set_items(User, Domain, exmpp_xml:xmlel_to_xmlelement(El)) of {atomic, ok} -> io:format(" DONE.~n",[]), ok; _ -> io:format(" ERROR.~n",[]), ?ERROR_MSG("Error trying to add a new user: ~s ~n", [exmpp_xml:document_to_list(El)]), {error, not_found} end; E -> io:format(" ERROR: ~p~n",[E]), ?ERROR_MSG("No modules loaded [mod_roster, mod_roster_odbc] ~s ~n", [exmpp_xml:document_to_list(El)]), {error, not_found} end; %% @spec User = String with the user name %% Domain = String with a domain name %% El = Sub XML element with vCard tags values %% @ret ok | {error, not_found} %% @doc Read vcards from the XML and send it to the server %% %% Example: %% ``` %% %% %% %% %% %% Admin %% %% %% %% %% ''' populate_user(User,Domain,El=#xmlel{name='vCard', ns='vcard-temp'}) -> io:format("Trying to add/update vCards...",[]), case loaded_module(Domain,[mod_vcard,mod_vcard_odbc]) of {ok, M} -> FullUser = jid_to_old_jid(exmpp_jid:make(User, Domain)), IQ = iq_to_old_iq(#iq{type = set, payload = El}), case M:process_sm_iq(FullUser, FullUser , IQ) of {error,_Err} -> io:format(" ERROR.~n",[]), ?ERROR_MSG("Error processing vcard ~s : ~p ~n", [exmpp_xml:document_to_list(El), _Err]); _ -> io:format(" DONE.~n",[]), ok end; _ -> io:format(" ERROR.~n",[]), ?ERROR_MSG("No modules loaded [mod_vcard, mod_vcard_odbc] ~s ~n", [exmpp_xml:document_to_list(El)]), {error, not_found} end; %% @spec User = String with the user name %% Domain = String with a domain name %% El = Sub XML element with offline messages values %% @ret ok | {error, not_found} %% @doc Read off-line message from the XML and send it to the server populate_user(User,Domain,El=#xmlel{name='offline-messages'}) -> io:format("Trying to add/update offline-messages...",[]), case loaded_module(Domain, [mod_offline, mod_offline_odbc]) of {ok, M} -> ok = exmpp_xml:foreach( fun (_Element, {xmlcdata, _}) -> ok; (_Element, Child) -> From = exmpp_xml:get_attribute(Child, <<"from">>,none), FullFrom = jid_to_old_jid(exmpp_jid:parse(From)), FullUser = jid_to_old_jid(exmpp_jid:make(User, Domain)), OldChild = exmpp_xml:xmlel_to_xmlelement(Child), _R = M:store_packet(FullFrom, FullUser, OldChild) end, El), io:format(" DONE.~n",[]); _ -> io:format(" ERROR.~n",[]), ?ERROR_MSG("No modules loaded [mod_offline, mod_offline_odbc] ~s ~n", [exmpp_xml:document_to_list(El)]), {error, not_found} end; %% @spec User = String with the user name %% Domain = String with a domain name %% El = Sub XML element with private storage values %% @ret ok | {error, not_found} %% @doc Private storage parsing populate_user(User,Domain,El=#xmlel{name='query', ns='jabber:iq:private'}) -> io:format("Trying to add/update private storage...",[]), case loaded_module(Domain,[mod_private_odbc,mod_private]) of {ok, M} -> FullUser = jid_to_old_jid(exmpp_jid:make(User, Domain)), IQ = iq_to_old_iq(#iq{type = set, ns = 'jabber:iq:private', kind = request, iq_ns = 'jabberd:client', payload = El}), case M:process_sm_iq(FullUser, FullUser, IQ ) of {error, _Err} -> io:format(" ERROR.~n",[]), ?ERROR_MSG("Error processing private storage ~s : ~p ~n", [exmpp_xml:document_to_list(El), _Err]); _ -> io:format(" DONE.~n",[]), ok end; _ -> io:format(" ERROR.~n",[]), ?ERROR_MSG("No modules loaded [mod_private, mod_private_odbc] ~s ~n", [exmpp_xml:document_to_list(El)]), {error, not_found} end; populate_user(_User, _Domain, #xmlcdata{cdata = _CData}) -> ok; populate_user(_User, _Domain, _El) -> ok. %%%================================== %%%% Utilities loaded_module(Domain,Options) -> LoadedModules = gen_mod:loaded_modules(Domain), case lists:filter(fun(Module) -> lists:member(Module, LoadedModules) end, Options) of [M|_] -> {ok, M}; [] -> {error,not_found} end. jid_to_old_jid(Jid) -> {jid, to_list(exmpp_jid:node_as_list(Jid)), to_list(exmpp_jid:domain_as_list(Jid)), to_list(exmpp_jid:resource_as_list(Jid)), to_list(exmpp_jid:prep_node_as_list(Jid)), to_list(exmpp_jid:prep_domain_as_list(Jid)), to_list(exmpp_jid:prep_resource_as_list(Jid))}. iq_to_old_iq(#iq{id = ID, type = Type, lang = Lang, ns= NS, payload = El }) -> {iq, to_list(ID), Type, to_list(NS), to_list(Lang), exmpp_xml:xmlel_to_xmlelement(El)}. to_list(L) when is_list(L) -> L; to_list(B) when is_binary(B) -> binary_to_list(B); to_list(undefined) -> ""; to_list(B) when is_atom(B) -> atom_to_list(B). %%%================================== %%%% Export hosts %% @spec (Dir::string(), Hosts::[string()]) -> ok export_hosts(Dir, Hosts) -> try_start_exmpp(), FnT = make_filename_template(), DFn = make_main_basefilename(Dir, FnT), {ok, Fd} = file_open(DFn), print(Fd, make_piefxis_xml_head()), print(Fd, make_piefxis_server_head()), FilesAndHosts = [{make_host_filename(FnT, Host), Host} || Host <- Hosts], [print(Fd, make_xinclude(FnH)) || {FnH, _Host} <- FilesAndHosts], print(Fd, make_piefxis_server_tail()), print(Fd, make_piefxis_xml_tail()), file_close(Fd), [export_host(Dir, FnH, Host) || {FnH, Host} <- FilesAndHosts], ok. %%%================================== %%%% Export server %% @spec (Dir::string()) -> ok export_server(Dir) -> Hosts = ?MYHOSTS, export_hosts(Dir, Hosts). %%%================================== %%%% Export host %% @spec (Dir::string(), Host::string()) -> ok export_host(Dir, Host) -> Hosts = [Host], export_hosts(Dir, Hosts). %% @spec (Dir::string(), Fn::string(), Host::string()) -> ok export_host(Dir, FnH, Host) -> DFn = make_host_basefilename(Dir, FnH), {ok, Fd} = file_open(DFn), print(Fd, make_piefxis_xml_head()), print(Fd, make_piefxis_host_head(Host)), Users = ejabberd_auth:get_vh_registered_users(Host), [export_user(Fd, Username, Host) || {Username, _Host} <- Users], timer:sleep(500), % Delay to ensure ERROR_MSG are displayed in the shell print(Fd, make_piefxis_host_tail()), print(Fd, make_piefxis_xml_tail()), file_close(Fd). %%%================================== %%%% PIEFXIS formatting %% @spec () -> string() make_piefxis_xml_head() -> "". %% @spec () -> string() make_piefxis_xml_tail() -> "". %% @spec () -> string() make_piefxis_server_head() -> "". %% @spec () -> string() make_piefxis_server_tail() -> "". %% @spec (Host::string()) -> string() make_piefxis_host_head(Host) -> NSString = " xmlns='http://www.xmpp.org/extensions/xep-0227.html#ns'" " xmlns:xi='http://www.w3.org/2001/XInclude'", io_lib:format("", [NSString, Host]). %% @spec () -> string() make_piefxis_host_tail() -> "". %% @spec (Fn::string()) -> string() make_xinclude(Fn) -> Base = filename:basename(Fn), io_lib:format("", [Base]). %%%================================== %%%% Export user %% @spec (Fd, Username::string(), Host::string()) -> ok %% @doc Extract user information and print it. export_user(Fd, Username, Host) -> try extract_user(Username, Host) of UserString -> print(Fd, UserString) catch E1:E2 -> ?ERROR_MSG("The account ~s@~s is not exported because a problem " "was found in it:~n~p: ~p", [Username, Host, E1, E2]) end. %% @spec (Username::string(), Host::string()) -> string() extract_user(Username, Host) -> Password = ejabberd_auth:get_password(Username, Host), PasswordStr = build_password_string(Password), UserInfo = [extract_user_info(InfoName, Username, Host) || InfoName <- [roster, offline, private, vcard]], UserInfoString = lists:flatten(UserInfo), io_lib:format("", [Username, PasswordStr, UserInfoString]). build_password_string({StoredKey, ServerKey, Salt, IterationCount}) -> io_lib:format("password-format='scram'>" " ", [base64:encode_to_string(StoredKey), base64:encode_to_string(ServerKey), base64:encode_to_string(Salt), IterationCount]); build_password_string(Password) when is_list(Password) -> io_lib:format("password-format='plaintext' password='~s'>", [Password]). %% @spec (InfoName::atom(), Username::string(), Host::string()) -> string() extract_user_info(roster, Username, Host) -> case loaded_module(Host,[mod_roster_odbc,mod_roster]) of {ok, M} -> From = To = jlib:make_jid(Username, Host, ""), SubelGet = {xmlelement, "query", [{"xmlns",?NS_ROSTER}], []}, %%IQGet = #iq{type=get, xmlns=?NS_ROSTER, payload=SubelGet}, % this is for 3.0.0 version IQGet = {iq, "", get, ?NS_ROSTER, "" , SubelGet}, Res = M:process_local_iq(From, To, IQGet), %%[El] = Res#iq.payload, % this is for 3.0.0 version {iq, _, result, _, _, Els} = Res, case Els of [El] -> exmpp_xml:document_to_list(El); [] -> "" end; _E -> "" end; extract_user_info(offline, Username, Host) -> case loaded_module(Host,[mod_offline,mod_offline_odbc]) of {ok, mod_offline} -> Els = mnesia_pop_offline_messages([], Username, Host), case Els of [] -> ""; Els -> OfEl = {xmlelement, "offline-messages", [], Els}, exmpp_xml:document_to_list(OfEl) end; {ok, mod_offline_odbc} -> ""; _E -> "" end; extract_user_info(private, Username, Host) -> case loaded_module(Host,[mod_private,mod_private_odbc]) of {ok, mod_private} -> get_user_private_mnesia(Username, Host); {ok, mod_private_odbc} -> ""; _E -> "" end; extract_user_info(vcard, Username, Host) -> case loaded_module(Host,[mod_vcard, mod_vcard_odbc, mod_vcard_odbc]) of {ok, M} -> From = To = jlib:make_jid(Username, Host, ""), SubelGet = {xmlelement, "vCard", [{"xmlns",?NS_VCARD}], []}, %%IQGet = #iq{type=get, xmlns=?NS_VCARD, payload=SubelGet}, % this is for 3.0.0 version IQGet = {iq, "", get, ?NS_VCARD, "" , SubelGet}, Res = M:process_sm_iq(From, To, IQGet), %%[El] = Res#iq.payload, % this is for 3.0.0 version {iq, _, result, _, _, Els} = Res, case Els of [El] -> exmpp_xml:document_to_list(El); [] -> "" end; _E -> "" end. %%%================================== %%%% Interface with ejabberd offline storage %% Copied from mod_offline.erl and customized -record(offline_msg, {us, timestamp, expire, from, to, packet}). mnesia_pop_offline_messages(Ls, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, F = fun() -> Rs = mnesia:wread({offline_msg, US}), %%mnesia:delete({offline_msg, US}), Rs end, case mnesia:transaction(F) of {atomic, Rs} -> TS = now(), Ls ++ lists:map( fun(R) -> {xmlelement, Name, Attrs, Els} = R#offline_msg.packet, FromString = jlib:jid_to_string(R#offline_msg.from), Attrs2 = lists:keystore("from", 1, Attrs, {"from", FromString}), Attrs3 = lists:keystore("xmlns", 1, Attrs2, {"xmlns", "jabber:client"}), {xmlelement, Name, Attrs3, Els ++ [jlib:timestamp_to_xml( calendar:now_to_universal_time( R#offline_msg.timestamp))]} end, lists:filter( fun(R) -> case R#offline_msg.expire of never -> true; TimeStamp -> TS < TimeStamp end end, lists:keysort(#offline_msg.timestamp, Rs))); _ -> Ls end. %%%================================== %%%% Interface with ejabberd private storage get_user_private_mnesia(Username, Host) -> ListNsEl = mnesia:dirty_select(private_storage, [{#private_storage{usns={Username, Host, '$1'}, xml = '$2'}, [], ['$$']}]), Els = [exmpp_xml:document_to_list(El) || [_Ns, El] <- ListNsEl], case lists:flatten(Els) of "" -> ""; ElsString -> io_lib:format("~s", [ElsString]) end. %%%================================== %%%% Disk file access %% @spec () -> string() make_filename_template() -> {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:local_time(), lists:flatten( io_lib:format("~4..0w~2..0w~2..0w-~2..0w~2..0w~2..0w", [Year, Month, Day, Hour, Minute, Second])). %% @spec (Dir::string(), FnT::string()) -> string() make_main_basefilename(Dir, FnT) -> Filename2 = filename:flatten([FnT, ".xml"]), filename:join([Dir, Filename2]). %% @spec (FnT::string(), Host::string()) -> FnH::string() %% @doc Make the filename for the host. %% Example: ``("20080804-231550", "jabber.example.org") -> "20080804-231550_jabber_example_org.xml"'' make_host_filename(FnT, Host) -> Host2 = string:join(string:tokens(Host, "."), "_"), filename:flatten([FnT, "_", Host2, ".xml"]). make_host_basefilename(Dir, FnT) -> filename:join([Dir, FnT]). %% @spec (Fn::string()) -> {ok, Fd} file_open(Fn) -> file:open(Fn, [write]). %% @spec (Fd) -> ok file_close(Fd) -> file:close(Fd). %% @spec (Fd, String::string()) -> ok print(Fd, String) -> io:format(Fd, String, []). %%%================================== %%% vim: set filetype=erlang tabstop=8 foldmarker=%%%%,%%%= foldmethod=marker: ejabberd-2.1.11/src/config.sub0000664000000000000000000010242512240230175012771 0ustar #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 # Free Software Foundation, Inc. timestamp='2009-06-11' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tile*) basic_machine=tile-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ejabberd-2.1.11/src/scram.erl0000664000000000000000000000522512240230175012622 0ustar %%%---------------------------------------------------------------------- %%% File : scram.erl %%% Author : Stephen Röttger %%% Purpose : SCRAM (RFC 5802) %%% Created : 7 Aug 2011 by Stephen Röttger %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(scram). -author('stephen.roettger@googlemail.com'). %% External exports -export([salted_password/3, stored_key/1, server_key/1, server_signature/2, client_signature/2, client_key/1, client_key/2 ]). %% ejabberd doesn't implement SASLPREP, so we use the similar RESOURCEPREP instead salted_password(Password, Salt, IterationCount) -> hi(jlib:resourceprep(Password), Salt, IterationCount). client_key(SaltedPassword) -> crypto:sha_mac(SaltedPassword, "Client Key"). stored_key(ClientKey) -> crypto:sha(ClientKey). server_key(SaltedPassword) -> crypto:sha_mac(SaltedPassword, "Server Key"). client_signature(StoredKey, AuthMessage) -> crypto:sha_mac(StoredKey, AuthMessage). client_key(ClientProof, ClientSignature) -> list_to_binary(lists:zipwith(fun(X, Y) -> X bxor Y end, binary_to_list(ClientProof), binary_to_list(ClientSignature))). server_signature(ServerKey, AuthMessage) -> crypto:sha_mac(ServerKey, AuthMessage). hi(Password, Salt, IterationCount) -> U1 = crypto:sha_mac(Password, string:concat(binary_to_list(Salt), [0,0,0,1])), list_to_binary(lists:zipwith(fun(X, Y) -> X bxor Y end, binary_to_list(U1), binary_to_list(hi_round(Password, U1, IterationCount-1)))). hi_round(Password, UPrev, 1) -> crypto:sha_mac(Password, UPrev); hi_round(Password, UPrev, IterationCount) -> U = crypto:sha_mac(Password, UPrev), list_to_binary(lists:zipwith(fun(X, Y) -> X bxor Y end, binary_to_list(U), binary_to_list(hi_round(Password, U, IterationCount-1)))). ejabberd-2.1.11/src/ejabberd_update.erl0000664000000000000000000001656012240230175014621 0ustar %%%------------------------------------------------------------------- %%% File : ejabberd_update.erl %%% Author : Alexey Shchepin %%% Purpose : ejabberd code updater %%% Created : 27 Jan 2006 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(ejabberd_update). -author('alexey@process-one.net'). %% API -export([update/0, update/1, update_info/0]). -include("ejabberd.hrl"). %%==================================================================== %% API %%==================================================================== %% Update all the modified modules update() -> case update_info() of {ok, Dir, _UpdatedBeams, _Script, LowLevelScript, _Check} -> Eval = eval_script( LowLevelScript, [], [{ejabberd, "", filename:join(Dir, "..")}]), ?DEBUG("eval: ~p~n", [Eval]), Eval; {error, Reason} -> {error, Reason} end. %% Update only the specified modules update(ModulesToUpdate) -> case update_info() of {ok, Dir, UpdatedBeamsAll, _Script, _LowLevelScript, _Check} -> UpdatedBeamsNow = [A || A <- UpdatedBeamsAll, B <- ModulesToUpdate, A == B], {_, LowLevelScript, _} = build_script(Dir, UpdatedBeamsNow), Eval = eval_script( LowLevelScript, [], [{ejabberd, "", filename:join(Dir, "..")}]), ?DEBUG("eval: ~p~n", [Eval]), Eval; {error, Reason} -> {error, Reason} end. %% OTP R14B03 and older provided release_handler_1:eval_script/3 %% But OTP R14B04 and newer provide release_handler_1:eval_script/5 %% Dialyzer reports a call to missing function; don't worry. eval_script(Script, Apps, LibDirs) -> case lists:member({eval_script, 5}, release_handler_1:module_info(exports)) of true -> release_handler_1:eval_script(Script, Apps, LibDirs, [], []); false -> release_handler_1:eval_script(Script, Apps, LibDirs) end. %% Get information about the modified modules update_info() -> Dir = filename:dirname(code:which(ejabberd)), case file:list_dir(Dir) of {ok, Files} -> update_info(Dir, Files); {error, Reason} -> {error, Reason} end. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- update_info(Dir, Files) -> Beams = lists:sort(get_beams(Files)), UpdatedBeams = get_updated_beams(Beams), ?DEBUG("beam files: ~p~n", [UpdatedBeams]), {Script, LowLevelScript, Check} = build_script(Dir, UpdatedBeams), {ok, Dir, UpdatedBeams, Script, LowLevelScript, Check}. get_beams(Files) -> [list_to_atom(filename:rootname(FN)) || FN <- Files, lists:suffix(".beam", FN)]. %% Return only the beams that have different version get_updated_beams(Beams) -> lists:filter( fun(Module) -> NewVsn = get_new_version(Module), case code:is_loaded(Module) of {file, _} -> CurVsn = get_current_version(Module), (NewVsn /= CurVsn andalso NewVsn /= unknown_version); false -> false end end, Beams). get_new_version(Module) -> Path = code:which(Module), VersionRes = beam_lib:version(Path), case VersionRes of {ok, {Module, NewVsn}} -> NewVsn; %% If a m1.erl has -module("m2"): _ -> unknown_version end. get_current_version(Module) -> Attrs = Module:module_info(attributes), case lists:keysearch(vsn, 1, Attrs) of {value, {vsn, CurVsn}} -> CurVsn; _ -> unknown_version end. %% @spec(Dir::string(), UpdatedBeams::[atom()]) -> {Script,LowLevelScript,Check} build_script(Dir, UpdatedBeams) -> Script = make_script(UpdatedBeams), LowLevelScript = make_low_level_script(UpdatedBeams, Script), Check = release_handler_1:check_script( LowLevelScript, [{ejabberd, "", filename:join(Dir, "..")}]), case Check of ok -> %% This clause is for OTP R14B03 and older. %% Newer Dialyzer reports a never match pattern; don't worry. ?DEBUG("script: ~p~n", [Script]), ?DEBUG("low level script: ~p~n", [LowLevelScript]), ?DEBUG("check: ~p~n", [Check]); {ok, []} -> ?DEBUG("script: ~p~n", [Script]), ?DEBUG("low level script: ~p~n", [LowLevelScript]), ?DEBUG("check: ~p~n", [Check]); _ -> ?ERROR_MSG("script: ~p~n", [Script]), ?ERROR_MSG("low level script: ~p~n", [LowLevelScript]), ?ERROR_MSG("check: ~p~n", [Check]) end, {Script, LowLevelScript, Check}. %% Copied from Erlang/OTP file: lib/sasl/src/systools.hrl -record(application, {name, %% Name of the application, atom(). type = permanent, %% Application start type, atom(). vsn = "", %% Version of the application, string(). id = "", %% Id of the application, string(). description = "", %% Description of application, string(). modules = [], %% [Module | {Module,Vsn}] of modules %% incorporated in the application, %% Module = atom(), Vsn = string(). uses = [], %% [Application] list of applications required %% by the application, Application = atom(). includes = [], %% [Application] list of applications included %% by the application, Application = atom(). regs = [], %% [RegNames] a list of registered process %% names used by the application, RegNames = %% atom(). env = [], %% [{Key,Value}] environment variable of %% application, Key = Value = term(). maxT = infinity, %% Max time an application may exist, %% integer() | infinity. maxP = infinity, %% Max number of processes in an application, %% integer() | infinity. mod = [], %% [] | {Mod, StartArgs}, Mod= atom(), %% StartArgs = list(). start_phases = [], %% [] | {Phase, PhaseArgs}, Phase = atom(), %% PhaseArgs = list(). dir = "" %% The directory where the .app file was %% found (internal use). }). make_script(UpdatedBeams) -> lists:map( fun(Module) -> {ok, {Module, [{attributes, NewAttrs}]}} = beam_lib:chunks(code:which(Module), [attributes]), CurAttrs = Module:module_info(attributes), case lists:keysearch(update_info, 1, NewAttrs) of {value, {_, [{update, _}]}} -> case lists:keysearch(update_info, 1, CurAttrs) of {value, {_, [{update, Extra}]}} -> {update, Module, {advanced, Extra}}; false -> {update, Module, {advanced, 0}} end; false -> {load_module, Module} end end, UpdatedBeams). make_low_level_script(UpdatedBeams, Script) -> EJDApp = #application{name = ejabberd, modules = UpdatedBeams}, {ok, LowLevelScript} = systools_rc:translate_scripts([Script], [EJDApp], [EJDApp]), LowLevelScript. ejabberd-2.1.11/src/idna.erl0000664000000000000000000001243212240230175012426 0ustar %%%---------------------------------------------------------------------- %%% File : idna.erl %%% Author : Alexey Shchepin %%% Purpose : Support for IDNA (RFC3490) %%% Created : 10 Apr 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(idna). -author('alexey@process-one.net'). %%-compile(export_all). -export([domain_utf8_to_ascii/1, domain_ucs2_to_ascii/1]). domain_utf8_to_ascii(Domain) -> domain_ucs2_to_ascii(utf8_to_ucs2(Domain)). utf8_to_ucs2(S) -> utf8_to_ucs2(S, ""). utf8_to_ucs2([], R) -> lists:reverse(R); utf8_to_ucs2([C | S], R) when C < 16#80 -> utf8_to_ucs2(S, [C | R]); utf8_to_ucs2([C1, C2 | S], R) when C1 < 16#E0 -> utf8_to_ucs2(S, [((C1 band 16#1F) bsl 6) bor (C2 band 16#3F) | R]); utf8_to_ucs2([C1, C2, C3 | S], R) when C1 < 16#F0 -> utf8_to_ucs2(S, [((C1 band 16#0F) bsl 12) bor ((C2 band 16#3F) bsl 6) bor (C3 band 16#3F) | R]). domain_ucs2_to_ascii(Domain) -> case catch domain_ucs2_to_ascii1(Domain) of {'EXIT', _Reason} -> false; Res -> Res end. domain_ucs2_to_ascii1(Domain) -> Parts = string:tokens(Domain, [16#002E, 16#3002, 16#FF0E, 16#FF61]), ASCIIParts = lists:map(fun(P) -> to_ascii(P) end, Parts), string:strip(lists:flatmap(fun(P) -> [$. | P] end, ASCIIParts), left, $.). %% Domain names are already nameprep'ed in ejabberd, so we skiping this step to_ascii(Name) -> false = lists:any( fun(C) when ( 0 =< C) and (C =< 16#2C) or (16#2E =< C) and (C =< 16#2F) or (16#3A =< C) and (C =< 16#40) or (16#5B =< C) and (C =< 16#60) or (16#7B =< C) and (C =< 16#7F) -> true; (_) -> false end, Name), case Name of [H | _] when H /= $- -> true = lists:last(Name) /= $- end, ASCIIName = case lists:any(fun(C) -> C > 16#7F end, Name) of true -> true = case Name of "xn--" ++ _ -> false; _ -> true end, "xn--" ++ punycode_encode(Name); false -> Name end, L = length(ASCIIName), true = (1 =< L) and (L =< 63), ASCIIName. %%% PUNYCODE (RFC3492) -define(BASE, 36). -define(TMIN, 1). -define(TMAX, 26). -define(SKEW, 38). -define(DAMP, 700). -define(INITIAL_BIAS, 72). -define(INITIAL_N, 128). punycode_encode(Input) -> N = ?INITIAL_N, Delta = 0, Bias = ?INITIAL_BIAS, Basic = lists:filter(fun(C) -> C =< 16#7f end, Input), NonBasic = lists:filter(fun(C) -> C > 16#7f end, Input), L = length(Input), B = length(Basic), SNonBasic = lists:usort(NonBasic), Output1 = if B > 0 -> Basic ++ "-"; true -> "" end, Output2 = punycode_encode1(Input, SNonBasic, B, B, L, N, Delta, Bias, ""), Output1 ++ Output2. punycode_encode1(Input, [M | SNonBasic], B, H, L, N, Delta, Bias, Out) when H < L -> Delta1 = Delta + (M - N) * (H + 1), % let n = m {NewDelta, NewBias, NewH, NewOut} = lists:foldl( fun(C, {ADelta, ABias, AH, AOut}) -> if C < M -> {ADelta + 1, ABias, AH, AOut}; C == M -> NewOut = punycode_encode_delta(ADelta, ABias, AOut), NewBias = adapt(ADelta, H + 1, H == B), {0, NewBias, AH + 1, NewOut}; true -> {ADelta, ABias, AH, AOut} end end, {Delta1, Bias, H, Out}, Input), punycode_encode1( Input, SNonBasic, B, NewH, L, M + 1, NewDelta + 1, NewBias, NewOut); punycode_encode1(_Input, _SNonBasic, _B, _H, _L, _N, _Delta, _Bias, Out) -> lists:reverse(Out). punycode_encode_delta(Delta, Bias, Out) -> punycode_encode_delta(Delta, Bias, Out, ?BASE). punycode_encode_delta(Delta, Bias, Out, K) -> T = if K =< Bias -> ?TMIN; K >= Bias + ?TMAX -> ?TMAX; true -> K - Bias end, if Delta < T -> [codepoint(Delta) | Out]; true -> C = T + ((Delta - T) rem (?BASE - T)), punycode_encode_delta((Delta - T) div (?BASE - T), Bias, [codepoint(C) | Out], K + ?BASE) end. adapt(Delta, NumPoints, FirstTime) -> Delta1 = if FirstTime -> Delta div ?DAMP; true -> Delta div 2 end, Delta2 = Delta1 + (Delta1 div NumPoints), adapt1(Delta2, 0). adapt1(Delta, K) -> if Delta > ((?BASE - ?TMIN) * ?TMAX) div 2 -> adapt1(Delta div (?BASE - ?TMIN), K + ?BASE); true -> K + (((?BASE - ?TMIN + 1) * Delta) div (Delta + ?SKEW)) end. codepoint(C) -> if (0 =< C) and (C =< 25) -> C + 97; (26 =< C) and (C =< 35) -> C + 22 end. ejabberd-2.1.11/src/web/0000775000000000000000000000000012240452476011574 5ustar ejabberd-2.1.11/src/web/ejabberd_web.erl0000664000000000000000000000541512240230175014666 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_web.erl %%% Author : Alexey Shchepin %%% Purpose : %%% Created : 28 Feb 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_web). -author('alexey@process-one.net'). %% External exports -export([make_xhtml/1, make_xhtml/2, error/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("ejabberd_http.hrl"). %% XXX bard: there are variants of make_xhtml in ejabberd_http and %% ejabberd_web_admin. It might be a good idea to centralize it here %% and also create an ejabberd_web.hrl file holding the macros, so %% that third parties can use ejabberd_web as an "utility" library. make_xhtml(Els) -> make_xhtml([], Els). make_xhtml(HeadEls, Els) -> {xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"}, {"xml:lang", "en"}, {"lang", "en"}], [{xmlelement, "head", [], [{xmlelement, "meta", [{"http-equiv", "Content-Type"}, {"content", "text/html; charset=utf-8"}], []} | HeadEls]}, {xmlelement, "body", [], Els} ]}. -define(X(Name), {xmlelement, Name, [], []}). -define(XA(Name, Attrs), {xmlelement, Name, Attrs, []}). -define(XE(Name, Els), {xmlelement, Name, [], Els}). -define(XAE(Name, Attrs, Els), {xmlelement, Name, Attrs, Els}). -define(C(Text), {xmlcdata, Text}). -define(XC(Name, Text), ?XE(Name, [?C(Text)])). -define(XAC(Name, Attrs, Text), ?XAE(Name, Attrs, [?C(Text)])). -define(LI(Els), ?XE("li", Els)). -define(A(URL, Els), ?XAE("a", [{"href", URL}], Els)). -define(AC(URL, Text), ?A(URL, [?C(Text)])). -define(P, ?X("p")). -define(BR, ?X("br")). -define(INPUT(Type, Name, Value), ?XA("input", [{"type", Type}, {"name", Name}, {"value", Value}])). error(not_found) -> {404, [], make_xhtml([?XC("h1", "404 Not Found")])}; error(not_allowed) -> {401, [], make_xhtml([?XC("h1", "401 Unauthorized")])}. ejabberd-2.1.11/src/web/Makefile.win320000664000000000000000000000202612240230175014163 0ustar include ..\Makefile.inc EFLAGS = -I .. -pz .. OUTDIR = .. BEAMS = ..\ejabberd_http.beam ..\ejabberd_http_bind.beam ..\ejabberd_http_poll.beam ..\ejabberd_web.beam ..\ejabberd_web_admin.beam ..\mod_http_bind.beam ..\mod_http_fileserver.beam ALL : $(BEAMS) CLEAN : -@erase $(BEAMS) $(OUTDIR)\ejabberd_http.beam : ejabberd_http.erl erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_http.erl $(OUTDIR)\ejabberd_web.beam : ejabberd_web.erl erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_web.erl $(OUTDIR)\ejabberd_web_admin.beam : ejabberd_web_admin.erl erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_web_admin.erl $(OUTDIR)\ejabberd_http_bind.beam : ejabberd_http_bind.erl erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_http_bind.erl $(OUTDIR)\ejabberd_http_poll.beam : ejabberd_http_poll.erl erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_http_poll.erl $(OUTDIR)\mod_http_bind.beam : mod_http_bind.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_http_bind.erl $(OUTDIR)\mod_http_fileserver.beam : mod_http_fileserver.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_http_fileserver.erl ejabberd-2.1.11/src/web/ejabberd_http.hrl0000664000000000000000000000217512240230175015073 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -record(request, {method, path, q = [], us, auth, lang = "", data = "", ip, host, % string() port, % integer() tp, % transfer protocol = http | https headers }). ejabberd-2.1.11/src/web/mod_http_fileserver.erl0000664000000000000000000004251312240230175016337 0ustar %%%------------------------------------------------------------------- %%% File : mod_http_fileserver.erl %%% Author : Massimiliano Mirra %%% Purpose : Simple file server plugin for embedded ejabberd web server %%% Created : %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_http_fileserver). -author('mmirra@process-one.net'). -behaviour(gen_mod). -behaviour(gen_server). %% gen_mod callbacks -export([start/2, stop/1]). %% API -export([start_link/2]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). %% request_handlers callbacks -export([process/2]). %% ejabberd_hooks callbacks -export([reopen_log/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include_lib("kernel/include/file.hrl"). %%-include("ejabberd_http.hrl"). %% TODO: When ejabberd-modules SVN gets the new ejabberd_http.hrl, delete this code: -record(request, {method, path, q = [], us, auth, lang = "", data = "", ip, host, % string() port, % integer() tp, % transfer protocol = http | https headers }). -ifdef(SSL40). -define(STRING2LOWER, string). -else. -ifdef(SSL39). -define(STRING2LOWER, string). -else. -define(STRING2LOWER, httpd_util). -endif. -endif. -record(state, {host, docroot, accesslog, accesslogfd, directory_indices, custom_headers, default_content_type, content_types = []}). -define(PROCNAME, ejabberd_mod_http_fileserver). %% Response is {DataSize, Code, [{HeaderKey, HeaderValue}], Data} -define(HTTP_ERR_FILE_NOT_FOUND, {-1, 404, [], "Not found"}). -define(HTTP_ERR_FORBIDDEN, {-1, 403, [], "Forbidden"}). -define(DEFAULT_CONTENT_TYPE, "application/octet-stream"). -define(DEFAULT_CONTENT_TYPES, [{".css", "text/css"}, {".gif", "image/gif"}, {".html", "text/html"}, {".jar", "application/java-archive"}, {".jpeg", "image/jpeg"}, {".jpg", "image/jpeg"}, {".js", "text/javascript"}, {".png", "image/png"}, {".svg", "image/svg+xml"}, {".txt", "text/plain"}, {".xml", "application/xml"}, {".xpi", "application/x-xpinstall"}, {".xul", "application/vnd.mozilla.xul+xml"}]). -compile(export_all). %%==================================================================== %% gen_mod callbacks %%==================================================================== start(Host, Opts) -> Proc = get_proc_name(Host), ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, transient, % if process crashes abruptly, it gets restarted 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> Proc = get_proc_name(Host), gen_server:call(Proc, stop), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Host, Opts) -> Proc = get_proc_name(Host), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([Host, Opts]) -> try initialize(Host, Opts) of {DocRoot, AccessLog, AccessLogFD, DirectoryIndices, CustomHeaders, DefaultContentType, ContentTypes} -> {ok, #state{host = Host, accesslog = AccessLog, accesslogfd = AccessLogFD, docroot = DocRoot, directory_indices = DirectoryIndices, custom_headers = CustomHeaders, default_content_type = DefaultContentType, content_types = ContentTypes}} catch throw:Reason -> {stop, Reason} end. initialize(Host, Opts) -> DocRoot = gen_mod:get_opt(docroot, Opts, undefined), check_docroot_defined(DocRoot, Host), DRInfo = check_docroot_exists(DocRoot), check_docroot_is_dir(DRInfo, DocRoot), check_docroot_is_readable(DRInfo, DocRoot), AccessLog = gen_mod:get_opt(accesslog, Opts, undefined), AccessLogFD = try_open_log(AccessLog, Host), DirectoryIndices = gen_mod:get_opt(directory_indices, Opts, []), CustomHeaders = gen_mod:get_opt(custom_headers, Opts, []), DefaultContentType = gen_mod:get_opt(default_content_type, Opts, ?DEFAULT_CONTENT_TYPE), ContentTypes = build_list_content_types(gen_mod:get_opt(content_types, Opts, []), ?DEFAULT_CONTENT_TYPES), ?INFO_MSG("initialize: ~n ~p", [ContentTypes]),%+++ {DocRoot, AccessLog, AccessLogFD, DirectoryIndices, CustomHeaders, DefaultContentType, ContentTypes}. %% @spec (AdminCTs::[CT], Default::[CT]) -> [CT] %% where CT = {Extension::string(), Value} %% Value = string() | undefined %% @doc Return a unified list without duplicates. %% Elements of AdminCTs have more priority. %% If a CT is declared as 'undefined', then it is not included in the result. build_list_content_types(AdminCTsUnsorted, DefaultCTsUnsorted) -> AdminCTs = lists:ukeysort(1, AdminCTsUnsorted), DefaultCTs = lists:ukeysort(1, DefaultCTsUnsorted), CTsUnfiltered = lists:ukeymerge(1, AdminCTs, DefaultCTs), [{Extension, Value} || {Extension, Value} <- CTsUnfiltered, Value /= undefined]. check_docroot_defined(DocRoot, Host) -> case DocRoot of undefined -> throw({undefined_docroot_option, Host}); _ -> ok end. check_docroot_exists(DocRoot) -> case file:read_file_info(DocRoot) of {error, Reason} -> throw({error_access_docroot, DocRoot, Reason}); {ok, FI} -> FI end. check_docroot_is_dir(DRInfo, DocRoot) -> case DRInfo#file_info.type of directory -> ok; _ -> throw({docroot_not_directory, DocRoot}) end. check_docroot_is_readable(DRInfo, DocRoot) -> case DRInfo#file_info.access of read -> ok; read_write -> ok; _ -> throw({docroot_not_readable, DocRoot}) end. try_open_log(undefined, _Host) -> undefined; try_open_log(FN, Host) -> FD = try open_log(FN) of FD1 -> FD1 catch throw:{cannot_open_accesslog, FN, Reason} -> ?ERROR_MSG("Cannot open access log file: ~p~nReason: ~p", [FN, Reason]), undefined end, ejabberd_hooks:add(reopen_log_hook, Host, ?MODULE, reopen_log, 50), FD. %%-------------------------------------------------------------------- %% Function: handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call({serve, LocalPath}, _From, State) -> Reply = serve(LocalPath, State#state.docroot, State#state.directory_indices, State#state.custom_headers, State#state.default_content_type, State#state.content_types), {reply, Reply, State}; handle_call(_Request, _From, State) -> {reply, ok, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast({add_to_log, FileSize, Code, Request}, State) -> add_to_log(State#state.accesslogfd, FileSize, Code, Request), {noreply, State}; handle_cast(reopen_log, State) -> FD2 = reopen_log(State#state.accesslog, State#state.accesslogfd), {noreply, State#state{accesslogfd = FD2}}; handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, State) -> close_log(State#state.accesslogfd), ejabberd_hooks:delete(reopen_log_hook, State#state.host, ?MODULE, reopen_log, 50), ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%==================================================================== %% request_handlers callbacks %%==================================================================== %% @spec (LocalPath, Request) -> {HTTPCode::integer(), [Header], Page::string()} %% @doc Handle an HTTP request. %% LocalPath is the part of the requested URL path that is "local to the module". %% Returns the page to be sent back to the client and/or HTTP status code. process(LocalPath, Request) -> ?DEBUG("Requested ~p", [LocalPath]), try gen_server:call(get_proc_name(Request#request.host), {serve, LocalPath}) of {FileSize, Code, Headers, Contents} -> add_to_log(FileSize, Code, Request), {Code, Headers, Contents} catch exit:{noproc, _} -> ?ERROR_MSG("Received an HTTP request with Host ~p, but couldn't find the related " "ejabberd virtual host", [Request#request.host]), ejabberd_web:error(not_found) end. serve(LocalPath, DocRoot, DirectoryIndices, CustomHeaders, DefaultContentType, ContentTypes) -> FileName = filename:join(filename:split(DocRoot) ++ LocalPath), case file:read_file_info(FileName) of {error, enoent} -> ?HTTP_ERR_FILE_NOT_FOUND; {error, eacces} -> ?HTTP_ERR_FORBIDDEN; {ok, #file_info{type = directory}} -> serve_index(FileName, DirectoryIndices, CustomHeaders, DefaultContentType, ContentTypes); {ok, FileInfo} -> serve_file(FileInfo, FileName, CustomHeaders, DefaultContentType, ContentTypes) end. %% Troll through the directory indices attempting to find one which %% works, if none can be found, return a 404. serve_index(_FileName, [], _CH, _DefaultContentType, _ContentTypes) -> ?HTTP_ERR_FILE_NOT_FOUND; serve_index(FileName, [Index | T], CH, DefaultContentType, ContentTypes) -> IndexFileName = filename:join([FileName] ++ [Index]), case file:read_file_info(IndexFileName) of {error, _Error} -> serve_index(FileName, T, CH, DefaultContentType, ContentTypes); {ok, #file_info{type = directory}} -> serve_index(FileName, T, CH, DefaultContentType, ContentTypes); {ok, FileInfo} -> serve_file(FileInfo, IndexFileName, CH, DefaultContentType, ContentTypes) end. %% Assume the file exists if we got this far and attempt to read it in %% and serve it up. serve_file(FileInfo, FileName, CustomHeaders, DefaultContentType, ContentTypes) -> ?DEBUG("Delivering: ~s", [FileName]), {ok, FileContents} = file:read_file(FileName), ContentType = content_type(FileName, DefaultContentType, ContentTypes), {FileInfo#file_info.size, 200, [{"Server", "ejabberd"}, {"Last-Modified", last_modified(FileInfo)}, {"Content-Type", ContentType} | CustomHeaders], FileContents}. %%---------------------------------------------------------------------- %% Log file %%---------------------------------------------------------------------- open_log(FN) -> case file:open(FN, [append]) of {ok, FD} -> FD; {error, Reason} -> throw({cannot_open_accesslog, FN, Reason}) end. close_log(FD) -> file:close(FD). reopen_log(undefined, undefined) -> ok; reopen_log(FN, FD) -> close_log(FD), open_log(FN). reopen_log(Host) -> gen_server:cast(get_proc_name(Host), reopen_log). add_to_log(FileSize, Code, Request) -> gen_server:cast(get_proc_name(Request#request.host), {add_to_log, FileSize, Code, Request}). add_to_log(undefined, _FileSize, _Code, _Request) -> ok; add_to_log(File, FileSize, Code, Request) -> {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:local_time(), IP = ip_to_string(element(1, Request#request.ip)), Path = join(Request#request.path, "/"), Query = case join(lists:map(fun(E) -> lists:concat([element(1, E), "=", element(2, E)]) end, Request#request.q), "&") of [] -> ""; String -> [$? | String] end, UserAgent = find_header('User-Agent', Request#request.headers, "-"), Referer = find_header('Referer', Request#request.headers, "-"), %% Pseudo Combined Apache log format: %% 127.0.0.1 - - [28/Mar/2007:18:41:55 +0200] "GET / HTTP/1.1" 302 303 "-" "tsung" %% TODO some fields are harcoded/missing: %% The date/time integers should have always 2 digits. For example day "7" should be "07" %% Month should be 3*letter, not integer 1..12 %% Missing time zone = (`+' | `-') 4*digit %% Missing protocol version: HTTP/1.1 %% For reference: http://httpd.apache.org/docs/2.2/logs.html io:format(File, "~s - - [~p/~p/~p:~p:~p:~p] \"~s /~s~s\" ~p ~p ~p ~p~n", [IP, Day, Month, Year, Hour, Minute, Second, Request#request.method, Path, Query, Code, FileSize, Referer, UserAgent]). find_header(Header, Headers, Default) -> case lists:keysearch(Header, 1, Headers) of {value, {_, Value}} -> Value; false -> Default end. %%---------------------------------------------------------------------- %% Utilities %%---------------------------------------------------------------------- get_proc_name(Host) -> gen_mod:get_module_proc(Host, ?PROCNAME). join([], _) -> ""; join([E], _) -> E; join([H | T], Separator) -> lists:foldl(fun(E, Acc) -> lists:concat([Acc, Separator, E]) end, H, T). content_type(Filename, DefaultContentType, ContentTypes) -> Extension = ?STRING2LOWER:to_lower(filename:extension(Filename)), case lists:keysearch(Extension, 1, ContentTypes) of {value, {_, ContentType}} -> ContentType; false -> DefaultContentType end. last_modified(FileInfo) -> Then = FileInfo#file_info.mtime, httpd_util:rfc1123_date(Then). %% Convert IP address tuple to string representation. Accepts either %% IPv4 or IPv6 address tuples. ip_to_string(Address) when size(Address) == 4 -> join(tuple_to_list(Address), "."); ip_to_string(Address) when size(Address) == 8 -> Parts = lists:map(fun (Int) -> io_lib:format("~.16B", [Int]) end, tuple_to_list(Address)), ?STRING2LOWER:to_lower(lists:flatten(join(Parts, ":"))). ejabberd-2.1.11/src/web/Makefile.in0000664000000000000000000000111012240230175013620 0ustar # $Id$ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ EFLAGS += @ERLANG_SSLVER@ EFLAGS += -I .. EFLAGS += -pz .. # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif SOURCES = $(wildcard *.erl) OUTDIR = .. BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) all: $(BEAMS) $(OUTDIR)/%.beam: %.erl @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< clean: rm -f $(BEAMS) distclean: clean rm -f Makefile TAGS: etags *.erl ejabberd-2.1.11/src/web/ejabberd_web_admin.erl0000664000000000000000000024453012240230175016041 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_web_admin.erl %%% Author : Alexey Shchepin %%% Purpose : Administration web interface %%% Created : 9 Apr 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %%%% definitions -module(ejabberd_web_admin). -author('alexey@process-one.net'). %% External exports -export([process/2, list_users/4, list_users_in_diapason/4, pretty_print_xml/1, term_to_id/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("ejabberd_http.hrl"). -include("ejabberd_web_admin.hrl"). -define(INPUTATTRS(Type, Name, Value, Attrs), ?XA("input", Attrs ++ [{"type", Type}, {"name", Name}, {"value", Value}])). %%%================================== %%%% get_acl_access %% @spec (Path::[string()], Method) -> {HostOfRule, [AccessRule]} %% where Method = 'GET' | 'POST' %% All accounts can access those URLs get_acl_rule([],_) -> {"localhost", [all]}; get_acl_rule(["style.css"],_) -> {"localhost", [all]}; get_acl_rule(["logo.png"],_) -> {"localhost", [all]}; get_acl_rule(["logo-fill.png"],_) -> {"localhost", [all]}; get_acl_rule(["favicon.ico"],_) -> {"localhost", [all]}; get_acl_rule(["additions.js"],_) -> {"localhost", [all]}; %% This page only displays vhosts that the user is admin: get_acl_rule(["vhosts"],_) -> {"localhost", [all]}; %% The pages of a vhost are only accesible if the user is admin of that vhost: get_acl_rule(["server", VHost | _RPath], Method) when Method=:='GET' orelse Method=:='HEAD' -> {VHost, [configure, webadmin_view]}; get_acl_rule(["server", VHost | _RPath], 'POST') -> {VHost, [configure]}; %% Default rule: only global admins can access any other random page get_acl_rule(_RPath, Method) when Method=:='GET' orelse Method=:='HEAD' -> {global, [configure, webadmin_view]}; get_acl_rule(_RPath, 'POST') -> {global, [configure]}. is_acl_match(Host, Rules, Jid) -> lists:any( fun(Rule) -> allow == acl:match_rule(Host, Rule, Jid) end, Rules). %%%================================== %%%% Menu Items Access get_jid(Auth, HostHTTP, Method) -> case get_auth_admin(Auth, HostHTTP, [], Method) of {ok, {User, Server}} -> jlib:make_jid(User, Server, ""); {unauthorized, Error} -> ?ERROR_MSG("Unauthorized ~p: ~p", [Auth, Error]), throw({unauthorized, Auth}) end. get_menu_items(global, cluster, Lang, JID) -> {Base, _, Items} = make_server_menu([], [], Lang, JID), lists:map( fun({URI, Name}) -> {Base++URI++"/", Name}; ({URI, Name, _SubMenu}) -> {Base++URI++"/", Name} end, Items ); get_menu_items(Host, cluster, Lang, JID) -> {Base, _, Items} = make_host_menu(Host, [], Lang, JID), lists:map( fun({URI, Name}) -> {Base++URI++"/", Name}; ({URI, Name, _SubMenu}) -> {Base++URI++"/", Name} end, Items ). %% get_menu_items(Host, Node, Lang, JID) -> %% {Base, _, Items} = make_host_node_menu(Host, Node, Lang, JID), %% lists:map( %% fun({URI, Name}) -> %% {Base++URI++"/", Name}; %% ({URI, Name, _SubMenu}) -> %% {Base++URI++"/", Name} %% end, %% Items %% ). is_allowed_path(BasePath, {Path, _}, JID) -> is_allowed_path(BasePath ++ [Path], JID); is_allowed_path(BasePath, {Path, _, _}, JID) -> is_allowed_path(BasePath ++ [Path], JID). is_allowed_path(["admin" | Path], JID) -> is_allowed_path(Path, JID); is_allowed_path(Path, JID) -> {HostOfRule, AccessRule} = get_acl_rule(Path, 'GET'), is_acl_match(HostOfRule, AccessRule, JID). %% @spec(Path) -> URL %% where Path = [string()] %% URL = string() %% Convert ["admin", "user", "tom"] -> "/admin/user/tom/" %%path_to_url(Path) -> %% "/" ++ string:join(Path, "/") ++ "/". %% @spec(URL) -> Path %% where Path = [string()] %% URL = string() %% Convert "admin/user/tom" -> ["admin", "user", "tom"] url_to_path(URL) -> string:tokens(URL, "/"). %%%================================== %%%% process/2 process(["doc", LocalFile], _Request) -> DocPath = case os:getenv("EJABBERD_DOC_PATH") of P when is_list(P) -> P; false -> "/share/doc/ejabberd/" end, %% Code based in mod_http_fileserver FileName = filename:join(DocPath, LocalFile), case file:read_file(FileName) of {ok, FileContents} -> ?DEBUG("Delivering content.", []), {200, [{"Server", "ejabberd"}], FileContents}; {error, Error} -> ?DEBUG("Delivering error: ~p", [Error]), Help = " " ++ FileName ++ " - Try to specify the path to ejabberd documentation " "with the environment variable EJABBERD_DOC_PATH. Check the ejabberd Guide for more information.", case Error of eacces -> {403, [], "Forbidden"++Help}; enoent -> {404, [], "Not found"++Help}; _Else -> {404, [], atom_to_list(Error)++Help} end end; process(["server", SHost | RPath] = Path, #request{auth = Auth, lang = Lang, host = HostHTTP, method = Method} = Request) -> Host = jlib:nameprep(SHost), case lists:member(Host, ?MYHOSTS) of true -> case get_auth_admin(Auth, HostHTTP, Path, Method) of {ok, {User, Server}} -> AJID = get_jid(Auth, HostHTTP, Method), process_admin(Host, Request#request{path = RPath, auth = {auth_jid, Auth, AJID}, us = {User, Server}}); {unauthorized, "no-auth-provided"} -> {401, [{"WWW-Authenticate", "basic realm=\"ejabberd\""}], ejabberd_web:make_xhtml([?XCT("h1", "Unauthorized")])}; {unauthorized, Error} -> {BadUser, _BadPass} = Auth, {IPT, _Port} = Request#request.ip, IPS = inet_parse:ntoa(IPT), ?WARNING_MSG("Access of ~p from ~p failed with error: ~p", [BadUser, IPS, Error]), {401, [{"WWW-Authenticate", "basic realm=\"auth error, retry login to ejabberd\""}], ejabberd_web:make_xhtml([?XCT("h1", "Unauthorized")])} end; false -> ejabberd_web:error(not_found) end; process(RPath, #request{auth = Auth, lang = Lang, host = HostHTTP, method = Method} = Request) -> case get_auth_admin(Auth, HostHTTP, RPath, Method) of {ok, {User, Server}} -> AJID = get_jid(Auth, HostHTTP, Method), process_admin(global, Request#request{path = RPath, auth = {auth_jid, Auth, AJID}, us = {User, Server}}); {unauthorized, "no-auth-provided"} -> {401, [{"WWW-Authenticate", "basic realm=\"ejabberd\""}], ejabberd_web:make_xhtml([?XCT("h1", "Unauthorized")])}; {unauthorized, Error} -> {BadUser, _BadPass} = Auth, {IPT, _Port} = Request#request.ip, IPS = inet_parse:ntoa(IPT), ?WARNING_MSG("Access of ~p from ~p failed with error: ~p", [BadUser, IPS, Error]), {401, [{"WWW-Authenticate", "basic realm=\"auth error, retry login to ejabberd\""}], ejabberd_web:make_xhtml([?XCT("h1", "Unauthorized")])} end. get_auth_admin(Auth, HostHTTP, RPath, Method) -> case Auth of {SJID, Pass} -> {HostOfRule, AccessRule} = get_acl_rule(RPath, Method), case jlib:string_to_jid(SJID) of error -> {unauthorized, "badformed-jid"}; #jid{user = "", server = User} -> %% If the user only specified username, not username@server get_auth_account(HostOfRule, AccessRule, User, HostHTTP, Pass); #jid{user = User, server = Server} -> get_auth_account(HostOfRule, AccessRule, User, Server, Pass) end; undefined -> {unauthorized, "no-auth-provided"} end. get_auth_account(HostOfRule, AccessRule, User, Server, Pass) -> case ejabberd_auth:check_password(User, Server, Pass) of true -> case is_acl_match(HostOfRule, AccessRule, jlib:make_jid(User, Server, "")) of false -> {unauthorized, "unprivileged-account"}; true -> {ok, {User, Server}} end; false -> case ejabberd_auth:is_user_exists(User, Server) of true -> {unauthorized, "bad-password"}; false -> {unauthorized, "inexistent-account"} end end. %%%================================== %%%% make_xhtml make_xhtml(Els, Host, Lang, JID) -> make_xhtml(Els, Host, cluster, Lang, JID). %% @spec (Els, Host, Node, Lang, JID) -> {200, [html], xmlelement()} %% where Host = global | string() %% Node = cluster | atom() %% JID = jid() make_xhtml(Els, Host, Node, Lang, JID) -> Base = get_base_path(Host, cluster), %% Enforcing 'cluster' on purpose here MenuItems = make_navigation(Host, Node, Lang, JID), {200, [html], {xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"}, {"xml:lang", Lang}, {"lang", Lang}], [{xmlelement, "head", [], [?XCT("title", "ejabberd Web Admin"), {xmlelement, "meta", [{"http-equiv", "Content-Type"}, {"content", "text/html; charset=utf-8"}], []}, {xmlelement, "script", [{"src", Base ++ "/additions.js"}, {"type", "text/javascript"}], [?C(" ")]}, {xmlelement, "link", [{"href", Base ++ "favicon.ico"}, {"type", "image/x-icon"}, {"rel", "shortcut icon"}], []}, {xmlelement, "link", [{"href", Base ++ "style.css"}, {"type", "text/css"}, {"rel", "stylesheet"}], []}]}, ?XE("body", [?XAE("div", [{"id", "container"}], [?XAE("div", [{"id", "header"}], [?XE("h1", [?ACT("/admin/", "ejabberd Web Admin")] )]), ?XAE("div", [{"id", "navigation"}], [?XE("ul", MenuItems )]), ?XAE("div", [{"id", "content"}], Els), ?XAE("div", [{"id", "clearcopyright"}], [{xmlcdata, ""}])]), ?XAE("div", [{"id", "copyrightouter"}], [?XAE("div", [{"id", "copyright"}], [?XC("p", "ejabberd (c) 2002-2012 ProcessOne") ])])]) ]}}. get_base_path(global, cluster) -> "/admin/"; get_base_path(Host, cluster) -> "/admin/server/" ++ Host ++ "/"; get_base_path(global, Node) -> "/admin/node/" ++ atom_to_list(Node) ++ "/"; get_base_path(Host, Node) -> "/admin/server/" ++ Host ++ "/node/" ++ atom_to_list(Node) ++ "/". %%%================================== %%%% css & images additions_js() -> " function selectAll() { for(i=0;i Base = get_base_path(Host, cluster), " html,body { background: white; margin: 0; padding: 0; height: 100%; } #container { padding: 0; margin: 0; min-height: 100%; height: 100%; margin-bottom: -30px; } html>body #container { height: auto; } #header h1 { width: 100%; height: 55px; padding: 0; margin: 0; background: transparent url(\"" ++ Base ++ "logo-fill.png\"); } #header h1 a { position: absolute; top: 0; left: 0; width: 100%; height: 55px; padding: 0; margin: 0; background: transparent url(\"" ++ Base ++ "logo.png\") no-repeat; display: block; text-indent: -700em; } #clearcopyright { display: block; width: 100%; height: 30px; } #copyrightouter { display: table; width: 100%; height: 30px; } #copyright { display: table-cell; vertical-align: bottom; width: 100%; height: 30px; } #copyright p { margin-left: 0; margin-right: 0; margin-top: 5px; margin-bottom: 0; padding-left: 0; padding-right: 0; padding-top: 1px; padding-bottom: 1px; width: 100%; color: #ffffff; background-color: #fe8a00; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 7pt; font-weight: bold; text-align: center; } #navigation ul { position: absolute; top: 65px; left: 0; padding: 0 1px 1px 1px; margin: 0; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 8pt; font-weight: bold; border-top: 1px solid #d47911; width: 17em; } #navigation ul li { list-style: none; margin: 0; text-align: left; display: inline; } #navigation ul li a { margin: 0; display: block; padding: 3px 6px 3px 9px; border-left: 1em solid #ffc78c; border-right: 1px solid #d47911; border-bottom: 1px solid #d47911; background: #ffe3c9; text-decoration: none; } #navigation ul li a:link { color: #844; } #navigation ul li a:visited { color: #766; } #navigation ul li a:hover { border-color: #fc8800; color: #FFF; background: #332; } ul li #navhead a, ul li #navheadsub a, ul li #navheadsubsub a { text-align: center; border-top: 1px solid #d47911; border-bottom: 2px solid #d47911; background: #FED6A6; } #navheadsub, #navitemsub { border-left: 7px solid white; margin-left: 2px; } #navheadsubsub, #navitemsubsub { border-left: 14px solid white; margin-left: 4px; } #lastactivity li { font-weight: bold; border: 1px solid #d6760e; background-color: #fff2e8; padding: 2px; margin-bottom: -1px; } td.copy { color: #ffffff; background-color: #fe8a00; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 7pt; font-weight: bold; text-align: center; } input { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; border: 1px solid #d6760e; color: #723202; background-color: #fff2e8; vertical-align: middle; margin-bottom: 0px; padding: 0.1em; } input[type=submit] { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 8pt; font-weight: bold; color: #ffffff; background-color: #fe8a00; border: 1px solid #d6760e; } textarea { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; border: 1px solid #d6760e; color: #723202; background-color: #fff2e8; } select { border: 1px solid #d6760e; color: #723202; background-color: #fff2e8; vertical-align: middle; margin-bottom: 0px; padding: 0.1em; } thead { color: #000000; background-color: #ffffff; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; font-weight: bold; } tr.head { color: #ffffff; background-color: #3b547a; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 9pt; font-weight: bold; text-align: center; } tr.oddraw { color: #412c75; background-color: #ccd4df; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 9pt; font-weight: normal; text-align: center; } tr.evenraw { color: #412c75; background-color: #dbe0e8; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 9pt; font-weight: normal; text-align: center; } td.leftheader { color: #412c75; background-color: #ccccc1; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 9pt; font-weight: bold; padding-left: 5px; padding-top: 2px; padding-bottom: 2px; margin-top: 0px; margin-bottom: 0px; } td.leftcontent { color: #000044; background-color: #e6e6df; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 7pt; font-weight: normal; padding-left: 5px; padding-right: 5px; padding-top: 2px; padding-bottom: 2px; margin-top: 0px; margin-bottom: 0px; } td.rightcontent { color: #000044; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; font-weight: normal; text-align: justify; padding-left: 10px; padding-right: 10px; padding-bottom: 5px; } h1 { color: #000044; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14pt; font-weight: bold; text-align: center; padding-top: 2px; padding-bottom: 2px; margin-top: 0px; margin-bottom: 0px; } h2 { color: #000044; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12pt; font-weight: bold; text-align: center; padding-top: 2px; padding-bottom: 2px; margin-top: 0px; margin-bottom: 0px; } h3 { color: #000044; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; font-weight: bold; text-align: left; padding-top: 20px; padding-bottom: 2px; margin-top: 0px; margin-bottom: 0px; } #content a:link { color: #990000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; font-weight: bold; text-decoration: underline; } #content a:visited { color: #990000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; font-weight: bold; text-decoration: underline; } #content a:hover { color: #cc6600; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; font-weight: bold; text-decoration: underline; } #content ul li { list-style-type: disc; font-size: 10pt; /*font-size: 7pt;*/ padding-left: 10px; } #content ul.nolistyle>li { list-style-type: none; } #content li.big { font-size: 10pt; } #content { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; padding-left: 17em; padding-top: 5px; } div.guidelink { text-align: right; padding-right: 1em; } table.withtextareas>tbody>tr>td { vertical-align: top; } p.result { border: 1px; border-style: dashed; border-color: #FE8A02; padding: 1em; margin-right: 1em; background: #FFE3C9; } *.alignright { font-size: 10pt; text-align: right; } ". favicon() -> jlib:decode_base64( "AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAAAA" "AAAAAAAAAAAAAAAAAAAAAAAAJf+cAAIPsAAGC8gAVhecAAIr8ACiR7wBBmO" "cAUKPsAFun8ABhqeoAgLryAJLB8ACz1PcAv9r7AMvi+gAAAAAAAgICARMhI" "CAkJCQkQkFCQgICN2d2cSMgJCRevdvVQkICAlqYh5MgICQkXrRCQkJCMgI7" "kiAjICAUFF2swkFBQRQUXazCQUFBAgI7kiAgICAkJF60QkJCQgICOpiHkyA" "gJCRevdvlQkICAjdndnMgICQkJCRCQkJCAgICARAgICAAAAAAAAAAAAAAAA" "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" "AAAAAAAAAAA"). logo() -> jlib:decode_base64( "iVBORw0KGgoAAAANSUhEUgAAAVcAAAA3CAMAAACPbPnEAAAAAXNSR0IArs4c" "6QAAAEtQTFRFcTIA1XcE/YsA/40E/pIH/JYc/5kg/54i/KIu/6U6/apE/61H" "/61P/bFX/7Vh/bda/rpq/L5s/8J2/cJ8/8qI/86Y/9aj/9mt/+bJ7EGiPwAA" "AZRJREFUeNrt28lug0AQhGHajrPv+/s/aVwpDlgE0gQ3tqO/DhxihMg33VJ7" "JmmCVKSJlVJ4bZQ93Jl/zjJv+8tzcMUVV1xxLXIlRfPAZptYrbf5YeW618PW" "yvG8w/g9ZwquuJ6Y6+bbdY0rrifhSmrmgUulVXbVDq3H39Zy6Cf9+8c7JNM/" "mXeY8+SMRmuIK6644oprkSupmQdulLhQdup1qJKmrmWmVpb5NN9LUyddu7nn" "LYkrrrjiimuVK6mZB+6VuFbiXJk8v/bnv0PVa+Yd5tdr/x7vCfqbgPsfV1xx" "xRXXKldSMw+8KPGgxJWyU7WZE538p0vOr/lOm/q7dPf+bOVKvVXiUcEVV1xx" "xbXMldTMA29KPCtxp7T6XpvxE6/9nm/l987mnG9l5u/8jO4Ot9uTEq8Krrji" "iiuuZa6kZh74UFpli3sO61btMfyHyWGv/RMs7wB67ne32/BdwRVXXHHFtcyV" "1MwDn0qrbHHvyPT/Dsarla/R/1GpQydYPhf0bqC/A7jz7YkrrrjiimuVK6nI" "F5dWoNvcLcs/AAAAAElFTkSuQmCC"). logo_fill() -> jlib:decode_base64( "iVBORw0KGgoAAAANSUhEUgAAAAYAAAA3BAMAAADdxCZzAAAAAXNSR0IArs4c" "6QAAAB5QTFRF1nYO/ooC/o4O/pIS/p4q/q5K/rpq/sqM/tam/ubGzn/S/AAA" "AEFJREFUCNdlw0sRwCAQBUE+gSRHLGABC1jAAhbWAhZwC+88XdXOXb4UlFAr" "SmwN5ekdJY2BkudEec1QvrVQ/r3xOlK9HsTvertmAAAAAElFTkSuQmCC"). %%%================================== %%%% process_admin process_admin(global, #request{path = [], auth = {_, _, AJID}, lang = Lang}) -> %%Base = get_base_path(global, cluster), make_xhtml(?H1GL(?T("Administration"), "toc", "Contents") ++ [?XE("ul", [?LI([?ACT(MIU, MIN)]) || {MIU, MIN} <- get_menu_items(global, cluster, Lang, AJID)] ) ], global, Lang, AJID); process_admin(Host, #request{path = [], auth = {_, _Auth, AJID}, lang = Lang}) -> %%Base = get_base_path(Host, cluster), make_xhtml([?XCT("h1", "Administration"), ?XE("ul", [?LI([?ACT(MIU, MIN)]) || {MIU, MIN} <- get_menu_items(Host, cluster, Lang, AJID)] ) ], Host, Lang, AJID); process_admin(Host, #request{path = ["style.css"]}) -> {200, [{"Content-Type", "text/css"}, last_modified(), cache_control_public()], css(Host)}; process_admin(_Host, #request{path = ["favicon.ico"]}) -> {200, [{"Content-Type", "image/x-icon"}, last_modified(), cache_control_public()], favicon()}; process_admin(_Host, #request{path = ["logo.png"]}) -> {200, [{"Content-Type", "image/png"}, last_modified(), cache_control_public()], logo()}; process_admin(_Host, #request{path = ["logo-fill.png"]}) -> {200, [{"Content-Type", "image/png"}, last_modified(), cache_control_public()], logo_fill()}; process_admin(_Host, #request{path = ["additions.js"]}) -> {200, [{"Content-Type", "text/javascript"}, last_modified(), cache_control_public()], additions_js()}; process_admin(Host, #request{path = ["acls-raw"], q = Query, auth = {_, _Auth, AJID}, lang = Lang}) -> Res = case lists:keysearch("acls", 1, Query) of {value, {_, String}} -> case erl_scan:string(String) of {ok, Tokens, _} -> case erl_parse:parse_term(Tokens) of {ok, NewACLs} -> case acl:add_list(Host, NewACLs, true) of ok -> ok; _ -> error end; _ -> error end; _ -> error end; _ -> nothing end, ACLs = lists:keysort(2, ets:select(acl, [{{acl, {'$1', Host}, '$2'}, [], [{{acl, '$1', '$2'}}]}])), {NumLines, ACLsP} = term_to_paragraph(ACLs, 80), make_xhtml(?H1GL(?T("Access Control Lists"), "ACLDefinition", "ACL Definition") ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [?TEXTAREA("acls", integer_to_list(lists:max([16, NumLines])), "80", ACLsP++"."), ?BR, ?INPUTT("submit", "submit", "Submit") ]) ], Host, Lang, AJID); process_admin(Host, #request{method = Method, path = ["acls"], auth = {_, _Auth, AJID}, q = Query, lang = Lang}) -> ?DEBUG("query: ~p", [Query]), Res = case Method of 'POST' -> case catch acl_parse_query(Host, Query) of {'EXIT', _} -> error; NewACLs -> ?INFO_MSG("NewACLs at ~s: ~p", [Host, NewACLs]), case acl:add_list(Host, NewACLs, true) of ok -> ?INFO_MSG("NewACLs: ok", []), ok; _ -> error end end; _ -> nothing end, ACLs = lists:keysort( 2, ets:select(acl, [{{acl, {'$1', Host}, '$2'}, [], [{{acl, '$1', '$2'}}]}])), make_xhtml(?H1GL(?T("Access Control Lists"), "ACLDefinition", "ACL Definition") ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XE("p", [?ACT("../acls-raw/", "Raw")])] ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [acls_to_xhtml(ACLs), ?BR, ?INPUTT("submit", "delete", "Delete Selected"), ?C(" "), ?INPUTT("submit", "submit", "Submit") ]) ], Host, Lang, AJID); process_admin(Host, #request{path = ["access-raw"], auth = {_, _Auth, AJID}, q = Query, lang = Lang}) -> SetAccess = fun(Rs) -> mnesia:transaction( fun() -> Os = mnesia:select( config, [{{config, {access, '$1', Host}, '$2'}, [], ['$_']}]), lists:foreach(fun(O) -> mnesia:delete_object(O) end, Os), lists:foreach( fun({access, Name, Rules}) -> mnesia:write({config, {access, Name, Host}, Rules}) end, Rs) end) end, Res = case lists:keysearch("access", 1, Query) of {value, {_, String}} -> case erl_scan:string(String) of {ok, Tokens, _} -> case erl_parse:parse_term(Tokens) of {ok, Rs} -> case SetAccess(Rs) of {atomic, _} -> ok; _ -> error end; _ -> error end; _ -> error end; _ -> nothing end, Access = ets:select(config, [{{config, {access, '$1', Host}, '$2'}, [], [{{access, '$1', '$2'}}]}]), {NumLines, AccessP} = term_to_paragraph(Access, 80), make_xhtml(?H1GL(?T("Access Rules"), "AccessRights", "Access Rights") ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [?TEXTAREA("access", integer_to_list(lists:max([16, NumLines])), "80", AccessP++"."), ?BR, ?INPUTT("submit", "submit", "Submit") ]) ], Host, Lang, AJID); process_admin(Host, #request{method = Method, path = ["access"], q = Query, auth = {_, _Auth, AJID}, lang = Lang}) -> ?DEBUG("query: ~p", [Query]), Res = case Method of 'POST' -> case catch access_parse_query(Host, Query) of {'EXIT', _} -> error; ok -> ok end; _ -> nothing end, AccessRules = ets:select(config, [{{config, {access, '$1', Host}, '$2'}, [], [{{access, '$1', '$2'}}]}]), make_xhtml(?H1GL(?T("Access Rules"), "AccessRights", "Access Rights") ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XE("p", [?ACT("../access-raw/", "Raw")])] ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [access_rules_to_xhtml(AccessRules, Lang), ?BR, ?INPUTT("submit", "delete", "Delete Selected") ]) ], Host, Lang, AJID); process_admin(Host, #request{path = ["access", SName], q = Query, auth = {_, _Auth, AJID}, lang = Lang}) -> ?DEBUG("query: ~p", [Query]), Name = list_to_atom(SName), Res = case lists:keysearch("rules", 1, Query) of {value, {_, String}} -> case parse_access_rule(String) of {ok, Rs} -> ejabberd_config:add_global_option( {access, Name, Host}, Rs), ok; _ -> error end; _ -> nothing end, Rules = case ejabberd_config:get_global_option({access, Name, Host}) of undefined -> []; Rs1 -> Rs1 end, make_xhtml([?XC("h1", io_lib:format(?T("~s access rule configuration"), [SName]))] ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [access_rule_to_xhtml(Rules), ?BR, ?INPUTT("submit", "submit", "Submit") ]) ], Host, Lang, AJID); process_admin(global, #request{path = ["vhosts"], auth = {_, _Auth, AJID}, lang = Lang}) -> Res = list_vhosts(Lang, AJID), make_xhtml(?H1GL(?T("Virtual Hosts"), "virtualhost", "Virtual Hosting") ++ Res, global, Lang, AJID); process_admin(Host, #request{path = ["users"], q = Query, auth = {_, _Auth, AJID}, lang = Lang}) when is_list(Host) -> Res = list_users(Host, Query, Lang, fun url_func/1), make_xhtml([?XCT("h1", "Users")] ++ Res, Host, Lang, AJID); process_admin(Host, #request{path = ["users", Diap], auth = {_, _Auth, AJID}, lang = Lang}) when is_list(Host) -> Res = list_users_in_diapason(Host, Diap, Lang, fun url_func/1), make_xhtml([?XCT("h1", "Users")] ++ Res, Host, Lang, AJID); process_admin(Host, #request{ path = ["online-users"], auth = {_, _Auth, AJID}, lang = Lang}) when is_list(Host) -> Res = list_online_users(Host, Lang), make_xhtml([?XCT("h1", "Online Users")] ++ Res, Host, Lang, AJID); process_admin(Host, #request{path = ["last-activity"], auth = {_, _Auth, AJID}, q = Query, lang = Lang}) when is_list(Host) -> ?DEBUG("query: ~p", [Query]), Month = case lists:keysearch("period", 1, Query) of {value, {_, Val}} -> Val; _ -> "month" end, Res = case lists:keysearch("ordinary", 1, Query) of {value, {_, _}} -> list_last_activity(Host, Lang, false, Month); _ -> list_last_activity(Host, Lang, true, Month) end, make_xhtml([?XCT("h1", "Users Last Activity")] ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [?CT("Period: "), ?XAE("select", [{"name", "period"}], lists:map( fun({O, V}) -> Sel = if O == Month -> [{"selected", "selected"}]; true -> [] end, ?XAC("option", Sel ++ [{"value", O}], V) end, [{"month", ?T("Last month")}, {"year", ?T("Last year")}, {"all", ?T("All activity")}])), ?C(" "), ?INPUTT("submit", "ordinary", "Show Ordinary Table"), ?C(" "), ?INPUTT("submit", "integral", "Show Integral Table") ])] ++ Res, Host, Lang, AJID); process_admin(Host, #request{path = ["stats"], auth = {_, _Auth, AJID}, lang = Lang}) -> Res = get_stats(Host, Lang), make_xhtml([?XCT("h1", "Statistics")] ++ Res, Host, Lang, AJID); process_admin(Host, #request{path = ["user", U], auth = {_, _Auth, AJID}, q = Query, lang = Lang}) -> case ejabberd_auth:is_user_exists(U, Host) of true -> Res = user_info(U, Host, Query, Lang), make_xhtml(Res, Host, Lang, AJID); false -> make_xhtml([?XCT("h1", "Not Found")], Host, Lang, AJID) end; process_admin(Host, #request{path = ["nodes"], auth = {_, _Auth, AJID}, lang = Lang}) -> Res = get_nodes(Lang), make_xhtml(Res, Host, Lang, AJID); process_admin(Host, #request{path = ["node", SNode | NPath], auth = {_, _Auth, AJID}, q = Query, lang = Lang}) -> case search_running_node(SNode) of false -> make_xhtml([?XCT("h1", "Node not found")], Host, Lang, AJID); Node -> Res = get_node(Host, Node, NPath, Query, Lang), make_xhtml(Res, Host, Node, Lang, AJID) end; %%%================================== %%%% process_admin default case process_admin(Host, #request{lang = Lang, auth = {_, _Auth, AJID} } = Request) -> {Hook, Opts} = case Host of global -> {webadmin_page_main, [Request]}; Host -> {webadmin_page_host, [Host, Request]} end, case ejabberd_hooks:run_fold(Hook, Host, [], Opts) of [] -> setelement(1, make_xhtml([?XC("h1", "Not Found")], Host, Lang, AJID), 404); Res -> make_xhtml(Res, Host, Lang, AJID) end. %%%================================== %%%% acl acls_to_xhtml(ACLs) -> ?XAE("table", [], [?XE("tbody", lists:map( fun({acl, Name, Spec} = ACL) -> SName = atom_to_list(Name), ID = term_to_id(ACL), ?XE("tr", [?XE("td", [?INPUT("checkbox", "selected", ID)]), ?XC("td", SName)] ++ acl_spec_to_xhtml(ID, Spec) ) end, ACLs) ++ [?XE("tr", [?X("td"), ?XE("td", [?INPUT("text", "namenew", "")]) ] ++ acl_spec_to_xhtml("new", {user, ""}) )] )]). acl_spec_to_text({user, U}) -> {user, U}; acl_spec_to_text({server, S}) -> {server, S}; acl_spec_to_text({user, U, S}) -> {user, U ++ "@" ++ S}; acl_spec_to_text({user_regexp, RU}) -> {user_regexp, RU}; acl_spec_to_text({user_regexp, RU, S}) -> {user_regexp, RU ++ "@" ++ S}; acl_spec_to_text({server_regexp, RS}) -> {server_regexp, RS}; acl_spec_to_text({node_regexp, RU, RS}) -> {node_regexp, RU ++ "@" ++ RS}; acl_spec_to_text({user_glob, RU}) -> {user_glob, RU}; acl_spec_to_text({user_glob, RU, S}) -> {user_glob, RU ++ "@" ++ S}; acl_spec_to_text({server_glob, RS}) -> {server_glob, RS}; acl_spec_to_text({node_glob, RU, RS}) -> {node_glob, RU ++ "@" ++ RS}; acl_spec_to_text(all) -> {all, ""}; acl_spec_to_text(Spec) -> {raw, term_to_string(Spec)}. acl_spec_to_xhtml(ID, Spec) -> {Type, Str} = acl_spec_to_text(Spec), [acl_spec_select(ID, Type), ?ACLINPUT(Str)]. acl_spec_select(ID, Opt) -> ?XE("td", [?XAE("select", [{"name", "type" ++ ID}], lists:map( fun(O) -> Sel = if O == Opt -> [{"selected", "selected"}]; true -> [] end, ?XAC("option", Sel ++ [{"value", atom_to_list(O)}], atom_to_list(O)) end, [user, server, user_regexp, server_regexp, node_regexp, user_glob, server_glob, node_glob, all, raw]))]). %% @spec (T::any()) -> StringLine::string() term_to_string(T) -> StringParagraph = lists:flatten(io_lib:format("~1000000p", [T])), %% Remove from the string all the carriage returns characters ejabberd_regexp:greplace(StringParagraph, "\\n ", ""). %% @spec (T::any(), Cols::integer()) -> {NumLines::integer(), Paragraph::string()} term_to_paragraph(T, Cols) -> Paragraph = erl_prettypr:format(erl_syntax:abstract(T), [{paper, Cols}]), FieldList = ejabberd_regexp:split(Paragraph, "\n"), NumLines = length(FieldList), {NumLines, Paragraph}. term_to_id(T) -> jlib:encode_base64(binary_to_list(term_to_binary(T))). acl_parse_query(Host, Query) -> ACLs = ets:select(acl, [{{acl, {'$1', Host}, '$2'}, [], [{{acl, '$1', '$2'}}]}]), case lists:keysearch("submit", 1, Query) of {value, _} -> acl_parse_submit(ACLs, Query); _ -> case lists:keysearch("delete", 1, Query) of {value, _} -> acl_parse_delete(ACLs, Query) end end. acl_parse_submit(ACLs, Query) -> NewACLs = lists:map( fun({acl, Name, Spec} = ACL) -> %%SName = atom_to_list(Name), ID = term_to_id(ACL), case {lists:keysearch("type" ++ ID, 1, Query), lists:keysearch("value" ++ ID, 1, Query)} of {{value, {_, T}}, {value, {_, V}}} -> {Type, Str} = acl_spec_to_text(Spec), case {atom_to_list(Type), Str} of {T, V} -> ACL; _ -> NewSpec = string_to_spec(T, V), {acl, Name, NewSpec} end; _ -> ACL end end, ACLs), NewACL = case {lists:keysearch("namenew", 1, Query), lists:keysearch("typenew", 1, Query), lists:keysearch("valuenew", 1, Query)} of {{value, {_, ""}}, _, _} -> []; {{value, {_, N}}, {value, {_, T}}, {value, {_, V}}} -> NewName = list_to_atom(N), NewSpec = string_to_spec(T, V), [{acl, NewName, NewSpec}]; _ -> [] end, NewACLs ++ NewACL. string_to_spec("user", Val) -> string_to_spec2(user, Val); string_to_spec("server", Val) -> {server, Val}; string_to_spec("user_regexp", Val) -> string_to_spec2(user_regexp, Val); string_to_spec("server_regexp", Val) -> {server_regexp, Val}; string_to_spec("node_regexp", Val) -> #jid{luser = U, lserver = S, resource = ""} = jlib:string_to_jid(Val), {node_regexp, U, S}; string_to_spec("user_glob", Val) -> string_to_spec2(user_glob, Val); string_to_spec("server_glob", Val) -> {server_glob, Val}; string_to_spec("node_glob", Val) -> #jid{luser = U, lserver = S, resource = ""} = jlib:string_to_jid(Val), {node_glob, U, S}; string_to_spec("all", _) -> all; string_to_spec("raw", Val) -> {ok, Tokens, _} = erl_scan:string(Val ++ "."), {ok, NewSpec} = erl_parse:parse_term(Tokens), NewSpec. string_to_spec2(ACLName, Val) -> #jid{luser = U, lserver = S, resource = ""} = jlib:string_to_jid(Val), case U of "" -> {ACLName, S}; _ -> {ACLName, U, S} end. acl_parse_delete(ACLs, Query) -> NewACLs = lists:filter( fun({acl, _Name, _Spec} = ACL) -> ID = term_to_id(ACL), not lists:member({"selected", ID}, Query) end, ACLs), NewACLs. access_rules_to_xhtml(AccessRules, Lang) -> ?XAE("table", [], [?XE("tbody", lists:map( fun({access, Name, Rules} = Access) -> SName = atom_to_list(Name), ID = term_to_id(Access), ?XE("tr", [?XE("td", [?INPUT("checkbox", "selected", ID)]), ?XE("td", [?AC(SName ++ "/", SName)]), ?XC("td", term_to_string(Rules)) ] ) end, AccessRules) ++ [?XE("tr", [?X("td"), ?XE("td", [?INPUT("text", "namenew", "")]), ?XE("td", [?INPUTT("submit", "addnew", "Add New")]) ] )] )]). access_parse_query(Host, Query) -> AccessRules = ets:select(config, [{{config, {access, '$1', Host}, '$2'}, [], [{{access, '$1', '$2'}}]}]), case lists:keysearch("addnew", 1, Query) of {value, _} -> access_parse_addnew(AccessRules, Host, Query); _ -> case lists:keysearch("delete", 1, Query) of {value, _} -> access_parse_delete(AccessRules, Host, Query) end end. access_parse_addnew(_AccessRules, Host, Query) -> case lists:keysearch("namenew", 1, Query) of {value, {_, String}} when String /= "" -> Name = list_to_atom(String), ejabberd_config:add_global_option({access, Name, Host}, []), ok end. access_parse_delete(AccessRules, Host, Query) -> lists:foreach( fun({access, Name, _Rules} = AccessRule) -> ID = term_to_id(AccessRule), case lists:member({"selected", ID}, Query) of true -> mnesia:transaction( fun() -> mnesia:delete({config, {access, Name, Host}}) end); _ -> ok end end, AccessRules), ok. access_rule_to_xhtml(Rules) -> Text = lists:flatmap( fun({Access, ACL} = _Rule) -> SAccess = element_to_list(Access), SACL = atom_to_list(ACL), SAccess ++ "\s\t" ++ SACL ++ "\n" end, Rules), ?XAC("textarea", [{"name", "rules"}, {"rows", "16"}, {"cols", "80"}], Text). parse_access_rule(Text) -> Strings = string:tokens(Text, "\r\n"), case catch lists:flatmap( fun(String) -> case string:tokens(String, "\s\t") of [Access, ACL] -> [{list_to_element(Access), list_to_atom(ACL)}]; [] -> [] end end, Strings) of {'EXIT', _Reason} -> error; Rs -> {ok, Rs} end. %%%================================== %%%% list_vhosts list_vhosts(Lang, JID) -> Hosts = ?MYHOSTS, HostsAllowed = lists:filter( fun(Host) -> is_acl_match(Host, [configure, webadmin_view], JID) end, Hosts ), list_vhosts2(Lang, HostsAllowed). list_vhosts2(Lang, Hosts) -> SHosts = lists:sort(Hosts), [?XE("table", [?XE("thead", [?XE("tr", [?XCT("td", "Host"), ?XCT("td", "Registered Users"), ?XCT("td", "Online Users") ])]), ?XE("tbody", lists:map( fun(Host) -> OnlineUsers = length(ejabberd_sm:get_vh_session_list(Host)), RegisteredUsers = ejabberd_auth:get_vh_registered_users_number(Host), ?XE("tr", [?XE("td", [?AC("../server/" ++ Host ++ "/", Host)]), ?XC("td", pretty_string_int(RegisteredUsers)), ?XC("td", pretty_string_int(OnlineUsers)) ]) end, SHosts) )])]. %%%================================== %%%% list_users list_users(Host, Query, Lang, URLFunc) -> Res = list_users_parse_query(Query, Host), Users = ejabberd_auth:get_vh_registered_users(Host), SUsers = lists:sort([{S, U} || {U, S} <- Users]), FUsers = case length(SUsers) of N when N =< 100 -> [list_given_users(Host, SUsers, "../", Lang, URLFunc)]; N -> NParts = trunc(math:sqrt(N * 0.618)) + 1, M = trunc(N / NParts) + 1, lists:flatmap( fun(K) -> L = K + M - 1, %%Node = integer_to_list(K) ++ "-" ++ integer_to_list(L), Last = if L < N -> su_to_list(lists:nth(L, SUsers)); true -> su_to_list(lists:last(SUsers)) end, Name = su_to_list(lists:nth(K, SUsers)) ++ [$\s, 226, 128, 148, $\s] ++ Last, [?AC(URLFunc({user_diapason, K, L}), Name), ?BR] end, lists:seq(1, N, M)) end, case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [?XE("table", [?XE("tr", [?XC("td", ?T("User") ++ ":"), ?XE("td", [?INPUT("text", "newusername", "")]), ?XE("td", [?C([" @ ", Host])]) ]), ?XE("tr", [?XC("td", ?T("Password") ++ ":"), ?XE("td", [?INPUT("password", "newuserpassword", "")]), ?X("td") ]), ?XE("tr", [?X("td"), ?XAE("td", [{"class", "alignright"}], [?INPUTT("submit", "addnewuser", "Add User")]), ?X("td") ])]), ?P] ++ FUsers)]. %% Parse user creation query and try register: list_users_parse_query(Query, Host) -> case lists:keysearch("addnewuser", 1, Query) of {value, _} -> {value, {_, Username}} = lists:keysearch("newusername", 1, Query), {value, {_, Password}} = lists:keysearch("newuserpassword", 1, Query), case jlib:string_to_jid(Username++"@"++Host) of error -> error; #jid{user = User, server = Server} -> case ejabberd_auth:try_register(User, Server, Password) of {error, _Reason} -> error; _ -> ok end end; false -> nothing end. list_users_in_diapason(Host, Diap, Lang, URLFunc) -> Users = ejabberd_auth:get_vh_registered_users(Host), SUsers = lists:sort([{S, U} || {U, S} <- Users]), [S1, S2] = ejabberd_regexp:split(Diap, "-"), N1 = list_to_integer(S1), N2 = list_to_integer(S2), Sub = lists:sublist(SUsers, N1, N2 - N1 + 1), [list_given_users(Host, Sub, "../../", Lang, URLFunc)]. list_given_users(Host, Users, Prefix, Lang, URLFunc) -> ModLast = get_lastactivity_module(Host), ModOffline = get_offlinemsg_module(Host), ?XE("table", [?XE("thead", [?XE("tr", [?XCT("td", "User"), ?XCT("td", "Offline Messages"), ?XCT("td", "Last Activity")])]), ?XE("tbody", lists:map( fun(_SU = {Server, User}) -> US = {User, Server}, QueueLenStr = get_offlinemsg_length(ModOffline, User, Server), FQueueLen = [?AC(URLFunc({users_queue, Prefix, User, Server}), QueueLenStr)], FLast = case ejabberd_sm:get_user_resources(User, Server) of [] -> case ModLast:get_last_info(User, Server) of not_found -> ?T("Never"); {ok, Shift, _Status} -> TimeStamp = {Shift div 1000000, Shift rem 1000000, 0}, {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:now_to_local_time(TimeStamp), lists:flatten( io_lib:format( "~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Year, Month, Day, Hour, Minute, Second])) end; _ -> ?T("Online") end, ?XE("tr", [?XE("td", [?AC(URLFunc({user, Prefix, ejabberd_http:url_encode(User), Server}), us_to_list(US))]), ?XE("td", FQueueLen), ?XC("td", FLast)]) end, Users) )]). get_offlinemsg_length(ModOffline, User, Server) -> case ModOffline of none -> "disabled"; _ -> pretty_string_int(ModOffline:get_queue_length(User, Server)) end. get_offlinemsg_module(Server) -> case [mod_offline, mod_offline_odbc] -- gen_mod:loaded_modules(Server) of [mod_offline, mod_offline_odbc] -> none; [mod_offline_odbc] -> mod_offline; [mod_offline] -> mod_offline_odbc end. get_lastactivity_module(Server) -> case lists:member(mod_last, gen_mod:loaded_modules(Server)) of true -> mod_last; _ -> mod_last_odbc end. get_lastactivity_menuitem_list(Server) -> case get_lastactivity_module(Server) of mod_last -> [{"last-activity", "Last Activity"}]; mod_last_odbc -> [] end. us_to_list({User, Server}) -> jlib:jid_to_string({User, Server, ""}). su_to_list({Server, User}) -> jlib:jid_to_string({User, Server, ""}). %%%================================== %%%% get_stats get_stats(global, Lang) -> OnlineUsers = mnesia:table_info(session, size), RegisteredUsers = lists:foldl( fun(Host, Total) -> ejabberd_auth:get_vh_registered_users_number(Host) + Total end, 0, ejabberd_config:get_global_option(hosts)), S2SConns = ejabberd_s2s:dirty_get_connections(), S2SConnections = length(S2SConns), S2SServers = length(lists:usort([element(2, C) || C <- S2SConns])), [?XAE("table", [], [?XE("tbody", [?XE("tr", [?XCT("td", "Registered Users:"), ?XC("td", pretty_string_int(RegisteredUsers))]), ?XE("tr", [?XCT("td", "Online Users:"), ?XC("td", pretty_string_int(OnlineUsers))]), ?XE("tr", [?XCT("td", "Outgoing s2s Connections:"), ?XC("td", pretty_string_int(S2SConnections))]), ?XE("tr", [?XCT("td", "Outgoing s2s Servers:"), ?XC("td", pretty_string_int(S2SServers))]) ]) ])]; get_stats(Host, Lang) -> OnlineUsers = length(ejabberd_sm:get_vh_session_list(Host)), RegisteredUsers = ejabberd_auth:get_vh_registered_users_number(Host), [?XAE("table", [], [?XE("tbody", [?XE("tr", [?XCT("td", "Registered Users:"), ?XC("td", pretty_string_int(RegisteredUsers))]), ?XE("tr", [?XCT("td", "Online Users:"), ?XC("td", pretty_string_int(OnlineUsers))]) ]) ])]. list_online_users(Host, _Lang) -> Users = [{S, U} || {U, S, _R} <- ejabberd_sm:get_vh_session_list(Host)], SUsers = lists:usort(Users), lists:flatmap( fun({_S, U} = SU) -> [?AC("../user/" ++ ejabberd_http:url_encode(U) ++ "/", su_to_list(SU)), ?BR] end, SUsers). user_info(User, Server, Query, Lang) -> LServer = jlib:nameprep(Server), US = {jlib:nodeprep(User), LServer}, Res = user_parse_query(User, Server, Query), Resources = ejabberd_sm:get_user_resources(User, Server), FResources = case Resources of [] -> [?CT("None")]; _ -> [?XE("ul", lists:map(fun(R) -> FIP = case ejabberd_sm:get_user_info( User, Server, R) of offline -> ""; Info when is_list(Info) -> Node = proplists:get_value(node, Info), Conn = proplists:get_value(conn, Info), {IP, Port} = proplists:get_value(ip, Info), ConnS = case Conn of c2s -> "plain"; c2s_tls -> "tls"; c2s_compressed -> "zlib"; c2s_compressed_tls -> "tls+zlib"; http_bind -> "http-bind"; http_poll -> "http-poll" end, " (" ++ ConnS ++ "://" ++ inet_parse:ntoa(IP) ++ ":" ++ integer_to_list(Port) ++ "#" ++ atom_to_list(Node) ++ ")" end, ?LI([?C(R ++ FIP)]) end, lists:sort(Resources)))] end, Password = ejabberd_auth:get_password_s(User, Server), FPassword = [?INPUT("password", "password", Password), ?C(" "), ?INPUTT("submit", "chpassword", "Change Password")], UserItems = ejabberd_hooks:run_fold(webadmin_user, LServer, [], [User, Server, Lang]), %% Code copied from list_given_users/5: ModLast = get_lastactivity_module(Server), LastActivity = case ejabberd_sm:get_user_resources(User, Server) of [] -> case ModLast:get_last_info(User, Server) of not_found -> ?T("Never"); {ok, Shift, _Status} -> TimeStamp = {Shift div 1000000, Shift rem 1000000, 0}, {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:now_to_local_time(TimeStamp), lists:flatten( io_lib:format( "~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Year, Month, Day, Hour, Minute, Second])) end; _ -> ?T("Online") end, [?XC("h1", ?T("User ") ++ us_to_list(US))] ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [?XCT("h3", "Connected Resources:")] ++ FResources ++ [?XCT("h3", "Password:")] ++ FPassword ++ [?XCT("h3", "Last Activity")] ++ [?C(LastActivity)] ++ UserItems ++ [?P, ?INPUTT("submit", "removeuser", "Remove User")])]. user_parse_query(User, Server, Query) -> lists:foldl(fun({Action, _Value}, Acc) when Acc == nothing -> user_parse_query1(Action, User, Server, Query); ({_Action, _Value}, Acc) -> Acc end, nothing, Query). user_parse_query1("password", _User, _Server, _Query) -> nothing; user_parse_query1("chpassword", User, Server, Query) -> case lists:keysearch("password", 1, Query) of {value, {_, undefined}} -> error; {value, {_, Password}} -> ejabberd_auth:set_password(User, Server, Password), ok; _ -> error end; user_parse_query1("removeuser", User, Server, _Query) -> ejabberd_auth:remove_user(User, Server), ok; user_parse_query1(Action, User, Server, Query) -> case ejabberd_hooks:run_fold(webadmin_user_parse_query, Server, [], [Action, User, Server, Query]) of [] -> nothing; Res -> Res end. list_last_activity(Host, Lang, Integral, Period) -> {MegaSecs, Secs, _MicroSecs} = now(), TimeStamp = MegaSecs * 1000000 + Secs, case Period of "all" -> TS = 0, Days = infinity; "year" -> TS = TimeStamp - 366 * 86400, Days = 366; _ -> TS = TimeStamp - 31 * 86400, Days = 31 end, case catch mnesia:dirty_select( last_activity, [{{last_activity, {'_', Host}, '$1', '_'}, [{'>', '$1', TS}], [{'trunc', {'/', {'-', TimeStamp, '$1'}, 86400}}]}]) of {'EXIT', _Reason} -> []; Vals -> Hist = histogram(Vals, Integral), if Hist == [] -> [?CT("No Data")]; true -> Left = if Days == infinity -> 0; true -> Days - length(Hist) end, Tail = if Integral -> lists:duplicate(Left, lists:last(Hist)); true -> lists:duplicate(Left, 0) end, Max = lists:max(Hist), [?XAE("ol", [{"id", "lastactivity"}, {"start", "0"}], [?XAE("li", [{"style", "width:" ++ integer_to_list( trunc(90 * V / Max)) ++ "%;"}], [{xmlcdata, pretty_string_int(V)}]) || V <- Hist ++ Tail])] end end. histogram(Values, Integral) -> histogram(lists:sort(Values), Integral, 0, 0, []). histogram([H | T], Integral, Current, Count, Hist) when Current == H -> histogram(T, Integral, Current, Count + 1, Hist); histogram([H | _] = Values, Integral, Current, Count, Hist) when Current < H -> if Integral -> histogram(Values, Integral, Current + 1, Count, [Count | Hist]); true -> histogram(Values, Integral, Current + 1, 0, [Count | Hist]) end; histogram([], _Integral, _Current, Count, Hist) -> if Count > 0 -> lists:reverse([Count | Hist]); true -> lists:reverse(Hist) end. %%%================================== %%%% get_nodes get_nodes(Lang) -> RunningNodes = mnesia:system_info(running_db_nodes), StoppedNodes = lists:usort(mnesia:system_info(db_nodes) ++ mnesia:system_info(extra_db_nodes)) -- RunningNodes, FRN = if RunningNodes == [] -> ?CT("None"); true -> ?XE("ul", lists:map( fun(N) -> S = atom_to_list(N), ?LI([?AC("../node/" ++ S ++ "/", S)]) end, lists:sort(RunningNodes))) end, FSN = if StoppedNodes == [] -> ?CT("None"); true -> ?XE("ul", lists:map( fun(N) -> S = atom_to_list(N), ?LI([?C(S)]) end, lists:sort(StoppedNodes))) end, [?XCT("h1", "Nodes"), ?XCT("h3", "Running Nodes"), FRN, ?XCT("h3", "Stopped Nodes"), FSN]. search_running_node(SNode) -> search_running_node(SNode, mnesia:system_info(running_db_nodes)). search_running_node(_, []) -> false; search_running_node(SNode, [Node | Nodes]) -> case atom_to_list(Node) of SNode -> Node; _ -> search_running_node(SNode, Nodes) end. get_node(global, Node, [], Query, Lang) -> Res = node_parse_query(Node, Query), Base = get_base_path(global, Node), MenuItems2 = make_menu_items(global, Node, Base, Lang), [?XC("h1", ?T("Node ") ++ atom_to_list(Node))] ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XE("ul", [?LI([?ACT(Base ++ "db/", "Database")]), ?LI([?ACT(Base ++ "backup/", "Backup")]), ?LI([?ACT(Base ++ "ports/", "Listened Ports")]), ?LI([?ACT(Base ++ "stats/", "Statistics")]), ?LI([?ACT(Base ++ "update/", "Update")]) ] ++ MenuItems2), ?XAE("form", [{"action", ""}, {"method", "post"}], [?INPUTT("submit", "restart", "Restart"), ?C(" "), ?INPUTT("submit", "stop", "Stop")]) ]; get_node(Host, Node, [], _Query, Lang) -> Base = get_base_path(Host, Node), MenuItems2 = make_menu_items(Host, Node, Base, Lang), [?XC("h1", ?T("Node ") ++ atom_to_list(Node)), ?XE("ul", [?LI([?ACT(Base ++ "modules/", "Modules")])] ++ MenuItems2) ]; get_node(global, Node, ["db"], Query, Lang) -> case rpc:call(Node, mnesia, system_info, [tables]) of {badrpc, _Reason} -> [?XCT("h1", "RPC Call Error")]; Tables -> ResS = case node_db_parse_query(Node, Tables, Query) of nothing -> []; ok -> [?XREST("Submitted")] end, STables = lists:sort(Tables), Rows = lists:map( fun(Table) -> STable = atom_to_list(Table), TInfo = case rpc:call(Node, mnesia, table_info, [Table, all]) of {badrpc, _} -> []; I -> I end, {Type, Size, Memory} = case {lists:keysearch(storage_type, 1, TInfo), lists:keysearch(size, 1, TInfo), lists:keysearch(memory, 1, TInfo)} of {{value, {storage_type, T}}, {value, {size, S}}, {value, {memory, M}}} -> {T, S, M}; _ -> {unknown, 0, 0} end, ?XE("tr", [?XC("td", STable), ?XE("td", [db_storage_select( STable, Type, Lang)]), ?XAC("td", [{"class", "alignright"}], pretty_string_int(Size)), ?XAC("td", [{"class", "alignright"}], pretty_string_int(Memory)) ]) end, STables), [?XC("h1", ?T("Database Tables at ") ++ atom_to_list(Node))] ++ ResS ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [?XAE("table", [], [?XE("thead", [?XE("tr", [?XCT("td", "Name"), ?XCT("td", "Storage Type"), ?XCT("td", "Elements"), %% Elements/items/records inserted in the table ?XCT("td", "Memory") %% Words or Bytes allocated to the table on this node ])]), ?XE("tbody", Rows ++ [?XE("tr", [?XAE("td", [{"colspan", "4"}, {"class", "alignright"}], [?INPUTT("submit", "submit", "Submit")]) ])] )])])] end; get_node(global, Node, ["backup"], Query, Lang) -> HomeDirRaw = case {os:getenv("HOME"), os:type()} of {EnvHome, _} when is_list(EnvHome) -> EnvHome; {false, {win32, _Osname}} -> "C:/"; {false, _} -> "/tmp/" end, HomeDir = filename:nativename(HomeDirRaw), ResS = case node_backup_parse_query(Node, Query) of nothing -> []; ok -> [?XREST("Submitted")]; {error, Error} -> [?XRES(?T("Error") ++": " ++ io_lib:format("~p", [Error]))] end, ?H1GL(?T("Backup of ") ++ atom_to_list(Node), "list-eja-commands", "List of ejabberd Commands") ++ ResS ++ [?XCT("p", "Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately."), ?XAE("form", [{"action", ""}, {"method", "post"}], [?XAE("table", [], [?XE("tbody", [?XE("tr", [?XCT("td", "Store binary backup:"), ?XE("td", [?INPUT("text", "storepath", filename:join(HomeDir, "ejabberd.backup"))]), ?XE("td", [?INPUTT("submit", "store", "OK")]) ]), ?XE("tr", [?XCT("td", "Restore binary backup immediately:"), ?XE("td", [?INPUT("text", "restorepath", filename:join(HomeDir, "ejabberd.backup"))]), ?XE("td", [?INPUTT("submit", "restore", "OK")]) ]), ?XE("tr", [?XCT("td", "Restore binary backup after next ejabberd restart (requires less memory):"), ?XE("td", [?INPUT("text", "fallbackpath", filename:join(HomeDir, "ejabberd.backup"))]), ?XE("td", [?INPUTT("submit", "fallback", "OK")]) ]), ?XE("tr", [?XCT("td", "Store plain text backup:"), ?XE("td", [?INPUT("text", "dumppath", filename:join(HomeDir, "ejabberd.dump"))]), ?XE("td", [?INPUTT("submit", "dump", "OK")]) ]), ?XE("tr", [?XCT("td", "Restore plain text backup immediately:"), ?XE("td", [?INPUT("text", "loadpath", filename:join(HomeDir, "ejabberd.dump"))]), ?XE("td", [?INPUTT("submit", "load", "OK")]) ]), ?XE("tr", [?XCT("td", "Import users data from a PIEFXIS file (XEP-0227):"), ?XE("td", [?INPUT("text", "import_piefxis_filepath", filename:join(HomeDir, "users.xml"))]), ?XE("td", [?INPUTT("submit", "import_piefxis_file", "OK")]) ]), ?XE("tr", [?XCT("td", "Export data of all users in the server to PIEFXIS files (XEP-0227):"), ?XE("td", [?INPUT("text", "export_piefxis_dirpath", HomeDir)]), ?XE("td", [?INPUTT("submit", "export_piefxis_dir", "OK")]) ]), ?XE("tr", [?XE("td", [?CT("Export data of users in a host to PIEFXIS files (XEP-0227):"), ?C(" "), ?INPUT("text", "export_piefxis_host_dirhost", ?MYNAME)]), ?XE("td", [?INPUT("text", "export_piefxis_host_dirpath", HomeDir)]), ?XE("td", [?INPUTT("submit", "export_piefxis_host_dir", "OK")]) ]), ?XE("tr", [?XCT("td", "Import user data from jabberd14 spool file:"), ?XE("td", [?INPUT("text", "import_filepath", filename:join(HomeDir, "user1.xml"))]), ?XE("td", [?INPUTT("submit", "import_file", "OK")]) ]), ?XE("tr", [?XCT("td", "Import users data from jabberd14 spool directory:"), ?XE("td", [?INPUT("text", "import_dirpath", "/var/spool/jabber/")]), ?XE("td", [?INPUTT("submit", "import_dir", "OK")]) ]) ]) ])])]; get_node(global, Node, ["ports"], Query, Lang) -> Ports = rpc:call(Node, ejabberd_config, get_local_option, [listen]), Res = case catch node_ports_parse_query(Node, Ports, Query) of submitted -> ok; {'EXIT', _Reason} -> error; {is_added, ok} -> ok; {is_added, {error, Reason}} -> {error, io_lib:format("~p", [Reason])}; _ -> nothing end, %% TODO: This sorting does not work when [{{Port, IP}, Module, Opts}] NewPorts = lists:sort( rpc:call(Node, ejabberd_config, get_local_option, [listen])), H1String = ?T("Listened Ports at ") ++ atom_to_list(Node), ?H1GL(H1String, "listened", "Listening Ports") ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; {error, ReasonT} -> [?XRES(?T("Error") ++ ": " ++ ReasonT)]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [node_ports_to_xhtml(NewPorts, Lang)]) ]; get_node(Host, Node, ["modules"], Query, Lang) when is_list(Host) -> Modules = rpc:call(Node, gen_mod, loaded_modules_with_opts, [Host]), Res = case catch node_modules_parse_query(Host, Node, Modules, Query) of submitted -> ok; {'EXIT', Reason} -> ?INFO_MSG("~p~n", [Reason]), error; _ -> nothing end, NewModules = lists:sort( rpc:call(Node, gen_mod, loaded_modules_with_opts, [Host])), H1String = ?T("Modules at ") ++ atom_to_list(Node), ?H1GL(H1String, "modoverview", "Modules Overview") ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [node_modules_to_xhtml(NewModules, Lang)]) ]; get_node(global, Node, ["stats"], _Query, Lang) -> UpTime = rpc:call(Node, erlang, statistics, [wall_clock]), UpTimeS = io_lib:format("~.3f", [element(1, UpTime)/1000]), CPUTime = rpc:call(Node, erlang, statistics, [runtime]), CPUTimeS = io_lib:format("~.3f", [element(1, CPUTime)/1000]), OnlineUsers = mnesia:table_info(session, size), TransactionsCommitted = rpc:call(Node, mnesia, system_info, [transaction_commits]), TransactionsAborted = rpc:call(Node, mnesia, system_info, [transaction_failures]), TransactionsRestarted = rpc:call(Node, mnesia, system_info, [transaction_restarts]), TransactionsLogged = rpc:call(Node, mnesia, system_info, [transaction_log_writes]), [?XC("h1", io_lib:format(?T("Statistics of ~p"), [Node])), ?XAE("table", [], [?XE("tbody", [?XE("tr", [?XCT("td", "Uptime:"), ?XAC("td", [{"class", "alignright"}], UpTimeS)]), ?XE("tr", [?XCT("td", "CPU Time:"), ?XAC("td", [{"class", "alignright"}], CPUTimeS)]), ?XE("tr", [?XCT("td", "Online Users:"), ?XAC("td", [{"class", "alignright"}], pretty_string_int(OnlineUsers))]), ?XE("tr", [?XCT("td", "Transactions Committed:"), ?XAC("td", [{"class", "alignright"}], pretty_string_int(TransactionsCommitted))]), ?XE("tr", [?XCT("td", "Transactions Aborted:"), ?XAC("td", [{"class", "alignright"}], pretty_string_int(TransactionsAborted))]), ?XE("tr", [?XCT("td", "Transactions Restarted:"), ?XAC("td", [{"class", "alignright"}], pretty_string_int(TransactionsRestarted))]), ?XE("tr", [?XCT("td", "Transactions Logged:"), ?XAC("td", [{"class", "alignright"}], pretty_string_int(TransactionsLogged))]) ]) ])]; get_node(global, Node, ["update"], Query, Lang) -> rpc:call(Node, code, purge, [ejabberd_update]), Res = node_update_parse_query(Node, Query), rpc:call(Node, code, load_file, [ejabberd_update]), {ok, _Dir, UpdatedBeams, Script, LowLevelScript, Check} = rpc:call(Node, ejabberd_update, update_info, []), Mods = case UpdatedBeams of [] -> ?CT("None"); _ -> BeamsLis = lists:map( fun(Beam) -> BeamString = atom_to_list(Beam), ?LI([ ?INPUT("checkbox", "selected", BeamString), %%?XA("input", [{"checked", ""}, %% Selected by default %% {"type", "checkbox"}, %% {"name", "selected"}, %% {"value", BeamString}]), ?C(BeamString)]) end, UpdatedBeams), SelectButtons = [?BR, ?INPUTATTRS("button", "selectall", "Select All", [{"onClick", "selectAll()"}]), ?C(" "), ?INPUTATTRS("button", "unselectall", "Unselect All", [{"onClick", "unSelectAll()"}])], %%?XE("ul", BeamsLis) ?XAE("ul", [{"class", "nolistyle"}], BeamsLis ++ SelectButtons) end, FmtScript = ?XC("pre", io_lib:format("~p", [Script])), FmtLowLevelScript = ?XC("pre", io_lib:format("~p", [LowLevelScript])), [?XC("h1", ?T("Update ") ++ atom_to_list(Node))] ++ case Res of ok -> [?XREST("Submitted")]; {error, ErrorText} -> [?XREST("Error: " ++ ErrorText)]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [ ?XCT("h2", "Update plan"), ?XCT("h3", "Modified modules"), Mods, ?XCT("h3", "Update script"), FmtScript, ?XCT("h3", "Low level update script"), FmtLowLevelScript, ?XCT("h3", "Script check"), ?XC("pre", atom_to_list(Check)), ?BR, ?INPUTT("submit", "update", "Update") ]) ]; get_node(Host, Node, NPath, Query, Lang) -> {Hook, Opts} = case Host of global -> {webadmin_page_node, [Node, NPath, Query, Lang]}; Host -> {webadmin_page_hostnode, [Host, Node, NPath, Query, Lang]} end, case ejabberd_hooks:run_fold(Hook, Host, [], Opts) of [] -> [?XC("h1", "Not Found")]; Res -> Res end. %%%================================== %%%% node parse node_parse_query(Node, Query) -> case lists:keysearch("restart", 1, Query) of {value, _} -> case rpc:call(Node, init, restart, []) of {badrpc, _Reason} -> error; _ -> ok end; _ -> case lists:keysearch("stop", 1, Query) of {value, _} -> case rpc:call(Node, init, stop, []) of {badrpc, _Reason} -> error; _ -> ok end; _ -> nothing end end. db_storage_select(ID, Opt, Lang) -> ?XAE("select", [{"name", "table" ++ ID}], lists:map( fun({O, Desc}) -> Sel = if O == Opt -> [{"selected", "selected"}]; true -> [] end, ?XACT("option", Sel ++ [{"value", atom_to_list(O)}], Desc) end, [{ram_copies, "RAM copy"}, {disc_copies, "RAM and disc copy"}, {disc_only_copies, "Disc only copy"}, {unknown, "Remote copy"}, {delete_content, "Delete content"}, {delete_table, "Delete table"}])). node_db_parse_query(_Node, _Tables, [{nokey,[]}]) -> nothing; node_db_parse_query(Node, Tables, Query) -> lists:foreach( fun(Table) -> STable = atom_to_list(Table), case lists:keysearch("table" ++ STable, 1, Query) of {value, {_, SType}} -> Type = case SType of "unknown" -> unknown; "ram_copies" -> ram_copies; "disc_copies" -> disc_copies; "disc_only_copies" -> disc_only_copies; "delete_content" -> delete_content; "delete_table" -> delete_table; _ -> false end, if Type == false -> ok; Type == delete_content -> mnesia:clear_table(Table); Type == delete_table -> mnesia:delete_table(Table); Type == unknown -> mnesia:del_table_copy(Table, Node); true -> case mnesia:add_table_copy(Table, Node, Type) of {aborted, _} -> mnesia:change_table_copy_type( Table, Node, Type); _ -> ok end end; _ -> ok end end, Tables), ok. node_backup_parse_query(_Node, [{nokey,[]}]) -> nothing; node_backup_parse_query(Node, Query) -> lists:foldl( fun(Action, nothing) -> case lists:keysearch(Action, 1, Query) of {value, _} -> case lists:keysearch(Action ++ "path", 1, Query) of {value, {_, Path}} -> Res = case Action of "store" -> rpc:call(Node, mnesia, backup, [Path]); "restore" -> rpc:call(Node, ejabberd_admin, restore, [Path]); "fallback" -> rpc:call(Node, mnesia, install_fallback, [Path]); "dump" -> rpc:call(Node, ejabberd_admin, dump_to_textfile, [Path]); "load" -> rpc:call(Node, mnesia, load_textfile, [Path]); "import_piefxis_file" -> rpc:call(Node, ejabberd_piefxis, import_file, [Path]); "export_piefxis_dir" -> rpc:call(Node, ejabberd_piefxis, export_server, [Path]); "export_piefxis_host_dir" -> {value, {_, Host}} = lists:keysearch(Action ++ "host", 1, Query), rpc:call(Node, ejabberd_piefxis, export_host, [Path, Host]); "import_file" -> rpc:call(Node, ejabberd_admin, import_file, [Path]); "import_dir" -> rpc:call(Node, ejabberd_admin, import_dir, [Path]) end, case Res of {error, Reason} -> {error, Reason}; {badrpc, Reason} -> {badrpc, Reason}; _ -> ok end; OtherError -> {error, OtherError} end; _ -> nothing end; (_Action, Res) -> Res end, nothing, ["store", "restore", "fallback", "dump", "load", "import_file", "import_dir", "import_piefxis_file", "export_piefxis_dir", "export_piefxis_host_dir"]). node_ports_to_xhtml(Ports, Lang) -> ?XAE("table", [{"class", "withtextareas"}], [?XE("thead", [?XE("tr", [?XCT("td", "Port"), ?XCT("td", "IP"), ?XCT("td", "Protocol"), ?XCT("td", "Module"), ?XCT("td", "Options") ])]), ?XE("tbody", lists:map( fun({PortIP, Module, Opts} = _E) -> {_Port, SPort, _TIP, SIP, SSPort, NetProt, OptsClean} = get_port_data(PortIP, Opts), SModule = atom_to_list(Module), {NumLines, SOptsClean} = term_to_paragraph(OptsClean, 40), %%ID = term_to_id(E), ?XE("tr", [?XAE("td", [{"size", "6"}], [?C(SPort)]), ?XAE("td", [{"size", "15"}], [?C(SIP)]), ?XAE("td", [{"size", "4"}], [?C(atom_to_list(NetProt))]), ?XE("td", [?INPUTS("text", "module" ++ SSPort, SModule, "15")]), ?XE("td", [?TEXTAREA("opts" ++ SSPort, integer_to_list(NumLines), "35", SOptsClean)]), ?XE("td", [?INPUTT("submit", "add" ++ SSPort, "Update")]), ?XE("td", [?INPUTT("submit", "delete" ++ SSPort, "Delete")]) ] ) end, Ports) ++ [?XE("tr", [?XE("td", [?INPUTS("text", "portnew", "", "6")]), ?XE("td", [?INPUTS("text", "ipnew", "0.0.0.0", "15")]), ?XE("td", [make_netprot_html("tcp")]), ?XE("td", [?INPUTS("text", "modulenew", "", "15")]), ?XE("td", [?TEXTAREA("optsnew", "2", "35", "[]")]), ?XAE("td", [{"colspan", "2"}], [?INPUTT("submit", "addnew", "Add New")]) ] )] )]). make_netprot_html(NetProt) -> ?XAE("select", [{"name", "netprotnew"}], lists:map( fun(O) -> Sel = if O == NetProt -> [{"selected", "selected"}]; true -> [] end, ?XAC("option", Sel ++ [{"value", O}], O) end, ["tcp", "udp"])). get_port_data(PortIP, Opts) -> {Port, IPT, IPS, _IPV, NetProt, OptsClean} = ejabberd_listener:parse_listener_portip(PortIP, Opts), SPort = io_lib:format("~p", [Port]), SSPort = lists:flatten( lists:map( fun(N) -> io_lib:format("~.16b", [N]) end, binary_to_list(crypto:md5(SPort++IPS++atom_to_list(NetProt))))), {Port, SPort, IPT, IPS, SSPort, NetProt, OptsClean}. node_ports_parse_query(Node, Ports, Query) -> lists:foreach( fun({PortIpNetp, Module1, Opts1}) -> {Port, _SPort, TIP, _SIP, SSPort, NetProt, _OptsClean} = get_port_data(PortIpNetp, Opts1), case lists:keysearch("add" ++ SSPort, 1, Query) of {value, _} -> PortIpNetp2 = {Port, TIP, NetProt}, {{value, {_, SModule}}, {value, {_, SOpts}}} = {lists:keysearch("module" ++ SSPort, 1, Query), lists:keysearch("opts" ++ SSPort, 1, Query)}, Module = list_to_atom(SModule), {ok, Tokens, _} = erl_scan:string(SOpts ++ "."), {ok, Opts} = erl_parse:parse_term(Tokens), rpc:call(Node, ejabberd_listener, delete_listener, [PortIpNetp2, Module1]), R=rpc:call(Node, ejabberd_listener, add_listener, [PortIpNetp2, Module, Opts]), throw({is_added, R}); _ -> case lists:keysearch("delete" ++ SSPort, 1, Query) of {value, _} -> rpc:call(Node, ejabberd_listener, delete_listener, [PortIpNetp, Module1]), throw(submitted); _ -> ok end end end, Ports), case lists:keysearch("addnew", 1, Query) of {value, _} -> {{value, {_, SPort}}, {value, {_, STIP}}, %% It is a string that may represent a tuple {value, {_, SNetProt}}, {value, {_, SModule}}, {value, {_, SOpts}}} = {lists:keysearch("portnew", 1, Query), lists:keysearch("ipnew", 1, Query), lists:keysearch("netprotnew", 1, Query), lists:keysearch("modulenew", 1, Query), lists:keysearch("optsnew", 1, Query)}, {ok, Toks, _} = erl_scan:string(SPort ++ "."), {ok, Port2} = erl_parse:parse_term(Toks), {ok, ToksIP, _} = erl_scan:string(STIP ++ "."), STIP2 = case erl_parse:parse_term(ToksIP) of {ok, IPTParsed} -> IPTParsed; {error, _} -> STIP end, Module = list_to_atom(SModule), NetProt2 = list_to_atom(SNetProt), {ok, Tokens, _} = erl_scan:string(SOpts ++ "."), {ok, Opts} = erl_parse:parse_term(Tokens), {Port2, _SPort, IP2, _SIP, _SSPort, NetProt2, OptsClean} = get_port_data({Port2, STIP2, NetProt2}, Opts), R=rpc:call(Node, ejabberd_listener, add_listener, [{Port2, IP2, NetProt2}, Module, OptsClean]), throw({is_added, R}); _ -> ok end. node_modules_to_xhtml(Modules, Lang) -> ?XAE("table", [{"class", "withtextareas"}], [?XE("thead", [?XE("tr", [?XCT("td", "Module"), ?XCT("td", "Options") ])]), ?XE("tbody", lists:map( fun({Module, Opts} = _E) -> SModule = atom_to_list(Module), {NumLines, SOpts} = term_to_paragraph(Opts, 40), %%ID = term_to_id(E), ?XE("tr", [?XC("td", SModule), ?XE("td", [?TEXTAREA("opts" ++ SModule, integer_to_list(NumLines), "40", SOpts)]), ?XE("td", [?INPUTT("submit", "restart" ++ SModule, "Restart")]), ?XE("td", [?INPUTT("submit", "stop" ++ SModule, "Stop")]) ] ) end, Modules) ++ [?XE("tr", [?XE("td", [?INPUT("text", "modulenew", "")]), ?XE("td", [?TEXTAREA("optsnew", "2", "40", "[]")]), ?XAE("td", [{"colspan", "2"}], [?INPUTT("submit", "start", "Start")]) ] )] )]). node_modules_parse_query(Host, Node, Modules, Query) -> lists:foreach( fun({Module, _Opts1}) -> SModule = atom_to_list(Module), case lists:keysearch("restart" ++ SModule, 1, Query) of {value, _} -> {value, {_, SOpts}} = lists:keysearch("opts" ++ SModule, 1, Query), {ok, Tokens, _} = erl_scan:string(SOpts ++ "."), {ok, Opts} = erl_parse:parse_term(Tokens), rpc:call(Node, gen_mod, stop_module, [Host, Module]), rpc:call(Node, gen_mod, start_module, [Host, Module, Opts]), throw(submitted); _ -> case lists:keysearch("stop" ++ SModule, 1, Query) of {value, _} -> rpc:call(Node, gen_mod, stop_module, [Host, Module]), throw(submitted); _ -> ok end end end, Modules), case lists:keysearch("start", 1, Query) of {value, _} -> {{value, {_, SModule}}, {value, {_, SOpts}}} = {lists:keysearch("modulenew", 1, Query), lists:keysearch("optsnew", 1, Query)}, Module = list_to_atom(SModule), {ok, Tokens, _} = erl_scan:string(SOpts ++ "."), {ok, Opts} = erl_parse:parse_term(Tokens), rpc:call(Node, gen_mod, start_module, [Host, Module, Opts]), throw(submitted); _ -> ok end. node_update_parse_query(Node, Query) -> case lists:keysearch("update", 1, Query) of {value, _} -> ModulesToUpdateStrings = proplists:get_all_values("selected",Query), ModulesToUpdate = [list_to_atom(M) || M <- ModulesToUpdateStrings], case rpc:call(Node, ejabberd_update, update, [ModulesToUpdate]) of {ok, _} -> ok; {error, Error} -> ?ERROR_MSG("~p~n", [Error]), {error, io_lib:format("~p", [Error])}; {badrpc, Error} -> ?ERROR_MSG("Bad RPC: ~p~n", [Error]), {error, "Bad RPC: " ++ io_lib:format("~p", [Error])} end; _ -> nothing end. pretty_print_xml(El) -> lists:flatten(pretty_print_xml(El, "")). pretty_print_xml({xmlcdata, CData}, Prefix) -> [Prefix, CData, $\n]; pretty_print_xml({xmlelement, Name, Attrs, Els}, Prefix) -> [Prefix, $<, Name, case Attrs of [] -> []; [{Attr, Val} | RestAttrs] -> AttrPrefix = [Prefix, string:copies(" ", length(Name) + 2)], [$\s, Attr, $=, $', xml:crypt(Val), $' | lists:map(fun({Attr1, Val1}) -> [$\n, AttrPrefix, Attr1, $=, $', xml:crypt(Val1), $'] end, RestAttrs)] end, if Els == [] -> "/>\n"; true -> OnlyCData = lists:all(fun({xmlcdata, _}) -> true; ({xmlelement, _, _, _}) -> false end, Els), if OnlyCData -> [$>, xml:get_cdata(Els), $<, $/, Name, $>, $\n ]; true -> [$>, $\n, lists:map(fun(E) -> pretty_print_xml(E, [Prefix, " "]) end, Els), Prefix, $<, $/, Name, $>, $\n ] end end]. element_to_list(X) when is_atom(X) -> atom_to_list(X); element_to_list(X) when is_integer(X) -> integer_to_list(X). list_to_element(List) -> {ok, Tokens, _} = erl_scan:string(List), [{_, _, Element}] = Tokens, Element. url_func({user_diapason, From, To}) -> integer_to_list(From) ++ "-" ++ integer_to_list(To) ++ "/"; url_func({users_queue, Prefix, User, _Server}) -> Prefix ++ "user/" ++ User ++ "/queue/"; url_func({user, Prefix, User, _Server}) -> Prefix ++ "user/" ++ User ++ "/". last_modified() -> {"Last-Modified", "Mon, 25 Feb 2008 13:23:30 GMT"}. cache_control_public() -> {"Cache-Control", "public"}. %% Transform 1234567890 into "1,234,567,890" pretty_string_int(Integer) when is_integer(Integer) -> pretty_string_int(integer_to_list(Integer)); pretty_string_int(String) when is_list(String) -> {_, Result} = lists:foldl( fun(NewNumber, {3, Result}) -> {1, [NewNumber, $, | Result]}; (NewNumber, {CountAcc, Result}) -> {CountAcc+1, [NewNumber | Result]} end, {0, ""}, lists:reverse(String)), Result. %%%================================== %%%% navigation menu %% @spec (Host, Node, Lang, JID::jid()) -> [LI] make_navigation(Host, Node, Lang, JID) -> Menu = make_navigation_menu(Host, Node, Lang, JID), make_menu_items(Lang, Menu). %% @spec (Host, Node, Lang, JID::jid()) -> Menu %% where Host = global | string() %% Node = cluster | string() %% Lang = string() %% Menu = {URL, Title} | {URL, Title, [Menu]} %% URL = string() %% Title = string() make_navigation_menu(Host, Node, Lang, JID) -> HostNodeMenu = make_host_node_menu(Host, Node, Lang, JID), HostMenu = make_host_menu(Host, HostNodeMenu, Lang, JID), NodeMenu = make_node_menu(Host, Node, Lang), make_server_menu(HostMenu, NodeMenu, Lang, JID). %% @spec (Host, Node, Base, Lang) -> [LI] make_menu_items(global, cluster, Base, Lang) -> HookItems = get_menu_items_hook(server, Lang), make_menu_items(Lang, {Base, "", HookItems}); make_menu_items(global, Node, Base, Lang) -> HookItems = get_menu_items_hook({node, Node}, Lang), make_menu_items(Lang, {Base, "", HookItems}); make_menu_items(Host, cluster, Base, Lang) -> HookItems = get_menu_items_hook({host, Host}, Lang), make_menu_items(Lang, {Base, "", HookItems}); make_menu_items(Host, Node, Base, Lang) -> HookItems = get_menu_items_hook({hostnode, Host, Node}, Lang), make_menu_items(Lang, {Base, "", HookItems}). make_host_node_menu(global, _, _Lang, _JID) -> {"", "", []}; make_host_node_menu(_, cluster, _Lang, _JID) -> {"", "", []}; make_host_node_menu(Host, Node, Lang, JID) -> HostNodeBase = get_base_path(Host, Node), HostNodeFixed = [{"modules/", "Modules"}] ++ get_menu_items_hook({hostnode, Host, Node}, Lang), HostNodeBasePath = url_to_path(HostNodeBase), HostNodeFixed2 = [Tuple || Tuple <- HostNodeFixed, is_allowed_path(HostNodeBasePath, Tuple, JID)], {HostNodeBase, atom_to_list(Node), HostNodeFixed2}. make_host_menu(global, _HostNodeMenu, _Lang, _JID) -> {"", "", []}; make_host_menu(Host, HostNodeMenu, Lang, JID) -> HostBase = get_base_path(Host, cluster), HostFixed = [{"acls", "Access Control Lists"}, {"access", "Access Rules"}, {"users", "Users"}, {"online-users", "Online Users"}] ++ get_lastactivity_menuitem_list(Host) ++ [{"nodes", "Nodes", HostNodeMenu}, {"stats", "Statistics"}] ++ get_menu_items_hook({host, Host}, Lang), HostBasePath = url_to_path(HostBase), HostFixed2 = [Tuple || Tuple <- HostFixed, is_allowed_path(HostBasePath, Tuple, JID)], {HostBase, Host, HostFixed2}. make_node_menu(_Host, cluster, _Lang) -> {"", "", []}; make_node_menu(global, Node, Lang) -> NodeBase = get_base_path(global, Node), NodeFixed = [{"db/", "Database"}, {"backup/", "Backup"}, {"ports/", "Listened Ports"}, {"stats/", "Statistics"}, {"update/", "Update"}] ++ get_menu_items_hook({node, Node}, Lang), {NodeBase, atom_to_list(Node), NodeFixed}; make_node_menu(_Host, _Node, _Lang) -> {"", "", []}. make_server_menu(HostMenu, NodeMenu, Lang, JID) -> Base = get_base_path(global, cluster), Fixed = [{"acls", "Access Control Lists"}, {"access", "Access Rules"}, {"vhosts", "Virtual Hosts", HostMenu}, {"nodes", "Nodes", NodeMenu}, {"stats", "Statistics"}] ++ get_menu_items_hook(server, Lang), BasePath = url_to_path(Base), Fixed2 = [Tuple || Tuple <- Fixed, is_allowed_path(BasePath, Tuple, JID)], {Base, "ejabberd", Fixed2}. get_menu_items_hook({hostnode, Host, Node}, Lang) -> ejabberd_hooks:run_fold(webadmin_menu_hostnode, Host, [], [Host, Node, Lang]); get_menu_items_hook({host, Host}, Lang) -> ejabberd_hooks:run_fold(webadmin_menu_host, Host, [], [Host, Lang]); get_menu_items_hook({node, Node}, Lang) -> ejabberd_hooks:run_fold(webadmin_menu_node, [], [Node, Lang]); get_menu_items_hook(server, Lang) -> ejabberd_hooks:run_fold(webadmin_menu_main, [], [Lang]). %% @spec (Lang::string(), Menu) -> [LI] %% where Menu = {MURI::string(), MName::string(), Items::[Item]} %% Item = {IURI::string(), IName::string()} | {IURI::string(), IName::string(), Menu} make_menu_items(Lang, Menu) -> lists:reverse(make_menu_items2(Lang, 1, Menu)). make_menu_items2(Lang, Deep, {MURI, MName, _} = Menu) -> Res = case MName of "" -> []; _ -> [make_menu_item(header, Deep, MURI, MName, Lang) ] end, make_menu_items2(Lang, Deep, Menu, Res). make_menu_items2(_, _Deep, {_, _, []}, Res) -> Res; make_menu_items2(Lang, Deep, {MURI, MName, [Item | Items]}, Res) -> Res2 = case Item of {IURI, IName} -> [make_menu_item(item, Deep, MURI++IURI++"/", IName, Lang) | Res]; {IURI, IName, SubMenu} -> %%ResTemp = [?LI([?ACT(MURI ++ IURI ++ "/", IName)]) | Res], ResTemp = [make_menu_item(item, Deep, MURI++IURI++"/", IName, Lang) | Res], ResSubMenu = make_menu_items2(Lang, Deep+1, SubMenu), ResSubMenu ++ ResTemp end, make_menu_items2(Lang, Deep, {MURI, MName, Items}, Res2). make_menu_item(header, 1, URI, Name, _Lang) -> ?LI([?XAE("div", [{"id", "navhead"}], [?AC(URI, Name)] )]); make_menu_item(header, 2, URI, Name, _Lang) -> ?LI([?XAE("div", [{"id", "navheadsub"}], [?AC(URI, Name)] )]); make_menu_item(header, 3, URI, Name, _Lang) -> ?LI([?XAE("div", [{"id", "navheadsubsub"}], [?AC(URI, Name)] )]); make_menu_item(item, 1, URI, Name, Lang) -> ?LI([?XAE("div", [{"id", "navitem"}], [?ACT(URI, Name)] )]); make_menu_item(item, 2, URI, Name, Lang) -> ?LI([?XAE("div", [{"id", "navitemsub"}], [?ACT(URI, Name)] )]); make_menu_item(item, 3, URI, Name, Lang) -> ?LI([?XAE("div", [{"id", "navitemsubsub"}], [?ACT(URI, Name)] )]). %%%================================== %%% vim: set foldmethod=marker foldmarker=%%%%,%%%=: ejabberd-2.1.11/src/web/mod_register_web.erl0000664000000000000000000005066412240230175015621 0ustar %%%------------------------------------------------------------------- %%% File : mod_register_web.erl %%% Author : Badlop %%% Purpose : Web page to register account and related tasks %%% Created : 4 May 2008 by Badlop %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %%% IDEAS: %%% %%% * Implement those options, already present in mod_register: %%% + access %%% + captcha_protected %%% + password_strength %%% + welcome_message %%% + registration_timeout %%% %%% * Improve this module to allow each virtual host to have different %%% options. See http://support.process-one.net/browse/EJAB-561 %%% %%% * Check that all the text is translatable. %%% %%% * Add option to use a custom CSS file, or custom CSS lines. %%% %%% * Don't hardcode the "register" path in URL. %%% %%% * Allow private email during register, and store in custom table. %%% * Optionally require private email to register. %%% * Optionally require email confirmation to register. %%% * Allow to set a private email address anytime. %%% * Allow to recover password using private email to confirm (mod_passrecover) %%% * Optionally require invitation %%% * Optionally register request is forwarded to admin, no account created. -module(mod_register_web). -author('badlop@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process/2 ]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("ejabberd_http.hrl"). -include("ejabberd_web_admin.hrl"). %%%---------------------------------------------------------------------- %%% gen_mod callbacks %%%---------------------------------------------------------------------- start(_Host, _Opts) -> %% case gen_mod:get_opt(docroot, Opts, undefined) of ok. stop(_Host) -> ok. %%%---------------------------------------------------------------------- %%% HTTP handlers %%%---------------------------------------------------------------------- process([], #request{method = 'GET', lang = Lang}) -> index_page(Lang); process(["register.css"], #request{method = 'GET'}) -> serve_css(); process(["new"], #request{method = 'GET', lang = Lang, host = Host, ip = IP}) -> {Addr, _Port} = IP, form_new_get(Host, Lang, Addr); process(["delete"], #request{method = 'GET', lang = Lang, host = Host}) -> form_del_get(Host, Lang); process(["change_password"], #request{method = 'GET', lang = Lang, host = Host}) -> form_changepass_get(Host, Lang); process(["new"], #request{method = 'POST', q = Q, ip = {Ip,_Port}, lang = Lang, host = Host}) -> case form_new_post(Q, Host) of {success, ok, {Username, Host, _Password}} -> Jid = jlib:make_jid(Username, Host, ""), send_registration_notifications(Jid, Ip), Text = ?T("Your Jabber account was successfully created."), {200, [], Text}; Error -> ErrorText = ?T("There was an error creating the account: ") ++ ?T(get_error_text(Error)), {404, [], ErrorText} end; process(["delete"], #request{method = 'POST', q = Q, lang = Lang, host = Host}) -> case form_del_post(Q, Host) of {atomic, ok} -> Text = ?T("Your Jabber account was successfully deleted."), {200, [], Text}; Error -> ErrorText = ?T("There was an error deleting the account: ") ++ ?T(get_error_text(Error)), {404, [], ErrorText} end; %% TODO: Currently only the first vhost is usable. The web request record %% should include the host where the POST was sent. process(["change_password"], #request{method = 'POST', q = Q, lang = Lang, host = Host}) -> case form_changepass_post(Q, Host) of {atomic, ok} -> Text = ?T("The password of your Jabber account was successfully changed."), {200, [], Text}; Error -> ErrorText = ?T("There was an error changing the password: ") ++ ?T(get_error_text(Error)), {404, [], ErrorText} end. %%%---------------------------------------------------------------------- %%% CSS %%%---------------------------------------------------------------------- serve_css() -> {200, [{"Content-Type", "text/css"}, last_modified(), cache_control_public()], css()}. last_modified() -> {"Last-Modified", "Mon, 25 Feb 2008 13:23:30 GMT"}. cache_control_public() -> {"Cache-Control", "public"}. css() -> "html,body { background: white; margin: 0; padding: 0; height: 100%; }". %%%---------------------------------------------------------------------- %%% Index page %%%---------------------------------------------------------------------- index_page(Lang) -> HeadEls = [ ?XCT("title", "Jabber Account Registration"), ?XA("link", [{"href", "/register/register.css"}, {"type", "text/css"}, {"rel", "stylesheet"}]) ], Els=[ ?XACT("h1", [{"class", "title"}, {"style", "text-align:center;"}], "Jabber Account Registration"), ?XE("ul", [ ?XE("li", [?ACT("new", "Register a Jabber account")]), ?XE("li", [?ACT("change_password", "Change Password")]), ?XE("li", [?ACT("delete", "Unregister a Jabber account")]) ] ) ], {200, [{"Server", "ejabberd"}, {"Content-Type", "text/html"}], ejabberd_web:make_xhtml(HeadEls, Els)}. %%%---------------------------------------------------------------------- %%% Formulary new account GET %%%---------------------------------------------------------------------- form_new_get(Host, Lang, IP) -> CaptchaEls = build_captcha_li_list(Lang, IP), HeadEls = [ ?XCT("title", "Register a Jabber account"), ?XA("link", [{"href", "/register/register.css"}, {"type", "text/css"}, {"rel", "stylesheet"}]) ], Els=[ ?XACT("h1", [{"class", "title"}, {"style", "text-align:center;"}], "Register a Jabber account"), ?XCT("p", "This page allows to create a Jabber account in this Jabber server. " "Your JID (Jabber IDentifier) will be of the form: username@server. " "Please read carefully the instructions to fill correctly the fields."), %% ?XAE("form", [{"action", ""}, {"method", "post"}], [ ?XE("ol", [ ?XE("li", [ ?CT("Username:"), ?C(" "), ?INPUTS("text", "username", "", "20"), ?BR, ?XE("ul", [ ?XCT("li", "This is case insensitive: macbeth is the same that MacBeth and Macbeth."), ?XC("li", ?T("Characters not allowed:") ++ " \" & ' / : < > @ ") ]) ]), ?XE("li", [ ?CT("Server:"), ?C(" "), ?C(Host) ]), ?XE("li", [ ?CT("Password:"), ?C(" "), ?INPUTS("password", "password", "", "20"), ?BR, ?XE("ul", [ ?XCT("li", "Don't tell your password to anybody, " "not even the administrators of the Jabber server."), ?XCT("li", "You can later change your password using a Jabber client."), ?XCT("li", "Some Jabber clients can store your password in your computer. " "Use that feature only if you trust your computer is safe."), ?XCT("li", "Memorize your password, or write it in a paper placed in a safe place. " "In Jabber there isn't an automated way to recover your password if you forget it.") ]) ]), ?XE("li", [ ?CT("Password Verification:"), ?C(" "), ?INPUTS("password", "password2", "", "20") ])] ++ CaptchaEls ++ [ %% Nombre
(opcional):

--> %% %% Dirección de correo
(opcional):

--> ?XE("li", [ ?INPUTT("submit", "register", "Register") ]) ]) ]) ], {200, [{"Server", "ejabberd"}, {"Content-Type", "text/html"}], ejabberd_web:make_xhtml(HeadEls, Els)}. %% Copied from mod_register.erl send_registration_notifications(UJID, Source) -> Host = UJID#jid.lserver, case gen_mod:get_module_opt(Host, ?MODULE, registration_watchers, []) of [] -> ok; JIDs when is_list(JIDs) -> Body = lists:flatten( io_lib:format( "[~s] The account ~s was registered from IP address ~s " "on node ~w using ~p.", [get_time_string(), jlib:jid_to_string(UJID), ip_to_string(Source), node(), ?MODULE])), lists:foreach( fun(S) -> case jlib:string_to_jid(S) of error -> ok; JID -> ejabberd_router:route( jlib:make_jid("", Host, ""), JID, {xmlelement, "message", [{"type", "chat"}], [{xmlelement, "body", [], [{xmlcdata, Body}]}]}) end end, JIDs); _ -> ok end. ip_to_string(Source) when is_tuple(Source) -> inet_parse:ntoa(Source); ip_to_string(undefined) -> "undefined"; ip_to_string(_) -> "unknown". get_time_string() -> write_time(erlang:localtime()). %% Function copied from ejabberd_logger_h.erl and customized write_time({{Y,Mo,D},{H,Mi,S}}) -> io_lib:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Y, Mo, D, H, Mi, S]). %%%---------------------------------------------------------------------- %%% Formulary new POST %%%---------------------------------------------------------------------- form_new_post(Q, Host) -> case catch get_register_parameters(Q) of [Username, Password, Password, Id, Key] -> form_new_post(Username, Host, Password, {Id, Key}); [_Username, _Password, _Password2, false, false] -> {error, passwords_not_identical}; [_Username, _Password, _Password2, Id, Key] -> ejabberd_captcha:check_captcha(Id, Key), %% This deletes the captcha {error, passwords_not_identical}; _ -> {error, wrong_parameters} end. get_register_parameters(Q) -> lists:map( fun(Key) -> case lists:keysearch(Key, 1, Q) of {value, {_Key, Value}} -> Value; false -> false end end, ["username", "password", "password2", "id", "key"]). form_new_post(Username, Host, Password, {false, false}) -> register_account(Username, Host, Password); form_new_post(Username, Host, Password, {Id, Key}) -> case ejabberd_captcha:check_captcha(Id, Key) of captcha_valid -> register_account(Username, Host, Password); captcha_non_valid -> {error, captcha_non_valid}; captcha_not_found -> {error, captcha_non_valid} end. %%%---------------------------------------------------------------------- %%% Formulary Captcha support for new GET/POST %%%---------------------------------------------------------------------- build_captcha_li_list(Lang, IP) -> case ejabberd_captcha:is_feature_available() of true -> build_captcha_li_list2(Lang, IP); false -> [] end. build_captcha_li_list2(Lang, IP) -> SID = "", From = #jid{user = "", server = "test", resource = ""}, To = #jid{user = "", server = "test", resource = ""}, Args = [], case ejabberd_captcha:create_captcha(SID, From, To, Lang, IP, Args) of {ok, Id, _} -> {_, {CImg,CText,CId,CKey}} = ejabberd_captcha:build_captcha_html(Id, Lang), [?XE("li", [CText, ?C(" "), CId, CKey, ?BR, CImg] )]; _ -> [] end. %%%---------------------------------------------------------------------- %%% Formulary change password GET %%%---------------------------------------------------------------------- form_changepass_get(Host, Lang) -> HeadEls = [ ?XCT("title", "Change Password"), ?XA("link", [{"href", "/register/register.css"}, {"type", "text/css"}, {"rel", "stylesheet"}]) ], Els=[ ?XACT("h1", [{"class", "title"}, {"style", "text-align:center;"}], "Change Password"), ?XAE("form", [{"action", ""}, {"method", "post"}], [ ?XE("ol", [ ?XE("li", [ ?CT("Username:"), ?C(" "), ?INPUTS("text", "username", "", "20") ]), ?XE("li", [ ?CT("Server:"), ?C(" "), ?C(Host) ]), ?XE("li", [ ?CT("Old Password:"), ?C(" "), ?INPUTS("password", "passwordold", "", "20") ]), ?XE("li", [ ?CT("New Password:"), ?C(" "), ?INPUTS("password", "password", "", "20") ]), ?XE("li", [ ?CT("Password Verification:"), ?C(" "), ?INPUTS("password", "password2", "", "20") ]), ?XE("li", [ ?INPUTT("submit", "changepass", "Change Password") ]) ]) ]) ], {200, [{"Server", "ejabberd"}, {"Content-Type", "text/html"}], ejabberd_web:make_xhtml(HeadEls, Els)}. %%%---------------------------------------------------------------------- %%% Formulary change password POST %%%---------------------------------------------------------------------- form_changepass_post(Q, Host) -> case catch get_changepass_parameters(Q) of [Username, PasswordOld, Password, Password] -> try_change_password(Username, Host, PasswordOld, Password); [_Username, _PasswordOld, _Password, _Password2] -> {error, passwords_not_identical}; _ -> {error, wrong_parameters} end. get_changepass_parameters(Q) -> lists:map( fun(Key) -> {value, {_Key, Value}} = lists:keysearch(Key, 1, Q), Value end, ["username", "passwordold", "password", "password2"]). %% @spec(Username,Host,PasswordOld,Password) -> {atomic, ok} | %% {error, account_doesnt_exist} | %% {error, password_not_changed} | %% {error, password_incorrect} try_change_password(Username, Host, PasswordOld, Password) -> try change_password(Username, Host, PasswordOld, Password) of {atomic, ok} -> {atomic, ok} catch error:{badmatch, Error} -> {error, Error} end. change_password(Username, Host, PasswordOld, Password) -> %% Check the account exists account_exists = check_account_exists(Username, Host), %% Check the old password is correct password_correct = check_password(Username, Host, PasswordOld), %% This function always returns: ok %% Change the password ok = ejabberd_auth:set_password(Username, Host, Password), %% Check the new password is correct case check_password(Username, Host, Password) of password_correct -> {atomic, ok}; password_incorrect -> {error, password_not_changed} end. check_account_exists(Username, Host) -> case ejabberd_auth:is_user_exists(Username, Host) of true -> account_exists; false -> account_doesnt_exist end. check_password(Username, Host, Password) -> case ejabberd_auth:check_password(Username, Host, Password) of true -> password_correct; false -> password_incorrect end. %%%---------------------------------------------------------------------- %%% Formulary delete account GET %%%---------------------------------------------------------------------- form_del_get(Host, Lang) -> HeadEls = [ ?XCT("title", "Unregister a Jabber account"), ?XA("link", [{"href", "/register/register.css"}, {"type", "text/css"}, {"rel", "stylesheet"}]) ], Els=[ ?XACT("h1", [{"class", "title"}, {"style", "text-align:center;"}], "Unregister a Jabber account"), ?XCT("p", "This page allows to unregister a Jabber account in this Jabber server."), ?XAE("form", [{"action", ""}, {"method", "post"}], [ ?XE("ol", [ ?XE("li", [ ?CT("Username:"), ?C(" "), ?INPUTS("text", "username", "", "20") ]), ?XE("li", [ ?CT("Server:"), ?C(" "), ?C(Host) ]), ?XE("li", [ ?CT("Password:"), ?C(" "), ?INPUTS("password", "password", "", "20") ]), ?XE("li", [ ?INPUTT("submit", "unregister", "Unregister") ]) ]) ]) ], {200, [{"Server", "ejabberd"}, {"Content-Type", "text/html"}], ejabberd_web:make_xhtml(HeadEls, Els)}. %% @spec(Username, Host, Password) -> {success, ok, {Username, Host, Password} | %% {success, exists, {Username, Host, Password}} | %% {error, not_allowed} | %% {error, invalid_jid} register_account(Username, Host, Password) -> case jlib:make_jid(Username, Host, "") of error -> {error, invalid_jid}; _ -> register_account2(Username, Host, Password) end. register_account2(Username, Host, Password) -> case ejabberd_auth:try_register(Username, Host, Password) of {atomic, Res} -> {success, Res, {Username, Host, Password}}; Other -> Other end. %%%---------------------------------------------------------------------- %%% Formulary delete POST %%%---------------------------------------------------------------------- form_del_post(Q, Host) -> case catch get_unregister_parameters(Q) of [Username, Password] -> try_unregister_account(Username, Host, Password); _ -> {error, wrong_parameters} end. get_unregister_parameters(Q) -> lists:map( fun(Key) -> {value, {_Key, Value}} = lists:keysearch(Key, 1, Q), Value end, ["username", "password"]). %% @spec(Username, Host, Password) -> {atomic, ok} | %% {error, account_doesnt_exist} | %% {error, account_exists} | %% {error, password_incorrect} try_unregister_account(Username, Host, Password) -> try unregister_account(Username, Host, Password) of {atomic, ok} -> {atomic, ok} catch error:{badmatch, Error} -> {error, Error} end. unregister_account(Username, Host, Password) -> %% Check the account exists account_exists = check_account_exists(Username, Host), %% Check the password is correct password_correct = check_password(Username, Host, Password), %% This function always returns: ok ok = ejabberd_auth:remove_user(Username, Host, Password), %% Check the account does not exist anymore account_doesnt_exist = check_account_exists(Username, Host), %% If we reached this point, return success {atomic, ok}. %%%---------------------------------------------------------------------- %%% Error texts %%%---------------------------------------------------------------------- get_error_text({error, captcha_non_valid}) -> "The captcha you entered is wrong"; get_error_text({success, exists, _}) -> get_error_text({atomic, exists}); get_error_text({atomic, exists}) -> "The account already exists"; get_error_text({error, password_incorrect}) -> "Incorrect password"; get_error_text({error, invalid_jid}) -> "The username is not valid"; get_error_text({error, not_allowed}) -> "Not allowed"; get_error_text({error, account_doesnt_exist}) -> "Account doesn't exist"; get_error_text({error, account_exists}) -> "The account was not deleted"; get_error_text({error, password_not_changed}) -> "The password was not changed"; get_error_text({error, passwords_not_identical}) -> "The passwords are different"; get_error_text({error, wrong_parameters}) -> "Wrong parameters in the web formulary". ejabberd-2.1.11/src/web/ejabberd_http.erl0000664000000000000000000010247712240230175015076 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_http.erl %%% Author : Alexey Shchepin %%% Purpose : %%% Created : 27 Feb 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_http). -author('alexey@process-one.net'). %% External exports -export([start/2, start_link/2, become_controller/1, socket_type/0, receive_headers/1, url_encode/1]). %% Callbacks -export([init/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("ejabberd_http.hrl"). -record(state, {sockmod, socket, request_method, request_version, request_path, request_auth, request_keepalive, request_content_length, request_lang = "en", %% XXX bard: request handlers are configured in %% ejabberd.cfg under the HTTP service. For example, %% to have the module test_web handle requests with %% paths starting with "/test/module": %% %% {5280, ejabberd_http, [http_poll, web_admin, %% {request_handlers, [{["test", "module"], mod_test_web}]}]} %% request_handlers = [], request_host, request_port, request_tp, request_headers = [], end_of_request = false, default_host, trail = <<>> }). -define(XHTML_DOCTYPE, "\n" "\n"). -define(HTML_DOCTYPE, "\n"). start(SockData, Opts) -> supervisor:start_child(ejabberd_http_sup, [SockData, Opts]). start_link(SockData, Opts) -> {ok, proc_lib:spawn_link(ejabberd_http, init, [SockData, Opts])}. init({SockMod, Socket}, Opts) -> TLSEnabled = lists:member(tls, Opts), TLSOpts1 = lists:filter(fun({certfile, _}) -> true; (_) -> false end, Opts), TLSOpts = [verify_none | TLSOpts1], {SockMod1, Socket1} = if TLSEnabled -> inet:setopts(Socket, [{recbuf, 8192}]), {ok, TLSSocket} = tls:tcp_to_tls(Socket, TLSOpts), {tls, TLSSocket}; true -> {SockMod, Socket} end, case SockMod1 of gen_tcp -> inet:setopts(Socket1, [{packet, http}, {recbuf, 8192}]); _ -> ok end, %% XXX bard: for backward compatibility, expand in Opts: %% web_admin -> {["admin"], ejabberd_web_admin} %% http_bind -> {["http-bind"], mod_http_bind} %% http_poll -> {["http-poll"], ejabberd_http_poll} %% register -> {["register"], mod_register_web} RequestHandlers = case lists:keysearch(request_handlers, 1, Opts) of {value, {request_handlers, H}} -> H; false -> [] end ++ case lists:member(captcha, Opts) of true -> [{["captcha"], ejabberd_captcha}]; false -> [] end ++ case lists:member(register, Opts) of true -> [{["register"], mod_register_web}]; false -> [] end ++ case lists:member(web_admin, Opts) of true -> [{["admin"], ejabberd_web_admin}]; false -> [] end ++ case lists:member(http_bind, Opts) of true -> [{["http-bind"], mod_http_bind}]; false -> [] end ++ case lists:member(http_poll, Opts) of true -> [{["http-poll"], ejabberd_http_poll}]; false -> [] end, ?DEBUG("S: ~p~n", [RequestHandlers]), DefaultHost = gen_mod:get_opt(default_host, Opts, undefined), ?INFO_MSG("started: ~p", [{SockMod1, Socket1}]), State = #state{sockmod = SockMod1, socket = Socket1, default_host = DefaultHost, request_handlers = RequestHandlers}, receive_headers(State). become_controller(_Pid) -> ok. socket_type() -> raw. send_text(State, Text) -> case catch (State#state.sockmod):send(State#state.socket, Text) of ok -> ok; {error, timeout} -> ?INFO_MSG("Timeout on ~p:send",[State#state.sockmod]), exit(normal); Error -> ?DEBUG("Error in ~p:send: ~p",[State#state.sockmod, Error]), exit(normal) end. receive_headers(#state{trail=Trail} = State) -> SockMod = State#state.sockmod, Socket = State#state.socket, Data = SockMod:recv(Socket, 0, 300000), case State#state.sockmod of gen_tcp -> NewState = process_header(State, Data), case NewState#state.end_of_request of true -> ok; _ -> receive_headers(NewState) end; _ -> case Data of {ok, D} -> parse_headers(State#state{trail = <>}); {error, _} -> ok end end. parse_headers(#state{trail = <<>>} = State) -> receive_headers(State); parse_headers(#state{request_method = Method, trail = Data} = State) -> PktType = case Method of undefined -> http; _ -> httph end, case decode_packet(PktType, Data) of {ok, Pkt, Rest} -> NewState = process_header(State#state{trail = Rest}, {ok, Pkt}), case NewState#state.end_of_request of true -> ok; _ -> parse_headers(NewState) end; {more, _} -> receive_headers(State#state{trail = Data}); _ -> ok end. process_header(State, Data) -> SockMod = State#state.sockmod, Socket = State#state.socket, case Data of {ok, {http_request, Method, Uri, Version}} -> KeepAlive = case Version of {1, 1} -> true; _ -> false end, Path = case Uri of {absoluteURI, _Scheme, _Host, _Port, P} -> {abs_path, P}; _ -> Uri end, State#state{request_method = Method, request_version = Version, request_path = Path, request_keepalive = KeepAlive}; {ok, {http_header, _, 'Connection'=Name, _, Conn}} -> KeepAlive1 = case jlib:tolower(Conn) of "keep-alive" -> true; "close" -> false; _ -> State#state.request_keepalive end, State#state{request_keepalive = KeepAlive1, request_headers=add_header(Name, Conn, State)}; {ok, {http_header, _, 'Authorization'=Name, _, Auth}} -> State#state{request_auth = parse_auth(Auth), request_headers=add_header(Name, Auth, State)}; {ok, {http_header, _, 'Content-Length'=Name, _, SLen}} -> case catch list_to_integer(SLen) of Len when is_integer(Len) -> State#state{request_content_length = Len, request_headers=add_header(Name, SLen, State)}; _ -> State end; {ok, {http_header, _, 'Accept-Language'=Name, _, Langs}} -> State#state{request_lang = parse_lang(Langs), request_headers=add_header(Name, Langs, State)}; {ok, {http_header, _, 'Host'=Name, _, Host}} -> State#state{request_host = Host, request_headers=add_header(Name, Host, State)}; {ok, {http_header, _, Name, _, Value}} -> State#state{request_headers=add_header(Name, Value, State)}; {ok, http_eoh} when State#state.request_host == undefined -> ?WARNING_MSG("An HTTP request without 'Host' HTTP header was received.", []), throw(http_request_no_host_header); {ok, http_eoh} -> ?DEBUG("(~w) http query: ~w ~s~n", [State#state.socket, State#state.request_method, element(2, State#state.request_path)]), {HostProvided, Port, TP} = get_transfer_protocol(SockMod, State#state.request_host), Host = get_host_really_served(State#state.default_host, HostProvided), State2 = State#state{request_host = Host, request_port = Port, request_tp = TP}, Out = process_request(State2), send_text(State2, Out), case State2#state.request_keepalive of true -> case SockMod of gen_tcp -> inet:setopts(Socket, [{packet, http}]); _ -> ok end, #state{sockmod = SockMod, socket = Socket, request_handlers = State#state.request_handlers}; _ -> #state{end_of_request = true, request_handlers = State#state.request_handlers} end; {error, _Reason} -> #state{end_of_request = true, request_handlers = State#state.request_handlers}; _ -> #state{end_of_request = true, request_handlers = State#state.request_handlers} end. add_header(Name, Value, State) -> [{Name, Value} | State#state.request_headers]. get_host_really_served(undefined, Provided) -> Provided; get_host_really_served(Default, Provided) -> case lists:member(Provided, ?MYHOSTS) of true -> Provided; false -> Default end. %% @spec (SockMod, HostPort) -> {Host::string(), Port::integer(), TP} %% where %% SockMod = gen_tcp | tls %% HostPort = string() %% TP = http | https %% @doc Given a socket and hostport header, return data of transfer protocol. %% Note that HostPort can be a string of a host like "example.org", %% or a string of a host and port like "example.org:5280". get_transfer_protocol(SockMod, HostPort) -> [Host | PortList] = string:tokens(HostPort, ":"), case {SockMod, PortList} of {gen_tcp, []} -> {Host, 80, http}; {gen_tcp, [Port]} -> {Host, list_to_integer(Port), http}; {tls, []} -> {Host, 443, https}; {tls, [Port]} -> {Host, list_to_integer(Port), https} end. %% XXX bard: search through request handlers looking for one that %% matches the requested URL path, and pass control to it. If none is %% found, answer with HTTP 404. process([], _) -> ejabberd_web:error(not_found); process(Handlers, Request) -> [{HandlerPathPrefix, HandlerModule} | HandlersLeft] = Handlers, case (lists:prefix(HandlerPathPrefix, Request#request.path) or (HandlerPathPrefix==Request#request.path)) of true -> ?DEBUG("~p matches ~p", [Request#request.path, HandlerPathPrefix]), %% LocalPath is the path "local to the handler", i.e. if %% the handler was registered to handle "/test/" and the %% requested path is "/test/foo/bar", the local path is %% ["foo", "bar"] LocalPath = lists:nthtail(length(HandlerPathPrefix), Request#request.path), R = HandlerModule:process(LocalPath, Request), ejabberd_hooks:run(http_request_debug, [{LocalPath, Request}]), R; false -> process(HandlersLeft, Request) end. process_request(#state{request_method = Method, request_path = {abs_path, Path}, request_auth = Auth, request_lang = Lang, request_handlers = RequestHandlers, request_host = Host, request_port = Port, request_tp = TP, request_headers = RequestHeaders, sockmod = SockMod, socket = Socket} = State) when Method=:='GET' orelse Method=:='HEAD' orelse Method=:='DELETE' orelse Method=:='OPTIONS' -> case (catch url_decode_q_split(Path)) of {'EXIT', _} -> make_bad_request(State); {NPath, Query} -> LPath = [path_decode(NPE) || NPE <- string:tokens(NPath, "/")], LQuery = case (catch parse_urlencoded(Query)) of {'EXIT', _Reason} -> []; LQ -> LQ end, {ok, IPHere} = case SockMod of gen_tcp -> inet:peername(Socket); _ -> SockMod:peername(Socket) end, XFF = proplists:get_value('X-Forwarded-For', RequestHeaders, []), IP = analyze_ip_xff(IPHere, XFF, Host), Request = #request{method = Method, path = LPath, q = LQuery, auth = Auth, lang = Lang, host = Host, port = Port, tp = TP, headers = RequestHeaders, ip = IP}, %% XXX bard: This previously passed control to %% ejabberd_web:process_get, now passes it to a local %% procedure (process) that handles dispatching based on %% URL path prefix. case process(RequestHandlers, Request) of El when element(1, El) == xmlelement -> make_xhtml_output(State, 200, [], El); {Status, Headers, El} when element(1, El) == xmlelement -> make_xhtml_output(State, Status, Headers, El); Output when is_list(Output) or is_binary(Output) -> make_text_output(State, 200, [], Output); {Status, Headers, Output} when is_list(Output) or is_binary(Output) -> make_text_output(State, Status, Headers, Output) end end; process_request(#state{request_method = Method, request_path = {abs_path, Path}, request_auth = Auth, request_content_length = Len, request_lang = Lang, sockmod = SockMod, socket = Socket, request_host = Host, request_port = Port, request_tp = TP, request_headers = RequestHeaders, request_handlers = RequestHandlers} = State) when (Method=:='POST' orelse Method=:='PUT') andalso is_integer(Len) -> {ok, IPHere} = case SockMod of gen_tcp -> inet:peername(Socket); _ -> SockMod:peername(Socket) end, XFF = proplists:get_value('X-Forwarded-For', RequestHeaders, []), IP = analyze_ip_xff(IPHere, XFF, Host), case SockMod of gen_tcp -> inet:setopts(Socket, [{packet, 0}]); _ -> ok end, Data = recv_data(State, Len), ?DEBUG("client data: ~p~n", [Data]), case (catch url_decode_q_split(Path)) of {'EXIT', _} -> make_bad_request(State); {NPath, _Query} -> LPath = [path_decode(NPE) || NPE <- string:tokens(NPath, "/")], LQuery = case (catch parse_urlencoded(Data)) of {'EXIT', _Reason} -> []; LQ -> LQ end, Request = #request{method = Method, path = LPath, q = LQuery, auth = Auth, data = Data, lang = Lang, host = Host, port = Port, tp = TP, headers = RequestHeaders, ip = IP}, case process(RequestHandlers, Request) of El when element(1, El) == xmlelement -> make_xhtml_output(State, 200, [], El); {Status, Headers, El} when element(1, El) == xmlelement -> make_xhtml_output(State, Status, Headers, El); Output when is_list(Output) or is_binary(Output) -> make_text_output(State, 200, [], Output); {Status, Headers, Output} when is_list(Output) or is_binary(Output) -> make_text_output(State, Status, Headers, Output) end end; process_request(State) -> make_bad_request(State). make_bad_request(State) -> make_xhtml_output(State, 400, [], ejabberd_web:make_xhtml([{xmlelement, "h1", [], [{xmlcdata, "400 Bad Request"}]}])). %% Support for X-Forwarded-From analyze_ip_xff(IP, [], _Host) -> IP; analyze_ip_xff({IPLast, Port}, XFF, Host) -> [ClientIP | ProxiesIPs] = string:tokens(XFF, ", ") ++ [inet_parse:ntoa(IPLast)], TrustedProxies = case ejabberd_config:get_local_option( {trusted_proxies, Host}) of undefined -> []; TPs -> TPs end, IPClient = case is_ipchain_trusted(ProxiesIPs, TrustedProxies) of true -> {ok, IPFirst} = inet_parse:address(ClientIP), ?DEBUG("The IP ~w was replaced with ~w due to header " "X-Forwarded-For: ~s", [IPLast, IPFirst, XFF]), IPFirst; false -> IPLast end, {IPClient, Port}. is_ipchain_trusted(_UserIPs, all) -> true; is_ipchain_trusted(UserIPs, TrustedIPs) -> [] == UserIPs -- ["127.0.0.1" | TrustedIPs]. recv_data(State, Len) -> recv_data(State, Len, []). recv_data(_State, 0, Acc) -> binary_to_list(list_to_binary(Acc)); recv_data(State, Len, Acc) -> case State#state.trail of <<>> -> case (State#state.sockmod):recv(State#state.socket, Len, 300000) of {ok, Data} -> recv_data(State, Len - size(Data), [Acc | [Data]]); _ -> "" end; _ -> Trail = binary_to_list(State#state.trail), recv_data(State#state{trail = <<>>}, Len - length(Trail), [Acc | Trail]) end. make_xhtml_output(State, Status, Headers, XHTML) -> Data = case lists:member(html, Headers) of true -> list_to_binary([?HTML_DOCTYPE, element_to_string(XHTML)]); _ -> list_to_binary([?XHTML_DOCTYPE, element_to_string(XHTML)]) end, Headers1 = case lists:keysearch("Content-Type", 1, Headers) of {value, _} -> [{"Content-Length", integer_to_list(size(Data))} | Headers]; _ -> [{"Content-Type", "text/html; charset=utf-8"}, {"Content-Length", integer_to_list(size(Data))} | Headers] end, HeadersOut = case {State#state.request_version, State#state.request_keepalive} of {{1, 1}, true} -> Headers1; {_, true} -> [{"Connection", "keep-alive"} | Headers1]; {_, false} -> % not required for http versions < 1.1 % but would make no harm [{"Connection", "close"} | Headers1] end, Version = case State#state.request_version of {1, 1} -> "HTTP/1.1 "; _ -> "HTTP/1.0 " end, H = lists:map(fun({Attr, Val}) -> [Attr, ": ", Val, "\r\n"]; (_) -> [] end, HeadersOut), SL = [Version, integer_to_list(Status), " ", code_to_phrase(Status), "\r\n"], Data2 = case State#state.request_method of 'HEAD' -> ""; _ -> Data end, [SL, H, "\r\n", Data2]. make_text_output(State, Status, Headers, Text) when is_list(Text) -> make_text_output(State, Status, Headers, list_to_binary(Text)); make_text_output(State, Status, Headers, Data) when is_binary(Data) -> Headers1 = case lists:keysearch("Content-Type", 1, Headers) of {value, _} -> [{"Content-Length", integer_to_list(size(Data))} | Headers]; _ -> [{"Content-Type", "text/html; charset=utf-8"}, {"Content-Length", integer_to_list(size(Data))} | Headers] end, HeadersOut = case {State#state.request_version, State#state.request_keepalive} of {{1, 1}, true} -> Headers1; {_, true} -> [{"Connection", "keep-alive"} | Headers1]; {_, false} -> % not required for http versions < 1.1 % but would make no harm [{"Connection", "close"} | Headers1] end, Version = case State#state.request_version of {1, 1} -> "HTTP/1.1 "; _ -> "HTTP/1.0 " end, H = lists:map(fun({Attr, Val}) -> [Attr, ": ", Val, "\r\n"] end, HeadersOut), SL = [Version, integer_to_list(Status), " ", code_to_phrase(Status), "\r\n"], Data2 = case State#state.request_method of 'HEAD' -> ""; _ -> Data end, [SL, H, "\r\n", Data2]. parse_lang(Langs) -> case string:tokens(Langs, ",; ") of [First | _] -> First; [] -> "en" end. element_to_string(El) -> case El of {xmlelement, Name, Attrs, Els} -> if Els /= [] -> [$<, Name, attrs_to_list(Attrs), $>, [element_to_string(E) || E <- Els], $<, $/, Name, $>]; true -> [$<, Name, attrs_to_list(Attrs), $/, $>] end; {xmlcdata, CData} -> crypt(CData) end. attrs_to_list(Attrs) -> [attr_to_list(A) || A <- Attrs]. attr_to_list({Name, Value}) -> [$\s, crypt(Name), $=, $", crypt(Value), $"]. crypt(S) when is_list(S) -> [case C of $& -> "&"; $< -> "<"; $> -> ">"; $" -> """; $' -> "'"; _ -> C end || C <- S]; crypt(S) when is_binary(S) -> crypt(binary_to_list(S)). % Code below is taken (with some modifications) from the yaws webserver, which % is distributed under the folowing license: % % This software (the yaws webserver) is free software. % Parts of this software is Copyright (c) Claes Wikstrom % Any use or misuse of the source code is hereby freely allowed. % % 1. Redistributions of source code must retain the above copyright % notice as well as this list of conditions. % % 2. Redistributions in binary form must reproduce the above copyright % notice as well as this list of conditions. %% @doc Split the URL and return {Path, QueryPart} url_decode_q_split(Path) -> url_decode_q_split(Path, []). url_decode_q_split([$?|T], Ack) -> %% Don't decode the query string here, that is parsed separately. {path_norm_reverse(Ack), T}; url_decode_q_split([H|T], Ack) when H /= 0 -> url_decode_q_split(T, [H|Ack]); url_decode_q_split([], Ack) -> {path_norm_reverse(Ack), []}. %% @doc Decode a part of the URL and return string() path_decode(Path) -> path_decode(Path, []). path_decode([$%, Hi, Lo | Tail], Ack) -> Hex = hex_to_integer([Hi, Lo]), if Hex == 0 -> exit(badurl); true -> ok end, path_decode(Tail, [Hex|Ack]); path_decode([H|T], Ack) when H /= 0 -> path_decode(T, [H|Ack]); path_decode([], Ack) -> lists:reverse(Ack). path_norm_reverse("/" ++ T) -> start_dir(0, "/", T); path_norm_reverse( T) -> start_dir(0, "", T). start_dir(N, Path, ".." ) -> rest_dir(N, Path, ""); start_dir(N, Path, "/" ++ T ) -> start_dir(N , Path, T); start_dir(N, Path, "./" ++ T ) -> start_dir(N , Path, T); start_dir(N, Path, "../" ++ T ) -> start_dir(N + 1, Path, T); start_dir(N, Path, T ) -> rest_dir (N , Path, T). rest_dir (_N, Path, [] ) -> case Path of [] -> "/"; _ -> Path end; rest_dir (0, Path, [ $/ | T ] ) -> start_dir(0 , [ $/ | Path ], T); rest_dir (N, Path, [ $/ | T ] ) -> start_dir(N - 1, Path , T); rest_dir (0, Path, [ H | T ] ) -> rest_dir (0 , [ H | Path ], T); rest_dir (N, Path, [ _H | T ] ) -> rest_dir (N , Path , T). %% hex_to_integer hex_to_integer(Hex) -> case catch erlang:list_to_integer(Hex, 16) of {'EXIT', _} -> old_hex_to_integer(Hex); X -> X end. old_hex_to_integer(Hex) -> DEHEX = fun (H) when H >= $a, H =< $f -> H - $a + 10; (H) when H >= $A, H =< $F -> H - $A + 10; (H) when H >= $0, H =< $9 -> H - $0 end, lists:foldl(fun(E, Acc) -> Acc*16+DEHEX(E) end, 0, Hex). code_to_phrase(100) -> "Continue"; code_to_phrase(101) -> "Switching Protocols "; code_to_phrase(200) -> "OK"; code_to_phrase(201) -> "Created"; code_to_phrase(202) -> "Accepted"; code_to_phrase(203) -> "Non-Authoritative Information"; code_to_phrase(204) -> "No Content"; code_to_phrase(205) -> "Reset Content"; code_to_phrase(206) -> "Partial Content"; code_to_phrase(300) -> "Multiple Choices"; code_to_phrase(301) -> "Moved Permanently"; code_to_phrase(302) -> "Found"; code_to_phrase(303) -> "See Other"; code_to_phrase(304) -> "Not Modified"; code_to_phrase(305) -> "Use Proxy"; code_to_phrase(306) -> "(Unused)"; code_to_phrase(307) -> "Temporary Redirect"; code_to_phrase(400) -> "Bad Request"; code_to_phrase(401) -> "Unauthorized"; code_to_phrase(402) -> "Payment Required"; code_to_phrase(403) -> "Forbidden"; code_to_phrase(404) -> "Not Found"; code_to_phrase(405) -> "Method Not Allowed"; code_to_phrase(406) -> "Not Acceptable"; code_to_phrase(407) -> "Proxy Authentication Required"; code_to_phrase(408) -> "Request Timeout"; code_to_phrase(409) -> "Conflict"; code_to_phrase(410) -> "Gone"; code_to_phrase(411) -> "Length Required"; code_to_phrase(412) -> "Precondition Failed"; code_to_phrase(413) -> "Request Entity Too Large"; code_to_phrase(414) -> "Request-URI Too Long"; code_to_phrase(415) -> "Unsupported Media Type"; code_to_phrase(416) -> "Requested Range Not Satisfiable"; code_to_phrase(417) -> "Expectation Failed"; code_to_phrase(500) -> "Internal Server Error"; code_to_phrase(501) -> "Not Implemented"; code_to_phrase(502) -> "Bad Gateway"; code_to_phrase(503) -> "Service Unavailable"; code_to_phrase(504) -> "Gateway Timeout"; code_to_phrase(505) -> "HTTP Version Not Supported". parse_auth(_Orig = "Basic " ++ Auth64) -> case decode_base64(Auth64) of {error, _Err} -> undefined; Auth -> %% Auth should be a string with the format: user@server:password %% Note that password can contain additional characters '@' and ':' case string:chr(Auth, $:) of 0 -> undefined; SplitIndex -> {User, [$: | Pass]} = lists:split(SplitIndex-1, Auth), {User, Pass} end end; parse_auth(_) -> undefined. decode_base64([]) -> []; decode_base64([Sextet1,Sextet2,$=,$=|Rest]) -> Bits2x6= (d(Sextet1) bsl 18) bor (d(Sextet2) bsl 12), Octet1=Bits2x6 bsr 16, [Octet1|decode_base64(Rest)]; decode_base64([Sextet1,Sextet2,Sextet3,$=|Rest]) -> Bits3x6= (d(Sextet1) bsl 18) bor (d(Sextet2) bsl 12) bor (d(Sextet3) bsl 6), Octet1=Bits3x6 bsr 16, Octet2=(Bits3x6 bsr 8) band 16#ff, [Octet1,Octet2|decode_base64(Rest)]; decode_base64([Sextet1,Sextet2,Sextet3,Sextet4|Rest]) -> Bits4x6= (d(Sextet1) bsl 18) bor (d(Sextet2) bsl 12) bor (d(Sextet3) bsl 6) bor d(Sextet4), Octet1=Bits4x6 bsr 16, Octet2=(Bits4x6 bsr 8) band 16#ff, Octet3=Bits4x6 band 16#ff, [Octet1,Octet2,Octet3|decode_base64(Rest)]; decode_base64(_CatchAll) -> {error, bad_base64}. d(X) when X >= $A, X =<$Z -> X-65; d(X) when X >= $a, X =<$z -> X-71; d(X) when X >= $0, X =<$9 -> X+4; d($+) -> 62; d($/) -> 63; d(_) -> 63. parse_urlencoded(S) -> parse_urlencoded(S, nokey, [], key). parse_urlencoded([$%, Hi, Lo | Tail], Last, Cur, State) -> Hex = hex_to_integer([Hi, Lo]), parse_urlencoded(Tail, Last, [Hex | Cur], State); parse_urlencoded([$& | Tail], _Last, Cur, key) -> [{lists:reverse(Cur), ""} | parse_urlencoded(Tail, nokey, [], key)]; %% cont keymode parse_urlencoded([$& | Tail], Last, Cur, value) -> V = {Last, lists:reverse(Cur)}, [V | parse_urlencoded(Tail, nokey, [], key)]; parse_urlencoded([$+ | Tail], Last, Cur, State) -> parse_urlencoded(Tail, Last, [$\s | Cur], State); parse_urlencoded([$= | Tail], _Last, Cur, key) -> parse_urlencoded(Tail, lists:reverse(Cur), [], value); %% change mode parse_urlencoded([H | Tail], Last, Cur, State) -> parse_urlencoded(Tail, Last, [H|Cur], State); parse_urlencoded([], Last, Cur, _State) -> [{Last, lists:reverse(Cur)}]; parse_urlencoded(undefined, _, _, _) -> []. url_encode([H|T]) -> if H >= $a, $z >= H -> [H|url_encode(T)]; H >= $A, $Z >= H -> [H|url_encode(T)]; H >= $0, $9 >= H -> [H|url_encode(T)]; H == $_; H == $.; H == $-; H == $/; H == $: -> % FIXME: more.. [H|url_encode(T)]; true -> case integer_to_hex(H) of [X, Y] -> [$%, X, Y | url_encode(T)]; [X] -> [$%, $0, X | url_encode(T)] end end; url_encode([]) -> []. integer_to_hex(I) -> case catch erlang:integer_to_list(I, 16) of {'EXIT', _} -> old_integer_to_hex(I); Int -> Int end. old_integer_to_hex(I) when I<10 -> integer_to_list(I); old_integer_to_hex(I) when I<16 -> [I-10+$A]; old_integer_to_hex(I) when I>=16 -> N = trunc(I/16), old_integer_to_hex(N) ++ old_integer_to_hex(I rem 16). % The following code is mostly taken from yaws_ssl.erl extract_line(_, <<>>, _) -> none; extract_line(0, <<"\r", Rest/binary>>, Line) -> extract_line(1, Rest, Line); extract_line(0, <>, Line) -> extract_line(0, Rest, <>); extract_line(1, <<"\n", Rest/binary>>, Line) -> {Line, Rest}; extract_line(1, Data, Line) -> extract_line(0, Data, <>). decode_packet(_, <<"\r\n", Rest/binary>>) -> {ok, http_eoh, Rest}; decode_packet(Type, Data) -> case extract_line(0, Data, <<>>) of {LineB, Rest} -> Line = binary_to_list(LineB), Result = case Type of http -> parse_req(Line); httph -> parse_header_line(Line) end, case Result of {ok, H} -> {ok, H, Rest}; Err -> {error, Err} end; _ -> {more, undefined} end. get_word(Line)-> {Word, T} = lists:splitwith(fun(X)-> X /= $\ end, Line), {Word, lists:dropwhile(fun(X) -> X == $\ end, T)}. parse_req(Line) -> {MethodStr, L1} = get_word(Line), ?DEBUG("Method: ~p~n", [MethodStr]), case L1 of [] -> bad_request; _ -> {URI, L2} = get_word(L1), {VersionStr, L3} = get_word(L2), ?DEBUG("URI: ~p~nVersion: ~p~nL3: ~p~n", [URI, VersionStr, L3]), case L3 of [] -> Method = case MethodStr of "GET" -> 'GET'; "POST" -> 'POST'; "HEAD" -> 'HEAD'; "OPTIONS" -> 'OPTIONS'; "TRACE" -> 'TRACE'; "PUT" -> 'PUT'; "DELETE" -> 'DELETE'; S -> S end, Path = case URI of "*" -> % Is this correct? "*"; _ -> case string:str(URI, "://") of 0 -> % Relative URI % ex: /index.html {abs_path, URI}; N -> % Absolute URI % ex: http://localhost/index.html % Remove scheme % ex: URI2 = localhost/index.html URI2 = string:substr(URI, N + 3), % Look for the start of the path % (or the lack of a path thereof) case string:chr(URI2, $/) of 0 -> {abs_path, "/"}; M -> {abs_path, string:substr(URI2, M + 1)} end end end, case VersionStr of [] -> {ok, {http_request, Method, Path, {0,9}}}; "HTTP/1.0" -> {ok, {http_request, Method, Path, {1,0}}}; "HTTP/1.1" -> {ok, {http_request, Method, Path, {1,1}}}; _ -> bad_request end; _ -> bad_request end end. toupper(C) when C >= $a andalso C =< $z -> C - 32; toupper(C) -> C. tolower(C) when C >= $A andalso C =< $Z -> C + 32; tolower(C) -> C. parse_header_line(Line) -> parse_header_line(Line, "", true). parse_header_line("", _, _) -> bad_request; parse_header_line(":" ++ Rest, Name, _) -> encode_header(lists:reverse(Name), Rest); parse_header_line("-" ++ Rest, Name, _) -> parse_header_line(Rest, "-" ++ Name, true); parse_header_line([C | Rest], Name, true) -> parse_header_line(Rest, [toupper(C) | Name], false); parse_header_line([C | Rest], Name, false) -> parse_header_line(Rest, [tolower(C) | Name], false). encode_header("Connection", Con) -> {ok, {http_header, undefined, 'Connection', undefined, strip_spaces(Con)}}; encode_header("Host", Con) -> {ok, {http_header, undefined, 'Host', undefined, strip_spaces(Con)}}; encode_header("Accept", Con) -> {ok, {http_header, undefined, 'Accept', undefined, strip_spaces(Con)}}; encode_header("If-Modified-Since", Con) -> {ok, {http_header, undefined, 'If-Modified-Since', undefined, strip_spaces(Con)}}; encode_header("If-Match", Con) -> {ok, {http_header, undefined, 'If-Match', undefined, strip_spaces(Con)}}; encode_header("If-None-Match", Con) -> {ok, {http_header, undefined, 'If-None-Match', undefined, strip_spaces(Con)}}; encode_header("If-Range", Con) -> {ok, {http_header, undefined, 'If-Range', undefined, strip_spaces(Con)}}; encode_header("If-Unmodified-Since", Con) -> {ok, {http_header, undefined, 'If-Unmodified-Since', undefined, strip_spaces(Con)}}; encode_header("Range", Con) -> {ok, {http_header, undefined, 'Range', undefined, strip_spaces(Con)}}; encode_header("User-Agent", Con) -> {ok, {http_header, undefined, 'User-Agent', undefined, strip_spaces(Con)}}; encode_header("Accept-Ranges", Con) -> {ok, {http_header, undefined, 'Accept-Ranges', undefined, strip_spaces(Con)}}; encode_header("Authorization", Con) -> {ok, {http_header, undefined, 'Authorization', undefined, strip_spaces(Con)}}; encode_header("Keep-Alive", Con) -> {ok, {http_header, undefined, 'Keep-Alive', undefined, strip_spaces(Con)}}; encode_header("Referer", Con) -> {ok, {http_header, undefined, 'Referer', undefined, strip_spaces(Con)}}; encode_header("Content-Type", Con) -> {ok, {http_header, undefined, 'Content-Type', undefined, strip_spaces(Con)}}; encode_header("Content-Length", Con) -> {ok, {http_header, undefined, 'Content-Length', undefined, strip_spaces(Con)}}; encode_header("Cookie", Con) -> {ok, {http_header, undefined, 'Cookie', undefined, strip_spaces(Con)}}; encode_header("Accept-Language", Con) -> {ok, {http_header, undefined, 'Accept-Language', undefined, strip_spaces(Con)}}; encode_header("Accept-Encoding", Con) -> {ok, {http_header, undefined, 'Accept-Encoding', undefined, strip_spaces(Con)}}; encode_header(Name, Val) -> {ok, {http_header, undefined, Name, undefined, strip_spaces(Val)}}. is_space($\s) -> true; is_space($\r) -> true; is_space($\n) -> true; is_space($\t) -> true; is_space(_) -> false. strip_spaces(String) -> strip_spaces(String, both). %% strip_spaces(String, left) -> %% drop_spaces(String); strip_spaces(String, right) -> lists:reverse(drop_spaces(lists:reverse(String))); strip_spaces(String, both) -> strip_spaces(drop_spaces(String), right). drop_spaces([]) -> []; drop_spaces(YS=[X|XS]) -> case is_space(X) of true -> drop_spaces(XS); false -> YS end. ejabberd-2.1.11/src/web/mod_http_bind.erl0000664000000000000000000001144212240230175015102 0ustar %%%---------------------------------------------------------------------- %%% File : mod_http_bind.erl %%% Author : Stefan Strigler %%% Purpose : Implementation of XMPP over BOSH (XEP-0206) %%% Created : Tue Feb 20 13:15:52 CET 2007 %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %%%---------------------------------------------------------------------- %%% This module acts as a bridge to ejabberd_http_bind which implements %%% the real stuff, this is to handle the new pluggable architecture for %%% extending ejabberd's http service. %%%---------------------------------------------------------------------- -module(mod_http_bind). -author('steve@zeank.in-berlin.de'). %%-define(ejabberd_debug, true). -behaviour(gen_mod). -export([ start/2, stop/1, process/2 ]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("ejabberd_http.hrl"). -include("http_bind.hrl"). -define(PROCNAME_MHB, ejabberd_mod_http_bind). %% Duplicated from ejabberd_http_bind. %% TODO: move to hrl file. -record(http_bind, {id, pid, to, hold, wait, process_delay, version}). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- process([], #request{method = 'POST', data = []}) -> ?DEBUG("Bad Request: no data", []), {400, ?HEADER, {xmlelement, "h1", [], [{xmlcdata, "400 Bad Request"}]}}; process([], #request{method = 'POST', data = Data, ip = IP}) -> ?DEBUG("Incoming data: ~s", [Data]), ejabberd_http_bind:process_request(Data, IP); process([], #request{method = 'GET', data = []}) -> {200, ?HEADER, get_human_html_xmlel()}; process([], #request{method = 'OPTIONS', data = []}) -> {200, ?OPTIONS_HEADER, []}; process([], #request{method = 'HEAD'}) -> {200, ?HEADER, []}; process(_Path, _Request) -> ?DEBUG("Bad Request: ~p", [_Request]), {400, ?HEADER, {xmlelement, "h1", [], [{xmlcdata, "400 Bad Request"}]}}. get_human_html_xmlel() -> Heading = "ejabberd " ++ atom_to_list(?MODULE), {xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"}], [{xmlelement, "head", [], [{xmlelement, "title", [], [{xmlcdata, Heading}]}]}, {xmlelement, "body", [], [{xmlelement, "h1", [], [{xmlcdata, Heading}]}, {xmlelement, "p", [], [{xmlcdata, "An implementation of "}, {xmlelement, "a", [{"href", "http://xmpp.org/extensions/xep-0206.html"}], [{xmlcdata, "XMPP over BOSH (XEP-0206)"}]}]}, {xmlelement, "p", [], [{xmlcdata, "This web page is only informative. " "To use HTTP-Bind you need a Jabber/XMPP client that supports it."} ]} ]}]}. %%%---------------------------------------------------------------------- %%% BEHAVIOUR CALLBACKS %%%---------------------------------------------------------------------- start(Host, _Opts) -> setup_database(), Proc = gen_mod:get_module_proc(Host, ?PROCNAME_MHB), ChildSpec = {Proc, {ejabberd_tmp_sup, start_link, [Proc, ejabberd_http_bind]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME_MHB), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). setup_database() -> migrate_database(), mnesia:create_table(http_bind, [{ram_copies, [node()]}, {attributes, record_info(fields, http_bind)}]). migrate_database() -> case catch mnesia:table_info(http_bind, attributes) of [id, pid, to, hold, wait, process_delay, version] -> ok; _ -> %% Since the stored information is not important, instead %% of actually migrating data, let's just destroy the table mnesia:delete_table(http_bind) end. ejabberd-2.1.11/src/web/http_bind.hrl0000664000000000000000000000277712240230175014261 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -define(CT_XML, {"Content-Type", "text/xml; charset=utf-8"}). -define(CT_PLAIN, {"Content-Type", "text/plain"}). -define(AC_ALLOW_ORIGIN, {"Access-Control-Allow-Origin", "*"}). -define(AC_ALLOW_METHODS, {"Access-Control-Allow-Methods", "GET, POST, OPTIONS"}). -define(AC_ALLOW_HEADERS, {"Access-Control-Allow-Headers", "Content-Type"}). -define(AC_MAX_AGE, {"Access-Control-Max-Age", "86400"}). -define(OPTIONS_HEADER, [?CT_PLAIN, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_METHODS, ?AC_ALLOW_HEADERS, ?AC_MAX_AGE]). -define(HEADER, [?CT_XML, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_HEADERS]). ejabberd-2.1.11/src/web/ejabberd_http_bind.erl0000664000000000000000000011737412240230175016074 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_http_bind.erl %%% Author : Stefan Strigler %%% Purpose : Implements XMPP over BOSH (XEP-0206) (formerly known as %%% HTTP Binding) %%% Created : 21 Sep 2005 by Stefan Strigler %%% Modified: may 2009 by Mickael Remond, Alexey Schepin %%% Id : $Id: ejabberd_http_bind.erl 953 2009-05-07 10:40:40Z alexey $ %%%---------------------------------------------------------------------- -module(ejabberd_http_bind). -behaviour(gen_fsm). %% External exports -export([start_link/3, init/1, handle_event/3, handle_sync_event/4, code_change/4, handle_info/3, terminate/3, send/2, send_xml/2, sockname/1, peername/1, setopts/2, controlling_process/2, become_controller/2, custom_receiver/1, reset_stream/1, change_shaper/2, monitor/1, close/1, start/4, handle_session_start/8, handle_http_put/7, http_put/7, http_get/2, prepare_response/4, process_request/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("ejabberd_http.hrl"). -include("http_bind.hrl"). -record(http_bind, {id, pid, to, hold, wait, process_delay, version}). -define(NULL_PEER, {{0, 0, 0, 0}, 0}). %% http binding request -record(hbr, {rid, key, out}). -record(state, {id, rid = none, key, socket, output = "", input = queue:new(), waiting_input = false, shaper_state, shaper_timer, last_receiver, last_poll, http_receiver, wait_timer, ctime = 0, timer, pause=0, unprocessed_req_list = [], % list of request that have been delayed for proper reordering: {Request, PID} req_list = [], % list of requests (cache) max_inactivity, max_pause, ip = ?NULL_PEER }). %% Internal request format: -record(http_put, {rid, attrs, payload, payload_size, hold, stream, ip}). %%-define(DBGFSM, true). -ifdef(DBGFSM). -define(FSMOPTS, [{debug, [trace]}]). -else. -define(FSMOPTS, []). -endif. -define(BOSH_VERSION, "1.8"). -define(NS_CLIENT, "jabber:client"). -define(NS_BOSH, "urn:xmpp:xbosh"). -define(NS_HTTP_BIND, "http://jabber.org/protocol/httpbind"). -define(MAX_REQUESTS, 2). % number of simultaneous requests -define(MIN_POLLING, 2000000). % don't poll faster than that or we will % shoot you (time in microsec) -define(MAX_WAIT, 3600). % max num of secs to keep a request on hold -define(MAX_INACTIVITY, 30000). % msecs to wait before terminating % idle sessions -define(MAX_PAUSE, 120). % may num of sec a client is allowed to pause % the session %% Wait 100ms before continue processing, to allow the client provide more related stanzas. -define(PROCESS_DELAY_DEFAULT, 100). -define(PROCESS_DELAY_MIN, 0). -define(PROCESS_DELAY_MAX, 1000). %% Line copied from mod_http_bind.erl -define(PROCNAME_MHB, ejabberd_mod_http_bind). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- %% TODO: If compile with no supervisor option, start the session without %% supervisor start(XMPPDomain, Sid, Key, IP) -> ?DEBUG("Starting session", []), SupervisorProc = gen_mod:get_module_proc(XMPPDomain, ?PROCNAME_MHB), case catch supervisor:start_child(SupervisorProc, [Sid, Key, IP]) of {ok, Pid} -> {ok, Pid}; _ -> check_bind_module(XMPPDomain), {error, "Cannot start HTTP bind session"} end. start_link(Sid, Key, IP) -> gen_fsm:start_link(?MODULE, [Sid, Key, IP], ?FSMOPTS). send({http_bind, FsmRef, _IP}, Packet) -> gen_fsm:sync_send_all_state_event(FsmRef, {send, Packet}). send_xml({http_bind, FsmRef, _IP}, Packet) -> gen_fsm:sync_send_all_state_event(FsmRef, {send_xml, Packet}). setopts({http_bind, FsmRef, _IP}, Opts) -> case lists:member({active, once}, Opts) of true -> gen_fsm:send_all_state_event(FsmRef, {activate, self()}); _ -> ok end. controlling_process(_Socket, _Pid) -> ok. custom_receiver({http_bind, FsmRef, _IP}) -> {receiver, ?MODULE, FsmRef}. become_controller(FsmRef, C2SPid) -> gen_fsm:send_all_state_event(FsmRef, {become_controller, C2SPid}). reset_stream({http_bind, _FsmRef, _IP}) -> ok. change_shaper({http_bind, FsmRef, _IP}, Shaper) -> gen_fsm:send_all_state_event(FsmRef, {change_shaper, Shaper}). monitor({http_bind, FsmRef, _IP}) -> erlang:monitor(process, FsmRef). close({http_bind, FsmRef, _IP}) -> catch gen_fsm:sync_send_all_state_event(FsmRef, {stop, close}). sockname(_Socket) -> {ok, ?NULL_PEER}. peername({http_bind, _FsmRef, IP}) -> {ok, IP}. %% Entry point for data coming from client through ejabberd HTTP server: process_request(Data, IP) -> Opts1 = ejabberd_c2s_config:get_c2s_limits(), Opts = [{xml_socket, true} | Opts1], MaxStanzaSize = case lists:keysearch(max_stanza_size, 1, Opts) of {value, {_, Size}} -> Size; _ -> infinity end, PayloadSize = iolist_size(Data), case catch parse_request(Data, PayloadSize, MaxStanzaSize) of %% No existing session: {ok, {"", Rid, Attrs, Payload}} -> case xml:get_attr_s("to",Attrs) of "" -> ?DEBUG("Session not created (Improper addressing)", []), {200, ?HEADER, ""}; XmppDomain -> %% create new session Sid = sha:sha(term_to_binary({now(), make_ref()})), case start(XmppDomain, Sid, "", IP) of {error, _} -> {200, ?HEADER, "BOSH module not started"}; {ok, Pid} -> handle_session_start( Pid, XmppDomain, Sid, Rid, Attrs, Payload, PayloadSize, IP) end end; %% Existing session {ok, {Sid, Rid, Attrs, Payload1}} -> StreamStart = case xml:get_attr_s("xmpp:restart",Attrs) of "true" -> true; _ -> false end, Payload2 = case xml:get_attr_s("type",Attrs) of "terminate" -> %% close stream Payload1 ++ [{xmlstreamend, "stream:stream"}]; _ -> Payload1 end, handle_http_put(Sid, Rid, Attrs, Payload2, PayloadSize, StreamStart, IP); {size_limit, Sid} -> case mnesia:dirty_read({http_bind, Sid}) of [] -> {404, ?HEADER, ""}; [#http_bind{pid = FsmRef}] -> gen_fsm:sync_send_all_state_event(FsmRef, {stop, close}), {200, ?HEADER, "Request Too Large"} end; _ -> ?DEBUG("Received bad request: ~p", [Data]), {400, ?HEADER, ""} end. handle_session_start(Pid, XmppDomain, Sid, Rid, Attrs, Payload, PayloadSize, IP) -> ?DEBUG("got pid: ~p", [Pid]), Wait = case string:to_integer(xml:get_attr_s("wait",Attrs)) of {error, _} -> ?MAX_WAIT; {CWait, _} -> if (CWait > ?MAX_WAIT) -> ?MAX_WAIT; true -> CWait end end, Hold = case string:to_integer(xml:get_attr_s("hold",Attrs)) of {error, _} -> (?MAX_REQUESTS - 1); {CHold, _} -> if (CHold > (?MAX_REQUESTS - 1)) -> (?MAX_REQUESTS - 1); true -> CHold end end, Pdelay = case string:to_integer(xml:get_attr_s("process-delay",Attrs)) of {error, _} -> ?PROCESS_DELAY_DEFAULT; {CPdelay, _} when (?PROCESS_DELAY_MIN =< CPdelay) and (CPdelay =< ?PROCESS_DELAY_MAX) -> CPdelay; {CPdelay, _} -> lists:max([lists:min([CPdelay, ?PROCESS_DELAY_MAX]), ?PROCESS_DELAY_MIN]) end, Version = case catch list_to_float( xml:get_attr_s("ver", Attrs)) of {'EXIT', _} -> 0.0; V -> V end, XmppVersion = xml:get_attr_s("xmpp:version", Attrs), ?DEBUG("Create session: ~p", [Sid]), mnesia:dirty_write( #http_bind{id = Sid, pid = Pid, to = {XmppDomain, XmppVersion}, hold = Hold, wait = Wait, process_delay = Pdelay, version = Version }), handle_http_put(Sid, Rid, Attrs, Payload, PayloadSize, true, IP). %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, StateName, StateData} | %% {ok, StateName, StateData, Timeout} | %% ignore | %% {stop, StopReason} %%---------------------------------------------------------------------- init([Sid, Key, IP]) -> ?DEBUG("started: ~p", [{Sid, Key, IP}]), %% Read c2s options from the first ejabberd_c2s configuration in %% the config file listen section %% TODO: We should have different access and shaper values for %% each connector. The default behaviour should be however to use %% the default c2s restrictions if not defined for the current %% connector. Opts1 = ejabberd_c2s_config:get_c2s_limits(), Opts = [{xml_socket, true} | Opts1], Shaper = none, ShaperState = shaper:new(Shaper), Socket = {http_bind, self(), IP}, ejabberd_socket:start(ejabberd_c2s, ?MODULE, Socket, Opts), Timer = erlang:start_timer(?MAX_INACTIVITY, self(), []), {ok, loop, #state{id = Sid, key = Key, socket = Socket, shaper_state = ShaperState, max_inactivity = ?MAX_INACTIVITY, max_pause = ?MAX_PAUSE, timer = Timer}}. %%---------------------------------------------------------------------- %% Func: handle_event/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_event({become_controller, C2SPid}, StateName, StateData) -> case StateData#state.input of cancel -> {next_state, StateName, StateData#state{ waiting_input = C2SPid}}; Input -> lists:foreach( fun(Event) -> C2SPid ! Event end, queue:to_list(Input)), {next_state, StateName, StateData#state{ input = queue:new(), waiting_input = C2SPid}} end; handle_event({change_shaper, Shaper}, StateName, StateData) -> NewShaperState = shaper:new(Shaper), {next_state, StateName, StateData#state{shaper_state = NewShaperState}}; handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- handle_sync_event({send_xml, Packet}, _From, StateName, #state{http_receiver = undefined} = StateData) -> Output = [Packet | StateData#state.output], Reply = ok, {reply, Reply, StateName, StateData#state{output = Output}}; handle_sync_event({send_xml, Packet}, _From, StateName, StateData) -> Output = [Packet | StateData#state.output], cancel_timer(StateData#state.timer), Timer = set_inactivity_timer(StateData#state.pause, StateData#state.max_inactivity), HTTPReply = {ok, Output}, gen_fsm:reply(StateData#state.http_receiver, HTTPReply), cancel_timer(StateData#state.wait_timer), Rid = StateData#state.rid, ReqList = [#hbr{rid = Rid, key = StateData#state.key, out = Output } | [El || El <- StateData#state.req_list, El#hbr.rid /= Rid ] ], Reply = ok, {reply, Reply, StateName, StateData#state{output = [], http_receiver = undefined, req_list = ReqList, wait_timer = undefined, timer = Timer}}; handle_sync_event({stop,close}, _From, _StateName, StateData) -> Reply = ok, {stop, normal, Reply, StateData}; handle_sync_event({stop,stream_closed}, _From, _StateName, StateData) -> Reply = ok, {stop, normal, Reply, StateData}; handle_sync_event({stop,Reason}, _From, _StateName, StateData) -> ?DEBUG("Closing bind session ~p - Reason: ~p", [StateData#state.id, Reason]), Reply = ok, {stop, normal, Reply, StateData}; %% HTTP PUT: Receive packets from the client handle_sync_event(#http_put{rid = Rid}, _From, StateName, StateData) when StateData#state.shaper_timer /= undefined -> Pause = case erlang:read_timer(StateData#state.shaper_timer) of false -> 0; P -> P end, Reply = {wait, Pause}, ?DEBUG("Shaper timer for RID ~p: ~p", [Rid, Reply]), {reply, Reply, StateName, StateData}; handle_sync_event(#http_put{payload_size = PayloadSize} = Request, _From, StateName, StateData) -> ?DEBUG("New request: ~p",[Request]), %% Updating trafic shaper {NewShaperState, NewShaperTimer} = update_shaper(StateData#state.shaper_state, PayloadSize), handle_http_put_event(Request, StateName, StateData#state{shaper_state = NewShaperState, shaper_timer = NewShaperTimer}); %% HTTP GET: send packets to the client handle_sync_event({http_get, Rid, Wait, Hold}, From, StateName, StateData) -> %% setup timer send_receiver_reply(StateData#state.http_receiver, {ok, empty}), cancel_timer(StateData#state.wait_timer), TNow = tnow(), if (Hold > 0) and (StateData#state.output == []) and ((TNow - StateData#state.ctime) < (Wait*1000*1000)) and (StateData#state.rid == Rid) and (StateData#state.input /= cancel) and (StateData#state.pause == 0) -> WaitTimer = erlang:start_timer(Wait * 1000, self(), []), %% MR: Not sure we should cancel the state timer here. cancel_timer(StateData#state.timer), {next_state, StateName, StateData#state{ http_receiver = From, wait_timer = WaitTimer, timer = undefined}}; (StateData#state.input == cancel) -> cancel_timer(StateData#state.timer), Timer = set_inactivity_timer(StateData#state.pause, StateData#state.max_inactivity), Reply = {ok, cancel}, {reply, Reply, StateName, StateData#state{ input = queue:new(), http_receiver = undefined, wait_timer = undefined, timer = Timer}}; true -> cancel_timer(StateData#state.timer), Timer = set_inactivity_timer(StateData#state.pause, StateData#state.max_inactivity), Reply = {ok, StateData#state.output}, %% save request ReqList = [#hbr{rid = Rid, key = StateData#state.key, out = StateData#state.output } | [El || El <- StateData#state.req_list, El#hbr.rid /= Rid ] ], {reply, Reply, StateName, StateData#state{ output = [], http_receiver = undefined, wait_timer = undefined, timer = Timer, req_list = ReqList}} end; handle_sync_event(peername, _From, StateName, StateData) -> Reply = {ok, StateData#state.ip}, {reply, Reply, StateName, StateData}; handle_sync_event(_Event, _From, StateName, StateData) -> Reply = ok, {reply, Reply, StateName, StateData}. code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_info/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- %% We reached the max_inactivity timeout: handle_info({timeout, Timer, _}, _StateName, #state{id=SID, timer = Timer} = StateData) -> ?INFO_MSG("Session timeout. Closing the HTTP bind session: ~p", [SID]), {stop, normal, StateData}; handle_info({timeout, WaitTimer, _}, StateName, #state{wait_timer = WaitTimer} = StateData) -> if StateData#state.http_receiver /= undefined -> cancel_timer(StateData#state.timer), Timer = set_inactivity_timer(StateData#state.pause, StateData#state.max_inactivity), gen_fsm:reply(StateData#state.http_receiver, {ok, empty}), Rid = StateData#state.rid, ReqList = [#hbr{rid = Rid, key = StateData#state.key, out = [] } | [El || El <- StateData#state.req_list, El#hbr.rid /= Rid ] ], {next_state, StateName, StateData#state{http_receiver = undefined, req_list = ReqList, wait_timer = undefined, timer = Timer}}; true -> {next_state, StateName, StateData} end; handle_info({timeout, ShaperTimer, _}, StateName, #state{shaper_timer = ShaperTimer} = StateData) -> {next_state, StateName, StateData#state{shaper_timer = undefined}}; handle_info(_, StateName, StateData) -> {next_state, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: terminate/3 %% Purpose: Shutdown the fsm %% Returns: any %%---------------------------------------------------------------------- terminate(_Reason, _StateName, StateData) -> ?DEBUG("terminate: Deleting session ~s", [StateData#state.id]), mnesia:dirty_delete({http_bind, StateData#state.id}), send_receiver_reply(StateData#state.http_receiver, {ok, terminate}), case StateData#state.waiting_input of false -> ok; C2SPid -> gen_fsm:send_event(C2SPid, closed) end, ok. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- %% PUT / Get processing: handle_http_put_event(#http_put{rid = Rid, attrs = Attrs, hold = Hold} = Request, StateName, StateData) -> ?DEBUG("New request: ~p",[Request]), %% Check if Rid valid RidAllow = rid_allow(StateData#state.rid, Rid, Attrs, Hold, StateData#state.max_pause), %% Check if Rid is in sequence or out of sequence: case RidAllow of buffer -> ?DEBUG("Buffered request: ~p", [Request]), %% Request is out of sequence: PendingRequests = StateData#state.unprocessed_req_list, %% In case an existing RID was already buffered: Requests = lists:keydelete(Rid, 2, PendingRequests), ReqList = [#hbr{rid = Rid, key = StateData#state.key, out = [] } | [El || El <- StateData#state.req_list, El#hbr.rid > (Rid - 1 - Hold)] ], ?DEBUG("reqlist: ~p", [ReqList]), UnprocessedReqList = [Request | Requests], cancel_timer(StateData#state.timer), Timer = set_inactivity_timer(0, StateData#state.max_inactivity), {reply, buffered, StateName, StateData#state{unprocessed_req_list = UnprocessedReqList, req_list = ReqList, timer = Timer}}; _ -> %% Request is in sequence: process_http_put(Request, StateName, StateData, RidAllow) end. process_http_put(#http_put{rid = Rid, attrs = Attrs, payload = Payload, hold = Hold, stream = StreamTo, ip = IP} = Request, StateName, StateData, RidAllow) -> ?DEBUG("Actually processing request: ~p", [Request]), %% Check if key valid Key = xml:get_attr_s("key", Attrs), NewKey = xml:get_attr_s("newkey", Attrs), KeyAllow = case RidAllow of repeat -> true; false -> false; {true, _} -> case StateData#state.key of "" -> true; OldKey -> NextKey = sha:sha(Key), ?DEBUG("Key/OldKey/NextKey: ~s/~s/~s", [Key, OldKey, NextKey]), if OldKey == NextKey -> true; true -> ?DEBUG("wrong key: ~s",[Key]), false end end end, TNow = tnow(), LastPoll = if Payload == [] -> TNow; true -> 0 end, if (Payload == []) and (Hold == 0) and (TNow - StateData#state.last_poll < ?MIN_POLLING) -> Reply = {error, polling_too_frequently}, {reply, Reply, StateName, StateData}; KeyAllow -> case RidAllow of false -> Reply = {error, not_exists}, {reply, Reply, StateName, StateData}; repeat -> ?DEBUG("REPEATING ~p", [Rid]), Reply = case [El#hbr.out || El <- StateData#state.req_list, El#hbr.rid == Rid] of [] -> {error, not_exists}; [Out | _XS] -> {repeat, lists:reverse(Out)} end, {reply, Reply, StateName, StateData#state{input = cancel, last_poll = LastPoll}}; {true, Pause} -> SaveKey = if NewKey == "" -> Key; true -> NewKey end, ?DEBUG(" -- SaveKey: ~s~n", [SaveKey]), %% save request ReqList1 = [El || El <- StateData#state.req_list, El#hbr.rid > (Rid - 1 - Hold)], ReqList = case lists:keymember(Rid, #hbr.rid, ReqList1) of true -> ReqList1; false -> [#hbr{rid = Rid, key = StateData#state.key, out = [] } | ReqList1 ] end, ?DEBUG("reqlist: ~p", [ReqList]), %% setup next timer cancel_timer(StateData#state.timer), Timer = set_inactivity_timer(Pause, StateData#state.max_inactivity), case StateData#state.waiting_input of false -> Input = lists:foldl( fun queue:in/2, StateData#state.input, Payload), Reply = ok, process_buffered_request(Reply, StateName, StateData#state{input = Input, rid = Rid, key = SaveKey, ctime = TNow, timer = Timer, pause = Pause, last_poll = LastPoll, req_list = ReqList, ip = IP }); C2SPid -> case StreamTo of {To, ""} -> gen_fsm:send_event( C2SPid, {xmlstreamstart, "stream:stream", [{"to", To}, {"xmlns", ?NS_CLIENT}, {"xmlns:stream", ?NS_STREAM}]}); {To, Version} -> gen_fsm:send_event( C2SPid, {xmlstreamstart, "stream:stream", [{"to", To}, {"xmlns", ?NS_CLIENT}, {"version", Version}, {"xmlns:stream", ?NS_STREAM}]}); _ -> ok end, MaxInactivity = get_max_inactivity(StreamTo, StateData#state.max_inactivity), MaxPause = get_max_inactivity(StreamTo, StateData#state.max_pause), ?DEBUG("really sending now: ~p", [Payload]), lists:foreach( fun({xmlstreamend, End}) -> gen_fsm:send_event( C2SPid, {xmlstreamend, End}); (El) -> gen_fsm:send_event( C2SPid, {xmlstreamelement, El}) end, Payload), Reply = ok, process_buffered_request(Reply, StateName, StateData#state{input = queue:new(), rid = Rid, key = SaveKey, ctime = TNow, timer = Timer, pause = Pause, last_poll = LastPoll, req_list = ReqList, max_inactivity = MaxInactivity, max_pause = MaxPause, ip = IP }) end end; true -> Reply = {error, bad_key}, {reply, Reply, StateName, StateData} end. process_buffered_request(Reply, StateName, StateData) -> Rid = StateData#state.rid, Requests = StateData#state.unprocessed_req_list, case lists:keysearch(Rid+1, 2, Requests) of {value, Request} -> ?DEBUG("Processing buffered request: ~p", [Request]), NewRequests = lists:keydelete(Rid+1, 2, Requests), handle_http_put_event( Request, StateName, StateData#state{unprocessed_req_list = NewRequests}); _ -> {reply, Reply, StateName, StateData, hibernate} end. handle_http_put(Sid, Rid, Attrs, Payload, PayloadSize, StreamStart, IP) -> case http_put(Sid, Rid, Attrs, Payload, PayloadSize, StreamStart, IP) of {error, not_exists} -> ?DEBUG("no session associated with sid: ~p", [Sid]), {404, ?HEADER, ""}; {{error, Reason}, Sess} -> ?DEBUG("Error on HTTP put. Reason: ~p", [Reason]), handle_http_put_error(Reason, Sess); {{repeat, OutPacket}, Sess} -> ?DEBUG("http_put said 'repeat!' ...~nOutPacket: ~p", [OutPacket]), send_outpacket(Sess, OutPacket); {{wait, Pause}, _Sess} -> ?DEBUG("Trafic Shaper: Delaying request ~p", [Rid]), timer:sleep(Pause), %{200, ?HEADER, % xml:element_to_binary( % {xmlelement, "body", % [{"xmlns", ?NS_HTTP_BIND}, % {"type", "error"}], []})}; handle_http_put(Sid, Rid, Attrs, Payload, PayloadSize, StreamStart, IP); {buffered, _Sess} -> {200, ?HEADER, ""}; {ok, Sess} -> prepare_response(Sess, Rid, [], StreamStart) end. http_put(Sid, Rid, Attrs, Payload, PayloadSize, StreamStart, IP) -> ?DEBUG("Looking for session: ~p", [Sid]), case mnesia:dirty_read({http_bind, Sid}) of [] -> {error, not_exists}; [#http_bind{pid = FsmRef, hold=Hold, to={To, StreamVersion}}=Sess] -> NewStream = case StreamStart of true -> {To, StreamVersion}; _ -> "" end, {gen_fsm:sync_send_all_state_event( FsmRef, #http_put{rid = Rid, attrs = Attrs, payload = Payload, payload_size = PayloadSize, hold = Hold, stream = NewStream, ip = IP}, 30000), Sess} end. handle_http_put_error(Reason, #http_bind{pid=FsmRef, version=Version}) when Version >= 0 -> gen_fsm:sync_send_all_state_event(FsmRef, {stop, {put_error,Reason}}), case Reason of not_exists -> {200, ?HEADER, xml:element_to_binary( {xmlelement, "body", [{"xmlns", ?NS_HTTP_BIND}, {"type", "terminate"}, {"condition", "item-not-found"}], []})}; bad_key -> {200, ?HEADER, xml:element_to_binary( {xmlelement, "body", [{"xmlns", ?NS_HTTP_BIND}, {"type", "terminate"}, {"condition", "item-not-found"}], []})}; polling_too_frequently -> {200, ?HEADER, xml:element_to_binary( {xmlelement, "body", [{"xmlns", ?NS_HTTP_BIND}, {"type", "terminate"}, {"condition", "policy-violation"}], []})} end; handle_http_put_error(Reason, #http_bind{pid=FsmRef}) -> gen_fsm:sync_send_all_state_event(FsmRef,{stop, {put_error_no_version, Reason}}), case Reason of not_exists -> %% bad rid ?DEBUG("Closing HTTP bind session (Bad rid).", []), {404, ?HEADER, ""}; bad_key -> ?DEBUG("Closing HTTP bind session (Bad key).", []), {404, ?HEADER, ""}; polling_too_frequently -> ?DEBUG("Closing HTTP bind session (User polling too frequently).", []), {403, ?HEADER, ""} end. %% Control RID ordering rid_allow(none, _NewRid, _Attrs, _Hold, _MaxPause) -> %% First request - nothing saved so far {true, 0}; rid_allow(OldRid, NewRid, Attrs, Hold, MaxPause) -> ?DEBUG("Previous rid / New rid: ~p/~p", [OldRid, NewRid]), if %% We did not miss any packet, we can process it immediately: NewRid == OldRid + 1 -> case catch list_to_integer( xml:get_attr_s("pause", Attrs)) of {'EXIT', _} -> {true, 0}; Pause1 when Pause1 =< MaxPause -> ?DEBUG("got pause: ~p", [Pause1]), {true, Pause1}; _ -> {true, 0} end; %% We have missed packets, we need to cached it to process it later on: (OldRid < NewRid) and (NewRid =< (OldRid + Hold + 1)) -> buffer; (NewRid =< OldRid) and (NewRid > OldRid - Hold - 1) -> repeat; true -> false end. update_shaper(ShaperState, PayloadSize) -> {NewShaperState, Pause} = shaper:update(ShaperState, PayloadSize), if Pause > 0 -> ShaperTimer = erlang:start_timer(Pause, self(), activate), %% MR: Seems timer is not needed. Activate is not handled {NewShaperState, ShaperTimer}; true -> {NewShaperState, undefined} end. prepare_response(Sess, Rid, OutputEls, StreamStart) -> receive after Sess#http_bind.process_delay -> ok end, case catch http_get(Sess, Rid) of {ok, cancel} -> %% actually it would be better if we could completely %% cancel this request, but then we would have to hack %% ejabberd_http and I'm too lazy now {200, ?HEADER, ""}; {ok, empty} -> {200, ?HEADER, ""}; {ok, terminate} -> {200, ?HEADER, ""}; {ok, ROutPacket} -> OutPacket = lists:reverse(ROutPacket), ?DEBUG("OutPacket: ~p", [OutputEls++OutPacket]), prepare_outpacket_response(Sess, Rid, OutputEls++OutPacket, StreamStart); {'EXIT', {shutdown, _}} -> {200, ?HEADER, ""}; {'EXIT', _Reason} -> {200, ?HEADER, ""} end. %% Send output payloads on establised sessions prepare_outpacket_response(Sess, _Rid, OutPacket, false) -> case catch send_outpacket(Sess, OutPacket) of {'EXIT', _Reason} -> ?DEBUG("Error in sending packet ~p ", [_Reason]), {200, ?HEADER, ""}; SendRes -> SendRes end; %% Handle a new session along with its output payload prepare_outpacket_response(#http_bind{id=Sid, wait=Wait, hold=Hold, to=To}=_Sess, _Rid, OutPacket, true) -> case OutPacket of [{xmlstreamstart, _, OutAttrs} | Els] -> AuthID = xml:get_attr_s("id", OutAttrs), From = xml:get_attr_s("from", OutAttrs), Version = xml:get_attr_s("version", OutAttrs), OutEls = case Els of [] -> []; [{xmlstreamelement, {xmlelement, "stream:features", StreamAttribs, StreamEls}} | StreamTail] -> TypedTail = [check_default_xmlns(OEl) || {xmlstreamelement, OEl} <- StreamTail], [{xmlelement, "stream:features", [{"xmlns:stream", ?NS_STREAM}] ++ StreamAttribs, StreamEls}] ++ TypedTail; StreamTail -> [check_default_xmlns(OEl) || {xmlstreamelement, OEl} <- StreamTail] end, case OutEls of [{xmlelement, "stream:error",_,_}] -> {200, ?HEADER, ""}; _ -> BOSH_attribs = [{"authid", AuthID}, {"xmlns:xmpp", ?NS_BOSH}, {"xmlns:stream", ?NS_STREAM}] ++ case OutEls of [] -> []; _ -> [{"xmpp:version", Version}] end, MaxInactivity = get_max_inactivity(To, ?MAX_INACTIVITY), MaxPause = get_max_pause(To), {200, ?HEADER, xml:element_to_binary( {xmlelement,"body", [{"xmlns", ?NS_HTTP_BIND}, {"sid", Sid}, {"wait", integer_to_list(Wait)}, {"requests", integer_to_list(Hold+1)}, {"inactivity", integer_to_list( trunc(MaxInactivity/1000))}, {"maxpause", integer_to_list(MaxPause)}, {"polling", integer_to_list( trunc(?MIN_POLLING/1000000))}, {"ver", ?BOSH_VERSION}, {"from", From}, {"secure", "true"} %% we're always being secure ] ++ BOSH_attribs,OutEls})} end; _ -> {200, ?HEADER, ""} end. http_get(#http_bind{pid = FsmRef, wait = Wait, hold = Hold}, Rid) -> gen_fsm:sync_send_all_state_event( FsmRef, {http_get, Rid, Wait, Hold}, 2 * ?MAX_WAIT * 1000). send_outpacket(#http_bind{pid = FsmRef}, OutPacket) -> case OutPacket of [] -> {200, ?HEADER, ""}; [{xmlstreamend, _}] -> gen_fsm:sync_send_all_state_event(FsmRef,{stop,stream_closed}), {200, ?HEADER, ""}; _ -> %% TODO: We parse to add a default namespace to packet, %% The spec says adding the jabber:client namespace if %% mandatory, even if some implementation do not do that %% change on packets. %% I think this should be an option to avoid modifying %% packet in most case. AllElements = lists:all(fun({xmlstreamelement, {xmlelement, "stream:error", _, _}}) -> false; ({xmlstreamelement, _}) -> true; ({xmlstreamraw, _}) -> true; (_) -> false end, OutPacket), case AllElements of true -> TypedEls = lists:foldl(fun({xmlstreamelement, El}, Acc) -> Acc ++ [xml:element_to_string( check_default_xmlns(El) )]; ({xmlstreamraw, R}, Acc) -> Acc ++ [R] end, [], OutPacket), Body = "" ++ TypedEls ++ "", ?DEBUG(" --- outgoing data --- ~n~s~n --- END --- ~n", [Body]), {200, ?HEADER, Body}; false -> case OutPacket of [{xmlstreamstart, _, _} | SEls] -> OutEls = case SEls of [{xmlstreamelement, {xmlelement, "stream:features", StreamAttribs, StreamEls}} | StreamTail] -> TypedTail = [check_default_xmlns(OEl) || {xmlstreamelement, OEl} <- StreamTail], [{xmlelement, "stream:features", [{"xmlns:stream", ?NS_STREAM}] ++ StreamAttribs, StreamEls}] ++ TypedTail; StreamTail -> [check_default_xmlns(OEl) || {xmlstreamelement, OEl} <- StreamTail] end, {200, ?HEADER, xml:element_to_binary( {xmlelement,"body", [{"xmlns", ?NS_HTTP_BIND}], OutEls})}; _ -> SErrCond = lists:filter( fun({xmlstreamelement, {xmlelement, "stream:error", _, _}}) -> true; (_) -> false end, OutPacket), StreamErrCond = case SErrCond of [] -> null; [{xmlstreamelement, {xmlelement, _, _, _Cond} = StreamErrorTag} | _] -> [StreamErrorTag] end, gen_fsm:sync_send_all_state_event(FsmRef, {stop, {stream_error,OutPacket}}), case StreamErrCond of null -> {200, ?HEADER, ""}; _ -> {200, ?HEADER, "" ++ elements_to_string(StreamErrCond) ++ ""} end end end end. parse_request(Data, PayloadSize, MaxStanzaSize) -> ?DEBUG("--- incoming data --- ~n~s~n --- END --- ", [Data]), %% MR: I do not think it works if put put several elements in the %% same body: case xml_stream:parse_element(Data) of {xmlelement, "body", Attrs, Els} -> Xmlns = xml:get_attr_s("xmlns",Attrs), if Xmlns /= ?NS_HTTP_BIND -> {error, bad_request}; true -> case catch list_to_integer(xml:get_attr_s("rid", Attrs)) of {'EXIT', _} -> {error, bad_request}; Rid -> %% I guess this is to remove XMLCDATA: Is it really needed ? FixedEls = lists:filter( fun(I) -> case I of {xmlelement, _, _, _} -> true; _ -> false end end, Els), Sid = xml:get_attr_s("sid",Attrs), if PayloadSize =< MaxStanzaSize -> {ok, {Sid, Rid, Attrs, FixedEls}}; true -> {size_limit, Sid} end end end; {xmlelement, _Name, _Attrs, _Els} -> {error, bad_request}; {error, _Reason} -> {error, bad_request} end. send_receiver_reply(undefined, _Reply) -> ok; send_receiver_reply(Receiver, Reply) -> gen_fsm:reply(Receiver, Reply). %% Cancel timer and empty message queue. cancel_timer(undefined) -> ok; cancel_timer(Timer) -> erlang:cancel_timer(Timer), receive {timeout, Timer, _} -> ok after 0 -> ok end. %% If client asked for a pause (pause > 0), we apply the pause value %% as inactivity timer: set_inactivity_timer(Pause, _MaxInactivity) when Pause > 0 -> erlang:start_timer(Pause*1000, self(), []); %% Otherwise, we apply the max_inactivity value as inactivity timer: set_inactivity_timer(_Pause, MaxInactivity) -> erlang:start_timer(MaxInactivity, self(), []). %% TODO: Use tail recursion and list reverse ? elements_to_string([]) -> []; elements_to_string([El | Els]) -> [xml:element_to_binary(El)|elements_to_string(Els)]. %% @spec (To, Default::integer()) -> integer() %% where To = [] | {Host::string(), Version::string()} get_max_inactivity({Host, _}, Default) -> case gen_mod:get_module_opt(Host, mod_http_bind, max_inactivity, undefined) of Seconds when is_integer(Seconds) -> Seconds * 1000; undefined -> Default end; get_max_inactivity(_, Default) -> Default. get_max_pause({Host, _}) -> gen_mod:get_module_opt(Host, mod_http_bind, max_pause, ?MAX_PAUSE); get_max_pause(_) -> ?MAX_PAUSE. %% Current time as integer tnow() -> {TMegSec, TSec, TMSec} = now(), (TMegSec * 1000000 + TSec) * 1000000 + TMSec. check_default_xmlns({xmlelement, Name, Attrs, Els} = El) -> case xml:get_tag_attr_s("xmlns", El) of "" -> {xmlelement, Name, [{"xmlns", ?NS_CLIENT} | Attrs], Els}; _ -> El end; check_default_xmlns(El) -> El. %% Check that mod_http_bind has been defined in config file. %% Print a warning in log file if this is not the case. check_bind_module(XmppDomain) -> case gen_mod:is_loaded(XmppDomain, mod_http_bind) of true -> ok; false -> ?ERROR_MSG("You are trying to use BOSH (HTTP Bind) in host ~p," " but the module mod_http_bind is not started in" " that host. Configure your BOSH client to connect" " to the correct host, or add your desired host to" " the configuration, or check your 'modules'" " section in your ejabberd configuration file.", [XmppDomain]) end. ejabberd-2.1.11/src/web/ejabberd_web_admin.hrl0000664000000000000000000000537312240230175016044 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -define(X(Name), {xmlelement, Name, [], []}). -define(XA(Name, Attrs), {xmlelement, Name, Attrs, []}). -define(XE(Name, Els), {xmlelement, Name, [], Els}). -define(XAE(Name, Attrs, Els), {xmlelement, Name, Attrs, Els}). -define(C(Text), {xmlcdata, Text}). -define(XC(Name, Text), ?XE(Name, [?C(Text)])). -define(XAC(Name, Attrs, Text), ?XAE(Name, Attrs, [?C(Text)])). -define(T(Text), translate:translate(Lang, Text)). -define(CT(Text), ?C(?T(Text))). -define(XCT(Name, Text), ?XC(Name, ?T(Text))). -define(XACT(Name, Attrs, Text), ?XAC(Name, Attrs, ?T(Text))). -define(LI(Els), ?XE("li", Els)). -define(A(URL, Els), ?XAE("a", [{"href", URL}], Els)). -define(AC(URL, Text), ?A(URL, [?C(Text)])). -define(ACT(URL, Text), ?AC(URL, ?T(Text))). -define(P, ?X("p")). -define(BR, ?X("br")). -define(INPUT(Type, Name, Value), ?XA("input", [{"type", Type}, {"name", Name}, {"value", Value}])). -define(INPUTT(Type, Name, Value), ?INPUT(Type, Name, ?T(Value))). -define(INPUTS(Type, Name, Value, Size), ?XA("input", [{"type", Type}, {"name", Name}, {"value", Value}, {"size", Size}])). -define(INPUTST(Type, Name, Value, Size), ?INPUT(Type, Name, ?T(Value), Size)). -define(ACLINPUT(Text), ?XE("td", [?INPUT("text", "value" ++ ID, Text)])). -define(TEXTAREA(Name, Rows, Cols, Value), ?XAC("textarea", [{"name", Name}, {"rows", Rows}, {"cols", Cols}], Value)). %% Build an xmlelement for result -define(XRES(Text), ?XAC("p", [{"class", "result"}], Text)). -define(XREST(Text), ?XRES(?T(Text))). %% Guide Link -define(GL(Ref, Title), ?XAE("div", [{"class", "guidelink"}], [?XAE("a", [{"href", "/admin/doc/guide.html#"++ Ref}, {"target", "_blank"}], [?C("[Guide: " ++ Title ++ "]")]) ])). %% h1 with a Guide Link -define(H1GL(Name, Ref, Title), [?XC("h1", Name), ?GL(Ref, Title)]). ejabberd-2.1.11/src/web/ejabberd_http_poll.erl0000664000000000000000000003440612240230175016120 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_http_poll.erl %%% Author : Alexey Shchepin %%% Purpose : HTTP Polling support (XEP-0025) %%% Created : 4 Mar 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_http_poll). -author('alexey@process-one.net'). -behaviour(gen_fsm). %% External exports -export([start_link/3, init/1, handle_event/3, handle_sync_event/4, code_change/4, handle_info/3, terminate/3, send/2, setopts/2, sockname/1, peername/1, controlling_process/2, close/1, process/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("ejabberd_http.hrl"). -record(http_poll, {id, pid}). -record(state, {id, key, socket, output = "", input = "", waiting_input = false, %% {ReceiverPid, Tag} last_receiver, http_poll_timeout, timer}). %-define(DBGFSM, true). -ifdef(DBGFSM). -define(FSMOPTS, [{debug, [trace]}]). -else. -define(FSMOPTS, []). -endif. -define(HTTP_POLL_TIMEOUT, 300000). -define(CT, {"Content-Type", "text/xml; charset=utf-8"}). -define(BAD_REQUEST, [?CT, {"Set-Cookie", "ID=-3:0; expires=-1"}]). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start(ID, Key, IP) -> mnesia:create_table(http_poll, [{ram_copies, [node()]}, {attributes, record_info(fields, http_poll)}]), supervisor:start_child(ejabberd_http_poll_sup, [ID, Key, IP]). start_link(ID, Key, IP) -> gen_fsm:start_link(?MODULE, [ID, Key, IP], ?FSMOPTS). send({http_poll, FsmRef, _IP}, Packet) -> gen_fsm:sync_send_all_state_event(FsmRef, {send, Packet}). setopts({http_poll, FsmRef, _IP}, Opts) -> case lists:member({active, once}, Opts) of true -> gen_fsm:send_all_state_event(FsmRef, {activate, self()}); _ -> ok end. sockname(_Socket) -> {ok, {{0, 0, 0, 0}, 0}}. peername({http_poll, _FsmRef, IP}) -> {ok, IP}. controlling_process(_Socket, _Pid) -> ok. close({http_poll, FsmRef, _IP}) -> catch gen_fsm:sync_send_all_state_event(FsmRef, close). process([], #request{data = Data, ip = IP} = _Request) -> case catch parse_request(Data) of {ok, ID1, Key, NewKey, Packet} -> ID = if (ID1 == "0") or (ID1 == "mobile") -> NewID = sha:sha(term_to_binary({now(), make_ref()})), {ok, Pid} = start(NewID, "", IP), mnesia:transaction( fun() -> mnesia:write(#http_poll{id = NewID, pid = Pid}) end), NewID; true -> ID1 end, case http_put(ID, Key, NewKey, Packet) of {error, not_exists} -> {200, ?BAD_REQUEST, ""}; {error, bad_key} -> {200, ?BAD_REQUEST, ""}; ok -> receive after 100 -> ok end, case http_get(ID) of {error, not_exists} -> {200, ?BAD_REQUEST, ""}; {ok, OutPacket} -> if ID == ID1 -> Cookie = "ID=" ++ ID ++ "; expires=-1", {200, [?CT, {"Set-Cookie", Cookie}], OutPacket}; ID1 == "mobile" -> {200, [?CT], [ID, $\n, OutPacket]}; true -> Cookie = "ID=" ++ ID ++ "; expires=-1", {200, [?CT, {"Set-Cookie", Cookie}], OutPacket} end end end; _ -> HumanHTMLxmlel = get_human_html_xmlel(), {200, [?CT, {"Set-Cookie", "ID=-2:0; expires=-1"}], HumanHTMLxmlel} end; process(_, _Request) -> {400, [], {xmlelement, "h1", [], [{xmlcdata, "400 Bad Request"}]}}. %% Code copied from mod_http_bind.erl and customized get_human_html_xmlel() -> Heading = "ejabberd " ++ atom_to_list(?MODULE), {xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"}], [{xmlelement, "head", [], [{xmlelement, "title", [], [{xmlcdata, Heading}]}]}, {xmlelement, "body", [], [{xmlelement, "h1", [], [{xmlcdata, Heading}]}, {xmlelement, "p", [], [{xmlcdata, "An implementation of "}, {xmlelement, "a", [{"href", "http://xmpp.org/extensions/xep-0025.html"}], [{xmlcdata, "Jabber HTTP Polling (XEP-0025)"}]}]}, {xmlelement, "p", [], [{xmlcdata, "This web page is only informative. " "To use HTTP-Poll you need a Jabber/XMPP client that supports it."} ]} ]}]}. %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, StateName, StateData} | %% {ok, StateName, StateData, Timeout} | %% ignore | %% {stop, StopReason} %%---------------------------------------------------------------------- init([ID, Key, IP]) -> ?INFO_MSG("started: ~p", [{ID, Key, IP}]), %% Read c2s options from the first ejabberd_c2s configuration in %% the config file listen section %% TODO: We should have different access and shaper values for %% each connector. The default behaviour should be however to use %% the default c2s restrictions if not defined for the current %% connector. Opts = ejabberd_c2s_config:get_c2s_limits(), HTTPPollTimeout = case ejabberd_config:get_local_option({http_poll_timeout, ?MYNAME}) of %% convert seconds of option into milliseconds Int when is_integer(Int) -> Int*1000; undefined -> ?HTTP_POLL_TIMEOUT end, Socket = {http_poll, self(), IP}, ejabberd_socket:start(ejabberd_c2s, ?MODULE, Socket, Opts), Timer = erlang:start_timer(HTTPPollTimeout, self(), []), {ok, loop, #state{id = ID, key = Key, socket = Socket, http_poll_timeout = HTTPPollTimeout, timer = Timer}}. %%---------------------------------------------------------------------- %% Func: StateName/2 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: StateName/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- %state_name(Event, From, StateData) -> % Reply = ok, % {reply, Reply, state_name, StateData}. %%---------------------------------------------------------------------- %% Func: handle_event/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_event({activate, From}, StateName, StateData) -> case StateData#state.input of "" -> {next_state, StateName, StateData#state{waiting_input = {From, ok}}}; Input -> Receiver = From, Receiver ! {tcp, StateData#state.socket, list_to_binary(Input)}, {next_state, StateName, StateData#state{input = "", waiting_input = false, last_receiver = Receiver }} end; handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- handle_sync_event({send, Packet}, _From, StateName, StateData) -> Packet2 = if is_binary(Packet) -> binary_to_list(Packet); true -> Packet end, Output = StateData#state.output ++ [lists:flatten(Packet2)], Reply = ok, {reply, Reply, StateName, StateData#state{output = Output}}; handle_sync_event(stop, _From, _StateName, StateData) -> Reply = ok, {stop, normal, Reply, StateData}; handle_sync_event({http_put, Key, NewKey, Packet}, _From, StateName, StateData) -> Allow = case StateData#state.key of "" -> true; OldKey -> NextKey = jlib:encode_base64( binary_to_list(crypto:sha(Key))), if OldKey == NextKey -> true; true -> false end end, if Allow -> case StateData#state.waiting_input of false -> Input = [StateData#state.input|Packet], Reply = ok, {reply, Reply, StateName, StateData#state{input = Input, key = NewKey}}; {Receiver, _Tag} -> Receiver ! {tcp, StateData#state.socket, list_to_binary(Packet)}, cancel_timer(StateData#state.timer), Timer = erlang:start_timer(StateData#state.http_poll_timeout, self(), []), Reply = ok, {reply, Reply, StateName, StateData#state{waiting_input = false, last_receiver = Receiver, key = NewKey, timer = Timer}} end; true -> Reply = {error, bad_key}, {reply, Reply, StateName, StateData} end; handle_sync_event(http_get, _From, StateName, StateData) -> Reply = {ok, StateData#state.output}, {reply, Reply, StateName, StateData#state{output = ""}}; handle_sync_event(_Event, _From, StateName, StateData) -> Reply = ok, {reply, Reply, StateName, StateData}. code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_info/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_info({timeout, Timer, _}, _StateName, #state{timer = Timer} = StateData) -> {stop, normal, StateData}; handle_info(_, StateName, StateData) -> {next_state, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: terminate/3 %% Purpose: Shutdown the fsm %% Returns: any %%---------------------------------------------------------------------- terminate(_Reason, _StateName, StateData) -> mnesia:transaction( fun() -> mnesia:delete({http_poll, StateData#state.id}) end), case StateData#state.waiting_input of false -> %% We are testing this case due to "socket activation": If we pass %% here and the "socket" is not ready to receive, the tcp_closed %% will be lost. case StateData#state.last_receiver of undefined -> ok; Receiver -> Receiver ! {tcp_closed, StateData#state.socket} end; {Receiver, _Tag} -> Receiver ! {tcp_closed, StateData#state.socket} end, catch resend_messages(StateData#state.output), ok. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- http_put(ID, Key, NewKey, Packet) -> case mnesia:dirty_read({http_poll, ID}) of [] -> {error, not_exists}; [#http_poll{pid = FsmRef}] -> gen_fsm:sync_send_all_state_event( FsmRef, {http_put, Key, NewKey, Packet}) end. http_get(ID) -> case mnesia:dirty_read({http_poll, ID}) of [] -> {error, not_exists}; [#http_poll{pid = FsmRef}] -> gen_fsm:sync_send_all_state_event(FsmRef, http_get) end. parse_request(Data) -> Comma = string:chr(Data, $,), Header = lists:sublist(Data, Comma - 1), Packet = lists:nthtail(Comma, Data), {ID, Key, NewKey} = case string:tokens(Header, ";") of [ID1] -> {ID1, "", ""}; [ID1, Key1] -> {ID1, Key1, Key1}; [ID1, Key1, NewKey1] -> {ID1, Key1, NewKey1} end, {ok, ID, Key, NewKey, Packet}. cancel_timer(Timer) -> erlang:cancel_timer(Timer), receive {timeout, Timer, _} -> ok after 0 -> ok end. %% Resend the polled messages resend_messages(Messages) -> lists:foreach(fun(Packet) -> resend_message(Packet) end, Messages). %% This function is used to resend messages that have been polled but not %% delivered. resend_message(Packet) -> {xmlelement, Name, _, _} = ParsedPacket = xml_stream:parse_element(Packet), %% Avoid sending if Name == "iq"; Name == "message"; Name == "presence" -> From = get_jid("from", ParsedPacket), To = get_jid("to", ParsedPacket), ?DEBUG("Resend ~p ~p ~p~n",[From,To, ParsedPacket]), ejabberd_router:route(From, To, ParsedPacket); true -> ok end. %% Type can be "from" or "to" %% Parsed packet is a parsed Jabber packet. get_jid(Type, ParsedPacket) -> case xml:get_tag_attr(Type, ParsedPacket) of {value, StringJid} -> jlib:string_to_jid(StringJid); false -> jlib:make_jid("","","") end. ejabberd-2.1.11/src/ejabberd_zlib/0000775000000000000000000000000012240452476013575 5ustar ejabberd-2.1.11/src/ejabberd_zlib/Makefile.win320000664000000000000000000000167012240230175016170 0ustar include ..\Makefile.inc EFLAGS = -I .. -pz .. OUTDIR = .. BEAMS = ..\ejabberd_zlib.beam SOURCE = ejabberd_zlib_drv.c OBJECT = ejabberd_zlib_drv.o DLL = $(OUTDIR)\ejabberd_zlib_drv.dll ALL : $(DLL) $(BEAMS) CLEAN : -@erase $(DLL) -@erase $(OUTDIR)\ejabberd_zlib_drv.exp -@erase $(OUTDIR)\ejabberd_zlib_drv.lib -@erase $(OBJECT) -@erase $(BEAMS) $(OUTDIR)\ejabberd_zlib.beam : ejabberd_zlib.erl erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_zlib.erl CC=cl.exe CC_FLAGS=-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -MD -Ox -I"$(ERLANG_DIR)\usr\include" -I"$(EI_DIR)\include" -I"$(ZLIB_DIR)\include" LD=link.exe LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" "$(ZLIB_LIB)" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib $(DLL) : $(OBJECT) $(LD) $(LD_FLAGS) -out:$@ $< $(OBJECT) : $(SOURCE) $(CC) $(CC_FLAGS) -c -Fo$@ $< ejabberd-2.1.11/src/ejabberd_zlib/ejabberd_zlib_drv.c0000664000000000000000000001372512240230175017370 0ustar /* * ejabberd, Copyright (C) 2002-2012 ProcessOne * * 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., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * */ #include #include #include #include /* * R15B changed several driver callbacks to use ErlDrvSizeT and * ErlDrvSSizeT typedefs instead of int. * This provides missing typedefs on older OTP versions. */ #if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 typedef int ErlDrvSizeT; typedef int ErlDrvSSizeT; #endif #define BUF_SIZE 1024 typedef struct { ErlDrvPort port; z_stream *d_stream; z_stream *i_stream; } ejabberd_zlib_data; static void* zlib_alloc(void* data, unsigned int items, unsigned int size) { return (void*) driver_alloc(items*size); } static void zlib_free(void* data, void* addr) { driver_free(addr); } static ErlDrvData ejabberd_zlib_drv_start(ErlDrvPort port, char *buff) { ejabberd_zlib_data *d = (ejabberd_zlib_data *)driver_alloc(sizeof(ejabberd_zlib_data)); d->port = port; d->d_stream = (z_stream *)driver_alloc(sizeof(z_stream)); d->d_stream->zalloc = zlib_alloc; d->d_stream->zfree = zlib_free; d->d_stream->opaque = (voidpf)0; deflateInit(d->d_stream, Z_DEFAULT_COMPRESSION); d->i_stream = (z_stream *)driver_alloc(sizeof(z_stream)); d->i_stream->zalloc = zlib_alloc; d->i_stream->zfree = zlib_free; d->i_stream->opaque = (voidpf)0; inflateInit(d->i_stream); set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); return (ErlDrvData)d; } static void ejabberd_zlib_drv_stop(ErlDrvData handle) { ejabberd_zlib_data *d = (ejabberd_zlib_data *)handle; deflateEnd(d->d_stream); driver_free(d->d_stream); inflateEnd(d->i_stream); driver_free(d->i_stream); driver_free((char *)handle); } #define DEFLATE 1 #define INFLATE 2 #define die_unless(cond, errstr) \ if (!(cond)) \ { \ rlen = strlen(errstr) + 1; \ b = driver_realloc_binary(b, rlen); \ b->orig_bytes[0] = 1; \ strncpy(b->orig_bytes + 1, errstr, rlen - 1); \ *rbuf = (char *)b; \ return rlen; \ } static ErlDrvSSizeT ejabberd_zlib_drv_control(ErlDrvData handle, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { ejabberd_zlib_data *d = (ejabberd_zlib_data *)handle; int err; int size; ErlDrvBinary *b; switch (command) { case DEFLATE: size = BUF_SIZE + 1; rlen = 1; b = driver_alloc_binary(size); b->orig_bytes[0] = 0; d->d_stream->next_in = (unsigned char *)buf; d->d_stream->avail_in = len; d->d_stream->avail_out = 0; err = Z_OK; while (err == Z_OK && d->d_stream->avail_out == 0) { d->d_stream->next_out = (unsigned char *)b->orig_bytes + rlen; d->d_stream->avail_out = BUF_SIZE; err = deflate(d->d_stream, Z_SYNC_FLUSH); die_unless((err == Z_OK) || (err == Z_STREAM_END), "Deflate error"); rlen += (BUF_SIZE - d->d_stream->avail_out); size += (BUF_SIZE - d->d_stream->avail_out); b = driver_realloc_binary(b, size); } b = driver_realloc_binary(b, rlen); *rbuf = (char *)b; return rlen; case INFLATE: size = BUF_SIZE + 1; rlen = 1; b = driver_alloc_binary(size); b->orig_bytes[0] = 0; if (len > 0) { d->i_stream->next_in = (unsigned char *)buf; d->i_stream->avail_in = len; d->i_stream->avail_out = 0; err = Z_OK; while (err == Z_OK && d->i_stream->avail_out == 0) { d->i_stream->next_out = (unsigned char *)b->orig_bytes + rlen; d->i_stream->avail_out = BUF_SIZE; err = inflate(d->i_stream, Z_SYNC_FLUSH); die_unless((err == Z_OK) || (err == Z_STREAM_END), "Inflate error"); rlen += (BUF_SIZE - d->i_stream->avail_out); size += (BUF_SIZE - d->i_stream->avail_out); b = driver_realloc_binary(b, size); } } b = driver_realloc_binary(b, rlen); *rbuf = (char *)b; return rlen; } b = driver_alloc_binary(1); b->orig_bytes[0] = 0; *rbuf = (char *)b; return 1; } ErlDrvEntry ejabberd_zlib_driver_entry = { NULL, /* F_PTR init, N/A */ ejabberd_zlib_drv_start, /* L_PTR start, called when port is opened */ ejabberd_zlib_drv_stop, /* F_PTR stop, called when port is closed */ NULL, /* F_PTR output, called when erlang has sent */ NULL, /* F_PTR ready_input, called when input descriptor ready */ NULL, /* F_PTR ready_output, called when output descriptor ready */ "ejabberd_zlib_drv", /* char *driver_name, the argument to open_port */ NULL, /* F_PTR finish, called when unloaded */ NULL, /* handle */ ejabberd_zlib_drv_control, /* F_PTR control, port_command callback */ NULL, /* F_PTR timeout, reserved */ NULL, /* F_PTR outputv, reserved */ /* Added in Erlang/OTP R15B: */ NULL, /* ready_async */ NULL, /* flush */ NULL, /* call */ NULL, /* event */ ERL_DRV_EXTENDED_MARKER, /* extended_marker */ ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ 0, /* driver_flags */ NULL, /* handle2 */ NULL, /* process_exit */ NULL /* stop_select */ }; DRIVER_INIT(ejabberd_zlib_drv) /* must match name in driver_entry */ { return &ejabberd_zlib_driver_entry; } ejabberd-2.1.11/src/ejabberd_zlib/ejabberd_zlib.erl0000664000000000000000000001167612240230175017060 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_zlib.erl %%% Author : Alexey Shchepin %%% Purpose : Interface to zlib %%% Created : 19 Jan 2006 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_zlib). -author('alexey@process-one.net'). -behaviour(gen_server). -export([start/0, start_link/0, enable_zlib/2, disable_zlib/1, send/2, recv/2, recv/3, recv_data/2, setopts/2, sockname/1, peername/1, get_sockmod/1, controlling_process/2, close/1]). %% Internal exports, call-back functions. -export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]). -define(DEFLATE, 1). -define(INFLATE, 2). -record(zlibsock, {sockmod, socket, zlibport}). start() -> gen_server:start({local, ?MODULE}, ?MODULE, [], []). start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). init([]) -> case erl_ddll:load_driver(ejabberd:get_so_path(), ejabberd_zlib_drv) of ok -> ok; {error, already_loaded} -> ok end, Port = open_port({spawn, "ejabberd_zlib_drv"}, [binary]), {ok, Port}. %%% -------------------------------------------------------- %%% The call-back functions. %%% -------------------------------------------------------- handle_call(_, _, State) -> {noreply, State}. handle_cast(_, State) -> {noreply, State}. handle_info({'EXIT', Port, Reason}, Port) -> {stop, {port_died, Reason}, Port}; handle_info({'EXIT', _Pid, _Reason}, Port) -> {noreply, Port}; handle_info(_, State) -> {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. terminate(_Reason, Port) -> Port ! {self, close}, ok. enable_zlib(SockMod, Socket) -> case erl_ddll:load_driver(ejabberd:get_so_path(), ejabberd_zlib_drv) of ok -> ok; {error, already_loaded} -> ok end, Port = open_port({spawn, "ejabberd_zlib_drv"}, [binary]), {ok, #zlibsock{sockmod = SockMod, socket = Socket, zlibport = Port}}. disable_zlib(#zlibsock{sockmod = SockMod, socket = Socket, zlibport = Port}) -> port_close(Port), {SockMod, Socket}. recv(Socket, Length) -> recv(Socket, Length, infinity). recv(#zlibsock{sockmod = SockMod, socket = Socket} = ZlibSock, Length, Timeout) -> case SockMod:recv(Socket, Length, Timeout) of {ok, Packet} -> recv_data(ZlibSock, Packet); {error, _Reason} = Error -> Error end. recv_data(#zlibsock{sockmod = SockMod, socket = Socket} = ZlibSock, Packet) -> case SockMod of gen_tcp -> recv_data2(ZlibSock, Packet); _ -> case SockMod:recv_data(Socket, Packet) of {ok, Packet2} -> recv_data2(ZlibSock, Packet2); Error -> Error end end. recv_data2(ZlibSock, Packet) -> case catch recv_data1(ZlibSock, Packet) of {'EXIT', Reason} -> {error, Reason}; Res -> Res end. recv_data1(#zlibsock{zlibport = Port} = _ZlibSock, Packet) -> case port_control(Port, ?INFLATE, Packet) of <<0, In/binary>> -> {ok, In}; <<1, Error/binary>> -> {error, binary_to_list(Error)} end. send(#zlibsock{sockmod = SockMod, socket = Socket, zlibport = Port}, Packet) -> case port_control(Port, ?DEFLATE, Packet) of <<0, Out/binary>> -> SockMod:send(Socket, Out); <<1, Error/binary>> -> {error, binary_to_list(Error)} end. setopts(#zlibsock{sockmod = SockMod, socket = Socket}, Opts) -> case SockMod of gen_tcp -> inet:setopts(Socket, Opts); _ -> SockMod:setopts(Socket, Opts) end. sockname(#zlibsock{sockmod = SockMod, socket = Socket}) -> case SockMod of gen_tcp -> inet:sockname(Socket); _ -> SockMod:sockname(Socket) end. get_sockmod(#zlibsock{sockmod = SockMod}) -> SockMod. peername(#zlibsock{sockmod = SockMod, socket = Socket}) -> case SockMod of gen_tcp -> inet:peername(Socket); _ -> SockMod:peername(Socket) end. controlling_process(#zlibsock{sockmod = SockMod, socket = Socket}, Pid) -> SockMod:controlling_process(Socket, Pid). close(#zlibsock{sockmod = SockMod, socket = Socket, zlibport = Port}) -> SockMod:close(Socket), port_close(Port). ejabberd-2.1.11/src/ejabberd_zlib/Makefile.in0000664000000000000000000000235712240230175015637 0ustar # $Id$ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ ZLIB_CFLAGS = @ZLIB_CFLAGS@ ZLIB_LIBS = @ZLIB_LIBS@ ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ # Assume Linux-style dynamic library flags DYNAMIC_LIB_CFLAGS = -fpic -shared ifeq ($(shell uname),Darwin) DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress endif ifeq ($(shell uname),SunOs) DYNAMIC_LIB_CFLAGS = -KPIC -G -z text endif EFLAGS += -I .. EFLAGS += -pz .. # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif ERLSHLIBS = ../ejabberd_zlib_drv.so OUTDIR = .. SOURCES = $(wildcard *.erl) BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) all: $(BEAMS) $(ERLSHLIBS) $(OUTDIR)/%.beam: %.erl @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< #all: $(ERLSHLIBS) # erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt $(ERLSHLIBS): ../%.so: %.c $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \ $(subst ../,,$(subst .so,.c,$@)) \ $(LIBS) \ $(ZLIB_LIBS) \ $(ZLIB_CFLAGS) \ $(ERLANG_LIBS) \ $(ERLANG_CFLAGS) \ -o $@ \ $(DYNAMIC_LIB_CFLAGS) clean: rm -f $(BEAMS) $(ERLSHLIBS) distclean: clean rm -f Makefile TAGS: etags *.erl ejabberd-2.1.11/src/mod_time.erl0000664000000000000000000000642412240230175013314 0ustar %%%---------------------------------------------------------------------- %%% File : mod_time.erl %%% Author : Alexey Shchepin %%% Purpose : %%% Created : 18 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_time). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_local_iq90/3, % TODO: Remove once XEP-0090 is Obsolete process_local_iq/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), %% TODO: Remove the next two lines once XEP-0090 is Obsolete gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME90, ?MODULE, process_local_iq90, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME, ?MODULE, process_local_iq, IQDisc). stop(Host) -> %% TODO: Remove the next line once XEP-0090 is Obsolete gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_TIME90), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_TIME). %% TODO: Remove this function once XEP-0090 is Obsolete process_local_iq90(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> UTC = jlib:timestamp_to_iso(calendar:universal_time()), IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_TIME90}], [{xmlelement, "utc", [], [{xmlcdata, UTC}]}]}]} end. process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> Now = now(), Now_universal = calendar:now_to_universal_time(Now), Now_local = calendar:now_to_local_time(Now), {UTC, UTC_diff} = jlib:timestamp_to_iso(Now_universal, utc), Seconds_diff = calendar:datetime_to_gregorian_seconds(Now_local) - calendar:datetime_to_gregorian_seconds(Now_universal), {Hd, Md, _} = calendar:seconds_to_time(abs(Seconds_diff)), {_, TZO_diff} = jlib:timestamp_to_iso({{0, 0, 0}, {0, 0, 0}}, {sign(Seconds_diff), {Hd, Md}}), IQ#iq{type = result, sub_el = [{xmlelement, "time", [{"xmlns", ?NS_TIME}], [{xmlelement, "tzo", [], [{xmlcdata, TZO_diff}]}, {xmlelement, "utc", [], [{xmlcdata, UTC ++ UTC_diff}]}]}]} end. sign(N) when N < 0 -> "-"; sign(_) -> "+". ejabberd-2.1.11/src/mod_proxy65/0000775000000000000000000000000012240452476013212 5ustar ejabberd-2.1.11/src/mod_proxy65/mod_proxy65_lib.erl0000664000000000000000000000505412240230175016731 0ustar %%%---------------------------------------------------------------------- %%% File : mod_proxy65_lib.erl %%% Author : Evgeniy Khramtsov %%% Purpose : SOCKS5 parsing library. %%% Created : 12 Oct 2006 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_proxy65_lib). -author('xram@jabber.ru'). -include("mod_proxy65.hrl"). -export([ unpack_init_message/1, unpack_auth_request/1, unpack_request/1, make_init_reply/1, make_auth_reply/1, make_reply/1, make_error_reply/1, make_error_reply/2 ]). unpack_init_message(<>) when N > 0, N < 256 -> {ok, binary_to_list(AuthMethodList)}; unpack_init_message(_) -> error. unpack_auth_request(<<1, ULen, User:ULen/binary, PLen, Pass:PLen/binary>>) when ULen < 256, PLen < 256 -> {binary_to_list(User), binary_to_list(Pass)}; unpack_auth_request(_) -> error. unpack_request(<>) when CMD == ?CMD_CONNECT; CMD == ?CMD_UDP -> Command = if CMD == ?CMD_CONNECT -> connect; CMD == ?CMD_UDP -> udp end, #s5_request{cmd = Command, rsv = RSV, sha1 = binary_to_list(SHA1)}; unpack_request(_) -> error. make_init_reply(Method) -> [?VERSION_5, Method]. make_auth_reply(true) -> [1, ?SUCCESS]; make_auth_reply(false) -> [1, ?ERR_NOT_ALLOWED]. make_reply(#s5_request{rsv = RSV, sha1 = SHA1}) -> [?VERSION_5, ?SUCCESS, RSV, ?ATYP_DOMAINNAME, length(SHA1), SHA1, 0,0]. make_error_reply(Request) -> make_error_reply(Request, ?ERR_NOT_ALLOWED). make_error_reply(#s5_request{rsv = RSV, sha1 = SHA1}, Reason) -> [?VERSION_5, Reason, RSV, ?ATYP_DOMAINNAME, length(SHA1), SHA1, 0,0]. ejabberd-2.1.11/src/mod_proxy65/Makefile.win320000664000000000000000000000140212240230175015576 0ustar include ..\Makefile.inc EFLAGS = -I .. -pz .. OUTDIR = .. BEAMS = ..\mod_proxy65.beam ..\mod_proxy65_lib.beam ..\mod_proxy65_service.beam ..\mod_proxy65_sm.beam ..\mod_proxy65_stream.beam ALL : $(BEAMS) CLEAN : -@erase $(BEAMS) $(OUTDIR)\mod_proxy65.beam : mod_proxy65.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65.erl $(OUTDIR)\mod_proxy65_service.beam : mod_proxy65_service.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_service.erl $(OUTDIR)\mod_proxy65_sm.beam : mod_proxy65_sm.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_sm.erl $(OUTDIR)\mod_proxy65_stream.beam : mod_proxy65_stream.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_stream.erl $(OUTDIR)\mod_proxy65_lib.beam : mod_proxy65_lib.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_proxy65_lib.erl ejabberd-2.1.11/src/mod_proxy65/mod_proxy65_service.erl0000664000000000000000000001771312240230175017630 0ustar %%%---------------------------------------------------------------------- %%% File : mod_proxy65_service.erl %%% Author : Evgeniy Khramtsov %%% Purpose : SOCKS5 Bytestreams XMPP service. %%% Created : 12 Oct 2006 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_proxy65_service). -author('xram@jabber.ru'). -behaviour(gen_server). %% gen_server callbacks. -export([init/1, handle_info/2, handle_call/3, handle_cast/2, terminate/2, code_change/3 ]). %% API. -export([start_link/2, add_listener/2, delete_listener/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). -define(PROCNAME, ejabberd_mod_proxy65_service). -record(state, { myhost, serverhost, name, stream_addr, port, ip, acl }). %%%------------------------ %%% gen_server callbacks %%%------------------------ start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). init([Host, Opts]) -> State = parse_options(Host, Opts), ejabberd_router:register_route(State#state.myhost), {ok, State}. terminate(_Reason, #state{myhost=MyHost}) -> ejabberd_router:unregister_route(MyHost), ok. handle_info({route, From, To, {xmlelement, "iq", _, _} = Packet}, State) -> IQ = jlib:iq_query_info(Packet), case catch process_iq(From, IQ, State) of Result when is_record(Result, iq) -> ejabberd_router:route(To, From, jlib:iq_to_xml(Result)); {'EXIT', Reason} -> ?ERROR_MSG("Error when processing IQ stanza: ~p", [Reason]), Err = jlib:make_error_reply(Packet, ?ERR_INTERNAL_SERVER_ERROR), ejabberd_router:route(To, From, Err); _ -> ok end, {noreply, State}; handle_info(_Info, State) -> {noreply, State}. handle_call(get_port_ip, _From, State) -> {reply, {port_ip, State#state.port, State#state.ip}, State}; handle_call(_Request, _From, State) -> {reply, ok, State}. handle_cast(_Request, State) -> {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. %%%------------------------ %%% Listener management %%%------------------------ add_listener(Host, Opts) -> State = parse_options(Host, Opts), NewOpts = [Host | Opts], ejabberd_listener:add_listener({State#state.port, State#state.ip}, mod_proxy65_stream, NewOpts). delete_listener(Host) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), {port_ip, Port, IP} = gen_server:call(Proc, get_port_ip), catch ejabberd_listener:delete_listener({Port, IP}, mod_proxy65_stream). %%%------------------------ %%% IQ Processing %%%------------------------ %% disco#info request process_iq(_, #iq{type = get, xmlns = ?NS_DISCO_INFO, lang = Lang} = IQ, #state{name=Name, serverhost=ServerHost}) -> Info = ejabberd_hooks:run_fold( disco_info, ServerHost, [], [ServerHost, ?MODULE, "", ""]), IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_INFO}], iq_disco_info(Lang, Name) ++ Info}]}; %% disco#items request process_iq(_, #iq{type = get, xmlns = ?NS_DISCO_ITEMS} = IQ, _) -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}], []}]}; %% vCard request process_iq(_, #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} = IQ, _) -> IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", ?NS_VCARD}], iq_vcard(Lang)}]}; %% bytestreams info request process_iq(JID, #iq{type = get, sub_el = SubEl, xmlns = ?NS_BYTESTREAMS} = IQ, #state{acl = ACL, stream_addr = StreamAddr, serverhost = ServerHost}) -> case acl:match_rule(ServerHost, ACL, JID) of allow -> StreamHostEl = [{xmlelement, "streamhost", StreamAddr, []}], IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_BYTESTREAMS}], StreamHostEl}]}; deny -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]} end; %% bytestream activation request process_iq(InitiatorJID, #iq{type = set, sub_el = SubEl, xmlns = ?NS_BYTESTREAMS} = IQ, #state{acl = ACL, serverhost = ServerHost}) -> case acl:match_rule(ServerHost, ACL, InitiatorJID) of allow -> ActivateEl = xml:get_path_s(SubEl, [{elem, "activate"}]), SID = xml:get_tag_attr_s("sid", SubEl), case catch jlib:string_to_jid(xml:get_tag_cdata(ActivateEl)) of TargetJID when is_record(TargetJID, jid), SID /= "", length(SID) =< 128, TargetJID /= InitiatorJID -> Target = jlib:jid_to_string(jlib:jid_tolower(TargetJID)), Initiator = jlib:jid_to_string(jlib:jid_tolower(InitiatorJID)), SHA1 = sha:sha(SID ++ Initiator ++ Target), case mod_proxy65_sm:activate_stream(SHA1, InitiatorJID, TargetJID, ServerHost) of ok -> IQ#iq{type = result, sub_el = []}; false -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}; limit -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_RESOURCE_CONSTRAINT]}; conflict -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_CONFLICT]}; _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} end; _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]} end; deny -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]} end; %% Unknown "set" or "get" request process_iq(_, #iq{type=Type, sub_el=SubEl} = IQ, _) when Type==get; Type==set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]}; %% IQ "result" or "error". process_iq(_, _, _) -> ok. %%%------------------------- %%% Auxiliary functions. %%%------------------------- -define(FEATURE(Feat), {xmlelement,"feature",[{"var", Feat}],[]}). iq_disco_info(Lang, Name) -> [{xmlelement, "identity", [{"category", "proxy"}, {"type", "bytestreams"}, {"name", translate:translate(Lang, Name)}], []}, ?FEATURE(?NS_DISCO_INFO), ?FEATURE(?NS_VCARD), ?FEATURE(?NS_BYTESTREAMS)]. iq_vcard(Lang) -> [{xmlelement, "FN", [], [{xmlcdata, "ejabberd/mod_proxy65"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate(Lang, "ejabberd SOCKS5 Bytestreams module") ++ "\nCopyright (c) 2003-2012 ProcessOne"}]}]. parse_options(ServerHost, Opts) -> MyHost = gen_mod:get_opt_host(ServerHost, Opts, "proxy.@HOST@"), Port = gen_mod:get_opt(port, Opts, 7777), ACL = gen_mod:get_opt(access, Opts, all), Name = gen_mod:get_opt(name, Opts, "SOCKS5 Bytestreams"), IP = case gen_mod:get_opt(ip, Opts, none) of none -> get_my_ip(); Addr -> Addr end, HostName = case gen_mod:get_opt(hostname, Opts, none) of none -> inet_parse:ntoa(IP); HostAddr when is_tuple(HostAddr) -> inet_parse:ntoa(HostAddr); HostNameStr -> HostNameStr end, StreamAddr = [{"jid", MyHost}, {"host", HostName}, {"port", integer_to_list(Port)}], #state{myhost = MyHost, serverhost = ServerHost, name = Name, port = Port, ip = IP, stream_addr = StreamAddr, acl = ACL}. get_my_ip() -> {ok, MyHostName} = inet:gethostname(), case inet:getaddr(MyHostName, inet) of {ok, Addr} -> Addr; {error, _} -> {127,0,0,1} end. ejabberd-2.1.11/src/mod_proxy65/mod_proxy65_stream.erl0000664000000000000000000002140112240230175017450 0ustar %%%---------------------------------------------------------------------- %%% File : mod_proxy65_stream.erl %%% Author : Evgeniy Khramtsov %%% Purpose : Bytestream process. %%% Created : 12 Oct 2006 by Evgeniy Khramtsov %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_proxy65_stream). -author('xram@jabber.ru'). -behaviour(gen_fsm). %% gen_fsm callbacks. -export([ init/1, handle_event/3, handle_sync_event/4, code_change/4, handle_info/3, terminate/3 ]). %% gen_fsm states. -export([ wait_for_init/2, wait_for_auth/2, wait_for_request/2, wait_for_activation/2, stream_established/2 ]). %% API. -export([ start/2, stop/1, start_link/3, activate/2, relay/3, socket_type/0 ]). -include("mod_proxy65.hrl"). -include("ejabberd.hrl"). -define(WAIT_TIMEOUT, 60000). %% 1 minute (is it enough?) -record(state, { socket, %% TCP socket timer, %% timer reference sha1, %% SHA1 key host, %% virtual host auth_type, %% authentication type: anonymous or plain shaper %% Shaper name }). %% Unused callbacks handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData}. code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. %%------------------------------- start({gen_tcp, Socket}, Opts1) -> {[Host], Opts} = lists:partition(fun(O) -> is_list(O) end, Opts1), Supervisor = gen_mod:get_module_proc(Host, ejabberd_mod_proxy65_sup), supervisor:start_child(Supervisor, [Socket, Host, Opts]). start_link(Socket, Host, Opts) -> gen_fsm:start_link(?MODULE, [Socket, Host, Opts], []). init([Socket, Host, Opts]) -> process_flag(trap_exit, true), AuthType = gen_mod:get_opt(auth_type, Opts, anonymous), Shaper = gen_mod:get_opt(shaper, Opts, none), RecvBuf = gen_mod:get_opt(recbuf, Opts, 8192), SendBuf = gen_mod:get_opt(sndbuf, Opts, 8192), TRef = erlang:send_after(?WAIT_TIMEOUT, self(), stop), inet:setopts(Socket, [{active, true}, {recbuf, RecvBuf}, {sndbuf, SendBuf}]), {ok, wait_for_init, #state{host = Host, auth_type = AuthType, socket = Socket, shaper = Shaper, timer = TRef}}. terminate(_Reason, StateName, #state{sha1=SHA1}) -> catch mod_proxy65_sm:unregister_stream(SHA1), if StateName == stream_established -> ?INFO_MSG("Bytestream terminated", []); true -> ok end. %%%------------------------------ %%% API. %%%------------------------------ socket_type() -> raw. stop(StreamPid) -> StreamPid ! stop. activate({P1, J1}, {P2, J2}) -> case catch {gen_fsm:sync_send_all_state_event(P1, get_socket), gen_fsm:sync_send_all_state_event(P2, get_socket)} of {S1, S2} when is_port(S1), is_port(S2) -> P1 ! {activate, P2, S2, J1, J2}, P2 ! {activate, P1, S1, J1, J2}, JID1 = jlib:jid_to_string(J1), JID2 = jlib:jid_to_string(J2), ?INFO_MSG("(~w:~w) Activated bytestream for ~s -> ~s", [P1, P2, JID1, JID2]), ok; _ -> error end. %%%----------------------- %%% States %%%----------------------- wait_for_init(Packet, #state{socket=Socket, auth_type=AuthType} = StateData) -> case mod_proxy65_lib:unpack_init_message(Packet) of {ok, AuthMethods} -> Method = select_auth_method(AuthType, AuthMethods), gen_tcp:send(Socket, mod_proxy65_lib:make_init_reply(Method)), case Method of ?AUTH_ANONYMOUS -> {next_state, wait_for_request, StateData}; ?AUTH_PLAIN -> {next_state, wait_for_auth, StateData}; ?AUTH_NO_METHODS -> {stop, normal, StateData} end; error -> {stop, normal, StateData} end. wait_for_auth(Packet, #state{socket=Socket, host=Host} = StateData) -> case mod_proxy65_lib:unpack_auth_request(Packet) of {User, Pass} -> Result = ejabberd_auth:check_password(User, Host, Pass), gen_tcp:send(Socket, mod_proxy65_lib:make_auth_reply(Result)), case Result of true -> {next_state, wait_for_request, StateData}; false -> {stop, normal, StateData} end; _ -> {stop, normal, StateData} end. wait_for_request(Packet, #state{socket=Socket} = StateData) -> Request = mod_proxy65_lib:unpack_request(Packet), case Request of #s5_request{sha1=SHA1, cmd=connect} -> case catch mod_proxy65_sm:register_stream(SHA1) of {atomic, ok} -> inet:setopts(Socket, [{active, false}]), gen_tcp:send(Socket, mod_proxy65_lib:make_reply(Request)), {next_state, wait_for_activation, StateData#state{sha1=SHA1}}; _ -> Err = mod_proxy65_lib:make_error_reply(Request), gen_tcp:send(Socket, Err), {stop, normal, StateData} end; #s5_request{cmd=udp} -> Err = mod_proxy65_lib:make_error_reply(Request, ?ERR_COMMAND_NOT_SUPPORTED), gen_tcp:send(Socket, Err), {stop, normal, StateData}; _ -> {stop, normal, StateData} end. wait_for_activation(_Data, StateData) -> {next_state, wait_for_activation, StateData}. stream_established(_Data, StateData) -> {next_state, stream_established, StateData}. %%%----------------------- %%% Callbacks processing %%%----------------------- %% SOCKS5 packets. handle_info({tcp, _S, Data}, StateName, StateData) when StateName /= wait_for_activation -> erlang:cancel_timer(StateData#state.timer), TRef = erlang:send_after(?WAIT_TIMEOUT, self(), stop), gen_fsm:send_event(self(), Data), {next_state, StateName, StateData#state{timer=TRef}}; %% Activation message. handle_info({activate, PeerPid, PeerSocket, IJid, TJid}, wait_for_activation, StateData) -> erlang:monitor(process, PeerPid), erlang:cancel_timer(StateData#state.timer), MySocket = StateData#state.socket, Shaper = StateData#state.shaper, Host = StateData#state.host, MaxRate = find_maxrate(Shaper, IJid, TJid, Host), spawn_link(?MODULE, relay, [MySocket, PeerSocket, MaxRate]), {next_state, stream_established, StateData}; %% Socket closed handle_info({tcp_closed, _Socket}, _StateName, StateData) -> {stop, normal, StateData}; handle_info({tcp_error, _Socket, _Reason}, _StateName, StateData) -> {stop, normal, StateData}; %% Got stop message. handle_info(stop, _StateName, StateData) -> {stop, normal, StateData}; %% Either linked process or peer process died. handle_info({'EXIT',_,_}, _StateName, StateData) -> {stop, normal, StateData}; handle_info({'DOWN',_,_,_,_}, _StateName, StateData) -> {stop, normal, StateData}; %% Packets of no interest handle_info(_Info, StateName, StateData) -> {next_state, StateName, StateData}. %% Socket request. handle_sync_event(get_socket, _From, wait_for_activation, StateData) -> Socket = StateData#state.socket, {reply, Socket, wait_for_activation, StateData}; handle_sync_event(_Event, _From, StateName, StateData) -> {reply, error, StateName, StateData}. %%%------------------------------------------------- %%% Relay Process. %%%------------------------------------------------- relay(MySocket, PeerSocket, Shaper) -> case gen_tcp:recv(MySocket, 0) of {ok, Data} -> gen_tcp:send(PeerSocket, Data), {NewShaper, Pause} = shaper:update(Shaper, size(Data)), if Pause > 0 -> timer:sleep(Pause); true -> pass end, relay(MySocket, PeerSocket, NewShaper); _ -> stopped end. %%%------------------------ %%% Auxiliary functions %%%------------------------ select_auth_method(plain, AuthMethods) -> case lists:member(?AUTH_PLAIN, AuthMethods) of true -> ?AUTH_PLAIN; false -> ?AUTH_NO_METHODS end; select_auth_method(anonymous, AuthMethods) -> case lists:member(?AUTH_ANONYMOUS, AuthMethods) of true -> ?AUTH_ANONYMOUS; false -> ?AUTH_NO_METHODS end. %% Obviously, we must use shaper with maximum rate. find_maxrate(Shaper, JID1, JID2, Host) -> MaxRate1 = shaper:new(acl:match_rule(Host, Shaper, JID1)), MaxRate2 = shaper:new(acl:match_rule(Host, Shaper, JID2)), if MaxRate1 == none; MaxRate2 == none -> none; true -> lists:max([MaxRate1, MaxRate2]) end. ejabberd-2.1.11/src/mod_proxy65/mod_proxy65.hrl0000664000000000000000000000334012240230175016102 0ustar %%%---------------------------------------------------------------------- %%% RFC 1928 constants. %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %% Version -define(VERSION_5, 5). %% Authentication methods -define(AUTH_ANONYMOUS, 0). -define(AUTH_GSSAPI, 1). -define(AUTH_PLAIN, 2). -define(AUTH_NO_METHODS, 16#FF). %% Address Type -define(ATYP_IPV4, 1). -define(ATYP_DOMAINNAME, 3). -define(ATYP_IPV6, 4). %% Commands -define(CMD_CONNECT, 1). -define(CMD_BIND, 2). -define(CMD_UDP, 3). %% RFC 1928 replies -define(SUCCESS, 0). -define(ERR_GENERAL_FAILURE, 1). -define(ERR_NOT_ALLOWED, 2). -define(ERR_NETWORK_UNREACHABLE, 3). -define(ERR_HOST_UNREACHABLE, 4). -define(ERR_CONNECTION_REFUSED, 5). -define(ERR_TTL_EXPIRED, 6). -define(ERR_COMMAND_NOT_SUPPORTED, 7). -define(ERR_ADDRESS_TYPE_NOT_SUPPORTED, 8). %% RFC 1928 defined timeout. -define(SOCKS5_REPLY_TIMEOUT, 10000). -record(s5_request, { rsv = 0, cmd, sha1 }). ejabberd-2.1.11/src/mod_proxy65/Makefile.in0000664000000000000000000000107012240230175015243 0ustar # $Id$ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ EFLAGS += -I .. EFLAGS += -pz .. # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif OUTDIR = .. SOURCES = $(wildcard *.erl) BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) all: $(BEAMS) $(OUTDIR)/%.beam: %.erl @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< clean: rm -f $(BEAMS) distclean: clean rm -f Makefile TAGS: etags *.erl ejabberd-2.1.11/src/mod_proxy65/mod_proxy65.erl0000664000000000000000000000524012240230175016100 0ustar %%%---------------------------------------------------------------------- %%% File : mod_proxy65.erl %%% Author : Evgeniy Khramtsov %%% Purpose : Main supervisor. %%% Created : 12 Oct 2006 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_proxy65). -author('xram@jabber.ru'). -behaviour(gen_mod). -behaviour(supervisor). %% gen_mod callbacks. -export([start/2, stop/1]). %% supervisor callbacks. -export([init/1]). %% API. -export([start_link/2]). -define(PROCNAME, ejabberd_mod_proxy65). start(Host, Opts) -> case mod_proxy65_service:add_listener(Host, Opts) of {error, _} = Err -> erlang:error(Err); _ -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ChildSpec = { Proc, {?MODULE, start_link, [Host, Opts]}, transient, infinity, supervisor, [?MODULE] }, supervisor:start_child(ejabberd_sup, ChildSpec) end. stop(Host) -> mod_proxy65_service:delete_listener(Host), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), supervisor:start_link({local, Proc}, ?MODULE, [Host, Opts]). init([Host, Opts]) -> Service = {mod_proxy65_service, {mod_proxy65_service, start_link, [Host, Opts]}, transient, 5000, worker, [mod_proxy65_service]}, StreamSupervisor = {ejabberd_mod_proxy65_sup, {ejabberd_tmp_sup, start_link, [gen_mod:get_module_proc(Host, ejabberd_mod_proxy65_sup), mod_proxy65_stream]}, transient, infinity, supervisor, [ejabberd_tmp_sup]}, StreamManager = {mod_proxy65_sm, {mod_proxy65_sm, start_link, [Host, Opts]}, transient, 5000, worker, [mod_proxy65_sm]}, {ok, {{one_for_one, 10, 1}, [StreamManager, StreamSupervisor, Service]}}. ejabberd-2.1.11/src/mod_proxy65/mod_proxy65_sm.erl0000664000000000000000000001243312240230175016601 0ustar %%%---------------------------------------------------------------------- %%% File : mod_proxy65_sm.erl %%% Author : Evgeniy Khramtsov %%% Purpose : Bytestreams manager. %%% Created : 12 Oct 2006 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_proxy65_sm). -author('xram@jabber.ru'). -behaviour(gen_server). %% gen_server callbacks. -export([init/1, handle_info/2, handle_call/3, handle_cast/2, terminate/2, code_change/3 ]). %% API. -export([ start_link/2, register_stream/1, unregister_stream/1, activate_stream/4 ]). -record(state, {max_connections}). -record(bytestream, { sha1, %% SHA1 key target, %% Target Pid initiator, %% Initiator Pid active = false, %% Activity flag jid_i %% Initiator's JID }). -define(PROCNAME, ejabberd_mod_proxy65_sm). %% Unused callbacks. handle_cast(_Request, State) -> {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. handle_info(_Info, State) -> {noreply, State}. %%---------------- start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Opts], []). init([Opts]) -> mnesia:create_table(bytestream, [{ram_copies, [node()]}, {attributes, record_info(fields, bytestream)}]), mnesia:add_table_copy(bytestream, node(), ram_copies), MaxConnections = gen_mod:get_opt(max_connections, Opts, infinity), {ok, #state{max_connections=MaxConnections}}. terminate(_Reason, _State) -> ok. handle_call({activate, SHA1, IJid}, _From, State) -> MaxConns = State#state.max_connections, F = fun() -> case mnesia:read(bytestream, SHA1, write) of [#bytestream{target = TPid, initiator = IPid} = ByteStream] when is_pid(TPid), is_pid(IPid) -> ActiveFlag = ByteStream#bytestream.active, if ActiveFlag == false -> ConnsPerJID = mnesia:select(bytestream, [{#bytestream{sha1 = '$1', jid_i = IJid, _='_'}, [], ['$1']}]), if length(ConnsPerJID) < MaxConns -> mnesia:write( ByteStream#bytestream{active = true, jid_i = IJid}), {ok, IPid, TPid}; true -> {limit, IPid, TPid} end; true -> conflict end; _ -> false end end, Reply = mnesia:transaction(F), {reply, Reply, State}; handle_call(_Request, _From, State) -> {reply, ok, State}. %%%---------------------- %%% API. %%%---------------------- %%%--------------------------------------------------- %%% register_stream(SHA1) -> {atomic, ok} | %%% {atomic, error} | %%% transaction abort %%% SHA1 = string() %%%--------------------------------------------------- register_stream(SHA1) when is_list(SHA1) -> StreamPid = self(), F = fun() -> case mnesia:read(bytestream, SHA1, write) of [] -> mnesia:write(#bytestream{sha1 = SHA1, target = StreamPid}); [#bytestream{target = Pid, initiator = undefined} = ByteStream] when is_pid(Pid), Pid /= StreamPid -> mnesia:write( ByteStream#bytestream{initiator = StreamPid}); _ -> error end end, mnesia:transaction(F). %%%---------------------------------------------------- %%% unregister_stream(SHA1) -> ok | transaction abort %%% SHA1 = string() %%%---------------------------------------------------- unregister_stream(SHA1) when is_list(SHA1) -> F = fun() -> mnesia:delete({bytestream, SHA1}) end, mnesia:transaction(F). %%%-------------------------------------------------------- %%% activate_stream(SHA1, IJid, TJid, Host) -> ok | %%% false | %%% limit | %%% conflict | %%% error %%% SHA1 = string() %%% IJid = TJid = jid() %%% Host = string() %%%-------------------------------------------------------- activate_stream(SHA1, IJid, TJid, Host) when is_list(SHA1) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), case catch gen_server:call(Proc, {activate, SHA1, IJid}) of {atomic, {ok, IPid, TPid}} -> mod_proxy65_stream:activate({IPid, IJid}, {TPid, TJid}); {atomic, {limit, IPid, TPid}} -> mod_proxy65_stream:stop(IPid), mod_proxy65_stream:stop(TPid), limit; {atomic, conflict} -> conflict; {atomic, false} -> false; _ -> error end. ejabberd-2.1.11/src/xml.erl0000664000000000000000000001734212240230175012320 0ustar %%%---------------------------------------------------------------------- %%% File : xml.erl %%% Author : Alexey Shchepin %%% Purpose : XML utils %%% Created : 20 Nov 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(xml). -author('alexey@process-one.net'). -export([element_to_string/1, element_to_binary/1, crypt/1, make_text_node/1, remove_cdata/1, get_cdata/1, get_tag_cdata/1, get_attr/2, get_attr_s/2, get_tag_attr/2, get_tag_attr_s/2, get_subtag/2, get_subtag_cdata/2, append_subtags/2, get_path_s/2, start/0, replace_tag_attr/3]). -include("ejabberd.hrl"). %% Select at compile time how to escape characters in binary text %% nodes. %% Can be choosen with ./configure --enable-full-xml -ifdef(FULL_XML_SUPPORT). -define(ESCAPE_BINARY(CData), make_text_node(CData)). -else. -define(ESCAPE_BINARY(CData), crypt(CData)). -endif. %% Replace element_to_binary/1 with NIF %% Can be choosen with ./configure --enable-nif -ifdef(NIF). start() -> SOPath = filename:join(ejabberd:get_so_path(), "xml"), case catch erlang:load_nif(SOPath, 0) of ok -> ok; Err -> ?WARNING_MSG("unable to load xml NIF: ~p", [Err]) end. -else. start() -> ok. -endif. element_to_binary(El) -> iolist_to_binary(element_to_string(El)). element_to_string(El) -> case catch element_to_string_nocatch(El) of {'EXIT', Reason} -> erlang:error({badxml, El, Reason}); Result -> Result end. element_to_string_nocatch(El) -> case El of {xmlelement, Name, Attrs, Els} -> if Els /= [] -> [$<, Name, attrs_to_list(Attrs), $>, [element_to_string_nocatch(E) || E <- Els], $<, $/, Name, $>]; true -> [$<, Name, attrs_to_list(Attrs), $/, $>] end; %% We do not crypt CDATA binary, but we enclose it in XML CDATA {xmlcdata, CData} when is_binary(CData) -> ?ESCAPE_BINARY(CData); %% We crypt list and possibly binaries if full XML usage is %% disabled unsupported (implies a conversion to list). {xmlcdata, CData} -> crypt(CData) end. attrs_to_list(Attrs) -> [attr_to_list(A) || A <- Attrs]. attr_to_list({Name, Value}) -> [$\s, Name, $=, $', crypt(Value), $']. crypt(S) when is_list(S) -> [case C of $& -> "&"; $< -> "<"; $> -> ">"; $" -> """; $' -> "'"; _ when is_list(C); is_binary(C) -> crypt(C); _ -> C end || C <- S]; crypt(S) when is_binary(S) -> crypt(binary_to_list(S)). %% Make a cdata_binary depending on what characters it contains make_text_node(CData) -> case cdata_need_escape(CData) of cdata -> CDATA1 = <<">, CDATA2 = <<"]]>">>, list_to_binary([CDATA1, CData, CDATA2]); none -> CData; {cdata, EndTokens} -> EscapedCData = escape_cdata(CData, EndTokens), list_to_binary(EscapedCData) end. %% Returns escape type needed for the text node %% none, cdata, {cdata, [Positions]} %% Positions is a list a integer containing positions of CDATA end %% tokens, so that they can be escaped cdata_need_escape(CData) -> cdata_need_escape(CData, 0, false, []). cdata_need_escape(<<>>, _, false, _) -> none; cdata_need_escape(<<>>, _, true, []) -> cdata; cdata_need_escape(<<>>, _, true, CDataEndTokens) -> {cdata, lists:reverse(CDataEndTokens)}; cdata_need_escape(<<$],$],$>,Rest/binary>>, CurrentPosition, _XMLEscape, CDataEndTokens) -> NewPosition = CurrentPosition + 3, cdata_need_escape(Rest, NewPosition, true, [CurrentPosition+1|CDataEndTokens]); %% Only <, & need to be escaped in XML text node %% See reference: http://www.w3.org/TR/xml11/#syntax cdata_need_escape(<<$<,Rest/binary>>, CurrentPosition, _XMLEscape, CDataEndTokens) -> cdata_need_escape(Rest, CurrentPosition+1, true, CDataEndTokens); cdata_need_escape(<<$&,Rest/binary>>, CurrentPosition, _XMLEscape, CDataEndTokens) -> cdata_need_escape(Rest, CurrentPosition+1, true, CDataEndTokens); cdata_need_escape(<<_:8,Rest/binary>>, CurrentPosition, XMLEscape, CDataEndTokens) -> cdata_need_escape(Rest, CurrentPosition+1, XMLEscape, CDataEndTokens). %% escape cdata that contain CDATA end tokens %% EndTokens is a list of position of end tokens (integer) %% This is supposed to be a very rare case: You need to generate several %% fields, splitting it in the middle of the end token. %% See example: http://en.wikipedia.org/wiki/CDATA#Uses_of_CDATA_sections escape_cdata(CData, EndTokens) -> escape_cdata(CData, 0, EndTokens, []). escape_cdata(<<>>, _CurrentPosition, [], Acc) -> lists:reverse(Acc); escape_cdata(Rest, CurrentPosition, [], Acc) -> CDATA1 = <<">, CDATA2 = <<"]]>">>, escape_cdata(<<>>, CurrentPosition, [], [CDATA2, Rest, CDATA1|Acc]); escape_cdata(CData, Index, [Pos|Positions], Acc) -> CDATA1 = <<">, CDATA2 = <<"]]>">>, Split = Pos-Index, {Part, Rest} = split_binary(CData, Split+1), %% Note: We build the list in reverse to optimize construction escape_cdata(Rest, Pos+1, Positions, [CDATA2, Part, CDATA1|Acc]). remove_cdata_p({xmlelement, _Name, _Attrs, _Els}) -> true; remove_cdata_p(_) -> false. remove_cdata(L) -> [E || E <- L, remove_cdata_p(E)]. get_cdata(L) -> binary_to_list(list_to_binary(get_cdata(L, ""))). get_cdata([{xmlcdata, CData} | L], S) -> get_cdata(L, [S, CData]); get_cdata([_ | L], S) -> get_cdata(L, S); get_cdata([], S) -> S. get_tag_cdata({xmlelement, _Name, _Attrs, Els}) -> get_cdata(Els). get_attr(AttrName, Attrs) -> case lists:keysearch(AttrName, 1, Attrs) of {value, {_, Val}} -> {value, Val}; _ -> false end. get_attr_s(AttrName, Attrs) -> case lists:keysearch(AttrName, 1, Attrs) of {value, {_, Val}} -> Val; _ -> "" end. get_tag_attr(AttrName, {xmlelement, _Name, Attrs, _Els}) -> get_attr(AttrName, Attrs). get_tag_attr_s(AttrName, {xmlelement, _Name, Attrs, _Els}) -> get_attr_s(AttrName, Attrs). get_subtag({xmlelement, _, _, Els}, Name) -> get_subtag1(Els, Name). get_subtag1([El | Els], Name) -> case El of {xmlelement, Name, _, _} -> El; _ -> get_subtag1(Els, Name) end; get_subtag1([], _) -> false. get_subtag_cdata(Tag, Name) -> case get_subtag(Tag, Name) of false -> ""; Subtag -> get_tag_cdata(Subtag) end. append_subtags({xmlelement, Name, Attrs, SubTags1}, SubTags2) -> {xmlelement, Name, Attrs, SubTags1 ++ SubTags2}. get_path_s(El, []) -> El; get_path_s(El, [{elem, Name} | Path]) -> case get_subtag(El, Name) of false -> ""; SubEl -> get_path_s(SubEl, Path) end; get_path_s(El, [{attr, Name}]) -> get_tag_attr_s(Name, El); get_path_s(El, [cdata]) -> get_tag_cdata(El). replace_tag_attr(Attr, Value, {xmlelement, Name, Attrs, Els}) -> Attrs1 = lists:keydelete(Attr, 1, Attrs), Attrs2 = [{Attr, Value} | Attrs1], {xmlelement, Name, Attrs2, Els}. ejabberd-2.1.11/src/ejabberd_auth_external.erl0000664000000000000000000002356112240230175016201 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_auth_external.erl %%% Author : Alexey Shchepin %%% Purpose : Authentification via LDAP external script %%% Created : 12 Dec 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_auth_external). -author('alexey@process-one.net'). %% External exports -export([start/1, set_password/3, check_password/3, check_password/5, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, get_vh_registered_users_number/1, get_vh_registered_users_number/2, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, remove_user/3, store_type/0, plain_password_required/0 ]). -include("ejabberd.hrl"). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start(Host) -> extauth:start( Host, ejabberd_config:get_local_option({extauth_program, Host})), case check_cache_last_options(Host) of cache -> ok = ejabberd_auth_internal:start(Host); no_cache -> ok end. check_cache_last_options(Server) -> %% if extauth_cache is enabled, then a mod_last module must also be enabled case get_cache_option(Server) of false -> no_cache; {true, _CacheTime} -> case get_mod_last_configured(Server) of no_mod_last -> ?ERROR_MSG("In host ~p extauth is used, extauth_cache is enabled but " "mod_last is not enabled.", [Server]), no_cache; _ -> cache end end. plain_password_required() -> true. store_type() -> external. check_password(User, Server, Password) -> case get_cache_option(Server) of false -> check_password_extauth(User, Server, Password); {true, CacheTime} -> check_password_cache(User, Server, Password, CacheTime) end. check_password(User, Server, Password, _Digest, _DigestGen) -> check_password(User, Server, Password). set_password(User, Server, Password) -> case extauth:set_password(User, Server, Password) of true -> set_password_internal(User, Server, Password), ok; _ -> {error, unknown_problem} end. try_register(User, Server, Password) -> case get_cache_option(Server) of false -> try_register_extauth(User, Server, Password); {true, _CacheTime} -> try_register_external_cache(User, Server, Password) end. dirty_get_registered_users() -> ejabberd_auth_internal:dirty_get_registered_users(). get_vh_registered_users(Server) -> ejabberd_auth_internal:get_vh_registered_users(Server). get_vh_registered_users(Server, Data) -> ejabberd_auth_internal:get_vh_registered_users(Server, Data). get_vh_registered_users_number(Server) -> ejabberd_auth_internal:get_vh_registered_users_number(Server). get_vh_registered_users_number(Server, Data) -> ejabberd_auth_internal:get_vh_registered_users_number(Server, Data). %% The password can only be returned if cache is enabled, cached info exists and is fresh enough. get_password(User, Server) -> case get_cache_option(Server) of false -> false; {true, CacheTime} -> get_password_cache(User, Server, CacheTime) end. get_password_s(User, Server) -> case get_password(User, Server) of false -> []; Other -> Other end. %% @spec (User, Server) -> true | false | {error, Error} is_user_exists(User, Server) -> try extauth:is_user_exists(User, Server) of Res -> Res catch _:Error -> {error, Error} end. remove_user(User, Server) -> case extauth:remove_user(User, Server) of false -> false; true -> case get_cache_option(Server) of false -> false; {true, _CacheTime} -> ejabberd_auth_internal:remove_user(User, Server) end end. remove_user(User, Server, Password) -> case extauth:remove_user(User, Server, Password) of false -> false; true -> case get_cache_option(Server) of false -> false; {true, _CacheTime} -> ejabberd_auth_internal:remove_user(User, Server, Password) end end. %%% %%% Extauth cache management %%% %% @spec (Host::string()) -> false | {true, CacheTime::integer()} get_cache_option(Host) -> case ejabberd_config:get_local_option({extauth_cache, Host}) of CacheTime when is_integer(CacheTime) -> {true, CacheTime}; _ -> false end. %% @spec (User, Server, Password) -> true | false check_password_extauth(User, Server, Password) -> extauth:check_password(User, Server, Password) andalso Password /= "". %% @spec (User, Server, Password) -> true | false try_register_extauth(User, Server, Password) -> extauth:try_register(User, Server, Password). check_password_cache(User, Server, Password, CacheTime) -> case get_last_access(User, Server) of online -> check_password_internal(User, Server, Password); never -> check_password_external_cache(User, Server, Password); mod_last_required -> ?ERROR_MSG("extauth is used, extauth_cache is enabled but mod_last is not enabled in that host", []), check_password_external_cache(User, Server, Password); TimeStamp -> %% If last access exists, compare last access with cache refresh time case is_fresh_enough(TimeStamp, CacheTime) of %% If no need to refresh, check password against Mnesia true -> case check_password_internal(User, Server, Password) of %% If password valid in Mnesia, accept it true -> true; %% Else (password nonvalid in Mnesia), check in extauth and cache result false -> check_password_external_cache(User, Server, Password) end; %% Else (need to refresh), check in extauth and cache result false -> check_password_external_cache(User, Server, Password) end end. get_password_internal(User, Server) -> ejabberd_auth_internal:get_password(User, Server). %% @spec (User, Server, CacheTime) -> false | Password::string() get_password_cache(User, Server, CacheTime) -> case get_last_access(User, Server) of online -> get_password_internal(User, Server); never -> false; mod_last_required -> ?ERROR_MSG("extauth is used, extauth_cache is enabled but mod_last is not enabled in that host", []), false; TimeStamp -> case is_fresh_enough(TimeStamp, CacheTime) of true -> get_password_internal(User, Server); false -> false end end. %% Check the password using extauth; if success then cache it check_password_external_cache(User, Server, Password) -> case check_password_extauth(User, Server, Password) of true -> set_password_internal(User, Server, Password), true; false -> false end. %% Try to register using extauth; if success then cache it try_register_external_cache(User, Server, Password) -> case try_register_extauth(User, Server, Password) of {atomic, ok} = R -> set_password_internal(User, Server, Password), R; _ -> {error, not_allowed} end. %% @spec (User, Server, Password) -> true | false check_password_internal(User, Server, Password) -> ejabberd_auth_internal:check_password(User, Server, Password). %% @spec (User, Server, Password) -> ok | {error, invalid_jid} set_password_internal(User, Server, Password) -> ejabberd_auth_internal:set_password(User, Server, Password). %% @spec (TimeLast, CacheTime) -> true | false %% TimeLast = online | never | integer() %% CacheTime = integer() | false is_fresh_enough(online, _CacheTime) -> true; is_fresh_enough(never, _CacheTime) -> false; is_fresh_enough(TimeStampLast, CacheTime) -> {MegaSecs, Secs, _MicroSecs} = now(), Now = MegaSecs * 1000000 + Secs, (TimeStampLast + CacheTime > Now). %% @spec (User, Server) -> online | never | mod_last_required | TimeStamp::integer() %% Code copied from mod_configure.erl %% Code copied from web/ejabberd_web_admin.erl %% TODO: Update time format to XEP-0202: Entity Time get_last_access(User, Server) -> case ejabberd_sm:get_user_resources(User, Server) of [] -> _US = {User, Server}, case get_last_info(User, Server) of mod_last_required -> mod_last_required; not_found -> never; {ok, Timestamp, _Status} -> Timestamp end; _ -> online end. %% @spec (User, Server) -> {ok, Timestamp, Status} | not_found | mod_last_required get_last_info(User, Server) -> case get_mod_last_enabled(Server) of mod_last -> mod_last:get_last_info(User, Server); mod_last_odbc -> mod_last_odbc:get_last_info(User, Server); no_mod_last -> mod_last_required end. %% @spec (Server) -> mod_last | mod_last_odbc | no_mod_last get_mod_last_enabled(Server) -> ML = gen_mod:is_loaded(Server, mod_last), MLO = gen_mod:is_loaded(Server, mod_last_odbc), case {ML, MLO} of {true, _} -> mod_last; {false, true} -> mod_last_odbc; {false, false} -> no_mod_last end. get_mod_last_configured(Server) -> ML = is_configured(Server, mod_last), MLO = is_configured(Server, mod_last_odbc), case {ML, MLO} of {true, _} -> mod_last; {false, true} -> mod_last_odbc; {false, false} -> no_mod_last end. is_configured(Host, Module) -> lists:keymember(Module, 1, ejabberd_config:get_local_option({modules, Host})). ejabberd-2.1.11/src/mod_configure2.erl0000664000000000000000000001347712240230175014427 0ustar %%%---------------------------------------------------------------------- %%% File : mod_configure2.erl %%% Author : Alexey Shchepin %%% Purpose : Support for online configuration of ejabberd %%% Created : 26 Oct 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_configure2). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_local_iq/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -define(NS_ECONFIGURE, "http://ejabberd.jabberstudio.org/protocol/configure"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE, ?MODULE, process_local_iq, IQDisc), ok. stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE). process_local_iq(From, To, #iq{type = Type, lang = _Lang, sub_el = SubEl} = IQ) -> case acl:match_rule(To#jid.lserver, configure, From) of deny -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; allow -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]}; %%case xml:get_tag_attr_s("type", SubEl) of %% "cancel" -> %% IQ#iq{type = result, %% sub_el = [{xmlelement, "query", %% [{"xmlns", XMLNS}], []}]}; %% "submit" -> %% XData = jlib:parse_xdata_submit(SubEl), %% case XData of %% invalid -> %% IQ#iq{type = error, %% sub_el = [SubEl, ?ERR_BAD_REQUEST]}; %% _ -> %% Node = %% string:tokens( %% xml:get_tag_attr_s("node", SubEl), %% "/"), %% case set_form(Node, Lang, XData) of %% {result, Res} -> %% IQ#iq{type = result, %% sub_el = [{xmlelement, "query", %% [{"xmlns", XMLNS}], %% Res %% }]}; %% {error, Error} -> %% IQ#iq{type = error, %% sub_el = [SubEl, Error]} %% end %% end; %% _ -> %% IQ#iq{type = error, %% sub_el = [SubEl, ?ERR_NOT_ALLOWED]} %%end; get -> case process_get(SubEl) of {result, Res} -> IQ#iq{type = result, sub_el = [Res]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end end end. process_get({xmlelement, "info", _Attrs, _SubEls}) -> S2SConns = ejabberd_s2s:dirty_get_connections(), TConns = lists:usort([element(2, C) || C <- S2SConns]), Attrs = [{"registered-users", integer_to_list(mnesia:table_info(passwd, size))}, {"online-users", integer_to_list(mnesia:table_info(presence, size))}, {"running-nodes", integer_to_list(length(mnesia:system_info(running_db_nodes)))}, {"stopped-nodes", integer_to_list( length(lists:usort(mnesia:system_info(db_nodes) ++ mnesia:system_info(extra_db_nodes)) -- mnesia:system_info(running_db_nodes)))}, {"outgoing-s2s-servers", integer_to_list(length(TConns))}], {result, {xmlelement, "info", [{"xmlns", ?NS_ECONFIGURE} | Attrs], []}}; process_get({xmlelement, "welcome-message", Attrs, _SubEls}) -> {Subj, Body} = case ejabberd_config:get_local_option(welcome_message) of {_Subj, _Body} = SB -> SB; _ -> {"", ""} end, {result, {xmlelement, "welcome-message", Attrs, [{xmlelement, "subject", [], [{xmlcdata, Subj}]}, {xmlelement, "body", [], [{xmlcdata, Body}]}]}}; process_get({xmlelement, "registration-watchers", Attrs, _SubEls}) -> SubEls = case ejabberd_config:get_local_option(registration_watchers) of JIDs when is_list(JIDs) -> lists:map(fun(JID) -> {xmlelement, "jid", [], [{xmlcdata, JID}]} end, JIDs); _ -> [] end, {result, {xmlelement, "registration_watchers", Attrs, SubEls}}; process_get({xmlelement, "acls", Attrs, _SubEls}) -> Str = lists:flatten(io_lib:format("~p.", [ets:tab2list(acl)])), {result, {xmlelement, "acls", Attrs, [{xmlcdata, Str}]}}; process_get({xmlelement, "access", Attrs, _SubEls}) -> Str = lists:flatten( io_lib:format( "~p.", [ets:select(config, [{{config, {access, '$1'}, '$2'}, [], [{{access, '$1', '$2'}}]}]) ])), {result, {xmlelement, "access", Attrs, [{xmlcdata, Str}]}}; process_get({xmlelement, "last", Attrs, _SubEls}) -> case catch mnesia:dirty_select( last_activity, [{{last_activity, '_', '$1', '_'}, [], ['$1']}]) of {'EXIT', _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; Vals -> {MegaSecs, Secs, _MicroSecs} = now(), TimeStamp = MegaSecs * 1000000 + Secs, Str = lists:flatten( lists:append( [[integer_to_list(TimeStamp - V), " "] || V <- Vals])), {result, {xmlelement, "last", Attrs, [{xmlcdata, Str}]}} end; %%process_get({xmlelement, Name, Attrs, SubEls}) -> %% {result, }; process_get(_) -> {error, ?ERR_BAD_REQUEST}. ejabberd-2.1.11/src/ejabberdctl.template0000664000000000000000000002342312240230175015007 0ustar #!/bin/sh # define default configuration POLL=true SMP=auto ERL_MAX_PORTS=32000 ERL_PROCESSES=250000 ERL_MAX_ETS_TABLES=1400 # define default environment variables NODE=ejabberd HOST=localhost ERLANG_NODE=$NODE@$HOST ERL=@erl@ INSTALLUSER=@installuser@ # parse command line parameters ARGS= while [ $# -ne 0 ] ; do PARAM=$1 shift case $PARAM in --) break ;; --node) ERLANG_NODE_ARG=$1; shift ;; --config-dir) ETCDIR=$1 ; shift ;; --config) EJABBERD_CONFIG_PATH=$1 ; shift ;; --ctl-config) EJABBERDCTL_CONFIG_PATH=$1 ; shift ;; --logs) LOGS_DIR=$1 ; shift ;; --spool) SPOOLDIR=$1 ; shift ;; *) ARGS="$ARGS $PARAM" ;; esac done # Define ejabberd variable if they have not been defined from the command line if [ "$ETCDIR" = "" ] ; then ETCDIR=@SYSCONFDIR@/ejabberd fi if [ "$EJABBERD_CONFIG_PATH" = "" ] ; then EJABBERD_CONFIG_PATH=$ETCDIR/ejabberd.cfg fi if [ "$EJABBERDCTL_CONFIG_PATH" = "" ] ; then EJABBERDCTL_CONFIG_PATH=$ETCDIR/ejabberdctl.cfg fi [ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH" if [ "$LOGS_DIR" = "" ] ; then LOGS_DIR=@LOCALSTATEDIR@/log/ejabberd fi if [ "$SPOOLDIR" = "" ] ; then SPOOLDIR=@LOCALSTATEDIR@/lib/ejabberd fi if [ "$EJABBERD_DOC_PATH" = "" ] ; then EJABBERD_DOC_PATH=@DOCDIR@ fi if [ "$ERLANG_NODE_ARG" != "" ] ; then ERLANG_NODE=$ERLANG_NODE_ARG fi # check the proper system user is used ID=`id -g` GIDS=`id -G` EJID=`id -g $INSTALLUSER` EXEC_CMD="false" for GID in $GIDS; do if [ $GID -eq 0 ] ; then EXEC_CMD="su ${INSTALLUSER} -p -c" fi done if [ "$ID" -eq "$EJID" ] ; then EXEC_CMD="sh -c" fi if [ "$EXEC_CMD" = "false" ] ; then echo "This command can only be run by root or the user $INSTALLUSER" >&2 exit 4 fi NAME=-name [ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && NAME=-sname KERNEL_OPTS="" if [ "$FIREWALL_WINDOW" != "" ] ; then KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}" fi if [ "$INET_DIST_INTERFACE" != "" ] ; then KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_use_interface \"${INET_DIST_INTERFACE}\"" fi ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS" # define additional environment variables if [ "$EJABBERDDIR" = "" ]; then EJABBERDDIR=@LIBDIR@/ejabberd fi if [ "$EJABBERD_EBIN_PATH" = "" ]; then EJABBERD_EBIN_PATH=$EJABBERDDIR/ebin fi if [ "$EJABBERD_PRIV_PATH" = "" ]; then EJABBERD_PRIV_PATH=$EJABBERDDIR/priv fi if [ "$EJABBERD_BIN_PATH" = "" ]; then EJABBERD_BIN_PATH=$EJABBERD_PRIV_PATH/bin fi if [ "$EJABBERD_SO_PATH" = "" ]; then EJABBERD_SO_PATH=$EJABBERD_PRIV_PATH/lib fi if [ "$EJABBERD_MSGS_PATH" = "" ]; then EJABBERD_MSGS_PATH=$EJABBERD_PRIV_PATH/msgs fi EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log SASL_LOG_PATH=$LOGS_DIR/erlang.log DATETIME=`date "+%Y%m%d-%H%M%S"` ERL_CRASH_DUMP=$LOGS_DIR/erl_crash_$DATETIME.dump ERL_INETRC=$ETCDIR/inetrc HOME=$SPOOLDIR # create the home dir with the proper user if doesn't exist, because it stores cookie file [ -d $HOME ] || $EXEC_CMD "mkdir -p $HOME" # Change to a directory readable by INSTALLUSER to # prevent "File operation error: eacces." messages cd $HOME # export global variables export EJABBERD_CONFIG_PATH export EJABBERD_MSGS_PATH export EJABBERD_LOG_PATH export EJABBERD_SO_PATH export EJABBERD_BIN_PATH export EJABBERD_DOC_PATH export EJABBERD_PID_PATH export ERL_CRASH_DUMP export ERL_EPMD_ADDRESS export ERL_INETRC export ERL_MAX_PORTS export ERL_MAX_ETS_TABLES export HOME export EXEC_CMD # Compatibility in ZSH #setopt shwordsplit 2>/dev/null # start server start () { $EXEC_CMD "$ERL \ $NAME $ERLANG_NODE \ -noinput -detached \ -pa $EJABBERD_EBIN_PATH \ -mnesia dir \"\\\"$SPOOLDIR\\\"\" \ $KERNEL_OPTS \ -s ejabberd \ -sasl sasl_error_logger \\{file,\\\"$SASL_LOG_PATH\\\"\\} \ $ERLANG_OPTS $ARGS \"$@\"" } # attach to server debug () { echo "--------------------------------------------------------------------" echo "" echo "IMPORTANT: we will attempt to attach an INTERACTIVE shell" echo "to an already running ejabberd node." echo "If an ERROR is printed, it means the connection was not successful." echo "You can interact with the ejabberd node if you know how to use it." echo "Please be extremely cautious with your actions," echo "and exit immediately if you are not completely sure." echo "" echo "To detach this shell from ejabberd, press:" echo " control+c, control+c" echo "" echo "--------------------------------------------------------------------" echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:" echo " EJABBERD_BYPASS_WARNINGS=true" echo "Press any key to continue" if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then read foo fi echo "" TTY=`tty | sed -e 's/.*\///g'` $EXEC_CMD "$ERL \ $NAME debug-${TTY}-${ERLANG_NODE} \ -remsh $ERLANG_NODE \ -hidden \ $KERNEL_OPTS \ $ERLANG_OPTS $ARGS \"$@\"" } # start interactive server live () { echo "--------------------------------------------------------------------" echo "" echo "IMPORTANT: ejabberd is going to start in LIVE (interactive) mode." echo "All log messages will be shown in the command shell." echo "You can interact with the ejabberd node if you know how to use it." echo "Please be extremely cautious with your actions," echo "and exit immediately if you are not completely sure." echo "" echo "To exit this LIVE mode and stop ejabberd, press:" echo " q(). and press the Enter key" echo "" echo "--------------------------------------------------------------------" echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:" echo " EJABBERD_BYPASS_WARNINGS=true" echo "Press any key to continue" if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then read foo fi echo "" $EXEC_CMD "$ERL \ $NAME $ERLANG_NODE \ -pa $EJABBERD_EBIN_PATH \ -mnesia dir \"\\\"$SPOOLDIR\\\"\" \ $KERNEL_OPTS \ -s ejabberd \ $ERLANG_OPTS $ARGS \"$@\"" } help () { echo "" echo "Commands to start an ejabberd node:" echo " start Start an ejabberd node in server mode" echo " debug Attach an interactive Erlang shell to a running ejabberd node" echo " live Start an ejabberd node in live (interactive) mode" echo "" echo "Optional parameters when starting an ejabberd node:" echo " --config-dir dir Config ejabberd: $ETCDIR" echo " --config file Config ejabberd: $EJABBERD_CONFIG_PATH" echo " --ctl-config file Config ejabberdctl: $EJABBERDCTL_CONFIG_PATH" echo " --logs dir Directory for logs: $LOGS_DIR" echo " --spool dir Database spool dir: $SPOOLDIR" echo " --node nodename ejabberd node name: $ERLANG_NODE" echo "" } # common control function ctl () { COMMAND=$@ # Control number of connections identifiers # using flock if available. Expects a linux-style # flock that can lock a file descriptor. MAXCONNID=100 CONNLOCKDIR=@LOCALSTATEDIR@/lock/ejabberdctl FLOCK='/usr/bin/flock' if [ ! -x "$FLOCK" ] || [ ! -d "$CONNLOCKDIR" ] ; then JOT='/usr/bin/jot' if [ ! -x "$JOT" ] ; then # no flock or jot, simply invoke ctlexec() CTL_CONN="ctl-${ERLANG_NODE}" ctlexec $CTL_CONN $COMMAND result=$? else # no flock, but at least there is jot RAND=`jot -r 1 0 $MAXCONNID` CTL_CONN="ctl-${RAND}-${ERLANG_NODE}" ctlexec $CTL_CONN $COMMAND result=$? fi else # we have flock so we get a lock # on one of a limited number of # conn names -- this allows # concurrent invocations using a bound # number of atoms for N in $(seq 1 $MAXCONNID); do CTL_CONN="ejabberdctl-$N" CTL_LOCKFILE="$CONNLOCKDIR/$CTL_CONN" ( exec 8>"$CTL_LOCKFILE" if flock --nb 8; then ctlexec $CTL_CONN $COMMAND ssresult=$? # segregate from possible flock exit(1) ssresult=$(expr $ssresult \* 10) exit $ssresult else exit 1 fi ) result=$? if [ $result -eq 1 ]; then # means we errored out in flock # rather than in the exec - stay in the loop # trying other conn names... badlock=1 else badlock="" break; fi done result=$(expr $result / 10) fi if [ "$badlock" ];then echo "Ran out of connections to try. Your ejabberd processes" >&2 echo "may be stuck or this is a very busy server. For very" >&2 echo "busy servers, consider raising MAXCONNID in ejabberdctl">&2 exit 1; fi case $result in 0) :;; 1) :;; 2) help;; 3) help;; esac return $result } ctlexec () { CONN_NAME=$1; shift COMMAND=$@ $EXEC_CMD "$ERL \ $NAME ${CONN_NAME} \ -noinput \ -hidden \ -pa $EJABBERD_EBIN_PATH \ $KERNEL_OPTS \ -s ejabberd_ctl -extra $ERLANG_NODE $COMMAND" } # display ctl usage usage () { ctl exit } # stop epmd if there is no other running node stop_epmd() { epmd -names | grep -q name || epmd -kill } # allow sync calls wait_for_status() { # args: status try delay # return: 0 OK, 1 KO timeout=$2 status=4 while [ $status -ne $1 ]; do sleep $3 timeout=$(($timeout - 1)) [ $timeout -eq 0 ] && { status=$1 } || { ctl status > /dev/null status=$? } done [ $timeout -eq 0 ] && { status=1 } || { status=0 } return $status } case $ARGS in ' start') start;; ' debug') debug;; ' live') live;; ' started') wait_for_status 0 30 2;; # wait 30x2s before timeout ' stopped') wait_for_status 3 15 2; stop_epmd;; # wait 15x2s before timeout *) ctl $ARGS;; esac ejabberd-2.1.11/src/ejabberd_sup.erl0000664000000000000000000001147612240230175014147 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_sup.erl %%% Author : Alexey Shchepin %%% Purpose : Erlang/OTP supervisor %%% Created : 31 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_sup). -author('alexey@process-one.net'). -behaviour(supervisor). -export([start_link/0, init/1]). start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> Hooks = {ejabberd_hooks, {ejabberd_hooks, start_link, []}, permanent, brutal_kill, worker, [ejabberd_hooks]}, NodeGroups = {ejabberd_node_groups, {ejabberd_node_groups, start_link, []}, permanent, brutal_kill, worker, [ejabberd_node_groups]}, SystemMonitor = {ejabberd_system_monitor, {ejabberd_system_monitor, start_link, []}, permanent, brutal_kill, worker, [ejabberd_system_monitor]}, Router = {ejabberd_router, {ejabberd_router, start_link, []}, permanent, brutal_kill, worker, [ejabberd_router]}, SM = {ejabberd_sm, {ejabberd_sm, start_link, []}, permanent, brutal_kill, worker, [ejabberd_sm]}, S2S = {ejabberd_s2s, {ejabberd_s2s, start_link, []}, permanent, brutal_kill, worker, [ejabberd_s2s]}, Local = {ejabberd_local, {ejabberd_local, start_link, []}, permanent, brutal_kill, worker, [ejabberd_local]}, Captcha = {ejabberd_captcha, {ejabberd_captcha, start_link, []}, permanent, brutal_kill, worker, [ejabberd_captcha]}, Listener = {ejabberd_listener, {ejabberd_listener, start_link, []}, permanent, infinity, supervisor, [ejabberd_listener]}, ReceiverSupervisor = {ejabberd_receiver_sup, {ejabberd_tmp_sup, start_link, [ejabberd_receiver_sup, ejabberd_receiver]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, C2SSupervisor = {ejabberd_c2s_sup, {ejabberd_tmp_sup, start_link, [ejabberd_c2s_sup, ejabberd_c2s]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, S2SInSupervisor = {ejabberd_s2s_in_sup, {ejabberd_tmp_sup, start_link, [ejabberd_s2s_in_sup, ejabberd_s2s_in]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, S2SOutSupervisor = {ejabberd_s2s_out_sup, {ejabberd_tmp_sup, start_link, [ejabberd_s2s_out_sup, ejabberd_s2s_out]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, ServiceSupervisor = {ejabberd_service_sup, {ejabberd_tmp_sup, start_link, [ejabberd_service_sup, ejabberd_service]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, HTTPSupervisor = {ejabberd_http_sup, {ejabberd_tmp_sup, start_link, [ejabberd_http_sup, ejabberd_http]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, HTTPPollSupervisor = {ejabberd_http_poll_sup, {ejabberd_tmp_sup, start_link, [ejabberd_http_poll_sup, ejabberd_http_poll]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, FrontendSocketSupervisor = {ejabberd_frontend_socket_sup, {ejabberd_tmp_sup, start_link, [ejabberd_frontend_socket_sup, ejabberd_frontend_socket]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, IQSupervisor = {ejabberd_iq_sup, {ejabberd_tmp_sup, start_link, [ejabberd_iq_sup, gen_iq_handler]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, STUNSupervisor = {ejabberd_stun_sup, {ejabberd_tmp_sup, start_link, [ejabberd_stun_sup, ejabberd_stun]}, permanent, infinity, supervisor, [ejabberd_tmp_sup]}, CacheTabSupervisor = {cache_tab_sup, {cache_tab_sup, start_link, []}, permanent, infinity, supervisor, [cache_tab_sup]}, {ok, {{one_for_one, 10, 1}, [Hooks, NodeGroups, SystemMonitor, Router, SM, S2S, Local, Captcha, ReceiverSupervisor, C2SSupervisor, S2SInSupervisor, S2SOutSupervisor, ServiceSupervisor, HTTPSupervisor, HTTPPollSupervisor, IQSupervisor, STUNSupervisor, FrontendSocketSupervisor, CacheTabSupervisor, Listener]}}. ejabberd-2.1.11/src/p1_prof.erl0000664000000000000000000002222012240230175013055 0ustar %%%------------------------------------------------------------------- %%% File : p1_prof.erl %%% Author : Evgeniy Khramtsov %%% Description : Handy wrapper around eprof and fprof %%% %%% Created : 23 Jan 2010 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(p1_prof). %% API -export([eprof_start/0, eprof_stop/0, fprof_start/0, fprof_start/1, fprof_stop/0, fprof_analyze/0, queue/0, queue/1, memory/0, memory/1, reds/0, reds/1, trace/1, help/0, q/0, m/0, r/0, q/1, m/1, r/1]). -define(APPS, [ejabberd, mnesia]). %%==================================================================== %% API %%==================================================================== eprof_start() -> eprof:start(), case lists:keyfind(running, 1, application:info()) of {_, Apps} -> case get_procs(?APPS, Apps) of [] -> {error, no_procs_found}; Procs -> eprof:start_profiling(Procs) end; _ -> {error, no_app_info} end. fprof_start() -> fprof_start(0). fprof_start(Duration) -> case lists:keyfind(running, 1, application:info()) of {_, Apps} -> case get_procs(?APPS, Apps) of [] -> {error, no_procs_found}; Procs -> fprof:trace([start, {procs, Procs}]), io:format("Profiling started~n"), if Duration > 0 -> timer:sleep(Duration*1000), fprof:trace([stop]), fprof:stop(); true-> ok end end; _ -> {error, no_app_info} end. fprof_stop() -> fprof:trace([stop]), fprof:profile(), fprof:analyse([totals, no_details, {sort, own}, no_callers, {dest, "fprof.analysis"}]), fprof:stop(), format_fprof_analyze(). fprof_analyze() -> fprof_stop(). eprof_stop() -> eprof:stop_profiling(), case erlang:function_exported(eprof, analyse, 0) of true -> eprof:analyse(); false -> eprof:analyze() end. help() -> M = ?MODULE, io:format("Brief help:~n" "~p:queue(N) - show top N pids sorted by queue length~n" "~p:queue() - shorthand for ~p:queue(10)~n" "~p:memory(N) - show top N pids sorted by memory usage~n" "~p:memory() - shorthand for ~p:memory(10)~n" "~p:reds(N) - show top N pids sorted by reductions~n" "~p:reds() - shorthand for ~p:reds(10)~n" "~p:q(N)|~p:q() - same as ~p:queue(N)|~p:queue()~n" "~p:m(N)|~p:m() - same as ~p:memory(N)|~p:memory()~n" "~p:r(N)|~p:r() - same as ~p:reds(N)|~p:reds()~n" "~p:trace(Pid) - trace Pid; to stop tracing close " "Erlang shell with Ctrl+C~n" "~p:eprof_start() - start eprof on all available pids; " "DO NOT use on production system!~n" "~p:eprof_stop() - stop eprof and print result~n" "~p:fprof_start() - start fprof on all available pids; " "DO NOT use on production system!~n" "~p:fprof_stop() - stop eprof and print formatted result~n" "~p:fprof_start(N) - start and run fprof for N seconds; " "use ~p:fprof_analyze() to analyze collected statistics and " "print formatted result; use on production system with CARE~n" "~p:fprof_analyze() - analyze previously collected statistics " "using ~p:fprof_start(N) and print formatted result~n" "~p:help() - print this help~n", lists:duplicate(31, M)). q() -> queue(). q(N) -> queue(N). m() -> memory(). m(N) -> memory(N). r() -> reds(). r(N) -> reds(N). queue() -> queue(10). memory() -> memory(10). reds() -> reds(10). queue(N) -> dump(N, lists:reverse(lists:ukeysort(1, all_pids(queue)))). memory(N) -> dump(N, lists:reverse(lists:ukeysort(3, all_pids(memory)))). reds(N) -> dump(N, lists:reverse(lists:ukeysort(4, all_pids(reductions)))). trace(Pid) -> erlang:trace(Pid, true, [send, 'receive']), trace_loop(). trace_loop() -> receive M -> io:format("~p~n", [M]), trace_loop() end. %%==================================================================== %% Internal functions %%==================================================================== get_procs(Apps, AppList) -> io:format("Searching for processes to profile...~n", []), Procs = lists:flatmap( fun({App, Leader}) when is_pid(Leader) -> case lists:member(App, Apps) of true -> get_procs(Leader); false -> [] end; (_) -> [] end, AppList), io:format("Found ~p processes~n", [length(Procs)]), Procs. get_procs(Leader) -> lists:filter( fun(Pid) -> case process_info(Pid, group_leader) of {_, Leader} -> true; _ -> false end end, processes()). format_fprof_analyze() -> case file:consult("fprof.analysis") of {ok, [_, [{totals, _, _, TotalOWN}] | Rest]} -> OWNs = lists:flatmap( fun({MFA, _, _, OWN}) -> Percent = OWN*100/TotalOWN, case round(Percent) of 0 -> []; _ -> [{mfa_to_list(MFA), Percent}] end end, Rest), ACCs = collect_accs(Rest), MaxACC = find_max(ACCs), MaxOWN = find_max(OWNs), io:format("=== Sorted by OWN:~n"), lists:foreach( fun({MFA, Per}) -> L = length(MFA), S = lists:duplicate(MaxOWN - L + 2, $ ), io:format("~s~s~.2f%~n", [MFA, S, Per]) end, lists:reverse(lists:keysort(2, OWNs))), io:format("~n=== Sorted by ACC:~n"), lists:foreach( fun({MFA, Per}) -> L = length(MFA), S = lists:duplicate(MaxACC - L + 2, $ ), io:format("~s~s~.2f%~n", [MFA, S, Per]) end, lists:reverse(lists:keysort(2, ACCs))); Err -> Err end. mfa_to_list({M, F, A}) -> atom_to_list(M) ++ ":" ++ atom_to_list(F) ++ "/" ++ integer_to_list(A); mfa_to_list(F) when is_atom(F) -> atom_to_list(F). find_max(List) -> find_max(List, 0). find_max([{V, _}|Tail], Acc) -> find_max(Tail, lists:max([length(V), Acc])); find_max([], Acc) -> Acc. collect_accs(List) -> List1 = lists:filter( fun({MFA, _, _, _}) -> case MFA of {sys, _, _} -> false; suspend -> false; {gen_fsm, _, _} -> false; {p1_fsm, _, _} -> false; {gen, _, _} -> false; {gen_server, _, _} -> false; {proc_lib, _, _} -> false; _ -> true end end, List), TotalACC = lists:sum([A || {_, _, A, _} <- List1]), lists:flatmap( fun({MFA, _, ACC, _}) -> Percent = ACC*100/TotalACC, case round(Percent) of 0 -> []; _ -> [{mfa_to_list(MFA), Percent}] end end, List1). all_pids(Type) -> lists:foldl( fun(P, Acc) when P == self() -> %% exclude ourself from statistics Acc; (P, Acc) -> case catch process_info( P, [message_queue_len, memory, reductions, dictionary, current_function, registered_name]) of [{_, Len}, {_, Memory}, {_, Reds}, {_, Dict}, {_, CurFun}, {_, RegName}] -> IntQLen = case lists:keysearch('$internal_queue_len', 1, Dict) of {value, {_, N}} -> N; _ -> 0 end, if Type == queue andalso Len == 0 andalso IntQLen == 0 -> Acc; true -> MaxLen = lists:max([Len, IntQLen]), [{MaxLen, Len, Memory, Reds, Dict, CurFun, P, RegName}|Acc] end; _ -> Acc end end, [], processes()). dump(N, Rs) -> lists:foreach( fun({_, MsgQLen, Memory, Reds, Dict, CurFun, Pid, RegName}) -> PidStr = pid_to_list(Pid), [_, Maj, Min] = string:tokens( string:substr( PidStr, 2, length(PidStr) - 2), "."), io:format("** pid(0,~s,~s)~n" "** registered name: ~p~n" "** memory: ~p~n" "** reductions: ~p~n" "** message queue len: ~p~n" "** current_function: ~p~n" "** dictionary: ~p~n~n", [Maj, Min, RegName, Memory, Reds, MsgQLen, CurFun, Dict]) end, nthhead(N, Rs)). nthhead(N, L) -> lists:reverse(nthhead(N, L, [])). nthhead(0, _L, Acc) -> Acc; nthhead(N, [H|T], Acc) -> nthhead(N-1, T, [H|Acc]); nthhead(_N, [], Acc) -> Acc. ejabberd-2.1.11/src/translate.erl0000664000000000000000000001026512240230175013512 0ustar %%%---------------------------------------------------------------------- %%% File : translate.erl %%% Author : Alexey Shchepin %%% Purpose : Localization helper %%% Created : 6 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(translate). -author('alexey@process-one.net'). -export([start/0, load_dir/1, load_file/2, translate/2]). -include("ejabberd.hrl"). start() -> ets:new(translations, [named_table, public]), Dir = case os:getenv("EJABBERD_MSGS_PATH") of false -> case code:priv_dir(ejabberd) of {error, _} -> ?MSGS_DIR; Path -> filename:join([Path, "msgs"]) end; Path -> Path end, load_dir(Dir), ok. load_dir(Dir) -> case file:list_dir(Dir) of {ok, Files} -> MsgFiles = lists:filter( fun(FN) -> case string:len(FN) > 4 of true -> string:substr( FN, string:len(FN) - 3) == ".msg"; _ -> false end end, Files), lists:foreach( fun(FN) -> LP = ascii_tolower( string:substr(FN, 1, string:len(FN) - 4)), L = case string:tokens(LP, ".") of [Language] -> Language; [Language, _Project] -> Language end, load_file(L, Dir ++ "/" ++ FN) end, MsgFiles), ok; {error, Reason} -> ?ERROR_MSG("~p", [Reason]) end. load_file(Lang, File) -> case file:consult(File) of {ok, Terms} -> lists:foreach(fun({Orig, Trans}) -> Trans1 = case Trans of "" -> Orig; _ -> Trans end, ets:insert(translations, {{Lang, Orig}, Trans1}) end, Terms); %% Code copied from ejabberd_config.erl {error, {_LineNumber, erl_parse, _ParseMessage} = Reason} -> ExitText = lists:flatten(File ++ " approximately in the line " ++ file:format_error(Reason)), ?ERROR_MSG("Problem loading translation file ~n~s", [ExitText]), exit(ExitText); {error, Reason} -> ExitText = lists:flatten(File ++ ": " ++ file:format_error(Reason)), ?ERROR_MSG("Problem loading translation file ~n~s", [ExitText]), exit(ExitText) end. translate(Lang, Msg) -> LLang = ascii_tolower(Lang), case ets:lookup(translations, {LLang, Msg}) of [{_, Trans}] -> Trans; _ -> ShortLang = case string:tokens(LLang, "-") of [] -> LLang; [SL | _] -> SL end, case ShortLang of "en" -> Msg; LLang -> translate(Msg); _ -> case ets:lookup(translations, {ShortLang, Msg}) of [{_, Trans}] -> Trans; _ -> translate(Msg) end end end. translate(Msg) -> case ?MYLANG of undefined -> Msg; "en" -> Msg; Lang -> LLang = ascii_tolower(Lang), case ets:lookup(translations, {LLang, Msg}) of [{_, Trans}] -> Trans; _ -> ShortLang = case string:tokens(LLang, "-") of [] -> LLang; [SL | _] -> SL end, case ShortLang of "en" -> Msg; Lang -> Msg; _ -> case ets:lookup(translations, {ShortLang, Msg}) of [{_, Trans}] -> Trans; _ -> Msg end end end end. ascii_tolower([C | Cs]) when C >= $A, C =< $Z -> [C + ($a - $A) | ascii_tolower(Cs)]; ascii_tolower([C | Cs]) -> [C | ascii_tolower(Cs)]; ascii_tolower([]) -> []. ejabberd-2.1.11/src/expat_erl.c0000664000000000000000000001730312240230175013140 0ustar /* * ejabberd, Copyright (C) 2002-2012 ProcessOne * * 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., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * */ #include #include #include #include #include #define XML_START 0 #define XML_END 1 #define XML_CDATA 2 #define XML_ERROR 3 #define PARSE_COMMAND 0 #define PARSE_FINAL_COMMAND 1 /* * R15B changed several driver callbacks to use ErlDrvSizeT and * ErlDrvSSizeT typedefs instead of int. * This provides missing typedefs on older OTP versions. */ #if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 typedef int ErlDrvSizeT; typedef int ErlDrvSSizeT; #endif ei_x_buff event_buf; ei_x_buff xmlns_buf; typedef struct { ErlDrvPort port; XML_Parser parser; } expat_data; static XML_Memory_Handling_Suite ms; void encode_name(const XML_Char *name) { char *name_start; char *prefix_start; char *buf; int name_len, prefix_len, buf_len; if ((name_start = strchr(name, '\n'))) { if ((prefix_start = strchr(name_start+1, '\n'))) { name_len = prefix_start - name_start; prefix_len = strlen(prefix_start+1); buf_len = prefix_len + name_len; buf = driver_alloc(buf_len); memcpy(buf, prefix_start+1, prefix_len); memcpy(buf+prefix_len, name_start, name_len); buf[prefix_len] = ':'; ei_x_encode_string_len(&event_buf, buf, buf_len); driver_free(buf); } else { ei_x_encode_string(&event_buf, name_start+1); }; } else { ei_x_encode_string(&event_buf, name); } } void *erlXML_StartElementHandler(expat_data *d, const XML_Char *name, const XML_Char **atts) { int i; ei_x_encode_list_header(&event_buf, 1); ei_x_encode_tuple_header(&event_buf, 2); ei_x_encode_long(&event_buf, XML_START); ei_x_encode_tuple_header(&event_buf, 2); encode_name(name); ei_x_append(&event_buf, &xmlns_buf); ei_x_free(&xmlns_buf); ei_x_new(&xmlns_buf); for (i = 0; atts[i]; i += 2) {} if (i > 0) { ei_x_encode_list_header(&event_buf, i/2); for (i = 0; atts[i]; i += 2) { ei_x_encode_tuple_header(&event_buf, 2); encode_name(atts[i]); ei_x_encode_string(&event_buf, atts[i+1]); } } ei_x_encode_empty_list(&event_buf); return NULL; } void *erlXML_EndElementHandler(expat_data *d, const XML_Char *name) { ei_x_encode_list_header(&event_buf, 1); ei_x_encode_tuple_header(&event_buf, 2); ei_x_encode_long(&event_buf, XML_END); encode_name(name); return NULL; } void *erlXML_CharacterDataHandler(expat_data *d, const XML_Char *s, int len) { ei_x_encode_list_header(&event_buf, 1); ei_x_encode_tuple_header(&event_buf, 2); ei_x_encode_long(&event_buf, XML_CDATA); ei_x_encode_binary(&event_buf, s, len); return NULL; } void *erlXML_StartNamespaceDeclHandler(expat_data *d, const XML_Char *prefix, const XML_Char *uri) { int prefix_len; char *buf; /* From the expat documentation: "For a default namespace declaration (xmlns='...'), the prefix will be null ... ... The URI will be null for the case where the default namespace is being unset." FIXME: I'm not quite sure what all that means */ if (uri == NULL) return NULL; ei_x_encode_list_header(&xmlns_buf, 1); ei_x_encode_tuple_header(&xmlns_buf, 2); if (prefix) { prefix_len = strlen(prefix); buf = driver_alloc(7 + prefix_len); strcpy(buf, "xmlns:"); strcpy(buf+6, prefix); ei_x_encode_string(&xmlns_buf, buf); driver_free(buf); } else { ei_x_encode_string(&xmlns_buf, "xmlns"); }; ei_x_encode_string(&xmlns_buf, uri); return NULL; } static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff) { expat_data* d = (expat_data*)driver_alloc(sizeof(expat_data)); d->port = port; d->parser = XML_ParserCreate_MM("UTF-8", &ms, "\n"); XML_SetUserData(d->parser, d); set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); XML_SetStartElementHandler( d->parser, (XML_StartElementHandler)erlXML_StartElementHandler); XML_SetEndElementHandler( d->parser, (XML_EndElementHandler)erlXML_EndElementHandler); XML_SetCharacterDataHandler( d->parser, (XML_CharacterDataHandler)erlXML_CharacterDataHandler); XML_SetStartNamespaceDeclHandler( d->parser, (XML_StartNamespaceDeclHandler) erlXML_StartNamespaceDeclHandler); XML_SetReturnNSTriplet(d->parser, 1); XML_SetDefaultHandler(d->parser, NULL); return (ErlDrvData)d; } static void expat_erl_stop(ErlDrvData handle) { XML_ParserFree(((expat_data *)handle)->parser); driver_free((char*)handle); } static ErlDrvSSizeT expat_erl_control(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { expat_data* d = (expat_data*)drv_data; int res, errcode; char *errstring; ErlDrvBinary *b; size_t size; switch (command) { case PARSE_COMMAND: case PARSE_FINAL_COMMAND: ei_x_new_with_version(&event_buf); ei_x_new(&xmlns_buf); res = XML_Parse(d->parser, buf, len, command == PARSE_FINAL_COMMAND); if(!res) { errcode = XML_GetErrorCode(d->parser); errstring = (char *)XML_ErrorString(errcode); ei_x_encode_list_header(&event_buf, 1); ei_x_encode_tuple_header(&event_buf, 2); ei_x_encode_long(&event_buf, XML_ERROR); ei_x_encode_tuple_header(&event_buf, 2); ei_x_encode_long(&event_buf, errcode); ei_x_encode_string(&event_buf, errstring); } ei_x_encode_empty_list(&event_buf); size = event_buf.index; b = driver_alloc_binary(size); memcpy(b->orig_bytes, event_buf.buff, size); ei_x_free(&event_buf); ei_x_free(&xmlns_buf); *rbuf = (char *)b; return size; default: return 0; } } ErlDrvEntry expat_driver_entry = { NULL, /* F_PTR init, N/A */ expat_erl_start, /* L_PTR start, called when port is opened */ expat_erl_stop, /* F_PTR stop, called when port is closed */ NULL, /* F_PTR output, called when erlang has sent */ NULL, /* F_PTR ready_input, called when input descriptor ready */ NULL, /* F_PTR ready_output, called when output descriptor ready */ "expat_erl", /* char *driver_name, the argument to open_port */ NULL, /* F_PTR finish, called when unloaded */ NULL, /* handle */ expat_erl_control, /* F_PTR control, port_command callback */ NULL, /* F_PTR timeout, reserved */ NULL, /* F_PTR outputv, reserved */ /* Added in Erlang/OTP R15B: */ NULL, /* ready_async */ NULL, /* flush */ NULL, /* call */ NULL, /* event */ ERL_DRV_EXTENDED_MARKER, /* extended_marker */ ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ 0, /* driver_flags */ NULL, /* handle2 */ NULL, /* process_exit */ NULL /* stop_select */ }; DRIVER_INIT(expat_erl) /* must match name in driver_entry */ { ms.malloc_fcn = driver_alloc; ms.realloc_fcn = driver_realloc; ms.free_fcn = driver_free; return &expat_driver_entry; } ejabberd-2.1.11/src/ejabberd.hrl0000664000000000000000000000442212240230175013254 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %% This macro returns a string of the ejabberd version running, e.g. "2.3.4" %% If the ejabberd application description isn't loaded, returns atom: undefined -define(VERSION, element(2, application:get_key(ejabberd,vsn))). -define(MYHOSTS, ejabberd_config:get_global_option(hosts)). -define(MYNAME, hd(ejabberd_config:get_global_option(hosts))). -define(MYLANG, ejabberd_config:get_global_option(language)). -define(MSGS_DIR, "msgs"). -define(CONFIG_PATH, "ejabberd.cfg"). -define(LOG_PATH, "ejabberd.log"). -define(EJABBERD_URI, "http://www.process-one.net/en/ejabberd/"). -define(S2STIMEOUT, 600000). %%-define(DBGFSM, true). -record(scram, {storedkey, serverkey, salt, iterationcount}). -define(SCRAM_DEFAULT_ITERATION_COUNT, 4096). %% --------------------------------- %% Logging mechanism %% Print in standard output -define(PRINT(Format, Args), io:format(Format, Args)). -define(DEBUG(Format, Args), ejabberd_logger:debug_msg(?MODULE,?LINE,Format, Args)). -define(INFO_MSG(Format, Args), ejabberd_logger:info_msg(?MODULE,?LINE,Format, Args)). -define(WARNING_MSG(Format, Args), ejabberd_logger:warning_msg(?MODULE,?LINE,Format, Args)). -define(ERROR_MSG(Format, Args), ejabberd_logger:error_msg(?MODULE,?LINE,Format, Args)). -define(CRITICAL_MSG(Format, Args), ejabberd_logger:critical_msg(?MODULE,?LINE,Format, Args)). ejabberd-2.1.11/src/ejabberd_logger_h.erl0000664000000000000000000002011712240230175015116 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_logger_h.erl %%% Author : Alexey Shchepin %%% Purpose : Manage Erlang logging. %%% Created : 23 Oct 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_logger_h). -author('alexey@process-one.net'). -behaviour(gen_event). %% gen_event callbacks -export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, code_change/3, reopen_log/0, rotate_log/1]). -record(state, {fd, file}). %%%---------------------------------------------------------------------- %%% Callback functions from gen_event %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, State} | %% Other %%---------------------------------------------------------------------- init(File) -> case file:open(File, [append, raw]) of {ok, Fd} -> {ok, #state{fd = Fd, file = File}}; Error -> Error end. %%---------------------------------------------------------------------- %% Func: handle_event/2 %% Returns: {ok, State} | %% {swap_handler, Args1, State1, Mod2, Args2} | %% remove_handler %%---------------------------------------------------------------------- handle_event(Event, State) -> write_event(State#state.fd, {erlang:localtime(), Event}), {ok, State}. %%---------------------------------------------------------------------- %% Func: handle_call/2 %% Returns: {ok, Reply, State} | %% {swap_handler, Reply, Args1, State1, Mod2, Args2} | %% {remove_handler, Reply} %%---------------------------------------------------------------------- handle_call(_Request, State) -> Reply = ok, {ok, Reply, State}. %%---------------------------------------------------------------------- %% Func: handle_info/2 %% Returns: {ok, State} | %% {swap_handler, Args1, State1, Mod2, Args2} | %% remove_handler %%---------------------------------------------------------------------- handle_info({'EXIT', _Fd, _Reason}, _State) -> remove_handler; handle_info({emulator, _GL, reopen}, State) -> file:close(State#state.fd), rotate_log(State#state.file), case file:open(State#state.file, [append, raw]) of {ok, Fd} -> {ok, State#state{fd = Fd}}; Error -> Error end; handle_info({emulator, GL, Chars}, State) -> write_event(State#state.fd, {erlang:localtime(), {emulator, GL, Chars}}), {ok, State}; handle_info(_Info, State) -> {ok, State}. %%---------------------------------------------------------------------- %% Func: terminate/2 %% Purpose: Shutdown the server %% Returns: any %%---------------------------------------------------------------------- terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. reopen_log() -> error_logger ! {emulator, noproc, reopen}. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- % Copied from erlang_logger_file_h.erl write_event(Fd, {Time, {error, _GL, {Pid, Format, Args}}}) -> T = write_time(Time), case catch io_lib:format(add_node(Format,Pid), Args) of S when is_list(S) -> file:write(Fd, io_lib:format(T ++ S, [])); _ -> F = add_node("ERROR: ~p - ~p~n", Pid), file:write(Fd, io_lib:format(T ++ F, [Format,Args])) end; write_event(Fd, {Time, {emulator, _GL, Chars}}) -> T = write_time(Time), case catch io_lib:format(Chars, []) of S when is_list(S) -> file:write(Fd, io_lib:format(T ++ S, [])); _ -> file:write(Fd, io_lib:format(T ++ "ERROR: ~p ~n", [Chars])) end; write_event(Fd, {Time, {info, _GL, {Pid, Info, _}}}) -> T = write_time(Time), file:write(Fd, io_lib:format(T ++ add_node("~p~n",Pid), [Info])); write_event(Fd, {Time, {error_report, _GL, {Pid, std_error, Rep}}}) -> T = write_time(Time), S = format_report(Rep), file:write(Fd, io_lib:format(T ++ S ++ add_node("", Pid), [])); write_event(Fd, {Time, {info_report, _GL, {Pid, std_info, Rep}}}) -> T = write_time(Time, "INFO REPORT"), S = format_report(Rep), file:write(Fd, io_lib:format(T ++ S ++ add_node("", Pid), [])); write_event(Fd, {Time, {info_msg, _GL, {Pid, Format, Args}}}) -> T = write_time(Time, "INFO REPORT"), case catch io_lib:format(add_node(Format,Pid), Args) of S when is_list(S) -> file:write(Fd, io_lib:format(T ++ S, [])); _ -> F = add_node("ERROR: ~p - ~p~n", Pid), file:write(Fd, io_lib:format(T ++ F, [Format,Args])) end; write_event(Fd, {Time, {warning_report, _GL, {Pid, std_warning, Rep}}}) -> T = write_time(Time, "WARNING REPORT"), S = format_report(Rep), file:write(Fd, io_lib:format(T ++ S ++ add_node("", Pid), [])); write_event(Fd, {Time, {warning_msg, _GL, {Pid, Format, Args}}}) -> T = write_time(Time, "WARNING REPORT"), case catch io_lib:format(add_node(Format,Pid), Args) of S when is_list(S) -> file:write(Fd, io_lib:format(T ++ S, [])); _ -> F = add_node("ERROR: ~p - ~p~n", Pid), file:write(Fd, io_lib:format(T ++ F, [Format,Args])) end; write_event(_, _) -> ok. format_report(Rep) when is_list(Rep) -> case string_p(Rep) of true -> io_lib:format("~s~n",[Rep]); _ -> format_rep(Rep) end; format_report(Rep) -> io_lib:format("~p~n",[Rep]). format_rep([{Tag,Data}|Rep]) -> io_lib:format(" ~p: ~p~n",[Tag,Data]) ++ format_rep(Rep); format_rep([Other|Rep]) -> io_lib:format(" ~p~n",[Other]) ++ format_rep(Rep); format_rep(_) -> []. add_node(X, Pid) when is_atom(X) -> add_node(atom_to_list(X), Pid); add_node(X, Pid) when node(Pid) /= node() -> lists:concat([X,"** at node ",node(Pid)," **~n"]); add_node(X, _) -> X. string_p([]) -> false; string_p(Term) -> string_p1(Term). string_p1([H|T]) when is_integer(H), H >= $\s, H < 255 -> string_p1(T); string_p1([$\n|T]) -> string_p1(T); string_p1([$\r|T]) -> string_p1(T); string_p1([$\t|T]) -> string_p1(T); string_p1([$\v|T]) -> string_p1(T); string_p1([$\b|T]) -> string_p1(T); string_p1([$\f|T]) -> string_p1(T); string_p1([$\e|T]) -> string_p1(T); string_p1([H|T]) when is_list(H) -> case string_p1(H) of true -> string_p1(T); _ -> false end; string_p1([]) -> true; string_p1(_) -> false. write_time(Time) -> write_time(Time, "ERROR REPORT"). write_time({{Y,Mo,D},{H,Mi,S}}, Type) -> io_lib:format("~n=~s==== ~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w ===~n", [Type, Y, Mo, D, H, Mi, S]). %% @doc Rename the log file if exists, to "*-old.log". %% This is needed in systems when the file must be closed before rotation (Windows). %% On most Unix-like system, the file can be renamed from the command line and %% the log can directly be reopened. %% @spec (Filename::string()) -> ok rotate_log(Filename) -> case file:read_file_info(Filename) of {ok, _FileInfo} -> RotationName = filename:rootname(Filename), file:rename(Filename, [RotationName, "-old.log"]), ok; {error, _Reason} -> ok end. ejabberd-2.1.11/src/acinclude.m40000664000000000000000000002436712240230175013212 0ustar AC_DEFUN([AM_WITH_EXPAT], [ AC_ARG_WITH(expat, [AC_HELP_STRING([--with-expat=PREFIX], [prefix where EXPAT is installed])]) EXPAT_CFLAGS= EXPAT_LIBS= if test x"$with_expat" != x; then EXPAT_CFLAGS="-I$with_expat/include" EXPAT_LIBS="-L$with_expat/lib" fi AC_CHECK_LIB(expat, XML_ParserCreate, [ EXPAT_LIBS="$EXPAT_LIBS -lexpat" expat_found=yes ], [ expat_found=no ], "$EXPAT_LIBS") if test $expat_found = no; then AC_MSG_ERROR([Could not find development files of Expat library]) fi expat_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $EXPAT_CFLAGS" expat_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $EXPAT_CFLAGS" AC_CHECK_HEADERS(expat.h, , expat_found=no) if test $expat_found = no; then AC_MSG_ERROR([Could not find expat.h]) fi CFLAGS="$expat_save_CFLAGS" CPPFLAGS="$expat_save_CPPFLAGS" AC_SUBST(EXPAT_CFLAGS) AC_SUBST(EXPAT_LIBS) ]) AC_DEFUN([AM_WITH_ZLIB], [ AC_ARG_WITH(zlib, [AC_HELP_STRING([--with-zlib=PREFIX], [prefix where zlib is installed])]) if test x"$ejabberd_zlib" != x; then ZLIB_CFLAGS= ZLIB_LIBS= if test x"$with_zlib" != x; then ZLIB_CFLAGS="-I$with_zlib/include" ZLIB_LIBS="-L$with_zlib/lib" fi AC_CHECK_LIB(z, gzgets, [ ZLIB_LIBS="$ZLIB_LIBS -lz" zlib_found=yes ], [ zlib_found=no ], "$ZLIB_LIBS") if test $zlib_found = no; then AC_MSG_ERROR([Could not find development files of zlib library. Install them or disable `ejabberd_zlib' with: --disable-ejabberd_zlib]) fi zlib_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $ZLIB_CFLAGS" zlib_save_CPPFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" AC_CHECK_HEADERS(zlib.h, , zlib_found=no) if test $zlib_found = no; then AC_MSG_ERROR([Could not find zlib.h. Install it or disable `ejabberd_zlib' with: --disable-ejabberd_zlib]) fi CFLAGS="$zlib_save_CFLAGS" CPPFLAGS="$zlib_save_CPPFLAGS" AC_SUBST(ZLIB_CFLAGS) AC_SUBST(ZLIB_LIBS) fi ]) AC_DEFUN([AM_WITH_PAM], [ AC_ARG_WITH(pam, [AC_HELP_STRING([--with-pam=PREFIX], [prefix where PAM is installed])]) if test x"$pam" != x; then PAM_CFLAGS= PAM_LIBS= if test x"$with_pam" != x; then PAM_CFLAGS="-I$with_pam/include" PAM_LIBS="-L$with_pam/lib" fi AC_CHECK_LIB(pam, pam_start, [ PAM_LIBS="$PAM_LIBS -lpam" pam_found=yes ], [ pam_found=no ], "$PAM_LIBS") if test $pam_found = no; then AC_MSG_ERROR([Could not find development files of PAM library. Install them or disable `pam' with: --disable-pam]) fi pam_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PAM_CFLAGS" pam_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $PAM_CFLAGS" AC_CHECK_HEADERS(security/pam_appl.h, , pam_found=no) if test $pam_found = no; then AC_MSG_ERROR([Could not find security/pam_appl.h. Install it or disable `pam' with: --disable-pam]) fi CFLAGS="$pam_save_CFLAGS" CPPFLAGS="$pam_save_CPPFLAGS" AC_SUBST(PAM_CFLAGS) AC_SUBST(PAM_LIBS) fi ]) AC_DEFUN([AM_WITH_ERLANG], [ AC_ARG_WITH(erlang, [AC_HELP_STRING([--with-erlang=PREFIX], [path to erlc and erl])]) AC_PATH_TOOL(ERLC, erlc, , $with_erlang:$with_erlang/bin:$PATH) AC_PATH_TOOL(ERL, erl, , $with_erlang:$with_erlang/bin:$PATH) if test "z$ERLC" = "z" || test "z$ERL" = "z"; then AC_MSG_ERROR([erlang not found]) fi cat >>conftest.erl <<_EOF -module(conftest). -author('alexey@sevcom.net'). -export([[start/0]]). start() -> EIDirS = code:lib_dir("erl_interface") ++ "\n", EILibS = libpath("erl_interface") ++ "\n", RootDirS = code:root_dir() ++ "\n", file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ ssldef() ++ RootDirS)), halt(). ssldef() -> OTP = (catch erlang:system_info(otp_release)), if OTP >= "R14" -> "-DSSL40\n"; OTP >= "R12" -> "-DSSL39\n"; true -> "\n" end. %% return physical architecture based on OS/Processor archname() -> ArchStr = erlang:system_info(system_architecture), case os:type() of {win32, _} -> "windows"; {unix,UnixName} -> Specs = string:tokens(ArchStr,"-"), Cpu = case lists:nth(2,Specs) of "pc" -> "x86"; _ -> hd(Specs) end, atom_to_list(UnixName) ++ "-" ++ Cpu; _ -> "generic" end. %% Return arch-based library path or a default value if this directory %% does not exist libpath(App) -> PrivDir = code:priv_dir(App), ArchDir = archname(), LibArchDir = filename:join([[PrivDir,"lib",ArchDir]]), case file:list_dir(LibArchDir) of %% Arch lib dir exists: We use it {ok, _List} -> LibArchDir; %% Arch lib dir does not exist: Return the default value %% ({error, enoent}): _Error -> code:lib_dir("erl_interface") ++ "/lib" end. _EOF if ! $ERLC conftest.erl; then AC_MSG_ERROR([could not compile sample program]) fi if ! $ERL -s conftest -noshell; then AC_MSG_ERROR([could not run sample program]) fi if ! test -f conftest.out; then AC_MSG_ERROR([erlang program was not properly executed, (conftest.out was not produced)]) fi # First line ERLANG_EI_DIR=`cat conftest.out | head -n 1` # Second line ERLANG_EI_LIB=`cat conftest.out | head -n 2 | tail -n 1` # Third line ERLANG_SSLVER=`cat conftest.out | head -n 3 | tail -n 1` # End line ERLANG_DIR=`cat conftest.out | tail -n 1` ERLANG_CFLAGS="-I$ERLANG_EI_DIR/include -I$ERLANG_DIR/usr/include" ERLANG_LIBS="-L$ERLANG_EI_LIB -lerl_interface -lei" AC_SUBST(ERLANG_CFLAGS) AC_SUBST(ERLANG_LIBS) AC_SUBST(ERLANG_SSLVER) AC_SUBST(ERLC) AC_SUBST(ERL) ]) AC_DEFUN([AC_MOD_ENABLE], [ $1= make_$1= AC_MSG_CHECKING([whether build $1]) AC_ARG_ENABLE($1, [AC_HELP_STRING([--enable-$1], [enable $1 (default: $2)])], [mr_enable_$1="$enableval"], [mr_enable_$1=$2]) if test "$mr_enable_$1" = "yes"; then $1=$1 make_$1=$1/Makefile fi AC_MSG_RESULT($mr_enable_$1) AC_SUBST($1) AC_SUBST(make_$1) ]) dnl From Bruno Haible. AC_DEFUN([AM_ICONV], [ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and dnl those with the standalone portable GNU libiconv installed). AC_ARG_WITH([libiconv-prefix], [AC_HELP_STRING([--with-libiconv-prefix=PREFIX], [prefix where libiconv is installed])], [ for dir in `echo "$withval" | tr : ' '`; do if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi if test -d $dir/include; then CFLAGS="$CFLAGS -I$dir/include"; fi if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi done ]) AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_func_iconv=yes) if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS -liconv" AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_lib_iconv=yes am_cv_func_iconv=yes) LIBS="$am_save_LIBS" fi dnl trying /usr/local if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" am_save_CFLAGS="$CFLAGS" am_save_LDFLAGS="$LDFLAGS" LIBS="$LIBS -liconv" LDFLAGS="$LDFLAGS -L/usr/local/lib" CFLAGS="$CFLAGS -I/usr/local/include" AC_TRY_LINK([#include #include ], [iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd);], am_cv_lib_iconv=yes am_cv_func_iconv=yes CPPFLAGS="$CPPFLAGS -I/usr/local/include", LDFLAGS="$am_save_LDFLAGS" CFLAGS="$am_save_CFLAGS") LIBS="$am_save_LIBS" fi ]) if test "$am_cv_func_iconv" = yes; then AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) AC_MSG_CHECKING([for iconv declaration]) AC_CACHE_VAL(am_cv_proto_iconv, [ AC_TRY_COMPILE([ #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif ], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` AC_MSG_RESULT([$]{ac_t:- }[$]am_cv_proto_iconv) AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, [Define as const if the declaration of iconv() needs const.]) fi LIBICONV= if test "$am_cv_lib_iconv" = yes; then LIBICONV="-liconv" fi AC_SUBST(LIBICONV) ]) dnl AC_DEFUN([AM_WITH_OPENSSL], [ AC_ARG_WITH(openssl, [AC_HELP_STRING([--with-openssl=PREFIX], [prefix where OPENSSL is installed])]) unset SSL_LIBS; unset SSL_CFLAGS; have_openssl=no if test x"$tls" != x; then for ssl_prefix in $withval /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr; do printf "looking for openssl in $ssl_prefix...\n" SSL_CFLAGS="-I$ssl_prefix/include" SSL_LIBS="-L$ssl_prefix/lib -lcrypto" AC_CHECK_LIB(ssl, SSL_new, [ have_openssl=yes ], [ have_openssl=no ], [ $SSL_LIBS $SSL_CFLAGS ]) if test x"$have_openssl" = xyes; then save_CPPFLAGS=$CPPFLAGS CPPFLAGS="-I$ssl_prefix/include $CPPFLAGS" AC_CHECK_HEADERS(openssl/ssl.h, have_openssl_h=yes) CPPFLAGS=$save_CPPFLAGS if test x"$have_openssl_h" = xyes; then have_openssl=yes printf "openssl found in $ssl_prefix\n"; SSL_LIBS="-L$ssl_prefix/lib -lssl -lcrypto" CPPFLAGS="-I$ssl_prefix/include $CPPFLAGS" SSL_CFLAGS="-DHAVE_SSL" break fi else # Clear this from the autoconf cache, so in the next pass of # this loop with different -L arguments, it will test again. unset ac_cv_lib_ssl_SSL_new fi done if test x${have_openssl} != xyes; then AC_MSG_ERROR([Could not find development files of OpenSSL library. Install them or disable `tls' with: --disable-tls]) fi AC_SUBST(SSL_LIBS) AC_SUBST(SSL_CFLAGS) fi ]) dnl ejabberd-2.1.11/src/cyrsasl_digest.erl0000664000000000000000000001626412240230175014541 0ustar %%%---------------------------------------------------------------------- %%% File : cyrsasl_digest.erl %%% Author : Alexey Shchepin %%% Purpose : DIGEST-MD5 SASL mechanism %%% Created : 11 Mar 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(cyrsasl_digest). -author('alexey@sevcom.net'). -export([start/1, stop/0, mech_new/4, mech_step/2]). -include("ejabberd.hrl"). -behaviour(cyrsasl). -record(state, {step, nonce, username, authzid, get_password, check_password, auth_module, host, hostfqdn}). start(_Opts) -> Fqdn = get_local_fqdn(), ?INFO_MSG("FQDN used to check DIGEST-MD5 SASL authentication: ~p", [Fqdn]), cyrsasl:register_mechanism("DIGEST-MD5", ?MODULE, digest). stop() -> ok. mech_new(Host, GetPassword, _CheckPassword, CheckPasswordDigest) -> {ok, #state{step = 1, nonce = randoms:get_string(), host = Host, hostfqdn = get_local_fqdn(), get_password = GetPassword, check_password = CheckPasswordDigest}}. mech_step(#state{step = 1, nonce = Nonce} = State, _) -> {continue, "nonce=\"" ++ Nonce ++ "\",qop=\"auth\",charset=utf-8,algorithm=md5-sess", State#state{step = 3}}; mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) -> case parse(ClientIn) of bad -> {error, "bad-protocol"}; KeyVals -> DigestURI = xml:get_attr_s("digest-uri", KeyVals), UserName = xml:get_attr_s("username", KeyVals), case is_digesturi_valid(DigestURI, State#state.host, State#state.hostfqdn) of false -> ?DEBUG("User login not authorized because digest-uri " "seems invalid: ~p (checking for Host ~p, FQDN ~p)", [DigestURI, State#state.host, State#state.hostfqdn]), {error, "not-authorized", UserName}; true -> AuthzId = xml:get_attr_s("authzid", KeyVals), case (State#state.get_password)(UserName) of {false, _} -> {error, "not-authorized", UserName}; {Passwd, AuthModule} -> case (State#state.check_password)(UserName, "", xml:get_attr_s("response", KeyVals), fun(PW) -> response(KeyVals, UserName, PW, Nonce, AuthzId, "AUTHENTICATE") end) of {true, _} -> RspAuth = response(KeyVals, UserName, Passwd, Nonce, AuthzId, ""), {continue, "rspauth=" ++ RspAuth, State#state{step = 5, auth_module = AuthModule, username = UserName, authzid = AuthzId}}; false -> {error, "not-authorized", UserName}; {false, _} -> {error, "not-authorized", UserName} end end end end; mech_step(#state{step = 5, auth_module = AuthModule, username = UserName, authzid = AuthzId}, "") -> {ok, [{username, UserName}, {authzid, AuthzId}, {auth_module, AuthModule}]}; mech_step(A, B) -> ?DEBUG("SASL DIGEST: A ~p B ~p", [A,B]), {error, "bad-protocol"}. parse(S) -> parse1(S, "", []). parse1([$= | Cs], S, Ts) -> parse2(Cs, lists:reverse(S), "", Ts); parse1([$, | Cs], [], Ts) -> parse1(Cs, [], Ts); parse1([$\s | Cs], [], Ts) -> parse1(Cs, [], Ts); parse1([C | Cs], S, Ts) -> parse1(Cs, [C | S], Ts); parse1([], [], T) -> lists:reverse(T); parse1([], _S, _T) -> bad. parse2([$\" | Cs], Key, Val, Ts) -> parse3(Cs, Key, Val, Ts); parse2([C | Cs], Key, Val, Ts) -> parse4(Cs, Key, [C | Val], Ts); parse2([], _, _, _) -> bad. parse3([$\" | Cs], Key, Val, Ts) -> parse4(Cs, Key, Val, Ts); parse3([$\\, C | Cs], Key, Val, Ts) -> parse3(Cs, Key, [C | Val], Ts); parse3([C | Cs], Key, Val, Ts) -> parse3(Cs, Key, [C | Val], Ts); parse3([], _, _, _) -> bad. parse4([$, | Cs], Key, Val, Ts) -> parse1(Cs, "", [{Key, lists:reverse(Val)} | Ts]); parse4([$\s | Cs], Key, Val, Ts) -> parse4(Cs, Key, Val, Ts); parse4([C | Cs], Key, Val, Ts) -> parse4(Cs, Key, [C | Val], Ts); parse4([], Key, Val, Ts) -> parse1([], "", [{Key, lists:reverse(Val)} | Ts]). %% @doc Check if the digest-uri is valid. %% RFC-2831 allows to provide the IP address in Host, %% however ejabberd doesn't allow that. %% If the service (for example jabber.example.org) %% is provided by several hosts (being one of them server3.example.org), %% then acceptable digest-uris would be: %% xmpp/server3.example.org/jabber.example.org, xmpp/server3.example.org and %% xmpp/jabber.example.org %% The last version is not actually allowed by the RFC, but implemented by popular clients is_digesturi_valid(DigestURICase, JabberDomain, JabberFQDN) -> DigestURI = stringprep:tolower(DigestURICase), case catch string:tokens(DigestURI, "/") of ["xmpp", Host] when (Host == JabberDomain) or (Host == JabberFQDN) -> true; ["xmpp", Host, ServName] when (ServName == JabberDomain) and (Host == JabberFQDN) -> true; _ -> false end. get_local_fqdn() -> case (catch get_local_fqdn2()) of Str when is_list(Str) -> Str; _ -> "unknown-fqdn, please configure fqdn option in ejabberd.cfg!" end. get_local_fqdn2() -> case ejabberd_config:get_local_option(fqdn) of ConfiguredFqdn when is_list(ConfiguredFqdn) -> ConfiguredFqdn; _undefined -> {ok, Hostname} = inet:gethostname(), {ok, {hostent, Fqdn, _, _, _, _}} = inet:gethostbyname(Hostname), Fqdn end. digit_to_xchar(D) when (D >= 0) and (D < 10) -> D + 48; digit_to_xchar(D) -> D + 87. hex(S) -> hex(S, []). hex([], Res) -> lists:reverse(Res); hex([N | Ns], Res) -> hex(Ns, [digit_to_xchar(N rem 16), digit_to_xchar(N div 16) | Res]). response(KeyVals, User, Passwd, Nonce, AuthzId, A2Prefix) -> Realm = xml:get_attr_s("realm", KeyVals), CNonce = xml:get_attr_s("cnonce", KeyVals), DigestURI = xml:get_attr_s("digest-uri", KeyVals), NC = xml:get_attr_s("nc", KeyVals), QOP = xml:get_attr_s("qop", KeyVals), A1 = case AuthzId of "" -> binary_to_list( crypto:md5(User ++ ":" ++ Realm ++ ":" ++ Passwd)) ++ ":" ++ Nonce ++ ":" ++ CNonce; _ -> binary_to_list( crypto:md5(User ++ ":" ++ Realm ++ ":" ++ Passwd)) ++ ":" ++ Nonce ++ ":" ++ CNonce ++ ":" ++ AuthzId end, A2 = case QOP of "auth" -> A2Prefix ++ ":" ++ DigestURI; _ -> A2Prefix ++ ":" ++ DigestURI ++ ":00000000000000000000000000000000" end, T = hex(binary_to_list(crypto:md5(A1))) ++ ":" ++ Nonce ++ ":" ++ NC ++ ":" ++ CNonce ++ ":" ++ QOP ++ ":" ++ hex(binary_to_list(crypto:md5(A2))), hex(binary_to_list(crypto:md5(T))). ejabberd-2.1.11/src/ejabberd_admin.erl0000664000000000000000000005013512240230175014423 0ustar %%%------------------------------------------------------------------- %%% File : ejabberd_admin.erl %%% Author : Mickael Remond %%% Purpose : Administrative functions and commands %%% Created : 7 May 2006 by Mickael Remond %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(ejabberd_admin). -author('mickael.remond@process-one.net'). -export([start/0, stop/0, %% Server status/0, reopen_log/0, stop_kindly/2, send_service_message_all_mucs/2, %% Erlang update_list/0, update/1, %% Accounts register/3, unregister/2, registered_users/1, %% Migration jabberd1.4 import_file/1, import_dir/1, %% Purge DB delete_expired_messages/0, delete_old_messages/1, %% Mnesia set_master/1, backup_mnesia/1, restore_mnesia/1, dump_mnesia/1, dump_table/2, load_mnesia/1, install_fallback_mnesia/1, dump_to_textfile/1, dump_to_textfile/2, mnesia_change_nodename/4, restore/1 % Still used by some modules ]). -include("ejabberd.hrl"). -include("ejabberd_commands.hrl"). start() -> ejabberd_commands:register_commands(commands()). stop() -> ejabberd_commands:unregister_commands(commands()). %%% %%% ejabberd commands %%% commands() -> [ %% The commands status, stop and restart are implemented also in ejabberd_ctl %% They are defined here so that other interfaces can use them too #ejabberd_commands{name = status, tags = [server], desc = "Get status of the ejabberd server", module = ?MODULE, function = status, args = [], result = {res, restuple}}, #ejabberd_commands{name = stop, tags = [server], desc = "Stop ejabberd gracefully", module = init, function = stop, args = [], result = {res, rescode}}, #ejabberd_commands{name = restart, tags = [server], desc = "Restart ejabberd gracefully", module = init, function = restart, args = [], result = {res, rescode}}, #ejabberd_commands{name = reopen_log, tags = [logs, server], desc = "Reopen the log files", module = ?MODULE, function = reopen_log, args = [], result = {res, rescode}}, #ejabberd_commands{name = stop_kindly, tags = [server], desc = "Inform users and rooms, wait, and stop the server", longdesc = "Provide the delay in seconds, and the " "announcement quoted, for example: \n" "ejabberdctl stop_kindly 60 " "\\\"The server will stop in one minute.\\\"", module = ?MODULE, function = stop_kindly, args = [{delay, integer}, {announcement, string}], result = {res, rescode}}, #ejabberd_commands{name = get_loglevel, tags = [logs, server], desc = "Get the current loglevel", module = ejabberd_loglevel, function = get, args = [], result = {leveltuple, {tuple, [{levelnumber, integer}, {levelatom, atom}, {leveldesc, string} ]}}}, #ejabberd_commands{name = update_list, tags = [server], desc = "List modified modules that can be updated", module = ?MODULE, function = update_list, args = [], result = {modules, {list, {module, string}}}}, #ejabberd_commands{name = update, tags = [server], desc = "Update the given module, or use the keyword: all", module = ?MODULE, function = update, args = [{module, string}], result = {res, restuple}}, #ejabberd_commands{name = register, tags = [accounts], desc = "Register a user", module = ?MODULE, function = register, args = [{user, string}, {host, string}, {password, string}], result = {res, restuple}}, #ejabberd_commands{name = unregister, tags = [accounts], desc = "Unregister a user", module = ?MODULE, function = unregister, args = [{user, string}, {host, string}], result = {res, restuple}}, #ejabberd_commands{name = registered_users, tags = [accounts], desc = "List all registered users in HOST", module = ?MODULE, function = registered_users, args = [{host, string}], result = {users, {list, {username, string}}}}, #ejabberd_commands{name = import_file, tags = [mnesia], desc = "Import user data from jabberd14 spool file", module = ?MODULE, function = import_file, args = [{file, string}], result = {res, restuple}}, #ejabberd_commands{name = import_dir, tags = [mnesia], desc = "Import users data from jabberd14 spool dir", module = ?MODULE, function = import_dir, args = [{file, string}], result = {res, restuple}}, #ejabberd_commands{name = import_piefxis, tags = [mnesia], desc = "Import users data from a PIEFXIS file (XEP-0227)", module = ejabberd_piefxis, function = import_file, args = [{file, string}], result = {res, rescode}}, #ejabberd_commands{name = export_piefxis, tags = [mnesia], desc = "Export data of all users in the server to PIEFXIS files (XEP-0227)", module = ejabberd_piefxis, function = export_server, args = [{dir, string}], result = {res, rescode}}, #ejabberd_commands{name = export_piefxis_host, tags = [mnesia], desc = "Export data of users in a host to PIEFXIS files (XEP-0227)", module = ejabberd_piefxis, function = export_host, args = [{dir, string}, {host, string}], result = {res, rescode}}, #ejabberd_commands{name = delete_expired_messages, tags = [purge], desc = "Delete expired offline messages from database", module = ?MODULE, function = delete_expired_messages, args = [], result = {res, rescode}}, #ejabberd_commands{name = delete_old_messages, tags = [purge], desc = "Delete offline messages older than DAYS", module = ?MODULE, function = delete_old_messages, args = [{days, integer}], result = {res, rescode}}, #ejabberd_commands{name = rename_default_nodeplugin, tags = [mnesia], desc = "Update PubSub table from old ejabberd trunk SVN to 2.1.0", module = mod_pubsub, function = rename_default_nodeplugin, args = [], result = {res, rescode}}, #ejabberd_commands{name = set_master, tags = [mnesia], desc = "Set master node of the clustered Mnesia tables", longdesc = "If you provide as nodename \"self\", this " "node will be set as its own master.", module = ?MODULE, function = set_master, args = [{nodename, string}], result = {res, restuple}}, #ejabberd_commands{name = mnesia_change_nodename, tags = [mnesia], desc = "Change the erlang node name in a backup file", module = ?MODULE, function = mnesia_change_nodename, args = [{oldnodename, string}, {newnodename, string}, {oldbackup, string}, {newbackup, string}], result = {res, restuple}}, #ejabberd_commands{name = backup, tags = [mnesia], desc = "Store the database to backup file", module = ?MODULE, function = backup_mnesia, args = [{file, string}], result = {res, restuple}}, #ejabberd_commands{name = restore, tags = [mnesia], desc = "Restore the database from backup file", module = ?MODULE, function = restore_mnesia, args = [{file, string}], result = {res, restuple}}, #ejabberd_commands{name = dump, tags = [mnesia], desc = "Dump the database to text file", module = ?MODULE, function = dump_mnesia, args = [{file, string}], result = {res, restuple}}, #ejabberd_commands{name = dump_table, tags = [mnesia], desc = "Dump a table to text file", module = ?MODULE, function = dump_table, args = [{file, string}, {table, string}], result = {res, restuple}}, #ejabberd_commands{name = load, tags = [mnesia], desc = "Restore the database from text file", module = ?MODULE, function = load_mnesia, args = [{file, string}], result = {res, restuple}}, #ejabberd_commands{name = install_fallback, tags = [mnesia], desc = "Install the database from a fallback file", module = ?MODULE, function = install_fallback_mnesia, args = [{file, string}], result = {res, restuple}} ]. %%% %%% Server management %%% status() -> {InternalStatus, ProvidedStatus} = init:get_status(), String1 = io_lib:format("The node ~p is ~p. Status: ~p", [node(), InternalStatus, ProvidedStatus]), {Is_running, String2} = case lists:keysearch(ejabberd, 1, application:which_applications()) of false -> {ejabberd_not_running, "ejabberd is not running in that node."}; {value, {_, _, Version}} -> {ok, io_lib:format("ejabberd ~s is running in that node", [Version])} end, {Is_running, String1 ++ String2}. reopen_log() -> ejabberd_hooks:run(reopen_log_hook, []), %% TODO: Use the Reopen log API for logger_h ? ejabberd_logger_h:reopen_log(), case application:get_env(sasl,sasl_error_logger) of {ok, {file, SASLfile}} -> error_logger:delete_report_handler(sasl_report_file_h), ejabberd_logger_h:rotate_log(SASLfile), error_logger:add_report_handler(sasl_report_file_h, {SASLfile, get_sasl_error_logger_type()}); _ -> false end, ok. %% Function copied from Erlang/OTP lib/sasl/src/sasl.erl which doesn't export it get_sasl_error_logger_type () -> case application:get_env (sasl, errlog_type) of {ok, error} -> error; {ok, progress} -> progress; {ok, all} -> all; {ok, Bad} -> exit ({bad_config, {sasl, {errlog_type, Bad}}}); _ -> all end. %%% %%% Stop Kindly %%% stop_kindly(DelaySeconds, AnnouncementText) -> Subject = io_lib:format("Server stop in ~p seconds!", [DelaySeconds]), WaitingDesc = io_lib:format("Waiting ~p seconds", [DelaySeconds]), Steps = [ {"Stopping ejabberd port listeners", ejabberd_listener, stop_listeners, []}, {"Sending announcement to connected users", mod_announce, send_announcement_to_all, [?MYNAME, Subject, AnnouncementText]}, {"Sending service message to MUC rooms", ejabberd_admin, send_service_message_all_mucs, [Subject, AnnouncementText]}, {WaitingDesc, timer, sleep, [DelaySeconds * 1000]}, {"Stopping ejabberd", application, stop, [ejabberd]}, {"Stopping Mnesia", mnesia, stop, []}, {"Stopping Erlang node", init, stop, []} ], NumberLast = length(Steps), TimestampStart = calendar:datetime_to_gregorian_seconds({date(), time()}), lists:foldl( fun({Desc, Mod, Func, Args}, NumberThis) -> SecondsDiff = calendar:datetime_to_gregorian_seconds({date(), time()}) - TimestampStart, io:format("[~p/~p ~ps] ~s... ", [NumberThis, NumberLast, SecondsDiff, Desc]), Result = (catch apply(Mod, Func, Args)), io:format("~p~n", [Result]), NumberThis+1 end, 1, Steps), ok. send_service_message_all_mucs(Subject, AnnouncementText) -> Message = io_lib:format("~s~n~s", [Subject, AnnouncementText]), lists:foreach( fun(ServerHost) -> MUCHost = gen_mod:get_module_opt_host( ServerHost, mod_muc, "conference.@HOST@"), mod_muc:broadcast_service_message(MUCHost, Message) end, ?MYHOSTS). %%% %%% ejabberd_update %%% update_list() -> {ok, _Dir, UpdatedBeams, _Script, _LowLevelScript, _Check} = ejabberd_update:update_info(), [atom_to_list(Beam) || Beam <- UpdatedBeams]. update("all") -> [update_module(ModStr) || ModStr <- update_list()], {ok, []}; update(ModStr) -> update_module(ModStr). update_module(ModuleNameString) -> ModuleName = list_to_atom(ModuleNameString), case ejabberd_update:update([ModuleName]) of {ok, _Res} -> {ok, []}; {error, Reason} -> {error, Reason} end. %%% %%% Account management %%% register(User, Host, Password) -> case ejabberd_auth:try_register(User, Host, Password) of {atomic, ok} -> {ok, io_lib:format("User ~s@~s successfully registered", [User, Host])}; {atomic, exists} -> String = io_lib:format("User ~s@~s already registered at node ~p", [User, Host, node()]), {exists, String}; {error, Reason} -> String = io_lib:format("Can't register user ~s@~s at node ~p: ~p", [User, Host, node(), Reason]), {cannot_register, String} end. unregister(User, Host) -> ejabberd_auth:remove_user(User, Host), {ok, ""}. registered_users(Host) -> Users = ejabberd_auth:get_vh_registered_users(Host), SUsers = lists:sort(Users), lists:map(fun({U, _S}) -> U end, SUsers). %%% %%% Migration management %%% import_file(Path) -> case jd2ejd:import_file(Path) of ok -> {ok, ""}; {error, Reason} -> String = io_lib:format("Can't import jabberd14 spool file ~p at node ~p: ~p", [filename:absname(Path), node(), Reason]), {cannot_import_file, String} end. import_dir(Path) -> case jd2ejd:import_dir(Path) of ok -> {ok, ""}; {error, Reason} -> String = io_lib:format("Can't import jabberd14 spool dir ~p at node ~p: ~p", [filename:absname(Path), node(), Reason]), {cannot_import_dir, String} end. %%% %%% Purge DB %%% delete_expired_messages() -> {atomic, ok} = mod_offline:remove_expired_messages(), ok. delete_old_messages(Days) -> {atomic, _} = mod_offline:remove_old_messages(Days), ok. %%% %%% Mnesia management %%% set_master("self") -> set_master(node()); set_master(NodeString) when is_list(NodeString) -> set_master(list_to_atom(NodeString)); set_master(Node) when is_atom(Node) -> case mnesia:set_master_nodes([Node]) of ok -> {ok, ""}; {error, Reason} -> String = io_lib:format("Can't set master node ~p at node ~p:~n~p", [Node, node(), Reason]), {error, String} end. backup_mnesia(Path) -> case mnesia:backup(Path) of ok -> {ok, ""}; {error, Reason} -> String = io_lib:format("Can't store backup in ~p at node ~p: ~p", [filename:absname(Path), node(), Reason]), {cannot_backup, String} end. restore_mnesia(Path) -> case ejabberd_admin:restore(Path) of {atomic, _} -> {ok, ""}; {error, Reason} -> String = io_lib:format("Can't restore backup from ~p at node ~p: ~p", [filename:absname(Path), node(), Reason]), {cannot_restore, String}; {aborted,{no_exists,Table}} -> String = io_lib:format("Can't restore backup from ~p at node ~p: Table ~p does not exist.", [filename:absname(Path), node(), Table]), {table_not_exists, String}; {aborted,enoent} -> String = io_lib:format("Can't restore backup from ~p at node ~p: File not found.", [filename:absname(Path), node()]), {file_not_found, String} end. %% Mnesia database restore %% This function is called from ejabberd_ctl, ejabberd_web_admin and %% mod_configure/adhoc restore(Path) -> mnesia:restore(Path, [{keep_tables,keep_tables()}, {default_op, skip_tables}]). %% This function return a list of tables that should be kept from a previous %% version backup. %% Obsolete tables or tables created by module who are no longer used are not %% restored and are ignored. keep_tables() -> lists:flatten([acl, passwd, config, local_config, keep_modules_tables()]). %% Returns the list of modules tables in use, according to the list of actually %% loaded modules keep_modules_tables() -> lists:map(fun(Module) -> module_tables(Module) end, gen_mod:loaded_modules(?MYNAME)). %% TODO: This mapping should probably be moved to a callback function in each %% module. %% Mapping between modules and their tables module_tables(mod_announce) -> [motd, motd_users]; module_tables(mod_irc) -> [irc_custom]; module_tables(mod_last) -> [last_activity]; module_tables(mod_muc) -> [muc_room, muc_registered]; module_tables(mod_offline) -> [offline_msg]; module_tables(mod_privacy) -> [privacy]; module_tables(mod_private) -> [private_storage]; module_tables(mod_pubsub) -> [pubsub_node]; module_tables(mod_roster) -> [roster]; module_tables(mod_shared_roster) -> [sr_group, sr_user]; module_tables(mod_vcard) -> [vcard, vcard_search]; module_tables(_Other) -> []. get_local_tables() -> Tabs1 = lists:delete(schema, mnesia:system_info(local_tables)), Tabs = lists:filter( fun(T) -> case mnesia:table_info(T, storage_type) of disc_copies -> true; disc_only_copies -> true; _ -> false end end, Tabs1), Tabs. dump_mnesia(Path) -> Tabs = get_local_tables(), dump_tables(Path, Tabs). dump_table(Path, STable) -> Table = list_to_atom(STable), dump_tables(Path, [Table]). dump_tables(Path, Tables) -> case dump_to_textfile(Path, Tables) of ok -> {ok, ""}; {error, Reason} -> String = io_lib:format("Can't store dump in ~p at node ~p: ~p", [filename:absname(Path), node(), Reason]), {cannot_dump, String} end. dump_to_textfile(File) -> Tabs = get_local_tables(), dump_to_textfile(File, Tabs). dump_to_textfile(File, Tabs) -> dump_to_textfile(mnesia:system_info(is_running), Tabs, file:open(File, [write])). dump_to_textfile(yes, Tabs, {ok, F}) -> Defs = lists:map( fun(T) -> {T, [{record_name, mnesia:table_info(T, record_name)}, {attributes, mnesia:table_info(T, attributes)}]} end, Tabs), io:format(F, "~p.~n", [{tables, Defs}]), lists:foreach(fun(T) -> dump_tab(F, T) end, Tabs), file:close(F); dump_to_textfile(_, _, {ok, F}) -> file:close(F), {error, mnesia_not_running}; dump_to_textfile(_, _, {error, Reason}) -> {error, Reason}. dump_tab(F, T) -> W = mnesia:table_info(T, wild_pattern), {atomic,All} = mnesia:transaction( fun() -> mnesia:match_object(T, W, read) end), lists:foreach( fun(Term) -> io:format(F,"~p.~n", [setelement(1, Term, T)]) end, All). load_mnesia(Path) -> case mnesia:load_textfile(Path) of {atomic, ok} -> {ok, ""}; {error, Reason} -> String = io_lib:format("Can't load dump in ~p at node ~p: ~p", [filename:absname(Path), node(), Reason]), {cannot_load, String} end. install_fallback_mnesia(Path) -> case mnesia:install_fallback(Path) of ok -> {ok, ""}; {error, Reason} -> String = io_lib:format("Can't install fallback from ~p at node ~p: ~p", [filename:absname(Path), node(), Reason]), {cannot_fallback, String} end. mnesia_change_nodename(FromString, ToString, Source, Target) -> From = list_to_atom(FromString), To = list_to_atom(ToString), Switch = fun (Node) when Node == From -> io:format(" - Replacing nodename: '~p' with: '~p'~n", [From, To]), To; (Node) when Node == To -> %% throw({error, already_exists}); io:format(" - Node: '~p' will not be modified (it is already '~p')~n", [Node, To]), Node; (Node) -> io:format(" - Node: '~p' will not be modified (it is not '~p')~n", [Node, From]), Node end, Convert = fun ({schema, db_nodes, Nodes}, Acc) -> io:format(" +++ db_nodes ~p~n", [Nodes]), {[{schema, db_nodes, lists:map(Switch,Nodes)}], Acc}; ({schema, version, Version}, Acc) -> io:format(" +++ version: ~p~n", [Version]), {[{schema, version, Version}], Acc}; ({schema, cookie, Cookie}, Acc) -> io:format(" +++ cookie: ~p~n", [Cookie]), {[{schema, cookie, Cookie}], Acc}; ({schema, Tab, CreateList}, Acc) -> io:format("~n * Checking table: '~p'~n", [Tab]), Keys = [ram_copies, disc_copies, disc_only_copies], OptSwitch = fun({Key, Val}) -> case lists:member(Key, Keys) of true -> io:format(" + Checking key: '~p'~n", [Key]), {Key, lists:map(Switch, Val)}; false-> {Key, Val} end end, Res = {[{schema, Tab, lists:map(OptSwitch, CreateList)}], Acc}, Res; (Other, Acc) -> {[Other], Acc} end, mnesia:traverse_backup(Source, Target, Convert, switched). ejabberd-2.1.11/src/mod_last.erl0000664000000000000000000001735112240230175013322 0ustar %%%---------------------------------------------------------------------- %%% File : mod_last.erl %%% Author : Alexey Shchepin %%% Purpose : jabber:iq:last support (XEP-0012) %%% Created : 24 Oct 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_last). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_local_iq/3, process_sm_iq/3, on_presence_update/4, store_last_info/4, get_last_info/2, remove_user/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_privacy.hrl"). -record(last_activity, {us, timestamp, status}). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), mnesia:create_table(last_activity, [{disc_copies, [node()]}, {attributes, record_info(fields, last_activity)}]), update_table(), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST, ?MODULE, process_local_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST, ?MODULE, process_sm_iq, IQDisc), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:add(unset_presence_hook, Host, ?MODULE, on_presence_update, 50). stop(Host) -> ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(unset_presence_hook, Host, ?MODULE, on_presence_update, 50), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST). %%% %%% Uptime of ejabberd node %%% process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> Sec = get_node_uptime(), IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_LAST}, {"seconds", integer_to_list(Sec)}], []}]} end. %% @spec () -> integer() %% @doc Get the uptime of the ejabberd node, expressed in seconds. %% When ejabberd is starting, ejabberd_config:start/0 stores the datetime. get_node_uptime() -> case ejabberd_config:get_local_option(node_start) of {_, _, _} = StartNow -> now_to_seconds(now()) - now_to_seconds(StartNow); _undefined -> trunc(element(1, erlang:statistics(wall_clock))/1000) end. now_to_seconds({MegaSecs, Secs, _MicroSecs}) -> MegaSecs * 1000000 + Secs. %%% %%% Serve queries about user last online %%% process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> User = To#jid.luser, Server = To#jid.lserver, {Subscription, _Groups} = ejabberd_hooks:run_fold( roster_get_jid_info, Server, {none, []}, [User, Server, From]), if (Subscription == both) or (Subscription == from) or ((From#jid.luser == To#jid.luser) and (From#jid.lserver == To#jid.lserver)) -> UserListRecord = ejabberd_hooks:run_fold( privacy_get_user_list, Server, #userlist{}, [User, Server]), case ejabberd_hooks:run_fold( privacy_check_packet, Server, allow, [User, Server, UserListRecord, {To, From, {xmlelement, "presence", [], []}}, out]) of allow -> get_last_iq(IQ, SubEl, User, Server); deny -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]} end; true -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]} end end. %% @spec (LUser::string(), LServer::string()) -> %% {ok, TimeStamp::integer(), Status::string()} | not_found | {error, Reason} get_last(LUser, LServer) -> case catch mnesia:dirty_read(last_activity, {LUser, LServer}) of {'EXIT', Reason} -> {error, Reason}; [] -> not_found; [#last_activity{timestamp = TimeStamp, status = Status}] -> {ok, TimeStamp, Status} end. get_last_iq(IQ, SubEl, LUser, LServer) -> case ejabberd_sm:get_user_resources(LUser, LServer) of [] -> case get_last(LUser, LServer) of {error, _Reason} -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; not_found -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]}; {ok, TimeStamp, Status} -> TimeStamp2 = now_to_seconds(now()), Sec = TimeStamp2 - TimeStamp, IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_LAST}, {"seconds", integer_to_list(Sec)}], [{xmlcdata, Status}]}]} end; _ -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_LAST}, {"seconds", "0"}], []}]} end. on_presence_update(User, Server, _Resource, Status) -> TimeStamp = now_to_seconds(now()), store_last_info(User, Server, TimeStamp, Status). store_last_info(User, Server, TimeStamp, Status) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, F = fun() -> mnesia:write(#last_activity{us = US, timestamp = TimeStamp, status = Status}) end, mnesia:transaction(F). %% @spec (LUser::string(), LServer::string()) -> %% {ok, TimeStamp::integer(), Status::string()} | not_found get_last_info(LUser, LServer) -> case get_last(LUser, LServer) of {error, _Reason} -> not_found; Res -> Res end. remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, F = fun() -> mnesia:delete({last_activity, US}) end, mnesia:transaction(F). update_table() -> Fields = record_info(fields, last_activity), case mnesia:table_info(last_activity, attributes) of Fields -> ok; [user, timestamp, status] -> ?INFO_MSG("Converting last_activity table from {user, timestamp, status} format", []), Host = ?MYNAME, mnesia:transform_table(last_activity, ignore, Fields), F = fun() -> mnesia:write_lock_table(last_activity), mnesia:foldl( fun({_, U, T, S} = R, _) -> mnesia:delete_object(R), mnesia:write( #last_activity{us = {U, Host}, timestamp = T, status = S}) end, ok, last_activity) end, mnesia:transaction(F); [user, timestamp] -> ?INFO_MSG("Converting last_activity table from {user, timestamp} format", []), Host = ?MYNAME, mnesia:transform_table( last_activity, fun({_, U, T}) -> #last_activity{us = U, timestamp = T, status = ""} end, Fields), F = fun() -> mnesia:write_lock_table(last_activity), mnesia:foldl( fun({_, U, T, S} = R, _) -> mnesia:delete_object(R), mnesia:write( #last_activity{us = {U, Host}, timestamp = T, status = S}) end, ok, last_activity) end, mnesia:transaction(F); _ -> ?INFO_MSG("Recreating last_activity table", []), mnesia:transform_table(last_activity, ignore, Fields) end. ejabberd-2.1.11/src/mod_privacy.erl0000664000000000000000000004561012240230175014033 0ustar %%%---------------------------------------------------------------------- %%% File : mod_privacy.erl %%% Author : Alexey Shchepin %%% Purpose : jabber:iq:privacy support %%% Created : 21 Jul 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_privacy). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_iq/3, process_iq_set/4, process_iq_get/5, get_user_list/3, check_packet/6, remove_user/2, updated_list/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_privacy.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), mnesia:create_table(privacy, [{disc_copies, [node()]}, {attributes, record_info(fields, privacy)}]), update_table(), ejabberd_hooks:add(privacy_iq_get, Host, ?MODULE, process_iq_get, 50), ejabberd_hooks:add(privacy_iq_set, Host, ?MODULE, process_iq_set, 50), ejabberd_hooks:add(privacy_get_user_list, Host, ?MODULE, get_user_list, 50), ejabberd_hooks:add(privacy_check_packet, Host, ?MODULE, check_packet, 50), ejabberd_hooks:add(privacy_updated_list, Host, ?MODULE, updated_list, 50), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY, ?MODULE, process_iq, IQDisc). stop(Host) -> ejabberd_hooks:delete(privacy_iq_get, Host, ?MODULE, process_iq_get, 50), ejabberd_hooks:delete(privacy_iq_set, Host, ?MODULE, process_iq_set, 50), ejabberd_hooks:delete(privacy_get_user_list, Host, ?MODULE, get_user_list, 50), ejabberd_hooks:delete(privacy_check_packet, Host, ?MODULE, check_packet, 50), ejabberd_hooks:delete(privacy_updated_list, Host, ?MODULE, updated_list, 50), ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY). process_iq(_From, _To, IQ) -> SubEl = IQ#iq.sub_el, IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}. process_iq_get(_, From, _To, #iq{sub_el = SubEl}, #userlist{name = Active}) -> #jid{luser = LUser, lserver = LServer} = From, {xmlelement, _, _, Els} = SubEl, case xml:remove_cdata(Els) of [] -> process_lists_get(LUser, LServer, Active); [{xmlelement, Name, Attrs, _SubEls}] -> case Name of "list" -> ListName = xml:get_attr("name", Attrs), process_list_get(LUser, LServer, ListName); _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end. process_lists_get(LUser, LServer, Active) -> case catch mnesia:dirty_read(privacy, {LUser, LServer}) of {'EXIT', _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; [] -> {result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]}; [#privacy{default = Default, lists = Lists}] -> case Lists of [] -> {result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]}; _ -> LItems = lists:map( fun({N, _}) -> {xmlelement, "list", [{"name", N}], []} end, Lists), DItems = case Default of none -> LItems; _ -> [{xmlelement, "default", [{"name", Default}], []} | LItems] end, ADItems = case Active of none -> DItems; _ -> [{xmlelement, "active", [{"name", Active}], []} | DItems] end, {result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], ADItems}]} end end. process_list_get(LUser, LServer, {value, Name}) -> case catch mnesia:dirty_read(privacy, {LUser, LServer}) of {'EXIT', _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; [] -> {error, ?ERR_ITEM_NOT_FOUND}; %{result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]}; [#privacy{lists = Lists}] -> case lists:keysearch(Name, 1, Lists) of {value, {_, List}} -> LItems = lists:map(fun item_to_xml/1, List), {result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], [{xmlelement, "list", [{"name", Name}], LItems}]}]}; _ -> {error, ?ERR_ITEM_NOT_FOUND} end end; process_list_get(_LUser, _LServer, false) -> {error, ?ERR_BAD_REQUEST}. item_to_xml(Item) -> Attrs1 = [{"action", action_to_list(Item#listitem.action)}, {"order", order_to_list(Item#listitem.order)}], Attrs2 = case Item#listitem.type of none -> Attrs1; Type -> [{"type", type_to_list(Item#listitem.type)}, {"value", value_to_list(Type, Item#listitem.value)} | Attrs1] end, SubEls = case Item#listitem.match_all of true -> []; false -> SE1 = case Item#listitem.match_iq of true -> [{xmlelement, "iq", [], []}]; false -> [] end, SE2 = case Item#listitem.match_message of true -> [{xmlelement, "message", [], []} | SE1]; false -> SE1 end, SE3 = case Item#listitem.match_presence_in of true -> [{xmlelement, "presence-in", [], []} | SE2]; false -> SE2 end, SE4 = case Item#listitem.match_presence_out of true -> [{xmlelement, "presence-out", [], []} | SE3]; false -> SE3 end, SE4 end, {xmlelement, "item", Attrs2, SubEls}. action_to_list(Action) -> case Action of allow -> "allow"; deny -> "deny" end. order_to_list(Order) -> integer_to_list(Order). type_to_list(Type) -> case Type of jid -> "jid"; group -> "group"; subscription -> "subscription" end. value_to_list(Type, Val) -> case Type of jid -> jlib:jid_to_string(Val); group -> Val; subscription -> case Val of both -> "both"; to -> "to"; from -> "from"; none -> "none" end end. list_to_action(S) -> case S of "allow" -> allow; "deny" -> deny end. process_iq_set(_, From, _To, #iq{sub_el = SubEl}) -> #jid{luser = LUser, lserver = LServer} = From, {xmlelement, _, _, Els} = SubEl, case xml:remove_cdata(Els) of [{xmlelement, Name, Attrs, SubEls}] -> ListName = xml:get_attr("name", Attrs), case Name of "list" -> process_list_set(LUser, LServer, ListName, xml:remove_cdata(SubEls)); "active" -> process_active_set(LUser, LServer, ListName); "default" -> process_default_set(LUser, LServer, ListName); _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end. process_default_set(LUser, LServer, {value, Name}) -> F = fun() -> case mnesia:read({privacy, {LUser, LServer}}) of [] -> {error, ?ERR_ITEM_NOT_FOUND}; [#privacy{lists = Lists} = P] -> case lists:keymember(Name, 1, Lists) of true -> mnesia:write(P#privacy{default = Name, lists = Lists}), {result, []}; false -> {error, ?ERR_ITEM_NOT_FOUND} end end end, case mnesia:transaction(F) of {atomic, {error, _} = Error} -> Error; {atomic, {result, _} = Res} -> Res; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end; process_default_set(LUser, LServer, false) -> F = fun() -> case mnesia:read({privacy, {LUser, LServer}}) of [] -> {result, []}; [R] -> mnesia:write(R#privacy{default = none}), {result, []} end end, case mnesia:transaction(F) of {atomic, {error, _} = Error} -> Error; {atomic, {result, _} = Res} -> Res; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. process_active_set(LUser, LServer, {value, Name}) -> case catch mnesia:dirty_read(privacy, {LUser, LServer}) of [] -> {error, ?ERR_ITEM_NOT_FOUND}; [#privacy{lists = Lists}] -> case lists:keysearch(Name, 1, Lists) of {value, {_, List}} -> NeedDb = is_list_needdb(List), {result, [], #userlist{name = Name, list = List, needdb = NeedDb}}; false -> {error, ?ERR_ITEM_NOT_FOUND} end end; process_active_set(_LUser, _LServer, false) -> {result, [], #userlist{}}. process_list_set(LUser, LServer, {value, Name}, Els) -> case parse_items(Els) of false -> {error, ?ERR_BAD_REQUEST}; remove -> F = fun() -> case mnesia:read({privacy, {LUser, LServer}}) of [] -> {result, []}; [#privacy{default = Default, lists = Lists} = P] -> % TODO: check active if Name == Default -> {error, ?ERR_CONFLICT}; true -> NewLists = lists:keydelete(Name, 1, Lists), mnesia:write( P#privacy{lists = NewLists}), {result, []} end end end, case mnesia:transaction(F) of {atomic, {error, _} = Error} -> Error; {atomic, {result, _} = Res} -> ejabberd_router:route( jlib:make_jid(LUser, LServer, ""), jlib:make_jid(LUser, LServer, ""), {xmlelement, "broadcast", [], [{privacy_list, #userlist{name = Name, list = []}, Name}]}), Res; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end; List -> F = fun() -> case mnesia:wread({privacy, {LUser, LServer}}) of [] -> NewLists = [{Name, List}], mnesia:write(#privacy{us = {LUser, LServer}, lists = NewLists}), {result, []}; [#privacy{lists = Lists} = P] -> NewLists1 = lists:keydelete(Name, 1, Lists), NewLists = [{Name, List} | NewLists1], mnesia:write(P#privacy{lists = NewLists}), {result, []} end end, case mnesia:transaction(F) of {atomic, {error, _} = Error} -> Error; {atomic, {result, _} = Res} -> NeedDb = is_list_needdb(List), ejabberd_router:route( jlib:make_jid(LUser, LServer, ""), jlib:make_jid(LUser, LServer, ""), {xmlelement, "broadcast", [], [{privacy_list, #userlist{name = Name, list = List, needdb = NeedDb}, Name}]}), Res; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end end; process_list_set(_LUser, _LServer, false, _Els) -> {error, ?ERR_BAD_REQUEST}. parse_items([]) -> remove; parse_items(Els) -> parse_items(Els, []). parse_items([], Res) -> %% Sort the items by their 'order' attribute lists:keysort(#listitem.order, Res); parse_items([{xmlelement, "item", Attrs, SubEls} | Els], Res) -> Type = xml:get_attr("type", Attrs), Value = xml:get_attr("value", Attrs), SAction = xml:get_attr("action", Attrs), SOrder = xml:get_attr("order", Attrs), Action = case catch list_to_action(element(2, SAction)) of {'EXIT', _} -> false; Val -> Val end, Order = case catch list_to_integer(element(2, SOrder)) of {'EXIT', _} -> false; IntVal -> if IntVal >= 0 -> IntVal; true -> false end end, if (Action /= false) and (Order /= false) -> I1 = #listitem{action = Action, order = Order}, I2 = case {Type, Value} of {{value, T}, {value, V}} -> case T of "jid" -> case jlib:string_to_jid(V) of error -> false; JID -> I1#listitem{ type = jid, value = jlib:jid_tolower(JID)} end; "group" -> I1#listitem{type = group, value = V}; "subscription" -> case V of "none" -> I1#listitem{type = subscription, value = none}; "both" -> I1#listitem{type = subscription, value = both}; "from" -> I1#listitem{type = subscription, value = from}; "to" -> I1#listitem{type = subscription, value = to}; _ -> false end end; {{value, _}, false} -> false; _ -> I1 end, case I2 of false -> false; _ -> case parse_matches(I2, xml:remove_cdata(SubEls)) of false -> false; I3 -> parse_items(Els, [I3 | Res]) end end; true -> false end; parse_items(_, _Res) -> false. parse_matches(Item, []) -> Item#listitem{match_all = true}; parse_matches(Item, Els) -> parse_matches1(Item, Els). parse_matches1(Item, []) -> Item; parse_matches1(Item, [{xmlelement, "message", _, _} | Els]) -> parse_matches1(Item#listitem{match_message = true}, Els); parse_matches1(Item, [{xmlelement, "iq", _, _} | Els]) -> parse_matches1(Item#listitem{match_iq = true}, Els); parse_matches1(Item, [{xmlelement, "presence-in", _, _} | Els]) -> parse_matches1(Item#listitem{match_presence_in = true}, Els); parse_matches1(Item, [{xmlelement, "presence-out", _, _} | Els]) -> parse_matches1(Item#listitem{match_presence_out = true}, Els); parse_matches1(_Item, [{xmlelement, _, _, _} | _Els]) -> false. is_list_needdb(Items) -> lists:any( fun(X) -> case X#listitem.type of subscription -> true; group -> true; _ -> false end end, Items). get_user_list(_, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), case catch mnesia:dirty_read(privacy, {LUser, LServer}) of [] -> #userlist{}; [#privacy{default = Default, lists = Lists}] -> case Default of none -> #userlist{}; _ -> case lists:keysearch(Default, 1, Lists) of {value, {_, List}} -> NeedDb = is_list_needdb(List), #userlist{name = Default, list = List, needdb = NeedDb}; _ -> #userlist{} end end; _ -> #userlist{} end. %% From is the sender, To is the destination. %% If Dir = out, User@Server is the sender account (From). %% If Dir = in, User@Server is the destination account (To). check_packet(_, _User, _Server, _UserList, {#jid{luser = "", lserver = Server} = _From, #jid{lserver = Server} = _To, _}, in) -> allow; check_packet(_, _User, _Server, _UserList, {#jid{lserver = Server} = _From, #jid{luser = "", lserver = Server} = _To, _}, out) -> allow; check_packet(_, _User, _Server, _UserList, {#jid{luser = User, lserver = Server} = _From, #jid{luser = User, lserver = Server} = _To, _}, _Dir) -> allow; check_packet(_, User, Server, #userlist{list = List, needdb = NeedDb}, {From, To, {xmlelement, PName, Attrs, _}}, Dir) -> case List of [] -> allow; _ -> PType = case PName of "message" -> message; "iq" -> iq; "presence" -> case xml:get_attr_s("type", Attrs) of %% notification "" -> presence; "unavailable" -> presence; %% subscribe, subscribed, unsubscribe, %% unsubscribed, error, probe, or other _ -> other end end, PType2 = case {PType, Dir} of {message, in} -> message; {iq, in} -> iq; {presence, in} -> presence_in; {presence, out} -> presence_out; {_, _} -> other end, LJID = case Dir of in -> jlib:jid_tolower(From); out -> jlib:jid_tolower(To) end, {Subscription, Groups} = case NeedDb of true -> ejabberd_hooks:run_fold(roster_get_jid_info, jlib:nameprep(Server), {none, []}, [User, Server, LJID]); false -> {[], []} end, check_packet_aux(List, PType2, LJID, Subscription, Groups) end. %% Ptype = mesage | iq | presence_in | presence_out | other check_packet_aux([], _PType, _JID, _Subscription, _Groups) -> allow; check_packet_aux([Item | List], PType, JID, Subscription, Groups) -> #listitem{type = Type, value = Value, action = Action} = Item, case is_ptype_match(Item, PType) of true -> case Type of none -> Action; _ -> case is_type_match(Type, Value, JID, Subscription, Groups) of true -> Action; false -> check_packet_aux(List, PType, JID, Subscription, Groups) end end; false -> check_packet_aux(List, PType, JID, Subscription, Groups) end. is_ptype_match(Item, PType) -> case Item#listitem.match_all of true -> true; false -> case PType of message -> Item#listitem.match_message; iq -> Item#listitem.match_iq; presence_in -> Item#listitem.match_presence_in; presence_out -> Item#listitem.match_presence_out; other -> false end end. is_type_match(Type, Value, JID, Subscription, Groups) -> case Type of jid -> case Value of {"", Server, ""} -> case JID of {_, Server, _} -> true; _ -> false end; {User, Server, ""} -> case JID of {User, Server, _} -> true; _ -> false end; _ -> Value == JID end; subscription -> Value == Subscription; group -> lists:member(Value, Groups) end. remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), F = fun() -> mnesia:delete({privacy, {LUser, LServer}}) end, mnesia:transaction(F). updated_list(_, #userlist{name = OldName} = Old, #userlist{name = NewName} = New) -> if OldName == NewName -> New; true -> Old end. update_table() -> Fields = record_info(fields, privacy), case mnesia:table_info(privacy, attributes) of Fields -> ok; [user, default, lists] -> ?INFO_MSG("Converting privacy table from " "{user, default, lists} format", []), Host = ?MYNAME, {atomic, ok} = mnesia:create_table( mod_privacy_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, privacy}, {attributes, record_info(fields, privacy)}]), mnesia:transform_table(privacy, ignore, Fields), F1 = fun() -> mnesia:write_lock_table(mod_privacy_tmp_table), mnesia:foldl( fun(#privacy{us = U} = R, _) -> mnesia:dirty_write( mod_privacy_tmp_table, R#privacy{us = {U, Host}}) end, ok, privacy) end, mnesia:transaction(F1), mnesia:clear_table(privacy), F2 = fun() -> mnesia:write_lock_table(privacy), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, mod_privacy_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(mod_privacy_tmp_table); _ -> ?INFO_MSG("Recreating privacy table", []), mnesia:transform_table(privacy, ignore, Fields) end. ejabberd-2.1.11/src/odbc/0000775000000000000000000000000012240452476011726 5ustar ejabberd-2.1.11/src/odbc/ejabberd_odbc_sup.erl0000664000000000000000000000701112240230175016033 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_odbc_sup.erl %%% Author : Alexey Shchepin %%% Purpose : ODBC connections supervisor %%% Created : 22 Dec 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_odbc_sup). -author('alexey@process-one.net'). %% API -export([start_link/1, init/1, add_pid/2, remove_pid/2, get_pids/1, get_random_pid/1 ]). -include("ejabberd.hrl"). -define(DEFAULT_POOL_SIZE, 10). -define(DEFAULT_ODBC_START_INTERVAL, 30). % 30 seconds % time to wait for the supervisor to start its child before returning % a timeout error to the request -define(CONNECT_TIMEOUT, 500). % milliseconds -record(sql_pool, {host, pid}). start_link(Host) -> mnesia:create_table(sql_pool, [{ram_copies, [node()]}, {type, bag}, {local_content, true}, {attributes, record_info(fields, sql_pool)}]), mnesia:add_table_copy(sql_pool, node(), ram_copies), F = fun() -> mnesia:delete({sql_pool, Host}) end, mnesia:ets(F), supervisor:start_link({local, gen_mod:get_module_proc(Host, ?MODULE)}, ?MODULE, [Host]). init([Host]) -> PoolSize = case ejabberd_config:get_local_option({odbc_pool_size, Host}) of I when is_integer(I) -> I; undefined -> ?DEFAULT_POOL_SIZE; Other -> ?ERROR_MSG("Wrong odbc_pool_size definition '~p' " "for host ~p, default to ~p~n", [Other, Host, ?DEFAULT_POOL_SIZE]), ?DEFAULT_POOL_SIZE end, StartInterval = case ejabberd_config:get_local_option({odbc_start_interval, Host}) of Interval when is_integer(Interval) -> Interval; undefined -> ?DEFAULT_ODBC_START_INTERVAL; _Other2 -> ?ERROR_MSG("Wrong odbc_start_interval " "definition '~p' for host ~p, " "defaulting to ~p~n", [_Other2, Host, ?DEFAULT_ODBC_START_INTERVAL]), ?DEFAULT_ODBC_START_INTERVAL end, {ok, {{one_for_one, PoolSize*10, 1}, lists:map( fun(I) -> {I, {ejabberd_odbc, start_link, [Host, StartInterval*1000]}, transient, 2000, worker, [?MODULE]} end, lists:seq(1, PoolSize))}}. get_pids(Host) -> Rs = mnesia:dirty_read(sql_pool, Host), [R#sql_pool.pid || R <- Rs]. get_random_pid(Host) -> Pids = get_pids(Host), lists:nth(erlang:phash(now(), length(Pids)), Pids). add_pid(Host, Pid) -> F = fun() -> mnesia:write( #sql_pool{host = Host, pid = Pid}) end, mnesia:ets(F). remove_pid(Host, Pid) -> F = fun() -> mnesia:delete_object( #sql_pool{host = Host, pid = Pid}) end, mnesia:ets(F). ejabberd-2.1.11/src/odbc/mssql2000.sql0000664000000000000000000010314112240230175014076 0ustar /* * ejabberd, Copyright (C) 2002-2012 ProcessOne * * 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., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * */ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO exec sp_dboption N'ejabberd', N'autoclose', N'false' GO exec sp_dboption N'ejabberd', N'bulkcopy', N'true' GO exec sp_dboption N'ejabberd', N'trunc. log', N'false' GO exec sp_dboption N'ejabberd', N'torn page detection', N'true' GO exec sp_dboption N'ejabberd', N'read only', N'false' GO exec sp_dboption N'ejabberd', N'dbo use', N'false' GO exec sp_dboption N'ejabberd', N'single', N'false' GO exec sp_dboption N'ejabberd', N'autoshrink', N'false' GO exec sp_dboption N'ejabberd', N'ANSI null default', N'false' GO exec sp_dboption N'ejabberd', N'recursive triggers', N'false' GO exec sp_dboption N'ejabberd', N'ANSI nulls', N'false' GO exec sp_dboption N'ejabberd', N'concat null yields null', N'false' GO exec sp_dboption N'ejabberd', N'cursor close on commit', N'false' GO exec sp_dboption N'ejabberd', N'default to local cursor', N'false' GO exec sp_dboption N'ejabberd', N'quoted identifier', N'false' GO exec sp_dboption N'ejabberd', N'ANSI warnings', N'false' GO exec sp_dboption N'ejabberd', N'auto create statistics', N'true' GO exec sp_dboption N'ejabberd', N'auto update statistics', N'true' GO use [ejabberd] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[last]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[last] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[rostergroups]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[rostergroups] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[rosterusers]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[rosterusers] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[spool]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[spool] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[users]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[users] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[vcard]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[vcard] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[private_storage]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[private_storage] GO CREATE TABLE [dbo].[last] ( [username] [varchar] (250) NOT NULL , [seconds] [varchar] (50) NOT NULL , [state] [varchar] (100) NOT NULL , ) ON [PRIMARY] GO CREATE TABLE [dbo].[rostergroups] ( [username] [varchar] (250) NOT NULL , [jid] [varchar] (250) NOT NULL , [grp] [varchar] (100) NOT NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[rosterusers] ( [username] [varchar] (250) NOT NULL , [jid] [varchar] (250) NOT NULL , [nick] [varchar] (50) NOT NULL , [subscription] [char] (1) NOT NULL , [ask] [char] (1) NOT NULL , [askmessage] [varchar] (250) NOT NULL , [server] [char] (1) NOT NULL , [subscribe] [varchar] (200) NULL , [type] [varchar] (50) NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[spool] ( [id] [numeric](19, 0) IDENTITY (1, 1) NOT NULL , [username] [varchar] (250) NOT NULL , [xml] [text] NOT NULL , [notifyprocessed] [bit] NULL , [created] [datetime] NULL , ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO CREATE TABLE [dbo].[users] ( [username] [varchar] (250) NOT NULL , [password] [varchar] (50) NOT NULL , [created] [datetime] NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[vcard] ( [username] [varchar] (250) NOT NULL , [full_name] [varchar] (250) NULL , [first_name] [varchar] (50) NULL , [last_name] [varchar] (50) NULL , [nick_name] [varchar] (50) NULL , [url] [varchar] (1024) NULL , [address1] [varchar] (50) NULL , [address2] [varchar] (50) NULL , [locality] [varchar] (50) NULL , [region] [varchar] (50) NULL , [pcode] [varchar] (50) NULL , [country] [varchar] (50) NULL , [telephone] [varchar] (50) NULL , [email] [varchar] (250) NULL , [orgname] [varchar] (50) NULL , [orgunit] [varchar] (50) NULL , [title] [varchar] (50) NULL , [role] [varchar] (50) NULL , [b_day] [datetime] NULL , [descr] [varchar] (500) NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[private_storage] ( [username] [varchar] (250) NOT NULL , [namespace] [varchar] (250) NOT NULL , [data] [text] NOT NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[privacy_default_list] ( [username] [varchar] (250) NOT NULL, [name] [varchar] (250) NOT NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[privacy_list] ( [username] [varchar] (250) NOT NULL, [name] [varchar] (250) NOT NULL, id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE ) ON [PRIMARY] GO CREATE TABLE [dbo].[privacy_list_data] ( [id] [bigint] NOT NULL, [t] [character] (1) NOT NULL, [value] [text] NOT NULL, [action] [character] (1) NOT NULL, [ord] [NUMERIC] NOT NULL, [match_all] [boolean] NOT NULL, [match_iq] [boolean] NOT NULL, [match_message] [boolean] NOT NULL, [match_presence_in] [boolean] NOT NULL, [match_presence_out] [boolean] NOT NULL ) ON [PRIMARY] GO /* Not tested on mssql */ CREATE TABLE [dbo].[roster_version] ( [username] [varchar] (250) NOT NULL , [version] [varchar] (64) NOT NULL ) ON [PRIMARY] GO /* Constraints to add: - id in privacy_list is a SERIAL autogenerated number - id in privacy_list_data must exist in the table privacy_list */ ALTER TABLE [dbo].[last] WITH NOCHECK ADD CONSTRAINT [PK_last] PRIMARY KEY CLUSTERED ( [username] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO ALTER TABLE [dbo].[rostergroups] WITH NOCHECK ADD CONSTRAINT [PK_rostergroups] PRIMARY KEY CLUSTERED ( [username], [jid], [grp] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO ALTER TABLE [dbo].[spool] WITH NOCHECK ADD CONSTRAINT [PK_spool] PRIMARY KEY CLUSTERED ( [username], [id] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO ALTER TABLE [dbo].[users] WITH NOCHECK ADD CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED ( [username] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO ALTER TABLE [dbo].[roster_version] WITH NOCHECK ADD CONSTRAINT [PK_roster_version] PRIMARY KEY CLUSTERED ( [username] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO ALTER TABLE [dbo].[vcard] WITH NOCHECK ADD CONSTRAINT [PK_vcard] PRIMARY KEY CLUSTERED ( [username] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE CLUSTERED INDEX [IX_rosterusers_user] ON [dbo].[rosterusers]([username]) WITH FILLFACTOR = 90 ON [PRIMARY] GO ALTER TABLE [dbo].[last] WITH NOCHECK ADD CONSTRAINT [DF_last_updated] DEFAULT (getdate()) FOR [Modify_Date] GO ALTER TABLE [dbo].[spool] WITH NOCHECK ADD CONSTRAINT [DF_spool_notifyprocessed] DEFAULT (0) FOR [notifyprocessed], CONSTRAINT [DF_spool_created] DEFAULT (getdate()) FOR [created], CONSTRAINT [DF_spool_MustDelete] DEFAULT (0) FOR [MustDelete] GO ALTER TABLE [dbo].[users] WITH NOCHECK ADD CONSTRAINT [DF_users_created] DEFAULT (getdate()) FOR [created] GO ALTER TABLE [dbo].[privacy_default_list] WITH NOCHECK ADD CONSTRAINT [PK_privacy_defaut_list] PRIMARY KEY CLUSTERED ( [username] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_rostergroups_jid] ON [dbo].[rostergroups]([jid]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_rostergroups_user] ON [dbo].[rostergroups]([username]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_rosterusers_jid] ON [dbo].[rosterusers]([username], [jid]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_spool_user] ON [dbo].[spool]([username]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_spool_process] ON [dbo].[spool]([created], [notifyprocessed]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IK_Spool_Del] ON [dbo].[spool]([MustDelete]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IK_Spool_Created] ON [dbo].[spool]([created]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_private_user] ON [dbo].[private_storage]([username]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_private_user_ns] ON [dbo].[private_storage]([username], [namespace]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_privacy_list_username] ON [dbo].[privacy_list]([username]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_privacy_list_username_name] ON [dbo].[privacy_list]([username], [name]) WITH FILLFACTOR = 90 ON [PRIMARY] GO /*********************************************************/ /** These store procedures are for use with ejabberd **/ /** 1.1 and Microsoft Sql Server 2000 **/ /** **/ /** The stored procedures reduce the need to sql **/ /** compilation of the database and also allow for also **/ /** provide each of database integration. The stored **/ /** procedure have been optimized to increase database **/ /** performance and a reduction of 80% in CPU was **/ /** achieved over the use of standard sql. **/ /*********************************************************/ /****** Object: StoredProcedure [dbo].[add_roster] ******/ /** Add or update user entries in the roster **/ /*********************************************************/ CREATE PROCEDURE [dbo].[add_roster] @Username varchar(250), @JID varchar(250), @Nick varchar(50), @Subscription char(1), @Ask char(1), @AskMessage varchar(250), @Server char(1), @Subscribe varchar(200), @Type varchar(50), @Grp varchar(100) AS BEGIN BEGIN TRANSACTION --- Update Roster if user exist else add roster item IF EXISTS (SELECT username FROM rosterusers WITH (NOLOCK) WHERE rosterusers.username=@Username AND rosterusers.jid=@JID) BEGIN UPDATE rosterusers SET rosterusers.username=@Username, rosterusers.jid=@JID, rosterusers.nick=@Nick, rosterusers.subscription=@Subscription, rosterusers.ask=@Ask, rosterusers.askmessage=@AskMessage, rosterusers.server=@Server, rosterusers.subscribe=@Subscribe, rosterusers.type=@Type WHERE (rosterusers.username=@Username) AND (rosterusers.jid=@JID); END ELSE BEGIN INSERT INTO rosterusers ( rosterusers.username, rosterusers.jid, rosterusers.nick, rosterusers.subscription, rosterusers.ask, rosterusers.askmessage, rosterusers.server, rosterusers.subscribe, rosterusers.type ) VALUES ( @Username, @JID, @Nick, @Subscription, @Ask, @AskMessage, @Server, @Subscribe, @Type ); END --- Update Roster Groups if exist else add group entry IF NOT EXISTS (SELECT username FROM rostergroups WITH (NOLOCK) WHERE rostergroups.username=@Username AND rostergroups.jid=@JID AND rostergroups.grp=@Grp) BEGIN INSERT INTO rostergroups ( rostergroups.username, rostergroups.jid, rostergroups.grp ) VALUES ( @Username, @JID, @Grp ); END COMMIT END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[add_roster_group] ******/ /** Add or update user group entries in the roster groups **/ /***************************************************************/ CREATE PROCEDURE [dbo].[add_roster_group] @Username varchar(250), @JID varchar(250), @Grp varchar(100) AS BEGIN --- Update Roster Groups if exist else add group IF NOT EXISTS (SELECT username FROM rostergroups WHERE rostergroups.username=@Username AND rostergroups.jid=@JID AND rostergroups.grp=@Grp) BEGIN INSERT INTO rostergroups ( rostergroups.username, rostergroups.jid, rostergroups.grp ) VALUES ( @Username, @JID, @Grp ) END END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[add_roster_user] ******/ /** Add or update user entries in the roster **/ /***************************************************************/ CREATE PROCEDURE [dbo].[add_roster_user] @Username varchar(250), @JID varchar(250), @Nick varchar(50), @Subscription char(1), @Ask char(1), @AskMessage varchar(250), @Server char(1), @Subscribe varchar(200), @Type varchar(50), @Grp varchar(100) = Null AS BEGIN BEGIN TRANSACTION --- Update Roster Users if exist of add new user IF EXISTS (SELECT username FROM rosterusers WHERE rosterusers.username=@Username AND rosterusers.jid=@JID) BEGIN UPDATE rosterusers SET rosterusers.username=@Username, rosterusers.jid=@JID, rosterusers.nick=@Nick, rosterusers.subscription=@Subscription, rosterusers.ask=@Ask, rosterusers.askmessage=@AskMessage, rosterusers.server=@Server, rosterusers.subscribe=@Subscribe, rosterusers.type=@Type WHERE (rosterusers.username=@Username) AND (rosterusers.jid=@JID); END ELSE BEGIN INSERT INTO rosterusers ( rosterusers.username, rosterusers.jid, rosterusers.nick, rosterusers.subscription, rosterusers.ask, rosterusers.askmessage, rosterusers.server, rosterusers.subscribe, rosterusers.type ) VALUES ( @Username, @JID, @Nick, @Subscription, @Ask, @AskMessage, @Server, @Subscribe, @Type ); END --- Update Roster Group if exist of add new group IF @Grp IS NOT NULL EXECUTE [dbo].[add_roster_group] @Username, @JID, @Grp COMMIT END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[del_roster_groups] ******/ /** Remove user group entries from the roster groups table **/ /***************************************************************/ CREATE PROCEDURE [dbo].[del_roster_groups] @Username varchar(250), @JID varchar(250) AS BEGIN DELETE FROM rostergroups WITH (ROWLOCK) WHERE (rostergroups.username = @Username) AND (rostergroups.jid = @JID); END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[add_spool] ******/ /** Add a entry to the spool table **/ /***************************************************************/ CREATE PROCEDURE [dbo].[add_spool] @Username varchar(250), @XML varchar(8000) AS BEGIN INSERT INTO spool ( spool.username, spool.xml ) VALUES ( @Username, @XML ) END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[add_user] ******/ /** Add or update user entries to jabber **/ /***************************************************************/ CREATE PROCEDURE [dbo].[add_user] @Username varchar(200), @Password varchar(50) AS BEGIN INSERT INTO users ( [username], [password] ) VALUES ( @Username, @Password ); END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[set_password] **/ /** Update users password **/ /******************************************************************/ CREATE PROCEDURE [dbo].[set_password] @Username varchar(200), @Password varchar(50) AS BEGIN IF EXISTS (SELECT username FROM users WITH (NOLOCK) WHERE username=@Username) BEGIN UPDATE users SET username=@Username, password=@Password WHERE username=@Username; END ELSE BEGIN INSERT INTO users (username, password) VALUES (@Username, @Password); END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_password] **/ /** Retrive the user password **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_password] @Username varchar(200) AS BEGIN SELECT users.password as password FROM users WITH (NOLOCK) WHERE username=@Username; END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[set_roster_version] **/ /** Update users roster_version **/ /******************************************************************/ CREATE PROCEDURE [dbo].[set_roster_version] @Username varchar(200), @Version varchar(50) AS BEGIN IF EXISTS (SELECT username FROM roster_version WITH (NOLOCK) WHERE username=@Username) BEGIN UPDATE roster_version SET username=@Username, version=@Version WHERE username=@Username; END ELSE BEGIN INSERT INTO roster_version (username, version) VALUES (@Username, @Version); END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_roster_version] **/ /** Retrive the user roster_version **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_roster_version] @Username varchar(200) AS BEGIN SELECT roster_version.version as version FROM roster_version WITH (NOLOCK) WHERE username=@Username; END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[clean_spool_msg] ******/ /** Delete messages older that 3 days from spool **/ /***************************************************************/ CREATE PROCEDURE [dbo].[clean_spool_msg] AS DECLARE @dt datetime, @myRowCount int BEGIN -- Delete small amounts because if locks the database table SET ROWCOUNT 500 SET @myRowCount = 1 WHILE (@myRowCount) > 0 BEGIN BEGIN TRANSACTION SELECT @dt = DATEADD(d, -3, GETDATE()) DELETE FROM spool WITH (ROWLOCK) WHERE (MustDelete=1) OR (Created < @dt); SET @myRowCount = @@RowCount COMMIT END END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[del_last] ******/ /** Delete an entry from the last table **/ /***************************************************************/ CREATE PROCEDURE [dbo].[del_last] @Username varchar(250) AS BEGIN DELETE FROM [last] WITH (ROWLOCK) WHERE [last].username=@Username; END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[del_roster] ******/ /** Delete an entry from the roster **/ /***************************************************************/ CREATE PROCEDURE [dbo].[del_roster] @Username varchar(250), @JID varchar(250) AS BEGIN BEGIN TRANSACTION DELETE FROM rosterusers WITH (ROWLOCK) WHERE (rosterusers.username = @Username) AND (rosterusers.jid = @JID); DELETE FROM rostergroups WITH (ROWLOCK) WHERE (rostergroups.username = @Username) AND (rostergroups.jid = @JID); COMMIT END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[del_spool_msg] ******/ /** Delete an entry from the spool table **/ /***************************************************************/ CREATE PROCEDURE [dbo].[del_spool_msg] @Username varchar(250) AS BEGIN DELETE FROM spool WITH (ROWLOCK) WHERE spool.username=@Username; END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[del_user] ******/ /** Delete an entry from the user table **/ /***************************************************************/ CREATE PROCEDURE [dbo].[del_user] @Username varchar(200) AS BEGIN DELETE FROM users WITH (ROWLOCK) WHERE username=@Username; END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[del_user_return_password]**/ /** Delete an entry from the user table and return user password **/ /******************************************************************/ CREATE PROCEDURE [dbo].[del_user_return_password] @Username varchar(250) AS DECLARE @Pwd varchar(50) BEGIN EXECUTE @Pwd = dbo.get_password @Username DELETE FROM users WITH (ROWLOCK) WHERE username=@Username SELECT @Pwd; END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[del_user_roster] **/ /** Delete the users roster **/ /******************************************************************/ CREATE PROCEDURE [dbo].[del_user_roster] @Username varchar(250) AS BEGIN BEGIN TRANSACTION DELETE FROM rosterusers WITH (ROWLOCK) WHERE rosterusers.username = @Username; DELETE FROM rostergroups WITH (ROWLOCK) WHERE rostergroups.username = @Username; COMMIT END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_and_del_spool_msg] **/ /** Fetch and delete the users offline messages **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_and_del_spool_msg] @Username varchar(250) AS DECLARE @vSpool table( username varchar(1), xml varchar(1)) BEGIN IF EXISTS (SELECT username FROM spool with (nolock) WHERE spool.username=@Username) BEGIN SELECT spool.username AS username, spool.xml AS xml FROM spool WITH (NOLOCK) WHERE spool.username=@Username; DELETE spool WITH (ROWLOCK) WHERE spool.username=@Username END ELSE BEGIN SELECT * FROM @vSpool; END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_last] **/ /** Retrive the last user login **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_last] @Username varchar(250) AS BEGIN SELECT last.seconds AS seconds, last.state AS state FROM last WITH (NOLOCK) WHERE last.username=@Username; END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_roster] **/ /** Retrive the user roster **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_roster] @Username varchar(250) AS DECLARE @vRosterusers table( username varchar(1), jid varchar(1), nick varchar(1), subscription varchar(1), ask varchar(1), askmessage varchar(1), server varchar(1), subscribe varchar(1), type varchar(1)) BEGIN IF EXISTS (SELECT username FROM rosterusers with (nolock) WHERE rosterusers.username = @Username) BEGIN SELECT rosterusers.username AS username, rosterusers.jid AS jid, rosterusers.nick AS nick, rosterusers.subscription AS subscription, rosterusers.ask AS ask, rosterusers.askmessage AS askmessage, rosterusers.server AS server, rosterusers.subscribe AS subscribe, rosterusers.type AS type FROM rosterusers WITH (NOLOCK) WHERE rosterusers.username = @Username; END ELSE BEGIN SELECT * FROM @vRosterusers END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_roster_by_jid] **/ /** Retrive the user roster via JID **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_roster_by_jid] @Username varchar(200), @JID varchar(250) AS DECLARE @vRosterusers table( username varchar(1), jid varchar(1), nick varchar(1), subscription varchar(1), ask varchar(1), askmessage varchar(1), server varchar(1), subscribe varchar(1), type varchar(1)) BEGIN IF EXISTS (SELECT username FROM rosterusers with (nolock) WHERE (rosterusers.username = @Username) AND (rosterusers.jid = @JID)) BEGIN SELECT rosterusers.username AS username, rosterusers.jid AS jid, rosterusers.nick AS nick, rosterusers.subscription AS subscription, rosterusers.ask AS ask, rosterusers.askmessage AS askmessage, rosterusers.server AS server, rosterusers.subscribe AS subscribe, rosterusers.type AS type FROM rosterusers WITH (NOLOCK) WHERE (rosterusers.username = @Username) AND (rosterusers.jid = @JID); END ELSE BEGIN SELECT * FROM @vRosterusers END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_roster_jid_groups] **/ /** Retrieve the user roster groups **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_roster_jid_groups] @Username varchar(200) AS DECLARE @vrostergroups table( jid varchar(1), grp varchar(1)) BEGIN IF EXISTS (SELECT username FROM rostergroups with (nolock) WHERE rostergroups.username = @Username) BEGIN SELECT rostergroups.jid AS jid, rostergroups.grp AS grp FROM rostergroups WITH (NOLOCK) WHERE rostergroups.username = @Username; END ELSE BEGIN SELECT * FROM @vrostergroups END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_roster_groups] **/ /** Retrive the user roster groups **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_roster_groups] @Username varchar(200), @JID varchar(250) AS DECLARE @vrostergroups table( grp varchar(1)) BEGIN IF EXISTS (SELECT username FROM rostergroups with (nolock) WHERE rostergroups.username = @Username) BEGIN SELECT rostergroups.grp AS grp FROM rostergroups WITH (NOLOCK) WHERE (rostergroups.username = @Username) AND (rostergroups.jid = @JID); END ELSE BEGIN SELECT * FROM @vrostergroups END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_rostergroup_by_jid] **/ /** Retrive the user roster groups via JID **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_rostergroup_by_jid] @Username varchar(250), @JID varchar(250) AS DECLARE @vrostergroups table(grp varchar(1)) BEGIN IF EXISTS (SELECT username FROM rostergroups with (nolock) WHERE rostergroups.username=@Username AND rostergroups.jid=@JID) BEGIN SELECT rostergroups.grp AS grp FROM rostergroups WITH (NOLOCK) WHERE rostergroups.username=@Username AND rostergroups.jid=@JID; END ELSE BEGIN SELECT * FROM @vrostergroups END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_subscription] **/ /** Retrive the user subscription requests **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_subscription] @Username varchar(250), @JID varchar(250) AS DECLARE @vrosterusers table( subscription varchar(1)) BEGIN IF EXISTS (SELECT username FROM rosterusers with (nolock) WHERE rosterusers.username=@Username AND rosterusers.jid=@JID) BEGIN SELECT rosterusers.subscription AS subscription FROM rosterusers WITH (NOLOCK) WHERE rosterusers.username=@Username AND rosterusers.jid=@JID; END ELSE BEGIN SELECT * FROM @vrosterusers END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[list_users] **/ /** Retrieve a list of all users **/ /******************************************************************/ CREATE PROCEDURE [dbo].[list_users] AS BEGIN SELECT users.username AS username FROM users WITH (NOLOCK); END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[set_last] **/ /** Update users last login status **/ /******************************************************************/ CREATE PROCEDURE [dbo].[set_last] @Username varchar(250), @Seconds varchar(50), @State varchar(100) AS BEGIN IF EXISTS (SELECT username FROM [last] WITH (NOLOCK) WHERE username=@Username) BEGIN UPDATE [last] SET [last].username = @Username, [last].seconds = @Seconds, [last].state = @State WHERE last.username=@Username; END ELSE BEGIN INSERT INTO [last] ( [last].username, [last].seconds, [last].state ) VALUES ( @Username, @Seconds, @State ) END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[set_private_data] **/ /** store user private data by namespace **/ /******************************************************************/ CREATE PROCEDURE [dbo].[set_private_data] @Username varchar(250), @Namespace varchar(250), @Data varchar(8000) AS BEGIN IF EXISTS (SELECT username FROM private_storage with (nolock) WHERE private_storage.username = @Username AND private_storage.namespace = @Namespace) BEGIN UPDATE [private_storage] SET [private_storage].username = @Username, [private_storage].namespace = @Namespace, [private_storage].data = @Data WHERE private_storage.username = @Username AND private_storage.namespace = @Namespace; END ELSE BEGIN INSERT INTO [private_storage] ( [private_storage].username, [private_storage].namespace, [private_storage].data ) VALUES ( @Username, @Namespace, @Data ) END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_private_data] **/ /** Retrieve user private data by namespace **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_private_data] @Username varchar(250), @Namespace varchar(250) AS BEGIN SELECT private_storage.data AS data FROM private_storage WITH (NOLOCK) WHERE username=@Username and namespace=@Namespace; END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[del_user_storage] ******/ /** Delete private storage area for a given user **/ /***************************************************************/ CREATE PROCEDURE [dbo].[del_user_storage] @Username varchar(250) AS BEGIN DELETE FROM [private_storage] WITH (ROWLOCK) WHERE [private_storage].username=@Username; END GO ejabberd-2.1.11/src/odbc/Makefile.win320000664000000000000000000000076712240230175014327 0ustar include ..\Makefile.inc EFLAGS = -I .. -pz .. OUTDIR = .. BEAMS = ..\ejabberd_odbc.beam ..\ejabberd_odbc_sup.beam ..\odbc_queries.beam ALL : $(BEAMS) CLEAN : -@erase $(BEAMS) $(OUTDIR)\ejabberd_odbc.beam : ejabberd_odbc.erl erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_odbc.erl $(OUTDIR)\ejabberd_odbc_sup.beam : ejabberd_odbc_sup.erl erlc -W $(EFLAGS) -o $(OUTDIR) ejabberd_odbc_sup.erl $(OUTDIR)\odbc_queries.beam : odbc_queries.erl erlc -W $(EFLAGS) -o $(OUTDIR) -D$(DBTYPE) odbc_queries.erl ejabberd-2.1.11/src/odbc/odbc_queries.erl0000664000000000000000000007144112240230175015073 0ustar %%%---------------------------------------------------------------------- %%% File : odbc_queries.erl %%% Author : Mickael Remond %%% Purpose : ODBC queries dependind on back-end %%% Created : by Mickael Remond %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(odbc_queries). -author("mremond@process-one.net"). -export([get_db_type/0, update_t/4, sql_transaction/2, get_last/2, set_last_t/4, del_last/2, get_password/2, set_password_t/3, add_user/3, del_user/2, del_user_return_password/3, list_users/1, list_users/2, users_number/1, users_number/2, add_spool_sql/2, add_spool/2, get_and_del_spool_msg_t/2, del_spool_msg/2, get_roster/2, get_roster_jid_groups/2, get_roster_groups/3, del_user_roster_t/2, get_roster_by_jid/3, get_rostergroup_by_jid/3, del_roster/3, del_roster_sql/2, update_roster/5, update_roster_sql/4, roster_subscribe/4, get_subscription/3, set_private_data/4, set_private_data_sql/3, get_private_data/3, del_user_private_storage/2, get_default_privacy_list/2, get_default_privacy_list_t/1, get_privacy_list_names/2, get_privacy_list_names_t/1, get_privacy_list_id/3, get_privacy_list_id_t/2, get_privacy_list_data/3, get_privacy_list_data_by_id/2, get_privacy_list_data_by_id_t/1, set_default_privacy_list/2, unset_default_privacy_list/2, remove_privacy_list/2, add_privacy_list/2, set_privacy_list/2, del_privacy_lists/3, set_vcard/26, get_vcard/2, escape/1, count_records_where/3, get_roster_version/2, set_roster_version/2]). %% We have only two compile time options for db queries: %-define(generic, true). %-define(mssql, true). -ifndef(mssql). -undef(generic). -define(generic, true). -endif. -include("ejabberd.hrl"). %% Almost a copy of string:join/2. %% We use this version because string:join/2 is relatively %% new function (introduced in R12B-0). join([], _Sep) -> []; join([H|T], Sep) -> [H, [[Sep, X] || X <- T]]. %% ----------------- %% Generic queries -ifdef(generic). get_db_type() -> generic. %% Safe atomic update. update_t(Table, Fields, Vals, Where) -> UPairs = lists:zipwith(fun(A, B) -> A ++ "='" ++ B ++ "'" end, Fields, Vals), case ejabberd_odbc:sql_query_t( ["update ", Table, " set ", join(UPairs, ", "), " where ", Where, ";"]) of {updated, 1} -> ok; _ -> ejabberd_odbc:sql_query_t( ["insert into ", Table, "(", join(Fields, ", "), ") values ('", join(Vals, "', '"), "');"]) end. update(LServer, Table, Fields, Vals, Where) -> UPairs = lists:zipwith(fun(A, B) -> A ++ "='" ++ B ++ "'" end, Fields, Vals), case ejabberd_odbc:sql_query( LServer, ["update ", Table, " set ", join(UPairs, ", "), " where ", Where, ";"]) of {updated, 1} -> ok; _ -> ejabberd_odbc:sql_query( LServer, ["insert into ", Table, "(", join(Fields, ", "), ") values ('", join(Vals, "', '"), "');"]) end. %% F can be either a fun or a list of queries %% TODO: We should probably move the list of queries transaction %% wrapper from the ejabberd_odbc module to this one (odbc_queries) sql_transaction(LServer, F) -> ejabberd_odbc:sql_transaction(LServer, F). get_last(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["select seconds, state from last " "where username='", Username, "'"]). set_last_t(LServer, Username, Seconds, State) -> update(LServer, "last", ["username", "seconds", "state"], [Username, Seconds, State], ["username='", Username, "'"]). del_last(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["delete from last where username='", Username, "'"]). get_password(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["select password from users " "where username='", Username, "';"]). set_password_t(LServer, Username, Pass) -> ejabberd_odbc:sql_transaction( LServer, fun() -> update_t("users", ["username", "password"], [Username, Pass], ["username='", Username ,"'"]) end). add_user(LServer, Username, Pass) -> ejabberd_odbc:sql_query( LServer, ["insert into users(username, password) " "values ('", Username, "', '", Pass, "');"]). del_user(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["delete from users where username='", Username ,"';"]). del_user_return_password(_LServer, Username, Pass) -> P = ejabberd_odbc:sql_query_t( ["select password from users where username='", Username, "';"]), ejabberd_odbc:sql_query_t(["delete from users " "where username='", Username, "' and password='", Pass, "';"]), P. list_users(LServer) -> ejabberd_odbc:sql_query( LServer, "select username from users"). list_users(LServer, [{from, Start}, {to, End}]) when is_integer(Start) and is_integer(End) -> list_users(LServer, [{limit, End-Start+1}, {offset, Start-1}]); list_users(LServer, [{prefix, Prefix}, {from, Start}, {to, End}]) when is_list(Prefix) and is_integer(Start) and is_integer(End) -> list_users(LServer, [{prefix, Prefix}, {limit, End-Start+1}, {offset, Start-1}]); list_users(LServer, [{limit, Limit}, {offset, Offset}]) when is_integer(Limit) and is_integer(Offset) -> ejabberd_odbc:sql_query( LServer, io_lib:format( "select username from users " ++ "order by username " ++ "limit ~w offset ~w", [Limit, Offset])); list_users(LServer, [{prefix, Prefix}, {limit, Limit}, {offset, Offset}]) when is_list(Prefix) and is_integer(Limit) and is_integer(Offset) -> ejabberd_odbc:sql_query( LServer, io_lib:format("select username from users " ++ "where username like '~s%' " ++ "order by username " ++ "limit ~w offset ~w ", [Prefix, Limit, Offset])). users_number(LServer) -> case element(1, ejabberd_config:get_local_option({odbc_server, LServer})) of pgsql -> case ejabberd_config:get_local_option({pgsql_users_number_estimate, LServer}) of true -> ejabberd_odbc:sql_query( LServer, "select reltuples from pg_class where oid = 'users'::regclass::oid"); _ -> ejabberd_odbc:sql_query( LServer, "select count(*) from users") end; _ -> ejabberd_odbc:sql_query( LServer, "select count(*) from users") end. users_number(LServer, [{prefix, Prefix}]) when is_list(Prefix) -> ejabberd_odbc:sql_query( LServer, io_lib:fwrite("select count(*) from users " ++ %% Warning: Escape prefix at higher level to prevent SQL %% injection. "where username like '~s%'", [Prefix])); users_number(LServer, []) -> users_number(LServer). add_spool_sql(Username, XML) -> ["insert into spool(username, xml) " "values ('", Username, "', '", XML, "');"]. add_spool(LServer, Queries) -> ejabberd_odbc:sql_transaction( LServer, Queries). get_and_del_spool_msg_t(LServer, Username) -> F = fun() -> Result = ejabberd_odbc:sql_query_t( ["select username, xml from spool where username='", Username, "'" " order by seq;"]), ejabberd_odbc:sql_query_t( ["delete from spool where username='", Username, "';"]), Result end, ejabberd_odbc:sql_transaction(LServer,F). del_spool_msg(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["delete from spool where username='", Username, "';"]). get_roster(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["select username, jid, nick, subscription, ask, " "askmessage, server, subscribe, type from rosterusers " "where username='", Username, "'"]). get_roster_jid_groups(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["select jid, grp from rostergroups " "where username='", Username, "'"]). get_roster_groups(_LServer, Username, SJID) -> ejabberd_odbc:sql_query_t( ["select grp from rostergroups " "where username='", Username, "' " "and jid='", SJID, "';"]). del_user_roster_t(LServer, Username) -> ejabberd_odbc:sql_transaction( LServer, fun() -> ejabberd_odbc:sql_query_t( ["delete from rosterusers " " where username='", Username, "';"]), ejabberd_odbc:sql_query_t( ["delete from rostergroups " " where username='", Username, "';"]) end). get_roster_by_jid(_LServer, Username, SJID) -> ejabberd_odbc:sql_query_t( ["select username, jid, nick, subscription, " "ask, askmessage, server, subscribe, type from rosterusers " "where username='", Username, "' " "and jid='", SJID, "';"]). get_rostergroup_by_jid(LServer, Username, SJID) -> ejabberd_odbc:sql_query( LServer, ["select grp from rostergroups " "where username='", Username, "' " "and jid='", SJID, "'"]). del_roster(_LServer, Username, SJID) -> ejabberd_odbc:sql_query_t( ["delete from rosterusers " " where username='", Username, "' " " and jid='", SJID, "';"]), ejabberd_odbc:sql_query_t( ["delete from rostergroups " " where username='", Username, "' " " and jid='", SJID, "';"]). del_roster_sql(Username, SJID) -> [["delete from rosterusers " " where username='", Username, "' " " and jid='", SJID, "';"], ["delete from rostergroups " " where username='", Username, "' " " and jid='", SJID, "';"]]. update_roster(_LServer, Username, SJID, ItemVals, ItemGroups) -> update_t("rosterusers", ["username", "jid", "nick", "subscription", "ask", "askmessage", "server", "subscribe", "type"], ItemVals, ["username='", Username, "' and jid='", SJID, "'"]), ejabberd_odbc:sql_query_t( ["delete from rostergroups " " where username='", Username, "' " " and jid='", SJID, "';"]), lists:foreach(fun(ItemGroup) -> ejabberd_odbc:sql_query_t( ["insert into rostergroups(" " username, jid, grp) " " values ('", join(ItemGroup, "', '"), "');"]) end, ItemGroups). update_roster_sql(Username, SJID, ItemVals, ItemGroups) -> [["delete from rosterusers " " where username='", Username, "' " " and jid='", SJID, "';"], ["insert into rosterusers(" " username, jid, nick, " " subscription, ask, askmessage, " " server, subscribe, type) " " values ('", join(ItemVals, "', '"), "');"], ["delete from rostergroups " " where username='", Username, "' " " and jid='", SJID, "';"]] ++ [["insert into rostergroups(" " username, jid, grp) " " values ('", join(ItemGroup, "', '"), "');"] || ItemGroup <- ItemGroups]. roster_subscribe(_LServer, Username, SJID, ItemVals) -> update_t("rosterusers", ["username", "jid", "nick", "subscription", "ask", "askmessage", "server", "subscribe", "type"], ItemVals, ["username='", Username, "' and jid='", SJID, "'"]). get_subscription(LServer, Username, SJID) -> ejabberd_odbc:sql_query( LServer, ["select subscription from rosterusers " "where username='", Username, "' " "and jid='", SJID, "'"]). set_private_data(_LServer, Username, LXMLNS, SData) -> update_t("private_storage", ["username", "namespace", "data"], [Username, LXMLNS, SData], ["username='", Username, "' and namespace='", LXMLNS, "'"]). set_private_data_sql(Username, LXMLNS, SData) -> [["delete from private_storage " "where username='", Username, "' and " "namespace='", LXMLNS, "';"], ["insert into private_storage(username, namespace, data) " "values ('", Username, "', '", LXMLNS, "', " "'", SData, "');"]]. get_private_data(LServer, Username, LXMLNS) -> ejabberd_odbc:sql_query( LServer, ["select data from private_storage " "where username='", Username, "' and " "namespace='", LXMLNS, "';"]). del_user_private_storage(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["delete from private_storage where username='", Username, "';"]). set_vcard(LServer, LUsername, SBDay, SCTRY, SEMail, SFN, SFamily, SGiven, SLBDay, SLCTRY, SLEMail, SLFN, SLFamily, SLGiven, SLLocality, SLMiddle, SLNickname, SLOrgName, SLOrgUnit, SLocality, SMiddle, SNickname, SOrgName, SOrgUnit, SVCARD, Username) -> ejabberd_odbc:sql_transaction( LServer, fun() -> update_t("vcard", ["username", "vcard"], [LUsername, SVCARD], ["username='", LUsername, "'"]), update_t("vcard_search", ["username", "lusername", "fn", "lfn", "family", "lfamily", "given", "lgiven", "middle", "lmiddle", "nickname", "lnickname", "bday", "lbday", "ctry", "lctry", "locality", "llocality", "email", "lemail", "orgname", "lorgname", "orgunit", "lorgunit"], [Username, LUsername, SFN, SLFN, SFamily, SLFamily, SGiven, SLGiven, SMiddle, SLMiddle, SNickname, SLNickname, SBDay, SLBDay, SCTRY, SLCTRY, SLocality, SLLocality, SEMail, SLEMail, SOrgName, SLOrgName, SOrgUnit, SLOrgUnit], ["lusername='", LUsername, "'"]) end). get_vcard(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["select vcard from vcard " "where username='", Username, "';"]). get_default_privacy_list(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["select name from privacy_default_list " "where username='", Username, "';"]). get_default_privacy_list_t(Username) -> ejabberd_odbc:sql_query_t( ["select name from privacy_default_list " "where username='", Username, "';"]). get_privacy_list_names(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["select name from privacy_list " "where username='", Username, "';"]). get_privacy_list_names_t(Username) -> ejabberd_odbc:sql_query_t( ["select name from privacy_list " "where username='", Username, "';"]). get_privacy_list_id(LServer, Username, SName) -> ejabberd_odbc:sql_query( LServer, ["select id from privacy_list " "where username='", Username, "' and name='", SName, "';"]). get_privacy_list_id_t(Username, SName) -> ejabberd_odbc:sql_query_t( ["select id from privacy_list " "where username='", Username, "' and name='", SName, "';"]). get_privacy_list_data(LServer, Username, SName) -> ejabberd_odbc:sql_query( LServer, ["select t, value, action, ord, match_all, match_iq, " "match_message, match_presence_in, match_presence_out " "from privacy_list_data " "where id = (select id from privacy_list where " " username='", Username, "' and name='", SName, "') " "order by ord;"]). get_privacy_list_data_by_id(LServer, ID) -> ejabberd_odbc:sql_query( LServer, ["select t, value, action, ord, match_all, match_iq, " "match_message, match_presence_in, match_presence_out " "from privacy_list_data " "where id='", ID, "' order by ord;"]). get_privacy_list_data_by_id_t(ID) -> ejabberd_odbc:sql_query_t( ["select t, value, action, ord, match_all, match_iq, " "match_message, match_presence_in, match_presence_out " "from privacy_list_data " "where id='", ID, "' order by ord;"]). set_default_privacy_list(Username, SName) -> update_t("privacy_default_list", ["username", "name"], [Username, SName], ["username='", Username, "'"]). unset_default_privacy_list(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["delete from privacy_default_list " " where username='", Username, "';"]). remove_privacy_list(Username, SName) -> ejabberd_odbc:sql_query_t( ["delete from privacy_list " "where username='", Username, "' and name='", SName, "';"]). add_privacy_list(Username, SName) -> ejabberd_odbc:sql_query_t( ["insert into privacy_list(username, name) " "values ('", Username, "', '", SName, "');"]). set_privacy_list(ID, RItems) -> ejabberd_odbc:sql_query_t( ["delete from privacy_list_data " "where id='", ID, "';"]), lists:foreach(fun(Items) -> ejabberd_odbc:sql_query_t( ["insert into privacy_list_data(" "id, t, value, action, ord, match_all, match_iq, " "match_message, match_presence_in, " "match_presence_out " ") " "values ('", ID, "', '", join(Items, "', '"), "');"]) end, RItems). del_privacy_lists(LServer, Server, Username) -> ejabberd_odbc:sql_query( LServer, ["delete from privacy_list where username='", Username, "';"]), ejabberd_odbc:sql_query( LServer, ["delete from privacy_list_data where value='", Username++"@"++Server, "';"]), ejabberd_odbc:sql_query( LServer, ["delete from privacy_default_list where username='", Username, "';"]). %% Characters to escape escape($\0) -> "\\0"; escape($\n) -> "\\n"; escape($\t) -> "\\t"; escape($\b) -> "\\b"; escape($\r) -> "\\r"; escape($') -> "''"; escape($") -> "\\\""; escape($\\) -> "\\\\"; escape(C) -> C. %% Count number of records in a table given a where clause count_records_where(LServer, Table, WhereClause) -> ejabberd_odbc:sql_query( LServer, ["select count(*) from ", Table, " ", WhereClause, ";"]). get_roster_version(LServer, LUser) -> ejabberd_odbc:sql_query(LServer, ["select version from roster_version where username = '", LUser, "'"]). set_roster_version(LUser, Version) -> update_t("roster_version", ["username", "version"], [LUser, Version], ["username = '", LUser, "'"]). -endif. %% ----------------- %% MSSQL queries -ifdef(mssql). get_db_type() -> mssql. %% Queries can be either a fun or a list of queries sql_transaction(LServer, Queries) when is_list(Queries) -> %% SQL transaction based on a list of queries %% This function automatically F = fun() -> lists:foreach(fun(Query) -> ejabberd_odbc:sql_query(LServer, Query) end, Queries) end, {atomic, catch F()}; sql_transaction(_LServer, FQueries) -> {atomic, catch FQueries()}. get_last(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_last '", Username, "'"]). set_last_t(LServer, Username, Seconds, State) -> Result = ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.set_last '", Username, "', '", Seconds, "', '", State, "'"]), {atomic, Result}. del_last(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.del_last '", Username, "'"]). get_password(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_password '", Username, "'"]). set_password_t(LServer, Username, Pass) -> Result = ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.set_password '", Username, "', '", Pass, "'"]), {atomic, Result}. add_user(LServer, Username, Pass) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.add_user '", Username, "', '", Pass, "'"]). del_user(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.del_user '", Username ,"'"]). del_user_return_password(LServer, Username, Pass) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.del_user_return_password '", Username, "'"]), Pass. list_users(LServer) -> ejabberd_odbc:sql_query( LServer, "EXECUTE dbo.list_users"). list_users(LServer, _) -> % scope listing not supported list_users(LServer). users_number(LServer) -> ejabberd_odbc:sql_query( LServer, "select count(*) from users with (nolock)"). users_number(LServer, _) -> % scope listing not supported users_number(LServer). add_spool_sql(Username, XML) -> ["EXECUTE dbo.add_spool '", Username, "' , '",XML,"'"]. add_spool(LServer, Queries) -> lists:foreach(fun(Query) -> ejabberd_odbc:sql_query(LServer, Query) end, Queries). get_and_del_spool_msg_t(LServer, Username) -> [Result] = case ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_and_del_spool_msg '", Username, "'"]) of Rs when is_list(Rs) -> lists:filter(fun({selected, _Header, _Row}) -> true; ({updated, _N}) -> false end, Rs); Rs -> [Rs] end, {atomic, Result}. del_spool_msg(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.del_spool_msg '", Username, "'"]). get_roster(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_roster '", Username, "'"]). get_roster_jid_groups(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_roster_jid_groups '", Username, "'"]). get_roster_groups(LServer, Username, SJID) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_roster_groups '", Username, "' , '", SJID, "'"]). del_user_roster_t(LServer, Username) -> Result = ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.del_user_roster '", Username, "'"]), {atomic, Result}. get_roster_by_jid(LServer, Username, SJID) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_roster_by_jid '", Username, "' , '", SJID, "'"]). get_rostergroup_by_jid(LServer, Username, SJID) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_rostergroup_by_jid '", Username, "' , '", SJID, "'"]). del_roster(LServer, Username, SJID) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.del_roster '", Username, "', '", SJID, "'"]). del_roster_sql(Username, SJID) -> ["EXECUTE dbo.del_roster '", Username, "', '", SJID, "'"]. update_roster(LServer, Username, SJID, ItemVals, ItemGroups) -> Query1 = ["EXECUTE dbo.del_roster '", Username, "', '", SJID, "' "], ejabberd_odbc:sql_query(LServer, lists:flatten(Query1)), Query2 = ["EXECUTE dbo.add_roster_user ", ItemVals], ejabberd_odbc:sql_query(LServer, lists:flatten(Query2)), Query3 = ["EXECUTE dbo.del_roster_groups '", Username, "', '", SJID, "' "], ejabberd_odbc:sql_query(LServer, lists:flatten(Query3)), lists:foreach(fun(ItemGroup) -> Query = ["EXECUTE dbo.add_roster_group ", ItemGroup], ejabberd_odbc:sql_query(LServer, lists:flatten(Query)) end, ItemGroups). update_roster_sql(Username, SJID, ItemVals, ItemGroups) -> ["BEGIN TRANSACTION ", "EXECUTE dbo.del_roster_groups '", Username, "','", SJID, "' ", "EXECUTE dbo.add_roster_user ", ItemVals, " "] ++ [lists:flatten("EXECUTE dbo.add_roster_group ", ItemGroup, " ") || ItemGroup <- ItemGroups] ++ ["COMMIT"]. roster_subscribe(LServer, _Username, _SJID, ItemVals) -> catch ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.add_roster_user ", ItemVals]). get_subscription(LServer, Username, SJID) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_subscription '", Username, "' , '", SJID, "'"]). set_private_data(LServer, Username, LXMLNS, SData) -> ejabberd_odbc:sql_query( LServer, set_private_data_sql(Username, LXMLNS, SData)). set_private_data_sql(Username, LXMLNS, SData) -> ["EXECUTE dbo.set_private_data '", Username, "' , '", LXMLNS, "' , '", SData, "'"]. get_private_data(LServer, Username, LXMLNS) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_private_data '", Username, "' , '", LXMLNS, "'"]). del_user_private_storage(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.del_user_storage '", Username, "'"]). set_vcard(LServer, LUsername, SBDay, SCTRY, SEMail, SFN, SFamily, SGiven, SLBDay, SLCTRY, SLEMail, SLFN, SLFamily, SLGiven, SLLocality, SLMiddle, SLNickname, SLOrgName, SLOrgUnit, SLocality, SMiddle, SNickname, SOrgName, SOrgUnit, SVCARD, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.set_vcard '", SVCARD, "' , '", Username, "' , '", LUsername, "' , '", SFN, "' , '", SLFN, "' , '", SFamily, "' , '", SLFamily, "' , '", SGiven, "' , '", SLGiven, "' , '", SMiddle, "' , '", SLMiddle, "' , '", SNickname, "' , '", SLNickname, "' , '", SBDay, "' , '", SLBDay, "' , '", SCTRY, "' , '", SLCTRY, "' , '", SLocality, "' , '", SLLocality, "' , '", SEMail, "' , '", SLEMail, "' , '", SOrgName, "' , '", SLOrgName, "' , '", SOrgUnit, "' , '", SLOrgUnit, "'"]). get_vcard(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_vcard '", Username, "'"]). get_default_privacy_list(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_default_privacy_list '", Username, "'"]). get_default_privacy_list_t(Username) -> ejabberd_odbc:sql_query_t( ["EXECUTE dbo.get_default_privacy_list '", Username, "'"]). get_privacy_list_names(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_privacy_list_names '", Username, "'"]). get_privacy_list_names_t(Username) -> ejabberd_odbc:sql_query_t( ["EXECUTE dbo.get_privacy_list_names '", Username, "'"]). get_privacy_list_id(LServer, Username, SName) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_privacy_list_id '", Username, "' , '", SName, "'"]). get_privacy_list_id_t(Username, SName) -> ejabberd_odbc:sql_query_t( ["EXECUTE dbo.get_privacy_list_id '", Username, "' , '", SName, "'"]). get_privacy_list_data(LServer, Username, SName) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_privacy_list_data '", Username, "' , '", SName, "'"]). get_privacy_list_data_by_id(LServer, ID) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_privacy_list_data_by_id '", ID, "'"]). get_privacy_list_data_by_id_t(ID) -> ejabberd_odbc:sql_query_t( ["EXECUTE dbo.get_privacy_list_data_by_id '", ID, "'"]). set_default_privacy_list(Username, SName) -> ejabberd_odbc:sql_query_t( ["EXECUTE dbo.set_default_privacy_list '", Username, "' , '", SName, "'"]). unset_default_privacy_list(LServer, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.unset_default_privacy_list '", Username, "'"]). remove_privacy_list(Username, SName) -> ejabberd_odbc:sql_query_t( ["EXECUTE dbo.remove_privacy_list '", Username, "' , '", SName, "'"]). add_privacy_list(Username, SName) -> ejabberd_odbc:sql_query_t( ["EXECUTE dbo.add_privacy_list '", Username, "' , '", SName, "'"]). set_privacy_list(ID, RItems) -> ejabberd_odbc:sql_query_t( ["EXECUTE dbo.del_privacy_list_by_id '", ID, "'"]), lists:foreach(fun(Items) -> ejabberd_odbc:sql_query_t( ["EXECUTE dbo.set_privacy_list '", ID, "', '", join(Items, "', '"), "'"]) end, RItems). del_privacy_lists(LServer, Server, Username) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.del_privacy_lists @Server='", Server ,"' @username='", Username, "'"]). %% Characters to escape escape($\0) -> "\\0"; escape($\t) -> "\\t"; escape($\b) -> "\\b"; escape($\r) -> "\\r"; escape($') -> "\''"; escape($") -> "\\\""; escape(C) -> C. %% Count number of records in a table given a where clause count_records_where(LServer, Table, WhereClause) -> ejabberd_odbc:sql_query( LServer, ["select count(*) from ", Table, " with (nolock) ", WhereClause]). get_roster_version(LServer, LUser) -> ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.get_roster_version '", LUser, "'"]). set_roster_version(Username, Version) -> %% This function doesn't know the vhost, so we hope it's the first one defined: LServer = ?MYNAME, ejabberd_odbc:sql_query( LServer, ["EXECUTE dbo.set_roster_version '", Username, "', '", Version, "'"]). -endif. ejabberd-2.1.11/src/odbc/Makefile.in0000664000000000000000000000110412240230175013755 0ustar # $Id$ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ EFLAGS += -I .. EFLAGS += -pz .. # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif OUTDIR = .. SOURCES = $(wildcard *.erl) BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) all: $(BEAMS) $(OUTDIR)/%.beam: %.erl @ERLC@ -W $(EFLAGS) -D@db_type@ -o $(OUTDIR) $< clean: rm -f $(BEAMS) distclean: clean rm -f Makefile TAGS: etags *.erl ejabberd-2.1.11/src/odbc/ejabberd_odbc.erl0000664000000000000000000004500712240230175015153 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_odbc.erl %%% Author : Alexey Shchepin %%% Purpose : Serve ODBC connection %%% Created : 8 Dec 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_odbc). -author('alexey@process-one.net'). -define(GEN_FSM, p1_fsm). -behaviour(?GEN_FSM). %% External exports -export([start/1, start_link/2, sql_query/2, sql_query_t/1, sql_transaction/2, sql_bloc/2, escape/1, escape_like/1, to_bool/1, encode_term/1, decode_term/1, keep_alive/1]). %% gen_fsm callbacks -export([init/1, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, print_state/1, code_change/4]). %% gen_fsm states -export([connecting/2, connecting/3, session_established/2, session_established/3]). -include("ejabberd.hrl"). -record(state, {db_ref, db_type, start_interval, host, max_pending_requests_len, pending_requests}). -define(STATE_KEY, ejabberd_odbc_state). -define(NESTING_KEY, ejabberd_odbc_nesting_level). -define(TOP_LEVEL_TXN, 0). -define(MAX_TRANSACTION_RESTARTS, 10). -define(PGSQL_PORT, 5432). -define(MYSQL_PORT, 3306). -define(TRANSACTION_TIMEOUT, 60000). % milliseconds -define(KEEPALIVE_TIMEOUT, 60000). -define(KEEPALIVE_QUERY, "SELECT 1;"). %%-define(DBGFSM, true). -ifdef(DBGFSM). -define(FSMOPTS, [{debug, [trace]}]). -else. -define(FSMOPTS, []). -endif. %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start(Host) -> ?GEN_FSM:start(ejabberd_odbc, [Host], fsm_limit_opts() ++ ?FSMOPTS). start_link(Host, StartInterval) -> ?GEN_FSM:start_link(ejabberd_odbc, [Host, StartInterval], fsm_limit_opts() ++ ?FSMOPTS). sql_query(Host, Query) -> sql_call(Host, {sql_query, Query}). %% SQL transaction based on a list of queries %% This function automatically sql_transaction(Host, Queries) when is_list(Queries) -> F = fun() -> lists:foreach(fun(Query) -> sql_query_t(Query) end, Queries) end, sql_transaction(Host, F); %% SQL transaction, based on a erlang anonymous function (F = fun) sql_transaction(Host, F) when is_function(F) -> sql_call(Host, {sql_transaction, F}). %% SQL bloc, based on a erlang anonymous function (F = fun) sql_bloc(Host, F) -> sql_call(Host, {sql_bloc, F}). sql_call(Host, Msg) -> case get(?STATE_KEY) of undefined -> ?GEN_FSM:sync_send_event(ejabberd_odbc_sup:get_random_pid(Host), {sql_cmd, Msg, now()}, ?TRANSACTION_TIMEOUT); _State -> nested_op(Msg) end. % perform a harmless query on all opened connexions to avoid connexion close. keep_alive(PID) -> ?GEN_FSM:sync_send_event(PID, {sql_cmd, {sql_query, ?KEEPALIVE_QUERY}, now()}, ?KEEPALIVE_TIMEOUT). %% This function is intended to be used from inside an sql_transaction: sql_query_t(Query) -> QRes = sql_query_internal(Query), case QRes of {error, Reason} -> throw({aborted, Reason}); Rs when is_list(Rs) -> case lists:keysearch(error, 1, Rs) of {value, {error, Reason}} -> throw({aborted, Reason}); _ -> QRes end; _ -> QRes end. %% Escape character that will confuse an SQL engine escape(S) when is_list(S) -> [odbc_queries:escape(C) || C <- S]; escape(S) when is_binary(S) -> escape(binary_to_list(S)). %% Escape character that will confuse an SQL engine %% Percent and underscore only need to be escaped for pattern matching like %% statement escape_like(S) when is_list(S) -> [escape_like(C) || C <- S]; escape_like($%) -> "\\%"; escape_like($_) -> "\\_"; escape_like(C) -> odbc_queries:escape(C). to_bool("t") -> true; to_bool("true") -> true; to_bool("1") -> true; to_bool(true) -> true; to_bool(1) -> true; to_bool(_) -> false. encode_term(Term) -> escape(erl_prettypr:format(erl_syntax:abstract(Term))). decode_term(Str) -> {ok, Tokens, _} = erl_scan:string(Str ++ "."), {ok, Term} = erl_parse:parse_term(Tokens), Term. %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- init([Host, StartInterval]) -> case ejabberd_config:get_local_option({odbc_keepalive_interval, Host}) of KeepaliveInterval when is_integer(KeepaliveInterval) -> timer:apply_interval(KeepaliveInterval*1000, ?MODULE, keep_alive, [self()]); undefined -> ok; _Other -> ?ERROR_MSG("Wrong odbc_keepalive_interval definition '~p'" " for host ~p.~n", [_Other, Host]) end, [DBType | _] = db_opts(Host), ?GEN_FSM:send_event(self(), connect), ejabberd_odbc_sup:add_pid(Host, self()), {ok, connecting, #state{db_type = DBType, host = Host, max_pending_requests_len = max_fsm_queue(), pending_requests = {0, queue:new()}, start_interval = StartInterval}}. connecting(connect, #state{host = Host} = State) -> ConnectRes = case db_opts(Host) of [mysql | Args] -> apply(fun mysql_connect/5, Args); [pgsql | Args] -> apply(fun pgsql_connect/5, Args); [odbc | Args] -> apply(fun odbc_connect/1, Args) end, {_, PendingRequests} = State#state.pending_requests, case ConnectRes of {ok, Ref} -> erlang:monitor(process, Ref), lists:foreach( fun(Req) -> ?GEN_FSM:send_event(self(), Req) end, queue:to_list(PendingRequests)), {next_state, session_established, State#state{db_ref = Ref, pending_requests = {0, queue:new()}}}; {error, Reason} -> ?INFO_MSG("~p connection failed:~n" "** Reason: ~p~n" "** Retry after: ~p seconds", [State#state.db_type, Reason, State#state.start_interval div 1000]), ?GEN_FSM:send_event_after(State#state.start_interval, connect), {next_state, connecting, State} end; connecting(Event, State) -> ?WARNING_MSG("unexpected event in 'connecting': ~p", [Event]), {next_state, connecting, State}. connecting({sql_cmd, {sql_query, ?KEEPALIVE_QUERY}, _Timestamp}, From, State) -> ?GEN_FSM:reply(From, {error, "SQL connection failed"}), {next_state, connecting, State}; connecting({sql_cmd, Command, Timestamp} = Req, From, State) -> ?DEBUG("queuing pending request while connecting:~n\t~p", [Req]), {Len, PendingRequests} = State#state.pending_requests, NewPendingRequests = if Len < State#state.max_pending_requests_len -> {Len + 1, queue:in({sql_cmd, Command, From, Timestamp}, PendingRequests)}; true -> lists:foreach( fun({sql_cmd, _, To, _Timestamp}) -> ?GEN_FSM:reply( To, {error, "SQL connection failed"}) end, queue:to_list(PendingRequests)), {1, queue:from_list([{sql_cmd, Command, From, Timestamp}])} end, {next_state, connecting, State#state{pending_requests = NewPendingRequests}}; connecting(Request, {Who, _Ref}, State) -> ?WARNING_MSG("unexpected call ~p from ~p in 'connecting'", [Request, Who]), {reply, {error, badarg}, connecting, State}. session_established({sql_cmd, Command, Timestamp}, From, State) -> run_sql_cmd(Command, From, State, Timestamp); session_established(Request, {Who, _Ref}, State) -> ?WARNING_MSG("unexpected call ~p from ~p in 'session_established'", [Request, Who]), {reply, {error, badarg}, session_established, State}. session_established({sql_cmd, Command, From, Timestamp}, State) -> run_sql_cmd(Command, From, State, Timestamp); session_established(Event, State) -> ?WARNING_MSG("unexpected event in 'session_established': ~p", [Event]), {next_state, session_established, State}. handle_event(_Event, StateName, State) -> {next_state, StateName, State}. handle_sync_event(_Event, _From, StateName, State) -> {reply, {error, badarg}, StateName, State}. code_change(_OldVsn, StateName, State, _Extra) -> {ok, StateName, State}. %% We receive the down signal when we loose the MySQL connection (we are %% monitoring the connection) handle_info({'DOWN', _MonitorRef, process, _Pid, _Info}, _StateName, State) -> ?GEN_FSM:send_event(self(), connect), {next_state, connecting, State}; handle_info(Info, StateName, State) -> ?WARNING_MSG("unexpected info in ~p: ~p", [StateName, Info]), {next_state, StateName, State}. terminate(_Reason, _StateName, State) -> ejabberd_odbc_sup:remove_pid(State#state.host, self()), case State#state.db_type of mysql -> %% old versions of mysql driver don't have the stop function %% so the catch catch mysql_conn:stop(State#state.db_ref); _ -> ok end, ok. %%---------------------------------------------------------------------- %% Func: print_state/1 %% Purpose: Prepare the state to be printed on error log %% Returns: State to print %%---------------------------------------------------------------------- print_state(State) -> State. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- run_sql_cmd(Command, From, State, Timestamp) -> case timer:now_diff(now(), Timestamp) div 1000 of Age when Age < ?TRANSACTION_TIMEOUT -> put(?NESTING_KEY, ?TOP_LEVEL_TXN), put(?STATE_KEY, State), abort_on_driver_error(outer_op(Command), From); Age -> ?ERROR_MSG("Database was not available or too slow," " discarding ~p milliseconds old request~n~p~n", [Age, Command]), {next_state, session_established, State} end. %% Only called by handle_call, only handles top level operations. %% @spec outer_op(Op) -> {error, Reason} | {aborted, Reason} | {atomic, Result} outer_op({sql_query, Query}) -> sql_query_internal(Query); outer_op({sql_transaction, F}) -> outer_transaction(F, ?MAX_TRANSACTION_RESTARTS, ""); outer_op({sql_bloc, F}) -> execute_bloc(F). %% Called via sql_query/transaction/bloc from client code when inside a %% nested operation nested_op({sql_query, Query}) -> %% XXX - use sql_query_t here insted? Most likely would break %% callers who expect {error, _} tuples (sql_query_t turns %% these into throws) sql_query_internal(Query); nested_op({sql_transaction, F}) -> NestingLevel = get(?NESTING_KEY), if NestingLevel =:= ?TOP_LEVEL_TXN -> %% First transaction inside a (series of) sql_blocs outer_transaction(F, ?MAX_TRANSACTION_RESTARTS, ""); true -> %% Transaction inside a transaction inner_transaction(F) end; nested_op({sql_bloc, F}) -> execute_bloc(F). %% Never retry nested transactions - only outer transactions inner_transaction(F) -> PreviousNestingLevel = get(?NESTING_KEY), case get(?NESTING_KEY) of ?TOP_LEVEL_TXN -> {backtrace, T} = process_info(self(), backtrace), ?ERROR_MSG("inner transaction called at outer txn level. Trace: ~s", [T]), erlang:exit(implementation_faulty); _N -> ok end, put(?NESTING_KEY, PreviousNestingLevel + 1), Result = (catch F()), put(?NESTING_KEY, PreviousNestingLevel), case Result of {aborted, Reason} -> {aborted, Reason}; {'EXIT', Reason} -> {'EXIT', Reason}; {atomic, Res} -> {atomic, Res}; Res -> {atomic, Res} end. outer_transaction(F, NRestarts, _Reason) -> PreviousNestingLevel = get(?NESTING_KEY), case get(?NESTING_KEY) of ?TOP_LEVEL_TXN -> ok; _N -> {backtrace, T} = process_info(self(), backtrace), ?ERROR_MSG("outer transaction called at inner txn level. Trace: ~s", [T]), erlang:exit(implementation_faulty) end, sql_query_internal("begin;"), put(?NESTING_KEY, PreviousNestingLevel + 1), Result = (catch F()), put(?NESTING_KEY, PreviousNestingLevel), case Result of {aborted, Reason} when NRestarts > 0 -> %% Retry outer transaction upto NRestarts times. sql_query_internal("rollback;"), outer_transaction(F, NRestarts - 1, Reason); {aborted, Reason} when NRestarts =:= 0 -> %% Too many retries of outer transaction. ?ERROR_MSG("SQL transaction restarts exceeded~n" "** Restarts: ~p~n" "** Last abort reason: ~p~n" "** Stacktrace: ~p~n" "** When State == ~p", [?MAX_TRANSACTION_RESTARTS, Reason, erlang:get_stacktrace(), get(?STATE_KEY)]), sql_query_internal("rollback;"), {aborted, Reason}; {'EXIT', Reason} -> %% Abort sql transaction on EXIT from outer txn only. sql_query_internal("rollback;"), {aborted, Reason}; Res -> %% Commit successful outer txn sql_query_internal("commit;"), {atomic, Res} end. execute_bloc(F) -> %% We don't alter ?NESTING_KEY here as only SQL transactions alter %% txn nesting case catch F() of {aborted, Reason} -> {aborted, Reason}; {'EXIT', Reason} -> {aborted, Reason}; Res -> {atomic, Res} end. sql_query_internal(Query) -> State = get(?STATE_KEY), Res = case State#state.db_type of odbc -> odbc:sql_query(State#state.db_ref, Query); pgsql -> pgsql_to_odbc(pgsql:squery(State#state.db_ref, Query)); mysql -> ?DEBUG("MySQL, Send query~n~p~n", [Query]), R = mysql_to_odbc(mysql_conn:fetch(State#state.db_ref, Query, self())), %% ?INFO_MSG("MySQL, Received result~n~p~n", [R]), R end, case Res of {error, "No SQL-driver information available."} -> % workaround for odbc bug {updated, 0}; _Else -> Res end. %% Generate the OTP callback return tuple depending on the driver result. abort_on_driver_error({error, "query timed out"} = Reply, From) -> %% mysql driver error ?GEN_FSM:reply(From, Reply), {stop, timeout, get(?STATE_KEY)}; abort_on_driver_error({error, "Failed sending data on socket" ++ _} = Reply, From) -> %% mysql driver error ?GEN_FSM:reply(From, Reply), {stop, closed, get(?STATE_KEY)}; abort_on_driver_error(Reply, From) -> ?GEN_FSM:reply(From, Reply), {next_state, session_established, get(?STATE_KEY)}. %% == pure ODBC code %% part of init/1 %% Open an ODBC database connection odbc_connect(SQLServer) -> application:start(odbc), odbc:connect(SQLServer, [{scrollable_cursors, off}]). %% == Native PostgreSQL code %% part of init/1 %% Open a database connection to PostgreSQL pgsql_connect(Server, Port, DB, Username, Password) -> pgsql:connect(Server, DB, Username, Password, Port). %% Convert PostgreSQL query result to Erlang ODBC result formalism pgsql_to_odbc({ok, PGSQLResult}) -> case PGSQLResult of [Item] -> pgsql_item_to_odbc(Item); Items -> [pgsql_item_to_odbc(Item) || Item <- Items] end. pgsql_item_to_odbc({"SELECT" ++ _, Rows, Recs}) -> {selected, [element(1, Row) || Row <- Rows], [list_to_tuple(Rec) || Rec <- Recs]}; pgsql_item_to_odbc("INSERT " ++ OIDN) -> [_OID, N] = string:tokens(OIDN, " "), {updated, list_to_integer(N)}; pgsql_item_to_odbc("DELETE " ++ N) -> {updated, list_to_integer(N)}; pgsql_item_to_odbc("UPDATE " ++ N) -> {updated, list_to_integer(N)}; pgsql_item_to_odbc({error, Error}) -> {error, Error}; pgsql_item_to_odbc(_) -> {updated,undefined}. %% == Native MySQL code %% part of init/1 %% Open a database connection to MySQL mysql_connect(Server, Port, DB, Username, Password) -> case mysql_conn:start(Server, Port, Username, Password, DB, fun log/3) of {ok, Ref} -> mysql_conn:fetch(Ref, ["set names 'utf8';"], self()), {ok, Ref}; Err -> Err end. %% Convert MySQL query result to Erlang ODBC result formalism mysql_to_odbc({updated, MySQLRes}) -> {updated, mysql:get_result_affected_rows(MySQLRes)}; mysql_to_odbc({data, MySQLRes}) -> mysql_item_to_odbc(mysql:get_result_field_info(MySQLRes), mysql:get_result_rows(MySQLRes)); mysql_to_odbc({error, MySQLRes}) when is_list(MySQLRes) -> {error, MySQLRes}; mysql_to_odbc({error, MySQLRes}) -> {error, mysql:get_result_reason(MySQLRes)}. %% When tabular data is returned, convert it to the ODBC formalism mysql_item_to_odbc(Columns, Recs) -> %% For now, there is a bug and we do not get the correct value from MySQL %% module: {selected, [element(2, Column) || Column <- Columns], [list_to_tuple(Rec) || Rec <- Recs]}. % log function used by MySQL driver log(Level, Format, Args) -> case Level of debug -> ?DEBUG(Format, Args); normal -> ?INFO_MSG(Format, Args); error -> ?ERROR_MSG(Format, Args) end. db_opts(Host) -> case ejabberd_config:get_local_option({odbc_server, Host}) of %% Default pgsql port {pgsql, Server, DB, User, Pass} -> [pgsql, Server, ?PGSQL_PORT, DB, User, Pass]; {pgsql, Server, Port, DB, User, Pass} when is_integer(Port) -> [pgsql, Server, Port, DB, User, Pass]; %% Default mysql port {mysql, Server, DB, User, Pass} -> [mysql, Server, ?MYSQL_PORT, DB, User, Pass]; {mysql, Server, Port, DB, User, Pass} when is_integer(Port) -> [mysql, Server, Port, DB, User, Pass]; SQLServer when is_list(SQLServer) -> [odbc, SQLServer] end. max_fsm_queue() -> case ejabberd_config:get_local_option(max_fsm_queue) of N when is_integer(N), N>0 -> N; _ -> undefined end. fsm_limit_opts() -> case max_fsm_queue() of N when is_integer(N) -> [{max_queue, N}]; _ -> [] end. ejabberd-2.1.11/src/odbc/mssql2005.sql0000664000000000000000000016221412240230175014111 0ustar /* * ejabberd, Copyright (C) 2002-2012 ProcessOne * * 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., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * */ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO exec sp_dboption N'ejabberd', N'autoclose', N'false' GO exec sp_dboption N'ejabberd', N'bulkcopy', N'true' GO exec sp_dboption N'ejabberd', N'trunc. log', N'false' GO exec sp_dboption N'ejabberd', N'torn page detection', N'true' GO exec sp_dboption N'ejabberd', N'read only', N'false' GO exec sp_dboption N'ejabberd', N'dbo use', N'false' GO exec sp_dboption N'ejabberd', N'single', N'false' GO exec sp_dboption N'ejabberd', N'autoshrink', N'false' GO exec sp_dboption N'ejabberd', N'ANSI null default', N'false' GO exec sp_dboption N'ejabberd', N'recursive triggers', N'false' GO exec sp_dboption N'ejabberd', N'ANSI nulls', N'false' GO exec sp_dboption N'ejabberd', N'concat null yields null', N'false' GO exec sp_dboption N'ejabberd', N'cursor close on commit', N'false' GO exec sp_dboption N'ejabberd', N'default to local cursor', N'false' GO exec sp_dboption N'ejabberd', N'quoted identifier', N'false' GO exec sp_dboption N'ejabberd', N'ANSI warnings', N'false' GO exec sp_dboption N'ejabberd', N'auto create statistics', N'true' GO exec sp_dboption N'ejabberd', N'auto update statistics', N'true' GO use [ejabberd] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[last]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[last] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[rostergroups]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[rostergroups] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[rosterusers]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[rosterusers] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[spool]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[spool] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[users]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[users] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[vcard]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[vcard] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[vcard_search]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[vcard_search] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[private_storage]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[private_storage] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[privacy_default_list]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[privacy_default_list] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[privacy_list]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[privacy_list] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[privacy_list_data]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[privacy_list_data] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[roster_version]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[roster_version] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[pubsub_node_option]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[pubsub_node_option] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[pubsub_node_owner]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[pubsub_node_owner] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[pubsub_state]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[pubsub_state] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[pubsub_item]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[pubsub_item] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[pubsub_subscription_opt]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[pubsub_subscription_opt] GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[pubsub_node]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[pubsub_node] GO CREATE TABLE [dbo].[last] ( [username] [varchar] (250) NOT NULL , [seconds] [varchar] (50) NOT NULL , [state] [varchar] (100) NOT NULL , [Modify_Date] [datetime] NOT NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[rostergroups] ( [username] [varchar] (250) NOT NULL , [jid] [varchar] (250) NOT NULL , [grp] [varchar] (100) NOT NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[rosterusers] ( [username] [varchar] (250) NOT NULL , [jid] [varchar] (250) NOT NULL , [nick] [varchar] (50) NOT NULL , [subscription] [char] (1) NOT NULL , [ask] [char] (1) NOT NULL , [askmessage] [varchar] (250) NOT NULL , [server] [char] (1) NOT NULL , [subscribe] [varchar] (200) NULL , [type] [varchar] (50) NULL , CONSTRAINT [PK_rosterusers] PRIMARY KEY NONCLUSTERED ( [username] ASC, [jid] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO CREATE TABLE [dbo].[spool] ( [id] [numeric](19, 0) IDENTITY (1, 1) NOT NULL , [username] [varchar] (250) NOT NULL , [xml] [text] NOT NULL , [notifyprocessed] [bit] NULL , [created] [datetime] NULL , [MustDelete] [bit] NOT NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO CREATE TABLE [dbo].[users] ( [username] [varchar] (250) NOT NULL , [password] [varchar] (50) NOT NULL , [created] [datetime] NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[vcard] ( [username] [varchar] (250) NOT NULL , [vcard] [text] NOT NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[vcard_search] ( [username] [varchar] (250) NOT NULL , [lusername] [varchar] (250) NOT NULL , [fn] [text] NOT NULL , [lfn] [varchar] (250) NOT NULL , [family] [text] NOT NULL , [lfamily] [varchar] (250) NOT NULL , [given] [text] NOT NULL , [lgiven] [varchar] (250) NOT NULL , [middle] [text] NOT NULL , [lmiddle] [varchar] (250) NOT NULL , [nickname] [text] NOT NULL , [lnickname] [varchar] (250) NOT NULL , [bday] [text] NOT NULL , [lbday] [varchar] (250) NOT NULL , [ctry] [text] NOT NULL , [lctry] [varchar] (250) NOT NULL , [locality] [text] NOT NULL , [llocality] [varchar] (250) NOT NULL , [email] [text] NOT NULL , [lemail] [varchar] (250) NOT NULL , [orgname] [text] NOT NULL , [lorgname] [varchar] (250) NOT NULL , [orgunit] [text] NOT NULL , [lorgunit] [varchar] (250) NOT NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[private_storage] ( [username] [varchar] (250) NOT NULL , [namespace] [varchar] (250) NOT NULL , [data] [text] NOT NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[privacy_default_list] ( [username] [varchar] (250) NOT NULL, [name] [varchar] (250) NOT NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[privacy_list]( [username] [varchar](250) NOT NULL, [name] [varchar](250) NOT NULL, [id] [bigint] IDENTITY(1,1) NOT NULL, CONSTRAINT [PK_privacy_list] PRIMARY KEY CLUSTERED ( [id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO CREATE TABLE [dbo].[privacy_list_data] ( [id] [bigint] NOT NULL, [t] [character] (1) NOT NULL, [value] [text] NOT NULL, [action] [character] (1) NOT NULL, [ord] [NUMERIC] NOT NULL, [match_all] [bit] NOT NULL, [match_iq] [bit] NOT NULL, [match_message] [bit] NOT NULL, [match_presence_in] [bit] NOT NULL, [match_presence_out] [bit] NOT NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[roster_version] ( [username] [varchar](250) PRIMARY KEY, [version] [text] NOT NULL ) ON [PRIMARY] GO CREATE TABLE [dbo].[pubsub_node] ( [host] [varchar](250), [node] [varchar](250), [parent] [varchar](250), [type] [varchar](250), [nodeid] [bigint] IDENTITY(1,1) PRIMARY KEY ) ON [PRIMARY] GO CREATE TABLE [dbo].[pubsub_node_option] ( [nodeid] [bigint], [name] [varchar](250), [val] [varchar](250) ) ON [PRIMARY] GO CREATE TABLE [dbo].[pubsub_node_owner] ( [nodeid] [bigint], [owner] [varchar](250) ) ON [PRIMARY] GO CREATE TABLE [dbo].[pubsub_state] ( [nodeid] [bigint], [jid] [varchar](250), [affiliation] [CHAR](1), [subscriptions] [text], [stateid] [bigint] IDENTITY(1,1) PRIMARY KEY ) ON [PRIMARY] GO CREATE TABLE [dbo].[pubsub_item] ( [nodeid] [bigint], [itemid] [varchar](250), [publisher] [text], [creation] [text], [modification] [text], [payload] [text] ) ON [PRIMARY] GO CREATE TABLE [dbo].[pubsub_subscription_opt] ( [subid] [varchar](250), [opt_name] [varchar](32), [opt_value] [text] ) ON [PRIMARY] GO /* Constraints to add: - id in privacy_list is a SERIAL autogenerated number - id in privacy_list_data must exist in the table privacy_list */ ALTER TABLE [dbo].[last] WITH NOCHECK ADD CONSTRAINT [PK_last] PRIMARY KEY CLUSTERED ( [username] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO ALTER TABLE [dbo].[rostergroups] WITH NOCHECK ADD CONSTRAINT [PK_rostergroups] PRIMARY KEY CLUSTERED ( [username], [jid], [grp] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO ALTER TABLE [dbo].[spool] WITH NOCHECK ADD CONSTRAINT [PK_spool] PRIMARY KEY CLUSTERED ( [username], [id] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO ALTER TABLE [dbo].[users] WITH NOCHECK ADD CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED ( [username] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO ALTER TABLE [dbo].[vcard] WITH NOCHECK ADD CONSTRAINT [PK_vcard] PRIMARY KEY CLUSTERED ( [username] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO ALTER TABLE [dbo].[pubsub_node_option] WITH NOCHECK ADD CONSTRAINT [FK_pubsub_node_option] FOREIGN KEY ( [nodeid] ) REFERENCES [dbo].[pubsub_node] ( [nodeid] ) ON DELETE CASCADE GO ALTER TABLE [dbo].[pubsub_node_owner] WITH NOCHECK ADD CONSTRAINT [FK_pubsub_node_owner] FOREIGN KEY ( [nodeid] ) REFERENCES [pubsub_node] ( [nodeid] ) ON DELETE CASCADE GO ALTER TABLE [dbo].[pubsub_state] WITH NOCHECK ADD CONSTRAINT [FK_pubsub_state] FOREIGN KEY ( [nodeid] ) REFERENCES [pubsub_node] ( [nodeid] ) ON DELETE CASCADE GO ALTER TABLE [dbo].[pubsub_item] WITH NOCHECK ADD CONSTRAINT [FK_pubsub_item] FOREIGN KEY ( [nodeid] ) REFERENCES [pubsub_node] ( [nodeid] ) ON DELETE CASCADE GO CREATE INDEX [IX_vcard_search_lfn] ON [dbo].[vcard_search]([lfn]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_vcard_search_lfamily] ON [dbo].[vcard_search]([lfamily]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_vcard_search_lgiven] ON [dbo].[vcard_search]([lgiven]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_vcard_search_lmiddle] ON [dbo].[vcard_search]([lmiddle]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_vcard_search_lnickname] ON [dbo].[vcard_search]([lnickname]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_vcard_search_lbday] ON [dbo].[vcard_search]([lbday]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_vcard_search_lctry] ON [dbo].[vcard_search]([lctry]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_vcard_search_llocality] ON [dbo].[vcard_search]([llocality]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_vcard_search_lemail] ON [dbo].[vcard_search]([lemail]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_vcard_search_lorgname] ON [dbo].[vcard_search]([lorgname]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_vcard_search_lorgunit] ON [dbo].[vcard_search]([lorgunit]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE CLUSTERED INDEX [IX_rosterusers_user] ON [dbo].[rosterusers]([username]) WITH FILLFACTOR = 90 ON [PRIMARY] GO ALTER TABLE [dbo].[last] WITH NOCHECK ADD CONSTRAINT [DF_last_updated] DEFAULT (getdate()) FOR [Modify_Date] GO ALTER TABLE [dbo].[spool] WITH NOCHECK ADD CONSTRAINT [DF_spool_notifyprocessed] DEFAULT (0) FOR [notifyprocessed], CONSTRAINT [DF_spool_created] DEFAULT (getdate()) FOR [created], CONSTRAINT [DF_spool_MustDelete] DEFAULT (0) FOR [MustDelete] GO ALTER TABLE [dbo].[users] WITH NOCHECK ADD CONSTRAINT [DF_users_created] DEFAULT (getdate()) FOR [created] GO ALTER TABLE [dbo].[privacy_default_list] WITH NOCHECK ADD CONSTRAINT [PK_privacy_defaut_list] PRIMARY KEY CLUSTERED ( [username] ) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_rostergroups_jid] ON [dbo].[rostergroups]([jid]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_rostergroups_user] ON [dbo].[rostergroups]([username]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_spool_user] ON [dbo].[spool]([username]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_spool_process] ON [dbo].[spool]([created], [notifyprocessed]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IK_Spool_Del] ON [dbo].[spool]([MustDelete]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IK_Spool_Created] ON [dbo].[spool]([created]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_private_user] ON [dbo].[private_storage]([username]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_private_user_ns] ON [dbo].[private_storage]([username], [namespace]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_privacy_list_username] ON [dbo].[privacy_list]([username]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_privacy_list_username_name] ON [dbo].[privacy_list]([username], [name]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_pubsub_node_parent] ON [dbo].[pubsub_node]([parent]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_pubsub_node_tuple] ON [dbo].[pubsub_node]([host], [node]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_pubsub_node_option_nodeid] ON [dbo].[pubsub_node_option]([nodeid]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_pubsub_node_owner_nodeid] ON [dbo].[pubsub_node_owner]([nodeid]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_pubsub_state_jid] ON [dbo].[pubsub_state]([jid]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_pubsub_state_tuple] ON [dbo].[pubsub_state]([nodeid], [jid]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_pubsub_item_itemid] ON [dbo].[pubsub_item]([itemid]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_pubsub_item_tuple] ON [dbo].[pubsub_item]([nodeid], [itemid]) WITH FILLFACTOR = 90 ON [PRIMARY] GO CREATE INDEX [IX_pubsub_subscription_opt] ON [dbo].[pubsub_subscription_opt]([subid], [opt_name]) WITH FILLFACTOR = 90 ON [PRIMARY] Go /*********************************************************/ /** These store procedures are for use with ejabberd **/ /** 1.1 and Microsoft Sql Server 2000 **/ /** **/ /** The stored procedures reduce the need to sql **/ /** compilation of the database and also allow for also **/ /** provide each of database integration. The stored **/ /** procedure have been optimized to increase database **/ /** performance and a reduction of 80% in CPU was **/ /** achieved over the use of standard sql. **/ /*********************************************************/ /****** Object: StoredProcedure [dbo].[add_roster] ******/ /** Add or update user entries in the roster **/ /*********************************************************/ IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[add_roster]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[add_roster] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[add_roster_group]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[add_roster_group] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[add_roster_user]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[add_roster_user] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[del_roster_groups]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[del_roster_groups] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[add_spool]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[add_spool] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[add_user]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[add_user] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[set_password]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[set_password] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[clean_spool_msg]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[clean_spool_msg] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_password]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_password] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[del_last]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[del_last] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[del_roster]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[del_roster] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[del_spool_msg]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[del_spool_msg] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[del_user]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[del_user] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[del_user_return_password]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[del_user_return_password] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[del_user_roster]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[del_user_roster] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_and_del_spool_msg]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_and_del_spool_msg] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_last]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_last] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_roster]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_roster] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_roster_by_jid]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_roster_by_jid] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_roster_jid_groups]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_roster_jid_groups] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_roster_groups]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_roster_groups] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_rostergroup_by_jid]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_rostergroup_by_jid] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_subscription]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_subscription] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[list_users]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[list_users] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[set_last]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[set_last] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[set_private_data]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[set_private_data] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_private_data]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_private_data] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[del_user_storage]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[del_user_storage] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[set_vcard]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[set_vcard] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_vcard]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_vcard] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_default_privacy_list]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_default_privacy_list] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_privacy_list_names]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_privacy_list_names] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_privacy_list_id]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_privacy_list_id] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_privacy_list_data]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_privacy_list_data] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[get_privacy_list_data_by_id]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[get_privacy_list_data_by_id] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[set_default_privacy_list]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[set_default_privacy_list] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[unset_default_privacy_list]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[unset_default_privacy_list] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[remove_privacy_list]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[remove_privacy_list] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[add_privacy_list]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[add_privacy_list] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[set_privacy_list]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[set_privacy_list] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[del_privacy_list_by_id]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[del_privacy_list_by_id] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[del_privacy_lists]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[del_privacy_lists] GO CREATE PROCEDURE [dbo].[add_roster] @Username varchar(250), @JID varchar(250), @Nick varchar(50), @Subscription char(1), @Ask char(1), @AskMessage varchar(250), @Server char(1), @Subscribe varchar(200), @Type varchar(50), @Grp varchar(100) AS BEGIN BEGIN TRANSACTION --- Update Roster if user exist else add roster item IF EXISTS (SELECT username FROM rosterusers WITH (NOLOCK) WHERE rosterusers.username=@Username AND rosterusers.jid=@JID) BEGIN UPDATE rosterusers SET rosterusers.username=@Username, rosterusers.jid=@JID, rosterusers.nick=@Nick, rosterusers.subscription=@Subscription, rosterusers.ask=@Ask, rosterusers.askmessage=@AskMessage, rosterusers.server=@Server, rosterusers.subscribe=@Subscribe, rosterusers.type=@Type WHERE (rosterusers.username=@Username) AND (rosterusers.jid=@JID); END ELSE BEGIN INSERT INTO rosterusers ( rosterusers.username, rosterusers.jid, rosterusers.nick, rosterusers.subscription, rosterusers.ask, rosterusers.askmessage, rosterusers.server, rosterusers.subscribe, rosterusers.type ) VALUES ( @Username, @JID, @Nick, @Subscription, @Ask, @AskMessage, @Server, @Subscribe, @Type ); END --- Update Roster Groups if exist else add group entry IF NOT EXISTS (SELECT username FROM rostergroups WITH (NOLOCK) WHERE rostergroups.username=@Username AND rostergroups.jid=@JID AND rostergroups.grp=@Grp) BEGIN INSERT INTO rostergroups ( rostergroups.username, rostergroups.jid, rostergroups.grp ) VALUES ( @Username, @JID, @Grp ); END COMMIT END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[add_roster_group] ******/ /** Add or update user group entries in the roster groups **/ /***************************************************************/ CREATE PROCEDURE [dbo].[add_roster_group] @Username varchar(250), @JID varchar(250), @Grp varchar(100) AS BEGIN --- Update Roster Groups if exist else add group IF NOT EXISTS (SELECT username FROM rostergroups WHERE rostergroups.username=@Username AND rostergroups.jid=@JID AND rostergroups.grp=@Grp) BEGIN INSERT INTO rostergroups ( rostergroups.username, rostergroups.jid, rostergroups.grp ) VALUES ( @Username, @JID, @Grp ) END END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[add_roster_user] ******/ /** Add or update user entries in the roster **/ /***************************************************************/ CREATE PROCEDURE [dbo].[add_roster_user] @Username varchar(250), @JID varchar(250), @Nick varchar(50), @Subscription char(1), @Ask char(1), @AskMessage varchar(250), @Server char(1), @Subscribe varchar(200), @Type varchar(50), @Grp varchar(100) = Null AS BEGIN BEGIN TRANSACTION --- Update Roster Users if exist of add new user IF EXISTS (SELECT username FROM rosterusers WHERE rosterusers.username=@Username AND rosterusers.jid=@JID) BEGIN UPDATE rosterusers SET rosterusers.username=@Username, rosterusers.jid=@JID, rosterusers.nick=@Nick, rosterusers.subscription=@Subscription, rosterusers.ask=@Ask, rosterusers.askmessage=@AskMessage, rosterusers.server=@Server, rosterusers.subscribe=@Subscribe, rosterusers.type=@Type WHERE (rosterusers.username=@Username) AND (rosterusers.jid=@JID); END ELSE BEGIN INSERT INTO rosterusers ( rosterusers.username, rosterusers.jid, rosterusers.nick, rosterusers.subscription, rosterusers.ask, rosterusers.askmessage, rosterusers.server, rosterusers.subscribe, rosterusers.type ) VALUES ( @Username, @JID, @Nick, @Subscription, @Ask, @AskMessage, @Server, @Subscribe, @Type ); END --- Update Roster Group if exist of add new group IF @Grp IS NOT NULL EXECUTE [dbo].[add_roster_group] @Username, @JID, @Grp COMMIT END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[del_roster_groups] ******/ /** Remove user group entries from the roster groups table **/ /***************************************************************/ CREATE PROCEDURE [dbo].[del_roster_groups] @Username varchar(250), @JID varchar(250) AS BEGIN DELETE FROM rostergroups WITH (ROWLOCK) WHERE (rostergroups.username = @Username) AND (rostergroups.jid = @JID); END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[add_spool] ******/ /** Add a entry to the spool table **/ /***************************************************************/ CREATE PROCEDURE [dbo].[add_spool] @Username varchar(250), @XML varchar(8000) AS BEGIN INSERT INTO spool ( spool.username, spool.xml ) VALUES ( @Username, @XML ) END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[add_user] ******/ /** Add or update user entries to jabber **/ /***************************************************************/ CREATE PROCEDURE [dbo].[add_user] @Username varchar(200), @Password varchar(50) AS BEGIN INSERT INTO users ( [username], [password] ) VALUES ( @Username, @Password ); END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[set_password] **/ /** Update users password **/ /******************************************************************/ CREATE PROCEDURE [dbo].[set_password] @Username varchar(200), @Password varchar(50) AS BEGIN IF EXISTS (SELECT username FROM users WITH (NOLOCK) WHERE username=@Username) BEGIN UPDATE users SET username=@Username, password=@Password WHERE username=@Username; END ELSE BEGIN INSERT INTO users (username, password) VALUES (@Username, @Password); END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_password] **/ /** Retrive the user password **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_password] @Username varchar(200) AS BEGIN SELECT users.password as password FROM users WITH (NOLOCK) WHERE username=@Username; END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[set_roster_version] **/ /** Update users roster_version **/ /******************************************************************/ CREATE PROCEDURE [dbo].[set_roster_version] @Username varchar(200), @Version varchar(8000) AS BEGIN IF EXISTS (SELECT username FROM roster_version WITH (NOLOCK) WHERE username=@Username) BEGIN UPDATE roster_version SET username=@Username, version=@Version WHERE username=@Username; END ELSE BEGIN INSERT INTO roster_version (username, version) VALUES (@Username, @Version); END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_roster_version] **/ /** Retrive the user roster_version **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_roster_version] @Username varchar(200) AS BEGIN SELECT roster_version.version as version FROM roster_version WITH (NOLOCK) WHERE username=@Username; END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[clean_spool_msg] ******/ /** Delete messages older that 3 days from spool **/ /***************************************************************/ CREATE PROCEDURE [dbo].[clean_spool_msg] AS DECLARE @dt datetime, @myRowCount int BEGIN -- Delete small amounts because if locks the database table SET ROWCOUNT 500 SET @myRowCount = 1 WHILE (@myRowCount) > 0 BEGIN BEGIN TRANSACTION SELECT @dt = DATEADD(d, -3, GETDATE()) DELETE FROM spool WITH (ROWLOCK) WHERE (MustDelete=1) OR (Created < @dt); SET @myRowCount = @@RowCount COMMIT END END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[del_last] ******/ /** Delete an entry from the last table **/ /***************************************************************/ CREATE PROCEDURE [dbo].[del_last] @Username varchar(250) AS BEGIN DELETE FROM [last] WITH (ROWLOCK) WHERE [last].username=@Username; END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[del_roster] ******/ /** Delete an entry from the roster **/ /***************************************************************/ CREATE PROCEDURE [dbo].[del_roster] @Username varchar(250), @JID varchar(250) AS BEGIN BEGIN TRANSACTION DELETE FROM rosterusers WITH (ROWLOCK) WHERE (rosterusers.username = @Username) AND (rosterusers.jid = @JID); DELETE FROM rostergroups WITH (ROWLOCK) WHERE (rostergroups.username = @Username) AND (rostergroups.jid = @JID); COMMIT END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[del_spool_msg] ******/ /** Delete an entry from the spool table **/ /***************************************************************/ CREATE PROCEDURE [dbo].[del_spool_msg] @Username varchar(250) AS BEGIN DELETE FROM spool WITH (ROWLOCK) WHERE spool.username=@Username; END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[del_user] ******/ /** Delete an entry from the user table **/ /***************************************************************/ CREATE PROCEDURE [dbo].[del_user] @Username varchar(200) AS BEGIN DELETE FROM users WITH (ROWLOCK) WHERE username=@Username; END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[del_user_return_password]**/ /** Delete an entry from the user table and return user password **/ /******************************************************************/ CREATE PROCEDURE [dbo].[del_user_return_password] @Username varchar(250) AS DECLARE @Pwd varchar(50) BEGIN EXECUTE @Pwd = dbo.get_password @Username DELETE FROM users WITH (ROWLOCK) WHERE username=@Username SELECT @Pwd; END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[del_user_roster] **/ /** Delete the users roster **/ /******************************************************************/ CREATE PROCEDURE [dbo].[del_user_roster] @Username varchar(250) AS BEGIN BEGIN TRANSACTION DELETE FROM rosterusers WITH (ROWLOCK) WHERE rosterusers.username = @Username; DELETE FROM rostergroups WITH (ROWLOCK) WHERE rostergroups.username = @Username; COMMIT END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_and_del_spool_msg] **/ /** Fetch and delete the users offline messages **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_and_del_spool_msg] @Username varchar(250) AS DECLARE @vSpool table( username varchar(1), xml varchar(1)) BEGIN IF EXISTS (SELECT username FROM spool with (nolock) WHERE spool.username=@Username) BEGIN SELECT spool.username AS username, spool.xml AS xml FROM spool WITH (NOLOCK) WHERE spool.username=@Username; DELETE spool WITH (ROWLOCK) WHERE spool.username=@Username END ELSE BEGIN SELECT * FROM @vSpool; END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_last] **/ /** Retrive the last user login **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_last] @Username varchar(250) AS BEGIN SELECT last.seconds AS seconds, last.state AS state FROM last WITH (NOLOCK) WHERE last.username=@Username; END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_roster] **/ /** Retrive the user roster **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_roster] @Username varchar(250) AS DECLARE @vRosterusers table( username varchar(1), jid varchar(1), nick varchar(1), subscription varchar(1), ask varchar(1), askmessage varchar(1), server varchar(1), subscribe varchar(1), type varchar(1)) BEGIN IF EXISTS (SELECT username FROM rosterusers with (nolock) WHERE rosterusers.username = @Username) BEGIN SELECT rosterusers.username AS username, rosterusers.jid AS jid, rosterusers.nick AS nick, rosterusers.subscription AS subscription, rosterusers.ask AS ask, rosterusers.askmessage AS askmessage, rosterusers.server AS server, rosterusers.subscribe AS subscribe, rosterusers.type AS type FROM rosterusers WITH (NOLOCK) WHERE rosterusers.username = @Username; END ELSE BEGIN SELECT * FROM @vRosterusers END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_roster_by_jid] **/ /** Retrive the user roster via JID **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_roster_by_jid] @Username varchar(200), @JID varchar(250) AS DECLARE @vRosterusers table( username varchar(1), jid varchar(1), nick varchar(1), subscription varchar(1), ask varchar(1), askmessage varchar(1), server varchar(1), subscribe varchar(1), type varchar(1)) BEGIN IF EXISTS (SELECT username FROM rosterusers with (nolock) WHERE (rosterusers.username = @Username) AND (rosterusers.jid = @JID)) BEGIN SELECT rosterusers.username AS username, rosterusers.jid AS jid, rosterusers.nick AS nick, rosterusers.subscription AS subscription, rosterusers.ask AS ask, rosterusers.askmessage AS askmessage, rosterusers.server AS server, rosterusers.subscribe AS subscribe, rosterusers.type AS type FROM rosterusers WITH (NOLOCK) WHERE (rosterusers.username = @Username) AND (rosterusers.jid = @JID); END ELSE BEGIN SELECT * FROM @vRosterusers END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_roster_jid_groups] **/ /** Retrieve the user roster groups **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_roster_jid_groups] @Username varchar(200) AS DECLARE @vrostergroups table( jid varchar(1), grp varchar(1)) BEGIN IF EXISTS (SELECT username FROM rostergroups with (nolock) WHERE rostergroups.username = @Username) BEGIN SELECT rostergroups.jid AS jid, rostergroups.grp AS grp FROM rostergroups WITH (NOLOCK) WHERE rostergroups.username = @Username; END ELSE BEGIN SELECT * FROM @vrostergroups END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_roster_groups] **/ /** Retrive the user roster groups **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_roster_groups] @Username varchar(200), @JID varchar(250) AS DECLARE @vrostergroups table( grp varchar(1)) BEGIN IF EXISTS (SELECT username FROM rostergroups with (nolock) WHERE rostergroups.username = @Username) BEGIN SELECT rostergroups.grp AS grp FROM rostergroups WITH (NOLOCK) WHERE (rostergroups.username = @Username) AND (rostergroups.jid = @JID); END ELSE BEGIN SELECT * FROM @vrostergroups END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_rostergroup_by_jid] **/ /** Retrive the user roster groups via JID **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_rostergroup_by_jid] @Username varchar(250), @JID varchar(250) AS DECLARE @vrostergroups table(grp varchar(1)) BEGIN IF EXISTS (SELECT username FROM rostergroups with (nolock) WHERE rostergroups.username=@Username AND rostergroups.jid=@JID) BEGIN SELECT rostergroups.grp AS grp FROM rostergroups WITH (NOLOCK) WHERE rostergroups.username=@Username AND rostergroups.jid=@JID; END ELSE BEGIN SELECT * FROM @vrostergroups END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_subscription] **/ /** Retrive the user subscription requests **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_subscription] @Username varchar(250), @JID varchar(250) AS DECLARE @vrosterusers table( subscription varchar(1)) BEGIN IF EXISTS (SELECT username FROM rosterusers with (nolock) WHERE rosterusers.username=@Username AND rosterusers.jid=@JID) BEGIN SELECT rosterusers.subscription AS subscription FROM rosterusers WITH (NOLOCK) WHERE rosterusers.username=@Username AND rosterusers.jid=@JID; END ELSE BEGIN SELECT * FROM @vrosterusers END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[list_users] **/ /** Retrieve a list of all users **/ /******************************************************************/ CREATE PROCEDURE [dbo].[list_users] AS BEGIN SELECT users.username AS username FROM users WITH (NOLOCK); END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[set_last] **/ /** Update users last login status **/ /******************************************************************/ CREATE PROCEDURE [dbo].[set_last] @Username varchar(250), @Seconds varchar(50), @State varchar(100) AS BEGIN IF EXISTS (SELECT username FROM [last] WITH (NOLOCK) WHERE username=@Username) BEGIN UPDATE [last] SET [last].username = @Username, [last].seconds = @Seconds, [last].state = @State WHERE last.username=@Username; END ELSE BEGIN INSERT INTO [last] ( [last].username, [last].seconds, [last].state ) VALUES ( @Username, @Seconds, @State ) END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[set_private_data] **/ /** store user private data by namespace **/ /******************************************************************/ CREATE PROCEDURE [dbo].[set_private_data] @Username varchar(250), @Namespace varchar(250), @Data varchar(8000) AS BEGIN IF EXISTS (SELECT username FROM private_storage with (nolock) WHERE private_storage.username = @Username AND private_storage.namespace = @Namespace) BEGIN UPDATE [private_storage] SET [private_storage].username = @Username, [private_storage].namespace = @Namespace, [private_storage].data = @Data WHERE private_storage.username = @Username AND private_storage.namespace = @Namespace; END ELSE BEGIN INSERT INTO [private_storage] ( [private_storage].username, [private_storage].namespace, [private_storage].data ) VALUES ( @Username, @Namespace, @Data ) END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_private_data] **/ /** Retrieve user private data by namespace **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_private_data] @Username varchar(250), @Namespace varchar(250) AS BEGIN SELECT private_storage.data AS data FROM private_storage WITH (NOLOCK) WHERE username=@Username and namespace=@Namespace; END GO /***************************************************************/ /****** Object: StoredProcedure [dbo].[del_user_storage] ******/ /** Delete private storage area for a given user **/ /***************************************************************/ CREATE PROCEDURE [dbo].[del_user_storage] @Username varchar(250) AS BEGIN DELETE FROM [private_storage] WITH (ROWLOCK) WHERE [private_storage].username=@Username; END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[set_vcard] **/ /** Set the user's vCard **/ /******************************************************************/ CREATE PROCEDURE [dbo].[set_vcard] @VCard varchar(8000), @Username varchar(250), @Lusername varchar(250), @Fn varchar(8000), @Lfn varchar(250), @Family varchar(8000), @Lfamily varchar(250), @Given varchar(8000), @Lgiven varchar(250), @Middle varchar(8000), @Lmiddle varchar(250), @Nickname varchar(8000), @Lnickname varchar(250), @Bday varchar(8000), @Lbday varchar(250), @Ctry varchar(8000), @Lctry varchar(250), @Locality varchar(8000), @Llocality varchar(250), @Email varchar(8000), @Lemail varchar(250), @Orgname varchar(8000), @Lorgname varchar(250), @Orgunit varchar(8000), @Lorgunit varchar(250) AS BEGIN IF EXISTS (SELECT username FROM vcard with (nolock) WHERE vcard.username = @Username) BEGIN UPDATE [vcard] SET [vcard].username = @LUsername, [vcard].vcard = @Vcard WHERE vcard.username = @LUsername; UPDATE [vcard_search] SET [vcard_search].username = @Username, [vcard_search].lusername = @Lusername, [vcard_search].fn = @Fn, [vcard_search].lfn = @Lfn, [vcard_search].family = @Family, [vcard_search].lfamily = @Lfamily, [vcard_search].given = @Given, [vcard_search].lgiven = @Lgiven, [vcard_search].middle = @Middle, [vcard_search].lmiddle = @Lmiddle, [vcard_search].nickname = @Nickname, [vcard_search].lnickname = @Lnickname, [vcard_search].bday = @Bday, [vcard_search].lbday = @Lbday, [vcard_search].ctry = @Ctry, [vcard_search].lctry = @Lctry, [vcard_search].locality = @Locality, [vcard_search].llocality = @Llocality, [vcard_search].email = @Email, [vcard_search].lemail = @Lemail, [vcard_search].orgname = @Orgname, [vcard_search].lorgname = @Lorgname, [vcard_search].orgunit = @Orgunit, [vcard_search].lorgunit = @Lorgunit WHERE vcard_search.lusername = @LUsername; END ELSE BEGIN INSERT INTO [vcard] ( [vcard].username, [vcard].vcard ) VALUES ( @lUsername, @Vcard ); INSERT INTO [vcard_search] ( [vcard_search].username , [vcard_search].lusername , [vcard_search].fn , [vcard_search].lfn , [vcard_search].family , [vcard_search].lfamily , [vcard_search].given , [vcard_search].lgiven , [vcard_search].middle , [vcard_search].lmiddle , [vcard_search].nickname, [vcard_search].lnickname, [vcard_search].bday, [vcard_search].lbday, [vcard_search].ctry, [vcard_search].lctry, [vcard_search].locality, [vcard_search].llocality, [vcard_search].email, [vcard_search].lemail, [vcard_search].orgname, [vcard_search].lorgname, [vcard_search].orgunit, [vcard_search].lorgunit ) VALUES ( @Username, @Lusername, @Fn, @Lfn, @Family, @Lfamily, @Given, @Lgiven, @Middle, @Lmiddle, @Nickname, @Lnickname, @Bday, @Lbday, @Ctry, @Lctry, @Locality, @Llocality, @Email, @Lemail, @Orgname, @Lorgname, @Orgunit, @Lorgunit ) END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_vcard] **/ /** Retrive the user's vCard **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_vcard] @Username varchar(250) AS BEGIN SELECT vcard.vcard as vcard FROM vcard WITH (NOLOCK) WHERE username=@Username; END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_default_privacy_list]**/ /** Retrive the user's default privacy list **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_default_privacy_list] @Username varchar(250) AS BEGIN SELECT list.name FROM privacy_default_list list WITH (NOLOCK) WHERE list.username=@Username END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_privacy_list_names] **/ /** Retrive the user's default privacy list names **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_privacy_list_names] @username varchar(250) AS BEGIN SELECT list.name FROM privacy_list list WITH (NOLOCK) WHERE list.username=@Username END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_privacy_list_id] **/ /** **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_privacy_list_id] @username varchar(250), @SName varchar(250) AS BEGIN SELECT id FROM privacy_list WHERE username=@Username AND name=@SName END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_privacy_list_data] **/ /** **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_privacy_list_data] @username varchar(250), @SName varchar(250) AS BEGIN SELECT l_data.t, l_data.value, l_data.action, l_data.ord, l_data.match_all, l_data.match_iq, l_data.match_message, l_data.match_presence_in, l_data.match_presence_out FROM privacy_list_data l_data (NOLOCK) WHERE l_data.id = (SELECT list.id FROM privacy_list list WHERE list.username=@username AND list.name=@SName) ORDER BY l_data.ord END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[get_privacy_list_data_by_id]**/ /** **/ /******************************************************************/ CREATE PROCEDURE [dbo].[get_privacy_list_data_by_id] @Id bigint AS BEGIN SELECT l_data.t, l_data.value, l_data.action, l_data.ord, l_data.match_all, l_data.match_iq, l_data.match_message, l_data.match_presence_in, l_data.match_presence_out FROM privacy_list_data l_data (NOLOCK) WHERE l_data.id=@ID ORDER BY l_data.ord END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[set_default_privacy_list]**/ /** **/ /******************************************************************/ CREATE PROCEDURE [dbo].[set_default_privacy_list] @username varchar(250), @Sname varchar(250) AS BEGIN IF EXISTS (SELECT username FROM privacy_default_list with (nolock) WHERE privacy_default_list.username = @Username AND privacy_default_list.name = @Sname) BEGIN UPDATE [privacy_default_list] SET [privacy_default_list].username = @Username, [privacy_default_list].name = @Sname WHERE privacy_default_list.username = @Username END ELSE BEGIN INSERT INTO [privacy_default_list] ( [privacy_default_list].username, [privacy_default_list].name ) VALUES ( @Username, @SName ) END END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[unset_default_privacy_list]**/ /** **/ /******************************************************************/ CREATE PROCEDURE [dbo].[unset_default_privacy_list] @username varchar(250) AS BEGIN DELETE FROM privacy_default_list WHERE privacy_default_list.username=@username END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[remove_privacy_list] **/ /** **/ /******************************************************************/ CREATE PROCEDURE [dbo].[remove_privacy_list] @username varchar(250), @SName varchar(250) AS BEGIN DELETE FROM privacy_list WHERE privacy_list.username=@username AND privacy_list.name=@SName END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[add_privacy_list] **/ /** **/ /******************************************************************/ CREATE PROCEDURE [dbo].[add_privacy_list] @username varchar(250), @SName varchar(250) AS BEGIN INSERT INTO privacy_list(username, name) VALUES (@username, @SName) END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[set_privacy_list] **/ /** **/ /******************************************************************/ CREATE PROCEDURE [dbo].[set_privacy_list] @Id bigint, @t char(1), @value text, @action char(1), @ord numeric, @match_all bit, @match_iq bit, @match_message bit, @match_presence_in bit, @match_presence_out bit AS BEGIN insert into privacy_list_data ( id, t, value, action, ord, match_all, match_iq, match_message, match_presence_in, match_presence_out ) values (@Id, @t, @value, @action, @ord, @match_all, @match_iq, @match_message, @match_presence_in, @match_presence_out ) END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[del_privacy_list_by_id] **/ /** **/ /******************************************************************/ CREATE PROCEDURE [dbo].[del_privacy_list_by_id] @Id bigint AS BEGIN DELETE FROM privacy_list_data WHERE privacy_list_data.id=@Id END GO /******************************************************************/ /****** Object: StoredProcedure [dbo].[del_privacy_lists] **/ /** **/ /******************************************************************/ CREATE PROCEDURE [dbo].[del_privacy_lists] @Server varchar(250), @username varchar(250) AS BEGIN DELETE FROM privacy_list WHERE username=@username DELETE FROM privacy_list_data WHERE convert(varchar,value)=@username+'@'+@Server DELETE FROM privacy_default_list WHERE username=@username END GO ejabberd-2.1.11/src/odbc/pg.sql0000664000000000000000000001777712240230175013066 0ustar -- -- ejabberd, Copyright (C) 2002-2012 ProcessOne -- -- 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., 59 Temple Place, Suite 330, Boston, MA -- 02111-1307 USA -- CREATE TABLE users ( username text PRIMARY KEY, "password" text NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT now() ); CREATE TABLE last ( username text PRIMARY KEY, seconds text NOT NULL, state text NOT NULL ); CREATE TABLE rosterusers ( username text NOT NULL, jid text NOT NULL, nick text NOT NULL, subscription character(1) NOT NULL, ask character(1) NOT NULL, askmessage text NOT NULL, server character(1) NOT NULL, subscribe text, "type" text, created_at TIMESTAMP NOT NULL DEFAULT now() ); CREATE UNIQUE INDEX i_rosteru_user_jid ON rosterusers USING btree (username, jid); CREATE INDEX i_rosteru_username ON rosterusers USING btree (username); CREATE INDEX i_rosteru_jid ON rosterusers USING btree (jid); CREATE TABLE rostergroups ( username text NOT NULL, jid text NOT NULL, grp text NOT NULL ); CREATE INDEX pk_rosterg_user_jid ON rostergroups USING btree (username, jid); CREATE TABLE sr_group ( name text NOT NULL, opts text NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT now() ); CREATE TABLE sr_user ( jid text NOT NULL, grp text NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT now() ); CREATE UNIQUE INDEX i_sr_user_jid_grp ON sr_user USING btree (jid, grp); CREATE INDEX i_sr_user_jid ON sr_user USING btree (jid); CREATE INDEX i_sr_user_grp ON sr_user USING btree (grp); CREATE TABLE spool ( username text NOT NULL, xml text NOT NULL, seq SERIAL, created_at TIMESTAMP NOT NULL DEFAULT now() ); CREATE INDEX i_despool ON spool USING btree (username); CREATE TABLE vcard ( username text PRIMARY KEY, vcard text NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT now() ); CREATE TABLE vcard_xupdate ( username text PRIMARY KEY, hash text NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT now() ); CREATE TABLE vcard_search ( username text NOT NULL, lusername text PRIMARY KEY, fn text NOT NULL, lfn text NOT NULL, family text NOT NULL, lfamily text NOT NULL, given text NOT NULL, lgiven text NOT NULL, middle text NOT NULL, lmiddle text NOT NULL, nickname text NOT NULL, lnickname text NOT NULL, bday text NOT NULL, lbday text NOT NULL, ctry text NOT NULL, lctry text NOT NULL, locality text NOT NULL, llocality text NOT NULL, email text NOT NULL, lemail text NOT NULL, orgname text NOT NULL, lorgname text NOT NULL, orgunit text NOT NULL, lorgunit text NOT NULL ); CREATE INDEX i_vcard_search_lfn ON vcard_search(lfn); CREATE INDEX i_vcard_search_lfamily ON vcard_search(lfamily); CREATE INDEX i_vcard_search_lgiven ON vcard_search(lgiven); CREATE INDEX i_vcard_search_lmiddle ON vcard_search(lmiddle); CREATE INDEX i_vcard_search_lnickname ON vcard_search(lnickname); CREATE INDEX i_vcard_search_lbday ON vcard_search(lbday); CREATE INDEX i_vcard_search_lctry ON vcard_search(lctry); CREATE INDEX i_vcard_search_llocality ON vcard_search(llocality); CREATE INDEX i_vcard_search_lemail ON vcard_search(lemail); CREATE INDEX i_vcard_search_lorgname ON vcard_search(lorgname); CREATE INDEX i_vcard_search_lorgunit ON vcard_search(lorgunit); CREATE TABLE privacy_default_list ( username text PRIMARY KEY, name text NOT NULL ); CREATE TABLE privacy_list ( username text NOT NULL, name text NOT NULL, id SERIAL UNIQUE, created_at TIMESTAMP NOT NULL DEFAULT now() ); CREATE INDEX i_privacy_list_username ON privacy_list USING btree (username); CREATE UNIQUE INDEX i_privacy_list_username_name ON privacy_list USING btree (username, name); CREATE TABLE privacy_list_data ( id bigint REFERENCES privacy_list(id) ON DELETE CASCADE, t character(1) NOT NULL, value text NOT NULL, action character(1) NOT NULL, ord NUMERIC NOT NULL, match_all boolean NOT NULL, match_iq boolean NOT NULL, match_message boolean NOT NULL, match_presence_in boolean NOT NULL, match_presence_out boolean NOT NULL ); CREATE TABLE private_storage ( username text NOT NULL, namespace text NOT NULL, data text NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT now() ); CREATE INDEX i_private_storage_username ON private_storage USING btree (username); CREATE UNIQUE INDEX i_private_storage_username_namespace ON private_storage USING btree (username, namespace); CREATE TABLE roster_version ( username text PRIMARY KEY, version text NOT NULL ); -- To update from 0.9.8: -- CREATE SEQUENCE spool_seq_seq; -- ALTER TABLE spool ADD COLUMN seq integer; -- ALTER TABLE spool ALTER COLUMN seq SET DEFAULT nextval('spool_seq_seq'); -- UPDATE spool SET seq = DEFAULT; -- ALTER TABLE spool ALTER COLUMN seq SET NOT NULL; -- To update from 1.x: -- ALTER TABLE rosterusers ADD COLUMN askmessage text; -- UPDATE rosterusers SET askmessage = ''; -- ALTER TABLE rosterusers ALTER COLUMN askmessage SET NOT NULL; CREATE TABLE pubsub_node ( host text, node text, parent text, "type" text, nodeid SERIAL UNIQUE ); CREATE INDEX i_pubsub_node_parent ON pubsub_node USING btree (parent); CREATE UNIQUE INDEX i_pubsub_node_tuple ON pubsub_node USING btree (host, node); CREATE TABLE pubsub_node_option ( nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE, name text, val text ); CREATE INDEX i_pubsub_node_option_nodeid ON pubsub_node_option USING btree (nodeid); CREATE TABLE pubsub_node_owner ( nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE, owner text ); CREATE INDEX i_pubsub_node_owner_nodeid ON pubsub_node_owner USING btree (nodeid); CREATE TABLE pubsub_state ( nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE, jid text, affiliation character(1), subscriptions text, stateid SERIAL UNIQUE ); CREATE INDEX i_pubsub_state_jid ON pubsub_state USING btree (jid); CREATE UNIQUE INDEX i_pubsub_state_tuple ON pubsub_state USING btree (nodeid, jid); CREATE TABLE pubsub_item ( nodeid bigint REFERENCES pubsub_node(nodeid) ON DELETE CASCADE, itemid text, publisher text, creation text, modification text, payload text ); CREATE INDEX i_pubsub_item_itemid ON pubsub_item USING btree (itemid); CREATE UNIQUE INDEX i_pubsub_item_tuple ON pubsub_item USING btree (nodeid, itemid); CREATE TABLE pubsub_subscription_opt ( subid text, opt_name varchar(32), opt_value text ); CREATE UNIQUE INDEX i_pubsub_subscription_opt ON pubsub_subscription_opt USING btree (subid, opt_name); CREATE TABLE muc_room ( name text NOT NULL, host text NOT NULL, opts text NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT now() ); CREATE UNIQUE INDEX i_muc_room_name_host ON muc_room USING btree (name, host); CREATE TABLE muc_registered ( jid text NOT NULL, host text NOT NULL, nick text NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT now() ); CREATE INDEX i_muc_registered_nick ON muc_registered USING btree (nick); CREATE UNIQUE INDEX i_muc_registered_jid_host ON muc_registered USING btree (jid, host); CREATE TABLE irc_custom ( jid text NOT NULL, host text NOT NULL, data text NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT now() ); CREATE UNIQUE INDEX i_irc_custom_jid_host ON irc_custom USING btree (jid, host); CREATE TABLE motd ( username text PRIMARY KEY, xml text, created_at TIMESTAMP NOT NULL DEFAULT now() ); ejabberd-2.1.11/src/odbc/mysql.sql0000664000000000000000000002161412240230175013606 0ustar -- -- ejabberd, Copyright (C) 2002-2012 ProcessOne -- -- 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., 59 Temple Place, Suite 330, Boston, MA -- 02111-1307 USA -- -- Needs MySQL (at least 4.0.x) with innodb back-end SET table_type=InnoDB; CREATE TABLE users ( username varchar(250) PRIMARY KEY, password text NOT NULL, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; CREATE TABLE last ( username varchar(250) PRIMARY KEY, seconds text NOT NULL, state text NOT NULl ) CHARACTER SET utf8; CREATE TABLE rosterusers ( username varchar(250) NOT NULL, jid varchar(250) NOT NULL, nick text NOT NULL, subscription character(1) NOT NULL, ask character(1) NOT NULL, askmessage text NOT NULL, server character(1) NOT NULL, subscribe text NOT NULL, type text, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; CREATE UNIQUE INDEX i_rosteru_user_jid ON rosterusers(username(75), jid(75)); CREATE INDEX i_rosteru_username ON rosterusers(username); CREATE INDEX i_rosteru_jid ON rosterusers(jid); CREATE TABLE rostergroups ( username varchar(250) NOT NULL, jid varchar(250) NOT NULL, grp text NOT NULL ) CHARACTER SET utf8; CREATE INDEX pk_rosterg_user_jid ON rostergroups(username(75), jid(75)); CREATE TABLE sr_group ( name varchar(250) NOT NULL, opts text NOT NULL, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; CREATE TABLE sr_user ( jid varchar(250) NOT NULL, grp varchar(250) NOT NULL, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; CREATE UNIQUE INDEX i_sr_user_jid_group ON sr_user(jid(75), grp(75)); CREATE INDEX i_sr_user_jid ON sr_user(jid); CREATE INDEX i_sr_user_grp ON sr_user(grp); CREATE TABLE spool ( username varchar(250) NOT NULL, xml text NOT NULL, seq BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; CREATE INDEX i_despool USING BTREE ON spool(username); CREATE TABLE vcard ( username varchar(250) PRIMARY KEY, vcard mediumtext NOT NULL, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; CREATE TABLE vcard_xupdate ( username varchar(250) PRIMARY KEY, hash text NOT NULL, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; CREATE TABLE vcard_search ( username varchar(250) NOT NULL, lusername varchar(250) PRIMARY KEY, fn text NOT NULL, lfn varchar(250) NOT NULL, family text NOT NULL, lfamily varchar(250) NOT NULL, given text NOT NULL, lgiven varchar(250) NOT NULL, middle text NOT NULL, lmiddle varchar(250) NOT NULL, nickname text NOT NULL, lnickname varchar(250) NOT NULL, bday text NOT NULL, lbday varchar(250) NOT NULL, ctry text NOT NULL, lctry varchar(250) NOT NULL, locality text NOT NULL, llocality varchar(250) NOT NULL, email text NOT NULL, lemail varchar(250) NOT NULL, orgname text NOT NULL, lorgname varchar(250) NOT NULL, orgunit text NOT NULL, lorgunit varchar(250) NOT NULL ) CHARACTER SET utf8; CREATE INDEX i_vcard_search_lfn ON vcard_search(lfn); CREATE INDEX i_vcard_search_lfamily ON vcard_search(lfamily); CREATE INDEX i_vcard_search_lgiven ON vcard_search(lgiven); CREATE INDEX i_vcard_search_lmiddle ON vcard_search(lmiddle); CREATE INDEX i_vcard_search_lnickname ON vcard_search(lnickname); CREATE INDEX i_vcard_search_lbday ON vcard_search(lbday); CREATE INDEX i_vcard_search_lctry ON vcard_search(lctry); CREATE INDEX i_vcard_search_llocality ON vcard_search(llocality); CREATE INDEX i_vcard_search_lemail ON vcard_search(lemail); CREATE INDEX i_vcard_search_lorgname ON vcard_search(lorgname); CREATE INDEX i_vcard_search_lorgunit ON vcard_search(lorgunit); CREATE TABLE privacy_default_list ( username varchar(250) PRIMARY KEY, name varchar(250) NOT NULL ) CHARACTER SET utf8; CREATE TABLE privacy_list ( username varchar(250) NOT NULL, name varchar(250) NOT NULL, id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; CREATE INDEX i_privacy_list_username USING BTREE ON privacy_list(username); CREATE UNIQUE INDEX i_privacy_list_username_name USING BTREE ON privacy_list (username(75), name(75)); CREATE TABLE privacy_list_data ( id bigint, t character(1) NOT NULL, value text NOT NULL, action character(1) NOT NULL, ord NUMERIC NOT NULL, match_all boolean NOT NULL, match_iq boolean NOT NULL, match_message boolean NOT NULL, match_presence_in boolean NOT NULL, match_presence_out boolean NOT NULL ) CHARACTER SET utf8; CREATE TABLE private_storage ( username varchar(250) NOT NULL, namespace varchar(250) NOT NULL, data text NOT NULL, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; CREATE INDEX i_private_storage_username USING BTREE ON private_storage(username); CREATE UNIQUE INDEX i_private_storage_username_namespace USING BTREE ON private_storage(username(75), namespace(75)); -- Not tested in mysql CREATE TABLE roster_version ( username varchar(250) PRIMARY KEY, version text NOT NULL ) CHARACTER SET utf8; -- To update from 1.x: -- ALTER TABLE rosterusers ADD COLUMN askmessage text AFTER ask; -- UPDATE rosterusers SET askmessage = ''; -- ALTER TABLE rosterusers ALTER COLUMN askmessage SET NOT NULL; CREATE TABLE pubsub_node ( host text, node text, parent text, type text, nodeid bigint auto_increment primary key ) CHARACTER SET utf8; CREATE INDEX i_pubsub_node_parent ON pubsub_node(parent(120)); CREATE UNIQUE INDEX i_pubsub_node_tuple ON pubsub_node(host(20), node(120)); CREATE TABLE pubsub_node_option ( nodeid bigint, name text, val text ) CHARACTER SET utf8; CREATE INDEX i_pubsub_node_option_nodeid ON pubsub_node_option(nodeid); ALTER TABLE `pubsub_node_option` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE; CREATE TABLE pubsub_node_owner ( nodeid bigint, owner text ) CHARACTER SET utf8; CREATE INDEX i_pubsub_node_owner_nodeid ON pubsub_node_owner(nodeid); ALTER TABLE `pubsub_node_owner` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE; CREATE TABLE pubsub_state ( nodeid bigint, jid text, affiliation character(1), subscriptions text, stateid bigint auto_increment primary key ) CHARACTER SET utf8; CREATE INDEX i_pubsub_state_jid ON pubsub_state(jid(60)); CREATE UNIQUE INDEX i_pubsub_state_tuple ON pubsub_state(nodeid, jid(60)); ALTER TABLE `pubsub_state` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE; CREATE TABLE pubsub_item ( nodeid bigint, itemid text, publisher text, creation text, modification text, payload text ) CHARACTER SET utf8; CREATE INDEX i_pubsub_item_itemid ON pubsub_item(itemid(36)); CREATE UNIQUE INDEX i_pubsub_item_tuple ON pubsub_item(nodeid, itemid(36)); ALTER TABLE `pubsub_item` ADD FOREIGN KEY (`nodeid`) REFERENCES `pubsub_node` (`nodeid`) ON DELETE CASCADE; CREATE TABLE pubsub_subscription_opt ( subid text, opt_name varchar(32), opt_value text ); CREATE UNIQUE INDEX i_pubsub_subscription_opt ON pubsub_subscription_opt(subid(32), opt_name(32)); CREATE TABLE muc_room ( name text NOT NULL, host text NOT NULL, opts text NOT NULL, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; CREATE UNIQUE INDEX i_muc_room_name_host USING BTREE ON muc_room(name(75), host(75)); CREATE TABLE muc_registered ( jid text NOT NULL, host text NOT NULL, nick text NOT NULL, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; CREATE INDEX i_muc_registered_nick USING BTREE ON muc_registered(nick(75)); CREATE UNIQUE INDEX i_muc_registered_jid_host USING BTREE ON muc_registered(jid(75), host(75)); CREATE TABLE irc_custom ( jid text NOT NULL, host text NOT NULL, data text NOT NULL, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; CREATE UNIQUE INDEX i_irc_custom_jid_host USING BTREE ON irc_custom(jid(75), host(75)); CREATE TABLE motd ( username varchar(250) PRIMARY KEY, xml text, created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ) CHARACTER SET utf8; ejabberd-2.1.11/src/mod_privacy.hrl0000664000000000000000000000240712240230175014033 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -record(privacy, {us, default = none, lists = []}). -record(listitem, {type = none, value = none, action, order, match_all = false, match_iq = false, match_message = false, match_presence_in = false, match_presence_out = false }). -record(userlist, {name = none, list = [], needdb = false }). ejabberd-2.1.11/src/mod_roster_odbc.erl0000664000000000000000000011436712240230175014671 0ustar %%%---------------------------------------------------------------------- %%% File : mod_roster_odbc.erl %%% Author : Alexey Shchepin %%% Purpose : Roster management %%% Created : 15 Dec 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %%% @doc Roster management (Mnesia storage). %%% %%% Includes support for XEP-0237: Roster Versioning. %%% The roster versioning follows an all-or-nothing strategy: %%% - If the version supplied by the client is the latest, return an empty response. %%% - If not, return the entire new roster (with updated version string). %%% Roster version is a hash digest of the entire roster. %%% No additional data is stored in DB. -module(mod_roster_odbc). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_iq/3, process_local_iq/3, get_user_roster/2, get_subscription_lists/3, get_in_pending_subscriptions/3, in_subscription/6, out_subscription/4, set_items/3, remove_user/2, get_jid_info/4, webadmin_page/3, webadmin_user/4, get_versioning_feature/2, roster_versioning_enabled/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_roster.hrl"). -include("web/ejabberd_http.hrl"). -include("web/ejabberd_web_admin.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), ejabberd_hooks:add(roster_get, Host, ?MODULE, get_user_roster, 50), ejabberd_hooks:add(roster_in_subscription, Host, ?MODULE, in_subscription, 50), ejabberd_hooks:add(roster_out_subscription, Host, ?MODULE, out_subscription, 50), ejabberd_hooks:add(roster_get_subscription_lists, Host, ?MODULE, get_subscription_lists, 50), ejabberd_hooks:add(roster_get_jid_info, Host, ?MODULE, get_jid_info, 50), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:add(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), ejabberd_hooks:add(resend_subscription_requests_hook, Host, ?MODULE, get_in_pending_subscriptions, 50), ejabberd_hooks:add(roster_get_versioning_feature, Host, ?MODULE, get_versioning_feature, 50), ejabberd_hooks:add(webadmin_page_host, Host, ?MODULE, webadmin_page, 50), ejabberd_hooks:add(webadmin_user, Host, ?MODULE, webadmin_user, 50), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER, ?MODULE, process_iq, IQDisc). stop(Host) -> ejabberd_hooks:delete(roster_get, Host, ?MODULE, get_user_roster, 50), ejabberd_hooks:delete(roster_in_subscription, Host, ?MODULE, in_subscription, 50), ejabberd_hooks:delete(roster_out_subscription, Host, ?MODULE, out_subscription, 50), ejabberd_hooks:delete(roster_get_subscription_lists, Host, ?MODULE, get_subscription_lists, 50), ejabberd_hooks:delete(roster_get_jid_info, Host, ?MODULE, get_jid_info, 50), ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(resend_subscription_requests_hook, Host, ?MODULE, get_in_pending_subscriptions, 50), ejabberd_hooks:delete(roster_get_versioning_feature, Host, ?MODULE, get_versioning_feature, 50), ejabberd_hooks:delete(webadmin_page_host, Host, ?MODULE, webadmin_page, 50), ejabberd_hooks:delete(webadmin_user, Host, ?MODULE, webadmin_user, 50), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER). process_iq(From, To, IQ) -> #iq{sub_el = SubEl} = IQ, #jid{lserver = LServer} = From, case lists:member(LServer, ?MYHOSTS) of true -> process_local_iq(From, To, IQ); _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]} end. process_local_iq(From, To, #iq{type = Type} = IQ) -> case Type of set -> process_iq_set(From, To, IQ); get -> process_iq_get(From, To, IQ) end. roster_hash(Items) -> sha:sha(term_to_binary( lists:sort( [R#roster{groups = lists:sort(Grs)} || R = #roster{groups = Grs} <- Items]))). roster_versioning_enabled(Host) -> gen_mod:get_module_opt(Host, ?MODULE, versioning, false). roster_version_on_db(Host) -> gen_mod:get_module_opt(Host, ?MODULE, store_current_id, false). %% Returns a list that may contain an xmlelement with the XEP-237 feature if it's enabled. get_versioning_feature(Acc, Host) -> case roster_versioning_enabled(Host) of true -> Feature = {xmlelement, "ver", [{"xmlns", ?NS_ROSTER_VER}], [{xmlelement, "optional", [], []}]}, [Feature | Acc]; false -> [] end. roster_version(LServer ,LUser) -> US = {LUser, LServer}, case roster_version_on_db(LServer) of true -> case odbc_queries:get_roster_version(ejabberd_odbc:escape(LServer), ejabberd_odbc:escape(LUser)) of {selected, ["version"], [{Version}]} -> Version; {selected, ["version"], []} -> %% If for some reason we don't had it on DB. Create a version Id and store it. %% (we did the same on process_iq_get, that is called when client get roster, %% not sure why it can still not be on DB at this point) RosterVersion = sha:sha(term_to_binary(now())), {atomic, {updated,1}} = odbc_queries:sql_transaction(LServer, fun() -> odbc_queries:set_roster_version(ejabberd_odbc:escape(LUser), RosterVersion) end), RosterVersion end; false -> roster_hash(ejabberd_hooks:run_fold(roster_get, LServer, [], [US])) end. %% Load roster from DB only if neccesary. %% It is neccesary if %% - roster versioning is disabled in server OR %% - roster versioning is not used by the client OR %% - roster versioning is used by server and client, BUT the server isn't storing versions on db OR %% - the roster version from client don't match current version. process_iq_get(From, To, #iq{sub_el = SubEl} = IQ) -> LUser = From#jid.luser, LServer = From#jid.lserver, US = {LUser, LServer}, try {ItemsToSend, VersionToSend} = case {xml:get_tag_attr("ver", SubEl), roster_versioning_enabled(LServer), roster_version_on_db(LServer)} of {{value, RequestedVersion}, true, true} -> %% Retrieve version from DB. Only load entire roster %% when neccesary. case odbc_queries:get_roster_version(ejabberd_odbc:escape(LServer), ejabberd_odbc:escape(LUser)) of {selected, ["version"], [{RequestedVersion}]} -> {false, false}; {selected, ["version"], [{NewVersion}]} -> {lists:map(fun item_to_xml/1, ejabberd_hooks:run_fold(roster_get, To#jid.lserver, [], [US])), NewVersion}; {selected, ["version"], []} -> RosterVersion = sha:sha(term_to_binary(now())), {atomic, {updated,1}} = odbc_queries:sql_transaction(LServer, fun() -> odbc_queries:set_roster_version(ejabberd_odbc:escape(LUser), RosterVersion) end), {lists:map(fun item_to_xml/1, ejabberd_hooks:run_fold(roster_get, To#jid.lserver, [], [US])), RosterVersion} end; {{value, RequestedVersion}, true, false} -> RosterItems = ejabberd_hooks:run_fold(roster_get, To#jid.lserver, [] , [US]), case roster_hash(RosterItems) of RequestedVersion -> {false, false}; New -> {lists:map(fun item_to_xml/1, RosterItems), New} end; _ -> {lists:map(fun item_to_xml/1, ejabberd_hooks:run_fold(roster_get, To#jid.lserver, [], [US])), false} end, IQ#iq{type = result, sub_el = case {ItemsToSend, VersionToSend} of {false, false} -> []; {Items, false} -> [{xmlelement, "query", [{"xmlns", ?NS_ROSTER}], Items}]; {Items, Version} -> [{xmlelement, "query", [{"xmlns", ?NS_ROSTER}, {"ver", Version}], Items}] end} catch _:_ -> IQ#iq{type =error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} end. get_user_roster(Acc, {LUser, LServer}) -> Items = get_roster(LUser, LServer), lists:filter(fun(#roster{subscription = none, ask = in}) -> false; (_) -> true end, Items) ++ Acc. get_roster(LUser, LServer) -> Username = ejabberd_odbc:escape(LUser), case catch odbc_queries:get_roster(LServer, Username) of {selected, ["username", "jid", "nick", "subscription", "ask", "askmessage", "server", "subscribe", "type"], Items} when is_list(Items) -> JIDGroups = case catch odbc_queries:get_roster_jid_groups(LServer, Username) of {selected, ["jid","grp"], JGrps} when is_list(JGrps) -> JGrps; _ -> [] end, GroupsDict = lists:foldl( fun({J, G}, Acc) -> dict:append(J, G, Acc) end, dict:new(), JIDGroups), RItems = lists:flatmap( fun(I) -> case raw_to_record(LServer, I) of %% Bad JID in database: error -> []; R -> SJID = jlib:jid_to_string(R#roster.jid), Groups = case dict:find(SJID, GroupsDict) of {ok, Gs} -> Gs; error -> [] end, [R#roster{groups = Groups}] end end, Items), RItems; _ -> [] end. item_to_xml(Item) -> Attrs1 = [{"jid", jlib:jid_to_string(Item#roster.jid)}], Attrs2 = case Item#roster.name of "" -> Attrs1; Name -> [{"name", Name} | Attrs1] end, Attrs3 = case Item#roster.subscription of none -> [{"subscription", "none"} | Attrs2]; from -> [{"subscription", "from"} | Attrs2]; to -> [{"subscription", "to"} | Attrs2]; both -> [{"subscription", "both"} | Attrs2]; remove -> [{"subscription", "remove"} | Attrs2] end, Attrs = case ask_to_pending(Item#roster.ask) of out -> [{"ask", "subscribe"} | Attrs3]; both -> [{"ask", "subscribe"} | Attrs3]; _ -> Attrs3 end, SubEls = lists:map(fun(G) -> {xmlelement, "group", [], [{xmlcdata, G}]} end, Item#roster.groups), {xmlelement, "item", Attrs, SubEls}. process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) -> {xmlelement, _Name, _Attrs, Els} = SubEl, lists:foreach(fun(El) -> process_item_set(From, To, El) end, Els), IQ#iq{type = result, sub_el = []}. process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) -> JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)), #jid{user = User, luser = LUser, lserver = LServer} = From, case JID1 of error -> ok; _ -> LJID = jlib:jid_tolower(JID1), Username = ejabberd_odbc:escape(LUser), SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)), F = fun() -> {selected, ["username", "jid", "nick", "subscription", "ask", "askmessage", "server", "subscribe", "type"], Res} = odbc_queries:get_roster_by_jid(LServer, Username, SJID), Item = case Res of [] -> #roster{usj = {LUser, LServer, LJID}, us = {LUser, LServer}, jid = LJID}; [I] -> R = raw_to_record(LServer, I), case R of %% Bad JID in database: error -> #roster{usj = {LUser, LServer, LJID}, us = {LUser, LServer}, jid = LJID}; _ -> R#roster{ usj = {LUser, LServer, LJID}, us = {LUser, LServer}, jid = LJID, name = ""} end end, Item1 = process_item_attrs(Item, Attrs), Item2 = process_item_els(Item1, Els), case Item2#roster.subscription of remove -> odbc_queries:del_roster(LServer, Username, SJID); _ -> ItemVals = record_to_string(Item2), ItemGroups = groups_to_string(Item2), odbc_queries:update_roster(LServer, Username, SJID, ItemVals, ItemGroups) end, %% If the item exist in shared roster, take the %% subscription information from there: Item3 = ejabberd_hooks:run_fold(roster_process_item, LServer, Item2, [LServer]), case roster_version_on_db(LServer) of true -> odbc_queries:set_roster_version(ejabberd_odbc:escape(LUser), sha:sha(term_to_binary(now()))); false -> ok end, {Item, Item3} end, case odbc_queries:sql_transaction(LServer, F) of {atomic, {OldItem, Item}} -> push_item(User, LServer, To, Item), case Item#roster.subscription of remove -> send_unsubscribing_presence(From, OldItem), ok; _ -> ok end; E -> ?DEBUG("ROSTER: roster item set error: ~p~n", [E]), ok end end; process_item_set(_From, _To, _) -> ok. process_item_attrs(Item, [{Attr, Val} | Attrs]) -> case Attr of "jid" -> case jlib:string_to_jid(Val) of error -> process_item_attrs(Item, Attrs); JID1 -> JID = {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource}, process_item_attrs(Item#roster{jid = JID}, Attrs) end; "name" -> process_item_attrs(Item#roster{name = Val}, Attrs); "subscription" -> case Val of "remove" -> process_item_attrs(Item#roster{subscription = remove}, Attrs); _ -> process_item_attrs(Item, Attrs) end; "ask" -> process_item_attrs(Item, Attrs); _ -> process_item_attrs(Item, Attrs) end; process_item_attrs(Item, []) -> Item. process_item_els(Item, [{xmlelement, Name, _Attrs, SEls} | Els]) -> case Name of "group" -> Groups = [xml:get_cdata(SEls) | Item#roster.groups], process_item_els(Item#roster{groups = Groups}, Els); _ -> process_item_els(Item, Els) end; process_item_els(Item, [{xmlcdata, _} | Els]) -> process_item_els(Item, Els); process_item_els(Item, []) -> Item. push_item(User, Server, From, Item) -> ejabberd_sm:route(jlib:make_jid("", "", ""), jlib:make_jid(User, Server, ""), {xmlelement, "broadcast", [], [{item, Item#roster.jid, Item#roster.subscription}]}), case roster_versioning_enabled(Server) of true -> push_item_version(Server, User, From, Item, roster_version(Server, User)); false -> lists:foreach(fun(Resource) -> push_item(User, Server, Resource, From, Item) end, ejabberd_sm:get_user_resources(User, Server)) end. % TODO: don't push to those who not load roster push_item(User, Server, Resource, From, Item) -> ResIQ = #iq{type = set, xmlns = ?NS_ROSTER, id = "push" ++ randoms:get_string(), sub_el = [{xmlelement, "query", [{"xmlns", ?NS_ROSTER}], [item_to_xml(Item)]}]}, ejabberd_router:route( From, jlib:make_jid(User, Server, Resource), jlib:iq_to_xml(ResIQ)). %% @doc Roster push, calculate and include the version attribute. %% TODO: don't push to those who didn't load roster push_item_version(Server, User, From, Item, RosterVersion) -> lists:foreach(fun(Resource) -> push_item_version(User, Server, Resource, From, Item, RosterVersion) end, ejabberd_sm:get_user_resources(User, Server)). push_item_version(User, Server, Resource, From, Item, RosterVersion) -> IQPush = #iq{type = 'set', xmlns = ?NS_ROSTER, id = "push" ++ randoms:get_string(), sub_el = [{xmlelement, "query", [{"xmlns", ?NS_ROSTER}, {"ver", RosterVersion}], [item_to_xml(Item)]}]}, ejabberd_router:route( From, jlib:make_jid(User, Server, Resource), jlib:iq_to_xml(IQPush)). get_subscription_lists(_, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), Username = ejabberd_odbc:escape(LUser), case catch odbc_queries:get_roster(LServer, Username) of {selected, ["username", "jid", "nick", "subscription", "ask", "askmessage", "server", "subscribe", "type"], Items} when is_list(Items) -> fill_subscription_lists(LServer, Items, [], []); _ -> {[], []} end. fill_subscription_lists(LServer, [RawI | Is], F, T) -> I = raw_to_record(LServer, RawI), case I of %% Bad JID in database: error -> fill_subscription_lists(LServer, Is, F, T); _ -> J = I#roster.jid, case I#roster.subscription of both -> fill_subscription_lists(LServer, Is, [J | F], [J | T]); from -> fill_subscription_lists(LServer, Is, [J | F], T); to -> fill_subscription_lists(LServer, Is, F, [J | T]); _ -> fill_subscription_lists(LServer, Is, F, T) end end; fill_subscription_lists(_LServer, [], F, T) -> {F, T}. ask_to_pending(subscribe) -> out; ask_to_pending(unsubscribe) -> none; ask_to_pending(Ask) -> Ask. in_subscription(_, User, Server, JID, Type, Reason) -> process_subscription(in, User, Server, JID, Type, Reason). out_subscription(User, Server, JID, Type) -> process_subscription(out, User, Server, JID, Type, []). process_subscription(Direction, User, Server, JID1, Type, Reason) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), LJID = jlib:jid_tolower(JID1), Username = ejabberd_odbc:escape(LUser), SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)), F = fun() -> Item = case odbc_queries:get_roster_by_jid(LServer, Username, SJID) of {selected, ["username", "jid", "nick", "subscription", "ask", "askmessage", "server", "subscribe", "type"], [I]} -> %% raw_to_record can return error, but %% jlib_to_string would fail before this point R = raw_to_record(LServer, I), Groups = case odbc_queries:get_roster_groups(LServer, Username, SJID) of {selected, ["grp"], JGrps} when is_list(JGrps) -> [JGrp || {JGrp} <- JGrps]; _ -> [] end, R#roster{groups = Groups}; {selected, ["username", "jid", "nick", "subscription", "ask", "askmessage", "server", "subscribe", "type"], []} -> #roster{usj = {LUser, LServer, LJID}, us = {LUser, LServer}, jid = LJID} end, NewState = case Direction of out -> out_state_change(Item#roster.subscription, Item#roster.ask, Type); in -> in_state_change(Item#roster.subscription, Item#roster.ask, Type) end, AutoReply = case Direction of out -> none; in -> in_auto_reply(Item#roster.subscription, Item#roster.ask, Type) end, AskMessage = case NewState of {_, both} -> Reason; {_, in} -> Reason; _ -> "" end, case NewState of none -> {none, AutoReply}; {none, none} when Item#roster.subscription == none, Item#roster.ask == in -> odbc_queries:del_roster(LServer, Username, SJID), {none, AutoReply}; {Subscription, Pending} -> NewItem = Item#roster{subscription = Subscription, ask = Pending, askmessage = AskMessage}, ItemVals = record_to_string(NewItem), odbc_queries:roster_subscribe(LServer, Username, SJID, ItemVals), case roster_version_on_db(LServer) of true -> odbc_queries:set_roster_version(ejabberd_odbc:escape(LUser), sha:sha(term_to_binary(now()))); false -> ok end, {{push, NewItem}, AutoReply} end end, case odbc_queries:sql_transaction(LServer, F) of {atomic, {Push, AutoReply}} -> case AutoReply of none -> ok; _ -> T = case AutoReply of subscribed -> "subscribed"; unsubscribed -> "unsubscribed" end, ejabberd_router:route( jlib:make_jid(User, Server, ""), JID1, {xmlelement, "presence", [{"type", T}], []}) end, case Push of {push, Item} -> if Item#roster.subscription == none, Item#roster.ask == in -> ok; true -> push_item(User, Server, jlib:make_jid(User, Server, ""), Item) end, true; none -> false end; _ -> false end. %% in_state_change(Subscription, Pending, Type) -> NewState %% NewState = none | {NewSubscription, NewPending} -ifdef(ROSTER_GATEWAY_WORKAROUND). -define(NNSD, {to, none}). -define(NISD, {to, in}). -else. -define(NNSD, none). -define(NISD, none). -endif. in_state_change(none, none, subscribe) -> {none, in}; in_state_change(none, none, subscribed) -> ?NNSD; in_state_change(none, none, unsubscribe) -> none; in_state_change(none, none, unsubscribed) -> none; in_state_change(none, out, subscribe) -> {none, both}; in_state_change(none, out, subscribed) -> {to, none}; in_state_change(none, out, unsubscribe) -> none; in_state_change(none, out, unsubscribed) -> {none, none}; in_state_change(none, in, subscribe) -> none; in_state_change(none, in, subscribed) -> ?NISD; in_state_change(none, in, unsubscribe) -> {none, none}; in_state_change(none, in, unsubscribed) -> none; in_state_change(none, both, subscribe) -> none; in_state_change(none, both, subscribed) -> {to, in}; in_state_change(none, both, unsubscribe) -> {none, out}; in_state_change(none, both, unsubscribed) -> {none, in}; in_state_change(to, none, subscribe) -> {to, in}; in_state_change(to, none, subscribed) -> none; in_state_change(to, none, unsubscribe) -> none; in_state_change(to, none, unsubscribed) -> {none, none}; in_state_change(to, in, subscribe) -> none; in_state_change(to, in, subscribed) -> none; in_state_change(to, in, unsubscribe) -> {to, none}; in_state_change(to, in, unsubscribed) -> {none, in}; in_state_change(from, none, subscribe) -> none; in_state_change(from, none, subscribed) -> {both, none}; in_state_change(from, none, unsubscribe) -> {none, none}; in_state_change(from, none, unsubscribed) -> none; in_state_change(from, out, subscribe) -> none; in_state_change(from, out, subscribed) -> {both, none}; in_state_change(from, out, unsubscribe) -> {none, out}; in_state_change(from, out, unsubscribed) -> {from, none}; in_state_change(both, none, subscribe) -> none; in_state_change(both, none, subscribed) -> none; in_state_change(both, none, unsubscribe) -> {to, none}; in_state_change(both, none, unsubscribed) -> {from, none}. out_state_change(none, none, subscribe) -> {none, out}; out_state_change(none, none, subscribed) -> none; out_state_change(none, none, unsubscribe) -> none; out_state_change(none, none, unsubscribed) -> none; out_state_change(none, out, subscribe) -> {none, out}; %% We need to resend query (RFC3921, section 9.2) out_state_change(none, out, subscribed) -> none; out_state_change(none, out, unsubscribe) -> {none, none}; out_state_change(none, out, unsubscribed) -> none; out_state_change(none, in, subscribe) -> {none, both}; out_state_change(none, in, subscribed) -> {from, none}; out_state_change(none, in, unsubscribe) -> none; out_state_change(none, in, unsubscribed) -> {none, none}; out_state_change(none, both, subscribe) -> none; out_state_change(none, both, subscribed) -> {from, out}; out_state_change(none, both, unsubscribe) -> {none, in}; out_state_change(none, both, unsubscribed) -> {none, out}; out_state_change(to, none, subscribe) -> none; out_state_change(to, none, subscribed) -> {both, none}; out_state_change(to, none, unsubscribe) -> {none, none}; out_state_change(to, none, unsubscribed) -> none; out_state_change(to, in, subscribe) -> none; out_state_change(to, in, subscribed) -> {both, none}; out_state_change(to, in, unsubscribe) -> {none, in}; out_state_change(to, in, unsubscribed) -> {to, none}; out_state_change(from, none, subscribe) -> {from, out}; out_state_change(from, none, subscribed) -> none; out_state_change(from, none, unsubscribe) -> none; out_state_change(from, none, unsubscribed) -> {none, none}; out_state_change(from, out, subscribe) -> none; out_state_change(from, out, subscribed) -> none; out_state_change(from, out, unsubscribe) -> {from, none}; out_state_change(from, out, unsubscribed) -> {none, out}; out_state_change(both, none, subscribe) -> none; out_state_change(both, none, subscribed) -> none; out_state_change(both, none, unsubscribe) -> {from, none}; out_state_change(both, none, unsubscribed) -> {to, none}. in_auto_reply(from, none, subscribe) -> subscribed; in_auto_reply(from, out, subscribe) -> subscribed; in_auto_reply(both, none, subscribe) -> subscribed; in_auto_reply(none, in, unsubscribe) -> unsubscribed; in_auto_reply(none, both, unsubscribe) -> unsubscribed; in_auto_reply(to, in, unsubscribe) -> unsubscribed; in_auto_reply(from, none, unsubscribe) -> unsubscribed; in_auto_reply(from, out, unsubscribe) -> unsubscribed; in_auto_reply(both, none, unsubscribe) -> unsubscribed; in_auto_reply(_, _, _) -> none. remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), Username = ejabberd_odbc:escape(LUser), send_unsubscription_to_rosteritems(LUser, LServer), odbc_queries:del_user_roster_t(LServer, Username), ok. %% For each contact with Subscription: %% Both or From, send a "unsubscribed" presence stanza; %% Both or To, send a "unsubscribe" presence stanza. send_unsubscription_to_rosteritems(LUser, LServer) -> RosterItems = get_user_roster([], {LUser, LServer}), From = jlib:make_jid({LUser, LServer, ""}), lists:foreach(fun(RosterItem) -> send_unsubscribing_presence(From, RosterItem) end, RosterItems). %% @spec (From::jid(), Item::roster()) -> ok send_unsubscribing_presence(From, Item) -> IsTo = case Item#roster.subscription of both -> true; to -> true; _ -> false end, IsFrom = case Item#roster.subscription of both -> true; from -> true; _ -> false end, if IsTo -> send_presence_type( jlib:jid_remove_resource(From), jlib:make_jid(Item#roster.jid), "unsubscribe"); true -> ok end, if IsFrom -> send_presence_type( jlib:jid_remove_resource(From), jlib:make_jid(Item#roster.jid), "unsubscribed"); true -> ok end, ok. send_presence_type(From, To, Type) -> ejabberd_router:route( From, To, {xmlelement, "presence", [{"type", Type}], []}). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% set_items(User, Server, SubEl) -> {xmlelement, _Name, _Attrs, Els} = SubEl, LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), catch odbc_queries:sql_transaction( LServer, lists:flatmap(fun(El) -> process_item_set_t(LUser, LServer, El) end, Els)). process_item_set_t(LUser, LServer, {xmlelement, _Name, Attrs, Els}) -> JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)), case JID1 of error -> []; _ -> LJID = {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource}, Username = ejabberd_odbc:escape(LUser), SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)), Item = #roster{usj = {LUser, LServer, LJID}, us = {LUser, LServer}, jid = LJID}, Item1 = process_item_attrs_ws(Item, Attrs), Item2 = process_item_els(Item1, Els), case Item2#roster.subscription of remove -> odbc_queries:del_roster_sql(Username, SJID); _ -> ItemVals = record_to_string(Item1), ItemGroups = groups_to_string(Item2), odbc_queries:update_roster_sql(Username, SJID, ItemVals, ItemGroups) end end; process_item_set_t(_LUser, _LServer, _) -> []. process_item_attrs_ws(Item, [{Attr, Val} | Attrs]) -> case Attr of "jid" -> case jlib:string_to_jid(Val) of error -> process_item_attrs_ws(Item, Attrs); JID1 -> JID = {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource}, process_item_attrs_ws(Item#roster{jid = JID}, Attrs) end; "name" -> process_item_attrs_ws(Item#roster{name = Val}, Attrs); "subscription" -> case Val of "remove" -> process_item_attrs_ws(Item#roster{subscription = remove}, Attrs); "none" -> process_item_attrs_ws(Item#roster{subscription = none}, Attrs); "both" -> process_item_attrs_ws(Item#roster{subscription = both}, Attrs); "from" -> process_item_attrs_ws(Item#roster{subscription = from}, Attrs); "to" -> process_item_attrs_ws(Item#roster{subscription = to}, Attrs); _ -> process_item_attrs_ws(Item, Attrs) end; "ask" -> process_item_attrs_ws(Item, Attrs); _ -> process_item_attrs_ws(Item, Attrs) end; process_item_attrs_ws(Item, []) -> Item. get_in_pending_subscriptions(Ls, User, Server) -> JID = jlib:make_jid(User, Server, ""), LUser = JID#jid.luser, LServer = JID#jid.lserver, Username = ejabberd_odbc:escape(LUser), case catch odbc_queries:get_roster(LServer, Username) of {selected, ["username", "jid", "nick", "subscription", "ask", "askmessage", "server", "subscribe", "type"], Items} when is_list(Items) -> Ls ++ lists:map( fun(R) -> Message = R#roster.askmessage, {xmlelement, "presence", [{"from", jlib:jid_to_string(R#roster.jid)}, {"to", jlib:jid_to_string(JID)}, {"type", "subscribe"}], [{xmlelement, "status", [], [{xmlcdata, Message}]}]} end, lists:flatmap( fun(I) -> case raw_to_record(LServer, I) of %% Bad JID in database: error -> []; R -> case R#roster.ask of in -> [R]; both -> [R]; _ -> [] end end end, Items)); _ -> Ls end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% get_jid_info(_, User, Server, JID) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), LJID = jlib:jid_tolower(JID), Username = ejabberd_odbc:escape(LUser), SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)), case catch odbc_queries:get_subscription(LServer, Username, SJID) of {selected, ["subscription"], [{SSubscription}]} -> Subscription = case SSubscription of "B" -> both; "T" -> to; "F" -> from; _ -> none end, Groups = case catch odbc_queries:get_rostergroup_by_jid(LServer, Username, SJID) of {selected, ["grp"], JGrps} when is_list(JGrps) -> [JGrp || {JGrp} <- JGrps]; _ -> [] end, {Subscription, Groups}; _ -> LRJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)), if LRJID == LJID -> {none, []}; true -> SRJID = ejabberd_odbc:escape(jlib:jid_to_string(LRJID)), case catch odbc_queries:get_subscription(LServer, Username, SRJID) of {selected, ["subscription"], [{SSubscription}]} -> Subscription = case SSubscription of "B" -> both; "T" -> to; "F" -> from; _ -> none end, Groups = case catch odbc_queries:get_rostergroup_by_jid(LServer, Username, SRJID) of {selected, ["grp"], JGrps} when is_list(JGrps) -> [JGrp || {JGrp} <- JGrps]; _ -> [] end, {Subscription, Groups}; _ -> {none, []} end end end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% raw_to_record(LServer, {User, SJID, Nick, SSubscription, SAsk, SAskMessage, _SServer, _SSubscribe, _SType}) -> case jlib:string_to_jid(SJID) of error -> error; JID -> LJID = jlib:jid_tolower(JID), Subscription = case SSubscription of "B" -> both; "T" -> to; "F" -> from; _ -> none end, Ask = case SAsk of "S" -> subscribe; "U" -> unsubscribe; "B" -> both; "O" -> out; "I" -> in; _ -> none end, #roster{usj = {User, LServer, LJID}, us = {User, LServer}, jid = LJID, name = Nick, subscription = Subscription, ask = Ask, askmessage = SAskMessage} end. record_to_string(#roster{us = {User, _Server}, jid = JID, name = Name, subscription = Subscription, ask = Ask, askmessage = AskMessage}) -> Username = ejabberd_odbc:escape(User), SJID = ejabberd_odbc:escape(jlib:jid_to_string(jlib:jid_tolower(JID))), Nick = ejabberd_odbc:escape(Name), SSubscription = case Subscription of both -> "B"; to -> "T"; from -> "F"; none -> "N" end, SAsk = case Ask of subscribe -> "S"; unsubscribe -> "U"; both -> "B"; out -> "O"; in -> "I"; none -> "N" end, SAskMessage = ejabberd_odbc:escape(AskMessage), [Username, SJID, Nick, SSubscription, SAsk, SAskMessage, "N", "", "item"]. groups_to_string(#roster{us = {User, _Server}, jid = JID, groups = Groups}) -> Username = ejabberd_odbc:escape(User), SJID = ejabberd_odbc:escape(jlib:jid_to_string(jlib:jid_tolower(JID))), %% Empty groups do not need to be converted to string to be inserted in %% the database lists:foldl( fun([], Acc) -> Acc; (Group, Acc) -> G = ejabberd_odbc:escape(Group), [[Username, SJID, G]|Acc] end, [], Groups). webadmin_page(_, Host, #request{us = _US, path = ["user", U, "roster"], q = Query, lang = Lang} = _Request) -> Res = user_roster(U, Host, Query, Lang), {stop, Res}; webadmin_page(Acc, _, _) -> Acc. user_roster(User, Server, Query, Lang) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, Items1 = get_roster(LUser, LServer), Res = user_roster_parse_query(User, Server, Items1, Query), Items = get_roster(LUser, LServer), SItems = lists:sort(Items), FItems = case SItems of [] -> [?CT("None")]; _ -> [?XE("table", [?XE("thead", [?XE("tr", [?XCT("td", "Jabber ID"), ?XCT("td", "Nickname"), ?XCT("td", "Subscription"), ?XCT("td", "Pending"), ?XCT("td", "Groups") ])]), ?XE("tbody", lists:map( fun(R) -> Groups = lists:flatmap( fun(Group) -> [?C(Group), ?BR] end, R#roster.groups), Pending = ask_to_pending(R#roster.ask), TDJID = build_contact_jid_td(R#roster.jid), ?XE("tr", [TDJID, ?XAC("td", [{"class", "valign"}], R#roster.name), ?XAC("td", [{"class", "valign"}], atom_to_list(R#roster.subscription)), ?XAC("td", [{"class", "valign"}], atom_to_list(Pending)), ?XAE("td", [{"class", "valign"}], Groups), if Pending == in -> ?XAE("td", [{"class", "valign"}], [?INPUTT("submit", "validate" ++ ejabberd_web_admin:term_to_id(R#roster.jid), "Validate")]); true -> ?X("td") end, ?XAE("td", [{"class", "valign"}], [?INPUTT("submit", "remove" ++ ejabberd_web_admin:term_to_id(R#roster.jid), "Remove")])]) end, SItems))])] end, [?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], FItems ++ [?P, ?INPUT("text", "newjid", ""), ?C(" "), ?INPUTT("submit", "addjid", "Add Jabber ID") ])]. build_contact_jid_td(RosterJID) -> %% Convert {U, S, R} into {jid, U, S, R, U, S, R}: ContactJID = jlib:make_jid(RosterJID), JIDURI = case {ContactJID#jid.luser, ContactJID#jid.lserver} of {"", _} -> ""; {CUser, CServer} -> case lists:member(CServer, ?MYHOSTS) of false -> ""; true -> "/admin/server/" ++ CServer ++ "/user/" ++ CUser ++ "/" end end, case JIDURI of [] -> ?XAC("td", [{"class", "valign"}], jlib:jid_to_string(RosterJID)); URI when is_list(URI) -> ?XAE("td", [{"class", "valign"}], [?AC(JIDURI, jlib:jid_to_string(RosterJID))]) end. user_roster_parse_query(User, Server, Items, Query) -> case lists:keysearch("addjid", 1, Query) of {value, _} -> case lists:keysearch("newjid", 1, Query) of {value, {_, undefined}} -> error; {value, {_, SJID}} -> case jlib:string_to_jid(SJID) of JID when is_record(JID, jid) -> user_roster_subscribe_jid(User, Server, JID), ok; error -> error end; false -> error end; false -> case catch user_roster_item_parse_query( User, Server, Items, Query) of submitted -> ok; {'EXIT', _Reason} -> error; _ -> nothing end end. user_roster_subscribe_jid(User, Server, JID) -> out_subscription(User, Server, JID, subscribe), UJID = jlib:make_jid(User, Server, ""), ejabberd_router:route( UJID, JID, {xmlelement, "presence", [{"type", "subscribe"}], []}). user_roster_item_parse_query(User, Server, Items, Query) -> lists:foreach( fun(R) -> JID = R#roster.jid, case lists:keysearch( "validate" ++ ejabberd_web_admin:term_to_id(JID), 1, Query) of {value, _} -> JID1 = jlib:make_jid(JID), out_subscription( User, Server, JID1, subscribed), UJID = jlib:make_jid(User, Server, ""), ejabberd_router:route( UJID, JID1, {xmlelement, "presence", [{"type", "subscribed"}], []}), throw(submitted); false -> case lists:keysearch( "remove" ++ ejabberd_web_admin:term_to_id(JID), 1, Query) of {value, _} -> UJID = jlib:make_jid(User, Server, ""), process_iq( UJID, UJID, #iq{type = set, sub_el = {xmlelement, "query", [{"xmlns", ?NS_ROSTER}], [{xmlelement, "item", [{"jid", jlib:jid_to_string(JID)}, {"subscription", "remove"}], []}]}}), throw(submitted); false -> ok end end end, Items), nothing. us_to_list({User, Server}) -> jlib:jid_to_string({User, Server, ""}). webadmin_user(Acc, _User, _Server, Lang) -> Acc ++ [?XE("h3", [?ACT("roster/", "Roster")])]. ejabberd-2.1.11/src/mod_ip_blacklist.erl0000664000000000000000000000730312240230175015013 0ustar %%%---------------------------------------------------------------------- %%% File : mod_ip_blacklist.erl %%% Author : Mickael Remond %%% Purpose : Download blacklists from ProcessOne %%% Created : 5 May 2008 by Mickael Remond %%% Usage : Add the following line in modules section of ejabberd.cfg: %%% {mod_ip_blacklist, []} %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_ip_blacklist). -author('mremond@process-one.net'). -behaviour(gen_mod). %% API: -export([start/2, preinit/2, init/1, stop/1]). -export([update_bl_c2s/0]). %% Hooks: -export([is_ip_in_c2s_blacklist/2]). -include("ejabberd.hrl"). -define(PROCNAME, ?MODULE). -define(BLC2S, "http://xaai.process-one.net/bl_c2s.txt"). -define(UPDATE_INTERVAL, 6). %% in hours -record(state, {timer}). -record(bl_c2s, {ip}). %% Start once for all vhost start(_Host, _Opts) -> Pid = spawn(?MODULE, preinit, [self(), #state{}]), receive {ok, Pid, PreinitResult} -> PreinitResult end. preinit(Parent, State) -> Pid = self(), try register(?PROCNAME, Pid) of true -> Parent ! {ok, Pid, true}, init(State) catch error:_ -> Parent ! {ok, Pid, true} end. %% TODO: stop(_Host) -> ok. init(State)-> inets:start(), ets:new(bl_c2s, [named_table, public, {keypos, #bl_c2s.ip}]), update_bl_c2s(), %% Register hooks for blacklist ejabberd_hooks:add(check_bl_c2s, ?MODULE, is_ip_in_c2s_blacklist, 50), %% Set timer: Download the blacklist file every 6 hours timer:apply_interval(timer:hours(?UPDATE_INTERVAL), ?MODULE, update_bl_c2s, []), loop(State). %% Remove timer when stop is received. loop(_State) -> receive stop -> ok end. %% Download blacklist file from ProcessOne XAAI %% and update the table internal table %% TODO: Support comment lines starting by % update_bl_c2s() -> ?INFO_MSG("Updating C2S Blacklist", []), case httpc:request(?BLC2S) of {ok, {{_Version, 200, _Reason}, _Headers, Body}} -> IPs = string:tokens(Body,"\n"), ets:delete_all_objects(bl_c2s), lists:foreach( fun(IP) -> ets:insert(bl_c2s, #bl_c2s{ip=list_to_binary(IP)}) end, IPs); {error, Reason} -> ?ERROR_MSG("Cannot download C2S blacklist file. Reason: ~p", [Reason]) end. %% Hook is run with: %% ejabberd_hooks:run_fold(check_bl_c2s, false, [IP]), %% Return: false: IP not blacklisted %% true: IP is blacklisted %% IPV4 IP tuple: is_ip_in_c2s_blacklist(_Val, IP) when is_tuple(IP) -> BinaryIP = list_to_binary(jlib:ip_to_list(IP)), case ets:lookup(bl_c2s, BinaryIP) of [] -> %% Not in blacklist false; [_] -> %% Blacklisted! {stop, true} end; is_ip_in_c2s_blacklist(_Val, _IP) -> false. %% TODO: %% - For now, we do not kick user already logged on a given IP after %% we update the blacklist. ejabberd-2.1.11/src/tls/0000775000000000000000000000000012240452476011621 5ustar ejabberd-2.1.11/src/tls/Makefile.win320000664000000000000000000000201712240230175014210 0ustar include ..\Makefile.inc EFLAGS = -I .. -pz .. OUTDIR = .. BEAMS = ..\tls.beam SOURCE = tls_drv.c sha_drv.c OBJECT = tls_drv.o sha_drv.o DLL = $(OUTDIR)\tls_drv.dll $(OUTPUT)\sha_drv.dll ALL : $(DLL) $(BEAMS) CLEAN : -@erase $(DLL) -@erase $(OUTDIR)\tls_drv.exp -@erase $(OUTDIR)\tls_drv.lib -@erase $(OUTDIR)\sha_drv.exp -@erase $(OUTDIR)\sha_drv.lib -@erase $(OBJECT) -@erase $(BEAMS) $(OUTDIR)\tls.beam : tls.erl erlc -W $(EFLAGS) -o $(OUTDIR) tls.erl CC=cl.exe CC_FLAGS=-nologo -D__WIN32__ -DWIN32 -DWINDOWS -D_WIN32 -DNT -MD -Ox -I"$(ERLANG_DIR)\usr\include" -I"$(EI_DIR)\include" -I"$(OPENSSL_DIR)\include" -I"." LD=link.exe LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" "$(OPENSSL_DIR)\lib\VC\ssleay32MD.lib" "$(OPENSSL_DIR)\lib\VC\libeay32MD.lib" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib $(DLL) : $(OBJECT) $(LD) $(LD_FLAGS) -out:$@ $< $(OBJECT) : $(SOURCE) $(CC) $(CC_FLAGS) -c -Fo$@ $< ejabberd-2.1.11/src/tls/sha_drv.c0000664000000000000000000000724712240230175013413 0ustar /* * ejabberd, Copyright (C) 2002-2012 ProcessOne * * 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., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * */ #include #include #ifdef HAVE_MD2 #include #endif /* * R15B changed several driver callbacks to use ErlDrvSizeT and * ErlDrvSSizeT typedefs instead of int. * This provides missing typedefs on older OTP versions. */ #if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 typedef int ErlDrvSizeT; typedef int ErlDrvSSizeT; #endif static ErlDrvData sha_drv_start(ErlDrvPort port, char *buf) { set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); return NULL; } static ErlDrvSSizeT sha_drv_control(ErlDrvData handle, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { ErlDrvBinary *b = NULL; switch (command) { #ifdef HAVE_MD2 case 2: rlen = MD2_DIGEST_LENGTH; b = driver_alloc_binary(rlen); if (b) MD2((unsigned char*)buf, len, (unsigned char*)b->orig_bytes); break; #endif case 224: rlen = SHA224_DIGEST_LENGTH; b = driver_alloc_binary(rlen); if (b) SHA224((unsigned char*)buf, len, (unsigned char*)b->orig_bytes); break; case 256: rlen = SHA256_DIGEST_LENGTH; b = driver_alloc_binary(rlen); if (b) SHA256((unsigned char*)buf, len, (unsigned char*)b->orig_bytes); break; case 384: rlen = SHA384_DIGEST_LENGTH; b = driver_alloc_binary(rlen); if (b) SHA384((unsigned char*)buf, len, (unsigned char*)b->orig_bytes); break; case 512: rlen = SHA512_DIGEST_LENGTH; b = driver_alloc_binary(rlen); if (b) SHA512((unsigned char*)buf, len, (unsigned char*)b->orig_bytes); break; }; if (b) { *rbuf = (char *)b; } else { *rbuf = NULL; rlen = 0; }; return rlen; } ErlDrvEntry sha_driver_entry = { NULL, /* F_PTR init, N/A */ sha_drv_start, /* L_PTR start, called when port is opened */ NULL, /* F_PTR stop, called when port is closed */ NULL, /* F_PTR output, called when erlang has sent */ NULL, /* F_PTR ready_input, called when input descriptor ready */ NULL, /* F_PTR ready_output, called when output descriptor ready */ "sha_drv", /* char *driver_name, the argument to open_port */ NULL, /* F_PTR finish, called when unloaded */ NULL, /* handle */ sha_drv_control, /* F_PTR control, port_command callback */ NULL, /* F_PTR timeout, reserved */ NULL, /* F_PTR outputv, reserved */ /* Added in Erlang/OTP R15B: */ NULL, /* ready_async */ NULL, /* flush */ NULL, /* call */ NULL, /* event */ ERL_DRV_EXTENDED_MARKER, /* extended_marker */ ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ 0, /* driver_flags */ NULL, /* handle2 */ NULL, /* process_exit */ NULL /* stop_select */ }; DRIVER_INIT(sha_drv) /* must match name in driver_entry */ { return &sha_driver_entry; } ejabberd-2.1.11/src/tls/Makefile.in0000664000000000000000000000252512240230175013660 0ustar # $Id$ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ SSL_CFLAGS = @SSL_CFLAGS@ SSL_LIBS = @SSL_LIBS@ ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ # Assume Linux-style dynamic library flags DYNAMIC_LIB_CFLAGS = -fpic -shared ifeq ($(shell uname),Darwin) DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress endif ifeq ($(shell uname),SunOs) DYNAMIC_LIB_CFLAGS = -KPIC -G -z text endif EFLAGS += @ERLANG_SSLVER@ EFLAGS += -I .. EFLAGS += -pz .. # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif ifeq (@md2@, true) EFLAGS+=-DHAVE_MD2 ERLANG_CFLAGS += -DHAVE_MD2 endif ERLSHLIBS = ../tls_drv.so ../sha_drv.so OUTDIR = .. SOURCES = $(wildcard *.erl) BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) all: $(BEAMS) $(ERLSHLIBS) $(OUTDIR)/%.beam: %.erl @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< #all: $(ERLSHLIBS) # erl -s make all report "{outdir, \"..\"}" -noinput -s erlang halt $(ERLSHLIBS): ../%.so: %.c $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \ $(subst ../,,$(subst .so,.c,$@)) \ $(LIBS) \ $(SSL_LIBS) \ $(SSL_CFLAGS) \ $(ERLANG_LIBS) \ $(ERLANG_CFLAGS) \ -o $@ \ $(DYNAMIC_LIB_CFLAGS) clean: rm -f $(BEAMS) $(ERLSHLIBS) distclean: clean rm -f Makefile TAGS: etags *.erl ejabberd-2.1.11/src/tls/tls_drv.c0000664000000000000000000003345012240230175013435 0ustar /* * ejabberd, Copyright (C) 2002-2012 ProcessOne * * 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., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * */ #include #include #include #include #include #include #include #include #define BUF_SIZE 1024 typedef struct { ErlDrvPort port; BIO *bio_read; BIO *bio_write; SSL *ssl; } tls_data; #ifdef _WIN32 typedef unsigned __int32 uint32_t; #endif #ifndef SSL_OP_NO_TICKET #define SSL_OP_NO_TICKET 0 #endif /* * R15B changed several driver callbacks to use ErlDrvSizeT and * ErlDrvSSizeT typedefs instead of int. * This provides missing typedefs on older OTP versions. */ #if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 typedef int ErlDrvSizeT; typedef int ErlDrvSSizeT; #endif /* * str_hash is based on the public domain code from * http://www.burtleburtle.net/bob/hash/doobs.html */ static uint32_t str_hash(char *s) { unsigned char *key = (unsigned char *)s; uint32_t hash = 0; size_t i; for (i = 0; key[i] != 0; i++) { hash += key[i]; hash += (hash << 10); hash ^= (hash >> 6); } hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15); return hash; } /* Linear hashing */ #define MIN_LEVEL 8 #define MAX_LEVEL 20 struct bucket { uint32_t hash; char *key_file; time_t mtime; SSL_CTX *ssl_ctx; struct bucket *next; }; struct hash_table { int split; int level; struct bucket **buckets; int size; }; struct hash_table ht; static void init_hash_table() { size_t size = 1 << (MIN_LEVEL + 1); size_t i; ht.buckets = (struct bucket **)driver_alloc(sizeof(struct bucket *) * size); ht.split = 0; ht.level = MIN_LEVEL; for (i = 0; i < size; i++) ht.buckets[i] = NULL; } static void hash_table_insert(char *key_file, time_t mtime, SSL_CTX *ssl_ctx) { int level, split; uint32_t hash = str_hash(key_file); size_t bucket; int do_split = 0; struct bucket *el; struct bucket *new_bucket_el; split = ht.split; level = ht.level; bucket = hash & ((1 << level) - 1); if (bucket < split) bucket = hash & ((1 << (level + 1)) - 1); el = ht.buckets[bucket]; while (el != NULL) { if (el->hash == hash && strcmp(el->key_file, key_file) == 0) { el->mtime = mtime; if (el->ssl_ctx != NULL) SSL_CTX_free(el->ssl_ctx); el->ssl_ctx = ssl_ctx; break; } el = el->next; } if (el == NULL) { if (ht.buckets[bucket] != NULL) do_split = !0; new_bucket_el = (struct bucket *)driver_alloc(sizeof(struct bucket)); new_bucket_el->hash = hash; new_bucket_el->key_file = (char *)driver_alloc(strlen(key_file) + 1); strcpy(new_bucket_el->key_file, key_file); new_bucket_el->mtime = mtime; new_bucket_el->ssl_ctx = ssl_ctx; new_bucket_el->next = ht.buckets[bucket]; ht.buckets[bucket] = new_bucket_el; } if (do_split) { struct bucket **el_ptr = &ht.buckets[split]; size_t new_bucket = split + (1 << level); while (*el_ptr != NULL) { uint32_t hash = (*el_ptr)->hash; if ((hash & ((1 << (level + 1)) - 1)) == new_bucket) { struct bucket *moved_el = *el_ptr; *el_ptr = (*el_ptr)->next; moved_el->next = ht.buckets[new_bucket]; ht.buckets[new_bucket] = moved_el; } else el_ptr = &(*el_ptr)->next; } split++; if (split == 1 << level) { size_t size; size_t i; split = 0; level++; size = 1 << (level + 1); ht.split = split; ht.level = level; ht.buckets = (struct bucket **) driver_realloc(ht.buckets, sizeof(struct bucket *) * size); for (i = 1 << level; i < size; i++) ht.buckets[i] = NULL; } else ht.split = split; } } static SSL_CTX *hash_table_lookup(char *key_file, time_t *pmtime) { int level, split; uint32_t hash = str_hash(key_file); size_t bucket; struct bucket *el; split = ht.split; level = ht.level; bucket = hash & ((1 << level) - 1); if (bucket < split) bucket = hash & ((1 << (level + 1)) - 1); el = ht.buckets[bucket]; while (el != NULL) { if (el->hash == hash && strcmp(el->key_file, key_file) == 0) { *pmtime = el->mtime; return el->ssl_ctx; } el = el->next; } return NULL; } static ErlDrvData tls_drv_start(ErlDrvPort port, char *buff) { tls_data *d = (tls_data *)driver_alloc(sizeof(tls_data)); d->port = port; d->bio_read = NULL; d->bio_write = NULL; d->ssl = NULL; set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); return (ErlDrvData)d; } static void tls_drv_stop(ErlDrvData handle) { tls_data *d = (tls_data *)handle; if (d->ssl != NULL) SSL_free(d->ssl); driver_free((char *)handle); } static void tls_drv_finish() { int level; struct bucket *el; int i; level = ht.level; for (i = 0; i < 1 << (level + 1); i++) { el = ht.buckets[i]; while (el != NULL) { if (el->ssl_ctx != NULL) SSL_CTX_free(el->ssl_ctx); driver_free(el->key_file); el = el->next; } } driver_free(ht.buckets); } static int is_key_file_modified(char *file, time_t *key_file_mtime) { struct stat file_stat; if (stat(file, &file_stat)) { *key_file_mtime = 0; return 1; } else { if (*key_file_mtime != file_stat.st_mtime) { *key_file_mtime = file_stat.st_mtime; return 1; } else return 0; } } static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { return 1; } #define SET_CERTIFICATE_FILE_ACCEPT 1 #define SET_CERTIFICATE_FILE_CONNECT 2 #define SET_ENCRYPTED_INPUT 3 #define SET_DECRYPTED_OUTPUT 4 #define GET_ENCRYPTED_OUTPUT 5 #define GET_DECRYPTED_INPUT 6 #define GET_PEER_CERTIFICATE 7 #define GET_VERIFY_RESULT 8 #define VERIFY_NONE 0x10000 #define die_unless(cond, errstr) \ if (!(cond)) \ { \ int errstrlen = strlen(errstr); \ unsigned long error_code = ERR_get_error(); \ char *error_string = error_code ? \ ERR_error_string(error_code, NULL) : \ NULL; \ int error_string_length = error_string ? \ strlen(error_string) : 0; \ if (error_code) \ rlen = errstrlen + error_string_length + 3; \ else \ rlen = errstrlen + 1; \ b = driver_alloc_binary(rlen); \ b->orig_bytes[0] = 1; \ strncpy(b->orig_bytes + 1, errstr, errstrlen); \ if (error_code) { \ strncpy(b->orig_bytes + 1 + errstrlen, \ ": ", 2); \ strncpy(b->orig_bytes + 3 + errstrlen, \ error_string, error_string_length); \ } \ *rbuf = (char *)b; \ return rlen; \ } static ErlDrvSSizeT tls_drv_control(ErlDrvData handle, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { tls_data *d = (tls_data *)handle; int res; int size; ErlDrvBinary *b; X509 *cert; unsigned int flags = command; command &= 0xffff; ERR_clear_error(); switch (command) { case SET_CERTIFICATE_FILE_ACCEPT: case SET_CERTIFICATE_FILE_CONNECT: { time_t mtime = 0; SSL_CTX *ssl_ctx = hash_table_lookup(buf, &mtime); if (is_key_file_modified(buf, &mtime) || ssl_ctx == NULL) { SSL_CTX *ctx; hash_table_insert(buf, mtime, NULL); ctx = SSL_CTX_new(SSLv23_method()); die_unless(ctx, "SSL_CTX_new failed"); res = SSL_CTX_use_certificate_chain_file(ctx, buf); die_unless(res > 0, "SSL_CTX_use_certificate_file failed"); res = SSL_CTX_use_PrivateKey_file(ctx, buf, SSL_FILETYPE_PEM); die_unless(res > 0, "SSL_CTX_use_PrivateKey_file failed"); res = SSL_CTX_check_private_key(ctx); die_unless(res > 0, "SSL_CTX_check_private_key failed"); SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); SSL_CTX_set_default_verify_paths(ctx); #ifdef SSL_MODE_RELEASE_BUFFERS SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS); #endif /* SSL_CTX_load_verify_locations(ctx, "/etc/ejabberd/ca_certificates.pem", NULL); */ /* SSL_CTX_load_verify_locations(ctx, NULL, "/etc/ejabberd/ca_certs/"); */ /* This IF is commented to allow verification in all cases: */ /* if (command == SET_CERTIFICATE_FILE_ACCEPT) */ /* { */ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verify_callback); /* } */ ssl_ctx = ctx; hash_table_insert(buf, mtime, ssl_ctx); } d->ssl = SSL_new(ssl_ctx); die_unless(d->ssl, "SSL_new failed"); if (flags & VERIFY_NONE) SSL_set_verify(d->ssl, SSL_VERIFY_NONE, verify_callback); d->bio_read = BIO_new(BIO_s_mem()); d->bio_write = BIO_new(BIO_s_mem()); SSL_set_bio(d->ssl, d->bio_read, d->bio_write); if (command == SET_CERTIFICATE_FILE_ACCEPT) { SSL_set_options(d->ssl, SSL_OP_NO_TICKET); SSL_set_accept_state(d->ssl); } else { SSL_set_options(d->ssl, SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET); SSL_set_connect_state(d->ssl); } break; } case SET_ENCRYPTED_INPUT: die_unless(d->ssl, "SSL not initialized"); BIO_write(d->bio_read, buf, len); break; case SET_DECRYPTED_OUTPUT: die_unless(d->ssl, "SSL not initialized"); res = SSL_write(d->ssl, buf, len); if (res <= 0) { res = SSL_get_error(d->ssl, res); if (res == SSL_ERROR_WANT_READ || res == SSL_ERROR_WANT_WRITE) { b = driver_alloc_binary(1); b->orig_bytes[0] = 2; *rbuf = (char *)b; return 1; } else { die_unless(0, "SSL_write failed"); } } break; case GET_ENCRYPTED_OUTPUT: die_unless(d->ssl, "SSL not initialized"); size = BIO_ctrl_pending(d->bio_write) + 1; b = driver_alloc_binary(size); b->orig_bytes[0] = 0; BIO_read(d->bio_write, b->orig_bytes + 1, size - 1); *rbuf = (char *)b; return size; case GET_DECRYPTED_INPUT: if (!SSL_is_init_finished(d->ssl)) { res = SSL_do_handshake(d->ssl); if (res <= 0) die_unless(SSL_get_error(d->ssl, res) == SSL_ERROR_WANT_READ, "SSL_do_handshake failed"); } if (SSL_is_init_finished(d->ssl)) { size_t req_size = 0; if (len == 4) { req_size = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; } size = BUF_SIZE + 1; rlen = 1; b = driver_alloc_binary(size); b->orig_bytes[0] = 0; res = 0; while ((req_size == 0 || rlen < req_size + 1) && (res = SSL_read(d->ssl, b->orig_bytes + rlen, (req_size == 0 || req_size + 1 >= size) ? size - rlen : req_size + 1 - rlen)) > 0) { //printf("%d bytes of decrypted data read from state machine\r\n",res); rlen += res; if (size - rlen < BUF_SIZE) { size *= 2; b = driver_realloc_binary(b, size); } } if (res < 0) { int err = SSL_get_error(d->ssl, res); if (err == SSL_ERROR_WANT_READ) { //printf("SSL_read wants more data\r\n"); //return 0; } // TODO } b = driver_realloc_binary(b, rlen); *rbuf = (char *)b; return rlen; } break; case GET_PEER_CERTIFICATE: cert = SSL_get_peer_certificate(d->ssl); if (cert == NULL) { b = driver_alloc_binary(1); b->orig_bytes[0] = 1; *rbuf = (char *)b; return 1; } else { unsigned char *tmp_buf; rlen = i2d_X509(cert, NULL); if (rlen >= 0) { rlen++; b = driver_alloc_binary(rlen); b->orig_bytes[0] = 0; tmp_buf = (unsigned char *)&b->orig_bytes[1]; i2d_X509(cert, &tmp_buf); X509_free(cert); *rbuf = (char *)b; return rlen; } else X509_free(cert); } break; case GET_VERIFY_RESULT: b = driver_alloc_binary(1); b->orig_bytes[0] = SSL_get_verify_result(d->ssl); *rbuf = (char *)b; return 1; break; } b = driver_alloc_binary(1); b->orig_bytes[0] = 0; *rbuf = (char *)b; return 1; } ErlDrvEntry tls_driver_entry = { NULL, /* F_PTR init, N/A */ tls_drv_start, /* L_PTR start, called when port is opened */ tls_drv_stop, /* F_PTR stop, called when port is closed */ NULL, /* F_PTR output, called when erlang has sent */ NULL, /* F_PTR ready_input, called when input descriptor ready */ NULL, /* F_PTR ready_output, called when output descriptor ready */ "tls_drv", /* char *driver_name, the argument to open_port */ tls_drv_finish, /* F_PTR finish, called when unloaded */ NULL, /* handle */ tls_drv_control, /* F_PTR control, port_command callback */ NULL, /* F_PTR timeout, reserved */ NULL, /* F_PTR outputv, reserved */ /* Added in Erlang/OTP R15B: */ NULL, /* ready_async */ NULL, /* flush */ NULL, /* call */ NULL, /* event */ ERL_DRV_EXTENDED_MARKER, /* extended_marker */ ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ 0, /* driver_flags */ NULL, /* handle2 */ NULL, /* process_exit */ NULL /* stop_select */ }; DRIVER_INIT(tls_drv) /* must match name in driver_entry */ { OpenSSL_add_ssl_algorithms(); SSL_load_error_strings(); init_hash_table(); return &tls_driver_entry; } ejabberd-2.1.11/src/tls/tls.erl0000664000000000000000000002644612240230175013131 0ustar %%%---------------------------------------------------------------------- %%% File : tls.erl %%% Author : Alexey Shchepin %%% Purpose : Interface to openssl %%% Created : 24 Jul 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(tls). -author('alexey@process-one.net'). -behaviour(gen_server). -export([start/0, start_link/0, tcp_to_tls/2, tls_to_tcp/1, send/2, recv/2, recv/3, recv_data/2, setopts/2, sockname/1, peername/1, controlling_process/2, close/1, get_peer_certificate/1, get_verify_result/1, get_cert_verify_string/2, test/0]). %% Internal exports, call-back functions. -export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]). -include("ejabberd.hrl"). -define(SET_CERTIFICATE_FILE_ACCEPT, 1). -define(SET_CERTIFICATE_FILE_CONNECT, 2). -define(SET_ENCRYPTED_INPUT, 3). -define(SET_DECRYPTED_OUTPUT, 4). -define(GET_ENCRYPTED_OUTPUT, 5). -define(GET_DECRYPTED_INPUT, 6). -define(GET_PEER_CERTIFICATE, 7). -define(GET_VERIFY_RESULT, 8). -define(VERIFY_NONE, 16#10000). -ifdef(SSL40). -define(CERT_DECODE, {public_key, pkix_decode_cert, plain}). -define(CERT_SELFSIGNED, {public_key, pkix_is_self_signed}). -else. -define(CERT_DECODE, {ssl_pkix, decode_cert, [pkix]}). -define(CERT_SELFSIGNED, {erlang, is_atom}). %% Dummy function for old OTPs -endif. -record(tlssock, {tcpsock, tlsport}). start() -> gen_server:start({local, ?MODULE}, ?MODULE, [], []). start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). init([]) -> case erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv) of ok -> ok; {error, already_loaded} -> ok end, Port = open_port({spawn, "tls_drv"}, [binary]), Res = port_control(Port, ?SET_CERTIFICATE_FILE_ACCEPT, "./ssl.pem" ++ [0]), case Res of <<0>> -> %ets:new(iconv_table, [set, public, named_table]), %ets:insert(iconv_table, {port, Port}), {ok, Port}; <<1, Error/binary>> -> {error, binary_to_list(Error)} end. %%% -------------------------------------------------------- %%% The call-back functions. %%% -------------------------------------------------------- handle_call(_, _, State) -> {noreply, State}. handle_cast(_, State) -> {noreply, State}. handle_info({'EXIT', Port, Reason}, Port) -> {stop, {port_died, Reason}, Port}; handle_info({'EXIT', _Pid, _Reason}, Port) -> {noreply, Port}; handle_info(_, State) -> {noreply, State}. code_change(_OldVsn, State, _Extra) -> {ok, State}. terminate(_Reason, Port) -> Port ! {self, close}, ok. tcp_to_tls(TCPSocket, Options) -> case lists:keysearch(certfile, 1, Options) of {value, {certfile, CertFile}} -> case erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv) of ok -> ok; {error, already_loaded} -> ok end, Port = open_port({spawn, "tls_drv"}, [binary]), Flags = case lists:member(verify_none, Options) of true -> ?VERIFY_NONE; false -> 0 end, Command = case lists:member(connect, Options) of true -> ?SET_CERTIFICATE_FILE_CONNECT; false -> ?SET_CERTIFICATE_FILE_ACCEPT end, case port_control(Port, Command bor Flags, CertFile ++ [0]) of <<0>> -> {ok, #tlssock{tcpsock = TCPSocket, tlsport = Port}}; <<1, Error/binary>> -> {error, binary_to_list(Error)} end; false -> {error, no_certfile} end. tls_to_tcp(#tlssock{tcpsock = TCPSocket, tlsport = Port}) -> port_close(Port), TCPSocket. recv(Socket, Length) -> recv(Socket, Length, infinity). recv(#tlssock{tcpsock = TCPSocket, tlsport = Port} = TLSSock, Length, Timeout) -> case port_control(Port, ?GET_DECRYPTED_INPUT, <>) of <<0>> -> case gen_tcp:recv(TCPSocket, 0, Timeout) of {ok, Packet} -> recv_data(TLSSock, Packet, Length); {error, _Reason} = Error -> Error end; <<0, In/binary>> -> {ok, In}; <<1, Error/binary>> -> {error, binary_to_list(Error)} end. recv_data(TLSSock, Packet) -> recv_data(TLSSock, Packet, 0). recv_data(TLSSock, Packet, Length) -> case catch recv_data1(TLSSock, Packet, Length) of {'EXIT', Reason} -> {error, Reason}; Res -> Res end. recv_data1(#tlssock{tcpsock = TCPSocket, tlsport = Port}, Packet, Length) -> case port_control(Port, ?SET_ENCRYPTED_INPUT, Packet) of <<0>> -> case port_control(Port, ?GET_DECRYPTED_INPUT, <>) of <<0, In/binary>> -> case port_control(Port, ?GET_ENCRYPTED_OUTPUT, []) of <<0, Out/binary>> -> case gen_tcp:send(TCPSocket, Out) of ok -> %?PRINT("IN: ~p~n", [{TCPSocket, binary_to_list(In)}]), {ok, In}; Error -> Error end; <<1, Error/binary>> -> {error, binary_to_list(Error)} end; <<1, Error/binary>> -> {error, binary_to_list(Error)} end; <<1, Error/binary>> -> {error, binary_to_list(Error)} end. send(#tlssock{tcpsock = TCPSocket, tlsport = Port} = TLSSock, Packet) -> case port_control(Port, ?SET_DECRYPTED_OUTPUT, Packet) of <<0>> -> %?PRINT("OUT: ~p~n", [{TCPSocket, lists:flatten(Packet)}]), case port_control(Port, ?GET_ENCRYPTED_OUTPUT, []) of <<0, Out/binary>> -> gen_tcp:send(TCPSocket, Out); <<1, Error/binary>> -> {error, binary_to_list(Error)} end; <<1, Error/binary>> -> {error, binary_to_list(Error)}; <<2>> -> % Dirty hack receive {timeout, _Timer, _} -> {error, timeout} after 100 -> send(TLSSock, Packet) end end. setopts(#tlssock{tcpsock = TCPSocket}, Opts) -> inet:setopts(TCPSocket, Opts). sockname(#tlssock{tcpsock = TCPSocket}) -> inet:sockname(TCPSocket). peername(#tlssock{tcpsock = TCPSocket}) -> inet:peername(TCPSocket). controlling_process(#tlssock{tcpsock = TCPSocket}, Pid) -> gen_tcp:controlling_process(TCPSocket, Pid). close(#tlssock{tcpsock = TCPSocket, tlsport = Port}) -> gen_tcp:close(TCPSocket), port_close(Port). get_peer_certificate(#tlssock{tlsport = Port}) -> case port_control(Port, ?GET_PEER_CERTIFICATE, []) of <<0, BCert/binary>> -> {CertMod, CertFun, CertSecondArg} = ?CERT_DECODE, case catch apply(CertMod, CertFun, [BCert, CertSecondArg]) of {ok, Cert} -> %% returned by R13 and older {ok, Cert}; {'Certificate', _, _, _} = Cert -> {ok, Cert}; _ -> error end; <<1>> -> error end. get_verify_result(#tlssock{tlsport = Port}) -> <> = port_control(Port, ?GET_VERIFY_RESULT, []), Res. test() -> case erl_ddll:load_driver(ejabberd:get_so_path(), tls_drv) of ok -> ok; {error, already_loaded} -> ok end, Port = open_port({spawn, "tls_drv"}, [binary]), ?PRINT("open_port: ~p~n", [Port]), PCRes = port_control(Port, ?SET_CERTIFICATE_FILE_ACCEPT, "./ssl.pem" ++ [0]), ?PRINT("port_control: ~p~n", [PCRes]), {ok, ListenSocket} = gen_tcp:listen(1234, [binary, {packet, 0}, {active, true}, {reuseaddr, true}, {nodelay, true}]), ?PRINT("listen: ~p~n", [ListenSocket]), {ok, Socket} = gen_tcp:accept(ListenSocket), ?PRINT("accept: ~p~n", [Socket]), loop(Port, Socket). loop(Port, Socket) -> receive {tcp, Socket, Data} -> %?PRINT("read: ~p~n", [Data]), Res = port_control(Port, ?SET_ENCRYPTED_INPUT, Data), ?PRINT("SET_ENCRYPTED_INPUT: ~p~n", [Res]), DIRes = port_control(Port, ?GET_DECRYPTED_INPUT, Data), ?PRINT("GET_DECRYPTED_INPUT: ~p~n", [DIRes]), case DIRes of <<0, In/binary>> -> ?PRINT("input: ~s~n", [binary_to_list(In)]); <<1, DIError/binary>> -> ?PRINT("GET_DECRYPTED_INPUT error: ~p~n", [binary_to_list(DIError)]) end, EORes = port_control(Port, ?GET_ENCRYPTED_OUTPUT, Data), ?PRINT("GET_ENCRYPTED_OUTPUT: ~p~n", [EORes]), case EORes of <<0, Out/binary>> -> gen_tcp:send(Socket, Out); <<1, EOError/binary>> -> ?PRINT("GET_ENCRYPTED_OUTPUT error: ~p~n", [binary_to_list(EOError)]) end, loop(Port, Socket); Msg -> ?PRINT("receive: ~p~n", [Msg]), loop(Port, Socket) end. get_cert_verify_string(CertVerifyRes, Cert) -> BCert = public_key:pkix_encode('Certificate', Cert, plain), {CertMod, CertFun} = ?CERT_SELFSIGNED, IsSelfsigned = apply(CertMod, CertFun, [BCert]), case {CertVerifyRes, IsSelfsigned} of {21, true} -> "self-signed certificate"; _ -> cert_verify_code(CertVerifyRes) end. %% http://www.openssl.org/docs/apps/verify.html cert_verify_code(0) -> "ok"; cert_verify_code(2) -> "unable to get issuer certificate"; cert_verify_code(3) -> "unable to get certificate CRL"; cert_verify_code(4) -> "unable to decrypt certificate's signature"; cert_verify_code(5) -> "unable to decrypt CRL's signature"; cert_verify_code(6) -> "unable to decode issuer public key"; cert_verify_code(7) -> "certificate signature failure"; cert_verify_code(8) -> "CRL signature failure"; cert_verify_code(9) -> "certificate is not yet valid"; cert_verify_code(10) -> "certificate has expired"; cert_verify_code(11) -> "CRL is not yet valid"; cert_verify_code(12) -> "CRL has expired"; cert_verify_code(13) -> "format error in certificate's notBefore field"; cert_verify_code(14) -> "format error in certificate's notAfter field"; cert_verify_code(15) -> "format error in CRL's lastUpdate field"; cert_verify_code(16) -> "format error in CRL's nextUpdate field"; cert_verify_code(17) -> "out of memory"; cert_verify_code(18) -> "self signed certificate"; cert_verify_code(19) -> "self signed certificate in certificate chain"; cert_verify_code(20) -> "unable to get local issuer certificate"; cert_verify_code(21) -> "unable to verify the first certificate"; cert_verify_code(22) -> "certificate chain too long"; cert_verify_code(23) -> "certificate revoked"; cert_verify_code(24) -> "invalid CA certificate"; cert_verify_code(25) -> "path length constraint exceeded"; cert_verify_code(26) -> "unsupported certificate purpose"; cert_verify_code(27) -> "certificate not trusted"; cert_verify_code(28) -> "certificate rejected"; cert_verify_code(29) -> "subject issuer mismatch"; cert_verify_code(30) -> "authority and subject key identifier mismatch"; cert_verify_code(31) -> "authority and issuer serial number mismatch"; cert_verify_code(32) -> "key usage does not include certificate signing"; cert_verify_code(50) -> "application verification failure"; cert_verify_code(X) -> "Unknown OpenSSL error code: " ++ integer_to_list(X). ejabberd-2.1.11/src/tls/stdint.h0000775000000000000000000001620112240230175013270 0ustar // ISO C9x compliant stdint.h for Microsoft Visual Studio // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 // // Copyright (c) 2006-2008 Alexander Chemeris // // 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. The name of the author may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 _MSC_VER // [ #error "Use this header only with Microsoft Visual C++ compilers!" #endif // _MSC_VER ] #ifndef _MSC_STDINT_H_ // [ #define _MSC_STDINT_H_ #if _MSC_VER > 1000 #pragma once #endif #include // For Visual Studio 6 in C++ mode wrap include with 'extern "C++" {}' // or compiler give many errors like this: // error C2733: second C linkage of overloaded function 'wmemchr' not allowed #if (_MSC_VER < 1300) && defined(__cplusplus) extern "C++" { #endif # include #if (_MSC_VER < 1300) && defined(__cplusplus) } #endif // Define _W64 macros to mark types changing their size, like intptr_t. #ifndef _W64 # if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 # define _W64 __w64 # else # define _W64 # endif #endif // 7.18.1 Integer types // 7.18.1.1 Exact-width integer types typedef __int8 int8_t; typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; typedef unsigned __int64 uint64_t; // 7.18.1.2 Minimum-width integer types typedef int8_t int_least8_t; typedef int16_t int_least16_t; typedef int32_t int_least32_t; typedef int64_t int_least64_t; typedef uint8_t uint_least8_t; typedef uint16_t uint_least16_t; typedef uint32_t uint_least32_t; typedef uint64_t uint_least64_t; // 7.18.1.3 Fastest minimum-width integer types typedef int8_t int_fast8_t; typedef int16_t int_fast16_t; typedef int32_t int_fast32_t; typedef int64_t int_fast64_t; typedef uint8_t uint_fast8_t; typedef uint16_t uint_fast16_t; typedef uint32_t uint_fast32_t; typedef uint64_t uint_fast64_t; // 7.18.1.4 Integer types capable of holding object pointers #ifdef _WIN64 // [ typedef __int64 intptr_t; typedef unsigned __int64 uintptr_t; #else // _WIN64 ][ typedef _W64 int intptr_t; typedef _W64 unsigned int uintptr_t; #endif // _WIN64 ] // 7.18.1.5 Greatest-width integer types typedef int64_t intmax_t; typedef uint64_t uintmax_t; // 7.18.2 Limits of specified-width integer types #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 // 7.18.2.1 Limits of exact-width integer types #define INT8_MIN ((int8_t)_I8_MIN) #define INT8_MAX _I8_MAX #define INT16_MIN ((int16_t)_I16_MIN) #define INT16_MAX _I16_MAX #define INT32_MIN ((int32_t)_I32_MIN) #define INT32_MAX _I32_MAX #define INT64_MIN ((int64_t)_I64_MIN) #define INT64_MAX _I64_MAX #define UINT8_MAX _UI8_MAX #define UINT16_MAX _UI16_MAX #define UINT32_MAX _UI32_MAX #define UINT64_MAX _UI64_MAX // 7.18.2.2 Limits of minimum-width integer types #define INT_LEAST8_MIN INT8_MIN #define INT_LEAST8_MAX INT8_MAX #define INT_LEAST16_MIN INT16_MIN #define INT_LEAST16_MAX INT16_MAX #define INT_LEAST32_MIN INT32_MIN #define INT_LEAST32_MAX INT32_MAX #define INT_LEAST64_MIN INT64_MIN #define INT_LEAST64_MAX INT64_MAX #define UINT_LEAST8_MAX UINT8_MAX #define UINT_LEAST16_MAX UINT16_MAX #define UINT_LEAST32_MAX UINT32_MAX #define UINT_LEAST64_MAX UINT64_MAX // 7.18.2.3 Limits of fastest minimum-width integer types #define INT_FAST8_MIN INT8_MIN #define INT_FAST8_MAX INT8_MAX #define INT_FAST16_MIN INT16_MIN #define INT_FAST16_MAX INT16_MAX #define INT_FAST32_MIN INT32_MIN #define INT_FAST32_MAX INT32_MAX #define INT_FAST64_MIN INT64_MIN #define INT_FAST64_MAX INT64_MAX #define UINT_FAST8_MAX UINT8_MAX #define UINT_FAST16_MAX UINT16_MAX #define UINT_FAST32_MAX UINT32_MAX #define UINT_FAST64_MAX UINT64_MAX // 7.18.2.4 Limits of integer types capable of holding object pointers #ifdef _WIN64 // [ # define INTPTR_MIN INT64_MIN # define INTPTR_MAX INT64_MAX # define UINTPTR_MAX UINT64_MAX #else // _WIN64 ][ # define INTPTR_MIN INT32_MIN # define INTPTR_MAX INT32_MAX # define UINTPTR_MAX UINT32_MAX #endif // _WIN64 ] // 7.18.2.5 Limits of greatest-width integer types #define INTMAX_MIN INT64_MIN #define INTMAX_MAX INT64_MAX #define UINTMAX_MAX UINT64_MAX // 7.18.3 Limits of other integer types #ifdef _WIN64 // [ # define PTRDIFF_MIN _I64_MIN # define PTRDIFF_MAX _I64_MAX #else // _WIN64 ][ # define PTRDIFF_MIN _I32_MIN # define PTRDIFF_MAX _I32_MAX #endif // _WIN64 ] #define SIG_ATOMIC_MIN INT_MIN #define SIG_ATOMIC_MAX INT_MAX #ifndef SIZE_MAX // [ # ifdef _WIN64 // [ # define SIZE_MAX _UI64_MAX # else // _WIN64 ][ # define SIZE_MAX _UI32_MAX # endif // _WIN64 ] #endif // SIZE_MAX ] // WCHAR_MIN and WCHAR_MAX are also defined in #ifndef WCHAR_MIN // [ # define WCHAR_MIN 0 #endif // WCHAR_MIN ] #ifndef WCHAR_MAX // [ # define WCHAR_MAX _UI16_MAX #endif // WCHAR_MAX ] #define WINT_MIN 0 #define WINT_MAX _UI16_MAX #endif // __STDC_LIMIT_MACROS ] // 7.18.4 Limits of other integer types #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 // 7.18.4.1 Macros for minimum-width integer constants #define INT8_C(val) val##i8 #define INT16_C(val) val##i16 #define INT32_C(val) val##i32 #define INT64_C(val) val##i64 #define UINT8_C(val) val##ui8 #define UINT16_C(val) val##ui16 #define UINT32_C(val) val##ui32 #define UINT64_C(val) val##ui64 // 7.18.4.2 Macros for greatest-width integer constants #define INTMAX_C INT64_C #define UINTMAX_C UINT64_C #endif // __STDC_CONSTANT_MACROS ] #endif // _MSC_STDINT_H_ ] ejabberd-2.1.11/src/mod_configure.erl0000664000000000000000000016542112240230175014342 0ustar %%%---------------------------------------------------------------------- %%% File : mod_configure.erl %%% Author : Alexey Shchepin %%% Purpose : Support for online configuration of ejabberd %%% Created : 19 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %%% Implements most of XEP-0133: Service Administration Version 1.1 %%% (2005-08-19) -module(mod_configure). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, get_local_identity/5, get_local_features/5, get_local_items/5, adhoc_local_items/4, adhoc_local_commands/4, get_sm_identity/5, get_sm_features/5, get_sm_items/5, adhoc_sm_items/4, adhoc_sm_commands/4]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("adhoc.hrl"). -define(T(Lang, Text), translate:translate(Lang, Text)). %% Copied from ejabberd_sm.erl -record(session, {sid, usr, us, priority, info}). start(Host, _Opts) -> ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_items, 50), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 50), ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 50), ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_items, 50), ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50), ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 50), ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, adhoc_local_items, 50), ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, adhoc_local_commands, 50), ejabberd_hooks:add(adhoc_sm_items, Host, ?MODULE, adhoc_sm_items, 50), ejabberd_hooks:add(adhoc_sm_commands, Host, ?MODULE, adhoc_sm_commands, 50), ok. stop(Host) -> ejabberd_hooks:delete(adhoc_sm_commands, Host, ?MODULE, adhoc_sm_commands, 50), ejabberd_hooks:delete(adhoc_sm_items, Host, ?MODULE, adhoc_sm_items, 50), ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, adhoc_local_commands, 50), ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, adhoc_local_items, 50), ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 50), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50), ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_items, 50), ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 50), ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 50), ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_items, 50), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS). %%%----------------------------------------------------------------------- -define(INFO_IDENTITY(Category, Type, Name, Lang), [{xmlelement, "identity", [{"category", Category}, {"type", Type}, {"name", ?T(Lang, Name)}], []}]). -define(INFO_COMMAND(Name, Lang), ?INFO_IDENTITY("automation", "command-node", Name, Lang)). -define(NODEJID(To, Name, Node), {xmlelement, "item", [{"jid", jlib:jid_to_string(To)}, {"name", ?T(Lang, Name)}, {"node", Node}], []}). -define(NODE(Name, Node), {xmlelement, "item", [{"jid", Server}, {"name", ?T(Lang, Name)}, {"node", Node}], []}). -define(NS_ADMINX(Sub), ?NS_ADMIN++"#"++Sub). -define(NS_ADMINL(Sub), ["http:","jabber.org","protocol","admin", Sub]). tokenize(Node) -> string:tokens(Node, "/#"). get_sm_identity(Acc, _From, _To, Node, Lang) -> case Node of "config" -> ?INFO_COMMAND("Configuration", Lang); _ -> Acc end. get_local_identity(Acc, _From, _To, Node, Lang) -> LNode = tokenize(Node), case LNode of ["running nodes", ENode] -> ?INFO_IDENTITY("ejabberd", "node", ENode, Lang); ["running nodes", _ENode, "DB"] -> ?INFO_COMMAND("Database", Lang); ["running nodes", _ENode, "modules", "start"] -> ?INFO_COMMAND("Start Modules", Lang); ["running nodes", _ENode, "modules", "stop"] -> ?INFO_COMMAND("Stop Modules", Lang); ["running nodes", _ENode, "backup", "backup"] -> ?INFO_COMMAND("Backup", Lang); ["running nodes", _ENode, "backup", "restore"] -> ?INFO_COMMAND("Restore", Lang); ["running nodes", _ENode, "backup", "textfile"] -> ?INFO_COMMAND("Dump to Text File", Lang); ["running nodes", _ENode, "import", "file"] -> ?INFO_COMMAND("Import File", Lang); ["running nodes", _ENode, "import", "dir"] -> ?INFO_COMMAND("Import Directory", Lang); ["running nodes", _ENode, "restart"] -> ?INFO_COMMAND("Restart Service", Lang); ["running nodes", _ENode, "shutdown"] -> ?INFO_COMMAND("Shut Down Service", Lang); ?NS_ADMINL("add-user") -> ?INFO_COMMAND("Add User", Lang); ?NS_ADMINL("delete-user") -> ?INFO_COMMAND("Delete User", Lang); ?NS_ADMINL("end-user-session") -> ?INFO_COMMAND("End User Session", Lang); ?NS_ADMINL("get-user-password") -> ?INFO_COMMAND("Get User Password", Lang); ?NS_ADMINL("change-user-password") -> ?INFO_COMMAND("Change User Password", Lang); ?NS_ADMINL("get-user-lastlogin") -> ?INFO_COMMAND("Get User Last Login Time", Lang); ?NS_ADMINL("user-stats") -> ?INFO_COMMAND("Get User Statistics", Lang); ?NS_ADMINL("get-registered-users-num") -> ?INFO_COMMAND("Get Number of Registered Users", Lang); ?NS_ADMINL("get-online-users-num") -> ?INFO_COMMAND("Get Number of Online Users", Lang); ["config", "acls"] -> ?INFO_COMMAND("Access Control Lists", Lang); ["config", "access"] -> ?INFO_COMMAND("Access Rules", Lang); _ -> Acc end. %%%----------------------------------------------------------------------- -define(INFO_RESULT(Allow, Feats), case Allow of deny -> {error, ?ERR_FORBIDDEN}; allow -> {result, Feats} end). get_sm_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> Allow = acl:match_rule(LServer, configure, From), case Node of "config" -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); _ -> Acc end end. get_local_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> LNode = tokenize(Node), Allow = acl:match_rule(LServer, configure, From), case LNode of ["config"] -> ?INFO_RESULT(Allow, []); ["user"] -> ?INFO_RESULT(Allow, []); ["online users"] -> ?INFO_RESULT(Allow, []); ["all users"] -> ?INFO_RESULT(Allow, []); ["all users", [$@ | _]] -> ?INFO_RESULT(Allow, []); ["outgoing s2s" | _] -> ?INFO_RESULT(Allow, []); ["running nodes"] -> ?INFO_RESULT(Allow, []); ["stopped nodes"] -> ?INFO_RESULT(Allow, []); ["running nodes", _ENode] -> ?INFO_RESULT(Allow, [?NS_STATS]); ["running nodes", _ENode, "DB"] -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ["running nodes", _ENode, "modules"] -> ?INFO_RESULT(Allow, []); ["running nodes", _ENode, "modules", _] -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ["running nodes", _ENode, "backup"] -> ?INFO_RESULT(Allow, []); ["running nodes", _ENode, "backup", _] -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ["running nodes", _ENode, "import"] -> ?INFO_RESULT(Allow, []); ["running nodes", _ENode, "import", _] -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ["running nodes", _ENode, "restart"] -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ["running nodes", _ENode, "shutdown"] -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ["config", _] -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMINL("add-user") -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMINL("delete-user") -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMINL("end-user-session") -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMINL("get-user-password") -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMINL("change-user-password") -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMINL("get-user-lastlogin") -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMINL("user-stats") -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMINL("get-registered-users-num") -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); ?NS_ADMINL("get-online-users-num") -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); _ -> Acc end end. %%%----------------------------------------------------------------------- adhoc_sm_items(Acc, From, #jid{lserver = LServer} = To, Lang) -> case acl:match_rule(LServer, configure, From) of allow -> Items = case Acc of {result, Its} -> Its; empty -> [] end, Nodes = [{xmlelement, "item", [{"jid", jlib:jid_to_string(To)}, {"name", ?T(Lang, "Configuration")}, {"node", "config"}], []}], {result, Items ++ Nodes}; _ -> Acc end. %%%----------------------------------------------------------------------- get_sm_items(Acc, From, #jid{user = User, server = Server, lserver = LServer} = To, Node, Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> Items = case Acc of {result, Its} -> Its; empty -> [] end, case {acl:match_rule(LServer, configure, From), Node} of {allow, ""} -> Nodes = [?NODEJID(To, "Configuration", "config"), ?NODEJID(To, "User Management", "user")], {result, Items ++ Nodes ++ get_user_resources(User, Server)}; {allow, "config"} -> {result, []}; {_, "config"} -> {error, ?ERR_FORBIDDEN}; _ -> Acc end end. get_user_resources(User, Server) -> Rs = ejabberd_sm:get_user_resources(User, Server), lists:map(fun(R) -> {xmlelement, "item", [{"jid", User ++ "@" ++ Server ++ "/" ++ R}, {"name", User}], []} end, lists:sort(Rs)). %%%----------------------------------------------------------------------- adhoc_local_items(Acc, From, #jid{lserver = LServer, server = Server} = To, Lang) -> case acl:match_rule(LServer, configure, From) of allow -> Items = case Acc of {result, Its} -> Its; empty -> [] end, PermLev = get_permission_level(From), %% Recursively get all configure commands Nodes = recursively_get_local_items(PermLev, LServer, "", Server, Lang), Nodes1 = lists:filter( fun(N) -> Nd = xml:get_tag_attr_s("node", N), F = get_local_features([], From, To, Nd, Lang), case F of {result, [?NS_COMMANDS]} -> true; _ -> false end end, Nodes), {result, Items ++ Nodes1}; _ -> Acc end. recursively_get_local_items(_PermLev, _LServer, "online users", _Server, _Lang) -> []; recursively_get_local_items(_PermLev, _LServer, "all users", _Server, _Lang) -> []; recursively_get_local_items(PermLev, LServer, Node, Server, Lang) -> LNode = tokenize(Node), Items = case get_local_items({PermLev, LServer}, LNode, Server, Lang) of {result, Res} -> Res; {error, _Error} -> [] end, Nodes = lists:flatten( lists:map( fun(N) -> S = xml:get_tag_attr_s("jid", N), Nd = xml:get_tag_attr_s("node", N), if (S /= Server) or (Nd == "") -> []; true -> [N, recursively_get_local_items( PermLev, LServer, Nd, Server, Lang)] end end, Items)), Nodes. get_permission_level(JID) -> case acl:match_rule(global, configure, JID) of allow -> global; deny -> vhost end. %%%----------------------------------------------------------------------- -define(ITEMS_RESULT(Allow, LNode, Fallback), case Allow of deny -> Fallback; allow -> PermLev = get_permission_level(From), case get_local_items({PermLev, LServer}, LNode, jlib:jid_to_string(To), Lang) of {result, Res} -> {result, Res}; {error, Error} -> {error, Error} end end). get_local_items(Acc, From, #jid{lserver = LServer} = To, "", Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> Items = case Acc of {result, Its} -> Its; empty -> [] end, Allow = acl:match_rule(LServer, configure, From), case Allow of deny -> {result, Items}; allow -> PermLev = get_permission_level(From), case get_local_items({PermLev, LServer}, [], jlib:jid_to_string(To), Lang) of {result, Res} -> {result, Items ++ Res}; {error, _Error} -> {result, Items} end end end; get_local_items(Acc, From, #jid{lserver = LServer} = To, Node, Lang) -> case gen_mod:is_loaded(LServer, mod_adhoc) of false -> Acc; _ -> LNode = tokenize(Node), Allow = acl:match_rule(LServer, configure, From), case LNode of ["config"] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["user"] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["online users"] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["all users"] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["all users", [$@ | _]] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["outgoing s2s" | _] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["running nodes"] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["stopped nodes"] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["running nodes", _ENode] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["running nodes", _ENode, "DB"] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["running nodes", _ENode, "modules"] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["running nodes", _ENode, "modules", _] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["running nodes", _ENode, "backup"] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["running nodes", _ENode, "backup", _] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["running nodes", _ENode, "import"] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["running nodes", _ENode, "import", _] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["running nodes", _ENode, "restart"] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["running nodes", _ENode, "shutdown"] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ["config", _] -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?NS_ADMINL("add-user") -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?NS_ADMINL("delete-user") -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?NS_ADMINL("end-user-session") -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?NS_ADMINL("get-user-password") -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?NS_ADMINL("change-user-password") -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?NS_ADMINL("get-user-lastlogin") -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?NS_ADMINL("user-stats") -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?NS_ADMINL("get-registered-users-num") -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?NS_ADMINL("get-online-users-num") -> ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); _ -> Acc end end. %%%----------------------------------------------------------------------- %% @spec ({PermissionLevel, Host}, [string()], Server::string(), Lang) %% -> {result, [xmlelement()]} %% PermissionLevel = global | vhost get_local_items(_Host, [], Server, Lang) -> {result, [?NODE("Configuration", "config"), ?NODE("User Management", "user"), ?NODE("Online Users", "online users"), ?NODE("All Users", "all users"), ?NODE("Outgoing s2s Connections", "outgoing s2s"), ?NODE("Running Nodes", "running nodes"), ?NODE("Stopped Nodes", "stopped nodes") ]}; get_local_items(_Host, ["config"], Server, Lang) -> {result, [?NODE("Access Control Lists", "config/acls"), ?NODE("Access Rules", "config/access") ]}; get_local_items(_Host, ["config", _], _Server, _Lang) -> {result, []}; get_local_items(_Host, ["user"], Server, Lang) -> {result, [?NODE("Add User", ?NS_ADMINX("add-user")), ?NODE("Delete User", ?NS_ADMINX("delete-user")), ?NODE("End User Session", ?NS_ADMINX("end-user-session")), ?NODE("Get User Password", ?NS_ADMINX("get-user-password")), ?NODE("Change User Password",?NS_ADMINX("change-user-password")), ?NODE("Get User Last Login Time", ?NS_ADMINX("get-user-lastlogin")), ?NODE("Get User Statistics", ?NS_ADMINX("user-stats")), ?NODE("Get Number of Registered Users",?NS_ADMINX("get-registered-users-num")), ?NODE("Get Number of Online Users",?NS_ADMINX("get-online-users-num")) ]}; get_local_items(_Host, ["http:" | _], _Server, _Lang) -> {result, []}; get_local_items({_, Host}, ["online users"], _Server, _Lang) -> {result, get_online_vh_users(Host)}; get_local_items({_, Host}, ["all users"], _Server, _Lang) -> {result, get_all_vh_users(Host)}; get_local_items({_, Host}, ["all users", [$@ | Diap]], _Server, _Lang) -> case catch ejabberd_auth:get_vh_registered_users(Host) of {'EXIT', _Reason} -> ?ERR_INTERNAL_SERVER_ERROR; Users -> SUsers = lists:sort([{S, U} || {U, S} <- Users]), case catch begin [S1, S2] = ejabberd_regexp:split(Diap, "-"), N1 = list_to_integer(S1), N2 = list_to_integer(S2), Sub = lists:sublist(SUsers, N1, N2 - N1 + 1), lists:map(fun({S, U}) -> {xmlelement, "item", [{"jid", U ++ "@" ++ S}, {"name", U ++ "@" ++ S}], []} end, Sub) end of {'EXIT', _Reason} -> ?ERR_NOT_ACCEPTABLE; Res -> {result, Res} end end; get_local_items({_, Host}, ["outgoing s2s"], _Server, Lang) -> {result, get_outgoing_s2s(Host, Lang)}; get_local_items({_, Host}, ["outgoing s2s", To], _Server, Lang) -> {result, get_outgoing_s2s(Host, Lang, To)}; get_local_items(_Host, ["running nodes"], Server, Lang) -> {result, get_running_nodes(Server, Lang)}; get_local_items(_Host, ["stopped nodes"], _Server, Lang) -> {result, get_stopped_nodes(Lang)}; get_local_items({global, _Host}, ["running nodes", ENode], Server, Lang) -> {result, [?NODE("Database", "running nodes/" ++ ENode ++ "/DB"), ?NODE("Modules", "running nodes/" ++ ENode ++ "/modules"), ?NODE("Backup Management", "running nodes/" ++ ENode ++ "/backup"), ?NODE("Import Users From jabberd14 Spool Files", "running nodes/" ++ ENode ++ "/import"), ?NODE("Restart Service", "running nodes/" ++ ENode ++ "/restart"), ?NODE("Shut Down Service", "running nodes/" ++ ENode ++ "/shutdown") ]}; get_local_items({vhost, _Host}, ["running nodes", ENode], Server, Lang) -> {result, [?NODE("Modules", "running nodes/" ++ ENode ++ "/modules") ]}; get_local_items(_Host, ["running nodes", _ENode, "DB"], _Server, _Lang) -> {result, []}; get_local_items(_Host, ["running nodes", ENode, "modules"], Server, Lang) -> {result, [?NODE("Start Modules", "running nodes/" ++ ENode ++ "/modules/start"), ?NODE("Stop Modules", "running nodes/" ++ ENode ++ "/modules/stop") ]}; get_local_items(_Host, ["running nodes", _ENode, "modules", _], _Server, _Lang) -> {result, []}; get_local_items(_Host, ["running nodes", ENode, "backup"], Server, Lang) -> {result, [?NODE("Backup", "running nodes/" ++ ENode ++ "/backup/backup"), ?NODE("Restore", "running nodes/" ++ ENode ++ "/backup/restore"), ?NODE("Dump to Text File", "running nodes/" ++ ENode ++ "/backup/textfile") ]}; get_local_items(_Host, ["running nodes", _ENode, "backup", _], _Server, _Lang) -> {result, []}; get_local_items(_Host, ["running nodes", ENode, "import"], Server, Lang) -> {result, [?NODE("Import File", "running nodes/" ++ ENode ++ "/import/file"), ?NODE("Import Directory", "running nodes/" ++ ENode ++ "/import/dir") ]}; get_local_items(_Host, ["running nodes", _ENode, "import", _], _Server, _Lang) -> {result, []}; get_local_items(_Host, ["running nodes", _ENode, "restart"], _Server, _Lang) -> {result, []}; get_local_items(_Host, ["running nodes", _ENode, "shutdown"], _Server, _Lang) -> {result, []}; get_local_items(_Host, _, _Server, _Lang) -> {error, ?ERR_ITEM_NOT_FOUND}. get_online_vh_users(Host) -> case catch ejabberd_sm:get_vh_session_list(Host) of {'EXIT', _Reason} -> []; USRs -> SURs = lists:sort([{S, U, R} || {U, S, R} <- USRs]), lists:map(fun({S, U, R}) -> {xmlelement, "item", [{"jid", U ++ "@" ++ S ++ "/" ++ R}, {"name", U ++ "@" ++ S}], []} end, SURs) end. get_all_vh_users(Host) -> case catch ejabberd_auth:get_vh_registered_users(Host) of {'EXIT', _Reason} -> []; Users -> SUsers = lists:sort([{S, U} || {U, S} <- Users]), case length(SUsers) of N when N =< 100 -> lists:map(fun({S, U}) -> {xmlelement, "item", [{"jid", U ++ "@" ++ S}, {"name", U ++ "@" ++ S}], []} end, SUsers); N -> NParts = trunc(math:sqrt(N * 0.618)) + 1, M = trunc(N / NParts) + 1, lists:map(fun(K) -> L = K + M - 1, Node = "@" ++ integer_to_list(K) ++ "-" ++ integer_to_list(L), {FS, FU} = lists:nth(K, SUsers), {LS, LU} = if L < N -> lists:nth(L, SUsers); true -> lists:last(SUsers) end, Name = FU ++ "@" ++ FS ++ " -- " ++ LU ++ "@" ++ LS, {xmlelement, "item", [{"jid", Host}, {"node", "all users/" ++ Node}, {"name", Name}], []} end, lists:seq(1, N, M)) end end. get_outgoing_s2s(Host, Lang) -> case catch ejabberd_s2s:dirty_get_connections() of {'EXIT', _Reason} -> []; Connections -> DotHost = "." ++ Host, TConns = [TH || {FH, TH} <- Connections, Host == FH orelse lists:suffix(DotHost, FH)], lists:map( fun(T) -> {xmlelement, "item", [{"jid", Host}, {"node", "outgoing s2s/" ++ T}, {"name", lists:flatten( io_lib:format( ?T(Lang, "To ~s"), [T]))}], []} end, lists:usort(TConns)) end. get_outgoing_s2s(Host, Lang, To) -> case catch ejabberd_s2s:dirty_get_connections() of {'EXIT', _Reason} -> []; Connections -> lists:map( fun({F, _T}) -> {xmlelement, "item", [{"jid", Host}, {"node", "outgoing s2s/" ++ To ++ "/" ++ F}, {"name", lists:flatten( io_lib:format( ?T(Lang, "From ~s"), [F]))}], []} end, lists:keysort(1, lists:filter(fun(E) -> element(2, E) == To end, Connections))) end. get_running_nodes(Server, _Lang) -> case catch mnesia:system_info(running_db_nodes) of {'EXIT', _Reason} -> []; DBNodes -> lists:map( fun(N) -> S = atom_to_list(N), {xmlelement, "item", [{"jid", Server}, {"node", "running nodes/" ++ S}, {"name", S}], []} end, lists:sort(DBNodes)) end. get_stopped_nodes(_Lang) -> case catch (lists:usort(mnesia:system_info(db_nodes) ++ mnesia:system_info(extra_db_nodes)) -- mnesia:system_info(running_db_nodes)) of {'EXIT', _Reason} -> []; DBNodes -> lists:map( fun(N) -> S = atom_to_list(N), {xmlelement, "item", [{"jid", ?MYNAME}, {"node", "stopped nodes/" ++ S}, {"name", S}], []} end, lists:sort(DBNodes)) end. %%------------------------------------------------------------------------- -define(COMMANDS_RESULT(LServerOrGlobal, From, To, Request), case acl:match_rule(LServerOrGlobal, configure, From) of deny -> {error, ?ERR_FORBIDDEN}; allow -> adhoc_local_commands(From, To, Request) end). adhoc_local_commands(Acc, From, #jid{lserver = LServer} = To, #adhoc_request{node = Node} = Request) -> LNode = tokenize(Node), case LNode of ["running nodes", _ENode, "DB"] -> ?COMMANDS_RESULT(global, From, To, Request); ["running nodes", _ENode, "modules", _] -> ?COMMANDS_RESULT(LServer, From, To, Request); ["running nodes", _ENode, "backup", _] -> ?COMMANDS_RESULT(global, From, To, Request); ["running nodes", _ENode, "import", _] -> ?COMMANDS_RESULT(global, From, To, Request); ["running nodes", _ENode, "restart"] -> ?COMMANDS_RESULT(global, From, To, Request); ["running nodes", _ENode, "shutdown"] -> ?COMMANDS_RESULT(global, From, To, Request); ["config", _] -> ?COMMANDS_RESULT(LServer, From, To, Request); ?NS_ADMINL(_) -> ?COMMANDS_RESULT(LServer, From, To, Request); _ -> Acc end. adhoc_local_commands(From, #jid{lserver = LServer} = _To, #adhoc_request{lang = Lang, node = Node, sessionid = SessionID, action = Action, xdata = XData} = Request) -> LNode = tokenize(Node), %% If the "action" attribute is not present, it is %% understood as "execute". If there was no %% element in the first response (which there isn't in our %% case), "execute" and "complete" are equivalent. ActionIsExecute = lists:member(Action, ["", "execute", "complete"]), if Action == "cancel" -> %% User cancels request adhoc:produce_response( Request, #adhoc_response{status = canceled}); XData == false, ActionIsExecute -> %% User requests form case get_form(LServer, LNode, Lang) of {result, Form} -> adhoc:produce_response( Request, #adhoc_response{status = executing, elements = Form}); {result, Status, Form} -> adhoc:produce_response( Request, #adhoc_response{status = Status, elements = Form}); {error, Error} -> {error, Error} end; XData /= false, ActionIsExecute -> %% User returns form. case jlib:parse_xdata_submit(XData) of invalid -> {error, ?ERR_BAD_REQUEST}; Fields -> case catch set_form(From, LServer, LNode, Lang, Fields) of {result, Res} -> adhoc:produce_response( #adhoc_response{lang = Lang, node = Node, sessionid = SessionID, elements = Res, status = completed}); {'EXIT', _} -> {error, ?ERR_BAD_REQUEST}; {error, Error} -> {error, Error} end end; true -> {error, ?ERR_BAD_REQUEST} end. -define(TVFIELD(Type, Var, Val), {xmlelement, "field", [{"type", Type}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). -define(HFIELD(), ?TVFIELD("hidden", "FORM_TYPE", ?NS_ADMIN)). -define(TLFIELD(Type, Label, Var), {xmlelement, "field", [{"type", Type}, {"label", ?T(Lang, Label)}, {"var", Var}], []}). -define(XFIELD(Type, Label, Var, Val), {xmlelement, "field", [{"type", Type}, {"label", ?T(Lang, Label)}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). -define(XMFIELD(Type, Label, Var, Vals), {xmlelement, "field", [{"type", Type}, {"label", ?T(Lang, Label)}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata,Val}]} || Val <- Vals]}). -define(TABLEFIELD(Table, Val), {xmlelement, "field", [{"type", "list-single"}, {"label", atom_to_list(Table)}, {"var", atom_to_list(Table)}], [{xmlelement, "value", [], [{xmlcdata, atom_to_list(Val)}]}, {xmlelement, "option", [{"label", ?T(Lang, "RAM copy")}], [{xmlelement, "value", [], [{xmlcdata, "ram_copies"}]}]}, {xmlelement, "option", [{"label", ?T(Lang, "RAM and disc copy")}], [{xmlelement, "value", [], [{xmlcdata, "disc_copies"}]}]}, {xmlelement, "option", [{"label", ?T(Lang, "Disc only copy")}], [{xmlelement, "value", [], [{xmlcdata, "disc_only_copies"}]}]}, {xmlelement, "option", [{"label", ?T(Lang, "Remote copy")}], [{xmlelement, "value", [], [{xmlcdata, "unknown"}]}]} ]}). get_form(_Host, ["running nodes", ENode, "DB"], Lang) -> case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> case rpc:call(Node, mnesia, system_info, [tables]) of {badrpc, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; Tables -> STables = lists:sort(Tables), {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T( Lang, "Database Tables Configuration at ") ++ ENode}]}, {xmlelement, "instructions", [], [{xmlcdata, ?T( Lang, "Choose storage type of tables")}]} | lists:map( fun(Table) -> case rpc:call(Node, mnesia, table_info, [Table, storage_type]) of {badrpc, _} -> ?TABLEFIELD(Table, unknown); Type -> ?TABLEFIELD(Table, Type) end end, STables) ]}]} end end; get_form(Host, ["running nodes", ENode, "modules", "stop"], Lang) -> case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> case rpc:call(Node, gen_mod, loaded_modules, [Host]) of {badrpc, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; Modules -> SModules = lists:sort(Modules), {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T( Lang, "Stop Modules at ") ++ ENode}]}, {xmlelement, "instructions", [], [{xmlcdata, ?T( Lang, "Choose modules to stop")}]} | lists:map(fun(M) -> S = atom_to_list(M), ?XFIELD("boolean", S, S, "0") end, SModules) ]}]} end end; get_form(_Host, ["running nodes", ENode, "modules", "start"], Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T( Lang, "Start Modules at ") ++ ENode}]}, {xmlelement, "instructions", [], [{xmlcdata, ?T( Lang, "Enter list of {Module, [Options]}")}]}, ?XFIELD("text-multi", "List of modules to start", "modules", "[].") ]}]}; get_form(_Host, ["running nodes", ENode, "backup", "backup"], Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T( Lang, "Backup to File at ") ++ ENode}]}, {xmlelement, "instructions", [], [{xmlcdata, ?T( Lang, "Enter path to backup file")}]}, ?XFIELD("text-single", "Path to File", "path", "") ]}]}; get_form(_Host, ["running nodes", ENode, "backup", "restore"], Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T( Lang, "Restore Backup from File at ") ++ ENode}]}, {xmlelement, "instructions", [], [{xmlcdata, ?T( Lang, "Enter path to backup file")}]}, ?XFIELD("text-single", "Path to File", "path", "") ]}]}; get_form(_Host, ["running nodes", ENode, "backup", "textfile"], Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T( Lang, "Dump Backup to Text File at ") ++ ENode}]}, {xmlelement, "instructions", [], [{xmlcdata, ?T( Lang, "Enter path to text file")}]}, ?XFIELD("text-single", "Path to File", "path", "") ]}]}; get_form(_Host, ["running nodes", ENode, "import", "file"], Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T( Lang, "Import User from File at ") ++ ENode}]}, {xmlelement, "instructions", [], [{xmlcdata, ?T( Lang, "Enter path to jabberd14 spool file")}]}, ?XFIELD("text-single", "Path to File", "path", "") ]}]}; get_form(_Host, ["running nodes", ENode, "import", "dir"], Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T( Lang, "Import Users from Dir at ") ++ ENode}]}, {xmlelement, "instructions", [], [{xmlcdata, ?T( Lang, "Enter path to jabberd14 spool dir")}]}, ?XFIELD("text-single", "Path to Dir", "path", "") ]}]}; get_form(_Host, ["running nodes", _ENode, "restart"], Lang) -> Make_option = fun(LabelNum, LabelUnit, Value)-> {xmlelement, "option", [{"label", LabelNum ++ ?T(Lang, LabelUnit)}], [{xmlelement, "value", [], [{xmlcdata, Value}]}]} end, {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T(Lang, "Restart Service")}]}, {xmlelement, "field", [{"type", "list-single"}, {"label", ?T(Lang, "Time delay")}, {"var", "delay"}], [Make_option("", "immediately", "1"), Make_option("15 ", "seconds", "15"), Make_option("30 ", "seconds", "30"), Make_option("60 ", "seconds", "60"), Make_option("90 ", "seconds", "90"), Make_option("2 ", "minutes", "120"), Make_option("3 ", "minutes", "180"), Make_option("4 ", "minutes", "240"), Make_option("5 ", "minutes", "300"), Make_option("10 ", "minutes", "600"), Make_option("15 ", "minutes", "900"), Make_option("30 ", "minutes", "1800"), {xmlelement, "required", [], []} ]}, {xmlelement, "field", [{"type", "fixed"}, {"label", ?T(Lang, "Send announcement to all online users on all hosts")}], []}, {xmlelement, "field", [{"var", "subject"}, {"type", "text-single"}, {"label", ?T(Lang, "Subject")}], []}, {xmlelement, "field", [{"var", "announcement"}, {"type", "text-multi"}, {"label", ?T(Lang, "Message body")}], []} ]}]}; get_form(_Host, ["running nodes", _ENode, "shutdown"], Lang) -> Make_option = fun(LabelNum, LabelUnit, Value)-> {xmlelement, "option", [{"label", LabelNum ++ ?T(Lang, LabelUnit)}], [{xmlelement, "value", [], [{xmlcdata, Value}]}]} end, {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T(Lang, "Shut Down Service")}]}, {xmlelement, "field", [{"type", "list-single"}, {"label", ?T(Lang, "Time delay")}, {"var", "delay"}], [Make_option("", "immediately", "1"), Make_option("15 ", "seconds", "15"), Make_option("30 ", "seconds", "30"), Make_option("60 ", "seconds", "60"), Make_option("90 ", "seconds", "90"), Make_option("2 ", "minutes", "120"), Make_option("3 ", "minutes", "180"), Make_option("4 ", "minutes", "240"), Make_option("5 ", "minutes", "300"), Make_option("10 ", "minutes", "600"), Make_option("15 ", "minutes", "900"), Make_option("30 ", "minutes", "1800"), {xmlelement, "required", [], []} ]}, {xmlelement, "field", [{"type", "fixed"}, {"label", ?T(Lang, "Send announcement to all online users on all hosts")}], []}, {xmlelement, "field", [{"var", "subject"}, {"type", "text-single"}, {"label", ?T(Lang, "Subject")}], []}, {xmlelement, "field", [{"var", "announcement"}, {"type", "text-multi"}, {"label", ?T(Lang, "Message body")}], []} ]}]}; get_form(Host, ["config", "acls"], Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T( Lang, "Access Control List Configuration")}]}, {xmlelement, "field", [{"type", "text-multi"}, {"label", ?T( Lang, "Access control lists")}, {"var", "acls"}], lists:map(fun(S) -> {xmlelement, "value", [], [{xmlcdata, S}]} end, string:tokens( lists:flatten( io_lib:format( "~p.", [ets:select(acl, [{{acl, {'$1', '$2'}, '$3'}, [{'==', '$2', Host}], [{{acl, '$1', '$3'}}]}]) ])), "\n")) } ]}]}; get_form(Host, ["config", "access"], Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T( Lang, "Access Configuration")}]}, {xmlelement, "field", [{"type", "text-multi"}, {"label", ?T( Lang, "Access rules")}, {"var", "access"}], lists:map(fun(S) -> {xmlelement, "value", [], [{xmlcdata, S}]} end, string:tokens( lists:flatten( io_lib:format( "~p.", [ets:select(config, [{{config, {access, '$1', '$2'}, '$3'}, [{'==', '$2', Host}], [{{access, '$1', '$3'}}]}]) ])), "\n")) } ]}]}; get_form(_Host, ?NS_ADMINL("add-user"), Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T(Lang, "Add User")}]}, {xmlelement, "field", [{"type", "jid-single"}, {"label", ?T(Lang, "Jabber ID")}, {"var", "accountjid"}], [{xmlelement, "required", [], []}]}, {xmlelement, "field", [{"type", "text-private"}, {"label", ?T(Lang, "Password")}, {"var", "password"}], [{xmlelement, "required", [], []}]}, {xmlelement, "field", [{"type", "text-private"}, {"label", ?T(Lang, "Password Verification")}, {"var", "password-verify"}], [{xmlelement, "required", [], []}]} ]}]}; get_form(_Host, ?NS_ADMINL("delete-user"), Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T(Lang, "Delete User")}]}, {xmlelement, "field", [{"type", "jid-multi"}, {"label", ?T(Lang, "Jabber ID")}, {"var", "accountjids"}], [{xmlelement, "required", [], []}]} ]}]}; get_form(_Host, ?NS_ADMINL("end-user-session"), Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T(Lang, "End User Session")}]}, {xmlelement, "field", [{"type", "jid-single"}, {"label", ?T(Lang, "Jabber ID")}, {"var", "accountjid"}], [{xmlelement, "required", [], []}]} ]}]}; get_form(_Host, ?NS_ADMINL("get-user-password"), Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T(Lang, "Get User Password")}]}, {xmlelement, "field", [{"type", "jid-single"}, {"label", ?T(Lang, "Jabber ID")}, {"var", "accountjid"}], [{xmlelement, "required", [], []}]} ]}]}; get_form(_Host, ?NS_ADMINL("change-user-password"), Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T(Lang, "Get User Password")}]}, {xmlelement, "field", [{"type", "jid-single"}, {"label", ?T(Lang, "Jabber ID")}, {"var", "accountjid"}], [{xmlelement, "required", [], []}]}, {xmlelement, "field", [{"type", "text-private"}, {"label", ?T(Lang, "Password")}, {"var", "password"}], [{xmlelement, "required", [], []}]} ]}]}; get_form(_Host, ?NS_ADMINL("get-user-lastlogin"), Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T(Lang, "Get User Last Login Time")}]}, {xmlelement, "field", [{"type", "jid-single"}, {"label", ?T(Lang, "Jabber ID")}, {"var", "accountjid"}], [{xmlelement, "required", [], []}]} ]}]}; get_form(_Host, ?NS_ADMINL("user-stats"), Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T(Lang, "Get User Statistics")}]}, {xmlelement, "field", [{"type", "jid-single"}, {"label", ?T(Lang, "Jabber ID")}, {"var", "accountjid"}], [{xmlelement, "required", [], []}]} ]}]}; get_form(Host, ?NS_ADMINL("get-registered-users-num"), Lang) -> [Num] = io_lib:format("~p", [ejabberd_auth:get_vh_registered_users_number(Host)]), {result, completed, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "field", [{"type", "text-single"}, {"label", ?T(Lang, "Number of registered users")}, {"var", "registeredusersnum"}], [{xmlelement, "value", [], [{xmlcdata, Num}]}] }]}]}; get_form(Host, ?NS_ADMINL("get-online-users-num"), Lang) -> Num = io_lib:format("~p", [length(ejabberd_sm:get_vh_session_list(Host))]), {result, completed, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "field", [{"type", "text-single"}, {"label", ?T(Lang, "Number of online users")}, {"var", "onlineusersnum"}], [{xmlelement, "value", [], [{xmlcdata, Num}]}] }]}]}; get_form(_Host, _, _Lang) -> {error, ?ERR_SERVICE_UNAVAILABLE}. set_form(_From, _Host, ["running nodes", ENode, "DB"], _Lang, XData) -> case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> lists:foreach( fun({SVar, SVals}) -> %% We believe that this is allowed only for good people Table = list_to_atom(SVar), Type = case SVals of ["unknown"] -> unknown; ["ram_copies"] -> ram_copies; ["disc_copies"] -> disc_copies; ["disc_only_copies"] -> disc_only_copies; _ -> false end, if Type == false -> ok; Type == unknown -> mnesia:del_table_copy(Table, Node); true -> case mnesia:add_table_copy(Table, Node, Type) of {aborted, _} -> mnesia:change_table_copy_type( Table, Node, Type); _ -> ok end end end, XData), {result, []} end; set_form(_From, Host, ["running nodes", ENode, "modules", "stop"], _Lang, XData) -> case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> lists:foreach( fun({Var, Vals}) -> case Vals of ["1"] -> Module = list_to_atom(Var), rpc:call(Node, gen_mod, stop_module, [Host, Module]); _ -> ok end end, XData), {result, []} end; set_form(_From, Host, ["running nodes", ENode, "modules", "start"], _Lang, XData) -> case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> case lists:keysearch("modules", 1, XData) of false -> {error, ?ERR_BAD_REQUEST}; {value, {_, Strings}} -> String = lists:foldl(fun(S, Res) -> Res ++ S ++ "\n" end, "", Strings), case erl_scan:string(String) of {ok, Tokens, _} -> case erl_parse:parse_term(Tokens) of {ok, Modules} -> lists:foreach( fun({Module, Args}) -> rpc:call(Node, gen_mod, start_module, [Host, Module, Args]) end, Modules), {result, []}; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end end end; set_form(_From, _Host, ["running nodes", ENode, "backup", "backup"], _Lang, XData) -> case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> case lists:keysearch("path", 1, XData) of false -> {error, ?ERR_BAD_REQUEST}; {value, {_, [String]}} -> case rpc:call(Node, mnesia, backup, [String]) of {badrpc, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; {error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; _ -> {result, []} end; _ -> {error, ?ERR_BAD_REQUEST} end end; set_form(_From, _Host, ["running nodes", ENode, "backup", "restore"], _Lang, XData) -> case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> case lists:keysearch("path", 1, XData) of false -> {error, ?ERR_BAD_REQUEST}; {value, {_, [String]}} -> case rpc:call(Node, ejabberd_admin, restore, [String]) of {badrpc, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; {error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; _ -> {result, []} end; _ -> {error, ?ERR_BAD_REQUEST} end end; set_form(_From, _Host, ["running nodes", ENode, "backup", "textfile"], _Lang, XData) -> case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> case lists:keysearch("path", 1, XData) of false -> {error, ?ERR_BAD_REQUEST}; {value, {_, [String]}} -> case rpc:call(Node, ejabberd_admin, dump_to_textfile, [String]) of {badrpc, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; {error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; _ -> {result, []} end; _ -> {error, ?ERR_BAD_REQUEST} end end; set_form(_From, _Host, ["running nodes", ENode, "import", "file"], _Lang, XData) -> case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> case lists:keysearch("path", 1, XData) of false -> {error, ?ERR_BAD_REQUEST}; {value, {_, [String]}} -> rpc:call(Node, jd2ejd, import_file, [String]), {result, []}; _ -> {error, ?ERR_BAD_REQUEST} end end; set_form(_From, _Host, ["running nodes", ENode, "import", "dir"], _Lang, XData) -> case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> case lists:keysearch("path", 1, XData) of false -> {error, ?ERR_BAD_REQUEST}; {value, {_, [String]}} -> rpc:call(Node, jd2ejd, import_dir, [String]), {result, []}; _ -> {error, ?ERR_BAD_REQUEST} end end; set_form(From, Host, ["running nodes", ENode, "restart"], _Lang, XData) -> stop_node(From, Host, ENode, restart, XData); set_form(From, Host, ["running nodes", ENode, "shutdown"], _Lang, XData) -> stop_node(From, Host, ENode, stop, XData); set_form(_From, Host, ["config", "acls"], _Lang, XData) -> case lists:keysearch("acls", 1, XData) of {value, {_, Strings}} -> String = lists:foldl(fun(S, Res) -> Res ++ S ++ "\n" end, "", Strings), case erl_scan:string(String) of {ok, Tokens, _} -> case erl_parse:parse_term(Tokens) of {ok, ACLs} -> case acl:add_list(Host, ACLs, true) of ok -> {result, []}; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end; set_form(_From, Host, ["config", "access"], _Lang, XData) -> SetAccess = fun(Rs) -> mnesia:transaction( fun() -> Os = mnesia:select(config, [{{config, {access, '$1', '$2'}, '$3'}, [{'==', '$2', Host}], ['$_']}]), lists:foreach(fun(O) -> mnesia:delete_object(O) end, Os), lists:foreach( fun({access, Name, Rules}) -> mnesia:write({config, {access, Name, Host}, Rules}) end, Rs) end) end, case lists:keysearch("access", 1, XData) of {value, {_, Strings}} -> String = lists:foldl(fun(S, Res) -> Res ++ S ++ "\n" end, "", Strings), case erl_scan:string(String) of {ok, Tokens, _} -> case erl_parse:parse_term(Tokens) of {ok, Rs} -> case SetAccess(Rs) of {atomic, _} -> {result, []}; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end; set_form(From, Host, ?NS_ADMINL("add-user"), _Lang, XData) -> AccountString = get_value("accountjid", XData), Password = get_value("password", XData), Password = get_value("password-verify", XData), AccountJID = jlib:string_to_jid(AccountString), User = AccountJID#jid.luser, Server = AccountJID#jid.lserver, true = lists:member(Server, ?MYHOSTS), true = (Server == Host) orelse (get_permission_level(From) == global), ejabberd_auth:try_register(User, Server, Password), {result, []}; set_form(From, Host, ?NS_ADMINL("delete-user"), _Lang, XData) -> AccountStringList = get_values("accountjids", XData), [_|_] = AccountStringList, ASL2 = lists:map( fun(AccountString) -> JID = jlib:string_to_jid(AccountString), [_|_] = JID#jid.luser, User = JID#jid.luser, Server = JID#jid.lserver, true = (Server == Host) orelse (get_permission_level(From) == global), true = ejabberd_auth:is_user_exists(User, Server), {User, Server} end, AccountStringList), [ejabberd_auth:remove_user(User, Server) || {User, Server} <- ASL2], {result, []}; set_form(From, Host, ?NS_ADMINL("end-user-session"), _Lang, XData) -> AccountString = get_value("accountjid", XData), JID = jlib:string_to_jid(AccountString), [_|_] = JID#jid.luser, LUser = JID#jid.luser, LServer = JID#jid.lserver, true = (LServer == Host) orelse (get_permission_level(From) == global), %% Code copied from ejabberd_sm.erl case JID#jid.lresource of [] -> SIDs = mnesia:dirty_select(session, [{#session{sid = '$1', usr = {LUser, LServer, '_'}, _ = '_'}, [], ['$1']}]), [Pid ! replaced || {_, Pid} <- SIDs]; R -> [{_, Pid}] = mnesia:dirty_select(session, [{#session{sid = '$1', usr = {LUser, LServer, R}, _ = '_'}, [], ['$1']}]), Pid ! replaced end, {result, []}; set_form(From, Host, ?NS_ADMINL("get-user-password"), Lang, XData) -> AccountString = get_value("accountjid", XData), JID = jlib:string_to_jid(AccountString), [_|_] = JID#jid.luser, User = JID#jid.luser, Server = JID#jid.lserver, true = (Server == Host) orelse (get_permission_level(From) == global), Password = ejabberd_auth:get_password(User, Server), true = is_list(Password), {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), ?XFIELD("jid-single", "Jabber ID", "accountjid", AccountString), ?XFIELD("text-single", "Password", "password", Password) ]}]}; set_form(From, Host, ?NS_ADMINL("change-user-password"), _Lang, XData) -> AccountString = get_value("accountjid", XData), Password = get_value("password", XData), JID = jlib:string_to_jid(AccountString), [_|_] = JID#jid.luser, User = JID#jid.luser, Server = JID#jid.lserver, true = (Server == Host) orelse (get_permission_level(From) == global), true = ejabberd_auth:is_user_exists(User, Server), ejabberd_auth:set_password(User, Server, Password), {result, []}; set_form(From, Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) -> AccountString = get_value("accountjid", XData), JID = jlib:string_to_jid(AccountString), [_|_] = JID#jid.luser, User = JID#jid.luser, Server = JID#jid.lserver, true = (Server == Host) orelse (get_permission_level(From) == global), %% Code copied from web/ejabberd_web_admin.erl %% TODO: Update time format to XEP-0202: Entity Time FLast = case ejabberd_sm:get_user_resources(User, Server) of [] -> _US = {User, Server}, case get_last_info(User, Server) of not_found -> ?T(Lang, "Never"); {ok, Timestamp, _Status} -> Shift = Timestamp, TimeStamp = {Shift div 1000000, Shift rem 1000000, 0}, {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:now_to_local_time(TimeStamp), lists:flatten( io_lib:format( "~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Year, Month, Day, Hour, Minute, Second])) end; _ -> ?T(Lang, "Online") end, {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}], [?HFIELD(), ?XFIELD("jid-single", "Jabber ID", "accountjid", AccountString), ?XFIELD("text-single", "Last login", "lastlogin", FLast) ]}]}; set_form(From, Host, ?NS_ADMINL("user-stats"), Lang, XData) -> AccountString = get_value("accountjid", XData), JID = jlib:string_to_jid(AccountString), [_|_] = JID#jid.luser, User = JID#jid.luser, Server = JID#jid.lserver, true = (Server == Host) orelse (get_permission_level(From) == global), Resources = ejabberd_sm:get_user_resources(User, Server), IPs1 = [ejabberd_sm:get_user_ip(User, Server, Resource) || Resource <- Resources], IPs = [inet_parse:ntoa(IP)++":"++integer_to_list(Port) || {IP, Port} <- IPs1], Items = ejabberd_hooks:run_fold(roster_get, Server, [], [{User, Server}]), Rostersize = integer_to_list(erlang:length(Items)), {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), ?XFIELD("jid-single", "Jabber ID", "accountjid", AccountString), ?XFIELD("text-single", "Roster size", "rostersize", Rostersize), ?XMFIELD("text-multi", "IP addresses", "ipaddresses", IPs), ?XMFIELD("text-multi", "Resources", "onlineresources", Resources) ]}]}; set_form(_From, _Host, _, _Lang, _XData) -> {error, ?ERR_SERVICE_UNAVAILABLE}. get_value(Field, XData) -> hd(get_values(Field, XData)). get_values(Field, XData) -> {value, {_, ValueList}} = lists:keysearch(Field, 1, XData), ValueList. search_running_node(SNode) -> search_running_node(SNode, mnesia:system_info(running_db_nodes)). search_running_node(_, []) -> false; search_running_node(SNode, [Node | Nodes]) -> case atom_to_list(Node) of SNode -> Node; _ -> search_running_node(SNode, Nodes) end. stop_node(From, Host, ENode, Action, XData) -> Delay = list_to_integer(get_value("delay", XData)), Subject = case get_value("subject", XData) of [] -> []; S -> [{xmlelement, "field", [{"var","subject"}], [{xmlelement,"value",[],[{xmlcdata,S}]}]}] end, Announcement = case get_values("announcement", XData) of [] -> []; As -> [{xmlelement, "field", [{"var","body"}], [{xmlelement,"value",[],[{xmlcdata,Line}]} || Line <- As] }] end, case Subject ++ Announcement of [] -> ok; SubEls -> Request = #adhoc_request{ node = ?NS_ADMINX("announce-allhosts"), action = "complete", xdata = {xmlelement, "x", [{"xmlns","jabber:x:data"},{"type","submit"}], SubEls}, others= [{xmlelement, "x", [{"xmlns","jabber:x:data"},{"type","submit"}], SubEls}] }, To = jlib:make_jid("", Host, ""), mod_announce:announce_commands(empty, From, To, Request) end, Time = timer:seconds(Delay), Node = list_to_atom(ENode), {ok, _} = timer:apply_after(Time, rpc, call, [Node, init, Action, []]), {result, []}. get_last_info(User, Server) -> ML = lists:member(mod_last, gen_mod:loaded_modules(Server)), MLO = lists:member(mod_last_odbc, gen_mod:loaded_modules(Server)), case {ML, MLO} of {true, _} -> mod_last:get_last_info(User, Server); {false, true} -> mod_last_odbc:get_last_info(User, Server); {false, false} -> not_found end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% adhoc_sm_commands(_Acc, From, #jid{user = User, server = Server, lserver = LServer} = _To, #adhoc_request{lang = Lang, node = "config", action = Action, xdata = XData} = Request) -> case acl:match_rule(LServer, configure, From) of deny -> {error, ?ERR_FORBIDDEN}; allow -> %% If the "action" attribute is not present, it is %% understood as "execute". If there was no %% element in the first response (which there isn't in our %% case), "execute" and "complete" are equivalent. ActionIsExecute = lists:member(Action, ["", "execute", "complete"]), if Action == "cancel" -> %% User cancels request adhoc:produce_response( Request, #adhoc_response{status = canceled}); XData == false, ActionIsExecute -> %% User requests form case get_sm_form(User, Server, "config", Lang) of {result, Form} -> adhoc:produce_response( Request, #adhoc_response{status = executing, elements = Form}); {error, Error} -> {error, Error} end; XData /= false, ActionIsExecute -> %% User returns form. case jlib:parse_xdata_submit(XData) of invalid -> {error, ?ERR_BAD_REQUEST}; Fields -> set_sm_form(User, Server, "config", Request, Fields) end; true -> {error, ?ERR_BAD_REQUEST} end end; adhoc_sm_commands(Acc, _From, _To, _Request) -> Acc. get_sm_form(User, Server, "config", Lang) -> {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}], [?HFIELD(), {xmlelement, "title", [], [{xmlcdata, ?T( Lang, "Administration of ") ++ User}]}, {xmlelement, "field", [{"type", "list-single"}, {"label", ?T(Lang, "Action on user")}, {"var", "action"}], [{xmlelement, "value", [], [{xmlcdata, "edit"}]}, {xmlelement, "option", [{"label", ?T(Lang, "Edit Properties")}], [{xmlelement, "value", [], [{xmlcdata, "edit"}]}]}, {xmlelement, "option", [{"label", ?T(Lang, "Remove User")}], [{xmlelement, "value", [], [{xmlcdata, "remove"}]}]} ]}, ?XFIELD("text-private", "Password", "password", ejabberd_auth:get_password_s(User, Server)) ]}]}; get_sm_form(_User, _Server, _Node, _Lang) -> {error, ?ERR_SERVICE_UNAVAILABLE}. set_sm_form(User, Server, "config", #adhoc_request{lang = Lang, node = Node, sessionid = SessionID}, XData) -> Response = #adhoc_response{lang = Lang, node = Node, sessionid = SessionID, status = completed}, case lists:keysearch("action", 1, XData) of {value, {_, ["edit"]}} -> case lists:keysearch("password", 1, XData) of {value, {_, [Password]}} -> ejabberd_auth:set_password(User, Server, Password), adhoc:produce_response(Response); _ -> {error, ?ERR_NOT_ACCEPTABLE} end; {value, {_, ["remove"]}} -> catch ejabberd_auth:remove_user(User, Server), adhoc:produce_response(Response); _ -> {error, ?ERR_NOT_ACCEPTABLE} end; set_sm_form(_User, _Server, _Node, _Request, _Fields) -> {error, ?ERR_SERVICE_UNAVAILABLE}. ejabberd-2.1.11/src/ejabberd.app0000664000000000000000000000621312240230175013247 0ustar %% $Id$ {application, ejabberd, [{description, "ejabberd"}, {vsn, "2.1.11"}, {modules, [acl, adhoc, configure, cyrsasl_anonymous, cyrsasl, cyrsasl_digest, cyrsasl_plain, cyrsasl_scram, ejabberd_admin, ejabberd_app, ejabberd_auth_anonymous, ejabberd_auth, ejabberd_auth_external, ejabberd_auth_internal, ejabberd_auth_ldap, ejabberd_auth_odbc, ejabberd_auth_pam, ejabberd, ejabberd_c2s, ejabberd_c2s_config, ejabberd_config, ejabberd_ctl, ejabberd_frontend_socket, ejabberd_hooks, ejabberd_http, ejabberd_http_bind, ejabberd_http_poll, ejabberd_listener, ejabberd_local, ejabberd_logger_h, ejabberd_loglevel, ejabberd_node_groups, ejabberd_rdbms, ejabberd_receiver, ejabberd_router, ejabberd_s2s, ejabberd_s2s_in, ejabberd_s2s_out, ejabberd_service, ejabberd_sm, ejabberd_socket, ejabberd_sup, ejabberd_system_monitor, ejabberd_tmp_sup, ejabberd_update, ejabberd_web_admin, ejabberd_web, ejabberd_zlib, ejd2odbc, eldap, eldap_filter, eldap_pool, eldap_utils, 'ELDAPv3', extauth, gen_iq_handler, gen_mod, gen_pubsub_node, gen_pubsub_nodetree, iconv, idna, jd2ejd, jlib, mod_adhoc, mod_announce, mod_caps, mod_configure2, mod_configure, mod_disco, mod_echo, mod_http_bind, mod_http_fileserver, mod_irc, mod_irc_connection, mod_last, mod_last_odbc, mod_muc, mod_muc_log, mod_muc_room, mod_offline, mod_offline_odbc, mod_privacy, mod_privacy_odbc, mod_private, mod_private_odbc, mod_proxy65, mod_proxy65_lib, mod_proxy65_service, mod_proxy65_sm, mod_proxy65_stream, mod_pubsub, mod_register, mod_roster, mod_roster_odbc, mod_service_log, mod_shared_roster, mod_stats, mod_time, mod_vcard, mod_vcard_ldap, mod_vcard_odbc, mod_version, node_buddy, node_club, node_default, node_dispatch, node_pep, node_private, node_public, nodetree_default, nodetree_virtual, p1_fsm, p1_mnesia, p1_prof, randoms, sha, shaper, stringprep, stringprep_sup, tls, translate, xml, xml_stream, 'XmppAddr' ]}, {registered, [ejabberd, ejabberd_sup, ejabberd_auth, ejabberd_router, ejabberd_sm, ejabberd_s2s, ejabberd_local, ejabberd_listeners, ejabberd_iq_sup, ejabberd_service_sup, ejabberd_s2s_out_sup, ejabberd_s2s_in_sup, ejabberd_c2s_sup, ejabberd_mod_roster, ejabberd_mod_echo, ejabberd_mod_pubsub, ejabberd_mod_irc, ejabberd_mod_muc, ejabberd_offline, random_generator ]}, {applications, [kernel, stdlib]}, {env, []}, {mod, {ejabberd_app, []}}]}. %% Local Variables: %% mode: erlang %% End: %% vim: set filetype=erlang tabstop=8: ejabberd-2.1.11/src/ejabberd_hooks.erl0000664000000000000000000002635312240230175014463 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_hooks.erl %%% Author : Alexey Shchepin %%% Purpose : Manage hooks %%% Created : 8 Aug 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_hooks). -author('alexey@process-one.net'). -behaviour(gen_server). %% External exports -export([start_link/0, add/3, add/4, add_dist/5, delete/3, delete/4, delete_dist/5, run/2, run_fold/3, add/5, add_dist/6, delete/5, delete_dist/6, run/3, run_fold/4]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, code_change/3, handle_info/2, terminate/2]). -include("ejabberd.hrl"). %% Timeout of 5 seconds in calls to distributed hooks -define(TIMEOUT_DISTRIBUTED_HOOK, 5000). -record(state, {}). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ejabberd_hooks}, ejabberd_hooks, [], []). %% @spec (Hook::atom(), Function::function(), Seq::integer()) -> ok %% @doc See add/4. add(Hook, Function, Seq) when is_function(Function) -> add(Hook, global, undefined, Function, Seq). add(Hook, Host, Function, Seq) when is_function(Function) -> add(Hook, Host, undefined, Function, Seq); %% @spec (Hook::atom(), Module::atom(), Function::atom(), Seq::integer()) -> ok %% @doc Add a module and function to this hook. %% The integer sequence is used to sort the calls: low number is called before high number. add(Hook, Module, Function, Seq) -> add(Hook, global, Module, Function, Seq). add(Hook, Host, Module, Function, Seq) -> gen_server:call(ejabberd_hooks, {add, Hook, Host, Module, Function, Seq}). add_dist(Hook, Node, Module, Function, Seq) -> gen_server:call(ejabberd_hooks, {add, Hook, global, Node, Module, Function, Seq}). add_dist(Hook, Host, Node, Module, Function, Seq) -> gen_server:call(ejabberd_hooks, {add, Hook, Host, Node, Module, Function, Seq}). %% @spec (Hook::atom(), Function::function(), Seq::integer()) -> ok %% @doc See del/4. delete(Hook, Function, Seq) when is_function(Function) -> delete(Hook, global, undefined, Function, Seq). delete(Hook, Host, Function, Seq) when is_function(Function) -> delete(Hook, Host, undefined, Function, Seq); %% @spec (Hook::atom(), Module::atom(), Function::atom(), Seq::integer()) -> ok %% @doc Delete a module and function from this hook. %% It is important to indicate exactly the same information than when the call was added. delete(Hook, Module, Function, Seq) -> delete(Hook, global, Module, Function, Seq). delete(Hook, Host, Module, Function, Seq) -> gen_server:call(ejabberd_hooks, {delete, Hook, Host, Module, Function, Seq}). delete_dist(Hook, Node, Module, Function, Seq) -> delete_dist(Hook, global, Node, Module, Function, Seq). delete_dist(Hook, Host, Node, Module, Function, Seq) -> gen_server:call(ejabberd_hooks, {delete, Hook, Host, Node, Module, Function, Seq}). %% @spec (Hook::atom(), Args) -> ok %% @doc Run the calls of this hook in order, don't care about function results. %% If a call returns stop, no more calls are performed. run(Hook, Args) -> run(Hook, global, Args). run(Hook, Host, Args) -> case ets:lookup(hooks, {Hook, Host}) of [{_, Ls}] -> run1(Ls, Hook, Args); [] -> ok end. %% @spec (Hook::atom(), Val, Args) -> Val | stopped | NewVal %% @doc Run the calls of this hook in order. %% The arguments passed to the function are: [Val | Args]. %% The result of a call is used as Val for the next call. %% If a call returns 'stop', no more calls are performed and 'stopped' is returned. %% If a call returns {stopped, NewVal}, no more calls are performed and NewVal is returned. run_fold(Hook, Val, Args) -> run_fold(Hook, global, Val, Args). run_fold(Hook, Host, Val, Args) -> case ets:lookup(hooks, {Hook, Host}) of [{_, Ls}] -> run_fold1(Ls, Hook, Val, Args); [] -> Val end. %%%---------------------------------------------------------------------- %%% Callback functions from gen_server %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %%---------------------------------------------------------------------- init([]) -> ets:new(hooks, [named_table]), {ok, #state{}}. %%---------------------------------------------------------------------- %% Func: handle_call/3 %% Returns: {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | (terminate/2 is called) %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_call({add, Hook, Host, Module, Function, Seq}, _From, State) -> Reply = case ets:lookup(hooks, {Hook, Host}) of [{_, Ls}] -> El = {Seq, Module, Function}, case lists:member(El, Ls) of true -> ok; false -> NewLs = lists:merge(Ls, [El]), ets:insert(hooks, {{Hook, Host}, NewLs}), ok end; [] -> NewLs = [{Seq, Module, Function}], ets:insert(hooks, {{Hook, Host}, NewLs}), ok end, {reply, Reply, State}; handle_call({add, Hook, Host, Node, Module, Function, Seq}, _From, State) -> Reply = case ets:lookup(hooks, {Hook, Host}) of [{_, Ls}] -> El = {Seq, Node, Module, Function}, case lists:member(El, Ls) of true -> ok; false -> NewLs = lists:merge(Ls, [El]), ets:insert(hooks, {{Hook, Host}, NewLs}), ok end; [] -> NewLs = [{Seq, Node, Module, Function}], ets:insert(hooks, {{Hook, Host}, NewLs}), ok end, {reply, Reply, State}; handle_call({delete, Hook, Host, Module, Function, Seq}, _From, State) -> Reply = case ets:lookup(hooks, {Hook, Host}) of [{_, Ls}] -> NewLs = lists:delete({Seq, Module, Function}, Ls), ets:insert(hooks, {{Hook, Host}, NewLs}), ok; [] -> ok end, {reply, Reply, State}; handle_call({delete, Hook, Host, Node, Module, Function, Seq}, _From, State) -> Reply = case ets:lookup(hooks, {Hook, Host}) of [{_, Ls}] -> NewLs = lists:delete({Seq, Node, Module, Function}, Ls), ets:insert(hooks, {{Hook, Host}, NewLs}), ok; [] -> ok end, {reply, Reply, State}; handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. %%---------------------------------------------------------------------- %% Func: handle_cast/2 %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%---------------------------------------------------------------------- %% Func: handle_info/2 %% Returns: {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%---------------------------------------------------------------------- handle_info(_Info, State) -> {noreply, State}. %%---------------------------------------------------------------------- %% Func: terminate/2 %% Purpose: Shutdown the server %% Returns: any (ignored by gen_server) %%---------------------------------------------------------------------- terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- run1([], _Hook, _Args) -> ok; run1([{_Seq, Node, Module, Function} | Ls], Hook, Args) -> case rpc:call(Node, Module, Function, Args, ?TIMEOUT_DISTRIBUTED_HOOK) of timeout -> ?ERROR_MSG("Timeout on RPC to ~p~nrunning hook: ~p", [Node, {Hook, Args}]), run1(Ls, Hook, Args); {badrpc, Reason} -> ?ERROR_MSG("Bad RPC error to ~p: ~p~nrunning hook: ~p", [Node, Reason, {Hook, Args}]), run1(Ls, Hook, Args); stop -> ?INFO_MSG("~nThe process ~p in node ~p ran a hook in node ~p.~n" "Stop.", [self(), node(), Node]), % debug code ok; Res -> ?INFO_MSG("~nThe process ~p in node ~p ran a hook in node ~p.~n" "The response is:~n~s", [self(), node(), Node, Res]), % debug code run1(Ls, Hook, Args) end; run1([{_Seq, Module, Function} | Ls], Hook, Args) -> Res = if is_function(Function) -> catch apply(Function, Args); true -> catch apply(Module, Function, Args) end, case Res of {'EXIT', Reason} -> ?ERROR_MSG("~p~nrunning hook: ~p", [Reason, {Hook, Args}]), run1(Ls, Hook, Args); stop -> ok; _ -> run1(Ls, Hook, Args) end. run_fold1([], _Hook, Val, _Args) -> Val; run_fold1([{_Seq, Node, Module, Function} | Ls], Hook, Val, Args) -> case rpc:call(Node, Module, Function, [Val | Args], ?TIMEOUT_DISTRIBUTED_HOOK) of {badrpc, Reason} -> ?ERROR_MSG("Bad RPC error to ~p: ~p~nrunning hook: ~p", [Node, Reason, {Hook, Args}]), run_fold1(Ls, Hook, Val, Args); timeout -> ?ERROR_MSG("Timeout on RPC to ~p~nrunning hook: ~p", [Node, {Hook, Args}]), run_fold1(Ls, Hook, Val, Args); stop -> stopped; {stop, NewVal} -> ?INFO_MSG("~nThe process ~p in node ~p ran a hook in node ~p.~n" "Stop, and the NewVal is:~n~p", [self(), node(), Node, NewVal]), % debug code NewVal; NewVal -> ?INFO_MSG("~nThe process ~p in node ~p ran a hook in node ~p.~n" "The NewVal is:~n~p", [self(), node(), Node, NewVal]), % debug code run_fold1(Ls, Hook, NewVal, Args) end; run_fold1([{_Seq, Module, Function} | Ls], Hook, Val, Args) -> Res = if is_function(Function) -> catch apply(Function, [Val | Args]); true -> catch apply(Module, Function, [Val | Args]) end, case Res of {'EXIT', Reason} -> ?ERROR_MSG("~p~nrunning hook: ~p", [Reason, {Hook, Args}]), run_fold1(Ls, Hook, Val, Args); stop -> stopped; {stop, NewVal} -> NewVal; NewVal -> run_fold1(Ls, Hook, NewVal, Args) end. ejabberd-2.1.11/src/ejabberd_sm.erl0000664000000000000000000006162612240230175013761 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_sm.erl %%% Author : Alexey Shchepin %%% Purpose : Session manager %%% Created : 24 Nov 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_sm). -author('alexey@process-one.net'). -behaviour(gen_server). %% API -export([start_link/0, route/3, open_session/5, close_session/4, check_in_subscription/6, bounce_offline_message/3, disconnect_removed_user/2, get_user_resources/2, set_presence/7, unset_presence/6, close_session_unset_presence/5, dirty_get_sessions_list/0, dirty_get_my_sessions_list/0, get_vh_session_list/1, get_vh_session_number/1, register_iq_handler/4, register_iq_handler/5, unregister_iq_handler/2, force_update_presence/1, connected_users/0, connected_users_number/0, user_resources/2, get_session_pid/3, get_user_info/3, get_user_ip/3, is_existing_resource/3 ]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("ejabberd_commands.hrl"). -include("mod_privacy.hrl"). -record(session, {sid, usr, us, priority, info}). -record(session_counter, {vhost, count}). -record(state, {}). %% default value for the maximum number of user connections -define(MAX_USER_SESSIONS, infinity). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). route(From, To, Packet) -> case catch do_route(From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p~nwhen processing: ~p", [Reason, {From, To, Packet}]); _ -> ok end. open_session(SID, User, Server, Resource, Info) -> set_session(SID, User, Server, Resource, undefined, Info), mnesia:dirty_update_counter(session_counter, jlib:nameprep(Server), 1), check_for_sessions_to_replace(User, Server, Resource), JID = jlib:make_jid(User, Server, Resource), ejabberd_hooks:run(sm_register_connection_hook, JID#jid.lserver, [SID, JID, Info]). close_session(SID, User, Server, Resource) -> Info = case mnesia:dirty_read({session, SID}) of [] -> []; [#session{info=I}] -> I end, F = fun() -> mnesia:delete({session, SID}), mnesia:dirty_update_counter(session_counter, jlib:nameprep(Server), -1) end, mnesia:sync_dirty(F), JID = jlib:make_jid(User, Server, Resource), ejabberd_hooks:run(sm_remove_connection_hook, JID#jid.lserver, [SID, JID, Info]). check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) -> case ejabberd_auth:is_user_exists(User, Server) of true -> Acc; false -> {stop, false} end. bounce_offline_message(From, To, Packet) -> Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err), stop. disconnect_removed_user(User, Server) -> ejabberd_sm:route(jlib:make_jid("", "", ""), jlib:make_jid(User, Server, ""), {xmlelement, "broadcast", [], [{exit, "User removed"}]}). get_user_resources(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, case catch mnesia:dirty_index_read(session, US, #session.us) of {'EXIT', _Reason} -> []; Ss -> [element(3, S#session.usr) || S <- clean_session_list(Ss)] end. get_user_ip(User, Server, Resource) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), LResource = jlib:resourceprep(Resource), USR = {LUser, LServer, LResource}, case mnesia:dirty_index_read(session, USR, #session.usr) of [] -> undefined; Ss -> Session = lists:max(Ss), proplists:get_value(ip, Session#session.info) end. get_user_info(User, Server, Resource) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), LResource = jlib:resourceprep(Resource), USR = {LUser, LServer, LResource}, case mnesia:dirty_index_read(session, USR, #session.usr) of [] -> offline; Ss -> Session = lists:max(Ss), Node = node(element(2, Session#session.sid)), Conn = proplists:get_value(conn, Session#session.info), IP = proplists:get_value(ip, Session#session.info), [{node, Node}, {conn, Conn}, {ip, IP}] end. set_presence(SID, User, Server, Resource, Priority, Presence, Info) -> set_session(SID, User, Server, Resource, Priority, Info), ejabberd_hooks:run(set_presence_hook, jlib:nameprep(Server), [User, Server, Resource, Presence]). unset_presence(SID, User, Server, Resource, Status, Info) -> set_session(SID, User, Server, Resource, undefined, Info), ejabberd_hooks:run(unset_presence_hook, jlib:nameprep(Server), [User, Server, Resource, Status]). close_session_unset_presence(SID, User, Server, Resource, Status) -> close_session(SID, User, Server, Resource), ejabberd_hooks:run(unset_presence_hook, jlib:nameprep(Server), [User, Server, Resource, Status]). get_session_pid(User, Server, Resource) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), LResource = jlib:resourceprep(Resource), USR = {LUser, LServer, LResource}, case catch mnesia:dirty_index_read(session, USR, #session.usr) of [#session{sid = {_, Pid}}] -> Pid; _ -> none end. dirty_get_sessions_list() -> mnesia:dirty_select( session, [{#session{usr = '$1', _ = '_'}, [], ['$1']}]). dirty_get_my_sessions_list() -> mnesia:dirty_select( session, [{#session{sid = {'_', '$1'}, _ = '_'}, [{'==', {node, '$1'}, node()}], ['$_']}]). get_vh_session_list(Server) -> LServer = jlib:nameprep(Server), mnesia:dirty_select( session, [{#session{usr = '$1', _ = '_'}, [{'==', {element, 2, '$1'}, LServer}], ['$1']}]). get_vh_session_number(Server) -> LServer = jlib:nameprep(Server), Query = mnesia:dirty_select( session_counter, [{#session_counter{vhost = LServer, count = '$1'}, [], ['$1']}]), case Query of [Count] -> Count; _ -> 0 end. register_iq_handler(Host, XMLNS, Module, Fun) -> ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun}. register_iq_handler(Host, XMLNS, Module, Fun, Opts) -> ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}. unregister_iq_handler(Host, XMLNS) -> ejabberd_sm ! {unregister_iq_handler, Host, XMLNS}. %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([]) -> update_tables(), mnesia:create_table(session, [{ram_copies, [node()]}, {attributes, record_info(fields, session)}]), mnesia:create_table(session_counter, [{ram_copies, [node()]}, {attributes, record_info(fields, session_counter)}]), mnesia:add_table_index(session, usr), mnesia:add_table_index(session, us), mnesia:add_table_copy(session, node(), ram_copies), mnesia:add_table_copy(session_counter, node(), ram_copies), mnesia:subscribe(system), ets:new(sm_iqtable, [named_table]), lists:foreach( fun(Host) -> ejabberd_hooks:add(roster_in_subscription, Host, ejabberd_sm, check_in_subscription, 20), ejabberd_hooks:add(offline_message_hook, Host, ejabberd_sm, bounce_offline_message, 100), ejabberd_hooks:add(remove_user, Host, ejabberd_sm, disconnect_removed_user, 100) end, ?MYHOSTS), ejabberd_commands:register_commands(commands()), {ok, #state{}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info({route, From, To, Packet}, State) -> case catch do_route(From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p~nwhen processing: ~p", [Reason, {From, To, Packet}]); _ -> ok end, {noreply, State}; handle_info({mnesia_system_event, {mnesia_down, Node}}, State) -> recount_session_table(Node), {noreply, State}; handle_info({register_iq_handler, Host, XMLNS, Module, Function}, State) -> ets:insert(sm_iqtable, {{XMLNS, Host}, Module, Function}), {noreply, State}; handle_info({register_iq_handler, Host, XMLNS, Module, Function, Opts}, State) -> ets:insert(sm_iqtable, {{XMLNS, Host}, Module, Function, Opts}), {noreply, State}; handle_info({unregister_iq_handler, Host, XMLNS}, State) -> case ets:lookup(sm_iqtable, {XMLNS, Host}) of [{_, Module, Function, Opts}] -> gen_iq_handler:stop_iq_handler(Module, Function, Opts); _ -> ok end, ets:delete(sm_iqtable, {XMLNS, Host}), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ejabberd_commands:unregister_commands(commands()), ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- set_session(SID, User, Server, Resource, Priority, Info) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), LResource = jlib:resourceprep(Resource), US = {LUser, LServer}, USR = {LUser, LServer, LResource}, F = fun() -> mnesia:write(#session{sid = SID, usr = USR, us = US, priority = Priority, info = Info}) end, mnesia:sync_dirty(F). %% Recalculates alive sessions when Node goes down %% and updates session and session_counter tables recount_session_table(Node) -> F = fun() -> Es = mnesia:select( session, [{#session{sid = {'_', '$1'}, _ = '_'}, [{'==', {node, '$1'}, Node}], ['$_']}]), lists:foreach(fun(E) -> mnesia:delete({session, E#session.sid}) end, Es), %% reset session_counter table with active sessions mnesia:clear_table(session_counter), lists:foreach(fun(Server) -> LServer = jlib:nameprep(Server), Hs = mnesia:select(session, [{#session{usr = '$1', _ = '_'}, [{'==', {element, 2, '$1'}, LServer}], ['$1']}]), mnesia:write( #session_counter{vhost = LServer, count = length(Hs)}) end, ?MYHOSTS) end, mnesia:async_dirty(F). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% do_route(From, To, Packet) -> ?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n", [From, To, Packet, 8]), #jid{user = User, server = Server, luser = LUser, lserver = LServer, lresource = LResource} = To, {xmlelement, Name, Attrs, _Els} = Packet, case LResource of "" -> case Name of "presence" -> {Pass, _Subsc} = case xml:get_attr_s("type", Attrs) of "subscribe" -> Reason = xml:get_path_s( Packet, [{elem, "status"}, cdata]), {is_privacy_allow(From, To, Packet) andalso ejabberd_hooks:run_fold( roster_in_subscription, LServer, false, [User, Server, From, subscribe, Reason]), true}; "subscribed" -> {is_privacy_allow(From, To, Packet) andalso ejabberd_hooks:run_fold( roster_in_subscription, LServer, false, [User, Server, From, subscribed, ""]), true}; "unsubscribe" -> {is_privacy_allow(From, To, Packet) andalso ejabberd_hooks:run_fold( roster_in_subscription, LServer, false, [User, Server, From, unsubscribe, ""]), true}; "unsubscribed" -> {is_privacy_allow(From, To, Packet) andalso ejabberd_hooks:run_fold( roster_in_subscription, LServer, false, [User, Server, From, unsubscribed, ""]), true}; _ -> {true, false} end, if Pass -> PResources = get_user_present_resources( LUser, LServer), lists:foreach( fun({_, R}) -> do_route( From, jlib:jid_replace_resource(To, R), Packet) end, PResources); true -> ok end; "message" -> route_message(From, To, Packet); "iq" -> process_iq(From, To, Packet); "broadcast" -> lists:foreach( fun(R) -> do_route(From, jlib:jid_replace_resource(To, R), Packet) end, get_user_resources(User, Server)); _ -> ok end; _ -> USR = {LUser, LServer, LResource}, case mnesia:dirty_index_read(session, USR, #session.usr) of [] -> case Name of "message" -> route_message(From, To, Packet); "iq" -> case xml:get_attr_s("type", Attrs) of "error" -> ok; "result" -> ok; _ -> Err = jlib:make_error_reply( Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err) end; _ -> ?DEBUG("packet droped~n", []) end; Ss -> Session = lists:max(Ss), Pid = element(2, Session#session.sid), ?DEBUG("sending to process ~p~n", [Pid]), Pid ! {route, From, To, Packet} end end. %% The default list applies to the user as a whole, %% and is processed if there is no active list set %% for the target session/resource to which a stanza is addressed, %% or if there are no current sessions for the user. is_privacy_allow(From, To, Packet) -> User = To#jid.user, Server = To#jid.server, PrivacyList = ejabberd_hooks:run_fold(privacy_get_user_list, Server, #userlist{}, [User, Server]), is_privacy_allow(From, To, Packet, PrivacyList). %% Check if privacy rules allow this delivery %% Function copied from ejabberd_c2s.erl is_privacy_allow(From, To, Packet, PrivacyList) -> User = To#jid.user, Server = To#jid.server, allow == ejabberd_hooks:run_fold( privacy_check_packet, Server, allow, [User, Server, PrivacyList, {From, To, Packet}, in]). route_message(From, To, Packet) -> LUser = To#jid.luser, LServer = To#jid.lserver, PrioRes = get_user_present_resources(LUser, LServer), case catch lists:max(PrioRes) of {Priority, _R} when is_integer(Priority), Priority >= 0 -> lists:foreach( %% Route messages to all priority that equals the max, if %% positive fun({P, R}) when P == Priority -> LResource = jlib:resourceprep(R), USR = {LUser, LServer, LResource}, case mnesia:dirty_index_read(session, USR, #session.usr) of [] -> ok; % Race condition Ss -> Session = lists:max(Ss), Pid = element(2, Session#session.sid), ?DEBUG("sending to process ~p~n", [Pid]), Pid ! {route, From, To, Packet} end; %% Ignore other priority: ({_Prio, _Res}) -> ok end, PrioRes); _ -> case xml:get_tag_attr_s("type", Packet) of "error" -> ok; "groupchat" -> bounce_offline_message(From, To, Packet); "headline" -> bounce_offline_message(From, To, Packet); _ -> case ejabberd_auth:is_user_exists(LUser, LServer) of true -> case is_privacy_allow(From, To, Packet) of true -> ejabberd_hooks:run(offline_message_hook, LServer, [From, To, Packet]); false -> ok end; _ -> Err = jlib:make_error_reply( Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err) end end end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clean_session_list(Ss) -> clean_session_list(lists:keysort(#session.usr, Ss), []). clean_session_list([], Res) -> Res; clean_session_list([S], Res) -> [S | Res]; clean_session_list([S1, S2 | Rest], Res) -> if S1#session.usr == S2#session.usr -> if S1#session.sid > S2#session.sid -> clean_session_list([S1 | Rest], Res); true -> clean_session_list([S2 | Rest], Res) end; true -> clean_session_list([S2 | Rest], [S1 | Res]) end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% get_user_present_resources(LUser, LServer) -> US = {LUser, LServer}, case catch mnesia:dirty_index_read(session, US, #session.us) of {'EXIT', _Reason} -> []; Ss -> [{S#session.priority, element(3, S#session.usr)} || S <- clean_session_list(Ss), is_integer(S#session.priority)] end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% On new session, check if some existing connections need to be replace check_for_sessions_to_replace(User, Server, Resource) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), LResource = jlib:resourceprep(Resource), %% TODO: Depending on how this is executed, there could be an unneeded %% replacement for max_sessions. We need to check this at some point. check_existing_resources(LUser, LServer, LResource), check_max_sessions(LUser, LServer). check_existing_resources(LUser, LServer, LResource) -> SIDs = get_resource_sessions(LUser, LServer, LResource), if SIDs == [] -> ok; true -> %% A connection exist with the same resource. We replace it: MaxSID = lists:max(SIDs), lists:foreach( fun({_, Pid} = S) when S /= MaxSID -> Pid ! replaced; (_) -> ok end, SIDs) end. is_existing_resource(LUser, LServer, LResource) -> [] /= get_resource_sessions(LUser, LServer, LResource). get_resource_sessions(User, Server, Resource) -> USR = {jlib:nodeprep(User), jlib:nameprep(Server), jlib:resourceprep(Resource)}, mnesia:dirty_select( session, [{#session{sid = '$1', usr = USR, _ = '_'}, [], ['$1']}]). check_max_sessions(LUser, LServer) -> %% If the max number of sessions for a given is reached, we replace the %% first one SIDs = mnesia:dirty_select( session, [{#session{sid = '$1', us = {LUser, LServer}, _ = '_'}, [], ['$1']}]), MaxSessions = get_max_user_sessions(LUser, LServer), if length(SIDs) =< MaxSessions -> ok; true -> {_, Pid} = lists:min(SIDs), Pid ! replaced end. %% Get the user_max_session setting %% This option defines the max number of time a given users are allowed to %% log in %% Defaults to infinity get_max_user_sessions(LUser, Host) -> case acl:match_rule( Host, max_user_sessions, jlib:make_jid(LUser, Host, "")) of Max when is_integer(Max) -> Max; infinity -> infinity; _ -> ?MAX_USER_SESSIONS end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% process_iq(From, To, Packet) -> IQ = jlib:iq_query_info(Packet), case IQ of #iq{xmlns = XMLNS} -> Host = To#jid.lserver, case ets:lookup(sm_iqtable, {XMLNS, Host}) of [{_, Module, Function}] -> ResIQ = Module:Function(From, To, IQ), if ResIQ /= ignore -> ejabberd_router:route(To, From, jlib:iq_to_xml(ResIQ)); true -> ok end; [{_, Module, Function, Opts}] -> gen_iq_handler:handle(Host, Module, Function, Opts, From, To, IQ); [] -> Err = jlib:make_error_reply( Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err) end; reply -> ok; _ -> Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST), ejabberd_router:route(To, From, Err), ok end. force_update_presence({LUser, _LServer} = US) -> case catch mnesia:dirty_index_read(session, US, #session.us) of {'EXIT', _Reason} -> ok; Ss -> lists:foreach(fun(#session{sid = {_, Pid}}) -> Pid ! {force_update_presence, LUser} end, Ss) end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% ejabberd commands commands() -> [ #ejabberd_commands{name = connected_users, tags = [session], desc = "List all established sessions", module = ?MODULE, function = connected_users, args = [], result = {connected_users, {list, {sessions, string}}}}, #ejabberd_commands{name = connected_users_number, tags = [session, stats], desc = "Get the number of established sessions", module = ?MODULE, function = connected_users_number, args = [], result = {num_sessions, integer}}, #ejabberd_commands{name = user_resources, tags = [session], desc = "List user's connected resources", module = ?MODULE, function = user_resources, args = [{user, string}, {host, string}], result = {resources, {list, {resource, string}}}} ]. connected_users() -> USRs = dirty_get_sessions_list(), SUSRs = lists:sort(USRs), lists:map(fun({U, S, R}) -> [U, $@, S, $/, R] end, SUSRs). connected_users_number() -> length(dirty_get_sessions_list()). user_resources(User, Server) -> Resources = get_user_resources(User, Server), lists:sort(Resources). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Update Mnesia tables update_tables() -> case catch mnesia:table_info(session, attributes) of [ur, user, node] -> mnesia:delete_table(session); [ur, user, pid] -> mnesia:delete_table(session); [usr, us, pid] -> mnesia:delete_table(session); [sid, usr, us, priority] -> mnesia:delete_table(session); [sid, usr, us, priority, info] -> ok; {'EXIT', _} -> ok end, case lists:member(presence, mnesia:system_info(tables)) of true -> mnesia:delete_table(presence); false -> ok end, case lists:member(local_session, mnesia:system_info(tables)) of true -> mnesia:delete_table(local_session); false -> ok end. ejabberd-2.1.11/src/ejabberd_auth_pam.erl0000664000000000000000000000670212240230175015132 0ustar %%%------------------------------------------------------------------- %%% File : ejabberd_auth_pam.erl %%% Author : Evgeniy Khramtsov %%% Purpose : PAM authentication %%% Created : 5 Jul 2007 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(ejabberd_auth_pam). -author('xram@jabber.ru'). %% External exports -export([start/1, set_password/3, check_password/3, check_password/5, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_password/2, get_password_s/2, is_user_exists/2, remove_user/2, remove_user/3, store_type/0, plain_password_required/0 ]). %%==================================================================== %% API %%==================================================================== start(_Host) -> case epam:start() of {ok, _} -> ok; {error,{already_started, _}} -> ok; Err -> Err end. set_password(_User, _Server, _Password) -> {error, not_allowed}. check_password(User, Server, Password, _Digest, _DigestGen) -> check_password(User, Server, Password). check_password(User, Host, Password) -> Service = get_pam_service(Host), UserInfo = case get_pam_userinfotype(Host) of username -> User; jid -> User++"@"++Host end, case catch epam:authenticate(Service, UserInfo, Password) of true -> true; _ -> false end. try_register(_User, _Server, _Password) -> {error, not_allowed}. dirty_get_registered_users() -> []. get_vh_registered_users(_Host) -> []. get_password(_User, _Server) -> false. get_password_s(_User, _Server) -> "". %% @spec (User, Server) -> true | false | {error, Error} %% TODO: Improve this function to return an error instead of 'false' when connection to PAM failed is_user_exists(User, Host) -> Service = get_pam_service(Host), UserInfo = case get_pam_userinfotype(Host) of username -> User; jid -> User++"@"++Host end, case catch epam:acct_mgmt(Service, UserInfo) of true -> true; _ -> false end. remove_user(_User, _Server) -> {error, not_allowed}. remove_user(_User, _Server, _Password) -> not_allowed. plain_password_required() -> true. store_type() -> external. %%==================================================================== %% Internal functions %%==================================================================== get_pam_service(Host) -> case ejabberd_config:get_local_option({pam_service, Host}) of undefined -> "ejabberd"; Service -> Service end. get_pam_userinfotype(Host) -> case ejabberd_config:get_local_option({pam_userinfotype, Host}) of undefined -> username; Type -> Type end. ejabberd-2.1.11/src/extauth.erl0000664000000000000000000001166212240230175013201 0ustar %%%---------------------------------------------------------------------- %%% File : extauth.erl %%% Author : Leif Johansson %%% Purpose : External authentication using a simple port-driver %%% Created : 30 Jul 2004 by Leif Johansson %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(extauth). -author('leifj@it.su.se'). -export([start/2, stop/1, init/2, check_password/3, set_password/3, try_register/3, remove_user/2, remove_user/3, is_user_exists/2]). -include("ejabberd.hrl"). -define(INIT_TIMEOUT, 60000). % Timeout is in milliseconds: 60 seconds == 60000 -define(CALL_TIMEOUT, 10000). % Timeout is in milliseconds: 10 seconds == 10000 start(Host, ExtPrg) -> lists:foreach( fun(This) -> start_instance(get_process_name(Host, This), ExtPrg) end, lists:seq(0, get_instances(Host)-1) ). start_instance(ProcessName, ExtPrg) -> spawn(?MODULE, init, [ProcessName, ExtPrg]). restart_instance(ProcessName, ExtPrg) -> unregister(ProcessName), start_instance(ProcessName, ExtPrg). init(ProcessName, ExtPrg) -> register(ProcessName, self()), process_flag(trap_exit,true), Port = open_port({spawn, ExtPrg}, [{packet,2}]), loop(Port, ?INIT_TIMEOUT, ProcessName, ExtPrg). stop(Host) -> lists:foreach( fun(This) -> get_process_name(Host, This) ! stop end, lists:seq(0, get_instances(Host)-1) ). get_process_name(Host, Integer) -> gen_mod:get_module_proc(lists:append([Host, integer_to_list(Integer)]), eauth). check_password(User, Server, Password) -> call_port(Server, ["auth", User, Server, Password]). is_user_exists(User, Server) -> call_port(Server, ["isuser", User, Server]). set_password(User, Server, Password) -> call_port(Server, ["setpass", User, Server, Password]). try_register(User, Server, Password) -> case call_port(Server, ["tryregister", User, Server, Password]) of true -> {atomic, ok}; false -> {error, not_allowed} end. remove_user(User, Server) -> call_port(Server, ["removeuser", User, Server]). remove_user(User, Server, Password) -> call_port(Server, ["removeuser3", User, Server, Password]). call_port(Server, Msg) -> LServer = jlib:nameprep(Server), ProcessName = get_process_name(LServer, random_instance(get_instances(LServer))), ProcessName ! {call, self(), Msg}, receive {eauth,Result} -> Result end. random_instance(MaxNum) -> {A1,A2,A3} = now(), random:seed(A1, A2, A3), random:uniform(MaxNum) - 1. get_instances(Server) -> case ejabberd_config:get_local_option({extauth_instances, Server}) of Num when is_integer(Num) -> Num; _ -> 1 end. loop(Port, Timeout, ProcessName, ExtPrg) -> receive {call, Caller, Msg} -> port_command(Port, encode(Msg)), receive {Port, {data, Data}} -> ?DEBUG("extauth call '~p' received data response:~n~p", [Msg, Data]), Caller ! {eauth, decode(Data)}, loop(Port, ?CALL_TIMEOUT, ProcessName, ExtPrg); {Port, Other} -> ?ERROR_MSG("extauth call '~p' received strange response:~n~p", [Msg, Other]), Caller ! {eauth, false}, loop(Port, ?CALL_TIMEOUT, ProcessName, ExtPrg) after Timeout -> ?ERROR_MSG("extauth call '~p' didn't receive response", [Msg]), Caller ! {eauth, false}, Pid = restart_instance(ProcessName, ExtPrg), flush_buffer_and_forward_messages(Pid), exit(port_terminated) end; stop -> Port ! {self(), close}, receive {Port, closed} -> exit(normal) end; {'EXIT', Port, Reason} -> ?CRITICAL_MSG("extauth script has exitted abruptly with reason '~p'", [Reason]), Pid = restart_instance(ProcessName, ExtPrg), flush_buffer_and_forward_messages(Pid), exit(port_terminated) end. flush_buffer_and_forward_messages(Pid) -> receive Message -> Pid ! Message, flush_buffer_and_forward_messages(Pid) after 0 -> true end. join(List, Sep) -> lists:foldl(fun(A, "") -> A; (A, Acc) -> Acc ++ Sep ++ A end, "", List). encode(L) -> join(L,":"). decode([0,0]) -> false; decode([0,1]) -> true. ejabberd-2.1.11/src/jlib.hrl0000664000000000000000000003431312240230175012440 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -define(NS_DISCO_ITEMS, "http://jabber.org/protocol/disco#items"). -define(NS_DISCO_INFO, "http://jabber.org/protocol/disco#info"). -define(NS_VCARD, "vcard-temp"). -define(NS_VCARD_UPDATE, "vcard-temp:x:update"). -define(NS_AUTH, "jabber:iq:auth"). -define(NS_AUTH_ERROR, "jabber:iq:auth:error"). -define(NS_REGISTER, "jabber:iq:register"). -define(NS_SEARCH, "jabber:iq:search"). -define(NS_ROSTER, "jabber:iq:roster"). -define(NS_ROSTER_VER, "urn:xmpp:features:rosterver"). -define(NS_PRIVACY, "jabber:iq:privacy"). -define(NS_BLOCKING, "urn:xmpp:blocking"). -define(NS_PRIVATE, "jabber:iq:private"). -define(NS_VERSION, "jabber:iq:version"). -define(NS_TIME90, "jabber:iq:time"). % TODO: Remove once XEP-0090 is Obsolete -define(NS_TIME, "urn:xmpp:time"). -define(NS_LAST, "jabber:iq:last"). -define(NS_XDATA, "jabber:x:data"). -define(NS_IQDATA, "jabber:iq:data"). -define(NS_DELAY91, "jabber:x:delay"). % TODO: Remove once XEP-0091 is Obsolete -define(NS_DELAY, "urn:xmpp:delay"). -define(NS_EXPIRE, "jabber:x:expire"). -define(NS_EVENT, "jabber:x:event"). -define(NS_CHATSTATES, "http://jabber.org/protocol/chatstates"). -define(NS_XCONFERENCE, "jabber:x:conference"). -define(NS_STATS, "http://jabber.org/protocol/stats"). -define(NS_MUC, "http://jabber.org/protocol/muc"). -define(NS_MUC_USER, "http://jabber.org/protocol/muc#user"). -define(NS_MUC_ADMIN, "http://jabber.org/protocol/muc#admin"). -define(NS_MUC_OWNER, "http://jabber.org/protocol/muc#owner"). -define(NS_MUC_UNIQUE, "http://jabber.org/protocol/muc#unique"). -define(NS_PUBSUB, "http://jabber.org/protocol/pubsub"). -define(NS_PUBSUB_EVENT, "http://jabber.org/protocol/pubsub#event"). -define(NS_PUBSUB_OWNER, "http://jabber.org/protocol/pubsub#owner"). -define(NS_PUBSUB_NMI, "http://jabber.org/protocol/pubsub#node-meta-info"). -define(NS_PUBSUB_ERRORS,"http://jabber.org/protocol/pubsub#errors"). -define(NS_PUBSUB_NODE_CONFIG, "http://jabber.org/protocol/pubsub#node_config"). -define(NS_PUBSUB_SUB_OPTIONS, "http://jabber.org/protocol/pubsub#subscribe_options"). -define(NS_PUBSUB_SUB_AUTH, "http://jabber.org/protocol/pubsub#subscribe_authorization"). -define(NS_PUBSUB_GET_PENDING, "http://jabber.org/protocol/pubsub#get-pending"). -define(NS_COMMANDS, "http://jabber.org/protocol/commands"). -define(NS_BYTESTREAMS, "http://jabber.org/protocol/bytestreams"). -define(NS_ADMIN, "http://jabber.org/protocol/admin"). -define(NS_SERVERINFO, "http://jabber.org/network/serverinfo"). -define(NS_RSM, "http://jabber.org/protocol/rsm"). -define(NS_EJABBERD_CONFIG, "ejabberd:config"). -define(NS_STREAM, "http://etherx.jabber.org/streams"). -define(NS_STANZAS, "urn:ietf:params:xml:ns:xmpp-stanzas"). -define(NS_STREAMS, "urn:ietf:params:xml:ns:xmpp-streams"). -define(NS_TLS, "urn:ietf:params:xml:ns:xmpp-tls"). -define(NS_SASL, "urn:ietf:params:xml:ns:xmpp-sasl"). -define(NS_SESSION, "urn:ietf:params:xml:ns:xmpp-session"). -define(NS_BIND, "urn:ietf:params:xml:ns:xmpp-bind"). -define(NS_FEATURE_IQAUTH, "http://jabber.org/features/iq-auth"). -define(NS_FEATURE_IQREGISTER, "http://jabber.org/features/iq-register"). -define(NS_FEATURE_COMPRESS, "http://jabber.org/features/compress"). -define(NS_FEATURE_MSGOFFLINE, "msgoffline"). -define(NS_COMPRESS, "http://jabber.org/protocol/compress"). -define(NS_CAPS, "http://jabber.org/protocol/caps"). -define(NS_SHIM, "http://jabber.org/protocol/shim"). -define(NS_ADDRESS, "http://jabber.org/protocol/address"). %% CAPTCHA related NSes. -define(NS_OOB, "jabber:x:oob"). -define(NS_CAPTCHA, "urn:xmpp:captcha"). -define(NS_MEDIA, "urn:xmpp:media-element"). -define(NS_BOB, "urn:xmpp:bob"). % TODO: remove "code" attribute (currently it used for backward-compatibility) -define(STANZA_ERROR(Code, Type, Condition), {xmlelement, "error", [{"code", Code}, {"type", Type}], [{xmlelement, Condition, [{"xmlns", ?NS_STANZAS}], []}]}). -define(ERR_BAD_FORMAT, ?STANZA_ERROR("406", "modify", "bad-format")). -define(ERR_BAD_REQUEST, ?STANZA_ERROR("400", "modify", "bad-request")). -define(ERR_CONFLICT, ?STANZA_ERROR("409", "cancel", "conflict")). -define(ERR_FEATURE_NOT_IMPLEMENTED, ?STANZA_ERROR("501", "cancel", "feature-not-implemented")). -define(ERR_FORBIDDEN, ?STANZA_ERROR("403", "auth", "forbidden")). -define(ERR_GONE, ?STANZA_ERROR("302", "modify", "gone")). -define(ERR_INTERNAL_SERVER_ERROR, ?STANZA_ERROR("500", "wait", "internal-server-error")). -define(ERR_ITEM_NOT_FOUND, ?STANZA_ERROR("404", "cancel", "item-not-found")). -define(ERR_JID_MALFORMED, ?STANZA_ERROR("400", "modify", "jid-malformed")). -define(ERR_NOT_ACCEPTABLE, ?STANZA_ERROR("406", "modify", "not-acceptable")). -define(ERR_NOT_ALLOWED, ?STANZA_ERROR("405", "cancel", "not-allowed")). -define(ERR_NOT_AUTHORIZED, ?STANZA_ERROR("401", "auth", "not-authorized")). -define(ERR_PAYMENT_REQUIRED, ?STANZA_ERROR("402", "auth", "payment-required")). -define(ERR_RECIPIENT_UNAVAILABLE, ?STANZA_ERROR("404", "wait", "recipient-unavailable")). -define(ERR_REDIRECT, ?STANZA_ERROR("302", "modify", "redirect")). -define(ERR_REGISTRATION_REQUIRED, ?STANZA_ERROR("407", "auth", "registration-required")). -define(ERR_REMOTE_SERVER_NOT_FOUND, ?STANZA_ERROR("404", "cancel", "remote-server-not-found")). -define(ERR_REMOTE_SERVER_TIMEOUT, ?STANZA_ERROR("504", "wait", "remote-server-timeout")). -define(ERR_RESOURCE_CONSTRAINT, ?STANZA_ERROR("500", "wait", "resource-constraint")). -define(ERR_SERVICE_UNAVAILABLE, ?STANZA_ERROR("503", "cancel", "service-unavailable")). -define(ERR_SUBSCRIPTION_REQUIRED, ?STANZA_ERROR("407", "auth", "subscription-required")). -define(ERR_UNEXPECTED_REQUEST, ?STANZA_ERROR("400", "wait", "unexpected-request")). -define(ERR_UNEXPECTED_REQUEST_CANCEL, ?STANZA_ERROR("401", "cancel", "unexpected-request")). %-define(ERR_, % ?STANZA_ERROR("", "", "")). -define(STANZA_ERRORT(Code, Type, Condition, Lang, Text), {xmlelement, "error", [{"code", Code}, {"type", Type}], [{xmlelement, Condition, [{"xmlns", ?NS_STANZAS}], []}, {xmlelement, "text", [{"xmlns", ?NS_STANZAS}], [{xmlcdata, translate:translate(Lang, Text)}]}]}). -define(ERRT_BAD_FORMAT(Lang, Text), ?STANZA_ERRORT("406", "modify", "bad-format", Lang, Text)). -define(ERRT_BAD_REQUEST(Lang, Text), ?STANZA_ERRORT("400", "modify", "bad-request", Lang, Text)). -define(ERRT_CONFLICT(Lang, Text), ?STANZA_ERRORT("409", "cancel", "conflict", Lang, Text)). -define(ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Text), ?STANZA_ERRORT("501", "cancel", "feature-not-implemented", Lang, Text)). -define(ERRT_FORBIDDEN(Lang, Text), ?STANZA_ERRORT("403", "auth", "forbidden", Lang, Text)). -define(ERRT_GONE(Lang, Text), ?STANZA_ERRORT("302", "modify", "gone", Lang, Text)). -define(ERRT_INTERNAL_SERVER_ERROR(Lang, Text), ?STANZA_ERRORT("500", "wait", "internal-server-error", Lang, Text)). -define(ERRT_ITEM_NOT_FOUND(Lang, Text), ?STANZA_ERRORT("404", "cancel", "item-not-found", Lang, Text)). -define(ERRT_JID_MALFORMED(Lang, Text), ?STANZA_ERRORT("400", "modify", "jid-malformed", Lang, Text)). -define(ERRT_NOT_ACCEPTABLE(Lang, Text), ?STANZA_ERRORT("406", "modify", "not-acceptable", Lang, Text)). -define(ERRT_NOT_ALLOWED(Lang, Text), ?STANZA_ERRORT("405", "cancel", "not-allowed", Lang, Text)). -define(ERRT_NOT_AUTHORIZED(Lang, Text), ?STANZA_ERRORT("401", "auth", "not-authorized", Lang, Text)). -define(ERRT_PAYMENT_REQUIRED(Lang, Text), ?STANZA_ERRORT("402", "auth", "payment-required", Lang, Text)). -define(ERRT_RECIPIENT_UNAVAILABLE(Lang, Text), ?STANZA_ERRORT("404", "wait", "recipient-unavailable", Lang, Text)). -define(ERRT_REDIRECT(Lang, Text), ?STANZA_ERRORT("302", "modify", "redirect", Lang, Text)). -define(ERRT_REGISTRATION_REQUIRED(Lang, Text), ?STANZA_ERRORT("407", "auth", "registration-required", Lang, Text)). -define(ERRT_REMOTE_SERVER_NOT_FOUND(Lang, Text), ?STANZA_ERRORT("404", "cancel", "remote-server-not-found", Lang, Text)). -define(ERRT_REMOTE_SERVER_TIMEOUT(Lang, Text), ?STANZA_ERRORT("504", "wait", "remote-server-timeout", Lang, Text)). -define(ERRT_RESOURCE_CONSTRAINT(Lang, Text), ?STANZA_ERRORT("500", "wait", "resource-constraint", Lang, Text)). -define(ERRT_SERVICE_UNAVAILABLE(Lang, Text), ?STANZA_ERRORT("503", "cancel", "service-unavailable", Lang, Text)). -define(ERRT_SUBSCRIPTION_REQUIRED(Lang, Text), ?STANZA_ERRORT("407", "auth", "subscription-required", Lang, Text)). -define(ERRT_UNEXPECTED_REQUEST(Lang, Text), ?STANZA_ERRORT("400", "wait", "unexpected-request", Lang, Text)). % Auth stanza errors -define(ERR_AUTH_NO_RESOURCE_PROVIDED(Lang), ?ERRT_NOT_ACCEPTABLE(Lang, "No resource provided")). -define(ERR_AUTH_BAD_RESOURCE_FORMAT(Lang), ?ERRT_NOT_ACCEPTABLE(Lang, "Illegal resource format")). -define(ERR_AUTH_RESOURCE_CONFLICT(Lang), ?ERRT_CONFLICT(Lang, "Resource conflict")). -define(STREAM_ERROR(Condition), {xmlelement, "stream:error", [], [{xmlelement, Condition, [{"xmlns", ?NS_STREAMS}], []}]}). -define(SERR_BAD_FORMAT, ?STREAM_ERROR("bad-format")). -define(SERR_BAD_NAMESPACE_PREFIX, ?STREAM_ERROR("bad-namespace-prefix")). -define(SERR_CONFLICT, ?STREAM_ERROR("conflict")). -define(SERR_CONNECTION_TIMEOUT, ?STREAM_ERROR("connection-timeout")). -define(SERR_HOST_GONE, ?STREAM_ERROR("host-gone")). -define(SERR_HOST_UNKNOWN, ?STREAM_ERROR("host-unknown")). -define(SERR_IMPROPER_ADDRESSING, ?STREAM_ERROR("improper-addressing")). -define(SERR_INTERNAL_SERVER_ERROR, ?STREAM_ERROR("internal-server-error")). -define(SERR_INVALID_FROM, ?STREAM_ERROR("invalid-from")). -define(SERR_INVALID_ID, ?STREAM_ERROR("invalid-id")). -define(SERR_INVALID_NAMESPACE, ?STREAM_ERROR("invalid-namespace")). -define(SERR_INVALID_XML, ?STREAM_ERROR("invalid-xml")). -define(SERR_NOT_AUTHORIZED, ?STREAM_ERROR("not-authorized")). -define(SERR_POLICY_VIOLATION, ?STREAM_ERROR("policy-violation")). -define(SERR_REMOTE_CONNECTION_FAILED, ?STREAM_ERROR("remote-connection-failed")). -define(SERR_RESOURSE_CONSTRAINT, ?STREAM_ERROR("resource-constraint")). -define(SERR_RESTRICTED_XML, ?STREAM_ERROR("restricted-xml")). % TODO: include hostname or IP -define(SERR_SEE_OTHER_HOST, ?STREAM_ERROR("see-other-host")). -define(SERR_SYSTEM_SHUTDOWN, ?STREAM_ERROR("system-shutdown")). -define(SERR_UNSUPPORTED_ENCODING, ?STREAM_ERROR("unsupported-encoding")). -define(SERR_UNSUPPORTED_STANZA_TYPE, ?STREAM_ERROR("unsupported-stanza-type")). -define(SERR_UNSUPPORTED_VERSION, ?STREAM_ERROR("unsupported-version")). -define(SERR_XML_NOT_WELL_FORMED, ?STREAM_ERROR("xml-not-well-formed")). %-define(SERR_, % ?STREAM_ERROR("")). -define(STREAM_ERRORT(Condition, Lang, Text), {xmlelement, "stream:error", [], [{xmlelement, Condition, [{"xmlns", ?NS_STREAMS}], []}, {xmlelement, "text", [{"xml:lang", Lang}, {"xmlns", ?NS_STREAMS}], [{xmlcdata, translate:translate(Lang, Text)}]}]}). -define(SERRT_BAD_FORMAT(Lang, Text), ?STREAM_ERRORT("bad-format", Lang, Text)). -define(SERRT_BAD_NAMESPACE_PREFIX(Lang, Text), ?STREAM_ERRORT("bad-namespace-prefix", Lang, Text)). -define(SERRT_CONFLICT(Lang, Text), ?STREAM_ERRORT("conflict", Lang, Text)). -define(SERRT_CONNECTION_TIMEOUT(Lang, Text), ?STREAM_ERRORT("connection-timeout", Lang, Text)). -define(SERRT_HOST_GONE(Lang, Text), ?STREAM_ERRORT("host-gone", Lang, Text)). -define(SERRT_HOST_UNKNOWN(Lang, Text), ?STREAM_ERRORT("host-unknown", Lang, Text)). -define(SERRT_IMPROPER_ADDRESSING(Lang, Text), ?STREAM_ERRORT("improper-addressing", Lang, Text)). -define(SERRT_INTERNAL_SERVER_ERROR(Lang, Text), ?STREAM_ERRORT("internal-server-error", Lang, Text)). -define(SERRT_INVALID_FROM(Lang, Text), ?STREAM_ERRORT("invalid-from", Lang, Text)). -define(SERRT_INVALID_ID(Lang, Text), ?STREAM_ERRORT("invalid-id", Lang, Text)). -define(SERRT_INVALID_NAMESPACE(Lang, Text), ?STREAM_ERRORT("invalid-namespace", Lang, Text)). -define(SERRT_INVALID_XML(Lang, Text), ?STREAM_ERRORT("invalid-xml", Lang, Text)). -define(SERRT_NOT_AUTHORIZED(Lang, Text), ?STREAM_ERRORT("not-authorized", Lang, Text)). -define(SERRT_POLICY_VIOLATION(Lang, Text), ?STREAM_ERRORT("policy-violation", Lang, Text)). -define(SERRT_REMOTE_CONNECTION_FAILED(Lang, Text), ?STREAM_ERRORT("remote-connection-failed", Lang, Text)). -define(SERRT_RESOURSE_CONSTRAINT(Lang, Text), ?STREAM_ERRORT("resource-constraint", Lang, Text)). -define(SERRT_RESTRICTED_XML(Lang, Text), ?STREAM_ERRORT("restricted-xml", Lang, Text)). % TODO: include hostname or IP -define(SERRT_SEE_OTHER_HOST(Lang, Text), ?STREAM_ERRORT("see-other-host", Lang, Text)). -define(SERRT_SYSTEM_SHUTDOWN(Lang, Text), ?STREAM_ERRORT("system-shutdown", Lang, Text)). -define(SERRT_UNSUPPORTED_ENCODING(Lang, Text), ?STREAM_ERRORT("unsupported-encoding", Lang, Text)). -define(SERRT_UNSUPPORTED_STANZA_TYPE(Lang, Text), ?STREAM_ERRORT("unsupported-stanza-type", Lang, Text)). -define(SERRT_UNSUPPORTED_VERSION(Lang, Text), ?STREAM_ERRORT("unsupported-version", Lang, Text)). -define(SERRT_XML_NOT_WELL_FORMED(Lang, Text), ?STREAM_ERRORT("xml-not-well-formed", Lang, Text)). %-define(SERRT_(Lang, Text), % ?STREAM_ERRORT("", Lang, Text)). -record(jid, {user, server, resource, luser, lserver, lresource}). -record(iq, {id = "", type, xmlns = "", lang = "", sub_el}). -record(rsm_in, {max, direction, id, index}). -record(rsm_out, {count, index, first, last}). ejabberd-2.1.11/src/ejabberd_ctl.hrl0000664000000000000000000000203412240230175014113 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -define(STATUS_SUCCESS, 0). -define(STATUS_ERROR, 1). -define(STATUS_USAGE, 2). -define(STATUS_BADRPC, 3). ejabberd-2.1.11/src/ejabberd_service.erl0000664000000000000000000003216412240230175014775 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_service.erl %%% Author : Alexey Shchepin %%% Purpose : External component management (XEP-0114) %%% Created : 6 Dec 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_service). -author('alexey@process-one.net'). -define(GEN_FSM, p1_fsm). -behaviour(?GEN_FSM). %% External exports -export([start/2, start_link/2, send_text/2, send_element/2, socket_type/0]). %% gen_fsm callbacks -export([init/1, wait_for_stream/2, wait_for_handshake/2, stream_established/2, handle_event/3, handle_sync_event/4, code_change/4, handle_info/3, terminate/3, print_state/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). -record(state, {socket, sockmod, streamid, hosts, password, access, check_from}). %-define(DBGFSM, true). -ifdef(DBGFSM). -define(FSMOPTS, [{debug, [trace]}]). -else. -define(FSMOPTS, []). -endif. -define(STREAM_HEADER, "" "" ). -define(STREAM_TRAILER, ""). -define(INVALID_HEADER_ERR, "" "Invalid Stream Header" "" ). -define(INVALID_HANDSHAKE_ERR, "" "" "" "Invalid Handshake" "" "" ). -define(INVALID_XML_ERR, xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)). -define(INVALID_NS_ERR, xml:element_to_string(?SERR_INVALID_NAMESPACE)). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start(SockData, Opts) -> supervisor:start_child(ejabberd_service_sup, [SockData, Opts]). start_link(SockData, Opts) -> ?GEN_FSM:start_link(ejabberd_service, [SockData, Opts], fsm_limit_opts(Opts) ++ ?FSMOPTS). socket_type() -> xml_stream. %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, StateName, StateData} | %% {ok, StateName, StateData, Timeout} | %% ignore | %% {stop, StopReason} %%---------------------------------------------------------------------- init([{SockMod, Socket}, Opts]) -> ?INFO_MSG("(~w) External service connected", [Socket]), Access = case lists:keysearch(access, 1, Opts) of {value, {_, A}} -> A; _ -> all end, {Hosts, Password} = case lists:keysearch(hosts, 1, Opts) of {value, {_, Hs, HOpts}} -> case lists:keysearch(password, 1, HOpts) of {value, {_, P}} -> {Hs, P}; _ -> % TODO: generate error false end; _ -> case lists:keysearch(host, 1, Opts) of {value, {_, H, HOpts}} -> case lists:keysearch(password, 1, HOpts) of {value, {_, P}} -> {[H], P}; _ -> % TODO: generate error false end; _ -> % TODO: generate error false end end, Shaper = case lists:keysearch(shaper_rule, 1, Opts) of {value, {_, S}} -> S; _ -> none end, CheckFrom = case lists:keysearch(service_check_from, 1, Opts) of {value, {_, CF}} -> CF; _ -> true end, SockMod:change_shaper(Socket, Shaper), {ok, wait_for_stream, #state{socket = Socket, sockmod = SockMod, streamid = new_id(), hosts = Hosts, password = Password, access = Access, check_from = CheckFrom }}. %%---------------------------------------------------------------------- %% Func: StateName/2 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> case xml:get_attr_s("xmlns", Attrs) of "jabber:component:accept" -> %% Note: XEP-0114 requires to check that destination is a Jabber %% component served by this Jabber server. %% However several transports don't respect that, %% so ejabberd doesn't check 'to' attribute (EJAB-717) To = xml:get_attr_s("to", Attrs), Header = io_lib:format(?STREAM_HEADER, [StateData#state.streamid, xml:crypt(To)]), send_text(StateData, Header), {next_state, wait_for_handshake, StateData}; _ -> send_text(StateData, ?INVALID_HEADER_ERR), {stop, normal, StateData} end; wait_for_stream({xmlstreamerror, _}, StateData) -> Header = io_lib:format(?STREAM_HEADER, ["none", ?MYNAME]), send_text(StateData, Header ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER), {stop, normal, StateData}; wait_for_stream(closed, StateData) -> {stop, normal, StateData}. wait_for_handshake({xmlstreamelement, El}, StateData) -> {xmlelement, Name, _Attrs, Els} = El, case {Name, xml:get_cdata(Els)} of {"handshake", Digest} -> case sha:sha(StateData#state.streamid ++ StateData#state.password) of Digest -> send_text(StateData, ""), lists:foreach( fun(H) -> ejabberd_router:register_route(H), ?INFO_MSG("Route registered for service ~p~n", [H]) end, StateData#state.hosts), {next_state, stream_established, StateData}; _ -> send_text(StateData, ?INVALID_HANDSHAKE_ERR), {stop, normal, StateData} end; _ -> {next_state, wait_for_handshake, StateData} end; wait_for_handshake({xmlstreamend, _Name}, StateData) -> {stop, normal, StateData}; wait_for_handshake({xmlstreamerror, _}, StateData) -> send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), {stop, normal, StateData}; wait_for_handshake(closed, StateData) -> {stop, normal, StateData}. stream_established({xmlstreamelement, El}, StateData) -> NewEl = jlib:remove_attr("xmlns", El), {xmlelement, Name, Attrs, _Els} = NewEl, From = xml:get_attr_s("from", Attrs), FromJID = case StateData#state.check_from of %% If the admin does not want to check the from field %% when accept packets from any address. %% In this case, the component can send packet of %% behalf of the server users. false -> jlib:string_to_jid(From); %% The default is the standard behaviour in XEP-0114 _ -> FromJID1 = jlib:string_to_jid(From), case FromJID1 of #jid{lserver = Server} -> case lists:member(Server, StateData#state.hosts) of true -> FromJID1; false -> error end; _ -> error end end, To = xml:get_attr_s("to", Attrs), ToJID = case To of "" -> error; _ -> jlib:string_to_jid(To) end, if ((Name == "iq") or (Name == "message") or (Name == "presence")) and (ToJID /= error) and (FromJID /= error) -> ejabberd_router:route(FromJID, ToJID, NewEl); true -> Err = jlib:make_error_reply(NewEl, ?ERR_BAD_REQUEST), send_element(StateData, Err), error end, {next_state, stream_established, StateData}; stream_established({xmlstreamend, _Name}, StateData) -> % TODO {stop, normal, StateData}; stream_established({xmlstreamerror, _}, StateData) -> send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), {stop, normal, StateData}; stream_established(closed, StateData) -> % TODO {stop, normal, StateData}. %%---------------------------------------------------------------------- %% Func: StateName/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- %state_name(Event, From, StateData) -> % Reply = ok, % {reply, Reply, state_name, StateData}. %%---------------------------------------------------------------------- %% Func: handle_event/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- handle_sync_event(_Event, _From, StateName, StateData) -> Reply = ok, {reply, Reply, StateName, StateData}. code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_info/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_info({send_text, Text}, StateName, StateData) -> send_text(StateData, Text), {next_state, StateName, StateData}; handle_info({send_element, El}, StateName, StateData) -> send_element(StateData, El), {next_state, StateName, StateData}; handle_info({route, From, To, Packet}, StateName, StateData) -> case acl:match_rule(global, StateData#state.access, From) of allow -> {xmlelement, Name, Attrs, Els} = Packet, Attrs2 = jlib:replace_from_to_attrs(jlib:jid_to_string(From), jlib:jid_to_string(To), Attrs), Text = xml:element_to_binary({xmlelement, Name, Attrs2, Els}), send_text(StateData, Text); deny -> Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED), ejabberd_router:route_error(To, From, Err, Packet) end, {next_state, StateName, StateData}; handle_info(Info, StateName, StateData) -> ?ERROR_MSG("Unexpected info: ~p", [Info]), {next_state, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: terminate/3 %% Purpose: Shutdown the fsm %% Returns: any %%---------------------------------------------------------------------- terminate(Reason, StateName, StateData) -> ?INFO_MSG("terminated: ~p", [Reason]), case StateName of stream_established -> lists:foreach( fun(H) -> ejabberd_router:unregister_route(H) end, StateData#state.hosts); _ -> ok end, (StateData#state.sockmod):close(StateData#state.socket), ok. %%---------------------------------------------------------------------- %% Func: print_state/1 %% Purpose: Prepare the state to be printed on error log %% Returns: State to print %%---------------------------------------------------------------------- print_state(State) -> State. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- send_text(StateData, Text) -> (StateData#state.sockmod):send(StateData#state.socket, Text). send_element(StateData, El) -> send_text(StateData, xml:element_to_binary(El)). new_id() -> randoms:get_string(). fsm_limit_opts(Opts) -> case lists:keysearch(max_fsm_queue, 1, Opts) of {value, {_, N}} when is_integer(N) -> [{max_queue, N}]; _ -> case ejabberd_config:get_local_option(max_fsm_queue) of N when is_integer(N) -> [{max_queue, N}]; _ -> [] end end. ejabberd-2.1.11/src/mod_pubsub/0000775000000000000000000000000012240452476013156 5ustar ejabberd-2.1.11/src/mod_pubsub/pubsub.hrl0000664000000000000000000001370112240230175015155 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% copyright 2006-2012 ProcessOne %%% %%% This file contains pubsub types definition. %%% ==================================================================== %% ------------------------------- %% Pubsub constants -define(ERR_EXTENDED(E,C), mod_pubsub:extended_error(E,C)). %% The actual limit can be configured with mod_pubsub's option max_items_node -define(MAXITEMS, 10). %% this is currently a hard limit. %% Would be nice to have it configurable. -define(MAX_PAYLOAD_SIZE, 60000). %% ------------------------------- %% Pubsub types %% @type hostPubsub() = string(). %%

hostPubsub is the name of the PubSub service. For example, it can be %% "pubsub.localhost".

%% @type hostPEP() = {User, Server, Resource} %% User = string() %% Server = string() %% Resource = []. %%

For example, it can be : %% ```{"bob", "example.org", []}'''.

%% @type host() = hostPubsub() | hostPEP(). %% @type nodeId() = binary(). %%

A node is defined by a list of its ancestors. The last element is the name %% of the current node. For example: %% ```<<"/home/localhost/user">>'''

%% @type nodeIdx() = integer(). %% @type itemId() = string(). %% @type subId() = string(). %% @type payload() = [#xmlelement{} | #xmlcdata{}]. %% @type stanzaError() = #xmlelement{}. %% Example: %% ```{xmlelement, "error", %% [{"code", Code}, {"type", Type}], %% [{xmlelement, Condition, [{"xmlns", ?NS_STANZAS}], []}]}''' %% @type pubsubIQResponse() = #xmlelement{}. %% Example: %% ```{xmlelement, "pubsub", %% [{"xmlns", ?NS_PUBSUB_EVENT}], %% [{xmlelement, "affiliations", [], %% []}]}''' %% @type nodeOption() = {Option, Value} %% Option = atom() %% Value = term(). %% Example: %% ```{deliver_payloads, true}''' %% @type nodeType() = string(). %%

The nodeType is a string containing the name of the PubSub %% plugin to use to manage a given node. For example, it can be %% "flat", "hometree" or "blog".

%% @type jid() = {jid, User, Server, Resource, LUser, LServer, LResource} %% User = string() %% Server = string() %% Resource = string() %% LUser = string() %% LServer = string() %% LResource = string(). %% @type ljid() = {User, Server, Resource} %% User = string() %% Server = string() %% Resource = string(). %% @type affiliation() = 'none' | 'owner' | 'publisher' | 'publish-only' | 'member' | 'outcast'. %% @type subscription() = 'none' | 'pending' | 'unconfigured' | 'subscribed'. %% @type accessModel() = 'open' | 'presence' | 'roster' | 'authorize' | 'whitelist'. %% @type pubsubIndex() = {pubsub_index, Index, Last, Free} %% Index = atom() %% Last = integer() %% Free = [integer()]. %% internal pubsub index table -record(pubsub_index, { index, last, free }). %% @type pubsubNode() = {pubsub_node, NodeId, Id, Parents, Type, Owners, Options} %% NodeId = {host() | ljid(), nodeId()} %% Id = nodeIdx() %% Parents = [nodeId()] %% Type = nodeType() %% Owners = [ljid()] %% Options = [nodeOption()]. %%

This is the format of the nodes table. The type of the table %% is: set,ram/disc.

%%

The Parents and type fields are indexed.

%% id can be anything you want. -record(pubsub_node, { nodeid, id, parents = [], type = "flat", owners = [], options = [] }). %% @type pubsubState() = {pubsub_state, StateId, Items, Affiliation, Subscriptions} %% StateId = {ljid(), nodeIdx()} %% Items = [itemId()] %% Affiliation = affiliation() %% Subscriptions = [{subscription(), subId()}]. %%

This is the format of the affiliations table. The type of the %% table is: set,ram/disc.

-record(pubsub_state, { stateid, items = [], affiliation = 'none', subscriptions = [] }). %% @type pubsubItem() = {pubsub_item, ItemId, Creation, Modification, Payload} %% ItemId = {itemId(), nodeIdx()} %% Creation = {now(), ljid()} %% Modification = {now(), ljid()} %% Payload = payload(). %%

This is the format of the published items table. The type of the %% table is: set,disc,fragmented.

-record(pubsub_item, { itemid, creation = {'unknown','unknown'}, modification = {'unknown','unknown'}, payload = [] }). %% @type pubsubSubscription() = {pubsub_subscription, SubId, Options} %% SubId = subId() %% Options = [nodeOption()]. %%

This is the format of the subscriptions table. The type of the %% table is: set,ram/disc.

-record(pubsub_subscription, { subid, options }). %% @type pubsubLastItem() = {pubsub_last_item, NodeId, ItemId, Creation, Payload} %% NodeId = nodeIdx() %% ItemId = itemId() %% Creation = {now(),ljid()} %% Payload = payload(). %%

This is the format of the last items table. it stores last item payload %% for every node

-record(pubsub_last_item, { nodeid, itemid, creation, payload }). ejabberd-2.1.11/src/mod_pubsub/mod_pubsub_odbc.erl0000664000000000000000000042706012240230175017007 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %%% @doc The module {@module} is the core of the PubSub %%% extension. It relies on PubSub plugins for a large part of its functions. %%% %%% @headerfile "pubsub.hrl" %%% %%% @reference See XEP-0060: Pubsub for %%% the latest version of the PubSub specification. %%% This module uses version 1.12 of the specification as a base. %%% Most of the specification is implemented. %%% Functions concerning configuration should be rewritten. %%% %%% Support for subscription-options and multi-subscribe features was %%% added by Brian Cully (bjc AT kublai.com). Subscriptions and options are %%% stored in the pubsub_subscription table, with a link to them provided %%% by the subscriptions field of pubsub_state. For information on %%% subscription-options and mulit-subscribe see XEP-0060 sections 6.1.6, %%% 6.2.3.1, 6.2.3.5, and 6.3. For information on subscription leases see %%% XEP-0060 section 12.18. -module(mod_pubsub_odbc). -author('christophe.romain@process-one.net'). -version('1.13-0'). -behaviour(gen_server). -behaviour(gen_mod). -include("ejabberd.hrl"). -include("adhoc.hrl"). -include("jlib.hrl"). -include("pubsub.hrl"). -define(STDTREE, "tree_odbc"). -define(STDNODE, "flat_odbc"). -define(PEPNODE, "pep_odbc"). %% exports for hooks -export([presence_probe/3, caps_update/3, in_subscription/6, out_subscription/4, on_user_offline/3, remove_user/2, disco_local_identity/5, disco_local_features/5, disco_local_items/5, disco_sm_identity/5, disco_sm_features/5, disco_sm_items/5 ]). %% exported iq handlers -export([iq_sm/3 ]). %% exports for console debug manual use -export([create_node/5, delete_node/3, subscribe_node/5, unsubscribe_node/5, publish_item/6, delete_item/4, send_items/6, get_items/2, get_item/3, get_cached_item/2, broadcast_stanza/9, get_configure/5, set_configure/5, tree_action/3, node_action/4 ]). %% general helpers for plugins -export([node_to_string/1, string_to_node/1, subscription_to_string/1, affiliation_to_string/1, string_to_subscription/1, string_to_affiliation/1, extended_error/2, extended_error/3, escape/1 ]). %% API and gen_server callbacks -export([start_link/2, start/2, stop/1, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3 ]). %% calls for parallel sending of last items -export([send_loop/1 ]). -define(PROCNAME, ejabberd_mod_pubsub_odbc). -define(LOOPNAME, ejabberd_mod_pubsub_loop). -define(PLUGIN_PREFIX, "node_"). -define(TREE_PREFIX, "nodetree_"). -record(state, {server_host, host, access, pep_mapping = [], ignore_pep_from_offline = true, last_item_cache = false, max_items_node = ?MAXITEMS, nodetree = ?STDTREE, plugins = [?STDNODE]}). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, transient, 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:call(Proc, stop), supervisor:delete_child(ejabberd_sup, Proc). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([ServerHost, Opts]) -> ?DEBUG("pubsub init ~p ~p",[ServerHost,Opts]), Host = gen_mod:get_opt_host(ServerHost, Opts, "pubsub.@HOST@"), Access = gen_mod:get_opt(access_createnode, Opts, all), PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts, true), IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), LastItemCache = gen_mod:get_opt(last_item_cache, Opts, false), MaxItemsNode = gen_mod:get_opt(max_items_node, Opts, ?MAXITEMS), pubsub_index:init(Host, ServerHost, Opts), ets:new(gen_mod:get_module_proc(Host, config), [set, named_table]), ets:new(gen_mod:get_module_proc(ServerHost, config), [set, named_table]), {Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts), mnesia:create_table(pubsub_last_item, [{ram_copies, [node()]}, {attributes, record_info(fields, pubsub_last_item)}]), mod_disco:register_feature(ServerHost, ?NS_PUBSUB), ets:insert(gen_mod:get_module_proc(Host, config), {nodetree, NodeTree}), ets:insert(gen_mod:get_module_proc(Host, config), {plugins, Plugins}), ets:insert(gen_mod:get_module_proc(Host, config), {last_item_cache, LastItemCache}), ets:insert(gen_mod:get_module_proc(Host, config), {max_items_node, MaxItemsNode}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {nodetree, NodeTree}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {plugins, Plugins}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {last_item_cache, LastItemCache}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {max_items_node, MaxItemsNode}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {pep_mapping, PepMapping}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {ignore_pep_from_offline, PepOffline}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {host, Host}), ejabberd_hooks:add(sm_remove_connection_hook, ServerHost, ?MODULE, on_user_offline, 75), ejabberd_hooks:add(disco_local_identity, ServerHost, ?MODULE, disco_local_identity, 75), ejabberd_hooks:add(disco_local_features, ServerHost, ?MODULE, disco_local_features, 75), ejabberd_hooks:add(disco_local_items, ServerHost, ?MODULE, disco_local_items, 75), ejabberd_hooks:add(presence_probe_hook, ServerHost, ?MODULE, presence_probe, 80), ejabberd_hooks:add(roster_in_subscription, ServerHost, ?MODULE, in_subscription, 50), ejabberd_hooks:add(roster_out_subscription, ServerHost, ?MODULE, out_subscription, 50), ejabberd_hooks:add(remove_user, ServerHost, ?MODULE, remove_user, 50), ejabberd_hooks:add(anonymous_purge_hook, ServerHost, ?MODULE, remove_user, 50), case lists:member(?PEPNODE, Plugins) of true -> ejabberd_hooks:add(caps_update, ServerHost, ?MODULE, caps_update, 80), ejabberd_hooks:add(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75), ejabberd_hooks:add(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75), ejabberd_hooks:add(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75), gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB, ?MODULE, iq_sm, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB_OWNER, ?MODULE, iq_sm, IQDisc); false -> ok end, ejabberd_router:register_route(Host), put(server_host, ServerHost), % not clean, but needed to plug hooks at any location init_nodes(Host, ServerHost, NodeTree, Plugins), State = #state{host = Host, server_host = ServerHost, access = Access, pep_mapping = PepMapping, ignore_pep_from_offline = PepOffline, last_item_cache = LastItemCache, max_items_node = MaxItemsNode, nodetree = NodeTree, plugins = Plugins}, init_send_loop(ServerHost, State), {ok, State}. init_send_loop(ServerHost, State) -> Proc = gen_mod:get_module_proc(ServerHost, ?LOOPNAME), SendLoop = spawn(?MODULE, send_loop, [State]), register(Proc, SendLoop), SendLoop. %% @spec (Host, ServerHost, Opts) -> Plugins %% Host = mod_pubsub:host() Opts = [{Key,Value}] %% ServerHost = host() %% Key = atom() %% Value = term() %% Plugins = [Plugin::string()] %% @doc Call the init/1 function for each plugin declared in the config file. %% The default plugin module is implicit. %%

The Erlang code for the plugin is located in a module called %% node_plugin. The 'node_' prefix is mandatory.

%%

The modules are initialized in alphetical order and the list is checked %% and sorted to ensure that each module is initialized only once.

%%

See {@link node_hometree:init/1} for an example implementation.

init_plugins(Host, ServerHost, Opts) -> TreePlugin = list_to_atom(?TREE_PREFIX ++ gen_mod:get_opt(nodetree, Opts, ?STDTREE)), ?DEBUG("** tree plugin is ~p",[TreePlugin]), TreePlugin:init(Host, ServerHost, Opts), Plugins = gen_mod:get_opt(plugins, Opts, [?STDNODE]), PepMapping = gen_mod:get_opt(pep_mapping, Opts, []), ?DEBUG("** PEP Mapping : ~p~n",[PepMapping]), PluginsOK = lists:foldl(fun(Name, Acc) -> Plugin = list_to_atom(?PLUGIN_PREFIX ++ Name), case catch apply(Plugin, init, [Host, ServerHost, Opts]) of {'EXIT', _Error} -> Acc; _ -> ?DEBUG("** init ~s plugin",[Name]), [Name | Acc] end end, [], Plugins), {lists:reverse(PluginsOK), TreePlugin, PepMapping}. terminate_plugins(Host, ServerHost, Plugins, TreePlugin) -> lists:foreach(fun(Name) -> ?DEBUG("** terminate ~s plugin",[Name]), Plugin = list_to_atom(?PLUGIN_PREFIX++Name), Plugin:terminate(Host, ServerHost) end, Plugins), TreePlugin:terminate(Host, ServerHost), ok. init_nodes(Host, ServerHost, _NodeTree, Plugins) -> %% TODO, this call should be done plugin side case lists:member("hometree_odbc", Plugins) of true -> create_node(Host, ServerHost, string_to_node("/home"), service_jid(Host), "hometree_odbc"), create_node(Host, ServerHost, string_to_node("/home/"++ServerHost), service_jid(Host), "hometree_odbc"); false -> ok end. send_loop(State) -> receive {presence, JID, Pid} -> Host = State#state.host, ServerHost = State#state.server_host, LJID = jlib:jid_tolower(JID), BJID = jlib:jid_remove_resource(LJID), %% for each node From is subscribed to %% and if the node is so configured, send the last published item to From lists:foreach(fun(PType) -> Subscriptions = case catch node_action(Host, PType, get_entity_subscriptions_for_send_last, [Host, JID]) of {result, S} -> S; _ -> [] end, lists:foreach( fun({Node, subscribed, _, SubJID}) -> if (SubJID == LJID) or (SubJID == BJID) -> #pubsub_node{nodeid = {H, N}, type = Type, id = NodeId} = Node, send_items(H, N, NodeId, Type, LJID, last); true -> % resource not concerned about that subscription ok end; (_) -> ok end, Subscriptions) end, State#state.plugins), %% and force send the last PEP events published by its offline and local contacts %% only if pubsub is explicitely configured for that. %% this is a hack in a sense that PEP should only be based on presence %% and is not able to "store" events of remote users (via s2s) %% this makes that hack only work for local domain by now if not State#state.ignore_pep_from_offline -> {User, Server, Resource} = jlib:jid_tolower(JID), case catch ejabberd_c2s:get_subscribed(Pid) of Contacts when is_list(Contacts) -> lists:foreach( fun({U, S, R}) -> case S of ServerHost -> %% local contacts case user_resources(U, S) of [] -> %% offline PeerJID = jlib:make_jid(U, S, R), self() ! {presence, User, Server, [Resource], PeerJID}; _ -> %% online % this is already handled by presence probe ok end; _ -> %% remote contacts % we can not do anything in any cases ok end end, Contacts); _ -> ok end; true -> ok end, send_loop(State); {presence, User, Server, Resources, JID} -> %% get resources caps and check if processing is needed spawn(fun() -> Host = State#state.host, Owner = jlib:jid_remove_resource(jlib:jid_tolower(JID)), lists:foreach(fun(#pubsub_node{nodeid = {_, Node}, type = Type, id = NodeId, options = Options}) -> case get_option(Options, send_last_published_item) of on_sub_and_presence -> lists:foreach( fun(Resource) -> LJID = {User, Server, Resource}, Subscribed = case get_option(Options, access_model) of open -> true; presence -> true; whitelist -> false; % subscribers are added manually authorize -> false; % likewise roster -> Grps = get_option(Options, roster_groups_allowed, []), {OU, OS, _} = Owner, element(2, get_roster_info(OU, OS, LJID, Grps)) end, if Subscribed -> send_items(Owner, Node, NodeId, Type, LJID, last); true -> ok end end, Resources); _ -> ok end end, tree_action(Host, get_nodes, [Owner, JID])) end), send_loop(State); stop -> ok end. %% ------- %% disco hooks handling functions %% disco_local_identity(Acc, _From, To, [], _Lang) -> case lists:member(?PEPNODE, plugins(To#jid.lserver)) of true -> [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "pep"}], []} | Acc]; false -> Acc end; disco_local_identity(Acc, _From, _To, _Node, _Lang) -> Acc. disco_local_features(Acc, _From, To, [], _Lang) -> Host = To#jid.lserver, Feats = case Acc of {result, I} -> I; _ -> [] end, {result, Feats ++ lists:map(fun(Feature) -> ?NS_PUBSUB++"#"++Feature end, features(Host, <<>>))}; disco_local_features(Acc, _From, _To, _Node, _Lang) -> Acc. disco_local_items(Acc, _From, _To, [], _Lang) -> Acc; disco_local_items(Acc, _From, _To, _Node, _Lang) -> Acc. disco_sm_identity(Acc, From, To, Node, Lang) when is_list(Node) -> disco_sm_identity(Acc, From, To, list_to_binary(Node), Lang); disco_sm_identity(empty, From, To, Node, Lang) -> disco_sm_identity([], From, To, Node, Lang); disco_sm_identity(Acc, From, To, Node, _Lang) -> disco_identity(jlib:jid_tolower(jlib:jid_remove_resource(To)), Node, From) ++ Acc. disco_identity(_Host, <<>>, _From) -> [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "pep"}], []}]; disco_identity(Host, Node, From) -> Action = fun(#pubsub_node{id = Idx, type = Type, options = Options}) -> Owners = node_owners_call(Type, Idx), case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> {result, [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "pep"}], []}, {xmlelement, "identity", [{"category", "pubsub"}, {"type", "leaf"} | case get_option(Options, title) of false -> []; [Title] -> [{"name", Title}] end], []}]}; _ -> {result, []} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> Result; _ -> [] end. disco_sm_features(Acc, From, To, Node, Lang) when is_list(Node) -> disco_sm_features(Acc, From, To, list_to_binary(Node), Lang); disco_sm_features(empty, From, To, Node, Lang) -> disco_sm_features({result, []}, From, To, Node, Lang); disco_sm_features({result, OtherFeatures} = _Acc, From, To, Node, _Lang) -> {result, OtherFeatures ++ disco_features(jlib:jid_tolower(jlib:jid_remove_resource(To)), Node, From)}; disco_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. disco_features(_Host, <<>>, _From) -> [?NS_PUBSUB | [?NS_PUBSUB++"#"++Feature || Feature <- features("pep")]]; disco_features(Host, Node, From) -> Action = fun(#pubsub_node{id = Idx, type = Type, options = Options}) -> Owners = node_owners_call(Type, Idx), case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> {result, [?NS_PUBSUB | [?NS_PUBSUB ++ "#" ++ Feature || Feature <- features("pep")]]}; _ -> {result, []} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> Result; _ -> [] end. disco_sm_items(Acc, From, To, Node, Lang) when is_list(Node) -> disco_sm_items(Acc, From, To, list_to_binary(Node), Lang); disco_sm_items(empty, From, To, Node, Lang) -> disco_sm_items({result, []}, From, To, Node, Lang); disco_sm_items({result, OtherItems}, From, To, Node, _Lang) -> {result, lists:usort(OtherItems ++ disco_items(jlib:jid_tolower(jlib:jid_remove_resource(To)), Node, From))}; disco_sm_items(Acc, _From, _To, _Node, _Lang) -> Acc. disco_items(Host, <<>>, From) -> Action = fun(#pubsub_node{nodeid ={_, NodeID}, options = Options, type = Type, id = Idx}, Acc) -> Owners = node_owners_call(Type, Idx), case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> [{xmlelement, "item", [{"node", binary_to_list(NodeID)}, {"jid", case Host of {_,_,_} -> jlib:jid_to_string(Host); _Host -> Host end} | case get_option(Options, title) of false -> []; [Title] -> [{"name", Title}] end], []} | Acc]; _ -> Acc end end, case transaction_on_nodes(Host, Action, sync_dirty) of {result, Items} -> Items; _ -> [] end; disco_items(Host, Node, From) -> Action = fun(#pubsub_node{id = Idx, type = Type, options = Options}) -> Owners = node_owners_call(Type, Idx), case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, Items} -> {result, [{xmlelement, "item", [{"jid", case Host of {_,_,_} -> jlib:jid_to_string(Host); _Host -> Host end}, {"name", ItemID}], []} || #pubsub_item{itemid = {ItemID,_}} <- Items]}; _ -> {result, []} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> Result; _ -> [] end. %% ------- %% presence hooks handling functions %% caps_update(#jid{luser = U, lserver = S, lresource = R} = From, To, _Features) -> Pid = ejabberd_sm:get_session_pid(U, S, R), presence_probe(From, To, Pid). presence_probe(#jid{luser = User, lserver = Server, lresource = Resource} = JID, JID, Pid) -> %%?DEBUG("presence probe self ~s@~s/~s ~s@~s/~s",[User,Server,Resource,element(2,JID),element(3,JID),element(4,JID)]), presence(Server, {presence, JID, Pid}), presence(Server, {presence, User, Server, [Resource], JID}); presence_probe(#jid{luser = User, lserver = Server}, #jid{luser = User, lserver = Server}, _Pid) -> %% ignore presence_probe from other ressources for the current user %% this way, we do not send duplicated last items if user already connected with other clients ok; presence_probe(#jid{luser = User, lserver = Server, lresource = Resource}, #jid{lserver = Host} = JID, _Pid) -> %%?DEBUG("presence probe peer ~s@~s/~s ~s@~s/~s",[User,Server,Resource,element(2,JID),element(3,JID),element(4,JID)]), presence(Host, {presence, User, Server, [Resource], JID}). presence(ServerHost, Presence) -> SendLoop = case whereis(gen_mod:get_module_proc(ServerHost, ?LOOPNAME)) of undefined -> % in case send_loop process died, we rebuild a minimal State record and respawn it Host = host(ServerHost), Plugins = plugins(Host), PepOffline = case catch ets:lookup(gen_mod:get_module_proc(ServerHost, config), ignore_pep_from_offline) of [{ignore_pep_from_offline, PO}] -> PO; _ -> true end, State = #state{host = Host, server_host = ServerHost, ignore_pep_from_offline = PepOffline, plugins = Plugins}, init_send_loop(ServerHost, State); Pid -> Pid end, SendLoop ! Presence. %% ------- %% subscription hooks handling functions %% out_subscription(User, Server, JID, subscribed) -> Owner = jlib:make_jid(User, Server, ""), {PUser, PServer, PResource} = jlib:jid_tolower(JID), PResources = case PResource of [] -> user_resources(PUser, PServer); _ -> [PResource] end, presence(Server, {presence, PUser, PServer, PResources, Owner}), true; out_subscription(_,_,_,_) -> true. in_subscription(_, User, Server, Owner, unsubscribed, _) -> unsubscribe_user(jlib:make_jid(User, Server, ""), Owner), true; in_subscription(_, _, _, _, _, _) -> true. unsubscribe_user(Entity, Owner) -> BJID = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), Host = host(element(2, BJID)), spawn(fun() -> lists:foreach(fun(PType) -> {result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Entity]), lists:foreach(fun ({#pubsub_node{options = Options, id = NodeId}, subscribed, _, JID}) -> case get_option(Options, access_model) of presence -> case lists:member(BJID, node_owners(Host, PType, NodeId)) of true -> node_action(Host, PType, unsubscribe_node, [NodeId, Entity, JID, all]); false -> {result, ok} end; _ -> {result, ok} end; (_) -> ok end, Subscriptions) end, plugins(Host)) end). %% ------- %% user remove hook handling function %% remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), Entity = jlib:make_jid(LUser, LServer, ""), Host = host(LServer), HomeTreeBase = string_to_node("/home/"++LServer++"/"++LUser), spawn(fun() -> lists:foreach(fun(PType) -> {result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Entity]), lists:foreach(fun ({#pubsub_node{id = NodeId}, _, _, JID}) -> node_action(Host, PType, unsubscribe_node, [NodeId, Entity, JID, all]) end, Subscriptions), {result, Affiliations} = node_action(Host, PType, get_entity_affiliations, [Host, Entity]), lists:foreach(fun ({#pubsub_node{nodeid = {H, N}, parents = []}, owner}) -> delete_node(H, N, Entity); ({#pubsub_node{nodeid = {H, N}, type = "hometree"}, owner}) when N == HomeTreeBase -> delete_node(H, N, Entity); ({#pubsub_node{id = NodeId}, publisher}) -> node_action(Host, PType, set_affiliation, [NodeId, Entity, none]); (_) -> ok end, Affiliations) end, plugins(Host)) end). %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- %% @private handle_call(server_host, _From, State) -> {reply, State#state.server_host, State}; handle_call(plugins, _From, State) -> {reply, State#state.plugins, State}; handle_call(pep_mapping, _From, State) -> {reply, State#state.pep_mapping, State}; handle_call(nodetree, _From, State) -> {reply, State#state.nodetree, State}; handle_call(stop, _From, State) -> {stop, normal, ok, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- %% @private handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- %% @private handle_info({route, From, To, Packet}, #state{server_host = ServerHost, access = Access, plugins = Plugins} = State) -> case catch do_route(ServerHost, Access, Plugins, To#jid.lserver, From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); _ -> ok end, {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- %% @private terminate(_Reason, #state{host = Host, server_host = ServerHost, nodetree = TreePlugin, plugins = Plugins}) -> ejabberd_router:unregister_route(Host), case lists:member(?PEPNODE, Plugins) of true -> ejabberd_hooks:delete(caps_update, ServerHost, ?MODULE, caps_update, 80), ejabberd_hooks:delete(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75), ejabberd_hooks:delete(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75), ejabberd_hooks:delete(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75), gen_iq_handler:remove_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB), gen_iq_handler:remove_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB_OWNER); false -> ok end, ejabberd_hooks:delete(sm_remove_connection_hook, ServerHost, ?MODULE, on_user_offline, 75), ejabberd_hooks:delete(disco_local_identity, ServerHost, ?MODULE, disco_local_identity, 75), ejabberd_hooks:delete(disco_local_features, ServerHost, ?MODULE, disco_local_features, 75), ejabberd_hooks:delete(disco_local_items, ServerHost, ?MODULE, disco_local_items, 75), ejabberd_hooks:delete(presence_probe_hook, ServerHost, ?MODULE, presence_probe, 80), ejabberd_hooks:delete(roster_in_subscription, ServerHost, ?MODULE, in_subscription, 50), ejabberd_hooks:delete(roster_out_subscription, ServerHost, ?MODULE, out_subscription, 50), ejabberd_hooks:delete(remove_user, ServerHost, ?MODULE, remove_user, 50), ejabberd_hooks:delete(anonymous_purge_hook, ServerHost, ?MODULE, remove_user, 50), mod_disco:unregister_feature(ServerHost, ?NS_PUBSUB), gen_mod:get_module_proc(ServerHost, ?LOOPNAME) ! stop, terminate_plugins(Host, ServerHost, Plugins, TreePlugin). %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- %% @private code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- do_route(ServerHost, Access, Plugins, Host, From, To, Packet) -> {xmlelement, Name, Attrs, _Els} = Packet, case To of #jid{luser = "", lresource = ""} -> case Name of "iq" -> case jlib:iq_query_info(Packet) of #iq{type = get, xmlns = ?NS_DISCO_INFO, sub_el = SubEl, lang = Lang} = IQ -> {xmlelement, _, QAttrs, _} = SubEl, Node = xml:get_attr_s("node", QAttrs), Info = ejabberd_hooks:run_fold( disco_info, ServerHost, [], [ServerHost, ?MODULE, "", ""]), Res = case iq_disco_info(Host, Node, From, Lang) of {result, IQRes} -> jlib:iq_to_xml( IQ#iq{type = result, sub_el = [{xmlelement, "query", QAttrs, IQRes++Info}]}); {error, Error} -> jlib:make_error_reply(Packet, Error) end, ejabberd_router:route(To, From, Res); #iq{type = get, xmlns = ?NS_DISCO_ITEMS, sub_el = SubEl} = IQ -> {xmlelement, _, QAttrs, _} = SubEl, Node = xml:get_attr_s("node", QAttrs), Rsm = jlib:rsm_decode(IQ), Res = case iq_disco_items(Host, Node, From, Rsm) of {result, IQRes} -> jlib:iq_to_xml( IQ#iq{type = result, sub_el = [{xmlelement, "query", QAttrs, IQRes}]}); {error, Error} -> jlib:make_error_reply(Packet, Error) end, ejabberd_router:route(To, From, Res); #iq{type = IQType, xmlns = ?NS_PUBSUB, lang = Lang, sub_el = SubEl} = IQ -> Res = case iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, Access, Plugins) of {result, IQRes} -> jlib:iq_to_xml( IQ#iq{type = result, sub_el = IQRes}); {error, Error} -> jlib:make_error_reply(Packet, Error) end, ejabberd_router:route(To, From, Res); #iq{type = IQType, xmlns = ?NS_PUBSUB_OWNER, lang = Lang, sub_el = SubEl} = IQ -> Res = case iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) of {result, IQRes} -> jlib:iq_to_xml( IQ#iq{type = result, sub_el = IQRes}); {error, Error} -> jlib:make_error_reply(Packet, Error) end, ejabberd_router:route(To, From, Res); #iq{type = get, xmlns = ?NS_VCARD = XMLNS, lang = Lang, sub_el = _SubEl} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", XMLNS}], iq_get_vcard(Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{type = set, xmlns = ?NS_COMMANDS} = IQ -> Res = case iq_command(Host, ServerHost, From, IQ, Access, Plugins) of {error, Error} -> jlib:make_error_reply(Packet, Error); {result, IQRes} -> jlib:iq_to_xml(IQ#iq{type = result, sub_el = IQRes}) end, ejabberd_router:route(To, From, Res); #iq{} -> Err = jlib:make_error_reply( Packet, ?ERR_FEATURE_NOT_IMPLEMENTED), ejabberd_router:route(To, From, Err); _ -> ok end; "message" -> case xml:get_attr_s("type", Attrs) of "error" -> ok; _ -> case find_authorization_response(Packet) of none -> ok; invalid -> ejabberd_router:route(To, From, jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST)); XFields -> handle_authorization_response(Host, From, To, Packet, XFields) end end; _ -> ok end; _ -> case xml:get_attr_s("type", Attrs) of "error" -> ok; "result" -> ok; _ -> Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND), ejabberd_router:route(To, From, Err) end end. command_disco_info(_Host, <>, _From) -> IdentityEl = {xmlelement, "identity", [{"category", "automation"}, {"type", "command-list"}], []}, {result, [IdentityEl]}; command_disco_info(_Host, <>, _From) -> IdentityEl = {xmlelement, "identity", [{"category", "automation"}, {"type", "command-node"}], []}, FeaturesEl = {xmlelement, "feature", [{"var", ?NS_COMMANDS}], []}, {result, [IdentityEl, FeaturesEl]}. node_disco_info(Host, Node, From) -> node_disco_info(Host, Node, From, true, true). %node_disco_identity(Host, Node, From) -> % node_disco_info(Host, Node, From, true, false). %node_disco_features(Host, Node, From) -> % node_disco_info(Host, Node, From, false, true). node_disco_info(Host, Node, From, Identity, Features) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> I = case Identity of false -> []; true -> Types = case tree_call(Host, get_subnodes, [Host, Node, From]) of [] -> ["leaf"]; %% No sub-nodes: it's a leaf node _ -> case node_call(Type, get_items, [NodeId, From, none]) of {result, []} -> ["collection"]; {result, _} -> ["leaf", "collection"]; _ -> [] end end, lists:map(fun(T) -> {xmlelement, "identity", [{"category", "pubsub"}, {"type", T}], []} end, Types) end, F = case Features of false -> []; true -> [{xmlelement, "feature", [{"var", ?NS_PUBSUB}], []} | lists:map(fun ("rsm")-> {xmlelement, "feature", [{"var", ?NS_RSM}], []}; (T) -> {xmlelement, "feature", [{"var", ?NS_PUBSUB++"#"++T}], []} end, features(Type))] end, %% TODO: add meta-data info (spec section 5.4) {result, I ++ F} end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; Other -> Other end. iq_disco_info(Host, SNode, From, Lang) -> [RealSNode|_] = case SNode of [] -> [[]]; _ -> string:tokens(SNode, "!") end, Node = string_to_node(RealSNode), case Node of <<>> -> {result, [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "service"}, {"name", translate:translate(Lang, "Publish-Subscribe")}], []}, {xmlelement, "feature", [{"var", ?NS_DISCO_INFO}], []}, {xmlelement, "feature", [{"var", ?NS_DISCO_ITEMS}], []}, {xmlelement, "feature", [{"var", ?NS_PUBSUB}], []}, {xmlelement, "feature", [{"var", ?NS_COMMANDS}], []}, {xmlelement, "feature", [{"var", ?NS_VCARD}], []}] ++ lists:map(fun ("rsm")-> {xmlelement, "feature", [{"var", ?NS_RSM}], []}; (T) -> {xmlelement, "feature", [{"var", ?NS_PUBSUB++"#"++T}], []} end, features(Host, Node))}; <> -> command_disco_info(Host, Node, From); <> -> command_disco_info(Host, Node, From); _ -> node_disco_info(Host, Node, From) end. iq_disco_items(Host, [], From, _RSM) -> case tree_action(Host, get_subnodes, [Host, <<>>, From]) of Nodes when is_list(Nodes) -> {result, lists:map( fun(#pubsub_node{nodeid = {_, SubNode}, options = Options}) -> Attrs = case get_option(Options, title) of false -> [{"jid", Host} |nodeAttr(SubNode)]; Title -> [{"jid", Host}, {"name", Title}|nodeAttr(SubNode)] end, {xmlelement, "item", Attrs, []} end, Nodes)}; Other -> Other end; iq_disco_items(Host, ?NS_COMMANDS, _From, _RSM) -> %% TODO: support localization of this string CommandItems = [{xmlelement, "item", [{"jid", Host}, {"node", ?NS_PUBSUB_GET_PENDING}, {"name", "Get Pending"}], []}], {result, CommandItems}; iq_disco_items(_Host, ?NS_PUBSUB_GET_PENDING, _From, _RSM) -> CommandItems = [], {result, CommandItems}; iq_disco_items(Host, Item, From, RSM) -> case string:tokens(Item, "!") of [_SNode, _ItemID] -> {result, []}; [SNode] -> Node = string_to_node(SNode), Action = fun(#pubsub_node{id = Idx, type = Type, options = Options}) -> Owners = node_owners_call(Type, Idx), {NodeItems, RsmOut} = case get_allowed_items_call(Host, Idx, From, Type, Options, Owners, RSM) of {result, R} -> R; _ -> {[], none} end, Nodes = lists:map( fun(#pubsub_node{nodeid = {_, SubNode}, options = SubOptions}) -> Attrs = case get_option(SubOptions, title) of false -> [{"jid", Host} |nodeAttr(SubNode)]; Title -> [{"jid", Host}, {"name", Title}|nodeAttr(SubNode)] end, {xmlelement, "item", Attrs, []} end, tree_call(Host, get_subnodes, [Host, Node, From])), Items = lists:map( fun(#pubsub_item{itemid = {RN, _}}) -> {result, Name} = node_call(Type, get_item_name, [Host, Node, RN]), {xmlelement, "item", [{"jid", Host}, {"name", Name}], []} end, NodeItems), {result, Nodes ++ Items ++ jlib:rsm_encode(RsmOut)} end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; Other -> Other end end. iq_sm(From, To, #iq{type = Type, sub_el = SubEl, xmlns = XMLNS, lang = Lang} = IQ) -> ServerHost = To#jid.lserver, LOwner = jlib:jid_tolower(jlib:jid_remove_resource(To)), Res = case XMLNS of ?NS_PUBSUB -> iq_pubsub(LOwner, ServerHost, From, Type, SubEl, Lang); ?NS_PUBSUB_OWNER -> iq_pubsub_owner(LOwner, ServerHost, From, Type, SubEl, Lang) end, case Res of {result, IQRes} -> IQ#iq{type = result, sub_el = IQRes}; {error, Error} -> IQ#iq{type = error, sub_el = [Error, SubEl]} end. iq_get_vcard(Lang) -> [{xmlelement, "FN", [], [{xmlcdata, "ejabberd/mod_pubsub"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate(Lang, "ejabberd Publish-Subscribe module") ++ "\nCopyright (c) 2004-2012 ProcessOne"}]}]. iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang) -> iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, all, plugins(ServerHost)). iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, Access, Plugins) -> {xmlelement, _, _, SubEls} = SubEl, case xml:remove_cdata(SubEls) of [{xmlelement, Name, Attrs, Els} | Rest] -> Node = string_to_node(xml:get_attr_s("node", Attrs)), case {IQType, Name} of {set, "create"} -> Config = case Rest of [{xmlelement, "configure", _, C}] -> C; _ -> [] end, %% Get the type of the node Type = case xml:get_attr_s("type", Attrs) of [] -> hd(Plugins); T -> T end, %% we use Plugins list matching because we do not want to allocate %% atoms for non existing type, this prevent atom allocation overflow case lists:member(Type, Plugins) of false -> {error, extended_error( ?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "create-nodes")}; true -> create_node(Host, ServerHost, Node, From, Type, Access, Config) end; {set, "publish"} -> case xml:remove_cdata(Els) of [{xmlelement, "item", ItemAttrs, Payload}] -> ItemId = xml:get_attr_s("id", ItemAttrs), publish_item(Host, ServerHost, Node, From, ItemId, Payload); [] -> %% Publisher attempts to publish to persistent node with no item {error, extended_error(?ERR_BAD_REQUEST, "item-required")}; _ -> %% Entity attempts to publish item with multiple payload elements or namespace does not match {error, extended_error(?ERR_BAD_REQUEST, "invalid-payload")} end; {set, "retract"} -> ForceNotify = case xml:get_attr_s("notify", Attrs) of "1" -> true; "true" -> true; _ -> false end, case xml:remove_cdata(Els) of [{xmlelement, "item", ItemAttrs, _}] -> ItemId = xml:get_attr_s("id", ItemAttrs), delete_item(Host, Node, From, ItemId, ForceNotify); _ -> %% Request does not specify an item {error, extended_error(?ERR_BAD_REQUEST, "item-required")} end; {set, "subscribe"} -> Config = case Rest of [{xmlelement, "options", _, C}] -> C; _ -> [] end, JID = xml:get_attr_s("jid", Attrs), subscribe_node(Host, Node, From, JID, Config); {set, "unsubscribe"} -> JID = xml:get_attr_s("jid", Attrs), SubId = xml:get_attr_s("subid", Attrs), unsubscribe_node(Host, Node, From, JID, SubId); {get, "items"} -> MaxItems = xml:get_attr_s("max_items", Attrs), SubId = xml:get_attr_s("subid", Attrs), ItemIDs = lists:foldl(fun ({xmlelement, "item", ItemAttrs, _}, Acc) -> case xml:get_attr_s("id", ItemAttrs) of "" -> Acc; ItemID -> [ItemID|Acc] end; (_, Acc) -> Acc end, [], xml:remove_cdata(Els)), RSM = jlib:rsm_decode(SubEl), get_items(Host, Node, From, SubId, MaxItems, ItemIDs, RSM); {get, "subscriptions"} -> get_subscriptions(Host, Node, From, Plugins); {get, "affiliations"} -> get_affiliations(Host, Node, From, Plugins); {get, "options"} -> SubID = xml:get_attr_s("subid", Attrs), JID = xml:get_attr_s("jid", Attrs), get_options(Host, Node, JID, SubID, Lang); {set, "options"} -> SubID = xml:get_attr_s("subid", Attrs), JID = xml:get_attr_s("jid", Attrs), set_options(Host, Node, JID, SubID, Els); _ -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED} end; Other -> ?INFO_MSG("Too many actions: ~p", [Other]), {error, ?ERR_BAD_REQUEST} end. iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) -> {xmlelement, _, _, SubEls} = SubEl, Action = lists:filter(fun({xmlelement, "set", _, _}) -> false; (_) -> true end, xml:remove_cdata(SubEls)), case Action of [{xmlelement, Name, Attrs, Els}] -> Node = string_to_node(xml:get_attr_s("node", Attrs)), case {IQType, Name} of {get, "configure"} -> get_configure(Host, ServerHost, Node, From, Lang); {set, "configure"} -> set_configure(Host, Node, From, Els, Lang); {get, "default"} -> get_default(Host, Node, From, Lang); {set, "delete"} -> delete_node(Host, Node, From); {set, "purge"} -> purge_node(Host, Node, From); {get, "subscriptions"} -> get_subscriptions(Host, Node, From); {set, "subscriptions"} -> set_subscriptions(Host, Node, From, xml:remove_cdata(Els)); {get, "affiliations"} -> get_affiliations(Host, Node, From); {set, "affiliations"} -> set_affiliations(Host, Node, From, xml:remove_cdata(Els)); _ -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED} end; _ -> ?INFO_MSG("Too many actions: ~p", [Action]), {error, ?ERR_BAD_REQUEST} end. iq_command(Host, ServerHost, From, IQ, Access, Plugins) -> case adhoc:parse_request(IQ) of Req when is_record(Req, adhoc_request) -> case adhoc_request(Host, ServerHost, From, Req, Access, Plugins) of Resp when is_record(Resp, adhoc_response) -> {result, [adhoc:produce_response(Req, Resp)]}; Error -> Error end; Err -> Err end. %% @doc

Processes an Ad Hoc Command.

adhoc_request(Host, _ServerHost, Owner, #adhoc_request{node = ?NS_PUBSUB_GET_PENDING, lang = Lang, action = "execute", xdata = false}, _Access, Plugins) -> send_pending_node_form(Host, Owner, Lang, Plugins); adhoc_request(Host, _ServerHost, Owner, #adhoc_request{node = ?NS_PUBSUB_GET_PENDING, action = "execute", xdata = XData}, _Access, _Plugins) -> ParseOptions = case XData of {xmlelement, "x", _Attrs, _SubEls} = XEl -> case jlib:parse_xdata_submit(XEl) of invalid -> {error, ?ERR_BAD_REQUEST}; XData2 -> case set_xoption(Host, XData2, []) of NewOpts when is_list(NewOpts) -> {result, NewOpts}; Err -> Err end end; _ -> ?INFO_MSG("Bad XForm: ~p", [XData]), {error, ?ERR_BAD_REQUEST} end, case ParseOptions of {result, XForm} -> case lists:keysearch(node, 1, XForm) of {value, {_, Node}} -> send_pending_auth_events(Host, Node, Owner); false -> {error, extended_error(?ERR_BAD_REQUEST, "bad-payload")} end; Error -> Error end; adhoc_request(_Host, _ServerHost, _Owner, #adhoc_request{action = "cancel"}, _Access, _Plugins) -> #adhoc_response{status = canceled}; adhoc_request(Host, ServerHost, Owner, #adhoc_request{action = []} = R, Access, Plugins) -> adhoc_request(Host, ServerHost, Owner, R#adhoc_request{action = "execute"}, Access, Plugins); adhoc_request(_Host, _ServerHost, _Owner, Other, _Access, _Plugins) -> ?DEBUG("Couldn't process ad hoc command:~n~p", [Other]), {error, ?ERR_ITEM_NOT_FOUND}. %% @spec (Host, Owner, Lang, Plugins) -> iqRes() %% @doc

Sends the process pending subscriptions XForm for Host to %% Owner.

send_pending_node_form(Host, Owner, _Lang, Plugins) -> Filter = fun (Plugin) -> lists:member("get-pending", features(Plugin)) end, case lists:filter(Filter, Plugins) of [] -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED}; Ps -> XOpts = lists:map(fun (Node) -> {xmlelement, "option", [], [{xmlelement, "value", [], [{xmlcdata, node_to_string(Node)}]}]} end, get_pending_nodes(Host, Owner, Ps)), XForm = {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [{xmlelement, "field", [{"type", "list-single"}, {"var", "pubsub#node"}], lists:usort(XOpts)}]}, #adhoc_response{status = executing, defaultaction = "execute", elements = [XForm]} end. get_pending_nodes(Host, Owner, Plugins) -> Tr = fun (Type) -> case node_call(Type, get_pending_nodes, [Host, Owner]) of {result, Nodes} -> Nodes; _ -> [] end end, case transaction(Host, fun () -> {result, lists:flatmap(Tr, Plugins)} end, sync_dirty) of {result, Res} -> Res; Err -> Err end. %% @spec (Host, Node, Owner) -> iqRes() %% @doc

Send a subscription approval form to Owner for all pending %% subscriptions on Host and Node.

send_pending_auth_events(Host, Node, Owner) -> ?DEBUG("Sending pending auth events for ~s on ~s:~s", [jlib:jid_to_string(Owner), Host, node_to_string(Node)]), Action = fun (#pubsub_node{id = NodeID, type = Type}) -> case lists:member("get-pending", features(Type)) of true -> case node_call(Type, get_affiliation, [NodeID, Owner]) of {result, owner} -> node_call(Type, get_node_subscriptions, [NodeID]); _ -> {error, ?ERR_FORBIDDEN} end; false -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {N, Subscriptions}} -> lists:foreach(fun({J, pending, _SubID}) -> send_authorization_request(N, jlib:make_jid(J)); ({J, pending}) -> send_authorization_request(N, jlib:make_jid(J)); (_) -> ok end, Subscriptions), #adhoc_response{}; Err -> Err end. %%% authorization handling send_authorization_request(#pubsub_node{nodeid = {Host, Node}, type = Type, id = NodeId}, Subscriber) -> Lang = "en", %% TODO fix Stanza = {xmlelement, "message", [], [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "PubSub subscriber request")}]}, {xmlelement, "instructions", [], [{xmlcdata, translate:translate(Lang, "Choose whether to approve this entity's subscription.")}]}, {xmlelement, "field", [{"var", "FORM_TYPE"}, {"type", "hidden"}], [{xmlelement, "value", [], [{xmlcdata, ?NS_PUBSUB_SUB_AUTH}]}]}, {xmlelement, "field", [{"var", "pubsub#node"}, {"type", "text-single"}, {"label", translate:translate(Lang, "Node ID")}], [{xmlelement, "value", [], [{xmlcdata, node_to_string(Node)}]}]}, {xmlelement, "field", [{"var", "pubsub#subscriber_jid"}, {"type", "jid-single"}, {"label", translate:translate(Lang, "Subscriber Address")}], [{xmlelement, "value", [], [{xmlcdata, jlib:jid_to_string(Subscriber)}]}]}, {xmlelement, "field", [{"var", "pubsub#allow"}, {"type", "boolean"}, {"label", translate:translate(Lang, "Allow this Jabber ID to subscribe to this pubsub node?")}], [{xmlelement, "value", [], [{xmlcdata, "false"}]}]}]}]}, lists:foreach(fun(Owner) -> ejabberd_router:route(service_jid(Host), jlib:make_jid(Owner), Stanza) end, node_owners(Host, Type, NodeId)). find_authorization_response(Packet) -> {xmlelement, _Name, _Attrs, Els} = Packet, XData1 = lists:map(fun({xmlelement, "x", XAttrs, _} = XEl) -> case xml:get_attr_s("xmlns", XAttrs) of ?NS_XDATA -> case xml:get_attr_s("type", XAttrs) of "cancel" -> none; _ -> jlib:parse_xdata_submit(XEl) end; _ -> none end; (_) -> none end, xml:remove_cdata(Els)), XData = lists:filter(fun(E) -> E /= none end, XData1), case XData of [invalid] -> invalid; [] -> none; [XFields] when is_list(XFields) -> ?DEBUG("XFields: ~p", [XFields]), case lists:keysearch("FORM_TYPE", 1, XFields) of {value, {_, [?NS_PUBSUB_SUB_AUTH]}} -> XFields; _ -> invalid end end. %% @spec (Host, JID, Node, Subscription) -> void %% Host = mod_pubsub:host() %% JID = jlib:jid() %% SNode = string() %% Subscription = atom() | {atom(), mod_pubsub:subid()} %% @doc Send a message to JID with the supplied Subscription send_authorization_approval(Host, JID, SNode, Subscription) -> SubAttrs = case Subscription of {S, SID} -> [{"subscription", subscription_to_string(S)}, {"subid", SID}]; S -> [{"subscription", subscription_to_string(S)}] end, Stanza = event_stanza( [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(JID)}|nodeAttr(SNode)] ++ SubAttrs, []}]), ejabberd_router:route(service_jid(Host), JID, Stanza). handle_authorization_response(Host, From, To, Packet, XFields) -> case {lists:keysearch("pubsub#node", 1, XFields), lists:keysearch("pubsub#subscriber_jid", 1, XFields), lists:keysearch("pubsub#allow", 1, XFields)} of {{value, {_, [SNode]}}, {value, {_, [SSubscriber]}}, {value, {_, [SAllow]}}} -> Node = string_to_node(SNode), Subscriber = jlib:string_to_jid(SSubscriber), Allow = case SAllow of "1" -> true; "true" -> true; _ -> false end, Action = fun(#pubsub_node{type = Type, id = NodeId}) -> IsApprover = lists:member(jlib:jid_tolower(jlib:jid_remove_resource(From)), node_owners_call(Type, NodeId)), {result, Subscriptions} = node_call(Type, get_subscriptions, [NodeId, Subscriber]), if not IsApprover -> {error, ?ERR_FORBIDDEN}; true -> update_auth(Host, SNode, Type, NodeId, Subscriber, Allow, Subscriptions) end end, case transaction(Host, Node, Action, sync_dirty) of {error, Error} -> ejabberd_router:route( To, From, jlib:make_error_reply(Packet, Error)); {result, {_, _NewSubscription}} -> %% XXX: notify about subscription state change, section 12.11 ok; _ -> ejabberd_router:route( To, From, jlib:make_error_reply(Packet, ?ERR_INTERNAL_SERVER_ERROR)) end; _ -> ejabberd_router:route( To, From, jlib:make_error_reply(Packet, ?ERR_NOT_ACCEPTABLE)) end. update_auth(Host, Node, Type, NodeId, Subscriber, Allow, Subscriptions) -> Subscription = lists:filter(fun({pending, _}) -> true; (_) -> false end, Subscriptions), case Subscription of [{pending, SubID}] -> %% TODO does not work if several pending NewSubscription = case Allow of true -> subscribed; false -> none end, node_call(Type, set_subscriptions, [NodeId, Subscriber, NewSubscription, SubID]), send_authorization_approval(Host, Subscriber, Node, NewSubscription), {result, ok}; _ -> {error, ?ERR_UNEXPECTED_REQUEST} end. -define(XFIELD(Type, Label, Var, Val), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). -define(BOOLXFIELD(Label, Var, Val), ?XFIELD("boolean", Label, Var, case Val of true -> "1"; _ -> "0" end)). -define(STRINGXFIELD(Label, Var, Val), ?XFIELD("text-single", Label, Var, Val)). -define(STRINGMXFIELD(Label, Var, Vals), {xmlelement, "field", [{"type", "text-multi"}, {"label", translate:translate(Lang, Label)}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, V}]} || V <- Vals]}). -define(XFIELDOPT(Type, Label, Var, Val, Opts), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, {"var", Var}], lists:map(fun(Opt) -> {xmlelement, "option", [], [{xmlelement, "value", [], [{xmlcdata, Opt}]}]} end, Opts) ++ [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). -define(LISTXFIELD(Label, Var, Val, Opts), ?XFIELDOPT("list-single", Label, Var, Val, Opts)). -define(LISTMXFIELD(Label, Var, Vals, Opts), {xmlelement, "field", [{"type", "list-multi"}, {"label", translate:translate(Lang, Label)}, {"var", Var}], lists:map(fun(Opt) -> {xmlelement, "option", [], [{xmlelement, "value", [], [{xmlcdata, Opt}]}]} end, Opts) ++ lists:map(fun(Val) -> {xmlelement, "value", [], [{xmlcdata, Val}]} end, Vals)}). %% @spec (Host::host(), ServerHost::host(), Node::pubsubNode(), Owner::jid(), NodeType::nodeType()) -> %% {error, Reason::stanzaError()} | %% {result, []} %% @doc

Create new pubsub nodes

%%

In addition to method-specific error conditions, there are several general reasons why the node creation request might fail:

%%
    %%
  • The service does not support node creation.
  • %%
  • Only entities that are registered with the service are allowed to create nodes but the requesting entity is not registered.
  • %%
  • The requesting entity does not have sufficient privileges to create nodes.
  • %%
  • The requested NodeID already exists.
  • %%
  • The request did not include a NodeID and "instant nodes" are not supported.
  • %%
%%

ote: node creation is a particular case, error return code is evaluated at many places:

%%
    %%
  • iq_pubsub checks if service supports node creation (type exists)
  • %%
  • create_node checks if instant nodes are supported
  • %%
  • create_node asks node plugin if entity have sufficient privilege
  • %%
  • nodetree create_node checks if nodeid already exists
  • %%
  • node plugin create_node just sets default affiliation/subscription
  • %%
create_node(Host, ServerHost, Node, Owner, Type) -> create_node(Host, ServerHost, Node, Owner, Type, all, []). create_node(Host, ServerHost, <<>>, Owner, Type, Access, Configuration) -> case lists:member("instant-nodes", features(Type)) of true -> NewNode = string_to_node(randoms:get_string()), case create_node(Host, ServerHost, NewNode, Owner, Type, Access, Configuration) of {result, []} -> {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "create", nodeAttr(NewNode), []}]}]}; Error -> Error end; false -> %% Service does not support instant nodes {error, extended_error(?ERR_NOT_ACCEPTABLE, "nodeid-required")} end; create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) -> Type = select_type(ServerHost, Host, Node, GivenType), %% TODO, check/set node_type = Type ParseOptions = case xml:remove_cdata(Configuration) of [] -> {result, node_options(Type)}; [{xmlelement, "x", _Attrs, _SubEls} = XEl] -> case jlib:parse_xdata_submit(XEl) of invalid -> {error, ?ERR_BAD_REQUEST}; XData -> case set_xoption(Host, XData, node_options(Type)) of NewOpts when is_list(NewOpts) -> {result, NewOpts}; Err -> Err end end; _ -> ?INFO_MSG("Node ~p; bad configuration: ~p", [Node, Configuration]), {error, ?ERR_BAD_REQUEST} end, case ParseOptions of {result, NodeOptions} -> CreateNode = fun() -> SNode = node_to_string(Node), Parent = case node_call(Type, node_to_path, [Node]) of {result, [SNode]} -> <<>>; {result, Path} -> element(2, node_call(Type, path_to_node, [lists:sublist(Path, length(Path)-1)])) end, Parents = case Parent of <<>> -> []; _ -> [Parent] end, case node_call(Type, create_node_permission, [Host, ServerHost, Node, Parent, Owner, Access]) of {result, true} -> case tree_call(Host, create_node, [Host, Node, Type, Owner, NodeOptions, Parents]) of {ok, NodeId} -> ParentTree = tree_call(Host, get_parentnodes_tree, [Host, Node, Owner]), SubsByDepth = [{Depth, [{N, get_node_subs(N)} || N <- Nodes]} || {Depth, Nodes} <- ParentTree], case node_call(Type, create_node, [NodeId, Owner]) of {result, Result} -> {result, {NodeId, SubsByDepth, Result}}; Error -> Error end; {error, {virtual, NodeId}} -> case node_call(Type, create_node, [NodeId, Owner]) of {result, Result} -> {result, {NodeId, [], Result}}; Error -> Error end; Error -> Error end; _ -> {error, ?ERR_FORBIDDEN} end end, Reply = [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "create", nodeAttr(Node), []}]}], case transaction(Host, CreateNode, transaction) of {result, {NodeId, SubsByDepth, {Result, broadcast}}} -> broadcast_created_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth), ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), case Result of default -> {result, Reply}; _ -> {result, Result} end; {result, {NodeId, _SubsByDepth, default}} -> ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), {result, Reply}; {result, {NodeId, _SubsByDepth, Result}} -> ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), {result, Result}; Error -> %% in case we change transaction to sync_dirty... %% node_call(Type, delete_node, [Host, Node]), %% tree_call(Host, delete_node, [Host, Node]), Error end; Error -> Error end. %% @spec (Host, Node, Owner) -> %% {error, Reason} | {result, []} %% Host = host() %% Node = pubsubNode() %% Owner = jid() %% Reason = stanzaError() %% @doc

Delete specified node and all childs.

%%

There are several reasons why the node deletion request might fail:

%%
    %%
  • The requesting entity does not have sufficient privileges to delete the node.
  • %%
  • The node is the root collection node, which cannot be deleted.
  • %%
  • The specified node does not exist.
  • %%
delete_node(_Host, <<>>, _Owner) -> %% Node is the root {error, ?ERR_NOT_ALLOWED}; delete_node(Host, Node, Owner) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> case node_call(Type, get_affiliation, [NodeId, Owner]) of {result, owner} -> ParentTree = tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]), SubsByDepth = [{Depth, [{N, get_node_subs(N)} || N <- Nodes]} || {Depth, Nodes} <- ParentTree], Removed = tree_call(Host, delete_node, [Host, Node]), case node_call(Type, delete_node, [Removed]) of {result, Res} -> {result, {SubsByDepth, Res}}; Error -> Error end; _ -> %% Entity is not an owner {error, ?ERR_FORBIDDEN} end end, Reply = [], ServerHost = get(server_host), % not clean, but prevent many API changes case transaction(Host, Node, Action, transaction) of {result, {_TNode, {SubsByDepth, {Result, broadcast, Removed}}}} -> lists:foreach(fun({RNode, _RSubscriptions}) -> {RH, RN} = RNode#pubsub_node.nodeid, NodeId = RNode#pubsub_node.id, Type = RNode#pubsub_node.type, Options = RNode#pubsub_node.options, broadcast_removed_node(RH, RN, NodeId, Type, Options, SubsByDepth), ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, RH, RN, NodeId]) end, Removed), case Result of default -> {result, Reply}; _ -> {result, Result} end; {result, {_TNode, {_, {Result, Removed}}}} -> lists:foreach(fun({RNode, _RSubscriptions}) -> {RH, RN} = RNode#pubsub_node.nodeid, NodeId = RNode#pubsub_node.id, ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, RH, RN, NodeId]) end, Removed), case Result of default -> {result, Reply}; _ -> {result, Result} end; {result, {TNode, {_, default}}} -> NodeId = TNode#pubsub_node.id, ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, Host, Node, NodeId]), {result, Reply}; {result, {TNode, {_, Result}}} -> NodeId = TNode#pubsub_node.id, ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, Host, Node, NodeId]), {result, Result}; Error -> Error end. %% @spec (Host, Node, From, JID, Configuration) -> %% {error, Reason::stanzaError()} | %% {result, []} %% Host = host() %% Node = pubsubNode() %% From = jid() %% JID = jid() %% @see node_hometree:subscribe_node/5 %% @doc

Accepts or rejects subcription requests on a PubSub node.

%%

There are several reasons why the subscription request might fail:

%%
    %%
  • The bare JID portions of the JIDs do not match.
  • %%
  • The node has an access model of "presence" and the requesting entity is not subscribed to the owner's presence.
  • %%
  • The node has an access model of "roster" and the requesting entity is not in one of the authorized roster groups.
  • %%
  • The node has an access model of "whitelist" and the requesting entity is not on the whitelist.
  • %%
  • The service requires payment for subscriptions to the node.
  • %%
  • The requesting entity is anonymous and the service does not allow anonymous entities to subscribe.
  • %%
  • The requesting entity has a pending subscription.
  • %%
  • The requesting entity is blocked from subscribing (e.g., because having an affiliation of outcast).
  • %%
  • The node does not support subscriptions.
  • %%
  • The node does not exist.
  • %%
subscribe_node(Host, Node, From, JID, Configuration) -> SubOpts = case pubsub_subscription_odbc:parse_options_xform(Configuration) of {result, GoodSubOpts} -> GoodSubOpts; _ -> invalid end, Subscriber = case jlib:string_to_jid(JID) of error -> {"", "", ""}; J -> jlib:jid_tolower(J) end, Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> Features = features(Type), SubscribeFeature = lists:member("subscribe", Features), OptionsFeature = lists:member("subscription-options", Features), HasOptions = not (SubOpts == []), SubscribeConfig = get_option(Options, subscribe), AccessModel = get_option(Options, access_model), SendLast = get_option(Options, send_last_published_item), AllowedGroups = get_option(Options, roster_groups_allowed, []), Owners = node_owners_call(Type, NodeId), {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, Subscriber, Owners, AccessModel, AllowedGroups), if not SubscribeFeature -> %% Node does not support subscriptions {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscribe")}; not SubscribeConfig -> %% Node does not support subscriptions {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscribe")}; HasOptions andalso not OptionsFeature -> %% Node does not support subscription options {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscription-options")}; SubOpts == invalid -> %% Passed invalit options submit form {error, extended_error(?ERR_BAD_REQUEST, "invalid-options")}; true -> node_call(Type, subscribe_node, [NodeId, From, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, SubOpts]) end end, Reply = fun(Subscription) -> %% TODO, this is subscription-notification, should depends on node features SubAttrs = case Subscription of {subscribed, SubId} -> [{"subscription", subscription_to_string(subscribed)}, {"subid", SubId}, {"node",Node}]; Other -> [{"subscription", subscription_to_string(Other)}, {"node", Node}] end, Fields = [{"jid", jlib:jid_to_string(Subscriber)} | SubAttrs], [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "subscription", Fields, []}]}] end, case transaction(Host, Node, Action, sync_dirty) of {result, {TNode, {Result, subscribed, SubId, send_last}}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, send_items(Host, Node, NodeId, Type, Subscriber, last), case Result of default -> {result, Reply({subscribed, SubId})}; _ -> {result, Result} end; {result, {_TNode, {default, subscribed, SubId}}} -> {result, Reply({subscribed, SubId})}; {result, {_TNode, {Result, subscribed, _SubId}}} -> {result, Result}; {result, {TNode, {default, pending, _SubId}}} -> send_authorization_request(TNode, Subscriber), {result, Reply(pending)}; {result, {TNode, {Result, pending}}} -> send_authorization_request(TNode, Subscriber), {result, Result}; {result, {_, Result}} -> %% this case should never occure anyway {result, Result}; Error -> Error end. %% @spec (Host, Noce, From, JID, SubId) -> {error, Reason} | {result, []} %% Host = host() %% Node = pubsubNode() %% From = jid() %% JID = string() %% SubId = string() %% Reason = stanzaError() %% @doc

Unsubscribe JID from the Node.

%%

There are several reasons why the unsubscribe request might fail:

%%
    %%
  • The requesting entity has multiple subscriptions to the node but does not specify a subscription ID.
  • %%
  • The request does not specify an existing subscriber.
  • %%
  • The requesting entity does not have sufficient privileges to unsubscribe the specified JID.
  • %%
  • The node does not exist.
  • %%
  • The request specifies a subscription ID that is not valid or current.
  • %%
unsubscribe_node(Host, Node, From, JID, SubId) when is_list(JID) -> Subscriber = case jlib:string_to_jid(JID) of error -> {"", "", ""}; J -> jlib:jid_tolower(J) end, unsubscribe_node(Host, Node, From, Subscriber, SubId); unsubscribe_node(Host, Node, From, Subscriber, SubId) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> node_call(Type, unsubscribe_node, [NodeId, From, Subscriber, SubId]) end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, default}} -> {result, []}; {result, {_, Result}} -> {result, Result}; Error -> Error end. %% @spec (Host::host(), ServerHost::host(), JID::jid(), Node::pubsubNode(), ItemId::string(), Payload::term()) -> %% {error, Reason::stanzaError()} | %% {result, []} %% @doc

Publish item to a PubSub node.

%%

The permission to publish an item must be verified by the plugin implementation.

%%

There are several reasons why the publish request might fail:

%%
    %%
  • The requesting entity does not have sufficient privileges to publish.
  • %%
  • The node does not support item publication.
  • %%
  • The node does not exist.
  • %%
  • The payload size exceeds a service-defined limit.
  • %%
  • The item contains more than one payload element or the namespace of the root payload element does not match the configured namespace for the node.
  • %%
  • The request does not match the node configuration.
  • %%
publish_item(Host, ServerHost, Node, Publisher, "", Payload) -> %% if publisher does not specify an ItemId, the service MUST generate the ItemId publish_item(Host, ServerHost, Node, Publisher, uniqid(), Payload); publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> Features = features(Type), PublishFeature = lists:member("publish", Features), PublishModel = get_option(Options, publish_model), MaxItems = max_items(Host, Options), DeliverPayloads = get_option(Options, deliver_payloads), PersistItems = get_option(Options, persist_items), PayloadCount = payload_xmlelements(Payload), PayloadSize = size(term_to_binary(Payload))-2, % size(term_to_binary([])) == 2 PayloadMaxSize = get_option(Options, max_payload_size), % pubsub#deliver_payloads true % pubsub#persist_items true -> 1 item; false -> 0 item if not PublishFeature -> %% Node does not support item publication {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "publish")}; PayloadSize > PayloadMaxSize -> %% Entity attempts to publish very large payload {error, extended_error(?ERR_NOT_ACCEPTABLE, "payload-too-big")}; (PayloadCount == 0) and (Payload == []) -> %% Publisher attempts to publish to payload node with no payload {error, extended_error(?ERR_BAD_REQUEST, "payload-required")}; (PayloadCount > 1) or (PayloadCount == 0) -> %% Entity attempts to publish item with multiple payload elements {error, extended_error(?ERR_BAD_REQUEST, "invalid-payload")}; (DeliverPayloads == 0) and (PersistItems == 0) and (PayloadSize > 0) -> %% Publisher attempts to publish to transient notification node with item {error, extended_error(?ERR_BAD_REQUEST, "item-forbidden")}; ((DeliverPayloads == 1) or (PersistItems == 1)) and (PayloadSize == 0) -> %% Publisher attempts to publish to persistent node with no item {error, extended_error(?ERR_BAD_REQUEST, "item-required")}; true -> node_call(Type, publish_item, [NodeId, Publisher, PublishModel, MaxItems, ItemId, Payload]) end end, ejabberd_hooks:run(pubsub_publish_item, ServerHost, [ServerHost, Node, Publisher, service_jid(Host), ItemId, Payload]), Reply = [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "publish", nodeAttr(Node), [{xmlelement, "item", itemAttr(ItemId), []}]}]}], case transaction(Host, Node, Action, sync_dirty) of {result, {TNode, {Result, Broadcast, Removed}}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, case get_option(Options, deliver_notifications) of true -> BroadcastPayload = case Broadcast of default -> Payload; broadcast -> Payload; PluginPayload -> PluginPayload end, broadcast_publish_item(Host, Node, NodeId, Type, Options, Removed, ItemId, jlib:jid_tolower(Publisher), BroadcastPayload); false -> ok end, set_cached_item(Host, NodeId, ItemId, Publisher, Payload), case Result of default -> {result, Reply}; _ -> {result, Result} end; {result, {TNode, {default, Removed}}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, broadcast_retract_items(Host, Node, NodeId, Type, Options, Removed), set_cached_item(Host, NodeId, ItemId, Publisher, Payload), {result, Reply}; {result, {TNode, {Result, Removed}}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, broadcast_retract_items(Host, Node, NodeId, Type, Options, Removed), set_cached_item(Host, NodeId, ItemId, Publisher, Payload), {result, Result}; {result, {_, default}} -> {result, Reply}; {result, {_, Result}} -> {result, Result}; {error, ?ERR_ITEM_NOT_FOUND} -> %% handles auto-create feature %% for automatic node creation. we'll take the default node type: %% first listed into the plugins configuration option, or pep Type = select_type(ServerHost, Host, Node), case lists:member("auto-create", features(Type)) of true -> case create_node(Host, ServerHost, Node, Publisher, Type) of {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "create", [{"node", NewNode}], []}]}]} -> publish_item(Host, ServerHost, list_to_binary(NewNode), Publisher, ItemId, Payload); _ -> {error, ?ERR_ITEM_NOT_FOUND} end; false -> {error, ?ERR_ITEM_NOT_FOUND} end; Error -> Error end. %% @spec (Host::host(), JID::jid(), Node::pubsubNode(), ItemId::string()) -> %% {error, Reason::stanzaError()} | %% {result, []} %% @doc

Delete item from a PubSub node.

%%

The permission to delete an item must be verified by the plugin implementation.

%%

There are several reasons why the item retraction request might fail:

%%
    %%
  • The publisher does not have sufficient privileges to delete the requested item.
  • %%
  • The node or item does not exist.
  • %%
  • The request does not specify a node.
  • %%
  • The request does not include an element or the element does not specify an ItemId.
  • %%
  • The node does not support persistent items.
  • %%
  • The service does not support the deletion of items.
  • %%
delete_item(Host, Node, Publisher, ItemId) -> delete_item(Host, Node, Publisher, ItemId, false). delete_item(_, "", _, _, _) -> %% Request does not specify a node {error, extended_error(?ERR_BAD_REQUEST, "node-required")}; delete_item(Host, Node, Publisher, ItemId, ForceNotify) -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> Features = features(Type), PersistentFeature = lists:member("persistent-items", Features), DeleteFeature = lists:member("delete-items", Features), PublishModel = get_option(Options, publish_model), if %%-> iq_pubsub just does that matchs %% %% Request does not specify an item %% {error, extended_error(?ERR_BAD_REQUEST, "item-required")}; not PersistentFeature -> %% Node does not support persistent items {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")}; not DeleteFeature -> %% Service does not support item deletion {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "delete-items")}; true -> node_call(Type, delete_item, [NodeId, Publisher, PublishModel, ItemId]) end end, Reply = [], case transaction(Host, Node, Action, sync_dirty) of {result, {TNode, {Result, broadcast}}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, broadcast_retract_items(Host, Node, NodeId, Type, Options, [ItemId], ForceNotify), case get_cached_item(Host, NodeId) of #pubsub_item{itemid = {ItemId, NodeId}, _ = '_'} -> unset_cached_item(Host, NodeId); _ -> ok end, case Result of default -> {result, Reply}; _ -> {result, Result} end; {result, {_, default}} -> {result, Reply}; {result, {_, Result}} -> {result, Result}; Error -> Error end. %% @spec (Host, JID, Node) -> %% {error, Reason} | {result, []} %% Host = host() %% Node = pubsubNode() %% JID = jid() %% Reason = stanzaError() %% @doc

Delete all items of specified node owned by JID.

%%

There are several reasons why the node purge request might fail:

%%
    %%
  • The node or service does not support node purging.
  • %%
  • The requesting entity does not have sufficient privileges to purge the node.
  • %%
  • The node is not configured to persist items.
  • %%
  • The specified node does not exist.
  • %%
purge_node(Host, Node, Owner) -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> Features = features(Type), PurgeFeature = lists:member("purge-nodes", Features), PersistentFeature = lists:member("persistent-items", Features), PersistentConfig = get_option(Options, persist_items), if not PurgeFeature -> %% Service does not support node purging {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "purge-nodes")}; not PersistentFeature -> %% Node does not support persistent items {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")}; not PersistentConfig -> %% Node is not configured for persistent items {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")}; true -> node_call(Type, purge_node, [NodeId, Owner]) end end, Reply = [], case transaction(Host, Node, Action, sync_dirty) of {result, {TNode, {Result, broadcast}}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, broadcast_purge_node(Host, Node, NodeId, Type, Options), unset_cached_item(Host, NodeId), case Result of default -> {result, Reply}; _ -> {result, Result} end; {result, {_, default}} -> {result, Reply}; {result, {_, Result}} -> {result, Result}; Error -> Error end. %% @doc

Return the items of a given node.

%%

The number of items to return is limited by MaxItems.

%%

The permission are not checked in this function.

%% @todo We probably need to check that the user doing the query has the right %% to read the items. get_items(Host, Node, From, SubId, SMaxItems, ItemIDs, RSM) -> MaxItems = if SMaxItems == "" -> get_max_items_node(Host); true -> case catch list_to_integer(SMaxItems) of {'EXIT', _} -> {error, ?ERR_BAD_REQUEST}; Val -> Val end end, case MaxItems of {error, Error} -> {error, Error}; _ -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> Features = features(Type), RetreiveFeature = lists:member("retrieve-items", Features), PersistentFeature = lists:member("persistent-items", Features), AccessModel = get_option(Options, access_model), AllowedGroups = get_option(Options, roster_groups_allowed, []), Owners = node_owners_call(Type, NodeId), {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups), if not RetreiveFeature -> %% Item Retrieval Not Supported {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-items")}; not PersistentFeature -> %% Persistent Items Not Supported {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")}; true -> node_call(Type, get_items, [NodeId, From, AccessModel, PresenceSubscription, RosterGroup, SubId, RSM]) end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, {Items, RSMOut}}} -> SendItems = case ItemIDs of [] -> Items; _ -> lists:filter(fun(#pubsub_item{itemid = {ItemId, _}}) -> lists:member(ItemId, ItemIDs) end, Items) end, %% Generate the XML response (Item list), limiting the %% number of items sent to MaxItems: {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "items", nodeAttr(Node), itemsEls(lists:sublist(SendItems, MaxItems))} | jlib:rsm_encode(RSMOut)]}]}; Error -> Error end end. get_items(Host, Node) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> node_call(Type, get_items, [NodeId, service_jid(Host)]) end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Items}} -> Items; Error -> Error end. get_item(Host, Node, ItemId) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> node_call(Type, get_item, [NodeId, ItemId]) end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Items}} -> Items; Error -> Error end. get_allowed_items_call(Host, NodeIdx, From, Type, Options, Owners) -> case get_allowed_items_call(Host, NodeIdx, From, Type, Options, Owners, none) of {result, {I, _}} -> {result, I}; Error -> Error end. get_allowed_items_call(Host, NodeIdx, From, Type, Options, Owners, RSM) -> AccessModel = get_option(Options, access_model), AllowedGroups = get_option(Options, roster_groups_allowed, []), {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups), node_call(Type, get_items, [NodeIdx, From, AccessModel, PresenceSubscription, RosterGroup, undefined, RSM]). %% @spec (Host, Node, NodeId, Type, LJID, Number) -> any() %% Host = pubsubHost() %% Node = pubsubNode() %% NodeId = pubsubNodeId() %% Type = pubsubNodeType() %% LJID = {U, S, []} %% Number = last | integer() %% @doc

Resend the items of a node to the user.

%% @todo use cache-last-item feature send_items(Host, Node, NodeId, Type, LJID, last) -> Stanza = case get_cached_item(Host, NodeId) of undefined -> % special ODBC optimization, works only with node_hometree_odbc, node_flat_odbc and node_pep_odbc case node_action(Host, Type, get_last_items, [NodeId, LJID, 1]) of {result, [LastItem]} -> {ModifNow, ModifUSR} = LastItem#pubsub_item.modification, event_stanza_with_delay( [{xmlelement, "items", nodeAttr(Node), itemsEls([LastItem])}], ModifNow, ModifUSR); _ -> event_stanza( [{xmlelement, "items", nodeAttr(Node), itemsEls([])}]) end; LastItem -> {ModifNow, ModifUSR} = LastItem#pubsub_item.modification, event_stanza_with_delay( [{xmlelement, "items", nodeAttr(Node), itemsEls([LastItem])}], ModifNow, ModifUSR) end, ejabberd_router:route(service_jid(Host), jlib:make_jid(LJID), Stanza); send_items(Host, Node, NodeId, Type, LJID, Number) -> ToSend = case node_action(Host, Type, get_items, [NodeId, LJID]) of {result, []} -> []; {result, Items} -> case Number of N when N > 0 -> lists:sublist(Items, N); _ -> Items end; _ -> [] end, Stanza = case ToSend of [LastItem] -> {ModifNow, ModifUSR} = LastItem#pubsub_item.modification, event_stanza_with_delay( [{xmlelement, "items", nodeAttr(Node), itemsEls(ToSend)}], ModifNow, ModifUSR); _ -> event_stanza( [{xmlelement, "items", nodeAttr(Node), itemsEls(ToSend)}]) end, ejabberd_router:route(service_jid(Host), jlib:make_jid(LJID), Stanza). %% @spec (Host, JID, Plugins) -> {error, Reason} | {result, Response} %% Host = host() %% JID = jid() %% Plugins = [Plugin::string()] %% Reason = stanzaError() %% Response = [pubsubIQResponse()] %% @doc

Return the list of affiliations as an XMPP response.

get_affiliations(Host, <<>>, JID, Plugins) when is_list(Plugins) -> Result = lists:foldl( fun(Type, {Status, Acc}) -> Features = features(Type), RetrieveFeature = lists:member("retrieve-affiliations", Features), if not RetrieveFeature -> %% Service does not support retreive affiliatons {{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-affiliations")}, Acc}; true -> {result, Affiliations} = node_action(Host, Type, get_entity_affiliations, [Host, JID]), {Status, [Affiliations|Acc]} end end, {ok, []}, Plugins), case Result of {ok, Affiliations} -> Entities = lists:flatmap( fun({_, none}) -> []; ({#pubsub_node{nodeid = {_, Node}}, Affiliation}) -> [{xmlelement, "affiliation", [{"affiliation", affiliation_to_string(Affiliation)}|nodeAttr(Node)], []}] end, lists:usort(lists:flatten(Affiliations))), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "affiliations", [], Entities}]}]}; {Error, _} -> Error end; get_affiliations(Host, NodeId, JID, Plugins) when is_list(Plugins) -> Result = lists:foldl( fun(Type, {Status, Acc}) -> Features = features(Type), RetrieveFeature = lists:member("retrieve-affiliations", Features), if not RetrieveFeature -> %% Service does not support retreive affiliatons {{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-affiliations")}, Acc}; true -> {result, Affiliations} = node_action(Host, Type, get_entity_affiliations, [Host, JID]), {Status, [Affiliations|Acc]} end end, {ok, []}, Plugins), case Result of {ok, Affiliations} -> Entities = lists:flatmap( fun({_, none}) -> []; ({#pubsub_node{nodeid = {_, Node}}, Affiliation}) when NodeId == Node -> [{xmlelement, "affiliation", [{"affiliation", affiliation_to_string(Affiliation)}|nodeAttr(Node)], []}]; (_) -> [] end, lists:usort(lists:flatten(Affiliations))), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "affiliations", [], Entities}]}]}; {Error, _} -> Error end. get_affiliations(Host, Node, JID) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> Features = features(Type), RetrieveFeature = lists:member("modify-affiliations", Features), {result, Affiliation} = node_call(Type, get_affiliation, [NodeId, JID]), if not RetrieveFeature -> %% Service does not support modify affiliations {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "modify-affiliations")}; Affiliation /= owner -> %% Entity is not an owner {error, ?ERR_FORBIDDEN}; true -> node_call(Type, get_node_affiliations, [NodeId]) end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, []}} -> {error, ?ERR_ITEM_NOT_FOUND}; {result, {_, Affiliations}} -> Entities = lists:flatmap( fun({_, none}) -> []; ({AJID, Affiliation}) -> [{xmlelement, "affiliation", [{"jid", jlib:jid_to_string(AJID)}, {"affiliation", affiliation_to_string(Affiliation)}], []}] end, Affiliations), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}], [{xmlelement, "affiliations", nodeAttr(Node), Entities}]}]}; Error -> Error end. set_affiliations(Host, Node, From, EntitiesEls) -> Owner = jlib:jid_tolower(jlib:jid_remove_resource(From)), Entities = lists:foldl( fun(El, Acc) -> case Acc of error -> error; _ -> case El of {xmlelement, "affiliation", Attrs, _} -> JID = jlib:string_to_jid( xml:get_attr_s("jid", Attrs)), Affiliation = string_to_affiliation( xml:get_attr_s("affiliation", Attrs)), if (JID == error) or (Affiliation == false) -> error; true -> [{jlib:jid_tolower(JID), Affiliation} | Acc] end end end end, [], EntitiesEls), case Entities of error -> {error, ?ERR_BAD_REQUEST}; _ -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> Owners = node_owners_call(Type, NodeId), case lists:member(Owner, Owners) of true -> OwnerJID = jlib:make_jid(Owner), FilteredEntities = case Owners of [Owner] -> [E || E <- Entities, element(1, E) =/= OwnerJID]; _ -> Entities end, lists:foreach( fun({JID, Affiliation}) -> node_call(Type, set_affiliation, [NodeId, JID, Affiliation]) end, FilteredEntities), {result, []}; _ -> {error, ?ERR_FORBIDDEN} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; Other -> Other end end. get_options(Host, Node, JID, SubID, Lang) -> Action = fun(#pubsub_node{type = Type, id = NodeID}) -> case lists:member("subscription-options", features(Type)) of true -> get_options_helper(JID, Lang, Node, NodeID, SubID, Type); false -> {error, extended_error( ?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscription-options")} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_Node, XForm}} -> {result, [XForm]}; Error -> Error end. get_options_helper(JID, Lang, Node, NodeID, SubID, Type) -> Subscriber = case jlib:string_to_jid(JID) of error -> {"", "", ""}; J -> jlib:jid_tolower(J) end, {result, Subs} = node_call(Type, get_subscriptions, [NodeID, Subscriber]), SubIDs = lists:foldl(fun({subscribed, SID}, Acc) -> [SID | Acc]; (_, Acc) -> Acc end, [], Subs), case {SubID, SubIDs} of {_, []} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "not-subscribed")}; {[], [SID]} -> read_sub(Subscriber, Node, NodeID, SID, Lang); {[], _} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "subid-required")}; {_, _} -> read_sub(Subscriber, Node, NodeID, SubID, Lang) end. read_sub(Subscriber, Node, NodeID, SubID, Lang) -> case pubsub_subscription_odbc:get_subscription(Subscriber, NodeID, SubID) of {error, notfound} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; {result, #pubsub_subscription{options = Options}} -> {result, XdataEl} = pubsub_subscription_odbc:get_options_xform(Lang, Options), OptionsEl = {xmlelement, "options", [{"jid", jlib:jid_to_string(Subscriber)}, {"subid", SubID}|nodeAttr(Node)], [XdataEl]}, PubsubEl = {xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [OptionsEl]}, {result, PubsubEl} end. set_options(Host, Node, JID, SubID, Configuration) -> Action = fun(#pubsub_node{type = Type, id = NodeID}) -> case lists:member("subscription-options", features(Type)) of true -> set_options_helper(Configuration, JID, NodeID, SubID, Type); false -> {error, extended_error( ?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscription-options")} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_Node, Result}} -> {result, Result}; Error -> Error end. set_options_helper(Configuration, JID, NodeID, SubID, Type) -> SubOpts = case pubsub_subscription_odbc:parse_options_xform(Configuration) of {result, GoodSubOpts} -> GoodSubOpts; _ -> invalid end, Subscriber = case jlib:string_to_jid(JID) of error -> {"", "", ""}; J -> jlib:jid_tolower(J) end, {result, Subs} = node_call(Type, get_subscriptions, [NodeID, Subscriber]), SubIDs = lists:foldl(fun({subscribed, SID}, Acc) -> [SID | Acc]; (_, Acc) -> Acc end, [], Subs), case {SubID, SubIDs} of {_, []} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "not-subscribed")}; {[], [SID]} -> write_sub(Subscriber, NodeID, SID, SubOpts); {[], _} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "subid-required")}; {_, _} -> write_sub(Subscriber, NodeID, SubID, SubOpts) end. write_sub(_Subscriber, _NodeID, _SubID, invalid) -> {error, extended_error(?ERR_BAD_REQUEST, "invalid-options")}; write_sub(Subscriber, NodeID, SubID, Options) -> case pubsub_subscription_odbc:set_subscription(Subscriber, NodeID, SubID, Options) of {error, notfound} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; {result, _} -> {result, []} end. %% @spec (Host, Node, JID, Plugins) -> {error, Reason} | {result, Response} %% Host = host() %% Node = pubsubNode() %% JID = jid() %% Plugins = [Plugin::string()] %% Reason = stanzaError() %% Response = [pubsubIQResponse()] %% @doc

Return the list of subscriptions as an XMPP response.

get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) -> Result = lists:foldl( fun(Type, {Status, Acc}) -> Features = features(Type), RetrieveFeature = lists:member("retrieve-subscriptions", Features), if not RetrieveFeature -> %% Service does not support retreive subscriptions {{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-subscriptions")}, Acc}; true -> Subscriber = jlib:jid_remove_resource(JID), {result, Subscriptions} = node_action(Host, Type, get_entity_subscriptions, [Host, Subscriber]), {Status, [Subscriptions|Acc]} end end, {ok, []}, Plugins), case Result of {ok, Subscriptions} -> Entities = lists:flatmap( fun({_, none}) -> []; ({#pubsub_node{nodeid = {_, SubsNode}}, Subscription}) -> case Node of <<>> -> [{xmlelement, "subscription", [{"subscription", subscription_to_string(Subscription)}|nodeAttr(SubsNode)], []}]; SubsNode -> [{xmlelement, "subscription", [{"subscription", subscription_to_string(Subscription)}], []}]; _ -> [] end; ({_, none, _}) -> []; ({#pubsub_node{nodeid = {_, SubsNode}}, Subscription, SubID, SubJID}) -> case Node of <<>> -> [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(SubJID)}, {"subid", SubID}, {"subscription", subscription_to_string(Subscription)}|nodeAttr(SubsNode)], []}]; SubsNode -> [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(SubJID)}, {"subid", SubID}, {"subscription", subscription_to_string(Subscription)}], []}]; _ -> [] end; ({#pubsub_node{nodeid = {_, SubsNode}}, Subscription, SubJID}) -> case Node of <<>> -> [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(SubJID)}, {"subscription", subscription_to_string(Subscription)}|nodeAttr(SubsNode)], []}]; SubsNode -> [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(SubJID)}, {"subscription", subscription_to_string(Subscription)}], []}]; _ -> [] end end, lists:usort(lists:flatten(Subscriptions))), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "subscriptions", [], Entities}]}]}; {Error, _} -> Error end. get_subscriptions(Host, Node, JID) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> Features = features(Type), RetrieveFeature = lists:member("manage-subscriptions", Features), {result, Affiliation} = node_call(Type, get_affiliation, [NodeId, JID]), if not RetrieveFeature -> %% Service does not support manage subscriptions {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "manage-subscriptions")}; Affiliation /= owner -> %% Entity is not an owner {error, ?ERR_FORBIDDEN}; true -> node_call(Type, get_node_subscriptions, [NodeId]) end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Subscriptions}} -> Entities = lists:flatmap( fun({_, none}) -> []; ({_, pending, _}) -> []; ({AJID, Subscription}) -> [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(AJID)}, {"subscription", subscription_to_string(Subscription)}], []}]; ({AJID, Subscription, SubId}) -> [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(AJID)}, {"subscription", subscription_to_string(Subscription)}, {"subid", SubId}], []}] end, Subscriptions), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}], [{xmlelement, "subscriptions", nodeAttr(Node), Entities}]}]}; Error -> Error end. set_subscriptions(Host, Node, From, EntitiesEls) -> Owner = jlib:jid_tolower(jlib:jid_remove_resource(From)), Entities = lists:foldl( fun(El, Acc) -> case Acc of error -> error; _ -> case El of {xmlelement, "subscription", Attrs, _} -> JID = jlib:string_to_jid( xml:get_attr_s("jid", Attrs)), Subscription = string_to_subscription( xml:get_attr_s("subscription", Attrs)), SubId = xml:get_attr_s("subid", Attrs), if (JID == error) or (Subscription == false) -> error; true -> [{jlib:jid_tolower(JID), Subscription, SubId} | Acc] end end end end, [], EntitiesEls), case Entities of error -> {error, ?ERR_BAD_REQUEST}; _ -> Notify = fun(JID, Sub, _SubId) -> Stanza = {xmlelement, "message", [], [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(JID)}, %{"subid", SubId}, {"subscription", subscription_to_string(Sub)} | nodeAttr(Node)], []}]}]}, ejabberd_router:route(service_jid(Host), jlib:make_jid(JID), Stanza) end, Action = fun(#pubsub_node{type = Type, id = NodeId}) -> case lists:member(Owner, node_owners_call(Type, NodeId)) of true -> Result = lists:foldl(fun({JID, Subscription, SubId}, Acc) -> case node_call(Type, set_subscriptions, [NodeId, JID, Subscription, SubId]) of {error, Err} -> [{error, Err} | Acc]; _ -> Notify(JID, Subscription, SubId), Acc end end, [], Entities), case Result of [] -> {result, []}; _ -> {error, ?ERR_NOT_ACCEPTABLE} end; _ -> {error, ?ERR_FORBIDDEN} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; Other -> Other end end. get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups) -> if (AccessModel == presence) or (AccessModel == roster) -> case Host of {User, Server, _} -> get_roster_info(User, Server, From, AllowedGroups); _ -> [{OUser, OServer, _}|_] = Owners, get_roster_info(OUser, OServer, From, AllowedGroups) end; true -> {true, true} end. %% @spec (OwnerUser, OwnerServer, {SubscriberUser, SubscriberServer, SubscriberResource}, AllowedGroups) %% -> {PresenceSubscription, RosterGroup} get_roster_info(_, _, {"", "", _}, _) -> {false, false}; get_roster_info(OwnerUser, OwnerServer, {SubscriberUser, SubscriberServer, _}, AllowedGroups) -> {Subscription, Groups} = ejabberd_hooks:run_fold( roster_get_jid_info, OwnerServer, {none, []}, [OwnerUser, OwnerServer, {SubscriberUser, SubscriberServer, ""}]), PresenceSubscription = (Subscription == both) orelse (Subscription == from) orelse ({OwnerUser, OwnerServer} == {SubscriberUser, SubscriberServer}), RosterGroup = lists:any(fun(Group) -> lists:member(Group, AllowedGroups) end, Groups), {PresenceSubscription, RosterGroup}; get_roster_info(OwnerUser, OwnerServer, JID, AllowedGroups) -> get_roster_info(OwnerUser, OwnerServer, jlib:jid_tolower(JID), AllowedGroups). %% @spec (AffiliationStr) -> Affiliation %% AffiliationStr = string() %% Affiliation = atom() %% @doc

Convert an affiliation type from string to atom.

string_to_affiliation("owner") -> owner; string_to_affiliation("publisher") -> publisher; string_to_affiliation("member") -> member; string_to_affiliation("outcast") -> outcast; string_to_affiliation("none") -> none; string_to_affiliation(_) -> false. %% @spec (SubscriptionStr) -> Subscription %% SubscriptionStr = string() %% Subscription = atom() %% @doc

Convert a subscription type from string to atom.

string_to_subscription("subscribed") -> subscribed; string_to_subscription("pending") -> pending; string_to_subscription("unconfigured") -> unconfigured; string_to_subscription("none") -> none; string_to_subscription(_) -> false. %% @spec (Affiliation) -> AffiliationStr %% Affiliation = atom() %% AffiliationStr = string() %% @doc

Convert an affiliation type from atom to string.

affiliation_to_string(owner) -> "owner"; affiliation_to_string(publisher) -> "publisher"; affiliation_to_string(member) -> "member"; affiliation_to_string(outcast) -> "outcast"; affiliation_to_string(_) -> "none". %% @spec (Subscription) -> SubscriptionStr %% Subscription = atom() %% SubscriptionStr = string() %% @doc

Convert a subscription type from atom to string.

subscription_to_string(subscribed) -> "subscribed"; subscription_to_string(pending) -> "pending"; subscription_to_string(unconfigured) -> "unconfigured"; subscription_to_string(_) -> "none". %% @spec (Node) -> NodeStr %% Node = pubsubNode() %% NodeStr = string() %% @doc

Convert a node type from pubsubNode to string.

node_to_string(Node) -> binary_to_list(Node). string_to_node(SNode) -> list_to_binary(SNode). %% @spec (Host) -> jid() %% Host = host() %% @doc

Generate pubsub service JID.

service_jid(Host) -> case Host of {U,S,_} -> {jid, U, S, "", U, S, ""}; _ -> {jid, "", Host, "", "", Host, ""} end. %% @spec (LJID, NotifyType, Depth, NodeOptions, SubOptions) -> boolean() %% LJID = jid() %% NotifyType = items | nodes %% Depth = integer() %% NodeOptions = [{atom(), term()}] %% SubOptions = [{atom(), term()}] %% @doc

Check if a notification must be delivered or not based on %% node and subscription options.

is_to_deliver(LJID, NotifyType, Depth, NodeOptions, SubOptions) -> sub_to_deliver(LJID, NotifyType, Depth, SubOptions) andalso node_to_deliver(LJID, NodeOptions). sub_to_deliver(_LJID, NotifyType, Depth, SubOptions) -> lists:all(fun (Option) -> sub_option_can_deliver(NotifyType, Depth, Option) end, SubOptions). sub_option_can_deliver(items, _, {subscription_type, nodes}) -> false; sub_option_can_deliver(nodes, _, {subscription_type, items}) -> false; sub_option_can_deliver(_, _, {subscription_depth, all}) -> true; sub_option_can_deliver(_, Depth, {subscription_depth, D}) -> Depth =< D; sub_option_can_deliver(_, _, {deliver, false}) -> false; sub_option_can_deliver(_, _, {expire, When}) -> now() < When; sub_option_can_deliver(_, _, _) -> true. node_to_deliver(LJID, NodeOptions) -> PresenceDelivery = get_option(NodeOptions, presence_based_delivery), presence_can_deliver(LJID, PresenceDelivery). presence_can_deliver(_, false) -> true; presence_can_deliver({User, Server, Resource}, true) -> case mnesia:dirty_match_object({session, '_', '_', {User, Server}, '_', '_'}) of [] -> false; Ss -> lists:foldl(fun(_, true) -> true; ({session, _, _ , _, undefined, _}, _Acc) -> false; ({session, _, {_, _, R}, _, _Priority, _}, _Acc) -> case Resource of [] -> true; R -> true; _ -> false end end, false, Ss) end. state_can_deliver({U, S, R}, []) -> [{U, S, R}]; state_can_deliver({U, S, R}, SubOptions) -> %% Check SubOptions for 'show_values' case lists:keysearch('show_values', 1, SubOptions) of %% If not in suboptions, item can be delivered, case doesn't apply false -> [{U, S, R}]; %% If in a suboptions ... {_, {_, ShowValues}} -> %% Get subscriber resources Resources = case R of %% If the subscriber JID is a bare one, get all its resources [] -> user_resources(U, S); %% If the subscriber JID is a full one, use its resource R -> [R] end, %% For each resource, test if the item is allowed to be delivered %% based on resource state lists:foldl( fun(Resource, Acc) -> get_resource_state({U, S, Resource}, ShowValues, Acc) end, [], Resources) end. get_resource_state({U, S, R}, ShowValues, JIDs) -> %% Get user session PID case ejabberd_sm:get_session_pid(U, S, R) of %% If no PID, item can be delivered none -> lists:append([{U, S, R}], JIDs); %% If PID ... Pid -> %% Get user resource state %% TODO : add a catch clause Show = case ejabberd_c2s:get_presence(Pid) of {_, _, "available", _} -> "online"; {_, _, State, _} -> State end, %% Is current resource state listed in 'show-values' suboption ? case lists:member(Show, ShowValues) of %andalso Show =/= "online" of %% If yes, item can be delivered true -> lists:append([{U, S, R}], JIDs); %% If no, item can't be delivered false -> JIDs end end. %% @spec (Payload) -> int() %% Payload = term() %% @doc

Count occurence of XML elements in payload.

payload_xmlelements(Payload) -> payload_xmlelements(Payload, 0). payload_xmlelements([], Count) -> Count; payload_xmlelements([{xmlelement, _, _, _}|Tail], Count) -> payload_xmlelements(Tail, Count+1); payload_xmlelements([_|Tail], Count) -> payload_xmlelements(Tail, Count). %% @spec (Els) -> stanza() %% Els = [xmlelement()] %% @doc

Build pubsub event stanza

event_stanza(Els) -> event_stanza_withmoreels(Els, []). event_stanza_with_delay(Els, ModifNow, ModifUSR) -> DateTime = calendar:now_to_datetime(ModifNow), MoreEls = [jlib:timestamp_to_xml(DateTime, utc, ModifUSR, "")], event_stanza_withmoreels(Els, MoreEls). event_stanza_withmoreels(Els, MoreEls) -> {xmlelement, "message", [], [{xmlelement, "event", [{"xmlns", ?NS_PUBSUB_EVENT}], Els} | MoreEls]}. %%%%%% broadcast functions broadcast_publish_item(Host, Node, NodeId, Type, NodeOptions, Removed, ItemId, From, Payload) -> case get_collection_subscriptions(Host, Node) of SubsByDepth when is_list(SubsByDepth) -> Content = case get_option(NodeOptions, deliver_payloads) of true -> Payload; false -> [] end, Stanza = event_stanza( [{xmlelement, "items", nodeAttr(Node), [{xmlelement, "item", itemAttr(ItemId), Content}]}]), broadcast_stanza(Host, From, Node, NodeId, Type, NodeOptions, SubsByDepth, items, Stanza, true), case Removed of [] -> ok; _ -> case get_option(NodeOptions, notify_retract) of true -> RetractStanza = event_stanza( [{xmlelement, "items", nodeAttr(Node), [{xmlelement, "retract", itemAttr(RId), []} || RId <- Removed]}]), broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, items, RetractStanza, true); _ -> ok end end, {result, true}; _ -> {result, false} end. broadcast_retract_items(Host, Node, NodeId, Type, NodeOptions, ItemIds) -> broadcast_retract_items(Host, Node, NodeId, Type, NodeOptions, ItemIds, false). broadcast_retract_items(_Host, _Node, _NodeId, _Type, _NodeOptions, [], _ForceNotify) -> {result, false}; broadcast_retract_items(Host, Node, NodeId, Type, NodeOptions, ItemIds, ForceNotify) -> case (get_option(NodeOptions, notify_retract) or ForceNotify) of true -> case get_collection_subscriptions(Host, Node) of SubsByDepth when is_list(SubsByDepth) -> Stanza = event_stanza( [{xmlelement, "items", nodeAttr(Node), [{xmlelement, "retract", itemAttr(ItemId), []} || ItemId <- ItemIds]}]), broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, items, Stanza, true), {result, true}; _ -> {result, false} end; _ -> {result, false} end. broadcast_purge_node(Host, Node, NodeId, Type, NodeOptions) -> case get_option(NodeOptions, notify_retract) of true -> case get_collection_subscriptions(Host, Node) of SubsByDepth when is_list(SubsByDepth) -> Stanza = event_stanza( [{xmlelement, "purge", nodeAttr(Node), []}]), broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, nodes, Stanza, false), {result, true}; _ -> {result, false} end; _ -> {result, false} end. broadcast_removed_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth) -> case get_option(NodeOptions, notify_delete) of true -> case SubsByDepth of [] -> {result, false}; _ -> Stanza = event_stanza( [{xmlelement, "delete", nodeAttr(Node), []}]), broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, nodes, Stanza, false), {result, true} end; _ -> {result, false} end. broadcast_created_node(_, _, _, _, _, []) -> {result, false}; broadcast_created_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth) -> Stanza = event_stanza([{xmlelement, "create", nodeAttr(Node), []}]), broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, nodes, Stanza, true), {result, true}. broadcast_config_notification(Host, Node, NodeId, Type, NodeOptions, Lang) -> case get_option(NodeOptions, notify_config) of true -> case get_collection_subscriptions(Host, Node) of SubsByDepth when is_list(SubsByDepth) -> Content = case get_option(NodeOptions, deliver_payloads) of true -> [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}], get_configure_xfields(Type, NodeOptions, Lang, [])}]; false -> [] end, Stanza = event_stanza( [{xmlelement, "configuration", nodeAttr(Node), Content}]), broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, nodes, Stanza, false), {result, true}; _ -> {result, false} end; _ -> {result, false} end. get_collection_subscriptions(Host, Node) -> Action = fun() -> {result, lists:map(fun({Depth, Nodes}) -> {Depth, [{N, get_node_subs(N)} || N <- Nodes]} end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))} end, case transaction(Host, Action, sync_dirty) of {result, CollSubs} -> CollSubs; _ -> [] end. get_node_subs(#pubsub_node{type = Type, id = NodeID}) -> case node_call(Type, get_node_subscriptions, [NodeID]) of {result, Subs} -> get_options_for_subs(NodeID, Subs); Other -> Other end. get_options_for_subs(NodeID, Subs) -> lists:foldl(fun({JID, subscribed, SubID}, Acc) -> case pubsub_subscription_odbc:get_subscription(JID, NodeID, SubID) of {error, notfound} -> [{JID, SubID, []} | Acc]; {result, #pubsub_subscription{options = Options}} -> [{JID, SubID, Options} | Acc]; _ -> Acc end; (_, Acc) -> Acc end, [], Subs). broadcast_stanza(Host, _Node, _NodeId, _Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM) -> NotificationType = get_option(NodeOptions, notification_type, headline), BroadcastAll = get_option(NodeOptions, broadcast_all_resources), %% XXX this is not standard, but usefull From = service_jid(Host), Stanza = case NotificationType of normal -> BaseStanza; MsgType -> add_message_type(BaseStanza, atom_to_list(MsgType)) end, %% Handles explicit subscriptions SubIDsByJID = subscribed_nodes_by_jid(NotifyType, SubsByDepth), lists:foreach(fun ({LJID, NodeName, SubIDs}) -> LJIDs = case BroadcastAll of true -> {U, S, _} = LJID, [{U, S, R} || R <- user_resources(U, S)]; false -> [LJID] end, %% Determine if the stanza should have SHIM ('SubID' and 'name') headers StanzaToSend = case {SHIM, SubIDs} of {false, _} -> Stanza; %% If there's only one SubID, don't add it {true, [_]} -> add_shim_headers(Stanza, collection_shim(NodeName)); {true, SubIDs} -> add_shim_headers(Stanza, lists:append(collection_shim(NodeName), subid_shim(SubIDs))) end, lists:foreach(fun(To) -> ejabberd_router:route(From, jlib:make_jid(To), StanzaToSend) end, LJIDs) end, SubIDsByJID). broadcast_stanza({LUser, LServer, LResource}, Publisher, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM) -> broadcast_stanza({LUser, LServer, LResource}, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM), %% Handles implicit presence subscriptions SenderResource = case LResource of [] -> case user_resources(LUser, LServer) of [Resource|_] -> Resource; _ -> "" end; _ -> LResource end, case ejabberd_sm:get_session_pid(LUser, LServer, SenderResource) of C2SPid when is_pid(C2SPid) -> Stanza = case get_option(NodeOptions, notification_type, headline) of normal -> BaseStanza; MsgType -> add_message_type(BaseStanza, atom_to_list(MsgType)) end, %% set the from address on the notification to the bare JID of the account owner %% Also, add "replyto" if entity has presence subscription to the account owner %% See XEP-0163 1.1 section 4.3.1 ejabberd_c2s:broadcast(C2SPid, {pep_message, binary_to_list(Node)++"+notify"}, _Sender = jlib:make_jid(LUser, LServer, ""), _StanzaToSend = add_extended_headers(Stanza, _ReplyTo = extended_headers([jlib:jid_to_string(Publisher)]))); _ -> ?DEBUG("~p@~p has no session; can't deliver ~p to contacts", [LUser, LServer, BaseStanza]) end; broadcast_stanza(Host, _Publisher, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM) -> broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM). subscribed_nodes_by_jid(NotifyType, SubsByDepth) -> NodesToDeliver = fun(Depth, Node, Subs, Acc) -> NodeName = case Node#pubsub_node.nodeid of {_, N} -> N; Other -> Other end, NodeOptions = Node#pubsub_node.options, lists:foldl(fun({LJID, SubID, SubOptions}, {JIDs, Recipients}) -> case is_to_deliver(LJID, NotifyType, Depth, NodeOptions, SubOptions) of true -> %% If is to deliver : case state_can_deliver(LJID, SubOptions) of [] -> {JIDs, Recipients}; JIDsToDeliver -> lists:foldl( fun(JIDToDeliver, {JIDsAcc, RecipientsAcc}) -> case lists:member(JIDToDeliver, JIDs) of %% check if the JIDs co-accumulator contains the Subscription Jid, false -> %% - if not, %% - add the Jid to JIDs list co-accumulator ; %% - create a tuple of the Jid, NodeId, and SubID (as list), %% and add the tuple to the Recipients list co-accumulator {[JIDToDeliver | JIDsAcc], [{JIDToDeliver, NodeName, [SubID]} | RecipientsAcc]}; true -> %% - if the JIDs co-accumulator contains the Jid %% get the tuple containing the Jid from the Recipient list co-accumulator {_, {JIDToDeliver, NodeName1, SubIDs}} = lists:keysearch(JIDToDeliver, 1, RecipientsAcc), %% delete the tuple from the Recipients list % v1 : Recipients1 = lists:keydelete(LJID, 1, Recipients), % v2 : Recipients1 = lists:keyreplace(LJID, 1, Recipients, {LJID, NodeId1, [SubID | SubIDs]}), %% add the SubID to the SubIDs list in the tuple, %% and add the tuple back to the Recipients list co-accumulator % v1.1 : {JIDs, lists:append(Recipients1, [{LJID, NodeId1, lists:append(SubIDs, [SubID])}])} % v1.2 : {JIDs, [{LJID, NodeId1, [SubID | SubIDs]} | Recipients1]} % v2: {JIDs, Recipients1} {JIDsAcc, lists:keyreplace(JIDToDeliver, 1, RecipientsAcc, {JIDToDeliver, NodeName1, [SubID | SubIDs]})} end end, {JIDs, Recipients}, JIDsToDeliver) end; false -> {JIDs, Recipients} end end, Acc, Subs) end, DepthsToDeliver = fun({Depth, SubsByNode}, Acc1) -> lists:foldl(fun({Node, Subs}, Acc2) -> NodesToDeliver(Depth, Node, Subs, Acc2) end, Acc1, SubsByNode) end, {_, JIDSubs} = lists:foldl(DepthsToDeliver, {[], []}, SubsByDepth), JIDSubs. user_resources(User, Server) -> ejabberd_sm:get_user_resources(User, Server). %%%%%%% Configuration handling %%

There are several reasons why the default node configuration options request might fail:

%%
    %%
  • The service does not support node configuration.
  • %%
  • The service does not support retrieval of default node configuration.
  • %%
get_configure(Host, ServerHost, Node, From, Lang) -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> case node_call(Type, get_affiliation, [NodeId, From]) of {result, owner} -> Groups = ejabberd_hooks:run_fold(roster_groups, ServerHost, [], [ServerHost]), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}], [{xmlelement, "configure", nodeAttr(Node), [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], get_configure_xfields(Type, Options, Lang, Groups) }]}]}]}; _ -> {error, ?ERR_FORBIDDEN} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; Other -> Other end. get_default(Host, Node, _From, Lang) -> Type = select_type(Host, Host, Node), Options = node_options(Type), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}], [{xmlelement, "default", [], [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], get_configure_xfields(Type, Options, Lang, []) }]}]}]}. %% Get node option %% The result depend of the node type plugin system. get_option([], _) -> false; get_option(Options, Var) -> get_option(Options, Var, false). get_option(Options, Var, Def) -> case lists:keysearch(Var, 1, Options) of {value, {_Val, Ret}} -> Ret; _ -> Def end. %% Get default options from the module plugin. node_options(Type) -> Module = list_to_atom(?PLUGIN_PREFIX ++ Type), case catch Module:options() of {'EXIT',{undef,_}} -> DefaultModule = list_to_atom(?PLUGIN_PREFIX++?STDNODE), DefaultModule:options(); Result -> Result end. %% @spec (Host, Type, NodeId) -> [ljid()] %% NodeId = pubsubNodeId() %% @doc

Return list of node owners.

node_owners(Host, Type, NodeId) -> case node_action(Host, Type, get_node_affiliations, [NodeId]) of {result, Affiliations} -> lists:foldl( fun({LJID, owner}, Acc) -> [LJID|Acc]; (_, Acc) -> Acc end, [], Affiliations); _ -> [] end. node_owners_call(Type, NodeId) -> case node_call(Type, get_node_affiliations, [NodeId]) of {result, Affiliations} -> lists:foldl( fun({LJID, owner}, Acc) -> [LJID|Acc]; (_, Acc) -> Acc end, [], Affiliations); _ -> [] end. %% @spec (Host, Options) -> MaxItems %% Host = host() %% Options = [Option] %% Option = {Key::atom(), Value::term()} %% MaxItems = integer() | unlimited %% @doc

Return the maximum number of items for a given node.

%%

Unlimited means that there is no limit in the number of items that can %% be stored.

%% @todo In practice, the current data structure means that we cannot manage %% millions of items on a given node. This should be addressed in a new %% version. max_items(Host, Options) -> case get_option(Options, persist_items) of true -> case get_option(Options, max_items) of false -> unlimited; Result when (Result < 0) -> 0; Result -> Result end; false -> case get_option(Options, send_last_published_item) of never -> 0; _ -> case is_last_item_cache_enabled(Host) of true -> 0; false -> 1 end end end. -define(BOOL_CONFIG_FIELD(Label, Var), ?BOOLXFIELD(Label, "pubsub#" ++ atom_to_list(Var), get_option(Options, Var))). -define(STRING_CONFIG_FIELD(Label, Var), ?STRINGXFIELD(Label, "pubsub#" ++ atom_to_list(Var), get_option(Options, Var, ""))). -define(INTEGER_CONFIG_FIELD(Label, Var), ?STRINGXFIELD(Label, "pubsub#" ++ atom_to_list(Var), integer_to_list(get_option(Options, Var)))). -define(JLIST_CONFIG_FIELD(Label, Var, Opts), ?LISTXFIELD(Label, "pubsub#" ++ atom_to_list(Var), jlib:jid_to_string(get_option(Options, Var)), [jlib:jid_to_string(O) || O <- Opts])). -define(ALIST_CONFIG_FIELD(Label, Var, Opts), ?LISTXFIELD(Label, "pubsub#" ++ atom_to_list(Var), atom_to_list(get_option(Options, Var)), [atom_to_list(O) || O <- Opts])). -define(LISTM_CONFIG_FIELD(Label, Var, Opts), ?LISTMXFIELD(Label, "pubsub#" ++ atom_to_list(Var), get_option(Options, Var), Opts)). -define(NLIST_CONFIG_FIELD(Label, Var), ?STRINGMXFIELD(Label, "pubsub#" ++ atom_to_list(Var), [node_to_string(N) || N <- get_option(Options, Var, [])])). get_configure_xfields(_Type, Options, Lang, Groups) -> [?XFIELD("hidden", "", "FORM_TYPE", ?NS_PUBSUB_NODE_CONFIG), ?BOOL_CONFIG_FIELD("Deliver payloads with event notifications", deliver_payloads), ?BOOL_CONFIG_FIELD("Deliver event notifications", deliver_notifications), ?BOOL_CONFIG_FIELD("Notify subscribers when the node configuration changes", notify_config), ?BOOL_CONFIG_FIELD("Notify subscribers when the node is deleted", notify_delete), ?BOOL_CONFIG_FIELD("Notify subscribers when items are removed from the node", notify_retract), ?BOOL_CONFIG_FIELD("Persist items to storage", persist_items), ?STRING_CONFIG_FIELD("A friendly name for the node", title), ?INTEGER_CONFIG_FIELD("Max # of items to persist", max_items), ?BOOL_CONFIG_FIELD("Whether to allow subscriptions", subscribe), ?ALIST_CONFIG_FIELD("Specify the access model", access_model, [open, authorize, presence, roster, whitelist]), %% XXX: change to list-multi, include current roster groups as options ?LISTM_CONFIG_FIELD("Roster groups allowed to subscribe", roster_groups_allowed, Groups), ?ALIST_CONFIG_FIELD("Specify the publisher model", publish_model, [publishers, subscribers, open]), ?BOOL_CONFIG_FIELD("Purge all items when the relevant publisher goes offline", purge_offline), ?ALIST_CONFIG_FIELD("Specify the event message type", notification_type, [headline, normal]), ?INTEGER_CONFIG_FIELD("Max payload size in bytes", max_payload_size), ?ALIST_CONFIG_FIELD("When to send the last published item", send_last_published_item, [never, on_sub, on_sub_and_presence]), ?BOOL_CONFIG_FIELD("Only deliver notifications to available users", presence_based_delivery), ?NLIST_CONFIG_FIELD("The collections with which a node is affiliated", collection) ]. %%

There are several reasons why the node configuration request might fail:

%%
    %%
  • The service does not support node configuration.
  • %%
  • The requesting entity does not have sufficient privileges to configure the node.
  • %%
  • The request did not specify a node.
  • %%
  • The node has no configuration options.
  • %%
  • The specified node does not exist.
  • %%
set_configure(Host, Node, From, Els, Lang) -> case xml:remove_cdata(Els) of [{xmlelement, "x", _Attrs1, _Els1} = XEl] -> case {xml:get_tag_attr_s("xmlns", XEl), xml:get_tag_attr_s("type", XEl)} of {?NS_XDATA, "cancel"} -> {result, []}; {?NS_XDATA, "submit"} -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId} = N) -> case node_call(Type, get_affiliation, [NodeId, From]) of {result, owner} -> case jlib:parse_xdata_submit(XEl) of invalid -> {error, ?ERR_BAD_REQUEST}; XData -> OldOpts = case Options of [] -> node_options(Type); _ -> Options end, case set_xoption(Host, XData, OldOpts) of NewOpts when is_list(NewOpts) -> case tree_call(Host, set_node, [N#pubsub_node{options = NewOpts}]) of ok -> {result, ok}; Err -> Err end; Err -> Err end end; _ -> {error, ?ERR_FORBIDDEN} end end, case transaction(Host, Node, Action, transaction) of {result, {TNode, ok}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, broadcast_config_notification(Host, Node, NodeId, Type, Options, Lang), {result, []}; Other -> Other end; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end. add_opt(Key, Value, Opts) -> Opts1 = lists:keydelete(Key, 1, Opts), [{Key, Value} | Opts1]. -define(SET_BOOL_XOPT(Opt, Val), BoolVal = case Val of "0" -> false; "1" -> true; "false" -> false; "true" -> true; _ -> error end, case BoolVal of error -> {error, ?ERR_NOT_ACCEPTABLE}; _ -> set_xoption(Host, Opts, add_opt(Opt, BoolVal, NewOpts)) end). -define(SET_STRING_XOPT(Opt, Val), set_xoption(Host, Opts, add_opt(Opt, Val, NewOpts))). -define(SET_INTEGER_XOPT(Opt, Val, Min, Max), case catch list_to_integer(Val) of IVal when is_integer(IVal), IVal >= Min, IVal =< Max -> set_xoption(Host, Opts, add_opt(Opt, IVal, NewOpts)); _ -> {error, ?ERR_NOT_ACCEPTABLE} end). -define(SET_ALIST_XOPT(Opt, Val, Vals), case lists:member(Val, [atom_to_list(V) || V <- Vals]) of true -> set_xoption(Host, Opts, add_opt(Opt, list_to_atom(Val), NewOpts)); false -> {error, ?ERR_NOT_ACCEPTABLE} end). -define(SET_LIST_XOPT(Opt, Val), set_xoption(Host, Opts, add_opt(Opt, Val, NewOpts))). set_xoption(_Host, [], NewOpts) -> NewOpts; set_xoption(Host, [{"FORM_TYPE", _} | Opts], NewOpts) -> set_xoption(Host, Opts, NewOpts); set_xoption(Host, [{"pubsub#roster_groups_allowed", Value} | Opts], NewOpts) -> ?SET_LIST_XOPT(roster_groups_allowed, Value); set_xoption(Host, [{"pubsub#deliver_payloads", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(deliver_payloads, Val); set_xoption(Host, [{"pubsub#deliver_notifications", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(deliver_notifications, Val); set_xoption(Host, [{"pubsub#notify_config", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(notify_config, Val); set_xoption(Host, [{"pubsub#notify_delete", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(notify_delete, Val); set_xoption(Host, [{"pubsub#notify_retract", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(notify_retract, Val); set_xoption(Host, [{"pubsub#persist_items", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(persist_items, Val); set_xoption(Host, [{"pubsub#max_items", [Val]} | Opts], NewOpts) -> MaxItems = get_max_items_node(Host), ?SET_INTEGER_XOPT(max_items, Val, 0, MaxItems); set_xoption(Host, [{"pubsub#subscribe", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(subscribe, Val); set_xoption(Host, [{"pubsub#access_model", [Val]} | Opts], NewOpts) -> ?SET_ALIST_XOPT(access_model, Val, [open, authorize, presence, roster, whitelist]); set_xoption(Host, [{"pubsub#publish_model", [Val]} | Opts], NewOpts) -> ?SET_ALIST_XOPT(publish_model, Val, [publishers, subscribers, open]); set_xoption(Host, [{"pubsub#notification_type", [Val]} | Opts], NewOpts) -> ?SET_ALIST_XOPT(notification_type, Val, [headline, normal]); set_xoption(Host, [{"pubsub#node_type", [Val]} | Opts], NewOpts) -> ?SET_ALIST_XOPT(node_type, Val, [leaf, collection]); set_xoption(Host, [{"pubsub#max_payload_size", [Val]} | Opts], NewOpts) -> ?SET_INTEGER_XOPT(max_payload_size, Val, 0, ?MAX_PAYLOAD_SIZE); set_xoption(Host, [{"pubsub#send_last_published_item", [Val]} | Opts], NewOpts) -> ?SET_ALIST_XOPT(send_last_published_item, Val, [never, on_sub, on_sub_and_presence]); set_xoption(Host, [{"pubsub#presence_based_delivery", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(presence_based_delivery, Val); set_xoption(Host, [{"pubsub#purge_offline", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(purge_offline, Val); set_xoption(Host, [{"pubsub#title", Value} | Opts], NewOpts) -> ?SET_STRING_XOPT(title, Value); set_xoption(Host, [{"pubsub#type", Value} | Opts], NewOpts) -> ?SET_STRING_XOPT(type, Value); set_xoption(Host, [{"pubsub#body_xslt", Value} | Opts], NewOpts) -> ?SET_STRING_XOPT(body_xslt, Value); set_xoption(Host, [{"pubsub#collection", Value} | Opts], NewOpts) -> NewValue = [string_to_node(V) || V <- Value], ?SET_LIST_XOPT(collection, NewValue); set_xoption(Host, [{"pubsub#node", [Value]} | Opts], NewOpts) -> NewValue = string_to_node(Value), ?SET_LIST_XOPT(node, NewValue); set_xoption(Host, [_ | Opts], NewOpts) -> % skip unknown field set_xoption(Host, Opts, NewOpts). get_max_items_node({_, ServerHost, _}) -> get_max_items_node(ServerHost); get_max_items_node(Host) -> case catch ets:lookup(gen_mod:get_module_proc(Host, config), max_items_node) of [{max_items_node, Integer}] -> Integer; _ -> ?MAXITEMS end. %%%% last item cache handling is_last_item_cache_enabled({_, ServerHost, _}) -> is_last_item_cache_enabled(ServerHost); is_last_item_cache_enabled(Host) -> case catch ets:lookup(gen_mod:get_module_proc(Host, config), last_item_cache) of [{last_item_cache, true}] -> true; _ -> false end. set_cached_item({_, ServerHost, _}, NodeId, ItemId, Publisher, Payload) -> set_cached_item(ServerHost, NodeId, ItemId, Publisher, Payload); set_cached_item(Host, NodeId, ItemId, Publisher, Payload) -> case is_last_item_cache_enabled(Host) of true -> mnesia:dirty_write({pubsub_last_item, NodeId, ItemId, {now(), jlib:jid_tolower(jlib:jid_remove_resource(Publisher))}, Payload}); _ -> ok end. unset_cached_item({_, ServerHost, _}, NodeId) -> unset_cached_item(ServerHost, NodeId); unset_cached_item(Host, NodeId) -> case is_last_item_cache_enabled(Host) of true -> mnesia:dirty_delete({pubsub_last_item, NodeId}); _ -> ok end. get_cached_item({_, ServerHost, _}, NodeId) -> get_cached_item(ServerHost, NodeId); get_cached_item(Host, NodeId) -> case is_last_item_cache_enabled(Host) of true -> case mnesia:dirty_read({pubsub_last_item, NodeId}) of [{pubsub_last_item, NodeId, ItemId, Creation, Payload}] -> #pubsub_item{itemid = {ItemId, NodeId}, payload = Payload, creation = Creation, modification = Creation}; _ -> undefined end; _ -> undefined end. %%%% plugin handling host(ServerHost) -> case catch ets:lookup(gen_mod:get_module_proc(ServerHost, config), host) of [{host, Host}] -> Host; _ -> "pubsub."++ServerHost end. plugins(Host) -> case catch ets:lookup(gen_mod:get_module_proc(Host, config), plugins) of [{plugins, []}] -> [?STDNODE]; [{plugins, PL}] -> PL; _ -> [?STDNODE] end. select_type(ServerHost, Host, Node, Type)-> SelectedType = case Host of {_User, _Server, _Resource} -> case catch ets:lookup(gen_mod:get_module_proc(ServerHost, config), pep_mapping) of [{pep_mapping, PM}] -> proplists:get_value(node_to_string(Node), PM, ?PEPNODE); _ -> ?PEPNODE end; _ -> Type end, ConfiguredTypes = plugins(ServerHost), case lists:member(SelectedType, ConfiguredTypes) of true -> SelectedType; false -> hd(ConfiguredTypes) end. select_type(ServerHost, Host, Node) -> select_type(ServerHost, Host, Node, hd(plugins(ServerHost))). features() -> [ % see plugin "access-authorize", % OPTIONAL "access-open", % OPTIONAL this relates to access_model option in node_hometree "access-presence", % OPTIONAL this relates to access_model option in node_pep %TODO "access-roster", % OPTIONAL "access-whitelist", % OPTIONAL % see plugin "auto-create", % OPTIONAL % see plugin "auto-subscribe", % RECOMMENDED "collections", % RECOMMENDED "config-node", % RECOMMENDED "create-and-configure", % RECOMMENDED % see plugin "create-nodes", % RECOMMENDED % see plugin "delete-items", % RECOMMENDED % see plugin "delete-nodes", % RECOMMENDED % see plugin "filtered-notifications", % RECOMMENDED % see plugin "get-pending", % OPTIONAL % see plugin "instant-nodes", % RECOMMENDED "item-ids", % RECOMMENDED "last-published", % RECOMMENDED %TODO "cache-last-item", %TODO "leased-subscription", % OPTIONAL % see plugin "manage-subscriptions", % OPTIONAL "member-affiliation", % RECOMMENDED %TODO "meta-data", % RECOMMENDED % see plugin "modify-affiliations", % OPTIONAL % see plugin "multi-collection", % OPTIONAL % see plugin "multi-subscribe", % OPTIONAL % see plugin "outcast-affiliation", % RECOMMENDED % see plugin "persistent-items", % RECOMMENDED "presence-notifications", % OPTIONAL "presence-subscribe", % RECOMMENDED % see plugin "publish", % REQUIRED %TODO "publish-options", % OPTIONAL "publisher-affiliation", % RECOMMENDED % see plugin "purge-nodes", % OPTIONAL % see plugin "retract-items", % OPTIONAL % see plugin "retrieve-affiliations", % RECOMMENDED "retrieve-default" % RECOMMENDED % see plugin "retrieve-items", % RECOMMENDED % see plugin "retrieve-subscriptions", % RECOMMENDED %TODO "shim", % OPTIONAL % see plugin "subscribe", % REQUIRED % see plugin "subscription-options", % OPTIONAL % see plugin "subscription-notifications" % OPTIONAL ]. features(Type) -> Module = list_to_atom(?PLUGIN_PREFIX++Type), features() ++ case catch Module:features() of {'EXIT', {undef, _}} -> []; Result -> Result end. features(Host, <<>>) -> lists:usort(lists:foldl(fun(Plugin, Acc) -> Acc ++ features(Plugin) end, [], plugins(Host))); features(Host, Node) -> Action = fun(#pubsub_node{type = Type}) -> {result, features(Type)} end, case transaction(Host, Node, Action, sync_dirty) of {result, Features} -> lists:usort(features() ++ Features); _ -> features() end. %% @doc

node tree plugin call.

tree_call({_User, Server, _Resource}, Function, Args) -> tree_call(Server, Function, Args); tree_call(Host, Function, Args) -> ?DEBUG("tree_call ~p ~p ~p",[Host, Function, Args]), Module = case catch ets:lookup(gen_mod:get_module_proc(Host, config), nodetree) of [{nodetree, N}] -> N; _ -> list_to_atom(?TREE_PREFIX ++ ?STDTREE) end, catch apply(Module, Function, Args). tree_action(Host, Function, Args) -> ?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]), Fun = fun() -> tree_call(Host, Function, Args) end, case catch ejabberd_odbc:sql_bloc(odbc_conn(Host), Fun) of {atomic, Result} -> Result; {aborted, Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n",[{aborted, Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR} end. %% @doc

node plugin call.

node_call(Type, Function, Args) -> ?DEBUG("node_call ~p ~p ~p",[Type, Function, Args]), Module = list_to_atom(?PLUGIN_PREFIX++Type), case apply(Module, Function, Args) of {result, Result} -> {result, Result}; {error, Error} -> {error, Error}; {'EXIT', {undef, Undefined}} -> case Type of ?STDNODE -> {error, {undef, Undefined}}; _ -> node_call(?STDNODE, Function, Args) end; {'EXIT', Reason} -> {error, Reason}; Result -> {result, Result} %% any other return value is forced as result end. node_action(Host, Type, Function, Args) -> ?DEBUG("node_action ~p ~p ~p ~p",[Host,Type,Function,Args]), transaction(Host, fun() -> node_call(Type, Function, Args) end, sync_dirty). %% @doc

plugin transaction handling.

transaction(Host, Node, Action, Trans) -> transaction(Host, fun() -> case tree_call(Host, get_node, [Host, Node]) of N when is_record(N, pubsub_node) -> case Action(N) of {result, Result} -> {result, {N, Result}}; {atomic, {result, Result}} -> {result, {N, Result}}; Other -> Other end; Error -> Error end end, Trans). transaction_on_nodes(Host, Action, Trans) -> transaction(Host, fun() -> {result, lists:foldl(Action, [], tree_call(Host, get_nodes, [Host]))} end, Trans). transaction(Host, Fun, Trans) -> transaction_retry(Host, Fun, Trans, 2). transaction_retry(Host, Fun, Trans, Count) -> SqlFun = case Trans of transaction -> sql_transaction; _ -> sql_bloc end, case catch ejabberd_odbc:SqlFun(odbc_conn(Host), Fun) of {result, Result} -> {result, Result}; {error, Error} -> {error, Error}; {atomic, {result, Result}} -> {result, Result}; {atomic, {error, Error}} -> {error, Error}; {aborted, Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR}; {'EXIT', {timeout, _} = Reason} -> case Count of 0 -> ?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR}; N -> erlang:yield(), transaction_retry(Host, Fun, Trans, N-1) end; {'EXIT', Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR}; Other -> ?ERROR_MSG("transaction return internal error: ~p~n", [Other]), {error, ?ERR_INTERNAL_SERVER_ERROR} end. odbc_conn({_U, Host, _R})-> Host; odbc_conn(Host) -> lists:dropwhile(fun(A) -> A/=$. end, Host) -- ".". %% escape value for database storage escape({_U, _H, _R}=JID)-> ejabberd_odbc:escape(jlib:jid_to_string(JID)); escape(Value)-> ejabberd_odbc:escape(Value). %%%% helpers %% Add pubsub-specific error element extended_error(Error, Ext) -> extended_error(Error, Ext, [{"xmlns", ?NS_PUBSUB_ERRORS}]). extended_error(Error, unsupported, Feature) -> extended_error(Error, "unsupported", [{"xmlns", ?NS_PUBSUB_ERRORS}, {"feature", Feature}]); extended_error({xmlelement, Error, Attrs, SubEls}, Ext, ExtAttrs) -> {xmlelement, Error, Attrs, lists:reverse([{xmlelement, Ext, ExtAttrs, []} | SubEls])}. %% Give a uniq identifier uniqid() -> {T1, T2, T3} = now(), lists:flatten(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3])). % node attributes nodeAttr(Node) when is_list(Node) -> [{"node", Node}]; nodeAttr(Node) -> [{"node", node_to_string(Node)}]. % item attributes itemAttr([]) -> []; itemAttr(ItemId) -> [{"id", ItemId}]. % build item elements from item list itemsEls(Items) -> lists:map(fun(#pubsub_item{itemid = {ItemId, _}, payload = Payload}) -> {xmlelement, "item", itemAttr(ItemId), Payload} end, Items). add_message_type({xmlelement, "message", Attrs, Els}, Type) -> {xmlelement, "message", [{"type", Type}|Attrs], Els}; add_message_type(XmlEl, _Type) -> XmlEl. %% Place of changed at the bottom of the stanza %% cf. http://xmpp.org/extensions/xep-0060.html#publisher-publish-success-subid %% %% "[SHIM Headers] SHOULD be included after the event notification information %% (i.e., as the last child of the stanza)". add_shim_headers(Stanza, HeaderEls) -> add_headers(Stanza, "headers", ?NS_SHIM, HeaderEls). add_extended_headers(Stanza, HeaderEls) -> add_headers(Stanza, "addresses", ?NS_ADDRESS, HeaderEls). add_headers({xmlelement, Name, Attrs, Els}, HeaderName, HeaderNS, HeaderEls) -> HeaderEl = {xmlelement, HeaderName, [{"xmlns", HeaderNS}], HeaderEls}, {xmlelement, Name, Attrs, lists:append(Els, [HeaderEl])}. %% Removed multiple
Foo
elements %% Didn't seem compliant, but not sure. Confirmation required. %% cf. http://xmpp.org/extensions/xep-0248.html#notify %% %% "If an item is published to a node which is also included by a collection, %% and an entity is subscribed to that collection with a subscription type of %% "items" (Is there a way to check that currently ?), then the notifications %% generated by the service MUST contain additional information. The %% element contained in the notification message MUST specify the node %% identifier of the node that generated the notification (not the collection) %% and the element MUST contain a SHIM header that specifies the node %% identifier of the collection". collection_shim(Node) -> [{xmlelement, "header", [{"name", "Collection"}], [{xmlcdata, node_to_string(Node)}]}]. subid_shim(SubIDs) -> [{xmlelement, "header", [{"name", "SubID"}], [{xmlcdata, SubID}]} || SubID <- SubIDs]. %% The argument is a list of Jids because this function could be used %% with the 'pubsub#replyto' (type=jid-multi) node configuration. extended_headers(Jids) -> [{xmlelement, "address", [{"type", "replyto"}, {"jid", Jid}], []} || Jid <- Jids]. on_user_offline(_, JID, _) -> {User, Server, Resource} = jlib:jid_tolower(JID), case ejabberd_sm:get_user_resources(User, Server) of [] -> purge_offline({User, Server, Resource}); _ -> true end. purge_offline({User, Server, _} = LJID) -> Host = host(element(2, LJID)), Plugins = plugins(Host), Result = lists:foldl( fun(Type, {Status, Acc}) -> case lists:member("retrieve-affiliations", features(Type)) of false -> {{error, extended_error('feature-not-implemented', unsupported, "retrieve-affiliations")}, Acc}; true -> {result, Affiliations} = node_action(Host, Type, get_entity_affiliations, [Host, LJID]), {Status, [Affiliations|Acc]} end end, {ok, []}, Plugins), case Result of {ok, Affiliations} -> lists:foreach( fun({#pubsub_node{nodeid = {_, NodeId}, options = Options, type = Type}, Affiliation}) when Affiliation == 'owner' orelse Affiliation == 'publisher' -> Action = fun(#pubsub_node{type = NType, id = NodeIdx}) -> node_call(NType, get_items, [NodeIdx, service_jid(Host)]) end, case transaction(Host, NodeId, Action, sync_dirty) of {result, {_, []}} -> true; {result, {_, Items}} -> Features = features(Type), case {lists:member("retract-items", Features), lists:member("persistent-items", Features), get_option(Options, persist_items), get_option(Options, purge_offline)} of {true, true, true, true} -> ForceNotify = get_option(Options, notify_retract), lists:foreach( fun(#pubsub_item{itemid = {ItemId, _}, modification = {_, Modification}}) -> case Modification of {User, Server, _} -> delete_item(Host, NodeId, LJID, ItemId, ForceNotify); _ -> true end; (_) -> true end, Items); _ -> true end; Error -> Error end; (_) -> true end, lists:usort(lists:flatten(Affiliations))); {Error, _} -> ?DEBUG("on_user_offline ~p", [Error]) end. ejabberd-2.1.11/src/mod_pubsub/pubsub_odbc.patch0000664000000000000000000010363412240230175016463 0ustar --- mod_pubsub.erl 2012-04-11 16:47:33.620900390 +0200 +++ mod_pubsub_odbc.erl 2012-04-11 16:47:53.390899087 +0200 @@ -42,7 +42,7 @@ %%% 6.2.3.1, 6.2.3.5, and 6.3. For information on subscription leases see %%% XEP-0060 section 12.18. --module(mod_pubsub). +-module(mod_pubsub_odbc). -author('christophe.romain@process-one.net'). -version('1.13-0'). @@ -54,9 +54,9 @@ -include("jlib.hrl"). -include("pubsub.hrl"). --define(STDTREE, "tree"). --define(STDNODE, "flat"). --define(PEPNODE, "pep"). +-define(STDTREE, "tree_odbc"). +-define(STDNODE, "flat_odbc"). +-define(PEPNODE, "pep_odbc"). %% exports for hooks -export([presence_probe/3, @@ -103,7 +103,7 @@ string_to_affiliation/1, extended_error/2, extended_error/3, - rename_default_nodeplugin/0 + escape/1 ]). %% API and gen_server callbacks @@ -122,7 +122,7 @@ -export([send_loop/1 ]). --define(PROCNAME, ejabberd_mod_pubsub). +-define(PROCNAME, ejabberd_mod_pubsub_odbc). -define(LOOPNAME, ejabberd_mod_pubsub_loop). -define(PLUGIN_PREFIX, "node_"). -define(TREE_PREFIX, "nodetree_"). @@ -217,8 +217,6 @@ ok end, ejabberd_router:register_route(Host), - update_node_database(Host, ServerHost), - update_state_database(Host, ServerHost), put(server_host, ServerHost), % not clean, but needed to plug hooks at any location init_nodes(Host, ServerHost, NodeTree, Plugins), State = #state{host = Host, @@ -283,207 +281,14 @@ init_nodes(Host, ServerHost, _NodeTree, Plugins) -> %% TODO, this call should be done plugin side - case lists:member("hometree", Plugins) of + case lists:member("hometree_odbc", Plugins) of true -> - create_node(Host, ServerHost, string_to_node("/home"), service_jid(Host), "hometree"), - create_node(Host, ServerHost, string_to_node("/home/"++ServerHost), service_jid(Host), "hometree"); + create_node(Host, ServerHost, string_to_node("/home"), service_jid(Host), "hometree_odbc"), + create_node(Host, ServerHost, string_to_node("/home/"++ServerHost), service_jid(Host), "hometree_odbc"); false -> ok end. -update_node_database(Host, ServerHost) -> - mnesia:del_table_index(pubsub_node, type), - mnesia:del_table_index(pubsub_node, parentid), - case catch mnesia:table_info(pubsub_node, attributes) of - [host_node, host_parent, info] -> - ?INFO_MSG("upgrade node pubsub tables",[]), - F = fun() -> - {Result, LastIdx} = lists:foldl( - fun({pubsub_node, NodeId, ParentId, {nodeinfo, Items, Options, Entities}}, {RecList, NodeIdx}) -> - ItemsList = - lists:foldl( - fun({item, IID, Publisher, Payload}, Acc) -> - C = {unknown, Publisher}, - M = {now(), Publisher}, - mnesia:write( - #pubsub_item{itemid = {IID, NodeIdx}, - creation = C, - modification = M, - payload = Payload}), - [{Publisher, IID} | Acc] - end, [], Items), - Owners = - dict:fold( - fun(JID, {entity, Aff, Sub}, Acc) -> - UsrItems = - lists:foldl( - fun({P, I}, IAcc) -> - case P of - JID -> [I | IAcc]; - _ -> IAcc - end - end, [], ItemsList), - mnesia:write({pubsub_state, - {JID, NodeIdx}, - UsrItems, - Aff, - Sub}), - case Aff of - owner -> [JID | Acc]; - _ -> Acc - end - end, [], Entities), - mnesia:delete({pubsub_node, NodeId}), - {[#pubsub_node{nodeid = NodeId, - id = NodeIdx, - parents = [element(2, ParentId)], - owners = Owners, - options = Options} | - RecList], NodeIdx + 1} - end, {[], 1}, - mnesia:match_object( - {pubsub_node, {Host, '_'}, '_', '_'})), - mnesia:write(#pubsub_index{index = node, last = LastIdx, free = []}), - Result - end, - {atomic, NewRecords} = mnesia:transaction(F), - {atomic, ok} = mnesia:delete_table(pubsub_node), - {atomic, ok} = mnesia:create_table(pubsub_node, - [{disc_copies, [node()]}, - {attributes, record_info(fields, pubsub_node)}]), - FNew = fun() -> lists:foreach(fun(Record) -> - mnesia:write(Record) - end, NewRecords) - end, - case mnesia:transaction(FNew) of - {atomic, Result} -> - ?INFO_MSG("Pubsub node tables updated correctly: ~p", [Result]); - {aborted, Reason} -> - ?ERROR_MSG("Problem updating Pubsub node tables:~n~p", [Reason]) - end; - [nodeid, parentid, type, owners, options] -> - F = fun({pubsub_node, NodeId, {_, Parent}, Type, Owners, Options}) -> - #pubsub_node{ - nodeid = NodeId, - id = 0, - parents = [Parent], - type = Type, - owners = Owners, - options = Options} - end, - mnesia:transform_table(pubsub_node, F, [nodeid, id, parents, type, owners, options]), - FNew = fun() -> - LastIdx = lists:foldl(fun(#pubsub_node{nodeid = NodeId} = PubsubNode, NodeIdx) -> - mnesia:write(PubsubNode#pubsub_node{id = NodeIdx}), - lists:foreach(fun(#pubsub_state{stateid = StateId} = State) -> - {JID, _} = StateId, - mnesia:delete({pubsub_state, StateId}), - mnesia:write(State#pubsub_state{stateid = {JID, NodeIdx}}) - end, mnesia:match_object(#pubsub_state{stateid = {'_', NodeId}, _ = '_'})), - lists:foreach(fun(#pubsub_item{itemid = ItemId} = Item) -> - {IID, _} = ItemId, - {M1, M2} = Item#pubsub_item.modification, - {C1, C2} = Item#pubsub_item.creation, - mnesia:delete({pubsub_item, ItemId}), - mnesia:write(Item#pubsub_item{itemid = {IID, NodeIdx}, - modification = {M2, M1}, - creation = {C2, C1}}) - end, mnesia:match_object(#pubsub_item{itemid = {'_', NodeId}, _ = '_'})), - NodeIdx + 1 - end, 1, mnesia:match_object( - {pubsub_node, {Host, '_'}, '_', '_', '_', '_', '_'}) - ++ mnesia:match_object( - {pubsub_node, {{'_', ServerHost, '_'}, '_'}, '_', '_', '_', '_', '_'})), - mnesia:write(#pubsub_index{index = node, last = LastIdx, free = []}) - end, - case mnesia:transaction(FNew) of - {atomic, Result} -> - rename_default_nodeplugin(), - ?INFO_MSG("Pubsub node tables updated correctly: ~p", [Result]); - {aborted, Reason} -> - ?ERROR_MSG("Problem updating Pubsub node tables:~n~p", [Reason]) - end; - [nodeid, id, parent, type, owners, options] -> - F = fun({pubsub_node, NodeId, Id, Parent, Type, Owners, Options}) -> - #pubsub_node{ - nodeid = NodeId, - id = Id, - parents = [Parent], - type = Type, - owners = Owners, - options = Options} - end, - mnesia:transform_table(pubsub_node, F, [nodeid, id, parents, type, owners, options]), - rename_default_nodeplugin(); - _ -> - ok - end, - mnesia:transaction(fun() -> - case catch mnesia:first(pubsub_node) of - {_, L} when is_list(L) -> - lists:foreach( - fun({H, N}) when is_list(N) -> - [Node] = mnesia:read({pubsub_node, {H, N}}), - Type = Node#pubsub_node.type, - BN = element(2, node_call(Type, path_to_node, [N])), - BP = case [element(2, node_call(Type, path_to_node, [P])) || P <- Node#pubsub_node.parents] of - [<<>>] -> []; - Parents -> Parents - end, - mnesia:write(Node#pubsub_node{nodeid={H, BN}, parents=BP}), - mnesia:delete({pubsub_node, {H, N}}); - (_) -> - ok - end, mnesia:all_keys(pubsub_node)); - _ -> - ok - end - end). - -rename_default_nodeplugin() -> - lists:foreach(fun(Node) -> - mnesia:dirty_write(Node#pubsub_node{type = "hometree"}) - end, mnesia:dirty_match_object(#pubsub_node{type = "default", _ = '_'})). - -update_state_database(_Host, _ServerHost) -> - case catch mnesia:table_info(pubsub_state, attributes) of - [stateid, items, affiliation, subscription] -> - ?INFO_MSG("upgrade state pubsub tables", []), - F = fun ({pubsub_state, {JID, NodeID}, Items, Aff, Sub}, Acc) -> - Subs = case Sub of - none -> - []; - _ -> - {result, SubID} = pubsub_subscription:subscribe_node(JID, NodeID, []), - [{Sub, SubID}] - end, - NewState = #pubsub_state{stateid = {JID, NodeID}, - items = Items, - affiliation = Aff, - subscriptions = Subs}, - [NewState | Acc] - end, - {atomic, NewRecs} = mnesia:transaction(fun mnesia:foldl/3, - [F, [], pubsub_state]), - {atomic, ok} = mnesia:delete_table(pubsub_state), - {atomic, ok} = mnesia:create_table(pubsub_state, - [{disc_copies, [node()]}, - {attributes, record_info(fields, pubsub_state)}]), - FNew = fun () -> - lists:foreach(fun mnesia:write/1, NewRecs) - end, - case mnesia:transaction(FNew) of - {atomic, Result} -> - ?INFO_MSG("Pubsub state tables updated correctly: ~p", - [Result]); - {aborted, Reason} -> - ?ERROR_MSG("Problem updating Pubsub state tables:~n~p", - [Reason]) - end; - _ -> - ok - end. - send_loop(State) -> receive {presence, JID, Pid} -> @@ -494,17 +299,15 @@ %% for each node From is subscribed to %% and if the node is so configured, send the last published item to From lists:foreach(fun(PType) -> - {result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, JID]), + Subscriptions = case catch node_action(Host, PType, get_entity_subscriptions_for_send_last, [Host, JID]) of + {result, S} -> S; + _ -> [] + end, lists:foreach( fun({Node, subscribed, _, SubJID}) -> if (SubJID == LJID) or (SubJID == BJID) -> - #pubsub_node{nodeid = {H, N}, type = Type, id = NodeId, options = Options} = Node, - case get_option(Options, send_last_published_item) of - on_sub_and_presence -> - send_items(H, N, NodeId, Type, LJID, last); - _ -> - ok - end; + #pubsub_node{nodeid = {H, N}, type = Type, id = NodeId} = Node, + send_items(H, N, NodeId, Type, LJID, last); true -> % resource not concerned about that subscription ok @@ -623,7 +426,8 @@ disco_identity(_Host, <<>>, _From) -> [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "pep"}], []}]; disco_identity(Host, Node, From) -> - Action = fun(#pubsub_node{id = Idx, type = Type, options = Options, owners = Owners}) -> + Action = fun(#pubsub_node{id = Idx, type = Type, options = Options}) -> + Owners = node_owners_call(Type, Idx), case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> {result, [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "pep"}], []}, @@ -658,7 +462,8 @@ [?NS_PUBSUB | [?NS_PUBSUB++"#"++Feature || Feature <- features("pep")]]; disco_features(Host, Node, From) -> - Action = fun(#pubsub_node{id = Idx, type = Type, options = Options, owners = Owners}) -> + Action = fun(#pubsub_node{id = Idx, type = Type, options = Options}) -> + Owners = node_owners_call(Type, Idx), case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> {result, [?NS_PUBSUB @@ -683,7 +488,8 @@ Acc. disco_items(Host, <<>>, From) -> - Action = fun(#pubsub_node{nodeid ={_, NodeID}, options = Options, type = Type, id = Idx, owners = Owners}, Acc) -> + Action = fun(#pubsub_node{nodeid ={_, NodeID}, options = Options, type = Type, id = Idx}, Acc) -> + Owners = node_owners_call(Type, Idx), case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> [{xmlelement, "item", @@ -701,13 +507,14 @@ _ -> Acc end end, - case transaction(Host, Action, sync_dirty) of + case transaction_on_nodes(Host, Action, sync_dirty) of {result, Items} -> Items; _ -> [] end; disco_items(Host, Node, From) -> - Action = fun(#pubsub_node{id = Idx, type = Type, options = Options, owners = Owners}) -> + Action = fun(#pubsub_node{id = Idx, type = Type, options = Options}) -> + Owners = node_owners_call(Type, Idx), case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, Items} -> {result, [{xmlelement, "item", @@ -793,10 +600,10 @@ lists:foreach(fun(PType) -> {result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Entity]), lists:foreach(fun - ({#pubsub_node{options = Options, owners = Owners, id = NodeId}, subscribed, _, JID}) -> + ({#pubsub_node{options = Options, id = NodeId}, subscribed, _, JID}) -> case get_option(Options, access_model) of presence -> - case lists:member(BJID, Owners) of + case lists:member(BJID, node_owners(Host, PType, NodeId)) of true -> node_action(Host, PType, unsubscribe_node, [NodeId, Entity, JID, all]); false -> @@ -964,7 +771,8 @@ sub_el = SubEl} = IQ -> {xmlelement, _, QAttrs, _} = SubEl, Node = xml:get_attr_s("node", QAttrs), - Res = case iq_disco_items(Host, Node, From) of + Rsm = jlib:rsm_decode(IQ), + Res = case iq_disco_items(Host, Node, From, Rsm) of {result, IQRes} -> jlib:iq_to_xml( IQ#iq{type = result, @@ -1077,7 +885,7 @@ [] -> ["leaf"]; %% No sub-nodes: it's a leaf node _ -> - case node_call(Type, get_items, [NodeId, From]) of + case node_call(Type, get_items, [NodeId, From, none]) of {result, []} -> ["collection"]; {result, _} -> ["leaf", "collection"]; _ -> [] @@ -1093,8 +901,9 @@ []; true -> [{xmlelement, "feature", [{"var", ?NS_PUBSUB}], []} | - lists:map(fun(T) -> - {xmlelement, "feature", [{"var", ?NS_PUBSUB++"#"++T}], []} + lists:map(fun + ("rsm")-> {xmlelement, "feature", [{"var", ?NS_RSM}], []}; + (T) -> {xmlelement, "feature", [{"var", ?NS_PUBSUB++"#"++T}], []} end, features(Type))] end, %% TODO: add meta-data info (spec section 5.4) @@ -1123,8 +932,9 @@ {xmlelement, "feature", [{"var", ?NS_PUBSUB}], []}, {xmlelement, "feature", [{"var", ?NS_COMMANDS}], []}, {xmlelement, "feature", [{"var", ?NS_VCARD}], []}] ++ - lists:map(fun(Feature) -> - {xmlelement, "feature", [{"var", ?NS_PUBSUB++"#"++Feature}], []} + lists:map(fun + ("rsm")-> {xmlelement, "feature", [{"var", ?NS_RSM}], []}; + (T) -> {xmlelement, "feature", [{"var", ?NS_PUBSUB++"#"++T}], []} end, features(Host, Node))}; <> -> command_disco_info(Host, Node, From); @@ -1134,7 +944,7 @@ node_disco_info(Host, Node, From) end. -iq_disco_items(Host, [], From) -> +iq_disco_items(Host, [], From, _RSM) -> case tree_action(Host, get_subnodes, [Host, <<>>, From]) of Nodes when is_list(Nodes) -> {result, lists:map( @@ -1151,23 +961,24 @@ Other -> Other end; -iq_disco_items(Host, ?NS_COMMANDS, _From) -> +iq_disco_items(Host, ?NS_COMMANDS, _From, _RSM) -> %% TODO: support localization of this string CommandItems = [{xmlelement, "item", [{"jid", Host}, {"node", ?NS_PUBSUB_GET_PENDING}, {"name", "Get Pending"}], []}], {result, CommandItems}; -iq_disco_items(_Host, ?NS_PUBSUB_GET_PENDING, _From) -> +iq_disco_items(_Host, ?NS_PUBSUB_GET_PENDING, _From, _RSM) -> CommandItems = [], {result, CommandItems}; -iq_disco_items(Host, Item, From) -> +iq_disco_items(Host, Item, From, RSM) -> case string:tokens(Item, "!") of [_SNode, _ItemID] -> {result, []}; [SNode] -> Node = string_to_node(SNode), - Action = fun(#pubsub_node{id = Idx, type = Type, options = Options, owners = Owners}) -> - NodeItems = case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of + Action = fun(#pubsub_node{id = Idx, type = Type, options = Options}) -> + Owners = node_owners_call(Type, Idx), + {NodeItems, RsmOut} = case get_allowed_items_call(Host, Idx, From, Type, Options, Owners, RSM) of {result, R} -> R; - _ -> [] + _ -> {[], none} end, Nodes = lists:map( fun(#pubsub_node{nodeid = {_, SubNode}, options = SubOptions}) -> @@ -1185,7 +996,7 @@ {result, Name} = node_call(Type, get_item_name, [Host, Node, RN]), {xmlelement, "item", [{"jid", Host}, {"name", Name}], []} end, NodeItems), - {result, Nodes ++ Items} + {result, Nodes ++ Items ++ jlib:rsm_encode(RsmOut)} end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; @@ -1296,7 +1107,8 @@ (_, Acc) -> Acc end, [], xml:remove_cdata(Els)), - get_items(Host, Node, From, SubId, MaxItems, ItemIDs); + RSM = jlib:rsm_decode(SubEl), + get_items(Host, Node, From, SubId, MaxItems, ItemIDs, RSM); {get, "subscriptions"} -> get_subscriptions(Host, Node, From, Plugins); {get, "affiliations"} -> @@ -1319,7 +1131,9 @@ iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) -> {xmlelement, _, _, SubEls} = SubEl, - Action = xml:remove_cdata(SubEls), + Action = lists:filter(fun({xmlelement, "set", _, _}) -> false; + (_) -> true + end, xml:remove_cdata(SubEls)), case Action of [{xmlelement, Name, Attrs, Els}] -> Node = string_to_node(xml:get_attr_s("node", Attrs)), @@ -1449,7 +1263,8 @@ _ -> [] end end, - case transaction(fun () -> {result, lists:flatmap(Tr, Plugins)} end, + case transaction(Host, + fun () -> {result, lists:flatmap(Tr, Plugins)} end, sync_dirty) of {result, Res} -> Res; Err -> Err @@ -1488,7 +1303,7 @@ %%% authorization handling -send_authorization_request(#pubsub_node{owners = Owners, nodeid = {Host, Node}}, Subscriber) -> +send_authorization_request(#pubsub_node{nodeid = {Host, Node}, type = Type, id = NodeId}, Subscriber) -> Lang = "en", %% TODO fix Stanza = {xmlelement, "message", [], @@ -1517,7 +1332,7 @@ [{xmlelement, "value", [], [{xmlcdata, "false"}]}]}]}]}, lists:foreach(fun(Owner) -> ejabberd_router:route(service_jid(Host), jlib:make_jid(Owner), Stanza) - end, Owners). + end, node_owners(Host, Type, NodeId)). find_authorization_response(Packet) -> {xmlelement, _Name, _Attrs, Els} = Packet, @@ -1581,8 +1396,8 @@ "true" -> true; _ -> false end, - Action = fun(#pubsub_node{type = Type, owners = Owners, id = NodeId}) -> - IsApprover = lists:member(jlib:jid_tolower(jlib:jid_remove_resource(From)), Owners), + Action = fun(#pubsub_node{type = Type, id = NodeId}) -> + IsApprover = lists:member(jlib:jid_tolower(jlib:jid_remove_resource(From)), node_owners_call(Type, NodeId)), {result, Subscriptions} = node_call(Type, get_subscriptions, [NodeId, Subscriber]), if not IsApprover -> @@ -1781,7 +1596,7 @@ Reply = [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "create", nodeAttr(Node), []}]}], - case transaction(CreateNode, transaction) of + case transaction(Host, CreateNode, transaction) of {result, {NodeId, SubsByDepth, {Result, broadcast}}} -> broadcast_created_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth), ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), @@ -1898,7 +1713,7 @@ %%
  • The node does not exist.
  • %% subscribe_node(Host, Node, From, JID, Configuration) -> - SubOpts = case pubsub_subscription:parse_options_xform(Configuration) of + SubOpts = case pubsub_subscription_odbc:parse_options_xform(Configuration) of {result, GoodSubOpts} -> GoodSubOpts; _ -> invalid end, @@ -1906,7 +1721,7 @@ error -> {"", "", ""}; J -> jlib:jid_tolower(J) end, - Action = fun(#pubsub_node{options = Options, owners = Owners, type = Type, id = NodeId}) -> + Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> Features = features(Type), SubscribeFeature = lists:member("subscribe", Features), OptionsFeature = lists:member("subscription-options", Features), @@ -1915,6 +1730,7 @@ AccessModel = get_option(Options, access_model), SendLast = get_option(Options, send_last_published_item), AllowedGroups = get_option(Options, roster_groups_allowed, []), + Owners = node_owners_call(Type, NodeId), {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, Subscriber, Owners, AccessModel, AllowedGroups), if not SubscribeFeature -> @@ -2036,12 +1852,9 @@ Features = features(Type), PublishFeature = lists:member("publish", Features), PublishModel = get_option(Options, publish_model), + MaxItems = max_items(Host, Options), DeliverPayloads = get_option(Options, deliver_payloads), PersistItems = get_option(Options, persist_items), - MaxItems = case PersistItems of - false -> 0; - true -> max_items(Host, Options) - end, PayloadCount = payload_xmlelements(Payload), PayloadSize = size(term_to_binary(Payload))-2, % size(term_to_binary([])) == 2 PayloadMaxSize = get_option(Options, max_payload_size), @@ -2092,7 +1905,7 @@ false -> ok end, - set_cached_item(Host, NodeId, ItemId, Publisher, Payload), + set_cached_item(Host, NodeId, ItemId, Publisher, Payload), case Result of default -> {result, Reply}; _ -> {result, Result} @@ -2258,7 +2071,7 @@ %%

    The permission are not checked in this function.

    %% @todo We probably need to check that the user doing the query has the right %% to read the items. -get_items(Host, Node, From, SubId, SMaxItems, ItemIDs) -> +get_items(Host, Node, From, SubId, SMaxItems, ItemIDs, RSM) -> MaxItems = if SMaxItems == "" -> get_max_items_node(Host); @@ -2272,12 +2085,13 @@ {error, Error} -> {error, Error}; _ -> - Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId, owners = Owners}) -> + Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> Features = features(Type), RetreiveFeature = lists:member("retrieve-items", Features), PersistentFeature = lists:member("persistent-items", Features), AccessModel = get_option(Options, access_model), AllowedGroups = get_option(Options, roster_groups_allowed, []), + Owners = node_owners_call(Type, NodeId), {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups), if not RetreiveFeature -> @@ -2290,11 +2104,11 @@ node_call(Type, get_items, [NodeId, From, AccessModel, PresenceSubscription, RosterGroup, - SubId]) + SubId, RSM]) end end, case transaction(Host, Node, Action, sync_dirty) of - {result, {_, Items}} -> + {result, {_, {Items, RSMOut}}} -> SendItems = case ItemIDs of [] -> Items; @@ -2307,7 +2121,8 @@ %% number of items sent to MaxItems: {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "items", nodeAttr(Node), - itemsEls(lists:sublist(SendItems, MaxItems))}]}]}; + itemsEls(lists:sublist(SendItems, MaxItems))} + | jlib:rsm_encode(RSMOut)]}]}; Error -> Error end @@ -2329,10 +2144,15 @@ Error -> Error end. get_allowed_items_call(Host, NodeIdx, From, Type, Options, Owners) -> + case get_allowed_items_call(Host, NodeIdx, From, Type, Options, Owners, none) of + {result, {I, _}} -> {result, I}; + Error -> Error + end. +get_allowed_items_call(Host, NodeIdx, From, Type, Options, Owners, RSM) -> AccessModel = get_option(Options, access_model), AllowedGroups = get_option(Options, roster_groups_allowed, []), {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups), - node_call(Type, get_items, [NodeIdx, From, AccessModel, PresenceSubscription, RosterGroup, undefined]). + node_call(Type, get_items, [NodeIdx, From, AccessModel, PresenceSubscription, RosterGroup, undefined, RSM]). %% @spec (Host, Node, NodeId, Type, LJID, Number) -> any() @@ -2344,31 +2164,29 @@ %% Number = last | integer() %% @doc

    Resend the items of a node to the user.

    %% @todo use cache-last-item feature -send_items(Host, Node, NodeId, Type, {U,S,R} = LJID, last) -> - case get_cached_item(Host, NodeId) of +send_items(Host, Node, NodeId, Type, LJID, last) -> + Stanza = case get_cached_item(Host, NodeId) of undefined -> - send_items(Host, Node, NodeId, Type, LJID, 1); + % special ODBC optimization, works only with node_hometree_odbc, node_flat_odbc and node_pep_odbc + case node_action(Host, Type, get_last_items, [NodeId, LJID, 1]) of + {result, [LastItem]} -> + {ModifNow, ModifUSR} = LastItem#pubsub_item.modification, + event_stanza_with_delay( + [{xmlelement, "items", nodeAttr(Node), + itemsEls([LastItem])}], ModifNow, ModifUSR); + _ -> + event_stanza( + [{xmlelement, "items", nodeAttr(Node), + itemsEls([])}]) + end; LastItem -> {ModifNow, ModifUSR} = LastItem#pubsub_item.modification, - Stanza = event_stanza_with_delay( + event_stanza_with_delay( [{xmlelement, "items", nodeAttr(Node), - itemsEls([LastItem])}], ModifNow, ModifUSR), - case is_tuple(Host) of - false -> - ejabberd_router:route(service_jid(Host), jlib:make_jid(LJID), Stanza); - true -> - case ejabberd_sm:get_session_pid(U,S,R) of - C2SPid when is_pid(C2SPid) -> - ejabberd_c2s:broadcast(C2SPid, - {pep_message, binary_to_list(Node)++"+notify"}, - _Sender = service_jid(Host), - Stanza); - _ -> - ok - end - end - end; -send_items(Host, Node, NodeId, Type, {U,S,R} = LJID, Number) -> + itemsEls([LastItem])}], ModifNow, ModifUSR) + end, + ejabberd_router:route(service_jid(Host), jlib:make_jid(LJID), Stanza); +send_items(Host, Node, NodeId, Type, LJID, Number) -> ToSend = case node_action(Host, Type, get_items, [NodeId, LJID]) of {result, []} -> []; @@ -2391,20 +2209,7 @@ [{xmlelement, "items", nodeAttr(Node), itemsEls(ToSend)}]) end, - case is_tuple(Host) of - false -> - ejabberd_router:route(service_jid(Host), jlib:make_jid(LJID), Stanza); - true -> - case ejabberd_sm:get_session_pid(U,S,R) of - C2SPid when is_pid(C2SPid) -> - ejabberd_c2s:broadcast(C2SPid, - {pep_message, binary_to_list(Node)++"+notify"}, - _Sender = service_jid(Host), - Stanza); - _ -> - ok - end - end. + ejabberd_router:route(service_jid(Host), jlib:make_jid(LJID), Stanza). %% @spec (Host, JID, Plugins) -> {error, Reason} | {result, Response} %% Host = host() @@ -2540,7 +2345,8 @@ error -> {error, ?ERR_BAD_REQUEST}; _ -> - Action = fun(#pubsub_node{owners = Owners, type = Type, id = NodeId}=N) -> + Action = fun(#pubsub_node{type = Type, id = NodeId}) -> + Owners = node_owners_call(Type, NodeId), case lists:member(Owner, Owners) of true -> OwnerJID = jlib:make_jid(Owner), @@ -2550,24 +2356,7 @@ end, lists:foreach( fun({JID, Affiliation}) -> - node_call(Type, set_affiliation, [NodeId, JID, Affiliation]), - case Affiliation of - owner -> - NewOwner = jlib:jid_tolower(jlib:jid_remove_resource(JID)), - NewOwners = [NewOwner|Owners], - tree_call(Host, set_node, [N#pubsub_node{owners = NewOwners}]); - none -> - OldOwner = jlib:jid_tolower(jlib:jid_remove_resource(JID)), - case lists:member(OldOwner, Owners) of - true -> - NewOwners = Owners--[OldOwner], - tree_call(Host, set_node, [N#pubsub_node{owners = NewOwners}]); - _ -> - ok - end; - _ -> - ok - end + node_call(Type, set_affiliation, [NodeId, JID, Affiliation]) end, FilteredEntities), {result, []}; _ -> @@ -2620,11 +2409,11 @@ end. read_sub(Subscriber, Node, NodeID, SubID, Lang) -> - case pubsub_subscription:get_subscription(Subscriber, NodeID, SubID) of + case pubsub_subscription_odbc:get_subscription(Subscriber, NodeID, SubID) of {error, notfound} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; {result, #pubsub_subscription{options = Options}} -> - {result, XdataEl} = pubsub_subscription:get_options_xform(Lang, Options), + {result, XdataEl} = pubsub_subscription_odbc:get_options_xform(Lang, Options), OptionsEl = {xmlelement, "options", [{"jid", jlib:jid_to_string(Subscriber)}, {"subid", SubID}|nodeAttr(Node)], [XdataEl]}, @@ -2650,7 +2439,7 @@ end. set_options_helper(Configuration, JID, NodeID, SubID, Type) -> - SubOpts = case pubsub_subscription:parse_options_xform(Configuration) of + SubOpts = case pubsub_subscription_odbc:parse_options_xform(Configuration) of {result, GoodSubOpts} -> GoodSubOpts; _ -> invalid end, @@ -2679,7 +2468,7 @@ write_sub(_Subscriber, _NodeID, _SubID, invalid) -> {error, extended_error(?ERR_BAD_REQUEST, "invalid-options")}; write_sub(Subscriber, NodeID, SubID, Options) -> - case pubsub_subscription:set_subscription(Subscriber, NodeID, SubID, Options) of + case pubsub_subscription_odbc:set_subscription(Subscriber, NodeID, SubID, Options) of {error, notfound} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; {result, _} -> @@ -2847,8 +2636,8 @@ {"subscription", subscription_to_string(Sub)} | nodeAttr(Node)], []}]}]}, ejabberd_router:route(service_jid(Host), jlib:make_jid(JID), Stanza) end, - Action = fun(#pubsub_node{owners = Owners, type = Type, id = NodeId}) -> - case lists:member(Owner, Owners) of + Action = fun(#pubsub_node{type = Type, id = NodeId}) -> + case lists:member(Owner, node_owners_call(Type, NodeId)) of true -> Result = lists:foldl(fun({JID, Subscription, SubId}, Acc) -> @@ -3203,7 +2992,7 @@ {Depth, [{N, get_node_subs(N)} || N <- Nodes]} end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))} end, - case transaction(Action, sync_dirty) of + case transaction(Host, Action, sync_dirty) of {result, CollSubs} -> CollSubs; _ -> [] end. @@ -3217,9 +3006,9 @@ get_options_for_subs(NodeID, Subs) -> lists:foldl(fun({JID, subscribed, SubID}, Acc) -> - case pubsub_subscription:read_subscription(JID, NodeID, SubID) of + case pubsub_subscription_odbc:get_subscription(JID, NodeID, SubID) of {error, notfound} -> [{JID, SubID, []} | Acc]; - #pubsub_subscription{options = Options} -> [{JID, SubID, Options} | Acc]; + {result, #pubsub_subscription{options = Options}} -> [{JID, SubID, Options} | Acc]; _ -> Acc end; (_, Acc) -> @@ -3408,6 +3197,30 @@ Result end. +%% @spec (Host, Type, NodeId) -> [ljid()] +%% NodeId = pubsubNodeId() +%% @doc

    Return list of node owners.

    +node_owners(Host, Type, NodeId) -> + case node_action(Host, Type, get_node_affiliations, [NodeId]) of + {result, Affiliations} -> + lists:foldl( + fun({LJID, owner}, Acc) -> [LJID|Acc]; + (_, Acc) -> Acc + end, [], Affiliations); + _ -> + [] + end. +node_owners_call(Type, NodeId) -> + case node_call(Type, get_node_affiliations, [NodeId]) of + {result, Affiliations} -> + lists:foldl( + fun({LJID, owner}, Acc) -> [LJID|Acc]; + (_, Acc) -> Acc + end, [], Affiliations); + _ -> + [] + end. + %% @spec (Host, Options) -> MaxItems %% Host = host() %% Options = [Option] @@ -3804,7 +3617,13 @@ tree_action(Host, Function, Args) -> ?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]), Fun = fun() -> tree_call(Host, Function, Args) end, - catch mnesia:sync_dirty(Fun). + case catch ejabberd_odbc:sql_bloc(odbc_conn(Host), Fun) of + {atomic, Result} -> + Result; + {aborted, Reason} -> + ?ERROR_MSG("transaction return internal error: ~p~n",[{aborted, Reason}]), + {error, ?ERR_INTERNAL_SERVER_ERROR} + end. %% @doc

    node plugin call.

    node_call(Type, Function, Args) -> @@ -3824,13 +3643,13 @@ node_action(Host, Type, Function, Args) -> ?DEBUG("node_action ~p ~p ~p ~p",[Host,Type,Function,Args]), - transaction(fun() -> + transaction(Host, fun() -> node_call(Type, Function, Args) end, sync_dirty). %% @doc

    plugin transaction handling.

    transaction(Host, Node, Action, Trans) -> - transaction(fun() -> + transaction(Host, fun() -> case tree_call(Host, get_node, [Host, Node]) of N when is_record(N, pubsub_node) -> case Action(N) of @@ -3842,13 +3661,19 @@ Error end end, Trans). -transaction(Host, Action, Trans) -> - transaction(fun() -> +transaction_on_nodes(Host, Action, Trans) -> + transaction(Host, fun() -> {result, lists:foldl(Action, [], tree_call(Host, get_nodes, [Host]))} end, Trans). -transaction(Fun, Trans) -> - case catch mnesia:Trans(Fun) of +transaction(Host, Fun, Trans) -> + transaction_retry(Host, Fun, Trans, 2). +transaction_retry(Host, Fun, Trans, Count) -> + SqlFun = case Trans of + transaction -> sql_transaction; + _ -> sql_bloc + end, + case catch ejabberd_odbc:SqlFun(odbc_conn(Host), Fun) of {result, Result} -> {result, Result}; {error, Error} -> {error, Error}; {atomic, {result, Result}} -> {result, Result}; @@ -3856,6 +3681,15 @@ {aborted, Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR}; + {'EXIT', {timeout, _} = Reason} -> + case Count of + 0 -> + ?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]), + {error, ?ERR_INTERNAL_SERVER_ERROR}; + N -> + erlang:yield(), + transaction_retry(Host, Fun, Trans, N-1) + end; {'EXIT', Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR}; @@ -3864,6 +3698,17 @@ {error, ?ERR_INTERNAL_SERVER_ERROR} end. +odbc_conn({_U, Host, _R})-> + Host; +odbc_conn(Host) -> + lists:dropwhile(fun(A) -> A/=$. end, Host) -- ".". + +%% escape value for database storage +escape({_U, _H, _R}=JID)-> + ejabberd_odbc:escape(jlib:jid_to_string(JID)); +escape(Value)-> + ejabberd_odbc:escape(Value). + %%%% helpers %% Add pubsub-specific error element ejabberd-2.1.11/src/mod_pubsub/node_dag.erl0000664000000000000000000001270112240230175015411 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% @author Brian Cully %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(node_dag). -author('bjc@kublai.com'). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_node). %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/6, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1]). init(Host, ServerHost, Opts) -> node_hometree:init(Host, ServerHost, Opts). terminate(Host, ServerHost) -> node_hometree:terminate(Host, ServerHost). options() -> [{node_type, leaf} | node_hometree:options()]. features() -> ["multi-collection" | node_hometree:features()]. create_node_permission(_Host, _ServerHost, _Node, _ParentNode, _Owner, _Access) -> {result, true}. create_node(NodeID, Owner) -> node_hometree:create_node(NodeID, Owner). delete_node(Removed) -> node_hometree:delete_node(Removed). subscribe_node(NodeID, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> node_hometree:subscribe_node(NodeID, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options). unsubscribe_node(NodeID, Sender, Subscriber, SubID) -> node_hometree:unsubscribe_node(NodeID, Sender, Subscriber, SubID). publish_item(NodeID, Publisher, Model, MaxItems, ItemID, Payload) -> %% TODO: should look up the NodeTree plugin here. There's no %% access to the Host of the request at this level, so for now we %% just use nodetree_dag. case nodetree_dag:get_node(NodeID) of #pubsub_node{options = Options} -> case find_opt(node_type, Options) of collection -> {error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "publish")}; _ -> node_hometree:publish_item(NodeID, Publisher, Model, MaxItems, ItemID, Payload) end; Err -> Err end. find_opt(_, []) -> false; find_opt(Option, [{Option, Value} | _]) -> Value; find_opt(Option, [_ | T]) -> find_opt(Option, T). remove_extra_items(NodeID, MaxItems, ItemIDs) -> node_hometree:remove_extra_items(NodeID, MaxItems, ItemIDs). delete_item(NodeID, Publisher, PublishModel, ItemID) -> node_hometree:delete_item(NodeID, Publisher, PublishModel, ItemID). purge_node(NodeID, Owner) -> node_hometree:purge_node(NodeID, Owner). get_entity_affiliations(Host, Owner) -> node_hometree:get_entity_affiliations(Host, Owner). get_node_affiliations(NodeID) -> node_hometree:get_node_affiliations(NodeID). get_affiliation(NodeID, Owner) -> node_hometree:get_affiliation(NodeID, Owner). set_affiliation(NodeID, Owner, Affiliation) -> node_hometree:set_affiliation(NodeID, Owner, Affiliation). get_entity_subscriptions(Host, Owner) -> node_hometree:get_entity_subscriptions(Host, Owner). get_node_subscriptions(NodeID) -> node_hometree:get_node_subscriptions(NodeID). get_subscriptions(NodeID, Owner) -> node_hometree:get_subscriptions(NodeID, Owner). set_subscriptions(NodeID, Owner, Subscription, SubID) -> node_hometree:set_subscriptions(NodeID, Owner, Subscription, SubID). get_pending_nodes(Host, Owner) -> node_hometree:get_pending_nodes(Host, Owner). get_states(NodeID) -> node_hometree:get_states(NodeID). get_state(NodeID, JID) -> node_hometree:get_state(NodeID, JID). set_state(State) -> node_hometree:set_state(State). get_items(NodeID, From) -> node_hometree:get_items(NodeID, From). get_items(NodeID, JID, AccessModel, PresenceSubscription, RosterGroup, SubID) -> node_hometree:get_items(NodeID, JID, AccessModel, PresenceSubscription, RosterGroup, SubID). get_item(NodeID, ItemID) -> node_hometree:get_item(NodeID, ItemID). get_item(NodeID, ItemID, JID, AccessModel, PresenceSubscription, RosterGroup, SubID) -> node_hometree:get_item(NodeID, ItemID, JID, AccessModel, PresenceSubscription, RosterGroup, SubID). set_item(Item) -> node_hometree:set_item(Item). get_item_name(Host, Node, ID) -> node_hometree:get_item_name(Host, Node, ID). node_to_path(Node) -> node_hometree:node_to_path(Node). path_to_node(Path) -> node_hometree:path_to_node(Path). ejabberd-2.1.11/src/mod_pubsub/nodetree_tree_odbc.erl0000664000000000000000000002661512240230175017475 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %%% @doc The module {@module} is the default PubSub node tree plugin. %%%

    It is used as a default for all unknown PubSub node type. It can serve %%% as a developer basis and reference to build its own custom pubsub node tree %%% types.

    %%%

    PubSub node tree plugins are using the {@link gen_nodetree} behaviour.

    %%%

    The API isn't stabilized yet. The pubsub plugin %%% development is still a work in progress. However, the system is already %%% useable and useful as is. Please, send us comments, feedback and %%% improvements.

    -module(nodetree_tree_odbc). -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -include("jlib.hrl"). -define(PUBSUB, mod_pubsub_odbc). -define(PLUGIN_PREFIX, "node_"). -behaviour(gen_pubsub_nodetree). -export([init/3, terminate/2, options/0, set_node/1, get_node/3, get_node/2, get_node/1, get_nodes/2, get_nodes/1, get_parentnodes/3, get_parentnodes_tree/3, get_subnodes/3, get_subnodes_tree/3, create_node/6, delete_node/2 ]). -export([raw_to_node/2]). %% ================ %% API definition %% ================ %% @spec (Host, ServerHost, Opts) -> any() %% Host = mod_pubsub:host() %% ServerHost = host() %% Opts = list() %% @doc

    Called during pubsub modules initialisation. Any pubsub plugin must %% implement this function. It can return anything.

    %%

    This function is mainly used to trigger the setup task necessary for the %% plugin. It can be used for example by the developer to create the specific %% module database schema if it does not exists yet.

    init(_Host, _ServerHost, _Opts) -> ok. terminate(_Host, _ServerHost) -> ok. %% @spec () -> [Option] %% Option = mod_pubsub:nodetreeOption() %% @doc Returns the default pubsub node tree options. options() -> [{virtual_tree, false}, {odbc, true}]. %% @spec (Host, Node, From) -> pubsubNode() | {error, Reason} %% Host = mod_pubsub:host() %% Node = mod_pubsub:pubsubNode() get_node(Host, Node, _From) -> get_node(Host, Node). get_node(Host, Node) -> H = ?PUBSUB:escape(Host), N = ?PUBSUB:escape(?PUBSUB:node_to_string(Node)), case catch ejabberd_odbc:sql_query_t( ["select node, parent, type, nodeid " "from pubsub_node " "where host='", H, "' and node='", N, "';"]) of {selected, ["node", "parent", "type", "nodeid"], [RItem]} -> raw_to_node(Host, RItem); {'EXIT', _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; _ -> {error, ?ERR_ITEM_NOT_FOUND} end. get_node(NodeId) -> case catch ejabberd_odbc:sql_query_t( ["select host, node, parent, type " "from pubsub_node " "where nodeid='", NodeId, "';"]) of {selected, ["host", "node", "parent", "type"], [{Host, Node, Parent, Type}]} -> raw_to_node(Host, {Node, Parent, Type, NodeId}); {'EXIT', _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; _ -> {error, ?ERR_ITEM_NOT_FOUND} end. %% @spec (Host, From) -> [pubsubNode()] | {error, Reason} %% Host = mod_pubsub:host() | mod_pubsub:jid() get_nodes(Host, _From) -> get_nodes(Host). get_nodes(Host) -> H = ?PUBSUB:escape(Host), case catch ejabberd_odbc:sql_query_t( ["select node, parent, type, nodeid " "from pubsub_node " "where host='", H, "';"]) of {selected, ["node", "parent", "type", "nodeid"], RItems} -> lists:map(fun(Item) -> raw_to_node(Host, Item) end, RItems); _ -> [] end. %% @spec (Host, Node, From) -> [{Depth, Record}] | {error, Reason} %% Host = mod_pubsub:host() | mod_pubsub:jid() %% Node = mod_pubsub:pubsubNode() %% From = mod_pubsub:jid() %% Depth = integer() %% Record = pubsubNode() %% @doc

    Default node tree does not handle parents, return empty list.

    get_parentnodes(_Host, _Node, _From) -> []. %% @spec (Host, Node, From) -> [{Depth, Record}] | {error, Reason} %% Host = mod_pubsub:host() | mod_pubsub:jid() %% Node = mod_pubsub:pubsubNode() %% From = mod_pubsub:jid() %% Depth = integer() %% Record = pubsubNode() %% @doc

    Default node tree does not handle parents, return a list %% containing just this node.

    get_parentnodes_tree(Host, Node, From) -> case get_node(Host, Node, From) of N when is_record(N, pubsub_node) -> [{0, [N]}]; _Error -> [] end. get_subnodes(Host, Node, _From) -> get_subnodes(Host, Node). %% @spec (Host, Index) -> [pubsubNode()] | {error, Reason} %% Host = mod_pubsub:host() %% Node = mod_pubsub:pubsubNode() get_subnodes(Host, Node) -> H = ?PUBSUB:escape(Host), N = ?PUBSUB:escape(?PUBSUB:node_to_string(Node)), case catch ejabberd_odbc:sql_query_t( ["select node, parent, type, nodeid " "from pubsub_node " "where host='", H, "' and parent='", N, "';"]) of {selected, ["node", "parent", "type", "nodeid"], RItems} -> lists:map(fun(Item) -> raw_to_node(Host, Item) end, RItems); _ -> [] end. get_subnodes_tree(Host, Node, _From) -> get_subnodes_tree(Host, Node). %% @spec (Host, Index) -> [pubsubNode()] | {error, Reason} %% Host = mod_pubsub:host() %% Node = mod_pubsub:pubsubNode() get_subnodes_tree(Host, Node) -> H = ?PUBSUB:escape(Host), N = ?PUBSUB:escape(?PUBSUB:node_to_string(Node)), case catch ejabberd_odbc:sql_query_t( ["select node, parent, type, nodeid " "from pubsub_node " "where host='", H, "' and node like '", N, "%';"]) of {selected, ["node", "parent", "type", "nodeid"], RItems} -> lists:map(fun(Item) -> raw_to_node(Host, Item) end, RItems); _ -> [] end. %% @spec (Host, Node, Type, Owner, Options, Parents) -> ok | {error, Reason} %% Host = mod_pubsub:host() | mod_pubsub:jid() %% Node = mod_pubsub:pubsubNode() %% NodeType = mod_pubsub:nodeType() %% Owner = mod_pubsub:jid() %% Options = list() %% Parents = list() create_node(Host, Node, Type, Owner, Options, Parents) -> BJID = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), case nodeid(Host, Node) of {error, ?ERR_ITEM_NOT_FOUND} -> ParentExists = case Host of {_U, _S, _R} -> %% This is special case for PEP handling %% PEP does not uses hierarchy true; _ -> case Parents of [] -> true; [Parent|_] -> case nodeid(Host, Parent) of {result, PNodeId} -> case nodeowners(PNodeId) of [{[], Host, []}] -> true; Owners -> lists:member(BJID, Owners) end; _ -> false end; _ -> false end end, case ParentExists of true -> case set_node(#pubsub_node{ nodeid={Host, Node}, parents=Parents, type=Type, options=Options}) of {result, NodeId} -> {ok, NodeId}; Other -> Other end; false -> %% Requesting entity is prohibited from creating nodes {error, ?ERR_FORBIDDEN} end; {result, _} -> %% NodeID already exists {error, ?ERR_CONFLICT}; Error -> Error end. %% @spec (Host, Node) -> [mod_pubsub:node()] %% Host = mod_pubsub:host() | mod_pubsub:jid() %% Node = mod_pubsub:pubsubNode() delete_node(Host, Node) -> H = ?PUBSUB:escape(Host), N = ?PUBSUB:escape(?PUBSUB:node_to_string(Node)), Removed = get_subnodes_tree(Host, Node), catch ejabberd_odbc:sql_query_t( ["delete from pubsub_node " "where host='", H, "' and node like '", N, "%';"]), Removed. %% helpers raw_to_node(Host, {Node, Parent, Type, NodeId}) -> Options = case catch ejabberd_odbc:sql_query_t( ["select name,val " "from pubsub_node_option " "where nodeid='", NodeId, "';"]) of {selected, ["name", "val"], ROptions} -> DbOpts = lists:map(fun({Key, Value}) -> RKey = list_to_atom(Key), Tokens = element(2, erl_scan:string(Value++".")), RValue = element(2, erl_parse:parse_term(Tokens)), {RKey, RValue} end, ROptions), Module = list_to_atom(?PLUGIN_PREFIX++Type), StdOpts = Module:options(), lists:foldl(fun({Key, Value}, Acc)-> lists:keyreplace(Key, 1, Acc, {Key, Value}) end, StdOpts, DbOpts); _ -> [] end, #pubsub_node{ nodeid = {Host, ?PUBSUB:string_to_node(Node)}, parents = [?PUBSUB:string_to_node(Parent)], id = NodeId, type = Type, options = Options}. %% @spec (NodeRecord) -> ok | {error, Reason} %% Record = mod_pubsub:pubsub_node() set_node(Record) -> {Host, Node} = Record#pubsub_node.nodeid, Parent = case Record#pubsub_node.parents of [] -> <<>>; [First|_] -> First end, Type = Record#pubsub_node.type, H = ?PUBSUB:escape(Host), N = ?PUBSUB:escape(?PUBSUB:node_to_string(Node)), P = ?PUBSUB:escape(?PUBSUB:node_to_string(Parent)), NodeId = case nodeid(Host, Node) of {result, OldNodeId} -> catch ejabberd_odbc:sql_query_t( ["delete from pubsub_node_option " "where nodeid='", OldNodeId, "';"]), catch ejabberd_odbc:sql_query_t( ["update pubsub_node " "set host='", H, "' " "node='", N, "' " "parent='", P, "' " "type='", Type, "' " "where nodeid='", OldNodeId, "';"]), OldNodeId; _ -> catch ejabberd_odbc:sql_query_t( ["insert into pubsub_node(host, node, parent, type) " "values('", H, "', '", N, "', '", P, "', '", Type, "');"]), case nodeid(Host, Node) of {result, NewNodeId} -> NewNodeId; _ -> none % this should not happen end end, case NodeId of none -> {error, ?ERR_INTERNAL_SERVER_ERROR}; _ -> lists:foreach(fun({Key, Value}) -> SKey = atom_to_list(Key), SValue = ?PUBSUB:escape(lists:flatten(io_lib:fwrite("~p",[Value]))), catch ejabberd_odbc:sql_query_t( ["insert into pubsub_node_option(nodeid, name, val) " "values('", NodeId, "', '", SKey, "', '", SValue, "');"]) end, Record#pubsub_node.options), {result, NodeId} end. nodeid(Host, Node) -> H = ?PUBSUB:escape(Host), N = ?PUBSUB:escape(?PUBSUB:node_to_string(Node)), case catch ejabberd_odbc:sql_query_t( ["select nodeid " "from pubsub_node " "where host='", H, "' and node='", N, "';"]) of {selected, ["nodeid"], [{NodeId}]} -> {result, NodeId}; {'EXIT', _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; _ -> {error, ?ERR_ITEM_NOT_FOUND} end. nodeowners(NodeId) -> {result, Res} = node_hometree_odbc:get_node_affiliations(NodeId), lists:foldl(fun({LJID, owner}, Acc) -> [LJID|Acc]; (_, Acc) -> Acc end, [], Res). ejabberd-2.1.11/src/mod_pubsub/Makefile.win320000664000000000000000000000616712240230175015557 0ustar include ..\Makefile.inc EFLAGS = -I .. -pz .. OUTDIR = .. BEAMS = ..\gen_pubsub_node.beam ..\gen_pubsub_nodetree.beam ..\mod_pubsub.beam ..\mod_pubsub_odbc.beam ..\node_buddy.beam ..\node_club.beam ..\node_dag.beam ..\node_dispatch.beam ..\node_flat.beam ..\node_flat_odbc.beam ..\node_hometree.beam ..\node_hometree_odbc.beam ..\node_mb.beam ..\node_pep.beam ..\node_pep_odbc.beam ..\node_private.beam ..\node_public.beam ..\nodetree_dag.beam ..\nodetree_tree.beam ..\nodetree_tree_odbc.beam ..\nodetree_virtual.beam ..\pubsub_db_odbc.beam ..\pubsub_index.beam ..\pubsub_subscription.beam ..\pubsub_subscription_odbc.beam ALL : $(BEAMS) CLEAN : -@erase $(BEAMS) $(OUTDIR)\gen_pubsub_node.beam : gen_pubsub_node.erl erlc -W $(EFLAGS) -o $(OUTDIR) gen_pubsub_node.erl $(OUTDIR)\gen_pubsub_nodetree.beam : gen_pubsub_nodetree.erl erlc -W $(EFLAGS) -o $(OUTDIR) gen_pubsub_nodetree.erl $(OUTDIR)\mod_pubsub.beam : mod_pubsub.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_pubsub.erl $(OUTDIR)\mod_pubsub_odbc.beam : mod_pubsub_odbc.erl erlc -W $(EFLAGS) -o $(OUTDIR) mod_pubsub_odbc.erl $(OUTDIR)\node_buddy.beam : node_buddy.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_buddy.erl $(OUTDIR)\node_club.beam : node_club.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_club.erl $(OUTDIR)\node_dag.beam : node_dag.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_dag.erl $(OUTDIR)\node_dispatch.beam : node_dispatch.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_dispatch.erl $(OUTDIR)\node_flat.beam : node_flat.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_flat.erl $(OUTDIR)\node_flat_odbc.beam : node_flat_odbc.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_flat_odbc.erl $(OUTDIR)\node_hometree.beam : node_hometree.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_hometree.erl $(OUTDIR)\node_hometree_odbc.beam : node_hometree_odbc.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_hometree_odbc.erl $(OUTDIR)\node_mb.beam : node_mb.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_mb.erl $(OUTDIR)\node_pep.beam : node_pep.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_pep.erl $(OUTDIR)\node_pep_odbc.beam : node_pep_odbc.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_pep_odbc.erl $(OUTDIR)\node_private.beam : node_private.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_private.erl $(OUTDIR)\node_public.beam : node_public.erl erlc -W $(EFLAGS) -o $(OUTDIR) node_public.erl $(OUTDIR)\nodetree_dag.beam : nodetree_dag.erl erlc -W $(EFLAGS) -o $(OUTDIR) nodetree_dag.erl $(OUTDIR)\nodetree_tree.beam : nodetree_tree.erl erlc -W $(EFLAGS) -o $(OUTDIR) nodetree_tree.erl $(OUTDIR)\nodetree_tree_odbc.beam : nodetree_tree_odbc.erl erlc -W $(EFLAGS) -o $(OUTDIR) nodetree_tree_odbc.erl $(OUTDIR)\nodetree_virtual.beam : nodetree_virtual.erl erlc -W $(EFLAGS) -o $(OUTDIR) nodetree_virtual.erl $(OUTDIR)\pubsub_db_odbc.beam : pubsub_db_odbc.erl erlc -W $(EFLAGS) -o $(OUTDIR) pubsub_db_odbc.erl $(OUTDIR)\pubsub_index.beam : pubsub_index.erl erlc -W $(EFLAGS) -o $(OUTDIR) pubsub_index.erl $(OUTDIR)\pubsub_subscription.beam : pubsub_subscription.erl erlc -W $(EFLAGS) -o $(OUTDIR) pubsub_subscription.erl $(OUTDIR)\pubsub_subscription_odbc.beam : pubsub_subscription_odbc.erl erlc -W $(EFLAGS) -o $(OUTDIR) pubsub_subscription_odbc.erl ejabberd-2.1.11/src/mod_pubsub/node_mb.erl0000664000000000000000000001427112240230175015260 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Eric Cestari %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %%% @doc The module {@module} is the pep microblog PubSub plugin. %%%

    To be used, mod_pubsub must be configured : %%% {mod_pubsub, [ % requires mod_caps %%% {access_createnode, pubsub_createnode}, %%% {plugins, ["default", "pep","mb"]}, %%% {pep_mapping, [{"urn:xmpp:microblog", "mb"}]} %%% ]}, %%%

    %%%

    PubSub plugin nodes are using the {@link gen_pubsub_node} behaviour.

    -module(node_mb). -author('eric@ohmforce.com'). -include("ejabberd.hrl"). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_node). %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/6, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1 ]). init(Host, ServerHost, Opts) -> node_pep:init(Host, ServerHost, Opts). terminate(Host, ServerHost) -> node_pep:terminate(Host, ServerHost), ok. options() -> [{deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, false}, {purge_offline, false}, {persist_items, true}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, presence}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, on_sub_and_presence}, {deliver_notifications, true}, {presence_based_delivery, true}]. features() -> ["create-nodes", %* "auto-create", %* "auto-subscribe", %* "delete-nodes", %* "delete-items", %* "filtered-notifications", %* "modify-affiliations", "outcast-affiliation", "persistent-items", "publish", %* "purge-nodes", "retract-items", "retrieve-affiliations", "retrieve-items", %* "retrieve-subscriptions", "subscribe" %* ]. create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access) -> node_pep:create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access). create_node(NodeId, Owner) -> node_pep:create_node(NodeId, Owner). delete_node(Removed) -> node_pep:delete_node(Removed). subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> node_pep:subscribe_node( NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options). unsubscribe_node(NodeId, Sender, Subscriber, SubID) -> node_pep:unsubscribe_node(NodeId, Sender, Subscriber, SubID). publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) -> node_pep:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload). remove_extra_items(NodeId, MaxItems, ItemIds) -> node_pep:remove_extra_items(NodeId, MaxItems, ItemIds). delete_item(NodeId, Publisher, PublishModel, ItemId) -> node_pep:delete_item(NodeId, Publisher, PublishModel, ItemId). purge_node(NodeId, Owner) -> node_pep:purge_node(NodeId, Owner). get_entity_affiliations(Host, Owner) -> node_pep:get_entity_affiliations(Host, Owner). get_node_affiliations(NodeId) -> node_pep:get_node_affiliations(NodeId). get_affiliation(NodeId, Owner) -> node_pep:get_affiliation(NodeId, Owner). set_affiliation(NodeId, Owner, Affiliation) -> node_pep:set_affiliation(NodeId, Owner, Affiliation). get_entity_subscriptions(Host, Owner) -> node_pep:get_entity_subscriptions(Host, Owner). get_node_subscriptions(NodeId) -> node_pep:get_node_subscriptions(NodeId). get_subscriptions(NodeId, Owner) -> node_pep:get_subscriptions(NodeId, Owner). set_subscriptions(NodeId, Owner, Subscription, SubId) -> node_pep:set_subscriptions(NodeId, Owner, Subscription, SubId). get_pending_nodes(Host, Owner) -> node_hometree:get_pending_nodes(Host, Owner). get_states(NodeId) -> node_pep:get_states(NodeId). get_state(NodeId, JID) -> node_pep:get_state(NodeId, JID). set_state(State) -> node_pep:set_state(State). get_items(NodeId, From) -> node_pep:get_items(NodeId, From). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_pep:get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). get_item(NodeId, ItemId) -> node_pep:get_item(NodeId, ItemId). get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_pep:get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). set_item(Item) -> node_pep:set_item(Item). get_item_name(Host, Node, Id) -> node_pep:get_item_name(Host, Node, Id). node_to_path(Node) -> node_pep:node_to_path(Node). path_to_node(Path) -> node_pep:path_to_node(Path). ejabberd-2.1.11/src/mod_pubsub/node_hometree.erl0000664000000000000000000012122112240230175016464 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %%% @todo The item table should be handled by the plugin, but plugin that do %%% not want to manage it should be able to use the default behaviour. %%% @todo Plugin modules should be able to register to receive presence update %%% send to pubsub. %%% @doc The module {@module} is the default PubSub plugin. %%%

    It is used as a default for all unknown PubSub node type. It can serve %%% as a developer basis and reference to build its own custom pubsub node %%% types.

    %%%

    PubSub plugin nodes are using the {@link gen_node} behaviour.

    %%%

    The API isn't stabilized yet. The pubsub plugin %%% development is still a work in progress. However, the system is already %%% useable and useful as is. Please, send us comments, feedback and %%% improvements.

    -module(node_hometree). -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_node). %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/6, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1 ]). %% ================ %% API definition %% ================ %% @spec (Host, ServerHost, Options) -> ok %% Host = string() %% ServerHost = string() %% Options = [{atom(), term()}] %% @doc

    Called during pubsub modules initialisation. Any pubsub plugin must %% implement this function. It can return anything.

    %%

    This function is mainly used to trigger the setup task necessary for the %% plugin. It can be used for example by the developer to create the specific %% module database schema if it does not exists yet.

    init(_Host, _ServerHost, _Options) -> pubsub_subscription:init(), mnesia:create_table(pubsub_state, [{disc_copies, [node()]}, {attributes, record_info(fields, pubsub_state)}]), mnesia:create_table(pubsub_item, [{disc_only_copies, [node()]}, {attributes, record_info(fields, pubsub_item)}]), ItemsFields = record_info(fields, pubsub_item), case mnesia:table_info(pubsub_item, attributes) of ItemsFields -> ok; _ -> mnesia:transform_table(pubsub_item, ignore, ItemsFields) end, ok. %% @spec (Host, ServerHost) -> ok %% Host = string() %% ServerHost = string() %% @doc

    Called during pubsub modules termination. Any pubsub plugin must %% implement this function. It can return anything.

    terminate(_Host, _ServerHost) -> ok. %% @spec () -> Options %% Options = [mod_pubsub:nodeOption()] %% @doc Returns the default pubsub node options. %%

    Example of function return value:

    %% ``` %% [{deliver_payloads, true}, %% {notify_config, false}, %% {notify_delete, false}, %% {notify_retract, true}, %% {persist_items, true}, %% {max_items, 10}, %% {subscribe, true}, %% {access_model, open}, %% {publish_model, publishers}, %% {max_payload_size, 100000}, %% {send_last_published_item, never}, %% {presence_based_delivery, false}]''' options() -> [{deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, true}, {purge_offline, false}, {persist_items, true}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, open}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, on_sub_and_presence}, {deliver_notifications, true}, {presence_based_delivery, false}]. %% @spec () -> Features %% Features = [string()] %% @doc Returns the node features features() -> ["create-nodes", "auto-create", "access-authorize", "delete-nodes", "delete-items", "get-pending", "instant-nodes", "manage-subscriptions", "modify-affiliations", "multi-subscribe", "outcast-affiliation", "persistent-items", "publish", "purge-nodes", "retract-items", "retrieve-affiliations", "retrieve-items", "retrieve-subscriptions", "subscribe", "subscription-notifications", "subscription-options" ]. %% @spec (Host, ServerHost, NodeId, ParentNodeId, Owner, Access) -> {result, Allowed} %% Host = mod_pubsub:hostPubsub() %% ServerHost = string() %% NodeId = mod_pubsub:nodeId() %% ParentNodeId = mod_pubsub:nodeId() %% Owner = mod_pubsub:jid() %% Access = all | atom() %% Allowed = boolean() %% @doc Checks if the current user has the permission to create the requested node %%

    In {@link node_default}, the permission is decided by the place in the %% hierarchy where the user is creating the node. The access parameter is also %% checked in the default module. This parameter depends on the value of the %% access_createnode ACL value in ejabberd config file.

    %%

    This function also check that node can be created a a children of its %% parent node

    %%

    PubSub plugins can redefine the PubSub node creation rights as they %% which. They can simply delegate this check to the {@link node_default} %% module by implementing this function like this: %% ```check_create_user_permission(Host, ServerHost, NodeId, ParentNodeId, Owner, Access) -> %% node_default:check_create_user_permission(Host, ServerHost, NodeId, ParentNodeId, Owner, Access).'''

    create_node_permission(Host, ServerHost, NodeId, _ParentNodeId, Owner, Access) -> LOwner = jlib:jid_tolower(Owner), {User, Server, _Resource} = LOwner, Allowed = case LOwner of {"", Host, ""} -> true; % pubsub service always allowed _ -> case acl:match_rule(ServerHost, Access, LOwner) of allow -> case node_to_path(NodeId) of ["home", Server, User | _] -> true; _ -> false end; _ -> false end end, {result, Allowed}. %% @spec (NodeIdx, Owner) -> {result, {default, broadcast}} %% NodeIdx = mod_pubsub:nodeIdx() %% Owner = mod_pubsub:jid() %% @doc

    create_node(NodeIdx, Owner) -> OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), set_state(#pubsub_state{stateid = {OwnerKey, NodeIdx}, affiliation = owner}), {result, {default, broadcast}}. %% @spec (Nodes) -> {result, {default, broadcast, Reply}} %% Nodes = [mod_pubsub:pubsubNode()] %% Reply = [{mod_pubsub:pubsubNode(), %% [{mod_pubsub:ljid(), [{mod_pubsub:subscription(), mod_pubsub:subId()}]}]}] %% @doc

    purge items of deleted nodes after effective deletion.

    delete_node(Nodes) -> Tr = fun(#pubsub_state{stateid = {J, _}, subscriptions = Ss}) -> lists:map(fun(S) -> {J, S} end, Ss) end, Reply = lists:map( fun(#pubsub_node{id = NodeId} = PubsubNode) -> {result, States} = get_states(NodeId), lists:foreach( fun(#pubsub_state{stateid = {LJID, _}, items = Items}) -> del_items(NodeId, Items), del_state(NodeId, LJID) end, States), {PubsubNode, lists:flatmap(Tr, States)} end, Nodes), {result, {default, broadcast, Reply}}. %% @spec (NodeIdx, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> {error, Reason} | {result, Result} %% NodeIdx = mod_pubsub:nodeIdx() %% Sender = mod_pubsub:jid() %% Subscriber = mod_pubsub:jid() %% AccessModel = mod_pubsub:accessModel() %% SendLast = atom() %% PresenceSubscription = boolean() %% RosterGroup = boolean() %% Options = [mod_pubsub:nodeOption()] %% Reason = mod_pubsub:stanzaError() %% Result = {result, {default, subscribed, mod_pubsub:subId()}} %% | {result, {default, subscribed, mod_pubsub:subId(), send_last}} %% | {result, {default, pending, mod_pubsub:subId()}} %% %% @doc

    Accepts or rejects subcription requests on a PubSub node.

    %%

    The mechanism works as follow: %%

      %%
    • The main PubSub module prepares the subscription and passes the %% result of the preparation as a record.
    • %%
    • This function gets the prepared record and several other parameters and %% can decide to:
        %%
      • reject the subscription;
      • %%
      • allow it as is, letting the main module perform the database %% persistance;
      • %%
      • allow it, modifying the record. The main module will store the %% modified record;
      • %%
      • allow it, but perform the needed persistance operations.
      %%

    %%

    The selected behaviour depends on the return parameter: %%

      %%
    • {error, Reason}: an IQ error result will be returned. No %% subscription will actually be performed.
    • %%
    • true: Subscribe operation is allowed, based on the %% unmodified record passed in parameter SubscribeResult. If this %% parameter contains an error, no subscription will be performed.
    • %%
    • {true, PubsubState}: Subscribe operation is allowed, but %% the {@link mod_pubsub:pubsubState()} record returned replaces the value %% passed in parameter SubscribeResult.
    • %%
    • {true, done}: Subscribe operation is allowed, but the %% {@link mod_pubsub:pubsubState()} will be considered as already stored and %% no further persistance operation will be performed. This case is used, %% when the plugin module is doing the persistance by itself or when it want %% to completly disable persistance.
    %%

    %%

    In the default plugin module, the record is unchanged.

    subscribe_node(NodeIdx, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> SubKey = jlib:jid_tolower(Subscriber), GenKey = jlib:jid_remove_resource(SubKey), Authorized = (jlib:jid_tolower(jlib:jid_remove_resource(Sender)) == GenKey), GenState = get_state(NodeIdx, GenKey), SubState = case SubKey of GenKey -> GenState; _ -> get_state(NodeIdx, SubKey) end, Affiliation = GenState#pubsub_state.affiliation, Subscriptions = SubState#pubsub_state.subscriptions, Whitelisted = lists:member(Affiliation, [member, publisher, owner]), PendingSubscription = lists:any(fun({pending, _}) -> true; (_) -> false end, Subscriptions), if not Authorized -> %% JIDs do not match {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "invalid-jid")}; Affiliation == outcast -> %% Requesting entity is blocked {error, ?ERR_FORBIDDEN}; PendingSubscription -> %% Requesting entity has pending subscription {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "pending-subscription")}; (AccessModel == presence) and (not PresenceSubscription) -> %% Entity is not authorized to create a subscription (presence subscription required) {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")}; (AccessModel == roster) and (not RosterGroup) -> %% Entity is not authorized to create a subscription (not in roster group) {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")}; (AccessModel == whitelist) and (not Whitelisted) -> %% Node has whitelist access model and entity lacks required affiliation {error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")}; %%MustPay -> %% % Payment is required for a subscription %% {error, ?ERR_PAYMENT_REQUIRED}; %%ForbiddenAnonymous -> %% % Requesting entity is anonymous %% {error, ?ERR_FORBIDDEN}; true -> case pubsub_subscription:add_subscription(Subscriber, NodeIdx, Options) of SubId when is_list(SubId) -> NewSub = case AccessModel of authorize -> pending; _ -> subscribed end, set_state(SubState#pubsub_state{subscriptions = [{NewSub, SubId} | Subscriptions]}), case {NewSub, SendLast} of {subscribed, never} -> {result, {default, subscribed, SubId}}; {subscribed, _} -> {result, {default, subscribed, SubId, send_last}}; {_, _} -> {result, {default, pending, SubId}} end; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end end. %% @spec (NodeIdx, Sender, Subscriber, SubId) -> {error, Reason} | {result, default} %% NodeIdx = mod_pubsub:nodeIdx() %% Sender = mod_pubsub:jid() %% Subscriber = mod_pubsub:jid() %% SubId = mod_pubsub:subId() %% Reason = mod_pubsub:stanzaError() %% @doc

    Unsubscribe the Subscriber from the Node.

    unsubscribe_node(NodeIdx, Sender, Subscriber, SubId) -> SubKey = jlib:jid_tolower(Subscriber), GenKey = jlib:jid_remove_resource(SubKey), Authorized = (jlib:jid_tolower(jlib:jid_remove_resource(Sender)) == GenKey), GenState = get_state(NodeIdx, GenKey), SubState = case SubKey of GenKey -> GenState; _ -> get_state(NodeIdx, SubKey) end, Subscriptions = lists:filter(fun({_Sub, _SubId}) -> true; (_SubId) -> false end, SubState#pubsub_state.subscriptions), SubIdExists = case SubId of [] -> false; List when is_list(List) -> true; _ -> false end, if %% Requesting entity is prohibited from unsubscribing entity not Authorized -> {error, ?ERR_FORBIDDEN}; %% Entity did not specify SubId %%SubId == "", ?? -> %% {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")}; %% Invalid subscription identifier %%InvalidSubId -> %% {error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; %% Requesting entity is not a subscriber Subscriptions == [] -> {error, ?ERR_EXTENDED(?ERR_UNEXPECTED_REQUEST_CANCEL, "not-subscribed")}; %% Subid supplied, so use that. SubIdExists -> Sub = first_in_list(fun(S) -> case S of {_Sub, SubId} -> true; _ -> false end end, SubState#pubsub_state.subscriptions), case Sub of {value, S} -> delete_subscriptions(SubKey, NodeIdx, [S], SubState), {result, default}; false -> {error, ?ERR_EXTENDED(?ERR_UNEXPECTED_REQUEST_CANCEL, "not-subscribed")} end; %% Asking to remove all subscriptions to the given node SubId == all -> delete_subscriptions(SubKey, NodeIdx, Subscriptions, SubState), {result, default}; %% No subid supplied, but there's only one matching subscription length(Subscriptions) == 1 -> delete_subscriptions(SubKey, NodeIdx, Subscriptions, SubState), {result, default}; %% No subid and more than one possible subscription match. true -> {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")} end. delete_subscriptions(SubKey, NodeIdx, Subscriptions, SubState) -> NewSubs = lists:foldl(fun({Subscription, SubId}, Acc) -> pubsub_subscription:delete_subscription(SubKey, NodeIdx, SubId), Acc -- [{Subscription, SubId}] end, SubState#pubsub_state.subscriptions, Subscriptions), case {SubState#pubsub_state.affiliation, NewSubs} of {none, []} -> % Just a regular subscriber, and this is final item, so % delete the state. del_state(NodeIdx, SubKey); _ -> set_state(SubState#pubsub_state{subscriptions = NewSubs}) end. %% @spec (NodeIdx, Publisher, PublishModel, MaxItems, ItemId, Payload) -> %% {result, {default, broadcast, ItemIds}} | {error, Reason} %% NodeIdx = mod_pubsub:nodeIdx() %% Publisher = mod_pubsub:jid() %% PublishModel = atom() %% MaxItems = integer() %% ItemId = mod_pubsub:itemId() %% Payload = mod_pubsub:payload() %% ItemIds = [mod_pubsub:itemId()] | [] %% Reason = mod_pubsub:stanzaError() %% @doc

    Publishes the item passed as parameter.

    %%

    The mechanism works as follow: %%

      %%
    • The main PubSub module prepares the item to publish and passes the %% result of the preparation as a {@link mod_pubsub:pubsubItem()} record.
    • %%
    • This function gets the prepared record and several other parameters and can decide to:
        %%
      • reject the publication;
      • %%
      • allow the publication as is, letting the main module perform the database persistance;
      • %%
      • allow the publication, modifying the record. The main module will store the modified record;
      • %%
      • allow it, but perform the needed persistance operations.
      %%

    %%

    The selected behaviour depends on the return parameter: %%

      %%
    • {error, Reason}: an iq error result will be return. No %% publication is actually performed.
    • %%
    • true: Publication operation is allowed, based on the %% unmodified record passed in parameter Item. If the Item %% parameter contains an error, no subscription will actually be %% performed.
    • %%
    • {true, Item}: Publication operation is allowed, but the %% {@link mod_pubsub:pubsubItem()} record returned replaces the value passed %% in parameter Item. The persistance will be performed by the main %% module.
    • %%
    • {true, done}: Publication operation is allowed, but the %% {@link mod_pubsub:pubsubItem()} will be considered as already stored and %% no further persistance operation will be performed. This case is used, %% when the plugin module is doing the persistance by itself or when it want %% to completly disable persistance.
    %%

    %%

    In the default plugin module, the record is unchanged.

    publish_item(NodeIdx, Publisher, PublishModel, MaxItems, ItemId, Payload) -> SubKey = jlib:jid_tolower(Publisher), GenKey = jlib:jid_remove_resource(SubKey), GenState = get_state(NodeIdx, GenKey), SubState = case SubKey of GenKey -> GenState; _ -> get_state(NodeIdx, SubKey) end, Affiliation = GenState#pubsub_state.affiliation, Subscribed = case PublishModel of subscribers -> is_subscribed(SubState#pubsub_state.subscriptions); _ -> undefined end, if not ((PublishModel == open) or ((PublishModel == publishers) and ((Affiliation == owner) or (Affiliation == publisher))) or (Subscribed == true)) -> %% Entity does not have sufficient privileges to publish to node {error, ?ERR_FORBIDDEN}; true -> %% TODO: check creation, presence, roster if MaxItems > 0 -> Now = now(), PubId = {Now, SubKey}, Item = case get_item(NodeIdx, ItemId) of {result, OldItem} -> OldItem#pubsub_item{modification = PubId, payload = Payload}; _ -> #pubsub_item{itemid = {ItemId, NodeIdx}, creation = {Now, GenKey}, modification = PubId, payload = Payload} end, Items = [ItemId | GenState#pubsub_state.items--[ItemId]], {result, {NI, OI}} = remove_extra_items(NodeIdx, MaxItems, Items), set_item(Item), set_state(GenState#pubsub_state{items = NI}), {result, {default, broadcast, OI}}; true -> {result, {default, broadcast, []}} end end. %% @spec (NodeIdx, MaxItems, ItemIds) -> {result, {NewItemIds,OldItemIds}} %% NodeIdx = mod_pubsub:nodeIdx() %% MaxItems = integer() | unlimited %% ItemIds = [mod_pubsub:itemId()] %% NewItemIds = [mod_pubsub:itemId()] %% OldItemIds = [mod_pubsub:itemId()] | [] %% @doc

    This function is used to remove extra items, most notably when the %% maximum number of items has been reached.

    %%

    This function is used internally by the core PubSub module, as no %% permission check is performed.

    %%

    In the default plugin module, the oldest items are removed, but other %% rules can be used.

    %%

    If another PubSub plugin wants to delegate the item removal (and if the %% plugin is using the default pubsub storage), it can implements this function like this: %% ```remove_extra_items(NodeIdx, MaxItems, ItemIds) -> %% node_default:remove_extra_items(NodeIdx, MaxItems, ItemIds).'''

    remove_extra_items(_NodeIdx, unlimited, ItemIds) -> {result, {ItemIds, []}}; remove_extra_items(NodeIdx, MaxItems, ItemIds) -> NewItems = lists:sublist(ItemIds, MaxItems), OldItems = lists:nthtail(length(NewItems), ItemIds), %% Remove extra items: del_items(NodeIdx, OldItems), %% Return the new items list: {result, {NewItems, OldItems}}. %% @spec (NodeIdx, Publisher, PublishModel, ItemId) -> %% {result, {default, broadcast}} | {error, Reason} %% NodeIdx = mod_pubsub:nodeIdx() %% Publisher = mod_pubsub:jid() %% PublishModel = atom() %% ItemId = mod_pubsub:itemId() %% Reason = mod_pubsub:stanzaError() %% @doc

    Triggers item deletion.

    %%

    Default plugin: The user performing the deletion must be the node owner %% or a publisher, or PublishModel being open.

    delete_item(NodeIdx, Publisher, PublishModel, ItemId) -> SubKey = jlib:jid_tolower(Publisher), GenKey = jlib:jid_remove_resource(SubKey), GenState = get_state(NodeIdx, GenKey), #pubsub_state{affiliation = Affiliation, items = Items} = GenState, Allowed = (Affiliation == publisher) orelse (Affiliation == owner) orelse (PublishModel == open) orelse case get_item(NodeIdx, ItemId) of {result, #pubsub_item{creation = {_, GenKey}}} -> true; _ -> false end, if not Allowed -> %% Requesting entity does not have sufficient privileges {error, ?ERR_FORBIDDEN}; true -> case lists:member(ItemId, Items) of true -> del_item(NodeIdx, ItemId), set_state(GenState#pubsub_state{items = lists:delete(ItemId, Items)}), {result, {default, broadcast}}; false -> case Affiliation of owner -> %% Owner can delete any items from its own node {result, States} = get_states(NodeIdx), lists:foldl( fun(#pubsub_state{items = PI} = S, Res) -> case lists:member(ItemId, PI) of true -> del_item(NodeIdx, ItemId), set_state(S#pubsub_state{items = lists:delete(ItemId, PI)}), {result, {default, broadcast}}; false -> Res end; (_, Res) -> Res end, {error, ?ERR_ITEM_NOT_FOUND}, States); _ -> %% Non-existent node or item {error, ?ERR_ITEM_NOT_FOUND} end end end. %% @spec (NodeIdx, Owner) -> {error, Reason} | {result, {default, broadcast}} %% NodeIdx = mod_pubsub:nodeIdx() %% Owner = mod_pubsub:jid() %% Reason = mod_pubsub:stanzaError() purge_node(NodeIdx, Owner) -> SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), GenState = get_state(NodeIdx, GenKey), case GenState of #pubsub_state{affiliation = owner} -> {result, States} = get_states(NodeIdx), lists:foreach( fun(#pubsub_state{items = []}) -> ok; (#pubsub_state{items = Items} = S) -> del_items(NodeIdx, Items), set_state(S#pubsub_state{items = []}) end, States), {result, {default, broadcast}}; _ -> %% Entity is not owner {error, ?ERR_FORBIDDEN} end. %% @spec (Host, Owner) -> {result, Reply} %% Host = mod_pubsub:hostPubsub() %% Owner = mod_pubsub:jid() %% Reply = [] | [{mod_pubsub:pubsubNode(), mod_pubsub:affiliation()}] %% @doc

    Return the current affiliations for the given user

    %%

    The default module reads affiliations in the main Mnesia %% pubsub_state table. If a plugin stores its data in the same %% table, it should return an empty list, as the affiliation will be read by %% the default PubSub module. Otherwise, it should return its own affiliation, %% that will be added to the affiliation stored in the main %% pubsub_state table.

    get_entity_affiliations(Host, Owner) -> SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), States = mnesia:match_object(#pubsub_state{stateid = {GenKey, '_'}, _ = '_'}), NodeTree = case catch ets:lookup(gen_mod:get_module_proc(Host, config), nodetree) of [{nodetree, N}] -> N; _ -> nodetree_tree end, Reply = lists:foldl(fun(#pubsub_state{stateid = {_, N}, affiliation = A}, Acc) -> case NodeTree:get_node(N) of #pubsub_node{nodeid = {Host, _}} = Node -> [{Node, A}|Acc]; _ -> Acc end end, [], States), {result, Reply}. get_node_affiliations(NodeId) -> {result, States} = get_states(NodeId), Tr = fun(#pubsub_state{stateid = {J, _}, affiliation = A}) -> {J, A} end, {result, lists:map(Tr, States)}. get_affiliation(NodeId, Owner) -> SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), GenState = get_state(NodeId, GenKey), {result, GenState#pubsub_state.affiliation}. set_affiliation(NodeId, Owner, Affiliation) -> SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), GenState = get_state(NodeId, GenKey), case {Affiliation, GenState#pubsub_state.subscriptions} of {none, none} -> del_state(NodeId, GenKey); _ -> set_state(GenState#pubsub_state{affiliation = Affiliation}) end. %% @spec (Host, Owner) -> %% {'result', [] %% | [{Node, Subscription, SubId, Entity}] %% | [{Node, Subscription, Entity}]} %% Host = mod_pubsub:hostPubsub() %% Owner = mod_pubsub:jid() %% Node = mod_pubsub:pubsubNode() %% Subscription = mod_pubsub:subscription() %% SubId = mod_pubsub:subId() %% Entity = mod_pubsub:ljid() %% @doc

    Return the current subscriptions for the given user

    %%

    The default module reads subscriptions in the main Mnesia %% pubsub_state table. If a plugin stores its data in the same %% table, it should return an empty list, as the affiliation will be read by %% the default PubSub module. Otherwise, it should return its own affiliation, %% that will be added to the affiliation stored in the main %% pubsub_state table.

    get_entity_subscriptions(Host, Owner) -> {U, D, _} = SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), States = case SubKey of GenKey -> mnesia:match_object( #pubsub_state{stateid = {{U, D, '_'}, '_'}, _ = '_'}); _ -> mnesia:match_object( #pubsub_state{stateid = {GenKey, '_'}, _ = '_'}) ++ mnesia:match_object( #pubsub_state{stateid = {SubKey, '_'}, _ = '_'}) end, NodeTree = case catch ets:lookup(gen_mod:get_module_proc(Host, config), nodetree) of [{nodetree, N}] -> N; _ -> nodetree_tree end, Reply = lists:foldl(fun(#pubsub_state{stateid = {J, N}, subscriptions = Ss}, Acc) -> case NodeTree:get_node(N) of #pubsub_node{nodeid = {Host, _}} = Node -> lists:foldl(fun({Sub, SubId}, Acc2) -> [{Node, Sub, SubId, J} | Acc2]; (S, Acc2) -> [{Node, S, J} | Acc2] end, Acc, Ss); _ -> Acc end end, [], States), {result, Reply}. get_node_subscriptions(NodeId) -> {result, States} = get_states(NodeId), Tr = fun(#pubsub_state{stateid = {J, _}, subscriptions = Subscriptions}) -> %% TODO: get rid of cases to handle non-list subscriptions case Subscriptions of [_|_] -> lists:foldl(fun({S, SubId}, Acc) -> [{J, S, SubId} | Acc]; (S, Acc) -> [{J, S} | Acc] end, [], Subscriptions); [] -> []; _ -> [{J, none}] end end, {result, lists:flatmap(Tr, States)}. get_subscriptions(NodeId, Owner) -> SubKey = jlib:jid_tolower(Owner), SubState = get_state(NodeId, SubKey), {result, SubState#pubsub_state.subscriptions}. set_subscriptions(NodeId, Owner, Subscription, SubId) -> SubKey = jlib:jid_tolower(Owner), SubState = get_state(NodeId, SubKey), case {SubId, SubState#pubsub_state.subscriptions} of {_, []} -> case Subscription of none -> {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "not-subscribed")}; _ -> new_subscription(NodeId, Owner, Subscription, SubState) end; {"", [{_, SID}]} -> case Subscription of none -> unsub_with_subid(NodeId, SID, SubState); _ -> replace_subscription({Subscription, SID}, SubState) end; {"", [_|_]} -> {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")}; _ -> case Subscription of none -> unsub_with_subid(NodeId, SubId, SubState); _ -> replace_subscription({Subscription, SubId}, SubState) end end. replace_subscription(NewSub, SubState) -> NewSubs = replace_subscription(NewSub, SubState#pubsub_state.subscriptions, []), set_state(SubState#pubsub_state{subscriptions = NewSubs}). replace_subscription(_, [], Acc) -> Acc; replace_subscription({Sub, SubId}, [{_, SubID} | T], Acc) -> replace_subscription({Sub, SubId}, T, [{Sub, SubID} | Acc]). new_subscription(NodeId, Owner, Subscription, SubState) -> SubId = pubsub_subscription:add_subscription(Owner, NodeId, []), Subscriptions = SubState#pubsub_state.subscriptions, set_state(SubState#pubsub_state{subscriptions = [{Subscription, SubId} | Subscriptions]}), {Subscription, SubId}. unsub_with_subid(NodeId, SubId, SubState) -> pubsub_subscription:delete_subscription(SubState#pubsub_state.stateid, NodeId, SubId), NewSubs = lists:filter(fun ({_, SID}) -> SubId =/= SID end, SubState#pubsub_state.subscriptions), case {NewSubs, SubState#pubsub_state.affiliation} of {[], none} -> del_state(NodeId, element(1, SubState#pubsub_state.stateid)); _ -> set_state(SubState#pubsub_state{subscriptions = NewSubs}) end. %% TODO : doc %% @spec (Host, Owner) -> {result, Reply} | {error, Reason} %% Host = mod_pubsub:hostPubsub() %% Owner = mod_pubsub:jid() %% Reply = [] | [mod_pubsub:nodeId()] %% @doc

    Returns a list of Owner's nodes on Host with pending %% subscriptions.

    get_pending_nodes(Host, Owner) -> GenKey = jlib:jid_remove_resource(jlib:jid_tolower(Owner)), States = mnesia:match_object(#pubsub_state{stateid = {GenKey, '_'}, affiliation = owner, _ = '_'}), NodeIDs = [ID || #pubsub_state{stateid = {_, ID}} <- States], NodeTree = case catch ets:lookup(gen_mod:get_module_proc(Host, config), nodetree) of [{nodetree, N}] -> N; _ -> nodetree_tree end, Reply = mnesia:foldl(fun(#pubsub_state{stateid = {_, NID}} = S, Acc) -> case lists:member(NID, NodeIDs) of true -> case get_nodes_helper(NodeTree, S) of {value, Node} -> [Node | Acc]; false -> Acc end; false -> Acc end end, [], pubsub_state), {result, Reply}. get_nodes_helper(NodeTree, #pubsub_state{stateid = {_, N}, subscriptions = Subs}) -> HasPending = fun ({pending, _}) -> true; (pending) -> true; (_) -> false end, case lists:any(HasPending, Subs) of true -> case NodeTree:get_node(N) of #pubsub_node{nodeid = {_, Node}} -> {value, Node}; _ -> false end; false -> false end. %% @spec (NodeIdx) -> {result, States} %% NodeIdx = mod_pubsub:nodeIdx() %% States = [] | [mod_pubsub:pubsubState()] %% @doc Returns the list of stored states for a given node. %%

    For the default PubSub module, states are stored in Mnesia database.

    %%

    We can consider that the pubsub_state table have been created by the main %% mod_pubsub module.

    %%

    PubSub plugins can store the states where they wants (for example in a %% relational database).

    %%

    If a PubSub plugin wants to delegate the states storage to the default node, %% they can implement this function like this: %% ```get_states(NodeIdx) -> %% node_default:get_states(NodeIdx).'''

    get_states(NodeIdx) -> States = case catch mnesia:match_object( #pubsub_state{stateid = {'_', NodeIdx}, _ = '_'}) of List when is_list(List) -> List; _ -> [] end, {result, States}. %% @spec (NodeIdx, JID) -> State %% NodeIdx = mod_pubsub:nodeIdx() %% JID = mod_pubsub:jid() %% State = mod_pubsub:pubsubState() %% @doc

    Returns a state (one state list), given its reference.

    get_state(NodeIdx, JID) -> StateId = {JID, NodeIdx}, case catch mnesia:read({pubsub_state, StateId}) of [State] when is_record(State, pubsub_state) -> State; _ -> #pubsub_state{stateid=StateId} end. %% @spec (State) -> ok | {error, Reason} %% State = mod_pubsub:pubsubState() %% Reason = mod_pubsub:stanzaError() %% @doc

    Write a state into database.

    set_state(State) when is_record(State, pubsub_state) -> mnesia:write(State); set_state(_) -> {error, ?ERR_INTERNAL_SERVER_ERROR}. %% @spec (NodeIdx, JID) -> ok | {error, Reason} %% NodeIdx = mod_pubsub:nodeIdx() %% JID = mod_pubsub:jid() %% Reason = mod_pubsub:stanzaError() %% @doc

    Delete a state from database.

    del_state(NodeIdx, JID) -> mnesia:delete({pubsub_state, {JID, NodeIdx}}). %% @spec (NodeIdx, From) -> {result, Items} %% NodeIdx = mod_pubsub:nodeIdx() %% From = mod_pubsub:jid() %% Items = [] | [mod_pubsub:pubsubItem()] %% @doc Returns the list of stored items for a given node. %%

    For the default PubSub module, items are stored in Mnesia database.

    %%

    We can consider that the pubsub_item table have been created by the main %% mod_pubsub module.

    %%

    PubSub plugins can store the items where they wants (for example in a %% relational database), or they can even decide not to persist any items.

    %%

    If a PubSub plugin wants to delegate the item storage to the default node, %% they can implement this function like this: %% ```get_items(NodeIdx, From) -> %% node_default:get_items(NodeIdx, From).'''

    get_items(NodeIdx, _From) -> Items = mnesia:match_object(#pubsub_item{itemid = {'_', NodeIdx}, _ = '_'}), {result, lists:reverse(lists:keysort(#pubsub_item.modification, Items))}. get_items(NodeIdx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) -> SubKey = jlib:jid_tolower(JID), GenKey = jlib:jid_remove_resource(SubKey), GenState = get_state(NodeIdx, GenKey), SubState = get_state(NodeIdx, SubKey), Affiliation = GenState#pubsub_state.affiliation, Subscriptions = SubState#pubsub_state.subscriptions, Whitelisted = can_fetch_item(Affiliation, Subscriptions), if %%SubId == "", ?? -> %% Entity has multiple subscriptions to the node but does not specify a subscription ID %{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")}; %%InvalidSubId -> %% Entity is subscribed but specifies an invalid subscription ID %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; GenState#pubsub_state.affiliation == outcast -> %% Requesting entity is blocked {error, ?ERR_FORBIDDEN}; (AccessModel == presence) and (not PresenceSubscription) -> %% Entity is not authorized to create a subscription (presence subscription required) {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")}; (AccessModel == roster) and (not RosterGroup) -> %% Entity is not authorized to create a subscription (not in roster group) {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")}; (AccessModel == whitelist) and (not Whitelisted) -> %% Node has whitelist access model and entity lacks required affiliation {error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")}; (AccessModel == authorize) and (not Whitelisted) -> %% Node has authorize access model {error, ?ERR_FORBIDDEN}; %%MustPay -> %% % Payment is required for a subscription %% {error, ?ERR_PAYMENT_REQUIRED}; true -> get_items(NodeIdx, JID) end. %% @spec (NodeIdx, ItemId) -> {result, Item} | {error, 'item-not-found'} %% NodeIdx = mod_pubsub:nodeIdx() %% ItemId = mod_pubsub:itemId() %% Item = mod_pubsub:pubsubItem() %% @doc

    Returns an item (one item list), given its reference.

    get_item(NodeIdx, ItemId) -> case mnesia:read({pubsub_item, {ItemId, NodeIdx}}) of [Item] when is_record(Item, pubsub_item) -> {result, Item}; _ -> {error, ?ERR_ITEM_NOT_FOUND} end. %% @spec (NodeIdx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> {result, Item} | {error, Reason} %% NodeIdx = mod_pubsub:nodeIdx() %% ItemId = mod_pubsub:itemId() %% JID = mod_pubsub:jid() %% AccessModel = mod_pubsub:accessModel() %% PresenceSubscription = boolean() %% RosterGroup = boolean() %% SubId = mod_pubsub:subId() %% Item = mod_pubsub:pubsubItem() %% Reason = mod_pubsub:stanzaError() | 'item-not-found' get_item(NodeIdx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) -> SubKey = jlib:jid_tolower(JID), GenKey = jlib:jid_remove_resource(SubKey), GenState = get_state(NodeIdx, GenKey), Affiliation = GenState#pubsub_state.affiliation, Subscriptions = GenState#pubsub_state.subscriptions, Whitelisted = can_fetch_item(Affiliation, Subscriptions), if %%SubId == "", ?? -> %% Entity has multiple subscriptions to the node but does not specify a subscription ID %{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")}; %%InvalidSubId -> %% Entity is subscribed but specifies an invalid subscription ID %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; GenState#pubsub_state.affiliation == outcast -> %% Requesting entity is blocked {error, ?ERR_FORBIDDEN}; (AccessModel == presence) and (not PresenceSubscription) -> %% Entity is not authorized to create a subscription (presence subscription required) {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")}; (AccessModel == roster) and (not RosterGroup) -> %% Entity is not authorized to create a subscription (not in roster group) {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")}; (AccessModel == whitelist) and (not Whitelisted) -> %% Node has whitelist access model and entity lacks required affiliation {error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")}; (AccessModel == authorize) and (not Whitelisted) -> %% Node has authorize access model {error, ?ERR_FORBIDDEN}; %%MustPay -> %% % Payment is required for a subscription %% {error, ?ERR_PAYMENT_REQUIRED}; true -> get_item(NodeIdx, ItemId) end. %% @spec (Item) -> ok | {error, Reason} %% Item = mod_pubsub:pubsubItem() %% Reason = mod_pubsub:stanzaError() %% @doc

    Write an item into database.

    set_item(Item) when is_record(Item, pubsub_item) -> mnesia:write(Item); set_item(_) -> {error, ?ERR_INTERNAL_SERVER_ERROR}. %% @spec (NodeIdx, ItemId) -> ok | {error, Reason} %% NodeIdx = mod_pubsub:nodeIdx() %% ItemId = mod_pubsub:itemId() %% Reason = mod_pubsub:stanzaError() %% @doc

    Delete an item from database.

    del_item(NodeIdx, ItemId) -> mnesia:delete({pubsub_item, {ItemId, NodeIdx}}). del_items(NodeIdx, ItemIds) -> lists:foreach(fun(ItemId) -> del_item(NodeIdx, ItemId) end, ItemIds). %% @doc

    Return the name of the node if known: Default is to return %% node id.

    get_item_name(_Host, _Node, Id) -> Id. node_to_path(Node) -> string:tokens(binary_to_list(Node), "/"). path_to_node([]) -> <<>>; path_to_node(Path) -> list_to_binary(string:join([""|Path], "/")). %% @spec (Affiliation, Subscription) -> true | false %% Affiliation = owner | member | publisher | outcast | none %% Subscription = subscribed | none %% @doc Determines if the combination of Affiliation and Subscribed %% are allowed to get items from a node. can_fetch_item(owner, _) -> true; can_fetch_item(member, _) -> true; can_fetch_item(publisher, _) -> true; can_fetch_item(outcast, _) -> false; can_fetch_item(none, Subscriptions) -> is_subscribed(Subscriptions); can_fetch_item(_Affiliation, _Subscription) -> false. is_subscribed(Subscriptions) -> lists:any(fun ({subscribed, _SubId}) -> true; (_) -> false end, Subscriptions). %% Returns the first item where Pred() is true in List first_in_list(_Pred, []) -> false; first_in_list(Pred, [H | T]) -> case Pred(H) of true -> {value, H}; _ -> first_in_list(Pred, T) end. ejabberd-2.1.11/src/mod_pubsub/pubsub_index.erl0000664000000000000000000000401712240230175016341 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %% important note: %% new/1 and free/2 MUST be called inside a transaction bloc -module(pubsub_index). -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -export([init/3, new/1, free/2]). init(_Host, _ServerHost, _Opts) -> mnesia:create_table(pubsub_index, [{disc_copies, [node()]}, {attributes, record_info(fields, pubsub_index)}]). new(Index) -> case mnesia:read({pubsub_index, Index}) of [I] -> case I#pubsub_index.free of [] -> Id = I#pubsub_index.last + 1, mnesia:write(I#pubsub_index{last = Id}), Id; [Id|Free] -> mnesia:write(I#pubsub_index{free = Free}), Id end; _ -> mnesia:write(#pubsub_index{index = Index, last = 1, free = []}), 1 end. free(Index, Id) -> case mnesia:read({pubsub_index, Index}) of [I] -> Free = I#pubsub_index.free, mnesia:write(I#pubsub_index{free = [Id|Free]}); _ -> ok end. ejabberd-2.1.11/src/mod_pubsub/node_public.erl0000664000000000000000000001441712240230175016142 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(node_public). -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_node). %% Note on function definition %% included is all defined plugin function %% it's possible not to define some function at all %% in that case, warning will be generated at compilation %% and function call will fail, %% then mod_pubsub will call function from node_hometree %% (this makes code cleaner, but execution a little bit longer) %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/6, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1 ]). init(Host, ServerHost, Opts) -> node_hometree:init(Host, ServerHost, Opts). terminate(Host, ServerHost) -> node_hometree:terminate(Host, ServerHost). options() -> [{deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, true}, {purge_offline, false}, {persist_items, true}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, open}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, never}, {deliver_notifications, true}, {presence_based_delivery, false}]. features() -> ["create-nodes", "delete-nodes", "delete-items", "instant-nodes", "outcast-affiliation", "persistent-items", "publish", "purge-nodes", "retract-items", "retrieve-affiliations", "retrieve-items", "retrieve-subscriptions", "subscribe", "subscription-notifications" ]. create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access) -> node_hometree:create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access). create_node(NodeId, Owner) -> node_hometree:create_node(NodeId, Owner). delete_node(Removed) -> node_hometree:delete_node(Removed). subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> node_hometree:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options). unsubscribe_node(NodeId, Sender, Subscriber, SubID) -> node_hometree:unsubscribe_node(NodeId, Sender, Subscriber, SubID). publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) -> node_hometree:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload). remove_extra_items(NodeId, MaxItems, ItemIds) -> node_hometree:remove_extra_items(NodeId, MaxItems, ItemIds). delete_item(NodeId, Publisher, PublishModel, ItemId) -> node_hometree:delete_item(NodeId, Publisher, PublishModel, ItemId). purge_node(NodeId, Owner) -> node_hometree:purge_node(NodeId, Owner). get_entity_affiliations(Host, Owner) -> node_hometree:get_entity_affiliations(Host, Owner). get_node_affiliations(NodeId) -> node_hometree:get_node_affiliations(NodeId). get_affiliation(NodeId, Owner) -> node_hometree:get_affiliation(NodeId, Owner). set_affiliation(NodeId, Owner, Affiliation) -> node_hometree:set_affiliation(NodeId, Owner, Affiliation). get_entity_subscriptions(Host, Owner) -> node_hometree:get_entity_subscriptions(Host, Owner). get_node_subscriptions(NodeId) -> node_hometree:get_node_subscriptions(NodeId). get_subscriptions(NodeId, Owner) -> node_hometree:get_subscriptions(NodeId, Owner). set_subscriptions(NodeId, Owner, Subscription, SubId) -> node_hometree:set_subscriptions(NodeId, Owner, Subscription, SubId). get_pending_nodes(Host, Owner) -> node_hometree:get_pending_nodes(Host, Owner). get_states(NodeId) -> node_hometree:get_states(NodeId). get_state(NodeId, JID) -> node_hometree:get_state(NodeId, JID). set_state(State) -> node_hometree:set_state(State). get_items(NodeId, From) -> node_hometree:get_items(NodeId, From). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). get_item(NodeId, ItemId) -> node_hometree:get_item(NodeId, ItemId). get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). set_item(Item) -> node_hometree:set_item(Item). %% @doc

    Return the name of the node if known: Default is to return %% node id.

    get_item_name(Host, Node, Id) -> node_hometree:get_item_name(Host, Node, Id). node_to_path(Node) -> node_flat:node_to_path(Node). path_to_node(Path) -> node_flat:path_to_node(Path). ejabberd-2.1.11/src/mod_pubsub/pubsub_db_odbc.erl0000664000000000000000000001143612240230175016611 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% @author Pablo Polvorin %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(pubsub_db_odbc). -author("pablo.polvorin@process-one.net"). -include("pubsub.hrl"). -export([add_subscription/1, read_subscription/1, delete_subscription/1, update_subscription/1]). %% TODO: Those -spec lines produce errors in old Erlang versions. %% They can be enabled again in ejabberd 3.0 because it uses R12B or higher. %% -spec read_subscription(SubID :: string()) -> {ok, #pubsub_subscription{}} | notfound. read_subscription(SubID) -> case ejabberd_odbc:sql_query_t( ["select opt_name, opt_value " "from pubsub_subscription_opt " "where subid = '", ejabberd_odbc:escape(SubID), "'"]) of {selected, ["opt_name", "opt_value"], []} -> notfound; {selected, ["opt_name", "opt_value"], Options} -> {ok, #pubsub_subscription{subid = SubID, options = lists:map(fun subscription_opt_from_odbc/1, Options)}} end. %% -spec delete_subscription(SubID :: string()) -> ok. delete_subscription(SubID) -> ejabberd_odbc:sql_query_t(["delete from pubsub_subscription_opt " "where subid = '", ejabberd_odbc:escape(SubID), "'"]), ok. %% -spec update_subscription(#pubsub_subscription{}) -> ok . update_subscription(#pubsub_subscription{subid = SubId} = Sub) -> delete_subscription(SubId), add_subscription(Sub). %% -spec add_subscription(#pubsub_subscription{}) -> ok. add_subscription(#pubsub_subscription{subid = SubId, options = Opts}) -> EscapedSubId = ejabberd_odbc:escape(SubId), lists:foreach(fun(Opt) -> {OdbcOptName, OdbcOptValue} = subscription_opt_to_odbc(Opt), ejabberd_odbc:sql_query_t( ["insert into pubsub_subscription_opt(subid, opt_name, opt_value)" "values ('", EscapedSubId, "','", OdbcOptName, "','", OdbcOptValue, "')"]) end, Opts), ok. %% -------------- Internal utilities ----------------------- subscription_opt_from_odbc({"DELIVER", Value}) -> {deliver, odbc_to_boolean(Value)}; subscription_opt_from_odbc({"DIGEST", Value}) -> {digest, odbc_to_boolean(Value)}; subscription_opt_from_odbc({"DIGEST_FREQUENCY", Value}) -> {digest_frequency, odbc_to_integer(Value)}; subscription_opt_from_odbc({"EXPIRE", Value}) -> {expire, odbc_to_timestamp(Value)}; subscription_opt_from_odbc({"INCLUDE_BODY", Value}) -> {include_body, odbc_to_boolean(Value)}; %%TODO: might be > than 1 show_values value??. %% need to use compact all in only 1 opt. subscription_opt_from_odbc({"SHOW_VALUES", Value}) -> {show_values, Value}; subscription_opt_from_odbc({"SUBSCRIPTION_TYPE", Value}) -> {subscription_type, case Value of "items" -> items; "nodes" -> nodes end}; subscription_opt_from_odbc({"SUBSCRIPTION_DEPTH", Value}) -> {subscription_depth, case Value of "all" -> all; N -> odbc_to_integer(N) end}. subscription_opt_to_odbc({deliver, Bool}) -> {"DELIVER", boolean_to_odbc(Bool)}; subscription_opt_to_odbc({digest, Bool}) -> {"DIGEST", boolean_to_odbc(Bool)}; subscription_opt_to_odbc({digest_frequency, Int}) -> {"DIGEST_FREQUENCY", integer_to_odbc(Int)}; subscription_opt_to_odbc({expire, Timestamp}) -> {"EXPIRE", timestamp_to_odbc(Timestamp)}; subscription_opt_to_odbc({include_body, Bool}) -> {"INCLUDE_BODY", boolean_to_odbc(Bool)}; subscription_opt_to_odbc({show_values, Values}) -> {"SHOW_VALUES", Values}; subscription_opt_to_odbc({subscription_type, Type}) -> {"SUBSCRIPTION_TYPE", case Type of items -> "items"; nodes -> "nodes" end}; subscription_opt_to_odbc({subscription_depth, Depth}) -> {"SUBSCRIPTION_DEPTH", case Depth of all -> "all"; N -> integer_to_odbc(N) end}. integer_to_odbc(N) -> integer_to_list(N). boolean_to_odbc(true) -> "1"; boolean_to_odbc(false) -> "0". timestamp_to_odbc(T) -> jlib:now_to_utc_string(T). odbc_to_integer(N) -> list_to_integer(N). odbc_to_boolean(B) -> B == "1". odbc_to_timestamp(T) -> jlib:datetime_string_to_timestamp(T). ejabberd-2.1.11/src/mod_pubsub/nodetree_dag.erl0000664000000000000000000001711012240230175016270 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% @author Brian Cully %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(nodetree_dag). -author('bjc@kublai.com'). %% API -export([init/3, terminate/2, options/0, set_node/1, get_node/3, get_node/2, get_node/1, get_nodes/2, get_nodes/1, get_parentnodes/3, get_parentnodes_tree/3, get_subnodes/3, get_subnodes_tree/3, create_node/6, delete_node/2]). -include_lib("stdlib/include/qlc.hrl"). -include("ejabberd.hrl"). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_nodetree). -define(DEFAULT_NODETYPE, leaf). -define(DEFAULT_PARENTS, []). -define(DEFAULT_CHILDREN, []). -compile(export_all). %%==================================================================== %% API %%==================================================================== init(Host, ServerHost, Opts) -> nodetree_tree:init(Host, ServerHost, Opts). terminate(Host, ServerHost) -> nodetree_tree:terminate(Host, ServerHost). create_node(Key, NodeID, Type, Owner, Options, Parents) -> OwnerJID = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), case find_node(Key, NodeID) of false -> ID = pubsub_index:new(node), N = #pubsub_node{nodeid = oid(Key, NodeID), id = ID, type = Type, parents = Parents, owners = [OwnerJID], options = Options}, case set_node(N) of ok -> {ok, ID}; Other -> Other end; _ -> {error, ?ERR_CONFLICT} end. set_node(#pubsub_node{nodeid = {Key, _}, owners = Owners, options = Options} = Node) -> Parents = find_opt(collection, ?DEFAULT_PARENTS, Options), case validate_parentage(Key, Owners, Parents) of true -> %% Update parents whenever the config changes. mnesia:write(Node#pubsub_node{parents = Parents}); Other -> Other end. delete_node(Key, NodeID) -> case find_node(Key, NodeID) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> %% Find all of N's children, update their configs to %% remove N from the collection setting. lists:foreach(fun (#pubsub_node{options = Opts} = Child) -> NewOpts = remove_config_parent(NodeID, Opts), Parents = find_opt(collection, ?DEFAULT_PARENTS, NewOpts), ok = mnesia:write(pubsub_node, Child#pubsub_node{ parents = Parents, options = NewOpts}, write) end, get_subnodes(Key, NodeID)), %% Remove and return the requested node. pubsub_index:free(node, Node#pubsub_node.id), mnesia:delete_object(pubsub_node, Node, write), [Node] end. options() -> nodetree_tree:options(). get_node(Host, NodeID, _From) -> get_node(Host, NodeID). get_node(Host, NodeID) -> case find_node(Host, NodeID) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> Node end. get_node(NodeId) -> nodetree_tree:get_node(NodeId). get_nodes(Key, From) -> nodetree_tree:get_nodes(Key, From). get_nodes(Key) -> nodetree_tree:get_nodes(Key). get_parentnodes(Host, NodeID, _From) -> case find_node(Host, NodeID) of false -> {error, ?ERR_ITEM_NOT_FOUND}; #pubsub_node{parents = Parents} -> Q = qlc:q([N || #pubsub_node{nodeid = {NHost, NNode}} = N <- mnesia:table(pubsub_node), Parent <- Parents, Host == NHost, Parent == NNode]), qlc:e(Q) end. get_parentnodes_tree(Host, NodeID, _From) -> Pred = fun (NID, #pubsub_node{nodeid = {_, NNodeID}}) -> NID == NNodeID end, Tr = fun (#pubsub_node{parents = Parents}) -> Parents end, traversal_helper(Pred, Tr, Host, [NodeID]). get_subnodes(Host, NodeID, _From) -> get_subnodes(Host, NodeID). get_subnodes(Host, <<>>) -> get_subnodes_helper(Host, <<>>); get_subnodes(Host, NodeID) -> case find_node(Host, NodeID) of false -> {error, ?ERR_ITEM_NOT_FOUND}; _ -> get_subnodes_helper(Host, NodeID) end. get_subnodes_helper(Host, NodeID) -> Q = qlc:q([Node || #pubsub_node{nodeid = {NHost, _}, parents = Parents} = Node <- mnesia:table(pubsub_node), Host == NHost, lists:member(NodeID, Parents)]), qlc:e(Q). get_subnodes_tree(Host, NodeID, From) -> Pred = fun (NID, #pubsub_node{parents = Parents}) -> lists:member(NID, Parents) end, Tr = fun (#pubsub_node{nodeid = {_, N}}) -> [N] end, traversal_helper(Pred, Tr, 1, Host, [NodeID], [{0, [get_node(Host, NodeID, From)]}]). %%==================================================================== %% Internal functions %%==================================================================== oid(Key, Name) -> {Key, Name}. %% Key = jlib:jid() | host() %% NodeID = string() find_node(Key, NodeID) -> case mnesia:read(pubsub_node, oid(Key, NodeID), read) of [] -> false; [Node] -> Node end. %% Key = jlib:jid() | host() %% Default = term() %% Options = [{Key = atom(), Value = term()}] find_opt(Key, Default, Options) -> case lists:keysearch(Key, 1, Options) of {value, {Key, Val}} -> Val; _ -> Default end. traversal_helper(Pred, Tr, Host, NodeIDs) -> traversal_helper(Pred, Tr, 0, Host, NodeIDs, []). traversal_helper(_Pred, _Tr, _Depth, _Host, [], Acc) -> Acc; traversal_helper(Pred, Tr, Depth, Host, NodeIDs, Acc) -> Q = qlc:q([Node || #pubsub_node{nodeid = {NHost, _}} = Node <- mnesia:table(pubsub_node), NodeID <- NodeIDs, Host == NHost, Pred(NodeID, Node)]), Nodes = qlc:e(Q), IDs = lists:flatmap(Tr, Nodes), traversal_helper(Pred, Tr, Depth + 1, Host, IDs, [{Depth, Nodes} | Acc]). remove_config_parent(NodeID, Options) -> remove_config_parent(NodeID, Options, []). remove_config_parent(_NodeID, [], Acc) -> lists:reverse(Acc); remove_config_parent(NodeID, [{collection, Parents} | T], Acc) -> remove_config_parent(NodeID, T, [{collection, lists:delete(NodeID, Parents)} | Acc]); remove_config_parent(NodeID, [H | T], Acc) -> remove_config_parent(NodeID, T, [H | Acc]). validate_parentage(_Key, _Owners, []) -> true; validate_parentage(Key, Owners, [[] | T]) -> validate_parentage(Key, Owners, T); validate_parentage(Key, Owners, [<<>> | T]) -> validate_parentage(Key, Owners, T); validate_parentage(Key, Owners, [ParentID | T]) -> case find_node(Key, ParentID) of false -> {error, ?ERR_ITEM_NOT_FOUND}; #pubsub_node{owners = POwners, options = POptions} -> NodeType = find_opt(node_type, ?DEFAULT_NODETYPE, POptions), MutualOwners = [O || O <- Owners, PO <- POwners, O == PO], case {MutualOwners, NodeType} of {[], _} -> {error, ?ERR_FORBIDDEN}; {_, collection} -> validate_parentage(Key, Owners, T); {_, _} -> {error, ?ERR_NOT_ALLOWED} end end. %% @spec (Host) -> jid() %% Host = host() %% @doc

    Generate pubsub service JID.

    service_jid(Host) -> case Host of {U,S,_} -> {jid, U, S, "", U, S, ""}; _ -> {jid, "", Host, "", "", Host, ""} end. ejabberd-2.1.11/src/mod_pubsub/Makefile.in0000664000000000000000000000157312240230175015217 0ustar # $Id$ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ EFLAGS += -I .. EFLAGS += -pz .. # make debug=true to compile Erlang module with debug informations. ifdef debug EFLAGS+=+debug_info +export_all endif OUTDIR = .. ERLBEHAVS = gen_pubsub_node.erl gen_pubsub_nodetree.erl SOURCES_ALL = $(wildcard *.erl) SOURCES = $(filter-out $(ERLBEHAVS),$(SOURCES_ALL)) ERLBEHAVBEAMS = $(addprefix $(OUTDIR)/,$(ERLBEHAVS:.erl=.beam)) BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam)) all: mod_pubsub_odbc.erl $(ERLBEHAVBEAMS) $(BEAMS) $(BEAMS): $(ERLBEHAVBEAMS) $(OUTDIR)/%.beam: %.erl @ERLC@ -W $(EFLAGS) -o $(OUTDIR) $< clean: rm -f $(BEAMS) distclean: clean rm -f Makefile mod_pubsub_odbc.erl: patch -o mod_pubsub_odbc.erl mod_pubsub.erl pubsub_odbc.patch TAGS: etags *.erl ejabberd-2.1.11/src/mod_pubsub/node_private.erl0000664000000000000000000001432512240230175016334 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(node_private). -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_node). %% Note on function definition %% included is all defined plugin function %% it's possible not to define some function at all %% in that case, warning will be generated at compilation %% and function call will fail, %% then mod_pubsub will call function from node_hometree %% (this makes code cleaner, but execution a little bit longer) %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/6, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1 ]). init(Host, ServerHost, Opts) -> node_hometree:init(Host, ServerHost, Opts). terminate(Host, ServerHost) -> node_hometree:terminate(Host, ServerHost). options() -> [{deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, true}, {purge_offline, false}, {persist_items, true}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, whitelist}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, never}, {deliver_notifications, false}, {presence_based_delivery, false}]. features() -> ["create-nodes", "delete-nodes", "delete-items", "instant-nodes", "outcast-affiliation", "persistent-items", "publish", "purge-nodes", "retract-items", "retrieve-affiliations", "retrieve-items", "retrieve-subscriptions", "subscribe", "subscription-notifications" ]. create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access) -> node_hometree:create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access). create_node(NodeId, Owner) -> node_hometree:create_node(NodeId, Owner). delete_node(Removed) -> node_hometree:delete_node(Removed). subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> node_hometree:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options). unsubscribe_node(NodeId, Sender, Subscriber, SubID) -> node_hometree:unsubscribe_node(NodeId, Sender, Subscriber, SubID). publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) -> node_hometree:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload). remove_extra_items(NodeId, MaxItems, ItemIds) -> node_hometree:remove_extra_items(NodeId, MaxItems, ItemIds). delete_item(NodeId, Publisher, PublishModel, ItemId) -> node_hometree:delete_item(NodeId, Publisher, PublishModel, ItemId). purge_node(NodeId, Owner) -> node_hometree:purge_node(NodeId, Owner). get_entity_affiliations(Host, Owner) -> node_hometree:get_entity_affiliations(Host, Owner). get_node_affiliations(NodeId) -> node_hometree:get_node_affiliations(NodeId). get_affiliation(NodeId, Owner) -> node_hometree:get_affiliation(NodeId, Owner). set_affiliation(NodeId, Owner, Affiliation) -> node_hometree:set_affiliation(NodeId, Owner, Affiliation). get_entity_subscriptions(Host, Owner) -> node_hometree:get_entity_subscriptions(Host, Owner). get_node_subscriptions(NodeId) -> node_hometree:get_node_subscriptions(NodeId). get_subscriptions(NodeId, Owner) -> node_hometree:get_subscriptions(NodeId, Owner). set_subscriptions(NodeId, Owner, Subscription, SubId) -> node_hometree:set_subscriptions(NodeId, Owner, Subscription, SubId). get_pending_nodes(Host, Owner) -> node_hometree:get_pending_nodes(Host, Owner). get_states(NodeId) -> node_hometree:get_states(NodeId). get_state(NodeId, JID) -> node_hometree:get_state(NodeId, JID). set_state(State) -> node_hometree:set_state(State). get_items(NodeId, From) -> node_hometree:get_items(NodeId, From). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). get_item(NodeId, ItemId) -> node_hometree:get_item(NodeId, ItemId). get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). set_item(Item) -> node_hometree:set_item(Item). get_item_name(Host, Node, Id) -> node_hometree:get_item_name(Host, Node, Id). node_to_path(Node) -> node_flat:node_to_path(Node). path_to_node(Path) -> node_flat:path_to_node(Path). ejabberd-2.1.11/src/mod_pubsub/gen_pubsub_node.erl0000664000000000000000000000466712240230175017023 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %%% @private %%% @doc

    The module {@module} defines the PubSub node %%% plugin behaviour. This behaviour is used to check that a PubSub plugin %%% respects the current ejabberd PubSub plugin API.

    -module(gen_pubsub_node). -export([behaviour_info/1]). %% @spec (Query::atom()) -> Callbacks | atom() %% Callbacks = [{Function,Arity}] %% Function = atom() %% Arity = integer() %% @doc Behaviour definition behaviour_info(callbacks) -> [{init, 3}, {terminate, 2}, {options, 0}, {features, 0}, {create_node_permission, 6}, {create_node, 2}, {delete_node, 1}, {purge_node, 2}, {subscribe_node, 8}, {unsubscribe_node, 4}, {publish_item, 6}, {delete_item, 4}, {remove_extra_items, 3}, {get_node_affiliations, 1}, {get_entity_affiliations, 2}, {get_affiliation, 2}, {set_affiliation, 3}, {get_node_subscriptions, 1}, {get_entity_subscriptions, 2}, {get_subscriptions, 2}, {set_subscriptions, 4}, {get_pending_nodes, 2}, {get_states, 1}, {get_state, 2}, {set_state, 1}, {get_items, 6}, {get_items, 2}, {get_item, 7}, {get_item, 2}, {set_item, 1}, {get_item_name, 3}, {node_to_path, 1}, {path_to_node, 1} ]; behaviour_info(_Other) -> undefined. ejabberd-2.1.11/src/mod_pubsub/node_dispatch.erl0000664000000000000000000001374412240230175016465 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(node_dispatch). -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_node). %%% @doc

    The {@module} module is a PubSub plugin whose %%% goal is to republished each published item to all its children.

    %%%

    Users cannot subscribe to this node, but are supposed to subscribe to %%% its children.

    %%% This module can not work with virtual nodetree %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/6, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1 ]). init(Host, ServerHost, Opts) -> node_hometree:init(Host, ServerHost, Opts). terminate(Host, ServerHost) -> node_hometree:terminate(Host, ServerHost). options() -> [{deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, true}, {purge_offline, false}, {persist_items, true}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, open}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, never}, {deliver_notifications, true}, {presence_based_delivery, false}]. features() -> ["create-nodes", "delete-nodes", "instant-nodes", "outcast-affiliation", "persistent-items", "publish", %%"purge-nodes", %%"retract-items", %%"retrieve-affiliations", "retrieve-items" %%"retrieve-subscriptions", %%"subscribe", %%"subscription-notifications", ]. create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access) -> node_hometree:create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access). create_node(NodeId, Owner) -> node_hometree:create_node(NodeId, Owner). delete_node(Removed) -> node_hometree:delete_node(Removed). subscribe_node(_NodeId, _Sender, _Subscriber, _AccessModel, _SendLast, _PresenceSubscription, _RosterGroup, _Options) -> {error, ?ERR_FORBIDDEN}. unsubscribe_node(_NodeId, _Sender, _Subscriber, _SubID) -> {error, ?ERR_FORBIDDEN}. publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) -> lists:foreach(fun(SubNode) -> node_hometree:publish_item( SubNode#pubsub_node.id, Publisher, Model, MaxItems, ItemId, Payload) end, nodetree_tree:get_subnodes(NodeId, Publisher, Publisher)). remove_extra_items(_NodeId, _MaxItems, ItemIds) -> {result, {ItemIds, []}}. delete_item(_NodeId, _Publisher, _PublishModel, _ItemId) -> {error, ?ERR_ITEM_NOT_FOUND}. purge_node(_NodeId, _Owner) -> {error, ?ERR_FORBIDDEN}. get_entity_affiliations(_Host, _Owner) -> {result, []}. get_node_affiliations(_NodeId) -> {result, []}. get_affiliation(_NodeId, _Owner) -> {result, []}. set_affiliation(NodeId, Owner, Affiliation) -> node_hometree:set_affiliation(NodeId, Owner, Affiliation). get_entity_subscriptions(_Host, _Owner) -> {result, []}. get_node_subscriptions(NodeId) -> %% note: get_node_subscriptions is used for broadcasting %% DO NOT REMOVE node_hometree:get_node_subscriptions(NodeId). get_subscriptions(_NodeId, _Owner) -> {result, []}. set_subscriptions(NodeId, Owner, Subscription, SubId) -> node_hometree:set_subscriptions(NodeId, Owner, Subscription, SubId). get_pending_nodes(Host, Owner) -> node_hometree:get_pending_nodes(Host, Owner). get_states(NodeId) -> node_hometree:get_states(NodeId). get_state(NodeId, JID) -> node_hometree:get_state(NodeId, JID). set_state(State) -> node_hometree:set_state(State). get_items(NodeId, From) -> node_hometree:get_items(NodeId, From). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). get_item(NodeId, ItemId) -> node_hometree:get_item(NodeId, ItemId). get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). set_item(Item) -> node_hometree:set_item(Item). get_item_name(Host, Node, Id) -> node_hometree:get_item_name(Host, Node, Id). node_to_path(Node) -> node_flat:node_to_path(Node). path_to_node(Path) -> node_flat:path_to_node(Path). ejabberd-2.1.11/src/mod_pubsub/mod_pubsub.erl0000664000000000000000000044131412240230175016016 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %%% @doc The module {@module} is the core of the PubSub %%% extension. It relies on PubSub plugins for a large part of its functions. %%% %%% @headerfile "pubsub.hrl" %%% %%% @reference See XEP-0060: Pubsub for %%% the latest version of the PubSub specification. %%% This module uses version 1.12 of the specification as a base. %%% Most of the specification is implemented. %%% Functions concerning configuration should be rewritten. %%% %%% Support for subscription-options and multi-subscribe features was %%% added by Brian Cully (bjc AT kublai.com). Subscriptions and options are %%% stored in the pubsub_subscription table, with a link to them provided %%% by the subscriptions field of pubsub_state. For information on %%% subscription-options and mulit-subscribe see XEP-0060 sections 6.1.6, %%% 6.2.3.1, 6.2.3.5, and 6.3. For information on subscription leases see %%% XEP-0060 section 12.18. -module(mod_pubsub). -author('christophe.romain@process-one.net'). -version('1.13-0'). -behaviour(gen_server). -behaviour(gen_mod). -include("ejabberd.hrl"). -include("adhoc.hrl"). -include("jlib.hrl"). -include("pubsub.hrl"). -define(STDTREE, "tree"). -define(STDNODE, "flat"). -define(PEPNODE, "pep"). %% exports for hooks -export([presence_probe/3, caps_update/3, in_subscription/6, out_subscription/4, on_user_offline/3, remove_user/2, disco_local_identity/5, disco_local_features/5, disco_local_items/5, disco_sm_identity/5, disco_sm_features/5, disco_sm_items/5 ]). %% exported iq handlers -export([iq_sm/3 ]). %% exports for console debug manual use -export([create_node/5, delete_node/3, subscribe_node/5, unsubscribe_node/5, publish_item/6, delete_item/4, send_items/6, get_items/2, get_item/3, get_cached_item/2, broadcast_stanza/9, get_configure/5, set_configure/5, tree_action/3, node_action/4 ]). %% general helpers for plugins -export([node_to_string/1, string_to_node/1, subscription_to_string/1, affiliation_to_string/1, string_to_subscription/1, string_to_affiliation/1, extended_error/2, extended_error/3, rename_default_nodeplugin/0 ]). %% API and gen_server callbacks -export([start_link/2, start/2, stop/1, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3 ]). %% calls for parallel sending of last items -export([send_loop/1 ]). -define(PROCNAME, ejabberd_mod_pubsub). -define(LOOPNAME, ejabberd_mod_pubsub_loop). -define(PLUGIN_PREFIX, "node_"). -define(TREE_PREFIX, "nodetree_"). -record(state, {server_host, host, access, pep_mapping = [], ignore_pep_from_offline = true, last_item_cache = false, max_items_node = ?MAXITEMS, nodetree = ?STDTREE, plugins = [?STDNODE]}). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, transient, 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:call(Proc, stop), supervisor:delete_child(ejabberd_sup, Proc). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([ServerHost, Opts]) -> ?DEBUG("pubsub init ~p ~p",[ServerHost,Opts]), Host = gen_mod:get_opt_host(ServerHost, Opts, "pubsub.@HOST@"), Access = gen_mod:get_opt(access_createnode, Opts, all), PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts, true), IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), LastItemCache = gen_mod:get_opt(last_item_cache, Opts, false), MaxItemsNode = gen_mod:get_opt(max_items_node, Opts, ?MAXITEMS), pubsub_index:init(Host, ServerHost, Opts), ets:new(gen_mod:get_module_proc(Host, config), [set, named_table]), ets:new(gen_mod:get_module_proc(ServerHost, config), [set, named_table]), {Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts), mnesia:create_table(pubsub_last_item, [{ram_copies, [node()]}, {attributes, record_info(fields, pubsub_last_item)}]), mod_disco:register_feature(ServerHost, ?NS_PUBSUB), ets:insert(gen_mod:get_module_proc(Host, config), {nodetree, NodeTree}), ets:insert(gen_mod:get_module_proc(Host, config), {plugins, Plugins}), ets:insert(gen_mod:get_module_proc(Host, config), {last_item_cache, LastItemCache}), ets:insert(gen_mod:get_module_proc(Host, config), {max_items_node, MaxItemsNode}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {nodetree, NodeTree}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {plugins, Plugins}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {last_item_cache, LastItemCache}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {max_items_node, MaxItemsNode}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {pep_mapping, PepMapping}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {ignore_pep_from_offline, PepOffline}), ets:insert(gen_mod:get_module_proc(ServerHost, config), {host, Host}), ejabberd_hooks:add(sm_remove_connection_hook, ServerHost, ?MODULE, on_user_offline, 75), ejabberd_hooks:add(disco_local_identity, ServerHost, ?MODULE, disco_local_identity, 75), ejabberd_hooks:add(disco_local_features, ServerHost, ?MODULE, disco_local_features, 75), ejabberd_hooks:add(disco_local_items, ServerHost, ?MODULE, disco_local_items, 75), ejabberd_hooks:add(presence_probe_hook, ServerHost, ?MODULE, presence_probe, 80), ejabberd_hooks:add(roster_in_subscription, ServerHost, ?MODULE, in_subscription, 50), ejabberd_hooks:add(roster_out_subscription, ServerHost, ?MODULE, out_subscription, 50), ejabberd_hooks:add(remove_user, ServerHost, ?MODULE, remove_user, 50), ejabberd_hooks:add(anonymous_purge_hook, ServerHost, ?MODULE, remove_user, 50), case lists:member(?PEPNODE, Plugins) of true -> ejabberd_hooks:add(caps_update, ServerHost, ?MODULE, caps_update, 80), ejabberd_hooks:add(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75), ejabberd_hooks:add(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75), ejabberd_hooks:add(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75), gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB, ?MODULE, iq_sm, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB_OWNER, ?MODULE, iq_sm, IQDisc); false -> ok end, ejabberd_router:register_route(Host), update_node_database(Host, ServerHost), update_state_database(Host, ServerHost), put(server_host, ServerHost), % not clean, but needed to plug hooks at any location init_nodes(Host, ServerHost, NodeTree, Plugins), State = #state{host = Host, server_host = ServerHost, access = Access, pep_mapping = PepMapping, ignore_pep_from_offline = PepOffline, last_item_cache = LastItemCache, max_items_node = MaxItemsNode, nodetree = NodeTree, plugins = Plugins}, init_send_loop(ServerHost, State), {ok, State}. init_send_loop(ServerHost, State) -> Proc = gen_mod:get_module_proc(ServerHost, ?LOOPNAME), SendLoop = spawn(?MODULE, send_loop, [State]), register(Proc, SendLoop), SendLoop. %% @spec (Host, ServerHost, Opts) -> Plugins %% Host = mod_pubsub:host() Opts = [{Key,Value}] %% ServerHost = host() %% Key = atom() %% Value = term() %% Plugins = [Plugin::string()] %% @doc Call the init/1 function for each plugin declared in the config file. %% The default plugin module is implicit. %%

    The Erlang code for the plugin is located in a module called %% node_plugin. The 'node_' prefix is mandatory.

    %%

    The modules are initialized in alphetical order and the list is checked %% and sorted to ensure that each module is initialized only once.

    %%

    See {@link node_hometree:init/1} for an example implementation.

    init_plugins(Host, ServerHost, Opts) -> TreePlugin = list_to_atom(?TREE_PREFIX ++ gen_mod:get_opt(nodetree, Opts, ?STDTREE)), ?DEBUG("** tree plugin is ~p",[TreePlugin]), TreePlugin:init(Host, ServerHost, Opts), Plugins = gen_mod:get_opt(plugins, Opts, [?STDNODE]), PepMapping = gen_mod:get_opt(pep_mapping, Opts, []), ?DEBUG("** PEP Mapping : ~p~n",[PepMapping]), PluginsOK = lists:foldl(fun(Name, Acc) -> Plugin = list_to_atom(?PLUGIN_PREFIX ++ Name), case catch apply(Plugin, init, [Host, ServerHost, Opts]) of {'EXIT', _Error} -> Acc; _ -> ?DEBUG("** init ~s plugin",[Name]), [Name | Acc] end end, [], Plugins), {lists:reverse(PluginsOK), TreePlugin, PepMapping}. terminate_plugins(Host, ServerHost, Plugins, TreePlugin) -> lists:foreach(fun(Name) -> ?DEBUG("** terminate ~s plugin",[Name]), Plugin = list_to_atom(?PLUGIN_PREFIX++Name), Plugin:terminate(Host, ServerHost) end, Plugins), TreePlugin:terminate(Host, ServerHost), ok. init_nodes(Host, ServerHost, _NodeTree, Plugins) -> %% TODO, this call should be done plugin side case lists:member("hometree", Plugins) of true -> create_node(Host, ServerHost, string_to_node("/home"), service_jid(Host), "hometree"), create_node(Host, ServerHost, string_to_node("/home/"++ServerHost), service_jid(Host), "hometree"); false -> ok end. update_node_database(Host, ServerHost) -> mnesia:del_table_index(pubsub_node, type), mnesia:del_table_index(pubsub_node, parentid), case catch mnesia:table_info(pubsub_node, attributes) of [host_node, host_parent, info] -> ?INFO_MSG("upgrade node pubsub tables",[]), F = fun() -> {Result, LastIdx} = lists:foldl( fun({pubsub_node, NodeId, ParentId, {nodeinfo, Items, Options, Entities}}, {RecList, NodeIdx}) -> ItemsList = lists:foldl( fun({item, IID, Publisher, Payload}, Acc) -> C = {unknown, Publisher}, M = {now(), Publisher}, mnesia:write( #pubsub_item{itemid = {IID, NodeIdx}, creation = C, modification = M, payload = Payload}), [{Publisher, IID} | Acc] end, [], Items), Owners = dict:fold( fun(JID, {entity, Aff, Sub}, Acc) -> UsrItems = lists:foldl( fun({P, I}, IAcc) -> case P of JID -> [I | IAcc]; _ -> IAcc end end, [], ItemsList), mnesia:write({pubsub_state, {JID, NodeIdx}, UsrItems, Aff, Sub}), case Aff of owner -> [JID | Acc]; _ -> Acc end end, [], Entities), mnesia:delete({pubsub_node, NodeId}), {[#pubsub_node{nodeid = NodeId, id = NodeIdx, parents = [element(2, ParentId)], owners = Owners, options = Options} | RecList], NodeIdx + 1} end, {[], 1}, mnesia:match_object( {pubsub_node, {Host, '_'}, '_', '_'})), mnesia:write(#pubsub_index{index = node, last = LastIdx, free = []}), Result end, {atomic, NewRecords} = mnesia:transaction(F), {atomic, ok} = mnesia:delete_table(pubsub_node), {atomic, ok} = mnesia:create_table(pubsub_node, [{disc_copies, [node()]}, {attributes, record_info(fields, pubsub_node)}]), FNew = fun() -> lists:foreach(fun(Record) -> mnesia:write(Record) end, NewRecords) end, case mnesia:transaction(FNew) of {atomic, Result} -> ?INFO_MSG("Pubsub node tables updated correctly: ~p", [Result]); {aborted, Reason} -> ?ERROR_MSG("Problem updating Pubsub node tables:~n~p", [Reason]) end; [nodeid, parentid, type, owners, options] -> F = fun({pubsub_node, NodeId, {_, Parent}, Type, Owners, Options}) -> #pubsub_node{ nodeid = NodeId, id = 0, parents = [Parent], type = Type, owners = Owners, options = Options} end, mnesia:transform_table(pubsub_node, F, [nodeid, id, parents, type, owners, options]), FNew = fun() -> LastIdx = lists:foldl(fun(#pubsub_node{nodeid = NodeId} = PubsubNode, NodeIdx) -> mnesia:write(PubsubNode#pubsub_node{id = NodeIdx}), lists:foreach(fun(#pubsub_state{stateid = StateId} = State) -> {JID, _} = StateId, mnesia:delete({pubsub_state, StateId}), mnesia:write(State#pubsub_state{stateid = {JID, NodeIdx}}) end, mnesia:match_object(#pubsub_state{stateid = {'_', NodeId}, _ = '_'})), lists:foreach(fun(#pubsub_item{itemid = ItemId} = Item) -> {IID, _} = ItemId, {M1, M2} = Item#pubsub_item.modification, {C1, C2} = Item#pubsub_item.creation, mnesia:delete({pubsub_item, ItemId}), mnesia:write(Item#pubsub_item{itemid = {IID, NodeIdx}, modification = {M2, M1}, creation = {C2, C1}}) end, mnesia:match_object(#pubsub_item{itemid = {'_', NodeId}, _ = '_'})), NodeIdx + 1 end, 1, mnesia:match_object( {pubsub_node, {Host, '_'}, '_', '_', '_', '_', '_'}) ++ mnesia:match_object( {pubsub_node, {{'_', ServerHost, '_'}, '_'}, '_', '_', '_', '_', '_'})), mnesia:write(#pubsub_index{index = node, last = LastIdx, free = []}) end, case mnesia:transaction(FNew) of {atomic, Result} -> rename_default_nodeplugin(), ?INFO_MSG("Pubsub node tables updated correctly: ~p", [Result]); {aborted, Reason} -> ?ERROR_MSG("Problem updating Pubsub node tables:~n~p", [Reason]) end; [nodeid, id, parent, type, owners, options] -> F = fun({pubsub_node, NodeId, Id, Parent, Type, Owners, Options}) -> #pubsub_node{ nodeid = NodeId, id = Id, parents = [Parent], type = Type, owners = Owners, options = Options} end, mnesia:transform_table(pubsub_node, F, [nodeid, id, parents, type, owners, options]), rename_default_nodeplugin(); _ -> ok end, mnesia:transaction(fun() -> case catch mnesia:first(pubsub_node) of {_, L} when is_list(L) -> lists:foreach( fun({H, N}) when is_list(N) -> [Node] = mnesia:read({pubsub_node, {H, N}}), Type = Node#pubsub_node.type, BN = element(2, node_call(Type, path_to_node, [N])), BP = case [element(2, node_call(Type, path_to_node, [P])) || P <- Node#pubsub_node.parents] of [<<>>] -> []; Parents -> Parents end, mnesia:write(Node#pubsub_node{nodeid={H, BN}, parents=BP}), mnesia:delete({pubsub_node, {H, N}}); (_) -> ok end, mnesia:all_keys(pubsub_node)); _ -> ok end end). rename_default_nodeplugin() -> lists:foreach(fun(Node) -> mnesia:dirty_write(Node#pubsub_node{type = "hometree"}) end, mnesia:dirty_match_object(#pubsub_node{type = "default", _ = '_'})). update_state_database(_Host, _ServerHost) -> case catch mnesia:table_info(pubsub_state, attributes) of [stateid, items, affiliation, subscription] -> ?INFO_MSG("upgrade state pubsub tables", []), F = fun ({pubsub_state, {JID, NodeID}, Items, Aff, Sub}, Acc) -> Subs = case Sub of none -> []; _ -> {result, SubID} = pubsub_subscription:subscribe_node(JID, NodeID, []), [{Sub, SubID}] end, NewState = #pubsub_state{stateid = {JID, NodeID}, items = Items, affiliation = Aff, subscriptions = Subs}, [NewState | Acc] end, {atomic, NewRecs} = mnesia:transaction(fun mnesia:foldl/3, [F, [], pubsub_state]), {atomic, ok} = mnesia:delete_table(pubsub_state), {atomic, ok} = mnesia:create_table(pubsub_state, [{disc_copies, [node()]}, {attributes, record_info(fields, pubsub_state)}]), FNew = fun () -> lists:foreach(fun mnesia:write/1, NewRecs) end, case mnesia:transaction(FNew) of {atomic, Result} -> ?INFO_MSG("Pubsub state tables updated correctly: ~p", [Result]); {aborted, Reason} -> ?ERROR_MSG("Problem updating Pubsub state tables:~n~p", [Reason]) end; _ -> ok end. send_loop(State) -> receive {presence, JID, Pid} -> Host = State#state.host, ServerHost = State#state.server_host, LJID = jlib:jid_tolower(JID), BJID = jlib:jid_remove_resource(LJID), %% for each node From is subscribed to %% and if the node is so configured, send the last published item to From lists:foreach(fun(PType) -> {result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, JID]), lists:foreach( fun({Node, subscribed, _, SubJID}) -> if (SubJID == LJID) or (SubJID == BJID) -> #pubsub_node{nodeid = {H, N}, type = Type, id = NodeId, options = Options} = Node, case get_option(Options, send_last_published_item) of on_sub_and_presence -> send_items(H, N, NodeId, Type, LJID, last); _ -> ok end; true -> % resource not concerned about that subscription ok end; (_) -> ok end, Subscriptions) end, State#state.plugins), %% and force send the last PEP events published by its offline and local contacts %% only if pubsub is explicitely configured for that. %% this is a hack in a sense that PEP should only be based on presence %% and is not able to "store" events of remote users (via s2s) %% this makes that hack only work for local domain by now if not State#state.ignore_pep_from_offline -> {User, Server, Resource} = jlib:jid_tolower(JID), case catch ejabberd_c2s:get_subscribed(Pid) of Contacts when is_list(Contacts) -> lists:foreach( fun({U, S, R}) -> case S of ServerHost -> %% local contacts case user_resources(U, S) of [] -> %% offline PeerJID = jlib:make_jid(U, S, R), self() ! {presence, User, Server, [Resource], PeerJID}; _ -> %% online % this is already handled by presence probe ok end; _ -> %% remote contacts % we can not do anything in any cases ok end end, Contacts); _ -> ok end; true -> ok end, send_loop(State); {presence, User, Server, Resources, JID} -> %% get resources caps and check if processing is needed spawn(fun() -> Host = State#state.host, Owner = jlib:jid_remove_resource(jlib:jid_tolower(JID)), lists:foreach(fun(#pubsub_node{nodeid = {_, Node}, type = Type, id = NodeId, options = Options}) -> case get_option(Options, send_last_published_item) of on_sub_and_presence -> lists:foreach( fun(Resource) -> LJID = {User, Server, Resource}, Subscribed = case get_option(Options, access_model) of open -> true; presence -> true; whitelist -> false; % subscribers are added manually authorize -> false; % likewise roster -> Grps = get_option(Options, roster_groups_allowed, []), {OU, OS, _} = Owner, element(2, get_roster_info(OU, OS, LJID, Grps)) end, if Subscribed -> send_items(Owner, Node, NodeId, Type, LJID, last); true -> ok end end, Resources); _ -> ok end end, tree_action(Host, get_nodes, [Owner, JID])) end), send_loop(State); stop -> ok end. %% ------- %% disco hooks handling functions %% disco_local_identity(Acc, _From, To, [], _Lang) -> case lists:member(?PEPNODE, plugins(To#jid.lserver)) of true -> [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "pep"}], []} | Acc]; false -> Acc end; disco_local_identity(Acc, _From, _To, _Node, _Lang) -> Acc. disco_local_features(Acc, _From, To, [], _Lang) -> Host = To#jid.lserver, Feats = case Acc of {result, I} -> I; _ -> [] end, {result, Feats ++ lists:map(fun(Feature) -> ?NS_PUBSUB++"#"++Feature end, features(Host, <<>>))}; disco_local_features(Acc, _From, _To, _Node, _Lang) -> Acc. disco_local_items(Acc, _From, _To, [], _Lang) -> Acc; disco_local_items(Acc, _From, _To, _Node, _Lang) -> Acc. disco_sm_identity(Acc, From, To, Node, Lang) when is_list(Node) -> disco_sm_identity(Acc, From, To, list_to_binary(Node), Lang); disco_sm_identity(empty, From, To, Node, Lang) -> disco_sm_identity([], From, To, Node, Lang); disco_sm_identity(Acc, From, To, Node, _Lang) -> disco_identity(jlib:jid_tolower(jlib:jid_remove_resource(To)), Node, From) ++ Acc. disco_identity(_Host, <<>>, _From) -> [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "pep"}], []}]; disco_identity(Host, Node, From) -> Action = fun(#pubsub_node{id = Idx, type = Type, options = Options, owners = Owners}) -> case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> {result, [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "pep"}], []}, {xmlelement, "identity", [{"category", "pubsub"}, {"type", "leaf"} | case get_option(Options, title) of false -> []; [Title] -> [{"name", Title}] end], []}]}; _ -> {result, []} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> Result; _ -> [] end. disco_sm_features(Acc, From, To, Node, Lang) when is_list(Node) -> disco_sm_features(Acc, From, To, list_to_binary(Node), Lang); disco_sm_features(empty, From, To, Node, Lang) -> disco_sm_features({result, []}, From, To, Node, Lang); disco_sm_features({result, OtherFeatures} = _Acc, From, To, Node, _Lang) -> {result, OtherFeatures ++ disco_features(jlib:jid_tolower(jlib:jid_remove_resource(To)), Node, From)}; disco_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. disco_features(_Host, <<>>, _From) -> [?NS_PUBSUB | [?NS_PUBSUB++"#"++Feature || Feature <- features("pep")]]; disco_features(Host, Node, From) -> Action = fun(#pubsub_node{id = Idx, type = Type, options = Options, owners = Owners}) -> case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> {result, [?NS_PUBSUB | [?NS_PUBSUB ++ "#" ++ Feature || Feature <- features("pep")]]}; _ -> {result, []} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> Result; _ -> [] end. disco_sm_items(Acc, From, To, Node, Lang) when is_list(Node) -> disco_sm_items(Acc, From, To, list_to_binary(Node), Lang); disco_sm_items(empty, From, To, Node, Lang) -> disco_sm_items({result, []}, From, To, Node, Lang); disco_sm_items({result, OtherItems}, From, To, Node, _Lang) -> {result, lists:usort(OtherItems ++ disco_items(jlib:jid_tolower(jlib:jid_remove_resource(To)), Node, From))}; disco_sm_items(Acc, _From, _To, _Node, _Lang) -> Acc. disco_items(Host, <<>>, From) -> Action = fun(#pubsub_node{nodeid ={_, NodeID}, options = Options, type = Type, id = Idx, owners = Owners}, Acc) -> case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> [{xmlelement, "item", [{"node", binary_to_list(NodeID)}, {"jid", case Host of {_,_,_} -> jlib:jid_to_string(Host); _Host -> Host end} | case get_option(Options, title) of false -> []; [Title] -> [{"name", Title}] end], []} | Acc]; _ -> Acc end end, case transaction(Host, Action, sync_dirty) of {result, Items} -> Items; _ -> [] end; disco_items(Host, Node, From) -> Action = fun(#pubsub_node{id = Idx, type = Type, options = Options, owners = Owners}) -> case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, Items} -> {result, [{xmlelement, "item", [{"jid", case Host of {_,_,_} -> jlib:jid_to_string(Host); _Host -> Host end}, {"name", ItemID}], []} || #pubsub_item{itemid = {ItemID,_}} <- Items]}; _ -> {result, []} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> Result; _ -> [] end. %% ------- %% presence hooks handling functions %% caps_update(#jid{luser = U, lserver = S, lresource = R} = From, To, _Features) -> Pid = ejabberd_sm:get_session_pid(U, S, R), presence_probe(From, To, Pid). presence_probe(#jid{luser = User, lserver = Server, lresource = Resource} = JID, JID, Pid) -> %%?DEBUG("presence probe self ~s@~s/~s ~s@~s/~s",[User,Server,Resource,element(2,JID),element(3,JID),element(4,JID)]), presence(Server, {presence, JID, Pid}), presence(Server, {presence, User, Server, [Resource], JID}); presence_probe(#jid{luser = User, lserver = Server}, #jid{luser = User, lserver = Server}, _Pid) -> %% ignore presence_probe from other ressources for the current user %% this way, we do not send duplicated last items if user already connected with other clients ok; presence_probe(#jid{luser = User, lserver = Server, lresource = Resource}, #jid{lserver = Host} = JID, _Pid) -> %%?DEBUG("presence probe peer ~s@~s/~s ~s@~s/~s",[User,Server,Resource,element(2,JID),element(3,JID),element(4,JID)]), presence(Host, {presence, User, Server, [Resource], JID}). presence(ServerHost, Presence) -> SendLoop = case whereis(gen_mod:get_module_proc(ServerHost, ?LOOPNAME)) of undefined -> % in case send_loop process died, we rebuild a minimal State record and respawn it Host = host(ServerHost), Plugins = plugins(Host), PepOffline = case catch ets:lookup(gen_mod:get_module_proc(ServerHost, config), ignore_pep_from_offline) of [{ignore_pep_from_offline, PO}] -> PO; _ -> true end, State = #state{host = Host, server_host = ServerHost, ignore_pep_from_offline = PepOffline, plugins = Plugins}, init_send_loop(ServerHost, State); Pid -> Pid end, SendLoop ! Presence. %% ------- %% subscription hooks handling functions %% out_subscription(User, Server, JID, subscribed) -> Owner = jlib:make_jid(User, Server, ""), {PUser, PServer, PResource} = jlib:jid_tolower(JID), PResources = case PResource of [] -> user_resources(PUser, PServer); _ -> [PResource] end, presence(Server, {presence, PUser, PServer, PResources, Owner}), true; out_subscription(_,_,_,_) -> true. in_subscription(_, User, Server, Owner, unsubscribed, _) -> unsubscribe_user(jlib:make_jid(User, Server, ""), Owner), true; in_subscription(_, _, _, _, _, _) -> true. unsubscribe_user(Entity, Owner) -> BJID = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), Host = host(element(2, BJID)), spawn(fun() -> lists:foreach(fun(PType) -> {result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Entity]), lists:foreach(fun ({#pubsub_node{options = Options, owners = Owners, id = NodeId}, subscribed, _, JID}) -> case get_option(Options, access_model) of presence -> case lists:member(BJID, Owners) of true -> node_action(Host, PType, unsubscribe_node, [NodeId, Entity, JID, all]); false -> {result, ok} end; _ -> {result, ok} end; (_) -> ok end, Subscriptions) end, plugins(Host)) end). %% ------- %% user remove hook handling function %% remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), Entity = jlib:make_jid(LUser, LServer, ""), Host = host(LServer), HomeTreeBase = string_to_node("/home/"++LServer++"/"++LUser), spawn(fun() -> lists:foreach(fun(PType) -> {result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Entity]), lists:foreach(fun ({#pubsub_node{id = NodeId}, _, _, JID}) -> node_action(Host, PType, unsubscribe_node, [NodeId, Entity, JID, all]) end, Subscriptions), {result, Affiliations} = node_action(Host, PType, get_entity_affiliations, [Host, Entity]), lists:foreach(fun ({#pubsub_node{nodeid = {H, N}, parents = []}, owner}) -> delete_node(H, N, Entity); ({#pubsub_node{nodeid = {H, N}, type = "hometree"}, owner}) when N == HomeTreeBase -> delete_node(H, N, Entity); ({#pubsub_node{id = NodeId}, publisher}) -> node_action(Host, PType, set_affiliation, [NodeId, Entity, none]); (_) -> ok end, Affiliations) end, plugins(Host)) end). %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- %% @private handle_call(server_host, _From, State) -> {reply, State#state.server_host, State}; handle_call(plugins, _From, State) -> {reply, State#state.plugins, State}; handle_call(pep_mapping, _From, State) -> {reply, State#state.pep_mapping, State}; handle_call(nodetree, _From, State) -> {reply, State#state.nodetree, State}; handle_call(stop, _From, State) -> {stop, normal, ok, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- %% @private handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- %% @private handle_info({route, From, To, Packet}, #state{server_host = ServerHost, access = Access, plugins = Plugins} = State) -> case catch do_route(ServerHost, Access, Plugins, To#jid.lserver, From, To, Packet) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); _ -> ok end, {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- %% @private terminate(_Reason, #state{host = Host, server_host = ServerHost, nodetree = TreePlugin, plugins = Plugins}) -> ejabberd_router:unregister_route(Host), case lists:member(?PEPNODE, Plugins) of true -> ejabberd_hooks:delete(caps_update, ServerHost, ?MODULE, caps_update, 80), ejabberd_hooks:delete(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75), ejabberd_hooks:delete(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75), ejabberd_hooks:delete(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75), gen_iq_handler:remove_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB), gen_iq_handler:remove_iq_handler(ejabberd_sm, ServerHost, ?NS_PUBSUB_OWNER); false -> ok end, ejabberd_hooks:delete(sm_remove_connection_hook, ServerHost, ?MODULE, on_user_offline, 75), ejabberd_hooks:delete(disco_local_identity, ServerHost, ?MODULE, disco_local_identity, 75), ejabberd_hooks:delete(disco_local_features, ServerHost, ?MODULE, disco_local_features, 75), ejabberd_hooks:delete(disco_local_items, ServerHost, ?MODULE, disco_local_items, 75), ejabberd_hooks:delete(presence_probe_hook, ServerHost, ?MODULE, presence_probe, 80), ejabberd_hooks:delete(roster_in_subscription, ServerHost, ?MODULE, in_subscription, 50), ejabberd_hooks:delete(roster_out_subscription, ServerHost, ?MODULE, out_subscription, 50), ejabberd_hooks:delete(remove_user, ServerHost, ?MODULE, remove_user, 50), ejabberd_hooks:delete(anonymous_purge_hook, ServerHost, ?MODULE, remove_user, 50), mod_disco:unregister_feature(ServerHost, ?NS_PUBSUB), gen_mod:get_module_proc(ServerHost, ?LOOPNAME) ! stop, terminate_plugins(Host, ServerHost, Plugins, TreePlugin). %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- %% @private code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- do_route(ServerHost, Access, Plugins, Host, From, To, Packet) -> {xmlelement, Name, Attrs, _Els} = Packet, case To of #jid{luser = "", lresource = ""} -> case Name of "iq" -> case jlib:iq_query_info(Packet) of #iq{type = get, xmlns = ?NS_DISCO_INFO, sub_el = SubEl, lang = Lang} = IQ -> {xmlelement, _, QAttrs, _} = SubEl, Node = xml:get_attr_s("node", QAttrs), Info = ejabberd_hooks:run_fold( disco_info, ServerHost, [], [ServerHost, ?MODULE, "", ""]), Res = case iq_disco_info(Host, Node, From, Lang) of {result, IQRes} -> jlib:iq_to_xml( IQ#iq{type = result, sub_el = [{xmlelement, "query", QAttrs, IQRes++Info}]}); {error, Error} -> jlib:make_error_reply(Packet, Error) end, ejabberd_router:route(To, From, Res); #iq{type = get, xmlns = ?NS_DISCO_ITEMS, sub_el = SubEl} = IQ -> {xmlelement, _, QAttrs, _} = SubEl, Node = xml:get_attr_s("node", QAttrs), Res = case iq_disco_items(Host, Node, From) of {result, IQRes} -> jlib:iq_to_xml( IQ#iq{type = result, sub_el = [{xmlelement, "query", QAttrs, IQRes}]}); {error, Error} -> jlib:make_error_reply(Packet, Error) end, ejabberd_router:route(To, From, Res); #iq{type = IQType, xmlns = ?NS_PUBSUB, lang = Lang, sub_el = SubEl} = IQ -> Res = case iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, Access, Plugins) of {result, IQRes} -> jlib:iq_to_xml( IQ#iq{type = result, sub_el = IQRes}); {error, Error} -> jlib:make_error_reply(Packet, Error) end, ejabberd_router:route(To, From, Res); #iq{type = IQType, xmlns = ?NS_PUBSUB_OWNER, lang = Lang, sub_el = SubEl} = IQ -> Res = case iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) of {result, IQRes} -> jlib:iq_to_xml( IQ#iq{type = result, sub_el = IQRes}); {error, Error} -> jlib:make_error_reply(Packet, Error) end, ejabberd_router:route(To, From, Res); #iq{type = get, xmlns = ?NS_VCARD = XMLNS, lang = Lang, sub_el = _SubEl} = IQ -> Res = IQ#iq{type = result, sub_el = [{xmlelement, "vCard", [{"xmlns", XMLNS}], iq_get_vcard(Lang)}]}, ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); #iq{type = set, xmlns = ?NS_COMMANDS} = IQ -> Res = case iq_command(Host, ServerHost, From, IQ, Access, Plugins) of {error, Error} -> jlib:make_error_reply(Packet, Error); {result, IQRes} -> jlib:iq_to_xml(IQ#iq{type = result, sub_el = IQRes}) end, ejabberd_router:route(To, From, Res); #iq{} -> Err = jlib:make_error_reply( Packet, ?ERR_FEATURE_NOT_IMPLEMENTED), ejabberd_router:route(To, From, Err); _ -> ok end; "message" -> case xml:get_attr_s("type", Attrs) of "error" -> ok; _ -> case find_authorization_response(Packet) of none -> ok; invalid -> ejabberd_router:route(To, From, jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST)); XFields -> handle_authorization_response(Host, From, To, Packet, XFields) end end; _ -> ok end; _ -> case xml:get_attr_s("type", Attrs) of "error" -> ok; "result" -> ok; _ -> Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND), ejabberd_router:route(To, From, Err) end end. command_disco_info(_Host, <>, _From) -> IdentityEl = {xmlelement, "identity", [{"category", "automation"}, {"type", "command-list"}], []}, {result, [IdentityEl]}; command_disco_info(_Host, <>, _From) -> IdentityEl = {xmlelement, "identity", [{"category", "automation"}, {"type", "command-node"}], []}, FeaturesEl = {xmlelement, "feature", [{"var", ?NS_COMMANDS}], []}, {result, [IdentityEl, FeaturesEl]}. node_disco_info(Host, Node, From) -> node_disco_info(Host, Node, From, true, true). %node_disco_identity(Host, Node, From) -> % node_disco_info(Host, Node, From, true, false). %node_disco_features(Host, Node, From) -> % node_disco_info(Host, Node, From, false, true). node_disco_info(Host, Node, From, Identity, Features) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> I = case Identity of false -> []; true -> Types = case tree_call(Host, get_subnodes, [Host, Node, From]) of [] -> ["leaf"]; %% No sub-nodes: it's a leaf node _ -> case node_call(Type, get_items, [NodeId, From]) of {result, []} -> ["collection"]; {result, _} -> ["leaf", "collection"]; _ -> [] end end, lists:map(fun(T) -> {xmlelement, "identity", [{"category", "pubsub"}, {"type", T}], []} end, Types) end, F = case Features of false -> []; true -> [{xmlelement, "feature", [{"var", ?NS_PUBSUB}], []} | lists:map(fun(T) -> {xmlelement, "feature", [{"var", ?NS_PUBSUB++"#"++T}], []} end, features(Type))] end, %% TODO: add meta-data info (spec section 5.4) {result, I ++ F} end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; Other -> Other end. iq_disco_info(Host, SNode, From, Lang) -> [RealSNode|_] = case SNode of [] -> [[]]; _ -> string:tokens(SNode, "!") end, Node = string_to_node(RealSNode), case Node of <<>> -> {result, [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "service"}, {"name", translate:translate(Lang, "Publish-Subscribe")}], []}, {xmlelement, "feature", [{"var", ?NS_DISCO_INFO}], []}, {xmlelement, "feature", [{"var", ?NS_DISCO_ITEMS}], []}, {xmlelement, "feature", [{"var", ?NS_PUBSUB}], []}, {xmlelement, "feature", [{"var", ?NS_COMMANDS}], []}, {xmlelement, "feature", [{"var", ?NS_VCARD}], []}] ++ lists:map(fun(Feature) -> {xmlelement, "feature", [{"var", ?NS_PUBSUB++"#"++Feature}], []} end, features(Host, Node))}; <> -> command_disco_info(Host, Node, From); <> -> command_disco_info(Host, Node, From); _ -> node_disco_info(Host, Node, From) end. iq_disco_items(Host, [], From) -> case tree_action(Host, get_subnodes, [Host, <<>>, From]) of Nodes when is_list(Nodes) -> {result, lists:map( fun(#pubsub_node{nodeid = {_, SubNode}, options = Options}) -> Attrs = case get_option(Options, title) of false -> [{"jid", Host} |nodeAttr(SubNode)]; Title -> [{"jid", Host}, {"name", Title}|nodeAttr(SubNode)] end, {xmlelement, "item", Attrs, []} end, Nodes)}; Other -> Other end; iq_disco_items(Host, ?NS_COMMANDS, _From) -> %% TODO: support localization of this string CommandItems = [{xmlelement, "item", [{"jid", Host}, {"node", ?NS_PUBSUB_GET_PENDING}, {"name", "Get Pending"}], []}], {result, CommandItems}; iq_disco_items(_Host, ?NS_PUBSUB_GET_PENDING, _From) -> CommandItems = [], {result, CommandItems}; iq_disco_items(Host, Item, From) -> case string:tokens(Item, "!") of [_SNode, _ItemID] -> {result, []}; [SNode] -> Node = string_to_node(SNode), Action = fun(#pubsub_node{id = Idx, type = Type, options = Options, owners = Owners}) -> NodeItems = case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, R} -> R; _ -> [] end, Nodes = lists:map( fun(#pubsub_node{nodeid = {_, SubNode}, options = SubOptions}) -> Attrs = case get_option(SubOptions, title) of false -> [{"jid", Host} |nodeAttr(SubNode)]; Title -> [{"jid", Host}, {"name", Title}|nodeAttr(SubNode)] end, {xmlelement, "item", Attrs, []} end, tree_call(Host, get_subnodes, [Host, Node, From])), Items = lists:map( fun(#pubsub_item{itemid = {RN, _}}) -> {result, Name} = node_call(Type, get_item_name, [Host, Node, RN]), {xmlelement, "item", [{"jid", Host}, {"name", Name}], []} end, NodeItems), {result, Nodes ++ Items} end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; Other -> Other end end. iq_sm(From, To, #iq{type = Type, sub_el = SubEl, xmlns = XMLNS, lang = Lang} = IQ) -> ServerHost = To#jid.lserver, LOwner = jlib:jid_tolower(jlib:jid_remove_resource(To)), Res = case XMLNS of ?NS_PUBSUB -> iq_pubsub(LOwner, ServerHost, From, Type, SubEl, Lang); ?NS_PUBSUB_OWNER -> iq_pubsub_owner(LOwner, ServerHost, From, Type, SubEl, Lang) end, case Res of {result, IQRes} -> IQ#iq{type = result, sub_el = IQRes}; {error, Error} -> IQ#iq{type = error, sub_el = [Error, SubEl]} end. iq_get_vcard(Lang) -> [{xmlelement, "FN", [], [{xmlcdata, "ejabberd/mod_pubsub"}]}, {xmlelement, "URL", [], [{xmlcdata, ?EJABBERD_URI}]}, {xmlelement, "DESC", [], [{xmlcdata, translate:translate(Lang, "ejabberd Publish-Subscribe module") ++ "\nCopyright (c) 2004-2012 ProcessOne"}]}]. iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang) -> iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, all, plugins(ServerHost)). iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, Access, Plugins) -> {xmlelement, _, _, SubEls} = SubEl, case xml:remove_cdata(SubEls) of [{xmlelement, Name, Attrs, Els} | Rest] -> Node = string_to_node(xml:get_attr_s("node", Attrs)), case {IQType, Name} of {set, "create"} -> Config = case Rest of [{xmlelement, "configure", _, C}] -> C; _ -> [] end, %% Get the type of the node Type = case xml:get_attr_s("type", Attrs) of [] -> hd(Plugins); T -> T end, %% we use Plugins list matching because we do not want to allocate %% atoms for non existing type, this prevent atom allocation overflow case lists:member(Type, Plugins) of false -> {error, extended_error( ?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "create-nodes")}; true -> create_node(Host, ServerHost, Node, From, Type, Access, Config) end; {set, "publish"} -> case xml:remove_cdata(Els) of [{xmlelement, "item", ItemAttrs, Payload}] -> ItemId = xml:get_attr_s("id", ItemAttrs), publish_item(Host, ServerHost, Node, From, ItemId, Payload); [] -> %% Publisher attempts to publish to persistent node with no item {error, extended_error(?ERR_BAD_REQUEST, "item-required")}; _ -> %% Entity attempts to publish item with multiple payload elements or namespace does not match {error, extended_error(?ERR_BAD_REQUEST, "invalid-payload")} end; {set, "retract"} -> ForceNotify = case xml:get_attr_s("notify", Attrs) of "1" -> true; "true" -> true; _ -> false end, case xml:remove_cdata(Els) of [{xmlelement, "item", ItemAttrs, _}] -> ItemId = xml:get_attr_s("id", ItemAttrs), delete_item(Host, Node, From, ItemId, ForceNotify); _ -> %% Request does not specify an item {error, extended_error(?ERR_BAD_REQUEST, "item-required")} end; {set, "subscribe"} -> Config = case Rest of [{xmlelement, "options", _, C}] -> C; _ -> [] end, JID = xml:get_attr_s("jid", Attrs), subscribe_node(Host, Node, From, JID, Config); {set, "unsubscribe"} -> JID = xml:get_attr_s("jid", Attrs), SubId = xml:get_attr_s("subid", Attrs), unsubscribe_node(Host, Node, From, JID, SubId); {get, "items"} -> MaxItems = xml:get_attr_s("max_items", Attrs), SubId = xml:get_attr_s("subid", Attrs), ItemIDs = lists:foldl(fun ({xmlelement, "item", ItemAttrs, _}, Acc) -> case xml:get_attr_s("id", ItemAttrs) of "" -> Acc; ItemID -> [ItemID|Acc] end; (_, Acc) -> Acc end, [], xml:remove_cdata(Els)), get_items(Host, Node, From, SubId, MaxItems, ItemIDs); {get, "subscriptions"} -> get_subscriptions(Host, Node, From, Plugins); {get, "affiliations"} -> get_affiliations(Host, Node, From, Plugins); {get, "options"} -> SubID = xml:get_attr_s("subid", Attrs), JID = xml:get_attr_s("jid", Attrs), get_options(Host, Node, JID, SubID, Lang); {set, "options"} -> SubID = xml:get_attr_s("subid", Attrs), JID = xml:get_attr_s("jid", Attrs), set_options(Host, Node, JID, SubID, Els); _ -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED} end; Other -> ?INFO_MSG("Too many actions: ~p", [Other]), {error, ?ERR_BAD_REQUEST} end. iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) -> {xmlelement, _, _, SubEls} = SubEl, Action = xml:remove_cdata(SubEls), case Action of [{xmlelement, Name, Attrs, Els}] -> Node = string_to_node(xml:get_attr_s("node", Attrs)), case {IQType, Name} of {get, "configure"} -> get_configure(Host, ServerHost, Node, From, Lang); {set, "configure"} -> set_configure(Host, Node, From, Els, Lang); {get, "default"} -> get_default(Host, Node, From, Lang); {set, "delete"} -> delete_node(Host, Node, From); {set, "purge"} -> purge_node(Host, Node, From); {get, "subscriptions"} -> get_subscriptions(Host, Node, From); {set, "subscriptions"} -> set_subscriptions(Host, Node, From, xml:remove_cdata(Els)); {get, "affiliations"} -> get_affiliations(Host, Node, From); {set, "affiliations"} -> set_affiliations(Host, Node, From, xml:remove_cdata(Els)); _ -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED} end; _ -> ?INFO_MSG("Too many actions: ~p", [Action]), {error, ?ERR_BAD_REQUEST} end. iq_command(Host, ServerHost, From, IQ, Access, Plugins) -> case adhoc:parse_request(IQ) of Req when is_record(Req, adhoc_request) -> case adhoc_request(Host, ServerHost, From, Req, Access, Plugins) of Resp when is_record(Resp, adhoc_response) -> {result, [adhoc:produce_response(Req, Resp)]}; Error -> Error end; Err -> Err end. %% @doc

    Processes an Ad Hoc Command.

    adhoc_request(Host, _ServerHost, Owner, #adhoc_request{node = ?NS_PUBSUB_GET_PENDING, lang = Lang, action = "execute", xdata = false}, _Access, Plugins) -> send_pending_node_form(Host, Owner, Lang, Plugins); adhoc_request(Host, _ServerHost, Owner, #adhoc_request{node = ?NS_PUBSUB_GET_PENDING, action = "execute", xdata = XData}, _Access, _Plugins) -> ParseOptions = case XData of {xmlelement, "x", _Attrs, _SubEls} = XEl -> case jlib:parse_xdata_submit(XEl) of invalid -> {error, ?ERR_BAD_REQUEST}; XData2 -> case set_xoption(Host, XData2, []) of NewOpts when is_list(NewOpts) -> {result, NewOpts}; Err -> Err end end; _ -> ?INFO_MSG("Bad XForm: ~p", [XData]), {error, ?ERR_BAD_REQUEST} end, case ParseOptions of {result, XForm} -> case lists:keysearch(node, 1, XForm) of {value, {_, Node}} -> send_pending_auth_events(Host, Node, Owner); false -> {error, extended_error(?ERR_BAD_REQUEST, "bad-payload")} end; Error -> Error end; adhoc_request(_Host, _ServerHost, _Owner, #adhoc_request{action = "cancel"}, _Access, _Plugins) -> #adhoc_response{status = canceled}; adhoc_request(Host, ServerHost, Owner, #adhoc_request{action = []} = R, Access, Plugins) -> adhoc_request(Host, ServerHost, Owner, R#adhoc_request{action = "execute"}, Access, Plugins); adhoc_request(_Host, _ServerHost, _Owner, Other, _Access, _Plugins) -> ?DEBUG("Couldn't process ad hoc command:~n~p", [Other]), {error, ?ERR_ITEM_NOT_FOUND}. %% @spec (Host, Owner, Lang, Plugins) -> iqRes() %% @doc

    Sends the process pending subscriptions XForm for Host to %% Owner.

    send_pending_node_form(Host, Owner, _Lang, Plugins) -> Filter = fun (Plugin) -> lists:member("get-pending", features(Plugin)) end, case lists:filter(Filter, Plugins) of [] -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED}; Ps -> XOpts = lists:map(fun (Node) -> {xmlelement, "option", [], [{xmlelement, "value", [], [{xmlcdata, node_to_string(Node)}]}]} end, get_pending_nodes(Host, Owner, Ps)), XForm = {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [{xmlelement, "field", [{"type", "list-single"}, {"var", "pubsub#node"}], lists:usort(XOpts)}]}, #adhoc_response{status = executing, defaultaction = "execute", elements = [XForm]} end. get_pending_nodes(Host, Owner, Plugins) -> Tr = fun (Type) -> case node_call(Type, get_pending_nodes, [Host, Owner]) of {result, Nodes} -> Nodes; _ -> [] end end, case transaction(fun () -> {result, lists:flatmap(Tr, Plugins)} end, sync_dirty) of {result, Res} -> Res; Err -> Err end. %% @spec (Host, Node, Owner) -> iqRes() %% @doc

    Send a subscription approval form to Owner for all pending %% subscriptions on Host and Node.

    send_pending_auth_events(Host, Node, Owner) -> ?DEBUG("Sending pending auth events for ~s on ~s:~s", [jlib:jid_to_string(Owner), Host, node_to_string(Node)]), Action = fun (#pubsub_node{id = NodeID, type = Type}) -> case lists:member("get-pending", features(Type)) of true -> case node_call(Type, get_affiliation, [NodeID, Owner]) of {result, owner} -> node_call(Type, get_node_subscriptions, [NodeID]); _ -> {error, ?ERR_FORBIDDEN} end; false -> {error, ?ERR_FEATURE_NOT_IMPLEMENTED} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {N, Subscriptions}} -> lists:foreach(fun({J, pending, _SubID}) -> send_authorization_request(N, jlib:make_jid(J)); ({J, pending}) -> send_authorization_request(N, jlib:make_jid(J)); (_) -> ok end, Subscriptions), #adhoc_response{}; Err -> Err end. %%% authorization handling send_authorization_request(#pubsub_node{owners = Owners, nodeid = {Host, Node}}, Subscriber) -> Lang = "en", %% TODO fix Stanza = {xmlelement, "message", [], [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], [{xmlelement, "title", [], [{xmlcdata, translate:translate(Lang, "PubSub subscriber request")}]}, {xmlelement, "instructions", [], [{xmlcdata, translate:translate(Lang, "Choose whether to approve this entity's subscription.")}]}, {xmlelement, "field", [{"var", "FORM_TYPE"}, {"type", "hidden"}], [{xmlelement, "value", [], [{xmlcdata, ?NS_PUBSUB_SUB_AUTH}]}]}, {xmlelement, "field", [{"var", "pubsub#node"}, {"type", "text-single"}, {"label", translate:translate(Lang, "Node ID")}], [{xmlelement, "value", [], [{xmlcdata, node_to_string(Node)}]}]}, {xmlelement, "field", [{"var", "pubsub#subscriber_jid"}, {"type", "jid-single"}, {"label", translate:translate(Lang, "Subscriber Address")}], [{xmlelement, "value", [], [{xmlcdata, jlib:jid_to_string(Subscriber)}]}]}, {xmlelement, "field", [{"var", "pubsub#allow"}, {"type", "boolean"}, {"label", translate:translate(Lang, "Allow this Jabber ID to subscribe to this pubsub node?")}], [{xmlelement, "value", [], [{xmlcdata, "false"}]}]}]}]}, lists:foreach(fun(Owner) -> ejabberd_router:route(service_jid(Host), jlib:make_jid(Owner), Stanza) end, Owners). find_authorization_response(Packet) -> {xmlelement, _Name, _Attrs, Els} = Packet, XData1 = lists:map(fun({xmlelement, "x", XAttrs, _} = XEl) -> case xml:get_attr_s("xmlns", XAttrs) of ?NS_XDATA -> case xml:get_attr_s("type", XAttrs) of "cancel" -> none; _ -> jlib:parse_xdata_submit(XEl) end; _ -> none end; (_) -> none end, xml:remove_cdata(Els)), XData = lists:filter(fun(E) -> E /= none end, XData1), case XData of [invalid] -> invalid; [] -> none; [XFields] when is_list(XFields) -> ?DEBUG("XFields: ~p", [XFields]), case lists:keysearch("FORM_TYPE", 1, XFields) of {value, {_, [?NS_PUBSUB_SUB_AUTH]}} -> XFields; _ -> invalid end end. %% @spec (Host, JID, Node, Subscription) -> void %% Host = mod_pubsub:host() %% JID = jlib:jid() %% SNode = string() %% Subscription = atom() | {atom(), mod_pubsub:subid()} %% @doc Send a message to JID with the supplied Subscription send_authorization_approval(Host, JID, SNode, Subscription) -> SubAttrs = case Subscription of {S, SID} -> [{"subscription", subscription_to_string(S)}, {"subid", SID}]; S -> [{"subscription", subscription_to_string(S)}] end, Stanza = event_stanza( [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(JID)}|nodeAttr(SNode)] ++ SubAttrs, []}]), ejabberd_router:route(service_jid(Host), JID, Stanza). handle_authorization_response(Host, From, To, Packet, XFields) -> case {lists:keysearch("pubsub#node", 1, XFields), lists:keysearch("pubsub#subscriber_jid", 1, XFields), lists:keysearch("pubsub#allow", 1, XFields)} of {{value, {_, [SNode]}}, {value, {_, [SSubscriber]}}, {value, {_, [SAllow]}}} -> Node = string_to_node(SNode), Subscriber = jlib:string_to_jid(SSubscriber), Allow = case SAllow of "1" -> true; "true" -> true; _ -> false end, Action = fun(#pubsub_node{type = Type, owners = Owners, id = NodeId}) -> IsApprover = lists:member(jlib:jid_tolower(jlib:jid_remove_resource(From)), Owners), {result, Subscriptions} = node_call(Type, get_subscriptions, [NodeId, Subscriber]), if not IsApprover -> {error, ?ERR_FORBIDDEN}; true -> update_auth(Host, SNode, Type, NodeId, Subscriber, Allow, Subscriptions) end end, case transaction(Host, Node, Action, sync_dirty) of {error, Error} -> ejabberd_router:route( To, From, jlib:make_error_reply(Packet, Error)); {result, {_, _NewSubscription}} -> %% XXX: notify about subscription state change, section 12.11 ok; _ -> ejabberd_router:route( To, From, jlib:make_error_reply(Packet, ?ERR_INTERNAL_SERVER_ERROR)) end; _ -> ejabberd_router:route( To, From, jlib:make_error_reply(Packet, ?ERR_NOT_ACCEPTABLE)) end. update_auth(Host, Node, Type, NodeId, Subscriber, Allow, Subscriptions) -> Subscription = lists:filter(fun({pending, _}) -> true; (_) -> false end, Subscriptions), case Subscription of [{pending, SubID}] -> %% TODO does not work if several pending NewSubscription = case Allow of true -> subscribed; false -> none end, node_call(Type, set_subscriptions, [NodeId, Subscriber, NewSubscription, SubID]), send_authorization_approval(Host, Subscriber, Node, NewSubscription), {result, ok}; _ -> {error, ?ERR_UNEXPECTED_REQUEST} end. -define(XFIELD(Type, Label, Var, Val), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). -define(BOOLXFIELD(Label, Var, Val), ?XFIELD("boolean", Label, Var, case Val of true -> "1"; _ -> "0" end)). -define(STRINGXFIELD(Label, Var, Val), ?XFIELD("text-single", Label, Var, Val)). -define(STRINGMXFIELD(Label, Var, Vals), {xmlelement, "field", [{"type", "text-multi"}, {"label", translate:translate(Lang, Label)}, {"var", Var}], [{xmlelement, "value", [], [{xmlcdata, V}]} || V <- Vals]}). -define(XFIELDOPT(Type, Label, Var, Val, Opts), {xmlelement, "field", [{"type", Type}, {"label", translate:translate(Lang, Label)}, {"var", Var}], lists:map(fun(Opt) -> {xmlelement, "option", [], [{xmlelement, "value", [], [{xmlcdata, Opt}]}]} end, Opts) ++ [{xmlelement, "value", [], [{xmlcdata, Val}]}]}). -define(LISTXFIELD(Label, Var, Val, Opts), ?XFIELDOPT("list-single", Label, Var, Val, Opts)). -define(LISTMXFIELD(Label, Var, Vals, Opts), {xmlelement, "field", [{"type", "list-multi"}, {"label", translate:translate(Lang, Label)}, {"var", Var}], lists:map(fun(Opt) -> {xmlelement, "option", [], [{xmlelement, "value", [], [{xmlcdata, Opt}]}]} end, Opts) ++ lists:map(fun(Val) -> {xmlelement, "value", [], [{xmlcdata, Val}]} end, Vals)}). %% @spec (Host::host(), ServerHost::host(), Node::pubsubNode(), Owner::jid(), NodeType::nodeType()) -> %% {error, Reason::stanzaError()} | %% {result, []} %% @doc

    Create new pubsub nodes

    %%

    In addition to method-specific error conditions, there are several general reasons why the node creation request might fail:

    %%
      %%
    • The service does not support node creation.
    • %%
    • Only entities that are registered with the service are allowed to create nodes but the requesting entity is not registered.
    • %%
    • The requesting entity does not have sufficient privileges to create nodes.
    • %%
    • The requested NodeID already exists.
    • %%
    • The request did not include a NodeID and "instant nodes" are not supported.
    • %%
    %%

    ote: node creation is a particular case, error return code is evaluated at many places:

    %%
      %%
    • iq_pubsub checks if service supports node creation (type exists)
    • %%
    • create_node checks if instant nodes are supported
    • %%
    • create_node asks node plugin if entity have sufficient privilege
    • %%
    • nodetree create_node checks if nodeid already exists
    • %%
    • node plugin create_node just sets default affiliation/subscription
    • %%
    create_node(Host, ServerHost, Node, Owner, Type) -> create_node(Host, ServerHost, Node, Owner, Type, all, []). create_node(Host, ServerHost, <<>>, Owner, Type, Access, Configuration) -> case lists:member("instant-nodes", features(Type)) of true -> NewNode = string_to_node(randoms:get_string()), case create_node(Host, ServerHost, NewNode, Owner, Type, Access, Configuration) of {result, []} -> {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "create", nodeAttr(NewNode), []}]}]}; Error -> Error end; false -> %% Service does not support instant nodes {error, extended_error(?ERR_NOT_ACCEPTABLE, "nodeid-required")} end; create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) -> Type = select_type(ServerHost, Host, Node, GivenType), %% TODO, check/set node_type = Type ParseOptions = case xml:remove_cdata(Configuration) of [] -> {result, node_options(Type)}; [{xmlelement, "x", _Attrs, _SubEls} = XEl] -> case jlib:parse_xdata_submit(XEl) of invalid -> {error, ?ERR_BAD_REQUEST}; XData -> case set_xoption(Host, XData, node_options(Type)) of NewOpts when is_list(NewOpts) -> {result, NewOpts}; Err -> Err end end; _ -> ?INFO_MSG("Node ~p; bad configuration: ~p", [Node, Configuration]), {error, ?ERR_BAD_REQUEST} end, case ParseOptions of {result, NodeOptions} -> CreateNode = fun() -> SNode = node_to_string(Node), Parent = case node_call(Type, node_to_path, [Node]) of {result, [SNode]} -> <<>>; {result, Path} -> element(2, node_call(Type, path_to_node, [lists:sublist(Path, length(Path)-1)])) end, Parents = case Parent of <<>> -> []; _ -> [Parent] end, case node_call(Type, create_node_permission, [Host, ServerHost, Node, Parent, Owner, Access]) of {result, true} -> case tree_call(Host, create_node, [Host, Node, Type, Owner, NodeOptions, Parents]) of {ok, NodeId} -> ParentTree = tree_call(Host, get_parentnodes_tree, [Host, Node, Owner]), SubsByDepth = [{Depth, [{N, get_node_subs(N)} || N <- Nodes]} || {Depth, Nodes} <- ParentTree], case node_call(Type, create_node, [NodeId, Owner]) of {result, Result} -> {result, {NodeId, SubsByDepth, Result}}; Error -> Error end; {error, {virtual, NodeId}} -> case node_call(Type, create_node, [NodeId, Owner]) of {result, Result} -> {result, {NodeId, [], Result}}; Error -> Error end; Error -> Error end; _ -> {error, ?ERR_FORBIDDEN} end end, Reply = [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "create", nodeAttr(Node), []}]}], case transaction(CreateNode, transaction) of {result, {NodeId, SubsByDepth, {Result, broadcast}}} -> broadcast_created_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth), ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), case Result of default -> {result, Reply}; _ -> {result, Result} end; {result, {NodeId, _SubsByDepth, default}} -> ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), {result, Reply}; {result, {NodeId, _SubsByDepth, Result}} -> ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), {result, Result}; Error -> %% in case we change transaction to sync_dirty... %% node_call(Type, delete_node, [Host, Node]), %% tree_call(Host, delete_node, [Host, Node]), Error end; Error -> Error end. %% @spec (Host, Node, Owner) -> %% {error, Reason} | {result, []} %% Host = host() %% Node = pubsubNode() %% Owner = jid() %% Reason = stanzaError() %% @doc

    Delete specified node and all childs.

    %%

    There are several reasons why the node deletion request might fail:

    %%
      %%
    • The requesting entity does not have sufficient privileges to delete the node.
    • %%
    • The node is the root collection node, which cannot be deleted.
    • %%
    • The specified node does not exist.
    • %%
    delete_node(_Host, <<>>, _Owner) -> %% Node is the root {error, ?ERR_NOT_ALLOWED}; delete_node(Host, Node, Owner) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> case node_call(Type, get_affiliation, [NodeId, Owner]) of {result, owner} -> ParentTree = tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]), SubsByDepth = [{Depth, [{N, get_node_subs(N)} || N <- Nodes]} || {Depth, Nodes} <- ParentTree], Removed = tree_call(Host, delete_node, [Host, Node]), case node_call(Type, delete_node, [Removed]) of {result, Res} -> {result, {SubsByDepth, Res}}; Error -> Error end; _ -> %% Entity is not an owner {error, ?ERR_FORBIDDEN} end end, Reply = [], ServerHost = get(server_host), % not clean, but prevent many API changes case transaction(Host, Node, Action, transaction) of {result, {_TNode, {SubsByDepth, {Result, broadcast, Removed}}}} -> lists:foreach(fun({RNode, _RSubscriptions}) -> {RH, RN} = RNode#pubsub_node.nodeid, NodeId = RNode#pubsub_node.id, Type = RNode#pubsub_node.type, Options = RNode#pubsub_node.options, broadcast_removed_node(RH, RN, NodeId, Type, Options, SubsByDepth), ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, RH, RN, NodeId]) end, Removed), case Result of default -> {result, Reply}; _ -> {result, Result} end; {result, {_TNode, {_, {Result, Removed}}}} -> lists:foreach(fun({RNode, _RSubscriptions}) -> {RH, RN} = RNode#pubsub_node.nodeid, NodeId = RNode#pubsub_node.id, ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, RH, RN, NodeId]) end, Removed), case Result of default -> {result, Reply}; _ -> {result, Result} end; {result, {TNode, {_, default}}} -> NodeId = TNode#pubsub_node.id, ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, Host, Node, NodeId]), {result, Reply}; {result, {TNode, {_, Result}}} -> NodeId = TNode#pubsub_node.id, ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, Host, Node, NodeId]), {result, Result}; Error -> Error end. %% @spec (Host, Node, From, JID, Configuration) -> %% {error, Reason::stanzaError()} | %% {result, []} %% Host = host() %% Node = pubsubNode() %% From = jid() %% JID = jid() %% @see node_hometree:subscribe_node/5 %% @doc

    Accepts or rejects subcription requests on a PubSub node.

    %%

    There are several reasons why the subscription request might fail:

    %%
      %%
    • The bare JID portions of the JIDs do not match.
    • %%
    • The node has an access model of "presence" and the requesting entity is not subscribed to the owner's presence.
    • %%
    • The node has an access model of "roster" and the requesting entity is not in one of the authorized roster groups.
    • %%
    • The node has an access model of "whitelist" and the requesting entity is not on the whitelist.
    • %%
    • The service requires payment for subscriptions to the node.
    • %%
    • The requesting entity is anonymous and the service does not allow anonymous entities to subscribe.
    • %%
    • The requesting entity has a pending subscription.
    • %%
    • The requesting entity is blocked from subscribing (e.g., because having an affiliation of outcast).
    • %%
    • The node does not support subscriptions.
    • %%
    • The node does not exist.
    • %%
    subscribe_node(Host, Node, From, JID, Configuration) -> SubOpts = case pubsub_subscription:parse_options_xform(Configuration) of {result, GoodSubOpts} -> GoodSubOpts; _ -> invalid end, Subscriber = case jlib:string_to_jid(JID) of error -> {"", "", ""}; J -> jlib:jid_tolower(J) end, Action = fun(#pubsub_node{options = Options, owners = Owners, type = Type, id = NodeId}) -> Features = features(Type), SubscribeFeature = lists:member("subscribe", Features), OptionsFeature = lists:member("subscription-options", Features), HasOptions = not (SubOpts == []), SubscribeConfig = get_option(Options, subscribe), AccessModel = get_option(Options, access_model), SendLast = get_option(Options, send_last_published_item), AllowedGroups = get_option(Options, roster_groups_allowed, []), {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, Subscriber, Owners, AccessModel, AllowedGroups), if not SubscribeFeature -> %% Node does not support subscriptions {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscribe")}; not SubscribeConfig -> %% Node does not support subscriptions {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscribe")}; HasOptions andalso not OptionsFeature -> %% Node does not support subscription options {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscription-options")}; SubOpts == invalid -> %% Passed invalit options submit form {error, extended_error(?ERR_BAD_REQUEST, "invalid-options")}; true -> node_call(Type, subscribe_node, [NodeId, From, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, SubOpts]) end end, Reply = fun(Subscription) -> %% TODO, this is subscription-notification, should depends on node features SubAttrs = case Subscription of {subscribed, SubId} -> [{"subscription", subscription_to_string(subscribed)}, {"subid", SubId}, {"node",Node}]; Other -> [{"subscription", subscription_to_string(Other)}, {"node", Node}] end, Fields = [{"jid", jlib:jid_to_string(Subscriber)} | SubAttrs], [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "subscription", Fields, []}]}] end, case transaction(Host, Node, Action, sync_dirty) of {result, {TNode, {Result, subscribed, SubId, send_last}}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, send_items(Host, Node, NodeId, Type, Subscriber, last), case Result of default -> {result, Reply({subscribed, SubId})}; _ -> {result, Result} end; {result, {_TNode, {default, subscribed, SubId}}} -> {result, Reply({subscribed, SubId})}; {result, {_TNode, {Result, subscribed, _SubId}}} -> {result, Result}; {result, {TNode, {default, pending, _SubId}}} -> send_authorization_request(TNode, Subscriber), {result, Reply(pending)}; {result, {TNode, {Result, pending}}} -> send_authorization_request(TNode, Subscriber), {result, Result}; {result, {_, Result}} -> %% this case should never occure anyway {result, Result}; Error -> Error end. %% @spec (Host, Noce, From, JID, SubId) -> {error, Reason} | {result, []} %% Host = host() %% Node = pubsubNode() %% From = jid() %% JID = string() %% SubId = string() %% Reason = stanzaError() %% @doc

    Unsubscribe JID from the Node.

    %%

    There are several reasons why the unsubscribe request might fail:

    %%
      %%
    • The requesting entity has multiple subscriptions to the node but does not specify a subscription ID.
    • %%
    • The request does not specify an existing subscriber.
    • %%
    • The requesting entity does not have sufficient privileges to unsubscribe the specified JID.
    • %%
    • The node does not exist.
    • %%
    • The request specifies a subscription ID that is not valid or current.
    • %%
    unsubscribe_node(Host, Node, From, JID, SubId) when is_list(JID) -> Subscriber = case jlib:string_to_jid(JID) of error -> {"", "", ""}; J -> jlib:jid_tolower(J) end, unsubscribe_node(Host, Node, From, Subscriber, SubId); unsubscribe_node(Host, Node, From, Subscriber, SubId) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> node_call(Type, unsubscribe_node, [NodeId, From, Subscriber, SubId]) end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, default}} -> {result, []}; {result, {_, Result}} -> {result, Result}; Error -> Error end. %% @spec (Host::host(), ServerHost::host(), JID::jid(), Node::pubsubNode(), ItemId::string(), Payload::term()) -> %% {error, Reason::stanzaError()} | %% {result, []} %% @doc

    Publish item to a PubSub node.

    %%

    The permission to publish an item must be verified by the plugin implementation.

    %%

    There are several reasons why the publish request might fail:

    %%
      %%
    • The requesting entity does not have sufficient privileges to publish.
    • %%
    • The node does not support item publication.
    • %%
    • The node does not exist.
    • %%
    • The payload size exceeds a service-defined limit.
    • %%
    • The item contains more than one payload element or the namespace of the root payload element does not match the configured namespace for the node.
    • %%
    • The request does not match the node configuration.
    • %%
    publish_item(Host, ServerHost, Node, Publisher, "", Payload) -> %% if publisher does not specify an ItemId, the service MUST generate the ItemId publish_item(Host, ServerHost, Node, Publisher, uniqid(), Payload); publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> Features = features(Type), PublishFeature = lists:member("publish", Features), PublishModel = get_option(Options, publish_model), DeliverPayloads = get_option(Options, deliver_payloads), PersistItems = get_option(Options, persist_items), MaxItems = case PersistItems of false -> 0; true -> max_items(Host, Options) end, PayloadCount = payload_xmlelements(Payload), PayloadSize = size(term_to_binary(Payload))-2, % size(term_to_binary([])) == 2 PayloadMaxSize = get_option(Options, max_payload_size), % pubsub#deliver_payloads true % pubsub#persist_items true -> 1 item; false -> 0 item if not PublishFeature -> %% Node does not support item publication {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "publish")}; PayloadSize > PayloadMaxSize -> %% Entity attempts to publish very large payload {error, extended_error(?ERR_NOT_ACCEPTABLE, "payload-too-big")}; (PayloadCount == 0) and (Payload == []) -> %% Publisher attempts to publish to payload node with no payload {error, extended_error(?ERR_BAD_REQUEST, "payload-required")}; (PayloadCount > 1) or (PayloadCount == 0) -> %% Entity attempts to publish item with multiple payload elements {error, extended_error(?ERR_BAD_REQUEST, "invalid-payload")}; (DeliverPayloads == 0) and (PersistItems == 0) and (PayloadSize > 0) -> %% Publisher attempts to publish to transient notification node with item {error, extended_error(?ERR_BAD_REQUEST, "item-forbidden")}; ((DeliverPayloads == 1) or (PersistItems == 1)) and (PayloadSize == 0) -> %% Publisher attempts to publish to persistent node with no item {error, extended_error(?ERR_BAD_REQUEST, "item-required")}; true -> node_call(Type, publish_item, [NodeId, Publisher, PublishModel, MaxItems, ItemId, Payload]) end end, ejabberd_hooks:run(pubsub_publish_item, ServerHost, [ServerHost, Node, Publisher, service_jid(Host), ItemId, Payload]), Reply = [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "publish", nodeAttr(Node), [{xmlelement, "item", itemAttr(ItemId), []}]}]}], case transaction(Host, Node, Action, sync_dirty) of {result, {TNode, {Result, Broadcast, Removed}}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, case get_option(Options, deliver_notifications) of true -> BroadcastPayload = case Broadcast of default -> Payload; broadcast -> Payload; PluginPayload -> PluginPayload end, broadcast_publish_item(Host, Node, NodeId, Type, Options, Removed, ItemId, jlib:jid_tolower(Publisher), BroadcastPayload); false -> ok end, set_cached_item(Host, NodeId, ItemId, Publisher, Payload), case Result of default -> {result, Reply}; _ -> {result, Result} end; {result, {TNode, {default, Removed}}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, broadcast_retract_items(Host, Node, NodeId, Type, Options, Removed), set_cached_item(Host, NodeId, ItemId, Publisher, Payload), {result, Reply}; {result, {TNode, {Result, Removed}}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, broadcast_retract_items(Host, Node, NodeId, Type, Options, Removed), set_cached_item(Host, NodeId, ItemId, Publisher, Payload), {result, Result}; {result, {_, default}} -> {result, Reply}; {result, {_, Result}} -> {result, Result}; {error, ?ERR_ITEM_NOT_FOUND} -> %% handles auto-create feature %% for automatic node creation. we'll take the default node type: %% first listed into the plugins configuration option, or pep Type = select_type(ServerHost, Host, Node), case lists:member("auto-create", features(Type)) of true -> case create_node(Host, ServerHost, Node, Publisher, Type) of {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "create", [{"node", NewNode}], []}]}]} -> publish_item(Host, ServerHost, list_to_binary(NewNode), Publisher, ItemId, Payload); _ -> {error, ?ERR_ITEM_NOT_FOUND} end; false -> {error, ?ERR_ITEM_NOT_FOUND} end; Error -> Error end. %% @spec (Host::host(), JID::jid(), Node::pubsubNode(), ItemId::string()) -> %% {error, Reason::stanzaError()} | %% {result, []} %% @doc

    Delete item from a PubSub node.

    %%

    The permission to delete an item must be verified by the plugin implementation.

    %%

    There are several reasons why the item retraction request might fail:

    %%
      %%
    • The publisher does not have sufficient privileges to delete the requested item.
    • %%
    • The node or item does not exist.
    • %%
    • The request does not specify a node.
    • %%
    • The request does not include an element or the element does not specify an ItemId.
    • %%
    • The node does not support persistent items.
    • %%
    • The service does not support the deletion of items.
    • %%
    delete_item(Host, Node, Publisher, ItemId) -> delete_item(Host, Node, Publisher, ItemId, false). delete_item(_, "", _, _, _) -> %% Request does not specify a node {error, extended_error(?ERR_BAD_REQUEST, "node-required")}; delete_item(Host, Node, Publisher, ItemId, ForceNotify) -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> Features = features(Type), PersistentFeature = lists:member("persistent-items", Features), DeleteFeature = lists:member("delete-items", Features), PublishModel = get_option(Options, publish_model), if %%-> iq_pubsub just does that matchs %% %% Request does not specify an item %% {error, extended_error(?ERR_BAD_REQUEST, "item-required")}; not PersistentFeature -> %% Node does not support persistent items {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")}; not DeleteFeature -> %% Service does not support item deletion {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "delete-items")}; true -> node_call(Type, delete_item, [NodeId, Publisher, PublishModel, ItemId]) end end, Reply = [], case transaction(Host, Node, Action, sync_dirty) of {result, {TNode, {Result, broadcast}}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, broadcast_retract_items(Host, Node, NodeId, Type, Options, [ItemId], ForceNotify), case get_cached_item(Host, NodeId) of #pubsub_item{itemid = {ItemId, NodeId}, _ = '_'} -> unset_cached_item(Host, NodeId); _ -> ok end, case Result of default -> {result, Reply}; _ -> {result, Result} end; {result, {_, default}} -> {result, Reply}; {result, {_, Result}} -> {result, Result}; Error -> Error end. %% @spec (Host, JID, Node) -> %% {error, Reason} | {result, []} %% Host = host() %% Node = pubsubNode() %% JID = jid() %% Reason = stanzaError() %% @doc

    Delete all items of specified node owned by JID.

    %%

    There are several reasons why the node purge request might fail:

    %%
      %%
    • The node or service does not support node purging.
    • %%
    • The requesting entity does not have sufficient privileges to purge the node.
    • %%
    • The node is not configured to persist items.
    • %%
    • The specified node does not exist.
    • %%
    purge_node(Host, Node, Owner) -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> Features = features(Type), PurgeFeature = lists:member("purge-nodes", Features), PersistentFeature = lists:member("persistent-items", Features), PersistentConfig = get_option(Options, persist_items), if not PurgeFeature -> %% Service does not support node purging {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "purge-nodes")}; not PersistentFeature -> %% Node does not support persistent items {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")}; not PersistentConfig -> %% Node is not configured for persistent items {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")}; true -> node_call(Type, purge_node, [NodeId, Owner]) end end, Reply = [], case transaction(Host, Node, Action, sync_dirty) of {result, {TNode, {Result, broadcast}}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, broadcast_purge_node(Host, Node, NodeId, Type, Options), unset_cached_item(Host, NodeId), case Result of default -> {result, Reply}; _ -> {result, Result} end; {result, {_, default}} -> {result, Reply}; {result, {_, Result}} -> {result, Result}; Error -> Error end. %% @doc

    Return the items of a given node.

    %%

    The number of items to return is limited by MaxItems.

    %%

    The permission are not checked in this function.

    %% @todo We probably need to check that the user doing the query has the right %% to read the items. get_items(Host, Node, From, SubId, SMaxItems, ItemIDs) -> MaxItems = if SMaxItems == "" -> get_max_items_node(Host); true -> case catch list_to_integer(SMaxItems) of {'EXIT', _} -> {error, ?ERR_BAD_REQUEST}; Val -> Val end end, case MaxItems of {error, Error} -> {error, Error}; _ -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId, owners = Owners}) -> Features = features(Type), RetreiveFeature = lists:member("retrieve-items", Features), PersistentFeature = lists:member("persistent-items", Features), AccessModel = get_option(Options, access_model), AllowedGroups = get_option(Options, roster_groups_allowed, []), {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups), if not RetreiveFeature -> %% Item Retrieval Not Supported {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-items")}; not PersistentFeature -> %% Persistent Items Not Supported {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")}; true -> node_call(Type, get_items, [NodeId, From, AccessModel, PresenceSubscription, RosterGroup, SubId]) end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Items}} -> SendItems = case ItemIDs of [] -> Items; _ -> lists:filter(fun(#pubsub_item{itemid = {ItemId, _}}) -> lists:member(ItemId, ItemIDs) end, Items) end, %% Generate the XML response (Item list), limiting the %% number of items sent to MaxItems: {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "items", nodeAttr(Node), itemsEls(lists:sublist(SendItems, MaxItems))}]}]}; Error -> Error end end. get_items(Host, Node) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> node_call(Type, get_items, [NodeId, service_jid(Host)]) end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Items}} -> Items; Error -> Error end. get_item(Host, Node, ItemId) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> node_call(Type, get_item, [NodeId, ItemId]) end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Items}} -> Items; Error -> Error end. get_allowed_items_call(Host, NodeIdx, From, Type, Options, Owners) -> AccessModel = get_option(Options, access_model), AllowedGroups = get_option(Options, roster_groups_allowed, []), {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups), node_call(Type, get_items, [NodeIdx, From, AccessModel, PresenceSubscription, RosterGroup, undefined]). %% @spec (Host, Node, NodeId, Type, LJID, Number) -> any() %% Host = pubsubHost() %% Node = pubsubNode() %% NodeId = pubsubNodeId() %% Type = pubsubNodeType() %% LJID = {U, S, []} %% Number = last | integer() %% @doc

    Resend the items of a node to the user.

    %% @todo use cache-last-item feature send_items(Host, Node, NodeId, Type, {U,S,R} = LJID, last) -> case get_cached_item(Host, NodeId) of undefined -> send_items(Host, Node, NodeId, Type, LJID, 1); LastItem -> {ModifNow, ModifUSR} = LastItem#pubsub_item.modification, Stanza = event_stanza_with_delay( [{xmlelement, "items", nodeAttr(Node), itemsEls([LastItem])}], ModifNow, ModifUSR), case is_tuple(Host) of false -> ejabberd_router:route(service_jid(Host), jlib:make_jid(LJID), Stanza); true -> case ejabberd_sm:get_session_pid(U,S,R) of C2SPid when is_pid(C2SPid) -> ejabberd_c2s:broadcast(C2SPid, {pep_message, binary_to_list(Node)++"+notify"}, _Sender = service_jid(Host), Stanza); _ -> ok end end end; send_items(Host, Node, NodeId, Type, {U,S,R} = LJID, Number) -> ToSend = case node_action(Host, Type, get_items, [NodeId, LJID]) of {result, []} -> []; {result, Items} -> case Number of N when N > 0 -> lists:sublist(Items, N); _ -> Items end; _ -> [] end, Stanza = case ToSend of [LastItem] -> {ModifNow, ModifUSR} = LastItem#pubsub_item.modification, event_stanza_with_delay( [{xmlelement, "items", nodeAttr(Node), itemsEls(ToSend)}], ModifNow, ModifUSR); _ -> event_stanza( [{xmlelement, "items", nodeAttr(Node), itemsEls(ToSend)}]) end, case is_tuple(Host) of false -> ejabberd_router:route(service_jid(Host), jlib:make_jid(LJID), Stanza); true -> case ejabberd_sm:get_session_pid(U,S,R) of C2SPid when is_pid(C2SPid) -> ejabberd_c2s:broadcast(C2SPid, {pep_message, binary_to_list(Node)++"+notify"}, _Sender = service_jid(Host), Stanza); _ -> ok end end. %% @spec (Host, JID, Plugins) -> {error, Reason} | {result, Response} %% Host = host() %% JID = jid() %% Plugins = [Plugin::string()] %% Reason = stanzaError() %% Response = [pubsubIQResponse()] %% @doc

    Return the list of affiliations as an XMPP response.

    get_affiliations(Host, <<>>, JID, Plugins) when is_list(Plugins) -> Result = lists:foldl( fun(Type, {Status, Acc}) -> Features = features(Type), RetrieveFeature = lists:member("retrieve-affiliations", Features), if not RetrieveFeature -> %% Service does not support retreive affiliatons {{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-affiliations")}, Acc}; true -> {result, Affiliations} = node_action(Host, Type, get_entity_affiliations, [Host, JID]), {Status, [Affiliations|Acc]} end end, {ok, []}, Plugins), case Result of {ok, Affiliations} -> Entities = lists:flatmap( fun({_, none}) -> []; ({#pubsub_node{nodeid = {_, Node}}, Affiliation}) -> [{xmlelement, "affiliation", [{"affiliation", affiliation_to_string(Affiliation)}|nodeAttr(Node)], []}] end, lists:usort(lists:flatten(Affiliations))), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "affiliations", [], Entities}]}]}; {Error, _} -> Error end; get_affiliations(Host, NodeId, JID, Plugins) when is_list(Plugins) -> Result = lists:foldl( fun(Type, {Status, Acc}) -> Features = features(Type), RetrieveFeature = lists:member("retrieve-affiliations", Features), if not RetrieveFeature -> %% Service does not support retreive affiliatons {{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-affiliations")}, Acc}; true -> {result, Affiliations} = node_action(Host, Type, get_entity_affiliations, [Host, JID]), {Status, [Affiliations|Acc]} end end, {ok, []}, Plugins), case Result of {ok, Affiliations} -> Entities = lists:flatmap( fun({_, none}) -> []; ({#pubsub_node{nodeid = {_, Node}}, Affiliation}) when NodeId == Node -> [{xmlelement, "affiliation", [{"affiliation", affiliation_to_string(Affiliation)}|nodeAttr(Node)], []}]; (_) -> [] end, lists:usort(lists:flatten(Affiliations))), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "affiliations", [], Entities}]}]}; {Error, _} -> Error end. get_affiliations(Host, Node, JID) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> Features = features(Type), RetrieveFeature = lists:member("modify-affiliations", Features), {result, Affiliation} = node_call(Type, get_affiliation, [NodeId, JID]), if not RetrieveFeature -> %% Service does not support modify affiliations {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "modify-affiliations")}; Affiliation /= owner -> %% Entity is not an owner {error, ?ERR_FORBIDDEN}; true -> node_call(Type, get_node_affiliations, [NodeId]) end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, []}} -> {error, ?ERR_ITEM_NOT_FOUND}; {result, {_, Affiliations}} -> Entities = lists:flatmap( fun({_, none}) -> []; ({AJID, Affiliation}) -> [{xmlelement, "affiliation", [{"jid", jlib:jid_to_string(AJID)}, {"affiliation", affiliation_to_string(Affiliation)}], []}] end, Affiliations), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}], [{xmlelement, "affiliations", nodeAttr(Node), Entities}]}]}; Error -> Error end. set_affiliations(Host, Node, From, EntitiesEls) -> Owner = jlib:jid_tolower(jlib:jid_remove_resource(From)), Entities = lists:foldl( fun(El, Acc) -> case Acc of error -> error; _ -> case El of {xmlelement, "affiliation", Attrs, _} -> JID = jlib:string_to_jid( xml:get_attr_s("jid", Attrs)), Affiliation = string_to_affiliation( xml:get_attr_s("affiliation", Attrs)), if (JID == error) or (Affiliation == false) -> error; true -> [{jlib:jid_tolower(JID), Affiliation} | Acc] end end end end, [], EntitiesEls), case Entities of error -> {error, ?ERR_BAD_REQUEST}; _ -> Action = fun(#pubsub_node{owners = Owners, type = Type, id = NodeId}=N) -> case lists:member(Owner, Owners) of true -> OwnerJID = jlib:make_jid(Owner), FilteredEntities = case Owners of [Owner] -> [E || E <- Entities, element(1, E) =/= OwnerJID]; _ -> Entities end, lists:foreach( fun({JID, Affiliation}) -> node_call(Type, set_affiliation, [NodeId, JID, Affiliation]), case Affiliation of owner -> NewOwner = jlib:jid_tolower(jlib:jid_remove_resource(JID)), NewOwners = [NewOwner|Owners], tree_call(Host, set_node, [N#pubsub_node{owners = NewOwners}]); none -> OldOwner = jlib:jid_tolower(jlib:jid_remove_resource(JID)), case lists:member(OldOwner, Owners) of true -> NewOwners = Owners--[OldOwner], tree_call(Host, set_node, [N#pubsub_node{owners = NewOwners}]); _ -> ok end; _ -> ok end end, FilteredEntities), {result, []}; _ -> {error, ?ERR_FORBIDDEN} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; Other -> Other end end. get_options(Host, Node, JID, SubID, Lang) -> Action = fun(#pubsub_node{type = Type, id = NodeID}) -> case lists:member("subscription-options", features(Type)) of true -> get_options_helper(JID, Lang, Node, NodeID, SubID, Type); false -> {error, extended_error( ?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscription-options")} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_Node, XForm}} -> {result, [XForm]}; Error -> Error end. get_options_helper(JID, Lang, Node, NodeID, SubID, Type) -> Subscriber = case jlib:string_to_jid(JID) of error -> {"", "", ""}; J -> jlib:jid_tolower(J) end, {result, Subs} = node_call(Type, get_subscriptions, [NodeID, Subscriber]), SubIDs = lists:foldl(fun({subscribed, SID}, Acc) -> [SID | Acc]; (_, Acc) -> Acc end, [], Subs), case {SubID, SubIDs} of {_, []} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "not-subscribed")}; {[], [SID]} -> read_sub(Subscriber, Node, NodeID, SID, Lang); {[], _} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "subid-required")}; {_, _} -> read_sub(Subscriber, Node, NodeID, SubID, Lang) end. read_sub(Subscriber, Node, NodeID, SubID, Lang) -> case pubsub_subscription:get_subscription(Subscriber, NodeID, SubID) of {error, notfound} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; {result, #pubsub_subscription{options = Options}} -> {result, XdataEl} = pubsub_subscription:get_options_xform(Lang, Options), OptionsEl = {xmlelement, "options", [{"jid", jlib:jid_to_string(Subscriber)}, {"subid", SubID}|nodeAttr(Node)], [XdataEl]}, PubsubEl = {xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [OptionsEl]}, {result, PubsubEl} end. set_options(Host, Node, JID, SubID, Configuration) -> Action = fun(#pubsub_node{type = Type, id = NodeID}) -> case lists:member("subscription-options", features(Type)) of true -> set_options_helper(Configuration, JID, NodeID, SubID, Type); false -> {error, extended_error( ?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscription-options")} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_Node, Result}} -> {result, Result}; Error -> Error end. set_options_helper(Configuration, JID, NodeID, SubID, Type) -> SubOpts = case pubsub_subscription:parse_options_xform(Configuration) of {result, GoodSubOpts} -> GoodSubOpts; _ -> invalid end, Subscriber = case jlib:string_to_jid(JID) of error -> {"", "", ""}; J -> jlib:jid_tolower(J) end, {result, Subs} = node_call(Type, get_subscriptions, [NodeID, Subscriber]), SubIDs = lists:foldl(fun({subscribed, SID}, Acc) -> [SID | Acc]; (_, Acc) -> Acc end, [], Subs), case {SubID, SubIDs} of {_, []} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "not-subscribed")}; {[], [SID]} -> write_sub(Subscriber, NodeID, SID, SubOpts); {[], _} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "subid-required")}; {_, _} -> write_sub(Subscriber, NodeID, SubID, SubOpts) end. write_sub(_Subscriber, _NodeID, _SubID, invalid) -> {error, extended_error(?ERR_BAD_REQUEST, "invalid-options")}; write_sub(Subscriber, NodeID, SubID, Options) -> case pubsub_subscription:set_subscription(Subscriber, NodeID, SubID, Options) of {error, notfound} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; {result, _} -> {result, []} end. %% @spec (Host, Node, JID, Plugins) -> {error, Reason} | {result, Response} %% Host = host() %% Node = pubsubNode() %% JID = jid() %% Plugins = [Plugin::string()] %% Reason = stanzaError() %% Response = [pubsubIQResponse()] %% @doc

    Return the list of subscriptions as an XMPP response.

    get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) -> Result = lists:foldl( fun(Type, {Status, Acc}) -> Features = features(Type), RetrieveFeature = lists:member("retrieve-subscriptions", Features), if not RetrieveFeature -> %% Service does not support retreive subscriptions {{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-subscriptions")}, Acc}; true -> Subscriber = jlib:jid_remove_resource(JID), {result, Subscriptions} = node_action(Host, Type, get_entity_subscriptions, [Host, Subscriber]), {Status, [Subscriptions|Acc]} end end, {ok, []}, Plugins), case Result of {ok, Subscriptions} -> Entities = lists:flatmap( fun({_, none}) -> []; ({#pubsub_node{nodeid = {_, SubsNode}}, Subscription}) -> case Node of <<>> -> [{xmlelement, "subscription", [{"subscription", subscription_to_string(Subscription)}|nodeAttr(SubsNode)], []}]; SubsNode -> [{xmlelement, "subscription", [{"subscription", subscription_to_string(Subscription)}], []}]; _ -> [] end; ({_, none, _}) -> []; ({#pubsub_node{nodeid = {_, SubsNode}}, Subscription, SubID, SubJID}) -> case Node of <<>> -> [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(SubJID)}, {"subid", SubID}, {"subscription", subscription_to_string(Subscription)}|nodeAttr(SubsNode)], []}]; SubsNode -> [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(SubJID)}, {"subid", SubID}, {"subscription", subscription_to_string(Subscription)}], []}]; _ -> [] end; ({#pubsub_node{nodeid = {_, SubsNode}}, Subscription, SubJID}) -> case Node of <<>> -> [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(SubJID)}, {"subscription", subscription_to_string(Subscription)}|nodeAttr(SubsNode)], []}]; SubsNode -> [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(SubJID)}, {"subscription", subscription_to_string(Subscription)}], []}]; _ -> [] end end, lists:usort(lists:flatten(Subscriptions))), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "subscriptions", [], Entities}]}]}; {Error, _} -> Error end. get_subscriptions(Host, Node, JID) -> Action = fun(#pubsub_node{type = Type, id = NodeId}) -> Features = features(Type), RetrieveFeature = lists:member("manage-subscriptions", Features), {result, Affiliation} = node_call(Type, get_affiliation, [NodeId, JID]), if not RetrieveFeature -> %% Service does not support manage subscriptions {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "manage-subscriptions")}; Affiliation /= owner -> %% Entity is not an owner {error, ?ERR_FORBIDDEN}; true -> node_call(Type, get_node_subscriptions, [NodeId]) end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Subscriptions}} -> Entities = lists:flatmap( fun({_, none}) -> []; ({_, pending, _}) -> []; ({AJID, Subscription}) -> [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(AJID)}, {"subscription", subscription_to_string(Subscription)}], []}]; ({AJID, Subscription, SubId}) -> [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(AJID)}, {"subscription", subscription_to_string(Subscription)}, {"subid", SubId}], []}] end, Subscriptions), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}], [{xmlelement, "subscriptions", nodeAttr(Node), Entities}]}]}; Error -> Error end. set_subscriptions(Host, Node, From, EntitiesEls) -> Owner = jlib:jid_tolower(jlib:jid_remove_resource(From)), Entities = lists:foldl( fun(El, Acc) -> case Acc of error -> error; _ -> case El of {xmlelement, "subscription", Attrs, _} -> JID = jlib:string_to_jid( xml:get_attr_s("jid", Attrs)), Subscription = string_to_subscription( xml:get_attr_s("subscription", Attrs)), SubId = xml:get_attr_s("subid", Attrs), if (JID == error) or (Subscription == false) -> error; true -> [{jlib:jid_tolower(JID), Subscription, SubId} | Acc] end end end end, [], EntitiesEls), case Entities of error -> {error, ?ERR_BAD_REQUEST}; _ -> Notify = fun(JID, Sub, _SubId) -> Stanza = {xmlelement, "message", [], [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "subscription", [{"jid", jlib:jid_to_string(JID)}, %{"subid", SubId}, {"subscription", subscription_to_string(Sub)} | nodeAttr(Node)], []}]}]}, ejabberd_router:route(service_jid(Host), jlib:make_jid(JID), Stanza) end, Action = fun(#pubsub_node{owners = Owners, type = Type, id = NodeId}) -> case lists:member(Owner, Owners) of true -> Result = lists:foldl(fun({JID, Subscription, SubId}, Acc) -> case node_call(Type, set_subscriptions, [NodeId, JID, Subscription, SubId]) of {error, Err} -> [{error, Err} | Acc]; _ -> Notify(JID, Subscription, SubId), Acc end end, [], Entities), case Result of [] -> {result, []}; _ -> {error, ?ERR_NOT_ACCEPTABLE} end; _ -> {error, ?ERR_FORBIDDEN} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; Other -> Other end end. get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups) -> if (AccessModel == presence) or (AccessModel == roster) -> case Host of {User, Server, _} -> get_roster_info(User, Server, From, AllowedGroups); _ -> [{OUser, OServer, _}|_] = Owners, get_roster_info(OUser, OServer, From, AllowedGroups) end; true -> {true, true} end. %% @spec (OwnerUser, OwnerServer, {SubscriberUser, SubscriberServer, SubscriberResource}, AllowedGroups) %% -> {PresenceSubscription, RosterGroup} get_roster_info(_, _, {"", "", _}, _) -> {false, false}; get_roster_info(OwnerUser, OwnerServer, {SubscriberUser, SubscriberServer, _}, AllowedGroups) -> {Subscription, Groups} = ejabberd_hooks:run_fold( roster_get_jid_info, OwnerServer, {none, []}, [OwnerUser, OwnerServer, {SubscriberUser, SubscriberServer, ""}]), PresenceSubscription = (Subscription == both) orelse (Subscription == from) orelse ({OwnerUser, OwnerServer} == {SubscriberUser, SubscriberServer}), RosterGroup = lists:any(fun(Group) -> lists:member(Group, AllowedGroups) end, Groups), {PresenceSubscription, RosterGroup}; get_roster_info(OwnerUser, OwnerServer, JID, AllowedGroups) -> get_roster_info(OwnerUser, OwnerServer, jlib:jid_tolower(JID), AllowedGroups). %% @spec (AffiliationStr) -> Affiliation %% AffiliationStr = string() %% Affiliation = atom() %% @doc

    Convert an affiliation type from string to atom.

    string_to_affiliation("owner") -> owner; string_to_affiliation("publisher") -> publisher; string_to_affiliation("member") -> member; string_to_affiliation("outcast") -> outcast; string_to_affiliation("none") -> none; string_to_affiliation(_) -> false. %% @spec (SubscriptionStr) -> Subscription %% SubscriptionStr = string() %% Subscription = atom() %% @doc

    Convert a subscription type from string to atom.

    string_to_subscription("subscribed") -> subscribed; string_to_subscription("pending") -> pending; string_to_subscription("unconfigured") -> unconfigured; string_to_subscription("none") -> none; string_to_subscription(_) -> false. %% @spec (Affiliation) -> AffiliationStr %% Affiliation = atom() %% AffiliationStr = string() %% @doc

    Convert an affiliation type from atom to string.

    affiliation_to_string(owner) -> "owner"; affiliation_to_string(publisher) -> "publisher"; affiliation_to_string(member) -> "member"; affiliation_to_string(outcast) -> "outcast"; affiliation_to_string(_) -> "none". %% @spec (Subscription) -> SubscriptionStr %% Subscription = atom() %% SubscriptionStr = string() %% @doc

    Convert a subscription type from atom to string.

    subscription_to_string(subscribed) -> "subscribed"; subscription_to_string(pending) -> "pending"; subscription_to_string(unconfigured) -> "unconfigured"; subscription_to_string(_) -> "none". %% @spec (Node) -> NodeStr %% Node = pubsubNode() %% NodeStr = string() %% @doc

    Convert a node type from pubsubNode to string.

    node_to_string(Node) -> binary_to_list(Node). string_to_node(SNode) -> list_to_binary(SNode). %% @spec (Host) -> jid() %% Host = host() %% @doc

    Generate pubsub service JID.

    service_jid(Host) -> case Host of {U,S,_} -> {jid, U, S, "", U, S, ""}; _ -> {jid, "", Host, "", "", Host, ""} end. %% @spec (LJID, NotifyType, Depth, NodeOptions, SubOptions) -> boolean() %% LJID = jid() %% NotifyType = items | nodes %% Depth = integer() %% NodeOptions = [{atom(), term()}] %% SubOptions = [{atom(), term()}] %% @doc

    Check if a notification must be delivered or not based on %% node and subscription options.

    is_to_deliver(LJID, NotifyType, Depth, NodeOptions, SubOptions) -> sub_to_deliver(LJID, NotifyType, Depth, SubOptions) andalso node_to_deliver(LJID, NodeOptions). sub_to_deliver(_LJID, NotifyType, Depth, SubOptions) -> lists:all(fun (Option) -> sub_option_can_deliver(NotifyType, Depth, Option) end, SubOptions). sub_option_can_deliver(items, _, {subscription_type, nodes}) -> false; sub_option_can_deliver(nodes, _, {subscription_type, items}) -> false; sub_option_can_deliver(_, _, {subscription_depth, all}) -> true; sub_option_can_deliver(_, Depth, {subscription_depth, D}) -> Depth =< D; sub_option_can_deliver(_, _, {deliver, false}) -> false; sub_option_can_deliver(_, _, {expire, When}) -> now() < When; sub_option_can_deliver(_, _, _) -> true. node_to_deliver(LJID, NodeOptions) -> PresenceDelivery = get_option(NodeOptions, presence_based_delivery), presence_can_deliver(LJID, PresenceDelivery). presence_can_deliver(_, false) -> true; presence_can_deliver({User, Server, Resource}, true) -> case mnesia:dirty_match_object({session, '_', '_', {User, Server}, '_', '_'}) of [] -> false; Ss -> lists:foldl(fun(_, true) -> true; ({session, _, _ , _, undefined, _}, _Acc) -> false; ({session, _, {_, _, R}, _, _Priority, _}, _Acc) -> case Resource of [] -> true; R -> true; _ -> false end end, false, Ss) end. state_can_deliver({U, S, R}, []) -> [{U, S, R}]; state_can_deliver({U, S, R}, SubOptions) -> %% Check SubOptions for 'show_values' case lists:keysearch('show_values', 1, SubOptions) of %% If not in suboptions, item can be delivered, case doesn't apply false -> [{U, S, R}]; %% If in a suboptions ... {_, {_, ShowValues}} -> %% Get subscriber resources Resources = case R of %% If the subscriber JID is a bare one, get all its resources [] -> user_resources(U, S); %% If the subscriber JID is a full one, use its resource R -> [R] end, %% For each resource, test if the item is allowed to be delivered %% based on resource state lists:foldl( fun(Resource, Acc) -> get_resource_state({U, S, Resource}, ShowValues, Acc) end, [], Resources) end. get_resource_state({U, S, R}, ShowValues, JIDs) -> %% Get user session PID case ejabberd_sm:get_session_pid(U, S, R) of %% If no PID, item can be delivered none -> lists:append([{U, S, R}], JIDs); %% If PID ... Pid -> %% Get user resource state %% TODO : add a catch clause Show = case ejabberd_c2s:get_presence(Pid) of {_, _, "available", _} -> "online"; {_, _, State, _} -> State end, %% Is current resource state listed in 'show-values' suboption ? case lists:member(Show, ShowValues) of %andalso Show =/= "online" of %% If yes, item can be delivered true -> lists:append([{U, S, R}], JIDs); %% If no, item can't be delivered false -> JIDs end end. %% @spec (Payload) -> int() %% Payload = term() %% @doc

    Count occurence of XML elements in payload.

    payload_xmlelements(Payload) -> payload_xmlelements(Payload, 0). payload_xmlelements([], Count) -> Count; payload_xmlelements([{xmlelement, _, _, _}|Tail], Count) -> payload_xmlelements(Tail, Count+1); payload_xmlelements([_|Tail], Count) -> payload_xmlelements(Tail, Count). %% @spec (Els) -> stanza() %% Els = [xmlelement()] %% @doc

    Build pubsub event stanza

    event_stanza(Els) -> event_stanza_withmoreels(Els, []). event_stanza_with_delay(Els, ModifNow, ModifUSR) -> DateTime = calendar:now_to_datetime(ModifNow), MoreEls = [jlib:timestamp_to_xml(DateTime, utc, ModifUSR, "")], event_stanza_withmoreels(Els, MoreEls). event_stanza_withmoreels(Els, MoreEls) -> {xmlelement, "message", [], [{xmlelement, "event", [{"xmlns", ?NS_PUBSUB_EVENT}], Els} | MoreEls]}. %%%%%% broadcast functions broadcast_publish_item(Host, Node, NodeId, Type, NodeOptions, Removed, ItemId, From, Payload) -> case get_collection_subscriptions(Host, Node) of SubsByDepth when is_list(SubsByDepth) -> Content = case get_option(NodeOptions, deliver_payloads) of true -> Payload; false -> [] end, Stanza = event_stanza( [{xmlelement, "items", nodeAttr(Node), [{xmlelement, "item", itemAttr(ItemId), Content}]}]), broadcast_stanza(Host, From, Node, NodeId, Type, NodeOptions, SubsByDepth, items, Stanza, true), case Removed of [] -> ok; _ -> case get_option(NodeOptions, notify_retract) of true -> RetractStanza = event_stanza( [{xmlelement, "items", nodeAttr(Node), [{xmlelement, "retract", itemAttr(RId), []} || RId <- Removed]}]), broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, items, RetractStanza, true); _ -> ok end end, {result, true}; _ -> {result, false} end. broadcast_retract_items(Host, Node, NodeId, Type, NodeOptions, ItemIds) -> broadcast_retract_items(Host, Node, NodeId, Type, NodeOptions, ItemIds, false). broadcast_retract_items(_Host, _Node, _NodeId, _Type, _NodeOptions, [], _ForceNotify) -> {result, false}; broadcast_retract_items(Host, Node, NodeId, Type, NodeOptions, ItemIds, ForceNotify) -> case (get_option(NodeOptions, notify_retract) or ForceNotify) of true -> case get_collection_subscriptions(Host, Node) of SubsByDepth when is_list(SubsByDepth) -> Stanza = event_stanza( [{xmlelement, "items", nodeAttr(Node), [{xmlelement, "retract", itemAttr(ItemId), []} || ItemId <- ItemIds]}]), broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, items, Stanza, true), {result, true}; _ -> {result, false} end; _ -> {result, false} end. broadcast_purge_node(Host, Node, NodeId, Type, NodeOptions) -> case get_option(NodeOptions, notify_retract) of true -> case get_collection_subscriptions(Host, Node) of SubsByDepth when is_list(SubsByDepth) -> Stanza = event_stanza( [{xmlelement, "purge", nodeAttr(Node), []}]), broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, nodes, Stanza, false), {result, true}; _ -> {result, false} end; _ -> {result, false} end. broadcast_removed_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth) -> case get_option(NodeOptions, notify_delete) of true -> case SubsByDepth of [] -> {result, false}; _ -> Stanza = event_stanza( [{xmlelement, "delete", nodeAttr(Node), []}]), broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, nodes, Stanza, false), {result, true} end; _ -> {result, false} end. broadcast_created_node(_, _, _, _, _, []) -> {result, false}; broadcast_created_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth) -> Stanza = event_stanza([{xmlelement, "create", nodeAttr(Node), []}]), broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, nodes, Stanza, true), {result, true}. broadcast_config_notification(Host, Node, NodeId, Type, NodeOptions, Lang) -> case get_option(NodeOptions, notify_config) of true -> case get_collection_subscriptions(Host, Node) of SubsByDepth when is_list(SubsByDepth) -> Content = case get_option(NodeOptions, deliver_payloads) of true -> [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}], get_configure_xfields(Type, NodeOptions, Lang, [])}]; false -> [] end, Stanza = event_stanza( [{xmlelement, "configuration", nodeAttr(Node), Content}]), broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, nodes, Stanza, false), {result, true}; _ -> {result, false} end; _ -> {result, false} end. get_collection_subscriptions(Host, Node) -> Action = fun() -> {result, lists:map(fun({Depth, Nodes}) -> {Depth, [{N, get_node_subs(N)} || N <- Nodes]} end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))} end, case transaction(Action, sync_dirty) of {result, CollSubs} -> CollSubs; _ -> [] end. get_node_subs(#pubsub_node{type = Type, id = NodeID}) -> case node_call(Type, get_node_subscriptions, [NodeID]) of {result, Subs} -> get_options_for_subs(NodeID, Subs); Other -> Other end. get_options_for_subs(NodeID, Subs) -> lists:foldl(fun({JID, subscribed, SubID}, Acc) -> case pubsub_subscription:read_subscription(JID, NodeID, SubID) of {error, notfound} -> [{JID, SubID, []} | Acc]; #pubsub_subscription{options = Options} -> [{JID, SubID, Options} | Acc]; _ -> Acc end; (_, Acc) -> Acc end, [], Subs). broadcast_stanza(Host, _Node, _NodeId, _Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM) -> NotificationType = get_option(NodeOptions, notification_type, headline), BroadcastAll = get_option(NodeOptions, broadcast_all_resources), %% XXX this is not standard, but usefull From = service_jid(Host), Stanza = case NotificationType of normal -> BaseStanza; MsgType -> add_message_type(BaseStanza, atom_to_list(MsgType)) end, %% Handles explicit subscriptions SubIDsByJID = subscribed_nodes_by_jid(NotifyType, SubsByDepth), lists:foreach(fun ({LJID, NodeName, SubIDs}) -> LJIDs = case BroadcastAll of true -> {U, S, _} = LJID, [{U, S, R} || R <- user_resources(U, S)]; false -> [LJID] end, %% Determine if the stanza should have SHIM ('SubID' and 'name') headers StanzaToSend = case {SHIM, SubIDs} of {false, _} -> Stanza; %% If there's only one SubID, don't add it {true, [_]} -> add_shim_headers(Stanza, collection_shim(NodeName)); {true, SubIDs} -> add_shim_headers(Stanza, lists:append(collection_shim(NodeName), subid_shim(SubIDs))) end, lists:foreach(fun(To) -> ejabberd_router:route(From, jlib:make_jid(To), StanzaToSend) end, LJIDs) end, SubIDsByJID). broadcast_stanza({LUser, LServer, LResource}, Publisher, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM) -> broadcast_stanza({LUser, LServer, LResource}, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM), %% Handles implicit presence subscriptions SenderResource = case LResource of [] -> case user_resources(LUser, LServer) of [Resource|_] -> Resource; _ -> "" end; _ -> LResource end, case ejabberd_sm:get_session_pid(LUser, LServer, SenderResource) of C2SPid when is_pid(C2SPid) -> Stanza = case get_option(NodeOptions, notification_type, headline) of normal -> BaseStanza; MsgType -> add_message_type(BaseStanza, atom_to_list(MsgType)) end, %% set the from address on the notification to the bare JID of the account owner %% Also, add "replyto" if entity has presence subscription to the account owner %% See XEP-0163 1.1 section 4.3.1 ejabberd_c2s:broadcast(C2SPid, {pep_message, binary_to_list(Node)++"+notify"}, _Sender = jlib:make_jid(LUser, LServer, ""), _StanzaToSend = add_extended_headers(Stanza, _ReplyTo = extended_headers([jlib:jid_to_string(Publisher)]))); _ -> ?DEBUG("~p@~p has no session; can't deliver ~p to contacts", [LUser, LServer, BaseStanza]) end; broadcast_stanza(Host, _Publisher, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM) -> broadcast_stanza(Host, Node, NodeId, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM). subscribed_nodes_by_jid(NotifyType, SubsByDepth) -> NodesToDeliver = fun(Depth, Node, Subs, Acc) -> NodeName = case Node#pubsub_node.nodeid of {_, N} -> N; Other -> Other end, NodeOptions = Node#pubsub_node.options, lists:foldl(fun({LJID, SubID, SubOptions}, {JIDs, Recipients}) -> case is_to_deliver(LJID, NotifyType, Depth, NodeOptions, SubOptions) of true -> %% If is to deliver : case state_can_deliver(LJID, SubOptions) of [] -> {JIDs, Recipients}; JIDsToDeliver -> lists:foldl( fun(JIDToDeliver, {JIDsAcc, RecipientsAcc}) -> case lists:member(JIDToDeliver, JIDs) of %% check if the JIDs co-accumulator contains the Subscription Jid, false -> %% - if not, %% - add the Jid to JIDs list co-accumulator ; %% - create a tuple of the Jid, NodeId, and SubID (as list), %% and add the tuple to the Recipients list co-accumulator {[JIDToDeliver | JIDsAcc], [{JIDToDeliver, NodeName, [SubID]} | RecipientsAcc]}; true -> %% - if the JIDs co-accumulator contains the Jid %% get the tuple containing the Jid from the Recipient list co-accumulator {_, {JIDToDeliver, NodeName1, SubIDs}} = lists:keysearch(JIDToDeliver, 1, RecipientsAcc), %% delete the tuple from the Recipients list % v1 : Recipients1 = lists:keydelete(LJID, 1, Recipients), % v2 : Recipients1 = lists:keyreplace(LJID, 1, Recipients, {LJID, NodeId1, [SubID | SubIDs]}), %% add the SubID to the SubIDs list in the tuple, %% and add the tuple back to the Recipients list co-accumulator % v1.1 : {JIDs, lists:append(Recipients1, [{LJID, NodeId1, lists:append(SubIDs, [SubID])}])} % v1.2 : {JIDs, [{LJID, NodeId1, [SubID | SubIDs]} | Recipients1]} % v2: {JIDs, Recipients1} {JIDsAcc, lists:keyreplace(JIDToDeliver, 1, RecipientsAcc, {JIDToDeliver, NodeName1, [SubID | SubIDs]})} end end, {JIDs, Recipients}, JIDsToDeliver) end; false -> {JIDs, Recipients} end end, Acc, Subs) end, DepthsToDeliver = fun({Depth, SubsByNode}, Acc1) -> lists:foldl(fun({Node, Subs}, Acc2) -> NodesToDeliver(Depth, Node, Subs, Acc2) end, Acc1, SubsByNode) end, {_, JIDSubs} = lists:foldl(DepthsToDeliver, {[], []}, SubsByDepth), JIDSubs. user_resources(User, Server) -> ejabberd_sm:get_user_resources(User, Server). %%%%%%% Configuration handling %%

    There are several reasons why the default node configuration options request might fail:

    %%
      %%
    • The service does not support node configuration.
    • %%
    • The service does not support retrieval of default node configuration.
    • %%
    get_configure(Host, ServerHost, Node, From, Lang) -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId}) -> case node_call(Type, get_affiliation, [NodeId, From]) of {result, owner} -> Groups = ejabberd_hooks:run_fold(roster_groups, ServerHost, [], [ServerHost]), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}], [{xmlelement, "configure", nodeAttr(Node), [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], get_configure_xfields(Type, Options, Lang, Groups) }]}]}]}; _ -> {error, ?ERR_FORBIDDEN} end end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; Other -> Other end. get_default(Host, Node, _From, Lang) -> Type = select_type(Host, Host, Node), Options = node_options(Type), {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}], [{xmlelement, "default", [], [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}], get_configure_xfields(Type, Options, Lang, []) }]}]}]}. %% Get node option %% The result depend of the node type plugin system. get_option([], _) -> false; get_option(Options, Var) -> get_option(Options, Var, false). get_option(Options, Var, Def) -> case lists:keysearch(Var, 1, Options) of {value, {_Val, Ret}} -> Ret; _ -> Def end. %% Get default options from the module plugin. node_options(Type) -> Module = list_to_atom(?PLUGIN_PREFIX ++ Type), case catch Module:options() of {'EXIT',{undef,_}} -> DefaultModule = list_to_atom(?PLUGIN_PREFIX++?STDNODE), DefaultModule:options(); Result -> Result end. %% @spec (Host, Options) -> MaxItems %% Host = host() %% Options = [Option] %% Option = {Key::atom(), Value::term()} %% MaxItems = integer() | unlimited %% @doc

    Return the maximum number of items for a given node.

    %%

    Unlimited means that there is no limit in the number of items that can %% be stored.

    %% @todo In practice, the current data structure means that we cannot manage %% millions of items on a given node. This should be addressed in a new %% version. max_items(Host, Options) -> case get_option(Options, persist_items) of true -> case get_option(Options, max_items) of false -> unlimited; Result when (Result < 0) -> 0; Result -> Result end; false -> case get_option(Options, send_last_published_item) of never -> 0; _ -> case is_last_item_cache_enabled(Host) of true -> 0; false -> 1 end end end. -define(BOOL_CONFIG_FIELD(Label, Var), ?BOOLXFIELD(Label, "pubsub#" ++ atom_to_list(Var), get_option(Options, Var))). -define(STRING_CONFIG_FIELD(Label, Var), ?STRINGXFIELD(Label, "pubsub#" ++ atom_to_list(Var), get_option(Options, Var, ""))). -define(INTEGER_CONFIG_FIELD(Label, Var), ?STRINGXFIELD(Label, "pubsub#" ++ atom_to_list(Var), integer_to_list(get_option(Options, Var)))). -define(JLIST_CONFIG_FIELD(Label, Var, Opts), ?LISTXFIELD(Label, "pubsub#" ++ atom_to_list(Var), jlib:jid_to_string(get_option(Options, Var)), [jlib:jid_to_string(O) || O <- Opts])). -define(ALIST_CONFIG_FIELD(Label, Var, Opts), ?LISTXFIELD(Label, "pubsub#" ++ atom_to_list(Var), atom_to_list(get_option(Options, Var)), [atom_to_list(O) || O <- Opts])). -define(LISTM_CONFIG_FIELD(Label, Var, Opts), ?LISTMXFIELD(Label, "pubsub#" ++ atom_to_list(Var), get_option(Options, Var), Opts)). -define(NLIST_CONFIG_FIELD(Label, Var), ?STRINGMXFIELD(Label, "pubsub#" ++ atom_to_list(Var), [node_to_string(N) || N <- get_option(Options, Var, [])])). get_configure_xfields(_Type, Options, Lang, Groups) -> [?XFIELD("hidden", "", "FORM_TYPE", ?NS_PUBSUB_NODE_CONFIG), ?BOOL_CONFIG_FIELD("Deliver payloads with event notifications", deliver_payloads), ?BOOL_CONFIG_FIELD("Deliver event notifications", deliver_notifications), ?BOOL_CONFIG_FIELD("Notify subscribers when the node configuration changes", notify_config), ?BOOL_CONFIG_FIELD("Notify subscribers when the node is deleted", notify_delete), ?BOOL_CONFIG_FIELD("Notify subscribers when items are removed from the node", notify_retract), ?BOOL_CONFIG_FIELD("Persist items to storage", persist_items), ?STRING_CONFIG_FIELD("A friendly name for the node", title), ?INTEGER_CONFIG_FIELD("Max # of items to persist", max_items), ?BOOL_CONFIG_FIELD("Whether to allow subscriptions", subscribe), ?ALIST_CONFIG_FIELD("Specify the access model", access_model, [open, authorize, presence, roster, whitelist]), %% XXX: change to list-multi, include current roster groups as options ?LISTM_CONFIG_FIELD("Roster groups allowed to subscribe", roster_groups_allowed, Groups), ?ALIST_CONFIG_FIELD("Specify the publisher model", publish_model, [publishers, subscribers, open]), ?BOOL_CONFIG_FIELD("Purge all items when the relevant publisher goes offline", purge_offline), ?ALIST_CONFIG_FIELD("Specify the event message type", notification_type, [headline, normal]), ?INTEGER_CONFIG_FIELD("Max payload size in bytes", max_payload_size), ?ALIST_CONFIG_FIELD("When to send the last published item", send_last_published_item, [never, on_sub, on_sub_and_presence]), ?BOOL_CONFIG_FIELD("Only deliver notifications to available users", presence_based_delivery), ?NLIST_CONFIG_FIELD("The collections with which a node is affiliated", collection) ]. %%

    There are several reasons why the node configuration request might fail:

    %%
      %%
    • The service does not support node configuration.
    • %%
    • The requesting entity does not have sufficient privileges to configure the node.
    • %%
    • The request did not specify a node.
    • %%
    • The node has no configuration options.
    • %%
    • The specified node does not exist.
    • %%
    set_configure(Host, Node, From, Els, Lang) -> case xml:remove_cdata(Els) of [{xmlelement, "x", _Attrs1, _Els1} = XEl] -> case {xml:get_tag_attr_s("xmlns", XEl), xml:get_tag_attr_s("type", XEl)} of {?NS_XDATA, "cancel"} -> {result, []}; {?NS_XDATA, "submit"} -> Action = fun(#pubsub_node{options = Options, type = Type, id = NodeId} = N) -> case node_call(Type, get_affiliation, [NodeId, From]) of {result, owner} -> case jlib:parse_xdata_submit(XEl) of invalid -> {error, ?ERR_BAD_REQUEST}; XData -> OldOpts = case Options of [] -> node_options(Type); _ -> Options end, case set_xoption(Host, XData, OldOpts) of NewOpts when is_list(NewOpts) -> case tree_call(Host, set_node, [N#pubsub_node{options = NewOpts}]) of ok -> {result, ok}; Err -> Err end; Err -> Err end end; _ -> {error, ?ERR_FORBIDDEN} end end, case transaction(Host, Node, Action, transaction) of {result, {TNode, ok}} -> NodeId = TNode#pubsub_node.id, Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, broadcast_config_notification(Host, Node, NodeId, Type, Options, Lang), {result, []}; Other -> Other end; _ -> {error, ?ERR_BAD_REQUEST} end; _ -> {error, ?ERR_BAD_REQUEST} end. add_opt(Key, Value, Opts) -> Opts1 = lists:keydelete(Key, 1, Opts), [{Key, Value} | Opts1]. -define(SET_BOOL_XOPT(Opt, Val), BoolVal = case Val of "0" -> false; "1" -> true; "false" -> false; "true" -> true; _ -> error end, case BoolVal of error -> {error, ?ERR_NOT_ACCEPTABLE}; _ -> set_xoption(Host, Opts, add_opt(Opt, BoolVal, NewOpts)) end). -define(SET_STRING_XOPT(Opt, Val), set_xoption(Host, Opts, add_opt(Opt, Val, NewOpts))). -define(SET_INTEGER_XOPT(Opt, Val, Min, Max), case catch list_to_integer(Val) of IVal when is_integer(IVal), IVal >= Min, IVal =< Max -> set_xoption(Host, Opts, add_opt(Opt, IVal, NewOpts)); _ -> {error, ?ERR_NOT_ACCEPTABLE} end). -define(SET_ALIST_XOPT(Opt, Val, Vals), case lists:member(Val, [atom_to_list(V) || V <- Vals]) of true -> set_xoption(Host, Opts, add_opt(Opt, list_to_atom(Val), NewOpts)); false -> {error, ?ERR_NOT_ACCEPTABLE} end). -define(SET_LIST_XOPT(Opt, Val), set_xoption(Host, Opts, add_opt(Opt, Val, NewOpts))). set_xoption(_Host, [], NewOpts) -> NewOpts; set_xoption(Host, [{"FORM_TYPE", _} | Opts], NewOpts) -> set_xoption(Host, Opts, NewOpts); set_xoption(Host, [{"pubsub#roster_groups_allowed", Value} | Opts], NewOpts) -> ?SET_LIST_XOPT(roster_groups_allowed, Value); set_xoption(Host, [{"pubsub#deliver_payloads", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(deliver_payloads, Val); set_xoption(Host, [{"pubsub#deliver_notifications", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(deliver_notifications, Val); set_xoption(Host, [{"pubsub#notify_config", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(notify_config, Val); set_xoption(Host, [{"pubsub#notify_delete", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(notify_delete, Val); set_xoption(Host, [{"pubsub#notify_retract", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(notify_retract, Val); set_xoption(Host, [{"pubsub#persist_items", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(persist_items, Val); set_xoption(Host, [{"pubsub#max_items", [Val]} | Opts], NewOpts) -> MaxItems = get_max_items_node(Host), ?SET_INTEGER_XOPT(max_items, Val, 0, MaxItems); set_xoption(Host, [{"pubsub#subscribe", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(subscribe, Val); set_xoption(Host, [{"pubsub#access_model", [Val]} | Opts], NewOpts) -> ?SET_ALIST_XOPT(access_model, Val, [open, authorize, presence, roster, whitelist]); set_xoption(Host, [{"pubsub#publish_model", [Val]} | Opts], NewOpts) -> ?SET_ALIST_XOPT(publish_model, Val, [publishers, subscribers, open]); set_xoption(Host, [{"pubsub#notification_type", [Val]} | Opts], NewOpts) -> ?SET_ALIST_XOPT(notification_type, Val, [headline, normal]); set_xoption(Host, [{"pubsub#node_type", [Val]} | Opts], NewOpts) -> ?SET_ALIST_XOPT(node_type, Val, [leaf, collection]); set_xoption(Host, [{"pubsub#max_payload_size", [Val]} | Opts], NewOpts) -> ?SET_INTEGER_XOPT(max_payload_size, Val, 0, ?MAX_PAYLOAD_SIZE); set_xoption(Host, [{"pubsub#send_last_published_item", [Val]} | Opts], NewOpts) -> ?SET_ALIST_XOPT(send_last_published_item, Val, [never, on_sub, on_sub_and_presence]); set_xoption(Host, [{"pubsub#presence_based_delivery", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(presence_based_delivery, Val); set_xoption(Host, [{"pubsub#purge_offline", [Val]} | Opts], NewOpts) -> ?SET_BOOL_XOPT(purge_offline, Val); set_xoption(Host, [{"pubsub#title", Value} | Opts], NewOpts) -> ?SET_STRING_XOPT(title, Value); set_xoption(Host, [{"pubsub#type", Value} | Opts], NewOpts) -> ?SET_STRING_XOPT(type, Value); set_xoption(Host, [{"pubsub#body_xslt", Value} | Opts], NewOpts) -> ?SET_STRING_XOPT(body_xslt, Value); set_xoption(Host, [{"pubsub#collection", Value} | Opts], NewOpts) -> NewValue = [string_to_node(V) || V <- Value], ?SET_LIST_XOPT(collection, NewValue); set_xoption(Host, [{"pubsub#node", [Value]} | Opts], NewOpts) -> NewValue = string_to_node(Value), ?SET_LIST_XOPT(node, NewValue); set_xoption(Host, [_ | Opts], NewOpts) -> % skip unknown field set_xoption(Host, Opts, NewOpts). get_max_items_node({_, ServerHost, _}) -> get_max_items_node(ServerHost); get_max_items_node(Host) -> case catch ets:lookup(gen_mod:get_module_proc(Host, config), max_items_node) of [{max_items_node, Integer}] -> Integer; _ -> ?MAXITEMS end. %%%% last item cache handling is_last_item_cache_enabled({_, ServerHost, _}) -> is_last_item_cache_enabled(ServerHost); is_last_item_cache_enabled(Host) -> case catch ets:lookup(gen_mod:get_module_proc(Host, config), last_item_cache) of [{last_item_cache, true}] -> true; _ -> false end. set_cached_item({_, ServerHost, _}, NodeId, ItemId, Publisher, Payload) -> set_cached_item(ServerHost, NodeId, ItemId, Publisher, Payload); set_cached_item(Host, NodeId, ItemId, Publisher, Payload) -> case is_last_item_cache_enabled(Host) of true -> mnesia:dirty_write({pubsub_last_item, NodeId, ItemId, {now(), jlib:jid_tolower(jlib:jid_remove_resource(Publisher))}, Payload}); _ -> ok end. unset_cached_item({_, ServerHost, _}, NodeId) -> unset_cached_item(ServerHost, NodeId); unset_cached_item(Host, NodeId) -> case is_last_item_cache_enabled(Host) of true -> mnesia:dirty_delete({pubsub_last_item, NodeId}); _ -> ok end. get_cached_item({_, ServerHost, _}, NodeId) -> get_cached_item(ServerHost, NodeId); get_cached_item(Host, NodeId) -> case is_last_item_cache_enabled(Host) of true -> case mnesia:dirty_read({pubsub_last_item, NodeId}) of [{pubsub_last_item, NodeId, ItemId, Creation, Payload}] -> #pubsub_item{itemid = {ItemId, NodeId}, payload = Payload, creation = Creation, modification = Creation}; _ -> undefined end; _ -> undefined end. %%%% plugin handling host(ServerHost) -> case catch ets:lookup(gen_mod:get_module_proc(ServerHost, config), host) of [{host, Host}] -> Host; _ -> "pubsub."++ServerHost end. plugins(Host) -> case catch ets:lookup(gen_mod:get_module_proc(Host, config), plugins) of [{plugins, []}] -> [?STDNODE]; [{plugins, PL}] -> PL; _ -> [?STDNODE] end. select_type(ServerHost, Host, Node, Type)-> SelectedType = case Host of {_User, _Server, _Resource} -> case catch ets:lookup(gen_mod:get_module_proc(ServerHost, config), pep_mapping) of [{pep_mapping, PM}] -> proplists:get_value(node_to_string(Node), PM, ?PEPNODE); _ -> ?PEPNODE end; _ -> Type end, ConfiguredTypes = plugins(ServerHost), case lists:member(SelectedType, ConfiguredTypes) of true -> SelectedType; false -> hd(ConfiguredTypes) end. select_type(ServerHost, Host, Node) -> select_type(ServerHost, Host, Node, hd(plugins(ServerHost))). features() -> [ % see plugin "access-authorize", % OPTIONAL "access-open", % OPTIONAL this relates to access_model option in node_hometree "access-presence", % OPTIONAL this relates to access_model option in node_pep %TODO "access-roster", % OPTIONAL "access-whitelist", % OPTIONAL % see plugin "auto-create", % OPTIONAL % see plugin "auto-subscribe", % RECOMMENDED "collections", % RECOMMENDED "config-node", % RECOMMENDED "create-and-configure", % RECOMMENDED % see plugin "create-nodes", % RECOMMENDED % see plugin "delete-items", % RECOMMENDED % see plugin "delete-nodes", % RECOMMENDED % see plugin "filtered-notifications", % RECOMMENDED % see plugin "get-pending", % OPTIONAL % see plugin "instant-nodes", % RECOMMENDED "item-ids", % RECOMMENDED "last-published", % RECOMMENDED %TODO "cache-last-item", %TODO "leased-subscription", % OPTIONAL % see plugin "manage-subscriptions", % OPTIONAL "member-affiliation", % RECOMMENDED %TODO "meta-data", % RECOMMENDED % see plugin "modify-affiliations", % OPTIONAL % see plugin "multi-collection", % OPTIONAL % see plugin "multi-subscribe", % OPTIONAL % see plugin "outcast-affiliation", % RECOMMENDED % see plugin "persistent-items", % RECOMMENDED "presence-notifications", % OPTIONAL "presence-subscribe", % RECOMMENDED % see plugin "publish", % REQUIRED %TODO "publish-options", % OPTIONAL "publisher-affiliation", % RECOMMENDED % see plugin "purge-nodes", % OPTIONAL % see plugin "retract-items", % OPTIONAL % see plugin "retrieve-affiliations", % RECOMMENDED "retrieve-default" % RECOMMENDED % see plugin "retrieve-items", % RECOMMENDED % see plugin "retrieve-subscriptions", % RECOMMENDED %TODO "shim", % OPTIONAL % see plugin "subscribe", % REQUIRED % see plugin "subscription-options", % OPTIONAL % see plugin "subscription-notifications" % OPTIONAL ]. features(Type) -> Module = list_to_atom(?PLUGIN_PREFIX++Type), features() ++ case catch Module:features() of {'EXIT', {undef, _}} -> []; Result -> Result end. features(Host, <<>>) -> lists:usort(lists:foldl(fun(Plugin, Acc) -> Acc ++ features(Plugin) end, [], plugins(Host))); features(Host, Node) -> Action = fun(#pubsub_node{type = Type}) -> {result, features(Type)} end, case transaction(Host, Node, Action, sync_dirty) of {result, Features} -> lists:usort(features() ++ Features); _ -> features() end. %% @doc

    node tree plugin call.

    tree_call({_User, Server, _Resource}, Function, Args) -> tree_call(Server, Function, Args); tree_call(Host, Function, Args) -> ?DEBUG("tree_call ~p ~p ~p",[Host, Function, Args]), Module = case catch ets:lookup(gen_mod:get_module_proc(Host, config), nodetree) of [{nodetree, N}] -> N; _ -> list_to_atom(?TREE_PREFIX ++ ?STDTREE) end, catch apply(Module, Function, Args). tree_action(Host, Function, Args) -> ?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]), Fun = fun() -> tree_call(Host, Function, Args) end, catch mnesia:sync_dirty(Fun). %% @doc

    node plugin call.

    node_call(Type, Function, Args) -> ?DEBUG("node_call ~p ~p ~p",[Type, Function, Args]), Module = list_to_atom(?PLUGIN_PREFIX++Type), case apply(Module, Function, Args) of {result, Result} -> {result, Result}; {error, Error} -> {error, Error}; {'EXIT', {undef, Undefined}} -> case Type of ?STDNODE -> {error, {undef, Undefined}}; _ -> node_call(?STDNODE, Function, Args) end; {'EXIT', Reason} -> {error, Reason}; Result -> {result, Result} %% any other return value is forced as result end. node_action(Host, Type, Function, Args) -> ?DEBUG("node_action ~p ~p ~p ~p",[Host,Type,Function,Args]), transaction(fun() -> node_call(Type, Function, Args) end, sync_dirty). %% @doc

    plugin transaction handling.

    transaction(Host, Node, Action, Trans) -> transaction(fun() -> case tree_call(Host, get_node, [Host, Node]) of N when is_record(N, pubsub_node) -> case Action(N) of {result, Result} -> {result, {N, Result}}; {atomic, {result, Result}} -> {result, {N, Result}}; Other -> Other end; Error -> Error end end, Trans). transaction(Host, Action, Trans) -> transaction(fun() -> {result, lists:foldl(Action, [], tree_call(Host, get_nodes, [Host]))} end, Trans). transaction(Fun, Trans) -> case catch mnesia:Trans(Fun) of {result, Result} -> {result, Result}; {error, Error} -> {error, Error}; {atomic, {result, Result}} -> {result, Result}; {atomic, {error, Error}} -> {error, Error}; {aborted, Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR}; {'EXIT', Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR}; Other -> ?ERROR_MSG("transaction return internal error: ~p~n", [Other]), {error, ?ERR_INTERNAL_SERVER_ERROR} end. %%%% helpers %% Add pubsub-specific error element extended_error(Error, Ext) -> extended_error(Error, Ext, [{"xmlns", ?NS_PUBSUB_ERRORS}]). extended_error(Error, unsupported, Feature) -> extended_error(Error, "unsupported", [{"xmlns", ?NS_PUBSUB_ERRORS}, {"feature", Feature}]); extended_error({xmlelement, Error, Attrs, SubEls}, Ext, ExtAttrs) -> {xmlelement, Error, Attrs, lists:reverse([{xmlelement, Ext, ExtAttrs, []} | SubEls])}. %% Give a uniq identifier uniqid() -> {T1, T2, T3} = now(), lists:flatten(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3])). % node attributes nodeAttr(Node) when is_list(Node) -> [{"node", Node}]; nodeAttr(Node) -> [{"node", node_to_string(Node)}]. % item attributes itemAttr([]) -> []; itemAttr(ItemId) -> [{"id", ItemId}]. % build item elements from item list itemsEls(Items) -> lists:map(fun(#pubsub_item{itemid = {ItemId, _}, payload = Payload}) -> {xmlelement, "item", itemAttr(ItemId), Payload} end, Items). add_message_type({xmlelement, "message", Attrs, Els}, Type) -> {xmlelement, "message", [{"type", Type}|Attrs], Els}; add_message_type(XmlEl, _Type) -> XmlEl. %% Place of changed at the bottom of the stanza %% cf. http://xmpp.org/extensions/xep-0060.html#publisher-publish-success-subid %% %% "[SHIM Headers] SHOULD be included after the event notification information %% (i.e., as the last child of the stanza)". add_shim_headers(Stanza, HeaderEls) -> add_headers(Stanza, "headers", ?NS_SHIM, HeaderEls). add_extended_headers(Stanza, HeaderEls) -> add_headers(Stanza, "addresses", ?NS_ADDRESS, HeaderEls). add_headers({xmlelement, Name, Attrs, Els}, HeaderName, HeaderNS, HeaderEls) -> HeaderEl = {xmlelement, HeaderName, [{"xmlns", HeaderNS}], HeaderEls}, {xmlelement, Name, Attrs, lists:append(Els, [HeaderEl])}. %% Removed multiple
    Foo
    elements %% Didn't seem compliant, but not sure. Confirmation required. %% cf. http://xmpp.org/extensions/xep-0248.html#notify %% %% "If an item is published to a node which is also included by a collection, %% and an entity is subscribed to that collection with a subscription type of %% "items" (Is there a way to check that currently ?), then the notifications %% generated by the service MUST contain additional information. The %% element contained in the notification message MUST specify the node %% identifier of the node that generated the notification (not the collection) %% and the element MUST contain a SHIM header that specifies the node %% identifier of the collection". collection_shim(Node) -> [{xmlelement, "header", [{"name", "Collection"}], [{xmlcdata, node_to_string(Node)}]}]. subid_shim(SubIDs) -> [{xmlelement, "header", [{"name", "SubID"}], [{xmlcdata, SubID}]} || SubID <- SubIDs]. %% The argument is a list of Jids because this function could be used %% with the 'pubsub#replyto' (type=jid-multi) node configuration. extended_headers(Jids) -> [{xmlelement, "address", [{"type", "replyto"}, {"jid", Jid}], []} || Jid <- Jids]. on_user_offline(_, JID, _) -> {User, Server, Resource} = jlib:jid_tolower(JID), case ejabberd_sm:get_user_resources(User, Server) of [] -> purge_offline({User, Server, Resource}); _ -> true end. purge_offline({User, Server, _} = LJID) -> Host = host(element(2, LJID)), Plugins = plugins(Host), Result = lists:foldl( fun(Type, {Status, Acc}) -> case lists:member("retrieve-affiliations", features(Type)) of false -> {{error, extended_error('feature-not-implemented', unsupported, "retrieve-affiliations")}, Acc}; true -> {result, Affiliations} = node_action(Host, Type, get_entity_affiliations, [Host, LJID]), {Status, [Affiliations|Acc]} end end, {ok, []}, Plugins), case Result of {ok, Affiliations} -> lists:foreach( fun({#pubsub_node{nodeid = {_, NodeId}, options = Options, type = Type}, Affiliation}) when Affiliation == 'owner' orelse Affiliation == 'publisher' -> Action = fun(#pubsub_node{type = NType, id = NodeIdx}) -> node_call(NType, get_items, [NodeIdx, service_jid(Host)]) end, case transaction(Host, NodeId, Action, sync_dirty) of {result, {_, []}} -> true; {result, {_, Items}} -> Features = features(Type), case {lists:member("retract-items", Features), lists:member("persistent-items", Features), get_option(Options, persist_items), get_option(Options, purge_offline)} of {true, true, true, true} -> ForceNotify = get_option(Options, notify_retract), lists:foreach( fun(#pubsub_item{itemid = {ItemId, _}, modification = {_, Modification}}) -> case Modification of {User, Server, _} -> delete_item(Host, NodeId, LJID, ItemId, ForceNotify); _ -> true end; (_) -> true end, Items); _ -> true end; Error -> Error end; (_) -> true end, lists:usort(lists:flatten(Affiliations))); {Error, _} -> ?DEBUG("on_user_offline ~p", [Error]) end. ejabberd-2.1.11/src/mod_pubsub/node_flat.erl0000664000000000000000000001411212240230175015602 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(node_flat). -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_node). %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/6, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1 ]). init(Host, ServerHost, Opts) -> node_hometree:init(Host, ServerHost, Opts). terminate(Host, ServerHost) -> node_hometree:terminate(Host, ServerHost). options() -> [{deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, true}, {purge_offline, false}, {persist_items, true}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, open}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, on_sub_and_presence}, {deliver_notifications, true}, {presence_based_delivery, false}]. features() -> node_hometree:features(). %% use same code as node_hometree, but do not limite node to %% the home/localhost/user/... hierarchy %% any node is allowed create_node_permission(Host, ServerHost, _Node, _ParentNode, Owner, Access) -> LOwner = jlib:jid_tolower(Owner), Allowed = case LOwner of {"", Host, ""} -> true; % pubsub service always allowed _ -> acl:match_rule(ServerHost, Access, LOwner) =:= allow end, {result, Allowed}. create_node(NodeId, Owner) -> node_hometree:create_node(NodeId, Owner). delete_node(Removed) -> node_hometree:delete_node(Removed). subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> node_hometree:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options). unsubscribe_node(NodeId, Sender, Subscriber, SubID) -> node_hometree:unsubscribe_node(NodeId, Sender, Subscriber, SubID). publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) -> node_hometree:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload). remove_extra_items(NodeId, MaxItems, ItemIds) -> node_hometree:remove_extra_items(NodeId, MaxItems, ItemIds). delete_item(NodeId, Publisher, PublishModel, ItemId) -> node_hometree:delete_item(NodeId, Publisher, PublishModel, ItemId). purge_node(NodeId, Owner) -> node_hometree:purge_node(NodeId, Owner). get_entity_affiliations(Host, Owner) -> node_hometree:get_entity_affiliations(Host, Owner). get_node_affiliations(NodeId) -> node_hometree:get_node_affiliations(NodeId). get_affiliation(NodeId, Owner) -> node_hometree:get_affiliation(NodeId, Owner). set_affiliation(NodeId, Owner, Affiliation) -> node_hometree:set_affiliation(NodeId, Owner, Affiliation). get_entity_subscriptions(Host, Owner) -> node_hometree:get_entity_subscriptions(Host, Owner). get_node_subscriptions(NodeId) -> node_hometree:get_node_subscriptions(NodeId). get_subscriptions(NodeId, Owner) -> node_hometree:get_subscriptions(NodeId, Owner). set_subscriptions(NodeId, Owner, Subscription, SubId) -> node_hometree:set_subscriptions(NodeId, Owner, Subscription, SubId). get_pending_nodes(Host, Owner) -> node_hometree:get_pending_nodes(Host, Owner). get_states(NodeId) -> node_hometree:get_states(NodeId). get_state(NodeId, JID) -> node_hometree:get_state(NodeId, JID). set_state(State) -> node_hometree:set_state(State). get_items(NodeId, From) -> node_hometree:get_items(NodeId, From). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). get_item(NodeId, ItemId) -> node_hometree:get_item(NodeId, ItemId). get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). set_item(Item) -> node_hometree:set_item(Item). get_item_name(Host, Node, Id) -> node_hometree:get_item_name(Host, Node, Id). node_to_path(Node) -> [binary_to_list(Node)]. path_to_node(Path) -> case Path of % default slot [Node] -> list_to_binary(Node); % handle old possible entries, used when migrating database content to new format [Node|_] when is_list(Node) -> list_to_binary(string:join([""|Path], "/")); % default case (used by PEP for example) _ -> list_to_binary(Path) end. ejabberd-2.1.11/src/mod_pubsub/gen_pubsub_nodetree.erl0000664000000000000000000000365512240230175017677 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %%% @private %%% @doc

    The module {@module} defines the PubSub node %%% tree plugin behaviour. This behaviour is used to check that a PubSub %%% node tree plugin respects the current ejabberd PubSub plugin API.

    -module(gen_pubsub_nodetree). -export([behaviour_info/1]). %% @spec (Query::atom()) -> Callbacks | atom() %% Callbacks = [{Function,Arity}] %% Function = atom() %% Arity = integer() %% @doc Behaviour definition behaviour_info(callbacks) -> [{init, 3}, {terminate, 2}, {options, 0}, {set_node, 1}, {get_node, 3}, {get_node, 2}, {get_node, 1}, {get_nodes, 2}, {get_nodes, 1}, {get_parentnodes, 3}, {get_parentnodes_tree, 3}, {get_subnodes, 3}, {get_subnodes_tree, 3}, {create_node, 6}, {delete_node, 2} ]; behaviour_info(_Other) -> undefined. ejabberd-2.1.11/src/mod_pubsub/node_pep.erl0000664000000000000000000002205512240230175015445 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %%% @doc The module {@module} is the pep PubSub plugin. %%%

    PubSub plugin nodes are using the {@link gen_pubsub_node} behaviour.

    -module(node_pep). -author('christophe.romain@process-one.net'). -include("ejabberd.hrl"). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_node). %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/6, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1 ]). init(Host, ServerHost, Opts) -> node_hometree:init(Host, ServerHost, Opts), complain_if_modcaps_disabled(ServerHost), ok. terminate(Host, ServerHost) -> node_hometree:terminate(Host, ServerHost), ok. options() -> [{deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, false}, {purge_offline, false}, {persist_items, false}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, presence}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, on_sub_and_presence}, {deliver_notifications, true}, {presence_based_delivery, true}]. features() -> ["create-nodes", %* "auto-create", %* "auto-subscribe", %* "delete-nodes", %* "delete-items", %* "filtered-notifications", %* "modify-affiliations", "outcast-affiliation", "persistent-items", "publish", %* "purge-nodes", "retract-items", "retrieve-affiliations", "retrieve-items", %* "retrieve-subscriptions", "subscribe" %* ]. create_node_permission(Host, ServerHost, _Node, _ParentNode, Owner, Access) -> LOwner = jlib:jid_tolower(Owner), {User, Server, _Resource} = LOwner, Allowed = case LOwner of {"", Host, ""} -> true; % pubsub service always allowed _ -> case acl:match_rule(ServerHost, Access, LOwner) of allow -> case Host of {User, Server, _} -> true; _ -> false end; E -> ?DEBUG("Create not allowed : ~p~n", [E]), false end end, {result, Allowed}. create_node(NodeId, Owner) -> node_hometree:create_node(NodeId, Owner). delete_node(Removed) -> case node_hometree:delete_node(Removed) of {result, {_, _, Removed}} -> {result, {[], Removed}}; Error -> Error end. subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> node_hometree:subscribe_node( NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options). unsubscribe_node(NodeId, Sender, Subscriber, SubID) -> case node_hometree:unsubscribe_node(NodeId, Sender, Subscriber, SubID) of {error, Error} -> {error, Error}; {result, _} -> {result, []} end. publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) -> node_hometree:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload). remove_extra_items(NodeId, MaxItems, ItemIds) -> node_hometree:remove_extra_items(NodeId, MaxItems, ItemIds). delete_item(NodeId, Publisher, PublishModel, ItemId) -> node_hometree:delete_item(NodeId, Publisher, PublishModel, ItemId). purge_node(NodeId, Owner) -> node_hometree:purge_node(NodeId, Owner). get_entity_affiliations(_Host, Owner) -> {_, D, _} = SubKey = jlib:jid_tolower(Owner), SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), States = mnesia:match_object(#pubsub_state{stateid = {GenKey, '_'}, _ = '_'}), NodeTree = case catch ets:lookup(gen_mod:get_module_proc(D, config), nodetree) of [{nodetree, N}] -> N; _ -> nodetree_tree end, Reply = lists:foldl(fun(#pubsub_state{stateid = {_, N}, affiliation = A}, Acc) -> case NodeTree:get_node(N) of #pubsub_node{nodeid = {{_, D, _}, _}} = Node -> [{Node, A}|Acc]; _ -> Acc end end, [], States), {result, Reply}. get_node_affiliations(NodeId) -> node_hometree:get_node_affiliations(NodeId). get_affiliation(NodeId, Owner) -> node_hometree:get_affiliation(NodeId, Owner). set_affiliation(NodeId, Owner, Affiliation) -> node_hometree:set_affiliation(NodeId, Owner, Affiliation). get_entity_subscriptions(_Host, Owner) -> {U, D, _} = SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), States = case SubKey of GenKey -> mnesia:match_object( #pubsub_state{stateid = {{U, D, '_'}, '_'}, _ = '_'}); _ -> mnesia:match_object( #pubsub_state{stateid = {GenKey, '_'}, _ = '_'}) ++ mnesia:match_object( #pubsub_state{stateid = {SubKey, '_'}, _ = '_'}) end, NodeTree = case catch ets:lookup(gen_mod:get_module_proc(D, config), nodetree) of [{nodetree, N}] -> N; _ -> nodetree_tree end, Reply = lists:foldl(fun(#pubsub_state{stateid = {J, N}, subscriptions = Ss}, Acc) -> case NodeTree:get_node(N) of #pubsub_node{nodeid = {{_, D, _}, _}} = Node -> lists:foldl(fun({subscribed, SubID}, Acc2) -> [{Node, subscribed, SubID, J} | Acc2]; ({pending, _SubID}, Acc2) -> [{Node, pending, J} | Acc2]; (S, Acc2) -> [{Node, S, J} | Acc2] end, Acc, Ss); _ -> Acc end end, [], States), {result, Reply}. get_node_subscriptions(NodeId) -> %% note: get_node_subscriptions is used for broadcasting %% there should not have any subscriptions %% but that call returns also all subscription to none %% and this is required for broadcast to occurs %% DO NOT REMOVE node_hometree:get_node_subscriptions(NodeId). get_subscriptions(NodeId, Owner) -> node_hometree:get_subscriptions(NodeId, Owner). set_subscriptions(NodeId, Owner, Subscription, SubId) -> node_hometree:set_subscriptions(NodeId, Owner, Subscription, SubId). get_pending_nodes(Host, Owner) -> node_hometree:get_pending_nodes(Host, Owner). get_states(NodeId) -> node_hometree:get_states(NodeId). get_state(NodeId, JID) -> node_hometree:get_state(NodeId, JID). set_state(State) -> node_hometree:set_state(State). get_items(NodeId, From) -> node_hometree:get_items(NodeId, From). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). get_item(NodeId, ItemId) -> node_hometree:get_item(NodeId, ItemId). get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). set_item(Item) -> node_hometree:set_item(Item). get_item_name(Host, Node, Id) -> node_hometree:get_item_name(Host, Node, Id). node_to_path(Node) -> node_flat:node_to_path(Node). path_to_node(Path) -> node_flat:path_to_node(Path). %%% %%% Internal %%% %% @doc Check mod_caps is enabled, otherwise show warning. %% The PEP plugin for mod_pubsub requires mod_caps to be enabled in the host. %% Check that the mod_caps module is enabled in that Jabber Host %% If not, show a warning message in the ejabberd log file. complain_if_modcaps_disabled(ServerHost) -> Modules = ejabberd_config:get_local_option({modules, ServerHost}), ModCaps = [mod_caps_enabled || {mod_caps, _Opts} <- Modules], case ModCaps of [] -> ?WARNING_MSG("The PEP plugin is enabled in mod_pubsub of host ~p. " "This plugin requires mod_caps to be enabled, " "but it isn't.", [ServerHost]); _ -> ok end. ejabberd-2.1.11/src/mod_pubsub/node.template0000664000000000000000000001405012240230175015626 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(__TO_BE_DEFINED__). -author(__TO_BE_DEFINED__). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_node). %% Note on function definition %% included is all defined plugin function %% it's possible not to define some function at all %% in that case, warning will be generated at compilation %% and function call will fail, %% then mod_pubsub will call function from node_hometree %% (this makes code cleaner, but execution a little bit longer) %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/6, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3 ]). init(Host, ServerHost, Opts) -> node_hometree:init(Host, ServerHost, Opts). terminate(Host, ServerHost) -> node_hometree:terminate(Host, ServerHost). options() -> [{deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, true}, {purge_offline, false}, {persist_items, true}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, open}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, on_sub_and_presence}, {deliver_notifications, true}, {presence_based_delivery, false}]. features() -> ["create-nodes", "delete-nodes", "delete-items", "instant-nodes", "outcast-affiliation", "persistent-items", "publish", "purge-nodes", "retract-items", "retrieve-affiliations", "retrieve-items", "retrieve-subscriptions", "subscribe", "subscription-notifications" ]. create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access) -> node_hometree:create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access). create_node(NodeId, Owner) -> node_hometree:create_node(NodeId, Owner). delete_node(Removed) -> node_hometree:delete_node(Removed). subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> node_hometree:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options). unsubscribe_node(NodeId, Sender, Subscriber, SubID) -> node_hometree:unsubscribe_node(NodeId, Sender, Subscriber, SubID). publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) -> node_hometree:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload). remove_extra_items(NodeId, MaxItems, ItemIds) -> node_hometree:remove_extra_items(NodeId, MaxItems, ItemIds). delete_item(NodeId, Publisher, PublishModel, ItemId) -> node_hometree:delete_item(NodeId, Publisher, PublishModel, ItemId). purge_node(NodeId, Owner) -> node_hometree:purge_node(NodeId, Owner). get_entity_affiliations(Host, Owner) -> node_hometree:get_entity_affiliations(Host, Owner). get_node_affiliations(NodeId) -> node_hometree:get_node_affiliations(NodeId). get_affiliation(NodeId, Owner) -> node_hometree:get_affiliation(NodeId, Owner). set_affiliation(NodeId, Owner, Affiliation) -> node_hometree:set_affiliation(NodeId, Owner, Affiliation). get_entity_subscriptions(Host, Owner) -> node_hometree:get_entity_subscriptions(Host, Owner). get_node_subscriptions(NodeId) -> node_hometree:get_node_subscriptions(NodeId). get_subscriptions(NodeId, Owner) -> node_hometree:get_subscriptions(NodeId, Owner). set_subscriptions(NodeId, Owner, Subscription, SubId) -> node_hometree:set_subscriptions(NodeId, Owner, Subscription, SubId). get_pending_nodes(Host, Owner) -> node_hometree:get_pending_nodes(Host, Owner). get_states(NodeId) -> node_hometree:get_states(NodeId). get_state(NodeId, JID) -> node_hometree:get_state(NodeId, JID). set_state(State) -> node_hometree:set_state(State). get_items(NodeId, From) -> node_hometree:get_items(NodeId, From). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). get_item(NodeId, ItemId) -> node_hometree:get_item(NodeId, ItemId). get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). set_item(Item) -> node_hometree:set_item(Item). get_item_name(Host, Node, Id) -> node_hometree:get_item_name(Host, Node, Id). ejabberd-2.1.11/src/mod_pubsub/pubsub_subscription_odbc.erl0000664000000000000000000002537412240230175020756 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% @author Pablo Polvorin %%% @author based on pubsub_subscription.erl by Brian Cully %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(pubsub_subscription_odbc). -author("pablo.polvorin@process-one.net"). %% API -export([init/0, subscribe_node/3, unsubscribe_node/3, get_subscription/3, set_subscription/4, get_options_xform/2, parse_options_xform/1]). -include("pubsub.hrl"). -include("jlib.hrl"). -define(PUBSUB_DELIVER, "pubsub#deliver"). -define(PUBSUB_DIGEST, "pubsub#digest"). -define(PUBSUB_DIGEST_FREQUENCY, "pubsub#digest_frequency"). -define(PUBSUB_EXPIRE, "pubsub#expire"). -define(PUBSUB_INCLUDE_BODY, "pubsub#include_body"). -define(PUBSUB_SHOW_VALUES, "pubsub#show-values"). -define(PUBSUB_SUBSCRIPTION_TYPE, "pubsub#subscription_type"). -define(PUBSUB_SUBSCRIPTION_DEPTH, "pubsub#subscription_depth"). -define(DELIVER_LABEL, "Whether an entity wants to receive or disable notifications"). -define(DIGEST_LABEL, "Whether an entity wants to receive digests (aggregations) of notifications or all notifications individually"). -define(DIGEST_FREQUENCY_LABEL, "The minimum number of milliseconds between sending any two notification digests"). -define(EXPIRE_LABEL, "The DateTime at which a leased subscription will end or has ended"). -define(INCLUDE_BODY_LABEL, "Whether an entity wants to receive an XMPP message body in addition to the payload format"). -define(SHOW_VALUES_LABEL, "The presence states for which an entity wants to receive notifications"). -define(SUBSCRIPTION_TYPE_LABEL, "Type of notification to receive"). -define(SUBSCRIPTION_DEPTH_LABEL, "Depth from subscription for which to receive notifications"). -define(SHOW_VALUE_AWAY_LABEL, "XMPP Show Value of Away"). -define(SHOW_VALUE_CHAT_LABEL, "XMPP Show Value of Chat"). -define(SHOW_VALUE_DND_LABEL, "XMPP Show Value of DND (Do Not Disturb)"). -define(SHOW_VALUE_ONLINE_LABEL, "Mere Availability in XMPP (No Show Value)"). -define(SHOW_VALUE_XA_LABEL, "XMPP Show Value of XA (Extended Away)"). -define(SUBSCRIPTION_TYPE_VALUE_ITEMS_LABEL, "Receive notification of new items only"). -define(SUBSCRIPTION_TYPE_VALUE_NODES_LABEL, "Receive notification of new nodes only"). -define(SUBSCRIPTION_DEPTH_VALUE_ONE_LABEL, "Receive notification from direct child nodes only"). -define(SUBSCRIPTION_DEPTH_VALUE_ALL_LABEL, "Receive notification from all descendent nodes"). -define(DB_MOD, pubsub_db_odbc). %%==================================================================== %% API %%==================================================================== init() -> ok = create_table(). subscribe_node(_JID, _NodeID, Options) -> SubID = make_subid(), ?DB_MOD:add_subscription(#pubsub_subscription{subid = SubID, options = Options}), {result, SubID}. unsubscribe_node(_JID, _NodeID, SubID) -> case ?DB_MOD:read_subscription(SubID) of {ok, Sub} -> ?DB_MOD:delete_subscription(SubID), {result, Sub}; notfound -> {error, notfound} end. get_subscription(_JID, _NodeID, SubID) -> case ?DB_MOD:read_subscription(SubID) of {ok, Sub} -> {result, Sub}; notfound -> {error, notfound} end. set_subscription(_JID, _NodeID, SubID, Options) -> case ?DB_MOD:read_subscription(SubID) of {ok, _} -> ?DB_MOD:update_subscription(#pubsub_subscription{subid = SubID, options = Options}), {result, ok}; notfound -> ?DB_MOD:add_subscription(#pubsub_subscription{subid = SubID, options = Options}), {result, ok} end. get_options_xform(Lang, Options) -> Keys = [deliver, show_values, subscription_type, subscription_depth], XFields = [get_option_xfield(Lang, Key, Options) || Key <- Keys], {result, {xmlelement, "x", [{"xmlns", ?NS_XDATA}], [{xmlelement, "field", [{"var", "FORM_TYPE"}, {"type", "hidden"}], [{xmlelement, "value", [], [{xmlcdata, ?NS_PUBSUB_SUB_OPTIONS}]}]}] ++ XFields}}. parse_options_xform(XFields) -> case xml:remove_cdata(XFields) of [] -> {result, []}; [{xmlelement, "x", _Attrs, _Els} = XEl] -> case jlib:parse_xdata_submit(XEl) of XData when is_list(XData) -> case set_xoption(XData, []) of Opts when is_list(Opts) -> {result, Opts}; Other -> Other end; Other -> Other end; Other -> Other end. %%==================================================================== %% Internal functions %%==================================================================== create_table() -> ok. make_subid() -> {T1, T2, T3} = now(), lists:flatten(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3])). %% %% Subscription XForm processing. %% %% Return processed options, with types converted and so forth, using %% Opts as defaults. set_xoption([], Opts) -> Opts; set_xoption([{Var, Value} | T], Opts) -> NewOpts = case var_xfield(Var) of {error, _} -> Opts; Key -> Val = val_xfield(Key, Value), lists:keystore(Key, 1, Opts, {Key, Val}) end, set_xoption(T, NewOpts). %% Return the options list's key for an XForm var. var_xfield(?PUBSUB_DELIVER) -> deliver; var_xfield(?PUBSUB_DIGEST) -> digest; var_xfield(?PUBSUB_DIGEST_FREQUENCY) -> digest_frequency; var_xfield(?PUBSUB_EXPIRE) -> expire; var_xfield(?PUBSUB_INCLUDE_BODY) -> include_body; var_xfield(?PUBSUB_SHOW_VALUES) -> show_values; var_xfield(?PUBSUB_SUBSCRIPTION_TYPE) -> subscription_type; var_xfield(?PUBSUB_SUBSCRIPTION_DEPTH) -> subscription_depth; var_xfield(_) -> {error, badarg}. %% Convert Values for option list's Key. val_xfield(deliver, [Val]) -> xopt_to_bool(Val); val_xfield(digest, [Val]) -> xopt_to_bool(Val); val_xfield(digest_frequency, [Val]) -> list_to_integer(Val); val_xfield(expire, [Val]) -> jlib:datetime_string_to_timestamp(Val); val_xfield(include_body, [Val]) -> xopt_to_bool(Val); val_xfield(show_values, Vals) -> Vals; val_xfield(subscription_type, ["items"]) -> items; val_xfield(subscription_type, ["nodes"]) -> nodes; val_xfield(subscription_depth, ["all"]) -> all; val_xfield(subscription_depth, [Depth]) -> case catch list_to_integer(Depth) of N when is_integer(N) -> N; _ -> {error, ?ERR_NOT_ACCEPTABLE} end. %% Convert XForm booleans to Erlang booleans. xopt_to_bool("0") -> false; xopt_to_bool("1") -> true; xopt_to_bool("false") -> false; xopt_to_bool("true") -> true; xopt_to_bool(_) -> {error, ?ERR_NOT_ACCEPTABLE}. %% Return a field for an XForm for Key, with data filled in, if %% applicable, from Options. get_option_xfield(Lang, Key, Options) -> Var = xfield_var(Key), Label = xfield_label(Key), {Type, OptEls} = type_and_options(xfield_type(Key), Lang), Vals = case lists:keysearch(Key, 1, Options) of {value, {_, Val}} -> [tr_xfield_values(Vals) || Vals <- xfield_val(Key, Val)]; false -> [] end, {xmlelement, "field", [{"var", Var}, {"type", Type}, {"label", translate:translate(Lang, Label)}], OptEls ++ Vals}. type_and_options({Type, Options}, Lang) -> {Type, [tr_xfield_options(O, Lang) || O <- Options]}; type_and_options(Type, _Lang) -> {Type, []}. tr_xfield_options({Value, Label}, Lang) -> {xmlelement, "option", [{"label", translate:translate(Lang, Label)}], [{xmlelement, "value", [], [{xmlcdata, Value}]}]}. tr_xfield_values(Value) -> {xmlelement, "value", [], [{xmlcdata, Value}]}. %% Return the XForm variable name for a subscription option key. xfield_var(deliver) -> ?PUBSUB_DELIVER; xfield_var(digest) -> ?PUBSUB_DIGEST; xfield_var(digest_frequency) -> ?PUBSUB_DIGEST_FREQUENCY; xfield_var(expire) -> ?PUBSUB_EXPIRE; xfield_var(include_body) -> ?PUBSUB_INCLUDE_BODY; xfield_var(show_values) -> ?PUBSUB_SHOW_VALUES; xfield_var(subscription_type) -> ?PUBSUB_SUBSCRIPTION_TYPE; xfield_var(subscription_depth) -> ?PUBSUB_SUBSCRIPTION_DEPTH. %% Return the XForm variable type for a subscription option key. xfield_type(deliver) -> "boolean"; xfield_type(digest) -> "boolean"; xfield_type(digest_frequency) -> "text-single"; xfield_type(expire) -> "text-single"; xfield_type(include_body) -> "boolean"; xfield_type(show_values) -> {"list-multi", [{"away", ?SHOW_VALUE_AWAY_LABEL}, {"chat", ?SHOW_VALUE_CHAT_LABEL}, {"dnd", ?SHOW_VALUE_DND_LABEL}, {"online", ?SHOW_VALUE_ONLINE_LABEL}, {"xa", ?SHOW_VALUE_XA_LABEL}]}; xfield_type(subscription_type) -> {"list-single", [{"items", ?SUBSCRIPTION_TYPE_VALUE_ITEMS_LABEL}, {"nodes", ?SUBSCRIPTION_TYPE_VALUE_NODES_LABEL}]}; xfield_type(subscription_depth) -> {"list-single", [{"1", ?SUBSCRIPTION_DEPTH_VALUE_ONE_LABEL}, {"all", ?SUBSCRIPTION_DEPTH_VALUE_ALL_LABEL}]}. %% Return the XForm variable label for a subscription option key. xfield_label(deliver) -> ?DELIVER_LABEL; xfield_label(digest) -> ?DIGEST_LABEL; xfield_label(digest_frequency) -> ?DIGEST_FREQUENCY_LABEL; xfield_label(expire) -> ?EXPIRE_LABEL; xfield_label(include_body) -> ?INCLUDE_BODY_LABEL; xfield_label(show_values) -> ?SHOW_VALUES_LABEL; xfield_label(subscription_type) -> ?SUBSCRIPTION_TYPE_LABEL; xfield_label(subscription_depth) -> ?SUBSCRIPTION_DEPTH_LABEL. %% Return the XForm value for a subscription option key. xfield_val(deliver, Val) -> [bool_to_xopt(Val)]; xfield_val(digest, Val) -> [bool_to_xopt(Val)]; xfield_val(digest_frequency, Val) -> [integer_to_list(Val)]; xfield_val(expire, Val) -> [jlib:now_to_utc_string(Val)]; xfield_val(include_body, Val) -> [bool_to_xopt(Val)]; xfield_val(show_values, Val) -> Val; xfield_val(subscription_type, items) -> ["items"]; xfield_val(subscription_type, nodes) -> ["nodes"]; xfield_val(subscription_depth, all) -> ["all"]; xfield_val(subscription_depth, N) -> [integer_to_list(N)]. %% Convert erlang booleans to XForms. bool_to_xopt(false) -> "false"; bool_to_xopt(true) -> "true". ejabberd-2.1.11/src/mod_pubsub/node_buddy.erl0000664000000000000000000001431512240230175015770 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(node_buddy). -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_node). %% Note on function definition %% included is all defined plugin function %% it's possible not to define some function at all %% in that case, warning will be generated at compilation %% and function call will fail, %% then mod_pubsub will call function from node_hometree %% (this makes code cleaner, but execution a little bit longer) %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/6, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1 ]). init(Host, ServerHost, Opts) -> node_hometree:init(Host, ServerHost, Opts). terminate(Host, ServerHost) -> node_hometree:terminate(Host, ServerHost). options() -> [{deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, true}, {purge_offline, false}, {persist_items, true}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, presence}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, never}, {deliver_notifications, true}, {presence_based_delivery, false}]. features() -> ["create-nodes", "delete-nodes", "delete-items", "instant-nodes", "item-ids", "outcast-affiliation", "persistent-items", "publish", "purge-nodes", "retract-items", "retrieve-affiliations", "retrieve-items", "retrieve-subscriptions", "subscribe", "subscription-notifications" ]. create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access) -> node_hometree:create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access). create_node(NodeId, Owner) -> node_hometree:create_node(NodeId, Owner). delete_node(Removed) -> node_hometree:delete_node(Removed). subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> node_hometree:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options). unsubscribe_node(NodeId, Sender, Subscriber, SubID) -> node_hometree:unsubscribe_node(NodeId, Sender, Subscriber, SubID). publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) -> node_hometree:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload). remove_extra_items(NodeId, MaxItems, ItemIds) -> node_hometree:remove_extra_items(NodeId, MaxItems, ItemIds). delete_item(NodeId, Publisher, PublishModel, ItemId) -> node_hometree:delete_item(NodeId, Publisher, PublishModel, ItemId). purge_node(NodeId, Owner) -> node_hometree:purge_node(NodeId, Owner). get_entity_affiliations(Host, Owner) -> node_hometree:get_entity_affiliations(Host, Owner). get_node_affiliations(NodeId) -> node_hometree:get_node_affiliations(NodeId). get_affiliation(NodeId, Owner) -> node_hometree:get_affiliation(NodeId, Owner). set_affiliation(NodeId, Owner, Affiliation) -> node_hometree:set_affiliation(NodeId, Owner, Affiliation). get_entity_subscriptions(Host, Owner) -> node_hometree:get_entity_subscriptions(Host, Owner). get_node_subscriptions(NodeId) -> node_hometree:get_node_subscriptions(NodeId). get_subscriptions(NodeId, Owner) -> node_hometree:get_subscriptions(NodeId, Owner). set_subscriptions(NodeId, Owner, Subscription, SubId) -> node_hometree:set_subscriptions(NodeId, Owner, Subscription, SubId). get_pending_nodes(Host, Owner) -> node_hometree:get_pending_nodes(Host, Owner). get_states(NodeId) -> node_hometree:get_states(NodeId). get_state(NodeId, JID) -> node_hometree:get_state(NodeId, JID). set_state(State) -> node_hometree:set_state(State). get_items(NodeId, From) -> node_hometree:get_items(NodeId, From). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). get_item(NodeId, ItemId) -> node_hometree:get_item(NodeId, ItemId). get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). set_item(Item) -> node_hometree:set_item(Item). get_item_name(Host, Node, Id) -> node_hometree:get_item_name(Host, Node, Id). node_to_path(Node) -> node_flat:node_to_path(Node). path_to_node(Path) -> node_flat:path_to_node(Path). ejabberd-2.1.11/src/mod_pubsub/node_hometree_odbc.erl0000664000000000000000000014534012240230175017463 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %%% @todo The item table should be handled by the plugin, but plugin that do %%% not want to manage it should be able to use the default behaviour. %%% @todo Plugin modules should be able to register to receive presence update %%% send to pubsub. %%% @doc The module {@module} is the default PubSub plugin. %%%

    It is used as a default for all unknown PubSub node type. It can serve %%% as a developer basis and reference to build its own custom pubsub node %%% types.

    %%%

    PubSub plugin nodes are using the {@link gen_node} behaviour.

    %%%

    The API isn't stabilized yet. The pubsub plugin %%% development is still a work in progress. However, the system is already %%% useable and useful as is. Please, send us comments, feedback and %%% improvements.

    -module(node_hometree_odbc). -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -include("jlib.hrl"). -define(PUBSUB, mod_pubsub_odbc). -behaviour(gen_pubsub_node). %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_entity_subscriptions_for_send_last/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/7, get_items/6, get_items/3, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, get_last_items/3, path_to_node/1, node_to_path/1 ]). -export([ decode_jid/1, decode_node/1, decode_affiliation/1, decode_subscriptions/1, encode_jid/1, encode_affiliation/1, encode_subscriptions/1 ]). %% ================ %% API definition %% ================ %% @spec (Host, ServerHost, Opts) -> any() %% Host = mod_pubsub:host() %% ServerHost = mod_pubsub:host() %% Opts = list() %% @doc

    Called during pubsub modules initialisation. Any pubsub plugin must %% implement this function. It can return anything.

    %%

    This function is mainly used to trigger the setup task necessary for the %% plugin. It can be used for example by the developer to create the specific %% module database schema if it does not exists yet.

    init(_Host, _ServerHost, _Opts) -> pubsub_subscription_odbc:init(), ok. %% @spec (Host, ServerHost) -> any() %% Host = mod_pubsub:host() %% ServerHost = host() %% @doc

    Called during pubsub modules termination. Any pubsub plugin must %% implement this function. It can return anything.

    terminate(_Host, _ServerHost) -> ok. %% @spec () -> [Option] %% Option = mod_pubsub:nodeOption() %% @doc Returns the default pubsub node options. %%

    Example of function return value:

    %% ``` %% [{deliver_payloads, true}, %% {notify_config, false}, %% {notify_delete, false}, %% {notify_retract, true}, %% {persist_items, true}, %% {max_items, 10}, %% {subscribe, true}, %% {access_model, open}, %% {publish_model, publishers}, %% {max_payload_size, 100000}, %% {send_last_published_item, never}, %% {presence_based_delivery, false}]''' options() -> [{deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, true}, {purge_offline, false}, {persist_items, true}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, open}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, on_sub_and_presence}, {deliver_notifications, true}, {presence_based_delivery, false}, {odbc, true}, {rsm, true}]. %% @spec () -> [] %% @doc Returns the node features features() -> ["create-nodes", "auto-create", "access-authorize", "delete-nodes", "delete-items", "get-pending", "instant-nodes", "manage-subscriptions", "modify-affiliations", "multi-subscribe", "outcast-affiliation", "persistent-items", "publish", "purge-nodes", "retract-items", "retrieve-affiliations", "retrieve-items", "retrieve-subscriptions", "subscribe", "subscription-notifications", "subscription-options", "rsm" ]. %% @spec (Host, ServerHost, Node, ParentNode, Owner, Access) -> bool() %% Host = mod_pubsub:host() %% ServerHost = mod_pubsub:host() %% Node = mod_pubsub:pubsubNode() %% ParentNode = mod_pubsub:pubsubNode() %% Owner = mod_pubsub:jid() %% Access = all | atom() %% @doc Checks if the current user has the permission to create the requested node %%

    In {@link node_default}, the permission is decided by the place in the %% hierarchy where the user is creating the node. The access parameter is also %% checked in the default module. This parameter depends on the value of the %% access_createnode ACL value in ejabberd config file.

    %%

    This function also check that node can be created a a children of its %% parent node

    %%

    PubSub plugins can redefine the PubSub node creation rights as they %% which. They can simply delegate this check to the {@link node_default} %% module by implementing this function like this: %% ```check_create_user_permission(Host, ServerHost, Node, ParentNode, Owner, Access) -> %% node_default:check_create_user_permission(Host, ServerHost, Node, ParentNode, Owner, Access).'''

    create_node_permission(Host, ServerHost, Node, _ParentNode, Owner, Access) -> LOwner = jlib:jid_tolower(Owner), {User, Server, _Resource} = LOwner, Allowed = case LOwner of {"", Host, ""} -> true; % pubsub service always allowed _ -> case acl:match_rule(ServerHost, Access, LOwner) of allow -> case node_to_path(Node) of ["home", Server, User | _] -> true; _ -> false end; _ -> false end end, {result, Allowed}. %% @spec (NodeId, Owner) -> %% {result, Result} | exit %% NodeId = mod_pubsub:pubsubNodeId() %% Owner = mod_pubsub:jid() %% @doc

    create_node(NodeId, Owner) -> OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), State = #pubsub_state{stateid = {OwnerKey, NodeId}, affiliation = owner}, catch ejabberd_odbc:sql_query_t( ["insert into pubsub_state(nodeid, jid, affiliation, subscriptions) " "values(", state_to_raw(NodeId, State), ");"]), {result, {default, broadcast}}. %% @spec (Removed) -> ok %% Removed = [mod_pubsub:pubsubNode()] %% @doc

    purge items of deleted nodes after effective deletion.

    delete_node(Removed) -> Reply = lists:map( fun(#pubsub_node{id = NodeId} = PubsubNode) -> Subscriptions = case catch ejabberd_odbc:sql_query_t( ["select jid, subscriptions " "from pubsub_state " "where nodeid='", NodeId, "';"]) of {selected, ["jid", "subscriptions"], RItems} -> lists:map(fun({SJID, Subscriptions}) -> {decode_jid(SJID), decode_subscriptions(Subscriptions)} end, RItems); _ -> [] end, %% state and item remove already done thanks to DELETE CASCADE %% but here we get nothing in States, making notify_retract unavailable ! %% TODO, remove DELETE CASCADE from schema {PubsubNode, Subscriptions} end, Removed), {result, {default, broadcast, Reply}}. %% @spec (NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> %% {error, Reason} | {result, Result} %% @doc

    Accepts or rejects subcription requests on a PubSub node.

    %%

    The mechanism works as follow: %%

      %%
    • The main PubSub module prepares the subscription and passes the %% result of the preparation as a record.
    • %%
    • This function gets the prepared record and several other parameters and %% can decide to:
        %%
      • reject the subscription;
      • %%
      • allow it as is, letting the main module perform the database %% persistance;
      • %%
      • allow it, modifying the record. The main module will store the %% modified record;
      • %%
      • allow it, but perform the needed persistance operations.
      %%

    %%

    The selected behaviour depends on the return parameter: %%

      %%
    • {error, Reason}: an IQ error result will be returned. No %% subscription will actually be performed.
    • %%
    • true: Subscribe operation is allowed, based on the %% unmodified record passed in parameter SubscribeResult. If this %% parameter contains an error, no subscription will be performed.
    • %%
    • {true, PubsubState}: Subscribe operation is allowed, but %% the {@link mod_pubsub:pubsubState()} record returned replaces the value %% passed in parameter SubscribeResult.
    • %%
    • {true, done}: Subscribe operation is allowed, but the %% {@link mod_pubsub:pubsubState()} will be considered as already stored and %% no further persistance operation will be performed. This case is used, %% when the plugin module is doing the persistance by itself or when it want %% to completly disable persistance.
    %%

    %%

    In the default plugin module, the record is unchanged.

    subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> SubKey = jlib:jid_tolower(Subscriber), GenKey = jlib:jid_remove_resource(SubKey), Authorized = (jlib:jid_tolower(jlib:jid_remove_resource(Sender)) == GenKey), {Affiliation, Subscriptions} = select_affiliation_subscriptions(NodeId, GenKey, SubKey), Whitelisted = lists:member(Affiliation, [member, publisher, owner]), PendingSubscription = lists:any(fun({pending, _}) -> true; (_) -> false end, Subscriptions), if not Authorized -> %% JIDs do not match {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "invalid-jid")}; Affiliation == outcast -> %% Requesting entity is blocked {error, ?ERR_FORBIDDEN}; PendingSubscription -> %% Requesting entity has pending subscription {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "pending-subscription")}; (AccessModel == presence) and (not PresenceSubscription) -> %% Entity is not authorized to create a subscription (presence subscription required) {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")}; (AccessModel == roster) and (not RosterGroup) -> %% Entity is not authorized to create a subscription (not in roster group) {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")}; (AccessModel == whitelist) and (not Whitelisted) -> %% Node has whitelist access model and entity lacks required affiliation {error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")}; %%MustPay -> %% % Payment is required for a subscription %% {error, ?ERR_PAYMENT_REQUIRED}; %%ForbiddenAnonymous -> %% % Requesting entity is anonymous %% {error, ?ERR_FORBIDDEN}; true -> case pubsub_subscription_odbc:subscribe_node(Subscriber, NodeId, Options) of {result, SubId} -> NewSub = case AccessModel of authorize -> pending; _ -> subscribed end, update_subscription(NodeId, SubKey, [{NewSub, SubId} | Subscriptions]), case {NewSub, SendLast} of {subscribed, never} -> {result, {default, subscribed, SubId}}; {subscribed, _} -> {result, {default, subscribed, SubId, send_last}}; {_, _} -> {result, {default, pending, SubId}} end; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end end. %% @spec (NodeId, Sender, Subscriber, SubId) -> %% {error, Reason} | {result, []} %% NodeId = mod_pubsub:pubsubNodeId() %% Sender = mod_pubsub:jid() %% Subscriber = mod_pubsub:jid() %% SubId = mod_pubsub:subid() %% Reason = mod_pubsub:stanzaError() %% @doc

    Unsubscribe the Subscriber from the Node.

    unsubscribe_node(NodeId, Sender, Subscriber, SubId) -> SubKey = jlib:jid_tolower(Subscriber), GenKey = jlib:jid_remove_resource(SubKey), Authorized = (jlib:jid_tolower(jlib:jid_remove_resource(Sender)) == GenKey), {Affiliation, Subscriptions} = select_affiliation_subscriptions(NodeId, SubKey), SubIdExists = case SubId of [] -> false; List when is_list(List) -> true; _ -> false end, if %% Requesting entity is prohibited from unsubscribing entity not Authorized -> {error, ?ERR_FORBIDDEN}; %% Entity did not specify SubId %%SubId == "", ?? -> %% {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")}; %% Invalid subscription identifier %%InvalidSubId -> %% {error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; %% Requesting entity is not a subscriber Subscriptions == [] -> {error, ?ERR_EXTENDED(?ERR_UNEXPECTED_REQUEST_CANCEL, "not-subscribed")}; %% Subid supplied, so use that. SubIdExists -> Sub = first_in_list(fun(S) -> case S of {_Sub, SubId} -> true; _ -> false end end, Subscriptions), case Sub of {value, S} -> delete_subscription(SubKey, NodeId, S, Affiliation, Subscriptions), {result, default}; false -> {error, ?ERR_EXTENDED(?ERR_UNEXPECTED_REQUEST_CANCEL, "not-subscribed")} end; %% Asking to remove all subscriptions to the given node SubId == all -> [delete_subscription(SubKey, NodeId, S, Affiliation, Subscriptions) || S <- Subscriptions], {result, default}; %% No subid supplied, but there's only one matching %% subscription, so use that. length(Subscriptions) == 1 -> delete_subscription(SubKey, NodeId, hd(Subscriptions), Affiliation, Subscriptions), {result, default}; %% No subid and more than one possible subscription match. true -> {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")} end. delete_subscription(SubKey, NodeId, {Subscription, SubId}, Affiliation, Subscriptions) -> NewSubs = Subscriptions -- [{Subscription, SubId}], pubsub_subscription_odbc:unsubscribe_node(SubKey, NodeId, SubId), case {Affiliation, NewSubs} of {none, []} -> % Just a regular subscriber, and this is final item, so % delete the state. del_state(NodeId, SubKey); _ -> update_subscription(NodeId, SubKey, NewSubs) end. %% @spec (NodeId, Publisher, PublishModel, MaxItems, ItemId, Payload) -> %% {true, PubsubItem} | {result, Reply} %% NodeId = mod_pubsub:pubsubNodeId() %% Publisher = mod_pubsub:jid() %% PublishModel = atom() %% MaxItems = integer() %% ItemId = string() %% Payload = term() %% @doc

    Publishes the item passed as parameter.

    %%

    The mechanism works as follow: %%

      %%
    • The main PubSub module prepares the item to publish and passes the %% result of the preparation as a {@link mod_pubsub:pubsubItem()} record.
    • %%
    • This function gets the prepared record and several other parameters and can decide to:
        %%
      • reject the publication;
      • %%
      • allow the publication as is, letting the main module perform the database persistance;
      • %%
      • allow the publication, modifying the record. The main module will store the modified record;
      • %%
      • allow it, but perform the needed persistance operations.
      %%

    %%

    The selected behaviour depends on the return parameter: %%

      %%
    • {error, Reason}: an iq error result will be return. No %% publication is actually performed.
    • %%
    • true: Publication operation is allowed, based on the %% unmodified record passed in parameter Item. If the Item %% parameter contains an error, no subscription will actually be %% performed.
    • %%
    • {true, Item}: Publication operation is allowed, but the %% {@link mod_pubsub:pubsubItem()} record returned replaces the value passed %% in parameter Item. The persistance will be performed by the main %% module.
    • %%
    • {true, done}: Publication operation is allowed, but the %% {@link mod_pubsub:pubsubItem()} will be considered as already stored and %% no further persistance operation will be performed. This case is used, %% when the plugin module is doing the persistance by itself or when it want %% to completly disable persistance.
    %%

    %%

    In the default plugin module, the record is unchanged.

    publish_item(NodeId, Publisher, PublishModel, MaxItems, ItemId, Payload) -> SubKey = jlib:jid_tolower(Publisher), GenKey = jlib:jid_remove_resource(SubKey), {Affiliation, Subscriptions} = select_affiliation_subscriptions(NodeId, GenKey, SubKey), Subscribed = case PublishModel of subscribers -> is_subscribed(Subscriptions); _ -> undefined end, if not ((PublishModel == open) or ((PublishModel == publishers) and ((Affiliation == owner) or (Affiliation == publisher))) or (Subscribed == true)) -> %% Entity does not have sufficient privileges to publish to node {error, ?ERR_FORBIDDEN}; true -> %% TODO: check creation, presence, roster if MaxItems > 0 -> %% Note: this works cause set_item tries an update before %% the insert, and the update just ignore creation field. PubId = {now(), SubKey}, set_item(#pubsub_item{itemid = {ItemId, NodeId}, creation = {now(), GenKey}, modification = PubId, payload = Payload}), Items = [ItemId | itemids(NodeId, GenKey)--[ItemId]], {result, {_, OI}} = remove_extra_items(NodeId, MaxItems, Items), %% set new item list use useless {result, {default, broadcast, OI}}; true -> {result, {default, broadcast, []}} end end. %% @spec (NodeId, MaxItems, ItemIds) -> {NewItemIds,OldItemIds} %% NodeId = mod_pubsub:pubsubNodeId() %% MaxItems = integer() | unlimited %% ItemIds = [ItemId::string()] %% NewItemIds = [ItemId::string()] %% @doc

    This function is used to remove extra items, most notably when the %% maximum number of items has been reached.

    %%

    This function is used internally by the core PubSub module, as no %% permission check is performed.

    %%

    In the default plugin module, the oldest items are removed, but other %% rules can be used.

    %%

    If another PubSub plugin wants to delegate the item removal (and if the %% plugin is using the default pubsub storage), it can implements this function like this: %% ```remove_extra_items(NodeId, MaxItems, ItemIds) -> %% node_default:remove_extra_items(NodeId, MaxItems, ItemIds).'''

    remove_extra_items(_NodeId, unlimited, ItemIds) -> {result, {ItemIds, []}}; remove_extra_items(NodeId, MaxItems, ItemIds) -> NewItems = lists:sublist(ItemIds, MaxItems), OldItems = lists:nthtail(length(NewItems), ItemIds), %% Remove extra items: del_items(NodeId, OldItems), %% Return the new items list: {result, {NewItems, OldItems}}. %% @spec (NodeId, Publisher, PublishModel, ItemId) -> %% {error, Reason::stanzaError()} | %% {result, []} %% NodeId = mod_pubsub:pubsubNodeId() %% Publisher = mod_pubsub:jid() %% PublishModel = atom() %% ItemId = string() %% @doc

    Triggers item deletion.

    %%

    Default plugin: The user performing the deletion must be the node owner %% or a publisher.

    delete_item(NodeId, Publisher, PublishModel, ItemId) -> SubKey = jlib:jid_tolower(Publisher), GenKey = jlib:jid_remove_resource(SubKey), {result, Affiliation} = get_affiliation(NodeId, GenKey), Allowed = (Affiliation == publisher) orelse (Affiliation == owner) orelse (PublishModel == open) orelse case get_item(NodeId, ItemId) of {result, #pubsub_item{creation = {_, GenKey}}} -> true; _ -> false end, if not Allowed -> %% Requesting entity does not have sufficient privileges {error, ?ERR_FORBIDDEN}; true -> case del_item(NodeId, ItemId) of {updated, 1} -> %% set new item list use useless {result, {default, broadcast}}; _ -> %% Non-existent node or item {error, ?ERR_ITEM_NOT_FOUND} end end. %% @spec (NodeId, Owner) -> %% {error, Reason::stanzaError()} | %% {result, {default, broadcast}} %% NodeId = mod_pubsub:pubsubNodeId() %% Owner = mod_pubsub:jid() purge_node(NodeId, Owner) -> SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), GenState = get_state(NodeId, GenKey), case GenState of #pubsub_state{affiliation = owner} -> {result, States} = get_states(NodeId), lists:foreach( fun(#pubsub_state{items = []}) -> ok; (#pubsub_state{items = Items}) -> del_items(NodeId, Items) end, States), {result, {default, broadcast}}; _ -> %% Entity is not owner {error, ?ERR_FORBIDDEN} end. %% @spec (Host, JID) -> [{Node,Affiliation}] %% Host = host() %% JID = mod_pubsub:jid() %% @doc

    Return the current affiliations for the given user

    %%

    The default module reads affiliations in the main Mnesia %% pubsub_state table. If a plugin stores its data in the same %% table, it should return an empty list, as the affiliation will be read by %% the default PubSub module. Otherwise, it should return its own affiliation, %% that will be added to the affiliation stored in the main %% pubsub_state table.

    get_entity_affiliations(Host, Owner) -> SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), H = ?PUBSUB:escape(Host), J = encode_jid(GenKey), Reply = case catch ejabberd_odbc:sql_query_t( ["select node, type, i.nodeid, affiliation " "from pubsub_state i, pubsub_node n " "where i.nodeid = n.nodeid " "and jid='", J, "' " "and host='", H, "';"]) of {selected, ["node", "type", "nodeid", "affiliation"], RItems} -> lists:map(fun({N, T, I, A}) -> Node = nodetree_tree_odbc:raw_to_node(Host, {N, "", T, I}), {Node, decode_affiliation(A)} end, RItems); _ -> [] end, {result, Reply}. get_node_affiliations(NodeId) -> Reply = case catch ejabberd_odbc:sql_query_t( ["select jid, affiliation " "from pubsub_state " "where nodeid='", NodeId, "';"]) of {selected, ["jid", "affiliation"], RItems} -> lists:map(fun({J, A}) -> {decode_jid(J), decode_affiliation(A)} end, RItems); _ -> [] end, {result, Reply}. get_affiliation(NodeId, Owner) -> SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), J = encode_jid(GenKey), Reply = case catch ejabberd_odbc:sql_query_t( ["select affiliation from pubsub_state " "where nodeid='", NodeId, "' and jid='", J, "';"]) of {selected, ["affiliation"], [{A}]} -> decode_affiliation(A); _ -> none end, {result, Reply}. set_affiliation(NodeId, Owner, Affiliation) -> SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), {_, Subscriptions} = select_affiliation_subscriptions(NodeId, GenKey), case {Affiliation, Subscriptions} of {none, none} -> del_state(NodeId, GenKey); _ -> update_affiliation(NodeId, GenKey, Affiliation) end. %% @spec (Host, Owner) -> [{Node,Subscription}] %% Host = host() %% Owner = mod_pubsub:jid() %% @doc

    Return the current subscriptions for the given user

    %%

    The default module reads subscriptions in the main Mnesia %% pubsub_state table. If a plugin stores its data in the same %% table, it should return an empty list, as the affiliation will be read by %% the default PubSub module. Otherwise, it should return its own affiliation, %% that will be added to the affiliation stored in the main %% pubsub_state table.

    get_entity_subscriptions(Host, Owner) -> SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), H = ?PUBSUB:escape(Host), SJ = encode_jid(SubKey), GJ = encode_jid(GenKey), Query = case SubKey of GenKey -> ["select node, type, i.nodeid, jid, subscriptions " "from pubsub_state i, pubsub_node n " "where i.nodeid = n.nodeid " "and jid like '", GJ, "%' " "and host='", H, "';"]; _ -> ["select node, type, i.nodeid, jid, subscriptions " "from pubsub_state i, pubsub_node n " "where i.nodeid = n.nodeid " "and jid in ('", SJ, "', '", GJ, "') " "and host='", H, "';"] end, Reply = case catch ejabberd_odbc:sql_query_t(Query) of {selected, ["node", "type", "nodeid", "jid", "subscriptions"], RItems} -> lists:foldl(fun({N, T, I, J, S}, Acc) -> Node = nodetree_tree_odbc:raw_to_node(Host, {N, "", T, I}), Jid = decode_jid(J), case decode_subscriptions(S) of [] -> [{Node, none, Jid}|Acc]; Subs -> lists:foldl(fun({Sub, SubId}, Acc2) -> [{Node, Sub, SubId, Jid}|Acc2]; (Sub, Acc2) -> [{Node, Sub, Jid}|Acc2] end, Acc, Subs) end end, [], RItems); _ -> [] end, {result, Reply}. %% do the same as get_entity_subscriptions but filter result only to %% nodes having send_last_published_item=on_sub_and_presence %% as this call avoid seeking node, it must return node and type as well get_entity_subscriptions_for_send_last(Host, Owner) -> SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), H = ?PUBSUB:escape(Host), SJ = encode_jid(SubKey), GJ = encode_jid(GenKey), Query = case SubKey of GenKey -> ["select node, type, i.nodeid, jid, subscriptions " "from pubsub_state i, pubsub_node n, pubsub_node_option o " "where i.nodeid = n.nodeid and n.nodeid = o.nodeid " "and name='send_last_published_item' and val='on_sub_and_presence' " "and jid like '", GJ, "%' " "and host='", H, "';"]; _ -> ["select node, type, i.nodeid, jid, subscriptions " "from pubsub_state i, pubsub_node n, pubsub_node_option o " "where i.nodeid = n.nodeid and n.nodeid = o.nodeid " "and name='send_last_published_item' and val='on_sub_and_presence' " "and jid in ('", SJ, "', '", GJ, "') " "and host='", H, "';"] end, Reply = case catch ejabberd_odbc:sql_query_t(Query) of {selected, ["node", "type", "nodeid", "jid", "subscriptions"], RItems} -> lists:foldl(fun({N, T, I, J, S}, Acc) -> Node = nodetree_tree_odbc:raw_to_node(Host, {N, "", T, I}), Jid = decode_jid(J), case decode_subscriptions(S) of [] -> [{Node, none, Jid}|Acc]; Subs -> lists:foldl(fun({Sub, SubId}, Acc2) -> [{Node, Sub, SubId, Jid}|Acc2]; (Sub, Acc2) -> [{Node, Sub, Jid}|Acc2] end, Acc, Subs) end end, [], RItems); _ -> [] end, {result, Reply}. get_node_subscriptions(NodeId) -> Reply = case catch ejabberd_odbc:sql_query_t( ["select jid, subscriptions " "from pubsub_state " "where nodeid='", NodeId, "';"]) of {selected, ["jid", "subscriptions"], RItems} -> lists:foldl(fun({J, S}, Acc) -> Jid = decode_jid(J), case decode_subscriptions(S) of [] -> [{Jid, none}|Acc]; Subs -> lists:foldl(fun({Sub, SubId}, Acc2) -> [{Jid, Sub, SubId}|Acc2]; (Sub, Acc2) -> [{Jid, Sub}|Acc2] end, Acc, Subs) end end, [], RItems); _ -> [] end, {result, Reply}. get_subscriptions(NodeId, Owner) -> SubKey = jlib:jid_tolower(Owner), J = encode_jid(SubKey), Reply = case catch ejabberd_odbc:sql_query_t( ["select subscriptions from pubsub_state " "where nodeid='", NodeId, "' and jid='", J, "';"]) of {selected, ["subscriptions"], [{S}]} -> decode_subscriptions(S); _ -> [] end, {result, Reply}. set_subscriptions(NodeId, Owner, Subscription, SubId) -> SubKey = jlib:jid_tolower(Owner), SubState = get_state_without_itemids(NodeId, SubKey), case {SubId, SubState#pubsub_state.subscriptions} of {_, []} -> case Subscription of none -> {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "not-subscribed")}; _ -> new_subscription(NodeId, Owner, Subscription, SubState) end; {"", [{_, SID}]} -> case Subscription of none -> unsub_with_subid(NodeId, SID, SubState); _ -> replace_subscription({Subscription, SID}, SubState) end; {"", [_|_]} -> {error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")}; _ -> case Subscription of none -> unsub_with_subid(NodeId, SubId, SubState); _ -> replace_subscription({Subscription, SubId}, SubState) end end. replace_subscription(NewSub, SubState) -> NewSubs = replace_subscription(NewSub, SubState#pubsub_state.subscriptions, []), set_state(SubState#pubsub_state{subscriptions = NewSubs}). replace_subscription(_, [], Acc) -> Acc; replace_subscription({Sub, SubId}, [{_, SubID} | T], Acc) -> replace_subscription({Sub, SubId}, T, [{Sub, SubID} | Acc]). new_subscription(NodeId, Owner, Subscription, SubState) -> case pubsub_subscription_odbc:subscribe_node(Owner, NodeId, []) of {result, SubId} -> Subscriptions = SubState#pubsub_state.subscriptions, set_state(SubState#pubsub_state{subscriptions = [{Subscription, SubId} | Subscriptions]}), {Subscription, SubId}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. unsub_with_subid(NodeId, SubId, SubState) -> pubsub_subscription_odbc:unsubscribe_node(SubState#pubsub_state.stateid, NodeId, SubId), NewSubs = lists:filter(fun ({_, SID}) -> SubId =/= SID end, SubState#pubsub_state.subscriptions), case {NewSubs, SubState#pubsub_state.affiliation} of {[], none} -> del_state(NodeId, element(1, SubState#pubsub_state.stateid)); _ -> set_state(SubState#pubsub_state{subscriptions = NewSubs}) end. %% @spec (Host, Owner) -> {result, [Node]} | {error, Reason} %% Host = host() %% Owner = jid() %% Node = pubsubNode() %% @doc

    Returns a list of Owner's nodes on Host with pending %% subscriptions.

    get_pending_nodes(Host, Owner) -> GenKey = jlib:jid_remove_resource(jlib:jid_tolower(Owner)), States = mnesia:match_object(#pubsub_state{stateid = {GenKey, '_'}, affiliation = owner, _ = '_'}), NodeIDs = [ID || #pubsub_state{stateid = {_, ID}} <- States], NodeTree = case catch ets:lookup(gen_mod:get_module_proc(Host, config), nodetree) of [{nodetree, N}] -> N; _ -> nodetree_tree_odbc end, Reply = mnesia:foldl(fun(#pubsub_state{stateid = {_, NID}} = S, Acc) -> case lists:member(NID, NodeIDs) of true -> case get_nodes_helper(NodeTree, S) of {value, Node} -> [Node | Acc]; false -> Acc end; false -> Acc end end, [], pubsub_state), {result, Reply}. get_nodes_helper(NodeTree, #pubsub_state{stateid = {_, N}, subscriptions = Subs}) -> HasPending = fun ({pending, _}) -> true; (pending) -> true; (_) -> false end, case lists:any(HasPending, Subs) of true -> case NodeTree:get_node(N) of #pubsub_node{nodeid = {_, Node}} -> {value, Node}; _ -> false end; false -> false end. %% @spec (NodeId) -> [States] | [] %% NodeId = mod_pubsub:pubsubNodeId() %% @doc Returns the list of stored states for a given node. %%

    For the default PubSub module, states are stored in Mnesia database.

    %%

    We can consider that the pubsub_state table have been created by the main %% mod_pubsub module.

    %%

    PubSub plugins can store the states where they wants (for example in a %% relational database).

    %%

    If a PubSub plugin wants to delegate the states storage to the default node, %% they can implement this function like this: %% ```get_states(NodeId) -> %% node_default:get_states(NodeId).'''

    get_states(NodeId) -> case catch ejabberd_odbc:sql_query_t( ["select jid, affiliation, subscriptions " "from pubsub_state " "where nodeid='", NodeId, "';"]) of {selected, ["jid", "affiliation", "subscriptions"], RItems} -> {result, lists:map(fun({SJID, Affiliation, Subscriptions}) -> #pubsub_state{stateid = {decode_jid(SJID), NodeId}, items = itemids(NodeId, SJID), affiliation = decode_affiliation(Affiliation), subscriptions = decode_subscriptions(Subscriptions)} end, RItems)}; _ -> {result, []} end. %% @spec (NodeId, JID) -> [State] | [] %% NodeId = mod_pubsub:pubsubNodeId() %% JID = mod_pubsub:jid() %% State = mod_pubsub:pubsubItems() %% @doc

    Returns a state (one state list), given its reference.

    get_state(NodeId, JID) -> State = get_state_without_itemids(NodeId, JID), {SJID, _} = State#pubsub_state.stateid, State#pubsub_state{items = itemids(NodeId, SJID)}. get_state_without_itemids(NodeId, JID) -> J = encode_jid(JID), case catch ejabberd_odbc:sql_query_t( ["select jid, affiliation, subscriptions " "from pubsub_state " "where jid='", J, "' " "and nodeid='", NodeId, "';"]) of {selected, ["jid", "affiliation", "subscriptions"], [{SJID, Affiliation, Subscriptions}]} -> #pubsub_state{stateid = {decode_jid(SJID), NodeId}, affiliation = decode_affiliation(Affiliation), subscriptions = decode_subscriptions(Subscriptions)}; _ -> #pubsub_state{stateid={JID, NodeId}} end. %% @spec (State) -> ok | {error, Reason::stanzaError()} %% State = mod_pubsub:pubsubStates() %% @doc

    Write a state into database.

    set_state(State) -> {_, NodeId} = State#pubsub_state.stateid, set_state(NodeId, State). set_state(NodeId, State) -> %% NOTE: in odbc version, as we do not handle item list, %% we just need to update affiliation and subscription %% cause {JID,NodeId} is the key. if it does not exists, then we insert it. %% MySQL can be optimized using INSERT ... ON DUPLICATE KEY as well {JID, _} = State#pubsub_state.stateid, J = encode_jid(JID), S = encode_subscriptions(State#pubsub_state.subscriptions), A = encode_affiliation(State#pubsub_state.affiliation), case catch ejabberd_odbc:sql_query_t( ["update pubsub_state " "set subscriptions='", S, "', affiliation='", A, "' " "where nodeid='", NodeId, "' and jid='", J, "';"]) of {updated, 1} -> ok; _ -> catch ejabberd_odbc:sql_query_t( ["insert into pubsub_state(nodeid, jid, affiliation, subscriptions) " "values('", NodeId, "', '", J, "', '", A, "', '", S, "');"]) end, {result, []}. %% @spec (NodeId, JID) -> ok | {error, Reason::stanzaError()} %% NodeId = mod_pubsub:pubsubNodeId() %% JID = mod_pubsub:jid() %% @doc

    Delete a state from database.

    del_state(NodeId, JID) -> J = encode_jid(JID), catch ejabberd_odbc:sql_query_t( ["delete from pubsub_state " "where jid='", J, "' " "and nodeid='", NodeId, "';"]), ok. %% @spec (NodeId, From) -> {[Items],RsmOut} | [] %% NodeId = mod_pubsub:pubsubNodeId() %% Items = mod_pubsub:pubsubItems() %% @doc Returns the list of stored items for a given node. %%

    For the default PubSub module, items are stored in Mnesia database.

    %%

    We can consider that the pubsub_item table have been created by the main %% mod_pubsub module.

    %%

    PubSub plugins can store the items where they wants (for example in a %% relational database), or they can even decide not to persist any items.

    %%

    If a PubSub plugin wants to delegate the item storage to the default node, %% they can implement this function like this: %% ```get_items(NodeId, From) -> %% node_default:get_items(NodeId, From).'''

    get_items(NodeId, _From) -> case catch ejabberd_odbc:sql_query_t( ["select itemid, publisher, creation, modification, payload " "from pubsub_item " "where nodeid='", NodeId, "' " "order by modification desc;"]) of {selected, ["itemid", "publisher", "creation", "modification", "payload"], RItems} -> {result, lists:map(fun(RItem) -> raw_to_item(NodeId, RItem) end, RItems)}; _ -> {result, []} end. get_items(NodeId, From, none) -> MaxItems = case catch ejabberd_odbc:sql_query_t( ["select val from pubsub_node_option " "where nodeid='", NodeId, "' " "and name='max_items';"]) of {selected, ["val"], [{Value}]} -> Tokens = element(2, erl_scan:string(Value++".")), element(2, erl_parse:parse_term(Tokens)); _ -> ?MAXITEMS end, get_items(NodeId, From, #rsm_in{max=MaxItems}); get_items(NodeId, _From, #rsm_in{max=M, direction=Direction, id=I, index=IncIndex})-> Max = ?PUBSUB:escape(i2l(M)), {Way, Order} = case Direction of aft -> {"<", "desc"}; before when I == [] -> {"is not", "asc"}; before -> {">", "asc"}; _ when IncIndex =/= undefined -> {"<", "desc"}; % using index _ -> {"is not", "desc"}% Can be better end, [AttrName, Id] = case I of undefined when IncIndex =/= undefined -> case catch ejabberd_odbc:sql_query_t( ["select modification from pubsub_item pi " "where exists ( " "select count(*) as count1 " "from pubsub_item " "where nodeid='", NodeId, "' " "and modification > pi.modification " "having count1 = ",?PUBSUB:escape(i2l(IncIndex))," );"]) of {selected, [_], [{O}]} -> ["modification", "'"++O++"'"]; _ -> ["modification", "null"] end; undefined -> ["modification", "null"]; [] -> ["modification", "null"]; I -> [A, B] = string:tokens(?PUBSUB:escape(i2l(I)), "@"), [A, "'"++B++"'"] end, Count= case catch ejabberd_odbc:sql_query_t( ["select count(*) " "from pubsub_item " "where nodeid='", NodeId, "';"]) of {selected, [_], [{C}]} -> C; _ -> "0" end, case catch ejabberd_odbc:sql_query_t( ["select itemid, publisher, creation, modification, payload " "from pubsub_item " "where nodeid='", NodeId, "' " "and ", AttrName," ", Way, " ", Id, " " "order by ", AttrName," ", Order," limit ", i2l(Max)," ;"]) of {selected, ["itemid", "publisher", "creation", "modification", "payload"], RItems} -> case length(RItems) of 0 -> {result, {[], #rsm_out{count=Count}}}; _ -> {_, _, _, F, _} = hd(RItems), Index = case catch ejabberd_odbc:sql_query_t( ["select count(*) " "from pubsub_item " "where nodeid='", NodeId, "' " "and ", AttrName," > '", F, "';"]) of %{selected, [_], [{C}, {In}]} -> [string:strip(C, both, $"), string:strip(In, both, $")]; {selected, [_], [{In}]} -> In; _ -> "0" end, %{F, _} = string:to_integer(FStr), {_, _, _, L, _} = lists:last(RItems), RsmOut = #rsm_out{count=Count, index=Index, first="modification@"++F, last="modification@"++i2l(L)}, {result, {lists:map(fun(RItem) -> raw_to_item(NodeId, RItem) end, RItems), RsmOut}} end; _ -> {result, {[], none}} end. get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId, none). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId, RSM) -> SubKey = jlib:jid_tolower(JID), GenKey = jlib:jid_remove_resource(SubKey), {Affiliation, Subscriptions} = select_affiliation_subscriptions(NodeId, GenKey, SubKey), Whitelisted = can_fetch_item(Affiliation, Subscriptions), if %%SubId == "", ?? -> %% Entity has multiple subscriptions to the node but does not specify a subscription ID %{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")}; %%InvalidSubId -> %% Entity is subscribed but specifies an invalid subscription ID %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; Affiliation == outcast -> %% Requesting entity is blocked {error, ?ERR_FORBIDDEN}; (AccessModel == presence) and (not PresenceSubscription) -> %% Entity is not authorized to create a subscription (presence subscription required) {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")}; (AccessModel == roster) and (not RosterGroup) -> %% Entity is not authorized to create a subscription (not in roster group) {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")}; (AccessModel == whitelist) and (not Whitelisted) -> %% Node has whitelist access model and entity lacks required affiliation {error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")}; (AccessModel == authorize) and (not Whitelisted) -> %% Node has authorize access model {error, ?ERR_FORBIDDEN}; %%MustPay -> %% % Payment is required for a subscription %% {error, ?ERR_PAYMENT_REQUIRED}; true -> get_items(NodeId, JID, RSM) end. get_last_items(NodeId, _From, Count) -> case catch ejabberd_odbc:sql_query_t( ["select itemid, publisher, creation, modification, payload " "from pubsub_item " "where nodeid='", NodeId, "' " "order by modification desc limit ", i2l(Count), ";"]) of {selected, ["itemid", "publisher", "creation", "modification", "payload"], RItems} -> {result, lists:map(fun(RItem) -> raw_to_item(NodeId, RItem) end, RItems)}; _ -> {result, []} end. %% @spec (NodeId, ItemId) -> [Item] | [] %% NodeId = mod_pubsub:pubsubNodeId() %% ItemId = string() %% Item = mod_pubsub:pubsubItems() %% @doc

    Returns an item (one item list), given its reference.

    get_item(NodeId, ItemId) -> I = ?PUBSUB:escape(ItemId), case catch ejabberd_odbc:sql_query_t( ["select itemid, publisher, creation, modification, payload " "from pubsub_item " "where nodeid='", NodeId, "' " "and itemid='", I,"';"]) of {selected, ["itemid", "publisher", "creation", "modification", "payload"], [RItem]} -> {result, raw_to_item(NodeId, RItem)}; _ -> {error, ?ERR_ITEM_NOT_FOUND} end. get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) -> SubKey = jlib:jid_tolower(JID), GenKey = jlib:jid_remove_resource(SubKey), {Affiliation, Subscriptions} = select_affiliation_subscriptions(NodeId, GenKey, SubKey), Whitelisted = can_fetch_item(Affiliation, Subscriptions), if %%SubId == "", ?? -> %% Entity has multiple subscriptions to the node but does not specify a subscription ID %{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")}; %%InvalidSubId -> %% Entity is subscribed but specifies an invalid subscription ID %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; Affiliation == outcast -> %% Requesting entity is blocked {error, ?ERR_FORBIDDEN}; (AccessModel == presence) and (not PresenceSubscription) -> %% Entity is not authorized to create a subscription (presence subscription required) {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")}; (AccessModel == roster) and (not RosterGroup) -> %% Entity is not authorized to create a subscription (not in roster group) {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")}; (AccessModel == whitelist) and (not Whitelisted) -> %% Node has whitelist access model and entity lacks required affiliation {error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")}; (AccessModel == authorize) and (not Whitelisted) -> %% Node has authorize access model {error, ?ERR_FORBIDDEN}; %%MustPay -> %% % Payment is required for a subscription %% {error, ?ERR_PAYMENT_REQUIRED}; true -> get_item(NodeId, ItemId) end. %% @spec (Item) -> ok | {error, Reason::stanzaError()} %% Item = mod_pubsub:pubsubItems() %% @doc

    Write an item into database.

    set_item(Item) -> {ItemId, NodeId} = Item#pubsub_item.itemid, I = ?PUBSUB:escape(ItemId), {C, _} = Item#pubsub_item.creation, {M, JID} = Item#pubsub_item.modification, P = encode_jid(JID), Payload = Item#pubsub_item.payload, XML = ?PUBSUB:escape(lists:flatten(lists:map(fun(X) -> xml:element_to_string(X) end, Payload))), S = fun({T1, T2, T3}) -> lists:flatten([i2l(T1, 6), ":", i2l(T2, 6), ":", i2l(T3, 6)]) end, case catch ejabberd_odbc:sql_query_t( ["update pubsub_item " "set publisher='", P, "', modification='", S(M), "', payload='", XML, "' " "where nodeid='", NodeId, "' and itemid='", I, "';"]) of {updated, 1} -> ok; _ -> catch ejabberd_odbc:sql_query_t( ["insert into pubsub_item " "(nodeid, itemid, publisher, creation, modification, payload) " "values('", NodeId, "', '", I, "', '", P, "', '", S(C), "', '", S(M), "', '", XML, "');"]) end, {result, []}. %% @spec (NodeId, ItemId) -> ok | {error, Reason::stanzaError()} %% NodeId = mod_pubsub:pubsubNodeId() %% ItemId = string() %% @doc

    Delete an item from database.

    del_item(NodeId, ItemId) -> I = ?PUBSUB:escape(ItemId), catch ejabberd_odbc:sql_query_t( ["delete from pubsub_item " "where itemid='", I, "' " "and nodeid='", NodeId, "';"]). del_items(_, []) -> ok; del_items(NodeId, [ItemId]) -> del_item(NodeId, ItemId); del_items(NodeId, ItemIds) -> I = string:join([["'", ?PUBSUB:escape(X), "'"] || X <- ItemIds], ","), catch ejabberd_odbc:sql_query_t( ["delete from pubsub_item " "where itemid in (", I, ") " "and nodeid='", NodeId, "';"]). %% @doc

    Return the name of the node if known: Default is to return %% node id.

    get_item_name(_Host, _Node, Id) -> Id. node_to_path(Node) -> string:tokens(binary_to_list(Node), "/"). path_to_node([]) -> <<>>; path_to_node(Path) -> list_to_binary(string:join([""|Path], "/")). %% @spec (Affiliation, Subscription) -> true | false %% Affiliation = owner | member | publisher | outcast | none %% Subscription = subscribed | none %% @doc Determines if the combination of Affiliation and Subscribed %% are allowed to get items from a node. can_fetch_item(owner, _) -> true; can_fetch_item(member, _) -> true; can_fetch_item(publisher, _) -> true; can_fetch_item(outcast, _) -> false; can_fetch_item(none, Subscriptions) -> is_subscribed(Subscriptions); can_fetch_item(_Affiliation, _Subscription) -> false. is_subscribed(Subscriptions) -> lists:any(fun ({subscribed, _SubId}) -> true; (_) -> false end, Subscriptions). %% Returns the first item where Pred() is true in List first_in_list(_Pred, []) -> false; first_in_list(Pred, [H | T]) -> case Pred(H) of true -> {value, H}; _ -> first_in_list(Pred, T) end. itemids(NodeId, {U, S, R}) -> itemids(NodeId, encode_jid({U, S, R})); itemids(NodeId, SJID) -> case catch ejabberd_odbc:sql_query_t( ["select itemid " "from pubsub_item " "where nodeid='", NodeId, "' " "and publisher like '", SJID, "%' " "order by modification desc;"]) of {selected, ["itemid"], RItems} -> lists:map(fun({ItemId}) -> ItemId end, RItems); _ -> [] end. select_affiliation_subscriptions(NodeId, JID) -> J = encode_jid(JID), case catch ejabberd_odbc:sql_query_t( ["select affiliation,subscriptions from pubsub_state " "where nodeid='", NodeId, "' and jid='", J, "';"]) of {selected, ["affiliation", "subscriptions"], [{A, S}]} -> {decode_affiliation(A), decode_subscriptions(S)}; _ -> {none, []} end. select_affiliation_subscriptions(NodeId, JID, JID) -> select_affiliation_subscriptions(NodeId, JID); select_affiliation_subscriptions(NodeId, GenKey, SubKey) -> {result, Affiliation} = get_affiliation(NodeId, GenKey), {result, Subscriptions} = get_subscriptions(NodeId, SubKey), {Affiliation, Subscriptions}. update_affiliation(NodeId, JID, Affiliation) -> J = encode_jid(JID), A = encode_affiliation(Affiliation), case catch ejabberd_odbc:sql_query_t( ["update pubsub_state " "set affiliation='", A, "' " "where nodeid='", NodeId, "' and jid='", J, "';"]) of {updated, 1} -> ok; _ -> catch ejabberd_odbc:sql_query_t( ["insert into pubsub_state(nodeid, jid, affiliation, subscriptions) " "values('", NodeId, "', '", J, "', '", A, "', '');"]) end. update_subscription(NodeId, JID, Subscription) -> J = encode_jid(JID), S = encode_subscriptions(Subscription), case catch ejabberd_odbc:sql_query_t( ["update pubsub_state " "set subscriptions='", S, "' " "where nodeid='", NodeId, "' and jid='", J, "';"]) of {updated, 1} -> ok; _ -> catch ejabberd_odbc:sql_query_t( ["insert into pubsub_state(nodeid, jid, affiliation, subscriptions) " "values('", NodeId, "', '", J, "', 'n', '", S, "');"]) end. decode_jid(SJID) -> jlib:jid_tolower(jlib:string_to_jid(SJID)). decode_node(N) -> ?PUBSUB:string_to_node(N). decode_affiliation("o") -> owner; decode_affiliation("p") -> publisher; decode_affiliation("m") -> member; decode_affiliation("c") -> outcast; decode_affiliation(_) -> none. decode_subscription("s") -> subscribed; decode_subscription("p") -> pending; decode_subscription("u") -> unconfigured; decode_subscription(_) -> none. decode_subscriptions(Subscriptions) -> lists:foldl(fun(Subscription, Acc) -> case string:tokens(Subscription, ":") of [S, SubId] -> [{decode_subscription(S), SubId}|Acc]; _ -> Acc end end, [], string:tokens(Subscriptions, ",")). encode_jid(JID) -> ?PUBSUB:escape(jlib:jid_to_string(JID)). encode_affiliation(owner) -> "o"; encode_affiliation(publisher) -> "p"; encode_affiliation(member) -> "m"; encode_affiliation(outcast) -> "c"; encode_affiliation(_) -> "n". encode_subscription(subscribed) -> "s"; encode_subscription(pending) -> "p"; encode_subscription(unconfigured) -> "u"; encode_subscription(_) -> "n". encode_subscriptions(Subscriptions) -> string:join(lists:map(fun({S, SubId}) -> encode_subscription(S)++":"++SubId end, Subscriptions), ","). %%% record getter/setter state_to_raw(NodeId, State) -> {JID, _} = State#pubsub_state.stateid, J = encode_jid(JID), A = encode_affiliation(State#pubsub_state.affiliation), S = encode_subscriptions(State#pubsub_state.subscriptions), ["'", NodeId, "', '", J, "', '", A, "', '", S, "'"]. raw_to_item(NodeId, {ItemId, SJID, Creation, Modification, XML}) -> JID = decode_jid(SJID), ToTime = fun(Str) -> [T1,T2,T3] = string:tokens(Str, ":"), {l2i(T1), l2i(T2), l2i(T3)} end, Payload = case xml_stream:parse_element(XML) of {error, _Reason} -> []; El -> [El] end, #pubsub_item{itemid = {ItemId, NodeId}, creation={ToTime(Creation), JID}, modification={ToTime(Modification), JID}, payload = Payload}. l2i(L) when is_list(L) -> list_to_integer(L); l2i(I) when is_integer(I) -> I. i2l(I) when is_integer(I) -> integer_to_list(I); i2l(L) when is_list(L) -> L. i2l(I, N) when is_integer(I) -> i2l(i2l(I), N); i2l(L, N) when is_list(L) -> case length(L) of N -> L; C when C > N -> L; _ -> i2l([$0|L], N) end. ejabberd-2.1.11/src/mod_pubsub/nodetree_virtual.erl0000664000000000000000000001356712240230175017237 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %%% @doc The module {@module} is the PubSub node tree plugin that %%% allow virtual nodes handling. %%%

    PubSub node tree plugins are using the {@link gen_nodetree} behaviour.

    %%%

    This plugin development is still a work in progress. Due to optimizations in %%% mod_pubsub, this plugin can not work anymore without altering functioning. %%% Please, send us comments, feedback and improvements.

    -module(nodetree_virtual). -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_nodetree). -export([init/3, terminate/2, options/0, set_node/1, get_node/3, get_node/2, get_node/1, get_nodes/2, get_nodes/1, get_parentnodes/3, get_parentnodes_tree/3, get_subnodes/3, get_subnodes_tree/3, create_node/6, delete_node/2 ]). %% ================ %% API definition %% ================ %% @spec (Host, ServerHost, Opts) -> any() %% Host = mod_pubsub:host() %% ServerHost = host() %% Opts = list() %% @doc

    Called during pubsub modules initialisation. Any pubsub plugin must %% implement this function. It can return anything.

    %%

    This function is mainly used to trigger the setup task necessary for the %% plugin. It can be used for example by the developer to create the specific %% module database schema if it does not exists yet.

    init(_Host, _ServerHost, _Opts) -> ok. terminate(_Host, _ServerHost) -> ok. %% @spec () -> [Option] %% Option = mod_pubsub:nodetreeOption() %% @doc

    Returns the default pubsub node tree options.

    options() -> [{virtual_tree, true}]. %% @spec (NodeRecord) -> ok | {error, Reason} %% NodeRecord = mod_pubsub:pubsub_node() %% @doc

    No node record is stored on database. Just do nothing.

    set_node(_NodeRecord) -> ok. %% @spec (Host, Node, From) -> pubsubNode() %% Host = mod_pubsub:host() %% Node = mod_pubsub:pubsubNode() %% From = mod_pubsub:jid() %% @doc

    Virtual node tree does not handle a node database. Any node is considered %% as existing. Node record contains default values.

    get_node(Host, Node, _From) -> get_node(Host, Node). get_node(Host, Node) -> get_node({Host, Node}). get_node({Host, _} = NodeId) -> Record = #pubsub_node{nodeid = NodeId, id = NodeId}, Module = list_to_atom("node_" ++ Record#pubsub_node.type), Options = Module:options(), Owners = [{"", Host, ""}], Record#pubsub_node{owners = Owners, options = Options}. %% @spec (Host, From) -> [pubsubNode()] %% Host = mod_pubsub:host() | mod_pubsub:jid() %% From = mod_pubsub:jid() %% @doc

    Virtual node tree does not handle a node database. Any node is considered %% as existing. Nodes list can not be determined.

    get_nodes(Host, _From) -> get_nodes(Host). get_nodes(_Host) -> []. %% @spec (Host, Node, From) -> [pubsubNode()] %% Host = mod_pubsub:host() %% Node = mod_pubsub:pubsubNode() %% From = mod_pubsub:jid() %% @doc

    Virtual node tree does not handle parent/child. Child list is empty.

    get_parentnodes(_Host, _Node, _From) -> []. %% @spec (Host, Node, From) -> [pubsubNode()] %% Host = mod_pubsub:host() %% Node = mod_pubsub:pubsubNode() %% From = mod_pubsub:jid() %% @doc

    Virtual node tree does not handle parent/child. Child list is empty.

    get_parentnodes_tree(_Host, _Node, _From) -> []. %% @spec (Host, Node, From) -> [pubsubNode()] %% Host = mod_pubsub:host() %% Node = mod_pubsub:pubsubNode() %% From = mod_pubsub:jid() %% @doc

    Virtual node tree does not handle parent/child. Child list is empty.

    get_subnodes(Host, Node, _From) -> get_subnodes(Host, Node). get_subnodes(_Host, _Node) -> []. %% @spec (Host, Node, From) -> [pubsubNode()] %% Host = mod_pubsub:host() %% Node = mod_pubsub:pubsubNode() %% From = mod_pubsub:jid() %% @doc

    Virtual node tree does not handle parent/child. Child list is empty.

    get_subnodes_tree(Host, Node, _From) -> get_subnodes_tree(Host, Node). get_subnodes_tree(_Host, _Node) -> []. %% @spec (Host, Node, Type, Owner, Options, Parents) -> ok %% Host = mod_pubsub:host() %% Node = mod_pubsub:pubsubNode() %% Type = mod_pubsub:nodeType() %% Owner = mod_pubsub:jid() %% Options = list() %% @doc

    No node record is stored on database. Any valid node %% is considered as already created.

    %%

    default allowed nodes: /home/host/user/any/node/name

    create_node(Host, Node, _Type, _Owner, _Options, _Parents) -> {error, {virtual, {Host, Node}}}. %% @spec (Host, Node) -> [mod_pubsub:node()] %% Host = mod_pubsub:host() %% Node = mod_pubsub:pubsubNode() %% @doc

    Virtual node tree does not handle parent/child. %% node deletion just affects the corresponding node.

    delete_node(Host, Node) -> [get_node(Host, Node)]. ejabberd-2.1.11/src/mod_pubsub/pubsub_subscription.erl0000664000000000000000000002736212240230175017766 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% @author Brian Cully %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(pubsub_subscription). -author("bjc@kublai.com"). %% API -export([init/0, subscribe_node/3, unsubscribe_node/3, get_subscription/3, set_subscription/4, get_options_xform/2, parse_options_xform/1]). % Internal function also exported for use in transactional bloc from pubsub plugins -export([add_subscription/3, delete_subscription/3, read_subscription/3, write_subscription/4]). -include("pubsub.hrl"). -include("jlib.hrl"). -define(PUBSUB_DELIVER, "pubsub#deliver"). -define(PUBSUB_DIGEST, "pubsub#digest"). -define(PUBSUB_DIGEST_FREQUENCY, "pubsub#digest_frequency"). -define(PUBSUB_EXPIRE, "pubsub#expire"). -define(PUBSUB_INCLUDE_BODY, "pubsub#include_body"). -define(PUBSUB_SHOW_VALUES, "pubsub#show-values"). -define(PUBSUB_SUBSCRIPTION_TYPE, "pubsub#subscription_type"). -define(PUBSUB_SUBSCRIPTION_DEPTH, "pubsub#subscription_depth"). -define(DELIVER_LABEL, "Whether an entity wants to receive or disable notifications"). -define(DIGEST_LABEL, "Whether an entity wants to receive digests (aggregations) of notifications or all notifications individually"). -define(DIGEST_FREQUENCY_LABEL, "The minimum number of milliseconds between sending any two notification digests"). -define(EXPIRE_LABEL, "The DateTime at which a leased subscription will end or has ended"). -define(INCLUDE_BODY_LABEL, "Whether an entity wants to receive an XMPP message body in addition to the payload format"). -define(SHOW_VALUES_LABEL, "The presence states for which an entity wants to receive notifications"). -define(SUBSCRIPTION_TYPE_LABEL, "Type of notification to receive"). -define(SUBSCRIPTION_DEPTH_LABEL, "Depth from subscription for which to receive notifications"). -define(SHOW_VALUE_AWAY_LABEL, "XMPP Show Value of Away"). -define(SHOW_VALUE_CHAT_LABEL, "XMPP Show Value of Chat"). -define(SHOW_VALUE_DND_LABEL, "XMPP Show Value of DND (Do Not Disturb)"). -define(SHOW_VALUE_ONLINE_LABEL, "Mere Availability in XMPP (No Show Value)"). -define(SHOW_VALUE_XA_LABEL, "XMPP Show Value of XA (Extended Away)"). -define(SUBSCRIPTION_TYPE_VALUE_ITEMS_LABEL, "Receive notification of new items only"). -define(SUBSCRIPTION_TYPE_VALUE_NODES_LABEL, "Receive notification of new nodes only"). -define(SUBSCRIPTION_DEPTH_VALUE_ONE_LABEL, "Receive notification from direct child nodes only"). -define(SUBSCRIPTION_DEPTH_VALUE_ALL_LABEL, "Receive notification from all descendent nodes"). %%==================================================================== %% API %%==================================================================== init() -> ok = create_table(). subscribe_node(JID, NodeID, Options) -> case catch mnesia:sync_dirty(fun add_subscription/3, [JID, NodeID, Options]) of {'EXIT', {aborted, Error}} -> Error; {error, Error} -> {error, Error}; Result -> {result, Result} end. unsubscribe_node(JID, NodeID, SubID) -> case catch mnesia:sync_dirty(fun delete_subscription/3, [JID, NodeID, SubID]) of {'EXIT', {aborted, Error}} -> Error; {error, Error} -> {error, Error}; Result -> {result, Result} end. get_subscription(JID, NodeID, SubID) -> case catch mnesia:sync_dirty(fun read_subscription/3, [JID, NodeID, SubID]) of {'EXIT', {aborted, Error}} -> Error; {error, Error} -> {error, Error}; Result -> {result, Result} end. set_subscription(JID, NodeID, SubID, Options) -> case catch mnesia:sync_dirty(fun write_subscription/4, [JID, NodeID, SubID, Options]) of {'EXIT', {aborted, Error}} -> Error; {error, Error} -> {error, Error}; Result -> {result, Result} end. get_options_xform(Lang, Options) -> Keys = [deliver, show_values, subscription_type, subscription_depth], XFields = [get_option_xfield(Lang, Key, Options) || Key <- Keys], {result, {xmlelement, "x", [{"xmlns", ?NS_XDATA}], [{xmlelement, "field", [{"var", "FORM_TYPE"}, {"type", "hidden"}], [{xmlelement, "value", [], [{xmlcdata, ?NS_PUBSUB_SUB_OPTIONS}]}]}] ++ XFields}}. parse_options_xform(XFields) -> case xml:remove_cdata(XFields) of [] -> {result, []}; [{xmlelement, "x", _Attrs, _Els} = XEl] -> case jlib:parse_xdata_submit(XEl) of XData when is_list(XData) -> case set_xoption(XData, []) of Opts when is_list(Opts) -> {result, Opts}; Other -> Other end; Other -> Other end; Other -> Other end. %%==================================================================== %% Internal functions %%==================================================================== create_table() -> case mnesia:create_table(pubsub_subscription, [{disc_copies, [node()]}, {attributes, record_info(fields, pubsub_subscription)}, {type, set}]) of {atomic, ok} -> ok; {aborted, {already_exists, _}} -> ok; Other -> Other end. add_subscription(_JID, _NodeID, Options) -> SubID = make_subid(), mnesia:write(#pubsub_subscription{subid = SubID, options = Options}), SubID. delete_subscription(_JID, _NodeID, SubID) -> mnesia:delete({pubsub_subscription, SubID}). read_subscription(_JID, _NodeID, SubID) -> case mnesia:read({pubsub_subscription, SubID}) of [Sub] -> Sub; _ -> {error, notfound} end. write_subscription(JID, NodeID, SubID, Options) -> case read_subscription(JID, NodeID, SubID) of {error, notfound} -> {error, notfound}; Sub -> mnesia:write(Sub#pubsub_subscription{options = Options}) end. make_subid() -> {T1, T2, T3} = now(), lists:flatten(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3])). %% %% Subscription XForm processing. %% %% Return processed options, with types converted and so forth, using %% Opts as defaults. set_xoption([], Opts) -> Opts; set_xoption([{Var, Value} | T], Opts) -> NewOpts = case var_xfield(Var) of {error, _} -> Opts; Key -> Val = val_xfield(Key, Value), lists:keystore(Key, 1, Opts, {Key, Val}) end, set_xoption(T, NewOpts). %% Return the options list's key for an XForm var. var_xfield(?PUBSUB_DELIVER) -> deliver; var_xfield(?PUBSUB_DIGEST) -> digest; var_xfield(?PUBSUB_DIGEST_FREQUENCY) -> digest_frequency; var_xfield(?PUBSUB_EXPIRE) -> expire; var_xfield(?PUBSUB_INCLUDE_BODY) -> include_body; var_xfield(?PUBSUB_SHOW_VALUES) -> show_values; var_xfield(?PUBSUB_SUBSCRIPTION_TYPE) -> subscription_type; var_xfield(?PUBSUB_SUBSCRIPTION_DEPTH) -> subscription_depth; var_xfield(_) -> {error, badarg}. %% Convert Values for option list's Key. val_xfield(deliver, [Val]) -> xopt_to_bool(Val); val_xfield(digest, [Val]) -> xopt_to_bool(Val); val_xfield(digest_frequency, [Val]) -> list_to_integer(Val); val_xfield(expire, [Val]) -> jlib:datetime_string_to_timestamp(Val); val_xfield(include_body, [Val]) -> xopt_to_bool(Val); val_xfield(show_values, Vals) -> Vals; val_xfield(subscription_type, ["items"]) -> items; val_xfield(subscription_type, ["nodes"]) -> nodes; val_xfield(subscription_depth, ["all"]) -> all; val_xfield(subscription_depth, [Depth]) -> case catch list_to_integer(Depth) of N when is_integer(N) -> N; _ -> {error, ?ERR_NOT_ACCEPTABLE} end. %% Convert XForm booleans to Erlang booleans. xopt_to_bool("0") -> false; xopt_to_bool("1") -> true; xopt_to_bool("false") -> false; xopt_to_bool("true") -> true; xopt_to_bool(_) -> {error, ?ERR_NOT_ACCEPTABLE}. %% Return a field for an XForm for Key, with data filled in, if %% applicable, from Options. get_option_xfield(Lang, Key, Options) -> Var = xfield_var(Key), Label = xfield_label(Key), {Type, OptEls} = type_and_options(xfield_type(Key), Lang), Vals = case lists:keysearch(Key, 1, Options) of {value, {_, Val}} -> [tr_xfield_values(Vals) || Vals <- xfield_val(Key, Val)]; false -> [] end, {xmlelement, "field", [{"var", Var}, {"type", Type}, {"label", translate:translate(Lang, Label)}], OptEls ++ Vals}. type_and_options({Type, Options}, Lang) -> {Type, [tr_xfield_options(O, Lang) || O <- Options]}; type_and_options(Type, _Lang) -> {Type, []}. tr_xfield_options({Value, Label}, Lang) -> {xmlelement, "option", [{"label", translate:translate(Lang, Label)}], [{xmlelement, "value", [], [{xmlcdata, Value}]}]}. tr_xfield_values(Value) -> {xmlelement, "value", [], [{xmlcdata, Value}]}. %% Return the XForm variable name for a subscription option key. xfield_var(deliver) -> ?PUBSUB_DELIVER; xfield_var(digest) -> ?PUBSUB_DIGEST; xfield_var(digest_frequency) -> ?PUBSUB_DIGEST_FREQUENCY; xfield_var(expire) -> ?PUBSUB_EXPIRE; xfield_var(include_body) -> ?PUBSUB_INCLUDE_BODY; xfield_var(show_values) -> ?PUBSUB_SHOW_VALUES; xfield_var(subscription_type) -> ?PUBSUB_SUBSCRIPTION_TYPE; xfield_var(subscription_depth) -> ?PUBSUB_SUBSCRIPTION_DEPTH. %% Return the XForm variable type for a subscription option key. xfield_type(deliver) -> "boolean"; xfield_type(digest) -> "boolean"; xfield_type(digest_frequency) -> "text-single"; xfield_type(expire) -> "text-single"; xfield_type(include_body) -> "boolean"; xfield_type(show_values) -> {"list-multi", [{"away", ?SHOW_VALUE_AWAY_LABEL}, {"chat", ?SHOW_VALUE_CHAT_LABEL}, {"dnd", ?SHOW_VALUE_DND_LABEL}, {"online", ?SHOW_VALUE_ONLINE_LABEL}, {"xa", ?SHOW_VALUE_XA_LABEL}]}; xfield_type(subscription_type) -> {"list-single", [{"items", ?SUBSCRIPTION_TYPE_VALUE_ITEMS_LABEL}, {"nodes", ?SUBSCRIPTION_TYPE_VALUE_NODES_LABEL}]}; xfield_type(subscription_depth) -> {"list-single", [{"1", ?SUBSCRIPTION_DEPTH_VALUE_ONE_LABEL}, {"all", ?SUBSCRIPTION_DEPTH_VALUE_ALL_LABEL}]}. %% Return the XForm variable label for a subscription option key. xfield_label(deliver) -> ?DELIVER_LABEL; xfield_label(digest) -> ?DIGEST_LABEL; xfield_label(digest_frequency) -> ?DIGEST_FREQUENCY_LABEL; xfield_label(expire) -> ?EXPIRE_LABEL; xfield_label(include_body) -> ?INCLUDE_BODY_LABEL; xfield_label(show_values) -> ?SHOW_VALUES_LABEL; xfield_label(subscription_type) -> ?SUBSCRIPTION_TYPE_LABEL; xfield_label(subscription_depth) -> ?SUBSCRIPTION_DEPTH_LABEL. %% Return the XForm value for a subscription option key. xfield_val(deliver, Val) -> [bool_to_xopt(Val)]; xfield_val(digest, Val) -> [bool_to_xopt(Val)]; xfield_val(digest_frequency, Val) -> [integer_to_list(Val)]; xfield_val(expire, Val) -> [jlib:now_to_utc_string(Val)]; xfield_val(include_body, Val) -> [bool_to_xopt(Val)]; xfield_val(show_values, Val) -> Val; xfield_val(subscription_type, items) -> ["items"]; xfield_val(subscription_type, nodes) -> ["nodes"]; xfield_val(subscription_depth, all) -> ["all"]; xfield_val(subscription_depth, N) -> [integer_to_list(N)]. %% Convert erlang booleans to XForms. bool_to_xopt(false) -> "false"; bool_to_xopt(true) -> "true". ejabberd-2.1.11/src/mod_pubsub/node_pep_odbc.erl0000664000000000000000000002555012240230175016437 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %%% @doc The module {@module} is the pep PubSub plugin. %%%

    PubSub plugin nodes are using the {@link gen_pubsub_node} behaviour.

    -module(node_pep_odbc). -author('christophe.romain@process-one.net'). -include("ejabberd.hrl"). -include("pubsub.hrl"). -include("jlib.hrl"). -define(PUBSUB, mod_pubsub_odbc). -behaviour(gen_pubsub_node). %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_entity_subscriptions_for_send_last/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/7, get_items/6, get_items/3, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, get_last_items/3, node_to_path/1, path_to_node/1 ]). init(Host, ServerHost, Opts) -> node_hometree_odbc:init(Host, ServerHost, Opts), complain_if_modcaps_disabled(ServerHost), ok. terminate(Host, ServerHost) -> node_hometree_odbc:terminate(Host, ServerHost), ok. options() -> [{odbc, true}, {node_type, pep}, {deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, false}, {purge_offline, false}, {persist_items, false}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, presence}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, on_sub_and_presence}, {deliver_notifications, true}, {presence_based_delivery, true}]. features() -> ["create-nodes", %* "auto-create", %* "auto-subscribe", %* "delete-nodes", %* "delete-items", %* "filtered-notifications", %* "modify-affiliations", "outcast-affiliation", "persistent-items", "publish", %* "purge-nodes", "retract-items", "retrieve-affiliations", "retrieve-items", %* "retrieve-subscriptions", "subscribe" %* ]. create_node_permission(Host, ServerHost, _Node, _ParentNode, Owner, Access) -> LOwner = jlib:jid_tolower(Owner), {User, Server, _Resource} = LOwner, Allowed = case LOwner of {"", Host, ""} -> true; % pubsub service always allowed _ -> case acl:match_rule(ServerHost, Access, LOwner) of allow -> case Host of {User, Server, _} -> true; _ -> false end; E -> ?DEBUG("Create not allowed : ~p~n", [E]), false end end, {result, Allowed}. create_node(NodeId, Owner) -> case node_hometree_odbc:create_node(NodeId, Owner) of {result, _} -> {result, []}; Error -> Error end. delete_node(Removed) -> case node_hometree_odbc:delete_node(Removed) of {result, {_, _, Removed}} -> {result, {[], Removed}}; Error -> Error end. subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> node_hometree_odbc:subscribe_node( NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options). unsubscribe_node(NodeId, Sender, Subscriber, SubID) -> case node_hometree_odbc:unsubscribe_node(NodeId, Sender, Subscriber, SubID) of {error, Error} -> {error, Error}; {result, _} -> {result, []} end. publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) -> node_hometree_odbc:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload). remove_extra_items(NodeId, MaxItems, ItemIds) -> node_hometree_odbc:remove_extra_items(NodeId, MaxItems, ItemIds). delete_item(NodeId, Publisher, PublishModel, ItemId) -> node_hometree_odbc:delete_item(NodeId, Publisher, PublishModel, ItemId). purge_node(NodeId, Owner) -> node_hometree_odbc:purge_node(NodeId, Owner). get_entity_affiliations(_Host, Owner) -> OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), node_hometree_odbc:get_entity_affiliations(OwnerKey, Owner). get_node_affiliations(NodeId) -> node_hometree_odbc:get_node_affiliations(NodeId). get_affiliation(NodeId, Owner) -> node_hometree_odbc:get_affiliation(NodeId, Owner). set_affiliation(NodeId, Owner, Affiliation) -> node_hometree_odbc:set_affiliation(NodeId, Owner, Affiliation). get_entity_subscriptions(_Host, Owner) -> SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), Host = ?PUBSUB:escape(element(2, SubKey)), SJ = node_hometree_odbc:encode_jid(SubKey), GJ = node_hometree_odbc:encode_jid(GenKey), Query = case SubKey of GenKey -> ["select host, node, type, i.nodeid, jid, subscriptions " "from pubsub_state i, pubsub_node n " "where i.nodeid = n.nodeid " "and jid like '", GJ, "%' " "and host like '%@", Host, "';"]; _ -> ["select host, node, type, i.nodeid, jid, subscriptions " "from pubsub_state i, pubsub_node n " "where i.nodeid = n.nodeid " "and jid in ('", SJ, "', '", GJ, "') " "and host like '%@", Host, "';"] end, Reply = case catch ejabberd_odbc:sql_query_t(Query) of {selected, ["host", "node", "type", "nodeid", "jid", "subscriptions"], RItems} -> lists:map(fun({H, N, T, I, J, S}) -> O = node_hometree_odbc:decode_jid(H), Node = nodetree_tree_odbc:raw_to_node(O, {N, "", T, I}), {Node, node_hometree_odbc:decode_subscriptions(S), node_hometree_odbc:decode_jid(J)} end, RItems); _ -> [] end, {result, Reply}. get_entity_subscriptions_for_send_last(_Host, Owner) -> SubKey = jlib:jid_tolower(Owner), GenKey = jlib:jid_remove_resource(SubKey), Host = ?PUBSUB:escape(element(2, SubKey)), SJ = node_hometree_odbc:encode_jid(SubKey), GJ = node_hometree_odbc:encode_jid(GenKey), Query = case SubKey of GenKey -> ["select host, node, type, i.nodeid, jid, subscriptions " "from pubsub_state i, pubsub_node n, pubsub_node_option o " "where i.nodeid = n.nodeid and n.nodeid = o.nodeid " "and name='send_last_published_item' and val='on_sub_and_presence' " "and jid like '", GJ, "%' " "and host like '%@", Host, "';"]; _ -> ["select host, node, type, i.nodeid, jid, subscriptions " "from pubsub_state i, pubsub_node n, pubsub_node_option o " "where i.nodeid = n.nodeid and n.nodeid = o.nodeid " "and name='send_last_published_item' and val='on_sub_and_presence' " "and jid in ('", SJ, "', '", GJ, "') " "and host like '%@", Host, "';"] end, Reply = case catch ejabberd_odbc:sql_query_t(Query) of {selected, ["host", "node", "type", "nodeid", "jid", "subscriptions"], RItems} -> lists:map(fun({H, N, T, I, J, S}) -> O = node_hometree_odbc:decode_jid(H), Node = nodetree_tree_odbc:raw_to_node(O, {N, "", T, I}), {Node, node_hometree_odbc:decode_subscriptions(S), node_hometree_odbc:decode_jid(J)} end, RItems); _ -> [] end, {result, Reply}. get_node_subscriptions(NodeId) -> %% note: get_node_subscriptions is used for broadcasting %% there should not have any subscriptions %% but that call returns also all subscription to none %% and this is required for broadcast to occurs %% DO NOT REMOVE node_hometree_odbc:get_node_subscriptions(NodeId). get_subscriptions(NodeId, Owner) -> node_hometree_odbc:get_subscriptions(NodeId, Owner). set_subscriptions(NodeId, Owner, Subscription, SubId) -> node_hometree_odbc:set_subscriptions(NodeId, Owner, Subscription, SubId). get_pending_nodes(Host, Owner) -> node_hometree_odbc:get_pending_nodes(Host, Owner). get_states(NodeId) -> node_hometree_odbc:get_states(NodeId). get_state(NodeId, JID) -> node_hometree_odbc:get_state(NodeId, JID). set_state(State) -> node_hometree_odbc:set_state(State). get_items(NodeId, From) -> node_hometree_odbc:get_items(NodeId, From). get_items(NodeId, From, RSM) -> node_hometree_odbc:get_items(NodeId, From, RSM). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId, none). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId, RSM) -> node_hometree_odbc:get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId, RSM). get_last_items(NodeId, JID, Count) -> node_hometree_odbc:get_last_items(NodeId, JID, Count). get_item(NodeId, ItemId) -> node_hometree_odbc:get_item(NodeId, ItemId). get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree_odbc:get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). set_item(Item) -> node_hometree_odbc:set_item(Item). get_item_name(Host, Node, Id) -> node_hometree_odbc:get_item_name(Host, Node, Id). node_to_path(Node) -> node_flat_odbc:node_to_path(Node). path_to_node(Path) -> node_flat_odbc:path_to_node(Path). %%% %%% Internal %%% %% @doc Check mod_caps is enabled, otherwise show warning. %% The PEP plugin for mod_pubsub requires mod_caps to be enabled in the host. %% Check that the mod_caps module is enabled in that Jabber Host %% If not, show a warning message in the ejabberd log file. complain_if_modcaps_disabled(ServerHost) -> Modules = ejabberd_config:get_local_option({modules, ServerHost}), ModCaps = [mod_caps_enabled || {mod_caps, _Opts} <- Modules], case ModCaps of [] -> ?WARNING_MSG("The PEP plugin is enabled in mod_pubsub of host ~p. " "This plugin requires mod_caps to be enabled, " "but it isn't.", [ServerHost]); _ -> ok end. ejabberd-2.1.11/src/mod_pubsub/node_club.erl0000664000000000000000000001427412240230175015612 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(node_club). -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_node). %% Note on function definition %% included is all defined plugin function %% it's possible not to define some function at all %% in that case, warning will be generated at compilation %% and function call will fail, %% then mod_pubsub will call function from node_hometree %% (this makes code cleaner, but execution a little bit longer) %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/6, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, node_to_path/1, path_to_node/1 ]). init(Host, ServerHost, Opts) -> node_hometree:init(Host, ServerHost, Opts). terminate(Host, ServerHost) -> node_hometree:terminate(Host, ServerHost). options() -> [{deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, true}, {purge_offline, false}, {persist_items, true}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, authorize}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, never}, {deliver_notifications, true}, {presence_based_delivery, false}]. features() -> ["create-nodes", "delete-nodes", "delete-items", "instant-nodes", "outcast-affiliation", "persistent-items", "publish", "purge-nodes", "retract-items", "retrieve-affiliations", "retrieve-items", "retrieve-subscriptions", "subscribe", "subscription-notifications" ]. create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access) -> node_hometree:create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access). create_node(NodeId, Owner) -> node_hometree:create_node(NodeId, Owner). delete_node(Removed) -> node_hometree:delete_node(Removed). subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> node_hometree:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options). unsubscribe_node(NodeId, Sender, Subscriber, SubID) -> node_hometree:unsubscribe_node(NodeId, Sender, Subscriber, SubID). publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) -> node_hometree:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload). remove_extra_items(NodeId, MaxItems, ItemIds) -> node_hometree:remove_extra_items(NodeId, MaxItems, ItemIds). delete_item(NodeId, Publisher, PublishModel, ItemId) -> node_hometree:delete_item(NodeId, Publisher, PublishModel, ItemId). purge_node(NodeId, Owner) -> node_hometree:purge_node(NodeId, Owner). get_entity_affiliations(Host, Owner) -> node_hometree:get_entity_affiliations(Host, Owner). get_node_affiliations(NodeId) -> node_hometree:get_node_affiliations(NodeId). get_affiliation(NodeId, Owner) -> node_hometree:get_affiliation(NodeId, Owner). set_affiliation(NodeId, Owner, Affiliation) -> node_hometree:set_affiliation(NodeId, Owner, Affiliation). get_entity_subscriptions(Host, Owner) -> node_hometree:get_entity_subscriptions(Host, Owner). get_node_subscriptions(NodeId) -> node_hometree:get_node_subscriptions(NodeId). get_subscriptions(NodeId, Owner) -> node_hometree:get_subscriptions(NodeId, Owner). set_subscriptions(NodeId, Owner, Subscription, SubId) -> node_hometree:set_subscriptions(NodeId, Owner, Subscription, SubId). get_pending_nodes(Host, Owner) -> node_hometree:get_pending_nodes(Host, Owner). get_states(NodeId) -> node_hometree:get_states(NodeId). get_state(NodeId, JID) -> node_hometree:get_state(NodeId, JID). set_state(State) -> node_hometree:set_state(State). get_items(NodeId, From) -> node_hometree:get_items(NodeId, From). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). get_item(NodeId, ItemId) -> node_hometree:get_item(NodeId, ItemId). get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree:get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). set_item(Item) -> node_hometree:set_item(Item). get_item_name(Host, Node, Id) -> node_hometree:get_item_name(Host, Node, Id). node_to_path(Node) -> node_flat:node_to_path(Node). path_to_node(Path) -> node_flat:path_to_node(Path). ejabberd-2.1.11/src/mod_pubsub/node_flat_odbc.erl0000664000000000000000000001556312240230175016604 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== -module(node_flat_odbc). -author('christophe.romain@process-one.net'). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_node). %% API definition -export([init/3, terminate/2, options/0, features/0, create_node_permission/6, create_node/2, delete_node/1, purge_node/2, subscribe_node/8, unsubscribe_node/4, publish_item/6, delete_item/4, remove_extra_items/3, get_entity_affiliations/2, get_node_affiliations/1, get_affiliation/2, set_affiliation/3, get_entity_subscriptions/2, get_entity_subscriptions_for_send_last/2, get_node_subscriptions/1, get_subscriptions/2, set_subscriptions/4, get_pending_nodes/2, get_states/1, get_state/2, set_state/1, get_items/7, get_items/6, get_items/3, get_items/2, get_item/7, get_item/2, set_item/1, get_item_name/3, get_last_items/3, node_to_path/1, path_to_node/1 ]). init(Host, ServerHost, Opts) -> node_hometree_odbc:init(Host, ServerHost, Opts). terminate(Host, ServerHost) -> node_hometree_odbc:terminate(Host, ServerHost). options() -> [{node_type, flat}, {deliver_payloads, true}, {notify_config, false}, {notify_delete, false}, {notify_retract, true}, {purge_offline, false}, {persist_items, true}, {max_items, ?MAXITEMS}, {subscribe, true}, {access_model, open}, {roster_groups_allowed, []}, {publish_model, publishers}, {notification_type, headline}, {max_payload_size, ?MAX_PAYLOAD_SIZE}, {send_last_published_item, on_sub_and_presence}, {deliver_notifications, true}, {presence_based_delivery, false}, {odbc, true}, {rsm, true}]. features() -> node_hometree_odbc:features(). %% use same code as node_hometree_odbc, but do not limite node to %% the home/localhost/user/... hierarchy %% any node is allowed create_node_permission(Host, ServerHost, _Node, _ParentNode, Owner, Access) -> LOwner = jlib:jid_tolower(Owner), Allowed = case LOwner of {"", Host, ""} -> true; % pubsub service always allowed _ -> acl:match_rule(ServerHost, Access, LOwner) =:= allow end, {result, Allowed}. create_node(NodeId, Owner) -> node_hometree_odbc:create_node(NodeId, Owner). delete_node(Removed) -> node_hometree_odbc:delete_node(Removed). subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options) -> node_hometree_odbc:subscribe_node(NodeId, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup, Options). unsubscribe_node(NodeId, Sender, Subscriber, SubID) -> node_hometree_odbc:unsubscribe_node(NodeId, Sender, Subscriber, SubID). publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload) -> node_hometree_odbc:publish_item(NodeId, Publisher, Model, MaxItems, ItemId, Payload). remove_extra_items(NodeId, MaxItems, ItemIds) -> node_hometree_odbc:remove_extra_items(NodeId, MaxItems, ItemIds). delete_item(NodeId, Publisher, PublishModel, ItemId) -> node_hometree_odbc:delete_item(NodeId, Publisher, PublishModel, ItemId). purge_node(NodeId, Owner) -> node_hometree_odbc:purge_node(NodeId, Owner). get_entity_affiliations(Host, Owner) -> node_hometree_odbc:get_entity_affiliations(Host, Owner). get_node_affiliations(NodeId) -> node_hometree_odbc:get_node_affiliations(NodeId). get_affiliation(NodeId, Owner) -> node_hometree_odbc:get_affiliation(NodeId, Owner). set_affiliation(NodeId, Owner, Affiliation) -> node_hometree_odbc:set_affiliation(NodeId, Owner, Affiliation). get_entity_subscriptions(Host, Owner) -> node_hometree_odbc:get_entity_subscriptions(Host, Owner). get_entity_subscriptions_for_send_last(Host, Owner) -> node_hometree_odbc:get_entity_subscriptions_for_send_last(Host, Owner). get_node_subscriptions(NodeId) -> node_hometree_odbc:get_node_subscriptions(NodeId). get_subscriptions(NodeId, Owner) -> node_hometree_odbc:get_subscriptions(NodeId, Owner). set_subscriptions(NodeId, Owner, Subscription, SubId) -> node_hometree_odbc:set_subscriptions(NodeId, Owner, Subscription, SubId). get_pending_nodes(Host, Owner) -> node_hometree_odbc:get_pending_nodes(Host, Owner). get_states(NodeId) -> node_hometree_odbc:get_states(NodeId). get_state(NodeId, JID) -> node_hometree_odbc:get_state(NodeId, JID). set_state(State) -> node_hometree_odbc:set_state(State). get_items(NodeId, From) -> node_hometree_odbc:get_items(NodeId, From). get_items(NodeId, From, RSM) -> node_hometree_odbc:get_items(NodeId, From, RSM). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId, none). get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId, RSM) -> node_hometree_odbc:get_items(NodeId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId, RSM). get_item(NodeId, ItemId) -> node_hometree_odbc:get_item(NodeId, ItemId). get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) -> node_hometree_odbc:get_item(NodeId, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId). set_item(Item) -> node_hometree_odbc:set_item(Item). get_item_name(Host, Node, Id) -> node_hometree_odbc:get_item_name(Host, Node, Id). get_last_items(NodeId, From, Count) -> node_hometree_odbc:get_last_items(NodeId, From, Count). node_to_path(Node) -> [binary_to_list(Node)]. path_to_node(Path) -> case Path of % default slot [Node] -> list_to_binary(Node); % handle old possible entries, used when migrating database content to new format [Node|_] when is_list(Node) -> list_to_binary(string:join([""|Path], "/")); % default case (used by PEP for example) _ -> list_to_binary(Path) end. ejabberd-2.1.11/src/mod_pubsub/nodetree_tree.erl0000664000000000000000000002114612240230175016500 0ustar %%% ==================================================================== %%% ``The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved via the world wide web at http://www.erlang.org/. %%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. %%% Portions created by ProcessOne are Copyright 2006-2012, ProcessOne %%% All Rights Reserved.'' %%% This software is copyright 2006-2012, ProcessOne. %%% %%% %%% @copyright 2006-2012 ProcessOne %%% @author Christophe Romain %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} %%% @end %%% ==================================================================== %%% @doc The module {@module} is the default PubSub node tree plugin. %%%

    It is used as a default for all unknown PubSub node type. It can serve %%% as a developer basis and reference to build its own custom pubsub node tree %%% types.

    %%%

    PubSub node tree plugins are using the {@link gen_nodetree} behaviour.

    %%%

    The API isn't stabilized yet. The pubsub plugin %%% development is still a work in progress. However, the system is already %%% useable and useful as is. Please, send us comments, feedback and %%% improvements.

    -module(nodetree_tree). -author('christophe.romain@process-one.net'). -include_lib("stdlib/include/qlc.hrl"). -include("pubsub.hrl"). -include("jlib.hrl"). -behaviour(gen_pubsub_nodetree). -export([init/3, terminate/2, options/0, set_node/1, get_node/3, get_node/2, get_node/1, get_nodes/2, get_nodes/1, get_parentnodes/3, get_parentnodes_tree/3, get_subnodes/3, get_subnodes_tree/3, create_node/6, delete_node/2 ]). %% ================ %% API definition %% ================ %% @spec (Host, ServerHost, Options) -> ok %% Host = string() %% ServerHost = string() %% Options = [{atom(), term()}] %% @doc

    Called during pubsub modules initialisation. Any pubsub plugin must %% implement this function. It can return anything.

    %%

    This function is mainly used to trigger the setup task necessary for the %% plugin. It can be used for example by the developer to create the specific %% module database schema if it does not exists yet.

    init(_Host, _ServerHost, _Options) -> mnesia:create_table(pubsub_node, [{disc_copies, [node()]}, {attributes, record_info(fields, pubsub_node)}]), mnesia:add_table_index(pubsub_node, id), NodesFields = record_info(fields, pubsub_node), case mnesia:table_info(pubsub_node, attributes) of NodesFields -> ok; _ -> ok %% mnesia:transform_table(pubsub_state, ignore, StatesFields) end, ok. %% @spec (Host, ServerHost) -> ok %% Host = string() %% ServerHost = string() terminate(_Host, _ServerHost) -> ok. %% @spec () -> Options %% Options = [mod_pubsub:nodeOption()] %% @doc Returns the default pubsub node tree options. options() -> [{virtual_tree, false}]. %% @spec (Node) -> ok | {error, Reason} %% Node = mod_pubsub:pubsubNode() %% Reason = mod_pubsub:stanzaError() set_node(Node) when is_record(Node, pubsub_node) -> mnesia:write(Node); set_node(_) -> {error, ?ERR_INTERNAL_SERVER_ERROR}. get_node(Host, Node, _From) -> get_node(Host, Node). %% @spec (Host, NodeId) -> Node | {error, Reason} %% Host = mod_pubsub:host() %% NodeId = mod_pubsub:nodeId() %% Node = mod_pubsub:pubsubNode() %% Reason = mod_pubsub:stanzaError() get_node(Host, NodeId) -> case catch mnesia:read({pubsub_node, {Host, NodeId}}) of [Record] when is_record(Record, pubsub_node) -> Record; [] -> {error, ?ERR_ITEM_NOT_FOUND}; Error -> Error end. get_node(NodeId) -> case catch mnesia:index_read(pubsub_node, NodeId, #pubsub_node.id) of [Record] when is_record(Record, pubsub_node) -> Record; [] -> {error, ?ERR_ITEM_NOT_FOUND}; Error -> Error end. get_nodes(Host, _From) -> get_nodes(Host). %% @spec (Host) -> Nodes | {error, Reason} %% Host = mod_pubsub:host() %% Nodes = [mod_pubsub:pubsubNode()] %% Reason = {aborted, atom()} get_nodes(Host) -> mnesia:match_object(#pubsub_node{nodeid = {Host, '_'}, _ = '_'}). %% @spec (Host, Node, From) -> [] %% Host = mod_pubsub:host() %% NodeId = mod_pubsub:nodeId() %% From = mod_pubsub:jid() %% @doc

    Default node tree does not handle parents, return empty list.

    get_parentnodes(_Host, _NodeId, _From) -> []. %% @spec (Host, NodeId, From) -> [{Depth, Node}] | [] %% Host = mod_pubsub:host() %% NodeId = mod_pubsub:nodeId() %% From = mod_pubsub:jid() %% Depth = integer() %% Node = mod_pubsub:pubsubNode() %% @doc

    Default node tree does not handle parents, return a list %% containing just this node.

    get_parentnodes_tree(Host, NodeId, From) -> case get_node(Host, NodeId, From) of Node when is_record(Node, pubsub_node) -> [{0, [Node]}]; _Error -> [] end. %% @spec (Host, NodeId, From) -> Nodes %% Host = mod_pubsub:host() %% NodeId = mod_pubsub:nodeId() %% From = mod_pubsub:jid() %% Nodes = [mod_pubsub:pubsubNode()] get_subnodes(Host, NodeId, _From) -> get_subnodes(Host, NodeId). get_subnodes(Host, <<>>) -> Q = qlc:q([N || #pubsub_node{nodeid = {NHost, _}, parents = Parents} = N <- mnesia:table(pubsub_node), Host == NHost, Parents == []]), qlc:e(Q); get_subnodes(Host, Node) -> Q = qlc:q([N || #pubsub_node{nodeid = {NHost, _}, parents = Parents} = N <- mnesia:table(pubsub_node), Host == NHost, lists:member(Node, Parents)]), qlc:e(Q). get_subnodes_tree(Host, Node, _From) -> get_subnodes_tree(Host, Node). %% @spec (Host, NodeId) -> Nodes %% Host = mod_pubsub:host() %% NodeId = mod_pubsub:nodeId() %% Nodes = [] | [mod_pubsub:pubsubNode()] get_subnodes_tree(Host, NodeId) -> case get_node(Host, NodeId) of {error, _} -> []; Rec -> BasePlugin = list_to_atom("node_"++Rec#pubsub_node.type), BasePath = BasePlugin:node_to_path(NodeId), mnesia:foldl(fun(#pubsub_node{nodeid = {H, N}} = R, Acc) -> Plugin = list_to_atom("node_"++R#pubsub_node.type), Path = Plugin:node_to_path(N), case lists:prefix(BasePath, Path) and (H == Host) of true -> [R | Acc]; false -> Acc end end, [], pubsub_node) end. %% @spec (Host, NodeId, Type, Owner, Options, Parents) -> %% {ok, NodeIdx} | {error, Reason} %% Host = mod_pubsub:host() %% NodeId = mod_pubsub:nodeId() %% Type = mod_pubsub:nodeType() %% Owner = mod_pubsub:jid() %% Options = [mod_pubsub:nodeOption()] %% Parents = [] | [mod_pubsub:nodeId()] %% NodeIdx = mod_pubsub:nodeIdx() %% Reason = mod_pubsub:stanzaError() create_node(Host, NodeId, Type, Owner, Options, Parents) -> BJID = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), case catch mnesia:read({pubsub_node, {Host, NodeId}}) of [] -> ParentExists = case Host of {_U, _S, _R} -> %% This is special case for PEP handling %% PEP does not uses hierarchy true; _ -> case Parents of [] -> true; [Parent|_] -> case catch mnesia:read({pubsub_node, {Host, Parent}}) of [#pubsub_node{owners = [{[], Host, []}]}] -> true; [#pubsub_node{owners = Owners}] -> lists:member(BJID, Owners); _ -> false end; _ -> false end end, case ParentExists of true -> NodeIdx = pubsub_index:new(node), mnesia:write(#pubsub_node{nodeid = {Host, NodeId}, id = NodeIdx, parents = Parents, type = Type, owners = [BJID], options = Options}), {ok, NodeIdx}; false -> %% Requesting entity is prohibited from creating nodes {error, ?ERR_FORBIDDEN} end; _ -> %% NodeID already exists {error, ?ERR_CONFLICT} end. %% @spec (Host, NodeId) -> Removed %% Host = mod_pubsub:host() %% NodeId = mod_pubsub:nodeId() %% Removed = [mod_pubsub:pubsubNode()] delete_node(Host, NodeId) -> Removed = get_subnodes_tree(Host, NodeId), lists:foreach(fun(#pubsub_node{nodeid = {_, SubNodeId}, id = SubNodeIdx}) -> pubsub_index:free(node, SubNodeIdx), mnesia:delete({pubsub_node, {Host, SubNodeId}}) end, Removed), Removed. ejabberd-2.1.11/src/ejabberd_c2s_config.erl0000664000000000000000000000444412240230175015351 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_c2s_config.erl %%% Author : Mickael Remond %%% Purpose : Functions for c2s interactions from other client %%% connector modules %%% Created : 2 Nov 2007 by Mickael Remond %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_c2s_config). -author('mremond@process-one.net'). -export([get_c2s_limits/0]). %% Get first c2s configuration limitations to apply it to other c2s %% connectors. get_c2s_limits() -> case ejabberd_config:get_local_option(listen) of undefined -> []; C2SFirstListen -> case lists:keysearch(ejabberd_c2s, 2, C2SFirstListen) of false -> []; {value, {_Port, ejabberd_c2s, Opts}} -> select_opts_values(Opts) end end. %% Only get access, shaper and max_stanza_size values select_opts_values(Opts) -> select_opts_values(Opts, []). select_opts_values([], SelectedValues) -> SelectedValues; select_opts_values([{access,Value}|Opts], SelectedValues) -> select_opts_values(Opts, [{access, Value}|SelectedValues]); select_opts_values([{shaper,Value}|Opts], SelectedValues) -> select_opts_values(Opts, [{shaper, Value}|SelectedValues]); select_opts_values([{max_stanza_size,Value}|Opts], SelectedValues) -> select_opts_values(Opts, [{max_stanza_size, Value}|SelectedValues]); select_opts_values([_Opt|Opts], SelectedValues) -> select_opts_values(Opts, SelectedValues). ejabberd-2.1.11/src/sha.erl0000664000000000000000000000515412240230175012271 0ustar %%%---------------------------------------------------------------------- %%% File : sha.erl %%% Author : Alexey Shchepin %%% Purpose : %%% Created : 20 Dec 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(sha). -author('alexey@process-one.net'). -export([start/0, sha/1, sha1/1, sha224/1, sha256/1, sha384/1, sha512/1]). -ifdef(HAVE_MD2). -export([md2/1]). -endif. -include("ejabberd.hrl"). -define(DRIVER, sha_drv). start() -> crypto:start(), Res = case erl_ddll:load_driver(ejabberd:get_so_path(), ?DRIVER) of ok -> ok; {error, already_loaded} -> ok; Err -> Err end, case Res of ok -> Port = open_port({spawn, atom_to_list(?DRIVER)}, [binary]), register(?DRIVER, Port); {error, Reason} -> ?CRITICAL_MSG("unable to load driver '~s': ~s", [driver_path(), erl_ddll:format_error(Reason)]) end. digit_to_xchar(D) when (D >= 0) and (D < 10) -> D + 48; digit_to_xchar(D) -> D + 87. sha(Text) -> Bin = crypto:sha(Text), lists:reverse(ints_to_rxstr(binary_to_list(Bin), [])). ints_to_rxstr([], Res) -> Res; ints_to_rxstr([N | Ns], Res) -> ints_to_rxstr(Ns, [digit_to_xchar(N rem 16), digit_to_xchar(N div 16) | Res]). sha1(Text) -> crypto:sha(Text). sha224(Text) -> erlang:port_control(?DRIVER, 224, Text). sha256(Text) -> erlang:port_control(?DRIVER, 256, Text). sha384(Text) -> erlang:port_control(?DRIVER, 384, Text). sha512(Text) -> erlang:port_control(?DRIVER, 512, Text). -ifdef(HAVE_MD2). md2(Text) -> erlang:port_control(?DRIVER, 2, Text). -endif. driver_path() -> Suffix = case os:type() of {win32, _} -> ".dll"; _ -> ".so" end, filename:join(ejabberd:get_so_path(), atom_to_list(?DRIVER) ++ Suffix). ejabberd-2.1.11/src/mod_register.erl0000664000000000000000000004503312240230175014201 0ustar %%%---------------------------------------------------------------------- %%% File : mod_register.erl %%% Author : Alexey Shchepin %%% Purpose : Inband registration support %%% Created : 8 Dec 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_register). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, stream_feature_register/2, unauthenticated_iq_register/4, try_register/5, process_iq/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER, ?MODULE, process_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_REGISTER, ?MODULE, process_iq, IQDisc), ejabberd_hooks:add(c2s_stream_features, Host, ?MODULE, stream_feature_register, 50), ejabberd_hooks:add(c2s_unauthenticated_iq, Host, ?MODULE, unauthenticated_iq_register, 50), mnesia:create_table(mod_register_ip, [{ram_copies, [node()]}, {local_content, true}, {attributes, [key, value]}]), mnesia:add_table_copy(mod_register_ip, node(), ram_copies), ok. stop(Host) -> ejabberd_hooks:delete(c2s_stream_features, Host, ?MODULE, stream_feature_register, 50), ejabberd_hooks:delete(c2s_unauthenticated_iq, Host, ?MODULE, unauthenticated_iq_register, 50), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_REGISTER), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_REGISTER). stream_feature_register(Acc, _Host) -> [{xmlelement, "register", [{"xmlns", ?NS_FEATURE_IQREGISTER}], []} | Acc]. unauthenticated_iq_register(_Acc, Server, #iq{xmlns = ?NS_REGISTER} = IQ, IP) -> Address = case IP of {A, _Port} -> A; _ -> undefined end, ResIQ = process_iq(jlib:make_jid("", "", ""), jlib:make_jid("", Server, ""), IQ, Address), Res1 = jlib:replace_from_to(jlib:make_jid("", Server, ""), jlib:make_jid("", "", ""), jlib:iq_to_xml(ResIQ)), jlib:remove_attr("to", Res1); unauthenticated_iq_register(Acc, _Server, _IQ, _IP) -> Acc. process_iq(From, To, IQ) -> process_iq(From, To, IQ, jlib:jid_tolower(From)). process_iq(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl, id = ID} = IQ, Source) -> IsCaptchaEnabled = case gen_mod:get_module_opt( To#jid.lserver, ?MODULE, captcha_protected, false) of true -> true; _ -> false end, case Type of set -> UTag = xml:get_subtag(SubEl, "username"), PTag = xml:get_subtag(SubEl, "password"), RTag = xml:get_subtag(SubEl, "remove"), Server = To#jid.lserver, Access = gen_mod:get_module_opt(Server, ?MODULE, access, all), AllowRemove = (allow == acl:match_rule(Server, Access, From)), if (UTag /= false) and (RTag /= false) and AllowRemove -> User = xml:get_tag_cdata(UTag), case From of #jid{user = User, lserver = Server} -> ejabberd_auth:remove_user(User, Server), IQ#iq{type = result, sub_el = [SubEl]}; _ -> if PTag /= false -> Password = xml:get_tag_cdata(PTag), case ejabberd_auth:remove_user(User, Server, Password) of ok -> IQ#iq{type = result, sub_el = [SubEl]}; %% TODO FIXME: This piece of %% code does not work since %% the code have been changed %% to allow several auth %% modules. lists:foreach can %% only return ok: not_allowed -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; not_exists -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}; _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} end; true -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]} end end; (UTag == false) and (RTag /= false) and AllowRemove -> case From of #jid{user = User, lserver = Server, resource = Resource} -> ResIQ = #iq{type = result, xmlns = ?NS_REGISTER, id = ID, sub_el = [SubEl]}, ejabberd_router:route( jlib:make_jid(User, Server, Resource), jlib:make_jid(User, Server, Resource), jlib:iq_to_xml(ResIQ)), ejabberd_auth:remove_user(User, Server), ignore; _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} end; (UTag /= false) and (PTag /= false) -> User = xml:get_tag_cdata(UTag), Password = xml:get_tag_cdata(PTag), try_register_or_set_password( User, Server, Password, From, IQ, SubEl, Source, Lang, not IsCaptchaEnabled); IsCaptchaEnabled -> case ejabberd_captcha:process_reply(SubEl) of ok -> case process_xdata_submit(SubEl) of {ok, User, Password} -> try_register_or_set_password( User, Server, Password, From, IQ, SubEl, Source, Lang, true); _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]} end; {error, malformed} -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}; _ -> ErrText = "The CAPTCHA verification has failed", IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, ErrText)]} end; true -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]} end; get -> {IsRegistered, UsernameSubels, QuerySubels} = case From of #jid{user = User, lserver = Server} -> case ejabberd_auth:is_user_exists(User,Server) of true -> {true, [{xmlcdata, User}], [{xmlelement, "registered", [], []}]}; false -> {false, [{xmlcdata, User}], []} end; _ -> {false, [], []} end, if IsCaptchaEnabled and not IsRegistered -> TopInstrEl = {xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "You need a client that supports x:data " "and CAPTCHA to register")}]}, InstrEl = {xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "Choose a username and password " "to register with this server")}]}, UField = {xmlelement, "field", [{"type", "text-single"}, {"label", translate:translate(Lang, "User")}, {"var", "username"}], [{xmlelement, "required", [], []}]}, PField = {xmlelement, "field", [{"type", "text-private"}, {"label", translate:translate(Lang, "Password")}, {"var", "password"}], [{xmlelement, "required", [], []}]}, case ejabberd_captcha:create_captcha_x( ID, To, Lang, Source, [InstrEl, UField, PField]) of {ok, CaptchaEls} -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", "jabber:iq:register"}], [TopInstrEl | CaptchaEls]}]}; {error, limit} -> ErrText = "Too many CAPTCHA requests", IQ#iq{type = error, sub_el = [SubEl, ?ERRT_RESOURCE_CONSTRAINT( Lang, ErrText)]}; _Err -> ErrText = "Unable to generate a CAPTCHA", IQ#iq{type = error, sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR( Lang, ErrText)]} end; true -> IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", "jabber:iq:register"}], [{xmlelement, "instructions", [], [{xmlcdata, translate:translate( Lang, "Choose a username and password " "to register with this server")}]}, {xmlelement, "username", [], UsernameSubels}, {xmlelement, "password", [], []} | QuerySubels]}]} end end. try_register_or_set_password(User, Server, Password, From, IQ, SubEl, Source, Lang, CaptchaSucceed) -> case From of #jid{user = User, lserver = Server} -> try_set_password(User, Server, Password, IQ, SubEl, Lang); _ when CaptchaSucceed -> case check_from(From, Server) of allow -> case try_register(User, Server, Password, Source, Lang) of ok -> IQ#iq{type = result, sub_el = [SubEl]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end; deny -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]} end; _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} end. %% @doc Try to change password and return IQ response try_set_password(User, Server, Password, IQ, SubEl, Lang) -> case is_strong_password(Server, Password) of true -> case ejabberd_auth:set_password(User, Server, Password) of ok -> IQ#iq{type = result, sub_el = [SubEl]}; {error, empty_password} -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}; {error, not_allowed} -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; {error, invalid_jid} -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}; _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} end; false -> ErrText = "The password is too weak", IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)]} end. try_register(User, Server, Password, SourceRaw, Lang) -> case jlib:is_nodename(User) of false -> {error, ?ERR_BAD_REQUEST}; _ -> JID = jlib:make_jid(User, Server, ""), Access = gen_mod:get_module_opt(Server, ?MODULE, access, all), IPAccess = get_ip_access(Server), case {acl:match_rule(Server, Access, JID), check_ip_access(SourceRaw, IPAccess)} of {deny, _} -> {error, ?ERR_FORBIDDEN}; {_, deny} -> {error, ?ERR_FORBIDDEN}; {allow, allow} -> Source = may_remove_resource(SourceRaw), case check_timeout(Source) of true -> case is_strong_password(Server, Password) of true -> case ejabberd_auth:try_register( User, Server, Password) of {atomic, ok} -> send_welcome_message(JID), send_registration_notifications(JID, Source), ok; Error -> remove_timeout(Source), case Error of {atomic, exists} -> {error, ?ERR_CONFLICT}; {error, invalid_jid} -> {error, ?ERR_JID_MALFORMED}; {error, not_allowed} -> {error, ?ERR_NOT_ALLOWED}; {error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR} end end; false -> ErrText = "The password is too weak", {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)} end; false -> ErrText = "Users are not allowed to register " "accounts so quickly", {error, ?ERRT_RESOURCE_CONSTRAINT(Lang, ErrText)} end end end. send_welcome_message(JID) -> Host = JID#jid.lserver, case gen_mod:get_module_opt(Host, ?MODULE, welcome_message, {"", ""}) of {"", ""} -> ok; {Subj, Body} -> ejabberd_router:route( jlib:make_jid("", Host, ""), JID, {xmlelement, "message", [{"type", "normal"}], [{xmlelement, "subject", [], [{xmlcdata, Subj}]}, {xmlelement, "body", [], [{xmlcdata, Body}]}]}); _ -> ok end. send_registration_notifications(UJID, Source) -> Host = UJID#jid.lserver, case gen_mod:get_module_opt(Host, ?MODULE, registration_watchers, []) of [] -> ok; JIDs when is_list(JIDs) -> Body = lists:flatten( io_lib:format( "[~s] The account ~s was registered from IP address ~s " "on node ~w using ~p.", [get_time_string(), jlib:jid_to_string(UJID), ip_to_string(Source), node(), ?MODULE])), lists:foreach( fun(S) -> case jlib:string_to_jid(S) of error -> ok; JID -> ejabberd_router:route( jlib:make_jid("", Host, ""), JID, {xmlelement, "message", [{"type", "chat"}], [{xmlelement, "body", [], [{xmlcdata, Body}]}]}) end end, JIDs); _ -> ok end. check_from(#jid{user = "", server = ""}, _Server) -> allow; check_from(JID, Server) -> Access = gen_mod:get_module_opt(Server, ?MODULE, access_from, none), acl:match_rule(Server, Access, JID). check_timeout(undefined) -> true; check_timeout(Source) -> Timeout = case ejabberd_config:get_local_option(registration_timeout) of undefined -> 600; TO -> TO end, if is_integer(Timeout) -> {MSec, Sec, _USec} = now(), Priority = -(MSec * 1000000 + Sec), CleanPriority = Priority + Timeout, F = fun() -> Treap = case mnesia:read(mod_register_ip, treap, write) of [] -> treap:empty(); [{mod_register_ip, treap, T}] -> T end, Treap1 = clean_treap(Treap, CleanPriority), case treap:lookup(Source, Treap1) of error -> Treap2 = treap:insert(Source, Priority, [], Treap1), mnesia:write({mod_register_ip, treap, Treap2}), true; {ok, _, _} -> mnesia:write({mod_register_ip, treap, Treap1}), false end end, case mnesia:transaction(F) of {atomic, Res} -> Res; {aborted, Reason} -> ?ERROR_MSG("mod_register: timeout check error: ~p~n", [Reason]), true end; true -> true end. clean_treap(Treap, CleanPriority) -> case treap:is_empty(Treap) of true -> Treap; false -> {_Key, Priority, _Value} = treap:get_root(Treap), if Priority > CleanPriority -> clean_treap(treap:delete_root(Treap), CleanPriority); true -> Treap end end. remove_timeout(undefined) -> true; remove_timeout(Source) -> Timeout = case ejabberd_config:get_local_option(registration_timeout) of undefined -> 600; TO -> TO end, if is_integer(Timeout) -> F = fun() -> Treap = case mnesia:read(mod_register_ip, treap, write) of [] -> treap:empty(); [{mod_register_ip, treap, T}] -> T end, Treap1 = treap:delete(Source, Treap), mnesia:write({mod_register_ip, treap, Treap1}), ok end, case mnesia:transaction(F) of {atomic, ok} -> ok; {aborted, Reason} -> ?ERROR_MSG("mod_register: timeout remove error: ~p~n", [Reason]), ok end; true -> ok end. ip_to_string(Source) when is_tuple(Source) -> inet_parse:ntoa(Source); ip_to_string(undefined) -> "undefined"; ip_to_string(_) -> "unknown". get_time_string() -> write_time(erlang:localtime()). %% Function copied from ejabberd_logger_h.erl and customized write_time({{Y,Mo,D},{H,Mi,S}}) -> io_lib:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Y, Mo, D, H, Mi, S]). process_xdata_submit(El) -> case xml:get_subtag(El, "x") of false -> error; Xdata -> Fields = jlib:parse_xdata_submit(Xdata), case catch {proplists:get_value("username", Fields), proplists:get_value("password", Fields)} of {[User|_], [Pass|_]} -> {ok, User, Pass}; _ -> error end end. is_strong_password(Server, Password) -> LServer = jlib:nameprep(Server), case gen_mod:get_module_opt(LServer, ?MODULE, password_strength, 0) of Entropy when is_number(Entropy), Entropy >= 0 -> if Entropy == 0 -> true; true -> ejabberd_auth:entropy(Password) >= Entropy end; Wrong -> ?WARNING_MSG("Wrong value for password_strength option: ~p", [Wrong]), true end. %%% %%% ip_access management %%% may_remove_resource({_, _, _} = From) -> jlib:jid_remove_resource(From); may_remove_resource(From) -> From. get_ip_access(Host) -> IPAccess = gen_mod:get_module_opt(Host, ?MODULE, ip_access, []), lists:flatmap( fun({Access, S}) -> case parse_ip_netmask(S) of {ok, IP, Mask} -> [{Access, IP, Mask}]; error -> ?ERROR_MSG("mod_register: invalid " "network specification: ~p", [S]), [] end end, IPAccess). parse_ip_netmask(S) -> case string:tokens(S, "/") of [IPStr] -> case inet_parse:address(IPStr) of {ok, {_, _, _, _} = IP} -> {ok, IP, 32}; {ok, {_, _, _, _, _, _, _, _} = IP} -> {ok, IP, 128}; _ -> error end; [IPStr, MaskStr] -> case catch list_to_integer(MaskStr) of Mask when is_integer(Mask), Mask >= 0 -> case inet_parse:address(IPStr) of {ok, {_, _, _, _} = IP} when Mask =< 32 -> {ok, IP, Mask}; {ok, {_, _, _, _, _, _, _, _} = IP} when Mask =< 128 -> {ok, IP, Mask}; _ -> error end; _ -> error end; _ -> error end. check_ip_access(_Source, []) -> allow; check_ip_access({User, Server, Resource}, IPAccess) -> case ejabberd_sm:get_user_ip(User, Server, Resource) of {IPAddress, _PortNumber} -> check_ip_access(IPAddress, IPAccess); _ -> true end; check_ip_access({_, _, _, _} = IP, [{Access, {_, _, _, _} = Net, Mask} | IPAccess]) -> IPInt = ip_to_integer(IP), NetInt = ip_to_integer(Net), M = bnot ((1 bsl (32 - Mask)) - 1), if IPInt band M =:= NetInt band M -> Access; true -> check_ip_access(IP, IPAccess) end; check_ip_access({_, _, _, _, _, _, _, _} = IP, [{Access, {_, _, _, _, _, _, _, _} = Net, Mask} | IPAccess]) -> IPInt = ip_to_integer(IP), NetInt = ip_to_integer(Net), M = bnot ((1 bsl (128 - Mask)) - 1), if IPInt band M =:= NetInt band M -> Access; true -> check_ip_access(IP, IPAccess) end; check_ip_access(IP, [_ | IPAccess]) -> check_ip_access(IP, IPAccess). ip_to_integer({IP1, IP2, IP3, IP4}) -> (((((IP1 bsl 8) bor IP2) bsl 8) bor IP3) bsl 8) bor IP4; ip_to_integer({IP1, IP2, IP3, IP4, IP5, IP6, IP7, IP8}) -> (((((((((((((IP1 bsl 16) bor IP2) bsl 16) bor IP3) bsl 16) bor IP4) bsl 16) bor IP5) bsl 16) bor IP6) bsl 16) bor IP7) bsl 16) bor IP8. ejabberd-2.1.11/src/jd2ejd.erl0000664000000000000000000001332612240230175012660 0ustar %%%---------------------------------------------------------------------- %%% File : jd2ejd.erl %%% Author : Alexey Shchepin %%% Purpose : Import of jabberd14 user spool file %%% Created : 2 Feb 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(jd2ejd). -author('alexey@process-one.net'). %% External exports -export([import_file/1, import_dir/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- import_file(File) -> User = filename:rootname(filename:basename(File)), Server = filename:basename(filename:dirname(File)), case (jlib:nodeprep(User) /= error) andalso (jlib:nameprep(Server) /= error) of true -> case file:read_file(File) of {ok, Text} -> case xml_stream:parse_element(Text) of El when element(1, El) == xmlelement -> case catch process_xdb(User, Server, El) of {'EXIT', Reason} -> ?ERROR_MSG( "Error while processing file \"~s\": ~p~n", [File, Reason]), {error, Reason}; _ -> ok end; {error, Reason} -> ?ERROR_MSG("Can't parse file \"~s\": ~p~n", [File, Reason]), {error, Reason} end; {error, Reason} -> ?ERROR_MSG("Can't read file \"~s\": ~p~n", [File, Reason]), {error, Reason} end; false -> ?ERROR_MSG("Illegal user/server name in file \"~s\"~n", [File]), {error, "illegal user/server"} end. import_dir(Dir) -> {ok, Files} = file:list_dir(Dir), MsgFiles = lists:filter( fun(FN) -> case string:len(FN) > 4 of true -> string:substr(FN, string:len(FN) - 3) == ".xml"; _ -> false end end, Files), lists:foldl( fun(FN, A) -> Res = import_file(filename:join([Dir, FN])), case {A, Res} of {ok, ok} -> ok; {ok, _} -> {error, "see ejabberd log for details"}; _ -> A end end, ok, MsgFiles). %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- process_xdb(User, Server, {xmlelement, Name, _Attrs, Els}) -> case Name of "xdb" -> lists:foreach( fun(El) -> xdb_data(User, Server, El) end, Els); _ -> ok end. xdb_data(_User, _Server, {xmlcdata, _CData}) -> ok; xdb_data(User, Server, {xmlelement, _Name, Attrs, _Els} = El) -> From = jlib:make_jid(User, Server, ""), LServer = jlib:nameprep(Server), case xml:get_attr_s("xmlns", Attrs) of ?NS_AUTH -> Password = xml:get_tag_cdata(El), ejabberd_auth:set_password(User, Server, Password), ok; ?NS_ROSTER -> case lists:member(mod_roster_odbc, gen_mod:loaded_modules(LServer)) of true -> catch mod_roster_odbc:set_items(User, Server, El); false -> catch mod_roster:set_items(User, Server, El) end, ok; ?NS_LAST -> TimeStamp = xml:get_attr_s("last", Attrs), Status = xml:get_tag_cdata(El), case lists:member(mod_last_odbc, gen_mod:loaded_modules(LServer)) of true -> catch mod_last_odbc:store_last_info( User, Server, list_to_integer(TimeStamp), Status); false -> catch mod_last:store_last_info( User, Server, list_to_integer(TimeStamp), Status) end, ok; ?NS_VCARD -> case lists:member(mod_vcard_odbc, gen_mod:loaded_modules(LServer)) of true -> catch mod_vcard_odbc:process_sm_iq( From, jlib:make_jid("", Server, ""), #iq{type = set, xmlns = ?NS_VCARD, sub_el = El}); false -> catch mod_vcard:process_sm_iq( From, jlib:make_jid("", Server, ""), #iq{type = set, xmlns = ?NS_VCARD, sub_el = El}) end, ok; "jabber:x:offline" -> process_offline(Server, From, El), ok; XMLNS -> case xml:get_attr_s("j_private_flag", Attrs) of "1" -> catch mod_private:process_sm_iq( From, jlib:make_jid("", Server, ""), #iq{type = set, xmlns = ?NS_PRIVATE, sub_el = {xmlelement, "query", [], [jlib:remove_attr( "j_private_flag", jlib:remove_attr("xdbns", El))]}}); _ -> ?DEBUG("jd2ejd: Unknown namespace \"~s\"~n", [XMLNS]) end, ok end. process_offline(Server, To, {xmlelement, _, _, Els}) -> LServer = jlib:nameprep(Server), lists:foreach(fun({xmlelement, _, Attrs, _} = El) -> FromS = xml:get_attr_s("from", Attrs), From = case FromS of "" -> jlib:make_jid("", Server, ""); _ -> jlib:string_to_jid(FromS) end, case From of error -> ok; _ -> ejabberd_hooks:run(offline_message_hook, LServer, [From, To, El]) end end, Els). ejabberd-2.1.11/src/xml_stream.erl0000664000000000000000000001240112240230175013662 0ustar %%%---------------------------------------------------------------------- %%% File : xml_stream.erl %%% Author : Alexey Shchepin %%% Purpose : Parse XML streams %%% Created : 17 Nov 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(xml_stream). -author('alexey@process-one.net'). -export([new/1, new/2, parse/2, close/1, parse_element/1]). -define(XML_START, 0). -define(XML_END, 1). -define(XML_CDATA, 2). -define(XML_ERROR, 3). -define(PARSE_COMMAND, 0). -define(PARSE_FINAL_COMMAND, 1). -record(xml_stream_state, {callback_pid, port, stack, size, maxsize}). process_data(CallbackPid, Stack, Data) -> case Data of {?XML_START, {Name, Attrs}} -> if Stack == [] -> catch gen_fsm:send_event(CallbackPid, {xmlstreamstart, Name, Attrs}); true -> ok end, [{xmlelement, Name, Attrs, []} | Stack]; {?XML_END, EndName} -> case Stack of [{xmlelement, Name, Attrs, Els} | Tail] -> NewEl = {xmlelement, Name, Attrs, lists:reverse(Els)}, case Tail of [] -> catch gen_fsm:send_event(CallbackPid, {xmlstreamend, EndName}), Tail; [_] -> catch gen_fsm:send_event(CallbackPid, {xmlstreamelement, NewEl}), Tail; [{xmlelement, Name1, Attrs1, Els1} | Tail1] -> [{xmlelement, Name1, Attrs1, [NewEl | Els1]} | Tail1] end end; {?XML_CDATA, CData} -> case Stack of [El] -> [El]; %% Merge CDATA nodes if they are contiguous %% This does not change the semantic: the split in %% several CDATA nodes depends on the TCP/IP packet %% fragmentation [{xmlelement, Name, Attrs, [{xmlcdata, PreviousCData}|Els]} | Tail] -> [{xmlelement, Name, Attrs, [{xmlcdata, list_to_binary([PreviousCData, CData])} | Els]} | Tail]; %% No previous CDATA [{xmlelement, Name, Attrs, Els} | Tail] -> [{xmlelement, Name, Attrs, [{xmlcdata, CData} | Els]} | Tail]; [] -> [] end; {?XML_ERROR, Err} -> catch gen_fsm:send_event(CallbackPid, {xmlstreamerror, Err}) end. new(CallbackPid) -> new(CallbackPid, infinity). new(CallbackPid, MaxSize) -> Port = open_port({spawn, "expat_erl"}, [binary]), #xml_stream_state{callback_pid = CallbackPid, port = Port, stack = [], size = 0, maxsize = MaxSize}. parse(#xml_stream_state{callback_pid = CallbackPid, port = Port, stack = Stack, size = Size, maxsize = MaxSize} = State, Str) -> StrSize = if is_list(Str) -> length(Str); is_binary(Str) -> size(Str) end, Res = port_control(Port, ?PARSE_COMMAND, Str), {NewStack, NewSize} = lists:foldl( fun(Data, {St, Sz}) -> NewSt = process_data(CallbackPid, St, Data), case NewSt of [_] -> {NewSt, 0}; _ -> {NewSt, Sz} end end, {Stack, Size + StrSize}, binary_to_term(Res)), if NewSize > MaxSize -> catch gen_fsm:send_event(CallbackPid, {xmlstreamerror, "XML stanza is too big"}); true -> ok end, State#xml_stream_state{stack = NewStack, size = NewSize}. close(#xml_stream_state{port = Port}) -> port_close(Port). parse_element(Str) -> Port = open_port({spawn, "expat_erl"}, [binary]), Res = port_control(Port, ?PARSE_FINAL_COMMAND, Str), port_close(Port), process_element_events(binary_to_term(Res)). process_element_events(Events) -> process_element_events(Events, []). process_element_events([], _Stack) -> {error, parse_error}; process_element_events([Event | Events], Stack) -> case Event of {?XML_START, {Name, Attrs}} -> process_element_events( Events, [{xmlelement, Name, Attrs, []} | Stack]); {?XML_END, _EndName} -> case Stack of [{xmlelement, Name, Attrs, Els} | Tail] -> NewEl = {xmlelement, Name, Attrs, lists:reverse(Els)}, case Tail of [] -> if Events == [] -> NewEl; true -> {error, parse_error} end; [{xmlelement, Name1, Attrs1, Els1} | Tail1] -> process_element_events( Events, [{xmlelement, Name1, Attrs1, [NewEl | Els1]} | Tail1]) end end; {?XML_CDATA, CData} -> case Stack of [{xmlelement, Name, Attrs, Els} | Tail] -> process_element_events( Events, [{xmlelement, Name, Attrs, [{xmlcdata, CData} | Els]} | Tail]); [] -> process_element_events(Events, []) end; {?XML_ERROR, Err} -> {error, Err} end. ejabberd-2.1.11/src/ejabberd_ctl.erl0000664000000000000000000006145412240230175014123 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_ctl.erl %%% Author : Alexey Shchepin %%% Purpose : ejabberd command line admin tool %%% Created : 11 Jan 2004 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %%% @headerfile "ejabberd_ctl.hrl" %%% @doc Management of ejabberdctl commands and frontend to ejabberd commands. %%% %%% An ejabberdctl command is an abstract function identified by a %%% name, with a defined number of calling arguments, that can be %%% defined in any Erlang module and executed using ejabberdctl %%% administration script. %%% %%% Note: strings cannot have blankspaces %%% %%% Does not support commands that have arguments with ctypes: list, tuple %%% %%% TODO: Update the guide %%% TODO: Mention this in the release notes %%% Note: the commands with several words use now the underline: _ %%% It is still possible to call the commands with dash: - %%% but this is deprecated, and may be removed in a future version. -module(ejabberd_ctl). -author('alexey@process-one.net'). -export([start/0, init/0, process/1, process2/2, register_commands/3, unregister_commands/3]). -include("ejabberd_ctl.hrl"). -include("ejabberd_commands.hrl"). -include("ejabberd.hrl"). %%----------------------------- %% Module %%----------------------------- start() -> case init:get_plain_arguments() of [SNode | Args] -> SNode1 = case string:tokens(SNode, "@") of [_Node, _Server] -> SNode; _ -> case net_kernel:longnames() of true -> SNode ++ "@" ++ inet_db:gethostname() ++ "." ++ inet_db:res_option(domain); false -> SNode ++ "@" ++ inet_db:gethostname(); _ -> SNode end end, Node = list_to_atom(SNode1), Status = case rpc:call(Node, ?MODULE, process, [Args]) of {badrpc, Reason} -> ?PRINT("Failed RPC connection to the node ~p: ~p~n", [Node, Reason]), %% TODO: show minimal start help ?STATUS_BADRPC; S -> S end, halt(Status); _ -> print_usage(), halt(?STATUS_USAGE) end. init() -> ets:new(ejabberd_ctl_cmds, [named_table, set, public]), ets:new(ejabberd_ctl_host_cmds, [named_table, set, public]). %%----------------------------- %% ejabberdctl Command managment %%----------------------------- register_commands(CmdDescs, Module, Function) -> ets:insert(ejabberd_ctl_cmds, CmdDescs), ejabberd_hooks:add(ejabberd_ctl_process, Module, Function, 50), ok. unregister_commands(CmdDescs, Module, Function) -> lists:foreach(fun(CmdDesc) -> ets:delete_object(ejabberd_ctl_cmds, CmdDesc) end, CmdDescs), ejabberd_hooks:delete(ejabberd_ctl_process, Module, Function, 50), ok. %%----------------------------- %% Process %%----------------------------- %% The commands status, stop and restart are defined here to ensure %% they are usable even if ejabberd is completely stopped. process(["status"]) -> {InternalStatus, ProvidedStatus} = init:get_status(), ?PRINT("The node ~p is ~p with status: ~p~n", [node(), InternalStatus, ProvidedStatus]), case lists:keysearch(ejabberd, 1, application:which_applications()) of false -> EjabberdLogPath = ejabberd_app:get_log_path(), ?PRINT("ejabberd is not running in that node~n" "Check for error messages: ~s~n" "or other files in that directory.~n", [EjabberdLogPath]), ?STATUS_ERROR; {value, {_, _, Version}} -> ?PRINT("ejabberd ~s is running in that node~n", [Version]), ?STATUS_SUCCESS end; process(["stop"]) -> %%ejabberd_cover:stop(), init:stop(), ?STATUS_SUCCESS; process(["restart"]) -> init:restart(), ?STATUS_SUCCESS; process(["mnesia"]) -> ?PRINT("~p~n", [mnesia:system_info(all)]), ?STATUS_SUCCESS; process(["mnesia", "info"]) -> mnesia:info(), ?STATUS_SUCCESS; process(["mnesia", Arg]) when is_list(Arg) -> case catch mnesia:system_info(list_to_atom(Arg)) of {'EXIT', Error} -> ?PRINT("Error: ~p~n", [Error]); Return -> ?PRINT("~p~n", [Return]) end, ?STATUS_SUCCESS; %% The arguments --long and --dual are not documented because they are %% automatically selected depending in the number of columns of the shell process(["help" | Mode]) -> {MaxC, ShCode} = get_shell_info(), case Mode of [] -> print_usage(dual, MaxC, ShCode), ?STATUS_USAGE; ["--dual"] -> print_usage(dual, MaxC, ShCode), ?STATUS_USAGE; ["--long"] -> print_usage(long, MaxC, ShCode), ?STATUS_USAGE; ["--tags"] -> print_usage_tags(MaxC, ShCode), ?STATUS_SUCCESS; ["--tags", Tag] -> print_usage_tags(Tag, MaxC, ShCode), ?STATUS_SUCCESS; ["help"] -> print_usage_help(MaxC, ShCode), ?STATUS_SUCCESS; [CmdString | _] -> CmdStringU = ejabberd_regexp:greplace(CmdString, "-", "_"), print_usage_commands(CmdStringU, MaxC, ShCode), ?STATUS_SUCCESS end; process(Args) -> AccessCommands = get_accesscommands(), {String, Code} = process2(Args, AccessCommands), case String of [] -> ok; _ -> io:format("~s~n", [String]) end, Code. %% @spec (Args::[string()], AccessCommands) -> {String::string(), Code::integer()} process2(["--auth", User, Server, Pass | Args], AccessCommands) -> process2(Args, {User, Server, Pass}, AccessCommands); process2(Args, AccessCommands) -> process2(Args, noauth, AccessCommands). process2(Args, Auth, AccessCommands) -> case try_run_ctp(Args, Auth, AccessCommands) of {String, wrong_command_arguments} when is_list(String) -> io:format(lists:flatten(["\n" | String]++["\n"])), [CommandString | _] = Args, process(["help" | [CommandString]]), {lists:flatten(String), ?STATUS_ERROR}; {String, Code} when is_list(String) and is_integer(Code) -> {lists:flatten(String), Code}; String when is_list(String) -> {lists:flatten(String), ?STATUS_SUCCESS}; Code when is_integer(Code) -> {"", Code}; Other -> {"Erroneous result: " ++ io_lib:format("~p", [Other]), ?STATUS_ERROR} end. get_accesscommands() -> case ejabberd_config:get_local_option(ejabberdctl_access_commands) of ACs when is_list(ACs) -> ACs; _ -> [] end. %%----------------------------- %% Command calling %%----------------------------- %% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()} try_run_ctp(Args, Auth, AccessCommands) -> try ejabberd_hooks:run_fold(ejabberd_ctl_process, false, [Args]) of false when Args /= [] -> try_call_command(Args, Auth, AccessCommands); false -> print_usage(), {"", ?STATUS_USAGE}; Status -> {"", Status} catch exit:Why -> print_usage(), {io_lib:format("Error in ejabberd ctl process: ~p", [Why]), ?STATUS_USAGE}; Error:Why -> %% In this case probably ejabberd is not started, so let's show Status process(["status"]), ?PRINT("~n", []), {io_lib:format("Error in ejabberd ctl process: '~p' ~p", [Error, Why]), ?STATUS_USAGE} end. %% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()} try_call_command(Args, Auth, AccessCommands) -> try call_command(Args, Auth, AccessCommands) of {error, command_unknown} -> {io_lib:format("Error: command ~p not known.", [hd(Args)]), ?STATUS_ERROR}; {error, wrong_command_arguments} -> {"Error: wrong arguments", ?STATUS_ERROR}; Res -> Res catch A:Why -> Stack = erlang:get_stacktrace(), {io_lib:format("Problem '~p ~p' occurred executing the command.~nStacktrace: ~p", [A, Why, Stack]), ?STATUS_ERROR} end. %% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()} | {error, ErrorType} call_command([CmdString | Args], Auth, AccessCommands) -> CmdStringU = ejabberd_regexp:greplace(CmdString, "-", "_"), Command = list_to_atom(CmdStringU), case ejabberd_commands:get_command_format(Command) of {error, command_unknown} -> {error, command_unknown}; {ArgsFormat, ResultFormat} -> case (catch format_args(Args, ArgsFormat)) of ArgsFormatted when is_list(ArgsFormatted) -> Result = ejabberd_commands:execute_command(AccessCommands, Auth, Command, ArgsFormatted), format_result(Result, ResultFormat); {'EXIT', {function_clause,[{lists,zip,[A1, A2]} | _]}} -> {NumCompa, TextCompa} = case {length(A1), length(A2)} of {L1, L2} when L1 < L2 -> {L2-L1, "less argument"}; {L1, L2} when L1 > L2 -> {L1-L2, "more argument"} end, {io_lib:format("Error: the command ~p requires ~p ~s.", [CmdString, NumCompa, TextCompa]), wrong_command_arguments} end end. %%----------------------------- %% Format arguments %%----------------------------- format_args(Args, ArgsFormat) -> lists:foldl( fun({{_ArgName, ArgFormat}, Arg}, Res) -> Formatted = format_arg(Arg, ArgFormat), Res ++ [Formatted] end, [], lists:zip(ArgsFormat, Args)). format_arg(Arg, integer) -> format_arg2(Arg, "~d"); format_arg("", string) -> ""; format_arg(Arg, string) -> NumChars = integer_to_list(string:len(Arg)), Parse = "~" ++ NumChars ++ "c", format_arg2(Arg, Parse). format_arg2(Arg, Parse)-> {ok, [Arg2], _RemainingArguments} = io_lib:fread(Parse, Arg), Arg2. %%----------------------------- %% Format result %%----------------------------- format_result({error, ErrorAtom}, _) -> {io_lib:format("Error: ~p", [ErrorAtom]), make_status(error)}; format_result(Atom, {_Name, atom}) -> io_lib:format("~p", [Atom]); format_result(Int, {_Name, integer}) -> io_lib:format("~p", [Int]); format_result(String, {_Name, string}) -> io_lib:format("~s", [String]); format_result(Code, {_Name, rescode}) -> make_status(Code); format_result({Code, Text}, {_Name, restuple}) -> {io_lib:format("~s", [Text]), make_status(Code)}; %% The result is a list of something: [something()] format_result([], {_Name, {list, _ElementsDef}}) -> ""; format_result([FirstElement | Elements], {_Name, {list, ElementsDef}}) -> %% Start formatting the first element [format_result(FirstElement, ElementsDef) | %% If there are more elements, put always first a newline character lists:map( fun(Element) -> ["\n" | format_result(Element, ElementsDef)] end, Elements)]; %% The result is a tuple with several elements: {something1(), something2(),...} %% NOTE: the elements in the tuple are separated with tabular characters, %% if a string is empty, it will be difficult to notice in the shell, %% maybe a different separation character should be used, like ;;? format_result(ElementsTuple, {_Name, {tuple, ElementsDef}}) -> ElementsList = tuple_to_list(ElementsTuple), [{FirstE, FirstD} | ElementsAndDef] = lists:zip(ElementsList, ElementsDef), [format_result(FirstE, FirstD) | lists:map( fun({Element, ElementDef}) -> ["\t" | format_result(Element, ElementDef)] end, ElementsAndDef)]. make_status(ok) -> ?STATUS_SUCCESS; make_status(true) -> ?STATUS_SUCCESS; make_status(_Error) -> ?STATUS_ERROR. get_list_commands() -> try ejabberd_commands:list_commands() of Commands -> [tuple_command_help(Command) || {N,_,_}=Command <- Commands, %% Don't show again those commands, because they are already %% announced by ejabberd_ctl itself N /= status, N /= stop, N /= restart] catch exit:_ -> [] end. %% Return: {string(), [string()], string()} tuple_command_help({Name, Args, Desc}) -> Arguments = [atom_to_list(ArgN) || {ArgN, _ArgF} <- Args], Prepend = case is_supported_args(Args) of true -> ""; false -> "*" end, CallString = atom_to_list(Name), {CallString, Arguments, Prepend ++ Desc}. is_supported_args(Args) -> lists:all( fun({_Name, Format}) -> (Format == integer) or (Format == string) end, Args). get_list_ctls() -> case catch ets:tab2list(ejabberd_ctl_cmds) of {'EXIT', _} -> []; Cs -> [{NameArgs, [], Desc} || {NameArgs, Desc} <- Cs] end. %%----------------------------- %% Print help %%----------------------------- %% Bold -define(B1, "\e[1m"). -define(B2, "\e[22m"). -define(B(S), case ShCode of true -> [?B1, S, ?B2]; false -> S end). %% Underline -define(U1, "\e[4m"). -define(U2, "\e[24m"). -define(U(S), case ShCode of true -> [?U1, S, ?U2]; false -> S end). print_usage() -> {MaxC, ShCode} = get_shell_info(), print_usage(dual, MaxC, ShCode). print_usage(HelpMode, MaxC, ShCode) -> AllCommands = [ {"status", [], "Get ejabberd status"}, {"stop", [], "Stop ejabberd"}, {"restart", [], "Restart ejabberd"}, {"help", ["[--tags [tag] | com?*]"], "Show help (try: ejabberdctl help help)"}, {"mnesia", ["[info]"], "show information of Mnesia system"}] ++ get_list_commands() ++ get_list_ctls(), ?PRINT( ["Usage: ", ?B("ejabberdctl"), " [--node ", ?U("nodename"), "] [--auth ", ?U("user"), " ", ?U("host"), " ", ?U("password"), "] ", ?U("command"), " [", ?U("options"), "]\n" "\n" "Available commands in this ejabberd node:\n"], []), print_usage_commands(HelpMode, MaxC, ShCode, AllCommands), ?PRINT( ["\n" "Examples:\n" " ejabberdctl restart\n" " ejabberdctl --node ejabberd@host restart\n"], []). print_usage_commands(HelpMode, MaxC, ShCode, Commands) -> CmdDescsSorted = lists:keysort(1, Commands), %% What is the length of the largest command? {CmdArgsLenDescsSorted, Lens} = lists:mapfoldl( fun({Cmd, Args, Desc}, Lengths) -> Len = length(Cmd) + lists:foldl(fun(Arg, R) -> R + 1 + length(Arg) end, 0, Args), {{Cmd, Args, Len, Desc}, [Len | Lengths]} end, [], CmdDescsSorted), MaxCmdLen = case Lens of [] -> 80; _ -> lists:max(Lens) end, %% For each command in the list of commands %% Convert its definition to a line FmtCmdDescs = format_command_lines(CmdArgsLenDescsSorted, MaxCmdLen, MaxC, ShCode, HelpMode), ?PRINT([FmtCmdDescs], []). %% Get some info about the shell: %% how many columns of width %% and guess if it supports text formatting codes. get_shell_info() -> %% This function was introduced in OTP R12B-0 try io:columns() of {ok, C} -> {C-2, true}; {error, enotsup} -> {78, false} catch _:_ -> {78, false} end. %% Split this command description in several lines of proper length prepare_description(DescInit, MaxC, Desc) -> Words = string:tokens(Desc, " "), prepare_long_line(DescInit, MaxC, Words). prepare_long_line(DescInit, MaxC, Words) -> MaxSegmentLen = MaxC - DescInit, MarginString = lists:duplicate(DescInit, $\s), % Put spaces [FirstSegment | MoreSegments] = split_desc_segments(MaxSegmentLen, Words), MoreSegmentsMixed = mix_desc_segments(MarginString, MoreSegments), [FirstSegment | MoreSegmentsMixed]. mix_desc_segments(MarginString, Segments) -> [["\n", MarginString, Segment] || Segment <- Segments]. split_desc_segments(MaxL, Words) -> join(MaxL, Words). %% Join words in a segment, %% but stop adding to a segment if adding this word would pass L join(L, Words) -> join(L, Words, 0, [], []). join(_L, [], _LenLastSeg, LastSeg, ResSeg) -> ResSeg2 = [lists:reverse(LastSeg) | ResSeg], lists:reverse(ResSeg2); join(L, [Word | Words], LenLastSeg, LastSeg, ResSeg) -> LWord = length(Word), case LWord + LenLastSeg < L of true -> %% This word fits in the last segment %% If this word ends with "\n", reset column counter case string:str(Word, "\n") of 0 -> join(L, Words, LenLastSeg+LWord+1, [" ", Word | LastSeg], ResSeg); _ -> join(L, Words, LWord+1, [" ", Word | LastSeg], ResSeg) end; false -> join(L, Words, LWord, [" ", Word], [lists:reverse(LastSeg) | ResSeg]) end. format_command_lines(CALD, MaxCmdLen, MaxC, ShCode, dual) when MaxC - MaxCmdLen < 40 -> %% If the space available for descriptions is too narrow, enforce long help mode format_command_lines(CALD, MaxCmdLen, MaxC, ShCode, long); format_command_lines(CALD, MaxCmdLen, MaxC, ShCode, dual) -> lists:map( fun({Cmd, Args, CmdArgsL, Desc}) -> DescFmt = prepare_description(MaxCmdLen+4, MaxC, Desc), [" ", ?B(Cmd), " ", [[?U(Arg), " "] || Arg <- Args], string:chars($\s, MaxCmdLen - CmdArgsL + 1), DescFmt, "\n"] end, CALD); format_command_lines(CALD, _MaxCmdLen, MaxC, ShCode, long) -> lists:map( fun({Cmd, Args, _CmdArgsL, Desc}) -> DescFmt = prepare_description(8, MaxC, Desc), ["\n ", ?B(Cmd), " ", [[?U(Arg), " "] || Arg <- Args], "\n", " ", DescFmt, "\n"] end, CALD). %%----------------------------- %% Print Tags %%----------------------------- print_usage_tags(MaxC, ShCode) -> ?PRINT("Available tags and commands:", []), TagsCommands = ejabberd_commands:get_tags_commands(), lists:foreach( fun({Tag, Commands} = _TagCommands) -> ?PRINT(["\n\n ", ?B(Tag), "\n "], []), Words = lists:sort(Commands), Desc = prepare_long_line(5, MaxC, Words), ?PRINT(Desc, []) end, TagsCommands), ?PRINT("\n\n", []). print_usage_tags(Tag, MaxC, ShCode) -> ?PRINT(["Available commands with tag ", ?B(Tag), ":", "\n"], []), HelpMode = long, TagsCommands = ejabberd_commands:get_tags_commands(), CommandsNames = case lists:keysearch(Tag, 1, TagsCommands) of {value, {Tag, CNs}} -> CNs; false -> [] end, CommandsList = lists:map( fun(NameString) -> C = ejabberd_commands:get_command_definition(list_to_atom(NameString)), #ejabberd_commands{name = Name, args = Args, desc = Desc} = C, tuple_command_help({Name, Args, Desc}) end, CommandsNames), print_usage_commands(HelpMode, MaxC, ShCode, CommandsList), ?PRINT("\n", []). %%----------------------------- %% Print usage of 'help' command %%----------------------------- print_usage_help(MaxC, ShCode) -> LongDesc = ["The special 'help' ejabberdctl command provides help of ejabberd commands.\n\n" "The format is:\n ", ?B("ejabberdctl"), " ", ?B("help"), " [", ?B("--tags"), " ", ?U("[tag]"), " | ", ?U("com?*"), "]\n\n" "The optional arguments:\n" " ",?B("--tags")," Show all tags and the names of commands in each tag\n" " ",?B("--tags"), " ", ?U("tag")," Show description of commands in this tag\n" " ",?U("command")," Show detailed description of the command\n" " ",?U("com?*")," Show detailed description of commands that match this glob.\n" " You can use ? to match a simple character,\n" " and * to match several characters.\n" "\n", "Some example usages:\n", " ejabberdctl help\n", " ejabberdctl help --tags\n", " ejabberdctl help --tags accounts\n", " ejabberdctl help register\n", " ejabberdctl help regist*\n", "\n", "Please note that 'ejabberdctl help' shows all ejabberd commands,\n", "even those that cannot be used in the shell with ejabberdctl.\n", "Those commands can be identified because the description starts with: *"], ArgsDef = [], C = #ejabberd_commands{ desc = "Show help of ejabberd commands", longdesc = lists:flatten(LongDesc), args = ArgsDef, result = {help, string}}, print_usage_command("help", C, MaxC, ShCode). %%----------------------------- %% Print usage command %%----------------------------- %% @spec (CmdSubString::string(), MaxC::integer(), ShCode::boolean()) -> ok print_usage_commands(CmdSubString, MaxC, ShCode) -> %% Get which command names match this substring AllCommandsNames = [atom_to_list(Name) || {Name, _, _} <- ejabberd_commands:list_commands()], Cmds = filter_commands(AllCommandsNames, CmdSubString), case Cmds of [] -> io:format("Error: not command found that match: ~p~n", [CmdSubString]); _ -> print_usage_commands2(lists:sort(Cmds), MaxC, ShCode) end. print_usage_commands2(Cmds, MaxC, ShCode) -> %% Then for each one print it lists:mapfoldl( fun(Cmd, Remaining) -> print_usage_command(Cmd, MaxC, ShCode), case Remaining > 1 of true -> ?PRINT([" ", lists:duplicate(MaxC, 126), " \n"], []); false -> ok end, {ok, Remaining-1} end, length(Cmds), Cmds). filter_commands(All, SubString) -> case lists:member(SubString, All) of true -> [SubString]; false -> filter_commands_regexp(All, SubString) end. filter_commands_regexp(All, Glob) -> RegExp = ejabberd_regexp:sh_to_awk(Glob), lists:filter( fun(Command) -> case ejabberd_regexp:run(Command, RegExp) of match -> true; nomatch -> false end end, All). %% @spec (Cmd::string(), MaxC::integer(), ShCode::boolean()) -> ok print_usage_command(Cmd, MaxC, ShCode) -> Name = list_to_atom(Cmd), case ejabberd_commands:get_command_definition(Name) of command_not_found -> io:format("Error: command ~p not known.~n", [Cmd]); C -> print_usage_command(Cmd, C, MaxC, ShCode) end. print_usage_command(Cmd, C, MaxC, ShCode) -> #ejabberd_commands{ tags = TagsAtoms, desc = Desc, longdesc = LongDesc, args = ArgsDef, result = ResultDef} = C, NameFmt = [" ", ?B("Command Name"), ": ", Cmd, "\n"], %% Initial indentation of result is 13 = length(" Arguments: ") Args = [format_usage_ctype(ArgDef, 13) || ArgDef <- ArgsDef], ArgsMargin = lists:duplicate(13, $\s), ArgsListFmt = case Args of [] -> "\n"; _ -> [ [Arg, "\n", ArgsMargin] || Arg <- Args] end, ArgsFmt = [" ", ?B("Arguments"), ": ", ArgsListFmt], %% Initial indentation of result is 11 = length(" Returns: ") ResultFmt = format_usage_ctype(ResultDef, 11), ReturnsFmt = [" ",?B("Returns"),": ", ResultFmt], XmlrpcFmt = "", %%+++ [" ",?B("XML-RPC"),": ", format_usage_xmlrpc(ArgsDef, ResultDef), "\n\n"], TagsFmt = [" ",?B("Tags"),": ", prepare_long_line(8, MaxC, [atom_to_list(TagA) || TagA <- TagsAtoms])], DescFmt = [" ",?B("Description"),": ", prepare_description(15, MaxC, Desc)], LongDescFmt = case LongDesc of "" -> ""; _ -> ["", prepare_description(0, MaxC, LongDesc), "\n\n"] end, NoteEjabberdctl = case is_supported_args(ArgsDef) of true -> ""; false -> [" ", ?B("Note:"), " This command cannot be executed using ejabberdctl. Try ejabberd_xmlrpc.\n\n"] end, ?PRINT(["\n", NameFmt, "\n", ArgsFmt, "\n", ReturnsFmt, "\n\n", XmlrpcFmt, TagsFmt, "\n\n", DescFmt, "\n\n", LongDescFmt, NoteEjabberdctl], []). format_usage_ctype(Type, _Indentation) when (Type==atom) or (Type==integer) or (Type==string) or (Type==rescode) or (Type==restuple)-> io_lib:format("~p", [Type]); format_usage_ctype({Name, Type}, _Indentation) when (Type==atom) or (Type==integer) or (Type==string) or (Type==rescode) or (Type==restuple)-> io_lib:format("~p::~p", [Name, Type]); format_usage_ctype({Name, {list, ElementDef}}, Indentation) -> NameFmt = atom_to_list(Name), Indentation2 = Indentation + length(NameFmt) + 4, ElementFmt = format_usage_ctype(ElementDef, Indentation2), [NameFmt, "::[ ", ElementFmt, " ]"]; format_usage_ctype({Name, {tuple, ElementsDef}}, Indentation) -> NameFmt = atom_to_list(Name), Indentation2 = Indentation + length(NameFmt) + 4, ElementsFmt = format_usage_tuple(ElementsDef, Indentation2), [NameFmt, "::{ " | ElementsFmt]. format_usage_tuple([], _Indentation) -> []; format_usage_tuple([ElementDef], Indentation) -> [format_usage_ctype(ElementDef, Indentation) , " }"]; format_usage_tuple([ElementDef | ElementsDef], Indentation) -> ElementFmt = format_usage_ctype(ElementDef, Indentation), MarginString = lists:duplicate(Indentation, $\s), % Put spaces [ElementFmt, ",\n", MarginString, format_usage_tuple(ElementsDef, Indentation)]. %%----------------------------- %% Command managment %%----------------------------- %%+++ %% Struct(Integer res) create_account(Struct(String user, String server, String password)) %%format_usage_xmlrpc(ArgsDef, ResultDef) -> %% ["aaaa bbb ccc"]. ejabberd-2.1.11/src/configure.bat0000664000000000000000000000045712240230175013464 0ustar @if "x%1"=="x--help" goto usage @set arg=dynamic @if "x%1"=="x--static" set arg=static @echo Configuring for %arg% build... erlc configure.erl erl -s configure -env arg %arg% -noshell @goto end :usage @echo Usage: configure.bat @echo or configure.bat --static @echo or configure.bat --help :end ejabberd-2.1.11/src/ejabberd_tmp_sup.erl0000664000000000000000000000272012240230175015017 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_tmp_sup.erl %%% Author : Alexey Shchepin %%% Purpose : Supervisor for temporary processess %%% Created : 18 Jul 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_tmp_sup). -author('alexey@process-one.net'). -export([start_link/2, init/1]). start_link(Name, Module) -> supervisor:start_link({local, Name}, ?MODULE, Module). init(Module) -> {ok, {{simple_one_for_one, 10, 1}, [{undefined, {Module, start_link, []}, temporary, brutal_kill, worker, [Module]}]}}. ejabberd-2.1.11/src/mod_disco.erl0000664000000000000000000003702612240230175013461 0ustar %%%---------------------------------------------------------------------- %%% File : mod_disco.erl %%% Author : Alexey Shchepin %%% Purpose : Service Discovery (XEP-0030) support %%% Created : 1 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_disco). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_local_iq_items/3, process_local_iq_info/3, get_local_identity/5, get_local_features/5, get_local_services/5, process_sm_iq_items/3, process_sm_iq_info/3, get_sm_identity/5, get_sm_features/5, get_sm_items/5, get_info/5, register_feature/2, unregister_feature/2, register_extra_domain/2, unregister_extra_domain/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_roster.hrl"). start(Host, Opts) -> ejabberd_local:refresh_iq_handlers(), IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS, ?MODULE, process_local_iq_items, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO, ?MODULE, process_local_iq_info, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS, ?MODULE, process_sm_iq_items, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO, ?MODULE, process_sm_iq_info, IQDisc), catch ets:new(disco_features, [named_table, ordered_set, public]), register_feature(Host, "iq"), register_feature(Host, "presence"), register_feature(Host, "presence-invisible"), catch ets:new(disco_extra_domains, [named_table, ordered_set, public]), ExtraDomains = gen_mod:get_opt(extra_domains, Opts, []), lists:foreach(fun(Domain) -> register_extra_domain(Host, Domain) end, ExtraDomains), catch ets:new(disco_sm_features, [named_table, ordered_set, public]), catch ets:new(disco_sm_nodes, [named_table, ordered_set, public]), ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_services, 100), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 100), ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 100), ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_items, 100), ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 100), ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 100), ejabberd_hooks:add(disco_info, Host, ?MODULE, get_info, 100), ok. stop(Host) -> ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 100), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 100), ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_items, 100), ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 100), ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 100), ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_services, 100), ejabberd_hooks:delete(disco_info, Host, ?MODULE, get_info, 100), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS), gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO), catch ets:match_delete(disco_features, {{'_', Host}}), catch ets:match_delete(disco_extra_domains, {{'_', Host}}), ok. register_feature(Host, Feature) -> catch ets:new(disco_features, [named_table, ordered_set, public]), ets:insert(disco_features, {{Feature, Host}}). unregister_feature(Host, Feature) -> catch ets:new(disco_features, [named_table, ordered_set, public]), ets:delete(disco_features, {Feature, Host}). register_extra_domain(Host, Domain) -> catch ets:new(disco_extra_domains, [named_table, ordered_set, public]), ets:insert(disco_extra_domains, {{Domain, Host}}). unregister_extra_domain(Host, Domain) -> catch ets:new(disco_extra_domains, [named_table, ordered_set, public]), ets:delete(disco_extra_domains, {Domain, Host}). process_local_iq_items(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> Node = xml:get_tag_attr_s("node", SubEl), Host = To#jid.lserver, case ejabberd_hooks:run_fold(disco_local_items, Host, empty, [From, To, Node, Lang]) of {result, Items} -> ANode = case Node of "" -> []; _ -> [{"node", Node}] end, IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS} | ANode], Items }]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end end. process_local_iq_info(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> Host = To#jid.lserver, Node = xml:get_tag_attr_s("node", SubEl), Identity = ejabberd_hooks:run_fold(disco_local_identity, Host, [], [From, To, Node, Lang]), Info = ejabberd_hooks:run_fold(disco_info, Host, [], [Host, ?MODULE, Node, Lang]), case ejabberd_hooks:run_fold(disco_local_features, Host, empty, [From, To, Node, Lang]) of {result, Features} -> ANode = case Node of "" -> []; _ -> [{"node", Node}] end, IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_INFO} | ANode], Identity ++ Info ++ features_to_xml(Features) }]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end end. get_local_identity(Acc, _From, _To, [], _Lang) -> Acc ++ [{xmlelement, "identity", [{"category", "server"}, {"type", "im"}, {"name", "ejabberd"}], []}]; get_local_identity(Acc, _From, _To, _Node, _Lang) -> Acc. get_local_features({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; get_local_features(Acc, _From, To, [], _Lang) -> Feats = case Acc of {result, Features} -> Features; empty -> [] end, Host = To#jid.lserver, {result, ets:select(disco_features, [{{{'_', Host}}, [], ['$_']}]) ++ Feats}; get_local_features(Acc, _From, _To, _Node, _Lang) -> case Acc of {result, _Features} -> Acc; empty -> {error, ?ERR_ITEM_NOT_FOUND} end. features_to_xml(FeatureList) -> %% Avoid duplicating features [{xmlelement, "feature", [{"var", Feat}], []} || Feat <- lists:usort( lists:map( fun({{Feature, _Host}}) -> Feature; (Feature) when is_list(Feature) -> Feature end, FeatureList))]. domain_to_xml({Domain}) -> {xmlelement, "item", [{"jid", Domain}], []}; domain_to_xml(Domain) -> {xmlelement, "item", [{"jid", Domain}], []}. get_local_services({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; get_local_services(Acc, _From, To, [], _Lang) -> Items = case Acc of {result, Its} -> Its; empty -> [] end, Host = To#jid.lserver, {result, lists:usort( lists:map(fun domain_to_xml/1, get_vh_services(Host) ++ ets:select(disco_extra_domains, [{{{'$1', Host}}, [], ['$1']}])) ) ++ Items}; get_local_services({result, _} = Acc, _From, _To, _Node, _Lang) -> Acc; get_local_services(empty, _From, _To, _Node, _Lang) -> {error, ?ERR_ITEM_NOT_FOUND}. get_vh_services(Host) -> Hosts = lists:sort(fun(H1, H2) -> length(H1) >= length(H2) end, ?MYHOSTS), lists:filter(fun(H) -> case lists:dropwhile( fun(VH) -> not lists:suffix("." ++ VH, H) end, Hosts) of [] -> false; [VH | _] -> VH == Host end end, ejabberd_router:dirty_get_all_routes()). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% process_sm_iq_items(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> case is_presence_subscribed(From, To) of true -> Host = To#jid.lserver, Node = xml:get_tag_attr_s("node", SubEl), case ejabberd_hooks:run_fold(disco_sm_items, Host, empty, [From, To, Node, Lang]) of {result, Items} -> ANode = case Node of "" -> []; _ -> [{"node", Node}] end, IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS} | ANode], Items }]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end; false -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]} end end. get_sm_items({error, _Error} = Acc, _From, _To, _Node, _Lang) -> Acc; get_sm_items(Acc, From, #jid{user = User, server = Server} = To, [], _Lang) -> Items = case Acc of {result, Its} -> Its; empty -> [] end, Items1 = case is_presence_subscribed(From, To) of true -> get_user_resources(User, Server); _ -> [] end, {result, Items ++ Items1}; get_sm_items({result, _} = Acc, _From, _To, _Node, _Lang) -> Acc; get_sm_items(empty, From, To, _Node, _Lang) -> #jid{luser = LFrom, lserver = LSFrom} = From, #jid{luser = LTo, lserver = LSTo} = To, case {LFrom, LSFrom} of {LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND}; _ -> {error, ?ERR_NOT_ALLOWED} end. is_presence_subscribed(#jid{luser=User, lserver=Server}, #jid{luser=LUser, lserver=LServer}) -> lists:any(fun(#roster{jid = {TUser, TServer, _}, subscription = S}) -> if LUser == TUser, LServer == TServer, S/=none -> true; true -> false end end, ejabberd_hooks:run_fold(roster_get, Server, [], [{User, Server}])) orelse User == LUser andalso Server == LServer. process_sm_iq_info(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> case Type of set -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; get -> case is_presence_subscribed(From, To) of true -> Host = To#jid.lserver, Node = xml:get_tag_attr_s("node", SubEl), Identity = ejabberd_hooks:run_fold(disco_sm_identity, Host, [], [From, To, Node, Lang]), case ejabberd_hooks:run_fold(disco_sm_features, Host, empty, [From, To, Node, Lang]) of {result, Features} -> ANode = case Node of "" -> []; _ -> [{"node", Node}] end, IQ#iq{type = result, sub_el = [{xmlelement, "query", [{"xmlns", ?NS_DISCO_INFO} | ANode], Identity ++ features_to_xml(Features) }]}; {error, Error} -> IQ#iq{type = error, sub_el = [SubEl, Error]} end; false -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]} end end. get_sm_identity(Acc, _From, #jid{luser = LUser, lserver=LServer}, _Node, _Lang) -> Acc ++ case ejabberd_auth:is_user_exists(LUser, LServer) of true -> [{xmlelement, "identity", [{"category", "account"}, {"type", "registered"}], []}]; _ -> [] end. get_sm_features(empty, From, To, _Node, _Lang) -> #jid{luser = LFrom, lserver = LSFrom} = From, #jid{luser = LTo, lserver = LSTo} = To, case {LFrom, LSFrom} of {LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND}; _ -> {error, ?ERR_NOT_ALLOWED} end; get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. get_user_resources(User, Server) -> Rs = ejabberd_sm:get_user_resources(User, Server), lists:map(fun(R) -> {xmlelement, "item", [{"jid", User ++ "@" ++ Server ++ "/" ++ R}, {"name", User}], []} end, lists:sort(Rs)). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Support for: XEP-0157 Contact Addresses for XMPP Services get_info(_A, Host, Mod, Node, _Lang) when Node == [] -> Module = case Mod of undefined -> ?MODULE; _ -> Mod end, Serverinfo_fields = get_fields_xml(Host, Module), [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}], [{xmlelement, "field", [{"var", "FORM_TYPE"}, {"type", "hidden"}], [{xmlelement, "value", [], [{xmlcdata, ?NS_SERVERINFO}] }] }] ++ Serverinfo_fields }]; get_info(Acc, _, _, _Node, _) -> Acc. get_fields_xml(Host, Module) -> Fields = gen_mod:get_module_opt(Host, ?MODULE, server_info, []), %% filter, and get only the ones allowed for this module Fields_good = lists:filter( fun({Modules, _, _}) -> case Modules of all -> true; Modules -> lists:member(Module, Modules) end end, Fields), fields_to_xml(Fields_good). fields_to_xml(Fields) -> [ field_to_xml(Field) || Field <- Fields]. field_to_xml({_, Var, Values}) -> Values_xml = values_to_xml(Values), {xmlelement, "field", [{"var", Var}], Values_xml }. values_to_xml(Values) -> lists:map( fun(Value) -> {xmlelement, "value", [], [{xmlcdata, Value}] } end, Values ). ejabberd-2.1.11/src/ejabberd_node_groups.erl0000664000000000000000000001324312240230175015656 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_node_groups.erl %%% Author : Alexey Shchepin %%% Purpose : Distributed named node groups based on pg2 module %%% Created : 1 Nov 2006 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_node_groups). -author('alexey@process-one.net'). -behaviour(gen_server). %% API -export([start_link/0, join/1, leave/1, get_members/1, get_closest_node/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -ifdef(SSL40). -define(PG2, pg2). -else. -define(PG2, pg2_backport). -endif. -record(state, {}). %%==================================================================== %% API %%==================================================================== %%-------------------------------------------------------------------- %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} %% Description: Starts the server %%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). join(Name) -> PG = {?MODULE, Name}, ?PG2:create(PG), ?PG2:join(PG, whereis(?MODULE)). leave(Name) -> PG = {?MODULE, Name}, ?PG2:leave(PG, whereis(?MODULE)). get_members(Name) -> PG = {?MODULE, Name}, [node(P) || P <- ?PG2:get_members(PG)]. get_closest_node(Name) -> PG = {?MODULE, Name}, node(?PG2:get_closest_pid(PG)). %%==================================================================== %% gen_server callbacks %%==================================================================== %%-------------------------------------------------------------------- %% Function: init(Args) -> {ok, State} | %% {ok, State, Timeout} | %% ignore | %% {stop, Reason} %% Description: Initiates the server %%-------------------------------------------------------------------- init([]) -> {FE, BE} = case ejabberd_config:get_local_option(node_type) of frontend -> {true, false}; backend -> {false, true}; generic -> {true, true}; undefined -> {true, true} end, if FE -> join(frontend); true -> ok end, if BE -> join(backend); true -> ok end, {ok, #state{}}. %%-------------------------------------------------------------------- %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | %% {reply, Reply, State, Timeout} | %% {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, Reply, State} | %% {stop, Reason, State} %% Description: Handling call messages %%-------------------------------------------------------------------- handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. %%-------------------------------------------------------------------- %% Function: handle_cast(Msg, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: handle_info(Info, State) -> {noreply, State} | %% {noreply, State, Timeout} | %% {stop, Reason, State} %% Description: Handling all non call/cast messages %%-------------------------------------------------------------------- handle_info(_Info, State) -> {noreply, State}. %%-------------------------------------------------------------------- %% Function: terminate(Reason, State) -> void() %% Description: This function is called by a gen_server when it is about to %% terminate. It should be the opposite of Module:init/1 and do any necessary %% cleaning up. When it returns, the gen_server terminates with Reason. %% The return value is ignored. %%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. %%-------------------------------------------------------------------- %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} %% Description: Convert process state when code is changed %%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- ejabberd-2.1.11/src/mod_roster.erl0000664000000000000000000010361012240230175013667 0ustar %%%---------------------------------------------------------------------- %%% File : mod_roster.erl %%% Author : Alexey Shchepin %%% Purpose : Roster management %%% Created : 11 Dec 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- %%% @doc Roster management (Mnesia storage). %%% %%% Includes support for XEP-0237: Roster Versioning. %%% The roster versioning follows an all-or-nothing strategy: %%% - If the version supplied by the client is the latest, return an empty response. %%% - If not, return the entire new roster (with updated version string). %%% Roster version is a hash digest of the entire roster. %%% No additional data is stored in DB. -module(mod_roster). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([start/2, stop/1, process_iq/3, process_local_iq/3, get_user_roster/2, get_subscription_lists/3, get_in_pending_subscriptions/3, in_subscription/6, out_subscription/4, set_items/3, remove_user/2, get_jid_info/4, item_to_xml/1, webadmin_page/3, webadmin_user/4, get_versioning_feature/2, roster_versioning_enabled/1, roster_version/2]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("mod_roster.hrl"). -include("web/ejabberd_http.hrl"). -include("web/ejabberd_web_admin.hrl"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), mnesia:create_table(roster,[{disc_copies, [node()]}, {attributes, record_info(fields, roster)}]), mnesia:create_table(roster_version, [{disc_copies, [node()]}, {attributes, record_info(fields, roster_version)}]), update_table(), mnesia:add_table_index(roster, us), mnesia:add_table_index(roster_version, us), ejabberd_hooks:add(roster_get, Host, ?MODULE, get_user_roster, 50), ejabberd_hooks:add(roster_in_subscription, Host, ?MODULE, in_subscription, 50), ejabberd_hooks:add(roster_out_subscription, Host, ?MODULE, out_subscription, 50), ejabberd_hooks:add(roster_get_subscription_lists, Host, ?MODULE, get_subscription_lists, 50), ejabberd_hooks:add(roster_get_jid_info, Host, ?MODULE, get_jid_info, 50), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:add(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), ejabberd_hooks:add(resend_subscription_requests_hook, Host, ?MODULE, get_in_pending_subscriptions, 50), ejabberd_hooks:add(roster_get_versioning_feature, Host, ?MODULE, get_versioning_feature, 50), ejabberd_hooks:add(webadmin_page_host, Host, ?MODULE, webadmin_page, 50), ejabberd_hooks:add(webadmin_user, Host, ?MODULE, webadmin_user, 50), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER, ?MODULE, process_iq, IQDisc). stop(Host) -> ejabberd_hooks:delete(roster_get, Host, ?MODULE, get_user_roster, 50), ejabberd_hooks:delete(roster_in_subscription, Host, ?MODULE, in_subscription, 50), ejabberd_hooks:delete(roster_out_subscription, Host, ?MODULE, out_subscription, 50), ejabberd_hooks:delete(roster_get_subscription_lists, Host, ?MODULE, get_subscription_lists, 50), ejabberd_hooks:delete(roster_get_jid_info, Host, ?MODULE, get_jid_info, 50), ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(resend_subscription_requests_hook, Host, ?MODULE, get_in_pending_subscriptions, 50), ejabberd_hooks:delete(roster_get_versioning_feature, Host, ?MODULE, get_versioning_feature, 50), ejabberd_hooks:delete(webadmin_page_host, Host, ?MODULE, webadmin_page, 50), ejabberd_hooks:delete(webadmin_user, Host, ?MODULE, webadmin_user, 50), gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER). process_iq(From, To, IQ) -> #iq{sub_el = SubEl} = IQ, #jid{lserver = LServer} = From, case lists:member(LServer, ?MYHOSTS) of true -> process_local_iq(From, To, IQ); _ -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]} end. process_local_iq(From, To, #iq{type = Type} = IQ) -> case Type of set -> process_iq_set(From, To, IQ); get -> process_iq_get(From, To, IQ) end. roster_hash(Items) -> sha:sha(term_to_binary( lists:sort( [R#roster{groups = lists:sort(Grs)} || R = #roster{groups = Grs} <- Items]))). roster_versioning_enabled(Host) -> gen_mod:get_module_opt(Host, ?MODULE, versioning, false). roster_version_on_db(Host) -> gen_mod:get_module_opt(Host, ?MODULE, store_current_id, false). %% Returns a list that may contain an xmlelement with the XEP-237 feature if it's enabled. get_versioning_feature(Acc, Host) -> case roster_versioning_enabled(Host) of true -> Feature = {xmlelement, "ver", [{"xmlns", ?NS_ROSTER_VER}], []}, [Feature | Acc]; false -> [] end. roster_version(LServer ,LUser) -> US = {LUser, LServer}, case roster_version_on_db(LServer) of true -> case mnesia:dirty_read(roster_version, US) of [#roster_version{version = V}] -> V; [] -> not_found end; false -> roster_hash(ejabberd_hooks:run_fold(roster_get, LServer, [], [US])) end. %% Load roster from DB only if neccesary. %% It is neccesary if %% - roster versioning is disabled in server OR %% - roster versioning is not used by the client OR %% - roster versioning is used by server and client, BUT the server isn't storing versions on db OR %% - the roster version from client don't match current version. process_iq_get(From, To, #iq{sub_el = SubEl} = IQ) -> LUser = From#jid.luser, LServer = From#jid.lserver, US = {LUser, LServer}, try {ItemsToSend, VersionToSend} = case {xml:get_tag_attr("ver", SubEl), roster_versioning_enabled(LServer), roster_version_on_db(LServer)} of {{value, RequestedVersion}, true, true} -> %% Retrieve version from DB. Only load entire roster %% when neccesary. case mnesia:dirty_read(roster_version, US) of [#roster_version{version = RequestedVersion}] -> {false, false}; [#roster_version{version = NewVersion}] -> {lists:map(fun item_to_xml/1, ejabberd_hooks:run_fold(roster_get, To#jid.lserver, [], [US])), NewVersion}; [] -> RosterVersion = sha:sha(term_to_binary(now())), mnesia:dirty_write(#roster_version{us = US, version = RosterVersion}), {lists:map(fun item_to_xml/1, ejabberd_hooks:run_fold(roster_get, To#jid.lserver, [], [US])), RosterVersion} end; {{value, RequestedVersion}, true, false} -> RosterItems = ejabberd_hooks:run_fold(roster_get, To#jid.lserver, [] , [US]), case roster_hash(RosterItems) of RequestedVersion -> {false, false}; New -> {lists:map(fun item_to_xml/1, RosterItems), New} end; _ -> {lists:map(fun item_to_xml/1, ejabberd_hooks:run_fold(roster_get, To#jid.lserver, [], [US])), false} end, IQ#iq{type = result, sub_el = case {ItemsToSend, VersionToSend} of {false, false} -> []; {Items, false} -> [{xmlelement, "query", [{"xmlns", ?NS_ROSTER}], Items}]; {Items, Version} -> [{xmlelement, "query", [{"xmlns", ?NS_ROSTER}, {"ver", Version}], Items}] end} catch _:_ -> IQ#iq{type =error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} end. get_user_roster(Acc, US) -> case catch mnesia:dirty_index_read(roster, US, #roster.us) of Items when is_list(Items) -> lists:filter(fun(#roster{subscription = none, ask = in}) -> false; (_) -> true end, Items) ++ Acc; _ -> Acc end. item_to_xml(Item) -> Attrs1 = [{"jid", jlib:jid_to_string(Item#roster.jid)}], Attrs2 = case Item#roster.name of "" -> Attrs1; Name -> [{"name", Name} | Attrs1] end, Attrs3 = case Item#roster.subscription of none -> [{"subscription", "none"} | Attrs2]; from -> [{"subscription", "from"} | Attrs2]; to -> [{"subscription", "to"} | Attrs2]; both -> [{"subscription", "both"} | Attrs2]; remove -> [{"subscription", "remove"} | Attrs2] end, Attrs4 = case ask_to_pending(Item#roster.ask) of out -> [{"ask", "subscribe"} | Attrs3]; both -> [{"ask", "subscribe"} | Attrs3]; _ -> Attrs3 end, SubEls1 = lists:map(fun(G) -> {xmlelement, "group", [], [{xmlcdata, G}]} end, Item#roster.groups), SubEls = SubEls1 ++ Item#roster.xs, {xmlelement, "item", Attrs4, SubEls}. process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) -> {xmlelement, _Name, _Attrs, Els} = SubEl, lists:foreach(fun(El) -> process_item_set(From, To, El) end, Els), IQ#iq{type = result, sub_el = []}. process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) -> JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)), #jid{user = User, luser = LUser, lserver = LServer} = From, case JID1 of error -> ok; _ -> JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource}, LJID = jlib:jid_tolower(JID1), F = fun() -> Res = mnesia:read({roster, {LUser, LServer, LJID}}), Item = case Res of [] -> #roster{usj = {LUser, LServer, LJID}, us = {LUser, LServer}, jid = JID}; [I] -> I#roster{jid = JID, name = "", groups = [], xs = []} end, Item1 = process_item_attrs(Item, Attrs), Item2 = process_item_els(Item1, Els), case Item2#roster.subscription of remove -> mnesia:delete({roster, {LUser, LServer, LJID}}); _ -> mnesia:write(Item2) end, %% If the item exist in shared roster, take the %% subscription information from there: Item3 = ejabberd_hooks:run_fold(roster_process_item, LServer, Item2, [LServer]), case roster_version_on_db(LServer) of true -> mnesia:write(#roster_version{us = {LUser, LServer}, version = sha:sha(term_to_binary(now()))}); false -> ok end, {Item, Item3} end, case mnesia:transaction(F) of {atomic, {OldItem, Item}} -> push_item(User, LServer, To, Item), case Item#roster.subscription of remove -> send_unsubscribing_presence(From, OldItem), ok; _ -> ok end; E -> ?DEBUG("ROSTER: roster item set error: ~p~n", [E]), ok end end; process_item_set(_From, _To, _) -> ok. process_item_attrs(Item, [{Attr, Val} | Attrs]) -> case Attr of "jid" -> case jlib:string_to_jid(Val) of error -> process_item_attrs(Item, Attrs); JID1 -> JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource}, process_item_attrs(Item#roster{jid = JID}, Attrs) end; "name" -> process_item_attrs(Item#roster{name = Val}, Attrs); "subscription" -> case Val of "remove" -> process_item_attrs(Item#roster{subscription = remove}, Attrs); _ -> process_item_attrs(Item, Attrs) end; "ask" -> process_item_attrs(Item, Attrs); _ -> process_item_attrs(Item, Attrs) end; process_item_attrs(Item, []) -> Item. process_item_els(Item, [{xmlelement, Name, Attrs, SEls} | Els]) -> case Name of "group" -> Groups = [xml:get_cdata(SEls) | Item#roster.groups], process_item_els(Item#roster{groups = Groups}, Els); _ -> case xml:get_attr_s("xmlns", Attrs) of "" -> process_item_els(Item, Els); _ -> XEls = [{xmlelement, Name, Attrs, SEls} | Item#roster.xs], process_item_els(Item#roster{xs = XEls}, Els) end end; process_item_els(Item, [{xmlcdata, _} | Els]) -> process_item_els(Item, Els); process_item_els(Item, []) -> Item. push_item(User, Server, From, Item) -> ejabberd_sm:route(jlib:make_jid("", "", ""), jlib:make_jid(User, Server, ""), {xmlelement, "broadcast", [], [{item, Item#roster.jid, Item#roster.subscription}]}), case roster_versioning_enabled(Server) of true -> push_item_version(Server, User, From, Item, roster_version(Server, User)); false -> lists:foreach(fun(Resource) -> push_item(User, Server, Resource, From, Item) end, ejabberd_sm:get_user_resources(User, Server)) end. % TODO: don't push to those who didn't load roster push_item(User, Server, Resource, From, Item) -> push_item(User, Server, Resource, From, Item, not_found). push_item(User, Server, Resource, From, Item, RosterVersion) -> ExtraAttrs = case RosterVersion of not_found -> []; _ -> [{"ver", RosterVersion}] end, ResIQ = #iq{type = set, xmlns = ?NS_ROSTER, id = "push" ++ randoms:get_string(), sub_el = [{xmlelement, "query", [{"xmlns", ?NS_ROSTER}|ExtraAttrs], [item_to_xml(Item)]}]}, ejabberd_router:route( From, jlib:make_jid(User, Server, Resource), jlib:iq_to_xml(ResIQ)). %% @doc Roster push, calculate and include the version attribute. %% TODO: don't push to those who didn't load roster push_item_version(Server, User, From, Item, RosterVersion) -> lists:foreach(fun(Resource) -> push_item(User, Server, Resource, From, Item, RosterVersion) end, ejabberd_sm:get_user_resources(User, Server)). get_subscription_lists(_, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, case mnesia:dirty_index_read(roster, US, #roster.us) of Items when is_list(Items) -> fill_subscription_lists(Items, [], []); _ -> {[], []} end. fill_subscription_lists([I | Is], F, T) -> J = element(3, I#roster.usj), case I#roster.subscription of both -> fill_subscription_lists(Is, [J | F], [J | T]); from -> fill_subscription_lists(Is, [J | F], T); to -> fill_subscription_lists(Is, F, [J | T]); _ -> fill_subscription_lists(Is, F, T) end; fill_subscription_lists([], F, T) -> {F, T}. ask_to_pending(subscribe) -> out; ask_to_pending(unsubscribe) -> none; ask_to_pending(Ask) -> Ask. in_subscription(_, User, Server, JID, Type, Reason) -> process_subscription(in, User, Server, JID, Type, Reason). out_subscription(User, Server, JID, Type) -> process_subscription(out, User, Server, JID, Type, []). process_subscription(Direction, User, Server, JID1, Type, Reason) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, LJID = jlib:jid_tolower(JID1), F = fun() -> Item = case mnesia:read({roster, {LUser, LServer, LJID}}) of [] -> JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource}, #roster{usj = {LUser, LServer, LJID}, us = US, jid = JID}; [I] -> I end, NewState = case Direction of out -> out_state_change(Item#roster.subscription, Item#roster.ask, Type); in -> in_state_change(Item#roster.subscription, Item#roster.ask, Type) end, AutoReply = case Direction of out -> none; in -> in_auto_reply(Item#roster.subscription, Item#roster.ask, Type) end, AskMessage = case NewState of {_, both} -> Reason; {_, in} -> Reason; _ -> "" end, case NewState of none -> {none, AutoReply}; {none, none} when Item#roster.subscription == none, Item#roster.ask == in -> mnesia:delete({roster, {LUser, LServer, LJID}}), {none, AutoReply}; {Subscription, Pending} -> NewItem = Item#roster{subscription = Subscription, ask = Pending, askmessage = list_to_binary(AskMessage)}, mnesia:write(NewItem), case roster_version_on_db(LServer) of true -> mnesia:write(#roster_version{us = {LUser, LServer}, version = sha:sha(term_to_binary(now()))}); false -> ok end, {{push, NewItem}, AutoReply} end end, case mnesia:transaction(F) of {atomic, {Push, AutoReply}} -> case AutoReply of none -> ok; _ -> T = case AutoReply of subscribed -> "subscribed"; unsubscribed -> "unsubscribed" end, ejabberd_router:route( jlib:make_jid(User, Server, ""), JID1, {xmlelement, "presence", [{"type", T}], []}) end, case Push of {push, Item} -> if Item#roster.subscription == none, Item#roster.ask == in -> ok; true -> push_item(User, Server, jlib:make_jid(User, Server, ""), Item) end, true; none -> false end; _ -> false end. %% in_state_change(Subscription, Pending, Type) -> NewState %% NewState = none | {NewSubscription, NewPending} -ifdef(ROSTER_GATEWAY_WORKAROUND). -define(NNSD, {to, none}). -define(NISD, {to, in}). -else. -define(NNSD, none). -define(NISD, none). -endif. in_state_change(none, none, subscribe) -> {none, in}; in_state_change(none, none, subscribed) -> ?NNSD; in_state_change(none, none, unsubscribe) -> none; in_state_change(none, none, unsubscribed) -> none; in_state_change(none, out, subscribe) -> {none, both}; in_state_change(none, out, subscribed) -> {to, none}; in_state_change(none, out, unsubscribe) -> none; in_state_change(none, out, unsubscribed) -> {none, none}; in_state_change(none, in, subscribe) -> none; in_state_change(none, in, subscribed) -> ?NISD; in_state_change(none, in, unsubscribe) -> {none, none}; in_state_change(none, in, unsubscribed) -> none; in_state_change(none, both, subscribe) -> none; in_state_change(none, both, subscribed) -> {to, in}; in_state_change(none, both, unsubscribe) -> {none, out}; in_state_change(none, both, unsubscribed) -> {none, in}; in_state_change(to, none, subscribe) -> {to, in}; in_state_change(to, none, subscribed) -> none; in_state_change(to, none, unsubscribe) -> none; in_state_change(to, none, unsubscribed) -> {none, none}; in_state_change(to, in, subscribe) -> none; in_state_change(to, in, subscribed) -> none; in_state_change(to, in, unsubscribe) -> {to, none}; in_state_change(to, in, unsubscribed) -> {none, in}; in_state_change(from, none, subscribe) -> none; in_state_change(from, none, subscribed) -> {both, none}; in_state_change(from, none, unsubscribe) -> {none, none}; in_state_change(from, none, unsubscribed) -> none; in_state_change(from, out, subscribe) -> none; in_state_change(from, out, subscribed) -> {both, none}; in_state_change(from, out, unsubscribe) -> {none, out}; in_state_change(from, out, unsubscribed) -> {from, none}; in_state_change(both, none, subscribe) -> none; in_state_change(both, none, subscribed) -> none; in_state_change(both, none, unsubscribe) -> {to, none}; in_state_change(both, none, unsubscribed) -> {from, none}. out_state_change(none, none, subscribe) -> {none, out}; out_state_change(none, none, subscribed) -> none; out_state_change(none, none, unsubscribe) -> none; out_state_change(none, none, unsubscribed) -> none; out_state_change(none, out, subscribe) -> {none, out}; %% We need to resend query (RFC3921, section 9.2) out_state_change(none, out, subscribed) -> none; out_state_change(none, out, unsubscribe) -> {none, none}; out_state_change(none, out, unsubscribed) -> none; out_state_change(none, in, subscribe) -> {none, both}; out_state_change(none, in, subscribed) -> {from, none}; out_state_change(none, in, unsubscribe) -> none; out_state_change(none, in, unsubscribed) -> {none, none}; out_state_change(none, both, subscribe) -> none; out_state_change(none, both, subscribed) -> {from, out}; out_state_change(none, both, unsubscribe) -> {none, in}; out_state_change(none, both, unsubscribed) -> {none, out}; out_state_change(to, none, subscribe) -> none; out_state_change(to, none, subscribed) -> {both, none}; out_state_change(to, none, unsubscribe) -> {none, none}; out_state_change(to, none, unsubscribed) -> none; out_state_change(to, in, subscribe) -> none; out_state_change(to, in, subscribed) -> {both, none}; out_state_change(to, in, unsubscribe) -> {none, in}; out_state_change(to, in, unsubscribed) -> {to, none}; out_state_change(from, none, subscribe) -> {from, out}; out_state_change(from, none, subscribed) -> none; out_state_change(from, none, unsubscribe) -> none; out_state_change(from, none, unsubscribed) -> {none, none}; out_state_change(from, out, subscribe) -> none; out_state_change(from, out, subscribed) -> none; out_state_change(from, out, unsubscribe) -> {from, none}; out_state_change(from, out, unsubscribed) -> {none, out}; out_state_change(both, none, subscribe) -> none; out_state_change(both, none, subscribed) -> none; out_state_change(both, none, unsubscribe) -> {from, none}; out_state_change(both, none, unsubscribed) -> {to, none}. in_auto_reply(from, none, subscribe) -> subscribed; in_auto_reply(from, out, subscribe) -> subscribed; in_auto_reply(both, none, subscribe) -> subscribed; in_auto_reply(none, in, unsubscribe) -> unsubscribed; in_auto_reply(none, both, unsubscribe) -> unsubscribed; in_auto_reply(to, in, unsubscribe) -> unsubscribed; in_auto_reply(from, none, unsubscribe) -> unsubscribed; in_auto_reply(from, out, unsubscribe) -> unsubscribed; in_auto_reply(both, none, unsubscribe) -> unsubscribed; in_auto_reply(_, _, _) -> none. remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), US = {LUser, LServer}, send_unsubscription_to_rosteritems(LUser, LServer), F = fun() -> lists:foreach(fun(R) -> mnesia:delete_object(R) end, mnesia:index_read(roster, US, #roster.us)) end, mnesia:transaction(F). %% For each contact with Subscription: %% Both or From, send a "unsubscribed" presence stanza; %% Both or To, send a "unsubscribe" presence stanza. send_unsubscription_to_rosteritems(LUser, LServer) -> RosterItems = get_user_roster([], {LUser, LServer}), From = jlib:make_jid({LUser, LServer, ""}), lists:foreach(fun(RosterItem) -> send_unsubscribing_presence(From, RosterItem) end, RosterItems). %% @spec (From::jid(), Item::roster()) -> ok send_unsubscribing_presence(From, Item) -> IsTo = case Item#roster.subscription of both -> true; to -> true; _ -> false end, IsFrom = case Item#roster.subscription of both -> true; from -> true; _ -> false end, if IsTo -> send_presence_type( jlib:jid_remove_resource(From), jlib:make_jid(Item#roster.jid), "unsubscribe"); true -> ok end, if IsFrom -> send_presence_type( jlib:jid_remove_resource(From), jlib:make_jid(Item#roster.jid), "unsubscribed"); true -> ok end, ok. send_presence_type(From, To, Type) -> ejabberd_router:route( From, To, {xmlelement, "presence", [{"type", Type}], []}). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% set_items(User, Server, SubEl) -> {xmlelement, _Name, _Attrs, Els} = SubEl, LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), F = fun() -> lists:foreach(fun(El) -> process_item_set_t(LUser, LServer, El) end, Els) end, mnesia:transaction(F). process_item_set_t(LUser, LServer, {xmlelement, _Name, Attrs, Els}) -> JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)), case JID1 of error -> ok; _ -> JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource}, LJID = {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource}, Item = #roster{usj = {LUser, LServer, LJID}, us = {LUser, LServer}, jid = JID}, Item1 = process_item_attrs_ws(Item, Attrs), Item2 = process_item_els(Item1, Els), case Item2#roster.subscription of remove -> mnesia:delete({roster, {LUser, LServer, LJID}}); _ -> mnesia:write(Item2) end end; process_item_set_t(_LUser, _LServer, _) -> ok. process_item_attrs_ws(Item, [{Attr, Val} | Attrs]) -> case Attr of "jid" -> case jlib:string_to_jid(Val) of error -> process_item_attrs_ws(Item, Attrs); JID1 -> JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource}, process_item_attrs_ws(Item#roster{jid = JID}, Attrs) end; "name" -> process_item_attrs_ws(Item#roster{name = Val}, Attrs); "subscription" -> case Val of "remove" -> process_item_attrs_ws(Item#roster{subscription = remove}, Attrs); "none" -> process_item_attrs_ws(Item#roster{subscription = none}, Attrs); "both" -> process_item_attrs_ws(Item#roster{subscription = both}, Attrs); "from" -> process_item_attrs_ws(Item#roster{subscription = from}, Attrs); "to" -> process_item_attrs_ws(Item#roster{subscription = to}, Attrs); _ -> process_item_attrs_ws(Item, Attrs) end; "ask" -> process_item_attrs_ws(Item, Attrs); _ -> process_item_attrs_ws(Item, Attrs) end; process_item_attrs_ws(Item, []) -> Item. get_in_pending_subscriptions(Ls, User, Server) -> JID = jlib:make_jid(User, Server, ""), US = {JID#jid.luser, JID#jid.lserver}, case mnesia:dirty_index_read(roster, US, #roster.us) of Result when is_list(Result) -> Ls ++ lists:map( fun(R) -> Message = R#roster.askmessage, Status = if is_binary(Message) -> binary_to_list(Message); true -> "" end, {xmlelement, "presence", [{"from", jlib:jid_to_string(R#roster.jid)}, {"to", jlib:jid_to_string(JID)}, {"type", "subscribe"}], [{xmlelement, "status", [], [{xmlcdata, Status}]}]} end, lists:filter( fun(R) -> case R#roster.ask of in -> true; both -> true; _ -> false end end, Result)); _ -> Ls end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% get_jid_info(_, User, Server, JID) -> LUser = jlib:nodeprep(User), LJID = jlib:jid_tolower(JID), LServer = jlib:nameprep(Server), case catch mnesia:dirty_read(roster, {LUser, LServer, LJID}) of [#roster{subscription = Subscription, groups = Groups}] -> {Subscription, Groups}; _ -> LRJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)), if LRJID == LJID -> {none, []}; true -> case catch mnesia:dirty_read( roster, {LUser, LServer, LRJID}) of [#roster{subscription = Subscription, groups = Groups}] -> {Subscription, Groups}; _ -> {none, []} end end end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% update_table() -> Fields = record_info(fields, roster), case mnesia:table_info(roster, attributes) of Fields -> ok; [uj, user, jid, name, subscription, ask, groups, xattrs, xs] -> convert_table1(Fields); [usj, us, jid, name, subscription, ask, groups, xattrs, xs] -> convert_table2(Fields); _ -> ?INFO_MSG("Recreating roster table", []), mnesia:transform_table(roster, ignore, Fields) end. %% Convert roster table to support virtual host convert_table1(Fields) -> ?INFO_MSG("Virtual host support: converting roster table from " "{uj, user, jid, name, subscription, ask, groups, xattrs, xs} format", []), Host = ?MYNAME, {atomic, ok} = mnesia:create_table( mod_roster_tmp_table, [{disc_only_copies, [node()]}, {type, bag}, {local_content, true}, {record_name, roster}, {attributes, record_info(fields, roster)}]), mnesia:del_table_index(roster, user), mnesia:transform_table(roster, ignore, Fields), F1 = fun() -> mnesia:write_lock_table(mod_roster_tmp_table), mnesia:foldl( fun(#roster{usj = {U, JID}, us = U} = R, _) -> mnesia:dirty_write( mod_roster_tmp_table, R#roster{usj = {U, Host, JID}, us = {U, Host}}) end, ok, roster) end, mnesia:transaction(F1), mnesia:clear_table(roster), F2 = fun() -> mnesia:write_lock_table(roster), mnesia:foldl( fun(R, _) -> mnesia:dirty_write(R) end, ok, mod_roster_tmp_table) end, mnesia:transaction(F2), mnesia:delete_table(mod_roster_tmp_table). %% Convert roster table: xattrs fields become convert_table2(Fields) -> ?INFO_MSG("Converting roster table from " "{usj, us, jid, name, subscription, ask, groups, xattrs, xs} format", []), mnesia:transform_table(roster, ignore, Fields). webadmin_page(_, Host, #request{us = _US, path = ["user", U, "roster"], q = Query, lang = Lang} = _Request) -> Res = user_roster(U, Host, Query, Lang), {stop, Res}; webadmin_page(Acc, _, _) -> Acc. user_roster(User, Server, Query, Lang) -> US = {jlib:nodeprep(User), jlib:nameprep(Server)}, Items1 = mnesia:dirty_index_read(roster, US, #roster.us), Res = user_roster_parse_query(User, Server, Items1, Query), Items = mnesia:dirty_index_read(roster, US, #roster.us), SItems = lists:sort(Items), FItems = case SItems of [] -> [?CT("None")]; _ -> [?XE("table", [?XE("thead", [?XE("tr", [?XCT("td", "Jabber ID"), ?XCT("td", "Nickname"), ?XCT("td", "Subscription"), ?XCT("td", "Pending"), ?XCT("td", "Groups") ])]), ?XE("tbody", lists:map( fun(R) -> Groups = lists:flatmap( fun(Group) -> [?C(Group), ?BR] end, R#roster.groups), Pending = ask_to_pending(R#roster.ask), TDJID = build_contact_jid_td(R#roster.jid), ?XE("tr", [TDJID, ?XAC("td", [{"class", "valign"}], R#roster.name), ?XAC("td", [{"class", "valign"}], atom_to_list(R#roster.subscription)), ?XAC("td", [{"class", "valign"}], atom_to_list(Pending)), ?XAE("td", [{"class", "valign"}], Groups), if Pending == in -> ?XAE("td", [{"class", "valign"}], [?INPUTT("submit", "validate" ++ ejabberd_web_admin:term_to_id(R#roster.jid), "Validate")]); true -> ?X("td") end, ?XAE("td", [{"class", "valign"}], [?INPUTT("submit", "remove" ++ ejabberd_web_admin:term_to_id(R#roster.jid), "Remove")])]) end, SItems))])] end, [?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++ case Res of ok -> [?XREST("Submitted")]; error -> [?XREST("Bad format")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], FItems ++ [?P, ?INPUT("text", "newjid", ""), ?C(" "), ?INPUTT("submit", "addjid", "Add Jabber ID") ])]. build_contact_jid_td(RosterJID) -> %% Convert {U, S, R} into {jid, U, S, R, U, S, R}: ContactJID = jlib:make_jid(RosterJID), JIDURI = case {ContactJID#jid.luser, ContactJID#jid.lserver} of {"", _} -> ""; {CUser, CServer} -> case lists:member(CServer, ?MYHOSTS) of false -> ""; true -> "/admin/server/" ++ CServer ++ "/user/" ++ CUser ++ "/" end end, case JIDURI of [] -> ?XAC("td", [{"class", "valign"}], jlib:jid_to_string(RosterJID)); URI when is_list(URI) -> ?XAE("td", [{"class", "valign"}], [?AC(JIDURI, jlib:jid_to_string(RosterJID))]) end. user_roster_parse_query(User, Server, Items, Query) -> case lists:keysearch("addjid", 1, Query) of {value, _} -> case lists:keysearch("newjid", 1, Query) of {value, {_, undefined}} -> error; {value, {_, SJID}} -> case jlib:string_to_jid(SJID) of JID when is_record(JID, jid) -> user_roster_subscribe_jid(User, Server, JID), ok; error -> error end; false -> error end; false -> case catch user_roster_item_parse_query( User, Server, Items, Query) of submitted -> ok; {'EXIT', _Reason} -> error; _ -> nothing end end. user_roster_subscribe_jid(User, Server, JID) -> out_subscription(User, Server, JID, subscribe), UJID = jlib:make_jid(User, Server, ""), ejabberd_router:route( UJID, JID, {xmlelement, "presence", [{"type", "subscribe"}], []}). user_roster_item_parse_query(User, Server, Items, Query) -> lists:foreach( fun(R) -> JID = R#roster.jid, case lists:keysearch( "validate" ++ ejabberd_web_admin:term_to_id(JID), 1, Query) of {value, _} -> JID1 = jlib:make_jid(JID), out_subscription( User, Server, JID1, subscribed), UJID = jlib:make_jid(User, Server, ""), ejabberd_router:route( UJID, JID1, {xmlelement, "presence", [{"type", "subscribed"}], []}), throw(submitted); false -> case lists:keysearch( "remove" ++ ejabberd_web_admin:term_to_id(JID), 1, Query) of {value, _} -> UJID = jlib:make_jid(User, Server, ""), process_iq( UJID, UJID, #iq{type = set, sub_el = {xmlelement, "query", [{"xmlns", ?NS_ROSTER}], [{xmlelement, "item", [{"jid", jlib:jid_to_string(JID)}, {"subscription", "remove"}], []}]}}), throw(submitted); false -> ok end end end, Items), nothing. us_to_list({User, Server}) -> jlib:jid_to_string({User, Server, ""}). webadmin_user(Acc, _User, _Server, Lang) -> Acc ++ [?XE("h3", [?ACT("roster/", "Roster")])]. ejabberd-2.1.11/src/ejabberd_rdbms.erl0000664000000000000000000000504612240230175014443 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_rdbms.erl %%% Author : Mickael Remond %%% Purpose : Manage the start of the database modules when needed %%% Created : 31 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_rdbms). -author('alexey@process-one.net'). -export([start/0]). -include("ejabberd.hrl"). start() -> %% Check if ejabberd has been compiled with ODBC case catch ejabberd_odbc_sup:module_info() of {'EXIT',{undef,_}} -> ?INFO_MSG("ejabberd has not been compiled with relational database support. Skipping database startup.", []); _ -> %% If compiled with ODBC, start ODBC on the needed host start_hosts() end. %% Start relationnal DB module on the nodes where it is needed start_hosts() -> lists:foreach( fun(Host) -> case needs_odbc(Host) of true -> start_odbc(Host); false -> ok end end, ?MYHOSTS). %% Start the ODBC module on the given host start_odbc(Host) -> Supervisor_name = gen_mod:get_module_proc(Host, ejabberd_odbc_sup), ChildSpec = {Supervisor_name, {ejabberd_odbc_sup, start_link, [Host]}, transient, infinity, supervisor, [ejabberd_odbc_sup]}, case supervisor:start_child(ejabberd_sup, ChildSpec) of {ok, _PID} -> ok; _Error -> ?ERROR_MSG("Start of supervisor ~p failed:~n~p~nRetrying...~n", [Supervisor_name, _Error]), start_odbc(Host) end. %% Returns true if we have configured odbc_server for the given host needs_odbc(Host) -> LHost = jlib:nameprep(Host), case ejabberd_config:get_local_option({odbc_server, LHost}) of undefined -> false; _ -> true end. ejabberd-2.1.11/src/mod_pres_counter.erl0000664000000000000000000000721212240230175015062 0ustar %%%---------------------------------------------------------------------- %%% File : mod_pres_counter.erl %%% Author : Ahmed Omar %%% Purpose : Presence subscription flood prevention %%% Created : 23 Sep 2010 by Ahmed Omar %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_pres_counter). -behavior(gen_mod). -export([start/2, stop/1, check_packet/6]). -include("ejabberd.hrl"). -include("jlib.hrl"). -record(pres_counter, {dir, start, count, logged = false}). start(Host, _Opts) -> ejabberd_hooks:add(privacy_check_packet, Host, ?MODULE, check_packet, 25), ok. stop(Host) -> ejabberd_hooks:delete(privacy_check_packet, Host, ?MODULE, check_packet, 25), ok. check_packet(_, _User, Server, _PrivacyList, {From, To, {xmlelement, Name, Attrs, _}}, Dir) -> case Name of "presence" -> IsSubscription = case xml:get_attr_s("type", Attrs) of "subscribe" -> true; "subscribed" -> true; "unsubscribe" -> true; "unsubscribed" -> true; _ -> false end, if IsSubscription -> JID = case Dir of in -> To; out -> From end, update(Server, JID, Dir); true -> allow end; _ -> allow end. update(Server, JID, Dir) -> %% get options StormCount = gen_mod:get_module_opt(Server, ?MODULE, count, 5), TimeInterval = gen_mod:get_module_opt(Server, ?MODULE, interval, 60), {MegaSecs, Secs, _MicroSecs} = now(), TimeStamp = MegaSecs * 1000000 + Secs, case read(Dir) of undefined -> write(Dir, #pres_counter{dir = Dir, start = TimeStamp, count = 1}), allow; #pres_counter{start = TimeStart, count = Count, logged = Logged} = R -> %% record for this key exists, check if we're %% within TimeInterval seconds, and whether the StormCount is %% high enough. or else just increment the count. if TimeStamp - TimeStart > TimeInterval -> write(Dir, R#pres_counter{ start = TimeStamp, count = 1}), allow; (Count =:= StormCount) and Logged -> {stop, deny}; Count =:= StormCount -> write(Dir, R#pres_counter{logged = true}), case Dir of in -> ?WARNING_MSG( "User ~s is being flooded, " "ignoring received presence subscriptions", [jlib:jid_to_string(JID)]); out -> IP = ejabberd_sm:get_user_ip( JID#jid.luser, JID#jid.lserver, JID#jid.lresource), ?WARNING_MSG( "Flooder detected: ~s, on IP: ~s " "ignoring sent presence subscriptions~n", [jlib:jid_to_string(JID), jlib:ip_to_list(IP)]) end, {stop, deny}; true -> write(Dir, R#pres_counter{ start = TimeStamp, count = Count + 1}), allow end end. read(K)-> get({pres_counter, K}). write(K, V)-> put({pres_counter, K}, V). ejabberd-2.1.11/src/configure.erl0000664000000000000000000000600612240230175013474 0ustar %%%---------------------------------------------------------------------- %%% File : configure.erl %%% Author : Alexey Shchepin %%% Purpose : %%% Created : 27 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(configure). -author('alexey@process-one.net'). -export([start/0]). -include("ejabberd.hrl"). start() -> Static = case os:getenv("arg") of false -> false; "static" -> true; _ -> false end, case Static of true -> ExpatLib = "EXPAT_LIB = $(EXPAT_DIR)\\StaticLibs\\libexpatMT.lib\n", ExpatFlag = "EXPAT_FLAG = -DXML_STATIC\n", IconvDir = "ICONV_DIR = c:\\sdk\\GnuWin32\n", IconvLib = "ICONV_LIB = $(ICONV_DIR)\\lib\\libiconv.lib\n", ZlibDir = "ZLIB_DIR = c:\\sdk\\GnuWin32\n", ZlibLib = "ZLIB_LIB = $(ZLIB_DIR)\\lib\\zlib.lib\n"; false -> ExpatLib = "EXPAT_LIB = $(EXPAT_DIR)\\Libs\\libexpat.lib\n", ExpatFlag = "", IconvDir = "ICONV_DIR = c:\\sdk\\GnuWin32\n", IconvLib = "ICONV_LIB = $(ICONV_DIR)\\lib\\libiconv.lib\n", ZlibDir = "ZLIB_DIR = c:\\sdk\\GnuWin32\n", ZlibLib = "ZLIB_LIB = $(ZLIB_DIR)\\lib\\zlib.lib\n" end, EVersion = "ERLANG_VERSION = " ++ erlang:system_info(version) ++ "\n", EIDirS = "EI_DIR = " ++ code:lib_dir(erl_interface) ++ "\n", RootDirS = "ERLANG_DIR = " ++ code:root_dir() ++ "\n", %% Load the ejabberd application description so that ?VERSION can read the vsn key application:load(ejabberd), Version = "EJABBERD_VERSION = " ++ ?VERSION ++ "\n", ExpatDir = "EXPAT_DIR = c:\\sdk\\Expat-2.0.0\n", OpenSSLDir = "OPENSSL_DIR = c:\\sdk\\OpenSSL\n", DBType = "DBTYPE = generic\n", %% 'generic' or 'mssql' SSLDir = "SSLDIR = " ++ code:lib_dir(ssl) ++ "\n", StdLibDir = "STDLIBDIR = " ++ code:lib_dir(stdlib) ++ "\n", file:write_file("Makefile.inc", list_to_binary(EVersion ++ EIDirS ++ RootDirS ++ Version ++ SSLDir ++ StdLibDir ++ OpenSSLDir ++ DBType ++ ExpatDir ++ ExpatLib ++ ExpatFlag ++ IconvDir ++ IconvLib ++ ZlibDir ++ ZlibLib)), halt(). ejabberd-2.1.11/src/ejabberd_config.erl0000664000000000000000000004601712240230175014604 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_config.erl %%% Author : Alexey Shchepin %%% Purpose : Load config file %%% Created : 14 Dec 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_config). -author('alexey@process-one.net'). -export([start/0, load_file/1, add_global_option/2, add_local_option/2, get_global_option/1, get_local_option/1]). -export([get_vh_by_auth_method/1]). -export([is_file_readable/1]). -include("ejabberd.hrl"). -include("ejabberd_config.hrl"). -include_lib("kernel/include/file.hrl"). %% @type macro() = {macro_key(), macro_value()} %% @type macro_key() = atom(). %% The atom must have all characters in uppercase. %% @type macro_value() = term(). start() -> mnesia:create_table(config, [{disc_copies, [node()]}, {attributes, record_info(fields, config)}]), mnesia:add_table_copy(config, node(), ram_copies), mnesia:create_table(local_config, [{disc_copies, [node()]}, {local_content, true}, {attributes, record_info(fields, local_config)}]), mnesia:add_table_copy(local_config, node(), ram_copies), Config = get_ejabberd_config_path(), load_file(Config), %% This start time is used by mod_last: add_local_option(node_start, now()), ok. %% @doc Get the filename of the ejabberd configuration file. %% The filename can be specified with: erl -config "/path/to/ejabberd.cfg". %% It can also be specified with the environtment variable EJABBERD_CONFIG_PATH. %% If not specified, the default value 'ejabberd.cfg' is assumed. %% @spec () -> string() get_ejabberd_config_path() -> case application:get_env(config) of {ok, Path} -> Path; undefined -> case os:getenv("EJABBERD_CONFIG_PATH") of false -> ?CONFIG_PATH; Path -> Path end end. %% @doc Load the ejabberd configuration file. %% It also includes additional configuration files and replaces macros. %% This function will crash if finds some error in the configuration file. %% @spec (File::string()) -> ok load_file(File) -> Terms = get_plain_terms_file(File), State = lists:foldl(fun search_hosts/2, #state{}, Terms), Terms_macros = replace_macros(Terms), Res = lists:foldl(fun process_term/2, State, Terms_macros), set_opts(Res). %% @doc Read an ejabberd configuration file and return the terms. %% Input is an absolute or relative path to an ejabberd config file. %% Returns a list of plain terms, %% in which the options 'include_config_file' were parsed %% and the terms in those files were included. %% @spec(string()) -> [term()] get_plain_terms_file(File1) -> File = get_absolute_path(File1), case file:consult(File) of {ok, Terms} -> include_config_files(Terms); {error, {LineNumber, erl_parse, _ParseMessage} = Reason} -> ExitText = describe_config_problem(File, Reason, LineNumber), ?ERROR_MSG(ExitText, []), exit_or_halt(ExitText); {error, Reason} -> ExitText = describe_config_problem(File, Reason), ?ERROR_MSG(ExitText, []), exit_or_halt(ExitText) end. %% @doc Convert configuration filename to absolute path. %% Input is an absolute or relative path to an ejabberd configuration file. %% And returns an absolute path to the configuration file. %% @spec (string()) -> string() get_absolute_path(File) -> case filename:pathtype(File) of absolute -> File; relative -> Config_path = get_ejabberd_config_path(), Config_dir = filename:dirname(Config_path), filename:absname_join(Config_dir, File) end. search_hosts(Term, State) -> case Term of {host, Host} -> if State#state.hosts == [] -> add_hosts_to_option([Host], State); true -> ?ERROR_MSG("Can't load config file: " "too many hosts definitions", []), exit("too many hosts definitions") end; {hosts, Hosts} -> if State#state.hosts == [] -> add_hosts_to_option(Hosts, State); true -> ?ERROR_MSG("Can't load config file: " "too many hosts definitions", []), exit("too many hosts definitions") end; _ -> State end. add_hosts_to_option(Hosts, State) -> PrepHosts = normalize_hosts(Hosts), add_option(hosts, PrepHosts, State#state{hosts = PrepHosts}). normalize_hosts(Hosts) -> normalize_hosts(Hosts,[]). normalize_hosts([], PrepHosts) -> lists:reverse(PrepHosts); normalize_hosts([Host|Hosts], PrepHosts) -> case jlib:nodeprep(Host) of error -> ?ERROR_MSG("Can't load config file: " "invalid host name [~p]", [Host]), exit("invalid hostname"); PrepHost -> normalize_hosts(Hosts, [PrepHost|PrepHosts]) end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Errors reading the config file describe_config_problem(Filename, Reason) -> Text1 = lists:flatten("Problem loading ejabberd config file " ++ Filename), Text2 = lists:flatten(" : " ++ file:format_error(Reason)), ExitText = Text1 ++ Text2, ExitText. describe_config_problem(Filename, Reason, LineNumber) -> Text1 = lists:flatten("Problem loading ejabberd config file " ++ Filename), Text2 = lists:flatten(" approximately in the line " ++ file:format_error(Reason)), ExitText = Text1 ++ Text2, Lines = get_config_lines(Filename, LineNumber, 10, 3), ?ERROR_MSG("The following lines from your configuration file might be" " relevant to the error: ~n~s", [Lines]), ExitText. get_config_lines(Filename, TargetNumber, PreContext, PostContext) -> {ok, Fd} = file:open(Filename, [read]), LNumbers = lists:seq(TargetNumber-PreContext, TargetNumber+PostContext), NextL = io:get_line(Fd, no_prompt), R = get_config_lines2(Fd, NextL, 1, LNumbers, []), file:close(Fd), R. get_config_lines2(_Fd, eof, _CurrLine, _LNumbers, R) -> lists:reverse(R); get_config_lines2(_Fd, _NewLine, _CurrLine, [], R) -> lists:reverse(R); get_config_lines2(Fd, Data, CurrLine, [NextWanted | LNumbers], R) when is_list(Data) -> NextL = io:get_line(Fd, no_prompt), if CurrLine >= NextWanted -> Line2 = [integer_to_list(CurrLine), ": " | Data], get_config_lines2(Fd, NextL, CurrLine+1, LNumbers, [Line2 | R]); true -> get_config_lines2(Fd, NextL, CurrLine+1, [NextWanted | LNumbers], R) end. %% If ejabberd isn't yet running in this node, then halt the node exit_or_halt(ExitText) -> case [Vsn || {ejabberd, _Desc, Vsn} <- application:which_applications()] of [] -> timer:sleep(1000), halt(string:substr(ExitText, 1, 199)); [_] -> exit(ExitText) end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Support for 'include_config_file' %% @doc Include additional configuration files in the list of terms. %% @spec ([term()]) -> [term()] include_config_files(Terms) -> include_config_files(Terms, []). include_config_files([], Res) -> Res; include_config_files([{include_config_file, Filename} | Terms], Res) -> include_config_files([{include_config_file, Filename, []} | Terms], Res); include_config_files([{include_config_file, Filename, Options} | Terms], Res) -> Included_terms = get_plain_terms_file(Filename), Disallow = proplists:get_value(disallow, Options, []), Included_terms2 = delete_disallowed(Disallow, Included_terms), Allow_only = proplists:get_value(allow_only, Options, all), Included_terms3 = keep_only_allowed(Allow_only, Included_terms2), include_config_files(Terms, Res ++ Included_terms3); include_config_files([Term | Terms], Res) -> include_config_files(Terms, Res ++ [Term]). %% @doc Filter from the list of terms the disallowed. %% Returns a sublist of Terms without the ones which first element is %% included in Disallowed. %% @spec (Disallowed::[atom()], Terms::[term()]) -> [term()] delete_disallowed(Disallowed, Terms) -> lists:foldl( fun(Dis, Ldis) -> delete_disallowed2(Dis, Ldis) end, Terms, Disallowed). delete_disallowed2(Disallowed, [H|T]) -> case element(1, H) of Disallowed -> ?WARNING_MSG("The option '~p' is disallowed, " "and will not be accepted", [Disallowed]), delete_disallowed2(Disallowed, T); _ -> [H|delete_disallowed2(Disallowed, T)] end; delete_disallowed2(_, []) -> []. %% @doc Keep from the list only the allowed terms. %% Returns a sublist of Terms with only the ones which first element is %% included in Allowed. %% @spec (Allowed::[atom()], Terms::[term()]) -> [term()] keep_only_allowed(all, Terms) -> Terms; keep_only_allowed(Allowed, Terms) -> {As, NAs} = lists:partition( fun(Term) -> lists:member(element(1, Term), Allowed) end, Terms), [?WARNING_MSG("This option is not allowed, " "and will not be accepted:~n~p", [NA]) || NA <- NAs], As. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Support for Macro %% @doc Replace the macros with their defined values. %% @spec (Terms::[term()]) -> [term()] replace_macros(Terms) -> {TermsOthers, Macros} = split_terms_macros(Terms), replace(TermsOthers, Macros). %% @doc Split Terms into normal terms and macro definitions. %% @spec (Terms) -> {Terms, Macros} %% Terms = [term()] %% Macros = [macro()] split_terms_macros(Terms) -> lists:foldl( fun(Term, {TOs, Ms}) -> case Term of {define_macro, Key, Value} -> case is_atom(Key) and is_all_uppercase(Key) of true -> {TOs, Ms++[{Key, Value}]}; false -> exit({macro_not_properly_defined, Term}) end; Term -> {TOs ++ [Term], Ms} end end, {[], []}, Terms). %% @doc Recursively replace in Terms macro usages with the defined value. %% @spec (Terms, Macros) -> Terms %% Terms = [term()] %% Macros = [macro()] replace([], _) -> []; replace([Term|Terms], Macros) -> [replace_term(Term, Macros) | replace(Terms, Macros)]. replace_term(Key, Macros) when is_atom(Key) -> case is_all_uppercase(Key) of true -> case proplists:get_value(Key, Macros) of undefined -> exit({undefined_macro, Key}); Value -> Value end; false -> Key end; replace_term({use_macro, Key, Value}, Macros) -> proplists:get_value(Key, Macros, Value); replace_term(Term, Macros) when is_list(Term) -> replace(Term, Macros); replace_term(Term, Macros) when is_tuple(Term) -> List = tuple_to_list(Term), List2 = replace(List, Macros), list_to_tuple(List2); replace_term(Term, _) -> Term. is_all_uppercase(Atom) -> String = erlang:atom_to_list(Atom), lists:all(fun(C) when C >= $a, C =< $z -> false; (_) -> true end, String). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Process terms process_term(Term, State) -> case Term of override_global -> State#state{override_global = true}; override_local -> State#state{override_local = true}; override_acls -> State#state{override_acls = true}; {acl, _ACLName, _ACLData} -> process_host_term(Term, global, State); {access, _RuleName, _Rules} -> process_host_term(Term, global, State); {shaper, _Name, _Data} -> %%lists:foldl(fun(Host, S) -> process_host_term(Term, Host, S) end, %% State, State#state.hosts); process_host_term(Term, global, State); {host, _Host} -> State; {hosts, _Hosts} -> State; {fqdn, HostFQDN} -> ?DEBUG("FQDN set to: ~p", [HostFQDN]), add_option(fqdn, HostFQDN, State); {host_config, Host, Terms} -> lists:foldl(fun(T, S) -> process_host_term(T, Host, S) end, State, Terms); {listen, Listeners} -> Listeners2 = lists:map( fun({PortIP, Module, Opts}) -> {Port, IPT, _, _, Proto, OptsClean} = ejabberd_listener:parse_listener_portip(PortIP, Opts), {{Port, IPT, Proto}, Module, OptsClean} end, Listeners), add_option(listen, Listeners2, State); {language, Val} -> add_option(language, Val, State); {outgoing_s2s_port, Port} -> add_option(outgoing_s2s_port, Port, State); {outgoing_s2s_options, Methods, Timeout} -> add_option(outgoing_s2s_options, {Methods, Timeout}, State); {s2s_dns_options, PropList} -> add_option(s2s_dns_options, PropList, State); {s2s_use_starttls, Port} -> add_option(s2s_use_starttls, Port, State); {s2s_certfile, CertFile} -> case ejabberd_config:is_file_readable(CertFile) of true -> add_option(s2s_certfile, CertFile, State); false -> ErrorText = "There is a problem in the configuration: " "the specified file is not readable: ", throw({error, ErrorText ++ CertFile}) end; {domain_certfile, Domain, CertFile} -> case ejabberd_config:is_file_readable(CertFile) of true -> add_option({domain_certfile, Domain}, CertFile, State); false -> ErrorText = "There is a problem in the configuration: " "the specified file is not readable: ", throw({error, ErrorText ++ CertFile}) end; {node_type, NodeType} -> add_option(node_type, NodeType, State); {cluster_nodes, Nodes} -> add_option(cluster_nodes, Nodes, State); {domain_balancing, Domain, Balancing} -> add_option({domain_balancing, Domain}, Balancing, State); {domain_balancing_component_number, Domain, N} -> add_option({domain_balancing_component_number, Domain}, N, State); {watchdog_admins, Admins} -> add_option(watchdog_admins, Admins, State); {watchdog_large_heap, LH} -> add_option(watchdog_large_heap, LH, State); {registration_timeout, Timeout} -> add_option(registration_timeout, Timeout, State); {captcha_cmd, Cmd} -> add_option(captcha_cmd, Cmd, State); {captcha_host, Host} -> add_option(captcha_host, Host, State); {captcha_limit, Limit} -> add_option(captcha_limit, Limit, State); {ejabberdctl_access_commands, ACs} -> add_option(ejabberdctl_access_commands, ACs, State); {loglevel, Loglevel} -> ejabberd_loglevel:set(Loglevel), State; {max_fsm_queue, N} -> add_option(max_fsm_queue, N, State); {_Opt, _Val} -> lists:foldl(fun(Host, S) -> process_host_term(Term, Host, S) end, State, State#state.hosts) end. process_host_term(Term, Host, State) -> case Term of {acl, ACLName, ACLData} -> State#state{opts = [acl:to_record(Host, ACLName, ACLData) | State#state.opts]}; {access, RuleName, Rules} -> State#state{opts = [#config{key = {access, RuleName, Host}, value = Rules} | State#state.opts]}; {shaper, Name, Data} -> State#state{opts = [#config{key = {shaper, Name, Host}, value = Data} | State#state.opts]}; {host, Host} -> State; {hosts, _Hosts} -> State; {odbc_server, ODBC_server} -> add_option({odbc_server, Host}, ODBC_server, State); {Opt, Val} -> add_option({Opt, Host}, Val, State) end. add_option(Opt, Val, State) -> Table = case Opt of hosts -> config; language -> config; _ -> local_config end, case Table of config -> State#state{opts = [#config{key = Opt, value = Val} | State#state.opts]}; local_config -> case Opt of {{add, OptName}, Host} -> State#state{opts = compact({OptName, Host}, Val, State#state.opts, [])}; _ -> State#state{opts = [#local_config{key = Opt, value = Val} | State#state.opts]} end end. compact({OptName, Host} = Opt, Val, [], Os) -> ?WARNING_MSG("The option '~p' is defined for the host ~p using host_config " "before the global '~p' option. This host_config option may get overwritten.", [OptName, Host, OptName]), [#local_config{key = Opt, value = Val}] ++ Os; %% Traverse the list of the options already parsed compact(Opt, Val, [O | Os1], Os2) -> case catch O#local_config.key of %% If the key of a local_config matches the Opt that wants to be added Opt -> %% Then prepend the new value to the list of old values Os2 ++ [#local_config{key = Opt, value = Val++O#local_config.value} ] ++ Os1; _ -> compact(Opt, Val, Os1, Os2++[O]) end. set_opts(State) -> Opts = lists:reverse(State#state.opts), F = fun() -> if State#state.override_global -> Ksg = mnesia:all_keys(config), lists:foreach(fun(K) -> mnesia:delete({config, K}) end, Ksg); true -> ok end, if State#state.override_local -> Ksl = mnesia:all_keys(local_config), lists:foreach(fun(K) -> mnesia:delete({local_config, K}) end, Ksl); true -> ok end, if State#state.override_acls -> Ksa = mnesia:all_keys(acl), lists:foreach(fun(K) -> mnesia:delete({acl, K}) end, Ksa); true -> ok end, lists:foreach(fun(R) -> mnesia:write(R) end, Opts) end, case mnesia:transaction(F) of {atomic, _} -> ok; {aborted,{no_exists,Table}} -> MnesiaDirectory = mnesia:system_info(directory), ?ERROR_MSG("Error reading Mnesia database spool files:~n" "The Mnesia database couldn't read the spool file for the table '~p'.~n" "ejabberd needs read and write access in the directory:~n ~s~n" "Maybe the problem is a change in the computer hostname,~n" "or a change in the Erlang node name, which is currently:~n ~p~n" "Check the ejabberd guide for details about changing the~n" "computer hostname or Erlang node name.~n", [Table, MnesiaDirectory, node()]), exit("Error reading Mnesia database") end. add_global_option(Opt, Val) -> mnesia:transaction(fun() -> mnesia:write(#config{key = Opt, value = Val}) end). add_local_option(Opt, Val) -> mnesia:transaction(fun() -> mnesia:write(#local_config{key = Opt, value = Val}) end). get_global_option(Opt) -> case ets:lookup(config, Opt) of [#config{value = Val}] -> Val; _ -> undefined end. get_local_option(Opt) -> case ets:lookup(local_config, Opt) of [#local_config{value = Val}] -> Val; _ -> undefined end. %% Return the list of hosts handled by a given module get_vh_by_auth_method(AuthMethod) -> mnesia:dirty_select(local_config, [{#local_config{key = {auth_method, '$1'}, value=AuthMethod},[],['$1']}]). %% @spec (Path::string()) -> true | false is_file_readable(Path) -> case file:read_file_info(Path) of {ok, FileInfo} -> case {FileInfo#file_info.type, FileInfo#file_info.access} of {regular, read} -> true; {regular, read_write} -> true; _ -> false end; {error, _Reason} -> false end. ejabberd-2.1.11/src/mod_offline_odbc.erl0000664000000000000000000004045512240230175014771 0ustar %%%---------------------------------------------------------------------- %%% File : mod_offline_odbc.erl %%% Author : Alexey Shchepin %%% Purpose : Store and manage offline messages in relational database. %%% Created : 5 Jan 2003 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(mod_offline_odbc). -author('alexey@process-one.net'). -behaviour(gen_mod). -export([count_offline_messages/2]). -export([start/2, loop/2, stop/1, store_packet/3, pop_offline_messages/3, get_sm_features/5, remove_user/2, get_queue_length/2, webadmin_page/3, webadmin_user/4, webadmin_user_parse_query/5]). -include("ejabberd.hrl"). -include("jlib.hrl"). -include("web/ejabberd_http.hrl"). -include("web/ejabberd_web_admin.hrl"). -record(offline_msg, {user, timestamp, expire, from, to, packet}). -define(PROCNAME, ejabberd_offline). -define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000). %% default value for the maximum number of user messages -define(MAX_USER_MESSAGES, infinity). start(Host, Opts) -> ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, store_packet, 50), ejabberd_hooks:add(resend_offline_messages_hook, Host, ?MODULE, pop_offline_messages, 50), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:add(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_sm_features, 50), ejabberd_hooks:add(webadmin_page_host, Host, ?MODULE, webadmin_page, 50), ejabberd_hooks:add(webadmin_user, Host, ?MODULE, webadmin_user, 50), ejabberd_hooks:add(webadmin_user_parse_query, Host, ?MODULE, webadmin_user_parse_query, 50), AccessMaxOfflineMsgs = gen_mod:get_opt(access_max_user_messages, Opts, max_user_offline_messages), register(gen_mod:get_module_proc(Host, ?PROCNAME), spawn(?MODULE, loop, [Host, AccessMaxOfflineMsgs])). loop(Host, AccessMaxOfflineMsgs) -> receive #offline_msg{user = User} = Msg -> Msgs = receive_all(User, [Msg]), Len = length(Msgs), MaxOfflineMsgs = get_max_user_messages(AccessMaxOfflineMsgs, User, Host), %% Only count existing messages if needed: Count = if MaxOfflineMsgs =/= infinity -> Len + count_offline_messages(User, Host); true -> 0 end, if Count > MaxOfflineMsgs -> discard_warn_sender(Msgs); true -> Query = lists:map( fun(M) -> Username = ejabberd_odbc:escape( (M#offline_msg.to)#jid.luser), From = M#offline_msg.from, To = M#offline_msg.to, {xmlelement, Name, Attrs, Els} = M#offline_msg.packet, Attrs2 = jlib:replace_from_to_attrs( jlib:jid_to_string(From), jlib:jid_to_string(To), Attrs), Packet = {xmlelement, Name, Attrs2, Els ++ [jlib:timestamp_to_xml( calendar:now_to_universal_time( M#offline_msg.timestamp), utc, jlib:make_jid("", Host, ""), "Offline Storage"), %% TODO: Delete the next three lines once XEP-0091 is Obsolete jlib:timestamp_to_xml( calendar:now_to_universal_time( M#offline_msg.timestamp))]}, XML = ejabberd_odbc:escape( xml:element_to_binary(Packet)), odbc_queries:add_spool_sql(Username, XML) end, Msgs), case catch odbc_queries:add_spool(Host, Query) of {'EXIT', Reason} -> ?ERROR_MSG("~p~n", [Reason]); {error, Reason} -> ?ERROR_MSG("~p~n", [Reason]); _ -> ok end end, loop(Host, AccessMaxOfflineMsgs); _ -> loop(Host, AccessMaxOfflineMsgs) end. %% Function copied from ejabberd_sm.erl: get_max_user_messages(AccessRule, LUser, Host) -> case acl:match_rule( Host, AccessRule, jlib:make_jid(LUser, Host, "")) of Max when is_integer(Max) -> Max; infinity -> infinity; _ -> ?MAX_USER_MESSAGES end. receive_all(Username, Msgs) -> receive #offline_msg{user=Username} = Msg -> receive_all(Username, [Msg | Msgs]) after 0 -> lists:reverse(Msgs) end. stop(Host) -> ejabberd_hooks:delete(offline_message_hook, Host, ?MODULE, store_packet, 50), ejabberd_hooks:delete(resend_offline_messages_hook, Host, ?MODULE, pop_offline_messages, 50), ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50), ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_sm_features, 50), ejabberd_hooks:delete(webadmin_page_host, Host, ?MODULE, webadmin_page, 50), ejabberd_hooks:delete(webadmin_user, Host, ?MODULE, webadmin_user, 50), ejabberd_hooks:delete(webadmin_user_parse_query, Host, ?MODULE, webadmin_user_parse_query, 50), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), exit(whereis(Proc), stop), ok. get_sm_features(Acc, _From, _To, "", _Lang) -> Feats = case Acc of {result, I} -> I; _ -> [] end, {result, Feats ++ [?NS_FEATURE_MSGOFFLINE]}; get_sm_features(_Acc, _From, _To, ?NS_FEATURE_MSGOFFLINE, _Lang) -> %% override all lesser features... {result, []}; get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. store_packet(From, To, Packet) -> Type = xml:get_tag_attr_s("type", Packet), if (Type /= "error") and (Type /= "groupchat") and (Type /= "headline") -> case check_event_chatstates(From, To, Packet) of true -> #jid{luser = LUser} = To, TimeStamp = now(), {xmlelement, _Name, _Attrs, Els} = Packet, Expire = find_x_expire(TimeStamp, Els), gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) ! #offline_msg{user = LUser, timestamp = TimeStamp, expire = Expire, from = From, to = To, packet = Packet}, stop; _ -> ok end; true -> ok end. %% Check if the packet has any content about XEP-0022 or XEP-0085 check_event_chatstates(From, To, Packet) -> {xmlelement, Name, Attrs, Els} = Packet, case find_x_event_chatstates(Els, {false, false, false}) of %% There wasn't any x:event or chatstates subelements {false, false, _} -> true; %% There a chatstates subelement and other stuff, but no x:event {false, CEl, true} when CEl /= false -> true; %% There was only a subelement: a chatstates {false, CEl, false} when CEl /= false -> %% Don't allow offline storage false; %% There was an x:event element, and maybe also other stuff {El, _, _} when El /= false -> case xml:get_subtag(El, "id") of false -> case xml:get_subtag(El, "offline") of false -> true; _ -> ID = case xml:get_tag_attr_s("id", Packet) of "" -> {xmlelement, "id", [], []}; S -> {xmlelement, "id", [], [{xmlcdata, S}]} end, ejabberd_router:route( To, From, {xmlelement, Name, Attrs, [{xmlelement, "x", [{"xmlns", ?NS_EVENT}], [ID, {xmlelement, "offline", [], []}]}] }), true end; _ -> false end end. %% Check if the packet has subelements about XEP-0022, XEP-0085 or other find_x_event_chatstates([], Res) -> Res; find_x_event_chatstates([{xmlcdata, _} | Els], Res) -> find_x_event_chatstates(Els, Res); find_x_event_chatstates([El | Els], {A, B, C}) -> case xml:get_tag_attr_s("xmlns", El) of ?NS_EVENT -> find_x_event_chatstates(Els, {El, B, C}); ?NS_CHATSTATES -> find_x_event_chatstates(Els, {A, El, C}); _ -> find_x_event_chatstates(Els, {A, B, true}) end. find_x_expire(_, []) -> never; find_x_expire(TimeStamp, [{xmlcdata, _} | Els]) -> find_x_expire(TimeStamp, Els); find_x_expire(TimeStamp, [El | Els]) -> case xml:get_tag_attr_s("xmlns", El) of ?NS_EXPIRE -> Val = xml:get_tag_attr_s("seconds", El), case catch list_to_integer(Val) of {'EXIT', _} -> never; Int when Int > 0 -> {MegaSecs, Secs, MicroSecs} = TimeStamp, S = MegaSecs * 1000000 + Secs + Int, MegaSecs1 = S div 1000000, Secs1 = S rem 1000000, {MegaSecs1, Secs1, MicroSecs}; _ -> never end; _ -> find_x_expire(TimeStamp, Els) end. pop_offline_messages(Ls, User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), EUser = ejabberd_odbc:escape(LUser), case odbc_queries:get_and_del_spool_msg_t(LServer, EUser) of {atomic, {selected, ["username","xml"], Rs}} -> Ls ++ lists:flatmap( fun({_, XML}) -> case xml_stream:parse_element(XML) of {error, _Reason} -> []; El -> To = jlib:string_to_jid( xml:get_tag_attr_s("to", El)), From = jlib:string_to_jid( xml:get_tag_attr_s("from", El)), if (To /= error) and (From /= error) -> [{route, From, To, El}]; true -> [] end end end, Rs); _ -> Ls end. remove_user(User, Server) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), Username = ejabberd_odbc:escape(LUser), odbc_queries:del_spool_msg(LServer, Username). %% Helper functions: %% TODO: Warning - This function is a duplicate from mod_offline.erl %% It is duplicate to stay consistent (many functions are duplicated %% in this module). It will be refactored later on. %% Warn senders that their messages have been discarded: discard_warn_sender(Msgs) -> lists:foreach( fun(#offline_msg{from=From, to=To, packet=Packet}) -> ErrText = "Your contact offline message queue is full. The message has been discarded.", Lang = xml:get_tag_attr_s("xml:lang", Packet), Err = jlib:make_error_reply( Packet, ?ERRT_RESOURCE_CONSTRAINT(Lang, ErrText)), ejabberd_router:route( To, From, Err) end, Msgs). webadmin_page(_, Host, #request{us = _US, path = ["user", U, "queue"], q = Query, lang = Lang} = _Request) -> Res = user_queue(U, Host, Query, Lang), {stop, Res}; webadmin_page(Acc, _, _) -> Acc. user_queue(User, Server, Query, Lang) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), Username = ejabberd_odbc:escape(LUser), US = {LUser, LServer}, Res = user_queue_parse_query(Username, LServer, Query), MsgsAll = case catch ejabberd_odbc:sql_query( LServer, ["select username, xml from spool" " where username='", Username, "'" " order by seq;"]) of {selected, ["username", "xml"], Rs} -> lists:flatmap( fun({_, XML}) -> case xml_stream:parse_element(XML) of {error, _Reason} -> []; El -> [El] end end, Rs); _ -> [] end, Msgs = get_messages_subset(User, Server, MsgsAll), FMsgs = lists:map( fun({xmlelement, _Name, _Attrs, _Els} = Msg) -> ID = jlib:encode_base64(binary_to_list(term_to_binary(Msg))), Packet = Msg, FPacket = ejabberd_web_admin:pretty_print_xml(Packet), ?XE("tr", [?XAE("td", [{"class", "valign"}], [?INPUT("checkbox", "selected", ID)]), ?XAE("td", [{"class", "valign"}], [?XC("pre", FPacket)])] ) end, Msgs), [?XC("h1", io_lib:format(?T("~s's Offline Messages Queue"), [us_to_list(US)]))] ++ case Res of ok -> [?XREST("Submitted")]; nothing -> [] end ++ [?XAE("form", [{"action", ""}, {"method", "post"}], [?XE("table", [?XE("thead", [?XE("tr", [?X("td"), ?XCT("td", "Packet") ])]), ?XE("tbody", if FMsgs == [] -> [?XE("tr", [?XAC("td", [{"colspan", "4"}], " ")] )]; true -> FMsgs end )]), ?BR, ?INPUTT("submit", "delete", "Delete Selected") ])]. user_queue_parse_query(Username, LServer, Query) -> case lists:keysearch("delete", 1, Query) of {value, _} -> Msgs = case catch ejabberd_odbc:sql_query( LServer, ["select xml, seq from spool" " where username='", Username, "'" " order by seq;"]) of {selected, ["xml", "seq"], Rs} -> lists:flatmap( fun({XML, Seq}) -> case xml_stream:parse_element(XML) of {error, _Reason} -> []; El -> [{El, Seq}] end end, Rs); _ -> [] end, F = fun() -> lists:foreach( fun({Msg, Seq}) -> ID = jlib:encode_base64( binary_to_list(term_to_binary(Msg))), case lists:member({"selected", ID}, Query) of true -> SSeq = ejabberd_odbc:escape(Seq), catch ejabberd_odbc:sql_query( LServer, ["delete from spool" " where username='", Username, "'" " and seq='", SSeq, "';"]); false -> ok end end, Msgs) end, mnesia:transaction(F), ok; false -> nothing end. us_to_list({User, Server}) -> jlib:jid_to_string({User, Server, ""}). get_queue_length(Username, LServer) -> case catch ejabberd_odbc:sql_query( LServer, ["select count(*) from spool" " where username='", Username, "';"]) of {selected, [_], [{SCount}]} -> SCount; _ -> 0 end. get_messages_subset(User, Host, MsgsAll) -> Access = gen_mod:get_module_opt(Host, ?MODULE, access_max_user_messages, max_user_offline_messages), MaxOfflineMsgs = case get_max_user_messages(Access, User, Host) of Number when is_integer(Number) -> Number; _ -> 100 end, Length = length(MsgsAll), get_messages_subset2(MaxOfflineMsgs, Length, MsgsAll). get_messages_subset2(Max, Length, MsgsAll) when Length =< Max*2 -> MsgsAll; get_messages_subset2(Max, Length, MsgsAll) -> FirstN = Max, {MsgsFirstN, Msgs2} = lists:split(FirstN, MsgsAll), MsgsLastN = lists:nthtail(Length - FirstN - FirstN, Msgs2), IntermediateMsg = {xmlelement, "...", [], []}, MsgsFirstN ++ [IntermediateMsg] ++ MsgsLastN. webadmin_user(Acc, User, Server, Lang) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), Username = ejabberd_odbc:escape(LUser), QueueLen = get_queue_length(Username, LServer), FQueueLen = [?AC("queue/", QueueLen)], Acc ++ [?XCT("h3", "Offline Messages:")] ++ FQueueLen ++ [?C(" "), ?INPUTT("submit", "removealloffline", "Remove All Offline Messages")]. webadmin_user_parse_query(_, "removealloffline", User, Server, _Query) -> case catch odbc_queries:del_spool_msg(Server, User) of {'EXIT', Reason} -> ?ERROR_MSG("Failed to remove offline messages: ~p", [Reason]), {stop, error}; {error, Reason} -> ?ERROR_MSG("Failed to remove offline messages: ~p", [Reason]), {stop, error}; _ -> ?INFO_MSG("Removed all offline messages for ~s@~s", [User, Server]), {stop, ok} end; webadmin_user_parse_query(Acc, _Action, _User, _Server, _Query) -> Acc. %% ------------------------------------------------ %% mod_offline: number of messages quota management %% Returns as integer the number of offline messages for a given user count_offline_messages(LUser, LServer) -> Username = ejabberd_odbc:escape(LUser), case catch odbc_queries:count_records_where( LServer, "spool", "where username='" ++ Username ++ "'") of {selected, [_], [{Res}]} -> list_to_integer(Res); _ -> 0 end. ejabberd-2.1.11/src/ejabberd_s2s_in.erl0000664000000000000000000006341212240230175014532 0ustar %%%---------------------------------------------------------------------- %%% File : ejabberd_s2s_in.erl %%% Author : Alexey Shchepin %%% Purpose : Serve incoming s2s connection %%% Created : 6 Dec 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(ejabberd_s2s_in). -author('alexey@process-one.net'). -behaviour(p1_fsm). %% External exports -export([start/2, start_link/2, match_domain/2, socket_type/0]). %% gen_fsm callbacks -export([init/1, wait_for_stream/2, wait_for_feature_request/2, stream_established/2, handle_event/3, handle_sync_event/4, code_change/4, handle_info/3, print_state/1, terminate/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -ifdef(SSL40). -include_lib("public_key/include/public_key.hrl"). -define(PKIXEXPLICIT, 'OTP-PUB-KEY'). -define(PKIXIMPLICIT, 'OTP-PUB-KEY'). -else. -ifdef(SSL39). -include_lib("ssl/include/ssl_pkix.hrl"). -define(PKIXEXPLICIT, 'OTP-PKIX'). -define(PKIXIMPLICIT, 'OTP-PKIX'). -else. -include_lib("ssl/include/PKIX1Explicit88.hrl"). -include_lib("ssl/include/PKIX1Implicit88.hrl"). -define(PKIXEXPLICIT, 'PKIX1Explicit88'). -define(PKIXIMPLICIT, 'PKIX1Implicit88'). -endif. -endif. -include("XmppAddr.hrl"). -define(DICT, dict). -record(state, {socket, sockmod, streamid, shaper, tls = false, tls_enabled = false, tls_required = false, tls_certverify = false, tls_options = [], server, authenticated = false, auth_domain, connections = ?DICT:new(), timer}). %-define(DBGFSM, true). -ifdef(DBGFSM). -define(FSMOPTS, [{debug, [trace]}]). -else. -define(FSMOPTS, []). -endif. -define(FSMLIMITS, [{max_queue, 2000}]). %% if queue grows more than this, we shutdown this connection. %% Module start with or without supervisor: -ifdef(NO_TRANSIENT_SUPERVISORS). -define(SUPERVISOR_START, p1_fsm:start(ejabberd_s2s_in, [SockData, Opts], ?FSMOPTS ++ ?FSMLIMITS)). -else. -define(SUPERVISOR_START, supervisor:start_child(ejabberd_s2s_in_sup, [SockData, Opts])). -endif. -define(STREAM_HEADER(Version), ("" "") ). -define(STREAM_TRAILER, ""). -define(INVALID_NAMESPACE_ERR, xml:element_to_string(?SERR_INVALID_NAMESPACE)). -define(HOST_UNKNOWN_ERR, xml:element_to_string(?SERR_HOST_UNKNOWN)). -define(INVALID_FROM_ERR, xml:element_to_string(?SERR_INVALID_FROM)). -define(INVALID_XML_ERR, xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)). %%%---------------------------------------------------------------------- %%% API %%%---------------------------------------------------------------------- start(SockData, Opts) -> ?SUPERVISOR_START. start_link(SockData, Opts) -> p1_fsm:start_link(ejabberd_s2s_in, [SockData, Opts], ?FSMOPTS ++ ?FSMLIMITS). socket_type() -> xml_stream. %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- %%---------------------------------------------------------------------- %% Func: init/1 %% Returns: {ok, StateName, StateData} | %% {ok, StateName, StateData, Timeout} | %% ignore | %% {stop, StopReason} %%---------------------------------------------------------------------- init([{SockMod, Socket}, Opts]) -> ?DEBUG("started: ~p", [{SockMod, Socket}]), Shaper = case lists:keysearch(shaper, 1, Opts) of {value, {_, S}} -> S; _ -> none end, {StartTLS, TLSRequired, TLSCertverify} = case ejabberd_config:get_local_option(s2s_use_starttls) of UseTls when (UseTls==undefined) or (UseTls==false) -> {false, false, false}; UseTls when (UseTls==true) or (UseTls==optional) -> {true, false, false}; required -> {true, true, false}; required_trusted -> {true, true, true} end, TLSOpts = case ejabberd_config:get_local_option(s2s_certfile) of undefined -> []; CertFile -> [{certfile, CertFile}] end, Timer = erlang:start_timer(?S2STIMEOUT, self(), []), {ok, wait_for_stream, #state{socket = Socket, sockmod = SockMod, streamid = new_id(), shaper = Shaper, tls = StartTLS, tls_enabled = false, tls_required = TLSRequired, tls_certverify = TLSCertverify, tls_options = TLSOpts, timer = Timer}}. %%---------------------------------------------------------------------- %% Func: StateName/2 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> case {xml:get_attr_s("xmlns", Attrs), xml:get_attr_s("xmlns:db", Attrs), xml:get_attr_s("to", Attrs), xml:get_attr_s("version", Attrs) == "1.0"} of {"jabber:server", _, Server, true} when StateData#state.tls and (not StateData#state.authenticated) -> send_text(StateData, ?STREAM_HEADER(" version='1.0'")), SASL = if StateData#state.tls_enabled -> case (StateData#state.sockmod):get_peer_certificate( StateData#state.socket) of {ok, Cert} -> case (StateData#state.sockmod):get_verify_result(StateData#state.socket) of 0 -> [{xmlelement, "mechanisms", [{"xmlns", ?NS_SASL}], [{xmlelement, "mechanism", [], [{xmlcdata, "EXTERNAL"}]}]}]; CertVerifyRes -> case StateData#state.tls_certverify of true -> {error_cert_verif, CertVerifyRes, Cert}; false -> [] end end; error -> [] end; true -> [] end, StartTLS = if StateData#state.tls_enabled -> []; (not StateData#state.tls_enabled) and (not StateData#state.tls_required) -> [{xmlelement, "starttls", [{"xmlns", ?NS_TLS}], []}]; (not StateData#state.tls_enabled) and StateData#state.tls_required -> [{xmlelement, "starttls", [{"xmlns", ?NS_TLS}], [{xmlelement, "required", [], []}] }] end, case SASL of {error_cert_verif, CertVerifyResult, Certificate} -> CertError = tls:get_cert_verify_string(CertVerifyResult, Certificate), RemoteServer = xml:get_attr_s("from", Attrs), ?INFO_MSG("Closing s2s connection: ~s <--> ~s (~s)", [StateData#state.server, RemoteServer, CertError]), send_text(StateData, xml:element_to_string(?SERRT_POLICY_VIOLATION("en", CertError))), {atomic, Pid} = ejabberd_s2s:find_connection(jlib:make_jid("", Server, ""), jlib:make_jid("", RemoteServer, "")), ejabberd_s2s_out:stop_connection(Pid), {stop, normal, StateData}; _ -> send_element(StateData, {xmlelement, "stream:features", [], SASL ++ StartTLS ++ ejabberd_hooks:run_fold( s2s_stream_features, Server, [], [Server])}), {next_state, wait_for_feature_request, StateData#state{server = Server}} end; {"jabber:server", _, Server, true} when StateData#state.authenticated -> send_text(StateData, ?STREAM_HEADER(" version='1.0'")), send_element(StateData, {xmlelement, "stream:features", [], ejabberd_hooks:run_fold( s2s_stream_features, Server, [], [Server])}), {next_state, stream_established, StateData}; {"jabber:server", "jabber:server:dialback", _Server, _} -> send_text(StateData, ?STREAM_HEADER("")), {next_state, stream_established, StateData}; _ -> send_text(StateData, ?INVALID_NAMESPACE_ERR), {stop, normal, StateData} end; wait_for_stream({xmlstreamerror, _}, StateData) -> send_text(StateData, ?STREAM_HEADER("") ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER), {stop, normal, StateData}; wait_for_stream(timeout, StateData) -> {stop, normal, StateData}; wait_for_stream(closed, StateData) -> {stop, normal, StateData}. wait_for_feature_request({xmlstreamelement, El}, StateData) -> {xmlelement, Name, Attrs, Els} = El, TLS = StateData#state.tls, TLSEnabled = StateData#state.tls_enabled, SockMod = (StateData#state.sockmod):get_sockmod(StateData#state.socket), case {xml:get_attr_s("xmlns", Attrs), Name} of {?NS_TLS, "starttls"} when TLS == true, TLSEnabled == false, SockMod == gen_tcp -> ?DEBUG("starttls", []), Socket = StateData#state.socket, TLSOpts = case ejabberd_config:get_local_option( {domain_certfile, StateData#state.server}) of undefined -> StateData#state.tls_options; CertFile -> [{certfile, CertFile} | lists:keydelete( certfile, 1, StateData#state.tls_options)] end, TLSSocket = (StateData#state.sockmod):starttls( Socket, TLSOpts, xml:element_to_binary( {xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []})), {next_state, wait_for_stream, StateData#state{socket = TLSSocket, streamid = new_id(), tls_enabled = true, tls_options = TLSOpts }}; {?NS_SASL, "auth"} when TLSEnabled -> Mech = xml:get_attr_s("mechanism", Attrs), case Mech of "EXTERNAL" -> Auth = jlib:decode_base64(xml:get_cdata(Els)), AuthDomain = jlib:nameprep(Auth), AuthRes = case (StateData#state.sockmod):get_peer_certificate( StateData#state.socket) of {ok, Cert} -> case (StateData#state.sockmod):get_verify_result( StateData#state.socket) of 0 -> case AuthDomain of error -> false; _ -> case idna:domain_utf8_to_ascii(AuthDomain) of false -> false; PCAuthDomain -> lists:any( fun(D) -> match_domain( PCAuthDomain, D) end, get_cert_domains(Cert)) end end; _ -> false end; error -> false end, AllowRemoteHost = ejabberd_s2s:allow_host("", AuthDomain), if AuthRes andalso AllowRemoteHost -> (StateData#state.sockmod):reset_stream( StateData#state.socket), send_element(StateData, {xmlelement, "success", [{"xmlns", ?NS_SASL}], []}), ?DEBUG("(~w) Accepted s2s authentication for ~s", [StateData#state.socket, AuthDomain]), %% acess rules are first checked against the globally defined ones, that have precedence over %% domain-specific ones.. http://www.process-one.net/docs/ejabberd/guide_en.html#AccessRights %% since there is allways a shaper defined globally for s2s, it doesn't matter the actual %% local host, since the globall one will be used, even if this domain has a special rule change_shaper(StateData, "", jlib:make_jid("", AuthDomain, "")), {next_state, wait_for_stream, StateData#state{streamid = new_id(), authenticated = true, auth_domain = AuthDomain }}; true -> send_element(StateData, {xmlelement, "failure", [{"xmlns", ?NS_SASL}], []}), send_text(StateData, ?STREAM_TRAILER), {stop, normal, StateData} end; _ -> send_element(StateData, {xmlelement, "failure", [{"xmlns", ?NS_SASL}], [{xmlelement, "invalid-mechanism", [], []}]}), {stop, normal, StateData} end; _ -> stream_established({xmlstreamelement, El}, StateData) end; wait_for_feature_request({xmlstreamend, _Name}, StateData) -> send_text(StateData, ?STREAM_TRAILER), {stop, normal, StateData}; wait_for_feature_request({xmlstreamerror, _}, StateData) -> send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), {stop, normal, StateData}; wait_for_feature_request(closed, StateData) -> {stop, normal, StateData}. stream_established({xmlstreamelement, El}, StateData) -> cancel_timer(StateData#state.timer), Timer = erlang:start_timer(?S2STIMEOUT, self(), []), case is_key_packet(El) of {key, To, From, Id, Key} -> ?DEBUG("GET KEY: ~p", [{To, From, Id, Key}]), LTo = jlib:nameprep(To), LFrom = jlib:nameprep(From), %% Checks if the from domain is allowed and if the to %% domain is handled by this server: case {ejabberd_s2s:allow_host(LTo, LFrom), lists:member(LTo, ejabberd_router:dirty_get_all_domains())} of {true, true} -> ejabberd_s2s_out:terminate_if_waiting_delay(LTo, LFrom), ejabberd_s2s_out:start(LTo, LFrom, {verify, self(), Key, StateData#state.streamid}), Conns = ?DICT:store({LFrom, LTo}, wait_for_verification, StateData#state.connections), change_shaper(StateData, LTo, jlib:make_jid("", LFrom, "")), {next_state, stream_established, StateData#state{connections = Conns, timer = Timer}}; {_, false} -> send_text(StateData, ?HOST_UNKNOWN_ERR), {stop, normal, StateData}; {false, _} -> send_text(StateData, ?INVALID_FROM_ERR), {stop, normal, StateData} end; {verify, To, From, Id, Key} -> ?DEBUG("VERIFY KEY: ~p", [{To, From, Id, Key}]), LTo = jlib:nameprep(To), LFrom = jlib:nameprep(From), Type = case ejabberd_s2s:has_key({LTo, LFrom}, Key) of true -> "valid"; _ -> "invalid" end, %Type = if Key == Key1 -> "valid"; % true -> "invalid" % end, send_element(StateData, {xmlelement, "db:verify", [{"from", To}, {"to", From}, {"id", Id}, {"type", Type}], []}), {next_state, stream_established, StateData#state{timer = Timer}}; _ -> NewEl = jlib:remove_attr("xmlns", El), {xmlelement, Name, Attrs, _Els} = NewEl, From_s = xml:get_attr_s("from", Attrs), From = jlib:string_to_jid(From_s), To_s = xml:get_attr_s("to", Attrs), To = jlib:string_to_jid(To_s), if (To /= error) and (From /= error) -> LFrom = From#jid.lserver, LTo = To#jid.lserver, if StateData#state.authenticated -> case (LFrom == StateData#state.auth_domain) andalso lists:member( LTo, ejabberd_router:dirty_get_all_domains()) of true -> if ((Name == "iq") or (Name == "message") or (Name == "presence")) -> ejabberd_hooks:run( s2s_receive_packet, LTo, [From, To, NewEl]), ejabberd_router:route( From, To, NewEl); true -> error end; false -> error end; true -> case ?DICT:find({LFrom, LTo}, StateData#state.connections) of {ok, established} -> if ((Name == "iq") or (Name == "message") or (Name == "presence")) -> ejabberd_hooks:run( s2s_receive_packet, LTo, [From, To, NewEl]), ejabberd_router:route( From, To, NewEl); true -> error end; _ -> error end end; true -> error end, ejabberd_hooks:run(s2s_loop_debug, [{xmlstreamelement, El}]), {next_state, stream_established, StateData#state{timer = Timer}} end; stream_established({valid, From, To}, StateData) -> send_element(StateData, {xmlelement, "db:result", [{"from", To}, {"to", From}, {"type", "valid"}], []}), LFrom = jlib:nameprep(From), LTo = jlib:nameprep(To), NSD = StateData#state{ connections = ?DICT:store({LFrom, LTo}, established, StateData#state.connections)}, {next_state, stream_established, NSD}; stream_established({invalid, From, To}, StateData) -> send_element(StateData, {xmlelement, "db:result", [{"from", To}, {"to", From}, {"type", "invalid"}], []}), LFrom = jlib:nameprep(From), LTo = jlib:nameprep(To), NSD = StateData#state{ connections = ?DICT:erase({LFrom, LTo}, StateData#state.connections)}, {next_state, stream_established, NSD}; stream_established({xmlstreamend, _Name}, StateData) -> {stop, normal, StateData}; stream_established({xmlstreamerror, _}, StateData) -> send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER), {stop, normal, StateData}; stream_established(timeout, StateData) -> {stop, normal, StateData}; stream_established(closed, StateData) -> {stop, normal, StateData}. %%---------------------------------------------------------------------- %% Func: StateName/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- %state_name(Event, From, StateData) -> % Reply = ok, % {reply, Reply, state_name, StateData}. %%---------------------------------------------------------------------- %% Func: handle_event/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 %% Returns: The associated StateData for this connection %% {reply, Reply, NextStateName, NextStateData} %% Reply = {state_infos, [{InfoName::atom(), InfoValue::any()] %%---------------------------------------------------------------------- handle_sync_event(get_state_infos, _From, StateName, StateData) -> SockMod = StateData#state.sockmod, {Addr,Port} = try SockMod:peername(StateData#state.socket) of {ok, {A,P}} -> {A,P}; {error, _} -> {unknown,unknown} catch _:_ -> {unknown,unknown} end, Domains = get_external_hosts(StateData), Infos = [ {direction, in}, {statename, StateName}, {addr, Addr}, {port, Port}, {streamid, StateData#state.streamid}, {tls, StateData#state.tls}, {tls_enabled, StateData#state.tls_enabled}, {tls_options, StateData#state.tls_options}, {authenticated, StateData#state.authenticated}, {shaper, StateData#state.shaper}, {sockmod, SockMod}, {domains, Domains} ], Reply = {state_infos, Infos}, {reply,Reply,StateName,StateData}; %%---------------------------------------------------------------------- %% Func: handle_sync_event/4 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {reply, Reply, NextStateName, NextStateData} | %% {reply, Reply, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- handle_sync_event(_Event, _From, StateName, StateData) -> Reply = ok, {reply, Reply, StateName, StateData}. code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: handle_info/3 %% Returns: {next_state, NextStateName, NextStateData} | %% {next_state, NextStateName, NextStateData, Timeout} | %% {stop, Reason, NewStateData} %%---------------------------------------------------------------------- handle_info({send_text, Text}, StateName, StateData) -> send_text(StateData, Text), {next_state, StateName, StateData}; handle_info({timeout, Timer, _}, _StateName, #state{timer = Timer} = StateData) -> {stop, normal, StateData}; handle_info(_, StateName, StateData) -> {next_state, StateName, StateData}. %%---------------------------------------------------------------------- %% Func: terminate/3 %% Purpose: Shutdown the fsm %% Returns: any %%---------------------------------------------------------------------- terminate(Reason, _StateName, StateData) -> ?DEBUG("terminated: ~p", [Reason]), case Reason of {process_limit, _} -> [ejabberd_s2s:external_host_overloaded(Host) || Host <- get_external_hosts(StateData)]; _ -> ok end, (StateData#state.sockmod):close(StateData#state.socket), ok. get_external_hosts(StateData) -> case StateData#state.authenticated of true -> [StateData#state.auth_domain]; false -> Connections = StateData#state.connections, [D || {{D, _}, established} <- dict:to_list(Connections)] end. %%---------------------------------------------------------------------- %% Func: print_state/1 %% Purpose: Prepare the state to be printed on error log %% Returns: State to print %%---------------------------------------------------------------------- print_state(State) -> State. %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- send_text(StateData, Text) -> (StateData#state.sockmod):send(StateData#state.socket, Text). send_element(StateData, El) -> send_text(StateData, xml:element_to_binary(El)). change_shaper(StateData, Host, JID) -> Shaper = acl:match_rule(Host, StateData#state.shaper, JID), (StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper). new_id() -> randoms:get_string(). cancel_timer(Timer) -> erlang:cancel_timer(Timer), receive {timeout, Timer, _} -> ok after 0 -> ok end. is_key_packet({xmlelement, Name, Attrs, Els}) when Name == "db:result" -> {key, xml:get_attr_s("to", Attrs), xml:get_attr_s("from", Attrs), xml:get_attr_s("id", Attrs), xml:get_cdata(Els)}; is_key_packet({xmlelement, Name, Attrs, Els}) when Name == "db:verify" -> {verify, xml:get_attr_s("to", Attrs), xml:get_attr_s("from", Attrs), xml:get_attr_s("id", Attrs), xml:get_cdata(Els)}; is_key_packet(_) -> false. get_cert_domains(Cert) -> {rdnSequence, Subject} = (Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.subject, Extensions = (Cert#'Certificate'.tbsCertificate)#'TBSCertificate'.extensions, lists:flatmap( fun(#'AttributeTypeAndValue'{type = ?'id-at-commonName', value = Val}) -> case ?PKIXEXPLICIT:decode('X520CommonName', Val) of {ok, {_, D1}} -> D = if is_list(D1) -> D1; is_binary(D1) -> binary_to_list(D1); true -> error end, if D /= error -> case jlib:string_to_jid(D) of #jid{luser = "", lserver = LD, lresource = ""} -> [LD]; _ -> [] end; true -> [] end; _ -> [] end; (_) -> [] end, lists:flatten(Subject)) ++ lists:flatmap( fun(#'Extension'{extnID = ?'id-ce-subjectAltName', extnValue = Val}) -> BVal = if is_list(Val) -> list_to_binary(Val); is_binary(Val) -> Val; true -> Val end, case ?PKIXIMPLICIT:decode('SubjectAltName', BVal) of {ok, SANs} -> lists:flatmap( fun({otherName, #'AnotherName'{'type-id' = ?'id-on-xmppAddr', value = XmppAddr }}) -> case 'XmppAddr':decode( 'XmppAddr', XmppAddr) of {ok, D} when is_binary(D) -> case jlib:string_to_jid( binary_to_list(D)) of #jid{luser = "", lserver = LD, lresource = ""} -> case idna:domain_utf8_to_ascii(LD) of false -> []; PCLD -> [PCLD] end; _ -> [] end; _ -> [] end; ({dNSName, D}) when is_list(D) -> case jlib:string_to_jid(D) of #jid{luser = "", lserver = LD, lresource = ""} -> [LD]; _ -> [] end; (_) -> [] end, SANs); _ -> [] end; (_) -> [] end, Extensions). match_domain(Domain, Domain) -> true; match_domain(Domain, Pattern) -> DLabels = string:tokens(Domain, "."), PLabels = string:tokens(Pattern, "."), match_labels(DLabels, PLabels). match_labels([], []) -> true; match_labels([], [_ | _]) -> false; match_labels([_ | _], []) -> false; match_labels([DL | DLabels], [PL | PLabels]) -> case lists:all(fun(C) -> (($a =< C) andalso (C =< $z)) orelse (($0 =< C) andalso (C =< $9)) orelse (C == $-) orelse (C == $*) end, PL) of true -> Regexp = ejabberd_regexp:sh_to_awk(PL), case ejabberd_regexp:run(DL, Regexp) of match -> match_labels(DLabels, PLabels); nomatch -> false end; false -> false end. ejabberd-2.1.11/src/configure0000775000000000000000000053656712240230175012742 0ustar #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.68 for ejabberd 2.1.x. # # Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: ejabberd@process-one.net about your system, including $0: any error possibly output before this message. Then $0: install a modern shell, or manually run the script $0: under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ejabberd' PACKAGE_TARNAME='ejabberd' PACKAGE_VERSION='2.1.x' PACKAGE_STRING='ejabberd 2.1.x' PACKAGE_BUGREPORT='ejabberd@process-one.net' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_default_prefix=/ ac_subst_vars='LTLIBOBJS ERLCFLAGS target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build md2 INSTALLUSER SSL_CFLAGS SSL_LIBS nif full_xml transient_supervisors db_type roster_gateway_workaround hipe PAM_LIBS PAM_CFLAGS make_pam pam ZLIB_LIBS ZLIB_CFLAGS make_ejabberd_zlib ejabberd_zlib make_web web make_tls tls make_odbc odbc make_eldap eldap make_mod_pubsub mod_pubsub make_mod_proxy65 mod_proxy65 make_mod_muc mod_muc make_mod_irc mod_irc LIBOBJS EXPAT_LIBS EXPAT_CFLAGS EGREP GREP CPP LIBICONV ERLANG_SSLVER ERLANG_LIBS ERLANG_CFLAGS ERL ERLC SET_MAKE OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking with_erlang with_libiconv_prefix with_expat enable_mod_irc enable_mod_muc enable_mod_proxy65 enable_mod_pubsub enable_eldap enable_odbc enable_tls enable_web enable_ejabberd_zlib with_zlib enable_pam with_pam enable_hipe enable_roster_gateway_workaround enable_mssql enable_transient_supervisors enable_full_xml enable_nif with_openssl enable_user ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP ERLC ERLCFLAGS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures ejabberd 2.1.x to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/ejabberd] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of ejabberd 2.1.x:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-mod_irc enable mod_irc (default: yes) --enable-mod_muc enable mod_muc (default: yes) --enable-mod_proxy65 enable mod_proxy65 (default: yes) --enable-mod_pubsub enable mod_pubsub (default: yes) --enable-eldap enable eldap (default: yes) --enable-odbc enable odbc (default: no) --enable-tls enable tls (default: yes) --enable-web enable web (default: yes) --enable-ejabberd_zlib enable ejabberd_zlib (default: yes) --enable-pam enable pam (default: no) --enable-hipe compile natively with HiPE, not recommended (default: no) --enable-roster-gateway-workaround turn on workaround for processing gateway subscriptions (default: no) --enable-mssql use Microsoft SQL Server database (default: no, requires --enable-odbc) --enable-transient_supervisors use Erlang supervision for transient process (default: yes) --enable-full-xml use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients) --enable-nif replace some functions with C equivalents. Requires Erlang R13B04 or higher (default: no) --enable-user[[[=USER]]] allow this system user to start ejabberd (default: no) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-erlang=PREFIX path to erlc and erl --with-libiconv-prefix=PREFIX prefix where libiconv is installed --with-expat=PREFIX prefix where EXPAT is installed --with-zlib=PREFIX prefix where zlib is installed --with-pam=PREFIX prefix where PAM is installed --with-openssl=PREFIX prefix where OPENSSL is installed Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor ERLC Erlang/OTP compiler command [autodetected] ERLCFLAGS Erlang/OTP compiler flags [none] Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF ejabberd configure 2.1.x generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## --------------------------------------- ## ## Report this to ejabberd@process-one.net ## ## --------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_erl_try_run LINENO # ------------------------ # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_erl_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_erl_try_run cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by ejabberd $as_me 2.1.x, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Checks for programs. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi if test "x$GCC" = "xyes"; then CFLAGS="$CFLAGS -Wall" fi #locating erlang # Check whether --with-erlang was given. if test "${with_erlang+set}" = set; then : withval=$with_erlang; fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}erlc", so it can be a program name with args. set dummy ${ac_tool_prefix}erlc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ERLC+:} false; then : $as_echo_n "(cached) " >&6 else case $ERLC in [\\/]* | ?:[\\/]*) ac_cv_path_ERLC="$ERLC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="$with_erlang:$with_erlang/bin:$PATH" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ERLC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ERLC=$ac_cv_path_ERLC if test -n "$ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5 $as_echo "$ERLC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_ERLC"; then ac_pt_ERLC=$ERLC # Extract the first word of "erlc", so it can be a program name with args. set dummy erlc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_ERLC+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_ERLC in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_ERLC="$ac_pt_ERLC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="$with_erlang:$with_erlang/bin:$PATH" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ac_pt_ERLC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_ERLC=$ac_cv_path_ac_pt_ERLC if test -n "$ac_pt_ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERLC" >&5 $as_echo "$ac_pt_ERLC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_ERLC" = x; then ERLC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac ERLC=$ac_pt_ERLC fi else ERLC="$ac_cv_path_ERLC" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}erl", so it can be a program name with args. set dummy ${ac_tool_prefix}erl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ERL+:} false; then : $as_echo_n "(cached) " >&6 else case $ERL in [\\/]* | ?:[\\/]*) ac_cv_path_ERL="$ERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="$with_erlang:$with_erlang/bin:$PATH" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ERL=$ac_cv_path_ERL if test -n "$ERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERL" >&5 $as_echo "$ERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_ERL"; then ac_pt_ERL=$ERL # Extract the first word of "erl", so it can be a program name with args. set dummy erl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_ERL+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_ERL in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_ERL="$ac_pt_ERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_dummy="$with_erlang:$with_erlang/bin:$PATH" for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ac_pt_ERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_ERL=$ac_cv_path_ac_pt_ERL if test -n "$ac_pt_ERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERL" >&5 $as_echo "$ac_pt_ERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_ERL" = x; then ERL="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac ERL=$ac_pt_ERL fi else ERL="$ac_cv_path_ERL" fi if test "z$ERLC" = "z" || test "z$ERL" = "z"; then as_fn_error $? "erlang not found" "$LINENO" 5 fi cat >>conftest.erl <<_EOF -module(conftest). -author('alexey@sevcom.net'). -export([start/0]). start() -> EIDirS = code:lib_dir("erl_interface") ++ "\n", EILibS = libpath("erl_interface") ++ "\n", RootDirS = code:root_dir() ++ "\n", file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ ssldef() ++ RootDirS)), halt(). ssldef() -> OTP = (catch erlang:system_info(otp_release)), if OTP >= "R14" -> "-DSSL40\n"; OTP >= "R12" -> "-DSSL39\n"; true -> "\n" end. %% return physical architecture based on OS/Processor archname() -> ArchStr = erlang:system_info(system_architecture), case os:type() of {win32, _} -> "windows"; {unix,UnixName} -> Specs = string:tokens(ArchStr,"-"), Cpu = case lists:nth(2,Specs) of "pc" -> "x86"; _ -> hd(Specs) end, atom_to_list(UnixName) ++ "-" ++ Cpu; _ -> "generic" end. %% Return arch-based library path or a default value if this directory %% does not exist libpath(App) -> PrivDir = code:priv_dir(App), ArchDir = archname(), LibArchDir = filename:join([PrivDir,"lib",ArchDir]), case file:list_dir(LibArchDir) of %% Arch lib dir exists: We use it {ok, _List} -> LibArchDir; %% Arch lib dir does not exist: Return the default value %% ({error, enoent}): _Error -> code:lib_dir("erl_interface") ++ "/lib" end. _EOF if ! $ERLC conftest.erl; then as_fn_error $? "could not compile sample program" "$LINENO" 5 fi if ! $ERL -s conftest -noshell; then as_fn_error $? "could not run sample program" "$LINENO" 5 fi if ! test -f conftest.out; then as_fn_error $? "erlang program was not properly executed, (conftest.out was not produced)" "$LINENO" 5 fi # First line ERLANG_EI_DIR=`cat conftest.out | head -n 1` # Second line ERLANG_EI_LIB=`cat conftest.out | head -n 2 | tail -n 1` # Third line ERLANG_SSLVER=`cat conftest.out | head -n 3 | tail -n 1` # End line ERLANG_DIR=`cat conftest.out | tail -n 1` ERLANG_CFLAGS="-I$ERLANG_EI_DIR/include -I$ERLANG_DIR/usr/include" ERLANG_LIBS="-L$ERLANG_EI_LIB -lerl_interface -lei" #locating iconv # Check whether --with-libiconv-prefix was given. if test "${with_libiconv_prefix+set}" = set; then : withval=$with_libiconv_prefix; for dir in `echo "$withval" | tr : ' '`; do if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi if test -d $dir/include; then CFLAGS="$CFLAGS -I$dir/include"; fi if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 $as_echo_n "checking for iconv... " >&6; } if ${am_cv_func_iconv+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS -liconv" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_lib_iconv=yes am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$am_save_LIBS" fi if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" am_save_CFLAGS="$CFLAGS" am_save_LDFLAGS="$LDFLAGS" LIBS="$LIBS -liconv" LDFLAGS="$LDFLAGS -L/usr/local/lib" CFLAGS="$CFLAGS -I/usr/local/include" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_lib_iconv=yes am_cv_func_iconv=yes CPPFLAGS="$CPPFLAGS -I/usr/local/include" else LDFLAGS="$am_save_LDFLAGS" CFLAGS="$am_save_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$am_save_LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 $as_echo "$am_cv_func_iconv" >&6; } if test "$am_cv_func_iconv" = yes; then $as_echo "#define HAVE_ICONV 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5 $as_echo_n "checking for iconv declaration... " >&6; } if ${am_cv_proto_iconv+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include extern #ifdef __cplusplus "C" #endif #if defined(__STDC__) || defined(__cplusplus) size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); #else size_t iconv(); #endif int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : am_cv_proto_iconv_arg1="" else am_cv_proto_iconv_arg1="const" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" fi am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_t:- }$am_cv_proto_iconv" >&5 $as_echo "${ac_t:- }$am_cv_proto_iconv" >&6; } cat >>confdefs.h <<_ACEOF #define ICONV_CONST $am_cv_proto_iconv_arg1 _ACEOF fi LIBICONV= if test "$am_cv_lib_iconv" = yes; then LIBICONV="-liconv" fi #locating libexpat ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Check whether --with-expat was given. if test "${with_expat+set}" = set; then : withval=$with_expat; fi EXPAT_CFLAGS= EXPAT_LIBS= if test x"$with_expat" != x; then EXPAT_CFLAGS="-I$with_expat/include" EXPAT_LIBS="-L$with_expat/lib" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML_ParserCreate in -lexpat" >&5 $as_echo_n "checking for XML_ParserCreate in -lexpat... " >&6; } if ${ac_cv_lib_expat_XML_ParserCreate+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lexpat "$EXPAT_LIBS" $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char XML_ParserCreate (); int main () { return XML_ParserCreate (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_expat_XML_ParserCreate=yes else ac_cv_lib_expat_XML_ParserCreate=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_expat_XML_ParserCreate" >&5 $as_echo "$ac_cv_lib_expat_XML_ParserCreate" >&6; } if test "x$ac_cv_lib_expat_XML_ParserCreate" = xyes; then : EXPAT_LIBS="$EXPAT_LIBS -lexpat" expat_found=yes else expat_found=no fi if test $expat_found = no; then as_fn_error $? "Could not find development files of Expat library" "$LINENO" 5 fi expat_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $EXPAT_CFLAGS" expat_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $EXPAT_CFLAGS" for ac_header in expat.h do : ac_fn_c_check_header_mongrel "$LINENO" "expat.h" "ac_cv_header_expat_h" "$ac_includes_default" if test "x$ac_cv_header_expat_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_EXPAT_H 1 _ACEOF else expat_found=no fi done if test $expat_found = no; then as_fn_error $? "Could not find expat.h" "$LINENO" 5 fi CFLAGS="$expat_save_CFLAGS" CPPFLAGS="$expat_save_CPPFLAGS" # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi # Check Erlang headers are installed #AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])]) # Change default prefix # Checks for library functions. for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDLIB_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 $as_echo_n "checking for GNU libc compatible malloc... " >&6; } if ${ac_cv_func_malloc_0_nonnull+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_malloc_0_nonnull=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *malloc (); #endif int main () { return ! malloc (0); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_malloc_0_nonnull=yes else ac_cv_func_malloc_0_nonnull=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5 $as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } if test $ac_cv_func_malloc_0_nonnull = yes; then : $as_echo "#define HAVE_MALLOC 1" >>confdefs.h else $as_echo "#define HAVE_MALLOC 0" >>confdefs.h case " $LIBOBJS " in *" malloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;; esac $as_echo "#define malloc rpl_malloc" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi mod_irc= make_mod_irc= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build mod_irc" >&5 $as_echo_n "checking whether build mod_irc... " >&6; } # Check whether --enable-mod_irc was given. if test "${enable_mod_irc+set}" = set; then : enableval=$enable_mod_irc; mr_enable_mod_irc="$enableval" else mr_enable_mod_irc=yes fi if test "$mr_enable_mod_irc" = "yes"; then mod_irc=mod_irc make_mod_irc=mod_irc/Makefile fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_mod_irc" >&5 $as_echo "$mr_enable_mod_irc" >&6; } mod_muc= make_mod_muc= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build mod_muc" >&5 $as_echo_n "checking whether build mod_muc... " >&6; } # Check whether --enable-mod_muc was given. if test "${enable_mod_muc+set}" = set; then : enableval=$enable_mod_muc; mr_enable_mod_muc="$enableval" else mr_enable_mod_muc=yes fi if test "$mr_enable_mod_muc" = "yes"; then mod_muc=mod_muc make_mod_muc=mod_muc/Makefile fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_mod_muc" >&5 $as_echo "$mr_enable_mod_muc" >&6; } mod_proxy65= make_mod_proxy65= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build mod_proxy65" >&5 $as_echo_n "checking whether build mod_proxy65... " >&6; } # Check whether --enable-mod_proxy65 was given. if test "${enable_mod_proxy65+set}" = set; then : enableval=$enable_mod_proxy65; mr_enable_mod_proxy65="$enableval" else mr_enable_mod_proxy65=yes fi if test "$mr_enable_mod_proxy65" = "yes"; then mod_proxy65=mod_proxy65 make_mod_proxy65=mod_proxy65/Makefile fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_mod_proxy65" >&5 $as_echo "$mr_enable_mod_proxy65" >&6; } mod_pubsub= make_mod_pubsub= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build mod_pubsub" >&5 $as_echo_n "checking whether build mod_pubsub... " >&6; } # Check whether --enable-mod_pubsub was given. if test "${enable_mod_pubsub+set}" = set; then : enableval=$enable_mod_pubsub; mr_enable_mod_pubsub="$enableval" else mr_enable_mod_pubsub=yes fi if test "$mr_enable_mod_pubsub" = "yes"; then mod_pubsub=mod_pubsub make_mod_pubsub=mod_pubsub/Makefile fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_mod_pubsub" >&5 $as_echo "$mr_enable_mod_pubsub" >&6; } eldap= make_eldap= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build eldap" >&5 $as_echo_n "checking whether build eldap... " >&6; } # Check whether --enable-eldap was given. if test "${enable_eldap+set}" = set; then : enableval=$enable_eldap; mr_enable_eldap="$enableval" else mr_enable_eldap=yes fi if test "$mr_enable_eldap" = "yes"; then eldap=eldap make_eldap=eldap/Makefile fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_eldap" >&5 $as_echo "$mr_enable_eldap" >&6; } odbc= make_odbc= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build odbc" >&5 $as_echo_n "checking whether build odbc... " >&6; } # Check whether --enable-odbc was given. if test "${enable_odbc+set}" = set; then : enableval=$enable_odbc; mr_enable_odbc="$enableval" else mr_enable_odbc=no fi if test "$mr_enable_odbc" = "yes"; then odbc=odbc make_odbc=odbc/Makefile fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_odbc" >&5 $as_echo "$mr_enable_odbc" >&6; } tls= make_tls= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build tls" >&5 $as_echo_n "checking whether build tls... " >&6; } # Check whether --enable-tls was given. if test "${enable_tls+set}" = set; then : enableval=$enable_tls; mr_enable_tls="$enableval" else mr_enable_tls=yes fi if test "$mr_enable_tls" = "yes"; then tls=tls make_tls=tls/Makefile fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_tls" >&5 $as_echo "$mr_enable_tls" >&6; } web= make_web= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build web" >&5 $as_echo_n "checking whether build web... " >&6; } # Check whether --enable-web was given. if test "${enable_web+set}" = set; then : enableval=$enable_web; mr_enable_web="$enableval" else mr_enable_web=yes fi if test "$mr_enable_web" = "yes"; then web=web make_web=web/Makefile fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_web" >&5 $as_echo "$mr_enable_web" >&6; } ejabberd_zlib= make_ejabberd_zlib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build ejabberd_zlib" >&5 $as_echo_n "checking whether build ejabberd_zlib... " >&6; } # Check whether --enable-ejabberd_zlib was given. if test "${enable_ejabberd_zlib+set}" = set; then : enableval=$enable_ejabberd_zlib; mr_enable_ejabberd_zlib="$enableval" else mr_enable_ejabberd_zlib=yes fi if test "$mr_enable_ejabberd_zlib" = "yes"; then ejabberd_zlib=ejabberd_zlib make_ejabberd_zlib=ejabberd_zlib/Makefile fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_ejabberd_zlib" >&5 $as_echo "$mr_enable_ejabberd_zlib" >&6; } #locating zlib # Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then : withval=$with_zlib; fi if test x"$ejabberd_zlib" != x; then ZLIB_CFLAGS= ZLIB_LIBS= if test x"$with_zlib" != x; then ZLIB_CFLAGS="-I$with_zlib/include" ZLIB_LIBS="-L$with_zlib/lib" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzgets in -lz" >&5 $as_echo_n "checking for gzgets in -lz... " >&6; } if ${ac_cv_lib_z_gzgets+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz "$ZLIB_LIBS" $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gzgets (); int main () { return gzgets (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_z_gzgets=yes else ac_cv_lib_z_gzgets=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzgets" >&5 $as_echo "$ac_cv_lib_z_gzgets" >&6; } if test "x$ac_cv_lib_z_gzgets" = xyes; then : ZLIB_LIBS="$ZLIB_LIBS -lz" zlib_found=yes else zlib_found=no fi if test $zlib_found = no; then as_fn_error $? "Could not find development files of zlib library. Install them or disable \`ejabberd_zlib' with: --disable-ejabberd_zlib" "$LINENO" 5 fi zlib_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $ZLIB_CFLAGS" zlib_save_CPPFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" for ac_header in zlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ZLIB_H 1 _ACEOF else zlib_found=no fi done if test $zlib_found = no; then as_fn_error $? "Could not find zlib.h. Install it or disable \`ejabberd_zlib' with: --disable-ejabberd_zlib" "$LINENO" 5 fi CFLAGS="$zlib_save_CFLAGS" CPPFLAGS="$zlib_save_CPPFLAGS" fi pam= make_pam= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build pam" >&5 $as_echo_n "checking whether build pam... " >&6; } # Check whether --enable-pam was given. if test "${enable_pam+set}" = set; then : enableval=$enable_pam; mr_enable_pam="$enableval" else mr_enable_pam=no fi if test "$mr_enable_pam" = "yes"; then pam=pam make_pam=pam/Makefile fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mr_enable_pam" >&5 $as_echo "$mr_enable_pam" >&6; } #locating PAM # Check whether --with-pam was given. if test "${with_pam+set}" = set; then : withval=$with_pam; fi if test x"$pam" != x; then PAM_CFLAGS= PAM_LIBS= if test x"$with_pam" != x; then PAM_CFLAGS="-I$with_pam/include" PAM_LIBS="-L$with_pam/lib" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam_start in -lpam" >&5 $as_echo_n "checking for pam_start in -lpam... " >&6; } if ${ac_cv_lib_pam_pam_start+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam "$PAM_LIBS" $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pam_start (); int main () { return pam_start (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pam_pam_start=yes else ac_cv_lib_pam_pam_start=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pam_pam_start" >&5 $as_echo "$ac_cv_lib_pam_pam_start" >&6; } if test "x$ac_cv_lib_pam_pam_start" = xyes; then : PAM_LIBS="$PAM_LIBS -lpam" pam_found=yes else pam_found=no fi if test $pam_found = no; then as_fn_error $? "Could not find development files of PAM library. Install them or disable \`pam' with: --disable-pam" "$LINENO" 5 fi pam_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PAM_CFLAGS" pam_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $PAM_CFLAGS" for ac_header in security/pam_appl.h do : ac_fn_c_check_header_mongrel "$LINENO" "security/pam_appl.h" "ac_cv_header_security_pam_appl_h" "$ac_includes_default" if test "x$ac_cv_header_security_pam_appl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SECURITY_PAM_APPL_H 1 _ACEOF else pam_found=no fi done if test $pam_found = no; then as_fn_error $? "Could not find security/pam_appl.h. Install it or disable \`pam' with: --disable-pam" "$LINENO" 5 fi CFLAGS="$pam_save_CFLAGS" CPPFLAGS="$pam_save_CPPFLAGS" fi # Check whether --enable-hipe was given. if test "${enable_hipe+set}" = set; then : enableval=$enable_hipe; case "${enableval}" in yes) hipe=true ;; no) hipe=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-hipe" "$LINENO" 5 ;; esac else hipe=false fi # Check whether --enable-roster_gateway_workaround was given. if test "${enable_roster_gateway_workaround+set}" = set; then : enableval=$enable_roster_gateway_workaround; case "${enableval}" in yes) roster_gateway_workaround=true ;; no) roster_gateway_workaround=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-roster-gateway-workaround" "$LINENO" 5 ;; esac else roster_gateway_workaround=false fi # Check whether --enable-mssql was given. if test "${enable_mssql+set}" = set; then : enableval=$enable_mssql; case "${enableval}" in yes) db_type=mssql ;; no) db_type=generic ;; *) as_fn_error $? "bad value ${enableval} for --enable-mssql" "$LINENO" 5 ;; esac else db_type=generic fi # Check whether --enable-transient_supervisors was given. if test "${enable_transient_supervisors+set}" = set; then : enableval=$enable_transient_supervisors; case "${enableval}" in yes) transient_supervisors=true ;; no) transient_supervisors=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-transient_supervisors" "$LINENO" 5 ;; esac else transient_supervisors=true fi # Check whether --enable-full_xml was given. if test "${enable_full_xml+set}" = set; then : enableval=$enable_full_xml; case "${enableval}" in yes) full_xml=true ;; no) full_xml=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-full-xml" "$LINENO" 5 ;; esac else full_xml=false fi # Check whether --enable-nif was given. if test "${enable_nif+set}" = set; then : enableval=$enable_nif; case "${enableval}" in yes) nif=true ;; no) nif=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-nif" "$LINENO" 5 ;; esac else nif=false fi ac_config_files="$ac_config_files Makefile $make_mod_irc $make_mod_muc $make_mod_pubsub $make_mod_proxy65 $make_eldap $make_pam $make_web stringprep/Makefile stun/Makefile $make_tls $make_odbc $make_ejabberd_zlib" #openssl # Check whether --with-openssl was given. if test "${with_openssl+set}" = set; then : withval=$with_openssl; fi unset SSL_LIBS; unset SSL_CFLAGS; have_openssl=no if test x"$tls" != x; then for ssl_prefix in $withval /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr; do printf "looking for openssl in $ssl_prefix...\n" SSL_CFLAGS="-I$ssl_prefix/include" SSL_LIBS="-L$ssl_prefix/lib -lcrypto" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_new in -lssl" >&5 $as_echo_n "checking for SSL_new in -lssl... " >&6; } if ${ac_cv_lib_ssl_SSL_new+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lssl $SSL_LIBS $SSL_CFLAGS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SSL_new (); int main () { return SSL_new (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ssl_SSL_new=yes else ac_cv_lib_ssl_SSL_new=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_new" >&5 $as_echo "$ac_cv_lib_ssl_SSL_new" >&6; } if test "x$ac_cv_lib_ssl_SSL_new" = xyes; then : have_openssl=yes else have_openssl=no fi if test x"$have_openssl" = xyes; then save_CPPFLAGS=$CPPFLAGS CPPFLAGS="-I$ssl_prefix/include $CPPFLAGS" for ac_header in openssl/ssl.h do : ac_fn_c_check_header_mongrel "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default" if test "x$ac_cv_header_openssl_ssl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_OPENSSL_SSL_H 1 _ACEOF have_openssl_h=yes fi done CPPFLAGS=$save_CPPFLAGS if test x"$have_openssl_h" = xyes; then have_openssl=yes printf "openssl found in $ssl_prefix\n"; SSL_LIBS="-L$ssl_prefix/lib -lssl -lcrypto" CPPFLAGS="-I$ssl_prefix/include $CPPFLAGS" SSL_CFLAGS="-DHAVE_SSL" break fi else # Clear this from the autoconf cache, so in the next pass of # this loop with different -L arguments, it will test again. unset ac_cv_lib_ssl_SSL_new fi done if test x${have_openssl} != xyes; then as_fn_error $? "Could not find development files of OpenSSL library. Install them or disable \`tls' with: --disable-tls" "$LINENO" 5 fi fi # If ssl is kerberized it need krb5.h # On RedHat and OpenBSD, krb5.h is in an unsual place: KRB5_INCLUDE="`krb5-config --cflags 2>/dev/null`" if test -n "$KRB5_INCLUDE" ; then CPPFLAGS="$CPPFLAGS $KRB5_INCLUDE" else # For RedHat For BSD for D in /usr/kerberos/include /usr/include/kerberos /usr/include/kerberosV do if test -d $D ; then CPPFLAGS="$CPPFLAGS -I$D" fi done fi ac_fn_c_check_header_mongrel "$LINENO" "krb5.h" "ac_cv_header_krb5_h" "$ac_includes_default" if test "x$ac_cv_header_krb5_h" = xyes; then : fi ENABLEUSER="" # Check whether --enable-user was given. if test "${enable_user+set}" = set; then : enableval=$enable_user; case "${enableval}" in yes) ENABLEUSER=`whoami` ;; no) ENABLEUSER="" ;; *) ENABLEUSER=$enableval esac fi if test "$ENABLEUSER" != ""; then echo "allow this system user to start ejabberd: $ENABLEUSER" INSTALLUSER=$ENABLEUSER fi ac_fn_c_check_header_mongrel "$LINENO" "openssl/md2.h" "ac_cv_header_openssl_md2_h" "$ac_includes_default" if test "x$ac_cv_header_openssl_md2_h" = xyes; then : md2=true else md2=false fi ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- #AC_DEFINE_UNQUOTED(CPU_VENDOR_OS, "$target") #AC_SUBST(target_os) case "$target_os" in *darwin10*) echo "Target OS is 'Darwin10'" ac_ext=erl ac_compile='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5' ac_link='$ERLC $ERLCFLAGS -b beam conftest.$ac_ext >&5 && echo "#!/bin/sh" > conftest$ac_exeext && $as_echo "\"$ERL\" -run conftest start -run init stop -noshell" >> conftest$ac_exeext && chmod +x conftest$ac_exeext' if test -n "$ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erlc" >&5 $as_echo_n "checking for erlc... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5 $as_echo "$ERLC" >&6; } else if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}erlc", so it can be a program name with args. set dummy ${ac_tool_prefix}erlc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ERLC+:} false; then : $as_echo_n "(cached) " >&6 else case $ERLC in [\\/]* | ?:[\\/]*) ac_cv_path_ERLC="$ERLC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ERLC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ERLC=$ac_cv_path_ERLC if test -n "$ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ERLC" >&5 $as_echo "$ERLC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_ERLC"; then ac_pt_ERLC=$ERLC # Extract the first word of "erlc", so it can be a program name with args. set dummy erlc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_ERLC+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_ERLC in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_ERLC="$ac_pt_ERLC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ac_pt_ERLC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_ERLC=$ac_cv_path_ac_pt_ERLC if test -n "$ac_pt_ERLC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_ERLC" >&5 $as_echo "$ac_pt_ERLC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_ERLC" = x; then ERLC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac ERLC=$ac_pt_ERLC fi else ERLC="$ac_cv_path_ERLC" fi fi if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat > conftest.$ac_ext <<_ACEOF -module(conftest). -export([start/0]). start() -> halt(case erlang:system_info(wordsize) of 8 -> 0; 4 -> 1 end) . _ACEOF if ac_fn_erl_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: found 64-bit Erlang" >&5 $as_echo "$as_me: found 64-bit Erlang" >&6;} CBIT=-m64 else { $as_echo "$as_me:${as_lineno-$LINENO}: found 32-bit Erlang" >&5 $as_echo "$as_me: found 32-bit Erlang" >&6;} CBIT=-m32 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ;; *) echo "Target OS is '$target_os'" CBIT="" ;; esac CFLAGS="$CFLAGS $CBIT" LD_SHARED="$LD_SHARED $CBIT" echo "CBIT is set to '$CBIT'" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by ejabberd $as_me 2.1.x, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ ejabberd config.status 2.1.x configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "$make_mod_irc") CONFIG_FILES="$CONFIG_FILES $make_mod_irc" ;; "$make_mod_muc") CONFIG_FILES="$CONFIG_FILES $make_mod_muc" ;; "$make_mod_pubsub") CONFIG_FILES="$CONFIG_FILES $make_mod_pubsub" ;; "$make_mod_proxy65") CONFIG_FILES="$CONFIG_FILES $make_mod_proxy65" ;; "$make_eldap") CONFIG_FILES="$CONFIG_FILES $make_eldap" ;; "$make_pam") CONFIG_FILES="$CONFIG_FILES $make_pam" ;; "$make_web") CONFIG_FILES="$CONFIG_FILES $make_web" ;; "stringprep/Makefile") CONFIG_FILES="$CONFIG_FILES stringprep/Makefile" ;; "stun/Makefile") CONFIG_FILES="$CONFIG_FILES stun/Makefile" ;; "$make_tls") CONFIG_FILES="$CONFIG_FILES $make_tls" ;; "$make_odbc") CONFIG_FILES="$CONFIG_FILES $make_odbc" ;; "$make_ejabberd_zlib") CONFIG_FILES="$CONFIG_FILES $make_ejabberd_zlib" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi ejabberd-2.1.11/src/xml.c0000664000000000000000000001402412240230175011752 0ustar #include #include #include #ifdef SSL40 #define ENIF_ALLOC(SIZE) enif_alloc(SIZE) #define ENIF_FREE(PTR) enif_free(PTR) #define ENIF_REALLOC(PTR, SIZE) enif_realloc(PTR, SIZE) #define ENIF_ALLOC_BINARY(SIZE, BIN) enif_alloc_binary(SIZE, BIN) #define ENIF_COMPARE(TERM1, TERM2) enif_compare(TERM1, TERM2) #else #define ENIF_ALLOC(SIZE) enif_alloc(env, SIZE) #define ENIF_FREE(PTR) enif_free(env, PTR) #define ENIF_REALLOC(PTR, SIZE) enif_realloc(env, PTR, SIZE) #define ENIF_ALLOC_BINARY(SIZE, BIN) enif_alloc_binary(env, SIZE, BIN) #define ENIF_COMPARE(TERM1, TERM2) enif_compare(env, TERM1, TERM2) #endif static ERL_NIF_TERM atom_xmlelement; static ERL_NIF_TERM atom_xmlcdata; struct buf { int limit; int len; unsigned char *b; }; static int make_element(ErlNifEnv* env, struct buf *rbuf, ERL_NIF_TERM el); static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info) { atom_xmlelement = enif_make_atom(env, "xmlelement"); atom_xmlcdata = enif_make_atom(env, "xmlcdata"); return 0; } static struct buf *init_buf(ErlNifEnv* env) { struct buf *rbuf = ENIF_ALLOC(sizeof(struct buf)); rbuf->limit = 1024; rbuf->len = 0; rbuf->b = ENIF_ALLOC(rbuf->limit); return rbuf; } static void destroy_buf(ErlNifEnv* env, struct buf *rbuf) { if (rbuf) { if (rbuf->b) { ENIF_FREE(rbuf->b); }; ENIF_FREE(rbuf); }; } inline void resize_buf(ErlNifEnv* env, struct buf *rbuf, int len_to_add) { int new_len = rbuf->len + len_to_add; if (new_len >= rbuf->limit) { rbuf->limit = ((new_len / 1024) + 1) * 1024; rbuf->b = ENIF_REALLOC(rbuf->b, rbuf->limit); }; } static void buf_add_char(ErlNifEnv* env, struct buf *rbuf, unsigned char c) { resize_buf(env, rbuf, 1); (rbuf->b)[rbuf->len] = c; rbuf->len += 1; } static void buf_add_str(ErlNifEnv* env, struct buf *rbuf, char *data, int len) { resize_buf(env, rbuf, len); memcpy(rbuf->b + rbuf->len, data, len); rbuf->len += len; } inline void crypt(ErlNifEnv* env, struct buf *rbuf, unsigned char *data, int len) { int i; for (i = 0; i < len; i++) { switch (data[i]) { case '&': buf_add_str(env, rbuf, "&", 5); break; case '<': buf_add_str(env, rbuf, "<", 4); break; case '>': buf_add_str(env, rbuf, ">", 4); break; case '"': buf_add_str(env, rbuf, """, 6); break; case '\'': buf_add_str(env, rbuf, "'", 6); break; default: buf_add_char(env, rbuf, data[i]); break; }; }; } static int make_elements(ErlNifEnv* env, struct buf *rbuf, ERL_NIF_TERM els) { ERL_NIF_TERM head, tail; int ret = 0; while (enif_get_list_cell(env, els, &head, &tail)) { ret = make_element(env, rbuf, head); if (ret) { els = tail; } else { break; }; }; return ret; } static int make_attrs(ErlNifEnv* env, struct buf *rbuf, ERL_NIF_TERM attrs) { ErlNifBinary name, data; ERL_NIF_TERM head, tail; const ERL_NIF_TERM *tuple; int arity, ret = 1; while (enif_get_list_cell(env, attrs, &head, &tail)) { if (enif_get_tuple(env, head, &arity, &tuple)) { if (arity == 2) { if (enif_inspect_iolist_as_binary(env, tuple[0], &name) && enif_inspect_iolist_as_binary(env, tuple[1], &data)) { buf_add_char(env, rbuf, ' '); buf_add_str(env, rbuf, (char *)name.data, name.size); buf_add_str(env, rbuf, "='", 2); crypt(env, rbuf, data.data, data.size); buf_add_char(env, rbuf, '\''); attrs = tail; } else { ret = 0; break; }; } else { ret = 0; break; }; } else { ret = 0; break; }; }; return ret; } static int make_element(ErlNifEnv* env, struct buf *rbuf, ERL_NIF_TERM el) { ErlNifBinary cdata, name; const ERL_NIF_TERM *tuple; int arity, ret = 0; if (enif_get_tuple(env, el, &arity, &tuple)) { if (arity == 2) { if (!ENIF_COMPARE(tuple[0], atom_xmlcdata)) { if (enif_inspect_iolist_as_binary(env, tuple[1], &cdata)) { crypt(env, rbuf, cdata.data, cdata.size); ret = 1; }; }; }; if (arity == 4) { if (!ENIF_COMPARE(tuple[0], atom_xmlelement)) { if (enif_inspect_iolist_as_binary(env, tuple[1], &name)) { buf_add_char(env, rbuf, '<'); buf_add_str(env, rbuf, (char *)name.data, name.size); ret = make_attrs(env, rbuf, tuple[2]); if (ret) { if (enif_is_empty_list(env, tuple[3])) { buf_add_str(env, rbuf, "/>", 2); } else { buf_add_char(env, rbuf, '>'); ret = make_elements(env, rbuf, tuple[3]); if (ret) { buf_add_str(env, rbuf, "'); }; }; }; }; }; }; }; return ret; } static ERL_NIF_TERM element_to(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[], int as_string) { ErlNifBinary output; ERL_NIF_TERM result; struct buf *rbuf; if (argc == 1) { rbuf = init_buf(env); if (make_element(env, rbuf, argv[0])) { if (as_string) { (rbuf->b)[rbuf->len] = 0; result = enif_make_string(env, (char *) rbuf->b, ERL_NIF_LATIN1); destroy_buf(env, rbuf); return result; } else { if (ENIF_ALLOC_BINARY(rbuf->len, &output)) { memcpy(output.data, rbuf->b, rbuf->len); result = enif_make_binary(env, &output); destroy_buf(env, rbuf); return result; }; }; }; destroy_buf(env, rbuf); }; return enif_make_badarg(env); } #ifdef SSL40 static ERL_NIF_TERM element_to_string(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { return element_to(env, argc, argv, 1); } #endif static ERL_NIF_TERM element_to_binary(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { return element_to(env, argc, argv, 0); } static ErlNifFunc nif_funcs[] = { /* Stupid Erlang bug with enif_make_string() is fixed in R14A only (OTP-8685), so we can't use element_to_string in Erlang < R14A.*/ #ifdef SSL40 {"element_to_string", 1, element_to_string}, #endif {"element_to_binary", 1, element_to_binary} }; ERL_NIF_INIT(xml, nif_funcs, load, NULL, NULL, NULL) ejabberd-2.1.11/src/cache_tab_sup.erl0000664000000000000000000000357712240230175014305 0ustar %%%------------------------------------------------------------------- %%% File : cache_tab_sup.erl %%% Author : Evgeniy Khramtsov %%% Description : Cache tables supervisor %%% %%% Created : 30 Aug 2010 by Evgeniy Khramtsov %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%------------------------------------------------------------------- -module(cache_tab_sup). -behaviour(supervisor). %% API -export([start_link/0]). %% Supervisor callbacks -export([init/1]). -define(SERVER, ?MODULE). %%==================================================================== %% API functions %%==================================================================== start_link() -> supervisor:start_link({local, ?SERVER}, ?MODULE, []). %%==================================================================== %% Supervisor callbacks %%==================================================================== init([]) -> {ok, {{one_for_one,10,1}, []}}. %%==================================================================== %% Internal functions %%==================================================================== ejabberd-2.1.11/src/mod_vcard_xupdate_odbc.erl0000664000000000000000000001016512240230175016173 0ustar %%%---------------------------------------------------------------------- %%% File : mod_vcard_xupdate_odbc.erl %%% Author : Igor Goryachev %%% Purpose : Add avatar hash in presence on behalf of client (XEP-0153) %%% Created : 9 Mar 2007 by Igor Goryachev %%%---------------------------------------------------------------------- -module(mod_vcard_xupdate_odbc). -behaviour(gen_mod). %% gen_mod callbacks -export([start/2, stop/1]). %% hooks -export([update_presence/3, vcard_set/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). %%==================================================================== %% gen_mod callbacks %%==================================================================== start(Host, _Opts) -> ejabberd_hooks:add(c2s_update_presence, Host, ?MODULE, update_presence, 100), ejabberd_hooks:add(vcard_set, Host, ?MODULE, vcard_set, 100), ok. stop(Host) -> ejabberd_hooks:delete(c2s_update_presence, Host, ?MODULE, update_presence, 100), ejabberd_hooks:delete(vcard_set, Host, ?MODULE, vcard_set, 100), ok. %%==================================================================== %% Hooks %%==================================================================== update_presence({xmlelement, "presence", Attrs, _Els} = Packet, User, Host) -> case xml:get_attr_s("type", Attrs) of [] -> presence_with_xupdate(Packet, User, Host); _ -> Packet end; update_presence(Packet, _User, _Host) -> Packet. vcard_set(LUser, LServer, VCARD) -> US = {LUser, LServer}, case xml:get_path_s(VCARD, [{elem, "PHOTO"}, {elem, "BINVAL"}, cdata]) of [] -> remove_xupdate(LUser, LServer); BinVal -> add_xupdate(LUser, LServer, sha:sha(jlib:decode_base64(BinVal))) end, ejabberd_sm:force_update_presence(US). %%==================================================================== %% ODBC storage %%==================================================================== add_xupdate(LUser, LServer, Hash) -> Username = ejabberd_odbc:escape(LUser), SHash = ejabberd_odbc:escape(Hash), F = fun() -> odbc_queries:update_t( "vcard_xupdate", ["username", "hash"], [Username, SHash], ["username='", Username, "'"]) end, ejabberd_odbc:sql_transaction(LServer, F). get_xupdate(LUser, LServer) -> Username = ejabberd_odbc:escape(LUser), case ejabberd_odbc:sql_query( LServer, ["select hash from vcard_xupdate " "where username='", Username, "';"]) of {selected, ["hash"], [{Hash}]} -> Hash; _ -> undefined end. remove_xupdate(LUser, LServer) -> Username = ejabberd_odbc:escape(LUser), F = fun() -> ejabberd_odbc:sql_query_t( ["delete from vcard_xupdate where " "username='", Username, "';"]) end, ejabberd_odbc:sql_transaction(LServer, F). %%%---------------------------------------------------------------------- %%% Presence stanza rebuilding %%%---------------------------------------------------------------------- presence_with_xupdate({xmlelement, "presence", Attrs, Els}, User, Host) -> XPhotoEl = build_xphotoel(User, Host), Els2 = presence_with_xupdate2(Els, [], XPhotoEl), {xmlelement, "presence", Attrs, Els2}. presence_with_xupdate2([], Els2, XPhotoEl) -> lists:reverse([XPhotoEl | Els2]); %% This clause assumes that the x element contains only the XMLNS attribute: presence_with_xupdate2([{xmlelement, "x", [{"xmlns", ?NS_VCARD_UPDATE}], _} | Els], Els2, XPhotoEl) -> presence_with_xupdate2(Els, Els2, XPhotoEl); presence_with_xupdate2([El | Els], Els2, XPhotoEl) -> presence_with_xupdate2(Els, [El | Els2], XPhotoEl). build_xphotoel(User, Host) -> Hash = get_xupdate(User, Host), PhotoSubEls = case Hash of Hash when is_list(Hash) -> [{xmlcdata, Hash}]; _ -> [] end, PhotoEl = [{xmlelement, "photo", [], PhotoSubEls}], {xmlelement, "x", [{"xmlns", ?NS_VCARD_UPDATE}], PhotoEl}. ejabberd-2.1.11/src/ejabberd_commands.hrl0000664000000000000000000000377412240230175015146 0ustar %%%---------------------------------------------------------------------- %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -record(ejabberd_commands, {name, tags = [], desc = "", longdesc = "", module, function, args = [], result = rescode}). %% @type ejabberd_commands() = #ejabberd_commands{ %% name = atom(), %% tags = [atom()], %% desc = string(), %% longdesc = string(), %% module = atom(), %% function = atom(), %% args = [aterm()], %% result = rterm() %% }. %% desc: Description of the command %% args: Describe the accepted arguments. %% This way the function that calls the command can format the %% arguments before calling. %% @type atype() = integer | string | {tuple, [aterm()]} | {list, aterm()}. %% Allowed types for arguments are integer, string, tuple and list. %% @type rtype() = integer | string | atom | {tuple, [rterm()]} | {list, rterm()} | rescode | restuple. %% A rtype is either an atom or a tuple with two elements. %% @type aterm() = {Name::atom(), Type::atype()}. %% An argument term is a tuple with the term name and the term type. %% @type rterm() = {Name::atom(), Type::rtype()}. %% A result term is a tuple with the term name and the term type. ejabberd-2.1.11/src/XmppAddr.asn10000664000000000000000000000057712240230175013321 0ustar XmppAddr { iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) id-on(8) id-on-xmppAddr(5) } DEFINITIONS EXPLICIT TAGS ::= BEGIN id-on-xmppAddr OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) id-on(8) 5 } XmppAddr ::= UTF8String END ejabberd-2.1.11/src/jlib.erl0000664000000000000000000005203612240230175012437 0ustar %%%---------------------------------------------------------------------- %%% File : jlib.erl %%% Author : Alexey Shchepin %%% Purpose : General XMPP library. %%% Created : 23 Nov 2002 by Alexey Shchepin %%% %%% %%% ejabberd, Copyright (C) 2002-2012 ProcessOne %%% %%% 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., 59 Temple Place, Suite 330, Boston, MA %%% 02111-1307 USA %%% %%%---------------------------------------------------------------------- -module(jlib). -author('alexey@process-one.net'). -export([make_result_iq_reply/1, make_error_reply/3, make_error_reply/2, make_error_element/2, make_correct_from_to_attrs/3, replace_from_to_attrs/3, replace_from_to/3, replace_from_attrs/2, replace_from/2, remove_attr/2, make_jid/3, make_jid/1, string_to_jid/1, jid_to_string/1, is_nodename/1, tolower/1, nodeprep/1, nameprep/1, resourceprep/1, jid_tolower/1, jid_remove_resource/1, jid_replace_resource/2, get_iq_namespace/1, iq_query_info/1, iq_query_or_response_info/1, is_iq_request_type/1, iq_to_xml/1, parse_xdata_submit/1, timestamp_to_iso/1, % TODO: Remove once XEP-0091 is Obsolete timestamp_to_iso/2, timestamp_to_xml/4, timestamp_to_xml/1, % TODO: Remove once XEP-0091 is Obsolete now_to_utc_string/1, now_to_local_string/1, datetime_string_to_timestamp/1, decode_base64/1, encode_base64/1, ip_to_list/1, rsm_encode/1, rsm_encode/2, rsm_decode/1]). -include("jlib.hrl"). %send_iq(From, To, ID, SubTags) -> % ok. make_result_iq_reply({xmlelement, Name, Attrs, SubTags}) -> NewAttrs = make_result_iq_reply_attrs(Attrs), {xmlelement, Name, NewAttrs, SubTags}. make_result_iq_reply_attrs(Attrs) -> To = xml:get_attr("to", Attrs), From = xml:get_attr("from", Attrs), Attrs1 = lists:keydelete("to", 1, Attrs), Attrs2 = lists:keydelete("from", 1, Attrs1), Attrs3 = case To of {value, ToVal} -> [{"from", ToVal} | Attrs2]; _ -> Attrs2 end, Attrs4 = case From of {value, FromVal} -> [{"to", FromVal} | Attrs3]; _ -> Attrs3 end, Attrs5 = lists:keydelete("type", 1, Attrs4), Attrs6 = [{"type", "result"} | Attrs5], Attrs6. make_error_reply({xmlelement, Name, Attrs, SubTags}, Code, Desc) -> NewAttrs = make_error_reply_attrs(Attrs), {xmlelement, Name, NewAttrs, SubTags ++ [{xmlelement, "error", [{"code", Code}], [{xmlcdata, Desc}]}]}. make_error_reply({xmlelement, Name, Attrs, SubTags}, Error) -> NewAttrs = make_error_reply_attrs(Attrs), {xmlelement, Name, NewAttrs, SubTags ++ [Error]}. make_error_reply_attrs(Attrs) -> To = xml:get_attr("to", Attrs), From = xml:get_attr("from", Attrs), Attrs1 = lists:keydelete("to", 1, Attrs), Attrs2 = lists:keydelete("from", 1, Attrs1), Attrs3 = case To of {value, ToVal} -> [{"from", ToVal} | Attrs2]; _ -> Attrs2 end, Attrs4 = case From of {value, FromVal} -> [{"to", FromVal} | Attrs3]; _ -> Attrs3 end, Attrs5 = lists:keydelete("type", 1, Attrs4), Attrs6 = [{"type", "error"} | Attrs5], Attrs6. make_error_element(Code, Desc) -> {xmlelement, "error", [{"code", Code}], [{xmlcdata, Desc}]}. make_correct_from_to_attrs(From, To, Attrs) -> Attrs1 = lists:keydelete("from", 1, Attrs), Attrs2 = case xml:get_attr("to", Attrs) of {value, _} -> Attrs1; _ -> [{"to", To} | Attrs1] end, Attrs3 = [{"from", From} | Attrs2], Attrs3. replace_from_to_attrs(From, To, Attrs) -> Attrs1 = lists:keydelete("to", 1, Attrs), Attrs2 = lists:keydelete("from", 1, Attrs1), Attrs3 = [{"to", To} | Attrs2], Attrs4 = [{"from", From} | Attrs3], Attrs4. replace_from_to(From, To, {xmlelement, Name, Attrs, Els}) -> NewAttrs = replace_from_to_attrs(jlib:jid_to_string(From), jlib:jid_to_string(To), Attrs), {xmlelement, Name, NewAttrs, Els}. replace_from_attrs(From, Attrs) -> Attrs1 = lists:keydelete("from", 1, Attrs), [{"from", From} | Attrs1]. replace_from(From, {xmlelement, Name, Attrs, Els}) -> NewAttrs = replace_from_attrs(jlib:jid_to_string(From), Attrs), {xmlelement, Name, NewAttrs, Els}. remove_attr(Attr, {xmlelement, Name, Attrs, Els}) -> NewAttrs = lists:keydelete(Attr, 1, Attrs), {xmlelement, Name, NewAttrs, Els}. make_jid(User, Server, Resource) -> case nodeprep(User) of error -> error; LUser -> case nameprep(Server) of error -> error; LServer -> case resourceprep(Resource) of error -> error; LResource -> #jid{user = User, server = Server, resource = Resource, luser = LUser, lserver = LServer, lresource = LResource} end end end. make_jid({User, Server, Resource}) -> make_jid(User, Server, Resource). string_to_jid(J) -> string_to_jid1(J, ""). string_to_jid1([$@ | _J], "") -> error; string_to_jid1([$@ | J], N) -> string_to_jid2(J, lists:reverse(N), ""); string_to_jid1([$/ | _J], "") -> error; string_to_jid1([$/ | J], N) -> string_to_jid3(J, "", lists:reverse(N), ""); string_to_jid1([C | J], N) -> string_to_jid1(J, [C | N]); string_to_jid1([], "") -> error; string_to_jid1([], N) -> make_jid("", lists:reverse(N), ""). %% Only one "@" is admitted per JID string_to_jid2([$@ | _J], _N, _S) -> error; string_to_jid2([$/ | _J], _N, "") -> error; string_to_jid2([$/ | J], N, S) -> string_to_jid3(J, N, lists:reverse(S), ""); string_to_jid2([C | J], N, S) -> string_to_jid2(J, N, [C | S]); string_to_jid2([], _N, "") -> error; string_to_jid2([], N, S) -> make_jid(N, lists:reverse(S), ""). string_to_jid3([C | J], N, S, R) -> string_to_jid3(J, N, S, [C | R]); string_to_jid3([], N, S, R) -> make_jid(N, S, lists:reverse(R)). jid_to_string(#jid{user = User, server = Server, resource = Resource}) -> jid_to_string({User, Server, Resource}); jid_to_string({Node, Server, Resource}) -> S1 = case Node of "" -> ""; _ -> Node ++ "@" end, S2 = S1 ++ Server, S3 = case Resource of "" -> S2; _ -> S2 ++ "/" ++ Resource end, S3. is_nodename([]) -> false; is_nodename(J) -> nodeprep(J) /= error. %tolower_c(C) when C >= $A, C =< $Z -> % C + 32; %tolower_c(C) -> % C. -define(LOWER(Char), if Char >= $A, Char =< $Z -> Char + 32; true -> Char end). %tolower(S) -> % lists:map(fun tolower_c/1, S). %tolower(S) -> % [?LOWER(Char) || Char <- S]. % Not tail-recursive but it seems works faster than variants above tolower([C | Cs]) -> if C >= $A, C =< $Z -> [C + 32 | tolower(Cs)]; true -> [C | tolower(Cs)] end; tolower([]) -> []. %tolower([C | Cs]) when C >= $A, C =< $Z -> % [C + 32 | tolower(Cs)]; %tolower([C | Cs]) -> % [C | tolower(Cs)]; %tolower([]) -> % []. nodeprep(S) when length(S) < 1024 -> R = stringprep:nodeprep(S), if length(R) < 1024 -> R; true -> error end; nodeprep(_) -> error. nameprep(S) when length(S) < 1024 -> R = stringprep:nameprep(S), if length(R) < 1024 -> R; true -> error end; nameprep(_) -> error. resourceprep(S) when length(S) < 1024 -> R = stringprep:resourceprep(S), if length(R) < 1024 -> R; true -> error end; resourceprep(_) -> error. jid_tolower(#jid{luser = U, lserver = S, lresource = R}) -> {U, S, R}; jid_tolower({U, S, R}) -> case nodeprep(U) of error -> error; LUser -> case nameprep(S) of error -> error; LServer -> case resourceprep(R) of error -> error; LResource -> {LUser, LServer, LResource} end end end. jid_remove_resource(#jid{} = JID) -> JID#jid{resource = "", lresource = ""}; jid_remove_resource({U, S, _R}) -> {U, S, ""}. jid_replace_resource(JID, Resource) -> case resourceprep(Resource) of error -> error; LResource -> JID#jid{resource = Resource, lresource = LResource} end. get_iq_namespace({xmlelement, Name, _Attrs, Els}) when Name == "iq" -> case xml:remove_cdata(Els) of [{xmlelement, _Name2, Attrs2, _Els2}] -> xml:get_attr_s("xmlns", Attrs2); _ -> "" end; get_iq_namespace(_) -> "". %% @spec (xmlelement()) -> iq() | reply | invalid | not_iq iq_query_info(El) -> iq_info_internal(El, request). iq_query_or_response_info(El) -> iq_info_internal(El, any). iq_info_internal({xmlelement, Name, Attrs, Els}, Filter) when Name == "iq" -> %% Filter is either request or any. If it is request, any replies %% are converted to the atom reply. ID = xml:get_attr_s("id", Attrs), Type = xml:get_attr_s("type", Attrs), Lang = xml:get_attr_s("xml:lang", Attrs), {Type1, Class} = case Type of "set" -> {set, request}; "get" -> {get, request}; "result" -> {result, reply}; "error" -> {error, reply}; _ -> {invalid, invalid} end, if Type1 == invalid -> invalid; Class == request; Filter == any -> %% The iq record is a bit strange. The sub_el field is an %% XML tuple for requests, but a list of XML tuples for %% responses. FilteredEls = xml:remove_cdata(Els), {XMLNS, SubEl} = case {Class, FilteredEls} of {request, [{xmlelement, _Name2, Attrs2, _Els2}]} -> {xml:get_attr_s("xmlns", Attrs2), hd(FilteredEls)}; {reply, _} -> %% Find the namespace of the first non-error %% element, if there is one. NonErrorEls = [El || {xmlelement, SubName, _, _} = El <- FilteredEls, SubName /= "error"], {case NonErrorEls of [NonErrorEl] -> xml:get_tag_attr_s("xmlns", NonErrorEl); _ -> "" end, FilteredEls}; _ -> {"", []} end, if XMLNS == "", Class == request -> invalid; true -> #iq{id = ID, type = Type1, xmlns = XMLNS, lang = Lang, sub_el = SubEl} end; Class == reply, Filter /= any -> reply end; iq_info_internal(_, _) -> not_iq. is_iq_request_type(set) -> true; is_iq_request_type(get) -> true; is_iq_request_type(_) -> false. iq_type_to_string(set) -> "set"; iq_type_to_string(get) -> "get"; iq_type_to_string(result) -> "result"; iq_type_to_string(error) -> "error"; iq_type_to_string(_) -> invalid. iq_to_xml(#iq{id = ID, type = Type, sub_el = SubEl}) -> if ID /= "" -> {xmlelement, "iq", [{"id", ID}, {"type", iq_type_to_string(Type)}], SubEl}; true -> {xmlelement, "iq", [{"type", iq_type_to_string(Type)}], SubEl} end. parse_xdata_submit(El) -> {xmlelement, _Name, Attrs, Els} = El, case xml:get_attr_s("type", Attrs) of "submit" -> lists:reverse(parse_xdata_fields(Els, [])); "form" -> %% This is a workaround to accept Psi's wrong forms lists:reverse(parse_xdata_fields(Els, [])); _ -> invalid end. parse_xdata_fields([], Res) -> Res; parse_xdata_fields([{xmlelement, Name, Attrs, SubEls} | Els], Res) -> case Name of "field" -> case xml:get_attr_s("var", Attrs) of "" -> parse_xdata_fields(Els, Res); Var -> Field = {Var, lists:reverse(parse_xdata_values(SubEls, []))}, parse_xdata_fields(Els, [Field | Res]) end; _ -> parse_xdata_fields(Els, Res) end; parse_xdata_fields([_ | Els], Res) -> parse_xdata_fields(Els, Res). parse_xdata_values([], Res) -> Res; parse_xdata_values([{xmlelement, Name, _Attrs, SubEls} | Els], Res) -> case Name of "value" -> Val = xml:get_cdata(SubEls), parse_xdata_values(Els, [Val | Res]); _ -> parse_xdata_values(Els, Res) end; parse_xdata_values([_ | Els], Res) -> parse_xdata_values(Els, Res). rsm_decode(#iq{sub_el=SubEl})-> rsm_decode(SubEl); rsm_decode({xmlelement, _,_,_}=SubEl)-> case xml:get_subtag(SubEl,"set") of false -> none; {xmlelement, "set", _Attrs, SubEls}-> lists:foldl(fun rsm_parse_element/2, #rsm_in{}, SubEls) end. rsm_parse_element({xmlelement, "max",[], _}=Elem, RsmIn)-> CountStr = xml:get_tag_cdata(Elem), {Count, _} = string:to_integer(CountStr), RsmIn#rsm_in{max=Count}; rsm_parse_element({xmlelement, "before", [], _}=Elem, RsmIn)-> UID = xml:get_tag_cdata(Elem), RsmIn#rsm_in{direction=before, id=UID}; rsm_parse_element({xmlelement, "after", [], _}=Elem, RsmIn)-> UID = xml:get_tag_cdata(Elem), RsmIn#rsm_in{direction=aft, id=UID}; rsm_parse_element({xmlelement, "index",[], _}=Elem, RsmIn)-> IndexStr = xml:get_tag_cdata(Elem), {Index, _} = string:to_integer(IndexStr), RsmIn#rsm_in{index=Index}; rsm_parse_element(_, RsmIn)-> RsmIn. rsm_encode(#iq{sub_el=SubEl}=IQ,RsmOut)-> Set = {xmlelement, "set", [{"xmlns", ?NS_RSM}], lists:reverse(rsm_encode_out(RsmOut))}, {xmlelement, Name, Attrs, SubEls} = SubEl, New = {xmlelement, Name, Attrs, [Set | SubEls]}, IQ#iq{sub_el=New}. rsm_encode(none)-> []; rsm_encode(RsmOut)-> [{xmlelement, "set", [{"xmlns", ?NS_RSM}], lists:reverse(rsm_encode_out(RsmOut))}]. rsm_encode_out(#rsm_out{count=Count, index=Index, first=First, last=Last})-> El = rsm_encode_first(First, Index, []), El2 = rsm_encode_last(Last,El), rsm_encode_count(Count, El2). rsm_encode_first(undefined, undefined, Arr) -> Arr; rsm_encode_first(First, undefined, Arr) -> [{xmlelement, "first",[], [{xmlcdata, First}]}|Arr]; rsm_encode_first(First, Index, Arr) -> [{xmlelement, "first",[{"index", i2l(Index)}], [{xmlcdata, First}]}|Arr]. rsm_encode_last(undefined, Arr) -> Arr; rsm_encode_last(Last, Arr) -> [{xmlelement, "last",[], [{xmlcdata, Last}]}|Arr]. rsm_encode_count(undefined, Arr)-> Arr; rsm_encode_count(Count, Arr)-> [{xmlelement, "count",[], [{xmlcdata, i2l(Count)}]} | Arr]. i2l(I) when is_integer(I) -> integer_to_list(I); i2l(L) when is_list(L) -> L. %% Timezone = utc | {Sign::string(), {Hours, Minutes}} | {Hours, Minutes} %% Hours = integer() %% Minutes = integer() timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}}, Timezone) -> Timestamp_string = lists:flatten( io_lib:format("~4..0w-~2..0w-~2..0wT~2..0w:~2..0w:~2..0w", [Year, Month, Day, Hour, Minute, Second])), Timezone_string = case Timezone of utc -> "Z"; {Sign, {TZh, TZm}} -> io_lib:format("~s~2..0w:~2..0w", [Sign, TZh, TZm]); {TZh, TZm} -> Sign = case TZh >= 0 of true -> "+"; false -> "-" end, io_lib:format("~s~2..0w:~2..0w", [Sign, abs(TZh),TZm]) end, {Timestamp_string, Timezone_string}. timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}}) -> lists:flatten( io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w", [Year, Month, Day, Hour, Minute, Second])). timestamp_to_xml(DateTime, Timezone, FromJID, Desc) -> {T_string, Tz_string} = timestamp_to_iso(DateTime, Timezone), Text = [{xmlcdata, Desc}], From = jlib:jid_to_string(FromJID), {xmlelement, "delay", [{"xmlns", ?NS_DELAY}, {"from", From}, {"stamp", T_string ++ Tz_string}], Text}. %% TODO: Remove this function once XEP-0091 is Obsolete timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) -> {xmlelement, "x", [{"xmlns", ?NS_DELAY91}, {"stamp", lists:flatten( io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w", [Year, Month, Day, Hour, Minute, Second]))}], []}. now_to_utc_string({MegaSecs, Secs, MicroSecs}) -> {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:now_to_universal_time({MegaSecs, Secs, MicroSecs}), lists:flatten( io_lib:format("~4..0w-~2..0w-~2..0wT~2..0w:~2..0w:~2..0w.~6..0wZ", [Year, Month, Day, Hour, Minute, Second, MicroSecs])). now_to_local_string({MegaSecs, Secs, MicroSecs}) -> LocalTime = calendar:now_to_local_time({MegaSecs, Secs, MicroSecs}), UTCTime = calendar:now_to_universal_time({MegaSecs, Secs, MicroSecs}), Seconds = calendar:datetime_to_gregorian_seconds(LocalTime) - calendar:datetime_to_gregorian_seconds(UTCTime), {{H, M, _}, Sign} = if Seconds < 0 -> {calendar:seconds_to_time(-Seconds), "-"}; true -> {calendar:seconds_to_time(Seconds), "+"} end, {{Year, Month, Day}, {Hour, Minute, Second}} = LocalTime, lists:flatten( io_lib:format("~4..0w-~2..0w-~2..0wT~2..0w:~2..0w:~2..0w.~6..0w~s~2..0w:~2..0w", [Year, Month, Day, Hour, Minute, Second, MicroSecs, Sign, H, M])). % yyyy-mm-ddThh:mm:ss[.sss]{Z|{+|-}hh:mm} -> {MegaSecs, Secs, MicroSecs} datetime_string_to_timestamp(TimeStr) -> case catch parse_datetime(TimeStr) of {'EXIT', _Err} -> undefined; TimeStamp -> TimeStamp end. parse_datetime(TimeStr) -> [Date, Time] = string:tokens(TimeStr, "T"), D = parse_date(Date), {T, MS, TZH, TZM} = parse_time(Time), S = calendar:datetime_to_gregorian_seconds({D, T}), S1 = calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}), Seconds = (S - S1) - TZH * 60 * 60 - TZM * 60, {Seconds div 1000000, Seconds rem 1000000, MS}. % yyyy-mm-dd parse_date(Date) -> [Y, M, D] = string:tokens(Date, "-"), Date1 = {list_to_integer(Y), list_to_integer(M), list_to_integer(D)}, case calendar:valid_date(Date1) of true -> Date1; _ -> false end. % hh:mm:ss[.sss]TZD parse_time(Time) -> case string:str(Time, "Z") of 0 -> parse_time_with_timezone(Time); _ -> [T | _] = string:tokens(Time, "Z"), {TT, MS} = parse_time1(T), {TT, MS, 0, 0} end. parse_time_with_timezone(Time) -> case string:str(Time, "+") of 0 -> case string:str(Time, "-") of 0 -> false; _ -> parse_time_with_timezone(Time, "-") end; _ -> parse_time_with_timezone(Time, "+") end. parse_time_with_timezone(Time, Delim) -> [T, TZ] = string:tokens(Time, Delim), {TZH, TZM} = parse_timezone(TZ), {TT, MS} = parse_time1(T), case Delim of "-" -> {TT, MS, -TZH, -TZM}; "+" -> {TT, MS, TZH, TZM} end. parse_timezone(TZ) -> [H, M] = string:tokens(TZ, ":"), {[H1, M1], true} = check_list([{H, 12}, {M, 60}]), {H1, M1}. parse_time1(Time) -> [HMS | T] = string:tokens(Time, "."), MS = case T of [] -> 0; [Val] -> list_to_integer(string:left(Val, 6, $0)) end, [H, M, S] = string:tokens(HMS, ":"), {[H1, M1, S1], true} = check_list([{H, 24}, {M, 60}, {S, 60}]), {{H1, M1, S1}, MS}. check_list(List) -> lists:mapfoldl( fun({L, N}, B)-> V = list_to_integer(L), if (V >= 0) and (V =< N) -> {V, B}; true -> {false, false} end end, true, List). % % Base64 stuff (based on httpd_util.erl) % decode_base64(S) -> decode1_base64([C || C <- S, C /= $ , C /= $\t, C /= $\n, C /= $\r]). decode1_base64([]) -> []; decode1_base64([Sextet1,Sextet2,$=,$=|Rest]) -> Bits2x6= (d(Sextet1) bsl 18) bor (d(Sextet2) bsl 12), Octet1=Bits2x6 bsr 16, [Octet1|decode1_base64(Rest)]; decode1_base64([Sextet1,Sextet2,Sextet3,$=|Rest]) -> Bits3x6= (d(Sextet1) bsl 18) bor (d(Sextet2) bsl 12) bor (d(Sextet3) bsl 6), Octet1=Bits3x6 bsr 16, Octet2=(Bits3x6 bsr 8) band 16#ff, [Octet1,Octet2|decode1_base64(Rest)]; decode1_base64([Sextet1,Sextet2,Sextet3,Sextet4|Rest]) -> Bits4x6= (d(Sextet1) bsl 18) bor (d(Sextet2) bsl 12) bor (d(Sextet3) bsl 6) bor d(Sextet4), Octet1=Bits4x6 bsr 16, Octet2=(Bits4x6 bsr 8) band 16#ff, Octet3=Bits4x6 band 16#ff, [Octet1,Octet2,Octet3|decode1_base64(Rest)]; decode1_base64(_CatchAll) -> "". d(X) when X >= $A, X =<$Z -> X-65; d(X) when X >= $a, X =<$z -> X-71; d(X) when X >= $0, X =<$9 -> X+4; d($+) -> 62; d($/) -> 63; d(_) -> 63. encode_base64([]) -> []; encode_base64([A]) -> [e(A bsr 2), e((A band 3) bsl 4), $=, $=]; encode_base64([A,B]) -> [e(A bsr 2), e(((A band 3) bsl 4) bor (B bsr 4)), e((B band 15) bsl 2), $=]; encode_base64([A,B,C|Ls]) -> encode_base64_do(A,B,C, Ls). encode_base64_do(A,B,C, Rest) -> BB = (A bsl 16) bor (B bsl 8) bor C, [e(BB bsr 18), e((BB bsr 12) band 63), e((BB bsr 6) band 63), e(BB band 63)|encode_base64(Rest)]. e(X) when X >= 0, X < 26 -> X+65; e(X) when X>25, X<52 -> X+71; e(X) when X>51, X<62 -> X-4; e(62) -> $+; e(63) -> $/; e(X) -> exit({bad_encode_base64_token, X}). %% Convert Erlang inet IP to list ip_to_list({IP, _Port}) -> ip_to_list(IP); ip_to_list({_,_,_,_,_,_,_,_} = Ipv6Address) -> inet_parse:ntoa(Ipv6Address); %% This function clause could use inet_parse too: ip_to_list({A,B,C,D}) -> lists:flatten(io_lib:format("~w.~w.~w.~w",[A,B,C,D])); ip_to_list(IP) -> lists:flatten(io_lib:format("~w", [IP])). ejabberd-2.1.11/doc/0000775000000000000000000000000012240452476010775 5ustar ejabberd-2.1.11/doc/guide.html0000664000000000000000000120461512240230175012757 0ustar ejabberd 2.1.11 Installation and Operation Guide




    ejabberd 2.1.11
     
    Installation and Operation Guide



    Contents

    Chapter 1  Introduction

    ejabberd is a free and open source instant messaging server written in Erlang/OTP.

    ejabberd is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication.

    ejabberd is designed to be a rock-solid and feature rich XMPP server.

    ejabberd is suitable for small deployments, whether they need to be scalable or not, as well as extremely big deployments.

    1.1  Key Features

    ejabberd is:

    • Cross-platform: ejabberd runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.
    • Distributed: You can run ejabberd on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.
    • Fault-tolerant: You can deploy an ejabberd cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced ‘on the fly’.
    • Administrator Friendly: ejabberd is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
      • Comprehensive documentation.
      • Straightforward installers for Linux, Mac OS X, and Windows.
      • Web Administration.
      • Shared Roster Groups.
      • Command line administration tool.
      • Can integrate with existing authentication mechanisms.
      • Capability to send announce messages.
    • Internationalized: ejabberd leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
      • Translated to 25 languages.
      • Support for IDNA.
    • Open Standards: ejabberd is the first Open Source Jabber server claiming to fully comply to the XMPP standard.

    1.2  Additional Features

    Moreover, ejabberd comes with a wide range of other state-of-the-art features:

    • Modular
      • Load only the modules you want.
      • Extend ejabberd with your own custom modules.
    • Security
      • SASL and STARTTLS for c2s and s2s connections.
      • STARTTLS and Dialback s2s connections.
      • Web Admin accessible via HTTPS secure access.
    • Databases
      • Internal database for fast deployment (Mnesia).
      • Native MySQL support.
      • Native PostgreSQL support.
      • ODBC data storage support.
      • Microsoft SQL Server support.
    • Authentication
      • Internal Authentication.
      • PAM, LDAP and ODBC.
      • External Authentication script.
    • Others
      • Support for virtual hosting.
      • Compressing XML streams with Stream Compression (XEP-0138).
      • Statistics via Statistics Gathering (XEP-0039).
      • IPv6 support both for c2s and s2s connections.
      • Multi-User Chat module with support for clustering and HTML logging.
      • Users Directory based on users vCards.
      • Publish-Subscribe component with support for Personal Eventing via Pubsub.
      • Support for web clients: HTTP Polling and HTTP Binding (BOSH) services.
      • IRC transport.
      • Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.

    Chapter 2  Installing ejabberd

    2.1  Installing ejabberd with Binary Installer

    Probably the easiest way to install an ejabberd instant messaging server is using the binary installer published by ProcessOne. The binary installers of released ejabberd versions are available in the ProcessOne ejabberd downloads page: http://www.process-one.net/en/ejabberd/downloads

    The installer will deploy and configure a full featured ejabberd server and does not require any extra dependencies.

    In *nix systems, remember to set executable the binary installer before starting it. For example:

    chmod +x ejabberd-2.0.0_1-linux-x86-installer.bin
    ./ejabberd-2.0.0_1-linux-x86-installer.bin
    

    ejabberd can be started manually at any time, or automatically by the operating system at system boot time.

    To start and stop ejabberd manually, use the desktop shortcuts created by the installer. If the machine doesn’t have a graphical system, use the scripts ’start’ and ’stop’ in the ’bin’ directory where ejabberd is installed.

    The Windows installer also adds ejabberd as a system service, and a shortcut to a debug console for experienced administrators. If you want ejabberd to be started automatically at boot time, go to the Windows service settings and set ejabberd to be automatically started. Note that the Windows service is a feature still in development, and for example it doesn’t read the file ejabberdctl.cfg.

    On a *nix system, if you want ejabberd to be started as daemon at boot time, copy ejabberd.init from the ’bin’ directory to something like /etc/init.d/ejabberd (depending on your distribution). Create a system user called ejabberd, give it write access to the directories database/ and logs/, and set that as home; the script will start the server with that user. Then you can call /etc/inid.d/ejabberd start as root to start the server.

    If ejabberd doesn’t start correctly in Windows, try to start it using the shortcut in desktop or start menu. If the window shows error 14001, the solution is to install: "Microsoft Visual C++ 2005 SP1 Redistributable Package". You can download it from www.microsoft.com. Then uninstall ejabberd and install it again.

    If ejabberd doesn’t start correctly and a crash dump is generated, there was a severe problem. You can try starting ejabberd with the script bin/live.bat in Windows, or with the command bin/ejabberdctl live in other Operating Systems. This way you see the error message provided by Erlang and can identify what is exactly the problem.

    The ejabberdctl administration script is included in the bin directory. Please refer to the section 4.1 for details about ejabberdctl, and configurable options to fine tune the Erlang runtime system.

    2.2  Installing ejabberd with Operating System Specific Packages

    Some Operating Systems provide a specific ejabberd package adapted to the system architecture and libraries. It usually also checks dependencies and performs basic configuration tasks like creating the initial administrator account. Some examples are Debian and Gentoo. Consult the resources provided by your Operating System for more information.

    Usually those packages create a script like /etc/init.d/ejabberd to start and stop ejabberd as a service at boot time.

    2.3  Installing ejabberd with CEAN

    CEAN (Comprehensive Erlang Archive Network) is a repository that hosts binary packages from many Erlang programs, including ejabberd and all its dependencies. The binaries are available for many different system architectures, so this is an alternative to the binary installer and Operating System’s ejabberd packages.

    You will have to create your own ejabberd start script depending of how you handle your CEAN installation. The default ejabberdctl script is located into ejabberd’s priv directory and can be used as an example.

    2.4  Installing ejabberd from Source Code

    The canonical form for distribution of ejabberd stable releases is the source code package. Compiling ejabberd from source code is quite easy in *nix systems, as long as your system have all the dependencies.

    2.4.1  Requirements

    To compile ejabberd on a ‘Unix-like’ operating system, you need:

    • GNU Make
    • GCC
    • Libexpat 1.95 or higher
    • Erlang/OTP R10B-9 or higher. The recommended versions are R13B04 and R14B04. Don’t use R14A or R14B because they have a bug.
    • OpenSSL 0.9.8 or higher, for STARTTLS, SASL and SSL encryption.
    • Zlib 1.2.3 or higher, for Stream Compression support (XEP-0138). Optional.
    • Erlang mysql library. Optional. For MySQL authentication or storage. See section 3.2.1.
    • Erlang pgsql library. Optional. For PostgreSQL authentication or storage. See section 3.2.3.
    • PAM library. Optional. For Pluggable Authentication Modules (PAM). See section 3.1.4.
    • GNU Iconv 1.8 or higher, for the IRC Transport (mod_irc). Optional. Not needed on systems with GNU Libc. See section 3.3.8.
    • ImageMagick’s Convert program. Optional. For CAPTCHA challenges. See section 3.1.8.
    • exmpp 0.9.6 or higher. Optional. For import/export user data with XEP-0227 XML files.

    2.4.2  Download Source Code

    Released versions of ejabberd are available in the ProcessOne ejabberd downloads page: http://www.process-one.net/en/ejabberd/downloads

    Alternatively, the latest development source code can be retrieved from the Git repository using the commands:

    git clone git://git.process-one.net/ejabberd/mainline.git ejabberd
    cd ejabberd
    git checkout -b 2.1.x origin/2.1.x
    

    2.4.3  Compile

    To compile ejabberd execute the commands:

    ./configure
    make
    

    The build configuration script allows several options. To get the full list run the command:

    ./configure --help
    

    Some options that you may be interested in modifying:

    --prefix=/
    Specify the path prefix where the files will be copied when running the make install command.

    --enable-user[=USER]
    Allow this normal system user to execute the ejabberdctl script (see section 4.1), read the configuration files, read and write in the spool directory, read and write in the log directory. The account user and group must exist in the machine before running make install. This account doesn’t need an explicit HOME directory, because /var/lib/ejabberd/ will be used by default.

    --enable-pam
    Enable the PAM authentication method (see section 3.1.4).

    --enable-odbc or --enable-mssql
    Required if you want to use an external database. See section 3.2 for more information.

    --enable-full-xml
    Enable the use of XML based optimisations. It will for example use CDATA to escape characters in the XMPP stream. Use this option only if you are sure your XMPP clients include a fully compliant XML parser.

    --disable-transient-supervisors
    Disable the use of Erlang/OTP supervision for transient processes.

    --enable-nif
    Replaces some critical Erlang functions with equivalents written in C to improve performance. This feature requires Erlang/OTP R13B04 or higher.

    2.4.4  Install

    To install ejabberd in the destination directories, run the command:

    make install
    

    Note that you probably need administrative privileges in the system to install ejabberd.

    The files and directories created are, by default:

    /etc/ejabberd/
    Configuration directory:
    ejabberd.cfg
    ejabberd configuration file
    ejabberdctl.cfg
    Configuration file of the administration script
    inetrc
    Network DNS configuration file
    /lib/ejabberd/
    ebin/
    Erlang binary files (*.beam)
    include/
    Erlang header files (*.hrl)
    priv/
    Additional files required at runtime
    bin/
    Executable programs
    lib/
    Binary system libraries (*.so)
    msgs/
    Translation files (*.msgs)
    /sbin/ejabberdctl
    Administration script (see section 4.1)
    /share/doc/ejabberd/
    Documentation of ejabberd
    /var/lib/ejabberd/
    Spool directory:
    .erlang.cookie
    Erlang cookie file (see section 5.3)
    acl.DCD, ...
    Mnesia database spool files (*.DCD, *.DCL, *.DAT)
    /var/log/ejabberd/
    Log directory (see section 7.1):
    ejabberd.log
    ejabberd service log
    erlang.log
    Erlang/OTP system log

    2.4.5  Start

    You can use the ejabberdctl command line administration script to start and stop ejabberd. If you provided the configure option --enable-user=USER (see 2.4.3), you can execute ejabberdctl with either that system account or root.

    Usage example:

    ejabberdctl start
    
    ejabberdctl status
    The node ejabberd@localhost is started with status: started
    ejabberd is running in that node
    
    ejabberdctl stop
    

    If ejabberd doesn’t start correctly and a crash dump is generated, there was a severe problem. You can try starting ejabberd with the command ejabberdctl live to see the error message provided by Erlang and can identify what is exactly the problem.

    Please refer to the section 4.1 for details about ejabberdctl, and configurable options to fine tune the Erlang runtime system.

    If you want ejabberd to be started as daemon at boot time, copy ejabberd.init to something like /etc/init.d/ejabberd (depending on your distribution). Create a system user called ejabberd; it will be used by the script to start the server. Then you can call /etc/inid.d/ejabberd start as root to start the server.

    2.4.6  Specific Notes for BSD

    The command to compile ejabberd in BSD systems is:

    gmake
    

    2.4.7  Specific Notes for Sun Solaris

    You need to have GNU install, but it isn’t included in Solaris. It can be easily installed if your Solaris system is set up for blastwave.org package repository. Make sure /opt/csw/bin is in your PATH and run:

    pkg-get -i fileutils
    

    If that program is called ginstall, modify the ejabberd Makefile script to suit your system, for example:

    cat Makefile | sed s/install/ginstall/ > Makefile.gi
    

    And finally install ejabberd with:

    gmake -f Makefile.gi ginstall
    

    2.4.8  Specific Notes for Microsoft Windows

    Requirements

    To compile ejabberd on a Microsoft Windows system, you need:

    Compilation

    We assume that we will try to put as much library as possible into C:\sdk\ to make it easier to track what is install for ejabberd.

    1. Install Erlang emulator (for example, into C:\sdk\erl5.5.5).
    2. Install Expat library into C:\sdk\Expat-2.0.0 directory.

      Copy file C:\sdk\Expat-2.0.0\Libs\libexpat.dll to your Windows system directory (for example, C:\WINNT or C:\WINNT\System32)

    3. Build and install the Iconv library into the directory C:\sdk\GnuWin32.

      Copy file C:\sdk\GnuWin32\bin\lib*.dll to your Windows system directory (more installation instructions can be found in the file README.woe32 in the iconv distribution).

      Note: instead of copying libexpat.dll and iconv.dll to the Windows directory, you can add the directories C:\sdk\Expat-2.0.0\Libs and C:\sdk\GnuWin32\bin to the PATH environment variable.

    4. Install OpenSSL in C:\sdk\OpenSSL and add C:\sdk\OpenSSL\lib\VC to your path or copy the binaries to your system directory.
    5. Install ZLib in C:\sdk\gnuWin32. Copy C:\sdk\GnuWin32\bin\zlib1.dll to your system directory. If you change your path it should already be set after libiconv install.
    6. Make sure the you can access Erlang binaries from your path. For example: set PATH=%PATH%;"C:\sdk\erl5.6.5\bin"
    7. Depending on how you end up actually installing the library you might need to check and tweak the paths in the file configure.erl.
    8. While in the directory ejabberd\src run:
      configure.bat
      nmake -f Makefile.win32
      
    9. Edit the file ejabberd\src\ejabberd.cfg and run
      werl -s ejabberd -name ejabberd
      

    2.5  Create an XMPP Account for Administration

    You need an XMPP account and grant him administrative privileges to enter the ejabberd Web Admin:

    1. Register an XMPP account on your ejabberd server, for example admin1@example.org. There are two ways to register an XMPP account:
      1. Using ejabberdctl (see section 4.1):
        ejabberdctl register admin1 example.org FgT5bk3
        
      2. Using an XMPP client and In-Band Registration (see section 3.3.19).
    2. Edit the ejabberd configuration file to give administration rights to the XMPP account you created:
      {acl, admin, {user, "admin1", "example.org"}}.
      {access, configure, [{allow, admin}]}.
      
      You can grant administrative privileges to many XMPP accounts, and also to accounts in other XMPP servers.
    3. Restart ejabberd to load the new configuration.
    4. Open the Web Admin (http://server:port/admin/) in your favourite browser. Make sure to enter the full JID as username (in this example: admin1@example.org. The reason that you also need to enter the suffix, is because ejabberd’s virtual hosting support.

    2.6  Upgrading ejabberd

    To upgrade an ejabberd installation to a new version, simply uninstall the old version, and then install the new one. Of course, it is important that the configuration file and Mnesia database spool directory are not removed.

    ejabberd automatically updates the Mnesia table definitions at startup when needed. If you also use an external database for storage of some modules, check if the release notes of the new ejabberd version indicates you need to also update those tables.

    Chapter 3  Configuring ejabberd

    3.1  Basic Configuration

    The configuration file will be loaded the first time you start ejabberd. The content from this file will be parsed and stored in the internal ejabberd database. Subsequently the configuration will be loaded from the database and any commands in the configuration file are appended to the entries in the database.

    Note that ejabberd never edits the configuration file. So, the configuration changes done using the Web Admin are stored in the database, but are not reflected in the configuration file. If you want those changes to be use after ejabberd restart, you can either edit the configuration file, or remove all its content.

    The configuration file contains a sequence of Erlang terms. Lines beginning with a ‘%’ sign are ignored. Each term is a tuple of which the first element is the name of an option, and any further elements are that option’s values. If the configuration file do not contain for instance the ‘hosts’ option, the old host name(s) stored in the database will be used.

    You can override the old values stored in the database by adding next lines to the beginning of the configuration file:

    override_global.
    override_local.
    override_acls.
    

    With these lines the old global options (shared between all ejabberd nodes in a cluster), local options (which are specific for this particular ejabberd node) and ACLs will be removed before new ones are added.

    3.1.1  Host Names

    The option hosts defines a list containing one or more domains that ejabberd will serve.

    The syntax is:

    {hosts, [HostName, ...]}.

    Examples:

    • Serving one domain:
      {hosts, ["example.org"]}.
      
    • Serving three domains:
      {hosts, ["example.net", "example.com", "jabber.somesite.org"]}.
      

    3.1.2  Virtual Hosting

    Options can be defined separately for every virtual host using the host_config option.

    The syntax is:

    {host_config, HostName, [Option, ...]}

    Examples:

    • Domain example.net is using the internal authentication method while domain example.com is using the LDAP server running on the domain localhost to perform authentication:
      {host_config, "example.net", [{auth_method,   internal}]}.
      
      {host_config, "example.com", [{auth_method,   ldap},
                                    {ldap_servers,  ["localhost"]},
                                    {ldap_uids,     [{"uid"}]},
                                    {ldap_rootdn,   "dc=localdomain"},
                                    {ldap_rootdn,   "dc=example,dc=com"},
                                    {ldap_password, ""}]}.
      
    • Domain example.net is using ODBC to perform authentication while domain example.com is using the LDAP servers running on the domains localhost and otherhost:
      {host_config, "example.net", [{auth_method, odbc},
                                    {odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}]}.
      
      {host_config, "example.com", [{auth_method,   ldap},
                                    {ldap_servers,  ["localhost", "otherhost"]},
                                    {ldap_uids,     [{"uid"}]},
                                    {ldap_rootdn,   "dc=localdomain"},
                                    {ldap_rootdn,   "dc=example,dc=com"},
                                    {ldap_password, ""}]}.
      

    To define specific ejabberd modules in a virtual host, you can define the global modules option with the common modules, and later add specific modules to certain virtual hosts. To accomplish that, instead of defining each option in host_config with the general syntax

    {OptionName, OptionValue}

    use this syntax:

    {{add, OptionName}, OptionValue}

    In this example three virtual hosts have some similar modules, but there are also other different modules for some specific virtual hosts:

    %% This ejabberd server has three vhosts:
    {hosts, ["one.example.org", "two.example.org", "three.example.org"]}.
    
    %% Configuration of modules that are common to all vhosts
    {modules,
     [
      {mod_roster,     []},
      {mod_configure,  []},
      {mod_disco,      []},
      {mod_private,    []},
      {mod_time,       []},
      {mod_last,       []},
      {mod_version,    []}
     ]}.
    
    %% Add some modules to vhost one:
    {host_config, "one.example.org",
     [{{add, modules}, [
                        {mod_echo,       [{host, "echo-service.one.example.org"}]}
                        {mod_http_bind,  []},
                        {mod_logxml,     []}
                       ]
      }
     ]}.
    
    %% Add a module just to vhost two:
    {host_config, "two.example.org",
     [{{add, modules}, [
                        {mod_echo,       [{host, "mirror.two.example.org"}]}
                       ]
      }
     ]}.
    

    3.1.3  Listening Ports

    The option listen defines for which ports, addresses and network protocols ejabberd will listen and what services will be run on them. Each element of the list is a tuple with the following elements:

    • Port number. Optionally also the IP address and/or a transport protocol.
    • Listening module that serves this port.
    • Options for the TCP socket and for the listening module.

    The option syntax is:

    {listen, [Listener, ...]}.

    To define a listener there are several syntax.

    {PortNumber, Module, [Option, ...]}
    {{PortNumber, IPaddress}, Module, [Option, ...]}
    {{PortNumber, TransportProtocol}, Module, [Option, ...]}
    {{PortNumber, IPaddress, TransportProtocol}, Module, [Option, ...]}

    Port Number, IP Address and Transport Protocol

    The port number defines which port to listen for incoming connections. It can be a Jabber/XMPP standard port (see section 5.1) or any other valid port number.

    The IP address can be represented with a string or an Erlang tuple with decimal or hexadecimal numbers. The socket will listen only in that network interface. It is possible to specify a generic address, so ejabberd will listen in all addresses. Depending in the type of the IP address, IPv4 or IPv6 will be used. When not specified the IP address, it will listen on all IPv4 network addresses.

    Some example values for IP address:

    • "0.0.0.0" to listen in all IPv4 network interfaces. This is the default value when no IP is specified.
    • "::" to listen in all IPv6 network interfaces
    • "10.11.12.13" is the IPv4 address 10.11.12.13
    • "::FFFF:127.0.0.1" is the IPv6 address ::FFFF:127.0.0.1/128
    • {10, 11, 12, 13} is the IPv4 address 10.11.12.13
    • {0, 0, 0, 0, 0, 65535, 32512, 1} is the IPv6 address ::FFFF:127.0.0.1/128
    • {16#fdca, 16#8ab6, 16#a243, 16#75ef, 0, 0, 0, 1} is the IPv6 address FDCA:8AB6:A243:75EF::1/128

    The transport protocol can be tcp or udp. Default is tcp.

    Listening Module

    The available modules, their purpose and the options allowed by each one are:

    ejabberd_c2s
    Handles c2s connections.
    Options: access, certfile, max_fsm_queue, max_stanza_size, shaper, starttls, starttls_required, tls, zlib
    ejabberd_s2s_in
    Handles incoming s2s connections.
    Options: max_stanza_size, shaper
    ejabberd_service
    Interacts with an external component (as defined in the Jabber Component Protocol (XEP-0114).
    Options: access, hosts, max_fsm_queue, service_check_from, shaper
    ejabberd_stun
    Handles STUN Binding requests as defined in RFC 5389.
    Options: certfile
    ejabberd_http
    Handles incoming HTTP connections.
    Options: captcha, certfile, default_host, http_bind, http_poll, request_handlers, tls, trusted_proxies, web_admin

    Options

    This is a detailed description of each option allowed by the listening modules:

    {access, AccessName}
    This option defines access to the port. The default value is all.
    {backlog, Value}
    The backlog value defines the maximum length that the queue of pending connections may grow to. This should be increased if the server is going to handle lots of new incoming connections as they may be dropped if there is no space in the queue (and ejabberd was not able to accept them immediately). Default value is 5.
    captcha
    Simple web page that allows a user to fill a CAPTCHA challenge (see section 3.1.8).
    {certfile, Path}
    Full path to a file containing the default SSL certificate. To define a certificate file specific for a given domain, use the global option domain_certfile.
    {default_host, undefined|HostName}
    If the HTTP request received by ejabberd contains the HTTP header Host with an ambiguous virtual host that doesn’t match any one defined in ejabberd (see 3.1.1), then this configured HostName is set as the request Host. The default value of this option is: undefined.
    {hosts, [Hostname, ...], [HostOption, ...]}
    The external Jabber component that connects to this ejabberd_service can serve one or more hostnames. As HostOption you can define options for the component; currently the only allowed option is the password required to the component when attempt to connect to ejabberd: {password, Secret}. Note that you cannot define in a single ejabberd_service components of different services: add an ejabberd_service for each service, as seen in an example below.
    http_bind
    This option enables HTTP Binding (XEP-0124 and XEP-0206) support. HTTP Bind enables access via HTTP requests to ejabberd from behind firewalls which do not allow outgoing sockets on port 5222.

    Remember that you must also install and enable the module mod_http_bind.

    If HTTP Bind is enabled, it will be available at http://server:port/http-bind/. Be aware that support for HTTP Bind is also needed in the XMPP client. Remark also that HTTP Bind can be interesting to host a web-based XMPP client such as JWChat (check the tutorials to install JWChat with ejabberd and an embedded local web server or Apache).

    http_poll
    This option enables HTTP Polling (XEP-0025) support. HTTP Polling enables access via HTTP requests to ejabberd from behind firewalls which do not allow outgoing sockets on port 5222.

    If HTTP Polling is enabled, it will be available at http://server:port/http-poll/. Be aware that support for HTTP Polling is also needed in the XMPP client. Remark also that HTTP Polling can be interesting to host a web-based XMPP client such as JWChat.

    The maximum period of time to keep a client session active without an incoming POST request can be configured with the global option http_poll_timeout. The default value is five minutes. The option can be defined in ejabberd.cfg, expressing the time in seconds: {http_poll_timeout, 300}.

    {max_fsm_queue, Size}
    This option specifies the maximum number of elements in the queue of the FSM (Finite State Machine). Roughly speaking, each message in such queues represents one XML stanza queued to be sent into its relevant outgoing stream. If queue size reaches the limit (because, for example, the receiver of stanzas is too slow), the FSM and the corresponding connection (if any) will be terminated and error message will be logged. The reasonable value for this option depends on your hardware configuration. However, there is no much sense to set the size above 1000 elements. This option can be specified for ejabberd_service and ejabberd_c2s listeners, or also globally for ejabberd_s2s_out. If the option is not specified for ejabberd_service or ejabberd_c2s listeners, the globally configured value is used. The allowed values are integers and ’undefined’. Default value: ’undefined’.
    {max_stanza_size, Size}
    This option specifies an approximate maximum size in bytes of XML stanzas. Approximate, because it is calculated with the precision of one block of read data. For example {max_stanza_size, 65536}. The default value is infinity. Recommended values are 65536 for c2s connections and 131072 for s2s connections. s2s max stanza size must always much higher than c2s limit. Change this value with extreme care as it can cause unwanted disconnect if set too low.
    {request_handlers, [ {Path, Module}, ...]}
    To define one or several handlers that will serve HTTP requests. The Path is a list of strings; so the URIs that start with that Path will be served by Module. For example, if you want mod_foo to serve the URIs that start with /a/b/, and you also want mod_http_bind to serve the URIs /http-bind/, use this option: {request_handlers, [{["a", "b"], mod_foo}, {["http-bind"], mod_http_bind}]}
    {service_check_from, true|false}
    This option can be used with ejabberd_service only. XEP-0114 requires that the domain must match the hostname of the component. If this option is set to false, ejabberd will allow the component to send stanzas with any arbitrary domain in the ’from’ attribute. Only use this option if you are completely sure about it. The default value is true, to be compliant with XEP-0114.
    {shaper, none|ShaperName}
    This option defines a shaper for the port (see section 3.1.6). The default value is none.
    starttls
    This option specifies that STARTTLS encryption is available on connections to the port. You should also set the certfile option. You can define a certificate file for a specific domain using the global option domain_certfile.
    starttls_required
    This option specifies that STARTTLS encryption is required on connections to the port. No unencrypted connections will be allowed. You should also set the certfile option. You can define a certificate file for a specific domain using the global option domain_certfile.
    tls
    This option specifies that traffic on the port will be encrypted using SSL immediately after connecting. This was the traditional encryption method in the early Jabber software, commonly on port 5223 for client-to-server communications. But this method is nowadays deprecated and not recommended. The preferable encryption method is STARTTLS on port 5222, as defined RFC 3920: XMPP Core, which can be enabled in ejabberd with the option starttls. If this option is set, you should also set the certfile option. The option tls can also be used in ejabberd_http to support HTTPS.
    {trusted_proxies, all | [IpString]}
    Specify what proxies are trusted when an HTTP request contains the header X-Forwarded-For You can specify all to allow all proxies, or specify a list of IPs in string format. The default value is: ["127.0.0.1"]
    web_admin
    This option enables the Web Admin for ejabberd administration which is available at http://server:port/admin/. Login and password are the username and password of one of the registered users who are granted access by the ‘configure’ access rule.
    zlib
    This option specifies that Zlib stream compression (as defined in XEP-0138) is available on connections to the port.

    There are some additional global options that can be specified in the ejabberd configuration file (outside listen):

    {s2s_use_starttls, false|optional|required|required_trusted}
    This option defines if s2s connections don’t use STARTTLS encryption; if STARTTLS can be used optionally; if STARTTLS is required to establish the connection; or if STARTTLS is required and the remote certificate must be valid and trusted. The default value is to not use STARTTLS: false.
    {s2s_certfile, Path}
    Full path to a file containing a SSL certificate.
    {domain_certfile, Domain, Path}
    Full path to the file containing the SSL certificate for a specific domain.
    {outgoing_s2s_options, [Family, ...], Timeout}
    Specify which address families to try, in what order, and connect timeout in milliseconds. By default it first tries connecting with IPv4, if that fails it tries using IPv6, with a timeout of 10000 milliseconds.
    {s2s_dns_options, [ {Property, Value}, ...]}
    Define properties to use for DNS resolving. Allowed Properties are: timeout in seconds which default value is 10 and retries which default value is 2.
    {s2s_default_policy, allow|deny}
    The default policy for incoming and outgoing s2s connections to other XMPP servers. The default value is allow.
    {{s2s_host, Host}, allow|deny}
    Defines if incoming and outgoing s2s connections with a specific remote host are allowed or denied. This allows to restrict ejabberd to only establish s2s connections with a small list of trusted servers, or to block some specific servers.
    {s2s_max_retry_delay, Seconds}
    The maximum allowed delay for retry to connect after a failed connection attempt. Specified in seconds. The default value is 300 seconds (5 minutes).
    {max_fsm_queue, Size}
    This option specifies the maximum number of elements in the queue of the FSM (Finite State Machine). Roughly speaking, each message in such queues represents one XML stanza queued to be sent into its relevant outgoing stream. If queue size reaches the limit (because, for example, the receiver of stanzas is too slow), the FSM and the corresponding connection (if any) will be terminated and error message will be logged. The reasonable value for this option depends on your hardware configuration. However, there is no much sense to set the size above 1000 elements. This option can be specified for ejabberd_service and ejabberd_c2s listeners, or also globally for ejabberd_s2s_out. If the option is not specified for ejabberd_service or ejabberd_c2s listeners, the globally configured value is used. The allowed values are integers and ’undefined’. Default value: ’undefined’.
    {route_subdomains, local|s2s}
    Defines if ejabberd must route stanzas directed to subdomains locally (compliant with RFC 3920: XMPP Core), or to foreign server using S2S (compliant with RFC 3920 bis).

    Examples

    For example, the following simple configuration defines:

    • There are three domains. The default certificate file is server.pem. However, the c2s and s2s connections to the domain example.com use the file example_com.pem.
    • Port 5222 listens for c2s connections with STARTTLS, and also allows plain connections for old clients.
    • Port 5223 listens for c2s connections with the old SSL.
    • Port 5269 listens for s2s connections with STARTTLS. The socket is set for IPv6 instead of IPv4.
    • Port 3478 listens for STUN requests over UDP.
    • Port 5280 listens for HTTP requests, and serves the HTTP Poll service.
    • Port 5281 listens for HTTP requests, using HTTPS to serve HTTP-Bind (BOSH) and the Web Admin as explained in section 4.3. The socket only listens connections to the IP address 127.0.0.1.
    {hosts, ["example.com", "example.org", "example.net"]}.
    {listen,
     [
      {5222, ejabberd_c2s, [
                            {access, c2s},
                            {shaper, c2s_shaper},
                            starttls, {certfile, "/etc/ejabberd/server.pem"},
                            {max_stanza_size, 65536}
                           ]},
      {5223, ejabberd_c2s, [
                            {access, c2s},
                            {shaper, c2s_shaper},
                            tls, {certfile, "/etc/ejabberd/server.pem"},
                            {max_stanza_size, 65536}
                           ]},
      {{5269, "::"}, ejabberd_s2s_in, [
                                       {shaper, s2s_shaper},
                                       {max_stanza_size, 131072}
                                      ]},
      {{3478, udp}, ejabberd_stun, []},
      {5280, ejabberd_http, [
                             http_poll
                            ]},
      {{5281, "127.0.0.1"}, ejabberd_http, [
                                            web_admin,
                                            http_bind,
                                            tls, {certfile, "/etc/ejabberd/server.pem"},
                                           ]}
     ]
    }.
    {s2s_use_starttls, optional}.
    {s2s_certfile, "/etc/ejabberd/server.pem"}.
    {domain_certfile, "example.com", "/etc/ejabberd/example_com.pem"}.
    {outgoing_s2s_options, [ipv4, ipv6], 10000}.
    

    In this example, the following configuration defines that:

    • c2s connections are listened for on port 5222 (all IPv4 addresses) and on port 5223 (SSL, IP 192.168.0.1 and fdca:8ab6:a243:75ef::1) and denied for the user called ‘bad’.
    • s2s connections are listened for on port 5269 (all IPv4 addresses) with STARTTLS for secured traffic strictly required, and the certificates are verified. Incoming and outgoing connections of remote XMPP servers are denied, only two servers can connect: "jabber.example.org" and "example.com".
    • Port 5280 is serving the Web Admin and the HTTP Polling service in all the IPv4 addresses. Note that it is also possible to serve them on different ports. The second example in section 4.3 shows how exactly this can be done.
    • All users except for the administrators have a traffic of limit 1,000 Bytes/second
    • The AIM transport aim.example.org is connected to port 5233 on localhost IP addresses (127.0.0.1 and ::1) with password ‘aimsecret’.
    • The ICQ transport JIT (icq.example.org and sms.example.org) is connected to port 5234 with password ‘jitsecret’.
    • The MSN transport msn.example.org is connected to port 5235 with password ‘msnsecret’.
    • The Yahoo! transport yahoo.example.org is connected to port 5236 with password ‘yahoosecret’.
    • The Gadu-Gadu transport gg.example.org is connected to port 5237 with password ‘ggsecret’.
    • The Jabber Mail Component jmc.example.org is connected to port 5238 with password ‘jmcsecret’.
    • The service custom has enabled the special option to avoiding checking the from attribute in the packets send by this component. The component can send packets in behalf of any users from the server, or even on behalf of any server.
    {acl, blocked, {user, "bad"}}.
    {access, c2s, [{deny, blocked},
                   {allow, all}]}.
    {shaper, normal, {maxrate, 1000}}.
    {access, c2s_shaper, [{none, admin},
                          {normal, all}]}.
    {listen,
     [{5222, ejabberd_c2s, [
                            {access, c2s},
                            {shaper, c2s_shaper}
                           ]},
      {{5223, {192, 168, 0, 1}}, ejabberd_c2s, [
                                                {access, c2s},
                                                ssl, {certfile, "/path/to/ssl.pem"}
                                               ]},
      {{5223, {16#fdca, 16#8ab6, 16#a243, 16#75ef, 0, 0, 0, 1}},
       ejabberd_c2s, [
                      {access, c2s},
                      ssl, {certfile, "/path/to/ssl.pem"}
                     ]},
      {5269, ejabberd_s2s_in, []},
      {{5280, {0, 0, 0, 0}}, ejabberd_http, [
                                             http_poll,
                                             web_admin
                                            ]},
      {{5233, {127, 0, 0, 1}}, ejabberd_service, [
                                                  {hosts, ["aim.example.org"],
                                                     [{password, "aimsecret"}]}
                                                 ]},
      {{5233, "::1"}, ejabberd_service, [
                                         {hosts, ["aim.example.org"],
                                            [{password, "aimsecret"}]}
                                        ]},
      {5234, ejabberd_service, [{hosts, ["icq.example.org", "sms.example.org"],
                                 [{password, "jitsecret"}]}]},
      {5235, ejabberd_service, [{hosts, ["msn.example.org"],
                                 [{password, "msnsecret"}]}]},
      {5236, ejabberd_service, [{hosts, ["yahoo.example.org"],
                                 [{password, "yahoosecret"}]}]},
      {5237, ejabberd_service, [{hosts, ["gg.example.org"],
                                 [{password, "ggsecret"}]}]},
      {5238, ejabberd_service, [{hosts, ["jmc.example.org"],
                                 [{password, "jmcsecret"}]}]},
      {5239, ejabberd_service, [{hosts, ["custom.example.org"],
                                 [{password, "customsecret"}]},
                                {service_check_from, false}]}
     ]
    }.
    {s2s_use_starttls, required_trusted}.
    {s2s_certfile, "/path/to/ssl.pem"}.
    {s2s_default_policy, deny}.
    {{s2s_host,"jabber.example.org"}, allow}.
    {{s2s_host,"example.com"}, allow}.
    

    Note, that for services based in jabberd14 or WPJabber you have to make the transports log and do XDB by themselves:

      <!--
         You have to add elogger and rlogger entries here when using ejabberd.
         In this case the transport will do the logging.
      -->
    
      <log id='logger'>
        <host/>
        <logtype/>
        <format>%d: [%t] (%h): %s</format>
        <file>/var/log/jabber/service.log</file>
      </log>
    
      <!--
         Some XMPP server implementations do not provide
         XDB services (for example, jabberd2 and ejabberd).
         xdb_file.so is loaded in to handle all XDB requests.
      -->
    
      <xdb id="xdb">
        <host/>
        <load>
          <!-- this is a lib of wpjabber or jabberd14 -->
          <xdb_file>/usr/lib/jabber/xdb_file.so</xdb_file>
          </load>
        <xdb_file xmlns="jabber:config:xdb_file">
          <spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
        </xdb_file>
      </xdb>
    

    3.1.4  Authentication

    The option auth_method defines the authentication methods that are used for user authentication. The syntax is:

    {auth_method, [Method, ...]}.

    The following authentication methods are supported by ejabberd:

    Account creation is only supported by internal, external and odbc methods.

    The option resource_conflict defines the action when a client attempts to login to an account with a resource that is already connected. The option syntax is:

    {resource_conflict, setresource|closenew|closeold}.

    The possible values match exactly the three possibilities described in XMPP Core: section 7.7.2.2. The default value is closeold. If the client uses old Jabber Non-SASL authentication (XEP-0078), then this option is not respected, and the action performed is closeold.

    The option fqdn allows you to define the Fully Qualified Domain Name of the machine, in case it isn’t detected automatically. The FQDN is used to authenticate some clients that use the DIGEST-MD5 SASL mechanism. The option syntax is:

    {fqdn, undefined|FqdnString}.

    Internal

    ejabberd uses its internal Mnesia database as the default authentication method. The value internal will enable the internal authentication method.

    The option {auth_password_format, plain|scram} defines in what format the users passwords are stored:

    plain
    The password is stored as plain text in the database. This is risky because the passwords can be read if your database gets compromised. This is the default value. This format allows clients to authenticate using: the old Jabber Non-SASL (XEP-0078), SASL PLAIN, SASL DIGEST-MD5, and SASL SCRAM-SHA-1.
    scram
    The password is not stored, only some information that allows to verify the hash provided by the client. It is impossible to obtain the original plain password from the stored information; for this reason, when this value is configured it cannot be changed to plain anymore. This format allows clients to authenticate using: SASL PLAIN and SASL SCRAM-SHA-1.

    Examples:

    • To use internal authentication on example.org and LDAP authentication on example.net:
      {host_config, "example.org", [{auth_method, [internal]}]}.
      {host_config, "example.net", [{auth_method, [ldap]}]}.
      
    • To use internal authentication with hashed passwords on all virtual hosts:
      {auth_method, internal}.
      {auth_password_format, scram}.
      

    External Script

    In this authentication method, when ejabberd starts, it start a script, and calls it to perform authentication tasks.

    The server administrator can write the external authentication script in any language. The details on the interface between ejabberd and the script are described in the ejabberd Developers Guide. There are also several example authentication scripts.

    These are the specific options:

    {extauth_program, PathToScript}
    Indicate in this option the full path to the external authentication script. The script must be executable by ejabberd.
    {extauth_instances, Integer}
    Indicate how many instances of the script to run simultaneously to serve authentication in the virtual host. The default value is the minimum number: 1.
    {extauth_cache, false|CacheTimeInteger}
    The value false disables the caching feature, this is the default. The integer 0 (zero) enables caching for statistics, but doesn’t use that cached information to authenticate users. If another integer value is set, caching is enabled both for statistics and for authentication: the CacheTimeInteger indicates the number of seconds that ejabberd can reuse the authentication information since the user last disconnected, to verify again the user authentication without querying again the extauth script. Note: caching should not be enabled in a host if internal auth is also enabled. If caching is enabled, mod_last or mod_last_odbc must be enabled also in that vhost.

    This example sets external authentication, the extauth script, enables caching for 10 minutes, and starts three instances of the script for each virtual host defined in ejabberd:

    {auth_method, [external]}.
    {extauth_program, "/etc/ejabberd/JabberAuth.class.php"}.
    {extauth_cache, 600}.
    {extauth_instances, 3}. 
    

    SASL Anonymous and Anonymous Login

    The value anonymous will enable the internal authentication method.

    The anonymous authentication method can be configured with the following options. Remember that you can use the host_config option to set virtual host specific options (see section 3.1.2). Note that there also is a detailed tutorial regarding SASL Anonymous and anonymous login configuration.

    {allow_multiple_connections, false|true}
    This option is only used when the anonymous mode is enabled. Setting it to true means that the same username can be taken multiple times in anonymous login mode if different resource are used to connect. This option is only useful in very special occasions. The default value is false.
    {anonymous_protocol, sasl_anon | login_anon | both}
    sasl_anon means that the SASL Anonymous method will be used. login_anon means that the anonymous login method will be used. both means that SASL Anonymous and login anonymous are both enabled.

    Those options are defined for each virtual host with the host_config parameter (see section 3.1.2).

    Examples:

    • To enable anonymous login on all virtual hosts:
      {auth_method, [anonymous]}.
      {anonymous_protocol, login_anon}.
      
    • Similar as previous example, but limited to public.example.org:
      {host_config, "public.example.org", [{auth_method, [anonymous]},
                                           {anonymous_protocol, login_anon}]}.
      
    • To enable anonymous login and internal authentication on a virtual host:
      {host_config, "public.example.org", [{auth_method, [internal,anonymous]},
                                           {anonymous_protocol, login_anon}]}.
      
    • To enable SASL Anonymous on a virtual host:
      {host_config, "public.example.org", [{auth_method, [anonymous]},
                                           {anonymous_protocol, sasl_anon}]}.
      
    • To enable SASL Anonymous and anonymous login on a virtual host:
      {host_config, "public.example.org", [{auth_method, [anonymous]},
                                           {anonymous_protocol, both}]}.
      
    • To enable SASL Anonymous, anonymous login, and internal authentication on a virtual host:
      {host_config, "public.example.org", [{auth_method, [internal,anonymous]},
                                           {anonymous_protocol, both}]}.
      

    PAM Authentication

    ejabberd supports authentication via Pluggable Authentication Modules (PAM). PAM is currently supported in AIX, FreeBSD, HP-UX, Linux, Mac OS X, NetBSD and Solaris. PAM authentication is disabled by default, so you have to configure and compile ejabberd with PAM support enabled:

    ./configure --enable-pam && make install
    

    Options:

    {pam_service, Name}
    This option defines the PAM service name. Default is "ejabberd". Refer to the PAM documentation of your operation system for more information.
    {pam_userinfotype, username|jid}
    This option defines what type of information about the user ejabberd provides to the PAM service: only the username, or the user JID. Default is username.

    Example:

    {auth_method, [pam]}.
    {pam_service, "ejabberd"}.
    

    Though it is quite easy to set up PAM support in ejabberd, PAM itself introduces some security issues:

    • To perform PAM authentication ejabberd uses external C-program called epam. By default, it is located in /var/lib/ejabberd/priv/bin/ directory. You have to set it root on execution in the case when your PAM module requires root privileges (pam_unix.so for example). Also you have to grant access for ejabberd to this file and remove all other permissions from it. Execute with root privileges:
      chown root:ejabberd /var/lib/ejabberd/priv/bin/epam
      chmod 4750 /var/lib/ejabberd/priv/bin/epam
      
    • Make sure you have the latest version of PAM installed on your system. Some old versions of PAM modules cause memory leaks. If you are not able to use the latest version, you can kill(1) epam process periodically to reduce its memory consumption: ejabberd will restart this process immediately.
    • epam program tries to turn off delays on authentication failures. However, some PAM modules ignore this behavior and rely on their own configuration options. You can create a configuration file ejabberd.pam. This example shows how to turn off delays in pam_unix.so module:
      #%PAM-1.0
      auth        sufficient  pam_unix.so likeauth nullok nodelay
      account     sufficient  pam_unix.so
      
      That is not a ready to use configuration file: you must use it as a hint when building your own PAM configuration instead. Note that if you want to disable delays on authentication failures in the PAM configuration file, you have to restrict access to this file, so a malicious user can’t use your configuration to perform brute-force attacks.
    • You may want to allow login access only for certain users. pam_listfile.so module provides such functionality.
    • If you use pam_winbind to authorise against a Windows Active Directory, then /etc/nssswitch.conf must be configured to use winbind as well.

    3.1.5  Access Rules

    ACL Definition

    Access control in ejabberd is performed via Access Control Lists (ACLs). The declarations of ACLs in the configuration file have the following syntax:

    {acl, ACLName, ACLValue}.

    ACLValue can be one of the following:

    all
    Matches all JIDs. Example:
    {acl, all, all}.
    
    {user, Username}
    Matches the user with the name Username at the first virtual host. Example:
    {acl, admin, {user, "yozhik"}}.
    
    {user, Username, Server}
    Matches the user with the JID Username@Server and any resource. Example:
    {acl, admin, {user, "yozhik", "example.org"}}.
    
    {server, Server}
    Matches any JID from server Server. Example:
    {acl, exampleorg, {server, "example.org"}}.
    
    {resource, Resource}
    Matches any JID with a resource Resource. Example:
    {acl, mucklres, {resource, "muckl"}}.
    
    {shared_group, Groupname}
    Matches any member of a Shared Roster Group with name Groupname in the virtual host. Example:
    {acl, techgroupmembers, {shared_group, "techteam"}}.
    
    {shared_group, Groupname, Server}
    Matches any member of a Shared Roster Group with name Groupname in the virtual host Server. Example:
    {acl, techgroupmembers, {shared_group, "techteam", "example.org"}}.
    
    {user_regexp, Regexp}
    Matches any local user with a name that matches Regexp on local virtual hosts. Example:
    {acl, tests, {user_regexp, "^test[0-9]*$"}}.
    
    {user_regexp, Regexp, Server}
    Matches any user with a name that matches Regexp at server Server. Example:
    {acl, tests, {user_regexp, "^test", "example.org"}}.
    
    {server_regexp, Regexp}
    Matches any JID from the server that matches Regexp. Example:
    {acl, icq, {server_regexp, "^icq\\."}}.
    
    {resource_regexp, Regexp}
    Matches any JID with a resource that matches Regexp. Example:
    {acl, icq, {resource_regexp, "^laptop\\."}}.
    
    {node_regexp, UserRegexp, ServerRegexp}
    Matches any user with a name that matches UserRegexp at any server that matches ServerRegexp. Example:
    {acl, yozhik, {node_regexp, "^yozhik$", "^example.(com|org)$"}}.
    
    {user_glob, Glob}
    {user_glob, Glob, Server}
    {server_glob, Glob}
    {resource_glob, Glob}
    {node_glob, UserGlob, ServerGlob}
    This is the same as above. However, it uses shell glob patterns instead of regexp. These patterns can have the following special characters:
    *
    matches any string including the null string.
    ?
    matches any single character.
    [...]
    matches any of the enclosed characters. Character ranges are specified by a pair of characters separated by a ‘-’. If the first character after ‘[’ is a ‘!’, any character not enclosed is matched.

    The following ACLName are pre-defined:

    all
    Matches any JID.
    none
    Matches no JID.

    Access Rights

    An entry allowing or denying access to different services. The syntax is:

    {access, AccessName, [ {allow|deny, ACLName}, ...]}.

    When a JID is checked to have access to Accessname, the server sequentially checks if that JID matches any of the ACLs that are named in the second elements of the tuples in the list. If it matches, the first element of the first matched tuple is returned, otherwise the value ‘deny’ is returned.

    If you define specific Access rights in a virtual host, remember that the globally defined Access rights have precedence over those. This means that, in case of conflict, the Access granted or denied in the global server is used and the Access of a virtual host doesn’t have effect.

    Example:

    {access, configure, [{allow, admin}]}.
    {access, something, [{deny, badmans},
                         {allow, all}]}.
    

    The following AccessName are pre-defined:

    all
    Always returns the value ‘allow’.
    none
    Always returns the value ‘deny’.

    Limiting Opened Sessions with ACL

    The special access max_user_sessions specifies the maximum number of sessions (authenticated connections) per user. If a user tries to open more sessions by using different resources, the first opened session will be disconnected. The error session replaced will be sent to the disconnected session. The value for this option can be either a number, or infinity. The default value is infinity.

    The syntax is:

    {access, max_user_sessions, [ {MaxNumber, ACLName}, ...]}.

    This example limits the number of sessions per user to 5 for all users, and to 10 for admins:

    {access, max_user_sessions, [{10, admin}, {5, all}]}.
    

    Several connections to a remote XMPP server with ACL

    The special access max_s2s_connections specifies how many simultaneous S2S connections can be established to a specific remote XMPP server. The default value is 1. There’s also available the access max_s2s_connections_per_node.

    The syntax is:

    {access, max_s2s_connections, [ {MaxNumber, ACLName}, ...]}.

    Examples:

    • Allow up to 3 connections with each remote server:
      {access, max_s2s_connections, [{3, all}]}.
      

    3.1.6  Shapers

    Shapers enable you to limit connection traffic. The syntax is:

    {shaper, ShaperName, Kind}.

    Currently only one kind of shaper called maxrate is available. It has the following syntax:

    {maxrate, Rate}

    where Rate stands for the maximum allowed incoming rate in bytes per second. When a connection exceeds this limit, ejabberd stops reading from the socket until the average rate is again below the allowed maximum.

    Examples:

    • To define a shaper named ‘normal’ with traffic speed limited to 1,000 bytes/second:
      {shaper, normal, {maxrate, 1000}}.
      
    • To define a shaper named ‘fast’ with traffic speed limited to 50,000 bytes/second:
      {shaper, fast, {maxrate, 50000}}.
      

    3.1.7  Default Language

    The option language defines the default language of server strings that can be seen by XMPP clients. If a XMPP client does not support xml:lang, the specified language is used.

    The option syntax is:

    {language, Language}.

    The default value is en. In order to take effect there must be a translation file Language.msg in ejabberd’s msgs directory.

    For example, to set Russian as default language:

    {language, "ru"}.
    

    Appendix A provides more details about internationalization and localization.

    3.1.8  CAPTCHA

    Some ejabberd modules can be configured to require a CAPTCHA challenge on certain actions. If the client does not support CAPTCHA Forms (XEP-0158), a web link is provided so the user can fill the challenge in a web browser.

    An example script is provided that generates the image using ImageMagick’s Convert program.

    The configurable options are:

    {captcha_cmd, Path}
    Full path to a script that generates the image. The default value disables the feature: undefined
    {captcha_host, ProtocolHostPort}
    ProtocolHostPort is a string with the host, and optionally the Protocol and Port number. It must identify where ejabberd listens for CAPTCHA requests. The URL sent to the user is formed by: Protocol://Host:Port/captcha/ The default value is: protocol http, the first hostname configured, and port 80. If you specify a port number that does not match exactly an ejabberd listener (because you are using a reverse proxy or other port-forwarding tool), then you must specify the transfer protocol, as seen in the example below.

    Additionally, an ejabberd_http listener must be enabled with the captcha option. See section 3.1.3.

    Example configuration:

    {hosts, ["example.org"]}.
    
    {captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}.
    {captcha_host, "example.org:5280"}.
    %% {captcha_host, "https://example.org:443"}.
    %% {captcha_host, "http://example.com"}.
    
    {listen,
     [
      ...
      {5280, ejabberd_http, [
                             captcha,
                             ...
                            ]
      }
    
    ]}.
    

    3.1.9  STUN

    ejabberd is able to act as a stand-alone STUN server (RFC 5389). Currently only Binding usage is supported. In that role ejabberd helps clients with Jingle ICE (XEP-0176) support to discover their external addresses and ports.

    You should configure ejabberd_stun listening module as described in 3.1.3 section. If certfile option is defined, ejabberd multiplexes TCP and TLS over TCP connections on the same port. Obviously, certfile option is defined for tcp only. Note however that TCP or TLS over TCP support is not required for Binding usage and is reserved for TURN functionality. Feel free to configure udp transport only.

    Example configuration:

    {listen,
     [
      ...
      {{3478, udp}, ejabberd_stun, []},
      {3478, ejabberd_stun, []},
      {5349, ejabberd_stun, [{certfile, "/etc/ejabberd/server.pem"}]},
      ...
     ]
    }.
    

    You also need to configure DNS SRV records properly so clients can easily discover a STUN server serving your XMPP domain. Refer to section DNS Discovery of a Server of RFC 5389 for details.

    Example DNS SRV configuration:

    _stun._udp   IN SRV  0 0 3478 stun.example.com.
    _stun._tcp   IN SRV  0 0 3478 stun.example.com.
    _stuns._tcp  IN SRV  0 0 5349 stun.example.com.
    

    3.1.10  Include Additional Configuration Files

    The option include_config_file in a configuration file instructs ejabberd to include other configuration files immediately.

    The basic syntax is:

    {include_config_file, Filename}.

    It is possible to specify suboptions using the full syntax:

    {include_config_file, Filename, [Suboption, ...]}.

    The filename can be indicated either as an absolute path, or relative to the main ejabberd configuration file. It isn’t possible to use wildcards. The file must exist and be readable.

    The allowed suboptions are:

    {disallow, [Optionname, ...]}
    Disallows the usage of those options in the included configuration file. The options that match this criteria are not accepted. The default value is an empty list: []
    {allow_only, [Optionname, ...]}
    Allows only the usage of those options in the included configuration file. The options that do not match this criteria are not accepted. The default value is: all

    This is a basic example:

    {include_config_file, "/etc/ejabberd/additional.cfg"}.
    

    In this example, the included file is not allowed to contain a listen option. If such an option is present, the option will not be accepted. The file is in a subdirectory from where the main configuration file is.

    {include_config_file, "./example.org/additional_not_listen.cfg", [{disallow, [listen]}]}.
    

    In this example, ejabberd.cfg defines some ACL and Access rules, and later includes another file with additional rules:

    {acl, admin, {user, "admin", "localhost"}}.
    {access, announce, [{allow, admin}]}.
    {include_config_file, "/etc/ejabberd/acl_and_access.cfg", [{allow_only, [acl, access]}]}.
    

    and content of the file acl_and_access.cfg can be, for example:

    {acl, admin, {user, "bob", "localhost"}}.
    {acl, admin, {user, "jan", "localhost"}}.
    

    3.1.11  Option Macros in Configuration File

    In the ejabberd configuration file, it is possible to define a macro for a value and later use this macro when defining an option.

    A macro is defined with this syntax:

    {define_macro, ’MACRO’, Value}.

    The MACRO must be surrounded by single quotation marks, and all letters in uppercase; check the examples bellow. The value can be any valid arbitrary Erlang term.

    The first definition of a macro is preserved, and additional definitions of the same macro are forgotten.

    Macros are processed after additional configuration files have been included, so it is possible to use macros that are defined in configuration files included before the usage.

    It isn’t possible to use a macro in the definition of another macro.

    There are two ways to use a macro:

    ’MACRO’
    You can put this instead of a value in an ejabberd option, and will be replaced with the value previously defined. If the macro is not defined previously, the program will crash and report an error.
    {use_macro, ’MACRO’, Defaultvalue}
    Use a macro even if it may not be defined. If the macro is not defined previously, the provided defaultvalue is used. This usage behaves as if it were defined and used this way:
    {define_macro, 'MACRO', Defaultvalue}.
    'MACRO'
    

    This example shows the basic usage of a macro:

    {define_macro, 'LOG_LEVEL_NUMBER', 5}.
    {loglevel, 'LOG_LEVEL_NUMBER'}.
    

    The resulting option interpreted by ejabberd is: {loglevel, 5}.

    This example shows that values can be any arbitrary Erlang term:

    {define_macro, 'USERBOB', {user, "bob", "localhost"}}.
    {acl, admin, 'USERBOB'}.
    

    The resulting option interpreted by ejabberd is: {acl, admin, {user, "bob", "localhost"}}.

    This complex example:

    {define_macro, 'NUMBER_PORT_C2S', 5222}.
    {define_macro, 'PORT_S2S_IN', {5269, ejabberd_s2s_in, []}}.
    {listen,
     [
      {'NUMBER_PORT_C2S', ejabberd_c2s, []},
      'PORT_S2S_IN',
      {{use_macro, 'NUMBER_PORT_HTTP', 5280}, ejabberd_http, []}
     ]
    }.
    

    produces this result after being interpreted:

    {listen,
     [
      {5222, ejabberd_c2s, []},
      {5269, ejabberd_s2s_in, []},
      {5280, ejabberd_http, []}
     ]
    }.
    

    3.2  Database and LDAP Configuration

    ejabberd uses its internal Mnesia database by default. However, it is possible to use a relational database or an LDAP server to store persistent, long-living data. ejabberd is very flexible: you can configure different authentication methods for different virtual hosts, you can configure different authentication mechanisms for the same virtual host (fallback), you can set different storage systems for modules, and so forth.

    The following databases are supported by ejabberd:

    The following LDAP servers are tested with ejabberd:

    Important note about virtual hosting: if you define several domains in ejabberd.cfg (see section 3.1.1), you probably want that each virtual host uses a different configuration of database, authentication and storage, so that usernames do not conflict and mix between different virtual hosts. For that purpose, the options described in the next sections must be set inside a host_config for each vhost (see section 3.1.2). For example:

    {host_config, "public.example.org", [
      {odbc_server, {pgsql, "localhost", "database-public-example-org", "ejabberd", "password"}},
      {auth_method, [odbc]}
    ]}.
    

    3.2.1  MySQL

    Although this section will describe ejabberd’s configuration when you want to use the native MySQL driver, it does not describe MySQL’s installation and database creation. Check the MySQL documentation and the tutorial Using ejabberd with MySQL native driver for information regarding these topics. Note that the tutorial contains information about ejabberd’s configuration which is duplicate to this section.

    Moreover, the file mysql.sql in the directory src/odbc might be interesting for you. This file contains the ejabberd schema for MySQL. At the end of the file you can find information to update your database schema.

    Driver Compilation

    You can skip this step if you installed ejabberd using a binary installer or if the binary packages of ejabberd you are using include support for MySQL.

    1. First, install the Erlang MySQL library. Make sure the compiled files are in your Erlang path; you can put them for example in the same directory as your ejabberd .beam files.
    2. Then, configure and install ejabberd with ODBC support enabled (this is also needed for native MySQL support!). This can be done, by using next commands:
      ./configure --enable-odbc && make install
      

    Database Connection

    The actual database access is defined in the option odbc_server. Its value is used to define if we want to use ODBC, or one of the two native interface available, PostgreSQL or MySQL.

    To use the native MySQL interface, you can pass a tuple of the following form as parameter:

    {mysql, "Server", "Database", "Username", "Password"}

    mysql is a keyword that should be kept as is. For example:

    {odbc_server, {mysql, "localhost", "test", "root", "password"}}.

    Optionally, it is possible to define the MySQL port to use. This option is only useful, in very rare cases, when you are not running MySQL with the default port setting. The mysql parameter can thus take the following form:

    {mysql, "Server", Port, "Database", "Username", "Password"}

    The Port value should be an integer, without quotes. For example:

    {odbc_server, {mysql, "localhost", Port, "test", "root", "password"}}.

    By default ejabberd opens 10 connections to the database for each virtual host. Use this option to modify the value:

    {odbc_pool_size, 10}.
    

    You can configure an interval to make a dummy SQL request to keep alive the connections to the database. The default value is ’undefined’, so no keepalive requests are made. Specify in seconds: for example 28800 means 8 hours.

    {odbc_keepalive_interval, undefined}.
    

    If the connection to the database fails, ejabberd waits 30 seconds before retrying. You can modify this interval with this option:

    {odbc_start_interval, 30}.
    

    Authentication

    The option value name may be misleading, as the auth_method name is used for access to a relational database through ODBC, as well as through the native MySQL interface. Anyway, the first configuration step is to define the odbc auth_method. For example:

    {auth_method, [odbc]}.
    

    Storage

    MySQL also can be used to store information into from several ejabberd modules. See section 3.3.1 to see which modules have a version with the ‘_odbc’. This suffix indicates that the module can be used with relational databases like MySQL. To enable storage to your database, just make sure that your database is running well (see previous sections), and replace the suffix-less or ldap module variant with the odbc module variant. Keep in mind that you cannot have several variants of the same module loaded!

    3.2.2  Microsoft SQL Server

    Although this section will describe ejabberd’s configuration when you want to use Microsoft SQL Server, it does not describe Microsoft SQL Server’s installation and database creation. Check the MySQL documentation and the tutorial Using ejabberd with MySQL native driver for information regarding these topics. Note that the tutorial contains information about ejabberd’s configuration which is duplicate to this section.

    Moreover, the file mssql.sql in the directory src/odbc might be interesting for you. This file contains the ejabberd schema for Microsoft SQL Server. At the end of the file you can find information to update your database schema.

    Driver Compilation

    You can skip this step if you installed ejabberd using a binary installer or if the binary packages of ejabberd you are using include support for ODBC.

    If you want to use Microsoft SQL Server with ODBC, you need to configure, compile and install ejabberd with support for ODBC and Microsoft SQL Server enabled. This can be done, by using next commands:

    ./configure --enable-odbc --enable-mssql && make install
    

    Database Connection

    The configuration of Database Connection for a Microsoft SQL Server is the same as the configuration for ODBC compatible servers (see section 3.2.4).

    Authentication

    The configuration of Authentication for a Microsoft SQL Server is the same as the configuration for ODBC compatible servers (see section 3.2.4).

    Storage

    Microsoft SQL Server also can be used to store information into from several ejabberd modules. See section 3.3.1 to see which modules have a version with the ‘_odbc’. This suffix indicates that the module can be used with relational databases like Microsoft SQL Server. To enable storage to your database, just make sure that your database is running well (see previous sections), and replace the suffix-less or ldap module variant with the odbc module variant. Keep in mind that you cannot have several variants of the same module loaded!

    3.2.3  PostgreSQL

    Although this section will describe ejabberd’s configuration when you want to use the native PostgreSQL driver, it does not describe PostgreSQL’s installation and database creation. Check the PostgreSQL documentation and the tutorial Using ejabberd with MySQL native driver for information regarding these topics. Note that the tutorial contains information about ejabberd’s configuration which is duplicate to this section.

    Also the file pg.sql in the directory src/odbc might be interesting for you. This file contains the ejabberd schema for PostgreSQL. At the end of the file you can find information to update your database schema.

    Driver Compilation

    You can skip this step if you installed ejabberd using a binary installer or if the binary packages of ejabberd you are using include support for PostgreSQL.

    1. First, install the Erlang pgsql library from ejabberd-modules SVN repository. Make sure the compiled files are in your Erlang path; you can put them for example in the same directory as your ejabberd .beam files.
    2. Then, configure, compile and install ejabberd with ODBC support enabled (this is also needed for native PostgreSQL support!). This can be done, by using next commands:
      ./configure --enable-odbc && make install
      

    Database Connection

    The actual database access is defined in the option odbc_server. Its value is used to define if we want to use ODBC, or one of the two native interface available, PostgreSQL or MySQL.

    To use the native PostgreSQL interface, you can pass a tuple of the following form as parameter:

    {pgsql, "Server", "Database", "Username", "Password"}

    pgsql is a keyword that should be kept as is. For example:

    {odbc_server, {pgsql, "localhost", "database", "ejabberd", "password"}}.

    Optionally, it is possible to define the PostgreSQL port to use. This option is only useful, in very rare cases, when you are not running PostgreSQL with the default port setting. The pgsql parameter can thus take the following form:

    {pgsql, "Server", Port, "Database", "Username", "Password"}

    The Port value should be an integer, without quotes. For example:

    {odbc_server, {pgsql, "localhost", 5432, "database", "ejabberd", "password"}}.

    By default ejabberd opens 10 connections to the database for each virtual host. Use this option to modify the value:

    {odbc_pool_size, 10}.
    

    You can configure an interval to make a dummy SQL request to keep alive the connections to the database. The default value is ’undefined’, so no keepalive requests are made. Specify in seconds: for example 28800 means 8 hours.

    {odbc_keepalive_interval, undefined}.
    

    Authentication

    The option value name may be misleading, as the auth_method name is used for access to a relational database through ODBC, as well as through the native PostgreSQL interface. Anyway, the first configuration step is to define the odbc auth_method. For example:

    {auth_method, [odbc]}.
    

    Storage

    PostgreSQL also can be used to store information into from several ejabberd modules. See section 3.3.1 to see which modules have a version with the ‘_odbc’. This suffix indicates that the module can be used with relational databases like PostgreSQL. To enable storage to your database, just make sure that your database is running well (see previous sections), and replace the suffix-less or ldap module variant with the odbc module variant. Keep in mind that you cannot have several variants of the same module loaded!

    3.2.4  ODBC Compatible

    Although this section will describe ejabberd’s configuration when you want to use the ODBC driver, it does not describe the installation and database creation of your database. Check the documentation of your database. The tutorial Using ejabberd with MySQL native driver also can help you. Note that the tutorial contains information about ejabberd’s configuration which is duplicate to this section.

    Driver Compilation

    You can skip this step if you installed ejabberd using a binary installer or if the binary packages of ejabberd you are using include support for ODBC.

    1. First, install the Erlang MySQL library. Make sure the compiled files are in your Erlang path; you can put them for example in the same directory as your ejabberd .beam files.
    2. Then, configure, compile and install ejabberd with ODBC support enabled. This can be done, by using next commands:
      ./configure --enable-odbc && make install
      

    Database Connection

    The actual database access is defined in the option odbc_server. Its value is used to defined if we want to use ODBC, or one of the two native interface available, PostgreSQL or MySQL.

    To use a relational database through ODBC, you can pass the ODBC connection string as odbc_server parameter. For example:

    {odbc_server, "DSN=database;UID=ejabberd;PWD=password"}.
    

    By default ejabberd opens 10 connections to the database for each virtual host. Use this option to modify the value:

    {odbc_pool_size, 10}.
    

    You can configure an interval to make a dummy SQL request to keep alive the connections to the database. The default value is ’undefined’, so no keepalive requests are made. Specify in seconds: for example 28800 means 8 hours.

    {odbc_keepalive_interval, undefined}.
    

    Authentication

    The first configuration step is to define the odbc auth_method. For example:

    {auth_method, [odbc]}.
    

    Storage

    An ODBC compatible database also can be used to store information into from several ejabberd modules. See section 3.3.1 to see which modules have a version with the ‘_odbc’. This suffix indicates that the module can be used with ODBC compatible relational databases. To enable storage to your database, just make sure that your database is running well (see previous sections), and replace the suffix-less or ldap module variant with the odbc module variant. Keep in mind that you cannot have several variants of the same module loaded!

    3.2.5  LDAP

    ejabberd has built-in LDAP support. You can authenticate users against LDAP server and use LDAP directory as vCard storage.

    Usually ejabberd treats LDAP as a read-only storage: it is possible to consult data, but not possible to create accounts or edit vCard that is stored in LDAP. However, it is possible to change passwords if mod_register module is enabled and LDAP server supports RFC 3062.

    Connection

    Two connections are established to the LDAP server per vhost, one for authentication and other for regular calls.

    Parameters:

    {ldap_servers, [Servers, ...]}
    List of IP addresses or DNS names of your LDAP servers. This option is required.
    {ldap_encrypt, none|tls}
    Type of connection encryption to the LDAP server. Allowed values are: none, tls. The value tls enables encryption by using LDAP over SSL. Note that STARTTLS encryption is not supported. The default value is: none.
    {ldap_tls_verify, false|soft|hard}
    This option specifies whether to verify LDAP server certificate or not when TLS is enabled. When hard is enabled ejabberd doesn’t proceed if a certificate is invalid. When soft is enabled ejabberd proceeds even if check fails. The default is false which means no checks are performed.
    {ldap_tls_cacertfile, Path}
    Path to file containing PEM encoded CA certificates. This option is needed (and required) when TLS verification is enabled.
    {ldap_tls_depth, Number}
    Specifies the maximum verification depth when TLS verification is enabled, i.e. how far in a chain of certificates the verification process can proceed before the verification is considered to fail. Peer certificate = 0, CA certificate = 1, higher level CA certificate = 2, etc. The value 2 thus means that a chain can at most contain peer cert, CA cert, next CA cert, and an additional CA cert. The default value is 1.
    {ldap_port, Number}
    Port to connect to your LDAP server. The default port is 389 if encryption is disabled; and 636 if encryption is enabled. If you configure a value, it is stored in ejabberd’s database. Then, if you remove that value from the configuration file, the value previously stored in the database will be used instead of the default port.
    {ldap_rootdn, RootDN}
    Bind DN. The default value is "" which means ‘anonymous connection’.
    {ldap_password, Password}
    Bind password. The default value is "".
    {ldap_deref_aliases, never|always|finding|searching}
    Whether or not to dereference aliases. The default is never.

    Example:

    {auth_method, ldap}.
    {ldap_servers, ["ldap.example.org"]}.
    {ldap_port, 389}.
    {ldap_rootdn, "cn=Manager,dc=domain,dc=org"}.
    {ldap_password, "secret"}.
    

    Authentication

    You can authenticate users against an LDAP directory. Note that current LDAP implementation does not support SASL authentication.

    Available options are:

    {ldap_base, Base}
    LDAP base directory which stores users accounts. This option is required.
    {ldap_uids, [ {ldap_uidattr} | {ldap_uidattr, ldap_uidattr_format}, ...]}
    LDAP attribute which holds a list of attributes to use as alternatives for getting the JID. The default attributes are [{"uid", "%u"}]. The attributes are of the form: [{ldap_uidattr}] or [{ldap_uidattr, ldap_uidattr_format}]. You can use as many comma separated attributes as needed. The values for ldap_uidattr and ldap_uidattr_format are described as follow:
    ldap_uidattr
    LDAP attribute which holds the user’s part of a JID. The default value is "uid".
    ldap_uidattr_format
    Format of the ldap_uidattr variable. The format must contain one and only one pattern variable "%u" which will be replaced by the user’s part of a JID. For example, "%u@example.org". The default value is "%u".
    {ldap_filter, Filter}
    RFC 4515 LDAP filter. The default Filter value is: undefined. Example: "(&(objectClass=shadowAccount)(memberOf=Jabber Users))". Please, do not forget to close brackets and do not use superfluous whitespaces. Also you must not use ldap_uidattr attribute in filter because this attribute will be substituted in LDAP filter automatically.
    {ldap_dn_filter, { Filter, FilterAttrs }}
    This filter is applied on the results returned by the main filter. This filter performs additional LDAP lookup to make the complete result. This is useful when you are unable to define all filter rules in ldap_filter. You can define "%u", "%d", "%s" and "%D" pattern variables in Filter: "%u" is replaced by a user’s part of a JID, "%d" is replaced by the corresponding domain (virtual host), all "%s" variables are consecutively replaced by values of FilterAttrs attributes and "%D" is replaced by Distinguished Name. By default ldap_dn_filter is undefined. Example:
    {ldap_dn_filter, {"(&(name=%s)(owner=%D)(user=%u@%d))", ["sn"]}}.
    
    Since this filter makes additional LDAP lookups, use it only in the last resort: try to define all filter rules in ldap_filter if possible.
    {ldap_local_filter, Filter}
    If you can’t use ldap_filter due to performance reasons (the LDAP server has many users registered), you can use this local filter. The local filter checks an attribute in ejabberd, not in LDAP, so this limits the load on the LDAP directory. The default filter is: undefined. Example values:
    {ldap_local_filter, {notequal, {"accountStatus",["disabled"]}}}.
    {ldap_local_filter, {equal, {"accountStatus",["enabled"]}}}.
    {ldap_local_filter, undefined}.
    

    Examples

    Common example

    Let’s say ldap.example.org is the name of our LDAP server. We have users with their passwords in "ou=Users,dc=example,dc=org" directory. Also we have addressbook, which contains users emails and their additional infos in "ou=AddressBook,dc=example,dc=org" directory. The connection to the LDAP server is encrypted using TLS, and using the custom port 6123. Corresponding authentication section should looks like this:

    %% Authentication method
    {auth_method, ldap}.
    %% DNS name of our LDAP server
    {ldap_servers, ["ldap.example.org"]}.
    %% Bind to LDAP server as "cn=Manager,dc=example,dc=org" with password "secret"
    {ldap_rootdn, "cn=Manager,dc=example,dc=org"}.
    {ldap_password, "secret"}.
    {ldap_encrypt, tls}.
    {ldap_port, 6123}.
    %% Define the user's base
    {ldap_base, "ou=Users,dc=example,dc=org"}.
    %% We want to authorize users from 'shadowAccount' object class only
    {ldap_filter, "(objectClass=shadowAccount)"}.
    

    Now we want to use users LDAP-info as their vCards. We have four attributes defined in our LDAP schema: "mail" — email address, "givenName" — first name, "sn" — second name, "birthDay" — birthday. Also we want users to search each other. Let’s see how we can set it up:

    {modules,
     [
      ...
      {mod_vcard_ldap,
       [
        %% We use the same server and port, but want to bind anonymously because
        %% our LDAP server accepts anonymous requests to
        %% "ou=AddressBook,dc=example,dc=org" subtree.
        {ldap_rootdn, ""},
        {ldap_password, ""},
        %% define the addressbook's base
        {ldap_base, "ou=AddressBook,dc=example,dc=org"},
        %% uidattr: user's part of JID is located in the "mail" attribute
        %% uidattr_format: common format for our emails
        {ldap_uids, [{"mail", "%u@mail.example.org"}]},
        %% We have to define empty filter here, because entries in addressbook does not
        %% belong to shadowAccount object class
        {ldap_filter, ""},
        %% Now we want to define vCard pattern
        {ldap_vcard_map,
         [{"NICKNAME", "%u", []}, % just use user's part of JID as his nickname
          {"GIVEN", "%s", ["givenName"]},
          {"FAMILY", "%s", ["sn"]},
          {"FN", "%s, %s", ["sn", "givenName"]}, % example: "Smith, John"
          {"EMAIL", "%s", ["mail"]},
          {"BDAY", "%s", ["birthDay"]}]},
        %% Search form
        {ldap_search_fields,
         [{"User", "%u"},
          {"Name", "givenName"},
          {"Family Name", "sn"},
          {"Email", "mail"},
          {"Birthday", "birthDay"}]},
        %% vCard fields to be reported
        %% Note that JID is always returned with search results
        {ldap_search_reported,
         [{"Full Name", "FN"},
          {"Nickname", "NICKNAME"},
          {"Birthday", "BDAY"}]}
      ]},
      ...
     ]}.
    

    Note that mod_vcard_ldap module checks for the existence of the user before searching in his information in LDAP.

    Active Directory

    Active Directory is just an LDAP-server with predefined attributes. A sample configuration is shown below:

    {auth_method, ldap}.
    {ldap_servers, ["office.org"]}.    % List of LDAP servers
    {ldap_base, "DC=office,DC=org"}. % Search base of LDAP directory
    {ldap_rootdn, "CN=Administrator,CN=Users,DC=office,DC=org"}. % LDAP manager
    {ldap_password, "*******"}. % Password to LDAP manager
    {ldap_uids, [{"sAMAccountName"}]}.
    {ldap_filter, "(memberOf=*)"}.
    
    {modules,
     [
      ...
      {mod_vcard_ldap,
       [{ldap_vcard_map,
         [{"NICKNAME", "%u", []},
          {"GIVEN", "%s", ["givenName"]},
          {"MIDDLE", "%s", ["initials"]},
          {"FAMILY", "%s", ["sn"]},
          {"FN", "%s", ["displayName"]},
          {"EMAIL", "%s", ["mail"]},
          {"ORGNAME", "%s", ["company"]},
          {"ORGUNIT", "%s", ["department"]},
          {"CTRY", "%s", ["c"]},
          {"LOCALITY", "%s", ["l"]},
          {"STREET", "%s", ["streetAddress"]},
          {"REGION", "%s", ["st"]},
          {"PCODE", "%s", ["postalCode"]},
          {"TITLE", "%s", ["title"]},
          {"URL", "%s", ["wWWHomePage"]},
          {"DESC", "%s", ["description"]},
          {"TEL", "%s", ["telephoneNumber"]}]},
        {ldap_search_fields,
         [{"User", "%u"},
          {"Name", "givenName"},
          {"Family Name", "sn"},
          {"Email", "mail"},
          {"Company", "company"},
          {"Department", "department"},
          {"Role", "title"},
          {"Description", "description"},
          {"Phone", "telephoneNumber"}]},
        {ldap_search_reported,
         [{"Full Name", "FN"},
          {"Nickname", "NICKNAME"},
          {"Email", "EMAIL"}]}
      ]},
      ...
     ]}.
    

    3.3  Modules Configuration

    The option modules defines the list of modules that will be loaded after ejabberd’s startup. Each entry in the list is a tuple in which the first element is the name of a module and the second is a list of options for that module.

    The syntax is:

    {modules, [ {ModuleName, ModuleOptions}, ...]}.

    Examples:

    • In this example only the module mod_echo is loaded and no module options are specified between the square brackets:
      {modules,
       [
        {mod_echo,      []}
       ]}.
      
    • In the second example the modules mod_echo, mod_time, and mod_version are loaded without options. Remark that, besides the last entry, all entries end with a comma:
      {modules,
       [
        {mod_echo,      []},
        {mod_time,      []},
        {mod_version,   []}
       ]}.
      

    3.3.1  Modules Overview

    The following table lists all modules included in ejabberd.


    ModuleFeatureDependencies
    mod_adhocAd-Hoc Commands (XEP-0050) 
    mod_announceManage announcementsrecommends mod_adhoc
    mod_announce_odbcManage announcementsrecommends mod_adhoc
      supported DB (*)
    mod_blockingSimple Communications Blocking (XEP-0191)mod_privacy
    mod_blocking_odbcSimple Communications Blocking (XEP-0191)mod_privacy_odbc
    mod_capsEntity Capabilities (XEP-0115) 
    mod_configureServer configuration using Ad-Hocmod_adhoc
    mod_discoService Discovery (XEP-0030) 
    mod_echoEchoes XMPP stanzas 
    mod_http_bindXMPP over Bosh service (HTTP Binding) 
    mod_http_fileserverSmall HTTP file server 
    mod_ircIRC transport 
    mod_irc_odbcIRC transportsupported DB (*)
    mod_lastLast Activity (XEP-0012) 
    mod_last_odbcLast Activity (XEP-0012)supported DB (*)
    mod_mucMulti-User Chat (XEP-0045) 
    mod_muc_odbcMulti-User Chat (XEP-0045)supported DB (*)
    mod_muc_logMulti-User Chat room loggingmod_muc or mod_muc_odbc
    mod_offlineOffline message storage (XEP-0160) 
    mod_offline_odbcOffline message storage (XEP-0160)supported DB (*)
    mod_pingXMPP Ping and periodic keepalives (XEP-0199) 
    mod_pres_counterDetect presence subscription flood 
    mod_privacyBlocking Communication (XEP-0016) 
    mod_privacy_odbcBlocking Communication (XEP-0016)supported DB (*)
    mod_privatePrivate XML Storage (XEP-0049) 
    mod_private_odbcPrivate XML Storage (XEP-0049)supported DB (*)
    mod_proxy65SOCKS5 Bytestreams (XEP-0065) 
    mod_pubsubPub-Sub (XEP-0060), PEP (XEP-0163)mod_caps
    mod_pubsub_odbcPub-Sub (XEP-0060), PEP (XEP-0163)supported DB (*) and mod_caps
    mod_registerIn-Band Registration (XEP-0077) 
    mod_register_webWeb for Account Registrations 
    mod_rosterRoster management (XMPP IM) 
    mod_roster_odbcRoster management (XMPP IM)supported DB (*)
    mod_service_logCopy user messages to logger service 
    mod_shared_rosterShared roster managementmod_roster or
      mod_roster_odbc
    mod_shared_roster_odbcShared roster managementsupported DB (*) and
      mod_roster or mod_roster_odbc
    mod_shared_roster_ldapLDAP Shared roster managementmod_roster or
      mod_roster_odbc
    mod_sicServer IP Check (XEP-0279) 
    mod_statsStatistics Gathering (XEP-0039) 
    mod_timeEntity Time (XEP-0202) 
    mod_vcardvcard-temp (XEP-0054) 
    mod_vcard_ldapvcard-temp (XEP-0054)LDAP server
    mod_vcard_odbcvcard-temp (XEP-0054)supported DB (*)
    mod_vcard_xupdatevCard-Based Avatars (XEP-0153)mod_vcard or mod_vcard_odbc
    mod_vcard_xupdate_odbcvCard-Based Avatars (XEP-0153)mod_vcard or mod_vcard_odbc
    mod_versionSoftware Version (XEP-0092) 

    • (*) This module requires a supported database. For a list of supported databases, see section 3.2.

    You can see which database backend each module needs by looking at the suffix:

    • No suffix, this means that the modules uses Erlang’s built-in database Mnesia as backend.
    • ‘_odbc’, this means that the module needs a supported database (see 3.2) as backend.
    • ‘_ldap’, this means that the module needs an LDAP server as backend.

    If you want to, it is possible to use a relational database to store the tables created by some ejabberd modules. You can do this by changing the module name to a name with an _odbc suffix in ejabberd config file. You can use a relational database for the following data:

    • Last connection date and time: Use mod_last_odbc instead of mod_last.
    • Offline messages: Use mod_offline_odbc instead of mod_offline.
    • Rosters: Use mod_roster_odbc instead of mod_roster.
    • Shared Rosters: Use mod_shared_roster_odbc instead of mod_shared_roster.
    • Users’ VCARD: Use mod_vcard_odbc instead of mod_vcard.
    • vCard-Based Avatars: Use mod_vcard_xupdate_odbc instead of mod_vcard_xupdate.
    • Private XML storage: Use mod_private_odbc instead of mod_private.
    • User rules for blocking communications: Use mod_privacy_odbc instead of mod_privacy.
    • Simple Communications Blocking: Use mod_blocking_odbc instead of mod_blocking.
    • Pub-Sub nodes, items and subscriptions: Use mod_pubsub_odbc instead of mod_pubsub.
    • Multi-user chats: Use mod_muc_odbc instead of mod_muc.
    • Manage announcements: Use mod_announce_odbc instead of mod_announce.
    • IRC transport: Use mod_irc_odbc instead of mod_irc.

    You can find more contributed modules on the ejabberd website. Please remember that these contributions might not work or that they can contain severe bugs and security leaks. Therefore, use them at your own risk!

    3.3.2  Common Options

    The following options are used by many modules. Therefore, they are described in this separate section.

    iqdisc

    Many modules define handlers for processing IQ queries of different namespaces to this server or to a user (e. g. to example.org or to user@example.org). This option defines processing discipline for these queries.

    The syntax is:

    {iqdisc, Value}

    Possible Value are:

    no_queue
    All queries of a namespace with this processing discipline are processed directly. This means that the XMPP connection that sends this IQ query gets blocked: no other packets can be processed until this one has been completely processed. Hence this discipline is not recommended if the processing of a query can take a relatively long time.
    one_queue
    In this case a separate queue is created for the processing of IQ queries of a namespace with this discipline. In addition, the processing of this queue is done in parallel with that of other packets. This discipline is most recommended.
    {queues, N}
    N separate queues are created to process the queries. The queries are thus processed in parallel, but in a controlled way.
    parallel
    For every packet with this discipline a separate Erlang process is spawned. Consequently, all these packets are processed in parallel. Although spawning of Erlang process has a relatively low cost, this can break the server’s normal work, because the Erlang emulator has a limit on the number of processes (32000 by default).

    Example:

    {modules,
     [
      ...
      {mod_time, [{iqdisc, no_queue}]},
      ...
     ]}.
    

    host

    This option defines the Jabber ID of a service provided by an ejabberd module.

    The syntax is:

    {host, HostName}

    If you include the keyword "@HOST@" in the HostName, it is replaced at start time with the real virtual host string.

    This example configures the echo module to provide its echoing service in the Jabber ID mirror.example.org:

    {modules,
     [
      ...
      {mod_echo, [{host, "mirror.example.org"}]},
      ...
     ]}.
    

    However, if there are several virtual hosts and this module is enabled in all of them, the "@HOST@" keyword must be used:

    {modules,
     [
      ...
      {mod_echo, [{host, "mirror.@HOST@"}]},
      ...
     ]}.
    

    3.3.3  mod_announce

    This module enables configured users to broadcast announcements and to set the message of the day (MOTD). Configured users can perform these actions with a XMPP client either using Ad-hoc commands or sending messages to specific JIDs.

    The Ad-hoc commands are listed in the Server Discovery. For this feature to work, mod_adhoc must be enabled.

    The specific JIDs where messages can be sent are listed bellow. The first JID in each entry will apply only to the specified virtual host example.org, while the JID between brackets will apply to all virtual hosts in ejabberd.

    example.org/announce/all (example.org/announce/all-hosts/all)
    The message is sent to all registered users. If the user is online and connected to several resources, only the resource with the highest priority will receive the message. If the registered user is not connected, the message will be stored offline in assumption that offline storage (see section 3.3.12) is enabled.
    example.org/announce/online (example.org/announce/all-hosts/online)
    The message is sent to all connected users. If the user is online and connected to several resources, all resources will receive the message.
    example.org/announce/motd (example.org/announce/all-hosts/motd)
    The message is set as the message of the day (MOTD) and is sent to users when they login. In addition the message is sent to all connected users (similar to announce/online).
    example.org/announce/motd/update (example.org/announce/all-hosts/motd/update)
    The message is set as message of the day (MOTD) and is sent to users when they login. The message is not sent to any currently connected user.
    example.org/announce/motd/delete (example.org/announce/all-hosts/motd/delete)
    Any message sent to this JID removes the existing message of the day (MOTD).

    Options:

    {access, AccessName}
    This option specifies who is allowed to send announcements and to set the message of the day (by default, nobody is able to send such messages).

    Examples:

    • Only administrators can send announcements:
      {access, announce, [{allow, admin}]}.
      
      {modules,
       [
        ...
        {mod_adhoc, []},
        {mod_announce, [{access, announce}]},
        ...
       ]}.
      
    • Administrators as well as the direction can send announcements:
      {acl, direction, {user, "big_boss", "example.org"}}.
      {acl, direction, {user, "assistant", "example.org"}}.
      {acl, admin, {user, "admin", "example.org"}}.
      
      {access, announce, [{allow, admin},
                          {allow, direction}]}.
      
      {modules,
       [
        ...
        {mod_adhoc, []},
        {mod_announce, [{access, announce}]},
        ...
       ]}.
      

    Note that mod_announce can be resource intensive on large deployments as it can broadcast lot of messages. This module should be disabled for instances of ejabberd with hundreds of thousands users.

    3.3.4  mod_disco

    This module adds support for Service Discovery (XEP-0030). With this module enabled, services on your server can be discovered by XMPP clients. Note that ejabberd has no modules with support for the superseded Jabber Browsing (XEP-0011) and Agent Information (XEP-0094). Accordingly, XMPP clients need to have support for the newer Service Discovery protocol if you want them be able to discover the services you offer.

    Options:

    {iqdisc, Discipline}
    This specifies the processing discipline for Service Discovery (http://jabber.org/protocol/disco#items and http://jabber.org/protocol/disco#info) IQ queries (see section 3.3.2).
    {extra_domains, [Domain, ...]}
    With this option, you can specify a list of extra domains that are added to the Service Discovery item list.
    {server_info, [ {Modules, Field, [Value, ...]}, ... ]}
    Specify additional information about the server, as described in Contact Addresses for XMPP Services (XEP-0157). Modules can be the keyword ‘all’, in which case the information is reported in all the services; or a list of ejabberd modules, in which case the information is only specified for the services provided by those modules. Any arbitrary Field and Value can be specified, not only contact addresses.

    Examples:

    • To serve a link to the Jabber User Directory on jabber.org:
      {modules,
       [
        ...
        {mod_disco, [{extra_domains, ["users.jabber.org"]}]},
        ...
       ]}.
      
    • To serve a link to the transports on another server:
      {modules,
       [
        ...
        {mod_disco, [{extra_domains, ["icq.example.com",
                                      "msn.example.com"]}]},
        ...
       ]}.
      
    • To serve a link to a few friendly servers:
      {modules,
       [
        ...
        {mod_disco, [{extra_domains, ["example.org",
                                      "example.com"]}]},
        ...
       ]}.
      
    • With this configuration, all services show abuse addresses, feedback address on the main server, and admin addresses for both the main server and the vJUD service:
      {modules,
       [
        ...
        {mod_disco, [{server_info, [
            {all,
             "abuse-addresses",
             ["mailto:abuse@shakespeare.lit"]},
            {[mod_muc],
             "Web chatroom logs",
             ["http://www.example.org/muc-logs"]},
            {[mod_disco],
             "feedback-addresses",
             ["http://shakespeare.lit/feedback.php", "mailto:feedback@shakespeare.lit", "xmpp:feedback@shakespeare.lit"]},
            {[mod_disco, mod_vcard],
             "admin-addresses",
             ["mailto:xmpp@shakespeare.lit", "xmpp:admins@shakespeare.lit"]}
        ]}]},
        ...
       ]}.
      

    3.3.5  mod_echo

    This module simply echoes any XMPP packet back to the sender. This mirror can be of interest for ejabberd and XMPP client debugging.

    Options:

    {host, HostName}
    This option defines the Jabber ID of the service. If the host option is not specified, the Jabber ID will be the hostname of the virtual host with the prefix ‘echo.’. The keyword "@HOST@" is replaced at start time with the real virtual host name.

    Example: Mirror, mirror, on the wall, who is the most beautiful of them all?

    {modules,
     [
      ...
      {mod_echo, [{host, "mirror.example.org"}]},
      ...
     ]}.
    

    3.3.6  mod_http_bind

    This module implements XMPP over Bosh (formerly known as HTTP Binding) as defined in XEP-0124 and XEP-0206. It extends ejabberd’s built in HTTP service with a configurable resource at which this service will be hosted.

    To use HTTP-Binding, enable the module:

    {modules,
     [
      ...
      {mod_http_bind, []},
      ...
    ]}.
    

    and add http_bind in the HTTP service. For example:

    {listen, 
     [
      ...
      {5280, ejabberd_http, [
                             http_bind,
                             http_poll,
                             web_admin
                            ]
      },
      ...
    ]}.
    

    With this configuration, the module will serve the requests sent to http://example.org:5280/http-bind/ Remember that this page is not designed to be used by web browsers, it is used by XMPP clients that support XMPP over Bosh.

    If you want to set the service in a different URI path or use a different module, you can configure it manually using the option request_handlers. For example:

    {listen, 
     [
      ...
      {5280, ejabberd_http, [
                             {request_handlers, [{["http-bind"], mod_http_bind}]},
                             http_poll,
                             web_admin
                            ]
      },
      ...
    ]}.
    

    Options:

    {max_inactivity, Seconds}
    Define the maximum inactivity period in seconds. Default value is 30 seconds. For example, to set 50 seconds:
    {modules,
     [
      ...
      {mod_http_bind, [ {max_inactivity, 50} ]},
      ...
    ]}.
    

    3.3.7  mod_http_fileserver

    This simple module serves files from the local disk over HTTP.

    Options:

    {docroot, Path}
    Directory to serve the files.
    {accesslog, Path}
    File to log accesses using an Apache-like format. No log will be recorded if this option is not specified.
    {directory_indices, [Index, ...]}
    Indicate one or more directory index files, similarly to Apache’s DirectoryIndex variable. When a web request hits a directory instead of a regular file, those directory indices are looked in order, and the first one found is returned.
    {custom_headers, [ {Name, Value}, ...]}
    Indicate custom HTTP headers to be included in all responses. Default value is: []
    {content_types, [ {Name, Type}, ...]}
    Specify mappings of extension to content type. There are several content types already defined, with this option you can add new definitions, modify or delete existing ones. To delete an existing definition, simply define it with a value: ‘undefined’.
    {default_content_type, Type}
    Specify the content type to use for unknown extensions. Default value is ‘application/octet-stream’.

    This example configuration will serve the files from the local directory /var/www in the address http://example.org:5280/pub/archive/. In this example a new content type ogg is defined, png is redefined, and jpg definition is deleted. To use this module you must enable it:

    {modules,
     [
      ...
      {mod_http_fileserver, [
                             {docroot, "/var/www"}, 
                             {accesslog, "/var/log/ejabberd/access.log"},
                             {directory_indices, ["index.html", "main.htm"]},
                             {custom_headers, [{"X-Powered-By", "Erlang/OTP"},
                                               {"X-Fry", "It's a widely-believed fact!"}
                                              ]},
                             {content_types, [{".ogg", "audio/ogg"},
                                              {".png", "image/png"},
                                              {".jpg", undefined}
                                             ]},
                             {default_content_type, "text/html"}
                            ]
      },
      ...
    ]}.
    

    And define it as a handler in the HTTP service:

    {listen, 
     [
      ...
      {5280, ejabberd_http, [
                             ...
                             {request_handlers, [
                                                 ...
                                                 {["pub", "archive"], mod_http_fileserver},
                                                 ...
                                                ]
                             },
                             ...
                            ]
      },
      ...
    ]}.
    

    3.3.8  mod_irc

    This module is an IRC transport that can be used to join channels on IRC servers.

    End user information:

    • A XMPP client with ‘groupchat 1.0’ support or Multi-User Chat support (XEP-0045) is necessary to join IRC channels.
    • An IRC channel can be joined in nearly the same way as joining a XMPP Multi-User Chat room. The difference is that the room name will be ‘channel%irc.example.org’ in case irc.example.org is the IRC server hosting ‘channel’. And of course the host should point to the IRC transport instead of the Multi-User Chat service.
    • You can register your nickame by sending ‘IDENTIFY password’ to
      nickserver!irc.example.org@irc.jabberserver.org.
    • Entering your password is possible by sending ‘LOGIN nick password’
      to nickserver!irc.example.org@irc.jabberserver.org.
    • The IRC transport provides Ad-Hoc Commands (XEP-0050) to join a channel, and to set custom IRC username and encoding.
    • When using a popular XMPP server, it can occur that no connection can be achieved with some IRC servers because they limit the number of connections from one IP.

    Options:

    {host, HostName}
    This option defines the Jabber ID of the service. If the host option is not specified, the Jabber ID will be the hostname of the virtual host with the prefix ‘irc.’. The keyword "@HOST@" is replaced at start time with the real virtual host name.
    {access, AccessName}
    This option can be used to specify who may use the IRC transport (default value: all).
    {default_encoding, Encoding}
    Set the default IRC encoding. Default value: "iso8859-1"

    Examples:

    • In the first example, the IRC transport is available on (all) your virtual host(s) with the prefix ‘irc.’. Furthermore, anyone is able to use the transport. The default encoding is set to "iso8859-15".
      {modules,
       [
        ...
        {mod_irc, [{access, all}, {default_encoding, "iso8859-15"}]},
        ...
       ]}.
      
    • In next example the IRC transport is available with JIDs with prefix irc-t.net. Moreover, the transport is only accessible to two users of example.org, and any user of example.com:
      {acl, paying_customers, {user, "customer1", "example.org"}}.
      {acl, paying_customers, {user, "customer2", "example.org"}}.
      {acl, paying_customers, {server, "example.com"}}.
      
      {access, irc_users, [{allow, paying_customers}, {deny, all}]}.
      
      {modules,
       [
        ...
        {mod_irc, [{access, irc_users},
                   {host, "irc.example.net"}]},
        ...
       ]}.
      

    3.3.9  mod_last

    This module adds support for Last Activity (XEP-0012). It can be used to discover when a disconnected user last accessed the server, to know when a connected user was last active on the server, or to query the uptime of the ejabberd server.

    Options:

    {iqdisc, Discipline}
    This specifies the processing discipline for Last activity (jabber:iq:last) IQ queries (see section 3.3.2).

    3.3.10  mod_muc

    This module provides a Multi-User Chat (XEP-0045) service. Users can discover existing rooms, join or create them. Occupants of a room can chat in public or have private chats.

    Some of the features of Multi-User Chat:

    • Sending public and private messages to room occupants.
    • Inviting other users to a room.
    • Setting a room subject.
    • Creating password protected rooms.
    • Kicking and banning occupants.

    The MUC service allows any Jabber ID to register a nickname, so nobody else can use that nickname in any room in the MUC service. To register a nickname, open the Service Discovery in your XMPP client and register in the MUC service.

    This module supports clustering and load balancing. One module can be started per cluster node. Rooms are distributed at creation time on all available MUC module instances. The multi-user chat module is clustered but the rooms themselves are not clustered nor fault-tolerant: if the node managing a set of rooms goes down, the rooms disappear and they will be recreated on an available node on first connection attempt.

    Module options:

    {host, HostName}
    This option defines the Jabber ID of the service. If the host option is not specified, the Jabber ID will be the hostname of the virtual host with the prefix ‘conference.’. The keyword "@HOST@" is replaced at start time with the real virtual host name.
    {access, AccessName}
    You can specify who is allowed to use the Multi-User Chat service. By default everyone is allowed to use it.
    {access_create, AccessName}
    To configure who is allowed to create new rooms at the Multi-User Chat service, this option can be used. By default any account in the local ejabberd server is allowed to create rooms.
    {access_persistent, AccessName}
    To configure who is allowed to modify the ’persistent’ room option. By default any account in the local ejabberd server is allowed to modify that option.
    {access_admin, AccessName}
    This option specifies who is allowed to administrate the Multi-User Chat service. The default value is none, which means that only the room creator can administer his room. The administrators can send a normal message to the service JID, and it will be shown in all active rooms as a service message. The administrators can send a groupchat message to the JID of an active room, and the message will be shown in the room as a service message.
    {history_size, Size}
    A small history of the current discussion is sent to users when they enter the room. With this option you can define the number of history messages to keep and send to users joining the room. The value is an integer. Setting the value to 0 disables the history feature and, as a result, nothing is kept in memory. The default value is 20. This value is global and thus affects all rooms on the service.
    {max_users, Number}
    This option defines at the service level, the maximum number of users allowed per room. It can be lowered in each room configuration but cannot be increased in individual room configuration. The default value is 200.
    {max_users_admin_threshold, Number}
    This option defines the number of service admins or room owners allowed to enter the room when the maximum number of allowed occupants was reached. The default limit is 5.
    {max_user_conferences, Number}
    This option defines the maximum number of rooms that any given user can join. The default value is 10. This option is used to prevent possible abuses. Note that this is a soft limit: some users can sometimes join more conferences in cluster configurations.
    {max_room_id, Number}
    This option defines the maximum number of characters that Room ID can have when creating a new room. The default value is to not limit: infinite.
    {max_room_name, Number}
    This option defines the maximum number of characters that Room Name can have when configuring the room. The default value is to not limit: infinite.
    {max_room_desc, Number}
    This option defines the maximum number of characters that Room Description can have when configuring the room. The default value is to not limit: infinite.
    {min_message_interval, Number}
    This option defines the minimum interval between two messages send by an occupant in seconds. This option is global and valid for all rooms. A decimal value can be used. When this option is not defined, message rate is not limited. This feature can be used to protect a MUC service from occupant abuses and limit number of messages that will be broadcasted by the service. A good value for this minimum message interval is 0.4 second. If an occupant tries to send messages faster, an error is send back explaining that the message has been discarded and describing the reason why the message is not acceptable.
    {min_presence_interval, Number}
    This option defines the minimum of time between presence changes coming from a given occupant in seconds. This option is global and valid for all rooms. A decimal value can be used. When this option is not defined, no restriction is applied. This option can be used to protect a MUC service for occupants abuses. If an occupant tries to change its presence more often than the specified interval, the presence is cached by ejabberd and only the last presence is broadcasted to all occupants in the room after expiration of the interval delay. Intermediate presence packets are silently discarded. A good value for this option is 4 seconds.
    {default_room_options, [ {OptionName, OptionValue}, ...]}
    This module option allows to define the desired default room options. Note that the creator of a room can modify the options of his room at any time using an XMPP client with MUC capability. The available room options and the default values are:
    {allow_change_subj, true|false}
    Allow occupants to change the subject.
    {allow_private_messages, true|false}
    Occupants can send private messages to other occupants.
    {allow_private_messages_from_visitors, anyone|moderators|nobody}
    Visitors can send private messages to other occupants.
    {allow_query_users, true|false}
    Occupants can send IQ queries to other occupants.
    {allow_user_invites, false|true}
    Allow occupants to send invitations.
    {allow_visitor_nickchange, true|false}
    Allow visitors to change nickname.
    {allow_visitor_status, true|false}
    Allow visitors to send status text in presence updates. If disallowed, the status text is stripped before broadcasting the presence update to all the room occupants.
    {anonymous, true|false}
    The room is anonymous: occupants don’t see the real JIDs of other occupants. Note that the room moderators can always see the real JIDs of the occupants.
    {captcha_protected, false}
    When a user tries to join a room where he has no affiliation (not owner, admin or member), the room requires him to fill a CAPTCHA challenge (see section 3.1.8) in order to accept her join in the room.
    {logging, false|true}
    The public messages are logged using mod_muc_log.
    {max_users, 200}
    Maximum number of occupants in the room.
    {members_by_default, true|false}
    The occupants that enter the room are participants by default, so they have ’voice’.
    {members_only, false|true}
    Only members of the room can enter.
    {moderated, true|false}
    Only occupants with ’voice’ can send public messages.
    {password, "roompass123"}
    Password of the room. You may want to enable the next option too.
    {password_protected, false|true}
    The password is required to enter the room.
    {persistent, false|true}
    The room persists even if the last participant leaves.
    {public, true|false}
    The room is public in the list of the MUC service, so it can be discovered.
    {public_list, true|false}
    The list of participants is public, without requiring to enter the room.
    {title, "Room Title"}
    A human-readable title of the room.
    All of those room options can be set to true or false, except password and title which are strings, and max_users that is integer.

    Examples:

    • In the first example everyone is allowed to use the Multi-User Chat service. Everyone will also be able to create new rooms but only the user admin@example.org is allowed to administrate any room. In this example he is also a global administrator. When admin@example.org sends a message such as ‘Tomorrow, the XMPP server will be moved to new hardware. This will involve service breakdowns around 23:00 UMT. We apologise for this inconvenience.’ to conference.example.org, it will be displayed in all active rooms. In this example the history feature is disabled.
      {acl, admin, {user, "admin", "example.org"}}.
      
      {access, muc_admin, [{allow, admin}]}.
      
      {modules,
       [
        ...
        {mod_muc, [{access, all},
                   {access_create, all},
                   {access_admin, muc_admin},
                   {history_size, 0}]},
        ...
       ]}.
      
    • In the second example the Multi-User Chat service is only accessible by paying customers registered on our domains and on other servers. Of course the administrator is also allowed to access rooms. In addition, he is the only authority able to create and administer rooms. When admin@example.org sends a message such as ‘Tomorrow, the Jabber server will be moved to new hardware. This will involve service breakdowns around 23:00 UMT. We apologise for this inconvenience.’ to conference.example.org, it will be displayed in all active rooms. No history_size option is used, this means that the feature is enabled and the default value of 20 history messages will be send to the users.
      {acl, paying_customers, {user, "customer1", "example.net"}}.
      {acl, paying_customers, {user, "customer2", "example.com"}}.
      {acl, paying_customers, {user, "customer3", "example.org"}}.
      {acl, admin, {user, "admin", "example.org"}}.
      
      {access, muc_admin, [{allow, admin},
                            {deny, all}]}.
      {access, muc_access, [{allow, paying_customers},
                            {allow, admin},
                            {deny, all}]}.
      
      {modules,
       [
        ...
        {mod_muc, [{access, muc_access},
                   {access_create, muc_admin},
                   {access_admin, muc_admin}]},
        ...
       ]}.
      
    • In the following example, MUC anti abuse options are used. An occupant cannot send more than one message every 0.4 seconds and cannot change its presence more than once every 4 seconds. The length of Room IDs and Room Names are limited to 20 characters, and Room Description to 300 characters. No ACLs are defined, but some user restriction could be added as well:
      {modules,
       [
        ...
        {mod_muc, [{min_message_interval, 0.4},
                   {min_presence_interval, 4},
                   {max_room_id, 20},
                   {max_room_name, 20},
                   {max_room_desc, 300}]},
        ...
       ]}.
      
    • This example shows how to use default_room_options to make sure the newly created rooms have by default those options.
      {modules,
       [
        ...
        {mod_muc, [{access, muc_access},
                   {access_create, muc_admin},
                   {default_room_options,
                    [
                     {allow_change_subj, false},
                     {allow_query_users, true},
                     {allow_private_messages, true},
                     {members_by_default, false},
                     {title, "New chatroom"},
                     {anonymous, false}
                    ]},
                   {access_admin, muc_admin}]},
        ...
       ]}.
      

    3.3.11  mod_muc_log

    This module enables optional logging of Multi-User Chat (MUC) public conversations to HTML. Once you enable this module, users can join a room using a MUC capable XMPP client, and if they have enough privileges, they can request the configuration form in which they can set the option to enable room logging.

    Features:

    • Room details are added on top of each page: room title, JID, author, subject and configuration.
    • The room JID in the generated HTML is a link to join the room (using XMPP URI).
    • Subject and room configuration changes are tracked and displayed.
    • Joins, leaves, nick changes, kicks, bans and ‘/me’ are tracked and displayed, including the reason if available.
    • Generated HTML files are XHTML 1.0 Transitional and CSS compliant.
    • Timestamps are self-referencing links.
    • Links on top for quicker navigation: Previous day, Next day, Up.
    • CSS is used for style definition, and a custom CSS file can be used.
    • URLs on messages and subjects are converted to hyperlinks.
    • Timezone used on timestamps is shown on the log files.
    • A custom link can be added on top of each page.

    Options:

    {access_log, AccessName}
    This option restricts which occupants are allowed to enable or disable room logging. The default value is muc_admin. Note for this default setting you need to have an access rule for muc_admin in order to take effect.
    {cssfile, false|URL}
    With this option you can set whether the HTML files should have a custom CSS file or if they need to use the embedded CSS file. Allowed values are false and an URL to a CSS file. With the first value, HTML files will include the embedded CSS code. With the latter, you can specify the URL of the custom CSS file (for example: "http://example.com/my.css"). The default value is false.
    {dirname, room_jid|room_name}
    Allows to configure the name of the room directory. Allowed values are room_jid and room_name. With the first value, the room directory name will be the full room JID. With the latter, the room directory name will be only the room name, not including the MUC service name. The default value is room_jid.
    {dirtype, subdirs|plain}
    The type of the created directories can be specified with this option. Allowed values are subdirs and plain. With the first value, subdirectories are created for each year and month. With the latter, the names of the log files contain the full date, and there are no subdirectories. The default value is subdirs.
    {file_format, html|plaintext}
    Define the format of the log files: html stores in HTML format, plaintext stores in plain text. The default value is html.
    {outdir, Path}
    This option sets the full path to the directory in which the HTML files should be stored. Make sure the ejabberd daemon user has write access on that directory. The default value is "www/muc".
    {spam_prevention true|false}
    To prevent spam, the spam_prevention option adds a special attribute to links that prevent their indexation by search engines. The default value is true, which mean that nofollow attributes will be added to user submitted links.
    {timezone, local|universal}
    The time zone for the logs is configurable with this option. Allowed values are local and universal. With the first value, the local time, as reported to Erlang by the operating system, will be used. With the latter, GMT/UTC time will be used. The default value is local.
    {top_link, {URL, Text}}
    With this option you can customize the link on the top right corner of each log file. The default value is {"/", "Home"}.

    Examples:

    • In the first example any room owner can enable logging, and a custom CSS file will be used (http://example.com/my.css). The names of the log files will contain the full date, and there will be no subdirectories. The log files will be stored in /var/www/muclogs, and the time zone will be GMT/UTC. Finally, the top link will be <a href="http://www.jabber.ru/">Jabber.ru</a>.
      {access, muc, [{allow, all}]}.
      
      {modules,
       [
        ...
        {mod_muc_log, [
                       {access_log, muc},
                       {cssfile, "http://example.com/my.css"},
                       {dirtype, plain},
                       {dirname, room_jid},
                       {outdir, "/var/www/muclogs"},
                       {timezone, universal},
                       {spam_prevention, true},
                       {top_link, {"http://www.jabber.ru/", "Jabber.ru"}}
                      ]},
        ...
       ]}.
      
    • In the second example only admin1@example.org and admin2@example.net can enable logging, and the embedded CSS file will be used. The names of the log files will only contain the day (number), and there will be subdirectories for each year and month. The log files will be stored in /var/www/muclogs, and the local time will be used. Finally, the top link will be the default <a href="/">Home</a>.
      {acl, admin, {user, "admin1", "example.org"}}.
      {acl, admin, {user, "admin2", "example.net"}}.
      
      {access, muc_log, [{allow, admin},
                         {deny, all}]}.
      
      {modules,
       [
        ...
        {mod_muc_log, [
                       {access_log, muc_log},
                       {cssfile, false},
                       {dirtype, subdirs},
                       {outdir, "/var/www/muclogs"},
                       {timezone, local}
                      ]},
        ...
       ]}.
      

    3.3.12  mod_offline

    This module implements offline message storage (XEP-0160). This means that all messages sent to an offline user will be stored on the server until that user comes online again. Thus it is very similar to how email works. Note that ejabberdctl has a command to delete expired messages (see section 4.1).

    {access_max_user_messages, AccessName}
    This option defines which access rule will be enforced to limit the maximum number of offline messages that a user can have (quota). When a user has too many offline messages, any new messages that he receive are discarded, and a resource-constraint error is returned to the sender. The default value is max_user_offline_messages. Then you can define an access rule with a syntax similar to max_user_sessions (see 3.1.5).

    This example allows power users to have as much as 5000 offline messages, administrators up to 2000, and all the other users up to 100.

    {acl, admin, {user, "admin1", "localhost"}}.
    {acl, admin, {user, "admin2", "example.org"}}.
    {acl, poweruser, {user, "bob", "example.org"}}.
    {acl, poweruser, {user, "jane", "example.org"}}.
    
    {access, max_user_offline_messages, [ {5000, poweruser}, {2000, admin}, {100, all} ]}.
    
    {modules,
     [
      ...
      {mod_offline,  [ {access_max_user_messages, max_user_offline_messages} ]},
      ...
     ]}.
    

    3.3.13  mod_ping

    This module implements support for XMPP Ping (XEP-0199) and periodic keepalives. When this module is enabled ejabberd responds correctly to ping requests, as defined in the protocol.

    Configuration options:

    {send_pings, true|false}
    If this option is set to true, the server sends pings to connected clients that are not active in a given interval ping_interval. This is useful to keep client connections alive or checking availability. By default this option is disabled.
    {ping_interval, Seconds}
    How often to send pings to connected clients, if the previous option is enabled. If a client connection does not send or receive any stanza in this interval, a ping request is sent to the client. The default value is 60 seconds.
    {timeout_action, none|kill}
    What to do when a client does not answer to a server ping request in less than 32 seconds. The default is to do nothing.

    This example enables Ping responses, configures the module to send pings to client connections that are inactive for 4 minutes, and if a client does not answer to the ping in less than 32 seconds, its connection is closed:

    {modules,
     [
      ...
      {mod_ping,  [{send_pings, true}, {ping_interval, 240}, {timeout_action, kill}]},
      ...
     ]}.
    

    3.3.14  mod_pres_counter

    This module detects flood/spam in presence subscription stanza traffic. If a user sends or receives more of those stanzas in a time interval, the exceeding stanzas are silently dropped, and warning is logged.

    Configuration options:

    {count, StanzaNumber}
    The number of subscription presence stanzas (subscribe, unsubscribe, subscribed, unsubscribed) allowed for any direction (input or output) per time interval. Please note that two users subscribing to each other usually generate 4 stanzas, so the recommended value is 4 or more. The default value is: 5.
    {interval, Seconds}
    The time interval defined in seconds. The default value is 60.

    This example enables the module, and allows up to 5 presence subscription stanzas to be sent or received by the users in 60 seconds:

    {modules,
     [
      ...
      {mod_pres_counter,  [{count, 5}, {interval, 60}]},
      ...
     ]}.
    

    3.3.15  mod_privacy

    This module implements Blocking Communication (also known as Privacy Rules) as defined in section 10 from XMPP IM. If end users have support for it in their XMPP client, they will be able to:

    • Retrieving one’s privacy lists.
    • Adding, removing, and editing one’s privacy lists.
    • Setting, changing, or declining active lists.
    • Setting, changing, or declining the default list (i.e., the list that is active by default).
    • Allowing or blocking messages based on JID, group, or subscription type (or globally).
    • Allowing or blocking inbound presence notifications based on JID, group, or subscription type (or globally).
    • Allowing or blocking outbound presence notifications based on JID, group, or subscription type (or globally).
    • Allowing or blocking IQ stanzas based on JID, group, or subscription type (or globally).
    • Allowing or blocking all communications based on JID, group, or subscription type (or globally).
    (from http://xmpp.org/rfcs/rfc3921.html#privacy)

    Options:

    {iqdisc, Discipline}
    This specifies the processing discipline for Blocking Communication (jabber:iq:privacy) IQ queries (see section 3.3.2).

    3.3.16  mod_private

    This module adds support for Private XML Storage (XEP-0049):

    Using this method, XMPP entities can store private data on the server and retrieve it whenever necessary. The data stored might be anything, as long as it is valid XML. One typical usage for this namespace is the server-side storage of client-specific preferences; another is Bookmark Storage (XEP-0048).

    Options:

    {iqdisc, Discipline}
    This specifies the processing discipline for Private XML Storage (jabber:iq:private) IQ queries (see section 3.3.2).

    3.3.17  mod_proxy65

    This module implements SOCKS5 Bytestreams (XEP-0065). It allows ejabberd to act as a file transfer proxy between two XMPP clients.

    Options:

    {host, HostName}
    This option defines the Jabber ID of the service. If the host option is not specified, the Jabber ID will be the hostname of the virtual host with the prefix ‘proxy.’. The keyword "@HOST@" is replaced at start time with the real virtual host name.
    {name, Text}
    Defines Service Discovery name of the service. Default is "SOCKS5 Bytestreams".
    {ip, IPTuple}
    This option specifies which network interface to listen for. Default is an IP address of the service’s DNS name, or, if fails, {127,0,0,1}.
    {port, Number}
    This option defines port to listen for incoming connections. Default is 7777.
    {hostname, HostName}
    Defines a hostname advertised by the service when establishing a session with clients. This is useful when you run the service behind a NAT. The default is the value of ip option. Examples: "proxy.mydomain.org", "200.150.100.50". Note that not all clients understand domain names in stream negotiation, so you should think twice before setting domain name in this option.
    {auth_type, anonymous|plain}
    SOCKS5 authentication type. Possible values are anonymous and plain. Default is anonymous.
    {access, AccessName}
    Defines ACL for file transfer initiators. Default is all.
    {max_connections, Number}
    Maximum number of active connections per file transfer initiator. No limit by default.
    {shaper, none|ShaperName}
    This option defines shaper for the file transfer peers. Shaper with the maximum bandwidth will be selected. Default is none.

    Examples:

    • The simpliest configuration of the module:
      {modules,
       [
        ...
        {mod_proxy65, []},
        ...
       ]}.
      
    • More complicated configuration.
      {acl, proxy_users, {server, "example.org"}}.
      {access, proxy65_access, [{allow, proxy_users}, {deny, all}]}.
      
      {acl, admin, {user, "admin", "example.org"}}.
      {shaper, proxyrate, {maxrate, 10240}}. %% 10 Kbytes/sec
      {access, proxy65_shaper, [{none, admin}, {proxyrate, proxy_users}]}.
      
      {modules,
       [
        ...
        {mod_proxy65, [{host, "proxy1.example.org"},
                       {name, "File Transfer Proxy"},
                       {ip, {200,150,100,1}},
                       {port, 7778},
                       {max_connections, 5},
                       {access, proxy65_access},
                       {shaper, proxy65_shaper}]},
        ...
       ]}.
      

    3.3.18  mod_pubsub

    This module offers a Publish-Subscribe Service (XEP-0060). The functionality in mod_pubsub can be extended using plugins. The plugin that implements PEP (Personal Eventing via Pubsub) (XEP-0163) is enabled in the default ejabberd configuration file, and it requires mod_caps.

    Options:

    {host, HostName}
    This option defines the Jabber ID of the service. If the host option is not specified, the Jabber ID will be the hostname of the virtual host with the prefix ‘pubsub.’. The keyword "@HOST@" is replaced at start time with the real virtual host name. If you use mod_pubsub_odbc, please ensure the prefix contains only one dot, for example ‘pubsub.’, or ‘publish.’,.
    {access_createnode, AccessName}
    This option restricts which users are allowed to create pubsub nodes using ACL and ACCESS. By default any account in the local ejabberd server is allowed to create pubsub nodes.
    {max_items_node, MaxItems}
    Define the maximum number of items that can be stored in a node. Default value is 10.
    {plugins, [ Plugin, ...]}
    To specify which pubsub node plugins to use. The first one in the list is used by default. If this option is not defined, the default plugins list is: ["flat"]. PubSub clients can define which plugin to use when creating a node: add type=’plugin-name’ attribute to the create stanza element.
    {nodetree, Nodetree}
    To specify which nodetree to use. If not defined, the default pubsub nodetree is used: "tree". Only one nodetree can be used per host, and is shared by all node plugins.

    The "virtual" nodetree does not store nodes on database. This saves resources on systems with tons of nodes. If using the "virtual" nodetree, you can only enable those node plugins: ["flat","pep"] or ["flat"]; any other plugins configuration will not work. Also, all nodes will have the defaut configuration, and this can not be changed. Using "virtual" nodetree requires to start from a clean database, it will not work if you used the default "tree" nodetree before.

    The "dag" nodetree provides experimental support for PubSub Collection Nodes (XEP-0248). In that case you should also add "dag" node plugin as default, for example: {plugins, ["dag","flat","hometree","pep"]}

    {ignore_pep_from_offline, false|true}
    To specify whether or not we should get last published PEP items from users in our roster which are offline when we connect. Value is true or false. If not defined, pubsub assumes true so we only get last items of online contacts.
    {last_item_cache, false|true}
    To specify whether or not pubsub should cache last items. Value is true or false. If not defined, pubsub do not cache last items. On systems with not so many nodes, caching last items speeds up pubsub and allows to raise user connection rate. The cost is memory usage, as every item is stored in memory.
    {pep_mapping, [ {Key, Value}, ...]}
    This allow to define a Key-Value list to choose defined node plugins on given PEP namespace. The following example will use node_tune instead of node_pep for every PEP node with tune namespace:
      {mod_pubsub, [{pep_mapping, [{"http://jabber.org/protocol/tune", "tune"}]}]}
    

    Example of configuration that uses flat nodes as default, and allows use of flat, nodetree and pep nodes:

    {modules,
     [
      ...
      {mod_pubsub, [
                    {access_createnode, pubsub_createnode},
                    {plugins, ["flat", "hometree", "pep"]}
                   ]},
      ...
     ]}.
    

    Using ODBC database requires use of dedicated plugins. The following example shows previous configuration with ODBC usage:

    {modules,
     [
      ...
      {mod_pubsub_odbc, [
                    {access_createnode, pubsub_createnode},
                    {plugins, ["flat_odbc", "hometree_odbc", "pep_odbc"]}
                   ]},
      ...
     ]}.
    

    3.3.19  mod_register

    This module adds support for In-Band Registration (XEP-0077). This protocol enables end users to use a XMPP client to:

    • Register a new account on the server.
    • Change the password from an existing account on the server.
    • Delete an existing account on the server.

    Options:

    {access, AccessName}
    Specify rules to restrict what usernames can be registered and unregistered. If a rule returns ‘deny’ on the requested username, registration and unregistration of that user name is denied. There are no restrictions by default.
    {access_from, AccessName}
    By default, ejabberd doesn’t allow to register new accounts from s2s or existing c2s sessions. You can change it by defining access rule in this option. Use with care: allowing registration from s2s leads to uncontrolled massive accounts creation by rogue users.
    {captcha_protected, false|true}
    Protect registrations with CAPTCHA (see section 3.1.8). The default is false.
    {ip_access, [ {allow|deny, IPaddress}, ...]}
    Define rules to allow or deny account registration depending in the IP address of the XMPP client. If there is no matching IP mask, the default rule is “allow”. IPv6 addresses are supported, but not tested. The default option value is an empty list: [].
    {password_strength, Entropy}
    This option sets the minimum informational entropy for passwords. The value Entropy is a number of bits of entropy. The recommended minimum is 32 bits. The default is 0, i.e. no checks are performed.
    {welcome_message, {Subject, Body}}
    Set a welcome message that is sent to each newly registered account. The first string is the subject, and the second string is the message body. In the body you can set a newline with the characters: \n
    {registration_watchers, [ JID, ...]}
    This option defines a list of JIDs which will be notified each time a new account is registered.
    {iqdisc, Discipline}
    This specifies the processing discipline for In-Band Registration (jabber:iq:register) IQ queries (see section 3.3.2).

    This module reads also another option defined globally for the server: {registration_timeout, Timeout}. This option limits the frequency of registration from a given IP or username. So, a user that tries to register a new account from the same IP address or JID during this number of seconds after his previous registration will receive an error resource-constraint with the explanation: “Users are not allowed to register accounts so quickly”. The timeout is expressed in seconds, and it must be an integer. To disable this limitation, instead of an integer put a word like: infinity. Default value: 600 seconds.

    Examples:

    • Next example prohibits the registration of too short account names, and allows to create accounts only to clients of the local network:
      {acl, shortname, {user_glob, "?"}}.
      {acl, shortname, {user_glob, "??"}}.
      %% The same using regexp:
      %%{acl, shortname, {user_regexp, "^..?$"}}.
      
      {access, register, [{deny, shortname},
                          {allow, all}]}.
      
      {modules,
       [
        ...
        {mod_register, [{access, register},
                        {ip_access, [{allow, "127.0.0.0/8"},
                                     {deny, "0.0.0.0/0"}]}
        ]},
        ...
       ]}.
      
    • This configuration prohibits usage of In-Band Registration to create or delete accounts, but allows existing accounts to change the password:
      {access, register, [{deny, all}]}.
      
      {modules,
       [
        ...
        {mod_register, [{access, register}]},
        ...
       ]}.
      
    • This configuration disables all In-Band Registration functionality: create, delete accounts and change password:
      {modules,
       [
        ...
        %% {mod_register, [{access, register}]},
        ...
       ]}.
      
    • Define the welcome message and two registration watchers. Also define a registration timeout of one hour:
      {registration_timeout, 3600}.
      {modules,
       [
        ...
        {mod_register,
         [
          {welcome_message, {"Welcome!", "Hi.\nWelcome to this Jabber server.\n Check http://www.jabber.org\n\nBye"}},
          {registration_watchers, ["admin1@example.org", "boss@example.net"]}
         ]},
        ...
       ]}.
      

    3.3.20  mod_register_web

    This module provides a web page where people can:

    • Register a new account on the server.
    • Change the password from an existing account on the server.
    • Delete an existing account on the server.

    This module supports CAPTCHA image to register a new account. To enable this feature, configure the options captcha_cmd and captcha_host.

    Options:

    {registration_watchers, [ JID, ...]}
    This option defines a list of JIDs which will be notified each time a new account is registered.

    This example configuration shows how to enable the module and the web handler:

    {hosts, ["localhost", "example.org", "example.com"]}.
    
    {listen, [
      ...
      {5281, ejabberd_http, [
        tls,
        {certfile, "/etc/ejabberd/certificate.pem"},
        register
      ]},
      ...
    ]}.
    
    {modules,
     [
      ...
      {mod_register_web, []},
      ...
     ]}.
    

    For example, the users of the host example.org can visit the page: https://example.org:5281/register/ It is important to include the last / character in the URL, otherwise the subpages URL will be incorrect.

    3.3.21  mod_roster

    This module implements roster management as defined in RFC 3921: XMPP IM. It also supports Roster Versioning (XEP-0237).

    Options:

    {iqdisc, Discipline}
    This specifies the processing discipline for Roster Management (jabber:iq:roster) IQ queries (see section 3.3.2).
    {versioning, false|true}
    Enables Roster Versioning. This option is disabled by default.
    {store_current_id, false|true}
    If this option is enabled, the current version number is stored on the database. If disabled, the version number is calculated on the fly each time. Enabling this option reduces the load for both ejabberd and the database. This option does not affect the client in any way. This option is only useful if Roster Versioning is enabled. This option is disabled by default. Important: if you use mod_shared_roster, mod_shared_roster_odbc or mod_shared_roster_ldap, you must disable this option.

    This example configuration enables Roster Versioning with storage of current id:

    {modules,
     [
      ...
      {mod_roster, [{versioning, true}, {store_current_id, true}]},
      ...
     ]}.
    

    3.3.22  mod_service_log

    This module adds support for logging end user packets via a XMPP message auditing service such as Bandersnatch. All user packets are encapsulated in a <route/> element and sent to the specified service(s).

    Options:

    {loggers, [Names, ...]}
    With this option a (list of) service(s) that will receive the packets can be specified.

    Examples:

    • To log all end user packets to the Bandersnatch service running on bandersnatch.example.com:
      {modules,
       [
        ...
        {mod_service_log, [{loggers, ["bandersnatch.example.com"]}]},
        ...
       ]}.
      
    • To log all end user packets to the Bandersnatch service running on bandersnatch.example.com and the backup service on bandersnatch.example.org:
      {modules,
       [
        ...
        {mod_service_log, [{loggers, ["bandersnatch.example.com",
                                      "bandersnatch.example.org"]}]},
        ...
       ]}.
      

    3.3.23  mod_shared_roster

    This module enables you to create shared roster groups. This means that you can create groups of people that can see members from (other) groups in their rosters. The big advantages of this feature are that end users do not need to manually add all users to their rosters, and that they cannot permanently delete users from the shared roster groups. A shared roster group can have members from any XMPP server, but the presence will only be available from and to members of the same virtual host where the group is created.

    Shared roster groups can be edited only via the Web Admin. Each group has a unique identification and the following parameters:

    Name
    The name of the group, which will be displayed in the roster.
    Description
    The description of the group. This parameter does not affect anything.
    Members
    A list of JIDs of group members, entered one per line in the Web Admin. The special member directive @all@ represents all the registered users in the virtual host; which is only recommended for a small server with just a few hundred users. The special member directive @online@ represents the online users in the virtual host.
    Displayed groups
    A list of groups that will be in the rosters of this group’s members. A group of other vhost can be identified with groupid@vhost

    Examples:

    • Take the case of a computer club that wants all its members seeing each other in their rosters. To achieve this, they need to create a shared roster group similar to next table:

      IdentificationGroup ‘club_members
      NameClub Members
      DescriptionMembers from the computer club
      Members
      member1@example.org
      member2@example.org
      member3@example.org
      Displayed groupsclub_members

    • In another case we have a company which has three divisions: Management, Marketing and Sales. All group members should see all other members in their rosters. Additionally, all managers should have all marketing and sales people in their roster. Simultaneously, all marketeers and the whole sales team should see all managers. This scenario can be achieved by creating shared roster groups as shown in the following table:

      Identification Group ‘management Group ‘marketing Group ‘sales
      NameManagementMarketingSales
      Description 
      Members
      manager1@example.org
      manager2@example.org
      manager3@example.org
      manager4@example.org
      marketeer1@example.org
      marketeer2@example.org
      marketeer3@example.org
      marketeer4@example.org
      saleswoman1@example.org
      salesman1@example.org
      saleswoman2@example.org
      salesman2@example.org
      Displayed groups
      management
      marketing
      sales
      management
      marketing
      management
      sales

    3.3.24  mod_shared_roster_ldap

    This module lets the server administrator automatically populate users’ rosters (contact lists) with entries based on users and groups defined in an LDAP-based directory.

    Configuration parameters

    The module accepts the following configuration parameters. Some of them, if unspecified, default to the values specified for the top level of configuration. This lets you avoid specifying, for example, the bind password, in multiple places.

    Filters

    These parameters specify LDAP filters used to query for shared roster information. All of them are run against the ldap_base.

    ldap_rfilter
    So called “Roster Filter”. Used to find names of all “shared roster” groups. See also the ldap_groupattr parameter. If unspecified, defaults to the top-level parameter of the same name. You must specify it in some place in the configuration, there is no default.
    ldap_ufilter
    “User Filter” – used for retrieving the human-readable name of roster entries (usually full names of people in the roster). See also the parameters ldap_userdesc and ldap_useruid. If unspecified, defaults to the top-level parameter of the same name. If that one also is unspecified, then the filter is assembled from values of other parameters as follows ([ldap_SOMETHING] is used to mean “the value of the configuration parameter ldap_SOMETHING”):
    (&(&([ldap_memberattr]=[ldap_memberattr_format])([ldap_groupattr]=%g))[ldap_filter])
    

    Subsequently %u and %g are replaced with a *. This means that given the defaults, the filter sent to the LDAP server is would be (&(memberUid=*)(cn=*)). If however the ldap_memberattr_format is something like uid=%u,ou=People,o=org, then the filter will be (&(memberUid=uid=*,ou=People,o=org)(cn=*)).

    ldap_gfilter
    “Group Filter” – used when retrieving human-readable name (a.k.a. “Display Name”) and the members of a group. See also the parameters ldap_groupattr, ldap_groupdesc and ldap_memberattr. If unspecified, defaults to the top-level parameter of the same name. If that one also is unspecified, then the filter is constructed exactly in the same way as User Filter.
    ldap_filter
    Additional filter which is AND-ed together with User Filter and Group Filter. If unspecified, defaults to the top-level parameter of the same name. If that one is also unspecified, then no additional filter is merged with the other filters.

    Note that you will probably need to manually define the User and Group Filters (since the auto-assembled ones will not work) if:

    • your ldap_memberattr_format is anything other than a simple %u,
    • and the attribute specified with ldap_memberattr does not support substring matches.

    An example where it is the case is OpenLDAP and (unique)MemberName attribute from the groupOf(Unique)Names objectClass. A symptom of this problem is that you will see messages such as the following in your slapd.log:

    get_filter: unknown filter type=130
    filter="(&(?=undefined)(?=undefined)(something=else))"
    

    Attributes

    These parameters specify the names of the attributes which hold interesting data in the entries returned by running filters specified in section 3.3.24.

    ldap_groupattr
    The name of the attribute that holds the group name, and that is used to differentiate between them. Retrieved from results of the “Roster Filter” and “Group Filter”. Defaults to cn.
    ldap_groupdesc
    The name of the attribute which holds the human-readable group name in the objects you use to represent groups. Retrieved from results of the “Group Filter”. Defaults to whatever ldap_groupattr is set.
    ldap_memberattr
    The name of the attribute which holds the IDs of the members of a group. Retrieved from results of the “Group Filter”. Defaults to memberUid.

    The name of the attribute differs depending on the objectClass you use for your group objects, for example:

    posixGroupmemberUid
    groupOfNamesmember
    groupOfUniqueNamesuniqueMember
    ldap_userdesc
    The name of the attribute which holds the human-readable user name. Retrieved from results of the “User Filter”. Defaults to cn.
    ldap_useruid
    The name of the attribute which holds the ID of a roster item. Value of this attribute in the roster item objects needs to match the ID retrieved from the ldap_memberattr attribute of a group object. Retrieved from results of the “User Filter”. Defaults to cn.

    Control parameters

    These paramters control the behaviour of the module.

    ldap_memberattr_format
    A globbing format for extracting user ID from the value of the attribute named by ldap_memberattr. Defaults to %u, which means that the whole value is the member ID. If you change it to something different, you may also need to specify the User and Group Filters manually — see section 3.3.24.
    ldap_memberattr_format_re
    A regex for extracting user ID from the value of the attribute named by ldap_memberattr.

    An example value "CN=(\\w*),(OU=.*,)*DC=company,DC=com" works for user IDs such as the following:

    • CN=Romeo,OU=Montague,DC=company,DC=com
    • CN=Abram,OU=Servants,OU=Montague,DC=company,DC=com
    • CN=Juliet,OU=Capulet,DC=company,DC=com
    • CN=Peter,OU=Servants,OU=Capulet,DC=company,DC=com

    In case:

    • the option is unset,
    • or the re module in unavailable in the current Erlang environment,
    • or the regular expression does not compile,

    then instead of a regular expression, a simple format specified by ldap_memberattr_format is used. Also, in the last two cases an error message is logged during the module initialization.

    Also, note that in all cases ldap_memberattr_format (and not the regex version) is used for constructing the default “User/Group Filter” — see section 3.3.24.

    ldap_auth_check
    Whether the module should check (via the ejabberd authentication subsystem) for existence of each user in the shared LDAP roster. See section 3.3.24 form more information. Set to off if you want to disable the check. Defaults to on.
    ldap_user_cache_validity
    Number of seconds for which the cache for roster item full names is considered fresh after retrieval. 300 by default. See section 3.3.24 on how it is used during roster retrieval.
    ldap_group_cache_validity
    Number of seconds for which the cache for group membership is considered fresh after retrieval. 300 by default. See section 3.3.24 on how it is used during roster retrieval.

    Connection parameters

    The module also accepts the connection parameters, all of which default to the top-level parameter of the same name, if unspecified. See 3.2.5 for more information about them.

    Retrieving the roster

    When the module is called to retrieve the shared roster for a user, the following algorithm is used:

    1. A list of names of groups to display is created: the Roster Filter is run against the base DN, retrieving the values of the attribute named by ldap_groupattr.
    2. Unless the group cache is fresh (see the ldap_group_cache_validity option), it is refreshed:
      1. Information for all groups is retrieved using a single query: the Group Filter is run against the Base DN, retrieving the values of attributes named by ldap_groupattr (group ID), ldap_groupdesc (group “Display Name”) and ldap_memberattr (IDs of group members).
      2. group “Display Name”, read from the attribute named by ldap_groupdesc, is stored in the cache for the given group
      3. the following processing takes place for each retrieved value of attribute named by ldap_memberattr:
        1. the user ID part of it is extracted using ldap_memberattr_format(_re),
        2. then (unless ldap_auth_check is set to off) for each found user ID, the module checks (using the ejabberd authentication subsystem) whether such user exists in the given virtual host. It is skipped if the check is enabled and fails.

          This step is here for historical reasons. If you have a tidy DIT and properly defined “Roster Filter” and “Group Filter”, it is safe to disable it by setting ldap_auth_check to off — it will speed up the roster retrieval.

        3. the user ID is stored in the list of members in the cache for the given group
    3. For each item (group name) in the list of groups retrieved in step 1:
      1. the display name of a shared roster group is retrieved from the group cache
      2. for each IDs of users which belong to the group, retrieved from the group cache:
        1. the ID is skipped if it’s the same as the one for which we are retrieving the roster. This is so that the user does not have himself in the roster.
        2. the display name of a shared roster user is retrieved:
          1. first, unless the user name cache is fresh (see the ldap_user_cache_validity option), it is refreshed by running the User Filter, against the Base DN, retrieving the values of attributes named by ldap_useruid and ldap_userdesc.
          2. then, the display name for the given user ID is retrieved from the user name cache.

    Configuration examples

    Since there are many possible DIT layouts, it will probably be easiest to understand how to configure the module by looking at an example for a given DIT (or one resembling it).

    Flat DIT

    This seems to be the kind of DIT for which this module was initially designed. Basically there are just user objects, and group membership is stored in an attribute individually for each user. For example in a layout shown in figure 3.1, the group of each user is stored in its ou attribute.


    msrl-dit-flat.png
    Figure 3.1: Flat DIT graph

    Such layout has a few downsides, including:

    • information duplication – the group name is repeated in every member object
    • difficult group management – information about group members is not centralized, but distributed between member objects
    • inefficiency – the list of unique group names has to be computed by iterating over all users

    This however seems to be a common DIT layout, so the module keeps supporting it. You can use the following configuration…

      {mod_shared_roster_ldap,[
        {ldap_base, "ou=flat,dc=nodomain"},
        {ldap_rfilter, "(objectClass=inetOrgPerson)"},
        {ldap_groupattr, "ou"},
        {ldap_memberattr, "cn"},
        {ldap_filter,  "(objectClass=inetOrgPerson)"},
        {ldap_userdesc, "displayName"}
      ]},
    

    …to be provided with a roster as shown in figure 3.2 upon connecting as user czesio.


    msrl-roster-flat.png
    Figure 3.2: Roster from flat DIT

    Deep DIT

    This type of DIT contains distinctly typed objects for users and groups – see figure 3.3. They are shown separated into different subtrees, but it’s not a requirement.


    msrl-dit-deep.png
    Figure 3.3: Example “deep” DIT graph

    If you use the following example module configuration with it:

      {mod_shared_roster_ldap,[
        {ldap_base, "ou=deep,dc=nodomain"},
        {ldap_rfilter, "(objectClass=groupOfUniqueNames)"},
        {ldap_filter, ""},
        {ldap_gfilter, "(&(objectClass=groupOfUniqueNames)(cn=%g))"},
        {ldap_groupdesc, "description"},
        {ldap_memberattr, "uniqueMember"},
        {ldap_memberattr_format, "cn=%u,ou=people,ou=deep,dc=nodomain"},
        {ldap_ufilter, "(&(objectClass=inetOrgPerson)(cn=%u))"},
        {ldap_userdesc, "displayName"}
      ]},
    

    …and connect as user czesio, then ejabberd will provide you with the roster shown in figure 3.4.


    msrl-roster-deep.png
    Figure 3.4: Example roster from “deep” DIT

    3.3.25  mod_sic

    This module adds support for Server IP Check (XEP-0279). This protocol enables a client to discover its external IP address.

    Options:

    {iqdisc, Discipline}
    This specifies the processing discipline for urn:xmpp:sic:0 IQ queries (see section 3.3.2).

    3.3.26  mod_stats

    This module adds support for Statistics Gathering (XEP-0039). This protocol allows you to retrieve next statistics from your ejabberd deployment:

    • Total number of registered users on the current virtual host (users/total).
    • Total number of registered users on all virtual hosts (users/all-hosts/total).
    • Total number of online users on the current virtual host (users/online).
    • Total number of online users on all virtual hosts (users/all-hosts/online).

    Options:

    {iqdisc, Discipline}
    This specifies the processing discipline for Statistics Gathering (http://jabber.org/protocol/stats) IQ queries (see section 3.3.2).

    As there are only a small amount of clients (for example Tkabber) and software libraries with support for this XEP, a few examples are given of the XML you need to send in order to get the statistics. Here they are:

    • You can request the number of online users on the current virtual host (example.org) by sending:
      <iq to='example.org' type='get'>
        <query xmlns='http://jabber.org/protocol/stats'>
          <stat name='users/online'/>
        </query>
      </iq>
      
    • You can request the total number of registered users on all virtual hosts by sending:
      <iq to='example.org' type='get'>
        <query xmlns='http://jabber.org/protocol/stats'>
          <stat name='users/all-hosts/total'/>
        </query>
      </iq>
      

    3.3.27  mod_time

    This module features support for Entity Time (XEP-0202). By using this XEP, you are able to discover the time at another entity’s location.

    Options:

    {iqdisc, Discipline}
    This specifies the processing discipline for Entity Time (jabber:iq:time) IQ queries (see section 3.3.2).

    3.3.28  mod_vcard

    This module allows end users to store and retrieve their vCard, and to retrieve other users vCards, as defined in vcard-temp (XEP-0054). The module also implements an uncomplicated Jabber User Directory based on the vCards of these users. Moreover, it enables the server to send its vCard when queried.

    Options:

    {host, HostName}
    This option defines the Jabber ID of the service. If the host option is not specified, the Jabber ID will be the hostname of the virtual host with the prefix ‘vjud.’. The keyword "@HOST@" is replaced at start time with the real virtual host name.
    {iqdisc, Discipline}
    This specifies the processing discipline for vcard-temp IQ queries (see section 3.3.2).
    {search, true|false}
    This option specifies whether the search functionality is enabled or not If disabled, the option host will be ignored and the Jabber User Directory service will not appear in the Service Discovery item list. The default value is true.
    {matches, infinity|Number}
    With this option, the number of reported search results can be limited. If the option’s value is set to infinity, all search results are reported. The default value is 30.
    {allow_return_all, false|true}
    This option enables you to specify if search operations with empty input fields should return all users who added some information to their vCard. The default value is false.
    {search_all_hosts, true|false}
    If this option is set to true, search operations will apply to all virtual hosts. Otherwise only the current host will be searched. The default value is true. This option is available in mod_vcard, but not available in mod_vcard_odbc.

    Examples:

    • In this first situation, search results are limited to twenty items, every user who added information to their vCard will be listed when people do an empty search, and only users from the current host will be returned:
      {modules,
       [
        ...
        {mod_vcard, [{search, true},
                     {matches, 20},
                     {allow_return_all, true},
                     {search_all_hosts, false}]},
        ...
       ]}.
      
    • The second situation differs in a way that search results are not limited, and that all virtual hosts will be searched instead of only the current one:
      {modules,
       [
        ...
        {mod_vcard, [{search, true},
                     {matches, infinity},
                     {allow_return_all, true}]},
        ...
       ]}.
      

    3.3.29  mod_vcard_ldap

    ejabberd can map LDAP attributes to vCard fields. This behaviour is implemented in the mod_vcard_ldap module. This module does not depend on the authentication method (see 3.2.5).

    Usually ejabberd treats LDAP as a read-only storage: it is possible to consult data, but not possible to create accounts or edit vCard that is stored in LDAP. However, it is possible to change passwords if mod_register module is enabled and LDAP server supports RFC 3062.

    The mod_vcard_ldap module has its own optional parameters. The first group of parameters has the same meaning as the top-level LDAP parameters to set the authentication method: ldap_servers, ldap_port, ldap_rootdn, ldap_password, ldap_base, ldap_uids, ldap_deref_aliases and ldap_filter. See section 3.2.5 for detailed information about these options. If one of these options is not set, ejabberd will look for the top-level option with the same name.

    The second group of parameters consists of the following mod_vcard_ldap-specific options:

    {host, HostName}
    This option defines the Jabber ID of the service. If the host option is not specified, the Jabber ID will be the hostname of the virtual host with the prefix ‘vjud.’. The keyword "@HOST@" is replaced at start time with the real virtual host name.
    {iqdisc, Discipline}
    This specifies the processing discipline for vcard-temp IQ queries (see section 3.3.2).
    {search, true|false}
    This option specifies whether the search functionality is enabled (value: true) or disabled (value: false). If disabled, the option host will be ignored and the Jabber User Directory service will not appear in the Service Discovery item list. The default value is true.
    {matches, infinity|Number}
    With this option, the number of reported search results can be limited. If the option’s value is set to infinity, all search results are reported. The default value is 30.
    {ldap_vcard_map, [ {Name, Pattern, LDAPattributes}, ...]}
    With this option you can set the table that maps LDAP attributes to vCard fields. Name is the type name of the vCard as defined in RFC 2426. Pattern is a string which contains pattern variables "%u", "%d" or "%s". LDAPattributes is the list containing LDAP attributes. The pattern variables "%s" will be sequentially replaced with the values of LDAP attributes from List_of_LDAP_attributes, "%u" will be replaced with the user part of a JID, and "%d" will be replaced with the domain part of a JID. The default is:
    [{"NICKNAME", "%u", []},
     {"FN", "%s", ["displayName"]},
     {"LAST", "%s", ["sn"]},
     {"FIRST", "%s", ["givenName"]},
     {"MIDDLE", "%s", ["initials"]},
     {"ORGNAME", "%s", ["o"]},
     {"ORGUNIT", "%s", ["ou"]},
     {"CTRY", "%s", ["c"]},
     {"LOCALITY", "%s", ["l"]},
     {"STREET", "%s", ["street"]},
     {"REGION", "%s", ["st"]},
     {"PCODE", "%s", ["postalCode"]},
     {"TITLE", "%s", ["title"]},
     {"URL", "%s", ["labeleduri"]},
     {"DESC", "%s", ["description"]},
     {"TEL", "%s", ["telephoneNumber"]},
     {"EMAIL", "%s", ["mail"]},
     {"BDAY", "%s", ["birthDay"]},
     {"ROLE", "%s", ["employeeType"]},
     {"PHOTO", "%s", ["jpegPhoto"]}]
    
    {ldap_search_fields, [ {Name, Attribute}, ...]}
    This option defines the search form and the LDAP attributes to search within. Name is the name of a search form field which will be automatically translated by using the translation files (see msgs/*.msg for available words). Attribute is the LDAP attribute or the pattern "%u". The default is:
    [{"User", "%u"},
     {"Full Name", "displayName"},
     {"Given Name", "givenName"},
     {"Middle Name", "initials"},
     {"Family Name", "sn"},
     {"Nickname", "%u"},
     {"Birthday", "birthDay"},
     {"Country", "c"},
     {"City", "l"},
     {"Email", "mail"},
     {"Organization Name", "o"},
     {"Organization Unit", "ou"}]
    
    {ldap_search_reported, [ {SearchField, VcardField}, ...]}
    This option defines which search fields should be reported. SearchField is the name of a search form field which will be automatically translated by using the translation files (see msgs/*.msg for available words). VcardField is the vCard field name defined in the ldap_vcard_map option. The default is:
    [{"Full Name", "FN"},
     {"Given Name", "FIRST"},
     {"Middle Name", "MIDDLE"},
     {"Family Name", "LAST"},
     {"Nickname", "NICKNAME"},
     {"Birthday", "BDAY"},
     {"Country", "CTRY"},
     {"City", "LOCALITY"},
     {"Email", "EMAIL"},
     {"Organization Name", "ORGNAME"},
     {"Organization Unit", "ORGUNIT"}]
    

    Examples:

    • Let’s say ldap.example.org is the name of our LDAP server. We have users with their passwords in "ou=Users,dc=example,dc=org" directory. Also we have addressbook, which contains users emails and their additional infos in "ou=AddressBook,dc=example,dc=org" directory. Corresponding authentication section should looks like this:

      %% authentication method
      {auth_method, ldap}.
      %% DNS name of our LDAP server
      {ldap_servers, ["ldap.example.org"]}.
      %% We want to authorize users from 'shadowAccount' object class only
      {ldap_filter, "(objectClass=shadowAccount)"}.
      

      Now we want to use users LDAP-info as their vCards. We have four attributes defined in our LDAP schema: "mail" — email address, "givenName" — first name, "sn" — second name, "birthDay" — birthday. Also we want users to search each other. Let’s see how we can set it up:

      {modules,
        ...
        {mod_vcard_ldap,
         [
          %% We use the same server and port, but want to bind anonymously because
          %% our LDAP server accepts anonymous requests to
          %% "ou=AddressBook,dc=example,dc=org" subtree.
          {ldap_rootdn, ""},
          {ldap_password, ""},
          %% define the addressbook's base
          {ldap_base, "ou=AddressBook,dc=example,dc=org"},
          %% uidattr: user's part of JID is located in the "mail" attribute
          %% uidattr_format: common format for our emails
          {ldap_uids, [{"mail","%u@mail.example.org"}]},
          %% We have to define empty filter here, because entries in addressbook does not
          %% belong to shadowAccount object class
          {ldap_filter, ""},
          %% Now we want to define vCard pattern
          {ldap_vcard_map,
           [{"NICKNAME", "%u", []}, % just use user's part of JID as his nickname
            {"FIRST", "%s", ["givenName"]},
            {"LAST", "%s", ["sn"]},
            {"FN", "%s, %s", ["sn", "givenName"]}, % example: "Smith, John"
            {"EMAIL", "%s", ["mail"]},
            {"BDAY", "%s", ["birthDay"]}]},
          %% Search form
          {ldap_search_fields,
           [{"User", "%u"},
            {"Name", "givenName"},
            {"Family Name", "sn"},
            {"Email", "mail"},
            {"Birthday", "birthDay"}]},
          %% vCard fields to be reported
          %% Note that JID is always returned with search results
          {ldap_search_reported,
           [{"Full Name", "FN"},
            {"Nickname", "NICKNAME"},
            {"Birthday", "BDAY"}]}
        ]}
        ...
      }.
      

      Note that mod_vcard_ldap module checks an existence of the user before searching his info in LDAP.

    • ldap_vcard_map example:
      {ldap_vcard_map,
       [{"NICKNAME", "%u", []},
        {"FN", "%s", ["displayName"]},
        {"CTRY", "Russia", []},
        {"EMAIL", "%u@%d", []},
        {"DESC", "%s\n%s", ["title", "description"]}
       ]},
      
    • ldap_search_fields example:
      {ldap_search_fields,
       [{"User", "uid"},
        {"Full Name", "displayName"},
        {"Email", "mail"}
       ]},
      
    • ldap_search_reported example:
      {ldap_search_reported,
       [{"Full Name", "FN"},
        {"Email", "EMAIL"},
        {"Birthday", "BDAY"},
        {"Nickname", "NICKNAME"}
       ]},
      

    3.3.30  mod_vcard_xupdate

    The user’s client can store an avatar in the user vCard. The vCard-Based Avatars protocol (XEP-0153) provides a method for clients to inform the contacts what is the avatar hash value. However, simple or small clients may not implement that protocol.

    If this module is enabled, all the outgoing client presence stanzas get automatically the avatar hash on behalf of the client. So, the contacts receive the presence stanzas with the Update Data described in XEP-0153 as if the client would had inserted it itself. If the client had already included such element in the presence stanza, it is replaced with the element generated by ejabberd.

    By enabling this module, each vCard modification produces a hash recalculation, and each presence sent by a client produces hash retrieval and a presence stanza rewrite. For this reason, enabling this module will introduce a computational overhead in servers with clients that change frequently their presence.

    3.3.31  mod_version

    This module implements Software Version (XEP-0092). Consequently, it answers ejabberd’s version when queried.

    Options:

    {show_os, true|false}
    Should the operating system be revealed or not. The default value is true.
    {iqdisc, Discipline}
    This specifies the processing discipline for Software Version (jabber:iq:version) IQ queries (see section 3.3.2).

    Chapter 4  Managing an ejabberd Server

    4.1  ejabberdctl

    With the ejabberdctl command line administration script you can execute ejabberdctl commands (described in the next section, 4.1.1) and also many general ejabberd commands (described in section 4.2). This means you can start, stop and perform many other administrative tasks in a local or remote ejabberd server (by providing the argument --node NODENAME).

    The ejabberdctl script can be configured in the file ejabberdctl.cfg. This file includes detailed information about each configurable option. See section 4.1.2.

    The ejabberdctl script returns a numerical status code. Success is represented by 0, error is represented by 1, and other codes may be used for specific results. This can be used by other scripts to determine automatically if a command succeeded or failed, for example using: echo $?

    4.1.1  ejabberdctl Commands

    When ejabberdctl is executed without any parameter, it displays the available options. If there isn’t an ejabberd server running, the available parameters are:

    start
    Start ejabberd in background mode. This is the default method.
    debug
    Attach an Erlang shell to an already existing ejabberd server. This allows to execute commands interactively in the ejabberd server.
    live
    Start ejabberd in live mode: the shell keeps attached to the started server, showing log messages and allowing to execute interactive commands.

    If there is an ejabberd server running in the system, ejabberdctl shows the ejabberdctl commands described bellow and all the ejabberd commands available in that server (see 4.2.1).

    The ejabberdctl commands are:

    help
    Get help about ejabberdctl or any available command. Try ejabberdctl help help.
    status
    Check the status of the ejabberd server.
    stop
    Stop the ejabberd server.
    restart
    Restart the ejabberd server.
    mnesia
    Get information about the Mnesia database.

    The ejabberdctl script can be restricted to require authentication and execute some ejabberd commands; see 4.2.2. Add the option to the file ejabberd.cfg. In this example there is no restriction:

    {ejabberdctl_access_commands, []}.
    

    If account robot1@example.org is registered in ejabberd with password abcdef (which MD5 is E8B501798950FC58AAD83C8C14978E), and ejabberd.cfg contains this setting:

    {hosts, ["example.org"]}.
    {acl, bots, {user, "robot1", "example.org"}}.
    {access, ctlaccess, [{allow, bots}]}.
    {ejabberdctl_access_commands, [ {ctlaccess, [registered_users, register], []} ]}.
    

    then you can do this in the shell:

    $ ejabberdctl registered_users example.org
    Error: no_auth_provided
    $ ejabberdctl --auth robot1 example.org E8B501798950FC58AAD83C8C14978E registered_users example.org
    robot1
    testuser1
    testuser2
    

    4.1.2  Erlang Runtime System

    ejabberd is an Erlang/OTP application that runs inside an Erlang runtime system. This system is configured using environment variables and command line parameters. The ejabberdctl administration script uses many of those possibilities. You can configure some of them with the file ejabberdctl.cfg, which includes detailed description about them. This section describes for reference purposes all the environment variables and command line parameters.

    The environment variables:

    EJABBERD_CONFIG_PATH
    Path to the ejabberd configuration file.
    EJABBERD_MSGS_PATH
    Path to the directory with translated strings.
    EJABBERD_LOG_PATH
    Path to the ejabberd service log file.
    EJABBERD_SO_PATH
    Path to the directory with binary system libraries.
    EJABBERD_DOC_PATH
    Path to the directory with ejabberd documentation.
    EJABBERD_PID_PATH
    Path to the PID file that ejabberd can create when started.
    HOME
    Path to the directory that is considered ejabberd’s home. This path is used to read the file .erlang.cookie.
    ERL_CRASH_DUMP
    Path to the file where crash reports will be dumped.
    ERL_EPMD_ADDRESS
    IP address where epmd listens for connections (see section 5.2).
    ERL_INETRC
    Indicates which IP name resolution to use. If using -sname, specify either this option or -kernel inetrc filepath.
    ERL_MAX_PORTS
    Maximum number of simultaneously open Erlang ports.
    ERL_MAX_ETS_TABLES
    Maximum number of ETS and Mnesia tables.

    The command line parameters:

    -sname ejabberd
    The Erlang node will be identified using only the first part of the host name, i. e. other Erlang nodes outside this domain cannot contact this node. This is the preferable option in most cases.
    -name ejabberd
    The Erlang node will be fully identified. This is only useful if you plan to setup an ejabberd cluster with nodes in different networks.
    -kernel inetrc ’"/etc/ejabberd/inetrc"’
    Indicates which IP name resolution to use. If using -sname, specify either this option or ERL_INETRC.
    -kernel inet_dist_listen_min 4200 inet_dist_listen_min 4210
    Define the first and last ports that epmd (section 5.2) can listen to.
    -kernel inet_dist_use_interface "{ 127,0,0,1 }"
    Define the IP address where this Erlang node listens for other nodes connections (see section 5.2).
    -detached
    Starts the Erlang system detached from the system console. Useful for running daemons and background processes.
    -noinput
    Ensures that the Erlang system never tries to read any input. Useful for running daemons and background processes.
    -pa /var/lib/ejabberd/ebin
    Specify the directory where Erlang binary files (*.beam) are located.
    -s ejabberd
    Tell Erlang runtime system to start the ejabberd application.
    -mnesia dir ’"/var/lib/ejabberd/"’
    Specify the Mnesia database directory.
    -sasl sasl_error_logger {file, "/var/log/ejabberd/erlang.log"}
    Path to the Erlang/OTP system log file. SASL here means “System Architecture Support Libraries” not “Simple Authentication and Security Layer”.
    +K [true|false]
    Kernel polling.
    -smp [auto|enable|disable]
    SMP support.
    +P 250000
    Maximum number of Erlang processes.
    -remsh ejabberd@localhost
    Open an Erlang shell in a remote Erlang node.
    -hidden
    The connections to other nodes are hidden (not published). The result is that this node is not considered part of the cluster. This is important when starting a temporary ctl or debug node.

    Note that some characters need to be escaped when used in shell scripts, for instance " and {}. You can find other options in the Erlang manual page (erl -man erl).

    4.2  ejabberd Commands

    An ejabberd command is an abstract function identified by a name, with a defined number and type of calling arguments and type of result that is registered in the ejabberd_commands service. Those commands can be defined in any Erlang module and executed using any valid frontend.

    ejabberd includes a frontend to execute ejabberd commands: the script ejabberdctl. Other known frontends that can be installed to execute ejabberd commands in different ways are: ejabberd_xmlrpc (XML-RPC service), mod_rest (HTTP POST service), mod_shcommands (ejabberd WebAdmin page).

    4.2.1  List of ejabberd Commands

    ejabberd includes a few ejabberd Commands by default. When more modules are installed, new commands may be available in the frontends.

    The easiest way to get a list of the available commands, and get help for them is to use the ejabberdctl script:

    $ ejabberdctl help
    Usage: ejabberdctl [--node nodename] [--auth user host password] command [options]
    
    Available commands in this ejabberd node:
      backup file                  Store the database to backup file
      connected_users              List all established sessions
      connected_users_number       Get the number of established sessions
      ...
    

    The most interesting ones are:

    reopen_log
    Reopen the log files after they were renamed. If the old files were not renamed before calling this command, they are automatically renamed to "*-old.log". See section 7.1.
    backup ejabberd.backup
    Store internal Mnesia database to a binary backup file.
    restore ejabberd.backup
    Restore immediately from a binary backup file the internal Mnesia database. This will consume a lot of memory if you have a large database, so better use install_fallback.
    install_fallback ejabberd.backup
    The binary backup file is installed as fallback: it will be used to restore the database at the next ejabberd start. This means that, after running this command, you have to restart ejabberd. This command requires less memory than restore.
    dump ejabberd.dump
    Dump internal Mnesia database to a text file dump.
    load ejabberd.dump
    Restore immediately from a text file dump. This is not recommended for big databases, as it will consume much time, memory and processor. In that case it’s preferable to use backup and install_fallback.
    import_piefxis, export_piefxis, export_piefxis_host
    These options can be used to migrate accounts using XEP-0227 formatted XML files from/to other Jabber/XMPP servers or move users of a vhost to another ejabberd installation. See also ejabberd migration kit.
    import_file, import_dir
    These options can be used to migrate accounts using jabberd1.4 formatted XML files. from other Jabber/XMPP servers There exist tutorials to migrate from other software to ejabberd.
    delete_expired_messages
    This option can be used to delete old messages in offline storage. This might be useful when the number of offline messages is very high.
    delete_old_messages days
    Delete offline messages older than the given days.
    register user host password
    Register an account in that domain with the given password.
    unregister user host
    Unregister the given account.

    4.2.2  Restrict Execution with AccessCommands

    The frontends can be configured to restrict access to certain commands. In that case, authentication information must be provided. In each frontend the AccessCommands option is defined in a different place. But in all cases the option syntax is the same:

    AccessCommands = [ {Access, CommandNames, Arguments}, ...]
    Access = atom()
    CommandNames = all | [CommandName]
    CommandName = atom()
    Arguments = [ {ArgumentName, ArgumentValue}, ...]
    ArgumentName = atom()
    ArgumentValue = any()
    

    The default value is to not define any restriction: []. The authentication information is provided when executing a command, and is Username, Hostname and Password of a local XMPP account that has permission to execute the corresponding command. This means that the account must be registered in the local ejabberd, because the information will be verified. It is possible to provide the plaintext password or its MD5 sum.

    When one or several access restrictions are defined and the authentication information is provided, each restriction is verified until one matches completely: the account matches the Access rule, the command name is listed in CommandNames, and the provided arguments do not contradict Arguments.

    As an example to understand the syntax, let’s suppose those options:

    {hosts, ["example.org"]}.
    {acl, bots, {user, "robot1", "example.org"}}.
    {access, commaccess, [{allow, bots}]}.
    

    This list of access restrictions allows only robot1@example.org to execute all commands:

    [{commaccess, all, []}]
    

    See another list of restrictions (the corresponding ACL and ACCESS are not shown):

    [
     %% This bot can execute all commands:
     {bot, all, []},
     %% This bot can only execute the command 'dump'. No argument restriction:
     {bot_backups, [dump], []}
     %% This bot can execute all commands,
     %% but if a 'host' argument is provided, it must be "example.org":
     {bot_all_example, all, [{host, "example.org"}]},
     %% This bot can only execute the command 'register',
     %% and if argument 'host' is provided, it must be "example.org":
     {bot_reg_example, [register], [{host, "example.org"}]},
     %% This bot can execute the commands 'register' and 'unregister',
     %% if argument host is provided, it must be "test.org":
     {_bot_reg_test, [register, unregister], [{host, "test.org"}]}
    ]
    

    4.3  Web Admin

    The ejabberd Web Admin allows to administer most of ejabberd using a web browser.

    This feature is enabled by default: a ejabberd_http listener with the option web_admin (see section 3.1.3) is included in the listening ports. Then you can open http://server:port/admin/ in your favourite web browser. You will be asked to enter the username (the full Jabber ID) and password of an ejabberd user with administrator rights. After authentication you will see a page similar to figure 4.1.


    webadmmain.png
    Figure 4.1: Top page from the Web Admin

    Here you can edit access restrictions, manage users, create backups, manage the database, enable/disable ports listened for, view server statistics,…

    The access rule configure determines what accounts can access the Web Admin and modify it. The access rule webadmin_view is to grant only view access: those accounts can browse the Web Admin with read-only access.

    Example configurations:

    • You can serve the Web Admin on the same port as the HTTP Polling interface. In this example you should point your web browser to http://example.org:5280/admin/ to administer all virtual hosts or to http://example.org:5280/admin/server/example.com/ to administer only the virtual host example.com. Before you get access to the Web Admin you need to enter as username, the JID and password from a registered user that is allowed to configure ejabberd. In this example you can enter as username ‘admin@example.net’ to administer all virtual hosts (first URL). If you log in with ‘admin@example.com’ on
      http://example.org:5280/admin/server/example.com/ you can only administer the virtual host example.com. The account ‘reviewer@example.com’ can browse that vhost in read-only mode.
      {acl, admin, {user, "admin", "example.net"}}.
      {host_config, "example.com", [{acl, admin, {user, "admin", "example.com"}}]}.
      {host_config, "example.com", [{acl, viewers, {user, "reviewer", "example.com"}}]}.
      
      {access, configure, [{allow, admin}]}.
      {access, webadmin_view, [{allow, viewers}]}.
      
      {hosts, ["example.org"]}.
      
      {listen,
       [
        ...
        {5280, ejabberd_http, [http_poll, web_admin]},
        ...
       ]}.
      
    • For security reasons, you can serve the Web Admin on a secured connection, on a port differing from the HTTP Polling interface, and bind it to the internal LAN IP. The Web Admin will be accessible by pointing your web browser to https://192.168.1.1:5282/admin/:
      {hosts, ["example.org"]}.
      
      {listen,
       [
        ...
        {5280, ejabberd_http, [
                               http_poll
                              ]},
        {{5282, "192.168.1.1"}, ejabberd_http, [
                                                web_admin,
                                                tls, {certfile, "/usr/local/etc/server.pem"}
                                               ]},
        ...
       ]}.
      

    Certain pages in the ejabberd Web Admin contain a link to a related section in the ejabberd Installation and Operation Guide. In order to view such links, a copy in HTML format of the Guide must be installed in the system. The file is searched by default in "/share/doc/ejabberd/guide.html". The directory of the documentation can be specified in the environment variable EJABBERD_DOC_PATH. See section 4.1.2.

    4.4  Ad-hoc Commands

    If you enable mod_configure and mod_adhoc, you can perform several administrative tasks in ejabberd with an XMPP client. The client must support Ad-Hoc Commands (XEP-0050), and you must login in the XMPP server with an account with proper privileges.

    4.5  Change Computer Hostname

    ejabberd uses the distributed Mnesia database. Being distributed, Mnesia enforces consistency of its file, so it stores the name of the Erlang node in it (see section 5.4). The name of an Erlang node includes the hostname of the computer. So, the name of the Erlang node changes if you change the name of the machine in which ejabberd runs, or when you move ejabberd to a different machine.

    You have two ways to use the old Mnesia database in an ejabberd with new node name: put the old node name in ejabberdctl.cfg, or convert the database to the new node name.

    Those example steps will backup, convert and load the Mnesia database. You need to have either the old Mnesia spool dir or a backup of Mnesia. If you already have a backup file of the old database, you can go directly to step 5. You also need to know the old node name and the new node name. If you don’t know them, look for them by executing ejabberdctl or in the ejabberd log files.

    Before starting, setup some variables:

    OLDNODE=ejabberd@oldmachine
    NEWNODE=ejabberd@newmachine
    OLDFILE=/tmp/old.backup
    NEWFILE=/tmp/new.backup
    
    1. Start ejabberd enforcing the old node name:
      ejabberdctl --node $OLDNODE start
      
    2. Generate a backup file:
      ejabberdctl --node $OLDNODE backup $OLDFILE
      
    3. Stop the old node:
      ejabberdctl --node $OLDNODE stop
      
    4. Make sure there aren’t files in the Mnesia spool dir. For example:
      mkdir /var/lib/ejabberd/oldfiles
      mv /var/lib/ejabberd/*.* /var/lib/ejabberd/oldfiles/
      
    5. Start ejabberd. There isn’t any need to specify the node name anymore:
      ejabberdctl start
      
    6. Convert the backup to new node name:
      ejabberdctl mnesia_change_nodename $OLDNODE $NEWNODE $OLDFILE $NEWFILE
      
    7. Install the backup file as a fallback:
      ejabberdctl install_fallback $NEWFILE
      
    8. Stop ejabberd:
      ejabberdctl stop
      
      You may see an error message in the log files, it’s normal, so don’t worry:
      Mnesia(ejabberd@newmachine):
      ** ERROR ** (ignoring core)
      ** FATAL ** A fallback is installed and Mnesia must be restarted.
        Forcing shutdown after mnesia_down from ejabberd@newmachine...
      
    9. Now you can finally start ejabberd:
      ejabberdctl start
      
    10. Check that the information of the old database is available: accounts, rosters... After you finish, remember to delete the temporary backup files from public directories.

    Chapter 5  Securing ejabberd

    5.1  Firewall Settings

    You need to take the following TCP ports in mind when configuring your firewall:


    PortDescription
    5222Standard port for Jabber/XMPP client connections, plain or STARTTLS.
    5223Standard port for Jabber client connections using the old SSL method.
    5269Standard port for Jabber/XMPP server connections.
    4369EPMD (section 5.2) listens for Erlang node name requests.
    port rangeUsed for connections between Erlang nodes. This range is configurable (see section 5.2).

    5.2  epmd

    epmd (Erlang Port Mapper Daemon) is a small name server included in Erlang/OTP and used by Erlang programs when establishing distributed Erlang communications. ejabberd needs epmd to use ejabberdctl and also when clustering ejabberd nodes. This small program is automatically started by Erlang, and is never stopped. If ejabberd is stopped, and there aren’t any other Erlang programs running in the system, you can safely stop epmd if you want.

    ejabberd runs inside an Erlang node. To communicate with ejabberd, the script ejabberdctl starts a new Erlang node and connects to the Erlang node that holds ejabberd. In order for this communication to work, epmd must be running and listening for name requests in the port 4369. You should block the port 4369 in the firewall in such a way that only the programs in your machine can access it. or configure the option ERL_EPMD_ADDRESS in the file ejabberdctl.cfg (this option works only in Erlang/OTP R14B03 or higher).

    If you build a cluster of several ejabberd instances, each ejabberd instance is called an ejabberd node. Those ejabberd nodes use a special Erlang communication method to build the cluster, and EPMD is again needed listening in the port 4369. So, if you plan to build a cluster of ejabberd nodes you must open the port 4369 for the machines involved in the cluster. Remember to block the port so Internet doesn’t have access to it.

    Once an Erlang node solved the node name of another Erlang node using EPMD and port 4369, the nodes communicate directly. The ports used in this case by default are random, but can be configured in the file ejabberdctl.cfg. The Erlang command-line parameter used internally is, for example:

    erl ... -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375
    

    It is also possible to configure in ejabberdctl.cfg the network interface where the Erlang node will listen and accept connections. The Erlang command-line parameter used internally is, for example:

    erl ... -kernel inet_dist_use_interface "{127,0,0,1}"
    

    5.3  Erlang Cookie

    The Erlang cookie is a string with numbers and letters. An Erlang node reads the cookie at startup from the command-line parameter -setcookie. If not indicated, the cookie is read from the cookie file $HOME/.erlang.cookie. If this file does not exist, it is created immediately with a random cookie. Two Erlang nodes communicate only if they have the same cookie. Setting a cookie on the Erlang node allows you to structure your Erlang network and define which nodes are allowed to connect to which.

    Thanks to Erlang cookies, you can prevent access to the Erlang node by mistake, for example when there are several Erlang nodes running different programs in the same machine.

    Setting a secret cookie is a simple method to difficult unauthorized access to your Erlang node. However, the cookie system is not ultimately effective to prevent unauthorized access or intrusion to an Erlang node. The communication between Erlang nodes are not encrypted, so the cookie could be read sniffing the traffic on the network. The recommended way to secure the Erlang node is to block the port 4369.

    5.4  Erlang Node Name

    An Erlang node may have a node name. The name can be short (if indicated with the command-line parameter -sname) or long (if indicated with the parameter -name). Starting an Erlang node with -sname limits the communication between Erlang nodes to the LAN.

    Using the option -sname instead of -name is a simple method to difficult unauthorized access to your Erlang node. However, it is not ultimately effective to prevent access to the Erlang node, because it may be possible to fake the fact that you are on another network using a modified version of Erlang epmd. The recommended way to secure the Erlang node is to block the port 4369.

    5.5  Securing Sensitive Files

    ejabberd stores sensitive data in the file system either in plain text or binary files. The file system permissions should be set to only allow the proper user to read, write and execute those files and directories.

    ejabberd configuration file: /etc/ejabberd/ejabberd.cfg
    Contains the JID of administrators and passwords of external components. The backup files probably contain also this information, so it is preferable to secure the whole /etc/ejabberd/ directory.
    ejabberd service log: /var/log/ejabberd/ejabberd.log
    Contains IP addresses of clients. If the loglevel is set to 5, it contains whole conversations and passwords. If a logrotate system is used, there may be several log files with similar information, so it is preferable to secure the whole /var/log/ejabberd/ directory.
    Mnesia database spool files in /var/lib/ejabberd/
    The files store binary data, but some parts are still readable. The files are generated by Mnesia and their permissions cannot be set directly, so it is preferable to secure the whole /var/lib/ejabberd/ directory.
    Erlang cookie file: /var/lib/ejabberd/.erlang.cookie
    See section 5.3.

    Chapter 6  Clustering

    6.1  How it Works

    A XMPP domain is served by one or more ejabberd nodes. These nodes can be run on different machines that are connected via a network. They all must have the ability to connect to port 4369 of all another nodes, and must have the same magic cookie (see Erlang/OTP documentation, in other words the file ~ejabberd/.erlang.cookie must be the same on all nodes). This is needed because all nodes exchange information about connected users, s2s connections, registered services, etc…

    Each ejabberd node has the following modules:

    • router,
    • local router,
    • session manager,
    • s2s manager.

    6.1.1  Router

    This module is the main router of XMPP packets on each node. It routes them based on their destination’s domains. It uses a global routing table. The domain of the packet’s destination is searched in the routing table, and if it is found, the packet is routed to the appropriate process. If not, it is sent to the s2s manager.

    6.1.2  Local Router

    This module routes packets which have a destination domain equal to one of this server’s host names. If the destination JID has a non-empty user part, it is routed to the session manager, otherwise it is processed depending on its content.

    6.1.3  Session Manager

    This module routes packets to local users. It looks up to which user resource a packet must be sent via a presence table. Then the packet is either routed to the appropriate c2s process, or stored in offline storage, or bounced back.

    6.1.4  s2s Manager

    This module routes packets to other XMPP servers. First, it checks if an opened s2s connection from the domain of the packet’s source to the domain of the packet’s destination exists. If that is the case, the s2s manager routes the packet to the process serving this connection, otherwise a new connection is opened.

    6.2  Clustering Setup

    Suppose you already configured ejabberd on one machine named (first), and you need to setup another one to make an ejabberd cluster. Then do following steps:

    1. Copy ~ejabberd/.erlang.cookie file from first to second.

      (alt) You can also add ‘-setcookie content_of_.erlang.cookie’ option to all ‘erl’ commands below.

    2. On second run the following command as the ejabberd daemon user, in the working directory of ejabberd:
      erl -sname ejabberd \
          -mnesia dir '"/var/lib/ejabberd/"' \
          -mnesia extra_db_nodes "['ejabberd@first']" \
          -s mnesia
      

      This will start Mnesia serving the same database as ejabberd@first. You can check this by running the command ‘mnesia:info().’. You should see a lot of remote tables and a line like the following:

      Note: the Mnesia directory may be different in your system. To know where does ejabberd expect Mnesia to be installed by default, call 4.1 without options and it will show some help, including the Mnesia database spool dir.

      running db nodes   = [ejabberd@first, ejabberd@second]
      
    3. Now run the following in the same ‘erl’ session:
      mnesia:change_table_copy_type(schema, node(), disc_copies).
      

      This will create local disc storage for the database.

      (alt) Change storage type of the scheme table to ‘RAM and disc copy’ on the second node via the Web Admin.

    4. Now you can add replicas of various tables to this node with ‘mnesia:add_table_copy’ or ‘mnesia:change_table_copy_type’ as above (just replace ‘schema’ with another table name and ‘disc_copies’ can be replaced with ‘ram_copies’ or ‘disc_only_copies’).

      Which tables to replicate is very dependant on your needs, you can get some hints from the command ‘mnesia:info().’, by looking at the size of tables and the default storage type for each table on ’first’.

      Replicating a table makes lookups in this table faster on this node. Writing, on the other hand, will be slower. And of course if machine with one of the replicas is down, other replicas will be used.

      Also section 5.3 (Table Fragmentation) of Mnesia User’s Guide can be helpful.

      (alt) Same as in previous item, but for other tables.

    5. Run ‘init:stop().’ or just ‘q().’ to exit from the Erlang shell. This probably can take some time if Mnesia has not yet transfered and processed all data it needed from first.
    6. Now run ejabberd on second with a configuration similar as on first: you probably do not need to duplicate ‘acl’ and ‘access’ options because they will be taken from first; and mod_irc should be enabled only on one machine in the cluster.

    You can repeat these steps for other machines supposed to serve this domain.

    6.3  Service Load-Balancing

    6.3.1  Domain Load-Balancing Algorithm

    ejabberd includes an algorithm to load balance the components that are plugged on an ejabberd cluster. It means that you can plug one or several instances of the same component on each ejabberd cluster and that the traffic will be automatically distributed.

    The default distribution algorithm try to deliver to a local instance of a component. If several local instances are available, one instance is chosen randomly. If no instance is available locally, one instance is chosen randomly among the remote component instances.

    If you need a different behaviour, you can change the load balancing behaviour with the option domain_balancing. The syntax of the option is the following:

    {domain_balancing, "component.example.com", BalancingCriteria}.

    Several balancing criteria are available:

    • destination: the full JID of the packet to attribute is used.
    • source: the full JID of the packet from attribute is used.
    • bare_destination: the bare JID (without resource) of the packet to attribute is used.
    • bare_source: the bare JID (without resource) of the packet from attribute is used.

    If the value corresponding to the criteria is the same, the same component instance in the cluster will be used.

    6.3.2  Load-Balancing Buckets

    When there is a risk of failure for a given component, domain balancing can cause service trouble. If one component is failing the service will not work correctly unless the sessions are rebalanced.

    In this case, it is best to limit the problem to the sessions handled by the failing component. This is what the domain_balancing_component_number option does, making the load balancing algorithm not dynamic, but sticky on a fix number of component instances.

    The syntax is:

    {domain_balancing_component_number, "component.example.com", Number}.

    Chapter 7  Debugging

    7.1  Log Files

    An ejabberd node writes two log files:

    ejabberd.log
    is the ejabberd service log, with the messages reported by ejabberd code
    erlang.log
    is the Erlang/OTP system log, with the messages reported by Erlang/OTP using SASL (System Architecture Support Libraries)

    The option loglevel modifies the verbosity of the file ejabberd.log. The syntax is one of:

    {loglevel, Level}.
    The standard form to set a global log level.
    {loglevel, {Level, [{Module, Level}, ...]}}.
    The given Erlang modules will be logged with specific log levels, all others will use the default log level.

    The possible Level are:

    0
    No ejabberd log at all (not recommended)
    1
    Critical
    2
    Error
    3
    Warning
    4
    Info
    5
    Debug

    For example, the default configuration is:

    {loglevel, 4}.
    

    The log files grow continually, so it is recommended to rotate them periodically. To rotate the log files, rename the files and then reopen them. The ejabberdctl command reopen-log (please refer to section 4.1.1) reopens the log files, and also renames the old ones if you didn’t rename them.

    7.2  Debug Console

    The Debug Console is an Erlang shell attached to an already running ejabberd server. With this Erlang shell, an experienced administrator can perform complex tasks.

    This shell gives complete control over the ejabberd server, so it is important to use it with extremely care. There are some simple and safe examples in the article Interconnecting Erlang Nodes

    To exit the shell, close the window or press the keys: control+c control+c.

    7.3  Watchdog Alerts

    ejabberd includes a watchdog mechanism that may be useful to developers when troubleshooting a problem related to memory usage. If a process in the ejabberd server consumes more memory than the configured threshold, a message is sent to the XMPP accounts defined with the option watchdog_admins in the ejabberd configuration file.

    The syntax is:

    {watchdog_admins, [JID, ...]}.

    The memory consumed is measured in words: a word on 32-bit architecture is 4 bytes, and a word on 64-bit architecture is 8 bytes. The threshold by default is 1000000 words. This value can be configured with the option watchdog_large_heap, or in a conversation with the watchdog alert bot.

    The syntax is:

    {watchdog_large_heap, Number}.

    Example configuration:

    {watchdog_admins, ["admin2@localhost", "admin2@example.org"]}.
    {watchdog_large_heap, 30000000}.
    

    To remove watchdog admins, remove them in the option. To remove all watchdog admins, set the option with an empty list:

    {watchdog_admins, []}.
    

    Appendix A  Internationalization and Localization

    The source code of ejabberd supports localization. The translators can edit the gettext .po files using any capable program (KBabel, Lokalize, Poedit...) or a simple text editor.

    Then gettext is used to extract, update and export those .po files to the .msg format read by ejabberd. To perform those management tasks, in the src/ directory execute make translations. The translatable strings are extracted from source code to generate the file ejabberd.pot. This file is merged with each .po file to produce updated .po files. Finally those .po files are exported to .msg files, that have a format easily readable by ejabberd.

    All built-in modules support the xml:lang attribute inside IQ queries. Figure A.1, for example, shows the reply to the following query:

    <iq id='5'
        to='example.org'
        type='get'
        xml:lang='ru'>
      <query xmlns='http://jabber.org/protocol/disco#items'/>
    </iq>
    

    discorus.png
    Figure A.1: Service Discovery when xml:lang=’ru’

    The Web Admin also supports the Accept-Language HTTP header.


    webadmmainru.png
    Figure A.2: Web Admin showing a virtual host when the web browser provides the HTTP header ‘Accept-Language: ru’

    Appendix B  Release Notes

    Release notes are available from ejabberd Home Page

    Appendix C  Acknowledgements

    Thanks to all people who contributed to this guide:

    Appendix D  Copyright Information

    Ejabberd Installation and Operation Guide.
    Copyright © 2003 — 2012 ProcessOne

    This document 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 document 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 document; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.


    This document was translated from LATEX by HEVEA.
    ejabberd-2.1.11/doc/dev.tex0000664000000000000000000003243112240230175012266 0ustar \documentclass[a4paper,10pt]{article} %% Packages \usepackage{graphics} \usepackage{hevea} \usepackage{makeidx} \usepackage{verbatim} %% Index \makeindex % Remove the index anchors from the HTML version to save size and bandwith. \newcommand{\ind}[1]{\begin{latexonly}\index{#1}\end{latexonly}} %% Images \newcommand{\logoscale}{0.7} \newcommand{\imgscale}{0.58} \newcommand{\insimg}[1]{\insscaleimg{\imgscale}{#1}} \newcommand{\insscaleimg}[2]{ \imgsrc{#2}{} \begin{latexonly} \scalebox{#1}{\includegraphics{#2}} \end{latexonly} } %% Various \newcommand{\ns}[1]{\texttt{#1}} \newcommand{\ejabberd}{\texttt{ejabberd}} \newcommand{\Jabber}{Jabber} \newcommand{\XMPP}{XMPP} %% Modules \newcommand{\module}[1]{\texttt{#1}} \newcommand{\modadhoc}{\module{mod\_adhoc}} \newcommand{\modannounce}{\module{mod\_announce}} \newcommand{\modconfigure}{\module{mod\_configure}} \newcommand{\moddisco}{\module{mod\_disco}} \newcommand{\modecho}{\module{mod\_echo}} \newcommand{\modirc}{\module{mod\_irc}} \newcommand{\modlast}{\module{mod\_last}} \newcommand{\modlastodbc}{\module{mod\_last\_odbc}} \newcommand{\modmuc}{\module{mod\_muc}} \newcommand{\modmuclog}{\module{mod\_muc\_log}} \newcommand{\modoffline}{\module{mod\_offline}} \newcommand{\modofflineodbc}{\module{mod\_offline\_odbc}} \newcommand{\modprivacy}{\module{mod\_privacy}} \newcommand{\modprivate}{\module{mod\_private}} \newcommand{\modpubsub}{\module{mod\_pubsub}} \newcommand{\modregister}{\module{mod\_register}} \newcommand{\modroster}{\module{mod\_roster}} \newcommand{\modrosterodbc}{\module{mod\_roster\_odbc}} \newcommand{\modservicelog}{\module{mod\_service\_log}} \newcommand{\modsharedroster}{\module{mod\_shared\_roster}} \newcommand{\modstats}{\module{mod\_stats}} \newcommand{\modtime}{\module{mod\_time}} \newcommand{\modvcard}{\module{mod\_vcard}} \newcommand{\modvcardldap}{\module{mod\_vcard\_ldap}} \newcommand{\modvcardodbc}{\module{mod\_vcard\_odbc}} \newcommand{\modversion}{\module{mod\_version}} %% Title page \include{version} \title{Ejabberd \version\ Developers Guide} \author{Alexey Shchepin \\ \ahrefurl{mailto:alexey@sevcom.net} \\ \ahrefurl{xmpp:aleksey@jabber.ru}} %% Options \newcommand{\marking}[1]{#1} % Marking disabled \newcommand{\quoting}[2][yozhik]{} % Quotes disabled \newcommand{\new}{\begin{latexonly}\marginpar{\textsc{new}}\end{latexonly}} % Highlight new features \newcommand{\improved}{\begin{latexonly}\marginpar{\textsc{improved}}\end{latexonly}} % Highlight improved features \newcommand{\moreinfo}[1]{} % Hide details %% Footnotes \newcommand{\txepref}[2]{\footahref{http://www.xmpp.org/extensions/xep-#1.html}{#2}} \newcommand{\xepref}[1]{\txepref{#1}{XEP-#1}} \begin{document} \label{titlepage} \begin{titlepage} \maketitle{} \begin{center} {\insscaleimg{\logoscale}{logo.png} \par } \end{center} \begin{quotation}\textit{I can thoroughly recommend ejabberd for ease of setup -- Kevin Smith, Current maintainer of the Psi project}\end{quotation} \end{titlepage} \tableofcontents{} % Input introduction.tex \input{introduction} \section{How it Works} \label{howitworks} A \XMPP{} domain is served by one or more \ejabberd{} nodes. These nodes can be run on different machines that are connected via a network. They all must have the ability to connect to port 4369 of all another nodes, and must have the same magic cookie (see Erlang/OTP documentation, in other words the file \texttt{\~{}ejabberd/.erlang.cookie} must be the same on all nodes). This is needed because all nodes exchange information about connected users, S2S connections, registered services, etc\ldots Each \ejabberd{} node have following modules: \begin{itemize} \item router; \item local router. \item session manager; \item S2S manager; \end{itemize} \subsection{Router} This module is the main router of \XMPP{} packets on each node. It routes them based on their destinations domains. It has two tables: local and global routes. First, domain of packet destination searched in local table, and if it found, then the packet is routed to appropriate process. If no, then it searches in global table, and is routed to the appropriate \ejabberd{} node or process. If it does not exists in either tables, then it sent to the S2S manager. \subsection{Local Router} This module routes packets which have a destination domain equal to this server name. If destination JID has a non-empty user part, then it routed to the session manager, else it is processed depending on it's content. \subsection{Session Manager} This module routes packets to local users. It searches for what user resource packet must be sent via presence table. If this resource is connected to this node, it is routed to C2S process, if it connected via another node, then the packet is sent to session manager on that node. \subsection{S2S Manager} This module routes packets to other \XMPP{} servers. First, it checks if an open S2S connection from the domain of the packet source to the domain of packet destination already exists. If it is open on another node, then it routes the packet to S2S manager on that node, if it is open on this node, then it is routed to the process that serves this connection, and if a connection does not exist, then it is opened and registered. \section{Authentication} \subsubsection{External} \label{externalauth} \ind{external authentication} The external authentication script follows \footahref{http://www.erlang.org/doc/tutorial/c_portdriver.html}{the erlang port driver API}. That script is supposed to do theses actions, in an infinite loop: \begin{itemize} \item read from stdin: AABBBBBBBBB..... \begin{itemize} \item A: 2 bytes of length data (a short in network byte order) \item B: a string of length found in A that contains operation in plain text operation are as follows: \begin{itemize} \item auth:User:Server:Password (check if a username/password pair is correct) \item isuser:User:Server (check if it's a valid user) \item setpass:User:Server:Password (set user's password) \item tryregister:User:Server:Password (try to register an account) \item removeuser:User:Server (remove this account) \item removeuser3:User:Server:Password (remove this account if the password is correct) \end{itemize} \end{itemize} \item write to stdout: AABB \begin{itemize} \item A: the number 2 (coded as a short, which is bytes length of following result) \item B: the result code (coded as a short), should be 1 for success/valid, or 0 for failure/invalid \end{itemize} \end{itemize} Example python script \begin{verbatim} #!/usr/bin/python import sys from struct import * def from_ejabberd(): input_length = sys.stdin.read(2) (size,) = unpack('>h', input_length) return sys.stdin.read(size).split(':') def to_ejabberd(bool): answer = 0 if bool: answer = 1 token = pack('>hh', 2, answer) sys.stdout.write(token) sys.stdout.flush() def auth(username, server, password): return True def isuser(username, server): return True def setpass(username, server, password): return True while True: data = from_ejabberd() success = False if data[0] == "auth": success = auth(data[1], data[2], data[3]) elif data[0] == "isuser": success = isuser(data[1], data[2]) elif data[0] == "setpass": success = setpass(data[1], data[2], data[3]) to_ejabberd(success) \end{verbatim} \section{XML Representation} \label{xmlrepr} Each XML stanza is represented as the following tuple: \begin{verbatim} XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]} Name = string() Attrs = [Attr] Attr = {Key, Val} Key = string() Val = string() ElementOrCDATA = XMLElement | CDATA CDATA = {xmlcdata, string()} \end{verbatim} E.\,g. this stanza: \begin{verbatim} test \end{verbatim} is represented as the following structure: \begin{verbatim} {xmlelement, "message", [{"to", "test@conference.example.org"}, {"type", "groupchat"}], [{xmlelement, "body", [], [{xmlcdata, "test"}]}]}} \end{verbatim} \section{Module \texttt{xml}} \label{xmlmod} \begin{description} \item{\verb|element_to_string(El) -> string()|} \begin{verbatim} El = XMLElement \end{verbatim} Returns string representation of XML stanza \texttt{El}. \item{\verb|crypt(S) -> string()|} \begin{verbatim} S = string() \end{verbatim} Returns string which correspond to \texttt{S} with encoded XML special characters. \item{\verb|remove_cdata(ECList) -> EList|} \begin{verbatim} ECList = [ElementOrCDATA] EList = [XMLElement] \end{verbatim} \texttt{EList} is a list of all non-CDATA elements of ECList. \item{\verb|get_path_s(El, Path) -> Res|} \begin{verbatim} El = XMLElement Path = [PathItem] PathItem = PathElem | PathAttr | PathCDATA PathElem = {elem, Name} PathAttr = {attr, Name} PathCDATA = cdata Name = string() Res = string() | XMLElement \end{verbatim} If \texttt{Path} is empty, then returns \texttt{El}. Else sequentially consider elements of \texttt{Path}. Each element is one of: \begin{description} \item{\verb|{elem, Name}|} \texttt{Name} is name of subelement of \texttt{El}, if such element exists, then this element considered in following steps, else returns empty string. \item{\verb|{attr, Name}|} If \texttt{El} have attribute \texttt{Name}, then returns value of this attribute, else returns empty string. \item{\verb|cdata|} Returns CDATA of \texttt{El}. \end{description} \item{TODO:} \begin{verbatim} get_cdata/1, get_tag_cdata/1 get_attr/2, get_attr_s/2 get_tag_attr/2, get_tag_attr_s/2 get_subtag/2 \end{verbatim} \end{description} \section{Module \texttt{xml\_stream}} \label{xmlstreammod} \begin{description} \item{\verb!parse_element(Str) -> XMLElement | {error, Err}!} \begin{verbatim} Str = string() Err = term() \end{verbatim} Parses \texttt{Str} using XML parser, returns either parsed element or error tuple. \end{description} \section{Modules} \label{emods} %\subsection{gen\_mod behaviour} %\label{genmod} %TBD \subsection{Module gen\_iq\_handler} \label{geniqhandl} The module \verb|gen_iq_handler| allows to easily write handlers for IQ packets of particular XML namespaces that addressed to server or to users bare JIDs. In this module the following functions are defined: \begin{description} \item{\verb|add_iq_handler(Component, Host, NS, Module, Function, Type)|} \begin{verbatim} Component = Module = Function = atom() Host = NS = string() Type = no_queue | one_queue | parallel \end{verbatim} Registers function \verb|Module:Function| as handler for IQ packets on virtual host \verb|Host| that contain child of namespace \verb|NS| in \verb|Component|. Queueing discipline is \verb|Type|. There are at least two components defined: \begin{description} \item{\verb|ejabberd_local|} Handles packets that addressed to server JID; \item{\verb|ejabberd_sm|} Handles packets that addressed to users bare JIDs. \end{description} \item{\verb|remove_iq_handler(Component, Host, NS)|} \begin{verbatim} Component = atom() Host = NS = string() \end{verbatim} Removes IQ handler on virtual host \verb|Host| for namespace \verb|NS| from \verb|Component|. \end{description} Handler function must have the following type: \begin{description} \item{\verb|Module:Function(From, To, IQ)|} \begin{verbatim} From = To = jid() \end{verbatim} \end{description} \begin{verbatim} -module(mod_cputime). -behaviour(gen_mod). -export([start/2, stop/1, process_local_iq/3]). -include("ejabberd.hrl"). -include("jlib.hrl"). -define(NS_CPUTIME, "ejabberd:cputime"). start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_CPUTIME, ?MODULE, process_local_iq, IQDisc). stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_CPUTIME). process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> case Type of set -> {iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; get -> CPUTime = element(1, erlang:statistics(runtime))/1000, SCPUTime = lists:flatten(io_lib:format("~.3f", CPUTime)), {iq, ID, result, XMLNS, [{xmlelement, "query", [{"xmlns", ?NS_CPUTIME}], [{xmlelement, "cputime", [], [{xmlcdata, SCPUTime}]}]}]} end. \end{verbatim} \subsection{Services} \label{services} %TBD %TODO: use \verb|proc_lib| \begin{verbatim} -module(mod_echo). -behaviour(gen_mod). -export([start/2, init/1, stop/1]). -include("ejabberd.hrl"). -include("jlib.hrl"). start(Host, Opts) -> MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host), register(gen_mod:get_module_proc(Host, ?PROCNAME), spawn(?MODULE, init, [MyHost])). init(Host) -> ejabberd_router:register_local_route(Host), loop(Host). loop(Host) -> receive {route, From, To, Packet} -> ejabberd_router:route(To, From, Packet), loop(Host); stop -> ejabberd_router:unregister_route(Host), ok; _ -> loop(Host) end. stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), Proc ! stop, {wait, Proc}. \end{verbatim} \end{document} ejabberd-2.1.11/doc/logo.png0000664000000000000000000024215612240230175012443 0ustar PNG  IHDR- pHYs  tIME ' IDATx˓du޻ɪwhP$("A+QġY~E@yt y [ĶL,ZԕQI!AijF<˃}>ڏs2d0'2/-$"omͷ6tk|omͷCmͷ6fͷ6|o3|omomͷ6fͷ6|n[`7-c|o3|KB =L8Ckoށ < (Tm|oGPQC8#jom),"2O_4 |vCe~2;:f,ͷCm]Щ'T6}ZL83iow/Q<$zxxm|ǩlX-x $NiwY-ͷCU<޶¾h1g3h43ioG@ISEcn[x,,̡vdV杂Y'ͷC{Fuy/&j)ͷ6sh?W1PwpcI3̡~铪{3R:} 8cwm 6shM-}TV)=TXN ̤6shm!k"X_F |G,8 f|94 ဧ9L:ԯVaX-|94~kQΔPr,~Xb|o3[? *t+TQEGҺ]ѱ=ER3̡y3L+0l>a HMUE8fͷ-jgL7Nu$,I6^7shkvQ{5̇=u3Pj[F^\!~&pmN,qL!T6̡v4PԽTS82QePJu3ۑO*j o 9Sp34ZK!h|; ʰ*GMn1?k\ *,94ˣCAƓ!oZfZoe=Dq>ίWC6f#̡vD4PRp\gHyMaι. Yh|;D*@gӊوwZe86i4sh@W(=LnN搩b]nԈ SK!4946@>HR?H,ǡp妉N$N(LCmR{+]aHnԀ ^q> ~e̡N1}؅%BLGqG8s$&U)Al|u̡6Z#D#g K(!yn{LC8h+1Q$,86C.Xc 2Yo@["~*!(cήR̡M !R TSQm`v) uQ@h̡V@Pi0|fuʧfW!k$Iu<+L7shMc~6нcgU1$z2494߼(`K*{91LF)*ʈTɱ]^~%Fsn|3eZ4M4ٜȧϮGb̡@8 PP":_P14^WXF3Q{]7߉ Y88=GxG8~U(pLOL7sAB(Fl0kqϴnp{j˕ x#;h. r*3 c{$XLa;`81eN[#~j-kt7 PY:L2#|ۮΤZT UN092WZuݐǞiV}=Sd\!M?4Z ֓j *.~ngK^:Uͱi+u;5CGY Ma] ӏ+u#CChlT1hnHyK^{P7nu.#L"ƎFsnjWTq*k&,=x{ӄQ^$*_>iI\9t8 {^)W ?PcSUφJb#fHpC( Th%0{{ʷ8j-5{f Ƚqay0D UTEEխ[}v uM*h1f8bKQM s"*jGN;+^6sxuyTq}M :s.(˽ cNY뉡`KGcŰ곫PrSv̡L % :dOϹ~Ѕ 4c)J6AUHԍ'p.9Tad;[@#̴:_X4 ̮=-mvhmٙC IZ+J&`V~f]sكل&ÉŤ(!d(E U.9~ $ʠ<~LM Ve!ՋF}O>!chL \9ąP^aPՊ7~AQƊD,%gVzRI&@fvһ>Piw]aÌCZˊN mGBB*ڔxBbc;rTeϮN&f!2B) %ygWUFykb8N)A2]!_Mt3t6kq| 8Lhd-i Td'ǰ0mᄲtI5tfWb (9P*C*2PRppG4,2il Uo!]B(JVl͎FEʞ d(53TKLH4^8!Ҍ{CI4juAjF(*AB ~TO*u;(I%QT^Baxb pd86sגA% 򊞨/.PKH"F} SHfRʦ;c>yW*(Ԛ6D M Ѣ$M"p-@E% KSDQ&e/9-:}C캟̡ 쬄ԍy Rk13J*n酘-KmqáQa4M(>Q C%U.0²l$KBλCa URawJRSaM#̮Y!o0ll߀Cl; rkPaOe u-$;I ܵքԑ a Pi;*YB#3-tϡPs$%4vvnό@@IJ>aݮQ[C)/%wRC{dmN#Xe6 E}x9t( ġKRBNӌhʣdn{RNMB,'{p5uIO3 I?%Bj2.!M+z!Tq=Dr10 wPJA|U+l{{wUW!wv 8ZB`g r]Y.:I+H9k³wQil$IjL AhvhLjQ5:*}qP;G(! PD;Fvo}NYJ]0rd2tX\-;tB6B…8zH8Bj3՚pKj AV(%S0J5/l&ųp8dx5AhE5 yp"ppN@-yR%T#Ms| Ĺp.R;䦫5-T2: gqVYtD@NXK|H s3BqP$2RYBhT8/ąHBraP- !>ZB(/AQ+)LUDpoPU t*1,ځV73q'P YCPչ7<|S|Fd5~"wd *Bhs(BjFA(v$4.% m; ׽*ʨm<ֶ!©ܜ͏ k ˹06vMцsH&r *?]O^ P+S߽]ݱmRMV9i)0tGTy!ù0*}kg3'6C+We@HmLkU(P})@}w8ӏ AJ{Wˆ1 xQ-Mjm`un9*rItIJLŽD_\ =|+@ޒZTjm`&Ì^_!i>2c" 1*oE,۴rH!P}_g(i ̴T#D3Z[{hRΪ 7-d(p]vh{Ӗo&R!POx:uV`G<{j:% S'kj!X cL YR(.f&6CPA@ȟ~uA2s q37dʹVT xS(:C0*ۻc+Q`Gݡ@b&6CζP]CH DЮ`k~n(IE,Lk:iݦtd,ihF6(-gq(\ 5 B#)U^=ҞV$*TT"7{$[1){P?y+(8P^ E)6MjP^! ܾ! :ے ?UrL+tPHhi!eZ1 aME&ǯm{8VZ'ۛi?/kl[`-yI$(vo3쀟$0Gm9)]i9_)I6Eu<ڄ!UK1ZJ(,k 6@pYcV=‰lU)a l3͢Q4&bacwKN-0Mm{s8m Uwu33p-.*rCEDؼ!HI$ yV9$̮t5TcȮqQÆhչ Jv\* 7[mg5ZcJq& 1aF  dOWmCQ; LJ h\m'8΅QQNu7gXsun8RƀP]8 !dN"GM!#6&ohxomI7S[/azB6W堬{48)./tȥ@VBm pڥV84/QHjU☇-ֲb"+J.|g ZJݣ!3D- >7n YS/xZ+GM2,8 gW9D%E&U9l=DkЊ]R0f+"8f$[EI_K5l l*Ԟ] 똋V9}#j;*N\"He7ak .+r%ZHPɞ! I hΩUIZ*<^N4*]M8s#P[?υnquq(O Uȍ R !_ SDQ8'C1%=Lk% ,w4\ml.ujD(05(*_u7Ti4{-c@ӌM!eE!!HK`2r';(gW!kZ(P[i!Pi{EuPވ+'.P)C-{`X*Ri!愐O@thP s[LធC%b|a| C=8c>eS|+@bog*p96^YL!fO8X1 oTK *'E(*I1ȣ)9lrP摫8-tx %0I@JωS+ژ̉"W3*rLiI:@JƢU*(Q!7Cam(Gѱ=ܓqȰ'T޴PIdC IDATfy*,Nf⒤۝J`O#L!5:%%"*In \]SĮ.E5[78!Ǐh83o&xOOt )Jq jnȚ(Na(dca&IIV9Լm yW(b-(Azn$CPu\ŶP*5-c@(*"c^^\P*o*2_C,_ BptPTY`.K=, FkCc1P gAH sT(-_ʌ:͛s?W>2&c%lthlCLZ$mU!Y&tJ1E3vR|"oUx k3ZE#:sJbLEM-F,yU;Ȳ0xf*P8݇ ˊ U^D *3`# D呯ģoxr 5L@dQ]9 i(Șrzl I4*PnB C.^g M#NXȚo(W\ΪsH*@*QUhqV7ڍ( /*D ƹ8D]* U\ATI0䂉 0!(+'-9%8NY!gu9~QxpYk#v}Ba t FB08g|C՗DqHCt~ &.  ? og$-t PQj]gб]c;FJ]ƴ(R`Qx< %KT|h$Cz[V9Kp6E_iC4[!.s(R:-!Â"w& scFS OCq=rfe-V"c(!O!ݰ$V]I, b  hT2-Y pBgID@&Wqfrlll`U1e,}YS>.H6v{Hv!.@l ?3貇gW14*FyBDc_Sv| K0?KdZġ**Q>lP2[kUku剡¼ITm Q՝TB9=C~$#2UEkN2, vծF*#ZnfEQ=5K;F|~&xTomZZC5܄*E5S V8v8)!PthҜ[0>}!e*gwuUGQREUkjI"&ec@(-d0hPBˊ GܐIaӘCI LUE|SήFFw+hd8Ċ>nIUm4V#t V#:`n]. ˊnPx$> @P^O\$jv L/8^P;2a[qGeu4WC"t-bZ!-FBqeE^S"$ʹ&&W03-懘BurEs2O,9P4Ƣ$ۛ!bI԰0$U6{H[#--i͈THb)sU2M˧ʛW h)eqgww*dTa PP$ %M (]`N2/ (c$˹U] F]];["~ jb$a8 jҨ麪v9rK1 K%6s]h@O̙V_ .;\7Ĉ9LbRR@2PxlFRApY/n3&jM;pWiš%[ ==!j׀FNt T8DH}ul>ߌ!P4'#gyY>U]S*"`Zĝߔ[tr7dqO)w8%.!P1T8x-p1+rR{ def2( NʵQ8X!ov y TRt5p*([m+;T:Wk5C1rH9R B'oMFRMr2p':QsK2qL}Ux*c6xQ BU:yUJ<:W=짢$f4L͡C8{T o-)U!jK 9Mڒd/WñԘ] |rʁ"`Έ+\1_dk[W7.A 1 [[>c=dBȉ9kqfOf!I i QWq"ήF' vw ϮF;FzE eѪs2]$ 5j|(4e+r*֮ba͞x uIu!"B9HW" gsl;P6-SScl'.cS<wZjvϺ$92Ɠ8Wy<S"g>S rB(/':iT@qoWtlWrRR&|B6 ELGuVBr' ycor( 8Te30[ fW4bF'02RGBy.( krgAlE * 9QXtwZ!Lf f!?Ӛ:Q5fZp;'PKJhxb|ź(2s]q4Ul~\[$9,ʕ̮ꘪGa1T>%-!5sηE0mvROcCĵ߈eg\9(J v T-w¤tnO:(es iyt) S`hع1d|+ηBՉ")#.pζPoߑ郫aQS&I"{F3`SYRZi.CFO9]"xQrL1ib br`Ύ#y0rB( |+@ƼT)$xoU6ȚxFxNT E̙(Z $r~+-~;C\j +vU qpnS.iB>dLq̴]c 8lsɬAdBMp.EQB(EQrDGjy'`8EǡR)UUb(Ϟ^Tu`:+;. XC`hADQ,4Ξ;㦏EUG'wCAtĽp] LbexͧrIK-%OTD:К!=%Vcư0&5@ $ד 7[V>* yr,la2Z7mŋVݑty(Bl頫A[WjFý!(a5CzQ|P!f;' R_ҬQ!dr@3оP?)._(Nૢ@QP1:$rX9.g2;:U #6{  d_%R[gZ=H춟hyB"fPmM 9h&s*?:!E8Tw"$ %%28Ys5rxCR_$q1 nBjgݜ3 / !lP{!Nb~~eE` :j"(tD 3x~ Oz㪠PQ )C7a[pBJmS tvnXǓ( bVWsPz`-P ɝ@y $yjtz~q0gD}#r(% qOh]6{wi?4}&๺Ġ7")cYQZq3@2BDiy=A5('BQDurK`#(9uY-%F㍂pVͻ7{c\Pg[(zIy Wl{٨Wl qo#@-%Ts|Hg` gr::k[=$H0ol4ȅKˊ\U8r\&ZAUJZH&C5ꮷѰk[ǨM$ч1 I[!RR;um+9Q(W x(9$o9̔ a9hB$b`mq 䢈SaFh9+R2Gή&-Z]\XoN PXkf\BZu9׭-?Onɨ!f `Z^;gW x!tFsBޚe3 I4lPÏ{ՏB͠iH$~eJAVj|ª!Zfn}?>ZAmXCWL͓9H[v(rve"mfy,÷Qrw<>@Yh.oi#9v^Q-m_S13 !`^| )qv .A XUc@y/̴|h gtלIeO "͡I gO *"A#"(aOHI#trtDŽIDd+d 2KV㠰WSD܁˱]܍䓐k]ݺ`#OCH{D+Tld Z˛ď""$}Eu69չAWdZc*M Ex~Q pqw9QdتC^F!:8F?CtZMŧÌi1ΑSbTBF'rRY^ B\P]$mY6Qi"cџmbe='(1 N1dg(…_mݴn< FOX\,yo>őD_Hly͋]PEݒrnN5~|h@#-*9 1V\v!ZW8R7٣<Tt>XvjHH-?h?D\bf@ áravI E:c0LWEP vQW-i@1MPfVaCmO]%":qϵ琜4v_jB|p9$z&`qeOid3'+~1g q VFg*/N#nr`Ȟv"":SENٌ1k6Do8M'W f?EP}DZDz(сb\1(xIRB8У|%A]&ȁ#4!dE- 6J hj 4lۂ9up>cy +5- =8, o۴h }` eRPquzu.dH"yq4FJmFGK"G@Q%Qbُ On8A)_&We|rص0p^}%2x s u0QNv^U}` )~䥣2Hw "'{ Dm~(B= F+R]2hP's@Hecڜ 0Vޏ±#ol]SzSM{9 њ{ՐӀL>y n;: zha@H9K:>@0-&qBɆmO!c Dw"Yj qd<:fVE}G6ej8h46ԑjuT@\1E ew(9զIu4&NUϪP!j:t?E$/pxЕ 3%{ׇwN@K RHoɫu@- ~(%/AMV;@hY}@8J+}#X:% q;( 􇌙٠$g8n˽QUFU4T BNܜ=y(t+r [`0+}T'>Mf3~Chpib(lRL燐 %XnnWT<:oJ`i0IO8xB} N+9"Qhl%wIo@ }Pur;;@Fn8dN0pr쁡@y /JGgJu פ3sjPG:qga BhÐ ?[?d~pb,@ҝ=_0P-㮾q"@=~ bSPRw9I *'t/$ɟ$ZrG>Mvw fOEw7UʛS8s} 4x$ЄOiJ "23H(U1)2.GrM LX1jŽʩr /: IDATs6AH~kn rxkU8r ?T0H>k"d>ҠjmdH?Kӆk&jKXBk.\3̌@ I"ȕD|3>Gg~(Yk,N^CyҫvpiVD?N0?Op-jgbO9tA!erQ5Np+?J5ZetQ3*o3TH`֟22>0&RA8ih,eX,9^ ?gC!V< a72,vg$Wd~⼪vD7x{ EZAGLČY!u' Y8y_*/΀аSVОX5oW$5D]/rPd*B ϭr RUxuQTP1DloYn.y @q]M9S3Zje%8-)Ε0 ^T 9܉"PVdg \!YX S8ab0"t`:j GB"xi$V[#AC72pEQIG0NݔT41= 5T||2Zl8Y譼7{;X?I#}E0xp$j?kQ [UG:˨uQg'j1?{Zq* 'Dl_M(~txjS ٬֞ 9,7^ VvMueAegK'۫-b{ ^=h'"UwECqLUz-Q2zBN}2V%gP8W>'\"u$j@ɯ;̭[8UvЮC>~ ^_q;:8j y \kqCBu X[û>)H?gyAˑ,l R[@1߼ph ~$($J"v;Bh,ᴐq:[{F-P 4&gWIV|!aA)ܞQ39gp[iQ.bj[阱>`U|$j|> BInrBh ! }H#TB7g W@W)GweCmPW3TB A"6pN|F!Pdi:PGPs'le ɊNBj&ypBTj-[7H^\{8CUDSج4P.Q3|Ÿ1bHo58s Mbsg\j5䘹C3`6H#j5/)W, @FJq} }G$kEH *V#03_Pa?Z"VpZ"q|v8W BhB 3',Id'tϰese:0 PmσઈܥPaT:Ca::N#\x7+E)Vp"xmJ$z>gxp$AȐAjou.>%Գ"Ѯ7?§Uΰo8KnMlHTn:BY!W^T7{/OH""g. {$yD—S̀4jfb)DymRz-6CL*bbsED7D ǡ0&xofkǝY W vN(| 4AB<êZ+ ]@ۮօP#[TOClk2Pҟ(]q,PE\zP"{A@ҬF½"rl0nc4@ _`Ah=~ʳL_4Ud|CDQtm+Q_1~+M=JV,M`Վ10 ̣[X@^ɉ"I@.A-)N XegZ j3Fݔ+ˆ/xUN_ێ%%"4rJdF#H4`ݟf:F'E]Cȕdz `0h@Xl w~g-t-w|Ca.0u=jznOU>EL@k1$mq nh {d5:DA9N>Aue&\7 o  *^%8h:n|iwu+%uV7FGnFF?U6'^IHH hFg\mWdAog-/LQRnIV|V| .`Y"^e HFE6R3q})&!m˜I?׼Q TO{i!Lת-Q*ҺG2H'4NiSDm>B؊p)LaVD {~zj76' B҅:HmcPvaĿ u@`Yij AQ+EuX٧i 05YFrSŜlN62ۜ"N5 ;ǖ e8TqsL?liXxN*]" E1dT]Ҝ4TTsh=^VK-SP9NBHΫb&G>7٣!$Vj.Mi> HT9NcʹY04 @SH@ vP_;-vS)]b,DHB;}S+D Km3Dxi]8af8XIrs6FfV9T^UaUODit*vqTNw6~|V_ , ؏@"1a~ o&"xPI.KP lR:Qzjn}G@{ BlHlF\C)$͔DFz4n1ںl)56Cmˑ@ SOxv(<(nD.elm®O]J"wɛU)_sHyobGǮEr`*g`IЪp%$?w6prFZtncUI JJBQCe&Cx֋{r^I㐐5Y!D6T7$tܥ0HXuux#P$sqHv; <,r:O $CW:[6 E ĦtE-S{QyZ~]pސNW 1#px  ΐrQ0H-Dge7] !pCBLIhHmHԉnN+VTsF,jQH4-hHdBdڐ\R#n0TEÕ|=oCEc㨎 X)>C8I+L5 h(E/a{w`ReˡT41jk0!!JLрmνҷ ,):HBg&U턂eNe{XS7~_@Ys!RQ$ZI'B Q/+rvNa?ˑp+vP|+HkH H` F]'$suMkFm-+=r2o"Z}m$!5 lbV<噳nc&!ZWw74:<U(炍Ӏ`!^baph/0wViQ$=! 6ʘE"AZZ(ӵj(um?$~R_u#Kkn; 9-7aQ ,qM; :E0@6:BG/d!$'('W;$ u!VQ9d2we&\:@'@n!!egPPCXάFCTBU< m 1+$,`j }BT!B蔐J^˩ V: ,;UE_!eS˄!l QZiR02"u?_=VGYFFV1YL0Ӓl 6,ċ \P $g^g\xX*Xn6 e)bD o4ܞL>s(x@>TFnmht*WVU(!WH"d@ʹлTQ0C_Uڬ_|?UCB"Bޚ396^*'Fڰ`P}T[Vd9kh"iV@E-yѷ؊hetΙZL+焂Cޮ .)+F|( sL*G!):貛Oj160e+Ewv3&qP U;3DzOA "R+}q"6݊.Snի qD-*-J zEb ޥʥGأH߃r`(p8c jBN;39St+帕HAXiZn>G*P}2 m:>k<+~])Jvwn:P}d$K:vn^p+t):œdu%:Zu8Ħ_T78#ںgBO,y̬)TΨ: l- 1ZD·˩e9-Lҝq~a9TCbzgvt91 hUiwtܠ 4H#RjiAۮժU@Paf[ l槥|D4xm4t$uӫ̐hHRhANe6'eOӧ j(BFN)Sb,"Ɨ:gY̷Fpm]/o- ˉaChX Il0`"U1JC>:kJY|K;gb&?g.'d5xl}rsuЃZiNoio7tlA![u-"h۶}{nػ}gZV]-`{ -nL0je!MO96Μ:$7ԙwo#D:7sFM3LIw=EDCe& >B_#{B XmvjoVH`=.A_v qP|C-0P?UE{{{nۿ{ppm aCP yC>szUQHQ;4zD֣Q{W.%h.uA-JBuճ{=]5IQBU41ָBԼN eV wu GAq/Yyiu9' 3'W^h^ܘ`lsCFxhN2{Hz0G4#&9jRUvy֛o]_.ԮYP6 !R6t6ݾwz}抪j=ꇩO4 8(ʭm7HՔ-5LpP#' hXRv( O1$ԕZB?q`K"#xMotvtw`lcaRߘ7S>jʬ֔jsXcf*H(7vXA}6Noow8`4u"C\hqe*rm'$B Z=qΫ{wH B !h!Dhׯ?v4ˢT=㾴I2UA=ز CPԟ\:!jXlFTZ@=s6jQD?6 ID!($\ӻ| pFP'a8]0%iyO婳Uoϰ ɲO^Q؄YǬzA #΢ZkLC0<͢6 O}|wخV;woػqsO{I#qsϟ8~|L{'W.mw b;@C]) P#(kBw^Ǫ Mq5p29 TJ@'o>m狇>TF Soݦ޳du7o?K?X,e/ĶY@S[=E9ujq7v\\.i|i[o/ɓ[2G R󜫋`WkD[--`m"hZ=Lw&I hvuʵkW߿n-Z 'wp…Nm7%jbRܹcN;7oܼӶ !,sc o={ 5 8sf'y(GX9)A]D mk.\}lk-X2? GSe F^7 qdpPohj e+H"4{Nex?Ӿ}ҷTgާ¡!Dǂa`K?Zm"DSf,xISdj9Vp[|XޏQE4j ?!mjssϽWvX ݕ⑇O_|乳; _Xmm_͞md)Qhٝco,?-ԮΞ],a$:Bdti"<kAgC6'8Q*.Z!;%zKFm.ψnsIE, lu8ɜCB-EZ $1[bc*+cHLWrb3$vm0)DյQCtMYThL1XYe۷/i݉!X,⅓sj}r⩝> BW+]?wo-+C;{w ݭcǚE5݊Nue7I-u` 65r\ݕZ91SJ;bL6{MZh(? YTp׃#~в A ~wa4{-s]5R=Py0I9Wv\ƤۆžU2JW0u17~1tz-NT۷[ff-sl|v VsRhE9[jWo{|qիw@.;:{Z.o߆wwvw?\i4h lZ9/mӍ iHzx!Mel+'oXs7д2gs*ocgViIu Ďp[!5'NnܾsWT簋"n\=ybg{rjQHѨAhD\T6N,G8!D4Ԧ mzicQљ%fQ,M8휴4HLd'HɨMGr!n:/9}ٳ[[] =|ίg|A"Z.7߼>xJ4o:9dB\wƏeh[~-+p44U+c?~'PiءtI-a?^ MC;;,?mՋ{; yIŭh%|h 6AMy _xһ=Pꊭ[H^jd%RMUE<l̺' Xnj:$ĩVbɻKW':DJl>y7)MpctLqjCN2 ims_8oROskZSkeM~h TtF_ǰtzz㏟_x…SV>ȃͿy;8X3ϼ/}WVG>/~ N~S//W>@̦/ϒYG:g-#}g-go].; N>ą3g>jg@m&.͔*:eAZȂ$֎-yy lZS)` "VJ)G2eض"jj@e㝂S΃R5ncHP0K|j2`#r:#Jyk\pJxP'3o{x;}عs/|{_ҷ> ?O_<{vWi]So/^KopN{~gG_,Ip0(r6DOObʞD-я[߾tppwk Jw^<oPg8[@5IM w,+1Թ别Grg{!A Dvݶ9Dm#j:-:'"rt=Rv>@谧zE8Y_ns\{{`Pƌj"EPKg8ySekCa֘k16mg^;7wW^}*"=??#g!{駯3\t~/^}wWpίgSO{KWܹ_G?y NaѣɎ3ե`5@xo}b!gD/^8sŅ[ۘ%*j(+xc$BۮղYSLz]yP9,˭-; A$I[(!Rvö}|wI   ^rl+Ϲ J@hǪ:c3w$ 3ERQuEGkZT;B[-wԟtO|?<_s?zݝOǷo~կ}텽8ɝ;?O]|ѳ޻ E?󙇚!4}"l'5޶>/7g\,b{ӟSvV!-i]hC(T$<@\۶m[3A'TECT_`Fh? (YWBnT''mvSϩ~Y/s[>ƈ(X*jඳ>:`ͦL^)/MmddPUE5?1ˡr!NM6kKk7o#kw.q޻ϟ>;ݛ7WGwxwoKW+o3gͿ3gv+:{Y}\#fMߴd4?eoA$:O~sB u֒.n v-]DRR+aU4*A# ZEH*k;AP>%|o]*u 2 /]"t%=RWNeҥqf󕙱 1lox.S! cȠQo{_+Wmut{{\vM|H}ӧwk__gz5S}/W~=~l]B)AOu~=WowږTc?ϟD\h ~rxke2R$+J%(z'GVɭ(v "rdj2oRRgboͰixnTS* AWuaJ=,qnM*=gO_~;_{_ܣ[毞{+Wn&(WWpnvwږri4|iPc7OGf4L${`M]qK}Bz[<{r6 O\|D+:#-n G__;#5MV!PڨiW|٤QA_CnGSbב:VzNIz5}r^~e:^nF"#Y1Ƈx܈8`4tw=/T;t(hg&Ԁ{{?yUzO?OɓهoWמ~ʕ+7<'N<Й>#Ξ=Zw?{?|O;]3*GQwo_rT$@GG?߭eHU}AmeZ;Wb ۻѧT HE͵D *IC_\wftW~Cksp TZ)݃ Vcу'Ad0##R9V:(߆.bUSP71X>Ċض[W޸_~ЇΉc??3{K'8ujO\xsϟ;w Es@Gɇ>}1heL+S/ ;-?:g}m[xBZAF RI`z7D_s!5MW]k [A@Ftxd!N[=U#@RnʤCB*·2_Up< Q]FTxJ)&dOٽouqq|̙x'я>zs/:s؉ۍ={\Q={voO'|>35zut  4B /J8hm3|-i^}rGӯ`r!}+Z'duÝbCUdǨLߘ@7~2lx]a:b[uWtҵv^6ݭǷΟ?V۷_ҷ>iL:9k+%h9$N} }Kɝ/^z.5\GnW򗟹v[wO>VW ~/8L+N|+Yc{ HtJz62 q˃;5cmm+O m n8K u0s A]yhV4wn@"ĿƘi5Vb[4:ʀ|lIVHlz4*$?/}hkk!^3s{+m[moo<+b[zOe+ Ԕ~gxի7:yrSO\قqjXsSKՌâֿX4vR 6imBT7tB4 z%2?3(K=قwK9,R;wF`5jӺQ)IH-~OZ?#8ꩧ^ׯ߶}=v@T+_|Ν~O}Xg3(QsLBj-V[ݴ8eֶAjiihK,ka^<~#mQ,KoI V1HvDQGccȝӎՑJS'Uk_iQ Lښ<=n;w~»_{r1M=t~35m[z+B+x>?פ.vWZum}O}BWO opEw9x5Xc7`MMoy B  $P-܄@i 0liqkzG]_4S G? ï{M?G9?Xw?_? Mzw7)sggqp"-;߹?nt"' y{|ի׮,'?yagg1R ] =T j4_7\4iM(LQSi޻yQJ/9y_ap7 5wcká=wm9un7y;?zßc{ OdؠF8WPKb2)0 &pb5ԳhZ$I$IIP[dQ$텳^ޯ8닗Fjt>zN-AVj9yrĴ!ttwʕrO~2p媾jzi5[߳ti컴>I`nY%dTÅ`,hשVnS A!H#`(YIȄO’uC=HL|@Kȑ5A#i"esbNo\Ê"A"P)F:a oѻpJwsG?:1;+@-o1n祗Nmz{cuv=ȭK8çNw% aٳ8Bxv5ݨ>I MO7xҵ#l(bLÜ+/L<h\݆'ޑ`&nYAA K@ӒWD5l M?.d7I;ޘZx;~bi˖e߿q[.ˊz;yNeddرҒ5ܩ;C׮M;~vۚ 朤 Pak##.\/ p׮-޽2"/ѠmM8,#q  0PCy0PfL܌YjPXp1e)g$14BBu'wbd-EZ9T;D|wSӻU>N[Fm}v򓁅b.۷Cڸe˲l6} w\:֊ݻnu?˃&B]`oC0y}r^Z[s;v3=!SCd"zMdڙF voQrʀ 1sF(@(47w9Hׇ7~#IՔHr")UA-KAzħwI Cz3>^xyX \A>͞ryɰ^COixx'=*1:%ԤPz kŋ7.Q"FϫuWT AFHD\jGp,UA7V՘V&:rmUU:>i ڧ xU%jm^G  y,%3>>xc|lN4>>wT9:H- ]Wlٲ{s47gpll?<񳟝CdT'9HK7Ti{{n%MMTPOi̊Dվ$/EY =LUu N_9R0Pqn@>JMtI@(N"F NH4"Vc͌&E[Iާ=Qªp|T5wMRn;$?y~+צxkWL7 *<"ݻ%ͷͲ|dKSSǏNN*tD??6SUɔUQ2 'jkWo DިXkn*#OQ$j'òe# 1 B`D 3*c: XߍLNZň+xLrK0 `:4Yg&-f|OX7jfUQgV)pr3#hF .֢uz?[lY#{?mmz듓bPggmf}h㗾o.j=;[OO=q {{L&Iw;<<15m޴5yphR]\ycF:'1LR EwD `;p 8:S#\QM-길+"{,;"~@ z~FGg~S?qnni~ kcX*DΏBN{{m]u󥡡eZ۷9ot_<_(=i\x+{2FFfϟ# p, Ȝb2^d7f Kw.F)ٌ(D"0sPd/qFR&Z d L KY,"II.BJv_nj(<(3z ,(m~Bگ.|{GΜ+MM[u]nڶ<הH 6?Ӆyﺫ?FSS߸1ɰ{W?ЮK[ ^"> pξ?;=;AzZ,b _ͳlh9 *$F/eulٺL_gWFLKy !# =F lWHy!d(@2"U~rt $b )$C Ɋlc$Lz/ k E<@e|.2 0n4hATQS~5U#WwӼá}6 "G"02^*$(]U=Ia'=!D>  *E"#XH.fs1W_Cit1qIIυQ ]b-x{qUijERNUԣ:;_~~KSSd?)mz097.~SO{/tPօ r`vm;UNyǎ]J)bEIFUgBT^}7-]CGWrY ̈́wLq @4{zLgQ{ rI0@#|ĈBS@ó`Y$ƛXQPJxv0k=q[j>Zl\a5ۣe7(eXI:~QOz\U-š,$&PU]zZ(kCjХK7x:2hn,Y#~c[A~I!iDH@`w0n5qx(/ E,"JpZbY-k!EE? v_Hr㮍Rsb7az]{L%='H5;Kh_>3@޴kW&ҍ Mh ,׮Mڵ];w953S+Yq] |y>dr SW_P.SmKȬ lܸtnV:}@3Tz3 P Y^"zH9 :I$a hj[4N^ a & "*!3JQh!aaMYlKX/y'6)E*3 +ET菪7]qkk]O[[w{K#zLaP(_2qZZ6,z{VK>?}Ϋzuǎ<̩RaS?r?K[wSpf Xphj>:\ښLqP52D'1LB# H!čHC 1 `(᧚ m* JlDg֎5=9Iި B9WOaN݈F']\:(>:jS_3p=b/׵{G^VCTsG5HdD87I@X_lOjJbQPw&MGGzǡH}}\Yve>M_6,qO-F; MaB| tk `6,] Ey $ߎnDCrQկ0&VNh8|HN@`1!S!$a: !&@^p. Y`xZ`%=<9.&*&T&.}yz u$@Lj[J~$8H*7T65^wO.] w?)DRU쟅 47gsnZ逸N>|9 nZOl.Ը{W|[o $O?=P.뷶vu|?+r78QGg+3[D|zl2f maƍLdnf&Eyq*$i$#!"#羢qǩpXo3УRJ^EAd%I At]ߍJ#7kJ;i"!S#&!E>qs[[â~ZR o[\=׊'/ҹ'86pr$ 2v-+[oݷeϗæt h@&YreK[fMWR{۲e}꩓_4LJg=P'4Cʳ$NSFfۡHG$6NCm&P}PHz )1=r" 0 \T_ID]t-Mij,P8մd }u5഻:ݠĭ &6F(H׏; 6V=V:4E4%zapâ,!0 @g')K[` $a0u}/꥗_:?;Wdmm;{?neEWwU_UV & (=aV(lL!Z0-Cn~ssy\3*YFSQN_(E9|kp/8Dҏi &sv0D=@$F"THr =]CޕI#@*FD/,RJD 9H1EH:6An>ט@H@g<Θ#*L TQ;3BH`\!=8!Ix5EW25=ٿV*ierx_^FΦ[o]gw۷Zp LV2j 岙 ELe29Co\c:?+Wv<9e.^855]&AQ^9J**ٛdž쮻׵7Y-7"@b0J %97o# ĀB}DrBR]H!>r0^?E"^"Dpg"0CS1 F |{ᘐyI.-df/lP! *35aB'p.,o}F/ `ÉZxGR|;5xzo($U{XbbW#Foit+_^҉#/9|Ӳw襁5ȧe⫽x45 KDE Yt^5%Hx}~xOS57}#gΌ@*SS'G eWܺu9j_i,R%'0+qwm˖ӆIsX۬ { ;FJ \ PCi+7>iЮ9e9]!r&J]Cj9 N1 'U%{g6jZ*Ud3iğW7y\/^;zu =7]T.+W EK;?%Bi۰gJTnommgg~Oٳ?>m׮>9 H'i[p:~)hmڹpNXy]>LJߊReJ]Zz"Đ4!Aȉ]Đ#Γ!2cʲ _ɤ)BrFڡ`8-jܭLavҫ)JKF28;1ɽX/qO@SLœi 6띌{NHr^W-nQJ7@e /'_}T ͏fz:?00z}"|}3 EdBGdr81c`llyĒ8dM7-җn}#G\@W'xX7KGOON㍷reMK3fIVOAHׇİ9P!Iלy.n'!(]BBJ`(j Inbvٺ9;TDZTNі1 V%.Y nu:BPz}aynM5ϢOs"]O6ct^EBBէuxImh}l#Kwzt{ܶ90_zLggsWwsGGczXggS\hė.Mq/aU3~}l>=Ƅc-'تU--YS|y| rBu^tc``@Ksvξeڵ6bvR;rX2#c VI\wGPoPn BSf#J^ C,TA{B1@i$EB465$e"ArHwi^t2>Xa3񄈧xXڌ2 @_@M.;0:v qVy_C[*Tu-_jK;*2Oe.!tamn|{K2 pn_c{ξ7-%r IP@<AN<7mttx @DG\/~Vf?LNOgf Bt2J9i cdžggK,izS/Kc%9¬lrhR< E  EB@ / ! ĸPRyCV2"YvHUvf`c`P0!Tjl!Cӓauڴ=O+rT5Lt0G*$tj Eϭjg б9`5~;9 )'5?j!+X=|_I&=jjQe); N=?<~赅twǷo1i)6C<AAV> T 4D\X(=5kK'jn|c[zz~𔺷P('e MMC'OiҞ58FNhQL5$`M(b( IDATe@!AB "'f%s Y!^_7l#HƳT#`[)rJv_5l@ bW)4cd˽?;"8\rENj.==Gi}ĪT)yClp'!A}i47pkVF|7I"y䶭[RaSS 99r/[{;911zu "%~ZZw{ylZ抿ř/ˡ3f43SQQ$v&S*h)*P&}txD֜2s g1U:"#MD ؀j !FT2iRI Iv8Qk"g3舱7sէ8e.MdU"IjxR&l54O=ɰ֙Q\L^w7=7cEΟ9;7q2u9CXԖyϞU!\6ww`||.&|f3v?g%A 1Dp~vIC?r䪺馛-[&;YqÉtR~T+>`-K> Y 0u#a Qr'YNG̑sK ̐t#d[X1@< T1#BbU "1U}2hZLB%7ċ!Lp 9V8IᎶԜ)YޒEտ*. ՛Ш̞:H:j".Hy$lټ+Om_o/IVxˉqcA0#].qAڵ>x֭CuNwqkxEJʕ_]{ 3?vvh:koLza~DDKd&㢆hrC<V]OLTԙt RY0InABbD58@7b T#1B@O05=@t̶xw:@EJLS11' Kc+I}ԊȳKDb׀=Ҫ\1c#T,+Ҽ/d."nV&NMq֞ヘ߱bE;v?};miBS12鿨ܶmgT*\CcQMuLsŨ =$C^ CdaT 8sʪRj3%$WGx]uSmC(բUj$ĔvJׇx-߿0 Jkmf 9E"/vkT9rʷu+c"`Ѭn,^ҜFF۹sEKKjC izDfR'*Ff %XOR+-ĕ1 q(h@[@EIJq&1I5 4 $MTL:@j8fhEgRCԽ䶡m_M2Y$˃U@ȕ!HftһffU71Y˗ӚϗGo=љ0$6_|sswܱvξ֖k{{+-J"Ƞ=y*[u=q%gZ.Ǐ XѾvmƍKڻsAssΜݿLQE]+::$?X߿D8rdX'1`sHzāDذdNuS}QAe9G"H8VKruFk( uoHKLi֯:SNÂtȉftJ,iQVW=2{KWI̔kL'^/nPCiUŘWr *>8Tg2wNr4D>۾; s0 ܲ11X A1nmMkkTYpꜼ0<$7 gؒoHO!}YdOrC2Kɜ%pu:Doaf. $.5dʼcI $6(cz8*01I5MjR-fuy|cVJզHHV 6JšpuZCu|a&P3|9 kߴiiee (, |WDpءCN=wnB؃%uw7wyڍ{ ~_xܹqQ5޽ZD Q_3CAˈ⤆ " e' AIEĥq%7FF&4.3)D") z d`LEnn2MC2DF&]VfjLR[\F8Hhk IYI";$zYCHK@u<5\@Cjb"I zF{q#ͫaHpk2~vEi.Ka@&Ô#;΋@09 g^|SR9';'r, YMM\.hjb{.ڻ;:rͭT.W r;zzZ!{S@jCI%xi|`D!(@Ε AM jgnsXPS<[3K$2e>!8f4%ZlE+PbMf*Q5'ʫRP}K5a=`DIe>k%Tp#{ 7]=| S5z?dϗ%.1 G=|BJlutV\kݺ+:ڲx&6Qi,F` |X)Bti1n쭷fCS6m'0?]R%@' zPQ9gʤQ[=rو:J100Nl%ROh$ݎHT {W= ds%G0x qn4M5d2dnwWrǫxRcFŵocJb9شTSS3UiL@DK tܴ7aX ·dWP)}o~ 5ݴ-zuǎ}Mx`VnȹK=I'G/]RdիӡmUlܮqq$Q I=M}~'Cגͯ B(A rdH0\5HjO6U3x{]I'kZt$Ł"TrDl9^i.Y:j'r`lW]қ*$ɬ61IXCtp+@n*A8<y$WK ,iY)~*B) C (%21rԷIYܲewKۤs"- fYH)SMnkÊMo5ϗM7vt4KR{h1YaOuPz꩓׮ͨ[|߸P(75gҾZR1,|,sCTM0?yrȑ+}/K[ 7'P"gCcIM7޸4?_K|7/JXP$p*G&H76C I&S ` T#_kYkR* +.(zZ'KM"mdtO!镐sOAHY 6CspʰX9;=C q&Z\YALbE5wVdTq^NSȤǕj'\GŠ ߬9_aaCrXo{^LLETƬ RBId2, I@b nc?}VELc. N#kddKJiL&aY\Wb̋tP2&`#r1D(ȅ#~*`tސ TU# %C}=ȔRU$`^0H6>Vi  <騬t$uQb61+@ۮ$C2RtU(C|^. a\l" zۨn[ҙR*xVlz|ԄCj&ХL5kצ5w]OGmM O6x#T &\ Ζ2իCC7x M˖9S5Nsәdo場!"mڴl.c3ɛi7 ViHf1h8&@3 Ce3 Yi UJcQBͧL769N mX@ză 7f2:ȫQ2ǁw K$&(]5ׄ57+mt!S.35)#dRnS." lkKnO}j?uo|cXѱc{o&,vkH~.R1,<ۛO|d yM@5^HQRD=@ Ir*=A!!c^#U O\v(TH&thR[(b@jucXURAjv]fN=1"UnZ!ߴy󒶶܆ =MM×_xlDktm[kHKaQ!lnX/G JX"p[6PRqۼƥ/Y~jBR<;0ۑL@c Iҍ@*`_,62!z omuT )1ց"F FA"0nBTT;&`LH(W com&e٦*գ4`0SgU3%⛳Jf䠈E޻GFf~c&3w0Sgljr8Ƣ`ii9>*|j(sD@d߿9690 ":%m9yx.衫 %#mը#dI:&h'k&8U4~4~+=莚Fkc)x'ub ԙ[V0Bsg~`RggӇ? =o2qf-uNrl6(Ñ7qE`5\pSr~[{+hutT~3) 4OFF'Syğb*{ߕp0 )n@v^w$OoHH K!2D&l$L <_G.wi@P<|$0* :*[ "8>`<l^`I Cd( 7p+!a_xHLROP[IýqWՏH@Uɹ/'b)4tsU9ts.!b>qɒ"\Hbb>{{y.~ff'OLMA[ v~ WC;9X3<梯}eP9[o&rV IDATEMa["〓I_߄hYS}BD>Ktd qW|u̎T=4W}02z(ը`UQ5ϸ\P-ԌC,q u צ@~p7l ?əﱉ + ) 9(qMaCϞ=ʕrOqhxx [,fgsHNPVorf,k5NdrGtF&|c9CO@i&`?(`l-g!&.ϙx^j6!SCm6ޝNأWM1Vb,ZJ 䀸XJ3d0>:aO+$!WUjn4+my'q(X\BSDW;밪=H{g~v*Yr800rh]%XwDaYВܑ;*0x`;clvpթ B.["reʕi뗬^4jr EncZD9DK| %*XQTKP3Ţp\%āV棘d;L2$4UAr 6'vx){<|XAL%}|؟/{[[ lܜ!:>q1s>oٙ~֭uDp YiD9.ƭ}֖ۺuYGG9$1|l\uVO0Tɖؼ"G4k-K9zW)4PE QM Z `*.5]#MT*F.Tu 2O㷢;&بv`tB295.bL*zS €N%C#%, @j]l@HI͊vA5F4NJKbkab׮ݳꑯяmiif3-7I{%a;, >*Jt[Z[s33^*ÄRmrW3* %[,3S]ׯ+Bi3C6M(RiDA)+:A BZLfO HfG4FQ1΂7;U8@;&Iʧڕ&r1 `t?Z,5]0x~聚xW= MG*&CILUIJT5ld!1ۅd麺[''7\޸q>-4Q⿐Oh`}Æ;W+t8R^T<9~bllNdժU:}Q, EN? K {1U~0 'FJ" *qHfE,a@0&ǂ^kBIAAJc)NAfR"YCPkhMW6N)%P?%.|jEdxH˥*L d(aIXMOV},q(27X)*{{ot?xڵlݱn]OR0$STᰎr{pll7E]fcÞUQ6教L`K^H,,m6idjq͟ @*T.hnd)Zu5 S|r栋CA'ۈҔmCP@h2C"Ϥ;ZʬfOhqWwb #;x&W 8b_I脍U*5ɦ7DoOֆ)>0jK;0{;`(wǯ!z#?2%*-.ScB-+r^'%${cVK|XRW<9 ޳J UQ0m4KȾ+:3g:,NEovbK;wuP y"˛`CFjKLit. @ a.7ͣ:gC#h r*C,]"B2B=mrk |ScyT @q4PK'l%2DP =ͪ^2Dz%L9j(W35ԉCPQЇT4!80T.jK1 L_%p|z"~mC7P"UooG__2L鿢<|#bҡCWtB>?"?\1][ f}`%7R#{ *"Ɯ0<_Z f0)#-d6]D7nؾ]?1f#wB'%Eg$6&  ٪=X߅GXZre!s2^ APeiŧ~g6 HbF\  ?酅z987FƐI.jєn{gF\{{]\P,O_6㪓|ybIEռqR3GN$!2Đn$ AI܅HrI2MC=YUF*-81O cQI̊ A',p9Ud)^ϵG5NSP#cEz 9XGx űrQ TtgmHZMH%zaE*$*yl\rS.Ѽvm(%^`N&dL )g<9" 7! ݨX׍vư%$SFoXP;ټyiKK6D&+2*9k_Ehs70g$ˉj?1?2s%`f%n70|Anyr"E f Q2wHgwfhqnC҂@JPz;a=%jP6n8L*u)z`;;ӣ@hi;ػuA=F21i;߹-/YP̣" ).eA&Hݹv" 86tv6ύ]pW0fd)sҿ.H̃;G@e܅`2YfhFq+b)=1w[GMt0ȑ^4Y)%č %EPCT(ʁ :ێ"E/g!)RPL@88Lsy&cCEcB2Ơb1AKq}EpM0p 5f | L]?ό_|粹2a]|GI0aL#" C>d/wG[}Ѝb[[.:UHA;|\\1\O&! @Sk=2OMXB`“o)(U2|Zt 9 Wcd'5 f_{YD=~xb ~n#GMIt8FmVaqš* Wb& J@JdQb kպ1%q8jzU9%6*{yͯ[5i>g9ub|`&d2 I~jgT+c}{/@CC''x/CC7\R]-Ui?M 5KJCDgEf\ f2w0JLULiP~%5.fS1T2)] J,--4_ώ*A2Lm>ͼfSzzB^GuEJ]!ږ%LqIcB1/i-z]QsPCӰV~% KB婿^yBXOܔ$]f7\sgcT nLL̯Y D &-93>7WT/8;7ngDh;;G))7N|t늅( G` zd1[m ފr2pnVYL'&@3;!;3XQIe p"bU-%$$xqd(wbƝ%){T ˡ@>( ?.0!oERhj: ŲclDr)aXJ7/==|o8%f)ыܱcc3tt4%ԱcX9fxU N핑(y|E @w@'VO_ˠWU*cUa~[$V*mnLXn 1}v@bu9ky!!T*0PTwWPu{WCnQ!{{I2ɀʃ {{[Z2T<^Cf刐BE%h}F;Jsg__FRE;\244t)/YҺjUW?* ّۖ(dmjFX +F2(׹(eL`| qq@myEi(G(IH&E<GS3„#-/866/wIhG[7|gn-،j&$!6&TOj<CfB̓VFbqbE:z7J%2-͙ 6ƦWLe |xLL-俟:5&+@!bIAmmM-/"67F{*C͙w̻ˢRN hM3s ,@c1AE fTC=U4E MBlO2Ec=~׃z)Ī^Q,2XMe(> 9/a\lcգLC;hO(Dՠzluލ".om.5{£zuک0uu5ww7ǘ*ɅS%~2Y UBHEwHmfb<<<3<:H{g;V'b3Aވ }(8QU%@"AQ%A=d:=inrPt_[zbT[(ƣÙBg=sK\#@djn9JP1~m>MC^uX1Z6lX2U_wĸ[,O~>|%5['ͻP(¹'F$I"Gm3W3ّqz戔X Vaמ`imR1[H8 U%0Om?yph&Ep{Z$ EUt=D/:%'$fhתP¥p:V[meV(pRU)U5pZQ"%IJ?b9rرk}/c6 fgis ג`Қ4XN*yU =9~nBUH%W9T u HАQC 6j:ߥ+DU5&`zj7.e>ىg=3?_jiɮY-¶!ܨwH7bDhmr,LJ#e"x׿Rt῔3Ϝt醱/1i:M4R,g`50*R8m=wgB~l*l3 ֙NdIJI;%y 3"|767]`NK%C*a\l ?bLyd2rDU[tH;@̝wyWoF w>-h'Ej?5؉ ?D`@Hf߾cKY[.`-7߼6<ok(sNm`3=dg E iFd9 HUt d`~N#`ix0d,Qe+@؞HÞh+]E.y4Ԅ)yiC)iwym 5 J5Hm[(.o4^>xJWw=xƍK+CFLpGw\p“O{ٙ\P(:=TF`ΟQ EXlUolh$˝3¨fHk\~c%|rJpl@(1JZKLh 2= BQowQ+daJVH `-˩S֍"wmAb1\nɪ՝b b D@5sLul0Csg &GiS)P[`-Kwߦ\S2%R4ޙ#Jƌ;=A<"=}KJMbˬEHXz{]EA\[+NLJK`%XqSUBdWT&CX] @[ X<9(1jI]. T@000Ҟnuͻ{Z\ l>r H7{eCF8{vɑ|56#E@Qss~e].B\2dN9h= Wj'[g0U#k]0Z1@ IBzhČZl&POr%+XːLRU鰆(Ίġ  PIf3TK?JC.:tޏ}| nP"&dL}(aܳo IDATփ1dS\"'QTyiOPGM0GA6~SKz l9GAH4!Z;BqU}/Vp:T#2"// UV$+EmgvdD;(PdQ"c#*A~}0T[tr!sAK}lSCKhP2# NHV*z"Cn _E瘨NU* Cg+ޥDt N?>L!1lг\a[o]mdVw*ҝm@:r5!Fm߶ĉɹ]tbI} ɲ͛sY̽P\X( ͔a}ի;2eGL)59e#=AF h&J0#G3&m=Ҩp?.j%Ww8SB}(#56Jw`URR0>jw5g!8TIIeP" 9HTXgg !Qww=o)ZӽM|MVwNB},iA&dx-mwy`vcG~ ݷϓni0 @X~O>y< Pqү|{i 6rk?QȉA&^(I֊4dBN6XM7r|ApKӨp)iPzI]T;*P|it&НRWpT5"Ib L5}Wpɶ8JzT-%u@d, ou͟=-͙}lC uɟܵvmġޛq]gfVf־ލN HNIEْ,ۚEPDh"y31e~,HJHepI$@@յzYU˽7ofU7@TWef+9W]!FxNj[*)_ľ}'Ο_C[nes2)øŭ[,I/>zѰ B!]c@'N&L\p4tE#ZiBrH;'ֺR4P5 pHL M 袭!VwQ!DlJB܈9"BXOJ^0N!Zn&gh9}:6)#Eab/C~:hԵ:G?{.;9Lxc0sp@(j߳ukap0u\ J<&}ç`E94f;N+wu׍]|D Q@sȶu~g,fr#OէQVN[`I؊pm~Ah7NXҁ2ğCܠrޟX`VDzS9<8ORO.oy5<.{PPrS;9сr6 PB˚,Apx!A@yORHл}w6۹ܰUUNoS*i V~i2~۳'>x~\/9=6Bp4jS5Fy\eo~f $]h[W&qƅI#cD g0Det\MYem8]XAvF0g0o?}NLd?:jOg ;|/g&HP* >-RI\*E"}@g_X'S)AUT9::P{%s}z䏍D׉1g 0B OέU UEμN?A/U!apAr0V1(㱳PZM/s'N,ɟܵ{0+FL@yiȉQ'}F*%ybCÉ :֭EpiMrpVVBM Ux ''sCN&Lo{s,-)tv @I I;L$=|bB)95;[ajBط{8elv,5oVA9@lh7z QNș p;[/>w"PfʊH|9ُ( YشVN\QӐ"@J<`%/' ȫ&EEO8(oq6 qc͓ML/XMQ7z~qC!kG+qު@a23q UQ V|_ ˡN`f޸:i`=)CS5w=i{|p2)W\ަ|䔲iX8PgcHQ$;/$bg Ed ۶J ϠU"O慎Fr L}<ջ.czBDc" B'XDUe,T0Xs3Eb30457G7]Q%񁯼`Y7?zm&pqu7d4[s$p7(bhv9 ڷ;tRJ#&~B#"a5o8CcOVok( Cfhi:?7gGjE%p=ۢZZ3*=]%2 #,;&ؼ9ķuknu3ȇg*" --GkD\|`j5"1&ؾøS8`QH ZH O||LZR5pSm!RJ@OE3Yŭ !4oz(̇-`Ih/8525\.Ts(u{sU [T[ 7ܰ)& DR9[LO_*fQd(Vr0Z.'q9/#\%MƔ“Dy9Q(zJhr,Di7bFG%!qfP Cr& 2Hnun8=:o f$!`j'͵} (s4T3.&O(5^xc1!|f~,['K<8hXM\ak'@lU70[!o^H1,̲V/pxڜU4]WvO` 660avĔN+bۙĘBtKCΡidDaXA1IlQsjB=-UGBƬ WD@@AP[_c坼PB,,rS E4(bz9O(V{pHhk^ h1 i ΁$RPT!CkPf1DEaN^.&^E}9 Ӡ!R*wY1m'Y`J?T"V%"~$ϝD (8L}X!y8C@V"~`BP[ = . = psBD$JEէOΜY ||p % b qE,i+\W^.eY1c~ Eh5@=xSmDe/ADpx!쨈39k'2z0գK{ӆ *X )|DVE'S `(!]LIR)E^4@Ӭ٪[, 7H,[jNe|9!`r*EnٯL-E yPl2mǦSeBAVD:s0{xg"Za=k!Lv ۜ܌Y*nb b)Nrn; TC>BԲi5+_yy)!ߘ >fji?EJd:Bna cQc1uzCCЀ<3 X=gѳ.>NaqL͒ndv>G Sp4=i'BUZ3AZ⎃j4]@9qTx7@E I.EPz8{lY:ur[z-g`f0:-{4 \0M~V} DQz9*x9l0m3FM#PXh!1i? דheX0q=iDAME@Kgg dm HCSS+l ]7_ĝ7DЬMvzX{B\%*_[o-9[j6u A;s+k0躩i&H V$9'KJ :Su۝t"<9:XPНJ2D HڜۼߢbOCJJPrpm@I/BQ~]=k1 {o5K-E1 Pd趁79u g#땃O5N/M}0DTe;Ѥ ȵ{hrʦWf&f+B,~eTV=41to5-UΘ\U#"9I'`־ah}r9ډ8#1B"IӢq[u̲+(- O`b1i剀" - @,&V|}lDZ"#O$~Q)r4m0H(W mVXF 8 =J8#́;#P!RJGwx\Hp~33U#<7W#x9P\rGEam(IUn5z\PLd#FH'!8hmS)f;?GmӕB &g+ܼ8ZA&Uqy3sjUkY䥔DRx #K"M@fjC( lL(TŏDlkeAHH]d+cȪʆzY7(B hk ȸ92/;azkJ-pr Ei5-mQ2Yig!aqQjl6[ѵ~zxl&P4 dDŽnl{,؁b#IQgh8p qh;(Tn< PZ4nn6׾vॗηQ@i^wD. W :ͦnL&N8!Lh4t ˱-wˑ@+߄_K{a"H re8|N.>pUH c Zp=! ١JJt{!F! t9xGE]Bȗ1L,i?= &#) }f$ }#ukU^_CZE?(mh!ɔ,K"s>M}iaZ9%es9ң+ג(G\kk'\P@@ʺohi $]khzR"sqjj'B> _[+6 a{Wi '`T, pSDBD F?T7ְz H!@HBPH83rz[-٪RB'U֝/< o{nuR#z≣[ xDBr| v4qm Umq1Ys$p9#O+8 $ev ,o$(sVch EZIbAP[+p  !Iz0ݕ6RY>9,tp(](.©0kp0o/|sr׮!G!? {ek A >"0߰{f.!L ߠ@-r5t&w9"U)Y&pf0m$rR4ٌe%c|E!Nѧ",eP3 >u!HrTpw&!S`^,&]n8cO>xt!P($Ym>?Ui6 @stѺh7 G0{u2 &$Zo1(:+|(P] B~՞Lw gFNf5BnBUwB0&0r> z=;Ν9y ioS>G0Ʈ #b!>Uj8vt>T@hb"˘Mq!UJǏhD)YzWr\6ۜۘPݸ*vUedpR? k n D4~^8X%gF"rt ![co>d?$¶^bۥަFo~" +HF(c\WXS(b(9]MNp|`ǏNkF0(H?Z"@-R\!h=A( ^7O|x\bRf 4Ywy2 f3{ IDAT˪Bc1a"Y}N z|-+(4!Vj78)Tұq`yߌ0)8\`".(a0 nFKݲ"jm8 G?43x˲]ܲ6.jwMw:ԪmdbJ{ oVkq4K W-\7'q-@q (L&^Rc)0c-)͸fkoBUVpr4 *;܁ 1{٥:ӟGoV|{vQ-ئ;_-(l/fX5<8UW!IJQ`7; \z9PT,X 'X OX18( !mln6:3e={FvP9l9! qJDixl!@, W\ FA:J$[VBMڅX#A B@ɭ*@SUk!~.^e!gB7s}sW^9O<8q{/O'>+c@aAKiਪ{@b ٳˋmGDBܻlǣ~s!$΃(zNN>Q@+gh?rI&koG;;8io[?zzvso]\$W;[y_ߣ@ڙpevCɡ99 B:':lxC{f!l(8'˱+J&' {P4 Xϊԩ6-܎`:IS_c01!}@6wqTb&]EA#$wDN O1$ZSL(˒:!|*FtV)q|GHDL?윍>DrЊ:HN?ŕgI/ 3]Lڄ ![`5͈gTԗ^:;v JW4I, g¢ivr+放A OGttiiaXLĘ@%vyB4=O 3):ݵŞ$>O:LqƏ DہҌ|3$pB/L b.B~Y5B@ @HC QX>C b_ީSK޾tt7l$dYGɥJE}&' $z&;B*P[(WZn+ \&gNDmV؝jc | o8O&@.SQcIbt; } j[+@֨k !N)"@ftD8mČWgMMK(+FKY#{%*VpU..k q9es>V\3`JvѻjbI@! bG ?oC8Fw"rQtrkXw!D_ĥz1148q7ZM %o|c_Q2)O=0m!$E@LMU/&u68zߩʰF@=i@eBT܁[U!jt7*bO'@~uyȵv[yvOㄴ~8(|='[Sgq !bW,x.8 $.J-S#~뷮ԧnoLz\cã(¾E40v&.܆ du3˥}pzbJYnl2y:XeX꟞D ~xqOCc Fl&% xtwnϟGkM?QY30 sNF[)pPQIަ?Ʋ!PؕW(qA6 WH":j;zę;Suzc>QsUVgm%GʭA)B=9DDQrI݀1>|xk`jfXo4{DQx,Z+zL@o-+4G6>O9`ׄ)>ґ]Qd>`Q~juϟ91BW '2qxcF:Y8T'HbAl3UU0 `FYd(SQX {Mc&E4j躥릦fPr\VyOX^n../)Aȃ"FˌfSemk-[ +p"pƸvƀp{9F`1W݉3ynXces~"B4Q4pzi{nG6SO* ਅ#""p Ia6 ;;<˶V!A(}!l33bTjT*jUjjZ=SFeneiZnYewXQV뵚f]y9…/CC~/xܹ'Umd`0Ƃ<-c0)X\Ӻ0_yREˇ[mఉЋF;FKE@N1tJLAw(LJ0,kc#a\ x+\0鸵X1.Ӵff:4{ѣϗu]-0 2Mlibjnx(*)W\;Rg>s}g>C2>\yӧK CCI&f#rܚoqhiojC0:_KC9ۯ_ BQ]M.s~gb:r7Fep.l*#ƙ! h](D'k(^EBճ4RQkV\rtFѣVWw,SѾ!ˢ.M9kEljEh~ {_s͘[=t/۷CC) f9S[Vg-OConCBW_5zd.W;G)29U2lK,geQB%Xf lEf?\L"F0^ =G J dt!T*5fg㋇Ϟ>]:{v̙eqs6QI)3%v& b1Y,&D(KCNASI6r:oa~U#mKw+!}Qxuۮn֍? ۝ J‡>tĂmhCq)PrX5GnxJ(p*D~PĴaWw ] .W$}xsqB @[KKٳ'O.âi%iطS)9tz9_iEQDD.u)sS+xaZRǏJdR:wnoo|*942 c؟BKϯ<0Bkoi-ʱQ4.hɓXÌЇD\PrVz9) x $1($,J $J(IB( aKCxjESO/XV~u?B`H3L!="1Ur[Gojiѥ?;eYքs,%6H#r $U5DyP`Bop -w Gr@HhOVE`lՙFC;WiΕϝ[>{vRQmeaZQlHF*6''s]6s֭ɼD 5oZa}ٛ f`_}uzfj9E^xnϞbEG Bز0ak;Y^?sf2~+wM|r!0=…]叄0;A9fWi:KCPpFEB!E*pp&m\8NqI ê׵zݬVZMVuZUU[-muʥR53&Ib6d2J.NLd''󣣙hfx8=4JeE>6 6ұO+n=ԉ}N?H۷+R)Y=9K1qg%<) {2~h0b0olRp(CxΒȑ?!ZHe! 8d0;XT*vۦT/vgc~^ݠS.7v.7B6 Sb198 R##;z[|΀G2)=kn}71N$nےHH ( t]^ڱ[K/ȑ<\ LF~v_y@X8@: i@\uA.@y@8toç Y85QQB8U.kKKlun>?_Uk5^כMݾa;4R5MhBol|t4=4J 2cct.OtHW>ᶡ#(?k~Ӳ lVI$z]SJG9pۯtv˵r9x#A(yD\z`OQTט D k8+C_Jͮ]_za1H D\ !uq^Xݞ v΍YrYhVOmvZ*n&uc(`a|0 \u]taHSUX̦MXvt4N+$u~X ]ZC=XD`$r")d2J6׵JE^Z B0XA 幹Z*%MN E\m(/ڿ\듌Ν?U(&cn!c)P]q87OA5pGBam9p=WRd|8\8chk5l”fh4jU=[>wl_ZͦIHt+ 'KDQLf2ETX.Jwgvfx8=<7*m-fL'd.|_Fޫ&E`y͹)sь./tϟ8pβ|m߾S_?Jɴde^NMn6//7ܝ(~wܽuf cǮ4Uv* HUa \BNDy)xʕ)b jlMըTCj:?_?wnyn67W./vcD<~rl` 94uhÙT>L5UVgjj|ܰ}{gNA$I ˢHBb|<;>oڔώf4B_ >Yj[@`B EQ,>G.|e͹J(ΏJv}N&ͯeۨ>[:koysxi)W*_*)lR dn;ZMGKi , R[+,ՅLuj2=S-.uvC@I)I9i9  CCiv[&[!׸>7&IĆ'N,&MLFմO?IԐ$)FI͵C?'Ξ]4Ӊw_=;QBaUNUD'\n3׮D]ٻKF0Yv&^"wq/ R(-7Kf(b\Vuo#c|բ((q)FEx.lc֙%lNEbBm#@_sS`ͦqTɲ/ۿ\"!)릪'G{}n>[z{'1Fa8Gg6ݷBͪ4M]pCSf#$6aCfx`,2HꡀP@ܴ}hf3|RњMQMԛM4,{h &dY٬3i9RI9%))x<IbFEAA@.?NDksǛ :]WqTRQBcmt:5LX/*6@av "XIj̲sv@ v( =vlA;AѳϞ~啩oܴwpZQbb}vzó@>D7gLЦa2xtp`L|<);9 )D ڹUTuky^)Z.7KrYUjMVT{8Mj5F+AIKcm FgK6e|ط=ch65'u,xu Rf1oAMn[P4߄cX}QԮUd%5<.bGXZ/,닋zԨTz]׵zMִzM 0%cLi%PHB!Y,&RbXHخLJLHɤ(RK8sXx  B@@ o-nnVܲ%ߑb , ^ziСivβ@U-]vQM M1Q6Ow8htmwUv .U^_m`TRs4lDp p=0ͦa;:T窳stZSM]7u놩 &jWb1!_H^!pjh(=0d[ HXZ0x*[-!ЅPc,,:"g@EΕr.NOLd3ccXFQąڿ|ij 4u oD-]J #9:4OZkinb}v6?_ff*sZMuBB$J(ɲ(b& FG3CC顡pfd$=0$y~֒@ 1\\ _Z'dlGTa hd$wDf®]C۶3xd$s#ժ/=g.]iI j:6_*҃IE291C(ݢք, hͦh^iKK=TjJr^׉g%Ex,>tZI&dJN|!Q($D>(犝?{a'uK Z@ dd(ϡu@Ӳ^8nq'?y7O $c1?'nyi:zͦHW0ĠnXQ\ 9qL(eJ"& \VZU5ZUۢVu0l5UZ뺦" 5RLf|>10*ݧdTZNTJΤ[㊻orO9I4w?AHEj>fE5/,/7;})?{oabFsqe` qb3gKjn+64-v {I##ّPzd$3:)vHJ<ȭTK]51;JM pKZ(};'s, ;uY?[fLWMl6ra놪AF((Nu#iӻ|,$ |giZv%ОioZV6=]LOWriU0!1X/$ <2&&b1 y!A$Mkn @T@!=кfgWOjxܐ$F 7Lu D[מѺB!R4O4 C{h6; a64MCU[2jYr4AvҬQ 0juRV뵪= ߃EQH$bH6 ɞ6<L $SCC\.[WXQgZ%^kA}Ͳ7ʛo ))w]ys ЅN+x!% ؈/T"8;3R FɷyZhE#FXZ/-5jMVZU׵jM՚VjVՊZiaVppKZhO<.SJ*%'Sr*)r*)'R*%sl.ƳYm$sF*!g)~$E=:Vjm,f3fw޹ 1f^%1Qؗl4-QhG lQ7PjES.x 5mfztuz23]YXjZ5ewb&f(wcbd D(Br`0irdvrLQD{,&l"CiR8PpZ: K A}]uq0u۪nv  k5kk$ jk5U5Hf׮$ttHZ.p^cla cijՙLef:=UV*UMMC7uòmRZ:A@A: PL B!Y(mAZL )&"EQXfB=bjVm0kAȮ XS 79tl=t uG>r, o+PJ8+ienng=sC*%O$I"-? g瀞Fnj4jlcT*|mnjgn67W]X+#&`;ZqI\+1YipN RCCb2jQ^"Ga> ? 8D8Vha$+[Cl?W^9hn~SѮ53 oHЈbfjRi4JETJY^n.-5ͥRTj,-5uݟD_~<$LlVNtZNlVd|>QlVEs)EF,@@E@z/}]|Tw슝]wmm%T#h]$$SD"O 9?_%BlԺGL%RsiToZivZUmӴȆDs7:s3 d(Bb` U,& x&RrșJIRaG6-a;eۈ9F8=zJ-< ݮTW('8z"񡫯}yz2@cC$s$N$KT\Zj2 t cnjΦ+\Tji{ikiVޙ 8sbDz% HH6 l9Rs Jjs*8E XώOե;BOkA$9tm 6G9tqnj|Ka_|c<2Nd{LL&.2@ :Gt3t'00,{D,=Aaa4RQ33\uf:;[V*jIV7cZWʵ])4'b, I%IPXKgGG2DF;4d3K&N>@;˰HSYY,aߺ zE GNq}YvCoIg=< \.>4N]yȇ?|M[m5+&I/+\\EM@ZJ ya6?i4=Z;'h1%R*ʕ%S<8(&ɡ`*_+rd7G0D3<->, <EEݼXI ߅.7ð>?hEu7|۷;c @0'8}ýD`j?Rx<11 RQfz Z^c2HDl9@XLrh\Pj: G?\*CDB:U:}DHH3ɝ( S##P*U )x\J$bDLDĦ 9 80Bu z%U[k? 4.0 (aPC$)wrE\whYq]4TzS?_< 7dDٽmIR)yx8m;όGG3iE"E$v#'5re2ɔ2A"oXb k.ea.-z˞n )r~R@}mMUPg` iRC/tn߾#F5{î F%LJJIɤHrhz|661Kδ!W?uY.7O\zj I%˦,gξ  XL\.^(y{gXLjb"ϛ8∃=$K>km:hL kt[c~)ho}B'>/>z=9&X-YGHx .)㱡pzd$=6N x&d2J*%J&#'cz3(溇gPwRxCN0؇NG Y?uB{tufkۡC{?X{"e+4ۦ0<ڶiS E$QE70BրF)ؤV)-D x,z@ hKiC3>ܹrN vLɤ44oْ۾=}{zb"=2eѽ`n `C*m8-袼@ !ޔHlp}]b[?nN"Pzl,31ݺk]C[GGɤ3`L{Q`bOWK,NB\QrGrxԓVN@ @pгO>h왘]v×]6iS~ӦM}tfۡf>ϳa* T8<RUDgj{ksrM O~*:S/p'4<|t4s5c{3rU#W]5JkIO @oٻP4Վ̯mDz' zH @髱lO}3gJΕU[IX۷q֫ݺ06Y[i:!~B dUOU;I+j5!-Cϡ auݪV'|}.,+U(IxoL&n[?? 2uQz]R(x޽k̘n*ꭀ?@!H!uO>6VkW|[LMU83(<2ٶxw;j4_yjrd1:)@;w ˅B޿K@vxߒϡ &*<83~V5mVڱnEܽf'3 `zW{[܅BZQL Է%shcnj],QSDHPdϡ JW7j⊡Ő @jx-["DaRYe5TshRrQg.C_, //7_7>g- J%&&ܳ7~㚽{%vG?<[ǰhLaȴãTP*@BmXiy+L=؛k< $wwk=, R'l'שh;uh=U!nDU9igۉϕJC%{޶'n|ǎEīhא^)@?:OʅJ7qC+j@8TkO=u|?h聇Ruه>kƷn-r$ f!$ZoOw^N =U@mr4ZMO™ZMcB(o>uTJžMobm'ucRW.^3n$ԋ}sC߂6& :ss|?bYx+G]wM9F7!|\f zbLX۸:qbG?zG=rYe,IΝݶ~wcpl6.r]DBϽ{>oCg.=_L!t[+o}UWr~ @2۳ z׻6Z yl lO8TO/U+@w޹~;غO-l&i2R'96BH"uC;O8htEIDATo1=G{R-wo{\KzSF^SI=!\,Rڤھ;R]Z=o/>{+?;7^TAq",? |M'V;k;.a5ƁOש|m[>ٷqǖTJ .r,LHRo# sHP/FЙ3+;woZmsߵv933 ]$ݯ}{Yo w.<ֶ[| &55щG*`a 2#\FIENDB`ejabberd-2.1.11/doc/release_notes_2.1.1.txt0000664000000000000000000000300712240230175015073 0ustar Release Notes ejabberd 2.1.1 ejabberd 2.1.1 is the first bugfix release in ejabberd 2.1.x branch. ejabberd 2.1.1 includes several important bugfixes. More details of those fixes can be retrieved from: http://redir.process-one.net/ejabberd-2.1.1 The new code can be downloaded from ejabberd download page: http://www.process-one.net/en/ejabberd/ The changes are: * Core - Call ejabberd_router:route/3 instead of sending a message - Can't connect if starttls_required and zlib are set - Routes vCard request to the occupant full JID, but should to bare JID - S2S: fix allow_host/2 on subdomains. added hook s2s_allow_host * MUC - Support converting one-to-one chat to MUC - Add support for serving a Unique Room Name * Publish Subscribe - Receive same last published PEP items at reconnect if several resources online - Typo in mod_pubsub_odbc breaks Service Discovery and more * Web - Fix memory and port leak when TLS is enabled in HTTP - WebAdmin doesn't report correct last activity with postgresql backend - Option to define custom HTTP headers in mod_http_fileserver - Show informative webpage when browsing the HTTP-Poll page * Other - Change captcha.sh to not depend on bash - Generate main XML file also when exporting only a vhost - Fix last newline in ejabberdctl result - Guide: fix -setcookie, mod_pubsub_odbc host, content_types Bug reports You can officially report bugs on ProcessOne support site: http://support.process-one.net/ ejabberd-2.1.11/doc/release_notes_0.9.1.txt0000664000000000000000000000302012240230175015074 0ustar Release notes ejabberd 0.9.1 This document describes the main changes from [25]ejabberd 0.9. The code can be downloaded from the [26]download page. For more detailed information, please refer to ejabberd [27]User Guide. Groupchat (Multi-user chat and IRC) improvements The multi-user chat code has been improved to comply with the latest version of Jabber Enhancement Proposal 0045. The IRC (Internet Relay Chat) features now support WHOIS and USERINFO requests. Web interface ejabberd modules management features have been added to the web interface. They now allow to start or stop extension module without restarting the ejabberd server. Publish and subscribe It is now possible to a subscribe node with a JabberID that includes a resource. Translations A new script has been included to help translate ejabberd into new languages and maintain existing translations. As a result, ejabberd is now translating into 10 languages: * Dutch * English * French * German * Polish * Portuguese * Russian * Spanish * Swedish * Ukrainian Migration No changes have been made to the database. No particular conversion steps are needed. However, you should backup your database before upgrading to a new ejabberd version. Bugfixes This release contains several bugfixes and architectural changes. Please refer to the Changelog file supplied with this release for details of all improvements in the ejabberd code. ejabberd-2.1.11/doc/release_notes_1.1.0.txt0000664000000000000000000000715612240230175015102 0ustar Release Notes ejabberd 1.1.0 24 April 2006 This document describes the main changes in ejabberd 1.1.0. This version introduce new features including support for new Jabber Enhancement Proposals and several performance improvements enabling deployments on an even larger scale than already possible. ejabberd can be downloaded from the Process-one website: http://www.process-one.net/en/projects/ejabberd/ Detailed information can be found in the ejabberd Feature Sheet and User Guide which are available on the Process-one website: http://www.process-one.net/en/projects/ejabberd/docs.html A complete list of changes is available from: http://support.process-one.net/secure/ReleaseNote.jspa?projectId=10011&styleName=Html&version=10025 Recent changes include: New Jabber Enhancement Proposal support: - JEP-0050: Ad-Hoc Commands. - JEP-0138: Stream Compression. - JEP-0175: SASL anonymous. Anonymous login - SASL anonymous. - Anonymous login for clients that do not yet support SASL Anonymous. Relational database Support - MySQL is now fully supported through ODBC and in native mode. - Various improvements to the native database interfaces. - The migration tool can use relational databases. Multi-User Chat improvements - Logging of room discussion to text file is now supported. - Better reconfiguration support. - Security oriented fixes. - Several improvements and updates to latest JEP-0045. Performance scalability improvements for large clusters - Improved session synchronisation management between cluster nodes. - Internal architecture has been reworked to use generalize Erlang/OTP framework usage. - Speed improvement on logger. - TCP/IP packet reception change for better network throttling and regulation. As a result, these improvements will reduce load on large scale deployments. XMPP Protocol related improvements - XML stanza size can be limited. - Messages are send to all resources with the same highest priority. Documentation and Internationalization - Documentation has been extended to cover more topics. - Translations have been updated. Web interface - XHTML 1.0 compliance. Bugfixes - This release contains many bugfixes on various areas such as Publish-Subscribe, build chain, installers, IRC gateway, ejabberdctl, amongst others. - Please refer to the ChangeLog file supplied with this release regarding all improvements in ejabberd. Installation Notes Supported Erlang Version - You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.0. Installation Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC. Installers can be retrieved from: http://www.process-one.net/en/projects/ejabberd/download.html Migration Notes - Before any migration, ejabberd system and database must be properly backed up. - The database schema has not been changed comparing to version 1.0.0 and consequently it does not require any migration. References Contributed tutorials and documents of interest are: - Migration from Jabberd1.4, Jabberd2 and WPJabber to ejabberd: http://ejabberd.jabber.ru/migrate-to-ejabberd - Transport configuration for connecting to other networks: http://ejabberd.jabber.ru/tutorials-transports - Using ejabberd with MySQL native driver: http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver - Anonymous User Support: http://support.process-one.net/doc/display/MESSENGER/Anonymous+users+support - Frequently Asked Questions: http://ejabberd.jabber.ru/faq END ejabberd-2.1.11/doc/msrl-dit-flat.png0000664000000000000000000023273212240230175014161 0ustar PNG  IHDR%bKGDtIME 8-sSR IDATxyXT?2ð"+5X ֨hD$mMQI$VMkbͷj4XHܒ{4:+ D@~s;#z8{{g23wш5qtDDDDDDDxbRQ))) "" ϔ """;x ֯_0_|vx=XYaQ=7n\3%! """""""`RI """""""r&%! """""""`RI """"r()Sѡ cOLJQ|2Ə???h{5[n00uTxyy!00WꩽFҥK?~<|}}aÆ)Vو^;BCC?FY*x" 7773r~eڮѬY,kINNƎ ^^#F̙3VW۶%G믿g~:ၠ l޼J}He˖X`]ߒSz6۲/ :EEEJOηy`d}l{󶶁c՞ilx#99yyy'ڵkgv{^Q JllnݒL~wbjڪU+ʕ+$$((Hio߾fWJV$,,L.^(/_'|Rzꥺ/r[FO?'Oʖ-[tQu)))UܹsgHYnÇ[nPM\4o%**Jӥ6mӦ r-[7o.999d<7o\y=gqdffJ˖-l߾]ԩS$..Ne֬Y@>S߃CTfdm>Dl51i4˗e@:t \~]6o,K.Ƀj{?ä՘_Jz- ׯWʲ̾0)߿/""@oҤI@::z_F=zP8;;ϸMIII2WWW9p:==]Y[D$?#7no-$33S)7o_~ٮ1u eR|Ŋ@"##XA>}ToOV8bNR=5j>Dl=f35홾obXDDJKKkm>ǏGbb"L۴i}lذ=z4n޼iuÇlݺU);}4 ::Z)S3}o#~&OG<{ήgimo洤Dwii)%{<0=ԾncPӞ6oK}WTTCy @e5iii"޲yfwr7ҪU+ׇeddHXXDDDX/33Sܔuu:ɺuDDTe6mٱc[N4oFu;wzjzJSN"Ųyf߿6:xR`0ȶmI\?|ptl2e/_͛J^^`v1ø{sOҩS'[n)9bh4qss4Wӟ鼧꿡iYY,[LYÆ RQQaqL%___ wVcij>Dl=vҪ:dLσ.jtҽ{wqqqݻˑ#GK?}6T}䟈G$''K^Uz%III2}#11Qt:[N<)ٳgv%dҤIRXX(<ɠADŋնio\3gάRֳgOiӦx{{9++K "%&&챉jdc\|4o\<<yO """""R>;u0q'هI """""RwO?ɓ';4'N(6k#"""""RI&!/ """""""`RI """""""r&%! """"CለPU`0`㨈>}5iw#G";;!"jX """"Cɪ;v z!"jXxQQbRեK0~xÆ CNN{*L:(,,DBB+mOCvv6PG(F.^ cƌAFFܴ5qk4k,= x՛k׮o߾ѣG䄐1>|Xt)f̘p >>ǏTTTؼWðap16mBRR꬟Xt)qF>t\/FHH|MEDDǤ 3f3giiiի***^ ej^ڬOSj1S@'T qiطoKNmZ˴ 6lwww=7oT5n"ƄI """"7pt:t(?ӕf*T>gڗ`߾}X~r)ŶmTӾ}{up5,ZHc$c())^GhhY;@ 0mu!ѣGkʕ+0aJJJaRMnݰk. ԩ.]ѣG 9z쩔@YΚx0sL_~VUŋx̞= F||< U0gz,Y>}(u kqƓrl߾])'ѣ%"""GQGQƤ9DDDDDDDLJC0)ADDDDDDD9DDDDDDDLJC0)ADDDD `)Scnxx8"""!*3P狈_LJQ2b,]6VTT@DjⲒ,Y?ϡдiSDDD )) ?ȑ#U>5iҤڱՔ***… ѷo_zG_ZATjGll,;Vk}QbR{ SSSqZŊsrrЧO,Xo._\,\))) S=zVc-HNN6/wXr%̙WxvZ Νˑy&駟"33ػwoEDK#Z&"""Ƹqk֬6EM4Q]Ξ=~EEEf}g+WphѢʺ+Vo[CPr";;NzwAnдiS>|:V1a?Pt ?ϔ """zcBCcĈ8s挲RӧOcȐ!pwwGݑ,3 :u*|}}7 ;Zl -tƏ___xxx`ذa :EEEJ?6mńZQvv6BCC,x" 7773fZn~ΗB$$$ ؿ9n>3:t$$ӦMӧh"x;wƀ֭[C>cM=T^ffLⰵ =NX""""Xoݺ%mڴ^xAnݺ%x{{K%''G@/.-[V+""ҪU+ѩSDI\\ˬY|""rUiժŋOJ^m*,,Lȉ'Tv~i 'O-[ر<22R֭['EEEra֭Wª2}=|r$%% R=k@RRRɓ@u&""O>֧~*6l.]ɓw~;Gs.")Cd-[@vމ:{?ä՘_J~m JټyJ˵k կ~%""U 0//OH>}DDdҤI@:R@Tvz$!8;;+]]]tm-2  qrrRֳ5OHnnnܻwOܽ{Wiܹsfuu:Br1i&C)ɠ_d-[@vމJJDDDDTc^Sܮ];;wpuudeesh޼9^ nݺf͚A#//}Zl+WTiӦ(,,SO=˗/TAj())1K]?? :۷oL8SNEPPz|Y?KqۚSKt(((@aa!6mj1hZxzzݻVѶm[?׮]O<"UbwqqAii)\]]ѥKx饗zTPPPm[5t5:T& }nܸ(,,TEׯ޽kW܁˗/۵5 1116mZK,'-[`DGGΝ;|}49cǎ .T[ǘԩx,X777;W_bq1Y6P#Y;&%<`(Hm۶@uj{سgʈ+ >c35}tlڴ III|8<.] lܸ晶[sjѣ|Mu[@LL W^yNBf0w\L:c2U1D+&%nݪ>}mum۶^|j0yd=zpASyyy;w._mF1i$|w(..˗Ə6&kqjoNxRc]|Y7o.~~~*yyy/J@@ܾ}[SO 1cܹsGӥy2h Wၛ,9rDܔrF#nnn&"Ob0]O֭[+df7RLIIoooرlذAܹ#RXX(}jJ iFȎ;dݺuh|7X:u$)))R\\,7o0vMc:x|Ç`P222Tiuu9ڵtYm&/7o]Jpp\pAqM===eݺuJyyy9///v.Z[5t|9\Mfeeɐ!CCzĘ=TъojJ\\\$00PfΜ)%%%fLJT&yquu=z޽{͖'''K^Uz%IIIf.\(:Nz-gϞ5[#tA\\\M%::Z9H74Dݓ'OJ% @٣& V+/imGZ:0FKe|7 www^z)OҰٲ>H6mj1mZSu8lm=NԐDDDDpuh4prr2;%-СC*î]0aܻwρ= """""Ih2e yP.]`ȑj35Paaa8w6mF)S8:$C_5n޼_tž}㣏>rtDx5*:t@nn.Ǝ (OoGSjj*Zl'Yf/K?VRJD)ADDDD5{JcDDDDDDDԨ1)ADDDDDDD9DDDDDDDLJՑpDDDk00yd>M+ΎQդG:aR$''{1:DDDDD NstDDI """"7/^Ā1c ##@=N ___"!!^^^ 6ܧ!;;QQQpwwGhh(RSSUh?#Kejǣ&.vf͚e_"G/ " IDAT""zI&a֭1qDeÑXt)f̘p >>ǏTTTؼWðap1}@Dp]xyy߿VhZ899Lu\={Daa!P^^ggg8;;TU?uufeƓooo{`ٲeHNNʕ+zDD """"7[?W_}'N@޽vOOOV% P^^nW?YYYصkJRCM?NNNUڴ6K7sb…Xz5DHcR͒%Ke˖!88ѸsT5 1116mٲXԅ p)|ᇵ+QCĤ՛Xt)qFz?ӧOǦMZok oA`RFӧJ&&&b߾}/c{1zjP.0=%T(??xL/91i-....ذa1zhܼySո&%^;@II z=BCCJLc* Zo>_^b۶mi߾=`ݺuv-Z1}Fu1TV\R=zXv-\ &ꘉ#&%^Z ś^ǒ%K, $$@*z [gM{t9s&ѯ_?@ժgG||>_|GcLTXX4cM9%|$(Xm=>5&%! """""""`RI """""""r&%! """""""`RI """"jPa`)SSOQ.5c42 |8rrr!fF#GDvvvFCD8LJQlΉ'U 5c4:vz}FCD8|OOOGPot:C "3LJQh4_ueSNٺ/_-Z`޽UWslDEEAHMMwaa!@߿_ŋ0`0fdddXL55k~^ADDDD"%%J`Ν8pҽ"n߾pTTT`޽hѢfΜY j6l;'Oٳ6l&N,.]3f <<111U0i$lݺ?#&Nhu$22ǏǬYluDD FDAQ4n85kl-//sobƯpuuUmVgڴi~zDGG~'tɬ={Daa!xQZZw*>Z-JJJj䄲2UcV{",, >}T;Fkq=[BDl2$''cʕpqqQ=v"d5|ꅓS-񫯾PyvQvj`@VVvڅߧBl(//W=hݺ5y8qz$ ,Z\Ν bLH#I """"j0,8LRr@5 1116m;kjɒ%IJehܹs~e… 8u>Zȑ """xB~~C5}tlڴ IIIz3x`?K.EPP6n܈؇k o^1)ADDDDx?bn0W.*o\ T>UKeq}zj^K$L^.a~2[c*φ8}rD۷,Z\]\\acѸyq5TLJQi߾=`ݺuv-Z, `P^gdd زe ڵ+ų>k???}~zRm۶!==]i_Jl`4vX8p%%% 5kt:tRѣ ڵkqL0%%%VLDԐ1)ADDDDfG||>_|5ćb۶mhӦ Fp 4^^^B9:t:fΜ`jʓ2 $$@S1zj FVœ9sd$&&1ZX4c-DD JDDDD5V[#"ƅ%""""""FI """""""r&%! """""""`RI """""""r&%! """""""`R`0`ʔ)QQPa>a00ydmk{ߺ[]DDDDPÇҥK5iV9rd~ƻ FFΝ;U56z ܹ8'F?mlUcJJRf[QQձ{.0)ADDDDuĉ*eHNN~=Z͚5 ϟ+,1fuqA@zz:***j5(++͛=ıcjǽ{ _۷_5ZlM"//,| 0ɱ{MMMŁTU;x&%ȡ<==m?TN8&Mgݻr_lܸѨjz-tq3( +W, z*[h֬CoMMFP1)ADDDD?~<ТE ݻl`ԩS뫔]x ƌ ȑ#x ׯ_Gtt4<<<d뾥@vv6Pbĉfh $%%O9_\\^{ ^^^h߾=8xzz]vU~ 7 ;Zl (ɓ'q ̝;عs'e B`` /]Tfm['͡m=k,՗Ѽ+sϟoVXfY: <]z衔1eS..V[ۥsamlLJP]cR/zjݻw.0@Bnnnkc[n)e_}~[Db:Nާҁ\qq_ !![lAAA-Z,ڵ+ cǎŁPRR^*OBnn.N>ӧӧOv> ۷ׯWm6+x _~: "JPi4$&&"$$J5ѣGĞY̸ٳ3gΠ{hҤ {9̛7@#A}*͛7/>>>UgϞ{.ƏW_۷oXn]f̓W-:tlvZ\r&L@II9xP6m0`8;;cܸqJ^/~ ֩vP3CD C5U_v-ݻw޽9rD:tH&44hhZ8p\xQiXO>͛1B.\PiwrI߿Ȟ={b^/v2+MK_srre˖fenjD*3ψCݫ,HPN>mxĵk.N'&MBx9tmlﶳT̙VSu>s5jTҽ{*5.ֵw.}6֙g4fx͚5+y]}x"yOJ_r ZhQѣ@ eeeHDDDDԨ&"")QPPSⷿm :vI """"jN8xFNSNaԩ6QXX|I|h42eC"r&%Q{駕ѣm۶-0bݻ6QcbwtHDF]GbÆ u.Z VrtD3%! """""""`RI """""""r&%d00e8:*#6ɓ'7DDDDH9r$E[C?ϔ """GѣGB#cǎyDDI """"z$yzz::jGl: "zXLJQرc1b9sFYh?keለӺ "##-[bHJJ2#::JٓO> :tRlDEEAHMM:bv*}̚5\$~"¤՛۷o#""pv؁t %%z;wRVQQ,mڴ+7@II v 4m+V@LL .]͛6ldcذaؼy30)ADDDDfܹs닟ӟk׮3o߾U{窔Z<Ž{0gt:L6 dDFFbذa(**֭[͚5 ==aaaF:v.]Wܹsvv4iRL-[ +VѻwoY허>0)ADDDDfΝ;+eQQQ@A\\\j{ZjF/// `ʕ;v(u6mꫯ /(m deea׮]߿?LYnzDui&͝; .ի̥~DDDDTo4" p֭:ƍBWXX4hz)|1giDNN6olv_PPQF!&&F9&lS،.\SN?_"Ĥ՛'xMT~%m۶mo< 99r'''7`عs'FXfϞ  R֙>}:6mڄ$SkNMb3Zx1BBBo"--ͮ~DDDDTo}hP\\ ʽ ??_U_ʿ+**L<G\\\acѸyCODT[ """z3{l4oCZZ޽wyx뭷z۷[׮]âEe* Vۗ`P}a7779sݻwG&Msa޼yf}t={*Gۇ+ضm]iǞ:ѣ ڵkqL0%%%50)ADDDDEؿ?BCC1`nHIIRoG||>_|3 gXҧO*޽;vލgy޽;mۆPu_yxxx`СJެ{N3g"88C@@Z]mGmlc2&-RRRP^^۷+$~"ڢ{LDDDD7fGBDD>y9DDDDDDDLJC0)ADDDDDDD9DDDDDDDLJC0)ADDDDu;w 5PLJQ(//GFFϟ.]˗/C#"J#"  :|C!""Ś5k ZYYYػw/vލ={ 77NNNTTT(\\\0|~h4pqq_|Ƥ4p@r+ЩSz3&%Ȧ={ 00͚5C&_!cǎuPtDDX1)ADDDD*,,oĉ.pqqAΝh"FIDDDDDDTEYY>ct˗/ǒ%KgaȐ!e/萉7HQQQ?gFvv6^~e̞=O>R'??z~zDGG;*\""j5 gϞ㑖 &`h۶mzرcl„=)ADDDDXnU IDATr%^{5k+V@HHu***c=z4~bҤIHKKS=4^ADDDڳg&Nعs'"##=v&"""zcڴi8p L&$!xcɓ7nΞ=?qqqcz퓈Gll,֬YSm2)ADDD(--o 7 .] wwwR_ZȱƍW'2)ADDD/8vX\c=zCc "_I%Q#W_!$$CFFDDD`R*--o#Gbذa8x :w谈7Ǐ'|^z!ϔ """jD{wU52(EES`45n~Zר۵E,*0E1Pi9n(ed|=||Μq{βm6xzz`BZ5&%ZJ,X&MBhh(/ "6op1c3uHDDDFQ G}HNNƈ#L """jA^pС{&!^x;v4u(m/LFV^Vamm J[[fS[Ö8ִL """ //_ya0333uX&$$a)ȦӧO:F1w\|xѩS'D6ODКy&%Zgbʔ)8z(6n܈G}!5\888:6%%%!I999`aaW<+W61}I """b߾}:u*:v숃b$M^kԩS ~G}1R9 @s saƌܹ3<++ is΅zdP={3f@N`kk'*^ۗT*U?]vՙ1cݺuÒ%KegΜA`` c!33*ژh46mj5j5BCCq SߺUPW9_|]tAAAakk lݺZJM{NUTTӧ1i$jL07oT07{w}OO;ګ[ii)}EJJ ^(ۣO>:g?ԵM}hLXN*fff[oIeeCjHԻ~aadggKAA<@Uwoe@<<>>uw޽ș3gܹsr˰aK}Զk.)//QTc;;;byNjȘ1cdÆ rM9| <:={Kaa߿_:t hfZ]v2ߋ-K.IvvtM(\!=o)sZ[5 4H/"۶mү_:ۨm"3S} }ǠO{Uc[bȊ+o!uV  kܽ;1]_LJȩSSt"( :o< 7nTʎ;ի߷nR fff7k, Rʖ/_.nnnFK>yf JYddPfqzyy)322+**v#$;;[)O9}-//gYYwt钲۷+W 3fRV\!=)洶k*2drܼ6j.b>S}i} }ǠO{UͲ2qRVZZ*""o߮o]}XkLJ!ҥK}Jf͚%GwL{9 @Qu9mg QJY}sOww)!mڵK|}}-7}wO Cc^g&wkJJDDDDO?E`` F4:$>NcǎJݏ?m)((\vUѷOׯ#,, VVVXn<\t PRR"DDylҥKaooO>Dxx8\R똴.U}gc֭ʐymhQZZ7WoHwbN q <裈+bZ~ic_;V6w y飮mrw|m LJ5rDGGc֬YxWi&ٙ:,7K={4ugTTggge `cٲe͛Yk_ڃ'O*e94ݻwq6fݪ ǚh_7U{Uc⯩׿csZc˖-X~=&MdZ3M1N}c06IKQ3|2j*|W?⿽joF)-tqq1˕+++~-G@@^SaÆQҷOxwi& 88Z9s ''pA=oB?ٳgѣHHH޽{@yBCBB}:ǣڧ0h[eIB]|Y]{7Wj洬Ljիk߫S>/}i}cЧjlkmrwMfTƸj+}2u8MkB:t [nׯ+7 ݻw+>|XDDL??:kkke];;;ܹlذADD Q_?r }yy޽[ȑ#:mT*tsmJiilݺUDnz @<(""ΝGGGܹ8p@^*'OWWWkCBBN>Lu/dry뭷8\\\ G=\rE~Wqww),,T7WƯOU6##C[ʜ'|i&qL={sNٰaT* ?tIHbbƩ.R>c}i}cЧte= L׵M]B۶m{{{/:&א))Gyu>kD?PDGȰaR &ׯWۗk׮T1bXZZʐ!C$))I't;vXYY?,gΜ3cǎɸqVjDDDT{СCgϞҡCr}ݽ{̚5KJJJC2{l*K_|!bkk+rԩju+}קl2uSBB_~quu={{ァ,g}V]LcY[~1מM٦ y_k"""""#oGa5ӧ֬YcHX]~… &C{Ss4e-eNڽ2{ES5""""͛73`Æ Xd Νkꐈ7,X`~,M_KpI """"#:w&M'O~@PPC"j7x ”)SLGnn{NN<==[m-eNڽ2Nj<^ADDDd$999?~WUǎ $uW߾}{o߾h4xꩧ :ҧODxxrFMc9}4䊫+#%"j= """̙3i&o!:vسgO+** yyy2Dze͛7#22־73;k"""PQQTXXX@RAAAJHLLĈ#`ii OOOl߾]I<_~EAVcҥB:NNNHNN7ѣGXZZ"55U܄-7s<#(..?j;;ADDDdyyy5jT*τ 1)ADDD=z@rrr'+QbR ۷oǘ1c]vz}""I """j1i$L:[lAMI """j,Y'|/2>3:$"""_)bcco?^|ESDDDDwaRڜrѠ>}:`͚5z۷/4 z)DGGCY&"U{I!cq9ܾ}uرc!C333@npj۷oҧO 8%1]Vgׯ#,, VVVXnK.JJJ "OIIIriWWW@aaaGJDԺr"""j|MDGG㭷ŋzJ|,[ ؼy3"##Oǎ{쩳^TT_I.jc@ɓJ6ֻwzFDD60)ADDD-`޼yXp!/_:$2"JǏc8z(w^@yyRY2}^{56lRwMjm̙1zzRQQQ-w},;~8 <<\fLJQUQQ{~!1k,SDM`ڴiHKKCYYj5Jl;<tԨQu`X[[ĉpss=&LW_}XaѢEr.\vaшw,X 33SiqqqHOOǵkװ`b޼y I"ևI """jO !![liL5/-ZҥKGl(uxСCÇsA}gM <wưa`ii www,[ SLDDDJ96<==#Fؾ}xk,^^^Jm}'''$''ѣ,--\nBDDDD┕!""v֭[C:$SSݝL~Q3+))Axx8ߏ;w!QaRZׯcĉ矱gQäEEE7n󑔔A:$"""jbLJ;v,.]{!Q3`RL ͛7 WWWSDDDD̈́%"""J0!ADDtaRL~?lllo>8;;:$"""jfLJQèQеkWڵC""""`RUnn.F>} 11:u2uHϯ:YYYxбcfxQ[]QFPP vvv@h IDATZv-$$1>}GDV1)ADDDx1dlݺ666Zz1>}GDV1-KDDDM.33>|8$M5DDDԤ8@FiӦAVCV#44'Nw,DD DDDdRSS|װ6uHԂV+۵k!!!Xt)\]|HIIARRrrr~jmUVVBDŋ9r$󑓓'N 33*// &&* cǎ={DAAfΜ_~ (̚5 EEE̙3q)ܹ탟Ξ=[xZ&%I۷<qFXZZ:$jaFYl:=zZŋԩSxw1x`tͫVHKK3 B?D䄅 ڵkJAPP̰eW_رc?qu,ZvvvxW|;pvv5+W9~Oƿ/t > bccqEO!"jmTR_@{AHH&L5kܜ־WL>fk/cj(Oׯ?˗/+P^g|uvvƹspz_ǎ $uW߾}{o߾h4xꩧ NMӧN>:˴"ўDze͛7#22־7s&$H/3iJKKnRBj7|,Ӯ]O_^{MyEzz: ywi& 88Z9s ''pA* ǏٳqQ$$$`޽PBBB}pFD0)ADDDk.!""~.Q} ذa.^_Y6p@dee)gffsŶmp ?5jT/X8q`oo &W_$%%!66~~~Xh;Dҋ *mxzz]v=z4~M4AVj… 舸8ڵkX`\]]k'QkO DDD(wFXXL>gHA>C`Xp!Ν:`{{{cٳ'}Qbرppp?o3gfؽ{7 KKKcٲe2e ""HMMT*D1ەx/ĢEVtRq5 F`` zKKKG-7O٘}hX`GNtTj뉈bhJeeeXb֬Y6l^x2co7CԴ;v4ӉBCCU)"c+t>|AAA9r$dRRRb~rrr믿|̜9ǎChh(JKKuTTT\UYYiF,Yyܹs(**{gT4[,nK."o;gϞX~}?.ֻnS;DƤ֒%""&@xyyoCVf5k4 QmʏMُ]7*U!1b?GS:+W3<,cjGMT*ꪔį4<M)]x ϔ """#GÇ믿fB͹s0c tNNNHJJYhK!Μ9@X[[Cffrҥ [[[xxx`֭J5iL4 j666ƁSOAR)?:&LP333cbwj񗖖/ зo_ի=S[,3666֭,Y,~}+ԘHU՟]W]א~zëtcjjjOS"''˗/h46mj5j5BCCq 9hȶ:ǏǸq`ccOOOkw{f'DDDtΖ.]Ș1cƍZHԻ~aadggKAA<@UwȘ1cdÆ rM9| 177eT#$;;[)OHs "n: qյ}kVmIHmݺU\\\9RDD%..Nqi4qtt_Ν;Wc޽{W< "Ҹm[S?C5^SxMнI """2'OJeȑr5SCmZwlr})>Nb6VVVֻ~L3̜9x|I8<ƍgp z$dHH`Ν<٠ ݾ͟|IVX]v!,, ,\Q︢w}MBW_rSϓ'O*˵Oݻw4ĥK=z1^DFe4h.\~Pc7i@V^iM ׮]ӹBD|BD$!!A oVHLLHr.--ggg133'''?ٕVcu[SUOޔj}*6HOOF.^(wKg>ouo yWk__\um߆nǏ 0UtʻiK2cƌ'%%̚5KgE^{ZǢﶭiھ1^toDDDh2h qssϛ:j К.ҡCٺu\~] ޽rCrAs@.RZZ*[n9ʕ+믿(U>gϞ@v)6lJ%tnR)" :uNyeenFFr u fUozzgVV:t2<9rDrJ%֒."wWvJMM:H~dӦMrٷot]333Sn4Z^^.wV]_\uml _}R6tP }]s!VVV2dȐ/}8s挌5JyM;wNsrzL&&&XXX9rD90IOOcNJ<:km/BVBCCԩSTm7!!Ad/H@@ʞ={tb...Z-w)͚Θh4ҭ[7mI(1B,--eȐ!,瑠U_"nnnbaa!":]vq ۘzjչ+cA{c~/^s17nڊZk4f/,ݻw իoyHC枨6MPڴׯ#((k뙉OXfIPT{6mjveLJ1"3g|!ՈI ""6DDcݺuغu+Fmꐈj{J!_j*lذcǎ5u8DDDDuDDDmĂ `͚54i!"""ϔ ""jx 0uTSCDM,++ /:vؤ}̙3I "DDDܒ%K??裏SO:"jaaa8}tgJb| ׿wQ3i>~&I ""Vj͚53g⥗^2u8DԌ훼;;&I ""Vh֭xK/_7u8Ԇ!""ǪU .4iӦMZZFhh(N8,WTO]e󫵟#G_D.]PPPp[nUeee!::;w#00piL4 j666Ɓ~zë &(eY2vliiix׫}C'"R*{s=' @ڵknmm-*ϗ+Vȏ?(N eHԻBٳ?^ eҡCqttF#""JZvV6rH/GGGeEɥK$;;[u&dǎ""r+eӦM2`4h_~Em&_~RQQ!baa!۷"9{oJJ\zU%%%E*++km>w)bQ&M$r:%w}1)ADDԊDDDHyyá6jرRҪ?*J\)Keĉz#$;;[)OHyyy㲲jet钲۷+W 3f\vMwI6 pk277WO}7nĢEгgO#%" DDD-FAPP\\\_!QtElڴ sEllN&fffPT@vvQB.\GGG!==׮] y) ذa.^_Y6p@w :j(EQQ?̙sprrBrr2=zرR? fϞ bܹСfϞ3>6>>>߿? 99:uOXfMԄ#0a8)n"""2 L>HLLdBjtmdff"%%HIIkЩS'!66FСC|FѮ];|xg|"EkQ5!"mbLDDDDD-g?۷4n޼~ Crr2q Ǜoxxx(Oh,ggg\|M\577W=''&&%Z^z k֬7|SC&T\\#99@ii)z聀,Ypwwo8RB >d^ADTKJ:w:&+44A͛aMnn.VªUL5 ]ʕ+HMMUFyy9g}Vy 5DD-OիWqF_'LDmƍѧOS`}^)S:F?/`ѣáFڸq#LJ\xQľ}pQ<<<_~prrjȉ_olذI 6lQ\\\0~x,^ԡO?#F: 2z k׮)h4ػwrSʼ<=`ԨQܹ&""2 S`Bm)++êUS^^^ ŨQZmPLI """"#*--ů9s`ȑx'#G(LJ郣G YYYXr%֬Y+WY* ~ CsjED<Ț۷gBˆBCCl2[O JU㲲2,]> о}{a駟Csj׮]ck͛x0rHj`Ȑ!Xx1nܸaT*U+++ 22?"aRZ4C 84r5 d̛7ΝCQQ{=GcԘ%%%)))Fm:s UVaѢEp [oaݺu6lNÇСC30SmUQQ0 //OI3ÇήQqkÇWUV/"5ϔ """"h46mj5?{wE݄,$  ,bBh@VY 7fdѯ#νęwdQYE}41B`E ! FNC'z~9Uu>TIS>>>>bl` p|7Z{mܸ?nѷXp!N87x,@9sȑ#xq뭷͎[\DKlš۞vMb=Yv9tΝK??NK222@OOfg[hזXX9;fŋ;;FsT-xlJ;KsZb_l###d̙9s勊أG?EEELKKXPP,|r3++twwgVVI2$$DY(//zgfYY.]J\nI all,YXXȮ]2&&A٦bcc G\ۉ$;v[n%G1bXQQC1**l}V^WXs1118`mjFELMMϱcQQQ$ɮ]*Znٿܹs ?XZZ{LYjdNN0""BSlšZ]gת%,Sh |Mmxe6F[hזXx;;f%׵-ѣGogo^KCS2(aߗEsrr^{+iO?8vXdqqqfΜI `II p$9s<{Z*ˋXQQ B;v仹oUgee~{]F$(멵 $[\%Re['O4[V Iܹs`ƸMXWWǃ*A?5Vj@݅pV7(ajKzE"ٸz/itvm uh dP:9G[hgo^[2(aߗ֞={+++<`PPfعtLJ$YWW`nݺ "_:u"Ihl77qvڵqqq {EwwwΙ3}o/Kg)n65cDx"m3 '$I@tss?p@~f٪8[k lM5(dsJ|N:puu`=MU[h׶Pv}(**y.^0 @p@ii]q ZիWq}aXpa~xq#!!W\ќ~{i}4ZZҧO7RKΝ;۷j<+W^x)O;v嫪@8|0?j8яdqؠDaa!f͚@t֭#vN6! /[iZ׫UݖIMcZٚL쭃=UVV'/z`F^oek$Oi}ÇSO[n /// 0[liojk-Z]ʷDsKu١={D[o/X}쥿?`޽#nĉ;wڵg}6mBbb"&M ̘1_;`&To*jmjؾ}e>}&LGyyyyܹ3^}U̟?ׯ P7s| nԿt1o1,, &!O6!< cRSS\k.4XD˔4I,mJOdO='RiY.\5k\_ eP& R'䩵ko*((HyK/ŋQ.Oꫯr&*=կZ-Mo)MI}{s:XBI;z(pɒ%Jχ~H|g.7e`޽3228l0dBB dzz: d_;wfxx8,/СCIޘ3kkkIޘxirСCCs1UWW7cZZjrӇ]vUn0U\\޽{s-6Zp:يCmh9֢xg}vqNh0ƴ51YKڤEZcҮ ҺNJZg:W*iƎ4^[$#""J2!!A9I74+=v ư0ݻWY'##G;G|mWR\?FKijmj _u4bLL 7Ӵ\իWSN6+d:يCmǷ=.3A 6Xc>h...nA׮]#KKZyy9Nʀn޼_Jkǎ ꥃSKup>f>qԱڒAWYڞdwww%wX fTL쎌IAҪжl rݺuf>$YVVM6I Ѷo9U0&3zKm"MMQO@kz GѺXg߀^7k̤b-M-_2 ڦya2dY^G1e'E&h J6oެ\BRSS/B4-Jډ' Jqfsc,׮]3^UUUܨ'|6leҮ,YD<##111vu?iZe{46ߖ⵵OoבǪhYK_eteoɓCΝ\@ff&~,}~ʷD_E׮]Ny9;$фmۆz iii(--E]]._M6+|Mg(GK'sFFF]]]-[\ CBB4O6!}B~??˗/W \?}~rr25i&NH^߮v%MФuhedd(':xʹL}IZxF{?r GۗfMT5~-Y+ʷ/J/k}#UV5k٢={lOOO4XQQhZ$g88p >L___6`|'p=RۄHwfhh(z=̙C@???>f3kQ?Vk/R}"K7a=gWMzZK#{I'Z6h*x?#ˋ'O6Hm7-k)gVE' J8wN !Mwi~3#G\DFFB4Rϟwv(l2g(=Qs"K^^,_7nTnKjox BGj!sJ^xa!Z1ӁhK^)BQ J/2"##1w\g"hŎ=6ey_l/B!-]!!j,B!ȠB!5B}#B~}~oW%B!CUWWcڴiC!D+ B!a6l OBLt)B!BA !B!B8E Jdggc޼yW]6..}쩃h9<6Z磭JH_-!B攘/_vj,W 髤B!DѱOGATTrss鰂H*4$?3"##QQQaVvUUN;wFnvZ< :sX;62ZQT7QQQ?~<-[N...t5jf͚':MU‘CS[|96n(B!R3f̀|||0ydOJ%'Nq鉁"55U`l1ʕ+Ϟ=Yf! ^^^0a {/***8:v~|,\|9s:>}&M<==1d+9r$<<<0m48pl;jZUkc̙3ׯF _|Ezpww{ui ,X___oii{ZzuELKڱmlůKјvvlVΝ;1k,t3f_~j!}UW髄BP'77[?˪"уǏgQQǠ ( ._bpp0ݙE Q3ˣ^ٳYVVƥK׭[G<[bϝ;D,cږvbMM IrѢEtꫯ4mY*CKh1XKo)~{VDFFrvuر#LJ?8QK_%}Uj-[Hg!B Xh0''GI{?,|!O cǎ%I7Xn̙|1+))!<$9gu{=FDD,ˋXQQ|٫QN*ﳲWBK*իK_%}UjdPB!!_;UUUPxm޽.Hܹso`RR-pBիUvx 7VNYYy08fLdmm-ΝˡC͍ݺuYVV@N;v4eLػ-mxl9sAٽ{wej)-Jtؑ:Na޽/ԍ_*髤j}}Uk$B!v0'b %ѣ%K(?Z]nʔ)ɀ~ی 6/'N$9h eܹ3ír_pС$oR $olҗC)ׯ_OZhiKi-\Pu۪guuum/RۭXXji[6ZWR$9zhxAbb"mǶ6F IDAT(:͍?c/}UW5A !B; J2((LOOgII Nʰ0{w|r ѣGUÇᡤt:zxx0##$chkd@@pϞ=fϏ}arr2\º: ~ avv6Pfѣ뿌&%%Qo߮ԥo߾LMMeee%l٢hɏe||MzzK6;)4Zϴ4eIKvvv}x޽[jm[/Ckh_-KI~wtwwgPPwk׮ʕ+ܺu+o9kL;:մA 5| KKKmӘJWF2(!BhA <~8ǍG///p -**O?͐2<0B!Њx7sQRRb6֮]谄EuvB!B(ZĩSooo::,!h+B!hJ(((3L<?锗8[-Ǹ|mmm>}&M<==1d^TTT(ر"CsUSO=[n.\@BB0`lٲ1b<==+W,ZB!)8dPˈGYYN:;w믿F||<Ξ= HMMmޮ]ٜつY~&L-[ 33IIIC>6jjj4Uz5g_5ft֬YիW#==Ř4ivܩ,{q :=z #駟5mOy/Ֆ&ܹs.j:gṁ6liuh~zrss Zh0''GI{?0IhZdUUU4,W?-::}1+cǎ6!D{ŋ;;FkLW]xQYZI_v-pĈJ̙3 $ɒ5mOyV>˖-cddø)>hIHHHգGfK||<㛭ա))R>OI4i`۶mh*8~8vލaÆ\!D;֜}U``acƌdee)i@k۞S+_!ѣa9e %%sF۳0>Vwݾa|M.e 9Fz*>L> .tZB9*ks7tPYY]x`0[H*8=էVB4V[\W;;&ؒχ>ڰ-f9dPɓ76{"gŦM(hZB_UVVƠk7S+_!*,,ĬYnݺ)Wbeggc` p|7rZi>{,f͚xyya„ (((,, .]djktSjjc=,t:IjO7w:j}@+{ uēO> ___)))())ٳ^z}ϳO;G~K̙C\bvQ%K;]FP)--\^ee^UUIkkkIzXYYI} ў9%2STT}E)iSL![7"##Æ +n-Y+Bا)QTTİ02''.\c=f}+VܹsLLL$0@]wX?!!!e~~> ٵkWh.˘2~߾}4iXQQC=8~x1--~~~ R9{lqҥuijcvŚ-tꫯZG[ljں صkY=.((HyK/ŋapp0(uZⷧ<{qKiSk[J$;v[n%e?k۰VO>TSO}τ:ۏY.\5k|ynٲؿ}RZ5jS2(QXXȠ 2==%%%:u*xee~??˗/W*J9FMM }ed1++KI"yc;w2)):}vd@@pϞ=hkDsUz?8\}ehhÇ, RR|!}3!آZ-3#ѫW*i櫫kmwՏ6ˠy1ǍG///p FJwPzΙ3~~~|'Fmd(j/\~=z=;vÆ cXXK\j?U_!Z8(A6__E>#ˋ'OS,;3nnn[KyJ- !k`6XZDNI_MOL9+ׯrř={ ͱYZ[nvԉzˣ7*WM8h]בZ{={㣤_Kٻ-qF6fvb\\\|1hcH>j#Z:8F6'~%K{hN7'JY샴42jgzZ,Yz_x[oՠL7~U$k׮PuXu6 n,++cٹsg܎%j;S_ݕ46-g>vtL7ӦZI:u*yFJhc>8viZ~R}}v<T!9<)RBMwFo&Oﭷ AfyM9Zdúuн{w4U>w-M-q1j}M=9{K{ J!D0}ts<B7oVLG\VV}]]TcÆ ,YD>##111в(O?099q%%oĉ/RI;q !!Asl:t(`ܹJ_w^u$''cѢE3fL`<]˗''OV޺*1giUUwuu5uO8>KKcZρVZ@klR[[RIm:K+mCk?l\BX^oȠ+e+`HHҔ"Ifgg+i m2᜜Izz=D*33SY7;;$cp̘1ʽZ&'ę$'&Vk}Ņ555ܽ{RH'N^￯9ri{mO6mX>TCk?uhedd4tKiS{<|Z=#[4R>GY'ZgcQ)Ê#G ** ml2g(=~!D۵|rlܸUJ%O>8Stl.5ey-MZ{g{?EB!p7Ξ=Ppox-gߚk mK=!B%UUU(//ǬYPSSP#..qqq0hr/2"##q;5A8ՖRڴzdPB!лwo#==iiiHOOŋQVVoooFll,nxyy9;l!nҥ.n%ҦMS\'o!NV\\E=^M~^^^9r$^|EرW\Ç|r`ڵ{; ,h[>vڅ nSք'W^m|8}Qg#nwiӦaڴiW:rSbȑx뭷Zu/mipB!cHHH/_|=[劊3gΠcǎ8p bccxt޽| wuuIlذHKKìY=zヒpuuUW]]Z ذa.©dPB!hA?W_󑘘pD d7āP\\ݻwG˗xbDGG?QWW`555(**ƒ>Xdgg;&s߿4^\QG!py$B,^ϟK.>|C-)#G`~z+$8;s/f1LӧO7k:4xΨB8)!B@$bػw/ D+S^^ͷg ˗/]w݅9DYY|||z(h?~B!O?Dqq1<aVСCvԠӟZ9Mٖ: !)!BPnnnHJJBϞ=1b8;$ъ>>N4YYY IG?~>j9:$O1cư$YXXȠ 2==%%%:u*xe1eee)333I6N3224ž}xVWW$kjj{nGQ!M!Ba ]\\ag"ڐ JdJJ cbbƘ&&&*yƓlZ#A-7H#Ǐsܸq򢏏OnL-1YZ$SSSyw͍ܿҥj9B8<}C!hyHNNV.f4B!%jSl?H!-믿2L6 ۷oÝB!&2(!Br:.1a۷C qvXB!B!D₏>#Gѣ'!Bd2(!BHJJBLL F! !B$B!D[W^1bN>쐄B!A !W_}@9ΝsvHB!ɠBbpqqѣq%g$Bр J!m-܂={ǏGIICB!0#B!D={ ??&M`pvHƼyﯺl\\!*SRK!ȠB;wѣG*g$کɓ'wAqquuu t:yUUUxqwCףSNGbb";e)ShCsСպ5Up]wƲepUŠ3gȑ#+K2(!Bضm!vȞt|-ڵ 0x`\< Q\\UV!55ʲQRRRmZk|q׿^z ϟDž |r|駈ɓ'Cmm-.]BII ֭[ 2wHYBCB!hk7vZ*چ#G ** tvICFdd$***Iu IDATwމs֭[u׮]G}$Zdjkk1d>}yyy 4[ʕ+BNp!zcLc0dDEE!''!!O\)!B#Æ Crr26l؀z63f̀|||0ydOJ ؉'0n8xzzbHMMU򲳳1|m?;;#F'rJgb֬Y&Lދ %;>`…$`̙`tiL4IaȐ!HOOW1rHxxx`ڴi8pv拨^ ,X___oԦkƍ8x  ĉx7 ę3gЯ_?9P]]_|z+옱%::LVjP?iw! !¥K:;sss5STT=zp,**bZZĂe9˗YYY ;H!!!rFyyy={6ʸtRuHϟgHHcccBvڕ111 6KJ#Ċ :tQQQfu]O2}b ;whnSK5j(`jjx;F"IvUֺu똜$ΝK?R>cʲ^^^Vۜ$srrd+}B7jSdPB!hQqŊE0Xh0''GI{?fO?%;$Y\\`3grXRRB fl`yކ/ 2$I  v(,,k=SW^}݇ӧc… ~mx{{ߎ\rEsu[6O>SNY]ܹs}ƳrJxxx^@YYďcZ\ $QYYÇ:يCmh9e`!G%Bvs=G}GR]tGARѳgOO$oV^ݫ1&Nعs]zgi&$&&bҤI nj_~ ?lL֦۷[]f߾}ӧno„ xGΝ;W_~z1jL}p3ǷBE3\!BV駟 pܾatG,Y¥~!gܔ)S{VaH J'H4hͲWvܙ,**X/C%yc%yc^C)ׯ_OjT]] F[ ijmj٧OvUTqq1{(xX*h…3KXbNPZo.D{#sJ!B:Ο?nnnܺuNԘAB100,))ԩS˗/+u]9r ѣGLYIÇᡤt:zxx0##'1z2))IF@@pϞ=f)Ϗ}arr2\º: ~ avv6 PңGΝ;DNGܾ}R}255ܲer%?66V4L)'Jځ4:y$o6׏;vիWYVV-[nSN)˧+e\t,vooos@DEE133 ɽ:يCmh9 J!B:>tssW_}p4fP$?qˋ>>>>}@V|BWWWgUUr~OMMwI777FGGsf)))cbbhj*zq O2""`hh(tӸL[~cǎqذa ޽{u2228zhsԨQ7ۦ|GZ:46^: DOOOzyy1&&LiZYի٩S'q'V'kVjT?iw!):d!B{$#)) [l#hfGATTrsst:\\\PSSEӫƍ!C(ؽ{7|A;1B!#O.BaF>ĉ1qD'QOzmӼy0|p ߿?LȄI%Bр ֯_c{EFFC@ll,v튴4t:̛7!&m6|8ߏ~9;,M2On2;thQG!p&RB!}v Çǝh9e %%sF™dPB!۷#<<ÇǏ?DBkuBS2(!B۷G>|8N8쐄cȑipt:I?>`0`"<<| 3tRt:eTPP3f>>>ouUK=ԂH7o"$$pv؁#$$.]:eeeaРAh׮rss1yd̞=7n\v  qYcĈ&yܹ̝;6l15BDDDTCn߾- VZ/v:TEz^^zGGG9x>--Mj  < vvv6f#"zj0a3w\ JҥKVtmDD )SP/xn*d޼y5>F")DDDDða믿b޽ڵ);=z@ף{V-өS'W^̙3L)e4^`˯e}lذ'N(;ܹs(((#g8t>>>zU9UVrJ6m ֭[(**}B`` zDK """QK9:uĉjDu`Ŋpwwǚ5kЭ[7DEE)=OBu]pNªUM3>Rlp s27A)\  77pΝJc߽{#G QVuHD(ADDD5?vT;%e8&**ggРAӧCRSS1x`@hh(`ʓ0RRR裏e̝;6F"voiADDD{СCKNP]~Z@$44TDD:ܼȑ#""6v$!!!,DDdbgg'RPP ""/_ÇK^^5J|}}͛VdY'IMMGҮhYRRRDD$33dx{{K\\ݻW$$$DDDXvڥSSc$",¢: )?U-J?/NNN2tPx2OEm Jxt kʒ^xA\]]Eʸq'fXyDD_~(zD<$ @% @bcci͛7OM>7^(((ѣ۷w)Q """s """m6"<<T;%"""RDDDTg!C <<W;%"""RDDDTaÆ^;NT¢9lڴ cƌADDE """R+3f 1{ ""ǗFU &xNDDD*FO>...4i NvZDDDTX ""zapuuq=̙3G픈DDDTo;ocjC5,88!!!Σ0c 4k:ӧOif,5I1)ADDDʬY쌩S`0NjH&9UMJKMRcDDuE """w^{5W^`g}FvZTMIII9q<<.\;v` KrJ̟?111pMVX0h k_i͛7;wNi3iСCjk|iE 5^SiI&ԩSذaZnmvHDTX ""h׮ Sz/I(((zBCCW%G}-[`ܹ1+zG """Zt= V+S;F]tEի*7fl۶)SSSED$%%ESݻMH6mDD$((HBBB*;55UYFӉNå@DD._,>>>-<5j͛7EDСCJ#GNS͎ѣ쬴k4qvv4&'""{;;; "yx]v)꒥SX ""@Ǝ+M6^t%v%m۶7772e iӦIFFr@m1ڽ{SgϞrQS*O0`Uط ,0_VV *ZVƍ<1XU4dׯ8::J^$11$Ϥ$ GGG XeZ-SSc$"K|5z%%%:u*֭[u!::Z<}KT<""""k֬&N\jEDDD(ADDDF~-Z`ٸr >CHDDD`Q7|͛7ǤIp]jEDDDf(ADDDNtt4x =vZDDD&j'@DDDT{"##aaaq)#X ""F+00lS"""2X ""FSN8x Ǐ/%kѢߏΝ;cРAHNNV;%"""DDDjؾ};0tP$$$R0c 4kLi FHHHCOm|t>}z.jj{~CDDDprrBll,&MQF!&&F\oVښ4iFS9\?ձdh4h4t7o,7qzٟ\Ɯ˵XsϾ2#GĪUjlxԣ>p?ƶsUU~CTU,Jc+W_WX`DD'NkKJJBRRRk4… qyL<YYY1b L)))Ajj* -- 5CM+))AFF^)9üy󐕕ӧxWرcSޯ]/Ry]~U5UDDDXZp!֭[?/ Nqwwo;ӯg&MЯ_?M4A>}zRr… >;w㱆[wpp@hh( 44ΝÞ={wAzh0sE3 *ݻ2j(ܹh49~9sFZn-[JvvvjQ^`(-MLLooo X6[d~ƍJǔ/]v'x><,_cH1طoȄ RmoE """*Xdh4?NJQ]ȝ;wLڭ9xϗ+WJy~M& T/2a;wo+7.sdP-RU-Jx{{ ٱcG|lhsInI6o\n~ 'OT lӓO>)$..1EEEF۷W8H>}[Xc:xMrСrei{~eM7DbQ֯_/mrjwcWDxx+mƿ6ʞvn<r)ƍYyo_ ;wٸnnn) ubgg'-[~ܸȑ#Ƭ_sy=X*f_N{HhhOb"##Eє+Ll2ĉ@ϟ/"brGs*))1;vKcR9sFDD>,}QrYlwyXܹs)mڴ15cNݻ8;;ˠAg"b~en{&~U"[(ADDDT {OOO xycQDJJ888$$$ݻw6m(7 ""RPP &_{5u떜>}Z~ii۶yk|rFv픿ʼnF&7OI{ii7--޽{eUY)))J:NDD222*m3GҮhYRRRDD$((HBBB*|JJJLSzzɘ_.*ߔ`^|Y|||[>,yyy2j(U.9tX`t&}-)33dx{{+gNݻW$$$DDqqڵKu}vpۚ1SZZ*XϘq^K۩5Ç*_,JUǥ}ҩS'_NU(!"{nٳ888HϞ=ѣ!SN59.W"?899СCŋJL֭quu#F<\܍7WN<)+{19??_ZڵˤјZ#Z2iߊoMHrrOW^LHPs)x)iYYY /hZ7nɽCU$(Lk޼~sUTD`0f;ej֬In7DFDDDDDT\1NB||S;FC׫B"cǎzDDugJl޼zœ9spQ^j֠B"7ާ)ADDDT4 Ν  ťKNV`jj1bΞ=Lh4Oem j ~)bccM*֢E /%''#;;jpqqAqJׁ*SS1˖-Cvv6>xyyw͛k׮0`@\6m{=ܽ{/z-+ÇO< ׯ/.-KDT(ADDDT4 ƍիjU-GTpƍZQ~ ϴn{Evv6xbkABBɁ{0zh7N9*,ũJnF.\Sj*%"X """Rȑ#k׮wؿ)UY^Ф_5;tP,HJJ2;/2D111عs'Fh}]om۶!66V9룬ŏa)NUr3Z|9郿/HII_"E """"#==AAA2d>#oXDDDr_8s **JiDPVURR.-- 40}tz@jj=+&M裏wwwL8/I?ׯ҇fM[r+ۇl3['"k,JLb˖-Xt)ϟQF!//OlK.EJJ ܹEsQԩ ..׮]L֭8p`}t:#GqYM4tRCCCQTTqy] طoFl߾ݦܬcKnk^o+WK/5%Fٳgc޽HMME`` 233Nj-[āп 2O=f͚)-_m۶Ŵib֬YĴixx,s˽ٳ'vލ~={ѿe'O WWWJĉg}dnnnX`uANNN6fmks+;&c"99%%%駟Uɟi!HDDDԈ]zǏ?UV_;=z@ף{u75.ODDDDL-k.̘1&M”)SL@DDX(ADDDTcҥضmb8i(%#F --  ď?vJDDD5E """z1|p,ZjEDDTm,J5...ꫯzj|'$%  ..| _~El¢Q6f9r۷/N}HJJ¢E0e޽k֬G;ݻw,qtرJkDD(""""ewK/MoAms̩숈qm۶Y """jdrss?{Œ%K0g4i«vaQ|'?>BCCO=i`ɜh43g<7nT;-""",J5bK/?;v,~7"""7vɓQ\\/Æ S;%""zL """s=^0 >SLA~~icgJ=1m4xxx`ݺu Q;%""z L """И1cѥK < N3vɰaƍr!rܹӤ͖㣼_x\~]233UV@~'SNL4Ie…@6l`u8-__iEkQ8-}?XޯV/X2kIٸkM6ٴl""""VUseee)SPھ DDn߾+,,{)m""RTTT^z) @鎎rA}ZZZEY;nK93w\ JҥK&[XXh룮_,[TT]VHXX-? :[{tL7GuZQ,m'` |x}R6-,JQJQO͛7GJKK%ƿ\=p,&5^E}ܹSMر899ɔ)S喳%('s:t`r$Si_5/]$D*m-[T-ӴiS󷥿GԿ9jӪĬh;6kD,׶v_3v Ϊ<&S=%جY3d\^\;wNWSݻѣGcܸqx뭷M_bݱft QQQu g IDATVY1~R񏾾7nXØcu{JoKԿ9jS[Te;1ǚYk?kP5[,JQsrrI={T9F~ƶmrqy\غu+&r2x`~9I:tXxPeΩږkb[~_8 CM}Ϥ.(ADDDD.88w)meb}ii)ӿ&۬ ?rW@@yRAE~zhpL6 Ǐƍo߾ ,㶔9~Ai;s **Ji3>?x@V͛7#F(m L>z۔5\,oZ봰Py]TTm|? ~֎x}hܚ*]ADDDDS"%%ESݻH6mСC#GNSED$((HBBB*/33Se[DD˖t""Qi[jjkNȎ;$..N4"Z~Z@$44TD聯$--b}y8qBymydC7&| FMuD Eu.߰|j]]X y|TE """""""RDDDDDDD %Iaƌh֬ک5(|Q59jADL """"jj@D (ADDDDTMj@D (ADDDDuҥK8q"Ç#''{2̜9^^^0 5k<<<о}{8p@ (o<<<ЩS'$%%!//&M;:v숤$elDFFBÇ/^Đ!C쌱c"==˪,㵔Q'DDDDD6شikիWM6$/^˗/K-$ @DDڴi#,[L\"@8 )'&&Frss%&&F,YDrss%!!AH׮]ew.ɓ ܹ2=,,Lrѣz0kMΞ= HIIA@@KJKKc%e/}0\כ(F3g`ڴi8~86n܈}Uoe:%-Z8{,_| --M733_8p`+zɲecm3. طoK,o߮;~x_'N@߾}dprr8::JJJC*...J1}:YYYصkBCCRYTZʉ1`Qj݊+5k֠[n­['CUT'ν{0zh7oVok>^m~-[͕4ɑ^zɠ]߾}%<<}_^rrrd@wޑٹsN:)vEȹsd׮]@HٺuKJJtU/O7e˖Ivv :&"@bbbYe˖-8q"YQQG2nSVVZQFzmΝ>۶mCTTয়~BYwii)PTT777@II j5w"\pA#8|0'N@޽شWKhΝ;3(ݻggg٦jJBLL &L`}jAw6| 22R)k׮U)&G .55.\JrZj/ Ξ=^zMOzQ}¤9S_///X:}[cǎŸq0w\5k1BBB۷oW?kQ}WCI{BAAAb޼yرcߏܠ~ذa|26mڄ?_~% gϞjg^)ADDDD5N{kDII L*((л=j_ing c}b[mi&PnJR!##ӧOǙ3g#G\`ژ&%ƵouV\~VRBBB|?q߆fϞ]vPoΝ;0`ɱ@zz:荗fPpl۶MBJ#!!@XXA)))KNN6InDDT_0)ADDDD5nӱh"̞=5W_wJ[I}XXك֭[cرׯ OOOʃ0+++۷{={-B7DHHAc5k zs~6ן УGW^VDDT_DDDDd[_ JDD6&%N0)ADDDDDDDuI """""""LJQ`RDDDDDDDT' """""":ՉT̜9^^^JY~п.>QՉ#F`ڵS4hJeqFm0΃xwRRбcGܺuˠ^ìjK,1vժUvQuojM6E߾}oڵk6[5ѣI """"gϞ5(C\\]IOOk .˗1uT\pFBII^ ?~J`o8r}ƍm7lؠ|콏/iiixn:tߚ8LJQpwwO>psz' 4@>}zzJ䄈@DD.]CKHH@ӦM[m 4hzRmNNNÌ3pQ#** ׯ_HLJQv&Mooo955fBƍWbȐ!pqqs='N('N«M"''QQQpssCpp0vܩa933#G\]]DL\)?qR>tPbԸU_RRW^yh߾=␟)Sڵ3{jj*"## ???XB3f_ޠnÆ J-sK[Qյ***ٳ6mѣVd̛7n˕rc}T*4kq s1JP"""""Ĉ?#sss% @%--Mrrr䥗^J_-[.")[nbIII]*>>>Jŋˍ7$--MݻWj]tr9ٵk )**~[HHH)ܽ{W|}}%99Y߼<ԩuͻ:ׯ_/999~z ;HNNܹSHN~ϟ?/FL"pB 7o}Jxx@ʤEV%''G˓@)++3XOKs/mGUjٲe-@::O>-cǎz/""2|QTw^c6mkXWĜ9sl۶M)pZ^^ɛZ{rrR ƍDFF*eU UN8::*=z7)SKŋI& w6f\HaaRVRR""$~'L $++KDD[lo_[z,^XigDKc}O;?r=)))1XK1[SxQQZm/`1~\cnDI """"5IJ uR=UYYip֮];qvviӦə3g4^D_ᡔ:ܿϠ~֭@F 4HZۯV\\jh4bPoi\SW)װaC㛢~ZwUA^&c277\Vb2ŚF1;ˀ&Ls% LJQNRBVݦV{&M(cǎKl;y^Ilݻwe̘1Ҹqc +**$((HT*9sF222n Wg}&W233 -[ݤ"mۧ#GHRRL8lLf뾴ZY:j}{zҩS'iҤrJMc60)ADDDD:I www w+d@֮]+@ f[tdӧ p9ٰa'e2Pei&%۷ [^cǎɚ5e_c:j}V(QTg8% LJQNRbذa@6mڤݻwO9Ѻs"rVhqqqQk*e|狈W4;+))-Z͛7 el*++eF478u/寬4(Ӷӎ׾}{IKK$07LoEhΖiڗ#݇m[+[u0&[<|ٲe@^umjjn"DA|%(ո~NNN={6vڅBZJܹ3RSSﺯ3?~<PZZ `!##̓?͛zGm۔WRٳGiVkTQbm?37775j\rŠnѢhW^r99t^!+ڧ???2s㚚5eoJIDAT""ҧOQ*V,|$00PMvMK[v]Q6m* ˗Kaa6͚53.Y+[c6P"""""lٲ'N3R暊իѝcKHH0c…k_,"""""Ĉ?#sssuOKnn;vL5j$>>>%""@WMlxbqㆤ{H͕v7o۷KNDDK.@Ν;'v$rAqrr J^^ʸqqq""/'&k"c|2rHINNbmkXW)eK. /HyyqiiA%7nP)++S7n($22RDDܹt^ 6.GGG~̘1@EDD<==,[LDD<(OSο&bcݺu2qD)--iMA}jܶm;vTF 999</6l 99ڴiGjj*.\ ""P^^O:駟OOO;| ~iԽ]m5֒%KrJlڴ`-KDTLJQӾr u,S'͚5m;v,ƍs:-ZLl۶ /F֭qqdeeaΝz'VMĦu?~UDDDDT K.)e )ڶmZ!̛7;v@llrE.O`ؿ?F &@Dh"@pp}[իѣGERRMUDDDDTFo @TTRB{5ý{:mRnR>F@J6mm L2#<<4i_z) F{Ǧ;oWWW<쳸yODd DDDDT-Z,]IIIsz-`Μ9Jn݊ׯcժUJ]HH0`U.Xyyyyy?}vR9r۶mSnسg^(++øq;wFk*55UR#aܹF~!33#GTnc CbbRU 2...xp ~,[z^D^TTٳgmڴѣGZSSev݉#Sm =⪓?4lҥ@^x_|!';a56bZP% Q^^.QWՒ|ONNR%UK6޽{""RRR"AҚ[/ooo yyy&{WWWsץKj4 EEE""- 0w!rI%ad.Ku' """ZSD۶m(eϟ㣔;ѽy4h뫔kذ )++3jAܖGDdү_?vډL6MΜ9czK355&ўGDM6@_.""EEE@j؝nݺܜaiXs|[Dу$%L """"q €@nnm5j())` 7n)rrrwܱ)6m]fv 1vX7s5_f #$$QQQ}T]/k_ jiM \rdl@,Ƴb ୷BAAƏ'|hRJJJp)zNⰴ9JVGDDDDT5kzԾm۶f՞HjdOOO0K///C#Fgv͛;v 66#G46l._k"88_~3-Kkj̳> ؽ{6=`ܸq{g0uT?M4%K0k,DGG[ &cRjoU222QQQfݳg`̘1& 80c ?A"""oF$sA&MtRܺuh;w*WTT(啕M6PJBFFO3g ::Gޒ1Ĩ~m55f |\+??K,App0Onrl_ӦM?\v ?*Qss2}`m<#DDDD;SgJ\vM|||[%??_ƌ#r-]-rmINN:t(P>SNRREDt5x{{֭[>7n,zRFIPPl߾]n߾-RTT$?lRRSSE@-u@'[nJ%d\:t RRR";w\{ݘ?.ǎSHjjRv z]tI:w,;v={HaaΝ;s"W\Q'&&*cܼyS/vwwwπڵ?~\*** ּZ8,kokם>tIDDDD:I  .SO=%nnn!ƍ{W+kҲeKqrr6mțo)z&%D'#jZBCCzqqqҳgOQҳgOի_rh4ի\xQ.++K^y '''qqqRNuҍ/::Zܹs!r!e$:t8;;O auth1; c2s12 -> auth1; auth1 -> c2s11; auth1 -> c2s12; c2s11 -> sm1; c2s11 -> router1; c2s12 -> sm1; c2s12 -> router1; router1 -> local1; router1 -> service11; router1 -> service12; router1 -> service13; router1 -> s2s11; router1 -> s2s12; service11 -> router1; service12 -> router1; service13 -> router1; s2s11 -> router1; s2s12 -> router1; local1 -> sm1; sm1 -> c2s11; sm1 -> c2s12; style = dashed; label = "Node1"; } subgraph clusternode2 { c2s2 -> auth2; auth2 -> c2s2; c2s2 -> sm2; c2s2 -> router2; router2 -> local2; router2 -> service21; router2 -> s2s21; service21 -> router2; s2s21 -> router2; local2 -> sm2; sm2 -> c2s2; style = dashed; label = "Node2"; } subgraph clusterservers { server1 [shape = box]; server2 [shape = box]; server3 [shape = box]; style = dashed; label = "Servers"; } client1 -> c2s11; client2 -> c2s12; client3 -> c2s2; c2s11 -> client1 [constraint=false]; c2s12 -> client2 [constraint=false]; c2s2 -> client3 [constraint=false]; s2s11 -> server1 [minlen = 2]; s2s12 -> server2 [minlen = 2]; s2s21 -> server3 [minlen = 2]; server1 -> s2s11 [constraint=false]; server2 -> s2s12 [constraint=false]; server3 -> s2s21 [constraint=false]; router1 -> router2; router2 -> router1; sm1 -> sm2; sm2 -> sm1; label = "Data Flows"; } ejabberd-2.1.11/doc/webadmmain.png0000664000000000000000000001461612240230175013605 0ustar PNG  IHDR2;sRGBPLTEE  !" $&#*+)/1.6758:7q2?@>HpEGDIKHLNK)[TVS._*i?-a9`-kH2b3c\][-g,h.qB`b_?h2j:jbda5l7n8yB9o0q8q)KwehhjgCwY5tJs9wopnCw1{]o5?@7`|~{8B:G;>aLd=G>ہw@xH.]UNWLEMm~X`m SYA]Zo\zDe]n_e@n`adaTVc۔}^_VwrSxmiᇞkx(sSAuݗgrw }٦"yuӕǪP.:[|ęaÔ͍D㚺ֈşGOʢWaZϭ򺀣ϙjߤlv|ֻŌƍʈΘԳ֣٭ڿbKGDH pHYs  tIME -80tEXtCommentCreated with GIMPWIDATxmly$_TIH옕HIX\pWSe6-V%\MDMR7@ .zH\Rh# (SkVkc;q43VL[:/33s{{wK;;;3Kjzfg! (."AqiIm!(. m~C`*7(+gH EQs5ӦApA!퓮GdB{Zd4 4?vsL!)Z25A͑{B aR'4f4RVV?4df +2b'x>DGAGNgw9*we؞rxy/|kڇǴC +b"E'p@J!O^5#WUܕեs4&$/#K/|BAQ /8gE~녥7QRN^er`tNr,}_^yC"LH D@2&D9uw Lp<7Nξ,v!=L"g=${5r׮Q![VWZ]_!&W+{B+6j  8 g܋.\*pvM ҃&o v|GK4G`y< eŜk'3F ~IB޳o}x{d Ħ:"C~>@Oq*z*xzCQyC/Vj '?xS |\yY_#?ۈã~PWirc}E"P ٞary]=y;R>f:9B~*mSBN,i]~IVC 9n8Ϲir\"|wj> }i8)Er|]cbnY)ϒ'Fm¯A9߲yEG"0tdyEǏ!p.\;˫B?ww|WG1B c-pA+;1Kr?"/ [@6Mc޼4G}\&]#b~ɝ}NtBd''Gݜ~3.L?se2ɡL_/&*F` OΚDZi ilxdddAr9_q^r`W`)1O?re粒 rQfskбy8p@s@a"KýOeGǞFx°rv y*FB{CǨ ò 4YlEEGO "Cp1ѡC.ИGUA3  |9=x2j#{Do8 @?:9r?* zT ޙE[o{;K7}KW%ivwr>*X!Ԙ]su~3nz-M[="^uNs{;'nrB18iF!…/2))|?"=h'sY^·[c%]>7s7\Ia]SlWϢilນ2낂YT x6PGҙmgJ.<©~˿sDܠ[wρgz9r|Wq_u!Źv.U]DL)D\/ da4S^SS|sۺd}37?,嘹qMoܼfew\06yecwF>س׽Wn_XGJz̥DOZ s|k_? TmOz͗";bL;1HG༤~ퟛOL8BPY\RO:,nG$@Cj"6/}ua0Lg (@E8XdB!@ B@ a ;)K&F @A  0BP`p_arC1ݙRK76B{H#A  @t!uc;,h–-QJ힘bݣ=>L!@  @A` z/\ 4k<0z) %g'&F @A  0BP^q?>U&}iߘC@A  A>_>:gc'b;pLew1!4 @A I't 4L9B{H#A  @t!}3A4_L?feBhiA  @Nm*t&;/|%-%P{ B @@fe > : RmZ@`ELj# CэX?}䙂aB~ bӦiD}ֲ~&+Rb 0,J̏K&0+C‰$0 % 0[ \7>$ LS!dC‚ra‰g>-A_&  D:(u6z#gdYt+މd{iZ$0A  B v&m*B@@B B Vuuuɇ jlZayA_& #|]OD!AcuJT0eIKVh8s`Qi2 +"~:^ jd_8)#O9NDldUCp1P>? 6@`%@`@ٚk u9 c!~+sWX5VXe4n9@V i@Ji '-6P@ _jA`z"(_ z"O C މ`4B@`3a@- ʂki@ M~k,( J  *Y6ƲN|A`UQH%3kвvQZ\ϸ4>u"P {+Y м4~)AIMsԯ !Xp㿺%V1!A Nm0 !A !@@B@ @B@ @B@ @B@ @B@ @B@ @BP!(@[hDsnT #_ʂ ԕtbwLQx*, [ƚ 4Q=X/ H("OD*cRTlM,V%0w^'oK-EU1⥋rmڂߏxutUTNKHQC`{"ʥuk^- w5M6(eZa-YNjŢ5Oʽߠ6t<v*:r4-lhkA` $oaٞh Cc}siTxUz"X[a<hLk90ƈÔG鉄 \q/4[5dǾhA lGL@ CP:A1H6 AP\DRlD0x*IENDB`ejabberd-2.1.11/doc/release_notes_1.0.0.txt0000664000000000000000000001031112240230175015064 0ustar Release Notes ejabberd 1.0.0 14 December 2005 This document describes the main changes in ejabberd 1.0.0. Unique in this version is the compliancy with the XMPP (eXtensible Messaging and Presence Protocol) standard. ejabberd is the first Open Source Jabber server claiming to fully comply to the XMPP standard. ejabberd can be downloaded from the Process-one website: http://www.process-one.net/en/projects/ejabberd/ Detailed information can be found in the ejabberd Feature Sheet and User Guide which are available on the Process-one website: http://www.process-one.net/en/projects/ejabberd/docs.html Recent changes include: Server-to-server Encryption for Enhanced Security - Support for STARTTLS and SASL EXTERNAL to secure server-to-server traffic has been added. - Also, STARTTLS and Dialback has been implemented for server-to-server (s2s) connections. Detailed information about these new features can be found on http://ejabberd.jabber.ru/s2s-encryption - commonName and dNSName fields matching were introduced to ease the process of retrieving certificates. - Different certificates can be defined for each virtual host. ODBC Support - ODBC support has been improved to allow production use of ejabberd with relational databases. - Support for vCard storage in ODBC has been added. - ejd2odbc.erl is a tool to convert an installation from Erlang's database Mnesia to an ODBC compatible relational database. Native PostgreSQL Support - Native PostgreSQL support gives you a better performance when you use PostgreSQL. Shared Roster groups - Shared Roster groups support has been enhanced. New is the ability to add all registered users to everyone's roster. Detailed information about this new feature can be found on http://ejabberd.jabber.ru/shared-roster-all Web Interface - The web interface internal code has been modified for better integration and compliancy with J-EAI, an ejabberd-based Enterprise Application Integration platform. - More XHTML 1.0 Transitional compliancy work was done. Transports - A transport workaround can be enabled during compilation. To do this, you can pass the "--enable-roster-gateway-workaround" option to the configure script. (./configure --enable-roster-gateway-workaround) This option allows transports to add items with subscription "to" in the roster by sending stanza to user. This option is only needed for JIT ICQ transport. Warning: by enabling this option, ejabberd will not be fully XMPP compliant anymore. Documentation and Internationalization - Documentation has been extended to cover more topics. - Translations have been updated. Bugfixes - This release contains several bugfixes. - Among other bugfixes include improvements to the client-to-server (c2s) connection management module. - Please refer to the ChangeLog file supplied with this release regarding all improvements in ejabberd. Installation Notes Supported Erlang Version - You need at least Erlang/OTP R9C to run ejabberd 1.0.0. Installation Installers are provided for Microsoft Windows and Linux/x86. Installers can be retrieved from: http://www.process-one.net/en/projects/ejabberd/download.html Migration Notes - Before any migration, ejabberd system and database must be properly backed up. - When upgrading an ODBC-based installation, you will need to change the relational database schema. The following SQL commands must be run on the database: CREATE SEQUENCE spool_seq_seq; ALTER TABLE spool ADD COLUMN seq integer; ALTER TABLE spool ALTER COLUMN seq SET DEFAULT nextval('spool_seq_seq'); UPDATE spool SET seq = DEFAULT; ALTER TABLE spool ALTER COLUMN seq SET NOT NULL; References Contributed tutorials of interest are: - Migration from Jabberd1.4 to ejabberd: http://ejabberd.jabber.ru/jabberd1-to-ejabberd - Migration from Jabberd2 to ejabberd: http://ejabberd.jabber.ru/jabberd2-to-ejabberd - Transport configuration for connecting to other networks: http://ejabberd.jabber.ru/tutorials-transports END ejabberd-2.1.11/doc/features.tex0000664000000000000000000001173312240230175013330 0ustar \documentclass[a4paper,10pt]{article} %% Packages \usepackage{epsfig} \usepackage{fancyhdr} \usepackage{graphics} \usepackage{hevea} \usepackage[pdftex,colorlinks,unicode,urlcolor=blue,linkcolor=blue,pdftitle=Ejabberd\ Feature\ Sheet,pdfauthor=Sander\ Devrieze,pdfsubject=ejabberd,pdfkeywords=ejabberd]{hyperref} \usepackage{verbatim} \usepackage{color} %% Index % Remove the index anchors from the HTML version to save size and bandwith. \newcommand{\ind}[1]{\begin{latexonly}\index{#1}\end{latexonly}} %% Images \newcommand{\logoscale}{0.7} \newcommand{\imgscale}{0.58} \newcommand{\insimg}[1]{\insscaleimg{\imgscale}{#1}} \newcommand{\insscaleimg}[2]{ \imgsrc{#2}{} \begin{latexonly} \scalebox{#1}{\includegraphics{#2}} \end{latexonly} } %% Various \newcommand{\bracehack}{\def\{{\char"7B}\def\}{\char"7D}} \newcommand{\titem}[1]{\item[\bracehack\texttt{#1}]} \newcommand{\ns}[1]{\texttt{#1}} \newcommand{\jid}[1]{\texttt{#1}} \newcommand{\option}[1]{\texttt{#1}} \newcommand{\poption}[1]{{\bracehack\texttt{#1}}} \newcommand{\node}[1]{\texttt{#1}} \newcommand{\term}[1]{\texttt{#1}} \newcommand{\shell}[1]{\texttt{#1}} \newcommand{\ejabberd}{\texttt{ejabberd}} \newcommand{\Jabber}{Jabber} %% Title page \include{version} \title{Ejabberd \version\ Feature Sheet} \author{Sander Devrieze \\ \ahrefurl{mailto:s.devrieze@pandora.be} \\ \ahrefurl{xmpp:sander@devrieze.dyndns.org}} % Options \newcommand{\marking}[1]{\textbf{\begin{large}\textcolor{ejblue}{#1}\end{large}}} % Marking enabled \newcommand{\quoting}[2][yozhik]{\begin{quotation}\textcolor{#1}{\textit{#2}}\end{quotation}} % Quotes enabled \newcommand{\new}{\marginpar{\textcolor{red}{\textsc{new}}}} % Highlight new features \newcommand{\improved}{\marginpar{\textcolor{orange}{\textsc{improved}}}} % Highlight improved features \setcounter{secnumdepth}{-1} % Disable section numbering %% To by-pass errors in the HTML version. \newstyle{SPAN}{width:20\%; float:right; text-align:left; margin-left:auto;} \definecolor{orange} {cmyk}{0.000,0.333,1.000,0.000} %% Footnotes \begin{latexonly} \global\parskip=9pt plus 3pt minus 1pt \global\parindent=0pt \gdef\ahrefurl#1{\href{#1}{\texttt{#1}}} \gdef\footahref#1#2{#2\footnote{\href{#1}{\texttt{#1}}}} \end{latexonly} \newcommand{\txepref}[2]{\footahref{http://www.xmpp.org/extensions/xep-#1.html}{#2}} \newcommand{\xepref}[1]{\txepref{#1}{XEP-#1}} %% Fancy header \fancyhf{} \pagestyle{fancy} \rhead{\textcolor{ejblue}{The Expandable Jabber/XMPP Daemon.}} \renewcommand{\headrule}{{\color{ejblue}% \hrule width\headwidth height\headrulewidth \vskip-\headrulewidth}} \lhead{\setlength{\unitlength}{-6mm} \begin{picture}(0,0) \put(5.8,3.25){\includegraphics[width=1.3\textwidth]{yozhikheader.png}} \end{picture}} % Official ejabberd colours \definecolor{ejblue} {cmyk}{1.000,0.831,0.000,0.537} %RGB: 0,0,118 HTML: 000076 \definecolor{ejgreenyellow}{cmyk}{0.079,0.000,0.275,0.102} %RGB: 209,229,159 HTML: d1e59f \definecolor{ejgreendark} {cmyk}{0.131,0.000,0.146,0.220} %RGB: 166,199,162 HTML: a6c7a2 \definecolor{ejgreen} {cmyk}{0.077,0.000,0.081,0.078} %RGB: 216,236,215 HTML: d8ecd7 \definecolor{ejgreenwhite} {cmyk}{0.044,0.000,0.048,0.020} %RGB: 239,250,238 HTML: effaee \definecolor{yozhik} {cmyk}{0.000,0.837,1.000,0.424} %RGB: 147,0,0 HTML: 930000 \begin{document} \label{titlepage} \begin{titlepage} \maketitle{} \thispagestyle{empty} \begin{center} {\insscaleimg{\logoscale}{logo.png} \par } \end{center} \quoting{I can thoroughly recommend ejabberd for ease of setup -- Kevin Smith, Current maintainer of the Psi project} \end{titlepage} \newpage % Set the page counter to 2 so that the titlepage and the second page do not % have the same page number. This fixes the PDFLaTeX warning "destination with % the same identifier". \begin{latexonly} \setcounter{page}{2} \pagecolor{ejgreenwhite} \end{latexonly} % Input introduction.tex \input{introduction} \end{document} %% TODO % * illustrations (e.g. screenshot from web interface) % * commented parts % * slides, guide and html version % * cleaning and improving LaTeX code % * key features: something like this (shorter)? (more focussed on Erlang now): "To reach the goal of high % availability, performance and clustering, ejabberd is written in Erlang, a programming language perfectly % suited for this. Besides that, some parts are written in C to also incude the advantages of this language. In % short, ejabberd is a perfect mix of mainly Erlang code, peppered with some C code to get the final touch!" % % * key features: saying that ejabberd the only XMPP server is that can do real clustering: % http://www.jivesoftware.org/forums/thread.jspa?threadID=14602 % "What I find interesting is that *no* XMPP servers truly provide clustering. This includes all the commercial % servers. The one partial exception appears to be ejabberd, which can cluster certain data such as sessions, % but not all services such as MUC." % * try it today: links to migration tutorials ejabberd-2.1.11/doc/features.html0000664000000000000000000002416312240230175013475 0ustar Ejabberd 2.1.11 Feature Sheet

    Ejabberd 2.1.11 Feature Sheet

    Sander Devrieze
    mailto:s.devrieze@pandora.be
    xmpp:sander@devrieze.dyndns.org

    logo.png
    I can thoroughly recommend ejabberd for ease of setup – Kevin Smith, Current maintainer of the Psi project

    Introduction

    I just tried out ejabberd and was impressed both by ejabberd itself and the language it is written in, Erlang. — Joeri

    ejabberd is a free and open source instant messaging server written in Erlang/OTP.

    ejabberd is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication.

    ejabberd is designed to be a rock-solid and feature rich XMPP server.

    ejabberd is suitable for small deployments, whether they need to be scalable or not, as well as extremely big deployments.

    Key Features

    Erlang seems to be tailor-made for writing stable, robust servers. — Peter Saint-André, Executive Director of the Jabber Software Foundation

    ejabberd is:

    • Cross-platform: ejabberd runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.
    • Distributed: You can run ejabberd on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.
    • Fault-tolerant: You can deploy an ejabberd cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced ‘on the fly’.
    • Administrator Friendly: ejabberd is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
      • Comprehensive documentation.
      • Straightforward installers for Linux, Mac OS X, and Windows.
      • Web Administration.
      • Shared Roster Groups.
      • Command line administration tool.
      • Can integrate with existing authentication mechanisms.
      • Capability to send announce messages.
    • Internationalized: ejabberd leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
      • Translated to 25 languages.
      • Support for IDNA.
    • Open Standards: ejabberd is the first Open Source Jabber server claiming to fully comply to the XMPP standard.

    Additional Features

    ejabberd is making inroads to solving the "buggy incomplete server" problem — Justin Karneges, Founder of the Psi and the Delta projects

    Moreover, ejabberd comes with a wide range of other state-of-the-art features:

    • Modular
      • Load only the modules you want.
      • Extend ejabberd with your own custom modules.
    • Security
      • SASL and STARTTLS for c2s and s2s connections.
      • STARTTLS and Dialback s2s connections.
      • Web Admin accessible via HTTPS secure access.
    • Databases
      • Internal database for fast deployment (Mnesia).
      • Native MySQL support.
      • Native PostgreSQL support.
      • ODBC data storage support.
      • Microsoft SQL Server support.
    • Authentication
      • Internal Authentication.
      • PAM, LDAP and ODBC.
      • External Authentication script.
    • Others
      • Support for virtual hosting.
      • Compressing XML streams with Stream Compression (XEP-0138).
      • Statistics via Statistics Gathering (XEP-0039).
      • IPv6 support both for c2s and s2s connections.
      • Multi-User Chat module with support for clustering and HTML logging.
      • Users Directory based on users vCards.
      • Publish-Subscribe component with support for Personal Eventing via Pubsub.
      • Support for web clients: HTTP Polling and HTTP Binding (BOSH) services.
      • IRC transport.
      • Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.

    This document was translated from LATEX by HEVEA.
    ejabberd-2.1.11/doc/release_notes_2.0.2.txt0000664000000000000000000000226312240230175015076 0ustar Release Notes ejabberd 2.0.2 28 August 2008 ejabberd 2.0.2 is the second bug fix release for ejabberd 2.0.x branch. ejabberd 2.0.2 includes many bugfixes and a few improvements. A complete list of changes can be retrieved from: http://redir.process-one.net/ejabberd-2.0.2 The new code can be downloaded from ejabberd download page: http://www.process-one.net/en/ejabberd/ Recent changes include: - Anti-abuse feature: client blacklist support by IP. - Guide: new section Securing ejabberd; improved usability. - LDAP filter optimisation: ability to filter user in ejabberd and not LDAP. - MUC improvements: room options to restrict visitors; broadcast reasons. - Privacy rules: fix MySQL storage. - Pub/Sub and PEP: many improvements in implementation and protocol compliance. - Proxy65: send valid SOCKS5 reply (removed support for Psi < 0.10). - Web server embedded: better support for HTTPS. - Binary installers: SMP on Windows; don't remove config when uninstalling. Bug reports You can officially report bugs on ProcessOne support site: http://support.process-one.net/ END ejabberd-2.1.11/doc/release_notes_2.1.3.txt0000664000000000000000000000622012240230175015075 0ustar Release Notes ejabberd 2.1.3 ejabberd 2.1.3 is the third release in ejabberd 2.1.x branch. ejabberd 2.1.3 includes many bugfixes, and some improvements. More details of those fixes can be retrieved from: http://redir.process-one.net/ejabberd-2.1.3 The new code can be downloaded from ejabberd download page: http://www.process-one.net/en/ejabberd/ This is the full list of changes: * Client connections - Avoid 'invalid' value in iq record - Avoid resending stream:error stanzas on terminate (EJAB-1180) - Close also legacy sessions that were half connected (EJAB-1165) - iq_query_info/1 now returns 'invalid' if XMLNS is invalid - New ejabberd_c2s option support: max_fsm_queue - Rewrite mnesia counter functions to use dirty_update_counter (EJAB-1177) - Run user_receive_packet also when sending offline messages (EJAB-1193) - Use p1_fsm behaviour in c2s FSM (EJAB-1173) * Clustering - Fix cluster race condition in route read - New command to set master Mnesia node - Use mnesia:async_dirty when cleaning table from failed node * Documentation - Add quotes in documentation of some erl arguments (EJAB-1191) - Add option access_from (EJAB-1187) - Add option max_fsm_queue (EJAB-1185) - Fix documentation installation, no need for executable permission (EJAB-1170) - Fix typo in EJABBERD_BIN_PATH (EJAB-891) - Fix typos in example config comments (EJAB-1192) * ejabberdctl - Support concurrent connections with bound connection names - Add support for Jot in ctl and TTY in debug - Support help command names with old - characters - Fix to really use the variable ERL_PROCESSES * Erlang compatibility - Don't call queue:filter/2 to keep compatibility with older Erlang versions - Use alternative of file:read_line/1 to not require R13B02 * HTTP - Add new debugging hook to the http receiving process - Allow a request_handler to serve a file in root of HTTP * HTTP-Bind (BOSH) - Cross-domain HTTP-Bind support (EJAB-1168) - Hibernate http-bind process after handling a request - Reduce verbosity of HTTP Binding log messages * LDAP - Document ldap_dn_filter, fetch only needed attributes in search (EJAB-1204) - Use "%u" pattern as default for ldap_uids (EJAB-1203) * Localization - Fix German translation (EJAB-1195) - Fix Russian translation * ODBC - Fix MSSQL support, which was broken (EJAB-1201) - Improved SQL reconnect behaviour * Pubsub, PEP and Caps - Add extended stanza addressing 'replyto' on PEP (EJAB-1198) - Add pubsub#purge_offline (EJAB-1186) - Fix pubsub#title option (EJAB-1190) - Fix remove_user for node subscriptions (EJAB-1172) - Optimizations in mod_caps * Other - mod_register: Add new acl access_from, default is to deny - mod_sic: new module for the experimental XEP-0279 Server IP Check (EJAB-1205) - PIEFXIS: Catch errors when exporting to PIEFXIS file (EJAB-1178) - Proxy65: new option "hostname" (EJAB-838) - Roster: Fix resending authorization problem - Shared Roster Groups: get contacts nickname from vcard (EJAB-114) - S2S: Improved s2s connections clean up (EJAB-1202) Bug reports You can officially report bugs on ProcessOne support site: http://support.process-one.net/ ejabberd-2.1.11/doc/release_notes_2.1.9.txt0000664000000000000000000000350712240230175015110 0ustar Release Notes ejabberd 2.1.9 ejabberd 2.1.9 is the eighth release in ejabberd 2.1.x branch, and includes a lot of bugfixes and improvements. Read more details about the changes in: http://redir.process-one.net/ejabberd-2.1.9 Download the source code and installers from: http://www.process-one.net/en/ejabberd/ The changes are: * Core ejabberd - Decrease CPU usage caused by tls:send with large data - Escape iolist correctly when NIFs are disabled (EJAB-1462) - Fix code to satisfy Dialyzer warnings - Fix compilation in Windows - Replace calls of OTP's Binary, since they would require R14 * LDAP - Document ldap_tls_cacertfile and ldap_tls_depth options (EJAB-1299) - Log an error when an LDAP filter is incorrect (EJAB-1395) - New options: ldap_tls_cacertfile and ldap_tls_depth (EJAB-1299) - New option: ldap_deref_aliases (EJAB-639) - Match ldap_uidattr_format case-insensitively (EJAB-1449) * MUC - Support for multiple entry with same nick to MUC rooms (EJAB-305) - Support voice request and approvement - New room option: allow_private_messages_from_visitors - New room options: allow_voice_requests and voice_request_min_interval - Include status 110 in presence to new occupant (EJAB-740) - Fix mod_muc_log crash when first log entry is room destroy (EJAB-1499) - Many fixes and improvements in mod_muc * Pubsub - Enable pubsub#deliver_notification checking (EJAB-1453) - Fix Denial of Service when user sends malformed publish stanza (EJAB-1498) * ODBC - Fix ODBC account counting (EJAB-1491) - Optimized mod_roster_odbc:get_roster * Miscellanea: - New SASL SCRAM-SHA-1 authentication mechanism (EJAB-1196) - New option: resource_conflict (EJAB-650) Bug reports You can officially report bugs on ProcessOne support site: http://support.process-one.net/ ejabberd-2.1.11/doc/webadmmainru.png0000664000000000000000000003143512240230175014152 0ustar PNG  IHDRCnsRGBPLTEEI  KPT ! \'(& *'a/1.12i685q2$>@=Hp'&BAt-/GIFLNK5188EC)[QQTVS<]oF?z|y]7{{zwsjD;XL.[=G>w@܂x}rsUNgLLEᛃ{MԴ~t_ZҠ tA]}{Tێ]ns}_Fn~cφ^ilюiTq֘(ŕnkc|הA̛ם"͢è.S:ڦԩaԲǂĜ̱dz૪گGOɗ߱W̥ܷaZѼj㽾lŮv|ñֻƍʶʈͷŻΘҷֿ֣٭bbKGDH pHYs  tIME -?xk)tEXtCommentCreated with GIMPW IDATxx%lm32 ?60#6+x%9B^r;>XJm5)g\c0m(ƭ|q:Jjպ#byծvjw_ؙG}gEs eKS-E A#h E''F`MM?j0)Yt$ \g~- E'N \2 :0,gHO y_$BƔE'N>*xʇZ;-g}~p", Ʒ:R0 )@2"GL,|^=#a\sYaY|5#Od]PV&ge ISh({vC OāB>K."(ήӡK/qrzB)/Ǥ}[Cr$u~ėKo=T/ҲArРS:eN74N|.@ 0ݝ -e#gp_\0|^bu ΋}#z*#o9/~qBs/o~=DKyx |EN7xyQ|\/q^yt/>eeY/oR9^HW1d3H6eK/9_"~y99HeZD755/7$΅zY<$`i0/Z _֐T[)[/b^M?r>1e|T/bIv4@P=~~tcynpE'>!/RZ(om@Q\| C^,1d,=ҦyK=1ut=9T- 54|W"e- 7/[\+\}%,UV6{Jff$WMF,ul>TE߻e4`"V佳TSll+rqM [?'P) r&kTm1%.[$>xrZdbl2t,N iKH _cۆK/|HQ=y5ߨ|tR/]Vzby+~)%RkDOm[Nfaodm1%.^*Jv?̏HǴƓ[c5OS ã'F7 ^aU%N5KߛUTo}~/vi}`X&Es0!Q4LD.Va*Ytc^ ˠAqFO1d^ڸq*YtqRBPVJʊAAJIEʂv@B PcJ:L zPz8@(KeyD Oŗ ]]ٿ/JSO[t"6rM 6O~Ol`'c&;8L7n$`ل JQ;$BLB">mg?σl`-cifǹq$?e49S)=mXԔN2;7NѺI]_8^$=&C?'k|Ebsy*ž늦<% _+geDwe޸IIL{j)yN7TiRZzK*zg->j[;IAXAo~~qr6?QXhu_m`Ѵ-'|^2ഁdw+|"d ;||Vbф}ΫGlu .: Y+SO 4(}ݴ+h-3;7Pn"u~kEUfXjW_ͫ~!-lyNzt }$`pC }0<5I"AES6 ƠSH)EESY+y<5ДtZyzh ēy6-X+2- I3gYPǞ/˿zgoE}8fkEoq”} t{x۴?H\H+PZj`)Eb|C.N8|igvkiou ͻ$}C@;?pW_}]{ (,]γW s$7IADY8ed)ES󟱉A=%7?iUњ pOv H(.p7 w_""őL`M'Bl?p¾+(S8 00 i 7fhkZ<YJQi|~r:|uA,8L'3VEUϼL ~ + ˟ю?HL 5|OǹC8 ǂXxߔ);+b@q;n(l8q&ThIm-ف@A  B'X=z>݋g ukbS7\vOٓ{F׿6@  @A`Ap60=LL>WbPwTkdA  @ @߅3{O/W~n#Jm-ف@A  B'ryw۱xN$ L9yn=DQT&ޒ @A ,t!Hm PToSaxKv @A  6ILP_Tk/Gm-ف@A  '9* &e,ݿ}ׁr[  @@>!@e@ˢ`1w*"dm@(~:jD^t3+*e9  泏^=!R!P1gtaej] [`e@OBWDZaH`c10n5RetJP@(kJ ,@0 ; Pp A @ ~ @ @ A !xjrsC9f՚JsIBsm]eM&6+hhҬe7h InW<3{Z+v'eUH[  9&~}lq4+UK̃ HyyHC>ܻ\վ\AwU6ܰQʚc*M9GStU U} IV}=|\udwv0Ӭ"8ZbVVUXxa"x)v<+4)K*ViwV8BqPk*Cob8"a[׊NXE['[' {{XX\o,|Iu(x:47dz}pE-%12in')s-"-}◤%P9(n٩VXtŻHzkn=Jo~4R> mAxlwo𑖃R sr de*j{M'Y4r >G@DsCy98ƅG §wtm`sM̘L*,l7W~A;הPb@ 6a6ڣ;|M }2YkPw;~ Y ݘA tu įr@ &9@ B @@A A Y @ =moEXAŧ7+> W^+3ԟf0rdS#0xEXAŧ7+LsSS D` beBJpgyD`]V#&L>|X.1q&0xE\Aŧ'hx(]6^Cmo}x)+UL"\yA̠Sӓ5=B0Nt|T=`Fxk4VGe8ʹ$ϴ<͡9bOCsÇaѭat"壹C81UTiex Tʴwӌ9].܋Ϣ}'֒ư5TBPxM,e "\yA̠SSϚEE3#_M2><`_!caTsyߘy氱sqGt(o3ض鹈u[%2B%!yZwHw8w48˲Z{s"\5&!;I`+5f~v&uP^H t5{wQީ/r8d;>@PheGpr+1JnsܘyhϹw+cxyf,ppJB+1+pCLu2)2t.#jii.;VX'F3@L7;g ] R*-'pԟL̛g4F8lDU%Ԏ ga=SiFp5N7sE#zU*uVp[b R"UVJ[aYֳwOĭ1*?4NNX *4CŠ i?b+|%:%M!czT҆K1ոwSsu SD?94Z1AVz}=i۽V#}/olX=4mwO%AΫ#-|/4knozӉn cCj, .ZuvZОd4-e}7S䣞-\ִ{,ѪZյ߬zI4v41[WjIr@Ӛv#Ǵ'0ki\g-+ʬVGU@ }Գ# F,L7-K Oz'0I"_-+ 3l, &"n0}f\j}M !s~kIDAT-@:\qj@3Ee >(1k˴^^ -3OZ=c\1LH`r^TrC3/;ϟQJ:CBs,NV~K렴$|A`,P΋JH#]Afi\dL^\5ዘҕ`,吾@:; Lߤsz*uaj?&T@"j7&rH?P͋J _i5n iQEfyqS4uP'ik9΋ʇ'>a,18 &/Uj1#ɵMdyQ1dZ8ܼИ!pLs13ɵ@ A A  $2i60gCU TPPjeҥ l2"`*Ά @602S~PF$tLP 㟧jt~tAڐˢ'pLP 㟧^eҥsÞD)9\/HĿLtS}ߠ'"`JΆ }V̿1LtxA="`JΆ @o"#!̘F7gQ!dn $n)W+Jrj2kKY,#TѸϡ^ \!l)s ]egO4@keJu/:یf\\$ %+v\CydneJ_3{}):KW;6X8$ͯ ϾgB&PتO I*wc;yѩ1w>Y%0:ݠю; 0 @YmL&P/A(D3!8S@8w#-/k}) o" B 0[`@@;Խ\7ArܻaY~6CP=v͘ ,˙Խk*7A\ ށ;X ҄ pQy Fsԉ4{KĜP9']ew `r$g {5o-ȇ)L3Ġ3ޥ| ~rNAoP恲t?0+^2J[6ߋg)_9S*t@Y!0+^#$Dm7pK3E5JՂbN@7s?>a楺]W'9<Ly$B·GQIO) sy @Jw)_5S*t@ V@B *'1͡Bc  O'(#fכS4FIieF(S ?DO[=dug"(m; jb`w!P\BQ?$$"+QnжV»v߶"-=vEeV-r <7fFá˭QF_< A?@dus>f;Bm:PT[MmuVS$Q'0CXoՑn_(Fiy@ jҪ 5Z0Z'*v~UP7@!A @ S&A A  BA`owm#FJ _FnČϑ@hxin'htO,uFjw-.˖IJ"Kmv7En^oEjx8}HӜ3w=C @m=tZ,YfUѱ궗[ua?ikwmz 쵏Ys{\oa2@4goeF+ lmH:MO,YG#"@4')ly?Ibz& гz$y] OsVG &<"гf;Xn]]Ʈ.4z@~ Le,귃Rd,cZI>Elcwzr'?LL+ ZA`XzlC,@A A BXA9@k;Tb5zWPzß лLCݴջw[ J@"ilXomikt~ ȠWwmzv@(- O9yv t~R] tcß@NH%fzw j,LWdP: 2Ri p? @ bjPV W@B@ @B@ @B@ @B@ @B@ @( A@`89@춸ZIIt ?3"0(' yP%J& Ejabberd 2.1.11 Developers Guide

    Ejabberd 2.1.11 Developers Guide

    Alexey Shchepin
    mailto:alexey@sevcom.net
    xmpp:aleksey@jabber.ru

    logo.png
    I can thoroughly recommend ejabberd for ease of setup – Kevin Smith, Current maintainer of the Psi project

    Contents

    Introduction

    ejabberd is a free and open source instant messaging server written in Erlang/OTP.

    ejabberd is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication.

    ejabberd is designed to be a rock-solid and feature rich XMPP server.

    ejabberd is suitable for small deployments, whether they need to be scalable or not, as well as extremely big deployments.

    1  Key Features

    ejabberd is:

    • Cross-platform: ejabberd runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.
    • Distributed: You can run ejabberd on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.
    • Fault-tolerant: You can deploy an ejabberd cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced ‘on the fly’.
    • Administrator Friendly: ejabberd is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
      • Comprehensive documentation.
      • Straightforward installers for Linux, Mac OS X, and Windows.
      • Web Administration.
      • Shared Roster Groups.
      • Command line administration tool.
      • Can integrate with existing authentication mechanisms.
      • Capability to send announce messages.
    • Internationalized: ejabberd leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
      • Translated to 25 languages.
      • Support for IDNA.
    • Open Standards: ejabberd is the first Open Source Jabber server claiming to fully comply to the XMPP standard.

    2  Additional Features

    Moreover, ejabberd comes with a wide range of other state-of-the-art features:

    • Modular
      • Load only the modules you want.
      • Extend ejabberd with your own custom modules.
    • Security
      • SASL and STARTTLS for c2s and s2s connections.
      • STARTTLS and Dialback s2s connections.
      • Web Admin accessible via HTTPS secure access.
    • Databases
      • Internal database for fast deployment (Mnesia).
      • Native MySQL support.
      • Native PostgreSQL support.
      • ODBC data storage support.
      • Microsoft SQL Server support.
    • Authentication
      • Internal Authentication.
      • PAM, LDAP and ODBC.
      • External Authentication script.
    • Others
      • Support for virtual hosting.
      • Compressing XML streams with Stream Compression (XEP-0138).
      • Statistics via Statistics Gathering (XEP-0039).
      • IPv6 support both for c2s and s2s connections.
      • Multi-User Chat module with support for clustering and HTML logging.
      • Users Directory based on users vCards.
      • Publish-Subscribe component with support for Personal Eventing via Pubsub.
      • Support for web clients: HTTP Polling and HTTP Binding (BOSH) services.
      • IRC transport.
      • Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.

    3  How it Works

    A XMPP domain is served by one or more ejabberd nodes. These nodes can be run on different machines that are connected via a network. They all must have the ability to connect to port 4369 of all another nodes, and must have the same magic cookie (see Erlang/OTP documentation, in other words the file ~ejabberd/.erlang.cookie must be the same on all nodes). This is needed because all nodes exchange information about connected users, S2S connections, registered services, etc…

    Each ejabberd node have following modules:

    • router;
    • local router.
    • session manager;
    • S2S manager;

    3.1  Router

    This module is the main router of XMPP packets on each node. It routes them based on their destinations domains. It has two tables: local and global routes. First, domain of packet destination searched in local table, and if it found, then the packet is routed to appropriate process. If no, then it searches in global table, and is routed to the appropriate ejabberd node or process. If it does not exists in either tables, then it sent to the S2S manager.

    3.2  Local Router

    This module routes packets which have a destination domain equal to this server name. If destination JID has a non-empty user part, then it routed to the session manager, else it is processed depending on it’s content.

    3.3  Session Manager

    This module routes packets to local users. It searches for what user resource packet must be sent via presence table. If this resource is connected to this node, it is routed to C2S process, if it connected via another node, then the packet is sent to session manager on that node.

    3.4  S2S Manager

    This module routes packets to other XMPP servers. First, it checks if an open S2S connection from the domain of the packet source to the domain of packet destination already exists. If it is open on another node, then it routes the packet to S2S manager on that node, if it is open on this node, then it is routed to the process that serves this connection, and if a connection does not exist, then it is opened and registered.

    4  Authentication

    4.0.1  External

    The external authentication script follows the erlang port driver API.

    That script is supposed to do theses actions, in an infinite loop:

    • read from stdin: AABBBBBBBBB.....
      • A: 2 bytes of length data (a short in network byte order)
      • B: a string of length found in A that contains operation in plain text operation are as follows:
        • auth:User:Server:Password (check if a username/password pair is correct)
        • isuser:User:Server (check if it’s a valid user)
        • setpass:User:Server:Password (set user’s password)
        • tryregister:User:Server:Password (try to register an account)
        • removeuser:User:Server (remove this account)
        • removeuser3:User:Server:Password (remove this account if the password is correct)
    • write to stdout: AABB
      • A: the number 2 (coded as a short, which is bytes length of following result)
      • B: the result code (coded as a short), should be 1 for success/valid, or 0 for failure/invalid

    Example python script

    #!/usr/bin/python
    
    import sys
    from struct import *
    
    def from_ejabberd():
        input_length = sys.stdin.read(2)
        (size,) = unpack('>h', input_length)
        return sys.stdin.read(size).split(':')
    
    def to_ejabberd(bool):
        answer = 0
        if bool:
            answer = 1
        token = pack('>hh', 2, answer)
        sys.stdout.write(token)
        sys.stdout.flush()
    
    def auth(username, server, password):
        return True
    
    def isuser(username, server):
        return True
    
    def setpass(username, server, password):
        return True
    
    while True:
        data = from_ejabberd()
        success = False
        if data[0] == "auth":
            success = auth(data[1], data[2], data[3])
        elif data[0] == "isuser":
            success = isuser(data[1], data[2])
        elif data[0] == "setpass":
            success = setpass(data[1], data[2], data[3])
        to_ejabberd(success)
    

    5  XML Representation

    Each XML stanza is represented as the following tuple:

    XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
            Name = string()
            Attrs = [Attr]
            Attr = {Key, Val}
            Key = string()
            Val = string()
            ElementOrCDATA = XMLElement | CDATA
            CDATA = {xmlcdata, string()}
    

    E. g. this stanza:

    <message to='test@conference.example.org' type='groupchat'>
      <body>test</body>
    </message>
    

    is represented as the following structure:

    {xmlelement, "message",
        [{"to", "test@conference.example.org"},
         {"type", "groupchat"}],
        [{xmlelement, "body",
             [],
             [{xmlcdata, "test"}]}]}}
    

    6  Module xml

    element_to_string(El) -> string()
    El = XMLElement
    
    Returns string representation of XML stanza El.
    crypt(S) -> string()
    S = string()
    
    Returns string which correspond to S with encoded XML special characters.
    remove_cdata(ECList) -> EList
    ECList = [ElementOrCDATA]
    EList = [XMLElement]
    
    EList is a list of all non-CDATA elements of ECList.
    get_path_s(El, Path) -> Res
    El = XMLElement
    Path = [PathItem]
    PathItem = PathElem | PathAttr | PathCDATA
    PathElem = {elem, Name}
    PathAttr = {attr, Name}
    PathCDATA = cdata
    Name = string()
    Res = string() | XMLElement
    
    If Path is empty, then returns El. Else sequentially consider elements of Path. Each element is one of:
    {elem, Name} Name is name of subelement of El, if such element exists, then this element considered in following steps, else returns empty string.
    {attr, Name} If El have attribute Name, then returns value of this attribute, else returns empty string.
    cdata Returns CDATA of El.
    TODO:
             get_cdata/1, get_tag_cdata/1
             get_attr/2, get_attr_s/2
             get_tag_attr/2, get_tag_attr_s/2
             get_subtag/2
    

    7  Module xml_stream

    parse_element(Str) -> XMLElement | {error, Err}
    Str = string()
    Err = term()
    
    Parses Str using XML parser, returns either parsed element or error tuple.

    8  Modules

    8.1  Module gen_iq_handler

    The module gen_iq_handler allows to easily write handlers for IQ packets of particular XML namespaces that addressed to server or to users bare JIDs.

    In this module the following functions are defined:

    add_iq_handler(Component, Host, NS, Module, Function, Type)
    Component = Module = Function = atom()
    Host = NS = string()
    Type = no_queue | one_queue | parallel
    
    Registers function Module:Function as handler for IQ packets on virtual host Host that contain child of namespace NS in Component. Queueing discipline is Type. There are at least two components defined:
    ejabberd_local Handles packets that addressed to server JID;
    ejabberd_sm Handles packets that addressed to users bare JIDs.
    remove_iq_handler(Component, Host, NS)
    Component = atom()
    Host = NS = string()
    
    Removes IQ handler on virtual host Host for namespace NS from Component.

    Handler function must have the following type:

    Module:Function(From, To, IQ)
    From = To = jid()
    
    -module(mod_cputime).
    
    -behaviour(gen_mod).
    
    -export([start/2,
             stop/1,
             process_local_iq/3]).
    
    -include("ejabberd.hrl").
    -include("jlib.hrl").
    
    -define(NS_CPUTIME, "ejabberd:cputime").
    
    start(Host, Opts) ->
        IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
        gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_CPUTIME,
                                      ?MODULE, process_local_iq, IQDisc).
    
    stop(Host) ->
        gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_CPUTIME).
    
    process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
        case Type of
            set ->
                {iq, ID, error, XMLNS,
                 [SubEl, ?ERR_NOT_ALLOWED]};
            get ->
                CPUTime = element(1, erlang:statistics(runtime))/1000,
                SCPUTime = lists:flatten(io_lib:format("~.3f", CPUTime)),
                {iq, ID, result, XMLNS,
                 [{xmlelement, "query",
                   [{"xmlns", ?NS_CPUTIME}],
                   [{xmlelement, "cputime", [], [{xmlcdata, SCPUTime}]}]}]}
        end.
    

    8.2  Services

    -module(mod_echo).
    
    -behaviour(gen_mod).
    
    -export([start/2, init/1, stop/1]).
    
    -include("ejabberd.hrl").
    -include("jlib.hrl").
    
    start(Host, Opts) ->
        MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host),
        register(gen_mod:get_module_proc(Host, ?PROCNAME),
                 spawn(?MODULE, init, [MyHost])).
    
    init(Host) ->
        ejabberd_router:register_local_route(Host),
        loop(Host).
    
    loop(Host) ->
        receive
            {route, From, To, Packet} ->
                ejabberd_router:route(To, From, Packet),
                loop(Host);
            stop ->
                ejabberd_router:unregister_route(Host),
                ok;
            _ ->
                loop(Host)
        end.
    
    stop(Host) ->
        Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
        Proc ! stop,
        {wait, Proc}.
    

    This document was translated from LATEX by HEVEA.
    ejabberd-2.1.11/doc/guide.tex0000664000000000000000000075116112240230175012615 0ustar \documentclass[a4paper,10pt]{book} %% Packages \usepackage{float} \usepackage{graphics} \usepackage{hevea} \usepackage[pdftex,colorlinks,unicode,urlcolor=blue,linkcolor=blue, pdftitle=Ejabberd\ Installation\ and\ Operation\ Guide,pdfauthor=ProcessOne,pdfsubject=ejabberd,pdfkeywords=ejabberd, pdfpagelabels=false]{hyperref} \usepackage{makeidx} %\usepackage{showidx} % Only for verifying the index entries. \usepackage{verbatim} \usepackage{geometry} \usepackage{fancyhdr} \pagestyle{fancy} %Forces the page to use the fancy template \renewcommand{\chaptermark}[1]{\markboth{\textbf{\thechapter}.\ \emph{#1}}{}} \renewcommand{\sectionmark}[1]{\markright{\thesection\ \boldmath\textbf{#1}\unboldmath}} \fancyhf{} \fancyhead[LE,RO]{\textbf{\thepage}} %Displays the page number in bold in the header, % to the left on even pages and to the right on odd pages. \fancyhead[RE]{\nouppercase{\leftmark}} %Displays the upper-level (chapter) information--- % as determined above---in non-upper case in the header, to the right on even pages. \fancyhead[LO]{\rightmark} %Displays the lower-level (section) information---as % determined above---in the header, to the left on odd pages. \renewcommand{\headrulewidth}{0.5pt} %Underlines the header. (Set to 0pt if not required). \renewcommand{\footrulewidth}{0.5pt} %Underlines the footer. (Set to 0pt if not required). %% Index \makeindex % Remove the index anchors from the HTML version to save size and bandwith. \newcommand{\ind}[1]{\begin{latexonly}\index{#1}\end{latexonly}} \newcommand{\makechapter}[2]{ \aname{#1}{} \chapter{\ahrefloc{#1}{#2}} \label{#1} } \newcommand{\makesection}[2]{ \aname{#1}{} \section{\ahrefloc{#1}{#2}} \label{#1} } \newcommand{\makesubsection}[2]{ \aname{#1}{} \subsection{\ahrefloc{#1}{#2}} \label{#1} } \newcommand{\makesubsubsection}[2]{ \aname{#1}{} \subsubsection{\ahrefloc{#1}{#2}} \label{#1} } \newcommand{\makeparagraph}[2]{ \aname{#1}{} \paragraph{\ahrefloc{#1}{#2}} \label{#1} } %% Images \newcommand{\logoscale}{0.7} \newcommand{\imgscale}{0.58} \newcommand{\insimg}[1]{\insscaleimg{\imgscale}{#1}} \newcommand{\insscaleimg}[2]{ \imgsrc{#2}{} \begin{latexonly} \scalebox{#1}{\includegraphics{#2}} \end{latexonly} } %% Various \newcommand{\bracehack}{\def\{{\char"7B}\def\}{\char"7D}} \newcommand{\titem}[1]{\item[\bracehack\texttt{#1}]} \newcommand{\ns}[1]{\texttt{#1}} \newcommand{\jid}[1]{\texttt{#1}} \newcommand{\option}[1]{\texttt{#1}} \newcommand{\poption}[1]{{\bracehack\texttt{#1}}} \newcommand{\node}[1]{\texttt{#1}} \newcommand{\term}[1]{\texttt{#1}} \newcommand{\shell}[1]{\texttt{#1}} \newcommand{\ejabberd}{\texttt{ejabberd}} \newcommand{\Jabber}{Jabber} \newcommand{\XMPP}{XMPP} \newcommand{\esyntax}[1]{\begin{description}\titem{#1}\end{description}} %% Modules \newcommand{\module}[1]{\texttt{#1}} \newcommand{\modadhoc}{\module{mod\_adhoc}} \newcommand{\modannounce}{\module{mod\_announce}} \newcommand{\modannounceodbc}{\module{mod\_announce\_odbc}} \newcommand{\modblocking}{\module{mod\_blocking}} \newcommand{\modblockingodbc}{\module{mod\_blocking\_odbc}} \newcommand{\modcaps}{\module{mod\_caps}} \newcommand{\modconfigure}{\module{mod\_configure}} \newcommand{\moddisco}{\module{mod\_disco}} \newcommand{\modecho}{\module{mod\_echo}} \newcommand{\modhttpbind}{\module{mod\_http\_bind}} \newcommand{\modhttpfileserver}{\module{mod\_http\_fileserver}} \newcommand{\modirc}{\module{mod\_irc}} \newcommand{\modircodbc}{\module{mod\_irc\_odbc}} \newcommand{\modlast}{\module{mod\_last}} \newcommand{\modlastodbc}{\module{mod\_last\_odbc}} \newcommand{\modmuc}{\module{mod\_muc}} \newcommand{\modmucodbc}{\module{mod\_muc\_odbc}} \newcommand{\modmuclog}{\module{mod\_muc\_log}} \newcommand{\modoffline}{\module{mod\_offline}} \newcommand{\modofflineodbc}{\module{mod\_offline\_odbc}} \newcommand{\modping}{\module{mod\_ping}} \newcommand{\modprescounter}{\module{mod\_pres\_counter}} \newcommand{\modprivacy}{\module{mod\_privacy}} \newcommand{\modprivacyodbc}{\module{mod\_privacy\_odbc}} \newcommand{\modprivate}{\module{mod\_private}} \newcommand{\modprivateodbc}{\module{mod\_private\_odbc}} \newcommand{\modproxy}{\module{mod\_proxy65}} \newcommand{\modpubsub}{\module{mod\_pubsub}} \newcommand{\modpubsubodbc}{\module{mod\_pubsub\_odbc}} \newcommand{\modregister}{\module{mod\_register}} \newcommand{\modregisterweb}{\module{mod\_register\_web}} \newcommand{\modroster}{\module{mod\_roster}} \newcommand{\modrosterodbc}{\module{mod\_roster\_odbc}} \newcommand{\modservicelog}{\module{mod\_service\_log}} \newcommand{\modsharedroster}{\module{mod\_shared\_roster}} \newcommand{\modsharedrosterodbc}{\module{mod\_shared\_roster\_odbc}} \newcommand{\modsharedrosterldap}{\module{mod\_shared\_roster\_ldap}} \newcommand{\modsic}{\module{mod\_sic}} \newcommand{\modstats}{\module{mod\_stats}} \newcommand{\modtime}{\module{mod\_time}} \newcommand{\modvcard}{\module{mod\_vcard}} \newcommand{\modvcardldap}{\module{mod\_vcard\_ldap}} \newcommand{\modvcardodbc}{\module{mod\_vcard\_odbc}} \newcommand{\modvcardxupdate}{\module{mod\_vcard\_xupdate}} \newcommand{\modvcardxupdateodbc}{\module{mod\_vcard\_xupdate\_odbc}} \newcommand{\modversion}{\module{mod\_version}} %% Contributed modules %\usepackage{ifthen} %\newboolean{modhttpbind} %\newcommand{\modhttpbind}{\module{mod\_http\_bind}} %\include{contributed_modules} % % Then in the document you can input the partial tex file with: %\ifthenelse{\boolean{modhttpbind}}{\input{mod_http_bind.tex}}{} %% Common options \newcommand{\iqdiscitem}[1]{\titem{\{iqdisc, Discipline\}} \ind{options!iqdisc}This specifies the processing discipline for #1 IQ queries (see section~\ref{modiqdiscoption}).} \newcommand{\hostitem}[1]{ \titem{\{host, HostName\}} \ind{options!host} This option defines the Jabber ID of the service. If the \texttt{host} option is not specified, the Jabber ID will be the hostname of the virtual host with the prefix `\jid{#1.}'. The keyword "@HOST@" is replaced at start time with the real virtual host name. } %% Title page \include{version} \newlength{\larg} \setlength{\larg}{14.5cm} \title{ {\rule{\larg}{1mm}}\vspace{7mm} \begin{tabular}{r} {\huge {\bf ejabberd \version\ }} \\ \\ {\huge Installation and Operation Guide} \end{tabular}\\ \vspace{2mm} {\rule{\larg}{1mm}} \begin{latexonly} \vspace{2mm} \\ \vspace{5.5cm} \end{latexonly} } \begin{latexonly} \author{\begin{tabular}{p{13.7cm}} ejabberd Development Team \end{tabular}} \date{} \end{latexonly} %% Options \newcommand{\marking}[1]{#1} % Marking disabled \newcommand{\quoting}[2][yozhik]{} % Quotes disabled %\newcommand{\new}{\marginpar{\textsc{new}}} % Highlight new features %\newcommand{\improved}{\marginpar{\textsc{improved}}} % Highlight improved features %% To by-pass errors in the HTML version: \newstyle{.SPAN}{width:20\%; float:right; text-align:left; margin-left:auto;} \newstyle{H1.titlemain HR}{display:none;} \newstyle{TABLE.title}{border-top:1px solid grey;border-bottom:1px solid grey; background: \#efefef} \newstyle{H1.chapter A, H2.section A, H3.subsection A, H4.subsubsection A, H5.paragraph A} {color:\#000000; text-decoration:none;} \newstyle{H1.chapter, H2.section, H3.subsection, H4.subsubsection, H5.paragraph} {border-top: 1px solid grey; background: \#efefef; padding: 0.5ex} \newstyle{pre.verbatim}{margin:1ex 2ex;border:1px dashed lightgrey;background-color:\#f9f9f9;padding:0.5ex;} \newstyle{.dt-description}{margin:0ex 2ex;} \newstyle{table[border="1"]}{border-collapse:collapse;margin-bottom:1em;} \newstyle{table[border="1"] td}{border:1px solid \#aaa;padding:2px} % Don't display
    before and after tables or images: \newstyle{BLOCKQUOTE.table DIV.center DIV.center HR}{display:none;} \newstyle{BLOCKQUOTE.figure DIV.center DIV.center HR}{display:none;} %% Footnotes \begin{latexonly} \global\parskip=9pt plus 3pt minus 1pt \global\parindent=0pt \gdef\ahrefurl#1{\href{#1}{\texttt{#1}}} \gdef\footahref#1#2{#2\footnote{\href{#1}{\texttt{#1}}}} \end{latexonly} \newcommand{\txepref}[2]{\footahref{http://xmpp.org/extensions/xep-#1.html}{#2}} \newcommand{\xepref}[1]{\txepref{#1}{XEP-#1}} \begin{document} \label{titlepage} \begin{titlepage} \maketitle{} %% Commenting. Breaking clean layout for now: %% \begin{center} %% {\insscaleimg{\logoscale}{logo.png} %% \par %% } %% \end{center} %% \begin{quotation}\textit{I can thoroughly recommend ejabberd for ease of setup --- %% Kevin Smith, Current maintainer of the Psi project}\end{quotation} \end{titlepage} % Set the page counter to 2 so that the titlepage and the second page do not % have the same page number. This fixes the PDFLaTeX warning "destination with % the same identifier". \begin{latexonly} \setcounter{page}{2} \end{latexonly} \label{toc} \tableofcontents{} % Input introduction.tex \input{introduction} \makechapter{installing}{Installing \ejabberd{}} \makesection{install.binary}{Installing \ejabberd{} with Binary Installer} Probably the easiest way to install an \ejabberd{} instant messaging server is using the binary installer published by ProcessOne. The binary installers of released \ejabberd{} versions are available in the ProcessOne \ejabberd{} downloads page: \ahrefurl{http://www.process-one.net/en/ejabberd/downloads} The installer will deploy and configure a full featured \ejabberd{} server and does not require any extra dependencies. In *nix systems, remember to set executable the binary installer before starting it. For example: \begin{verbatim} chmod +x ejabberd-2.0.0_1-linux-x86-installer.bin ./ejabberd-2.0.0_1-linux-x86-installer.bin \end{verbatim} \ejabberd{} can be started manually at any time, or automatically by the operating system at system boot time. To start and stop \ejabberd{} manually, use the desktop shortcuts created by the installer. If the machine doesn't have a graphical system, use the scripts 'start' and 'stop' in the 'bin' directory where \ejabberd{} is installed. The Windows installer also adds ejabberd as a system service, and a shortcut to a debug console for experienced administrators. If you want ejabberd to be started automatically at boot time, go to the Windows service settings and set ejabberd to be automatically started. Note that the Windows service is a feature still in development, and for example it doesn't read the file ejabberdctl.cfg. On a *nix system, if you want ejabberd to be started as daemon at boot time, copy \term{ejabberd.init} from the 'bin' directory to something like \term{/etc/init.d/ejabberd} (depending on your distribution). Create a system user called \term{ejabberd}, give it write access to the directories \term{database/} and \term{logs/}, and set that as home; the script will start the server with that user. Then you can call \term{/etc/inid.d/ejabberd start} as root to start the server. If \term{ejabberd} doesn't start correctly in Windows, try to start it using the shortcut in desktop or start menu. If the window shows error 14001, the solution is to install: "Microsoft Visual C++ 2005 SP1 Redistributable Package". You can download it from \footahref{http://www.microsoft.com/}{www.microsoft.com}. Then uninstall \ejabberd{} and install it again. If \term{ejabberd} doesn't start correctly and a crash dump is generated, there was a severe problem. You can try starting \term{ejabberd} with the script \term{bin/live.bat} in Windows, or with the command \term{bin/ejabberdctl live} in other Operating Systems. This way you see the error message provided by Erlang and can identify what is exactly the problem. The \term{ejabberdctl} administration script is included in the \term{bin} directory. Please refer to the section~\ref{ejabberdctl} for details about \term{ejabberdctl}, and configurable options to fine tune the Erlang runtime system. \makesection{install.os}{Installing \ejabberd{} with Operating System Specific Packages} Some Operating Systems provide a specific \ejabberd{} package adapted to the system architecture and libraries. It usually also checks dependencies and performs basic configuration tasks like creating the initial administrator account. Some examples are Debian and Gentoo. Consult the resources provided by your Operating System for more information. Usually those packages create a script like \term{/etc/init.d/ejabberd} to start and stop \ejabberd{} as a service at boot time. \makesection{install.cean}{Installing \ejabberd{} with CEAN} \footahref{http://cean.process-one.net/}{CEAN} (Comprehensive Erlang Archive Network) is a repository that hosts binary packages from many Erlang programs, including \ejabberd{} and all its dependencies. The binaries are available for many different system architectures, so this is an alternative to the binary installer and Operating System's \ejabberd{} packages. You will have to create your own \ejabberd{} start script depending of how you handle your CEAN installation. The default \term{ejabberdctl} script is located into \ejabberd{}'s priv directory and can be used as an example. \makesection{installation}{Installing \ejabberd{} from Source Code} \ind{install} The canonical form for distribution of \ejabberd{} stable releases is the source code package. Compiling \ejabberd{} from source code is quite easy in *nix systems, as long as your system have all the dependencies. \makesubsection{installreq}{Requirements} \ind{installation!requirements} To compile \ejabberd{} on a `Unix-like' operating system, you need: \begin{itemize} \item GNU Make \item GCC \item Libexpat 1.95 or higher \item Erlang/OTP R10B-9 or higher. The recommended versions are R13B04 and R14B04. Don't use R14A or R14B because \footahref{http://www.erlang.org/cgi-bin/ezmlm-cgi/4/54598}{they have a bug}. \item OpenSSL 0.9.8 or higher, for STARTTLS, SASL and SSL encryption. \item Zlib 1.2.3 or higher, for Stream Compression support (\xepref{0138}). Optional. \item Erlang mysql library. Optional. For MySQL authentication or storage. See section \ref{compilemysql}. \item Erlang pgsql library. Optional. For PostgreSQL authentication or storage. See section \ref{compilepgsql}. \item PAM library. Optional. For Pluggable Authentication Modules (PAM). See section \ref{pam}. \item GNU Iconv 1.8 or higher, for the IRC Transport (mod\_irc). Optional. Not needed on systems with GNU Libc. See section \ref{modirc}. \item ImageMagick's Convert program. Optional. For CAPTCHA challenges. See section \ref{captcha}. \item exmpp 0.9.6 or higher. Optional. For import/export user data with \xepref{0227} XML files. \end{itemize} \makesubsection{download}{Download Source Code} \ind{install!download} Released versions of \ejabberd{} are available in the ProcessOne \ejabberd{} downloads page: \ahrefurl{http://www.process-one.net/en/ejabberd/downloads} \ind{Git repository} Alternatively, the latest development source code can be retrieved from the Git repository using the commands: \begin{verbatim} git clone git://git.process-one.net/ejabberd/mainline.git ejabberd cd ejabberd git checkout -b 2.1.x origin/2.1.x \end{verbatim} \makesubsection{compile}{Compile} \ind{install!compile} To compile \ejabberd{} execute the commands: \begin{verbatim} ./configure make \end{verbatim} The build configuration script allows several options. To get the full list run the command: \begin{verbatim} ./configure --help \end{verbatim} Some options that you may be interested in modifying: \begin{description} \titem{--prefix=/} Specify the path prefix where the files will be copied when running the \term{make install} command. \titem{--enable-user[=USER]} Allow this normal system user to execute the ejabberdctl script (see section~\ref{ejabberdctl}), read the configuration files, read and write in the spool directory, read and write in the log directory. The account user and group must exist in the machine before running \term{make install}. This account doesn't need an explicit HOME directory, because \term{/var/lib/ejabberd/} will be used by default. \titem{--enable-pam} Enable the PAM authentication method (see section \ref{pam}). \titem{--enable-odbc or --enable-mssql} Required if you want to use an external database. See section~\ref{database} for more information. \titem{--enable-full-xml} Enable the use of XML based optimisations. It will for example use CDATA to escape characters in the XMPP stream. Use this option only if you are sure your XMPP clients include a fully compliant XML parser. \titem{--disable-transient-supervisors} Disable the use of Erlang/OTP supervision for transient processes. \titem{--enable-nif} Replaces some critical Erlang functions with equivalents written in C to improve performance. This feature requires Erlang/OTP R13B04 or higher. \end{description} \makesubsection{install}{Install} \ind{install!install} To install \ejabberd{} in the destination directories, run the command: \begin{verbatim} make install \end{verbatim} Note that you probably need administrative privileges in the system to install \term{ejabberd}. The files and directories created are, by default: \begin{description} \titem{/etc/ejabberd/} Configuration directory: \begin{description} \titem{ejabberd.cfg} ejabberd configuration file \titem{ejabberdctl.cfg} Configuration file of the administration script \titem{inetrc} Network DNS configuration file \end{description} \titem{/lib/ejabberd/} \begin{description} \titem{ebin/} Erlang binary files (*.beam) \titem{include/} Erlang header files (*.hrl) \titem{priv/} Additional files required at runtime \begin{description} \titem{bin/} Executable programs \titem{lib/} Binary system libraries (*.so) \titem{msgs/} Translation files (*.msgs) \end{description} \end{description} \titem{/sbin/ejabberdctl} Administration script (see section~\ref{ejabberdctl}) \titem{/share/doc/ejabberd/} Documentation of ejabberd \titem{/var/lib/ejabberd/} Spool directory: \begin{description} \titem{.erlang.cookie} Erlang cookie file (see section \ref{cookie}) \titem{acl.DCD, ...} Mnesia database spool files (*.DCD, *.DCL, *.DAT) \end{description} \titem{/var/log/ejabberd/} Log directory (see section~\ref{logfiles}): \begin{description} \titem{ejabberd.log} ejabberd service log \titem{erlang.log} Erlang/OTP system log \end{description} \end{description} \makesubsection{start}{Start} \ind{install!start} You can use the \term{ejabberdctl} command line administration script to start and stop \ejabberd{}. If you provided the configure option \term{--enable-user=USER} (see \ref{compile}), you can execute \term{ejabberdctl} with either that system account or root. Usage example: \begin{verbatim} ejabberdctl start ejabberdctl status The node ejabberd@localhost is started with status: started ejabberd is running in that node ejabberdctl stop \end{verbatim} If \term{ejabberd} doesn't start correctly and a crash dump is generated, there was a severe problem. You can try starting \term{ejabberd} with the command \term{ejabberdctl live} to see the error message provided by Erlang and can identify what is exactly the problem. Please refer to the section~\ref{ejabberdctl} for details about \term{ejabberdctl}, and configurable options to fine tune the Erlang runtime system. If you want ejabberd to be started as daemon at boot time, copy \term{ejabberd.init} to something like \term{/etc/init.d/ejabberd} (depending on your distribution). Create a system user called \term{ejabberd}; it will be used by the script to start the server. Then you can call \term{/etc/inid.d/ejabberd start} as root to start the server. \makesubsection{bsd}{Specific Notes for BSD} \ind{install!bsd} The command to compile \ejabberd{} in BSD systems is: \begin{verbatim} gmake \end{verbatim} \makesubsection{solaris}{Specific Notes for Sun Solaris} \ind{install!solaris} You need to have \term{GNU install}, but it isn't included in Solaris. It can be easily installed if your Solaris system is set up for \footahref{http://www.blastwave.org/}{blastwave.org} package repository. Make sure \term{/opt/csw/bin} is in your \term{PATH} and run: \begin{verbatim} pkg-get -i fileutils \end{verbatim} If that program is called \term{ginstall}, modify the \ejabberd{} \term{Makefile} script to suit your system, for example: \begin{verbatim} cat Makefile | sed s/install/ginstall/ > Makefile.gi \end{verbatim} And finally install \ejabberd{} with: \begin{verbatim} gmake -f Makefile.gi ginstall \end{verbatim} \makesubsection{windows}{Specific Notes for Microsoft Windows} \ind{install!windows} \makesubsubsection{windowsreq}{Requirements} To compile \ejabberd{} on a Microsoft Windows system, you need: \begin{itemize} \item MS Visual C++ 6.0 Compiler \item \footahref{http://www.erlang.org/download.html}{Erlang/OTP R11B-5} \item \footahref{http://sourceforge.net/project/showfiles.php?group\_id=10127\&package\_id=11277}{Expat 2.0.0 or higher} \item \footahref{http://www.gnu.org/software/libiconv/}{GNU Iconv 1.9.2} (optional) \item \footahref{http://www.slproweb.com/products/Win32OpenSSL.html}{Shining Light OpenSSL 0.9.8d or higher} (to enable SSL connections) \item \footahref{http://www.zlib.net/}{Zlib 1.2.3 or higher} \end{itemize} \makesubsubsection{windowscom}{Compilation} We assume that we will try to put as much library as possible into \verb|C:\sdk\| to make it easier to track what is install for \ejabberd{}. \begin{enumerate} \item Install Erlang emulator (for example, into \verb|C:\sdk\erl5.5.5|). \item Install Expat library into \verb|C:\sdk\Expat-2.0.0| directory. Copy file \verb|C:\sdk\Expat-2.0.0\Libs\libexpat.dll| to your Windows system directory (for example, \verb|C:\WINNT| or \verb|C:\WINNT\System32|) \item Build and install the Iconv library into the directory \verb|C:\sdk\GnuWin32|. Copy file \verb|C:\sdk\GnuWin32\bin\lib*.dll| to your Windows system directory (more installation instructions can be found in the file README.woe32 in the iconv distribution). Note: instead of copying libexpat.dll and iconv.dll to the Windows directory, you can add the directories \verb|C:\sdk\Expat-2.0.0\Libs| and \verb|C:\sdk\GnuWin32\bin| to the \verb|PATH| environment variable. \item Install OpenSSL in \verb|C:\sdk\OpenSSL| and add \verb|C:\sdk\OpenSSL\lib\VC| to your path or copy the binaries to your system directory. \item Install ZLib in \verb|C:\sdk\gnuWin32|. Copy \verb|C:\sdk\GnuWin32\bin\zlib1.dll| to your system directory. If you change your path it should already be set after libiconv install. \item Make sure the you can access Erlang binaries from your path. For example: \verb|set PATH=%PATH%;"C:\sdk\erl5.6.5\bin"| \item Depending on how you end up actually installing the library you might need to check and tweak the paths in the file configure.erl. \item While in the directory \verb|ejabberd\src| run: \begin{verbatim} configure.bat nmake -f Makefile.win32 \end{verbatim} \item Edit the file \verb|ejabberd\src\ejabberd.cfg| and run \begin{verbatim} werl -s ejabberd -name ejabberd \end{verbatim} \end{enumerate} %TODO: how to compile database support on windows? \makesection{initialadmin}{Create an XMPP Account for Administration} You need an XMPP account and grant him administrative privileges to enter the \ejabberd{} Web Admin: \begin{enumerate} \item Register an XMPP account on your \ejabberd{} server, for example \term{admin1@example.org}. There are two ways to register an XMPP account: \begin{enumerate} \item Using \term{ejabberdctl}\ind{ejabberdctl} (see section~\ref{ejabberdctl}): \begin{verbatim} ejabberdctl register admin1 example.org FgT5bk3 \end{verbatim} \item Using an XMPP client and In-Band Registration (see section~\ref{modregister}). \end{enumerate} \item Edit the \ejabberd{} configuration file to give administration rights to the XMPP account you created: \begin{verbatim} {acl, admin, {user, "admin1", "example.org"}}. {access, configure, [{allow, admin}]}. \end{verbatim} You can grant administrative privileges to many XMPP accounts, and also to accounts in other XMPP servers. \item Restart \ejabberd{} to load the new configuration. \item Open the Web Admin (\verb|http://server:port/admin/|) in your favourite browser. Make sure to enter the \emph{full} JID as username (in this example: \jid{admin1@example.org}. The reason that you also need to enter the suffix, is because \ejabberd{}'s virtual hosting support. \end{enumerate} \makesection{upgrade}{Upgrading \ejabberd{}} To upgrade an ejabberd installation to a new version, simply uninstall the old version, and then install the new one. Of course, it is important that the configuration file and Mnesia database spool directory are not removed. \ejabberd{} automatically updates the Mnesia table definitions at startup when needed. If you also use an external database for storage of some modules, check if the release notes of the new ejabberd version indicates you need to also update those tables. \makechapter{configure}{Configuring \ejabberd{}} \ind{configuration file} \makesection{basicconfig}{Basic Configuration} The configuration file will be loaded the first time you start \ejabberd{}. The content from this file will be parsed and stored in the internal \ejabberd{} database. Subsequently the configuration will be loaded from the database and any commands in the configuration file are appended to the entries in the database. Note that \ejabberd{} never edits the configuration file. So, the configuration changes done using the Web Admin are stored in the database, but are not reflected in the configuration file. If you want those changes to be use after \ejabberd{} restart, you can either edit the configuration file, or remove all its content. The configuration file contains a sequence of Erlang terms. Lines beginning with a \term{`\%'} sign are ignored. Each term is a tuple of which the first element is the name of an option, and any further elements are that option's values. If the configuration file do not contain for instance the `hosts' option, the old host name(s) stored in the database will be used. You can override the old values stored in the database by adding next lines to the beginning of the configuration file: \begin{verbatim} override_global. override_local. override_acls. \end{verbatim} With these lines the old global options (shared between all \ejabberd{} nodes in a cluster), local options (which are specific for this particular \ejabberd{} node) and ACLs will be removed before new ones are added. \makesubsection{hostnames}{Host Names} \ind{options!hosts}\ind{host names} The option \option{hosts} defines a list containing one or more domains that \ejabberd{} will serve. The syntax is: \esyntax{\{hosts, [HostName, ...]\}.} Examples: \begin{itemize} \item Serving one domain: \begin{verbatim} {hosts, ["example.org"]}. \end{verbatim} \item Serving three domains: \begin{verbatim} {hosts, ["example.net", "example.com", "jabber.somesite.org"]}. \end{verbatim} \end{itemize} \makesubsection{virtualhost}{Virtual Hosting} \ind{virtual hosting}\ind{virtual hosts}\ind{virtual domains} Options can be defined separately for every virtual host using the \term{host\_config} option. The syntax is: \ind{options!host\_config} \esyntax{\{host\_config, HostName, [Option, ...]\}} Examples: \begin{itemize} \item Domain \jid{example.net} is using the internal authentication method while domain \jid{example.com} is using the \ind{LDAP}LDAP server running on the domain \jid{localhost} to perform authentication: \begin{verbatim} {host_config, "example.net", [{auth_method, internal}]}. {host_config, "example.com", [{auth_method, ldap}, {ldap_servers, ["localhost"]}, {ldap_uids, [{"uid"}]}, {ldap_rootdn, "dc=localdomain"}, {ldap_rootdn, "dc=example,dc=com"}, {ldap_password, ""}]}. \end{verbatim} \item Domain \jid{example.net} is using \ind{ODBC}ODBC to perform authentication while domain \jid{example.com} is using the LDAP servers running on the domains \jid{localhost} and \jid{otherhost}: \begin{verbatim} {host_config, "example.net", [{auth_method, odbc}, {odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}]}. {host_config, "example.com", [{auth_method, ldap}, {ldap_servers, ["localhost", "otherhost"]}, {ldap_uids, [{"uid"}]}, {ldap_rootdn, "dc=localdomain"}, {ldap_rootdn, "dc=example,dc=com"}, {ldap_password, ""}]}. \end{verbatim} \end{itemize} To define specific ejabberd modules in a virtual host, you can define the global \term{modules} option with the common modules, and later add specific modules to certain virtual hosts. To accomplish that, instead of defining each option in \term{host\_config} with the general syntax \esyntax{\{OptionName, OptionValue\}} use this syntax: \esyntax{\{\{add, OptionName\}, OptionValue\}} In this example three virtual hosts have some similar modules, but there are also other different modules for some specific virtual hosts: \begin{verbatim} %% This ejabberd server has three vhosts: {hosts, ["one.example.org", "two.example.org", "three.example.org"]}. %% Configuration of modules that are common to all vhosts {modules, [ {mod_roster, []}, {mod_configure, []}, {mod_disco, []}, {mod_private, []}, {mod_time, []}, {mod_last, []}, {mod_version, []} ]}. %% Add some modules to vhost one: {host_config, "one.example.org", [{{add, modules}, [ {mod_echo, [{host, "echo-service.one.example.org"}]} {mod_http_bind, []}, {mod_logxml, []} ] } ]}. %% Add a module just to vhost two: {host_config, "two.example.org", [{{add, modules}, [ {mod_echo, [{host, "mirror.two.example.org"}]} ] } ]}. \end{verbatim} \makesubsection{listened}{Listening Ports} \ind{options!listen} The option \option{listen} defines for which ports, addresses and network protocols \ejabberd{} will listen and what services will be run on them. Each element of the list is a tuple with the following elements: \begin{itemize} \item Port number. Optionally also the IP address and/or a transport protocol. \item Listening module that serves this port. \item Options for the TCP socket and for the listening module. \end{itemize} The option syntax is: \esyntax{\{listen, [Listener, ...]\}.} To define a listener there are several syntax. \esyntax{\{PortNumber, Module, [Option, ...]\}} \esyntax{\{\{PortNumber, IPaddress\}, Module, [Option, ...]\}} \esyntax{\{\{PortNumber, TransportProtocol\}, Module, [Option, ...]\}} \esyntax{\{\{PortNumber, IPaddress, TransportProtocol\}, Module, [Option, ...]\}} \makesubsubsection{listened-port}{Port Number, IP Address and Transport Protocol} The port number defines which port to listen for incoming connections. It can be a Jabber/XMPP standard port (see section \ref{firewall}) or any other valid port number. The IP address can be represented with a string or an Erlang tuple with decimal or hexadecimal numbers. The socket will listen only in that network interface. It is possible to specify a generic address, so \ejabberd{} will listen in all addresses. Depending in the type of the IP address, IPv4 or IPv6 will be used. When not specified the IP address, it will listen on all IPv4 network addresses. Some example values for IP address: \begin{itemize} \item \verb|"0.0.0.0"| to listen in all IPv4 network interfaces. This is the default value when no IP is specified. \item \verb|"::"| to listen in all IPv6 network interfaces \item \verb|"10.11.12.13"| is the IPv4 address \verb|10.11.12.13| \item \verb|"::FFFF:127.0.0.1"| is the IPv6 address \verb|::FFFF:127.0.0.1/128| \item \verb|{10, 11, 12, 13}| is the IPv4 address \verb|10.11.12.13| \item \verb|{0, 0, 0, 0, 0, 65535, 32512, 1}| is the IPv6 address \verb|::FFFF:127.0.0.1/128| \item \verb|{16#fdca, 16#8ab6, 16#a243, 16#75ef, 0, 0, 0, 1}| is the IPv6 address \verb|FDCA:8AB6:A243:75EF::1/128| \end{itemize} The transport protocol can be \term{tcp} or \term{udp}. Default is \term{tcp}. \makesubsubsection{listened-module}{Listening Module} \ind{modules!ejabberd\_c2s}\ind{modules!ejabberd\_s2s\_in}\ind{modules!ejabberd\_service}\ind{modules!ejabberd\_http}\ind{protocols!XEP-0114: Jabber Component Protocol} The available modules, their purpose and the options allowed by each one are: \begin{description} \titem{\texttt{ejabberd\_c2s}} Handles c2s connections.\\ Options: \texttt{access}, \texttt{certfile}, \texttt{max\_fsm\_queue}, \texttt{max\_stanza\_size}, \texttt{shaper}, \texttt{starttls}, \texttt{starttls\_required}, \texttt{tls}, \texttt{zlib} \titem{\texttt{ejabberd\_s2s\_in}} Handles incoming s2s connections.\\ Options: \texttt{max\_stanza\_size}, \texttt{shaper} \titem{\texttt{ejabberd\_service}} Interacts with an \footahref{http://www.ejabberd.im/tutorials-transports}{external component} (as defined in the Jabber Component Protocol (\xepref{0114}).\\ Options: \texttt{access}, \texttt{hosts}, \texttt{max\_fsm\_queue}, \texttt{service\_check\_from}, \texttt{shaper} \titem{\texttt{ejabberd\_stun}} Handles STUN Binding requests as defined in \footahref{http://tools.ietf.org/html/rfc5389}{RFC 5389}.\\ Options: \texttt{certfile} \titem{\texttt{ejabberd\_http}} Handles incoming HTTP connections.\\ Options: \texttt{captcha}, \texttt{certfile}, \texttt{default\_host}, \texttt{http\_bind}, \texttt{http\_poll}, \texttt{request\_handlers}, \texttt{tls}, \texttt{trusted\_proxies}, \texttt{web\_admin}\\ \end{description} \makesubsubsection{listened-options}{Options} This is a detailed description of each option allowed by the listening modules: \begin{description} \titem{\{access, AccessName\}} \ind{options!access}This option defines access to the port. The default value is \term{all}. \titem{\{backlog, Value\}} \ind{options!backlog}The backlog value defines the maximum length that the queue of pending connections may grow to. This should be increased if the server is going to handle lots of new incoming connections as they may be dropped if there is no space in the queue (and ejabberd was not able to accept them immediately). Default value is 5. \titem{captcha} \ind{options!http-captcha} Simple web page that allows a user to fill a CAPTCHA challenge (see section \ref{captcha}). \titem{\{certfile, Path\}} Full path to a file containing the default SSL certificate. To define a certificate file specific for a given domain, use the global option \term{domain\_certfile}. \titem{\{default\_host, undefined|HostName\}} If the HTTP request received by ejabberd contains the HTTP header \term{Host} with an ambiguous virtual host that doesn't match any one defined in ejabberd (see \ref{hostnames}), then this configured HostName is set as the request Host. The default value of this option is: \term{undefined}. \titem{\{hosts, [Hostname, ...], [HostOption, ...]\}} \ind{options!hosts} The external Jabber component that connects to this \term{ejabberd\_service} can serve one or more hostnames. As \term{HostOption} you can define options for the component; currently the only allowed option is the password required to the component when attempt to connect to ejabberd: \poption{\{password, Secret\}}. Note that you cannot define in a single \term{ejabberd\_service} components of different services: add an \term{ejabberd\_service} for each service, as seen in an example below. \titem{http\_bind} \ind{options!http\_bind}\ind{protocols!XEP-0206: HTTP Binding}\ind{JWChat}\ind{web-based XMPP client} This option enables HTTP Binding (\xepref{0124} and \xepref{0206}) support. HTTP Bind enables access via HTTP requests to \ejabberd{} from behind firewalls which do not allow outgoing sockets on port 5222. Remember that you must also install and enable the module mod\_http\_bind. If HTTP Bind is enabled, it will be available at \verb|http://server:port/http-bind/|. Be aware that support for HTTP Bind is also needed in the \XMPP{} client. Remark also that HTTP Bind can be interesting to host a web-based \XMPP{} client such as \footahref{http://jwchat.sourceforge.net/}{JWChat} (check the tutorials to install JWChat with ejabberd and an \footahref{http://www.ejabberd.im/jwchat-localserver}{embedded local web server} or \footahref{http://www.ejabberd.im/jwchat-apache}{Apache}). \titem{http\_poll} \ind{options!http\_poll}\ind{protocols!XEP-0025: HTTP Polling}\ind{JWChat}\ind{web-based XMPP client} This option enables HTTP Polling (\xepref{0025}) support. HTTP Polling enables access via HTTP requests to \ejabberd{} from behind firewalls which do not allow outgoing sockets on port 5222. If HTTP Polling is enabled, it will be available at \verb|http://server:port/http-poll/|. Be aware that support for HTTP Polling is also needed in the \XMPP{} client. Remark also that HTTP Polling can be interesting to host a web-based \XMPP{} client such as \footahref{http://jwchat.sourceforge.net/}{JWChat}. The maximum period of time to keep a client session active without an incoming POST request can be configured with the global option \term{http\_poll\_timeout}. The default value is five minutes. The option can be defined in \term{ejabberd.cfg}, expressing the time in seconds: \verb|{http_poll_timeout, 300}.| \titem{\{max\_fsm\_queue, Size\}} This option specifies the maximum number of elements in the queue of the FSM (Finite State Machine). Roughly speaking, each message in such queues represents one XML stanza queued to be sent into its relevant outgoing stream. If queue size reaches the limit (because, for example, the receiver of stanzas is too slow), the FSM and the corresponding connection (if any) will be terminated and error message will be logged. The reasonable value for this option depends on your hardware configuration. However, there is no much sense to set the size above 1000 elements. This option can be specified for \term{ejabberd\_service} and \term{ejabberd\_c2s} listeners, or also globally for \term{ejabberd\_s2s\_out}. If the option is not specified for \term{ejabberd\_service} or \term{ejabberd\_c2s} listeners, the globally configured value is used. The allowed values are integers and 'undefined'. Default value: 'undefined'. \titem{\{max\_stanza\_size, Size\}} \ind{options!max\_stanza\_size}This option specifies an approximate maximum size in bytes of XML stanzas. Approximate, because it is calculated with the precision of one block of read data. For example \verb|{max_stanza_size, 65536}|. The default value is \term{infinity}. Recommended values are 65536 for c2s connections and 131072 for s2s connections. s2s max stanza size must always much higher than c2s limit. Change this value with extreme care as it can cause unwanted disconnect if set too low. \titem{\{request\_handlers, [ \{Path, Module\}, ...]\}} To define one or several handlers that will serve HTTP requests. The Path is a list of strings; so the URIs that start with that Path will be served by Module. For example, if you want \term{mod\_foo} to serve the URIs that start with \term{/a/b/}, and you also want \term{mod\_http\_bind} to serve the URIs \term{/http-bind/}, use this option: \term{\{request\_handlers, [\{["a", "b"], mod\_foo\}, \{["http-bind"], mod\_http\_bind\}]\}} \titem{\{service\_check\_from, true|false\}} \ind{options!service\_check\_from} This option can be used with \term{ejabberd\_service} only. \xepref{0114} requires that the domain must match the hostname of the component. If this option is set to \term{false}, \ejabberd{} will allow the component to send stanzas with any arbitrary domain in the 'from' attribute. Only use this option if you are completely sure about it. The default value is \term{true}, to be compliant with \xepref{0114}. \titem{\{shaper, none|ShaperName\}} \ind{options!shaper}This option defines a shaper for the port (see section~\ref{shapers}). The default value is \term{none}. \titem{starttls} \ind{options!starttls}\ind{STARTTLS}This option specifies that STARTTLS encryption is available on connections to the port. You should also set the \option{certfile} option. You can define a certificate file for a specific domain using the global option \option{domain\_certfile}. \titem{starttls\_required} \ind{options!starttls\_required}This option specifies that STARTTLS encryption is required on connections to the port. No unencrypted connections will be allowed. You should also set the \option{certfile} option. You can define a certificate file for a specific domain using the global option \option{domain\_certfile}. \titem{tls} \ind{options!tls}\ind{TLS}This option specifies that traffic on the port will be encrypted using SSL immediately after connecting. This was the traditional encryption method in the early Jabber software, commonly on port 5223 for client-to-server communications. But this method is nowadays deprecated and not recommended. The preferable encryption method is STARTTLS on port 5222, as defined \footahref{http://xmpp.org/rfcs/rfc3920.html\#tls}{RFC 3920: XMPP Core}, which can be enabled in \ejabberd{} with the option \term{starttls}. If this option is set, you should also set the \option{certfile} option. The option \term{tls} can also be used in \term{ejabberd\_http} to support HTTPS. \titem{\{trusted\_proxies, all | [IpString]\}} \ind{options!trusted\_proxies} Specify what proxies are trusted when an HTTP request contains the header \term{X-Forwarded-For} You can specify \term{all} to allow all proxies, or specify a list of IPs in string format. The default value is: \term{["127.0.0.1"]} \titem{web\_admin} \ind{options!web\_admin}\ind{web admin}This option enables the Web Admin for \ejabberd{} administration which is available at \verb|http://server:port/admin/|. Login and password are the username and password of one of the registered users who are granted access by the `configure' access rule. \titem{zlib} \ind{options!zlib}\ind{protocols!XEP-0138: Stream Compression}\ind{Zlib}This option specifies that Zlib stream compression (as defined in \xepref{0138}) is available on connections to the port. \end{description} There are some additional global options that can be specified in the ejabberd configuration file (outside \term{listen}): \begin{description} \titem{\{s2s\_use\_starttls, false|optional|required|required\_trusted\}} \ind{options!s2s\_use\_starttls}\ind{STARTTLS}This option defines if s2s connections don't use STARTTLS encryption; if STARTTLS can be used optionally; if STARTTLS is required to establish the connection; or if STARTTLS is required and the remote certificate must be valid and trusted. The default value is to not use STARTTLS: \term{false}. \titem{\{s2s\_certfile, Path\}} \ind{options!s2s\_certificate}Full path to a file containing a SSL certificate. \titem{\{domain\_certfile, Domain, Path\}} \ind{options!domain\_certfile} Full path to the file containing the SSL certificate for a specific domain. \titem{\{outgoing\_s2s\_options, [Family, ...], Timeout\}} \ind{options!outgoing\_s2s\_options} Specify which address families to try, in what order, and connect timeout in milliseconds. By default it first tries connecting with IPv4, if that fails it tries using IPv6, with a timeout of 10000 milliseconds. \titem{\{s2s\_dns\_options, [ \{Property, Value\}, ...]\}} \ind{options!s2s\_dns\_options}Define properties to use for DNS resolving. Allowed Properties are: \term{timeout} in seconds which default value is \term{10} and \term{retries} which default value is \term{2}. \titem{\{s2s\_default\_policy, allow|deny\}} The default policy for incoming and outgoing s2s connections to other XMPP servers. The default value is \term{allow}. \titem{\{\{s2s\_host, Host\}, allow|deny\}} Defines if incoming and outgoing s2s connections with a specific remote host are allowed or denied. This allows to restrict ejabberd to only establish s2s connections with a small list of trusted servers, or to block some specific servers. \titem{\{s2s\_max\_retry\_delay, Seconds\}} \ind{options!s2s\_max\_retry\_delay} The maximum allowed delay for retry to connect after a failed connection attempt. Specified in seconds. The default value is 300 seconds (5 minutes). \titem{\{max\_fsm\_queue, Size\}} This option specifies the maximum number of elements in the queue of the FSM (Finite State Machine). Roughly speaking, each message in such queues represents one XML stanza queued to be sent into its relevant outgoing stream. If queue size reaches the limit (because, for example, the receiver of stanzas is too slow), the FSM and the corresponding connection (if any) will be terminated and error message will be logged. The reasonable value for this option depends on your hardware configuration. However, there is no much sense to set the size above 1000 elements. This option can be specified for \term{ejabberd\_service} and \term{ejabberd\_c2s} listeners, or also globally for \term{ejabberd\_s2s\_out}. If the option is not specified for \term{ejabberd\_service} or \term{ejabberd\_c2s} listeners, the globally configured value is used. The allowed values are integers and 'undefined'. Default value: 'undefined'. \titem{\{route\_subdomains, local|s2s\}} Defines if ejabberd must route stanzas directed to subdomains locally (compliant with \footahref{http://xmpp.org/rfcs/rfc3920.html\#rules.subdomain}{RFC 3920: XMPP Core}), or to foreign server using S2S (compliant with \footahref{http://tools.ietf.org/html/draft-saintandre-rfc3920bis-09\#section-11.3}{RFC 3920 bis}). \end{description} \makesubsubsection{listened-examples}{Examples} For example, the following simple configuration defines: \begin{itemize} \item There are three domains. The default certificate file is \term{server.pem}. However, the c2s and s2s connections to the domain \term{example.com} use the file \term{example\_com.pem}. \item Port 5222 listens for c2s connections with STARTTLS, and also allows plain connections for old clients. \item Port 5223 listens for c2s connections with the old SSL. \item Port 5269 listens for s2s connections with STARTTLS. The socket is set for IPv6 instead of IPv4. \item Port 3478 listens for STUN requests over UDP. \item Port 5280 listens for HTTP requests, and serves the HTTP Poll service. \item Port 5281 listens for HTTP requests, using HTTPS to serve HTTP-Bind (BOSH) and the Web Admin as explained in section~\ref{webadmin}. The socket only listens connections to the IP address 127.0.0.1. \end{itemize} \begin{verbatim} {hosts, ["example.com", "example.org", "example.net"]}. {listen, [ {5222, ejabberd_c2s, [ {access, c2s}, {shaper, c2s_shaper}, starttls, {certfile, "/etc/ejabberd/server.pem"}, {max_stanza_size, 65536} ]}, {5223, ejabberd_c2s, [ {access, c2s}, {shaper, c2s_shaper}, tls, {certfile, "/etc/ejabberd/server.pem"}, {max_stanza_size, 65536} ]}, {{5269, "::"}, ejabberd_s2s_in, [ {shaper, s2s_shaper}, {max_stanza_size, 131072} ]}, {{3478, udp}, ejabberd_stun, []}, {5280, ejabberd_http, [ http_poll ]}, {{5281, "127.0.0.1"}, ejabberd_http, [ web_admin, http_bind, tls, {certfile, "/etc/ejabberd/server.pem"}, ]} ] }. {s2s_use_starttls, optional}. {s2s_certfile, "/etc/ejabberd/server.pem"}. {domain_certfile, "example.com", "/etc/ejabberd/example_com.pem"}. {outgoing_s2s_options, [ipv4, ipv6], 10000}. \end{verbatim} In this example, the following configuration defines that: \begin{itemize} \item c2s connections are listened for on port 5222 (all IPv4 addresses) and on port 5223 (SSL, IP 192.168.0.1 and fdca:8ab6:a243:75ef::1) and denied for the user called `\term{bad}'. \item s2s connections are listened for on port 5269 (all IPv4 addresses) with STARTTLS for secured traffic strictly required, and the certificates are verified. Incoming and outgoing connections of remote XMPP servers are denied, only two servers can connect: "jabber.example.org" and "example.com". \item Port 5280 is serving the Web Admin and the HTTP Polling service in all the IPv4 addresses. Note that it is also possible to serve them on different ports. The second example in section~\ref{webadmin} shows how exactly this can be done. \item All users except for the administrators have a traffic of limit 1,000\,Bytes/second \item \ind{transports!AIM}The \footahref{http://www.ejabberd.im/pyaimt}{AIM transport} \jid{aim.example.org} is connected to port 5233 on localhost IP addresses (127.0.0.1 and ::1) with password `\term{aimsecret}'. \item \ind{transports!ICQ}The ICQ transport JIT (\jid{icq.example.org} and \jid{sms.example.org}) is connected to port 5234 with password `\term{jitsecret}'. \item \ind{transports!MSN}The \footahref{http://www.ejabberd.im/pymsnt}{MSN transport} \jid{msn.example.org} is connected to port 5235 with password `\term{msnsecret}'. \item \ind{transports!Yahoo}The \footahref{http://www.ejabberd.im/yahoo-transport-2}{Yahoo! transport} \jid{yahoo.example.org} is connected to port 5236 with password `\term{yahoosecret}'. \item \ind{transports!Gadu-Gadu}The \footahref{http://www.ejabberd.im/jabber-gg-transport}{Gadu-Gadu transport} \jid{gg.example.org} is connected to port 5237 with password `\term{ggsecret}'. \item \ind{transports!email notifier}The \footahref{http://www.ejabberd.im/jmc}{Jabber Mail Component} \jid{jmc.example.org} is connected to port 5238 with password `\term{jmcsecret}'. \item The service custom has enabled the special option to avoiding checking the \term{from} attribute in the packets send by this component. The component can send packets in behalf of any users from the server, or even on behalf of any server. \end{itemize} \begin{verbatim} {acl, blocked, {user, "bad"}}. {access, c2s, [{deny, blocked}, {allow, all}]}. {shaper, normal, {maxrate, 1000}}. {access, c2s_shaper, [{none, admin}, {normal, all}]}. {listen, [{5222, ejabberd_c2s, [ {access, c2s}, {shaper, c2s_shaper} ]}, {{5223, {192, 168, 0, 1}}, ejabberd_c2s, [ {access, c2s}, ssl, {certfile, "/path/to/ssl.pem"} ]}, {{5223, {16#fdca, 16#8ab6, 16#a243, 16#75ef, 0, 0, 0, 1}}, ejabberd_c2s, [ {access, c2s}, ssl, {certfile, "/path/to/ssl.pem"} ]}, {5269, ejabberd_s2s_in, []}, {{5280, {0, 0, 0, 0}}, ejabberd_http, [ http_poll, web_admin ]}, {{5233, {127, 0, 0, 1}}, ejabberd_service, [ {hosts, ["aim.example.org"], [{password, "aimsecret"}]} ]}, {{5233, "::1"}, ejabberd_service, [ {hosts, ["aim.example.org"], [{password, "aimsecret"}]} ]}, {5234, ejabberd_service, [{hosts, ["icq.example.org", "sms.example.org"], [{password, "jitsecret"}]}]}, {5235, ejabberd_service, [{hosts, ["msn.example.org"], [{password, "msnsecret"}]}]}, {5236, ejabberd_service, [{hosts, ["yahoo.example.org"], [{password, "yahoosecret"}]}]}, {5237, ejabberd_service, [{hosts, ["gg.example.org"], [{password, "ggsecret"}]}]}, {5238, ejabberd_service, [{hosts, ["jmc.example.org"], [{password, "jmcsecret"}]}]}, {5239, ejabberd_service, [{hosts, ["custom.example.org"], [{password, "customsecret"}]}, {service_check_from, false}]} ] }. {s2s_use_starttls, required_trusted}. {s2s_certfile, "/path/to/ssl.pem"}. {s2s_default_policy, deny}. {{s2s_host,"jabber.example.org"}, allow}. {{s2s_host,"example.com"}, allow}. \end{verbatim} Note, that for services based in \ind{jabberd14}jabberd14 or \ind{WPJabber}WPJabber you have to make the transports log and do \ind{XDB}XDB by themselves: \begin{verbatim} %d: [%t] (%h): %s /var/log/jabber/service.log /usr/lib/jabber/xdb_file.so /var/spool/jabber \end{verbatim} \makesubsection{auth}{Authentication} \ind{authentication}\ind{options!auth\_method} The option \option{auth\_method} defines the authentication methods that are used for user authentication. The syntax is: \esyntax{\{auth\_method, [Method, ...]\}.} The following authentication methods are supported by \ejabberd{}: \begin{itemize} \item internal (default) --- See section~\ref{internalauth}. \item external --- See section~\ref{extauth}. \item ldap --- See section~\ref{ldap}. \item odbc --- See section~\ref{mysql}, \ref{pgsql}, \ref{mssql} and \ref{odbc}. \item anonymous --- See section~\ref{saslanonymous}. \item pam --- See section~\ref{pam}. \end{itemize} Account creation is only supported by internal, external and odbc methods. The option \option{resource\_conflict} defines the action when a client attempts to login to an account with a resource that is already connected. The option syntax is: \esyntax{\{resource\_conflict, setresource|closenew|closeold\}.} The possible values match exactly the three possibilities described in \footahref{http://tools.ietf.org/html/rfc6120\#section-7.7.2.2}{XMPP Core: section 7.7.2.2}. The default value is \term{closeold}. If the client uses old Jabber Non-SASL authentication (\xepref{0078}), then this option is not respected, and the action performed is \term{closeold}. The option \option{fqdn} allows you to define the Fully Qualified Domain Name of the machine, in case it isn't detected automatically. The FQDN is used to authenticate some clients that use the DIGEST-MD5 SASL mechanism. The option syntax is: \esyntax{\{fqdn, undefined|FqdnString\}.} \makesubsubsection{internalauth}{Internal} \ind{internal authentication}\ind{Mnesia} \ejabberd{} uses its internal Mnesia database as the default authentication method. The value \term{internal} will enable the internal authentication method. The option \term{\{auth\_password\_format, plain|scram\}} defines in what format the users passwords are stored: \begin{description} \titem{plain} The password is stored as plain text in the database. This is risky because the passwords can be read if your database gets compromised. This is the default value. This format allows clients to authenticate using: the old Jabber Non-SASL (\xepref{0078}), \term{SASL PLAIN}, \term{SASL DIGEST-MD5}, and \term{SASL SCRAM-SHA-1}. \titem{scram} The password is not stored, only some information that allows to verify the hash provided by the client. It is impossible to obtain the original plain password from the stored information; for this reason, when this value is configured it cannot be changed to \term{plain} anymore. This format allows clients to authenticate using: \term{SASL PLAIN} and \term{SASL SCRAM-SHA-1}. \end{description} Examples: \begin{itemize} \item To use internal authentication on \jid{example.org} and LDAP authentication on \jid{example.net}: \begin{verbatim} {host_config, "example.org", [{auth_method, [internal]}]}. {host_config, "example.net", [{auth_method, [ldap]}]}. \end{verbatim} \item To use internal authentication with hashed passwords on all virtual hosts: \begin{verbatim} {auth_method, internal}. {auth_password_format, scram}. \end{verbatim} \end{itemize} \makesubsubsection{extauth}{External Script} \ind{external authentication} In this authentication method, when \ejabberd{} starts, it start a script, and calls it to perform authentication tasks. The server administrator can write the external authentication script in any language. The details on the interface between ejabberd and the script are described in the \term{ejabberd Developers Guide}. There are also \footahref{http://www.ejabberd.im/extauth}{several example authentication scripts}. These are the specific options: \begin{description} \titem{\{extauth\_program, PathToScript\}} Indicate in this option the full path to the external authentication script. The script must be executable by ejabberd. \titem{\{extauth\_instances, Integer\}} Indicate how many instances of the script to run simultaneously to serve authentication in the virtual host. The default value is the minimum number: 1. \titem{\{extauth\_cache, false|CacheTimeInteger\}} The value \term{false} disables the caching feature, this is the default. The integer \term{0} (zero) enables caching for statistics, but doesn't use that cached information to authenticate users. If another integer value is set, caching is enabled both for statistics and for authentication: the CacheTimeInteger indicates the number of seconds that ejabberd can reuse the authentication information since the user last disconnected, to verify again the user authentication without querying again the extauth script. Note: caching should not be enabled in a host if internal auth is also enabled. If caching is enabled, \term{mod\_last} or \term{mod\_last\_odbc} must be enabled also in that vhost. \end{description} This example sets external authentication, the extauth script, enables caching for 10 minutes, and starts three instances of the script for each virtual host defined in ejabberd: \begin{verbatim} {auth_method, [external]}. {extauth_program, "/etc/ejabberd/JabberAuth.class.php"}. {extauth_cache, 600}. {extauth_instances, 3}. \end{verbatim} \makesubsubsection{saslanonymous}{SASL Anonymous and Anonymous Login} \ind{sasl anonymous}\ind{anonymous login} The value \term{anonymous} will enable the internal authentication method. %TODO: introduction; tell what people can do with this The anonymous authentication method can be configured with the following options. Remember that you can use the \term{host\_config} option to set virtual host specific options (see section~\ref{virtualhost}). Note that there also is a detailed tutorial regarding \footahref{http://support.process-one.net/doc/display/MESSENGER/Anonymous+users+support}{SASL Anonymous and anonymous login configuration}. \begin{description} \titem{\{allow\_multiple\_connections, false|true\}} This option is only used when the anonymous mode is enabled. Setting it to \term{true} means that the same username can be taken multiple times in anonymous login mode if different resource are used to connect. This option is only useful in very special occasions. The default value is \term{false}. \titem{\{anonymous\_protocol, sasl\_anon | login\_anon | both\}} \term{sasl\_anon} means that the SASL Anonymous method will be used. \term{login\_anon} means that the anonymous login method will be used. \term{both} means that SASL Anonymous and login anonymous are both enabled. \end{description} Those options are defined for each virtual host with the \term{host\_config} parameter (see section~\ref{virtualhost}). Examples: \begin{itemize} \item To enable anonymous login on all virtual hosts: \begin{verbatim} {auth_method, [anonymous]}. {anonymous_protocol, login_anon}. \end{verbatim} \item Similar as previous example, but limited to \jid{public.example.org}: \begin{verbatim} {host_config, "public.example.org", [{auth_method, [anonymous]}, {anonymous_protocol, login_anon}]}. \end{verbatim} \item To enable anonymous login and internal authentication on a virtual host: \begin{verbatim} {host_config, "public.example.org", [{auth_method, [internal,anonymous]}, {anonymous_protocol, login_anon}]}. \end{verbatim} \item To enable SASL Anonymous on a virtual host: \begin{verbatim} {host_config, "public.example.org", [{auth_method, [anonymous]}, {anonymous_protocol, sasl_anon}]}. \end{verbatim} \item To enable SASL Anonymous and anonymous login on a virtual host: \begin{verbatim} {host_config, "public.example.org", [{auth_method, [anonymous]}, {anonymous_protocol, both}]}. \end{verbatim} \item To enable SASL Anonymous, anonymous login, and internal authentication on a virtual host: \begin{verbatim} {host_config, "public.example.org", [{auth_method, [internal,anonymous]}, {anonymous_protocol, both}]}. \end{verbatim} \end{itemize} \makesubsubsection{pam}{PAM Authentication} \ind{PAM authentication}\ind{Pluggable Authentication Modules} \ejabberd{} supports authentication via Pluggable Authentication Modules (PAM). PAM is currently supported in AIX, FreeBSD, HP-UX, Linux, Mac OS X, NetBSD and Solaris. PAM authentication is disabled by default, so you have to configure and compile \ejabberd{} with PAM support enabled: \begin{verbatim} ./configure --enable-pam && make install \end{verbatim} Options: \begin{description} \titem{\{pam\_service, Name\}}\ind{options!pam\_service}This option defines the PAM service name. Default is \term{"ejabberd"}. Refer to the PAM documentation of your operation system for more information. \titem{\{pam\_userinfotype, username|jid\}}\ind{options!pam\_userinfotype} This option defines what type of information about the user ejabberd provides to the PAM service: only the username, or the user JID. Default is \term{username}. \end{description} Example: \begin{verbatim} {auth_method, [pam]}. {pam_service, "ejabberd"}. \end{verbatim} Though it is quite easy to set up PAM support in \ejabberd{}, PAM itself introduces some security issues: \begin{itemize} \item To perform PAM authentication \ejabberd{} uses external C-program called \term{epam}. By default, it is located in \verb|/var/lib/ejabberd/priv/bin/| directory. You have to set it root on execution in the case when your PAM module requires root privileges (\term{pam\_unix.so} for example). Also you have to grant access for \ejabberd{} to this file and remove all other permissions from it. Execute with root privileges: \begin{verbatim} chown root:ejabberd /var/lib/ejabberd/priv/bin/epam chmod 4750 /var/lib/ejabberd/priv/bin/epam \end{verbatim} \item Make sure you have the latest version of PAM installed on your system. Some old versions of PAM modules cause memory leaks. If you are not able to use the latest version, you can \term{kill(1)} \term{epam} process periodically to reduce its memory consumption: \ejabberd{} will restart this process immediately. \item \term{epam} program tries to turn off delays on authentication failures. However, some PAM modules ignore this behavior and rely on their own configuration options. You can create a configuration file \term{ejabberd.pam}. This example shows how to turn off delays in \term{pam\_unix.so} module: \begin{verbatim} #%PAM-1.0 auth sufficient pam_unix.so likeauth nullok nodelay account sufficient pam_unix.so \end{verbatim} That is not a ready to use configuration file: you must use it as a hint when building your own PAM configuration instead. Note that if you want to disable delays on authentication failures in the PAM configuration file, you have to restrict access to this file, so a malicious user can't use your configuration to perform brute-force attacks. \item You may want to allow login access only for certain users. \term{pam\_listfile.so} module provides such functionality. \item If you use \term{pam\_winbind} to authorise against a Windows Active Directory, then \term{/etc/nssswitch.conf} must be configured to use \term{winbind} as well. \end{itemize} \makesubsection{accessrules}{Access Rules} \ind{access rules}\ind{ACL}\ind{Access Control List} \makesubsubsection{ACLDefinition}{ACL Definition} \ind{ACL}\ind{options!acl}\ind{ACL}\ind{Access Control List} Access control in \ejabberd{} is performed via Access Control Lists (ACLs). The declarations of ACLs in the configuration file have the following syntax: \esyntax{\{acl, ACLName, ACLValue\}.} \term{ACLValue} can be one of the following: \begin{description} \titem{all} Matches all JIDs. Example: \begin{verbatim} {acl, all, all}. \end{verbatim} \titem{\{user, Username\}} Matches the user with the name \term{Username} at the first virtual host. Example: \begin{verbatim} {acl, admin, {user, "yozhik"}}. \end{verbatim} \titem{\{user, Username, Server\}} Matches the user with the JID \term{Username@Server} and any resource. Example: \begin{verbatim} {acl, admin, {user, "yozhik", "example.org"}}. \end{verbatim} \titem{\{server, Server\}} Matches any JID from server \term{Server}. Example: \begin{verbatim} {acl, exampleorg, {server, "example.org"}}. \end{verbatim} \titem{\{resource, Resource\}} Matches any JID with a resource \term{Resource}. Example: \begin{verbatim} {acl, mucklres, {resource, "muckl"}}. \end{verbatim} \titem{\{shared\_group, Groupname\}} Matches any member of a Shared Roster Group with name \term{Groupname} in the virtual host. Example: \begin{verbatim} {acl, techgroupmembers, {shared_group, "techteam"}}. \end{verbatim} \titem{\{shared\_group, Groupname, Server\}} Matches any member of a Shared Roster Group with name \term{Groupname} in the virtual host \term{Server}. Example: \begin{verbatim} {acl, techgroupmembers, {shared_group, "techteam", "example.org"}}. \end{verbatim} \titem{\{user\_regexp, Regexp\}} Matches any local user with a name that matches \term{Regexp} on local virtual hosts. Example: \begin{verbatim} {acl, tests, {user_regexp, "^test[0-9]*$"}}. \end{verbatim} %$ \titem{\{user\_regexp, Regexp, Server\}} Matches any user with a name that matches \term{Regexp} at server \term{Server}. Example: \begin{verbatim} {acl, tests, {user_regexp, "^test", "example.org"}}. \end{verbatim} \titem{\{server\_regexp, Regexp\}} Matches any JID from the server that matches \term{Regexp}. Example: \begin{verbatim} {acl, icq, {server_regexp, "^icq\\."}}. \end{verbatim} \titem{\{resource\_regexp, Regexp\}} Matches any JID with a resource that matches \term{Regexp}. Example: \begin{verbatim} {acl, icq, {resource_regexp, "^laptop\\."}}. \end{verbatim} \titem{\{node\_regexp, UserRegexp, ServerRegexp\}} Matches any user with a name that matches \term{UserRegexp} at any server that matches \term{ServerRegexp}. Example: \begin{verbatim} {acl, yozhik, {node_regexp, "^yozhik$", "^example.(com|org)$"}}. \end{verbatim} \titem{\{user\_glob, Glob\}} \titem{\{user\_glob, Glob, Server\}} \titem{\{server\_glob, Glob\}} \titem{\{resource\_glob, Glob\}} \titem{\{node\_glob, UserGlob, ServerGlob\}} This is the same as above. However, it uses shell glob patterns instead of regexp. These patterns can have the following special characters: \begin{description} \titem{*} matches any string including the null string. \titem{?} matches any single character. \titem{[...]} matches any of the enclosed characters. Character ranges are specified by a pair of characters separated by a \term{`-'}. If the first character after \term{`['} is a \term{`!'}, any character not enclosed is matched. \end{description} \end{description} The following \term{ACLName} are pre-defined: \begin{description} \titem{all} Matches any JID. \titem{none} Matches no JID. \end{description} \makesubsubsection{AccessRights}{Access Rights} \ind{access}\ind{ACL}\ind{options!acl}\ind{ACL}\ind{Access Control List} An entry allowing or denying access to different services. The syntax is: \esyntax{\{access, AccessName, [ \{allow|deny, ACLName\}, ...]\}.} When a JID is checked to have access to \term{Accessname}, the server sequentially checks if that JID matches any of the ACLs that are named in the second elements of the tuples in the list. If it matches, the first element of the first matched tuple is returned, otherwise the value `\term{deny}' is returned. If you define specific Access rights in a virtual host, remember that the globally defined Access rights have precedence over those. This means that, in case of conflict, the Access granted or denied in the global server is used and the Access of a virtual host doesn't have effect. Example: \begin{verbatim} {access, configure, [{allow, admin}]}. {access, something, [{deny, badmans}, {allow, all}]}. \end{verbatim} The following \term{AccessName} are pre-defined: \begin{description} \titem{all} Always returns the value `\term{allow}'. \titem{none} Always returns the value `\term{deny}'. \end{description} \makesubsubsection{configmaxsessions}{Limiting Opened Sessions with ACL} \ind{options!max\_user\_sessions} The special access \term{max\_user\_sessions} specifies the maximum number of sessions (authenticated connections) per user. If a user tries to open more sessions by using different resources, the first opened session will be disconnected. The error \term{session replaced} will be sent to the disconnected session. The value for this option can be either a number, or \term{infinity}. The default value is \term{infinity}. The syntax is: \esyntax{\{access, max\_user\_sessions, [ \{MaxNumber, ACLName\}, ...]\}.} This example limits the number of sessions per user to 5 for all users, and to 10 for admins: \begin{verbatim} {access, max_user_sessions, [{10, admin}, {5, all}]}. \end{verbatim} \makesubsubsection{configmaxs2sconns}{Several connections to a remote XMPP server with ACL} \ind{options!max\_s2s\_connections} The special access \term{max\_s2s\_connections} specifies how many simultaneous S2S connections can be established to a specific remote XMPP server. The default value is \term{1}. There's also available the access \term{max\_s2s\_connections\_per\_node}. The syntax is: \esyntax{\{access, max\_s2s\_connections, [ \{MaxNumber, ACLName\}, ...]\}.} Examples: \begin{itemize} \item Allow up to 3 connections with each remote server: \begin{verbatim} {access, max_s2s_connections, [{3, all}]}. \end{verbatim} \end{itemize} \makesubsection{shapers}{Shapers} \ind{options!shaper}\ind{options!maxrate}\ind{shapers}\ind{maxrate}\ind{traffic speed} Shapers enable you to limit connection traffic. The syntax is: \esyntax{\{shaper, ShaperName, Kind\}.} Currently only one kind of shaper called \term{maxrate} is available. It has the following syntax: \esyntax{\{maxrate, Rate\}} where \term{Rate} stands for the maximum allowed incoming rate in bytes per second. When a connection exceeds this limit, \ejabberd{} stops reading from the socket until the average rate is again below the allowed maximum. Examples: \begin{itemize} \item To define a shaper named `\term{normal}' with traffic speed limited to 1,000\,bytes/second: \begin{verbatim} {shaper, normal, {maxrate, 1000}}. \end{verbatim} \item To define a shaper named `\term{fast}' with traffic speed limited to 50,000\,bytes/second: \begin{verbatim} {shaper, fast, {maxrate, 50000}}. \end{verbatim} \end{itemize} \makesubsection{language}{Default Language} \ind{options!language}\ind{language} The option \option{language} defines the default language of server strings that can be seen by \XMPP{} clients. If a \XMPP{} client does not support \option{xml:lang}, the specified language is used. The option syntax is: \esyntax{\{language, Language\}.} The default value is \term{en}. In order to take effect there must be a translation file \term{Language.msg} in \ejabberd{}'s \term{msgs} directory. For example, to set Russian as default language: \begin{verbatim} {language, "ru"}. \end{verbatim} Appendix \ref{i18ni10n} provides more details about internationalization and localization. \makesubsection{captcha}{CAPTCHA} \ind{options!captcha}\ind{captcha} Some \ejabberd{} modules can be configured to require a CAPTCHA challenge on certain actions. If the client does not support CAPTCHA Forms (\xepref{0158}), a web link is provided so the user can fill the challenge in a web browser. An example script is provided that generates the image using ImageMagick's Convert program. The configurable options are: \begin{description} \titem{\{captcha\_cmd, Path\}} Full path to a script that generates the image. The default value disables the feature: \term{undefined} \titem{\{captcha\_host, ProtocolHostPort\}} ProtocolHostPort is a string with the host, and optionally the Protocol and Port number. It must identify where ejabberd listens for CAPTCHA requests. The URL sent to the user is formed by: \term{Protocol://Host:Port/captcha/} The default value is: protocol \term{http}, the first hostname configured, and port \term{80}. If you specify a port number that does not match exactly an ejabberd listener (because you are using a reverse proxy or other port-forwarding tool), then you must specify the transfer protocol, as seen in the example below. \end{description} Additionally, an \term{ejabberd\_http} listener must be enabled with the \term{captcha} option. See section \ref{listened-module}. Example configuration: \begin{verbatim} {hosts, ["example.org"]}. {captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}. {captcha_host, "example.org:5280"}. %% {captcha_host, "https://example.org:443"}. %% {captcha_host, "http://example.com"}. {listen, [ ... {5280, ejabberd_http, [ captcha, ... ] } ]}. \end{verbatim} \makesubsection{stun}{STUN} \ind{options!stun}\ind{stun} \ejabberd{} is able to act as a stand-alone STUN server (\footahref{http://tools.ietf.org/html/rfc5389}{RFC 5389}). Currently only Binding usage is supported. In that role \ejabberd{} helps clients with Jingle ICE (\xepref{0176}) support to discover their external addresses and ports. You should configure \term{ejabberd\_stun} listening module as described in \ref{listened} section. If \option{certfile} option is defined, \ejabberd{} multiplexes TCP and TLS over TCP connections on the same port. Obviously, \option{certfile} option is defined for \term{tcp} only. Note however that TCP or TLS over TCP support is not required for Binding usage and is reserved for \footahref{http://tools.ietf.org/html/draft-ietf-behave-turn-16}{TURN} functionality. Feel free to configure \term{udp} transport only. Example configuration: \begin{verbatim} {listen, [ ... {{3478, udp}, ejabberd_stun, []}, {3478, ejabberd_stun, []}, {5349, ejabberd_stun, [{certfile, "/etc/ejabberd/server.pem"}]}, ... ] }. \end{verbatim} You also need to configure DNS SRV records properly so clients can easily discover a STUN server serving your XMPP domain. Refer to section \footahref{http://tools.ietf.org/html/rfc5389\#section-9}{DNS Discovery of a Server} of \footahref{http://tools.ietf.org/html/rfc5389}{RFC 5389} for details. Example DNS SRV configuration: \begin{verbatim} _stun._udp IN SRV 0 0 3478 stun.example.com. _stun._tcp IN SRV 0 0 3478 stun.example.com. _stuns._tcp IN SRV 0 0 5349 stun.example.com. \end{verbatim} \makesubsection{includeconfigfile}{Include Additional Configuration Files} \ind{options!includeconfigfile}\ind{includeconfigfile} The option \option{include\_config\_file} in a configuration file instructs \ejabberd{} to include other configuration files immediately. The basic syntax is: \esyntax{\{include\_config\_file, Filename\}.} It is possible to specify suboptions using the full syntax: \esyntax{\{include\_config\_file, Filename, [Suboption, ...]\}.} The filename can be indicated either as an absolute path, or relative to the main \ejabberd{} configuration file. It isn't possible to use wildcards. The file must exist and be readable. The allowed suboptions are: \begin{description} \titem{\{disallow, [Optionname, ...]\}} Disallows the usage of those options in the included configuration file. The options that match this criteria are not accepted. The default value is an empty list: \term{[]} \titem{\{allow\_only, [Optionname, ...]\}} Allows only the usage of those options in the included configuration file. The options that do not match this criteria are not accepted. The default value is: \term{all} \end{description} This is a basic example: \begin{verbatim} {include_config_file, "/etc/ejabberd/additional.cfg"}. \end{verbatim} In this example, the included file is not allowed to contain a \term{listen} option. If such an option is present, the option will not be accepted. The file is in a subdirectory from where the main configuration file is. \begin{verbatim} {include_config_file, "./example.org/additional_not_listen.cfg", [{disallow, [listen]}]}. \end{verbatim} In this example, \term{ejabberd.cfg} defines some ACL and Access rules, and later includes another file with additional rules: \begin{verbatim} {acl, admin, {user, "admin", "localhost"}}. {access, announce, [{allow, admin}]}. {include_config_file, "/etc/ejabberd/acl_and_access.cfg", [{allow_only, [acl, access]}]}. \end{verbatim} and content of the file \term{acl\_and\_access.cfg} can be, for example: \begin{verbatim} {acl, admin, {user, "bob", "localhost"}}. {acl, admin, {user, "jan", "localhost"}}. \end{verbatim} \makesubsection{optionmacros}{Option Macros in Configuration File} \ind{options!optionmacros}\ind{optionmacros} In the \ejabberd{} configuration file, it is possible to define a macro for a value and later use this macro when defining an option. A macro is defined with this syntax: \esyntax{\{define\_macro, 'MACRO', Value\}.} The \term{MACRO} must be surrounded by single quotation marks, and all letters in uppercase; check the examples bellow. The \term{value} can be any valid arbitrary Erlang term. The first definition of a macro is preserved, and additional definitions of the same macro are forgotten. Macros are processed after additional configuration files have been included, so it is possible to use macros that are defined in configuration files included before the usage. It isn't possible to use a macro in the definition of another macro. There are two ways to use a macro: \begin{description} \titem{'MACRO'} You can put this instead of a value in an \ejabberd{} option, and will be replaced with the \term{value} previously defined. If the macro is not defined previously, the program will crash and report an error. \titem{\{use\_macro, 'MACRO', Defaultvalue\}} Use a macro even if it may not be defined. If the macro is not defined previously, the provided \term{defaultvalue} is used. This usage behaves as if it were defined and used this way: \begin{verbatim} {define_macro, 'MACRO', Defaultvalue}. 'MACRO' \end{verbatim} \end{description} This example shows the basic usage of a macro: \begin{verbatim} {define_macro, 'LOG_LEVEL_NUMBER', 5}. {loglevel, 'LOG_LEVEL_NUMBER'}. \end{verbatim} The resulting option interpreted by \ejabberd{} is: \term{\{loglevel, 5\}}. This example shows that values can be any arbitrary Erlang term: \begin{verbatim} {define_macro, 'USERBOB', {user, "bob", "localhost"}}. {acl, admin, 'USERBOB'}. \end{verbatim} The resulting option interpreted by \ejabberd{} is: \term{\{acl, admin, \{user, "bob", "localhost"\}\}}. This complex example: \begin{verbatim} {define_macro, 'NUMBER_PORT_C2S', 5222}. {define_macro, 'PORT_S2S_IN', {5269, ejabberd_s2s_in, []}}. {listen, [ {'NUMBER_PORT_C2S', ejabberd_c2s, []}, 'PORT_S2S_IN', {{use_macro, 'NUMBER_PORT_HTTP', 5280}, ejabberd_http, []} ] }. \end{verbatim} produces this result after being interpreted: \begin{verbatim} {listen, [ {5222, ejabberd_c2s, []}, {5269, ejabberd_s2s_in, []}, {5280, ejabberd_http, []} ] }. \end{verbatim} \makesection{database}{Database and LDAP Configuration} \ind{database} %TODO: this whole section is not yet 100% optimized \ejabberd{} uses its internal Mnesia database by default. However, it is possible to use a relational database or an LDAP server to store persistent, long-living data. \ejabberd{} is very flexible: you can configure different authentication methods for different virtual hosts, you can configure different authentication mechanisms for the same virtual host (fallback), you can set different storage systems for modules, and so forth. The following databases are supported by \ejabberd{}: \begin{itemize} \item \footahref{http://www.microsoft.com/sql/}{Microsoft SQL Server} \item \footahref{http://www.erlang.org/doc/apps/mnesia/index.html}{Mnesia} \item \footahref{http://www.mysql.com/}{MySQL} \item \footahref{http://en.wikipedia.org/wiki/Open\_Database\_Connectivity}{Any ODBC compatible database} \item \footahref{http://www.postgresql.org/}{PostgreSQL} \end{itemize} The following LDAP servers are tested with \ejabberd{}: \begin{itemize} \item \footahref{http://www.microsoft.com/activedirectory/}{Active Directory} (see section~\ref{ad}) \item \footahref{http://www.openldap.org/}{OpenLDAP} \item \footahref{http://www.communigate.com/}{CommuniGate Pro} \item Normally any LDAP compatible server should work; inform us about your success with a not-listed server so that we can list it here. \end{itemize} Important note about virtual hosting: if you define several domains in ejabberd.cfg (see section \ref{hostnames}), you probably want that each virtual host uses a different configuration of database, authentication and storage, so that usernames do not conflict and mix between different virtual hosts. For that purpose, the options described in the next sections must be set inside a \term{host\_config} for each vhost (see section \ref{virtualhost}). For example: \begin{verbatim} {host_config, "public.example.org", [ {odbc_server, {pgsql, "localhost", "database-public-example-org", "ejabberd", "password"}}, {auth_method, [odbc]} ]}. \end{verbatim} \makesubsection{mysql}{MySQL} \ind{MySQL}\ind{MySQL!schema} Although this section will describe \ejabberd{}'s configuration when you want to use the native MySQL driver, it does not describe MySQL's installation and database creation. Check the MySQL documentation and the tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} for information regarding these topics. Note that the tutorial contains information about \ejabberd{}'s configuration which is duplicate to this section. Moreover, the file mysql.sql in the directory src/odbc might be interesting for you. This file contains the \ejabberd{} schema for MySQL. At the end of the file you can find information to update your database schema. \makesubsubsection{compilemysql}{Driver Compilation} \ind{MySQL!Driver Compilation} You can skip this step if you installed \ejabberd{} using a binary installer or if the binary packages of \ejabberd{} you are using include support for MySQL. \begin{enumerate} \item First, install the \footahref{http://support.process-one.net/doc/display/CONTRIBS/Yxa}{Erlang MySQL library}. Make sure the compiled files are in your Erlang path; you can put them for example in the same directory as your \ejabberd{} .beam files. \item Then, configure and install \ejabberd{} with ODBC support enabled (this is also needed for native MySQL support!). This can be done, by using next commands: \begin{verbatim} ./configure --enable-odbc && make install \end{verbatim} \end{enumerate} \makesubsubsection{configuremysql}{Database Connection} \ind{MySQL!Database Connection} The actual database access is defined in the option \term{odbc\_server}. Its value is used to define if we want to use ODBC, or one of the two native interface available, PostgreSQL or MySQL. To use the native MySQL interface, you can pass a tuple of the following form as parameter: \esyntax{\{mysql, "Server", "Database", "Username", "Password"\}} \term{mysql} is a keyword that should be kept as is. For example: \esyntax{\{odbc\_server, \{mysql, "localhost", "test", "root", "password"\}\}.} Optionally, it is possible to define the MySQL port to use. This option is only useful, in very rare cases, when you are not running MySQL with the default port setting. The \term{mysql} parameter can thus take the following form: \esyntax{\{mysql, "Server", Port, "Database", "Username", "Password"\}} The \term{Port} value should be an integer, without quotes. For example: \esyntax{\{odbc\_server, \{mysql, "localhost", Port, "test", "root", "password"\}\}.} By default \ejabberd{} opens 10 connections to the database for each virtual host. Use this option to modify the value: \begin{verbatim} {odbc_pool_size, 10}. \end{verbatim} You can configure an interval to make a dummy SQL request to keep alive the connections to the database. The default value is 'undefined', so no keepalive requests are made. Specify in seconds: for example 28800 means 8 hours. \begin{verbatim} {odbc_keepalive_interval, undefined}. \end{verbatim} If the connection to the database fails, \ejabberd{} waits 30 seconds before retrying. You can modify this interval with this option: \begin{verbatim} {odbc_start_interval, 30}. \end{verbatim} \makesubsubsection{mysqlauth}{Authentication} \ind{MySQL!authentication} The option value name may be misleading, as the \term{auth\_method} name is used for access to a relational database through ODBC, as well as through the native MySQL interface. Anyway, the first configuration step is to define the odbc \term{auth\_method}. For example: \begin{verbatim} {auth_method, [odbc]}. \end{verbatim} \makesubsubsection{mysqlstorage}{Storage} \ind{MySQL!storage} MySQL also can be used to store information into from several \ejabberd{} modules. See section~\ref{modoverview} to see which modules have a version with the `\_odbc'. This suffix indicates that the module can be used with relational databases like MySQL. To enable storage to your database, just make sure that your database is running well (see previous sections), and replace the suffix-less or ldap module variant with the odbc module variant. Keep in mind that you cannot have several variants of the same module loaded! \makesubsection{mssql}{Microsoft SQL Server} \ind{Microsoft SQL Server}\ind{Microsoft SQL Server!schema} Although this section will describe \ejabberd{}'s configuration when you want to use Microsoft SQL Server, it does not describe Microsoft SQL Server's installation and database creation. Check the MySQL documentation and the tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} for information regarding these topics. Note that the tutorial contains information about \ejabberd{}'s configuration which is duplicate to this section. Moreover, the file mssql.sql in the directory src/odbc might be interesting for you. This file contains the \ejabberd{} schema for Microsoft SQL Server. At the end of the file you can find information to update your database schema. \makesubsubsection{compilemssql}{Driver Compilation} \ind{Microsoft SQL Server!Driver Compilation} You can skip this step if you installed \ejabberd{} using a binary installer or if the binary packages of \ejabberd{} you are using include support for ODBC. If you want to use Microsoft SQL Server with ODBC, you need to configure, compile and install \ejabberd{} with support for ODBC and Microsoft SQL Server enabled. This can be done, by using next commands: \begin{verbatim} ./configure --enable-odbc --enable-mssql && make install \end{verbatim} \makesubsubsection{configuremssql}{Database Connection} \ind{Microsoft SQL Server!Database Connection} The configuration of Database Connection for a Microsoft SQL Server is the same as the configuration for ODBC compatible servers (see section~\ref{configureodbc}). \makesubsubsection{mssqlauth}{Authentication} \ind{Microsoft SQL Server!authentication} %TODO: not sure if this section is right!!!!!! The configuration of Authentication for a Microsoft SQL Server is the same as the configuration for ODBC compatible servers (see section~\ref{odbcauth}). \makesubsubsection{mssqlstorage}{Storage} \ind{Microsoft SQL Server!storage} Microsoft SQL Server also can be used to store information into from several \ejabberd{} modules. See section~\ref{modoverview} to see which modules have a version with the `\_odbc'. This suffix indicates that the module can be used with relational databases like Microsoft SQL Server. To enable storage to your database, just make sure that your database is running well (see previous sections), and replace the suffix-less or ldap module variant with the odbc module variant. Keep in mind that you cannot have several variants of the same module loaded! \makesubsection{pgsql}{PostgreSQL} \ind{PostgreSQL}\ind{PostgreSQL!schema} Although this section will describe \ejabberd{}'s configuration when you want to use the native PostgreSQL driver, it does not describe PostgreSQL's installation and database creation. Check the PostgreSQL documentation and the tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} for information regarding these topics. Note that the tutorial contains information about \ejabberd{}'s configuration which is duplicate to this section. Also the file pg.sql in the directory src/odbc might be interesting for you. This file contains the \ejabberd{} schema for PostgreSQL. At the end of the file you can find information to update your database schema. \makesubsubsection{compilepgsql}{Driver Compilation} \ind{PostgreSQL!Driver Compilation} You can skip this step if you installed \ejabberd{} using a binary installer or if the binary packages of \ejabberd{} you are using include support for PostgreSQL. \begin{enumerate} \item First, install the Erlang pgsql library from \footahref{http://www.ejabberd.im/ejabberd-modules/}{ejabberd-modules SVN repository}. Make sure the compiled files are in your Erlang path; you can put them for example in the same directory as your \ejabberd{} .beam files. \item Then, configure, compile and install \ejabberd{} with ODBC support enabled (this is also needed for native PostgreSQL support!). This can be done, by using next commands: \begin{verbatim} ./configure --enable-odbc && make install \end{verbatim} \end{enumerate} \makesubsubsection{configurepgsql}{Database Connection} \ind{PostgreSQL!Database Connection} The actual database access is defined in the option \term{odbc\_server}. Its value is used to define if we want to use ODBC, or one of the two native interface available, PostgreSQL or MySQL. To use the native PostgreSQL interface, you can pass a tuple of the following form as parameter: \esyntax{\{pgsql, "Server", "Database", "Username", "Password"\}} \term{pgsql} is a keyword that should be kept as is. For example: \esyntax{\{odbc\_server, \{pgsql, "localhost", "database", "ejabberd", "password"\}\}.} Optionally, it is possible to define the PostgreSQL port to use. This option is only useful, in very rare cases, when you are not running PostgreSQL with the default port setting. The \term{pgsql} parameter can thus take the following form: \esyntax{\{pgsql, "Server", Port, "Database", "Username", "Password"\}} The \term{Port} value should be an integer, without quotes. For example: \esyntax{\{odbc\_server, \{pgsql, "localhost", 5432, "database", "ejabberd", "password"\}\}.} By default \ejabberd{} opens 10 connections to the database for each virtual host. Use this option to modify the value: \begin{verbatim} {odbc_pool_size, 10}. \end{verbatim} You can configure an interval to make a dummy SQL request to keep alive the connections to the database. The default value is 'undefined', so no keepalive requests are made. Specify in seconds: for example 28800 means 8 hours. \begin{verbatim} {odbc_keepalive_interval, undefined}. \end{verbatim} \makesubsubsection{pgsqlauth}{Authentication} \ind{PostgreSQL!authentication} The option value name may be misleading, as the \term{auth\_method} name is used for access to a relational database through ODBC, as well as through the native PostgreSQL interface. Anyway, the first configuration step is to define the odbc \term{auth\_method}. For example: \begin{verbatim} {auth_method, [odbc]}. \end{verbatim} \makesubsubsection{pgsqlstorage}{Storage} \ind{PostgreSQL!storage} PostgreSQL also can be used to store information into from several \ejabberd{} modules. See section~\ref{modoverview} to see which modules have a version with the `\_odbc'. This suffix indicates that the module can be used with relational databases like PostgreSQL. To enable storage to your database, just make sure that your database is running well (see previous sections), and replace the suffix-less or ldap module variant with the odbc module variant. Keep in mind that you cannot have several variants of the same module loaded! \makesubsection{odbc}{ODBC Compatible} \ind{databases!ODBC} Although this section will describe \ejabberd{}'s configuration when you want to use the ODBC driver, it does not describe the installation and database creation of your database. Check the documentation of your database. The tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} also can help you. Note that the tutorial contains information about \ejabberd{}'s configuration which is duplicate to this section. \makesubsubsection{compileodbc}{Driver Compilation} You can skip this step if you installed \ejabberd{} using a binary installer or if the binary packages of \ejabberd{} you are using include support for ODBC. \begin{enumerate} \item First, install the \footahref{http://support.process-one.net/doc/display/CONTRIBS/Yxa}{Erlang MySQL library}. Make sure the compiled files are in your Erlang path; you can put them for example in the same directory as your \ejabberd{} .beam files. \item Then, configure, compile and install \ejabberd{} with ODBC support enabled. This can be done, by using next commands: \begin{verbatim} ./configure --enable-odbc && make install \end{verbatim} \end{enumerate} \makesubsubsection{configureodbc}{Database Connection} \ind{ODBC!Database Connection} The actual database access is defined in the option \term{odbc\_server}. Its value is used to defined if we want to use ODBC, or one of the two native interface available, PostgreSQL or MySQL. To use a relational database through ODBC, you can pass the ODBC connection string as \term{odbc\_server} parameter. For example: \begin{verbatim} {odbc_server, "DSN=database;UID=ejabberd;PWD=password"}. \end{verbatim} By default \ejabberd{} opens 10 connections to the database for each virtual host. Use this option to modify the value: \begin{verbatim} {odbc_pool_size, 10}. \end{verbatim} You can configure an interval to make a dummy SQL request to keep alive the connections to the database. The default value is 'undefined', so no keepalive requests are made. Specify in seconds: for example 28800 means 8 hours. \begin{verbatim} {odbc_keepalive_interval, undefined}. \end{verbatim} \makesubsubsection{odbcauth}{Authentication} \ind{ODBC!authentication} The first configuration step is to define the odbc \term{auth\_method}. For example: \begin{verbatim} {auth_method, [odbc]}. \end{verbatim} \makesubsubsection{odbcstorage}{Storage} \ind{ODBC!storage} An ODBC compatible database also can be used to store information into from several \ejabberd{} modules. See section~\ref{modoverview} to see which modules have a version with the `\_odbc'. This suffix indicates that the module can be used with ODBC compatible relational databases. To enable storage to your database, just make sure that your database is running well (see previous sections), and replace the suffix-less or ldap module variant with the odbc module variant. Keep in mind that you cannot have several variants of the same module loaded! \makesubsection{ldap}{LDAP} \ind{databases!LDAP} \ejabberd{} has built-in LDAP support. You can authenticate users against LDAP server and use LDAP directory as vCard storage. Usually \ejabberd{} treats LDAP as a read-only storage: it is possible to consult data, but not possible to create accounts or edit vCard that is stored in LDAP. However, it is possible to change passwords if \module{mod\_register} module is enabled and LDAP server supports \footahref{http://tools.ietf.org/html/rfc3062}{RFC 3062}. \makesubsubsection{ldapconnection}{Connection} Two connections are established to the LDAP server per vhost, one for authentication and other for regular calls. Parameters: \begin{description} \titem{\{ldap\_servers, [Servers, ...]\}} \ind{options!ldap\_server}List of IP addresses or DNS names of your LDAP servers. This option is required. \titem{\{ldap\_encrypt, none|tls\}} \ind{options!ldap\_encrypt}Type of connection encryption to the LDAP server. Allowed values are: \term{none}, \term{tls}. The value \term{tls} enables encryption by using LDAP over SSL. Note that STARTTLS encryption is not supported. The default value is: \term{none}. \titem{\{ldap\_tls\_verify, false|soft|hard\}} \ind{options!ldap\_tls\_verify} This option specifies whether to verify LDAP server certificate or not when TLS is enabled. When \term{hard} is enabled \ejabberd{} doesn't proceed if a certificate is invalid. When \term{soft} is enabled \ejabberd{} proceeds even if check fails. The default is \term{false} which means no checks are performed. \titem{\{ldap\_tls\_cacertfile, Path\}} \ind{options!ldap\_tls\_cacertfile} Path to file containing PEM encoded CA certificates. This option is needed (and required) when TLS verification is enabled. \titem{\{ldap\_tls\_depth, Number\}} \ind{options!ldap\_tls\_depth} Specifies the maximum verification depth when TLS verification is enabled, i.e. how far in a chain of certificates the verification process can proceed before the verification is considered to fail. Peer certificate = 0, CA certificate = 1, higher level CA certificate = 2, etc. The value 2 thus means that a chain can at most contain peer cert, CA cert, next CA cert, and an additional CA cert. The default value is 1. \titem{\{ldap\_port, Number\}} \ind{options!ldap\_port}Port to connect to your LDAP server. The default port is~389 if encryption is disabled; and 636 if encryption is enabled. If you configure a value, it is stored in \ejabberd{}'s database. Then, if you remove that value from the configuration file, the value previously stored in the database will be used instead of the default port. \titem{\{ldap\_rootdn, RootDN\}} \ind{options!ldap\_rootdn}Bind DN. The default value is~\term{""} which means `anonymous connection'. \titem{\{ldap\_password, Password\}} \ind{options!ldap\_password}Bind password. The default value is \term{""}. \titem{\{ldap\_deref\_aliases, never|always|finding|searching\}} \ind{options!ldap\_deref\_aliases} Whether or not to dereference aliases. The default is \term{never}. \end{description} Example: \begin{verbatim} {auth_method, ldap}. {ldap_servers, ["ldap.example.org"]}. {ldap_port, 389}. {ldap_rootdn, "cn=Manager,dc=domain,dc=org"}. {ldap_password, "secret"}. \end{verbatim} \makesubsubsection{ldapauth}{Authentication} You can authenticate users against an LDAP directory. Note that current LDAP implementation does not support SASL authentication. Available options are: \begin{description} \titem{\{ldap\_base, Base\}}\ind{options!ldap\_base}LDAP base directory which stores users accounts. This option is required. \titem{\{ldap\_uids, [ \{ldap\_uidattr\} | \{ldap\_uidattr, ldap\_uidattr\_format\}, ...]\}}\ind{options!ldap\_uids} LDAP attribute which holds a list of attributes to use as alternatives for getting the JID. The default attributes are \term{[\{"uid", "\%u"\}]}. The attributes are of the form: \term{[\{ldap\_uidattr\}]} or \term{[\{ldap\_uidattr, ldap\_uidattr\_format\}]}. You can use as many comma separated attributes as needed. The values for \term{ldap\_uidattr} and \term{ldap\_uidattr\_format} are described as follow: \begin{description} \titem{ldap\_uidattr}\ind{options!ldap\_uidattr}LDAP attribute which holds the user's part of a JID. The default value is \term{"uid"}. \titem{ldap\_uidattr\_format}\ind{options!ldap\_uidattr\_format}Format of the \term{ldap\_uidattr} variable. The format \emph{must} contain one and only one pattern variable \term{"\%u"} which will be replaced by the user's part of a JID. For example, \term{"\%u@example.org"}. The default value is \term{"\%u"}. \end{description} \titem{\{ldap\_filter, Filter\}}\ind{options!ldap\_filter}\ind{protocols!RFC 4515: LDAP String Representation of Search Filters} \footahref{http://tools.ietf.org/html/rfc4515}{RFC 4515} LDAP filter. The default Filter value is: \term{undefined}. Example: \term{"(\&(objectClass=shadowAccount)(memberOf=Jabber Users))"}. Please, do not forget to close brackets and do not use superfluous whitespaces. Also you \emph{must not} use \option{ldap\_uidattr} attribute in filter because this attribute will be substituted in LDAP filter automatically. \titem{\{ldap\_dn\_filter, \{ Filter, FilterAttrs \}\}}\ind{options!ldap\_dn\_filter} This filter is applied on the results returned by the main filter. This filter performs additional LDAP lookup to make the complete result. This is useful when you are unable to define all filter rules in \term{ldap\_filter}. You can define \term{"\%u"}, \term{"\%d"}, \term{"\%s"} and \term{"\%D"} pattern variables in Filter: \term{"\%u"} is replaced by a user's part of a JID, \term{"\%d"} is replaced by the corresponding domain (virtual host), all \term{"\%s"} variables are consecutively replaced by values of FilterAttrs attributes and \term{"\%D"} is replaced by Distinguished Name. By default \term{ldap\_dn\_filter} is undefined. Example: \begin{verbatim} {ldap_dn_filter, {"(&(name=%s)(owner=%D)(user=%u@%d))", ["sn"]}}. \end{verbatim} Since this filter makes additional LDAP lookups, use it only in the last resort: try to define all filter rules in \term{ldap\_filter} if possible. \titem{\{ldap\_local\_filter, Filter\}}\ind{options!ldap\_local\_filter} If you can't use \term{ldap\_filter} due to performance reasons (the LDAP server has many users registered), you can use this local filter. The local filter checks an attribute in ejabberd, not in LDAP, so this limits the load on the LDAP directory. The default filter is: \term{undefined}. Example values: \begin{verbatim} {ldap_local_filter, {notequal, {"accountStatus",["disabled"]}}}. {ldap_local_filter, {equal, {"accountStatus",["enabled"]}}}. {ldap_local_filter, undefined}. \end{verbatim} \end{description} \makesubsubsection{ldapexamples}{Examples} \makeparagraph{ldapcommonexample}{Common example} Let's say \term{ldap.example.org} is the name of our LDAP server. We have users with their passwords in \term{"ou=Users,dc=example,dc=org"} directory. Also we have addressbook, which contains users emails and their additional infos in \term{"ou=AddressBook,dc=example,dc=org"} directory. The connection to the LDAP server is encrypted using TLS, and using the custom port 6123. Corresponding authentication section should looks like this: \begin{verbatim} %% Authentication method {auth_method, ldap}. %% DNS name of our LDAP server {ldap_servers, ["ldap.example.org"]}. %% Bind to LDAP server as "cn=Manager,dc=example,dc=org" with password "secret" {ldap_rootdn, "cn=Manager,dc=example,dc=org"}. {ldap_password, "secret"}. {ldap_encrypt, tls}. {ldap_port, 6123}. %% Define the user's base {ldap_base, "ou=Users,dc=example,dc=org"}. %% We want to authorize users from 'shadowAccount' object class only {ldap_filter, "(objectClass=shadowAccount)"}. \end{verbatim} Now we want to use users LDAP-info as their vCards. We have four attributes defined in our LDAP schema: \term{"mail"} --- email address, \term{"givenName"} --- first name, \term{"sn"} --- second name, \term{"birthDay"} --- birthday. Also we want users to search each other. Let's see how we can set it up: \begin{verbatim} {modules, [ ... {mod_vcard_ldap, [ %% We use the same server and port, but want to bind anonymously because %% our LDAP server accepts anonymous requests to %% "ou=AddressBook,dc=example,dc=org" subtree. {ldap_rootdn, ""}, {ldap_password, ""}, %% define the addressbook's base {ldap_base, "ou=AddressBook,dc=example,dc=org"}, %% uidattr: user's part of JID is located in the "mail" attribute %% uidattr_format: common format for our emails {ldap_uids, [{"mail", "%u@mail.example.org"}]}, %% We have to define empty filter here, because entries in addressbook does not %% belong to shadowAccount object class {ldap_filter, ""}, %% Now we want to define vCard pattern {ldap_vcard_map, [{"NICKNAME", "%u", []}, % just use user's part of JID as his nickname {"GIVEN", "%s", ["givenName"]}, {"FAMILY", "%s", ["sn"]}, {"FN", "%s, %s", ["sn", "givenName"]}, % example: "Smith, John" {"EMAIL", "%s", ["mail"]}, {"BDAY", "%s", ["birthDay"]}]}, %% Search form {ldap_search_fields, [{"User", "%u"}, {"Name", "givenName"}, {"Family Name", "sn"}, {"Email", "mail"}, {"Birthday", "birthDay"}]}, %% vCard fields to be reported %% Note that JID is always returned with search results {ldap_search_reported, [{"Full Name", "FN"}, {"Nickname", "NICKNAME"}, {"Birthday", "BDAY"}]} ]}, ... ]}. \end{verbatim} Note that \modvcardldap{} module checks for the existence of the user before searching in his information in LDAP. \makeparagraph{ad}{Active Directory} \ind{databases!Active Directory} Active Directory is just an LDAP-server with predefined attributes. A sample configuration is shown below: \begin{verbatim} {auth_method, ldap}. {ldap_servers, ["office.org"]}. % List of LDAP servers {ldap_base, "DC=office,DC=org"}. % Search base of LDAP directory {ldap_rootdn, "CN=Administrator,CN=Users,DC=office,DC=org"}. % LDAP manager {ldap_password, "*******"}. % Password to LDAP manager {ldap_uids, [{"sAMAccountName"}]}. {ldap_filter, "(memberOf=*)"}. {modules, [ ... {mod_vcard_ldap, [{ldap_vcard_map, [{"NICKNAME", "%u", []}, {"GIVEN", "%s", ["givenName"]}, {"MIDDLE", "%s", ["initials"]}, {"FAMILY", "%s", ["sn"]}, {"FN", "%s", ["displayName"]}, {"EMAIL", "%s", ["mail"]}, {"ORGNAME", "%s", ["company"]}, {"ORGUNIT", "%s", ["department"]}, {"CTRY", "%s", ["c"]}, {"LOCALITY", "%s", ["l"]}, {"STREET", "%s", ["streetAddress"]}, {"REGION", "%s", ["st"]}, {"PCODE", "%s", ["postalCode"]}, {"TITLE", "%s", ["title"]}, {"URL", "%s", ["wWWHomePage"]}, {"DESC", "%s", ["description"]}, {"TEL", "%s", ["telephoneNumber"]}]}, {ldap_search_fields, [{"User", "%u"}, {"Name", "givenName"}, {"Family Name", "sn"}, {"Email", "mail"}, {"Company", "company"}, {"Department", "department"}, {"Role", "title"}, {"Description", "description"}, {"Phone", "telephoneNumber"}]}, {ldap_search_reported, [{"Full Name", "FN"}, {"Nickname", "NICKNAME"}, {"Email", "EMAIL"}]} ]}, ... ]}. \end{verbatim} \makesection{modules}{Modules Configuration} \ind{modules} The option \term{modules} defines the list of modules that will be loaded after \ejabberd{}'s startup. Each entry in the list is a tuple in which the first element is the name of a module and the second is a list of options for that module. The syntax is: \esyntax{\{modules, [ \{ModuleName, ModuleOptions\}, ...]\}.} Examples: \begin{itemize} \item In this example only the module \modecho{} is loaded and no module options are specified between the square brackets: \begin{verbatim} {modules, [ {mod_echo, []} ]}. \end{verbatim} \item In the second example the modules \modecho{}, \modtime{}, and \modversion{} are loaded without options. Remark that, besides the last entry, all entries end with a comma: \begin{verbatim} {modules, [ {mod_echo, []}, {mod_time, []}, {mod_version, []} ]}. \end{verbatim} \end{itemize} \makesubsection{modoverview}{Modules Overview} \ind{modules!overview}\ind{XMPP compliancy} The following table lists all modules included in \ejabberd{}. \begin{table}[H] \centering \begin{tabular}{|l|l|l|} \hline {\bf Module} & {\bf Feature} & {\bf Dependencies} \\ \hline \hline \modadhoc{} & Ad-Hoc Commands (\xepref{0050}) & \\ \hline \ahrefloc{modannounce}{\modannounce{}} & Manage announcements & recommends \modadhoc{} \\ \hline \ahrefloc{modannounce}{\modannounceodbc{}} & Manage announcements & recommends \modadhoc{} \\ & & supported DB (*) \\ \hline \modblocking{} & Simple Communications Blocking (\xepref{0191}) & \modprivacy{} \\ \hline \modblockingodbc{} & Simple Communications Blocking (\xepref{0191}) & \modprivacyodbc{} \\ \hline \modcaps{} & Entity Capabilities (\xepref{0115}) & \\ \hline \modconfigure{} & Server configuration using Ad-Hoc & \modadhoc{} \\ \hline \ahrefloc{moddisco}{\moddisco{}} & Service Discovery (\xepref{0030}) & \\ \hline \ahrefloc{modecho}{\modecho{}} & Echoes XMPP stanzas & \\ \hline \ahrefloc{modhttpbind}{\modhttpbind{}} & XMPP over Bosh service (HTTP Binding) & \\ \hline \ahrefloc{modhttpfileserver}{\modhttpfileserver{}} & Small HTTP file server & \\ \hline \ahrefloc{modirc}{\modirc{}} & IRC transport & \\ \hline \ahrefloc{modirc}{\modircodbc{}} & IRC transport & supported DB (*) \\ \hline \ahrefloc{modlast}{\modlast{}} & Last Activity (\xepref{0012}) & \\ \hline \ahrefloc{modlast}{\modlastodbc{}} & Last Activity (\xepref{0012}) & supported DB (*) \\ \hline \ahrefloc{modmuc}{\modmuc{}} & Multi-User Chat (\xepref{0045}) & \\ \hline \ahrefloc{modmuc}{\modmucodbc{}} & Multi-User Chat (\xepref{0045}) & supported DB (*) \\ \hline \ahrefloc{modmuclog}{\modmuclog{}} & Multi-User Chat room logging & \modmuc{} or \modmucodbc{} \\ \hline \ahrefloc{modoffline}{\modoffline{}} & Offline message storage (\xepref{0160}) & \\ \hline \ahrefloc{modoffline}{\modofflineodbc{}} & Offline message storage (\xepref{0160}) & supported DB (*) \\ \hline \ahrefloc{modping}{\modping{}} & XMPP Ping and periodic keepalives (\xepref{0199}) & \\ \hline \ahrefloc{modprescounter}{\modprescounter{}} & Detect presence subscription flood & \\ \hline \ahrefloc{modprivacy}{\modprivacy{}} & Blocking Communication (\xepref{0016}) & \\ \hline \ahrefloc{modprivacy}{\modprivacyodbc{}} & Blocking Communication (\xepref{0016}) & supported DB (*) \\ \hline \ahrefloc{modprivate}{\modprivate{}} & Private XML Storage (\xepref{0049}) & \\ \hline \ahrefloc{modprivate}{\modprivateodbc{}} & Private XML Storage (\xepref{0049}) & supported DB (*) \\ \hline \ahrefloc{modproxy}{\modproxy{}} & SOCKS5 Bytestreams (\xepref{0065}) & \\ \hline \ahrefloc{modpubsub}{\modpubsub{}} & Pub-Sub (\xepref{0060}), PEP (\xepref{0163}) & \modcaps{} \\ \hline \ahrefloc{modpubsub}{\modpubsubodbc{}} & Pub-Sub (\xepref{0060}), PEP (\xepref{0163}) & supported DB (*) and \modcaps{} \\ \hline \ahrefloc{modregister}{\modregister{}} & In-Band Registration (\xepref{0077}) & \\ \hline \ahrefloc{modregisterweb}{\modregisterweb{}} & Web for Account Registrations & \\ \hline \ahrefloc{modroster}{\modroster{}} & Roster management (XMPP IM) & \\ \hline \ahrefloc{modroster}{\modrosterodbc{}} & Roster management (XMPP IM) & supported DB (*) \\ \hline \ahrefloc{modservicelog}{\modservicelog{}} & Copy user messages to logger service & \\ \hline \ahrefloc{modsharedroster}{\modsharedroster{}} & Shared roster management & \modroster{} or \\ & & \modrosterodbc\\ \hline \ahrefloc{modsharedroster}{\modsharedrosterodbc{}} & Shared roster management & supported DB (*) and\\ & & \modroster{} or \modrosterodbc\\ \hline \ahrefloc{modsharedrosterldap}{\modsharedrosterldap{}} & LDAP Shared roster management & \modroster{} or \\ & & \modrosterodbc\\ \hline \ahrefloc{modsic}{\modsic{}} & Server IP Check (\xepref{0279}) & \\ \hline \ahrefloc{modstats}{\modstats{}} & Statistics Gathering (\xepref{0039}) & \\ \hline \ahrefloc{modtime}{\modtime{}} & Entity Time (\xepref{0202}) & \\ \hline \ahrefloc{modvcard}{\modvcard{}} & vcard-temp (\xepref{0054}) & \\ \hline \ahrefloc{modvcardldap}{\modvcardldap{}} & vcard-temp (\xepref{0054}) & LDAP server \\ \hline \ahrefloc{modvcard}{\modvcardodbc{}} & vcard-temp (\xepref{0054}) & supported DB (*) \\ \hline \ahrefloc{modvcardxupdate}{\modvcardxupdate{}} & vCard-Based Avatars (\xepref{0153}) & \modvcard{} or \modvcardodbc{} \\ \hline \ahrefloc{modvcardxupdate}{\modvcardxupdateodbc{}} & vCard-Based Avatars (\xepref{0153}) & \modvcard{} or \modvcardodbc{} \\ \hline \ahrefloc{modversion}{\modversion{}} & Software Version (\xepref{0092}) & \\ \hline \end{tabular} \end{table} \begin{itemize} \item (*) This module requires a supported database. For a list of supported databases, see section~\ref{database}. \end{itemize} You can see which database backend each module needs by looking at the suffix: \begin{itemize} \item No suffix, this means that the modules uses Erlang's built-in database Mnesia as backend. \item `\_odbc', this means that the module needs a supported database (see~\ref{database}) as backend. \item `\_ldap', this means that the module needs an LDAP server as backend. \end{itemize} If you want to, it is possible to use a relational database to store the tables created by some ejabberd modules. You can do this by changing the module name to a name with an \term{\_odbc} suffix in \ejabberd{} config file. You can use a relational database for the following data: \begin{itemize} \item Last connection date and time: Use \term{mod\_last\_odbc} instead of \term{mod\_last}. \item Offline messages: Use \term{mod\_offline\_odbc} instead of \term{mod\_offline}. \item Rosters: Use \term{mod\_roster\_odbc} instead of \term{mod\_roster}. \item Shared Rosters: Use \term{mod\_shared\_roster\_odbc} instead of \term{mod\_shared\_roster}. \item Users' VCARD: Use \term{mod\_vcard\_odbc} instead of \term{mod\_vcard}. \item vCard-Based Avatars: Use \term{mod\_vcard\_xupdate\_odbc} instead of \term{mod\_vcard\_xupdate}. \item Private XML storage: Use \term{mod\_private\_odbc} instead of \term{mod\_private}. \item User rules for blocking communications: Use \term{mod\_privacy\_odbc} instead of \term{mod\_privacy}. \item Simple Communications Blocking: Use \term{mod\_blocking\_odbc} instead of \term{mod\_blocking}. \item Pub-Sub nodes, items and subscriptions: Use \term{mod\_pubsub\_odbc} instead of \term{mod\_pubsub}. \item Multi-user chats: Use \term{mod\_muc\_odbc} instead of \term{mod\_muc}. \item Manage announcements: Use \term{mod\_announce\_odbc} instead of \term{mod\_announce}. \item IRC transport: Use \term{mod\_irc\_odbc} instead of \term{mod\_irc}. \end{itemize} You can find more \footahref{http://www.ejabberd.im/contributions}{contributed modules} on the \ejabberd{} website. Please remember that these contributions might not work or that they can contain severe bugs and security leaks. Therefore, use them at your own risk! \makesubsection{modcommonoptions}{Common Options} The following options are used by many modules. Therefore, they are described in this separate section. \makesubsubsection{modiqdiscoption}{\option{iqdisc}} \ind{options!iqdisc} Many modules define handlers for processing IQ queries of different namespaces to this server or to a user (e.\,g.\ to \jid{example.org} or to \jid{user@example.org}). This option defines processing discipline for these queries. The syntax is: \esyntax{\{iqdisc, Value\}} Possible \term{Value} are: \begin{description} \titem{no\_queue} All queries of a namespace with this processing discipline are processed directly. This means that the XMPP connection that sends this IQ query gets blocked: no other packets can be processed until this one has been completely processed. Hence this discipline is not recommended if the processing of a query can take a relatively long time. \titem{one\_queue} In this case a separate queue is created for the processing of IQ queries of a namespace with this discipline. In addition, the processing of this queue is done in parallel with that of other packets. This discipline is most recommended. \titem{\{queues, N\}} N separate queues are created to process the queries. The queries are thus processed in parallel, but in a controlled way. \titem{parallel} For every packet with this discipline a separate Erlang process is spawned. Consequently, all these packets are processed in parallel. Although spawning of Erlang process has a relatively low cost, this can break the server's normal work, because the Erlang emulator has a limit on the number of processes (32000 by default). \end{description} Example: \begin{verbatim} {modules, [ ... {mod_time, [{iqdisc, no_queue}]}, ... ]}. \end{verbatim} \makesubsubsection{modhostoption}{\option{host}} \ind{options!host} This option defines the Jabber ID of a service provided by an \ejabberd{} module. The syntax is: \esyntax{\{host, HostName\}} If you include the keyword "@HOST@" in the HostName, it is replaced at start time with the real virtual host string. This example configures the \ind{modules!\modecho{}}echo module to provide its echoing service in the Jabber ID \jid{mirror.example.org}: \begin{verbatim} {modules, [ ... {mod_echo, [{host, "mirror.example.org"}]}, ... ]}. \end{verbatim} However, if there are several virtual hosts and this module is enabled in all of them, the "@HOST@" keyword must be used: \begin{verbatim} {modules, [ ... {mod_echo, [{host, "mirror.@HOST@"}]}, ... ]}. \end{verbatim} \makesubsection{modannounce}{\modannounce{}} \ind{modules!\modannounce{}}\ind{MOTD}\ind{message of the day}\ind{announcements} This module enables configured users to broadcast announcements and to set the message of the day (MOTD). Configured users can perform these actions with a \XMPP{} client either using Ad-hoc commands or sending messages to specific JIDs. The Ad-hoc commands are listed in the Server Discovery. For this feature to work, \modadhoc{} must be enabled. The specific JIDs where messages can be sent are listed bellow. The first JID in each entry will apply only to the specified virtual host \jid{example.org}, while the JID between brackets will apply to all virtual hosts in ejabberd. \begin{description} \titem{example.org/announce/all (example.org/announce/all-hosts/all)} The message is sent to all registered users. If the user is online and connected to several resources, only the resource with the highest priority will receive the message. If the registered user is not connected, the message will be stored offline in assumption that \ind{modules!\modoffline{}}offline storage (see section~\ref{modoffline}) is enabled. \titem{example.org/announce/online (example.org/announce/all-hosts/online)}The message is sent to all connected users. If the user is online and connected to several resources, all resources will receive the message. \titem{example.org/announce/motd (example.org/announce/all-hosts/motd)}The message is set as the message of the day (MOTD) and is sent to users when they login. In addition the message is sent to all connected users (similar to \term{announce/online}). \titem{example.org/announce/motd/update (example.org/announce/all-hosts/motd/update)} The message is set as message of the day (MOTD) and is sent to users when they login. The message is \emph{not sent} to any currently connected user. \titem{example.org/announce/motd/delete (example.org/announce/all-hosts/motd/delete)} Any message sent to this JID removes the existing message of the day (MOTD). \end{description} Options: \begin{description} \titem{\{access, AccessName\}} \ind{options!access}This option specifies who is allowed to send announcements and to set the message of the day (by default, nobody is able to send such messages). \end{description} Examples: \begin{itemize} \item Only administrators can send announcements: \begin{verbatim} {access, announce, [{allow, admin}]}. {modules, [ ... {mod_adhoc, []}, {mod_announce, [{access, announce}]}, ... ]}. \end{verbatim} \item Administrators as well as the direction can send announcements: \begin{verbatim} {acl, direction, {user, "big_boss", "example.org"}}. {acl, direction, {user, "assistant", "example.org"}}. {acl, admin, {user, "admin", "example.org"}}. {access, announce, [{allow, admin}, {allow, direction}]}. {modules, [ ... {mod_adhoc, []}, {mod_announce, [{access, announce}]}, ... ]}. \end{verbatim} \end{itemize} Note that \modannounce{} can be resource intensive on large deployments as it can broadcast lot of messages. This module should be disabled for instances of \ejabberd{} with hundreds of thousands users. \makesubsection{moddisco}{\moddisco{}} \ind{modules!\moddisco{}} \ind{protocols!XEP-0030: Service Discovery} \ind{protocols!XEP-0011: Jabber Browsing} \ind{protocols!XEP-0094: Agent Information} \ind{protocols!XEP-0157: Contact Addresses for XMPP Services} This module adds support for Service Discovery (\xepref{0030}). With this module enabled, services on your server can be discovered by \XMPP{} clients. Note that \ejabberd{} has no modules with support for the superseded Jabber Browsing (\xepref{0011}) and Agent Information (\xepref{0094}). Accordingly, \XMPP{} clients need to have support for the newer Service Discovery protocol if you want them be able to discover the services you offer. Options: \begin{description} \iqdiscitem{Service Discovery (\ns{http://jabber.org/protocol/disco\#items} and \ns{http://jabber.org/protocol/disco\#info})} \titem{\{extra\_domains, [Domain, ...]\}} \ind{options!extra\_domains}With this option, you can specify a list of extra domains that are added to the Service Discovery item list. \titem{\{server\_info, [ \{Modules, Field, [Value, ...]\}, ... ]\}} \ind{options!server\_info} Specify additional information about the server, as described in Contact Addresses for XMPP Services (\xepref{0157}). \term{Modules} can be the keyword `all', in which case the information is reported in all the services; or a list of \ejabberd{} modules, in which case the information is only specified for the services provided by those modules. Any arbitrary \term{Field} and \term{Value} can be specified, not only contact addresses. \end{description} Examples: \begin{itemize} \item To serve a link to the Jabber User Directory on \jid{jabber.org}: \begin{verbatim} {modules, [ ... {mod_disco, [{extra_domains, ["users.jabber.org"]}]}, ... ]}. \end{verbatim} \item To serve a link to the transports on another server: \begin{verbatim} {modules, [ ... {mod_disco, [{extra_domains, ["icq.example.com", "msn.example.com"]}]}, ... ]}. \end{verbatim} \item To serve a link to a few friendly servers: \begin{verbatim} {modules, [ ... {mod_disco, [{extra_domains, ["example.org", "example.com"]}]}, ... ]}. \end{verbatim} \item With this configuration, all services show abuse addresses, feedback address on the main server, and admin addresses for both the main server and the vJUD service: \begin{verbatim} {modules, [ ... {mod_disco, [{server_info, [ {all, "abuse-addresses", ["mailto:abuse@shakespeare.lit"]}, {[mod_muc], "Web chatroom logs", ["http://www.example.org/muc-logs"]}, {[mod_disco], "feedback-addresses", ["http://shakespeare.lit/feedback.php", "mailto:feedback@shakespeare.lit", "xmpp:feedback@shakespeare.lit"]}, {[mod_disco, mod_vcard], "admin-addresses", ["mailto:xmpp@shakespeare.lit", "xmpp:admins@shakespeare.lit"]} ]}]}, ... ]}. \end{verbatim} \end{itemize} \makesubsection{modecho}{\modecho{}} \ind{modules!\modecho{}}\ind{debugging} This module simply echoes any \XMPP{} packet back to the sender. This mirror can be of interest for \ejabberd{} and \XMPP{} client debugging. Options: \begin{description} \hostitem{echo} \end{description} Example: Mirror, mirror, on the wall, who is the most beautiful of them all? \begin{verbatim} {modules, [ ... {mod_echo, [{host, "mirror.example.org"}]}, ... ]}. \end{verbatim} \makesubsection{modhttpbind}{\modhttpbind{}} \ind{modules!\modhttpbind{}}\ind{modhttpbind} This module implements XMPP over Bosh (formerly known as HTTP Binding) as defined in \xepref{0124} and \xepref{0206}. It extends ejabberd's built in HTTP service with a configurable resource at which this service will be hosted. To use HTTP-Binding, enable the module: \begin{verbatim} {modules, [ ... {mod_http_bind, []}, ... ]}. \end{verbatim} and add \verb|http_bind| in the HTTP service. For example: \begin{verbatim} {listen, [ ... {5280, ejabberd_http, [ http_bind, http_poll, web_admin ] }, ... ]}. \end{verbatim} With this configuration, the module will serve the requests sent to \verb|http://example.org:5280/http-bind/| Remember that this page is not designed to be used by web browsers, it is used by XMPP clients that support XMPP over Bosh. If you want to set the service in a different URI path or use a different module, you can configure it manually using the option \verb|request_handlers|. For example: \begin{verbatim} {listen, [ ... {5280, ejabberd_http, [ {request_handlers, [{["http-bind"], mod_http_bind}]}, http_poll, web_admin ] }, ... ]}. \end{verbatim} Options: \begin{description} \titem{\{max\_inactivity, Seconds\}} \ind{options!max\_inactivity} Define the maximum inactivity period in seconds. Default value is 30 seconds. For example, to set 50 seconds: \begin{verbatim} {modules, [ ... {mod_http_bind, [ {max_inactivity, 50} ]}, ... ]}. \end{verbatim} \end{description} \makesubsection{modhttpfileserver}{\modhttpfileserver{}} \ind{modules!\modhttpfileserver{}}\ind{modhttpfileserver} This simple module serves files from the local disk over HTTP. Options: \begin{description} \titem{\{docroot, Path\}} \ind{options!docroot} Directory to serve the files. \titem{\{accesslog, Path\}} \ind{options!accesslog} File to log accesses using an Apache-like format. No log will be recorded if this option is not specified. \titem{\{directory\_indices, [Index, ...]\}} \ind{options!directoryindices} Indicate one or more directory index files, similarly to Apache's DirectoryIndex variable. When a web request hits a directory instead of a regular file, those directory indices are looked in order, and the first one found is returned. \titem{\{custom\_headers, [ \{Name, Value\}, ...]\}} \ind{options!customheaders} Indicate custom HTTP headers to be included in all responses. Default value is: \term{[]} \titem{\{content\_types, [ \{Name, Type\}, ...]\}} \ind{options!contenttypes} Specify mappings of extension to content type. There are several content types already defined, with this option you can add new definitions, modify or delete existing ones. To delete an existing definition, simply define it with a value: `undefined'. \titem{\{default\_content\_type, Type\}} \ind{options!defaultcontenttype} Specify the content type to use for unknown extensions. Default value is `application/octet-stream'. \end{description} This example configuration will serve the files from the local directory \verb|/var/www| in the address \verb|http://example.org:5280/pub/archive/|. In this example a new content type \term{ogg} is defined, \term{png} is redefined, and \term{jpg} definition is deleted. To use this module you must enable it: \begin{verbatim} {modules, [ ... {mod_http_fileserver, [ {docroot, "/var/www"}, {accesslog, "/var/log/ejabberd/access.log"}, {directory_indices, ["index.html", "main.htm"]}, {custom_headers, [{"X-Powered-By", "Erlang/OTP"}, {"X-Fry", "It's a widely-believed fact!"} ]}, {content_types, [{".ogg", "audio/ogg"}, {".png", "image/png"}, {".jpg", undefined} ]}, {default_content_type, "text/html"} ] }, ... ]}. \end{verbatim} And define it as a handler in the HTTP service: \begin{verbatim} {listen, [ ... {5280, ejabberd_http, [ ... {request_handlers, [ ... {["pub", "archive"], mod_http_fileserver}, ... ] }, ... ] }, ... ]}. \end{verbatim} \makesubsection{modirc}{\modirc{}} \ind{modules!\modirc{}}\ind{IRC} This module is an IRC transport that can be used to join channels on IRC servers. End user information: \ind{protocols!groupchat 1.0}\ind{protocols!XEP-0045: Multi-User Chat} \begin{itemize} \item A \XMPP{} client with `groupchat 1.0' support or Multi-User Chat support (\xepref{0045}) is necessary to join IRC channels. \item An IRC channel can be joined in nearly the same way as joining a \XMPP{} Multi-User Chat room. The difference is that the room name will be `channel\%\jid{irc.example.org}' in case \jid{irc.example.org} is the IRC server hosting `channel'. And of course the host should point to the IRC transport instead of the Multi-User Chat service. \item You can register your nickame by sending `IDENTIFY password' to \\ \jid{nickserver!irc.example.org@irc.jabberserver.org}. \item Entering your password is possible by sending `LOGIN nick password' \\ to \jid{nickserver!irc.example.org@irc.jabberserver.org}. \item The IRC transport provides Ad-Hoc Commands (\xepref{0050}) to join a channel, and to set custom IRC username and encoding. \item When using a popular \XMPP{} server, it can occur that no connection can be achieved with some IRC servers because they limit the number of connections from one IP. \end{itemize} Options: \begin{description} \hostitem{irc} \titem{\{access, AccessName\}} \ind{options!access}This option can be used to specify who may use the IRC transport (default value: \term{all}). \titem{\{default\_encoding, Encoding\}} \ind{options!defaultencoding}Set the default IRC encoding. Default value: \term{"iso8859-1"} \end{description} Examples: \begin{itemize} \item In the first example, the IRC transport is available on (all) your virtual host(s) with the prefix `\jid{irc.}'. Furthermore, anyone is able to use the transport. The default encoding is set to "iso8859-15". \begin{verbatim} {modules, [ ... {mod_irc, [{access, all}, {default_encoding, "iso8859-15"}]}, ... ]}. \end{verbatim} \item In next example the IRC transport is available with JIDs with prefix \jid{irc-t.net}. Moreover, the transport is only accessible to two users of \term{example.org}, and any user of \term{example.com}: \begin{verbatim} {acl, paying_customers, {user, "customer1", "example.org"}}. {acl, paying_customers, {user, "customer2", "example.org"}}. {acl, paying_customers, {server, "example.com"}}. {access, irc_users, [{allow, paying_customers}, {deny, all}]}. {modules, [ ... {mod_irc, [{access, irc_users}, {host, "irc.example.net"}]}, ... ]}. \end{verbatim} \end{itemize} \makesubsection{modlast}{\modlast{}} \ind{modules!\modlast{}}\ind{protocols!XEP-0012: Last Activity} This module adds support for Last Activity (\xepref{0012}). It can be used to discover when a disconnected user last accessed the server, to know when a connected user was last active on the server, or to query the uptime of the \ejabberd{} server. Options: \begin{description} \iqdiscitem{Last activity (\ns{jabber:iq:last})} \end{description} \makesubsection{modmuc}{\modmuc{}} \ind{modules!\modmuc{}}\ind{protocols!XEP-0045: Multi-User Chat}\ind{conferencing} This module provides a Multi-User Chat (\xepref{0045}) service. Users can discover existing rooms, join or create them. Occupants of a room can chat in public or have private chats. Some of the features of Multi-User Chat: \begin{itemize} \item Sending public and private messages to room occupants. \item Inviting other users to a room. \item Setting a room subject. \item Creating password protected rooms. \item Kicking and banning occupants. \end{itemize} The MUC service allows any Jabber ID to register a nickname, so nobody else can use that nickname in any room in the MUC service. To register a nickname, open the Service Discovery in your XMPP client and register in the MUC service. This module supports clustering and load balancing. One module can be started per cluster node. Rooms are distributed at creation time on all available MUC module instances. The multi-user chat module is clustered but the rooms themselves are not clustered nor fault-tolerant: if the node managing a set of rooms goes down, the rooms disappear and they will be recreated on an available node on first connection attempt. Module options: \begin{description} \hostitem{conference} \titem{\{access, AccessName\}} \ind{options!access}You can specify who is allowed to use the Multi-User Chat service. By default everyone is allowed to use it. \titem{\{access\_create, AccessName\}} \ind{options!access\_create}To configure who is allowed to create new rooms at the Multi-User Chat service, this option can be used. By default any account in the local ejabberd server is allowed to create rooms. \titem{\{access\_persistent, AccessName\}} \ind{options!access\_persistent}To configure who is allowed to modify the 'persistent' room option. By default any account in the local ejabberd server is allowed to modify that option. \titem{\{access\_admin, AccessName\}} \ind{options!access\_admin}This option specifies who is allowed to administrate the Multi-User Chat service. The default value is \term{none}, which means that only the room creator can administer his room. The administrators can send a normal message to the service JID, and it will be shown in all active rooms as a service message. The administrators can send a groupchat message to the JID of an active room, and the message will be shown in the room as a service message. \titem{\{history\_size, Size\}} \ind{options!history\_size}A small history of the current discussion is sent to users when they enter the room. With this option you can define the number of history messages to keep and send to users joining the room. The value is an integer. Setting the value to \term{0} disables the history feature and, as a result, nothing is kept in memory. The default value is \term{20}. This value is global and thus affects all rooms on the service. \titem{\{max\_users, Number\}} \ind{options!max\_users} This option defines at the service level, the maximum number of users allowed per room. It can be lowered in each room configuration but cannot be increased in individual room configuration. The default value is 200. \titem{\{max\_users\_admin\_threshold, Number\}} \ind{options!max\_users\_admin\_threshold} This option defines the number of service admins or room owners allowed to enter the room when the maximum number of allowed occupants was reached. The default limit is 5. \titem{\{max\_user\_conferences, Number\}} \ind{options!max\_user\_conferences} This option defines the maximum number of rooms that any given user can join. The default value is 10. This option is used to prevent possible abuses. Note that this is a soft limit: some users can sometimes join more conferences in cluster configurations. \titem{\{max\_room\_id, Number\}} \ind{options!max\_room\_id} This option defines the maximum number of characters that Room ID can have when creating a new room. The default value is to not limit: infinite. \titem{\{max\_room\_name, Number\}} \ind{options!max\_room\_name} This option defines the maximum number of characters that Room Name can have when configuring the room. The default value is to not limit: infinite. \titem{\{max\_room\_desc, Number\}} \ind{options!max\_room\_desc} This option defines the maximum number of characters that Room Description can have when configuring the room. The default value is to not limit: infinite. \titem{\{min\_message\_interval, Number\}} \ind{options!min\_message\_interval} This option defines the minimum interval between two messages send by an occupant in seconds. This option is global and valid for all rooms. A decimal value can be used. When this option is not defined, message rate is not limited. This feature can be used to protect a MUC service from occupant abuses and limit number of messages that will be broadcasted by the service. A good value for this minimum message interval is 0.4 second. If an occupant tries to send messages faster, an error is send back explaining that the message has been discarded and describing the reason why the message is not acceptable. \titem{\{min\_presence\_interval, Number\}} \ind{options!min\_presence\_interval} This option defines the minimum of time between presence changes coming from a given occupant in seconds. This option is global and valid for all rooms. A decimal value can be used. When this option is not defined, no restriction is applied. This option can be used to protect a MUC service for occupants abuses. If an occupant tries to change its presence more often than the specified interval, the presence is cached by \ejabberd{} and only the last presence is broadcasted to all occupants in the room after expiration of the interval delay. Intermediate presence packets are silently discarded. A good value for this option is 4 seconds. \titem{\{default\_room\_options, [ \{OptionName, OptionValue\}, ...]\}} \ind{options!default\_room\_options} This module option allows to define the desired default room options. Note that the creator of a room can modify the options of his room at any time using an XMPP client with MUC capability. The available room options and the default values are: \begin{description} \titem{\{allow\_change\_subj, true|false\}} Allow occupants to change the subject. \titem{\{allow\_private\_messages, true|false\}} Occupants can send private messages to other occupants. \titem{\{allow\_private\_messages\_from\_visitors, anyone|moderators|nobody\}} Visitors can send private messages to other occupants. \titem{\{allow\_query\_users, true|false\}} Occupants can send IQ queries to other occupants. \titem{\{allow\_user\_invites, false|true\}} Allow occupants to send invitations. \titem{\{allow\_visitor\_nickchange, true|false\}} Allow visitors to change nickname. \titem{\{allow\_visitor\_status, true|false\}} Allow visitors to send status text in presence updates. If disallowed, the \term{status} text is stripped before broadcasting the presence update to all the room occupants. \titem{\{anonymous, true|false\}} The room is anonymous: occupants don't see the real JIDs of other occupants. Note that the room moderators can always see the real JIDs of the occupants. \titem{\{captcha\_protected, false\}} When a user tries to join a room where he has no affiliation (not owner, admin or member), the room requires him to fill a CAPTCHA challenge (see section \ref{captcha}) in order to accept her join in the room. \titem{\{logging, false|true\}} The public messages are logged using \term{mod\_muc\_log}. \titem{\{max\_users, 200\}} Maximum number of occupants in the room. \titem{\{members\_by\_default, true|false\}} The occupants that enter the room are participants by default, so they have 'voice'. \titem{\{members\_only, false|true\}} Only members of the room can enter. \titem{\{moderated, true|false\}} Only occupants with 'voice' can send public messages. \titem{\{password, "roompass123"\}} Password of the room. You may want to enable the next option too. \titem{\{password\_protected, false|true\}} The password is required to enter the room. \titem{\{persistent, false|true\}} The room persists even if the last participant leaves. \titem{\{public, true|false\}} The room is public in the list of the MUC service, so it can be discovered. \titem{\{public\_list, true|false\}} The list of participants is public, without requiring to enter the room. \titem{\{title, "Room Title"\}} A human-readable title of the room. \end{description} All of those room options can be set to \term{true} or \term{false}, except \term{password} and \term{title} which are strings, and \term{max\_users} that is integer. \end{description} Examples: \begin{itemize} \item In the first example everyone is allowed to use the Multi-User Chat service. Everyone will also be able to create new rooms but only the user \jid{admin@example.org} is allowed to administrate any room. In this example he is also a global administrator. When \jid{admin@example.org} sends a message such as `Tomorrow, the \XMPP{} server will be moved to new hardware. This will involve service breakdowns around 23:00 UMT. We apologise for this inconvenience.' to \jid{conference.example.org}, it will be displayed in all active rooms. In this example the history feature is disabled. \begin{verbatim} {acl, admin, {user, "admin", "example.org"}}. {access, muc_admin, [{allow, admin}]}. {modules, [ ... {mod_muc, [{access, all}, {access_create, all}, {access_admin, muc_admin}, {history_size, 0}]}, ... ]}. \end{verbatim} \item In the second example the Multi-User Chat service is only accessible by paying customers registered on our domains and on other servers. Of course the administrator is also allowed to access rooms. In addition, he is the only authority able to create and administer rooms. When \jid{admin@example.org} sends a message such as `Tomorrow, the \Jabber{} server will be moved to new hardware. This will involve service breakdowns around 23:00 UMT. We apologise for this inconvenience.' to \jid{conference.example.org}, it will be displayed in all active rooms. No \term{history\_size} option is used, this means that the feature is enabled and the default value of 20 history messages will be send to the users. \begin{verbatim} {acl, paying_customers, {user, "customer1", "example.net"}}. {acl, paying_customers, {user, "customer2", "example.com"}}. {acl, paying_customers, {user, "customer3", "example.org"}}. {acl, admin, {user, "admin", "example.org"}}. {access, muc_admin, [{allow, admin}, {deny, all}]}. {access, muc_access, [{allow, paying_customers}, {allow, admin}, {deny, all}]}. {modules, [ ... {mod_muc, [{access, muc_access}, {access_create, muc_admin}, {access_admin, muc_admin}]}, ... ]}. \end{verbatim} \item In the following example, MUC anti abuse options are used. An occupant cannot send more than one message every 0.4 seconds and cannot change its presence more than once every 4 seconds. The length of Room IDs and Room Names are limited to 20 characters, and Room Description to 300 characters. No ACLs are defined, but some user restriction could be added as well: \begin{verbatim} {modules, [ ... {mod_muc, [{min_message_interval, 0.4}, {min_presence_interval, 4}, {max_room_id, 20}, {max_room_name, 20}, {max_room_desc, 300}]}, ... ]}. \end{verbatim} \item This example shows how to use \option{default\_room\_options} to make sure the newly created rooms have by default those options. \begin{verbatim} {modules, [ ... {mod_muc, [{access, muc_access}, {access_create, muc_admin}, {default_room_options, [ {allow_change_subj, false}, {allow_query_users, true}, {allow_private_messages, true}, {members_by_default, false}, {title, "New chatroom"}, {anonymous, false} ]}, {access_admin, muc_admin}]}, ... ]}. \end{verbatim} \end{itemize} \makesubsection{modmuclog}{\modmuclog{}} \ind{modules!\modmuclog{}} This module enables optional logging of Multi-User Chat (MUC) public conversations to HTML. Once you enable this module, users can join a room using a MUC capable XMPP client, and if they have enough privileges, they can request the configuration form in which they can set the option to enable room logging. Features: \begin{itemize} \item Room details are added on top of each page: room title, JID, author, subject and configuration. \item \ind{protocols!RFC 5122: Internationalized Resource Identifiers (IRIs) and Uniform Resource Identifiers (URIs) for the Extensible Messaging and Presence Protocol (XMPP)} The room JID in the generated HTML is a link to join the room (using \footahref{http://xmpp.org/rfcs/rfc5122.html}{XMPP URI}). \item Subject and room configuration changes are tracked and displayed. \item Joins, leaves, nick changes, kicks, bans and `/me' are tracked and displayed, including the reason if available. \item Generated HTML files are XHTML 1.0 Transitional and CSS compliant. \item Timestamps are self-referencing links. \item Links on top for quicker navigation: Previous day, Next day, Up. \item CSS is used for style definition, and a custom CSS file can be used. \item URLs on messages and subjects are converted to hyperlinks. \item Timezone used on timestamps is shown on the log files. \item A custom link can be added on top of each page. \end{itemize} Options: \begin{description} \titem{\{access\_log, AccessName\}}\ind{options!access\_log} This option restricts which occupants are allowed to enable or disable room logging. The default value is \term{muc\_admin}. Note for this default setting you need to have an access rule for \term{muc\_admin} in order to take effect. \titem{\{cssfile, false|URL\}}\ind{options!cssfile} With this option you can set whether the HTML files should have a custom CSS file or if they need to use the embedded CSS file. Allowed values are \term{false} and an URL to a CSS file. With the first value, HTML files will include the embedded CSS code. With the latter, you can specify the URL of the custom CSS file (for example: \term{"http://example.com/my.css"}). The default value is \term{false}. \titem{\{dirname, room\_jid|room\_name\}}\ind{options!dirname} Allows to configure the name of the room directory. Allowed values are \term{room\_jid} and \term{room\_name}. With the first value, the room directory name will be the full room JID. With the latter, the room directory name will be only the room name, not including the MUC service name. The default value is \term{room\_jid}. \titem{\{dirtype, subdirs|plain\}}\ind{options!dirtype} The type of the created directories can be specified with this option. Allowed values are \term{subdirs} and \term{plain}. With the first value, subdirectories are created for each year and month. With the latter, the names of the log files contain the full date, and there are no subdirectories. The default value is \term{subdirs}. \titem{\{file\_format, html|plaintext\}}\ind{options!file\_format} Define the format of the log files: \term{html} stores in HTML format, \term{plaintext} stores in plain text. The default value is \term{html}. \titem{\{outdir, Path\}}\ind{options!outdir} This option sets the full path to the directory in which the HTML files should be stored. Make sure the \ejabberd{} daemon user has write access on that directory. The default value is \term{"www/muc"}. \titem{\{spam\_prevention true|false\}}\ind{options!spam\_prevention} To prevent spam, the \term{spam\_prevention} option adds a special attribute to links that prevent their indexation by search engines. The default value is \term{true}, which mean that nofollow attributes will be added to user submitted links. \titem{\{timezone, local|universal\}}\ind{options!timezone} The time zone for the logs is configurable with this option. Allowed values are \term{local} and \term{universal}. With the first value, the local time, as reported to Erlang by the operating system, will be used. With the latter, GMT/UTC time will be used. The default value is \term{local}. \titem{\{top\_link, \{URL, Text\}\}}\ind{options!top\_link} With this option you can customize the link on the top right corner of each log file. The default value is \term{\{"/", "Home"\}}. \end{description} Examples: \begin{itemize} \item In the first example any room owner can enable logging, and a custom CSS file will be used (http://example.com/my.css). The names of the log files will contain the full date, and there will be no subdirectories. The log files will be stored in /var/www/muclogs, and the time zone will be GMT/UTC. Finally, the top link will be \verb|Jabber.ru|. \begin{verbatim} {access, muc, [{allow, all}]}. {modules, [ ... {mod_muc_log, [ {access_log, muc}, {cssfile, "http://example.com/my.css"}, {dirtype, plain}, {dirname, room_jid}, {outdir, "/var/www/muclogs"}, {timezone, universal}, {spam_prevention, true}, {top_link, {"http://www.jabber.ru/", "Jabber.ru"}} ]}, ... ]}. \end{verbatim} \item In the second example only \jid{admin1@example.org} and \jid{admin2@example.net} can enable logging, and the embedded CSS file will be used. The names of the log files will only contain the day (number), and there will be subdirectories for each year and month. The log files will be stored in /var/www/muclogs, and the local time will be used. Finally, the top link will be the default \verb|Home|. \begin{verbatim} {acl, admin, {user, "admin1", "example.org"}}. {acl, admin, {user, "admin2", "example.net"}}. {access, muc_log, [{allow, admin}, {deny, all}]}. {modules, [ ... {mod_muc_log, [ {access_log, muc_log}, {cssfile, false}, {dirtype, subdirs}, {outdir, "/var/www/muclogs"}, {timezone, local} ]}, ... ]}. \end{verbatim} \end{itemize} \makesubsection{modoffline}{\modoffline{}} \ind{modules!\modoffline{}} This module implements offline message storage (\xepref{0160}). This means that all messages sent to an offline user will be stored on the server until that user comes online again. Thus it is very similar to how email works. Note that \term{ejabberdctl}\ind{ejabberdctl} has a command to delete expired messages (see section~\ref{ejabberdctl}). \begin{description} \titem{\{access\_max\_user\_messages, AccessName\}}\ind{options!access\_max\_user\_messages} This option defines which access rule will be enforced to limit the maximum number of offline messages that a user can have (quota). When a user has too many offline messages, any new messages that he receive are discarded, and a resource-constraint error is returned to the sender. The default value is \term{max\_user\_offline\_messages}. Then you can define an access rule with a syntax similar to \term{max\_user\_sessions} (see \ref{configmaxsessions}). \end{description} This example allows power users to have as much as 5000 offline messages, administrators up to 2000, and all the other users up to 100. \begin{verbatim} {acl, admin, {user, "admin1", "localhost"}}. {acl, admin, {user, "admin2", "example.org"}}. {acl, poweruser, {user, "bob", "example.org"}}. {acl, poweruser, {user, "jane", "example.org"}}. {access, max_user_offline_messages, [ {5000, poweruser}, {2000, admin}, {100, all} ]}. {modules, [ ... {mod_offline, [ {access_max_user_messages, max_user_offline_messages} ]}, ... ]}. \end{verbatim} \makesubsection{modping}{\modping{}} \ind{modules!\modping{}} This module implements support for XMPP Ping (\xepref{0199}) and periodic keepalives. When this module is enabled ejabberd responds correctly to ping requests, as defined in the protocol. Configuration options: \begin{description} \titem{\{send\_pings, true|false\}}\ind{options!send\_pings} If this option is set to \term{true}, the server sends pings to connected clients that are not active in a given interval \term{ping\_interval}. This is useful to keep client connections alive or checking availability. By default this option is disabled. % because it is mostly not needed and consumes resources. \titem{\{ping\_interval, Seconds\}}\ind{options!ping\_interval} How often to send pings to connected clients, if the previous option is enabled. If a client connection does not send or receive any stanza in this interval, a ping request is sent to the client. The default value is 60 seconds. \titem{\{timeout\_action, none|kill\}}\ind{options!timeout\_action} What to do when a client does not answer to a server ping request in less than 32 seconds. % Those 32 seconds are defined in ejabberd_local.erl: -define(IQ_TIMEOUT, 32000). The default is to do nothing. \end{description} This example enables Ping responses, configures the module to send pings to client connections that are inactive for 4 minutes, and if a client does not answer to the ping in less than 32 seconds, its connection is closed: \begin{verbatim} {modules, [ ... {mod_ping, [{send_pings, true}, {ping_interval, 240}, {timeout_action, kill}]}, ... ]}. \end{verbatim} \makesubsection{modprescounter}{\modprescounter{}} \ind{modules!\modprescounter{}} This module detects flood/spam in presence subscription stanza traffic. If a user sends or receives more of those stanzas in a time interval, the exceeding stanzas are silently dropped, and warning is logged. Configuration options: \begin{description} \titem{\{count, StanzaNumber\}}\ind{options!count} The number of subscription presence stanzas (subscribe, unsubscribe, subscribed, unsubscribed) allowed for any direction (input or output) per time interval. Please note that two users subscribing to each other usually generate 4 stanzas, so the recommended value is 4 or more. The default value is: 5. \titem{\{interval, Seconds\}}\ind{options!interval} The time interval defined in seconds. The default value is 60. \end{description} This example enables the module, and allows up to 5 presence subscription stanzas to be sent or received by the users in 60 seconds: \begin{verbatim} {modules, [ ... {mod_pres_counter, [{count, 5}, {interval, 60}]}, ... ]}. \end{verbatim} \makesubsection{modprivacy}{\modprivacy{}} \ind{modules!\modprivacy{}}\ind{Blocking Communication}\ind{Privacy Rules}\ind{protocols!RFC 3921: XMPP IM} This module implements Blocking Communication (also known as Privacy Rules) as defined in section 10 from XMPP IM. If end users have support for it in their \XMPP{} client, they will be able to: \begin{quote} \begin{itemize} \item Retrieving one's privacy lists. \item Adding, removing, and editing one's privacy lists. \item Setting, changing, or declining active lists. \item Setting, changing, or declining the default list (i.e., the list that is active by default). \item Allowing or blocking messages based on JID, group, or subscription type (or globally). \item Allowing or blocking inbound presence notifications based on JID, group, or subscription type (or globally). \item Allowing or blocking outbound presence notifications based on JID, group, or subscription type (or globally). \item Allowing or blocking IQ stanzas based on JID, group, or subscription type (or globally). \item Allowing or blocking all communications based on JID, group, or subscription type (or globally). \end{itemize} (from \ahrefurl{http://xmpp.org/rfcs/rfc3921.html\#privacy}) \end{quote} Options: \begin{description} \iqdiscitem{Blocking Communication (\ns{jabber:iq:privacy})} \end{description} \makesubsection{modprivate}{\modprivate{}} \ind{modules!\modprivate{}}\ind{protocols!XEP-0049: Private XML Storage}\ind{protocols!XEP-0048: Bookmark Storage} This module adds support for Private XML Storage (\xepref{0049}): \begin{quote} Using this method, XMPP entities can store private data on the server and retrieve it whenever necessary. The data stored might be anything, as long as it is valid XML. One typical usage for this namespace is the server-side storage of client-specific preferences; another is Bookmark Storage (\xepref{0048}). \end{quote} Options: \begin{description} \iqdiscitem{Private XML Storage (\ns{jabber:iq:private})} \end{description} \makesubsection{modproxy}{\modproxy{}} \ind{modules!\modversion{}}\ind{protocols!XEP-0065: SOCKS5 Bytestreams} This module implements SOCKS5 Bytestreams (\xepref{0065}). It allows \ejabberd{} to act as a file transfer proxy between two XMPP clients. Options: \begin{description} \hostitem{proxy} \titem{\{name, Text\}}\ind{options!name}Defines Service Discovery name of the service. Default is \term{"SOCKS5 Bytestreams"}. \titem{\{ip, IPTuple\}}\ind{options!ip}This option specifies which network interface to listen for. Default is an IP address of the service's DNS name, or, if fails, \verb|{127,0,0,1}|. \titem{\{port, Number\}}\ind{options!port}This option defines port to listen for incoming connections. Default is~7777. \titem{\{hostname, HostName\}}\ind{options!hostname}Defines a hostname advertised by the service when establishing a session with clients. This is useful when you run the service behind a NAT. The default is the value of \term{ip} option. Examples: \term{"proxy.mydomain.org"}, \term{"200.150.100.50"}. Note that not all clients understand domain names in stream negotiation, so you should think twice before setting domain name in this option. \titem{\{auth\_type, anonymous|plain\}}\ind{options!auth\_type}SOCKS5 authentication type. Possible values are \term{anonymous} and \term{plain}. Default is \term{anonymous}. \titem{\{access, AccessName\}}\ind{options!access}Defines ACL for file transfer initiators. Default is \term{all}. \titem{\{max\_connections, Number\}}\ind{options!max\_connections}Maximum number of active connections per file transfer initiator. No limit by default. \titem{\{shaper, none|ShaperName\}}\ind{options!shaper}This option defines shaper for the file transfer peers. Shaper with the maximum bandwidth will be selected. Default is \term{none}. \end{description} Examples: \begin{itemize} \item The simpliest configuration of the module: \begin{verbatim} {modules, [ ... {mod_proxy65, []}, ... ]}. \end{verbatim} \item More complicated configuration. \begin{verbatim} {acl, proxy_users, {server, "example.org"}}. {access, proxy65_access, [{allow, proxy_users}, {deny, all}]}. {acl, admin, {user, "admin", "example.org"}}. {shaper, proxyrate, {maxrate, 10240}}. %% 10 Kbytes/sec {access, proxy65_shaper, [{none, admin}, {proxyrate, proxy_users}]}. {modules, [ ... {mod_proxy65, [{host, "proxy1.example.org"}, {name, "File Transfer Proxy"}, {ip, {200,150,100,1}}, {port, 7778}, {max_connections, 5}, {access, proxy65_access}, {shaper, proxy65_shaper}]}, ... ]}. \end{verbatim} \end{itemize} \makesubsection{modpubsub}{\modpubsub{}} \ind{modules!\modpubsub{}}\ind{protocols!XEP-0060: Publish-Subscribe} This module offers a Publish-Subscribe Service (\xepref{0060}). The functionality in \modpubsub{} can be extended using plugins. The plugin that implements PEP (Personal Eventing via Pubsub) (\xepref{0163}) is enabled in the default ejabberd configuration file, and it requires \modcaps{}. Options: \begin{description} \hostitem{pubsub} If you use \modpubsubodbc, please ensure the prefix contains only one dot, for example `\jid{pubsub.}', or `\jid{publish.}',. \titem{\{access\_createnode, AccessName\}} \ind{options!access\_createnode} This option restricts which users are allowed to create pubsub nodes using ACL and ACCESS. By default any account in the local ejabberd server is allowed to create pubsub nodes. \titem{\{max\_items\_node, MaxItems\}} \ind{options!max\_items\_node} Define the maximum number of items that can be stored in a node. Default value is 10. \titem{\{plugins, [ Plugin, ...]\}} \ind{options!plugins} To specify which pubsub node plugins to use. The first one in the list is used by default. If this option is not defined, the default plugins list is: \term{["flat"]}. PubSub clients can define which plugin to use when creating a node: add \term{type='plugin-name'} attribute to the \term{create} stanza element. \titem{\{nodetree, Nodetree\}} \ind{options!nodetree} To specify which nodetree to use. If not defined, the default pubsub nodetree is used: "tree". Only one nodetree can be used per host, and is shared by all node plugins. The "virtual" nodetree does not store nodes on database. This saves resources on systems with tons of nodes. If using the "virtual" nodetree, you can only enable those node plugins: ["flat","pep"] or ["flat"]; any other plugins configuration will not work. Also, all nodes will have the defaut configuration, and this can not be changed. Using "virtual" nodetree requires to start from a clean database, it will not work if you used the default "tree" nodetree before. The "dag" nodetree provides experimental support for PubSub Collection Nodes (\xepref{0248}). In that case you should also add "dag" node plugin as default, for example: \term{\{plugins, ["dag","flat","hometree","pep"]\}} \titem{\{ignore\_pep\_from\_offline, false|true\}} \ind{options!ignore\_pep\_from\_offline} To specify whether or not we should get last published PEP items from users in our roster which are offline when we connect. Value is true or false. If not defined, pubsub assumes true so we only get last items of online contacts. \titem{\{last\_item\_cache, false|true\}} \ind{options!last\_item\_cache} To specify whether or not pubsub should cache last items. Value is true or false. If not defined, pubsub do not cache last items. On systems with not so many nodes, caching last items speeds up pubsub and allows to raise user connection rate. The cost is memory usage, as every item is stored in memory. \titem{\{pep\_mapping, [ \{Key, Value\}, ...]\}} \ind{pep\_mapping} This allow to define a Key-Value list to choose defined node plugins on given PEP namespace. The following example will use node\_tune instead of node\_pep for every PEP node with tune namespace: \begin{verbatim} {mod_pubsub, [{pep_mapping, [{"http://jabber.org/protocol/tune", "tune"}]}]} \end{verbatim} %\titem{served\_hosts} \ind{options!served\_hosts} % This option allows to create additional pubsub virtual hosts in a single module instance. \end{description} Example of configuration that uses flat nodes as default, and allows use of flat, nodetree and pep nodes: \begin{verbatim} {modules, [ ... {mod_pubsub, [ {access_createnode, pubsub_createnode}, {plugins, ["flat", "hometree", "pep"]} ]}, ... ]}. \end{verbatim} Using ODBC database requires use of dedicated plugins. The following example shows previous configuration with ODBC usage: \begin{verbatim} {modules, [ ... {mod_pubsub_odbc, [ {access_createnode, pubsub_createnode}, {plugins, ["flat_odbc", "hometree_odbc", "pep_odbc"]} ]}, ... ]}. \end{verbatim} \makesubsection{modregister}{\modregister{}} \ind{modules!\modregister{}}\ind{protocols!XEP-0077: In-Band Registration}\ind{public registration} This module adds support for In-Band Registration (\xepref{0077}). This protocol enables end users to use a \XMPP{} client to: \begin{itemize} \item Register a new account on the server. \item Change the password from an existing account on the server. \item Delete an existing account on the server. \end{itemize} Options: \begin{description} \titem{\{access, AccessName\}} \ind{options!access} Specify rules to restrict what usernames can be registered and unregistered. If a rule returns `deny' on the requested username, registration and unregistration of that user name is denied. There are no restrictions by default. \titem{\{access\_from, AccessName\}} \ind{options!access\_from}By default, \ejabberd{} doesn't allow to register new accounts from s2s or existing c2s sessions. You can change it by defining access rule in this option. Use with care: allowing registration from s2s leads to uncontrolled massive accounts creation by rogue users. \titem{\{captcha\_protected, false|true\}} \ind{options!captcha\_protected} Protect registrations with CAPTCHA (see section \ref{captcha}). The default is \term{false}. \titem{\{ip\_access, [ \{allow|deny, IPaddress\}, ...]\}} \ind{options!ip\_access} Define rules to allow or deny account registration depending in the IP address of the XMPP client. If there is no matching IP mask, the default rule is ``allow''. IPv6 addresses are supported, but not tested. The default option value is an empty list: \term{[]}. \titem{\{password\_strength, Entropy\}} \ind{options!password\_strength} This option sets the minimum informational entropy for passwords. The value \term{Entropy} is a number of bits of entropy. The recommended minimum is 32 bits. The default is 0, i.e. no checks are performed. \titem{\{welcome\_message, \{Subject, Body\}\}} \ind{options!welcomem}Set a welcome message that is sent to each newly registered account. The first string is the subject, and the second string is the message body. In the body you can set a newline with the characters: \verb|\n| \titem{\{registration\_watchers, [ JID, ...]\}} \ind{options!rwatchers}This option defines a list of JIDs which will be notified each time a new account is registered. \iqdiscitem{In-Band Registration (\ns{jabber:iq:register})} \end{description} This module reads also another option defined globally for the server: \term{\{registration\_timeout, Timeout\}}. \ind{options!registratimeout} This option limits the frequency of registration from a given IP or username. So, a user that tries to register a new account from the same IP address or JID during this number of seconds after his previous registration will receive an error \term{resource-constraint} with the explanation: ``Users are not allowed to register accounts so quickly''. The timeout is expressed in seconds, and it must be an integer. To disable this limitation, instead of an integer put a word like: \term{infinity}. Default value: 600 seconds. Examples: \begin{itemize} \item Next example prohibits the registration of too short account names, and allows to create accounts only to clients of the local network: \begin{verbatim} {acl, shortname, {user_glob, "?"}}. {acl, shortname, {user_glob, "??"}}. %% The same using regexp: %%{acl, shortname, {user_regexp, "^..?$"}}. {access, register, [{deny, shortname}, {allow, all}]}. {modules, [ ... {mod_register, [{access, register}, {ip_access, [{allow, "127.0.0.0/8"}, {deny, "0.0.0.0/0"}]} ]}, ... ]}. \end{verbatim} \item This configuration prohibits usage of In-Band Registration to create or delete accounts, but allows existing accounts to change the password: \begin{verbatim} {access, register, [{deny, all}]}. {modules, [ ... {mod_register, [{access, register}]}, ... ]}. \end{verbatim} \item This configuration disables all In-Band Registration functionality: create, delete accounts and change password: \begin{verbatim} {modules, [ ... %% {mod_register, [{access, register}]}, ... ]}. \end{verbatim} \item Define the welcome message and two registration watchers. Also define a registration timeout of one hour: \begin{verbatim} {registration_timeout, 3600}. {modules, [ ... {mod_register, [ {welcome_message, {"Welcome!", "Hi.\nWelcome to this Jabber server.\n Check http://www.jabber.org\n\nBye"}}, {registration_watchers, ["admin1@example.org", "boss@example.net"]} ]}, ... ]}. \end{verbatim} \end{itemize} \makesubsection{modregisterweb}{\modregisterweb{}} \ind{modules!\modregisterweb{}} This module provides a web page where people can: \begin{itemize} \item Register a new account on the server. \item Change the password from an existing account on the server. \item Delete an existing account on the server. \end{itemize} This module supports CAPTCHA image to register a new account. To enable this feature, configure the options captcha\_cmd and captcha\_host. Options: \begin{description} \titem{\{registration\_watchers, [ JID, ...]\}} \ind{options!rwatchers}This option defines a list of JIDs which will be notified each time a new account is registered. \end{description} This example configuration shows how to enable the module and the web handler: \begin{verbatim} {hosts, ["localhost", "example.org", "example.com"]}. {listen, [ ... {5281, ejabberd_http, [ tls, {certfile, "/etc/ejabberd/certificate.pem"}, register ]}, ... ]}. {modules, [ ... {mod_register_web, []}, ... ]}. \end{verbatim} For example, the users of the host \term{example.org} can visit the page: \ns{https://example.org:5281/register/} It is important to include the last / character in the URL, otherwise the subpages URL will be incorrect. \makesubsection{modroster}{\modroster{}} \ind{modules!\modroster{}}\ind{roster management}\ind{protocols!RFC 3921: XMPP IM} This module implements roster management as defined in \footahref{http://xmpp.org/rfcs/rfc3921.html\#roster}{RFC 3921: XMPP IM}. It also supports Roster Versioning (\xepref{0237}). Options: \begin{description} \iqdiscitem{Roster Management (\ns{jabber:iq:roster})} \titem{\{versioning, false|true\}} \ind{options!versioning}Enables Roster Versioning. This option is disabled by default. \titem{\{store\_current\_id, false|true\}} \ind{options!storecurrentid} If this option is enabled, the current version number is stored on the database. If disabled, the version number is calculated on the fly each time. Enabling this option reduces the load for both ejabberd and the database. This option does not affect the client in any way. This option is only useful if Roster Versioning is enabled. This option is disabled by default. Important: if you use \modsharedroster{}, \modsharedrosterodbc{} or \modsharedrosterldap{}, you must disable this option. \end{description} This example configuration enables Roster Versioning with storage of current id: \begin{verbatim} {modules, [ ... {mod_roster, [{versioning, true}, {store_current_id, true}]}, ... ]}. \end{verbatim} \makesubsection{modservicelog}{\modservicelog{}} \ind{modules!\modservicelog{}}\ind{message auditing}\ind{Bandersnatch} This module adds support for logging end user packets via a \XMPP{} message auditing service such as \footahref{http://www.funkypenguin.info/project/bandersnatch/}{Bandersnatch}. All user packets are encapsulated in a \verb|| element and sent to the specified service(s). Options: \begin{description} \titem{\{loggers, [Names, ...]\}} \ind{options!loggers}With this option a (list of) service(s) that will receive the packets can be specified. \end{description} Examples: \begin{itemize} \item To log all end user packets to the Bandersnatch service running on \jid{bandersnatch.example.com}: \begin{verbatim} {modules, [ ... {mod_service_log, [{loggers, ["bandersnatch.example.com"]}]}, ... ]}. \end{verbatim} \item To log all end user packets to the Bandersnatch service running on \jid{bandersnatch.example.com} and the backup service on \jid{bandersnatch.example.org}: \begin{verbatim} {modules, [ ... {mod_service_log, [{loggers, ["bandersnatch.example.com", "bandersnatch.example.org"]}]}, ... ]}. \end{verbatim} \end{itemize} \makesubsection{modsharedroster}{\modsharedroster{}} \ind{modules!\modsharedroster{}}\ind{shared roster groups} This module enables you to create shared roster groups. This means that you can create groups of people that can see members from (other) groups in their rosters. The big advantages of this feature are that end users do not need to manually add all users to their rosters, and that they cannot permanently delete users from the shared roster groups. A shared roster group can have members from any XMPP server, but the presence will only be available from and to members of the same virtual host where the group is created. Shared roster groups can be edited \emph{only} via the Web Admin. Each group has a unique identification and the following parameters: \begin{description} \item[Name] The name of the group, which will be displayed in the roster. \item[Description] The description of the group. This parameter does not affect anything. \item[Members] A list of JIDs of group members, entered one per line in the Web Admin. The special member directive \term{@all@} represents all the registered users in the virtual host; which is only recommended for a small server with just a few hundred users. The special member directive \term{@online@} represents the online users in the virtual host. \item[Displayed groups] A list of groups that will be in the rosters of this group's members. A group of other vhost can be identified with \term{groupid@vhost} \end{description} Examples: \begin{itemize} \item Take the case of a computer club that wants all its members seeing each other in their rosters. To achieve this, they need to create a shared roster group similar to next table: \begin{table}[H] \centering \begin{tabular}{|l|l|} \hline Identification& Group `\texttt{club\_members}'\\ \hline Name& Club Members\\ \hline Description& Members from the computer club\\ \hline Members& {\begin{tabular}{l} \jid{member1@example.org}\\ \jid{member2@example.org}\\ \jid{member3@example.org} \end{tabular} }\\ \hline Displayed groups& \texttt{club\_members}\\ \hline \end{tabular} \end{table} \item In another case we have a company which has three divisions: Management, Marketing and Sales. All group members should see all other members in their rosters. Additionally, all managers should have all marketing and sales people in their roster. Simultaneously, all marketeers and the whole sales team should see all managers. This scenario can be achieved by creating shared roster groups as shown in the following table: \begin{table}[H] \centering \begin{tabular}{|l|l|l|l|} \hline Identification& Group `\texttt{management}'& Group `\texttt{marketing}'& Group `\texttt{sales}'\\ \hline Name& Management& Marketing& Sales\\ \hline Description& \\ Members& {\begin{tabular}{l} \jid{manager1@example.org}\\ \jid{manager2@example.org}\\ \jid{manager3@example.org}\\ \jid{manager4@example.org} \end{tabular} }& {\begin{tabular}{l} \jid{marketeer1@example.org}\\ \jid{marketeer2@example.org}\\ \jid{marketeer3@example.org}\\ \jid{marketeer4@example.org} \end{tabular} }& {\begin{tabular}{l} \jid{saleswoman1@example.org}\\ \jid{salesman1@example.org}\\ \jid{saleswoman2@example.org}\\ \jid{salesman2@example.org} \end{tabular} }\\ \hline Displayed groups& {\begin{tabular}{l} \texttt{management}\\ \texttt{marketing}\\ \texttt{sales} \end{tabular} }& {\begin{tabular}{l} \texttt{management}\\ \texttt{marketing} \end{tabular} }& {\begin{tabular}{l} \texttt{management}\\ \texttt{sales} \end{tabular} }\\ \hline \end{tabular} \end{table} \end{itemize} \makesubsection{modsharedrosterldap}{\modsharedrosterldap{}} \ind{modules!\modsharedrosterldap{}}\ind{shared roster groups ldap} This module lets the server administrator automatically populate users' rosters (contact lists) with entries based on users and groups defined in an LDAP-based directory. \makesubsubsection{msrlconfigparams}{Configuration parameters} The module accepts the following configuration parameters. Some of them, if unspecified, default to the values specified for the top level of configuration. This lets you avoid specifying, for example, the bind password, in multiple places. \makeparagraph{msrlfilters}{Filters} These parameters specify LDAP filters used to query for shared roster information. All of them are run against the \verb|ldap_base|. \begin{description} \titem{{\tt ldap\_rfilter}} So called ``Roster Filter''. Used to find names of all ``shared roster'' groups. See also the \verb|ldap_groupattr| parameter. If unspecified, defaults to the top-level parameter of the same name. You {\em must} specify it in some place in the configuration, there is no default. \titem{{\tt ldap\_ufilter}} ``User Filter'' -- used for retrieving the human-readable name of roster entries (usually full names of people in the roster). See also the parameters \verb|ldap_userdesc| and \verb|ldap_useruid|. If unspecified, defaults to the top-level parameter of the same name. If that one also is unspecified, then the filter is assembled from values of other parameters as follows (\verb|[ldap_SOMETHING]| is used to mean ``the value of the configuration parameter {\tt ldap\_SOMETHING}''): \begin{verbatim} (&(&([ldap_memberattr]=[ldap_memberattr_format])([ldap_groupattr]=%g))[ldap_filter]) \end{verbatim} Subsequently {\tt \%u} and {\tt \%g} are replaced with a {\tt *}. This means that given the defaults, the filter sent to the LDAP server is would be \verb|(&(memberUid=*)(cn=*))|. If however the {\tt ldap\_memberattr\_format} is something like \verb|uid=%u,ou=People,o=org|, then the filter will be \verb|(&(memberUid=uid=*,ou=People,o=org)(cn=*))|. \titem{{\tt ldap\_gfilter}} ``Group Filter'' -- used when retrieving human-readable name (a.k.a. ``Display Name'') and the members of a group. See also the parameters \verb|ldap_groupattr|, \verb|ldap_groupdesc| and \verb|ldap_memberattr|. If unspecified, defaults to the top-level parameter of the same name. If that one also is unspecified, then the filter is constructed exactly in the same way as {\tt User Filter}. \titem{{\tt ldap\_filter}} Additional filter which is AND-ed together with {\tt User Filter} and {\tt Group Filter}. If unspecified, defaults to the top-level parameter of the same name. If that one is also unspecified, then no additional filter is merged with the other filters. \end{description} Note that you will probably need to manually define the {\tt User} and {\tt Group Filter}s (since the auto-assembled ones will not work) if: \begin{itemize} \item your {\tt ldap\_memberattr\_format} is anything other than a simple {\tt \%u}, \item {\bf and} the attribute specified with {\tt ldap\_memberattr} does not support substring matches. \end{itemize} An example where it is the case is OpenLDAP and {\tt (unique)MemberName} attribute from the {\tt groupOf(Unique)Names} objectClass. A symptom of this problem is that you will see messages such as the following in your {\tt slapd.log}: \begin{verbatim} get_filter: unknown filter type=130 filter="(&(?=undefined)(?=undefined)(something=else))" \end{verbatim} \makesubsubsection{msrlattrs}{Attributes} These parameters specify the names of the attributes which hold interesting data in the entries returned by running filters specified in section~\ref{msrlfilters}. \begin{description} \titem{{\tt ldap\_groupattr}} The name of the attribute that holds the group name, and that is used to differentiate between them. Retrieved from results of the ``Roster Filter'' and ``Group Filter''. Defaults to {\tt cn}. \titem{{\tt ldap\_groupdesc}} The name of the attribute which holds the human-readable group name in the objects you use to represent groups. Retrieved from results of the ``Group Filter''. Defaults to whatever {\tt ldap\_groupattr} is set. \titem{{\tt ldap\_memberattr}} The name of the attribute which holds the IDs of the members of a group. Retrieved from results of the ``Group Filter''. Defaults to {\tt memberUid}. The name of the attribute differs depending on the {\tt objectClass} you use for your group objects, for example: \begin{description} \item{{\tt posixGroup}} $\rightarrow{}$ {\tt memberUid} \item{{\tt groupOfNames}} $\rightarrow{}$ {\tt member} \item{{\tt groupOfUniqueNames}} $\rightarrow{}$ {\tt uniqueMember} \end{description} \titem{{\tt ldap\_userdesc}} The name of the attribute which holds the human-readable user name. Retrieved from results of the ``User Filter''. Defaults to {\tt cn}. \titem{{\tt ldap\_useruid}} The name of the attribute which holds the ID of a roster item. Value of this attribute in the roster item objects needs to match the ID retrieved from the {\tt ldap\_memberattr} attribute of a group object. Retrieved from results of the ``User Filter''. Defaults to {\tt cn}. \end{description} \makesubsubsection{msrlcontrolparams}{Control parameters} These paramters control the behaviour of the module. \begin{description} \titem{{\tt ldap\_memberattr\_format}} A globbing format for extracting user ID from the value of the attribute named by \verb|ldap_memberattr|. Defaults to {\tt \%u}, which means that the whole value is the member ID. If you change it to something different, you may also need to specify the User and Group Filters manually --- see section~\ref{msrlfilters}. \titem{{\tt ldap\_memberattr\_format\_re}} A regex for extracting user ID from the value of the attribute named by \verb|ldap_memberattr|. An example value {\tt "CN=($\backslash{}\backslash{}$w*),(OU=.*,)*DC=company,DC=com"} works for user IDs such as the following: \begin{itemize} \item \texttt{CN=Romeo,OU=Montague,DC=company,DC=com} \item \texttt{CN=Abram,OU=Servants,OU=Montague,DC=company,DC=com} \item \texttt{CN=Juliet,OU=Capulet,DC=company,DC=com} \item \texttt{CN=Peter,OU=Servants,OU=Capulet,DC=company,DC=com} \end{itemize} In case: \begin{itemize} \item the option is unset, \item or the {\tt re} module in unavailable in the current Erlang environment, \item or the regular expression does not compile, \end{itemize} then instead of a regular expression, a simple format specified by {\tt ldap\_memberattr\_format} is used. Also, in the last two cases an error message is logged during the module initialization. Also, note that in all cases {\tt ldap\_memberattr\_format} (and {\em not} the regex version) is used for constructing the default ``User/Group Filter'' --- see section~\ref{msrlfilters}. \titem{{\tt ldap\_auth\_check}} Whether the module should check (via the ejabberd authentication subsystem) for existence of each user in the shared LDAP roster. See section~\ref{msrlconfigroster} form more information. Set to {\tt off} if you want to disable the check. Defaults to {\tt on}. \titem{{\tt ldap\_user\_cache\_validity}} Number of seconds for which the cache for roster item full names is considered fresh after retrieval. 300 by default. See section~\ref{msrlconfigroster} on how it is used during roster retrieval. \titem{{\tt ldap\_group\_cache\_validity}} Number of seconds for which the cache for group membership is considered fresh after retrieval. 300 by default. See section~\ref{msrlconfigroster} on how it is used during roster retrieval. \end{description} \makesubsubsection{msrlconnparams}{Connection parameters} The module also accepts the connection parameters, all of which default to the top-level parameter of the same name, if unspecified. See~\ref{ldapconnection} for more information about them. \makesubsubsection{msrlconfigroster}{Retrieving the roster} When the module is called to retrieve the shared roster for a user, the following algorithm is used: \begin{enumerate} \item \label{step:rfilter} A list of names of groups to display is created: the {\tt Roster Filter} is run against the base DN, retrieving the values of the attribute named by {\tt ldap\_groupattr}. \item Unless the group cache is fresh (see the {\tt ldap\_group\_cache\_validity} option), it is refreshed: \begin{enumerate} \item Information for all groups is retrieved using a single query: the {\tt Group Filter} is run against the Base DN, retrieving the values of attributes named by {\tt ldap\_groupattr} (group ID), {\tt ldap\_groupdesc} (group ``Display Name'') and {\tt ldap\_memberattr} (IDs of group members). \item group ``Display Name'', read from the attribute named by {\tt ldap\_groupdesc}, is stored in the cache for the given group \item the following processing takes place for each retrieved value of attribute named by {\tt ldap\_memberattr}: \begin{enumerate} \item the user ID part of it is extracted using {\tt ldap\_memberattr\_format(\_re)}, \item then (unless {\tt ldap\_auth\_check} is set to {\tt off}) for each found user ID, the module checks (using the \ejabberd{} authentication subsystem) whether such user exists in the given virtual host. It is skipped if the check is enabled and fails. This step is here for historical reasons. If you have a tidy DIT and properly defined ``Roster Filter'' and ``Group Filter'', it is safe to disable it by setting {\tt ldap\_auth\_check} to {\tt off} --- it will speed up the roster retrieval. \item the user ID is stored in the list of members in the cache for the given group \end{enumerate} \end{enumerate} \item For each item (group name) in the list of groups retrieved in step~\ref{step:rfilter}: \begin{enumerate} \item the display name of a shared roster group is retrieved from the group cache \item for each IDs of users which belong to the group, retrieved from the group cache: \begin{enumerate} \item the ID is skipped if it's the same as the one for which we are retrieving the roster. This is so that the user does not have himself in the roster. \item the display name of a shared roster user is retrieved: \begin{enumerate} \item first, unless the user name cache is fresh (see the {\tt ldap\_user\_cache\_validity} option), it is refreshed by running the {\tt User Filter}, against the Base DN, retrieving the values of attributes named by {\tt ldap\_useruid} and {\tt ldap\_userdesc}. \item then, the display name for the given user ID is retrieved from the user name cache. \end{enumerate} \end{enumerate} \end{enumerate} \end{enumerate} \makesubsubsection{msrlconfigexample}{Configuration examples} Since there are many possible \footahref{http://en.wikipedia.org/wiki/Directory\_Information\_Tree}{DIT} layouts, it will probably be easiest to understand how to configure the module by looking at an example for a given DIT (or one resembling it). \makeparagraph{msrlconfigexampleflat}{Flat DIT} This seems to be the kind of DIT for which this module was initially designed. Basically there are just user objects, and group membership is stored in an attribute individually for each user. For example in a layout shown in figure~\ref{fig:msrl-dit-flat}, the group of each user is stored in its {\tt ou} attribute. \begin{figure}[htbp] \centering \insscaleimg{0.4}{msrl-dit-flat.png} \caption{Flat DIT graph} \label{fig:msrl-dit-flat} \end{figure} Such layout has a few downsides, including: \begin{itemize} \item information duplication -- the group name is repeated in every member object \item difficult group management -- information about group members is not centralized, but distributed between member objects \item inefficiency -- the list of unique group names has to be computed by iterating over all users \end{itemize} This however seems to be a common DIT layout, so the module keeps supporting it. You can use the following configuration\ldots \begin{verbatim} {mod_shared_roster_ldap,[ {ldap_base, "ou=flat,dc=nodomain"}, {ldap_rfilter, "(objectClass=inetOrgPerson)"}, {ldap_groupattr, "ou"}, {ldap_memberattr, "cn"}, {ldap_filter, "(objectClass=inetOrgPerson)"}, {ldap_userdesc, "displayName"} ]}, \end{verbatim} \ldots to be provided with a roster as shown in figure~\ref{fig:msrl-roster-flat} upon connecting as user {\tt czesio}. \begin{figure}[htbp] \centering \insscaleimg{1}{msrl-roster-flat.png} \caption{Roster from flat DIT} \label{fig:msrl-roster-flat} \end{figure} \makeparagraph{msrlconfigexampledeep}{Deep DIT} This type of DIT contains distinctly typed objects for users and groups -- see figure~\ref{fig:msrl-dit-deep}. They are shown separated into different subtrees, but it's not a requirement. \begin{figure}[htbp] \centering \insscaleimg{0.35}{msrl-dit-deep.png} \caption{Example ``deep'' DIT graph} \label{fig:msrl-dit-deep} \end{figure} If you use the following example module configuration with it: \begin{verbatim} {mod_shared_roster_ldap,[ {ldap_base, "ou=deep,dc=nodomain"}, {ldap_rfilter, "(objectClass=groupOfUniqueNames)"}, {ldap_filter, ""}, {ldap_gfilter, "(&(objectClass=groupOfUniqueNames)(cn=%g))"}, {ldap_groupdesc, "description"}, {ldap_memberattr, "uniqueMember"}, {ldap_memberattr_format, "cn=%u,ou=people,ou=deep,dc=nodomain"}, {ldap_ufilter, "(&(objectClass=inetOrgPerson)(cn=%u))"}, {ldap_userdesc, "displayName"} ]}, \end{verbatim} \ldots and connect as user {\tt czesio}, then \ejabberd{} will provide you with the roster shown in figure~\ref{fig:msrl-roster-deep}. \begin{figure}[htbp] \centering \insscaleimg{1}{msrl-roster-deep.png} \caption{Example roster from ``deep'' DIT} \label{fig:msrl-roster-deep} \end{figure} \makesubsection{modsic}{\modsic{}} \ind{modules!\modstats{}}\ind{protocols!XEP-0279: Server IP Check} This module adds support for Server IP Check (\xepref{0279}). This protocol enables a client to discover its external IP address. Options: \begin{description} \iqdiscitem{\ns{urn:xmpp:sic:0}} \end{description} \makesubsection{modstats}{\modstats{}} \ind{modules!\modstats{}}\ind{protocols!XEP-0039: Statistics Gathering}\ind{statistics} This module adds support for Statistics Gathering (\xepref{0039}). This protocol allows you to retrieve next statistics from your \ejabberd{} deployment: \begin{itemize} \item Total number of registered users on the current virtual host (users/total). \item Total number of registered users on all virtual hosts (users/all-hosts/total). \item Total number of online users on the current virtual host (users/online). \item Total number of online users on all virtual hosts (users/all-hosts/online). \end{itemize} Options: \begin{description} \iqdiscitem{Statistics Gathering (\ns{http://jabber.org/protocol/stats})} \end{description} As there are only a small amount of clients (for \ind{Tkabber}example \footahref{http://tkabber.jabber.ru/}{Tkabber}) and software libraries with support for this XEP, a few examples are given of the XML you need to send in order to get the statistics. Here they are: \begin{itemize} \item You can request the number of online users on the current virtual host (\jid{example.org}) by sending: \begin{verbatim} \end{verbatim} \item You can request the total number of registered users on all virtual hosts by sending: \begin{verbatim} \end{verbatim} \end{itemize} \makesubsection{modtime}{\modtime{}} \ind{modules!\modtime{}}\ind{protocols!XEP-0202: Entity Time} This module features support for Entity Time (\xepref{0202}). By using this XEP, you are able to discover the time at another entity's location. Options: \begin{description} \iqdiscitem{Entity Time (\ns{jabber:iq:time})} \end{description} \makesubsection{modvcard}{\modvcard{}} \ind{modules!\modvcard{}}\ind{JUD}\ind{Jabber User Directory}\ind{vCard}\ind{protocols!XEP-0054: vcard-temp} This module allows end users to store and retrieve their vCard, and to retrieve other users vCards, as defined in vcard-temp (\xepref{0054}). The module also implements an uncomplicated \Jabber{} User Directory based on the vCards of these users. Moreover, it enables the server to send its vCard when queried. Options: \begin{description} \hostitem{vjud} \iqdiscitem{\ns{vcard-temp}} \titem{\{search, true|false\}}\ind{options!search}This option specifies whether the search functionality is enabled or not If disabled, the option \term{host} will be ignored and the \Jabber{} User Directory service will not appear in the Service Discovery item list. The default value is \term{true}. \titem{\{matches, infinity|Number\}}\ind{options!matches}With this option, the number of reported search results can be limited. If the option's value is set to \term{infinity}, all search results are reported. The default value is \term{30}. \titem{\{allow\_return\_all, false|true\}}\ind{options!allow\_return\_all}This option enables you to specify if search operations with empty input fields should return all users who added some information to their vCard. The default value is \term{false}. \titem{\{search\_all\_hosts, true|false\}}\ind{options!search\_all\_hosts}If this option is set to \term{true}, search operations will apply to all virtual hosts. Otherwise only the current host will be searched. The default value is \term{true}. This option is available in \modvcard, but not available in \modvcardodbc. \end{description} Examples: \begin{itemize} \item In this first situation, search results are limited to twenty items, every user who added information to their vCard will be listed when people do an empty search, and only users from the current host will be returned: \begin{verbatim} {modules, [ ... {mod_vcard, [{search, true}, {matches, 20}, {allow_return_all, true}, {search_all_hosts, false}]}, ... ]}. \end{verbatim} \item The second situation differs in a way that search results are not limited, and that all virtual hosts will be searched instead of only the current one: \begin{verbatim} {modules, [ ... {mod_vcard, [{search, true}, {matches, infinity}, {allow_return_all, true}]}, ... ]}. \end{verbatim} \end{itemize} \makesubsection{modvcardldap}{\modvcardldap{}} \ind{modules!\modvcardldap{}}\ind{JUD}\ind{Jabber User Directory}\ind{vCard}\ind{protocols!XEP-0054: vcard-temp} %TODO: verify if the referrers to the LDAP section are still correct \ejabberd{} can map LDAP attributes to vCard fields. This behaviour is implemented in the \modvcardldap{} module. This module does not depend on the authentication method (see~\ref{ldapauth}). Usually \ejabberd{} treats LDAP as a read-only storage: it is possible to consult data, but not possible to create accounts or edit vCard that is stored in LDAP. However, it is possible to change passwords if \module{mod\_register} module is enabled and LDAP server supports \footahref{http://tools.ietf.org/html/rfc3062}{RFC 3062}. The \modvcardldap{} module has its own optional parameters. The first group of parameters has the same meaning as the top-level LDAP parameters to set the authentication method: \option{ldap\_servers}, \option{ldap\_port}, \option{ldap\_rootdn}, \option{ldap\_password}, \option{ldap\_base}, \option{ldap\_uids}, \option{ldap\_deref\_aliases} and \option{ldap\_filter}. See section~\ref{ldapauth} for detailed information about these options. If one of these options is not set, \ejabberd{} will look for the top-level option with the same name. The second group of parameters consists of the following \modvcardldap{}-specific options: \begin{description} \hostitem{vjud} \iqdiscitem{\ns{vcard-temp}} \titem{\{search, true|false\}}\ind{options!search}This option specifies whether the search functionality is enabled (value: \term{true}) or disabled (value: \term{false}). If disabled, the option \term{host} will be ignored and the \Jabber{} User Directory service will not appear in the Service Discovery item list. The default value is \term{true}. \titem{\{matches, infinity|Number\}}\ind{options!matches}With this option, the number of reported search results can be limited. If the option's value is set to \term{infinity}, all search results are reported. The default value is \term{30}. \titem{\{ldap\_vcard\_map, [ \{Name, Pattern, LDAPattributes\}, ...]\}} \ind{options!ldap\_vcard\_map} With this option you can set the table that maps LDAP attributes to vCard fields. \ind{protocols!RFC 2426: vCard MIME Directory Profile} \term{Name} is the type name of the vCard as defined in \footahref{http://tools.ietf.org/html/rfc2426}{RFC 2426}. \term{Pattern} is a string which contains pattern variables \term{"\%u"}, \term{"\%d"} or \term{"\%s"}. \term{LDAPattributes} is the list containing LDAP attributes. The pattern variables \term{"\%s"} will be sequentially replaced with the values of LDAP attributes from \term{List\_of\_LDAP\_attributes}, \term{"\%u"} will be replaced with the user part of a JID, and \term{"\%d"} will be replaced with the domain part of a JID. The default is: \begin{verbatim} [{"NICKNAME", "%u", []}, {"FN", "%s", ["displayName"]}, {"LAST", "%s", ["sn"]}, {"FIRST", "%s", ["givenName"]}, {"MIDDLE", "%s", ["initials"]}, {"ORGNAME", "%s", ["o"]}, {"ORGUNIT", "%s", ["ou"]}, {"CTRY", "%s", ["c"]}, {"LOCALITY", "%s", ["l"]}, {"STREET", "%s", ["street"]}, {"REGION", "%s", ["st"]}, {"PCODE", "%s", ["postalCode"]}, {"TITLE", "%s", ["title"]}, {"URL", "%s", ["labeleduri"]}, {"DESC", "%s", ["description"]}, {"TEL", "%s", ["telephoneNumber"]}, {"EMAIL", "%s", ["mail"]}, {"BDAY", "%s", ["birthDay"]}, {"ROLE", "%s", ["employeeType"]}, {"PHOTO", "%s", ["jpegPhoto"]}] \end{verbatim} \titem{\{ldap\_search\_fields, [ \{Name, Attribute\}, ...]\}}\ind{options!ldap\_search\_fields}This option defines the search form and the LDAP attributes to search within. \term{Name} is the name of a search form field which will be automatically translated by using the translation files (see \term{msgs/*.msg} for available words). \term{Attribute} is the LDAP attribute or the pattern \term{"\%u"}. The default is: \begin{verbatim} [{"User", "%u"}, {"Full Name", "displayName"}, {"Given Name", "givenName"}, {"Middle Name", "initials"}, {"Family Name", "sn"}, {"Nickname", "%u"}, {"Birthday", "birthDay"}, {"Country", "c"}, {"City", "l"}, {"Email", "mail"}, {"Organization Name", "o"}, {"Organization Unit", "ou"}] \end{verbatim} \titem{\{ldap\_search\_reported, [ \{SearchField, VcardField\}, ...]\}}\ind{options!ldap\_search\_reported}This option defines which search fields should be reported. \term{SearchField} is the name of a search form field which will be automatically translated by using the translation files (see \term{msgs/*.msg} for available words). \term{VcardField} is the vCard field name defined in the \option{ldap\_vcard\_map} option. The default is: \begin{verbatim} [{"Full Name", "FN"}, {"Given Name", "FIRST"}, {"Middle Name", "MIDDLE"}, {"Family Name", "LAST"}, {"Nickname", "NICKNAME"}, {"Birthday", "BDAY"}, {"Country", "CTRY"}, {"City", "LOCALITY"}, {"Email", "EMAIL"}, {"Organization Name", "ORGNAME"}, {"Organization Unit", "ORGUNIT"}] \end{verbatim} \end{description} %TODO: this examples still should be organised better Examples: \begin{itemize} \item Let's say \term{ldap.example.org} is the name of our LDAP server. We have users with their passwords in \term{"ou=Users,dc=example,dc=org"} directory. Also we have addressbook, which contains users emails and their additional infos in \term{"ou=AddressBook,dc=example,dc=org"} directory. Corresponding authentication section should looks like this: \begin{verbatim} %% authentication method {auth_method, ldap}. %% DNS name of our LDAP server {ldap_servers, ["ldap.example.org"]}. %% We want to authorize users from 'shadowAccount' object class only {ldap_filter, "(objectClass=shadowAccount)"}. \end{verbatim} Now we want to use users LDAP-info as their vCards. We have four attributes defined in our LDAP schema: \term{"mail"} --- email address, \term{"givenName"} --- first name, \term{"sn"} --- second name, \term{"birthDay"} --- birthday. Also we want users to search each other. Let's see how we can set it up: \begin{verbatim} {modules, ... {mod_vcard_ldap, [ %% We use the same server and port, but want to bind anonymously because %% our LDAP server accepts anonymous requests to %% "ou=AddressBook,dc=example,dc=org" subtree. {ldap_rootdn, ""}, {ldap_password, ""}, %% define the addressbook's base {ldap_base, "ou=AddressBook,dc=example,dc=org"}, %% uidattr: user's part of JID is located in the "mail" attribute %% uidattr_format: common format for our emails {ldap_uids, [{"mail","%u@mail.example.org"}]}, %% We have to define empty filter here, because entries in addressbook does not %% belong to shadowAccount object class {ldap_filter, ""}, %% Now we want to define vCard pattern {ldap_vcard_map, [{"NICKNAME", "%u", []}, % just use user's part of JID as his nickname {"FIRST", "%s", ["givenName"]}, {"LAST", "%s", ["sn"]}, {"FN", "%s, %s", ["sn", "givenName"]}, % example: "Smith, John" {"EMAIL", "%s", ["mail"]}, {"BDAY", "%s", ["birthDay"]}]}, %% Search form {ldap_search_fields, [{"User", "%u"}, {"Name", "givenName"}, {"Family Name", "sn"}, {"Email", "mail"}, {"Birthday", "birthDay"}]}, %% vCard fields to be reported %% Note that JID is always returned with search results {ldap_search_reported, [{"Full Name", "FN"}, {"Nickname", "NICKNAME"}, {"Birthday", "BDAY"}]} ]} ... }. \end{verbatim} Note that \modvcardldap{} module checks an existence of the user before searching his info in LDAP. \item \term{ldap\_vcard\_map} example: \begin{verbatim} {ldap_vcard_map, [{"NICKNAME", "%u", []}, {"FN", "%s", ["displayName"]}, {"CTRY", "Russia", []}, {"EMAIL", "%u@%d", []}, {"DESC", "%s\n%s", ["title", "description"]} ]}, \end{verbatim} \item \term{ldap\_search\_fields} example: \begin{verbatim} {ldap_search_fields, [{"User", "uid"}, {"Full Name", "displayName"}, {"Email", "mail"} ]}, \end{verbatim} \item \term{ldap\_search\_reported} example: \begin{verbatim} {ldap_search_reported, [{"Full Name", "FN"}, {"Email", "EMAIL"}, {"Birthday", "BDAY"}, {"Nickname", "NICKNAME"} ]}, \end{verbatim} \end{itemize} \makesubsection{modvcardxupdate}{\modvcardxupdate{}} \ind{modules!\modvcardxupdate{}}\ind{protocols!XEP-0153: vCard-Based Avatars} The user's client can store an avatar in the user vCard. The vCard-Based Avatars protocol (\xepref{0153}) provides a method for clients to inform the contacts what is the avatar hash value. However, simple or small clients may not implement that protocol. If this module is enabled, all the outgoing client presence stanzas get automatically the avatar hash on behalf of the client. So, the contacts receive the presence stanzas with the Update Data described in \xepref{0153} as if the client would had inserted it itself. If the client had already included such element in the presence stanza, it is replaced with the element generated by ejabberd. By enabling this module, each vCard modification produces a hash recalculation, and each presence sent by a client produces hash retrieval and a presence stanza rewrite. For this reason, enabling this module will introduce a computational overhead in servers with clients that change frequently their presence. \makesubsection{modversion}{\modversion{}} \ind{modules!\modversion{}}\ind{protocols!XEP-0092: Software Version} This module implements Software Version (\xepref{0092}). Consequently, it answers \ejabberd{}'s version when queried. Options: \begin{description} \titem{\{show\_os, true|false\}}\ind{options!showos}Should the operating system be revealed or not. The default value is \term{true}. \iqdiscitem{Software Version (\ns{jabber:iq:version})} \end{description} \makechapter{manage}{Managing an \ejabberd{} Server} \makesection{ejabberdctl}{\term{ejabberdctl}} With the \term{ejabberdctl} command line administration script you can execute \term{ejabberdctl commands} (described in the next section, \ref{ectl-commands}) and also many general \term{ejabberd commands} (described in section \ref{eja-commands}). This means you can start, stop and perform many other administrative tasks in a local or remote \ejabberd{} server (by providing the argument \term{--node NODENAME}). The \term{ejabberdctl} script can be configured in the file \term{ejabberdctl.cfg}. This file includes detailed information about each configurable option. See section \ref{erlangconfiguration}. The \term{ejabberdctl} script returns a numerical status code. Success is represented by \term{0}, error is represented by \term{1}, and other codes may be used for specific results. This can be used by other scripts to determine automatically if a command succeeded or failed, for example using: \term{echo \$?} \makesubsection{ectl-commands}{ejabberdctl Commands} When \term{ejabberdctl} is executed without any parameter, it displays the available options. If there isn't an \ejabberd{} server running, the available parameters are: \begin{description} \titem{start} Start \ejabberd{} in background mode. This is the default method. \titem{debug} Attach an Erlang shell to an already existing \ejabberd{} server. This allows to execute commands interactively in the \ejabberd{} server. \titem{live} Start \ejabberd{} in live mode: the shell keeps attached to the started server, showing log messages and allowing to execute interactive commands. \end{description} If there is an \ejabberd{} server running in the system, \term{ejabberdctl} shows the \term{ejabberdctl commands} described bellow and all the \term{ejabberd commands} available in that server (see \ref{list-eja-commands}). The \term{ejabberdctl commands} are: \begin{description} \titem{help} Get help about ejabberdctl or any available command. Try \term{ejabberdctl help help}. \titem{status} Check the status of the \ejabberd{} server. \titem{stop} Stop the \ejabberd{} server. \titem{restart} Restart the \ejabberd{} server. \titem{mnesia} Get information about the Mnesia database. \end{description} The \term{ejabberdctl} script can be restricted to require authentication and execute some \term{ejabberd commands}; see \ref{accesscommands}. Add the option to the file \term{ejabberd.cfg}. In this example there is no restriction: \begin{verbatim} {ejabberdctl_access_commands, []}. \end{verbatim} If account \term{robot1@example.org} is registered in \ejabberd{} with password \term{abcdef} (which MD5 is E8B501798950FC58AAD83C8C14978E), and \term{ejabberd.cfg} contains this setting: \begin{verbatim} {hosts, ["example.org"]}. {acl, bots, {user, "robot1", "example.org"}}. {access, ctlaccess, [{allow, bots}]}. {ejabberdctl_access_commands, [ {ctlaccess, [registered_users, register], []} ]}. \end{verbatim} then you can do this in the shell: \begin{verbatim} $ ejabberdctl registered_users example.org Error: no_auth_provided $ ejabberdctl --auth robot1 example.org E8B501798950FC58AAD83C8C14978E registered_users example.org robot1 testuser1 testuser2 \end{verbatim} \makesubsection{erlangconfiguration}{Erlang Runtime System} \ejabberd{} is an Erlang/OTP application that runs inside an Erlang runtime system. This system is configured using environment variables and command line parameters. The \term{ejabberdctl} administration script uses many of those possibilities. You can configure some of them with the file \term{ejabberdctl.cfg}, which includes detailed description about them. This section describes for reference purposes all the environment variables and command line parameters. The environment variables: \begin{description} \titem{EJABBERD\_CONFIG\_PATH} Path to the ejabberd configuration file. \titem{EJABBERD\_MSGS\_PATH} Path to the directory with translated strings. \titem{EJABBERD\_LOG\_PATH} Path to the ejabberd service log file. \titem{EJABBERD\_SO\_PATH} Path to the directory with binary system libraries. \titem{EJABBERD\_DOC\_PATH} Path to the directory with ejabberd documentation. \titem{EJABBERD\_PID\_PATH} Path to the PID file that ejabberd can create when started. \titem{HOME} Path to the directory that is considered \ejabberd{}'s home. This path is used to read the file \term{.erlang.cookie}. \titem{ERL\_CRASH\_DUMP} Path to the file where crash reports will be dumped. \titem{ERL\_EPMD\_ADDRESS} IP address where epmd listens for connections (see section \ref{epmd}). \titem{ERL\_INETRC} Indicates which IP name resolution to use. If using \term{-sname}, specify either this option or \term{-kernel inetrc filepath}. \titem{ERL\_MAX\_PORTS} Maximum number of simultaneously open Erlang ports. \titem{ERL\_MAX\_ETS\_TABLES} Maximum number of ETS and Mnesia tables. \end{description} The command line parameters: \begin{description} \titem{-sname ejabberd} The Erlang node will be identified using only the first part of the host name, i.\,e. other Erlang nodes outside this domain cannot contact this node. This is the preferable option in most cases. \titem{-name ejabberd} The Erlang node will be fully identified. This is only useful if you plan to setup an \ejabberd{} cluster with nodes in different networks. \titem{-kernel inetrc '"/etc/ejabberd/inetrc"'} Indicates which IP name resolution to use. If using \term{-sname}, specify either this option or \term{ERL\_INETRC}. \titem{-kernel inet\_dist\_listen\_min 4200 inet\_dist\_listen\_min 4210} Define the first and last ports that \term{epmd} (section \ref{epmd}) can listen to. \titem{-kernel inet\_dist\_use\_interface "\{ 127,0,0,1 \}"} Define the IP address where this Erlang node listens for other nodes connections (see section \ref{epmd}). \titem{-detached} Starts the Erlang system detached from the system console. Useful for running daemons and background processes. \titem{-noinput} Ensures that the Erlang system never tries to read any input. Useful for running daemons and background processes. \titem{-pa /var/lib/ejabberd/ebin} Specify the directory where Erlang binary files (*.beam) are located. \titem{-s ejabberd} Tell Erlang runtime system to start the \ejabberd{} application. \titem{-mnesia dir '"/var/lib/ejabberd/"'} Specify the Mnesia database directory. \titem{-sasl sasl\_error\_logger \{file, "/var/log/ejabberd/erlang.log"\}} Path to the Erlang/OTP system log file. SASL here means ``System Architecture Support Libraries'' not ``Simple Authentication and Security Layer''. \titem{+K [true|false]} Kernel polling. \titem{-smp [auto|enable|disable]} SMP support. \titem{+P 250000} Maximum number of Erlang processes. \titem{-remsh ejabberd@localhost} Open an Erlang shell in a remote Erlang node. \titem{-hidden} The connections to other nodes are hidden (not published). The result is that this node is not considered part of the cluster. This is important when starting a temporary \term{ctl} or \term{debug} node. \end{description} Note that some characters need to be escaped when used in shell scripts, for instance \verb|"| and \verb|{}|. You can find other options in the Erlang manual page (\shell{erl -man erl}). \makesection{eja-commands}{\ejabberd{} Commands} An \term{ejabberd command} is an abstract function identified by a name, with a defined number and type of calling arguments and type of result that is registered in the \term{ejabberd\_commands} service. Those commands can be defined in any Erlang module and executed using any valid frontend. \ejabberd{} includes a frontend to execute \term{ejabberd commands}: the script \term{ejabberdctl}. Other known frontends that can be installed to execute ejabberd commands in different ways are: \term{ejabberd\_xmlrpc} (XML-RPC service), \term{mod\_rest} (HTTP POST service), \term{mod\_shcommands} (ejabberd WebAdmin page). \makesubsection{list-eja-commands}{List of ejabberd Commands} \ejabberd{} includes a few ejabberd Commands by default. When more modules are installed, new commands may be available in the frontends. The easiest way to get a list of the available commands, and get help for them is to use the ejabberdctl script: \begin{verbatim} $ ejabberdctl help Usage: ejabberdctl [--node nodename] [--auth user host password] command [options] Available commands in this ejabberd node: backup file Store the database to backup file connected_users List all established sessions connected_users_number Get the number of established sessions ... \end{verbatim} The most interesting ones are: \begin{description} \titem{reopen\_log} Reopen the log files after they were renamed. If the old files were not renamed before calling this command, they are automatically renamed to \term{"*-old.log"}. See section \ref{logfiles}. \titem {backup ejabberd.backup} Store internal Mnesia database to a binary backup file. \titem {restore ejabberd.backup} Restore immediately from a binary backup file the internal Mnesia database. This will consume a lot of memory if you have a large database, so better use \term{install\_fallback}. \titem {install\_fallback ejabberd.backup} The binary backup file is installed as fallback: it will be used to restore the database at the next ejabberd start. This means that, after running this command, you have to restart ejabberd. This command requires less memory than \term{restore}. \titem {dump ejabberd.dump} Dump internal Mnesia database to a text file dump. \titem {load ejabberd.dump} Restore immediately from a text file dump. This is not recommended for big databases, as it will consume much time, memory and processor. In that case it's preferable to use \term{backup} and \term{install\_fallback}. %%More information about backuping can %% be found in section~\ref{backup}. \titem{import\_piefxis, export\_piefxis, export\_piefxis\_host} \ind{migrate between servers} These options can be used to migrate accounts using \xepref{0227} formatted XML files from/to other Jabber/XMPP servers or move users of a vhost to another ejabberd installation. See also \footahref{https://support.process-one.net/doc/display/MESSENGER/ejabberd+migration+kit}{ejabberd migration kit}. \titem{import\_file, import\_dir} \ind{migration from other software} These options can be used to migrate accounts using jabberd1.4 formatted XML files. from other Jabber/XMPP servers There exist tutorials to \footahref{http://www.ejabberd.im/migrate-to-ejabberd}{migrate from other software to ejabberd}. \titem{delete\_expired\_messages} This option can be used to delete old messages in offline storage. This might be useful when the number of offline messages is very high. \titem{delete\_old\_messages days} Delete offline messages older than the given days. \titem{register user host password} Register an account in that domain with the given password. \titem{unregister user host} Unregister the given account. \end{description} \makesubsection{accesscommands}{Restrict Execution with AccessCommands} The frontends can be configured to restrict access to certain commands. In that case, authentication information must be provided. In each frontend the \term{AccessCommands} option is defined in a different place. But in all cases the option syntax is the same: \begin{verbatim} AccessCommands = [ {Access, CommandNames, Arguments}, ...] Access = atom() CommandNames = all | [CommandName] CommandName = atom() Arguments = [ {ArgumentName, ArgumentValue}, ...] ArgumentName = atom() ArgumentValue = any() \end{verbatim} The default value is to not define any restriction: \term{[]}. The authentication information is provided when executing a command, and is Username, Hostname and Password of a local XMPP account that has permission to execute the corresponding command. This means that the account must be registered in the local ejabberd, because the information will be verified. It is possible to provide the plaintext password or its MD5 sum. When one or several access restrictions are defined and the authentication information is provided, each restriction is verified until one matches completely: the account matches the Access rule, the command name is listed in CommandNames, and the provided arguments do not contradict Arguments. As an example to understand the syntax, let's suppose those options: \begin{verbatim} {hosts, ["example.org"]}. {acl, bots, {user, "robot1", "example.org"}}. {access, commaccess, [{allow, bots}]}. \end{verbatim} This list of access restrictions allows only \term{robot1@example.org} to execute all commands: \begin{verbatim} [{commaccess, all, []}] \end{verbatim} See another list of restrictions (the corresponding ACL and ACCESS are not shown): \begin{verbatim} [ %% This bot can execute all commands: {bot, all, []}, %% This bot can only execute the command 'dump'. No argument restriction: {bot_backups, [dump], []} %% This bot can execute all commands, %% but if a 'host' argument is provided, it must be "example.org": {bot_all_example, all, [{host, "example.org"}]}, %% This bot can only execute the command 'register', %% and if argument 'host' is provided, it must be "example.org": {bot_reg_example, [register], [{host, "example.org"}]}, %% This bot can execute the commands 'register' and 'unregister', %% if argument host is provided, it must be "test.org": {_bot_reg_test, [register, unregister], [{host, "test.org"}]} ] \end{verbatim} \makesection{webadmin}{Web Admin} \ind{web admin} The \ejabberd{} Web Admin allows to administer most of \ejabberd{} using a web browser. This feature is enabled by default: a \term{ejabberd\_http} listener with the option \term{web\_admin} (see section~\ref{listened}) is included in the listening ports. Then you can open \verb|http://server:port/admin/| in your favourite web browser. You will be asked to enter the username (the \emph{full} \Jabber{} ID) and password of an \ejabberd{} user with administrator rights. After authentication you will see a page similar to figure~\ref{fig:webadmmain}. \begin{figure}[htbp] \centering \insimg{webadmmain.png} \caption{Top page from the Web Admin} \label{fig:webadmmain} \end{figure} Here you can edit access restrictions, manage users, create backups, manage the database, enable/disable ports listened for, view server statistics,\ldots The access rule \term{configure} determines what accounts can access the Web Admin and modify it. The access rule \term{webadmin\_view} is to grant only view access: those accounts can browse the Web Admin with read-only access. Example configurations: \begin{itemize} \item You can serve the Web Admin on the same port as the \ind{protocols!XEP-0025: HTTP Polling}HTTP Polling interface. In this example you should point your web browser to \verb|http://example.org:5280/admin/| to administer all virtual hosts or to \verb|http://example.org:5280/admin/server/example.com/| to administer only the virtual host \jid{example.com}. Before you get access to the Web Admin you need to enter as username, the JID and password from a registered user that is allowed to configure \ejabberd{}. In this example you can enter as username `\jid{admin@example.net}' to administer all virtual hosts (first URL). If you log in with `\jid{admin@example.com}' on \\ \verb|http://example.org:5280/admin/server/example.com/| you can only administer the virtual host \jid{example.com}. The account `\jid{reviewer@example.com}' can browse that vhost in read-only mode. \begin{verbatim} {acl, admin, {user, "admin", "example.net"}}. {host_config, "example.com", [{acl, admin, {user, "admin", "example.com"}}]}. {host_config, "example.com", [{acl, viewers, {user, "reviewer", "example.com"}}]}. {access, configure, [{allow, admin}]}. {access, webadmin_view, [{allow, viewers}]}. {hosts, ["example.org"]}. {listen, [ ... {5280, ejabberd_http, [http_poll, web_admin]}, ... ]}. \end{verbatim} \item For security reasons, you can serve the Web Admin on a secured connection, on a port differing from the HTTP Polling interface, and bind it to the internal LAN IP. The Web Admin will be accessible by pointing your web browser to \verb|https://192.168.1.1:5282/admin/|: \begin{verbatim} {hosts, ["example.org"]}. {listen, [ ... {5280, ejabberd_http, [ http_poll ]}, {{5282, "192.168.1.1"}, ejabberd_http, [ web_admin, tls, {certfile, "/usr/local/etc/server.pem"} ]}, ... ]}. \end{verbatim} \end{itemize} Certain pages in the ejabberd Web Admin contain a link to a related section in the ejabberd Installation and Operation Guide. In order to view such links, a copy in HTML format of the Guide must be installed in the system. The file is searched by default in \term{"/share/doc/ejabberd/guide.html"}. The directory of the documentation can be specified in the environment variable \term{EJABBERD\_DOC\_PATH}. See section \ref{erlangconfiguration}. \makesection{adhoccommands}{Ad-hoc Commands} If you enable \modconfigure\ and \modadhoc, you can perform several administrative tasks in \ejabberd{} with an XMPP client. The client must support Ad-Hoc Commands (\xepref{0050}), and you must login in the XMPP server with an account with proper privileges. \makesection{changeerlangnodename}{Change Computer Hostname} \ejabberd{} uses the distributed Mnesia database. Being distributed, Mnesia enforces consistency of its file, so it stores the name of the Erlang node in it (see section \ref{nodename}). The name of an Erlang node includes the hostname of the computer. So, the name of the Erlang node changes if you change the name of the machine in which \ejabberd{} runs, or when you move \ejabberd{} to a different machine. You have two ways to use the old Mnesia database in an ejabberd with new node name: put the old node name in \term{ejabberdctl.cfg}, or convert the database to the new node name. Those example steps will backup, convert and load the Mnesia database. You need to have either the old Mnesia spool dir or a backup of Mnesia. If you already have a backup file of the old database, you can go directly to step 5. You also need to know the old node name and the new node name. If you don't know them, look for them by executing \term{ejabberdctl} or in the ejabberd log files. Before starting, setup some variables: \begin{verbatim} OLDNODE=ejabberd@oldmachine NEWNODE=ejabberd@newmachine OLDFILE=/tmp/old.backup NEWFILE=/tmp/new.backup \end{verbatim} \begin{enumerate} \item Start ejabberd enforcing the old node name: \begin{verbatim} ejabberdctl --node $OLDNODE start \end{verbatim} \item Generate a backup file: \begin{verbatim} ejabberdctl --node $OLDNODE backup $OLDFILE \end{verbatim} \item Stop the old node: \begin{verbatim} ejabberdctl --node $OLDNODE stop \end{verbatim} \item Make sure there aren't files in the Mnesia spool dir. For example: \begin{verbatim} mkdir /var/lib/ejabberd/oldfiles mv /var/lib/ejabberd/*.* /var/lib/ejabberd/oldfiles/ \end{verbatim} \item Start ejabberd. There isn't any need to specify the node name anymore: \begin{verbatim} ejabberdctl start \end{verbatim} \item Convert the backup to new node name: \begin{verbatim} ejabberdctl mnesia_change_nodename $OLDNODE $NEWNODE $OLDFILE $NEWFILE \end{verbatim} \item Install the backup file as a fallback: \begin{verbatim} ejabberdctl install_fallback $NEWFILE \end{verbatim} \item Stop ejabberd: \begin{verbatim} ejabberdctl stop \end{verbatim} You may see an error message in the log files, it's normal, so don't worry: \begin{verbatim} Mnesia(ejabberd@newmachine): ** ERROR ** (ignoring core) ** FATAL ** A fallback is installed and Mnesia must be restarted. Forcing shutdown after mnesia_down from ejabberd@newmachine... \end{verbatim} \item Now you can finally start ejabberd: \begin{verbatim} ejabberdctl start \end{verbatim} \item Check that the information of the old database is available: accounts, rosters... After you finish, remember to delete the temporary backup files from public directories. \end{enumerate} \makechapter{secure}{Securing \ejabberd{}} \makesection{firewall}{Firewall Settings} \ind{firewall}\ind{ports}\ind{SASL}\ind{TLS}\ind{clustering!ports} You need to take the following TCP ports in mind when configuring your firewall: \begin{table}[H] \centering \begin{tabular}{|l|l|} \hline {\bf Port} & {\bf Description} \\ \hline \hline 5222& Standard port for Jabber/XMPP client connections, plain or STARTTLS.\\ \hline 5223& Standard port for Jabber client connections using the old SSL method.\\ \hline 5269& Standard port for Jabber/XMPP server connections.\\ \hline 4369& EPMD (section \ref{epmd}) listens for Erlang node name requests.\\ \hline port range& Used for connections between Erlang nodes. This range is configurable (see section \ref{epmd}).\\ \hline \end{tabular} \end{table} \makesection{epmd}{epmd} \footahref{http://www.erlang.org/doc/man/epmd.html}{epmd (Erlang Port Mapper Daemon)} is a small name server included in Erlang/OTP and used by Erlang programs when establishing distributed Erlang communications. \ejabberd{} needs \term{epmd} to use \term{ejabberdctl} and also when clustering \ejabberd{} nodes. This small program is automatically started by Erlang, and is never stopped. If \ejabberd{} is stopped, and there aren't any other Erlang programs running in the system, you can safely stop \term{epmd} if you want. \ejabberd{} runs inside an Erlang node. To communicate with \ejabberd{}, the script \term{ejabberdctl} starts a new Erlang node and connects to the Erlang node that holds \ejabberd{}. In order for this communication to work, \term{epmd} must be running and listening for name requests in the port 4369. You should block the port 4369 in the firewall in such a way that only the programs in your machine can access it. or configure the option \term{ERL\_EPMD\_ADDRESS} in the file \term{ejabberdctl.cfg} (this option works only in Erlang/OTP R14B03 or higher). If you build a cluster of several \ejabberd{} instances, each \ejabberd{} instance is called an \ejabberd{} node. Those \ejabberd{} nodes use a special Erlang communication method to build the cluster, and EPMD is again needed listening in the port 4369. So, if you plan to build a cluster of \ejabberd{} nodes you must open the port 4369 for the machines involved in the cluster. Remember to block the port so Internet doesn't have access to it. Once an Erlang node solved the node name of another Erlang node using EPMD and port 4369, the nodes communicate directly. The ports used in this case by default are random, but can be configured in the file \term{ejabberdctl.cfg}. The Erlang command-line parameter used internally is, for example: \begin{verbatim} erl ... -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375 \end{verbatim} It is also possible to configure in \term{ejabberdctl.cfg} the network interface where the Erlang node will listen and accept connections. The Erlang command-line parameter used internally is, for example: \begin{verbatim} erl ... -kernel inet_dist_use_interface "{127,0,0,1}" \end{verbatim} \makesection{cookie}{Erlang Cookie} The Erlang cookie is a string with numbers and letters. An Erlang node reads the cookie at startup from the command-line parameter \term{-setcookie}. If not indicated, the cookie is read from the cookie file \term{\$HOME/.erlang.cookie}. If this file does not exist, it is created immediately with a random cookie. Two Erlang nodes communicate only if they have the same cookie. Setting a cookie on the Erlang node allows you to structure your Erlang network and define which nodes are allowed to connect to which. Thanks to Erlang cookies, you can prevent access to the Erlang node by mistake, for example when there are several Erlang nodes running different programs in the same machine. Setting a secret cookie is a simple method to difficult unauthorized access to your Erlang node. However, the cookie system is not ultimately effective to prevent unauthorized access or intrusion to an Erlang node. The communication between Erlang nodes are not encrypted, so the cookie could be read sniffing the traffic on the network. The recommended way to secure the Erlang node is to block the port 4369. \makesection{nodename}{Erlang Node Name} An Erlang node may have a node name. The name can be short (if indicated with the command-line parameter \term{-sname}) or long (if indicated with the parameter \term{-name}). Starting an Erlang node with -sname limits the communication between Erlang nodes to the LAN. Using the option \term{-sname} instead of \term{-name} is a simple method to difficult unauthorized access to your Erlang node. However, it is not ultimately effective to prevent access to the Erlang node, because it may be possible to fake the fact that you are on another network using a modified version of Erlang \term{epmd}. The recommended way to secure the Erlang node is to block the port 4369. \makesection{secure-files}{Securing Sensitive Files} \ejabberd{} stores sensitive data in the file system either in plain text or binary files. The file system permissions should be set to only allow the proper user to read, write and execute those files and directories. \begin{description} \titem{ejabberd configuration file: /etc/ejabberd/ejabberd.cfg} Contains the JID of administrators and passwords of external components. The backup files probably contain also this information, so it is preferable to secure the whole \term{/etc/ejabberd/} directory. \titem{ejabberd service log: /var/log/ejabberd/ejabberd.log} Contains IP addresses of clients. If the loglevel is set to 5, it contains whole conversations and passwords. If a logrotate system is used, there may be several log files with similar information, so it is preferable to secure the whole \term{/var/log/ejabberd/} directory. \titem{Mnesia database spool files in /var/lib/ejabberd/} The files store binary data, but some parts are still readable. The files are generated by Mnesia and their permissions cannot be set directly, so it is preferable to secure the whole \term{/var/lib/ejabberd/} directory. \titem{Erlang cookie file: /var/lib/ejabberd/.erlang.cookie} See section \ref{cookie}. \end{description} \makechapter{clustering}{Clustering} \ind{clustering} \makesection{howitworks}{How it Works} \ind{clustering!how it works} A \XMPP{} domain is served by one or more \ejabberd{} nodes. These nodes can be run on different machines that are connected via a network. They all must have the ability to connect to port 4369 of all another nodes, and must have the same magic cookie (see Erlang/OTP documentation, in other words the file \term{\~{}ejabberd/.erlang.cookie} must be the same on all nodes). This is needed because all nodes exchange information about connected users, s2s connections, registered services, etc\ldots Each \ejabberd{} node has the following modules: \begin{itemize} \item router, \item local router, \item session manager, \item s2s manager. \end{itemize} \makesubsection{router}{Router} \ind{clustering!router} This module is the main router of \XMPP{} packets on each node. It routes them based on their destination's domains. It uses a global routing table. The domain of the packet's destination is searched in the routing table, and if it is found, the packet is routed to the appropriate process. If not, it is sent to the s2s manager. \makesubsection{localrouter}{Local Router} \ind{clustering!local router} This module routes packets which have a destination domain equal to one of this server's host names. If the destination JID has a non-empty user part, it is routed to the session manager, otherwise it is processed depending on its content. \makesubsection{sessionmanager}{Session Manager} \ind{clustering!session manager} This module routes packets to local users. It looks up to which user resource a packet must be sent via a presence table. Then the packet is either routed to the appropriate c2s process, or stored in offline storage, or bounced back. \makesubsection{s2smanager}{s2s Manager} \ind{clustering!s2s manager} This module routes packets to other \XMPP{} servers. First, it checks if an opened s2s connection from the domain of the packet's source to the domain of the packet's destination exists. If that is the case, the s2s manager routes the packet to the process serving this connection, otherwise a new connection is opened. \makesection{cluster}{Clustering Setup} \ind{clustering!setup} Suppose you already configured \ejabberd{} on one machine named (\term{first}), and you need to setup another one to make an \ejabberd{} cluster. Then do following steps: \begin{enumerate} \item Copy \verb|~ejabberd/.erlang.cookie| file from \term{first} to \term{second}. (alt) You can also add `\verb|-setcookie content_of_.erlang.cookie|' option to all `\shell{erl}' commands below. \item On \term{second} run the following command as the \ejabberd{} daemon user, in the working directory of \ejabberd{}: \begin{verbatim} erl -sname ejabberd \ -mnesia dir '"/var/lib/ejabberd/"' \ -mnesia extra_db_nodes "['ejabberd@first']" \ -s mnesia \end{verbatim} This will start Mnesia serving the same database as \node{ejabberd@first}. You can check this by running the command `\verb|mnesia:info().|'. You should see a lot of remote tables and a line like the following: Note: the Mnesia directory may be different in your system. To know where does ejabberd expect Mnesia to be installed by default, call \ref{ejabberdctl} without options and it will show some help, including the Mnesia database spool dir. \begin{verbatim} running db nodes = [ejabberd@first, ejabberd@second] \end{verbatim} \item Now run the following in the same `\shell{erl}' session: \begin{verbatim} mnesia:change_table_copy_type(schema, node(), disc_copies). \end{verbatim} This will create local disc storage for the database. (alt) Change storage type of the \term{scheme} table to `RAM and disc copy' on the second node via the Web Admin. \item Now you can add replicas of various tables to this node with `\verb|mnesia:add_table_copy|' or `\verb|mnesia:change_table_copy_type|' as above (just replace `\verb|schema|' with another table name and `\verb|disc_copies|' can be replaced with `\verb|ram_copies|' or `\verb|disc_only_copies|'). Which tables to replicate is very dependant on your needs, you can get some hints from the command `\verb|mnesia:info().|', by looking at the size of tables and the default storage type for each table on 'first'. Replicating a table makes lookups in this table faster on this node. Writing, on the other hand, will be slower. And of course if machine with one of the replicas is down, other replicas will be used. Also \footahref{http://www.erlang.org/doc/apps/mnesia/Mnesia\_chap5.html\#5.3} {section 5.3 (Table Fragmentation) of Mnesia User's Guide} can be helpful. % The above URL needs update every Erlang release! (alt) Same as in previous item, but for other tables. \item Run `\verb|init:stop().|' or just `\verb|q().|' to exit from the Erlang shell. This probably can take some time if Mnesia has not yet transfered and processed all data it needed from \term{first}. \item Now run \ejabberd{} on \term{second} with a configuration similar as on \term{first}: you probably do not need to duplicate `\verb|acl|' and `\verb|access|' options because they will be taken from \term{first}; and \verb|mod_irc| should be enabled only on one machine in the cluster. \end{enumerate} You can repeat these steps for other machines supposed to serve this domain. \makesection{servicelb}{Service Load-Balancing} \ind{component load-balancing} % This section never had content, should it? % \makesubsection{componentlb}{Components Load-Balancing} \makesubsection{domainlb}{Domain Load-Balancing Algorithm} \ind{options!domain\_balancing} \ejabberd{} includes an algorithm to load balance the components that are plugged on an \ejabberd{} cluster. It means that you can plug one or several instances of the same component on each \ejabberd{} cluster and that the traffic will be automatically distributed. The default distribution algorithm try to deliver to a local instance of a component. If several local instances are available, one instance is chosen randomly. If no instance is available locally, one instance is chosen randomly among the remote component instances. If you need a different behaviour, you can change the load balancing behaviour with the option \option{domain\_balancing}. The syntax of the option is the following: \esyntax{\{domain\_balancing, "component.example.com", BalancingCriteria\}.} Several balancing criteria are available: \begin{itemize} \item \term{destination}: the full JID of the packet \term{to} attribute is used. \item \term{source}: the full JID of the packet \term{from} attribute is used. \item \term{bare\_destination}: the bare JID (without resource) of the packet \term{to} attribute is used. \item \term{bare\_source}: the bare JID (without resource) of the packet \term{from} attribute is used. \end{itemize} If the value corresponding to the criteria is the same, the same component instance in the cluster will be used. \makesubsection{lbbuckets}{Load-Balancing Buckets} \ind{options!domain\_balancing\_component\_number} When there is a risk of failure for a given component, domain balancing can cause service trouble. If one component is failing the service will not work correctly unless the sessions are rebalanced. In this case, it is best to limit the problem to the sessions handled by the failing component. This is what the \term{domain\_balancing\_component\_number} option does, making the load balancing algorithm not dynamic, but sticky on a fix number of component instances. The syntax is: \esyntax{\{domain\_balancing\_component\_number, "component.example.com", Number\}.} % TODO % See also the section about ejabberdctl!!!! %\section{Backup and Restore} %\label{backup} %\ind{backup} \makechapter{debugging}{Debugging} \ind{debugging} \makesection{logfiles}{Log Files} An \ejabberd{} node writes two log files: \begin{description} \titem{ejabberd.log} is the ejabberd service log, with the messages reported by \ejabberd{} code \titem{erlang.log} is the Erlang/OTP system log, with the messages reported by Erlang/OTP using SASL (System Architecture Support Libraries) \end{description} The option \term{loglevel} modifies the verbosity of the file ejabberd.log. The syntax is one of: \begin{description} \titem{\{loglevel, Level\}.} The standard form to set a global log level. \titem{\{loglevel, \{Level, [\{Module, Level\}, ...]\}\}.} The given Erlang modules will be logged with specific log levels, all others will use the default log level. \end{description} The possible \term{Level} are: \begin{description} \titem{0} No ejabberd log at all (not recommended) \titem{1} Critical \titem{2} Error \titem{3} Warning \titem{4} Info \titem{5} Debug \end{description} For example, the default configuration is: \begin{verbatim} {loglevel, 4}. \end{verbatim} The log files grow continually, so it is recommended to rotate them periodically. To rotate the log files, rename the files and then reopen them. The ejabberdctl command \term{reopen-log} (please refer to section \ref{ectl-commands}) reopens the log files, and also renames the old ones if you didn't rename them. \makesection{debugconsole}{Debug Console} The Debug Console is an Erlang shell attached to an already running \ejabberd{} server. With this Erlang shell, an experienced administrator can perform complex tasks. This shell gives complete control over the \ejabberd{} server, so it is important to use it with extremely care. There are some simple and safe examples in the article \footahref{http://www.ejabberd.im/interconnect-erl-nodes}{Interconnecting Erlang Nodes} To exit the shell, close the window or press the keys: control+c control+c. \makesection{watchdog}{Watchdog Alerts} \ind{debugging!watchdog} \ejabberd{} includes a watchdog mechanism that may be useful to developers when troubleshooting a problem related to memory usage. If a process in the \ejabberd{} server consumes more memory than the configured threshold, a message is sent to the XMPP accounts defined with the option \term{watchdog\_admins} \ind{options!watchdog\_admins} in the \ejabberd{} configuration file. The syntax is: \esyntax{\{watchdog\_admins, [JID, ...]\}.} The memory consumed is measured in \term{words}: a word on 32-bit architecture is 4 bytes, and a word on 64-bit architecture is 8 bytes. The threshold by default is 1000000 words. This value can be configured with the option \term{watchdog\_large\_heap}, or in a conversation with the watchdog alert bot. The syntax is: \esyntax{\{watchdog\_large\_heap, Number\}.} Example configuration: \begin{verbatim} {watchdog_admins, ["admin2@localhost", "admin2@example.org"]}. {watchdog_large_heap, 30000000}. \end{verbatim} To remove watchdog admins, remove them in the option. To remove all watchdog admins, set the option with an empty list: \begin{verbatim} {watchdog_admins, []}. \end{verbatim} \appendix{} \makechapter{i18ni10n}{Internationalization and Localization} \ind{xml:lang}\ind{internationalization}\ind{localization}\ind{i18n}\ind{l10n} The source code of \ejabberd{} supports localization. The translators can edit the \footahref{http://www.gnu.org/software/gettext/}{gettext} .po files using any capable program (KBabel, Lokalize, Poedit...) or a simple text editor. Then gettext is used to extract, update and export those .po files to the .msg format read by \ejabberd{}. To perform those management tasks, in the \term{src/} directory execute \term{make translations}. The translatable strings are extracted from source code to generate the file \term{ejabberd.pot}. This file is merged with each .po file to produce updated .po files. Finally those .po files are exported to .msg files, that have a format easily readable by \ejabberd{}. All built-in modules support the \texttt{xml:lang} attribute inside IQ queries. Figure~\ref{fig:discorus}, for example, shows the reply to the following query: \begin{verbatim} \end{verbatim} \begin{figure}[htbp] \centering \insimg{discorus.png} \caption{Service Discovery when \texttt{xml:lang='ru'}} \label{fig:discorus} \end{figure} The Web Admin also supports the \verb|Accept-Language| HTTP header. \begin{figure}[htbp] \centering \insimg{webadmmainru.png} \caption{Web Admin showing a virtual host when the web browser provides the HTTP header `Accept-Language: ru'} \label{fig:webadmmainru} \end{figure} \makechapter{releasenotes}{Release Notes} \ind{release notes} Release notes are available from \footahref{http://www.process-one.net/en/ejabberd/release\_notes/}{ejabberd Home Page} \makechapter{acknowledgements}{Acknowledgements} Thanks to all people who contributed to this guide: \begin{itemize} \item Alexey Shchepin (\ahrefurl{xmpp:aleksey@jabber.ru}) \item Badlop (\ahrefurl{xmpp:badlop@jabberes.org}) \item Evgeniy Khramtsov (\ahrefurl{xmpp:xram@jabber.ru}) \item Florian Zumbiehl (\ahrefurl{xmpp:florz@florz.de}) \item Ludovic Bocquet (\ahrefurl{xmpp:lbocquet@jabber.org}) \item Marcin Owsiany (\ahrefurl{xmpp:marcin.owsiany@gmail.com}) \item Michael Grigutsch (\ahrefurl{xmpp:migri@jabber.i-pobox.net}) \item Mickael Remond (\ahrefurl{xmpp:mremond@process-one.net}) \item Sander Devrieze (\ahrefurl{xmpp:s.devrieze@gmail.com}) \item Sergei Golovan (\ahrefurl{xmpp:sgolovan@nes.ru}) \item Vsevolod Pelipas (\ahrefurl{xmpp:vsevoload@jabber.ru}) \end{itemize} \makechapter{copyright}{Copyright Information} Ejabberd Installation and Operation Guide.\\ Copyright \copyright{} 2003 --- 2012 ProcessOne This document 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 document 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 document; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. %TODO: a glossary describing common terms %\makesection{glossary}{Glossary} %\ind{glossary} %\begin{description} %\titem{c2s} %\titem{s2s} %\titem{STARTTLS} %\titem{XEP} (\XMPP{} Extension Protocol) %\titem{Resource} %\titem{Roster} %\titem{Transport} %\titem{JID} (\Jabber{} ID) %\titem{JUD} (\Jabber{} User Directory) %\titem{vCard} %\titem{Publish-Subscribe} %\titem{Namespace} %\titem{Erlang} %\titem{Fault-tolerant} %\titem{Distributed} %\titem{Node} %\titem{Tuple} %\titem{Regular Expression} %\titem{ACL} (Access Control List) %\titem{IPv6} %\titem{XMPP} %\titem{LDAP} (Lightweight Directory Access Protocol) %\titem{ODBC} (Open Database Connectivity) %\titem{Virtual Hosting} %\end{description} % Remove the index from the HTML version to save size and bandwith. \begin{latexonly} \printindex \end{latexonly} \end{document} ejabberd-2.1.11/doc/msrl-roster-deep.png0000664000000000000000000005506512240230175014710 0ustar PNG  IHDR  sRGBbKGDC pHYst$qtIME "xɴ-tEXtCommentCreated with GIMPW IDATxw\TWS`[( HX7MѸl6fӳ&&ٍQLlXFłŊ]44A@Pzafdd +z߯UssssΝ{L!hĬp$$$nlKnOw EcB&!q!LTkJ'XdƬp<=g=rL2e$$n0dJ2҃hC&b٘0K1%>jb/_(;Nm\rݔDg0c60VJb!qv7wç<6)PF%Gg0 ȟ"CEQK͜;/Ƀ2%.r|!($Bndfp;h6̘Ȝ{BSCMJr0M WT։*8Hj[BTGZ (] @ftI?-!̘Tw][c-B-VJK,2`6lpI2ؘdd„[OW**8×k~#r`b˯_لIW.~ƨ+鲺fW |'ڻ" шO0шltko^Q='qlQ0}ڬd2RVe0 t- s/̤DQF)GKG/zV_[Tշҟ"bߞW׾yWD{uY>ƢYMYtO|{ud S7kddf=&c-U{~(ŲHZ?}1uL?Sf=; t ̆$Ͻ02JϗPQ(嘍f *2pl]~}Fųo/o8K>?OoԚ&\L5l*Jy'$0h3g=;0-L3"0I5  q9o{B.hl{޼~O(^~PgTvS7^LCL[dɈOY~91#qt`Ȕ` Je ?vDNޢE[ݑoІ\|.8Pœ>TK3[Rc6VnCη/GB"n!5ӀusM$)? j9k>TīOQ[kdZzVϑ[RH9D` U0LfO[^0LZnf@^`M=x]ujw a-k\Oxi 55u/zѻiYqG^#,r0nT[ 9o>61Fr0E.0lmUL>|chKjkk1R\Yӥv55Fjkk,}o魥u6kLz C&LBWB*BF UP]UWքAOmI`Pz.]R9lRPVœ^=P۔SsN+ڿ>AC7^BnfOߢU+pWEh[ɷ?Sc{y|3G'Ca{K6ߒ#e!vHm_AXHk=qG.0.q<J_s^ 92YRF BN9Nñ8zOTUˑJ ywJo.˸JJfA2fKSz&_SW2 ̏Y3`a kyݡRd΀\)%z&r}9/Яo?:G 1߫ Ƙ@M_uU몺|/VۓgO/?YJ)ݶw9-#Ŗ>.^_VFMI{8qvD&#ˑ@2*5Ǩq _Zrpxk}%:3v R!92'3r v{=ku]o/]̠"c_*jqwF)F)kvܐZbOZ%EU&\DkQH_n:sU>>au]~ʬ_>Ԣ`HHHHjL\rD$M" f6+\HHHaH!!!) v ?TAH;}?e \cڌ0DDZ$7$Bjg0ZQ%2b"^WcѮԔcP=_-|1?w=[IM9vh+j|QL1(H=U8!%|O[}o5?y˽lkO&77z/[nR>_{AD|keL&#9Л_ʒsW" 8,1c'lvmDyh8;+qUzmm-sGĈ 7~߮j^{Mn榈h5-jjۀ,ƌ@pX8ӧ;Z>j<^[[ m]6Ӯ\7#jGko`0tNqb}_ n1O}~E$lo+oo8q*+~fT*%W^OXw9z]lki<8~ˏZ"RYo ]i. ǭcÏ?ko8ϋ`R"ʿ漍ɣ@7… Lb!Y UO>Ͽ?ց^y?ܒ_Q\\ &_z\,,~h-*EEchV0>jmm#}Zmn8rS\c7^^vEeKSv~*#=:/Ʋ_TWV(--*ƹ<|}p.'CVyYzlӅ!ؙW&wljjjXf-6+rrrgC'PTpw#\6ZU߳n߶t[KjTw[}k+jsnا<\ݺm[] k4 oj= ;VLȻ ާ"[СO^6a4=5g_|Œ싯XtE <(//ޞq P^Q[;i#c2{vsأ3#gd}Ys}3~|Rm􆶮JۧmcMCr=2~2.onzl(stjuHHHtArnf;f rؓv[AYc S>}Ҟ~\?Uޑ|p|$~t =@GB ⼒'!!!ER!!!q FnV C'aQc$oIHT6'HBBH!!!! $`\Ve:DoDJc F7{y9HKBBjjdge_?}IDwz˭ Ǝ;Dm;vlwn,?W !h AQ|h~ VeGeتe$'VeP;w1*f4.n892yT6Ƿ%5r~ɧتPi{toYz Z'|Ѣ+j~i1aCq:?O>*lf0{̛%W˟7`!>~$$$ h%$$N|&Fty߇K/3bp.^gGx=yǎZ ؕVY{7%C?¾}?+-jaѳm,ԬGqH2%E[|x:to Yx LZf͚U']-ddpE}%}{opwQTx7ޘ{%W˟G !(x޲jV[|&.DCԤLK|>/Wُ̜W" aы }mR&/7Dzo_ nm(+-F.EiI ֬Ye)jJ{%~h4F^kJww-;[}|Pd2ѯ_?qHrh?bw)???˾>}@dg:!%W˟mPNNGv FshMP___K/ZT*}\.o J%zp˗"o ~^DCjQVZl) ;;;K 6yFaoo/rX'm[#GV+d2]2CіކFXdqv\iJ>]UMcY:qJeo츼ah̙3Cb5׷o_s:l{쭷 @|P! 5z)o7vl2ebw.;٣%m8agg'd2EMz-jJQUY.Jyc}/_/x*JXKVeade^3ǥqٝCWIFİtbz-.]|U,OꫯQZZFEE7mbm0ny!fLIN>l^=lj' ̘ѣP5X㎻f͚٤>ռs{to=UV"˹ﻬ/ E+:~=8->ٳ?d\^kMjP4hb bm>~%l=+ 5zQ^ @?v*5V;'8j\ EPPP(O>Ⓩv*h:_;KFx{{ [嫪,/ Bx{{9sްLQ~Kmqٝ#f_3qt.KKW7Wl6ӠP(*qmx{{k{I$$!7m`UߔᕐZTj{r9!!!|"I0$$r ҔDBB"KI7.k`DDFJޒ)+>0$oIHH4AZÐCBBB I0yg< `H'!U(É_L&BPXXkrݜ* gg'@o I0 %iiiXacs7 pqC899I#UBE}V')Ѭue_ii)㷒d/SMAc_-ζm)**B2rp kR_[vޙ;I''i/)Sիgʷ-{w^*mӦ8wγ}% '8]|mMakkéS)JgĕEB233IMO OON=s.N<#h(JE 㷵=:iWqcoϯ* |hI{BAzF3WZ#GU:+VbVBvLd2udLiq/S+x/,,wgnk ?|Qܖ7`dff"~NGw0 A \XZ8[ IDATZ& ?gfF`3extãZL7( J%eee$lajF B);mq%kkk)**JIa#YҖ/_(jOG f5LBBg;c*LlHMM NNNLld1p(PT`ogOaa4ʮa>|bH4Oo+*ѡ 2„Ha/GAj9k?I9_KnN FYy9*шȢ{vRpttրJDe0sߝ=IL2j((ry{Kr/ scAOO̕E u D!~r]U0 3f!꾙ff@d|'q!ݓqFqodJVn+D팾iyeyǐp$17-ݲ8G LNaa!>IG` LFU'j~,өVՒU5;[':v$3αws`8;;SQQBa7l qmJŰH***P(WT&.Uo=ĩ lH$eP2lY`:c[37Mv>}|پklU?LDV!=D Rh|~78v8[P]]k‰'^_-}zpӿr盋YX̛<ΏIWrwwJ04 ##~~~d#Z@(Jk~rjeeE,***,bI,$Z,f3l~Fߌ}p_RՖ@٣1C"?B!G.0Sh-(J U-3229sw6$$Z Bq?ӫWOϝϲ/+;8+vSg!!qk>&da2cӦx -a;z}5m4Z$nx#(h֮4;iq6'-cFKEB~uv .]BBD I0$$$$CBBB I0$$$$CBBB ]0lUvتnG;Zi86FKjjj$閐)==Yg=:ygk.!q!6cΝM"ֶ;wbww7̟+Z |cqp?Mke>_?Tj{`#2lUv2cc`pΝ3g7]___S'F/. @۷I˾իiXh4ѣ%EoXfV*JM#*K[˖Bz-* :䛶tou|B!D~#ɭLeߙӧ ,#}Vj"lO֘:2PNNGv FshMP___K/ZRlRrYZR$T*],_oyѳGVEYi',:4\lذb⟬Ҷm"F!ZdvdmLmh4K7iǕ_UU@49*+AR*O[c38h(sXtٍWܹ{7&:+gF[S\alaы?T 4H GGG1q~6m?v(?/lmm ;b͚UbtLPNDGGZV5wÆ"((H( ѧO ;aNG\ӯwߝ%_@acc#łUU_x^xzz B!Ŝ9oX(]9&:+g7R!=X⊩x=Fl6ӠP(*o*=XB!ظi}DrBBBE`HH\ ϥ[.#MI$$$,¨$!!q2 FU~ѱĵOYх yKBB $`HHHHq}yR[%$D++D|C}W^U>hVF#~*]>KH" 90Jrav74{IMMIMMC3g~ۻ4J%$i*|3vgd4 gxw((jp_Zz:_} [-ȑ+--eceTtͶ|~)h6xǏ|AAnne߱c VzK{Z[)DKtϒCΡʓ#?Jbmڵ4q"ؕ!Cše &LOd2knlmӬʔƺu;&vذa#U:{{rׯ@EE.\߯I{/ϳ֖[Hؾw_mUB#*)SHڛ͛ظyI{H9BUlw>`w>R|'L@bkkKTdCPRYU^ёɱ_L___lllPՌCFhCm{mT(sKF.F$'7.8~` EGchZT*2);կUB" !兇'~@SYYIDC&uC_uԑ|?g;޴qNwa]TjƏ&rrrٖ@~~ڷajbu oo/jF#Ǐok\EE_|umbBw^20֢B qqqŅ̳g9GtH4F#ǎ'*Rvr9X-.xzzp=w! =#x晦U{+~~PT C<?4ZJ&:ziYdJ%1Y3Fն޶J㸗fJpaY3o{d5 sE  >(LnKycJGJJ "//Ʉd ?#Gr4}xc6 R:TǩS)xyzY3:.;zdRQQW^Caa!f!f|tb2Q*(Jʈ۰IVcޓF1LJ]|i9 '.n#%%%f.\kV:V [#3!v{P2s5.Sw,}9yucDUU:R #%Z-!J>hDEFq.iiѣDiW="&fTiCHܽՓIXGbnZ-Q>}ƒ> 0+WQRRӦ5h)'e+eejDEE4+ZCM ed2t8IoUcN%:9}=G'q]xlgٙJ %%% yjR6!RT*""@PR^Q4$;l V6'!]\ԗ#Bɰg^Ʀl\u;%I???2V[KO qnJ%{P$Cii)Ό9Kz̘>޽{-a;?/ߙ;O.EQ8{L<`Nͼ'SN/O_lQ(5PȑdU[ @@呝?&C ں899$FekKhp_d{عoGoΟg߰a*++-bu[ԋEc$j0ֲpܿ[z;=~3}Ͻ lllP(N4:-211w;N^=GVc6QQYJ~BC sex{ۋǓ-Cg8n, #w#&fGP0i"TU֑S&ҧtHaTC7iN=ăB{NPfݥKa J'B8Q/AEjz/RTRggz1NMC)(`ע_VBiFGlO?Izz[ZcMs=wq6+qIgDs>RՖ@٣1C"?B!G.0Sh-(J U-3229sw֮[/ Ba#z嚿ӫWOϝӧ[t{|sjߟA:#$$.qDQlܸܺ[ssش)h?~lK؎^_Myy9k~[+k> `෵. ND܆ |ɧ888p˘h_]BBno1CBBB I0$$$$CBBB I0$$$$$[9s[S_%$č.O .p'ݷmw3w_~&BWPBdό{+Q7Qf/55 nzCem>~}`4ٴ9d3w&N`O^***ÝSXQ~f;vrQ Z4Jd"!a;Ol63bh5\r|>˖ ::alsDGEwߜ')Ѭue_ii)㷒d/SMAcoo݆HI9 QMcoe߾TTTګi!+! Fr6oz:;'Gٱc''KlyAT* nf|I$_g?-㷐}'`׮D.^,ϳƖ]v5+!55Դ4֭[I ;ۋlj˳He &LOd2knlmӦs.:=O>1Yh4ّ%n)IU)$MbMlܼINJwW^ÄSw+{{4ƏˉL0V-Q4[ѣ?~,ZJ-o~cO0a8Z-jq6y,ɇsm'C}k12$ i^"#<}ؠV3& K'ݘqcoE{lv~0BIjz^^^xxzt:=$I?N?R=vDaggOBU8;;Y ߦŗAWTTŗ_؆JSXXƍ}iL= l <== moABٹs'Oᄈm P[[یWdUwc?ϴ-+q"0^W3\]\<{9|DD#,l0v,_iSX2\\\,fNΑ5 f>V+(--յɧӱb*L: yTj5 :~RɰavG4U{+~~PT Vnlv6owq 3^a% 80,ݙ7ǽ[BixIDATvC&<~!_~777BP|/V ٳ٤йpwbJz+"$x [>}xpt*ѣcش9?=:SGG,^31rpKȑ#ضm;_9ҒGnn;L_%qpph9Kߘ)'e+eejDEEpT%}6l>GekKdT$iWdy3Sr*L3q!2a *d>x%;S];)f8p Q899RSS=A#PT7` /R2x4.8͌yˉ }|;(4tI\PEDT֑Cԙ\?+^;;#* (79]Utb7ӕ޷~.]]#na|j YÇR+vg9GaH﬋m຺:"#|$&%efTUe ?#Ue떀xU"#Lr0(?o&IeSqB+=VIŊ&c|_gP~כCQЀnG4 Xu6bb>lvǝN$ f̽o;El-ƫ5үW.[˶c 9 U{秧csvxC6!G BDɥ5s:,UfRRgfxx<^{BW7۫v@F%!qcRLr1|iF OUGQ&r$ɥsz~~JW{l!_fB#g_1o. Fll,.f ǝN n˖tRl ZDcc#fFd\rX-fnvXͲݹsD!>(,|͛w# Оgef/fEM7ck)2j, SYU:;v|UzU|qvŊ+x<]m(33v qqi0h y,2]HzIq!rrs)>xCpxXnԔүvw;Yn}ɘ _KX/ViHMMZ&m9BU" !0 t0K$nI"Ҳb5ftxD =zPQQAiI)yy膎Sx ]p[Xx s}|2fRSSb'Z.ƠX Iga~#F=Ľ7>IMwbdMcZ1]N4:,0jHߑ-v;av7誣( )ۧCoe1ddرcXvé8x~ދy 6lb63nؓ"vd()-ppg|["ECkzp}X0B"uu1w#1&!.8!DA\l,I rpܐTW%;pYY|T0(q;a#s8x> g-o>vde̚<;$',o. >:`@HNJb䕽1l6a2LKҒ( %ÇaX b}ƇH$g ٌjz-#G +)- fm}wBH$3MtUQ} t]WrUQy777/V'"-||>mՂZqXlobdoH#%ɥO oH$'R0$ D"C"HH$R0$ D"C"H`H$)D D"!H`H$)D"C"HH$R0$ D%iJ2g@~ F[%D$D D"!H. !Odon~U.Df3RRzhzi30NMJS81C|pYi$JC$%r2n|;9y=1[,H$@4Ϣf'{Nv{Y x'0@ 0&t! 92k6WqHg3etD bG~oL% zDFFo^ayK;W0*4dffSUQjS0aV Oy?~8bx~zOuł aXB5PI̊լnU eaUZ2-4m||W1N`D"ٶm;{ 0ulV?Q6/q.#~vGAQ0S?X0\H.uD"0 ,#քToc7o>rE|HگsLVZ[2p~X>-րKb6#-k4?qpzU+9/؊v]ڝtO(opF<9%6tRLj)O$&aBW:K)[流0Ea1X=ZhbSrp|"r4`]!!B(P;]rU\=nP8p=<:&Gn.\FFn딼)Kr$"~~^a6)AĖǸrP nEwC`x뉋 gԄٿc5< ^;0^Ў5HBp{ J1=uK"S'McM󰛢0a0PIJ#>:Yװd)y7}FdLg\s[׍b\hEaڡHq|# !4 oZ} =^Eua+F-c pVm&>ZSEdP^st64=S;Y'#%Bd! !tt@uܞǹ1?oy ߼NL\"\ VXIPcb)}܀XakCC>|g#Qu+ %c6w {3tv 0zTY;_cbу0 !ta?7־Fým:K/<[ogߡt+o{ʒL!0,&p!&! ]ubxECkB*BWLjv$ۋW QAd2X>7eLYzT% D;8ǰ+`7Ea >F@4Tuuu:|[Z& ɩ:6;osmk#tfyUU,Ku>,zƽ?咖$ !04/D:z _#ߍ<0P:ߊKtG4r9&GH tGћҌoqƴ:2Qt 7[~44|u^ͅF<Ժ+Lug-o1sBo'66[&,hw0ud~͞š(޿=zOlSP[~=֯e=zͲ^mv~{6̯_~4x,^D^F0))|xwo߽|x)) z0garaX"aнѽN ]m@h^qyl۾SSI }hTéDr)My"iTl`]]?wIT QP0ћ-M% 4e@MM I)i'Փ?['E2x q77mǎhjj VVuv) S>zͲ**+4=Sʒ\|? (+=HVj>Ը%a5>[}eu`H۲gsԣx)RvTJy/5^'<)HFi^L9Gս />̓ٲ,*_Lam'Kr@2[b`~,\iSo2w+ ^/v{#eOoGˡl3g<6˺<΋?KFF:^<.F-̪v.4ů X{2RǰO {CdW,=c}co7\wg?պvpP{ܷe&~W.ce\۪-(0Ph_nfĚ7 !pd C20,0M3YozFM E5f%>" bn3+`X) jM'/~I1YO2bh2Sr<0{^̊ sk 6D"F FZL<hoi@7Rߝ/5!gu.0جݠNP"E)˲M5=i ;O/!+%GvN,{^7d Jc'/RLvr6[Ngma`ShS Fs݀!PL}\rqן$g,t%/u!h`f4_N(@tMl6i(!_;!<"s#%-s/.JHIMoi:v 5FzJIFcKĵ .G0 Dz?1Μ6s$jb^;灨 pYr"z\a}|=ZRw׀ .r-Dхz31sS ʾ17%"g 059 "LviPO%EQ`:ܸE\xk륆㶺ssh}LMx LH!B=+v ֤5[#Rl .inܞ",ҬƼЫ kݹ%m]d># Q`(j zocXE1t涍ms" 0 C8s{ 3#[\Q"zhX]^.@7Z]5ЙbӭG;fU Or.0D]Sfru ej<~Jmc}԰]|oD]J}%q\gg]ѓ:S;7ԾE=ip@_ui=K):qwWv<6c)D+4sܻ` .@1م\ wDAQ|=eCk}RKuuZ =8=AkcD-Ժsږv!]]]ܻP.!=ܳVw:^ooKU fڨ+!x- w D] +WlB{kzo珰.VW+:]]H lWH;J[mDzZH6-% DYzz{3.ў^1 -`[89vM{wf@wuዱXW8[ȝݵ;|ݴo`ڿ>~ QR1wTB3s ; \!آ@Z{F3 D]"BbnoWBn-zqy̜h BoiCNu>q[Aԅ/J핹ۺZPv9k_MˍixcwD]PJv!)gu/]tiѷ[=j[-⮟KQ5oQ>gbYB<"+7/ lj }^Z7n/7w a!Z}G }OmZ39}U}`+`o!B,炨 ;ڕ[**1hǹh8#\#g@6u 掊W׍k/:{A akp{qSAԅ 2J̽+wk+ܝxyWd98skq`8_Pow]E:p!fsgrGڵ\'/ꮬ񴡿oЍ puu-Zr#':lɮ@Z]_-hC)v..L\˜1Bn ku8#MG=ýwX 0){AVR=K)P0u+0g5^P2["Mmw"E.LFo1g^nj9Ӵqgw페U;ewEY_5V+w涵qZr膶nrw 030 g=#z:vԻqgtu߯I̽k-Z 3u c2S;wk'j}v?&烨 i%#q{g0SݝdV E7ߡޖ[o/oM^]J@ԅ/%n۞Q *斈֙-b%6Q 5B"mk{:w[3"/.q B˾;vѱWBn"j`s"[ĵ`x{w{(۶D9PD D]QR m6w;*/wF!w{vyE֨F! -x6e1"j :ΝY)򶈵Bn{Un\ 5osuMCN[=ؖӯ~&wLㄷ>QH R0*~;GvF.XRyG\P@;>9Ⱥ"eMen*%QD Dݯ'p;U%`-ZqGZ'9k/kj-x}ݚ6@ZzCJԂە{;2ys85%V@kֽ4!gݣ}}vU$ÑLDݯ$&Em'Ou{뾧K(`c?Vm`Hx-ܻvqTuxCc@Bz-vZF-y-r5omW˸^c˾S癓V#vסZk7a]vubhgsgsGr{F6c%i.Z[G =D(ni4v}N9k=*_?]%gDݯWœQ s?Yu6ֹ\}W ߛh*}ܼ9q`Qm{HrvAxrܱQ %Z##\r-D\g>3с碍h׺ nOOqwޮk71NcoQYL|oƌm SWm1ʕkÙ"nWY5㽼!x{OmuږڸD ^%g Dݏ̸ܹggrEiφwTx5Bo;[hߙe1Ѯ]'q[8םk;;+i6hsna>"23gBl{oqw&nr |>|(_E="3CZU̵pr[ܸWpkg@;nlD^[UfnOn6 mn/no ~ !AD|;UA̵r sW*6zœq,K7OMx[^VnlmBh[HVOy g 0snYbbo˹QgvM;Ӿ@Zk#Zws`ڥ|6DQ m;173cI= -<(bbX7yˡ:^C7O$Ñk7%/B5Tu/KiAou^A̽;k眮|{嵟HZRnݷdu18 .|1ܾbњH#R!,W;88o`k+ZE%̳g$CC7f|Qr%l[+^!ja1Ʃ:N=X5>֑÷FpSܵ-h}l\\AՍk1^lۖs,ּܫF/8 x'2_k%%^ɵ( ^Aosmvn@ԝ;*?&nܝ;ZGXeгZkc95>VW e{w+ok7'W&+a -Q cܹ3D\ ;giJJssڴu(9tC\q G/.\ D)t[s*6ڝ#Z8}--䎌^-& ksP0ҡ[ޭf%d(٦5KMmEk;3vZZ 3 =Dܳ\c{jx^=b\9 -o`-y{v_vk4]Dipޟxa%躆m[s{D-sǻrk^jmUuχp mO/wQ۽j)֊ nk]8Z<M`Zuݡ ۬]ja"~cNs;?wVwnYBn#S?ޟ4=Kgn?qW$COn^.n8`f2rMf)Zrό^ԝ|&::f1z8tqڋ-y\P816\u1{fHw'="yI zJ3uψ`(g+&l-%g]8D!8,q 3sgs\g Ϡ;|[D^ 5S]Ha8v`Fu,C۝;Krgqv:O%q nnH]8j>Uǿ֕EZ1o0;+g)1t"UV"mOwVq`qqܚ1}Z:A vTmMP+ƞ`!ڶ=Su3j诔^UU!SqYo9V3 .|:ݘEнzHwbk"j9= ݵ `mQϯGbn|JW "hD޳\wpI9}B)8o;á[z,56޵;ggar06[قZƪOmZ!~;KѴ<u1KUݞ 3zPkvU® ɷvD9WkY:naFw=8ɣ{pR/M IDAT1ԴmýCܵ,6kWj0Ōtgϵ+vG$斞G;S@5ngN'抳 GG2p~{ mQ0ڷ oW/( r;zRow555Fn0ڵk!7C#R"_k[~~6Z0{{F֮|ܹ6+gE2Ew|o숺9 Rhn9ܱB3{kwnckʵr]#km,ܻ=ޑ }]Efv+.Cu$"Z=s[fZ8GmW!Ze7zL+9iE-hrڔO]l,W9c̱brljm;>ֺvu˹4:.8S͹淈ȯr/ԍ}9F!tg,f`{t=[5e'o[h-hf޵fL(YQݙrvGإp|D +{<ۚ;Z!^%vX#36uP?1E3MrZrvuX?u %gUuϩן.Z-\ѝk!d嶈=".;ܱs{W ֩W3ە\ٸe_v|]]H|B~tNȻ[k0ҝ;V̭XUڭGvjkR%$0[75,®=>7)DWݫ؞Yl/nufm/rgp~ۣOڴNmܣcݙ]%q niۣ'TEӨe 6uW9nX9QBm9s+7g^{c\z8#~ [ӝjS{.(jC6m9-Aq o"9V)1,V1w+w'<u8=" p 0ټ.p-Q7VE-H^A.?5n;bBn;:S#`xGWt0[?.5|kQU }k-uk3~kxx>`;2XUξvvk?x[E|}zsU!Z0hVClߧ= ]!g[?u`m{EݜVJ3,\jy^);iZ{ REmڵc4a7g|u`M;E}Bj!_>Mеӝ{ۣZz='.8gxڵٝY v'"Ourw+ ,mxsGҊ~yUѮ]ҵvM{4vP 越aF !5v1w;]l#c_*pw{UvW|г0nOq^ḘUޞaQ;{qLa7w͵mk yc ?oDy4 ǰg W[{e!ם9B=Wܽk"an_䞱 _{D]?vGaz!T#Km]ks-sxKrݠ>#?y/x,jz듅ݛ|c_Mľ0Zl5dr1ݯ]Эs{5jpדEwQeͺmM^2ږ^76 _..cCpsw9mmHX-wcJ߷_]o _ ~yw~k0;6fLW,~]hWc$l$7ʹ;:ڵے[c-/%5Q7P*"J@z؞SO/AZ 13nW; kGkljc Z.kR;3 pQwyWFS$OM olBAZ̵p(˂<:`3ݳ]Z^VJڟ,n?DB.wn(vaTaݜyohq %c]v5A6vzBE*$~;µk) GՆ>vE>|,. B ;?wwn"h1fhL~kj"v:3ּRn5%ƪX.즎B n*v*9sps{r-Y8wgֆVE=C%^͵k)۾YF!|]>Pcz"֍yF~l\g4NvkWn!W 2u~~4ܯ&pZGm>Eح9s.\0Y/-ε,VzOGi{5.^5>m\q 938v-3Fx6~'w.|2uR+}٣]븅3Yc,ʾ>u'Q?W/5O8nj[I<׮;7ǍB=j[:ڹUxǎxO9uV%G [#x"ε_sG D\Gz8jpfִ;cbn9c;~ ^4OCY+~ѕʱrsA=>לYd-w>#(VwfW r3wk3wKv{vGح[mj^+o.*"ICm흣[?E:F)MښnKI+p~{vW;cMnI[{׮+r[5Zǯeݵ m8ZKBKUGaVA7G 3DPz\WUinOϱω`(xG9&H{FnQbc{ |u]~;;G %AwQ W, ߚ{BPy ]+Lq7}b'p1?]mmۅ?G'k ='y/ZUvN%{ ss\j_~B`%=GMUحLB4֍#lZeQdZ0,w=~k{;wf1c?uf@Mg}U XsY̎EmNꋨi`$쏝w\}IW48Y>+:Q].2ch5Ƕ>W0;{c*Sw C{[>mݵ*VtmZ+5X{Kmn98g*iE~a៏%hY R9ot[qɸZ/1׺`Z_wp[{$2ꭙSK1jUs躂4K\.XIn{9@K9kuۊX:vI:tkwP4 sSw_F 9G7\DOt[cFG-#z y57x0BmnCn_}h"jٳp}r릮MsuDD~SȥY2[A)m)rG:{on}nC.,wWƌ;7Wa{,w;vSjp֌:G86gQ1 pu.]]=ݱ-9֊vnQН͝k-pPs bR^;nqxWUޖ(׮kص#u~s=_r: rOYqRp6Q5X:pQnkUb;V&Z Z=2̟ZZ8xe9\nOn5Z;v-H|X{C(Q\ȩ[mq~n %Ǜ{G}k\ WH!<3WK߲!)Ry]<,98vJǻjE>\ 9uڕ 9Z"j&Z-^{(Smq _Pȇ vnJLӵu9w햺vT֜]im5gRn5=ז܅]ܺW"NE^nӶ5Onka4 nkoq{;,1^ȵqQTGѫZhf[m7okM{ݞcr̛;Swn>ږw SAt>crsm\Bn]NͱeLxZM;yT5]3\GO'v֎!M眾Zp`7uo| p\nٚ[yg9ڊiC\jǐ1Dk+oMnnӕ[SܯdM[0o5Zug-qs5zuc:#_W3ޓGNDOdrKwga[۷]+6ӝ;^mrmD\gE}ޝy.^5ޭwucYvKrqs8;vkƐ_cg=#_=ߓyز*"r Qi["з0?$Z(6;3W q?Z?3= sh/>ߍvuZnwke+^uǮT-aۻوܺWdҒk^$r]e[jŝ"~ʂ[AIm9m#ouk2>'bHi?|/u={K(|/ȹc_-ᇈ).„kf?KDzԙِo+K?%\gpoos-g#D2z+Zvlm8lP͐3!' :Th7b(m:b%σԹaXݺ?t p&uK\ݑ 2GtMU14 w|Oوt{)3cBiK/96xݡ=eE`93 s>5°To-js{S(udK7ު8ZLp Xk;0Z[Ak+rOKK{rr-2tKbrb?)O7uN.c=rǬ.F^n}ےަEnصC >kw}Xҗl]0SZPSgB"j*趈ٰܹuN6gn=gl 58s#D39w]`1׮vƶ̿i;c7g.m<>s59nSs%.L] Dd\$wYrtK[ f.r-E+:t-ruc 5 5mJݚm9s6aw|vp.gJZ׈"d\ zt1k;v!w\Kny_Am5s_׬} \=rN-c?U-y5׭t}V#Mֹ_uRSb캺[3L,'[`v&u-]=:rƩ2f;LmCwsCpsc,B5q,yڊmJ߷Z/XMí 03d._FG5kbka?r侉u_strdlXO:ܼi9K2wv[ Ʈf^THY뺌u_[_ll4uffnH-qZt{dB,j--t:I;K"ğq'ͱu״)Wʵ{||-xhmX1j5pˮg۾b2L*~+j ~~[ j/ja.}5D]ßMMV-=zn?{P)ֈ Y^%!4oB ,ꦾ~r3tͻGnݲ=&X߼%\)9S;Haz9NZDpueT51\߹NKhMufdQ֥[E*%zTٱ _dۿG{Aw;+}-_/.g\9^"oX"OKݞg=O+.֚I߲wD~J 99_Dj]gG+к0Xt-  f3x1PiA5Xij`{Zn!Bi9EmErƫ)URby ;.xbתhZ8?eں r'Kw038ʱϜҦKеqϯE്Z(G*CgEE?5yVG+ϭț#ڮ,D2e#\ 5i\G 9s+<NJRy.}"WA9,]Rٶu̞ -9|%kR+9n#yob3jSGO:8-\\EuZyϮԹvK] 1rutJsʭ>9LIljw9R[bJ֦WdCzvr/Տi6[\)h2 .ɝU3;Ys/u־o}%Ҽpfu3ԤY35>S˞jOhMu`Nr._$jnpjNci`|͜C*F>wKߣBj)$.gw+hvϥO3MW&Q'(V"B#st]ofA7}r]--es+-usq QDMyssvKGOqԵRDMF=WuMs-ӧpZiokѵ3u_9 V u m+[F9-cJǭwFǶY`!Zō'[P5εkWǎָGBrJM VVqm[k7/a?Ovk!Vr:_ga(C\7=Nf{KxNp-Ys"0z+8wbnJ Y[H *}{ѫ)f ZqLnk®Tέ=7|n cg Èqjܺgs;KOaX,cJk W5^ s ]rjXǸEkmЂ9DV \q%!)֖;+ cgNsܖoa:.r|8"tZf|+?Gqri/=AD.t[ܹ#L!ו KGuW5LW9y!ss 9,Hi0[:٢,Tc%p:uud[GEL/ncwtBNnMag -F--Z5"n?|hh`s֊%oCBܵdP"cvs&dz(&FotHæhZEuE-62Hu^KV ֦tjV[= Z_wEB,.KᶰYjd|/(ЂvZ5 mݺ8'%2o' 9s>u%\ZϡmCʩl)S@Q1zgo*J`x 8A-?wwnõ;s[.ϫs)~pDiߝ{;xف޵wk"rus®HkaWĦpdCٻT{Z>պuD]i|TV V"uB]kAx&A$?;r]K9l_"ۛ 1AHKTC{w[ڵc_@F͍ $c*V:r"c.Oj.]1cjޮa#cڗ9<}Bp4%xK^P uφ !8,jz)x[b ޡ⮵k$jݚ }B Cښ+/|8..]h &[9;ގJmx܌1Z*.:h?_qU}z5x'nqcUʡbV8R9=60)/VN=..Y umŏ1~V}j1Eevٖo-vU#8vgtk#1rՊGv49 ;^C:J9D.͘v5- *kRQ6Ek) 1 VEӮ]O,.R"m"uSmuεstkڻ}["ZsK\KZֻfJEߜ\M<"FX.qe7G*(ѹ}VnK$CHYX=svvs׬pZ[1 =)s[7AQ k2mwͩ4G7gRڂn{X=c[ܔZXo3*. Sw޺'ױܼk+nC4q7[LmٝCحyk{aȽo\@4tui֎nZnZ;y[߶"m]wp϶  ݹ]%s]  3, vm9A5{FиECKna7>F^ki3!g]4mL{ÀD/xY-ir.u2"vT,*g!ZvZKbNYʚb{q3-O.dY֝$ ^0wq{TC}naxyօİU LEӤ`Jiq"'iWtJ~7㗎{5ю&x9skݹ5md_{ 9&H2Ti8+wro8o^CwGv-rvgv`kܒ?u4S;^nu~jI͉^mo\ҵp挓VLnI~nwnVnnrs$pŖgꊦ%| z=jvcJvu]q ]ɞ}*_W{cg~[>Y ;֥[?U\Q mTk?VgϺ>5ϵ[hZs\i!׉my^9U _r8kCuGcqoWnKYn\r޻-ϊa(٭O=Pl]4 ^m>V!\0*G}_}a6n[2ja#8#,8qG}7~}ptϑvɶvKa-c/VA`Ⴍs0Hz v=ܺ-rEH:sڟ[I~K ^5핣[S ]=v NT޿krn=KY_;7MEA,q{ V6ВS{V H851n]O`:-}, ,g{ԷYU_$6schFGܚivNլ'Dޱ 鮝>kO]nF6%Zq0!W ncꊕ9n[ܖ5`֝! '3 r^ť3ת3<@[/浙[-<,wn-CuEܺĵQ?1_-3Z4k~aqWds6i_E2dg1*%~>mGgKs.oYʭ[6x?1tukĎQ.] .]׹OiU~Uߜ} mtݹGQ !A6!Nq&I8ǎDCmnmUuou i  c0}KU\b6~{E66.kZ]װF-Zoεs-<.ŪY#j9Hw]݋P|ݵ?mq GcG YHƚ^9hZIڌZ+zu-&$!oo1[>q-fo׻k]ۆ"z9B*GZpキ3}T !=] 7UY\7ir&]Ŏy Z8t}J"UdVn]˸t 0EIGZs<lo}a"f-so*U 9 K5mn%sЀ>Vhn.q}NrW@ҡڦn0%ٷ{a|5Ӥp=rױ }Ѵ9֭F-*F0S6@G E+Hs>KlwU$uqTWu3ָ%>Z w]"\Bnڍ ٥c߲_uܹbg戻,N*hXQ@Sq QYʅ|}t><'>!/Yɸ#uzb(궈" vu\לK؅u:4' A{t]JMeY#%q.%V MpM =]t}.wy/*n](Ms[ 1X1+R[86_u{;{G7:b(q\%۷;DYq!4=nb](/kXk B5[7nO9DD}FZZQ/{7݅粿۽N)rX9^hEsnTᴔ}U/ [Z49­;ڹ3s胑;9'D(|K7*P*ZF %;S -xB(;Wuۼ\'GZd3⵻>Zk߽//vw?W mu\Zh-"^ pS('Pnid_v%1|ܺcLO0uK Nw\Z,~UOA _7vkR[k!J1#_W $w>BmY3ܺcٺu-ɯ CQS s[2FXsmuY ybnD}*.Ľ?k!nۗY]ڋGm=}vo1{ordq!n]cB*pZzcZ G}Z׺uK栗[- ]GP0J,oCֽ"{?>a/ެ~ܮ&>nr{[$:vvwkmXܜݙXW1SZMݟr~[z=o'FHFtЦ9:s]ֱFfbj±m ]3)}<͏[8r֊PBux=n9pg[=hpѵQbU.>vY7n_UHaW*nj 3j͝_E4STesg SwqJ\a ,ږi[SM*csES|>ڸͱ vws#ᦷ=r aQ\w7;ǭ} C89_X;}{uZ1`ui+BMN?K!U ro+$Ae?)׋~;Vݷ5NJy7[虶o,X\Yk]evn}ޯNT▇Ir+x^k89ϥ3;%ϯgkM[e]U?K=?䌇[N6>˥{|v閴-)fjE gVݛbZJ=9ݯc,_8ଽLGW͹cY(54.R oZ1 fgaI^>enwxts属9g8vpn5rg3C Ci4)X3ܺy#,\#s%WnMsw{ίKXqZ`V ,z]-rCnصYRs#BMo[-b'@^=h{Nwjx7TLmWLMSsoEnsK }#]^mbzMÕܺ YLWO!FQmZΥt3t{G;VoH,s#[l[Pj}hNUtY!Qs/F w?-Dt8®HyapM^i8Ϛqp|moL.5EXWsfa}[[BiaAVI-,s]ۣxrZÒwZ L{vӀq ^[YJDN}+s튬D٣܇+"*?Dqr]Za7uibN9v:_gMӭs7>q <VIuEz.Hq[7.,Z"N:ޑ[]\@MoyX=*zu%C#p`hh[-۱F2bBG>Vb/DGM a1S -Rf-ֈ}u0ƶhۧ\[#EV׭W^p^V.ݚ9՞WhlbB#4e! *NG(Dty,' ݼ~U7_EJ.~GWj9~{֝Sv=.;TOi&? `HSw䗋 Yt]5;_ ]-n\PYWAw;#nVd ;wB[ȝ9~gXMK$bA!j׽=Xq6n%!n5kݱ>zE+mmc=Wd s@.n`#z9 .k&9~Q=D]]:;Kltst D.$ em<Dkx"^4}T|}6t>.PvK} TƮx͋c a4_w CqsiVpdSJQwlw/LsUBTu Zr]ci|k񲇠τM]1z֋KrD&F|U u./)nzYzu| ^yԻz;qxpvˡ{+vݗϽU gS=S+^?3cbuc˰ IDATuk٢Hڈi>X"` W^%+5.^swM2G7HuK\߅sݐh6 sDZb 8Xg-kK=~ˈYؘau'ކN Ū>#vky߿F48\9,`,mwWv_mcY Beש6 qX1 btܒ㔌׭{߽ o*DPfu_*9HsnmNiCA7&r`Q-63Q -,ܹ_so)']`Mu-xi]=8Owꪆ-E=SCNhE"\Wd~F4Be`[aןW#"kk(cB_Knl_`W|n߻=YY"u,uKۍaϵ Yr13 stcrtc"k۰{w]qk>BﮭG7jB̍H\+_};~כء}|3t,i~n4BY-A >p⾄ݽv wN^X5Wؕ6O|ݲmEJKϞw1ZΉxk%ڞ1W.t:SM -k F[{B붿rumk;wk7Z࣭O]#!7M˫m5uo9k07O]_'Gy..vm?[wuZ?uT 3{'+X]"awv!?{5 U|];vAֵw3ns8K }H(腙zF}r}urtA;cAweU[vq w[B(x3 ̽ qngy\?sNvO-3VL[ylvkȍŋXQ^m},=\m3?EMc!"}{ckr)2*X%p]~gTVTK/nD/X~)cڜv*V-H3?j!0m(շ6G_NwvGOhwk<9浉`]Dzuwym17}~mwDאcw<\v"x\ys4vsA-۞1j/>1nݳ"ZG ru,pN`93#mq4؅XЯcݻ틏y_8͹GU ""8ZPmqw'b De'Z*Y-R"imCZ̸[W SvˎQV0?_D] :8u-E1 A3\3|]*s?-tw9owdJ]Sv ݹEmz]o+sƪ,X RlhUkogq(g7T-+>?]kPKp+fgЩxo~ADx&i۷s=|i#۬.0dXPAo^m3tKit.stwn!Ay}Uu[7nH] Wۺ]5Ýdznѹ7EB˨Kd\.-58mo.=q\yٺN_=s߱N1Ed=qy9vC'پƽ<ܺ.͔K6NfKusI-qҎvy+8mǹEҮB^i}Lγ].]xerz7׶f]Ϲ+i1@]6݋ⵗ]HWE/5MhmuY|vW9}/Zm1F}D.,U0Gun1a7VL~=Lx_S8(2!._۞ k[g`!X[/a.@+Xj-?FH]&ˉ8y91u:N6v?syNGn@ $~_~Mñ+[Xlj7a Q?ޭ[ko.>0w [9|_ n6*C,'#!.;1.N |{ ? !qHG ."w,_߯xYr? Zri~.U5sn7BEdFV{"KuKx]8E7k? z/G1WDM؍wEVQ}+ۆĽxQѴԡ+-BV>F;Ǹu.p~SVt??/_k, !Ƣ̔{1\Kҭ엊]pG}± k{'.~|C6ytz9w<C9qLU$n*/!wq;Y;__Oѻhp}fr"knvїv}E_Ą]ُe+'ޮvyL:E0DV߭][#P­]׌`83WQSMs/?믳HFL!zK=#zmtݮCG/AW7mCȉ]Xs[U/ٶ{tw /&/) wnx衛n.\憾~t^pFWy^vݠυpo1 ݵu[^1q wh\7ye.!d_4"k;Q.}0_̭zߖD)a[|X@T?¿YBivy},]W2:jH;ӥ+ǫ]p97(.Ebt=/g銼D#%#ܹ  m\5yqD uˌkou?[C7^o7G ګ>C|M:he]g]ٺ~wK krߧݼy{QXK b[Z8m$$ص0Hbֶeڭ3n4=[ޚK4OQP/ߑ`S u1-C|=Vu\yńƣܺ@F{s檡 ]O OQ߈;w^+Bn$ǁ0kO*l# <[^".#&{ê}vk,H?j!%:y n®ȫhzͿaEU e$}ó*[XȒX=S'ڥ`rVcQk ?'7Y$c2EO]~.:momBuWst}3!wOoQ>fUu;W3tcyGœ!cb|] ̋ +K|_D%bŻUU/j~du麇tszE*ݧۼ}xX[܏sg47.t&޷؆mh) Mb[0m[cDZ.sO/*WE]ũW̼zZtS٪%"}K7.穒(ĶE[ ~[O {}dnܹ.zXnYTUꯁr7V[> n>Euό۵#RAB3Jvu/'? e]s׭{:r7cL_}N!yE6Em{@>"k1؏uBTR4d3ݺ"iNt@9 a| 3w%E@-y|s¹.ݒutS {%M`mWmxb|Ttߝj7Q s^wAf٭v]y{.*&oD(5Vu/cm^L߄<GWSr7Hbyu./awS#}®1z!ߧ{9}nSE7y*nu|i*MK݋9MC?|? ϣ,@' D3qk}32x{D/\@չXt]%svOޫj9-;!8(亍H~ymڦ^#A1;wzQ i1re#g.[sziXuYuUo}E_ɽkW;|qCp]sw@Ob{fv{5[{dWaW_9z Zv;^[yYH\XXXrR@Dŀ9SQ$,"QPJeIXX`9y3M|owuUWWݪ>s\#?&JE!0-El< u" QSUn6 ^5w kqZ7ق!cBZJڞ4O˷p@ rq?[g$"@ բ譟noYn_oڭTn!˜sIt,Էa-3{9D>"f3\?q.cP4x".)"sW;I;[&McG׆##IE^=X>Y7Z=3x\%R:bime}B>YΊfEآֵj`$9bIfךI,5))lj%4Ժ\+8na*sXX0~N>@Pٍs1opGK臉&(oR m޾T&J7j>cD.D^v@uϛ Hb"v vԹľ\"UF\rjT>I7c:^Գ "’&YGMNHgG0j"+7+@[xkBCe 8@ T~rݳض=>s.{a{d!tCIӴ ]G̞?v`YfCr}㥛I2b7G1N$ 9(03V wU*v~=ziL 24ibi–9r@Aw=~ %)wfBTV9O G$| &ˑ0e+BK[9RW WmBb׾u @"vCIt^X-XN}3v*UqR l'zBZ2pBגIY텛i|5o;Cz%rr/O'`sQFxG-}rջ$Nv W*֨eYiXW'S3^:倜%cH_3IZvF݌\H%_Vf^#H&L3϶XǾT j\_#@ T|};  \>],k@tsS[2.D.Qv9n4!ZO.c@e̅UZ^G<'XeI,k*w]DlfR[@:(*U#4+t_֨v,ȏ/Q!vu5 _S.G!PZY ֆ/t(_" 7|e?CjGCݼ{"0 P/o@Pe'N7΁$@ (z-&IWj[)fsEߴ^*ݰ+EȜTѿc@aO =!$:TvԺY2K\l\"ײsrd.?b)C.F,; 9sR4gLMZZ}bU:ĮQH+xL@:)w9HI¾.C]4)s>ˤ=v hI_(zBպ9b{;-IgC[jB+f0խ&}-1G@ ~m<[^vR)%Bfơ}{B%$Z b$@KO*\C zY]ĥJS㭘5d2YOȳIf ^gU>X.(Ovnխ3Q #k}ٝT`D!xB"Iʔ$s ko!e<i4 IƁ.t5W )BZ+ >†_ yWO|)= qUrrdlP1V<4^Ga>@PJ\re8$@ (1zۻ/=ɷ^ӓ/e3P9\r`d$(pvʢ*]ÉFԪ69Ec1UQ&X+EYϐFkXBGUIosr됹4K~>Yrzpz‰32\r6!|.Euw7\{kאƏϑF(O&c]i_Y kX-iKU>-N-lF/2,(, )H֍Z6 |ZjܕA%{ /:ҫ APRg$W!طOrJH?5FnprDRLB4/Skm`Ǖ+m.L~=?7[pZx܅>5IR:"ζ8c%vV(_*uӵ̼yg}{O+}_U&N)|[KBX+^Zlfb1Į33%p>F&!(F3 C lXuVȏ,F}? R|.Un9*N{'{dqD @ 59g{)`(xlnOnRxK7j +Z)#)~oTVmֶ k]/bUF_C±j &9!:k p H_Kj Ըi&=\SR^R:QCD9vľZR}rC޻6Z&$5]>Iܑx`C#ү¨uK0MPYq[~Ֆ  H^ɾ>rqvshV5>Qz}(PՒ>{qwYB*DBWokBkKZZ:ډ֖ucP_BCB}] u)+)Ԙ"U&![oњȕRP9m@,JMH&v9 ]em.n <'o<c^dIv)9HEns3tܹԓDd-tB'3+s1|6 t2ۍA@&P[[;AhP?xpccK\ >nI*L/d.bWgXoh_ڴV\x X[0qhͳ^(!;;"'IL[_JzJAYib[cbΑ@ * 5g7M,0r @ =Pr׫R_n{) {$b8N Qo%Ϻ8d$G#(;9Hy5C1c͊XbniEJJ%t6 trIdSGi%|4[1zLVφ}1 ] 2, DieǚYYV%9 P* rx k.9mO&yIi 3aT)21! ƹ;תCV 6Gh|6n!o` k_LVLW ]4;cFo>K$Bv?$? 21B# I$9Z\8{ M8/^hz*z=t|މ_݀իaU!j-i%t) tUTkݸSOhF r9xl޹腯%mdX'Pillr&xc͠K޻@ OeVvNٱayvw%} gᇛ{[=OQɾ崋((@ | ~˗:p X' @"A[zՒ$/rl%Y/D)XP]B]e.M;V˙*] Tps9ȋxmzxGZ*[P)@_܁w¸Q_'+v9 MŦ .AZ kHިb(H}[XKsDinR4XW'sԵHuk|.oCE,B|kL4oCrk6-#Ŵ`\_WҸX\cA9qեw>qP$H@P!aJ'rLU{֋Gtn^a7Q*]G ǎ%Ʃt_}m˖V,۶$mJ$IB85$nC#aԤ4; <}]][A+Nj=iO`p Y\,|joU$%vahl<.5>$s.k] q@4u7~qBk7"? @yr≠V Ap]ϿH֦$P@P!DiXD9Tlz`ׇ|վMT;ְa.&e=i,Y˗mD*X*D]pdջZ!:ס^?%F}Q҉M}{%FC Hw1dX?E nC;Y]e j2"e2LkPa{?Fˮ-Eep \Rx [JpJeطrnm3z~m47w`8ĩ8؉HpO:gh|S$H@PA) Zw JgeSS6lcx^o#^9*݀ ^v, ]P,T}R>0v H)Gر4V#CD46 FKs;֭فή ~!K֭. ވ"ٍ'qlUCVZVzhS0:^$ iZt:Ld'̱NQ!ru=M|E}u3p:ZFhdiT,q,eKrĦI~m0w+2oតb CND T }z7/cB JSV8᭛kdEI<{z}y@br38$K 8̠eCyZ)UXrL! qɸϲ0\E@SS ƌQPSkx!t$ncMj0ilҊ͛Ά +w0{61\+>OI쐻&bq|ycƧ=҄CVl҄RN \$$_3QhS(.&NǃSY#ܓNJN`(gA%+/˓,XINL;p[Q,xi-=># w#"py'q)$@ 0i V5jLkJn-ӽBױMx곓 pfuT}&h;xw~#I!IT;tX=&L!Cjճ]2C>W*Aa1hp ֭فJרOMNlaFx51jt̚%ʹ+qɒ M}KEiZ'Lk.ZdsAt7j]Vz$9j 炃2t{-yS,W~WjZH"ZQm/o?vmmkߍZqoy?>rG"ʊ V$U[Iq\S9#-wUBb0jPM sfm[[}v JWuOSS 6G÷p .YrDhkE5iXv;ۻB JLcf ވT*PFz+; ]-5C/%m(Ji UpakZWJj]$MEI16%k*9뒷 I PBn5^YT^_2ޓ f`ϽG⠃K`Ay>YqO${IK!hKSTs[8^/K;Iɬ`; A;ֶoB[k; Jג WPݩ Қd d^}\jt oecظm6Z ӌM1pP-k38&zHaٺ}k"UeCƯ* D=UłQip y ZCy&;tk$q N'[T0˕[ke+s#ncU9+ f:sOŐ UK */\[J.h @ T(ΉԞ1UCTŶ^< a{v8oufmmfFl n&]C6<om!:ŌAa~d{I)ϋJk]*dL5񝷶+ᄑ}:(Jt5N,3%P@PRLWd=T`,* M+)8:7UnjdJ#h3t o'㯫-@z!T?m_j<`?!w TD@J0m7~ ]8*]m`PX Ǵ~ȍ_ZJ oĺb5b tveS+B]C u)z5Z?]%؅M&S/b66 V1jŞf4窱9X2\VX!Z0sɟm6@e4 AkkoX1ke[vtuJC&{3i;YAi]1)*b$pX"8V!bR"VolcYe]0 U#Zۨo)[ _ݞ]׻OVcT.UI_ Ve}ooD[[W^8pm>t\zڅ;~3qܡ\^%l|, A2lzw* [yWÆ-9jjR5w?|Vn&O!u˗mƳsV|T.9Y'hE:QFDd>q&msal8<0am`X%bk_QIȿJo5$+1;>Nyڃw =O9[ҫŴ}Fx_%|􃡔n⡽ ]=`I(2Bnͅ^jbَ֮~>۩ɖV\}SؾrMw:s?05K"njWs| [Chy鴯M) Є%]k$L[$x~}].mpBCh2 ^ȨvJ5Z'r5ŪI̚Gkm41lwʽ'?v0'Oꊷny筭x7*w)h/cev}@ @ T u wzº-6{; {O}A>֖N8-[\$Ztӄs.<MMu]ADP;K IDAT Qsu+%\!B=' D;:x?r\ScASc ^ۄ_eY;$L ;ӆ0n`fJR8q'cF:#8 Į ^B ͐ q 4ę>>GuM`H,$eV3Y߾ $ҹX.,{c3N:XjGN: xs伏up߃spbo'@ (Z[;kI,?#P#*@MޤOo>*/c_o C뛰c[}w7Jz$|#c mo 5676˞B[k@\/8 C\7] ֬nu2ώϪkj^z˰}kkE0;1@hz68o*Q)\,R+5 1;;B`Z0DىZV@z(Qjn!ua$"fV"-i7 q8o┶֊A@|lA梎fiPj_Ǜo3'B?0vKJ%<o Sw._-Aq/bز gI 0RWgn|+!$i//)?;:p5OQ %'zR81z٧Ws & !\;?m"!{L(%37[φ '){ %.Ҽpmi[o,݄ˍg|g{X]o~ M,=K+@ (8vO{6KFM@ AWlQYL,]4x6.`Ȑ|#{& qُ`k2<nylXߖ!P_# _)S+[8:>yQǥ7^6@.ـm( C(i`LG8q\݈ϫpe H;:BC{vIi%\!CdobǺeNs!Һg^MΜ5m((F v„Kx.6)f\P< ҫ_m#N:X:;;iPSǿ|,Lw:'{[RAq/`زŇ?I 5[n?.ݐoЂ_:<®ysW&_' {N0Rlݿr\{ 濴e]SC8eK;ntsFg>G#W0qqz(3ܽ7)غ9N2e0v}xƸ 2Vw5Դ]CF":kXm=lJ!x;;Pڠΰȴa`NP&'YZ2lߒ=F!\\2QhӔR@ 9ʮ}ޡ҉_\-0xH=QXF|;?N?P|CP__oo|@/f<8s].֭m/h-zA o$FKg@}r\Z^z\ullڞqܕ0i0,Y79lXl 1xzWK*_AkKWz:~mgp{WPҲ}x9^@p݈s9wE@q*{k 5^aED =&ٱI\K&xD|e'^pz^tMįPbTQ^9= l8cJwzx7w^xn,^k"n8ò>~/(֯k>笄g*8yhQ2u8 xw2ӘJyD4@Pmk{lّLıM AJjˣ--7>.&`ljwƣHL<FФ'{1ֵ{i<={Eb~s&qq@7ͼWuQnDu8 ~O\2qtg 1 LB2΢Įm(saFy& HWD(ͶkBI2ն&0rrN͠bԋ&y[\Pd;mGIɗ,XzVWش*vlئ:^Y?8yXcN,BGG_}X:^,Z3)ُ-@ (6mlŭ7X~UH Qa$\+GeW/㾻$|7 m]ߴE aтu~}gXMZQ'N8q ;CN~ỉ-X:g>2-;jgF1R/ A2B*?])l:M*EH6Ϋ;6!tƍg,!|MyT 9^EL ս,$M)vssώbBrW_Y{ZG\˷˟\{,=p$H@P( [r,e +T]es_E%fG/w-k6$[:q7<{5Iy~& Xs~ɤn6E@ 7_߄o{1vA.( @ T)(QZx!|^>>2vU \.:{= &EX V؎~">s*w̜5{3 c ĸVaf*󳶗JYQ=]9\.b=xw`Ztuz1>3Cs,h>t}<1Ahvس>;]ӾC47*ؑ o7 s {LQ[Ў4n,&V4ǽoJ=& \pS$8zHGRǒ,Ly,DiDv<ϋ0RJ1Hi|:(p{A݅>W.EQ6$^StD|I.)nm9 !U ٓޫ{ߛukwsǫ7w{d|K30u Ryر+q֖.w7giڿп4kbcpq RZ)FKK'.k||C (_$IYg}r/pX45Յ^[wf>9a׋>N]5'ENW/wsY9>.h(o~]b6nlx=]97Œ:))&^du6'lE< 46Ԡ^9elV@˚?Wrtii5op0adA$(r];㫉L 3'Q8oq]sl})=]~x9պ:qU TO|zoN㛲~*{Hwɏν7Z?PhQlВh츁2GGbep‰S%H@ ]Mi9@`z.W%WS_b_UԾ=k뻭xfΊGj 7<ߋ$)8kg0I"eʱ̍鮒NF_9_ȗ(݆̞֢JQi鐹m&7[Y} 6ss59Z:yqD.cvTenGDVg){?nCض=}4s_{)qaةoISW<{NK4qC }hy>RH| _LN|ٖ2H/zի럋-kh׿W$}9z⋽!nַwbkp}KoLQcv *t/a=cҫv2Ep?@0 lڎoMlz1jBDD*Կr6l2R*Jk REPX-!rVC܆ԺdQúd4~X{p&(S<ݲHݐ/pƤ [զ \J/_jkmoSO夶VOy4p3^Bſi?q ׿x gYb^{%W[1}+ {1eBA޸'o J@t5zOގGZ E|u+ꌹϝ9k'=>Oݿ4/֖.z 8ң*=^LsS5/Is$k0mH߳-\=6q`XzqmT9iB3NfE))]?̴a`/9,[)VZ׵Z tU]u(w1G~P aA2D) ' {{F|1Q^ص|%ٌ \lrHk9*lŭu-C0&Kc}΁Agm[TuTȶ]cQ:30W"p`0 ļWwS;;3g/}f|[s'suuyNK:{O]Q#_f<;j9m /-I&}9/T \.U,}h9ny.Z;BKdcM;oo6 *]㟚6[񣫟FW׳[J+gQ=Auŭ7͍-d& 9xi^&9Fc&eJ ݿsfIr4@ 蛐bA\,::p-4^]]νH XVqbkƦɉQ9DT%.pc\w<[Yy=SZ[!ѻHNq+ns$r q/bv.?PI&} r#.ÂTwgJFMto2,AKZDJ9vP4m2ؾ pս4egS1oY܍0' PmKrG^'#Ld\Fwk76ۏ lVΏ n]|BQsH ~~ gdpuLJ,{`л׿x)+O셓Nޣ"G>w_H]@6ojŵW̉:qI (T1h ?r>8q4y( oIJzo~jj|[JiO|bqmi˷fiw, ğgԢ lT[u!CÆjU7GK7 r&U`_ȅQF̵޻DrјHtaEa-kƂD:3P(*D IDATBpّnY>=Jbymm Wp>wA",Y/[O|zfkh/S˚ߜ^Tk[_GaҔJzd)H,3XX4m|8y mMp.Kv4 C2 &b،mW2OZ39޾A1M&6Qt Ճ1`[[Ǩ]dD!9׼/Ev.%,pϼ6ㆫM^\t8%פɟ/Vn3ض=O*rkbzA 7n[&M |vHbh:yֶH~tqL->c4>r^ݶɸGa[70l㆖>>C]sSxxT#^,^>,A%HlYM%A~qMeolE<?~ 2wYQ=4䴜ZKs7nZ9+QW—wPDPlmYI;fiC9Xz֯kްKވI~pX){ӎڕ$dVEIoAf;{ƚ@0;޳~e2Vw>Y}LL =zhT:`"JQ}UL (5Q^$a[J﫜Thfw~b /ؐPonn&.f4xU'c':<89y!u}|S.?OϿ#G GOW d~!͏+/]I RՅn?x͝ g54Fkc{cřk/˶dco#T_ٳ\R6/MlS3|$c s$Cd$N/d]ZRT$m~!0{H.ҕ*1d+&Yq0]2?\&QDZ |:z$3|&J ҼMTg$%C*'ǝ2Nfg;lk)$ m IXHvm3lv.1pƹUD_fm1TkNO!Wh;;ӸO?z^H 'bkpK orX78u8GuK`y8MMHwy%֭mX2gp1+\/@G`¤}z^21W ;:kbî'TMdFA``wԥ*lNJ6BX0r)H,f ݺIɔU()nI[X?h6 7DjژiDl~#5^f|^V ݬW>ѷ?=qų}[G\pT[͛[k}y`ՉW_\V+J㟞@ Ȇ~&;VuP H RH^xߺ'~❒p+btx46U?8yPzsOm7υz9GЄ…oAـ%Mp(7IQYx$/iZ(r֊ u- L³ !]{pux٪X ـj\oȵ>gSʯYBW{2pM=T@j.` sCdh>Z UݬldKJXcS}6T*r+xdS?3bysRw_rkiĕN,?}S/Li'A +Wl7<[6tX{!$@ Gnk~W͙z` Wdq<{1{5ǃ ǘ+]|*^/5ǩ#P<22ƩռׯQ2䝏ǘb|ZL6{鑣% ̨uk={Jꐐ4Pj".R*xZkl( {Y[1XR\]Y"]UOIZ&!5ov @iLaŮCVSJhn4Cƨt8VIm3^WPN9֍;oKs:>#yk+~8p>}*ϛ6+7gکOG~ ae)\Ux7nh~3EN0+_Z[bN!2A$}BX1[fhhATXL\lKg*k1}Ƙ^!Cp΅Gbn4o~Ut~aɢhmIވ;c4jjSkTj]K|굨RM:F \&[!NaTXbil֗DOCE@R#R #dW, ]Ds$DmPz±È(pY+z}nWҶń Z.G^ʈ1FN$r'%ϳ_֖ Pj0UB  decZ'a]d5 -m(K3<_ 1Į]8`%U%Kamz FUתrlbվ ^xfZR_ )jm!ȍS(pUA3ƠR>㨏U}bj` u ^(& KbYK\}Shn'GigZdy/ pbZ @ 3Wҷzn{5}.%c -i&\pQ9^m#l6nn>G&xҶnE`%yS{,oH:N"9xWd zӒJYbv_MiMt !vQdfչt&j`[TkQoVi ճ6 d.E4kfW v I.)MtDt7*\_*]? rFV7#1ZXN:!W5vWuYHJom~3?YVn +P9kqǯˎu>/\/ϵR@+^3sVĖMm>}%H@!J]A֖]w,?y?xP1M8#K%11cESOo|!CqGb飺mo'fՎޟ79QՂϯ0] TY;%Qk6^p\Y(M sυ"1 HNu5ޱbp%t6a8DCL4_@"WDjaU2dn`&XMZlRJ'szl60Bڨ5ikUq*]Iz+1Z Nl h]mL뮚.6@|;Ukb8 s_1buwݱ(Cݣ*#AyёE>X~eGF AD Ij#</}>hi,kŰa}5 |䔽r^hm{jp!힛6˞›o.ssURb͚f`:844պQKy_Y2jQ`2sƧ!]ϱH %vaI2V ݆,1MFQmX"z:̙?7c`չ._]?Z5>6*pl>U*_lɕ%+C#[%}sܟwq!XI&{ [S-kڈ~=&<[x?˯{T右w&>}ܑDٻ8)^;ѥ#)*5v-I؍-1F%XK4֨Q)AJ?:\m3λݽ]{wwyy qC2m.8匁z4444Rcߨz|7M,uav8~8gQԹeذ^$L;wi#[o˖('3!f0ՕѶm>x]ļpsߍ]l\iv"M0Z5uDHz1\R]&Km3Lb~AC!vA 1H`0撴a~l)s,>&.OmrVuLB@uܿ&}=l`-zRuiab!s91D.!> DN8]a/eakr+f)-ҹxf'oNK~Mp=  v1 Z(=5`´yGRWcpNŝL͚MZᏻS97:$ $Qff1<|||:gi?{4Z`[qkqTOe-[磱P 'KW; PMpr?os #|TD`$BFR]yllh*:$.cKf~LMO段ce"!!3M-0mea&ff(@ 0FA4YVWmb/Q5='Lpո,3&̱t-3PE8Ie=a:.12O6W(L(,%i!}DRFjcUEZ vԊ)z{_~$5'7n;0IӽM^}ڡ 󛾵fݚپ_6}ϊ%Xd:tPb=x_~בz4444ra\QIq΃3Z`*v×ԩBqqkwoA IڲJK+- d-￳gL̎.@C}嵸᜵`g%f5e.kaBV8.3xIvms`Y#%jK6mI&,Ii@m MWò0`ʍq*eK+L;+qn4~ fPKl^ t:.AKܠoZ[.I9+DO|jv)g |ȣe݋%/5{~<4߮nŭj❘FeZyP6OՁ"C![;5Lq9"+ R51[ j{98ڪT*|Ue*[ 1}j]p>Xi!s,Z 1ϏB%!%Ʉ5~:/lH#s>ssI~l_;Lq"^3CKv7@ʒ"þNS}C;-=XG,k*kn=8|ߴAR/_c߾zeZ NUb$Z;  r\:v.f@W3%D֬*Ŧ¹Ï쉇?AgwhGgw5jM2=NZ\onЪU%;wm?1ZrrLkJKk\< xUGQ8fEtQ΂;`D!Q^; tĮIZMJm汝fpemRҐ?xu]^WB(@B4 IDATzpg+82{1Zĵ8#Mmת۱AMBB Z&N;5 ]ôoj6 wXkBIK2Y/) HK48k ^E[3ĆuߍEaa _5XHmLrͪR?_/N-y{2-o]/<VQq-I0)ţ7@@z/V)٩s+qȏ9KpزysuH.gC^"mW sZd,M$ ]fJP7%Cqm \{ UIlRH~!}ֳf47ree-^|f2-7&mL~uٛ)sܔ=JkK}DCCC{jimeFnfn&poCEE-xuoAGGέ<1[͛Hyѕ{wŭS+p¡`8#7k5Սx`||ݎDHSFbk;,~ۑS{EE\zJq-BG2?׶1pi N*x$@% r:~̰9V6+>8>/BV޸p gBxTSX!z2 B5&28~.v *^*J7S=HRs܌P/Gk㹧Zz%ѹk?OnuV,'Qh{/nd5PS/BMM2m1ށhhhxB?\;p3 8K㦀5CL ﳿ܈GX{-s[g;b!Ҭu#lt:lY-+qbtJ?ү}uθGtжFO=g;S Wi{ L'ֹ%v/h47In۠Wv3\2ͶapRd!¸v.3b֐#s,5 `s$aXĮ[ti P=4@)e`CkT%&oʤ&`z{ @8 w7 Х[S^[S{ 0j4_}P⶛f^'ѽGc$ihhhh=XԬLƇ:ZeZ1ar?TO>PӧCǂjj2Cz텩c  ɧ AJQz7x={&ulrk­wNIR͕߹y N[0yGq6xe0 .}BpNTU-;TѶ|lKzպ9S2utof)T)5YHH\Ƒ}"+fLb~cF"Q8wh+I]˘Iז٧ 죏gջkX쭸{k}PGb*eZmpM$ihhhh"NR7`e&"n[L߿ꆀLTsB:o_=+|:_WW^X2uMQڌܗN#0bT爽+/ŃcJ\R*ա:ʰgwҵ=渾+]"I\vb:"v[5I\д][yꐻ( Pdĩ̅j*[Ux&e6m$\^k WY"3F5W*SםpDt#?5͏h"1~4n6IKޟgQ6xh:W'^Nƙ ΐ{T}{%oy&}~<#Ux䄠tO5>7O44444"4{ M'[۫*#[4LYiwAAN fId2m K^j,~rR?A-kXMT7cƦ&n#JZc"*eϪ&+wAv D |KPru۟E:X J%fmKJ-[7/<bv(up6x!MUC%Q µa|]nf>7LJlu~NKOȍuH[ Kt}'6RfK֕c=mB7l?4=<~h>oa̝FzObz,^_Dֱ\>B8444<ίQUUL;8Az44444ܑƳiVo‚84Anjr3jVh./cF_^V+@i+>Q~5s3ݖdK;Vd櫩٧` QֲZ,۶sY*#V\"+IuxU|~^2@TR[j+VusAc#-pHaNAKC&KPfiQ;_Nޣ#gy?_Gj)} c Yw0϶[`G/# Z쵑DB^rV zĽ˫tUhD$yI &O7IPO>k pO`KuMx927XԽ!v ߜ٨ҽ5xj\?Dkhh,X qsGfp/sRr2E1!j>0fq`Mպ00|l0f ֱaKkΪyĜHSh!.H/xb`C~)ϓ !eƿ$4k=7&iض v_6bԕ{I\٧YjjnXR$mw;ʴ.8+k[u풸2>+r?`.خLɉ`خY5O>Z97+Z/wY4tp4 @R$A#??q1f\w/<=nXd K.3=4,s W]1J}  <2;Kv DP~|Ɇcյbд]?`ͪRN=Nh&WWKu;$"G9;GMFB Ije!7֮Key^-}^^ f*n9%U6pF~SIYQ3'gUC-#(h%B^7g#5 ӓ ]W.(TOGs9rṧs'7pCѡC~V0epR>aPuW7ݖ]*ݦ&ҽ7Ѷm>4444x, Yܽ5y$ TJ3=C6Am [fY2xsq% 32upm𑝣;wVH׉Wָ#УWll >Zr3?ZU-\k0+X*{r 9@ yR 1Cbcl$9M۲Q,3( Y޺b4{ {!n. xm7.C%r "sϑy~#aӖBUʊHA xm3 F-)E4$}>Q_s ^%]N.~}=s3֭)WکsKqfkb&lRōE'$2ߩ{^w+NY%Y5Jia\qz44444bFnv?F}LA!19[|cy4 TVV9R=0nB7A5.O=[6Mj8ڵõ7N°%`]*LQQ(**tmOjaՏؕ_IiDD)L$^ Fg$`Dt%- ;&^V2E$qr}彂Қ'yqǰ2^BA1,+%R1Ro:%u&L $|~oF#76C_72^y~o ϠԷh޻xYuXUU{:QԩihhhX0Oȩ:8F|H~!9q6"= 6[A9guػ.MJMR%#rrh}TWAj?+/55okguzc~pLb0 +P76ZY[`410gnI!i%cyŭSB"p~5]K˩uaPnV^ۊH ^Aͬ@jږ'fa"mB$yC2V -b!vm52u@t꬝@G%t$=_'y5wܱZ] U]$ʵK@xߧf߇겟|;M:G+k /܉+(ӊZi5!i]^[uk?| }B&3}{W2-5.CCCC@c;47Lѓhje@D0f\7iƉ1c,i&/F-{"KpJ~~ymV㾻砢65WQpCq}TVZ}x4aܭq^>Ű]2*$U<]q|ec. ?"68S&^˓Er Mr>c.됵F#Z ʿBi@i+xv][S1˫{c${I]K< @H V(BZeh`?ӥM%FR^=>s<^t??ps872棩I=lSnVZ>!ѳmӋa^&iɣq0X =u|gqz74/KZlJw,a\wd Z1ߞո뎯ycEv)0z\gu(+UEUIys `a,s$b&E)I>H>|Y":SmuD18^0cB5_¨I2˚HY]UD:ĭ*ݶPշ=sR"kPsq+R;(]%Ľ^KAF?E>ZWu/ 6B~*yu3wv 4ĆuVJAgL5 Am[+mN=sUwTw155#M; UUuί}o=IP( IDATNSV5q.ۃLKJ<|g|G i n^^NT ?MKP+̙%ЍED.N<1k +i$369g6WDxSDm  wxd!J(~r!5$ jl6;u3O=E .:(&Lt}iƈ)4%d ذnOm `Eb0L:&\+0PfA>n̿}_! Q\_[A0)I" ,++a+9J&&q+bm/Z8,yVa?2i B' IJ~.F#S-M#y#9K?۫i'uDŽI=2~D__^&I @-ڨ(ӏ/46B]*/>ۀ_lM?匁1]hhhxogp A eL|c<{+0轵lYқPQ@s*/¢UV_O|5JW$@֗{V6^Yer,KQԩo/RK󦉊]` hmCP9jWފD A: q͈re–nK E+@"&[ DQ*2KeyZO:Q( 5/SEgQ"*]1 %:RAW?K-ao! ͥq8F_Y-z\J7<|l`cpֹC0ppam7MnH};!O8z\uL/l(ú5e(/cזg!q0v|1rris֦O3洑GЦm>ã֝&ض !Sz: qU;{:}搭048ըK=R˚`W$X7+Q2啧/e2VU֒EuMdα\WBa ǷCdk (r1OR%|2"oc tL4m9"|t!"_D Rs_S*x~8A(2{?ᄉڱ6q}ѣWfkz]3<\"2^y~)V.~#qHfSCCC.@UZ|qҩ0ldg=I #IR7 ozcfzmЦm|Q>ʼ͡ti`dhld¾Ca8ւAޘү#SW^XCPlX_ x7.DЮ#1ݻjڋK;BvخQaW-Rd}J6T8O뛄0C^H.{҂%v &bUSZ-QX(c!jթ|?ߌ$$U5(vX\9M$GD F *.oTB*Ω]9!gv!|3}_K=z B8!1MUű[M)Cpч森 N;o tjy,-rp}|H=JTGkFHM2"Kӧ onptIݰ\ݫof414zW;v,HzIrrC#Q[Ӏ j]z#f} B Z[qkQ凑C}ش u99OO F%\fa9;rl̰' "(trHqLTsĬw=mr^SW.W`^UEQ۲ ^`d%2WrQe**ߨeQ=yURҍn !:Ln|NeکgBg]= wG>ͅ-⍗W8n6tͯko=LRxn4ů;^B7*W֜A71c /$rױم"XtE"'" DD مf^pp*ylŃ:N"444<ضu/OX  W7]$j|u}{?;rsCN;9IR +j}%ݽ<0%w[:#??pN0AnN0AN}"& !7̗&!7Ӫu.Bab4T`b{-`ƴbR7/b܄>b`N*; f.c \Jg̵6 ̅5K䮰LU:_wL:s_^Um.E*Y2kwAMĵLV D+Ss t_P4.Ne$HXTCƈH Z_wXuO69L;T4(\ܽ '5 i lǬ/7sGP\sĬXӽ{K?,$xܫE{梾IvֹC0`PG=I! R7}kB[6! |Ȥ=c1#QcorrHJŻPSm~mr0f\7:DQQ @8̩Y eѭ+Lrɠa!v`(Adݲ*\/ / 4ռ `So3&y d.8O]uV^Uc4F_תn2MO y%V.OH>dSEdun$ ]]i8G#WRЦm.N9cPʕl(HT-|e#@C$ -1os=z͊+}~XHCCC-+sKwhFԵ}ul6}fTVIܼ=) 㺌M5۫k+t߶M\ &tࡅD#ǣ^NNݼس r8b<"ybSIr c.U\xx)k$"W:Zm*Z`FS:sC_&RU|H~b[u]Е@) H,rTt z A Y26*>o(%I%aG/|(T<zIglĢ;<)rsCct*rӧ ¥6K tΆACL;7$ @t,-xQ~5s3jk>y$4X &!Oaln % L;o(NQ6CM*sе3!ti8ZZ6tcogW ڴÉ  9~@06_<9c#2p=s= WBq6?۪p=SsPbSI^}a2-"z44444G8jѼ2Xʧ*b<|=K8. t\m0GZ7Ӷ]>N;sH mO79Xl|CEֹI3}ʊZezNų6mACCCF E~$ihhhh6 B&R>]mjۯDYi+jEnH݀6NqZ0֊7Gn+˱{Ws9SzWBN 4Vn$o$矖f{L [bȡQM0\2IWE.rT.@2' ÌJvLUu9n$U`1_J+E4T*]%sG"Zr*B:׵ 2y/lpX DZ>:cKb.(vMbxv蘏NnMo MM ~ׇpíбEƏ||55hhh(a]9^Im \U)B@.jDeRkQUU7(+ҿ[0T79DB(ͭ'Q ͛z Z_v ¡x*HTeXNalȩ=s,GF'vWI!v$wTÄXd|Nj_ۆd`v ? i`"^ ^x"2o nnX) z. Cf>Ӌ\ڴ!''4^D~]MO˶mpCDϿWa è¢6qc pRFa]_0]< ӓ:T), VWzrunLV,7J7boE;l.:;/hRMFe܃ }O -r2z 7s3'݂/֯-[T4IOFDIGH֋}uk듏Zxwk|)ơEAJrĨ~V#\պc;gg~ЪUCs C0k͏ zf>V6 5 nD+ovy~ UzU~ Z 7Q ?,W,8EU^.Dx~Z)Sy~2=G: i,/7u߸vb P*d|4gnFɆ BQ8~'Y:;TWE8'2xk|12w.J֗duTLC444|oɡVt54444Rp5lr3ID0xg%Mco~7hƌ /nc0 GX5+Z;Q'c V[@8&UWdnyYlFF_n׬w\3?m1=@5bPz^VOy."/:%UCڄ mZ2nYO% axu=4*7n2DEdu.ח늭Mz#߱ϪSў3 x*@dqo:=XUg/6ӏ{;aq}cKZQqҩ3tO5ٛ(SGh] xԤѳ$ "`R%)ZHM?8X ]th@[S ]ektsk}{6H>Yrk}۶úe{Ա}bZ%omVӼ*bM >Z#-:Z׌S SO04;/Ǔ @y rq~UAD"Vt.cAk$J7{ܵW_7jR dvlR~|uǝ/[/\\AAnȃq_UzloMOؾ6Ɔuy&O9^444"bֽx vn'ICCCC#8AIU]8L1͛*쓮1jL$`泶ļ]Bւh$"|(/6UKӦm>F'Ҝ(4;qĢVUиCꗇ*cH< hnDE(`̍t%VsQ7},\SS3z ~Ƙ"h8ҜDggNv 6k[Ѝ~MG7TGknpK&νhhY,c w>{+}\I(&O_`qǞM蝑7ˋǷsH;9D CCL;CѳVjhhhh)0N8Dp KWCCCC#=Hw8Mf(`(ۏ}^X? եK~ ְFhf$;ҵCnT&#&J^okB!ç^rW"5}+GRO*+jS^CpDH\ h!~*\V%IL[Sj\čM̕B~DP+Ѝ*XI߃Ekbz ;?< 4[@ؿ6+Ǔ.kVtO?-z{s3fG?] ^Wg`m 1o@6 &lqqTT+ /^^'x)(<6$Px.u [ )u \YxW TO$u|-D["?!Pc%tcэ+D[?`߾-n=czXob?T]P׈;n| "ީh:/{̿ڹc^&ɸ~j/"cqt/z {vW㹧)7jFg_TכM;a0`3O~q^G$I[ `=йKKkg xM++A7ȋh'%Դn7ʖX(8TN*WLc$hɔGVr>e0Oڈ?%*0 6 P__F.misg|^_^{/~3bhhhĄZIBg;}ד6 H&(6#1 Eƒ c=[<1/HZbj]JN9}je)J6Tp-4-$Xprڭ5zi<~^@,ĮptVHHQ}JD꼜ÌP"Ga=c$3Dܪ\"~dϜuZn.Iڏ뗷mҥҍ_++wm1^I|''onśL:;ι`h@"ṻyc%JeZƂeJS}DN8~XЈ ߩ? pMZ^P*)\`iQςݷ]5UNN_< ݊89*ZZ)H?h>U~&AR#εO†M,q%Q gOz*w'͍Kǡ \ee}oΎE-q˝SEΦO桩dcWEֹ2WsLϿ~ 즡?j5'+8{H;©:@}L9X7?LqlXk0سsfo  < mlp\|Hи6ܘjjkEg SxE'p-8h.//r߽eX! c+y?ڣ| m2v~'◥N5wptIi!шrHeԭZ "dDo3)Eɒ/15b e+@d%*bv @o"m7BK_ͧ}hH?9@ZCcƶ'sj9mN{F۶)'I8q ֬.ŇQu |$gy /}&^l*W37۱pvb73mcu57NBnk:߀Jw^ #ڪ0H'VS׿h}%ؿmWƑS{WVCud*bU Լ֑S{1᫙GX;J>FZEp3}ۡSElĮ{D 06Z.Q)|'weҘ+琻K}1H\""*TEDhb9u@E|Ω7?O` li@9L:=Yq^95祗쎿m\||5spMz4Fd2Us?f+Qg3ĪIݿ6 37b{ТEfjhhDFee->xg5~|5s(&__Y'N8__^~KWCCCCyN}MH6?IN `Ժk U{]"Dq]GE<03hm'0an{aC%mt0[Qk\6bu5x]˖C =O#~PqN?HbP_1(A2~T2IɫsUi,&6v!ɪtW܃sN}ٯF%xg$w*\ٻ(.zfKzJ ޫ"J,A{A)ҋR*RIocw-gvws~޻3wΥ3UUwůK*נr(P@Gp1H E9W1i>dgcy 4n5ZuVB bzV/TY Go^&}lox.Ah{cF`! O27 L}}'[=;o&t: h>}Z*L x .&u <Xʓ)J@^) Lj!"﷭ʀ lgWHj+*?q F79wVOE~2b(j$,.IEBґT }LM{v#)4\IW.R}8R&˙UtǛI)\6mJ=a8U edhҽt b&SFT^HokzO92IK_{!Z5'ԯf-:CVHFD3oX Ap(P oGв2l>b$8ۯZ~)yeu뇡U@ <70Z5,'"K8Ao4V*^`f?M&JKCay= h٪˱4A_7;SSm$HEf}8'N#r-J09 VBJxfV;ef(NLhl2_Ins$UCRƈv.]])]!ux$(Wj$cnP!2o3H\H q%o=oqRԶʡC*152?__݆2ծ{Ti_(B$k8&"|j Ue{{~/a#0F,KބʁS@H]5CM(9On JxJ&M´o82u6|Ao16l>,Y0bɞ?ʏz`!uǕeJ͜ݗ("re+"(dNKBEMZT)Krvh2&*dۥ繊AFPD됌$sc#+kbut'@8qJVc 9(lc =5E4B%4l)YFyC?>J|s?]Gv5jƎ}xJg؇3{{ѣOu2.ooMה\܈KErRrstӣf2M~QF 3>yOo>;օ@ m' 9eezEE xuwq6:6M QCq&jt3u[LYB0Z'ManQƁ.Zw1k=zĮy-K!-3\>*8|MfU d*䋉bY =9eʵK4$fiK\]>uܯ$nUSyFFJvذ&j~~ZEu}%q7ROnUд51}?>҅DF*Bc0 o cub&Tޝ Y,<}`yca˦X [AFvuAJ Q/>A>ĭiqJk܇-)=\?W=@nUбKeԬZ |ҟZt2V`l#)1;C,YplfR+l ((t7?R4ѯ`(@H)ol!=㭖8HkᴍIԾKZ 6&44ham99z\M [~1pkn_nq;@KPqn$cT+΄2l)rDwC/V1Bbq&q"8Qϟ̥+B<]>=.gSFz,ݩ=˭9/ jfgTVZ@RG>!# uNDl˭7I9k⮥2թ EDh4ش. z y.$b}X bcRN Y/cˈʣ~pk: o55P\s]#IF2a4jJﶗ,87ij5J{?oKnAp {>K&\"kQ8$c{K9OK9/R?@`M&A xn"uU6+f]AZ}d0 QA.:BѸI8T w_CzzaQe]CU;qg:ҐcDDeq-:(6J"}Kd!mdT*5ka]8m#D<3T+n9Zb ѵ.&T )a"o.d.۸os5#bW.!Xrk;I7bӺSK<;/cS#vAQ'@ꗐtI+6ksϠ7j)sA&܈{w2횷,RgRǏ ؼH7ѣS7 aeKNWljuģYx0 6_,W hm&y}4VR奆hBaB# :mmTRB|e062Y9/;d"1zYsgpb"7p*uyzF6@2V (<4JiB-0mmJuz|8}/1CrnԨc|Ek (6J0>t5K/'Gj5JHKb@ƞ%DC48CkO:ֵ%:Iaɞ IDAT|g[̑"iu&6c6P tY|\GWhu츉Ԕ<(ݲӿ&v-><ƴIPX`y0Hۻ eIoK]KfΈEOiT46JW% E'hשkmy rsuX,{FtT.⮥bPMupD Ϗw5P$rs՗Rz)(sNϏp`/ÏZLJo;ЈE,<k,Fq* (P@}|gqh&h HR W6>?Y"t5(_.B?#ÖM?QnĘpQ.##n|l#6m ,u  k"):sȈzd=Q{wFώX /;^y]$i] Z[93NеZt ^ م~lMէq&t_z]{V[NS/|0/_rF#u`FQfie2)P@Y.s.!A;bb$$ k'p#ZM@5|N}2TL&Wnk4ԮZ'I8q!XKtbF҆|(&vID1]2v JOZTEGI^6q|T{p U|Wq"\>)A:)B|!| {n׮[n +KgwMFuVV DI >|f ?f΄'#t7{Bj[&t8\O._ڂ淼Fi>w ΜzmVcܘ]1AU".]HĐ'(՜(J$bhߩG6HL=j۠q87+ @AhT:\T|=c˴~\L (P@6pZ-)%\! iXEye-oGV؟P?FNW,P7hI^z9 a&O$yr#$I.K/נrT6J1JRH%H>H [ ^&?%b,BD]I Ro?HH\G|'% yO1.KF #۷Qzo5dg0mA\L{>za Jze?ͧ^x&v HxÕ^oaʫ~ \ݸ &|uymD @Qh>UkF`+xx?Rq#.˗\GY:Xs]V/szoވG[3h0snWzIuܙcisc^@iW&:VV& ( L-s7X?ב+IA .+r?).Fd6z/5hkHԫ8e'ĮNg@̕ŵ-۠q]@:]k5~5oMI}*YV_*JI~ďk\qf&Fnp +˄.p{y50 Z1t;oH/έ4i1R*|]%Y^, 9R/.#{_ '(W3:aM{RbFێS'Y)o=zW/z# QUCU5=TǨ7㽱4ز)Da e7^;+m 2I7f+[&*̗k2D2&Hѧ䄳 (P HXZr`_g{wb3$ DV vGkyJu&˥FJj!)& =^eO\d1ѨI8kBgW*tn-6͇r5a;jadK,08t`}wN|."$%tI %u/ksݔ\er4pmnJr.>xg5k 5~Z $.wɦ8xk\3#u٭iv5+Kf]=}1:\ɛmٺVmK7ń) ]G-4ٍٱ^2PT?l#ѦZR8pub׉0LX\ݯ(P@YA.m_ߖTѺ{=̯h*z(B*ZKaPTU; W/'W\l*ڴ|׾6 2*UK;qkר]mm6 j ~:Mذ})HW#rEH/\*+W\/D` )O+N1*չcG !!\;I*0BD\kKHpqԔ|`/P&6qH?7\#+9V1㋏`dVrmMp^s᭑;) x8puٌYRbҟ0QժѨѪժѨ@  Fo [vZuB=r ,c"H/zEQ3{Wlڥ`6>DK?[R0|H~HR%IK]I:3=¿QF 0rL#suQc{4!ͤШY97ƋG(9ےQX@-MTCVHIŤa^XǠT1Mxc5NA= Ǝo*I)[ Rna'(ϟMOQfiY}[z EнW5TFLjj5ZuYժEo2Eį`hGJr.s$ıGmظm0ZW[)m^zoo,G}_?xK*B (4V ׂ֏v(w3oEj Ѻ^^* u_kNS^.6Z݈Kah q.Ñؽq= -Zw).8vҁ l#"oH^)}'9֗a&I\!@p\v&Sb4ǟoDXguD:Oq@.Q4zRIpҽq= S>܏L)i/j50Ǯhֲ*EkZ}'`Ӻh#xKz'ms|OYm Ś?^ aL$ƿnFS]R;1vq=Vuۖ8LVw-&\ƌE`G|Txy\B^-ԮZM =ıx獿dè0⻎ #d_ (P@ܠ\Zօ r\iH_߹C7:|"*6 D ~^vD^'f5@Ze߿BI1#+Ks.N`;0H};S%W]ۭZB UF,&--=]|#q ]:\_O|芓]`~޺?FT*6&̸z)+"tI]Ѫm.Jζp&~Z!_0lz8xbsEq"thiolK ] W=lɰ܉Xg_9G29.ZcگcK['yqO|}'aLѣwu9P@s]yZ}O%Lߘɸt! .= U|Upi~ tz#ZDU )"RFn|cfs  ŋk[X߹kc(6IE:o#yG !wӞSQH6GJqWMKG]i? <'G.WWµ+&Gѻ*"Bĕ=) /O8YI m)֤ҕ= weekFK~L$. cwZ~Z':®ӏbˬv:Vob (bcR$![cN[2^E_N’80E }G,(0ېI=Vc0RwP@ \VUmő+% [O$__5:V‡o.Z提Nv?U)@3~>8֮{w3nĥ^0;1\}P&G+&V:ЬE9dabar 0I@S?L M80& oR$hڞX2}>PDe&}N($DS[#G<Is Ͽ][\snH TyF9g`j?yA(6&&pUisz}q.УcH$l |0HLj|cNt1WiT S>m@G) <8q!,8y0HL$BХ{UtQxGgoh )K5r=Ks_{wqCADDy̙ Uk{lYY9ubj~Yi &B%[qơ}ӊ?-o.F]yu뇚7&v=]",]o_g?[\(؊aL]T^HqZ.5K]M !aBBnݪh6JZ(UmDޯ)lbj4pƿ/qRoulѳO5sP /v̓b6t^KWG2x0o)̛}ѦIjDC^OI& RуLmڶ,sbْ t!c<cf b}=E"<0xh]*].aБ (P@.KIe^4#aaRW $,L&lfx٬e|;}G)(rN@O–i\|-0Xg$I/0GͲ݄̟s 9:>و݌Blk .xv/>Ě(1(,4xsCxØ{qpE& JIS86]>ڬllru.Pqa;J 0X@X3eF@7ms*k`%S?o~kF ۾]<#> )Z zp.jfF&ߋ]7p&t41KB7I7͐vK tK"[ yܷ8I6x0fF5pioE0j6g]s:5Ř<Zȫ^DV9\[ (P$98v^mUWJ ͋uDT'RŒ+^OUbdf>l\n20Y$1wQW$/IAJi;?@D?ЦOᯀgfk-|<~,t& Łq*'s5N.$I.A*Ǘ`RNe,1s ʸBI?%.%1W]^]h ] @\TeK.a N @mVzV'_S/Mj)Jͫ]G8%__Gd"#-5w`}Ѩd}w)lѨdDŽ;nb[6;U@ܼry=~gt͸xُLa8X`40}~:ci*k 0뷼ǦaŘ72 \ Yum孑?a W`\M[tG`@_7w~CAOj{ܾfx,/_HC*`oTJE@V]E7|%CvvIq˅57$!)9x0nqa4}BՒOݎD/fM9I Ri~Y*Iuv.I%"w࢟Wci]4uq-R9++&_ttp\9BvlY[Rܰ߼<Ng<1Q~Yڿbc$yO:l+}ob+(]>$]·Fv>>|M{Z铏÷h˫,n. y-(0F3$slQ$' ª =Q1i^F@/L6+ko4VV $gc͈L}g"r@WK%Xa ^s|~W.& n+/OeK.bѻM?%Z(2!uU+pW´!Dޜ'QhyhFh6gc#ux5BS'ܽghѦ \V=]Xb70ЋfOrLp'{鎝}#wE&sFRl,ecB|Xk=#^jZyND&>gSývcnP_]MQ"{KwmP]UπT`^w'™S=kB,Zk~ ;r'F//5o\A.8v>rQ&@714hTV"J-h3qODg,sGPZrCD2!6 Z IDATCbofuBNR@AFUs5FckHI?$JwDV7h%F-VtOsgN P.4(ZH^r[b^ `%oϝbJ|6q6l+6w{V#9JRmKݮ{]@\:En2 Ld.rmLTGhS s+k%i:w16ⓣ]ϧFfFó=,_!svG A(UQO &<紝m8YfeLrs __ #yskON,k&;i3ưDtNQ6ܳQy'=byGUY $109F/Q?IǜO0ڄayv_P``%P1* Ҩ;3|;˵V`)PAe1ǮfVg{6ƞ(Ĺ¹'=|;"+c ԖH]h]wJ0G׆n5`E%u‹F{r}4%7:/Yxݵ#p]N7oĮ}5J!j)KGG/F*@;Rm4C]Ke.B[< ~)LlB?콋NB31^QՂ1oQ/.+r9Le50|Vw k]wf9 V#\7;[93NGgzVݏ/‡T.dΪbe=Ε/e=]O?:r]JX7*W QMb 5&)οnx{r@'r)yykn=r^qF?uE6ӿj//%F{mHbeo??sN3h*8PLW@s Эg5tY W/%bض9VoVf!켅=;oʕ@.QOe+(xx1.PJ"j40g &f?FÓksE,7B׻H{W.ݪP@ >1C2oGp<45lc lF0KPGўOTe9τ|\W?;Ǔ1s=ERsّ,8]Hirh8\50z"BV19ZQ9K*]QB۷o7#Dk=׺tOxv~LxaعBFNu(H]+`x" t\ueS,n=-&X#))hc^4 Ж7jC׬BǏأt?l!޾ɮw?EzO?:_g5"+ߠZʀ)P@npJk4֮ $Y1Ws%W/'ɑ : pM41 (5jq t<.22^_ׂmZ$0:X%tCZM1rLC<IPZFKK3o-fb Pz) C2(Sa~( ZNgēl<|i!vCJycm +m]A^˅!x*>2sOpC(ClJ"mʨV q/p},NZ|mGnSq(]B`Or~u4(]q7G]Ko+ɜ(0 "!9Xe?Ivӿn/4-h3n#?T\t55wS+4tQ;HĴlEVyĐ@ QB Ɯ'im(Y]JJ+u/_2ѺF 9eB2~`jB.U8TI-&&JsN2FNh*pb,5jwt&v z/PHڶu:a?2 ,NJ/:D< ñDiNrµ%#x[}b&?b]A:8uGt.S;bUnuAc4im4.A9crr9%I綪,oD!~Ǟ%`i&(ݰ_DE ŷNgIU^ܵޝt`ޫwq?ޛpnqM1uz[ٌbh0:F uy_W]O2]9.^ڊܭ *Ff2ؾ:F^D蒔se}l]b^>_ҽu3 ۷\9ZgM9AAX7q-}JE뙝vH8vLo5J9R&q+jxDfy0 lĨMBWdMB#sΥF1 I?2ش.F60{w1SKs>+)t5jOjg~KA9K٧(oC_k`W0423u<ޫ/;s I_-FCԩQ399@&҅'h>,wF:Ropf'mdWfj>ǤDqm )gm@ a˵Ѧ}$FΞ΀k˙Ѻ|$.' ^[W_vBjjqAOӽ2 >~Z;OR I_~媥Z< Zfۨqx.ʰz]'Ԇ D F2Es vy*CJܒDqlÕD+ڹ\_JB-1v Ae?wtF (+(8;oLX*)֎"OG[ 2ffkPg>x"J.OӖz6BJ2em;8v%9&w86"SU/y̷B>|52/ 6 evu+tWD.Qqfg_wpҽ 1D@P7z!s$ikDbܘ]?v\SYY@%ezIݮݫwʝ˴ruԭzRD2ܰfͬΨR5\ Mq&xŗ:9E_[oTR4*inCU;BjᏄl ]:g@-P[v.h^2.vk I$)+GCrRP -B~q* o/ZA{qv:F ƚB@l 7,+cǖM6C_J^Q>JapI ;x)y6זLnq#ukP<_tANQ d'@% $IL^KT9NP;E=Rr'u$LZO #qh93O"ImGrhK.2 ||+~,vÏ6\9׃!vC|-HJbauaJ@ƕEZJ2piǑ|`KFgpD$bUz"^d.ӾH):Մ=ui йkeT 0]9:CIR.T>m)'\xYI{x ͣ+rT)4$~[t$ ii `hTu{LZvXܽ7oG$lZZҒέ#ms>|Yn01 oBrV7m*+c&_$l 6od'^ZW9լE$.jкX[oYl(P@a0$!Or8 YHAB|i nB@]=zW/_`a(%&YE hmc+닷5/|Y*OS,{@f$1?RTHZmn)е/{V0?B/mQLu|JJK:nW 4)Y(*v;WB ؼ%ku}:Y:̮FQ 0|Th$mF#Vuly.Lt}4c#n=tPP@Xz),_M{nwmoFvЌ^a!6K}޲uoa?:ߗ^b٧:/˵+0@vϋGж"^!<=vhQ.m;Tn4pp]V) kd =2Ѻ|IY4 |4k.}r]Jy?ejճ{3!JEd"4Z c?|ݰ0?hԮF˅:F"vqkJx󄯍PK(Kg*bOx4r t`߷Ԛ(+:UFJ?SvL~pL *Gsdi$ݹn||؜?{wݱ3/p 1{&b3bL&~JrztXEWH?Iw?poӏ"Z*ZYeM]K#*SZ\lUte&z:'ΟM$͕,rĞoav^VƳ 99:$& I ik'OrGY k/nSn-A5rNh])#4L>5KˋUlVBJ!P _?/;=[FQ3ZMJ솆[Įܴs9fB$ !/-zKV+@ &JidTbIB0ૣK$vnK.XT,_ЫoMN/]%m"VvNg~<];xͰW::fp' L޴}oDZo勉jFG$`¡ԯٗ~ܣ}9 =vf-+{j?=X>`p-T^JV>oX :HNPQo |Y׊{p<8uޤxEu| ((#I.XY[J&&JQy * SZaMOjJ!FYA=goĴ$ ̉ӧ08UY Jht0}Q_Ké.nM=k%u. ]ԮC s q*5KJ ,6jپd.vWDry$~s:tBJ"fSS0Ӹp.|z@uFtROjR}ESRm\%V:Jw+xZh\GܿkXܹΩNNtu?D 񌾜1>~AV>$5_-clo73V[\GR׷-E Z q6`B*P@ I)yxo>϶'Et`BP7Ca۠,֯J kƒr-a^du̓|)h ZCpN>iwU4Jjj Ff=[nXEUq'}Q0]0ԥrCr#t AN1*GX?&Limye0GLƷvL,w_PX܆F§_ĩio>; ȃHwbַzh$ gݷ>2s*cN9)8yzj5Ol^(1s`:_%>X;dPj0dD=z {Oɜl}RL 23 Xϟk PЀ'9HH."hIZ[–CzwAUf2f~Yԭz %̙֬}I X>JR^uEg,3Ύ+I7Oګx6>--ߎ/ XNj4b#w鏃sLD81 IDATnP_*$ltIȇp@]chFKri/>E.2 KD͝dX[0o;s1NL`Q!2$t`;.@NQirsX8,=x%`Ыu1zl( By }]Rt%I|6_ -@ms.I I /J,_;M?{lqCz{;?ؼ@/xy㣁 &&F&uF)ɾ&?7xgT K<6^¬/+蓺 ZIEzW겟+|g=RiZ>[X+ P] HsT5XB1Y`IF %SIۃD>e(w dg$ޜɓ$>ɅЈMˡU 672uؾyHxeX=2C%t}9K̓HIɷO jL=j*sl$e[1դjx^W<-L&sG5%CsĬIVfFkN$qt<#۶!%Y[l}z#O:3bҝu{^Ӵ|~|L&{vbRӋQ+/.+ĭO + n$'6> 97e@XY?+o!j+Bd W0_B Ud$m`00齽X*豍.K Y_WGWX2_ EAѼpXj M[ù3x &BU_4.ttNHLxb9ĮVKR"$&:%J5a \&ޮ- fT$ BHiksS'x .RъKy5}9Z,5nu4vp A٧ ]7nmJ8: +6ߠ͵m=x}LCh}_]pG.q&>3O!Jd"PPAp~^ܳD$8n"pgׅ9q-:6a8j<~Y_ݿVn P@ hFƛtl-淎VG#\""^.XwTnmǁw|]-5iWTrgy5&1vZ~G?@d\<T2 %_9nĮFKðDEA|1!QO9ne`%fEGs'ld/]n?67//5Z5^jzB DV BNQUl[ )F<#{?;D:$zQo5fI$zIÊ_/lY4kQCyy:|~ ;t1Ш~u,>6FP6(HK{;wn?;x 5S=;7"(ȻDϙ Q,;1I/)J0fg_K/,w[P`A[qcF^}cƁ @s|=&OrR|ؑV6<"$nD.1ԔZU]0+4}"@-FWj45$H4.a pt/?N0 \ʮAH_دKE. mKM]{;E}=] 1td>qi[߀ȡbZktז HL I~KT+a63s,m`Z -/wRva. DDb+Cлo O]|Ps/`](,lHɇ71hH;J:VKn^;^CC} fi^h*ڣ-hvn;DYx|C><*3%}_ cٌ;%8__qLpO5U* wֻeB~{JhuےFTJ$!z6&6Ѵ6$ӍkUb c44.@"оh]!|6駦 Ba}0>`h8 !`\q]UwqrԴ`xzY魑$pB%L"&DR Bءp!y ޫoy Q2VJMt;jP\?;':nN~c5#l0RN/]lz:'nO:5!IXfױP4yݱygH'YXᣇS;P747k01;ܺf\8WmUDXL׸unTty*L됋_fA"!P_@}5Ք6qhi~~ubgL[&P6Env蝆dpG\GzY_x\3Q2"[p;&4-[7]e74,_9Ubv#۠`o : FFu/SWQZoʌuo7:nLu, %G'0?v*g@ѥk(Ujg d5Z5ХJ%g{d?.Mj ^Qr uwszʿ[#tY!g.[g%U4ҟPz'uoYmvG>v_ *pl*;qkg,vGuEѹؾSWNFじIpػ+v\ǞQV*szya܄N:#ܖva $):3%}_" :߀XȊr_YZWqr{ ж(7ܬcl9n%WV[ӌR)xLkKtlѵq`mL\b 7&.Aqe?46Χ:<`k[Xم0-f4RX&Sgw>`ozB"CѢY&M()%ERPRԈb1)g95m{*Adz=Y繗]& ]1yzW@Jٙ=;p`9Z!qqNjwDZ/><6./gMe$I.>ΫnfHS'÷'mjVױDƙSyƌK﫦:4JL4:55P^*Ci2#}ow7|}=q@@Rѵ-ְrqߝX"nƣOsnΜ49*WaB&)K$HI 0n{dlg6Vk&yQ1,G\cRkH[kr'Asz822#ԴP)PQ!K8e2(ޚjN-W_fk,@FEm kr h} ~RZ-܄_8FPX¶Wp58KfJ@C J$F9<ܰI  'Joqq3.{ IY׌ptC~12<iC;qnq0tD&N??Iys(o8qo+g񨛓E+h&V_@ЖH͢lKKe(/BIT:`!CTi-˻VٓWYG"!/1}v7Ҏ>d|I"+Gƀk0l۔kX4_xz;5<u4uI $SRiLF5jviw ;eFMa~:tEmsejgCVBh Yg˔ŜѪ*w@ i;qOԼb| OqQ#|uyV nyI;> ^^4Q~GϬ(̘AūuU `52.MVW7[zہnSS ̡֬ê?/?.EѴ;ynE TZ|͵A|- +fli] >:=(wvÈyv.ʞ[0 hQjVkVkѐGzpw CzF8":.㍗e,7/1eoW`K2nݔ g="\r÷G &Ւx}ruGIƊ5өMT[I!jKۙ[}tkc V9.!>u1{ͨ3L"!;ZE@0X-14?Uhw*XIo,܋Ͼcmј֭!jjB~65򷮦yp u oa9cnOEGVi9AwLI1 N[9: Eش>mWqflX{ttuCýC8v V@.S1&8۽=O۵[8^~c8bby_G&FUG>er^ |'sՖH[Q>}_y>sExOƴow +!+-YkiKIq1z':i?*b?̻ntkJ/{b݀Fy%Jj߈;8k@WHDuU.VFa["5 ѱ:)]TiXD o@+̯ǑCŌnnН2u^Y@84qOG047FA*Kwp_.fW[f8>+ j4X;(ćgBW40Us۽g$C}PWl% [c!as..]- 7W^B}e o<a{4.)p*Ψ?wva߄BbvZ=J;?3kn7JF);1m JٙG{iw_hr VWɱK@KN7K_g<.jf/m1]pda|tz~ ""& CL:3c *+A?b,R;8~c 5ggN(]?z3wwhok<j<)FiI# Wz~>r\BE1oVx慁i=ɹ} 3bt":9w{6pJ-}pАXXq$sOLMB0ߐU_m٘k"#P:௿; qJK@S@74/6 8Ƅqї6!\vT-ZC;p.IOw\Tl;,qg#z IDATǟf)n 'Oc()nd3p%ETߵ;WGj4Z|!|!^>#P"ۊr9JfJev% AL FFs:=!2,Uia| gʝ/0xX"K@Ԓ5]= IKPf>0=5qL1iLP {?fq `GgwĨD_cww>:ZxN/@8Jk஖$y}.V{h5gYQ+="@UR^.c8yׯ֛gJ:>@5цR $ U 3.S}~^>| -#ӏ5"?=zF &#=#ܐrkk}="Vk}USMn7a ~pCL>"ֿd#0(ބ`>6ˑGŐZhM?H 6wtNEdtD// ܽѶ5^>73Ё]8W-أt_X8MS)jls.?X)_|;DZc5Ʋ`t/d}}]cPt]Jx 8d#p~sM4ZC:@kl`*=hoh|,(|<?Z-u+"6ejaLJ{,S=g&M_ pΘygwח\ iȹXø нG.z2׿($%V6[cf__ n> tO&,9. ĩ][#W*pL%]EUMw!  FD/RRC%ivZ-sg*8DG z'A^mBvp!^ya7cy`\3A.?[1ɮsͼwHp7dZפR%fOYfU;~_5|q {w3sDi;]߄ښf^~5ihInFiq#JJ(92ߒboiM3minfP5ۘD[vC;wm)ԕBE-@%XI+QuJP83q]&UJC<[]d"@Mxz-{%B׺ΈtpWb2+]ÆG [߈şGg 4LoRrn- DZ$L!h,Ĥ`|UZ쇲ca2+}6p$ZzFNFE؂=iၒgBϬh>o7$2-" }}jhCSѵRPIZZG@d[Gm{LlBDZn%7ߒ~w2<2-GD2f4TW7a]jI Th2/p&NdRUy0[^.3B? &.;|t ~1Q|> kj}5OJA{| "&֟g-#C u.ΥT¶MWqlgt.Dݏ <ϵޖ}[6\ 莿- ?3n63N>l[6^YC{&L8kS־0  !<9GdtT~^{aFf8fޕ*i77PzNT3c krEP1q&`6$I.ںBk/aЛVn&o@,N+w%6yu q8$v|XpoҁMTTf%RJQZ"EEx[YH @l,Mk\h2 l /G';sf4j,xvjkhWSH/+d1. -6xD 8U^&3Ӷqg{x/2G҅*cadg$lnYF/q].<͢z;tG~1X3Z`_p\ruh}9k# iqqJˢy DEs$GUsxW}ݞ" caiXeSfexQtKKÂ8#F%1+\p\b4j_X܁ p~.Gq5^Ś!;#Z-rˋX ;as1[|egYѱA?Ʒ_Uga8퓦3B]8~b krԣ[ؠU?6.WNA B6"BjKtQ|Hi՚G &Eί(6gܶf4~8},U %!^6i3P_%r4J'Yv!r #$*15W_)V}5?qR7_]('oow̞#oN?r(?<1o >~ -T>q=\# P[ImR:6_5Ruo wߛer su NVO6't"x=o+95xhW"a/@cHa'Q%A`42\x1hc4-N+1&JWtǭ~xp[?HFQSܾ"cy[n1]\X4W}i$g/K's ƚ-h^vmuUxuimnMch7b*ږ3 Q1ZCrXcұXxS4:$T4f07uT2ץ>[_5DZ+ 2Lco/g 1D78G1B|?;Zq5rd.H2Gҗmݔϛ `j.!xفVG.d I2Gb&0{hy7\A ^GzAB}kS0877 8r|sK O=@JТԚ3}ےq',uՊ fAw'a:]`)JO螄ZFO~eRmߞ|Un+k"ܿ_gxJKNa;8yaM[pF=M̩rbh,>_ـռꇄzƶyThTVgc,Ab}aέc,w߶5J9^yaᩏv5cƥ G'NןLb,(ȋP VЮIKdC__wM?1X + W.}X$]ʶo~>G*Sb ϩc㉇6cꇆ"pi4zX+GYTke(/PQ&CU󰀳z~-oEZD8ցvjPR Lv|~8˩o"T߮G(%[-ӬveRYPخk-^ A ,‡>9c{7wݗ>8l6uzO~w ; 8|/` , w+?1+[ ‚׆-颪~P/X(Z[_hsDjZ ɑ`*_ ._*ZO>;5r~VH(SѱV [t~۽Bjj tZ6_/KϘXiI 0|r3fҖ@W&R5j-֬D{,~ kYӵNCF#L扞aq33УWT&PѺI)i${=+ބӻޘZZԤj3~]vgN ꕗPT@[5>ymg=OO7zFDd ߍ`Sƶ{u<&TU69?ظ^qte2TV HDEQVYGظ*6nhfn'oP`4,RnˤI{L[|lw>n#qόUȽ\cS0 եveRaN[V*3 ]MFZR~ðX%]G.(hĎtЕ]De/ Jmcae$GzZYcck"?[A {LmdN.CEر= eԮY̥oOp ػO {-dW/:R.?|Xş]g&F3ځ}hb<c}!\Fy Q.kmlIxt);]XF7ol u_{ikT퓻7ݰ:rY@ݚ&*; }s.]i蝃 Yw ~{ ۇmMHê.<xhzl;ǡ?hj\x㽑pw_g:VU&$Lfk$_m^T4N)DM4{A]/(}]コ m˧Ijڋ#t'OOCfcSY- 4Ufñ`7/@9{1?]r sO>s :"O^E$7fMH k eN"`t1U(7+.b" $@h8&-9PQ.0gq&I*"z֜|u?"?O{qBk|sصžs[ύtۏV\/oġG(D rH1:&vWp+exu>N!m⟟/wnG/AVX T? em[|hH̼+5Z%EΕ_P4xu%Kæh' u@.WaĕXx&#ZS v|q yy w?nq$ITQXЀ2*tQrTPQNVGQ6>*_=Z/f2A'AB8>2WֺZ5e82}xʤJl٘WdImoh{Fv/bG0]xk =\lMKװݬMy׆A!ެYdv0DC==@=q}0 wL5J^I0tD֯αبDJdtu ̝-~ ~&Ց'nN]*+;k- OA,aQf%,u?VMCrj[P׀z5@Po~~:@8ctm\܊ѵ&+XU%à5,Ԉ6RHJ B|B 1LQJ:Q,O|il ިDi'=] ?a>/1=^7`eb:[ o$c.{'Oc\0} @X0=B!/L!9B$iȭ[pEr4?[izGV s)ūΊ..O3aq0VWĄI8#P\Ԁsku([tI@6\_hX+`\Kŝ9e.-@ גJǰ}{Ku4Qmcl\"ua5P3zxH?S.u[S^Ku:Oo>ld"-O8W0k?zW/weڵ uvh!F c8YQRiPUل 9a|q%#ovCȡVSJ9R)JKu:e2,OED16RѵAA")M4nPW/ l)0c귴hkA@JjLdVǂ]Te~{Pqq!O<;m% @i =H ̞5Bqq<$݌9)9_ΩiU_.9,<=ݰI >2xpkx>%zڽߡ1mVE k.cÚˆmqhnV e_^yk8_p˟ry "lףee2HQU6<=th⍠Vi&R Dݘ{TĮEDhH)m?/]r ӹ2+%qvIL1QWԘ@jx[v '&z{j88ag]Sa w.9 \eЪ/s_e|5v@]KMP4hH<=fCZZd'PSӌo8XG?羞v=%*0 X@cR=nUG}`ҴH/6C#1z\8<2Ѕ[ux9=0`P9=.j/DvΝ0^ZZn5HDGş{㽑V@FQ"u5-k=G苹jW#i˪PWpvz `ϿϘszR҂i_g+C_Ƿ1Fr;~Z1 8ٯ~u͘sO-:yL$JKۼ[]>xSڵ }E#hu8s0h 7הaZ 3Ezy{*QQxnαzT$7w Iz&+Vzq6's pE&cԮX沙4ʿ{ )xk] /T2V&[olĸPh+LOQL L!V9.fWs.|{sFKώ~15NC͠T[\/G T7a\lp#S0mV7ww N,JF~ڬn<ՁFş_0s')Q?kuZR+D#(cZWO?8ZoL&$%e -|~7c,9&-Ɲٓ]krN T(Ľֲ>/<@5k?&v1ܾ?sO#Ix}ryu?VMm~pSVgC%ReJ(,m Ңi_DXjl.h] -2 }!̻knOxxH) Kf^WK&¥|{8U:~ѷL {~;^8} tU S+G]R$3VezǞGFkj`.['vBtޭ.XYס@'[掾.Rv5o{7Br=sVul'<@z:(ġE8wrav A w~bt^?cb2N6Xj@ػ'erF!l'!c`_ϝsj^|v'gœ?Mf}+95hjRѾ^oO2_. uZ~RS=ir{#9mRgFԤ+wc_wUMxؾ1XiS@\| v\S'Z|['|DzWs J4+QW׌2֖JQZ"CYe%R47N2@L?D}K4D " DM4l3uş0.;/gwgi̅yLb8$ W՜ v@!qZy4,_m+@muww /߄yOl=a.}@jI|!|-;uܥ=},S}Go텷H0X˻j7?F$ ddcm~:wE!!ѳW4K_jnt ҆JB0>8 T7&(3}5Z؋fI(_(.] JϙAC;+J6xkO4k˽RޏUo{q0i#ZOSN"+3˱WbWA Wo^}oOA8(pϱX}Q]Ռz({1c?$aΈeK&}ʪ~bbз xAE!ߝtzl%Οx/9w.}Y(5P*tt א n0,xnk//7(;>!ɲvuIĂyXXBRmWI)\oOSXDDϵɫO̻2"*}ThST/?=^}ƙvxz/bMxNfݶ*msdu6pt5EM4Dc7+Xd cu )ݶ{zJԧ3L<-=oqm. tP-IwL銐PomǼa.TV $LBkjRЁb6 YA7:8XJY+9hQji߇ OblOd t/ho'^nm]~P$V:z4$%}!'"zHL r)9s]'$1:%zmP7|v︎1R/Jgۆ?g_xӐ(Zyv 45Fo~ Y}̟Cs5|('=bt2~_57vMN!kj%Bsɕ$5 %KD&hn̼A]m00mWC}[|J폥'!$ƾmWL!! m.|Jq>ta۹Q_8/ۉF_uI()y#L3`:e\5+/AK۷ :w /d!*|(~HNq XpUz}c e2@q evߞ`uFŲhښcp4zPyD+!#о.R)ȳ-#3LR'"!t F;w^zGӽ]o:Z/|F!w4<<ݰwW.4bwLMǏ- =GŜkpX yx#!) zI@ODd萋&hfPjѥOV2 Z=6۶\EmrϽ4^/OFi@UO@nNԇ.P#]#QKd wkkXptαlQe& c.;2dXQ]+]IӺ⦡6KH?Lp=9%خi?FsjqROL}0WoyWYsiai9MtnJ#eĮw{d9+8 AFf8GB +]Ւ ij`Ll? >z sCݕ'Ca.|s8˛mgn=gNG^TtI߅Fţm/1ͳa]^-ebmur0mSp_K c]6bShlPr=zGؼs'y=Rfȇ4Գ/̥?8;U;xgoׯqJ-0 F1ݏcc3.$|q{ $LV,?#YdD3B]8u #F'߰H9qe:kth|^܃Ug SilTgv?y՟4+^yk] Ļwp/|-=ZS݄+kS+k{W.נ (g1YI2os-h&ku d[U4A}:|}zLsL5u^vk^^.kĝ@jPr PINxxP4 f:R܏ǥn.ܵwZtry=ym~r .J['J6a< H[sJV,jˏCg/eh/\:lR >HLFRJ0RR#+ ɩ!|pj5ɚtmDA}n͵_\f<7Mw'fOtĚX]m3^_)] u_Zb4{7`N<<$Xr KDGΡODqQ#cCpi$vp!` yտ^q=?~{r{qH_JUMlBUU*娮jBUem/̯g:Ӣ ѵc $dAh&h125(]řrgwxXiC.IHH̚Ӎ%wڄ\L鹜vssKHI  l ={ͅ{pŵuxpw@8vnF{C% $9?t_n@ZޫuXAT+ 02 __J_I?LՒ |3=ɳmoVP^*75us RS)p_; r+k:^4hpk .;x.4,8[SG'ޣcDT7֙ :q[>9Tl`M +bH<>xYٙㅅCpӐxtjI9T?=6&__0<6 /ML$4+PD}]VW?@ncMmLm\B`&h־L0d:Nh>30XE1:A;&>՘[Lv)xHOt2=KVCXKI ()nHfydW׆!:ڏfu> G= Ѭ.5nPM!y' bеَ;@Gqtۿ7+~=Zsz(&Kf--C3M%采2}|ܱbtܡWsG3`j5x]݀S-@Uׯա]~s;|Lso<˵3!)2i phW Hm*@g^HLddFH?&h&Zku9nNa`T?vda{=-mCl|s&إe2V\4lmKm_ތw^ݏK5[g݂?B׺%h  S/5u+9Xq^U-1~xaxpJRvT*-k* }Psk3u״LڕOr{_ܙ*V\aG'2F_&)St)=$A}r]ec.-3lqI|K2 7{ut b%2V/;U(Լ\r+\]#i~&:S_1"szJ~664Z W v5ZI,e=$Sȹd0qި] {ތO?8CZ:Ԭ…;*ࣽF۱Q6zcJ!BöM NT@/ $qβcYۧ_C"pr|!64bv* ܙr$hCG&1gBsΞI҃f^e4}Ez]Yc >1%xOKgs{>=mxc3[x˦jWc(2i0+&M% lN^ACÏف&7 N۬RI!; Z6jd90@]JN6 Uk IDAT]Y܉|pѥH;m.( hu1mCp3Qv WŀҠT)_.SQWaK ֣O/z ȠFQg(πt1?jFd7.¢peF)n7i:v]y4p,Ppx]*|~;Z˻Z4 $iU1~,?b2O.~$xeG4-p)Ff<07;+ )3IS{ >t6uu(.ldD݂X_LA2!1@W욇V0]p6wpUo`eWŗ;FQ.?ok˶c|̹ioaAxt-V8"|V _|w˹Dϗ﷎ƛLH3B(s4څ*[ж釷 mj} 5s1!+njz LDDDDDDD"PW41pB<Cxul\W߬P4 R49G`إwO# Dv`? )1``+$> ]Z2Ҁ إ@#>Xtdʳ4 [YƜ%/>c(Ănly;WC}Yyu'e_^yZ{ii(8YU?ߞ 5rL1#+DŽ3M 4CLj4 6 Le9Lh}#uiƀ(Ea_ %E=>~v{#@[kVYDm mh ha.X n]Z2ʋbmku㽷Nb-#1nBND;ίL3&6ԁ?ďߝDee ? r|̻uTD(9F ۷8,@: Fxגk˶c? [ _3Z!Vx`.5^#ĎQ: hr=t Eptkk]xtF#â8O1/(_&.p5R~m1gtޘqY62vWriM.vbɓD}^J(^OV^GoS$Ef瘐mBN)%ZJ>"_7zs'3G]mk&7#88- ))٥Ѝ~v덂^Jyew行􆥀t=bǢ!cAu f;;O{=˝woܭ(kƂCՀli(.l, (4ᇦ>X=MKv1S\sr2 &?1]Z* 5Gn3 7`ϮXq;j:ZjJ sy.d7OΓ0J`>wڮ1 =.W>N.un|۶87'X.$h4*3JhhnVu ZuxUe$g<3. 8オFcC;r#a;;=X^}q;UWVW/;'^ mvօjjkZQS>ojܧmLVS`4i`4%hdk`4~Lꐝcbg#"""""""P7.ix#V7)o`:</L~U 5AWwb0&ӗR&L+_. ݒ[>IOvt+Z] n 4ز3%+QZҌcvz2^(iwBO Ό/95 =Bo_ %x5nR—RQ3! R䋍ʍC(s8B%ؖ]vώk2kЛwnxZbngO{='Н4%SgWKsl0.X_3[ܿ5.2Ͼ4y=Ϛ9_8߬<֪ p,_apb`}44-> Lw\67jkp^׵O 56 [kfl """"":7Dn҂:Ϙ߃~n9s`:ȡTU"6Օ.&G]:(M욄ov@%)g5Xԟir]SĀA,YGD6;0>+6^tvzQSĩSM(*GIqn0g'k*\vy?\y h4lmr#$NEXQ\<'𶤅%N#aĀ\yW >оV=%Btډѹ#dR($u]x=(,hO:T:Ve|X>]a\9Ϛuk 95Ϫ4<_RPm[hG⻫${ V7_ف+>-Z&w.9#Kef6YUDMmicNNbŢL/= PKDDDDDD A:? ~ 4]|xs.)ШkÃwGX%/࡙ 潸zou9MJ 6l1GmBю 'חE?>zڍN0: Ÿ2 #G۰xFָ| VD. a|y R { FZN\$ՑO[7;k;&Kqcp܉㝏~mD;5'ՠŷ&a`w¤m HZ2<Ԋ7_ًoV33dQEAޔ-f .")-p9J3[Y' W01ƻoW>• S}^YY ԍNZz r<}r0yuDdZN1hܫonL_~:(hM<8z*]26:>+kY& jՌ/-݆r+f@n^2r{\șܤ$U""""""""O*Jv7:8-6_i}ip#<"U.zCP#3an`bգW4;]v -tz5nm feKd}X8/Ki@͈Q6\pIR!x.~N,zb=Z[=j\;=h'A:eKnPZFa7}{qؘF=ۄ,#rL6ÞmDvɗmn<%""""""sW&DJp+'5''Gѩzh4 P FFQ1(|]O'ICb/w4`@Me]e++-zWpUq<|o:A{ <`ށ\+~?7uMy@~TrutxRRB˖К1hݻ/!i?G3/>/J͈5F&+u^RxK0v{?Z?+=;[?9OY$õq͟OZ0vcڢޏŪGVak٦≈Er\ ap<]v=(A:-lMFw_ vFX7$Q v-߀ JP asLxWZ`tLiJ4pF(9͢k l;^u\kSRS?zH8*1 7)[@oЈ[^Pk;膍GToU끮K~Q+00| ><O{kזmǴsan5ܟgcx 'ERw> [-tU 9@mV ,#j%,F+XiB#P#=C>pK1vإ=t$}ڊe];+PQpޤ<f[/)"ݝ2Nl`>#@BD|R#sZ067=-#d Mx=##U(yy6=v456HKhJim㍂?y+>>41AC20knOKMVu`[RF<`^Q t`'^2F@W '{=;+XkDl*.lWĞ]sLߝ6rӃjWߡXj[X 5rLg|EEnH :Ph<)u"߯YU|3J%g鲷y/K{D6s1|hei 3_>YlFƩ${}Ch[8).[ EEM/i_v7.ނJxgg00d۰JAnr.5x~fx{ ,#v#&FFh4L]$?l$ v!oDIq( 04"ʹ;P)t-ELM!_t_jY #hW/>Q=L] t]avJ[)V 젗{|ЗxSo<㸭#kQ]MS/󟜎T-xhi`,zOe$#!&QTZ[=?t4_6G5@DGF;⻯c2f̝qzP>Ք4ś㓯~ZrjAUE ?++[P]قJg0M RQ"vk|O';"P˥0. <&O*x]rsSFյЁ*5򟰞H 2viZ!h\Xo/(`}^@{(])pc4(yT]qzrER >ʉlb6''o?XYX;l ` h,+pІAG21xx(A_*eNdbs|a ;wE^kֻOns2][5|@C)«o_Iށ;V7]5m.ÏOAJ6!xص> }C-XU ^/*+ZPUNTUPUHn޵X Z{zMDDDDDDDD!uONvFl <zIeJ9< QcF4l kVXP}+ɁF!fp W.W:l}Ɩ54Pij8:ni9lh } Z Xz k6b虦{o;]>V6-.7c)u8| /Gu՛߀4\pQ}P^=j)rmݢ&{ϑsi |v&ȹR' hѕ@7,\2wo ~t31CWšUnM޾DliW hAm Ҷ?P{)9E@0–ebfR)ȣ1h{ڤVͩ4OZV"_6yuC@ٸ ͚14 .#{2 >Bl"#tb˦jQY\{JFrGJ=Z$y(8рxШ1iMMXf_6zp0/t&eCaV @)(tժ/)jq/v 핗;1ﺯP_RĽES10*tFGB޲MMxr:6̚3f9=9%s:;PVڌ2G3Jp4~-Fѩ߷ mo B sjUga-VS(Q"P*ɏZ6ZWV8d&(pEʹgF$lGe ?|w"r-h IY̓;joWh{r'''nн4SRs倽Bח+c¸WaH/dzնNOpC0yZT(XWPq[ObGKQ|c`q˕a5D熏Ӻb|Xkot.W=@ t/m)L2:{C: y>в7.oE\ m 2mFX3 HСqԔXG됮]ʔJ X8)Zn{ڕ䇀M|j0^iGp v/MG`k#˧Zy~N=h4i؂<Z{:Fuӫe|eVlf4{? 9y}siP35څρPPGi#sE*tݥ65uAIqS) nųBTq@z$㉧T58t|JK!+Q l-V DDDDDDDDDDg[íwEO_/Wl,EQa]ڠ_+xklW_\|i ~Q҆3`R|70P+#vc@a+ Ǝӏq(߉!,{̠@KrNB$+@ShjꀰS&%2*4<^ס^6'τ'em<Ԋ;+̢ hl4Qn`+v@TW*:S^P(ŀȵ I4vYm2Db _hƿX6LVO?7*%[^MK@F=~b6d$%c]⠱tБ5xUhk0˟)<ʔq$t9X֞9x<4^XO-GW-_[ӆ۷1/-ǽ0v'lZʰ~m(C6KVk=DDDDDDDDDDEn4 ~hɖ :]]))Z\pq񣵸/Ez p"ndMp şvբ5P/ި]@%WRn\"t2h#V fP+aE6Է~AcC,#Z: i:qeL7+ J~_hq:֔|-Ã\Ws|pL#m9a.s-HIբ-n㛯9[(lTYg|ĺBA7.B~";q;cVvl+Cu3s[tTSeΫmۯp㑤Sl˒!8A틅y.S݀/@#EcѼډGX2Lz~62,ί唸YpV((q4C ɩ:D19:y[D۳=7ގ;/86 kWv/ނQ1E+5:om]xŭx{ 4p#0z\uҨpQ GIM()nx_UJNb0+L0f\jMKDDDDDDDDDDn744 \\`N4oO%FnϏ2ڌ܁t]}ɩZ%ATAB5Ж u=עx=k K TOӠ`2k1|M1E}][L^S< 7)<4+{ ϟJT)8⁹>W^3tr`ZO<+^}b(U +r'{UP?&Xt/m?\{0kO415KmxlAf9Q Gix5`$f6!;ۄ\3r45q@ny v7`DmM6EU?1bzbU;m4(uyd[zRX30盓17㡡T y!r// »o7~5 1~0(Nr]#p:QhFyY3(/sm3J}-QW L!kg`2!;O7` L^JFp2]5d}K9JKF `^s և|63#GQ@| }?LM<򓓓"6 8JTB^tVWJ;zX$,~~6Q?Yu*L{$R!zrL8~>f.4#'5`.xms\\~ [+01s FkP*y#x+>· /-݊ kE@rJ^|$iULI, ֪(iBY#khf9hlhVOjlrr1!3nMfT*Y.u)``Xt(u Z ؽ b`7@0n}vi:rE>wڃf߼RE{/-K・' ZPaTAS ΂ܠWum~o1.SxdDݲfN) o#pu?1MŌKb\!֔\{O_K8//MSHW.D\|`n@Z?z>痈ܘ/@} w?8v in|~.a$E?h:Yf}REUU-lAEy *ZPQDeR^v`mBvY-V=5&"""""""""":E# ](tB h9Ǝ,\2 ݈Ғd&A!l<1+S x]߼!K0+>@%W0 T+$45J;UP3!049\4%j=o(سw(p &B)- 7+޼9F2J  y0M7MN) X AZ_kڳHMӑG"""""""""""YE)h(@bno1 MXs!<5mHKOj`#kQXj߆?9Fa D  kK c0ĂÇjbq!`e/dMJ4|y'ca2kݗ65Ё*FCe&CoP4gHngԍZז nˣ6=CQ~冹l}iIZ%,\히ŠAaJ\/1gn/r8UUN|1|73ܳpt^ScfN|n|kNVk<&jdXXfa5b#n FdڌP-Q׋@3VI~°~xƐEwhU_׊?‘C51;睟 t団i||/Vx*Fcx{, jC|ZZrE%lPVWӊS Ѫ`B &S?? uCt5n|V:Iyx݌+vuF9/'Gi3Z8Vy>=]^ T07]c!,Vl.S\~_dmV2 P[nWD犉W[ ۷:X[HNI3/A~ζ6otV½)e H-ˈ2'Ҿv雎nM!< wDyYmF<\㜫PUVnƜ|hΈucTM %% c`8;NAJR@8rGU?w'D]! ]Kyyf%#G2raB^2,zE{K jN`w优Mr8PMJRlkߞr\wJxtD[.C]P#B`ᆰEΟSJKfBQ2?"tR6^]rX3HϷMHIѢ-$Mar! >{[Mx58rFjϼ8PpuvxcCp,yazI 7bno\0c^{3~~6 l܍8~5FEӐcʕanxڍ7BaA~d8Y`yfd&G}+@ @CJ{VHzl:o~8u!HIՁ 4Z@ur ?(-0N7ۜ#kp ߢ5qo@F,D׎-ؼ$^k tvzV+yBeVU JXHKٗ 7/=+NSKgs8/qryXar IDATat;~?hĊ{ouI5s}<^cGjQqFF, Qb!)gkBnn r{<MKױU{%h$G""""""""""Zdsֈ/b `P磱kVwMSHMM-weh'Ϗ>O>kw΢7`AQQ#zHww%otvli_Du7Wl.W;@bvT]! XiCiȿ8,݋k0b-: M Cqa#窠S-Y699f60|?Rj5go|Fΰ6cGjYՍg܄O?2 Ȕ𻟈nƑûU\Ԉ/r1Ǭ,.fEA=EFijhGz4%ōBWQ_׆6նa#K,Wt.ͽr-LزLȴ`i3–ef@Nųl@0! u{V* 4\~; 0?=u1@dGpXd) Q@46C;! T{pp4!PGGv)j/ <ѻ\G0(PZ(;?n RH^ƊOc8Ūs\]8=~meLڣ?/sG[q7肩0O"r\n:Ո'|'ԉԸxmӅY-%":h nL`2#3S^#b=hDDDDDDDDDDD=/4Z@'P;_ѧ_,3txh8;B|ő vt`۾=UhC5H~|抁ZdR6p=_w)蕂“ ӯvaB̜KP{Սl‰ 6`ߞ*Β6Ͻ<6ȍ8{MżNgvnc Lj{r_ᆛFAAQqQNEQaNo(8ـ'P^3;hNot 52FdL f`"n3fljFLs]JDYFDDDDDDDDDDt@ݳZ |v;6`䱆িƊOJR%:J6-'8ڋw`? NRt&lxI؆j]v5.^Դ^/ kttJpy! j MLVjEfڌ0p 2lׅg>(]vzpeFG2E2 gXtx=)ᇨ 7_ilϗ.'W=V9z%xʇڜ0)~u,Hx#kO nS؜ ?Ko5]ee #CW+*q2 z?En G຿ έe8 8ZXr^~2\<yɢriFCCVP[u5.T״څVTW㦙ۢ9,FP(%STTj%jT*j%T*ʟJ(R+P)}yi:X305<',M\t.S91v .ѹ.u|v)m#AdKK' N6 gM9 >;pKI6b֏sC`[|"m :Mʅٜv)>|-`rٶ< 514gҗ/@zNoW.̘/;J .NK嵫V+KþV+1mvO|2[6;+0Z0oko=8֘FEHW"-"gbּSk1oqVf>4 ?UXӃZ:5t:%Z;ԁV45v͙Gt=,zdXZzdX}32HҪ[aeJ?W[PΉy{Im8ЅN,#Ǝj*Zҧ7g`0+z4b5šGRU-r̉P^O_Zd/r\`)+w.W?)ǔ'>0, ^pQ|?2jW[ѻO*q!tlӋ<ދ6pd+K_Tq1܁b`q@fx诜KkZ<0Q'ڽފZCip1Ǭ1qR V4S*/W;@g&5yox:UWՙ:֯=u㔙OeE>xwC헪~]QVVJW*?BUϯPa^ß Wjosn\\V׺BZ׃\ۻv-%S_-~ܖ׳-WPn_4j½~fo~]]W_7F\9JQ-7mSGv,xzINj2n>fkv9;3UEEm͇P1::!iX9NZE 7iڵ\k׌։'֙o<׿?0C5WuUT]YJW 8yvSzfwwu JHTm WP_DmC:@V04&~R#ԅgu2T.ɡol3jy vn~ r=9ojҜ(:/k/sp.yv+]65뮆y{Sn12]CАiFkm\m[K|NW}3F<\={%[n׮]ڹT;-o s6&6<`,3AWں%(:u/B}f֥|.3CK_/zPMykA2nl?l6O +ݺ:r+f y =HM ޮ> Mk}lsjY漽sR ?ۢmi9f*I4II?iM k+ݹL۷Bm%ͭvF.dMIjvolVզ' lSScM^2:Fm¹*-`WL[]n@uЗ`ڛm3?luN۷4 u=u08ɪnifO{l{m㔜bK-o1鐷Nwhl8H_3zOp8UZZ W*R k +TPPJUwf;ĨWg${z22޸6#Qg#P0j3$K Ū\2uV* pj]US:j+=`D&3JaoӶ=nczeq|?H9{?}fYk~%WV zoߺ z[_ni/9$I*,l*%ɮ^);E}wdꝬ}Sgzgjچ2 wk9DZm($)` ٫ze$0TZjW\\\?7\9J@14moRuܽWn^ǸMj w7o*8FuU +t8=QX! RU~A&x[RTmJuKo-ֶڶD[7yaռ{}~ =6F6ъ%=JNW*W_3Jg{@>^(\_\չuVeegظ$rX9U+Cun~hTۤ$_bk$jdBM랰f+x[+Iw**p>fw+*j_Nrv)gwrsJR9\eM qݭ+2wq룽eۥK잕I eV&*=#Iqq>j>z(qy%ɩr{ܫHut# !:P=0kHanFD:P{8N=_L?hr اūK8%*)ٮ~oZCK{êJVCԴg}|m{n>NQ^}R_۽篨J;w*gWv*u9]ܜ Uڽι5Os(HI#IYUM_]+m-V7zk-51wnc'b5B|%iR H%@  oЦ E;NZw#OhT\Rkx_#I)vx]rpwuJwj2U;J{Wv,]ڵLuͿP< ٯ*VySRtL2ԣg23I=zV׺%y( y: m}~Z;T۹TkG[ IDAT2tmԾV1ZU6~,`Ԃ\멽6R b 'š'Iyқ`?h}[ixZ}mnŦmg~ngn6k5)9F)JNUBB+kgjk|Cuom]]mz$)k[ܼ{f#`>a9ީK_Vι@]~ͨHQ[+i kм UI DVBSO?^oNtu}Zm,P%CU:V+I%*-Tt&Wz;Nc@V6Ov mz&+33^BLwзuykLo}=o@9̬D]xI8fQ` ǪP<@-}T$j".$IKomlZ)/B_U'j]CR|CI iu2;o[RqQUSO?ۖko&*pJTVd*ն=낙 p=olc<ǹ[]}d^eǺqkW#56A6hR ?DKo eMRTGGӆ5z\=k} _Ǒ)#fd%*3+QYILPVd虬xټ.7wMsbenJ~ܜruBWOnFlAm;_K-$I/F`$mV++joںXKoܷh\%$ N=mq w]mjڌ&*33I]ylfgmYk>fX.uNq*.v{(]aN7"`,+VZ@p ts=mo^j!^R(PcGօlS}vW\۱U-kj_:mzOmSScգWêڬdWH#Q쑤D%%s8Oh6B+lC:WvmmN=ZtC_tAwǰjծa"yUn s|q%v()p2 (ȯʈ:(je7ݴn Oz[o.>>Z}S7;E=z*G}MQllkN+޴cx#_킟?W{o@)n6#!vVecTX<.-^I2[G%$)&z v>٩ꛝ n㟻'4& G۲ת6xs׎2};*-i1Ac B]b\F5<-w-GӬ'>sĮj$6읬}S?U}SݯKQr3l7,ӗK3izM4oaXs>WII6'N@hwF#aoWzgEkk= .ZZk^zvYĜSJjUwQ LRv(v֪ ֊p>oZ3Z4_mۼ}AGӪ93Ir_H!ZjE>0-![ꡑzh*l0$ɩXIU2T`K%S>c\4/vP`~ <^7Sxl3xH.jT;|!jkEڵ6?an\an@FۉmXvk-eߠ:%c헪5~B_qdzL+2$7Mwj [3ǒBzy_W}|unzn՚-FS_ݦ:R1 hV6n۴\om s-v55Z:O+֊e9Z䖔T[v=tđ?!['U~]7wz7m$ρ+б=73'M x[lk&?\^_M}P z#mU*۾5s\,@gBA^O>ZO>\a FIIvM_G_'>E,4/Pֹi#5ە3/M:sXlTZC{i>xh1_ ~+I"ΉP⅛ɇmk+Y?PSOe_5z+ufu m-iٹiu6!>FjVW?}:=Sx_"aF1(m_ū Bvl"h>hb-?:mLfdS*[0HS R>)t6c$ȩ:ݚf w ~3iͯu߿{~Ms\qiA-lb4ɱ4D?WV٫Sa]4yM=a&M ԫ)mpz^^)>qO~]4e M=aƎ(IIr!Z z%s+w%kK64ϱ=7 p[y^׳Y[6ytm6C1JJ{{9n(^FCjOJsZ7^Yol|Qcz6UҙplFjֿ iEc5|p-zqյctA3m:N䄸fAw/&NEjjɇ4UagqqњxT?M=a=~22p4>T^pFCWBןջf+6p_]xg6/U[ka>^:5"rlgP չ&9'WKuۀԷ_oҜ֨ʲ 5yf0P1Lx*)e\޵jv22N{Pnq2X$5?c[o,qrV! WVi˦bK>`dN?{͘3X\OSujZ: ]_i祉3r{@2 zh֗^$uOOu.gpJ,tƇPBP7 .بA~q{J֩g g!ugISNVV`5+@oU P4~X~<-eF_ 7!ȍF:}{~GKJԌӇiY4L&sgphn$G~wCSPmO6h\GtsȔX]81юjoߟ:A.1h;(, ,3OK/>>ZӦ̳ģ)*_혢$%ȩ딹r> HuW@J6rqZb 6Ͷs/"֬^yoAYS()w^ ZV8!X]G_ ݎkN4m7#}Cu{mBk—_l?F l z,ÐL+vz֪nBW^!65 g Gkˠ61:L,B&W8o#& ںk߼O0AoKo#|+}hN7mѷGF3B|FsOm\:O5<UP?31(z0]:, mqomChnmnߏ@?b;͛tډocnizw֏97Z}oS1r{%c?ѿ}ݿD./?XMWJ+y y]jZ6߲MYiCz|0$~Υ14'^hRйtPw/t?9wKt^*ԭóGU}}`A)oOVTӷ|\\sHoX[_m0+sͽW7Zp6};7y\3"6"l+t/FNE..!.:Mbn]rZ:/Yzh!5 V?Ұ~ }\aBݗ]jj?zi--9Oaow^o׃ѤGQz-ԜjU\lc`W["]ut5<ƹG&iZ)ڜSokui_<^6SQQΆlPfs)F+5$!m p##0 k o\sgѲw iÓtşp'JG{Qzm7,JJ7li\k=f$ܳyh+LJ?ݨyWUOJWN)pޡ Ϛ3 ]iwEN_ _B]éGKOOvfϝҹv>_wtu3"m]w⅛ca7OV>r=ď^ M?Ciy_݄ lԥ翯ܜ8SSd@4=mʏ7ޝ220)D|[W,?61 CkDƱ\qؾDjk離>9C={%3aӈPw]|aSM̳jDee}S0ЩDluo)?2qߩ@;p8udd&OT]0"澵F'jЁO3; #7\=_ウni8: u{[]p\UW5#OLy w/.q:,VĔ_sk>ы, zh]tA\]y_?ꑿ~qr]s>f2YSPV>dcczx.jWhGxunnQzm <:6/PSSsOcI{upUv䓏늋yz4n|_& @m;tj Au=rEvo稾OO'fYt:uh߂q5vd\<-UVylsu0YʹY{ݕ5UAsMcu㹒@;ycN<1 hMBJ/<4qv5#9׵{W6g;\>x$QXS ?dN= 9׏jFfga\9()Sgkϻ<7ޚwRS0~h##3Q}bj@;QZZS?ޞJbLy[_--j =J/uzNDYYN))zki7 `RC]U+r㱧h!Z@;QQQ'Mll^;CdPJ߽81~\)_m&*MaaPRA~e9n"W h'to/6{mS4e & ! u JJTlW htg#uy0a Yժ]OPV$%jQYIDATO6zmwtu0aA/?<ྣ /ځj7s.M-wgPwՊ-yW`'mӣOMaPvt;jIojn0z7.BBtn?+DU+r47}[v7zn& "! u}=(ɓ~qUM:9*)[!Jk?V|| W`ofL{g{͇{'0a|yw/MWPGڛtBPw;x8l.EgofMdBPwY`j~ӕ*mop|L@YWg~ճW2W 떅z}DS0<Ե/0\ lT |W?g۔X4aR?& ""=PՕP%>Ꝭ7;Mn :득•XEEeygS퇏IL@EJ@yڰT_$;f]=Ph 55_NT/G(,uwfkxf+eꕹ5kP& YKml:7KTW0'!!FOwN>m(BR^j] /_~eaӵL @(fvTlV•Bpߏ~ c+=Z<]bJDҺ+?tK5L+uW׏0'!!F<1Yg3 0ѡ4_C]*+_~G9N(l kWq% ?gz t)BꎟWlJزH3OzSΜ =& 5N-.Ґ>RUU09VjjW@mmί[h_BR755N'aN[@jc_n\\ng~{>.@;b gw_z}5WCuun~Yzʴnźqf2ڑ_$ө?MڭW+ %_V,ۭK_//Uw@& J]0tյcL[Y xp8߿QWkGӷ.&hBRWt'SaaOf32@+[ ?В[wz0+B9x\\_u]]UZyU: t{IK$@BRWr=i˜|SӺ_/Uj*u*]wǚ}(]s!C$t0P 66Z~x%*}K2.بq=W;y>vź/GtPp=unOsu)VW|֎ꝬwOU}(БB:u؋Z"Tc7;+Net%j}G>ԗ?^3t2p?jwb:x':qkںTnp}7  ns۶hAϪTбSra|xڼtq:Vtb8h>)ǚnmk W ^EEnSpniMռ"@۬mtgj;pيq.}V]qչg7\=8I@HjPNS&_~eU׎}M⪡]սw,&m>VeBuK& +Mm w|6]qڰT(p8]s!ۣ@C]IZ`N9~U]iOT"V^n{^|vչGteQD=#L-*UEE-W^O;)L"$m\cv,3O7=L"}{ul*6ݧO=c4AL $^zEEUqøҟw%L/UtT kE|+IkVc_SrS}Dl<< տ}[UTԚ3hnq:ePi$@'N~M;j?A'(1Ui٥[7__jS}n3 vJE:׵ycP)\ixT\T7__=Lmfi2 \G u%J<=-T̬D 4W-|x2ZUUՙ7,x8M6I@صPWNDqqzi>cW۽LB/\w!=utq0h32msWqQ=^7>ɔT~ל7glP}z;ģ1hs:ԕ\uvϙ9G+:SF?XXoPMMcÏ˄ bPWtUK+LǞ:NGݟ;ӧ;oSee]@L:n}֛I@nrӫ2 [http://www.process-one.net/] @copyright 2012 ProcessOne @version {@vsn}, {@date} {@time} @title ejabberd Development API Documentation @doc == Introduction == TODO: Insert content from Jerome documentation. ejabberd-2.1.11/doc/api/process-one.css0000664000000000000000000000202212240230175014477 0ustar html, body { font-family: Verdana, sans-serif; color: #000; background-color: #fff; } h1 { color: #4a5389; border-bottom: solid 1px #000; } h2 { font-size: 24px; text-align: right; color: #4a5389; border-bottom: 1px solid #000; } h3 { font-size: 18px; color: #900; } h4 { font-size: 14px; color: #000; } a[href] { color: #4a5389; } a[href]:hover { background-color: #ecefff; } p, li, dd { text-align: justify; } li { margin-top: 0.3em; } li:first-child { margin-top: 0px; } blockquote { color: #555; } caption { font-style: italic; color: #009; text-align: left; margin-left: 20px; } table[border="1"] { border-collapse: collapse; margin-bottom: 1em; } table[border="1"] td { border: 1px solid #ddd; } pre, tt, code { color: #461b7e; } pre { margin:1ex 2ex; border:1px dashed lightgrey; background-color:#f9f9f9; padding:0.5ex; } pre em { font-style: normal; font-weight: bold; } dt { margin:0ex 2ex; font-weight:bold; } dd { margin:0ex 0ex 1ex 4ex; } ejabberd-2.1.11/doc/api/Makefile0000664000000000000000000000070112240230175013172 0ustar APPNAME = ejabberd VSN = $(shell sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../../src/ejabberd.app) DOCDIR=. SRCDIR=../../src .PHONY = all all: docs clean: rm -f *.html rm edoc-info rm erlang.png docs: erl -noshell -run edoc_run application \ "'$(APPNAME)'" '"$(SRCDIR)"' '[{dir,"$(DOCDIR)"},{packages, false},{todo,true},{private,true},{def,{vsn,"$(VSN)"}},{stylesheet,"process-one.css"},{overview,"$(DOCDIR)/overview.edoc"}]' -s init stop ejabberd-2.1.11/doc/release_notes_1.1.1.txt0000664000000000000000000000746312240230175015104 0ustar Release Notes ejabberd 1.1.1 28 April 2006 This document describes the main changes in ejabberd 1.1.x. This version introduce new features including support for new Jabber Enhancement Proposals and several performance improvements enabling deployments on an even larger scale than already possible. This release fix a security issue introduced in ejabberd 1.1.0. In SASL mode, anonymous login was enabled as a default. Upgrading ejabberd 1.1.0 to ejabberd 1.1.1 is highly recommended. ejabberd can be downloaded from the Process-one website: http://www.process-one.net/en/projects/ejabberd/ Detailed information can be found in the ejabberd Feature Sheet and User Guide which are available on the Process-one website: http://www.process-one.net/en/projects/ejabberd/docs.html A complete list of changes is available from: http://support.process-one.net/secure/ReleaseNote.jspa?projectId=10011&styleName=Html&version=10025 Recent changes include: New Jabber Enhancement Proposal support: - JEP-0050: Ad-Hoc Commands. - JEP-0138: Stream Compression. - JEP-0175: SASL anonymous. Anonymous login - SASL anonymous. - Anonymous login for clients that do not yet support SASL Anonymous. Relational database Support - MySQL is now fully supported through ODBC and in native mode. - Various improvements to the native database interfaces. - The migration tool can use relational databases. Multi-User Chat improvements - Logging of room discussion to text file is now supported. - Better reconfiguration support. - Security oriented fixes. - Several improvements and updates to latest JEP-0045. Performance scalability improvements for large clusters - Improved session synchronisation management between cluster nodes. - Internal architecture has been reworked to use generalize Erlang/OTP framework usage. - Speed improvement on logger. - TCP/IP packet reception change for better network throttling and regulation. As a result, these improvements will reduce load on large scale deployments. XMPP Protocol related improvements - XML stanza size can be limited. - Messages are send to all resources with the same highest priority. Documentation and Internationalization - Documentation has been extended to cover more topics. - Translations have been updated. Web interface - XHTML 1.0 compliance. Bugfixes - This release contains many bugfixes on various areas such as Publish-Subscribe, build chain, installers, IRC gateway, ejabberdctl, amongst others. - Please refer to the ChangeLog file supplied with this release regarding all improvements in ejabberd. Installation Notes Supported Erlang Version - You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.0. Installation Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC. Installers can be retrieved from: http://www.process-one.net/en/projects/ejabberd/download.html Migration Notes - Before any migration, ejabberd system and database must be properly backed up. - The database schema has not been changed comparing to version 1.0.0 and consequently it does not require any migration. References Contributed tutorials and documents of interest are: - Migration from Jabberd1.4, Jabberd2 and WPJabber to ejabberd: http://ejabberd.jabber.ru/migrate-to-ejabberd - Transport configuration for connecting to other networks: http://ejabberd.jabber.ru/tutorials-transports - Using ejabberd with MySQL native driver: http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver - Anonymous User Support: http://support.process-one.net/doc/display/MESSENGER/Anonymous+users+support - Frequently Asked Questions: http://ejabberd.jabber.ru/faq END ejabberd-2.1.11/doc/release_notes_2.0.1.txt0000664000000000000000000000141012240230175015066 0ustar Release Notes ejabberd 2.0.1 20 May 2008 ejabberd 2.0.1 is a bugfix release for ejabberd 2.0.x branch. ejabberd 2.0.1 includes 10 improvements and 32 bugfixes. A complete list of changes can be retrieved from: http://redir.process-one.net/ejabberd-2.0.1 The new code can be downloaded from ejabberd download page: http://www.process-one.net/en/projects/ejabberd/ Recent changes include: - Erlang R12 support. - Better LDAP handling. - PubSub bugfixes. - Documentation improvements. - inband registration limitation per IP. - s2s improvements. Bugs report You can officially report bugs on Process-one support site: http://support.process-one.net/ END ejabberd-2.1.11/doc/discorus.png0000664000000000000000000002350412240230175013330 0ustar PNG  IHDR-C pHYsaa?itIME&\cU IDATxM%y"? l,"DQ2A Kb;+%y00 7wEF@d8+s83=σ>Q]ݧޮ:} \_b{o̳+W~o!kq5R\qP!B~','q(Ć>z݄IQaP?tdzM>x=ѥ`jFz_?>[sӻaJ(60Q 7o }97CO~?7?zӔ~ws;žC/^f÷ވC+?y׈(4> y6gq}yZ>~~w!=:4w~-CsJږjn?cus ?kaz:\?>{7ϳp]]PR]?&4ħ~w~;?{Ҭ_?OQ^_3N|RZS[BA7ﯼ޹7ezRq7g=3e-1.ǚC_ʟHI_͏ɻ98ڍ/',2.w~߉ĸϞό*wk][׏Wgc#q!}/.C}KRxLCd\.cӿO~ڿOB_O~եBmK )mOn_)/\IbzJOATβLX˦s%T?gy/=[ }緾v a!f{ݯ¯|41ݍ͖9o?ԹsEXO NQz.??,=goyRʖ~?<4įO/rP9yJ>j^ (͉7?_as.>[=dV|~zԻeVW[{75#j6Xp R}~?kNpb@Ų?j=_ݟ_L`@4Y'wڵm?Bx_[߭f[ +k`Iυ=z"͛7W ,H@@qq!! _zEuuu@Q}a;wְuS7X8^P3OUž,5D:ȁķm /b< ~[D:ȁŅ*rCm͛7O9/3<7>sq3$1 ͉NqhKEhd"L:.`/G9TO%XQ\xn,CgtƍӋXYuܬ::iibutέg\=7y%sby`ݫqhQIm6lm ġ[gxtf9鉀|]Fjqm34yWtH =ujyy{zAϏ^؜ʳ鱲Fuzt)(uƇfϊsqk69]::hO":5Ec).3Ỏ=k(gumV]Q Ѱyhs+cENʶmrSw9ʡ5HgѰFˎMft&Z~藙:FΊ)['䄿Z~q6opʉIB~jz[F?q\zm3\(JwģPsb[r{|ԎxyR[Ctbg3DsqtWsV:S;拐a!g3vs&)Ȝ!"g[ Nw*z%!9p =N`n f>ˎpW[N-Vb͉gH9CΝ;;D*) pTr~Ub`=HSx. yxΝ:ÇU1m^}۷?[n%t޽ۜx֭^+{F)q45[1;w.//k$!&ɝ;w>SqUwݻ7:Oo:v ,<Xj7TP.Cdd-IY V{𔖑uġ>lP*%:\N^4Yaj^GGH2'ZyJDO42Obr~2b~w6qC_t.{/0#)љ3ҝwۊN_$9@Q'2;>OܫB> zONf36[tz~isv.;[IB=U]gVtb`WtbVeLmJ3zzOb!Y]CϬ1D:y%g`Y*X?N }uuhO\o޼i\c*A=6zs=%Y% q9@@@qhBcP5lS8m~7=84m Pw."OZ9Yw3C+j(OyHqh6n|s&<5ᜉ?/BWb 3)G>֑vJxZ!OϚ_I-2†Аß0g>9Ϝx&=]Eg:s}֓zu<$yچġC^w(J:cXtM/WԩWCZ+A6qv&Kxz͓֩U@qh|) VlX'Cz5\pdz, kήE*Mf%|;Z)juy\l&:7g>ւc~8t $ (ы Xˎq9~K`X'ޭ?k:ugA"|9B|.̧[p]3p%+bJɸm|8 g'@`nݺ%;.///.. O%CC3٣"*DŘTGF|h;&BI5F;:.!mͬ+fw_*s~rչjHܙ`bARͶ{f7S*WWlCN +j)cH?T>V4ڰ&m륚qH+ES i!6ʸCC;_qhI&q2Xǚ}ơUc(k6Ra7H Lyj8q*IZkslLJt9Ìѕ[w$Bl0m<-ZfT ߱jMRuĦ" 5y:rz]}k􁕓(IţMϙި8:,5<-Ws+mۭ~1ϡI$s9;s=bC3ŒOfKk+\.,!Z<87M[sm++s%.2g86} Y9rwHKu&'DR" жM-37Fmc>_'6ėS>-^$2Dn4ζ<BxQ> !klƍ~hfkUc /.///..߽yq9>C[jwYQ@@کmck3.~OdǺqsGV@=j4i"i[쥵םz[mM!r²5j՚Ó;p7ϸ_ ǚxpaj3ΖuC,}vN.(8Vܯ3_DN: n m@Xѽڶ;9p;+ X')v\k[3m]yնIIcHڹ`Nr3X+ϸFG#;Sf#`)*kwzqUVXX9P W cvk7W'Xq`G\nb+Ud\qq!ġZI>H]\cvHL~E7FCC+ej[ϑ9;5]Nc% OڂÓ+kH\0l2my6]8Nԍ687rn0&O!B>'B!G?4fX~tğŬ6Gj| uL#u%u L>V} MT!@9֜{;J IZw+Ym>Qn?;NzV$Vk`sWkzέ$ܧtOYr  YMuɿCwBUNա鵉gnaX),hYuq_VXA¸CC  j^Ӡ?^ɜ]uCE(ilqqhrڷGtlqqhr+v[Vf DTqhc΍ɱ땟;su?γ˟bw|L|884 rCC  ! 4@"׭} C u9Aݻw:ux6C{:O6CFLD>ֵc.mĪcXӳOCF% tFCġ[*X=!ckzK"csX*?4awgX;W})b @ Xqqh!@@K1/0im%g;ϗ^LZew'[)6(t!ġ^%0=+c3 IN|7!# 9M_z2͙yLsza}@#e$c,F~/Xbf-rK^\jv H6IJ#-:A(Woju&TmKxmU3'+%?=k_&n6Mj5\Vt_Ӂ+7lzU-.8Xqyw P!˸%CǭNN` /~CC[4֚OS:_g"uHuux[4h\:v~؜?H Oȹ[m+l=6euF){dڇ)S9.bX/7V:`=f((Rg%:9e,^ʅ"XrGO_β"sGқq=X>p+ !'v `+  88S]؝̀8Cq(?jsAO&r߱J~ p8|% `Eqh7 H~ 8ELr=zב@)DkOd\n!J~ C6P̸CC'@@ZD4iˑ5$S9^:XO;L!9^Cc_Cz9^qhl+}PġM+rţLvMxvҡe>mKWlq9^ġKk/:Z\W(c7} @rPIiOU&6@@:y2Ck/qqҩEf|yBk#N9**&RX"!,*ОS`{qhOT@uEDNS@hh| t͉rCCCNzz~" *Tġ%`~0.88Nhpgzڋo?馝lѡۤsmeٱ#F3KvUXʻh-:g˹Gw@?}I?/]sjuoexyDCk69MONClKu?U9k,^{Qjבߜ8T>/$nz%/[lIl8Ⴉ?ۉ1q%5GfޥW>YyжL5nKSw*kĜA^KbIuaN˺Du̓uuV\|#.-cKF{K.ի9#iW_T:r84aE ro1f|ei9g6DٶTMlq9I!(nFN;ry{ (o[y ?R]A!@`tBǻy"oĘmߧ8n=]0C(mqmfDp({]VWSmۺq9,.C:D;L׵9;gn"#6RĮO/[<3E綪W/yh]%Cv$SUYhW }h[zq\.33f!tx29^9~ Բ\9֡(dnuiUUBZGj 9過ZQz9©Cjz]s' o%vuܦ(=O>H5b7Q40EZA%zYY-k{E. 7ݥ˹n ~V-;efrs>ݢDI[xJL3 ctնpUvsI-XpBs}\m ~5Z F:p"oq Q84Uό+fs,n߇ĩSptzlgێc?AZM=:r6Q9oEr)hwХ8DyV}c79 G-d\qq!ġj{Um*F܅O_Yn~9r9&s,d!ġ-t& -Y&kki@ r.4d IsLp@[2S'JVLX"H3^B&Pe/hqf=]W@&P&lfvyn2 k~mΣQV&Pإ/T}Y!#u2dm2QB+[) @f 3 ^O۔ (W E͐4sBL߱2v@hJNom-oIDAT(C8c-5[?d2m  88k"0!XOa\4p8t~B1 ,}#qKN]Cч <,"'U&dkNPYx"\gU5|R\tbmetIz^g]m_2-؉ֶ}Z Coff̵%ڑf+ZCZ"Z}SS%N^)n_ZġfzIWnjϟjIZġuŒ9h(;wW=ѹH=qD3v~bGf׭[Olh?4䲗>oxOZv@5ښT&]su[tLZyKZ6j& 77,37hg>qzِ{+zx'R'sU㦸qhl,٬Dze5-:鵭$ǫsΕ?r(/LH!JZU]w"qP'-k [lڤ`\qq!ġݺ Y K희CYl2|:7Yv]qxV8~ދɔXZ$,5z]5d$LS+=nα(^NZZ;\Sf姓Y_e}6 Rf9<;=C2I3gcQ\WxIŇW*8T(ZabºNiM Y_|G۝ 4W͡,}Gm%Ys>)"+Ё.sBQz &- kFs kf"qc*.r-(W։Oúέ̓*t%eIe}կvى eMJV5 +'iY^ף]m3 O*£G~a^ΐζsp杍 /.///..߽yq9`V%l8:9 wm7X9/2d}E!!XݧE|홮g 6ښtFC*맩>iuNm>>۩0.8E'񬶵^:ZRE{X[bsѧfhV'wSO<|mGrΨ3zgT`b'6V۞Xd4_H Oh#jW"gY[&bgv*8l>;s4=O9GlfKDk]PWeNٮ ġ] S۱rڂɔz^r>۷oo?gmk>T SqtƕnݺU_fKZnzv_E?BPX 1CWjΜ D;gY^}oWS祗^j5+eWܠ֯o|`s֭Z:՜~&+*Am.QPZ[o7WFvќ%vr_&V^ŐcvNpwr0~(gYӗQ|8wSvm7Iy !0qqq!!\_vU。6mB~F_ӬLݘB/}_|1њԍxOff1`?KWGIENDB`ejabberd-2.1.11/doc/release_notes_2.0.0.txt0000664000000000000000000001621412240230175015075 0ustar Release Notes ejabberd 2.0.0 21 February 2008 ejabberd 2.0.0 is a major new version for ejabberd adding plenty of new features, performance and scalability improvements and architectural changes. ejabberd 2.0.0 includes more than 200 improvements over ejabberd 1.1.x. A complete list of changes can be retrieved from: http://redir.process-one.net/ejabberd-2.0.0 The new code can be downloaded from ejabberd downloads page: http://www.process-one.net/en/ejabberd/ Recent changes include: * Clustering and Architecture - New front-end and back-end cluster architecture for better scalability and robustness. Back-end nodes are able to run a fully fault-tolerant XMPP router and services, but you can now deploy many front-end nodes to share the load without needing to synchronize any state with the back-ends. - All components now run in cluster mode (For example, Multi-User chat service and file transfer proxy). - New load balancing algorithm to support Multi-User chat and gateways clustering. More generally it supports any external component load balancing. - ejabberd watchdog to receive warning on suspicious resources consumption. - Traffic shapers are now supported on components. This protect ejabberd from components and gateways abuses. * Publish and Subscribe - Complete rewrite of the PubSub module. The new PubSub module is plugin-based, allowing developers to create new nodes type. Any application can be plugged to ejabberd and can provide rich presence as a pubsub plugin. - Personal Eventing via Pubsub support (XEP-0163). This module is implemented as a PubSub service. It supports user mood (XEP-107), User Tune (XEP-118), user location (XEP-0080) or user avatar (XEP-0084) for example. * Server to Server (s2s) - More robust code with connection timeout implementation. - Support for multiple s2s connections per domain. - s2s whitelist and blacklist support. - s2s retrial interval. * LDAP - Many enterprise-class enhancements such as better behaviour under heavy load. - Support for LDAP servers pool. - Simplified use of virtual hosting with LDAP with domain substitution in config. - Ability to match on several userid attributes. * Multi-User Chat - Clustering and load balancing support. - Ability to define default room configuration in ejabberd config file. - Many anti abuse features have been added: . New ACL to limit the creation of persistent room to authorized users. . Ability to define the maximum number of users per room. . Limitation of the rate of message and presence packets. . Limitation of the maximum number of room a user can join at the same time. * File Transfer - XEP-0065 - Proxy65 file transfer proxy. The proxy can run in cluster mode. * Authentication - PAM (Pluggable Authentication Modules) support on *nix systems. - External Authentication protocol is now fully documented. * Web Client Support - XEP-0124 - BOSH support: BOSH (Bidirectional-streams Over Synchronous HTTP) was formerly known as "HTTP binding". It provides an efficient alternative to HTTP polling for scalable Web based chat solutions. - HTTP module can now serve static documents (with mod_http_fileserver). It is needed for high-performance Web 2.0 chat / IM application. System administrators can now avoid using a proxy (like Apache) that handles much less simultaneous than ejabberd HTTP module. - Added limitations enforcement on HTTP poll and HTTP bind modules (bandwidth, packet size). * System Administration - XEP-0133 - Service administration support. System administrators can now perform lot of ejabberd related admin tasks from their XMPP client, through adhoc commands. - Dynamic log levels: Improved logging with more log levels. You can now change the loglevel at run time. No performance penalty is involved when less verbose levels are used. - The ejabberdctl command-line administration script now can start and stop ejabberd. It also includes other useful options. * Localization - ejabberd is now translated to 24 languages: Catalan, Chinese, Czech, Dutch, English, Esperanto, French, Galician, German, Italian, Japanese, Norwegian, Polish, Portuguese, Portuguese (Brazil), Russian, Slovak, Spanish, Swedish, Thai, Turkish, Ukrainian, Vietnamese, Walloon. * Build and Installer - Many launch script improvements. - New translations. The binary installer is now available in Chinese, Dutch, English, French, German, Spanish, Russian. - Makefile now implements uninstall command. - Full MacOSX compliance in Makefile. - Configure script is clever at finding libraries in unusual places. * Development API - Several hooks have been added for module developers (most notably presence related hooks). - HTTP request handler to write HTTP based plugins. - Manage connections IP address. * Bugfixes - ejabberd 2.0.0 also fixes numerous small bugs :) Read the full changelog for details. Important Note: - Since this release, ejabberd requires Erlang R10B-5 or higher. R11B-5 is the recommended version. R12 is not yet officially supported, and is not recommended for production servers. Upgrading From ejabberd 1.x: - If you upgrade from a version older than 1.1.4, please check the Release Notes of the intermediate versions for additional information about database or configuration changes. - The database schemas didn't change since ejabberd 1.1.4. Of course, you are encouraged to make a database backup of your SQL database, or your Mnesia spool directory before upgrading ejabberd. - The ejabberdctl command line administration script is improved in ejabberd 2.0.0, and now it can start and stop ejabberd. If you already wrote your own start script for ejabberd 1.x, you can continue using it, or try ejabberdctl. For your convenience, the ejabberd Guide describes all the ejabberd and Erlang options used by ejabberdctl. - The example ejabberd.cfg file has been reorganized, but its format and syntax rules are the same. So, you can continue using your ejabberd.cfg file from 1.x if you want. The most important changes are described now. - The 'ssl' option is no longer available in the listening ports. For legacy SSL encryption use the option 'tls'. For STARTTLS encryption as defined in RFC 3920 XMPP-CORE use the option 'starttls'. Check the ejabberd Guide for more information about configuring listening ports. - The options 'welcome_message' and 'registration_watchers' are now options of the module mod_register. Check in the ejabberd Guide how to configure that module. - To enable PEP support in mod_pubsub, you need to enable it in the mod_pubsub configuration, and also enable the new module mod_caps. Check the section about mod_pubsub in the ejabberd Guide. - Other new features and improvements also require changes in the ejabberd.cfg, like mod_http_bind, mod_http_fileserver, mod_proxy65, loglevel, pam_service, and watchdog_admins. Search for those words in the ejabberd Guide and the example ejabberd.cfg. Bug Reports You can officially report bugs on Process-one support site: https://support.process-one.net/ ENDejabberd-2.1.11/doc/release_notes_1.1.4.txt0000664000000000000000000000150012240230175015071 0ustar Release Notes ejabberd 1.1.4 3 september 2007 ejabberd 1.1.4 is a bugfix release for ejabberd 1.1.x branch. ejabberd 1.1.4 includes 10 improvements. A complete list of changes can be retrieved from: http://redir.process-one.net/ejabberd-1.1.4 The new code can be downloaded from ejabberd download page: http://www.process-one.net/en/projects/ejabberd/ Recent changes include: - Better LDAP support. - Support for UTF-8 with MySQL 5. - Roster migration script bugfixes. - Performance improvements on user removal. - Traffic shapers bugfix. - Configuration: host value is now case insensitive. - Build: ejabberd.cfg file is not overwritten with 'make install' command. Bugs report You can officially report bugs on Process-one support site: http://support.process-one.net/ END ejabberd-2.1.11/doc/release_notes_2.1.10.txt0000664000000000000000000000242612240230175015157 0ustar Release Notes ejabberd 2.1.10 ejabberd 2.1.10 includes a few bugfixes and improvements. Read more details about the changes in: http://redir.process-one.net/ejabberd-2.1.10 Download the source code and installers from: http://www.process-one.net/en/ejabberd/ The major changes are: * Erlang/OTP compatibility - Support Erlang/OTP R15B regexp and drivers (EJAB-1521) - Fix modules update in R14B04 and higher - Fix modules update of stripped beams (EJAB-1520) * XMPP Core - Fix presence problem in C2S after first unavailable (EJAB-1466) - Fix bug on S2S shaper when TLS is used - Prevent overload of incoming S2S connections * XEPs - BOSH: Get rid of useless mnesia transaction (EJAB-1502) - MUC: Don't reveal invitee resource when room informs invitor - Privacy: Activate "Blocked Contacts" to current c2s connection (EJAB-1519) - Privacy: Always allow packets from user's server and bare jid (EJAB-1441) - Pubsub: Add hooks for node creation/deletion (EJAB-1470) - Shared Rosters: support groupname@vhost in Displayed Groups (EJAB-506) - Vcard: Fix error when lowercasing some search results (EJAB-1490) Bug reports You can officially report bugs on ProcessOne support site: http://support.process-one.net/ ejabberd-2.1.11/doc/introduction.tex0000664000000000000000000001355412240230175014236 0ustar \chapter{Introduction} \label{intro} %% TODO: improve the feature sheet with a nice table to highlight new features. \quoting{I just tried out ejabberd and was impressed both by ejabberd itself and the language it is written in, Erlang. --- Joeri} %ejabberd is a free and open source instant messaging server written in Erlang. ejabberd is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication (Jabber/XMPP). \ejabberd{} is a \marking{free and open source} instant messaging server written in \footahref{http://www.erlang.org/}{Erlang/OTP}. \ejabberd{} is \marking{cross-platform}, distributed, fault-tolerant, and based on open standards to achieve real-time communication. \ejabberd{} is designed to be a \marking{rock-solid and feature rich} XMPP server. \ejabberd{} is suitable for small deployments, whether they need to be \marking{scalable} or not, as well as extremely big deployments. %\subsection{Layout with example deployment (title needs a better name)} %\label{layout} %In this section there will be a graphical overview like these:\\ %\verb|http://www.tipic.com/var/timp/timp_dep.gif| \\ %\verb|http://www.jabber.com/images/jabber_Com_Platform.jpg| \\ %\verb|http://www.antepo.com/files/OPN45systemdatasheet.pdf| \\ %A page full with names of Jabber client that are known to work with ejabberd. \begin{tiny}tiny font\end{tiny} %\subsection{Try It Today} %\label{trytoday} %(Not sure if I will include/finish this section for the next version.) %\begin{itemize} %\item Erlang REPOS %\item Packages in distributions %\item Windows binary %\item source tar.gz %\item Migration from Jabberd14 (and so also Jabberd2 because you can migrate from version 2 back to 14) and Jabber Inc. XCP possible. %\end{itemize} \newpage \section{Key Features} \label{keyfeatures} \ind{features!key features} \quoting{Erlang seems to be tailor-made for writing stable, robust servers. --- Peter Saint-Andr\'e, Executive Director of the Jabber Software Foundation} \ejabberd{} is: \begin{itemize} \item \marking{Cross-platform:} \ejabberd{} runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD. \item \marking{Distributed:} You can run \ejabberd{} on a cluster of machines and all of them will serve the same \Jabber{} domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users. \item \marking{Fault-tolerant:} You can deploy an \ejabberd{} cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced `on the fly'. \item \marking{Administrator Friendly:} \ejabberd{} is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include: \begin{itemize} \item Comprehensive documentation. \item Straightforward installers for Linux, Mac OS X, and Windows. %%\improved{} \item Web Administration. \item Shared Roster Groups. \item Command line administration tool. %%\improved{} \item Can integrate with existing authentication mechanisms. \item Capability to send announce messages. \end{itemize} \item \marking{Internationalized:} \ejabberd{} leads in internationalization. Hence it is very well suited in a globalized world. Related features are: \begin{itemize} \item Translated to 25 languages. %%\improved{} \item Support for \footahref{http://www.ietf.org/rfc/rfc3490.txt}{IDNA}. \end{itemize} \item \marking{Open Standards:} \ejabberd{} is the first Open Source Jabber server claiming to fully comply to the XMPP standard. \begin{itemize} \item Fully XMPP compliant. \item XML-based protocol. \item \footahref{http://www.ejabberd.im/protocols}{Many protocols supported}. \end{itemize} \end{itemize} \newpage \section{Additional Features} \label{addfeatures} \ind{features!additional features} \quoting{ejabberd is making inroads to solving the "buggy incomplete server" problem --- Justin Karneges, Founder of the Psi and the Delta projects} Moreover, \ejabberd{} comes with a wide range of other state-of-the-art features: \begin{itemize} \item Modular \begin{itemize} \item Load only the modules you want. \item Extend \ejabberd{} with your own custom modules. \end{itemize} \item Security \begin{itemize} \item SASL and STARTTLS for c2s and s2s connections. \item STARTTLS and Dialback s2s connections. \item Web Admin accessible via HTTPS secure access. \end{itemize} \item Databases \begin{itemize} \item Internal database for fast deployment (Mnesia). \item Native MySQL support. \item Native PostgreSQL support. \item ODBC data storage support. \item Microsoft SQL Server support. %%\new{} \end{itemize} \item Authentication \begin{itemize} \item Internal Authentication. \item PAM, LDAP and ODBC. %%\improved{} \item External Authentication script. \end{itemize} \item Others \begin{itemize} \item Support for virtual hosting. \item Compressing XML streams with Stream Compression (\xepref{0138}). \item Statistics via Statistics Gathering (\xepref{0039}). \item IPv6 support both for c2s and s2s connections. \item \txepref{0045}{Multi-User Chat} module with support for clustering and HTML logging. %%\improved{} \item Users Directory based on users vCards. \item \txepref{0060}{Publish-Subscribe} component with support for \txepref{0163}{Personal Eventing via Pubsub}. \item Support for web clients: \txepref{0025}{HTTP Polling} and \txepref{0206}{HTTP Binding (BOSH)} services. \item IRC transport. \item Component support: interface with networks such as AIM, ICQ and MSN installing special tranports. \end{itemize} \end{itemize} ejabberd-2.1.11/doc/release_notes_2.1.8.txt0000664000000000000000000000075112240230175015105 0ustar Release Notes ejabberd 2.1.8 ejabberd 2.1.8 is the ninth release in ejabberd 2.1.x branch, and includes a PubSub regression bugfix. Download the source code and installers from: http://www.process-one.net/en/ejabberd/ The change is: - Fix issue on PubSub preventing publication of items (EJAB-1457) Bug reports You can officially report bugs on ProcessOne support site: http://support.process-one.net/ ejabberd-2.1.11/doc/release_notes_2.1.7.txt0000664000000000000000000001012412240230175015077 0ustar Release Notes ejabberd 2.1.7 ejabberd 2.1.7 is the eighth release in ejabberd 2.1.x branch, and includes a lot of bugfixes and improvements. Read more details about the changes in: http://redir.process-one.net/ejabberd-2.1.7 Download the source code and installers from: http://www.process-one.net/en/ejabberd/ The changes are: * BOSH and Web - Clarify error message when BOSH query is sent to non-running module - Keep the order of stanzas when BOSH sends several (EJAB-1374) - Show configuration for HTTPS http_bind - Support as read-only HTTP method not only GET, also HEAD - The responses to HEAD must have empty Body * CAPTCHA - If the port number isn't listener, then specify the protocol (EJAB-1418) - New CAPTCHA limit - New CAPTCHA whitelist support - Only check system at startup if option is enabled - Provide HTTPS URL in CAPTCHA form when listener has 'tls' option (EJAB-1406) - Show captcha_limit option in the example config - Support more captcha_host value formats (EJAB-1418) - Throw error when captcha fails at server start, not later at runtime - captcha_host must have the port number to get protocol (EJAB-1418) * Core ejabberd - Disable all entity expansions (EJAB-1451) - Do not accept XML with undefined prefixes (EJAB-680) - Make jlib:ip_to_list safe to use - Make sure 'closed' event is correctly processed on every state - New route_iq/5 accepting Timeout (EJAB-1398) - Take into consideration internal queue length when sorting processes queues - Use route instead of send_element to go through standard workflow * Erlang/OTP compatibility - Remove Type and Spec, backport list comprehensions, so R12B-5 can compile - Tweak pg2_backport.erl to work with Erlang older than R13A (EJAB-1349) * ODBC - Don't let presence-in privacy rule block a presence subscription (EJAB-255) - Escape user input in mod_privacy_odbc (EJAB-1442) - Try to improve support for roster_version in MSSQL (EJAB-1437) * Pubsub/PEP/Caps - Apply filtered notification to PEP last items (EJAB-1456) - Fix empty pubsub payload check - Owner can delete any items from its own node (EJAB-1445) - Pubsub node maxitem forced to 0 if non persistent node (EJAB-1434) - Reorganize the push_item function, and handle version not_found (EJAB-1420) * Scripts - ejabberd.init: Several fixes and improvements - ejabberdctl: Escape output from ctlexec() to erl script (EJAB-1399) - ejabberdctl: Fix bashism and mimic master branch (EJAB-1404) - ejabberdctl: Fix space between INET_DIST_INTERFACE (EJAB-1416) - ejabberdctl: New DIST_USE_INTERFACE restricts IP of erlang listen (EJAB-1404) - ejabberdctl: New ERL_EPMD_ADDRESS that works since Erlang/OTP R14B03 - extauth: Fix delayed response of timeout was reused for next login (EJAB-1385) - extauth: Forward old messages to newly spawned extauth process (EJAB-1385) - extauth: If script crashes, ejabberd should restart it (EJAB-1428) * XEP support - mod_blocking: New XEP-0191 Simple Communications Blocking (EJAB-695) - No need to inform that XEP-0237 is optional; clarified in XEP version 1.2 * Miscellanea: - If a module start fails during server start, stop erlang (EJAB-1446) - New Indonesian translation (EJAB-1407) - LDAP: Note that ejabberd works with CGP LDAP server - S2S: Handle Tigase's unexpected version=1.0 (EJAB-1379) - mod_irc: Send presence unavailable to the departing occupant (EJAB-1417) - mod_last: Allow user to query his own Last activity - mod_muc: Do not decrease MUC admin's role/affiliation - mod_muc: Send jid attribute when occupant is banned (EJAB-1432) - mod_offline: Change c2s state before offline messages resending - mod_ping: Use iqdisc no_queue by default (EJAB-1435) - mod_pres_counter: Prevent subscription flood (EJAB-1388) - mod_register Access now also controls account unregistrations - mod_register: Clarify more the expected content of welcome_message option - mod_shared_roster: Fix support for anonymous accounts in @all@ (EJAB-1264) - mod_shared_roster: New @online@ directive (EJAB-1391) Bug reports You can officially report bugs on ProcessOne support site: http://support.process-one.net/ ejabberd-2.1.11/doc/release_notes_1.1.2.txt0000664000000000000000000000666012240230175015103 0ustar Release Notes ejabberd 1.1.2 27 September 2006 This document describes the main changes in ejabberd 1.1.2. This version is a major improvement over ejabberd 1.1.1, improving the overall behaviour of the server in many areas. Users of ejabberd 1.1.1 should upgrade to this new release for improved robustness and compliance. ejabberd can be downloaded from the Process-one website: http://www.process-one.net/en/projects/ejabberd/ Detailed information can be found in the Feature Sheet and in the Installation and Operation Guide which are both available on the Process-one website: http://www.process-one.net/en/projects/ejabberd/docs.html ejabberd includes 44 improvements. A complete list of changes can be retrieved from: http://redir.process-one.net/ejabberd-1.1.2 Recent changes include: LDAP Improvements - Major improvements have been made on the LDAP module. It is now more flexible and more robust. HTTP Polling Fixes - The HTTP polling modules have been fixed and improved: the connections are closed properly and polled messages cannot be lost anymore. Roster Management Improvement - Roster management improvements increase reliability, especially in cases where users are on different servers. - Shared rosters are more reliable. Improved Robustness - It is now possible to limit the number of opened connections for a single user. Relational databases - Database support: Microsoft SQL Server is now officially supported in ODBC mode. Publish-Subscribe Improvement - Restricting node creation with a dedicated ACL rule is now possible. Localization - A Czech translation has been added. - Translations have been updated. Binary Installer - New binary installer for Windows including all requirements. - Improved installers for Linux and MacOSX (PowerPC) XMPP Compliancy - Some protocol compliance fix have been added, after the Portland XMPP Interop Meeting in July. Miscelanous - MUC have been improved (logging rendering). - The command line tool ejabberdctl has been improved. - The build chain has been improved, including MacOSX support. - The documentation has been improved and updated to describe the new features. Bugfixes - Anonymous login bugfixes. - Please refer to the ChangeLog file supplied with this release regarding all improvements in ejabberd. Installation Notes Supported Erlang Version - You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.2. - The recommanded version is Erlang/OTP R10B-10. - Erlang/OTP R11B has not yet been fully certified for ejabberd. Installation Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC. They can be retrieved from: http://www.process-one.net/en/projects/ejabberd/download.html Migration Notes - Before any migration, ejabberd system and database must be properly backed up. - The relational database schema has changed between version 1.1.1 and 1.1.2. An "askmessage" column needs to be added in the "rosterusers" table to perform the migration. References Contributed tutorials and documents of interest are: - Migration from other XMPP servers to ejabberd: http://ejabberd.jabber.ru/migrate-to-ejabberd - Transport configuration for connecting to other networks: http://ejabberd.jabber.ru/tutorials-transports - Frequently Asked Questions: http://ejabberd.jabber.ru/faq END ejabberd-2.1.11/doc/release_notes_1.1.3.txt0000664000000000000000000000054112240230175015074 0ustar Release Notes ejabberd 1.1.3 2 February 2007 ejabberd 1.1.3 is a security fix release for ejabberd roster ODBC module. The upgrade is only necessary if you are using ejabberd with the mod_roster_odbc. The new code can be downloaded from ejabberd download page: http://www.process-one.net/en/projects/ejabberd/ END ejabberd-2.1.11/doc/Makefile0000664000000000000000000000300112240230175012415 0ustar # $Id$ SHELL = /bin/bash CONTRIBUTED_MODULES = "" #ifeq ($(shell ls mod_http_bind.tex),mod_http_bind.tex) # CONTRIBUTED_MODULES += "\\n\\setboolean{modhttpbind}{true}" #endif all: release pdf html release: @echo "Notes for the releaser:" @echo "* Do not forget to add a link to the release notes in guide.tex" @echo "* Do not forget to update the version number in src/ejabberd.app!" @echo "* Do not forget to update the features in introduction.tex (including \new{} and \improved{} tags)." @echo "Press any key to continue" ##@read foo @echo "% ejabberd version (automatically generated)." > version.tex @echo "\newcommand{\version}{"`sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../src/ejabberd.app`"}" >> version.tex @echo -n "% Contributed modules (automatically generated)." > contributed_modules.tex @echo -e "$(CONTRIBUTED_MODULES)" >> contributed_modules.tex html: guide.html dev.html features.html pdf: guide.pdf features.pdf clean: rm -f *.aux rm -f *.haux rm -f *.htoc rm -f *.idx rm -f *.ilg rm -f *.ind rm -f *.log rm -f *.out rm -f *.pdf rm -f *.toc [ ! -f contributed_modules.tex ] || rm contributed_modules.tex distclean: clean rm -f *.html guide.html: guide.tex hevea -fix -pedantic guide.tex dev.html: dev.tex hevea -fix -pedantic dev.tex features.html: features.tex hevea -fix -pedantic features.tex guide.pdf: guide.tex pdflatex guide.tex pdflatex guide.tex pdflatex guide.tex makeindex guide.idx pdflatex guide.tex features.pdf: features.tex pdflatex features.tex ejabberd-2.1.11/doc/msrl-roster-flat.png0000664000000000000000000005207512240230175014717 0ustar PNG  IHDR2sRGBbKGDC pHYst$qtIME 2ttEXtCommentCreated with GIMPW IDATxw\TW) ,QA*E5QQ,Dӳ$d7dnL䗞&M5M  4XJ)L?*EL@===e=W&ID C }>MHoOˣ7LҧQL JM HV35ZaƖ0\uZluUXk+U 2RQOl{ocV[V]{觃%}EQPt*<§ [f܋T^Ыxaf-XȸMwlrz1U⤖c4.ׄۗ U8uZ**x VQ (6с~TgntGFjj\v [8kG4͊`Cu=\8(-$5{siTdfAbү%C]@H_—ގ$ٰZ̘z4]Ō$`<PV֘٬<`c=F֧YOtl1T8_VH bFvw+͊X0vXcw:?],?Y#6:/lX,L=,łfz^$MNy۴d2,k3FF tGvV 5֤Вni9SwcRSAɁrTZ< ǟb0]ݧZkGqt[=A9[=ɛ=!&hmޯ'zkChY[-i[:cy]Mw{lg*0nkvANim6k]{s6֥YSP]I*J9 Fe7| o2!&<}KzΤ<`^w?5dw=GV>vctTQDY6ƣsd1L )JG=YVMj~~ygdEn`0D92EG(ۿ}+U^t3I"vsky]p8^f_4ֿf#43gRmCS2$dPx\Ɛ0F q͓=OƊ7F6jnC?rR$'xgcy]o j-HF*/7o 4\ƈк:1{HiF[[(xȀU{X0F,eBM8}&F_,؎LӉVxr5MD4ax8)I6pMgu=U{x!GfG AW}_MFO⢷^Ɩj4j1sU:n;i`~<{CK7 A\?ѻZiMD___G퉼s GVn<}s͢܌I\!N̜pu."1Jf̣O=gE&dYN&b:A݊WsS<'+EAq8?'<2V#lTG b6d%=;*12EN{1멩pGu`6w1;5ߖ 몝iwcZ35L2TC8gRc39e-hlE_Q| IfI-7,vxSe j7o BPEpl2gET܋A_}NMde>u^{9~-Z?Fs#O2ƿr)/#aN7i_gv!u#vVN񸀋䥥 dmw2r承<3+^íOG{O<qsVofHg<5tssrĔ"ԮDM>Sk-=+(>'~:5~>xS{(;δkg3R6mH`ZSs&KY%6кz]炙cAvgPkΩL&CvjrVi=V&Pw;w] Yzf'a_s>a1o'dNNɐ:2Lfd2؟~ԛq]%H6S]~Pi1)/VPUgO~^ybw}EqfJ{+>\G]E)_ӭx23;a<6J,w2Cqm9G婭 I嗑$6323"dYvz }1vOhXʶv.vI;O0X ;m r y;Wr\ބ$/9ܿ>I3HWƝ#M7t~R^ [ZFͩ|5b4YqqT0lͬpaɐ2~sEIAdUw#K6jk+T|7qtW"oYh/?.knƟ_P˹+2ٱ!rW{#^q`he2܀oXY;ýv]h); JjڽowPJך Kn#S ǸC|ddU $ z( }_0ƕc)LPodrSi*aT sF7_rU;ҙ& 8Ȉ'ª¬. qWPȻer8UR^kfk;eV!˘1 ?u&H8ZPm޷U: vnƛ kCZzdzȩ@&9`2+wTVgWQU[VC cJ&0/iÝ:M+'zó9]`w% y`*]Ξ<>jJ9=UPl~t3T rSv~ |/J-ź|mɈV#ˑr7'u1ph23^vq/yXtܤ^Kj36d^$Ν+/"-}of3/⾻BW^s˱~nmKbHϞ7xv!Ln/mݖŅ;܆+RRf/£2>"O>Sau<Ÿ(tocڌXBƄƅd;$^sʨe}(o7ML:s-G)3bvf"Oxk翌38-+;Gur9i;wu)?G3X[vlKFVoßz9{wەƲ/>cgGW_oE`r7yC2Y;~N\GqII|=JJΐ?t1o~`| 0sƵoGđ@G\2ju;[W~9|RZݻ6~%IQZZ[~c{1{>r}2Ys#nxz?KM?/_?4ɑx͛g9W~o]UԩS:ryqsb9t8Vs٧Tֵؚڟulп~sϝ8v/Gy;[W~y|n^n]s-Gc<W*֡hhv 7S] oӓБ|H֔T n킫'~~>>^mTPPwVA*y7{;]Njtgu~9kg4:s<<#y a6Ͼ|Rrf͛;_{sQVVW^RxϋoY;NaX8|!;;Ō$IXmK6n=Gl7!!$H\|Peb髯^,,n,eee˯17.eQE#'7YxOQ{;[GMӺ<>wn":|4sα1ޜ3ٴB۔ٻ7=?<~Nf|n"#›wqa8߸0N33f1}*)NĿxK*˯%.j3l- Y #=С,f{@{G`ff-`@~<Ý.ێs'7ݲаVF(o7M9wXZ2L57WW݃M)mMmF}@sϱC{qjͅ9whWIeЭ2eҙ|u5{˄(tC꽢O =K=FWb,*ChNy٢d+a!c;'1Di W5U]WB@ BW3*#*c!B[l[nW36 gayڌyw}~~CxwSUU@Ԏ۷ڑ}Ԏ mfbiv[SVZN֙>05& xzz$I$<==ILԘ$q6oJ$d.LJU#Grf zFOE>ɧ ~o7%5YΤ.o,[5-^Fax~C=*bʤHI$ifm%&n<==$)III1-7/sx}cG%@o%@LҪU?Htu ʊsԯj2믓iNԟƭ[wy[dСCӻT&b[S]ۗ&M)ujL?5&oY… INN 99 7:72hРVO:*G))\s <sx~4P'88-[)((ׇ|jk ,w߯ 6v&7\ʶmlڴ.5k2gl h4-%Mw@^~>wy;jvn}W cǎO?o o~23nBɹr&NhEu $KZ  *z J/эI˖H/PraO6{dw{usAI޶www*5O#={hH@"&S\RRjr z<"q&yg8|껭8{_X!0Ǜذ0LO#ƏUcDa2ߟlrss]t w)(J$7/ѡlСänWWWL&4t=<)y K/fmފ@iMF$- -VnslF*yx2{0E: f L'';G 6" jRobqwwfGRڍ?۸xy bVSvv D3lf6|.V2]S,W<^'& .}7[ppp@P9w[211?q1p@Z-FMCu%gJȐnNڎ̞= __|}}={)) -5oRM[BLv܅R`Μ.$55q-yz͍WAonї,C掱]8QPg;n&4EG.IWY=[JYy9$J?OOOV3 k~`??VEݲޕ.dأCvѯ_#CX&NS:|~+Lfo}Ӳ&!!!Iп_?bƏ@.B\~ajM ;OIP* U99?~}+_ 0`@O"߾//?߾4%Gtۺb?#8;; E(z}$2"7RXXj /IQUU׈"-/App&׬m]ppe7g λiSEm\C~%r[n>zL/?WzIxGؿ??=Y888pB-ZJj֬fXƎO``ޙt[SO?@R{G.y"O M˜@^ BʡZ5$6AÆvNLDo1Di bL/@ jxi+W/CO+.B;Y}gz4#o+V6nXx󭷩1vɇ,2$3%=}_^TI/Y}udffa4^XI+j}Vv6&:Ӫ;_y~?JJ\t_Vv6} /!h3^EE/_ɿ^?^y_|m|t1ovn6f(:l^PX$I6YC=6d|m^}uW{e NDŽ= h'/?Z]IX{SY9g3lXFm);U_AlLn~VmRٴi3-,^fVkܸ9 >U:['SʩSb08s MݞFqq ^T*7žGWՑҷ;N8Aڎ4oHۑFƱ jjvEEE92.Yٱt:T*tچBZ\\\7x7 </ŐӢױg^sˢEHP‘#GϷL2fi7t#)ٺujY3msB~NJfZ;wfQx{{]ѣXv-Q[[uX,: _qWg}c$`̘1 LmI帹Fɓ.>I]bCcx&/OW^{0ݒ_R>\EUWG>77 :t(ݳ"V+bOƱc &%GfLx{yshF0?;vl6c0X~}U)--f!I6^jATT*$aVqt:wޱ=~4I `۶0^[FBz˱l9sUیQLh7\t8:>. Q˜12[nn 7y:=ysu55F23f G9X,V@@dD$ NŰa8p//otNg^bb6H#qsSB))t:"#8v=~g""Lup@-K"EAt\βLz`,F'`/7ت}o.oG!_oJM$j}k$!$$a"jv4Ax?>q(n0e?/&tp(y &S[g%x2nRT' !i1&czX|QDQ[[\&j'Jd255F9?X&5fj&35-`^9b K]]]1Q(+/g℉h4*++HX@º*++PL `0P(2K+qP*nLb]DzGee {ٳ _[ L-V9]| vكFFR11J%V%L8x6QWWs>GؘHmm=x\T{r x<xƗiy蝝>,\Mnn.z :< %5R3:4]:tTTTʔф'%oa 8[4j쥥 $5dmtmS72OxHUAlA#ɺuky=@aOVzS=szwwwlVܼ|*!#llٺ[@N.fqpp (!jFD^Жm6f ˮL2< hC峋E/! <9P(}NL&cjL O`C VFfQScP]AqƄ:2[cg׷vG__fϞEJJ*AAxgyӖ3;wT(3g IM k~\K^~>zys4W( onї,C掱]8QPg;n&4EG.IWY=[JYy9$J?OOOV3{ʒx[vٻ҅l6{asHܴ.70rd ɼ<~JXǃ/q"-WZ$$$$ GPȑ/lWM):3ac>iRJʾ?''OfOBW i+^À?u i m]"Wo),lxl /IQUU׈"-/App&׬m]ppe7g λiSEm\Cow H> 3%2"$Ԕ\_!CoؘHF1BBF0k /-}9cٞ@~̟7ϾGel6eLf$nlj5Vd>f#::~imqt1/_ATT'v[DEFc'ޮ=-IQQ!޾j2d`/Vk/u7q -OW1Zv܅`g0ͦt%@ǎgc&neQUolJzIX'lʵ^c]wގZf$[=wF4K}Rؘ-̎m)=[o۶mkS'33UYY]s0|Nߒ l__󩭭w߯ 6v&7\ʶmlڴοzmky[RTT}ރSivžwkjd mG7n` H#X55KN?~jbgl&xG2s8i8;91k 9,Xt:*ȈpKڴqAf͚NCV3}4o:LlLt:3gJ#IW={[- D&mAdDxYo2x0h4M!''~V[2sƵvw&ͮі^$rss/oo jR@ 3pttoPM puuhl~qt4;Mq>TWW7ՒR֯n ٹs7cF۫ŲcbԨPnƑ#G)))ols$K0m\klݸ>"zIرs0fl777=yŧ<)[3f4Z#W`y񬓓Ǒn;^ٙ [ hdx͍k&Fc _~5j&cT*>׬eԘ6V?Zd7޼(q4fɆϘrD&ӕfD0fhxnɉ/L~l)L*իCHСCh4ү'$sgpl)aԩ1J{RT$`0Iɓd>'HɓaE5[#콳3߾e?ertߒys璸i3t:"#9z4>uj V +;n_Q!l:ZR&c3L ?XlɌdjD$ M0S̏ s˜2lxzz{"#]'u{*HZi l)jGװ;#%,'&b$G3YX(r3~)8~GוLkc cVTTd³'{P__^JܜEw zZJKD-*‚|3TcDAP/vx IV$E;{jC?j8m&,߰[B`X٩oT5..zfjs墖 z e;g-ѻb0TP(9W^ h4TVV.u TVVV`@PRe0!jWTݘĺl!,%AZdgAx7>S<4m[pwwGRs42޳FlO!bb8%%(J+K0.3q!7m}Ç11:{!pP? 7Cxa7aa|F@>nىe?9׻RRSQ*x Hn^>CCqquޡCII#I[Xx[4 uA#$!I6 -VnslF*yx2{0E: f L[ |ڬԛ걘-zݱY%rQTvnOeIDAT6n^^9}UdYuuuq ]-%x͆lfok%5r|~bڐ!xbKOο E~E/ɘ'Gբhl1TWP\r1 VٳׇٳgJPp{+-E޴i+La]( ̙}BRSÚג^gܸvo\9-};b1vK' lͤV|Ãy(%}!3;gK)+/G$\]I 7RRr~xʒx[vٻ҅l6{asHܴ.70rd ɼ<~<<2#ݝtnB I;Aԙ]cppkaםqreAXA@qeÝ]u44p<ӕ޷{ߪz7ldB7 $-wu0 9)!tdld:n1N]_AX,t5k?CO/o6Z7^'S\RBvVVp]QqqW߹~yUcR}fIjVqXevVE ig^q"g 71~ >؁ \ٳ~#005lVNzbME%WS=6ȴX IӐ ow}g Z$I"- ѶbM(!5;>39w>Cl7QmhFB'C^phkUذa`-^|#A85c߽7>2zI%]NwPYk/sZ{ێ;(<ΉLhK 6?EI% CCu4M{o.`ۗ-j11Xa'׺8Dw.ҍ-f [zvj]\ah b*9L1lB֬xR9_}HH$:ڌ[MͲnI'kf[͟ICB TMƧɨh rGw࣬-ʪ^l]Xd K.G״K濢tkV%Œ#,&p>u{W04CܧMF>}AINl+T > (d{S: ~bѕ = /xË+t}*2՞J7A׼躎Ր}Ve;.dYIؕ$xZp(-P?d{oM*Yt-`}|WǣUg%wa,%K5q `K?`M.[I'>sfsa)k.< ϩr8}c;w|}{W^ Y֛oCv^K<_kyO#FMh3Xj(t?4Zg)Uk^AyPO9|E-,,d?0q&졨'f%PU퉪t{̝;]!wۉat˞K8BڑԎ_]ȪUC_:SSq:,xi>֯鐒G2!O{l*[K+;o;b/aW۰DGWjѼgѼ.tMPXٳkL d%Yȿ>NvPlC4gDQ';(60YBq_D5in$$tC >+բj~b5UxٿyTUUz^|n]Yz5ǚ$'#{|k7 ~}+&uZg)ɉTTV,Iߖt[e Z }|ezγ EQW蔇AW=ꕉOڏsNF|3* ͇CDB7EiI -wOiȢdmrG{CĢE,}NhjenY[s:Ec{MYE!sB2jNY*dYfv2Yysf>sty'[~%咒Rڵ YVd&H()v߂1}i1{ 2~,NJ+mHFu.x0rݟMv>EY /22e^ʪWyZFoqzBnWwZ;ܞP5ŧ{QT2 q8|8}2,sK~5YN}Xn='=d{DEEѻw`>׋nS\R/vyXg^zŋ 0e=6u ?gytԑGż tk5'>jqFڌTS7xtI7ZKyf+fLYQx7^كȊ(X{2q֎l̥V0}Ԑۦ=(K3x<&y/%/9i;~49-1x:x Y֏8̮̚31G]-w*{O09t*d2L;dsTTMcࠡq٩y;jȭn.'[_|SJL&c=1>7n&+3du߯O!+>ݼg8##S)]g葌=ɺO .( ~O{"5.d6 |U}5lYq:D ɌZW^!Xc):ܝ7͉-ͱ^qx3>Y}alC95Fj%!:g߭@w2je[:&Nfo9wD&%X,<0n"y}í)82czd w00R蓜AYE!w/1sYmv߽@+z/v*C0?K@ 4xج C}8 s]8TX\2dSprNL&!Ed *'g3ks\uL&SV`һ\g/^mm:NA3 k5{m[K& ^jkUoG{ϽS_jQы[pЯ_,ڪŋ!,ns\DQa>f3'Ooe6CnSU5K>F|CGddˈ>%Egdo\pSZZDJ!jD-ThpUjm4x<${ÿbsFfY|kg㺵|o(.bUa曛LJ20i -˗6&nf␎aGXɈQc||\LU-)97U! q,ftOwں:^o7JHX,v;1D8+=@tL{·Xp!';%^Ь@ >(z ZB DQD:cDk7(g*x_/Ϸ n@|7/~eU$@ O6[d4OpϟbfVcι1d@Z 1dH.IENDB`ejabberd-2.1.11/doc/release_notes_0.9.8.txt0000664000000000000000000000623112240230175015112 0ustar Release notes ejabberd 0.9.8 2005-08-01 This document describes the main changes in ejabberd 0.9.8. This version prepares the way for the release of ejabberd 1.0, which is due later this year. The code can be downloaded from the Process-one website: http://www.process-one.net/en/projects/ejabberd/ For more detailed information, please refer to ejabberd User Guide on the Process-one website: http://www.process-one.net/en/projects/ejabberd/docs.html Recent changes include.... Enhanced virtual hosting Virtual hosting applies to many more setting options and features and is transparent. Virtual hosting accepts different parameters for different virtual hosts regarding the following features: authentication method, access control lists and access rules, users management, statistics, and shared roster. The web interface gives access to each virtual host's parameters. Enhanced Publish-Subscribe module ejabberd's Publish-Subscribe module integrates enhancements coming from J-EAI, an XMPP-based integration server built on ejabberd. ejabberd thus supports Publish-Subscribe node configuration. It is possible to define nodes that should be persistent, and the number of items to persist. Besides that, it is also possible to define various notification parameters, such as the delivery of the payload with the notifications, and the notification of subscribers when some changes occur on items. Other examples are: the maximum size of the items payload, the subscription approvers, the limitation of the notification to online users only, etc. Code reorganisation and update - The mod_register module has been cleaned up. - ODBC support has been updated and several bugs have been fixed. Development API To ease the work of Jabber/XMPP developers, a filter_packet hook has been added. As a result it is possible to develop plugins to filter or modify packets flowing through ejabberd. Translations - Translations have been updated to support the new Publish-Subscribe features. - A new Brazilian Portuguese translation has been contributed. Web interface - The CSS stylesheet from the web interface is W3C compliant. Installers Installers are provided for Microsoft Windows and Linux/x86. The Linux installer includes Erlang ASN.1 modules for LDAP authentication support. Bugfixes - This release contains several bugfixes and architectural changes. Among other bugfixes include improvements in LDAP authentication. Please refer to the ChangeLog file supplied with this release regarding all improvements in ejabberd. References The ejabberd feature sheet helps comparing with other Jabber/XMPP servers: http://www.process-one.net/en/projects/ejabberd/docs/features.pdf Contributed tutorials of interest are: - Migration from Jabberd1.4 to ejabberd: http://ejabberd.jabber.ru/jabberd1-to-ejabberd - Migration from Jabberd2 to ejabberd: http://ejabberd.jabber.ru/jabberd2-to-ejabberd - Transport configuration for connecting to other networks: http://ejabberd.jabber.ru/tutorials-transports END ejabberd-2.1.11/doc/release_notes_2.1.4.txt0000664000000000000000000000611312240230175015077 0ustar Release Notes ejabberd 2.1.4 ejabberd 2.1.4 is the fourth release in ejabberd 2.1.x branch, and includes many small bugfixes and improvements. Read more details about the changes in: http://redir.process-one.net/ejabberd-2.1.4 Download the source code and installers from: http://www.process-one.net/en/ejabberd/ This is the full list of changes: * Authentication - Extauth: Optionally cache extauth users in mnesia (EJAB-641) - LDAP: Allow inband password change (EJAB-199) - LDAP: Extensible match support (EJAB-722) - LDAP: New option ldap_tls_verify is added (EJAB-1229) - PAM: New option pam_userinfotype to provide username or JID (EJAB-652) * HTTP - Add xml default content type - Don't show HTTP request in logs, because reveals password (EJAB-1231) - Move HTTP session timeout log from warning level to info - New Access rule webadmin_view for read-only * HTTP-Bind (BOSH) - Change max inactivity from 30 to 120 seconds - Export functions to facilitate prebinding methods - Use dirty_delete when removing the session - Remove an unneeded delay of 100 milliseconds * Pubsub, PEP and Caps - Enforce pubsub#presence_based_delivery (EJAB-1221) - Enforce pubsub#show_values subscription option (EJAB-1096) - Fix error code when unsubscribing from a non-existent node - Fix to send node notifications (EJAB-1225) - Full support for XEP-0115 v1.5 (EJAB-1223)(EJAB-1189) - Make last_item_cache feature to be cluster aware - Prevent orphaned pubsub node (EJAB-1233) - Send created node notifications * Other - Bounce messages when closing c2s session - Bugfixes when handling Service Discovery to contacts (EJAB-1207) - Compilation of ejabberd_debug.erl is now optional - Don't send error stanza as reply to error stanza (EJAB-930) - Don't store blocked messages in offline queue - Reduce verbosity of log when captcha_cmd is checked but not configured - Use a standard method to get a random seed (EJAB-1229) - Commands: new update_list and update to update modified modules (EJAB-1237) - Localization: Updated most translations - MUC: Refactor code to reduce calls to get_affiliation and get_role - ODBC: Add created_at column also to PostgreSQL schema - Vcard: Automatic vcard avatar addition in presence Upgrading From previous ejabberd releases: - If you use PostgreSQL, maybe you want to add the column created_at to several tables. This is only a suggestion; ejabberd doesn't use that column. Add it to your existing database executing those SQL statements: ALTER TABLE users ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT now(); ALTER TABLE rosterusers ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT now(); ALTER TABLE spool ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT now(); ALTER TABLE vcard ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT now(); ALTER TABLE privacy_list ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT now(); ALTER TABLE privacy_storage ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT now(); Bug reports You can officially report bugs on ProcessOne support site: http://support.process-one.net/ ejabberd-2.1.11/doc/version.tex0000664000000000000000000000011412240230175013166 0ustar % ejabberd version (automatically generated). \newcommand{\version}{2.1.11} ejabberd-2.1.11/doc/release_notes_0.9.txt0000664000000000000000000000534112240230175014745 0ustar Release notes ejabberd 0.9 This document describes the major new features of and changes to ejabberd 0.9, compared to latest public release ejabber 0.7.5. For more detailed information, please refer to ejabberd User Guide. Virtual Hosting ejabberd now can host several domain on the same instance. This option is enabled by using: {hosts, ["erlang-projects.org", "erlang-fr.org"]}. instead of the previous host directive. Note that you are now using a list of hosts. The main one should be the first listed. See migration section further in this release note for details. Shared Roster Shared roster is a new feature that allow the ejabberd administrator to add jabber user that will be present in the roster of every users on the server. Shared roster are enabled by adding: {mod_shared_roster, []} at the end of your module list in your ejabberd.cfg file. PostgreSQL (ODBC) support This feature is experimental and not yet properly documented. This feature is released for testing purpose. You need to have Erlang/OTP R10 to compile with ODBC on various flavour of *nix. You should use Erlang/OTP R10B-4, as this task has became easier with this release. It comes already build in Erlang/OTP Microsoft Windows binary. PostgreSQL support is enabled by using the following module in ejabberd.cfg instead of their standard counterpart: mod_last_odbc.erl mod_offline_odbc.erl mod_roster_odbc.erl The database schema is located in the src/odbc/pq.sql file. Look at the src/ejabberd.cfg.example file for more information on how to configure ejabberd with odbc support. You can get support on how to configure ejabberd with a relational database. Migration from ejabberd 0.7.5 Migration is pretty straightforward as Mnesia database schema conversions is handled automatically. Remember however that you must backup your ejabberd database before migration. Here are the following steps to proceed: 1. Stop your instance of ejabberd. 2. In ejabberd.cfg, define the host lists. Change the host directive to the hosts one: Before: {host, "erlang-projects.org"}. After: {hosts, ["erlang-projects.org", "erlang-fr.org"]}. Note that when you restart the server the existing users will be affected to the first virtual host, so the order is important. You should keep the previous hostname as the first virtual host. 3. Restart ejabberd. Bugfixes This release contains several bugfixes and architectural changes. Please refer to the Changelog file supplied with this release for details of all improvements in the ejabberd code. ejabberd-2.1.11/doc/release_notes_2.1.11.txt0000664000000000000000000000376512240230175015167 0ustar Release Notes ejabberd 2.1.11 ejabberd 2.1.11 includes a few bugfixes and improvements. Read more details about the changes in: http://redir.process-one.net/ejabberd-2.1.11 Download the source code and installers from: http://www.process-one.net/en/ejabberd/ The major changes are: * HTTP service - Fix ejabberd_http:get_line - Don't use binary:match to extract lines from binaries - Parse and encode https header names like native http parser does - Parse correctly https request split into multiple packets - Properly handle HEAD request in mod_http_bind (EJAB-1538) - New option default_host for handling requests with ambiguous Host (EJAB-1261) * ODBC - New ODBC support for mod_announce - New ODBC support for mod_blocking - New ODBC support for mod_irc - New ODBC support for mod_muc - New ODBC support for mod_shared_roster - New ODBC support for mod_vcard_xupdate - Add ODBC exporting function for privacy table - Work also with some unicode strings in PgSQL (EJAB-1490) - Replace a single quote with double quotes in an ODBC escape * SSL - Make sure that res is initialized in all cases - Parse correctly https request split into multiple packets (EJAB-1537) - Added missed tls:recv_data/2 - Don't ignore Length parameter in tls:recv - Avoid quadratic behavior in reading SSL data - Dix http_bind webserver TLS fail on Chrome (EJAB-1530) * Miscelanea - Assume we have only one CPU when an auto-detection fails (EJAB-1516) - Auth: Relax digest-uri handling (EJAB-1529) - Caps: Cache caps timestamp before the IQ-request is done - IRC: Use of MUC password - Private: misc errors cases fixes - Pubsub: return user affiliation for a specified node (EJAB-1294) - Shared Roster: Foreign items were not pushed (EJAB-1509) - Shared Roster LDAP: user substitution in ldap_rfilter (EJAB-1555) - Windows: Fix makefile rules for building DLLs Bug reports You can officially report bugs on ProcessOne support site: http://support.process-one.net/ ejabberd-2.1.11/doc/release_notes_2.0.3.txt0000664000000000000000000000221612240230175015075 0ustar Release Notes ejabberd 2.0.3 14 January 2009 ejabberd 2.0.3 is the third bugfix release for ejabberd 2.0.x branch. ejabberd 2.0.3 includes several bugfixes and a few improvements. A complete list of changes can be retrieved from: http://redir.process-one.net/ejabberd-2.0.3 The new code can be downloaded from ejabberd download page: http://www.process-one.net/en/ejabberd/ Recent changes include: - Do not ask certificate for client (c2s) - Check digest-uri in SASL digest authentication - Use send timeout to avoid locking on gen_tcp:send - Fix ejabberd reconnection to database - HTTP-Bind: handle wrong order of packets - MUC: Improve traffic regulation management - PubSub: Several bugfixes and improvements for best coverage of XEP-0060 v1.12 - Shared Roster Groups: push immediately membership changes - Rotate also sasl.log on "reopen-log" command - Binary Windows installer: better detect "Error running Post Install Script" Bug reports You can officially report bugs on ProcessOne support site: http://support.process-one.net/ END ejabberd-2.1.11/doc/release_notes_2.1.2.txt0000664000000000000000000000340212240230175015073 0ustar Release Notes ejabberd 2.1.2 ejabberd 2.1.2 is the second bugfix release in ejabberd 2.1.x branch. ejabberd 2.1.2 includes several bugfixes. More details of those fixes can be retrieved from: http://redir.process-one.net/ejabberd-2.1.2 The new code can be downloaded from ejabberd download page: http://www.process-one.net/en/ejabberd/ The major changes are: * Core - Close sessions that were half connected - Fix SASL PLAIN authentication message for RFC4616 compliance - Fix support for old Erlang/OTP R10 and R11 - Return proper error (not 'conflict') when register is forbidden by ACL - When ejabberd stops, send stream close to clients * ejabberdctl - Check for EGID in ejabberdctl command - Command to stop ejabberd informing users, with grace period - If there's a problem in config file, display config lines and stop node * MUC - Kick occupants with reason when room is stopped due to MUC shutdown - Write in room log when a room is created, destroyed, started, stopped * PubSub and PEP - Don't call gen_server on internal event (improves performance and scalability) - Fix duplicate SHIM header in Pubsub message - Notification messages of Pubsub node config change contained a SHIM header - SubID SHIM header missing in Pubsub message with multiple subscriptions on the same node - PEP: last published item not sent from unavailable users when the subscription is implicit (XEP-0115) - pep_mapping not working due to Node type mismatch * WebAdmin - If big offline message queue, show only subset on WebAdmin - Support in user list page of WebAdmin when mod_offline is disabled Bug reports You can officially report bugs on ProcessOne support site: http://support.process-one.net/ ejabberd-2.1.11/doc/release_notes_2.1.6.txt0000664000000000000000000000502312240230175015100 0ustar Release Notes ejabberd 2.1.6 ejabberd 2.1.6 is the sixth release in ejabberd 2.1.x branch, and includes a lot of bugfixes and improvements. Read more details about the changes in: http://redir.process-one.net/ejabberd-2.1.6 Download the source code and installers from: http://www.process-one.net/en/ejabberd/ Some of the changes are: * Account register - mod_register: New ip_access option restricts which IPs can register (EJAB-915) - mod_register: Default configuration allows registrations only from localhost - mod_register: New password_strength for entropy check (EJAB-1326) - mod_register: New captcha_protected option to require CAPTCHA (EJAB-1262) - mod_register_web: New module, with CAPTCHA support (EJAB-471) * BOSH - Don't loop when there is nothing after a stream start (EJAB-1358) - Fix http-bind supervisor to support multiple vhosts (EJAB-1321) - Support to restart http-bind (EJAB-1318) - Support for X-Forwarded-For HTTP header (EJAB-1356) * Erlang/OTP compatibility - R11: Fix detection of Erlang R11 and older (EJAB-1287) - R12B5: Fix compatibility in ejabberd_http_bind.erl (EJAB-1343) - R14A: Make xml.c correctly compile (EJAB-1288) - R14A, R14B: Disapprove the use of R14A and R14B due to the rwlock bug - R14B: Use pg2 from this version in systems with older ones (EJAB-1349) * Listeners - Bind listener ports early and start accepting connections later - Fix a leak of ejabberd_receiver processes - Speed up ejabberd_s2s:is_service/2, allow_host/2 (EJAB-1319) - S2S: New option to require encryption (EJAB-495) - S2S: New option to reject connection if untrusted certificate (EJAB-464) - S2S: Include From attribute in the stream header of outgoing S2S connections - S2S: Fix domain_certfile tlsopts modifications for S2S connections (EJAB-1086) * Pubsub/PEP/Caps - Fix pubsub cross domain eventing (EJAB-1340) - Use one_queue IQ discipline by default - Implement lifetime for broken hashes - New CAPS processing * ODBC - Increase maximum restart strategy to handle some SQL timeouts - Support PostgreSQL 9.0 (EJAB-1359) - Use MEDIUMTEXT type for vcard avatars in MySQL schema (EJAB-1252) * Miscellanea: - mod_shared_roster_ldap: New Shared Roster Groups using LDAP information - mod_privacy: Fix to allow block by group and subscription again - Support timezone West of UTC (EJAB-1301) - Support to change loglevel per module at runtime (EJAB-225) Bug reports You can officially report bugs on ProcessOne support site: http://support.process-one.net/ ejabberd-2.1.11/doc/msrl-dit-deep.png0000664000000000000000000042703112240230175014146 0ustar PNG  IHDRbKGDtIME (x)a IDATxy|Uս!#IHT" ^JL2TB`}mx+~WAnԋ20ID !@&} dx=kO<cf&> u@UF GxzBh޼rrrBFH@j :@Ç:!b۷א!CB۹sBFp4h$?H~@ A  &AFIIIQ=\&aL!@ ;@կ_?:NkJvXc Uq |h.֭[0jtu7oެJvشiS;Yb *!CJEW^CBBP0c 5a ߯QFQFjҤVXQj{ff&N *??_&MRBBZl>̩<ӨQ԰aCƪo߾ΥRn FNNxĨ[nZf<l޽ݻ5tP[^7qlkڴi>%77WÇW||5`}7~w۶/7nC=+RD-YLLK111jڴ^|Šw_yc Կ/{NnT`ݥF0[c^ F jݺӕ1cƨ^zJ*sYP+=־}{9b-Z͛[VV}>k?9r>s_5nrss])ynܸCYVV5m$G}}v1c؉'lڴi&|M߅ USoO7c=,onfn~&oM{%c{Wꫯ$kӦM>+I2ԦMdSva"gbU-%T}]hٲerQcsS뮳(;vmٲոʋdO?p VTTjZ*E $IָqVy۷oIxI&Nݒ?uu0]X/PbNܝno{0sy)1:u܎R` 7UYYh +999 8eaaa\.tAI}nwWJ:u aÆiA֬YT^=͙3GIII}hݚ={;hĈw̙3թS'=#7k.N_[jv8Aϳ/ʛdI*uW ETRs 4 &@~Eor܎\* 4H}]䊓'NܹsbIW`xٳ$w\Ν;KR5o޼R}䶿pI3g8u_=vءqi˖-?V\)I****ӦJ֏o 2D;~I}lǎ;ent1{wofNm&I?~6m$I/(kK)1wcs?n[ܴ+w_L(..Z/P-{? ے%KɓM%Yf?w^oذ233u֙YrroYYY7..5jd .43sW0Zd?l…xL}ᇮL͛7Ͼ[KMMu4o{믷UVYAA-Yzif~$/_8333lҥf}qԯ_?9s8ݿ5n5jdk֬<{EfLW=zԾkyvƍKǢ-###Wr׮]4nO7c 57nc tyv222ʜׯ[3ϐ@#RetMa7tmܸ׿u/y3Yֽ{wKNN_zzu"##sζ`g۾1|.]ضm۬gϞ֢E ]|rk޼رc-??ׯoƍs*(222;ﴨ(;l޽l\SN-Sv7۵^k/5l뮻,66mذa܌)޸x kܸڀlϞ=eZ~ZdduVXtn+US9+onF0n[0cԞ.3>+k{cjT9i;~ڶmo6qxoj~VfUeN/`沶MMWfp4%?'i Oչ0KsY5 4Ok!c֭c%KeWUr f.kܠN 4zUW_M\noFx;B0͸ 4h$)))ѣ?~4hPQ.7 S*'' 4(Gzz뺛7oV|||%F. ۧQFaÆU߾}+=&N *??_&MRBBZl>i}rrrԿ+&&FݺuӚ5k\x/_e{U޽Cjݺud^ӦM/zN|w޽7oM6),,L:uҀn:I͞=[?RRR4l07N[l$X߾}yfm۶M;wT߾}5zhegggժUet˖-wQl̘1;v}}W=zd?nW^ڲeM ZT^=<**JUQQQP}eff*;;[˗/WϞ=%I',,LX\snv=ںut$|=_\%=31c͛G jh\9x$>W=N:Aiذa\WVaaխ[RH.(;7mڤ-[ꭷҁtU 4tA˗/WΝ믿^g֐!C$y$)7|S֥KIWsZO+..NSNURRn6hBQQQ9s7oq'ԤIT~}7NߝsSO=x͚5Kϗ$uթM[d#c%:5RSSM6:@Wf  4h$?H~@ A @Ԅ ԠAuSRRԣGUpTU jh*̀4{l;v,`bYW_VXXYf[nQ\\֭=zh/ 8.:u;oN>3f{WLL:vg}VN<O(5o\#F͛+/X$T`k֬ի+^{gynnv_|Q>߯cǎiƌZj6mИ*Jzz+k޽ҥ^u=SouAꭷRΝk׮ Hk׮u^>|Xyyyz7nݺiŊ\,U?RSSV #3S:u/;w}:}t PƍդI2}_Rf1\NWQQu릜m߾]5*GC[6lؠ ǻd,_~u:(++Bpq*oFu 4j኏W|| o^r;v讻RLLn&Zٖ'aÆT^M_,}߾}5j6lXW[Ov$4yd3I1b1xΥݺuӚ5k{U޽Cjݺu =.5i$%$$e˖\iy󕖖WU$5h@'O֎;K/QF׿nA{$={Vt5(**JQcǎ_jfLw01ҳ>k۷w]ȑ#vOS;r}V~}kܸ:$$KMMcǎڵkiӦek׮53f͚9onqqq6f;qM6$ٛoiff~5k̒m޽~ꫭse.)99$֭[]vڷool۶m{$k۶W^pB;}mذ:tPwݒˍ*矷؂ L%&&S_uw$[jUl۶$Yꫯvz7߶vڙM vq{ιYVVI6mڸ87Ƿyj`f4$Z*/CLeee9e=I)y뭷L'?13cǎ7b$+LuƎkl{׿J;66$ӧ]v:v$Ν;g,<<iWv^]m΍$;s挙$ shN}WFL;vxNk,իWOsQRRGȅk| 4mVgϞrxX_}x^|EEGG'Љ'''?YPfmܸT,Иh9;W*IҮ]2jVZ}7q5ה['!!As{ $Iˈׯ$GP+iʔ)Zx,XާO޽[gVbbyR&S_ "I˭'H }uWgĉ5|1t1cK9|$MDNَ;$IޥKJrvm;}я~$Iٳ$wΝ;GW\{N:K,q/**rʋ%I+Å<vءqi˖-?V\z{ tܹ21\9- 4L4Im۶՟gg_Iyyyzgqƕ۷{;V~ ~\B/@v@{5UU7޿5n5jdk֬<{E;~${ѣvZkܸyv .ƍ-::)x<mfv%YFl…N 64IMWZe׷momGbϷO?Ԛ5kffKrzך$?a .4c?tr۪U,Yb={,5VۓG}ɘ ϝ6l03Llݺu洼ڵkxv 7ҥKԩSv [dx㍖d{qYåbWO/2s^TTT\87Ƿyjh@-u1_XaÆ9OC:r=֬Y3-[ԩST hf]?-22:vh+V(===:wlֹsg[`A3f̰8ҥܹԶ\o~cmڴ͛RɸJ7|m۶YϞ=E;Ȱ;Ӣ;{jݻy**識ͩϷ?O֩S'Xܹ/q+ +Xݺu}ݪU+c*OycG}`fށ'x 'PKjGaaa.CR\\4iFݺusO<˗{ɓ'C!B7#Ը>5ӄ tJIR\\ڵk(2NxP{$''k׮]Zx<&LP>>|X=cǎiʕW^y%!+@pٴiFǎ/:OqDʹf5mTGW\z?vޭsA\afܹ;wneҴiS͘1C3fu(pIXA  4hCJJznffƏS%)C: 8P999 Hn޼Y .Q\\\CT"h\ٻwzh :T֭0 IDATt`'NTÆ I&)!!A-[g}b999߿nݺi͚5x<Ώ2qWvM_@%\3fƎ__}Flׯrss%Ig? 6LƍӖ-[$I-ַo_m޼Y۶mΝ;շo_=ZٮYjU$ݲetw\xK^eM6MIII~ 5j$IZr-Z\NtRnZpB}wz饗:%YxH.(;7mڤ-[ꭷҁtU 4͝;WO=5k,͟?_'YJRN$jW.]$_h5O?8M:UIIIԢE EEEg̙j޼ƍ'|R&MR5n88]:uI5qy딌gժU***G}<P=yzgFjjҴiӦPj V~@ A  4h$?H0)))ѣ:0a4hpXn蕙W۱ uj:u}~{n5p@Tb4ˁ ֭[pnyfWb4ˁK8\V uM\\\CThx$i޽ݻ5tP[U]iӦPuq 'VZU&l2qk_6bXBM4ԩS˴_\\b}͛m6ܹS}ѣ]ٳgWJJ qi˖- Icƌرc뫯ѣ_\K[lѴiӔwcf \~JKKӦM-**Rx~8{"##<կ_Tɓ'-ZKk]q7+??_N<:{?W̙3Raasι$EEEiŊJNN$[N]v-w 4g_WDD@7&N)0f'+뮻bTvv/_={JΝ;'}բ$I$]s5j֭ҥ,5Fq3hƌ7o3fH畓#IjРS+ƩS4h 6L'OŚ5kի9s())IѣG_\%ٳG۷o/\a.h*w5؉'.)ShZ`핧O>ڽ{fϞD;1b%5sLuI<222*#t@%! $ט׉'K%?]S}]g5o0|\R|_\%GDDVLL Ç7 Hpu֒ K/lKJJRffzݺu?񏊈ФI{ԩSw7J:h[ߨQ#Iʕ+h"rʥKjڵNRh ^ÇիUXXxu֭T;%/;7mڤ-[ꭷҁtU 4̜9S͛7׸qOjҤI_ƍڵSכp֭.]kV RJJN%$$׿bgEWy~iiԩJJJmݦ-Z(**yb$uIczuΝzJ5kϟ/I>/.oZJEEE裏K\Uǂyn4#55UiiiڴiSCTqo+?H~@ A  4h$\LM0A 4pRRRԣGJG0DffƏ}[cs!Ogֱcǜ:uTh?,ϥ>}<<n}exn:w=z4qsL 8P/r:<<ԾJJJ$ѣ~\jh<:::㷸XfVcs!mݺLYzz+M6Uh{ӦMݻu+;;[ PAAA:EEE/$Ik׮UqqqP>mذAΝӒ%KBK0͛/'OO$?6l IZr>5mTuU^^^]'NP޽գG}YFWvU*pi<6U9q>^111֭֬YѣG\O>{n|ݺuNwީ  8{ F jݺӕ1cƨ^zʬ2T^M_ts_m۶СCzge˖ĉeƚI&)!!A-[g}&I>/_Uo:&͡}=m4ח:zRْ-UMmڴQJJXc_=݌ndu1I<թS d۷wϑ#GEּysʲuLC'Xmڵvic?xEFFUW]Uj'''[V,66N:wRSSˍ~ xw36_mU>ߌ3֬Y*qMۂ 2裏$[hS]c|իW;׮]l?tSd^3I֫W/v;v$]Ν;g,<<ީS'dk֬qƌSj\6wiW\qه~Xf~KN:ٳgM91$Ynn$ڵ֪U+$/?n>رciMf;맟~n+** j.]jg?=s6i$+((xOjffӧOoKǻ/ H}]x<&,&&>S=~>PeҥvW8 *,Њ*ɓ'{ ڻ[f{QQm<mٲv\xa%&ɚ4ib999ebh&T+X'O {,^8 vC%3g jkuZ^^|͖iffÆ ;|%%%ZQ+@bH* 4"Ts۶mSZZ$7)W\\>SvmOTT$} }ݻ5{l%&&wш#G-ʭ3e-^X ,PlS&O,3ӳ>0_zZ~/VBB$y@0G#G_,̙3G;TH vÙ3gSNzG::uh̘1:}~i:v(I0`Ξ=?:p@h_Ŏ @2{}W6|pS%%%٘1c2ޟ+m۶mej>}$7oSvǏ{i$rH䊎v^{9r)?d|gҿ+&v ?Y&MekQqq 8ggK򊋋˔yykݺeeeYFF(֦M۵kWm(ǏٿW{LyvR;`݅we׷f͚١C\ͅyK/9yyyi&NX=b _.)3<<ڴi<]ЗYMn&n6nh _֯__[fWddd؝wiQQQvw޽{6ux kܸڀlϞ=elwg]tm۶YϞ=Eĉo˗//U~aZӦMK뷼)33[j?HرXֽ{wKNN_bccKcǎRʽ/Z/_n͛78;v[mܸq~8}ԩSoA)_j7tS/ v..[cھcfv7믿ӕ6m~N_ҵ^F);;Ԋ *--Y)*Gd޽_G\ P&M*!2Gaaa:w\C*UU*\ TQ;w/~ %&&/ܹsuV >gL7o^xAv<*J&*#v)M8Q//*y&j۶mCPHU̾}]vh֭9rd~*>>2Dzn^:u$ǣ8m߾]'Nd]}x4a„P@Çkʔ)jӦ.]_~Y[nսޫPW)ڷoޱc kUVրb TX@6mt1 >\/ƍTPv'O //ҳ>|PQQQU}~JisjܹeD ӧOW^3p4213oӍ7ި &Ν;sϑ< cp\R?4rH}GjժU.@*Ѷm4uTӧ7o֢EB[hBFȐ@*ÇOW_Ubb.]>}:,@CBx B9sOuj=zTW@*G}GyDw? uX`%ot='?zmݺUӧO'y@ A HgΜѓO>:(;;[˖-ŋղeP*p?֯k8p@ӧOפI^P ¡C\?u7j۶mzIPWpkɊw?aˀh@]wݥ_W{m6g"@;wz!]yJOO-e 44zhmܸ+ ,ZHcǎU 'gϞ +ѣG5rHg?СCi&gh$-_\w'?ICU+PkҤI;u-h$@)@@_;9rdCU+P;wNO>RRRt5(++(+PڵKÇ͛ /h„ x< Ta@@[ooVaa֯_'<@@w)9r~_(##Cڵ uXNh7nu!ׯ_C +P#fΜ[nE7VVV3pQXȑ#'ԩS갪T=cPE4o\999J %==]#FP:u'[o uH… C RSSuPQe@@`f1cL[6l갪kȐ!b;wTZZZè2H;~ƌ%Kh2e<O5 4TkYYY2dN8?Xv[C5 O@o(99YM6Uff&3P)H9s~_ĉSW_}u5pZٽ{ٳG/րBXjt"IZ~=3pY@@?I?Ou]wi͚5jժUC 4TiOȑ#cכoPrdffj„ jРAC1RRRԣGPQc::HU{׿*''G}z@~0j:uXP-5Iu8CTB6{I IDAT19QHJO5d5iD_~%lV[nUBBBèQCBiӦwV:HU%ٳg?zիW\񊏏׀7߸O26nܨzHW^y<+66VZdIMn+o,rϩW쾻gn9:{]P nnnҹsgIMM<3gG WWW˵k$**J׷_.+999+:tooo2vLmwȲeDRw}'"".][[[5k믿.$""BDDF!w۷oٳgSU_.]رc@N:%mڴ'''Qϙckya5k$??_RSSE(dZ}ƻo,kϘ9U_mm>kccGǶuV˓[ ѣ;'O+Wŋe@zY!1FDDDD&[u&]vϛ:'V}?,-^Xȗ_~|+**R_DD\Y;w3g(eѣ2vݻWȊ+ӧ C6΁?};c~2\DDܹS#~) 3e˖5.&ЈȤ:$[7u8O~Xѣ7o*e' & $qr,cǬҥKbgg'C QFqvv{LVDD[nbii)sέ@7'wwwڱS1{lCcmի@2CkeLvk*bϘ9U_|>3؟ƞ7c06>,~~~umLhDDDDd2| Ǝ#&&ڵ3uHTm*efff:mf3VmeZ8q",--k.uh4Ƚ "h4pa˖-ӧBBBp֭Z]wQu0VWuh+//W 1g_Siqz3f-1}fi2L<XdN6]&Ј豫Ă ~4uXTOsVRRX~=zQ=APW}ǜ5k.]tQu!xu|26o ݻӧOu,m"++K)kG;CO}c:}h zw?C7tLwM}Ӄ٘Og z946K.Ett40a„ 4""""z0~xl߾wƊ+L= ???_U"wU{Æ \Ry]bb"A2vLذaكe˖!00FC̛7iiiӧOc]-0?8v{ |7J]FF $${l˖-|/J$Lo޼[ V U}^xjMyd ј9`y3v5W=6ZUwg!o&""""z/_qqqdSC~7bnn.mڴ}Iiii6quuSN)ߟ={VDDRRR2W/55UcmmmQv-"bXah^_ٿݻresRJE޾Dzx)//}ɰaD O\qrrGGGIHH"4i$ec{-?ׯڵk8:w\u/˭[?K:w,J;CkelƌW}m11?cdӘsom>9`y3v"""gΜLҥCݻER 9p@ {b$С_rrrL bbbKKΝ;'[W^yECKD ?9oM_Yddʀŋ2l0qssG3a~2K%R!C`ݰ5uHڵksN6.jѳgO\~ݤqh75\?xeM哶6'hDDDDH}g0aBCCo>&ψV2i g<^cXǥk$ =y@#"""GBD_oO?TDwy}żyLDž ?+YxeM哶6-DDDD***0gDEEa֭xMУPQ}5g\''Ac" ! = < kI?LQQ3f n޼8xzz:$"""=ЈA\t &ψ`?t'N@NLQaÇ1bC6mLQbXTTƏ)S ::Z2uHDr2=Y@#"""G7 ?a۶m0333uHDT-RLIDDDDow ?=qqqL 4""""2Zee%°}vرoM#[8(6m"##^3f666?~QթcƌӧqQ:$j$V^ Z>pvvիQ\\ pv…С&NtR'O>X "9r$ua=z4Fii)֬Y[[[,YYǎaeec۶mJϟ둝w}xb ܸqoF֒7S=nݺ^x999O?mZv-v܉4wsZEʿE磈KOOѯ_?*Ouqqkjoժ4 wZ3gbs.ݺuCVVaaaݻwo899FϏW^7n?7n >>3!//tN({cibĉĮ]4 DDh4pa˖-ӧBBB[6%;;n" PPP3%"ƈ 4""""AVcذa(//G\\vjꐨj۶-ѣfYfҥK@ǎuZn ޭؼy3<<ֱ'RʴW5%L~ C AVpq:$j XrDx{{޽{! 6`Ϟ=Xlk1tPy[N>ÇwYFFpyDFFرcq.##b܈c/^Đ!CСC|6DZ VVVD=`ggqa$mjj %%!CڶmkCTS9Ɏ>J۴!..Amrrr0`l߾k֬בkb׮]FVVVPYY$EEE@jj*||| cK% '""""2d v킹C&`ڵعsg&DDsq駟зo_ܾ}[g슊 4׮]ùs\m۶=DĤsxj[J ;;.]qn݂'ZjgֶA^ W=~>>>DjjjCD= M@#"""jfRRR0j(<عs'gHjL6 Gpp0233fdd`̘1㕺,X:`Ĉ 6nܨSU̘1Vƍ۷8Zl ϐ%KMA+;;&LPneABBRXYYaԩHNNP_k4,\[F׮]q ִڹs'Μ9_~F ڶm%K ##_uqtt_;w7@N`ii^5S~w1s+C0ϺQ'DDDDl7NM51ҥK;vȩSM6$jZi@ڵkPE,--%))IDD\]]vZ.][[[5k믿.$""BDD_.+999+:toocW+… F~+ŋ~ ={TG!w۷oٳgSxC__Z~zvDEE 0zMרQŋxzzH"""dϞ=Oȼy˜9s666Hjj=z50ty}DMQ}'4wL5Ҿ}{5jg@aiٲe@RSSu y饗2}]v yDDFӧ %YQTT$d""2w\ gΜQu+ƶrmz?SfwҲeKBN<|szC_/_~EDD)ZS}(xJKKX[[HqqWVVN[[[[ FDD]&j$ GGGKUU9sFI\~Fͩ8 c^Ʈ;QS.FDDD \|C;<kkkSDMP}֭P^^ @zz:z '''\~ Ю];ۣH>c...vZq[jF;"77wQn7---QQQ!#G୷R~޽;j5fΜ C8Cܿ^O_܆T<<vvvزe 郐ܺuzC_/}맏5էgϞ+WFիx6n+++Z %%%ʓ?_x+** "(//ǹstgTW΁1ocם>&Ј|96668x Znm Ҿ}{@VVRݽcIN:Fz[߶m[ѣG Cu\uK.Ett40a„|26o ݻWCkϔ)S 51{l\t ڵûヒ  22蘪{9üau4%@hQ|R ؃&MTkC͛Bti >0l0ʕ+'#&&&ۻα/^vaݺuy6STʫN ST@XXΟ?H;vzCݻ5b~唶КpBr_uEEExwၰZZ|9ΝǏakkkWל90mQ3hX#"""GP|||[ncpѹ$ EEE2i$qss7o*:v(dʕr-IJJ'''=z(pΝ+++\R$&&Ƚ'2VGGGٽ{҇MM6ҳgOٳgܺuKDURRRDPڥK ݻwJre.zx)//}ɰatZW׺c:}:uJٳ""%''WVV<3һwo9x𠔕III۷Oyӧ\rEi?nggUӧOKeee5u-S]q:Ƽ]wB7 IDATQSVV&CWWO#za)==]ƌ#666boo/ dѢE*ҵkWyפB 4{AObccu[,,,[t7m$2`駟tjңG177+++ܹ( qU/22Rŋ2l0qssG*$&&ѣRF6T?xOԷV}5k4lذA}Y>@yڶmS'HV^jSۜ91Ϻ55LS8 !%%qqqD O\ST033ӹ-*ܹ=z􀏏R^ZZ#G෿-JKKM!iwBc=ЈJHLLDLL g,uݼ͟?կtg`kk~'N4QdDDuki0 o>>|}5uHD YYYJM=B~-~gD>}`kkB;v ?':D""xQrJl۶ _~%LQѣ 1m4lܸQy#5O pqq̙3Ѯ];aȑ|2v Q+Ј6l;0fSCԠv؁;v: zL\\\i&lڴԡ hDDDD۱tRl޼oLp5R_5̙5kW^1u8DDDDO,&ЈpBkQ#I&!44|!"""z1FDDDԈdffbر6lCR:$tE????>shlYӆ_s8DDC| pwwǮ]`fffꐈZpp0ն -Z4gԨ֭[_Dee%1|"'";;Az\YϠ juoƖ-[/ݻٳrҶ1k"Q#h0~xammm∈Ə?֭[6!!߶mrZcǢׯȑ#aii?0c mZZshl p 00-[???TUU!>>K.Ŏ;ph皈!0FDDDdb6mp)>^KII JJ Fkkk`ƍ:W^Ō3?^qܸq}G˖ϐ%K$Ϫ>}9heggc„ 5|||tA@@0uT$''ca*J5Ō3gggΝ8s ^~eV۶mddddkuj,皈{'fffԡ{'}5}AAtEƎ+r)iӦ899ZVvZ),,$qqqKKKIJJWWW֥KVf͚%%%% ׯJNNJۻ ps} x߿_HϞ=#FݻrY9P׷xkta2}kZPP nnnҹsgIMM<3gNvF_k /^Yc˹&W HddT*fPD-[&$55U)[n^zI)ӗصk^xADD k>}PqEEE@(""sr嘏?XzQ666@n߾m\_~Jݻ@Zl[XXɓ't7TovTTT[ŋ /Ciikkkk"zpLR%DDDD_V2u8DkbΝHKK3}nݐrXXXѻwo899wk_h׮QTTQʨmk׮UVh4ر#rssqΝZo7%***t6D_?p[8yN}ݡV1sL,X:И[Ӟ={"##7oD۶mL~v(++FAV_QQKKK١֘LywBs=ЈӧO#44gf򌚴l 777&uiӦ }{J6!$"h4<P7ڵ+{{=2L<XdIpa˖-ӧBBBp-Bm{Pg`ffV]Ϟ=W\m«W^uasMDP@#"""z2331~x࣏>2u8D},L{e{j&:uM֭qqqzIG=AAAC.]hDEEa„ 5qel޼ػw΃ ?*:M2pZ|:2&"j(L=&x]vꃨ)&,##RL46C̛7O>|8`ذa+W*OLLLwc/^ڵúupMmۧ_YYWUU>sR0?8vʨ_~QJJJ믕:`…ٳ'}ꊊaaauisMD`vkDDDDO2ݻK^^!ҫF抓8::JBBɤIMn޼ر+Wʭ[$))IdRRR};wNrJ%VVV("":(wVpppTxiӦS#nݒ*h4rqquu'IvEȡCdݢR8p@K^$>>^e߾}2l0U+u޽|ruYvgΝu>}$&&iF'ʃVV<3һwo9x𠔕III۷Oyӧ\rE'x!@#"""z޽+AAASOIFF!Ճ|XJOO1cƈKhh$EYhtU^{5iwRE^kРAbaa!X8 (M6 0@~':Z-CJ:w,!!!Jz\㋌Tx 6Lѣ12zhQFINNNu<`ȑ#ҹsgsF6mHXX9sFo""111%%Ν֭[+KF#6lg}VF>FS#z@ŧp=baaaرc{:Zk* fff{IƧLJ皨3FA][nEtt4gDF>?k"jJ"""G$""+Wە։H/:tSNARak"jʘ@#"""z?X|9~ߚ:FG(,,ĴiӰqFOt皈2IDDD2331e/!jv؁;v: z x)hDDDD ƍ;oJeꐈ! 4"""RQQI& 6uHDDDD@#"""j ?ԩSpvv6u8DDDD@@#"""j7n֭[}:""""j@!۷K,dp󃿿 ""hDDDDČ3/cѢE-xѓ 4"""tu3ĦML=BqqqLF!"""zAtt4,,,L="LՓ`֬Y7|֭[:$"A@@0uT$''CRRRR`888@`…hݺ5v'N(}իW1c 888ǏZVU*ޯ+mRRR0bX[[7n\S՘6maoo`dff>bQQ=k믱{nt̬Y0w\bŊ={Rpܺu 7oʕ+uV\raaaJ*Hܸq˗L$''#88XÇq]-[J@zz:.] //gƢEYhݼy())+Wp!?~z/*5JL_|kO?MIšcǎBm6… ʿ.\:`ĉK.)u 8yd^j}\]]իWXi#"9r$ua=z4Fii)֬Y[[[,YkĴ~zdggw߅{9X7noaQN:^z ˖-~;SCdr:u¯~+ 0`j2;;;%({VVVk<==?Smzz:fΜ!C`͚5Jyll,*JZk.5/{V&Lo5?""j@#"""2Bff&1vXQlق>} $$DQXC+)--ĉaii]vLp "|i4Kvv6~(((xQcEEE8q"vM 5e|26o ݻӧOoqڶm 8zhf͚K.!"";vԩ^qEp,E{ ̈&Ј "9s&~gݻ֦PT@XXΟ?H;v p]]UUݫe6l`ʕS.ٰaكe˖!00FC̛7iiiӧO+{5규j |7J]FF $$QQz-8p{!jtM'O$%%)mRSSu )))??? 21VZ+++dffGøq|r7[b}*++\1zj///hÇǺu E+$''+999aݺuHLLDqq1VZ777,^V3&ЈjW_͛kp;v`͚5Gxx8"##@=ﯔ 0+ ]#Gի6oތ)SBCCQYYxCRe˖9r҇bbb0h XXX TdueJm{ggg8q>>>@N`aaxS""j>TR:j""""p|1c:bڵعsr#=;A@#"""Oaa!&N~aӦML 4"""j*++_~{C"""""ki˗#..'NSO=ep`ᅬx{{:""""j$x '̞=-Œ3L5"L/??M52LSL9`fffꐈhDDDD[x1SCDDDD@#""'wcǎ۷!j_g̟?m۶}LQ5cGDDM@#""'Rbb"^y|X ֭[J͛7燸8"-- QQQ5Í70x`\|iiiDrr2ku]-[J@zz:.] //gƢE 5kΝBXg68?ʕ+8t?\zQ=.^9sOLbp(>|ϟÕ+WO=/^\]BBNDDxПub 4O={:$Fiڵعs'ҌjGe"} $$DeUO hDDdzLQi&|W!zYZZJJJ/mѣu5k.]tQN08ؼy3<<ֱ'RʴW5VLQe˖/Kio,///J]II *++﫪{&|Jxq6l`ʕS.ٰaكe˖!00FC̛7OM J 󈌌ıc@|R 1znDDԸ0FDDDҍ7_ƍҥKMQԽ{wݻq U郔do sss,\GYYq< {!C9U`eeLvvv7n/_Ŋ+5k􊉉Qn\z҇ZhÇcݺu8ӦMɓ'QQQ{{{^NNNXnQ\\UVMi`JL:666ؾ}}}Gܹ3°zj,\mڴAXX+ 8PiM:ҥ &O ???=[+_]ѥ68raaa^zaʓvCCCQYYxCRe˖9r҇bbb0h XXX T;v`͚5Gxx8"##@q :uu}#"O$""fgҥؼy3N:///SCdkDD ~3QW_ۙ<#"""[8Y0g⋦ &ЈYh42e z聏>Q3[8YZ3gQ35y| |ҥ!"""fpQvYXjM5CLQU\\SbȐ!Xj!"""f 4"""j^~e!22fff)&ЈIڲe كtm۶J8o { "@DDDMNjj*?a0u8DTMPPjNY w'";;{w[{SNAJq4X REEn݊/1 IDAT?#*++>>>e. }C_@@GzUspp0QwHDDDMJii)BCC1p@[s…eqqqkq_/_ٳ`봩ӧIIIjZbƍXx1rssQXXM6!>>->oo"??UUU~'m]tATT#4xуa0صk=#j8nnnK\̜9S窬-Z`РAuEUTT`ܸq~:1yd @xx8ly\ڼh׮r4 &N۷o#::<S=&Јؾ};"##\̘1pvvFllN}JJ ,Xs;dNN`eeS"99YIh;wSO!//!!!ۧ/y &ABBfΜ J|*nj7N)ONNVG(X6///ǫ֭[{CQQf͚;;;t֭F)))1b₍7*ug!55K,6ӧOZUj߾Qqu~sޢt Qy;O?;w)3ggթS՘6maoo`dffk1c^^^:{Z{"z xX[[ҥKM Q{I߾}n_PP nnnҹsgIMM<3gG WWWEDF!w۷oٳgSwrrRگYF%55U\\\|wJ?۷o_ /^ ٳh4y7GܹSZZ*Βoaa<@>y1q֭[%//On*wqUU?PJPG 03-oh(V]$iR˴JdNW M^B"ޒDt TQg9pp_/^kֳvjv*/lr=(̘1Ce…@"##EDdРAT 9ydUݻTDDϟ/JUjW3neeew^VZEDҥKu'""yyybmm-qqqR^^+VsU:+>>>2vX͕CKffnl[d\~]Ck{X꒩&4w@#""F͛ңG bsClaW^i&,==]C+M?Qם >\)X2qUZZ*Z9ޯ_? JF3fK[s䮻+++ٱcGjuMHDDJJJXYY)N6M(6yyy@/j9:: uڲe^{Mu\Ս6qD QQQ""RTT$...@-[&""{Ou~'ߕ IMMUʖ.]*d̙"R GTV]\DjqM'Ј{駥m۶rsBԬak׮@^i'@+MtEd֬Y믿i|;Ogggy""wJ7n(dܸqJ߯7٣W+..NlmmI=Z鸱vꏚ:(e?Z2ؾ!z9HKK֭[ː!CUVUMƊAȜ9sdҥ)Ҿ}{2xNΝ+---Mnl ]ꯋkH-NhDDDԨi4|/cpHGFFM6JY= yj*nk֬AϞ=1i$\v(oUS͛7裏",, sέtGmۆ'Oٳɩvʐ];v,ڭF999,t/HAaa::uZu((( `ggWicqU7#GGFF6mڄ~>>>HJJBff&bcc1vX*..ƤIpUlڴu׶l" P5qC5AD5 4"""js_U`gg7uF?=z-[*-d_ $!֭[~z KKK̝;"{}z)>xWqe3vk*m,`qvef̘4DFFӤL_c“O> ڵk{nL0ӦM7h̙D|6`(--ņ oqK;;wlNuرs 2soDDDDFܺuK+5nѢEr>ԨQ@֭[ݾ}[Zٍ7YVV&"w:HTT+kUʾ; 1X`krEEE)VVVҡC?+Ǥr0a:kP_.x[=O_e-D:t0u]ҩS'|[lW_}n|k:ngΜbcc#&L'O*":zӧO7xҭ[75kk-Xʾ[C}/Y R_ 4"""j{9qqqϛ;&T\"8p@6l VKXX!פ DWWWeu, @DAn$>>^$66Vo@{>+׮]ӧOKn[ҭWk]vƍBm "2e^yyyRorr2iuMe#]յę"""GLcǎRnaa!("wv 1:N*~~~yfv횔KaaOı~eRٳgocqU7C ٰaRַo_ ۷o6bgg'RXXXŋeȐ!5%& ''N___eͿڌ2w5INNwww9rWʕk.qM'Јٴi7;&%%%E .2}zNlmmI 폽_2޽{O>bcc#}cǎ\x<N>]/_\DDŒ%Kſ 7 ""F O<:t˗;&k׮U=fii7nm=GY}LݼysO?]]9yFDp{III!jOgggYXX`Μ9/`eesI|_~0gΜ:?NQz K,A>}QemmQF[hV\Y㧰K^Ν;8p'鉈$(??1b^|EsC$%%%A`Æ ɩ< |ހѩW_m޼^%"OEDD͛/0Dٳg[o ž={ܹs1cllls-,,`ii?v򌈈hDDDdVш¶mо}{sC`Æ FBBڷo0#00P9Kw6 DTTLbЉ,N\pgFDDƎkp[noFݻaggP1b^ 6  n݊1cƘ!z""hDDDdeeeGǎ;F F-[pmBa!O4ׯ_G߾}ѳgOrMj^M6A >>nnn ôi0x`sGDDD:5ܾ}9'Ϩ)**;wǏGll,F sHDDDpLdd$bbbsNr"jqADEEa(((aðfL8[6wDDDdIDDD SO=+V;zw h4?@߾}1}t 8FDDD CE~~>~ٙ;$zDEE{Q +DDDT.]Ç#99ga֭?WWWL4 } µNQJII[owyz2w8Du;wFQ^^cb˖-=z4'~۷ C"1Cha\~C 1i$;D"""'|͂ pEl߾gdA@GϞ=1o}Fιsh3gΠ{6mѹsgsGDDD'ЈNƌg"%%NNN999ذawwwL: 4wxDDDD+DDDT'>Sٳqqq<#u;DEEaݰChh(x <2wDDD 4"""ӧO_~x饗xbsC-PYYF[#GĴi GGGsHDDDM'ЈVJKK$$$!Q (_YYY0`vڙ;<"""j&N"""%K 55G5 h4h4:u ]tO?p;<"""j؉'w}?5cW^͛h777L24h,,,"5c@#"")))ravsEEEؾ};sNXZZbȑ#acccW8F}]#55gTg(lڴ 6lV^'!6zሎ6wDDDhNlqLv1;Xlvjp8q4 bbbo߾x7s@ј; ""jߚ;:ůpIWWW㏰4wHD]t 111pG NDGG#<|K,+ХKsCMDYYvڅ(|(//رcyf3vvvZ@#"""U׿C ADDá&ѣFANNrJL<mڴ1wxDDDDqT? l۶_*effB ** +t邈E"""j8FDDDF/xj*tP#SPP-[ ** +{1]6wxDDDD 4"""۷Obذa5káF úuߢFfDDD,qpB\t vW7 'N_deeaXt)Nmۚ;<"""z版J Xr%VXooosCf?{F޽7੧ӧq!DDDpJII?,6|HIIADDD%88!!! ֞9ؒ5VSSSј؇_5U| ***̙31|p̜9P+,,7|HݻNNN2e VZ!Ci`ܸq4wub„ h6--Ys%kn 1 }j8FDDD_Bff&~Nؿ?4 6oތ"5 1117n5kaN< sQ'N8ggm3..A3G[Ǐ7VSx7i}hUS 4"""$%%˖-ʕ+cpnnnС8w<%%sA۶mQXX^x...ԩ>>2vX͕CKfftJKK'''1c… DFFʉwR?XXX?P}:1Jq޽[̔swwW~%''GRSSC(}Wc5ҞcXrm{^M;nJ.ʍwLɍ>zYvdggڵktU/^,+{QիSNɶmUהh4QSڵkۗիWKxx3| JҥK̜9Sulׯ_yڴi@0rRі-[kuǪymiiiW*S+''GymIIR >|Rf,j7=SsTD{^M;nJ.k꨽}탚t+͛7")))2a+kJ5[2x` Tn~_]O>CkШdk׮@^U^^^n{M>k@P.۪wyGwnΝ;} qwwWs:t蠔jJDDWZZnZ w>VEkrK8;;+er\5Ԟcl9r*=O7%` IDATє1j=jMmS]ȝ'_9Nq 4"""Ƒ#G_P `ժU0`|ט:u*N8#G;5#222mڴQ*r7l7 WVUU… HKK'|R6"rssM@aa!΃ 0L0vvv1xmR2eʷ^VTTqmP{ksTjTҔOj{UqSۇT͛xGsX/w^'ЈΝâEkW^LPTTM6ak{{AFF,Y={;Lj Ҟ}j\~*裏Я_?@bb1+ew>2uܹƱ -KmNf̘4DFF9ǺOMNZN2s\ W:&]T{Xjg54%Fc*R;njP7on݊c񵮯Q '"xgйsg,X "8̚5 ۷ԩSqm|嗸r +1B?D[L|*ZB[СC ,PvKLLD@@i[PVVncc͛7'OƟ7n`Jٙ3g&MRn{s>@DD?HJJxN͛1|5XkʱL^zU];a˱}!ʩ<`OjlljZj=jMmgӍMx׭[U޺6+5'5W+++_ qYhVJ^dr%sFHM@KLLquuX)((P ^^^r!GHJJRva jKMM{{{NNN&7nQݖZIIIkSRRDDdΝbee%FRwwwqss˓'ؒDDرcz}{{{ILLT(k=ʞ={vꪏ""ƍ'''YfRݻwn:r,YDۤK>\vMN>-ݺuoooU3ciOwUߘr=OƎ;CQ){Ԏ>/11{ȑ#Ֆi?>>>@v%7n  ;vtos\yLrEqvvs;Bnn|2x` /5R5@ٻwGlllO>r1qqq{NGD 4H'bkk+~zڶ2_`}2fqttggg SvTˀVsҮ];UED+>>>W{oooqrrYfIaaٳvJTKW_}%(r…J˱մW1nL91Wꎫr6;0ޣfLC]{*''' SNСCWۧ^Ros@1˾DDDl7iiiHMMEVEEEعs'+„ cĈ䁪h4f7nW\1kEk}XrPLeKMs{6ks@DDDqFl߾Y#Hlذׯ_<իWcҤIprr2wxD,_-2k Ra!k 9m(%冚&N@׮]K/3f`ذaE;wn:={=zy///sGD-ŋѫW/L<٬q޽{cΜ9(--ݻn:Ƣƍ7|ѣG!Q4wDDDT֬Y_~}GwxzzFVVV\+W`ƍ7n'ψ HIIADDڴi`m#$$3G 4""#*nMԔ;f)..qqq5kCQeڴih4Z & ##A۴lgG""@#"R!44ӦM3wD5r)DGG7ހi/^#88C Cps@-؉'ܠm5h{#?N0ydL>>SO=_~QQQr{nBD0|XXX 22NHDDQF1wDDubڴi2m4sA&cSڵ  o" VVV&GDd.z̟?_HjjRtR 3gTWOU墢-[y꼏DDMF6d!b"""ja,,,h5 M gU1DVVJJJ`m]ydQv:))yw'OV)K.8չsZ3x\m.f̘4DFF9#=NpC,X@211RrONiˌ)++S~͛ɓ'?T7}v̙3I&I=9w ""Ǐ$%%W xyf̟?F>Q 4"^T?cBB4>#$$aP h"ٳڵ+Zn~* 99Y9755U;!u;dȐ*9rѩS'xQ\\ x7K"117nEW^yEuLڸJھtRU8p^{5pgl޽>Q#л55]8*Fuǧ)\;M!FccBBB$$$._M8..NVd1C}blРATe^W*IOO1cƈ8;;KXXsژ #"/ [[[Ev팶SW}$"j 'Q Tp޸qCYsb49A-qܸ 'H֭Bb49􁈈'ЈAVVO777t;9sm۶(,, /t TSRff&N ggg8;;#44TY2;^z w}71i$8::Gt~JJ xxx`Ŋ&ůb}C:ZƮ}긩cW/]ӧm۶ptt#O7"pqq_!//3f@֭ѥK]2220~x8;;DBBBzM}{ik抯x{{Kjjdgg3\)6mP&}߿Mibo9r*Qӧꎛ8k, GQ>SڵyQ~Q3nAM}ׯ_W^W\\,""7oTʊDDRʄzT)9P+ṷ̈́9Nq""#LDgΜիWѦMwȝxKKKoݶ*ӥK?EEE{pwwǕ+W&i7VV<==쌼<._\VZPUWO79];jT7oembDVVJJJc5v6צ)ƞ={[oVW.\`q""2*##`eewNmȪ=|}}]o׮H)*"L^ߔ*2־!ȩn];jTҔҐުظCmM5n޼G}aaa;wޱ=L 4":fggoϟWʴOtYu=-TGg$u*2~]ǤԜv&}VKSbNN۷*R;njPWAU͛[b?~|#""" 4": o2ݧzQZZ]^^@)mƍl߾]);s `ҤIJiXn߾SM]zU];aw}?~ߤմWVVX+jx&ơC,XZj7DE탚 ]si7u/W*[ """"SL#"j`&bcc#+K:}QIIIQ>,""AAARm{YYY.nnn yyy2qDW*u]Ⱥuʕ+d=oo4ƚ/"j4S'DD+}ӧ;vL\\\ ѶSlРAdt3f8::);0jٳGIf͚%*g)Q-m_}ʅ */ [[[ X}J̑S׎ڜVw\U1I@@J@@_F9Q~Q7nX}jc3T%NNN(NC۷N55ު7~ԩSU]TT$} 4H^%&&Fi'ۇT嫰PVX!֭[KVO>JAAA`ekk+;vS-"j\w$"2]8[6ڻq];Srrp毾ƍ+>vff&Ǝ,[ > p |WXz5 "fCC*_/^ĨQ`mm˗#88刏ǼyP\\;vZ8z(?舤$̞=;{ 6mQwݾDD"C("C`}|r,ZNlLeK UufkܹsO*ƕ+Wp1tA9@O?4!U2L0HKKrlԨQ8p zQFѣprrU Tֶ7tP|8p ^z%֪"Md'OT~.RT[x1zꅈ:2%--7D-]ff&N ggg8;;#44Tބ3g0f888O>W`Μ9h۶^)))>|8+VtOm<233?0nݺġ>Cjj*Ν7yK rC ##Ǐ30p@$$$(/^#F=>W 1|]XX^x...ԩ<*U+::G>7yզM̝;gΜ?ݻwLj#%%%x7бcGaذazLu>U1_ߦ䝈Z(Qܡk/53撸ZW1;vʡCU d~$'')xyyUǤ̘1Ce…@"##EDʕ+%AAArEʒK@@@u 9yVW^@N:%۶m>|lܸQnݺ%G޽{qcU̗˖-˗/CuN 롇_e<ڵz-""۷Wꊌ͛7=#""@>Cq<3ʹU\f3k׮T]@6DNs\ypN55 IMMUʴΜ9S)34#d""rJM6M(yyy@/""fzx|z+vttr-}X2aVZZ*Z9nkk+?v\Ǎ/mn۷E& JyʗׯWOAAqRurrRXX(""/_& ߺuˑ#G?T]@6DNs@W8ZM6wﮔ?W|?+s,,,Wm{V^ O풒wڪcϞ=:t(T9ޱcG<'O"00Po=IcǍ/uae,ܾ}[>ClllVVVZNνpauO2Npڵ?^)>չsj_رch$3xM6}qvet͛7[n땧t5 ;>c[lۘb,L<cǎ*ٿd^ IDAT? ,,h}<z)ᮻ»ヒ9s **JuLj'&"Q ھ}RvI}Ν;'NN.X@111ն+஻ҥKqU*~n:*3g0{l믈?1c6F'erj /???,_\yOW^^}]gϮmW_}fO?"dee-MQ]杈Z^sA=l"pQWWWIppp_LUjk!h̸@W1wwwqss˓'\zU9SȂ ڵk,2rHWC;&JKbbّQƍ:ڶm+d޽zNj͛ڵkR^^.O?#d׮]qFc/ݺux)**X:t^_;$!!!U^7$9tѣGED$%%E);|V˽+ݻw;w͛7%??_bcc{={ʅ 6O[nݻ$%%IYYYUT]@6DNsDyݱ 4hPݬjKE!EEEGɠAQ%88Xbbb$))IyGsTTƴPaÕn3bN5-[n5{M8==]ƌ#,aaanZ/HN_b ebkk+rqqq  ׯ;rJqrr@9wޱLyk׮bcc#-&MR&tҍ/**JԩS2tP})ILL#Gvff&Ǝ,[ > p |WXz5 "fjL͡Q^^D0`er=zG\\fƔ*<<h 1j(ڵ :u“O>S* W1GKyy9ѵkW 8P)/((={㏣9EGG#<T^\\~W\A||<}Q8;;Xj֬Yo>\*^ R4h2y= YcQ]pssxwЭ[7?ĥK]MQЛ<'''s=0a"#"@#":u*PeQd@3g`̘1ppp@>}KII9sжm[SRR0|p888+V;~%L>m۶#ydff~aܺuKg!55sE K)C>}ʶpMܺu s[O߾}QXXtSvvv8puÇWCM{wWUueU\W\0w=e­2&&ı,ul*E%3BEE PA7EY߿?.^9yrs`mm HJJBQFy&'NT8z1LMMSSSy@kqv믿,[Lm[r_hCmKUT*RWXQ;nԩSzN[?7oތ1cظ&C$""*@#" m߾ХK 3j(P5$Oq֭[CR)IxO?J{=%yVu*+66 8x nӦ ^z%{pGz]---3h޼9 ;;8?`bbʅz CŒ%KtSm}mt*TnG""""jg9-@?~=~XF% (w)wL%~$''4Nm-bgg'Ǐ˽{䧟~]J\\lUcy6n3f'|" S[ٳgW7ntrr!C<1F"ڨ>YFCDT*@IHHW^yE,,,Z&O\Vwܑ?PZn-Ҿ}{VP%h"O]ӧkGDDH~D'۶mӨ/R/4RSS5^Koff&m۶OOO%IW<+2|pqppÇ+DEEɘ1cTF-׮]hhI&nܸQ5j5֡C ǩmhkEmKSmmTv۔UکS_[[[100Mk,Wm;Pi5BڵKI\몶cuY^P9;;W/Ic$"cM%R)JDTT*BBB*,аZpH!444hR>8r@Y)uYEill;v&L۷:WWW޽{D1O̰a3gD\\ԩS1b`E)oČB~VZ;vcǎ1QUX̚5o$"Cp  DGG+˜?^|2dZfgΜQ~CuVܸqo1(ܿ}0oHwttƍ x 58;;+=+,,ġCRuDDT0FDDw(DDK,5֭[`L߾}/RֿOfy7M+QXX_Uy=;AaȑhӦ LLLpqftiݻ7:{ƾ}^zׯLLL#00&LL<8~8R`ddQFUvQIDDTJBHHH> !]|||!!!zj 1[hh(|||յgQwDDDDDDՆ 4" ///X[[È'ԟʆ gg29w>4o􄅅w={Z>66...077G˖-zJŭkPj#&Јݻwl`8z(PJ:p@r=;_~%n߾M6aƍDff&ܰ~eل 6 ڵCFFO?Pyƍ.qW*ꟈb\W\e`kk_|HOOwK7bĈRe8qD}+?/\͚5C^7ZJ?`ɒ%k֬9WREVLU۷t颔~ga+WӦMǎ V[JRNwe+j+!"ʸr ͷO:88ܹS}-Zrss[nrrrШQRwe+j+@#"fdRRRRf`C$l?@u[[%U?QmQ5suuݻW)KLLxzz*e[ ճ?~ԩRq]gu])6l`̙:uJyq_aaRWTTSDDDDDDhDD?㣏>͛,שS'@XX_*u=z 2Cթ_dff"11 ,@۶m`pe1b*.*˝={Vv2d]&66fB&Mtn7663gά:OKT'}hDDǎàA0rHi&&&8~8]m۶/>c̙37/~OfogpU ]t /]رcU{Ca011A޽o> 4Rq߀?W?ne> SԹ]_R<-]R1F""^*)h""*ER!$$E+:Q9)Wy߉lX[[Wj!Pԫ<@#"ÊAzuDDTXYYUzKKvic$"@#".\~0}ꏈjJR>ebׯcʔ)hڴ)^7Vŋk+55^^^5qex9993glllо}{;vܱhٲ%V^Q)SxאuhѢZHDDQֳgO>}Ի?~Tف4~wuuźup=ݻ2d"""8l۶T[EEE777DGGѣGJFJJ ߏGiii ĢEi&׷̱$$$`ذah׮2220}t|cHNNF\\._][AAD~~~PT 1 ; "j-jPeqAAyyye7o۷+e Eu6n(>>>+e@M&""YYYJ[?\ e[HjjF; 3f9s挲Ά Qxv)߿HDTToAmǗUD2*X b 4ܹ3q]mͅ022*Ֆ_BPP.\ֱcG$%%!77&&&ҥ pMq2-[ƍjԨrrrЪU+\~ʒO>a.K +W<$*%%/^ŘΝ;eYenݺnҨ IDATQl"@FF'o-σSSSlݺUx1~0FDDDDDfjj ή6׮]}bܹҨkѢ ))I)SСSkccZN>|vN/"((ZҺHDDO 4"" 99N®]yfo_#>|t}ATԷ%?~eggPkݻ:tQmcccر0an߾Թݫ%&&<==,>HX 9sSNaĈÇ-Z3** SZjv???;HDDgU@Rݽ?MDp dgg>333q=dggÇ)еkW,\5oM6wpvvY7u&LgcUyZ׮]qElٲG͛pB@۶msN 0q) :زe ^z%кuk\v C AN>AbccѧO7nF&&&q^x`޽֭NgٳhҤ "##8{,^x;w/ &&"Rj,ϟġJ)9A!.. R---ajj 6`„ ǨQ/"<<FFF(,,TO:Umc$" 3+jY?÷poUym۶bii)3f̐iܸʙ3gJCj޽{[Ν;'666Eycɩ̾Mk +X[[ɓ7gVEebbb"}p8#""_~bbb"m۶)u-Z94c$" N""׾;[:/ohhOOOظ#nݺ!!!B˖-1i$ڀoZ%""}3 4""RxyyNe o#$$3j7oYf!22.]o={o߾ѣVXW;L""""LS&]JyaÆ 044|F?D?F\\^z%kGllä(66f!Cٹڧ&}ybcc1szw\Tc0zh 8׮]CXX.\SXvj0J"*_W?[o]vo߾֭.]$}I +@RUk?yK.JJB.]pR˨j3mc)Unݺj&}y<<<~j;.J*͖-[V_~e/Ϋ*Q=!"ؽ{7 믿~%]vŒ%KpeGK=ĉXxl{Xk\jUUhh(|||DDuԣGGGGL6 /~we?;v,lق o60ydٳyyyׯcʔ)hڴ)QٳgV)vF 333L8QΝ;>͛7GFF<==aaaݻcϞ=Jnr `mm sss 4x뭷4n;vθq|̘1ضm+e[rxaccN:!""YYY:u*бcRbccssslWV|K.aXbEɳTxyypww˗5R+''ś ڷocǎZF1@ZZL[[[XXX^CjjR_֭-Zz\,^Xm"{6m*UW_9EMiӦz*t$k2 U!":%++K/_.vvvbff&ﰈHܹ#7naÆʌ3ȑ#RXXooJsqppm%##Cy K֭[k.""aaa#9{KS_dܺuKΟ?/-[믿*lgϞ@駟tYrrrO>ңGWyKttFҵkW 7nwˡ-9M6IFFlڴI,]T222dϞ=@v{ESJvv,^XHPP }  FFFJ}߾}DFF*e!!!2uTq'͚5CCC_Jo剈Ç\%bhh-NVVHe3gHZZZ 9R dڴiǏHnn4c  gΜQٰa8::juΝ@KWDdƍlʌ< YjRvZYdIX*:Nu9߿^D+j ѳ=s)))2k,iԨhB.]*wXDTˢEAMtRZ窒@sttr]L}****uޱcG1553fH||FږIKKbmmi[ND2dȐRaaa@\]]#Fh$EDDXZZٳgKWoYѥ^)+iԨˢ^obdd$;v2СFrO1bgg-Sј3 'OrEC*ъKtuF.c,zL7o[RۣӪW_Yb .țo)Ҷm[Yv<|PaQTTT$Ǐ3gJER[Nv%@311zS}YfJ믿,vejjZr<Nj޽T}aatYT*Kbbraۼy{{{rJjHHNNN+xҴiScǎi]PcfǏ+ɤcR߹s1eggK׮]YfnTqڵUcYI=ȑ#%>>>b)㥪畮W!z@#"wiqwwڵ|nW "2i$"RÇW^QQQJ""r̙rܹsbffT*133(qrrgg2Oaavӭ[L,,,?W^.puMJdddeeAɓJdhllF_}Ec:F4mTo8;;+I+((*ܶCCC;v$eILLLcDorVtr^EFF*LӜ7DhDDT-モnݺ+IDoW\˗K^mۖoC@y2wbll,{sΉ/H @d̘1bjj*Gk׮)mݼyىKJJJe,ҿ?d ֈ9;;[%v*-[(+߲ƯKebbb"}pnT6moV XXXLt/FV0f|wwTK\pA9..۷/T*,--qE̞=&""* hDD5 %%f͂,\W^ѢE }GDT0vX|wHOOGhh(1c vBnnC%=ٳs>}: yMDDT#}@DT\pغu+ZjUVaڴihԨC#"5ĉ1qDܻwvBHH&L+++?ӟCCC}KPM=fǎ5.Qy8:u իΜ99s&gD`4iӧOok׮;1j(i|N>0* 4"pA`HKKΝ;7߄#"қ-[?ӧ3f`߾}4h$""" hDDTTT~ѣRp!>}00W+Qq;wDGGЭ[7~)RSS&QxGD|l޼=z􀧧'ZjӧOСCpqqwxDDuBgڵkзo_,[ ڵÈ#i&ܽ{WaiPIM=ݓ7|O?ׯ_Э[7}FDT/_֭[gb̘1+߲XI>>>ؾ};BBB 5Pؽ{wPF@#"*Cff&fdggc7oڵkЈl޽8t///=ϗԁBCChDDYzz: _* ТE }FDԠddd` Edd$6m &C JwDDD@0FD駟o >Zߡ5x)))غu+BCCm ի#""z 4"j.\+V`۶mhݺ5͛iӦQFߕdڕ+Wн{wx{{ ۷wxDDDT1FD VTTVX={[n󃗗@DpIb}6 ///L4Qabٲe8r  ͍!"q!_=ȑ# wwwގODDDO@= EEEعs' È;gDDu1^~e!##!!!055Żヒ{'NݻP 4"+WҥKpss? Ј{.vڅ;v ?~<|||0|p;D"""@#z)''gƍ еkW}FDDzm۶!44gϞE˖-1qDx{{V\LQua͚5x!Mm۶jMpttT;<"""e@#z͛Xz56n̜9s؈B EXX_~ 'OFVLQ+WbͰ_W/ֈ qQ`׮]ʂ z-xxx\!0FDuR|| 7&M/F;D"""&ЈH_b̘1_aooЈΝ;صk{9rJ2mر0d IDAT55wDDD#&ЈHo駟o5̙3g!DDT蠟cΝ CDD憉'bԨQ011wDDDT&Ј;Ə֭[?Tkj(((Ft=~`JZZ͛|gxwuAx7qA$''c֬Y8v._u"=zݺuqDDD hDT%.];#:`֭裏pU,]-ZwxDDDZ۶mG7,m/#//FIDDT0FD &k׮8z(֭[$̟?VVVAQTTT2EEE^իWQtDDDhDÇcԨQ0`m6\xLMMQ hj8<ƍWÑ?LQsN 0#GDQQߏ3g`„ 00W8p022)LMMabbccRofx3+ D`!88+WDbb";4"""?Damm KKKhԨ,,,`ccF7FRR {DDDuhDW_}?n݂vލ.];4"""*aڴi6mZKKKccc_#$$ݫ6nک>0cEj JǏ;: 4"­[vZ"77.>CnZߡQ-T}Qyxxʕ+J.u!Ɗ1;Շ 4ʕ+3gfϞ [[[}FDDD܅ `cc0괸8nZ>pօ+R &Ј .`ʕغu+l2۰whDDDTGXYY;:۰v..X0*5 'Oz쉘|W|2}&ψ\ׯ_ǔ)SдiS#<<\>66Vɞ9s۷DZcǔ gg KKKÔ)S`kk kʭQ߇ :uꄈdeeaԩBǎ5ft\rnnn9 Hڵk9r$0qD(oIuTTxyypww˗zJ|+չsyȀ',,,н{wٳ򱱱pqq9ZlիWW*~]+k,ͳަjʨFEc*nei!DTO?$@^|Eٽ{;4"""҃8 qqq:sqppm%##Cy K֭[+\Rnܸ!۶mҽ{wSݼySZn-NNNr5~TrssED$??T}Q.V )&&&r rh嵧+I??? ϟWL6M*խ[uZR-z[ 0@+_1UԿ6ئ"l˧eUf WSAۭ6hDT=x@ i׮Ɨ55lUI9:: {RV¿HEUY,/̋ξ*^Y}8p@ Rcǎbjj*3f̐RUʎСƅȓHήܾ{ Ve5jsr>n.c*2ib軠2t=toiͧ=K[ߝ 1go'|vaѢEpuu˗^z;<"""î\hҤRfhh< WHy>|_'OKկ[VVV=zݫR{YQLڨ(e;wԆ:Ƨ-Z*en@L ''G+_I>i~;_uSyO-+.}twFu~O7DLqW\]3gĕ+WfkNQ=`jj ~&/H>\6_yZ ,]m6;v,ݻcΝr{6GRRRf`rC:]]} `ccOWREWwLUvzV4YmY+.\8(Ku|gn@#~wpttݻtR\z?ЬY3}GDDDȐ!CwVʊ0FAA{QQ2] >h"MuQQQׯTk_PXXXn{ꟵeKRTHLL/#Goy:bw^,11驔{0 "Yy֮nYni[gih b(s 3耼f뾯}]-ͼו[I^|YymLL0A)6l`8p#F+~5Y:.Ys+`{LjlJ~CMԴw~oѿ;[[={رcEHXX|BDDDD4e ɖ-[ի"$((Hۧl,33SDDbcc%>>j999$ @EDTefgg8p@DDBBB|,Fȷ~+"7ݻIUUlٲE."}Ȱٞqۊid͚5I``HzzɤI$44l>}Yn\pAx `8?䩧+Wȉ'w,%%%v2;'4xzz_MӜfL;Ks6F[ ߏv jڻ]L8wgk\ 4V+'[l:gFDDD-LSh""?Oݥ_~r!gyKGD, 2Dbccm*QQQj%**J:}=Ke6lN'r1>|Ν;}/=xxxȃ>(MjQ1 0@BBBlooo2e F;v`t2sL1 'f2{Rs'H``x{{˄ ܹs MKKVKJJ鯱sZiNEl{U;Fm~Þj=cT{Gl 4n'ۢo⧟~#<  >>١Q uaDFF"77z… qQ;v\Ng.[ܴ;v,-[P7g@D ]z~!V\ .`ԩHNNFXXC#"""[oŋ;5ċ'Ü)ek{!DHqq1?!$$/ƤIp)|LC,]={S8zڸH}Kb\o$jΞ=o׿///̝;śC#"" oUKnƹ$IDwTNNVXdtox xyy9;4""""N']q%F vڅ1c`8rԩS;w.gDDDDDDD hDwH]] 2? k:tӧO/%""""""j6[oĉ7nۇ١ L&Xf V\_?M6{uvhDDDDDDDdI`x/2e N>L5C٘3gڶmPjp?^xhW^ʼn'p9gϞ޽; ;;<&LiӦ9; """"8q"5c heeeظq#郈gD;wB~ WWWgeƍѽ{wgADDDtuvDDԌ5Zrr2hD* -- >hyfddC """j|||5s\t邩S~L>ƸqPXXbs΅? ͛___t{QڈC|||}SUUg}ѣRSSQVV3fݻwGjjo~~>兘+5j<==c!33֞ڊZ~'""""".^!C 88puu1adffbJ2mx饗)S`֬Y8r.. ߴuW^Axx8z)<+V`ҤI?~|-DwH;˖-sv(DDDt5O?5k8p >o'N\YC@uu5<<<7nꧬ ~~~j`0PUUV7nݬ`0 //pssjjjHIIAll, 33 *4{kZ}pU[n`O?'N0_CjkwwwRflӸliÎ;0|p0Ku<~i=zѨw-k`*..[XSJ;HرQQQjݻ7V^G}'[P9`,::+]6dqUn`_/#<<Æ Chh?|Xd z=VZ 6 lc|m=U 虦<G;[{MKbnCs;LDDDODDWk>yۮ@3}ݬ%%h0"""""""j@+**;"%%Ŭ>;;s΅? ͛___t{QSTaa!N ^^ &( 7 5X+s8M;rHxyySNXrCCQ\\Dx{{#,, [lqh Ox{{cܸq(,,c6;5}Lc³> ___(++Ì3ݻ#55U7?? BLL kQ # ͭ_ը `ɑby' RޯXBΟ?/III@” "6 cJII۷O$00P ED$--ͬ۷_g""ǏN'3f̐ yW_f}``ޒ%KҥK#:uwpIllHQQs=eܨ=j=cPӞilk׮bYv={ҥKXl"o߾J@;&[nҫW3IDD,Za֔DDDZI$^x 7nT eeeׯHUUWWW^pl@?ȍ7$\C8EDM&$q Y%͏?Xȑ#̙3 ą m)3NԩΟ?`6m`0X8OEEEܹ3z=n9Ν;555J]S=j1iϞscǎ{*u}E "[O:d |Pjͭ;XIP@IIvLDS_kK. \ SUUUVǤ6b7ni=sت=njǠ[9*++1ydL27߮#o"""""""j^@TTT89ɤ3g(eƫu릺䕵#ا1A1S;wXoܨ΃,X7oFRRn="""""""j@|JRq򾮮C25Ə믕'O2-X_nԌ ={6rss#T]|YymLM0!1>K/)Oܿ?ocjkkf|m)u\߮#o"""""""jf/֔EE/'[lW* ٷo>++KDDLxI``HzzɤI$44T._lקO ֭ .oz|SDСC驔k47?Sr9q[Dgd͚5vǘcNINN{^[MԴ~el9xղHHH^Eo%##l{sМE/++KfϞ-~~~h'@_~.C<3f ㏈X,2d///O~a^/SLQjL IDATic N'3g ~~~2k,O:rFiii2x`jҿIII1kZq>> ooo0a;wάHHHH٫155UDJTT$%%5iN[u͞1jOml6l :Nرc2|p ;w6ޞ9h.Z/<"""b>M5"5~tS8ɱyrcyy9z兘_SS;^[1Q SN\hfݣ5޳NDDDM?rHINNk׮IVVDFF*UϮ+VKRR0 [kvZ)..k ٳ,]Te˖-@!رcuV zR4m=QKOr 4V5޳NDDDMၔ2331h bׯ_WWWܸqCUeeeTWW*hZܸqfm0yyyPSSc3~S;^[1d$o$"""""txO?4=h%d@jkkU///ئ[;v``%S;^[1QYj*`͚5Gbb"\bMq+TVVbɘ2e ϟߠZ6N[1QY5zh={WFXX6mڄiӦ9;,ł yf$%%!!!Aj1QYhpI̚5 G k.%2[LoԎ񵥶׭[ʭo_kec l̙3m۶G\;=cquֹs'ύnSN޽{Q]] ^@FFMNNah\}M4-3صk6nܨfm6񛶗e=Uw,6a^6gSOWP]]UVNC6m$~'NT=jakdPh,YDDDD駟bɒ%Xj6lʓ-`n>(::֮F2dڸTT2c+t:^~ecذa UAmvjb""C#2UMy{vtrL^x]XXcիXb~'|> 1Ǝ3?7~1x`Y!++  Bjj*>6Ck|0ݾDDznw#=iO?xGp:t;vTꢣ#玁5vLbIӿ1<ݍv gaa!N ^^ &ԩSJ-f'O? ///iiiJ]vv6Ν 1rHxyySNXrY/ӧ7n <]v3oG!''7K2}:󑐐^/// ==]/((Q{ fتWޕ7k@@~gFOtf13 7o|}}ѵkWٳ6iC6tL;w΍m[(2DDDDDDD@ROnnU*));vȾ}OP7xCJKK%##C:u$!""AAAvFǏN'3f̐ yW_^DD.\ AAA+RTT$sDEE5TllGkv""";vLn*W^Jȑ#%99Y]&YYYi!CHll՘=ܣľ~zϥo߾""2{l o˓O>lmslŊryIJJ`ӹܾ}ܸqCDD.\(F;Us[=K}57%[yGc"""dѢEvGDDD-[S>j'@[pl@?3 _?3 cƌM6M( 2  3g 9x/={ڷk׮kv$Qnܸ!Mjw^}FFP3JgΜ1_ 1 ""ry`6N ׯ_* "bڴi_|QU" >̍Oce덚:L=@#"[O:΍7飔%$$7ݻl FQk?r`֭n.bgOĉVeaF^^v؁Çnܸw<~i=zf۪WCt:k׮foPQQ>J8M2>UHjkkX>Fyyyx1tP,YDUXCܨ)V瑈n$?244PRRbu_???@UUkI]t `0 7`0|="3UYYɓ'cʔ)?~UVk֬Axx8qjkkt\Xx1***ƌjjjlWbĉg}f$J[s[S@Y̘5U]] www爵ֈ>I}?s֭}ɱ.]4Tm۶ܹSe7?۵ `HJJRl25zh={WFXX6md`[jqOh׮^u̝;6lP=Φ1c?ףsfuVV1.\hPW\\GDDDDDDD͗ChD_e,V233G\]]%>>^jjjD;vPLvno+K熈ȏ?((۶mׯ˕+Wd֭ҷo_gMGk-qG"""}8deeٳϡ}-)V";5~tHMD$//O~a^/SLQiTRR"?tU^~e6SdjbV*QQQj%**Jyt-O6+,,g}Vz))$L2oÆ JǎÇKhhܹSgC>|EDDAաO8$={DLLR~UرoqU'FHKdd$Ǝe˖9;"""y\YX|֒b%"ZIv;! s<`<N}bĉN6>>>A+~&{F9sR7þ}P^^:\|7oƫ{!i4姱l̝;fa@ǎҠ87ڿiUUUxg=z 55eee1c|||н{w*#!!z^^^AzzR_PPQF=2331WM{q ̛7ڵ+٣:&""jyDwxxxHpp;w_~1[K(o\vmY'"""?痢5X lfe6+))P )..'|v5m{ڵR\\,k׮ҳgOYt˖-[W7""Bȱcd֭@zԏ9Rڵk%fՏZ{qXBΟ?/III@TDDr 4"Z=DDDdZZ`555jJYYY̶?>z-lܸ'Nwfbvuu5a0 Vō7n`0 555 66A)B3֞iׯ_aWLDD-Ak>ln$""""յA{^` 0rH{voڶ_///̘3&jkklaǎ>|8=K.xOѣس֞if5OL-il0h۶Rf)הժɓ1e̟?AU5k <<rJSyrsvDDDDDt1XQQ'Z.X7oAѣqY[?i&TVVb۶mMj1Q+Ј*UUUneTQQavb]]O/R3oO Kmfi|mZfnݺu*YFɓ'1k,9r6l]Z{aZSmLDD<5 l̙3q"""""u=z$''ŋxwpdgg+3331o5k&""y}Y a BL:zz&LSzFX+C||0}tcǎHII]vv6F ///t +WTU!(--EBBL0IXx/".^?O41bDtݻj˖-ùs h߾=^x/իWdt:̟?{٬?r΢EЮ];DFFbɒ%7|SQKƍ}Q| յ~MĞ#G*eݻwoΠ h4!䘵zMy=zh0{L5ݽlob[~~>_JJJхڶmYJ]t `0ЦM-СʾErhƤҙ3g۰ͦu.xxx***ng,55I4&_RvI@bbRfxו:[0Sqqq/R)3"ְagFnn.k._6&&L:^""""""""j@{W˗c(//ŋj=ɸx"}].<<СCk֭[QYYiֽޫSN_~pqq#|rUF/"JKKqI,XX`-Q˖9s-5/w15<Iu{ALL F.]@"--wc֬YxW1oH"""Yq5 _cbٲe G}///WoG?ΝҥKcСرc2pAFFuS֭N:e1p=z6;u.RWW, 4pit.]_|ŋ_|~It7h'r?hDDDDD|||Zl?裏\7u 1|pqܹv{E۝:lqqqAtt[npwwGN0{lٳ7n@bb".^H%bƿP0@DDDDZa@ǎbVs-uRPPQF=233͡Csϡ}(..Fbb"-[(mXJ#!!z^^^Azz:qF#(噙JC=$6砱~돿 >,|}}ѣG 3f̀w0w[k׮bYv={ҥKXl"o߾JǏN'3f̐ yW_^DD "6Ν;VbTz)555Xci1?W+VKRR01Yƾ>|XH>}̶߾}ܸqCDD.\(F;sj'@#jZ/<"""j^xAƍc #GTۿ%aq  nnnJ+e'3f0ӧOKvUj5uuTVV*eUUU""JUiwڴi@ EDLȠAxy7de;{&bXZjZ{ׯHUUUyyh,f0hZ6m/cS{5W$hDTkGDDDM* IDAT߳gO /_VʌcbA{!3gΔ#Gii{_~E^WKl߾]''' ?~R6b]Tj$++A~;biӦcl… jͮ֊/6X?ڼչSc$t:]Ǐ :TXouljQ5~hDDDDDdU~~>m۶J6Zj|||f#11W\it{Сx*++1ydL2oP?yd [nѣGq)\t kի;v,~g/]0 9@D`0^`` q ޽@޽֜Z;vlOӬի8q"<<O\sK>|X%$$DJKK+VoDԝDUk>+Ј`ݘ4i8P^;͛[R";;[y:u*݋jz4h_Dii)N<  88 ,v]vaƍms۶mSjxQ[[aÆ)(1fffNh4ذa Nk977A999 ʌĩSЯ_?`ĈX|9 ..Cmx<`>K,~Fx169JDP/R"""j'?Oݥ_~r!gyF(Jm? ooo0a;w6nذAt:DGG˱cd*;w4Bzرì SNfemljDDdj 2Dbcc=6`0HϞ=ڵknvNK{S;/jypssˈ#ߖJ}:t`gGͨskWiDD` ۷oȑ#ꫯ$$$knsѧODDD8; """>H:sʝz_I<N8ѤEϟ?;ކȈnsY"##1vX,[١1n |}}裏:#Gşg:t˗/իuV/f̘///gHDDD,&DɃJ̝;6gt;9%;kg}'N`ј?>BCCd\|9ѣG5ah4t8~8Ν밶(Qmԭ[7sSOaʕ ?gGDDD4av 0aRRRx5;>>_>}k֬?p$$$`߾},` Z-f̘#G/KC믿mO""""""""1FD...gw^u֡!zL5Æ 7|O<zw}bq)$$$ॗ^BHH^}UȢl̙3m۶m\\@Tg wRs/"ք 4f*$$1g^!!!7o &`(--m]]|駟h,UWWcժUЦM#)) ?ĉUNrqqitlMem]wyC ^e˖9F6m>찾nhD\vk!??:+odGzz:?c充4hV\^xEEE(--;#4*6VHMMuhWAA K, P\\7x}pP[[ 2_999AJJC""UZ$%%aŊ8z(ƌ bذaZÇ#22pX"tiDDDڵkf}WWWc8<:;6?GSp'56_A~~>?\HiYYYtx%i,?#bbbCDcbٲehD-rٖ-[P^^Ç#66_~%"݅ 1uTzzL0NRMoƸqPXXxGp5%777G}̟?b Mfq FHHHPneAzzR_PPQF=233ڱUok}e`0`޼yE׮]gUs|SO5H@۶m1|s۷̞=[o-O*z{{7:""999@zjLu Ԝj睨E9;; 4ѣGhZ zK˝5#MI-\PHNNR|r 2K>LȘ1cDDvӦMJLȠADDd̙@<%W,-ڵkZ+ 7nqssSZݻWyaz[ϗqnEDJ94_@JKKի@DD\i̙3ft: ADDΟ?/$ o޼YJ?T5&kq:joNZ@# `ʕYfa޼yСC#"""'khݻwǙ3gPUUV C>} .UII ڵk^2u ϟoo6m`0йsgFݰ>K}{xx,n[,;vg=z?8Ν0lR,͟mͩqt:TVV`0M6㩮|||P^^nuݸnݺٳx":tk׮ ZUUU bwwwGMM Z-8l5y'j-t邷~?DHHf͚尧&Q둟}C{ٳbhZ\z۶m… b kHDdNAڵ{gGΝԩS \~SLe˔8R󔚚 ___c֭jV~qOۇE@@|It9˭Q5g'N@xx8bccѱcG,]%%%pM׮]_̙3۷@#̙3vZc֬YC#"""""hD(]t ˗/'|x##"""""hDԨO>QTTg}:udЈ5 oڵkxbbҤI7ozeЈMIptt/_~k׮ѣG1c 55Q3 4"jRlmmSOѣoQXXP 2vvxDDDDDD q$F1c %%F}b֭j NQ7d޽?3:w'|ݻwǗ_~rkGDDDDDDM'Ј۷/lقǏ#,, :wy#"""""&w$f+77K.֭[c̙C#"""""&hD]|+VUPYYh̙3۷vhDDDDDDpZ^˖-իW^CΝ5b@#Xv-,Y'ļyЫW/kFDDDDDDo"@D-#^~e:u qqq׿`3vxDDDDDDpZ,[[[DEE!;;~- !C`׮] NQh0fhݺ5F}"!!Z!q 4""233ضm:wcԩvhDDԀlb 09FDd/EaÆ 9sॗ^C#"h57"**V:'ЈTҥKfBll,<==Ci"""j^Ls 4"">,_999s"??= 4"" m_~6mBN3gX;<""""""8FDTxp9ѵkWDEE!;;Q=]ppp@tt4N<8?~}ѣq!kGDDDDDDhDDQQQ8rq5#"";wBDDDDDtqi4곃 FBHHj"YhDDLaʔ)֭>s[;<""""""RhDDX>}W_7 Xt ˖-͛7cYYY>}:ڴicPZcKCĖFY Cxx}նqc'TB_7iu\h 5<|GXf 1c ̘1jh4ظq#}݇<hkb_]"\VZQ@@~7v?j)hNcàAIIIV~z\r+VUP^^h̙3O}L@SW. [II i6nWS9͡M}Jڶm/ヒM6SNx饗믿Z;<""'44Dl...Lm7qB)uSќPhDDVW_}Νw֭mB:u*о}{8p@o{VVR̜9ر#~'e?\pSN'1f>jRKL IDATСC___,[ h4#22V`JZrr2Ο?q NNN0`RSS-X>uz-LkN^^L777azVcijULWӧ1j(899wHNN֋I~9~~ ݺuðaL֩>888kCsyG9rgFvPPPH8;;GHLLԋ777Æ #&MLj+:o:vKnc4u%YsfiW=2̚5 "L6 ܹ1M j;""jT*++eӦMһwoh42j(IJJvXDD-ٸq %00P%;;[ _<_x\xQCkjK.Jnn狏.KܣzT~IqqqiӦIII[@֭[';;;iݺ\~]DD.\ @y+**[[[IJJV+={r tl׌X>UUUuf?7N222֭[&5PBIII<INNU={,\l>@_.+a~GguV޽vGIqqd1@{=|dgg]v):T֭[)z˻]ovKXܹۨ#St5fIW=5kHAAYFHPPRPP @e\Pܡ S@#"jZ|w&dРAcjŰtmܹ@l٢:uJFQQ""RVV&ƢJ'|"AAA^N/qQQQ@¦+""2qD 6lPwwwWh۷O|QbkkkqlKlXz2EX~tWTYY):tF#999O˺u$ @4J@@7dĉ)|f.ĦC+W֪r ?Woܾ}[Wgmt_,1v7߈KR\\,+W2n8yWGwOܹSڶmMbfOKc4vב49^ Yz.P[NcpY_^{{{С,]TJJJQcꃴ!@ks/hkNHBB}KMc޽1 ,`by7ScbbٳǢxk&Kcqm۷Kjj]ǯ*ĉJ'w 3UoKXfLx?sҺUUUIll 0իWtU/DVZ%=z2buXQ{~3קuscmW՜;-:8sAK@]8 |g8s &Mwy/\zXaaaoFI+++S.))Aee\|fOS#""`kiii z- j;x`@ll,= HOOǐ!C}MXd BCCꊩSK5J8565X[2uV899'+W*co߮>}ϸ}Duy%;w&Nh~O]eeeNJ+}PsǏW4 N>;v 6lMZcE 0NPs̷hi Yj3t^oC:̷k#"{ʕ+pB3g|n`hiiibgg'(7nPu ~~~<,%""*&GGGXRP[Z(wRS%|///IMM"8q[n@ҥK(1mctǪm:p犽k׮IFFx{{R񓚚_rEU}tW|KMY}{K/ɵk_~]WU%''KYY$&&JDD157sնQs%Ԟg:/--96."Ϸ^cM9FDԌˇ~(boo//>}a5YNܹkc޽Nz-GwwwyWT06p@΁$%%IHHKHHů,,=Kpp8pֱqqq,7oTҖ.]*BڰaH~ĉ!~bS oZ\n>}$ @<<<8uꔌ5JM&O\?+"RZZ*wGAj eΜ9'vvvұcGy7k݉T~"OvmӦ^ZZnmpM躩<te]VYƏ/999?--M.裏Jnn17sSնQs%,9Ϫ7K`.?Yz4k2)++C\\-ZDFFbvhDDMFƍeP)..F.]p%ơh`ccJbӦM €7n`޽xqƍEvc+ ŒkimC}FD 988_ĩS~z<{0aBQ}>&X,m6d}@#"jlll0edeea(..ƠA0h ر[ngϞ={vFLDDٳ'bccR~hh(|||Fӧ[%cHIIAqq1Z-^m۶a…XbEqqo"ue,i6d} 'Q O?>]ЫW/~}^z%@LL >cz"?3+x{{cΜ95kCXx1v؁١[nBll,$[=Y}NPG|-[SNx3"]_UV2e ֭[Wk9Q5Ј`ɓ2dOΝ;㣏>·~ӧO+j'ʑ5,NpAAApYjc^']%'' vRKDDDhD7-"FD`ƍsz1-T-ZM!FsCzꩧ7nr$uW7DDD4zhDbZ;R[N-IS9͡DDDD- 'ЈԩSz۳0c xzz3g΄;:v숟~IOZAyyy2e + JwwC0VuΟ?q NNN0`RSStN>QF {Frr^LjСC___,[L/>///o֭ fNxwp}?^˳>ȑ#={6ڵkDFF=z@bb^6l1i$>|XU_6X11֧[vw 0uTxzzcƌA^^񟺨9:˯zleee5kq#)) EEE6m\]]ѹsg;1:υ@#""hDX&((HիWZD]&):uVΕ:du1ȝjm7+WY_=Znm2tQ.""@ֹX.\UΝ;DGG˱cjd5Ɗׄ>5ݒuWU+jeɹfy.5%ϟiFIn֒2VT^`` Pu>׹20͛7cxT(++x˗/JKK!w":e舷~%%%/#G` @1\]]駟Ddd$]f2kzMvK1swKCud*6sjssA|\HDDD\pZ@III 8{֪՝SnNTS}BØ_۶mC||<ƍL݄}g~x3f<8y$ڶmo1c6l`6ctcI7#Fsj*_[`ߋ8-+j_.}n Qnrjz\@DDDD 4"j|VꗒTVV*ϵZ-Atij;}v%H%V/۷otٹs'`ĉ7x`@ll,= HOOǐ!CԖGtt4~G!??+V s/իߺ +iOFLL ; 6&h5S5u̵Ĩ ,PZ,""n|///IMMIu IDAT"8qꭅԭ[7 qqqr%.O@v- hرCDD:t dr5ooo>|(ȑ#ġhQ$55UIr努\_W^n2^zI]&tUPv*RVV&l;vȧ~zOⴄׄ>U]mj1fgg"^^^`q=7uP_ZZr\VV&E@w j@ vGffƊG=EuwBCC%,,u5XVCLi45ْ$QSa}hD$ ;}wbgg'{#G+z_8OBJ8prHSN:%Fgggqssɓ'+w*ٻwDGGKiixxxHLLժ9aqqq~ɉ'$""Be""RXX(s???;ʛoOG~""Cˁb mڴQUիWK֭ N]7g}k׊8;;%''VA}QUGj}`X11֧jm;cm6Ƥ$ {{{ :󀈺~S4SC/m`'pdȉ'jաyC^>2e=ztr5DJc]gJ"j85QhqFK4666z?jZ-6mڄ 0@Iq݋~7nhXt[fqq1tK.u^M%mڦ%xꩧ7nr$uW7zMܹstFSVLp8;;#==1118w{>dx:ҶkImC-CkgΜ?kUVׯ ?Oܺu g϶bcNiS^D8FDą)))h4>}C=fϞCիضm.\+V4HǏW-_W>zػ IZZP󖟟S ۷ǁ C Xl-77Æ #&MÇ+Wt\pSN'1f)yϘ1^^^Э[7 6LI9rgFvPPPH8;;GHLLT=z4nݺK'//SL0~xcDii)fΜ wwwt?_XXU>0~Fx4tiff޺ϟǸq''' 0F_sʣfСCx뭷KjǤ}㡮퓜l4O]1IDؽ)QC=I\<3 |rkSo.\ f͒ '''۷|r֭u\v2@+,,@l)((_|ɓ"ӦMy뭷_^DD* r-̔^z%P͕|񑐐Q\~lݺUw^k=6ooo{'/_lk. % @{1),,oooeM-^X.^(@zv}(Cl AAAFc5گk׮o>֭[EDDHlmm%))IZ {J7oh4{)ĉw ҥEb,:׫f?7N222jKcdLojxXn]klk#j%&hDD_K@;w-[(iNE9**J(_򋊊_DDСCDGG Q|'ʄQqqRٳg}_˗~_|CEj%rgdgg+i;>szu o2 666*ZY.m۶VYόjĉlذA]s+ǘk oL:UVV U.jKzjyꩧj`-jƛ1KИ$"5;@#"jZZPPW*iI_۷o_*MҺukܹ888Htt;vV9qO0Tg Cp777cuwH.++SN<)duLggg';q[֭[g2VS}`,F^o"'11Q 8PDDf̘!-R1ןU \Vݞ={$,,LU[Xu.ҭ[72-jƛ1&>ucDd=@#fhDD_K@7e[[[ ٹsmV9כ_XXh2v5گBj+DDn߾]몣{1f~XҡCh4#O?[NDHnnMO޽m۶oܸ!'NOOOo4f.Kg+WG}.bxLoj07>ucDd=y""""z())1; ))#FܹsXjz聯QQQ6m_aע?00Тtޟ={VIkWN:Op\ccc?Y{ … =zP1ן0m4ǛP#ƉhDDDDD$,, 7(ieeeߺIbccԦcȐ!%ӈcǰa,"w%FۺJ/ kpTk"""|WJZ>}l߾]o_S?+kUVV޽{ٽ{$$$FcȰ(JOOW;?U#F(YԌI5Mm{MZ>jԥQa}V"jn!X5d(Z']VV&+W8::JXXl޼Y+0V7&YPwjk>tLm3fMmjZȝ;[wrqwwW^yEﮙCˁMKKÇ<裒WNRRH||G6m <]VYƏ/999z-_\\\\_~rSNɨQYdzkzzZs1ScW]\\8;;͛7Kc5LuźaO8!(W]_y2|ͻzƤ}DL&-m5y3Qc}_;5)7n~(..V֪ƩqܹXticƍXx1?׿vZ^UUUׁSk96Z-Ҕ⡇R֎jD?񏰱Sٍa=S7Z5o 2e ;;;ދF5-eLj4!"j\]]V3gVzyy9FK.ȑ#h߾_~ׯ^xu@ZBhh|^rtMlڴ 6mL)S`РAʤqKU}BD "kiicK.TjٟEÔ)S777?^YxӧOcԨQprrB޽lŒ3驗VV '''bٲez/\S3f Gƭ[8lmlkzgUC2ϟ?q NNN0`RSS6l1i$>|X/sTMk]zyy~Cn0l0@EEyw}ppp?wzVR̜9ر#~ZToOC]LiOmc*~sMd-/1dbܹʲvXVsqo"Ddhh(|||Fӧ[;$"R^~^kJ@@={r tE>tPIHH[nIffKxsլ}||ׯ_/[nݻHll>H_Tuvv6[}xbx ѣG}={RDD͛'Fvڥmkg 5m&c,vC[ڎ2556nht}){{{ ;vw}WN:w7MM >&yqppY|!L73~7ol%MwW{N/ߚ6o,dȑ""rZEEE e£HHED$::Z-'HPPɲܺuKu]kLTVV UˡC;Sݮ/..Vb?{...@Yŋ@oT=u@n߾-"wn@lllDpV_ y7T)R/ m_xܮSvl_ȼ0Vagg'$88X.]*yyy~hDXSN@ȝ^5_rEhZo֭[PnOoN5]Q=nsMVٳGjmܹ888Htt;vq涫 Nǎ""RZZ\9V.VWWW4hr52koiKn'ڎ@ktW6ŋݔDDDL}B$D"? <PVVZR/_uֵNLر#N:|%^Kݼy< 3iFv5Դ5-[ɓ'Ƈ~uFj2ύ70a888`zw4׶jʸ۶xugriGjڵkp̜9Ӫq$''cŊCEEz#F`ɒ%С=#"/ 4b'NP0F޽`ڵ`N5~^Z]E #SRR"V=z1bE͹X;v 6lUoWCMK+t̟?waQU#r  KIh?K=ϱX)[*Hj~;X^+5 X@DQD30ۀ_0kg}fgCPVVYZVcwޭTv;#۷cѢE1bDrmEP7jCU'))  R^W"'''^~edee_ū;9:"""jpq 'rrrDӉHQQ;VڵkJm YdJzzt:>|NDMff(F\\\$55UDDLkZ1y"e˖@[Kt"۷oBRZZ*L@Y5}q[nF#d׮]J[v*RVV& aVKCCC%<<~U>5ҧOIKKdecǎHFFvKKK^$<<\ݻ~[ۊǴbjFM1wn,:Nv-oߖBٹst]?N?Z:О@3|8;;˰aҥK&eZ>p@U"8nooo}׭['-Z0;ֱcG4/2iݺj15W}SU49rlR5k&>>>2f̘JFT5 mmʔ)gT.^樽ɓU]VV&k׮HXXlٲE*zj wwwiѢW|M)))1Ϛ5k|7r5akí-_\k׮RPPP)OMDDd}Ϳ35*[&_i (%%%ؿ?L;FHDU4i 66֮q"/͍7 ǟ⯼ W;;;O?4JJJo㩧3~'|gXnݻ{$.]ˆ#мysZ aaaHLL… qڵW;wg* z",, G}͚ݟGرcxGpa 4daxױa>>& ѧOhǎ3yʀ1RUE4cfhӄ Wi1&K\DHP"99fͲwHM7|y!997n܀^ǵkװc,[ k֬wDD&1qDxxxQQQ2L>>}F+De[FFfϞ-[!C~~~Xz˗/chٲ%3 ;;?nRh޼9O>AVV,X`v ɇ sO\p+BBBlt ?G1)0͠_Ѯ];8;;'0{Cŋ֭lWs ?Ueffb޼yhժ 777 &ѣx饗* 7,XӧO3ϰhKxla|bΜ9D?Tc! IDAT3g΄/vZ,Y...8K4 >XxvY:SVVs;wÇQTTS:uÇUj&FN+t)j2uT)..K ٴi\rE%44T.]$999+6*ĉ6q9{rIٹs.](ۇ "[n[nɱcǤO>&[ۮf>3g ?!7nܐ_|QM|}}כ6m۷KEDݱKLL}t:%??_OȞ={} &$116ӧn{%77WٳR"ѣIjjM+!ׯK[6X>۳~z˓ _]$!!A(燚XDYzLD=Ј6MqmѢE@+W 6mI?XoٲEȑ#EDe@H#<"""ӧOrQe?P,&lDr Rܽ{WH͕NNN6ګvZVHii eƍJΝ3Wͱ38;w+ 8lذAȐ!C4ep*%%%@\]]Mkcp۷o$?/^,$..lYjJ9mٳg塇em|.ǰH͛72)//759LD4"zpkh;v4.rLʭի@<<*jѡC _899>5ɱ3N˗/_ \1 hWYtUj=]vonkeX?+|aqrrV+ǎݘsQMkmDd_9Q-pLhjxyyg,??PZZL/"(--ҧ-:tɱi?c7oij> &`pwwG}^z!::zj^Cqq16l9r$}jPcg:Zn ?tjUtUUy+m3i-VcV%ñ~z駟ŋ+t.dN2k9LD ЈjaܹsJaʎ;Z]vUJ4;7zh޽{m… c#22#F~?O_~ֶ3^SC7ٳyfةQ\\ ?r0n8]pJ5 +W*mSYAvN?_QFUn\Xk&hDDDDD0_+iODGG[wcV̜9Ǐa%K#SSSlW^y=V\k׮͓oXz=`ƍ&1Thpi̘1?36oތޮ_L>BYYrrrfhZO6P{ G'n߾l3 a%**JI3gtUV)O+**›o={bƌJ;w+>iֿC*A)޽n菊}dX'kj9]7|cƌ'*mt.kq ;WZ05`uQ":>Zhh{19sxyyJ>")΁#:N|||$%%Edر(׮]SmVȒ%KPEåؤ~?333EIh4"""e]ՊlݺU)e˖@[U-Kt"۷oBRZZ*L@Y5}@+[nF#H׮]%11Q$!!A"""Lji{hh[wwwsTG$%%EIzj]nlܸQ\"+VP 09n/ʯ*]v)((0ܹsңG֭޽[n޼)Œ =z^zwޕ>Hc?8;;Nݻw۷Pv)ݻwǏ+yr edd(iG19iii""k.h4+IIIrueUM_Y:zRzzܻwϤn޼)4ws155Up>=zb֮?k05|9FDRC@8pɇKNkK>")/2j(qss0ajAAA̟?_Q:t *q裏O8`,NNN,&}]j2`9{ɶl;wH@@DGG+qǷyfܓ'OJDDw}쓚*Çggg6l\tɤLKռ[NZhavͰHۻj% @ZL>]JKKKf̘~j>N'nnne2fTy߿J k[s$--MF)-[f͚3ʨI``JTT\xR5}%R9m"Y???4K碚6Wf)V>a"j,kQh4} 數q2[|DD ŤIv~h`U;2O#..AAA QKJJ~L2%%%a~mvM6Z'=,s4"";sww|DD`1H͚5 O>hZtcƌ8 ψ>plL8@TT22p Kiaaa ̞=-[T.\Hxxx!!!HIIQ08}4FWWW&gǐ!C ???^$>\xݺuСC-]yy9׿]vpvvO}8w49jggg w}^n._l2_VZ%nݪ8 UtMD`;5J~1 \RȴiDVs^~>S 4oܤ=زe#Gڜ/&&F(TEEE@yqRιsTI e"\ $Z*>??_y]^^۰a!C(iNNN6EDhDDDԘXzW8IضmJZdd$_J9::\G /ؿ?"""O= ))|C(jJ:eIBYYrrrf嫛ʬva0**JIh48}4f̘7oU"Ql2t:\q^{5W^QuuVxmz~]Ķm۔#ڶm xWqu9r/k)ͷl2̙3۷/5kcʕHKKSZuЧOJs?2k /^ׯXp!pB<'NDRRܹj+QCp{`ddd`֬Yw(M-dFFfΜUCyb!x_E j*/"F777 &(T߿_DӥTdƌrQ8po7oV+ 'OJDDw}'""2|GGGСrrILLG}T_~r[nhѢcǎVˬ7gN777WT>|8;;˰aҥKJDpV_xx{oFy}JJ@@@ArNoߞǫ<b!^kw"FE 66kh`u@#..AAA&Oq`2e JJJ%Ó{|"j&Ms$oj[yy91x`Y+Zݻwǘ1c%7!@DT7:#""p9|w%%%UVYT sR<}chScњ ЈjIhh(|}} FYf;Z7`޼yHNNƍ7q5ر˖-Ú5k%S9"JٳѲeKbΜ9D?Tc3g΄/vZ,Y...7!C ???^R{fΜ X~}mݜ7n[YYΝ OOOtFQQN wwwtIY(8ӧOcԨQpuuE߾}hs>>>x"u놡CP??˗1ydlnnnxg]}U_[]p+BBB>ťK0tP`8rVM\S.]ZXQvv6&Nxxx ** gΜڲļyЪU+!::nnnٳ'*vX_m}UE[Q}ANN&O iVn뱫I}[rvlm{߫l>CJDT`9i,yYwߵw82w\ GGGquu˪U֭[i"=MmJ}KoKnn ٳg<EEEңGT)))SSȩSDԩSX.]*dӦM&.//mۊ)ۮ_.AAAR^^nl|㶭_^d@_}=oeN^"##%==Ҿ}{y駥@Kt:26:Ny|rϗ,gk׏m:oCSC YYY'/mݖohڷo\j-mPS^MjU=U5JnlDD04wVr"۷EDLXŋ)ie_q|`2#[DowyGٶvZY|ϸlkͰ͛72ep'Uյe #GTU7rΝ;'>}P%((Ȥ.KVS>qUקprr$uzz9i).n:4iE*Zh,%mʕ@MfSW-//W7l dȐ!JGMW"{+"d۶mJ/bs,m/kkjj-mPS^Mі !uq-@#Ј6f_æq^V] ϷXEDڴihdO]899 r5%@6U6ח5ڵo ׭㦶 597m97ܫ^YS@K\kC~~>rVʫ_BZZv֭[W^h PVVV/9j7ogń `S߇;># (,,Kq;@U.\jcS?WՏ\6~[Ȗ}j\}6UVӗĨگVUl֎6TÖ{U].:S8FDDDD5oɟ-1,cN5a`ݮ]zʤjX1Xp!v؁xDFFָ U1b~7DϞ=_"&&jZv-_~V0 |;wNIk֎;mlNqq1 2ϯos~۫O]U֦YM_k6η7m*u'@ᩇ۷o+ۊq]^`4^ǽ{* ݻF?aU㴴4 v예ddd(iGQ&o iii""k.h4+IIIrueBh?/")...JFIMM^/G[eO?1gӐRJzFF=zbڶm+dɒ%RXX(dR\\SRRWP x|Lj#[nQu|mվ}{ {[Fk.9/H׮]%11Q$!!A"""DD̞JKKtLw-2beѣGV>HioNNt:񑔔)**cJ``Ojd þ/ʯ*]vK-ϸ +Z!ijj8::$$$HII2i=W&k;s}6Fk׾-^j6)&hKWKg "jT ߛ7n#!Yvv6~G|}}Ѿ}{)_y ˶mۆ;jh4cu* IDATU6c~-^x\v &Mի燘 Vs\߲e ,Y< 6 k֬A@@Ik#33=zի1x`nݺ}pqq2fCj7Ү]7x[n`ٲeptt4ɯ~ooo'V f͚!))#q_bb"͛~ {Ƃ s_ɓ'ѣG|爈@LL ?Y'sǮQk'7[`ܣm'TTb}hD(?!Qq]dggŋCѮ];UV ǜ9sF:V 8'=5V7n@.]pQR]PҗMov!"ۺuC &(''[lMpA`ɘ;L""""ЈѠA#77 N9s@aܸq׿;w;L""""24"""";pttѣuV>@~~>Ǝ6m`̙HJJMTXXFYfޡԫ ̜9^]=ؔ=RchScњ؆_5,OOOL6 ӦMŋ͛7>@`` bbb0qDޡR=i>h4&x ,Yl{3Iߨ&9g1cp…z={){{ζw5imFoM""")++ /pE&M„ `FX;zQ^^d <бcG9s 'N#88lp xzzAv766$bAhN"""o߾xoСC4hV\,>n:\va;w}]|IIIhժzu6xuVvCjBk mlHk11h̓ІQ׬Y3|EEE:u*ѩS'>|Xiӧ1j(o߾HLL~\xݺuСCK˘j{BEݧ999>Ј]V $FZn-f͒dѲeݻ>\ܹs$Hy}m)++ "*xb qqqJqYjʇC9 ҭ[7w^<;v4 *r Tf.Z;uꔸc=@#"""ztK.ʼn'g}9z쉇~V¥KffsyΟ?q RCDPZZZ)NCtt4~W:tiiiڵ+Zn]k{///@YYYԟjt=j~*:Ҷ .xbbO JJJ0f8;;c˖-pppmJM5f˱ ׎sVmW-{qBs璵6U>/mQ[UY;njP[ܼy>,&L lXn].dc4"""X~;… 8py[ s%Fy/$PS`2Q%>c_)& ۵kW/>L[T-~*Zv-_~& ϝ;5kv^ǎ+`?ԩSq)lڴ m۶5X[Scg}\WQu{3*T6K[bvV㦶 uy bǎGddd˫)5͚5~z`ǎt;w./+y֐a۷mŸ{Z0Ͻ^ǽ{* ݻF?iiij-۷o+ƍW*F 믕ӧOUfX;_ ;ؾ};-Z#FYv_5Ou0`Yc[ncsէaaaJI3~"L}NmĨQKGqS5便qF+c˭YIDDDD"e ˞={L(j`a.su&dƍrYb2J@@$''+;&""Jڑ#G$==]y&""vF#$ׯ_W&o6Z""⢤k4qqqTr \Tɳ?S|8 y-gddѣG-m۶@,Y".:N.JX?%%EIzɱ p7++ˤlV+>>>uVUiiif #FPN'>>>"EEE2vX T0g?/t]ٿROmQDdѢj壏>Raߗ^zI _]J@@(g| Z!ijj8::$$$HII2i=W&k;s}6Fk׎-{7mPS^M۷w^ٺuh4 vt}ܟ0ޓO<{&hj2}t)--///1cɇはiI``JTT\xRk$&&ʣ>*NNNү_?9p@JPPܺub̶oKZAA̟?_QYjj6gj>|XI%>>^٦-jW_5[/"F777 &(+ 㩦OZnmj?,۷///t5~2gN777Wkįԧ""~Wo߾)?Y}NvǮQk{7[P6o,ZV  'O Nս:_Kg """"R={qqqزe :t@LL &N={;zh{badIO7n@.]pQg]PҗMot9UҩS'k8y$;g}7nD^Я_?۸xl+CDUk5し@B[)MS4"""";#8p V\@`5}}~P{ؗTQhZ믿Fnn.VZlDFFM6>}::y?cѢEHKKѾ}{,X&@#""": "33'NGرG= gΜwDDDDVq\=̙3HIIСC ((!!!xk0Fb͚5|2كݻcٲeh׮z)*B#\V֭[صkbcck.Q0i$5 -ZK\0n8ODDDg۶mELLLm@#"""_~%pAhZDEE!&&C C2~zoΜ94""""jrssuVNs='"$$DyB.q3g ..[lSбcGL8111ѣ#""Ј@ll, dggo߾4i{9;<"""zp-^Ç#..۷o'bwDDD=ܹ{".. (//ǰaѣGC;D"""j8FDDDD|WǾ}ѣG#&&ÇC$""FhDDDD@z*mۆ8$%%ƍĉcYf8QqElٲqqq8~8ڵk{&MB~5P@#"""&ĉ`oݻ#&&&L@Ν5 @#"""&MD-[/@^^BBB0aL8:!qݻoqqqꫯpM^z G}ݻ|s9Q4""""wk|'ؽ{7|||0yd֭ID|WpuuŔ)Sg9sRf͚'͛1UhDDDDDu,//9qر*9::qqq>|x=FHDDD+DDDDDuuX`?* S^^ׯcȑX`ܹSQQU8FDDDDTOA[̣!"Xz5}Q>}#""+DDDDDմb ,^a pBq"""""Re֭V󤤤`h֬"Q:dĈ2e'b \zszqYW\\hj jpuuVZh777xzzEpuuZh-ZCK\gϞE\\\Q=6mMf0@#""""""""hDDDDDDDDDpY4""""""""" 8FDDDDdG5k 㒑3g>P>,, c^#MGc8֍!FkblwKs{@DDDDԔ=*3f .\oz͚{N#** /^|5acњ {8q*8~x~ uZG}KIIQ~RjQ!Fkb>ljC|DDDDD0www{@fqju^GCy4X7y`@#""""G9998 WWWa&;R^^h׮O2kҥK:t(\\\0~x9rDձsРcjm-}W-kma}q 3 s΅':wÇSN;:udT{A{Gm7!""""jy뭷wުH``HVVɋ/(𧹿ߖ\ҳgOJhh\"*.]`u[t˗K~~dee={g΃*?MV !@13#  SsѫaQqEV]\PgFGtTD-$ Qd B6H$y~cwz;tTH=}s:r3-[V!CHݻwO>!8ܰaسgOVWW$9bԛ?Z IDATK?sssLOlQ/IXTTĆSYY~[naee%7ǫ(Ʋ$PuҼZ… Y]]͢"3((EEE^۳g8c '4晻yٳ X[[kw-Wc`"ɱcrʕlhhm8tP\|iL=m\=kz{03n޴Ly-^\x1099< ˙CvǗsAs>٭iMDDDDc"~F޽{>8O>Mlll$y̙3 [n5x &''.0;{dرcIFە1|pCUSS>eˍx###Z$ap t̎Ͷ7|yęG}XRRb ۮ,69s!ͬjY]|o:ߴio^{yJXX$yQ0ݕ10{\d`` 7md.**8]1WHsCzMߵ'FOZo=/7o`oNN F"IΝ;/2]wdl2}Y<^3 @KRcccݶ.vg?n7_קO={߿?&I=Wc`"/AAA9s&w3]1WHsCzMߵ'FOZo=/7m0S7ޜ Z&+-to tkWi+++]T~ܕg!((c{N<)SW^555o߾X,M`}o|q:W\?fpp0>rѢEI&y,Wc*jڵݻo[8q1m˘;;gչifl|9_y{.0[7ڻt @]]] ظqct㎵III{GzjdggcҤI?$xb['Oƴi@O?4 %%tfY-Z\s ?zK7z8o?mpey/22n^nvm{g=Ν˗{,WcꦛnO?_)))裏0mڴN۹b|iL2fIfcty5f =_r.n&""""IF ㏍F:455[ZZ5͌ ' -- |ZWk'N0~~XҥKbwfƌ^z &Lu577;lU;ǏoW'N|Fھ}YYYF?_ӧmXmKk׮L2|7p`رc4{1̜9| QVVW_}aaawpɘìYsN,__6v\1s>܏V=1z:zy츙mmc,^wv{S5_)((`@@Ó'O7in޼xm6dqqedzz:nj㶾1&&+W$Iuyú}Ǫ*~4h7?n~_|W\IB\f] ?O#ꫯ&~m*Ӗ<:Bb羂Ǜnɸz'NȰ0[FeeeeLL YSS)S0))+}&.]ǎ… ]+}}߾} gUUdz(l۷y`w;СCYXXL_ʚoРAccc#srralNst?f;g}c6FOZo=/7m0S^AA9k֭n I?؞o ;佉=DDDDDL[߰a ƀ6۷ogdd$?}]p6j(I2--LKKcvvl]ް{166m#Fp`RR7nhoҥ S v2ö|:x ٯ_?FEEűw^N0ԩS'Z_ ̙3Y__Ϩ(Κ5f7b>Ȅ|'Dj6Ic`` ίʡ[;W|M"9 8~xoÇiχVv}o\ of͛6x*llޞ?_~o"ۿf.\+V_s_!|}jkk1p@;vKX, +V@rr2Fi+W^8t\N|I_qC h"""""""""nhMDDDDDDDD -4鶊1gDGGwhg:DDpH5yd]0"=zwhhh̙3pQl߾}qwɒ%O6\H1rHID|ٺMDDDD⮻BDD"""~n߾}0aBBB0l0ۊ1w\ˮb;!!!/lȑ#>}:zPvm(--zhhh0/JJJ;]<iӦ9m1i$+#GD~~7nqwb˖-vxn>\gϞ.CPP~Ocbbp! <ƍ3;w_۷c޼yKP^^,"%%999vX[n}xxᇱo>3k]֫E9V__߿?[<0{l!::-llp7`?]m{ 22W\qrssQSS3f <<_~Õwb4E?T+++ٯ_?r-͛X.\j1>>AAA,**"I&$$ð0Θ1uuu|' ˖-#I;v LOOÇYVVƸ89m+==k.mm]Njj*pO4;+WdCCmơCiQ6ٳg{ghh(˖-U8d.//ϡ֭K5^/X,))a||<?7 yyy.۴{nСCtVs_ѣGMLIIqcUSS+,((ɓ'3W9mC !.DYx1˹xb`rr2y3''a&VOsXD:٭hi#oG %%%F /@4g|o&IVWW;6m :555k$9sL֭[}x &'';44`>|HD7rӦM뢢"=m7#,,X__O}$H#|>+V8-l_m?#{M???YiHsѶ=gΜ!I:uHkll$I={֮9,"m4. Njccc4gǏ'FDD$[ZZHٳ'IW9.ܴ@=qPn:=a_Π Μ9;wtv3OI@Ԫ=cg檎#G؍/¥uVxx:ͤnr 4XQQnOetsssȰ0n۶a-gsL/氈]{t4NrAyRRQQQ`qm{={лwoS#m߾},]0eynٳc@aa!~_2227YPP4u?Cݻ7^x8qi| tRZX,طof͚;wbMo7̙37ߠeeexW2kVfκxd6"m_Z]233_A[555x琒YfgΜ1~o}5\o۴izuSS?Z'O fӜvɓk.m梳ض)V_aBE166111gMM L¤$8q׷o_YUUŢ"r񬫫3=o`#b088$ɒaaaʕ+2zEܰaS-ŁrժUbKK 70!!$9:㩡#~\r%- 7{A1//aFF][mOOO1cxx{T :7Ҏ?ަͪ*~'2dwaݼyQ~bFږ-[ƺ$fZ,qӦM6`;_9b_TTf;u{F]Kz IDATuViv{:?~j(?g|M"!֟h͌뙘Ȱ0Μ9YZxPfff-٪K/k!!! eZZ׿:<`YZϑB|ի{N>.\4fWibnHjTDDDDDL[p!VXa|]Y,}Nkii+#G'O?'OX7>uU=>}tj"=[@9Y(͙3o ,, C ɓ;%:ٽ:D&""""rIOOG\\6o ł9stuH> ͛Q[[8qWO?W_}Sⰽ}W]lۺ}.DDm&""""rINNFuu5.vO_@޽w駟#::SHMM5~>|xX S_ED#@DDDDD{wux+xW4k.vȅCW47&""""""""DDDDDDDDDyf3fLWmcΜ9$M1.y}>|ѓ؆ >/C{fϞ Xxö~m؈x+̘1ˍl߷o&L 6 yyy^Ca7n9rO^z!44vU*3K/cÇ1n8;Ė-[Y[뮻dff~0Oz3ؾ};͛K.Bhh(RRR)~j㳵S2L>111ӧ6voǮ=1z:<`82O ĤI9z EDDDDMyʛG|ݺuvi _|Gevv60%%!UMM Jdz'O>hL$gqƌO>I\lϞ=˾}200ƶj&''ٳe{*߶m/fyy9/^LLNN3vÇqqqLKK3=~i-sݺuljj"I>裴X,MرcrJ644p۶m:t9kUYY~[naee%7ǫ(Ʋm\ccc ,`EEKJJOF?+3{S_[ЧzȒ{M{ӗL3oyy3Jܽ{7?|͛lg&""""F1̙3vi555ӧO$ ~~~$-P.'XH-l$9m40>PY˹kJ,))1^xw=f5;ͪ0={dرc4O}e&~okZW)I>C?HۻwmrݛlOg==̶Ly9>X0'r_HqgFmZZZڔgРA y*$cnUƇ&1bg+Li ,U/my>_ikϞ= ~+j4_~ ̙3sNm0`݇mk6F]ˑ#G?fuEdrr2ĉF:Omj1/7Ǚ'ffl37֭ѣݾouĹЌ.h"""""݄{ 9s@tttc׃$Q__766YYY7ߠ 7AQQQNP[[t5cN'Ob |???c1z W]uPUUM'&%%*++ٞ}myӏ:{S_kV]ѧڞl65ӗhn|sq3ۆM3N:oSN?luP4󜿿? v7v~/vޗ]vYoɤf.3f`Ϟ=XlkStM駟#%%}M.=}0`8۳-oљ:,2=;߮Ӡ OmjK71z:|1Z3;nfy#<իW#;;&MjwyݑDDDDD:uzUӧmuuuhjj2^Zy_|En;v _iG~_6w;kmW֮] 2e͖JFF`Ɠ 13^z%Z >(n&2@VV\n'N[l2334O}mo=>}:zhl^fc͞Ʈ=192{0;nf`.] պ܎8v )"""""$ K.cǸpB/ܼyz۶m$b#m˖- $fZ,qӦM6nm'Ir 6- YPPnٲXTTfܰw!I|8yݕ_PP`$n6}%Ο?UUU,**bll,ǏϺ:՟o?~n9f[RRbWvXXcbbrJ45T_~I???3ƸSSSׯ_o w}B/ѠAF0##$Dz22&&)Sdw'2,,ofv_3s}>VUUAJ#2l$YOw>-((`@@Ó'O7Sm23?͌1ffl̔מsp~_|W\IB\fy#΅f!"""""]?ׯ_Dq̙gTTg͚evu<$b &%%1$$Ȅ|''2Stt>Fbzz1eZZlcٶx]^zO1p 7Ç޽0aCCCSOQٯ_?FEE٥\6{X233p뮯oUwSܰa ƀ6۷ogdd$?:nv\g<`fܼis^|98b޽LJJƍM\I{,_… b kEݍF_Z 8ǎ8:XKvoblMDDDD^6"_!8>vX\ ܶmj7]yfm&&g*++ٯ_?r-͛X47X XQQ?sSlז;ޤ$&&&{n1sA[swǏq fsP9}7hMDDDDcʙ3gjjjקO&I666H[j]?N\bf[Irڴi`|@syK/-Z lTmΜ9CZ熿=006m2^ovWv{əG}XRRb ۮ,Os߬ c߳gK,!;Ht<ߛr<}J=?4um/s7?f͛6)A|uHqg.mZZZڔgРA y*$cnUvW 1?ܕo޴vo*涼i/uq/rq̙ܹs~ޔm]̀>@Xuߏ9|37xn+$ 'N0Ҝ-yjS[qg}ٞ= a1;nfОu:wwM@&;YCEE< zo4h.6 DEE;r@mmf̏\9unvL:?^{ x뭷pUW!++ UUUm*lbr`4ؤ$@ee21߭|37l}j[y67ӗh\츙mC{ޜ3:!4y.p v7{v~/vҗ]vYo@ɤf~w^<V^lL4aM7݄~ :RRRGaڴim.19c]ؿ֣ǹ 0]// ֞Z[{WiPP_劧6fқ= :87;nfy/M h"""""ĺeƶ:455[ZZKK 򤥥v7ps c;v׿2qW㣏>?믿m w6[o']0eS-ו 'cf|ўZt]̭Y,۷fΝ;|r|.uWv{ə'>S#m߾},#o'N[l2334OǓl\=}:zhl^fe͞Ʈ=1z:xcv̶Lyuj]ϝm>EDDDDSƓl?::nQF1==2--LKKcvvl[jO-_aaa1bw͌ &%%qƍ>?~}W_9W\\c"$$x嗍mƸq;[lq#G0}t یcܹC0x`7Hի`7o.#++ HIIANNQ׭ފ:PUii).DDD ""mݯ?"##ѿ|Fi}ufYY,,dggۥeM8˶\zbҤI@HHFj$g_ouUF6mצMx'kKf礕֞:\GџyyyFd9,">DiWVV2)),))ayy9^{aXXg̘:>e˖$ǎ˕+W۶mСC?vÇqqqLKK#Iu.[V!C`Kllz`II Qg6.~[naee%7ǫ(Ʋa_|Gevv60%%(kԨQLOOc ɒ`rrXݍ4h7lٓ$#GK?sssq<pݺuljj"I>裴X,FwO>8p@UmnW:KN4EEElhhhSI3=u::?IgsXDyݚ.6zi{u;m40>Zd`` 7md/**̙[io`T[[kԹ~#Ouu],g,YB;vֺ "-`II /nӧI@???lZի­[oXݍ#)S/_ni, x 7xO[}7҆n,:555M2.:|M3g6vo椙֞:̓Ows{Z@"1LFOϞ=I_~98sLܹӡ2m9:Y|G!FDDi9wF#mϞ=Xuuq_@@000Æ 6Vwc*FYrrrH5jIrܹ|}Msi:ԤUVȑ#wEBꈔO)?l[\\]ZZZlll\mܸ-11=8%&&7Zib>ϭA'''[zz544Yww{mxxؽ/y$qdO?~اO,77ײ$kkk3o߾YFF[wwXYYK^zeff}}}/_뵢}=99Cooo=Bi t>$s۶m3IH3xuegg${5448&=zs*cq3NJ}{fɷ)bݟf^=%2Y~~Y~~[JJ9s&譙sN{{M~ۿ%$$ؾ}lhh(+,,x+,,RSSC<ܹcd688Tߍ7,99va?Y[GKJJ,))֬Ycǎ +R ڵ˼^o~{"M.L1ZRR=w5KLLU\~}ضbsÇ,''gٖ1v }zr,z-Hy B'i;0kW^ս{T+8Ki1rr98x 0; use constant WARN => 1; use constant INFO => 2; use constant DEBUG => 3; use constant RID => 31974; ### ### ### conf ### ### ### my $BASE_ADDRESS = "http://localhost:5280/http-bind/"; my $JABBER_SERVER = "localhost"; my $RID = RID; my $WAIT = 60; my $USER = "tester"; my $UPW = "mysecret"; my $DEBUG = INFO; ### ### ### END conf ### ### ### # create an agent we can use for our requests use LWP::UserAgent; my $ua = new LWP::UserAgent(); # create a tree parser to parse response content use XML::Parser; my $p = new XML::Parser(Style => 'Tree'); ### ### ### subs ### ### ### sub doSend() { my $content = shift; # create a request my $req = new HTTP::Request(POST => $BASE_ADDRESS); $req->content_type('text/xml; charset=utf-8'); $req->content($content); debug(DEBUG,"<< Request\n".$req->as_string."<< END Request"); # send request my $res = $ua->request($req); debug(DEBUG,">> Response\n" . $res->as_string .">> END Response"); return $res; } # getChildEls # used to strip enclosing body element # PARAMS: @tree - tree style array from XML::Parser # RETURN: @children - child elements of top level element sub getChildEls { my $t = $_[0]; shift @{$t->[1]}; return @{$t->[1]}; } sub debug { my $lvl = shift; my $msg = shift; return if ($DEBUG < $lvl); my $prefix = "["; $prefix .= "ERROR" if ($lvl == ERR); $prefix .= "WARNING" if ($lvl == WARN); $prefix .= "INFO" if ($lvl == INFO); $prefix .= "DEBUG" if ($lvl == DEBUG); $prefix .= "] "; $msg =~ s/\n/\n$prefix/g; print STDERR $prefix . $msg . "\n"; } ### ### ### main ### ### ### $| = 1; # set streaming output # no body print "Sending some 'foo': "; my $res = &doSend("foo"); if ($res->code == 400) { print "OK.\n"; } else { print "Failed!\n"; print $res->as_string, "\n"; } # no body print "Sending some '': "; $res = &doSend(""); if ($res->code == 400) { print "OK.\n"; } else { print "Failed!\n"; print $res->as_string, "\n"; } # empty body print "Sending empty body: "; $res = &doSend(""); if ($res->code == 400) { print "OK.\n"; } else { print "Failed!\n"; print $res->as_string, "\n"; } # fake a sid print "Sending wrong sid: "; $res = &doSend(""); if ($res->code == 404) { print "OK.\n"; } else { print "Failed!\n"; print $res->as_string, "\n"; } # forget to send 'to' print "Missing 'to' attribute at session creation request: "; $res = &doSend(""); if ($res->is_success && $res->content =~ /content =~/as_string, "\n"; } # sending empty 'to' attribute print "Empty 'to' attribute at session creation request: "; $res = &doSend(""); if ($res->is_success && $res->content =~ /content =~/as_string, "\n"; } # forget to send a rid print "Missing 'rid' attribute at session creation request: "; $res = &doSend(""); if ($res->code == 404) { print "OK.\n"; } else { print "Failed!\n"; print $res->as_string, "\n"; } # trying to connect to non-existent domain print "Connecting to non-existent domain: "; $res = &doSend(""); if ($res->is_success && $res->content =~ /content =~/as_string, "\n"; } # trying to connect to non-existent jabber server print "Connecting to non-existent jabber server: "; $res = &doSend(""); if ($res->is_success && $res->content =~ /content =~/content =~/as_string, "\n"; } # connection to foreign server #print "Connecting to foreign jabber server: "; #$res = &doSend(""); #if ($res->is_success && $res->content =~ /content =~/as_string, "\n"; #} my %sess; sub getSess { $sess{rid} = RID; # a rid to start $res = &doSend(""); if ($res->is_success) { my $t = $p->parse($res->content); %sess = %{$t->[1]->[0]}; $sess{rid} = RID; # a rid to start if (defined($sess{sid}) && $sess{sid} ne "" && defined($sess{wait}) && $sess{wait} ne '' && $sess{wait} <= $WAIT) { debug(INFO,"sid: $sess{sid}"); debug(INFO, "authid: $sess{authid}") if (defined($sess{authid})); debug(INFO, "wait: $sess{wait}"); debug(INFO, "inactivity: $sess{inactivity}") if (defined($sess{inactivity})); debug(INFO, "polling: $sess{polling}") if (defined($sess{polling})); debug(INFO, "requests: $sess{requests}") if (defined($sess{requests})); debug(INFO, "accept: $sess{accept}") if (defined($sess{accept})); debug(INFO, "charsets: $sess{charsets}") if (defined($sess{charsets})); debug (WARN, "authid missing") unless (defined($sess{authid}) && $sess{authid} ne ''); debug (WARN, "server indicates polling mode") if (defined($sess{requests}) && $sess{requests} == 1); return 1; } } debug(ERR, "sid missing") unless (defined($sess{sid}) && $sess{sid} ne ""); debug(ERR, "wait missing") unless (defined($sess{wait}) && $sess{wait} ne ''); debug(ERR, "wait bigger then requested") unless (defined($sess{wait}) && $sess{wait} ne '' && $sess{wait} <= $WAIT); debug(DEBUG, $res->as_string); return 0; } # try to get a real sid print "Create a new session: "; if (&getSess()) { print "OK.\n"; } else { debug(ERR, "Aborting."); exit(1); } # checking wait attribute print "Creating another session with smaller 'wait' then before: "; $WAIT = $sess{wait} - 1; if (&getSess()) { print "OK.\n"; } else { print "FAILED!\n"; debug(ERR, "Aborting."); exit(1); } sub doAuth { # query auth $sess{rid}++; $res = &doSend("$USER"); my @els = (&getChildEls($p->parse($res->content))); unless ($els[0] eq 'iq' && $els[1]->[0]->{'type'} eq 'result') { debug(ERR, $res->content); return 0; } # send auth $sess{rid}++; $res = &doSend("$USERtest$UPW"); @els = (&getChildEls($p->parse($res->content))); unless ($els[0] eq 'iq' && $els[1]->[0]->{'type'} eq 'result') { debug(ERR, $res->content); return 0; } return 1; } print "Authenticating: "; if (&doAuth()) { print "OK.\n"; } else { print "FAILED!\n"; debug(ERR, "Aborting."); exit(1); } sub doPoll { $sess{rid}++; return &doSend(""); } print "Polling with wrong 'rid': "; $sess{rid}--; $res = &doPoll(); if ($res->code != 404) { print "FAILED!\n"; debug(ERR, "Aborting."); # exit(1); } print "OK.\n"; print "Checking if session terminated: "; $res = &doPoll(); if ($res->code != 404) { print "FAILED!\n"; debug(ERR, "Aborting."); # exit(1); } print "OK.\n"; print "Create a new session: "; if (&getSess()) { print "OK.\n"; } else { debug(ERR, "Aborting."); exit(1); } print "Authenticating: "; if (&doAuth()) { print "OK.\n"; } else { print "FAILED!\n"; debug(ERR, "Aborting."); # exit(1); } print "Polling too frequently: "; $res = &doPoll(); if ($res->code != 200) { print "First poll failed unexpectedly!\n"; debug(ERR, "Aborting."); #exit(1); } $res = &doPoll(); if ($res->code != 403) { print "FAILED!\n"; debug(ERR, "Aborting."); #exit(1); } print "OK.\n"; print "Checking if session terminated: "; $res = &doPoll(); if ($res->code != 404) { print "FAILED!\n"; debug(ERR, "Aborting."); #exit(1); } print "OK.\n"; print "Create a new session: "; if (&getSess()) { print "OK.\n"; } else { debug(ERR, "Aborting."); exit(1); } print "Authenticating: "; if (&doAuth()) { print "OK.\n"; } else { print "FAILED!\n"; debug(ERR, "Aborting."); exit(1); } print "Test if proper polling is allowed: "; $res = &doPoll(); if ($res->code != 200) { print "FAILED!\n"; debug(ERR, "Aborting."); exit(1); } sleep $sess{polling}; $res = &doPoll(); if ($res->code != 200) { print "FAILED!\n"; debug(ERR, "Aborting."); exit(1); } print "OK.\n"; print "Waiting for session to timeout: "; my $STEP=10; for (my $i=0; $i<$sess{inactivity}; $i+=$STEP) { print "."; sleep $STEP; } sleep 1; # take another nap $res = &doPoll(); if ($res->code != 404) { print "FAILED!\n"; debug(ERR, "Aborting."); exit(1); } print "OK.\n"; print "Create a new session: "; if (&getSess()) { print "OK.\n"; } else { debug(ERR, "Aborting."); exit(1); } print "Authenticating: "; if (&doAuth()) { print "OK.\n"; } else { print "FAILED!\n"; debug(ERR, "Aborting."); exit(1); } # [TODO] # Check for # * KEY Sequence Algorithm Compliance # * Too Many Simultaneous Connections (probably hard to achieve for polling mode) # * request custom content-type/-encoding # get roster print "getting roster\n"; $sess{rid}++; $res = &doSend(""); debug(INFO, $res->content); # send presence print "sending presence\n"; $sess{rid}++; $res = &doSend(""); debug(INFO, $res->content); # sending bullshit print "sending bullshit\n"; $sess{rid}++; $res = &doSend("sending bullshit"); debug(INFO, $res->content); # send presence print "sending xa presence\n"; $sess{rid}++; $res = &doSend("xa"); debug(INFO, $res->content); # disconnect sleep 3; print "logout\n"; $sess{rid}++; $res = &doSend(""); debug(INFO, $res->content); print "Checking if session terminated: "; $res = &doPoll(); if ($res->code != 404) { print "FAILED!\n"; debug(ERR, "Aborting."); exit(1); } print "OK.\n"; ejabberd-2.1.11/tools/captcha.sh0000775000000000000000000000413512240230175013323 0ustar #!/bin/sh INPUT=$1 if test -n ${BASH_VERSION:-''} ; then get_random () { R=$RANDOM } else for n in `od -A n -t u2 -N 48 /dev/urandom`; do RL="$RL$n "; done get_random () { R=${RL%% *} RL=${RL#* } } fi get_random WAVE1_AMPLITUDE=$((2 + $R % 5)) get_random WAVE1_LENGTH=$((50 + $R % 25)) get_random WAVE2_AMPLITUDE=$((2 + $R % 5)) get_random WAVE2_LENGTH=$((50 + $R % 25)) get_random WAVE3_AMPLITUDE=$((2 + $R % 5)) get_random WAVE3_LENGTH=$((50 + $R % 25)) get_random W1_LINE_START_Y=$((10 + $R % 40)) get_random W1_LINE_STOP_Y=$((10 + $R % 40)) get_random W2_LINE_START_Y=$((10 + $R % 40)) get_random W2_LINE_STOP_Y=$((10 + $R % 40)) get_random W3_LINE_START_Y=$((10 + $R % 40)) get_random W3_LINE_STOP_Y=$((10 + $R % 40)) get_random B1_LINE_START_Y=$(($R % 40)) get_random B1_LINE_STOP_Y=$(($R % 40)) get_random B2_LINE_START_Y=$(($R % 40)) get_random B2_LINE_STOP_Y=$(($R % 40)) #B3_LINE_START_Y=$(($R % 40)) #B3_LINE_STOP_Y=$(($R % 40)) get_random B1_LINE_START_X=$(($R % 20)) get_random B1_LINE_STOP_X=$((100 + $R % 40)) get_random B2_LINE_START_X=$(($R % 20)) get_random B2_LINE_STOP_X=$((100 + $R % 40)) #B3_LINE_START_X=$(($R % 20)) #B3_LINE_STOP_X=$((100 + $R % 40)) get_random ROLL_X=$(($R % 40)) convert -size 180x60 xc:none -pointsize 40 \ \( -clone 0 -fill white \ -stroke black -strokewidth 4 -annotate +0+40 "$INPUT" \ -stroke white -strokewidth 2 -annotate +0+40 "$INPUT" \ -roll +$ROLL_X+0 \ -wave "$WAVE1_AMPLITUDE"x"$WAVE1_LENGTH" \ -roll -$ROLL_X+0 \) \ \( -clone 0 -stroke black \ -strokewidth 1 -draw \ "line $B1_LINE_START_X,$B1_LINE_START_Y $B1_LINE_STOP_X,$B1_LINE_STOP_Y" \ -strokewidth 1 -draw \ "line $B2_LINE_START_X,$B2_LINE_START_Y $B2_LINE_STOP_X,$B2_LINE_STOP_Y" \ -wave "$WAVE2_AMPLITUDE"x"$WAVE2_LENGTH" \) \ \( -clone 0 -stroke white \ -strokewidth 2 -draw "line 0,$W1_LINE_START_Y 140,$W1_LINE_STOP_Y" \ -strokewidth 2 -draw "line 0,$W2_LINE_START_Y 140,$W2_LINE_STOP_Y" \ -strokewidth 2 -draw "line 0,$W3_LINE_START_Y 140,$W3_LINE_STOP_Y" \ -wave "$WAVE3_AMPLITUDE"x"$WAVE3_LENGTH" \) \ -flatten -crop 140x60 +repage -quality 90 -depth 8 png:- ejabberd-2.1.11/examples/0000775000000000000000000000000012240452476012046 5ustar ejabberd-2.1.11/examples/extauth/0000775000000000000000000000000012240452476013530 5ustar ejabberd-2.1.11/examples/extauth/check_pass_null.pl0000775000000000000000000000266312240230175017222 0ustar #!/usr/bin/perl use Unix::Syslog qw(:macros :subs); my $domain = $ARGV[0] || "example.com"; while(1) { # my $rin = '',$rout; # vec($rin,fileno(STDIN),1) = 1; # $ein = $rin; # my $nfound = select($rout=$rin,undef,undef,undef); my $buf = ""; syslog LOG_INFO,"waiting for packet"; my $nread = sysread STDIN,$buf,2; do { syslog LOG_INFO,"port closed"; exit; } unless $nread == 2; my $len = unpack "n",$buf; my $nread = sysread STDIN,$buf,$len; my ($op,$user,$host,$password) = split /:/,$buf; #$user =~ s/\./\//og; my $jid = "$user\@$domain"; my $result; syslog(LOG_INFO,"request (%s)", $op); SWITCH: { $op eq 'auth' and do { $result = 1; },last SWITCH; $op eq 'setpass' and do { $result = 1; },last SWITCH; $op eq 'isuser' and do { # password is null. Return 1 if the user $user\@$domain exitst. $result = 1; },last SWITCH; $op eq 'tryregister' and do { $result = 1; },last SWITCH; $op eq 'removeuser' and do { # password is null. Return 1 if the user $user\@$domain exitst. $result = 1; },last SWITCH; $op eq 'removeuser3' and do { $result = 1; },last SWITCH; }; my $out = pack "nn",2,$result ? 1 : 0; syswrite STDOUT,$out; } closelog; ejabberd-2.1.11/examples/mtr/0000775000000000000000000000000012240452476012650 5ustar ejabberd-2.1.11/examples/mtr/ejabberd.cfg0000664000000000000000000000361012240230175015055 0ustar % jabber.dbc.mtview.ca.us override_acls. {acl, admin, {user, "mrose", "jabber.dbc.mtview.ca.us"}}. {access, announce, [{allow, admin}, {deny, all}]}. {access, c2s, [{deny, blocked}, {allow, all}]}. {access, c2s_shaper, [{none, admin}, {normal, all}]}. {access, configure, [{allow, admin}, {deny, all}]}. {access, disco_admin, [{allow, admin}, {deny, all}]}. {access, muc_admin, [{allow, admin}, {deny, all}]}. {access, register, [{deny, all}]}. {access, s2s_shaper, [{fast, all}]}. {auth_method, internal}. {host, "jabber.dbc.mtview.ca.us"}. {outgoing_s2s_port, 5269}. {shaper, normal, {maxrate, 1000}}. {shaper, fast, {maxrate, 50000}}. {welcome_message, none}. {listen, [{5222, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper}]}, {5223, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper}, {ssl, [{certfile, "/etc/openssl/certs/ejabberd.pem"}]}]}, {5269, ejabberd_s2s_in, [{shaper, s2s_shaper}]}]}. {modules, [ {mod_register, []}, {mod_roster, []}, {mod_privacy, []}, {mod_configure, []}, {mod_disco, []}, {mod_stats, []}, {mod_vcard, []}, {mod_offline, []}, {mod_echo, [{host, "echo.jabber.dbc.mtview.ca.us"}]}, {mod_private, []}, % {mod_irc, []}, {mod_muc, []}, {mod_pubsub, []}, {mod_time, []}, {mod_last, []}, {mod_version, []} ]}. % Local Variables: % mode: erlang % End: ejabberd-2.1.11/examples/mtr/ejabberd-netbsd.sh0000664000000000000000000000412112240230175016203 0ustar #!/bin/sh echo '1. fetch, compile, and install erlang' if [ ! pkg_info erlang 1>/dev/null 2>&1 ]; then cd /usr/pkgsrc/lang/erlang make fetch-list|sh make make install fi if pkg_info erlang | grep -q erlang-9.1nb1; then else echo "erlang-9.1nb1 not installed" 1>&2 exit 1 fi echo '2. install crypt_drv.so' if [ ! -d /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib ] ; then mkdir -p /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib fi if [ ! -f /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib/crypto_drv.so ]; then cp work/otp*/lib/crypto/priv/*/*/crypto_drv.so \ /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib fi echo '3. compile and install elibcrypto.so' if [ ! -f /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib/elibcrypto.so ]; then cd /usr/pkgsrc/lang/erlang/work/otp_src_R9B-1/lib/crypto/c_src ld -r -u CRYPTO_set_mem_functions -u MD5 -u MD5_Init -u MD5_Update \ -u MD5_Final -u SHA1 -u SHA1_Init -u SHA1_Update -u SHA1_Final \ -u des_set_key -u des_ncbc_encrypt -u des_ede3_cbc_encrypt \ -L/usr/lib -lcrypto -o ../priv/obj/i386--netbsdelf/elibcrypto.o cc -shared \ -L/usr/pkgsrc/lang/erlang/work/otp_src_R9B-1/lib/erl_interface/obj/i386--netbsdelf \ -o ../priv/obj/i386--netbsdelf/elibcrypto.so \ ../priv/obj/i386--netbsdelf/elibcrypto.o -L/usr/lib -lcrypto cp ../priv/obj/i386--netbsdelf/elibcrypto.so \ /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib fi echo '4. compile and install ssl_esock' if [ ! -f /usr/pkg/lib/erlang/lib/ssl-2.3.5/priv/bin/ssl_esock ]; then cd /usr/pkg/lib/erlang/lib/ssl-2.3.5/priv/obj/ make fi echo '5. initial ejabberd configuration' cd /usr/pkg/jabber/ejabberd/src ./configure echo '6. edit ejabberd Makefiles' for M in Makefile mod_*/Makefile; do if [ ! -f $M.orig ]; then mv $M $M.orig sed -e s%/usr/local%/usr/pkg%g < $M.orig > $M fi done echo '7. compile ejabberd' gmake for A in mod_irc mod_muc mod_pubsub; do (cd $A; gmake) done echo '' echo 'now edit ejabberd.cfg' echo '' echo 'to start ejabberd: erl -sname ejabberd -s ejabberd' ejabberd-2.1.11/examples/mtr/ejabberd0000664000000000000000000000315412240230175014322 0ustar #!/bin/sh # # PROVIDE: ejabberd # REQUIRE: DAEMON # KEYWORD: shutdown # HOME=/usr/pkg/jabber D=/usr/pkg/jabber/ejabberd export HOME name="ejabberd" rcvar=$name if [ -r /etc/rc.conf ] then . /etc/rc.conf else eval ${rcvar}=YES fi # $flags from environment overrides ${rcvar}_flags if [ -n "${flags}" ] then eval ${rcvar}_flags="${flags}" fi checkyesno() { eval _value=\$${1} case $_value in [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0 ;; [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1 ;; *) echo "\$${1} is not set properly." return 1 ;; esac } cmd=${1:-start} case ${cmd} in force*) cmd=${cmd#force} eval ${rcvar}=YES ;; esac if checkyesno ${rcvar} then else exit 0 fi case ${cmd} in start) if [ -x $D/src ]; then echo "Starting ${name}." cd $D/src ERL_MAX_PORTS=32000 export ERL_MAX_PORTS ulimit -n $ERL_MAX_PORTS su jabber -c "/usr/pkg/bin/erl -sname ejabberd -s ejabberd -heart -detached -sasl sasl_error_logger '{file, \"ejabberd-sasl.log\"}' &" \ 1>/dev/null 2>&1 fi ;; stop) echo "rpc:call('ejabberd@`hostname -s`', init, stop, [])." | \ su jabber -c "/usr/pkg/bin/erl -sname ejabberdstop" ;; restart) echo "rpc:call('ejabberd@`hostname -s`', init, restart, [])." | \ su jabber -c "/usr/pkg/bin/erl -sname ejabberdrestart" ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac ejabberd-2.1.11/examples/transport-configs/0000775000000000000000000000000012240452476015530 5ustar ejabberd-2.1.11/examples/transport-configs/configs/0000775000000000000000000000000012240452476017160 5ustar ejabberd-2.1.11/examples/transport-configs/configs/jabber-gg-transport.xml0000664000000000000000000001232212240230175023542 0ustar 127.0.0.1 5237 SECRET Fill in your GG number (after "username") and password to register on the transport.

    To change your information in the GaduGadu directory you need to fill in the other fields.

    To remove registration you need to leave the form blank. To search people:
    First fill in surname or family name, nickname, city, birthyear or range of birthyears (eg. 1950-1960) and gender (you may fill in more fields at once).
    or
    Fill in phone number
    or
    Fill in the GG number of the person you are searching.
    Please fill in the GaduGadu number of the person you want to add. GG Nummer Gadu-Gadu Transport This is the Gadu-Gadu Transport. EMAIL@ADDRESS.COM http://www.jabberstudio.org/projects/jabber-gg-transport/ /var/log/jabber/jabber-gg-transport.log 60 10 315360000 300 60 5 /var/spool/jabber/gg.SERVER.COM/ /var/run/jabber/jabber-gg-transport.pid GG_TRANSPORT_ADMIN@SERVER.COM ejabberd-2.1.11/examples/transport-configs/configs/ile.xml0000664000000000000000000001460112240230175020443 0ustar 127.0.0.1 5238 SECRET ile.SERVER.COM 7 en I Love Email With this service you can receive email notifications. Security warning: Be careful when using this. Your password will travel in clear from your client to your jabber server if you don't use SSL and it will probably travel in clear from the jabber server to your email server. Use with care. This shouldn't be an issue in your Intranet, but it is if you use an ILE installed in a foreign jabber server. EMAIL@ADDRESS.COM http://ile.jabberstudio.org/ /var/log/jabber/ile.log 1 10 20 /var/spool/jabber/ile.SERVER.COM/users.db /var/spool/jabber/ile.SERVER.COM/passwords.db /var/spool/jabber/ile.SERVER.COM/hosts.db /var/spool/jabber/ile.SERVER.COM/types.db /var/spool/jabber/ile.SERVER.COM/notifyxa.db /var/spool/jabber/ile.SERVER.COM/notifydnd.db /var/spool/jabber/ile.SERVER.COM/urls.db

    Please fill in the fields,according to your email account settings and notification preferences ILE: Email notification service Email account settings Username Password Hostname Type You have received NUM email messages since last time I checked, which was CHECKINTERVAL minutes ago. There was an error while trying to check mail for ACCOUNT. Notification Options Notify even when Xtended Away (XA) Notify even when Do Not Disturb (DND) Webmail URL Login to ACCOUNT ILE: an email notifier component: http://ile.jabberstudio.org Por favor, rellene los campos del formulario. ILE: Servicio de notificación de correo Configuración de la cuenta de correo Usuario Clave Host Tipo Ha recibido NUM email(s) desde la última comprobación que fue hace CHECKINTERVAL minutos Ha habido un error en la comprobación del correo para la cuenta ACCOUNT. Opciones de notificación Notificar incluso si muy ausente (XA) Notificar incluso si no molestar (DND) Webmail URL Leer correo de ACCOUNT ILE: un notificador de nuevo email - http://ile.jabberstudio.org Ompli els camps del formulari. ILE: Servei de notificació de nou email Dades del compte de mail Usuari Clau Host Tipus Ha rebut NUM email(s) des de la última comprobació que va ser fa CHECKINTERVAL minuts. S'ha produit un error en la comprobació del correu per al compte ACCOUNT. Opcions de notificació Notificar si molt absent (XA) Notificar si no molestar (DND) Webmail URL Llegir correu de ACCOUNT ILE: un notificador de nou email - http://ile.jabberstudio.org Va rog completati urmatoarele campuri I Love Email: new email notification service Email account settings Nume utilizator Parola Nume gazda Tip Ati primit NUM mesaj(e) de la ultima verificare, care a fost acum CHECKINTERVAL minute. A fost eroare in timp ce incercam sa verific posta pentru ACCOUNT. Notification Options Notify even when Xtended Away (XA) Notify even when Do Not Disturb (DND) Webmail URL Login to ACCOUNT ILE: an email notifier component: http://ile.jabberstudio.org Vul volgende velden in. ILE: Dienst voor e-mailnotificaties Instellingen van e-mailaccount Gebruikersnaam Wachtwoord Inkomende mailserver Type verbinding U hebt NUM berichten ontvangen sinds CHECKINTERVAL minuten geleden. Fout tijdens controle op nieuwe e-mails bij ACCOUNT. ILE zal deze account niet meer opnieuw controleren tot u uw registratiegegevens wijzigt of opnieuw aanmeldt. Notificatie-instellingen Notificeer ook in de status Niet Beschikbaar (XA) Notificeer ook in de status Niet Storen (DND) URL van webmail Aanmelden op ACCOUNT ILE: een dienst om e-mailnotificaties te ontvangen: http://ile.jabberstudio.org
    ejabberd-2.1.11/examples/transport-configs/configs/msn-transport.xml0000664000000000000000000000765512240230175022534 0ustar %d: [%t] (%h): %s /var/log/jabber/msn-transport-error.log record %d %h %s /var/log/jabber/msn-transport-record.log /usr/local/lib/jabber/libjabberdxdbfile.so /var/spool/jabber Fill in your MSN account and password (eg: user1@hotmail.com). A nickname is optional. MSN Transport This is the MSN Transport. EMAIL@ADDRESS.COM http://msn-transport.jabberstudio.org/ More than one user entered this chat session. Enter this room to switch to groupchat modus. is available has leaved the room /usr/local/lib/jabber/msn-transport.so 127.0.0.1 5235 SECRET /var/run/jabber/msn-transport.pid ejabberd-2.1.11/examples/transport-configs/configs/yahoo-transport-2.xml0000664000000000000000000000470212240230175023203 0ustar %d: [%t] (%h): %s /var/log/jabber/yahoo-transport-2-error.log /usr/local/lib/jabber/libjabberdxdbfile.so /var/spool/jabber Yahoo! Transport vCard not implemented in current version This is the Yahoo! transport. EMAIL@ADDRESS.COM http://yahoo-transport-2.jabberstudio.org/ Fill in your YAHOO! Messenger username and password to register on this transport. scs.msg.yahoo.com 5050 CP1252 /usr/local/lib/jabber/yahoo-transport-2.so 127.0.0.1 5236 SECRET /var/run/jabber/yahoo-transport-2.pid ejabberd-2.1.11/examples/transport-configs/configs/jit.xml0000664000000000000000000000704712240230175020466 0ustar /var/log/jabber/jit-error record /var/log/jabber/jit-record /usr/local/lib/jabber/xdb_file.so /var/spool/jabber sms.icq.SERVER.COM sms.icq.SERVER.COM away Fill in your UIN and password. Search ICQ users. ICQ Transport (JIT) This is the Jabber ICQ Transport. EMAIL@ADDRESS.COM http://jit.jabberstudio.org/ 3907 /var/spool/jabber/jit-count 5 5 18000 windows-1252 login.icq.com /usr/local/lib/jabber/jit.so SERVER.COM 127.0.0.1 5234 SECRET /var/run/jabber/jit.pid ejabberd-2.1.11/examples/transport-configs/configs/aim-transport.xml0000664000000000000000000000363412240230175022476 0ustar %d: [%t] (%h): %s /var/log/jabber/aim-transport-error.log record %d %h %s /var/log/jabber/aim-transport-record.log /usr/local/lib/jabber/libjabberdxdbfile.so /var/spool/jabber AIM/ICQ Transport This is the AIM/ICQ Transport. EMAIL@ADDRESS.COM http://aim-transport.jabberstudio.org/ cp1252 /usr/local/lib/jabber/aim-transport.so 127.0.0.1 5233 SECRET /var/run/jabber/aim-transport.pid ejabberd-2.1.11/examples/transport-configs/init-scripts/0000775000000000000000000000000012240452476020160 5ustar ejabberd-2.1.11/examples/transport-configs/init-scripts/jit0000775000000000000000000000161412240230175020664 0ustar #!/bin/sh ######################################################### # # jit -- script to start JIT. # ######################################################### DAEMON=/usr/local/sbin/wpjabber-jit CONF=/etc/jabber/jit.xml NAME=wpjabber-jit HOME=/etc/jabber/ USER=ejabberd ######################################################### if [ "`/usr/bin/whoami`" != "$USER" ]; then echo "You need to be" $USER "user to run this script." exit 1 fi case "$1" in debug) test -f $DAEMON -a -f $CONF || exit 0 echo "Starting $NAME in debugging mode." $DAEMON -D -H $HOME -c $CONF & ;; start) test -f $DAEMON -a -f $CONF || exit 0 echo "Starting $NAME." $DAEMON -H $HOME -c $CONF & ;; stop) echo "Stopping $NAME." killall $NAME & ;; restart|reload) $0 stop sleep 3 $0 start ;; *) echo "Usage: $0 {debug|start|stop|restart}" exit 1 esac ejabberd-2.1.11/examples/transport-configs/init-scripts/aim-transport0000775000000000000000000000166512240230175022704 0ustar #!/bin/sh ######################################################### # # aim-transport -- script to start aim-transport. # ######################################################### DAEMON=/usr/local/sbin/jabberd-aim-transport CONF=/etc/jabber/aim-transport.xml NAME=jabberd-aim-transport HOME=/etc/jabber/ USER=ejabberd ######################################################### if [ "`/usr/bin/whoami`" != "$USER" ]; then echo "You need to be" $USER "user to run this script." exit 1 fi case "$1" in debug) test -f $DAEMON -a -f $CONF || exit 0 echo "Starting $NAME in debugging mode." $DAEMON -D -H $HOME -c $CONF & ;; start) test -f $DAEMON -a -f $CONF || exit 0 echo "Starting $NAME." $DAEMON -H $HOME -c $CONF & ;; stop) echo "Stopping $NAME." killall $NAME & ;; restart|reload) $0 stop sleep 3 $0 start ;; *) echo "Usage: $0 {debug|start|stop|restart}" exit 1 esac ejabberd-2.1.11/examples/transport-configs/init-scripts/yahoo-transport-20000775000000000000000000000173512240230175023412 0ustar #!/bin/sh ############################################################## # # yahoo-transport-2 -- script to start Yahoo-transport-2. # ############################################################# DAEMON=/usr/local/sbin/jabberd-yahoo-transport-2 CONF=/etc/jabber/yahoo-transport-2.xml NAME=jabberd-yahoo-transport-2 HOME=/etc/jabber/ USER=ejabberd ############################################################# if [ "`/usr/bin/whoami`" != "$USER" ]; then echo "You need to be" $USER "user to run this script." exit 1 fi case "$1" in debug) test -f $DAEMON -a -f $CONF || exit 0 echo "Starting $NAME in debugging mode." $DAEMON -D -H $HOME -c $CONF & ;; start) test -f $DAEMON -a -f $CONF || exit 0 echo "Starting $NAME." $DAEMON -H $HOME -c $CONF & ;; stop) echo "Stopping $NAME." killall $NAME & ;; restart|reload) $0 stop sleep 3 $0 start ;; *) echo "Usage: $0 {debug|start|stop|restart}" exit 1 esac ejabberd-2.1.11/examples/transport-configs/init-scripts/ile0000775000000000000000000000141012240230175020641 0ustar #!/bin/sh ######################################################### # # ile -- script to start ILE. # ######################################################### DAEMON=/usr/local/sbin/ile.pl NAME=ile.pl CONF=/etc/jabber/ile.xml USER=ejabberd ######################################################### if [ "`/usr/bin/whoami`" != "$USER" ]; then echo "You need to be" $USER "user to run this script." exit 1 fi case "$1" in debug) echo "Not implemented yet. Starting in normal mode" $0 start ;; start) test -f $DAEMON || exit 0 echo "Starting $NAME." $DAEMON $CONF & ;; stop) echo "Stopping $NAME." killall $NAME & ;; restart|reload) $0 stop sleep 3 $0 start ;; *) echo "Usage: $0 {debug|start|stop|status|restart}" exit 1 esac ejabberd-2.1.11/examples/transport-configs/init-scripts/msn-transport0000775000000000000000000000217412240230175022727 0ustar #!/bin/sh ######################################################### # # msn-transport -- script to start MSN Transport. # ######################################################### DAEMON=/usr/local/sbin/jabberd-msn-transport CONF=/etc/jabber/msn-transport.xml NAME=jabberd-msn-transport HOME=/etc/jabber/ USER=ejabberd ######################################################### if [ "`/usr/bin/whoami`" != "$USER" ]; then echo "You need to be" $USER "user to run this script." exit 1 fi case "$1" in strace) test -f $DAEMON -a -f $CONF || exit 0 echo "Starting $NAME in strace mode." strace -o /opt/ejabberd/var/log/jabber/strace.log $DAEMON -H $HOME -c $CONF & ;; debug) test -f $DAEMON -a -f $CONF || exit 0 echo "Starting $NAME in debugging mode." $DAEMON -D -H $HOME -c $CONF & ;; start) test -f $DAEMON -a -f $CONF || exit 0 echo "Starting $NAME." $DAEMON -H $HOME -c $CONF & ;; stop) echo "Stopping $NAME." killall $NAME & ;; restart|reload) $0 stop sleep 3 $0 start ;; *) echo "Usage: $0 {debug|start|stop|restart}" exit 1 esac ejabberd-2.1.11/examples/transport-configs/init-scripts/jabber-gg-transport0000775000000000000000000000172312240230175023751 0ustar #!/bin/sh ######################################################### # # jabber-gg-transport -- script to start jabber-gg-transport. # ######################################################### DAEMON=/usr/local/sbin/jggtrans CONF=/etc/jabber/jabber-gg-transport.xml NAME=jggtrans HOME=/etc/jabber/ USER=ejabberd ######################################################### if [ "`/usr/bin/whoami`" != "$USER" ]; then echo "You need to be" $USER "user to run this script." exit 1 fi case "$1" in debug) test -f $DAEMON -a -f $CONF || exit 0 echo "Starting $NAME in debugging mode." $DAEMON -D -H $HOME -c $CONF & ;; start) test -f $DAEMON -a -f $CONF || exit 0 echo "Starting $NAME." $DAEMON $CONF & ;; stop) echo "Stopping $NAME." killall $NAME & rm /var/run/jabber/jabber-gg-transport.pid ;; restart|reload) $0 stop sleep 3 $0 start ;; *) echo "Usage: $0 {debug|start|stop|restart}" exit 1 esac ejabberd-2.1.11/.gitignore0000664000000000000000000000002412240230175012202 0ustar stamp-* *-stamp src

    QzEhIbfh/tX'|k^dWHq)סB?t![ũ6uX?ICiRJw\Ysvv z?"i oQ'M|+2Wm23Y%v$Y,gDҚS6n*Pn9t/Fw l< TɨNԇ',|XBcwš;⹥wKܠ2ΜdcҼ?8+XA{qW2f,G.J1jLnl)68tV i=LH^[MbY)TT8z!ԼÚwmprzتm^ز:z siub||=K?|cGQp%R6OO4f։K3}o(N:99LRb{E`txȿC #B@Q~rjqIL7312Lb`-I̛KLG!9#59; <(%3=dG Lx?C+#B@Q~rjqIL73c *wxȿC+#B@Q~rjqIL7312Lb.X\\_⒙Z\#F Dxȿs. ) ``b\YTXW_ZZ`jd`d``k`k````ejhejZZ5KUuy7Xduˊ4UR23o[05/E U'Sx'KRR>ZnqxȿFF͓'K|nx[˿C+#6Fu6%I/x[˿C+kZbNq^V&@3-Mx[˿C+#6F&ִĜͽ LiIxXmo,{F(-99wl'jcYc4x쒲sgzArggyfvvvwvv?䯺Cg/,TdGnE7@{Ob/ĂSg*B/_lH9rD^U(#'Q- O4h:Jرp!lҹO7b%Zݾʵ#Ån1k[{NWQt|hE*yD Asr쀔p(V<dTLd+SAPD>.}o|ϡO#cGZE_)hQ St&َ=0NcjFTEi ^ ya |mI W]BTj }4d[6Nj{_s{0hF_!.o|\*OX>~ꎾgQt8O/ih!XZ`zm3"=?*G@4BlrIߏ6k2վMRM(ECR]^_آn4,z P%ێh8g {(Emxl6r?Rj>Zjje|Q^aZTyŶwVB/.@GQ,ֵ^?wid1Un!3D+&kV Yf{_EVЎ{,V8q*Sнd+s|Q\4SZEj8(jaѯ'N-JkOfI~#Z(q?90b2<%;W(Y'M&#Pє`YtDpe nZ+uy2̮-+)8VK&!82`.,M8ڇA_'#jX!&9Qβ[8ܷ*VW/I< Ok [wQtQCasze ѣPJ* |D#}*~K&taaqƑi$U+.串Kle\0v/J;پ9&XB]J+z2fAk뿞_~0 FAɂ¨w$B~±$ëH^пC 1\es;Oҙh%V6W^ҢѼe[ffR2*˄h+zϣP1s]35M BJe=mBdQHN̩12Ӽ*8Jvbl*Fr񴇓=:5j$7q(qID!hlLkR>:"tA)y%:豨)̇^`(麒H`g%m"N2[Br#c8҅ +*wV%f4.8g+taԔ[4r,q=Yip֩7}y&nlRcTs6EQ kA;ڻqUwx 䁥RPreA@nW{w2767 wŪҀ iqfr7n2FU?8E)yC#,TJB=3+Hݾ9vLǡBC{+atόO::n0qw>"_5fY1Ry%\ItD["Yx_̓ZdҬj͇5=#səYw<ЧT9O7Zv{ȝ۟!y6s|_iRG[}Cސ/ߍ#u om|C݄|nͶP5uU l‚I/E\AҮkqr%e ɄB2aDOnIJ `%]f\qwRISu瞓]!l;(Gi-r5,hkVj)}`j;ZrnoExmSjA&R]-BZؕ )Vj4bSJYfwg5uwi)iӛ\B|'|v[6!9?|^'d9C1LTZ^"3jMO&X4vUem;-؅QcNh?#ҎJti4CIѸ@}8><%N&/)>jY1M#ef8\x2}qx%б6m&:ťVІǻώ`NU ->Z[5f ]_lF[l12ia@m+pj{\ xMu@/xuH0H-9V8~y\L)e[]UȖj*HoFS L' u1a:vyˆe͙}90GYt/b^U0-tq/nT%Thukkzxjth^V͇Y' Gc5xjth#fc.͇Y' lzZxjth!#fc.͇Y' s8&xltD{'gX)xX)$W'ħd(Z+XVVƦQ I)9 *XV3O><9udq,Z= <91,J-.+NKM!8/17UG! .RYWW5?d%@!=C5kV1o^+p?1 Wx{tWqIBbNjEj 3-uˊ4UR23@:U&et*gZbNqv9Zk.N΀kX'+Ona⓿MN̷J/M,2-Y"xx]qyBRbJN~ 3-6ffQ-N-KM\ƺϾ{xxMqYBbNjEj 3= '?ag4,tuhxUmoF~(-:#Um/8DAEhZKr$ؼ84mu|bggyq\_\.é…6ģ429S}3Ư`N1 |lj1U`-A{aݹNA vKAfNE"͌]Zň\7/S"hQG>TvjkU~uhP݌UT nhD0jbCX9"4V"H "3IP>] "|:2Ą!Rg5S҂wESEJJp$ @u5Vb{[{UMPJ)R2a078>&aK~5C4{ei1Ò4T+)EbTC\Z׮v$M6{vki;u@@J92fJ#Dhͦkj!qSq=$EN+brf3R '(Ã4:V1B9~cIXߡ$B7!A݇Xp~Ѩ6 `3Q-4~JU{=\JU*mB۽D<ݣ.%>o,{>Bkp'x"#0-D(˜2/ FW5܆xKoh]^R>yqu< +>;FTbӪotNat5XmXޢk'uO\ϳj"rI\8 2 ZۦgUvI5mn FlӢ>(޸gZQWd/xbȐ\6NČ’zfQ'$ Q6y̛!yQkEu3GR>bDYIDEVAcUi[xw&_xiݐ>vx1MЫ"vb9r=r9խL>elH"`5a%ʺZ܋F; Qvs!*ٖp^c{գ3nVJ /Y C mXo2 ?h<ЂpWtߠS925a-(Mʫtv-+&r[EabH&({ڬ?z׿jOfA8b}? a=n,x[!Bl#fsƏ#x|Ex[!BlC*+kZbNq,}?Ucx[!Bl#fsF=ִĜYXa%x[!U`)#fs,[E6;1ngdG4xXmo,(XvC(WElHriP>3"'E>3;8<<0Ri䥁GJG[gD8Sie\iz#(Y8 ? XZ'trt?"E?*=s6:/2r-?>iD: TĪ`,”V:{}kuNdMV0t8]gŒxQDSETݯ#WΆc hN>]9ƅUVxXq "z0O[qq9cQn{e7ۻxpD4X*,R=-h2mZZ!Na4E!ԁ @?d(QVhS9'K:Dd([1v2\h*E(kpzzқ$͒إ0t:v'/.>8h#בrj::hsq';h꟫Dg4u46R /V_o,' ZϔӴE~QS A V=YE =spVmYǡjgQBic ¹ʼ`v)Xs~hA ̋KGQbX9Ļ M޻yv3qݬE ٹϴ6ˏt4fv7oІ`;3=6e^~m8WiV&]xY|L]:{+xⱉX_\{ ؂ dgYXn"1D8{Y"nȁ*V?79Gۥ9˕+`Ty|uJD4R~ďF^cggl=iJud׳P74r`~NqP=.K$jv{VPoS-k>Wڃg0BaHtMԏ*|Yjl(E]y j>jķK̑Bf{<\ zU800~Kԗ>n)"^;煬ULu^ )ެ oM7J+?0J%\J{`zԽvpѻ\NfoR6V ceF@䵚ȹKz̭UdE `lt=Szmw&R4|q )/K<#*0Mmҏ?V_G Uct35|Oiah=a LacܮT\g_TD uudo+xc4jygkx= LJFm2aW-bu\qz!ĨBNyp?bpc[d/B0ZPe 3 2JCf[ *0`N ZvB5HDɱ@"QB(=qk,R`[\ @oi O+ J|vgx4Y^^R >bhtjeg<gqpp'+$!ghYZ1tYHձs|>B]: ؿ}B3Uƍ<Ӫ C'Tm-CceS6tf`.RO>*-bL6R-r=KPŸtȏoxl٭ɢ$ wp.)] t|m|p 2sijs\r_=dO.'xes9nOyO: 6e]u v,fi/Z-ɗfI/+I̓zm”R,x ZRg>+z+5ƾ96_7>FO%ʽM^nKxo8p#fq%=xkoWqm^۹M,ѱ.r\c) ؍-r^΃ɝ)kMvO;{{,yd=G e~^s7"\@-E(و̜}|nG/Wk/\+9 7)p}c,D\C)8bq߱+E)x'ҘyK=^@t dHo=>`= ɂ߬yzi(,.9۝j& bapL0]ƛQ))96J!*\Q ;IA|a8if aA7IyX0W+M$кs1 y%Tk.5"r*b#"` -A78j(quc9opZr(NAr%& [؜RZ@8jV'P[`$ĸv&ɀMdzɀ |24l;]}Ng &W6>fѯoQ3d0 OÆp φ3;OMm8" y6N`ax:ldnw'aiw?NGx4Ol07'x`ӓ)1~eLHO0N!,w9=2 1? hv_o6p=h6GVO@q6|{`Z_A2B.֡BxJ`Ŋ\"Lh#wh.$|abXˢ,lqo1/`+%`; ̶ka0K~7+O@[@|.Z ڃ3ċhK׃(  mVѤo@eqWFW *mQD) Y{J O!Ia;HxALP.1b/pN,0}]8CSD&;K| fhh֟wP̚9peszא8ljJݮ]ఎE%#XQI8r*PNmV)F ;)P1^%X' ܎w[6*gخ^DZgV qoizina/;FVͦ=oq'`5%X>ƴ}'wKRVA{Ko4O7PAT[Q0O5,UFgG[rbDMDPZ91rt P}ku{'&6j!#~y/ӈ9KŦQˈݜBElgLq(!A%rֳY B"cf oYrC|OKx-jXt[UD,\`mw5 `HַL%MQal{ڈ;aQW(`Y!o$d>+J+6i;H=l=D5+Mɶ6(i{J$=Q=0;}<ŖܪK#~CsǛ U|o %$*(7t[MюTӎH l^ m}U5%|m/:T ;B`z,$&" JJ[ʢo7JkC6X|m֩TJ[Ud*Ho2ϐ<P/ _')]OGIJ+_#ku}֬e-K6߫d2Y(ۘ͜ mdwK8&@IգBWlQ? Ş&e&۶*ڱ:HB<~@ ᒄ;ǃ7?2]SKlqXA }bB òq$t&8Z[֊2|U׌CRЈ㑦. N|OJU0~ ^ʃN)ar{GPF$e3 0_ n-k`ÔNZ`3gNQN["8 I<6#2*!ky)| Cf@FIeEh9.d4gqC>jFVfHYh`ttpLk eʫR:S1%I/mOIUd8ESbˊ<E:zQMZ͊t J YsS`!]VW:#4s? im@1]79͈"~ *ӞVz1xc#YZ~1--h9W.k5 iNӐkK UP YCPmx~UHpd; ;+4J1d'b#W&-$3)KfꋎX(afn%809)_c(zKXH%DpRX9_'Kl$}ж&Ԋ  ~T%+){]pTfi'O,Jr>*Q $nVJ[BtCX,ݦA{m/Ku/}-ۅ:z3Я;R)߅"~{-=Y&s}"Hv]:o"t14wOO# ( OUaGċ5^2o*fE^vm*qaJv Ki2L*ٮz#tt%@wPu,?[+pm|nev#8hL\hqEa,O000v-—a*χIepzuXG3{_[=)f5ȿv =,dx hib]{.~.m^K%gso}!/{hevoX,j;<hY;ղ 4ޤc}ڢh{$^QÀP,ĈZ-9wV2_(6tʯP7KvQY8 } AJ੿Bya}Vꁝ|1W}Z,Hnς s LS[atK +RmmJqC#dx!KA~^BrvUC5TaDz#*PPRkTA!@tWC*U}&WsyOdA5c>g֍/6Y\i{`JT ު˓zzCibJ˺G]- ZNHy/~wՄf3:So!먓*.݊" 'p~IMBySK\!{ <{.+9}FC#kC b:c_ǔ԰/uo8q=ABr}gI+X&YI-kR8:"5HԧXRg (́M} nbp `+OFnJ%JqsUe&pmG:׵߾3dXo8/BF!o) @eh#fHL/&ϞM}E/r˜H[ [H,-7r+:?<&ŏFPJ*<`"P)T0V ]J- ci)Am:L-lqd")1 R6uFׅU›d:ss2&4="H{ ggiD@#"'{F Ɇ>"\FSD`jvG%Q9krJBg>@,.ܥyu3 v 7p|{]'㙞flZPOA y Q\ 7k-qZŢOt {cpRt˃j,,5=5FL *OS|4s@ Fj&}7/)}x>^v{xY5P+h>`xS*At߄%/>2|t#ux*-9`O/oreQqbqN|qrQbƋK; x*%9rO/oreQqbqN|qrQbƋK lHx*Ub7FM"^_x*Lb7Fs͓83?w}x*Lb7Fs͓83?x*Q\UUA3J!5+1))(E/@RRPD0J!(?713Oa"3FsN̜ԢԢ]lx얜h׎lUx*Ub7FM"_x(9MrYBRbJN~D3fC=/p>d @]x(Qr5050T04202hք x(AriBRbJN~D37F&< ]Kx(9MriBRbJN~D3fC=Í/p>d;Ox(9]r.*XXYNe63XkɹC&i e Ix(yDUA3J!5+1))(E/@BLRȴ2525R-JKhjgg4Vf2׭'d(19Hs1NbIzL"&Ocl˪:y-d16Kr2R'{OP\a̖ZT7dM.͉\T|s2rRB)@$y)V\kLA-x(ArEBRbJN~D37Ɗ&< x;}{EBbNjEjDf=: x[ksF֨lgʖc-Wd[[z('@Ib  Jp{CL>lѐ@~{4bd<'EUIqZOdԚyTD3[٢4ҎLj;6~QY'#[EI*d/xNTϏ[͇E2uڨ<\NFoaUMRdq e(ab~L27Ќ)e)(0Q%[U5wE۲!l'Ձ=>1csyuszyv3NmntdtaK /UTEC'&SK󴄑ap ndpŌJ[[Q0q2NbDq0*inm :k;Bz/3GpFE34C [&~@%n")\ֶH@ݧN/>v/eRc8،N_iy\ O2U,q9*gA~=y/ר`Vcלf_uͱ.xoßVGU<5k.tP8^"]Pw&`bŌWt3XM Ӂt@-S\o;"(j30ʛжr ew~RX+$h!DĢK/؉ k7Bi|J4tb^Ut+Ar1)”lj',<$WsMTG&!N|=(BKZdNP+(Fw 9^@EKxvڿ9陫Z6JV0 `8ؒɦ 22%1-@-IOa l$)Jh2V gn^!w}os:67g}#dML02[xC1RR3EZ!3r L}Iȴb"d*Aeڙ[GEB 6M8+y2,:`RhP&ׯ^|Mg,27@>IfcۑOs$t 8'_ns:NopF>F_'k)~Қ|zV`tij+eTD84O"JI,~qb@BkVC!3(TqTVy۬^6ߋu^Ŀ)='Dx絳j%QqTsCQFV x(J_.̻$!"J,*Z^aI0Jc(hPgf "C“f".eߏ~SJA ̓)/nGlrpi/E @ {(!֢X H', `D&J :\8Og&y>G` p%\6VE5;8 yRcQr,N,IdO5%a/g]4U2Hv L[9x@$Gyp /ㇸvɧ0{n>\ܜXYztQk5K XV_xs'<Ñ0'F?iO2`?2t'"\E!d9VxU:xaY FC>>3Ę{_6Yec*iA2զXEG}~ex}XCUMޢn'$p:(qډ#JշJ5zRrazκ`\|6Tn[X:$ =66\(W~_kSu;b)AqkWmTΙUAs$5nW̎G3kog{XDhV_|rDBwCF9}/?ڔeBcإcHR*(ꦨ0_۪^@ʜj3?ڱA#ǂ#kwl~tR-Q~B5T|,JŜ2 F 2c,|T{7w>'7>"^Us4W$(g|T$heAN"jKAq t͑>1܌ڊC3``̎enث5Ddt|DA'=:8/qÉȨ.g7tP!FIs]n(aǽ8|l; !['mP9v2ӻiO&YI3ՌTI#2+ +dkq,PqϘWeKY"X [0sO!BN LqyG0oȤuܿxu>7_~mBXO C;'i5OJ.)*b.4yB~x&( p^b1- qb\r B8$(o9(uU1C&(ى7ϟ@ɼ i 0_RXfy,Zn{ߟufʘ-(AgТ5 LKydZuNwD_9*^As MX~m!xYNX :`\%̨Rm꙳˶ѓZG;x? MGXc^^h\dpr?. xN}styqs}yfض_&?132D&/# ErՄ:XCMdpz] *N},ͱW}(_Jd h2vugnǐn˝rkǠщwJ%ED F3vb ÷TR4UBٓ dt] pYqy[:XA`ӫg %--mu8Y@‹/҆3K-.a))1%+K6)ld@@3ݫ./tf@x,h0-Qn%cuۇNitiVKɹtxJNQ} m;8$~AgXF&+xC׫=sWB_wKug7! AG4}:1gzN|Βj6z9_M $"Է8L|gůiCxA#wus|^@bLkTzFxqA L0=p:4@?"ߑLnv70Epgfy8a:GI\*r{ƊkC !~z|pzB ˓k7ϑm^i EccQHCGz&247JBb-r20h80n3,T?u1RlݛqbpC\0eLu%eK|FƲ@)w=8)!F6[iSx.C8)\hx8%4!TlT:|ICSH|l@߂+.ч&>d2">W3<~Ncw&¼SG]TM^/ʣ5{&! v"WCUovA![ vbȍvspC/~2ZRĸ^`6$^Jy. d>P$-*<ިVh^ڒxdbg`c:TB;/[(eWFD * [coyP8%1E\?74{+Qz|\&4>K!y<#^X pxkD٩Ƹ;ݣܿBH#ocHdH:\pKne2w4TNf c=yo>anj>Yf%F xY0?)Ji/ 3G#:RsVW\13oYT|[Ư>]o]wyG:vGxXx UU.UUԴ̼TT@?4ԬĤԢ<Ԓ+”<Ԣ"cԊ܂T ψU"6xX ũy% %`~iqj :O[I!k/'yoov 3Zxoސ?4U!H!-18Uo2# Hhs;ơwHo7'@x=KAřuW6e`?̈ c fZg5EHnU]л҇GrJ.1+x)G^ ~8%.¯#yHV`u|~`LSy˔z2 vx"q243P,s %"ɘ+:>t27+4hNe3r;fރ0B~u+A6Iik3# }qvXڬ=ndܖMq)} $& '9O;}ЛoF7LKoa/hZxlI/l{`a0煭sxcf F VFVQ I)9LE bx{/}!v6ĤԢكɲ0b0vB)4u_EײԢʤJ<ĒTҤ$&٬6y@ 7c-H-/NKI,.OKKQHK)Nټ01X+XXVFVFCMI;xۗ~8fD 22*L^ $;n i2a YlaKUUusFfdE͊Ő )|)4_>&ݼ&())/QId@kݘX@ƉG Ĭ 1[?_[p_!hyt]34hQ#4ʁksx!s[(XD橱yʐUɮ^JB9* BRy:>[}Srx(`~! HDI'&"KEv0ϸ+jYux]SGMYTnZlA٤Xjj3Qf$۬у{lL?N>>}/W_t|6uޏǽț*/fk|LnU*s,y/)d@|cﻶR;M!VuA``.3.%s1o7'f'nwWh }cAEnb~>[;{Av͖9tO{tx^3"ӗ:/OFq:(-.o _lzwQyV h*zeK壖P Q.WW{229I ^2c-:/Gy2[y/V_|?XȇUPx4lXY[^E,4͗dy":S`mEeRfٷ5Qgy5HI<+Gq1i|y~e~Ab#ykD%MFDD?iQKV~]E{q9kHmAVD`(K{}nV!d0{ji P_$[k9k]:eL#v5zq?i6d\*  pOc7!-3$A G-{ ;خ7E4 EqiG%'2Ғҍ׸GeMZaco2G2t_#ˇB!U-ENœY Cl)\BEn6 A~Ok{|vy%*.F rp\KmowN@gմvN"n`@ʥe^H;'}\^p Z@[6~yΟ]R3;9/=N0@|Kt^F@y^Q6|hZ͵OɈojv# [1.-jqŢI/*7sk  V(b׶a61CEK0p'6E'$5Jf?؁|ȁעiwea,ax4sf|:4dY%'-";SgO"SI0 QX Ld}Nw=.G4zY_e.FJ!Eݓ:;{3KCaUb~QBo@0?۾tl` uY}kUaѠRRAP-D4_K "pD'4seHʻ^M0,)xClP茺;貴D%9K͎9/PƢ"=`Yz4v~Zn"Xs5&gYx9eK_-/E@&<#MTsB@{J,N%eH ` {q=޺5(JϴhхTb{2׷ eձT/dGg$me7 & X8oFkSkK -0Wn򺨀'򣉵ꌲtUօGyX )˛话𘹌m$S<-e"Yf9cA!)hwzSݬZD%052` Gg%dԙ՘x&~38El=v˞mn>I=SA ae㸷;zv~{4ys~Q7<,3*@YUb'HfMq~OfQ663 ':I,ab*ފ),:MQ*p쇆6l: V < Op+jGο%/MGI [:0\!L :=e xƂ|pFϦ2SGSe#V83}܇$9Í `~ܞ!Mc'h %79K7&t/rzyvDK־}sx|mB4"jʦ者 u^¦.~$Ks5Q&ERI,ZfAH "(햄BfW״1? 0A9Q3{9ժ.gIm#D m۸a*h9Bv/-;%.jNW}7=<k >\`3oLsNU#`:΀(ѝb+t[FꮺoKKu+4XČ.U1 aJlRx>S%:<|*`ӛ S[̹+z`ZOₘ-lM %.zLd8jQ5;Cx} >zO>~:(:g73tAxOB+8Ԯ:w5c }uR# _ys#uΞ ѨΟ>CkϨO%-= +_~llxè1yk qAnwXq7;`Oe8x8 [*ׂ0Eݦ)ccP}+ֹr25EtP夰Պj>X% ,]8w:̽NTG>&с D4ß$؍sYfHDy$9S?צ @*dG8M<~bIjD.#NQ?&yf4 jIUXVhME|>ߴn PDWj U=-`^9.<,$_I*k_`o@3La޸`\ļs&!"%d{6Qє=E?ha<>OMգFwUDg\31r$̨ܾoh&sɘʐ ↣ iRkov" 3O]jV.Yxx0FB]Voll@/gMBTHO̵+)mS'q8ehF צ4JG-!uhZ`l#Y}Ur K-N/ K Ay%ZߜMfɂl 8AY3󀜈d+BS`PW H]N_m~ UйG3' 6LI [NEKF ؚ,\ ,$aY{ܩFz޻3y<3Tcڢ<3]JR ¬`"Mu|d87IǍh92pZ9u.h' 5=$4}hϝDH}i4TN$6=AyM'b4c;n!A>i%LD1YPƔRZ[̎K6kiӎќvU*c31 !Å[ݝ|}.æ>1EyTBi۽{Iމ=KS?R9w1Y Wd8V LvBnlIiz*8{U n{ێO^{}pf# aQF%O.&oU0aƬ& tfJz܉FBw}syzgcmT)7Rp5\N(a<(5ʓ3Ito:;J,d=&0*)pg OsL& %p͊y˥ik2mA2qɎy뾧;r\B4aGH`"TCPL jb OChM'9jKנ%f>rD>H4ʮ;!&Do}>yxE#9U&<`a˴l4[Y__Ŏjg5 Dke[dU'|'(l6n-kN~8E ٬+= Kw2SoK^ %yቷpޮ)̝'JkAxw+M!N~dMxio8xgENhF]Ȃ-/IVw$DӜ$1|W2L"r݁;9Fwr$Ga |IH=g|yP51'd%"$GϺJ\ ;}6]n4Q(P,15I㨦䠏Sv OD&rD$>̶p!ʸ $U7\˩źy2jYt׀ lJXX6@ܤGqב5m1}Ef/ OX`.]t*boѥGDZ*w@4/ <>3r_+ku8z5R7(Q%T<5-Dd3Uȇ-9芪SUMCBjNcs1"hF)eMxCL>K#a #Sw1ە O$eͪښ:HvKN&ԫ>jE7wj@dszZ+4~V;rXrӂ{~T kme0xy#rQ01w71흟 ߺ =G myN6Ha/p2 A:H-j90v_]Ā'jIú.Nj/(On͆ZmT!+ S8w9D1q/E|zg{S#r s=?a'0w^$\Ei[%T;Ӷ\NPű WS,7ʛR/Y?EA~2dlC%Z13!Ĉ̄dWWB\Dy7W}VRY$-h%WPntfpX|4iXh7N F1#DqqOݢ)ȃ۽n:82<:3j(0]fDE Z 2ZկΞ_f-%^m!7;pUnoWg54p]5ga gEH7lܰ6nc4AАNd|)޴.M@MƊ/GC< cWױQJcVCBx:?qU7okuxc60G geM˕$nr%IqE49oFnnmkUU JV}Q&MKdRodw{̊?vф8x=;tVKX|DY @cj`֔ "!<}GjMzM[*? |^l%-@ %ӢWD7UA$+YuMO6#LvAn5sOQڞ2?6oH?f`Z6 B|C< ev$$$ʊlZ-DO2ϧe f*j/esCqYY$1i%-u917qX``vmb@% |p/ERBJה_S~1F&',tN'a89 1aǕ#bTi)+9j'^gd( dA$^tFr6tCqkMۚwP"FuzEu$ C֩_MNj=Z'iHL&)eao *@]R!  (#rLNAItifbi9NYCACI@~Vv~AV~ܡ Gj?\ c[E` 4bіfNm#rԥF2 ; \.ň{X(oo-ú:m ^0)#{?Vj{Қljn] DǶGK{iɞjN4c}l{zT*w4E5eb w51lCiWQiuvw':"m;#̳$RσJdE, = __$\=$=QLȢ$eb:0>#Ҧ-C ygBH٤UZLElC8k^GQI=K$*Fڼ[6c)bb`YϜpuL} ¯uQb[|Q[!l%\ms={,mr#э7{mz!q'f@u#XJDc ;6'mL BAw)k6Tєp%}QRU:8m8DgFjR71h[-,FJv/ !nz8C?D3q1}oOa&( x_fSn;[. !E[@ܸF:f5:Z )*뱼-6]q;t!Ō2NJNX;7-se];1o$)N@ ܚ.Lm7%wRMʦk0yV6j$))-qv5g)M7<ޮLW[{ۨY'+S,#[m36CT8G)T%Wj0ʴ#OEuIL|Dy0f7ܿ"v X{(#Y#l2)I.Ϟ1}7 \ӝD20`C4[E|zt?lS3SbvmfDFJ`Wx;s F&*'*qqqMηRl:Yx;s Qy V)% ɉI9 9y% % E%E7GKMnx{5#fƕl(n3x{5#fƕl(-x; FF?2pq*DSK=XcM6/c]ZTZ_\0ٟo!Y"0򠨱AS)ǩ`y%vgb&&&?f^dD虬Ʉ;@/~MAQx;qs 6n;YA`nk='WmnlVɜVx;qs 6n;YA`n=6W) 4]xqs LX6`uqXl͜ -xq ,7kyyln~ a$xq~ >cYoV8Lfr@&fml^col.N` #j[S&Inf7J\e8?''gbNN~=Y՘D8kNas{r'6Oq<4yunL= 6gzc*FpAjrfZfjB^frv^bnBfBbNQjbJBQjzfqIjQjѫXsS'YY]SP4!v8y}V6xRJ@E`Ƀ@ Vk= Z--Aвl U_P?Ƥ ѓ{ٝyo[csd_2:|{ )ŵqtxKEǁ-YC` rzM͚轌1SR'i*Z:x yBi_ x%U,0T"^eTƭ@mɛ@q (:D! ZRRH.q)QheQ4u!Q2g{Iޥ{j*۽ I< lReR&h \=ecE{wlLK6pA7bH=@ nѹ[!vns=if*Fx[q> F Eɩź9&o\cֱbk|i(>xP=KA%hmILaq!Z!,{nT _b,rxoϏd{r)m֖9<(&%*͔B|> |ۇARB4}wr+ۦ7G):LRLuL$ܠ[ 2JC^vg.\Z=[ %kKD6 h\sڮ_ϾNw=/шLD83*%TtܚIfU!ױ`!n #3-[d&?Il~A2B xۿn ܓx'ؼ%o &o,xۿq> 4&{xw5#B@Q~rjq^d?&Ɍo7g2/g 9xmBTqjYr~^^jB@iQA~qf貞) ``bZZ`dd`d`` D VVQ 9ũ *\&"LU-+PW J-,ϳ0 ,f2/lQxg{Y"YhxϷ?/udƵAE=xeSkA'Zk >Jb[-In<ƶZmHă5ٝ6cuwRăDA$=(e^ij=ɋw6J;&iv/I51b:b PC5jhbʤRDj4ɠ\*KgOk4PTnEb+qY )ţ@B͜ER`MnX  uJGA0j74\n6*OnVżXQ,cUDhs³B8~ ŽP ҚN64V*W"tzWmUܯE='F*1TmjHwGS-E<<|3|Z#~`Qa 9TA>\m*~QbB0srbUTt>F;skA_33~s}.ֆGP(za1}}8*u ލ٩| _E4Qy13ɷ|_G˅cYTNٵ0y {_mRin`@џ-{-k?{.]nwL;W#,1,AjĜ,M.`Onqoc&ܭj)Vr$P*mauPsIN3V&s$]x$_2˸-b2Dfʠ? wÅ|wnJ356kdP÷\+ԓ9>5IS<5$)5~7>$l23="3oNΐdn|=RhuLrBwigwz?!pk\%uMcEK6α \\F54X̧^Fh74M=& <נ%u7G-ǰ&U2 `;YL,zp=S'T,{nwURLD \~Y~}ᶋ=۲d-sЙ+/T=d%Q?d:6 Gs gB"3f9+9QˀG \_*YucA1;+KX&?hA]+.9R'R.͏:"io@ZE|ǹeYZ֊ ߫-ʺh Yԩ?|f*ґS2mgn=Uɪ۝Z(:YzNm ear9.IgAG*`&hIe/ @1`m\ȔY $ JOg'( .w%!(r'mܶ_k&Ԁ%2wH-7=ʟsk-<RM[M3T !$# +Tjfx}$r/>4!сG{w:eJ1P" ٘w[;6ɁzoDk!K8:t1:O6l;Q@nj"(ϿO_Z՝/eYK|䯞#/DK<ⴢ6AidLhxOH F`T!D<#HQ$ِYB1*J(lT͸T[ZE|@M$ϲ'LWk֙Q2k-`yG>b|n>dԣӝd䍸E,[9P>M2@22x&-*@Sw0YvLχ~׺J}ÈV JfFYtT֪eJSrb FAip|ĭ/X}6>\W* 36xQuz hΖM͜`EIvT~CV<8h( Fj7+1f|KEOw9Zx,{>v@wtP@@^sΤ@NR:"j2xw;@i=l'/{= ; Xz? F,'shv%"]X)uS애Umr]QYaK9Ni!@15nC*P`Sgů(^Yr˨hFŲM:GGK8l9fFeedJ7& Kt\P톳|zYq`W7a{+,؁C3\V1OsEW'g|ʑcBZq`vΏ"?}㐸ͦNIvS$.G/.0 |& KRd]]C5#]E7B?/ ݿC/xp"500 2006-02-06 05:12:54Z alexey $ JB501 p 㓪f}X@$ !R ?# From,04x6E|71w7ih0JMxuRMlE&qNtی{ӵ MR`Eͦ]MԊC=DU½r^*R!r7(ځ"1jgޛ9_ټgdy6%JXM^Ūx}slc:&d0LއP\8"Po ѭ$< LxLT[d RUb@M܍ }"N-mX`B&!MJR~ S6-]Ӎ:vt H]DUmKw(鿐ɦWS;Q]=e]IsAxCّ5E u=*\DV$l4iax .;Jd#:<_.s&Ɩ8.1{0~ɛh48`?B0!ׄg'gыp nT(L{i~p cwFFԍ<' a`"w,W@HjBNQ6(?JRԌ՛5"r+ J8RdF+yVRO `8٫[g_!B ²` Z ,lc< aB,.)Y$GJTHw./Po܏z {lQ=$);U)YFB/Zն\`zMh{DW`BGC~P}^+tzwN$N̘fܰ">vS;W}cA^>2悉f^{ ,/<;vBged?5{E=;s \ʵ=G])'PQD]84#,2hf*l.,ЪFcG(Uڦ`S ,ZPxd25д A8 EL< *%+<|1Me5u_b3tȒzhj}Ѿ \/jO*ykXwt'4hz?fGscJV1MTo y5woss+Ȯ7Ex8[yOYtx7fp/*'V"TJh.B&K=FV/l x$4IhBIl"x$TplL@9x$TpBͬ'397Wx$OpB!ba&I\`s͓, 'x] 0it_ tȑ +9 &{Oܣr^OANm=WlBaD w#IC$5zEߥYaXe-%ָ`8ݓ+Y'AYo=FT6I\Ox'TpBba7tlx'B-n:wf ݔԴ̼T0נ`O?%#==C YdYA #x'B-n:ݔԴ̼TԬĤԢԤtTM=.U[/\ &泥dgg4ٚ~%7u9&e&:Yuh@gsd|ph@PĨX.x]A 0EҍW])ToIDdHF[L ÛfͼOx_o^24 cFb'({(Dbr]U]>SdXmYrg7իlwߞtcFQ5>*G hxq1l0xȹsB-z#71xQK0ǟͧ8c_Tt>vL&:Pn{UjT'뾻״2K./wv b^HaW̢PB*I(sLNjnCP |Ms49UdL.-ʢ1~ N$ry Mu$l˖5c2Sk?r9 Y_ɧu|\Qk=Y4g|c+*kqRdϡ wN?zO'Mu!{^ o¬Y'y[s%^GSZ!NCڈuH[(ahTi^Z$yqrMQևd΋Vk{f%D񔺹Cliۅ6͚U1%}xQN1 PS?DALI &"L@e.Lعs0<Eos9'{l 4]\ׅrZjzkB]aU[-ԾE8DL\citnx>IesJ惀"wA2p?RRp jvD EyI/A=D=LkYO9.^5婰.i1#-p,AH(ʵRyJE'Ir6UʞQ+OS ABjO+Us9ϩ~vl40N*.l۾Ϧi ɋS|8 x\Sƒy+ڊXHRǾ,KBe0$oˏR yd%Ȗ[եRn˗۟˗/qj3E?$E'0/hiE:Uzg}Q?BGHӭِjCR-pNkS+SQO)"$`;H}qAj`%p[ra>]*]IqՌt iDJ0ψ'/R'oyeoϷ_5GbޖR\3tD_E[N] "tH 'JHL6*"9:+Z$>_pG~at@l9}_sL:<)Oc aYȏDSh>Vvjɣu[ 8Cw}+TNƞYVB='K0G]D N+m*6Q F"%"*&ٝt}goQCMㄿ)+):﷚.bD6m~ 4BO9',0gkhxdJLJùm:kP{hElHҌBI6)wxfu>f6kej~%P9C*S A)I,AA4TrnL?,>/f!h8>BVd&~i#1IFssor'TWKB5aqž2I_MF4:R/E`@z Z"? VP!uZ%s'g, Zl#!ֽh]R D:rRS؆p4%uo~3(sQ"*WuuF*!\Yf'Tɢ/:o@e_*%R\Igv9AGr)o(yU%<&OcNx0FZvPR t -YnvRi2$QVƋQ[yW"oGQy0La=/Z DC} ;;^ wD(98HTl>(gaGߥѬ!lr.} Ǎ(,/ў[.G]_u.sU~WUΎԕTkCeʔEM FN?X/|J[J'V8eT'Eqlٌ7{}GW$M9U+.zhp|XZΡŨ緁] P;} r2fBsfu[% nPlAXm[(XD=>M*q6tGhXsWD*8cq\FÀ,MЭ\ޑe`s [[6ݎǀ\0ؑRH;>rBsނGЀ DzEZ0E`>{KWX'~:-u1%цzc5gbh1SmکQZO332nCޫW4 r`,s希&e).$nq̐F:hC{.NmƱ_P1b׏(aT?*@E!/(C[W\K !'F?11  lدfd u#0%7@'cG z1i4ΘQ2POVM*^$zO]Ӹ־$ZlPnaQD?kIL9qO㧌L`g8 7y5dr5̔Fůb"EB2Q Oџz+Vޚ~l99ezed-(Ҷ:F>+/A.W#> 9 =ը{ <9;fiSoaXk#a$wb>Mt:ejNvzQ#E+qDR)@~9Һy&mpUC6? ;Iwr-ZՆܢ(e ,"`бrMI>K#Mk:W=W1)랧}ä$LaF ~r?rbȠu.G\>B)!]szUrXgJX:H {V0Dn))%_c5vpo"-$=,18'lrB:su z4{'o XQl5b>-PYnfK6>z[@"btf/" l$/xMR3iF;}0ޓƾ4œQ+3RoFS pE*21 XTz(\R˨ޡAo9d Q ꨇZ0ll$H$gqMw_Md2 ³Tdtgugax^|NBR*`6t7| G\>iIw0:_Ӎ5n|vU"(;55U1}B.{: ]M E gVcy6"||B_OL{IuvSi/4_,@H| >]!ω% |UPlo#h~<<pjPoCA]ӠŐ#>GkK\;8L 2hA4̦ p  FL3c-pC]7> gJR4B nBOD}%BKȲ^&_)8cN[e@*2~W |C$(Xvh7zЮ^~,l4)KQ3Q^A|iyeJR2a6|:.EHU$I5m`teN:y2܄uHx*RQ/#gtn@3ֱRqT '׭!8otY O,։qT<_vA* S3AR]tS [%^T&+<(c|\A9qSm>-s%pyJ><36G*+a yT K-5"i[) J|f=#py(ǍyEő.ޤu4wq.g,I_k؏l2ƑRNlSޤ{h= 1",KI _-JW4y^=-oOk h3`B( PA K iY8dgq9|%Җ7ojK]lCʸ8+H75z#\ fP05*s:q$`O K0 *8"0hqi8/8j/R:_ؘ%ͱrԫB ˤd=Oa0j+hۊj{ԉPOCUK&T,hE(bu>rـgM%~aELӉ`1U^#][`yK g: ~c[ҒejYcVG2^W 6 л^u+>/=-%X<%\C,\3_片TgRxգGY2/jdơiߧ& 9;y?s) ;"/.sDFm=ͫQ !>L~ZP"ee"-39@NEn 8]% P-2+Y!Ces-r,V~ЇĽd&(?s 9)̍wO7Um,7fyD[@;K"'[p俭 S 2d I n^ʇ%8&8Q[jee|y85qWY1{6h V:dXɤxl8?}D m4Nx6q| z|:\ @P[;W@|PjqLt7nBn x6q| 涛l .<z#x6q|  5?x=E0F _modified`   3.$x/> =xMJAE bo tB<֙GZ{7ý]}KZ^R48G~d,! n4&dY>f U $n%tU{:E4锂5#&'oqro,^*MmlNv#C׵oGW[{aN,x!8_  // 0x5qD X7N"dsdZcY . (x[;M#F&n{7ʳm,5G ,x{Blẑ<+bҜTĒԢbĔ<ҼdbJ̴ԢԼ.UUUTZ 4)$#? ]ԬĤԸļݜ̼TZS+I-JKLNŪ.1%#?ԉy-bE od`#9($(Up 6:XYSZUx{!vNlgFKbMLLY >~x{!vApC F/!0RPL\uuuTUU *23J45 SR&Ovfu-+PW J-, +mlx{!\l?FFML+ xXmoۺA@Ir/m4i}&(B%")'59(Ki~IMyoGE) $!siDTա4\,OsY*‹TZ{4P g;[S3BY\W*Py_%%\ɀc]}ttuFJaWI/X!/`+={3b|su>F4Mog.GSNgD3x5xzi+m$eEi@-4,3ŝDSYA?A)2G]+JVhMgT,H:{S ujם8Jc/t#*IR2ٚ%RZގᣓӣ?ӻ[?4_Q0pX=>0<'O aA#?WG[ S' (vĴuReR::TV ̮}r LFAܔpu i41RڬDS22KO &(֤DC+&U% jԬv,zVزDgzef1'lH`sgQKuPcGޏZ7"}t56aW^`V߱c_Sb\T',R23i"XR 25 u L$tA%YW!*r7X8ec+XA{[ lںʃׯ]PCt4q/࿑KNwӒGhQaP Z%R,#DGјB$1d@cVׯ͗F^N@}.`DqYIx.;6%y tP<ɲa^!_i^HuiwQd:(u#[N(lQb6PWd2=+scn+~ 8GݛM@R#qkv`'hQPyrt8輰R`kB-t$?o|HS+9'V"PoHi( CoJPsɽ(b^0m> 6,>R:h4갔Ķ8—]EڸCYY쐟G]|0,/ 0mbR+6Hr{m?'ud:qd6)@QXBivus&KqO59Bjf H:?[G! $VA׎ĴI楤e楦@d& kZsS!b>!@=`M P9HpYܿX77 O`Q*8x*t^h?QBbNjEjd})@51>|i1Dx;/Mh?d59@G7eJb, qxZyoFmP[FۭܴU'1`ņdA#5QIʎq?ޛ^:lF+4Ǜw_3^|OիW}IOG߽k7[2x*n$ȹ_enXn2͒J%mg0,T1O&d}I݊=q=!YPMI8g9l1ͽ]wv 1E]fzs2+ʇV+քno$k|qHnBrf}rax+~MHI('^1A,IU =Pߨzxm!ûi+W mvJzfF3ƒ>‘Lm3ӱAi5V[/)rnu C9^J%6*{t#&#ߗ,m$D ْ5!6:`& 2410Id6Kb |93Pk8j+([BɓDΩ\>QF"%eͥkd(Okԛ\ʓ 5)5u8؈'&5(kaVl G˘ǂ%.Ú" wnop=3d= Q {%N]9VU2E_!bEj6}G$Ř(D["}27Xkq3ţh@F]98Fai0^^jN{baAt]b+]g\lbu87RJ{`d_ ed<Σl|\,\rUDj*R~±r*u 723):*l"YIA-klmr98LgF;Vvn }ujFoOr娳֖Q.| yfxZl(FG+u;ZmG&Sjb ++4ydm{oQ*$%o]u:9-I Qf}Z,~rb EQ2ꕊ`XJ LМcw{-]ObUD0"Zym&[&Pj-9X*xJJ疵[hc?#{u }!ʗ%X>_QԍԠHyuЋ>p?lG?j/NeóL;TO=a蚸٤ 6 exixu{̃iuw"8h Sh^rq |7ś7S{/B$38@Kǧk!q-儫y5 Aa_2<Rr<RZq &1 JR3-AK(w;{CMKO#::ztlo2< }{{`m5 (%U&01 k~ *YҖEPiRmqr74U ,#KuYNP*Vm't5ƲCxR}(8͋zھtݍH^Gν>C5нEXoJ^,N42k>{iR%yG_Z;n6)\Mr_EOijP~nx9f#fcF]04 3x&jfJ'(\OH@׎SR6ƥPZT_P3yy*͓3y&k&Lfhܭ³j3idx[5/d#fcƫE&onZ! $n x[&j#fcƟ*2,%%x[u6t!#fcƛ2%9Eɩ%E%E)ƓEmt3sJSR5RRRz6{72K&zXYekh(dLnD.qY\6`Ա/B]0VSk!fG~#~&_Ɍ"8&UVܼ^= 4st'3*-(7DC.O hA,TY0̴uVE%`!|nbFZiFuB|p-M @6ĶXԼP#81$48>858֚ O@)PEaJM`ܦ Tx0hC _(+n^$_f 6x;0hd v̪.%VV%Ey: <+ҼrNq$^Oq 0cQ/ ~A ,ޛ5V15x;?*/rMާ3YOYt5g\Pqq“NxęRlr2KR 32sR58 4OWSA׎/QH,(ȩQHHMΎ/H,../J*QPS%Vs2{"@;Ӹ8cf)%Zy%) 5 `꒢Tp-ȰԼ iL`x8՞"qMe?Yg<9l(OVTV|N}&y[p̗_Qs^e&J39mE{x h`h٘QIRo!]DžwluG^q9 1Lz\KN(d5َKb, "Zxks`ȤَѐxGI>|“ |LJ [xXH4=-o>+ڳ % w 8~ sLs;|  io:format ^'hgx{lCmԲ܉ ,;.UUUЂĒ+#c$#3J"0cbX._W_ZP\ZP_T3JA3J!5+1))(%>$C/(G]s]SC+c3+#( *@s&2yLneWExE]SK8OC]%(,83? ldf]L8᎜-"M7uL[86da䚼Mj "%M~]xC&$37 2006-04-22 03:35:13Z alexey37" q3RxuKAq#JiY1?I!CU"ReN4eV{? z(SIl1J8|>#}RSea*_*\6[LgK<+* mHxs(!Uhyw!DN=옞zh"\CJdh;e\mC8vipksfp7^JHcPԵy?!B+A}F 3[qǺ6w.@#qF-jnF63']eI/փɰ8ihfUM/p>nV軂E_'6WTPجsPQ|jxe>Au|JFD֦Vm6߭{rI;̓G0pr?P.*%?x}JBAz">Pl{j("=%̨mJE[eER=Bв7ޡjV33w=b@ևjgrhXEL&Wc:@8TP%S(eJ$oٱC]Gי4 bŲ;"tP%}SU{'9g-u"dEqB Cj4:h& uCZ*> Hi č7 ֻ&>!rQ@8cVa6]/U1WxDp<ж:8q_OXKPwŒV }sRc/zeE&-ٕo24xt] 23~tP[mp<6,Ifu"_gWxY{o8Dʀ<9y 4\Q@KF}z$5|RHNzh46 ~ɏNd,g3>/Ȇ"U'epE&b߇)}*UȲJ0{,ҕPK,Nńxruzt}6Ð%ĥ-8 &@8d ~/ԁ gxV$./du Ґ2IVEm߳RWwdD<ajS3"jنqFl(лo(:1D g_gޞrW_kԝڕP(ZX{ȝocF ڱ~cb VfNd3 g{H۹ Trkžh&FfUB1T3 AOC6x;tz*b{A)]ge@&H a_ M$ hR0 R /`KE6d!u-V Bm7n;5g,RInv( dr`]E("Af9m;q #VX>g3ГS~xU` ~&fV."VktG<й ZG|6QwՄEc7C ;R}*V'FK)6x|QܖvѽwSZpc؂R4i{/G㙾P<,1F'yt[ym fP˂-rK{^vqJ̤ a")jehgAMNs.&қmF[-%Fu[LCv%{N$[eA[Fݔm!V#ڎ*V8XɎ(RGnx;f{vC#H\Y*.x;f;vC#HjONI #Nx;f{fC8#HjOlYX9`"[F&N|'o՘,()i_\RYRTk8K2R@i9ũ\ SRR6f$4Qam,EeE@`EћwKf!)1x;j3fC8#Hl\%El89wUy9z~>)AZM[+[!7Mailx;jf;Q\OxMbl}d~2 /x[k3zC#B@Q~rjqnF&I\`ssdy)52wfx[kjdy)58 Rxo=jaAxM];:B @ZhU\YTR59AȊK RR47O'xo=zC2#^l& 2LMuexgx1cc^~^en~iBqiAA~QBfBRbqjB~BIFBy~QB~obzPGj^~rMRZTWjXSZQ4/R!(?9X7?/UdD0RPLRHJLJJ-JO,-ɈO9P/(GRL  ͬL-rRs󁶪LN`)[VZYg֧0+nFY6a=/NM];. Mf(Q.HK^?x[kj1䟌ۘM6od#*F6~ixZmo8 "@pmoiHvWȴ,z))Y#{f(RcN?y>3$.ޞxFR7Fg̓R~/u {U"\,E(L )HH%rEm Lj_GG7>>`5 N^|~.a<~Mgp(_ DO{Eo ׃l_!!R(gC}.vOqH)bO.XSQ9#97ow~귄J /ə ˛ͦ&J~2 ;QFh-JYLђ*ic4u w_& u':Gd*9-,V*Ѕjv`T +i~X dʲJ ^ЄS,pX(L&5ؚ}q=)< )r8NhfEl_k^GWWfC)mYu}"5P㺮nq]`k6t.)Y9̴;9p؟9d§|PcExl&RtT-R7[O + A`>dXo<0#{zyl&+ͰylٸqߗI ?X.Xmmѭ՘$?]8inV-V $JUZ֐Rqѹk+ 9.Ђsůȁ'|D A#:(B|NcRVp,_;x'mN_ipX,953X<\ʩ?ABwZw{\6gOv8:dvE F1U8jɹkΣp6jw#wVs~{qo/0˅U<ջ^xYFr&}w~GvҌky}M.cMQ\ǒJ2Sɗ!P~xWS|]έaUs`ϜNAք~$*:F{Pm6rm!$3um n"Ԣ20# <(ESA׎KS2y%99)z\\ !. :((O$#U!'D!?MPhrBFb^JNjBRBjEIjQ^bWJfQIe|zjIh,7%cM `<ݪAN' nBhM@@AFi"IE'ŏN}#{`IVp8vtQ89=}&*OzGݮ8舶lwz'vG\;ݣ-!a.3 NmRx2u ɩ '0Ƚ@hRc oV`Ծ"R[<>T'ْ|y.c[-[|Wѓ`;N ۷;!J(Y7Zf_DC4*>Y7@ZUobks_#(#IIXWIvˮD"Sg&C{oiNgp7.gN,oa2V;=?Ng- q9P8ޡ4s?ZdD&w1<Yɨ]qmڑ_@8<oАX:l"ÌS]~86FqS bT=[̧- |V vYޏ6l mӣOh}KSڗ'bN1T2'uo`%GWs0%uF`mzGTL*!#k3]y2 ]0 AN[ڥW14F:pqnN2c WA)9+cDL&]*ӶbQ@S>TOc9夼ih6Z2"N BF&C$df1I)+\nð3`Nz-d] }s zHi\|8x5>|#Y~(#A"*2eo Y趸ԡ")gͱh%wbΰl#/XnZ$1f*p],y"b |/;%p 君cdu)Z"VWI+5udZMӪ}A sXE;mP<׻!0 HNMp>5DWOO>jrJG}я5+V-v1ޝ,EFV[w^g{{t og+c~>ѝEeGp~{z1'`t"qSm6j*8\nBVAeK>r:idPjcZM':P8~0a`R $b2 99qtGZ(+鲖*GMsP$S6E qt(\ԋW?iTM_]xT:Z+%\CMyCLHh)bK94ih.ݩr2)9|)n\P2uJU+_Ij)9dQ^q77Rr{Q:+J$&M^fOM[8HY[ڂaV4x糤b;j84O#[H8T]ūT/lF{ ou+Vd ="=9װe^j*eGOmPqmNfaꀠڿ*}*YتjB]2m@[_*3@rRz&:  \RZ%~tb8uA V5 9*MA+yI3bg ܣ6DÒn}`*pLR=-gA̷ 6 vRO,s6"8HvY @ljitHiC+ȢnS\4?\1/L%fgة,_"YA=OȄֺPk?Бl@ɾ^KiSV-ԵLJcULHW3WJ$2QåTLMGDIЏB;Lޢˁae 0 eu~Iӎ zG*# ~ScgN!qܚ%_E '} s6Fv*uZdT(8aZ,2͆W{tVnVКsAQ6т#UL[MΠ`24QUFWDDq ?t.:* vZ]w^~p4T@j RlP7*Z7I#š)P&#U@Zα-AOJY),;ϫHt R%PsIYM1(V>)4'|asjH`} xj'B/M%:G\+U[ԩ7WpDP5qpuHW4aPϗˌ8,.8?{(K@.,kjp\շ%;,<V9 kԠ0i,` @n?xs7g#fwF1S00 Xxo9dw ~-7`dMK)Nϣ19V kr$(*()M ;y;&]&lj(O%(=F fl\ ODo~29QZ8>Vd('g^~I|bNN~y/+&֨lV 75x!x#fw,:'mdcc6cdA91Ҽ" Ԣ"̪|\i9ũy4& dMӵT}[%d'OyǤk8ɷ%6pjpqAf^䅲hvn(r*)&k7y"p=grbqBn^jqfUyQjbFuQjz|iqjQ1: Pm i@KA΍vU9JVYCVV0M5T]u2 ] V wTfI5xWpIE` k5Ry)?p*1O-*/Bx1Haljbw*w˝P^xd z;Z&Xa$u*s''/07G+/$>1'' |w7g e|C+'5/$C#8ds%'J`LGbbd.r;7U<ȸUVjx;}[8&{KIo^  @x;1m#fwFa&I\`s3 s<[nM┚(s$Z]lUTQ__ZZZTbDn$u\+&G>zx6uC #n FMRUW4677qkρҿB?C?bFKѠvC=} ?|;MNx$i "DD=D:/xaBVut_M_Qbjv-uYt7,wEDnn/DӮQ,)|dZ<LWtA2FyEIUT wӌa4R$ ueUlt?~:V?DgA.&8Ө(șĘZ!dckP)(+?S:Io"LPm)|1I~ OU yswʠjp0cWC>?GqzZMr=-^Q\|~}g_ۗc4A h4#΂b LϘxrzrU痪.ڗW'קKuq}yq=Q I2SY#LPA00x8꾎_ФO 4㽂JޫhhY)Rfv<::I;-ݿԕn({RӼH{oS]w_-mh$֞ )viYo0Ӑlmt:Rjq/mefw%Qjlh0~ ݷNM}Wk AF%PyOCANkl`\Ӕ5"XF?{[8i mE63}Xљ whuȲ|wfPpO�KcJfYnf2=J4 e/c-̎ J'Ptwψ~;J$^0RU]Nt6a(`!LQ~^ *s4l2毤cTĹ/0aBVN2'& }5ϱU?>DpZz%ڣ8OG,ŭ&BNT?TW霜V-I^ )pj_"É3t%)#,TاhǶԿ?wOZ|t(cP(y-+1p -x; H$y@^fPoucf M3!@<hYH' >&+Oq@W ehPǺ feNƛń-T)}V7 0,9:\ h8rmO&b46Kni߀B︘ q]!nwBB ]~c}z'K.bvf.6xVD"h:㑥kCP} ŻvAL-(GzGXGLAPn7>|PͦuHAI|M]8#|fosrF;eX}I\P|T{~Xݱ7_Z:Iq0+$GS4b1ϪY݇h%.%F"䃡XZ3e)d?4y9+9@ yDjTS3GqCyɿZVX /pPgnbgonqcti8 KaU [qV`~7{Н ~B=PK@fA~f^tCV~<h)SP7Mi;d%@v*i5ɚʃo;'-؞ef4ͬ&)2|bp"FԬ"S/NRTKU֜78R@BY.b|PG%傧ސF gmZzFժrJ{~'Hc@l.NJ"THFBGc@ *0!C-c='5m༢QpZPXՙV'lj0r\!wc]31R¯R 5N[J@L1[=L`#0"! șZgeiڃ~&K_̒vO.+)ӆρ>BGN(pq*:GaATR $p:M/JK0K/N^gQmk9[V7 +ufbܱi׳SPߏxХwxcՀj]r &W|<5V[MUe&#tV]Mlj0: ]ep44!oѵ&*qBunЧt] U{ Odk它G\3ޒ5Sz"j7bKy|MB`ZBP^&.B[JbY)28Q"/`qv}F3nzJ#Jh IbK2FK¶=~RavnMD;EIٱzr:*Ʌκ@5TYeuF+~%Ado*̈́w<=SxJF, $]'1;P~Xec}tg:K@>"PYND} uQO7qJitezp``M8u9*@AW\Ƥ8q !O% q/lJVF*[yt@pKɬ TFY unPu 6cx b 3ʳ)Ń; H5*"h҅gU-z R'ϱ3^ƪ3,LG%dߨ0]1ںp` ߽Jh{7Rhq -Y!pN> b Dڎ~dSڵYu=|MĨ] K1h8حc@%ͥ!A+ZC(F!t2BN ,U_Kw /)5 zX/HG~G .t%ګ RJ薡L(3V߹=Y"Vz9)sG%qvٛm}E5e$H%5fh%V+QϦ[2ayKW_OS-H|0g%6Eϔ6bV 0o%Ɏ×QD.c.zGώ',+vGǮq~yEt +uKiyѽ7ԏ4-l&AE}5m69j u W\ k/Y7{'p}\w YҧyIJs2q'5-淔}q `*:\rQ B4т} 7*T^BkI .y䳧-Kur(c ݑ$f/]צ&e[j4,,'K)Ɏ˹2OLwf p%w ^[C.Ҟe$S; MPt@gܺ8 mUnJgVU |џݫ,ۡǭmyl^J\{gtJ[)C2*^X*.JU5+U -AJh<(Q&wF[ d X;fvP(BnQW=G-l)"6 e0 q~4㛩8<=ոv3cQ=GjhI:x?]%Ow i heWEOr&j!h.4J^ch =FnMxhّ (fx̹a lMP.Bs%)x[$~=#fGF.aYKKR5t 5+1))(%>$Ǫ4(5=$(>9?771/XJAKDe@ţ`zRStKStr" 99 IIm,L/Ғ  SSKZ5'~:7zMLWt%L9|WI0(51EG!%3=d36?ǒb[ԜĂҒ̜bbd|"HFcjyiFZEsm.ʢDqʓx'()2MV`ܼX6cfE4C-,7ibS.KIMKMQ3'1*lcdahx[+n=#fGF.6Լʂn3XKKR5t ?{D?BUMϣ5y>$;Dd9>U&!x=5o3`+DZP : %+5S|\ Ӹ8d}IN1% k\qIbQ 4xT xj^ HP6$ũ l\2y k[x=x[/n'"qY8 -18u2R ox+n=#fGFK=6hEx/n#B@Q~rjqnfF&I\`sm+d},xxVMlEK+Z $Mt.]q4IhZ vLFNm68iepԢ'NpT8 .HHH**qfiK;;}{~xݏ;=Yt6>6er$!5R ^a%2r9w,9LO'Gș33ɆK7 CG/D &g+ѡ,4=ӱSiw!uܘ,I:;Ũ8%|`ZL9Ү _샟^x&Og/|'aq6U%mavnj~!FF~;p!tT Gd?Jʃ;9nrթ|fZT=ʿXD֨y*ꖥ̻NeKR@X-hq]+#yzqmNܦN%*Fg1׶V^b+=&I0t%=7>sy@#MU}+n ;T1$<,ȁi-cA.nϿ=]YZnqH4M]iH\Ų~MrkDJ OmC/b4.11YnGY4!~' ' z'=FtW#4(ݡkJɧ'c~'↓}K2}}sPO=ٟ{:/,v xplvR0J=$=:~X_{1$eF"\vHX]kkXgO[EcԀ V+G8c۞0I2#H%sBZM+C5VK,4%0(o)4]DnC&*KLLڱgwu7@pUFJ` K}49X'1AH7SNoeGmd&TYFG).J1r,~r$w1n$GhA}SS{ ei,Df¨אƃƫŶHR%JAc;$`yMic`HxTMo@U*UԦjAJ-p*' MZ!~9ȲܸvXo Q".\8􌐐zG? pXiQ#>Dޝ7o޼ėl"y=HTFj6e3 Sm}X:gNM_jG\0t R~ree0O.I1;=)2&A&8n[NUz/uM6a l2,A@qqa!{ 55;s&ϭG6ϒ[ =t9?Eӹ*`lږsaTkJg+K1Q=JpZ[ x:Πv,)laMgw-p5+C$(̠/gbsz⍧GO[(7 V;ս gzBcuN>7q1.xhO/W!ق5I !*uG*]) *jC H+0¤iu0Ю1:S\Z\i3b[4OҁHXR:jib@NzXсc)b(ez=}ݹ~bߔF XΉ7г:-X$ZFCō3aR.k]#Z56}?,~L*B[:x{,Ln d/@2ovb[ խ-8}ZX2Y{62u"aD'p= ~bK"EJ5E1꟭e*Јƚy419GH">wwYd"`~0M#Y{.b,ĺC%"(Lb&" 1JKK5pGH0!O 1C@&F9R c,""0&1e!CUCYoDNיp": i\2&0:Fy "1 x^FHȪ!<*집g1~;Bֹw?Fq4&Y'dx|ud:gƊ5\\A.;Wӣ\\]^\o\#^(+<' gTi " lcP&}=E"X[tgxb=RG,bil{G" 2bE:5_zp(6;Vxwoozm]TiNخ6mWk.p2/&DHMQi&ΞWB'L{!Ý׆B [O{chZN|[+RO!t }JXvv͸ tDY 8 ?++BhGbH'q%sIjD JCneTs:ӹ< ͕;J4H@G~ F#jѪny}P+ҴqyPLm[9npzU4Lk8 qG]zaBE ]Z74/;ʱy^fF2=Esl|m0>E׊EJ4LCX`Y)tlW+gJטB떻93)IN9U2sjE,%ZyPa@k9wrSw6KJ٫df ޯcDjOB] Z4( Hֈv' m &v֬G_h.t0$ ?)3cbN 㰚=DѴ -MdrYd[ <<]G2c u2_%+JB# ќaj5Isw߹㷱>o7^6?؋ƳיѺ(Rv;Z |#CW&Te+i;Z"w3Ecm'N[ .GzYmV1>96~=_/:/<0-F<ݝI*z {"$jK. s^3]Mfr!MBfLϘ R,$bTn=VsDVvMiot fZK}v?sU3\a0D"1"=qMD4 Yh1}|*,nS0Rv&.MVw!^Dqem?Z<8 inٴ\6e߳׋6.][U&'ǜ!g{.<bjjO?O>8I߇KP\'%gE/hm8%Ŵ\h]4WBch2bS1c,H{@ ʛD b.te,pX3w/^4bbKl*G@O gV "qd7Nùn_v@69qod7*aH#Mĥ]6(Yu1XeUj}ƚarủB̟S^MGsxskb]'O`_rB x;nn=#fG7,<%E%5r{h*M^n,qq$fM(Í/ <(EAVAIir Bb^B^~BjnAI8]2SKt {jdIXdjN} .y70X?T+x;nn;gG~qRm&rJ($((TN)3Q%3=DGBMTͭEVl'"w~,#x;n|#ܪ8N+(1G @+PT'l5^rXC*0ov,nqx{jn#fGF9,g x{jn.f[6IK$&m~Iwn&xcn#fG߲)$ *xol#fGFa&I\`s6ۼ8'Ol qN$Z]lUTQ__ZZ3y''ԌPBpjQYjQ&؀=S0K0ҙ,'}<xnlI7csqj$<&JNUû (v8xSKo@VD[)0.NJi!Q Qp]{;nR*J@%+nr@Pq  y4)q3;3;oǾ~_lZj_Ib<)Cl=6Q`f ߞ(p8Rch"5~>2L=E+k}7FO2ޜ/I1Qž"fP|P V;B"@Jx`Q|9ǵg Ȃ(."{]dRhMUXHku'dXsJ  VXx g8a B~LHϜl5 WIժ:,?m\cEu!ĕ0rEBAbr<3ҲݟYz7a2FT)SBPvtG0KuQ'ė)KEGNfq XK1LOdzYwA3P:!Z$ԒҢJ$UBZv5?rtT3@ӁFf孵e+F$/,WqKC1mVMt?MI[Y]Ւ[ZҧHn&x;$}Hz#fMƙ<%1I?x;$=Mzb͛Y&_f]ax;$=Mz#fM*͛Y&_fw)x&NbyɦZ\: E)snq(.8)\Lio7x['Nb:#fMFVn%x['Vb`pIQjbBKfzjqfG, ~)x[+E|#B@Q~rjqnfF&I\` {8'qo>˕ilfx[+1Q|=L2Sx"Y|1#^dk&)\E$x}WcǑ_q_8a>{wOpa͆" ;^9:]f )OiN'tM'Rd{E=ٟzUrrI9גz_,}:xLR_ zp>^&z6O$-> *9Ny:<;ZIHы\k>yHE:̓v(689:g^vN@a. f|_=aLyH}ϓy+kDԵ.,u^d/vv^/9&[V}MET( >?ixz^zud 7d.l@j T$O0c%ß@'<`ɤmJ~q1^_$sH;eJrdQ=M@./P@ysQ:O/PlPsoK)51B&u/O~l%'(4.Y*u2'p|祟Ϩ$C kLpIt` 07up&umvZ/tPVC:[o:]c@8vOS/t*xpFKPjo>U?efd4aAyc6^,/R~s-|:?pr6ԉ\$XcpPNZ4P8һo.JCitw݉(^\?:{{o;oJ?׊Gv|{=*=Z҇MD}&qCz{I>CQZmeY:}D*E^MI87*4(M`U "gAȝ:X%@n na /5t݌+S>mN~M<i:z)^5!sn~Bi9^K~:. oqp7ާy:^huվWn~ɛZp|{[L룯 t> I ` D{#J ?]E\>5H `hDF"w7LN'&e%-Q-L"+ :p1.mS+Zi+Њc؂dJmJ`IZܭZe|)]Ɋ3ez6wl9ù-EPV:>PWnG+j9Moߺ=pMlV͜ec`PtoÁ+ (Gn= ih)Lim6u 䟉XWz(2KQd&fz"=} L "L), wC5L+|s0x4p@z17_ˇU $9i-`SgjN* q*0@ < #VVL RDN"G@wP @{a-Pہ@A]ӠQ# G [{[\X>|}CΕ -6\ Veؽd-l^;/t(#VnAX.'E2{56pd# 1٣UߺGY;7&Q0M9q=((D\a6jlP${NE.B͝TPp߆3WECb8o}|}!4f6f?OJܾpYpR[?֒|}Cbbz:C8|Ũ萓L0o>(.\a] 5@ eQO-1U" ^/XAV 2 .VɈ,Ю'ޞO9V6@HM4@r#>IA \0 HuW]6DSZ!d蜾<)\H:Q:BXlpBBJ@|ZTzjaC%QeOGӻ}w 'p0rK$.~Xe.ԩ ) C#gku<ZQ8;;a TIZ,[|?XՁ0[ ` G#V5֠1Oah` Yqqh/:WQa7yI+.\^ٷJ0З'@vwXu17W~z7{r+BN$VQq M U[?Y)|&|1-) v+[1Ҩ)'8h9[F%+9;k&ݨ2ϝT֤m3őQX_+oOFːjXt63"))׻o=~5=D:+I8\& I/trlAz |^Tlr,qnp!I"86 ēN ץ8$~i-q(CGjA}&>n/q>k=R"K4aA8@c!rsEX4I)'l0٘kY[ ``Kҝ0 M#)B;r"m1 rht⌭`Jj 8L 26|0> my}=7&[Xq I/5)׍tpb{hU&]V4%"̷(`\YY(- 5Z3\Za8[zLEI0K[c9S܀oP:ZKi vg0ǒ.$0א 8#)vg2Ju-,cu ; `$l)NAHC$m3 F.\#;5HCu-lc6Fz&)C无]CLz@_b`dbcNR1pu<iT wweQU|2(+:ܣsBQ75%ta9S*h,QNK5pcC`>m"/ICl"Q̙MMl\:צ# swo Hup 鼩hbKxC (=D?tvzǀ=#J+H*:LD۬b3atӋp VKMLzΦpPy6CL x[XI8ʁ"~5s:"݅KoI,A"7I%rc'Hq:-@vk;H@7 G̛dUbHlĐ❇1*ϒOrDlL_?!gBݛݫŠ ;2Ɏ!~M?zsz{AIsKI$[OhDAhSQ?U*2rH\餪 )Ϲӆa#Sl`)%3~L]ѤjT,l&j^Uٰa{](a.pXT4TolFU_a(q? sS%8r;;lEM"v 7Ѷ97&hB):qY0%8c|3Qfqx7Ayqg:?F#Kn`;-$Kvz{ UyFol硯Dݜe֑H=|>Ơx(~ ]A&V:bBY2@2b#q C"Ok"u=9q &-<>v NPi1&ncl^WIJ/`k>^TE;ݐq_Wt@Gɓ#|b2K]!IbaO"aih"<ɰպ6XnۯUl~]Z;bp:8&%]9d@.L!3*JIxƿ>fd3B:Und0@9֍a3,˯dW-6U?B?``- :d 9=\ s~@I4٤~0K:#+bo#0J05M$l{  $@wpmZ麈*q y¨vV"4#wG!zQj*+?D{s^B4l?z7 @É:62nF [ţ 2%e/4 K3sٰٯ.y]Tw6pN:k! vJzQB^d"_жOcA×єxw]A9`Fod y @z $u҆Y}Rvޢ/tif ul-YZ"hjH ]nG7"`EA@QȪ3k HUw.MS44bn W9A^'?bSoqA`,S.Mn1 D ǪKU&ӯB`Qf?ͪ1y ݿD 4^ xWb/ʔ[ %c0{?o͕@a!+A(aE_Tww8!MNcAmtَ:h5 ɏK" _sw!45YSu{jA _p.9p Ơ=wކ˯d8}ofnsN9Po9j{/ˉ͢G B`Č/LU(#[ZE!ө4/#{hv: JwubnuaZ)0l!JViyM<%6k[vg_.QU uBqg뻷5Uw5mgZ?>b{ wY< k\UjIH ^t"iaH]c1&'y F95"!!s<]+rI; |"oAGQ$$6p<kHHXћP NCS~re-A"zPnߔ@kJ xL֔(yT*l؋P@N QETA')rCDFԓ_>JLmSt?+7v/d3ͫ޶rob NtU[у%wU\tovlke VgtEܵwUx(4s08zJє)Kߖ{՛RY%xm0B\i,3ph\{fsg#@1=ֲЀ£c#{[ݱ9ГGB8fu|x_` *5+:^]eBQ;6U $x!̧&_Bd>36%X\H輠'@3P6V`7o:p=#l]B(md LK=)XӥD|w^n*U$s ;LH*j.*Y r(W+rݲ*;ESQՃ\NbB3#~"S#'U3Gt!=8qi5Ap)6l@YN >e jh_E- q4Wcix]]2pLc#BAS"UU 8nwvr&(l ҏ0GQM1buvR[ST-;ʡzf2-X\~uuh78:?EC5t|o\(Aoq#⬌s[x |t@jP7KIT I!Lt.AZL*iKP-j{xyVYLq).|suY^˔3ZvT#֚BtuQ];[][9V/g"h,׫ KSiw@Ȼ%&l\'oў-?iG"$05pFjH7J(ߒ^CwH$C\CO)hD-KX$BuL FkzVZ wГ0bL 0c fW9Fi+Bqb0HK$Lql&;8P)ЈmR*3EDqͤ|R˖pzNS`½n4ԟp ן[8I K94~hݑ!.Mu *5\l8pFM3#OR1WkvE͹!qȍ6Bꆑe/2}" ü4U I#f-bb"lͦ"ң&8;C (.NU;޸t_Nx1k{[KI aNjx+NAHcs<=wj H*I R(o`/:*2B!$!yZ5w(i7puF ZeCʲ_&Q OdtK[M6A_c|sS8D21y2YLŏE:AQcii[J4MP5n? YTF1#Jf$w yL׼G3sðŝtf G1ma&ZEzvX1NՕf?vɭ x&BZJT2%qQXjS:Ҝwjò&)"^yk$[ȅ}>tp7, Eb"_0TQV"Z 9g=J^i9sD_~ W[P PQz%h)|)4\xЗʯm:V41(A^vO"TS]k-WeibS1/8S4Z7rr|rtt1:F s%W}~ĝ\Ѡ eXl2BlD6Yc:0^-C[/3eۆ)c^[w4YDQb5{90zz0x:!+_UX~e$++T߾=$bcmZϣy&)T1,3,vNH MOYUa.T5_4gQF࠼s_|`8!Im+|ڄlTp Ф^fpn %i'PkUsؑz6d5U+NF&=d! q)=ؐ끓cBq*`X™J_C;}l wquNi1k d}|;ZPavVSbBU=].NxIIvMw:t<3sDE>NA{;j!Wٜ=Pib*iA{QK ;FDuS!Sj b6Hn*Ʋ1K5FEɛj.sI䂇ZZlM8D6%N,,_|]#GMUS_Q\.א9L5;<~diY`BLtXaql1lZx{{[Vwj\Lp/+@-ڨm~Ʉu#&Y7ؔ&8SF8ݱ) 4qg2]u[+kJNyGeyzH \RnHzտjtG01zr\A5U *Iq2t`ѼMP{1[eYws({wųGRa \9$G i爳 gȷ¸ƃ圥@ 9RCs/`ZAWӺUĸ[PB! EU2.0z 48AjȷHѦ-溍E:i xńv#zbA Ֆ`/(d&Jbh!6[ {J+3>mDU =mȃһ{^><;5`h$%*jêqLrD๬#Z}:q̚$ '1FN>|e|Jx8~EXe 'sKeje*Św+3Eގ@'Xy)g9s5ѐ c1C&>{_x=fSUOgZX^bÆ1D ڑlwܱ1Hn =ZǾsbP5dF=N!=\KIKc[1Ez)XW関VZ'1#E<fX<%UXk.Oݱj]Ff<"k*74!(9]& ]~n<]`"0k&y:?y?fBMX aMϣ緔9bl CE f".-íe .Y nC|gk9y2‹zӇbBحܥ1ujK*'l:9QW'BȊ~%%p;7]9}O/a8,VK|˯H^MpELƳ^o$YɈgH VK60=4quy!i/ +.5PJ><!`efYaS,;| *>65몺A[uS+,ؚCV/4"m<\& y:8)hK9}fpGd]˴"Rj|y6`Kp?V|W1KCgT)U@X05y bkNF/+R<_X 3[G PTw TKam'xs02aKQY^&_VEd3ܜBS X+nço#X7)BWyf>&G )m-F3׷+p׿J kB#旅/(gDy6hl=Sԝ@<&>]N˶#0n2b[W HH@4rxDK6^B lp3QI G۷0 q:ױFq']bpmaG.L&SfM$܀$)VԂ욭 &#- 1)*YjˠT+]ukQ*o\ӛU]C֌bԎt9)'3˳$cp`z'ђw O5e ]"[rZQ[$:EC[j%"TɦtIIbg+6OC ~X{h8@&{-*$ l_+vd1%š:d*nRe[yY'/`x, ܑͿMΖw1lyA#-џ,Qvˉh96r0SɽUk9>Q7SF]ϧP0{<AHeI8}ߚE]|i*ѧ[_:%~ڞQ{Fm:7܋dpQ  =|ȏ2z?rֈ{wHql7xcAe_K#1">nN#+U;`pz0~D:qe!\ sn[r0%8sBV%妬̄6+Y8H;?;}B`Bz!D5B@&#&!zovp٫1Kl 7Ur4 З}([YѱMι_Nw\G~"=}w2 AtL94:xU;#1qW?&`dYVUT^l'*}E]ίPvp@AerG5^][  /<EFHH\ΑEuOh"I˽NR~,qځ댗"- $TmGBA@t$"cNBA_=d(. ղc-zv/2{1l:mX֒9.lPOoAšVZ:,)ScN%UD ##FW̊>zeL|%(s%|w`-nheymߥ|)%CGD\)@) !,$įR"[nQ,RS/ oyA]]AuK+ځZR!tA`z5 107W>/Ŋb/9i1t#ݬ A[Os]9 څSyjtqtͫ3IA\du< JHK56P S ,AD?xP00)AkP>#rAZQ<~Bf*<ݵM?qʡV/4҃`& F  C^.7aM$PNsczqT/HgYF4)Ij^`nWA.gݻA52gIs^z6X(Bba%"'6Ce63%Vi+4JzHJ#ZFxN.>9Z^y9NDD?9Ŋ +V\ ή,Ļc GDl ,=2RG[2`-I;8"G\*~"`u!0m4~Bf!;]KQP&vN)J¡yl-!)yYmp|xXuܡzQ`ӣu#G?K7Z+3M5ˢ[&!ԅhz*T/6Ab$|:a%$pVۑ`ý~g³4H z"tF8a 풌}&t U# zhrg yܲO{Ǹ$npSb a! rtAH(ur"mn[l@AP1vC3(Wn8 |;7Տ8Ro',DD²%0hH2BX$Ե͒HM BJdsYҨ*gnՑ*#~In ^#A K}ńi=:)=VEqjVTŗ=/#I6F7 8F)Z{xrs#ΦCc"iCuMJ_=Cvy9wlTJȃ{`Ya$uBkIO!:W8Qp9ox8_RF V?Czi dsr{Qڴ]x!qhtagGGFP=VQhwЧ>*˰ {)m>0% I!p>Gd\{ Dyѯېo/vtNZWؙl $ ᠣJXF 8dB>[>#6Y!Kr.Fh 2㬛SJX/EY&hpG[ %mF kد :aDh3X=ͣ3yC&l]mZdyi(Dgzj鈳;2U:-&ڽ hSsKTB,ʽW_<8h9+M;]@f>'# lg(0t+)vPg9$7OaBX\1E\1vt|5ɫrJk6őa@S.p u,I zL{hdQg!5,%?`h󴅆a2A ɌX雄r)Kؽ6R˪V7@aO3@ "80ז 3 ԫp`dgUt=C%Z=ɬw@ ^lX DS~HV YY=<3_aO@ Uy0~ ;Vfŕ^]BK2gOjT[C:T4.>ApӍdxBctg+y/)( l J>|ptƹ"#)!-8n,Jwtαzn&tԇ ZiAMMYGv ~KD]pL{.^@H^^1Ww;~g}98ën&Kuξo"PSrJg4L$1說QHcyk(Q:گObuei ]nƔSQCNi4(Ņv@cv bW8wd'\g8yq6z"&h!p-bVL4Ko{#աe! pe1ΠMTE'w Ӹ#Oia<`b<ās,4Һeմ ~>)?Pz{!T 0эZ0ñJ!Qr|t hQ~0b2[ 3:"è>w\kjƍQnpf֏oȀ߾>/>avK7x"&ojShPhNH:LDIN%X/uaO@qܣ@s R#ñ2a$X hn:+sw*usHk0Wu󍊎}wEoz]rDknkurg&O9ɡx뽃?moK!$]$<`C rM *17rSI2j"X/镕 GcUPER޳7J9Kx(Bȝ"i8,H(EWړs @̥,>Qy!J_IWJ`)+>?nWk4+N^wzцZ lxxz$g8]2ί5]x+ z77iD?Ѵ:GSBA8bu;ꌻ6f0 UNN! )^o#}FM#Sa+NOpK!H:e 6`qvym69ixfe3iq鵍'✦Ę"jR^]YBJY{\>b*FXaJ>$C!*:F*I[TJ8X8c\#H I74IM>Q'L=znqpN؛^q/1bV_mEiƂ/<.0\%7܄\rpms&5K7~Dxe9gbDm,Ca{)KnEv@A[neUPxOfVjƨRlV#ӗ+`%W bbq(<(̷0A=wBWAv dU칓%WhXTkS_TpQpT4ԙYCh(4W _zdl{*c}CRľ(Бv\]YQ=w$@p x Ff=Zq .x O`/>Úi ;N.|8N͋'ONZ$1y}.=@\r&iN-=9*Or[ y{ K%**(de^.'m~gˬ`5yd;'Lcwޑ g@70xuR_kPg aNdPl4)1 ;Ruޜ&Yoo"q(~?O&MK^=sO~m̰7:YXnՍOt} 4ӧp ([GCӢڥC#7D| V,jq i5&ߪx܄c *.H>EQ?.z- Q-)̢:azm[XK}Mt9) ^c>29_ bC|_ Yˁs2$ c8Lceup$JZ; xdmɸìLRFKlhRn!/+b3 KҞ#:;?8C_D>6}[m"ל&Ϻ(0- ,L@E" N.;yuW6VE'+\HLN-YPZWY )-18&3y5)>[j'n5] ' la\v>yX:/Ȩ؅*M\m8w>ɛ\[c @,6~)cIIQsӖqgKYbqw'W*zuX7"]q?ҭ8xUmlSUmAvc`g d8&l 1][{ YjPb +YC?7 T$$0 &"5sm19wFV"'|Vz|^׬9a- hJb^U6 ] g+^z:>ky=}cĂGc%[82_N*\c݀oi:ӯYjbu]Z`oӫq:2Wԑ ~K2^R3S+M6R㳑jg[mh`]uM+ =ev_6>pǁY0 Npv_6ô'-+49lqyk1 -OŎb(=R:wtVD8NיhYkq54xgw6\28.iU9u[fɖw{OI^^!B >ڤMY[ <>;Pp5<*Vr|6)z6>"+:HUתD 96:_ }jJB,YY8''9at=*xm2WqD:&-zO2(XBOaa1 \ӡA*;\͊ވaj2{qs<KOItxlk%~r Z^RKfgs<^0-n'"ÏՃzD]gV`{nR.bW(Mfz͂#HݙD'תkc&eU80j:4LYY c q.ܵ8ܔǪ)2de1/ޮʥK2*5ISu|WܳąJaUe?fyʰ>aE_0D*{<1MGy8Nm6L1JOz8 縷R~$3201h~pB4F+P[Gml"Up܍#ͱtA6r0bWJ,*DzH}:cR: ?r(o;/_x ْ2*7o akpqB S9BR+Jb5u&mT{/ `x9{0&B])}), ( Q_P Xpi%f%`&H``a  nai& J`&[{"xmlns", ?NS_SESSION}], []} |%], O['v ;. u8ZWyRIZ (Vf  I Ux6Hˆc,IeEyiŹ?aer&_,. ɯ=9co8ρ$ROv~f3,Jt'ߘ-19cs༣!O9d]pDHx1Ď4096F]#`&g e8`i @h8ТtdxVx_Ď4096~ andalso (not StartTLSRequired)I#`&g e8`i @h/  Тtd|.$nxr &.2Ydu6WY Lsg+,)JqG1\_&8@~OV)|]bku\VLf\uN1;B8P\lS|+SG[b5dNB XDը쬇_P,2v+RJ-̇tn7 i_ 64Ы¯vkOK@؄jmhY vܵ%ZTБvY W($|WaQ`KJm$l<ɑ3 8̫q+J±5 _5f;Uә[ Jf%E)jif5} پa[?poՊhy&L|HgG`)W'F֥R\> haCjlA f #l66hgva:p$:殺x&(^M+c 3^PAS4`fҰyNڻ \7gB4b:gLg izN-\deoǾZ)D_B27X$0y9?'`ў(f?|d,ˍZ͚+v\Q H8وO\" jx41W{-?XB/_q΅ł J/BL(ov<"{e|#އr&dpcLͧ;ci0<.aQ!MiD2viLٍd_+<)po*qbHowF֝}wK9"ky} (y22-qѠw|>de{}ZiDl~UBvW뒄Ej*pZ= iO13dHXj{Guka5Ca.Mu9$?oFü+(5{HxTa弇j֯l8$ɮ:ѽ 8dvdpؠ+ې1ek8?VпBH!JVx7ȗl5ñVewz2;)1Qfbww~'(JYn/).)VTVkP?yT9( Eo,y~I?˱^˳;A%~4p{g4Y0GGUxs>BDy}^fTW 9G+z4S[mh{NSnDY %U8r;NpXuih7?NڮST_V.[cT_JZǾiC4Be|= Cn`j =.+TR%UGzTc[uJhLKωK022$H[fjOI Jܜ)`F>l&IJ#hT!#AB* XQ ])bE$QjyGn:TaIՖdf|%:Jv$FBڰBO D\Ѧdbsm8DP4ΰ?Ѯw#}I؇!#~q9%^v'rVѲ`9N CG}0,%T'; !ٌg [˚&۶i@䜆5R!"Ep~)_{4jPqKT 5d"ڸnW8#mѦ aB^ǂ~hkG!FL _ Hi(r7{5ոjcEkXiv^/ ³-Ȇ G'`ӲDЯזˢ`˒pbk"p\%dBMYq"+hpܒYE%ޮbKHxے(DaΈxHlti7-vDĶ/ڏR4\Lb *#6G5- AM:״($ro3xDKo?7FP_av(0ALb D~܇Dܟ 6߮U"мYe\ظlt 5Gc\PIY m1]|m;(G֧ì7`+Gr~úTqEN@aLUHPS4ֹan>_&ij!Np~W1^] E{v #{`$Oл5(l JYc%'cv766XK8Oh;XG?3`ǵIlP7;U~N)[Z897 mx} zWO),&N4-'yP 8gPtFPIH7dp HCEH?q q}B.nɆcK4yhG^t*ĘNcA^t;B4,$3Vp*v'3jxh, ҥeHy u ̪ w n:^\ȹpxy(8W"4j8(H/JntTOnqc 34Z&7`W.)M7i~DW1|7KWyMc( >_)r'.爀'sh@xjFn,?[ǢbrUjD~jH>MY} s9Bэ/Sejopu0>*ϔF2> aO/$_reqkPxg4&ø3&MJiFDctbΉ~ė l 2蒅x3˫~qX[, 3:8V2\Il=#7)7y54ŷo^^Vbՙo&3y&NJ؅ꊁx@=8\9q/5C_Sia%|L UU2"=ٗNgHc84:lE-_+هUZGF M0|ֻķbc|b 19̗[FXvy63_n29,h`\G jnp7skϕÓB4࡫6 {żcdQEx$̅)  o;}1➎2{\'~t*u*54ٟkj%r P/ @^0G wnئ~@?n~-0;MA)W-X#S#(jr$EݲXxx2V`~z Mil:;AlO!|L;24|zRTZH :7D 3EZkEW0,Mk %RnIl_Ҽ]1V_} .̜z%s'T9lt~ |ވ87ABƣ/^y9"=$sANӕ#<`_n&> _ \6o} l,,y RYx2{߄/~f!邻qńҬIQ.yy7mB?#wo"EeR0\S OڌV:WX?Z3F'TM=tģQl4 !|G4҅Vs@`bDlvj" }k]:ᗵJw.N|@ 1xVoU϶eXhn. ۥ [+mAL G;;̶M)1!1BLhBbMј_4QjcB$D`sgv&;sw~srI\^Su;v-!H졆J--m=i CēqmUbZaIjNhhn{CĤ"Ytb 4O5|sU'벲Yy"CCYW߂;դy)&BnZfdӜ ɩ5M;fFwccԈ|Ac,xϻ &]ĠDa*:E$j٭MjN!C6$Pp[u%?=~B9}wh/>:XRI!V=>xk͕rΔS>ZU%`1{¡(9|m-? tFn%Ĵw8Il=TT"dcw83SsohckOs~X'lt,lzMt}7-5Xw\dVN^HR#*körKuSx5څ_ >_Zޮ@wG"jI) ؙrBsjZXmRI 2#!д ooqPt99FÕ%)m{jkI4RY!.jb2!x4Ԑ hQ䖅YUk6 \Ip1tp5 `Mr`!N|WmEą&"j,:Gȑ!y籝\e2$SHFtI获c4e$KsȸKQήGYY1(^Rby 8O΢@48xUe)ʗM;KŞ{Fw7A|yHx. چD&Dᝳ4E֋$%BQB^0()d 40ir_6.TΝݘP\N~$·ͻ\.IËd"+KY:r#l#^<#ɻsijNY?"8?0 JjweK$TL.T;Ɇ$H^RY(T̨\g]pYU) sa _ͰPYnSv; nktQGiU<'HO]R57Xw߱~w(s'Fu {l`鬬 LwN6(jʍKY0WdG;X=1Kgz{M= /#SyՐknֶnrϭ5ܰ8h\46&mvG8@JDW¬{{E^()ᡊo{BDD@s=Tݤ+Rt⣓8(l>Qn¥& xuPM/ANPA|D"v}D6!ihCOLۗ\0G?AwW'Wd;<<<|31iYc6Ai 9+sfɇj{֦M=V3 80*8#t>XoFmǭfPvs j u%~ԣs}KJxsp+k%@(L) 2x;xY LmY&'HpoΧZb`řũ!>yI9) v\DդA%E NN.ԼzD&oEUdr2V! (ɩ0YOL SLH))dCT_PR P\R7,/<>3EC*Z\d#Xf1YE|ē&,(ё|e6ny fVTwxp) /6K2pqr&m+4Y\&zs(&;8Mު$zB#=VZ=dR;1Yu|7&Nyydˠ; 86;n`Ҳ>y?deɿ)Td)ғIp$$$ZÔedՁ8' FJhBL8QlQgAQ~rjqq|PKbre|fбѹ< FL$6 (\ZZ__ZN-*K-tI0S9nMl~r6Sinn^iY V6e|xTko; bPBTPUݢ"%x*"dvgY^{e{Iin{^"7*mW{Ι3Z#OVA z.u:f)U VaaS510Leڿ|ȵИؒh{ظй2H~!#˕4y.-j;*eS;QZ?<4Sq!Ff1&zPn͋}SFUjk8NR7Kb^iw QgQDLƘk=ē;,dL@dT|JKK#JRԤ$ }t13u{ר 'J'f)]gAؠ7 H=uRC1JB0"d _ϣ | 'p85uK.%1PnI<0`vf 0'Ao~N`2)E om:  Ȣޤ"*Di0R$ e& ) rχ2YI/b? r1iaq{) E&o<W2]ғ0 !U^PH4oE j۱v[:Z^{>={G'%['Χ։8tr|t^" e 6J3)BYKr_90Cq\Ilu_FW/}pûq yd"$-::EVǗ{(8!N'덆E4Ao\|锛難gVޓXzFjYOb̃Rs-JlUތӬ" ?sݡ^пQ Hkk^_d(~b$ k"gcֲ!z(zϿ(F1Kۍ:8%uur6ɤ\˂^,7($OB~E@Ujvbɵ쭛XB16]r%ucӯAF≬(ZD2k q6O4! W ;U^<x E㠍mz؝zCP9iďI;! 4KYMf wA!676k(S1m9tIh!l&z&RCY聅 lGP -n:-Զ}A.-Q"Ȇy]`%2EOL.VߋS!NsL4(Qo|zimONNӟD^M"X6şc?5p[,K,ڳB| ^F]< *!7IMQ*0 qw 2+M6ꎆʼEl~T`|S93bR68m탣OmOU)y^҆ q_ ~hNLaD|a<)G!l9X+ҏFPzzn% uaf !P0a:ʛCY%CX|xD/ҸMA"|`O[Hg ήM3vS-6_˗6&y ~꥽xfÚFl7(*X8u`ԡ}x8*Ƽw#(YyQnf']Abf) QQ"PZ"=[9sq3nrwx!ζ]Da(Z帍/Ɵhb.>nUG2#TBFK8UHQ9o3P%cLm%\ cyJ3Pyܙ$B(lyϙb3!nA{ӲDS0"5j4_m,)?4~HSMHu]xppzSg+@ERkPlgh(Gg^3\Έ #&1ePx#g hŸd l>mN{hT^${v}@n:<`̤քc|H@7s}?@{J˚i&G5D]O;7 yhOiprg"%}"E箮JzA;#7]VCN=C Ujt"̂'}ҿQr(MSL/ၴ]l}터p*3)kE3BGW+ ٌ;;Z΀STa((.bS;$.BR{0(B$)fU *jXP-uYilG-i <~[W-=q-ttt 6Exo`JT(NFiBNrDiaG[q  u]WaVyu( !eoVțbCg4n=F0aZjsm -倿pr#˽5}.m'hKa܈X4E/AӃ({Y@6|,Na1?Y͗93݃cF>팆ޅh{^ǹƁ@vS8\t۽:=V/ocBcC8lOS%N&7 E =FZάxwnimSh@b<ʲ'#P&\Rinִ7O 51.F[gvZKX_KU>\AH;LUs$Tԍ%A4uhShLC9"8۱e0.x`yW NThs2 b҂2 gJ.{tbFC:Y.#qw'*=S Pi~z 4Wv4 AOVg >3 ZHxXJ ->鲝XI&`$`!ۑKuuʎdɲߴl%XZ8^_Ҽ`5 GEWURfaVhZ-SVӽ :33[ ,oo(̑y1U~֋ Բ$-u53Hy'Q3a"vI֌BCcb OyAJ1< FW)qH^ J{ت>SpݶZ B).+gS($,Y1@WFW~*_̃jˇB.uUyWO( \NixewQ1oPQv©pYP`3NЗAqz TR0>΢t6X52H>bRGh|i_@=Uhff!8M/xQ^LZQ&a_ڣp3Kt(ŗ P^XZA^>r+Tin 9XŒ5BRD \ˠF,aDhrW^tP?l<,ca)9 qF9և50JT ׄNz3jZt#^ -s Z`:PA}D !2<Ld8KŘS,ARJ/ܜ]?_st~߾.wjʓ=G6MPK.Z'*-|"0N6m{D BE[͉sV8֐~K0(-F j;9u6TMO*э!24Ҫ3R1F[5(r;_3X.zl;C8 O qQѥj P؍̫NP+hXj+ IBog~{~lo~ƿ`` :7Qȟuʼn4l0Vy(6hGcYY=x`9 yk#5I<h@e~Ӫ=&&ѝ,2w8R6FlvA0/rܴJppO!Mj w|Ig d .TAϸ.KU"4ARİNo[OQ!_4J(<V8dd9TU- KU"?zRTvka렽HFi{`I!Kh}tgf@NF1GtɾYҠ݊c;1C+ƈAhlo:,vs(1.D8WѸ7f#I]FSԉ3Azz>H P`9Rq^ۘQ>$j g R3ZAA!}O[_hvw tV0Z.oyo By6r_o@'[H`QN-pO@Ccocä6y$ɭ6FHWi}̏(bh6}`sB.XV*Ԯ4'!ǴK]$8+y mS^Žu/_tsD ʵnQ:hCvFމ| EEep@(' tQP=ߤٞ f;=+crip5&م.eܛH02#;UYy<+XnDXR=hxVc}4o¿[D|LI%>5ޝ]7p]/+^gv;\}y/vR4׈%h?\^d[A2E4"Jݓj+;- 68JCĀ-6 =!޽{\d`W*@DK@(¥[\uFc;0VwA@OC+d3NdIsA/ёl#JC/^UeΒ5mӧDu"8 QB}y.To5TX<tgMq{C"YYuOZRjA}wV^: ,֗2jecKOM.T_-AY_MKc1q {Zh;nR"DsV% "p3-ԼQ.P5gn0w&rg>{sϢ}CLr? un٩qRD `,\2/ЯF`=6zרӑU0QUْ4bgZ=Rl>}{ T F5؝B=7Wh+U <(RxmQkAetuzشZ֎$,ncDh\-lBճH&;evJ-!oC=0x,B^͋"t7>@_DhAо*p O[⋼Teyen!6t_ON6tRcT'U֊4ݶ :A W҂7 <ˬdȪsUk12`L1F2,CP1@f᭺GMыn vAVkW˳ Qu$} uoO+*+XB^zیzm )Akyiۖu\6Fz\oPj{4v-!ـ=QǎHlm+Ɖow"odK<1X4lӳ)K"rNĂDm &)2)(lQcR9Wy!d5.Nɫ7w踱s;yx:;od\l)xڝAL)tV!7os$xz+y#f#LJJj]fUMN,NUHO-/(OKMTOTRRеSHK)N@m[\-xWNHMb+‘N m!@Bƞ=lF=چFj7̲):~t:Dsڨ'-\iJ`CLUTŧ\i ڏNй2Hj=6W[He3yYha@!'(,$p ۛtNէSB˹d-g8ΰVϥ2|E iD0jfoX"X崰27J; l,F v`Q̽|>:Ϙ heJg"fN r^J/@e@IQvy3SZ kP9+6$Z2PcshrB5'F& L " 1tkw8vHDxޖLDi¦Ef{_H?A|?pNN'ǣ6"3* fV86(\Obk$D(qA^gE$*tA 8Al7Zzx_uCgQ;_1R NQG[xv3]e,KNys{kkvUR/iEriiJcBekUbZVs 3EPYˈzjMkuC+E 1џLc+)>^RU߄8N-\ Rk];`5՝ 2p3,̈́& azop2}~N1R `|#t[L%a:5Z<ڨ҈1|Ew`\h]$ f1NmaܶyPdF4~2ڬm:3 fEV lDRC;;Ts0_1ֹ4VSN;DB?<СCU &n, &U&XRGtJXC LȃD˦/_op7t a}`{p-?l޸~:rS[E찹!Ooѩ,pԠ2GH$ցC I"n)KWC[A'S!Y#F0oVaJ0Ew̅㊣ n9p/*G[Ԅ10'M. fK 3d#e+`4],bķJaxov#`4 5oݕu˲ Rӗ犚*E)/TGڴOpex9O-oPU= *  element(1,  Wp gax#Df #fWFaͅz7t3jqn^x["Df #fW<$5x[kSHl~E.)73.!` QT+soޔg'b1H7G>|oY{{f/Q1$25Y}Q\2gt*WV^Y9-*o<9׮8ї;Oj?ꧏ<;H@]SLvMz3n;H+dY齫*)sw](]iU.t(I1NϮp} j_N* ?~~s_&;fȽNG>~JHL 4"UIsS/G_V= @`NRSn.ޝ:hD4.)Qyf;nVY֕}8r_G=jx^iiBVhL"7{;ÞGQWGo޿w;|x=8t޽9 Z*wh &EIU8"aO?^:%wF+ʱIV"+V7.ܥg./ꮻ*SN]9]z]ݑ;Ȓ3Rxq׽,Ȼ@6?~ɓ'^ >s)-(p\$0p)-l.D3z$qy2{0<4|61D]} GIORψE<"K_2I|6F^%xA $?a,f,I8J+ݮI ղ\'kM-Zҟ< *ۖxR&#xN.|Zio;rJ?C% OȳkLh1 Sڲz?G0psljGuQV݆A1y"{4'p$B9"ge& `O >†"??u1j DI$hԇ|#?|AApN8ۢErQ]#jJj(՜~Df/J`yYU;hlt!R ;D L̟2FY0s]wľ.@,ݩJR78D3rB>ɮjyO#?gRh+9L9.$]y4p@C2b9#.M#$2w@]d:el'NcCE[pDPM6:j?1T$w)eĤi9481!bPwQG“Pbsj2f(Q'48%LAՄV ѹ]_gLBUUDqEFJ5(Z`)-@Ƕv67 2UXϡ6xB7?Ynf71r ?P%]TL;rwPE5>%#NYOkٔ5@˩vBM ~H +c}nIXP%}jʩ>zm2ZQʎR\QEE[P+aJs,絈lgeOB)%R77T3`!+N!'D1@-?XnD+q`DP&AɄAi S*=DBLLfk=7P.&̄&,a[ DrgV(2$fOP%)̨p8FY&|繛`2F!ԋԴLÃ0"v$+E۔ŘKFL|0P6Dv;stHN5ă{%A8.P`ٔQLDᇌt!::U0L@.{\ XlhSK:K>^-4pjn9 |"ŴCs;E(jNdHm" F1z0!wvۮh-Q/,ئ͍J[ZT6j3!v閎]!状0 ъ%– [~UEla쬂S4wnLj›uv8Vp9AɄ$Fa<8.Uuǜ("PC#0KuKe[a G0l^к0['1`OķؼJxU*Л *p^00Y2Ygǜc&zg'_w^~cזDI =}Ke[N6X ~_p܇u]aoZDm{KՎqPaq; cvUPi5::4UeIըߏC?m:gb7C4鋎Q|${kT@ĩYM.y+.6~x+^68 i)ّO|4ܸT_9;|ms>v>яN木T͒bҸ@FJs8Y0^ 9\P@il,L6ًFs7zL$ب:jۢ4-Hb&O18>~@T*वVBC>Sh,ێ9DUt E=h#"iV wj<u{TfixX"^??U%lb-qnn5w5y+̅@mvX(5X/JdPԟ~9_Ip6r+vD&>hOGO0w4ψ7چm7ƦNѰ]"^C$mh筁-2O|Fc!3~ iahiKWV-D>n.ڃ%Ĵ՜F 3Ǐ A,8SZFHsc8.DOt5.ƥ_0G "!F6\v^WemnKe`}L?B\QQ-坄&.ܳzS `GS)f[Ur(5%e"y5 rsc^fΊ%LlN$XszDg ѧ p_Ea8넚T@!,$B"@ް.in`GBUiL/LqdQ=C:/ϼ8v_%5kZd?ְf]4qt͟RǨ1(o =NcC>aP2S< +*\ޏW o">i5X"WGT0Iůuoׅ(14Bɡn{8B8|jj< \13^M_R7eױ ҆3c LY^{"$ ݭU|I m@t^g/%!V{8?)g93]U(BC~8Pϩ* |Rb(xҨRc26./-}g-,e+sǴ۶9r^ _3 ג̂bQ½dcgpm0=x{P|x#fk D'M~lXXZ9ȅQ /?>ȉ/(/LIM|5^bNBZs%g&g'&'k8)Ilb)$lx{P[D{qmI>*onx;_|x1#f/Wn)x;_|x1#f/vUxUk9;Cuj;҄ۤIkHc)!;U1&wV;rA ݑ͛7?n~˯nC,h.fgjsхa? Lѹ[nZ:Xz\ZDpfL`[< t4\X-5G[:0u< jd2G 5+f1,3@I:za `"jBGx&olرKwk|`jRBkJynR@.+$ |en;N8;~mƒFIʕB n.'=];j/g3B t.&vvy 0#XrR9Jc B*J숡*`-J| ~rb+ѫ+ٷ%hZIM _F:?NgȐB(cNN N& `0 N`> &6Z=RآL߹)K%1b+iѠr2{43"esnO* rSSEY~GKKW߿2? ']ޔ.w,ڵȖ]Q+&WM<9> zf R0MgrnЀ\<ǍvDCC{[Qgas 9l@Ɵ c ]Q:JHqE'ão4xb#mAhN2[`i'Z5v40!!o yX^ĖؔSjBw *aIƎS-&VORqjP0Ge/>W:/]ISU$>WٌV%wM[AԱI$aU :o$QZ }9OzQ;L~ ~P$Z$0JKCwz1t眤i s= /nCN5q9&.i]0n(uᖾ=ɓ b_y\Ҁ0/:Ou=.$Q¼(ςMJ-cQ=<6(Ee6 @UMEi:Ɏ&Q |6(*4VڤtdD@֏]i8ć%v:LźaR-Re9qzNxf0mޟo٨*2ߺ`_DLkiTVKŒ| Kk֯h_3CvZiu/E|UFXIxhVБK聡IT}AAn]s(&شHV>G%O#ke;%I6PlÐS(N V ?eD6sü=\()U4BNU4C ^[d,=unL>v\)xdWVlv`\wZ '!d[~3St,= sZ:Jpp< s2b1nj0nR⺒rkҕQcd Ϡ:ϑ g/hsG/gqqҍHc%12r_f8 @*t&A`06W} XϡDH,9wVg)Y;bg*k -hK!Z~cR I!$UE%̬!\#KEh̗V'@3pj&fbJL0A+S`qه8E _ ?Ω$t`ݠUbogwCqp*(|ґ'-Q4ARʻ݇B0p%3(M?va_lH-~9=WIVCow2Zv\ In;004^CFTkش٧ &M9wE0bf=QHyqjoYYs$I 3 5F\1#kTs]S$WWTWDgQ./!ؗP1XR)LSW47{?ݖ??#ƙɾ`IJAve`x0\Y(c*2vU@1$OI+FA+.J=E ǼhPCMK%* aejTyt;Ѭ".uX3: J/sTԱ?'i'Ј }JZ鼉 S Gq;iҠ!=ޜhYqK' (Ku{:R2-|#NƇ 9صXZ* g~4 hH5ih"үA@&c|*cWW3[l.#ɸ2Kս&n@Oq4b[[(=s'f~M"hfiC#heFMY҇yJuBj%@Y`TMDK ,1YE濻;5 R m;1 ?R`jvtWjS`V'O42 n)(?cdwX],~ƖPs0ϩ/eS*X}ZЯXGU7җTTewumyb{v(OR P2*NFTx&z8^Ǩ_a8?S2*>\V>dLV$wbJp E,k5 Ќwg ̜%aQ*!.|J~jhm猪ޠF"|XZLNz rLmJ)`٬-G3vDr`thG ԡxhU̡r_ vJFXITb@M= W9&gq6o)9sg&Hc2/VQNEZ+{8hVT`n(S*ed=чV-DQ"g"sl~8_AȎ`F]h1eZPNMN:C#q*` q^o<2,z#6CZ`QR< *#j??Vw'9a5倊ZtD@f5z:zEn$#cLGC7tcZ,ݎW9A5y(T1*=4iFP+fŶjRD|i8+Q+}N@+PDj Pipq3or4gWa4)ص'βfl+-p»5r}/iλt ?QV)S]kҠ6&i0-(a5-1INAnK,n} /iϹkDނl.a[2 o <헱CjuHjEDXJx.nm-HOs&H6 .ըjQo:U 1uWq\jZv:r'^D7oĸ]ٴ4, FA Uֺ#S?f/FasdyoԨ< ^4Fj} ,X>"yk`PQN+d dKc:.'yJL(ZA]/[Kx\}:9j${+¢p^_ EʸP>Fg=) `t1TO5u+o2,EXQ=O2,pV~w0ި3܆I~r4y6.4ƶ#LNl+u䃙KbfK y Y5?Ƒ T5r\_[Y c) w cbG[Dp hTmә0; /]k!8 (dÿI~_x$WƸu;pE<6CMm0N疉SEaؕ~B\OEѕgϖ&fzeH^XGEy޷B%RqO!ӞI٪RtJղ1R\eSB* Bx.Ӏ~&RN#NcM 712˙9[쌧8.#6KC*$t}[,9_[Ko\gVF͚'zQ(y5GSDbnް5TRdb]\uU.f(*ӳ4]HzAmvz@[y}5Ɛ;baYےhG$,бE$z|S+l8$nAcdnC%9?8UK yr/k +^̑XybYb .3aBXu:N̏,D R UE$qX{(oGKrѦ-Yx?}SOyj~nt_ճWo he/Kt3-Z65tTԋ6}ό0D+r@.odBn"k Onpb9H$22Ai J%Fq]\ϮN,y{ ltZZյv7q(x[6FFͦR St"WGKS77Qzeb8UVkrlc[7-~HAe:2L gnmCg桔s.*Q :iLI[)xT.tJ]Mɸג?<7|Kfˤ ̪_y?˞fΕN~/|Sx'Z"fejX[D[(y{(Y$V(l*< 6U!an,1о_d$oh2 ?S!Kkwn¹ nkaQ2m(U7`Puc#p$b8z6y`RЈm #TSˀ0;j/dلiSZ X#.b^p$ @[g9wYޱIøP^|q[W"e;&7р|!]*@3Oc#qGh<*GjۖV\)|!eڃjvXL_[=F+/Tw#ɂiti }"\Xa[H7Of"u/nlZab9X\AIhd\_M+xw #fSFa&I\`i6&0N~ũĩ0KTS4/%5-3/5EAN(neǩS  q wstp $d Լ.8k,WN~bJ|ZfN,&$4nӭd0DǖbixT&.Xamң⟊+}JǮQU&0rҁ]txp2[( \Ƕ?B g:FR4rK, agFJZt@Ęi{`zqW2|7BfM XN;ݼD"GX{F%u‹;lZI X:E] kרni ,Vu_Lc}ƆQK(]jR*Ă@? 豧|վY XH S =9rmq=GǀdO QE~]BXزJxI$NhmN~8Z\1X"5}foi?FJDq?śOK+F4oxf&/xx}tŁ:baۛ=סAx}<, +Z,qtq&;n6$~PA=M`JX[=qX0φ=*1~XMUǭq6# ?x+4IxBrva4TFl cx+YpͯX|7ײe!1,NaV ) *x,cZtJĜZM=.]tN~rbN<E%%@b[X.NΌb$^~YjQQfJj<@mZbNq*TzN~XS*19&B`$x,8cǐPgg`M=.ݔԴ̼T kP!\h+HS%((i SbwxmPMK0>K:c"M$SI&U~D򍝬 s|>'v>Y2.PjQ$;f:2 bSZz(7x!,&á^|d{XM1p]J@:k?5tִ烓m Rͅa ZDpa]5oqڿ$7&DX %p*l:Gy6=!Ҫ!Ur}nx,_`B#<@b x,_`B!#<Elx{cBo#\5lx{cBo#R3l3x1cB$NlJx1cBLlx;ukB, mk%x;ǵev1{;x;5`c1,0 x\sǑ+phH;dE)fX|BX%$X.`S}_?fwX{zٳ?oٳg`C8M0,GYpqˇq?* 4!/?q'p8;zaKǠTR Wvűa>dLuHx_Ӽm ]3|?X0G!*^>L=dӴh\Ɨׅ$cb拙`ﲴ@b6d9U [("q/vmr8AJ|zN'0/F3#) ҊP1az ,xٻ~A{97b+ڡ+ m H18u!d̨C'U;lTů&P`fT(N lMfYGx#l>_cf|hviO~Z_*d~->/_o[^!i} +^Jqo8e$+ޚho E.hnͿ3QTHe:N`܍akレN~YqӭFa5|gS޵BX[ .B8\5| |{.!^8ii2] |ڜ W?i ^2s>xNemT]~696p A*n"֏-d}[]g3 ߈YNn2FJխ q `}ɘ5wGwiԠ5 ìȶ'$ *ˮv'եb[\+],+LS-4ӤwDPd_"dWsvB*m05[po50z*n?>AӪ/Ać}z) ߄%ot,}0P" 2&osӥbmD0uPU7H*K캖" 2ƅPfC\NY \(4bnPsl f:tFbn͍;WmFR+NbC%[F4૖J/d nirVg,,Ayq0*6hv 8/W!ܠFyrY,j>G1>m[kKPuGtǘ<8pe蘌{մ7RQA3:c:h+]X,g]8}K @k=q|Ͳc-݃S"|3Ԡfi;h&C q^*넡Uʦ/lK{%0USF-b]1r/քY'GKz&rRd}ytÆiJ<f Ω |Vnj64F+TlxO@s#p ih5߀䟨1b< yȂ1G7zIt"Ih\uA W%]_K?mrA]%XejbX1K˜bU!ikK KɀXY;G^2DǹT, _:? t;ٜ-l4nbB"Iai~߆<]Za+Gb涅9R--?8,0_EȶgŃYLzI:0"][>Oex.8o>Wuc/P;1evqÇa: yzY;cWAqBH;"Ne_Jͬ1AGw5("G8_)btJbS`-KPm-TI;qb[;|c|{( 5( z{f5L )gr^m+1O{ԅ0 2u9wk9Y*h >K7}4Xb kؔ#w]؁t\.|0!Ze 5*AПz$tLy瘦CΙR!:Gng63)}5$^]Z4¹p]"9eȊi0 t[%3ˮXa)Ju S'ɫ }efθVȊ`ݗYpG9mrcD" yA޽7MĠkkPw9ĖfVqNg*:yСPhLq XZSHXdH̫VVZ+ F<STGNu<Ʃ;J# H!@"9 >ܑPXy/H&Kf5뢕+\QUpǺ =Whr:v@aݘQycQ Z5_Ho k:gM o =W=(iȰt鰢"BMͼHsQO&Y!Q}QDG=WC.\QI Hp=B* [Ҩ;tB5`5]O돛pB=gyKX(}cJOycB\Щ 럮^Vv38YPm`5env!]ph6i tsoSh")_;XMnv7̬#rK0pM6{wĴqĹ wQ^b1_?plL6( 1cGi Ӹ;R -sQֺ8[˻4NS5_ٱLq6R1tO^-~1{}Qfugk׼e`|.ڱ|]Pʮ1w~E;t8Qs1pC]61ER\M_bsƂ9XJÁ6Z(룿'*c .]Qb؂--eq;RʡE.lbX8$fgH++p#cB9QOǕP DuM5<e9 c&^hu( AE%HL3s %`}P‹|  @#o3nyE߈=CρBjk&J>'[ȩf+4\M&悵̂KhvxCm*>~7y@I:WC~M`U\Xú5o7PB0TRU/hәgb?w)ҵ|Azŗlތɢxj85Xpݐf!Nxan6Nsܶa,0a8alL )Xe9c-oW&5Uּv"q:ii@p'-i[ |1:1 lt${ )8ϝw(r SÄ*VlhG\!o ݓBnHWaI(*H9!dЏmDvDfWaw[dN峹=D; k/45D|@GW 턾ȢHuSMc?-̐#˂qpgz\K>Bb=Dx_! 5"mQ6\GC$`$e[$H_T@|N$Z!!`Dؼ%`)[A B3U )?M"j_Qt!8M8 aIa:06*ht$PM uq 7vh^g^J(Wu~/KElA6;KXV`Er~mFh]ViZZĘVgnZ0UfMgFpba r|a˃'lUYi[)/ƖTH" A(;|\ܟw$&l֐ b %Bhf[Yroɢsфϩ˱e 5DSU/2 #Ɲ>\p OdבݤD@Ct^-zj_@}c:i p>:ipq衔j@kiqe+U) n(XE:D^I /qI2y}+zirijo4!(4@wH:ŷ-^x P~NTao%vy#2bu+dūv2hѧaw#}}fa%'^b ٫{wi$E9hۉ*)ߖH6ce2CF0rv'k}=J%#W D0\ڣ59RvIx>-ܙ=g[GԴSW۰}ȱ0/{0%A29bo!pA>x) . 5@> nI\+C<> T'RO~3`+yvV[]kDHetSd\}qk9e \s`-e n 2gV1a@Gi\)RRUßVB*f*VђA5)ArǶgۉqx{?B=r:U9ͫq%KV?Ac֓R:/;zu$pUiC#Ca3? 4w?wբqi*Tz쿭&rOc!I,Z POuؚʡ\8vw,5˩z4T`VYGlSԇ^-07qf퀻ٲMixwW3UZS}7E{ܪ#^)"n?^CdS@2nWd-@1yt `q/p`%W~EϬcD3XsF\+`0=H)KfPILM&| ' PYdBjx.u{Ӛˋ~[ZdK⌟R5}7իKȅu򮐡b["50@<^`eo]6f馳:FR:*ܿӓ3jJyl`YmU m޴ '_qlc#~lsJŨ,*ЭIr H-'!}n۸斖XG|WH,4Bf#Gf;%#(]M.Yj~w?OQv)Ut ځykUdߋ@qic)>\ڲ`@,j2r̟P@pQy)pU^cMI, vG;zT1TmI$iM%?",% - A)]B6~7LMW_VEe#mQ`V^[8UTCn&)pq풍5C|ME-'Zj +x]ZvVtgou 1PbVko B+; Kx3Y^Z@j+_Qt\vB֕4c%+JBX&۬W/]96Kcr掼MvYHra{E$Ȳ""B?%ؗ]1+vis*[- wPKtc#p5dӆvE~gtį޺е04y?Nx[sq1 F_%9Mkx[sq1 SusSK2CuklRS+ ҋK&oP|A3m^inRjQ|AbQbnjIjQqT+Y)+@T*)o0m7(qNn|/!>Pٴ̢Ē ļt׊MM\@T 9:Tk0/~sqN^eY#Mxqq1 &J M X^WA=bĒ< tdGExqq1 %723xq dK25u8 3*-(7DC)&Oiqc#Y7kn_xq "F4`[xy ubyD'|W,\RX7^ 6x;|a L&h*q)A@bQqBr")qqrf敤qrT*ե(Y%Eys `J ~@3Ald%.\j^d ,2*7/Xl P*< x~a [ąe 3*-(7DC)&OIS $蜟:yR^xZmo8\ c@y:sdkyA\+ Ai[YQt~ ;vu"(pf83|8d^_^8 ;AOȴd*fGꄻ6f4um&AN QϑV̲mʝT_rG* ;ue,c3_#´+E66m:?24 CDg")s˵űMtoӃ탽}Ҫqʂ=3: edRÉUUۖ"O _{%1HvgzG*Medv&v[#Oߊ7vi {hD0 #mPQ%'lR6A${q+@E$#cI>4қ 3Ji%$mVZ)PDy RfqSVLqJ2kdwymx]7pSwϣCxJ{zsrul R/~*zI 0{ ntF`_bn˸;RCLJ'wFoeStC\g ltlJ23e$D~W6iҠFtFogooޟ ^ӚL?{szZB(:ih7"d$ac, dq>:"k,q+' u4(_/Kd˗9MdLQL3ѼX5 ('hCt_nH_ne֒MY 9*c* $AU2+:5-ۅER$sA\0S))Sr 6^rHqHq]6^B'[T,N$8^@M у437ld<q+m$+ZJOZ^FuZrp`UN"by}C"$cILN{^eZ.>auj#˄r}64a` /Ng 3'[!]8+aC/Hra\;b!fpdC+*vC7^S#f$U?6&wDng(Vg zN̡$!luZIƒ]Raț#qI:Sk5e a ݣR[rH3pBA+% naλ$gv/$`vcbɤm9$IUls5촆~90'c7:6|A7cƉOW3qp[>Zsc߃ɬA2EQp6f%47]BnPLaJa놯7c5G8ˊ! "a_Rq#/ NP.06:)8 N;ֻ `2!.+y01`'Ȉ.+DW! U׊>,o Zi9X'Y@x_9[ Ʋv6q~K8#4M C}eټxw4+=5jΤ|L: 6x g-aΥi60']Q?Fh]q]!o:xx 7y7w2O>ħ]Z5"1L',ON-QU36S \x;C4#B@Q~rjqn~^\&Mo''Hngv`|]`gpWJV3N8U^`'^0Xf* e+t\1-pB+:OV$=2fo%7F(_e+TU`0rfR<xC#^<&͌j\xZyoI|',7R+xg/ȲPC㦚#Eg߫7NHEJ կ^ڪSڢcOV/|7`GhD:XLI› D<)vU."N-i)ё/PxDF4Կ{IaK6țhqTe}0w)<";oM_x!y ,I ~ rBg;;^-| ǂBOKz/-.  XB1` Y{Ttb*f+t ?o:Qhb&AO2>ySXwBޝ2X e\|:K}AQ k!p~٥Gn7κ SIh\d:-ށ>=V#sq5;:>oS.nѦyCԁBHYaY"!M<_-BqPq ]'U Y4%=Euzrx5I3$&L'MjIA]Q p01/Lz'M:m{{ˎZZRG0ӁSY*&` Z_@, 90G b\=ב7{fe,}|y鱝_pE(4H]A9@?_zC͡UpkmCFhJQ8Epݾ51H'gcWFJ"sxQ] ȡ!88{9rF06}}w3L;#B+ v>$lyסf#m6ݽwNz{m}8?,uooO텰\.C4ոhѴ333T 0]=xz &]]Xo^BobTM:Cr>jGY;2#Uv77PA}N \1RA)k֑X\{4h4hP*Szʄs6q8iS"9PI$Veo\$4~%)r:XJO3叢!Vg|TlLuU+KX?IрXz2*)>]W|mJFm[X(a1NlP^ SRlK*BbPyĪ2@mZym_D yK( .J/+!dZׁ@N9*[T[:͸8pc7g/՟/ ~2>sNEg$<.~ bMl9@g1)nv%^h]q]5i(|Һ%6<( S<"JJ*,CZ3CҿVd]ShFE$ $kNN)S{#zpGR+Sڣ_9RʝMfhtvZs:CdXDpSj4OPp>HdDÍ.z$a "$TҾj1&3˗* g5~$w>7ȫ% ^'>TM>؝Kd~XYUy9 s_Y?P\~vCM?,WyMթf ?Kv$ɟ+^k]S)g DpG*ۋJ%wOh] p[醬M-ͺH.ԍn26Q7Ito y>?H`N?XfkN? wnqx{:r>#f/fn x{:r>#f/do#x{:r#f4 x{bABAA!(?9X7?/u#0Ʒ fg浌&:\ )9%& YU856Obc7' ؜#mrx>܌ȆNVaIN,NA[ձ(XsG T''?VQ[( ky9Y+xk1~eARAA!(?9 #Xfu1 Uxk13a"[qjYr~9a!^^jgX)xX)f%&%gg((([ZXG)$VV*pMĢdvKe&Oo:#3(4DGas`#oq.x'OMD#(58?d(›1N/QD)n"xk1n6`نC"x[SGY]ryX xwIYa9EYF3~{=#!0ekڍ~z !I߮m1IYHe޴ KΜ\ $_cyݤȇ,7nfF$/-}Қ2^xhqeGX7fgkkǜIy:f?Ueu J{̆m4ᲈ/ Kl/۸]>5835Er>I*gy!QrqLJld S]YSb\BxHƩMdh>- Pʼn|9<{glEf"`ԎĢ"'ܸL ~&ud i"tO@$M͹5^Lӎ Ƙ}7{Gj$M@+8\YuǃanR?:891>=;w?ާMcN)b. G8}h㼰fd8I˚_ #sXzh!4Rc4.V`S;\,:H:U..W2n6옿[ʚ^mǜL ͛>/<똏{ykg{{{c'O 6F,"zĒ $/贬5hHz1ZK'TQxPPXxz['qQڰn@|GS#ڪ^zgu&$0lؼ*6_ )ksXgi3QvGF"l N~`/-fѺfNlqyx=qyy|:T^#Ahr7zxlG*>On┆gI=Yq0̳rB?H@ݖCq.EJE$8nuXg$66^EΘiz:lFc>Mr.l=E\';\2NW ,IqP3*e:1ۃv{'O*Wv6Js (y4LD V#B!;gBIpA0POGӎ\w( O@!瀔W uA4qlv7w9D)7;Z*ݙ-3Lɏ#nHmO q+w$3hUZA2%#1z, 6%,U\Zb)SD:M@puL N Q</H] *NMhLQtRH$=]5`D@QSn`{c,?jEw(j*/2i!Y&SdJ?Sʴwl:F`^}f Fҳ3'N+!tiȿjw87=%\ ̗n+x(bcfetPU6ʉZFhbbP|Qc]y8D8o !`z7EŨ ndڦJ^c tEHoY րpA @$hf\z'̪`hUh{PC ^$]ڌT`̜*"É;ȼxXꘋ8-(*P:B|QoM>0i~%nolwLBxIժ5]m!,C.P¦w*„xx)M/n"&Ue|ȧH_4d6,&\/ff":d *4~C쳨y\#P6e:PCJhbF,TU\U(RX+&KRAzziZ@t S:y*AȐ m'tҤhӄ>SV_A-KW"59࢐e*Gߏ^]w^Aj }v#+sNƜXdl Stf261r ITXk3aҦH[fNt(P]e j&U೥OVx<]v/y.xuVsYNoKX%ڦۂC^\N5` i]^N .V S!mO4dNier:om;h>|\r'_iyo͞|Q߂s;Sz1g1{^t *m>>GW7R9wJJw_:-  .:pmE4Q}y00[*֪́҆y40w3%Oh%^_GaLOx(] zΜgޓBuEEYvg?V/7Jj_(0XJj%:OLOB>-v`'+>%_joNȇ  ;R AuHt߀gV 1z WDkCxԲz)Ny Zx}r=AN|psiͼ2}Dߛƞymy9k|̲`SuFT Jխ#9d#xVBv- 9ZUAlر\ p X9˧(N `Bް$سJ7]୯| ?ӄ4,]h!a^c+M~J]*d/+s5E\5P0FR4]b EU\Su z(J"a:]ڎCH̸$ۥ Wl 6nݵd F6z^M+70r1B.|tdg5W#ĥ񣐶qE7|)gʈ349pcj_ӔhPYVMd"7k+W6gݿk-&3N~:0<Ouږ/xZj #f[MqM$'6K(K [xZ57 #f[F.2ײofjgݜ'cŸ(%d+U"7H&'$gpqr*AUBt,5RuAbrvjAP:1$,UG!-18(8FTZ:/?%5'RG,%mZZVW_PRl;98U!(X!?k9Qɲ O^4y仼3n-%?H'n@xZ5j #f[+,A~x?/w5#f[̛MXkXS'oןH,-18UAN!8?9ۿK6{ U]biKQ/Rx:{%_x0MV8Uy Ku!xTMkGTqܘi'rWֱP%v)% lGh23Nۭ~z) Z!豗@;;R:n =H<3; _V(.%0; ]Iߕ?_>bDZ GyQD(٠L8pO?[ G< ȈlGa8EYy4WS+!&,Y*yns)O]dnE~9wN~8T 9(fsà1WԳ2JX ZNH (>kjr6ߴeڮl dWƨ\JaN &VZ5D;Y3 l{)vpȟgiQ8֋'Rˌw4WFpfJ~A>?feE|ꐼt-ԡ }77cTHBM"(PLޛ>?6ɢ2ТtmSGD ̄ N"Wx1M`g ~aW9dfWG'*A IXй 7UwH!d'>EwGxls߯~R^w CPz"-#?9<}M0[0v`O7!Vl:\2ID}bGJƠ(WDz]q*K3cє:ލWmn弥\m;Y\k1;Jx] -_w'ۦHjm>qM춍./E'tG7?#wqo* N1̄g=P%9>{aHucx]Qzߋ@Y6MjeyY<ʓ+S>KsE0 -x;a` #B@Q~rjqn~^d?&Ɍo%p"LW2*L6v<[q Fx]AKQ |[I;uD=]9 g)sG.,1 늦iм \ Px|WAAmxv1:~_0(anʖU3-۴+`ٴZeTe/b+9*L>w U20Qf]!Uqʔdi$tǕ/M^ۊԳsdȀH7י޼hVxO!b- EK}1M]Eӑy>kt~r.(pxj`;#^d&)Tp`xVc$QBbNjvqj ɭ>@0sLƥٗˁurd_.͏'uHxZyoo0BE[٭% ܀őĘ"Jbh{3Cco9loo峹M'a&͍J/J~Hf8IyA+Rƃ1×@eNX?˶Y:M2md+4*dūT hΒtH7w$,.Jwi8jНx=U?3ԟS(K'?U.)UAixä9qr$ ?ŁJ)+U:(ʏ_ϮWԏbvzT S~ PON@0 >*!9#R2 `|G]}%Ǎ81OaэYȕ}~է[oc5oGaiVp8$vki2'Yף.w^]iu{qk)\(pzh$U-D(QA~~> IKQ$ T)Nr>!T'Oٚ|e)c:`ץN}V)r7cGG.L<]:mÃUOh,R0;j? K6wnBLP]~Ӻl$͝,܋vooR{GW/گBxjݙjU)?j#+^"U4>uiU(CFjiIP6x}/ڝmnӒ[QtL0;p WM,;,~0O,< FTY-"4b )޼ts6P<iU[? Ky8Qa+s 8MG3ݖ^8?H=O9\R1C'9mɹtpx55{h0FpI: ɭ{4Win*&3q 69)MYy=Dĥ_NϏ޴o.],җ8'i2qt! S.;X3yl1Yʢ(q?'Qaoz jQ} aiް# 35$M_ U Wv7䌍빇` Ɗ$*]RsѲ8z +eZcNDZoIئh'xF9/Se 3C&\_IK<.}|S{8:Jt9/hĿU跎0ZФv띴[n;;{Ӌ7Y}\t5X48% ДeEP$娠U] Bԫ4 D&+5j_n3"7[GԔNY YI׌n G60ѝ{BY69cm $+@b4<â܂sɌ yU 0"h{h*Cu4;nx( rڱ>9.:| `g?=s@*{.#u$-QJ3~Q$ Dj̹8Է~U'_Fsɥ%r4)UW[XH y[~,wNflZ)}M֡ &DpǫGKjEɍ!I7h$&9càN9C!݄&ܚK콢Y[(HGbÂ=߬*ȟ+d> BL0N4k]ZѥȪ ƿYTcCLg2y6"S-J2uO(m}j'77u T*u39C<`"F zT8:2]di~^ml|vy2PvsE>欩DP6yT#8qD,C̬B-YuMe`Vs)n[x\LsY1 lav#}Mǯtc2Gqσa'R'Lpq$S\ %2.  "ǜΦq'Up1J-YN<ˣ3})E̷^z3q]~-ytA,Z3۫n錭4ņܬMpΣ_K 3UJn$ ?IQ_TIMEOUTp2oNx[2z)#fs"-&x[}%h#fsFaɓ%$7{1obАԒZJɷE&_,+;YScbyqc!ZUAd:s,ICl*Xa q(Wa*syqɒ"ߋkf/ !aʇIX l:XViEUH+ф8ᣄI|KZ: Z4)? LK|#jw<^T10& w}=yɖ&ߐ49P^f|lxYmoI~Eo~St:uL k1igT3Iw|gz.oWަ+¯JVPި/sjh ϩꋚQ{/ :1°U T^.fC3'pNCb|/VdұQN\L:8f?C}R$h 6xQD!Ek3PYgF) zp:R ( #N#E^DNj# f<8 \e()>@ǧW1p]@z3 k ;#RW&;$Lj,f93oHOpȇ3Z1Э %X r>xOL}[06/;T;ϵVv޹>l{cyAVh8A4qv:>MƧF皥7:'6՛-Ei_~ulTs- 3m"WE燹0q}FνʻI/[Qu| fYMRG (БMƃDZ-Ws: Rt;}eS{{6H6Մx`7lo$SK2<|++,KTJeG5ʷ P=Ǒw:TV_&DV hw߆UW1AK^0ʡpt^1T6 GX]mFXqm\HMq"0 ACs*٤ 7 m*mRaNʚ[䅑 &3a6C%^ ŪlgfSי4Wk]0+&auzG8*:1i$%7Y+Sr_V6 W4<|p&T31&f3"x`AEB^OYٜU`pHL.5[±;GЯ"ڱIP;ni dԂ-5gOfYs+LַhP ^B7_8}ڸYY-V9U ??THS&T7Tۨho7k>jt^S9x=dAXdm ST٦S!YذIu;AV!`wlKn,1;ssMdE^z rU?:-aCɁ4rC|Ac8lΑ3&8ǰ>[}T#Z#Dq?'jf((s@Y9I^l7!3(M-PBŪ'|l*5WӓnriӜ1캲C-I_xRf s6\,;H1lL}'=߻T q^BJ0}jM#>Dade-)$js[?Sifg_/`1[sj82<[6 qa u0,c<*=̫$OP DV)7հGaW8ZK|+xer[˫kP5n &Ϲηb1{⊛7'm_&eTe{uqKz ys妸 PVryUhchw9՝wWY9`t.%ɔwVHKxQaX[[peˠa7'<&3 vc*3J6{jPy o=?<3w+{ GAe/G[0 .t6}!V8>.gwkrnO/`hzS־[-nt rqC30BoS|n\zxFt1:i^. pEh3@'/KoPpqpFNct4OxaC'g11nYp$A;^RJWRO|0[ D | |h:9 7K*|lΗY%;Rq:;4*@_Evnax;pa #f[F!y*azx;0f #f[p͗$jE,ynx;pa #f[F!y)_2x;0f5#f[p͗$jJ xhz{&,nw I16¸9Bqs RZxhsz #B@Q~rjqn~^d?&Ɍo'?qs c7DL'X6b2m>(6qs;$I+'3ʈe(d*e%*VdO֗Y>dY/+/2 xktԲ\;.UUUҢT+'xe'xMguCkq9E%99@ 8V\XYR $ӻ,xk}z;#^d&)2SAxg:`6f]y4&nz,o_Xᖢ;9JP ,X^;"l\hZsq+qq*e'_SߎM*J@#3/-h~^sR *L]X~B9QgL`xYioHlH0.FNfFD|7ɖ E $eGp߾L QwjȧKoP>R*0A* LwMϜgWtqӫi"_%ҴGj?RorrTP1ȼJ՟7<7QyءE <'n*$fN` h߲C#A͂8:&`?MG1TmB6݌O(ŖS{w mPM(| S_[h0暺C{~JE~iZtN([@!qvz{;7A#k}~:ۋ+e߻tbxO4XBXYlԦqWi2$ȜKEa1u2)qN,b56#oߦ_~kS) ]O43/lzYt֕G×,AvY3@Kql`ߌ?h$kަ*{qh7vh/+7NG +rrx' jZd$dW RŻMJ8aفcrH 34p}ͼA"wvHe[fe4 AXPP`6›YªuhÂne\H̆g~ǁ&$xXۦVo G " "o˂?`)BZAsc->lB kA >Arο/_-q«$!‰DF"!!l!p(SS|J.`yҙDy sЉ7m}:$lrty~ua3-" O+@.\M JP&'>lUEڟj R/LwAWO?On8GR)\d> 8(njJf. NA=;'`a:&EѰ޲%#[=anbcp0 ;YtMhUF\oZ8A\Ux*Q!܍gnO NLr 1yY$fܞa7zF9HLdnfHTi!S]D! 1 ѨT]H1~)$E"Y H ̇e*]xVRAA!(?9s "I>=xSn@U+J*!]Y t" DKxE[Y=I L43i$ lX H>wVR6`6s=>3|˝K;BJ٘\\^ JTodgKbJuƳR&`?瀁=ʾ_v >H$*"oBp`]9rNC۾ˣ8B{mikjzϑ B" k-d >=)<>l656I"&% %4Jz@PD@bO2[DI)WTS5"ro]^qq n}Dɻho1$$+iXIq잼#ƛYRf.4'Wg.t^sGbIMm4B6HM&6a$E2u $Ozڊn Vrd%n6.ubD`}1e_Gm۟GRB'B7c}(cjZv\GR5YoaR-U>_/hI:Dҭ (590OPjtڥ*~Ncm7{~i>)!j#'}LqJl˜rf7 8&@vQ^w4v rXbgCN!!qm[G^w>>DsJ)0{DRZaՑ?*yKNX_.vLhEx3՚ɐV6U h ƒ~LM{uGuJ|nܭ^Ċ\ˇoΚ͇Mʞ]r:)bE-}7|ܪt(SJ7tJ0ފ[=Rrq0:%D|$^y(߻@XQņعRP,[kB"Ec\Ї"OPBs{y(esA>G;P nj\qi'uS;Jĸή"zV<ХRfi%-ʈAwvV(wJˣt7[/ BMb!?&,{BN ZM|fBlVݸE'iBYb~ぼ6wv{]gF5O|6uI~mҟ>fA0:9l︪Ts]S?c O!eBwNg)15k>fl띛Sn-7*6gD`[=H\{m)J 65Iwٌ5xj5> y**_$na-m Ws,A+!7/bl]huӀ!P 5N]s䪧KA\FRoҠ3ZHյ8KvjGvR0sfI ŀ>L68' ,BmG6UelR7g=.o6VB`'JRrWJ0ݝPcTr-oAw*Ym]TLRqtKdnx[XwC#hFQ%Kn4x[XwC#hFQ%IMx[JgC$B@Q~rjqn~^&͍o'Jncg,&$Vnd\XனԥP>َÇ Hr/A@j'g/-gx{sAgC$#B@Q~rjq^\&Mo7w0? _x{sAgC#B@Q~rjq^\&Mo7w0?; 7Ix{RgC*#^\&M/DW x\[F>Oxl.|L3adk1&ã[,9< K޷[_6f[vRwuuuU^ZZZ]n ]^է mI(M&Mɱw8?I9o UߋՁdACzOqCxemc'Hjo4'Gxe@䣟Bi;՟'X[6d=6}7N +q#?{Kb|ڎIp}2iolC&ǚQNoTu>^%*'jE*A%$U)/Ɖf{>DC?Qٍ2?*/O e ~0#iz@K. ,7>Q% 3pb: roA`>Q !oIS n1fu]WԿ ~8:;U[?olmx5`4Ni8l@{{?r{~_-uur}uNb1_AB ISGq⫡yAKpn>zФWQ8BިJEq樻$d0[Y__AQ:!*_wTB _9}f1`K:m^:#>]0eeQF8dfG0ݎ<\1X3Bp4hE_Q!xUq f$7#  EL {D;M:GXr8X!l94m5Aq{Q"7X M.00XD:* EÈ~8WWTK5V-2^R|l+$[VVh ƶ5c.;J?v n\HW'xDnAzw?qWG QZZ@e} nn\xj7vpeE"8BD`gqe_AiZ};qztOz߶NvfuT/d>ci$|V]-Sf+EK/ QihŽ</>zğO:;tE x& OjAnHݏ5[a3c>=O8]ˇR Y0󮟞e`zQ*.M^@ /񮩻4a8YhQщ{ul%lK,X~p<[r笯m|kmv[4y {7aiVR3ӭ?nռɲqgu}'׫bW-d5}˞`Xb 7Ztj"Dž4Fºvfq0" "3 pgqNtIG@]ro$\ dI6dY8j$g7,\Aֲ#wS!8R:5nb=zDSҁ  Bb6=?|'`؆aPzH;$ߎʧPi@LL 3Cwp3nޑ^U`wW3(Mgο3ᶣyVBnaňDpG= DcxHÁZF":dVwLs!_y`?(^ UH%W9oф+.-n% n;jS˺X[>\9U]F2qT-kcwB lPZZj]j7q[yjH%}κTQҖQra2Ak4 n[YF}Uj7Ւ=j*;0eD*IaouCwl7YM]~@ҥuTv]/% S_I:Wm%vZ_|jL6犏.6'p`uI+fncMҳv;l٭Bɮ&%]`xGayqeY5B/9j6^]-f:g?pҏPIyu~uQ݂uKm֑wwn.∻}-7i\f^%9^o1\(강aqXs !v6_C9.. _#/@g;U5>g4).Lc~E;B0N8F|YufQfFo]: 5"BlOH&hL*'(e{R=wRХ7'#=2x~z"i&YǢ66\$ZڝAQuGOwWPNL 5Gt ~i ~y`ρVɑkh:"~6\ ydB\ਡ2^ϝfhȈH OIrQaVEu7ʤܧ|_(]@% %=3D%KopH*Q[dV${ő!9׻ zS5ĵ:T ?q~(3gҞk~\=iH -VGBiq׻ܾ*Uc^"x.TA!$\:9VU,_W=1 #p(LV&1?S'WQ!~&G> CːG-$Ƅr^Ө &OkϿ'*ej^¬?f27js67}yP,h̢Vk!&@V$:ZK"qL3T*CiO9'diNׄ>_0 )- D)S G3{yI!6_'RNķ/Keu3GIsv%q`]u<;iKϤtD![,۽ZW׌nƘ ~D*)g/W*'ud(jJ]9ȱvslwN:cE>X2W6WXQO8 ^؍> Z^@SAo[ナQ5JTډ}x(41(w/y X-]+[| *7޾ڬY*1zgWaXV&}%~&zїWC2爃Ý6?#*,˞V09vδU!t.nKZJUtf(pQ٧c\uZhު̬̏.0{'l,Զ@)2%A Xa7Ƙbauj&>"jbQXF[V(It6S ]rmp%BBz2SԵX>Kq$v"W`1w&,%)D [Xp(pmWW m$ls7 M*,l@ {XtI1nj]VP)%O8vYAbO6s~!XmrarpjFmg^^R8v:r?Geƫ*dXU u;"i=fNi?s f +Q ߣ̣+3SR'E{h҆.xPzKK{l [ny#S8];(o,Fqx^k-q#K2&pn> egomDxkyxD?6DS~d]a~NF\X8)sKʄniIOׄB٭NS4LHG^ɢO8[I)X&Sr 4%΂381S,}|{Ҽ&ۈ&=+}R& {: ~f% 'Q1 ^ϠczqВ.:h=%9粳:cl} W^ _L"L[3 j+r)-/_<Ђ3S5U8Ej~ '&2G\MmŻ\r~J #Қ=Y*2Rj?~mfS/mNǀӧve:H2`Be}*2HWWP݇cQj?+XH;o~U"b>Se„ڹ{(&}E oRj \<3n8fͷ\Nj|;Az+PƷPhZ|j)jGÞrA?>-9R_ ymZĐRT 7+/ R`0r.T&초VH2@ȶ̃Qm V(^c:#'R8{> ߅_'axihha94o^0-w ܭh57+׿v zh6[Cu=)bܩsPW_L[1AiB1Y2Iˁ6vfuY`^h;@`Q+WXYC`o*N-K!sMn.<@TL y.Z(B yB"ZI1cLуnTTy2@ז` |tH?2w #.ߒvI x۵q& iF/:j # )K @x{ i' JpYsq+)go dw -N-QR4'O)RCR+0`{=ţKAz:u{<H f],F@oC"`TڀmGvaq5Ԧy\ƒ;?]vEahYPIU+.Yc\&y`"FRvCLŭj990cAf^_\xu܄ʑ?}:?/GEz.NB'O_1BcT'2W ;5; iRR9XW D1tV&ҁu͹EBϝ)ϙ@DlpStѼN٭`9e[: j֍z^s@ hXIG['PK1-MYP1*`sԤ^$uU!] 3M[d2gjdk+V43Bv$-_0BzFqb$pedf8}ZTimsY3slZ!d\"C$F8i$fAσ ;4*o\_Y4qҢE9k%gz1KjZFߖux{" L9C6x{q" L߉Z{k()8($&T*Vd(g+(enϗqrѝL6W0N4  ON5`sPUlo,ʥM&5Ĵ['R0`x}/RAA!(?9?/ur BƷ˙ x쟗:9Irs!'A0x7k^CY\6by PxVmOH"7NZz!%' QCY{oqv54Bof$//<,k©*f34il҆hr_Lp){9LpU :4~watֶP;"[ %.CNzpb&Re3TSLA0%]G(t`~pQdXHx3佭Q0E9h~%.4ˆ% s( JPjSi!HB xT)ݡY5gWp a\rLP5zڌ L)gY&I%x@ci u)'o@lآWl@sB.p><Biq^恏M|t= |O&!&)>Pٗ\$İʭwqy2Mxx10$t4>pp}џz2E'!@DLWb{s!E'dnoĖ2SRUaEcl:9]Ft~W_oqCLB"=t8iewn{#ۿevuUs6GWmVh㚷~6ܱTI^Y 3uقQͱA=KU>SM9RI F(ᡓdX$eѫR5!{;w8 }AqOëQ|m3ѩoe`|3(&! ū#ep{:l7 pYDs6[T)qKN#?yrqjVSPuhl9ۣBdM `^9eDՃžE}gJzGW:XWQtys>KhDU5_\Ps kc/=* 4j+D T1-_zb~YZn< L#ayZz#кq.=i{櫎f/HRIoRX,n W`{WO8mk9=єI<~6gCSu,'hRuK3G`^ *$kE/jά!0|QgbwDя6&wQGzx'ZC5,z=`RO꬇450XTy*WJ |z>"(5^DXN-nyx[&LdC#x$nx[&LdC#x$o+x[&LdC,#x(x[&^hC#B@Q~rjqn~^&ͭo%pE,|9) \ՓMȮǑ[_XT9Ybr d w:#laxUPJ@TP7ohaA(9(^A<fK6e 5< ^|/FZ]c`ッ ۷JS!jA Sg;[o|GnpaPR3 Jk%<,fC4K';_"Gx(J!!2mWkV ̜ cj% p29X/i2)TSSx{6a2[qjYr~ya^^jgX)xX)f%&%ė(*VƦ@]Z29\anYqJPjYfqf~XD-Kx{{C0#^h&U,OxZmoli (~MvsWǑcXrip hjmHuIgfw"Qs>;;;3Og}}D>{^\(= T|҉9LsD}Uw4Gc5SS(ƑJaXbO1ls#b` C6>5ar];hb{akʦܱ (˾KmPMuDX~VhM11bqЅY.g/c0cN>ӏgg'h \᭺QFV<&1 0-0q;;>o<7ѧ3:Ӄa~6k+%f0N2h0Nj94LF4oB v9KVQ ,u}/) nu kا~m?PTN0R> f,mfy>Hݝ<+Ng%sVRGw kxߵSwhٸP0l 0zW* r^~b:8w6i K^8Y#*Oq^ SvV* '[;e"(LPQ$qB4լR$atWi\`$ &%P(¼B~e#la74Jf#r}.dK$(7»h7_ys$FzD[d̑S}흝 {܃m|ެ㠰ao mgfD=Fץ>OBU +3wH \IJZL W8 ",>O@yEw{>}yԟz ˌ^ZYL /;v'"Co(aopײk,6TIa`BRJoFujv6&! ûޫ3S< $+:0?1^MEuf7 5jMy–uؓUU<>qEQJy '58N$]zBm 'ړFAJ#9B:tZlR.X*\8[ݴ uAl-vXVML u(>e`s5o#cl _I-o׊6b娞24IcYD>U5P?L 7zpj5G:5 !̔6;wg[Io<83?siIO%3M0̠-A{jɹvvF %x[07qC # ƽ)񓥸t< ^73ȪpYɉ99): v\ @X $J3&q%R PQY L-*/YeRԼ=.0+n-x[ aC # sz*6oFx[ aC# sz/Rox[3|R!4._ĒT}[ҼԴ̼];.ɿU&ת*l>.$4d{qvOA6ɝfJmV`Zۖ kp$v lx!bs0dgYͩLy7f+濹C#^%4'KMRƺY_j Y0RȘ1ZsqN &6^~5#7ӓ]4fxVnJ  *~K@dT@R RULPg8( @ #vW!"AW {7lx 3رTobϙu*ZMjӲ2?;o.|mll ]22Q>nͷ+gҮ;K<M.Թy4uϘpEyL+2k34r jrFyΞ},FĻLάg_u4<*>lPpx[oВ_ca[e䆰BdE;xpx9ߴ KWYePp,: h⒆)ٜ52k40ž`ԸOtH,/j* D7;<'$(<(z׍_*ҼdrKdٔ\[ q4 nfv&ؒU8i;2 BHHBpss#I׵=qz Pҥ g 4b7xn^~Tb 2"S9->\H74?R{G d EYgp>Xh T/UH ʾ l%Xl#U  |{ 4Y0R青;s k?89Mf2m,2-UYk+\зIt\8/:>p޸vKzyX\,Zy|{HE;DځZ$nxo :KV HP|nycg,Gfz^wETk@N₅*?Ҡ0.Nm@S\  =*,PVuσv1 #v{%C zeJNr  l-'NS~{:x;nt_h{3M Lu t ̀L+#+#6Ar* z\\E%%E%:\ 2@̼̒ɯJ44t ??1%e2foV_+Or槔(LK,LQəlxLhWg('d&Y$Yy.>:H(DOլډ8Nqa 9 qTB]JSSSRJP (JMN,K\%5y (0Lдi"ɭ 6*5/E Su xVQo8~.b^@ :]N "UI&o9N)olR [{:UwGas}H;ͳ@k&Hp b,˹,y VfT#BReSLƄFueQL|yJ&ŧ>D,1%eZ$YIJk0QӾ%>1z@o1ckP%W p U9%[.JxlJ |F|Ew@X|SNZ)ÚI# .8}&?L;b2f0<~MG?2Xq LٔQ]w2R EJ\C@J# ~ bI?; %3ؼ^2l5C7M}Le? BJB=+PFIn}]N,CgNwdnowXm J |ĸG=/^]fvmٰCSیj.,Ɯ4.fv"%TG ݙc_xgŋ4Ns(ǰӑYdjlGf 8ьD~q=(N!(S]JN*_j;1 呓L0rPw`o@t& ?abll_$\x'uF} ,ڃX ¡^&Ъ߇|%&j,!ȖQ,@$"EF*ㅇ*{8N#| 6Bw,Lո]qwe Q@OkK8UJ_ c<w2xvFcjœτ`ODy;`j$2"hFj>Nёbeo6#5o.߶{:hٰ;ipQWH8 |yu0ǿ5Ϛi}Ѹ-q,[۳㖸zۺnq I2cy@=`LHa9b H ; Uwe|Bх%=E^6LTg^Aܤ^'R>a:bb+e}L;O-!*)+}q=& /_7s_(^'簽 's;:v>Z0ec#!ehviN-?T{7v_5$e*}l?wW|;Xq_j'GqÕ0IrzwpWG"5;FyA{<>Ù$I'9q֗F h0A=WC>&Ni"@C_4i7Gtzd&iucc=bj8(|( 4;0)}>8Xu"tvɓELխG3Y|g1ed3-u7k͞X mЉ>75_/_=k̊_@Hl ih+_\reN\3n3݁,+&ýצ[7[hPtFjDݯV_m~}I8%l Ce k繘~casD>_mԂee_ӢhEΪ#fE4mjvu8MNk&PB Ixy6Ϭȯ@ 3X9s8ԋS)=09erT,G58vGowaG\vf~r~tI^)^dUB4g ]逈.^3_Z ˸ UC:Yu&Ƿl-֒Y43cXde83͇0XXBdтEO2٤}l̝k+|S=ۮvKy&]7_MqrnTs2>ƚK'N(mr:syݾbLh #7q|)\u'"!j*YǠ[h,W2J{2N"a&̷ y9y›)SGDp"fVĔR_t¾"7¥63…D?R׋e : ai+ SPQ%M-J=zf'a4B /yq?TЊ<"4 !ᜇ/SbCۛ rq2b}ydž=r\Ng3l5%MRk?R#4-"J&d9 *_IC/ܿ!*#%?*rT %R)=(,h-XWi[YhAνsݷeUOhuUM-$vM5iILm6k)z[\G͔rGR=$B$ Nj(Ԅd)|e84e,^_i ?map73.54 sozYŦ&BB,qC.+T8:CÄ*>I5\Q>l,%s]aHi&`0NY `iq^ʂ8+ 0G˞*5)(`]մU .T[viPm:Zs dH׷: F7jnw*R``=\kL?,'z A35sEwD3wk4FnAb>8i0ҝi"@7lBغ Srƣ/X18KRY,M۰ 6f0:Q}Ynr%{Zd OV4r.}?9F5hmǵxy>'8-4mʬ7K@8GAv!fi\4:-M4uSZ~xSNА[iس΍& ڈ\.7g8 8lPYH(S#+5h?}誴k$dvNl1脨tЩd^/}*+޳,z,|Ըӥ,,UЖJ8GԾjj[ى\ ZɡA&͜eU*rPlX]>#vvӲboZg?oX a] ;u`iah4GP<*eouHt=K ZOke#7O6fjgg8Xg eK ~±EFs Q9mAbgyoz'hQPClQ5'YN%An"x{(n>#fF#=.hn;x{(n>#fF#=.\Tx{71f>#f5̛߲سltyx{2f#fFaʢg2n~bϲ9.f/ e 14x[3!f#fFa1gF6Sx[3!f>#fFa1gAqx[4f#n~^dG&a&p)L.fT%p_ OxuJPQR!K0&1MI= *x ҚFDNҪIuB_!/K)ܻraZEtV33ױEKNfq!$ 2@2 ۩t2s99eꃄkz\K k =%HeqH?]jhyV$[FGPB˫0 x7A/Z!\Îey ' \6]oɦ,;0/s2c2躑3ryR%ANk_۱[S:Y"-k ۩+d&zeW`[d֩U*abzq { {Ŵ.l'R0ܭk[Cɕ4dymdh Th().c#<ȃhUd:'v*jyDB๼!`n*wΚWMSu\$tTc'(3262+O&ɬD'E1]''MfoT][٭bЋ+>)OLmy=P(PRZLS50lֽo>\ _ڎ x\{sȑsrT/,ɕBօX嵋BAH ͢Ϟ_weҩ;Vfzz5n䳵NP+|JwtO'!>d8Gj8qy$4ݍ#'֝$8՘vuxqAQF^G'˴Q/D~ZY8O~)@wˮ {|Zo O׻DkwG//4DA%$*Ȕb()=DNT6*(Us~֑NPu'a0P`#K1=MvOO +:#P:D}I,` Ԇ/#ibOUzsҠتjBh!b0TZMR}7 6~9뽹{QFCV+{/ʦ8o]g{YӺRHu.{gKս^\CPD+_g^߃)0 }5>hzσ ;  yY/{+F"Bw*,f` u OU= Ri n Ax|^iG u~ēvE]_#z+ ڱFqpO1dkVйבK/`zg[8N2f^a=^bj/r3p8N$mfme6Br  q$=_ K<;ت6| [o|  0!C#' A  B|{0V X Q`11 ΃.N|l{$ͯapԎG85D@;'ӣv=?zr/:qsv_.Vnuv.NZ21I/޶.G'?hICy_GJ'+-Tai=?cPAس8fCx i((МbGdг]$BPY0X{4;;/7ac6a I>LmlSW?Y\}V}Dgg5I'NOt:H>ǖ0#6j7Kg06^P/Nۭy7 [a2P=HMAgi< l0T~ڃֻӆ^Gs Ⱦպtϯ~vDp T_%b߾t."{eY/`wK%,&X{ )Lx?)Q5=aSJHT1G*4M:&= %|bI#0"_:RlKI=i" f#s0_)(v>Nop ㇍[f\FC>! -HBpbfTsY03qMѸT&toѰ<ڨG<8*% qec:KlCTL+-r1&mgRT(-S2-Ռ]K<~p>7Lowfi% %d[QrD$L$f[^5(˪Zq[:ȣR+e$yuz}vmDѩ}E|sJ}~U8!Pe#JN,tp E,;9B(  BFcFCc-SAꘚDtbWQK$m䏒f(>'āϧWcFr8ㇴ@d*z@i!1{A:@,q('O7t"zC g#Hp%:Z LsY`ͼ{&:۔lI\ݦ<ím':Y)͐,l95˓љ4WQԽj]=;nםGgsf,iJᕤYAxd^X,pg/ *ā B4,g1H~k>}]Z{VsO1uQ)2ڋ+C"r ib.f O#R / Ɗ/qPQ B ΏQhBS23,jy- xhud0ܪVNl Zd5 /rAR+R$YG @H1lk\[ H)l+J%+Pڅ53D~*b6a5y nla@oٗE{.,coF"4*t6H${&yXy'FV;rqh8)nFg&2$FB&KuRm/c$0Ǖ*MKhiNn.0&HKe.A .*uE~Sn1ݔnK/;dL`0X[)vL>;!qɿw㐁eF1/^G#+&(ы;=5 б xGoRc)3 QƖŽMQ1q3 vixBcS6nϰkVew)'䁒a6<)6s/:ņwKklS=TQ9eyέzd2t;$ TAlhe$buN /Ė,mMX8=E&LD64J ˨.aQQe^ΰ#)C ՅmsɺD= &;Qbdm6z(3ɀDh)n1 x0rfɰҾZ>ՖS %r1N=f5 {)p ]`o!hvAr жBAlD9xFKV!=R~trp}} Gkp@UMVr{k6IIm2m2}|H p9NIIY3 V$Pi2P,4\r^Ƙ҇N@ȉMVo( hy.6r2#U5IuO⑇XVW3ɭm 0 97ĭ\s0條~(7dA{i.O xp~9I^sqջ2"#vqA1dl7i|Ty+], 2w..0$2-⮊0X*@~Ѷwqt1SjTܝ~tUƪ?QmmMh * E):|8` ckLYb+̍?N( g[!U %HI`99:}铒\YX&Y<- iMeTǁB.9oBSmQYh JDV\d{%(j0Hz B{XdpILT#w%tFa P{v~L%U v!CI'cqD&0}MOPm̊bWTnX?Qs2$]еhw*i[ =: 4uI 6U~Qtwީy0G|b)܅ldcMz8TV}Jep;IK ӎfKԂSAMy%:\-C j{~KLjF鈮{r63fo][hDpmcU!6_˓ $C=xtͮȓt˝iZ!?"_Řrv\Mt-:p ~@3!в/B;fI<>ldASpXOՃf L?f +fPޢ#F) Sisv AZAfR5"c2R( U5d,ɩ z|=8ƿ>ʊ%K^*K}v\B]^Y[7>BvO_A5YCP JPCZR$79ұh)ټswz{лOM]7(#K/؉Ӌ^ȇƑ2/xa&@g<IԍGѱr{0꘎b"3hQX` 4D'xG##HdRZlhEYd6zؼJI lxKGMnZm4q@bF# _&x Je¯/{') BT *TA="Mx!0Ba _\݃<1x:D F-7%NxuQMJ@&fn+ n4ҭQ[99z_K ̱oѻv\ tR\j6 r* rN. hl8up,7|4ǑPáek-*>kWu7^pF~%45)c h8(–IYȠ9jGAH %27xWx:}; FF͖,ت'rMNi._:fwK%Gx[ɸq|TDyx[ɸq9#fK|g6W:x[ɸq9#fKFfVEeE i\ PWkSj N/N)=dzl0 0)UUTqi9% F 9ɕ c7_w ŚA xj#B@Q~rjqnfF"}MxKr rF׳Lbse*ټm5mIUQjzfqIjQ|r~nnb^JDW+e3uuJsRt 2J&?ӪՁ*WV/-Iǭ\m,LK 7 OdϞPEY!'5/$Ct^45[X^ (y tDx{[uj#B@Q~rjq^do& o71[ ux{[r.fwV/v83rK&[GYl d_r)x{[j3#^do& 6]Y=Nx{q#fKmN9 x]msFl)z].d;ٽ]:OYR˅HHBL\c~=3HPe>?X$fߧ~|=zd^$1ii&ӭ8K"cwMbxϒ65a4ޚw22ya8d:L'i<,t*}8*xh>~Ԝ^֌$Bf/]gEa 'X|4E,<&_ϲ86yzV\EY\fMMȒ*L4mL/@ _¼H9"ݞ8A{f>Y橝DXm g&q06cۏZIr#l tΰ :؜2.m1??7ݓg NBk!VXd6NVP85 ^vO~Ę{Eop͋kwOW'QegD,6@YA3@YlFq%\lq #sex'_;.ʴ8s]3iZUuTWƗ{6pm3Aa6KBm}m^O+iRl?!()BEϠ.8^ƹG=C qË >ɯC>8<ޖ_2=Ku,KP*T%ɔ?mB/Gqru[ 89-Ⳡ?qzD ]>&$88K^o6GWo}Ý\+1quX}%|p>s .@S. :-jRiŀdi@3 oZzpg< _Lf(s=aFɰ6l<>7H|HE43>-ƹ1g6 )r1'\|>֋&saZ*N0!R@!Ġ V`=~J?si|l$nHGeEee,RdOtt<(><Ǘ"n~wCܴLYuӪz/{ m} g.=&8 !Oy^j`iF&e1JIec_V- V{!Ӭ(j{Au=y+$(qۨV^ P,Q͊\6-)W_~WRl,Sqy 2'i2-%$t N/ݓ:Xd󏓱v֟l=^] VVO`Nsdg(fn-|[A;ɅMBkgDbld"=4$C-(]w5{?'m,blWa޽׻pe ''hщ)M-ynǣ |uχwV^fyqrRŚQ~yyph=8ľ SAN $G d{DфS7N4#g制"YOmY!͌Ȥ8QDɞD8$C߿!h Gǣ}֢_f+_c!G_yeË W=LF's*|%^N6D'*UPRG*BrR+SNR1tߪUߧGChC|+? wRU&Wzz}m9Xw&T[Y}DT7/̃~Os~ H]Z^Ez{;\֍yވVArܺ LRc-zHB&y=:jՃֆTR"恔(y@vE-6d[fqLfZoiR:rr]TI/RT+'Y;ޒlԃi30̎oŞClmԈ]$nutOwZ7HG܈-Pq%rIz̺xuX\glq!i^tS'ПF} LtF9hj'(iCճXFPriU.K @F-Q)򬹰uowƨiްZO;20 o|/GٌZAOqdM XKVJ.v/OIZĪHoQ31{/—}{4_>Do7oL;6],Kzȧ #߄{G!hXH!jZ2 81rA<{X83pZ,P'p6t"lΪst$N"I4o. d) *[LuMӨxiMuW_aG"MK)~,b*;BNε1#BOyAT jPCxs΀j??\7%3!潺Vݾ`[e7sy3vc+~] /.ST--PugAK'S9Y=KRdJY) ⃋QǒE;?vZt<穁h?[[B-4QeK}lr `0 1SK4%6 r^d'7*Nt9{5 `?kvmsbXj܊s^]w7v͆Etx׹s4EC`Fi\+:ؑ|n1y=WKc$⢁\p\X̟!*3"H)#t0V˭NGL)Td e^)#pj[Xb{7E`KDnd16$%-ܦSTd> PK7{ݚ&&ۥ .a~}H^%a.0ne31rۣQ.΄ЬJyqA^"`EDZ _W_FR\Ps߾ ,XARNfY< DI|,ȬffpȂ:VYWfdq$GuWp.EIQ*=A<1NOEרՃFJ\ jf06)\A9l3C( mm[quuP=Jc/n]C$OXX,A11_EZVay H<дQR_4A@C)QA};+UCV]<-m Ӓ_ar`3V*~OU o+<'Udv[La.qI1(T[jQVyb)-)ne|))V}Y?3+lqK+;mVZK+1y$SSzKd#5_w"rmxDp euY1/1g=1J/h-9+*Y8YIΪp[[mH'g_g~ }/ǃARʉQڣY.J䵵SրW~8=T(D*kE]vjBsgx`Ams`Q78'vH_(C&ΐ-ˊPZc`cCb*(~g, $,d}5VVGVoEiLCI߹Z1* 6Tx{H~@딑`.耊:2@3Y %LdᰕVYl" +i e4U1v.5 VXX'l#R"jcY%NwYV ?YW}Y+B%MV湝vuۏ|Y*5ȞUuIśn vG*WTV/V- dZb[Im ͸q~j\#,vxd'LF!I?w<\ %0;; `vTSGzn,ER{yK;*zNH>y R$NS:D鎱]"?RRִa2q?eC:h7RSa%Q"CP(b ̹upID6>%{l/ȔϼEmZsB:H4z_TEx;rzhfg6}b <̜" 9*ы0+Rzg-ʉ'S 2k2CyMQL]Kf $)"姲4?FohfcDy,E%iZO~r 4>W΃mW:"'ULOI!SGhc_mn 0^n<ԾE|%lp f0N| G-G6ƢWl".6J@2BG=k<6XGPh8#Pcl!4X/ZJUrY%>C_ uyBvE%[pMz8i!?G']‹SY> /R|NRG>PnA]лH_pd6/pJl|k=%-.?Pst9è`-eq͟[a%)77Fa\؀/`IgAhwKjeR3M=[Y}Gm}5ZVeyL.1WYsUrTHRnK)6%@ȆKv)!F&YoCw5K]aT<%Jy>^{yؖ^PI6lZ2@WWx:ǚ:Cv?8^݋nV t=8 ~gE b/Aa\GEK3fYT%%Cu /J/h=yySsB?߿~Gʞxcf.'瓚҆+wx yDVJsG?οC3IU"n}$ ^l=2Ik/ѼSԜEw4ţߌY~)U;NlsVrs|HƢUH߃-nux^iT5gSL3/=VΆ*{ʸC*>} -:8cFP+^"!D(dU pgţ2*GLwפEmJù2WJ2 囇`mw( z؊/bf.g ֈ9 Ou "е,Tm=+';B p|y(UETl= qH8Hb(XOkLi[zSjmb=l![CE:"dp׹Ułcz[S }Mry4V*EsA*jc~P:j HEcR B?*[WKhz3A},_K'#JѴ ,{y+rpC{}4x>^ތ; @ H/F£W R.I4 :u򀼢6ӑ,x' ΃-9H )^oc0X!fVێ^_ {P3OuDN>{J sӢ;SSvrYg[USm]jM8<:FYsUF\22u0%d ;Vt ϸ1)өj'4=]cWH*e2k™ĊCjr"l}NaLF뎈t}>Xiu;Hv?͍`+Fusݭ),@ֶoJԭ\#VɎNB%,=h*+RJ[J*Ph_ß{v_}+tN<  .:z*2a_xcW}N-`U;PYi39Aw)3WcJUY4(euq9VX rWg"uNI`Q&7 %eJ_UyP?Df[_% TZ1{>nŞc b`(Cx@dvg]2y/hPvi#{mb!Y&oSڢ)SCdtZeR%6Zu~x:uq##f'6hx:xGFFNMy(1nzyWHd.On'%ÛXZZ#'*yL,+R%E v mѓYK ZCsAr\')hTR2KJs2K4RK25c*RR6_>1,RzrF&)hVX&$gh(4!(Qi:/YUx;x ';x;x6 9x J2lc7h.I,* /hɩPkĜTk?8 E 8f5ᙌYEW23O^'a7Jrd?O%79J4uiuVjRdD')N('>R`:S+(n&_:K#͑js(Lfp+ϝ-'tH`B}S8lxV lOY3n >yffh]5GSSk<m7x=x;f D&1l&X;yd+IfJ &l`QIN^o*;y/RgIx;f L;#?2x;qr  Eɩź}9&1E72Mg79}\m6rKx[m9GFKb~L  vx[R lenn`_9KkzgkEANfrff][LPa\o~:x[qr >4[VxuSMlEֺ͏c(fN նMSh v6@lgٙZN!+'"V BJ D8­bvǡ&sܼٙۺ'Yk뻄$P%h(#|I]^vQ!if:1J'Ɠt%rjUQXUb @ݰ9o釿Gme [c 7mtuZloaFK"— 避Bl>S~r-d`{D88^L yީEP0/Sl};cr~wBOOJRk7Ea|6 V3x=K*l"KB*o6 _' aGLSNj3?yMӝ-5p_V7KJŶ4L7Ax> fYl}u87윞D]~[g#yߞ;/DXa|`}g6Ӛw>PLv)5]ӓ'Gxn۷{-7s}ٓo'ƹ]EU7Lxb% {x[?L k&316U02005454W0022(55c&AFU̼Ҕ$  `oψɉR, MZ`8k&'g(hӸ6*3yÚL\nE: !: u\u,6Эj>yKrN~!gEx}mWǶg+j"g.9ć,_Fj%poٻ{gezٵk~>Çͫ|6L$|=IRdkRgc'K9'th˃Y70Y&ŏRp2eyja|y3'd7͆ä[0/I\$=T5v5O[57y.yaZ/WO0C0Վ`dgx`t$&N8\fӍfҼ'"1iaaI6Y/=ɰMq"rʏߘa2prOf/&C`-VL4?.0zE(: *C1IR`6on;HlmyllĊ+o_wu&ʡ g#b~ߜ$f'~[boǿ96[߶AXx\$V:SC&^u~=x{WGfn|udtvVSXVf` qbzI{CO !Di|~iˋx\صi䧃?)v`a`ݬD]H^o `LtOzIkّLzoOOӥXٸJ? K{v]=WlӸ''0I 1P v;KxLDITT'2b  .жmIeI2Ait>L>z)B(a*ȀA2EXim@7S{[;mL=NӦrY0eW,'#hi71$Ngwg899z98O1dI.3q6h_mr>x 4m xXkV̷ߚv+c>{SD(Y&b.;m)>\7Hɜ t<B /)˙9~yuv#e3O`24T# N@ B-G5Ud[A)l:R#1H a{*\ЀNv{Bv}{ts|G l~9"ӠtGkOq/  06hɓJاUեW?*l>o6z'4 NAv>֊Lփ}rlPEr5Q m\zZ[2J> -`)UUC"P/*`Ԍ[Y9֪c 8tV%B$FԵfƟWy0d w_09/Lp]9(@Hk[^ |X6-4WzSԸc$lF{kӬP.6*@  S_IA'ؖ',3 2ؐh]#& ZyЫBx`Antk'̝)rSiPYA-e; "JGGXF M!`EJ{6">keZX?n壵g?-hSTRUA{)uHYoCC+J!1*eKʖ^I c_"!(+b` ęUzYlb80RSE&W:Y͐ |pMTk]DHv~=~Ԇ?Pl7ǒ2NݧTZWSP &R_VQs jkC QFu(ZE_ F{_lPZZP~Fϋ+Cp<0H$f+4.M^.Q!My?F{&@Aq?cj r4Pbb5o}d iٷd}tE)Z"Ɲ5*!;?.R`m͹*.?n̊ U|ΚT̗HL&J抡Upe~+O3N@|$gUzJKXzPNj m!͌ Vw?˦&k7:&e{9Su| :_ʁfdQ#j''t٨XKFt_4Fœqr`qhRp&=/Wn5͞Y3H3`V L /N G'\[;i1vvP2x:$g \od (\S䃁y֢H#DfWQur_yg41M. AAWdsSČ I_L"(C )ߧt hB3wKvRLCMmn2 Z?SU9r|f/Tl){{OaV]] 2ar_K]6sk)0%T sqiQ2m1=@69kzZX¨|P=8.|H.`T_ .wy-wT4"{C8*9#h$?bC@bT$0.7EIrya魲^|_vJL7 [],$Ap.kb?x`YTF:r="LFa̢ESTWG [w`ϖ"otdjح=Hՙ: &ԣ T#)y## ה9 5Qtɑ*7Ϯr)J] @޲@PJn H8 Ml6eѿpޗkcD͡Ҕ kb xsp+k#YZ)j T܁ 1Q8sX<dD$'TBBLNp źdDG:eI>|T@":4܆o}6<YUT2W!jX%EEt1ͼf#2OFO2׹3Z9#!d c \@`bYF;G[{G"[ v@0eߣnKf={5(lF-*BѽpariC?6h> ;H,&+Ĭ`\ʨ2έ,eKOj ,jC Ŧ!Η4}YѵUvHծwI:ӈcmQ?) Cm/$a惮M|E(,CpV&w-?yŇMFvvV;~=֎HE6P9?Z}mP}F$+m!}3>̩2FCe={lk%#]BCė2@>ީ`/_bhJ""L:v"_tOzRcGޜQc웋sx2Sk}$#8'*mHs.O:=9Rlv؈lCpiGӽN`Μg9GN-N%r{1Jx Lmy᪾)ʰ䨨]J-־;0+j20>/|(QJzL*7k%jEW=\2"]%5R3QSř+8:X)wk]88Nf[m~tQ, ?t)&SK2-BCpU+:8:hn(W4|M-3 ӧFwXP1 KBA X"ׅ"WD৫ɻ!&Anҷ{^gi4Ƕ MbĴ+alvdy0x4v|`tҫT#JNؒ2avfȽl6 f;]^pD. a^=2noq,c<Mc Rʀ54Tc(Gn8;8k:y}pMGow䒤Wo!S>a +1FQS|=睋8r$EwN;}ޮ!5q~G+E8d>^,6.ԃS3ePD Co#v];#P.#7rJ ow_8{RJMFz+Pz\,JhWg#sguQE20}x^E5X*vM7@@!T.G.hY4^~y-,@4W#Ns9aĈJzX-O="L3ߦGQ_2җvQbc>E ^ZNOcL-+Mf6k{*ʢǤox'E7U,,OU z."<ʻ[SJ%q3ðn J%q±A q;n}\ \Xu,eI2/_@ZCY@/a5⒝Fb#89lw`+nYF%Oo)fϼu*xDu55KFb}~Ue2\u̵!,tj~<$- *44\[TYDB/.RS6ң.&zqާWK1R )\J,1V(Q~m칶Eb_V߀b +hx1~Q'͑lHxDE|1 ,"p弜! =meYYjPiE7ݎ; {371@g@#Ӌ B!휊eY7rtp #pAכSuq>Qs\N1Jr8]"k?]dպXq`:͆iDP/ 0CN+GhV''Iw!-Y$Rzr]F9*$NCJkHZTM UT XM\6*Dknyj2jH?Fݭi+t/+)ʱ6"!'RyKfJZ[F0ߤX=)u5[+x(aB>هȽWtaQTs_a#(n}y*`&ݕ{,F.* 3N;v^ Sεv ϐz1Bm`0bUR7q'KB<*ۣb85L yoNFuRtq'HԾڂƽ*6yK#2oj)Hl˦7J_i&&`DAF,+p3gbEnܷo{=Z5#7{CՓDy^ N<^ނ;L>Sjy̎m֞9DΘ|r̩ mvΦP]^m Ir_de8b<60dq!tg?[8G26ѧh8f5*e! 57ѽapwܓĽr/(A` 4sE 1y_*(t9:$O:q5ipڕ~C#Z S1̳q%o_s, |}{wd{t?K7QV1$Pֲ}'s&c+Q YLs"hKsTy FS^UK2miehJ0dE!,("6N9/rq-ԔQ#nD"ڲ٢s`?Hꮨ{$u}S]^7n)k d`mbrv)?vX]]^Joꕱj7`I_Ƥ(5H ?.5%9&U3^iW~[lA Ee vJPxBcP vQGPB XV_jnTP2p[0pu(_t.s0Vz(>0) 5;Ji)avet|#Zr Ëyt戓\G M>l@5dB}S w' @( E&ikCmQ ]hTbb%.D yYa܋/s@`lf24 xϓt_oGD;{[Ԙp2HgUh(fgn2-@g^ɷrl<!k`Y.&/&Ѡh\.A\d\ji4jTz2f[}+m'd%OM~9XCJ r:Cq xkpiC # F5%xktӆy,ɉũkz%Ӹ89ct ǔ"^[& %g@TA"'LSHN,IP*M,j:ѧ f Y@=@ PHKсHMԯfO!: Ay]1/8$5x`-VLF[_\4"?Q =&J#a]ŹĩbFVrvxqiY eXK &_LOv3"gE0xzi^ l:'_b_y37"3kqI~[-C|'t-KIMKMQеTPHK)N@ 85$Ih2pzꢗY''ȱM e,/rrXUɆϻrm>+/RY4K,1'3Ei,i *$&lb}ap3+! ͱS7Uo\Hy)M_xBԼvFN:,&M`F-y0G!('",[Myname, Serverڕ*rQxiN [6`۞?gr6Tr4.δ O׎S򳭹8S+ A"&?PJI*J-.)QWmTTZTZT PPINI,IQS[295/eRX쬎Lk1R-i0J jBRfD?4*Jz:!!{`O_W-Z=.ɿ75J`Exi. [6`۞?g,5~ xXP09Rccase/' false -> [] C / _, _} -> 0K$@:% aR8'&v gx۸i6 Y\n>!8[UUr*3SJ22sJS2*K3K@"ĢT̼t+.ݔԴ̼T y:ѱz\@1es+ KSKSu jAjuS6q 9is*d ͇'TONr?S*UoD%8xi 6?=_ZT_X^1bܓ%x'o`,|K^;(XV!98Ua<'8 '(HT'&d(%j*qAUL>Ta\XgXk4hgNXM ;Ł,Nt8!v1lukq(d楖jZìVw Qǰ]ѐx (5/E d8@{u~Bp~rvj V{'*O 6j2:?jNUԅnTIJWrNO2ټ"=Yra3)j ;&QE "=\δU*Tjl#'fEͽ]ь{zo<эU|xVoL&@`0p 6;0Is؇coVQNVMLnkha)aTMUjQhM?T@Dv_}ńgEȹ3M0[`Al'tMI[Yi |IEI/'I6.WMf#\$.dEtI9%=+Z`5^r#$˓JT0#/+dž%{^ L=>5;xZeBv5mYFhjZ=nUkC„%RgrYDAM5-诩__ך7(yMQ4#֭z3uݘ 9*A–Zf8i6t6Ōg p€w:zq̱~7`M0"4 1`ÕjyI{Өw~Gf5}vUsodž ]J՟ w>*T=v}h¥v ɟSr# F1zZ\,e~n{L?V޾U/#%=<kֽ U|qքQ-I>#^?En.=<'5GK 5v+3/]Ɛ m6ak,Կ%ev=>pdpw <;1PCOx vq,L2S7dg\j-}ŲxΨX!ܕDtR~ͬ1oZݘ*l9TD!& X92(1(c D0u @/G4/@f' JLz߷6?9o3Z9|>kt9sί#uEڪ2ܤd%A6_& Y0Mz"R Oix8sU'e uS}75a"|4 e #ʦ,'-c.wkx9Y7JVb-NJ4ַ+=K=l\yCEP+j;N^FbZ<6E|)(5Hi#\|PRY%r`lՓe{N(']D3#U:N*}v J[R~rc68c܉`$h6C GȐIO~hb@t7&}·6_p}٤r/p!iF0xMp v\.@\7mȪ2}ޝОmx\50#9W?.d\N "%/]ʰx_ܔ7)-t :V~h|XlUY1Cw'\Nbf[~@ 1-7}]), +"R5,^<{8 ,5, true*$@@@3,r8؃32xvkqFqcc#S]CC]C#c+#+Cz r/20N`ǜS혒R_TR;Q@oL7<8"^rr''N%7OW,*#+d` ŸSK4u8'تMv)"6R[S 6Ol/!P__Z`h`P }'Ra bZ`s  9ݖeua<3]+Y,+vYlgeeTn~oysm0ЯjhiN~(=9> w0];c=xsS5 y'wN>?:8,+ɹ @FtuB<$uILzɝHfy4ĩĶ}& E?O&؋W_OUvH/>{{'H U! #x\e үWz jxcDJƃKKOEߋD" ͒fId‹8DZ hp2H pax?޶߉2 r= #pKĄFxi)aX,BOg-! FC 2B>6Vowg)rR}BxF :07RLS95>{gWz 7;f%VC0+?K+OÉe A\:g|s~q@TڭnW^uDS\7;w͎~׹vS!Ppzh8—iN8/Fg Qey ag/"q4dZ:W"(j. :YsyߩM$X%ueMtŋxYe7_,uy:J> c,̸Np6Tt޶i&& ԍsi:y?,cyI{PlAtw3yo qVfn0{QC>00(v;/\ ' gGpȻ/ZJZӲPd G҇~Kɡ.H&`:|Xe@zé/M#Qn|01:T?N|,ev|a8n)6Մק@S[wGр7oYd*i &`u[g%K` SYXMF:{j:@n84p{go&M(ꏠ!R=p=ʲIcwWQ1t'NjG9V ĞI'7 Bqu@^lGi^,-ۿ6/O4nf#$N^G0EAI"0K-ltϚh-^O]Noxh4(60܀ǓIfWAkFC<ܖ60ğKP|Cpg30IBSOjf1 :G]եUuq"4^N1guE=(l^"{} te^M\M*ꯙtB9m' x .U恰T(,;D*}/5քƧ/n \Jőxzt9F9,h$P#ϐє/˫Tpƌ _?2)XD`Ɩ]\5pP!S@3 Pl"zO)FD[m Ȝ- nc!*-Ĺ}Kv*-rZn~`>DHT-Tm| ?WDŽBX#f+oOh} 34$2* 6,I,6.ts27uT8۔G\Rl#ڎ3χ^ )=X?@GiL+u+/ܐTV(jd-jMvEuq.(征h;OjdضBNRaۂx~N?W^ _dY[~#T]A女ː/Ԥd٨TqsQa9J1)HAcw",p-f̊jlU p9sJĜRH +L{RvdEc/,(#'Vh*Jhjz>M6*ѣ(4@]|?ڸ~8eFBXil[W5 KF^QeS)*Q}4= 6-`I0R:8N k r&ydtҥ`\&7A,:ITV rR=(qΘVk r{49DFKYj0ɚ;4 W+QO$_&_"0|K)9Z T|oXj0y3%?m2l/0jQfVJE%pH*e.R-ZHI{*"T{#hjjBgɡ<Z@zSgpk``jNcH5 _O총C]]!̟G+0ݔՎB U?bgλ( d@St>=nxvB@%/nCC1vD80?$th\S)CzQ7Č*Wt~SzgH3}.LĈLrw߈8ǾP"_7%XqCU/ũ T/̩D;AL0 DU¶R&6e㌋ b &%:Z&3dVT{&n"8<RIe#Cpd|Qt3{92?l0IuA%Hi%$jv c{.KM$|p#j(i?ߵ=J:ȣ:P%Jزl.b4JZ4C()Tw8o.4]ɪP`?\C ]U6k.Iis'(aI.]-ğLD6ƞ`0s1A[y ۿOrUrAB! (?T"WKZjAyYlwVm7(f Ƽ> 0 <_}=zZs[ut)IѪjGj% Vii^)A-F1غG#ﻪz͊ ? xl @./fԱE)2LmS,oD,b%j{1nٸt#NpY_}90\ŒY;<*_^_n |^a.t:\],Rù"dLAAam|'7)H2S2S詖\mPÊUő悪M=hƔfBgD\IPsXP ͤ(I˄zt*R XErxw̏ ac22s `7U O'wzVjdQצiA~mU/i8Cv^s݈A6.-Ƿnw=뜪\qiWx;Tք+קQT̞=}&4/ d rJK:Yx \mYz9=7~t #Ǔ&6{z>iQI?+.b!mn} i`kx5xQ:E3/k/;s١ Oo@fT n]nNx%c/#f?F5c2Engx%c/#f?F5c2Clx)}uzX2k/x)}.[qIQf^d@U3 )x1uf+Ru>|\עͧu&2lf+ o4xۘ1u#f?dC0+xۘz'q/#f?Fa%7'21 &f$eiŧn"WRyFv]pV8^xx8q/#f?FaUILp|x9a_ϑ~-one_to0 >! J>*#?MYNAMEO x\msFLY%.CUd;;9NVXWRvS: "! 1 0h[({fD;ޥXeמwZ>3ϓQl3/yb#ݟWYQ!6U5?iG#s<=%2)pճsBѷPFJﱉ] >Id;j׀TATdvf|;KqP-uh@btM+ uOF#si_LG]181ZwPud<%X+0Giy%zO_/O~*>7ç/{w|?1,`YFY 6 2JFEA*zԃ8y"3'ME6e饬T,$&ʮy'`2`0taNb*6ǣhwMA|evͫ}Ç~o/E,^pOGqvv$2!.y &`2N"?>؎?L Ί2powt7:&Ļ_+=E|~5$/+@ ކ MϋAαuq]\`8cl>4a3<G经2. ٦'(1r\+i@s-fa!gk+Wzv{wjCu"!w*/1~ɯ qU vR)!XZd&&\K8IJ/O$&ZaLK?W7*6XΣۢb$MJ` r V?AG@!ؠORll&n'`4A;Wh{2JK]pqr&؛ @.\ʍm,fV$.u8 ~f7M*|wQUѲzQ2na|MGyPGtl6Fms GOl?A/C tȵNd 'x[`O0:d,z1szT02ߚY{ oo&Lyffqgy߰=Z_%mbjճQ5߽:zv뚳7GٸkN9fK.ZFDPQ92,\Cgv'GEp;ꅯ?O~O_A*$Ğ} )mL灺yxb u)Z;B'̯ݡZ--,teqIGvۺ1P85 y!*h'T>ٮy<128z$;xveo|s!t &$|^q#|8|oC'ъ5 e̼d7[TW;go7ހ+ξ3J'7RuD_`2e&GqO%B]%$~6NpO|t2sBӨئ Q[SVHٍ*TQ9DO(-s`N`B"IH፣3A\A~7Hurׁ CM0?|K24IJSa¶$̀q;+؎䛛]0&MYk80a yECĘ8#plJu&~&cuqcguZ5n4b;BbSLLwf@5ɷofFRyI샠_lG\2i`:Z^cСQL(*-5NELY+7E V!oVO Mb,ޤr=~  Ă Sa[c0mh0z0B6Z,T><^u)mdza¹9t*_}x|SߕuOm eoc#e5 ihrU˞FMt7۽^}}ٰmJ*%"wԤ[鏮V^MC Օ\=<7r&'2gZ9VAѮ4íYh1A5 جP18( R%<ڙ. pˇ0C~ (5Xh;9X$`ޮ9XcvXI@֍1t0ʩt: "-828uV4ίAu:nK:tW? b?5d(?N?,SӁQiHkX&A oW%vY5tX:iMJkZ".:kX,oM~Κ8_O6Lt1.ݪ L1.aoCX~`WֵTF磸gV+w,$1T3oD6t,*=9ZWst.x4DCwOzu#.L T@ /&M@oi!/a*@\^Aq+=jM~xpۅ;zQ Op NA%EpuK wV0z| 6/_Ay,s׹V?I2G[Ϣ&q._n1^qIEٸ=+ct-e<7P Р:yE.{gmẂx-&|< ͮ6}]t4ѥj\466QDk~HKpŠBu8/5۸3q(Wť=)쾍 w(?>/짻fMTqXD&DD`EMo6@MKE4Lnqa CyMn_[$ uɪsĉ3=\E]UL*ړv_'nex6쨆)1 PJHn5Yӕ :,XshynD0h]:^#O'M1hmAG50,"(BSIwY207_ *7@\9i>T jcej02j4/<iirTw Hp "]"֕cwam##Ŵ؄e5@JDܳ ̈f[0!{љI!c]‹l4Tv6Z*(fT솱PuX&4C?\6ظW{hW[mT6rFęnG#H-9vB!(mTl]ñl@H==S  HYG~ 6k F#hYQ14T @$Zlܰզu$x\z^ɯ6N%xjED+XH9|iGW(4;eWHQ<+zׅ`2}ثpV0'PN(a;" )@Φ'e;n;B;"@6VlHkIIO_O5:ޖrARV۞va2͞2|MT":RbjE,6[/ ȖjDAX8X̓`9:C Ssp135YT4-!L.5F&L~Gh& fbҋt|9 2P) ]\%26g{ .O&Ht!`~sa4wqIw6Vг ʜdުRlkP%Y`S{It4yBi"_pJ̠,642җԽs-q9O@Y(L4yP:A1P ,Nu]>w.T  X~]GPOd9r1òFk覭!#Ѱя"F܆i,M c!GrTJ,wus@[Ր+C@/Rq8_`n&"}5>1 :lܰlzI ,9piF\WA5nG"zbfǪ. OL+&Q93qӬr,AɌA$ X;rl 7eX3ɅxuN,b/4BOʳ(<RP<ɠHEs +斨%h[is]DJ G(_~}s3-'Tx*0 xL=K^^KZF*>JX @TLAto7O܀^X;ׄY<&3UL\;s~ ֡uJJU 7&yʕ#@kOmB_RAv8M 7*T8hY%ҧ=1LǴ@T "pmP >;"Ѻ\T ­`!!72བྷun_$9&.5kb Ã"@wn-,+BK-yl7ph]j[$e{s/x?0*5?J>/6l5H#MiEKP3}IM\Da@ܵ윥y9d_9U鬐.)\Bc"[vHxEWJqԔ_hsTږ}ܭ+]v#BD_k5pghd/_^MJ} ^&դ, #GW nE[Kt[Q`ΩX"֏vvĶrrHVFxDA0Pi*%^gj]O#ZW p% lzΫ:Drf%# '݅ 'e"*Om5 ~Y;tUaq5x.f5r a8?iOs'Q?r V]ۿV@WRo{wn.Nz!x頄*@h9S}Ϩ|uCYp<;ZD$6_^f"IX_vZIı磋}16pa% ƧDaUσnf$8NlfeDWhッGeQ͡iæ"d Px-Ϧ=  # >2y[X5,qtΠ[Z7՚<Ǹ"w;E1B}ɛKbQfbO\,꫖I 6)NMd|w)roO >/ux:{**!lD]tm7,2Tޙ6S]!eY5א&(qU"3$%LmohͿ1`<E4긾񋪔~lM:7SH#S+߯V| &o'5~CG%v_ q9͹?n4睽_~wGưk6>*=8 %4kńmUT V2) u&1lZ-=ى騴, evrِ{KH.Z=0Y:oCǞVHcڱfdpǪWd,_Pf>vJ`zhƅtTk~^:ܕ}w鑑3Vh-n[Χ3ؙË͛o1oOɧTg}'O%=tr㙊#KW[]o|֓/:pڪL#"n,#o]4|E#Ck2Gkd4gR)y֘}Xfcb9ڣ4[f͊;L?one^;tXN}zg_N?meHk9%2E_8ٯ7 ̵ d4 A"&`DXRo|HFlt29E(ڜ5:Sf@Jd5όᅭT_ej0NU$s tF0-:%\QX&!D<*O|"YY(F_XX#(=Qp+B6bW78A"aJ8] ~#r&[S :f\G+5ħ%*yw'>~ج2*k(ql q~ Ti8T/ Ú$s] BB0,j+PǤ`35a xL]| C9^0Wv#@]"6| x#/AeαpwX(D#9j *Cb%„L"hIcyxMJm$ƺO=Ur9ϡ>;TvSc%;bmcFMZDm[UnwjTo\aיV2T # G1*s9PU=/V]A˗,Xb*e}bg#ܺ\rykB0〕ɋ$=u^RѤnt `x(Z%\/-Y m|Os ncx8q #fS8y$4'k|xafQ:iKxa #fS̛EYG8FMx;~A zL L.nd ;txRkA%5Q-+ōZJ!%[(Y$eLrfSslL!|y^^yvgnXbk*_,O`$PjA}*Ŏ!(훎(}ZT_zs[(úҗגAzcAr k1 JZuk˛[B8p#J(A^>ӗR~ZB04P/ǷB5^\$cB#kF(GBy_&)S))p[8 vדHcG˘2OġCa ݠeQdR ^Ñ8oxWKoUVjoHXiQ%>6MiJ^ӴR 3MfsיP!XlvذC_P8N3s;yīDf.w I' ՈKJH9vs$@r"n5h :>-$! "kr [8_Ct-X"n*YIx;d>7B,iv"dLþЭ:DL)P7BVrl.W0.ݒy' d%g"T*й!s #, [J()l@pIX,"%OPXЕ& + )"Y9UvuBIΕP'5Oci ﷄnOFCxsGegQFF7-7"y,Ҵ%I^wȽ-4FL`֮/ITK[IF}T`#b5/XX2Po۴E <זb(K fa2$GF[0P 46d,5TiGVĴI8Cz"auߢkR-bIl &7Mhn2h3ِWߠu4 s Yz'4j:2ͦ>F MUXFwf)ö3aog':  lxN0 Klea\Bv1v7-xR^RZ=B͑xR,5sK`|jXJ\X-5݇q5쬱:Eqj(ͮ,\oczУך58=`,ɦlafFآO&z~4O+$*tgrP:)osa kfQh7S׬,>ʶ"H8F V]pvkjH`)qT=LF{kt& 1([fJ_Vs5k3DxrhOY3^":^6a) mS!  z4NmusQ|uwUoS\Wx9Uu@-sc(wAxWKoUVJ& p`e,MTi4<E̵}u'2 VVٰ K`!~;cxfy|;OF2ߒ_΋r^Ix yP*`9Lp>`1,Ͽ察|6sfe]:ٙsb[N_LO/:[-v(d'q4O"cegjx)`(U_&G̣[3ɶDGBrFmf ~y*o Dv4w lObMśzGxP7| 'L_ev|i+Ty-Q\+q>|N]vː o˟@w2МۜP-cY~+'4Ec蹋a}IM$%xP6 hy4g[_\{Jv$e ~(Ul4ɪ&65V&~c- 4[a/g=x8;QT ]s .fX:c/ SdwaT;iģ,8JqnL ţ"]Lne _mEܸވؘ P kVmucoi>ag-7SC]nvez =: [=$ ƒlZ6Ml6j-th"/(MqL+BNhzf.g eAl<c4 Fu5\VIRX(\ꢋ.qtM ,E;hn~a!~w{8X\IK<jw\x?`Fz}(O& ‚?)k(cUjq|h6:" GZs6GEͧ(^'qgY/j;z)ӑ^8VT7#@tx;~A l'wmG XZBxu }F~ bɎL2NlyB`ZHN77\h~us%|Ēn}[H\L3,vxk]g5@6 Oɞ}P0X{&il1"xMROL`Oeh7A#,L}&,fQL00hSo$ă!=yPjŃy2p8r-sBE~~IX-ą8bX<cR/ݝJ'sHRj`q kFw3 oQDY:b Eez/w$P>KG)L$9@? zt'Ehcanb1pTK}8`υWp5<(-5<Bˮ@wUٲ9^cw.Q ebYO/+eV;<yje]Y g4FQLWQl"0'ZS 8u:tjۥvdDXl.a!GGÚ&*rMc{6uIWT`4{c5zsk@x[uu. P5(%Q`s4B?U4v2E^G?%q!`R˜T;%~qy-1U)%DY%QƂep5naMMxug~t%K_~FCxj < Eɩm962 pxj Vm?AaxQkPV С ٺ%mZ݆)tڭl(b!MmlonF)OFpo~ߊ~wޛ!{simRi4,--AͰ&Wa`N~? 3H=`Mto0VM0 oaQ9J):teM0 @h XUϫdavKjeᮎz1R- $)CtlSed.l$&Ʉ*:KnL<0\PG6G,?cVV@v)I:6ܐ!(0TJt=§SNnlq쵉ܞMJжi@Z\c2\ nÄ'Its2fci/bQN*Ex>YF%C#3]]#cK+cC+S(ܢ ^;Muˊ4UR23LZU6b<ʴ 3dcN͙63LkcTPPϮr|6Us`aYY\Z1YMːS 4}]B}\!&(DVzj i%'Kp8:\ 9`IJGA,]YY]_ZVZR R9y~IiNT38A^QՅ V ˡۜ2K!(?YA"W' mxUOL#UOe O-PP(t;i)Z`W"Ŭ"Hd>pә͗xMȣ,L*s.yAG P0Jϥ{nϥ ] ;"RN%4\TgGւhIc[pq"ۖJh"](dIUcF_wƍ)}Ȟ=5+9DFvu`ED'%Lݝ\=û4 :2|f#1(ۻ뚨Ѭی#ejV"vHɄ#["n4MQUeK,JE;>e[RZ\|F`:l 2(^?o&s!8鬥Dlf>bʊn4܆ͤ^21WkԆC w`j_ ,wй|K:n1&4 חRQm8Όt0::y+H"^5Ey&H vS\ds[fY/M*S>p{qɻ\ˑVQlEr&]" VtvLH~z_~쥴h5ڷ: x+mb9~&]ؘ>{x-&[v- G[ hIUWj9'.Yuμ*4xؒ=쮻^U7K54K_d"t%P!#M,OD*šRK+1 Mߥ%ii't)ÛqwyXm43W7_gRʒ8eS$4̔ '*k'Z"%/THRsAJEFL|O"ҏO001"gZDʫV t@$>$Bɝi*bTæxIIʌ-X.x;kcP:% ')C(&LӺlzD/so0]j0$w iWDXZ-dp<gg/d8ӫΎ{_WÓb e-eMgHP~e_lє@> ,j~7C g'ʣ{:*y__أ8xH T9K88C$袧w{^tvH4]ٮ4ھnVw@C?k7/kl!q,sP};HE>oopJ=f4%օP0@)x?,"F iIDn˅T9T, PKM` yr'G ~#a8hseNo6MWѣC9' moo@mliϺQd uXk^hģb<UjAhᆴkhmjL PW~t"UֽL27gt 6F1Ւ(g4ahD?Z1/,X^80Nj܋GxSi ] Au{MPW#miQNx?m`WSd証8]&bƄJbKankvUدC2FFG_0O6P?3R T؅k?6_\}>?qcKj(xLn=*˺kTU$flom6ec>MVrk3R["&e"=%!S*9L#|Zl!(!nW;b5UȡM]KwǕ֌nӅ5ڐ-OnKLEⲗQJSZlHXXX %Xc_N:{7{)`eٵSsxAmub< f=߈xˁ+l\uUq2:n_v$U n=o6h&qiCBs4LD3Aom 3/}]VJD wSz0fHM[ _t<g8Q%cƆC-Ǣ @U23NI])3)&ȵ/-ʘP@Ma+.O(׼u-@|p\鯌z@QF6x?ĘY*A.J6" tq6+J* #CF V[fOXO~wl s QlUدw"] 59loǧA5sznfZ\(pfzoEi t|5hu(s Qp>[u^\aʫӫS󝽧~Nw/o4_/BՌ#\q~{$O>\C91jxx[gؕBs"Cǘ&qbG5c 3W9EY%sޒ4FN|G>Mp=@\t⻨^b8|b\c/ U.;_ -ZkKz5裌kuTUтoC=j!g_Xnk#e{Ej*kcڹ_%e_xCŮg㈊t<ե SMo0%V*I|feоT!UQ¾&:fHP.ҕ[IpFb;P+6=W?٤Vdp9`_UzY^39QЍ ~);bq'nbxb}z#f_v+{xbj#f_ 'pMBnxb}z#f_v+4xbj7#f_ 'pS !xO:6  RecPid =a P4,( 0 PData). P ]x{k6_o#f_Fa&I\`ss,!Y2Mͣ=Sar,gyM'?<<ٕ_h\5'oQgdIg&/<_Tqfa\bz\\y%E٩%.%ŝ6I3/xצr/0Je<8x׮!E7?/urb6vl̔Z9t&[sg+qqr*A~dF.f.Ɏb/(HYsq%T 1DO(4ո͂|<"xZoY+pc;(*VqlX hq%LqU쿽rd'wwvv<;;;{١0RO/J/]xNU,gv#Y-74/>M@鞎~ײJI8BcI l0H'TC:::8 .i'$A\:E9m&zwtpx^V/bU,)ğ(l'-~L 4KY(ȏg:': ~8P6VdʏU?m]8PqOĔcE/N5(,B'I%)(DT]?cҢ68^PykAyԀhfh8DqyEth,reo~>~{ᚺ?ݫ/0QIZd8+$q[p#IGWԥw+puy;'AR!,T&:Q?Xlgr{D{ D8`S{ aH^0g=y駙d^wf=Ʉ}ya&:SMNE.-p](;" -ٳg5~v0@X #lƃh(e%?N˧% oL'gP0j +՝-{j[=ft:TikZ;2 W G1鯴TI啠ҡ[J*di[|8--vau0uF aDZdž8/ʟg4 LT^4@>Mz1_QYr.ͼSy)ܸ7ޝ\bz.^W9Mĥk%Ee̚0!r~ eOVRN=P۞uk,I"5Q1?{,KwXfcG6y]5#23eKe:sxIy39Y l3Qd>PtpqTSmhdLe:X`{KT?: n@i|nZXЂ!ҩ?,xn23MB!1Ky;)Êv 쨲]0FcG0cVXyb3<,%ld0l[P1$N71*e (p؇LÅ +rH|zSxuY֗n5iǹ;c\?pr%q-i&Z~,3*I4rb;b jCDe9V%uGvPFHQ`q` n=^QQƊ Nw+l'N{-Jt#:5WZMϔ[nbfi;YfhrRO:F;똎)҈cDe, R~q6ݧG ͒u2ӬTF֩i6#s71,#IkS9<.w=sN Z%t9K|r&M܂D+\T-aU¶Wm\ ; ,̓%M[mNpeI&]TD~Gr'(F3|ٍ08n i-8$@yy['=vP!N:ĭCڲ (ǰ6Ρ uklJv&Ɣ]76+6{0/mO3? V<ₖic˘IRD*]#HJ8/RW'a,_]QQ;oxZ3iQnI MkQEmUґ?7U ֈW4 v"Zb YTrִ4;Ștؚe*v|j3}Kv&Ls+SS>&BkBKC|(Һ7dKA(qX|`yIܩE?1/t%3qSͦn m.ER/㲻O,lF19,xe}"ܜxuQ( 5Q Z*Jw\6&3o[ծҪwfy Pa w>% n<,ޕ=jlFrԼ<4fʋTd c8]簴ç]VOMBZ23r_ %YA[悔͐'q.Ӂh'cvZ]csw|o9]G)Ÿ g}?jl&ݴo`kl9gƭ+* N&Fjz)wt&Sv!R^*|{Zq|k]жLCO+H%搯 + {<+3(KKat!{sOjI")-MMɏzo.&~keњL?F/k]f<\qU x Z-;=, X3&%nA&; qOQȥӂ^»HV؄ =;g9JMmmrebo6Zx{ @ ]$۲ m\=/{s^V{{{䯶'@ 4HdvN޶E>ԝʹS_<#W&I# A(7LyHTcǕ"D4a(ΝX:0R; D襸yx ͍D؟LSaui:j6*9h'+LqK)h;|-LN(bI7Y* '"?,d,)V*Y"1xy-PN Mwa)Ym2-z?'-Z qQZH㱸qߢ0͵._1,NAwN{R=}&8<)y"K8 ,F\]D=/G_c6N*^lX+,;a%0Aд.z;h~{0u/ѿ!i+3 ,d| 4 <1u$ڕs OzzYD m z-.c#L_q'=W?8=u1̈Q]4 CZf<>^\GQ5Y -A0 X/O L5n$L DW_QZԉCo#Rwn Y:rMM$]Kw4=V8$Nd 'D3!R#nq@0HdNdj8ǾCT`a8v,,H4cDMee&[qC2KRAqo8 ]:ԆZHϋ/p%Ez" jZP k`oݑ:Q>]tvꢉm;WfVfv/;Q]1A84=*xVfDtquȒxa 8C?qje3.sK 滰ŧ$4hl=8lW|$SxĔqzz d6jOI(-Թ >Ԝ!cA#KBX"]uA>ɋ~o`S}wV]U PpAZ<{ܒRBxZA`u)@ΕXfj}̵7pWw,y|Bq̳5`@hK;ȃrҺ, WDmIny4uCI.O _rOSR1J1Dŝdx(t0GBun&A c0OlgPT)c&g(,?(,W,iI^RAGxW(ډf3OuP"ǒ85*uCZ6*Ciͅ(te X-Y UIdCԽ 23@&%/A/lTSǪ s")A0XF[ӗf(Q9έg)1e::tWJeN '4C"Z&Syߕq u[=G_T-2-p2}G0[of*܈|5FqN(d5|(N.ըCQi J\DaI#ΩXQ'Z-Gke m֨尜*ʰP[9Gv,ǢzXZ8D(d{o]?!9!6Oz#q2 kd|eE0sB&֬6e_ň[Ćf(] z!{o3p0D(2FZ Rـ3G5lWؙh傌*iFW41Q3K  bϪPǩ/2] H_䇋OzPd =_K7 XV(iXvbD֨m-Cdt ""IeFx9+'Fv td ys3#bif]iG,ܡm%Xp<Aj8DG:p\AYҪXOY{3 u< s5`xAuS ߚ;T[4gB*j<+aB2M"l^R:'ZCjVF2=B ;mWWXc Е'?g)%*E_ɎO5z-/>pPu cbrcj-0&,aSb Ft\$x#CW_cU՞0fl.!jG}H&HsWD\"e.)_un8x<ݚD;w+񗢱CӨWDR%Cy%$n'hd>9,2GՊhX {]'7$2 var DHNZX.`dS,4nxrEnrE$*a8L-v[_l,;˿$C@ HHK43rBދ XVxd>E]-<ͬZV ^T-E6(z_7u9 ^zMeNB%PYU"Rb]3|qxO"faQ$H1eP'G*5swp[4S!_](§T W$Q\jM3%4YJK6HVl/Vii7Z7 MZګ  c=dW$H) }UI]L˻[ڱ负2qKo#|[ǿR₿RylNu"򧖕C`ZveK; d74OpviVMԗdIb: pheF: WaFwh!YLJ%]U+{eV}(Fh[wm݇荡^hX" s4(txXAh.]fN.(:gł|>y%: !+OSնHXi*)& (lԒZdpM3du hZcIEע"y)ȮQOK,Du(]y?s9ܺ_ )M+$ɮ`bs:EX1Fp f;)[xh ^SRTY>,xeAK0ǑyYx.z)DZiTx 8Q"~$34,C3[*fjZ~FjXX*S.<.5s8Z,![o`o_L(i&mZ"k#p.Go;p>_\\CvNp# Mcx2Y!s+:0pR2q+)((IGL6BPx@n>io[4}GxKXB,0-iD3>WLengthu.6-w@un!xkhؠhY%Cnx}{#fOv&kn'x}{#fOv&i%x긡}jATĒ Ԣ 'g  l#qqoGxkuluܠd`Y1B&7,lxkudAOpA#|$2>/xku|gABAA!(?9X7?/u`Ʒ ff=X'=<_<惂GwxkukABAA!(?9X7?/u`Ʒ fL7b|L 0rf[&leȊN!U+ G⭐)CF d3xeyȉN(W$/?PQHd$$ gpx{gn9#^d{&!RrS Hxk|BjYr~ĉq^^jgX)xX)(X++ZZD)$VV*pM\"0O]SK8OC]%(,83? l,S&ޜǺBټOl?H0x{ltd )L1vmc\+lxYoV9GYE5!iZtK24Li5Bs n/6ICι0dhEc;{{{E+§A`0Pf؟MABќecmg5q8V(yPiM'GakT$B=Td93 9~ ::8' _%4Ogz:78#BjGpeMITG){L#z=F\(iF 43`)2 ᾶnL0,*CXQ$%=/oJ bjqU R}o1bͭ AT =*;JDL.'$ 26ސ2c)F 1X:$$ )C(|HfF vCw[n^w_գ4+"l$}3xWwe.nԤVݹ8:<<:n3VP޳XyPWjs j.+5<&AtQ2=EIφuZcZ'_ N;3e(pWڏa/u6Y^GƧ8?6[fOn޿ǀFE)0 r8.($J&eNڇߞJ:e GF(!Xa/+S,Bȷ"$QO+!]$s՜N}WO +;K5n%fEDL33SE톡z1FAXu(,} g3BGgCPPFp4q[fnS4 a2kՂXr,6LkY5/G$d`HϷ@ДW^%υt22=4ZgRU3lDD<{!fZҘL"OrM~*{PT1\ Y}>sB 7ho4l{U @5]ij '{XXvj 8A9hU,y\֕8X?c8H%] >!cv' z]rNMQ?p{*#s5m0 <$6QZcȹ[ljS".<8M'OS" ugOqp:7q3A&O3иYR-6C/.&`VSxtkd%ES6 Mq$X >8;ɔfdO{0A'Na|nDYly^ӬYZ*[5u%l'(Tlصޓ؍ሱÄF.;5M0y'ʲr[垠6$<1YK̚_10Kr%" U7MQk+1aibA'!kNfK]sIdgU*y,'x5md"-0Q0,)$N< ^4%Q6>yyT*6PيU}Ǎ4)λ^W:+ sld?E5m[\e;)>&l ICx 95TH+J Jxoj#fsF%[UUĜʪ"ԂbDĜ|̼tҼ}ɵ: 9%V٩ũEey: : %%EŚ:\ @\ZVGn•(ntx55`hٜ1L"v x5k?7x6{(o ɇX&@y=27oBxk|x)#fse/xkܠBAA!(?9X7#.ًqU=)%ص6?ceY[`;**BM ''dfu;.NP*lNfqIUZfNIjVᛟRk2@Aa>- I@9IVeEřyŅ4u]Q*_ 5d&3HC>).Lͧ)*8YksSfԼ.(5ٹ9'G5;~' i ` ɺ⓻' MesJ@j>6SFM9TU܊s6 vpkXxk|RAA!(?93#fAxk|# dAVViE%;ي9RÊb'3qlv.-svp Nv A-LAs-G2r?ANA)n^xk30&Z ux{TiBfqjYr~^^jB@iQA~qBhAJbIBjVbRRjQfA=SJA3 4>٨X/(GHLPT(J!1'"RAk6m6/Px}Tmo0 $m&ѐB苠մ2klgwK[|=rpA<)߿C?8> wLf91 gzwY79-#;"d>.vvVT4`Ƴ|/#"DvCTQr`)M X*a-&/ËIliwd:G7TqFĚ.%{U"דe2$,l mtcWR@yքL_g٧'0|k\d\5;AoOցR%8Up0$lj4$cZl* t:[TALHm)R>W6? C#h2éWxl<VT1xp%=r:^T71Tp-Þ۩C KN#`)3xx驊]vSb޶i!6lJu=1PT{`8T%7ރVh Ä]+ZZ৙HX8Fl4]Qi+lqlY\v8R:ՆzF^if>7 õREu ʿ!qT;jЦBjͯqanpǫ!d)xbUVPLhr5=>8'5a2v==; ndxzɪ♲6 r`}xZb`nn`d``k`kd`hbelheh[` Y Y[]'33Isdqq{x:$nƤaũ9-5FqiRq H⠩2AS!h{r]xjVVPLRMNMIS047W0205050W02522ۨǴy*S!yxʵ53-PA!7AG4UKA=XV15$ SжU@nn``vx[}C:#vjEA~QI|bNtFK&nZ;xkz2ADXB\LhvĽڄS+ JsrRR2Ӹ&b*&gY;%# 'xkǥb`dab`d``khkd`hieh`ej4Q;Q7)=XV1\f+ کE%99\y)i\\A>PzzYIIE)U9I3of6eɩ̲4t Jxk:ũb`dab`d``khkd`hieh`ej4Q;K/l.OLL: کE%99\y)i\\A>@ zzyeE93%Of:#Ra G?xɍ,M\З- rxkΩb`dab`d``khkd`hieh`ej4Q;q^7LL کE%99\y)i\\A>>N zz%EyE32(eƧ$$%yEz\*Κ @=q3=}B]\'h%<&Gbf4~ +xkZ9ADT\H\p3=XsS8'rUeRR2Ӹ\|݃lt=t f}@uu&(hx:k*pqrrhC lgpi G?w (EnI,.n&xUYA3e+!?x5K[YA3J71;5-3'U/3O\RX\lvLLnax;9UYA3e4zx;ŹS[YA3J71;5-3'U/3O\RX\l%(&ŬnxιUYA3eb E70xyS[YA3J71;5-3'U/3O\RX\lT"& Ex;͹U[YA3J71;5-3'U/3OHRHRhɗRS+ JsrRR2Ӹ2R 4J3SJK R2tsS58]|݃mu]C=]BC\<Nnd*mr,16n3xʪ♲Ѥ LxUYA3e>chgkcX0_PT\Z.VR   rv wT(IIN,JQIkri9%E%@k"FM $c45᎙|QQ2+zIo1;ܔ v'`z'WG`McY!),Ԗ+.΂Ē |l \di>.G`)%Ő x_:x}C2chgkcX0_PT\Z.VR   rv wT(IIN,JQIkri9%E%@k"FM $c45᎙|QQ2+zIo1;ܔ v'`z'WG`McY!),Ԗ+.΂Ē |l \di>.G`)%Ő^ v!xee> G?`cK'fO>(`76KbNdi&vLU?vgxUKYA3J71;5-3'U/3OXB\Ld*hXFA3Dx[EKYA3J71;5-3'U/3OHRHRt*#vjEA~QI|bN<x[EKYA3J71;5-3'U/3OHRHRt*#vjEA~QI|bN\RK* R&0%!eltx[zeC8, x[:][YA3J71;5-3'U/3OHRB\dNa yIťIy)zE9b%E`q` gxGN̜Ģ-&L,tLIjn~i PSGE#Xa&LnFEQB+zI1;ܔ v'`'WG`McY!),Ԗ+.΂Ē |l \di>.G`)%Őx[eC8˸\RK* R&0% }dMM OɌ,Ɯ9%E)=Yb*,Wx[cBƽ\%EyElJ2SK̼\d.NNN g Ł O?gP[-&sb`1x[9=CYA3J71;5-3'U/3OLLBB8J!(57?/EAYVف=} G?O`t'Odh:9Q ur 5ٚI&?4r\az U Q'`h D~IN^Rjb.WbNP^(5(EVp̡ܺ * iɓY4A*YqHEx;6AD@BXH8J!(57?/eqƭA9uR2&2!sx;6mDč[{9uR2&2U@xuFmwu30 lBx[ze79,Yx[mFmF [==. 'Wǰ` 7=5/44)>/?%U/(](,3y= 4EE#-3$H7ȁ[KSn#puV mRs5'btх8:k0`,+$k&1Ix[ze79˸\RK* R&;0% A=x[eEBrQ~nbfD|A>~>Ɩ/VM^(`70YbNo&D^Rjb^jQBjVbRRjQJ|FII^dMrD(Fx{reaBRbJN~D23 nx˾}BD[seL(%&rq%X)((LdδM4/3>%$Q//KLONV W7RPpvqt|\LO?gPɯl&20r,Y x~]SYA3J71;5-3'U/3OD\BRxD[seLh%&*pqhxi#$K! sr&2OfgPX f%sqrr''++)h88kY>.pOL6u 0AOx~HYA3J71;5-3'U/3OLTPR2J!1'"rqƵE)R "x[~} .O'Ogpf&ŧLh뒛Yũ*KM.âl89Κ 99 *~>.@;bNɴp*1,x[XYA3J71;5-3'U/3OTDP42426RHI.Nh\9,#nZAfnqFbQjd/ Fgx;Ǿ}BkSD@q0\|f%&%Wd&ŧMhˋ":Y-s@dD ?x;fb`da`d``khkdZXF)$fVN4n\W7 3YA8#(5ers ar5x[HYA3J71;5-3'U/3OLLPR0J!1'"rMyu 2t3RS&1G ^x{:eD-͉JMęQRR;YQ<5 QĔ<H}|A~NX+1'JT45 M}U+NUԢԬĤԢx+5EsR8rt fL^d8T-x2PYA3J71;5-3'U/3OTDP42426RHI.hȥz2PxXYA3J71;5-3'U/3OBLRX L̢rRsR&OIJKJM̝P\ĉ/.- (pqhxiꃥ KS2S'3p8$ŗT:LȘ*)Uxr@YA3J71;5-3'U/3ORTL+#s+C(ĜԊ9SRs'>qK &3kLMxTn@ =wbPphohJVHI\F(RUjˁl!)Ź88;ࠍ9_ԣv ${݄ ͨ,"bK|8;(jղb-u&ݭ Yg ¸:(V8%?`31J& ǣ.+"b ~8aow]$Jjo7¢$52>Brd{&U;$E9\\XMv(>4L[k&:2(ҜAxy}WIN^Rjb.WhP(>L/9I(GlT4CC\<4coyԥVpq:%bhX dd{&UfO?/8''3/94%UIASIor3s'tNfRLsLqqNjbPDIA h)e@ Id^~~ 4AnUs c9U4An> np@9Hi*pqdV -x9sThg{0 *TD@1\*1yezI)EXd&_dؗ 4m5qLܛ'3q2kh*;y:hN^"a@#A`i*&+ÕC]5p9\x˱}{jVbRRjQJ|UNf^Rjb.Whd|JQ^2s=R|0Vpq:%*hxiƠ(h,+T'odTEr;SFL]N{!` ^Ewxy}m}hBqIQf^zAQjA|JQ^2chP4/3>%$Q//J;y:`jrjiT q ҌASTfTTU^Rjb?&hS+ 8uRSqZ29Q\\8mSB@&U.$nSdM[7s4S5o1xy}BWIN^Rjb.WhP(>L/9I(GlT4CC\<4cԥVpq:%bhX d@&Uf3YʎL s).IM46cQ&ob~ MZxcm}hBqIQf^zAQjA|JQ^2chP4/3>%$Q//J;y:`jrjiT q ҌASTfTTU^RjbB 'VK! &5A3?S!(8+&3bf\\]m.T` 7E;HdPSdM[7s i,6ʡt\x97XVAO/&39?L/)51O,JF&d灥61`uCxk>>5+1))(%*'3I/)51+?4UVE2>L/9d>*hxi`*KrRPx SEjECjQbq*>&3*ah0:FU^T\>(OI̽`z$wÈ]\xk1(3/(@/)51WAO/!_\   rvUU@M)*Kr QʔeƧ$$%yE@i'/WL\.>> *!.A1&0AӖZQũZXSdsFStY!`rԢ..BE;HdP.Sd>37s,|U {xqcT{nA q  9Aή 5*9)ɉE) ZzE9\NĔԴ _GE V/)51WS j$PD6@Y0nbW- x1aVjVbRRjQJ|UNfR|JQ^2s;R(}0Vpq:%*hxiƠ(\h"`j䋌VNNgRTRшtʎbə['M x}L2d.'/W[;R@jLAjECjQbqhgf Pzr %KJMU|Qdt^]O%W`<x!9I1a19F.z@%ʀTT杓YL9hB^xWmO#GE%'ci (w p{8b6hZPhӬ4:, Sf(.}[fӥ,.5h-IMOWI%t%\5qiUe`/gbT3ͱTqLa_ԩX5֐ 6^`^vY JC4aZ<]䡵 ЯϗWc^_ab=;vy+<,Ax 8/z]Kp?:ip5\z{D#xJV3BۭL)85q yJꄳ;)A&y8Wŵ 4:lJ2!}R$V~4fitB-DAH?Ҩ"7]+|iۭ?jdd4VB/r ͡hŶ/7W8hMN͐5Qk7\i+M>8ه(ϊ5vx5 I~oˁQyB>t*&v%TAY䦈oyҜYWr&* B UHQᜎ$G_o"蟶nǩ 25.D  ת)gEf8C1JLU Y1UmBDd*{cRf?λ^HmUؿ;6pi -Yt_9;#oeO"I \KHzsyoBz^5R' h]QQ4J5 Z>r汙Ủun;!9fVD++o]\ "mߗj#fM;|t A+xV1nE_4σ($ Ї@j]x҈瞗_r iq N8GϣձPi4p6zFgbHIDy`hn|]G}|#-iHHl`b~@Sx~]uByU+ K6|$mڐb.n̅AȲx\\ײe/ą =3KtR+ \̻TL4n4ofFh+/!- <611;oLs֕l=^ܾ͵rSŜkbCn=_&I!75Y9.Ш\GtVy롻v#6G=U0Il:L-`IcZ!~@7\IB,WYbfk W  bׯ=,`@-؍|'+ f=\mk$TS_mm7Z@*\L*@IɩFu~0/q)ԭ;9-y<օfk/ZcaC2/[qxAȍ$¹*oO=I͵~|8O{|hߖ_X/ËΚmSp/$BuzjW.aUU3Mpn@xۧO}1#f.!&`fYxۧK}vԬĤԢ̤%:9Hn1xۥK}1#f6!%XoIxۥK}#f6!*xۥ~Vy1#B@Q~rjqnf{F&I\`;34և,.>G7 f9Dx;Yy1#B@Q~rjqfF͉9|^ mx;.=a[qjYr~^^jgX)xX)f%&%Wd&(X)Z*Y[F)$VV*pMƢ0Y]SK8OC]%(,83? l},7qM. 0nx;|Fy#f^(xXmsFl~EǩG^R wI0P'罻R i0v ¾ۺSDOwO<3곓͟L Ik%fotq~~qzqlP%HA, BLi' S%4+ѢuIPe&HfYX< tʹe ELP&fsڷY|.Vfh^@n)FShRݨsȖ*&a3ZDsj67{sژᇡxS˚LnajH*a,*:,SE7qBF^ܰV7dZh WGd͠Ym|H^}V@&`<ϒ,?̣36fb'@7YdC]7nC]0K?_Cx˿\:yAg*<0?u&94|z]ֻkcFX/VC3򂫂#J𣓆c'i GMrlKwMY@R=Fc,(ݾ\lB)eVG6p]J'6vćg+4Cxp$n57l&1AMdu}h 'W .d2l xN VBڨMyEs 1iW |:!}mX0_|S3x`t~?xwք5d^dPp?=*wӫXy.#ũ'|9e=jC;x/H"kl{]9/<^r`՟xછaU(͵`" 41sY DT S1[2bv.#g<F2 ~ g8xs- < XxhW1 rP<\07+TȕHgc(/7'#%]) *w .]!7='bN؛H`8n.h^~UCdf _Ϲz+Hm|[Fi?ll xUFu!<$xQsFuSi,El̙y%p%n P7/Y܋89'ۊ*N/'\lFxۨQsF.\\xۨyW}skY0Nj̫Vi0,FZQj*Lk%Paµl 7_`caٞj#xXn#}WF,x6Ѭ6I w7;$۲ɿTݒC`Xb9UhZQXO+Shچ2UQfyj&[c+5*ƒZysZnIS-Y(`'XѤ]'rMLo}%mֺ" /ۍG1onW*]Pm VG ~*zGN1N{M][pPS@TQlf֕Z"Vެ̖g&ҵ^Cb ?/G=,9ِ?:oC&o|b jZ0žŌr5hdqdFtZmo;s#.ՖVdVT5q&7IU9 *>L!-ʹI:,h (ym> Lr4$8߉v|0[jʦ)dWҶ, "]0msQy0 6IX;zⅴwݖWU0 "N+gKR {{EꐼvpJDRT,(T:HJ4Oؕ"XFqmB|u|suzw}uHsDdE(GFEX9dx=}XCcv𣘉RP?s<`48iQ]ipl0TrsvZ9:3+^ z/.08wثq|}=lK< H9H͙(K1ΨA NɎj4:d&+l:qʹ0P*hmj}X:Unvg^~F'߭s>wq1r/$o+BDhr75q-LRL%]fTYTu?O=~.Um)_&/FtVZ'e)փm%F"bD8Ř2׹YQ% up +g7ɫ=6gn7}+]3Px'2"QJDyD'&Gxw|ǻk(I0e$$QߢDؐ8 p%<TʧMCYԾiD7%`merh05σJqՔwΟZr`D uz$d|f׸hlªlY <^ 嫬Ʋ42U$K.vF>NsA+}8!a Cf+>^ktrJ ˗q6xH!1rJM(p\-q4-LM)QvPs#cݘ%7zqFzs] +XSrd֤}' vBE3p)F> ߕ uɏJmunhA!3\5Y"D8mM|^l V0T.Y:P*3A8%"En/Px m/o/Oep-CϯcYXɚ3N3$Ix86%^xsjdX{vƜȊ )<ƈ˻%4(z$"M[ފ,c֬=[#5Κr8mս/p}vo_Sn6BoFw~gLY쏲@M}`.fsA;28#Fx1[q|Z Ĵqt=uODcĩR%|@9 %*O3IX^FRP ~>mwNfYf4 ㎧HE@"eRN`l p;WPHM'BfY2ڭT* yhff޽L{VTJcySc 7yQ:MさحӦh6{Hvm!vKUVCZ<b0(wκy:L,TsBy,!~ D_;,!&qd.ҶK(/rDk`L%.gT!Κs7ytCl(j T,:}`ʎ @Eҩ&t̻'9Ǩ0D*7Mۧ7:WZB☄3l;y1AAƱ̈́(pEDdOJnwm[^G-N* ALbCPp@qj.Łl|喒 ނ2I״@ ŒRwē&L"bBҜ${]T@2d1d:D:Q[@ZdbHRuP:jR^٣<ɳ4~>Y>`W2o– & =DIAT ;2O+ sTy@PXh{`~/"+Blg{{{͋?{N1hA5%xA5^N0D9U5Ұ]8O2;XTg„T mYoYc@2uGhlW+>a]cz.Z$mBW[ۻxX-Jlg1 ?)= 1UM'q>üD:+JKAHHJ4ʸ%X< )E5+ܝB\яrYp%1q0QDʣqDT~@Ƹ3 2]Ѻ#FD7\O(MO\xt7-jEsL\[Ayw4^Qd:責`< Q7*G}8JFx7X`2I1D5]P;Κ 6^uE~0dG9%W%.XŸ5^k訄j5MbFrOzGu?"TܪRn\Gb@e/d_SdӤ= /лn\hbBHQ+}aȗe^4Ҵը&8kj;0@X,Bn'J &2bJJȦtYF5"ڊO E]:KgJ@!wn0-l-Ge# 7  @ߴOZW!rp GAhC?V%CCq"Z)o?}(2]B74^ +?, .>-0FyWrr>Y$^%{c-piuyut #ˆ684-kĦm/)hsBrìH %%NWgCj8BP@NmOnb)TYrnGEKSNCL+:rBlQy(bR 0dmbpv yҙτH*XGPCqk5%9*;̵<v@F ܓvі~{e ?-&a?`tШؓ)|3IBg5MmDЕk~6/C4W88< J]x9PL fHt>_Lmwo/wM|!9C# x9ʓ{9T}}\6$1< 4x],3M!ZAI35'>?|r!v^ %ԜT. v s U<=is 捼+ORTPqus٬ Glpx{{ZͲQ`0tܝѝ+W&Ƹpo0n\kf mtVsw/YǒͰ,I /aގDt6Vb2N$ؤpAqe\RLErZJ8H*M-gSGe"iQ2>U־/?jkg] RDYÊj.FK%MaXs]!ּCBHB$ٿ _]Xvn&s H* W 9ul0H}NQS!-ja!p6ċ=)/Yrx{>[}OؘSr6e3 *7pN^7كCv*D%"dU=MDx~VmzOXR7'YC{xZ{oFH(.Cw YIrgPJRv ~3.mM}v^joիWtF%i̦F$eT'R_-+ c?i,k'zga;]$S`;LҜdh,)(OhTcg:Ki^IFST3m^^G|JZp%b2HKⱂ\a|@cs1"bL͓·`0<MN1Rs0momm1E0iG|p:R\8I"ݛNL#SE5+qU9B|Q긎H'X#\PEEh 9Yx4,z,6Ʉm%*zHnJ,7ELS?`+(}YPkaC54+\IM-giQMFC$E7E| &kGw3ãYi& !}!X xVEvUKՔZבs[LEXI,2y JF15B4Sh9X;d5 6c#("ڏVhH5^{Z{=ҜhsNA/U<5+ سS/7uL`Mty=9uUqS8 jjl(-\-~#v]a]Lx) YcOx/'#z3]9s7] hz%cZ-l5͂4]Cf)> RUɋ5rnjB<,[ :?;?[wUS=0emxhzA7@S[!/_y=++.D7 7әl0A5F9fDK5=g Dqbtp֗wh*F#{y(8KmRMф3kSYXY2818f2`:iy"v\f)Z9d/xn#[g{ڤRBvx(WqIқQ`rdWIc]u<+K[8qdeagJQ_jYL[2'6' Q.t*볚U9!xsZ|S'z޿.d$c}%2J5g}O!r+$yCZ̑s4w= |r%;9,.ݧ}|.gᖯ8c1,oqn&ϑ YC4!x[Mz|&^ |r& >3[>s6}q,ܳ |g|i^p|/ؿmIGsuܷut@9ڽh5!7PGoA b4uP#X܄VA; EHqx :agC*ZG+HCqs ]bµa_S8Lu tuXܤ:zvDRQ ")&` a1(`)B)vUӜJ,L˄T{ꎲvื $_ +ꚣ-)0u{?qޚa y$??e>k>OYA\.x yj9yݡ^oY2U5P[ }yŌ~=gƔ{aΚ)%ˬQpVϦ,Y n"y:27 6,vF=)mW,*+dV'Vt|X n>.Xž|p 1x@mAlӔHqn!n_9Dr1iB'֥}A:)EFk6iQqlw\>(o.56Jz^`k=eMЅݢrI'r%땗aqn/\e3&}&Ҭ-0ĕ%NhafzbKf?l'_~<1i -m{t!*])6t* =|ɧW"V@N5! 獩 =c)>iK3tg:&k}7K:јɄ/ec /%Zɽb^ jڶx5WzqK)赛|_7wɭW[1e*0^ioq?SmC$c.?1}t3`b&~,215>уx0Uli]n5.;kcT3‰9Bail+XcZCF!`|u/0qZ5]:Gͺ^kT*Y!ˇ 5]jɍwێ!E]Ccy 9 S,ʥvHEMi\9, ghq[Y= b(C1VuHVM$Ϋ/["/GC0A};[^"$ ,^ +ũh!826P*.sSv~+iq=﷑->/>Z^J7>b`G!dvx(RR7+nR1wؕ!X"jFM"4 = bax+I'hpxg-^Y3 ճUszU6T.n_PI0GJiC[YXKWmzG.Odؗ>"lV}d"̊֬v_gcX3ҕ[IJv=/p]8ENb|_t)L 崩?>7>Y'5+it&ss),|Vjgi $e*ͺsdoZ(N0s3YV67|T:7Os}p?h=7c>S cɣ~"."IxKsN X^ mh[Mrzǿc> z| +mrZ:=J*jcbuqPT9jF`hV][峭z O`yq&IqD)Kt<=a8"G!c'=f~U0>LP2y DZ>̛P&knQx'~#fGz/Wlx(n7τtd)(x'n#B@Q~rjqnfF&I\`s"τtd8 \xp-bB7[qjYr~i~^^jgX)xX)f$%(X(X+XZYZD)(L=EEanYqJPjYfqf~$kXx7?ґ.>3FxeAk0;-SC0 %;rcjKB2bf(_Ӥ4kfa>ק/#D`FUcϣgߟ`:]TF,)2 @l4ܚjL^KZM[ XeN -hWC` =`p 9d:IvRoP!Tt1vLraӞ.fͣW?XFc.S;wEL;uRc^D<B+L` c0 w"7]39̼c;hNz0e#D&G2'3s]0w8fv %0Uڭ9Xq]жJiH.ll?qکuە':*mp?z@J8p?ܭzVcx]1N04L"ҤBPdbȀPLbKTUR W( \ 5xg{wuӑ9}ܳlƅ`T B||v sjV EbP}υV~YV"z zb1SezrZ9$t$d -2&!q<k\J59/0nXn=rd ؜ /4J*AyAĆ""N}Ɖ+&K}/d f" ZA''zn+o3F[/n=x;n7#f_.xwLf %7nsaL[exsmBjYr~ĉ^^^jgX)xX)g$((X*ZZZZE)$VV*LV`RAǥ[VZYg2CEaL%'Kfx˳g2#^dm&YE YbxkXO*613 2006-09-22 08:05:50A613@ʓM#%N"&%&)''t**RM+  "zx;AQDT@L$J!1'"RAeC*7e<>ُSrYNG7RUͅqx]oHݏG4D1 sHr@Ь@ִ9cO߯dm2F]-!Ɏlw|Cs$2Avir tza_my6y͆eY!Mdo]2ݍx6]FNa2d}]~2:Z|uq4Zay_5ȱev,`֚IJ\.}1 1\+:I:xh^<<}#Dg8KgP@m\:1g;ƀ%2i@;$[{3]R)n##Ӗ0H a},6LP KX St!^S/4}b4ezs_A×{hxtM6zȹo^s& M=z9LzA(Yal0$$iBV@-0DұAt9:\\}SU\N' ĽݐI n S.$`9Zr>~- 8!T>0WPh,pqNSΖo"&e1vho?__S9.MYtZ0&_]}Lr \#c~Ca5KIx{{ 510 "ƧBYh4 eKR UGҶJMsMDo n_F.'ϴpΰf;?l ܜa.ʧd+>ޏr42sI Κ .?=UH,eI6J$u ?r~`~u/{C_gЮ|he*hmA[`_Sg>N|q:4> xc?T}N[g@j=3))͊u` c`/t{wvAr$31]lX #jɜLJ[&rNc(+vg4 @]**RF7pѐo"AA4ORN*8egL8?YeFfp`z91&eB\XO#nGCɏ1."kL@ӛ+[w׷~RI*'b7a"_0lX]3KT85.9I\ϋnTˡU;3,W/VZ%Iq>):RTK]HhyB6{ _Ҍ@ ˸Ĭuu aJB7(:tFnhbe%xe6)ɒEB+ hڬIy=L2qBC7 qr58B++!4ő&Źޔna8h\é:3~R140+tZ E]3;%ǮL{``gvAMi̧2@_Wh fh\`׏:*he* vя3;I;>N p1F) >_ӌٕ2rk;D2*18V lžkÄ}iGvbAaϤ^r+`Tȭ<s-ZS&/%|Y:Fv=AIpge3`_yCocHJ%1w'sB.I"WZr-LbXYuj%CUA~8M*TohZ ЈE1b]V Уt[! @?t102c|ѲX'bCW%;lsca/2rN(GZa*+jU(j<ې iNbFaF'X3R*Eu&9Hfjk.Blt mxG !ߐX`6_: ;UijNXI Ϫk8SvVhRE#J 1c_UB/sݽTmkjRjVZ4֊Sqݱ 0߆Qk. [~{BzDYȆƗ/k5 @MQkB u}#|zSVX/%4f)BGpPH[.5U`ua@SiSv)N R`U%hN0[Y<3 [SGk ٖb>6 d.}ƆO9QւrFwF%}fo%겂j1JA2 32^?h@L74tktp_[ECoKZm =KyY| eY%KO7"=4ؤ]'kꅊ׎[5eCVpd"V.EY2K +wv[e-εg*Kb,G+֪b`udukS(azmSUql;| R;q_DG#J즂ʔ!&s5+t^ڱ+0,W$GQy/TCO!=vSf\n˺LT47AlIhEzxqcj픢̲Ԣ=710mcxqmj픢̲Ԣ='11lrSdEfQ̭Xb([x;c~ G?`0 Ù n\x϶UYA3e63txv\YA3J71;5-3'U/3OHBPD$J!5;(18l+ی6IhxveB6w> G?`cKfOd q RUӛ ֱ|2KݩS^-bUb [.kmr`Y&#A(4` rUV-#Ä(">/$ -3մa$ύG:O:XHcӅT\ ؉ 32TCpsx>`-?Lf0w+>I:3MDY*?3wH[~Y͂Ot{?r?Jg.*d.rwF&UExqmB )EeEOVOnf ܬt +x;vcB^LjNJbA|ZfNIjQ|ejrΕzE9\Eũ ғjTW 2 (]zs#QFS.  MLW%&*`1}jF-A X"x;6mm`hkFyfNJrbQ^jQ&/D&1%(5- q Qрj)KJMԜ})nRRjQ|Rf {! x;6mĉq&%'em` x2A?43HVAO=rt @\N^ .N r͘Ԝ\ IZGJQo4f 2?Gjtxkay9==kyw_kfOw>tuҟ Fm,Kw275F#] iaJ=%:4N{;qlli;L+zSK387w@:y",ͯ/iFVӼ9k4 !<i^'YfmgϟŘ"I,;1(i.8n%/NǓtj`\ģkPM$*[`5AQ/Dh׌ױiF5u7Okkf rл40ͤ{דa> R@|hv`8m .&3F<FWf܅`۔eYܜМ`Cdd4!Miq7n! fMfRssٻ,%׭Q?;7K6ϒ]|~1֋l=ZZdωk xhOcr8%H9(`Ŀ]a{Oꌇ퉾e!fVXfI!k3@5ǖP{]>z!9Cv%]_Ry5?ixA5`G}l3U7:wשL'!ſufӾuAv=|Se1T185XHdBɥ5q:oK[=ߙ|׾ZdW?6FݬۺHn?kļO1T5v?\HRjͼI7" 87_I?bڒsdtC#M2R}wt!ߏu8XFsh}yXU/tQ~[%n7֑O2#2ͺp8%*@b!`MCɈ:q0%Am LBz} *!]T!l 1P.p.b( Ub7Ɗe:\Qb(wjly]4N =dɳZɷ֕a{xff wC<^&ø39a7L Dpw88m^Ys^W>uB|Ȭ6pn߽+@ `?Wa|.2hJ+% 6ƛ doye _c14ͷ/^<b`)T( "5T6}~"P.c5~7@Fl [l'_4:( ' K;[Au8OJp#^YQ!HfXPТBO]bE%> {H]3RAbHycP#q@b$l|>C1XpO09@]_vb6dpk8?|]'b8byLXC~o ,9"rPGy"lbg#R܊rd 7ͫÝv(G)|zF]$nXFW24"bj3Vf,7,IIOnG~ 06 eu:bF|D_8Bm.QYX:.]cQɊV!JlLbGRI(޽FJ=B٢i嵕h5C?#$4Lqz8 i:lEC9$ F'+Y2Z9/4S-̴c]^*`r@~ )jɯPe]*ڦi6vy{ C/}ÂV |={) nDStil_Z$OF&bIИvCrD {W濖P } n71;}eEMh1@;GЪo^}F=Ve6ןt@F !jS"fV(4;y7dIDrզم"1 @^./?^ E8"V\@e4O:k01_JxbN+qֿ26jT,Dp: pLa.aPK8 ƽ՜UH\`,܁@_rwn󳴅 4Vj7$kXqN0!^Kp ONKnY᚜ĪO2 tsURROAYKqJ '㧉,S5@b2l MSVe?PֱuBvc,}zhltzע*jUfΚ}̩)g_&5U9XP0xb2RQhJq-v.g-U!Z<#h (H]VS29?פKpfh:K" ߖ7XAtμFu-מ3ϙێ)bWa {NyOi]m:eX8Bh;u=xA1IBVK ӲL l b#bd긴 UM7͛d_i`r)in",WȞ Wi iP0A>f=`G (`[8jS-s+"e& ȿ6(sj)K=YadW4)q9^IBf.EBaE1'N&n8.nXsfq|-yKqs Z֍u2?Gw;p r#6:^ЈΑCH $Myw/}@w䫭1!`5IA.NONs%iHf*/ MH#-d$;D~oÒ$IfʼtnpPG ȀZ=S[9OT?JW0%Zzb i\ ^U̮J*4DtWMtYJQ{yc.\_L2ͯV5𥓹`fmWvo~r%c䀓dع)y(0!xByޏޓ8?IrE^IKTQUc; (7,gHdbcBd6D!ʗ`9F1A@ĥ*Zy uG/*M i͂PNL7a#%J Lž<@ue@Bs'E}"/Ǐ] mY64V Gs m`c{?65W79ے^zm[vxIzRX8Hܸ?'#>qÂb f1o{]|<6A}q]E  ҉`vZB 1yN?v].}7iNz]t(IIK[BGfN"/}4˷/ef rONg?z$`/cgtUyE-,!=v|3}/N%)>od3"m2QHv-& la=CrxTk`41!%p1){?F+:,}sTGة7+͢qkG@ېIa">>&TvJ?Z498ߜQcoq­Z21ܙOB/ KcE> zhEB{حnMg;̶q{Vj oJF|yʽ-'÷0Kݒ@.*XjsRO ocԖƠ3=ĥ1t>bJvoWg}?$W(֐}#ic[4~LJ-BkY9*<8+ dž]mX=֒ǍZ\Jr|.AS: Gb(#A sHT@30 tj5Pb~?FГ 5|,iVQ*"3a<g/$`IP-sut^/<[?IHmv~#haaݘm;_:0mŒ8(`Kw-Z\J;-ab<zN EIjiX,.B6d$F 2o6k%ӽ>;S5#w_./,6Va/c؎'o%1f謤X<+/g¿BD1pP !pLkSq1m]$Dz*''af5  -A^<禾}q|F$U@ )ó럣ݳIf Pc˸i}lQJ9p1\*%Dv^ yAf]D(5xG~Yq s3(1a4El2P 9L;႖{y B灌ԦOh !lC /S !G)泦d]w@{H"D 2?ϻr,b;a \aGSz'/$(dLCtaGTH7@yZOPZ|2%ww7 w@de]lBxAʚH2| I5Sa }Թ2Up!W[CTl&fLҰZESdXÎCI< ޘzV0:PRAڠORQafh vS_M?{敶͖ѡ:^e:<\\ҏ-/HMysXz2g%n;%8B_Ӹ5̹H;۰pNUhLlmjWV0Oԅ-c Cѕ'dxi9lqv[|GU{*16tD{CL:ɕXhgd{p& "}_s,ڄQLZ.#vY*SGݟ-RkJSK4O(k'nWn ʯjDOM^w,l&e}*[Hu¦Hݢ({tתQ|Ѩԑe7ɶJ[ŊJc-f% œǠ(+=c9$cْDgخ5Sd/hPS\j]},MO/u/9+KX*pʹpr1׻G ^}:xY_޵ mDbn55> ӰZ8rmՑ 瓉u mbObzǩGuA?86I0EQXS{œ̺8?bu>"4PSa{^.5/̅^ 4?/cYNYZyOC[>U.r8Ι-WD?MjMB |1UPKVK*-=+e laX | = e\\_}5oqՅf=klc<14o!/UZ NjEcjJh‚yXв+`9Xzɥ,ľ+ \a<08zBbmU#]ԎiNgYގp1dS`%vaG͈ш9:{62.ɺ/ #Y%3~>qOrԋ \#W.Ey+v d{i L^Xl_fÆ`{~ _8M!/rg j4HY6g[G D"pvhC82^(}S|r~ HM &ze JWJ`Pi{X W*B^,_GYd1ތe|٥Ȥ5 Mp5CHZ!m:(f)H@7C/ L:8-#Ij7͸E8dH8Z(7}mp!2rq% ݜh p6'Y~j/+sPXFQ"ZdJ"Ӕ9tHɐR 9,"dQtar] /2Ӝ:Q6Ane.i)j͡#rw7B.PGd DlsdeLD"&r ٦.ERUbC"-\NUע! Mx=F-C;N;icDYcR)ݵHc$`<67*2;G;yI`p$HsG t1A8cUR gh;A09JƑ(em%-_.ɥUKdV9IF>7kX$c s1L۶Sl2 _2Z)̠^i{6[YZBn#n7}۷ ā*LBP6UtJZ1o_BAJH+ܶuA=U/ҶkkHK)- ؃BifW %n“^gOc3R1^ ?/昃bART=R񃘦L ,Ɓ+.ɰϔKX :FF㆚я50z#hHCvXl:,JQ/òzlY%.ò`~X&l}"]WRj JZ5ڐ6UyV TއU `[>,]e젂l/:H+/ItC@eC5P͜۽=LF Tm[ifi뜮I&p܌0 99i=kՏك~\l| 4fXv~d;N@em0`aŵ[:!ݲ{y+5osC۠ !wY@x1(U+2"zWF=+.ɕ| ["K/ї7Bhh1?^AߴJٙlW A'N,*(1I!̣Kڠ _f9Vg͠0s}Wwo}Ϣk¼ztj*xCaEK -Q8&)^vhr<7R6J #h8 |FyyoDpw-DV!L|=\0Ĝk!ch ҔhKNd6|+dB$1]G%$PG!>(l Bf6?&5%)grBIFQ~FujQQ~NJjr~JjJ|Ibz|Nj^zIF& Z*:3~-ܠ#t(f8mWHƖY u"j:10Y Ess) 3 sڵxҸtPD]e,t KHa"<4&&YVo 䜆5c t)4Rt.-Zak*L5)(!K:Bڱ #CA:1u\7Ɗ]XM㞚l]cbZ  暁 MCՊ +lD6 t[*<ȲD/;s tv،s<ydgOG$-:V7}ݲ{ٿL`]AekqpБQ ќVFepi d$:yWNUhMJ/`3{6]HHwm=vWTIp|0= Ylg0"N8kʻx$-x{vZ Vl|EYIIEzEC6;1Z)$(Z*X*[YXD)$%(l.|49'g+ovv׼ʂɖ"i kx": ѱ7+~\2o<{#$9a5'_얞`o oUaaa\`t`b^U^~Xhd敤ŗdhDj*hk+`a6Ԝ?,(32>/?/5Vkr~懎U6I|x1G6/ڜ2y +ܱ23ua;3myKs5R"Sg0qăD'1j.d9G7'kcndx{iZ 86x :67~xmKLQ3S}ETl!FiR -&4tDyt`C FDč; >wq!h1.Hdc" [e==Ol{x ,&hQKӞjUMNgnu0O7ͽ8C4>+^dS$"IЪGMTK/2"1C np'w^CBH>O LEy )t0s96TP(qVk0~xH:=W3{y}Ò0>D H62a&kE]B"&IPkA'sƚ!ҧk. $&rp$ZT@V3he"\¿U9 Za9T3AװC9{EIoR_L9YvlTJLJd=өͿ ݻhhR/6%h9+U-+DWa{,a/" @Zt \anثʍa 7=IB>ruODBψG`&SeX6̂9]iQ,ZLY|d:5vC[+Id0@ ' 6 stO{ YRfjV´1Okӭi&Ҏ6IxWml֝M`le>|66p6ر3,ws{:JbKO"Uꏦ4VJHM( UV鿢Ҩ͏6ݵ+[7;3r^)PkvIUF]:]];;г+}TRiɇ推J'%siEQ>77HFIE1&|"8gųI%r , q- GѻQç2 AgGFt?ݸ|\pAKy‰xX.k풒׌4Mp i\U$֟J1 ʪgh"`M.W}SۘQ&vm@LlC^v('y4y4&4:J )Q;ȇQ{)2Mef1b&{H[Ҫ/Hou P'@"cI j<"m)&u l Dh~(iF[WJIMe]]q6YHc/o|rB=678ĩ8{yzJUOma˥yk{hsh`~;A<:򢮤Xb%f~o˗Bײe!Eѩ<+j| 0-5%I9 tkםi}ow:/9݃H~s zmzd9uM-CU b=J)xA}x%1~UM~dp82Pg'pkj : @oa2Gˆx^aq(˸ģ"$y9 dU*D ?X3ĪŤ.8TYkp q5 ~'_qOH%\r5Z: Fʐ9Ȭ•kʼltdMT&sU &WN\}xd2'g"?w.@^BGYF:| ~\^D5yiʶRLDMsdCI ÛYzZhhfj'I$EÖR,+)QiU(Q5y'HgE)C +%G`S ]a]QU`·zݣϦ;bf/2DM"u4úQ:e8R.=3}E#*%qL-<E3Fh'V*]% *@q5B GBDŽTGng)m )*s}_߅r{NϝpcqPTfLvsqkI$H..ހ/sQX=-72 qf^بh,UBK 3|.kXkpT^2S>Nh!&p՝޿׭sg1K3/~xzԼT;!/;W8o]V JNAxT w51, *:qIAf6W+"Q`2ITíUW_>M*A?)c͇7Q摇%[G~nv}|R1=|`QlR?}6,Oq1*L"I;S8YoV;wt7_ [v4D+TgY19Wl2s,Y9xTMlE(K'DrūVזb;?n`\ۉ]2f۬wu,7]TzT!UUW9!qBB+'zAn'F3f͛=OzDD(wr]46!H TBTihZ*$}FI4XQUBEE%ƝII=[% PοCiZ \e 4HKZw籗`!Ë0̿[`LD[FRUkB;DUًQײyu&Wp7NTNsNF _ď5W#LL]7x(!͛1;/sd4U߃H[x&e86cnBcw1\ty҆ Enבޖ(irqZKt"]J+v@#aBTcg3A+TQHE6JBM/Ϲ ׈, Pj:TՁgܮ#bǛ{8ђêd eIK-"1&+.1;_ iG+oЦ-YTAҡL@2v@% >L&RCt@:%LC谛aUJ! *2f4`v, e!г{\Bsu֮ǽU6^ΝbHZZ% 7.+=g<+dҤ]l'lcQD|!1`~u`?of1Kb ̼6*Y"h^P S4ؑ뇗d۱=N$F?stݪ6|b$WBL\ g)e?i#yN/kyyVi>9ӧ7xUR]LW'4X9j8% mSl昮~_G 0DMDILvcČI-[\25D 3^.-N[899ok3@ oS4}A~ԡNw{\{/mI{rDwsl#0[6`2GVZMYN0Y롷fkĐm9&OD{ ˳Wk\U'32=@܈&U:v^)Sd5!ȴT/--leNc~>)v153ޛ:;[Ϋ2cqv#T]?0sn*`Ktjͼnl6 ~=DtN=É4j,W v\3}RRz^v fRQATIҘ,R7T`1^#HTS2Ucq 2û'Eڈs+TZ&:"H!?҆_F4j$>.h ^{u'-aid+ٙoSb!E`jN˻pEuDu|g?:|!-N;͓vN/ZЀFs~|т˫Ed0EdeF`1M}4H@r?7%`b pnQpcϻQlDŽ"# ub8cЂYq{} ~tPk9!|X'_DJR|,ڍoT_JsWboڇe:A7$[%FofR|X[P?sCu|F tÁXQbU*zTP:'dĀz|2RBXpmEq&O+Ar6$r83% Jz"ɽMzeс2dxg|g̝aR.Au4)@h.] ڵ.VsŽFׯ; )Qsl*"z*"|q\ZyZHr!)bM zC`W_(I{~-C6)/L5z@`y%ԾR$C'C᜛Mh/,1bAs%RW_jT'x!jllCҞpU>{D 65UR%{oQ 2~c3)PWgŕ-;h,.-\OPTa0s>pTy>xTy [\-^o*W*V˦3 /ƘKioHV) q\^SiZ}A885R[̼EKն Uapj2յC-#`e+=кFOWu9x8`RF1ĉ=:tLcZzт25-z-!nT챃)Mogl4Tj϶-@/(듙-u$C9O zg}K}-» 'FQ#@!1L'WPHFׂ४7I0:)cu3 R%>MwTVͅh^ zQ-F檳H?Sq9rEtPmTx.1T_)ze&ɛo0 'jZyE` N2GR,=j$zRxe(6 95%M l_)f/O DV=iQxZ},$ч E_gGy s;h_M o4n ˓~ӯe(0Qܙ\G{935#'gQ؂5*I?) 9ׅ&0a v KtztA [!7LI6BUj{j)~ k O dB.װe܅E;x@%&rX`{gmo[EkXXܺkk~׵J ~7oOuaE4G5ǥυ4h6Wol>>&\U*Є}dفUlKmMw!R =E6<^}r @VUFhpC,DVC" |t QRu&nxU Jk֬bm S ۚ 9y:J7$eW&Ip .Tθϼ6)&ߏE0[-T)b%\)_Zr@|zFں@{ ^,\6t\u!eS 2gtF !tH~"#xG57!Mǒs-93UW+?Z[jt/wo3|*($Ɇ{F#Flk6)ý}e>cuQ0 7(io]RUx;yC#B@Q~rjqFͭnr *x;yC8#B@Q~rjqFͭnr nTx;|yC#t-#nxkztC<#ZI,-xkhf|8n0VcW'3958J=g-,Һ%EEYIIEzEz\@RHxV[o0~p!C({ O۶JU*n͹,6]5 tH6'|/rū,͙9@צJSRT4+e%TUPWvE5pH@aѫ+]xɳD|DXǹk өsc_ I\PW맫P{3වfeYETA/m0q\]c[B'!e͠.DK7_Y%_N)s_C!-!tNB`tɳRՀY&~tȞy%!Bo?ZSGHOa:㩉_{Κ '?8-tvS^%63ճ/`ǾNebOųNJ0Mŗ?gز2i&D~F@г.7c%z9jƙQګ+0>}|O ö?At7mPKјޗJƝy l–_G ϷVnMnOZf>xW⥕H+{ OQuɃ;qptڅk a٦cjMIWF&-Є0#xVmOFL~)9! mO 9H * "=pv5\o:E-V?̳3<;jZRV3:Y(2kf0Tvw?CGhy}_d!(T.5I7X RhX!3M CBj7dϰ˳eP|k]o7[-*P2F/)`Q@éB-)<, f&\'AHre§ XkS79^) T,dP, BqZd;σk p|}H֤{,<8J +&̂Rp|͢?{/CB ǃnU\z 1e)#+LO m.BLk0K eHS|^_;eR\d!)i|xPc۪_؇>+B2"4}$‡sn[Vu|W#d%+:ɻ[ZRgx{ۗ~`JR零0e>'nρid*Nv\ޣ(gZ?veչ"Ao7R[htSE. N>䳶]L?w ltDuq~`G˔P9)dCAC6DF *P G2Vҽax҇m U q8WHdOu+rT<B)MBćl^X#;xj#gr:sBx6؎%`pB621(FFƩ8Zju8-Nx[wLc?x%OvQޑ9O"\z_$MYD=dK?2ahy#9Sozh+V7c߇駕]734Qѿ6QNؒH;H;)n/I]:OO:rqrl"֞:Q+,iN9JQNͣ)=9~BZQfttE!? ?Z 0>`Sy|5*QڏQ@Q[$<̀g{1(N >wJ*¼3IaD<)s|kJ,XOћC )JġY@T3(EQӭFh2,Z@z mT+ 9W`3x4:P)@&xŬɝ o)uJєԸ#I٭M#~; Rԋ@4YǏ.f&M\fh~<2 W4*2<Jp C4Կ6N(/oQ4t+4هSf=f j~ jwCflx"7 o|9օsC#JYzh)w Ψ]2cwx6_&u03Ш:CmvCZ (PlPe48(+bf$v.ZʂHN V`Vspʨ<ԥZK+Za!.=V.{4@m%fm2x¯A@c  <^FT?Z}Ȫ%1j%Nӂ[oBfhSPtq<q+\ 6X&ҍl/DjhIm~/|yc@r㌰rYŢ:Ijk%>$vJC.+Z  -^o $ؕxbP 8vX+̈́*N%q!QufQQcG~F_'7$.bQ#Y|HT&gW<-ۅ1( q dh|~(q|uop@{JҖ}(o[ez A+leo:m/ܢ&3omh -h7?^Rds96;)|{n K?.u٩N:؝WĶFƳ C /$PT[m.Fa{|nAx۫W}#f{:!&n Zx۫~_qCbV+X?s*ArbqBQjzjEUqiF@bIIjQjBPjqiNB~'gu~BpIQf^B|X$,ZT_XQ*5/ Jqqn.6.q* x}QN@]Euφŵ Ӓ%Dtєјf8CSY#?; g3ss9s{Ll.zrMpɌX;ڙ;NyC <!!(21Ai:Z~Q,~*R71!35V2}¢+/RHR:rصc}}f)!GjQwrYWuq?"*})Os׃KIȐ0&27tc:0o2HhUN?Zju-nnPxx_q#f{)ixؤQBAA!(?9X7?/urTƷ ZJc9B8sJSurKj8t89'_+!ȹY(;jxkR|@AA!(?9?/ur 4Ʒsx xkRlT쟗:9Irs ?APxuJ@иv+Ei֍-j?*RB$4fG-!D/cNS"8e`;瞹t۾A2Dʈ:Je==88S8si+k#Wh(ce5#['K* $Q) Tcd}87 Z6+n[:^ZwjY]/k3>Ӥ"n4=:ˇ% > *ԎK| )#0ӛu=*f/'L)v.@ӵg`4Qbde{CoAri4e~3% :zugo!x{Ba-#f{FM~.?xY{oF;s.K6 z-'eCmAbK%e[ofRNbi8;`A;~<:Ϧs? jx興nuaJ'~^KA (N}CkNvT_m::>nA~t6H,e׾5?P8x/GqIr,utrՐs-iAV̧ PAqGM+qrycRu%\neI#O~\:AG?63,bAO=qOߩPF#I:IXC9}mW3f);`ms5?o8| PZ!'X6m|XYJ,R~LT3`a9u>40`iKm#M5y*XBXTB `4Mg;c-0M[ LFݣcD3O* I uHtJgXETK7 (&|d@6ɊDMD(Vf!SQ~<e$>.Ex}zV!롯@eRܥYx  9xJFxʴX?ACk|J*c 4LPHډ|fV`ã(r汄rMOL?F7׊6x\u:ccN\^UWq_d?L(d5Fo>ISc3F7f=c8a M`| XY75h/:ƒ]I ol7ʺŜQ}V9oҪzwWWKIWÛMϺq슲E5q5N/^sْ\%iƬxr@ϝp(*/feΧ\/ThaEi(3h/\͌ IyZgR3.ʲKܺDYRHC 8'jJ):nao}3F1Q][J- Vђ*ϙ3,7םnOxѠɚϰ<񦆦2QAf` GggRTm˪{dŬ2.Zhp3w$Cul}dʣݿc}^QGhnxuPp(D2e™[`gN&;hry.P/@E͗|?ƥ mnk 5P0p=]O L""$>LgKQaqW c@2Wb~~LTy|:9 llY|1 'kDdn L=4-9K FCζ۞\ +}4EDĬGz}a.j!v@J]åp]䋪B>.$S>-?bgF+ISnl C5]jkS^)L+`Z.)DP(PCѢă¢Poyl0?hZyThPJN@ +?[2>h{s32:VfV/q@})J5ɩD/> ?#> :n͐K.V,zEJЩu-xWB-nBަTUMCy_Cv\`MbbW/FL~M꺪KLxĈ9@ ]μHTC׹ȇw 1XgOwULĭ:ȸ.xupJDmI\^捤:9-q6K; v̅[+v<%40#~jKKnzH?WKW?|`qNE`/?ǕgkR).[ҋ#~ַlqH(ϻk쿷w&Mx{f6|T͇YsrsrӒlR2RB\ @TQE T((5UHz*c(7xe6'&0'!"/ >4 œ3/ ]); 1 / *3");p ! NULL2!kzh^tx{ު!eFnV 7] A\S9|9Ax;opEBnQjn~^D+Mg0_ 3}xj@i)8ng?ſRH2˱teM5ffdW}]OC}{9|]Tp$s҉Zm\dgs4LɘqAp(+Z,&QMmlUXДHc -DԔvJv2ݺͲHHfKziv4-EI9e0ab6MF ۃLM,TE$\cM̥yzPg:jlx\أL9`'S+1CndcN( e9Ďq?i4ý(fOiM,\ќLn9CuN%`8f.Boa8DtL8V/ڹ;3]NTɄy>'Ěx15~"r+\}e2EhwNAW=|FD&$13,ժ{Qƺ;iFqxת4c*_iˇO.N/W 2x;op)iejbej]Z9fSF!'WGx[cpYBbNjFlIyEoⲻxXkOHL~$qvv=D!hZVaWv\*Eosˏ$M>{>N孭immmщJ$O6E>ۑ&q#~h#&Z_b_aa2m%fҤ"!Fi"+VSd<Ú6y'64H{]Hh]߽fup 򋸾&HgwFMg9yGmv{=D:4:֞1ϔs¿#%Y=ot DJFF]$H7~c5EKC%=q?>]J DE4PL2a?3A {qQyA'.$ !u3[-`*TP;O!q y6PcRsh3D5(QIBe"H <Sp~FlA&ob(Ċ wA>&xǟ8NG0G`Dx!LO6FR,sJlaL|(u$A|?[V$X͒Rܧ@\;g5F;>oK_O#u}zmSNgz^_tyE):V /U*iuxkm6Zyۻ0]Ap6{TgLF_LX{Mf͓' bIS1r3% --FIKoI6P,'*^?cpاvi\2QU9ȯt}̢ziu*`0X^[s6ˤ5Ybfڦί-n}[h6&E걤 <*wIo).e0L\VΦAom4FAJt+slYXg u*= lM>]=a*g@io;7_@Əj4H&^Z$S/7"c2~n Yb[LC_.+bH"W+DcKٺl QL K ^+xr*MRw]"Cb sWc!]$Y8:]B7 iXO|$G=j6}zQt]qxYYѮ(+}=K襱[dU\|+Oe xa5>7Z\U>4K$ Q}#{qQsTrE׼}1ťsi~rW;NR% _uϲyZ0JfAG -UR;_v5] Պn`o/Z|rV=Qkc?H{twȔWkSq{V̛d.=bIWY:o=L!̡`o}Hλ@R,ì2W8s?=QS0Fa"{YBqvEt{ :qUQAi[ÊbWmdյD8BAXM@9\24fj@m,#c;=;0n~.-O߳e_0e3+{_a Au8nVV7@wZ5HNt'y67yVɏ(*E3W |71hq~T:hV(7RLq-8 n&xۤI} #f[R!%sK?xۤGq #f[,y.>: y%: ѓTc'NNe߼Yc:䛼zE% ũ9i: y): y)隵@x'3c| 7' k>YFɟ ()]X R$_?o:x8Ovd61׊XM=.̼ dQM];. (JM,.I-Ҙ!QXZ9&0BqI~hL I~Ԣ"vnwxX-wx'CrV}CYdSK Ru6Z0o>yvo;x!Cr5#f[0M1x!9Yt #B@Q~rjqn~^d?&Ɍo%p̧YK&Ozw!6yɯ889'_TKKсr 4J6gs2!kx,Sd #B@Q~rjq^d&)o7g1k x,Ud$fc(|Ēɳ8x Bx,:It;#^d&)BFGx*ȿAN3E TSJ*~IGœ aLڦ]vNт,Vp̊kW?޼=upҦ Ή\$bE2 eJ ̾*#1e).!q[`sP"kof3ٮ6@&}tN]sIa>l,n.T۲@zUM /Z;ϭNdcpB!oUbt=MM(3 v… !xZ3l VJpy[gf햚J.FH6~bZXm[kGϸ/𰂬>nw$I&r~:rwژLq:;^uUvKA?ԣed(+jU}ckʈI >߲.(t4y7ΫߓWhS6j=b?슩qWbEM2sHMQ`~Yii;MkV;*j6"5@u Qsc6CgrV|0*[_jTIlsT%0땭;g* ݵZl|qk2QŇW=%`,ފ%|l}I! 9u?|juL~_X`L7Ńj3u'Qܵ&"­˅? \yWt|1_,;_8Ht (5lO^^2h[kܼsguV|m;nQI+Z-$Zt,pg~?#iOH*WX&t`*gEsѡ>Ҟ FՒЂ&]xI¬hT.Cd:nFX.w~-juTa)ǯ|A_=tZ5Q1d[RD t)6e]!lJRU|b!~\:_Ϝtx[agPAA!(?9#d x[ag@AA!(?9#d ~Jx[agRAA!(?9#d Vntx[ab#f'gR'nx`hٌ#xYmoFl)T~i8Nm|@0XS$츊%))Ng/ϼ=3y_zFעkdM$3Y>I ϴ#ASoLtIe;Iwc..f&M2myd__* K(Ki5j3QޛzwTc͝~M.,NmI^5%)K2f(rg0'#0gH'rm%cxs~Iotb6€N@ǰDDʣ59:dI|H:ļ[m2|S"b:7$5 .~#O$IB]E44xlޝv.>On,շ iBWXب8 "{{/ONOY'^^wԦvrtye;%RV)_Ҧ4ҹ =\a4pu[S E9VEI|-MR)N:ݙ'vſqN`N>4]D*uX~^&Yu:kfi.{2 ln g v7wpoc&&YL_ Lq{v$IڀuI<dZ>yCX`!-%"O)b[ CgEd5eoG{_@"TfV[RYH-L{+ q+Mn^v)c$F PERQ2RC#{(Pg8ڴEOT{ܡn6◇.:UC㿧Ok5H"Lǜkk9RL!yvpGgl0G=EHV3Rvz*g*ٜAS=E?9>E$lM`^.F2ɫ1QPPz8S8MMbυffD.8L+QZBmirZQ9ʔ/DQrS}#\ݸfΖm977:Mlv&j*19 yĈ%B(bJ]0‛To{5 ;#C/#(46='-Z&ϲ|?'킊w ȪN|8EJ.r+%$]ޢYUăq@a#T}-pBR+=A.J3(VR|!,&8ШbЧvsִR{s1x"6ȱ=%>q~ȍſeW763jXRrheW =nn>^"k8(OQЬEIr3K~ԳzN\ZJ` |vCAx˯v}%ע܃W:Ha/T}Pmt0}ֵKRJ/S-^-<{hP;ۀ|69-Q)-?50Ȫ/^K' x WddO!cD|Qq!Ss{!3 ¡58%+ur-,=wKGh͐ W^7$ "i^w>B݊@Ÿ|q>}Nq~1mj, e mK2VW*ǿ A(k0BXhTBA3lBV8FPTEC6s$htBVg5JN[ϞD .$2<$Mx=JIחvw2@b^.2c~URc 15ly}>0Wnn 'b6]fWy'%4]fѓ;(U"xatpnvTĒ%'GsM>)?YM@IG!:(58?/VӚ3^A׎S7pCoQx;exp4#fYƵ+kx;e`#ɶ"9.x;e` #fYFa&I\`7Ÿ'|]wk.u9'+Me/()VUR:7wrDONbxlMg:#n~^d=&Ό37d aǡ6َr'\s3L~m=<k.84u6p 9xl^zB[qjYr~ĩ^^^jgX)xX)(X)Z*Y[F)$VV*pMǢ0S]SK8OC]%(,83? l,6Md4{>v;6_̨0τ[X[';2͇7׉meCBTx{/=Iz+d@ona" :xWOH9+F\ᤱBx\" DIPL!~ϱ-@#쮿qYݙg}fvv{xxXO!>_=BIC6\a/Yx B΢{0#n$0 /G(~s !bf#Ao6?_KzzbB֡ATOq͖NZ+ED"~Bֆ dš ,~abMg%mt1<9P$+FKO.}b1,#;|/,tHTPpŊ|~@5d|{5ȗjO~Z"(q]xbDl*@k6 nf`1}p0Ah\[hy!nz}z8UQo: ٰ{wmL`|7N{ )ceT+ŴYl9nW>ykzaXs q Xc^bE@\68 Xċݙ%_7o3j`ZsL4!VBǏb1sS4p75҄GZO\Pۨ5uw h~=B^;~Pw0-%_`NOB$v2aQ6<n2&aKD`$SS|_fOP91)(ƕ(Sf^t^>.q>ul憣lh\T1%h:AV7zAg;r ]~|쒹Mqh+»UZ lY|s!N>̱t+V&fIPX,xAtDebDM}.!&9׸Tט2+.TA?Y?rVH [ A:j+(A!+6b2021O8Vd}vyV͐3 :ҕFH]ڶ{tvVdlҹEzaVg`@q:[ !MҡpsjE o"WiJ.Dhgƍ. pבS5?(Wds;^,(5>"xVWrgaz Sh;/EG< )5/\b}#Y ;aϜ1Ld`F.[+m.u(f:36r/q>XB\P, ,CE¯(fvxf[c0Y1t2QJZa=\X+1|>E>~e0Yol>ɋX6 2=$RMnrxۢYk#f/'nx5Kk1#fg#x% D}yH%iq#͋)1axi|7< $[bptsQ v&,K_(* P8/8a$xkSG3+:&BD_(# Ǫ$;e|ҎО쬐Y~wiya"s?+>̏ gY̛f?#8jFd2L^yu O;Y0s!a1vGa;*"%z\4^}T" E&?ڳ4׊Ea|!}FQk[df3Hr a1}؀O?=w84U0g"CIBdbz ($A&s-Z4!Oq[X!~>6'tL0S, U,iEm֠eT BfEr̳pFT4Va5Pb1H%qm4W斫iEOW9Jd6i/4CjR5!2$ZTzRMH0_e .++HQt,B!K&8OaAȱt,U䂎Thɱ!1UF<%yjX66vlۃQc8 v0&L '0| oӣ&ߝ1 GHlprv:>:0Bw7Ǵó3< Gv~9+긗IN~%F0D)> N)NS)OFM ䷃q z4H1$2w?H D\UqpDV%zIF\'6%e?MďۭhBP$6г$3FJ/[RaAiI?bWK/|2 cy.pf_dNq{&[&/\ N@ */bg4Fh[ )N߄O.ȥ.31Y2SAϛj!Ra5qdY&pf`0!X/sʮ5'HP9$K;DYQAHtdeъ8Eqhԝ~ j-7j _ibHYmQsh#襞;DŽE!JdIGGgr4f) j/4]ۣ%}l~9"2<$V9[TF%}{9ܦ+¿aۍ 3@.(f'܄YP?(:[R>utƬNbl*&OGzGi2]'Q 'dLQ=c oG(Nޘ͝zltcY|P4Ǔ@;Y2ty/qiϠY[5wP{U/_3I|,ʛ7s;7dEbǢ#ZS<*C\ #,~Z8W*On<)oxJIIj(ȠfN sfx70&W}a^攠嗈yC"JQp.x?<8j{oƣ bG %=P 5h'C R<%xP3P޶1OXek?4-٣ܗY1 Gγ0;VQaqK_x%Ĵps(O4JX3&Gxovxhs 9g7NOȑlc"S 2* g: cD޸hS ]ïw q88x2 #ŀ>! 㤔J!@Ƒ'm0mtäj%7ifR` `,GVH/$yW}O]Y(ebBpVV(<>7忡נ3+ v0cʼnD@gcBϰK?{{↛ɳ(TF4k%SـµYL(KiUISo1P 9[S}QB]-B40TPl$,Es#?;7Sj!ixK,-<_TB4٩g"6-; 3tۓIVeK:ʜ7G܂\N(ԡQ5%G"b%9O"Q84AB":[ uЅtB|Q'ؗATR> DR+Mk,]IIRmM 1kBGO+dYkc 异3,Vg3!UK[7S81fTf3nKz)l|ך FV|Fj[ez_sn ׿^S׳>\J|Zf(:|*%|2|W8S.|%W~Ӿ8F+ma5e׈QgZ 5hZ1,g>^It4.uoH xmălsVC6;%xҏ:A*ac[:s7iGk5m-o06cnhMC?,c<E45݀j&4X*.HWԈcc:誨1cUUNiSq-%jI |%<:(I*`lNMH<j͹K>bqC>̩u C"PV+gk+QUZ& ;5 PwyF[/p vA`U me(d%h_Xg"`Kw~12!)[; GRރ?Mr􇇽X:)u(&%幺5dBk)`JWPcU҂b@i5yĘ$PZe$""ܼ} A-޺ꄛ+F`ϕ)Mn*R5ᣙ Ջ{O_~cab7by}tlm~"$h́Fmh&^8a^Bc#YTPWּNuQ̒ޒ:b]J)jfMZQ&0]kiZbes rUsƷ&2mm >'5>laT-?eςg4@%5t|dsv: >i-E(I}Ԅc`qs] F&0мڃ,=\jZ3DcI(Q]1g+ 3LtUVj$y uSֿjKD(T)Fb ]yq`9A=g0BFqk,AD %jɑIKqN.(4XhE{=s[ 9D'KHiM[I4x?ޫs3VeCU{i>Jf܃2b* sj3}tť _nM#%) fs|ۨ{7Z$908' Ex%lUĤ:;6 yTYu/}/:Wb4}[-n5TW U0wLHU'&K t%1(%SToDs1w$ѧW̟M|kCbA $M{a`}rRN =0ן+ L;t*KaR"-͓K^dW沘gH ?/R)̟U4$!@PMbV423y=PC6]a"h;)ƂrKf-iYS$kF@gcAWa%bIٝc>O6Qž?lb~Hrkz8ٵ/7uߢDC@Pn(4MF΋ת5cp_iQWK ٌ}v,.æ~k6UO",IӬ/h }Qu|xyp|ѱ>[Vze$bq}5O{Ix.MNju{]> 5x~~d3mn Ux/,Y3aG\8s2zo:tO4oFgh&m ꅿX.S빁i,qT9K͹xˀ褑gS.tjmgJ/N1TFk԰S`7KDL^(L_:WI&FE%dyE,^Y]eMLWsh>J@~V?_K0)"Cn ueM mB~_w|s }WBMHJ5{'AY19{+V+eP HjSF/訫yWI7Ton̊$qhQñxX{o)c^:WƑ~A.Ċ\IIK7\R I$7Ofss&&t&76LH3a8g|9"JuD ^l 9#[? Y Lv\ &YIJ 1޻w0~W[mL6 ??7 PTDrJL{&<ĬɓT2/Ji HvrG:\ Y8\0Og\ qgi 'i )-bNj`rLV p,P2+SQO^ 9DR$%91Gpǻ* dLѫ E?,1NYe 5}>Ax~ l1q#+Y7Ɋ]"N{~G_ȋ7BI8 0BYKy J𒥙k}c,1Op1؏ëLS R8@:Bs/o*?~o׿È#.2c .BDyjw{waXHȸoZH{a{[+v IP?0 ?PP_yD#vv؃$;I8[$ߞ#&KiyK ԔyߢyerޕBw'c4ې˻eFGN|1ROu sLh!p)LֆClRbEorə ' bOƓ 0gQp\ys2wvVY$ף4ÒU2J,+i˅AlCIH' 紘ҠQ,8գX@OFEo R_j(= w1*ySkݪtdMe+Pוp9櫅{ezJM26]ޮ2b5[X^Jk<w\;7־^7^Ѡדm_?t+އKܱtᲸ-}k5grCr&ZGbuV?K[ʿ4qZSVV15B0hT&^So|?MjhlOhj-97^J5^10Vu%"eatr}c4wuveˮF}7>zIx{Mw®y S70r0menu wx{]w=#B@Q~rjqfF͹- !x{Mw®[x,S70r0menw nNxAw#fƥ.(Anx{Mw#f{* n7x{Mw#f{* "x۩18,9?w]S~>}jބgs-P7o(f0ܚe2G/ ?]Q?Hh,2&c?]8`9>rۜ>1 Yf+Ëx[ tjACe(Ȇu/@ؿ2xI61}d`&iݤ SϣX_E7A20i_%&:˴pxs6 f/#O5[Ksrѱ\70iM?68i["bmS2BX1 u``h2t]CK М& oMŘ_w?}5ͯGGݏ뀆7(zBVh8G-D;G[?cݽGJf{7o̦9( Hpp8KSSMu+ Y.DVpԺ (JsuH-W6nQi^hTásC ++M:Jh42xj[+?wib7c\XX_%$x2|; zq ^;>]osFz8bۺRڮ*~di@wEśD[':8|&UY{oGC}m ni_}.m "4MNӒ )CwxČ Utde:fLSv& lE:[O+e0VBDz}460YnH alYG \>Llp~B\J^!;>թ#eü.q2Gb67HQ:z+VC%'N85D:*`# q#K,Na{eI4={?>>_buX;Ɯ S)^-뼧8K OX)C*lFIPsc6?QNF8B<ÞSV[ڛ)7~+Y6ӑ*h s9yGq|FCL ;V~ g K +`t^ҰLk¹f~ikqVBXl9զ$RM:I]R >|ܷpL뷰VLhx1\E9&Oxp,3tttʚ3r[ 2u}0֊޸Z3mVTP L!, /UjҳUkUoo=&2Q>Z@p2ѬYQM,2EHf쯑VeɆ޻i͠R=za66L#]*r"N+0|fV{жu}U%^ϣUF? 7NIyih@`T?%Ax'^ #ܯpSpO8q| eބ flL6i|'}슈&[&^r#`.nτ۸:̜\Kq;" #^04a{2)Eg^T%Kg,|Y#ϡP攰Д\iR ֮Q;9u z8aL$ӽ=tT3!>y !]2^X?@ps pYͲn 8IlF&t=gP(L6XwvZ;0gJ1b/29E_øp'z8ۉDd'yt^TfNcןXx,=ij=f?9Qxi$c:IdV|"q~et>FJȄ' /l#:([%CYW}.‡d8sŧ7{h,3ib Jq6Js}ъHI 6zHWFꪤ,+1oʲ$[1frXvx.S\ 6< PZH1ٖnP񠩂N-nچ Ykdu&lT#h20ǾZڹ1:;E\r)T5=W⿣O!17´Y^Z>smE\iجx q>/xumJFI<]ˊeUZ0]*JyQJE0@e!2/ ?,4k߽(3|*u(:z #%`Ny4 eߔؘ;1d!b/ڍ+K)g&;p\(B\IyhY#ILUٕ5)3D.SWsUc3JdVҷB^&S1[V(FBCe'6iWq E o{Uުel>5]xckp7{rTm#&Rsk*x1`K\oQ  GF{t83A_{Qe ŗ#^HŜqi^KK˟htiGT9lU)z$k-Acw@PE ZRҜpxMCj""_T}Y:gxFd *@XƏZ-,B"q"Ég\5_na<&47L) )݂g6^lrrq+SξJoLV 8I'/<XcPEk`Ȣ) b  흽͏bKWEu\B/!ED?&dTtl$w2V:$.~ss;27zƉ~p#"GX8<D֐;?} }o;.qhIf+' |Uc⮳uy \yq^#g߲jٌjyݚּw^Dwz$˄PW:g5OOi1 J 26-C,"Dm3XY$v0w⦎. ~Ȏ *Q6/ jG56?WWArj-IN$9ߍ-K+ @ؘI2g)  ,J=tsHn㎿S<-YI+f->ެE^I5D\̬Y6U +qG6#>G)yݹxk:RܖYz2uQkp1{7No4}֏?kpe3\:1؂Ⱥ/pt~¥:q;A\+AG ۓW`;RBveڶ_ӶNZEb?wh fᄎEVZp|X傛=5=޶"w" yi#n;]vRH!s~NX&HSv+|?-{gBvaXܥ |EgMQ 5㼊+l>ȍdKhb 8Uh=< vu@aTjcXZ RQIȦY:< &A2Njv9H$chnM;Ӧ,3jocqRfPBA|Qu 9K%WyPO_r\Э~EAbY>?t b0p4OYٺV408i &؇4~k*ƪ#قn3]Qd W\Ft3{x_s jxMUeӀ"MdM7*pFS,xK/v_yO2GFXUϯoύ/`g.zo 2.l<ϗ^'nmo/ 渗<3.(<1ŇMKOS, RE[nɉv VSO6|0M_Vq ڡ X0gдumGΘ}߰(0(6U0'wWa@eNyݕG[cEXKb ">>Z$mSSU5zIqwQ0(HMՄф`XZQ_-Vr\x}ESKx\ ߽!`r(`B B=y8gV .ӪeOۂEҹɓch2It4x{-^`K$6{sL!ܺÝ8Am6_7XeLx0~< #nh4-;nbPduq(e֩(]?;(dFiѭ mzf83zT%VsE8Sୂm;F濞<~X~JsK_w L[f'K8L!m1/gw(>Wg/t@(+o,Ax%D۽9(ꕍQ^/kel s\nw9`:Z+ɹ=~^#3;VĂ8Wly_E5Jxq zF3gxq z6W*qnN=ʽ92q_+1ӂݘI^cxr z1qH> ?x z6W*1m~ziV 3̼Ĝ̔ɟ5lf(gVg(*xpqAIeA* !"9y@_`՚*ij2oN=ʽ92q_+1ӂݘ/x; L:\x;qO~b{7p\P6 mM-&~1Ԕ`CxkfAb>0.ىYis+/Bh .xq%#n~^d&͡ l[ٍl&&UxP?K@Eɱgli iM A)%wIHEtdpqա~~/Ik{q;l6+g;O${^+%¥Cbᄙ9 fJ%(hZ1 ZI׊z G˱ H5ɾc*نө&6La:%<>}vb~{$?\\n7똇2#%D*yXDqfH"Udڍ3 Jh* . R˽ d>:e %+L͐3!C mWJ‚ ˅<(0lgmetbj r (>6.W {Eޗ$3~~iCެƾ x;QbyC##S]K]CSC +c#+(ĜԊ=@51^|Y& <x[ko۸|+Rj>..ڵ%$.,ӉJr[CMɢ$yf8?)K_jEcܦl_+焐yy4I̐Ӝ[?!8-RDލ$k?IcO)SWQoyd5IzKIJmB ᣱ iHc7 *=2=& رO[&G>iaZnGB} ~&s!&G(&gnʔIc_@GP rnVu Pd>p0 ;̅CT|V-K5F-> n>b bYO^SݹfCmriZD%srbZd榭$Ćaerm5M]?H_chɭ{GK궣Xy5#78]8TDDOm|B giagW6'8=lwц>(p[:ε);{_L1_YomV8zkF{x~> >#|Z詿e@NcN6Q%_2`()3- aҒ9f}Tju_j9^ Ccڎm^?ρLA+]Kuh_UR>XGJ3*#CplΎsCKRDx4}ƥfiƘ)XpCc o,qqL(nFxɘ\Y#s#SqLς(gz*\Btԁ0dw` @J L>9c1 -Ebtf yFklf!udP+A ̉d?id1㷎w[KҜ;8¡<\xg= XYqDEЬIE7|.,V!X-eu,sZUsj<>M71k F!)8ÿ]qǪf0@]ui!^-=-&`mWaFiRSЍ_ͮ/RS-FvAY_ߔ^!TpQ 1<`γA@(@fGr}'&lTY+Y|{|]^݂cu>w'kҏ cUL2C1e'ͺW0:Ti&MQJQD֯(Z=Gz.( ~'2q o ;Π\[,#<1{?I'ȏ?1%MoFibc):YZ*g0'Y}rJLXSk0$F4=~G8im" YT&m ϛy*(Q}XDGBL4vas9_)F壉o5uAcENY>[-w]?(b @ҳw*Dtx|x mpíaʖLl.8C `:Dc )iݴ N.uWAۖo:5?wT!E2-n0pspvkɓPe}EmXEwh:xFH+ iAbX剘,GdN7 ӇO `5߂jx[9 0aoT~wV[G|8uQ,FsOEl&D%RHJ/"v4}]pbӋX8E?1G~ f$(II*@i)~j%,%Q20~:+IfRY2+IEE$r3>'ՊIٝ$}uVr@d9D ;gGREoJ=D`R|2Dj˧g6[ AEh5(Ik&ٽMIdR`v-Jh c?cëU=1"ܲJ$|rW$A@oÊ|]p!" 1UPGv]82~C.CHdfIiŻc6)L*4///7CX+bB卲?fpt^,W}-^(W5kajவ5_m}@˜k)x[.-Ob]v4U\Nف%mhWݱK˜uܹza8BsI6WBLj,=ҍK2C=.39,9Z{rOS?7!^^jI~+%.  D+՗'[oEWvZLS 9ht'xpq^_S{HmM['D ĶJݐ* 5͖3ζJrOם0|nZlxpcdE1k ڲ'cVֱz릯e T7"#^gn=i?k)UiX^ߴYTmQmm-Y(n nvhL(@ RXy펉-1]!f-T#&UkqV+0byh7gNEۭ Hvk@xGb9l4.1C|#d ~b /&x[XppB$aV7 _ R|fJ: J)i@du j,/ 7qLғl?y<~= e.I!w^x[X)B2lFEQx oC,b ql>#& u ?x0oC,WE7RRNm?x[ oB!f)ox[w7w2Ils; dx1mBB@Q~rjqn:&I\`s)ɝ'qOVe6YGAa">f̓qOٱ=J62"jxۘ6=mBB@Q~rjqz & : xۘub.̛MQh:l#xۘ!mB-MF&(x{;?f?jA\SUA$UxY{oX>őh@cȣS6ٙ.MH*C*B/u|9ھ`hh";ǽԞS>88KeSs0Lr3.hƜzQW 1i췺539A=`]H<`lDw<o ]G,٭9ʍ炙!qh89/dL:s!,y0Ojw+ł= fNSa'1$l v ez(pQr!PdAg3A<>/C<&L5v y33>3JO[.~\rD6C{g:w8IHU4b yܧUx.[oJT)q!(q]36\]bj5 h_^=xѫp=˙(0p"Hf 4޷[$eknpAޠu>n;u;fXeEDsTBq)=lɏhYwm }b2n>uJ \8xgO|q*o€t]Bs#BxH<iMCn>:9>>> ϔN5teIr͔IÖהkcu=+S_/>a.M41=q.Lp_gG0Yihɏ;6B'\O0Ee#&@v3v^ßFR^Lnd&L)Q|rhTW -C*~)n/!Q)1c[j30CG>Z3ũiۙJl4b}ssh_Q^\ 5$`1kq[@*X @:} 4%O%څS3N]NsOn ݍ%fTp|t4"d6Ɠ}*Jm沐}+B ]^wuBYD{g,؜?=2sqvPe-`OG$¿I\~.b(_@8u %MU4I) Vѡ 06K\YԊj*i*B .kϵDq $#$@hz}w'lqO7_n^e\b*^$פUҺUtUqRn]]~/~Qʁoʹ_`.qӥ&𮰁S h~h1l7:>}u;ʶک\h8K_=z[b O($gҫ@KbA#tq!VhIGȒm +{.KRERҕG?i}I$~(' Ahwegؾi[XJ4&Wѣ#Bz[zYջuQ[>|9-ylM%#^#>u'?α;L/4`F˥X:%%3 0`ؤ~M1 $@J|[Ǚ@H!v7YQ4|Ix(>VIu+)u /݁O![J"y5j|#Yܢ#ߴ.R(]BX27.^v'眙6+ӺDEx2eiƈg*y S73r0m.a>  wux2e#B@Q~rjq`F%v xrn,gX)xX)'d'(X)Z*Y[F)$VV*pME]9,n0x'c` ^4qpBt X-Jjc~̬*[qc&b RUVV++ŋgY}ڏPgGӞ$I:LF5,nӌ^Kxn J? KaI_0ynGA܄V}Ń {hZkuu`WWak>nn _#ۯ0RIn(WM~PuqduU7HTȢazir==&0Sm0*?~:>W?I:^QWF0Ā淠fO 3WzAFxaoaL4Ԧϼ 30W1mnҠjOׄm:nX]jøc0ꗃ':~iۭ7h !s( 0WP8 S`G{?OǃÃGAxLퟴUKڝ燭:=om(uJ2C5,T8/g,΁aSg.$i>y N+)EꍊUMuE"ed+% n4Q itæ:ׯ_5Տi^ISׯ]#z,fb}G8 DaR K * "ϯ{믶^3m!|<(c}/kРaz ZX]x/h~gܻ iefwAVln7WW Q~[1KyK(A7Syv 5}D2H}LF1/nÊvQП/yQҍkq }[]M> zi<^]HY.`G9fM59 |hu {V]\R^x%w>y:k*ozgëh`lH[4ƯMD(P$;N{Z+EqS56#2M z{'a;]v8~\1.FS0cEdegPʏԻ¸gD׵˵ ag)c.4+#B]id,nSz^vg)`B=ЧMe!lfU=hhY*,_/!l 4VٸzSAR/͘ ,Ŭɒ&g;9f aaf xhMX)HHavApxV C.H_h/Fu7^]Ö6!Mu*f:n;oPy3$ʋ=*MbхƐ%̀"4~d5\pCT,3 ]1Ne"̀S{.34c XL 3N9hJh5{aaOff! vkK*5^ְ-V{:sYS._ϙxϩQGn" Nջ\=҅8;!6 |#U8;,(bZjt_hZAԫ>G͠J !JjDtRi?H;tRZs|[DL;6w;K>ҏa8h5TAo!*FhVa!M'7b PݕQo6t>!ANfxs D{co)Xr2@f'nz:#ZzFˍUnjJcYQViq-?"ؔai8Q|<ɥ*]FK& $  e4l9xtrSzЃ~voMOZǻaR*D2 E47̪٢.r7ivO\DB-sFA 5AH)&0xK>d5qpxSڛdvdEn*lCzQKSD {WG%psZu 'xb+0St} yS5, "QZW2UovVw=`)RhefY ﻽vɏ{jOtC|1}X] ,لϢ3J= 0KgPq 'CmTP SalJ3[-f[logӕck:/eMwq ?GwvIr58_8߄OHf8 #]*ft<±T@L8fHYO$FQk {`ԉzvJK$1/V6D[6~0!s/EU|"kʶ}:2sM6M0CtrANaϙ_(CDj1;d2rDffDb1a7k j',+xVEIp ct⤽웵V<[8Q}Y0XCf[OWj{cuKsdՔd%ޱ[YYfpy =4p OIz`&tnMHh0jL k9ͼNS2#0O.B~Iſ,#ZC 4=Ap BTa'¢ *8*\5pj#s 8uI#R)}u9sveyAmʡj.)%M/Ύ ] bq)j|BW¡f^RϘ U܅AG濹q+oO gqBNlTD +h"s[HYWPŠSe˂z+iM,aI^;.K!4'>|hyU݃t1h*4~`HA-F.z*@>/Emj|24a1j2$q|<6C'.<>IA*LݒXILΡإCPą3uCv.z I!. ,~1a-&t:㮱iQNJ+.!g>93 6hEϚ'eRuU-Jrͪ_w[d9jdm$-Qnp nM%ۃ0VKJ$ES4 va*&2/'Yi\iy#^4M#Hr:c68Gܡ)$^pÄs3VYzH[(86Ab=Q4ffDL'b=鏥6dX`Z2_V\z\A:2o@HCP B}O}Ʉ6(;ko` +!/_ry|A~^ȅ շ߰ )StIxc$[א"L<+Up^Ӧ:tR`9['Ӗ3~pey/T>{Ym* \u GVINY2u}G@#0kEs([ix,Hy@:$6"wBy\'3 `ECq$4PW,zhPvԫ6,jd`%@pxq 8ׄQbQx"m22u_lXLh6&矈\rȏ,F;/G+,ı(*IRف>MjoFYgJ!dCg̨ L>O1INqg&H8"eNz4/0Oƀ.둫G)+~=)Ju+8Ow-ɵTQF^F݀DC( ^d7tOtoQ.UHd.}qDhՄ:G$ ST'cwMpk='݈]f&-mg\85U pFQ`CAg#|ks=4>̟6kՏs|qSk'1Zp:d䠧\F,L 3"0OArΗuM'Jk v9bԏ_ǒȸ+Er.ĝzcZ8хN,,hV C55(Ե" ^WH/-gU} .X? drًq2f;G+MdZD&N!]QWg`<|t+ \WHSyDlWHT\3-W{~ mwm$rqdۦ"`f˹$7Z=1q:T߭vrM >W`ʻEEg|R: 1>ז|{ 1Y*"AeYt[jmyVQK J^JѪISmgk<w&'J% l0,9XJ6{ht`0#r*ȋFo 1+r4ޤK[Z3*$ZHgD6 K}s/fW;_5~XsfV?]Si82Z> ^;Xm=)>i4*""cU0XTG>:gMMT_K}G7{ߑHI(0xx@(U-wV5 N}'PYRd޷epWUnf@i0Yѭ-nwSdj3GZ]R1K}g>Ҏ2kD#=%%ex)FVT)Rje.F)2$^B 8隥H#qӁ߻Gr>נx@ 2Zs$U[T/.Fn _re:R%˷obxrvSQۇK 7t"=}rg:dMYw2&>ŽޞUTJ1RIB_K4ڌ#'qM$V9LZg\09GPjzgc0ÂHnp.MxPGNP Cn՛5NFƄ[] 1q^Yqu23\e tj&A+̦P?J [Okr8-"˦{Lˮ]g7*.)g84'2҃Jav yw*!Bi #lǧҷUVJNWaNuVhw[Cڵc*fJ$ ,\ΓseR7!š،|^%`'OlrMiӝ *Buv9:F~?Z%Ki?ѳ|" #CvLPןtB~槤Ft+)Ct#p%Bz{M>6Uy[yשY.:'BfӉpDk'јxP3(YI(VL4:TcM@:j BVGpfF#5b*$aBԟi[!3^$UIH]bʖ+#2=*ۋS i0'h=ڔ):ʍS6s0d}z;ǩP+ut*>O{|E.lGx;q; | Eɩy}$7'2eܜRyx;; .y}$7'2>+oP}TxU[LU ]Xh˦\skggpg@IYȟ>Q&Zm|1 />k&5p'$gWgrrٱ/tkhh@>AT/QRfxI3RqJD/t֎@s"jm :/%xSZmFG֨en*뻊LJr&Jf$x:!Ka¨Ww03ouìa%<, s*lE5 c0Ȓpv]gOZ'Mi!6tPגYt xk ArVJ[ +)dĴ]|Z[g&5' lX6@:r>iΏʊZ; dO[xBmQ424<~mp;,kؼ~+D$=%ADqN{%DzYIHw#*Po~%x69 N9|@=G`m*۝$?`u_q^ڠǞx?{TcS-ZQ$Uw-obxUMWC/ 4p9JM6fs@=%Twᵦ阏RR(ҩ ٫}*1,|cWzy^J7+ i^$47# Pї1*A,dp%(r ]|r)0B uqH!VZpbmC) ՕnxN14O#A|!, ;QPxw?v/neWy`xG~(ލ^{QbFC(2P; .T͑u7Qia|&TE k1a lP߻2FxkGƷ&/LjA(Lu/'"NPi/i|`gΛB;4 /ݘvT(WmT8SlP߸>ZnIꎘ #xuFqcs#S]3]#c+C +Cv'2nqs0[ f_n&u<̓r;lpgB(pndD\9U Mm='d?͗qKxC7$ɳ9էy^?2x=isF_ы:=ݑhi5kIʉKB@K  J(^_hTŨ1t3o޼zg͛7)瀌Cײ Bwlgm:dFئotF#gD'^@~ًDCx+ v@_Xi4 c .~DB'ch /b8vB]h;25B&G{8&dy-^sWU#/&!~G8OY8%^DpP%F ϻi҈$#Jc޳?~!ҀFC= !Kbo.HE_PANAxxapH#H& # ̴$>";Aުv RV]GFP}2df05lf@:o^s9|+}7";Hfq>ggӫNopv|sUMHR)eDm0]؞@HA>8`I˵Ƞ~<0^u*Cݓ L)tpQ,p䧿QQrh?Eɇ0NEu{_ߑP`ΐ1 m0x:i{(#z;"IX1)ﭽ67>5Pk{sf!|[Bͭ!y` ,o0J8dg%; 7_;.@H\< -ƽdSb43/ f%RXN8C(wy?ui=|e|[|{/usmԛ]ٟ[mrkdr` k;G:?mԹf:D“+ Х- <1{&:$#uXW$0خkc1Ha6a0676.Nn΁[$8n]+#j0SPYPL sm Nߪ@1Ф]L[T Y#l{/Ӱ] fD Qhbxca,&w$~~ Z-a*KpbkCdsY1 9  lkJ9v`vf#9́IAڣ 0!JG4NMrIm.M"ILk:OMl̡K}ڄC~  , W<.KTYB8^:]/E/` `c\= h*FՊ\!7dG~ndt|P&BT|~~1C6Hyl5c!bMHlJFڿcpnq/ O_{4N]ا|&$ku$Y]xo. D>`tA|!9#wP @!apJSA B.ba!ϸu&Z5URSISͰ֭6fjާKMm |T]Cda.O㫋ynqB' |n3ِY`p@a4CySHlNɘ@l$ @kb>iHnΦY%qH \*OW`gLG;MRt:EYRz:*aq-f2kX:d4bao렧2~wJֻ)it^s>0;>A\ <*{\)L(ĺYWg''o^!|S?pMϲݙ׌p=_XoiO!d. C/AR|= M-ؽ t9b 'I 6.m&_ /Zm? 댬T.OG G4/͔rMNuz_@<3yt(+S͚+HUSbȏ?pڏ -v! KqSj]@iY;^RVcVC !ؐye9鼳zU]#Hs&rP_0-68&^aZ;%pMqxo]؝,ϧ2'CqLnZڀNvZ iihX8\ի3ܿNÈ6^fY5VBa VwqU{YJ+U VR -)B[Z5-/.ʣaê *UɜW/`WCl\BG+ݱBw>YtqDJ3|whZy'&!Xa"R~‹Է6+ׅU0_) xq s[hϷ|=)){ ޴MkފuOڟV|kK'AM(G8S *2>JgJ\\ħ1ؾnDpq$KLl̶4d9Z:ӀoDXV.-37JJl,n՜4t;ײE0rvRU5աxqqJPIEUOY$e*l^*J@дe5!Vׄ_ \r qlLAOf7Ǵ'qY<j!"Z7$ALlEwr?7Nlx [ ?cpu+39dg^d7v ĎAQD(yCwJ1)OM{MBuo'_\vh0O&xV$ӳ9M(~XEH>Tێ\'y5GF(q~(ߏ$zcP_BIza >_w m2.@= :a^H؝&e VwНab~2nhìjJV&MC 0=Hefه1|3&6BUtnPChӑ22n؜aR1g*pR&=jGŭ1d1۔c>ڷ7+'xR@= Ln$t]{vduBRDnJ.W@Aq$G%^cny^-ي!\IO5W_dXH*QB `-iMx0KnɎ;Q0\i_6ѻdiYh3!8|ķ XuBIh`"쩙8o]O ԩcP qr>;[EsoW:9#Syo-GLmri[Iwsm Ê>{,5+,<wMe*Ĉ?KA,snU (:XmNx0oVA%b>^B?qFOApll%.;^S3RG(?v~!PDew.T^O5,^M*ü` ` EKQzP(&I͓WKtxWËӓ7,D u!: jS_#{2A'PūP f$l[-.ۻ[nSgjD~v# +¥*@_>)ɭPÀ!զc=\hVRDT|ͭ1d߷o- X-z5Z]pS{_`&-6UUӅh[z)[t wy]*!CpGbp*7X4,rA8x HU'n!f ciD(V.e".EQeGŨA4)J_ttpKv>u糙(O9Iu7٧h'׽ا q͑PQ!AиN\\@f칛^C-F[p¯b+~z%gb4MC2eN<&vŪC-sD+lh܁#w 6{}m nH 0ۍ9>w9?V!u؉{tʴ[]Í{ {I~s#+㏒yL^Z*o\SnxZ{OX;|#*4F2Ўv&] ٥&a !ˉ/űS?l{I(3;V:$~{v~"|4߷ NybIT僵x%@pd6s7&vρ?X^e'Pf m:6aOt@(p@>1ԧ^rd*S۶\irFQt4\ϳ JpMlVc,~wv|qڲ+^= &$rɲ`>FnT\#f2x9gGhw:X` T̼Udl* Eج]6PDWKSJZ@A.t u,X;++rNw`/Xr3n HͶ'+t~@*.*x{6nuN4OO> XYc#Ot`pćֱ aʛRj `sL={i' |/!/?.vUYG80 dDsg/ (zLpՂw1=PS2h Q4.Y h &8DZQ|ʹ˫y0[9l;V.+ംd%x&n(]a8H~%D*'J/kQ614e^2tsqGw U(ZɵX(Q$Ƶ``}8T:v?qDR7ڬy94ZuZe Į2X+g$$ؗQgQ6Y\bеf2) iTFDĺ2%ɶ xAs~%ϑtؽixiп5YQT4vልYr"wcV!W/f!p(&aUw&JT8D&c&r' B.(:bg/nrxE!D ֘@m1 `vwOLJU^.6 R" ~d>5yS VFuFb^fi#:s8p⬵ ms*Ė_ VKn8iD*dk,o#VӮs(Zl#Աi' ,7+ưK AUgm݇djD`&| J4ǥ5:$XCn#ϚŦbWBIj[ԉ2J?  jYO!a|յ6]9(LM3kIG`|M|t ^ `ЄbdpXsD0ݸUDpdn+F"b]P16nE9K WT/rCw( * Z(\B7a_PCE6 eͫ`ZE(Tm FTnle\9vҌᇉL}'bg"L'(b.e^7f A}j? HM.]!ZLݚ}\yURvuyEz磘W=0i@CRkZZвa*eVzMfagPEH@ܷWRd"Am΁6nWa9 ]DV#Qq`eG63Rk-};V7ARn0?x{m&q~؛,^4#O~GEaɹ.ZmM$V,DI8X,Ux[g"^dZ2Tܒ~*a ].sY R~8++#%;Jٳ-%([q n(#ٔ'q&}f&}"kC}vbxT` *ty,/Kg!^ pVwMxH2FMU +' oLiW>Ɍpg)`on"kh}ŁSAs`_7z_@ 9+VUvkaD"H?*Hy&!̰ʁߺ-Ng bӗ  (^[\3/ͤ]nYxw&#f-s/irx{kʪ}9LVJOVQ_\lr,5kNq\ڬ @08XQi~_ܲ%D$Qa)3(O95/esrI&oIM 09^fD3d9d3 gd K*N6QTKRPRlrb&}Mu87)`&QxZo8`e@yM.s^ꤶsm,ѱYrH)Y )z[Npч- gQw[[[q)qH&m ]ߺw;÷eigHtlzyoM}Nasj{o} r&SzO&Xf''hvʨPހ;r R r_|jZt7)uXo:c8 ilmW̷(c)9!q(%O&Gd50g81={gBaٔ`LI@ل$^wԣtMCױȅcQer!bO#9jя >H;"ԁyF)D1Tif3O ψ ywJ}4&'Sj B'uɐQBPOiuO^|9jT¨p@4L/ Bćv=N:3}r~#-r :]];)U^RJ<=iit\ l1 ]G [mQ3z;a+P/yD@'Ó X'Ͽ tBׯtr)?~KY6DxR-W;095"M4)c@ɂ}}s=Ih8 N7gw[!,7P3fn3_]gOhZ35)4ރ#ur9 xl9&=Y9Ґ6ut2ƾM֢%#+t" rpyv}3^-L@;CF )3FPCF#gw" lZ%Ddv_jzlThoDz4N-^ڡy2޳=k8=TI3ΙtGö yР9<3DŽ23HQ1o,h]\\~j.Ro5C'˵7U?&.t\,tL5DqF4@Y,بW_{Ba ׉ >}i^exaA$"bl.r6,K*$ĚCx!W;BkNXO|ŷ8GAȕh!*-hB&l.5Ę=](}RQ,9iv^- s>ĆAp P(#Sfu!)VXf\9ZZSRNX&qx:qripCQjCF$8Λiъ>  ?;Ab}s;#t@J4ضH@cn' ȵȱJyrTN/cy)AXGPXp1Ϡ2Q(TډWu`Lؚs>AR,r1~g02GX du6tKh,%S mr;gT'=5Up@O!Md -iIƬJx}Y+5P]ȠZ(9*!O(J"uLt^ua۽{<-/hjA~|[ [Fpjr|y7T+<Ʒ: @T@QӪ8GFm8 h),+KXc֢ˎ9ޕ&cb ԪiA@vQ qE DxZ[p$L@ I@|S0^ ɏȓ%癯S`| -MTӒwC3/^ [![o6\Bc.cHWRWzU\8'zbGs2hxS)*~YF 3w vW7dX*-LLY*4yBkXpwTY6u[;R,25ԭKܱY<'F32eJ/UyCܷl.B9=l5>+NIёIU SZ^T&:Me@8dS,9[V3|#kmٷgwZ( InHa<[PM$3@sR %"Y*"+$rȔ??w?n_u;)dS!% x\{sF[S ^#Vei=RDʉBD Zh$0iOsqFRϞ'}L F1GIJNa<{'x=FoDcfΧ$$.S"FRyߊ`t(C ﷣2e?^.v^@x=veگdrQ.Y_OX [Y*\xN* {46OOqg!IB_^6hAR$2HI*E_AeO8 F}1 >KuOA_ zФO $2ƩԾ"NICN0s6b-!*)Σ'5% /_n$˓.N r'qG8'N3 zd9Mz.Ώ!4G"t" 8olDt"Q҅cC$lRYM#Uۨ츼+ w%69xCLa?<hyB:NKnn+k̖' ?㚦2ܡ70^gab,>>ھ᥉Dʺ(˃4Ǟ?8kEa9A1 I∏Y!ČK>h[< #k/Ka!͗5(I5lZ ʓBqߟ/=:GګY="R4 }T{s7_^4Kj(tQ5O+}9c_~hՅC Iz;}?iVmC*3K~aIbCLuL6>_pZu@GօQ7q :Wc9PF'Cz8o'@vPquq6ɳXBep~xcVg g{(]]9={wyCmUQ[ N*k3bTxf)pDSsV@ӗ-&IeJ:,I5=ܳH A.':ل3J&T YOHA.e$sr(+tn8BDC'UCD8i2:Ib(Jkqr8n#5$눚c\FE9 ݍJ{!s\/xF>=lCqG)GC!]WJ)($Q?XLcOEcH˄x OJ`$凞LC$5Qy݋vh/(r+j8V 1KX;qA0=XQiQ ~g> P!aJK mPDLFZSNOY]e45 MzS9|J|"JCHђZ n uAHDH# zSp4\}dIyFZw9=nPhܛ8҂j -Q;g8${!i[`E(~U= o>yIkBju56r ʫyy{mAy%RJ,15= DUT9ّdbCMd,sEG@ӕ[hٳCWCS:giW 8^TF%6'ɇ`n|{{؟Ejr"Jf )xz`@.GѠZ YqeNIƭMoEX4 mbi}>$n$VWQcex8ۓkrʜ0PyHU\!I">|6cnM6(:SxpBJ_kgp '+~;sd\CY 5+t٤|ІJ¥_V:_w8ΏR;C-U+YH/Z =Ae5- &AͪXFsz#蛣5޾=x_^4- XAɕp(|W%%R9YY_}VvgY{Xu2&R~c~8ʻ$VYΌRހxmT"Is.E7b;f. whwHHC GB!(B Ђ >5 5fMrEfi /gZY 꼯NK)텐 K^3h@Ѐȉ?P0vl*Tb5j;TzGsU#5.[&E՜D(ՠgqW Z?6"hhrqFV{|r48G@ԩ^C4y 9``ho%'`R+v-|D 08Y족=XB:ًߚ)U8qK &[wzO,xvf͜j=Td/YJgV#%^C*9] WY8KV0gsb](i ,C熺xDE/58N/Tk0eaO_ZTM}1l`ja\H=@Zcqq~+\3\%!]~HַԻ8ItkK<_Upa eƩw]t~a O\Pr4`w oRc;=Pd43+"Jj#'MJ~BE^,?.&ƽ/_m`9NeUA[v(+1>^3'J;x={A8L2u;"bQV#vkvRl^ SG?f%p ;)kO1BW=|k%KemjI-r(FڰulPFSw@z|υ>IOtU>1:7Zvuo/[@7T,ݶM?` "nZF5ݲ jy?7 c^#L? T+2(AUo"1Q^_3)m}z*G0b>& 5Z.8c3PSХZZ3!ymCY}9Ĩ9ա%(p=U6ǯxL RQ(D|ϡ9Z T ZsyR */jW9Tb%z2+O/=5PTZj"|BDԬ_ES^'W.-me0xν! ^  Ć@L60oyћN0qNa?l)ҠfAN%%:dV 3ZA+xcai145;dZ@גr"Q'_뭈$!#c*n _:<QQRlbts?^'Og \0 ܱf:p+t.bV9i %dٞtjpx6(hW}ҤB?TET~͗/ʞH (XLxgR5'5i2!_fԕjDo|R9츲)myݜTjZȿkU_5np~`aF3OkM:DJHZD+bƠ~ N}=W# cRT4dk/Mt C(8 "7$rƛ2wrdpaE?=\ "x?qO?/FFތF h`{C%<"|IJ.te XPPZXZ\Rtr<6j6*N3\Ẇ,=yQcdYNƶz;M 04%xkA&C0If]5#TbXY;k(G&< x*݃#DOٸ~}_z.E`5u!ӖD_(XP~(ʟCYl@+@%oşE3'`%F^JϩQZo x; 91Eaǰ]ЫvB s1Oc&pOAD΁$#ؐzs}W?zX0uCqVSi*OPPHE]ѱæA1Z5\`6h{xTCLU>΅\eȴ1ѶWFPF(<9;j18Džs\2vbc)AbP <,>^;xYN@Ms;3*=48|kXsdVPece5<pKfprw$D`ɠṁd1¶z(l#Fcca!{Ӄu)K2N6-mb8w[*W~ *+ahx? ^M w0!MY#Ơ"@9".>.Av'Bzu N8ݚ D9~}89ߡ4 ow\ 6{ktA@mz:^loQnzq9:?:FLA+{l_[<=adWWyV&p=7eZ³S{qaBz7t;gOwxyCsWE haH{ Ǻ-@ 0@Rχ+{bV!Va`>E7I] Tp Ao QVQ20e6YoUV?;2Hk;|U2i {R)"uL8hZd6P%җsJ;S@AJ.F14pYiAy:a 3-4lJ\\Җˠ%<[@$Ltq7UV M1spͦDM $>A,=|UyOak:]+}RZE {o6u7JGa'%E"1OT)Fqf(>dAPcYgBX~:WK` C*| "e!^W.qL$RW@jKچi +*1}5Ra-@O*q`uَnO=By!pZ %I :3 a%*W=m6 ,S 骏Vľ/[*.ړU"x0 vp7gh۷Rz|J΁p (Yaw_9Հ~ .K8bz~+vgX`a ]d[%wӘjr9{`(mH`KwЃUՆ1؋TFa cSi`jr|z:&+A3IPx$EhqW[0.ysvɨۿT:]vY8: ?;<Up($4N+Ј0@jD_M?.#_W2߽ f&咃Ro4w9O@!B@,:܎Ye\yhfעm2CIhx}&::j& [L,$(+7K匑VQj$՛.Fb"ڭՈ!6ؠjNRV&{LTX7ޛ&v_D`uƐam##¤p ќ!O(?nv<̈ Vh}+Gmjm64 Y͞r*IO*2[ض Ylj܁W ,'Qtnǣ>YR*ndD5s|6}|j[+l ̚qe/ kUEcIѳ`$FE/439[nPMglMD\f]Ȃ4 ^/8o›bG1o 4/VCXw֮(vi%gtc7ilkÜw5v%En3Jn1\B{p QJS$7 +67,g<yu) qsz>Ϗ3:c,s@g[mH3 >j5G]ԢU E̱"9Ef^.vy#A/=M%e ylfTHhk^Ȧ ycRY9e r{ 8,݀  mɣom4sh#8[t;jm$)yD9vnqΩ#zA|ܫgxo ""H_*PɃ';6S ,on )RT=%+\/^wg6A3ys47ֺ2)C"jQ, ļòŸ0f^ឥ"7&q#t؜'?1DCݥ@*o m;I{l'0>127[l.>Sнx\S9vdKh侐S4]OE/y/)mƩ){6n,Sv{Y!h 6χk= .-f%[O oh/C5G^&LLfRy)ʺ/J.KI{5pKw2 : ¸50{D(A{x m=2qq`;7ח _A܊Q&<1VlGD(AKK%-a,X1~2+{tY.V6_N3Su ;*+J~L,:m$h, 4`OBlndtNH`]p~]ǂ<4;> v6ʆuٺ5ɝkzrZ v;DU4$8T;ۏ1#3]Sf&,Dep]QiFųtC=%!y&ԔsP.e9#E9A഼AqTd2{f ٚCqUniQL[qPŇuۨou@{_?lkћn`ڽ)N g85У? ߢ5Tzv^4 R$&Uk-6.y:R];g=Zd=9[#bY/ѣ(Dn^hsQɾ߇IwKjH7A! rt%͗lTJ#d^m"U@Usտf@n"ɁO"f4m);L Y#Ơ$boVjR Om*4ձIԺ ;wtFB:s3Q)LQ*A$Y͚NjΨky˹\dR0\ho+Ɏv]di~}"iDѪfk|#ApO)h Pq4m& ?ĺ@O܉E>ktUH;q_p,yPY#Oԟ81Xoe!Gsic_wOYyP7)sp߉Tp-'%:t|~ NGϥ5'F:A94Xjt bm({{8uX8/m ?-< ,<j >4Fo"HŚe[,~]ߠny^l7u7׫FfuS5`rnNJA2㍆kLlobAh8Gi\+i~Rɼud7].m'HscHacQq˷4̺x( Ab4Sa0a~Vg/ד *{?\ \=_t?zi@94LvQotKPmDQ.U6[G|U 8ϗ4ůw 6i).)kd-Y3A`MʽJv=hu5bW]lQ Z&FTհV>ySWc2i;2 )Uz3j C9枦 <_DŽ90tlM Mم'b a<f/ГYAKk,_)K E1s=_Va-&2dDexs::Nkp s,Cڡ#0|jq?2&9C=F=cϔ ,Q<&70+-vdu6LAڞo2Ta`<KW} ǏPcd^DW!SVH9TX\W84דk$AnJ$ڭ:32^6 (owEGM߉ d}We4`}3˕P9-vJeb5l6|a0*}r-?66~F[u»[T&tSOsd9`&ғRG?.ФYrw3hH)9%E/υ-rXl@zZC49iC (,?oR(C~C9_ !|6ݜT͞I/_SV{.l Ԭk ]g:{ƫxޛxЩްUġScjC'Bƚ})a. "$EbJȈ],};D݆|I_Gx#nlG/ѨhX2c H a/IĴE5QCq$QҴpK~(@/z}\RQOl7en09 HA+PQe[L$o,]T=0}E" 5Q TFRm'RO7glMȰb֗nS6|5,Pyo_1s-2DF֌M;'CPµ:XiSiRQM|p/o:V3뚓);!؆]qȂCd y,Fa'V:\;qf9L(0!R+Z6~cV٪c|iiw@|C4B&q|k `,5]zMtn@8:% T߄5.hDf\DYUgAG}\ TJAPyfVvDY'?q{gk %iMd{٥9zPA`ͻ&P66dȰjqn5ɸï)f0wV.;mXȫ8p ? y5\lvg ^WؘKw/5B%bOqخp`Mru}ң6*^}Ntz84GU=2^pW}A泈bn#N84zp֧-w/}Jf|#$I4.=f/tD) "Kفc(_6eX^B ;"bp,N >˦`Y*Lӆ{Axu'Kjm[&8Ⱦ!IG `Oxu$PB3a^?ۈriBNK%]fLSS9mΚ>%85 u2bOnYr)up\xEB {(abTQUrnoqL_D>Do(v>/ 2(lj,.Do >q-"gOSq >}qANO ig2%XVr%%kJ\x\)}s=0Nl`poUADl8!pa.=^+C]Ÿ8lǢN.GV 8cvXl@trk%u fг~9J14v+g[edCO{֕QcqoT+_Ը5_x7Sn+GV$Z(ڏ3] 3ǤۋiQED dCjjN\O,fz:kx߁tzW䄣-XqH[Яq}왶;FT&Ϫ-E 3G !ĸ(AZkTE/l'7䪆E[Cno~[~<LJTv7/^X v/$*[h/p7wm 㥈蜩9꼛ֲqŅ&Ln؃HF?yR-x>vί@](YfY:Hr9q&Oѝܝec|XJj35,"ƾ aN' ,Zep&as&R68G񗑘 NLϒYɴ;$,i Hr mՒOc${$fγVg4Lhjo||9]>>)6Bt1<9榥@k,wֻܩ\͛L^rS) *Q]=FH Smn3YT'G$l)x|?O\)I3T84rf˞9_${BMd[XZ2Ԋ3'Is8k;땝3S&ZV@E_A!rE|C AB<ң,s-C, ^hqgYIu$OjQPƭabchԐπ39ziN1l_c&nV$9M0l:KA4y^oAi&%K8]&:]B`CI!c-̰"89A OhEha{\2.ySf6zhY~O0r2ENaV3g.!=) |3{Y.W%&$>MKVeɫ]AO1l EXf_T<68qwi!vcCh+K&u͇%WU- , e)w2P~Rr:5yIk OLDOcJS tlApKܽEV3s2}8 ( ]->+eTԱ*3jX֜P3-4߾}Y,~vTeAw>i7d6VXC6PV1|yI(HND%; zZZv?1'w&H_cE^P3uN_8lU(g2hj!Sfޥ RD}7?)1GV Ґh*KtZiw1EP/참$TWZ+"cϯukЊMQ+->Ufh'IbS+vy) Tfأᵿn(FV/W 0 ?QN\Wڝ4`TB0:7d=syunP4:5T3Gˎ5 _*-iKpXЈ±$rz#tKǘ[͛,S2mhGjr]r!C$|K{aCz)z*"hIpLKPm47w03,[_1Odmk $cyY#do1#~幯lf7,qYq6+,|eo2AOxj8^7IGfv't- 0wT؊(>JQ>qMQW>u}Wg`Hr 8iH.:^e fB7}^T%BrPup&& 25{,A[(/M~.+E+g/zȅN~> X={ja Y+7Ůu!NRay#VڙA߼D*זAC-vgOXGC6 *ћn_@S1/#O[O=}!ggt1e-ƨQ5,֓34>,8XT'| cʼ~9b+ R;x12MZ:Pnn~FC3pn-l^cy :$!bjcKU3wsrcOGNl% 4 CʿޯOGփ=INҝaIq-[l%IL4FR[dΩ $s׎,-~NDۿu$%7|*^sOwbhH(;rRGYn0YCt90 -w*P!n[ZʣGʣG+*Pov1W◬(@tWBDJ:F.h[(J[ PGROP`7v 'r{\,0_ft׋[^{^f׀GxOP/%6NcݶyRrN0O@ ["http:" | _]"1h"?L*$_djLkP/Nk~iWEDvA$Ytɪ Sv!HmyUP;SݽϏyS%EB/':xqnޠs`-8,!RAg`2v~#g1~<8cQ[,)J,*K$Sv[)nj;gJFC&" QY*KxjV%]q!Vn7W3b)W@^Y~YV'tH`hs8Յf؁yջl;WٝU^UwF4IdT϶߳5}\`-fc Au+zHrd)$9Ef;~%~4 cVx!}^B2 "ddDESm$KS2>Za x) chCmZ"JeNb,[G\:p25-PَL`*H|JD:l0gàCQ1h dJ%QZLY(ܰ֩U 6ò+XUlPnT%k#:AO3Vn%jMjZoV4 Cx28`[ g=Qf#1 UYA,԰ܪ=V0;em4}D)̐m8`Zpˎ}ǻ_׊lྺ[U{.XnLcTC{%2&G&dK`v)jlB&"Hq,  y(05y;[Z-.<‘ &by<2FD!@\4]M*xڵ /N qnK=R!.oްu˶r̺@ !G!Pg ]OA{!cYJ?K|(X`lIkgI:|Itnwf=tn{PٽvjݕМ5bfWu] /V?v-ΕE$ u)mRMtcdNͥ<:y/~Oߣ8>ժ9a%)5{py ŀ؍2-[_ igcJd6 ۈHn!C Ҽ9A`nЇ}a_ cj_ ׅxqG#`z& .[hqP&d?+Dd)Bl b5)$߉|Ñ-{=&Bi/{N T:J? n i.OVFy'Hђ¶,j{cLGGmpɬ4m8^ ekϮ|hrEb>ύan77mm* JGV]K-ΎטR"ZS"8rRB-ǁtcC3^w?ǏТE0_\T{]r)j+|-_ e3{bΌQ>;N:֥ ې2mDV=1=傟[M,2OHLU0$hcyٚ~^*=+V9Pu5U6e?W犖(b+^'6 r92hQv"SoUZR٢-JU*w9&, -'I-/ϰuz̟Hi$)%眾ty"c[A٪T634i\Ȇ1Iޑ}^kjՅ-a? yZʞg)L+Y^_>_lylY lEJr^q8͌:u/a;W,K( U!SCto/c K3HoK̼ EB{OGLTIHYŔY7x2ZNy%eBX֭IKu_L:~~%Y74xc>"62 2006-05-07 16:52:21Z mremond $ JI62Qejabberd_admin, restor< 2!xX[LMB!X d!CD@Mp ˮ16Rי{xggxv) ٭V%}hU>􅗶mmT)Uf}l=gn`ŕR?0̙v?|+8duA;_C=gN fRw_^-Âa~fl?Lq!8 BW2!mOK`*x!r`CSI@¿BC(ʰt D撂5iX^H3izڲ`8 eTkQg>? vLN͸6TMuZwjDސnZV7 N)|熣v`NQTgXꜼDOǧh;P&8N8%"Nҁ=GB?fTK$%8GgOq |q 3 ezY~ 8F3K2 (xa`&̰#4.EDH,j|dS)plW*JL߅kJbwWZr16S Ri%f ›~"/p$.8.V́'H9>9J!dJmU.BR[SgG*wq\[Cq="[^༻vB1I֎`~rH+r<zNĆ9WۉOuVrʗmu@7"Ò?Mg_qm>iƱj^mcTB-߳4gNICׯ2k57VjI;&&d<`ǵ i]cǭn8^5:WH_7dFɠ]nw(7T!>qqq f87T.(pB*#k-dņn$,I۫)qUBkC|zf֛s c&}s0byAαe}>J%r%?3 !XP:A<a|Xuﰩb MVb19uhϟw^9F]Ne1ep8`X#DrB ϕZ6 "OA,FVmԐ:0Mx8aCLܢ*oU-6!~5^L<ْ G3i7v*2ʖLl+\IDCi\b-rSšVi#*Qn3NO 7lSԍGsH )̽7ϰU7%[F3M)l.K-3\utK%J!ҦW ֈcs2mVc[=):6rV6xDX7q* (ŚaGSyt7&S4 d `*Q֡B jk BqK貸iSoV){."jnn_|Z)>~dʥХ R%v%Ty9^_>OFjEgv)l{$_'PtjDQ_< 5l$(O/3eR`Xozu2#DGz񔩁TgUx[܏/!HobݾL\Jwu4_! F¶x\ ?3^ cvVIYm0H\h& #8z#]Õ,o*ĄOGP' o2%sImT,LKRqdx&݆GODJ5 g3_E6f!35_F(mv^׭IrpשgJB?[o)bnCRX唢0*~5]ĻWI}\ &ǧ["dqY!4BuKƐCje]Civ|ӈ#!dsw-5{Gp3Ѫ _&/ H] QTBET _8Ųon%QQX2 >8;S,뛋+m:?-(n"c?ja߻bCW23/@>)_ j0ߝi/K}n`L ژpH]bZClM)DH@ .L+6BzɩFnAc㢷8+XZc|* }OGцhFKY۫uMZ8I0`Z@y%;[,ĸllM4vN11&eV7DE|ju={U?UHW8 !elǴ@*Ҫ}.-y[N-d|"'wHYg(,T̔do_\}įyiDWo\&Ʈl y׽z$-eϜL /rKRϲe޵1MNxܔff'GE+B-g_׼VZ,4/^2XXn[Gi r7̝rrz0"/m.eez=Ab3 Md۝ߩ㦏9os!¦Y0^J6>5!h#S"YWlȱWhV*4nfsk&R7&ɌvkxBNO^9wW-2:l[!TWebJ=3|0Lõ#vV<8fې8׽9[lA3‡t x_o#B@Q~rjqF͵wA -7x_o?#B@Q~rjqF͵w naxwCoC#ƿ-Pnnxۯ_o?#)[nxۯ_o?#)OtxUP=OPG+,(Cm-TɅIMZltr'Gaq0q0:;xsNν=J/0dSG5kp$jXR׈uM!]SkqO-Z!L\m(JtDZzF pXy m|:dΎ>C`N-C4k!OFs)<0APC '5+-z jNu=xݳtjعJѱ﮲oN]\ 'a3pExBy?AIp_eSn0&}6SoN pir8"Kr0D[onQsx[sL`;N:uS;vx<-F$x(=6Nv:|A==Փ'OqR/x~2vdp_{Nځ$o`2ș\naG#$Q(wB~,J$ d|㏤xC`od|+vζww_6E2͢8)tSauCc&H M^]khvדT4ݽ={v~J;m8cw*8I4N?|%nakؿRpCy ?yX)RO姓s el~#BPMČZ hibw!"@vS? _ ?kwB/`4ԖnJE4MViCh& Y[wUѸ$d||o(3mƮESW;/~8 lԍܙAXj{~ Vb b64i`1Sc LXƫlmtPedx?`P:r.1V}r-dOvOoOߜ:5}->'G eCMbKޅ^#3u䦣iʏ bdݩԽ ` -^ ttYdCkк~ψT#8̍XC^H vR!%< tGx6$RRrah:a2HToCS9fF|O쁖}(v(|v9 ٽXEO]X<+ِ^OuM/uc*y$"}Smϟz)Rft;g|_,:O4/zwN͟f8=oO/#%X-h|{Nb״h8z_~XPvyj|T/?A'|%@r\2?lI2 {%SU6.'WEz4́⯅l2kW :_u%?&DQYVV#/ϞLϞe N9ņDzE&jGH9:tHAC'={0D3Ƒ"gA^GdD] :}O ͔fj%pqdǎMðe Ɔ:ڈX؏^M@3eX㈚|٣ˈta^xcPVj[Gl0`ټs&.4Z[/ZqSI}S"ckJ06;T:h [)v^(ɛekh%!{fe%M{›t9y $޺r qc<Юh?تѻn[4<&tԝW!(u b!4࠰A'Rg,CS|'y4RS&Fy %8hV:(-|+AyW%X iGM 0/պ~z|NLI# BO@RD_\TSe R\O8!%SlZbB"Fgq{Me0`WtAڙS'zC#r 'P%haZaI*2F!|A+^4p PHdeUG\ #PтZ exjwdscS!y:쥶51vz\w%Ŀ(BDqzyjDZԡrɤ@LJl)59*fl3%μ8y`<7p1hiPFh(6mMƬ*˽XL:~yykoG޻ZE&&qDVidCȍ, p#N08*7wsd)S_\|3*ګͳY_'-.=8'wncO~t ;jT\1 =0_O9n8|%:r+୩ѫ(sC E>p 1 ]6tרp벡PV6WIl B]\X/6r';_'v9>,C[1sƠ~o@- %#hqyHe1XhE؋M h8EL4بwUL G(_109GkD&nH ␞cc*L'{_[ C5y&!o?9#|gcYGWpqExL%>Ŭ>x~:UIS)Wa,;Q10 /VV:dG])e QQΜ],K4/6qȧ(;u# eSW"ߖ.o\ :@<V]FW,\5+ϟI#7UXA$oÈRu&GzJ!6SU~ :.VP<$}$;k*?>yg\~ W2MQ W|OJE.9g0sFzZ>y+7ވfE5< Ό'ۧM&S"sDw~ĊUͪ$BO\%Чj+JuF1ʵ5fP/Ew@+?[|(mO)ׯoŇt*1k/|UpuxĮ T!>NW*6v6m2Tp](ՁejЯo6⵼ULd LȮ&n+u|U? M|F!apȍQm'\Յ0`]u3F~NS܄#cr6j3+.LgƵhJNݣES&9ex`?.ITWxkNUiїIVAk"P>BTH6?OV[p#)#+*9@BؖwF0!&Q)l EN q S6rasqiEV=5m}$AN˟ 2o=zi/Deo~H\\$ޑ%YAAC@W]ZʰYVM2̫%6T Sfru( M-Wժs`Xmd[I*je0!5nixV3f#fg6+QxVzC%lTKRt:$ N-* ׂŃa @VSANaCCͳtjJxV%m#fgF3Sr2Kr 4JRKJRK+rs u6 K1C&VTun5d9S& (Dn.sg#0y,׫M>":9^rddiujbei0qqN2Ӝ̬0y`n>"̨TcTd1Sg5d'O0gc4'uM2: P䗟 4.YȚ}xVoEO/iipf7lrhnH;nw8ip=pnT(TGzT*čffױBH{}3onvĥ?uu" Sh^rZ+`rm_4S>)R7(R+`Byķ<n ]WaQM 3 Upꬆ'>](.Z2\ ՠ^y*ҪKwXیnĚi^%u5Sl@ p0!َsH5G cɱv@Q_"-IC-ل3<{6YIj6z&{FOv;;Svp &+vU/<(!5٤֭Jy5-l#WE9iLi <:?=?<ү9\F{4GU0 yǏ_h|ZA#Z91Z/^Ftoqj(1"2U|?x&şG ~A:aVeE9EQIKg}R5TTJr-[NOUBa[<_r.hDp_jFҹK.QCm ]T(jLj~dfbװB)2z-_*Z#\rzee_zwc} ݵŅEy==~)'N빃ZzYR(19lEg0+A6ppoA-:ؐ~V&A`e+1̤fD"\ŷ6'BIPH%aY{ R w{L`dr- J8q(6 +UݹۑA4UYqŢtI0O :&Xwsr/YhXoZFPIתNt$d{hIAH|1֭2Ey:zo]43xnX]5_ل0U^ÍdT>v $YUEgמ]~Wjf67 J _V2Җz5/rj/$xBd[3V6L.*hXETٙLM-:w]-)>֠3WS.<BF0=%3ZqrWFoDc!.[Lj&kab0'84f.mH5.$ꢸ >[p^8z=rpX(2μw1?@p:<OmG*lM@4)ֺOZESҐw]w ` }Zє*]"R=z׶! tՈ6ZKfp?jMj+?bt4eX8 ov,Mj  n_xSz#fgƝ65lx{\~|#B@Q~rjqfF, ?\xuSKkQ&mm}-#U)- Jbk+M4%8fnL-i(nE g#(܈A? =ޙtjk)s;y}Yy.Tx32 އ=}^1?^8#_=硈;:Dz0DM&#KNlcΧewD!46эa«}kTs>rq4,[bIIz&r{=>4C4 ǹ a]۰$۹5ܛaP1y(s3sl\!(&L,jB&<1*Av-QZ1)3JC#"l ~uY߉nLf$aHĤRE%b"PLjZ,i[h Mѽ(WSC-nlJj+QvIaĈFlҘfFںKG@UUE!: Ҕ e)+-sfvzm?C)8sYvǽbKץӨs;`"XX©0\A:G0tm*AH4c(ljupv CA"j< l͡c-NY ,[ī3f,0oGvhzqЕDO\p8$cE|xJ>e~p׬vwM}Mbɻ!{}JDx`MǼc>|hy8r8R@a/KFs #n:x{\|/#f)V3'gx;Y~dB[qjYr~y~^^jgX)xX)ħd'(*+ZZZQBbNjEjdUz\ey*AeřyV`CT6gd VT_/?%UV(3/ݪ$?;5X#$3ydc%LѱJ3o"v[͟% \'J+O^'-ͤ0~RIeAPCfRgR^b.X 5+1))(E6VG!:6֚KardfO;yfA2&4yb&;Jm~Bu5O tdž* \H *FZ@~FI`)M];.HUZ~NJFZi#PHVњd8H19" 2D9楀t(ܼH ExPpaBbNjEj 3],6?`th4YOwrn&%U7`,AL*8y1t7OU,cj;;wZi-^ի<#NRIxZ8Lph&mK:naڰ]-Li(WZq/̌dm%NmPLjZZTif^_Iqi2t'699;M7I.Q@8&4i׉S(IPT&Z"Siv4J<͎O[|$%QtZS]3^$9!s#Vיr=kamtAPdd LL2-,B$T|גن?*lY'>J%HiPL$$ ܙk@nVf/FtaYpH&87$MΩT83UP.!bo(nu3\Bg/08ITRYC7ɘpؽ>4IU&6B Bp&7^n{uo|5uH]t;d8菮D#dʲL`mXZKqӘIH&OOPJ(kEQ+y)3Jfim=| >T釟h,*IpiTwN|йʧS>霞Nߝ&#?),j4Zezo{n#'oPiMP\f+ȯ;ic c;~D%܇WBHDv|,EJènz/əoB/{aF+QQZ;iaCw ݻ+&WBuvq{t6 ߰q^~lv9|莯j{ӏ6{!jp M!_Ul4[6QqdcqnIؐ@>-PC t/Oa?yZ?3$gb*@D2yMx>6&Uг^lJ̋n+ (U o+W)nΩWR٠e`giPpyǚB}+^bW9.9tY$&_9UF,Y:6D.+qA TdJJdZ1MQnD)7XQUj &k\s*(6t+zk(èu^Ѳ궺| /u#i-ɼf atphr" Z?+-64JyJ50).ۆ-Lg /ׄݐh7R_iY/ {Y݌~v{9* qh:fd1W_*Fj>r6.^Űg5ux޻wᄙAgt[M_,Xc2޹c?|O:JkۍXP:l?d9V.5^b]X?:^N كB=2b't^H4+-leFƪ:L̈́VD amsg =țggG >:Ʌ_ aKP[9%߮Ovh+4/%m, v^델jUS~4i<laT@ @X'c=LN=QGPڶ4~H9wͲ w=.U—4 OXjeW (sYd5;[eu><e>;d])-ar %ٔsδ$}v_?^yxc,z>ǖͱ*N*\v:v~t.nx;,{XvFF;x+8x;,BfvF&;$pg3ng e/.Q/()Tе&'*gfk;9j*q (KIMKM{WPw Ģ̼t̂ SQȯÅȢt"U@AqAbyKBf^&hĒXMMkxt2go6xʴY{3aS^x{!s^fvF&C;6?enU3ex{!s^fFF;6?enO=nAx;/s^fFF;-xVYoH~HB^agvIfr jt[M߷mdf,@v_Ur\.W\.C ΀'J>P /o/Li'o | g 3.7dZ%hLUII[3ezҢ*Y.*J?Pr=o4yv}d[RKH)7Vxi&ӺaR>Y9R(W j>^#JLPab J3"sR3bPΥQ@W2\ 'Ԇ8!Pf]T+ |[{TSf*fJy>r! FX,E1>Fn#h_`оݶȚ(DZ|/2 rL!:O>]F.not{36ۃQb|@< ;5!JOm)Zƅ[WR .R$$(p qQPr@:O@*£OO! SR _aTC atIXgy'Fh a{7JUR`gR+U{L&jTLN (#)m;cuD˹{rg )ΚrERsGC&Lj̒9L2q%6pKGM yL`l@DD's7\緑rBQۣ4L(F&N`?Ϧh#YP AD.7GjNPV:$"OWCti(Ve⛱6{qn֜I|iY A($[`8 ?s\C¦0]y!pssM&K( -m˵uU!w8 {G`}7: Qr?1hdEM Mų4zt+_pэH4ҙ'۵~Ed?P(&^Rs?R Z-B)@tOs*/TuE/Ȫ( *X#B@Q~rjqfFͱB \ x;#roB[qjYr~^^jgX)xX)d&(+*YZZF)$VV*pMĢ0Q]SK8OC]%(,83? lM,+2S&rHN>!0ٙ#qs~<ĒT*6?n4x;#rZd#fFN&n[x"Ed>#fFN"Kn7x$Id>#fF&N"xXs|._lX78ǭHXŕTBjf&y=#ď帎RuV%:%[8WFWZ>N-o*tQ_. 1L`/OV:.-اP&Ԃ0#-bi$-Y|4X&+-XhSAV!Ͻ{,2ÔI*#HdFPhœf*b܊;01НJ5IH״.=JnJJS9\ ( k=}7^$3fh I)M-HiM $kgs~L[CvT,7%gTOV]>[%N3~`:^{4Z4h ǝnkH?j'!HlėfJ ej֎? ҘR K` ){^O*{tnɆGM eVIK*t'|*u}>A4HHTi`>ԫtUYxmhKTAfQdl,ՎHqW&t=ܽʖ,*; )#bfa7II}59BmHGr.2X$3V1G_fsU0t)cah&T@?|jqw۾ NG?E)7Q1nPBaYm9؅07w(Y*EG[<Ӷgt:Y$IvX<>QyKP  TJŁkW k Elw(38#Vi)Jp{au[N5|yv3aW+"K%zmw^ͷtQY)2㴒?߶#7TXo2TKGGGIt#3P o)n3Rj$jWKCm9. gx<#B.+O2KEأ{}YW yV*Z/~eb6].2Le,lr&Ef 3,dH"SesJ'ғafx/􋺏 rMv@#;QҤ]t]{lrkO?U[v4HD)"hjď4R~|W\NR F'鞛Ōwfܧ˄5~E]&B,44+Mx[yP`ټ z v.j }B TJo8_wl%f6Ʒ^Ǫ] }'psV)ZP84/<6tbEU'{D&]~D31v0}Ao^ ewE";| ]/?ھAVH>oN)ogGi*19s W|ᔸ!11`;Q9Ox \"sG/hyBKWs^(6S_} wuʡ+Y OʩATsʈsTRy @WWgu{[)o~HZk5e||jufs)֙m<D-^N@3PuO͂{LTxo/[J%mc1н.sX‰>T}`0"/yk [뱤떸 &;>Yqsu3#ܛ ;)o>8_!K. kKc C؈C5W9q`;N㜉[Me/?مS;U,ƧP?:F緀M 3 "K #w4x|}([ނʙ@PHor1`b?P@s>Go0Γ*4,zE3If3#a'KPř#l3< Sz=m|*hY֍zv~r_]5  v>:P,E6iy dAx&_V81-@lBx[^iFuA|Xx[Lq6ɩƓ-2((TZQjFZQ~5WfO*b|IY2(3/"YW Y#pm\x{Lq*F%x{Ov>@~ ,DX6blyq3=ϻ Fx{_vB@Q~rjqnFE''lgaٜƶq-ox'{UT_KA3J!39?,>(G/Y@THD"J!1'"RAen:SBl9x'OvF|# ax*~Zl!ie`fel] dIVUq[[M]CM.\0$V9j.Q-&`b,ήl_PWTYjPZlZS UkZ-QYps{6 ʂ2,x}mSIgu4ᰈY b fg!:@E[M0>OfUuUKsec]oUѣY}FϦ*IV6r$oˢ䛭Q)6e:r<۸,iUyJwr\T)nIϫqQNv'}kv3w@H-w,-]rbk|gO1wAnGYeEٿ2LSS瓏2}isSìtlbIQTv~͇|frIZ^U8?~?6?yZGl ̛l Kc>.A ̞wEbav @O"i K!-+mA1`T?!)}7ҠЀDcVy~F#siOG1;lspk_/TaeWQ5 vB{oYw{={ph̻ã7[ể^wØ(E AevU~6 ,hh.Rzf_ IwsQ폊B ljzisXfI!F5;f/lt̷mR*5FA1)!xc^դ;t~ٳg^<9#>~ ҶU k}Njc4Y]?KA "ؾHJK,{'դ_NQ򼳺bok1~#a2(<Pʟt-ۉr$fˀ{xQ!.:ƱN1O?un[(y-ƖXtNaf7"`kPDN%=0Ni[,Y\yU6옣*vG1bA~vaگ|^ ~ "T W-V֮ PI ޏ15K+++'3xɴl,$sW^YbSYhghg5S;kj.V-PBˆAo-y:L- ɾk8fch;v'KN<8gO.!Lv  5'o}zcF{SBrL/ne"~}8Icf~FS)(-nnDC<يaiJg3#PnG\}gf wƀh? / G FI]y.?ѣѾ+xAwE'ip]LL߁vWAZѪ&E$1PCnA5~5:ILVD_ImX&؃x .YgXUm17~qqmHLI<= fb=!O'Cdc3^v'ɉu`tx-# 尰VJ#Df5Vf=]kZOC0ymDru%͊Jխoj(XICHD~(a{mN[K^LR4A}*"'3'a7ĥd7a* ٷDnjևY]SR(Bׄ6c:0#dZpr_+Mꔙo4GḣhLre!?!3o'sVyrrs7-t]9H[Xpϕ~vR =-'gLr"ĉ`%\Çqk' c!I NRp\:ގFPgb?olfD1B'U7D3` s|ư \ђ7'q,'ըTc\Z2[6'֯?m^&%w=uPGolTU6͛}!sEFdhl!ֆNȌ1o $gȰ<-=+V ˋQ1xKm7rUa_boqV1ާ$O 4G 6^t JN\sxt06tA5g!]DHc'|g^ aJjbhc ,<}]ܝV_^Q}+\B? BZ'JOo&ؖ24?A{}$5Y7="/`mi>j/'A@zceQ6iȰ0yTȬ#ON6: Lp.c @)&#ɩe鈚S~q%0"XрoOol>LDiv PdӉH0 |j?;$>Gc&V?_a{re~}@qɓEx?s5`Ț¼ PEB-Aa탷owz ij&3kY MҠ&lUG&^E4.Y:'{X}`{~4kvu,hݒv܊ Vy{pgNfXRA5x/0WZYd ^<ۺ.mSmO%ۀUrKez.@re:U Q]6$σC9IakJm|#] .A]U{;B3ɺh$AڦnnB%%cij5hA.q&7 %溎Qs_#{2Td[%~"͎D~1T֛={HBXۺֱ a2G}~mUwD-]'̀(g?PG+r tوkЀ>) !"/FvޛZ|@/4R.%`:l(ع+YaWwooz9'gK9Xt;> [;aޑ`#yOZnTNF`o~9)ޣr"[bZV$(JNAYSD#l$F|*wG㹍v_Go~6}}[| J"W2m͑ĔgKTjP &uPgK(5|%[Q誚JѭDrgÏL_,MKDE,u IyT#7֙˾e5,r"7vCTvB 2v2i>`OcQk8hɓ$@ dos sW>Q.X*( @I?XJ#t<.0a?^f܉J^@caS miJ[++ǖ6 &^; ^0)bA~S@f-V\7`)"z>.5%"Q,A/ZlEA*q5MQ*R^* ۫EN6|<[)5n#1׿g0s0P?"5* ] t~6-Q2̗hF6a6`8.O<$%c0ڻ7|v')Vk-wM 9:w> nU2@j6%F}'])W8_#Ͱ0Gf"H/Lf)Ϭ6_CEi\SLϦn+p0V-Dtҝ, })x3z,VR1 `mӗ5O8jpUN3 v 0ԝFr qK7)݆S.&3[)-DDF4= ~:ڪTKz>k9w)ϧn- Ѓ)ԗfG\ :uuE]ϧEZ׉!`#a Hl5۔9E=54^ Z]*}9"V׃ " b0 f j0vW4!19|:Qј p lE.5vI#8/|+l J!=n#A@VZ99*@r2>vN'j2M =.M] ++ VFh^} g"ک< 2r;/H `I8 ĕŪiy]tڴmZ5UXYd;bWJG4TN:PϤeB >KA"85@⽣Vt[OxFH 7+DMghjCtA\vne4y:uD#$5"ZPy:s; -AnC2Ns@NQX v8를` l^!(], wK|'|bn 2y !epyK0R^:E!&MN[#^]Hx7)c]:5ΦJFSh bʣmC/KKcl[BMt 6KL7&4g-'Pg9aVNBuYm❐|վ-qaܽ%,w/4'`^4s76H =R3T>[ϖ!`Mwv- mDWTiAEeGml#ܴa{Ftso:, 7Oپ|(E-e}")LP 6JIF\d[kĂI ':,f{xmg겜}AH^T8݁ܶ *-n>rRNx0l%&(^ `ĭ6rP xB̑5\˿F^_dΐPK89y=>{ ysd&'iN"zlƵ/6tCHJ5> } { 0Ig@(+ҝ(xta ?/4}AqN'g? ^7|~-Nq3e[]$W)&̵\ AM#'Мphq]Oe`κ>WCHHRpx6ၸ-€yA)!eENE2\WTȠ/~THjxꪎd;l)"^ +~\l/Oɝ=$Y닏7WڶrA\i:q`Rb]|AP) 3S{u?3}6p>18+5itB(8T” Y~8>SݧΪwA+߆X..S'( _Rطi4qO kFYBG{ 'lrYĦKUi疸t4m} 7 ;V0x/`GDǻufI>ixLOIeT_C\$+8&ʼs8e翌awI֤cfn$S35v?/+8#ùݞ0 5|^P_&7%\Cqҏ0gfs[]ٴ^8Ĭ70ey6UʝȒ|v]7eS6.t;ɉs&+ey1uK#g\e+e᫿ŷX"/[ufjGQNdbLz{7M| cNMbr(Q0 NwC<C׸K<꩐Sd RMQ}W"=Dvs@)G?n/`\I2۳XRPW#旯qm2oAIq^Ba"qoun^a{X]d c/$$9Iy 1bI((XaP@2 6(l&B<gXM-LY|L{X䏑00ҨȆfMJ2ЄuRǏX!q?| Ui4pA^e2v}fcBÅ) dءO(^Z=#1X[7m B'9 bWnRe6բ?k>/ib[[guvZ:?U,2u!J5FUP,/c ∄ifex[T%@ʼödރSn6 _W10CaXGܒ|J$ֳ-F|6EmRto bGLv<:;a>@X ⬏(^8-qaWrW t\C!D䘱|)׋+η2 1"4]Kpm\lEsFRZ?/U. "aW,++M-"3M-a=pbE |q'²s^Z}1ag-lYTi[qezd֒|,Ǟ\dS!e {m.﹭mca~[!Th+-IV.Y>Gk:r@8b}P&{!X7}@MI_:: U}K,Pj$%kuҫel!RJ|]::rzPR_SwANvK!pPc]bFŗ@n jY88ȉƊoB/+k`<"(|sEMp !uVcz3я]kSpA}~AADjx'ܳ$<㫧,HxxaЬǂ:I NJ8zYwD/r(E1˹u, 'HX p_ 2O:\F9-3j%ȸ#\:l'UvwEmmO5`9jc[YK.p~dHlWӞ͖J'YJ4}VO2ދ' q1"++T|1LM\zi-WGWg" 28Tщӻo'܎[nk ;p Qo-{aÁ瀿?:K1k&^bC-3j*5+Xݸ +Nm (Yh=I$["k^O_8LGIOjh[trx *ߩg?`E(&U5 /p~{Si72vGHGBLh!,vIz[XHf~;C͜LQ/3' C$Mœz䂲~vɞ{M&M|;aPr&K`ZZc?DܙUc`@j vl3Lҧ3?R% e{zTł`ͅszWrÙ)Qz8yϺU ,x~]]_X8 // *7d3o>38&t VUE):E䒟mn%t6sj 9'.6Yz4HD\N*#D U&R^Y(l{s2bd4sJlŘfbY6pob5$3dqP$.R1asyOj oC= TH.,+uc*ž 8{>uqցO}8. $pa IQu.^!04l@lڧ.sC87/I{e1l+BTh$qDqZ҅uƥI%.[ ٞ@,VRBc*W-z Ι* ! lQF>E>w% ӝ݃I˝i.%̣qy51nr˞ټ..'B~jD,* oܶ)Z۸ 2/wx;oM0s3tLpf4ٹTb*pGb WՈ$Fn]3rZojad;@ꆀi)dZ1Eܑ]Sil,R4`RUT@0Aa-!NiLoQ {{rDPWO 0?ؑz~gd|c"~Śg,! ģr#yԦR+s 7>f͍gVxőNN$,{ kjLvh=8diL.b<:ɦ?2g37Bֹ'w N=_R#1h+-\~w (|tLJ]%fTad.ғmB&WYOfW).3?\8? *(yIX$Ld#xϴAh.ɊڂE): .>rU([x{i#f- ZxB#xuSMhp'uk9BvoZ>@ݺÖnW0jkڅIm"z/^ ) }Gֻq)!DM5.+I6a+eZ HJQcIj9X63fi30Ls$j{~|bʘD?zͪ/{Ru 7!no qYTQI 4 ywo/q7ڸذ7gҺ[ X܅DkRN)Sݴ : "f$Lנ_^jwGnPTLhB=֚宅WL٣G[Ͱ;-vઙ4}}e79Q_3S>`Dkm ؒ+lBA8:m)g| 9%k5db:/5 sN{1;?d%slTƱdvsWY^y;a1쮓X|no8铉T)|ZBмD4E uAfrj+_-kopмUW-<֏xXV)jΤ˿HHN :u0-1P2M, LV_2rLCIj00L>$W7,an'x{;4  Eɩźy$70e\/ٖDK&61h[Cu-6;{x{;4  Eɩźy$70e\/ٖ"gfUZ~Qnbd=U^OBM_#sU5}ظ@`:m35Y^'bsY)Gx34 &ym$72r{a4x}k[#Ggrs,EОY`Zms x}0GH-$YU2o?U=cl*+32n(?KKKelawZ`uph{\lݏEMsz׶\h<;9ZWp7zi_Q y)H;v=x{h6Cmvw>4LJƪ1M`K pn{8 q ]s~ԝMt;ev8޹ y;u<Ҹfv՚ssU9;Q4'assfpP3zR\9n%^~>X^]\i*~Z,YՋh:x8XDFq/II^Kȷ1)ju.ۃg۠yyj@hvugoKQ o۽i ʹ·}ՊREN6ىtg|z~ :hLc7'ݨZqJmrܯOޙҍ{l5kGI,3*OA:皉7-ޅ'm!>m|©MHAԏ$[mu7lrF t$q_nV_}f${NU/svrh\w `?: pzs- %ѵ(qMx[orA )E[x#X* !rJ^]\QpCಪՏ͞ 6<:%-A\o|ͳPʑʍ!>oR%Z(^unwB o(G*t5 sX&dmW_W+;ut?o}(8`5aS?@mY6Ɠw?,{6#{&s@=Ny:uCs=9|,:0&9 uW- %RluzF[R2X+@A|YҧZPM*fΑCΚyCâǧzVXSg%j8O rol U;V}8 ˆ9]^&:h'b,8t]>2'idSaPVCorS佩Y:zaJP*Z8{蕝3P㖐=ס ,,3x:A+Dъ?s胰6 oNȀ8@Ʃ"***kPڽzh3uhW"e:̓v?P7b8sv! sikY^elZ4n~-BM_@|0eֆ1L>ѨPܼBX)gf~JݳTiq6/Bh8.r:5cz0KpQl ՖŜGjpfE-QjlJS%NYE%fq*ٱA"^\ǜZ)z|~1E7!", [Um6^TWh.߷ Dǹ跘g 1,'*vz ؟;6HC¾kOxGʤ,=52`Q{j]u]T`1~1vn44(~t%he4 vcra?=3kg;4_,.%HFoZIޏ|bғ*A qDۭnOsik9ی笙ہ: ͺ^ρMs=8 FmW]e;<9;OS3dv?AР Hd4;4iNw=bD']S QG h9$2> E=̹oaa؆elB7M_aIv>8 {Ull%TZ*D%;fDSKAl,J]ݰQwwLo3Bu b:c'7,`˜(x`Yh8/J}_Ϝ SGI3(˪^0'(!DB@d§jfZs Kν4 4.Z+8KhQ;n`8 Q3h;TAġӅp*\d(xKT)Np{:j~*l$f\/1*1< `KKKӒb( 0&v$\S՟w|mpeR)ʋPh`w+l?̅i)TB09vܼDN|Xy|]6'ER5I *%ZÜP}JR*ґTv0!ˈk+Ǣǩu'Os^5BvgEV֊"O5NiF'TkƬbdÌ^bU*ԡi `T؄b<,N)!朾p ʘ)fLzQh-_J'=8ug+ `y2g=F"68GCZC+ڿcʹL  [0oIfQ~fh@c˽fNkūݽ\NVC]V=AI#GCCG wa`P$ڧr6pilY1cR c#e{r48%:?_6[/GLJQkW lWp:o U4W;Θ^ow=b7Mt>t}!b>tCeҋ&"ʱe[P}b:,lp:\44rd( b$5O>p#賍]߅ \gqB|]OƹEk2AY,~'VXK]ߕE[nVRrZgGo~rP3Ov߯šprg/_7e`~ 2;p\\LCl~jqClO7V@ɓgXB;yR҇L .q B(.2Kh4 Fe#LSE@`VH&9[#"V9q p<Ͳr_Cߩ=cR„Ow@E+l}'+aFw@vneC똜v #O^n5x~F͉ >C8X~NzsҖs+ A8 GZ= CɇXOϾx\EW(`CH^7Bu @ݩ 5>dsp3? i{[Ԟ&.Qh"v3K: tS23R3lV3l!3\dJ%3u\ฅ]է }U2sLj\_NY-w1Re.]*R/Mtw"0 %NDd޽H߼dB.Ȗin+c]f=JxIMk-H~Ptb[BEO3+@M>q| } t/aK%i16*PaG0Sn㷒ʔ1Gm 3*hOBXT@lHm ?ɱ=L8"rE<#akm$"#4IZCP%r+F_N}yR] PxAAhPN|?.r=<r]pLv=F!0r%7*7nk w.9z'oq%I>[Am)MsBiЮVGK෭uvҕb(MM{PY\GRN{~ DHKmd+TחQlw*+dq +i5.)d  yB WTсy _o ;%dřvif_gv$xKu~ַ{$FvS~y}~x% h_R';P5Qp8D >@YTɘ0j@( CF->N_Rfѥv  ^Q5tj W2Dpqb Av*1$pz^_0P c@0,Tw| %m%A -PyJ`=Vab%UII Q\I%"b7:A7]@|O& ó͝?G$h9 Ey{cPisė~C_' &8Ǫۂ$drQw":r^S8TK o}V d.-K–ҟqߣƫODz <6@p Z^m Og@uiݥ*Fz G틘6T9'R z5Z׏Zf u jWbAa[fQ2"Of<}R@vܩ;3c%`šӸ!>1gp]3WeEİ[pBphAyԊ& Xa^ܝ6j0"wD@K;@6횅g%YNæ]C,DŴ.|\ .GGW :"PKqJwNjʻTd.'cNdEfEmJ ifz`йxJѴnAw)_fH+SW񔮢3mCzkhKV)&M7WxwtڼA9+(S3A(_~ކne )= .Mk9qv.P/a M$.(Z`K%w/TPc흳 Ա8(YbJ!Ƚ4?Ùh;rPewv{Jy_ȻdC <ȫsb nM`9H<LhfEA4Vg-dْ,/T Ip<#zоO}#v$B:²HJ{QPjy Ha"V~ z%JMϒ@Я 4 yz4/nUds%wq99Dˁ)>OCW OxlC 3Tͥ8;r dbtC$T+..q- 4 3Y04L^D"?g;p-;^~Uvxo\UTCގ} h Ծ 3+ɴB3Dr;.UN媅-`=2%4}9l๸LEψ0$U4TԹ=duhCHWlmV^&׸!&Ŧ:K6'uW@,AҺgp/2n\g|2>[Gg9񜿂ĽnKg p`>1Eźfp^]saU׈ 3-ݜk !VEDl`P@{ (@Pnwo;9ۜ>MD \wU8s`AzʝE¼[xOgaDBjSaHy[2/[/؋䖨O\Ƌg!rǓ>)q't.m'G۟l"]xD:ց_Bh`yE`)L[M&OӴ5RlG C} ,9;BM.3AZf9ٍ0"@7JW*U9oXL^9aFeF7zp# +ֹ2uW`tڙC٧mѤl\{a dߝ̨ઌa  a ňsHZ0\6W]y,3)yO  pPGQfRkXƜKAm+(7p"ŖV%_tW<'3,wx[p1 JBۄ4'ȈL/19Pp{k)̼b[ԬĤԢ͒>Dd}ӑRS+ R rS7+$3M,*gP 6$?>3H#$378DSk U), \'O96YysiFveSr+KMţ/wgQrqjQP:8bJy9%x})8C}7(1,'df aSx'O\_BjR"L([n P:S]2*;~ '/Rjؿe@1QlXR5QPdr"]`gd Jx[pi1 JBۄ4'ȈL/19Pp{ElK2ҭJ3JRS4B2sSSK4u& r O^ˢ5yɚm7N_i˥/.`-4d[$ipMnܱHh=&/GQ8tx/&0'S1,"P1ܓXkDQnNUNq1;x}RMo@(NŇ"@IQ mPI8h+!5jס. -V+UPđgNzm\l͛5{a3Ƨ1k/_wF BOyB~z_h`ĹB^4]\O+eySUHLtN1ۈҝ0a[cuAБfXfQ et" G? QS>_=[sAR"JvdIuR&&8D,򺻺[+iɢ!^΢0}D(!<)MlFJΊ߱! T=ti3Է5Z:ZSFHP먟Bf6eIC 3R>NH# %1^숟֍w5Q:kjSu6Ѵ-%zxI;Q'67W XuoJ,Tse9$d!KחBs:zۉ䫊??K(;?\YAi9Ex;ti RK2Jꊭ tSRtJb5u 98u >9Ѥ̼ĢJX"z^(x;tA LUY6d,-2y^fŦu9? 7Se#(xtb &n.PPP(ON-.l4f[E\: %E%f_0rpqrNg3<-qDz8&plLg|y!&333ɻlVx?HQ[8(&O h((y{)(Cu~: yy9Un)I)*Z5ݯkl8o8"|?5Ol`䵹Ȅc6qOc"S&{Km6̘i7yBL}Aoe ڻz9:9ćyN>]*I|2$by8RA-l}~0rMdܼ; ŠSa\˯9YN@~a~=6BFe7kKX2!x'ˮeík7yB=͟^n(;Ygr~]קM'0Y'yM?'(ڼqŌo=x;ib < EɩM962WV Cx;b FMgO9|.!JxE_HSqǹAIr67-tnkfJSP eswʽeAf4A DxzBkCW :89rv/6VZukL*5G`drZqHqRlQgҼYT c$"Ca1d\.Fې~Uꕾ4 ?npKܸbqz3Z܉lsHP^dp /_fl^'n܌Mag4Fp0.h5C6M%CSX7N5He"Ti;t78;ł7\+:p6̉6)u5/j\芴Du?y_.jr\O:<@ц w*Z~ㅵ=:U;V; 'A:SNÐhՅfn]£=^xSMLA.вE4XmBDB$!-M;`mw.P"mOEx =xP/zQތ^<3@ztۙ}훷+A;։nw{+y:=ϡH7*}5׻.! Gq|k./9ʇ,]`b?4VUXenD4j,>2jySY8O[DZyEV zH,o5ǵ3d쬮k=s )- tTcKtFt"RgEa]77B ֍"e;v{zƒAdC--& [WYjXS)b%&Üt7ZdX5F`*̕MM<1ȵ%kGڒoxoŎZi%_\!5%xXxtpD4ydw!v8DY4aVMiBIdEEqYMH(F, [neʠ-d4SڒĚj<]Utq:]1DcEm+<:Z;jB,6=RIF5*XŦ2Vle5|N,8OwpUpxo%`}:__<0gu،I.񃇬R5ûmD%5.Yp@U3,K ̦x=kSDzWٔRYƾɁ8 "Q"ANRjkFa쮌)E/=0NΩ{UA3====ɓ'{} ;sFM5Oo_߳}уgq4I[v>gQ¡[w Y(^nKv¯/^FP3wuqEؿIY@_|v.\wcoI9KIzGs6B󱟤5O9SQL\1YzYi¢ }{~!q#%bO };Qxȸc |g/ FBm0`TKE3XY}40S3 ?"t`V7yla횇nc>}5:6HR/Nol0~fQe쎢0#W3w3篆r , F<〻 b$HCXcv)r=?19JW5oAr7U7FޘO׎'˷.hV=:;th0O_{YZ `5;o޶5~ z/v2P//<}y:2,(Pl 7l?wo@l揗vu 2o3M&y:m76Ji~%QV'yHd=`fl[n@X'C~(n%v?(gB!$ O g4A$wܘk&u.^t\*wu2k"X NgǗoA0f!|#nex|Acj#}G7~08Y T @ӥ+SK^|__x?@BƄF[eʀ C4S4f9WMkD^@zRҍ5{S_'zM9,rlX1 Ÿr#Y=zK[:|BTdb!ԤcÜ LpG<_|-}kb[R=AdnOvAM|Ibt!`.n=xQ Ew3.rHhb`3,_I{M_%[laf=oꩧH h\6?s9fb> Q&!+%7]%Y@bCÆ'# F/3><69yXr`]渾k ogH&!zlLY33 Zy$.= 0 i=L#j-hP (wO OvP}fo&#03.7q$w)[d"zu ,\<&kzg=C8Ou Z 뇻;n݊37J0C*7'Y8C-#F$#\B| c|(P"6 1-+ڥ#6Y'UѲ+xf``d*SrDN<łr#Q{>kc0-Љ)c&e7 VX7v .aڢb4o>tAY0% jHc ]~W{^qd<B0< 0~,mڮXs @/GS屄"B[X=LV@x q*Dz!Q9M3 =g^D$mٻ7 1۫wtw.5~A3{4M+ i hݤ(<^Irdlގ MGcbA8E;(8㖻tiSiL{r{9>nwkYC XWabRCծo1q#B*}^bď@aKI4a~a"5n kQIGs^Qzk^I?\p{a~iR`&wݾ{^[L* 8\Q*cOs5 ]8foZǰu|_P fj 薇IG*e2w(GB s8Vg8~bO_*}R27`Y1tIsdq`t p}Qb4#IxAhf먪xb[^-aI!`T&6JWҬȪ#є!ĢiM5K`c+!B/Bp,Ⱥ–ǶY-lhl`E&޺T;eKX֨kcebNr`o$2%.- pm!A.+CGk%+UjPUUތ+2ޮ **z˟%Mɷ 1nf|fۜaα]-4dx- 6fQ/rIYI̧{Lpz]%[e,*,2*q4OMR˰ǒyXDu' ç`6:jOqm{@َdTұ.İ|w1m>*VQT{[vcN%X\Dx&dl /[n)jVg ]Jbi+=VJ9RP5beL"9I ҄\~ X~J]Uh:xMš}8 (ahM2LJIxHaa%2`0 `JALOen;+$ #S= P㏹?@O{HejMʖRv^*Phf&Dh㉓>}qOnT~`j^cXGl)9h>Ƃ*^a~p *Q +V*v,ʋUAPLK_+ fP/c~&Zϫ閗Dp ,Kf| ES!+ # Zb,"ae>tcA';G QHsOs,u1yc\gt5tt[΂h`+{Ѱ^Dd˩:T< ś|t{j w $|eC{þ:kN@:x:ʱhSM\6]'aT#lOM/S`"Պ 32>gRx hд7 O2d)!XUE?\s㬉Cla)0l:͐MVL;-t+2>KD+g/M6qLx@!sOҀj*,cRvp6ODIV"tx S〒5}rXEfHg p(C= `SMa;#FV&Pnl}Hr ca6if.kxGVbD&v"FϓlG}M'?q=0iI]|)-h\n "yز>زj8*pr10ŚD~4b*i[e;X}~dۍ'O,&m`Q;3$ȼ-/$ seU& )QMu[ft5n bR!YK z8eiB.yDJ0a~Ɂ,˞PU|6v^.LA!=퇆M(8_!x+QGLJq.qȝ2!;"w& _<8ÁX8;y"?Tmz3Qh؜ sT?|ͻ5'VZ _[NS% *Ů d@i +OJ 5{ H?| /_}w圗-K^I$ͼ2k%VM\58,{`t!4?da MPa/ڞr}44dz^ͱG@e*pdWi{3.S2Q `e霒IeJ<G1Zn. zY !|s% @(ץy aXASkՉM VתR8 ntECu0ifxab?:U[a( HStn7!aB=|$ܭ ʅ?<ղT14XqfUWZY%=Lv 'H4gH-쮎:9GX펲au>5j2j'R FU?P_E' ERXQvs[HbMEcHɵRĜ)D=C:䍩:?7{٧%}.}: hQxA,04-Tw4RM+#ra;J-RRuCWZ$B.PB@Pj]$\&ųFǮb"ԌD.1X Mh.w O3֜xXe̱|C dLДffalP:pCGnp͆؎b)LŽ~ʜ@.h2blu<IJ*LjFy!礪7 cWc*U+l{{.ؽB?`?Fx2q|ąBʔ'Rc\ +*96Dt6J7 蝠nPCFrd+;T 2gL%E+RnRg;2yK]DTe_MDPȩĬ4%]=h<ǚ-#d`8yY~pRJo/Ko^7KmW:e)%WM"Y[K?] ./vrό9m YVELgEͺJ/%A'+m@Ҿ'SVHbySл$);}j(SD2ru5R蕥ҫeByZUVV7B~ =?[(/3̢DA9']-˃",@G|M8gaH";x&v;E W7{RPu#\hk-2%׏R), ZvcSrE>,zPEm*Fw  b7@ɻc}!9Xz*V_r#vxasr})vw%8ȷ_f:BP JL >kMDr C8ÝsrR+4gFFjoFy["n!ߤ1 ɯةt(SgNc ;Un.;+@n]5]W 7\7(夼vy\w n)[/[N Mܙ1/o0>IYVl4^H jh'$Q /K ޠ tM/3,uxYkoY Dd6vfZg3 cd"j5tX=UƐdv(J>ԩ7{{{?Sۣ3W (>P/S$鐧Z43#.B(ׁ:TlL…}vcxw',daLf.OCj?хq?t*Ki:iЩ^,CfO,xyt[/ʷ g^D0&t愯P)4~pB:! (T/CoĊ`rC9KL ))U8HOǻވީ@O\z *' fg Ղ4$;<̇t8=DĤRYNʇރ>X:!A(||ƊHM!g13|1R>Vo%VMU ߃p&v=t'3:S.[atmrԿk/B\&*v~qė·<<ހqiL·$:,Y znuo_V+ \@:mVfYp3@sZgZ}\`h'\ eԯV5,IS8eU-?^QkMPlA9IQP & 5Z_'EK5veu-N 7q>%_R.7ؓ`ݜa də\؛Uf{3>nզꙆ͒r@]P%a vC@?R39@giP 8|诲Kbw1cH3vK>f< -{7bgor)i9LOgWH =i遅wNeBiO?$sCtH1NAIE#W~biEp>XE5+xֱ93:cm1o,z1;?Rb3)V g -8# 쓛 g<ܴ2$&gBBQ")ppܫ[{ḷ D:#kj!Y *[-c]PC"[bi^]K׼6\S"F{Y|\L*D)}[U(+ޛ۷g&[*;B u.QkBa|V܏ $-e#|DNw}r" YLIǢSdgvɐdw|s ;6lr,Bv]%,1. 0*3piXJ%%Fyi6*v4Ji`oe/N0 ??pJo+1/#~сuf.J ,SRoVcB-< Бk_B*--fL޾o?Sp; ֆR6Sc˙ m ľ.;v\bt2g:?z[>N,}b~}:o# ] gK#y7Mw-%0߆o y;ta&[=/}fJ"ʍ6!Dn#`o!<Z2% oT-38P٨$ۿ8mGs9?cHx곚p1ba7~̼<̼Slhx귚p1ba"+ox`d`ٞ4(%xuPOKA…n*JlHѡȞ m23̘n%~>LǾC;ښ̼?{ޜ>M x&CFPk>8P j9Ep˯0g2׬y/!<eA.?seTEU2 C*?YP24JŒɼd.П$.ciLjtk3'Ebz7#Tj֒ܐd*!}F#7|D@O КiTNtNaIſ3ftlY3Γ>F-Cvz-޶D8DQըk;#;3rrS) Px{h] nx%X[*4xȻRAA!(?9?/u?Ʒ F # Cx;}BTqjYr~^^jB@iQA~qēf>貞) ``bP[Z`h`d``kD@yBbNjEj ,*#5tˊ4UR23@ƨ(l>r^/Sx;w;#^d&)BbyxZcBAA!(?9X7?/urTƷ f 97NN1ȵ|2o <2 y:\ !%F@ b-C0PV l^/$nЎfr"EtA<.UUԒҢb+lQ t&o^#MF8x[c6l#B@Q~rjq^@&io70t BixuJPƗ"(!)$%m ([\B9%&Z|[.:n}8]<9}{giϞ*SjkD(za~˜h`L}@qlcpn6۷S|)DK Ȭ闘w(cѐ &,8Ÿl*|= N3ؽLRțd̽/Ղc?1ւ2LgXǯw5{S)eEV%E1E_:v,x[cl'#^@&i$L۴xXmoJ~Ut.IWM i(InE08c4b93`BjQ=99ޟҩsDsq徊&бY3~'_=fL2TPdٞJ~"ߍB*L&Bɛ#VN"Mw|:l7c-\D8œڭsUd k4jұJﵼqڭC|n>KdFZsש25-^нZP$E$\"$s @ic9{H") ʅgALI,CP$HU)_fgSbTxA \ nڅ$ rv^JY)FBEgf*ET3(Ew2i"h"nH }ߝ]3D;ag0&4A#}wx27~o8шNφԡp;wt~115OIwFcWN.F;?lL/GUR4|k~k>?mW(a3۵n ]b\08M!] يD,rլㅲo^U'AS8wp4erJ_`sj@cdqq{V?VMz&o=K&/b-&_z\yӕp z*JWT]]Mzg'W/j;hRe$l><$kj._1@3 ء6uӤ:$Y-PMz&BD|@&ϕ5"\rPH"S zㄕe:R!֕)W9J$8b0)$X3LzwL!Sli>|#;Zel2s6k̊k-T*>mG]y<#j 4 > sMw^:׮r }o*$WIeĄ22̼ ~i4[VRG֖ujf^Z X>wsv}7 L"2{X $Fpك=wԳ2ڏ9;Z[XKwjivb@V4 НOvTőgWccZ5)T2n: =w˼_ AG;^ z&*XߙBؔAh~!J '^bTpwfYZ1)L,zn~ "@x#>uWؚ&p+Qɟ1??$?e[~($~l-pAi=..UU+bҼ<ҜTԒ̼|}#.!&L>ţ5DAɻ+'|e䌟(`9yd QweAD'Л @ qPQy%i@' 4 ""=y t Voxn8pqƈ'f1emN7Xlxn8pqƈ'΋#Zo(xn8p#f`q'QxnxQw3#B@Q~rjqnfF&I\`s8sg'6e᚜-$3g,,!: AyO^#,h=yS;xAkA/i!TzVy,¦$bbF!MA,e̾53$gOFzЯୟkp&ԄR̛{jM&ʣlP2|>.Z HqG7Qd vѬ5quw{D#|(&e.؛Z"YR`Ȁ3wjT:%^yODD4P {T^,Qxa UH8Dխ8uH>h9v0NHސjb32z%x@7`1 1r (Zbi J[׆ j Qxryhg{0 *TD@1\+) .͘t\y}|J&.gQ3&0}!N ux|yT{nA q  9Aή 5*9)ɉE) ZzE9\NĔԴ _GE V/)51WSG I(`ũZX Jm<(v,~ xqB([AiRqiĩv^RjbBn~J'?C(??,ϖax}i{ίЛ>=\'es}:Ǐ,ɶlm- d97O;%AA_߇_~))#Tsũj,dK%oYY j״ Q{Ct!:e h=— ޣ)YpC ly4;zVpx1L>ʃcS%؏- ZέLf\[ Jc֘ǶzOPDR4SUaKН=4h|`\Q퍱jUy\7XN/>0 B +6ͰdFAQc6PJRբl>A݋ZA5i+PsO2gtùcس%>cp$LOVLGD]Ga;~4YEhZcgn2ʄOA| KEmWA;LOMbASgowl$~51 A8~Tl|:&`)hSBez6L"_~ðD\]v?F}'l: 7̟Q<˖eXwE+d[2<2<_;:n+Dۦc#`IjĿ|xGj"#(1j c_ѓ_*ě2O$D9H95_ӆa D#~n k-a>{X@ad횠۰X* 0?ooI3A $YԮ/IC0nb` #1Qgr`;()("ST"yEGܠ %r6)Xu09(P@H@*.1T׏hGkqTzLQA%Y'#N@%2;j#cOf~9u8߲ւ(Py92(;lkiA C`^9]_Y  PP+.BB83쎹na0Dn 08v=@ }kF&| M)`Kzj xKGS+TU-YAueXAdy_A 4 .TB*҅j#פYk@Lo<ӹ}X`g:bp:&+<ƃE>Eqǧ'B /P<;ߤ0S*F,5|Lgx >Oxw>:Q7itg~n9 !p4."ْMuڑ|Gg{}I?W#Bop?$8GCىY_2h1~"~ hԪ0̧AT4 bATa(.z1N1*fӀׄR]♾Np%X mӆ;i#- S-Bm鲝twcӟԉ~\n3ܳ#_Eks&_˄3-#<ӠMuoMϻ>_@t'"?P__y}&Ko4R{4+E)8ou1$ܚ^k&[\iPۏ/s2EuKX0` C8]n](!"8 j|`M&vPwHHOsGl* :NJ -q-"dQTmS=m20=(ITE,T;= 4tcwJ;w/#pjWs2KMB~N| tg&_`?L;_s:-E.is[ I\2=4,`[ 8ϵKo"3C|JFdzǐ'LB;ޝ&zFLz-H|̱mz5'XȻZLd x\ݢb - m^+ 8>:80ua֢kEWH ]+M:]z*;!\EJtOtO(*r@~m+n ZUd|Y ]J>~f(KZ`2=]B']Bupso2F1Y_|A?`yeЭ;kF{Hm֍JNL?hBG3#f.lf}ItL1D_ܢK_ ׈hX^/It cY'lН%?SDP ۱Wtb 9 oaI r ؔ""Cd hc (V?#P#8A*-,,y-.{HB7Ac>()B{ =gl76-!\&QJ´~x?q 0m,2Д }`$i\ 7_?Dq$D|gZ3ԁiA PЌwx|P0>~Ģ /__7y.N9;pK<ϧ6/d\ " ĥ,Y} MpmT :ss H: ua0G :#`/]CDVYd *ň F0ndR:q)aGGb-&puA7’:ⶑT >ŷoIeB P"hzr "JT1JixB6i,X2w>kGbIHA0}PIBBC2P<-YvJ%#\8ĩ_BF(}I=J(Adؐ ~ҫximOП+/pN4w.5֟^ `#np2"7IX/ܨ2?noAE +P{E!"9%ϡ¥㘏0>U>( Mܫ2A(l=FalKa ~ M}EՁ"?n-,kkY{`XRG!_H޾w {5mOZB|*|dݧ;~=y8meF^D"LC`ڀ4`{R qA^6Ѯi т2>)0>`0bz">[ӎneX &o T7 O^%Bd#{-ƩAEro(CxSV:/AD=Dv%mS$K,KMj ?pآb8n~ 6 Auc{{Аo!h#S<"n[>7\-JW`GS(0<B}"g 6mXDB^r'lhCC2IB&L`Z2 "ž4 *Q< qѲ,r9`P} kG=% !iB8`?*hYy+kbܑmvI38@'Rv ͓HH,&@D%kEz[^t7t$~-j-:ž.AQoQ(ZS<:~`KZRŒJ$ht.b .įΣ߰0 Z`f{H|O{X,{ɩws MN! ˩OT{e* 4pAGR@D\0#lrtҝׅ./f@# QMA70(z5Y3x YkN42 䍭~ABS:}U=p fte+@l@9cb{)mߞH 1~zV4Fb>AX-=PkAiHX _f'f]%F 1цZ1/?NHљ@$ э'P㑂bIRH =},`qj;E?hm ] D1euފ ld%>ji*: D8IsO]<.!mt/yY 1$D탦"Z"X?N D쇿Ⱦ,!ťCp:/p_\]>yӜG4:mC~߁YQ`[WBs@?0Q , OoAeeF>* tAW[h hH 8ͫ !]8ou]8m0}L\p' ҋZ5?!qP`sM[鋤dKPC z"PqG%2."I i|:݅Xڼq%yfm+ ZŚ9 ;A~k\]V\.7uЇY!/`FG#6D-jA LP\#|DX绰 Ģɴ<{3w̘X?7}B>Ă#)x()WRBPDNyy {fi4K:)tm_u"Qc?ڐŹE\rP]`M|1pǣ+/A\$D&54>wRl߼ؐDfz< |s[-#<xK|¾]0IP3A$1 rh}ġ?9ݧvoQ6 _ VyG!붰@Qgݨ37Vs*s\7\~NO0 ,'YrLc8l;Ϗf2ࢫT;rŏ⠙R&YErm6Jnz:ވ. o!ɼJ_fsRZI~yڽbbd*k+Fj%1۹}ɮfV\+RziX2SoV)ghn1e}[-fQFKA9>-EV7[LˏG"-KN;T*jCj/j-$VEhۭP_[Y' Mئ.JڪM: μ``U=!I R_Zuxv=♍28Siؘ'QDwQo/kݮ%G؉5 2Uߨ;VMzfe9ni+\,CzPYW0j%ƇR#O樾K;mXd{!&xe3Km˲'+D62.'5VܸW[~z؍"i\hf3iTCj,;ER#:9O >tBw=̬ctnI܁Kkf}S;+^unil8ƒY~9$'Ykey'>t}>o`vGa| ծ1 )1m~n&B!gEId[ Uw0-0y#l륰ގbmjtZո~hk!B+Ј%TQ\E_J)Q[d(gYXWf3lg%Ȧ0Fv֠.f_A39Z[ }sjĠ|6MKLo<08ky;chzWJ)-a6EViu7vBmx;jCqYfU_Dd 1YCNqPvX_6ЗlDG+/&S6HAz\f|PCq 4]W'QŝY 5>>:5:BhՔyyg Y&?;X֙ec6V8Xh#NV}E]ʚm{dc^>‹>dE1s0T>mg"Tr\AnD\weu^D\#*6-c3Ag5a3j["rupFNod-m#򾱋Nx[rhɄuZTMnDl)SU,e4X}׶v3=%$l[xI3Ac2?,pB-3i'm+VoUkRq^VT߈^[5Yfw2(V!_UĜw7"_s\Դ&%&7;9DIkU):Zκ7۱K$aW/-S8'E(ݲ,'}KqWWҸ*fR? >ZJim\άJQC7U[5-?un-mKbo-FJvIGwRU#*.j*+ba)Şݶi)F, Ż56rRHcr{] ZDٵ]Fp7Uv\ l]VMo!"ZL.7loLa҈'4VXmĐHm9\[=;sZv^lt TT ^_ښQJld9Q3OV9-FLNí*Ufj*FKà ߋ:촭u)J*OZOt[Nd؟fZTԌҩ\#QȎwF76/-BRh'fֶ-&:ԑƶ\{> d;en!<v/†CZliHcybCYi&3A]ld#qs{!=[iyXDȦY!pKawH g|A\r"n]'gJՋ͗7,j;+\d'vI:YJmHg8/.re8ߩZՉepn/{=\Blz\NTJڸSPr,rH@9L0yVesmM9ڲ5sȊ,BWZ;TY,'b~&vxP])4#;p\J?enO*%yʭqR2x,K@]`<LDGn/ʩl5Yt8\_%֩M"+#jlWC,FrtnrUZdi=dV0FvXC$8Zm<%Vi̛S.2˕'n--;K%;˨=pAn-? ihF$ɈF DZ5B=0N$̺6,Epm)nvi ͅ<_ 3r!Cpu L TBTT8'*ct[_cOVIV1^fA'jڪ {l1ƍ\}/24dt2?IeFu[qt4=&eh[fjφdY*גFS-W%E’yJCa7&0F' m3ZFoI?vw[о|/ByhH [+6VԿrJw])ECK'懤-w;Hf'VXhwI=ny[ + OVL,z6{}6\l~t UqŬ>c7QOb_=tPm|80Ԧ,j6'7UذZ{1SB9e.*2ۇpI1 vev=yXB Z\=Oj B"ٖBKF+gi b;A"UuWbêٞ2Xe;bMW iQ-6wMjTĖ +cI%{pvmI>Ii=ԷAy 62nOP\ F/-ɴ>٢փa>θE֔G|=+ʾH]~fDS0zZv|n\2[Nˊ<=H4xI%d{Pz>Z 2)*ވan '$XNXsֈruX}%?'2O H)7Z-UgŭS[QrLƜaXm#Q( 2LF#/𙑘 eʚ6s-oƚ=b7QU4-\ܦWYgTf6ˎ21&B.1G w;RV]-nS( +dھ$']JJ)YzX:%Wl>^a!2r$BfyCE[nW_O7G {`{Z9m|-Nm&m)Vk4\M>3 ҠbJK5Х D7hFR7SvsL-r|?.ژ/a1#ad8lg] plat'ړl..RB@),uQc5%t6%m^{ܖopgQ(NcoіN?.hIwm!-Zv=8gڳ18ᯤV bXo ! zTAs,XF<ʋE w WjiR`Bj?.)mVbզێUgNd-5ˋ.:ZU;R^W}7IQXm!7yAؘ7d)2pW,wGj%vI7k*g}YJ)!\ :k"]WfP-] ef)i݆#2dEv]Tު(%!+1ԋ5I52+lξ W&Bh&BfS~[lOHnhOb26UӬV*屬g'z]Q5O87.ȫR2AtSί3{RK(^Q։3ݲG;^M(R#ma8SWV77RVղ~l!RҊ&߷1٧a&ZZDP1`AOkSN e{&Mm&}*in#] ;VW,ʅyqZH,zYjylFOe65ߕ:vo\O*-Xzջ2k JlL%3ģ'{VJ|ֽ}8Y)f# 5Sq1 ֶ ^U'^CӬ7[..D)ej c+Fʅ(RTBX?fqkcXHe4V5$9t\^RjTΤ|O'9]擓qG4LG} 2l~v?majirnq{=$xo@ LAϦp̕ U a(Ã3@ /Aqlߧ,c@Q? ƐBϼq, 9osa4c#_;`B)1!xH),3"ا#6@S8H_\OϨ8{SG19<f $YAr;U޽ |o)0[4)ר?na<zWNdi0={r]w6!"o &N?xhYXP/c~wchD"%tx,E,p{$l+|0=cS^`>r} wיggq?qQ*LwŎA|>GqZ3gQZ%y|Z1[7$K<?gfSo`{尀`mjO!/*\ ~b\uW$5&=q U1)%J 0V@hEOәqgx_.q_^4|ƭd"c_g?/ V$ vix #!KPO$LR`YbZPLvS"Jo<|~) z#GxE,;EGyho6y=϶yw!tuH>z ( ~~ÿ'I-2:thF ?N tv5O%S048<("MYxP'bǿEh2xGӿb6IAz"DSf5@%O rРUoQ/ZBnw:QŞ&]S780s O_1`AR{U;p+<J Q U'ЗǹcC֪{§?A8n@ ZI/!G:Sxu-b^wۗ {=c،+bb׻g}!|b3KT*NF~әiaTG!Y7z~JK!pQx@9#A)H0!{7XdD ~-t9$|(AiaQ{#FkUH\2Xdir=x:0 idb&n n_-;>5ar-e{e=#{:tWH/CJ` $zWNrnO *īuhs 7!bC]*+CffocyBu>;5)KG> Q'%|: h}K@%ބZXRP $,'c9w̏[MPT?~qKȻ-E n>g~%c3,M @Y$"Eb4!z$P =Ol4|N E@k|LJY]4}ț\ ]T=p7¥҇S&{n/L@"9z4yyk>^I~~Oqa:ކ+4`Uh19.}]yRѠuJ|=oӔ ~SޝfW+ߨU 8_iWzYb͚3hM~z/G#tSHVOTo4֔YO=:6 n;$VO0B j]A˘4S,0o"ʀ `=^_Vz½1 /iju"1jWmM 3pG8WB1P]pl UMīS7SN"vH9(w@PG3#BGmkz A..H<Wo(t^eRMzH QAo_`z&N>f w$lǼ@A@@ W VIUUY14XiDqU< µ&H&(@2l7byPg7<dPȽD2&o$ t 6X}y8( TA{7bZRIi{ 5tYC/)>(z 6׿7B^VTQA~x4őPD0%5Dw9a_}?ݺ]hi%گ7Ԇ֞jSC{ƀE&66p5'k%4z^lIs17Eri'^_}b 6/Q,isCi8eXG߅ֆgt %i-C6HDy(åZEZ9*7 +Lk^:/V0 XTg{p=~΢̍d A)՘9`JhR-Ln S`!ˆuzr 0>m2 qX!Ҕ<=v69hnIy)_C ?0߈EQvS_#zLMX2uħ~:3(S~z ۰niDa_cE| ])9 N7 8/9'jxzWw&.*@N,CǏ=i"]IVM8B1|7&} IMjԁ&4ܷln8hZ3x7 WAB8` p21@H2հ,^*E2x4OIu7[> 'Ƚ! DK93xh%KZk@4o &+#U`.@-ƒ%e.GZQ`Z(EIKxD Pȟ- lj Vk7hyq %a# W=+ƠIxƹ7h5p R*#=Y-5WDK.$|t8Qp3:6txø/p=ps-ui_h)C`Ʊ緉pm)AVHt AuH6]Q!V͐|tata)Rwv6/(:- 2V1/xo7QPcVO!фr0BnVl;hOE"T}RbvObz"5yx{ rF;x{. BEViE%%g T: @T ēc579HhVg(lӋK4 ulb씀L%M.NNٛ%sRsSJ4t0uĨ)Ak%MN 6ZC6$M&5Yu5Au#2iMY|Ef) 1m6}K2\>2Q622141472:?VIs`{&f̛E&qħl5#%a x{ -}*99Ee%ʼniEeř%Eœ7Z ۇh$Ks2K4B45'7Y ~M]~%'(P?&mTɡ\\Z]yc|?x{. r}< 2x{iV r{&UP U(,IUҜ|~sKF>T"Tqjn LNkSx Ls7)˴P* D,xUSmle]i]1X:^{wK;:@ƒ9h*ܺz7{c'CaKΙg.15F'5$#~0cƈOre9zRO5PЌ㮗i{B~u/0S߃wLc Or1ПM&)Tp?;4^-Ln[]p0tB?S ܨ_~+A[""S[D: ox#j:.t[kètf^`m ]*^U/4?nQ]5_-apbh#?mMH"NbZY.)gƻo#6]y}s nd)"y K{?J6e;hiwWxδi#fyFa̅ LUxʴ+ㄚ=Aũezy%v\ ) ``b[Z`fh`d``k`kd``nejDQ Ey) *\&m^΢ô1ִĜ3o`|H@IT(5+1))(EBnzy}MMD'%e&gO>f~s-#V\%9UmKr&o.ilWzT#&@J__/:N!VKIGA&Q!(56FI-FNF?NISS `͹Z!xq: Ffƺ& &VFfVQ 9$82Jrs2R5&'HJjpqN>(#;y+n)ɥ2=d'0WSrYEJ?)jLެlUlQRR`_^^Wn_W_[2`bFjfzF PaByfJIca'MWIܥ̝ 4"xQvjJn>E&*rF$Vn>=-(58?o;=z\ɋCWH12L>kHN2c e|uHe&\" WYEt MBrNbq1 )䅱6)eʱBT7ĺ0N>'!04)+5d2c| 7,؃K57ǯaaLܬ5ycy vJ: J11jwL7fT?OFRA*T\` `SX>xWr趴x=ko㶲_Edy).Ӵ&NE^v @P,:V#K$o㺿 dqٶvmp8/C͛7ۯlyg48tD`7(G>c`'~Ⱦvw8$َBjv5'Q¡1KIкW5ts7T7;wcvΞՕ-:;&ؿA5z}.CF~]|Ɯ$n,{~4OzQLnp/c8Ky mK*-}ˁ>ȡ}C'1ͿXU{s?IƩA}so58ƎAbv%Kc`s[|pSŀxqЇAljwG7pFR{r`0 'C'XOa@ pkb~0]CKU A0m)3 9K~ [ZGgCICw̝^M|oAee`L :͍ 1LGtHI9_=>t*яdNx,zZ}չLZ˴®o<_C̿ <'؟]!z-< ޓ\KM&g_vĤ7PeqPdokujiMÀ>"А:\@˓3~ "fex'`ɰEN8ܘ#Tѹ.@Ӆ1X7=|{㷾 y;f@y=CH!!f&9~WhlR[BOy)LLLR5AMr |6?4HkИfl5S=U'Ɋa0c ?'`7chpp|KsFl8Q8Gd$ L>d{v(\0`DQ+Á!j,䉄@CO=Om'MNvL ŜPJbz f ]PwR{<=6LF_, r?50taa+HU@,/01.4<I !0}3tf.:r!Y49ꛨ;O+I- 0X&1"z8BM Lb>1Q% CrWPlST>F|۔>OӉIjYVo!VY'Miݮ eWе+JG[N6`amY7 L&OIaYdlIeVp71i.džܛLo%05 RQ\Z+fXr\<łC;US_IInEYI>ԕ `6uߖ9بi"-1?0JTY^Tg_XKc57:XQ.Np~C@.U8>c⠈@-( ]=tڽywq\G4k 3j"A6U@v+ 80R\ڎ)}4.̾rNpz˄^){Ƥ»K2+|}ɓh jJeJBަg(U6VHKj!ON[`Tn]˜vš"SK̩`}0i<|ihFf|.S`˅@U9-dD!A`xDr ?U̅6''ې.}b8BןDp0AbC5ZU C|Q$<]"^{Dl9&m&BI#f;1"z낭G3#;-\I$:4cJ|PAFn;KaKP-sz!z&>[n'30QcYڤ2B Jl@3s P孛«XچQsp FQA:(qЮ2sQR`O6=C\@5Ui1\w)Z ɅmD f@B)5/Ԫ)lrnrDuŋldx_P|0`A>L [WI[j0m@8(X|~4c`֝>֙sCIu< ^C˺7'O Gh4eG`yB{kɁwS*n8́Б+[\a,G.6{^=BA^?e(֊KBAպ*Qۓֻm!L"GGuA({&矾X&(ޣ#L5m増bO2pe,Lz`l٠z]$1舩)+s,5/dЌ}S<ٰxZA?ut{%. '4'L#j2UWfM*[eSM]5"^$}J;ɴ\)T7|kV s"߶:ˎs DŽ 9ո]vt^%sXd]~? 㡽% W|_VY$vEAvhFQ%t3tzZ[kP#uzx[/z bi| IVNv&Lo9CA&c{vmd6"Q#bpo1.qSv+v7 ,1I,szl"y%ƍgȏk:a?cNc\7"L#u"ĐwF=G7rZĎhUY"vtT]ƝQP;ϯe_OI#hXbv9B{Ss!z^ }k|W7B7JjShyϳgmun'"/M] SLA(5ç}6hUNzI' KTUPb/ ucCN.8,ELJ9 hqb̲]Fza"z<${Y:bvZAc0D3 Hd0$6m6p{Ւkz+{=Kƅ=b~ٶlvJe 6vC{ze]ua-RaM!PK*^$R{RƍɉƊ2(ӱY7]Şj/R~ҍIh-KKЖ+>dQTaҬXmNr%#d cIHG8.μӝ޶:[JPm;Q'x:lfoMzѿ,:5ja#Uqer>k$l,%-7fi^DF"Ԍ/D,X |Feau%̤%$!˳?tquZ߷V'-UːeAޖǰ6ϕ _nb6")xn,6Dڟ!kdd 1r**IBS&kc.  (` @@qtK Ų\rc\5RfEP{!иIk譯?7;'xƚd4x~}\_n%|"m2oN`%D{|T)'3Dhu%UQk!JT.)f¼ b*?޴h>5Jг6([>Oz!tzL+㬑2my6`hOܒ6kۚaǥaI+U٘8Et/ĩ*iV~n4,=YPTtrff+4mQV^Ɓ-deix& {`s ?yta /pUg?QFJ\IpɕbxYa G\w+OTW0pNV']80Ȼ dFVxp~:Sbn" 'y&\-ެ\%6I:)yVm!4F6#6j#,珳^^< /k XPi(N-%0Q%mՒ.ÐlQa0pڡ&6?Bmb if.1} *a0MF11`X˴C@UbAKy-eg5+PH,ݣ%k~;Q/ ;}|g/z8mo$l2r`~3/0zׁ R>&([W`4nWyRLk´&Kvk("6ї"JHc {sә`J'DR\u4 ""{%W- ԋ'W7K1,,tv2re JSqǒy4zœWa(=Yȿ9=J5HH&ZDŠђ>4{ͅk Ӏg#)Kh6@.$FrJXkywbҤ?~wb[9Rp;@$n7m z=e2G'$!b!>EY snyTOmKpj+hj8榬04ich^0+wgR_ClSdp9g%G X艩RmKgZ8XN4:..FYݺJ%TO2GE@=;w+cs"nZ~I94FFX=²İ x7,/rQ>"G}+d-7&N\4ϜnSP‹:QrbԑA,ʾK{gK-2sN~ U&뒃'qHI L,ZD(&XK'j?7ep\l^ c?5p&nph!Sb^.+w-rEƃ>,erG YBįS=b>@S,iⲃ"CcX~(lX* 9ⱙcYLlzwgfYQ%F*Yj[wus֛WP^o.˳z0*/d|VNƣVL^)n..Τs|ūxWۏk5AHSrrY쌯?N.gEw!>{ӧܑx8*C&_/&eYLIuq|SGŤ<LgۛYY fEtx" ^|x3:/',fjZ/^+G?,ngY9]SqͧKgİ(^?G_'r25"` fgD~RY!0X APq+ bW 0_W~~ ۲7Mi)ק?lokmTX}'# ^uGI.Ow^>.^=.Pv5y9?bpx^\ߗr3pQfD\l0ufcA6_x=,?*a,Nn᫯lߎhx-<{飧_=<{>,6C'O]exAP`pf[^l S7Fu4!z\<vl+g=lQvS|X@8'өtv9w(N5) Dއ."v:}&Z.G(/ᆌ:x 1,[-C{7!m-ݙd`z(%Dto=v+ D&;H(9|U[֏>8wL73Z4ӱ{ `mrv3MJVAgO:_X#|ZklϧJ;X7 @j_*m@]qٟG$Bw-#k08%*dwmyn|&a3 u* .3[QSV\0`෍'Y<&_>ueKO,=L~. Bhs*ABZ?ٟN\ppqQ@蜟r5,x~W] =M{' %+n0Y+Q7v{WX`ڃ#ks(YjK^C%Gא5Y /lPqKg*סDuTކ~3żojmS(?EgϺ}*W+pNolbtw$l`lOB?.Co]PdnV#Lן p qPus juʩRAЀ#Z}9QM&EtB+⬘b8򗳲 rn+P*&j&a-A~OkZfa[ ld-TSJHL'OQ cj''ƿΥ򕳷9e*VFmJZk1 VB=ZV$q~ILBi @91`Ih'( >yB FW&VQ^ִc9Ӗt(or^t,KGfN&J헠tG2R8p}Nj`?4U;@"dMQZM cVq -3sIAfPqllWӄW_}bl(#5\v3@ڡ4.Qz<,EgKNl n:bKM8왈\yo'MS}EoXN^Eq= 岲V ;<%;qCG,v\HPh`W$&/͙Hr܍YRt:x ȽB0sJG$xc6/8ދh=-Cb- =R3c2  tp_LAl0=EcƩoG儾 G@ve\xpx;V˽H"#&<ۋRQL& -vH!)BŇK t+<8$!VkOm3EOGX$6XJX8~۟0F`q , 7rZO5W2 V2IVNUj<66];8T`|$[5 WZ+DkMu uV鯗tz0]qCm[#߃]/5# rqh"s GƠ dAS85W:͹`DistDKxBks7Ј]f8C[}٪e?ߊjvZQu~ÿU?V}_ml\aʮ*qX! qGb,1H+KGʈ i%0ڥ[_{Bw[0[i h=pE1m@'DXSDTvl̝ Ti{7h2#F @aE`+)<PXG /gD7~m[a93ò:^N&D2ZcdI7]g,D؊q~]aBd (:Opo7t.@6)e* 4uZ8o9EG~w O<<%>8z-dϿYV^sr=6GS >xӇ'nޖ"~sDڨPuqxApySEvڠ-Fa4n PvGajioe?]Դj?ç6eHقJ߂),Jft9N X?kΆ-ᅖ3KpJՐ8KB&6n˲ʪ8Z3wޙ9+#LYO8L2d$]`5 ϰC^krɮjB8D,*xqetUptLҶR^L Zkc^svx TqK%fʦHz{9ʹ[O5Now뽓[M:<_R Sͻ?FuFBΠ5؆KeS$B|_yCMhg'cW-A%jh| a9m莌Xٰq6[;!TL~C|mKqMY 1r%WJ"Drk"(ظ^ORvL29BnF˗۽thK簦 NbaK@ _a$_h40 BSlkB;( gQ26y os"':h>w9,y4%]: ]5}g,ؽjNcp4_=XƯBdl<=/~|d9!$b^I1y+o^1EѕZ QइsYc'IݛJgCV P`FFr~P#b{6WA1mUJ.:+M(hyֿFH \JVL+cL+GU$QX; VI 6 ɤBhG0L7`qJmc%#\(BW)⧟,*5Iz JH+*$3"hpzc"uwy/|#!bKp1j|5؇V"/RqM6*9!MIKDaF"PW\e^m>ѢurNwHY!<W4Q:@9r8g^_FUSTA鶝Alaq{vİ7ҳr(;j;ճFDa]x<%ঝOͼJXl4T{eJ&BQ5xëm9AIBۚ"U'-$9ֵcXW;ǖ6@$@D .u q$>FQ4./byԸm DIJ#3=袄)󔬟u8z$Y*>N ~RSBdͥ ,%BӪ$kFmP4yy6@ DJ>j8THТu0r:LG]j}w]X |q8(xvev]D{-&xǬ0A%K㌵1gf2C$\Cn:پ -$ǣl4X")&8/ʜ3\CiC~ W0# ~;`tҼOVtm>p]yfkB6+ 3)PlTHhzqd Ϲs2H$OTmX9:G>1GJ'`093٭2&P+Xni NNፔBcT5s29F@~U(rhl˴Vv/1PlaŠGWlMpljgEG>=/d7o-!B#bBzKD G7'nގl"fNEOq*Ov%9"w8;%^]c*lQF]XU@hUb|̯I;fhoJa?OYdH'sutW6Y;0{MPHp@kmvLվPT'gg7L;SdNcaF4*&&&9HRI4sGy)aɂ>$' RO⭜Ǘ.[v}ģC{5wٮkhtItddog5ivږ6{l}/nCush5NUJv7]c#ztB螉oIZ&X6C|`PrDfJ5 H% *V"qt_9/L5֤gyq#ƶ}֟0]KS>YSNi/-t+UrQ PA=A4te&,c愗Xm/a#a;a˘er޾ʱq&B9Ott~$8֠m~hGhrԶ[O虷6BjwիWk%u|Ӹ"Y 1 {0k˓yhn BQUO%ECӿM69w  m!t?L}ʎ~fz|ؔ ~"X2QmFn?ގ? 9)>H3YxvAH۝^Jo&u@;PPi1p3HjՉfips=1i&<ۨU*)Q D|9RDLx٨h7J)K)Xs>V 7ن = $DC کxO-(mgW+<BP5O)6U@Ir* d ט }6X>2/\Z IemBX 6",fv8'ࠌ PQ bYoQ` n0v&+TMJ.Dflnj60L^iPgdvW1k613YȚM?O2X#yzȝh-U-i H>UrWq+K[Ű;gu[;d B,U̎K$ph.cn. *f 󾣨\59V!V1+m p 0+ۑut@įjOtipw>HWLӘpf .Nlxl`j40d[1ƛ 3,,dKE:lztÇyS8==*_rNKtl+y /[Ƴr0@a8Qo}^FuFA/eܭ˕]*+*W*nl[ BLb5q۞!{ߥj\z- (>oP"]:u?]rkg(h4\ӏS'HIUthr5+ANElP$\nf܁w!> _r=>Wbv3꿇ld \ӾT6~Js«uGRWucg@/=Wެ%ftb[端#t6)1oUdy3f7nAw˜uBjrU윉¸S!,'~PwUF|vLл6뿅7Tb"4naR]Mޣ lyF96>õJ% jG G B QE[X59Y}ycxӪ'p*d}5@:dF.3=)pi-^ޕJqyO6x٢%Lk Snq(kAhbcnNC{ K3ɑ9&&t. EB_ 6"-6H`BhC0Lx߮76BKBFغ ^]-nX4T:N<4]icl5Ѽe L,/SV҆~m8?qT҈TxɌ ƨဍ&(x$zqje.6X=ȩ3a @/VVrEg VNŋ8bUym|ܕ͗Pj37%c }>>+vxrF`ʁQ:vFzwqԋaB3ѣ'OߊO?j'z{C?Œ=ZWTRE#ΐQqCyhP[>~x-BhVE>J?dݦy.xCYEz#x ~M JV<%"iE?:tJŰ#P@$Bw,]#Xc:@d.DB>2 C5,Z2!S؄ev3YIߊ {V%H8ăݑ. d]k?ˆd $-CZb5Gn\)P9,y5Y( 8;/^"Gs֗%cq_oه|T[6^kdK8E:1i}'c1 _ΤkiX@կ)iGeHaz!h.dM;cex,!JkJB6iZbVָ|׀[{@Ƕ<u T}OGrucF5%>є Io-,qŧ|M`s4-pa+`l=!,‚Ş%Q Bp"Ln<#m3U+JP; :,OЭ&:8c47V%lbnFHpfAG QCocz]cDq^+ME&n+>8jy{4wKO^$ #zdnΞCjgpHc)j-%J0vv9 rXx?8u_bi-0z #|]u}\Ԯ#@$wkLȉfaȟM%_UH#kr}0Alfi4A7+!=PhBvu`|rICt2K#*rc|WJ̟!!:ư(NDaA7BV~l%+%=V+v\%3' (X -ݨvN 0[)rw/ѫN=m9ÄؚЃPVe$/C6(lAGʧ8FRۼ 0+Vj%ĥ&pLgߜ0?f9sI_L?N*7,,c&Aedز%'nj^+ ;/YOqtvڅq@ P!: qzO0P6rk3wfxĭrHj%/xƣ1Nf^zt3?l4eiJǥѼ oˠXB[\jc9ýr."hYFerb1#`w0_KxsO]ޝs%pqVdxfE)書o(p&G -9&`y,=brr}OnQH*w%pQ|`^P.L`RϟD4)q7y"ba8!>2Ly&JPg<: (s/܆$X{$lo <ɧS೰E"AW.LZf2@sټ13wRΤGkt?>*X= 4]bIg-1z,T#*=XGaTNLۀTYSQ$k J t&hqT?<}EY#j8R%S2pGn#yF26<+YM]T'ɚѫ`&m[`l '$jE4YG܅X.S}J%cѷ1TC&?f7-> ]LL;Njvu$@eL#.p/* 0\!ys}l 9sy";2a.L+!w OA[N\t8O-LU?xp7{nX!}+q,!~1hZ3" 6U8`:x~X81|5_Բ 9^8ʍ8AD:Q̂ R oٶ^F."VU &PBH f_Z: 9EifޝI6xHWQeM5bklUORPɦǵA)́Z$i rشLClVy|;VBmc//E|gg^Y鰔F'Ia G0"yJHR#<w01ATBe .2[,XqpD+;`)\4#q;Y|jqv^l~yůBћ]bzI;#jsſ9J;1C].w,aw5n^n($g]{ DrL+ho*HWz#eaUrbc*_Fn`mm<}B$=l`ႆ}!<-g w%5z?+Y-F ]JFc1>f( r½|SFXY$\H8˳Ud]h8Ю)?aYWwbrQO&Xƾ> HO#d]wiPG /gQf#;Qדهip-J5LMVs#L$ÔҺM wcQ# P.0$Vua'(U1 ǧ0R}Jhء 4YN%(+tƇiC2s(f>D$;do0@\О$cW*~'K;Td 4NltpԺ=xN{;F$̜W IuFA3QTd_?7O3s‰GYb.:f`t\2l,'Cْv1mI|xk rxk4%@Js>&8eZQ"8<.g|*SO9,2SWXn<ZE=]9A?L8m;vaT^$W"& $ /TyyUAWXK;çFf%?zyp|<ƋAi7iiM0a2r37xDk",T$Mјd3IZeԃz9i0K#~JtD;Uܦ2մK%ؖ ^Rz &MIL3pU4("v,s Bʤtt]>$5Z1SR?5!#_ Y-2/b Jv` ]|@A[ 1 x]40aTO$a7LhU\Gd*_\Uʒ2U&bW Z) cwhK;r f?1#u$[5FuNK'tF E2Y磮j*)] ZjD E03Հ6ci^ K6 Z7)v3GЫl@*Xet:yL Cc@F쀄52*e!yBpH] Id3ollYp>qo>βUey^ GQKJ3~J?SlkuAܼsm/;ȎED:y c1I`g<6)wxKIZ5V}hqq GQGdSO98_@0/%w8br, rSV}U X2 @?i,_'N#?i<0|lL j`% ڄ,QqV HȨp8UQ@h&OdHw!;J*O$`!^0nS[N:e3<,%7rM7ݒ9K `PRT+ASjasi~fw@ꏲ Bkm>bt qք J:5cb5!L$=d'S5v$Vؕ /N?z[pUMY', 3 CN3^$̋H%1:4>08YB#Gt2^ -)(\#C~ M SjLf`ɇjWv?9rpS"PTȗm D0>k@2"jXɥnN 9G&u!svTTܛ |Hc4jmƘ_zC;{?lhvؘ9:VV%: ,$H%`gtz(Fn6y@P\L"oFP>)Tĺz[\^y5XQ,4J#?/I.=g\;Ax{60`d"$ĩI\-u^Q[ )s~a!k X, ^\.ܲ DiQ"jAFN4(9$ш!lChU՘Adb'.Ixޖj> Cq9%5zf'R#[e&VMsU_F52:;ގ w}&=߷mCێAShm0D4oЊޙC=B*Av_,PH*BvcoWeYHM,JLJD Hc.xfX(ur9`\X!4)_/IvfM9#D)دt@Xp\ȥcU1yBqsbyjB޼Oi[*:Hʍ+^+HW[Av8v)tljF:[VUsX&אr=LƷbckRX"Ggz4 G""&`VG$UO$U{|QRt;c XcNNQl\Y`ۗ~^"=_vJvW-u'1!/nRVO/:Yt-:]mg8Xa vےx5}w3eD.e3M!D>ILW9.ɡگJ~12N2rׂ>lVc P,=izVk^2w&7!ND;1Vz 3$U™i4oN_cKv4mi%V2ڕQxc%}$f iU/* mCA:,eA헲;a}x$1l}9#Ii hOXx$'LtЌ-#(YF3\\2R҅Dj-\)=8wǣ_ϐ҇E> =^A&&QkC}!/oz'5^aFJabDz5UXY^xcJh= ^22)}b`)BH/XA][sv#MbŦS_kfHJ bT\8j*v8;+тj8tp@8pg[la6ͤٻj%n2L~H삀QTEcSJ?38|T"AXbVKVkְCdJW3 GUQ u]7jjaoNNOHLO c.aBjnizg BLcT*(euZ ^+f_:}J,^^ɧ/g _R=PHJhL$z&yу )HWԹEbBfObxMd0vuՆ#fӅHh&Y=[$Ua$gb4BsGLZMzY!`x&jP߿Yr&dLLB; =oʷz[D#GP"sCqk/5vTdxXuu"` ם˾4s!I1fx~RfO`*# }S*Očgȵ:vc>T9A*U侷w 3iMXc.T`̯p#vz@xtu6 PҖcSs)gRe$OFzM@t첛*.Jg$FM"~9 jd1Kڃ577?d@ f6H KsٸƤAaOűB#l@Μ%䕞Tơwt<dK\j\mǑ$;mp(EXѶ@ :e0sA[3֔:*kCW*Ku #jfS{\c4ݰ.q6\o\@\'يb)ܫ%h[7Jj {qd=7{PQa_]w +wJ, H l$yD$[GRKpkqͤV},HEʀߐDٲ7{cƤ]lL:ˈ!&\R+Z^~i&F2ci걙QLZee%n{Q=kfcYTO!cPqb$T{)(#S˨zmALZPnQH2`T5GU炶,! 8*gpq+cy8>c= !bi|q՚zϝD<&nk.:P3P9UT ں9(͕C%>sPz!nnjƖ AJCCA!MɅa8OI"~:q!Ǿ-!_梔~ݱ#쑵+%*9)+cb(g>.fnlqb>.y" :b,XRWSgb߮5f42Ѧc0|Q͂e.j'mK%$=*u *)Q!88D`FRl\Ue0VdAΫKLYئ*@B] ۘfdC5~0UX;!Ty?YyRQabPjҎ|֕|*0f$FH("2 -o,RjbMUJK͔Jry-[JKD|k_ q^8d.&|/~=L~00|w&MWW[b-pNJ.{eΣ֥0+,qq It2:0cCZWlŗfk^_$Td6qC’x72X@6 ,ep^qѸYF–>#}0O.ZE)/7C  D&E`݀@3#{}9W1{/ Hv!W8~L!p>F I-q&C_/!!F9)0 !Z'o",+Rг}T*ۤ9_Rzr5U5`q_OwhLq e=ٷ( S^g \bH*UsTS)y+ɑ~xdKiPg(٤ЮkGx w{@ WBP*E`7Z%,0> 6;&̃thH4 _u+&X? T.4;o{?dg\6CC\H{e!$ܣ[ !Z\"/ / FL5D#"hy5%uԫ!T5\}ϑ6վzUBìG8?(KE F],I0q 烁$2@3&>Œ[: T?~)elE)u=ػnyACXJ%2L%.IJ!ϙ_jʴXZ]&T . /`xU^zر=q6{w'qhb"νF3Hki#چ>٩D\7d] TMIT^E^ͬ= =Rq,-*Q NzMo{q; _WL=Ӻpĭ=:@4:z,gkZiW%eɱ4MhxH"XU:S#ջġwQhb^ Wx\!>d +0)iRwq4U*-;2<[0>`aUH? SC1#DpQN~=e*J<YUֻ i`+\nHsB>ᱪ uQ;Zd{8iO[h0n{Lޜb2))|O;`:SX |';j);@6jf7 [2x-cFGwɓxJ9|;>s;0$c;/ !Sj sTӤZuW!/=,;6rZYV|Y,Awn~Uyfx$ ΄RAcw>uShBq ANp o'T2Lc25vV۷y4O(?|aP] [ d  ~B tk4֕G<(f!#4a^jv"!f3IRJ:v3U `H{妽|QMbԫܮd_%o(Y\i6O"2F %=oGS6$ %sV"ba6_VI&Sh.1dw, Iҏ: g8&";;.TVd*p1\ŝBV?hUr*Wj qW̧ ^\ g-a  !A:fK3C[ZI-H޺ހ%pgf IДn 3"xfMuC̮s9Hjow%'  REn,SE2BYO+'te[ Hz3 ,{vTO`v&ǯx%NMg7 5ƙ%}K苇We)V66 +#7 Clrp I:":W`0]2,C˅xsŦƝ(bu?P=,d^){ű(SqZ'gzsNZlҷ̋HQ>Ϫ"a:iRnp3r=XIK~6iB_)ļ X.bi iZObY;#B8ы\z ߹O?k6 m^aXcA֬TLg.N[EMv˞#ICx<8A9xfX6dN=0&.Q3ѶN8jpOYLtn[T4dKGGКC95 ~p.*`L/96M/p 8uM=UR8[t~*-3drZZ rzM趯;dhacZny]#{:VVW)p?l& VU[Ϟ[{"vdջU/Ls\{&ֳeŮ LȵŃ`}p_XᏔv]|5fQeL;/3jwSv.oɞ'a?cr3a00:Ϊbcil\uoO)XczbO}wIejL'׈EJ:vУʄV:qIMŀpF8q7s ac_ml:Y2Ǫ~sO^4V _%h0:u) mZ38Ou3[C!)@HbtY_#v%dUe5+cnζ$>ױ_%$AE)+=IaҖo=枢.Pk2I.&"jp`TԪfU*H) 5(дv[Xr\r$*/y }YPȞVQ!]A29dsxVNiJU a .s'x/KWN5Eiz&V A:MoЀ hr՟MusXt=}LVߜ%etў$!)on( lq|PJƹ#4-lz 25$.qW83EE(f6z`4`*70)8u9-mR:rJ(dlx9sp;mA7Y2^#FNH7ˌ ]7"?Rt;ZSR[iqՆqJ c\ ~\oL!uDAK3'(dXXix6$RW_4`Bx`c\kף)E>;ю;uR6ٱe\Ѫ әRVF؋Y } )!^Ab~IڸA=)] 5) q/M厎T _)f~(TZ9 /q ކeaPE@$=hT;ߌi)n O92I!ZH뱈" U "< 70@9=H\_#'-oЩibe,7,QDٖW%DfJhgcd,\g{ ڽEu6/oeN̚/+Rᨐ }#HWt~ѮS"=DmYIaZWxgÃ_ATt&ЫDf ifkh"NFmi]>{r0>H2UIc˄q|$Kb§]mn1Ln JaVM+r+D|"$p,&C|@}$86髯 _-eo:|w7K.(x)2u7p@%1-ei`bP@&9Q'= 992%T#nRl%{i@ fq=i/m˟a\QsHt1"xs7}! %RĂg\ myǮNM {d@J=Ԯkۣ$+ I*U#YRFdq:˄` a0Q36~ 0W0S7R tK0AW9fZI2&y')b 4vFj"M @sߣ*ƺ_x1Ql Up:jbjk5 Xw~ \ѿ3,G>cy+ F8k>&*Ҏc)Akm=A.`-ewi1Kkzm=SS7t*6NwK{qѠՠ1ᬘUl2WWxiؕ:h]: O{+)1:qq|Tq zooZ\JLަƮ0Qk)51vc4rZ[`c4Z\YQQ*J:m$U*T=89)|/mIZ|#rۡN]n]ly;* vhHQ u@wdk}8DM2~"ljXJ-ksec"mP8)qIeáW7ȖD܋vR%}W2dX53]y ( IIVN5w N1gС)#Cז!GҰ{ l3!FFtI[ 'eg5ϥi2&iDgn1A Hv\J>Cs(&~ZdPhlWWuL.Ey6M,M#K}H9/qwlNA"eu7oIIq-G($4rk{R7n㵀 *ꀅci<!O+#!Ƶ 1oy0fPDx2A³JjbNT#TKjl(^peVJTtMPi‰!]q%]fJI͂4d ;X j(+yZbɐJ0oBDG,a4^Y^Z#! 2ﶓ*P!lLIۢ :*ZAl:\Ie'DF8ږs%Ȳ3aEBN,7RΩ Vl$ҹ8,Ap͖X@n;mV?U*/S9$ Y?_LSY,1Ad 2' !\>F=9ޫSu&DI.SfDPOWE?u _Ql#u6PLjZ~ᵂI]i6ʶԑo+7s1[Y?;+SIp(SX`,9&KhĔaY"L1mK׏evhM~n3\Iɣp(dTRBr"g-obV[mÌڹ,<1`Mג7奔/p)W8d-fEUVaV5Rn'mH0S>] 6P$`48r-\8@Zn\]9aANB.BND|lHNc1e*fGYɸ0Iiit+:3qv1@zdC >.g7"npg/ 臟`Pΰ\3`v!{ ;UA R5 Ak9\D+-84pw>:Z~̛ wfN`)S@lFv22j '= XϔQ;(h9"xLNFH{ouM]s 9MY6)'?UNzȽN x6lm,hDw)_Zu.ޖ;Ej0t.93_ +); N~pD Ҏ]:;TBۚ~^L_ ܴ@S19×֯}c:oLjA3YR C8pDd4qHS?AQ͟ns BGG?l eXEyj@GxE߾GWH8|v Y+#ry7A2FsdOHs.y19 @vÐv|%&av >a*e!ۡm1MY`_W7\ \\GڶU@7>Z.2Qݠr tRce͎h^eiI.HVjV?\jwp.7 A*ieE#+(xg+1T:J hX8-REhDf:̺o*߄fƃY*ŀ7>;>؆{r @VH1aFJd 4Eȳ~Wܓ9xt)1;!#j(6S,فUOe&o"' I˙үzxn m6,flpqt",@:3s\ࡘ(X.>b: 8jZJ"u3:pLP/tN1qj? *f-ۏ85w.=DkM|,~)qI攖q-e) ;c; ~|\گ$>SY 9 حFo.sp f* $RiM KI%I fSˏ }><`/}̄T"G(B+;*%urYMFv4UmV s&Py\M A$vQenJ5kkܧ/-a*ѨܒB.YH" hEU3UH"Zq@9:*( ޏ%rRbq4ӌeŚFMBS$r?+lrENm9Pʳ|+)o-!Iٖe@qk ĥG|ֿFA 0`K j`?w%ql@gDJcq/=ӗyGj%†ꚞ[9?o&t~ a%d}tmZ3Cn02# EA-񣹗Ç1^u(v#IJ9> =%*B0?ݑՐ#+`Q 1R:yUVÃ"\odAw|}JhB7Ũ=R0(p#YW\\̅c~#N\ѼBddnw~;Aӥm8CjXFMgqi1 ,Z_tI^f qRNP>c `2 PU/̴x"8fF mx'>;.2Al(P9LHֆ@/{094(I)w_˝Pkh;hc9>Dkzz.֒nݶeXbHDFn3`.]sH}ؽNAcd=3{,4jdUve6s<QtH=#?o_U:?붕ulI&0ݮ')O[(5^ޯm c|?o': ~ V=ZqtS# Ő|["6ӓ,  "oî8OAj.prkǕ3T]^4r;70N,A1~XB]XY,ԈEv$i>W׳]81J|ҠXhΔ*CzTp1ҟ_UkA?G|A9TǾRWp۫k컮֖.ςn+$48Xm)UfEÙ똷E-OJ*yn- HPwI P !F]e^6LȭX}2i)m<6nɌ@iL=ת-d,!-+n{\j͚m5٬D D[[.M v6niͽ%!rcm^Ahi2ӂcv͎(-m_O9)[uNpYé5⍶4PrӸPpufC`,\X²,)6_7ZY v54bxw#ς+N'E$4O'lݩ6C{Uq#iK8BڳMq~'I\ꞌ |j`A,œs~p;<*KTrg=%0\ ?\ͯA4&bTJKjW6MÖR*]B}m A>$V)L37Ip&4xV⥝c*M̶OU@8(i"T i I{G(#njZ:>s-=3HpZҋ\3I#蔥A%z89 cjW3=5T^oz!ON^+U)d}8}8gx*AKHD%!ʓMX AkDUNS86`6iJϝZCkn/qC{){hrsg@3Vu=`tqSi+Oe8oV[UƝzh !+Z[LSJ ~qZ^@VΆ;ڢN-6苆Suh;5TƝG(Ut`1; Nա=;J+*1 ^w'ޛ-S V14Hz |nޒ4x_-U<W ~$=Z(eUp(|)!+5dz5oD1ַ+Os` 14Pzò3=2Wxm ֡ofHSA*{ rxX~ H5^mʦNer㬺D1^ecK7*i?,P{e7g\Q#f@(T9 P '[\9Uf#Q{Gk_#КM{ Z^ Ko;4ٚ-cRx܌5q*mּDbKa؎[/ޒl B-LsTYǒ4ԲBiPpK{szsL5CJDzsڞX7TCM|QeT ߒŤk?tҭY9q7@G!@NjSބjscr:r]E3W8=*H#ZD >Yx*rsYtV]-:tuAfSu.h\Din2T:]{IO. l"i?Hv{ ҍh~wIFG@ڒ1%vDoTZ];! !eXE-xؕzhsJFzI,:5G.V8C|'FӅΚ#F~BH@ .7SaI'Aⳑ/s(&FhGx6MyV{tr|4,A~<>)_ڼq^PCm1CPj!Wbf;a'r>*l]w̱ qRXXͺPa7Sq5HYTGwn [Îͦł:_]Si&yVYLWU֟0 ~kaKz_kf\zew χdhh=i8xMW>F~r!BW0  טaz-#p+z:3#WQDQCREQrY8 #C(oe/f*jyٙd/G?)u~9JjIHk:@H%UU ZR0,ho6oFƋk XGRXk5 6h>c 7ԛuސCvV ||>yY{ĢkuZ Z<Ȥ!MXm,TI1@p>d }l&?I~DB8dqaF<6Z,Dð`V 2\Gffbwxk +un{cDƆޛId'hľD:-3_hD;H& ,VkdDiԍ!I?T)*,W>M 9))ש!SXߡvV [1m \SZd<3dl`"i O%GxҜу(Gx=cTVM}gwU:I#C4RGtmD띰U`!{?DH^5\h9C̎jNK?l󃧼d|d{0`al#?II_Iw3.t"Z?º׷nOתwS^g}@E ,5Wښk+|tFmZ*j`վOE-sւA7oG"Mo?WmFk}t@-rCQ[E/W5&| )6 l-7zEGbA% yuy}훋d D8qP-ZX9s c6NFb䡷K^@ٽsxvV,7&S nV 69oOyp#I|S$l%;%. cj{l 0XAfydKdr}ܼ DmqLM~jnב~2 e2aV6.77p.rY,m_<좫luaRTmSOkP,0yaxQ 1)xgvD&:-ԍ[U 4`lBC5]..4%,nU&f#tj}5z˞X޳{mOFO[=Z.zCXpolnZiJkA _?~EKrsUL=>L?E) J4:h27{Fm'JIvQrQ Y, ɓ'Uē4-Bp @H%_oU_hZɚ^2T+݄= :-',x{=P[&%̐cLϗ=δaٗNA[(z$$a~7HVGa)ʮتeɨ8ȭf'xZO]2 Zp2W DxZR;Lq*< TqVW,v)˅9 8t7:s#VJ!H>c&2e\Q`$D_r}ʐ'ڌfB#e!& 5uQջ!+`%RKn>ơ\T\rXP#^"c(\yڪ{]bw9n?J*=Lɂ/s"vB޲M3#uo͓=-D 6$!_ݬ(g±>g&P8e)\aPMh0v `mDpf[]N wqrp! y#-$@ 2uSq^.pzĴ /? iĊRg 0GHEY!'R;L@axNS)|;s*$0O|)BW!h@ʖmN@1.3?OuOg-7[h.`A x ZZ@3 ,N+Jq^{qaʁE̪U[f3D ߲;y.gg  p3yFw⣉.J<CV^^ ޸5 dאd(ב!%,SȚj5yRK(XY̊cYc;BvLA0gc0γ@UVʒ'9Kj]%V6t DC-Az3@VVaQa\"YR[yullҘ*vQL>L [ryM8xX!M ɋvbˆt*iȀb p%+Kny+^U9qpŎJ\@Wyx8:l`fD e]:slfgPwÇ7J3yq%7Fxv ]qj2`!N|k*ҀG@=+_%~X'5F}km|Xy;"Κ\W&xͦ^5M (i\$>#$YNJ;+@=9ΒDQj)X-/s$:= ǟFBtB0OYu. tX xw 1UvV8MIr1\HVs9ż MtGߌؒ 饄^6I6jB1La-âyc #Z5wGYX OLonN/p.A_Cx}[HSqozvqtS:vQ(ۙۂ!4Hx SA҇%n/Ş6g<}w~O礿 ՈS5fsh;hߖ|+/Ͼ#6Y7@"A)9/$<%elɇs^q c*Qq-iFYi{W#2$LLɀq )G*yXɖlPQH;1`Ïkg^% rDߥ!ȎR dp"rnGsq%j9P .Zօʥp66TN!; V\h9!c8 M9Z$*Q R?G2$&5pP6qΔ T1aJ, :!&ϢVcm6] 0~ VX|k2;#L}JlE%䢽Np j1f㛄~ai_YkK g’q)k ,R҆﷡:nڹeyr"=JQ d#:}i3NF-mY@۸BXUr˨I`8Bg k"m$ 4r*?kcLTH$ _¶{{xTmlSU{k]; v% ؄10 t,4vz^Dc h4F`酈D ƄP$hԄhLHsڮ-׹y3v~)s y} qȿʦGM+ %!z<*½E%׬n-Z,ri.~*dWPm(Q:eq%.g-N'eeČ1'm'1K2'_Ƃ\q,C7a?fvך;H!WZRg.:f |[RJ-RRJY 4!'~2rZڇ͜/wxPMsi+ESc[g[mjV&`Og x~ºo:{@ʇ}܈5֋/p=j8NrT1N{xbcÓm4i˚ўXQqޙ2zwKa) KH8!K*֍;ȅr.PCJLSy bVCTEbx`ȷBN77 Z A?etq_G[ L.?}ʂI%Qqpp5Qr~.+RV_E0`O{ r40c&=i,6.eB2[S1@_L#@XllDݔ@wl,Az'BCT4- A|(BC˔I:Ƌe 8߶^bMθ}UcUڝۿԒJ摹5,A yfBl~6n'N#Q$SGf>bb 6`!K"R)+=g tiM@{A4D+ !>9d%D~HJ<"@)͙^@ Bt9ǒ?R f>DJ/ٽ 3s z&o l![ahN~:!d4kgɪn] ` $1 0A#h 6pfaj%cjk/Eߛ]R;Xp3B[CHRܨ&nk T@H_H Y >`XJ"GiqQ0szH{PI&FGNg[IgaN~#x¤)ȉ (_/>9&ǻ݁[ȟPr2\ {B}l";H6n+疒K6CFiʁ:E_>ix: lus/ZH>R%Ji)S$CRaN˻%.uHSsZ)mȶ076X `*SӮFF-ZKJPB rR*[*p풢I@3oooy^kZ_E]Va k~vƵunUJҾiI9~$=ݧK/͵SSIuz13lAQu"yLp2k<2GZ"LɰЉR|bLəZ75satc ?` ?]C?S>_WRM0 ޞĺJ_ 6%I#J8а>۫'o7K+ΖvGı19.sMӓ5ҖCوl9T' )1*%&zz XDo1K$-bR\Bz`cZlcwӳwA uX9.|Oqf+&z`r7:D]LX|㋼LdU-klmf\="6a+Fq$\2=^ қϷ)+݊.%q;dE?6*cxk]$!+`ŤO#֘WѹB]d'C*@&e}v6_=.Jf⦾ױfM-g1S:$'$ FSDOJTDSH⊸ra.,SΧbI%hX`TBL^s&{r6 L0eEe}V/8ij `dSQ@m|H9C/Uˈb \9IYk50EQ FjɂzPoN KٲуgV4(˜WDQ &$ x8HƂX0$A+dry1QCo/W#*, I3z(yfk̨K^r? 34gi0=d҆ť3RO y5q)&ȊOȚ%%%%*oQu E쵬l)U.j9Z@?+jrTh襦`di^X(bRI1))j2H[o-Wg6 Mwr:)F^9.Lhba.eTZ83QH. zaVNVbOLU I,+%_rV-vF1㒾C2Z/k2+wX lTΊ7cxĢd¤R;2U)1QyJTtxe8* o3ㅓ+PF8$Be}J|VBT2~S07#0c9\LoPΎ?i 6b)~?޺kD+dfmdo3_}MvZ-f ruya Da/L<mlئ VaLkR ?7jYUqBe6gMHrD!L.[6 ꩲKof+G'8w]FRt[0I*7$(ȧA!2/m4Z>.?8B8GRh%3ҿ|ܰ O5ѺӏK<-sxCP`tgqe@lse"XBN[^@//9#ѽ}hĂ;.[`M## M rj6k W@!a;sNDx@E˶,EpUC7ԘϜ lYR}V7^zڼ4T)v{?גJ#/}~>=+]1*>_[d:eS_)fG58㦢'g3̶L6cP9 fn-ܕm8ÿ09A5¡no*E㝅n]Տ% $#zz}mC?ޒ$]BS% P5<^kb{_(t,&%}:"9 E v7⬁i H}` PDdهz"MQOB9/ON8:YG7'I q6,,33x\͔EN/уSzY@' TRҰnnl+Oou=YjC2֢hsqzz7HHmr%Ayз>$=LAԀpR &J[SVp2`CZiN$#KW`f BF He`\2}@W^,<o#S+2!G,⥘{47~6FD~'[cV/Hm{ jkm&+mjG;,0Yy>.)K.C@؏A-yo1"RfnJ# [0<u7m5C_*5Oqn 8zV OT0#M6+}DJO]b1NUCX/g^}>7 TЌ58+Ā,BPR!$!hpJV4Ądf)!6CXQ fY >V/6bFh/TVToƗƏJZ|:Dw~kWr 8HXb3IEMS2SPޕ\/-`O}p=zMF1zZæX ΂e|'wa< 0 1Vc#izjJxJttvHV4__*Oi|Dn*^F{ЭLf5pZ__l k65}ƗٷFW?IJ:@ 1d-c-G5~<ԣ w^ 4.ډ p:H?tIF׮Lt_7Ŵ}X@XYh Q?$.c^8$%jYZ  BB4q\‰@(i._L‚A|g8;NZ{I>h{HqV!k܍QG׊8IRt&Q2IՁL|$3" Im$h$R@TYa\PH_*Ywqrq)RVທ5E)+rb:!X7¨Fr'48*1-0ѵxa/o% &>+%2,OYK?7Gc!RޱUGFä,ophc޲m1.2 ]9mCfbn 0/`äϸ}.y(V.0,ޙ֐aaxKhBƾVQRxȖR&ldLla15bO DA7$3YwTpAjV^w"A,gfva^R܅_猤]slROwV8]ф"t`7g'H)jzuĻw0@GP;Vgcd?D:xXW(e)mLҬ&I(]};#Cwasٍq!RQܓf{@Ӓa=J}\H*ez8pX`Pe"B h|| s,~Wc sgҘu$_ oF50&UXf l261&A;hvһkxB@̫I)4IJu>6(i-4e.ARmЖyklL\xh~#+ 3}rUޯPhم2, ,| 뱖ݓLBSP6Si;,Dg*/b腬7 `z|fC7sϼsY:V|O$tBcO)vh/'uVo<]_:E?\gwF¾(DȨ9LnvDU蕎OGgLXm찺(C{i%/qkoq-2TW\p@n.fόV864PX3:Ty4WNXS +O9;P dE@Jz47~MFacs,:@Oz'nH-7A)i$%ڭ.~qP]|e)10t C'eRIN_fA'^"{W-|̝Gv v04&Ne~=~ fe.6hƷP2V0{F?oOM[Bf$,TKDx{Ǿ}FFgUUUTU3RJ2RrSsK J2S'׋*$(Uf+xyY99) E )y)\ D7tQU(-JO-/.)KԙveF̞.:w+TOltN-*/pXl3U @XP_ZXY°ٷ2d|/?9U]'1Lpgt>˝qxf훋طK0qmg{ƙf1Vh7xmt]u*uZ u,r]}]),F!):+'Oug>q?H <`?b-5@z'-!3x[' r2KrKrRK24*rsRsRsSJKK25SK47s3̯:=ae'[I$$$pqNNgl1FwlF=׫N РZ_Z_4QUxr'ĠcE9: i9œ/Irq*Aj^ 1@dcK&wFM~3sRkR})T=7ŚNfy956VSg7^2iL0̜k.l_+hŸ6+enkz=tNF gLInd駦ybO(15P )*j*qqX v\10o9C3$) xuQkAtlTM&FnT*Q(5h'aG lDkMC=U"FI_P(x -zVpgE1&=ۑ^ʓu1܉MN*FGnWMM楜iZRԭ2c2~ h֤C+ȟH/Jw/NSq1X3< ڰ7?1(N!1(v?$x 9qǯTwVJIpAt l޾GM|߂>C`$7I鱂В"޲~ |_/ wN]Ĭ[)ܢ]jzY:f룏b†n*xPa B}96Q ЫSia5 g!EH#>eP$Я'0ވn>CX_|4H5CXƌA4&Q\=ڛ2n׌?^y 2v`{rqYx[m{ \^%)vK **f%+5K~/p0FEx[S zL oO"¸BxouqI~B^~Qnbfm\Ay: e'"M]i +y'7n~/%vmwƲ(~x:ۆ{6l&3.)*MQ v\ 7H0JNN0|v/~{UV/8NNpQHLN-*Լk.xĜ nKjо}B;c6J)~}xV}leϳ}nɶ#u&$m ؖ}(znk{] kF)hG!:^@ !h/Zeȇ SA AXd?p$H|߻H}ޏ7/N׏GSTey ;¥{9kk}[r"'2S _N9xV ϱaug_7Sf04 ^'$Zn2)'~'񂗪-l^h1Ӈ$?6PũB9; y)QUr.0'E yn^`8/A[`9r=  ?'r^v trjp(za/!^Ag>6eX##-Nدh(Dx&XXmd,WǤq㥊i& 8%s̴Zr9s]ԔSukb*68O%͈w895rXȘh*2P#Ky:f2fZf&JjbscFnKm-HF#_~'TLEw-s;|Kb:Tv|br5=tr ,,US+ks!3ҟ+kSЃ4:ߪ—ЏvL=j.35FBʈM%X2_&4|8pvssL3\CRCxLaOrrkp2U4M$)o3 t8ڶkЫ6TQTiCcE|G豚{cT"kgۘ[9~2SQ@n9.+ڄ[ru&U;x'$zrɑ^<嫾4HOFTuBlhTRo,! kOorwC{hDУ*Q~I/t5X-][TCNgRǾ/T6K^$o3#tғyo2|9(.J|A[q(QENzȰFh"YG`*JJͮ߻Q^g66fDFZ#G:0Yl0# X Cl/`KkLC&k|^8ޏv a_(!?J*2,*Q%4ޢH28WzϬZr1Hy5*K k2QʗՂKo:c n'˺VxJl '>pb4;`M uɟC< Mh,|I !60&El&Y>|"o ޹&G4>VҬ]x.Oe2Ow .x{  &_lvf5\Qqv#9'3nO5acʆ598Uar4I4.Na( b(;VR9 ?^ANA)/?/Uir/6,[f~ܚQ &2xU]HQyG~l2}52k!v!Q: /tMe7AO\zDIp/E7IE]H7]U7Xg{sq8s>WwM(32yy0qWƿ',BQ G*\?̾w7b++Zxo/p;qk|jd"DQ+<<'dEGإؓٳpL"LUTB@R;kv g" k'ً{!+_^jOO a(u`>K-:µjڲIerTD6=<%|Z0y i>ڲ~FmaDpYaHEpf` m 3 yˡ4Tf)sfu6Di]O2B=,;H.5g OOvr?5"9\W'6rSi9ޑ+CZhi5tWBzR VX zQGUj e{y7m4Pg54ٜ՛swH?jn=qE ٢DK'&: =vvg6L,NLtxkD 'x˳03g&OV6Q<3NwSn#.N PԼT[ҼԴ̼ԔZ.TpIbIKbI-“ d'_1|EY`r$3PFLE"6NU_IeAY mAʼn['hE O+xV{PT^`Y`˲ <X*Teݽ +˽dfLƪ_MM6*&iguS:fLfh3>M3T{3 gw9L[ő*yfō=1\LY,M_mt71>r9 b>\[VYWVYOW4TiNqufHPX-+mTZ}̔rllLÛⵥ_pXEmwŊ HWfT3iOö$/lT-j~Stm~)pReI *R6*byqєuY1!}.y,btKGށ~k~*.ZJτGihYQNӑcc]@O*]AzY&QF1s /8n̈́3tfQ#(Pޓ4bRdm΅Zcy] (JtW(dYԠ"*M˾۝L,ܵq 2kL{2RUw;݄qe|؄#qXMTb.emِ>};v iX,úKI#::#B"VtX]NS'0n8l7x8\sרdh!F uHvqhNc[4x4-:;]BwX#4)P-*率hUu@zɎ<% 8^ݷ/Εk"pId%cCohhal>Zmln*p( TA -%%%VTDtPv0{ÐGKI{5^\,s*/jQ 5I H2VМ@>*Y?*{ jkQ8vIe-Wc{:,6]CiM̫=-3Hm8H0_ɦV%)cSF6&&),^ָS6 ثYS)޾i6e&:)uܐ zB-[t@̕;{`#$20/)чBDIEDOpn(MqMn[Ҵp;}e6WOE~1)C9GN0iu g3 j%la1AQJJ!-c3J?JG!iSwM\HJRqAT.H9܍dW+`Y Yw ܞxţv>f;CO ?.D'JVx:jF>i<ٰpEp_\{{YBqq }[ ,ǀXBQ Q=̞*7)`dzQA6Ch|3NRX n\GBx$%sUϬ!_xc bY-p|;d,C݂ /TP?k*"Ԥ&z[s5Kd(ݿXK:P/t57R؂N-'`Ts`7Gn(pL/B'_7;vk<(U<;V8,]<#5;MJTȃXu(I)E!W2 KaA7 ?SvLצ LQBiqxх a*=n&OYM$VDF}ӐH^s!B^BCmᎡ]xf~$\w&qI;o\[ȢFM:%'ĊmOc|8plcotmdhMlٻ3in;Nj-gQ044B9 bN7U#ITQآX징J;zv4qHu}uNBpe^A3ChgQDD) ax{x YF%3C#3]K]#3C+ +(ܢؼ'w13nU ,8Ȫ$$>9#3'EK&`e O>e=%!6%ű_9d5k%x?Ȳa3YFESCs#3]c]C+#3+C(ĜԊJؼ'w13UN>YK6>'3/[TS$D 4$:9Slrs9L4O0Yks1W*<'׹ARX'?-lUdYnL/̼t%C?n8yj,%%9_rgM{)5/, Jr2'׿lrPAbqqy~QJ|AQ~IjrIj/8`“^LNx!XW_Z(&'9yk/d&`OM: ~rHԢD@Ev&'g$楧&em."\ZZ?9Éͺ<:Ydo:2拻1|pɷ"oɧsOCRuO^3B̼̒+O~Mtr/elA2/MDpA\3w]B6WQ>dxTL[U-- :-0,A!lˣf۷ F-ng%q#ƨ1̋#S 8m &0` Ch;X&;N'= HY:ݖ SY:ogWaNH3ޤhN& T@s$$A8WuI8V#-p.a<*8TZV^a\1BO7*M` 4vs} q p: e qupPI;y0S gS!F ڻdbD{JKV[rp]hFӊ3{\d VV& E.*hEa ob583' ?2Q;? {\9mZLWzˏ!#?.+@o9󶚞̀6X87iԳpbvqiBDCEyFE/ve /`̩8?Wf{t? APk^:u~CQwWN(Gɪ㉫5O}$y}u< Z|JaF{ 5 5V=,%ߏ֬J*׿yeu y5= % KX~nCAy? P2:yޒdhM j8AtD^x%Lߨiir؉8؇`6#k{O*E2 du3d ʒxۈ|glkKERMl'p ϊ EAsJl f_%JD}I!9BgR#^^N x\kSI,~E:=4mfy$ BJPKUꪒmBsQUz=i|ܼyy={M={LFV0Hon(ћ:wZҌTo4IItoL;f4ט+L0qZ=Wu< 0,0כ a~TR].LI_k ePu VGQ,+|ɴVyzS|3JݥS5jFyEB~_, F7wl&CbUqJȗO/:Yu q4 b|Z`H,z urXDiJՎ]DXm‚g*p:0S1 d< ʭ<"4J'@Qkm¨_.je?xѐ0OƓ8^A,L;lA@t0gYWnx/gΦR=PeomLI"8PO 8e0N[+)EꕊnTm9 :E*+KQ2l<zSBxr~J"Md_&olooolOuѓ&6 ƺU1kXf9m\k4nu/4+ZyfŋZCi:yOX)$|ŋtoga I:q֭iqps3?XK.glU:Ӹ!eZfA3*a6S:-F(d\քY +{*Jt[Mg6GY$}ϯqt /ܜ`TG`| qkP45m[ͦy[^I[a41:Ҷ2ܺu=;8?`5юM܈tvxx|t ǝ࿃nm[momm$ƇӸPx?DX%1|UT./s>u ϝ^XF@AlRj}X@[G/SB> -LnN`2n#>,yVjTq:cohovh@J*}c?fCVXz~_w$rf"6W{]2 !T+a M@Ľ0M d:Qo@jq#lku8kiFEI9i-Q®,j6Z˺1Z;k~ ӾwѻA=Y8n]f^H#S8u. .&Z. tbFiI*4iF1 Q4)/L&H[eZs`t^M8=0;o UVmm=߯!RmSl:W.r[ھ8.wh7ݯ,n H+EPdsi7tq< :tZQ@a⋱ L,CO7ʈ'ĽFsM_wdqE1YxwQ1]2v3 }ѰUV:Z <$G9BRF/$; ۯȽKD ATB8; <ZOaպ,ĕ* $}ݛ :E%[%Aʼ}Zd>-H}_fIT@{8DWJ>90x>@}$*n6nuDdQ4E!>0Y.ѿ#&Yb_2jpB;DE %Q"u9WL`r=F5q9vZAC9K}&M|?[‡83:b3(΄Hӄр+qC H^p_t;Ig_-",`|<DjȲh+Y S<˥/,p9F~42$%E%q2%-ۀ o5yR?F -Ш Yš*[ot: QhzF:2_ oF`p&NΗ`M(2;xYL> fCO>11S_@k~n10i8&qA;qN(nBGrGhFa|_@yTr*?|fvn{  x7t+3%^Cr6: >B'# w.aK !3? ]u=MPېU,Ӄ+"0<yFԍH:yfUP\A۳]\`uD)0<,2h)r~c?tz^4ENSHxO(lj4Tǔ̮)C*=W*Z)6"GU ʽF^OPzHFmף%:o0Y:wVxy96׈C2@BHFE,n_ˌ3m@PARY[0N-Ezݣ~Q6.AY(KWʹ/5#zP35 _<Ē^Ql@PQ9Fi7kI^EebT}Shq,#Q, ip<ކwχ.ʨ4$ÑcUL@\,pG G.o*@U)yRTIK! !=LeRM~3#( 2\/PpRr ݌Vܙ SEY>gΘv wpI>lJQ}stzxV M`dսK+D׺g"8#u`J^W>oN>H4 'eO6hW+b<1Ue4EPhZM5MۤH gDnN*IJŎHɲ'V<Ϊ֒[7A%mK/$EMy~gP݋PRo.gO+vw]D@kg3ԅqq>.0e,cL30 s|/e/XaiH* ]1̶#:F<?B'Ъ弢"v8"O@M+c~?LƏ){d{E@! `H,&mYqKL(^RiWĀ^9p!a4 wxK\57#v cvdTbi@UV(pUq}~5]T;Op@|WXeJcsd yǨ|-b]kHjZ ,u\B@;d&cwFΥ4kRfʺ'_*>ه fe D%!.a_M6|@S۔e;7 >Ѫ$ 1PI\`K Če4rnL,)BGO*ꠝۜe7B ܫw@>bPAȉ}ԸEv?]8&2ò /EK\3. *v!5[pn2Ku: :G#h0N5S8=N 4?$$ [HD⸓.Xy6p;aG1; E 0$G{,e}>mluxY3}4mk~XrimGD8ǺF_?o|r[cj:zu9 j#s$f'R3FYdL?#Dg "ϩyKiekbxrE m^\B '@!wf]1a<.߼g̚8yċHAQEՔ43{{|>z.9Q=pH9 !S@X ,dO`, "PLB@6$0b~="}#|) <Z`v\ wMFPH_txexΐ-R ^*ko*T! D.T0.(19"{!DBrN-`|0eH⺄&k(*'O-MW-~Ȧg0[W jdOGUZm d(*uufQ 6¿.s\3˿h W!;|$g?޽YouCdHv/{" b+:"AJ %q09~3SoIcp]B>lD/g[l*%u㌏E2節8žx0bua1m9~'hU;)"_v`f4B`Kb|,>XviuLxC;mo(D k:F0*bhO*<|v9>k]iWI!\!C:B pṂѐUhۀdd\~Rt:@|C+F克Cpf0M}& 2.Mt1zIndpT.Grp9,z`sWV +?">'d!#\N{<:IJ-)m Tv4Ds31;u]u[V?9þ чy h*M̪],fR 2S!a&^|`b +C=^\C Sd:/ ,FUP6"y,d]|W0Yg .~. dYo91T'*W ;^A$~UBK/\gN0xs3Q =x2 F:pZx2 :nwxCԜܔT09VV6fD,D(Q=! >J.X<7 QueueLen =F(US}JAU)Rx3_PF^ b͉L L.F̼̒Y"'fn~*Ƹ9ݘi.“sIN ,7\FcKSs+s$(̼4qs׃X: Ѿii9yűz\\ %Ep3ӀtHP&kCN~~B lv=pM& RY6ٟ'i" h~E~4g 1M89O$y^3r'g&gǧL6p|)Q6gImnc:%^#:ĜTk.'$, a~! 8AFLd)(er&:&FNtąC4Kr3KJRShy V&=.*Y8@xWrC(#B@Q~rjq$FՖ njxWrC#$97<Cx{RyBTqjYr~^^jB@iQA~qGf貞) ``bZ`bj`d``khk``hle`helZZ5kr:X, &d5y'dKEoI1NS\T\YP7y 9b5522K44t@/ y'p+ON6cL|xMiҒT6N Qy):\mx&J @|S-N/֜ϫ'im^|ʓ d&mBOMEBnl&3ᎏ6(,9b~󾭖dl SS{`~߯)ʼn5lI6 $Nm.6Odάg9$6plqjߧy6Ev#ϲ,fŲ~DL4mc&X߅&QgiQTFQa7nnҎǼ0fks󹹸&lIߣ f7^ո4nom>/)9ǩ0 *&_/skM]ܾ4 ZnGqQŬ&.I,򚃳tdsS)m>) ѩզ6.xhM¨Scs;,^×xO6/S60j@ATdS2 _^+BuǻޞotͳMDhS̬Ҭ'їx2t6w1W`6;~$PiEkjBi)Z bT =;CfїcM-¼2oShH=H0cqaj]ڷ>ɥΎr{!5 NM|sx5Lk~F?iIm$au;wq%n<8_nFqq(INJxr^a}шpI`˻L  Ux0>#$鋵#;2qzQrl$G_Eڷ9f k:bW)?#@V |"LC\0{8n2,堻؞DHSk!hb+ ,-vZKælwǣd@ =DZLkƤAvg bsc͗Ib;)횝̋%tº&Y͘lv4$:aA:"Wt HU@bu`hOdc٫ŋwae02?~F>!>`Ӡi|;>,E\Ԑڜ< ikV!O6At+:SJٌR?o7$>R AV&ӡ5{77Eqbi/Gj֎ۦ?<5;PDZڴim;mhZK/hbIVRfYՙ0Xh}xRfñY q k,NIIלبۆ{;99F5|~M!3uFrc<K>s$/Ca x((hHY:d0vvW}( G'(|H1QDsVBZ3L5uid*&$yxa~?BX&4ⓏU7K#㶪UEU5擂PҞ %6 "AV9:*(-55pEx*g$n:5==q`W4[YP4>qr(eENG6{ʛ?ԧ &yˋTnZ#+N`Ɔ0#wp;G!k|PϮ!G]Q5د$0Jrٰ:%nJ-Fd j;#S^l:Dg\4m4b'U?쇗!W9Ub֒{ V7R= * %$}0,7I4YZzWԓ 6  ̃_f-L5unQܩg| O@IiE_#UPQn{14Q& &gGB$$# f"s[fpu\8AKW8Be+uбV-Rkl:` ݯdHLAKlj7sE2nSiݞ*-\Ul#ߖ?R #1Fx 3u]feKGI<1oH-r~nt&UݖeDD}CIVƊDt- 7Ğn܀ P!Cd*`-2;0Z "]+|MrBye;W,8!'ѝˈLW6*'5E( aː 扼 @w+d=GQ^6ʑfۢd0O,QzWwH<1V!p>8Ŋyd cR;b`?;I ܉ @EL>Q=f\Y2R3VA=ΕN:O:`)J{$yt`ߚgb tD/b+Aп] N۰LE>p4xNDevV#[ΜMQQ>|VyY؏u(8.eDe5H;KDhE; 8.BPn:#4-jr_/䆩YsD-Lӑ|lq7 #]oJ})7oIO3ɫf)dpӗ˲8PPRrs6>ť[7I.m4]-Nw!j.7fc:L Qw[A礈 ;m!߸]g +j P:v/[ww+,FUsb݋<]|!4V\pk,*)Ú\v)0c8lV}qF1R,:zv ;k7` 0@}͂Oo4] +\T|`5DY! Â\ϙvH%9++I&=RBmF8ҀPO;)^$ m9 -jx{:}7!(|YO}^=M=(4ڍhe*b|ROˀ&(?QUa CoBNU]a-%YSNKh> C/&Rh+)E4U~뻱\\o7G Y7ltbi5߅+r~q!"s7R8Jpݙv/+9>`A莸% *A‹4;1z;ֲ) }4Պ)ZYH5wpҕl`+`x;ĸqC#x:~ԜԼ̼ĢJԒ"&vx4Ȃ{]09_.'m3*e-y/s;p3'7W<Zx[ĸqC#xs3x[ĸqC#xs3({xRݑ!bs<0dCq⬛2deLf\jf78MǥXZZXZ\Z_P$3@Z+'t=򋁔obZZNf^oqzq*BfBjfIFj$4 $5(f`Ԁ Skǥ9z5T43R`6hɣkeh>ICe's7m`ޜ'pq:?ŽL&N..}Key%d"T5\sNOLK)N9䒒Tk.N 9)r9'+h(%bFt,a Ҥ̒%`l~h9l0t*xHy!rs<0nZ=K IxH9!E7?/urVƏ7+ BFx}SMOQ Zٯ(V-ӦmcIIHD@PДULi a@BB] 7 uoBb܈pӒ{;s*~lzU*I8k5mq Yxcοթ4,JYRJEyVZ)&aȤR#t&ICz4NeGF*SK"[WEgfN ]4&.ˮvq׶_m^[EW?m( sɥh4IHE($Ɖ9ت1Gn|G{gLg >X{k4³N8Gv9x`3 ~&t]%>qf xS}vX3Ӑ#s.Xw6¢XQ9t:ʘ"ՌZR֪JD"^Pjeu#26Ѱ=#1qb2jhuBTZj5ųXרV&8!wp w{1"Mфc